From c1eceb1d7eee64a528cf16bda93f11a2feaf183f Mon Sep 17 00:00:00 2001 From: Juan Batiz-Benet Date: Thu, 26 Jun 2014 00:38:48 -0700 Subject: [PATCH 0001/1212] Big things have small beginnings. This commit was moved from ipfs/kubo@9d0e6a7ffb5deea2c8c8e555d7bf6bcab6fdc6ac This commit was moved from ipfs/boxo@0cc547ba5ce468b4d79e2c023ad7b49f0438e20e From 1e573836850aef678080d9b74e4780af612c98b6 Mon Sep 17 00:00:00 2001 From: Lars Gierth Date: Sun, 11 Sep 2016 05:09:43 +0200 Subject: [PATCH 0002/1212] coreapi: get going, add Cat() and Ls() License: MIT Signed-off-by: Lars Gierth This commit was moved from ipfs/interface-go-ipfs-core@d6cc518f50f331dfd20dc79e87319f307fa2b5e7 This commit was moved from ipfs/boxo@9a989442e7cd6463a7473cf7d6ed03e823c8b38a --- core/coreiface/interface.go | 56 +++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 core/coreiface/interface.go diff --git a/core/coreiface/interface.go b/core/coreiface/interface.go new file mode 100644 index 000000000..694a116a5 --- /dev/null +++ b/core/coreiface/interface.go @@ -0,0 +1,56 @@ +package iface + +import ( + "context" + "errors" + "io" + + cid "gx/ipfs/QmXfiyr2RWEXpVDdaYnD2HNiBk6UBddsvEP4RPfXb6nGqY/go-cid" +) + +// type CoreAPI interface { +// ID() CoreID +// Version() CoreVersion +// } + +type Link struct { + Name string + Size uint64 + Cid *cid.Cid +} + +type Reader interface { + io.ReadSeeker + io.Closer +} + +type UnixfsAPI interface { + Cat(context.Context, string) (Reader, error) + Ls(context.Context, string) ([]*Link, error) +} + +// type ObjectAPI interface { +// New() (cid.Cid, Object) +// Get(string) (Object, error) +// Links(string) ([]*Link, error) +// Data(string) (Reader, error) +// Stat(string) (ObjectStat, error) +// Put(Object) (cid.Cid, error) +// SetData(string, Reader) (cid.Cid, error) +// AppendData(string, Data) (cid.Cid, error) +// AddLink(string, string, string) (cid.Cid, error) +// RmLink(string, string) (cid.Cid, error) +// } + +// type ObjectStat struct { +// Cid cid.Cid +// NumLinks int +// BlockSize int +// LinksSize int +// DataSize int +// CumulativeSize int +// } + +var ErrIsDir = errors.New("object is a directory") +var ErrIsNonDag = errors.New("not a merkledag object") +var ErrOffline = errors.New("can't resolve, ipfs node is offline") From a4a55e7799c0b5814d14825650fe496d6a229ed8 Mon Sep 17 00:00:00 2001 From: Lars Gierth Date: Tue, 20 Sep 2016 04:30:43 +0200 Subject: [PATCH 0003/1212] coreapi: add Add() License: MIT Signed-off-by: Lars Gierth This commit was moved from ipfs/interface-go-ipfs-core@87e9bc0419bdabee9aa6534e53a669484ac2e706 This commit was moved from ipfs/boxo@b83c5e3fc362276e9bfa6a34848598556289bdfa --- core/coreiface/interface.go | 1 + 1 file changed, 1 insertion(+) diff --git a/core/coreiface/interface.go b/core/coreiface/interface.go index 694a116a5..297e8bfed 100644 --- a/core/coreiface/interface.go +++ b/core/coreiface/interface.go @@ -25,6 +25,7 @@ type Reader interface { } type UnixfsAPI interface { + Add(context.Context, io.Reader) (*cid.Cid, error) Cat(context.Context, string) (Reader, error) Ls(context.Context, string) ([]*Link, error) } From a3fb17377b56a28ef4e2e62dd620f179cf8bb7df Mon Sep 17 00:00:00 2001 From: Lars Gierth Date: Sun, 30 Oct 2016 03:09:48 +0100 Subject: [PATCH 0004/1212] coreapi: reuse go-ipld-node.Link License: MIT Signed-off-by: Lars Gierth This commit was moved from ipfs/interface-go-ipfs-core@c34bbcac7cbf4b4b075dac8474dad72ef4b6063b This commit was moved from ipfs/boxo@54a9bc53742ad876e1b9705c10b50fc47d58377d --- core/coreiface/interface.go | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/core/coreiface/interface.go b/core/coreiface/interface.go index 297e8bfed..18328a2a0 100644 --- a/core/coreiface/interface.go +++ b/core/coreiface/interface.go @@ -5,6 +5,7 @@ import ( "errors" "io" + ipld "gx/ipfs/QmU7bFWQ793qmvNy7outdCaMfSDNk8uqhx4VNrxYj5fj5g/go-ipld-node" cid "gx/ipfs/QmXfiyr2RWEXpVDdaYnD2HNiBk6UBddsvEP4RPfXb6nGqY/go-cid" ) @@ -13,11 +14,7 @@ import ( // Version() CoreVersion // } -type Link struct { - Name string - Size uint64 - Cid *cid.Cid -} +type Link ipld.Link type Reader interface { io.ReadSeeker From 10bf6e91714f6e4f180dd0adccc26ddebb7266fb Mon Sep 17 00:00:00 2001 From: Jeromy Date: Tue, 15 Nov 2016 18:00:49 -0800 Subject: [PATCH 0005/1212] update to newer ipld node interface with Copy and better Tree License: MIT Signed-off-by: Jeromy This commit was moved from ipfs/interface-go-ipfs-core@23f95c6d1e4016ab5a01c9339b3926fdace37198 This commit was moved from ipfs/boxo@4f28fc777233e298a426081032b35501ea5ae8eb --- core/coreiface/interface.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/coreiface/interface.go b/core/coreiface/interface.go index 18328a2a0..c1c83fa26 100644 --- a/core/coreiface/interface.go +++ b/core/coreiface/interface.go @@ -5,8 +5,8 @@ import ( "errors" "io" - ipld "gx/ipfs/QmU7bFWQ793qmvNy7outdCaMfSDNk8uqhx4VNrxYj5fj5g/go-ipld-node" - cid "gx/ipfs/QmXfiyr2RWEXpVDdaYnD2HNiBk6UBddsvEP4RPfXb6nGqY/go-cid" + ipld "gx/ipfs/QmUsVJ7AEnGyjX8YWnrwq9vmECVGwBQNAKPpgz5KSg8dcq/go-ipld-node" + cid "gx/ipfs/QmcEcrBAMrwMyhSjXt4yfyPpzgSuV8HLHavnfmiKCSRqZU/go-cid" ) // type CoreAPI interface { From 88ba95d954d28e4392c65e47de682efbed6d87b7 Mon Sep 17 00:00:00 2001 From: Jeromy Date: Mon, 28 Nov 2016 22:29:38 -0800 Subject: [PATCH 0006/1212] bubble up go-datastore deps License: MIT Signed-off-by: Jeromy This commit was moved from ipfs/interface-go-ipfs-core@3f68a10d21f3553c4639f477388b3b36492912a2 This commit was moved from ipfs/boxo@da6ace83a4549449f1c3f08748d0906d0bfeee37 --- core/coreiface/interface.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/coreiface/interface.go b/core/coreiface/interface.go index c1c83fa26..cf6471947 100644 --- a/core/coreiface/interface.go +++ b/core/coreiface/interface.go @@ -5,8 +5,8 @@ import ( "errors" "io" - ipld "gx/ipfs/QmUsVJ7AEnGyjX8YWnrwq9vmECVGwBQNAKPpgz5KSg8dcq/go-ipld-node" - cid "gx/ipfs/QmcEcrBAMrwMyhSjXt4yfyPpzgSuV8HLHavnfmiKCSRqZU/go-cid" + ipld "gx/ipfs/QmRSU5EqqWVZSNdbU51yXmVoF1uNw3JgTNB6RaiL7DZM16/go-ipld-node" + cid "gx/ipfs/QmcTcsTvfaeEBRFo1TkFgT8sRmgi1n1LTZpecfVP8fzpGD/go-cid" ) // type CoreAPI interface { From 95beda800ffd616baa7e5216dd86d0efa3dabf20 Mon Sep 17 00:00:00 2001 From: Jeromy Date: Thu, 2 Feb 2017 20:09:02 -0800 Subject: [PATCH 0007/1212] update go-multihash and bubble up deps License: MIT Signed-off-by: Jeromy This commit was moved from ipfs/interface-go-ipfs-core@c7723c40fead3509cec1fa255fc8531e8e87c744 This commit was moved from ipfs/boxo@c8a57ca4e3df2570f75832b5bebcb925ae647bce --- core/coreiface/interface.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/coreiface/interface.go b/core/coreiface/interface.go index cf6471947..b506e6509 100644 --- a/core/coreiface/interface.go +++ b/core/coreiface/interface.go @@ -5,8 +5,8 @@ import ( "errors" "io" - ipld "gx/ipfs/QmRSU5EqqWVZSNdbU51yXmVoF1uNw3JgTNB6RaiL7DZM16/go-ipld-node" - cid "gx/ipfs/QmcTcsTvfaeEBRFo1TkFgT8sRmgi1n1LTZpecfVP8fzpGD/go-cid" + cid "gx/ipfs/QmV5gPoRsjN1Gid3LMdNZTyfCtP2DsvqEbMAmz82RmmiGk/go-cid" + ipld "gx/ipfs/QmYDscK7dmdo2GZ9aumS8s5auUUAH5mR1jvj5pYhWusfK7/go-ipld-node" ) // type CoreAPI interface { From 5bce81d63e222d3ea8a7d3a2e1e4aaba6bb179bd Mon Sep 17 00:00:00 2001 From: Lars Gierth Date: Wed, 16 Nov 2016 06:21:15 +0100 Subject: [PATCH 0008/1212] coreapi: smarter way of dealing with the different APIs License: MIT Signed-off-by: Lars Gierth This commit was moved from ipfs/interface-go-ipfs-core@e69000d481d335aef4d610be31750e8558f3b795 This commit was moved from ipfs/boxo@295f1305501eabc7645b7d947d823148c3b0bb56 --- core/coreiface/interface.go | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/core/coreiface/interface.go b/core/coreiface/interface.go index b506e6509..7bf9d5c0a 100644 --- a/core/coreiface/interface.go +++ b/core/coreiface/interface.go @@ -9,11 +9,6 @@ import ( ipld "gx/ipfs/QmYDscK7dmdo2GZ9aumS8s5auUUAH5mR1jvj5pYhWusfK7/go-ipld-node" ) -// type CoreAPI interface { -// ID() CoreID -// Version() CoreVersion -// } - type Link ipld.Link type Reader interface { @@ -21,6 +16,10 @@ type Reader interface { io.Closer } +type CoreAPI interface { + Unixfs() UnixfsAPI +} + type UnixfsAPI interface { Add(context.Context, io.Reader) (*cid.Cid, error) Cat(context.Context, string) (Reader, error) From 1c53ef3f984b664538ada9d9adf27cdc4ea3c2b6 Mon Sep 17 00:00:00 2001 From: Lars Gierth Date: Fri, 17 Mar 2017 03:47:59 +0100 Subject: [PATCH 0009/1212] coreapi: make the interfaces path centric The new coreiface.Path maps a path to the cid.Cid resulting from a full path resolution. The path is internally represented as a go-ipfs/path.Path, but that doesn't matter to the outside. Apart from the path-to-CID mapping, it also aims to hold all resolved segment CIDs of the path. Right now it only exposes Root(), and only for flat paths a la /ipfs/Qmfoo. In other cases, the root is nil. In the future, resolution will internally use go-ipfs/path.Resolver.ResolvePathComponents and thus always return the proper resolved segments, via Root(), or a future Segments() func. - Add coreiface.Path with Cid() and Root(). - Add CoreAPI.ResolvePath() for getting a coreiface.Path. - All functions now expect and return coreiface.Path. - Add ParsePath() and ParseCid() for constructing a coreiface.Path. - Add coreiface.Node and Link which are simply go-ipld-node.Node and Link. - Add CoreAPI.ResolveNode() for getting a Node from a Path. License: MIT Signed-off-by: Lars Gierth This commit was moved from ipfs/interface-go-ipfs-core@66af039105d5e4ebc82a178143d8643ad3fed91d This commit was moved from ipfs/boxo@61e07c830c0222fbd796118e7784e24ecf1c7e24 --- core/coreiface/interface.go | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/core/coreiface/interface.go b/core/coreiface/interface.go index 7bf9d5c0a..d72fc8a3b 100644 --- a/core/coreiface/interface.go +++ b/core/coreiface/interface.go @@ -9,6 +9,16 @@ import ( ipld "gx/ipfs/QmYDscK7dmdo2GZ9aumS8s5auUUAH5mR1jvj5pYhWusfK7/go-ipld-node" ) +type Path interface { + String() string + Cid() *cid.Cid + Root() *cid.Cid + Resolved() bool +} + +// TODO: should we really copy these? +// if we didn't, godoc would generate nice links straight to go-ipld-node +type Node ipld.Node type Link ipld.Link type Reader interface { @@ -18,12 +28,14 @@ type Reader interface { type CoreAPI interface { Unixfs() UnixfsAPI + ResolvePath(context.Context, Path) (Path, error) + ResolveNode(context.Context, Path) (Node, error) } type UnixfsAPI interface { - Add(context.Context, io.Reader) (*cid.Cid, error) - Cat(context.Context, string) (Reader, error) - Ls(context.Context, string) ([]*Link, error) + Add(context.Context, io.Reader) (Path, error) + Cat(context.Context, Path) (Reader, error) + Ls(context.Context, Path) ([]*Link, error) } // type ObjectAPI interface { @@ -49,5 +61,4 @@ type UnixfsAPI interface { // } var ErrIsDir = errors.New("object is a directory") -var ErrIsNonDag = errors.New("not a merkledag object") var ErrOffline = errors.New("can't resolve, ipfs node is offline") From 393471674ced3be04563a5667bd5cda91f4e0bc3 Mon Sep 17 00:00:00 2001 From: Jeromy Date: Fri, 24 Mar 2017 23:51:18 -0700 Subject: [PATCH 0010/1212] bubble up updates from go-multihash changes License: MIT Signed-off-by: Jeromy This commit was moved from ipfs/interface-go-ipfs-core@be73d10538ec977bdb62976f52ac926f5eb83232 This commit was moved from ipfs/boxo@dcecd3345b8ceed091ee2e80857695e170ea5bf2 --- core/coreiface/interface.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/coreiface/interface.go b/core/coreiface/interface.go index d72fc8a3b..a7762c8c2 100644 --- a/core/coreiface/interface.go +++ b/core/coreiface/interface.go @@ -5,8 +5,8 @@ import ( "errors" "io" - cid "gx/ipfs/QmV5gPoRsjN1Gid3LMdNZTyfCtP2DsvqEbMAmz82RmmiGk/go-cid" - ipld "gx/ipfs/QmYDscK7dmdo2GZ9aumS8s5auUUAH5mR1jvj5pYhWusfK7/go-ipld-node" + cid "gx/ipfs/QmYhQaCYEcaPPjxJX7YcPcVKkQfRy6sJ7B3XmGFk82XYdQ/go-cid" + ipld "gx/ipfs/Qmb3Hm9QDFmfYuET4pu7Kyg8JV78jFa1nvZx5vnCZsK4ck/go-ipld-format" ) type Path interface { @@ -17,7 +17,7 @@ type Path interface { } // TODO: should we really copy these? -// if we didn't, godoc would generate nice links straight to go-ipld-node +// if we didn't, godoc would generate nice links straight to go-ipld-format type Node ipld.Node type Link ipld.Link From 4c057b0fc32b7ae9c834295946c507c0c03ba752 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Sun, 18 Jun 2017 13:07:24 -0700 Subject: [PATCH 0011/1212] blocks: gx import go-block-format And updated related dependencies. License: MIT Signed-off-by: Steven Allen This commit was moved from ipfs/interface-go-ipfs-core@477bd882b4bdd348fd7ef8f35c81f5a11a732199 This commit was moved from ipfs/boxo@8fd5b213838670d5fed83a6ca39240179ab8cf3f --- core/coreiface/interface.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/coreiface/interface.go b/core/coreiface/interface.go index a7762c8c2..273d8e25a 100644 --- a/core/coreiface/interface.go +++ b/core/coreiface/interface.go @@ -5,8 +5,8 @@ import ( "errors" "io" - cid "gx/ipfs/QmYhQaCYEcaPPjxJX7YcPcVKkQfRy6sJ7B3XmGFk82XYdQ/go-cid" - ipld "gx/ipfs/Qmb3Hm9QDFmfYuET4pu7Kyg8JV78jFa1nvZx5vnCZsK4ck/go-ipld-format" + cid "gx/ipfs/QmNw61A6sJoXMeP37mJRtQZdNhj5e3FdjoTN3v4FyE96Gk/go-cid" + ipld "gx/ipfs/QmUBtPvHKFAX43XMsyxsYpMi3U5VwZ4jYFTo4kFhvAR33G/go-ipld-format" ) type Path interface { From 3ba2027081fb010676936fd2492a66a6bf3e22a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 4 Jul 2017 20:18:57 +0200 Subject: [PATCH 0012/1212] Update go-datastore to 1.2.2, go-cid to 0.7.16 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@e706b34ea178ca535760a511e3950510e6bb1355 This commit was moved from ipfs/boxo@624057e9d94d8d44cc424dca843027b47fa25ec1 --- core/coreiface/interface.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/coreiface/interface.go b/core/coreiface/interface.go index 273d8e25a..363c5adac 100644 --- a/core/coreiface/interface.go +++ b/core/coreiface/interface.go @@ -5,8 +5,8 @@ import ( "errors" "io" - cid "gx/ipfs/QmNw61A6sJoXMeP37mJRtQZdNhj5e3FdjoTN3v4FyE96Gk/go-cid" - ipld "gx/ipfs/QmUBtPvHKFAX43XMsyxsYpMi3U5VwZ4jYFTo4kFhvAR33G/go-ipld-format" + ipld "gx/ipfs/QmPAKbSsgEX5B6fpmxa61jXYnoWzZr5sNafd3qgPiSH8Uv/go-ipld-format" + cid "gx/ipfs/Qma4RJSuh7mMeJQYCqMbKzekn6EwBo7HEs5AQYjVRMQATB/go-cid" ) type Path interface { From a7a3a37e827000bfaa7fb0fa5d68e85748ace90c Mon Sep 17 00:00:00 2001 From: Jeromy Date: Tue, 11 Jul 2017 19:17:51 -0700 Subject: [PATCH 0013/1212] update go-multihash and bubble up changes License: MIT Signed-off-by: Jeromy This commit was moved from ipfs/interface-go-ipfs-core@ee874380410e6a909c9517ecd58730cb17b4424d This commit was moved from ipfs/boxo@0997d0c7d5f69975acdf597e7266427e54c223b4 --- core/coreiface/interface.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/coreiface/interface.go b/core/coreiface/interface.go index 363c5adac..81197bb46 100644 --- a/core/coreiface/interface.go +++ b/core/coreiface/interface.go @@ -5,8 +5,8 @@ import ( "errors" "io" - ipld "gx/ipfs/QmPAKbSsgEX5B6fpmxa61jXYnoWzZr5sNafd3qgPiSH8Uv/go-ipld-format" - cid "gx/ipfs/Qma4RJSuh7mMeJQYCqMbKzekn6EwBo7HEs5AQYjVRMQATB/go-cid" + cid "gx/ipfs/QmTprEaAA2A9bst5XH7exuyi5KzNMK3SEDNN8rBDnKWcUS/go-cid" + ipld "gx/ipfs/QmYNyRZJBUYPNrLszFmrBrPJbsBh2vMsefz5gnDpB5M1P6/go-ipld-format" ) type Path interface { From 9065eaf739718d028c3572ecd33ef9bf7a0c28bf Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Mon, 28 Aug 2017 20:32:16 -0700 Subject: [PATCH 0014/1212] gx: update go-cid, go-multibase, base32 License: MIT Signed-off-by: Steven Allen This commit was moved from ipfs/interface-go-ipfs-core@6c6807b399ac688cbe92d85156b74cae3bd45321 This commit was moved from ipfs/boxo@d45714f3fa2fcf0224d6b0774cd729941109a450 --- core/coreiface/interface.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/coreiface/interface.go b/core/coreiface/interface.go index 81197bb46..78a64dd40 100644 --- a/core/coreiface/interface.go +++ b/core/coreiface/interface.go @@ -5,8 +5,8 @@ import ( "errors" "io" - cid "gx/ipfs/QmTprEaAA2A9bst5XH7exuyi5KzNMK3SEDNN8rBDnKWcUS/go-cid" - ipld "gx/ipfs/QmYNyRZJBUYPNrLszFmrBrPJbsBh2vMsefz5gnDpB5M1P6/go-ipld-format" + cid "gx/ipfs/QmNp85zy9RLrQ5oQD4hPyS39ezrrXpcaa7R4Y9kxdWQLLQ/go-cid" + ipld "gx/ipfs/QmPN7cwmpcc4DWXb4KTB9dNAJgjuPY69h3npsMfhRrQL9c/go-ipld-format" ) type Path interface { From 0826705811ed121d6044a600c72297cd0a4f3c22 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Sun, 3 Dec 2017 21:34:29 -0800 Subject: [PATCH 0015/1212] gx: update go-multihash License: MIT Signed-off-by: Steven Allen This commit was moved from ipfs/interface-go-ipfs-core@b5fea556bf3c13bbeed2b0fe72605f0c23b17ae3 This commit was moved from ipfs/boxo@efbab5e602175954bcef811bbbba89340ebfe687 --- core/coreiface/interface.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/coreiface/interface.go b/core/coreiface/interface.go index 78a64dd40..aef86d63a 100644 --- a/core/coreiface/interface.go +++ b/core/coreiface/interface.go @@ -5,8 +5,8 @@ import ( "errors" "io" - cid "gx/ipfs/QmNp85zy9RLrQ5oQD4hPyS39ezrrXpcaa7R4Y9kxdWQLLQ/go-cid" - ipld "gx/ipfs/QmPN7cwmpcc4DWXb4KTB9dNAJgjuPY69h3npsMfhRrQL9c/go-ipld-format" + ipld "gx/ipfs/QmNwUEK7QbwSqyKBu3mMtToo8SUc6wQJ7gdZq4gGGJqfnf/go-ipld-format" + cid "gx/ipfs/QmeSrf6pzut73u6zLQkRFQ3ygt3k6XFT2kjdYP8Tnkwwyg/go-cid" ) type Path interface { From 66f305fb517f962ad64a1aa92f4702c4d2b043f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 15 Dec 2017 01:34:49 +0100 Subject: [PATCH 0016/1212] docs/coreapi: Add some documentation to CoreAPI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@2fbdcd09c87e05ff355b4a492b01029273b1f0f3 This commit was moved from ipfs/boxo@9cc221d2ae772fe67425e873db64516bf1bf1f40 --- core/coreiface/interface.go | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/core/coreiface/interface.go b/core/coreiface/interface.go index 78a64dd40..87e9fcd0f 100644 --- a/core/coreiface/interface.go +++ b/core/coreiface/interface.go @@ -1,3 +1,5 @@ +// Package iface defines IPFS Core API which is a set of interfaces used to +// interact with IPFS nodes. package iface import ( @@ -9,6 +11,8 @@ import ( ipld "gx/ipfs/QmPN7cwmpcc4DWXb4KTB9dNAJgjuPY69h3npsMfhRrQL9c/go-ipld-format" ) +// Path is a generic wrapper for paths used in the API. A path can be resolved +// to a CID using one of Resolve functions in the API. type Path interface { String() string Cid() *cid.Cid @@ -26,15 +30,28 @@ type Reader interface { io.Closer } +// CoreAPI defines an unified interface to IPFS for Go programs. type CoreAPI interface { + // Unixfs returns an implementation of Unixfs API Unixfs() UnixfsAPI + + // ResolvePath resolves the path using Unixfs resolver ResolvePath(context.Context, Path) (Path, error) + + // ResolveNode resolves the path (if not resolved already) using Unixfs + // resolver, gets and returns the resolved Node ResolveNode(context.Context, Path) (Node, error) } +// UnixfsAPI is the basic interface to immutable files in IPFS type UnixfsAPI interface { + // Add imports the data from the reader into merkledag file Add(context.Context, io.Reader) (Path, error) + + // Cat returns a reader for the file Cat(context.Context, Path) (Reader, error) + + // Ls returns the list of links in a directory Ls(context.Context, Path) ([]*Link, error) } From 3051f3b60123d981b25e88dd45651064ac9a8511 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 8 Dec 2017 22:51:35 +0100 Subject: [PATCH 0017/1212] coreapi: DAG API proposal MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@c6015845cbf43a2b9fc83d749137bee10f9d6396 This commit was moved from ipfs/boxo@b351a5a73c7db7a1dbbbffe546f76563c91c2fa5 --- core/coreiface/interface.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/core/coreiface/interface.go b/core/coreiface/interface.go index b753c4184..508588a04 100644 --- a/core/coreiface/interface.go +++ b/core/coreiface/interface.go @@ -34,13 +34,14 @@ type Reader interface { type CoreAPI interface { // Unixfs returns an implementation of Unixfs API Unixfs() UnixfsAPI + Dag() DagAPI // ResolvePath resolves the path using Unixfs resolver ResolvePath(context.Context, Path) (Path, error) // ResolveNode resolves the path (if not resolved already) using Unixfs // resolver, gets and returns the resolved Node - ResolveNode(context.Context, Path) (Node, error) + ResolveNode(context.Context, Path) (Node, error) //TODO: should this get dropped in favor of DagAPI.Get? } // UnixfsAPI is the basic interface to immutable files in IPFS @@ -55,6 +56,12 @@ type UnixfsAPI interface { Ls(context.Context, Path) ([]*Link, error) } +type DagAPI interface { + Put(ctx context.Context, src io.Reader, inputEnc string, format *cid.Prefix) ([]Node, error) + Get(ctx context.Context, path Path) (Node, error) + Tree(ctx context.Context, path Path, depth int) ([]Path, error) +} + // type ObjectAPI interface { // New() (cid.Cid, Object) // Get(string) (Object, error) From 363c556e23c5ae12c40fda53fac95500f295f1a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 11 Dec 2017 17:22:21 +0100 Subject: [PATCH 0018/1212] coreapi: add tests for dag MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@c593c49d857c407d9e3b6a5576f2cdb5a1fe1e97 This commit was moved from ipfs/boxo@b0b4e68ff7103e39dd2698db9877b96978bc3ec4 --- core/coreiface/interface.go | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/core/coreiface/interface.go b/core/coreiface/interface.go index 508588a04..ecccc1c64 100644 --- a/core/coreiface/interface.go +++ b/core/coreiface/interface.go @@ -41,7 +41,7 @@ type CoreAPI interface { // ResolveNode resolves the path (if not resolved already) using Unixfs // resolver, gets and returns the resolved Node - ResolveNode(context.Context, Path) (Node, error) //TODO: should this get dropped in favor of DagAPI.Get? + ResolveNode(context.Context, Path) (Node, error) } // UnixfsAPI is the basic interface to immutable files in IPFS @@ -56,9 +56,17 @@ type UnixfsAPI interface { Ls(context.Context, Path) ([]*Link, error) } +// DagAPI specifies the interface to IPLD type DagAPI interface { - Put(ctx context.Context, src io.Reader, inputEnc string, format *cid.Prefix) ([]Node, error) + // Put inserts data using specified format and input encoding. + // If format is not specified (nil), default dag-cbor/sha256 is used + Put(ctx context.Context, src io.Reader, inputEnc string, format *cid.Prefix) ([]Node, error) //TODO: make format optional + + // Get attempts to resolve and get the node specified by the path Get(ctx context.Context, path Path) (Node, error) + + // Tree returns list of paths within a node specified by the path. + // To get all paths in a tree, set depth to -1 Tree(ctx context.Context, path Path, depth int) ([]Path, error) } From e6a16b57e63b33e1d8ed7f2edb079e1c96527873 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Sun, 17 Dec 2017 03:23:50 +0100 Subject: [PATCH 0019/1212] coreapi: functional options for DagAPI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@39f8afada852b5189996725ccde10b6d64f1b5ab This commit was moved from ipfs/boxo@9901857d2d284da55025a64aacf72d6ac9c89b1f --- core/coreiface/interface.go | 25 +++++++++-- core/coreiface/options/dag.go | 83 +++++++++++++++++++++++++++++++++++ 2 files changed, 105 insertions(+), 3 deletions(-) create mode 100644 core/coreiface/options/dag.go diff --git a/core/coreiface/interface.go b/core/coreiface/interface.go index ecccc1c64..f43700e9c 100644 --- a/core/coreiface/interface.go +++ b/core/coreiface/interface.go @@ -7,6 +7,8 @@ import ( "errors" "io" + options "github.com/ipfs/go-ipfs/core/coreapi/interface/options" + ipld "gx/ipfs/QmNwUEK7QbwSqyKBu3mMtToo8SUc6wQJ7gdZq4gGGJqfnf/go-ipld-format" cid "gx/ipfs/QmeSrf6pzut73u6zLQkRFQ3ygt3k6XFT2kjdYP8Tnkwwyg/go-cid" ) @@ -60,14 +62,31 @@ type UnixfsAPI interface { type DagAPI interface { // Put inserts data using specified format and input encoding. // If format is not specified (nil), default dag-cbor/sha256 is used - Put(ctx context.Context, src io.Reader, inputEnc string, format *cid.Prefix) ([]Node, error) //TODO: make format optional + Put(ctx context.Context, src io.Reader, opts ...options.DagPutOption) ([]Node, error) + + // WithInputEnc is an option for Put which specifies the input encoding of the + // data. Default is "json", most formats/codecs support "raw" + WithInputEnc(enc string) options.DagPutOption + + // WithCodec is an option for Put which specifies the multicodec to use to + // serialize the object. Default is cid.DagCBOR (0x71) + WithCodec(codec uint64) options.DagPutOption + + // WithHash is an option for Put which specifies the multihash settings to use + // when hashing the object. Default is based on the codec used + // (mh.SHA2_256 (0x12) for DagCBOR). If mhLen is set to -1, default length for + // the hash will be used + WithHash(mhType uint64, mhLen int) options.DagPutOption // Get attempts to resolve and get the node specified by the path Get(ctx context.Context, path Path) (Node, error) // Tree returns list of paths within a node specified by the path. - // To get all paths in a tree, set depth to -1 - Tree(ctx context.Context, path Path, depth int) ([]Path, error) + Tree(ctx context.Context, path Path, opts ...options.DagTreeOption) ([]Path, error) + + // WithDepth is an option for Tree which specifies maximum depth of the + // returned tree. Default is -1 (no depth limit) + WithDepth(depth int) options.DagTreeOption } // type ObjectAPI interface { diff --git a/core/coreiface/options/dag.go b/core/coreiface/options/dag.go new file mode 100644 index 000000000..7850c4bc3 --- /dev/null +++ b/core/coreiface/options/dag.go @@ -0,0 +1,83 @@ +package options + +import ( + "math" + + cid "gx/ipfs/QmeSrf6pzut73u6zLQkRFQ3ygt3k6XFT2kjdYP8Tnkwwyg/go-cid" +) + +type DagPutSettings struct { + InputEnc string + Codec uint64 + MhType uint64 + MhLength int +} + +type DagTreeSettings struct { + Depth int +} + +type DagPutOption func(*DagPutSettings) error +type DagTreeOption func(*DagTreeSettings) error + +func DagPutOptions(opts ...DagPutOption) (*DagPutSettings, error) { + options := &DagPutSettings{ + InputEnc: "json", + Codec: cid.DagCBOR, + MhType: math.MaxUint64, + MhLength: -1, + } + + for _, opt := range opts { + err := opt(options) + if err != nil { + return nil, err + } + } + return options, nil +} + +func DagTreeOptions(opts ...DagTreeOption) (*DagTreeSettings, error) { + options := &DagTreeSettings{ + Depth: -1, + } + + for _, opt := range opts { + err := opt(options) + if err != nil { + return nil, err + } + } + return options, nil +} + +type DagOptions struct{} + +func (api *DagOptions) WithInputEnc(enc string) DagPutOption { + return func(settings *DagPutSettings) error { + settings.InputEnc = enc + return nil + } +} + +func (api *DagOptions) WithCodec(codec uint64) DagPutOption { + return func(settings *DagPutSettings) error { + settings.Codec = codec + return nil + } +} + +func (api *DagOptions) WithHash(mhType uint64, mhLen int) DagPutOption { + return func(settings *DagPutSettings) error { + settings.MhType = mhType + settings.MhLength = mhLen + return nil + } +} + +func (api *DagOptions) WithDepth(depth int) DagTreeOption { + return func(settings *DagTreeSettings) error { + settings.Depth = depth + return nil + } +} From e68b73b54ed06fc8b078bc4866efe1653f6dae4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 21 Dec 2017 01:56:41 +0100 Subject: [PATCH 0020/1212] coreapi: dag review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@20fa7a599e839af20bef873f12fcc2f94fd0c529 This commit was moved from ipfs/boxo@bae5f5303ec03d6399c3345ba6c14397812b1ead --- core/coreiface/interface.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/core/coreiface/interface.go b/core/coreiface/interface.go index f43700e9c..e51888e60 100644 --- a/core/coreiface/interface.go +++ b/core/coreiface/interface.go @@ -61,8 +61,9 @@ type UnixfsAPI interface { // DagAPI specifies the interface to IPLD type DagAPI interface { // Put inserts data using specified format and input encoding. - // If format is not specified (nil), default dag-cbor/sha256 is used - Put(ctx context.Context, src io.Reader, opts ...options.DagPutOption) ([]Node, error) + // Unless used with WithCodec or WithHash, the defaults "dag-cbor" and + // "sha256" are used. + Put(ctx context.Context, src io.Reader, opts ...options.DagPutOption) (Path, error) // WithInputEnc is an option for Put which specifies the input encoding of the // data. Default is "json", most formats/codecs support "raw" From 71593fb48cd8b6b4bc7590d7b1cfa8b662ef611d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Sun, 10 Dec 2017 23:15:37 +0100 Subject: [PATCH 0021/1212] coreapi: Name API proposal MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@1b5e997ca845b58519a3592db60c78d4ec7efdc8 This commit was moved from ipfs/boxo@8972ab9e110214d72b9c048240ac75e33bd69248 --- core/coreiface/interface.go | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/core/coreiface/interface.go b/core/coreiface/interface.go index e51888e60..3fcf7374e 100644 --- a/core/coreiface/interface.go +++ b/core/coreiface/interface.go @@ -6,6 +6,7 @@ import ( "context" "errors" "io" + "time" options "github.com/ipfs/go-ipfs/core/coreapi/interface/options" @@ -27,6 +28,11 @@ type Path interface { type Node ipld.Node type Link ipld.Link +type IpnsEntry struct { + Name string + Value Path +} + type Reader interface { io.ReadSeeker io.Closer @@ -37,6 +43,7 @@ type CoreAPI interface { // Unixfs returns an implementation of Unixfs API Unixfs() UnixfsAPI Dag() DagAPI + Name() NameAPI // ResolvePath resolves the path using Unixfs resolver ResolvePath(context.Context, Path) (Path, error) @@ -90,6 +97,18 @@ type DagAPI interface { WithDepth(depth int) options.DagTreeOption } +type NameAPI interface { + Publish(ctx context.Context, path Path, validTime time.Duration, key string) (*IpnsEntry, error) + Resolve(ctx context.Context, name string, recursive bool, local bool, nocache bool) (Path, error) +} + +type KeyApi interface { + Generate(ctx context.Context, name string, algorithm string, size int) error + List(ctx context.Context) (map[string]string, error) //TODO: better key type? + Rename(ctx context.Context, oldName string, newName string) error + Remove(ctx context.Context, name string) error +} + // type ObjectAPI interface { // New() (cid.Cid, Object) // Get(string) (Object, error) From cb3c588799f563e5597d3855ccff3a10b915c13f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Sun, 10 Dec 2017 23:48:16 +0100 Subject: [PATCH 0022/1212] coreapi: Keystore API proposal MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@4fbdf56dc24b8b7357c0eb06c223093c506c1bbc This commit was moved from ipfs/boxo@286e418f6c66494631d6b570b1ec86396c13e2f0 --- core/coreiface/interface.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/core/coreiface/interface.go b/core/coreiface/interface.go index 3fcf7374e..f6412d68f 100644 --- a/core/coreiface/interface.go +++ b/core/coreiface/interface.go @@ -44,6 +44,7 @@ type CoreAPI interface { Unixfs() UnixfsAPI Dag() DagAPI Name() NameAPI + Key() KeyAPI // ResolvePath resolves the path using Unixfs resolver ResolvePath(context.Context, Path) (Path, error) @@ -102,11 +103,11 @@ type NameAPI interface { Resolve(ctx context.Context, name string, recursive bool, local bool, nocache bool) (Path, error) } -type KeyApi interface { - Generate(ctx context.Context, name string, algorithm string, size int) error +type KeyAPI interface { + Generate(ctx context.Context, name string, algorithm string, size int) (string, error) List(ctx context.Context) (map[string]string, error) //TODO: better key type? - Rename(ctx context.Context, oldName string, newName string) error - Remove(ctx context.Context, name string) error + Rename(ctx context.Context, oldName string, newName string, force bool) (string, bool, error) + Remove(ctx context.Context, name string) (string, error) } // type ObjectAPI interface { From d52ea2fe1ae543d162b8bb03dab2ab3c7f18d8a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 13 Dec 2017 19:05:23 +0100 Subject: [PATCH 0023/1212] coreapi: name/key functional options MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@7a786c5509ec924e3cfe2c29b42f76c47ccecbc4 This commit was moved from ipfs/boxo@c02dc49770c2cbbb89c695c8e83bfc1276c6d665 --- core/coreiface/interface.go | 19 ++++++-- core/coreiface/options/key.go | 65 +++++++++++++++++++++++++ core/coreiface/options/name.go | 89 ++++++++++++++++++++++++++++++++++ 3 files changed, 169 insertions(+), 4 deletions(-) create mode 100644 core/coreiface/options/key.go create mode 100644 core/coreiface/options/name.go diff --git a/core/coreiface/interface.go b/core/coreiface/interface.go index f6412d68f..36bd801a1 100644 --- a/core/coreiface/interface.go +++ b/core/coreiface/interface.go @@ -99,14 +99,25 @@ type DagAPI interface { } type NameAPI interface { - Publish(ctx context.Context, path Path, validTime time.Duration, key string) (*IpnsEntry, error) - Resolve(ctx context.Context, name string, recursive bool, local bool, nocache bool) (Path, error) + Publish(ctx context.Context, path Path, opts ...options.NamePublishOption) (*IpnsEntry, error) + WithValidTime(validTime time.Duration) options.NamePublishOption + WithKey(key string) options.NamePublishOption + + Resolve(ctx context.Context, name string, opts ...options.NameResolveOption) (Path, error) + WithRecursive(recursive bool) options.NameResolveOption + WithLocal(local bool) options.NameResolveOption + WithNoCache(nocache bool) options.NameResolveOption } type KeyAPI interface { - Generate(ctx context.Context, name string, algorithm string, size int) (string, error) + Generate(ctx context.Context, name string, opts ...options.KeyGenerateOption) (string, error) + WithAlgorithm(algorithm string) options.KeyGenerateOption + WithSize(size int) options.KeyGenerateOption + + Rename(ctx context.Context, oldName string, newName string, opts ...options.KeyRenameOption) (string, bool, error) + WithForce(force bool) options.KeyRenameOption + List(ctx context.Context) (map[string]string, error) //TODO: better key type? - Rename(ctx context.Context, oldName string, newName string, force bool) (string, bool, error) Remove(ctx context.Context, name string) (string, error) } diff --git a/core/coreiface/options/key.go b/core/coreiface/options/key.go new file mode 100644 index 000000000..5ed7b408f --- /dev/null +++ b/core/coreiface/options/key.go @@ -0,0 +1,65 @@ +package options + +type KeyGenerateSettings struct { + Algorithm string + Size int +} + +type KeyRenameSettings struct { + Force bool +} + +type KeyGenerateOption func(*KeyGenerateSettings) error +type KeyRenameOption func(*KeyRenameSettings) error + +func KeyGenerateOptions(opts ...KeyGenerateOption) (*KeyGenerateSettings, error) { + options := &KeyGenerateSettings{ + Algorithm: "rsa", + Size: 0, + } + + for _, opt := range opts { + err := opt(options) + if err != nil { + return nil, err + } + } + return options, nil +} + +func KeyRenameOptions(opts ...KeyRenameOption) (*KeyRenameSettings, error) { + options := &KeyRenameSettings{ + Force: false, + } + + for _, opt := range opts { + err := opt(options) + if err != nil { + return nil, err + } + } + return options, nil +} + +type KeyOptions struct{} + +func (api *KeyOptions) WithAlgorithm(algorithm string) KeyGenerateOption { + return func(settings *KeyGenerateSettings) error { + settings.Algorithm = algorithm + return nil + } +} + +func (api *KeyOptions) WithSize(size int) KeyGenerateOption { + return func(settings *KeyGenerateSettings) error { + settings.Size = size + return nil + } +} + +func (api *KeyOptions) WithForce(force bool) KeyRenameOption { + return func(settings *KeyRenameSettings) error { + settings.Force = force + return nil + } +} diff --git a/core/coreiface/options/name.go b/core/coreiface/options/name.go new file mode 100644 index 000000000..aa2129162 --- /dev/null +++ b/core/coreiface/options/name.go @@ -0,0 +1,89 @@ +package options + +import ( + "time" +) + +type NamePublishSettings struct { + ValidTime time.Duration + Key string +} + +type NameResolveSettings struct { + Recursive bool + Local bool + Nocache bool +} + +type NamePublishOption func(*NamePublishSettings) error +type NameResolveOption func(*NameResolveSettings) error + +func NamePublishOptions(opts ...NamePublishOption) (*NamePublishSettings, error) { + options := &NamePublishSettings{ + ValidTime: 24 * time.Hour, + Key: "self", + } + + for _, opt := range opts { + err := opt(options) + if err != nil { + return nil, err + } + } + + return options, nil +} + +func NameResolveOptions(opts ...NameResolveOption) (*NameResolveSettings, error) { + options := &NameResolveSettings{ + Recursive: false, + Local: false, + Nocache: false, + } + + for _, opt := range opts { + err := opt(options) + if err != nil { + return nil, err + } + } + + return options, nil +} + +type NameOptions struct{} + +func (api *NameOptions) WithValidTime(validTime time.Duration) NamePublishOption { + return func(settings *NamePublishSettings) error { + settings.ValidTime = validTime + return nil + } +} + +func (api *NameOptions) WithKey(key string) NamePublishOption { + return func(settings *NamePublishSettings) error { + settings.Key = key + return nil + } +} + +func (api *NameOptions) WithRecursive(recursive bool) NameResolveOption { + return func(settings *NameResolveSettings) error { + settings.Recursive = recursive + return nil + } +} + +func (api *NameOptions) WithLocal(local bool) NameResolveOption { + return func(settings *NameResolveSettings) error { + settings.Local = local + return nil + } +} + +func (api *NameOptions) WithNoCache(nocache bool) NameResolveOption { + return func(settings *NameResolveSettings) error { + settings.Nocache = nocache + return nil + } +} From b92cca8429acecf498e37fd438df15a323e4c246 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 15 Dec 2017 01:03:53 +0100 Subject: [PATCH 0024/1212] coreapi: Documentation for Name/Key MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@74695ab9b4f2efc64b6a88fcd900fbd67a63b416 This commit was moved from ipfs/boxo@d733fa263ca5d8340684f8c062ef474000f54fe7 --- core/coreiface/interface.go | 47 +++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/core/coreiface/interface.go b/core/coreiface/interface.go index 36bd801a1..a861e4700 100644 --- a/core/coreiface/interface.go +++ b/core/coreiface/interface.go @@ -98,26 +98,73 @@ type DagAPI interface { WithDepth(depth int) options.DagTreeOption } +// NameAPI specifies the interface to IPNS. +// +// IPNS is a PKI namespace, where names are the hashes of public keys, and the +// private key enables publishing new (signed) values. In both publish and +// resolve, the default name used is the node's own PeerID, which is the hash of +// its public key. +// +// You can use .Key API to list and generate more names and their respective keys. type NameAPI interface { + // Publish announces new IPNS name Publish(ctx context.Context, path Path, opts ...options.NamePublishOption) (*IpnsEntry, error) + + // WithValidTime is an option for Publish which specifies for how long the + // entry will remain valid. Default value is 24h WithValidTime(validTime time.Duration) options.NamePublishOption + + // WithKey is an option for Publish which specifies the key to use for + // publishing. Default value is "self" which is the node's own PeerID. + // + // You can use .Key API to list and generate more names and their respective keys. WithKey(key string) options.NamePublishOption + // Resolve attempts to resolve the newest version of the specified name Resolve(ctx context.Context, name string, opts ...options.NameResolveOption) (Path, error) + + // WithRecursive is an option for Resolve which specifies whether to perform a + // recursive lookup. Default value is false WithRecursive(recursive bool) options.NameResolveOption + + // WithLocal is an option for Resolve which specifies if the lookup should be + // offline. Default value is false WithLocal(local bool) options.NameResolveOption + + // WithNoCache is an option for Resolve which specifies when set to true + // disables the use of local name cache. Default value is false WithNoCache(nocache bool) options.NameResolveOption } +// KeyAPI specifies the interface to Keystore type KeyAPI interface { + // Generate generates new key, stores it in the keystore under the specified + // name and returns a base58 encoded multihash of it's public key Generate(ctx context.Context, name string, opts ...options.KeyGenerateOption) (string, error) + + // WithAlgorithm is an option for Generate which specifies which algorithm + // should be used for the key. Default is "rsa" + // + // Supported algorithms: + // * rsa + // * ed25519 WithAlgorithm(algorithm string) options.KeyGenerateOption + + // WithSize is an option for Generate which specifies the size of the key to + // generated. Default is 0 WithSize(size int) options.KeyGenerateOption + // Rename renames oldName key to newName. Rename(ctx context.Context, oldName string, newName string, opts ...options.KeyRenameOption) (string, bool, error) + + // WithForce is an option for Rename which specifies whether to allow to + // replace existing keys. WithForce(force bool) options.KeyRenameOption + // List lists keys stored in keystore List(ctx context.Context) (map[string]string, error) //TODO: better key type? + + // Remove removes keys from keystore Remove(ctx context.Context, name string) (string, error) } From 1caf71766f81e4c950ed4d527b4c5933cdd53726 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Sun, 17 Dec 2017 03:44:13 +0100 Subject: [PATCH 0025/1212] coreapi: name/key review suggestions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@8f7e0241ec5a85f3acaf3152107bd9ad202f56a8 This commit was moved from ipfs/boxo@d0730a47d3a8d4e4be5cc9d1886b8b5a32816267 --- core/coreiface/interface.go | 45 ++++++++++++++++++++-------------- core/coreiface/options/key.go | 7 +++++- core/coreiface/options/name.go | 14 +++++++---- 3 files changed, 41 insertions(+), 25 deletions(-) diff --git a/core/coreiface/interface.go b/core/coreiface/interface.go index a861e4700..0086bd0d6 100644 --- a/core/coreiface/interface.go +++ b/core/coreiface/interface.go @@ -28,16 +28,21 @@ type Path interface { type Node ipld.Node type Link ipld.Link -type IpnsEntry struct { - Name string - Value Path -} - type Reader interface { io.ReadSeeker io.Closer } +type IpnsEntry interface { + Name() string + Value() Path +} + +type Key interface { + Name() string + Path() Path +} + // CoreAPI defines an unified interface to IPFS for Go programs. type CoreAPI interface { // Unixfs returns an implementation of Unixfs API @@ -108,7 +113,7 @@ type DagAPI interface { // You can use .Key API to list and generate more names and their respective keys. type NameAPI interface { // Publish announces new IPNS name - Publish(ctx context.Context, path Path, opts ...options.NamePublishOption) (*IpnsEntry, error) + Publish(ctx context.Context, path Path, opts ...options.NamePublishOption) (IpnsEntry, error) // WithValidTime is an option for Publish which specifies for how long the // entry will remain valid. Default value is 24h @@ -116,8 +121,9 @@ type NameAPI interface { // WithKey is an option for Publish which specifies the key to use for // publishing. Default value is "self" which is the node's own PeerID. + // The key parameter must be either PeerID or keystore key alias. // - // You can use .Key API to list and generate more names and their respective keys. + // You can use KeyAPI to list and generate more names and their respective keys. WithKey(key string) options.NamePublishOption // Resolve attempts to resolve the newest version of the specified name @@ -131,41 +137,42 @@ type NameAPI interface { // offline. Default value is false WithLocal(local bool) options.NameResolveOption - // WithNoCache is an option for Resolve which specifies when set to true - // disables the use of local name cache. Default value is false - WithNoCache(nocache bool) options.NameResolveOption + // WithCache is an option for Resolve which specifies if cache should be used. + // Default value is true + WithCache(cache bool) options.NameResolveOption } // KeyAPI specifies the interface to Keystore type KeyAPI interface { // Generate generates new key, stores it in the keystore under the specified // name and returns a base58 encoded multihash of it's public key - Generate(ctx context.Context, name string, opts ...options.KeyGenerateOption) (string, error) + Generate(ctx context.Context, name string, opts ...options.KeyGenerateOption) (Key, error) // WithAlgorithm is an option for Generate which specifies which algorithm - // should be used for the key. Default is "rsa" + // should be used for the key. Default is options.RSAKey // // Supported algorithms: - // * rsa - // * ed25519 + // * options.RSAKey + // * options.Ed25519Key WithAlgorithm(algorithm string) options.KeyGenerateOption // WithSize is an option for Generate which specifies the size of the key to // generated. Default is 0 WithSize(size int) options.KeyGenerateOption - // Rename renames oldName key to newName. - Rename(ctx context.Context, oldName string, newName string, opts ...options.KeyRenameOption) (string, bool, error) + // Rename renames oldName key to newName. Returns the key and whether another + // key was overwritten, or an error + Rename(ctx context.Context, oldName string, newName string, opts ...options.KeyRenameOption) (Key, bool, error) // WithForce is an option for Rename which specifies whether to allow to // replace existing keys. WithForce(force bool) options.KeyRenameOption // List lists keys stored in keystore - List(ctx context.Context) (map[string]string, error) //TODO: better key type? + List(ctx context.Context) ([]Key, error) - // Remove removes keys from keystore - Remove(ctx context.Context, name string) (string, error) + // Remove removes keys from keystore. Returns ipns path of the removed key + Remove(ctx context.Context, name string) (Path, error) } // type ObjectAPI interface { diff --git a/core/coreiface/options/key.go b/core/coreiface/options/key.go index 5ed7b408f..c84f0f8f8 100644 --- a/core/coreiface/options/key.go +++ b/core/coreiface/options/key.go @@ -1,5 +1,10 @@ package options +const ( + RSAKey = "rsa" + Ed25519Key = "ed25519" +) + type KeyGenerateSettings struct { Algorithm string Size int @@ -14,7 +19,7 @@ type KeyRenameOption func(*KeyRenameSettings) error func KeyGenerateOptions(opts ...KeyGenerateOption) (*KeyGenerateSettings, error) { options := &KeyGenerateSettings{ - Algorithm: "rsa", + Algorithm: RSAKey, Size: 0, } diff --git a/core/coreiface/options/name.go b/core/coreiface/options/name.go index aa2129162..9f8aaafc8 100644 --- a/core/coreiface/options/name.go +++ b/core/coreiface/options/name.go @@ -4,6 +4,10 @@ import ( "time" ) +const ( + DefaultNameValidTime = 24 * time.Hour +) + type NamePublishSettings struct { ValidTime time.Duration Key string @@ -12,7 +16,7 @@ type NamePublishSettings struct { type NameResolveSettings struct { Recursive bool Local bool - Nocache bool + Cache bool } type NamePublishOption func(*NamePublishSettings) error @@ -20,7 +24,7 @@ type NameResolveOption func(*NameResolveSettings) error func NamePublishOptions(opts ...NamePublishOption) (*NamePublishSettings, error) { options := &NamePublishSettings{ - ValidTime: 24 * time.Hour, + ValidTime: DefaultNameValidTime, Key: "self", } @@ -38,7 +42,7 @@ func NameResolveOptions(opts ...NameResolveOption) (*NameResolveSettings, error) options := &NameResolveSettings{ Recursive: false, Local: false, - Nocache: false, + Cache: true, } for _, opt := range opts { @@ -81,9 +85,9 @@ func (api *NameOptions) WithLocal(local bool) NameResolveOption { } } -func (api *NameOptions) WithNoCache(nocache bool) NameResolveOption { +func (api *NameOptions) WithCache(cache bool) NameResolveOption { return func(settings *NameResolveSettings) error { - settings.Nocache = nocache + settings.Cache = cache return nil } } From 89776d9be77cc98652446551a29bcce5b4aba89c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 1 Jan 2018 18:59:07 +0100 Subject: [PATCH 0026/1212] coreapi: key tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@ed5f040416bbc6a72008cf3c9f299c47da6f42f1 This commit was moved from ipfs/boxo@6527d6e06318ce93a01a40d769225f9ad4fce6b2 --- core/coreiface/interface.go | 6 +++--- core/coreiface/options/key.go | 6 ++++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/core/coreiface/interface.go b/core/coreiface/interface.go index 0086bd0d6..dc8365669 100644 --- a/core/coreiface/interface.go +++ b/core/coreiface/interface.go @@ -148,13 +148,13 @@ type KeyAPI interface { // name and returns a base58 encoded multihash of it's public key Generate(ctx context.Context, name string, opts ...options.KeyGenerateOption) (Key, error) - // WithAlgorithm is an option for Generate which specifies which algorithm + // WithType is an option for Generate which specifies which algorithm // should be used for the key. Default is options.RSAKey // - // Supported algorithms: + // Supported key types: // * options.RSAKey // * options.Ed25519Key - WithAlgorithm(algorithm string) options.KeyGenerateOption + WithType(algorithm string) options.KeyGenerateOption // WithSize is an option for Generate which specifies the size of the key to // generated. Default is 0 diff --git a/core/coreiface/options/key.go b/core/coreiface/options/key.go index c84f0f8f8..114361875 100644 --- a/core/coreiface/options/key.go +++ b/core/coreiface/options/key.go @@ -3,6 +3,8 @@ package options const ( RSAKey = "rsa" Ed25519Key = "ed25519" + + DefaultRSALen = 2048 ) type KeyGenerateSettings struct { @@ -20,7 +22,7 @@ type KeyRenameOption func(*KeyRenameSettings) error func KeyGenerateOptions(opts ...KeyGenerateOption) (*KeyGenerateSettings, error) { options := &KeyGenerateSettings{ Algorithm: RSAKey, - Size: 0, + Size: -1, } for _, opt := range opts { @@ -48,7 +50,7 @@ func KeyRenameOptions(opts ...KeyRenameOption) (*KeyRenameSettings, error) { type KeyOptions struct{} -func (api *KeyOptions) WithAlgorithm(algorithm string) KeyGenerateOption { +func (api *KeyOptions) WithType(algorithm string) KeyGenerateOption { return func(settings *KeyGenerateSettings) error { settings.Algorithm = algorithm return nil From ef926cb0e353d66321a5bc364c53b9adc2b7800b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 2 Jan 2018 00:53:48 +0100 Subject: [PATCH 0027/1212] coreapi: Name tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@d28b9301ac2ca1a9e209680ba5bb613f19cbb6fe This commit was moved from ipfs/boxo@78823e7ccbdc16b651c269f86e4cf5915144250a --- core/coreiface/interface.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/core/coreiface/interface.go b/core/coreiface/interface.go index dc8365669..cdbb2508b 100644 --- a/core/coreiface/interface.go +++ b/core/coreiface/interface.go @@ -157,7 +157,10 @@ type KeyAPI interface { WithType(algorithm string) options.KeyGenerateOption // WithSize is an option for Generate which specifies the size of the key to - // generated. Default is 0 + // generated. Default is -1 + // + // value of -1 means 'use default size for key type': + // * 2048 for RSA WithSize(size int) options.KeyGenerateOption // Rename renames oldName key to newName. Returns the key and whether another From 4124018bc2dbec4efc870ce6046e941bc8987fc3 Mon Sep 17 00:00:00 2001 From: ForrestWeston Date: Mon, 22 Jan 2018 14:44:46 -0800 Subject: [PATCH 0028/1212] interface docs for coreapi interface License: MIT Signed-off-by: ForrestWeston This commit was moved from ipfs/interface-go-ipfs-core@2c3137f0557f44ca23730ff134b38b9426731e56 This commit was moved from ipfs/boxo@4d4c3dc176859461010b576f9af66919f34aaed3 --- core/coreiface/interface.go | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/core/coreiface/interface.go b/core/coreiface/interface.go index cdbb2508b..720f935e2 100644 --- a/core/coreiface/interface.go +++ b/core/coreiface/interface.go @@ -17,9 +17,13 @@ import ( // Path is a generic wrapper for paths used in the API. A path can be resolved // to a CID using one of Resolve functions in the API. type Path interface { + // String returns the path as a string. String() string + // Cid returns cid referred to by path Cid() *cid.Cid + // Root returns cid of root path Root() *cid.Cid + // Resolved returns whether path has been fully resolved Resolved() bool } @@ -33,22 +37,31 @@ type Reader interface { io.Closer } +// IpnsEntry specifies the interface to IpnsEntries type IpnsEntry interface { + // Name returns IpnsEntry name Name() string + // Value returns IpnsEntry value Value() Path } +// Key specifies the interface to Keys in KeyAPI Keystore type Key interface { + // Key returns key name Name() string + // Path returns key path Path() Path } // CoreAPI defines an unified interface to IPFS for Go programs. type CoreAPI interface { - // Unixfs returns an implementation of Unixfs API + // Unixfs returns an implementation of Unixfs API. Unixfs() UnixfsAPI + // Dag returns an implementation of Dag API. Dag() DagAPI + // Name returns an implementation of Name API. Name() NameAPI + // Key returns an implementation of Key API. Key() KeyAPI // ResolvePath resolves the path using Unixfs resolver From 4727b6e77612b3a2534f77853c113856be0a1842 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Wed, 24 Jan 2018 15:55:28 -0800 Subject: [PATCH 0029/1212] gx: mass update License: MIT Signed-off-by: Steven Allen This commit was moved from ipfs/interface-go-ipfs-core@318e958cdd426798e644612d76dc294463975f71 This commit was moved from ipfs/boxo@5e7d211f6eb13d87e9a47729d28beb2a4250aa14 --- core/coreiface/interface.go | 4 ++-- core/coreiface/options/dag.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/core/coreiface/interface.go b/core/coreiface/interface.go index 720f935e2..6e00d51ab 100644 --- a/core/coreiface/interface.go +++ b/core/coreiface/interface.go @@ -10,8 +10,8 @@ import ( options "github.com/ipfs/go-ipfs/core/coreapi/interface/options" - ipld "gx/ipfs/QmNwUEK7QbwSqyKBu3mMtToo8SUc6wQJ7gdZq4gGGJqfnf/go-ipld-format" - cid "gx/ipfs/QmeSrf6pzut73u6zLQkRFQ3ygt3k6XFT2kjdYP8Tnkwwyg/go-cid" + cid "gx/ipfs/QmcZfnkapfECQGcLZaf9B79NRg7cRa9EnZh4LSbkCzwNvY/go-cid" + ipld "gx/ipfs/Qme5bWv7wtjUNGsK2BNGVUFPKiuxWrsqrtvYwCLRw8YFES/go-ipld-format" ) // Path is a generic wrapper for paths used in the API. A path can be resolved diff --git a/core/coreiface/options/dag.go b/core/coreiface/options/dag.go index 7850c4bc3..b56fcd81a 100644 --- a/core/coreiface/options/dag.go +++ b/core/coreiface/options/dag.go @@ -3,7 +3,7 @@ package options import ( "math" - cid "gx/ipfs/QmeSrf6pzut73u6zLQkRFQ3ygt3k6XFT2kjdYP8Tnkwwyg/go-cid" + cid "gx/ipfs/QmcZfnkapfECQGcLZaf9B79NRg7cRa9EnZh4LSbkCzwNvY/go-cid" ) type DagPutSettings struct { From 9f5914daf7841d111ce090c3214a39035e653261 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 14 Dec 2017 23:55:24 +0100 Subject: [PATCH 0030/1212] coreapi: Basic object API implementation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@52f5b7ce1f8cc0503ec9d9ce070afdee7997049c This commit was moved from ipfs/boxo@f10a09d9b25f8ec1a43f7e93f9fe182ca5ef82ff --- core/coreiface/interface.go | 42 +++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/core/coreiface/interface.go b/core/coreiface/interface.go index 720f935e2..2c31d01b1 100644 --- a/core/coreiface/interface.go +++ b/core/coreiface/interface.go @@ -191,27 +191,29 @@ type KeyAPI interface { Remove(ctx context.Context, name string) (Path, error) } -// type ObjectAPI interface { -// New() (cid.Cid, Object) -// Get(string) (Object, error) -// Links(string) ([]*Link, error) -// Data(string) (Reader, error) -// Stat(string) (ObjectStat, error) -// Put(Object) (cid.Cid, error) -// SetData(string, Reader) (cid.Cid, error) -// AppendData(string, Data) (cid.Cid, error) -// AddLink(string, string, string) (cid.Cid, error) -// RmLink(string, string) (cid.Cid, error) -// } +//TODO: Should this use paths instead of cids? +type ObjectAPI interface { + New(ctx context.Context) (Node, error) + Put(context.Context, Node) error + Get(context.Context, Path) (Node, error) + Data(context.Context, Path) (io.Reader, error) + Links(context.Context, Path) ([]*Link, error) + Stat(context.Context, Path) (*ObjectStat, error) -// type ObjectStat struct { -// Cid cid.Cid -// NumLinks int -// BlockSize int -// LinksSize int -// DataSize int -// CumulativeSize int -// } + AddLink(ctx context.Context, base Path, name string, child Path, create bool) (Node, error) //TODO: make create optional + RmLink(context.Context, Path, string) (Node, error) + AppendData(context.Context, Path, io.Reader) (Node, error) + SetData(context.Context, Path, io.Reader) (Node, error) +} + +type ObjectStat struct { + Cid *cid.Cid + NumLinks int + BlockSize int + LinksSize int + DataSize int + CumulativeSize int +} var ErrIsDir = errors.New("object is a directory") var ErrOffline = errors.New("can't resolve, ipfs node is offline") From b031da2463b9041ca7d09064746067a69b8ae7f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 22 Dec 2017 17:22:53 +0100 Subject: [PATCH 0031/1212] coreapi: Object api review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@3b4b26deb1bc75aefe85df809afca5e3e09f71c6 This commit was moved from ipfs/boxo@85688ca1e91bcfa3cc7441142e5391b760b2b43c --- core/coreiface/interface.go | 10 ++++-- core/coreiface/options/object.go | 56 ++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 3 deletions(-) create mode 100644 core/coreiface/options/object.go diff --git a/core/coreiface/interface.go b/core/coreiface/interface.go index 2c31d01b1..db993a5c3 100644 --- a/core/coreiface/interface.go +++ b/core/coreiface/interface.go @@ -193,14 +193,18 @@ type KeyAPI interface { //TODO: Should this use paths instead of cids? type ObjectAPI interface { - New(ctx context.Context) (Node, error) - Put(context.Context, Node) error + New(context.Context, ...options.ObjectNewOption) (Node, error) + WithType(string) options.ObjectNewOption + + Put(context.Context, Node) (Path, error) Get(context.Context, Path) (Node, error) Data(context.Context, Path) (io.Reader, error) Links(context.Context, Path) ([]*Link, error) Stat(context.Context, Path) (*ObjectStat, error) - AddLink(ctx context.Context, base Path, name string, child Path, create bool) (Node, error) //TODO: make create optional + AddLink(ctx context.Context, base Path, name string, child Path, opts ...options.ObjectAddLinkOption) (Node, error) + WithCreate(create bool) options.ObjectAddLinkOption + RmLink(context.Context, Path, string) (Node, error) AppendData(context.Context, Path, io.Reader) (Node, error) SetData(context.Context, Path, io.Reader) (Node, error) diff --git a/core/coreiface/options/object.go b/core/coreiface/options/object.go new file mode 100644 index 000000000..6a144ab2b --- /dev/null +++ b/core/coreiface/options/object.go @@ -0,0 +1,56 @@ +package options + +type ObjectNewSettings struct { + Type string +} + +type ObjectAddLinkSettings struct { + Create bool +} + +type ObjectNewOption func(*ObjectNewSettings) error +type ObjectAddLinkOption func(*ObjectAddLinkSettings) error + +func ObjectNewOptions(opts ...ObjectNewOption) (*ObjectNewSettings, error) { + options := &ObjectNewSettings{ + Type: "empty", + } + + for _, opt := range opts { + err := opt(options) + if err != nil { + return nil, err + } + } + return options, nil +} + +func ObjectAddLinkOptions(opts ...ObjectAddLinkOption) (*ObjectAddLinkSettings, error) { + options := &ObjectAddLinkSettings{ + Create: false, + } + + for _, opt := range opts { + err := opt(options) + if err != nil { + return nil, err + } + } + return options, nil +} + +type ObjectOptions struct{} + +func (api *ObjectOptions) WithType(t string) ObjectNewOption { + return func(settings *ObjectNewSettings) error { + settings.Type = t + return nil + } +} + +func (api *ObjectOptions) WithCreate(create bool) ObjectAddLinkOption { + return func(settings *ObjectAddLinkSettings) error { + settings.Create = create + return nil + } +} From a806b175fa13ec957955c7678a8165d6c1ef25fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 2 Jan 2018 21:22:20 +0100 Subject: [PATCH 0032/1212] coreapi: object docs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@55c56578038a9e748aa996f7f9cb7dc1b546f1ac This commit was moved from ipfs/boxo@36545a88bcc2f636493de49939e8105d7fd1977c --- core/coreiface/interface.go | 55 ++++++++++++++++++++++++++++++++----- 1 file changed, 48 insertions(+), 7 deletions(-) diff --git a/core/coreiface/interface.go b/core/coreiface/interface.go index db993a5c3..7809c8b99 100644 --- a/core/coreiface/interface.go +++ b/core/coreiface/interface.go @@ -191,31 +191,72 @@ type KeyAPI interface { Remove(ctx context.Context, name string) (Path, error) } -//TODO: Should this use paths instead of cids? +// ObjectAPI specifies the interface to MerkleDAG and contains useful utilities +// for manipulating MerkleDAG data structures. type ObjectAPI interface { + // New creates new, empty (by default) dag-node. New(context.Context, ...options.ObjectNewOption) (Node, error) + + // WithType is an option for New which allows to change the type of created + // dag node. + // + // Supported types: + // * 'empty' - Empty node + // * 'unixfs-dir' - Empty UnixFS directory WithType(string) options.ObjectNewOption + // Put imports the node into merkledag Put(context.Context, Node) (Path, error) + + // Get returns the node for the path Get(context.Context, Path) (Node, error) + + // Data returns reader for data of the node Data(context.Context, Path) (io.Reader, error) + + // Links returns lint or links the node contains Links(context.Context, Path) ([]*Link, error) + + // Stat returns information about the node Stat(context.Context, Path) (*ObjectStat, error) + // AddLink adds a link under the specified path. child path can point to a + // subdirectory within the patent which must be present (can be overridden + // with WithCreate option). AddLink(ctx context.Context, base Path, name string, child Path, opts ...options.ObjectAddLinkOption) (Node, error) + + // WithCreate is an option for AddLink which specifies whether create required + // directories for the child WithCreate(create bool) options.ObjectAddLinkOption - RmLink(context.Context, Path, string) (Node, error) + // RmLink removes a link from the node + RmLink(ctx context.Context, base Path, link string) (Node, error) + + // AppendData appends data to the node AppendData(context.Context, Path, io.Reader) (Node, error) + + // SetData sets the data contained in the node SetData(context.Context, Path, io.Reader) (Node, error) } +// ObjectStat provides information about dag nodes type ObjectStat struct { - Cid *cid.Cid - NumLinks int - BlockSize int - LinksSize int - DataSize int + // Cid is the CID of the node + Cid *cid.Cid + + // NumLinks is number of links the node contains + NumLinks int + + // BlockSize is size of the raw serialized node + BlockSize int + + // LinksSize is size of the links block section + LinksSize int + + // DataSize is the size of data block section + DataSize int + + // CumulativeSize is size of node CumulativeSize int } From 540ec53bf8308b9b45d1ebbfc6e23d775ec779f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 4 Jan 2018 17:20:16 +0100 Subject: [PATCH 0033/1212] coreapi: implement object.Put MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@104bc87d13e259e45b68c3d00231e140a7b88fb6 This commit was moved from ipfs/boxo@8162a16f7c173b07fa645d5a20121f1ad29e5198 --- core/coreiface/interface.go | 15 +++++++++++++-- core/coreiface/options/object.go | 26 ++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/core/coreiface/interface.go b/core/coreiface/interface.go index 7809c8b99..3e0e3d460 100644 --- a/core/coreiface/interface.go +++ b/core/coreiface/interface.go @@ -64,6 +64,9 @@ type CoreAPI interface { // Key returns an implementation of Key API. Key() KeyAPI + // ObjectAPI returns an implementation of Object API + Object() ObjectAPI + // ResolvePath resolves the path using Unixfs resolver ResolvePath(context.Context, Path) (Path, error) @@ -205,8 +208,16 @@ type ObjectAPI interface { // * 'unixfs-dir' - Empty UnixFS directory WithType(string) options.ObjectNewOption - // Put imports the node into merkledag - Put(context.Context, Node) (Path, error) + // Put imports the data into merkledag + Put(context.Context, io.Reader, ...options.ObjectPutOption) (Path, error) + + // WithInputEnc is an option for Put which specifies the input encoding of the + // data. Default is "json". + // + // Supported encodings: + // * "protobuf" + // * "json" + WithInputEnc(e string) options.ObjectPutOption // Get returns the node for the path Get(context.Context, Path) (Node, error) diff --git a/core/coreiface/options/object.go b/core/coreiface/options/object.go index 6a144ab2b..fe86a1cde 100644 --- a/core/coreiface/options/object.go +++ b/core/coreiface/options/object.go @@ -4,11 +4,16 @@ type ObjectNewSettings struct { Type string } +type ObjectPutSettings struct { + InputEnc string +} + type ObjectAddLinkSettings struct { Create bool } type ObjectNewOption func(*ObjectNewSettings) error +type ObjectPutOption func(*ObjectPutSettings) error type ObjectAddLinkOption func(*ObjectAddLinkSettings) error func ObjectNewOptions(opts ...ObjectNewOption) (*ObjectNewSettings, error) { @@ -25,6 +30,20 @@ func ObjectNewOptions(opts ...ObjectNewOption) (*ObjectNewSettings, error) { return options, nil } +func ObjectPutOptions(opts ...ObjectPutOption) (*ObjectPutSettings, error) { + options := &ObjectPutSettings{ + InputEnc: "json", + } + + for _, opt := range opts { + err := opt(options) + if err != nil { + return nil, err + } + } + return options, nil +} + func ObjectAddLinkOptions(opts ...ObjectAddLinkOption) (*ObjectAddLinkSettings, error) { options := &ObjectAddLinkSettings{ Create: false, @@ -48,6 +67,13 @@ func (api *ObjectOptions) WithType(t string) ObjectNewOption { } } +func (api *ObjectOptions) WithInputEnc(e string) ObjectPutOption { + return func(settings *ObjectPutSettings) error { + settings.InputEnc = e + return nil + } +} + func (api *ObjectOptions) WithCreate(create bool) ObjectAddLinkOption { return func(settings *ObjectAddLinkSettings) error { settings.Create = create From a8a84d5b1bc8125a5113e80b994193e8f3fab9de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 5 Jan 2018 01:13:07 +0100 Subject: [PATCH 0034/1212] coreapi: object API tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@858d49b07c296b36a58fa4d4469f5e08a9f9b5e7 This commit was moved from ipfs/boxo@d878d812272fc70b7e3e799f139056885dab474f --- core/coreiface/interface.go | 18 +++++++++++++----- core/coreiface/options/object.go | 9 +++++++++ 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/core/coreiface/interface.go b/core/coreiface/interface.go index 3e0e3d460..9dca7f3c9 100644 --- a/core/coreiface/interface.go +++ b/core/coreiface/interface.go @@ -219,6 +219,14 @@ type ObjectAPI interface { // * "json" WithInputEnc(e string) options.ObjectPutOption + // WithDataType specifies the encoding of data field when using Josn or XML + // input encoding. + // + // Supported types: + // * "text" (default) + // * "base64" + WithDataType(t string) options.ObjectPutOption + // Get returns the node for the path Get(context.Context, Path) (Node, error) @@ -234,20 +242,20 @@ type ObjectAPI interface { // AddLink adds a link under the specified path. child path can point to a // subdirectory within the patent which must be present (can be overridden // with WithCreate option). - AddLink(ctx context.Context, base Path, name string, child Path, opts ...options.ObjectAddLinkOption) (Node, error) + AddLink(ctx context.Context, base Path, name string, child Path, opts ...options.ObjectAddLinkOption) (Path, error) // WithCreate is an option for AddLink which specifies whether create required // directories for the child WithCreate(create bool) options.ObjectAddLinkOption // RmLink removes a link from the node - RmLink(ctx context.Context, base Path, link string) (Node, error) + RmLink(ctx context.Context, base Path, link string) (Path, error) // AppendData appends data to the node - AppendData(context.Context, Path, io.Reader) (Node, error) + AppendData(context.Context, Path, io.Reader) (Path, error) // SetData sets the data contained in the node - SetData(context.Context, Path, io.Reader) (Node, error) + SetData(context.Context, Path, io.Reader) (Path, error) } // ObjectStat provides information about dag nodes @@ -267,7 +275,7 @@ type ObjectStat struct { // DataSize is the size of data block section DataSize int - // CumulativeSize is size of node + // CumulativeSize is size of the tree (BlockSize + link sizes) CumulativeSize int } diff --git a/core/coreiface/options/object.go b/core/coreiface/options/object.go index fe86a1cde..9c8c9a9dd 100644 --- a/core/coreiface/options/object.go +++ b/core/coreiface/options/object.go @@ -6,6 +6,7 @@ type ObjectNewSettings struct { type ObjectPutSettings struct { InputEnc string + DataType string } type ObjectAddLinkSettings struct { @@ -33,6 +34,7 @@ func ObjectNewOptions(opts ...ObjectNewOption) (*ObjectNewSettings, error) { func ObjectPutOptions(opts ...ObjectPutOption) (*ObjectPutSettings, error) { options := &ObjectPutSettings{ InputEnc: "json", + DataType: "text", } for _, opt := range opts { @@ -74,6 +76,13 @@ func (api *ObjectOptions) WithInputEnc(e string) ObjectPutOption { } } +func (api *ObjectOptions) WithDataType(t string) ObjectPutOption { + return func(settings *ObjectPutSettings) error { + settings.DataType = t + return nil + } +} + func (api *ObjectOptions) WithCreate(create bool) ObjectAddLinkOption { return func(settings *ObjectAddLinkSettings) error { settings.Create = create From c56118567677371082f7ff08a2556b101a887b06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 5 Jan 2018 01:50:14 +0100 Subject: [PATCH 0035/1212] coreapi: draft block API MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@3cd2995b5bd80584d23ba16037045558a17d04b9 This commit was moved from ipfs/boxo@3a525b897573cdf1e8d493d004e6b9623f07527b --- core/coreiface/interface.go | 18 ++++++++++++++++++ core/coreiface/options/block.go | 14 ++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 core/coreiface/options/block.go diff --git a/core/coreiface/interface.go b/core/coreiface/interface.go index ddcdc8db6..147a85412 100644 --- a/core/coreiface/interface.go +++ b/core/coreiface/interface.go @@ -53,6 +53,11 @@ type Key interface { Path() Path } +type BlockStat interface { + Size() int + Path() Path +} + // CoreAPI defines an unified interface to IPFS for Go programs. type CoreAPI interface { // Unixfs returns an implementation of Unixfs API. @@ -87,6 +92,19 @@ type UnixfsAPI interface { Ls(context.Context, Path) ([]*Link, error) } +type BlockAPI interface { + Put(context.Context, io.Reader) (Path, error) + WithCodec(codec uint64) options.BlockPutOption + WithHash(mhType uint64, mhLen int) options.BlockPutOption + + Get(context.Context) (io.Reader, error) + + Rm(context.Context) error + WithForce(force bool) options.BlockRmOption + + Stat(context.Context) (BlockStat, error) +} + // DagAPI specifies the interface to IPLD type DagAPI interface { // Put inserts data using specified format and input encoding. diff --git a/core/coreiface/options/block.go b/core/coreiface/options/block.go new file mode 100644 index 000000000..e2473e3f7 --- /dev/null +++ b/core/coreiface/options/block.go @@ -0,0 +1,14 @@ +package options + +type BlockPutSettings struct { + Codec uint64 + MhType uint64 + MhLength int +} + +type BlockRmSettings struct { + Force bool +} + +type BlockPutOption func(*BlockPutSettings) error +type BlockRmOption func(*BlockRmSettings) error From 6b6fdcde60d8198b343e0449533a3fa3e306cff0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Sat, 6 Jan 2018 16:57:41 +0100 Subject: [PATCH 0036/1212] coreapi: implement block API MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@a7509ebfcac3b153716fc1d2cf4bf021d8ece1b5 This commit was moved from ipfs/boxo@bfcc5b4d08e6efbcfb31f0551db2630613b94b49 --- core/coreiface/interface.go | 12 ++++--- core/coreiface/options/block.go | 61 ++++++++++++++++++++++++++++++++- 2 files changed, 67 insertions(+), 6 deletions(-) diff --git a/core/coreiface/interface.go b/core/coreiface/interface.go index 147a85412..bbe544344 100644 --- a/core/coreiface/interface.go +++ b/core/coreiface/interface.go @@ -62,6 +62,8 @@ type BlockStat interface { type CoreAPI interface { // Unixfs returns an implementation of Unixfs API. Unixfs() UnixfsAPI + // Block returns an implementation of Block API. + Block() BlockAPI // Dag returns an implementation of Dag API. Dag() DagAPI // Name returns an implementation of Name API. @@ -93,16 +95,16 @@ type UnixfsAPI interface { } type BlockAPI interface { - Put(context.Context, io.Reader) (Path, error) - WithCodec(codec uint64) options.BlockPutOption + Put(context.Context, io.Reader, ...options.BlockPutOption) (Path, error) + WithFormat(codec string) options.BlockPutOption WithHash(mhType uint64, mhLen int) options.BlockPutOption - Get(context.Context) (io.Reader, error) + Get(context.Context, Path) (io.Reader, error) - Rm(context.Context) error + Rm(context.Context, Path, ...options.BlockRmOption) error WithForce(force bool) options.BlockRmOption - Stat(context.Context) (BlockStat, error) + Stat(context.Context, Path) (BlockStat, error) } // DagAPI specifies the interface to IPLD diff --git a/core/coreiface/options/block.go b/core/coreiface/options/block.go index e2473e3f7..7e6ad3230 100644 --- a/core/coreiface/options/block.go +++ b/core/coreiface/options/block.go @@ -1,7 +1,12 @@ package options +import ( + //cid "gx/ipfs/QmeSrf6pzut73u6zLQkRFQ3ygt3k6XFT2kjdYP8Tnkwwyg/go-cid" + "gx/ipfs/QmYeKnKpubCMRiq3PGZcTREErthbb5Q9cXsCoSkD9bjEBd/go-multihash" +) + type BlockPutSettings struct { - Codec uint64 + Codec string MhType uint64 MhLength int } @@ -12,3 +17,57 @@ type BlockRmSettings struct { type BlockPutOption func(*BlockPutSettings) error type BlockRmOption func(*BlockRmSettings) error + +func BlockPutOptions(opts ...BlockPutOption) (*BlockPutSettings, error) { + options := &BlockPutSettings{ + Codec: "v0", + MhType: multihash.SHA2_256, + MhLength: -1, + } + + for _, opt := range opts { + err := opt(options) + if err != nil { + return nil, err + } + } + return options, nil +} + +func BlockRmOptions(opts ...BlockRmOption) (*BlockRmSettings, error) { + options := &BlockRmSettings{ + Force: false, + } + + for _, opt := range opts { + err := opt(options) + if err != nil { + return nil, err + } + } + return options, nil +} + +type BlockOptions struct{} + +func (api *BlockOptions) WithFormat(codec string) BlockPutOption { + return func(settings *BlockPutSettings) error { + settings.Codec = codec + return nil + } +} + +func (api *BlockOptions) WithHash(mhType uint64, mhLen int) BlockPutOption { + return func(settings *BlockPutSettings) error { + settings.MhType = mhType + settings.MhLength = mhLen + return nil + } +} + +func (api *BlockOptions) WithForce(force bool) BlockRmOption { + return func(settings *BlockRmSettings) error { + settings.Force = force + return nil + } +} From 3615341299acfa25c0061a7afaf60339dc596913 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Sat, 6 Jan 2018 17:13:33 +0100 Subject: [PATCH 0037/1212] corapi: block docs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@1ffde91c6cc373e97ed28eb80ad3fb9ddf5103e1 This commit was moved from ipfs/boxo@db1f6da007f8c3d45668459b81d4b99559b0cea7 --- core/coreiface/interface.go | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/core/coreiface/interface.go b/core/coreiface/interface.go index bbe544344..2402ecf81 100644 --- a/core/coreiface/interface.go +++ b/core/coreiface/interface.go @@ -94,16 +94,35 @@ type UnixfsAPI interface { Ls(context.Context, Path) ([]*Link, error) } +// BlockAPI specifies the interface to the block layer type BlockAPI interface { + // Put imports raw block data, hashing it using specified settings. Put(context.Context, io.Reader, ...options.BlockPutOption) (Path, error) + + // WithFormat is an option for Put which specifies the multicodec to use to + // serialize the object. Default is "v0" WithFormat(codec string) options.BlockPutOption + + // WithHash is an option for Put which specifies the multihash settings to use + // when hashing the object. Default is mh.SHA2_256 (0x12). + // If mhLen is set to -1, default length for the hash will be used WithHash(mhType uint64, mhLen int) options.BlockPutOption + // Get attempts to resolve the path and return a reader for data in the block Get(context.Context, Path) (io.Reader, error) + // Rm removes the block specified by the path from local blockstore. + // By default an error will be returned if the block can't be found locally. + // + // NOTE: If the specified block is pinned it won't be removed and no error + // will be returned Rm(context.Context, Path, ...options.BlockRmOption) error + + // WithForce is an option for Rm which, when set to true, will ignore + // non-existing blocks WithForce(force bool) options.BlockRmOption + // Stat returns information on Stat(context.Context, Path) (BlockStat, error) } From b47c82f3c79aa8bcfae27c7f022f62e5362a0b56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 31 Jan 2018 00:34:51 +0100 Subject: [PATCH 0038/1212] coreapi: update block after update MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@bf7867a20c4aed75aead015b6c720b16645e9626 This commit was moved from ipfs/boxo@72b62f5f64893169686ccb5569f41545c3ba8c67 --- core/coreiface/interface.go | 4 ++++ core/coreiface/options/block.go | 3 +-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/core/coreiface/interface.go b/core/coreiface/interface.go index 2402ecf81..95351e7d0 100644 --- a/core/coreiface/interface.go +++ b/core/coreiface/interface.go @@ -62,12 +62,16 @@ type BlockStat interface { type CoreAPI interface { // Unixfs returns an implementation of Unixfs API. Unixfs() UnixfsAPI + // Block returns an implementation of Block API. Block() BlockAPI + // Dag returns an implementation of Dag API. Dag() DagAPI + // Name returns an implementation of Name API. Name() NameAPI + // Key returns an implementation of Key API. Key() KeyAPI diff --git a/core/coreiface/options/block.go b/core/coreiface/options/block.go index 7e6ad3230..bbb14612f 100644 --- a/core/coreiface/options/block.go +++ b/core/coreiface/options/block.go @@ -1,8 +1,7 @@ package options import ( - //cid "gx/ipfs/QmeSrf6pzut73u6zLQkRFQ3ygt3k6XFT2kjdYP8Tnkwwyg/go-cid" - "gx/ipfs/QmYeKnKpubCMRiq3PGZcTREErthbb5Q9cXsCoSkD9bjEBd/go-multihash" + "gx/ipfs/QmZyZDi491cCNTLfAhwcaDii2Kg4pwKRkhqQzURGDvY6ua/go-multihash" ) type BlockPutSettings struct { From 9e02119ee9a6281648fd71aa658a0eaf4a04f341 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 9 Jan 2018 01:10:03 +0100 Subject: [PATCH 0039/1212] coreapi: pin draft MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@b3293937f6e9b665c70038d40b304844fd015930 This commit was moved from ipfs/boxo@7b5b64eefb105adf64cc51224ea381a15239767a --- core/coreiface/interface.go | 44 ++++++++++++++++++++++++++ core/coreiface/options/pin.go | 58 +++++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+) create mode 100644 core/coreiface/options/pin.go diff --git a/core/coreiface/interface.go b/core/coreiface/interface.go index 95351e7d0..40fa4131e 100644 --- a/core/coreiface/interface.go +++ b/core/coreiface/interface.go @@ -58,6 +58,15 @@ type BlockStat interface { Path() Path } +// Pin holds information about pinned resource +type Pin interface { + // Path to the pinned object + Path() Path + + // Type of the pin + Type() string +} + // CoreAPI defines an unified interface to IPFS for Go programs. type CoreAPI interface { // Unixfs returns an implementation of Unixfs API. @@ -322,5 +331,40 @@ type ObjectStat struct { CumulativeSize int } +// PinAPI specifies the interface to pining +type PinAPI interface { + // Add creates new pin, be default recursive - pinning the whole referenced + // tree + Add(context.Context, Path, ...options.PinAddOption) error + + // WithRecursive is an option for Add which specifies whether to pin an entire + // object tree or just one object. Default: true + WithRecursive(bool) options.PinAddOption + + // Ls returns list of pinned objects on this node + Ls(context.Context) ([]Pin, error) + + // WithType is an option for Ls which allows to specify which pin types should + // be returned + // + // Supported values: + // * "direct" - directly pinned objects + // * "recursive" - roots of recursive pins + // * "indirect" - indirectly pinned objects (referenced by recursively pinned + // objects) + // * "all" - all pinned objects (default) + WithType(string) options.PinLsOption + + // Rm removes pin for object specified by the path + Rm(context.Context, Path) error + + // Update changes one pin to another, skipping checks for matching paths in + // the old tree + Update(ctx context.Context, from Path, to Path) error + + // Verify verifies the integrity of pinned objects + Verify(context.Context) error +} + var ErrIsDir = errors.New("object is a directory") var ErrOffline = errors.New("can't resolve, ipfs node is offline") diff --git a/core/coreiface/options/pin.go b/core/coreiface/options/pin.go new file mode 100644 index 000000000..4ad16d555 --- /dev/null +++ b/core/coreiface/options/pin.go @@ -0,0 +1,58 @@ +package options + +type PinAddSettings struct { + Recursive bool +} + +type PinLsSettings struct { + Type string +} + +type PinAddOption func(*PinAddSettings) error +type PinLsOption func(settings *PinLsSettings) error + +func PinAddOptions(opts ...PinAddOption) (*PinAddSettings, error) { + options := &PinAddSettings{ + Recursive: true, + } + + for _, opt := range opts { + err := opt(options) + if err != nil { + return nil, err + } + } + + return options, nil +} + +func PinLsOptions(opts ...PinLsOption) (*PinLsSettings, error) { + options := &PinLsSettings{ + Type: "all", + } + + for _, opt := range opts { + err := opt(options) + if err != nil { + return nil, err + } + } + + return options, nil +} + +type PinOptions struct{} + +func (api *PinOptions) WithRecursive(recucsive bool) PinAddOption { + return func(settings *PinAddSettings) error { + settings.Recursive = recucsive + return nil + } +} + +func (api *PinOptions) WithType(t string) PinLsOption { + return func(settings *PinLsSettings) error { + settings.Type = t + return nil + } +} From ae6dbb3642d43bb9b1bbb798a564a120965ab21d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 10 Jan 2018 18:41:06 +0100 Subject: [PATCH 0040/1212] coreapi: implement pin api MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@4597fde83e61fa8d63fa7aef8a3118f7e441b6db This commit was moved from ipfs/boxo@c1c32446e398484fac04c9a35c4ca92f930bbe2a --- core/coreiface/interface.go | 25 ++++++++++++++++++++++--- core/coreiface/options/pin.go | 27 +++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 3 deletions(-) diff --git a/core/coreiface/interface.go b/core/coreiface/interface.go index 40fa4131e..75a168bf3 100644 --- a/core/coreiface/interface.go +++ b/core/coreiface/interface.go @@ -67,6 +67,24 @@ type Pin interface { Type() string } +// PinStatus holds information about pin health +type PinStatus interface { + // Ok indicates whether the pin has been verified to be correct + Ok() bool + + // BadNodes returns any bad (usually missing) nodes from the pin + BadNodes() []BadPinNode +} + +// BadPinNode is a node that has been marked as bad by Pin.Verify +type BadPinNode interface { + // Path is the path of the node + Path() Path + + // Err is the reason why the node has been marked as bad + Err() error +} + // CoreAPI defines an unified interface to IPFS for Go programs. type CoreAPI interface { // Unixfs returns an implementation of Unixfs API. @@ -83,6 +101,7 @@ type CoreAPI interface { // Key returns an implementation of Key API. Key() KeyAPI + Pin() PinAPI // ObjectAPI returns an implementation of Object API Object() ObjectAPI @@ -342,7 +361,7 @@ type PinAPI interface { WithRecursive(bool) options.PinAddOption // Ls returns list of pinned objects on this node - Ls(context.Context) ([]Pin, error) + Ls(context.Context, ...options.PinLsOption) ([]Pin, error) // WithType is an option for Ls which allows to specify which pin types should // be returned @@ -360,10 +379,10 @@ type PinAPI interface { // Update changes one pin to another, skipping checks for matching paths in // the old tree - Update(ctx context.Context, from Path, to Path) error + Update(ctx context.Context, from Path, to Path, opts ...options.PinUpdateOption) error // Verify verifies the integrity of pinned objects - Verify(context.Context) error + Verify(context.Context) (<-chan PinStatus, error) } var ErrIsDir = errors.New("object is a directory") diff --git a/core/coreiface/options/pin.go b/core/coreiface/options/pin.go index 4ad16d555..f97f7b16e 100644 --- a/core/coreiface/options/pin.go +++ b/core/coreiface/options/pin.go @@ -8,8 +8,13 @@ type PinLsSettings struct { Type string } +type PinUpdateSettings struct { + Unpin bool +} + type PinAddOption func(*PinAddSettings) error type PinLsOption func(settings *PinLsSettings) error +type PinUpdateOption func(*PinUpdateSettings) error func PinAddOptions(opts ...PinAddOption) (*PinAddSettings, error) { options := &PinAddSettings{ @@ -41,6 +46,21 @@ func PinLsOptions(opts ...PinLsOption) (*PinLsSettings, error) { return options, nil } +func PinUpdateOptions(opts ...PinUpdateOption) (*PinUpdateSettings, error) { + options := &PinUpdateSettings{ + Unpin: true, + } + + for _, opt := range opts { + err := opt(options) + if err != nil { + return nil, err + } + } + + return options, nil +} + type PinOptions struct{} func (api *PinOptions) WithRecursive(recucsive bool) PinAddOption { @@ -56,3 +76,10 @@ func (api *PinOptions) WithType(t string) PinLsOption { return nil } } + +func (api *PinOptions) WithUnpin(unpin bool) PinUpdateOption { + return func(settings *PinUpdateSettings) error { + settings.Unpin = unpin + return nil + } +} From a313b37f486d3e8ad1cbdfcb3f61e884b7e30b47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Sat, 10 Mar 2018 17:59:43 +0100 Subject: [PATCH 0041/1212] coreapi: move unixfs errors to the top MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@848f12365b041d32adfa2ba7d5e3b30a1bc4233b This commit was moved from ipfs/boxo@963f83df40b7e960430e8da91aef942e58278acd --- core/coreiface/interface.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/coreiface/interface.go b/core/coreiface/interface.go index 75a168bf3..4d68b5f4b 100644 --- a/core/coreiface/interface.go +++ b/core/coreiface/interface.go @@ -14,6 +14,9 @@ import ( ipld "gx/ipfs/Qme5bWv7wtjUNGsK2BNGVUFPKiuxWrsqrtvYwCLRw8YFES/go-ipld-format" ) +var ErrIsDir = errors.New("object is a directory") +var ErrOffline = errors.New("can't resolve, ipfs node is offline") + // Path is a generic wrapper for paths used in the API. A path can be resolved // to a CID using one of Resolve functions in the API. type Path interface { @@ -384,6 +387,3 @@ type PinAPI interface { // Verify verifies the integrity of pinned objects Verify(context.Context) (<-chan PinStatus, error) } - -var ErrIsDir = errors.New("object is a directory") -var ErrOffline = errors.New("can't resolve, ipfs node is offline") From 3f4a3d552477f2c4387e67f79ff30991a2121525 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Sat, 10 Mar 2018 18:31:28 +0100 Subject: [PATCH 0042/1212] coreapi: don't alias ipld types MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@ab9053378b45e67758591727b9140366d4874fc9 This commit was moved from ipfs/boxo@222c7a617e1ee17ba106b5e5279c15931138abc9 --- core/coreiface/interface.go | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/core/coreiface/interface.go b/core/coreiface/interface.go index 4d68b5f4b..02525c0d2 100644 --- a/core/coreiface/interface.go +++ b/core/coreiface/interface.go @@ -30,11 +30,6 @@ type Path interface { Resolved() bool } -// TODO: should we really copy these? -// if we didn't, godoc would generate nice links straight to go-ipld-format -type Node ipld.Node -type Link ipld.Link - type Reader interface { io.ReadSeeker io.Closer @@ -114,7 +109,7 @@ type CoreAPI interface { // ResolveNode resolves the path (if not resolved already) using Unixfs // resolver, gets and returns the resolved Node - ResolveNode(context.Context, Path) (Node, error) + ResolveNode(context.Context, Path) (ipld.Node, error) } // UnixfsAPI is the basic interface to immutable files in IPFS @@ -126,7 +121,7 @@ type UnixfsAPI interface { Cat(context.Context, Path) (Reader, error) // Ls returns the list of links in a directory - Ls(context.Context, Path) ([]*Link, error) + Ls(context.Context, Path) ([]*ipld.Link, error) } // BlockAPI specifies the interface to the block layer @@ -183,7 +178,7 @@ type DagAPI interface { WithHash(mhType uint64, mhLen int) options.DagPutOption // Get attempts to resolve and get the node specified by the path - Get(ctx context.Context, path Path) (Node, error) + Get(ctx context.Context, path Path) (ipld.Node, error) // Tree returns list of paths within a node specified by the path. Tree(ctx context.Context, path Path, opts ...options.DagTreeOption) ([]Path, error) @@ -272,7 +267,7 @@ type KeyAPI interface { // for manipulating MerkleDAG data structures. type ObjectAPI interface { // New creates new, empty (by default) dag-node. - New(context.Context, ...options.ObjectNewOption) (Node, error) + New(context.Context, ...options.ObjectNewOption) (ipld.Node, error) // WithType is an option for New which allows to change the type of created // dag node. @@ -302,13 +297,13 @@ type ObjectAPI interface { WithDataType(t string) options.ObjectPutOption // Get returns the node for the path - Get(context.Context, Path) (Node, error) + Get(context.Context, Path) (ipld.Node, error) // Data returns reader for data of the node Data(context.Context, Path) (io.Reader, error) // Links returns lint or links the node contains - Links(context.Context, Path) ([]*Link, error) + Links(context.Context, Path) ([]*ipld.Link, error) // Stat returns information about the node Stat(context.Context, Path) (*ObjectStat, error) From cdda2d3e4b7274fc60c237b3b72083f86a710779 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Sat, 10 Mar 2018 18:46:45 +0100 Subject: [PATCH 0043/1212] coreapi: split the interface into multiple files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@d4077754e8de62308542ca3838c8f280ca4aad22 This commit was moved from ipfs/boxo@a05b8c4e76d49997baeb11f87f247965fe2b33ed --- core/coreiface/block.go | 49 +++++ core/coreiface/coreapi.go | 38 ++++ core/coreiface/dag.go | 42 ++++ core/coreiface/errors.go | 6 + core/coreiface/interface.go | 384 ------------------------------------ core/coreiface/key.go | 51 +++++ core/coreiface/name.go | 55 ++++++ core/coreiface/object.go | 96 +++++++++ core/coreiface/path.go | 18 ++ core/coreiface/pin.go | 69 +++++++ core/coreiface/unixfs.go | 20 ++ core/coreiface/util.go | 10 + 12 files changed, 454 insertions(+), 384 deletions(-) create mode 100644 core/coreiface/block.go create mode 100644 core/coreiface/coreapi.go create mode 100644 core/coreiface/dag.go create mode 100644 core/coreiface/errors.go delete mode 100644 core/coreiface/interface.go create mode 100644 core/coreiface/key.go create mode 100644 core/coreiface/name.go create mode 100644 core/coreiface/object.go create mode 100644 core/coreiface/path.go create mode 100644 core/coreiface/pin.go create mode 100644 core/coreiface/unixfs.go create mode 100644 core/coreiface/util.go diff --git a/core/coreiface/block.go b/core/coreiface/block.go new file mode 100644 index 000000000..f38a664c3 --- /dev/null +++ b/core/coreiface/block.go @@ -0,0 +1,49 @@ +package iface + +import ( + "context" + "io" + + options "github.com/ipfs/go-ipfs/core/coreapi/interface/options" +) + +// BlockStat contains information about a block +type BlockStat interface { + // Size is the size of a block + Size() int + + // Path returns path to the block + Path() Path +} + +// BlockAPI specifies the interface to the block layer +type BlockAPI interface { + // Put imports raw block data, hashing it using specified settings. + Put(context.Context, io.Reader, ...options.BlockPutOption) (Path, error) + + // WithFormat is an option for Put which specifies the multicodec to use to + // serialize the object. Default is "v0" + WithFormat(codec string) options.BlockPutOption + + // WithHash is an option for Put which specifies the multihash settings to use + // when hashing the object. Default is mh.SHA2_256 (0x12). + // If mhLen is set to -1, default length for the hash will be used + WithHash(mhType uint64, mhLen int) options.BlockPutOption + + // Get attempts to resolve the path and return a reader for data in the block + Get(context.Context, Path) (io.Reader, error) + + // Rm removes the block specified by the path from local blockstore. + // By default an error will be returned if the block can't be found locally. + // + // NOTE: If the specified block is pinned it won't be removed and no error + // will be returned + Rm(context.Context, Path, ...options.BlockRmOption) error + + // WithForce is an option for Rm which, when set to true, will ignore + // non-existing blocks + WithForce(force bool) options.BlockRmOption + + // Stat returns information on + Stat(context.Context, Path) (BlockStat, error) +} diff --git a/core/coreiface/coreapi.go b/core/coreiface/coreapi.go new file mode 100644 index 000000000..f1388e5bc --- /dev/null +++ b/core/coreiface/coreapi.go @@ -0,0 +1,38 @@ +// Package iface defines IPFS Core API which is a set of interfaces used to +// interact with IPFS nodes. +package iface + +import ( + "context" + + ipld "gx/ipfs/Qme5bWv7wtjUNGsK2BNGVUFPKiuxWrsqrtvYwCLRw8YFES/go-ipld-format" +) + +// CoreAPI defines an unified interface to IPFS for Go programs. +type CoreAPI interface { + // Unixfs returns an implementation of Unixfs API. + Unixfs() UnixfsAPI + + // Block returns an implementation of Block API. + Block() BlockAPI + + // Dag returns an implementation of Dag API. + Dag() DagAPI + + // Name returns an implementation of Name API. + Name() NameAPI + + // Key returns an implementation of Key API. + Key() KeyAPI + Pin() PinAPI + + // ObjectAPI returns an implementation of Object API + Object() ObjectAPI + + // ResolvePath resolves the path using Unixfs resolver + ResolvePath(context.Context, Path) (Path, error) + + // ResolveNode resolves the path (if not resolved already) using Unixfs + // resolver, gets and returns the resolved Node + ResolveNode(context.Context, Path) (ipld.Node, error) +} diff --git a/core/coreiface/dag.go b/core/coreiface/dag.go new file mode 100644 index 000000000..1635d71b1 --- /dev/null +++ b/core/coreiface/dag.go @@ -0,0 +1,42 @@ +package iface + +import ( + "context" + "io" + + options "github.com/ipfs/go-ipfs/core/coreapi/interface/options" + + ipld "gx/ipfs/Qme5bWv7wtjUNGsK2BNGVUFPKiuxWrsqrtvYwCLRw8YFES/go-ipld-format" +) + +// DagAPI specifies the interface to IPLD +type DagAPI interface { + // Put inserts data using specified format and input encoding. + // Unless used with WithCodec or WithHash, the defaults "dag-cbor" and + // "sha256" are used. + Put(ctx context.Context, src io.Reader, opts ...options.DagPutOption) (Path, error) + + // WithInputEnc is an option for Put which specifies the input encoding of the + // data. Default is "json", most formats/codecs support "raw" + WithInputEnc(enc string) options.DagPutOption + + // WithCodec is an option for Put which specifies the multicodec to use to + // serialize the object. Default is cid.DagCBOR (0x71) + WithCodec(codec uint64) options.DagPutOption + + // WithHash is an option for Put which specifies the multihash settings to use + // when hashing the object. Default is based on the codec used + // (mh.SHA2_256 (0x12) for DagCBOR). If mhLen is set to -1, default length for + // the hash will be used + WithHash(mhType uint64, mhLen int) options.DagPutOption + + // Get attempts to resolve and get the node specified by the path + Get(ctx context.Context, path Path) (ipld.Node, error) + + // Tree returns list of paths within a node specified by the path. + Tree(ctx context.Context, path Path, opts ...options.DagTreeOption) ([]Path, error) + + // WithDepth is an option for Tree which specifies maximum depth of the + // returned tree. Default is -1 (no depth limit) + WithDepth(depth int) options.DagTreeOption +} diff --git a/core/coreiface/errors.go b/core/coreiface/errors.go new file mode 100644 index 000000000..73442be11 --- /dev/null +++ b/core/coreiface/errors.go @@ -0,0 +1,6 @@ +package iface + +import "errors" + +var ErrIsDir = errors.New("object is a directory") +var ErrOffline = errors.New("can't resolve, ipfs node is offline") diff --git a/core/coreiface/interface.go b/core/coreiface/interface.go deleted file mode 100644 index 02525c0d2..000000000 --- a/core/coreiface/interface.go +++ /dev/null @@ -1,384 +0,0 @@ -// Package iface defines IPFS Core API which is a set of interfaces used to -// interact with IPFS nodes. -package iface - -import ( - "context" - "errors" - "io" - "time" - - options "github.com/ipfs/go-ipfs/core/coreapi/interface/options" - - cid "gx/ipfs/QmcZfnkapfECQGcLZaf9B79NRg7cRa9EnZh4LSbkCzwNvY/go-cid" - ipld "gx/ipfs/Qme5bWv7wtjUNGsK2BNGVUFPKiuxWrsqrtvYwCLRw8YFES/go-ipld-format" -) - -var ErrIsDir = errors.New("object is a directory") -var ErrOffline = errors.New("can't resolve, ipfs node is offline") - -// Path is a generic wrapper for paths used in the API. A path can be resolved -// to a CID using one of Resolve functions in the API. -type Path interface { - // String returns the path as a string. - String() string - // Cid returns cid referred to by path - Cid() *cid.Cid - // Root returns cid of root path - Root() *cid.Cid - // Resolved returns whether path has been fully resolved - Resolved() bool -} - -type Reader interface { - io.ReadSeeker - io.Closer -} - -// IpnsEntry specifies the interface to IpnsEntries -type IpnsEntry interface { - // Name returns IpnsEntry name - Name() string - // Value returns IpnsEntry value - Value() Path -} - -// Key specifies the interface to Keys in KeyAPI Keystore -type Key interface { - // Key returns key name - Name() string - // Path returns key path - Path() Path -} - -type BlockStat interface { - Size() int - Path() Path -} - -// Pin holds information about pinned resource -type Pin interface { - // Path to the pinned object - Path() Path - - // Type of the pin - Type() string -} - -// PinStatus holds information about pin health -type PinStatus interface { - // Ok indicates whether the pin has been verified to be correct - Ok() bool - - // BadNodes returns any bad (usually missing) nodes from the pin - BadNodes() []BadPinNode -} - -// BadPinNode is a node that has been marked as bad by Pin.Verify -type BadPinNode interface { - // Path is the path of the node - Path() Path - - // Err is the reason why the node has been marked as bad - Err() error -} - -// CoreAPI defines an unified interface to IPFS for Go programs. -type CoreAPI interface { - // Unixfs returns an implementation of Unixfs API. - Unixfs() UnixfsAPI - - // Block returns an implementation of Block API. - Block() BlockAPI - - // Dag returns an implementation of Dag API. - Dag() DagAPI - - // Name returns an implementation of Name API. - Name() NameAPI - - // Key returns an implementation of Key API. - Key() KeyAPI - Pin() PinAPI - - // ObjectAPI returns an implementation of Object API - Object() ObjectAPI - - // ResolvePath resolves the path using Unixfs resolver - ResolvePath(context.Context, Path) (Path, error) - - // ResolveNode resolves the path (if not resolved already) using Unixfs - // resolver, gets and returns the resolved Node - ResolveNode(context.Context, Path) (ipld.Node, error) -} - -// UnixfsAPI is the basic interface to immutable files in IPFS -type UnixfsAPI interface { - // Add imports the data from the reader into merkledag file - Add(context.Context, io.Reader) (Path, error) - - // Cat returns a reader for the file - Cat(context.Context, Path) (Reader, error) - - // Ls returns the list of links in a directory - Ls(context.Context, Path) ([]*ipld.Link, error) -} - -// BlockAPI specifies the interface to the block layer -type BlockAPI interface { - // Put imports raw block data, hashing it using specified settings. - Put(context.Context, io.Reader, ...options.BlockPutOption) (Path, error) - - // WithFormat is an option for Put which specifies the multicodec to use to - // serialize the object. Default is "v0" - WithFormat(codec string) options.BlockPutOption - - // WithHash is an option for Put which specifies the multihash settings to use - // when hashing the object. Default is mh.SHA2_256 (0x12). - // If mhLen is set to -1, default length for the hash will be used - WithHash(mhType uint64, mhLen int) options.BlockPutOption - - // Get attempts to resolve the path and return a reader for data in the block - Get(context.Context, Path) (io.Reader, error) - - // Rm removes the block specified by the path from local blockstore. - // By default an error will be returned if the block can't be found locally. - // - // NOTE: If the specified block is pinned it won't be removed and no error - // will be returned - Rm(context.Context, Path, ...options.BlockRmOption) error - - // WithForce is an option for Rm which, when set to true, will ignore - // non-existing blocks - WithForce(force bool) options.BlockRmOption - - // Stat returns information on - Stat(context.Context, Path) (BlockStat, error) -} - -// DagAPI specifies the interface to IPLD -type DagAPI interface { - // Put inserts data using specified format and input encoding. - // Unless used with WithCodec or WithHash, the defaults "dag-cbor" and - // "sha256" are used. - Put(ctx context.Context, src io.Reader, opts ...options.DagPutOption) (Path, error) - - // WithInputEnc is an option for Put which specifies the input encoding of the - // data. Default is "json", most formats/codecs support "raw" - WithInputEnc(enc string) options.DagPutOption - - // WithCodec is an option for Put which specifies the multicodec to use to - // serialize the object. Default is cid.DagCBOR (0x71) - WithCodec(codec uint64) options.DagPutOption - - // WithHash is an option for Put which specifies the multihash settings to use - // when hashing the object. Default is based on the codec used - // (mh.SHA2_256 (0x12) for DagCBOR). If mhLen is set to -1, default length for - // the hash will be used - WithHash(mhType uint64, mhLen int) options.DagPutOption - - // Get attempts to resolve and get the node specified by the path - Get(ctx context.Context, path Path) (ipld.Node, error) - - // Tree returns list of paths within a node specified by the path. - Tree(ctx context.Context, path Path, opts ...options.DagTreeOption) ([]Path, error) - - // WithDepth is an option for Tree which specifies maximum depth of the - // returned tree. Default is -1 (no depth limit) - WithDepth(depth int) options.DagTreeOption -} - -// NameAPI specifies the interface to IPNS. -// -// IPNS is a PKI namespace, where names are the hashes of public keys, and the -// private key enables publishing new (signed) values. In both publish and -// resolve, the default name used is the node's own PeerID, which is the hash of -// its public key. -// -// You can use .Key API to list and generate more names and their respective keys. -type NameAPI interface { - // Publish announces new IPNS name - Publish(ctx context.Context, path Path, opts ...options.NamePublishOption) (IpnsEntry, error) - - // WithValidTime is an option for Publish which specifies for how long the - // entry will remain valid. Default value is 24h - WithValidTime(validTime time.Duration) options.NamePublishOption - - // WithKey is an option for Publish which specifies the key to use for - // publishing. Default value is "self" which is the node's own PeerID. - // The key parameter must be either PeerID or keystore key alias. - // - // You can use KeyAPI to list and generate more names and their respective keys. - WithKey(key string) options.NamePublishOption - - // Resolve attempts to resolve the newest version of the specified name - Resolve(ctx context.Context, name string, opts ...options.NameResolveOption) (Path, error) - - // WithRecursive is an option for Resolve which specifies whether to perform a - // recursive lookup. Default value is false - WithRecursive(recursive bool) options.NameResolveOption - - // WithLocal is an option for Resolve which specifies if the lookup should be - // offline. Default value is false - WithLocal(local bool) options.NameResolveOption - - // WithCache is an option for Resolve which specifies if cache should be used. - // Default value is true - WithCache(cache bool) options.NameResolveOption -} - -// KeyAPI specifies the interface to Keystore -type KeyAPI interface { - // Generate generates new key, stores it in the keystore under the specified - // name and returns a base58 encoded multihash of it's public key - Generate(ctx context.Context, name string, opts ...options.KeyGenerateOption) (Key, error) - - // WithType is an option for Generate which specifies which algorithm - // should be used for the key. Default is options.RSAKey - // - // Supported key types: - // * options.RSAKey - // * options.Ed25519Key - WithType(algorithm string) options.KeyGenerateOption - - // WithSize is an option for Generate which specifies the size of the key to - // generated. Default is -1 - // - // value of -1 means 'use default size for key type': - // * 2048 for RSA - WithSize(size int) options.KeyGenerateOption - - // Rename renames oldName key to newName. Returns the key and whether another - // key was overwritten, or an error - Rename(ctx context.Context, oldName string, newName string, opts ...options.KeyRenameOption) (Key, bool, error) - - // WithForce is an option for Rename which specifies whether to allow to - // replace existing keys. - WithForce(force bool) options.KeyRenameOption - - // List lists keys stored in keystore - List(ctx context.Context) ([]Key, error) - - // Remove removes keys from keystore. Returns ipns path of the removed key - Remove(ctx context.Context, name string) (Path, error) -} - -// ObjectAPI specifies the interface to MerkleDAG and contains useful utilities -// for manipulating MerkleDAG data structures. -type ObjectAPI interface { - // New creates new, empty (by default) dag-node. - New(context.Context, ...options.ObjectNewOption) (ipld.Node, error) - - // WithType is an option for New which allows to change the type of created - // dag node. - // - // Supported types: - // * 'empty' - Empty node - // * 'unixfs-dir' - Empty UnixFS directory - WithType(string) options.ObjectNewOption - - // Put imports the data into merkledag - Put(context.Context, io.Reader, ...options.ObjectPutOption) (Path, error) - - // WithInputEnc is an option for Put which specifies the input encoding of the - // data. Default is "json". - // - // Supported encodings: - // * "protobuf" - // * "json" - WithInputEnc(e string) options.ObjectPutOption - - // WithDataType specifies the encoding of data field when using Josn or XML - // input encoding. - // - // Supported types: - // * "text" (default) - // * "base64" - WithDataType(t string) options.ObjectPutOption - - // Get returns the node for the path - Get(context.Context, Path) (ipld.Node, error) - - // Data returns reader for data of the node - Data(context.Context, Path) (io.Reader, error) - - // Links returns lint or links the node contains - Links(context.Context, Path) ([]*ipld.Link, error) - - // Stat returns information about the node - Stat(context.Context, Path) (*ObjectStat, error) - - // AddLink adds a link under the specified path. child path can point to a - // subdirectory within the patent which must be present (can be overridden - // with WithCreate option). - AddLink(ctx context.Context, base Path, name string, child Path, opts ...options.ObjectAddLinkOption) (Path, error) - - // WithCreate is an option for AddLink which specifies whether create required - // directories for the child - WithCreate(create bool) options.ObjectAddLinkOption - - // RmLink removes a link from the node - RmLink(ctx context.Context, base Path, link string) (Path, error) - - // AppendData appends data to the node - AppendData(context.Context, Path, io.Reader) (Path, error) - - // SetData sets the data contained in the node - SetData(context.Context, Path, io.Reader) (Path, error) -} - -// ObjectStat provides information about dag nodes -type ObjectStat struct { - // Cid is the CID of the node - Cid *cid.Cid - - // NumLinks is number of links the node contains - NumLinks int - - // BlockSize is size of the raw serialized node - BlockSize int - - // LinksSize is size of the links block section - LinksSize int - - // DataSize is the size of data block section - DataSize int - - // CumulativeSize is size of the tree (BlockSize + link sizes) - CumulativeSize int -} - -// PinAPI specifies the interface to pining -type PinAPI interface { - // Add creates new pin, be default recursive - pinning the whole referenced - // tree - Add(context.Context, Path, ...options.PinAddOption) error - - // WithRecursive is an option for Add which specifies whether to pin an entire - // object tree or just one object. Default: true - WithRecursive(bool) options.PinAddOption - - // Ls returns list of pinned objects on this node - Ls(context.Context, ...options.PinLsOption) ([]Pin, error) - - // WithType is an option for Ls which allows to specify which pin types should - // be returned - // - // Supported values: - // * "direct" - directly pinned objects - // * "recursive" - roots of recursive pins - // * "indirect" - indirectly pinned objects (referenced by recursively pinned - // objects) - // * "all" - all pinned objects (default) - WithType(string) options.PinLsOption - - // Rm removes pin for object specified by the path - Rm(context.Context, Path) error - - // Update changes one pin to another, skipping checks for matching paths in - // the old tree - Update(ctx context.Context, from Path, to Path, opts ...options.PinUpdateOption) error - - // Verify verifies the integrity of pinned objects - Verify(context.Context) (<-chan PinStatus, error) -} diff --git a/core/coreiface/key.go b/core/coreiface/key.go new file mode 100644 index 000000000..730e855d7 --- /dev/null +++ b/core/coreiface/key.go @@ -0,0 +1,51 @@ +package iface + +import ( + "context" + + options "github.com/ipfs/go-ipfs/core/coreapi/interface/options" +) + +// Key specifies the interface to Keys in KeyAPI Keystore +type Key interface { + // Key returns key name + Name() string + // Path returns key path + Path() Path +} + +// KeyAPI specifies the interface to Keystore +type KeyAPI interface { + // Generate generates new key, stores it in the keystore under the specified + // name and returns a base58 encoded multihash of it's public key + Generate(ctx context.Context, name string, opts ...options.KeyGenerateOption) (Key, error) + + // WithType is an option for Generate which specifies which algorithm + // should be used for the key. Default is options.RSAKey + // + // Supported key types: + // * options.RSAKey + // * options.Ed25519Key + WithType(algorithm string) options.KeyGenerateOption + + // WithSize is an option for Generate which specifies the size of the key to + // generated. Default is -1 + // + // value of -1 means 'use default size for key type': + // * 2048 for RSA + WithSize(size int) options.KeyGenerateOption + + // Rename renames oldName key to newName. Returns the key and whether another + // key was overwritten, or an error + Rename(ctx context.Context, oldName string, newName string, opts ...options.KeyRenameOption) (Key, bool, error) + + // WithForce is an option for Rename which specifies whether to allow to + // replace existing keys. + WithForce(force bool) options.KeyRenameOption + + // List lists keys stored in keystore + List(ctx context.Context) ([]Key, error) + + // Remove removes keys from keystore. Returns ipns path of the removed key + Remove(ctx context.Context, name string) (Path, error) +} diff --git a/core/coreiface/name.go b/core/coreiface/name.go new file mode 100644 index 000000000..6d17d840a --- /dev/null +++ b/core/coreiface/name.go @@ -0,0 +1,55 @@ +package iface + +import ( + "context" + "time" + + options "github.com/ipfs/go-ipfs/core/coreapi/interface/options" +) + +// IpnsEntry specifies the interface to IpnsEntries +type IpnsEntry interface { + // Name returns IpnsEntry name + Name() string + // Value returns IpnsEntry value + Value() Path +} + +// NameAPI specifies the interface to IPNS. +// +// IPNS is a PKI namespace, where names are the hashes of public keys, and the +// private key enables publishing new (signed) values. In both publish and +// resolve, the default name used is the node's own PeerID, which is the hash of +// its public key. +// +// You can use .Key API to list and generate more names and their respective keys. +type NameAPI interface { + // Publish announces new IPNS name + Publish(ctx context.Context, path Path, opts ...options.NamePublishOption) (IpnsEntry, error) + + // WithValidTime is an option for Publish which specifies for how long the + // entry will remain valid. Default value is 24h + WithValidTime(validTime time.Duration) options.NamePublishOption + + // WithKey is an option for Publish which specifies the key to use for + // publishing. Default value is "self" which is the node's own PeerID. + // The key parameter must be either PeerID or keystore key alias. + // + // You can use KeyAPI to list and generate more names and their respective keys. + WithKey(key string) options.NamePublishOption + + // Resolve attempts to resolve the newest version of the specified name + Resolve(ctx context.Context, name string, opts ...options.NameResolveOption) (Path, error) + + // WithRecursive is an option for Resolve which specifies whether to perform a + // recursive lookup. Default value is false + WithRecursive(recursive bool) options.NameResolveOption + + // WithLocal is an option for Resolve which specifies if the lookup should be + // offline. Default value is false + WithLocal(local bool) options.NameResolveOption + + // WithCache is an option for Resolve which specifies if cache should be used. + // Default value is true + WithCache(cache bool) options.NameResolveOption +} diff --git a/core/coreiface/object.go b/core/coreiface/object.go new file mode 100644 index 000000000..75837f93e --- /dev/null +++ b/core/coreiface/object.go @@ -0,0 +1,96 @@ +package iface + +import ( + "context" + "io" + + options "github.com/ipfs/go-ipfs/core/coreapi/interface/options" + + cid "gx/ipfs/QmcZfnkapfECQGcLZaf9B79NRg7cRa9EnZh4LSbkCzwNvY/go-cid" + ipld "gx/ipfs/Qme5bWv7wtjUNGsK2BNGVUFPKiuxWrsqrtvYwCLRw8YFES/go-ipld-format" +) + +// ObjectStat provides information about dag nodes +type ObjectStat struct { + // Cid is the CID of the node + Cid *cid.Cid + + // NumLinks is number of links the node contains + NumLinks int + + // BlockSize is size of the raw serialized node + BlockSize int + + // LinksSize is size of the links block section + LinksSize int + + // DataSize is the size of data block section + DataSize int + + // CumulativeSize is size of the tree (BlockSize + link sizes) + CumulativeSize int +} + +// ObjectAPI specifies the interface to MerkleDAG and contains useful utilities +// for manipulating MerkleDAG data structures. +type ObjectAPI interface { + // New creates new, empty (by default) dag-node. + New(context.Context, ...options.ObjectNewOption) (ipld.Node, error) + + // WithType is an option for New which allows to change the type of created + // dag node. + // + // Supported types: + // * 'empty' - Empty node + // * 'unixfs-dir' - Empty UnixFS directory + WithType(string) options.ObjectNewOption + + // Put imports the data into merkledag + Put(context.Context, io.Reader, ...options.ObjectPutOption) (Path, error) + + // WithInputEnc is an option for Put which specifies the input encoding of the + // data. Default is "json". + // + // Supported encodings: + // * "protobuf" + // * "json" + WithInputEnc(e string) options.ObjectPutOption + + // WithDataType specifies the encoding of data field when using Josn or XML + // input encoding. + // + // Supported types: + // * "text" (default) + // * "base64" + WithDataType(t string) options.ObjectPutOption + + // Get returns the node for the path + Get(context.Context, Path) (ipld.Node, error) + + // Data returns reader for data of the node + Data(context.Context, Path) (io.Reader, error) + + // Links returns lint or links the node contains + Links(context.Context, Path) ([]*ipld.Link, error) + + // Stat returns information about the node + Stat(context.Context, Path) (*ObjectStat, error) + + // AddLink adds a link under the specified path. child path can point to a + // subdirectory within the patent which must be present (can be overridden + // with WithCreate option). + AddLink(ctx context.Context, base Path, name string, child Path, opts ...options.ObjectAddLinkOption) (Path, error) + + // WithCreate is an option for AddLink which specifies whether create required + // directories for the child + WithCreate(create bool) options.ObjectAddLinkOption + + // RmLink removes a link from the node + RmLink(ctx context.Context, base Path, link string) (Path, error) + + // AppendData appends data to the node + AppendData(context.Context, Path, io.Reader) (Path, error) + + // SetData sets the data contained in the node + SetData(context.Context, Path, io.Reader) (Path, error) +} diff --git a/core/coreiface/path.go b/core/coreiface/path.go new file mode 100644 index 000000000..b2160b942 --- /dev/null +++ b/core/coreiface/path.go @@ -0,0 +1,18 @@ +package iface + +import ( + cid "gx/ipfs/QmcZfnkapfECQGcLZaf9B79NRg7cRa9EnZh4LSbkCzwNvY/go-cid" +) + +// Path is a generic wrapper for paths used in the API. A path can be resolved +// to a CID using one of Resolve functions in the API. +type Path interface { + // String returns the path as a string. + String() string + // Cid returns cid referred to by path + Cid() *cid.Cid + // Root returns cid of root path + Root() *cid.Cid + // Resolved returns whether path has been fully resolved + Resolved() bool +} diff --git a/core/coreiface/pin.go b/core/coreiface/pin.go new file mode 100644 index 000000000..47a5a0bb2 --- /dev/null +++ b/core/coreiface/pin.go @@ -0,0 +1,69 @@ +package iface + +import ( + "context" + + options "github.com/ipfs/go-ipfs/core/coreapi/interface/options" +) + +// Pin holds information about pinned resource +type Pin interface { + // Path to the pinned object + Path() Path + + // Type of the pin + Type() string +} + +// PinStatus holds information about pin health +type PinStatus interface { + // Ok indicates whether the pin has been verified to be correct + Ok() bool + + // BadNodes returns any bad (usually missing) nodes from the pin + BadNodes() []BadPinNode +} + +// BadPinNode is a node that has been marked as bad by Pin.Verify +type BadPinNode interface { + // Path is the path of the node + Path() Path + + // Err is the reason why the node has been marked as bad + Err() error +} + +// PinAPI specifies the interface to pining +type PinAPI interface { + // Add creates new pin, be default recursive - pinning the whole referenced + // tree + Add(context.Context, Path, ...options.PinAddOption) error + + // WithRecursive is an option for Add which specifies whether to pin an entire + // object tree or just one object. Default: true + WithRecursive(bool) options.PinAddOption + + // Ls returns list of pinned objects on this node + Ls(context.Context, ...options.PinLsOption) ([]Pin, error) + + // WithType is an option for Ls which allows to specify which pin types should + // be returned + // + // Supported values: + // * "direct" - directly pinned objects + // * "recursive" - roots of recursive pins + // * "indirect" - indirectly pinned objects (referenced by recursively pinned + // objects) + // * "all" - all pinned objects (default) + WithType(string) options.PinLsOption + + // Rm removes pin for object specified by the path + Rm(context.Context, Path) error + + // Update changes one pin to another, skipping checks for matching paths in + // the old tree + Update(ctx context.Context, from Path, to Path, opts ...options.PinUpdateOption) error + + // Verify verifies the integrity of pinned objects + Verify(context.Context) (<-chan PinStatus, error) +} diff --git a/core/coreiface/unixfs.go b/core/coreiface/unixfs.go new file mode 100644 index 000000000..c1b4efa43 --- /dev/null +++ b/core/coreiface/unixfs.go @@ -0,0 +1,20 @@ +package iface + +import ( + "context" + "io" + + ipld "gx/ipfs/Qme5bWv7wtjUNGsK2BNGVUFPKiuxWrsqrtvYwCLRw8YFES/go-ipld-format" +) + +// UnixfsAPI is the basic interface to immutable files in IPFS +type UnixfsAPI interface { + // Add imports the data from the reader into merkledag file + Add(context.Context, io.Reader) (Path, error) + + // Cat returns a reader for the file + Cat(context.Context, Path) (Reader, error) + + // Ls returns the list of links in a directory + Ls(context.Context, Path) ([]*ipld.Link, error) +} diff --git a/core/coreiface/util.go b/core/coreiface/util.go new file mode 100644 index 000000000..8fd3e058f --- /dev/null +++ b/core/coreiface/util.go @@ -0,0 +1,10 @@ +package iface + +import ( + "io" +) + +type Reader interface { + io.ReadSeeker + io.Closer +} From 809fb6b34a9ccb507a7917265227a6941458fe1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Sat, 10 Mar 2018 18:52:10 +0100 Subject: [PATCH 0044/1212] coreapi: minor doc fixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@dba6c1b7a33059613de8019eafb527031e52e61d This commit was moved from ipfs/boxo@64d53e28ce0e428dadef3a318a1f44eb983376e7 --- core/coreiface/coreapi.go | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/core/coreiface/coreapi.go b/core/coreiface/coreapi.go index f1388e5bc..9428b3b63 100644 --- a/core/coreiface/coreapi.go +++ b/core/coreiface/coreapi.go @@ -8,22 +8,24 @@ import ( ipld "gx/ipfs/Qme5bWv7wtjUNGsK2BNGVUFPKiuxWrsqrtvYwCLRw8YFES/go-ipld-format" ) -// CoreAPI defines an unified interface to IPFS for Go programs. +// CoreAPI defines an unified interface to IPFS for Go programs type CoreAPI interface { - // Unixfs returns an implementation of Unixfs API. + // Unixfs returns an implementation of Unixfs API Unixfs() UnixfsAPI - // Block returns an implementation of Block API. + // Block returns an implementation of Block API Block() BlockAPI - // Dag returns an implementation of Dag API. + // Dag returns an implementation of Dag API Dag() DagAPI - // Name returns an implementation of Name API. + // Name returns an implementation of Name API Name() NameAPI - // Key returns an implementation of Key API. + // Key returns an implementation of Key API Key() KeyAPI + + // Pin returns an implementation of Pin API Pin() PinAPI // ObjectAPI returns an implementation of Object API From f3162d6ec66cecaf16eb7cd2f7db03035741db37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Sat, 10 Mar 2018 22:17:27 +0100 Subject: [PATCH 0045/1212] coreapi: var block for errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@60fc569676d93341f657737a221de2228a178183 This commit was moved from ipfs/boxo@5de1a8368e0d7b6abe9226f7e789ab8a521fb886 --- core/coreiface/errors.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/core/coreiface/errors.go b/core/coreiface/errors.go index 73442be11..81f978971 100644 --- a/core/coreiface/errors.go +++ b/core/coreiface/errors.go @@ -2,5 +2,7 @@ package iface import "errors" -var ErrIsDir = errors.New("object is a directory") -var ErrOffline = errors.New("can't resolve, ipfs node is offline") +var ( + ErrIsDir = errors.New("object is a directory") + ErrOffline = errors.New("can't resolve, ipfs node is offline") +) From 5e488491670bdb45a3fa957b624f44a068cb40a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Sun, 11 Mar 2018 18:55:35 +0100 Subject: [PATCH 0046/1212] coreapi: remove options from interfaces MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@38ccf0555876033759418de2c43b5d9c727b2c19 This commit was moved from ipfs/boxo@595afb8260f48d77dfff80a7d4a191f185adfb87 --- core/coreiface/block.go | 13 ------------- core/coreiface/dag.go | 18 ------------------ core/coreiface/key.go | 19 ------------------- core/coreiface/name.go | 24 ------------------------ core/coreiface/object.go | 28 ---------------------------- core/coreiface/options/block.go | 17 +++++++++++++---- core/coreiface/options/dag.go | 22 +++++++++++++++++----- core/coreiface/options/key.go | 23 +++++++++++++++++++---- core/coreiface/options/name.go | 27 +++++++++++++++++++++------ core/coreiface/options/object.go | 32 +++++++++++++++++++++++++++----- core/coreiface/options/pin.go | 23 +++++++++++++++++++---- core/coreiface/pin.go | 15 --------------- 12 files changed, 116 insertions(+), 145 deletions(-) diff --git a/core/coreiface/block.go b/core/coreiface/block.go index f38a664c3..a9e577d76 100644 --- a/core/coreiface/block.go +++ b/core/coreiface/block.go @@ -21,15 +21,6 @@ type BlockAPI interface { // Put imports raw block data, hashing it using specified settings. Put(context.Context, io.Reader, ...options.BlockPutOption) (Path, error) - // WithFormat is an option for Put which specifies the multicodec to use to - // serialize the object. Default is "v0" - WithFormat(codec string) options.BlockPutOption - - // WithHash is an option for Put which specifies the multihash settings to use - // when hashing the object. Default is mh.SHA2_256 (0x12). - // If mhLen is set to -1, default length for the hash will be used - WithHash(mhType uint64, mhLen int) options.BlockPutOption - // Get attempts to resolve the path and return a reader for data in the block Get(context.Context, Path) (io.Reader, error) @@ -40,10 +31,6 @@ type BlockAPI interface { // will be returned Rm(context.Context, Path, ...options.BlockRmOption) error - // WithForce is an option for Rm which, when set to true, will ignore - // non-existing blocks - WithForce(force bool) options.BlockRmOption - // Stat returns information on Stat(context.Context, Path) (BlockStat, error) } diff --git a/core/coreiface/dag.go b/core/coreiface/dag.go index 1635d71b1..f20c88f25 100644 --- a/core/coreiface/dag.go +++ b/core/coreiface/dag.go @@ -16,27 +16,9 @@ type DagAPI interface { // "sha256" are used. Put(ctx context.Context, src io.Reader, opts ...options.DagPutOption) (Path, error) - // WithInputEnc is an option for Put which specifies the input encoding of the - // data. Default is "json", most formats/codecs support "raw" - WithInputEnc(enc string) options.DagPutOption - - // WithCodec is an option for Put which specifies the multicodec to use to - // serialize the object. Default is cid.DagCBOR (0x71) - WithCodec(codec uint64) options.DagPutOption - - // WithHash is an option for Put which specifies the multihash settings to use - // when hashing the object. Default is based on the codec used - // (mh.SHA2_256 (0x12) for DagCBOR). If mhLen is set to -1, default length for - // the hash will be used - WithHash(mhType uint64, mhLen int) options.DagPutOption - // Get attempts to resolve and get the node specified by the path Get(ctx context.Context, path Path) (ipld.Node, error) // Tree returns list of paths within a node specified by the path. Tree(ctx context.Context, path Path, opts ...options.DagTreeOption) ([]Path, error) - - // WithDepth is an option for Tree which specifies maximum depth of the - // returned tree. Default is -1 (no depth limit) - WithDepth(depth int) options.DagTreeOption } diff --git a/core/coreiface/key.go b/core/coreiface/key.go index 730e855d7..928aa265f 100644 --- a/core/coreiface/key.go +++ b/core/coreiface/key.go @@ -20,29 +20,10 @@ type KeyAPI interface { // name and returns a base58 encoded multihash of it's public key Generate(ctx context.Context, name string, opts ...options.KeyGenerateOption) (Key, error) - // WithType is an option for Generate which specifies which algorithm - // should be used for the key. Default is options.RSAKey - // - // Supported key types: - // * options.RSAKey - // * options.Ed25519Key - WithType(algorithm string) options.KeyGenerateOption - - // WithSize is an option for Generate which specifies the size of the key to - // generated. Default is -1 - // - // value of -1 means 'use default size for key type': - // * 2048 for RSA - WithSize(size int) options.KeyGenerateOption - // Rename renames oldName key to newName. Returns the key and whether another // key was overwritten, or an error Rename(ctx context.Context, oldName string, newName string, opts ...options.KeyRenameOption) (Key, bool, error) - // WithForce is an option for Rename which specifies whether to allow to - // replace existing keys. - WithForce(force bool) options.KeyRenameOption - // List lists keys stored in keystore List(ctx context.Context) ([]Key, error) diff --git a/core/coreiface/name.go b/core/coreiface/name.go index 6d17d840a..a6aad0c3e 100644 --- a/core/coreiface/name.go +++ b/core/coreiface/name.go @@ -2,7 +2,6 @@ package iface import ( "context" - "time" options "github.com/ipfs/go-ipfs/core/coreapi/interface/options" ) @@ -27,29 +26,6 @@ type NameAPI interface { // Publish announces new IPNS name Publish(ctx context.Context, path Path, opts ...options.NamePublishOption) (IpnsEntry, error) - // WithValidTime is an option for Publish which specifies for how long the - // entry will remain valid. Default value is 24h - WithValidTime(validTime time.Duration) options.NamePublishOption - - // WithKey is an option for Publish which specifies the key to use for - // publishing. Default value is "self" which is the node's own PeerID. - // The key parameter must be either PeerID or keystore key alias. - // - // You can use KeyAPI to list and generate more names and their respective keys. - WithKey(key string) options.NamePublishOption - // Resolve attempts to resolve the newest version of the specified name Resolve(ctx context.Context, name string, opts ...options.NameResolveOption) (Path, error) - - // WithRecursive is an option for Resolve which specifies whether to perform a - // recursive lookup. Default value is false - WithRecursive(recursive bool) options.NameResolveOption - - // WithLocal is an option for Resolve which specifies if the lookup should be - // offline. Default value is false - WithLocal(local bool) options.NameResolveOption - - // WithCache is an option for Resolve which specifies if cache should be used. - // Default value is true - WithCache(cache bool) options.NameResolveOption } diff --git a/core/coreiface/object.go b/core/coreiface/object.go index 75837f93e..548b15a73 100644 --- a/core/coreiface/object.go +++ b/core/coreiface/object.go @@ -37,33 +37,9 @@ type ObjectAPI interface { // New creates new, empty (by default) dag-node. New(context.Context, ...options.ObjectNewOption) (ipld.Node, error) - // WithType is an option for New which allows to change the type of created - // dag node. - // - // Supported types: - // * 'empty' - Empty node - // * 'unixfs-dir' - Empty UnixFS directory - WithType(string) options.ObjectNewOption - // Put imports the data into merkledag Put(context.Context, io.Reader, ...options.ObjectPutOption) (Path, error) - // WithInputEnc is an option for Put which specifies the input encoding of the - // data. Default is "json". - // - // Supported encodings: - // * "protobuf" - // * "json" - WithInputEnc(e string) options.ObjectPutOption - - // WithDataType specifies the encoding of data field when using Josn or XML - // input encoding. - // - // Supported types: - // * "text" (default) - // * "base64" - WithDataType(t string) options.ObjectPutOption - // Get returns the node for the path Get(context.Context, Path) (ipld.Node, error) @@ -81,10 +57,6 @@ type ObjectAPI interface { // with WithCreate option). AddLink(ctx context.Context, base Path, name string, child Path, opts ...options.ObjectAddLinkOption) (Path, error) - // WithCreate is an option for AddLink which specifies whether create required - // directories for the child - WithCreate(create bool) options.ObjectAddLinkOption - // RmLink removes a link from the node RmLink(ctx context.Context, base Path, link string) (Path, error) diff --git a/core/coreiface/options/block.go b/core/coreiface/options/block.go index bbb14612f..20320705e 100644 --- a/core/coreiface/options/block.go +++ b/core/coreiface/options/block.go @@ -47,16 +47,23 @@ func BlockRmOptions(opts ...BlockRmOption) (*BlockRmSettings, error) { return options, nil } -type BlockOptions struct{} +type blockOpts struct{} -func (api *BlockOptions) WithFormat(codec string) BlockPutOption { +var Block blockOpts + +// Format is an option for Block.Put which specifies the multicodec to use to +// serialize the object. Default is "v0" +func (_ blockOpts) Format(codec string) BlockPutOption { return func(settings *BlockPutSettings) error { settings.Codec = codec return nil } } -func (api *BlockOptions) WithHash(mhType uint64, mhLen int) BlockPutOption { +// Hash is an option for Block.Put which specifies the multihash settings to use +// when hashing the object. Default is mh.SHA2_256 (0x12). +// If mhLen is set to -1, default length for the hash will be used +func (_ blockOpts) Hash(mhType uint64, mhLen int) BlockPutOption { return func(settings *BlockPutSettings) error { settings.MhType = mhType settings.MhLength = mhLen @@ -64,7 +71,9 @@ func (api *BlockOptions) WithHash(mhType uint64, mhLen int) BlockPutOption { } } -func (api *BlockOptions) WithForce(force bool) BlockRmOption { +// Force is an option for Block.Rm which, when set to true, will ignore +// non-existing blocks +func (_ blockOpts) Force(force bool) BlockRmOption { return func(settings *BlockRmSettings) error { settings.Force = force return nil diff --git a/core/coreiface/options/dag.go b/core/coreiface/options/dag.go index b56fcd81a..ec258cf95 100644 --- a/core/coreiface/options/dag.go +++ b/core/coreiface/options/dag.go @@ -51,23 +51,33 @@ func DagTreeOptions(opts ...DagTreeOption) (*DagTreeSettings, error) { return options, nil } -type DagOptions struct{} +type dagOpts struct{} -func (api *DagOptions) WithInputEnc(enc string) DagPutOption { +var Dag dagOpts + +// InputEnc is an option for Dag.Put which specifies the input encoding of the +// data. Default is "json", most formats/codecs support "raw" +func (_ dagOpts) InputEnc(enc string) DagPutOption { return func(settings *DagPutSettings) error { settings.InputEnc = enc return nil } } -func (api *DagOptions) WithCodec(codec uint64) DagPutOption { +// Codec is an option for Dag.Put which specifies the multicodec to use to +// serialize the object. Default is cid.DagCBOR (0x71) +func (_ dagOpts) Codec(codec uint64) DagPutOption { return func(settings *DagPutSettings) error { settings.Codec = codec return nil } } -func (api *DagOptions) WithHash(mhType uint64, mhLen int) DagPutOption { +// Hash is an option for Dag.Put which specifies the multihash settings to use +// when hashing the object. Default is based on the codec used +// (mh.SHA2_256 (0x12) for DagCBOR). If mhLen is set to -1, default length for +// the hash will be used +func (_ dagOpts) Hash(mhType uint64, mhLen int) DagPutOption { return func(settings *DagPutSettings) error { settings.MhType = mhType settings.MhLength = mhLen @@ -75,7 +85,9 @@ func (api *DagOptions) WithHash(mhType uint64, mhLen int) DagPutOption { } } -func (api *DagOptions) WithDepth(depth int) DagTreeOption { +// Depth is an option for Dag.Tree which specifies maximum depth of the +// returned tree. Default is -1 (no depth limit) +func (_ dagOpts) Depth(depth int) DagTreeOption { return func(settings *DagTreeSettings) error { settings.Depth = depth return nil diff --git a/core/coreiface/options/key.go b/core/coreiface/options/key.go index 114361875..a29261d14 100644 --- a/core/coreiface/options/key.go +++ b/core/coreiface/options/key.go @@ -48,23 +48,38 @@ func KeyRenameOptions(opts ...KeyRenameOption) (*KeyRenameSettings, error) { return options, nil } -type KeyOptions struct{} +type keyOpts struct{} -func (api *KeyOptions) WithType(algorithm string) KeyGenerateOption { +var Key keyOpts + +// Type is an option for Key.Generate which specifies which algorithm +// should be used for the key. Default is options.RSAKey +// +// Supported key types: +// * options.RSAKey +// * options.Ed25519Key +func (_ keyOpts) Type(algorithm string) KeyGenerateOption { return func(settings *KeyGenerateSettings) error { settings.Algorithm = algorithm return nil } } -func (api *KeyOptions) WithSize(size int) KeyGenerateOption { +// Size is an option for Key.Generate which specifies the size of the key to +// generated. Default is -1 +// +// value of -1 means 'use default size for key type': +// * 2048 for RSA +func (_ keyOpts) Size(size int) KeyGenerateOption { return func(settings *KeyGenerateSettings) error { settings.Size = size return nil } } -func (api *KeyOptions) WithForce(force bool) KeyRenameOption { +// Force is an option for Key.Rename which specifies whether to allow to +// replace existing keys. +func (_ keyOpts) Force(force bool) KeyRenameOption { return func(settings *KeyRenameSettings) error { settings.Force = force return nil diff --git a/core/coreiface/options/name.go b/core/coreiface/options/name.go index 9f8aaafc8..1f6de0ee3 100644 --- a/core/coreiface/options/name.go +++ b/core/coreiface/options/name.go @@ -55,37 +55,52 @@ func NameResolveOptions(opts ...NameResolveOption) (*NameResolveSettings, error) return options, nil } -type NameOptions struct{} +type nameOpts struct{} -func (api *NameOptions) WithValidTime(validTime time.Duration) NamePublishOption { +var Name nameOpts + +// ValidTime is an option for Name.Publish which specifies for how long the +// entry will remain valid. Default value is 24h +func (_ nameOpts) ValidTime(validTime time.Duration) NamePublishOption { return func(settings *NamePublishSettings) error { settings.ValidTime = validTime return nil } } -func (api *NameOptions) WithKey(key string) NamePublishOption { +// Key is an option for Name.Publish which specifies the key to use for +// publishing. Default value is "self" which is the node's own PeerID. +// The key parameter must be either PeerID or keystore key alias. +// +// You can use KeyAPI to list and generate more names and their respective keys. +func (_ nameOpts) Key(key string) NamePublishOption { return func(settings *NamePublishSettings) error { settings.Key = key return nil } } -func (api *NameOptions) WithRecursive(recursive bool) NameResolveOption { +// Recursive is an option for Name.Resolve which specifies whether to perform a +// recursive lookup. Default value is false +func (_ nameOpts) Recursive(recursive bool) NameResolveOption { return func(settings *NameResolveSettings) error { settings.Recursive = recursive return nil } } -func (api *NameOptions) WithLocal(local bool) NameResolveOption { +// Local is an option for Name.Resolve which specifies if the lookup should be +// offline. Default value is false +func (_ nameOpts) Local(local bool) NameResolveOption { return func(settings *NameResolveSettings) error { settings.Local = local return nil } } -func (api *NameOptions) WithCache(cache bool) NameResolveOption { +// Cache is an option for Name.Resolve which specifies if cache should be used. +// Default value is true +func (_ nameOpts) Cache(cache bool) NameResolveOption { return func(settings *NameResolveSettings) error { settings.Cache = cache return nil diff --git a/core/coreiface/options/object.go b/core/coreiface/options/object.go index 9c8c9a9dd..00e41d28b 100644 --- a/core/coreiface/options/object.go +++ b/core/coreiface/options/object.go @@ -60,30 +60,52 @@ func ObjectAddLinkOptions(opts ...ObjectAddLinkOption) (*ObjectAddLinkSettings, return options, nil } -type ObjectOptions struct{} +type objectOpts struct{} -func (api *ObjectOptions) WithType(t string) ObjectNewOption { +var Object objectOpts + +// Type is an option for Object.New which allows to change the type of created +// dag node. +// +// Supported types: +// * 'empty' - Empty node +// * 'unixfs-dir' - Empty UnixFS directory +func (_ objectOpts) Type(t string) ObjectNewOption { return func(settings *ObjectNewSettings) error { settings.Type = t return nil } } -func (api *ObjectOptions) WithInputEnc(e string) ObjectPutOption { +// InputEnc is an option for Object.Put which specifies the input encoding of the +// data. Default is "json". +// +// Supported encodings: +// * "protobuf" +// * "json" +func (_ objectOpts) InputEnc(e string) ObjectPutOption { return func(settings *ObjectPutSettings) error { settings.InputEnc = e return nil } } -func (api *ObjectOptions) WithDataType(t string) ObjectPutOption { +// DataType is an option for Object.Put which specifies the encoding of data +// field when using Json or XML input encoding. +// +// Supported types: +// * "text" (default) +// * "base64" +func (_ objectOpts) DataType(t string) ObjectPutOption { return func(settings *ObjectPutSettings) error { settings.DataType = t return nil } } -func (api *ObjectOptions) WithCreate(create bool) ObjectAddLinkOption { +// Create is an option for Object.AddLink which specifies whether create required +// directories for the child +func (_ objectOpts) Create(create bool) ObjectAddLinkOption { return func(settings *ObjectAddLinkSettings) error { settings.Create = create return nil diff --git a/core/coreiface/options/pin.go b/core/coreiface/options/pin.go index f97f7b16e..680ed391d 100644 --- a/core/coreiface/options/pin.go +++ b/core/coreiface/options/pin.go @@ -61,23 +61,38 @@ func PinUpdateOptions(opts ...PinUpdateOption) (*PinUpdateSettings, error) { return options, nil } -type PinOptions struct{} +type pinOpts struct{} -func (api *PinOptions) WithRecursive(recucsive bool) PinAddOption { +var Pin pinOpts + +// Recursive is an option for Pin.Add which specifies whether to pin an entire +// object tree or just one object. Default: true +func (_ pinOpts) Recursive(recucsive bool) PinAddOption { return func(settings *PinAddSettings) error { settings.Recursive = recucsive return nil } } -func (api *PinOptions) WithType(t string) PinLsOption { +// Type is an option for Pin.Ls which allows to specify which pin types should +// be returned +// +// Supported values: +// * "direct" - directly pinned objects +// * "recursive" - roots of recursive pins +// * "indirect" - indirectly pinned objects (referenced by recursively pinned +// objects) +// * "all" - all pinned objects (default) +func (_ pinOpts) Type(t string) PinLsOption { return func(settings *PinLsSettings) error { settings.Type = t return nil } } -func (api *PinOptions) WithUnpin(unpin bool) PinUpdateOption { +// Unpin is an option for Pin.Update which specifies whether to remove the old pin. +// Default is true. +func (_ pinOpts) Unpin(unpin bool) PinUpdateOption { return func(settings *PinUpdateSettings) error { settings.Unpin = unpin return nil diff --git a/core/coreiface/pin.go b/core/coreiface/pin.go index 47a5a0bb2..5994c7586 100644 --- a/core/coreiface/pin.go +++ b/core/coreiface/pin.go @@ -39,24 +39,9 @@ type PinAPI interface { // tree Add(context.Context, Path, ...options.PinAddOption) error - // WithRecursive is an option for Add which specifies whether to pin an entire - // object tree or just one object. Default: true - WithRecursive(bool) options.PinAddOption - // Ls returns list of pinned objects on this node Ls(context.Context, ...options.PinLsOption) ([]Pin, error) - // WithType is an option for Ls which allows to specify which pin types should - // be returned - // - // Supported values: - // * "direct" - directly pinned objects - // * "recursive" - roots of recursive pins - // * "indirect" - indirectly pinned objects (referenced by recursively pinned - // objects) - // * "all" - all pinned objects (default) - WithType(string) options.PinLsOption - // Rm removes pin for object specified by the path Rm(context.Context, Path) error From 8fea8513e3acbd23258c873a02808daf62ced490 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Sun, 25 Mar 2018 13:58:29 +0200 Subject: [PATCH 0047/1212] coreapi: use defined functions for pin type option MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@2e3f9758c88ce4572922c3fd4e8ef51c703e183d This commit was moved from ipfs/boxo@8a0f4029598ebf3be0d56e91fe07675702349a6d --- core/coreiface/options/pin.go | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/core/coreiface/options/pin.go b/core/coreiface/options/pin.go index 680ed391d..7cb4d09d2 100644 --- a/core/coreiface/options/pin.go +++ b/core/coreiface/options/pin.go @@ -61,10 +61,38 @@ func PinUpdateOptions(opts ...PinUpdateOption) (*PinUpdateSettings, error) { return options, nil } -type pinOpts struct{} +type pinType struct{} + +type pinOpts struct { + Type pinType +} var Pin pinOpts +// All is an option for Pin.Ls which will make it return all pins. It is +// the default +func (_ pinType) All() PinLsOption { + return Pin.pinType("all") +} + +// Recursive is an option for Pin.Ls which will make it only return recursive +// pins +func (_ pinType) Recursive() PinLsOption { + return Pin.pinType("recursive") +} + +// Direct is an option for Pin.Ls which will make it only return direct (non +// recursive) pins +func (_ pinType) Direct() PinLsOption { + return Pin.pinType("direct") +} + +// Indirect is an option for Pin.Ls which will make it only return indirect pins +// (objects referenced by other recursively pinned objects) +func (_ pinType) Indirect() PinLsOption { + return Pin.pinType("indirect") +} + // Recursive is an option for Pin.Add which specifies whether to pin an entire // object tree or just one object. Default: true func (_ pinOpts) Recursive(recucsive bool) PinAddOption { @@ -83,7 +111,7 @@ func (_ pinOpts) Recursive(recucsive bool) PinAddOption { // * "indirect" - indirectly pinned objects (referenced by recursively pinned // objects) // * "all" - all pinned objects (default) -func (_ pinOpts) Type(t string) PinLsOption { +func (_ pinOpts) pinType(t string) PinLsOption { return func(settings *PinLsSettings) error { settings.Type = t return nil From b5d36c8a1b2d8477021f4a7c3b044bfc5913e173 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Sun, 25 Mar 2018 14:09:59 +0200 Subject: [PATCH 0048/1212] coreapi: don't use underscores in opt reciever funcs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@8b65fc5e1ed16902cda0e3e36fe624b01856b182 This commit was moved from ipfs/boxo@6bd3ea5ab8c0df771963b4f8a9f5cfdc18a95b6d --- core/coreiface/options/block.go | 6 +++--- core/coreiface/options/dag.go | 8 ++++---- core/coreiface/options/key.go | 6 +++--- core/coreiface/options/name.go | 10 +++++----- core/coreiface/options/object.go | 8 ++++---- core/coreiface/options/pin.go | 14 +++++++------- 6 files changed, 26 insertions(+), 26 deletions(-) diff --git a/core/coreiface/options/block.go b/core/coreiface/options/block.go index 20320705e..55964b2b7 100644 --- a/core/coreiface/options/block.go +++ b/core/coreiface/options/block.go @@ -53,7 +53,7 @@ var Block blockOpts // Format is an option for Block.Put which specifies the multicodec to use to // serialize the object. Default is "v0" -func (_ blockOpts) Format(codec string) BlockPutOption { +func (blockOpts) Format(codec string) BlockPutOption { return func(settings *BlockPutSettings) error { settings.Codec = codec return nil @@ -63,7 +63,7 @@ func (_ blockOpts) Format(codec string) BlockPutOption { // Hash is an option for Block.Put which specifies the multihash settings to use // when hashing the object. Default is mh.SHA2_256 (0x12). // If mhLen is set to -1, default length for the hash will be used -func (_ blockOpts) Hash(mhType uint64, mhLen int) BlockPutOption { +func (blockOpts) Hash(mhType uint64, mhLen int) BlockPutOption { return func(settings *BlockPutSettings) error { settings.MhType = mhType settings.MhLength = mhLen @@ -73,7 +73,7 @@ func (_ blockOpts) Hash(mhType uint64, mhLen int) BlockPutOption { // Force is an option for Block.Rm which, when set to true, will ignore // non-existing blocks -func (_ blockOpts) Force(force bool) BlockRmOption { +func (blockOpts) Force(force bool) BlockRmOption { return func(settings *BlockRmSettings) error { settings.Force = force return nil diff --git a/core/coreiface/options/dag.go b/core/coreiface/options/dag.go index ec258cf95..96eea5b46 100644 --- a/core/coreiface/options/dag.go +++ b/core/coreiface/options/dag.go @@ -57,7 +57,7 @@ var Dag dagOpts // InputEnc is an option for Dag.Put which specifies the input encoding of the // data. Default is "json", most formats/codecs support "raw" -func (_ dagOpts) InputEnc(enc string) DagPutOption { +func (dagOpts) InputEnc(enc string) DagPutOption { return func(settings *DagPutSettings) error { settings.InputEnc = enc return nil @@ -66,7 +66,7 @@ func (_ dagOpts) InputEnc(enc string) DagPutOption { // Codec is an option for Dag.Put which specifies the multicodec to use to // serialize the object. Default is cid.DagCBOR (0x71) -func (_ dagOpts) Codec(codec uint64) DagPutOption { +func (dagOpts) Codec(codec uint64) DagPutOption { return func(settings *DagPutSettings) error { settings.Codec = codec return nil @@ -77,7 +77,7 @@ func (_ dagOpts) Codec(codec uint64) DagPutOption { // when hashing the object. Default is based on the codec used // (mh.SHA2_256 (0x12) for DagCBOR). If mhLen is set to -1, default length for // the hash will be used -func (_ dagOpts) Hash(mhType uint64, mhLen int) DagPutOption { +func (dagOpts) Hash(mhType uint64, mhLen int) DagPutOption { return func(settings *DagPutSettings) error { settings.MhType = mhType settings.MhLength = mhLen @@ -87,7 +87,7 @@ func (_ dagOpts) Hash(mhType uint64, mhLen int) DagPutOption { // Depth is an option for Dag.Tree which specifies maximum depth of the // returned tree. Default is -1 (no depth limit) -func (_ dagOpts) Depth(depth int) DagTreeOption { +func (dagOpts) Depth(depth int) DagTreeOption { return func(settings *DagTreeSettings) error { settings.Depth = depth return nil diff --git a/core/coreiface/options/key.go b/core/coreiface/options/key.go index a29261d14..80beea352 100644 --- a/core/coreiface/options/key.go +++ b/core/coreiface/options/key.go @@ -58,7 +58,7 @@ var Key keyOpts // Supported key types: // * options.RSAKey // * options.Ed25519Key -func (_ keyOpts) Type(algorithm string) KeyGenerateOption { +func (keyOpts) Type(algorithm string) KeyGenerateOption { return func(settings *KeyGenerateSettings) error { settings.Algorithm = algorithm return nil @@ -70,7 +70,7 @@ func (_ keyOpts) Type(algorithm string) KeyGenerateOption { // // value of -1 means 'use default size for key type': // * 2048 for RSA -func (_ keyOpts) Size(size int) KeyGenerateOption { +func (keyOpts) Size(size int) KeyGenerateOption { return func(settings *KeyGenerateSettings) error { settings.Size = size return nil @@ -79,7 +79,7 @@ func (_ keyOpts) Size(size int) KeyGenerateOption { // Force is an option for Key.Rename which specifies whether to allow to // replace existing keys. -func (_ keyOpts) Force(force bool) KeyRenameOption { +func (keyOpts) Force(force bool) KeyRenameOption { return func(settings *KeyRenameSettings) error { settings.Force = force return nil diff --git a/core/coreiface/options/name.go b/core/coreiface/options/name.go index 1f6de0ee3..48aecf18b 100644 --- a/core/coreiface/options/name.go +++ b/core/coreiface/options/name.go @@ -61,7 +61,7 @@ var Name nameOpts // ValidTime is an option for Name.Publish which specifies for how long the // entry will remain valid. Default value is 24h -func (_ nameOpts) ValidTime(validTime time.Duration) NamePublishOption { +func (nameOpts) ValidTime(validTime time.Duration) NamePublishOption { return func(settings *NamePublishSettings) error { settings.ValidTime = validTime return nil @@ -73,7 +73,7 @@ func (_ nameOpts) ValidTime(validTime time.Duration) NamePublishOption { // The key parameter must be either PeerID or keystore key alias. // // You can use KeyAPI to list and generate more names and their respective keys. -func (_ nameOpts) Key(key string) NamePublishOption { +func (nameOpts) Key(key string) NamePublishOption { return func(settings *NamePublishSettings) error { settings.Key = key return nil @@ -82,7 +82,7 @@ func (_ nameOpts) Key(key string) NamePublishOption { // Recursive is an option for Name.Resolve which specifies whether to perform a // recursive lookup. Default value is false -func (_ nameOpts) Recursive(recursive bool) NameResolveOption { +func (nameOpts) Recursive(recursive bool) NameResolveOption { return func(settings *NameResolveSettings) error { settings.Recursive = recursive return nil @@ -91,7 +91,7 @@ func (_ nameOpts) Recursive(recursive bool) NameResolveOption { // Local is an option for Name.Resolve which specifies if the lookup should be // offline. Default value is false -func (_ nameOpts) Local(local bool) NameResolveOption { +func (nameOpts) Local(local bool) NameResolveOption { return func(settings *NameResolveSettings) error { settings.Local = local return nil @@ -100,7 +100,7 @@ func (_ nameOpts) Local(local bool) NameResolveOption { // Cache is an option for Name.Resolve which specifies if cache should be used. // Default value is true -func (_ nameOpts) Cache(cache bool) NameResolveOption { +func (nameOpts) Cache(cache bool) NameResolveOption { return func(settings *NameResolveSettings) error { settings.Cache = cache return nil diff --git a/core/coreiface/options/object.go b/core/coreiface/options/object.go index 00e41d28b..aca02d672 100644 --- a/core/coreiface/options/object.go +++ b/core/coreiface/options/object.go @@ -70,7 +70,7 @@ var Object objectOpts // Supported types: // * 'empty' - Empty node // * 'unixfs-dir' - Empty UnixFS directory -func (_ objectOpts) Type(t string) ObjectNewOption { +func (objectOpts) Type(t string) ObjectNewOption { return func(settings *ObjectNewSettings) error { settings.Type = t return nil @@ -83,7 +83,7 @@ func (_ objectOpts) Type(t string) ObjectNewOption { // Supported encodings: // * "protobuf" // * "json" -func (_ objectOpts) InputEnc(e string) ObjectPutOption { +func (objectOpts) InputEnc(e string) ObjectPutOption { return func(settings *ObjectPutSettings) error { settings.InputEnc = e return nil @@ -96,7 +96,7 @@ func (_ objectOpts) InputEnc(e string) ObjectPutOption { // Supported types: // * "text" (default) // * "base64" -func (_ objectOpts) DataType(t string) ObjectPutOption { +func (objectOpts) DataType(t string) ObjectPutOption { return func(settings *ObjectPutSettings) error { settings.DataType = t return nil @@ -105,7 +105,7 @@ func (_ objectOpts) DataType(t string) ObjectPutOption { // Create is an option for Object.AddLink which specifies whether create required // directories for the child -func (_ objectOpts) Create(create bool) ObjectAddLinkOption { +func (objectOpts) Create(create bool) ObjectAddLinkOption { return func(settings *ObjectAddLinkSettings) error { settings.Create = create return nil diff --git a/core/coreiface/options/pin.go b/core/coreiface/options/pin.go index 7cb4d09d2..e46c27246 100644 --- a/core/coreiface/options/pin.go +++ b/core/coreiface/options/pin.go @@ -71,31 +71,31 @@ var Pin pinOpts // All is an option for Pin.Ls which will make it return all pins. It is // the default -func (_ pinType) All() PinLsOption { +func (pinType) All() PinLsOption { return Pin.pinType("all") } // Recursive is an option for Pin.Ls which will make it only return recursive // pins -func (_ pinType) Recursive() PinLsOption { +func (pinType) Recursive() PinLsOption { return Pin.pinType("recursive") } // Direct is an option for Pin.Ls which will make it only return direct (non // recursive) pins -func (_ pinType) Direct() PinLsOption { +func (pinType) Direct() PinLsOption { return Pin.pinType("direct") } // Indirect is an option for Pin.Ls which will make it only return indirect pins // (objects referenced by other recursively pinned objects) -func (_ pinType) Indirect() PinLsOption { +func (pinType) Indirect() PinLsOption { return Pin.pinType("indirect") } // Recursive is an option for Pin.Add which specifies whether to pin an entire // object tree or just one object. Default: true -func (_ pinOpts) Recursive(recucsive bool) PinAddOption { +func (pinOpts) Recursive(recucsive bool) PinAddOption { return func(settings *PinAddSettings) error { settings.Recursive = recucsive return nil @@ -111,7 +111,7 @@ func (_ pinOpts) Recursive(recucsive bool) PinAddOption { // * "indirect" - indirectly pinned objects (referenced by recursively pinned // objects) // * "all" - all pinned objects (default) -func (_ pinOpts) pinType(t string) PinLsOption { +func (pinOpts) pinType(t string) PinLsOption { return func(settings *PinLsSettings) error { settings.Type = t return nil @@ -120,7 +120,7 @@ func (_ pinOpts) pinType(t string) PinLsOption { // Unpin is an option for Pin.Update which specifies whether to remove the old pin. // Default is true. -func (_ pinOpts) Unpin(unpin bool) PinUpdateOption { +func (pinOpts) Unpin(unpin bool) PinUpdateOption { return func(settings *PinUpdateSettings) error { settings.Unpin = unpin return nil From 7ffe2f640d3ee26d8aee1f418f1e7c805478fafb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 19 Mar 2018 03:41:28 +0100 Subject: [PATCH 0049/1212] misc: Fix a few typos MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@646b14412abd5b2382fc11f37e40ef592c557fcb This commit was moved from ipfs/boxo@76ac2a8842d68a73acece177235ec746ca637793 --- core/coreiface/options/pin.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/coreiface/options/pin.go b/core/coreiface/options/pin.go index e46c27246..9d1107f92 100644 --- a/core/coreiface/options/pin.go +++ b/core/coreiface/options/pin.go @@ -95,9 +95,9 @@ func (pinType) Indirect() PinLsOption { // Recursive is an option for Pin.Add which specifies whether to pin an entire // object tree or just one object. Default: true -func (pinOpts) Recursive(recucsive bool) PinAddOption { +func (pinOpts) Recursive(recursive bool) PinAddOption { return func(settings *PinAddSettings) error { - settings.Recursive = recucsive + settings.Recursive = recursive return nil } } From 557277dda8b6c276d95f9fcec7721c014c60b5ee Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Fri, 8 Jun 2018 22:01:00 -0700 Subject: [PATCH 0050/1212] gx update go-log, sys, go-crypto * go-log * sys * go-crypto License: MIT Signed-off-by: Steven Allen This commit was moved from ipfs/interface-go-ipfs-core@0e613d93eacb5247a4ca23790a5fe82dde8917dc This commit was moved from ipfs/boxo@724c6143570accc8e163cc355b46eff0338f52e5 --- core/coreiface/coreapi.go | 2 +- core/coreiface/dag.go | 2 +- core/coreiface/object.go | 4 ++-- core/coreiface/options/block.go | 2 +- core/coreiface/options/dag.go | 2 +- core/coreiface/path.go | 2 +- core/coreiface/unixfs.go | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/core/coreiface/coreapi.go b/core/coreiface/coreapi.go index 9428b3b63..220f8df50 100644 --- a/core/coreiface/coreapi.go +++ b/core/coreiface/coreapi.go @@ -5,7 +5,7 @@ package iface import ( "context" - ipld "gx/ipfs/Qme5bWv7wtjUNGsK2BNGVUFPKiuxWrsqrtvYwCLRw8YFES/go-ipld-format" + ipld "gx/ipfs/QmWi2BYBL5gJ3CiAiQchg6rn1A8iBsrWy51EYxvHVjFvLb/go-ipld-format" ) // CoreAPI defines an unified interface to IPFS for Go programs diff --git a/core/coreiface/dag.go b/core/coreiface/dag.go index f20c88f25..3c4dc0c3a 100644 --- a/core/coreiface/dag.go +++ b/core/coreiface/dag.go @@ -6,7 +6,7 @@ import ( options "github.com/ipfs/go-ipfs/core/coreapi/interface/options" - ipld "gx/ipfs/Qme5bWv7wtjUNGsK2BNGVUFPKiuxWrsqrtvYwCLRw8YFES/go-ipld-format" + ipld "gx/ipfs/QmWi2BYBL5gJ3CiAiQchg6rn1A8iBsrWy51EYxvHVjFvLb/go-ipld-format" ) // DagAPI specifies the interface to IPLD diff --git a/core/coreiface/object.go b/core/coreiface/object.go index 548b15a73..d53f4d214 100644 --- a/core/coreiface/object.go +++ b/core/coreiface/object.go @@ -6,8 +6,8 @@ import ( options "github.com/ipfs/go-ipfs/core/coreapi/interface/options" - cid "gx/ipfs/QmcZfnkapfECQGcLZaf9B79NRg7cRa9EnZh4LSbkCzwNvY/go-cid" - ipld "gx/ipfs/Qme5bWv7wtjUNGsK2BNGVUFPKiuxWrsqrtvYwCLRw8YFES/go-ipld-format" + ipld "gx/ipfs/QmWi2BYBL5gJ3CiAiQchg6rn1A8iBsrWy51EYxvHVjFvLb/go-ipld-format" + cid "gx/ipfs/QmapdYm1b22Frv3k17fqrBYTFRxwiaVJkB299Mfn33edeB/go-cid" ) // ObjectStat provides information about dag nodes diff --git a/core/coreiface/options/block.go b/core/coreiface/options/block.go index 55964b2b7..d6da99774 100644 --- a/core/coreiface/options/block.go +++ b/core/coreiface/options/block.go @@ -1,7 +1,7 @@ package options import ( - "gx/ipfs/QmZyZDi491cCNTLfAhwcaDii2Kg4pwKRkhqQzURGDvY6ua/go-multihash" + "gx/ipfs/QmPnFwZ2JXKnXgMw8CdBPxn7FWh6LLdjUjxV1fKHuJnkr8/go-multihash" ) type BlockPutSettings struct { diff --git a/core/coreiface/options/dag.go b/core/coreiface/options/dag.go index 96eea5b46..b5e6dcea1 100644 --- a/core/coreiface/options/dag.go +++ b/core/coreiface/options/dag.go @@ -3,7 +3,7 @@ package options import ( "math" - cid "gx/ipfs/QmcZfnkapfECQGcLZaf9B79NRg7cRa9EnZh4LSbkCzwNvY/go-cid" + cid "gx/ipfs/QmapdYm1b22Frv3k17fqrBYTFRxwiaVJkB299Mfn33edeB/go-cid" ) type DagPutSettings struct { diff --git a/core/coreiface/path.go b/core/coreiface/path.go index b2160b942..929b97bcd 100644 --- a/core/coreiface/path.go +++ b/core/coreiface/path.go @@ -1,7 +1,7 @@ package iface import ( - cid "gx/ipfs/QmcZfnkapfECQGcLZaf9B79NRg7cRa9EnZh4LSbkCzwNvY/go-cid" + cid "gx/ipfs/QmapdYm1b22Frv3k17fqrBYTFRxwiaVJkB299Mfn33edeB/go-cid" ) // Path is a generic wrapper for paths used in the API. A path can be resolved diff --git a/core/coreiface/unixfs.go b/core/coreiface/unixfs.go index c1b4efa43..11e14cc84 100644 --- a/core/coreiface/unixfs.go +++ b/core/coreiface/unixfs.go @@ -4,7 +4,7 @@ import ( "context" "io" - ipld "gx/ipfs/Qme5bWv7wtjUNGsK2BNGVUFPKiuxWrsqrtvYwCLRw8YFES/go-ipld-format" + ipld "gx/ipfs/QmWi2BYBL5gJ3CiAiQchg6rn1A8iBsrWy51EYxvHVjFvLb/go-ipld-format" ) // UnixfsAPI is the basic interface to immutable files in IPFS From 7ffcd2a1be865e92ce369998a9a8147f45ce7e5c Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Mon, 16 Jul 2018 15:16:49 -0700 Subject: [PATCH 0051/1212] update go-cid alternative to #5243 that updates go-cid and all packages that depend on it License: MIT Signed-off-by: Steven Allen This commit was moved from ipfs/interface-go-ipfs-core@2c9291a232cb0febaf3bb029694ce2fb3155d3f9 This commit was moved from ipfs/boxo@c77c8df70d4c804e1f3acd068a8ef58937e7ef9e --- core/coreiface/coreapi.go | 2 +- core/coreiface/dag.go | 2 +- core/coreiface/object.go | 4 ++-- core/coreiface/options/dag.go | 2 +- core/coreiface/path.go | 2 +- core/coreiface/unixfs.go | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/core/coreiface/coreapi.go b/core/coreiface/coreapi.go index 220f8df50..a77ad6367 100644 --- a/core/coreiface/coreapi.go +++ b/core/coreiface/coreapi.go @@ -5,7 +5,7 @@ package iface import ( "context" - ipld "gx/ipfs/QmWi2BYBL5gJ3CiAiQchg6rn1A8iBsrWy51EYxvHVjFvLb/go-ipld-format" + ipld "gx/ipfs/QmZtNq8dArGfnpCZfx2pUNY7UcjGhVp5qqwQ4hH6mpTMRQ/go-ipld-format" ) // CoreAPI defines an unified interface to IPFS for Go programs diff --git a/core/coreiface/dag.go b/core/coreiface/dag.go index 3c4dc0c3a..158db7419 100644 --- a/core/coreiface/dag.go +++ b/core/coreiface/dag.go @@ -6,7 +6,7 @@ import ( options "github.com/ipfs/go-ipfs/core/coreapi/interface/options" - ipld "gx/ipfs/QmWi2BYBL5gJ3CiAiQchg6rn1A8iBsrWy51EYxvHVjFvLb/go-ipld-format" + ipld "gx/ipfs/QmZtNq8dArGfnpCZfx2pUNY7UcjGhVp5qqwQ4hH6mpTMRQ/go-ipld-format" ) // DagAPI specifies the interface to IPLD diff --git a/core/coreiface/object.go b/core/coreiface/object.go index d53f4d214..a18a38ebe 100644 --- a/core/coreiface/object.go +++ b/core/coreiface/object.go @@ -6,8 +6,8 @@ import ( options "github.com/ipfs/go-ipfs/core/coreapi/interface/options" - ipld "gx/ipfs/QmWi2BYBL5gJ3CiAiQchg6rn1A8iBsrWy51EYxvHVjFvLb/go-ipld-format" - cid "gx/ipfs/QmapdYm1b22Frv3k17fqrBYTFRxwiaVJkB299Mfn33edeB/go-cid" + cid "gx/ipfs/QmYVNvtQkeZ6AKSwDrjQTs432QtL6umrrK41EBq3cu7iSP/go-cid" + ipld "gx/ipfs/QmZtNq8dArGfnpCZfx2pUNY7UcjGhVp5qqwQ4hH6mpTMRQ/go-ipld-format" ) // ObjectStat provides information about dag nodes diff --git a/core/coreiface/options/dag.go b/core/coreiface/options/dag.go index b5e6dcea1..57465deee 100644 --- a/core/coreiface/options/dag.go +++ b/core/coreiface/options/dag.go @@ -3,7 +3,7 @@ package options import ( "math" - cid "gx/ipfs/QmapdYm1b22Frv3k17fqrBYTFRxwiaVJkB299Mfn33edeB/go-cid" + cid "gx/ipfs/QmYVNvtQkeZ6AKSwDrjQTs432QtL6umrrK41EBq3cu7iSP/go-cid" ) type DagPutSettings struct { diff --git a/core/coreiface/path.go b/core/coreiface/path.go index 929b97bcd..51513772f 100644 --- a/core/coreiface/path.go +++ b/core/coreiface/path.go @@ -1,7 +1,7 @@ package iface import ( - cid "gx/ipfs/QmapdYm1b22Frv3k17fqrBYTFRxwiaVJkB299Mfn33edeB/go-cid" + cid "gx/ipfs/QmYVNvtQkeZ6AKSwDrjQTs432QtL6umrrK41EBq3cu7iSP/go-cid" ) // Path is a generic wrapper for paths used in the API. A path can be resolved diff --git a/core/coreiface/unixfs.go b/core/coreiface/unixfs.go index 11e14cc84..c59451d00 100644 --- a/core/coreiface/unixfs.go +++ b/core/coreiface/unixfs.go @@ -4,7 +4,7 @@ import ( "context" "io" - ipld "gx/ipfs/QmWi2BYBL5gJ3CiAiQchg6rn1A8iBsrWy51EYxvHVjFvLb/go-ipld-format" + ipld "gx/ipfs/QmZtNq8dArGfnpCZfx2pUNY7UcjGhVp5qqwQ4hH6mpTMRQ/go-ipld-format" ) // UnixfsAPI is the basic interface to immutable files in IPFS From 63e861e549469348c5b075da5920df32c12689b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 2 Feb 2018 16:00:37 +0100 Subject: [PATCH 0052/1212] coreapi: expand public path api MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@ad6db2fc4cff3178bb50aacbe30559078661907b This commit was moved from ipfs/boxo@3b1cf7aed3af88561e5b851f79d4b480c59d1ce5 --- core/coreiface/coreapi.go | 13 +++++++++++++ core/coreiface/options/path.go | 30 ++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 core/coreiface/options/path.go diff --git a/core/coreiface/coreapi.go b/core/coreiface/coreapi.go index a77ad6367..179531352 100644 --- a/core/coreiface/coreapi.go +++ b/core/coreiface/coreapi.go @@ -5,6 +5,9 @@ package iface import ( "context" + options "github.com/ipfs/go-ipfs/core/coreapi/interface/options" + + cid "gx/ipfs/QmapdYm1b22Frv3k17fqrBYTFRxwiaVJkB299Mfn33edeB/go-cid" ipld "gx/ipfs/QmZtNq8dArGfnpCZfx2pUNY7UcjGhVp5qqwQ4hH6mpTMRQ/go-ipld-format" ) @@ -37,4 +40,14 @@ type CoreAPI interface { // ResolveNode resolves the path (if not resolved already) using Unixfs // resolver, gets and returns the resolved Node ResolveNode(context.Context, Path) (ipld.Node, error) + + // ParsePath parses string path to a Path + ParsePath(context.Context, string, ...options.ParsePathOption) (Path, error) + + // WithResolve is an option for ParsePath which when set to true tells + // ParsePath to also resolve the path + WithResolve(bool) options.ParsePathOption + + // ParseCid creates new path from the provided CID + ParseCid(*cid.Cid) Path } diff --git a/core/coreiface/options/path.go b/core/coreiface/options/path.go new file mode 100644 index 000000000..bf6eed65b --- /dev/null +++ b/core/coreiface/options/path.go @@ -0,0 +1,30 @@ +package options + +type ParsePathSettings struct { + Resolve bool +} + +type ParsePathOption func(*ParsePathSettings) error + +func ParsePathOptions(opts ...ParsePathOption) (*ParsePathSettings, error) { + options := &ParsePathSettings{ + Resolve: false, + } + + for _, opt := range opts { + err := opt(options) + if err != nil { + return nil, err + } + } + return options, nil +} + +type ApiOptions struct{} + +func (api *ApiOptions) WithResolve(r bool) ParsePathOption { + return func(settings *ParsePathSettings) error { + settings.Resolve = r + return nil + } +} From 161503c26f9fdc99045fc10d731bb8036769e390 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 8 Feb 2018 17:39:05 +0100 Subject: [PATCH 0053/1212] coreapi: separate path into two types MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@79875b01300b77c8437ec0ca1b22d497edb79cd9 This commit was moved from ipfs/boxo@5a61226d830993d09c7d76d970b1c5a9de94f834 --- core/coreiface/block.go | 4 ++-- core/coreiface/coreapi.go | 14 ++++---------- core/coreiface/dag.go | 2 +- core/coreiface/object.go | 10 +++++----- core/coreiface/options/path.go | 30 ------------------------------ core/coreiface/path.go | 15 +++++++++++++-- core/coreiface/pin.go | 4 ++-- core/coreiface/unixfs.go | 2 +- 8 files changed, 28 insertions(+), 53 deletions(-) delete mode 100644 core/coreiface/options/path.go diff --git a/core/coreiface/block.go b/core/coreiface/block.go index a9e577d76..468c00947 100644 --- a/core/coreiface/block.go +++ b/core/coreiface/block.go @@ -13,13 +13,13 @@ type BlockStat interface { Size() int // Path returns path to the block - Path() Path + Path() ResolvedPath } // BlockAPI specifies the interface to the block layer type BlockAPI interface { // Put imports raw block data, hashing it using specified settings. - Put(context.Context, io.Reader, ...options.BlockPutOption) (Path, error) + Put(context.Context, io.Reader, ...options.BlockPutOption) (ResolvedPath, error) // Get attempts to resolve the path and return a reader for data in the block Get(context.Context, Path) (io.Reader, error) diff --git a/core/coreiface/coreapi.go b/core/coreiface/coreapi.go index 179531352..615b039b3 100644 --- a/core/coreiface/coreapi.go +++ b/core/coreiface/coreapi.go @@ -5,10 +5,8 @@ package iface import ( "context" - options "github.com/ipfs/go-ipfs/core/coreapi/interface/options" - - cid "gx/ipfs/QmapdYm1b22Frv3k17fqrBYTFRxwiaVJkB299Mfn33edeB/go-cid" ipld "gx/ipfs/QmZtNq8dArGfnpCZfx2pUNY7UcjGhVp5qqwQ4hH6mpTMRQ/go-ipld-format" + cid "gx/ipfs/QmapdYm1b22Frv3k17fqrBYTFRxwiaVJkB299Mfn33edeB/go-cid" ) // CoreAPI defines an unified interface to IPFS for Go programs @@ -35,19 +33,15 @@ type CoreAPI interface { Object() ObjectAPI // ResolvePath resolves the path using Unixfs resolver - ResolvePath(context.Context, Path) (Path, error) + ResolvePath(context.Context, Path) (ResolvedPath, error) // ResolveNode resolves the path (if not resolved already) using Unixfs // resolver, gets and returns the resolved Node ResolveNode(context.Context, Path) (ipld.Node, error) // ParsePath parses string path to a Path - ParsePath(context.Context, string, ...options.ParsePathOption) (Path, error) - - // WithResolve is an option for ParsePath which when set to true tells - // ParsePath to also resolve the path - WithResolve(bool) options.ParsePathOption + ParsePath(context.Context, string) (Path, error) // ParseCid creates new path from the provided CID - ParseCid(*cid.Cid) Path + ParseCid(*cid.Cid) ResolvedPath } diff --git a/core/coreiface/dag.go b/core/coreiface/dag.go index 158db7419..3f92ebab3 100644 --- a/core/coreiface/dag.go +++ b/core/coreiface/dag.go @@ -14,7 +14,7 @@ type DagAPI interface { // Put inserts data using specified format and input encoding. // Unless used with WithCodec or WithHash, the defaults "dag-cbor" and // "sha256" are used. - Put(ctx context.Context, src io.Reader, opts ...options.DagPutOption) (Path, error) + Put(ctx context.Context, src io.Reader, opts ...options.DagPutOption) (ResolvedPath, error) // Get attempts to resolve and get the node specified by the path Get(ctx context.Context, path Path) (ipld.Node, error) diff --git a/core/coreiface/object.go b/core/coreiface/object.go index a18a38ebe..ea9aa5948 100644 --- a/core/coreiface/object.go +++ b/core/coreiface/object.go @@ -38,7 +38,7 @@ type ObjectAPI interface { New(context.Context, ...options.ObjectNewOption) (ipld.Node, error) // Put imports the data into merkledag - Put(context.Context, io.Reader, ...options.ObjectPutOption) (Path, error) + Put(context.Context, io.Reader, ...options.ObjectPutOption) (ResolvedPath, error) // Get returns the node for the path Get(context.Context, Path) (ipld.Node, error) @@ -55,14 +55,14 @@ type ObjectAPI interface { // AddLink adds a link under the specified path. child path can point to a // subdirectory within the patent which must be present (can be overridden // with WithCreate option). - AddLink(ctx context.Context, base Path, name string, child Path, opts ...options.ObjectAddLinkOption) (Path, error) + AddLink(ctx context.Context, base Path, name string, child Path, opts ...options.ObjectAddLinkOption) (ResolvedPath, error) // RmLink removes a link from the node - RmLink(ctx context.Context, base Path, link string) (Path, error) + RmLink(ctx context.Context, base Path, link string) (ResolvedPath, error) // AppendData appends data to the node - AppendData(context.Context, Path, io.Reader) (Path, error) + AppendData(context.Context, Path, io.Reader) (ResolvedPath, error) // SetData sets the data contained in the node - SetData(context.Context, Path, io.Reader) (Path, error) + SetData(context.Context, Path, io.Reader) (ResolvedPath, error) } diff --git a/core/coreiface/options/path.go b/core/coreiface/options/path.go deleted file mode 100644 index bf6eed65b..000000000 --- a/core/coreiface/options/path.go +++ /dev/null @@ -1,30 +0,0 @@ -package options - -type ParsePathSettings struct { - Resolve bool -} - -type ParsePathOption func(*ParsePathSettings) error - -func ParsePathOptions(opts ...ParsePathOption) (*ParsePathSettings, error) { - options := &ParsePathSettings{ - Resolve: false, - } - - for _, opt := range opts { - err := opt(options) - if err != nil { - return nil, err - } - } - return options, nil -} - -type ApiOptions struct{} - -func (api *ApiOptions) WithResolve(r bool) ParsePathOption { - return func(settings *ParsePathSettings) error { - settings.Resolve = r - return nil - } -} diff --git a/core/coreiface/path.go b/core/coreiface/path.go index 51513772f..4cfd916de 100644 --- a/core/coreiface/path.go +++ b/core/coreiface/path.go @@ -6,13 +6,24 @@ import ( // Path is a generic wrapper for paths used in the API. A path can be resolved // to a CID using one of Resolve functions in the API. +// TODO: figure out/explain namespaces type Path interface { // String returns the path as a string. String() string + + // Namespace returns the first component of the path + Namespace() string +} + +// ResolvedPath is a resolved Path +type ResolvedPath interface { // Cid returns cid referred to by path Cid() *cid.Cid + // Root returns cid of root path Root() *cid.Cid - // Resolved returns whether path has been fully resolved - Resolved() bool + + //TODO: Path remainder + + Path } diff --git a/core/coreiface/pin.go b/core/coreiface/pin.go index 5994c7586..2e119cbea 100644 --- a/core/coreiface/pin.go +++ b/core/coreiface/pin.go @@ -9,7 +9,7 @@ import ( // Pin holds information about pinned resource type Pin interface { // Path to the pinned object - Path() Path + Path() ResolvedPath // Type of the pin Type() string @@ -27,7 +27,7 @@ type PinStatus interface { // BadPinNode is a node that has been marked as bad by Pin.Verify type BadPinNode interface { // Path is the path of the node - Path() Path + Path() ResolvedPath // Err is the reason why the node has been marked as bad Err() error diff --git a/core/coreiface/unixfs.go b/core/coreiface/unixfs.go index c59451d00..1ddc20674 100644 --- a/core/coreiface/unixfs.go +++ b/core/coreiface/unixfs.go @@ -10,7 +10,7 @@ import ( // UnixfsAPI is the basic interface to immutable files in IPFS type UnixfsAPI interface { // Add imports the data from the reader into merkledag file - Add(context.Context, io.Reader) (Path, error) + Add(context.Context, io.Reader) (ResolvedPath, error) // Cat returns a reader for the file Cat(context.Context, Path) (Reader, error) From fd3e7b365a6752016b836ab1dd1eef45580522cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 30 Mar 2018 22:21:57 +0200 Subject: [PATCH 0054/1212] coreapi: remove ctx from ParsePath, split ParseCid MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@e4a333226c4cff7d76082700c14391133af6a7e5 This commit was moved from ipfs/boxo@38520ef87802adf0c77aaece8cc9d203b65461d5 --- core/coreiface/coreapi.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/core/coreiface/coreapi.go b/core/coreiface/coreapi.go index 615b039b3..f5e81adce 100644 --- a/core/coreiface/coreapi.go +++ b/core/coreiface/coreapi.go @@ -40,8 +40,11 @@ type CoreAPI interface { ResolveNode(context.Context, Path) (ipld.Node, error) // ParsePath parses string path to a Path - ParsePath(context.Context, string) (Path, error) + ParsePath(string) (Path, error) - // ParseCid creates new path from the provided CID - ParseCid(*cid.Cid) ResolvedPath + // IpfsPath creates new /ipfs path from the provided CID + IpfsPath(*cid.Cid) ResolvedPath + + // IpldPath creates new /ipld path from the provided CID + IpldPath(*cid.Cid) ResolvedPath } From 2aed59e080591ca0e2a41feb5e011332340cf965 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 30 Mar 2018 22:44:23 +0200 Subject: [PATCH 0055/1212] coreapi: path.Mutable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@bbff408d0ee7a756bce56956d0e72f0a3df6bbbc This commit was moved from ipfs/boxo@620bec8b444b2c41107a2aa8a0ed39062be3b877 --- core/coreiface/path.go | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/core/coreiface/path.go b/core/coreiface/path.go index 4cfd916de..bb87a6b3b 100644 --- a/core/coreiface/path.go +++ b/core/coreiface/path.go @@ -6,13 +6,25 @@ import ( // Path is a generic wrapper for paths used in the API. A path can be resolved // to a CID using one of Resolve functions in the API. -// TODO: figure out/explain namespaces +// +// Paths must be prefixed with a valid prefix: +// +// * /ipfs - Immutable unixfs path (files) +// * /ipld - Immutable ipld path (data) +// * /ipns - Mutable names. Usually resolves to one of the immutable paths +//TODO: /local (MFS) type Path interface { // String returns the path as a string. String() string // Namespace returns the first component of the path Namespace() string + + // Mutable returns false if the data pointed to by this path in guaranteed + // to not change. + // + // Note that resolved mutable path can be immutable. + Mutable() bool } // ResolvedPath is a resolved Path From 16ea6d13bacead469e49ea8135fc5d42342626fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 3 Apr 2018 14:49:33 +0200 Subject: [PATCH 0056/1212] coreapi: path remainders MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@a6d0272a575722dbaef8c21c869e7625692fe7f6 This commit was moved from ipfs/boxo@d0da662cf78f21d6e3d170b11e33da14444f838b --- core/coreiface/path.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/core/coreiface/path.go b/core/coreiface/path.go index bb87a6b3b..b4a9f0dbd 100644 --- a/core/coreiface/path.go +++ b/core/coreiface/path.go @@ -29,13 +29,14 @@ type Path interface { // ResolvedPath is a resolved Path type ResolvedPath interface { - // Cid returns cid referred to by path + // Cid returns the CID referred to by path Cid() *cid.Cid - // Root returns cid of root path + // Root returns the CID of root path Root() *cid.Cid - //TODO: Path remainder + // Remainder returns unresolved part of the path + Remainder() string Path } From 06f1d1a19a8863b41d9e9d7095ba00333be49598 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 20 Apr 2018 13:56:33 +0200 Subject: [PATCH 0057/1212] coreapi: add more docs for path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@5abaad9e8573557e0bd7f3b1b45838053a85ffd7 This commit was moved from ipfs/boxo@d1d67409e744a2a697a3c05de0eb34b0bfbed175 --- core/coreiface/path.go | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/core/coreiface/path.go b/core/coreiface/path.go index b4a9f0dbd..d233afae5 100644 --- a/core/coreiface/path.go +++ b/core/coreiface/path.go @@ -17,7 +17,9 @@ type Path interface { // String returns the path as a string. String() string - // Namespace returns the first component of the path + // Namespace returns the first component of the path. + // + // For example path "/ipfs/QmHash", calling Namespace() will return "ipfs" Namespace() string // Mutable returns false if the data pointed to by this path in guaranteed @@ -29,13 +31,29 @@ type Path interface { // ResolvedPath is a resolved Path type ResolvedPath interface { - // Cid returns the CID referred to by path + // Cid returns the CID of the object referenced by the path. + // + // Example: + // If you have 3 linked objects: QmRoot -> A -> B, and resolve path + // "/ipfs/QmRoot/A/B", the Cid method will return the CID of object B Cid() *cid.Cid - // Root returns the CID of root path + // Root returns the CID of the root object of the path + // + // Example: + // If you have 3 linked objects: QmRoot -> A -> B, and resolve path + // "/ipfs/QmRoot/A/B", the Root method will return the CID of object QmRoot Root() *cid.Cid // Remainder returns unresolved part of the path + // + // Example: + // If you have 2 linked objects: QmRoot -> A, where A is a CBOR node + // containing the following data: + // + // {"foo": {"bar": 42}} + // + // When resolving "/ipld/QmRoot/A/foo/bar", Remainder will return "foo/bar" Remainder() string Path From 70be3f394ba397728f5f31d4a4f2caf4d6c53af9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 12 Jun 2018 02:57:57 +0200 Subject: [PATCH 0058/1212] coreapi: more docs for ResolvedPath MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@1806f0f94a444c88f0c842e03a454619e6d42e56 This commit was moved from ipfs/boxo@88c3a9e6cc05757813f6a3266244543529c58cf6 --- core/coreiface/path.go | 41 +++++++++++++++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/core/coreiface/path.go b/core/coreiface/path.go index d233afae5..acdcd85da 100644 --- a/core/coreiface/path.go +++ b/core/coreiface/path.go @@ -29,13 +29,38 @@ type Path interface { Mutable() bool } -// ResolvedPath is a resolved Path +// ResolvedPath is a path which was resolved to the last resolvable node type ResolvedPath interface { - // Cid returns the CID of the object referenced by the path. + // Cid returns the CID of the node referenced by the path. Remainder of the + // path is guaranteed to be within the node. // - // Example: - // If you have 3 linked objects: QmRoot -> A -> B, and resolve path - // "/ipfs/QmRoot/A/B", the Cid method will return the CID of object B + // Examples: + // If you have 3 linked objects: QmRoot -> A -> B: + // + // cidB := {"foo": {"bar": 42 }} + // cidA := {"B": {"/": cidB }} + // cidRoot := {"A": {"/": cidA }} + // + // And resolve paths: + // * "/ipfs/${cidRoot}" + // * Calling Cid() will return `cidRoot` + // * Calling Root() will return `cidRoot` + // * Calling Remainder() will return `` + // + // * "/ipfs/${cidRoot}/A" + // * Calling Cid() will return `cidA` + // * Calling Root() will return `cidRoot` + // * Calling Remainder() will return `` + // + // * "/ipfs/${cidRoot}/A/B/foo" + // * Calling Cid() will return `cidB` + // * Calling Root() will return `cidRoot` + // * Calling Remainder() will return `foo` + // + // * "/ipfs/${cidRoot}/A/B/foo/bar" + // * Calling Cid() will return `cidB` + // * Calling Root() will return `cidRoot` + // * Calling Remainder() will return `foo/bar` Cid() *cid.Cid // Root returns the CID of the root object of the path @@ -43,6 +68,8 @@ type ResolvedPath interface { // Example: // If you have 3 linked objects: QmRoot -> A -> B, and resolve path // "/ipfs/QmRoot/A/B", the Root method will return the CID of object QmRoot + // + // For more examples see the documentation of Cid() method Root() *cid.Cid // Remainder returns unresolved part of the path @@ -51,9 +78,11 @@ type ResolvedPath interface { // If you have 2 linked objects: QmRoot -> A, where A is a CBOR node // containing the following data: // - // {"foo": {"bar": 42}} + // {"foo": {"bar": 42 }} // // When resolving "/ipld/QmRoot/A/foo/bar", Remainder will return "foo/bar" + // + // For more examples see the documentation of Cid() method Remainder() string Path From b808f144b5b65e02307e0de0624deba9758d529e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 12 Jun 2018 03:52:26 +0200 Subject: [PATCH 0059/1212] coreapi: move path utils to interface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@0a0e69cc424e6136e8f0a1fecabda94e7854bc7f This commit was moved from ipfs/boxo@92ebd6eb7be417dec28e3c8fbc0f0bb4db65d268 --- core/coreiface/coreapi.go | 10 ----- core/coreiface/path.go | 87 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+), 10 deletions(-) diff --git a/core/coreiface/coreapi.go b/core/coreiface/coreapi.go index f5e81adce..82a2ebf4e 100644 --- a/core/coreiface/coreapi.go +++ b/core/coreiface/coreapi.go @@ -6,7 +6,6 @@ import ( "context" ipld "gx/ipfs/QmZtNq8dArGfnpCZfx2pUNY7UcjGhVp5qqwQ4hH6mpTMRQ/go-ipld-format" - cid "gx/ipfs/QmapdYm1b22Frv3k17fqrBYTFRxwiaVJkB299Mfn33edeB/go-cid" ) // CoreAPI defines an unified interface to IPFS for Go programs @@ -38,13 +37,4 @@ type CoreAPI interface { // ResolveNode resolves the path (if not resolved already) using Unixfs // resolver, gets and returns the resolved Node ResolveNode(context.Context, Path) (ipld.Node, error) - - // ParsePath parses string path to a Path - ParsePath(string) (Path, error) - - // IpfsPath creates new /ipfs path from the provided CID - IpfsPath(*cid.Cid) ResolvedPath - - // IpldPath creates new /ipld path from the provided CID - IpldPath(*cid.Cid) ResolvedPath } diff --git a/core/coreiface/path.go b/core/coreiface/path.go index acdcd85da..e097ea3b6 100644 --- a/core/coreiface/path.go +++ b/core/coreiface/path.go @@ -1,9 +1,13 @@ package iface import ( + ipfspath "github.com/ipfs/go-ipfs/path" + cid "gx/ipfs/QmYVNvtQkeZ6AKSwDrjQTs432QtL6umrrK41EBq3cu7iSP/go-cid" ) +//TODO: merge with ipfspath so we don't depend on it + // Path is a generic wrapper for paths used in the API. A path can be resolved // to a CID using one of Resolve functions in the API. // @@ -87,3 +91,86 @@ type ResolvedPath interface { Path } + +// path implements coreiface.Path +type path struct { + path ipfspath.Path +} + +// resolvedPath implements coreiface.resolvedPath +type resolvedPath struct { + path + cid *cid.Cid + root *cid.Cid + remainder string +} + +// IpfsPath creates new /ipfs path from the provided CID +func IpfsPath(c *cid.Cid) ResolvedPath { + return &resolvedPath{ + path: path{ipfspath.Path("/ipfs/" + c.String())}, + cid: c, + root: c, + remainder: "", + } +} + +// IpldPath creates new /ipld path from the provided CID +func IpldPath(c *cid.Cid) ResolvedPath { + return &resolvedPath{ + path: path{ipfspath.Path("/ipld/" + c.String())}, + cid: c, + root: c, + remainder: "", + } +} + +// ParsePath parses string path to a Path +func ParsePath(p string) (Path, error) { + pp, err := ipfspath.ParsePath(p) + if err != nil { + return nil, err + } + + return &path{path: pp}, nil +} + +// NewResolvedPath creates new ResolvedPath. This function performs no checks +// and is intended to be used by resolver implementations. Incorrect inputs may +// cause panics. Handle with care. +func NewResolvedPath(ipath ipfspath.Path, c *cid.Cid, root *cid.Cid, remainder string) ResolvedPath { + return &resolvedPath{ + path: path{ipath}, + cid: c, + root: root, + remainder: remainder, + } +} + +func (p *path) String() string { + return p.path.String() +} + +func (p *path) Namespace() string { + if len(p.path.Segments()) < 1 { + panic("path without namespace") //this shouldn't happen under any scenario + } + return p.path.Segments()[0] +} + +func (p *path) Mutable() bool { + //TODO: MFS: check for /local + return p.Namespace() == "ipns" +} + +func (p *resolvedPath) Cid() *cid.Cid { + return p.cid +} + +func (p *resolvedPath) Root() *cid.Cid { + return p.root +} + +func (p *resolvedPath) Remainder() string { + return p.remainder +} From 68fee2eb3884f58e17551333f47e79cfd64a65c5 Mon Sep 17 00:00:00 2001 From: Jeromy Date: Sat, 28 Jul 2018 23:57:42 -0700 Subject: [PATCH 0060/1212] Extract path and resolver License: MIT Signed-off-by: Jeromy This commit was moved from ipfs/interface-go-ipfs-core@ebc2b3570f9c962cc9b9a8440fe1a88fea42628f This commit was moved from ipfs/boxo@069cd0e0d729e11cf7d9a4374b004e528fca18de --- core/coreiface/path.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/coreiface/path.go b/core/coreiface/path.go index e097ea3b6..49b8cc5ea 100644 --- a/core/coreiface/path.go +++ b/core/coreiface/path.go @@ -1,7 +1,7 @@ package iface import ( - ipfspath "github.com/ipfs/go-ipfs/path" + ipfspath "gx/ipfs/QmYKNMEUK7nCVAefgXF1LVtZEZg3uRmBqiae4FJRXDNAyJ/go-path" cid "gx/ipfs/QmYVNvtQkeZ6AKSwDrjQTs432QtL6umrrK41EBq3cu7iSP/go-cid" ) From 1841565f9c1c4cb6520540543bddf4a2cef384b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 2 Feb 2018 16:28:02 +0100 Subject: [PATCH 0061/1212] coreapi: Pin option for Object.Put MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@ca13e9b2ef673c3eb63baecc0cf840036405e214 This commit was moved from ipfs/boxo@8fa8a1e440ea9d280b5c2b717f1de35602f83f08 --- core/coreiface/options/object.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/core/coreiface/options/object.go b/core/coreiface/options/object.go index aca02d672..9257ea607 100644 --- a/core/coreiface/options/object.go +++ b/core/coreiface/options/object.go @@ -7,6 +7,7 @@ type ObjectNewSettings struct { type ObjectPutSettings struct { InputEnc string DataType string + Pin bool } type ObjectAddLinkSettings struct { @@ -35,6 +36,7 @@ func ObjectPutOptions(opts ...ObjectPutOption) (*ObjectPutSettings, error) { options := &ObjectPutSettings{ InputEnc: "json", DataType: "text", + Pin: false, } for _, opt := range opts { @@ -103,6 +105,15 @@ func (objectOpts) DataType(t string) ObjectPutOption { } } +// WithPin is an option for Object.Put which specifies whether to pin the added +// objects, default is false +func (objectOpts) WithPin(pin bool) ObjectPutOption { + return func(settings *ObjectPutSettings) error { + settings.Pin = pin + return nil + } +} + // Create is an option for Object.AddLink which specifies whether create required // directories for the child func (objectOpts) Create(create bool) ObjectAddLinkOption { From 5dbe176f5331c80be35bce0feeba622113c5545a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 2 Feb 2018 21:50:22 +0100 Subject: [PATCH 0062/1212] coreapi: implement Object.Diff MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@00f6430f32022c0038bb4407cca5d9f136b0ee24 This commit was moved from ipfs/boxo@83c279f0be6bbc7a498345e8b82b7331b8fb356c --- core/coreiface/object.go | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/core/coreiface/object.go b/core/coreiface/object.go index ea9aa5948..0a716dc97 100644 --- a/core/coreiface/object.go +++ b/core/coreiface/object.go @@ -31,6 +31,39 @@ type ObjectStat struct { CumulativeSize int } + +const ( + // DiffAdd is a Type of ObjectChange where a link was added to the graph + DiffAdd = iota + + // DiffRemove is a Type of ObjectChange where a link was removed from the graph + DiffRemove + + // DiffMod is a Type of ObjectChange where a link was changed in the graph + DiffMod +) + +// ObjectChange represents a change ia a graph +// TODO: do we want this to be an interface? +type ObjectChange struct { + // Type of the change, either: + // * DiffAdd - Added a link + // * DiffRemove - Removed a link + // * DiffMod - Modified a link + Type int + + // Path to the changed link + Path string + + // Before holds the link path before the change. Note that when a link is + // added, this will be nil. + Before Path + + // After holds the link path after the change. Note that when a link is + // removed, this will be nil. + After Path +} + // ObjectAPI specifies the interface to MerkleDAG and contains useful utilities // for manipulating MerkleDAG data structures. type ObjectAPI interface { @@ -65,4 +98,8 @@ type ObjectAPI interface { // SetData sets the data contained in the node SetData(context.Context, Path, io.Reader) (ResolvedPath, error) + + // Diff returns a set of changes needed to transform the first object into the + // second. + Diff(context.Context, Path, Path) ([]ObjectChange, error) } From cb79396b3531b910737e28a6e4bd4bc35a4ffdeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 2 Feb 2018 22:36:01 +0100 Subject: [PATCH 0063/1212] commands: switch object commands to CoreAPI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@9fe2a845730cb243ba72ceb3a1be7871467b416b This commit was moved from ipfs/boxo@157bb70fa94828c5c37466e6cc75e2058454ed2c --- core/coreiface/object.go | 5 ++--- core/coreiface/options/object.go | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/core/coreiface/object.go b/core/coreiface/object.go index 0a716dc97..1c7caeb77 100644 --- a/core/coreiface/object.go +++ b/core/coreiface/object.go @@ -31,7 +31,6 @@ type ObjectStat struct { CumulativeSize int } - const ( // DiffAdd is a Type of ObjectChange where a link was added to the graph DiffAdd = iota @@ -57,11 +56,11 @@ type ObjectChange struct { // Before holds the link path before the change. Note that when a link is // added, this will be nil. - Before Path + Before ResolvedPath // After holds the link path after the change. Note that when a link is // removed, this will be nil. - After Path + After ResolvedPath } // ObjectAPI specifies the interface to MerkleDAG and contains useful utilities diff --git a/core/coreiface/options/object.go b/core/coreiface/options/object.go index 9257ea607..e484a9f36 100644 --- a/core/coreiface/options/object.go +++ b/core/coreiface/options/object.go @@ -105,9 +105,9 @@ func (objectOpts) DataType(t string) ObjectPutOption { } } -// WithPin is an option for Object.Put which specifies whether to pin the added +// Pin is an option for Object.Put which specifies whether to pin the added // objects, default is false -func (objectOpts) WithPin(pin bool) ObjectPutOption { +func (objectOpts) Pin(pin bool) ObjectPutOption { return func(settings *ObjectPutSettings) error { settings.Pin = pin return nil From 5b28066131841060f97c7291189df9271d7d680b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 25 Jul 2018 22:49:17 +0200 Subject: [PATCH 0064/1212] object coreapi: Address review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@af43bf0a5b8a8eb409dc5e3731cf86afd5b67304 This commit was moved from ipfs/boxo@c1cdbfdc59df5b72610ae52ff80a44cb81f679c9 --- core/coreiface/object.go | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/core/coreiface/object.go b/core/coreiface/object.go index 1c7caeb77..3eb0ea9ef 100644 --- a/core/coreiface/object.go +++ b/core/coreiface/object.go @@ -31,25 +31,27 @@ type ObjectStat struct { CumulativeSize int } -const ( - // DiffAdd is a Type of ObjectChange where a link was added to the graph - DiffAdd = iota +// ChangeType denotes type of change in ObjectChange +type ChangeType int - // DiffRemove is a Type of ObjectChange where a link was removed from the graph +const ( + // DiffAdd is set when a link was added to the graph + DiffAdd ChangeType = iota + + // DiffRemove is set when a link was removed from the graph DiffRemove - // DiffMod is a Type of ObjectChange where a link was changed in the graph + // DiffMod is set when a link was changed in the graph DiffMod ) // ObjectChange represents a change ia a graph -// TODO: do we want this to be an interface? type ObjectChange struct { // Type of the change, either: // * DiffAdd - Added a link // * DiffRemove - Removed a link // * DiffMod - Modified a link - Type int + Type ChangeType // Path to the changed link Path string From 04c548b1d2e75aa0f31755a90b1d059ff9210dc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 3 Aug 2018 18:06:57 +0200 Subject: [PATCH 0065/1212] coreapi: dag: Batching interface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@f4b74679d1eb5597e430a52f4cca826d511898c3 This commit was moved from ipfs/boxo@83081a0c1b91bb9554d56ea074ef28ca02b38ed9 --- core/coreiface/dag.go | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/core/coreiface/dag.go b/core/coreiface/dag.go index 3f92ebab3..a128e97c5 100644 --- a/core/coreiface/dag.go +++ b/core/coreiface/dag.go @@ -4,21 +4,36 @@ import ( "context" "io" - options "github.com/ipfs/go-ipfs/core/coreapi/interface/options" + "github.com/ipfs/go-ipfs/core/coreapi/interface/options" ipld "gx/ipfs/QmZtNq8dArGfnpCZfx2pUNY7UcjGhVp5qqwQ4hH6mpTMRQ/go-ipld-format" ) -// DagAPI specifies the interface to IPLD -type DagAPI interface { +// DagOps groups operations that can be batched together +type DagOps interface { // Put inserts data using specified format and input encoding. // Unless used with WithCodec or WithHash, the defaults "dag-cbor" and // "sha256" are used. Put(ctx context.Context, src io.Reader, opts ...options.DagPutOption) (ResolvedPath, error) +} + +// DagBatch is the batching version of DagAPI. All implementations of DagBatch +// should be threadsafe +type DagBatch interface { + DagOps + + Commit(ctx context.Context) error +} + +// DagAPI specifies the interface to IPLD +type DagAPI interface { + DagOps // Get attempts to resolve and get the node specified by the path Get(ctx context.Context, path Path) (ipld.Node, error) // Tree returns list of paths within a node specified by the path. Tree(ctx context.Context, path Path, opts ...options.DagTreeOption) ([]Path, error) + + Batch(ctx context.Context) DagBatch } From a9097b5738eaf33a7ae2a723ccacdfd225863833 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 3 Aug 2018 18:19:45 +0200 Subject: [PATCH 0066/1212] coreapi: dag: Missing batch docs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@77b458e7426ae384692ed7c70a3a6179f4adc1b3 This commit was moved from ipfs/boxo@de98b9bd4549e5e475d3d096c519ae685ac008cc --- core/coreiface/dag.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/coreiface/dag.go b/core/coreiface/dag.go index a128e97c5..01d6112e7 100644 --- a/core/coreiface/dag.go +++ b/core/coreiface/dag.go @@ -22,6 +22,7 @@ type DagOps interface { type DagBatch interface { DagOps + // Commit commits nodes to the datastore and announces them to the network Commit(ctx context.Context) error } @@ -35,5 +36,6 @@ type DagAPI interface { // Tree returns list of paths within a node specified by the path. Tree(ctx context.Context, path Path, opts ...options.DagTreeOption) ([]Path, error) + // Batch creates new DagBatch Batch(ctx context.Context) DagBatch } From eea330740907c05834d39687ddc1596387f5743f Mon Sep 17 00:00:00 2001 From: Jeromy Date: Sun, 5 Aug 2018 13:22:51 -0700 Subject: [PATCH 0067/1212] Update bitswap deps License: MIT Signed-off-by: Jeromy This commit was moved from ipfs/interface-go-ipfs-core@24dde48825577a7f5e052be01025f22a413cc57b This commit was moved from ipfs/boxo@3bb8c057c6fe89c2bcc4824581cb3e444f0459c8 --- core/coreiface/path.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/coreiface/path.go b/core/coreiface/path.go index 49b8cc5ea..069474c23 100644 --- a/core/coreiface/path.go +++ b/core/coreiface/path.go @@ -1,7 +1,7 @@ package iface import ( - ipfspath "gx/ipfs/QmYKNMEUK7nCVAefgXF1LVtZEZg3uRmBqiae4FJRXDNAyJ/go-path" + ipfspath "gx/ipfs/Qme34dT9spiPgunbueNtziRX4SvfLHDFZQvmTBVK8p4qNT/go-path" cid "gx/ipfs/QmYVNvtQkeZ6AKSwDrjQTs432QtL6umrrK41EBq3cu7iSP/go-cid" ) From e4f5db5aa62f7982c2361a80b111d636de4640a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 3 Aug 2018 16:46:25 +0200 Subject: [PATCH 0068/1212] coreapi: key: some changes to match command functionality MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@12537a60f5318fec2fdf2c02a3afd3786b673f07 This commit was moved from ipfs/boxo@f9afe981175685c29705b480a2a68688d14c3a3b --- core/coreiface/key.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/core/coreiface/key.go b/core/coreiface/key.go index 928aa265f..9e9c7e400 100644 --- a/core/coreiface/key.go +++ b/core/coreiface/key.go @@ -4,14 +4,20 @@ import ( "context" options "github.com/ipfs/go-ipfs/core/coreapi/interface/options" + + "gx/ipfs/QmdVrMn1LhB4ybb8hMVaMLXnA8XRSewMnK6YqXKXoTcRvN/go-libp2p-peer" ) // Key specifies the interface to Keys in KeyAPI Keystore type Key interface { // Key returns key name Name() string + // Path returns key path Path() Path + + // Id returns key PeerID + Id() peer.ID } // KeyAPI specifies the interface to Keystore @@ -28,5 +34,5 @@ type KeyAPI interface { List(ctx context.Context) ([]Key, error) // Remove removes keys from keystore. Returns ipns path of the removed key - Remove(ctx context.Context, name string) (Path, error) + Remove(ctx context.Context, name string) (Key, error) } From 16c6be00861e9c59cb66bad9a412a94d61db64a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 7 Aug 2018 15:10:34 +0200 Subject: [PATCH 0069/1212] key cmd: fix codeclimate warnings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@814f82cf806d4fefc9f5158e85807b4c96751637 This commit was moved from ipfs/boxo@55223e9427daacfa41800357a551aad8bce06ea1 --- core/coreiface/key.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/coreiface/key.go b/core/coreiface/key.go index 9e9c7e400..2abf3559b 100644 --- a/core/coreiface/key.go +++ b/core/coreiface/key.go @@ -16,8 +16,8 @@ type Key interface { // Path returns key path Path() Path - // Id returns key PeerID - Id() peer.ID + // ID returns key PeerID + ID() peer.ID } // KeyAPI specifies the interface to Keystore From 390006651bde2fab907f89e3d946b83c5021f677 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Mon, 6 Aug 2018 22:10:53 -0700 Subject: [PATCH 0070/1212] gx: update deps License: MIT Signed-off-by: Steven Allen This commit was moved from ipfs/interface-go-ipfs-core@365f5eb472016cac6e893ccd44a114eb9b8cfcd5 This commit was moved from ipfs/boxo@aa067a121b31b26ae87a5a2494f574c55e2e7edc --- core/coreiface/path.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/coreiface/path.go b/core/coreiface/path.go index 069474c23..4c4c51532 100644 --- a/core/coreiface/path.go +++ b/core/coreiface/path.go @@ -1,7 +1,7 @@ package iface import ( - ipfspath "gx/ipfs/Qme34dT9spiPgunbueNtziRX4SvfLHDFZQvmTBVK8p4qNT/go-path" + ipfspath "gx/ipfs/QmY2QaawxgJw2rn7WsFNkWEYph3z2azpyYdrhAc1JctDmE/go-path" cid "gx/ipfs/QmYVNvtQkeZ6AKSwDrjQTs432QtL6umrrK41EBq3cu7iSP/go-cid" ) From e24a33d4cbf6ac3c67eac3320f42c5ecd7795b67 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Wed, 8 Aug 2018 18:51:17 -0700 Subject: [PATCH 0071/1212] update gogo-protobuf fixes #3214 License: MIT Signed-off-by: Steven Allen This commit was moved from ipfs/interface-go-ipfs-core@1ef16343d8d91bd685c8b4dc6554fda5e4531b36 This commit was moved from ipfs/boxo@e415aa12146cdbaffdc1619687c307cd9de09842 --- core/coreiface/key.go | 2 +- core/coreiface/path.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/coreiface/key.go b/core/coreiface/key.go index 2abf3559b..3730f3592 100644 --- a/core/coreiface/key.go +++ b/core/coreiface/key.go @@ -5,7 +5,7 @@ import ( options "github.com/ipfs/go-ipfs/core/coreapi/interface/options" - "gx/ipfs/QmdVrMn1LhB4ybb8hMVaMLXnA8XRSewMnK6YqXKXoTcRvN/go-libp2p-peer" + "gx/ipfs/QmcZSzKEM5yDfpZbeEEZaVmaZ1zXm6JWTbrQZSB8hCVPzk/go-libp2p-peer" ) // Key specifies the interface to Keys in KeyAPI Keystore diff --git a/core/coreiface/path.go b/core/coreiface/path.go index 4c4c51532..c51d31645 100644 --- a/core/coreiface/path.go +++ b/core/coreiface/path.go @@ -1,7 +1,7 @@ package iface import ( - ipfspath "gx/ipfs/QmY2QaawxgJw2rn7WsFNkWEYph3z2azpyYdrhAc1JctDmE/go-path" + ipfspath "gx/ipfs/QmPqCBrmkm7jNfYi7xFS7mUZsrN6DEumBMrxLnL7axNJx1/go-path" cid "gx/ipfs/QmYVNvtQkeZ6AKSwDrjQTs432QtL6umrrK41EBq3cu7iSP/go-cid" ) From 0d7b9a837e694a50d8cd1f9e179b2c569c4a11df Mon Sep 17 00:00:00 2001 From: Kevin Atkinson Date: Sun, 12 Aug 2018 19:15:07 -0400 Subject: [PATCH 0072/1212] Gx updates and fixes to use new cid.Builder interface. License: MIT Signed-off-by: Kevin Atkinson This commit was moved from ipfs/interface-go-ipfs-core@05f527a4ab81c36f8965de35bdb8352a92a61718 This commit was moved from ipfs/boxo@d91c0d7ac499f29b5b49219df4c1fdbf2e222bcd --- core/coreiface/coreapi.go | 2 +- core/coreiface/dag.go | 2 +- core/coreiface/object.go | 4 ++-- core/coreiface/options/dag.go | 2 +- core/coreiface/path.go | 4 ++-- core/coreiface/unixfs.go | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/core/coreiface/coreapi.go b/core/coreiface/coreapi.go index 82a2ebf4e..d7614f01d 100644 --- a/core/coreiface/coreapi.go +++ b/core/coreiface/coreapi.go @@ -5,7 +5,7 @@ package iface import ( "context" - ipld "gx/ipfs/QmZtNq8dArGfnpCZfx2pUNY7UcjGhVp5qqwQ4hH6mpTMRQ/go-ipld-format" + ipld "gx/ipfs/QmUSyMZ8Vt4vTZr5HdDEgEfpwAXfQRuDdfCFTt7XBzhxpQ/go-ipld-format" ) // CoreAPI defines an unified interface to IPFS for Go programs diff --git a/core/coreiface/dag.go b/core/coreiface/dag.go index 01d6112e7..77577d0fc 100644 --- a/core/coreiface/dag.go +++ b/core/coreiface/dag.go @@ -6,7 +6,7 @@ import ( "github.com/ipfs/go-ipfs/core/coreapi/interface/options" - ipld "gx/ipfs/QmZtNq8dArGfnpCZfx2pUNY7UcjGhVp5qqwQ4hH6mpTMRQ/go-ipld-format" + ipld "gx/ipfs/QmUSyMZ8Vt4vTZr5HdDEgEfpwAXfQRuDdfCFTt7XBzhxpQ/go-ipld-format" ) // DagOps groups operations that can be batched together diff --git a/core/coreiface/object.go b/core/coreiface/object.go index 3eb0ea9ef..dc86f46c1 100644 --- a/core/coreiface/object.go +++ b/core/coreiface/object.go @@ -6,8 +6,8 @@ import ( options "github.com/ipfs/go-ipfs/core/coreapi/interface/options" - cid "gx/ipfs/QmYVNvtQkeZ6AKSwDrjQTs432QtL6umrrK41EBq3cu7iSP/go-cid" - ipld "gx/ipfs/QmZtNq8dArGfnpCZfx2pUNY7UcjGhVp5qqwQ4hH6mpTMRQ/go-ipld-format" + ipld "gx/ipfs/QmUSyMZ8Vt4vTZr5HdDEgEfpwAXfQRuDdfCFTt7XBzhxpQ/go-ipld-format" + cid "gx/ipfs/Qmdu2AYUV7yMoVBQPxXNfe7FJcdx16kYtsx6jAPKWQYF1y/go-cid" ) // ObjectStat provides information about dag nodes diff --git a/core/coreiface/options/dag.go b/core/coreiface/options/dag.go index 57465deee..a43a144fc 100644 --- a/core/coreiface/options/dag.go +++ b/core/coreiface/options/dag.go @@ -3,7 +3,7 @@ package options import ( "math" - cid "gx/ipfs/QmYVNvtQkeZ6AKSwDrjQTs432QtL6umrrK41EBq3cu7iSP/go-cid" + cid "gx/ipfs/Qmdu2AYUV7yMoVBQPxXNfe7FJcdx16kYtsx6jAPKWQYF1y/go-cid" ) type DagPutSettings struct { diff --git a/core/coreiface/path.go b/core/coreiface/path.go index c51d31645..28e0f431c 100644 --- a/core/coreiface/path.go +++ b/core/coreiface/path.go @@ -1,9 +1,9 @@ package iface import ( - ipfspath "gx/ipfs/QmPqCBrmkm7jNfYi7xFS7mUZsrN6DEumBMrxLnL7axNJx1/go-path" + ipfspath "gx/ipfs/QmTG5WFmAM4uAnqGskeAPijdpTmmNDLJNCQ71NqfdvC6hV/go-path" - cid "gx/ipfs/QmYVNvtQkeZ6AKSwDrjQTs432QtL6umrrK41EBq3cu7iSP/go-cid" + cid "gx/ipfs/Qmdu2AYUV7yMoVBQPxXNfe7FJcdx16kYtsx6jAPKWQYF1y/go-cid" ) //TODO: merge with ipfspath so we don't depend on it diff --git a/core/coreiface/unixfs.go b/core/coreiface/unixfs.go index 1ddc20674..0ec63d516 100644 --- a/core/coreiface/unixfs.go +++ b/core/coreiface/unixfs.go @@ -4,7 +4,7 @@ import ( "context" "io" - ipld "gx/ipfs/QmZtNq8dArGfnpCZfx2pUNY7UcjGhVp5qqwQ4hH6mpTMRQ/go-ipld-format" + ipld "gx/ipfs/QmUSyMZ8Vt4vTZr5HdDEgEfpwAXfQRuDdfCFTt7XBzhxpQ/go-ipld-format" ) // UnixfsAPI is the basic interface to immutable files in IPFS From e1f39ec60e3ada6404a5d5681b872c0b483e7c1b Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Mon, 13 Aug 2018 14:29:22 -0700 Subject: [PATCH 0073/1212] update go-datastore to use []byte values instead of {}interface values * Most of our datastores barf on non []byte values. * We have to have a bunch of "is this a []byte" checks. * Saves some allocations. License: MIT Signed-off-by: Steven Allen This commit was moved from ipfs/interface-go-ipfs-core@bb2d55c26ae125a50a6250df13479d70a84e4073 This commit was moved from ipfs/boxo@454f0f425c406d96427b7e0a262a33081c308dbf --- core/coreiface/path.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/coreiface/path.go b/core/coreiface/path.go index 28e0f431c..d2933ece5 100644 --- a/core/coreiface/path.go +++ b/core/coreiface/path.go @@ -1,7 +1,7 @@ package iface import ( - ipfspath "gx/ipfs/QmTG5WFmAM4uAnqGskeAPijdpTmmNDLJNCQ71NqfdvC6hV/go-path" + ipfspath "gx/ipfs/QmV1W98rBAovVJGkeYHfqJ19JdT9dQbbWsCq9zPaMyrxYx/go-path" cid "gx/ipfs/Qmdu2AYUV7yMoVBQPxXNfe7FJcdx16kYtsx6jAPKWQYF1y/go-cid" ) From 9bef462a53b0edbc64bc2ad2c6c3e122895a17cf Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Wed, 15 Aug 2018 08:30:22 -0700 Subject: [PATCH 0074/1212] gx: update go-cid License: MIT Signed-off-by: Steven Allen This commit was moved from ipfs/interface-go-ipfs-core@9d5772a1cf4ffcf6d9c7717e074d30540d36f263 This commit was moved from ipfs/boxo@aac8a89a8ac8584416db46bc1968cd3e185241db --- core/coreiface/coreapi.go | 2 +- core/coreiface/dag.go | 2 +- core/coreiface/object.go | 4 ++-- core/coreiface/options/dag.go | 2 +- core/coreiface/path.go | 4 ++-- core/coreiface/unixfs.go | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/core/coreiface/coreapi.go b/core/coreiface/coreapi.go index d7614f01d..ab5374069 100644 --- a/core/coreiface/coreapi.go +++ b/core/coreiface/coreapi.go @@ -5,7 +5,7 @@ package iface import ( "context" - ipld "gx/ipfs/QmUSyMZ8Vt4vTZr5HdDEgEfpwAXfQRuDdfCFTt7XBzhxpQ/go-ipld-format" + ipld "gx/ipfs/QmaA8GkXUYinkkndvg7T6Tx7gYXemhxjaxLisEPes7Rf1P/go-ipld-format" ) // CoreAPI defines an unified interface to IPFS for Go programs diff --git a/core/coreiface/dag.go b/core/coreiface/dag.go index 77577d0fc..d547e8531 100644 --- a/core/coreiface/dag.go +++ b/core/coreiface/dag.go @@ -6,7 +6,7 @@ import ( "github.com/ipfs/go-ipfs/core/coreapi/interface/options" - ipld "gx/ipfs/QmUSyMZ8Vt4vTZr5HdDEgEfpwAXfQRuDdfCFTt7XBzhxpQ/go-ipld-format" + ipld "gx/ipfs/QmaA8GkXUYinkkndvg7T6Tx7gYXemhxjaxLisEPes7Rf1P/go-ipld-format" ) // DagOps groups operations that can be batched together diff --git a/core/coreiface/object.go b/core/coreiface/object.go index dc86f46c1..812b69a64 100644 --- a/core/coreiface/object.go +++ b/core/coreiface/object.go @@ -6,8 +6,8 @@ import ( options "github.com/ipfs/go-ipfs/core/coreapi/interface/options" - ipld "gx/ipfs/QmUSyMZ8Vt4vTZr5HdDEgEfpwAXfQRuDdfCFTt7XBzhxpQ/go-ipld-format" - cid "gx/ipfs/Qmdu2AYUV7yMoVBQPxXNfe7FJcdx16kYtsx6jAPKWQYF1y/go-cid" + cid "gx/ipfs/QmYjnkEL7i731PirfVH1sis89evN7jt4otSHw5D2xXXwUV/go-cid" + ipld "gx/ipfs/QmaA8GkXUYinkkndvg7T6Tx7gYXemhxjaxLisEPes7Rf1P/go-ipld-format" ) // ObjectStat provides information about dag nodes diff --git a/core/coreiface/options/dag.go b/core/coreiface/options/dag.go index a43a144fc..e89e4d707 100644 --- a/core/coreiface/options/dag.go +++ b/core/coreiface/options/dag.go @@ -3,7 +3,7 @@ package options import ( "math" - cid "gx/ipfs/Qmdu2AYUV7yMoVBQPxXNfe7FJcdx16kYtsx6jAPKWQYF1y/go-cid" + cid "gx/ipfs/QmYjnkEL7i731PirfVH1sis89evN7jt4otSHw5D2xXXwUV/go-cid" ) type DagPutSettings struct { diff --git a/core/coreiface/path.go b/core/coreiface/path.go index d2933ece5..49cea48cc 100644 --- a/core/coreiface/path.go +++ b/core/coreiface/path.go @@ -1,9 +1,9 @@ package iface import ( - ipfspath "gx/ipfs/QmV1W98rBAovVJGkeYHfqJ19JdT9dQbbWsCq9zPaMyrxYx/go-path" + ipfspath "gx/ipfs/QmWMcvZbNvk5codeqbm7L89C9kqSwka4KaHnDb8HRnxsSL/go-path" - cid "gx/ipfs/Qmdu2AYUV7yMoVBQPxXNfe7FJcdx16kYtsx6jAPKWQYF1y/go-cid" + cid "gx/ipfs/QmYjnkEL7i731PirfVH1sis89evN7jt4otSHw5D2xXXwUV/go-cid" ) //TODO: merge with ipfspath so we don't depend on it diff --git a/core/coreiface/unixfs.go b/core/coreiface/unixfs.go index 0ec63d516..b42f56ba8 100644 --- a/core/coreiface/unixfs.go +++ b/core/coreiface/unixfs.go @@ -4,7 +4,7 @@ import ( "context" "io" - ipld "gx/ipfs/QmUSyMZ8Vt4vTZr5HdDEgEfpwAXfQRuDdfCFTt7XBzhxpQ/go-ipld-format" + ipld "gx/ipfs/QmaA8GkXUYinkkndvg7T6Tx7gYXemhxjaxLisEPes7Rf1P/go-ipld-format" ) // UnixfsAPI is the basic interface to immutable files in IPFS From daa7186346d3f4263b3ebd2665695d933dccf2b5 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Tue, 21 Aug 2018 17:10:11 -0700 Subject: [PATCH 0075/1212] gx: update go-cid, go-libp2p-peer, go-ipfs-cmds, go-ipfs-cmdkit License: MIT Signed-off-by: Steven Allen This commit was moved from ipfs/interface-go-ipfs-core@14b366d332ad7524863889d6eddc696b550c57dd This commit was moved from ipfs/boxo@66c959b336ec55e8b2f9fbb8bd17f0922fdc0473 --- core/coreiface/coreapi.go | 2 +- core/coreiface/dag.go | 2 +- core/coreiface/key.go | 2 +- core/coreiface/object.go | 4 ++-- core/coreiface/options/dag.go | 2 +- core/coreiface/path.go | 4 ++-- core/coreiface/unixfs.go | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/core/coreiface/coreapi.go b/core/coreiface/coreapi.go index ab5374069..696eefbaf 100644 --- a/core/coreiface/coreapi.go +++ b/core/coreiface/coreapi.go @@ -5,7 +5,7 @@ package iface import ( "context" - ipld "gx/ipfs/QmaA8GkXUYinkkndvg7T6Tx7gYXemhxjaxLisEPes7Rf1P/go-ipld-format" + ipld "gx/ipfs/QmX5CsuHyVZeTLxgRSYkgLSDQKb9UjE8xnhQzCEJWWWFsC/go-ipld-format" ) // CoreAPI defines an unified interface to IPFS for Go programs diff --git a/core/coreiface/dag.go b/core/coreiface/dag.go index d547e8531..d3270928c 100644 --- a/core/coreiface/dag.go +++ b/core/coreiface/dag.go @@ -6,7 +6,7 @@ import ( "github.com/ipfs/go-ipfs/core/coreapi/interface/options" - ipld "gx/ipfs/QmaA8GkXUYinkkndvg7T6Tx7gYXemhxjaxLisEPes7Rf1P/go-ipld-format" + ipld "gx/ipfs/QmX5CsuHyVZeTLxgRSYkgLSDQKb9UjE8xnhQzCEJWWWFsC/go-ipld-format" ) // DagOps groups operations that can be batched together diff --git a/core/coreiface/key.go b/core/coreiface/key.go index 3730f3592..cc7c409fd 100644 --- a/core/coreiface/key.go +++ b/core/coreiface/key.go @@ -5,7 +5,7 @@ import ( options "github.com/ipfs/go-ipfs/core/coreapi/interface/options" - "gx/ipfs/QmcZSzKEM5yDfpZbeEEZaVmaZ1zXm6JWTbrQZSB8hCVPzk/go-libp2p-peer" + "gx/ipfs/QmQsErDt8Qgw1XrsXf2BpEzDgGWtB1YLsTAARBup5b6B9W/go-libp2p-peer" ) // Key specifies the interface to Keys in KeyAPI Keystore diff --git a/core/coreiface/object.go b/core/coreiface/object.go index 812b69a64..750638a33 100644 --- a/core/coreiface/object.go +++ b/core/coreiface/object.go @@ -6,8 +6,8 @@ import ( options "github.com/ipfs/go-ipfs/core/coreapi/interface/options" - cid "gx/ipfs/QmYjnkEL7i731PirfVH1sis89evN7jt4otSHw5D2xXXwUV/go-cid" - ipld "gx/ipfs/QmaA8GkXUYinkkndvg7T6Tx7gYXemhxjaxLisEPes7Rf1P/go-ipld-format" + ipld "gx/ipfs/QmX5CsuHyVZeTLxgRSYkgLSDQKb9UjE8xnhQzCEJWWWFsC/go-ipld-format" + cid "gx/ipfs/QmZFbDTY9jfSBms2MchvYM9oYRbAF19K7Pby47yDBfpPrb/go-cid" ) // ObjectStat provides information about dag nodes diff --git a/core/coreiface/options/dag.go b/core/coreiface/options/dag.go index e89e4d707..689bb5c53 100644 --- a/core/coreiface/options/dag.go +++ b/core/coreiface/options/dag.go @@ -3,7 +3,7 @@ package options import ( "math" - cid "gx/ipfs/QmYjnkEL7i731PirfVH1sis89evN7jt4otSHw5D2xXXwUV/go-cid" + cid "gx/ipfs/QmZFbDTY9jfSBms2MchvYM9oYRbAF19K7Pby47yDBfpPrb/go-cid" ) type DagPutSettings struct { diff --git a/core/coreiface/path.go b/core/coreiface/path.go index 49cea48cc..25b09f486 100644 --- a/core/coreiface/path.go +++ b/core/coreiface/path.go @@ -1,9 +1,9 @@ package iface import ( - ipfspath "gx/ipfs/QmWMcvZbNvk5codeqbm7L89C9kqSwka4KaHnDb8HRnxsSL/go-path" + ipfspath "gx/ipfs/QmdMPBephdLYNESkruDX2hcDTgFYhoCt4LimWhgnomSdV2/go-path" - cid "gx/ipfs/QmYjnkEL7i731PirfVH1sis89evN7jt4otSHw5D2xXXwUV/go-cid" + cid "gx/ipfs/QmZFbDTY9jfSBms2MchvYM9oYRbAF19K7Pby47yDBfpPrb/go-cid" ) //TODO: merge with ipfspath so we don't depend on it diff --git a/core/coreiface/unixfs.go b/core/coreiface/unixfs.go index b42f56ba8..80f7ba396 100644 --- a/core/coreiface/unixfs.go +++ b/core/coreiface/unixfs.go @@ -4,7 +4,7 @@ import ( "context" "io" - ipld "gx/ipfs/QmaA8GkXUYinkkndvg7T6Tx7gYXemhxjaxLisEPes7Rf1P/go-ipld-format" + ipld "gx/ipfs/QmX5CsuHyVZeTLxgRSYkgLSDQKb9UjE8xnhQzCEJWWWFsC/go-ipld-format" ) // UnixfsAPI is the basic interface to immutable files in IPFS From 7475c9a2465004489a6f1382a087127b5576c9b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 2 Aug 2018 09:48:52 +0200 Subject: [PATCH 0076/1212] block cmd: use coreapi MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@f4e38c0970c260e17d89348001eb15769e4650d8 This commit was moved from ipfs/boxo@e0f2bd3ae8cc797a0cdb789d8d7166b21d0264e9 --- core/coreiface/block.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/coreiface/block.go b/core/coreiface/block.go index 468c00947..b99b05fdb 100644 --- a/core/coreiface/block.go +++ b/core/coreiface/block.go @@ -19,7 +19,7 @@ type BlockStat interface { // BlockAPI specifies the interface to the block layer type BlockAPI interface { // Put imports raw block data, hashing it using specified settings. - Put(context.Context, io.Reader, ...options.BlockPutOption) (ResolvedPath, error) + Put(context.Context, io.Reader, ...options.BlockPutOption) (BlockStat, error) // Get attempts to resolve the path and return a reader for data in the block Get(context.Context, Path) (io.Reader, error) From 9716a02efe48ba601eac8a07426d8f9f3a495c3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 13 Aug 2018 21:39:41 +0200 Subject: [PATCH 0077/1212] coreapi: block: don't allow creation of invalid cidv0s MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@f9d6dcc420879110f6d332e3de5a2048c07497e9 This commit was moved from ipfs/boxo@1c96fc32d211d18837b63a3befd65a24c600e430 --- core/coreiface/options/block.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/coreiface/options/block.go b/core/coreiface/options/block.go index d6da99774..99445cca3 100644 --- a/core/coreiface/options/block.go +++ b/core/coreiface/options/block.go @@ -19,7 +19,7 @@ type BlockRmOption func(*BlockRmSettings) error func BlockPutOptions(opts ...BlockPutOption) (*BlockPutSettings, error) { options := &BlockPutSettings{ - Codec: "v0", + Codec: "", MhType: multihash.SHA2_256, MhLength: -1, } From b089e7cadcdb8cdf85874ea606bb64e7a1023487 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 15 Aug 2018 14:01:19 +0200 Subject: [PATCH 0078/1212] coreapi: block: move option logic to options package MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@68340710253f13b5c5376a9f882608cb0ab17f8c This commit was moved from ipfs/boxo@571c6def44851832a3617c699f1b166d1c9dc959 --- core/coreiface/options/block.go | 44 +++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 5 deletions(-) diff --git a/core/coreiface/options/block.go b/core/coreiface/options/block.go index 99445cca3..36b3baa0e 100644 --- a/core/coreiface/options/block.go +++ b/core/coreiface/options/block.go @@ -1,7 +1,9 @@ package options import ( - "gx/ipfs/QmPnFwZ2JXKnXgMw8CdBPxn7FWh6LLdjUjxV1fKHuJnkr8/go-multihash" + "fmt" + mh "gx/ipfs/QmPnFwZ2JXKnXgMw8CdBPxn7FWh6LLdjUjxV1fKHuJnkr8/go-multihash" + cid "gx/ipfs/QmZFbDTY9jfSBms2MchvYM9oYRbAF19K7Pby47yDBfpPrb/go-cid" ) type BlockPutSettings struct { @@ -17,20 +19,52 @@ type BlockRmSettings struct { type BlockPutOption func(*BlockPutSettings) error type BlockRmOption func(*BlockRmSettings) error -func BlockPutOptions(opts ...BlockPutOption) (*BlockPutSettings, error) { +func BlockPutOptions(opts ...BlockPutOption) (*BlockPutSettings, cid.Prefix, error) { options := &BlockPutSettings{ Codec: "", - MhType: multihash.SHA2_256, + MhType: mh.SHA2_256, MhLength: -1, } for _, opt := range opts { err := opt(options) if err != nil { - return nil, err + return nil, cid.Prefix{}, err } } - return options, nil + + var pref cid.Prefix + pref.Version = 1 + + if options.Codec == "" { + if options.MhType != mh.SHA2_256 || (options.MhLength != -1 && options.MhLength != 32) { + options.Codec = "protobuf" + } else { + options.Codec = "v0" + } + } + + if options.Codec == "v0" && options.MhType == mh.SHA2_256 { + pref.Version = 0 + } + + formatval, ok := cid.Codecs[options.Codec] + if !ok { + return nil, cid.Prefix{}, fmt.Errorf("unrecognized format: %s", options.Codec) + } + + if options.Codec == "v0" { + if options.MhType != mh.SHA2_256 || (options.MhLength != -1 && options.MhLength != 32) { + return nil, cid.Prefix{}, fmt.Errorf("only sha2-255-32 is allowed with CIDv0") + } + } + + pref.Codec = formatval + + pref.MhType = options.MhType + pref.MhLength = options.MhLength + + return options, pref, nil } func BlockRmOptions(opts ...BlockRmOption) (*BlockRmSettings, error) { From 3936b1e39d482574d75aa1e189c33f6c97d90544 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Wed, 29 Aug 2018 21:04:56 -0700 Subject: [PATCH 0079/1212] gx update deps License: MIT Signed-off-by: Steven Allen This commit was moved from ipfs/interface-go-ipfs-core@db3f7c2c47e384fabdc30a1b9141b92f56375f5d This commit was moved from ipfs/boxo@15e2043dc4f58e44d5676386753c2b8ec5be5229 --- core/coreiface/path.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/coreiface/path.go b/core/coreiface/path.go index 25b09f486..7873fe2bf 100644 --- a/core/coreiface/path.go +++ b/core/coreiface/path.go @@ -1,7 +1,7 @@ package iface import ( - ipfspath "gx/ipfs/QmdMPBephdLYNESkruDX2hcDTgFYhoCt4LimWhgnomSdV2/go-path" + ipfspath "gx/ipfs/QmTKaiDxQqVxmA1bRipSuP7hnTSgnMSmEa98NYeS6fcoiv/go-path" cid "gx/ipfs/QmZFbDTY9jfSBms2MchvYM9oYRbAF19K7Pby47yDBfpPrb/go-cid" ) From ae4189615030c7c4180f055426fdac04111ce15d Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Fri, 7 Sep 2018 23:40:08 -0700 Subject: [PATCH 0080/1212] gx: update peerstore Also: * Updates go-floodsub to fix a data race. * Updates golang-lru License: MIT Signed-off-by: Steven Allen This commit was moved from ipfs/interface-go-ipfs-core@618aaa45543916248c209032a2e0309793666dd3 This commit was moved from ipfs/boxo@55f24526833cddd68b49a7858a48d8019b00a617 --- core/coreiface/path.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/coreiface/path.go b/core/coreiface/path.go index 7873fe2bf..c2b4cd869 100644 --- a/core/coreiface/path.go +++ b/core/coreiface/path.go @@ -1,7 +1,7 @@ package iface import ( - ipfspath "gx/ipfs/QmTKaiDxQqVxmA1bRipSuP7hnTSgnMSmEa98NYeS6fcoiv/go-path" + ipfspath "gx/ipfs/QmNgXoHgXU1HzNb2HEZmRww9fDKE9NfDsvQwWLHiKHpvKM/go-path" cid "gx/ipfs/QmZFbDTY9jfSBms2MchvYM9oYRbAF19K7Pby47yDBfpPrb/go-cid" ) From 0787fb8f31349a102368878f3ea92ea59b0385bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Sat, 10 Mar 2018 19:07:50 +0100 Subject: [PATCH 0081/1212] coreapi: dht interface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@bbd736fdecec3e18d61e72b5a4beb9234f66c1ec This commit was moved from ipfs/boxo@6c40247cc1931a891782c579d48f517a7945569b --- core/coreiface/dht.go | 28 ++++++++++++++++++++++++++++ core/coreiface/options/dht.go | 30 ++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 core/coreiface/dht.go create mode 100644 core/coreiface/options/dht.go diff --git a/core/coreiface/dht.go b/core/coreiface/dht.go new file mode 100644 index 000000000..1c8e68bd1 --- /dev/null +++ b/core/coreiface/dht.go @@ -0,0 +1,28 @@ +package iface + +import ( + "context" + + options "github.com/ipfs/go-ipfs/core/coreapi/interface/options" + + ma "gx/ipfs/QmWWQ2Txc2c6tqjsBpzg5Ar652cHPGNsQQp2SejkNmkUMb/go-multiaddr" + peer "gx/ipfs/QmZoWKhxUmZ2seW4BzX6fJkNR8hh9PsGModr7q171yq2SS/go-libp2p-peer" +) + +// DhtAPI specifies the interface to the DHT +type DhtAPI interface { + // FindPeer queries the DHT for all of the multiaddresses associated with a + // Peer ID + FindPeer(context.Context, peer.ID) (<-chan ma.Multiaddr, error) + + // FindProviders finds peers in the DHT who can provide a specific value + // given a key. + FindProviders(context.Context, Path) (<-chan peer.ID, error) //TODO: is path the right choice here? + + // Provide announces to the network that you are providing given values + Provide(context.Context, Path, ...options.DhtProvideOption) error + + // WithRecursive is an option for Provide which specifies whether to provide + // the given path recursively + WithRecursive(recursive bool) options.DhtProvideOption +} diff --git a/core/coreiface/options/dht.go b/core/coreiface/options/dht.go new file mode 100644 index 000000000..92fd14f4a --- /dev/null +++ b/core/coreiface/options/dht.go @@ -0,0 +1,30 @@ +package options + +type DhtProvideSettings struct { + Recursive bool +} + +type DhtProvideOption func(*DhtProvideSettings) error + +func DhtProvideOptions(opts ...DhtProvideOption) (*DhtProvideSettings, error) { + options := &DhtProvideSettings{ + Recursive: false, + } + + for _, opt := range opts { + err := opt(options) + if err != nil { + return nil, err + } + } + return options, nil +} + +type DhtOptions struct{} + +func (api *DhtOptions) WithRecursive(recursive bool) DhtProvideOption { + return func(settings *DhtProvideSettings) error { + settings.Recursive = recursive + return nil + } +} From e11318040f8b6c396e64cfbfad1e31332275b7b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Sat, 10 Mar 2018 19:12:54 +0100 Subject: [PATCH 0082/1212] coreapi: implement dht api MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@db9865b9ee918e7db54e6cffa41a0e8950b3e170 This commit was moved from ipfs/boxo@1ca0f8b291354c50b54f51c7afd42bafcee8a0a6 --- core/coreiface/coreapi.go | 3 +++ core/coreiface/dht.go | 6 +++++- core/coreiface/options/dht.go | 26 ++++++++++++++++++++++++++ 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/core/coreiface/coreapi.go b/core/coreiface/coreapi.go index 696eefbaf..9811b75be 100644 --- a/core/coreiface/coreapi.go +++ b/core/coreiface/coreapi.go @@ -31,6 +31,9 @@ type CoreAPI interface { // ObjectAPI returns an implementation of Object API Object() ObjectAPI + // Dht returns an implementation of Dht API + Dht() DhtAPI + // ResolvePath resolves the path using Unixfs resolver ResolvePath(context.Context, Path) (ResolvedPath, error) diff --git a/core/coreiface/dht.go b/core/coreiface/dht.go index 1c8e68bd1..ce8509e01 100644 --- a/core/coreiface/dht.go +++ b/core/coreiface/dht.go @@ -17,7 +17,11 @@ type DhtAPI interface { // FindProviders finds peers in the DHT who can provide a specific value // given a key. - FindProviders(context.Context, Path) (<-chan peer.ID, error) //TODO: is path the right choice here? + FindProviders(context.Context, Path, ...options.DhtFindProvidersOption) (<-chan peer.ID, error) //TODO: is path the right choice here? + + // WithNumProviders is an option for FindProviders which specifies the + // number of peers to look for. Default is 20 + WithNumProviders(numProviders int) options.DhtFindProvidersOption // Provide announces to the network that you are providing given values Provide(context.Context, Path, ...options.DhtProvideOption) error diff --git a/core/coreiface/options/dht.go b/core/coreiface/options/dht.go index 92fd14f4a..3867e32c0 100644 --- a/core/coreiface/options/dht.go +++ b/core/coreiface/options/dht.go @@ -4,7 +4,12 @@ type DhtProvideSettings struct { Recursive bool } +type DhtFindProvidersSettings struct { + NumProviders int +} + type DhtProvideOption func(*DhtProvideSettings) error +type DhtFindProvidersOption func(*DhtFindProvidersSettings) error func DhtProvideOptions(opts ...DhtProvideOption) (*DhtProvideSettings, error) { options := &DhtProvideSettings{ @@ -20,6 +25,20 @@ func DhtProvideOptions(opts ...DhtProvideOption) (*DhtProvideSettings, error) { return options, nil } +func DhtFindProvidersOptions(opts ...DhtFindProvidersOption) (*DhtFindProvidersSettings, error) { + options := &DhtFindProvidersSettings{ + NumProviders: 20, + } + + for _, opt := range opts { + err := opt(options) + if err != nil { + return nil, err + } + } + return options, nil +} + type DhtOptions struct{} func (api *DhtOptions) WithRecursive(recursive bool) DhtProvideOption { @@ -28,3 +47,10 @@ func (api *DhtOptions) WithRecursive(recursive bool) DhtProvideOption { return nil } } + +func (api *DhtOptions) WithNumProviders(numProviders int) DhtFindProvidersOption { + return func(settings *DhtFindProvidersSettings) error { + settings.NumProviders = numProviders + return nil + } +} From afebd69388663cc1834e6f3e5660d91883cf6938 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Sat, 10 Mar 2018 19:17:30 +0100 Subject: [PATCH 0083/1212] coreapi: test using mock swarm MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@db721461cc7c24fba56f74cfd6eb9c8064d0f8c5 This commit was moved from ipfs/boxo@0e411a61d02330a3b2544fb300e4577c1e0a1087 --- core/coreiface/dht.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/coreiface/dht.go b/core/coreiface/dht.go index ce8509e01..1d23ece1f 100644 --- a/core/coreiface/dht.go +++ b/core/coreiface/dht.go @@ -5,8 +5,8 @@ import ( options "github.com/ipfs/go-ipfs/core/coreapi/interface/options" - ma "gx/ipfs/QmWWQ2Txc2c6tqjsBpzg5Ar652cHPGNsQQp2SejkNmkUMb/go-multiaddr" - peer "gx/ipfs/QmZoWKhxUmZ2seW4BzX6fJkNR8hh9PsGModr7q171yq2SS/go-libp2p-peer" + peer "gx/ipfs/QmQsErDt8Qgw1XrsXf2BpEzDgGWtB1YLsTAARBup5b6B9W/go-libp2p-peer" + ma "gx/ipfs/QmYmsdtJ3HsodkePE3eU3TsCaP2YvPZJ4LoXnNkDE5Tpt7/go-multiaddr" ) // DhtAPI specifies the interface to the DHT From e8da394b2146191447cf5812e4a8bcc846effcd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 19 Jul 2018 13:18:05 +0200 Subject: [PATCH 0084/1212] coreapi: dht: simplify the implementation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@22a12c2c233473aafa66ced10e222162a7711868 This commit was moved from ipfs/boxo@78b1cf5653e1cc2d8192db2b541fa09e2dbb2c7f --- core/coreiface/dht.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/core/coreiface/dht.go b/core/coreiface/dht.go index 1d23ece1f..01b7d7367 100644 --- a/core/coreiface/dht.go +++ b/core/coreiface/dht.go @@ -3,21 +3,21 @@ package iface import ( "context" - options "github.com/ipfs/go-ipfs/core/coreapi/interface/options" + "github.com/ipfs/go-ipfs/core/coreapi/interface/options" peer "gx/ipfs/QmQsErDt8Qgw1XrsXf2BpEzDgGWtB1YLsTAARBup5b6B9W/go-libp2p-peer" - ma "gx/ipfs/QmYmsdtJ3HsodkePE3eU3TsCaP2YvPZJ4LoXnNkDE5Tpt7/go-multiaddr" + pstore "gx/ipfs/Qmda4cPRvSRyox3SqgJN6DfSZGU5TtHufPTp9uXjFj71X6/go-libp2p-peerstore" ) // DhtAPI specifies the interface to the DHT type DhtAPI interface { // FindPeer queries the DHT for all of the multiaddresses associated with a // Peer ID - FindPeer(context.Context, peer.ID) (<-chan ma.Multiaddr, error) + FindPeer(context.Context, peer.ID) (pstore.PeerInfo, error) // FindProviders finds peers in the DHT who can provide a specific value // given a key. - FindProviders(context.Context, Path, ...options.DhtFindProvidersOption) (<-chan peer.ID, error) //TODO: is path the right choice here? + FindProviders(context.Context, Path, ...options.DhtFindProvidersOption) (<-chan pstore.PeerInfo, error) // WithNumProviders is an option for FindProviders which specifies the // number of peers to look for. Default is 20 From db3e060d61725dc22e97d7dab4ea69b3990f1170 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 19 Jul 2018 13:27:06 +0200 Subject: [PATCH 0085/1212] coreapi: dht: refactor options after rebase MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@656fc75b6f65435e224b7bd1e392ee8daf90f9b2 This commit was moved from ipfs/boxo@2bef47921404e491af08c3f66fc8475f53526685 --- core/coreiface/dht.go | 8 -------- core/coreiface/options/dht.go | 12 +++++++++--- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/core/coreiface/dht.go b/core/coreiface/dht.go index 01b7d7367..f9a08df34 100644 --- a/core/coreiface/dht.go +++ b/core/coreiface/dht.go @@ -19,14 +19,6 @@ type DhtAPI interface { // given a key. FindProviders(context.Context, Path, ...options.DhtFindProvidersOption) (<-chan pstore.PeerInfo, error) - // WithNumProviders is an option for FindProviders which specifies the - // number of peers to look for. Default is 20 - WithNumProviders(numProviders int) options.DhtFindProvidersOption - // Provide announces to the network that you are providing given values Provide(context.Context, Path, ...options.DhtProvideOption) error - - // WithRecursive is an option for Provide which specifies whether to provide - // the given path recursively - WithRecursive(recursive bool) options.DhtProvideOption } diff --git a/core/coreiface/options/dht.go b/core/coreiface/options/dht.go index 3867e32c0..f989fa5e7 100644 --- a/core/coreiface/options/dht.go +++ b/core/coreiface/options/dht.go @@ -39,16 +39,22 @@ func DhtFindProvidersOptions(opts ...DhtFindProvidersOption) (*DhtFindProvidersS return options, nil } -type DhtOptions struct{} +type dhtOpts struct{} -func (api *DhtOptions) WithRecursive(recursive bool) DhtProvideOption { +var Dht dhtOpts + +// WithRecursive is an option for Dht.Provide which specifies whether to provide +// the given path recursively +func (dhtOpts) WithRecursive(recursive bool) DhtProvideOption { return func(settings *DhtProvideSettings) error { settings.Recursive = recursive return nil } } -func (api *DhtOptions) WithNumProviders(numProviders int) DhtFindProvidersOption { +// WithNumProviders is an option for Dht.FindProviders which specifies the +// number of peers to look for. Default is 20 +func (dhtOpts) WithNumProviders(numProviders int) DhtFindProvidersOption { return func(settings *DhtFindProvidersSettings) error { settings.NumProviders = numProviders return nil From 1baa0c0a71135bed10d4602d53ae642860d47d40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 26 Jul 2018 15:09:26 +0200 Subject: [PATCH 0086/1212] coreapi dht: add a note on name change MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@da52b4bfdb425964a3b5909bdbeacdfdb57cef40 This commit was moved from ipfs/boxo@1ee72b14142c20703fe9bd9690543d42491b5a91 --- core/coreiface/dht.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/coreiface/dht.go b/core/coreiface/dht.go index f9a08df34..cd704c3e3 100644 --- a/core/coreiface/dht.go +++ b/core/coreiface/dht.go @@ -10,6 +10,8 @@ import ( ) // DhtAPI specifies the interface to the DHT +// Note: This API will likely get renamed in near future, see +// https://github.com/ipfs/interface-ipfs-core/issues/249 for more context. type DhtAPI interface { // FindPeer queries the DHT for all of the multiaddresses associated with a // Peer ID From 835950fe4a2548c91a771c7cc67b24991747328f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 10 Aug 2018 13:24:33 +0200 Subject: [PATCH 0087/1212] move streaming set to thirdparty MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@03a210bb130d8d46bc9d8c8bbac953edff53f32f This commit was moved from ipfs/boxo@8de59ef7854d5f337c333acc9902715e274cf2dc --- core/coreiface/dht.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/coreiface/dht.go b/core/coreiface/dht.go index cd704c3e3..7b8119e44 100644 --- a/core/coreiface/dht.go +++ b/core/coreiface/dht.go @@ -10,7 +10,7 @@ import ( ) // DhtAPI specifies the interface to the DHT -// Note: This API will likely get renamed in near future, see +// Note: This API will likely get deprecated in near future, see // https://github.com/ipfs/interface-ipfs-core/issues/249 for more context. type DhtAPI interface { // FindPeer queries the DHT for all of the multiaddresses associated with a From f56bdca2e6d56240778d8688e580ca385c2becc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 28 Aug 2018 02:22:09 +0200 Subject: [PATCH 0088/1212] coreapi: dht: remove option prefix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@a288d2c93dd22c48050ffb8cadce259377fd2125 This commit was moved from ipfs/boxo@4390a24ff2b4e85d7c999f3a1066c55bb2fa1cd6 --- core/coreiface/options/dht.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/core/coreiface/options/dht.go b/core/coreiface/options/dht.go index f989fa5e7..e13e16020 100644 --- a/core/coreiface/options/dht.go +++ b/core/coreiface/options/dht.go @@ -43,18 +43,18 @@ type dhtOpts struct{} var Dht dhtOpts -// WithRecursive is an option for Dht.Provide which specifies whether to provide +// Recursive is an option for Dht.Provide which specifies whether to provide // the given path recursively -func (dhtOpts) WithRecursive(recursive bool) DhtProvideOption { +func (dhtOpts) Recursive(recursive bool) DhtProvideOption { return func(settings *DhtProvideSettings) error { settings.Recursive = recursive return nil } } -// WithNumProviders is an option for Dht.FindProviders which specifies the +// NumProviders is an option for Dht.FindProviders which specifies the // number of peers to look for. Default is 20 -func (dhtOpts) WithNumProviders(numProviders int) DhtFindProvidersOption { +func (dhtOpts) NumProviders(numProviders int) DhtFindProvidersOption { return func(settings *DhtFindProvidersSettings) error { settings.NumProviders = numProviders return nil From 00a0dc6a4b8a9a580abc1e5ed50539f2d5400499 Mon Sep 17 00:00:00 2001 From: Kevin Atkinson Date: Tue, 11 Sep 2018 22:19:44 -0400 Subject: [PATCH 0089/1212] gx update and fix code to use new Cid type License: MIT Signed-off-by: Kevin Atkinson This commit was moved from ipfs/interface-go-ipfs-core@bdbcb4cff02fb5502fc59563e5cb51c641261390 This commit was moved from ipfs/boxo@a48e694f9d8c710e4354c9818c46ae76d5fece00 --- core/coreiface/coreapi.go | 2 +- core/coreiface/dag.go | 2 +- core/coreiface/object.go | 6 +++--- core/coreiface/options/block.go | 2 +- core/coreiface/options/dag.go | 2 +- core/coreiface/path.go | 22 +++++++++++----------- core/coreiface/unixfs.go | 2 +- 7 files changed, 19 insertions(+), 19 deletions(-) diff --git a/core/coreiface/coreapi.go b/core/coreiface/coreapi.go index 9811b75be..0053d472e 100644 --- a/core/coreiface/coreapi.go +++ b/core/coreiface/coreapi.go @@ -5,7 +5,7 @@ package iface import ( "context" - ipld "gx/ipfs/QmX5CsuHyVZeTLxgRSYkgLSDQKb9UjE8xnhQzCEJWWWFsC/go-ipld-format" + ipld "gx/ipfs/QmdDXJs4axxefSPgK6Y1QhpJWKuDPnGJiqgq4uncb4rFHL/go-ipld-format" ) // CoreAPI defines an unified interface to IPFS for Go programs diff --git a/core/coreiface/dag.go b/core/coreiface/dag.go index d3270928c..06bb91dce 100644 --- a/core/coreiface/dag.go +++ b/core/coreiface/dag.go @@ -6,7 +6,7 @@ import ( "github.com/ipfs/go-ipfs/core/coreapi/interface/options" - ipld "gx/ipfs/QmX5CsuHyVZeTLxgRSYkgLSDQKb9UjE8xnhQzCEJWWWFsC/go-ipld-format" + ipld "gx/ipfs/QmdDXJs4axxefSPgK6Y1QhpJWKuDPnGJiqgq4uncb4rFHL/go-ipld-format" ) // DagOps groups operations that can be batched together diff --git a/core/coreiface/object.go b/core/coreiface/object.go index 750638a33..6b355a302 100644 --- a/core/coreiface/object.go +++ b/core/coreiface/object.go @@ -6,14 +6,14 @@ import ( options "github.com/ipfs/go-ipfs/core/coreapi/interface/options" - ipld "gx/ipfs/QmX5CsuHyVZeTLxgRSYkgLSDQKb9UjE8xnhQzCEJWWWFsC/go-ipld-format" - cid "gx/ipfs/QmZFbDTY9jfSBms2MchvYM9oYRbAF19K7Pby47yDBfpPrb/go-cid" + cid "gx/ipfs/QmPSQnBKM9g7BaUcZCvswUJVscQ1ipjmwxN5PXCjkp9EQ7/go-cid" + ipld "gx/ipfs/QmdDXJs4axxefSPgK6Y1QhpJWKuDPnGJiqgq4uncb4rFHL/go-ipld-format" ) // ObjectStat provides information about dag nodes type ObjectStat struct { // Cid is the CID of the node - Cid *cid.Cid + Cid cid.Cid // NumLinks is number of links the node contains NumLinks int diff --git a/core/coreiface/options/block.go b/core/coreiface/options/block.go index 36b3baa0e..6603136f3 100644 --- a/core/coreiface/options/block.go +++ b/core/coreiface/options/block.go @@ -2,8 +2,8 @@ package options import ( "fmt" + cid "gx/ipfs/QmPSQnBKM9g7BaUcZCvswUJVscQ1ipjmwxN5PXCjkp9EQ7/go-cid" mh "gx/ipfs/QmPnFwZ2JXKnXgMw8CdBPxn7FWh6LLdjUjxV1fKHuJnkr8/go-multihash" - cid "gx/ipfs/QmZFbDTY9jfSBms2MchvYM9oYRbAF19K7Pby47yDBfpPrb/go-cid" ) type BlockPutSettings struct { diff --git a/core/coreiface/options/dag.go b/core/coreiface/options/dag.go index 689bb5c53..4fdff0489 100644 --- a/core/coreiface/options/dag.go +++ b/core/coreiface/options/dag.go @@ -3,7 +3,7 @@ package options import ( "math" - cid "gx/ipfs/QmZFbDTY9jfSBms2MchvYM9oYRbAF19K7Pby47yDBfpPrb/go-cid" + cid "gx/ipfs/QmPSQnBKM9g7BaUcZCvswUJVscQ1ipjmwxN5PXCjkp9EQ7/go-cid" ) type DagPutSettings struct { diff --git a/core/coreiface/path.go b/core/coreiface/path.go index c2b4cd869..e11e20cf0 100644 --- a/core/coreiface/path.go +++ b/core/coreiface/path.go @@ -1,9 +1,9 @@ package iface import ( - ipfspath "gx/ipfs/QmNgXoHgXU1HzNb2HEZmRww9fDKE9NfDsvQwWLHiKHpvKM/go-path" + ipfspath "gx/ipfs/QmRYx6fJzTWFoeTo3qQn64iDrVC154Gy9waQDhvKRr2ND3/go-path" - cid "gx/ipfs/QmZFbDTY9jfSBms2MchvYM9oYRbAF19K7Pby47yDBfpPrb/go-cid" + cid "gx/ipfs/QmPSQnBKM9g7BaUcZCvswUJVscQ1ipjmwxN5PXCjkp9EQ7/go-cid" ) //TODO: merge with ipfspath so we don't depend on it @@ -65,7 +65,7 @@ type ResolvedPath interface { // * Calling Cid() will return `cidB` // * Calling Root() will return `cidRoot` // * Calling Remainder() will return `foo/bar` - Cid() *cid.Cid + Cid() cid.Cid // Root returns the CID of the root object of the path // @@ -74,7 +74,7 @@ type ResolvedPath interface { // "/ipfs/QmRoot/A/B", the Root method will return the CID of object QmRoot // // For more examples see the documentation of Cid() method - Root() *cid.Cid + Root() cid.Cid // Remainder returns unresolved part of the path // @@ -100,13 +100,13 @@ type path struct { // resolvedPath implements coreiface.resolvedPath type resolvedPath struct { path - cid *cid.Cid - root *cid.Cid + cid cid.Cid + root cid.Cid remainder string } // IpfsPath creates new /ipfs path from the provided CID -func IpfsPath(c *cid.Cid) ResolvedPath { +func IpfsPath(c cid.Cid) ResolvedPath { return &resolvedPath{ path: path{ipfspath.Path("/ipfs/" + c.String())}, cid: c, @@ -116,7 +116,7 @@ func IpfsPath(c *cid.Cid) ResolvedPath { } // IpldPath creates new /ipld path from the provided CID -func IpldPath(c *cid.Cid) ResolvedPath { +func IpldPath(c cid.Cid) ResolvedPath { return &resolvedPath{ path: path{ipfspath.Path("/ipld/" + c.String())}, cid: c, @@ -138,7 +138,7 @@ func ParsePath(p string) (Path, error) { // NewResolvedPath creates new ResolvedPath. This function performs no checks // and is intended to be used by resolver implementations. Incorrect inputs may // cause panics. Handle with care. -func NewResolvedPath(ipath ipfspath.Path, c *cid.Cid, root *cid.Cid, remainder string) ResolvedPath { +func NewResolvedPath(ipath ipfspath.Path, c cid.Cid, root cid.Cid, remainder string) ResolvedPath { return &resolvedPath{ path: path{ipath}, cid: c, @@ -163,11 +163,11 @@ func (p *path) Mutable() bool { return p.Namespace() == "ipns" } -func (p *resolvedPath) Cid() *cid.Cid { +func (p *resolvedPath) Cid() cid.Cid { return p.cid } -func (p *resolvedPath) Root() *cid.Cid { +func (p *resolvedPath) Root() cid.Cid { return p.root } diff --git a/core/coreiface/unixfs.go b/core/coreiface/unixfs.go index 80f7ba396..4a3aff6fc 100644 --- a/core/coreiface/unixfs.go +++ b/core/coreiface/unixfs.go @@ -4,7 +4,7 @@ import ( "context" "io" - ipld "gx/ipfs/QmX5CsuHyVZeTLxgRSYkgLSDQKb9UjE8xnhQzCEJWWWFsC/go-ipld-format" + ipld "gx/ipfs/QmdDXJs4axxefSPgK6Y1QhpJWKuDPnGJiqgq4uncb4rFHL/go-ipld-format" ) // UnixfsAPI is the basic interface to immutable files in IPFS From 4160bd519c749fec8d300939a6f51e562cfa4c1a Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Tue, 11 Sep 2018 20:34:52 -0700 Subject: [PATCH 0090/1212] gx: fix hashes (some extra files got committed) License: MIT Signed-off-by: Steven Allen This commit was moved from ipfs/interface-go-ipfs-core@dec563d93e818189ec52f7eeeb70128c1c62deae This commit was moved from ipfs/boxo@91297a54c6b70a51fdea8f98c646e4191fc5d9ae --- core/coreiface/path.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/coreiface/path.go b/core/coreiface/path.go index e11e20cf0..c61b33533 100644 --- a/core/coreiface/path.go +++ b/core/coreiface/path.go @@ -1,7 +1,7 @@ package iface import ( - ipfspath "gx/ipfs/QmRYx6fJzTWFoeTo3qQn64iDrVC154Gy9waQDhvKRr2ND3/go-path" + ipfspath "gx/ipfs/QmX7uSbkNz76yNwBhuwYwRbhihLnJqM73VTCjS3UMJud9A/go-path" cid "gx/ipfs/QmPSQnBKM9g7BaUcZCvswUJVscQ1ipjmwxN5PXCjkp9EQ7/go-cid" ) From 7455bd65c0698e9a7975fd9fb072de6beb126e89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 18 Sep 2018 04:30:33 +0200 Subject: [PATCH 0091/1212] resolve cmd: use coreapi MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@c3053e816481188f8b20f1d56c3cfa648d4f39c8 This commit was moved from ipfs/boxo@28fe139695b6494eb257aca0d7e21741497a640a --- core/coreiface/options/name.go | 43 +++++++++++++++++++++++++++------- 1 file changed, 34 insertions(+), 9 deletions(-) diff --git a/core/coreiface/options/name.go b/core/coreiface/options/name.go index 48aecf18b..9ba4a8770 100644 --- a/core/coreiface/options/name.go +++ b/core/coreiface/options/name.go @@ -14,9 +14,12 @@ type NamePublishSettings struct { } type NameResolveSettings struct { - Recursive bool - Local bool - Cache bool + Depth int + Local bool + Cache bool + + DhtRecordCount int + DhtTimeout time.Duration } type NamePublishOption func(*NamePublishSettings) error @@ -40,9 +43,12 @@ func NamePublishOptions(opts ...NamePublishOption) (*NamePublishSettings, error) func NameResolveOptions(opts ...NameResolveOption) (*NameResolveSettings, error) { options := &NameResolveSettings{ - Recursive: false, - Local: false, - Cache: true, + Depth: 1, + Local: false, + Cache: true, + + DhtRecordCount: 16, + DhtTimeout: time.Minute, } for _, opt := range opts { @@ -80,11 +86,11 @@ func (nameOpts) Key(key string) NamePublishOption { } } -// Recursive is an option for Name.Resolve which specifies whether to perform a +// Depth is an option for Name.Resolve which specifies the maximum depth of a // recursive lookup. Default value is false -func (nameOpts) Recursive(recursive bool) NameResolveOption { +func (nameOpts) Depth(depth int) NameResolveOption { return func(settings *NameResolveSettings) error { - settings.Recursive = recursive + settings.Depth = depth return nil } } @@ -106,3 +112,22 @@ func (nameOpts) Cache(cache bool) NameResolveOption { return nil } } + +// DhtRecordCount is an option for Name.Resolve which specifies how many records +// we want to validate before selecting the best one (newest). Note that setting +// this value too low will have security implications +func (nameOpts) DhtRecordCount(rc int) NameResolveOption { + return func(settings *NameResolveSettings) error { + settings.DhtRecordCount = rc + return nil + } +} + +// DhtTimeout is an option for Name.Resolve which specifies timeout for +// DHT lookup +func (nameOpts) DhtTimeout(timeout time.Duration) NameResolveOption { + return func(settings *NameResolveSettings) error { + settings.DhtTimeout = timeout + return nil + } +} From 5411cc043c1656f4d4def511bea861932393b7c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 19 Sep 2018 11:51:42 +0200 Subject: [PATCH 0092/1212] coreapi name: accept namesys options MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@ca81d824222df0ed2c1ede6a3e166f7aa420b4f7 This commit was moved from ipfs/boxo@cd88b19ccb6d4ff617ea5e4c329c284315fc8707 --- core/coreiface/options/name.go | 36 ++++++---------------------------- 1 file changed, 6 insertions(+), 30 deletions(-) diff --git a/core/coreiface/options/name.go b/core/coreiface/options/name.go index 9ba4a8770..ba3691b03 100644 --- a/core/coreiface/options/name.go +++ b/core/coreiface/options/name.go @@ -2,6 +2,8 @@ package options import ( "time" + + ropts "github.com/ipfs/go-ipfs/namesys/opts" ) const ( @@ -14,12 +16,10 @@ type NamePublishSettings struct { } type NameResolveSettings struct { - Depth int Local bool Cache bool - DhtRecordCount int - DhtTimeout time.Duration + ResolveOpts []ropts.ResolveOpt } type NamePublishOption func(*NamePublishSettings) error @@ -43,12 +43,8 @@ func NamePublishOptions(opts ...NamePublishOption) (*NamePublishSettings, error) func NameResolveOptions(opts ...NameResolveOption) (*NameResolveSettings, error) { options := &NameResolveSettings{ - Depth: 1, Local: false, Cache: true, - - DhtRecordCount: 16, - DhtTimeout: time.Minute, } for _, opt := range opts { @@ -86,15 +82,6 @@ func (nameOpts) Key(key string) NamePublishOption { } } -// Depth is an option for Name.Resolve which specifies the maximum depth of a -// recursive lookup. Default value is false -func (nameOpts) Depth(depth int) NameResolveOption { - return func(settings *NameResolveSettings) error { - settings.Depth = depth - return nil - } -} - // Local is an option for Name.Resolve which specifies if the lookup should be // offline. Default value is false func (nameOpts) Local(local bool) NameResolveOption { @@ -113,21 +100,10 @@ func (nameOpts) Cache(cache bool) NameResolveOption { } } -// DhtRecordCount is an option for Name.Resolve which specifies how many records -// we want to validate before selecting the best one (newest). Note that setting -// this value too low will have security implications -func (nameOpts) DhtRecordCount(rc int) NameResolveOption { +// +func (nameOpts) ResolveOption(opt ropts.ResolveOpt) NameResolveOption { return func(settings *NameResolveSettings) error { - settings.DhtRecordCount = rc - return nil - } -} - -// DhtTimeout is an option for Name.Resolve which specifies timeout for -// DHT lookup -func (nameOpts) DhtTimeout(timeout time.Duration) NameResolveOption { - return func(settings *NameResolveSettings) error { - settings.DhtTimeout = timeout + settings.ResolveOpts = append(settings.ResolveOpts, opt) return nil } } From e8e2f54912998b5d4f2bd97f45ccc58aef0dbd4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 24 Sep 2018 14:03:57 +0200 Subject: [PATCH 0093/1212] gx: update go-libp2p-routing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@143c911f1528ad45768b9ea1dd180b865c229fd1 This commit was moved from ipfs/boxo@fdaee8e479945dfe29bec1b56e575b5c9622a454 --- core/coreiface/path.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/coreiface/path.go b/core/coreiface/path.go index c61b33533..75901eaa4 100644 --- a/core/coreiface/path.go +++ b/core/coreiface/path.go @@ -1,7 +1,7 @@ package iface import ( - ipfspath "gx/ipfs/QmX7uSbkNz76yNwBhuwYwRbhihLnJqM73VTCjS3UMJud9A/go-path" + ipfspath "gx/ipfs/Qmc17MNY1xUgiE2nopbi6KATWau9qcGZtdmKKuXvFMVUgc/go-path" cid "gx/ipfs/QmPSQnBKM9g7BaUcZCvswUJVscQ1ipjmwxN5PXCjkp9EQ7/go-cid" ) From ba7a34448e2bed4e26cc1feec81c5c98fe6cfbb6 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Mon, 24 Sep 2018 05:36:29 -0700 Subject: [PATCH 0094/1212] gx: update go-log go-ipld-cbor (and friends) License: MIT Signed-off-by: Steven Allen This commit was moved from ipfs/interface-go-ipfs-core@c1e241f73b853d5b8626125d24f8346c6331622b This commit was moved from ipfs/boxo@3bff21ef38fb40c5920de6e475607cd6e31bf0e5 --- core/coreiface/dht.go | 4 ++-- core/coreiface/key.go | 2 +- core/coreiface/path.go | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/core/coreiface/dht.go b/core/coreiface/dht.go index 7b8119e44..2309ceb90 100644 --- a/core/coreiface/dht.go +++ b/core/coreiface/dht.go @@ -5,8 +5,8 @@ import ( "github.com/ipfs/go-ipfs/core/coreapi/interface/options" - peer "gx/ipfs/QmQsErDt8Qgw1XrsXf2BpEzDgGWtB1YLsTAARBup5b6B9W/go-libp2p-peer" - pstore "gx/ipfs/Qmda4cPRvSRyox3SqgJN6DfSZGU5TtHufPTp9uXjFj71X6/go-libp2p-peerstore" + peer "gx/ipfs/QmbNepETomvmXfz1X5pHNFD2QuPqnqi47dTd94QJWSorQ3/go-libp2p-peer" + pstore "gx/ipfs/QmfAQMFpgDU2U4BXG64qVr8HSiictfWvkSBz7Y2oDj65st/go-libp2p-peerstore" ) // DhtAPI specifies the interface to the DHT diff --git a/core/coreiface/key.go b/core/coreiface/key.go index cc7c409fd..4305ae20d 100644 --- a/core/coreiface/key.go +++ b/core/coreiface/key.go @@ -5,7 +5,7 @@ import ( options "github.com/ipfs/go-ipfs/core/coreapi/interface/options" - "gx/ipfs/QmQsErDt8Qgw1XrsXf2BpEzDgGWtB1YLsTAARBup5b6B9W/go-libp2p-peer" + "gx/ipfs/QmbNepETomvmXfz1X5pHNFD2QuPqnqi47dTd94QJWSorQ3/go-libp2p-peer" ) // Key specifies the interface to Keys in KeyAPI Keystore diff --git a/core/coreiface/path.go b/core/coreiface/path.go index 75901eaa4..0beab0663 100644 --- a/core/coreiface/path.go +++ b/core/coreiface/path.go @@ -1,7 +1,7 @@ package iface import ( - ipfspath "gx/ipfs/Qmc17MNY1xUgiE2nopbi6KATWau9qcGZtdmKKuXvFMVUgc/go-path" + ipfspath "gx/ipfs/QmcjwUb36Z16NJkvDX6ccXPqsFswo6AsRXynyXcLLCphV2/go-path" cid "gx/ipfs/QmPSQnBKM9g7BaUcZCvswUJVscQ1ipjmwxN5PXCjkp9EQ7/go-cid" ) From 8404b8263de39467bda064cdce59293db5914a40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Sat, 10 Mar 2018 18:54:58 +0100 Subject: [PATCH 0095/1212] coreapi: swarm interface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@bc2ae0a441ed2da875bf2d815766e90b2c2a4d9f This commit was moved from ipfs/boxo@398a8ffdf544dac64be994ce4a34ef3013d9d584 --- core/coreiface/swarm.go | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 core/coreiface/swarm.go diff --git a/core/coreiface/swarm.go b/core/coreiface/swarm.go new file mode 100644 index 000000000..1ec260e07 --- /dev/null +++ b/core/coreiface/swarm.go @@ -0,0 +1,37 @@ +package iface + +import ( + "time" + + "context" + ma "gx/ipfs/QmWWQ2Txc2c6tqjsBpzg5Ar652cHPGNsQQp2SejkNmkUMb/go-multiaddr" + peer "gx/ipfs/QmZoWKhxUmZ2seW4BzX6fJkNR8hh9PsGModr7q171yq2SS/go-libp2p-peer" +) + +// PeerInfo contains information about a peer +type PeerInfo interface { + // ID returns PeerID + ID() peer.ID + + // Address returns the multiaddress via which we are connected with the peer + Address() ma.Multiaddr + + // Latency returns last known round trip time to the peer + Latency() time.Duration + + // Streams returns list of streams established with the peer + // TODO: should this return multicodecs? + Streams() []string +} + +// SwarmAPI specifies the interface to libp2p swarm +type SwarmAPI interface { + // Connect to a given address + Connect(context.Context, ma.Multiaddr) error + + // Disconnect from a given address + Disconnect(context.Context, ma.Multiaddr) error + + // Peers returns the list of peers we are connected to + Peers(context.Context) ([]PeerInfo, error) +} From fc8386301bc0534bac90eeb0b1c3b7b4a908a0b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Sat, 10 Mar 2018 19:02:57 +0100 Subject: [PATCH 0096/1212] coreapi: implement swarm api MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@3ab7f14240700d0e64e011e5fca7c847afc9ce9e This commit was moved from ipfs/boxo@81615a9f48e0bba90d04b4ac389948124aeff053 --- core/coreiface/coreapi.go | 3 +++ core/coreiface/swarm.go | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/core/coreiface/coreapi.go b/core/coreiface/coreapi.go index 0053d472e..0b153b6f9 100644 --- a/core/coreiface/coreapi.go +++ b/core/coreiface/coreapi.go @@ -34,6 +34,9 @@ type CoreAPI interface { // Dht returns an implementation of Dht API Dht() DhtAPI + // Swarm returns an implementation of Swarm API + Swarm() SwarmAPI + // ResolvePath resolves the path using Unixfs resolver ResolvePath(context.Context, Path) (ResolvedPath, error) diff --git a/core/coreiface/swarm.go b/core/coreiface/swarm.go index 1ec260e07..1f0b1216f 100644 --- a/core/coreiface/swarm.go +++ b/core/coreiface/swarm.go @@ -1,9 +1,9 @@ package iface import ( + "context" "time" - "context" ma "gx/ipfs/QmWWQ2Txc2c6tqjsBpzg5Ar652cHPGNsQQp2SejkNmkUMb/go-multiaddr" peer "gx/ipfs/QmZoWKhxUmZ2seW4BzX6fJkNR8hh9PsGModr7q171yq2SS/go-libp2p-peer" ) @@ -17,11 +17,11 @@ type PeerInfo interface { Address() ma.Multiaddr // Latency returns last known round trip time to the peer - Latency() time.Duration + Latency(context.Context) (time.Duration, error) // Streams returns list of streams established with the peer // TODO: should this return multicodecs? - Streams() []string + Streams(context.Context) ([]string, error) } // SwarmAPI specifies the interface to libp2p swarm From e839e46e938487e891dfea804e4ae18bddbefb4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 5 Apr 2018 20:22:49 +0200 Subject: [PATCH 0097/1212] fix infinite loop in connInfo.ID MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@89ce6041ad9b851959cdd2434d4f7ab375459599 This commit was moved from ipfs/boxo@7e79c2365ce422f3c26401f2a0c8e1da99515aaf --- core/coreiface/swarm.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/coreiface/swarm.go b/core/coreiface/swarm.go index 1f0b1216f..92817e6f4 100644 --- a/core/coreiface/swarm.go +++ b/core/coreiface/swarm.go @@ -4,8 +4,8 @@ import ( "context" "time" - ma "gx/ipfs/QmWWQ2Txc2c6tqjsBpzg5Ar652cHPGNsQQp2SejkNmkUMb/go-multiaddr" - peer "gx/ipfs/QmZoWKhxUmZ2seW4BzX6fJkNR8hh9PsGModr7q171yq2SS/go-libp2p-peer" + peer "gx/ipfs/QmQsErDt8Qgw1XrsXf2BpEzDgGWtB1YLsTAARBup5b6B9W/go-libp2p-peer" + ma "gx/ipfs/QmYmsdtJ3HsodkePE3eU3TsCaP2YvPZJ4LoXnNkDE5Tpt7/go-multiaddr" ) // PeerInfo contains information about a peer From 619855cc7a6f166359654b6ac2e6b1e0efcbe000 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 11 Sep 2018 20:50:15 +0200 Subject: [PATCH 0098/1212] swarm cmd: port to new cmd lib MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@59f549fe3aa60f48303f6283e09ae05c9224a84c This commit was moved from ipfs/boxo@6e9149c6f900ec598b0345cc97b0979b53ba8cb0 --- core/coreiface/swarm.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/coreiface/swarm.go b/core/coreiface/swarm.go index 92817e6f4..2492f2696 100644 --- a/core/coreiface/swarm.go +++ b/core/coreiface/swarm.go @@ -4,8 +4,8 @@ import ( "context" "time" - peer "gx/ipfs/QmQsErDt8Qgw1XrsXf2BpEzDgGWtB1YLsTAARBup5b6B9W/go-libp2p-peer" ma "gx/ipfs/QmYmsdtJ3HsodkePE3eU3TsCaP2YvPZJ4LoXnNkDE5Tpt7/go-multiaddr" + peer "gx/ipfs/QmbNepETomvmXfz1X5pHNFD2QuPqnqi47dTd94QJWSorQ3/go-libp2p-peer" ) // PeerInfo contains information about a peer From 284fd898dc3cf0f88b5816cb53d87d41676e9746 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 17 Sep 2018 16:45:59 +0200 Subject: [PATCH 0099/1212] coreapi swarm: rewire connect/disconnect MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@a48b2a807b98f5fe7eb4c1148bf938498a4836ce This commit was moved from ipfs/boxo@0f6f6ec8a4e5b41f01c658bf46f4d30b69a7ade5 --- core/coreiface/swarm.go | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/core/coreiface/swarm.go b/core/coreiface/swarm.go index 2492f2696..7bd009f16 100644 --- a/core/coreiface/swarm.go +++ b/core/coreiface/swarm.go @@ -2,14 +2,22 @@ package iface import ( "context" + "errors" "time" ma "gx/ipfs/QmYmsdtJ3HsodkePE3eU3TsCaP2YvPZJ4LoXnNkDE5Tpt7/go-multiaddr" - peer "gx/ipfs/QmbNepETomvmXfz1X5pHNFD2QuPqnqi47dTd94QJWSorQ3/go-libp2p-peer" + "gx/ipfs/QmZNkThpqfVXs9GNbexPrfBbXSLNYeKrE7jwFM2oqHbyqN/go-libp2p-protocol" + "gx/ipfs/QmbNepETomvmXfz1X5pHNFD2QuPqnqi47dTd94QJWSorQ3/go-libp2p-peer" + pstore "gx/ipfs/QmfAQMFpgDU2U4BXG64qVr8HSiictfWvkSBz7Y2oDj65st/go-libp2p-peerstore" ) -// PeerInfo contains information about a peer -type PeerInfo interface { +var ( + ErrNotConnected = errors.New("not connected") + ErrConnNotFound = errors.New("conn not found") + ) + +// ConnectionInfo contains information about a peer +type ConnectionInfo interface { // ID returns PeerID ID() peer.ID @@ -20,18 +28,17 @@ type PeerInfo interface { Latency(context.Context) (time.Duration, error) // Streams returns list of streams established with the peer - // TODO: should this return multicodecs? - Streams(context.Context) ([]string, error) + Streams(context.Context) ([]protocol.ID, error) } // SwarmAPI specifies the interface to libp2p swarm type SwarmAPI interface { - // Connect to a given address - Connect(context.Context, ma.Multiaddr) error + // Connect to a given peer + Connect(context.Context, pstore.PeerInfo) error // Disconnect from a given address Disconnect(context.Context, ma.Multiaddr) error // Peers returns the list of peers we are connected to - Peers(context.Context) ([]PeerInfo, error) + Peers(context.Context) ([]ConnectionInfo, error) } From cb1f0c550ff5acbde160286b46a5a18d9a4393df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 17 Sep 2018 19:53:15 +0200 Subject: [PATCH 0100/1212] coreapi swarm: rewire address listing cmds MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@8c35696f74f086858b6acaf8ee6a0ffe570e46cb This commit was moved from ipfs/boxo@4020059a81eb3f31fec83c825d6ce4d9dd8c65c4 --- core/coreiface/key.go | 3 +++ core/coreiface/swarm.go | 10 +++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/core/coreiface/key.go b/core/coreiface/key.go index 4305ae20d..cc6dc8900 100644 --- a/core/coreiface/key.go +++ b/core/coreiface/key.go @@ -33,6 +33,9 @@ type KeyAPI interface { // List lists keys stored in keystore List(ctx context.Context) ([]Key, error) + // Self returns the 'main' node key + Self(ctx context.Context) (Key, error) + // Remove removes keys from keystore. Returns ipns path of the removed key Remove(ctx context.Context, name string) (Key, error) } diff --git a/core/coreiface/swarm.go b/core/coreiface/swarm.go index 7bd009f16..caa6a70e3 100644 --- a/core/coreiface/swarm.go +++ b/core/coreiface/swarm.go @@ -9,12 +9,13 @@ import ( "gx/ipfs/QmZNkThpqfVXs9GNbexPrfBbXSLNYeKrE7jwFM2oqHbyqN/go-libp2p-protocol" "gx/ipfs/QmbNepETomvmXfz1X5pHNFD2QuPqnqi47dTd94QJWSorQ3/go-libp2p-peer" pstore "gx/ipfs/QmfAQMFpgDU2U4BXG64qVr8HSiictfWvkSBz7Y2oDj65st/go-libp2p-peerstore" + net "gx/ipfs/QmfDPh144WGBqRxZb1TGDHerbMnZATrHZggAPw7putNnBq/go-libp2p-net" ) var ( ErrNotConnected = errors.New("not connected") ErrConnNotFound = errors.New("conn not found") - ) +) // ConnectionInfo contains information about a peer type ConnectionInfo interface { @@ -24,6 +25,9 @@ type ConnectionInfo interface { // Address returns the multiaddress via which we are connected with the peer Address() ma.Multiaddr + // Direction returns which way the connection was established + Direction() net.Direction + // Latency returns last known round trip time to the peer Latency(context.Context) (time.Duration, error) @@ -41,4 +45,8 @@ type SwarmAPI interface { // Peers returns the list of peers we are connected to Peers(context.Context) ([]ConnectionInfo, error) + + KnownAddrs(context.Context) (map[peer.ID][]ma.Multiaddr, error) + LocalAddrs(context.Context) ([]ma.Multiaddr, error) + ListenAddrs(context.Context) ([]ma.Multiaddr, error) } From a95fe8e687f56947c1356ee4f10739c541e64891 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 2 Oct 2018 12:31:50 +0200 Subject: [PATCH 0101/1212] coreapi swarm: missing docs, review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@162cac0144b96596576bc9ec7389afaa8eb56135 This commit was moved from ipfs/boxo@9df903d67183fbb9c9ae66de11a4c62f92f7c1ee --- core/coreiface/swarm.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/core/coreiface/swarm.go b/core/coreiface/swarm.go index caa6a70e3..8b464e5c1 100644 --- a/core/coreiface/swarm.go +++ b/core/coreiface/swarm.go @@ -29,10 +29,10 @@ type ConnectionInfo interface { Direction() net.Direction // Latency returns last known round trip time to the peer - Latency(context.Context) (time.Duration, error) + Latency() (time.Duration, error) // Streams returns list of streams established with the peer - Streams(context.Context) ([]protocol.ID, error) + Streams() ([]protocol.ID, error) } // SwarmAPI specifies the interface to libp2p swarm @@ -46,7 +46,12 @@ type SwarmAPI interface { // Peers returns the list of peers we are connected to Peers(context.Context) ([]ConnectionInfo, error) + // KnownAddrs returns the list of all addresses this node is aware of KnownAddrs(context.Context) (map[peer.ID][]ma.Multiaddr, error) + + // LocalAddrs returns the list of announced listening addresses LocalAddrs(context.Context) ([]ma.Multiaddr, error) + + // ListenAddrs returns the list of all listening addresses ListenAddrs(context.Context) ([]ma.Multiaddr, error) } From 99c68ac8c97652369fa2eceac144e81f8177bd4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 19 Sep 2018 23:40:45 +0200 Subject: [PATCH 0102/1212] Cleanup instances of manual resolver construction MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@47db102ccd13e62f40e7372b56b33dcf33e63c60 This commit was moved from ipfs/boxo@b7e28a936c5c9edee31e262c366c30fde7d872ab --- core/coreiface/util.go | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/core/coreiface/util.go b/core/coreiface/util.go index 8fd3e058f..6d58bf40d 100644 --- a/core/coreiface/util.go +++ b/core/coreiface/util.go @@ -1,10 +1,20 @@ package iface import ( + "context" "io" ) type Reader interface { - io.ReadSeeker - io.Closer + ReadSeekCloser + Size() uint64 + CtxReadFull(context.Context, []byte) (int, error) +} + +// A ReadSeekCloser implements interfaces to read, copy, seek and close. +type ReadSeekCloser interface { + io.Reader + io.Seeker + io.Closer + io.WriterTo } From 7d9ebdcebe6a0691a0921c167b2c513037b1cebc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 20 Sep 2018 15:00:51 +0200 Subject: [PATCH 0103/1212] coreapi unixfs: use fileAdder directly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@78136afef00445d43c96ec7c66249b881dcf95ff This commit was moved from ipfs/boxo@60c358b08ca8bbb2773d19533ddd9b9864f3d360 --- core/coreiface/options/unixfs.go | 50 ++++++++++++++++++++++++++++++++ core/coreiface/unixfs.go | 4 ++- 2 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 core/coreiface/options/unixfs.go diff --git a/core/coreiface/options/unixfs.go b/core/coreiface/options/unixfs.go new file mode 100644 index 000000000..8dc9806a7 --- /dev/null +++ b/core/coreiface/options/unixfs.go @@ -0,0 +1,50 @@ +package options + +import ( + mh "gx/ipfs/QmPnFwZ2JXKnXgMw8CdBPxn7FWh6LLdjUjxV1fKHuJnkr8/go-multihash" +) + +type UnixfsAddSettings struct { + CidVersion int + MhType uint64 + + InlineLimit int +} + +type UnixfsAddOption func(*UnixfsAddSettings) error + +func UnixfsAddOptions(opts ...UnixfsAddOption) (*UnixfsAddSettings, error) { + options := &UnixfsAddSettings{ + CidVersion: -1, + MhType: mh.SHA2_256, + + InlineLimit: 0, + } + + for _, opt := range opts { + err := opt(options) + if err != nil { + return nil, err + } + } + + return options, nil +} + +type unixfsOpts struct{} + +var Unixfs unixfsOpts + +func (unixfsOpts) CidVersion(version int) UnixfsAddOption { + return func(settings *UnixfsAddSettings) error { + settings.CidVersion = version + return nil + } +} + +func (unixfsOpts) Hash(mhtype uint64) UnixfsAddOption { + return func(settings *UnixfsAddSettings) error { + settings.MhType = mhtype + return nil + } +} diff --git a/core/coreiface/unixfs.go b/core/coreiface/unixfs.go index 4a3aff6fc..10febd9fa 100644 --- a/core/coreiface/unixfs.go +++ b/core/coreiface/unixfs.go @@ -4,13 +4,15 @@ import ( "context" "io" + options "github.com/ipfs/go-ipfs/core/coreapi/interface/options" + ipld "gx/ipfs/QmdDXJs4axxefSPgK6Y1QhpJWKuDPnGJiqgq4uncb4rFHL/go-ipld-format" ) // UnixfsAPI is the basic interface to immutable files in IPFS type UnixfsAPI interface { // Add imports the data from the reader into merkledag file - Add(context.Context, io.Reader) (ResolvedPath, error) + Add(context.Context, io.ReadCloser, ...options.UnixfsAddOption) (ResolvedPath, error) // Cat returns a reader for the file Cat(context.Context, Path) (Reader, error) From d7afe85fe0523066da04d3274cd6f048328ca12f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 20 Sep 2018 15:59:53 +0200 Subject: [PATCH 0104/1212] coreapi unixfs: cid prefix options MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@6c7f760b5d8ae479518992b322a7bd1ccc406247 This commit was moved from ipfs/boxo@0df36df660ece10808c7af055b59cd7052aaa7cf --- core/coreiface/options/unixfs.go | 8 ++++++-- core/coreiface/unixfs.go | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/core/coreiface/options/unixfs.go b/core/coreiface/options/unixfs.go index 8dc9806a7..ffed75577 100644 --- a/core/coreiface/options/unixfs.go +++ b/core/coreiface/options/unixfs.go @@ -8,7 +8,9 @@ type UnixfsAddSettings struct { CidVersion int MhType uint64 - InlineLimit int + InlineLimit int + RawLeaves bool + RawLeavesSet bool } type UnixfsAddOption func(*UnixfsAddSettings) error @@ -18,7 +20,9 @@ func UnixfsAddOptions(opts ...UnixfsAddOption) (*UnixfsAddSettings, error) { CidVersion: -1, MhType: mh.SHA2_256, - InlineLimit: 0, + InlineLimit: 0, + RawLeaves: false, + RawLeavesSet: false, } for _, opt := range opts { diff --git a/core/coreiface/unixfs.go b/core/coreiface/unixfs.go index 10febd9fa..acc3b960c 100644 --- a/core/coreiface/unixfs.go +++ b/core/coreiface/unixfs.go @@ -10,6 +10,7 @@ import ( ) // UnixfsAPI is the basic interface to immutable files in IPFS +// NOTE: This API is heavily WIP, things are guaranteed to break frequently type UnixfsAPI interface { // Add imports the data from the reader into merkledag file Add(context.Context, io.ReadCloser, ...options.UnixfsAddOption) (ResolvedPath, error) From 9e57389b045a5202e2c91037d9cfaa87df751729 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 20 Sep 2018 16:19:32 +0200 Subject: [PATCH 0105/1212] coreapi unixfs: options for RawLeaves / Inline MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@dbdf6fd63ad66e3b5e5649a349ee9ba9534590a0 This commit was moved from ipfs/boxo@6a3bc40fc4c131b19837c1007ba3e65a51de6ab1 --- core/coreiface/options/unixfs.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/core/coreiface/options/unixfs.go b/core/coreiface/options/unixfs.go index ffed75577..3c46ed086 100644 --- a/core/coreiface/options/unixfs.go +++ b/core/coreiface/options/unixfs.go @@ -52,3 +52,18 @@ func (unixfsOpts) Hash(mhtype uint64) UnixfsAddOption { return nil } } + +func (unixfsOpts) RawLeaves(enable bool) UnixfsAddOption { + return func(settings *UnixfsAddSettings) error { + settings.RawLeaves = enable + settings.RawLeavesSet = true + return nil + } +} + +func (unixfsOpts) InlineLimit(limit int) UnixfsAddOption { + return func(settings *UnixfsAddSettings) error { + settings.InlineLimit = limit + return nil + } +} From 82ef32dcaf3619bc2d372ef0a634e56e159cc4e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 20 Sep 2018 16:40:31 +0200 Subject: [PATCH 0106/1212] coreapi unixfs: layout/chunker options MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@ee22ac438536720b2646e6071ecc6519f4161a0c This commit was moved from ipfs/boxo@f858a5213f527b1ff67c45692c9e481301678398 --- core/coreiface/options/unixfs.go | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/core/coreiface/options/unixfs.go b/core/coreiface/options/unixfs.go index 3c46ed086..fe41af9a8 100644 --- a/core/coreiface/options/unixfs.go +++ b/core/coreiface/options/unixfs.go @@ -4,6 +4,13 @@ import ( mh "gx/ipfs/QmPnFwZ2JXKnXgMw8CdBPxn7FWh6LLdjUjxV1fKHuJnkr8/go-multihash" ) +type Layout int + +const ( + BalancedLayout Layout = iota + TrickleLeyout +) + type UnixfsAddSettings struct { CidVersion int MhType uint64 @@ -11,6 +18,9 @@ type UnixfsAddSettings struct { InlineLimit int RawLeaves bool RawLeavesSet bool + + Chunker string + Layout Layout } type UnixfsAddOption func(*UnixfsAddSettings) error @@ -23,6 +33,9 @@ func UnixfsAddOptions(opts ...UnixfsAddOption) (*UnixfsAddSettings, error) { InlineLimit: 0, RawLeaves: false, RawLeavesSet: false, + + Chunker: "size-262144", + Layout: BalancedLayout, } for _, opt := range opts { @@ -67,3 +80,17 @@ func (unixfsOpts) InlineLimit(limit int) UnixfsAddOption { return nil } } + +func (unixfsOpts) Chunker(chunker string) UnixfsAddOption { + return func(settings *UnixfsAddSettings) error { + settings.Chunker = chunker + return nil + } +} + +func (unixfsOpts) Layout(layout Layout) UnixfsAddOption { + return func(settings *UnixfsAddSettings) error { + settings.Layout = layout + return nil + } +} From ac8ff307329da34110495b69df9c003232f78c81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 20 Sep 2018 23:05:22 +0200 Subject: [PATCH 0107/1212] coreapi unixfs: pin/local/hash-only options MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@8521907e1a8ac009252669ad3e40be2d93438ad3 This commit was moved from ipfs/boxo@27ded0dea2d8b2ee4c115c9cd40c2d1514927162 --- core/coreiface/options/unixfs.go | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/core/coreiface/options/unixfs.go b/core/coreiface/options/unixfs.go index fe41af9a8..6012ce77b 100644 --- a/core/coreiface/options/unixfs.go +++ b/core/coreiface/options/unixfs.go @@ -21,6 +21,10 @@ type UnixfsAddSettings struct { Chunker string Layout Layout + + Pin bool + OnlyHash bool + Local bool } type UnixfsAddOption func(*UnixfsAddSettings) error @@ -36,6 +40,10 @@ func UnixfsAddOptions(opts ...UnixfsAddOption) (*UnixfsAddSettings, error) { Chunker: "size-262144", Layout: BalancedLayout, + + Pin: false, + OnlyHash: false, + Local: false, } for _, opt := range opts { @@ -94,3 +102,24 @@ func (unixfsOpts) Layout(layout Layout) UnixfsAddOption { return nil } } + +func (unixfsOpts) Pin(pin bool) UnixfsAddOption { + return func(settings *UnixfsAddSettings) error { + settings.Pin = pin + return nil + } +} + +func (unixfsOpts) HashOnly(hashOnly bool) UnixfsAddOption { + return func(settings *UnixfsAddSettings) error { + settings.OnlyHash = hashOnly + return nil + } +} + +func (unixfsOpts) Local(local bool) UnixfsAddOption { + return func(settings *UnixfsAddSettings) error { + settings.Local = local + return nil + } +} From 7546c9386701ca6931a8bc0ac3fb202cace91015 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 20 Sep 2018 23:15:07 +0200 Subject: [PATCH 0108/1212] coreapi unixfs: cleanup options MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@e62f26507f22f00426172384461c53c7d14b702f This commit was moved from ipfs/boxo@c3289a5e7d437768d5f1ea158a9e093034097c17 --- core/coreiface/options/unixfs.go | 41 +++++++++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/core/coreiface/options/unixfs.go b/core/coreiface/options/unixfs.go index 6012ce77b..6abfd9622 100644 --- a/core/coreiface/options/unixfs.go +++ b/core/coreiface/options/unixfs.go @@ -1,7 +1,12 @@ package options import ( + "errors" + "fmt" + + cid "gx/ipfs/QmPSQnBKM9g7BaUcZCvswUJVscQ1ipjmwxN5PXCjkp9EQ7/go-cid" mh "gx/ipfs/QmPnFwZ2JXKnXgMw8CdBPxn7FWh6LLdjUjxV1fKHuJnkr8/go-multihash" + dag "gx/ipfs/QmcBoNcAP6qDjgRBew7yjvCqHq7p5jMstE44jPUBWBxzsV/go-merkledag" ) type Layout int @@ -29,7 +34,7 @@ type UnixfsAddSettings struct { type UnixfsAddOption func(*UnixfsAddSettings) error -func UnixfsAddOptions(opts ...UnixfsAddOption) (*UnixfsAddSettings, error) { +func UnixfsAddOptions(opts ...UnixfsAddOption) (*UnixfsAddSettings, cid.Prefix, error) { options := &UnixfsAddSettings{ CidVersion: -1, MhType: mh.SHA2_256, @@ -49,11 +54,41 @@ func UnixfsAddOptions(opts ...UnixfsAddOption) (*UnixfsAddSettings, error) { for _, opt := range opts { err := opt(options) if err != nil { - return nil, err + return nil, cid.Prefix{}, err } } - return options, nil + // (hash != "sha2-256") -> CIDv1 + if options.MhType != mh.SHA2_256 { + switch options.CidVersion { + case 0: + return nil, cid.Prefix{}, errors.New("CIDv0 only supports sha2-256") + case 1, -1: + options.CidVersion = 1 + default: + return nil, cid.Prefix{}, fmt.Errorf("unknown CID version: %d", options.CidVersion) + } + } else { + if options.CidVersion < 0 { + // Default to CIDv0 + options.CidVersion = 0 + } + } + + // cidV1 -> raw blocks (by default) + if options.CidVersion > 0 && !options.RawLeavesSet { + options.RawLeaves = true + } + + prefix, err := dag.PrefixForCidVersion(options.CidVersion) + if err != nil { + return nil, cid.Prefix{}, err + } + + prefix.MhType = options.MhType + prefix.MhLength = -1 + + return options, prefix, nil } type unixfsOpts struct{} From 8cea9f91e4aa09596b657d00b5d07e1d7b9c1151 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 20 Sep 2018 23:44:49 +0200 Subject: [PATCH 0109/1212] coreapi unixfs: docs on options MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@eeb50d8e478fbaff90d4ef5a434834abfff408ad This commit was moved from ipfs/boxo@0039c7d460983de5c06f86459a0fb00b81ed0505 --- core/coreiface/options/unixfs.go | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/core/coreiface/options/unixfs.go b/core/coreiface/options/unixfs.go index 6abfd9622..9b003e1af 100644 --- a/core/coreiface/options/unixfs.go +++ b/core/coreiface/options/unixfs.go @@ -13,7 +13,7 @@ type Layout int const ( BalancedLayout Layout = iota - TrickleLeyout + TrickleLayout ) type UnixfsAddSettings struct { @@ -95,6 +95,8 @@ type unixfsOpts struct{} var Unixfs unixfsOpts +// CidVersion specifies which CID version to use. Defaults to 0 unless an option +// that depends on CIDv1 is passed. func (unixfsOpts) CidVersion(version int) UnixfsAddOption { return func(settings *UnixfsAddSettings) error { settings.CidVersion = version @@ -102,6 +104,9 @@ func (unixfsOpts) CidVersion(version int) UnixfsAddOption { } } +// Hash function to use. Implies CIDv1 if not set to sha2-256 (default). +// +// Table of functions is declared in https://github.com/multiformats/go-multihash/blob/master/multihash.go func (unixfsOpts) Hash(mhtype uint64) UnixfsAddOption { return func(settings *UnixfsAddSettings) error { settings.MhType = mhtype @@ -109,6 +114,8 @@ func (unixfsOpts) Hash(mhtype uint64) UnixfsAddOption { } } +// RawLeaves specifies whether to use raw blocks for leaves (data nodes with no +// links) instead of wrapping them with unixfs structures. func (unixfsOpts) RawLeaves(enable bool) UnixfsAddOption { return func(settings *UnixfsAddSettings) error { settings.RawLeaves = enable @@ -117,6 +124,11 @@ func (unixfsOpts) RawLeaves(enable bool) UnixfsAddOption { } } +// InlineLimit sets the amount of bytes below which blocks will be encoded +// directly into CID instead of being stored and addressed by it's hash +// +// Note that while there is no hard limit on the number of bytes here, it should +// be kept at something reasonably low like 32b (default for 'ipfs add') func (unixfsOpts) InlineLimit(limit int) UnixfsAddOption { return func(settings *UnixfsAddSettings) error { settings.InlineLimit = limit @@ -124,6 +136,11 @@ func (unixfsOpts) InlineLimit(limit int) UnixfsAddOption { } } +// Chunker specifies settings for the chunking algorithm to use. +// +// Default: size-262144, formats: +// size-[bytes] - Simple chunker splitting data into blocks of n bytes +// rabin-[min]-[avg]-[max] - Rabin chunker func (unixfsOpts) Chunker(chunker string) UnixfsAddOption { return func(settings *UnixfsAddSettings) error { settings.Chunker = chunker @@ -131,6 +148,10 @@ func (unixfsOpts) Chunker(chunker string) UnixfsAddOption { } } +// Layout tells the adder how to balance data between leaves. +// options.BalancedLayout is the default, it's optimized for static seekable +// files. +// options.TrickleLayout is optimized for streaming data, func (unixfsOpts) Layout(layout Layout) UnixfsAddOption { return func(settings *UnixfsAddSettings) error { settings.Layout = layout @@ -138,6 +159,7 @@ func (unixfsOpts) Layout(layout Layout) UnixfsAddOption { } } +// Pin tells the adder to pin the file root recursively after adding func (unixfsOpts) Pin(pin bool) UnixfsAddOption { return func(settings *UnixfsAddSettings) error { settings.Pin = pin @@ -145,6 +167,8 @@ func (unixfsOpts) Pin(pin bool) UnixfsAddOption { } } +// HashOnly will make the adder calculate data hash without storing it in the +// blockstore or announcing it to the network func (unixfsOpts) HashOnly(hashOnly bool) UnixfsAddOption { return func(settings *UnixfsAddSettings) error { settings.OnlyHash = hashOnly @@ -152,6 +176,9 @@ func (unixfsOpts) HashOnly(hashOnly bool) UnixfsAddOption { } } +// Local will add the data to blockstore without announcing it to the network +// +// Note that this doesn't prevent other nodes from getting this data func (unixfsOpts) Local(local bool) UnixfsAddOption { return func(settings *UnixfsAddSettings) error { settings.Local = local From 33bb77072255f75e8a5a777069b9425a9f81e315 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 2 Oct 2018 09:42:50 +0200 Subject: [PATCH 0110/1212] coreapi unixfs: separate option to enable inlining MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@88ca0a07599ddd51c3db3864b99c1da87bf87eee This commit was moved from ipfs/boxo@80a937abb79a84f303465f05d86b206e1e90ff75 --- core/coreiface/options/unixfs.go | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/core/coreiface/options/unixfs.go b/core/coreiface/options/unixfs.go index 9b003e1af..df6f4fc71 100644 --- a/core/coreiface/options/unixfs.go +++ b/core/coreiface/options/unixfs.go @@ -20,6 +20,7 @@ type UnixfsAddSettings struct { CidVersion int MhType uint64 + Inline bool InlineLimit int RawLeaves bool RawLeavesSet bool @@ -39,7 +40,8 @@ func UnixfsAddOptions(opts ...UnixfsAddOption) (*UnixfsAddSettings, cid.Prefix, CidVersion: -1, MhType: mh.SHA2_256, - InlineLimit: 0, + Inline: false, + InlineLimit: 32, RawLeaves: false, RawLeavesSet: false, @@ -124,11 +126,26 @@ func (unixfsOpts) RawLeaves(enable bool) UnixfsAddOption { } } +// Inline tells the adder to inline small blocks into CIDs +func (unixfsOpts) Inline(enable bool) UnixfsAddOption { + return func(settings *UnixfsAddSettings) error { + settings.Inline = enable + return nil + } +} + // InlineLimit sets the amount of bytes below which blocks will be encoded -// directly into CID instead of being stored and addressed by it's hash +// directly into CID instead of being stored and addressed by it's hash. +// Specifying this option won't enable block inlining. For that use `Inline` +// option. Default: 32 bytes // -// Note that while there is no hard limit on the number of bytes here, it should -// be kept at something reasonably low like 32b (default for 'ipfs add') +// Note that while there is no hard limit on the number of bytes, it should +// be kept at a reasonably low value, like 64 bytes if you intend to display +// these hashes. Larger values like 256 bytes will work fine, but may affect +// de-duplication of smaller blocks. +// +// Setting this value too high may cause various problems, such as render some +// blocks unfetchable func (unixfsOpts) InlineLimit(limit int) UnixfsAddOption { return func(settings *UnixfsAddSettings) error { settings.InlineLimit = limit From d3bbffb3878a9fff3317ec4d439cb636dac9a153 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 3 Oct 2018 15:05:46 +0200 Subject: [PATCH 0111/1212] coreapi unixfs: multi file support in unixfs coreapi MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@9a760d89b5db34fa0fb7be8c71876e2f18dd8fa2 This commit was moved from ipfs/boxo@e50aac4cc71c5272b5a53994e958198286a585bc --- core/coreiface/unixfs.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/coreiface/unixfs.go b/core/coreiface/unixfs.go index acc3b960c..92168503e 100644 --- a/core/coreiface/unixfs.go +++ b/core/coreiface/unixfs.go @@ -2,10 +2,10 @@ package iface import ( "context" - "io" options "github.com/ipfs/go-ipfs/core/coreapi/interface/options" + files "gx/ipfs/QmSP88ryZkHSRn1fnngAaV2Vcn63WUJzAavnRM9CVdU1Ky/go-ipfs-cmdkit/files" ipld "gx/ipfs/QmdDXJs4axxefSPgK6Y1QhpJWKuDPnGJiqgq4uncb4rFHL/go-ipld-format" ) @@ -13,7 +13,7 @@ import ( // NOTE: This API is heavily WIP, things are guaranteed to break frequently type UnixfsAPI interface { // Add imports the data from the reader into merkledag file - Add(context.Context, io.ReadCloser, ...options.UnixfsAddOption) (ResolvedPath, error) + Add(context.Context, files.File, ...options.UnixfsAddOption) (ResolvedPath, error) // Cat returns a reader for the file Cat(context.Context, Path) (Reader, error) From a7b89529611d0071f0be88d45c64aac557f95668 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 3 Oct 2018 17:21:07 +0200 Subject: [PATCH 0112/1212] coreapi unixfs: unixfs.Get MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@7b2fdc90ee0528d4c0a437d95b1cb0d10c3e8aa5 This commit was moved from ipfs/boxo@15a4331a185c812bab3e229758bcfc79d682ac5d --- core/coreiface/unixfs.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/core/coreiface/unixfs.go b/core/coreiface/unixfs.go index 92168503e..69e731822 100644 --- a/core/coreiface/unixfs.go +++ b/core/coreiface/unixfs.go @@ -13,8 +13,16 @@ import ( // NOTE: This API is heavily WIP, things are guaranteed to break frequently type UnixfsAPI interface { // Add imports the data from the reader into merkledag file + // + // TODO: a long useful comment on how to use this for many different scenarios Add(context.Context, files.File, ...options.UnixfsAddOption) (ResolvedPath, error) + // Get returns a read-only handle to a file tree referenced by a path + // + // Note that some implementations of this API may apply the specified context + // to operations performed on the returned file + Get(context.Context, Path) (files.File, error) + // Cat returns a reader for the file Cat(context.Context, Path) (Reader, error) From ee45dafe78299ac3356a3a49b4ff63cac4c3530d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 3 Oct 2018 22:30:45 +0200 Subject: [PATCH 0113/1212] coreapi unixfs: wrap option MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@b977abfc696b22775fa68736c144760113b27af4 This commit was moved from ipfs/boxo@59fd418b398d9011c79167b82af869751acf2640 --- core/coreiface/options/unixfs.go | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/core/coreiface/options/unixfs.go b/core/coreiface/options/unixfs.go index df6f4fc71..abbea9681 100644 --- a/core/coreiface/options/unixfs.go +++ b/core/coreiface/options/unixfs.go @@ -31,6 +31,8 @@ type UnixfsAddSettings struct { Pin bool OnlyHash bool Local bool + + Wrap bool } type UnixfsAddOption func(*UnixfsAddSettings) error @@ -51,6 +53,8 @@ func UnixfsAddOptions(opts ...UnixfsAddOption) (*UnixfsAddSettings, cid.Prefix, Pin: false, OnlyHash: false, Local: false, + + Wrap: false, } for _, opt := range opts { @@ -202,3 +206,12 @@ func (unixfsOpts) Local(local bool) UnixfsAddOption { return nil } } + +// Wrap tells the adder to wrap the added file structure with an additional +// directory. +func (unixfsOpts) Wrap(wrap bool) UnixfsAddOption { + return func(settings *UnixfsAddSettings) error { + settings.Wrap = wrap + return nil + } +} From f10ca5c904954029737728199d48ba9346e614e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 3 Oct 2018 22:49:42 +0200 Subject: [PATCH 0114/1212] coreapi unixfs: hidden opiton MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@cb84af4b44e4660029e87a1c82a3d2ab35acb2cd This commit was moved from ipfs/boxo@1019fcea4b88f3a45cf81429f81066db1918771f --- core/coreiface/options/unixfs.go | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/core/coreiface/options/unixfs.go b/core/coreiface/options/unixfs.go index abbea9681..7d7af5b81 100644 --- a/core/coreiface/options/unixfs.go +++ b/core/coreiface/options/unixfs.go @@ -32,7 +32,8 @@ type UnixfsAddSettings struct { OnlyHash bool Local bool - Wrap bool + Wrap bool + Hidden bool } type UnixfsAddOption func(*UnixfsAddSettings) error @@ -54,7 +55,8 @@ func UnixfsAddOptions(opts ...UnixfsAddOption) (*UnixfsAddSettings, cid.Prefix, OnlyHash: false, Local: false, - Wrap: false, + Wrap: false, + Hidden: false, } for _, opt := range opts { @@ -215,3 +217,11 @@ func (unixfsOpts) Wrap(wrap bool) UnixfsAddOption { return nil } } + +// Hidden enables adding of hidden files (files prefixed with '.') +func (unixfsOpts) Hidden(hidden bool) UnixfsAddOption { + return func(settings *UnixfsAddSettings) error { + settings.Hidden = hidden + return nil + } +} From 48761861ca82c2744d0c33d7bd41ef8f94abdb8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 3 Oct 2018 23:17:18 +0200 Subject: [PATCH 0115/1212] coreapi unixfs: stdin-name option MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@aa7a877686c76f0767fa6fb618972b25f1545bb6 This commit was moved from ipfs/boxo@907d2f239738971d246b9ff9ce5add004adad2c7 --- core/coreiface/options/unixfs.go | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/core/coreiface/options/unixfs.go b/core/coreiface/options/unixfs.go index 7d7af5b81..90ad53e9e 100644 --- a/core/coreiface/options/unixfs.go +++ b/core/coreiface/options/unixfs.go @@ -32,8 +32,9 @@ type UnixfsAddSettings struct { OnlyHash bool Local bool - Wrap bool - Hidden bool + Wrap bool + Hidden bool + StdinName string } type UnixfsAddOption func(*UnixfsAddSettings) error @@ -55,8 +56,9 @@ func UnixfsAddOptions(opts ...UnixfsAddOption) (*UnixfsAddSettings, cid.Prefix, OnlyHash: false, Local: false, - Wrap: false, - Hidden: false, + Wrap: false, + Hidden: false, + StdinName: "", } for _, opt := range opts { @@ -225,3 +227,12 @@ func (unixfsOpts) Hidden(hidden bool) UnixfsAddOption { return nil } } + +// StdinName is the name set for files which don specify FilePath as +// os.Stdin.Name() +func (unixfsOpts) StdinName(name string) UnixfsAddOption { + return func(settings *UnixfsAddSettings) error { + settings.StdinName = name + return nil + } +} From be5cccd21ac577b26638e777d189a9f27df79058 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 4 Oct 2018 01:00:26 +0200 Subject: [PATCH 0116/1212] coreapi unixfs: progress events MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@df1797113e1dc062a9e53af11b8ea4268c855ef9 This commit was moved from ipfs/boxo@56ef5340a321a06604f4f98efcba4da03b6a4358 --- core/coreiface/options/unixfs.go | 35 ++++++++++++++++++++++++++++++++ core/coreiface/unixfs.go | 9 ++++++++ 2 files changed, 44 insertions(+) diff --git a/core/coreiface/options/unixfs.go b/core/coreiface/options/unixfs.go index 90ad53e9e..da99b42f6 100644 --- a/core/coreiface/options/unixfs.go +++ b/core/coreiface/options/unixfs.go @@ -35,6 +35,10 @@ type UnixfsAddSettings struct { Wrap bool Hidden bool StdinName string + + Events chan<- interface{} + Silent bool + Progress bool } type UnixfsAddOption func(*UnixfsAddSettings) error @@ -59,6 +63,10 @@ func UnixfsAddOptions(opts ...UnixfsAddOption) (*UnixfsAddSettings, cid.Prefix, Wrap: false, Hidden: false, StdinName: "", + + Events: nil, + Silent: false, + Progress: false, } for _, opt := range opts { @@ -236,3 +244,30 @@ func (unixfsOpts) StdinName(name string) UnixfsAddOption { return nil } } + +// Events specifies channel which will be used to report events about ongoing +// Add operation. +// +// Note that if this channel blocks it may slowdown the adder +func (unixfsOpts) Events(sink chan<- interface{}) UnixfsAddOption { + return func(settings *UnixfsAddSettings) error { + settings.Events = sink + return nil + } +} + +// Silent reduces event output +func (unixfsOpts) Silent(silent bool) UnixfsAddOption { + return func(settings *UnixfsAddSettings) error { + settings.Silent = silent + return nil + } +} + +// Progress tells the adder whether to enable progress events +func (unixfsOpts) Progress(enable bool) UnixfsAddOption { + return func(settings *UnixfsAddSettings) error { + settings.Progress = enable + return nil + } +} diff --git a/core/coreiface/unixfs.go b/core/coreiface/unixfs.go index 69e731822..c622e210e 100644 --- a/core/coreiface/unixfs.go +++ b/core/coreiface/unixfs.go @@ -9,6 +9,14 @@ import ( ipld "gx/ipfs/QmdDXJs4axxefSPgK6Y1QhpJWKuDPnGJiqgq4uncb4rFHL/go-ipld-format" ) +// TODO: ideas on making this more coreapi-ish without breaking the http API? +type AddEvent struct { + Name string + Hash string `json:",omitempty"` + Bytes int64 `json:",omitempty"` + Size string `json:",omitempty"` +} + // UnixfsAPI is the basic interface to immutable files in IPFS // NOTE: This API is heavily WIP, things are guaranteed to break frequently type UnixfsAPI interface { @@ -24,6 +32,7 @@ type UnixfsAPI interface { Get(context.Context, Path) (files.File, error) // Cat returns a reader for the file + // TODO: Remove in favour of Get (if we use Get on a file we still have reader directly, so..) Cat(context.Context, Path) (Reader, error) // Ls returns the list of links in a directory From dfb14f3974d44b6dd1670233c57d24552b9fbd83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 4 Oct 2018 01:24:57 +0200 Subject: [PATCH 0117/1212] coreapi unixfs: filestore opts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@97fb3e4d819ee3ee511a719da6d1bef4695a2dad This commit was moved from ipfs/boxo@90e8604702cde52200882080a6a8b5b3e0818d13 --- core/coreiface/options/unixfs.go | 35 ++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/core/coreiface/options/unixfs.go b/core/coreiface/options/unixfs.go index da99b42f6..810e3c6e8 100644 --- a/core/coreiface/options/unixfs.go +++ b/core/coreiface/options/unixfs.go @@ -31,6 +31,8 @@ type UnixfsAddSettings struct { Pin bool OnlyHash bool Local bool + FsCache bool + NoCopy bool Wrap bool Hidden bool @@ -59,6 +61,8 @@ func UnixfsAddOptions(opts ...UnixfsAddOption) (*UnixfsAddSettings, cid.Prefix, Pin: false, OnlyHash: false, Local: false, + FsCache: false, + NoCopy: false, Wrap: false, Hidden: false, @@ -76,6 +80,17 @@ func UnixfsAddOptions(opts ...UnixfsAddOption) (*UnixfsAddSettings, cid.Prefix, } } + // nocopy -> rawblocks + if options.NoCopy && !options.RawLeaves { + // fixed? + if options.RawLeavesSet { + return nil, cid.Prefix{}, fmt.Errorf("nocopy option requires '--raw-leaves' to be enabled as well") + } + + // No, satisfy mandatory constraint. + options.RawLeaves = true + } + // (hash != "sha2-256") -> CIDv1 if options.MhType != mh.SHA2_256 { switch options.CidVersion { @@ -271,3 +286,23 @@ func (unixfsOpts) Progress(enable bool) UnixfsAddOption { return nil } } + +// FsCache tells the adder to check the filestore for pre-existing blocks +// +// Experimental +func (unixfsOpts) FsCache(enable bool) UnixfsAddOption { + return func(settings *UnixfsAddSettings) error { + settings.FsCache = enable + return nil + } +} + +// NoCopy tells the adder to add the files using filestore. Implies RawLeaves. +// +// Experimental +func (unixfsOpts) Nocopy(enable bool) UnixfsAddOption { + return func(settings *UnixfsAddSettings) error { + settings.NoCopy = enable + return nil + } +} From e59b75ae4394525d2902dfb8bffc89214ef5e759 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 4 Oct 2018 20:39:43 +0200 Subject: [PATCH 0118/1212] coreapi unixfs: fix inline doc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@641542e1596817f70eeac14f87b3c49ef2d5e80a This commit was moved from ipfs/boxo@f46082072957d0f4634a70baec4f0ef573c89408 --- core/coreiface/options/unixfs.go | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/core/coreiface/options/unixfs.go b/core/coreiface/options/unixfs.go index 810e3c6e8..9249af895 100644 --- a/core/coreiface/options/unixfs.go +++ b/core/coreiface/options/unixfs.go @@ -170,13 +170,10 @@ func (unixfsOpts) Inline(enable bool) UnixfsAddOption { // Specifying this option won't enable block inlining. For that use `Inline` // option. Default: 32 bytes // -// Note that while there is no hard limit on the number of bytes, it should -// be kept at a reasonably low value, like 64 bytes if you intend to display -// these hashes. Larger values like 256 bytes will work fine, but may affect -// de-duplication of smaller blocks. -// -// Setting this value too high may cause various problems, such as render some -// blocks unfetchable +// Note that while there is no hard limit on the number of bytes, it should be +// kept at a reasonably low value, such as 64 and no more than 1k. Setting this +// value too high may cause various problems, such as render some +// blocks unfetchable. func (unixfsOpts) InlineLimit(limit int) UnixfsAddOption { return func(settings *UnixfsAddSettings) error { settings.InlineLimit = limit From 4c5803a3f45eb4c1ae769b0ffe0b4fc2f4300404 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 4 Oct 2018 22:11:17 +0200 Subject: [PATCH 0119/1212] coreapi name: add some missing options MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@0ad4722d65f9b8a3021320835291d2161091fd63 This commit was moved from ipfs/boxo@34497dfcf9b4083f51925ee9e7b9ccd14c8f69ce --- core/coreiface/options/name.go | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/core/coreiface/options/name.go b/core/coreiface/options/name.go index ba3691b03..c614db3ab 100644 --- a/core/coreiface/options/name.go +++ b/core/coreiface/options/name.go @@ -13,6 +13,10 @@ const ( type NamePublishSettings struct { ValidTime time.Duration Key string + + TTL *time.Duration + + AllowOffline bool } type NameResolveSettings struct { @@ -29,6 +33,8 @@ func NamePublishOptions(opts ...NamePublishOption) (*NamePublishSettings, error) options := &NamePublishSettings{ ValidTime: DefaultNameValidTime, Key: "self", + + AllowOffline: false, } for _, opt := range opts { @@ -82,6 +88,24 @@ func (nameOpts) Key(key string) NamePublishOption { } } +// AllowOffline is an option for Name.Publish which specifies whether to allow +// publishing when the node is offline. Default value is false +func (nameOpts) AllowOffline(allow bool) NamePublishOption { + return func(settings *NamePublishSettings) error { + settings.AllowOffline = allow + return nil + } +} + +// TTL is an option for Name.Publish which specifies the time duration the +// published record should be cached for (caution: experimental). +func (nameOpts) TTL(ttl time.Duration) NamePublishOption { + return func(settings *NamePublishSettings) error { + settings.TTL = &ttl + return nil + } +} + // Local is an option for Name.Resolve which specifies if the lookup should be // offline. Default value is false func (nameOpts) Local(local bool) NameResolveOption { From db11d51180922f44d45cf15f274e7617d17cec12 Mon Sep 17 00:00:00 2001 From: Lars Gierth Date: Wed, 3 Oct 2018 07:35:57 +0200 Subject: [PATCH 0120/1212] gx: update go-datastore, go-libp2p-swarm License: MIT Signed-off-by: Lars Gierth This commit was moved from ipfs/interface-go-ipfs-core@b9309ab1a51ec1b68e8c5561b0f02a610fd93f97 This commit was moved from ipfs/boxo@b00a9c91219246fb5cb954b1a50578eeb009dcae --- core/coreiface/dht.go | 2 +- core/coreiface/path.go | 2 +- core/coreiface/swarm.go | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/core/coreiface/dht.go b/core/coreiface/dht.go index 2309ceb90..4a76f4d39 100644 --- a/core/coreiface/dht.go +++ b/core/coreiface/dht.go @@ -5,8 +5,8 @@ import ( "github.com/ipfs/go-ipfs/core/coreapi/interface/options" + pstore "gx/ipfs/QmSJ36wcYQyEViJUWUEhJU81tw1KdakTKqLLHbvYbA9zDv/go-libp2p-peerstore" peer "gx/ipfs/QmbNepETomvmXfz1X5pHNFD2QuPqnqi47dTd94QJWSorQ3/go-libp2p-peer" - pstore "gx/ipfs/QmfAQMFpgDU2U4BXG64qVr8HSiictfWvkSBz7Y2oDj65st/go-libp2p-peerstore" ) // DhtAPI specifies the interface to the DHT diff --git a/core/coreiface/path.go b/core/coreiface/path.go index 0beab0663..0f06e8cc2 100644 --- a/core/coreiface/path.go +++ b/core/coreiface/path.go @@ -1,7 +1,7 @@ package iface import ( - ipfspath "gx/ipfs/QmcjwUb36Z16NJkvDX6ccXPqsFswo6AsRXynyXcLLCphV2/go-path" + ipfspath "gx/ipfs/QmbE9gr6c2FomTgc2pRZRTooHpchJ1uaZKremypyWJMV4t/go-path" cid "gx/ipfs/QmPSQnBKM9g7BaUcZCvswUJVscQ1ipjmwxN5PXCjkp9EQ7/go-cid" ) diff --git a/core/coreiface/swarm.go b/core/coreiface/swarm.go index 8b464e5c1..58caf6759 100644 --- a/core/coreiface/swarm.go +++ b/core/coreiface/swarm.go @@ -5,11 +5,11 @@ import ( "errors" "time" + net "gx/ipfs/QmQdLcvoy3JuSqhV6iwQ9T6Cv7hWLAdzob4jUZRPqFL67Z/go-libp2p-net" + pstore "gx/ipfs/QmSJ36wcYQyEViJUWUEhJU81tw1KdakTKqLLHbvYbA9zDv/go-libp2p-peerstore" ma "gx/ipfs/QmYmsdtJ3HsodkePE3eU3TsCaP2YvPZJ4LoXnNkDE5Tpt7/go-multiaddr" "gx/ipfs/QmZNkThpqfVXs9GNbexPrfBbXSLNYeKrE7jwFM2oqHbyqN/go-libp2p-protocol" "gx/ipfs/QmbNepETomvmXfz1X5pHNFD2QuPqnqi47dTd94QJWSorQ3/go-libp2p-peer" - pstore "gx/ipfs/QmfAQMFpgDU2U4BXG64qVr8HSiictfWvkSBz7Y2oDj65st/go-libp2p-peerstore" - net "gx/ipfs/QmfDPh144WGBqRxZb1TGDHerbMnZATrHZggAPw7putNnBq/go-libp2p-net" ) var ( From cd6d30548a305d5a32118c7dae7286c521fbbfa0 Mon Sep 17 00:00:00 2001 From: Kevin Atkinson Date: Thu, 4 Oct 2018 19:11:27 -0400 Subject: [PATCH 0121/1212] gx update go-libp2p-peerstore License: MIT Signed-off-by: Kevin Atkinson This commit was moved from ipfs/interface-go-ipfs-core@c8a6219cf25b4dfc1208523ec0bb2ee2efc2d85d This commit was moved from ipfs/boxo@0ef081eae1b8bdaf52870fe9f483ba05c7ca69ef --- core/coreiface/path.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/coreiface/path.go b/core/coreiface/path.go index 0f06e8cc2..5748bf465 100644 --- a/core/coreiface/path.go +++ b/core/coreiface/path.go @@ -1,7 +1,7 @@ package iface import ( - ipfspath "gx/ipfs/QmbE9gr6c2FomTgc2pRZRTooHpchJ1uaZKremypyWJMV4t/go-path" + ipfspath "gx/ipfs/QmYh33CFYYEgQNSZ9PEP7ZN57dhErRZ7NfLS1BUA9GBBRk/go-path" cid "gx/ipfs/QmPSQnBKM9g7BaUcZCvswUJVscQ1ipjmwxN5PXCjkp9EQ7/go-cid" ) From 59de96e6341ed97ed94bcebe098df14182fd289e Mon Sep 17 00:00:00 2001 From: Kevin Atkinson Date: Thu, 4 Oct 2018 19:32:33 -0400 Subject: [PATCH 0122/1212] gx update libp2p/go-buffer-pool License: MIT Signed-off-by: Kevin Atkinson This commit was moved from ipfs/interface-go-ipfs-core@349cbd1463198c9a811b6cc3c09c44608cdd486d This commit was moved from ipfs/boxo@3f8596df8b398139db13cb06f2c55c6738fc6528 --- core/coreiface/path.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/coreiface/path.go b/core/coreiface/path.go index 5748bf465..63b15fb50 100644 --- a/core/coreiface/path.go +++ b/core/coreiface/path.go @@ -1,7 +1,7 @@ package iface import ( - ipfspath "gx/ipfs/QmYh33CFYYEgQNSZ9PEP7ZN57dhErRZ7NfLS1BUA9GBBRk/go-path" + ipfspath "gx/ipfs/QmV4QxScV9Y7LbaWhHazFfRd8uyeUd4pAH8a7fFFbi5odJ/go-path" cid "gx/ipfs/QmPSQnBKM9g7BaUcZCvswUJVscQ1ipjmwxN5PXCjkp9EQ7/go-cid" ) From 1aa388cb87a449376a0d003ca44fbdced70af394 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Thu, 4 Oct 2018 21:12:53 -0700 Subject: [PATCH 0123/1212] update unixfs inline option comment to give us room to change things (addressing CR) License: MIT Signed-off-by: Steven Allen This commit was moved from ipfs/interface-go-ipfs-core@7d577641499b51b4d98ae7e10fed2fd5bf9d516a This commit was moved from ipfs/boxo@b06611e7da0ebaef24e0b3db614716c940882793 --- core/coreiface/options/unixfs.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/core/coreiface/options/unixfs.go b/core/coreiface/options/unixfs.go index 9249af895..d486981c3 100644 --- a/core/coreiface/options/unixfs.go +++ b/core/coreiface/options/unixfs.go @@ -171,9 +171,8 @@ func (unixfsOpts) Inline(enable bool) UnixfsAddOption { // option. Default: 32 bytes // // Note that while there is no hard limit on the number of bytes, it should be -// kept at a reasonably low value, such as 64 and no more than 1k. Setting this -// value too high may cause various problems, such as render some -// blocks unfetchable. +// kept at a reasonably low value, such as 64; implementations may choose to +// reject anything larger. func (unixfsOpts) InlineLimit(limit int) UnixfsAddOption { return func(settings *UnixfsAddSettings) error { settings.InlineLimit = limit From f9a93470069c116015b79f33f105275896f9917a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Sat, 10 Mar 2018 19:23:38 +0100 Subject: [PATCH 0124/1212] coreapi: pubsub interface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@ccaec46f3deaf46e20f9c265d5920f68251e4da4 This commit was moved from ipfs/boxo@f06c01e06b04ec7a27b0738f984e0f30b005c711 --- core/coreiface/options/pubsub.go | 56 ++++++++++++++++++++++++++++++++ core/coreiface/pubsub.go | 51 +++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+) create mode 100644 core/coreiface/options/pubsub.go create mode 100644 core/coreiface/pubsub.go diff --git a/core/coreiface/options/pubsub.go b/core/coreiface/options/pubsub.go new file mode 100644 index 000000000..e276d7e4a --- /dev/null +++ b/core/coreiface/options/pubsub.go @@ -0,0 +1,56 @@ +package options + +type PubSubPeersSettings struct { + Topic string +} + +type PubSubSubscribeSettings struct { + Discover bool +} + +type PubSubPeersOption func(*PubSubPeersSettings) error +type PubSubSubscribeOption func(*PubSubSubscribeSettings) error + +func PubSubPeersOptions(opts ...PubSubPeersOption) (*PubSubPeersSettings, error) { + options := &PubSubPeersSettings{ + Topic: "", + } + + for _, opt := range opts { + err := opt(options) + if err != nil { + return nil, err + } + } + return options, nil +} + +func PubSubSubscribeOptions(opts ...PubSubSubscribeOption) (*PubSubSubscribeSettings, error) { + options := &PubSubSubscribeSettings{ + Discover: false, + } + + for _, opt := range opts { + err := opt(options) + if err != nil { + return nil, err + } + } + return options, nil +} + +type PubSubOptions struct{} + +func (api *PubSubOptions) WithTopic(topic string) PubSubPeersOption { + return func(settings *PubSubPeersSettings) error { + settings.Topic = topic + return nil + } +} + +func (api *PubSubOptions) WithDiscover(discover bool) PubSubSubscribeOption { + return func(settings *PubSubSubscribeSettings) error { + settings.Discover = discover + return nil + } +} diff --git a/core/coreiface/pubsub.go b/core/coreiface/pubsub.go new file mode 100644 index 000000000..f78734a09 --- /dev/null +++ b/core/coreiface/pubsub.go @@ -0,0 +1,51 @@ +package iface + +import ( + "context" + "io" + + options "github.com/ipfs/go-ipfs/core/coreapi/interface/options" + + peer "gx/ipfs/QmZoWKhxUmZ2seW4BzX6fJkNR8hh9PsGModr7q171yq2SS/go-libp2p-peer" +) + +// PubSubSubscription is an active PubSub subscription +type PubSubSubscription interface { + io.Closer + + // Chan return incoming message channel + Chan(context.Context) <-chan PubSubMessage +} + +// PubSubMessage is a single PubSub message +type PubSubMessage interface { + // From returns id of a peer from which the message has arrived + From() peer.ID + + // Data returns the message body + Data() []byte +} + +// PubSubAPI specifies the interface to PubSub +type PubSubAPI interface { + // Ls lists subscribed topics by name + Ls(context.Context) ([]string, error) + + // Peers list peers we are currently pubsubbing with + // TODO: WithTopic + Peers(context.Context, ...options.PubSubPeersOption) ([]peer.ID, error) + + // WithTopic is an option for peers which specifies a topic filter for the + // function + WithTopic(topic string) options.PubSubPeersOption + + // Publish a message to a given pubsub topic + Publish(context.Context, string, []byte) error + + // Subscribe to messages on a given topic + Subscribe(context.Context, string) (PubSubSubscription, error) + + // WithDiscover is an option for Subscribe which specifies whether to try to + // discover other peers subscribed to the same topic + WithDiscover(discover bool) options.PubSubSubscribeOption +} From 729bb03d1b244e9ec7e27a28fa347ec79c15ae0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Sat, 10 Mar 2018 19:28:22 +0100 Subject: [PATCH 0125/1212] coreapi: implement pubsub api MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@0d0069ff23a4dd26fa62fd91e5875b2526742da5 This commit was moved from ipfs/boxo@1b8732304c12b825e9a8fd69b51494c9c67f39d0 --- core/coreiface/coreapi.go | 3 +++ core/coreiface/errors.go | 2 +- core/coreiface/options/pubsub.go | 8 +++++--- core/coreiface/pubsub.go | 16 ++++------------ 4 files changed, 13 insertions(+), 16 deletions(-) diff --git a/core/coreiface/coreapi.go b/core/coreiface/coreapi.go index 0b153b6f9..bc889237b 100644 --- a/core/coreiface/coreapi.go +++ b/core/coreiface/coreapi.go @@ -37,6 +37,9 @@ type CoreAPI interface { // Swarm returns an implementation of Swarm API Swarm() SwarmAPI + // PubSub returns an implementation of PubSub API + PubSub() PubSubAPI + // ResolvePath resolves the path using Unixfs resolver ResolvePath(context.Context, Path) (ResolvedPath, error) diff --git a/core/coreiface/errors.go b/core/coreiface/errors.go index 81f978971..072275409 100644 --- a/core/coreiface/errors.go +++ b/core/coreiface/errors.go @@ -4,5 +4,5 @@ import "errors" var ( ErrIsDir = errors.New("object is a directory") - ErrOffline = errors.New("can't resolve, ipfs node is offline") + ErrOffline = errors.New("this action must be run in online mode, try running 'ipfs daemon' first") ) diff --git a/core/coreiface/options/pubsub.go b/core/coreiface/options/pubsub.go index e276d7e4a..f0a614d58 100644 --- a/core/coreiface/options/pubsub.go +++ b/core/coreiface/options/pubsub.go @@ -39,16 +39,18 @@ func PubSubSubscribeOptions(opts ...PubSubSubscribeOption) (*PubSubSubscribeSett return options, nil } -type PubSubOptions struct{} +type pubsubOpts struct{} -func (api *PubSubOptions) WithTopic(topic string) PubSubPeersOption { +var PubBub nameOpts + +func (pubsubOpts) Topic(topic string) PubSubPeersOption { return func(settings *PubSubPeersSettings) error { settings.Topic = topic return nil } } -func (api *PubSubOptions) WithDiscover(discover bool) PubSubSubscribeOption { +func (pubsubOpts) Discover(discover bool) PubSubSubscribeOption { return func(settings *PubSubSubscribeSettings) error { settings.Discover = discover return nil diff --git a/core/coreiface/pubsub.go b/core/coreiface/pubsub.go index f78734a09..4b52ed6d6 100644 --- a/core/coreiface/pubsub.go +++ b/core/coreiface/pubsub.go @@ -6,15 +6,15 @@ import ( options "github.com/ipfs/go-ipfs/core/coreapi/interface/options" - peer "gx/ipfs/QmZoWKhxUmZ2seW4BzX6fJkNR8hh9PsGModr7q171yq2SS/go-libp2p-peer" + peer "gx/ipfs/QmQsErDt8Qgw1XrsXf2BpEzDgGWtB1YLsTAARBup5b6B9W/go-libp2p-peer" ) // PubSubSubscription is an active PubSub subscription type PubSubSubscription interface { io.Closer - // Chan return incoming message channel - Chan(context.Context) <-chan PubSubMessage + // Next return the next incoming message + Next(context.Context) (PubSubMessage, error) } // PubSubMessage is a single PubSub message @@ -35,17 +35,9 @@ type PubSubAPI interface { // TODO: WithTopic Peers(context.Context, ...options.PubSubPeersOption) ([]peer.ID, error) - // WithTopic is an option for peers which specifies a topic filter for the - // function - WithTopic(topic string) options.PubSubPeersOption - // Publish a message to a given pubsub topic Publish(context.Context, string, []byte) error // Subscribe to messages on a given topic - Subscribe(context.Context, string) (PubSubSubscription, error) - - // WithDiscover is an option for Subscribe which specifies whether to try to - // discover other peers subscribed to the same topic - WithDiscover(discover bool) options.PubSubSubscribeOption + Subscribe(context.Context, string, ...options.PubSubSubscribeOption) (PubSubSubscription, error) } From 3f6b34dd1a4845caa7c781d07328d58e9beabbe4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 11 Sep 2018 05:43:54 +0200 Subject: [PATCH 0126/1212] coreapi pubsub: add tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@3f9a6ce3446d2d5746c6d9976c9325f1673c8e99 This commit was moved from ipfs/boxo@d23f749f57daa3b22c91036530b9430bfebec610 --- core/coreiface/options/pubsub.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/coreiface/options/pubsub.go b/core/coreiface/options/pubsub.go index f0a614d58..c387d613d 100644 --- a/core/coreiface/options/pubsub.go +++ b/core/coreiface/options/pubsub.go @@ -41,7 +41,7 @@ func PubSubSubscribeOptions(opts ...PubSubSubscribeOption) (*PubSubSubscribeSett type pubsubOpts struct{} -var PubBub nameOpts +var PubSub pubsubOpts func (pubsubOpts) Topic(topic string) PubSubPeersOption { return func(settings *PubSubPeersSettings) error { From d5d6e5c13bd0db3b26c5c06a050eda92dc6c1437 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 11 Sep 2018 12:52:40 +0200 Subject: [PATCH 0127/1212] pubsub cmd: switch to coreapi MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@706e552037bd75687b5ff0cedb9802bc7f2d4617 This commit was moved from ipfs/boxo@add2ae0705df01044239e9ed5691974847332408 --- core/coreiface/pubsub.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/core/coreiface/pubsub.go b/core/coreiface/pubsub.go index 4b52ed6d6..4c9a1d73e 100644 --- a/core/coreiface/pubsub.go +++ b/core/coreiface/pubsub.go @@ -6,7 +6,7 @@ import ( options "github.com/ipfs/go-ipfs/core/coreapi/interface/options" - peer "gx/ipfs/QmQsErDt8Qgw1XrsXf2BpEzDgGWtB1YLsTAARBup5b6B9W/go-libp2p-peer" + peer "gx/ipfs/QmbNepETomvmXfz1X5pHNFD2QuPqnqi47dTd94QJWSorQ3/go-libp2p-peer" ) // PubSubSubscription is an active PubSub subscription @@ -24,6 +24,12 @@ type PubSubMessage interface { // Data returns the message body Data() []byte + + // Seq returns message identifier + Seq() []byte + + // Topics returns list of topics this message was set to + Topics() []string } // PubSubAPI specifies the interface to PubSub From 57fdb89f375e9a589d52e765d658b385ac28508b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 26 Sep 2018 18:24:35 +0200 Subject: [PATCH 0128/1212] coreapi pubsub: fix review nits MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@162e182a2c2f67c227b7dd4b3d661d3b15ca1d7b This commit was moved from ipfs/boxo@0373c3c9aee429624a99c6a1c080027923ec6e6f --- core/coreiface/pubsub.go | 1 - 1 file changed, 1 deletion(-) diff --git a/core/coreiface/pubsub.go b/core/coreiface/pubsub.go index 4c9a1d73e..d7a21e02f 100644 --- a/core/coreiface/pubsub.go +++ b/core/coreiface/pubsub.go @@ -38,7 +38,6 @@ type PubSubAPI interface { Ls(context.Context) ([]string, error) // Peers list peers we are currently pubsubbing with - // TODO: WithTopic Peers(context.Context, ...options.PubSubPeersOption) ([]peer.ID, error) // Publish a message to a given pubsub topic From fae14756dcdbd3b313f0dd3e861db5cbb676bdab Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Fri, 5 Oct 2018 14:11:56 -0700 Subject: [PATCH 0129/1212] gx: update stuff * go-datastore and friends: GetSize * badger: new release, fewer allocations * go-mplex: send fewer packets * go-bitswap: pack multiple blocks in a single message, fewer allocations * go-buffer-pool: replace the buffer pool from go-msgio * yamux: fixed data race and uses go-buffer-pool for stream read-buffers to reduce memory and allocations. * go-libp2p-secio: get rid of a hot-spot allocation * go-libp2p-peerstore: reduced allocations (at the cost of some memory) More? License: MIT Signed-off-by: Steven Allen This commit was moved from ipfs/interface-go-ipfs-core@144aa5240ff7e379b34dd0e1adf9f8c1e991b3cc This commit was moved from ipfs/boxo@b77e7021ee4b2093d2e2a98f5274ace254a537e1 --- core/coreiface/dht.go | 2 +- core/coreiface/options/unixfs.go | 2 +- core/coreiface/path.go | 2 +- core/coreiface/swarm.go | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/core/coreiface/dht.go b/core/coreiface/dht.go index 4a76f4d39..3096c8fb7 100644 --- a/core/coreiface/dht.go +++ b/core/coreiface/dht.go @@ -5,7 +5,7 @@ import ( "github.com/ipfs/go-ipfs/core/coreapi/interface/options" - pstore "gx/ipfs/QmSJ36wcYQyEViJUWUEhJU81tw1KdakTKqLLHbvYbA9zDv/go-libp2p-peerstore" + pstore "gx/ipfs/QmXEyLwySuDMXejWBu8XwdkX2WuGKk8x9jFwz8js7j72UX/go-libp2p-peerstore" peer "gx/ipfs/QmbNepETomvmXfz1X5pHNFD2QuPqnqi47dTd94QJWSorQ3/go-libp2p-peer" ) diff --git a/core/coreiface/options/unixfs.go b/core/coreiface/options/unixfs.go index 6a54b2d39..b4661b793 100644 --- a/core/coreiface/options/unixfs.go +++ b/core/coreiface/options/unixfs.go @@ -6,7 +6,7 @@ import ( cid "gx/ipfs/QmPSQnBKM9g7BaUcZCvswUJVscQ1ipjmwxN5PXCjkp9EQ7/go-cid" mh "gx/ipfs/QmPnFwZ2JXKnXgMw8CdBPxn7FWh6LLdjUjxV1fKHuJnkr8/go-multihash" - dag "gx/ipfs/QmTGpm48qm4fUZ9E5hMXy4ZngJUYCMKu15rTMVR3BSEnPm/go-merkledag" + dag "gx/ipfs/QmXTw4By9FMZAt7qJm4JoJuNBrBgqMMzkS4AjKc4zqTUVd/go-merkledag" ) type Layout int diff --git a/core/coreiface/path.go b/core/coreiface/path.go index 63b15fb50..9bb46b4b4 100644 --- a/core/coreiface/path.go +++ b/core/coreiface/path.go @@ -1,7 +1,7 @@ package iface import ( - ipfspath "gx/ipfs/QmV4QxScV9Y7LbaWhHazFfRd8uyeUd4pAH8a7fFFbi5odJ/go-path" + ipfspath "gx/ipfs/QmQmMu1vsgsjxyB8tzrA6ZTCTCLDLVaXMb4Q57r2v886Sx/go-path" cid "gx/ipfs/QmPSQnBKM9g7BaUcZCvswUJVscQ1ipjmwxN5PXCjkp9EQ7/go-cid" ) diff --git a/core/coreiface/swarm.go b/core/coreiface/swarm.go index 58caf6759..d8bca395c 100644 --- a/core/coreiface/swarm.go +++ b/core/coreiface/swarm.go @@ -5,8 +5,8 @@ import ( "errors" "time" - net "gx/ipfs/QmQdLcvoy3JuSqhV6iwQ9T6Cv7hWLAdzob4jUZRPqFL67Z/go-libp2p-net" - pstore "gx/ipfs/QmSJ36wcYQyEViJUWUEhJU81tw1KdakTKqLLHbvYbA9zDv/go-libp2p-peerstore" + net "gx/ipfs/QmWUPYHpNv4YahaBYXovuEJttgfqcNcN9Gg4arhQYcRoqa/go-libp2p-net" + pstore "gx/ipfs/QmXEyLwySuDMXejWBu8XwdkX2WuGKk8x9jFwz8js7j72UX/go-libp2p-peerstore" ma "gx/ipfs/QmYmsdtJ3HsodkePE3eU3TsCaP2YvPZJ4LoXnNkDE5Tpt7/go-multiaddr" "gx/ipfs/QmZNkThpqfVXs9GNbexPrfBbXSLNYeKrE7jwFM2oqHbyqN/go-libp2p-protocol" "gx/ipfs/QmbNepETomvmXfz1X5pHNFD2QuPqnqi47dTd94QJWSorQ3/go-libp2p-peer" From d54cf20f798baecd7ece7707ce5c14c0f54b2196 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Wed, 10 Oct 2018 14:06:57 +0100 Subject: [PATCH 0130/1212] gx: update go-buffer-pool Turns out that `pool.Put(buf)` had to *allocate* because we needed to turn `[]byte` into `interface{}`. Apparently, we've never done this correctly we just never noticed because we never really used buffer pools extensively. However, since migrating yamux to a buffer-pool backed buffer, this started showing up in allocation profiles. License: MIT Signed-off-by: Steven Allen This commit was moved from ipfs/interface-go-ipfs-core@54fd5775db59e6c0113851fb7556dd09adac4215 This commit was moved from ipfs/boxo@2bda31a93a5070433a41cff4799c0012f4d69460 --- core/coreiface/dht.go | 2 +- core/coreiface/options/unixfs.go | 2 +- core/coreiface/path.go | 2 +- core/coreiface/swarm.go | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/core/coreiface/dht.go b/core/coreiface/dht.go index 3096c8fb7..cb3362bb9 100644 --- a/core/coreiface/dht.go +++ b/core/coreiface/dht.go @@ -5,7 +5,7 @@ import ( "github.com/ipfs/go-ipfs/core/coreapi/interface/options" - pstore "gx/ipfs/QmXEyLwySuDMXejWBu8XwdkX2WuGKk8x9jFwz8js7j72UX/go-libp2p-peerstore" + pstore "gx/ipfs/QmWtCpWB39Rzc2xTB75MKorsxNpo3TyecTEN24CJ3KVohE/go-libp2p-peerstore" peer "gx/ipfs/QmbNepETomvmXfz1X5pHNFD2QuPqnqi47dTd94QJWSorQ3/go-libp2p-peer" ) diff --git a/core/coreiface/options/unixfs.go b/core/coreiface/options/unixfs.go index b4661b793..aaed6024e 100644 --- a/core/coreiface/options/unixfs.go +++ b/core/coreiface/options/unixfs.go @@ -6,7 +6,7 @@ import ( cid "gx/ipfs/QmPSQnBKM9g7BaUcZCvswUJVscQ1ipjmwxN5PXCjkp9EQ7/go-cid" mh "gx/ipfs/QmPnFwZ2JXKnXgMw8CdBPxn7FWh6LLdjUjxV1fKHuJnkr8/go-multihash" - dag "gx/ipfs/QmXTw4By9FMZAt7qJm4JoJuNBrBgqMMzkS4AjKc4zqTUVd/go-merkledag" + dag "gx/ipfs/QmTpyXP1bsqJvyW5VcNmALPCb47VPJFy2T8icGASNy4ML1/go-merkledag" ) type Layout int diff --git a/core/coreiface/path.go b/core/coreiface/path.go index 9bb46b4b4..a11a46324 100644 --- a/core/coreiface/path.go +++ b/core/coreiface/path.go @@ -1,7 +1,7 @@ package iface import ( - ipfspath "gx/ipfs/QmQmMu1vsgsjxyB8tzrA6ZTCTCLDLVaXMb4Q57r2v886Sx/go-path" + ipfspath "gx/ipfs/QmTy6VoHV2E5baEFDXbp1xmHhxSVff5qTSrTsoXxD1eB2P/go-path" cid "gx/ipfs/QmPSQnBKM9g7BaUcZCvswUJVscQ1ipjmwxN5PXCjkp9EQ7/go-cid" ) diff --git a/core/coreiface/swarm.go b/core/coreiface/swarm.go index d8bca395c..ba1a55698 100644 --- a/core/coreiface/swarm.go +++ b/core/coreiface/swarm.go @@ -5,8 +5,8 @@ import ( "errors" "time" - net "gx/ipfs/QmWUPYHpNv4YahaBYXovuEJttgfqcNcN9Gg4arhQYcRoqa/go-libp2p-net" - pstore "gx/ipfs/QmXEyLwySuDMXejWBu8XwdkX2WuGKk8x9jFwz8js7j72UX/go-libp2p-peerstore" + net "gx/ipfs/QmSTaEYUgDe1r581hxyd2u9582Hgp3KX4wGwYbRqz2u9Qh/go-libp2p-net" + pstore "gx/ipfs/QmWtCpWB39Rzc2xTB75MKorsxNpo3TyecTEN24CJ3KVohE/go-libp2p-peerstore" ma "gx/ipfs/QmYmsdtJ3HsodkePE3eU3TsCaP2YvPZJ4LoXnNkDE5Tpt7/go-multiaddr" "gx/ipfs/QmZNkThpqfVXs9GNbexPrfBbXSLNYeKrE7jwFM2oqHbyqN/go-libp2p-protocol" "gx/ipfs/QmbNepETomvmXfz1X5pHNFD2QuPqnqi47dTd94QJWSorQ3/go-libp2p-peer" From b3ad18600c88c12fb6fc247ec8aa7acb20e1e0bf Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Fri, 12 Oct 2018 16:15:40 +0100 Subject: [PATCH 0131/1212] gx: update yamux and refmt * yamux: fix memory leak. * refmt: obey the "empty" tag. License: MIT Signed-off-by: Steven Allen This commit was moved from ipfs/interface-go-ipfs-core@cb4d2fb72ce804cc5c277ac8d6b1b10a63943072 This commit was moved from ipfs/boxo@f3066c9cd309e9af638a8c03d9967776254d5d65 --- core/coreiface/options/unixfs.go | 2 +- core/coreiface/path.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/coreiface/options/unixfs.go b/core/coreiface/options/unixfs.go index aaed6024e..307d618de 100644 --- a/core/coreiface/options/unixfs.go +++ b/core/coreiface/options/unixfs.go @@ -6,7 +6,7 @@ import ( cid "gx/ipfs/QmPSQnBKM9g7BaUcZCvswUJVscQ1ipjmwxN5PXCjkp9EQ7/go-cid" mh "gx/ipfs/QmPnFwZ2JXKnXgMw8CdBPxn7FWh6LLdjUjxV1fKHuJnkr8/go-multihash" - dag "gx/ipfs/QmTpyXP1bsqJvyW5VcNmALPCb47VPJFy2T8icGASNy4ML1/go-merkledag" + dag "gx/ipfs/QmVvNkTCx8V9Zei8xuTYTBdUXmbnDRS4iNuw1SztYyhQwQ/go-merkledag" ) type Layout int diff --git a/core/coreiface/path.go b/core/coreiface/path.go index a11a46324..d90f04aa1 100644 --- a/core/coreiface/path.go +++ b/core/coreiface/path.go @@ -1,7 +1,7 @@ package iface import ( - ipfspath "gx/ipfs/QmTy6VoHV2E5baEFDXbp1xmHhxSVff5qTSrTsoXxD1eB2P/go-path" + ipfspath "gx/ipfs/QmdrpbDgeYH3VxkCciQCJY5LkDYdXtig6unDzQmMxFtWEw/go-path" cid "gx/ipfs/QmPSQnBKM9g7BaUcZCvswUJVscQ1ipjmwxN5PXCjkp9EQ7/go-cid" ) From 45b9ac582df7c77466cb7cb0464dede2554c1e02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 16 Oct 2018 11:41:00 +0200 Subject: [PATCH 0132/1212] namesys: review fixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@f660979841b69c6f91ff258b2eb90695dae98e75 This commit was moved from ipfs/boxo@6aaeb7276d4aa93de22390a6abf730231d75bbf3 --- core/coreiface/name.go | 1 - 1 file changed, 1 deletion(-) diff --git a/core/coreiface/name.go b/core/coreiface/name.go index 14127ac27..782f68351 100644 --- a/core/coreiface/name.go +++ b/core/coreiface/name.go @@ -2,7 +2,6 @@ package iface import ( "context" - "errors" options "github.com/ipfs/go-ipfs/core/coreapi/interface/options" From cfb18be463a1be895ec794d1a0f57c8e256a2884 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 16 Oct 2018 16:35:31 +0200 Subject: [PATCH 0133/1212] namesys: drop prefix args MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@1308d71ad0a2b782fd9b7f481ffe7789b30b8a29 This commit was moved from ipfs/boxo@183798effb213f1913b8c3702a89b5a026077e7a --- core/coreiface/name.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/coreiface/name.go b/core/coreiface/name.go index 782f68351..a02bc0787 100644 --- a/core/coreiface/name.go +++ b/core/coreiface/name.go @@ -40,7 +40,7 @@ type NameAPI interface { // Search is a version of Resolve which outputs paths as they are discovered, // reducing the time to first entry // - // Note that by default only the last path returned before the channel closes - // can be considered 'safe'. + // Note: by default, all paths read from the channel are considered unsafe, + // except the latest (last path in channel read buffer). Search(ctx context.Context, name string, opts ...options.NameResolveOption) (<-chan IpnsResult, error) } From 9a680c8fe31e4ad43e7812f82bd257f5dc538c8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 18 Oct 2018 10:16:31 +0200 Subject: [PATCH 0134/1212] gx: update to use extracted go-ipfs-files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@a945dc346666180846b543c15cf1a7cb3d25d7bd This commit was moved from ipfs/boxo@7af2ed03ee8171a3a4bf3d943fc50953f5390acd --- core/coreiface/unixfs.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/coreiface/unixfs.go b/core/coreiface/unixfs.go index c622e210e..078d648bc 100644 --- a/core/coreiface/unixfs.go +++ b/core/coreiface/unixfs.go @@ -5,7 +5,7 @@ import ( options "github.com/ipfs/go-ipfs/core/coreapi/interface/options" - files "gx/ipfs/QmSP88ryZkHSRn1fnngAaV2Vcn63WUJzAavnRM9CVdU1Ky/go-ipfs-cmdkit/files" + files "gx/ipfs/QmZMWMvWMVKCbHetJ4RgndbuEF1io2UpUxwQwtNjtYPzSC/go-ipfs-files" ipld "gx/ipfs/QmdDXJs4axxefSPgK6Y1QhpJWKuDPnGJiqgq4uncb4rFHL/go-ipld-format" ) From 278701f8d1c35e7b6541e739a98e639060e4a29c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 9 Oct 2018 18:57:25 +0200 Subject: [PATCH 0135/1212] coreapi unixfs: remove Cat, use sessions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@26985dbeb71dc2999d2640c301cc88b2e1e56b72 This commit was moved from ipfs/boxo@83af9fbde0491d60155e511ad14d2e20068fd753 --- core/coreiface/unixfs.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/core/coreiface/unixfs.go b/core/coreiface/unixfs.go index 078d648bc..4a6c956a0 100644 --- a/core/coreiface/unixfs.go +++ b/core/coreiface/unixfs.go @@ -31,10 +31,6 @@ type UnixfsAPI interface { // to operations performed on the returned file Get(context.Context, Path) (files.File, error) - // Cat returns a reader for the file - // TODO: Remove in favour of Get (if we use Get on a file we still have reader directly, so..) - Cat(context.Context, Path) (Reader, error) - // Ls returns the list of links in a directory Ls(context.Context, Path) ([]*ipld.Link, error) } From 7301aaa1201e6ecdff3d9ef82d66d957cc917d19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 15 Oct 2018 12:45:49 +0200 Subject: [PATCH 0136/1212] coreapi unixfs: Return seeker from get MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@7fad9653969f1e71a85778e3e4e225c97d71558b This commit was moved from ipfs/boxo@8d4196176a99ab51bfd521afbd061bfcf456354f --- core/coreiface/unixfs.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/core/coreiface/unixfs.go b/core/coreiface/unixfs.go index 4a6c956a0..dd7e5a392 100644 --- a/core/coreiface/unixfs.go +++ b/core/coreiface/unixfs.go @@ -2,6 +2,7 @@ package iface import ( "context" + "io" options "github.com/ipfs/go-ipfs/core/coreapi/interface/options" @@ -17,6 +18,11 @@ type AddEvent struct { Size string `json:",omitempty"` } +type UnixfsFile interface { + files.SizeFile + io.Seeker +} + // UnixfsAPI is the basic interface to immutable files in IPFS // NOTE: This API is heavily WIP, things are guaranteed to break frequently type UnixfsAPI interface { @@ -29,7 +35,7 @@ type UnixfsAPI interface { // // Note that some implementations of this API may apply the specified context // to operations performed on the returned file - Get(context.Context, Path) (files.File, error) + Get(context.Context, Path) (UnixfsFile, error) // Ls returns the list of links in a directory Ls(context.Context, Path) ([]*ipld.Link, error) From e6dbe550bc31a8f23aba03c561d6f847dee9ad31 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Wed, 24 Oct 2018 09:59:18 -0700 Subject: [PATCH 0137/1212] gx update License: MIT Signed-off-by: Steven Allen This commit was moved from ipfs/interface-go-ipfs-core@c9eb6014a863a96f762fd87274a63ff906da0c65 This commit was moved from ipfs/boxo@10afc1c6e7946a55faeacc943f1aa6802530796b --- core/coreiface/dht.go | 4 ++-- core/coreiface/key.go | 2 +- core/coreiface/options/unixfs.go | 2 +- core/coreiface/path.go | 2 +- core/coreiface/pubsub.go | 2 +- core/coreiface/swarm.go | 8 ++++---- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/core/coreiface/dht.go b/core/coreiface/dht.go index cb3362bb9..38a0f7348 100644 --- a/core/coreiface/dht.go +++ b/core/coreiface/dht.go @@ -5,8 +5,8 @@ import ( "github.com/ipfs/go-ipfs/core/coreapi/interface/options" - pstore "gx/ipfs/QmWtCpWB39Rzc2xTB75MKorsxNpo3TyecTEN24CJ3KVohE/go-libp2p-peerstore" - peer "gx/ipfs/QmbNepETomvmXfz1X5pHNFD2QuPqnqi47dTd94QJWSorQ3/go-libp2p-peer" + peer "gx/ipfs/QmTRhk7cgjUf2gfQ3p2M9KPECNZEW9XUrmHcFCgog4cPgB/go-libp2p-peer" + pstore "gx/ipfs/QmTTJcDL3gsnGDALjh2fDGg1onGRUdVgNL2hU2WEZcVrMX/go-libp2p-peerstore" ) // DhtAPI specifies the interface to the DHT diff --git a/core/coreiface/key.go b/core/coreiface/key.go index cc6dc8900..9e7bfee28 100644 --- a/core/coreiface/key.go +++ b/core/coreiface/key.go @@ -5,7 +5,7 @@ import ( options "github.com/ipfs/go-ipfs/core/coreapi/interface/options" - "gx/ipfs/QmbNepETomvmXfz1X5pHNFD2QuPqnqi47dTd94QJWSorQ3/go-libp2p-peer" + "gx/ipfs/QmTRhk7cgjUf2gfQ3p2M9KPECNZEW9XUrmHcFCgog4cPgB/go-libp2p-peer" ) // Key specifies the interface to Keys in KeyAPI Keystore diff --git a/core/coreiface/options/unixfs.go b/core/coreiface/options/unixfs.go index 307d618de..8fe172fea 100644 --- a/core/coreiface/options/unixfs.go +++ b/core/coreiface/options/unixfs.go @@ -6,7 +6,7 @@ import ( cid "gx/ipfs/QmPSQnBKM9g7BaUcZCvswUJVscQ1ipjmwxN5PXCjkp9EQ7/go-cid" mh "gx/ipfs/QmPnFwZ2JXKnXgMw8CdBPxn7FWh6LLdjUjxV1fKHuJnkr8/go-multihash" - dag "gx/ipfs/QmVvNkTCx8V9Zei8xuTYTBdUXmbnDRS4iNuw1SztYyhQwQ/go-merkledag" + dag "gx/ipfs/QmY5xpETYHq3PPvaJnafyLWKqk5y7cZnUeBqLRtLUpEV3s/go-merkledag" ) type Layout int diff --git a/core/coreiface/path.go b/core/coreiface/path.go index d90f04aa1..53938c3de 100644 --- a/core/coreiface/path.go +++ b/core/coreiface/path.go @@ -1,7 +1,7 @@ package iface import ( - ipfspath "gx/ipfs/QmdrpbDgeYH3VxkCciQCJY5LkDYdXtig6unDzQmMxFtWEw/go-path" + ipfspath "gx/ipfs/QmayGyPXjTt3cGzjCR3wb5HsHQX7LaJcWUbZemGDn6rKWq/go-path" cid "gx/ipfs/QmPSQnBKM9g7BaUcZCvswUJVscQ1ipjmwxN5PXCjkp9EQ7/go-cid" ) diff --git a/core/coreiface/pubsub.go b/core/coreiface/pubsub.go index d7a21e02f..b3f3f6b76 100644 --- a/core/coreiface/pubsub.go +++ b/core/coreiface/pubsub.go @@ -6,7 +6,7 @@ import ( options "github.com/ipfs/go-ipfs/core/coreapi/interface/options" - peer "gx/ipfs/QmbNepETomvmXfz1X5pHNFD2QuPqnqi47dTd94QJWSorQ3/go-libp2p-peer" + peer "gx/ipfs/QmTRhk7cgjUf2gfQ3p2M9KPECNZEW9XUrmHcFCgog4cPgB/go-libp2p-peer" ) // PubSubSubscription is an active PubSub subscription diff --git a/core/coreiface/swarm.go b/core/coreiface/swarm.go index ba1a55698..d4b92c017 100644 --- a/core/coreiface/swarm.go +++ b/core/coreiface/swarm.go @@ -5,11 +5,11 @@ import ( "errors" "time" - net "gx/ipfs/QmSTaEYUgDe1r581hxyd2u9582Hgp3KX4wGwYbRqz2u9Qh/go-libp2p-net" - pstore "gx/ipfs/QmWtCpWB39Rzc2xTB75MKorsxNpo3TyecTEN24CJ3KVohE/go-libp2p-peerstore" - ma "gx/ipfs/QmYmsdtJ3HsodkePE3eU3TsCaP2YvPZJ4LoXnNkDE5Tpt7/go-multiaddr" + ma "gx/ipfs/QmT4U94DnD8FRfqr21obWY32HLM5VExccPKMjQHofeYqr9/go-multiaddr" + "gx/ipfs/QmTRhk7cgjUf2gfQ3p2M9KPECNZEW9XUrmHcFCgog4cPgB/go-libp2p-peer" + pstore "gx/ipfs/QmTTJcDL3gsnGDALjh2fDGg1onGRUdVgNL2hU2WEZcVrMX/go-libp2p-peerstore" + net "gx/ipfs/QmXuRkCR7BNQa9uqfpTiFWsTQLzmTWYg91Ja1w95gnqb6u/go-libp2p-net" "gx/ipfs/QmZNkThpqfVXs9GNbexPrfBbXSLNYeKrE7jwFM2oqHbyqN/go-libp2p-protocol" - "gx/ipfs/QmbNepETomvmXfz1X5pHNFD2QuPqnqi47dTd94QJWSorQ3/go-libp2p-peer" ) var ( From 07161dee3ee30e4cbb13caa39737787662188eaa Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Wed, 24 Oct 2018 12:49:25 -0700 Subject: [PATCH 0138/1212] gx update go-libp2p License: MIT Signed-off-by: Steven Allen This commit was moved from ipfs/interface-go-ipfs-core@da1f68d4e43463145f44894cbb8cf5d5a992f8d3 This commit was moved from ipfs/boxo@8cdb97d783313ce8276610860ec005d66e395cb5 --- core/coreiface/options/unixfs.go | 2 +- core/coreiface/path.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/coreiface/options/unixfs.go b/core/coreiface/options/unixfs.go index 8fe172fea..4d179f9ff 100644 --- a/core/coreiface/options/unixfs.go +++ b/core/coreiface/options/unixfs.go @@ -6,7 +6,7 @@ import ( cid "gx/ipfs/QmPSQnBKM9g7BaUcZCvswUJVscQ1ipjmwxN5PXCjkp9EQ7/go-cid" mh "gx/ipfs/QmPnFwZ2JXKnXgMw8CdBPxn7FWh6LLdjUjxV1fKHuJnkr8/go-multihash" - dag "gx/ipfs/QmY5xpETYHq3PPvaJnafyLWKqk5y7cZnUeBqLRtLUpEV3s/go-merkledag" + dag "gx/ipfs/QmcescwzzD86xrxoXNJ6VwSw46wLC91QzFDnozYRVf4KnX/go-merkledag" ) type Layout int diff --git a/core/coreiface/path.go b/core/coreiface/path.go index 53938c3de..44d53f23c 100644 --- a/core/coreiface/path.go +++ b/core/coreiface/path.go @@ -1,7 +1,7 @@ package iface import ( - ipfspath "gx/ipfs/QmayGyPXjTt3cGzjCR3wb5HsHQX7LaJcWUbZemGDn6rKWq/go-path" + ipfspath "gx/ipfs/QmQ4sKWqHhSYekzST5RwT4VHdQB4df6JWLHNy7tuWTo8uY/go-path" cid "gx/ipfs/QmPSQnBKM9g7BaUcZCvswUJVscQ1ipjmwxN5PXCjkp9EQ7/go-cid" ) From 213fdce4feca11e9d02d837e94e695010f5d770d Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Wed, 24 Oct 2018 15:01:31 -0700 Subject: [PATCH 0139/1212] gx: update yamux (fixes a panic due to a race) License: MIT Signed-off-by: Steven Allen This commit was moved from ipfs/interface-go-ipfs-core@edab11e8dd939a1f41567c663c20e79a334c38f3 This commit was moved from ipfs/boxo@7e7e70c7ef59b3024e7030f93d9b24f7697a4b51 --- core/coreiface/options/unixfs.go | 2 +- core/coreiface/path.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/coreiface/options/unixfs.go b/core/coreiface/options/unixfs.go index 4d179f9ff..f564d2427 100644 --- a/core/coreiface/options/unixfs.go +++ b/core/coreiface/options/unixfs.go @@ -6,7 +6,7 @@ import ( cid "gx/ipfs/QmPSQnBKM9g7BaUcZCvswUJVscQ1ipjmwxN5PXCjkp9EQ7/go-cid" mh "gx/ipfs/QmPnFwZ2JXKnXgMw8CdBPxn7FWh6LLdjUjxV1fKHuJnkr8/go-multihash" - dag "gx/ipfs/QmcescwzzD86xrxoXNJ6VwSw46wLC91QzFDnozYRVf4KnX/go-merkledag" + dag "gx/ipfs/QmY8BMUSpCwNiTmFhACmC9Bt1qT63cHP35AoQAus4x14qH/go-merkledag" ) type Layout int diff --git a/core/coreiface/path.go b/core/coreiface/path.go index 44d53f23c..eb976ebd8 100644 --- a/core/coreiface/path.go +++ b/core/coreiface/path.go @@ -1,7 +1,7 @@ package iface import ( - ipfspath "gx/ipfs/QmQ4sKWqHhSYekzST5RwT4VHdQB4df6JWLHNy7tuWTo8uY/go-path" + ipfspath "gx/ipfs/QmRKuTyCzg7HFBcV1YUhzStroGtJSb8iWgyxfsDCwFhWTS/go-path" cid "gx/ipfs/QmPSQnBKM9g7BaUcZCvswUJVscQ1ipjmwxN5PXCjkp9EQ7/go-cid" ) From 1cd4f200e9f6753e25efbf21f787b14859f2e52c Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Sat, 27 Oct 2018 03:30:18 +0200 Subject: [PATCH 0140/1212] Bubble deps License: MIT Signed-off-by: Hector Sanjuan This commit was moved from ipfs/interface-go-ipfs-core@c21b863fa15557b64d4bdcc99a7134b28ac3ca05 This commit was moved from ipfs/boxo@95c39b6f72f1d32c0e68731b2a02e031ac941e02 --- core/coreiface/coreapi.go | 2 +- core/coreiface/dag.go | 2 +- core/coreiface/object.go | 2 +- core/coreiface/options/unixfs.go | 2 +- core/coreiface/path.go | 2 +- core/coreiface/unixfs.go | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/core/coreiface/coreapi.go b/core/coreiface/coreapi.go index bc889237b..b744a207a 100644 --- a/core/coreiface/coreapi.go +++ b/core/coreiface/coreapi.go @@ -5,7 +5,7 @@ package iface import ( "context" - ipld "gx/ipfs/QmdDXJs4axxefSPgK6Y1QhpJWKuDPnGJiqgq4uncb4rFHL/go-ipld-format" + ipld "gx/ipfs/QmR7TcHkR9nxkUorfi8XMTAMLUK7GiP64TWWBzY3aacc1o/go-ipld-format" ) // CoreAPI defines an unified interface to IPFS for Go programs diff --git a/core/coreiface/dag.go b/core/coreiface/dag.go index 06bb91dce..6cca5b9e6 100644 --- a/core/coreiface/dag.go +++ b/core/coreiface/dag.go @@ -6,7 +6,7 @@ import ( "github.com/ipfs/go-ipfs/core/coreapi/interface/options" - ipld "gx/ipfs/QmdDXJs4axxefSPgK6Y1QhpJWKuDPnGJiqgq4uncb4rFHL/go-ipld-format" + ipld "gx/ipfs/QmR7TcHkR9nxkUorfi8XMTAMLUK7GiP64TWWBzY3aacc1o/go-ipld-format" ) // DagOps groups operations that can be batched together diff --git a/core/coreiface/object.go b/core/coreiface/object.go index 6b355a302..229f69869 100644 --- a/core/coreiface/object.go +++ b/core/coreiface/object.go @@ -7,7 +7,7 @@ import ( options "github.com/ipfs/go-ipfs/core/coreapi/interface/options" cid "gx/ipfs/QmPSQnBKM9g7BaUcZCvswUJVscQ1ipjmwxN5PXCjkp9EQ7/go-cid" - ipld "gx/ipfs/QmdDXJs4axxefSPgK6Y1QhpJWKuDPnGJiqgq4uncb4rFHL/go-ipld-format" + ipld "gx/ipfs/QmR7TcHkR9nxkUorfi8XMTAMLUK7GiP64TWWBzY3aacc1o/go-ipld-format" ) // ObjectStat provides information about dag nodes diff --git a/core/coreiface/options/unixfs.go b/core/coreiface/options/unixfs.go index f564d2427..8a9137887 100644 --- a/core/coreiface/options/unixfs.go +++ b/core/coreiface/options/unixfs.go @@ -6,7 +6,7 @@ import ( cid "gx/ipfs/QmPSQnBKM9g7BaUcZCvswUJVscQ1ipjmwxN5PXCjkp9EQ7/go-cid" mh "gx/ipfs/QmPnFwZ2JXKnXgMw8CdBPxn7FWh6LLdjUjxV1fKHuJnkr8/go-multihash" - dag "gx/ipfs/QmY8BMUSpCwNiTmFhACmC9Bt1qT63cHP35AoQAus4x14qH/go-merkledag" + dag "gx/ipfs/QmSei8kFMfqdJq7Q68d2LMnHbTWKKg2daA29ezUYFAUNgc/go-merkledag" ) type Layout int diff --git a/core/coreiface/path.go b/core/coreiface/path.go index eb976ebd8..5a3d1128b 100644 --- a/core/coreiface/path.go +++ b/core/coreiface/path.go @@ -1,7 +1,7 @@ package iface import ( - ipfspath "gx/ipfs/QmRKuTyCzg7HFBcV1YUhzStroGtJSb8iWgyxfsDCwFhWTS/go-path" + ipfspath "gx/ipfs/QmZbQUht8hzKmQxLHnzY14WSuoQqYkR5mn4cunchyWPmhn/go-path" cid "gx/ipfs/QmPSQnBKM9g7BaUcZCvswUJVscQ1ipjmwxN5PXCjkp9EQ7/go-cid" ) diff --git a/core/coreiface/unixfs.go b/core/coreiface/unixfs.go index dd7e5a392..6fd33ad2c 100644 --- a/core/coreiface/unixfs.go +++ b/core/coreiface/unixfs.go @@ -6,8 +6,8 @@ import ( options "github.com/ipfs/go-ipfs/core/coreapi/interface/options" + ipld "gx/ipfs/QmR7TcHkR9nxkUorfi8XMTAMLUK7GiP64TWWBzY3aacc1o/go-ipld-format" files "gx/ipfs/QmZMWMvWMVKCbHetJ4RgndbuEF1io2UpUxwQwtNjtYPzSC/go-ipfs-files" - ipld "gx/ipfs/QmdDXJs4axxefSPgK6Y1QhpJWKuDPnGJiqgq4uncb4rFHL/go-ipld-format" ) // TODO: ideas on making this more coreapi-ish without breaking the http API? From 7c9bf201dbfa5c1d9e5271e4f7c8a800539f4ac5 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Tue, 30 Oct 2018 08:48:49 -0700 Subject: [PATCH 0141/1212] coreapi: fix errisdir JavaScript expects this to be "this dag node is a directory". I'm almost of a mind to say "don't parse errors" but, well, we don't give any better alternatives. License: MIT Signed-off-by: Steven Allen This commit was moved from ipfs/interface-go-ipfs-core@dc979581ae4496d6e2c57a019cb133d780585df7 This commit was moved from ipfs/boxo@abd0d4dddf5f23500d65ce04ab82a0dd8b7baa74 --- core/coreiface/errors.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/coreiface/errors.go b/core/coreiface/errors.go index 072275409..4ee3026ff 100644 --- a/core/coreiface/errors.go +++ b/core/coreiface/errors.go @@ -3,6 +3,6 @@ package iface import "errors" var ( - ErrIsDir = errors.New("object is a directory") + ErrIsDir = errors.New("this dag node is a directory") ErrOffline = errors.New("this action must be run in online mode, try running 'ipfs daemon' first") ) From a81292a58214577d336645132c21a57048ab443a Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Tue, 30 Oct 2018 09:27:41 -0700 Subject: [PATCH 0142/1212] gx: update go-path fixes the changed path cat error causing the js-ipfs-api tests to fail License: MIT Signed-off-by: Steven Allen This commit was moved from ipfs/interface-go-ipfs-core@6fcff53bc29de056f4b948bb0bfaa468546d1c66 This commit was moved from ipfs/boxo@41c1c071623c7781041fb09e69c641db9642bc1d --- core/coreiface/path.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/coreiface/path.go b/core/coreiface/path.go index 5a3d1128b..79dac201d 100644 --- a/core/coreiface/path.go +++ b/core/coreiface/path.go @@ -1,7 +1,7 @@ package iface import ( - ipfspath "gx/ipfs/QmZbQUht8hzKmQxLHnzY14WSuoQqYkR5mn4cunchyWPmhn/go-path" + ipfspath "gx/ipfs/QmT3rzed1ppXefourpmoZ7tyVQfsGPQZ1pHDngLmCvXxd3/go-path" cid "gx/ipfs/QmPSQnBKM9g7BaUcZCvswUJVscQ1ipjmwxN5PXCjkp9EQ7/go-cid" ) From 1eb12c92ea12cd542f132203e9ddc46d21781da4 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Fri, 2 Nov 2018 13:16:34 -0700 Subject: [PATCH 0143/1212] gx: update go-ipld-cbor (might as well do this at the same time) License: MIT Signed-off-by: Steven Allen This commit was moved from ipfs/interface-go-ipfs-core@bca0017a7a95666fff03c83e4a8e38b51d6158f3 This commit was moved from ipfs/boxo@9054f4c4c977dda2774bcf8493b2087fbf097d4d --- core/coreiface/options/unixfs.go | 2 +- core/coreiface/path.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/coreiface/options/unixfs.go b/core/coreiface/options/unixfs.go index 8a9137887..d541adac7 100644 --- a/core/coreiface/options/unixfs.go +++ b/core/coreiface/options/unixfs.go @@ -6,7 +6,7 @@ import ( cid "gx/ipfs/QmPSQnBKM9g7BaUcZCvswUJVscQ1ipjmwxN5PXCjkp9EQ7/go-cid" mh "gx/ipfs/QmPnFwZ2JXKnXgMw8CdBPxn7FWh6LLdjUjxV1fKHuJnkr8/go-multihash" - dag "gx/ipfs/QmSei8kFMfqdJq7Q68d2LMnHbTWKKg2daA29ezUYFAUNgc/go-merkledag" + dag "gx/ipfs/QmXyuFW7at4r9dxRAbrPU9JpHW5aqngAFyxvyhvYjzxRKS/go-merkledag" ) type Layout int diff --git a/core/coreiface/path.go b/core/coreiface/path.go index 79dac201d..034bfffc3 100644 --- a/core/coreiface/path.go +++ b/core/coreiface/path.go @@ -1,7 +1,7 @@ package iface import ( - ipfspath "gx/ipfs/QmT3rzed1ppXefourpmoZ7tyVQfsGPQZ1pHDngLmCvXxd3/go-path" + ipfspath "gx/ipfs/QmUB3RFRDctDp1k73mDJydzWiKdiuNHfyuoRPQeU52rWWT/go-path" cid "gx/ipfs/QmPSQnBKM9g7BaUcZCvswUJVscQ1ipjmwxN5PXCjkp9EQ7/go-cid" ) From 3e33625fe336ffcc052f002259e8744d9fea78e4 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Fri, 2 Nov 2018 17:15:21 -0700 Subject: [PATCH 0144/1212] gx: update go-log and sha256 fixes #5709 License: MIT Signed-off-by: Steven Allen This commit was moved from ipfs/interface-go-ipfs-core@1c6351bc2b6ca351b0aaf8f3a6eca43714af21e1 This commit was moved from ipfs/boxo@93332aaa1821369c585b86e957acd42a09d3f1dd --- core/coreiface/coreapi.go | 2 +- core/coreiface/dag.go | 2 +- core/coreiface/dht.go | 4 ++-- core/coreiface/key.go | 2 +- core/coreiface/object.go | 4 ++-- core/coreiface/options/block.go | 4 ++-- core/coreiface/options/dag.go | 2 +- core/coreiface/options/unixfs.go | 6 +++--- core/coreiface/path.go | 4 ++-- core/coreiface/pubsub.go | 2 +- core/coreiface/swarm.go | 8 ++++---- core/coreiface/unixfs.go | 2 +- 12 files changed, 21 insertions(+), 21 deletions(-) diff --git a/core/coreiface/coreapi.go b/core/coreiface/coreapi.go index b744a207a..bab4fc13b 100644 --- a/core/coreiface/coreapi.go +++ b/core/coreiface/coreapi.go @@ -5,7 +5,7 @@ package iface import ( "context" - ipld "gx/ipfs/QmR7TcHkR9nxkUorfi8XMTAMLUK7GiP64TWWBzY3aacc1o/go-ipld-format" + ipld "gx/ipfs/QmcKKBwfz6FyQdHR2jsXrrF6XeSBXYL86anmWNewpFpoF5/go-ipld-format" ) // CoreAPI defines an unified interface to IPFS for Go programs diff --git a/core/coreiface/dag.go b/core/coreiface/dag.go index 6cca5b9e6..eb9e2da4a 100644 --- a/core/coreiface/dag.go +++ b/core/coreiface/dag.go @@ -6,7 +6,7 @@ import ( "github.com/ipfs/go-ipfs/core/coreapi/interface/options" - ipld "gx/ipfs/QmR7TcHkR9nxkUorfi8XMTAMLUK7GiP64TWWBzY3aacc1o/go-ipld-format" + ipld "gx/ipfs/QmcKKBwfz6FyQdHR2jsXrrF6XeSBXYL86anmWNewpFpoF5/go-ipld-format" ) // DagOps groups operations that can be batched together diff --git a/core/coreiface/dht.go b/core/coreiface/dht.go index 38a0f7348..c4eef9379 100644 --- a/core/coreiface/dht.go +++ b/core/coreiface/dht.go @@ -5,8 +5,8 @@ import ( "github.com/ipfs/go-ipfs/core/coreapi/interface/options" - peer "gx/ipfs/QmTRhk7cgjUf2gfQ3p2M9KPECNZEW9XUrmHcFCgog4cPgB/go-libp2p-peer" - pstore "gx/ipfs/QmTTJcDL3gsnGDALjh2fDGg1onGRUdVgNL2hU2WEZcVrMX/go-libp2p-peerstore" + pstore "gx/ipfs/QmUymf8fJtideyv3z727BcZUifGBjMZMpCJqu3Gxk5aRUk/go-libp2p-peerstore" + peer "gx/ipfs/QmcqU6QUDSXprb1518vYDGczrTJTyGwLG9eUa5iNX4xUtS/go-libp2p-peer" ) // DhtAPI specifies the interface to the DHT diff --git a/core/coreiface/key.go b/core/coreiface/key.go index 9e7bfee28..36a74688b 100644 --- a/core/coreiface/key.go +++ b/core/coreiface/key.go @@ -5,7 +5,7 @@ import ( options "github.com/ipfs/go-ipfs/core/coreapi/interface/options" - "gx/ipfs/QmTRhk7cgjUf2gfQ3p2M9KPECNZEW9XUrmHcFCgog4cPgB/go-libp2p-peer" + "gx/ipfs/QmcqU6QUDSXprb1518vYDGczrTJTyGwLG9eUa5iNX4xUtS/go-libp2p-peer" ) // Key specifies the interface to Keys in KeyAPI Keystore diff --git a/core/coreiface/object.go b/core/coreiface/object.go index 229f69869..ba6f5a95d 100644 --- a/core/coreiface/object.go +++ b/core/coreiface/object.go @@ -6,8 +6,8 @@ import ( options "github.com/ipfs/go-ipfs/core/coreapi/interface/options" - cid "gx/ipfs/QmPSQnBKM9g7BaUcZCvswUJVscQ1ipjmwxN5PXCjkp9EQ7/go-cid" - ipld "gx/ipfs/QmR7TcHkR9nxkUorfi8XMTAMLUK7GiP64TWWBzY3aacc1o/go-ipld-format" + cid "gx/ipfs/QmR8BauakNcBa3RbE4nbQu76PDiJgoQgz8AJdhJuiU4TAw/go-cid" + ipld "gx/ipfs/QmcKKBwfz6FyQdHR2jsXrrF6XeSBXYL86anmWNewpFpoF5/go-ipld-format" ) // ObjectStat provides information about dag nodes diff --git a/core/coreiface/options/block.go b/core/coreiface/options/block.go index 6603136f3..ea4ae26bb 100644 --- a/core/coreiface/options/block.go +++ b/core/coreiface/options/block.go @@ -2,8 +2,8 @@ package options import ( "fmt" - cid "gx/ipfs/QmPSQnBKM9g7BaUcZCvswUJVscQ1ipjmwxN5PXCjkp9EQ7/go-cid" - mh "gx/ipfs/QmPnFwZ2JXKnXgMw8CdBPxn7FWh6LLdjUjxV1fKHuJnkr8/go-multihash" + cid "gx/ipfs/QmR8BauakNcBa3RbE4nbQu76PDiJgoQgz8AJdhJuiU4TAw/go-cid" + mh "gx/ipfs/QmerPMzPk1mJVowm8KgmoknWa4yCYvvugMPsgWmDNUvDLW/go-multihash" ) type BlockPutSettings struct { diff --git a/core/coreiface/options/dag.go b/core/coreiface/options/dag.go index 4fdff0489..9cccba585 100644 --- a/core/coreiface/options/dag.go +++ b/core/coreiface/options/dag.go @@ -3,7 +3,7 @@ package options import ( "math" - cid "gx/ipfs/QmPSQnBKM9g7BaUcZCvswUJVscQ1ipjmwxN5PXCjkp9EQ7/go-cid" + cid "gx/ipfs/QmR8BauakNcBa3RbE4nbQu76PDiJgoQgz8AJdhJuiU4TAw/go-cid" ) type DagPutSettings struct { diff --git a/core/coreiface/options/unixfs.go b/core/coreiface/options/unixfs.go index d541adac7..9b0683a11 100644 --- a/core/coreiface/options/unixfs.go +++ b/core/coreiface/options/unixfs.go @@ -4,9 +4,9 @@ import ( "errors" "fmt" - cid "gx/ipfs/QmPSQnBKM9g7BaUcZCvswUJVscQ1ipjmwxN5PXCjkp9EQ7/go-cid" - mh "gx/ipfs/QmPnFwZ2JXKnXgMw8CdBPxn7FWh6LLdjUjxV1fKHuJnkr8/go-multihash" - dag "gx/ipfs/QmXyuFW7at4r9dxRAbrPU9JpHW5aqngAFyxvyhvYjzxRKS/go-merkledag" + cid "gx/ipfs/QmR8BauakNcBa3RbE4nbQu76PDiJgoQgz8AJdhJuiU4TAw/go-cid" + dag "gx/ipfs/QmaDBne4KeY3UepeqSVKYpSmQGa3q9zP6x3LfVF2UjF3Hc/go-merkledag" + mh "gx/ipfs/QmerPMzPk1mJVowm8KgmoknWa4yCYvvugMPsgWmDNUvDLW/go-multihash" ) type Layout int diff --git a/core/coreiface/path.go b/core/coreiface/path.go index 034bfffc3..f5e7aeb4c 100644 --- a/core/coreiface/path.go +++ b/core/coreiface/path.go @@ -1,9 +1,9 @@ package iface import ( - ipfspath "gx/ipfs/QmUB3RFRDctDp1k73mDJydzWiKdiuNHfyuoRPQeU52rWWT/go-path" + ipfspath "gx/ipfs/QmRG3XuGwT7GYuAqgWDJBKTzdaHMwAnc1x7J2KHEXNHxzG/go-path" - cid "gx/ipfs/QmPSQnBKM9g7BaUcZCvswUJVscQ1ipjmwxN5PXCjkp9EQ7/go-cid" + cid "gx/ipfs/QmR8BauakNcBa3RbE4nbQu76PDiJgoQgz8AJdhJuiU4TAw/go-cid" ) //TODO: merge with ipfspath so we don't depend on it diff --git a/core/coreiface/pubsub.go b/core/coreiface/pubsub.go index b3f3f6b76..93e429574 100644 --- a/core/coreiface/pubsub.go +++ b/core/coreiface/pubsub.go @@ -6,7 +6,7 @@ import ( options "github.com/ipfs/go-ipfs/core/coreapi/interface/options" - peer "gx/ipfs/QmTRhk7cgjUf2gfQ3p2M9KPECNZEW9XUrmHcFCgog4cPgB/go-libp2p-peer" + peer "gx/ipfs/QmcqU6QUDSXprb1518vYDGczrTJTyGwLG9eUa5iNX4xUtS/go-libp2p-peer" ) // PubSubSubscription is an active PubSub subscription diff --git a/core/coreiface/swarm.go b/core/coreiface/swarm.go index d4b92c017..b830a0817 100644 --- a/core/coreiface/swarm.go +++ b/core/coreiface/swarm.go @@ -5,11 +5,11 @@ import ( "errors" "time" - ma "gx/ipfs/QmT4U94DnD8FRfqr21obWY32HLM5VExccPKMjQHofeYqr9/go-multiaddr" - "gx/ipfs/QmTRhk7cgjUf2gfQ3p2M9KPECNZEW9XUrmHcFCgog4cPgB/go-libp2p-peer" - pstore "gx/ipfs/QmTTJcDL3gsnGDALjh2fDGg1onGRUdVgNL2hU2WEZcVrMX/go-libp2p-peerstore" - net "gx/ipfs/QmXuRkCR7BNQa9uqfpTiFWsTQLzmTWYg91Ja1w95gnqb6u/go-libp2p-net" + ma "gx/ipfs/QmRKLtwMw131aK7ugC3G7ybpumMz78YrJe5dzneyindvG1/go-multiaddr" + net "gx/ipfs/QmRKbEchaYADxSCyyjhDh4cTrUby8ftXUb8MRLBTHQYupw/go-libp2p-net" + pstore "gx/ipfs/QmUymf8fJtideyv3z727BcZUifGBjMZMpCJqu3Gxk5aRUk/go-libp2p-peerstore" "gx/ipfs/QmZNkThpqfVXs9GNbexPrfBbXSLNYeKrE7jwFM2oqHbyqN/go-libp2p-protocol" + "gx/ipfs/QmcqU6QUDSXprb1518vYDGczrTJTyGwLG9eUa5iNX4xUtS/go-libp2p-peer" ) var ( diff --git a/core/coreiface/unixfs.go b/core/coreiface/unixfs.go index 6fd33ad2c..002635d99 100644 --- a/core/coreiface/unixfs.go +++ b/core/coreiface/unixfs.go @@ -6,8 +6,8 @@ import ( options "github.com/ipfs/go-ipfs/core/coreapi/interface/options" - ipld "gx/ipfs/QmR7TcHkR9nxkUorfi8XMTAMLUK7GiP64TWWBzY3aacc1o/go-ipld-format" files "gx/ipfs/QmZMWMvWMVKCbHetJ4RgndbuEF1io2UpUxwQwtNjtYPzSC/go-ipfs-files" + ipld "gx/ipfs/QmcKKBwfz6FyQdHR2jsXrrF6XeSBXYL86anmWNewpFpoF5/go-ipld-format" ) // TODO: ideas on making this more coreapi-ish without breaking the http API? From 202081523fdc8bc54b16e5e4447b221586febef7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 6 Nov 2018 13:12:10 +0100 Subject: [PATCH 0145/1212] Setup repo This commit was moved from ipfs/go-ipfs-http-client@4e7edce41d91825f0ea21dec426de2e128db5b38 --- client/httpapi/README.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 client/httpapi/README.md diff --git a/client/httpapi/README.md b/client/httpapi/README.md new file mode 100644 index 000000000..ab37a4cf8 --- /dev/null +++ b/client/httpapi/README.md @@ -0,0 +1,27 @@ +# go-ipfs-http-api + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://ipn.io) +[![](https://img.shields.io/badge/project-IPFS-blue.svg?style=flat-square)](http://ipfs.io/) +[![](https://img.shields.io/badge/freenode-%23ipfs-blue.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23ipfs) +[![standard-readme compliant](https://img.shields.io/badge/standard--readme-OK-green.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme) +[![GoDoc](https://godoc.org/github.com/ipfs/go-ipfs-http-api?status.svg)](https://godoc.org/github.com/ipfs/go-ipfs-http-api) + +> IPFS CoreAPI implementation using HTTP API + +## Documentation + +https://godoc.org/github.com/ipfs/go-ipfs-http-api + +## Contribute + +Feel free to join in. All welcome. Open an [issue](https://github.com/ipfs/go-ipfs-http-api/issues)! + +This repository falls under the IPFS [Code of Conduct](https://github.com/ipfs/community/blob/master/code-of-conduct.md). + +### Want to hack on IPFS? + +[![](https://cdn.rawgit.com/jbenet/contribute-ipfs-gif/master/img/contribute.gif)](https://github.com/ipfs/community/blob/master/contributing.md) + +## License + +MIT From 6d85aff407d3fb3eb6d2549fbac94615fd147b49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 6 Nov 2018 13:13:15 +0100 Subject: [PATCH 0146/1212] Initial structure, path stuff This commit was moved from ipfs/go-ipfs-http-client@93943f7f5671948b0d2aee19c30cf689307faf13 --- client/httpapi/api.go | 127 +++++++++++++++++++++++++++++ client/httpapi/name.go | 35 ++++++++ client/httpapi/path.go | 48 +++++++++++ client/httpapi/request.go | 34 ++++++++ client/httpapi/requestbuilder.go | 100 +++++++++++++++++++++++ client/httpapi/response.go | 132 +++++++++++++++++++++++++++++++ 6 files changed, 476 insertions(+) create mode 100644 client/httpapi/api.go create mode 100644 client/httpapi/name.go create mode 100644 client/httpapi/path.go create mode 100644 client/httpapi/request.go create mode 100644 client/httpapi/requestbuilder.go create mode 100644 client/httpapi/response.go diff --git a/client/httpapi/api.go b/client/httpapi/api.go new file mode 100644 index 000000000..82e030350 --- /dev/null +++ b/client/httpapi/api.go @@ -0,0 +1,127 @@ +package httpapi + +import ( + "github.com/pkg/errors" + "io/ioutil" + gohttp "net/http" + "os" + "path" + "strings" + + "github.com/ipfs/go-ipfs/core/coreapi/interface" + homedir "github.com/mitchellh/go-homedir" + ma "github.com/multiformats/go-multiaddr" + manet "github.com/multiformats/go-multiaddr-net" + ) + +const ( + DefaultPathName = ".ipfs" + DefaultPathRoot = "~/" + DefaultPathName + DefaultApiFile = "api" + EnvDir = "IPFS_PATH" +) + +var ErrNotImplemented = errors.New("not implemented") + +type HttpApi struct { + url string + httpcli *gohttp.Client +} + +func NewLocalApi() iface.CoreAPI { + baseDir := os.Getenv(EnvDir) + if baseDir == "" { + baseDir = DefaultPathRoot + } + + baseDir, err := homedir.Expand(baseDir) + if err != nil { + return nil + } + + apiFile := path.Join(baseDir, DefaultApiFile) + + if _, err := os.Stat(apiFile); err != nil { + return nil + } + + api, err := ioutil.ReadFile(apiFile) + if err != nil { + return nil + } + + return NewApi(strings.TrimSpace(string(api))) +} + +func NewApi(url string) *HttpApi { + c := &gohttp.Client{ + Transport: &gohttp.Transport{ + Proxy: gohttp.ProxyFromEnvironment, + DisableKeepAlives: true, + }, + } + + return NewApiWithClient(url, c) +} + +func NewApiWithClient(url string, c *gohttp.Client) *HttpApi { + if a, err := ma.NewMultiaddr(url); err == nil { + _, host, err := manet.DialArgs(a) + if err == nil { + url = host + } + } + + return &HttpApi{ + url: url, + httpcli: c, + } +} + +func (api *HttpApi) request(command string, args ...string) *RequestBuilder { + return &RequestBuilder{ + command: command, + args: args, + shell: api, + } +} + +func (api *HttpApi) Unixfs() iface.UnixfsAPI { + return nil +} + +func (api *HttpApi) Block() iface.BlockAPI { + return nil +} + +func (api *HttpApi) Dag() iface.DagAPI { + return nil +} + +func (api *HttpApi) Name() iface.NameAPI { + return (*NameAPI)(api) +} + +func (api *HttpApi) Key() iface.KeyAPI { + return nil +} + +func (api *HttpApi) Pin() iface.PinAPI { + return nil +} + +func (api *HttpApi) Object() iface.ObjectAPI { + return nil +} + +func (api *HttpApi) Dht() iface.DhtAPI { + return nil +} + +func (api *HttpApi) Swarm() iface.SwarmAPI { + return nil +} + +func (api *HttpApi) PubSub() iface.PubSubAPI { + return nil +} diff --git a/client/httpapi/name.go b/client/httpapi/name.go new file mode 100644 index 000000000..41426ef57 --- /dev/null +++ b/client/httpapi/name.go @@ -0,0 +1,35 @@ +package httpapi + +import ( + "context" + "github.com/ipfs/go-ipfs/core/coreapi/interface" + "github.com/ipfs/go-ipfs/core/coreapi/interface/options" +) + +type NameAPI HttpApi + +func (api *NameAPI) Publish(ctx context.Context, p iface.Path, opts ...options.NamePublishOption) (iface.IpnsEntry, error) { + return nil, ErrNotImplemented +} + +func (api *NameAPI) Search(ctx context.Context, name string, opts ...options.NameResolveOption) (<-chan iface.IpnsResult, error) { + return nil, ErrNotImplemented +} + +func (api *NameAPI) Resolve(ctx context.Context, name string, opts ...options.NameResolveOption) (iface.Path, error) { + // TODO: options! + + req := api.core().request("name/resolve") + req.Arguments(name) + + var out struct{ Path string } + if err := req.Exec(ctx, &out); err != nil { + return nil, err + } + + return iface.ParsePath(out.Path) +} + +func (api *NameAPI) core() *HttpApi { + return (*HttpApi)(api) +} diff --git a/client/httpapi/path.go b/client/httpapi/path.go new file mode 100644 index 000000000..28656fbd4 --- /dev/null +++ b/client/httpapi/path.go @@ -0,0 +1,48 @@ +package httpapi + +import ( + "context" + + "github.com/ipfs/go-ipfs/core/coreapi/interface" + + cid "gx/ipfs/QmR8BauakNcBa3RbE4nbQu76PDiJgoQgz8AJdhJuiU4TAw/go-cid" + ipfspath "gx/ipfs/QmRG3XuGwT7GYuAqgWDJBKTzdaHMwAnc1x7J2KHEXNHxzG/go-path" + ipld "gx/ipfs/QmcKKBwfz6FyQdHR2jsXrrF6XeSBXYL86anmWNewpFpoF5/go-ipld-format" +) + +func (api *HttpApi) ResolvePath(ctx context.Context, path iface.Path) (iface.ResolvedPath, error) { + var out struct { + Cid cid.Cid + RemPath string + } + + //TODO: this is hacky, fixing https://github.com/ipfs/go-ipfs/issues/5703 would help + + var err error + if path.Namespace() == "ipns" { + if path, err = api.Name().Resolve(ctx, path.String()); err != nil { + return nil, err + } + } + + if err := api.request("dag/resolve", path.String()).Exec(ctx, &out); err != nil { + return nil, err + } + + // TODO: + ipath, err := ipfspath.FromSegments("/" +path.Namespace() + "/", out.Cid.String(), out.RemPath) + if err != nil { + return nil, err + } + + root, err := cid.Parse(ipfspath.Path(path.String()).Segments()[1]) + if err != nil { + return nil, err + } + + return iface.NewResolvedPath(ipath, out.Cid, root, out.RemPath), nil +} + +func (api *HttpApi) ResolveNode(context.Context, iface.Path) (ipld.Node, error) { + return nil, ErrNotImplemented +} diff --git a/client/httpapi/request.go b/client/httpapi/request.go new file mode 100644 index 000000000..58c61ac67 --- /dev/null +++ b/client/httpapi/request.go @@ -0,0 +1,34 @@ +package httpapi + +import ( + "context" + "io" + "strings" +) + +type Request struct { + ApiBase string + Command string + Args []string + Opts map[string]string + Body io.Reader + Headers map[string]string +} + +func NewRequest(ctx context.Context, url, command string, args ...string) *Request { + if !strings.HasPrefix(url, "http") { + url = "http://" + url + } + + opts := map[string]string{ + "encoding": "json", + "stream-channels": "true", + } + return &Request{ + ApiBase: url + "/api/v0", + Command: command, + Args: args, + Opts: opts, + Headers: make(map[string]string), + } +} diff --git a/client/httpapi/requestbuilder.go b/client/httpapi/requestbuilder.go new file mode 100644 index 000000000..9ccc8cf97 --- /dev/null +++ b/client/httpapi/requestbuilder.go @@ -0,0 +1,100 @@ +package httpapi + +import ( + "bytes" + "context" + "fmt" + "io" + "strconv" + "strings" +) + +// RequestBuilder is an IPFS commands request builder. +type RequestBuilder struct { + command string + args []string + opts map[string]string + headers map[string]string + body io.Reader + + shell *HttpApi +} + +// Arguments adds the arguments to the args. +func (r *RequestBuilder) Arguments(args ...string) *RequestBuilder { + r.args = append(r.args, args...) + return r +} + +// BodyString sets the request body to the given string. +func (r *RequestBuilder) BodyString(body string) *RequestBuilder { + return r.Body(strings.NewReader(body)) +} + +// BodyBytes sets the request body to the given buffer. +func (r *RequestBuilder) BodyBytes(body []byte) *RequestBuilder { + return r.Body(bytes.NewReader(body)) +} + +// Body sets the request body to the given reader. +func (r *RequestBuilder) Body(body io.Reader) *RequestBuilder { + r.body = body + return r +} + +// Option sets the given option. +func (r *RequestBuilder) Option(key string, value interface{}) *RequestBuilder { + var s string + switch v := value.(type) { + case bool: + s = strconv.FormatBool(v) + case string: + s = v + case []byte: + s = string(v) + default: + // slow case. + s = fmt.Sprint(value) + } + if r.opts == nil { + r.opts = make(map[string]string, 1) + } + r.opts[key] = s + return r +} + +// Header sets the given header. +func (r *RequestBuilder) Header(name, value string) *RequestBuilder { + if r.headers == nil { + r.headers = make(map[string]string, 1) + } + r.headers[name] = value + return r +} + +// Send sends the request and return the response. +func (r *RequestBuilder) Send(ctx context.Context) (*Response, error) { + req := NewRequest(ctx, r.shell.url, r.command, r.args...) + req.Opts = r.opts + req.Headers = r.headers + req.Body = r.body + return req.Send(r.shell.httpcli) +} + +// Exec sends the request a request and decodes the response. +func (r *RequestBuilder) Exec(ctx context.Context, res interface{}) error { + httpRes, err := r.Send(ctx) + if err != nil { + return err + } + + if res == nil { + httpRes.Close() + if httpRes.Error != nil { + return httpRes.Error + } + return nil + } + + return httpRes.Decode(res) +} diff --git a/client/httpapi/response.go b/client/httpapi/response.go new file mode 100644 index 000000000..27709769b --- /dev/null +++ b/client/httpapi/response.go @@ -0,0 +1,132 @@ +package httpapi + +import ( + "encoding/json" + "fmt" + "io" + "io/ioutil" + "net/http" + "net/url" + "os" + "strings" + + files "github.com/ipfs/go-ipfs-files" +) + +type Response struct { + Output io.ReadCloser + Error *Error +} + +func (r *Response) Close() error { + if r.Output != nil { + // always drain output (response body) + ioutil.ReadAll(r.Output) + return r.Output.Close() + } + return nil +} + +func (r *Response) Decode(dec interface{}) error { + defer r.Close() + if r.Error != nil { + return r.Error + } + + return json.NewDecoder(r.Output).Decode(dec) +} + +type Error struct { + Command string + Message string + Code int +} + +func (e *Error) Error() string { + var out string + if e.Command != "" { + out = e.Command + ": " + } + if e.Code != 0 { + out = fmt.Sprintf("%s%d: ", out, e.Code) + } + return out + e.Message +} + +func (r *Request) Send(c *http.Client) (*Response, error) { + url := r.getURL() + req, err := http.NewRequest("POST", url, r.Body) + if err != nil { + return nil, err + } + + // Add any headers that were supplied via the RequestBuilder. + for k, v := range r.Headers { + req.Header.Add(k, v) + } + + if fr, ok := r.Body.(*files.MultiFileReader); ok { + req.Header.Set("Content-Type", "multipart/form-data; boundary="+fr.Boundary()) + req.Header.Set("Content-Disposition", "form-data: name=\"files\"") + } + + resp, err := c.Do(req) + if err != nil { + return nil, err + } + + contentType := resp.Header.Get("Content-Type") + parts := strings.Split(contentType, ";") + contentType = parts[0] + + nresp := new(Response) + + nresp.Output = resp.Body + if resp.StatusCode >= http.StatusBadRequest { + e := &Error{ + Command: r.Command, + } + switch { + case resp.StatusCode == http.StatusNotFound: + e.Message = "command not found" + case contentType == "text/plain": + out, err := ioutil.ReadAll(resp.Body) + if err != nil { + fmt.Fprintf(os.Stderr, "ipfs-shell: warning! response (%d) read error: %s\n", resp.StatusCode, err) + } + e.Message = string(out) + case contentType == "application/json": + if err = json.NewDecoder(resp.Body).Decode(e); err != nil { + fmt.Fprintf(os.Stderr, "ipfs-shell: warning! response (%d) unmarshall error: %s\n", resp.StatusCode, err) + } + default: + fmt.Fprintf(os.Stderr, "ipfs-shell: warning! unhandled response (%d) encoding: %s", resp.StatusCode, contentType) + out, err := ioutil.ReadAll(resp.Body) + if err != nil { + fmt.Fprintf(os.Stderr, "ipfs-shell: response (%d) read error: %s\n", resp.StatusCode, err) + } + e.Message = fmt.Sprintf("unknown ipfs-shell error encoding: %q - %q", contentType, out) + } + nresp.Error = e + nresp.Output = nil + + // drain body and close + ioutil.ReadAll(resp.Body) + resp.Body.Close() + } + + return nresp, nil +} + +func (r *Request) getURL() string { + + values := make(url.Values) + for _, arg := range r.Args { + values.Add("arg", arg) + } + for k, v := range r.Opts { + values.Add(k, v) + } + + return fmt.Sprintf("%s/%s?%s", r.ApiBase, r.Command, values.Encode()) +} From 35c271e3d88725a9ab25be40c1837435de110a7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 6 Nov 2018 14:40:02 +0100 Subject: [PATCH 0147/1212] wip notice in readme This commit was moved from ipfs/go-ipfs-http-client@e823507553ca82115e303e1ba26f76b83f5bd12c --- client/httpapi/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/client/httpapi/README.md b/client/httpapi/README.md index ab37a4cf8..dd09142e3 100644 --- a/client/httpapi/README.md +++ b/client/httpapi/README.md @@ -8,6 +8,8 @@ > IPFS CoreAPI implementation using HTTP API +This project is WIP, use https://github.com/ipfs/go-ipfs-api for now + ## Documentation https://godoc.org/github.com/ipfs/go-ipfs-http-api From 6c927fd9624807e124f0376445c41daaa975fbd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 6 Nov 2018 14:38:11 +0100 Subject: [PATCH 0148/1212] Partial ipld node impl This commit was moved from ipfs/go-ipfs-http-client@df916c7849d6cfd7f479c4fe80c0f75d6705a0fc --- client/httpapi/api.go | 6 +-- client/httpapi/block.go | 40 ++++++++++++++ client/httpapi/ipldnode.go | 107 +++++++++++++++++++++++++++++++++++++ client/httpapi/path.go | 2 +- 4 files changed, 151 insertions(+), 4 deletions(-) create mode 100644 client/httpapi/block.go create mode 100644 client/httpapi/ipldnode.go diff --git a/client/httpapi/api.go b/client/httpapi/api.go index 82e030350..cd3fb9fd0 100644 --- a/client/httpapi/api.go +++ b/client/httpapi/api.go @@ -1,7 +1,7 @@ package httpapi import ( - "github.com/pkg/errors" + "errors" "io/ioutil" gohttp "net/http" "os" @@ -12,7 +12,7 @@ import ( homedir "github.com/mitchellh/go-homedir" ma "github.com/multiformats/go-multiaddr" manet "github.com/multiformats/go-multiaddr-net" - ) +) const ( DefaultPathName = ".ipfs" @@ -91,7 +91,7 @@ func (api *HttpApi) Unixfs() iface.UnixfsAPI { } func (api *HttpApi) Block() iface.BlockAPI { - return nil + return (*BlockAPI)(api) } func (api *HttpApi) Dag() iface.DagAPI { diff --git a/client/httpapi/block.go b/client/httpapi/block.go new file mode 100644 index 000000000..8bdb4c502 --- /dev/null +++ b/client/httpapi/block.go @@ -0,0 +1,40 @@ +package httpapi + +import ( + "context" + "io" + + "github.com/ipfs/go-ipfs/core/coreapi/interface" + "github.com/ipfs/go-ipfs/core/coreapi/interface/options" +) + +type BlockAPI HttpApi + +func (api *BlockAPI) Put(ctx context.Context, r io.Reader, opts ...options.BlockPutOption) (iface.BlockStat, error) { + return nil, ErrNotImplemented +} + +func (api *BlockAPI) Get(ctx context.Context, p iface.Path) (io.Reader, error) { + resp, err := api.core().request("block/get", p.String()).Send(context.Background()) + if err != nil { + return nil, err + } + + //TODO: is close on the reader enough? + //defer resp.Close() + + //TODO: make blockApi return ReadCloser + return resp.Output, resp.Error +} + +func (api *BlockAPI) Rm(ctx context.Context, p iface.Path, opts ...options.BlockRmOption) error { + return ErrNotImplemented +} + +func (api *BlockAPI) Stat(ctx context.Context, p iface.Path) (iface.BlockStat, error) { + return nil, ErrNotImplemented +} + +func (api *BlockAPI) core() *HttpApi { + return (*HttpApi)(api) +} diff --git a/client/httpapi/ipldnode.go b/client/httpapi/ipldnode.go new file mode 100644 index 000000000..a3dd6204b --- /dev/null +++ b/client/httpapi/ipldnode.go @@ -0,0 +1,107 @@ +package httpapi + +import ( + "context" + "fmt" + "github.com/pkg/errors" + "gx/ipfs/QmR8BauakNcBa3RbE4nbQu76PDiJgoQgz8AJdhJuiU4TAw/go-cid" + "io/ioutil" + "strconv" + + "github.com/ipfs/go-ipfs/core/coreapi/interface" + + ipfspath "gx/ipfs/QmRG3XuGwT7GYuAqgWDJBKTzdaHMwAnc1x7J2KHEXNHxzG/go-path" + ipld "gx/ipfs/QmcKKBwfz6FyQdHR2jsXrrF6XeSBXYL86anmWNewpFpoF5/go-ipld-format" +) + +type ipldNode struct { + ctx context.Context //TODO: should we re-consider adding ctx to ipld interfaces? + path iface.ResolvedPath + api *HttpApi +} + +func (n *ipldNode) RawData() []byte { + r, err := n.api.Block().Get(n.ctx, n.path) + if err != nil { + panic(err) // TODO: eww, should we add errors too / better ideas? + } + + b, err := ioutil.ReadAll(r) + if err != nil { + panic(err) + } + + return b +} + +func (n *ipldNode) Cid() cid.Cid { + return n.path.Cid() +} + +func (n *ipldNode) String() string { + return fmt.Sprintf("[Block %s]", n.Cid()) +} + +func (n *ipldNode) Loggable() map[string]interface{} { + return nil //TODO: we can't really do better here, can we? +} + +// TODO: should we use 'full'/real ipld codecs for this? js-ipfs-api does that. +// We can also give people a choice +func (n *ipldNode) Resolve(path []string) (interface{}, []string, error) { + p := ipfspath.Join([]string{n.path.String(), ipfspath.Join(path)}) + + var out interface{} + n.api.request("dag/get", p).Exec(n.ctx, &out) + + // TODO: this is more than likely wrong, fix if we decide to stick with this 'http-ipld-node' hack + for len(path) > 0 { + switch o := out.(type) { + case map[string]interface{}: + v, ok := o[path[0]] + if !ok { + // TODO: ipld links + return nil, nil, errors.New("no element under this path") + } + out = v + case []interface{}: + n, err := strconv.ParseUint(path[0], 10, 32) + if err != nil { + return nil, nil, err + } + if len(o) < int(n) { + return nil, nil, errors.New("no element under this path") + } + out = o[n] + } + path = path[1:] + } + + return out, path, nil +} + +func (n *ipldNode) Tree(path string, depth int) []string { + panic("implement me") +} + +func (n *ipldNode) ResolveLink(path []string) (*ipld.Link, []string, error) { + panic("implement me") +} + +func (n *ipldNode) Copy() ipld.Node { + panic("implement me") +} + +func (n *ipldNode) Links() []*ipld.Link { + panic("implement me") +} + +func (n *ipldNode) Stat() (*ipld.NodeStat, error) { + panic("implement me") +} + +func (n *ipldNode) Size() (uint64, error) { + panic("implement me") +} + +var _ ipld.Node = &ipldNode{} diff --git a/client/httpapi/path.go b/client/httpapi/path.go index 28656fbd4..6b6e4b027 100644 --- a/client/httpapi/path.go +++ b/client/httpapi/path.go @@ -30,7 +30,7 @@ func (api *HttpApi) ResolvePath(ctx context.Context, path iface.Path) (iface.Res } // TODO: - ipath, err := ipfspath.FromSegments("/" +path.Namespace() + "/", out.Cid.String(), out.RemPath) + ipath, err := ipfspath.FromSegments("/"+path.Namespace()+"/", out.Cid.String(), out.RemPath) if err != nil { return nil, err } From 187f6a306b6fa567dc3bd0abd94e31dd4d57af9a Mon Sep 17 00:00:00 2001 From: hannahhoward Date: Sat, 10 Nov 2018 18:37:06 -0800 Subject: [PATCH 0149/1212] Update go-ipfs-delay and assoc deps License: MIT Signed-off-by: hannahhoward This commit was moved from ipfs/interface-go-ipfs-core@20ca7387bd766e8a03ba3d7675d4d611a3a3fdab This commit was moved from ipfs/boxo@cd374fff52aec080e9faa17753d6fc104c1bd4ae --- core/coreiface/dht.go | 2 +- core/coreiface/options/unixfs.go | 2 +- core/coreiface/path.go | 2 +- core/coreiface/swarm.go | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/core/coreiface/dht.go b/core/coreiface/dht.go index c4eef9379..243f1292c 100644 --- a/core/coreiface/dht.go +++ b/core/coreiface/dht.go @@ -5,7 +5,7 @@ import ( "github.com/ipfs/go-ipfs/core/coreapi/interface/options" - pstore "gx/ipfs/QmUymf8fJtideyv3z727BcZUifGBjMZMpCJqu3Gxk5aRUk/go-libp2p-peerstore" + pstore "gx/ipfs/QmQAGG1zxfePqj2t7bLxyN8AFccZ889DDR9Gn8kVLDrGZo/go-libp2p-peerstore" peer "gx/ipfs/QmcqU6QUDSXprb1518vYDGczrTJTyGwLG9eUa5iNX4xUtS/go-libp2p-peer" ) diff --git a/core/coreiface/options/unixfs.go b/core/coreiface/options/unixfs.go index 9b0683a11..742aa6f9e 100644 --- a/core/coreiface/options/unixfs.go +++ b/core/coreiface/options/unixfs.go @@ -5,7 +5,7 @@ import ( "fmt" cid "gx/ipfs/QmR8BauakNcBa3RbE4nbQu76PDiJgoQgz8AJdhJuiU4TAw/go-cid" - dag "gx/ipfs/QmaDBne4KeY3UepeqSVKYpSmQGa3q9zP6x3LfVF2UjF3Hc/go-merkledag" + dag "gx/ipfs/QmcGt25mrjuB2kKW2zhPbXVZNHc4yoTDQ65NA8m6auP2f1/go-merkledag" mh "gx/ipfs/QmerPMzPk1mJVowm8KgmoknWa4yCYvvugMPsgWmDNUvDLW/go-multihash" ) diff --git a/core/coreiface/path.go b/core/coreiface/path.go index f5e7aeb4c..0545c30d7 100644 --- a/core/coreiface/path.go +++ b/core/coreiface/path.go @@ -1,7 +1,7 @@ package iface import ( - ipfspath "gx/ipfs/QmRG3XuGwT7GYuAqgWDJBKTzdaHMwAnc1x7J2KHEXNHxzG/go-path" + ipfspath "gx/ipfs/QmVi2uUygezqaMTqs3Yzt5FcZFHJoYD4B7jQ2BELjj7ZuY/go-path" cid "gx/ipfs/QmR8BauakNcBa3RbE4nbQu76PDiJgoQgz8AJdhJuiU4TAw/go-cid" ) diff --git a/core/coreiface/swarm.go b/core/coreiface/swarm.go index b830a0817..1ecb0bb5e 100644 --- a/core/coreiface/swarm.go +++ b/core/coreiface/swarm.go @@ -5,11 +5,11 @@ import ( "errors" "time" + pstore "gx/ipfs/QmQAGG1zxfePqj2t7bLxyN8AFccZ889DDR9Gn8kVLDrGZo/go-libp2p-peerstore" ma "gx/ipfs/QmRKLtwMw131aK7ugC3G7ybpumMz78YrJe5dzneyindvG1/go-multiaddr" - net "gx/ipfs/QmRKbEchaYADxSCyyjhDh4cTrUby8ftXUb8MRLBTHQYupw/go-libp2p-net" - pstore "gx/ipfs/QmUymf8fJtideyv3z727BcZUifGBjMZMpCJqu3Gxk5aRUk/go-libp2p-peerstore" "gx/ipfs/QmZNkThpqfVXs9GNbexPrfBbXSLNYeKrE7jwFM2oqHbyqN/go-libp2p-protocol" "gx/ipfs/QmcqU6QUDSXprb1518vYDGczrTJTyGwLG9eUa5iNX4xUtS/go-libp2p-peer" + net "gx/ipfs/QmenvQQy4bFGSiHJUGupVmCRHfetg5rH3vTp9Z2f6v2KXR/go-libp2p-net" ) var ( From dda742853e04e8750589ad29a1bf3353aadbe730 Mon Sep 17 00:00:00 2001 From: Kevin Atkinson Date: Wed, 28 Nov 2018 17:21:36 -0500 Subject: [PATCH 0150/1212] Gx update go-merkledag and related deps. License: MIT Signed-off-by: Kevin Atkinson This commit was moved from ipfs/interface-go-ipfs-core@1f51fd41ce7d6160fa741a5c7699a3b5bb305540 This commit was moved from ipfs/boxo@33840cd7fb98e69e4a3795ad744faf3135dc9a9b --- core/coreiface/options/unixfs.go | 2 +- core/coreiface/path.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/coreiface/options/unixfs.go b/core/coreiface/options/unixfs.go index 742aa6f9e..4d7b61a93 100644 --- a/core/coreiface/options/unixfs.go +++ b/core/coreiface/options/unixfs.go @@ -5,7 +5,7 @@ import ( "fmt" cid "gx/ipfs/QmR8BauakNcBa3RbE4nbQu76PDiJgoQgz8AJdhJuiU4TAw/go-cid" - dag "gx/ipfs/QmcGt25mrjuB2kKW2zhPbXVZNHc4yoTDQ65NA8m6auP2f1/go-merkledag" + dag "gx/ipfs/QmdURv6Sbob8TVW2tFFve9vcEWrSUgwPqeqnXyvYhLrkyd/go-merkledag" mh "gx/ipfs/QmerPMzPk1mJVowm8KgmoknWa4yCYvvugMPsgWmDNUvDLW/go-multihash" ) diff --git a/core/coreiface/path.go b/core/coreiface/path.go index 0545c30d7..aa3b2d0c6 100644 --- a/core/coreiface/path.go +++ b/core/coreiface/path.go @@ -1,7 +1,7 @@ package iface import ( - ipfspath "gx/ipfs/QmVi2uUygezqaMTqs3Yzt5FcZFHJoYD4B7jQ2BELjj7ZuY/go-path" + ipfspath "gx/ipfs/QmQtg7N4XjAk2ZYpBjjv8B6gQprsRekabHBCnF6i46JYKJ/go-path" cid "gx/ipfs/QmR8BauakNcBa3RbE4nbQu76PDiJgoQgz8AJdhJuiU4TAw/go-cid" ) From f31d59e53839b6b5480309a1720725cb718399b4 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Fri, 7 Dec 2018 15:37:23 -0800 Subject: [PATCH 0151/1212] gx: update go-libp2p-peer Reverts the changes that allowed small keys (ed25519 keys) to be inlined. License: MIT Signed-off-by: Steven Allen This commit was moved from ipfs/interface-go-ipfs-core@2d2e05fe7cc9680e2a06a5f752e76666a17b5944 This commit was moved from ipfs/boxo@21152b6074f3bf08068a4f980775194769ba63e5 --- core/coreiface/dht.go | 4 ++-- core/coreiface/key.go | 2 +- core/coreiface/options/unixfs.go | 2 +- core/coreiface/path.go | 2 +- core/coreiface/pubsub.go | 2 +- core/coreiface/swarm.go | 6 +++--- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/core/coreiface/dht.go b/core/coreiface/dht.go index 243f1292c..e39be92c5 100644 --- a/core/coreiface/dht.go +++ b/core/coreiface/dht.go @@ -5,8 +5,8 @@ import ( "github.com/ipfs/go-ipfs/core/coreapi/interface/options" - pstore "gx/ipfs/QmQAGG1zxfePqj2t7bLxyN8AFccZ889DDR9Gn8kVLDrGZo/go-libp2p-peerstore" - peer "gx/ipfs/QmcqU6QUDSXprb1518vYDGczrTJTyGwLG9eUa5iNX4xUtS/go-libp2p-peer" + peer "gx/ipfs/QmY5Grm8pJdiSSVsYxx4uNRgweY72EmYwuSDbRnbFok3iY/go-libp2p-peer" + pstore "gx/ipfs/QmZ9zH2FnLcxv1xyzFeUpDUeo55xEhZQHgveZijcxr7TLj/go-libp2p-peerstore" ) // DhtAPI specifies the interface to the DHT diff --git a/core/coreiface/key.go b/core/coreiface/key.go index 36a74688b..f310c3cc2 100644 --- a/core/coreiface/key.go +++ b/core/coreiface/key.go @@ -5,7 +5,7 @@ import ( options "github.com/ipfs/go-ipfs/core/coreapi/interface/options" - "gx/ipfs/QmcqU6QUDSXprb1518vYDGczrTJTyGwLG9eUa5iNX4xUtS/go-libp2p-peer" + "gx/ipfs/QmY5Grm8pJdiSSVsYxx4uNRgweY72EmYwuSDbRnbFok3iY/go-libp2p-peer" ) // Key specifies the interface to Keys in KeyAPI Keystore diff --git a/core/coreiface/options/unixfs.go b/core/coreiface/options/unixfs.go index 4d7b61a93..b771896bc 100644 --- a/core/coreiface/options/unixfs.go +++ b/core/coreiface/options/unixfs.go @@ -5,7 +5,7 @@ import ( "fmt" cid "gx/ipfs/QmR8BauakNcBa3RbE4nbQu76PDiJgoQgz8AJdhJuiU4TAw/go-cid" - dag "gx/ipfs/QmdURv6Sbob8TVW2tFFve9vcEWrSUgwPqeqnXyvYhLrkyd/go-merkledag" + dag "gx/ipfs/QmdV35UHnL1FM52baPkeUo6u7Fxm2CRUkPTLRPxeF8a4Ap/go-merkledag" mh "gx/ipfs/QmerPMzPk1mJVowm8KgmoknWa4yCYvvugMPsgWmDNUvDLW/go-multihash" ) diff --git a/core/coreiface/path.go b/core/coreiface/path.go index aa3b2d0c6..57ef4c21b 100644 --- a/core/coreiface/path.go +++ b/core/coreiface/path.go @@ -1,7 +1,7 @@ package iface import ( - ipfspath "gx/ipfs/QmQtg7N4XjAk2ZYpBjjv8B6gQprsRekabHBCnF6i46JYKJ/go-path" + ipfspath "gx/ipfs/QmZErC2Ay6WuGi96CPg316PwitdwgLo6RxZRqVjJjRj2MR/go-path" cid "gx/ipfs/QmR8BauakNcBa3RbE4nbQu76PDiJgoQgz8AJdhJuiU4TAw/go-cid" ) diff --git a/core/coreiface/pubsub.go b/core/coreiface/pubsub.go index 93e429574..867c8adc4 100644 --- a/core/coreiface/pubsub.go +++ b/core/coreiface/pubsub.go @@ -6,7 +6,7 @@ import ( options "github.com/ipfs/go-ipfs/core/coreapi/interface/options" - peer "gx/ipfs/QmcqU6QUDSXprb1518vYDGczrTJTyGwLG9eUa5iNX4xUtS/go-libp2p-peer" + peer "gx/ipfs/QmY5Grm8pJdiSSVsYxx4uNRgweY72EmYwuSDbRnbFok3iY/go-libp2p-peer" ) // PubSubSubscription is an active PubSub subscription diff --git a/core/coreiface/swarm.go b/core/coreiface/swarm.go index 1ecb0bb5e..63d20f035 100644 --- a/core/coreiface/swarm.go +++ b/core/coreiface/swarm.go @@ -5,11 +5,11 @@ import ( "errors" "time" - pstore "gx/ipfs/QmQAGG1zxfePqj2t7bLxyN8AFccZ889DDR9Gn8kVLDrGZo/go-libp2p-peerstore" + net "gx/ipfs/QmPtFaR7BWHLAjSwLh9kXcyrgTzDpuhcWLkx8ioa9RMYnx/go-libp2p-net" ma "gx/ipfs/QmRKLtwMw131aK7ugC3G7ybpumMz78YrJe5dzneyindvG1/go-multiaddr" + "gx/ipfs/QmY5Grm8pJdiSSVsYxx4uNRgweY72EmYwuSDbRnbFok3iY/go-libp2p-peer" + pstore "gx/ipfs/QmZ9zH2FnLcxv1xyzFeUpDUeo55xEhZQHgveZijcxr7TLj/go-libp2p-peerstore" "gx/ipfs/QmZNkThpqfVXs9GNbexPrfBbXSLNYeKrE7jwFM2oqHbyqN/go-libp2p-protocol" - "gx/ipfs/QmcqU6QUDSXprb1518vYDGczrTJTyGwLG9eUa5iNX4xUtS/go-libp2p-peer" - net "gx/ipfs/QmenvQQy4bFGSiHJUGupVmCRHfetg5rH3vTp9Z2f6v2KXR/go-libp2p-net" ) var ( From 7505d2c4871eaa34dbf910902d3f43b1dfdbe0eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 26 Oct 2018 14:14:49 +0200 Subject: [PATCH 0152/1212] gx: update go-ipfs-files to 2.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@1dc26f7a3fc0c1992e3c005177cecddb3fa8e14a This commit was moved from ipfs/boxo@5a85a431f81b0ba3feb64c8adc814b09b7ebe4da --- core/coreiface/unixfs.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/coreiface/unixfs.go b/core/coreiface/unixfs.go index 002635d99..3a214085c 100644 --- a/core/coreiface/unixfs.go +++ b/core/coreiface/unixfs.go @@ -6,7 +6,7 @@ import ( options "github.com/ipfs/go-ipfs/core/coreapi/interface/options" - files "gx/ipfs/QmZMWMvWMVKCbHetJ4RgndbuEF1io2UpUxwQwtNjtYPzSC/go-ipfs-files" + files "gx/ipfs/QmXWZCd8jfaHmt4UDSnjKmGcrQMw95bDGWqEeVLVJjoANX/go-ipfs-files" ipld "gx/ipfs/QmcKKBwfz6FyQdHR2jsXrrF6XeSBXYL86anmWNewpFpoF5/go-ipld-format" ) From 20631f73bfece2e3c953e07c4a2473456ac9cd57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 26 Oct 2018 15:56:30 +0200 Subject: [PATCH 0153/1212] files2.0: fix build errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@072259200527f4b78299675bb5efbbaa715ca821 This commit was moved from ipfs/boxo@d4352730fe649983c5c9099d4ba2fba2170451f6 --- core/coreiface/unixfs.go | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/core/coreiface/unixfs.go b/core/coreiface/unixfs.go index 3a214085c..773b36dc0 100644 --- a/core/coreiface/unixfs.go +++ b/core/coreiface/unixfs.go @@ -2,9 +2,8 @@ package iface import ( "context" - "io" - options "github.com/ipfs/go-ipfs/core/coreapi/interface/options" + "github.com/ipfs/go-ipfs/core/coreapi/interface/options" files "gx/ipfs/QmXWZCd8jfaHmt4UDSnjKmGcrQMw95bDGWqEeVLVJjoANX/go-ipfs-files" ipld "gx/ipfs/QmcKKBwfz6FyQdHR2jsXrrF6XeSBXYL86anmWNewpFpoF5/go-ipld-format" @@ -18,11 +17,6 @@ type AddEvent struct { Size string `json:",omitempty"` } -type UnixfsFile interface { - files.SizeFile - io.Seeker -} - // UnixfsAPI is the basic interface to immutable files in IPFS // NOTE: This API is heavily WIP, things are guaranteed to break frequently type UnixfsAPI interface { @@ -35,7 +29,7 @@ type UnixfsAPI interface { // // Note that some implementations of this API may apply the specified context // to operations performed on the returned file - Get(context.Context, Path) (UnixfsFile, error) + Get(context.Context, Path) (files.File, error) // Ls returns the list of links in a directory Ls(context.Context, Path) ([]*ipld.Link, error) From 257add12aba544fb7bea36b972ffd8c9d8b709dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 19 Nov 2018 03:24:42 +0100 Subject: [PATCH 0154/1212] files2.0: updates for file type split MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@65f7599676af200b0b87cee47292e6a48b1c14eb This commit was moved from ipfs/boxo@2904a69ad87f9a72ce9598c08536212a6d19609d --- core/coreiface/unixfs.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/coreiface/unixfs.go b/core/coreiface/unixfs.go index 773b36dc0..589083c6b 100644 --- a/core/coreiface/unixfs.go +++ b/core/coreiface/unixfs.go @@ -23,13 +23,13 @@ type UnixfsAPI interface { // Add imports the data from the reader into merkledag file // // TODO: a long useful comment on how to use this for many different scenarios - Add(context.Context, files.File, ...options.UnixfsAddOption) (ResolvedPath, error) + Add(context.Context, files.Node, ...options.UnixfsAddOption) (ResolvedPath, error) // Get returns a read-only handle to a file tree referenced by a path // // Note that some implementations of this API may apply the specified context // to operations performed on the returned file - Get(context.Context, Path) (files.File, error) + Get(context.Context, Path) (files.Node, error) // Ls returns the list of links in a directory Ls(context.Context, Path) ([]*ipld.Link, error) From bee62f1823b1eb2c2cac33e60a449c3dd8ad69e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 18 Dec 2018 02:09:43 +0100 Subject: [PATCH 0155/1212] files2.0: address review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@d68c62b157814c099608799f543888595fdb8fd5 This commit was moved from ipfs/boxo@0e2ab3797e3ea5f3d78d72f7f8b646e22772e2dd --- core/coreiface/errors.go | 1 + 1 file changed, 1 insertion(+) diff --git a/core/coreiface/errors.go b/core/coreiface/errors.go index 4ee3026ff..234abe566 100644 --- a/core/coreiface/errors.go +++ b/core/coreiface/errors.go @@ -4,5 +4,6 @@ import "errors" var ( ErrIsDir = errors.New("this dag node is a directory") + ErrNotFile = errors.New("this dag node is not a regular file") ErrOffline = errors.New("this action must be run in online mode, try running 'ipfs daemon' first") ) From 1cd2ec05b7524e921f58750a4b9c8f48ad1a2e8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 20 Dec 2018 16:04:19 +0100 Subject: [PATCH 0156/1212] Init gx This commit was moved from ipfs/go-ipfs-http-client@e06cddbedd360b1982e414571dd08ab25df38546 --- client/httpapi/ipldnode.go | 8 ++++---- client/httpapi/name.go | 1 + client/httpapi/path.go | 6 +++--- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/client/httpapi/ipldnode.go b/client/httpapi/ipldnode.go index a3dd6204b..b8e6fba01 100644 --- a/client/httpapi/ipldnode.go +++ b/client/httpapi/ipldnode.go @@ -2,16 +2,16 @@ package httpapi import ( "context" + "errors" "fmt" - "github.com/pkg/errors" - "gx/ipfs/QmR8BauakNcBa3RbE4nbQu76PDiJgoQgz8AJdhJuiU4TAw/go-cid" "io/ioutil" "strconv" "github.com/ipfs/go-ipfs/core/coreapi/interface" - ipfspath "gx/ipfs/QmRG3XuGwT7GYuAqgWDJBKTzdaHMwAnc1x7J2KHEXNHxzG/go-path" - ipld "gx/ipfs/QmcKKBwfz6FyQdHR2jsXrrF6XeSBXYL86anmWNewpFpoF5/go-ipld-format" + "github.com/ipfs/go-cid" + ipld "github.com/ipfs/go-ipld-format" + ipfspath "github.com/ipfs/go-path" ) type ipldNode struct { diff --git a/client/httpapi/name.go b/client/httpapi/name.go index 41426ef57..7315ac2c3 100644 --- a/client/httpapi/name.go +++ b/client/httpapi/name.go @@ -2,6 +2,7 @@ package httpapi import ( "context" + "github.com/ipfs/go-ipfs/core/coreapi/interface" "github.com/ipfs/go-ipfs/core/coreapi/interface/options" ) diff --git a/client/httpapi/path.go b/client/httpapi/path.go index 6b6e4b027..5701326fc 100644 --- a/client/httpapi/path.go +++ b/client/httpapi/path.go @@ -5,9 +5,9 @@ import ( "github.com/ipfs/go-ipfs/core/coreapi/interface" - cid "gx/ipfs/QmR8BauakNcBa3RbE4nbQu76PDiJgoQgz8AJdhJuiU4TAw/go-cid" - ipfspath "gx/ipfs/QmRG3XuGwT7GYuAqgWDJBKTzdaHMwAnc1x7J2KHEXNHxzG/go-path" - ipld "gx/ipfs/QmcKKBwfz6FyQdHR2jsXrrF6XeSBXYL86anmWNewpFpoF5/go-ipld-format" + cid "github.com/ipfs/go-cid" + ipld "github.com/ipfs/go-ipld-format" + ipfspath "github.com/ipfs/go-path" ) func (api *HttpApi) ResolvePath(ctx context.Context, path iface.Path) (iface.ResolvedPath, error) { From f24ab99f72cfd21bd1db9c781da52ea0e9ca0945 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 6 Dec 2018 10:47:51 +0100 Subject: [PATCH 0157/1212] coreapi: Global options for api constructor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@84509e38781da3257c7a82d09483b4c7d9188a10 This commit was moved from ipfs/boxo@3d132ddab18ee64dc731918e08fd4548d1b335dc --- core/coreiface/options/global.go | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 core/coreiface/options/global.go diff --git a/core/coreiface/options/global.go b/core/coreiface/options/global.go new file mode 100644 index 000000000..f43965229 --- /dev/null +++ b/core/coreiface/options/global.go @@ -0,0 +1,32 @@ +package options + +type ApiSettings struct { + Offline bool +} + +type ApiOption func(*ApiSettings) error + +func ApiOptions(opts ...ApiOption) (*ApiSettings, error) { + options := &ApiSettings{ + Offline: false, + } + + for _, opt := range opts { + err := opt(options) + if err != nil { + return nil, err + } + } + return options, nil +} + +type apiOpts struct{} + +var Api dagOpts + +func (dagOpts) Offline(offline bool) ApiOption { + return func(settings *ApiSettings) error { + settings.Offline = offline + return nil + } +} From 5da159b33c400648d67d20e25d17b23043fb590c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 10 Dec 2018 14:21:19 +0100 Subject: [PATCH 0158/1212] coreapi.WithOptions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@7b478b88d1f788045344cede17f73e2f9b21d680 This commit was moved from ipfs/boxo@6d52ba5bb4ccdda79fb3a55fbc1d024bee208c6e --- core/coreiface/coreapi.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/core/coreiface/coreapi.go b/core/coreiface/coreapi.go index bab4fc13b..226399967 100644 --- a/core/coreiface/coreapi.go +++ b/core/coreiface/coreapi.go @@ -5,6 +5,8 @@ package iface import ( "context" + "github.com/ipfs/go-ipfs/core/coreapi/interface/options" + ipld "gx/ipfs/QmcKKBwfz6FyQdHR2jsXrrF6XeSBXYL86anmWNewpFpoF5/go-ipld-format" ) @@ -46,4 +48,8 @@ type CoreAPI interface { // ResolveNode resolves the path (if not resolved already) using Unixfs // resolver, gets and returns the resolved Node ResolveNode(context.Context, Path) (ipld.Node, error) + + // WithOptions creates new instance of CoreAPI based on this instance with + // a set of options applied + WithOptions(...options.ApiOption) (CoreAPI, error) } From 322654a45ffaaada90c2237e33212ca83898e6a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 10 Dec 2018 14:31:19 +0100 Subject: [PATCH 0159/1212] coreapi: drop nameopt.Local in favour of api.Offline MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@42d3b2edfa9d76d00e9fb2b86f6ab35ee15a0c0d This commit was moved from ipfs/boxo@57bf11c1602f87c424c2b0309d89642ef6d7d0d0 --- core/coreiface/options/name.go | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/core/coreiface/options/name.go b/core/coreiface/options/name.go index c614db3ab..e2a0fc164 100644 --- a/core/coreiface/options/name.go +++ b/core/coreiface/options/name.go @@ -20,7 +20,6 @@ type NamePublishSettings struct { } type NameResolveSettings struct { - Local bool Cache bool ResolveOpts []ropts.ResolveOpt @@ -49,7 +48,6 @@ func NamePublishOptions(opts ...NamePublishOption) (*NamePublishSettings, error) func NameResolveOptions(opts ...NameResolveOption) (*NameResolveSettings, error) { options := &NameResolveSettings{ - Local: false, Cache: true, } @@ -106,15 +104,6 @@ func (nameOpts) TTL(ttl time.Duration) NamePublishOption { } } -// Local is an option for Name.Resolve which specifies if the lookup should be -// offline. Default value is false -func (nameOpts) Local(local bool) NameResolveOption { - return func(settings *NameResolveSettings) error { - settings.Local = local - return nil - } -} - // Cache is an option for Name.Resolve which specifies if cache should be used. // Default value is true func (nameOpts) Cache(cache bool) NameResolveOption { From 2230c18f333eb14d63641f437559da445366e42e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 10 Dec 2018 15:26:27 +0100 Subject: [PATCH 0160/1212] coreapi: implement --local with Offline option MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@286ea29c95a4d398c9a4b08fc5d24494e0c5d7c1 This commit was moved from ipfs/boxo@3b8f8c7c8238d5fbd913ab0fb13f466ec3313e97 --- core/coreiface/options/unixfs.go | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/core/coreiface/options/unixfs.go b/core/coreiface/options/unixfs.go index b771896bc..fd748bb4a 100644 --- a/core/coreiface/options/unixfs.go +++ b/core/coreiface/options/unixfs.go @@ -30,7 +30,6 @@ type UnixfsAddSettings struct { Pin bool OnlyHash bool - Local bool FsCache bool NoCopy bool @@ -60,7 +59,6 @@ func UnixfsAddOptions(opts ...UnixfsAddOption) (*UnixfsAddSettings, cid.Prefix, Pin: false, OnlyHash: false, - Local: false, FsCache: false, NoCopy: false, @@ -220,16 +218,6 @@ func (unixfsOpts) HashOnly(hashOnly bool) UnixfsAddOption { } } -// Local will add the data to blockstore without announcing it to the network -// -// Note that this doesn't prevent other nodes from getting this data -func (unixfsOpts) Local(local bool) UnixfsAddOption { - return func(settings *UnixfsAddSettings) error { - settings.Local = local - return nil - } -} - // Wrap tells the adder to wrap the added file structure with an additional // directory. func (unixfsOpts) Wrap(wrap bool) UnixfsAddOption { From cd14497b17c5d772f183e4922552420e4999e304 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 11 Dec 2018 22:24:40 +0100 Subject: [PATCH 0161/1212] coreapi WithOptions: apply on top of parent options MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@3956a72f07973de428f73776571af0518872e87c This commit was moved from ipfs/boxo@e84f354e2490ba03d16798213311feb0ef47b59c --- core/coreiface/options/global.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/core/coreiface/options/global.go b/core/coreiface/options/global.go index f43965229..93d635e41 100644 --- a/core/coreiface/options/global.go +++ b/core/coreiface/options/global.go @@ -11,6 +11,10 @@ func ApiOptions(opts ...ApiOption) (*ApiSettings, error) { Offline: false, } + return ApiOptionsTo(options, opts...) +} + +func ApiOptionsTo(options *ApiSettings, opts ...ApiOption) (*ApiSettings, error) { for _, opt := range opts { err := opt(options) if err != nil { @@ -22,9 +26,9 @@ func ApiOptions(opts ...ApiOption) (*ApiSettings, error) { type apiOpts struct{} -var Api dagOpts +var Api apiOpts -func (dagOpts) Offline(offline bool) ApiOption { +func (apiOpts) Offline(offline bool) ApiOption { return func(settings *ApiSettings) error { settings.Offline = offline return nil From 16e97bf5e8f80b681c5a8d4b96f406b4b83a8e1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 21 Dec 2018 18:44:34 +0100 Subject: [PATCH 0162/1212] It builds This commit was moved from ipfs/go-ipfs-http-client@a23d794e5fceadb9115d8d0c8466c10e9c5d0891 --- client/httpapi/api.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/client/httpapi/api.go b/client/httpapi/api.go index cd3fb9fd0..dc9acb9f6 100644 --- a/client/httpapi/api.go +++ b/client/httpapi/api.go @@ -9,6 +9,7 @@ import ( "strings" "github.com/ipfs/go-ipfs/core/coreapi/interface" + "github.com/ipfs/go-ipfs/core/coreapi/interface/options" homedir "github.com/mitchellh/go-homedir" ma "github.com/multiformats/go-multiaddr" manet "github.com/multiformats/go-multiaddr-net" @@ -78,6 +79,10 @@ func NewApiWithClient(url string, c *gohttp.Client) *HttpApi { } } +func (api *HttpApi) WithOptions(...options.ApiOption) (iface.CoreAPI, error) { + return nil, ErrNotImplemented +} + func (api *HttpApi) request(command string, args ...string) *RequestBuilder { return &RequestBuilder{ command: command, From 1208d736c479be0d54acb55028d07cdcd541e2f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 18 Dec 2018 14:23:55 +0100 Subject: [PATCH 0163/1212] coreapi/unixfs: Use path instead of raw hash in AddEvent MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@a1cf89b78a61aef35a4893f916e14e39cd5c9157 This commit was moved from ipfs/boxo@b5e06d34876da3759fa39fb18f557085e27f76d0 --- core/coreiface/path.go | 1 + core/coreiface/unixfs.go | 7 +++---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/core/coreiface/path.go b/core/coreiface/path.go index 57ef4c21b..01dda97d5 100644 --- a/core/coreiface/path.go +++ b/core/coreiface/path.go @@ -46,6 +46,7 @@ type ResolvedPath interface { // cidRoot := {"A": {"/": cidA }} // // And resolve paths: + // // * "/ipfs/${cidRoot}" // * Calling Cid() will return `cidRoot` // * Calling Root() will return `cidRoot` diff --git a/core/coreiface/unixfs.go b/core/coreiface/unixfs.go index 589083c6b..b42b454cc 100644 --- a/core/coreiface/unixfs.go +++ b/core/coreiface/unixfs.go @@ -9,12 +9,11 @@ import ( ipld "gx/ipfs/QmcKKBwfz6FyQdHR2jsXrrF6XeSBXYL86anmWNewpFpoF5/go-ipld-format" ) -// TODO: ideas on making this more coreapi-ish without breaking the http API? type AddEvent struct { Name string - Hash string `json:",omitempty"` - Bytes int64 `json:",omitempty"` - Size string `json:",omitempty"` + Path ResolvedPath `json:",omitempty"` + Bytes int64 `json:",omitempty"` + Size string `json:",omitempty"` } // UnixfsAPI is the basic interface to immutable files in IPFS From fe4c9fd8033c94c5ea707b09e76479a6d018635d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Sun, 30 Dec 2018 04:24:09 +0100 Subject: [PATCH 0164/1212] Skeleton for tests This commit was moved from ipfs/go-ipfs-http-client@dfbe0026ad9438d4e795bbb43debeffb6bb9ca1a --- client/httpapi/api.go | 24 ++++++++--- client/httpapi/api_test.go | 84 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 103 insertions(+), 5 deletions(-) create mode 100644 client/httpapi/api_test.go diff --git a/client/httpapi/api.go b/client/httpapi/api.go index dc9acb9f6..63ea3aad7 100644 --- a/client/httpapi/api.go +++ b/client/httpapi/api.go @@ -35,7 +35,11 @@ func NewLocalApi() iface.CoreAPI { baseDir = DefaultPathRoot } - baseDir, err := homedir.Expand(baseDir) + return NewPathApi(baseDir) +} + +func NewPathApi(p string) iface.CoreAPI { + baseDir, err := homedir.Expand(p) if err != nil { return nil } @@ -51,10 +55,15 @@ func NewLocalApi() iface.CoreAPI { return nil } - return NewApi(strings.TrimSpace(string(api))) + maddr, err := ma.NewMultiaddr(strings.TrimSpace(string(api))) + if err != nil { + return nil + } + + return NewApi(maddr) } -func NewApi(url string) *HttpApi { +func NewApi(a ma.Multiaddr) *HttpApi { // TODO: should be MAddr? c := &gohttp.Client{ Transport: &gohttp.Transport{ Proxy: gohttp.ProxyFromEnvironment, @@ -62,10 +71,15 @@ func NewApi(url string) *HttpApi { }, } - return NewApiWithClient(url, c) + return NewApiWithClient(a, c) } -func NewApiWithClient(url string, c *gohttp.Client) *HttpApi { +func NewApiWithClient(a ma.Multiaddr, c *gohttp.Client) *HttpApi { + _, url, err := manet.DialArgs(a) + if err != nil { + return nil // TODO: return that error + } + if a, err := ma.NewMultiaddr(url); err == nil { _, host, err := manet.DialArgs(a) if err == nil { diff --git a/client/httpapi/api_test.go b/client/httpapi/api_test.go new file mode 100644 index 000000000..b925b5c34 --- /dev/null +++ b/client/httpapi/api_test.go @@ -0,0 +1,84 @@ +package httpapi + +import ( + "context" + "fmt" + "github.com/ipfs/iptb/testbed/interfaces" + "io/ioutil" + "os" + "path" + "strconv" + "testing" + + "github.com/ipfs/go-ipfs/core/coreapi/interface" + "github.com/ipfs/go-ipfs/core/coreapi/interface/tests" + + local "github.com/ipfs/iptb-plugins/local" + "github.com/ipfs/iptb/cli" + "github.com/ipfs/iptb/testbed" +) + +type NodeProvider struct{} + +func (NodeProvider) MakeAPISwarm(ctx context.Context, fullIdentity bool, n int) ([]iface.CoreAPI, error) { + _, err := testbed.RegisterPlugin(testbed.IptbPlugin{ + From: "", + NewNode: local.NewNode, + GetAttrList: local.GetAttrList, + GetAttrDesc: local.GetAttrDesc, + PluginName: local.PluginName, + BuiltIn: true, + }, false) + if err != nil { + return nil, err + } + + dir, err := ioutil.TempDir("", "httpapi-tb-") + if err != nil { + return nil, err + } + + c := cli.NewCli() + if err := c.Run([]string{"iptb", "--IPTB_ROOT", dir, "auto", "-type", "localipfs", "-count", strconv.FormatInt(int64(n), 10), "--start"}); err != nil { + return nil, err + } + + go func() { + <-ctx.Done() + + defer os.Remove(dir) + + defer func() { + _ = c.Run([]string{"iptb", "--IPTB_ROOT", dir, "stop"}) + }() + }() + + apis := make([]iface.CoreAPI, n) + + for i := range apis { + tb := testbed.NewTestbed(path.Join(dir, "testbeds", "default")) + + node, err := tb.Node(i) + if err != nil { + return nil, err + } + + attrNode, ok := node.(testbedi.Attribute) + if !ok { + return nil, fmt.Errorf("node does not implement attributes") + } + + pth, err := attrNode.Attr("path") + if err != nil { + return nil, err + } + + apis[i] = NewPathApi(pth) + } + + return apis, nil +} + +func TestHttpApi(t *testing.T) { + tests.TestApi(&NodeProvider{})(t) +} From e60f2ba563c6a5708ba08c8140ac517b206dfda6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 20 Dec 2018 19:45:58 +0100 Subject: [PATCH 0165/1212] coreapi: move tests to interface subpackage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@a479105a40eddefc84ca1de9aaaf12cbe2e13e56 This commit was moved from ipfs/boxo@3301b037c33fd42e0deb10965447a7e26e1e86fa --- core/coreiface/tests/block_test.go | 183 ++++++ core/coreiface/tests/dag_test.go | 151 +++++ core/coreiface/tests/dht_test.go | 126 ++++ core/coreiface/tests/key_test.go | 475 ++++++++++++++ core/coreiface/tests/name_test.go | 262 ++++++++ core/coreiface/tests/object_test.go | 427 ++++++++++++ core/coreiface/tests/path_test.go | 154 +++++ core/coreiface/tests/pin_test.go | 214 +++++++ core/coreiface/tests/pubsub_test.go | 106 +++ core/coreiface/tests/unixfs_test.go | 963 ++++++++++++++++++++++++++++ 10 files changed, 3061 insertions(+) create mode 100644 core/coreiface/tests/block_test.go create mode 100644 core/coreiface/tests/dag_test.go create mode 100644 core/coreiface/tests/dht_test.go create mode 100644 core/coreiface/tests/key_test.go create mode 100644 core/coreiface/tests/name_test.go create mode 100644 core/coreiface/tests/object_test.go create mode 100644 core/coreiface/tests/path_test.go create mode 100644 core/coreiface/tests/pin_test.go create mode 100644 core/coreiface/tests/pubsub_test.go create mode 100644 core/coreiface/tests/unixfs_test.go diff --git a/core/coreiface/tests/block_test.go b/core/coreiface/tests/block_test.go new file mode 100644 index 000000000..81360b150 --- /dev/null +++ b/core/coreiface/tests/block_test.go @@ -0,0 +1,183 @@ +package tests_test + +import ( + "context" + "io/ioutil" + "strings" + "testing" + + coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface" + opt "github.com/ipfs/go-ipfs/core/coreapi/interface/options" + + mh "gx/ipfs/QmerPMzPk1mJVowm8KgmoknWa4yCYvvugMPsgWmDNUvDLW/go-multihash" +) + +func TestBlockPut(t *testing.T) { + ctx := context.Background() + api, err := makeAPI(ctx) + if err != nil { + t.Error(err) + } + + res, err := api.Block().Put(ctx, strings.NewReader(`Hello`)) + if err != nil { + t.Error(err) + } + + if res.Path().Cid().String() != "QmPyo15ynbVrSTVdJL9th7JysHaAbXt9dM9tXk1bMHbRtk" { + t.Errorf("got wrong cid: %s", res.Path().Cid().String()) + } +} + +func TestBlockPutFormat(t *testing.T) { + ctx := context.Background() + api, err := makeAPI(ctx) + if err != nil { + t.Error(err) + } + + res, err := api.Block().Put(ctx, strings.NewReader(`Hello`), opt.Block.Format("cbor")) + if err != nil { + t.Error(err) + } + + if res.Path().Cid().String() != "zdpuAn4amuLWo8Widi5v6VQpuo2dnpnwbVE3oB6qqs7mDSeoa" { + t.Errorf("got wrong cid: %s", res.Path().Cid().String()) + } +} + +func TestBlockPutHash(t *testing.T) { + ctx := context.Background() + api, err := makeAPI(ctx) + if err != nil { + t.Error(err) + } + + res, err := api.Block().Put(ctx, strings.NewReader(`Hello`), opt.Block.Hash(mh.KECCAK_512, -1)) + if err != nil { + t.Fatal(err) + } + + if res.Path().Cid().String() != "zBurKB9YZkcDf6xa53WBE8CFX4ydVqAyf9KPXBFZt5stJzEstaS8Hukkhu4gwpMtc1xHNDbzP7sPtQKyWsP3C8fbhkmrZ" { + t.Errorf("got wrong cid: %s", res.Path().Cid().String()) + } +} + +func TestBlockGet(t *testing.T) { + ctx := context.Background() + api, err := makeAPI(ctx) + if err != nil { + t.Error(err) + } + + res, err := api.Block().Put(ctx, strings.NewReader(`Hello`), opt.Block.Hash(mh.KECCAK_512, -1)) + if err != nil { + t.Error(err) + } + + r, err := api.Block().Get(ctx, res.Path()) + if err != nil { + t.Error(err) + } + + d, err := ioutil.ReadAll(r) + if err != nil { + t.Error(err) + } + + if string(d) != "Hello" { + t.Error("didn't get correct data back") + } + + p, err := coreiface.ParsePath("/ipfs/" + res.Path().Cid().String()) + if err != nil { + t.Error(err) + } + + rp, err := api.ResolvePath(ctx, p) + if err != nil { + t.Fatal(err) + } + if rp.Cid().String() != res.Path().Cid().String() { + t.Error("paths didn't match") + } +} + +func TestBlockRm(t *testing.T) { + ctx := context.Background() + api, err := makeAPI(ctx) + if err != nil { + t.Error(err) + } + + res, err := api.Block().Put(ctx, strings.NewReader(`Hello`)) + if err != nil { + t.Error(err) + } + + r, err := api.Block().Get(ctx, res.Path()) + if err != nil { + t.Error(err) + } + + d, err := ioutil.ReadAll(r) + if err != nil { + t.Error(err) + } + + if string(d) != "Hello" { + t.Error("didn't get correct data back") + } + + err = api.Block().Rm(ctx, res.Path()) + if err != nil { + t.Error(err) + } + + _, err = api.Block().Get(ctx, res.Path()) + if err == nil { + t.Error("expected err to exist") + } + if err.Error() != "blockservice: key not found" { + t.Errorf("unexpected error; %s", err.Error()) + } + + err = api.Block().Rm(ctx, res.Path()) + if err == nil { + t.Error("expected err to exist") + } + if err.Error() != "blockstore: block not found" { + t.Errorf("unexpected error; %s", err.Error()) + } + + err = api.Block().Rm(ctx, res.Path(), opt.Block.Force(true)) + if err != nil { + t.Error(err) + } +} + +func TestBlockStat(t *testing.T) { + ctx := context.Background() + api, err := makeAPI(ctx) + if err != nil { + t.Error(err) + } + + res, err := api.Block().Put(ctx, strings.NewReader(`Hello`)) + if err != nil { + t.Error(err) + } + + stat, err := api.Block().Stat(ctx, res.Path()) + if err != nil { + t.Error(err) + } + + if stat.Path().String() != res.Path().String() { + t.Error("paths don't match") + } + + if stat.Size() != len("Hello") { + t.Error("length doesn't match") + } +} diff --git a/core/coreiface/tests/dag_test.go b/core/coreiface/tests/dag_test.go new file mode 100644 index 000000000..17059192b --- /dev/null +++ b/core/coreiface/tests/dag_test.go @@ -0,0 +1,151 @@ +package tests_test + +import ( + "context" + "path" + "strings" + "testing" + + coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface" + opt "github.com/ipfs/go-ipfs/core/coreapi/interface/options" + + mh "gx/ipfs/QmerPMzPk1mJVowm8KgmoknWa4yCYvvugMPsgWmDNUvDLW/go-multihash" +) + +var ( + treeExpected = map[string]struct{}{ + "a": {}, + "b": {}, + "c": {}, + "c/d": {}, + "c/e": {}, + } +) + +func TestPut(t *testing.T) { + ctx := context.Background() + api, err := makeAPI(ctx) + if err != nil { + t.Error(err) + } + + res, err := api.Dag().Put(ctx, strings.NewReader(`"Hello"`)) + if err != nil { + t.Error(err) + } + + if res.Cid().String() != "zdpuAqckYF3ToF3gcJNxPZXmnmGuXd3gxHCXhq81HGxBejEvv" { + t.Errorf("got wrong cid: %s", res.Cid().String()) + } +} + +func TestPutWithHash(t *testing.T) { + ctx := context.Background() + api, err := makeAPI(ctx) + if err != nil { + t.Error(err) + } + + res, err := api.Dag().Put(ctx, strings.NewReader(`"Hello"`), opt.Dag.Hash(mh.ID, -1)) + if err != nil { + t.Error(err) + } + + if res.Cid().String() != "z5hRLNd2sv4z1c" { + t.Errorf("got wrong cid: %s", res.Cid().String()) + } +} + +func TestPath(t *testing.T) { + ctx := context.Background() + api, err := makeAPI(ctx) + if err != nil { + t.Error(err) + } + + sub, err := api.Dag().Put(ctx, strings.NewReader(`"foo"`)) + if err != nil { + t.Error(err) + } + + res, err := api.Dag().Put(ctx, strings.NewReader(`{"lnk": {"/": "`+sub.Cid().String()+`"}}`)) + if err != nil { + t.Error(err) + } + + p, err := coreiface.ParsePath(path.Join(res.Cid().String(), "lnk")) + if err != nil { + t.Error(err) + } + + nd, err := api.Dag().Get(ctx, p) + if err != nil { + t.Error(err) + } + + if nd.Cid().String() != sub.Cid().String() { + t.Errorf("got unexpected cid %s, expected %s", nd.Cid().String(), sub.Cid().String()) + } +} + +func TestTree(t *testing.T) { + ctx := context.Background() + api, err := makeAPI(ctx) + if err != nil { + t.Error(err) + } + + c, err := api.Dag().Put(ctx, strings.NewReader(`{"a": 123, "b": "foo", "c": {"d": 321, "e": 111}}`)) + if err != nil { + t.Error(err) + } + + res, err := api.Dag().Get(ctx, c) + if err != nil { + t.Error(err) + } + + lst := res.Tree("", -1) + if len(lst) != len(treeExpected) { + t.Errorf("tree length of %d doesn't match expected %d", len(lst), len(treeExpected)) + } + + for _, ent := range lst { + if _, ok := treeExpected[ent]; !ok { + t.Errorf("unexpected tree entry %s", ent) + } + } +} + +func TestBatch(t *testing.T) { + ctx := context.Background() + api, err := makeAPI(ctx) + if err != nil { + t.Error(err) + } + + batch := api.Dag().Batch(ctx) + + c, err := batch.Put(ctx, strings.NewReader(`"Hello"`)) + if err != nil { + t.Error(err) + } + + if c.Cid().String() != "zdpuAqckYF3ToF3gcJNxPZXmnmGuXd3gxHCXhq81HGxBejEvv" { + t.Errorf("got wrong cid: %s", c.Cid().String()) + } + + _, err = api.Dag().Get(ctx, c) + if err == nil || err.Error() != "merkledag: not found" { + t.Error(err) + } + + if err := batch.Commit(ctx); err != nil { + t.Error(err) + } + + _, err = api.Dag().Get(ctx, c) + if err != nil { + t.Error(err) + } +} diff --git a/core/coreiface/tests/dht_test.go b/core/coreiface/tests/dht_test.go new file mode 100644 index 000000000..be16bb083 --- /dev/null +++ b/core/coreiface/tests/dht_test.go @@ -0,0 +1,126 @@ +package tests_test + +import ( + "context" + "io" + "testing" + + "github.com/ipfs/go-ipfs/core/coreapi/interface/options" +) + +func TestDhtFindPeer(t *testing.T) { + ctx := context.Background() + apis, err := makeAPISwarm(ctx, true, 5) + if err != nil { + t.Fatal(err) + } + + self0, err := apis[0].Key().Self(ctx) + if err != nil { + t.Fatal(err) + } + + pi, err := apis[2].Dht().FindPeer(ctx, self0.ID()) + if err != nil { + t.Fatal(err) + } + + if pi.Addrs[0].String() != "/ip4/127.0.0.1/tcp/4001" { + t.Errorf("got unexpected address from FindPeer: %s", pi.Addrs[0].String()) + } + + self2, err := apis[2].Key().Self(ctx) + if err != nil { + t.Fatal(err) + } + + pi, err = apis[1].Dht().FindPeer(ctx, self2.ID()) + if err != nil { + t.Fatal(err) + } + + if pi.Addrs[0].String() != "/ip4/127.0.2.1/tcp/4001" { + t.Errorf("got unexpected address from FindPeer: %s", pi.Addrs[0].String()) + } +} + +func TestDhtFindProviders(t *testing.T) { + ctx := context.Background() + apis, err := makeAPISwarm(ctx, true, 5) + if err != nil { + t.Fatal(err) + } + + p, err := addTestObject(ctx, apis[0]) + if err != nil { + t.Fatal(err) + } + + out, err := apis[2].Dht().FindProviders(ctx, p, options.Dht.NumProviders(1)) + if err != nil { + t.Fatal(err) + } + + provider := <-out + + self0, err := apis[0].Key().Self(ctx) + if err != nil { + t.Fatal(err) + } + + if provider.ID.String() != self0.ID().String() { + t.Errorf("got wrong provider: %s != %s", provider.ID.String(), self0.ID().String()) + } +} + +func TestDhtProvide(t *testing.T) { + ctx := context.Background() + apis, err := makeAPISwarm(ctx, true, 5) + if err != nil { + t.Fatal(err) + } + + off0, err := apis[0].WithOptions(options.Api.Offline(true)) + if err != nil { + t.Fatal(err) + } + + s, err := off0.Block().Put(ctx, &io.LimitedReader{R: rnd, N: 4092}) + if err != nil { + t.Fatal(err) + } + + p := s.Path() + + out, err := apis[2].Dht().FindProviders(ctx, p, options.Dht.NumProviders(1)) + if err != nil { + t.Fatal(err) + } + + provider := <-out + + self0, err := apis[0].Key().Self(ctx) + if err != nil { + t.Fatal(err) + } + + if provider.ID.String() != "" { + t.Errorf("got wrong provider: %s != %s", provider.ID.String(), self0.ID().String()) + } + + err = apis[0].Dht().Provide(ctx, p) + if err != nil { + t.Fatal(err) + } + + out, err = apis[2].Dht().FindProviders(ctx, p, options.Dht.NumProviders(1)) + if err != nil { + t.Fatal(err) + } + + provider = <-out + + if provider.ID.String() != self0.ID().String() { + t.Errorf("got wrong provider: %s != %s", provider.ID.String(), self0.ID().String()) + } +} diff --git a/core/coreiface/tests/key_test.go b/core/coreiface/tests/key_test.go new file mode 100644 index 000000000..21884e448 --- /dev/null +++ b/core/coreiface/tests/key_test.go @@ -0,0 +1,475 @@ +package tests_test + +import ( + "context" + "strings" + "testing" + + opt "github.com/ipfs/go-ipfs/core/coreapi/interface/options" +) + +func TestListSelf(t *testing.T) { + ctx := context.Background() + api, err := makeAPI(ctx) + if err != nil { + t.Fatal(err) + return + } + + keys, err := api.Key().List(ctx) + if err != nil { + t.Fatalf("failed to list keys: %s", err) + return + } + + if len(keys) != 1 { + t.Fatalf("there should be 1 key (self), got %d", len(keys)) + return + } + + if keys[0].Name() != "self" { + t.Errorf("expected the key to be called 'self', got '%s'", keys[0].Name()) + } + + if keys[0].Path().String() != "/ipns/"+testPeerID { + t.Errorf("expected the key to have path '/ipns/%s', got '%s'", testPeerID, keys[0].Path().String()) + } +} + +func TestRenameSelf(t *testing.T) { + ctx := context.Background() + api, err := makeAPI(ctx) + if err != nil { + t.Fatal(err) + return + } + + _, _, err = api.Key().Rename(ctx, "self", "foo") + if err == nil { + t.Error("expected error to not be nil") + } else { + if err.Error() != "cannot rename key with name 'self'" { + t.Fatalf("expected error 'cannot rename key with name 'self'', got '%s'", err.Error()) + } + } + + _, _, err = api.Key().Rename(ctx, "self", "foo", opt.Key.Force(true)) + if err == nil { + t.Error("expected error to not be nil") + } else { + if err.Error() != "cannot rename key with name 'self'" { + t.Fatalf("expected error 'cannot rename key with name 'self'', got '%s'", err.Error()) + } + } +} + +func TestRemoveSelf(t *testing.T) { + ctx := context.Background() + api, err := makeAPI(ctx) + if err != nil { + t.Fatal(err) + return + } + + _, err = api.Key().Remove(ctx, "self") + if err == nil { + t.Error("expected error to not be nil") + } else { + if err.Error() != "cannot remove key with name 'self'" { + t.Fatalf("expected error 'cannot remove key with name 'self'', got '%s'", err.Error()) + } + } +} + +func TestGenerate(t *testing.T) { + ctx := context.Background() + api, err := makeAPI(ctx) + if err != nil { + t.Error(err) + } + + k, err := api.Key().Generate(ctx, "foo") + if err != nil { + t.Fatal(err) + return + } + + if k.Name() != "foo" { + t.Errorf("expected the key to be called 'foo', got '%s'", k.Name()) + } + + if !strings.HasPrefix(k.Path().String(), "/ipns/Qm") { + t.Errorf("expected the key to be prefixed with '/ipns/Qm', got '%s'", k.Path().String()) + } +} + +func TestGenerateSize(t *testing.T) { + ctx := context.Background() + api, err := makeAPI(ctx) + if err != nil { + t.Error(err) + } + + k, err := api.Key().Generate(ctx, "foo", opt.Key.Size(1024)) + if err != nil { + t.Fatal(err) + return + } + + if k.Name() != "foo" { + t.Errorf("expected the key to be called 'foo', got '%s'", k.Name()) + } + + if !strings.HasPrefix(k.Path().String(), "/ipns/Qm") { + t.Errorf("expected the key to be prefixed with '/ipns/Qm', got '%s'", k.Path().String()) + } +} + +func TestGenerateType(t *testing.T) { + ctx := context.Background() + t.Skip("disabled until libp2p/specs#111 is fixed") + + api, err := makeAPI(ctx) + if err != nil { + t.Error(err) + } + + k, err := api.Key().Generate(ctx, "bar", opt.Key.Type(opt.Ed25519Key)) + if err != nil { + t.Fatal(err) + return + } + + if k.Name() != "bar" { + t.Errorf("expected the key to be called 'foo', got '%s'", k.Name()) + } + + // Expected to be an inlined identity hash. + if !strings.HasPrefix(k.Path().String(), "/ipns/12") { + t.Errorf("expected the key to be prefixed with '/ipns/12', got '%s'", k.Path().String()) + } +} + +func TestGenerateExisting(t *testing.T) { + ctx := context.Background() + api, err := makeAPI(ctx) + if err != nil { + t.Error(err) + } + + _, err = api.Key().Generate(ctx, "foo") + if err != nil { + t.Fatal(err) + return + } + + _, err = api.Key().Generate(ctx, "foo") + if err == nil { + t.Error("expected error to not be nil") + } else { + if err.Error() != "key with name 'foo' already exists" { + t.Fatalf("expected error 'key with name 'foo' already exists', got '%s'", err.Error()) + } + } + + _, err = api.Key().Generate(ctx, "self") + if err == nil { + t.Error("expected error to not be nil") + } else { + if err.Error() != "cannot create key with name 'self'" { + t.Fatalf("expected error 'cannot create key with name 'self'', got '%s'", err.Error()) + } + } +} + +func TestList(t *testing.T) { + ctx := context.Background() + api, err := makeAPI(ctx) + if err != nil { + t.Error(err) + } + + _, err = api.Key().Generate(ctx, "foo") + if err != nil { + t.Fatal(err) + return + } + + l, err := api.Key().List(ctx) + if err != nil { + t.Fatal(err) + return + } + + if len(l) != 2 { + t.Fatalf("expected to get 2 keys, got %d", len(l)) + return + } + + if l[0].Name() != "self" { + t.Fatalf("expected key 0 to be called 'self', got '%s'", l[0].Name()) + return + } + + if l[1].Name() != "foo" { + t.Fatalf("expected key 1 to be called 'foo', got '%s'", l[1].Name()) + return + } + + if !strings.HasPrefix(l[0].Path().String(), "/ipns/Qm") { + t.Fatalf("expected key 0 to be prefixed with '/ipns/Qm', got '%s'", l[0].Name()) + return + } + + if !strings.HasPrefix(l[1].Path().String(), "/ipns/Qm") { + t.Fatalf("expected key 1 to be prefixed with '/ipns/Qm', got '%s'", l[1].Name()) + return + } +} + +func TestRename(t *testing.T) { + ctx := context.Background() + api, err := makeAPI(ctx) + if err != nil { + t.Error(err) + } + + _, err = api.Key().Generate(ctx, "foo") + if err != nil { + t.Fatal(err) + return + } + + k, overwrote, err := api.Key().Rename(ctx, "foo", "bar") + if err != nil { + t.Fatal(err) + return + } + + if overwrote { + t.Error("overwrote should be false") + } + + if k.Name() != "bar" { + t.Errorf("returned key should be called 'bar', got '%s'", k.Name()) + } +} + +func TestRenameToSelf(t *testing.T) { + ctx := context.Background() + api, err := makeAPI(ctx) + if err != nil { + t.Error(err) + } + + _, err = api.Key().Generate(ctx, "foo") + if err != nil { + t.Fatal(err) + return + } + + _, _, err = api.Key().Rename(ctx, "foo", "self") + if err == nil { + t.Error("expected error to not be nil") + } else { + if err.Error() != "cannot overwrite key with name 'self'" { + t.Fatalf("expected error 'cannot overwrite key with name 'self'', got '%s'", err.Error()) + } + } +} + +func TestRenameToSelfForce(t *testing.T) { + ctx := context.Background() + api, err := makeAPI(ctx) + if err != nil { + t.Error(err) + } + + _, err = api.Key().Generate(ctx, "foo") + if err != nil { + t.Fatal(err) + return + } + + _, _, err = api.Key().Rename(ctx, "foo", "self", opt.Key.Force(true)) + if err == nil { + t.Error("expected error to not be nil") + } else { + if err.Error() != "cannot overwrite key with name 'self'" { + t.Fatalf("expected error 'cannot overwrite key with name 'self'', got '%s'", err.Error()) + } + } +} + +func TestRenameOverwriteNoForce(t *testing.T) { + ctx := context.Background() + api, err := makeAPI(ctx) + if err != nil { + t.Error(err) + } + + _, err = api.Key().Generate(ctx, "foo") + if err != nil { + t.Fatal(err) + return + } + + _, err = api.Key().Generate(ctx, "bar") + if err != nil { + t.Fatal(err) + return + } + + _, _, err = api.Key().Rename(ctx, "foo", "bar") + if err == nil { + t.Error("expected error to not be nil") + } else { + if err.Error() != "key by that name already exists, refusing to overwrite" { + t.Fatalf("expected error 'key by that name already exists, refusing to overwrite', got '%s'", err.Error()) + } + } +} + +func TestRenameOverwrite(t *testing.T) { + ctx := context.Background() + api, err := makeAPI(ctx) + if err != nil { + t.Error(err) + } + + kfoo, err := api.Key().Generate(ctx, "foo") + if err != nil { + t.Fatal(err) + return + } + + _, err = api.Key().Generate(ctx, "bar") + if err != nil { + t.Fatal(err) + return + } + + k, overwrote, err := api.Key().Rename(ctx, "foo", "bar", opt.Key.Force(true)) + if err != nil { + t.Fatal(err) + return + } + + if !overwrote { + t.Error("overwrote should be true") + } + + if k.Name() != "bar" { + t.Errorf("returned key should be called 'bar', got '%s'", k.Name()) + } + + if k.Path().String() != kfoo.Path().String() { + t.Errorf("k and kfoo should have equal paths, '%s'!='%s'", k.Path().String(), kfoo.Path().String()) + } +} + +func TestRenameSameNameNoForce(t *testing.T) { + ctx := context.Background() + api, err := makeAPI(ctx) + if err != nil { + t.Error(err) + } + + _, err = api.Key().Generate(ctx, "foo") + if err != nil { + t.Fatal(err) + return + } + + k, overwrote, err := api.Key().Rename(ctx, "foo", "foo") + if err != nil { + t.Fatal(err) + return + } + + if overwrote { + t.Error("overwrote should be false") + } + + if k.Name() != "foo" { + t.Errorf("returned key should be called 'foo', got '%s'", k.Name()) + } +} + +func TestRenameSameName(t *testing.T) { + ctx := context.Background() + api, err := makeAPI(ctx) + if err != nil { + t.Error(err) + } + + _, err = api.Key().Generate(ctx, "foo") + if err != nil { + t.Fatal(err) + return + } + + k, overwrote, err := api.Key().Rename(ctx, "foo", "foo", opt.Key.Force(true)) + if err != nil { + t.Fatal(err) + return + } + + if overwrote { + t.Error("overwrote should be false") + } + + if k.Name() != "foo" { + t.Errorf("returned key should be called 'foo', got '%s'", k.Name()) + } +} + +func TestRemove(t *testing.T) { + ctx := context.Background() + api, err := makeAPI(ctx) + if err != nil { + t.Error(err) + } + + k, err := api.Key().Generate(ctx, "foo") + if err != nil { + t.Fatal(err) + return + } + + l, err := api.Key().List(ctx) + if err != nil { + t.Fatal(err) + return + } + + if len(l) != 2 { + t.Fatalf("expected to get 2 keys, got %d", len(l)) + return + } + + p, err := api.Key().Remove(ctx, "foo") + if err != nil { + t.Fatal(err) + return + } + + if k.Path().String() != p.Path().String() { + t.Errorf("k and p should have equal paths, '%s'!='%s'", k.Path().String(), p.Path().String()) + } + + l, err = api.Key().List(ctx) + if err != nil { + t.Fatal(err) + return + } + + if len(l) != 1 { + t.Fatalf("expected to get 1 key, got %d", len(l)) + return + } + + if l[0].Name() != "self" { + t.Errorf("expected the key to be called 'self', got '%s'", l[0].Name()) + } +} diff --git a/core/coreiface/tests/name_test.go b/core/coreiface/tests/name_test.go new file mode 100644 index 000000000..a3514e051 --- /dev/null +++ b/core/coreiface/tests/name_test.go @@ -0,0 +1,262 @@ +package tests_test + +import ( + "context" + "io" + "math/rand" + "path" + "testing" + "time" + + "gx/ipfs/QmXWZCd8jfaHmt4UDSnjKmGcrQMw95bDGWqEeVLVJjoANX/go-ipfs-files" + ipath "gx/ipfs/QmZErC2Ay6WuGi96CPg316PwitdwgLo6RxZRqVjJjRj2MR/go-path" + + coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface" + opt "github.com/ipfs/go-ipfs/core/coreapi/interface/options" +) + +var rnd = rand.New(rand.NewSource(0x62796532303137)) + +func addTestObject(ctx context.Context, api coreiface.CoreAPI) (coreiface.Path, error) { + return api.Unixfs().Add(ctx, files.NewReaderFile(&io.LimitedReader{R: rnd, N: 4092})) +} + +func appendPath(p coreiface.Path, sub string) coreiface.Path { + p, err := coreiface.ParsePath(path.Join(p.String(), sub)) + if err != nil { + panic(err) + } + return p +} + +func TestPublishResolve(t *testing.T) { + ctx := context.Background() + init := func() (coreiface.CoreAPI, coreiface.Path) { + apis, err := makeAPISwarm(ctx, true, 5) + if err != nil { + t.Fatal(err) + return nil, nil + } + api := apis[0] + + p, err := addTestObject(ctx, api) + if err != nil { + t.Fatal(err) + return nil, nil + } + return api, p + } + + run := func(t *testing.T, ropts []opt.NameResolveOption) { + t.Run("basic", func(t *testing.T) { + api, p := init() + e, err := api.Name().Publish(ctx, p) + if err != nil { + t.Fatal(err) + } + + self, err := api.Key().Self(ctx) + if err != nil { + t.Fatal(err) + } + + if e.Name() != self.ID().Pretty() { + t.Errorf("expected e.Name to equal '%s', got '%s'", self.ID().Pretty(), e.Name()) + } + + if e.Value().String() != p.String() { + t.Errorf("expected paths to match, '%s'!='%s'", e.Value().String(), p.String()) + } + + resPath, err := api.Name().Resolve(ctx, e.Name(), ropts...) + if err != nil { + t.Fatal(err) + } + + if resPath.String() != p.String() { + t.Errorf("expected paths to match, '%s'!='%s'", resPath.String(), p.String()) + } + }) + + t.Run("publishPath", func(t *testing.T) { + api, p := init() + e, err := api.Name().Publish(ctx, appendPath(p, "/test")) + if err != nil { + t.Fatal(err) + } + + self, err := api.Key().Self(ctx) + if err != nil { + t.Fatal(err) + } + + if e.Name() != self.ID().Pretty() { + t.Errorf("expected e.Name to equal '%s', got '%s'", self.ID().Pretty(), e.Name()) + } + + if e.Value().String() != p.String()+"/test" { + t.Errorf("expected paths to match, '%s'!='%s'", e.Value().String(), p.String()) + } + + resPath, err := api.Name().Resolve(ctx, e.Name(), ropts...) + if err != nil { + t.Fatal(err) + } + + if resPath.String() != p.String()+"/test" { + t.Errorf("expected paths to match, '%s'!='%s'", resPath.String(), p.String()+"/test") + } + }) + + t.Run("revolvePath", func(t *testing.T) { + api, p := init() + e, err := api.Name().Publish(ctx, p) + if err != nil { + t.Fatal(err) + } + + self, err := api.Key().Self(ctx) + if err != nil { + t.Fatal(err) + } + + if e.Name() != self.ID().Pretty() { + t.Errorf("expected e.Name to equal '%s', got '%s'", self.ID().Pretty(), e.Name()) + } + + if e.Value().String() != p.String() { + t.Errorf("expected paths to match, '%s'!='%s'", e.Value().String(), p.String()) + } + + resPath, err := api.Name().Resolve(ctx, e.Name()+"/test", ropts...) + if err != nil { + t.Fatal(err) + } + + if resPath.String() != p.String()+"/test" { + t.Errorf("expected paths to match, '%s'!='%s'", resPath.String(), p.String()+"/test") + } + }) + + t.Run("publishRevolvePath", func(t *testing.T) { + api, p := init() + e, err := api.Name().Publish(ctx, appendPath(p, "/a")) + if err != nil { + t.Fatal(err) + } + + self, err := api.Key().Self(ctx) + if err != nil { + t.Fatal(err) + } + + if e.Name() != self.ID().Pretty() { + t.Errorf("expected e.Name to equal '%s', got '%s'", self.ID().Pretty(), e.Name()) + } + + if e.Value().String() != p.String()+"/a" { + t.Errorf("expected paths to match, '%s'!='%s'", e.Value().String(), p.String()) + } + + resPath, err := api.Name().Resolve(ctx, e.Name()+"/b", ropts...) + if err != nil { + t.Fatal(err) + } + + if resPath.String() != p.String()+"/a/b" { + t.Errorf("expected paths to match, '%s'!='%s'", resPath.String(), p.String()+"/a/b") + } + }) + } + + t.Run("default", func(t *testing.T) { + run(t, []opt.NameResolveOption{}) + }) + + t.Run("nocache", func(t *testing.T) { + run(t, []opt.NameResolveOption{opt.Name.Cache(false)}) + }) +} + +func TestBasicPublishResolveKey(t *testing.T) { + ctx := context.Background() + apis, err := makeAPISwarm(ctx, true, 5) + if err != nil { + t.Fatal(err) + } + api := apis[0] + + k, err := api.Key().Generate(ctx, "foo") + if err != nil { + t.Fatal(err) + } + + p, err := addTestObject(ctx, api) + if err != nil { + t.Fatal(err) + } + + e, err := api.Name().Publish(ctx, p, opt.Name.Key(k.Name())) + if err != nil { + t.Fatal(err) + } + + if ipath.Join([]string{"/ipns", e.Name()}) != k.Path().String() { + t.Errorf("expected e.Name to equal '%s', got '%s'", e.Name(), k.Path().String()) + } + + if e.Value().String() != p.String() { + t.Errorf("expected paths to match, '%s'!='%s'", e.Value().String(), p.String()) + } + + resPath, err := api.Name().Resolve(ctx, e.Name()) + if err != nil { + t.Fatal(err) + } + + if resPath.String() != p.String() { + t.Errorf("expected paths to match, '%s'!='%s'", resPath.String(), p.String()) + } +} + +func TestBasicPublishResolveTimeout(t *testing.T) { + t.Skip("ValidTime doesn't appear to work at this time resolution") + + ctx := context.Background() + apis, err := makeAPISwarm(ctx, true, 5) + if err != nil { + t.Fatal(err) + } + api := apis[0] + p, err := addTestObject(ctx, api) + if err != nil { + t.Fatal(err) + } + + e, err := api.Name().Publish(ctx, p, opt.Name.ValidTime(time.Millisecond*100)) + if err != nil { + t.Fatal(err) + } + + self, err := api.Key().Self(ctx) + if err != nil { + t.Fatal(err) + } + + if e.Name() != self.ID().Pretty() { + t.Errorf("expected e.Name to equal '%s', got '%s'", self.ID().Pretty(), e.Name()) + } + + if e.Value().String() != p.String() { + t.Errorf("expected paths to match, '%s'!='%s'", e.Value().String(), p.String()) + } + + time.Sleep(time.Second) + + _, err = api.Name().Resolve(ctx, e.Name()) + if err == nil { + t.Fatal("Expected an error") + } +} + +//TODO: When swarm api is created, add multinode tests diff --git a/core/coreiface/tests/object_test.go b/core/coreiface/tests/object_test.go new file mode 100644 index 000000000..ac9e1d5f3 --- /dev/null +++ b/core/coreiface/tests/object_test.go @@ -0,0 +1,427 @@ +package tests_test + +import ( + "bytes" + "context" + "encoding/hex" + "io/ioutil" + "strings" + "testing" + + "github.com/ipfs/go-ipfs/core/coreapi/interface" + opt "github.com/ipfs/go-ipfs/core/coreapi/interface/options" +) + +func TestNew(t *testing.T) { + ctx := context.Background() + api, err := makeAPI(ctx) + if err != nil { + t.Fatal(err) + } + + emptyNode, err := api.Object().New(ctx) + if err != nil { + t.Fatal(err) + } + + dirNode, err := api.Object().New(ctx, opt.Object.Type("unixfs-dir")) + if err != nil { + t.Fatal(err) + } + + if emptyNode.String() != "QmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zR1n" { + t.Errorf("Unexpected emptyNode path: %s", emptyNode.String()) + } + + if dirNode.String() != "QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn" { + t.Errorf("Unexpected dirNode path: %s", dirNode.String()) + } +} + +func TestObjectPut(t *testing.T) { + ctx := context.Background() + api, err := makeAPI(ctx) + if err != nil { + t.Fatal(err) + } + + p1, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"foo"}`)) + if err != nil { + t.Fatal(err) + } + + p2, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"YmFy"}`), opt.Object.DataType("base64")) //bar + if err != nil { + t.Fatal(err) + } + + pbBytes, err := hex.DecodeString("0a0362617a") + if err != nil { + t.Fatal(err) + } + + p3, err := api.Object().Put(ctx, bytes.NewReader(pbBytes), opt.Object.InputEnc("protobuf")) + if err != nil { + t.Fatal(err) + } + + if p1.String() != "/ipfs/QmQeGyS87nyijii7kFt1zbe4n2PsXTFimzsdxyE9qh9TST" { + t.Errorf("unexpected path: %s", p1.String()) + } + + if p2.String() != "/ipfs/QmNeYRbCibmaMMK6Du6ChfServcLqFvLJF76PzzF76SPrZ" { + t.Errorf("unexpected path: %s", p2.String()) + } + + if p3.String() != "/ipfs/QmZreR7M2t7bFXAdb1V5FtQhjk4t36GnrvueLJowJbQM9m" { + t.Errorf("unexpected path: %s", p3.String()) + } +} + +func TestObjectGet(t *testing.T) { + ctx := context.Background() + api, err := makeAPI(ctx) + if err != nil { + t.Fatal(err) + } + + p1, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"foo"}`)) + if err != nil { + t.Fatal(err) + } + + nd, err := api.Object().Get(ctx, p1) + if err != nil { + t.Fatal(err) + } + + if string(nd.RawData()[len(nd.RawData())-3:]) != "foo" { + t.Fatal("got non-matching data") + } +} + +func TestObjectData(t *testing.T) { + ctx := context.Background() + api, err := makeAPI(ctx) + if err != nil { + t.Fatal(err) + } + + p1, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"foo"}`)) + if err != nil { + t.Fatal(err) + } + + r, err := api.Object().Data(ctx, p1) + if err != nil { + t.Fatal(err) + } + + data, err := ioutil.ReadAll(r) + if err != nil { + t.Fatal(err) + } + + if string(data) != "foo" { + t.Fatal("got non-matching data") + } +} + +func TestObjectLinks(t *testing.T) { + ctx := context.Background() + api, err := makeAPI(ctx) + if err != nil { + t.Fatal(err) + } + + p1, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"foo"}`)) + if err != nil { + t.Fatal(err) + } + + p2, err := api.Object().Put(ctx, strings.NewReader(`{"Links":[{"Name":"bar", "Hash":"`+p1.Cid().String()+`"}]}`)) + if err != nil { + t.Fatal(err) + } + + links, err := api.Object().Links(ctx, p2) + if err != nil { + t.Fatal(err) + } + + if len(links) != 1 { + t.Errorf("unexpected number of links: %d", len(links)) + } + + if links[0].Cid.String() != p1.Cid().String() { + t.Fatal("cids didn't batch") + } + + if links[0].Name != "bar" { + t.Fatal("unexpected link name") + } +} + +func TestObjectStat(t *testing.T) { + ctx := context.Background() + api, err := makeAPI(ctx) + if err != nil { + t.Fatal(err) + } + + p1, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"foo"}`)) + if err != nil { + t.Fatal(err) + } + + p2, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"bazz", "Links":[{"Name":"bar", "Hash":"`+p1.Cid().String()+`", "Size":3}]}`)) + if err != nil { + t.Fatal(err) + } + + stat, err := api.Object().Stat(ctx, p2) + if err != nil { + t.Fatal(err) + } + + if stat.Cid.String() != p2.Cid().String() { + t.Error("unexpected stat.Cid") + } + + if stat.NumLinks != 1 { + t.Errorf("unexpected stat.NumLinks") + } + + if stat.BlockSize != 51 { + t.Error("unexpected stat.BlockSize") + } + + if stat.LinksSize != 47 { + t.Errorf("unexpected stat.LinksSize: %d", stat.LinksSize) + } + + if stat.DataSize != 4 { + t.Error("unexpected stat.DataSize") + } + + if stat.CumulativeSize != 54 { + t.Error("unexpected stat.DataSize") + } +} + +func TestObjectAddLink(t *testing.T) { + ctx := context.Background() + api, err := makeAPI(ctx) + if err != nil { + t.Fatal(err) + } + + p1, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"foo"}`)) + if err != nil { + t.Fatal(err) + } + + p2, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"bazz", "Links":[{"Name":"bar", "Hash":"`+p1.Cid().String()+`", "Size":3}]}`)) + if err != nil { + t.Fatal(err) + } + + p3, err := api.Object().AddLink(ctx, p2, "abc", p2) + if err != nil { + t.Fatal(err) + } + + links, err := api.Object().Links(ctx, p3) + if err != nil { + t.Fatal(err) + } + + if len(links) != 2 { + t.Errorf("unexpected number of links: %d", len(links)) + } + + if links[0].Name != "abc" { + t.Errorf("unexpected link 0 name: %s", links[0].Name) + } + + if links[1].Name != "bar" { + t.Errorf("unexpected link 1 name: %s", links[1].Name) + } +} + +func TestObjectAddLinkCreate(t *testing.T) { + ctx := context.Background() + api, err := makeAPI(ctx) + if err != nil { + t.Fatal(err) + } + + p1, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"foo"}`)) + if err != nil { + t.Fatal(err) + } + + p2, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"bazz", "Links":[{"Name":"bar", "Hash":"`+p1.Cid().String()+`", "Size":3}]}`)) + if err != nil { + t.Fatal(err) + } + + p3, err := api.Object().AddLink(ctx, p2, "abc/d", p2) + if err == nil { + t.Fatal("expected an error") + } + if err.Error() != "no link by that name" { + t.Fatalf("unexpected error: %s", err.Error()) + } + + p3, err = api.Object().AddLink(ctx, p2, "abc/d", p2, opt.Object.Create(true)) + if err != nil { + t.Fatal(err) + } + + links, err := api.Object().Links(ctx, p3) + if err != nil { + t.Fatal(err) + } + + if len(links) != 2 { + t.Errorf("unexpected number of links: %d", len(links)) + } + + if links[0].Name != "abc" { + t.Errorf("unexpected link 0 name: %s", links[0].Name) + } + + if links[1].Name != "bar" { + t.Errorf("unexpected link 1 name: %s", links[1].Name) + } +} + +func TestObjectRmLink(t *testing.T) { + ctx := context.Background() + api, err := makeAPI(ctx) + if err != nil { + t.Fatal(err) + } + + p1, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"foo"}`)) + if err != nil { + t.Fatal(err) + } + + p2, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"bazz", "Links":[{"Name":"bar", "Hash":"`+p1.Cid().String()+`", "Size":3}]}`)) + if err != nil { + t.Fatal(err) + } + + p3, err := api.Object().RmLink(ctx, p2, "bar") + if err != nil { + t.Fatal(err) + } + + links, err := api.Object().Links(ctx, p3) + if err != nil { + t.Fatal(err) + } + + if len(links) != 0 { + t.Errorf("unexpected number of links: %d", len(links)) + } +} + +func TestObjectAddData(t *testing.T) { + ctx := context.Background() + api, err := makeAPI(ctx) + if err != nil { + t.Fatal(err) + } + + p1, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"foo"}`)) + if err != nil { + t.Fatal(err) + } + + p2, err := api.Object().AppendData(ctx, p1, strings.NewReader("bar")) + if err != nil { + t.Fatal(err) + } + + r, err := api.Object().Data(ctx, p2) + if err != nil { + t.Fatal(err) + } + + data, err := ioutil.ReadAll(r) + + if string(data) != "foobar" { + t.Error("unexpected data") + } +} + +func TestObjectSetData(t *testing.T) { + ctx := context.Background() + api, err := makeAPI(ctx) + if err != nil { + t.Fatal(err) + } + + p1, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"foo"}`)) + if err != nil { + t.Fatal(err) + } + + p2, err := api.Object().SetData(ctx, p1, strings.NewReader("bar")) + if err != nil { + t.Fatal(err) + } + + r, err := api.Object().Data(ctx, p2) + if err != nil { + t.Fatal(err) + } + + data, err := ioutil.ReadAll(r) + + if string(data) != "bar" { + t.Error("unexpected data") + } +} + +func TestDiffTest(t *testing.T) { + ctx := context.Background() + api, err := makeAPI(ctx) + if err != nil { + t.Fatal(err) + } + + p1, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"foo"}`)) + if err != nil { + t.Fatal(err) + } + + p2, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"bar"}`)) + if err != nil { + t.Fatal(err) + } + + changes, err := api.Object().Diff(ctx, p1, p2) + if err != nil { + t.Fatal(err) + } + + if len(changes) != 1 { + t.Fatal("unexpected changes len") + } + + if changes[0].Type != iface.DiffMod { + t.Fatal("unexpected change type") + } + + if changes[0].Before.String() != p1.String() { + t.Fatal("unexpected before path") + } + + if changes[0].After.String() != p2.String() { + t.Fatal("unexpected before path") + } +} diff --git a/core/coreiface/tests/path_test.go b/core/coreiface/tests/path_test.go new file mode 100644 index 000000000..e05428073 --- /dev/null +++ b/core/coreiface/tests/path_test.go @@ -0,0 +1,154 @@ +package tests_test + +import ( + "context" + "strings" + "testing" + + coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface" + "github.com/ipfs/go-ipfs/core/coreapi/interface/options" +) + +func TestMutablePath(t *testing.T) { + ctx := context.Background() + api, err := makeAPI(ctx) + if err != nil { + t.Fatal(err) + } + + // get self /ipns path + keys, err := api.Key().List(ctx) + if err != nil { + t.Fatal(err) + } + + if !keys[0].Path().Mutable() { + t.Error("expected self /ipns path to be mutable") + } + + blk, err := api.Block().Put(ctx, strings.NewReader(`foo`)) + if err != nil { + t.Error(err) + } + + if blk.Path().Mutable() { + t.Error("expected /ipld path to be immutable") + } +} + +func TestPathRemainder(t *testing.T) { + ctx := context.Background() + api, err := makeAPI(ctx) + if err != nil { + t.Fatal(err) + } + + obj, err := api.Dag().Put(ctx, strings.NewReader(`{"foo": {"bar": "baz"}}`)) + if err != nil { + t.Fatal(err) + } + + p1, err := coreiface.ParsePath(obj.String() + "/foo/bar") + if err != nil { + t.Error(err) + } + + rp1, err := api.ResolvePath(ctx, p1) + if err != nil { + t.Fatal(err) + } + + if rp1.Remainder() != "foo/bar" { + t.Error("expected to get path remainder") + } +} + +func TestEmptyPathRemainder(t *testing.T) { + ctx := context.Background() + api, err := makeAPI(ctx) + if err != nil { + t.Fatal(err) + } + + obj, err := api.Dag().Put(ctx, strings.NewReader(`{"foo": {"bar": "baz"}}`)) + if err != nil { + t.Fatal(err) + } + + if obj.Remainder() != "" { + t.Error("expected the resolved path to not have a remainder") + } + + p1, err := coreiface.ParsePath(obj.String()) + if err != nil { + t.Error(err) + } + + rp1, err := api.ResolvePath(ctx, p1) + if err != nil { + t.Fatal(err) + } + + if rp1.Remainder() != "" { + t.Error("expected the resolved path to not have a remainder") + } +} + +func TestInvalidPathRemainder(t *testing.T) { + ctx := context.Background() + api, err := makeAPI(ctx) + if err != nil { + t.Fatal(err) + } + + obj, err := api.Dag().Put(ctx, strings.NewReader(`{"foo": {"bar": "baz"}}`)) + if err != nil { + t.Fatal(err) + } + + p1, err := coreiface.ParsePath(obj.String() + "/bar/baz") + if err != nil { + t.Error(err) + } + + _, err = api.ResolvePath(ctx, p1) + if err == nil || err.Error() != "no such link found" { + t.Fatalf("unexpected error: %s", err) + } +} + +func TestPathRoot(t *testing.T) { + ctx := context.Background() + api, err := makeAPI(ctx) + if err != nil { + t.Fatal(err) + } + + blk, err := api.Block().Put(ctx, strings.NewReader(`foo`), options.Block.Format("raw")) + if err != nil { + t.Error(err) + } + + obj, err := api.Dag().Put(ctx, strings.NewReader(`{"foo": {"/": "`+blk.Path().Cid().String()+`"}}`)) + if err != nil { + t.Fatal(err) + } + + p1, err := coreiface.ParsePath(obj.String() + "/foo") + if err != nil { + t.Error(err) + } + + rp, err := api.ResolvePath(ctx, p1) + if err != nil { + t.Fatal(err) + } + + if rp.Root().String() != obj.Cid().String() { + t.Error("unexpected path root") + } + + if rp.Cid().String() != blk.Path().Cid().String() { + t.Error("unexpected path cid") + } +} diff --git a/core/coreiface/tests/pin_test.go b/core/coreiface/tests/pin_test.go new file mode 100644 index 000000000..5c4b82bc2 --- /dev/null +++ b/core/coreiface/tests/pin_test.go @@ -0,0 +1,214 @@ +package tests_test + +import ( + "context" + "strings" + "testing" + + opt "github.com/ipfs/go-ipfs/core/coreapi/interface/options" +) + +func TestPinAdd(t *testing.T) { + ctx := context.Background() + api, err := makeAPI(ctx) + if err != nil { + t.Error(err) + } + + p, err := api.Unixfs().Add(ctx, strFile("foo")()) + if err != nil { + t.Error(err) + } + + err = api.Pin().Add(ctx, p) + if err != nil { + t.Error(err) + } +} + +func TestPinSimple(t *testing.T) { + ctx := context.Background() + api, err := makeAPI(ctx) + if err != nil { + t.Error(err) + } + + p, err := api.Unixfs().Add(ctx, strFile("foo")()) + if err != nil { + t.Error(err) + } + + err = api.Pin().Add(ctx, p) + if err != nil { + t.Error(err) + } + + list, err := api.Pin().Ls(ctx) + if err != nil { + t.Fatal(err) + } + + if len(list) != 1 { + t.Errorf("unexpected pin list len: %d", len(list)) + } + + if list[0].Path().Cid().String() != p.Cid().String() { + t.Error("paths don't match") + } + + if list[0].Type() != "recursive" { + t.Error("unexpected pin type") + } + + err = api.Pin().Rm(ctx, p) + if err != nil { + t.Fatal(err) + } + + list, err = api.Pin().Ls(ctx) + if err != nil { + t.Fatal(err) + } + + if len(list) != 0 { + t.Errorf("unexpected pin list len: %d", len(list)) + } +} + +func TestPinRecursive(t *testing.T) { + ctx := context.Background() + api, err := makeAPI(ctx) + if err != nil { + t.Error(err) + } + + p0, err := api.Unixfs().Add(ctx, strFile("foo")()) + if err != nil { + t.Error(err) + } + + p1, err := api.Unixfs().Add(ctx, strFile("bar")()) + if err != nil { + t.Error(err) + } + + p2, err := api.Dag().Put(ctx, strings.NewReader(`{"lnk": {"/": "`+p0.Cid().String()+`"}}`)) + if err != nil { + t.Error(err) + } + + p3, err := api.Dag().Put(ctx, strings.NewReader(`{"lnk": {"/": "`+p1.Cid().String()+`"}}`)) + if err != nil { + t.Error(err) + } + + err = api.Pin().Add(ctx, p2) + if err != nil { + t.Error(err) + } + + err = api.Pin().Add(ctx, p3, opt.Pin.Recursive(false)) + if err != nil { + t.Error(err) + } + + list, err := api.Pin().Ls(ctx) + if err != nil { + t.Fatal(err) + } + + if len(list) != 3 { + t.Errorf("unexpected pin list len: %d", len(list)) + } + + list, err = api.Pin().Ls(ctx, opt.Pin.Type.Direct()) + if err != nil { + t.Fatal(err) + } + + if len(list) != 1 { + t.Errorf("unexpected pin list len: %d", len(list)) + } + + if list[0].Path().String() != p3.String() { + t.Error("unexpected path") + } + + list, err = api.Pin().Ls(ctx, opt.Pin.Type.Recursive()) + if err != nil { + t.Fatal(err) + } + + if len(list) != 1 { + t.Errorf("unexpected pin list len: %d", len(list)) + } + + if list[0].Path().String() != p2.String() { + t.Error("unexpected path") + } + + list, err = api.Pin().Ls(ctx, opt.Pin.Type.Indirect()) + if err != nil { + t.Fatal(err) + } + + if len(list) != 1 { + t.Errorf("unexpected pin list len: %d", len(list)) + } + + if list[0].Path().Cid().String() != p0.Cid().String() { + t.Error("unexpected path") + } + + res, err := api.Pin().Verify(ctx) + if err != nil { + t.Fatal(err) + } + n := 0 + for r := range res { + if !r.Ok() { + t.Error("expected pin to be ok") + } + n++ + } + + if n != 1 { + t.Errorf("unexpected verify result count: %d", n) + } + + //TODO: figure out a way to test verify without touching IpfsNode + /* + err = api.Block().Rm(ctx, p0, opt.Block.Force(true)) + if err != nil { + t.Fatal(err) + } + + res, err = api.Pin().Verify(ctx) + if err != nil { + t.Fatal(err) + } + n = 0 + for r := range res { + if r.Ok() { + t.Error("expected pin to not be ok") + } + + if len(r.BadNodes()) != 1 { + t.Fatalf("unexpected badNodes len") + } + + if r.BadNodes()[0].Path().Cid().String() != p0.Cid().String() { + t.Error("unexpected badNode path") + } + + if r.BadNodes()[0].Err().Error() != "merkledag: not found" { + t.Errorf("unexpected badNode error: %s", r.BadNodes()[0].Err().Error()) + } + n++ + } + + if n != 1 { + t.Errorf("unexpected verify result count: %d", n) + } + */ +} diff --git a/core/coreiface/tests/pubsub_test.go b/core/coreiface/tests/pubsub_test.go new file mode 100644 index 000000000..19a1eba52 --- /dev/null +++ b/core/coreiface/tests/pubsub_test.go @@ -0,0 +1,106 @@ +package tests_test + +import ( + "context" + "github.com/ipfs/go-ipfs/core/coreapi/interface/options" + "testing" + "time" +) + +func TestBasicPubSub(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + apis, err := makeAPISwarm(ctx, true, 2) + if err != nil { + t.Fatal(err) + } + + sub, err := apis[0].PubSub().Subscribe(ctx, "testch") + if err != nil { + t.Fatal(err) + } + + go func() { + tick := time.Tick(100 * time.Millisecond) + + for { + err = apis[1].PubSub().Publish(ctx, "testch", []byte("hello world")) + if err != nil { + t.Fatal(err) + } + select { + case <-tick: + case <-ctx.Done(): + return + } + } + }() + + m, err := sub.Next(ctx) + if err != nil { + t.Fatal(err) + } + + if string(m.Data()) != "hello world" { + t.Errorf("got invalid data: %s", string(m.Data())) + } + + self1, err := apis[1].Key().Self(ctx) + if err != nil { + t.Fatal(err) + } + + if m.From() != self1.ID() { + t.Errorf("m.From didn't match") + } + + peers, err := apis[1].PubSub().Peers(ctx, options.PubSub.Topic("testch")) + if err != nil { + t.Fatal(err) + } + + if len(peers) != 1 { + t.Fatalf("got incorrect number of peers: %d", len(peers)) + } + + self0, err := apis[0].Key().Self(ctx) + if err != nil { + t.Fatal(err) + } + + if peers[0] != self0.ID() { + t.Errorf("peer didn't match") + } + + peers, err = apis[1].PubSub().Peers(ctx, options.PubSub.Topic("nottestch")) + if err != nil { + t.Fatal(err) + } + + if len(peers) != 0 { + t.Fatalf("got incorrect number of peers: %d", len(peers)) + } + + topics, err := apis[0].PubSub().Ls(ctx) + if err != nil { + t.Fatal(err) + } + + if len(topics) != 1 { + t.Fatalf("got incorrect number of topics: %d", len(peers)) + } + + if topics[0] != "testch" { + t.Errorf("topic didn't match") + } + + topics, err = apis[1].PubSub().Ls(ctx) + if err != nil { + t.Fatal(err) + } + + if len(topics) != 0 { + t.Fatalf("got incorrect number of topics: %d", len(peers)) + } +} diff --git a/core/coreiface/tests/unixfs_test.go b/core/coreiface/tests/unixfs_test.go new file mode 100644 index 000000000..d7ddae963 --- /dev/null +++ b/core/coreiface/tests/unixfs_test.go @@ -0,0 +1,963 @@ +package tests_test + +import ( + "bytes" + "context" + "encoding/base64" + "fmt" + "gx/ipfs/QmR8BauakNcBa3RbE4nbQu76PDiJgoQgz8AJdhJuiU4TAw/go-cid" + "io" + "io/ioutil" + "math" + "os" + "strconv" + "strings" + "sync" + "testing" + + "github.com/ipfs/go-ipfs/core" + "github.com/ipfs/go-ipfs/core/coreapi" + coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface" + "github.com/ipfs/go-ipfs/core/coreapi/interface/options" + mock "github.com/ipfs/go-ipfs/core/mock" + "github.com/ipfs/go-ipfs/keystore" + "github.com/ipfs/go-ipfs/repo" + + ci "gx/ipfs/QmNiJiXwWE3kRhZrC5ej3kSjWHm337pYfhjLGSCDNKJP2s/go-libp2p-crypto" + "gx/ipfs/QmRBaUEQEeFWywfrZJ64QgsmvcqgLSK3VbvGMR2NM2Edpf/go-libp2p/p2p/net/mock" + cbor "gx/ipfs/QmRoARq3nkUb13HSKZGepCZSWe5GrVPwx7xURJGZ7KWv9V/go-ipld-cbor" + "gx/ipfs/QmXWZCd8jfaHmt4UDSnjKmGcrQMw95bDGWqEeVLVJjoANX/go-ipfs-files" + "gx/ipfs/QmY5Grm8pJdiSSVsYxx4uNRgweY72EmYwuSDbRnbFok3iY/go-libp2p-peer" + pstore "gx/ipfs/QmZ9zH2FnLcxv1xyzFeUpDUeo55xEhZQHgveZijcxr7TLj/go-libp2p-peerstore" + "gx/ipfs/Qmbvw7kpSM2p6rbQ57WGRhhqNfCiNGW6EKH4xgHLw4bsnB/go-unixfs" + "gx/ipfs/QmcZfkbgwwwH5ZLTQRHkSQBDiDqd3skY2eU6MZRgWuXcse/go-ipfs-config" + mdag "gx/ipfs/QmdV35UHnL1FM52baPkeUo6u7Fxm2CRUkPTLRPxeF8a4Ap/go-merkledag" + mh "gx/ipfs/QmerPMzPk1mJVowm8KgmoknWa4yCYvvugMPsgWmDNUvDLW/go-multihash" + "gx/ipfs/Qmf4xQhNomPNhrtZc67qSnfJSjxjXs9LWvknJtSXwimPrM/go-datastore" + syncds "gx/ipfs/Qmf4xQhNomPNhrtZc67qSnfJSjxjXs9LWvknJtSXwimPrM/go-datastore/sync" +) + +const testPeerID = "QmTFauExutTsy4XP6JbMFcw2Wa9645HJt2bTqL6qYDCKfe" + +// `echo -n 'hello, world!' | ipfs add` +var hello = "/ipfs/QmQy2Dw4Wk7rdJKjThjYXzfFJNaRKRHhHP5gHHXroJMYxk" +var helloStr = "hello, world!" + +// `echo -n | ipfs add` +var emptyFile = "/ipfs/QmbFMke1KXqnYyBBWxB74N4c5SBnJMVAiMNRcGu6x1AwQH" + +func makeAPISwarm(ctx context.Context, fullIdentity bool, n int) ([]coreiface.CoreAPI, error) { + mn := mocknet.New(ctx) + + nodes := make([]*core.IpfsNode, n) + apis := make([]coreiface.CoreAPI, n) + + for i := 0; i < n; i++ { + var ident config.Identity + if fullIdentity { + sk, pk, err := ci.GenerateKeyPair(ci.RSA, 512) + if err != nil { + return nil, err + } + + id, err := peer.IDFromPublicKey(pk) + if err != nil { + return nil, err + } + + kbytes, err := sk.Bytes() + if err != nil { + return nil, err + } + + ident = config.Identity{ + PeerID: id.Pretty(), + PrivKey: base64.StdEncoding.EncodeToString(kbytes), + } + } else { + ident = config.Identity{ + PeerID: testPeerID, + } + } + + c := config.Config{} + c.Addresses.Swarm = []string{fmt.Sprintf("/ip4/127.0.%d.1/tcp/4001", i)} + c.Identity = ident + + r := &repo.Mock{ + C: c, + D: syncds.MutexWrap(datastore.NewMapDatastore()), + K: keystore.NewMemKeystore(), + } + + node, err := core.NewNode(ctx, &core.BuildCfg{ + Repo: r, + Host: mock.MockHostOption(mn), + Online: fullIdentity, + ExtraOpts: map[string]bool{ + "pubsub": true, + }, + }) + if err != nil { + return nil, err + } + nodes[i] = node + apis[i], err = coreapi.NewCoreAPI(node) + if err != nil { + return nil, err + } + } + + err := mn.LinkAll() + if err != nil { + return nil, err + } + + bsinf := core.BootstrapConfigWithPeers( + []pstore.PeerInfo{ + nodes[0].Peerstore.PeerInfo(nodes[0].Identity), + }, + ) + + for _, n := range nodes[1:] { + if err := n.Bootstrap(bsinf); err != nil { + return nil, err + } + } + + return apis, nil +} + +func makeAPI(ctx context.Context) (coreiface.CoreAPI, error) { + api, err := makeAPISwarm(ctx, false, 1) + if err != nil { + return nil, err + } + + return api[0], nil +} + +func strFile(data string) func() files.Node { + return func() files.Node { + return files.NewBytesFile([]byte(data)) + } +} + +func twoLevelDir() func() files.Node { + return func() files.Node { + return files.NewMapDirectory(map[string]files.Node{ + "abc": files.NewMapDirectory(map[string]files.Node{ + "def": files.NewBytesFile([]byte("world")), + }), + + "bar": files.NewBytesFile([]byte("hello2")), + "foo": files.NewBytesFile([]byte("hello1")), + }) + } +} + +func flatDir() files.Node { + return files.NewMapDirectory(map[string]files.Node{ + "bar": files.NewBytesFile([]byte("hello2")), + "foo": files.NewBytesFile([]byte("hello1")), + }) +} + +func wrapped(name string) func(f files.Node) files.Node { + return func(f files.Node) files.Node { + return files.NewMapDirectory(map[string]files.Node{ + name: f, + }) + } +} + +func TestAdd(t *testing.T) { + ctx := context.Background() + api, err := makeAPI(ctx) + if err != nil { + t.Error(err) + } + + p := func(h string) coreiface.ResolvedPath { + c, err := cid.Parse(h) + if err != nil { + t.Fatal(err) + } + return coreiface.IpfsPath(c) + } + + cases := []struct { + name string + data func() files.Node + expect func(files.Node) files.Node + + apiOpts []options.ApiOption + + path string + err string + + wrap string + + events []coreiface.AddEvent + + opts []options.UnixfsAddOption + }{ + // Simple cases + { + name: "simpleAdd", + data: strFile(helloStr), + path: hello, + opts: []options.UnixfsAddOption{}, + }, + { + name: "addEmpty", + data: strFile(""), + path: emptyFile, + }, + // CIDv1 version / rawLeaves + { + name: "addCidV1", + data: strFile(helloStr), + path: "/ipfs/zb2rhdhmJjJZs9qkhQCpCQ7VREFkqWw3h1r8utjVvQugwHPFd", + opts: []options.UnixfsAddOption{options.Unixfs.CidVersion(1)}, + }, + { + name: "addCidV1NoLeaves", + data: strFile(helloStr), + path: "/ipfs/zdj7WY4GbN8NDbTW1dfCShAQNVovams2xhq9hVCx5vXcjvT8g", + opts: []options.UnixfsAddOption{options.Unixfs.CidVersion(1), options.Unixfs.RawLeaves(false)}, + }, + // Non sha256 hash vs CID + { + name: "addCidSha3", + data: strFile(helloStr), + path: "/ipfs/zb2wwnYtXBxpndNABjtYxWAPt3cwWNRnc11iT63fvkYV78iRb", + opts: []options.UnixfsAddOption{options.Unixfs.Hash(mh.SHA3_256)}, + }, + { + name: "addCidSha3Cid0", + data: strFile(helloStr), + err: "CIDv0 only supports sha2-256", + opts: []options.UnixfsAddOption{options.Unixfs.CidVersion(0), options.Unixfs.Hash(mh.SHA3_256)}, + }, + // Inline + { + name: "addInline", + data: strFile(helloStr), + path: "/ipfs/zaYomJdLndMku8P9LHngHB5w2CQ7NenLbv", + opts: []options.UnixfsAddOption{options.Unixfs.Inline(true)}, + }, + { + name: "addInlineLimit", + data: strFile(helloStr), + path: "/ipfs/zaYomJdLndMku8P9LHngHB5w2CQ7NenLbv", + opts: []options.UnixfsAddOption{options.Unixfs.InlineLimit(32), options.Unixfs.Inline(true)}, + }, + { + name: "addInlineZero", + data: strFile(""), + path: "/ipfs/z2yYDV", + opts: []options.UnixfsAddOption{options.Unixfs.InlineLimit(0), options.Unixfs.Inline(true), options.Unixfs.RawLeaves(true)}, + }, + { //TODO: after coreapi add is used in `ipfs add`, consider making this default for inline + name: "addInlineRaw", + data: strFile(helloStr), + path: "/ipfs/zj7Gr8AcBreqGEfrnR5kPFe", + opts: []options.UnixfsAddOption{options.Unixfs.InlineLimit(32), options.Unixfs.Inline(true), options.Unixfs.RawLeaves(true)}, + }, + // Chunker / Layout + { + name: "addChunks", + data: strFile(strings.Repeat("aoeuidhtns", 200)), + path: "/ipfs/QmRo11d4QJrST47aaiGVJYwPhoNA4ihRpJ5WaxBWjWDwbX", + opts: []options.UnixfsAddOption{options.Unixfs.Chunker("size-4")}, + }, + { + name: "addChunksTrickle", + data: strFile(strings.Repeat("aoeuidhtns", 200)), + path: "/ipfs/QmNNhDGttafX3M1wKWixGre6PrLFGjnoPEDXjBYpTv93HP", + opts: []options.UnixfsAddOption{options.Unixfs.Chunker("size-4"), options.Unixfs.Layout(options.TrickleLayout)}, + }, + // Local + { + name: "addLocal", // better cases in sharness + data: strFile(helloStr), + path: hello, + apiOpts: []options.ApiOption{options.Api.Offline(true)}, + }, + { + name: "hashOnly", // test (non)fetchability + data: strFile(helloStr), + path: hello, + opts: []options.UnixfsAddOption{options.Unixfs.HashOnly(true)}, + }, + // multi file + { + name: "simpleDir", + data: flatDir, + wrap: "t", + path: "/ipfs/QmRKGpFfR32FVXdvJiHfo4WJ5TDYBsM1P9raAp1p6APWSp", + }, + { + name: "twoLevelDir", + data: twoLevelDir(), + wrap: "t", + path: "/ipfs/QmVG2ZYCkV1S4TK8URA3a4RupBF17A8yAr4FqsRDXVJASr", + }, + // wrapped + { + name: "addWrapped", + path: "/ipfs/QmVE9rNpj5doj7XHzp5zMUxD7BJgXEqx4pe3xZ3JBReWHE", + data: func() files.Node { + return files.NewBytesFile([]byte(helloStr)) + }, + wrap: "foo", + expect: wrapped("foo"), + opts: []options.UnixfsAddOption{options.Unixfs.Wrap(true)}, + }, + { + name: "addNotWrappedDirFile", + path: hello, + data: func() files.Node { + return files.NewBytesFile([]byte(helloStr)) + }, + wrap: "foo", + }, + { + name: "stdinWrapped", + path: "/ipfs/QmU3r81oZycjHS9oaSHw37ootMFuFUw1DvMLKXPsezdtqU", + data: func() files.Node { + return files.NewBytesFile([]byte(helloStr)) + }, + expect: func(files.Node) files.Node { + return files.NewMapDirectory(map[string]files.Node{ + "QmQy2Dw4Wk7rdJKjThjYXzfFJNaRKRHhHP5gHHXroJMYxk": files.NewBytesFile([]byte(helloStr)), + }) + }, + opts: []options.UnixfsAddOption{options.Unixfs.Wrap(true)}, + }, + { + name: "stdinNamed", + path: "/ipfs/QmQ6cGBmb3ZbdrQW1MRm1RJnYnaxCqfssz7CrTa9NEhQyS", + data: func() files.Node { + rf, err := files.NewReaderPathFile(os.Stdin.Name(), ioutil.NopCloser(strings.NewReader(helloStr)), nil) + if err != nil { + panic(err) + } + + return rf + }, + expect: func(files.Node) files.Node { + return files.NewMapDirectory(map[string]files.Node{ + "test": files.NewBytesFile([]byte(helloStr)), + }) + }, + opts: []options.UnixfsAddOption{options.Unixfs.Wrap(true), options.Unixfs.StdinName("test")}, + }, + { + name: "twoLevelDirWrapped", + data: twoLevelDir(), + wrap: "t", + expect: wrapped("t"), + path: "/ipfs/QmPwsL3T5sWhDmmAWZHAzyjKtMVDS9a11aHNRqb3xoVnmg", + opts: []options.UnixfsAddOption{options.Unixfs.Wrap(true)}, + }, + { + name: "twoLevelInlineHash", + data: twoLevelDir(), + wrap: "t", + expect: wrapped("t"), + path: "/ipfs/zBunoruKoyCHKkALNSWxDvj4L7yuQnMgQ4hUa9j1Z64tVcDEcu6Zdetyu7eeFCxMPfxb7YJvHeFHoFoHMkBUQf6vfdhmi", + opts: []options.UnixfsAddOption{options.Unixfs.Wrap(true), options.Unixfs.Inline(true), options.Unixfs.RawLeaves(true), options.Unixfs.Hash(mh.SHA3)}, + }, + // hidden + { + name: "hiddenFiles", + data: func() files.Node { + return files.NewMapDirectory(map[string]files.Node{ + ".bar": files.NewBytesFile([]byte("hello2")), + "bar": files.NewBytesFile([]byte("hello2")), + "foo": files.NewBytesFile([]byte("hello1")), + }) + }, + wrap: "t", + path: "/ipfs/QmehGvpf2hY196MzDFmjL8Wy27S4jbgGDUAhBJyvXAwr3g", + opts: []options.UnixfsAddOption{options.Unixfs.Hidden(true)}, + }, + { + name: "hiddenFileAlwaysAdded", + data: func() files.Node { + return files.NewBytesFile([]byte(helloStr)) + }, + wrap: ".foo", + path: hello, + }, + { + name: "hiddenFilesNotAdded", + data: func() files.Node { + return files.NewMapDirectory(map[string]files.Node{ + ".bar": files.NewBytesFile([]byte("hello2")), + "bar": files.NewBytesFile([]byte("hello2")), + "foo": files.NewBytesFile([]byte("hello1")), + }) + }, + expect: func(files.Node) files.Node { + return flatDir() + }, + wrap: "t", + path: "/ipfs/QmRKGpFfR32FVXdvJiHfo4WJ5TDYBsM1P9raAp1p6APWSp", + opts: []options.UnixfsAddOption{options.Unixfs.Hidden(false)}, + }, + // Events / Progress + { + name: "simpleAddEvent", + data: strFile(helloStr), + path: "/ipfs/zb2rhdhmJjJZs9qkhQCpCQ7VREFkqWw3h1r8utjVvQugwHPFd", + events: []coreiface.AddEvent{ + {Name: "zb2rhdhmJjJZs9qkhQCpCQ7VREFkqWw3h1r8utjVvQugwHPFd", Path: p("zb2rhdhmJjJZs9qkhQCpCQ7VREFkqWw3h1r8utjVvQugwHPFd"), Size: strconv.Itoa(len(helloStr))}, + }, + opts: []options.UnixfsAddOption{options.Unixfs.RawLeaves(true)}, + }, + { + name: "silentAddEvent", + data: twoLevelDir(), + path: "/ipfs/QmVG2ZYCkV1S4TK8URA3a4RupBF17A8yAr4FqsRDXVJASr", + events: []coreiface.AddEvent{ + {Name: "t/abc", Path: p("QmU7nuGs2djqK99UNsNgEPGh6GV4662p6WtsgccBNGTDxt"), Size: "62"}, + {Name: "t", Path: p("QmVG2ZYCkV1S4TK8URA3a4RupBF17A8yAr4FqsRDXVJASr"), Size: "229"}, + }, + wrap: "t", + opts: []options.UnixfsAddOption{options.Unixfs.Silent(true)}, + }, + { + name: "dirAddEvents", + data: twoLevelDir(), + path: "/ipfs/QmVG2ZYCkV1S4TK8URA3a4RupBF17A8yAr4FqsRDXVJASr", + events: []coreiface.AddEvent{ + {Name: "t/abc/def", Path: p("QmNyJpQkU1cEkBwMDhDNFstr42q55mqG5GE5Mgwug4xyGk"), Size: "13"}, + {Name: "t/bar", Path: p("QmS21GuXiRMvJKHos4ZkEmQDmRBqRaF5tQS2CQCu2ne9sY"), Size: "14"}, + {Name: "t/foo", Path: p("QmfAjGiVpTN56TXi6SBQtstit5BEw3sijKj1Qkxn6EXKzJ"), Size: "14"}, + {Name: "t/abc", Path: p("QmU7nuGs2djqK99UNsNgEPGh6GV4662p6WtsgccBNGTDxt"), Size: "62"}, + {Name: "t", Path: p("QmVG2ZYCkV1S4TK8URA3a4RupBF17A8yAr4FqsRDXVJASr"), Size: "229"}, + }, + wrap: "t", + }, + { + name: "progress1M", + data: func() files.Node { + return files.NewReaderFile(bytes.NewReader(bytes.Repeat([]byte{0}, 1000000))) + }, + path: "/ipfs/QmXXNNbwe4zzpdMg62ZXvnX1oU7MwSrQ3vAEtuwFKCm1oD", + events: []coreiface.AddEvent{ + {Name: "", Bytes: 262144}, + {Name: "", Bytes: 524288}, + {Name: "", Bytes: 786432}, + {Name: "", Bytes: 1000000}, + {Name: "QmXXNNbwe4zzpdMg62ZXvnX1oU7MwSrQ3vAEtuwFKCm1oD", Path: p("QmXXNNbwe4zzpdMg62ZXvnX1oU7MwSrQ3vAEtuwFKCm1oD"), Size: "1000256"}, + }, + wrap: "", + opts: []options.UnixfsAddOption{options.Unixfs.Progress(true)}, + }, + } + + for _, testCase := range cases { + t.Run(testCase.name, func(t *testing.T) { + ctx, cancel := context.WithCancel(ctx) + defer cancel() + + // recursive logic + + data := testCase.data() + if testCase.wrap != "" { + data = files.NewMapDirectory(map[string]files.Node{ + testCase.wrap: data, + }) + } + + // handle events if relevant to test case + + opts := testCase.opts + eventOut := make(chan interface{}) + var evtWg sync.WaitGroup + if len(testCase.events) > 0 { + opts = append(opts, options.Unixfs.Events(eventOut)) + evtWg.Add(1) + + go func() { + defer evtWg.Done() + expected := testCase.events + + for evt := range eventOut { + event, ok := evt.(*coreiface.AddEvent) + if !ok { + t.Fatal("unexpected event type") + } + + if len(expected) < 1 { + t.Fatal("got more events than expected") + } + + if expected[0].Size != event.Size { + t.Errorf("Event.Size didn't match, %s != %s", expected[0].Size, event.Size) + } + + if expected[0].Name != event.Name { + t.Errorf("Event.Name didn't match, %s != %s", expected[0].Name, event.Name) + } + + if expected[0].Path != nil && event.Path != nil { + if expected[0].Path.Cid().String() != event.Path.Cid().String() { + t.Errorf("Event.Hash didn't match, %s != %s", expected[0].Path, event.Path) + } + } else if event.Path != expected[0].Path { + t.Errorf("Event.Hash didn't match, %s != %s", expected[0].Path, event.Path) + } + if expected[0].Bytes != event.Bytes { + t.Errorf("Event.Bytes didn't match, %d != %d", expected[0].Bytes, event.Bytes) + } + + expected = expected[1:] + } + + if len(expected) > 0 { + t.Fatalf("%d event(s) didn't arrive", len(expected)) + } + }() + } + + tapi, err := api.WithOptions(testCase.apiOpts...) + if err != nil { + t.Fatal(err) + } + + // Add! + + p, err := tapi.Unixfs().Add(ctx, data, opts...) + close(eventOut) + evtWg.Wait() + if testCase.err != "" { + if err == nil { + t.Fatalf("expected an error: %s", testCase.err) + } + if err.Error() != testCase.err { + t.Fatalf("expected an error: '%s' != '%s'", err.Error(), testCase.err) + } + return + } + if err != nil { + t.Fatal(err) + } + + if p.String() != testCase.path { + t.Errorf("expected path %s, got: %s", testCase.path, p) + } + + // compare file structure with Unixfs().Get + + var cmpFile func(origName string, orig files.Node, gotName string, got files.Node) + cmpFile = func(origName string, orig files.Node, gotName string, got files.Node) { + _, origDir := orig.(files.Directory) + _, gotDir := got.(files.Directory) + + if origDir != gotDir { + t.Fatal("file type mismatch") + } + + if origName != gotName { + t.Errorf("file name mismatch, orig='%s', got='%s'", origName, gotName) + } + + if !gotDir { + defer orig.Close() + defer got.Close() + + do, err := ioutil.ReadAll(orig.(files.File)) + if err != nil { + t.Fatal(err) + } + + dg, err := ioutil.ReadAll(got.(files.File)) + if err != nil { + t.Fatal(err) + } + + if !bytes.Equal(do, dg) { + t.Fatal("data not equal") + } + + return + } + + origIt := orig.(files.Directory).Entries() + gotIt := got.(files.Directory).Entries() + + for { + if origIt.Next() { + if !gotIt.Next() { + t.Fatal("gotIt out of entries before origIt") + } + } else { + if gotIt.Next() { + t.Fatal("origIt out of entries before gotIt") + } + break + } + + cmpFile(origIt.Name(), origIt.Node(), gotIt.Name(), gotIt.Node()) + } + if origIt.Err() != nil { + t.Fatal(origIt.Err()) + } + if gotIt.Err() != nil { + t.Fatal(gotIt.Err()) + } + } + + f, err := tapi.Unixfs().Get(ctx, p) + if err != nil { + t.Fatal(err) + } + + orig := testCase.data() + if testCase.expect != nil { + orig = testCase.expect(orig) + } + + cmpFile("", orig, "", f) + }) + } +} + +func TestAddPinned(t *testing.T) { + ctx := context.Background() + api, err := makeAPI(ctx) + if err != nil { + t.Error(err) + } + + _, err = api.Unixfs().Add(ctx, strFile(helloStr)(), options.Unixfs.Pin(true)) + if err != nil { + t.Error(err) + } + + pins, err := api.Pin().Ls(ctx) + if len(pins) != 1 { + t.Fatalf("expected 1 pin, got %d", len(pins)) + } + + if pins[0].Path().String() != "/ipld/QmQy2Dw4Wk7rdJKjThjYXzfFJNaRKRHhHP5gHHXroJMYxk" { + t.Fatalf("got unexpected pin: %s", pins[0].Path().String()) + } +} + +func TestAddHashOnly(t *testing.T) { + ctx := context.Background() + api, err := makeAPI(ctx) + if err != nil { + t.Error(err) + } + + p, err := api.Unixfs().Add(ctx, strFile(helloStr)(), options.Unixfs.HashOnly(true)) + if err != nil { + t.Error(err) + } + + if p.String() != hello { + t.Errorf("unxepected path: %s", p.String()) + } + + _, err = api.Block().Get(ctx, p) + if err == nil { + t.Fatal("expected an error") + } + if err.Error() != "blockservice: key not found" { + t.Errorf("unxepected error: %s", err.Error()) + } +} + +func TestGetEmptyFile(t *testing.T) { + ctx := context.Background() + api, err := makeAPI(ctx) + if err != nil { + t.Fatal(err) + } + + _, err = api.Unixfs().Add(ctx, files.NewBytesFile([]byte{})) + if err != nil { + t.Fatal(err) + } + + emptyFilePath, err := coreiface.ParsePath(emptyFile) + if err != nil { + t.Fatal(err) + } + + r, err := api.Unixfs().Get(ctx, emptyFilePath) + if err != nil { + t.Fatal(err) + } + + buf := make([]byte, 1) // non-zero so that Read() actually tries to read + n, err := io.ReadFull(r.(files.File), buf) + if err != nil && err != io.EOF { + t.Error(err) + } + if !bytes.HasPrefix(buf, []byte{0x00}) { + t.Fatalf("expected empty data, got [%s] [read=%d]", buf, n) + } +} + +func TestGetDir(t *testing.T) { + ctx := context.Background() + api, err := makeAPI(ctx) + if err != nil { + t.Error(err) + } + edir := unixfs.EmptyDirNode() + _, err = api.Dag().Put(ctx, bytes.NewReader(edir.RawData()), options.Dag.Codec(cid.DagProtobuf), options.Dag.InputEnc("raw")) + if err != nil { + t.Error(err) + } + p := coreiface.IpfsPath(edir.Cid()) + + emptyDir, err := api.Object().New(ctx, options.Object.Type("unixfs-dir")) + if err != nil { + t.Error(err) + } + + if p.String() != coreiface.IpfsPath(emptyDir.Cid()).String() { + t.Fatalf("expected path %s, got: %s", emptyDir.Cid(), p.String()) + } + + r, err := api.Unixfs().Get(ctx, coreiface.IpfsPath(emptyDir.Cid())) + if err != nil { + t.Error(err) + } + + if _, ok := r.(files.Directory); !ok { + t.Fatalf("expected a directory") + } +} + +func TestGetNonUnixfs(t *testing.T) { + ctx := context.Background() + api, err := makeAPI(ctx) + if err != nil { + t.Error(err) + } + + nd := new(mdag.ProtoNode) + _, err = api.Dag().Put(ctx, bytes.NewReader(nd.RawData()), options.Dag.Codec(nd.CidBuilder().GetCodec()), options.Dag.InputEnc("raw")) + if err != nil { + t.Error(err) + } + + _, err = api.Unixfs().Get(ctx, coreiface.IpfsPath(nd.Cid())) + if !strings.Contains(err.Error(), "proto: required field") { + t.Fatalf("expected protobuf error, got: %s", err) + } +} + +func TestLs(t *testing.T) { + ctx := context.Background() + api, err := makeAPI(ctx) + if err != nil { + t.Error(err) + } + + r := strings.NewReader("content-of-file") + p, err := api.Unixfs().Add(ctx, files.NewMapDirectory(map[string]files.Node{ + "0": files.NewMapDirectory(map[string]files.Node{ + "name-of-file": files.NewReaderFile(r), + }), + })) + if err != nil { + t.Error(err) + } + + links, err := api.Unixfs().Ls(ctx, p) + if err != nil { + t.Error(err) + } + + if len(links) != 1 { + t.Fatalf("expected 1 link, got %d", len(links)) + } + if links[0].Size != 23 { + t.Fatalf("expected size = 23, got %d", links[0].Size) + } + if links[0].Name != "name-of-file" { + t.Fatalf("expected name = name-of-file, got %s", links[0].Name) + } + if links[0].Cid.String() != "QmX3qQVKxDGz3URVC3861Z3CKtQKGBn6ffXRBBWGMFz9Lr" { + t.Fatalf("expected cid = QmX3qQVKxDGz3URVC3861Z3CKtQKGBn6ffXRBBWGMFz9Lr, got %s", links[0].Cid) + } +} + +func TestEntriesExpired(t *testing.T) { + ctx := context.Background() + api, err := makeAPI(ctx) + if err != nil { + t.Error(err) + } + + r := strings.NewReader("content-of-file") + p, err := api.Unixfs().Add(ctx, files.NewMapDirectory(map[string]files.Node{ + "0": files.NewMapDirectory(map[string]files.Node{ + "name-of-file": files.NewReaderFile(r), + }), + })) + if err != nil { + t.Error(err) + } + + ctx, cancel := context.WithCancel(ctx) + + nd, err := api.Unixfs().Get(ctx, p) + if err != nil { + t.Error(err) + } + cancel() + + it := files.ToDir(nd).Entries() + if it == nil { + t.Fatal("it was nil") + } + + if it.Next() { + t.Fatal("Next succeeded") + } + + if it.Err() != context.Canceled { + t.Fatalf("unexpected error %s", it.Err()) + } + + if it.Next() { + t.Fatal("Next succeeded") + } +} + +func TestLsEmptyDir(t *testing.T) { + ctx := context.Background() + api, err := makeAPI(ctx) + if err != nil { + t.Error(err) + } + + _, err = api.Unixfs().Add(ctx, files.NewMapDirectory(map[string]files.Node{"0": files.NewSliceDirectory([]files.DirEntry{})})) + if err != nil { + t.Error(err) + } + + emptyDir, err := api.Object().New(ctx, options.Object.Type("unixfs-dir")) + if err != nil { + t.Error(err) + } + + links, err := api.Unixfs().Ls(ctx, coreiface.IpfsPath(emptyDir.Cid())) + if err != nil { + t.Error(err) + } + + if len(links) != 0 { + t.Fatalf("expected 0 links, got %d", len(links)) + } +} + +// TODO(lgierth) this should test properly, with len(links) > 0 +func TestLsNonUnixfs(t *testing.T) { + ctx := context.Background() + api, err := makeAPI(ctx) + if err != nil { + t.Error(err) + } + + nd, err := cbor.WrapObject(map[string]interface{}{"foo": "bar"}, math.MaxUint64, -1) + if err != nil { + t.Fatal(err) + } + + _, err = api.Dag().Put(ctx, bytes.NewReader(nd.RawData()), options.Dag.Codec(cid.DagCBOR), options.Dag.InputEnc("raw")) + if err != nil { + t.Error(err) + } + + links, err := api.Unixfs().Ls(ctx, coreiface.IpfsPath(nd.Cid())) + if err != nil { + t.Error(err) + } + + if len(links) != 0 { + t.Fatalf("expected 0 links, got %d", len(links)) + } +} + +type closeTestF struct { + files.File + closed bool + + t *testing.T +} + +type closeTestD struct { + files.Directory + closed bool + + t *testing.T +} + +func (f *closeTestD) Close() error { + if f.closed { + f.t.Fatal("already closed") + } + f.closed = true + return nil +} + +func (f *closeTestF) Close() error { + if f.closed { + f.t.Fatal("already closed") + } + f.closed = true + return nil +} + +func TestAddCloses(t *testing.T) { + ctx := context.Background() + api, err := makeAPI(ctx) + if err != nil { + t.Error(err) + } + + n4 := &closeTestF{files.NewBytesFile([]byte("foo")), false, t} + d3 := &closeTestD{files.NewMapDirectory(map[string]files.Node{ + "sub": n4, + }), false, t} + n2 := &closeTestF{files.NewBytesFile([]byte("bar")), false, t} + n1 := &closeTestF{files.NewBytesFile([]byte("baz")), false, t} + d0 := &closeTestD{files.NewMapDirectory(map[string]files.Node{ + "a": d3, + "b": n1, + "c": n2, + }), false, t} + + _, err = api.Unixfs().Add(ctx, d0) + if err != nil { + t.Error(err) + } + + d0.Close() // Adder doesn't close top-level file + + for i, n := range []*closeTestF{n1, n2, n4} { + if !n.closed { + t.Errorf("file %d not closed!", i) + } + } + + for i, n := range []*closeTestD{d0, d3} { + if !n.closed { + t.Errorf("dir %d not closed!", i) + } + } + +} From 373e313822941476f1b96535cab7e822254cad50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 20 Dec 2018 20:11:37 +0100 Subject: [PATCH 0166/1212] coreapi: run tests from interface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@88e58e6b286d55882958c68525d69c4a3dd213b8 This commit was moved from ipfs/boxo@6649a031fab719883b2f507b4191538d61d183bb --- core/coreiface/tests/api.go | 129 ++++++++++++++++++ .../tests/{block_test.go => block.go} | 11 +- core/coreiface/tests/{dag_test.go => dag.go} | 12 +- core/coreiface/tests/{dht_test.go => dht.go} | 8 +- core/coreiface/tests/{key_test.go => key.go} | 19 ++- .../coreiface/tests/{name_test.go => name.go} | 7 +- .../tests/{object_test.go => object.go} | 17 ++- .../coreiface/tests/{path_test.go => path.go} | 10 +- core/coreiface/tests/{pin_test.go => pin.go} | 8 +- .../tests/{pubsub_test.go => pubsub.go} | 6 +- .../tests/{unixfs_test.go => unixfs.go} | 123 +++-------------- 11 files changed, 233 insertions(+), 117 deletions(-) create mode 100644 core/coreiface/tests/api.go rename core/coreiface/tests/{block_test.go => block.go} (92%) rename core/coreiface/tests/{dag_test.go => dag.go} (92%) rename core/coreiface/tests/{dht_test.go => dht.go} (93%) rename core/coreiface/tests/{key_test.go => key.go} (93%) rename core/coreiface/tests/{name_test.go => name.go} (97%) rename core/coreiface/tests/{object_test.go => object.go} (93%) rename core/coreiface/tests/{path_test.go => path.go} (91%) rename core/coreiface/tests/{pin_test.go => pin.go} (95%) rename core/coreiface/tests/{pubsub_test.go => pubsub.go} (95%) rename core/coreiface/tests/{unixfs_test.go => unixfs.go} (89%) diff --git a/core/coreiface/tests/api.go b/core/coreiface/tests/api.go new file mode 100644 index 000000000..8baa869dd --- /dev/null +++ b/core/coreiface/tests/api.go @@ -0,0 +1,129 @@ +package tests + +import ( + "context" + "encoding/base64" + "fmt" + "testing" + + "github.com/ipfs/go-ipfs/core" + "github.com/ipfs/go-ipfs/core/coreapi" + coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface" + mock "github.com/ipfs/go-ipfs/core/mock" + "github.com/ipfs/go-ipfs/keystore" + "github.com/ipfs/go-ipfs/repo" + + ci "gx/ipfs/QmNiJiXwWE3kRhZrC5ej3kSjWHm337pYfhjLGSCDNKJP2s/go-libp2p-crypto" + "gx/ipfs/QmRBaUEQEeFWywfrZJ64QgsmvcqgLSK3VbvGMR2NM2Edpf/go-libp2p/p2p/net/mock" + "gx/ipfs/QmY5Grm8pJdiSSVsYxx4uNRgweY72EmYwuSDbRnbFok3iY/go-libp2p-peer" + pstore "gx/ipfs/QmZ9zH2FnLcxv1xyzFeUpDUeo55xEhZQHgveZijcxr7TLj/go-libp2p-peerstore" + "gx/ipfs/QmcZfkbgwwwH5ZLTQRHkSQBDiDqd3skY2eU6MZRgWuXcse/go-ipfs-config" + "gx/ipfs/Qmf4xQhNomPNhrtZc67qSnfJSjxjXs9LWvknJtSXwimPrM/go-datastore" + syncds "gx/ipfs/Qmf4xQhNomPNhrtZc67qSnfJSjxjXs9LWvknJtSXwimPrM/go-datastore/sync" +) + + +func makeAPISwarm(ctx context.Context, fullIdentity bool, n int) ([]coreiface.CoreAPI, error) { + mn := mocknet.New(ctx) + + nodes := make([]*core.IpfsNode, n) + apis := make([]coreiface.CoreAPI, n) + + for i := 0; i < n; i++ { + var ident config.Identity + if fullIdentity { + sk, pk, err := ci.GenerateKeyPair(ci.RSA, 512) + if err != nil { + return nil, err + } + + id, err := peer.IDFromPublicKey(pk) + if err != nil { + return nil, err + } + + kbytes, err := sk.Bytes() + if err != nil { + return nil, err + } + + ident = config.Identity{ + PeerID: id.Pretty(), + PrivKey: base64.StdEncoding.EncodeToString(kbytes), + } + } else { + ident = config.Identity{ + PeerID: testPeerID, + } + } + + c := config.Config{} + c.Addresses.Swarm = []string{fmt.Sprintf("/ip4/127.0.%d.1/tcp/4001", i)} + c.Identity = ident + + r := &repo.Mock{ + C: c, + D: syncds.MutexWrap(datastore.NewMapDatastore()), + K: keystore.NewMemKeystore(), + } + + node, err := core.NewNode(ctx, &core.BuildCfg{ + Repo: r, + Host: mock.MockHostOption(mn), + Online: fullIdentity, + ExtraOpts: map[string]bool{ + "pubsub": true, + }, + }) + if err != nil { + return nil, err + } + nodes[i] = node + apis[i], err = coreapi.NewCoreAPI(node) + if err != nil { + return nil, err + } + } + + err := mn.LinkAll() + if err != nil { + return nil, err + } + + bsinf := core.BootstrapConfigWithPeers( + []pstore.PeerInfo{ + nodes[0].Peerstore.PeerInfo(nodes[0].Identity), + }, + ) + + for _, n := range nodes[1:] { + if err := n.Bootstrap(bsinf); err != nil { + return nil, err + } + } + + return apis, nil +} + +func makeAPI(ctx context.Context) (coreiface.CoreAPI, error) { + api, err := makeAPISwarm(ctx, false, 1) + if err != nil { + return nil, err + } + + return api[0], nil +} + + +func TestApi(t *testing.T) { + t.Run("Block", TestBlock) + t.Run("TestDag", TestDag) + t.Run("TestDht", TestDht) + t.Run("TestKey", TestKey) + t.Run("TestName", TestName) + t.Run("TestObject", TestObject) + t.Run("TestPath", TestPath) + t.Run("TestPin", TestPin) + t.Run("TestPubSub", TestPubSub) + t.Run("TestUnixfs", TestUnixfs) +} diff --git a/core/coreiface/tests/block_test.go b/core/coreiface/tests/block.go similarity index 92% rename from core/coreiface/tests/block_test.go rename to core/coreiface/tests/block.go index 81360b150..07679a926 100644 --- a/core/coreiface/tests/block_test.go +++ b/core/coreiface/tests/block.go @@ -1,4 +1,4 @@ -package tests_test +package tests import ( "context" @@ -12,6 +12,15 @@ import ( mh "gx/ipfs/QmerPMzPk1mJVowm8KgmoknWa4yCYvvugMPsgWmDNUvDLW/go-multihash" ) +func TestBlock(t *testing.T) { + t.Run("TestBlockPut", TestBlockPut) + t.Run("TestBlockPutFormat", TestBlockPutFormat) + t.Run("TestBlockPutHash", TestBlockPutHash) + t.Run("TestBlockGet", TestBlockGet) + t.Run("TestBlockRm", TestBlockRm) + t.Run("TestBlockStat", TestBlockStat) +} + func TestBlockPut(t *testing.T) { ctx := context.Background() api, err := makeAPI(ctx) diff --git a/core/coreiface/tests/dag_test.go b/core/coreiface/tests/dag.go similarity index 92% rename from core/coreiface/tests/dag_test.go rename to core/coreiface/tests/dag.go index 17059192b..a75438ab1 100644 --- a/core/coreiface/tests/dag_test.go +++ b/core/coreiface/tests/dag.go @@ -1,4 +1,4 @@ -package tests_test +package tests import ( "context" @@ -12,6 +12,14 @@ import ( mh "gx/ipfs/QmerPMzPk1mJVowm8KgmoknWa4yCYvvugMPsgWmDNUvDLW/go-multihash" ) +func TestDag(t *testing.T) { + t.Run("TestPut", TestPut) + t.Run("TestPutWithHash", TestPutWithHash) + t.Run("TestPath", TestDagPath) + t.Run("TestTree", TestTree) + t.Run("TestBatch", TestBatch) +} + var ( treeExpected = map[string]struct{}{ "a": {}, @@ -56,7 +64,7 @@ func TestPutWithHash(t *testing.T) { } } -func TestPath(t *testing.T) { +func TestDagPath(t *testing.T) { ctx := context.Background() api, err := makeAPI(ctx) if err != nil { diff --git a/core/coreiface/tests/dht_test.go b/core/coreiface/tests/dht.go similarity index 93% rename from core/coreiface/tests/dht_test.go rename to core/coreiface/tests/dht.go index be16bb083..429197f70 100644 --- a/core/coreiface/tests/dht_test.go +++ b/core/coreiface/tests/dht.go @@ -1,4 +1,4 @@ -package tests_test +package tests import ( "context" @@ -8,6 +8,12 @@ import ( "github.com/ipfs/go-ipfs/core/coreapi/interface/options" ) +func TestDht(t *testing.T) { + t.Run("TestDhtFindPeer", TestDhtFindPeer) + t.Run("TestDhtFindProviders", TestDhtFindProviders) + t.Run("TestDhtProvide", TestDhtProvide) +} + func TestDhtFindPeer(t *testing.T) { ctx := context.Background() apis, err := makeAPISwarm(ctx, true, 5) diff --git a/core/coreiface/tests/key_test.go b/core/coreiface/tests/key.go similarity index 93% rename from core/coreiface/tests/key_test.go rename to core/coreiface/tests/key.go index 21884e448..b08f56a4f 100644 --- a/core/coreiface/tests/key_test.go +++ b/core/coreiface/tests/key.go @@ -1,4 +1,4 @@ -package tests_test +package tests import ( "context" @@ -8,6 +8,23 @@ import ( opt "github.com/ipfs/go-ipfs/core/coreapi/interface/options" ) +func TestKey(t *testing.T) { + t.Run("TestListSelf", TestListSelf) + t.Run("TestRenameSelf", TestRenameSelf) + t.Run("TestRemoveSelf", TestRemoveSelf) + t.Run("TestGenerateSize", TestGenerateSize) + t.Run("TestGenerateExisting", TestGenerateExisting) + t.Run("TestList", TestList) + t.Run("TestRename", TestRename) + t.Run("TestRenameToSelf", TestRenameToSelf) + t.Run("TestRenameToSelfForce", TestRenameToSelfForce) + t.Run("TestRenameOverwriteNoForce", TestRenameOverwriteNoForce) + t.Run("TestRenameOverwrite", TestRenameOverwrite) + t.Run("TestRenameSameNameNoForce", TestRenameSameNameNoForce) + t.Run("TestRenameSameName", TestRenameSameName) + t.Run("TestRemove", TestRemove) +} + func TestListSelf(t *testing.T) { ctx := context.Background() api, err := makeAPI(ctx) diff --git a/core/coreiface/tests/name_test.go b/core/coreiface/tests/name.go similarity index 97% rename from core/coreiface/tests/name_test.go rename to core/coreiface/tests/name.go index a3514e051..154c1d444 100644 --- a/core/coreiface/tests/name_test.go +++ b/core/coreiface/tests/name.go @@ -1,4 +1,4 @@ -package tests_test +package tests import ( "context" @@ -15,6 +15,11 @@ import ( opt "github.com/ipfs/go-ipfs/core/coreapi/interface/options" ) +func TestName(t *testing.T) { + t.Run("TestPublishResolve", TestPublishResolve) + t.Run("TestBasicPublishResolveKey", TestBasicPublishResolveKey) +} + var rnd = rand.New(rand.NewSource(0x62796532303137)) func addTestObject(ctx context.Context, api coreiface.CoreAPI) (coreiface.Path, error) { diff --git a/core/coreiface/tests/object_test.go b/core/coreiface/tests/object.go similarity index 93% rename from core/coreiface/tests/object_test.go rename to core/coreiface/tests/object.go index ac9e1d5f3..7d4243bca 100644 --- a/core/coreiface/tests/object_test.go +++ b/core/coreiface/tests/object.go @@ -1,4 +1,4 @@ -package tests_test +package tests import ( "bytes" @@ -12,6 +12,21 @@ import ( opt "github.com/ipfs/go-ipfs/core/coreapi/interface/options" ) +func TestObject(t *testing.T) { + t.Run("TestNew", TestNew) + t.Run("TestObjectPut", TestObjectPut) + t.Run("TestObjectGet", TestObjectGet) + t.Run("TestObjectData", TestObjectData) + t.Run("TestObjectLinks", TestObjectLinks) + t.Run("TestObjectStat", TestObjectStat) + t.Run("TestObjectAddLink", TestObjectAddLink) + t.Run("TestObjectAddLinkCreate", TestObjectAddLinkCreate) + t.Run("TestObjectRmLink", TestObjectRmLink) + t.Run("TestObjectAddData", TestObjectAddData) + t.Run("TestObjectSetData", TestObjectSetData) + t.Run("TestDiffTest", TestDiffTest) +} + func TestNew(t *testing.T) { ctx := context.Background() api, err := makeAPI(ctx) diff --git a/core/coreiface/tests/path_test.go b/core/coreiface/tests/path.go similarity index 91% rename from core/coreiface/tests/path_test.go rename to core/coreiface/tests/path.go index e05428073..efbacd29f 100644 --- a/core/coreiface/tests/path_test.go +++ b/core/coreiface/tests/path.go @@ -1,4 +1,4 @@ -package tests_test +package tests import ( "context" @@ -9,6 +9,14 @@ import ( "github.com/ipfs/go-ipfs/core/coreapi/interface/options" ) +func TestPath(t *testing.T) { + t.Run("TestMutablePath", TestMutablePath) + t.Run("TestPathRemainder", TestPathRemainder) + t.Run("TestEmptyPathRemainder", TestEmptyPathRemainder) + t.Run("TestInvalidPathRemainder", TestInvalidPathRemainder) + t.Run("TestPathRoot", TestPathRoot) +} + func TestMutablePath(t *testing.T) { ctx := context.Background() api, err := makeAPI(ctx) diff --git a/core/coreiface/tests/pin_test.go b/core/coreiface/tests/pin.go similarity index 95% rename from core/coreiface/tests/pin_test.go rename to core/coreiface/tests/pin.go index 5c4b82bc2..344cd0db7 100644 --- a/core/coreiface/tests/pin_test.go +++ b/core/coreiface/tests/pin.go @@ -1,4 +1,4 @@ -package tests_test +package tests import ( "context" @@ -8,6 +8,12 @@ import ( opt "github.com/ipfs/go-ipfs/core/coreapi/interface/options" ) +func TestPin(t *testing.T) { + t.Run("TestPinAdd", TestPinAdd) + t.Run("TestPinSimple", TestPinSimple) + t.Run("TestPinRecursive", TestPinRecursive) +} + func TestPinAdd(t *testing.T) { ctx := context.Background() api, err := makeAPI(ctx) diff --git a/core/coreiface/tests/pubsub_test.go b/core/coreiface/tests/pubsub.go similarity index 95% rename from core/coreiface/tests/pubsub_test.go rename to core/coreiface/tests/pubsub.go index 19a1eba52..3ecd80274 100644 --- a/core/coreiface/tests/pubsub_test.go +++ b/core/coreiface/tests/pubsub.go @@ -1,4 +1,4 @@ -package tests_test +package tests import ( "context" @@ -7,6 +7,10 @@ import ( "time" ) +func TestPubSub(t *testing.T) { + t.Run("TestBasicPubSub", TestBasicPubSub) +} + func TestBasicPubSub(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() diff --git a/core/coreiface/tests/unixfs_test.go b/core/coreiface/tests/unixfs.go similarity index 89% rename from core/coreiface/tests/unixfs_test.go rename to core/coreiface/tests/unixfs.go index d7ddae963..1ca0b282a 100644 --- a/core/coreiface/tests/unixfs_test.go +++ b/core/coreiface/tests/unixfs.go @@ -1,11 +1,8 @@ -package tests_test +package tests import ( "bytes" "context" - "encoding/base64" - "fmt" - "gx/ipfs/QmR8BauakNcBa3RbE4nbQu76PDiJgoQgz8AJdhJuiU4TAw/go-cid" "io" "io/ioutil" "math" @@ -15,28 +12,31 @@ import ( "sync" "testing" - "github.com/ipfs/go-ipfs/core" - "github.com/ipfs/go-ipfs/core/coreapi" coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface" "github.com/ipfs/go-ipfs/core/coreapi/interface/options" - mock "github.com/ipfs/go-ipfs/core/mock" - "github.com/ipfs/go-ipfs/keystore" - "github.com/ipfs/go-ipfs/repo" - ci "gx/ipfs/QmNiJiXwWE3kRhZrC5ej3kSjWHm337pYfhjLGSCDNKJP2s/go-libp2p-crypto" - "gx/ipfs/QmRBaUEQEeFWywfrZJ64QgsmvcqgLSK3VbvGMR2NM2Edpf/go-libp2p/p2p/net/mock" + "gx/ipfs/QmR8BauakNcBa3RbE4nbQu76PDiJgoQgz8AJdhJuiU4TAw/go-cid" cbor "gx/ipfs/QmRoARq3nkUb13HSKZGepCZSWe5GrVPwx7xURJGZ7KWv9V/go-ipld-cbor" "gx/ipfs/QmXWZCd8jfaHmt4UDSnjKmGcrQMw95bDGWqEeVLVJjoANX/go-ipfs-files" - "gx/ipfs/QmY5Grm8pJdiSSVsYxx4uNRgweY72EmYwuSDbRnbFok3iY/go-libp2p-peer" - pstore "gx/ipfs/QmZ9zH2FnLcxv1xyzFeUpDUeo55xEhZQHgveZijcxr7TLj/go-libp2p-peerstore" "gx/ipfs/Qmbvw7kpSM2p6rbQ57WGRhhqNfCiNGW6EKH4xgHLw4bsnB/go-unixfs" - "gx/ipfs/QmcZfkbgwwwH5ZLTQRHkSQBDiDqd3skY2eU6MZRgWuXcse/go-ipfs-config" mdag "gx/ipfs/QmdV35UHnL1FM52baPkeUo6u7Fxm2CRUkPTLRPxeF8a4Ap/go-merkledag" mh "gx/ipfs/QmerPMzPk1mJVowm8KgmoknWa4yCYvvugMPsgWmDNUvDLW/go-multihash" - "gx/ipfs/Qmf4xQhNomPNhrtZc67qSnfJSjxjXs9LWvknJtSXwimPrM/go-datastore" - syncds "gx/ipfs/Qmf4xQhNomPNhrtZc67qSnfJSjxjXs9LWvknJtSXwimPrM/go-datastore/sync" ) +func TestUnixfs(t *testing.T) { + t.Run("TestAdd", TestAdd) + t.Run("TestAddPinned", TestAddPinned) + t.Run("TestAddHashOnly", TestAddHashOnly) + t.Run("TestGetEmptyFile", TestGetEmptyFile) + t.Run("TestGetDir", TestGetDir) + t.Run("TestGetNonUnixfs", TestGetNonUnixfs) + t.Run("TestLs", TestLs) + t.Run("TestEntriesExpired", TestEntriesExpired) + t.Run("TestLsEmptyDir", TestLsEmptyDir) + t.Run("TestLsNonUnixfs", TestLsNonUnixfs) + t.Run("TestAddCloses", TestAddCloses) +} + const testPeerID = "QmTFauExutTsy4XP6JbMFcw2Wa9645HJt2bTqL6qYDCKfe" // `echo -n 'hello, world!' | ipfs add` @@ -46,97 +46,6 @@ var helloStr = "hello, world!" // `echo -n | ipfs add` var emptyFile = "/ipfs/QmbFMke1KXqnYyBBWxB74N4c5SBnJMVAiMNRcGu6x1AwQH" -func makeAPISwarm(ctx context.Context, fullIdentity bool, n int) ([]coreiface.CoreAPI, error) { - mn := mocknet.New(ctx) - - nodes := make([]*core.IpfsNode, n) - apis := make([]coreiface.CoreAPI, n) - - for i := 0; i < n; i++ { - var ident config.Identity - if fullIdentity { - sk, pk, err := ci.GenerateKeyPair(ci.RSA, 512) - if err != nil { - return nil, err - } - - id, err := peer.IDFromPublicKey(pk) - if err != nil { - return nil, err - } - - kbytes, err := sk.Bytes() - if err != nil { - return nil, err - } - - ident = config.Identity{ - PeerID: id.Pretty(), - PrivKey: base64.StdEncoding.EncodeToString(kbytes), - } - } else { - ident = config.Identity{ - PeerID: testPeerID, - } - } - - c := config.Config{} - c.Addresses.Swarm = []string{fmt.Sprintf("/ip4/127.0.%d.1/tcp/4001", i)} - c.Identity = ident - - r := &repo.Mock{ - C: c, - D: syncds.MutexWrap(datastore.NewMapDatastore()), - K: keystore.NewMemKeystore(), - } - - node, err := core.NewNode(ctx, &core.BuildCfg{ - Repo: r, - Host: mock.MockHostOption(mn), - Online: fullIdentity, - ExtraOpts: map[string]bool{ - "pubsub": true, - }, - }) - if err != nil { - return nil, err - } - nodes[i] = node - apis[i], err = coreapi.NewCoreAPI(node) - if err != nil { - return nil, err - } - } - - err := mn.LinkAll() - if err != nil { - return nil, err - } - - bsinf := core.BootstrapConfigWithPeers( - []pstore.PeerInfo{ - nodes[0].Peerstore.PeerInfo(nodes[0].Identity), - }, - ) - - for _, n := range nodes[1:] { - if err := n.Bootstrap(bsinf); err != nil { - return nil, err - } - } - - return apis, nil -} - -func makeAPI(ctx context.Context) (coreiface.CoreAPI, error) { - api, err := makeAPISwarm(ctx, false, 1) - if err != nil { - return nil, err - } - - return api[0], nil -} - func strFile(data string) func() files.Node { return func() files.Node { return files.NewBytesFile([]byte(data)) From cba8f3c2a51e6b4afeeabec713d6fe0c699bae57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 20 Dec 2018 21:01:00 +0100 Subject: [PATCH 0167/1212] coreapi: Interface for external test providers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@1532d2602204f7c279b22db1ebcb960f82e67050 This commit was moved from ipfs/boxo@9e88033a986fbd3454d5b438e3590b871ae0987d --- core/coreiface/tests/api.go | 138 +++++++-------------------------- core/coreiface/tests/block.go | 38 ++++----- core/coreiface/tests/dag.go | 32 ++++---- core/coreiface/tests/dht.go | 20 ++--- core/coreiface/tests/key.go | 105 +++++++++++++------------ core/coreiface/tests/name.go | 19 ++--- core/coreiface/tests/object.go | 74 +++++++++--------- core/coreiface/tests/path.go | 32 ++++---- core/coreiface/tests/pin.go | 20 ++--- core/coreiface/tests/pubsub.go | 8 +- core/coreiface/tests/unixfs.go | 70 ++++++++--------- 11 files changed, 238 insertions(+), 318 deletions(-) diff --git a/core/coreiface/tests/api.go b/core/coreiface/tests/api.go index 8baa869dd..a4b0312f6 100644 --- a/core/coreiface/tests/api.go +++ b/core/coreiface/tests/api.go @@ -2,111 +2,13 @@ package tests import ( "context" - "encoding/base64" - "fmt" "testing" - "github.com/ipfs/go-ipfs/core" - "github.com/ipfs/go-ipfs/core/coreapi" coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface" - mock "github.com/ipfs/go-ipfs/core/mock" - "github.com/ipfs/go-ipfs/keystore" - "github.com/ipfs/go-ipfs/repo" - - ci "gx/ipfs/QmNiJiXwWE3kRhZrC5ej3kSjWHm337pYfhjLGSCDNKJP2s/go-libp2p-crypto" - "gx/ipfs/QmRBaUEQEeFWywfrZJ64QgsmvcqgLSK3VbvGMR2NM2Edpf/go-libp2p/p2p/net/mock" - "gx/ipfs/QmY5Grm8pJdiSSVsYxx4uNRgweY72EmYwuSDbRnbFok3iY/go-libp2p-peer" - pstore "gx/ipfs/QmZ9zH2FnLcxv1xyzFeUpDUeo55xEhZQHgveZijcxr7TLj/go-libp2p-peerstore" - "gx/ipfs/QmcZfkbgwwwH5ZLTQRHkSQBDiDqd3skY2eU6MZRgWuXcse/go-ipfs-config" - "gx/ipfs/Qmf4xQhNomPNhrtZc67qSnfJSjxjXs9LWvknJtSXwimPrM/go-datastore" - syncds "gx/ipfs/Qmf4xQhNomPNhrtZc67qSnfJSjxjXs9LWvknJtSXwimPrM/go-datastore/sync" ) - -func makeAPISwarm(ctx context.Context, fullIdentity bool, n int) ([]coreiface.CoreAPI, error) { - mn := mocknet.New(ctx) - - nodes := make([]*core.IpfsNode, n) - apis := make([]coreiface.CoreAPI, n) - - for i := 0; i < n; i++ { - var ident config.Identity - if fullIdentity { - sk, pk, err := ci.GenerateKeyPair(ci.RSA, 512) - if err != nil { - return nil, err - } - - id, err := peer.IDFromPublicKey(pk) - if err != nil { - return nil, err - } - - kbytes, err := sk.Bytes() - if err != nil { - return nil, err - } - - ident = config.Identity{ - PeerID: id.Pretty(), - PrivKey: base64.StdEncoding.EncodeToString(kbytes), - } - } else { - ident = config.Identity{ - PeerID: testPeerID, - } - } - - c := config.Config{} - c.Addresses.Swarm = []string{fmt.Sprintf("/ip4/127.0.%d.1/tcp/4001", i)} - c.Identity = ident - - r := &repo.Mock{ - C: c, - D: syncds.MutexWrap(datastore.NewMapDatastore()), - K: keystore.NewMemKeystore(), - } - - node, err := core.NewNode(ctx, &core.BuildCfg{ - Repo: r, - Host: mock.MockHostOption(mn), - Online: fullIdentity, - ExtraOpts: map[string]bool{ - "pubsub": true, - }, - }) - if err != nil { - return nil, err - } - nodes[i] = node - apis[i], err = coreapi.NewCoreAPI(node) - if err != nil { - return nil, err - } - } - - err := mn.LinkAll() - if err != nil { - return nil, err - } - - bsinf := core.BootstrapConfigWithPeers( - []pstore.PeerInfo{ - nodes[0].Peerstore.PeerInfo(nodes[0].Identity), - }, - ) - - for _, n := range nodes[1:] { - if err := n.Bootstrap(bsinf); err != nil { - return nil, err - } - } - - return apis, nil -} - -func makeAPI(ctx context.Context) (coreiface.CoreAPI, error) { - api, err := makeAPISwarm(ctx, false, 1) +func (tp *provider) makeAPI(ctx context.Context) (coreiface.CoreAPI, error) { + api, err := tp.MakeAPISwarm(ctx, false, 1) if err != nil { return nil, err } @@ -114,16 +16,28 @@ func makeAPI(ctx context.Context) (coreiface.CoreAPI, error) { return api[0], nil } - -func TestApi(t *testing.T) { - t.Run("Block", TestBlock) - t.Run("TestDag", TestDag) - t.Run("TestDht", TestDht) - t.Run("TestKey", TestKey) - t.Run("TestName", TestName) - t.Run("TestObject", TestObject) - t.Run("TestPath", TestPath) - t.Run("TestPin", TestPin) - t.Run("TestPubSub", TestPubSub) - t.Run("TestUnixfs", TestUnixfs) +type Provider interface { + // Make creates n nodes. fullIdentity set to false can be ignored + MakeAPISwarm(ctx context.Context, fullIdentity bool, n int) ([]coreiface.CoreAPI, error) +} + +type provider struct { + Provider +} + +func TestApi(p Provider) func(t *testing.T) { + tp := &provider{p} + + return func(t *testing.T) { + t.Run("Block", tp.TestBlock) + t.Run("Dag", tp.TestDag) + t.Run("Dht", tp.TestDht) + t.Run("Key", tp.TestKey) + t.Run("Name", tp.TestName) + t.Run("Object", tp.TestObject) + t.Run("Path", tp.TestPath) + t.Run("Pin", tp.TestPin) + t.Run("PubSub", tp.TestPubSub) + t.Run("Unixfs", tp.TestUnixfs) + } } diff --git a/core/coreiface/tests/block.go b/core/coreiface/tests/block.go index 07679a926..0ee968860 100644 --- a/core/coreiface/tests/block.go +++ b/core/coreiface/tests/block.go @@ -12,18 +12,18 @@ import ( mh "gx/ipfs/QmerPMzPk1mJVowm8KgmoknWa4yCYvvugMPsgWmDNUvDLW/go-multihash" ) -func TestBlock(t *testing.T) { - t.Run("TestBlockPut", TestBlockPut) - t.Run("TestBlockPutFormat", TestBlockPutFormat) - t.Run("TestBlockPutHash", TestBlockPutHash) - t.Run("TestBlockGet", TestBlockGet) - t.Run("TestBlockRm", TestBlockRm) - t.Run("TestBlockStat", TestBlockStat) +func (tp *provider) TestBlock(t *testing.T) { + t.Run("TestBlockPut", tp.TestBlockPut) + t.Run("TestBlockPutFormat", tp.TestBlockPutFormat) + t.Run("TestBlockPutHash", tp.TestBlockPutHash) + t.Run("TestBlockGet", tp.TestBlockGet) + t.Run("TestBlockRm", tp.TestBlockRm) + t.Run("TestBlockStat", tp.TestBlockStat) } -func TestBlockPut(t *testing.T) { +func (tp *provider) TestBlockPut(t *testing.T) { ctx := context.Background() - api, err := makeAPI(ctx) + api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) } @@ -38,9 +38,9 @@ func TestBlockPut(t *testing.T) { } } -func TestBlockPutFormat(t *testing.T) { +func (tp *provider) TestBlockPutFormat(t *testing.T) { ctx := context.Background() - api, err := makeAPI(ctx) + api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) } @@ -55,9 +55,9 @@ func TestBlockPutFormat(t *testing.T) { } } -func TestBlockPutHash(t *testing.T) { +func (tp *provider) TestBlockPutHash(t *testing.T) { ctx := context.Background() - api, err := makeAPI(ctx) + api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) } @@ -72,9 +72,9 @@ func TestBlockPutHash(t *testing.T) { } } -func TestBlockGet(t *testing.T) { +func (tp *provider) TestBlockGet(t *testing.T) { ctx := context.Background() - api, err := makeAPI(ctx) + api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) } @@ -112,9 +112,9 @@ func TestBlockGet(t *testing.T) { } } -func TestBlockRm(t *testing.T) { +func (tp *provider) TestBlockRm(t *testing.T) { ctx := context.Background() - api, err := makeAPI(ctx) + api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) } @@ -165,9 +165,9 @@ func TestBlockRm(t *testing.T) { } } -func TestBlockStat(t *testing.T) { +func (tp *provider) TestBlockStat(t *testing.T) { ctx := context.Background() - api, err := makeAPI(ctx) + api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) } diff --git a/core/coreiface/tests/dag.go b/core/coreiface/tests/dag.go index a75438ab1..f19216221 100644 --- a/core/coreiface/tests/dag.go +++ b/core/coreiface/tests/dag.go @@ -12,12 +12,12 @@ import ( mh "gx/ipfs/QmerPMzPk1mJVowm8KgmoknWa4yCYvvugMPsgWmDNUvDLW/go-multihash" ) -func TestDag(t *testing.T) { - t.Run("TestPut", TestPut) - t.Run("TestPutWithHash", TestPutWithHash) - t.Run("TestPath", TestDagPath) - t.Run("TestTree", TestTree) - t.Run("TestBatch", TestBatch) +func (tp *provider) TestDag(t *testing.T) { + t.Run("TestPut", tp.TestPut) + t.Run("TestPutWithHash", tp.TestPutWithHash) + t.Run("TestPath", tp.TestDagPath) + t.Run("TestTree", tp.TestTree) + t.Run("TestBatch", tp.TestBatch) } var ( @@ -30,9 +30,9 @@ var ( } ) -func TestPut(t *testing.T) { +func (tp *provider) TestPut(t *testing.T) { ctx := context.Background() - api, err := makeAPI(ctx) + api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) } @@ -47,9 +47,9 @@ func TestPut(t *testing.T) { } } -func TestPutWithHash(t *testing.T) { +func (tp *provider) TestPutWithHash(t *testing.T) { ctx := context.Background() - api, err := makeAPI(ctx) + api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) } @@ -64,9 +64,9 @@ func TestPutWithHash(t *testing.T) { } } -func TestDagPath(t *testing.T) { +func (tp *provider) TestDagPath(t *testing.T) { ctx := context.Background() - api, err := makeAPI(ctx) + api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) } @@ -96,9 +96,9 @@ func TestDagPath(t *testing.T) { } } -func TestTree(t *testing.T) { +func (tp *provider) TestTree(t *testing.T) { ctx := context.Background() - api, err := makeAPI(ctx) + api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) } @@ -125,9 +125,9 @@ func TestTree(t *testing.T) { } } -func TestBatch(t *testing.T) { +func (tp *provider) TestBatch(t *testing.T) { ctx := context.Background() - api, err := makeAPI(ctx) + api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) } diff --git a/core/coreiface/tests/dht.go b/core/coreiface/tests/dht.go index 429197f70..9269bc4c5 100644 --- a/core/coreiface/tests/dht.go +++ b/core/coreiface/tests/dht.go @@ -8,15 +8,15 @@ import ( "github.com/ipfs/go-ipfs/core/coreapi/interface/options" ) -func TestDht(t *testing.T) { - t.Run("TestDhtFindPeer", TestDhtFindPeer) - t.Run("TestDhtFindProviders", TestDhtFindProviders) - t.Run("TestDhtProvide", TestDhtProvide) +func (tp *provider) TestDht(t *testing.T) { + t.Run("TestDhtFindPeer", tp.TestDhtFindPeer) + t.Run("TestDhtFindProviders", tp.TestDhtFindProviders) + t.Run("TestDhtProvide", tp.TestDhtProvide) } -func TestDhtFindPeer(t *testing.T) { +func (tp *provider) TestDhtFindPeer(t *testing.T) { ctx := context.Background() - apis, err := makeAPISwarm(ctx, true, 5) + apis, err := tp.MakeAPISwarm(ctx, true, 5) if err != nil { t.Fatal(err) } @@ -50,9 +50,9 @@ func TestDhtFindPeer(t *testing.T) { } } -func TestDhtFindProviders(t *testing.T) { +func (tp *provider) TestDhtFindProviders(t *testing.T) { ctx := context.Background() - apis, err := makeAPISwarm(ctx, true, 5) + apis, err := tp.MakeAPISwarm(ctx, true, 5) if err != nil { t.Fatal(err) } @@ -79,9 +79,9 @@ func TestDhtFindProviders(t *testing.T) { } } -func TestDhtProvide(t *testing.T) { +func (tp *provider) TestDhtProvide(t *testing.T) { ctx := context.Background() - apis, err := makeAPISwarm(ctx, true, 5) + apis, err := tp.MakeAPISwarm(ctx, true, 5) if err != nil { t.Fatal(err) } diff --git a/core/coreiface/tests/key.go b/core/coreiface/tests/key.go index b08f56a4f..c2b892599 100644 --- a/core/coreiface/tests/key.go +++ b/core/coreiface/tests/key.go @@ -8,31 +8,38 @@ import ( opt "github.com/ipfs/go-ipfs/core/coreapi/interface/options" ) -func TestKey(t *testing.T) { - t.Run("TestListSelf", TestListSelf) - t.Run("TestRenameSelf", TestRenameSelf) - t.Run("TestRemoveSelf", TestRemoveSelf) - t.Run("TestGenerateSize", TestGenerateSize) - t.Run("TestGenerateExisting", TestGenerateExisting) - t.Run("TestList", TestList) - t.Run("TestRename", TestRename) - t.Run("TestRenameToSelf", TestRenameToSelf) - t.Run("TestRenameToSelfForce", TestRenameToSelfForce) - t.Run("TestRenameOverwriteNoForce", TestRenameOverwriteNoForce) - t.Run("TestRenameOverwrite", TestRenameOverwrite) - t.Run("TestRenameSameNameNoForce", TestRenameSameNameNoForce) - t.Run("TestRenameSameName", TestRenameSameName) - t.Run("TestRemove", TestRemove) +func (tp *provider) TestKey(t *testing.T) { + t.Run("TestListSelf", tp.TestListSelf) + t.Run("TestRenameSelf", tp.TestRenameSelf) + t.Run("TestRemoveSelf", tp.TestRemoveSelf) + t.Run("TestGenerate", tp.TestGenerate) + t.Run("TestGenerateSize", tp.TestGenerateSize) + t.Run("TestGenerateType", tp.TestGenerateType) + t.Run("TestGenerateExisting", tp.TestGenerateExisting) + t.Run("TestList", tp.TestList) + t.Run("TestRename", tp.TestRename) + t.Run("TestRenameToSelf", tp.TestRenameToSelf) + t.Run("TestRenameToSelfForce", tp.TestRenameToSelfForce) + t.Run("TestRenameOverwriteNoForce", tp.TestRenameOverwriteNoForce) + t.Run("TestRenameOverwrite", tp.TestRenameOverwrite) + t.Run("TestRenameSameNameNoForce", tp.TestRenameSameNameNoForce) + t.Run("TestRenameSameName", tp.TestRenameSameName) + t.Run("TestRemove", tp.TestRemove) } -func TestListSelf(t *testing.T) { +func (tp *provider) TestListSelf(t *testing.T) { ctx := context.Background() - api, err := makeAPI(ctx) + api, err := tp.makeAPI(ctx) if err != nil { t.Fatal(err) return } + self, err := api.Key().Self(ctx) + if err != nil { + t.Fatal(err) + } + keys, err := api.Key().List(ctx) if err != nil { t.Fatalf("failed to list keys: %s", err) @@ -48,14 +55,14 @@ func TestListSelf(t *testing.T) { t.Errorf("expected the key to be called 'self', got '%s'", keys[0].Name()) } - if keys[0].Path().String() != "/ipns/"+testPeerID { - t.Errorf("expected the key to have path '/ipns/%s', got '%s'", testPeerID, keys[0].Path().String()) + if keys[0].Path().String() != "/ipns/"+self.ID().Pretty() { + t.Errorf("expected the key to have path '/ipns/%s', got '%s'", self.ID().Pretty(), keys[0].Path().String()) } } -func TestRenameSelf(t *testing.T) { +func (tp *provider) TestRenameSelf(t *testing.T) { ctx := context.Background() - api, err := makeAPI(ctx) + api, err := tp.makeAPI(ctx) if err != nil { t.Fatal(err) return @@ -80,9 +87,9 @@ func TestRenameSelf(t *testing.T) { } } -func TestRemoveSelf(t *testing.T) { +func (tp *provider) TestRemoveSelf(t *testing.T) { ctx := context.Background() - api, err := makeAPI(ctx) + api, err := tp.makeAPI(ctx) if err != nil { t.Fatal(err) return @@ -98,9 +105,9 @@ func TestRemoveSelf(t *testing.T) { } } -func TestGenerate(t *testing.T) { +func (tp *provider) TestGenerate(t *testing.T) { ctx := context.Background() - api, err := makeAPI(ctx) + api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) } @@ -120,9 +127,9 @@ func TestGenerate(t *testing.T) { } } -func TestGenerateSize(t *testing.T) { +func (tp *provider) TestGenerateSize(t *testing.T) { ctx := context.Background() - api, err := makeAPI(ctx) + api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) } @@ -142,11 +149,11 @@ func TestGenerateSize(t *testing.T) { } } -func TestGenerateType(t *testing.T) { +func (tp *provider) TestGenerateType(t *testing.T) { ctx := context.Background() t.Skip("disabled until libp2p/specs#111 is fixed") - api, err := makeAPI(ctx) + api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) } @@ -167,9 +174,9 @@ func TestGenerateType(t *testing.T) { } } -func TestGenerateExisting(t *testing.T) { +func (tp *provider) TestGenerateExisting(t *testing.T) { ctx := context.Background() - api, err := makeAPI(ctx) + api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) } @@ -199,9 +206,9 @@ func TestGenerateExisting(t *testing.T) { } } -func TestList(t *testing.T) { +func (tp *provider) TestList(t *testing.T) { ctx := context.Background() - api, err := makeAPI(ctx) + api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) } @@ -244,9 +251,9 @@ func TestList(t *testing.T) { } } -func TestRename(t *testing.T) { +func (tp *provider) TestRename(t *testing.T) { ctx := context.Background() - api, err := makeAPI(ctx) + api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) } @@ -272,9 +279,9 @@ func TestRename(t *testing.T) { } } -func TestRenameToSelf(t *testing.T) { +func (tp *provider) TestRenameToSelf(t *testing.T) { ctx := context.Background() - api, err := makeAPI(ctx) + api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) } @@ -295,9 +302,9 @@ func TestRenameToSelf(t *testing.T) { } } -func TestRenameToSelfForce(t *testing.T) { +func (tp *provider) TestRenameToSelfForce(t *testing.T) { ctx := context.Background() - api, err := makeAPI(ctx) + api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) } @@ -318,9 +325,9 @@ func TestRenameToSelfForce(t *testing.T) { } } -func TestRenameOverwriteNoForce(t *testing.T) { +func (tp *provider) TestRenameOverwriteNoForce(t *testing.T) { ctx := context.Background() - api, err := makeAPI(ctx) + api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) } @@ -347,9 +354,9 @@ func TestRenameOverwriteNoForce(t *testing.T) { } } -func TestRenameOverwrite(t *testing.T) { +func (tp *provider) TestRenameOverwrite(t *testing.T) { ctx := context.Background() - api, err := makeAPI(ctx) + api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) } @@ -385,9 +392,9 @@ func TestRenameOverwrite(t *testing.T) { } } -func TestRenameSameNameNoForce(t *testing.T) { +func (tp *provider) TestRenameSameNameNoForce(t *testing.T) { ctx := context.Background() - api, err := makeAPI(ctx) + api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) } @@ -413,9 +420,9 @@ func TestRenameSameNameNoForce(t *testing.T) { } } -func TestRenameSameName(t *testing.T) { +func (tp *provider) TestRenameSameName(t *testing.T) { ctx := context.Background() - api, err := makeAPI(ctx) + api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) } @@ -441,9 +448,9 @@ func TestRenameSameName(t *testing.T) { } } -func TestRemove(t *testing.T) { +func (tp *provider) TestRemove(t *testing.T) { ctx := context.Background() - api, err := makeAPI(ctx) + api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) } diff --git a/core/coreiface/tests/name.go b/core/coreiface/tests/name.go index 154c1d444..ecb06ddde 100644 --- a/core/coreiface/tests/name.go +++ b/core/coreiface/tests/name.go @@ -15,9 +15,10 @@ import ( opt "github.com/ipfs/go-ipfs/core/coreapi/interface/options" ) -func TestName(t *testing.T) { - t.Run("TestPublishResolve", TestPublishResolve) - t.Run("TestBasicPublishResolveKey", TestBasicPublishResolveKey) +func (tp *provider) TestName(t *testing.T) { + t.Run("TestPublishResolve", tp.TestPublishResolve) + t.Run("TestBasicPublishResolveKey", tp.TestBasicPublishResolveKey) + t.Run("TestBasicPublishResolveTimeout", tp.TestBasicPublishResolveTimeout) } var rnd = rand.New(rand.NewSource(0x62796532303137)) @@ -34,10 +35,10 @@ func appendPath(p coreiface.Path, sub string) coreiface.Path { return p } -func TestPublishResolve(t *testing.T) { +func (tp *provider) TestPublishResolve(t *testing.T) { ctx := context.Background() init := func() (coreiface.CoreAPI, coreiface.Path) { - apis, err := makeAPISwarm(ctx, true, 5) + apis, err := tp.MakeAPISwarm(ctx, true, 5) if err != nil { t.Fatal(err) return nil, nil @@ -183,9 +184,9 @@ func TestPublishResolve(t *testing.T) { }) } -func TestBasicPublishResolveKey(t *testing.T) { +func (tp *provider) TestBasicPublishResolveKey(t *testing.T) { ctx := context.Background() - apis, err := makeAPISwarm(ctx, true, 5) + apis, err := tp.MakeAPISwarm(ctx, true, 5) if err != nil { t.Fatal(err) } @@ -224,11 +225,11 @@ func TestBasicPublishResolveKey(t *testing.T) { } } -func TestBasicPublishResolveTimeout(t *testing.T) { +func (tp *provider) TestBasicPublishResolveTimeout(t *testing.T) { t.Skip("ValidTime doesn't appear to work at this time resolution") ctx := context.Background() - apis, err := makeAPISwarm(ctx, true, 5) + apis, err := tp.MakeAPISwarm(ctx, true, 5) if err != nil { t.Fatal(err) } diff --git a/core/coreiface/tests/object.go b/core/coreiface/tests/object.go index 7d4243bca..349b4a8f5 100644 --- a/core/coreiface/tests/object.go +++ b/core/coreiface/tests/object.go @@ -12,24 +12,24 @@ import ( opt "github.com/ipfs/go-ipfs/core/coreapi/interface/options" ) -func TestObject(t *testing.T) { - t.Run("TestNew", TestNew) - t.Run("TestObjectPut", TestObjectPut) - t.Run("TestObjectGet", TestObjectGet) - t.Run("TestObjectData", TestObjectData) - t.Run("TestObjectLinks", TestObjectLinks) - t.Run("TestObjectStat", TestObjectStat) - t.Run("TestObjectAddLink", TestObjectAddLink) - t.Run("TestObjectAddLinkCreate", TestObjectAddLinkCreate) - t.Run("TestObjectRmLink", TestObjectRmLink) - t.Run("TestObjectAddData", TestObjectAddData) - t.Run("TestObjectSetData", TestObjectSetData) - t.Run("TestDiffTest", TestDiffTest) +func (tp *provider) TestObject(t *testing.T) { + t.Run("TestNew", tp.TestNew) + t.Run("TestObjectPut", tp.TestObjectPut) + t.Run("TestObjectGet", tp.TestObjectGet) + t.Run("TestObjectData", tp.TestObjectData) + t.Run("TestObjectLinks", tp.TestObjectLinks) + t.Run("TestObjectStat", tp.TestObjectStat) + t.Run("TestObjectAddLink", tp.TestObjectAddLink) + t.Run("TestObjectAddLinkCreate", tp.TestObjectAddLinkCreate) + t.Run("TestObjectRmLink", tp.TestObjectRmLink) + t.Run("TestObjectAddData", tp.TestObjectAddData) + t.Run("TestObjectSetData", tp.TestObjectSetData) + t.Run("TestDiffTest", tp.TestDiffTest) } -func TestNew(t *testing.T) { +func (tp *provider) TestNew(t *testing.T) { ctx := context.Background() - api, err := makeAPI(ctx) + api, err := tp.makeAPI(ctx) if err != nil { t.Fatal(err) } @@ -53,9 +53,9 @@ func TestNew(t *testing.T) { } } -func TestObjectPut(t *testing.T) { +func (tp *provider) TestObjectPut(t *testing.T) { ctx := context.Background() - api, err := makeAPI(ctx) + api, err := tp.makeAPI(ctx) if err != nil { t.Fatal(err) } @@ -93,9 +93,9 @@ func TestObjectPut(t *testing.T) { } } -func TestObjectGet(t *testing.T) { +func (tp *provider) TestObjectGet(t *testing.T) { ctx := context.Background() - api, err := makeAPI(ctx) + api, err := tp.makeAPI(ctx) if err != nil { t.Fatal(err) } @@ -115,9 +115,9 @@ func TestObjectGet(t *testing.T) { } } -func TestObjectData(t *testing.T) { +func (tp *provider) TestObjectData(t *testing.T) { ctx := context.Background() - api, err := makeAPI(ctx) + api, err := tp.makeAPI(ctx) if err != nil { t.Fatal(err) } @@ -142,9 +142,9 @@ func TestObjectData(t *testing.T) { } } -func TestObjectLinks(t *testing.T) { +func (tp *provider) TestObjectLinks(t *testing.T) { ctx := context.Background() - api, err := makeAPI(ctx) + api, err := tp.makeAPI(ctx) if err != nil { t.Fatal(err) } @@ -177,9 +177,9 @@ func TestObjectLinks(t *testing.T) { } } -func TestObjectStat(t *testing.T) { +func (tp *provider) TestObjectStat(t *testing.T) { ctx := context.Background() - api, err := makeAPI(ctx) + api, err := tp.makeAPI(ctx) if err != nil { t.Fatal(err) } @@ -224,9 +224,9 @@ func TestObjectStat(t *testing.T) { } } -func TestObjectAddLink(t *testing.T) { +func (tp *provider) TestObjectAddLink(t *testing.T) { ctx := context.Background() - api, err := makeAPI(ctx) + api, err := tp.makeAPI(ctx) if err != nil { t.Fatal(err) } @@ -264,9 +264,9 @@ func TestObjectAddLink(t *testing.T) { } } -func TestObjectAddLinkCreate(t *testing.T) { +func (tp *provider) TestObjectAddLinkCreate(t *testing.T) { ctx := context.Background() - api, err := makeAPI(ctx) + api, err := tp.makeAPI(ctx) if err != nil { t.Fatal(err) } @@ -312,9 +312,9 @@ func TestObjectAddLinkCreate(t *testing.T) { } } -func TestObjectRmLink(t *testing.T) { +func (tp *provider) TestObjectRmLink(t *testing.T) { ctx := context.Background() - api, err := makeAPI(ctx) + api, err := tp.makeAPI(ctx) if err != nil { t.Fatal(err) } @@ -344,9 +344,9 @@ func TestObjectRmLink(t *testing.T) { } } -func TestObjectAddData(t *testing.T) { +func (tp *provider) TestObjectAddData(t *testing.T) { ctx := context.Background() - api, err := makeAPI(ctx) + api, err := tp.makeAPI(ctx) if err != nil { t.Fatal(err) } @@ -373,9 +373,9 @@ func TestObjectAddData(t *testing.T) { } } -func TestObjectSetData(t *testing.T) { +func (tp *provider) TestObjectSetData(t *testing.T) { ctx := context.Background() - api, err := makeAPI(ctx) + api, err := tp.makeAPI(ctx) if err != nil { t.Fatal(err) } @@ -402,9 +402,9 @@ func TestObjectSetData(t *testing.T) { } } -func TestDiffTest(t *testing.T) { +func (tp *provider) TestDiffTest(t *testing.T) { ctx := context.Background() - api, err := makeAPI(ctx) + api, err := tp.makeAPI(ctx) if err != nil { t.Fatal(err) } diff --git a/core/coreiface/tests/path.go b/core/coreiface/tests/path.go index efbacd29f..cb1246366 100644 --- a/core/coreiface/tests/path.go +++ b/core/coreiface/tests/path.go @@ -9,17 +9,17 @@ import ( "github.com/ipfs/go-ipfs/core/coreapi/interface/options" ) -func TestPath(t *testing.T) { - t.Run("TestMutablePath", TestMutablePath) - t.Run("TestPathRemainder", TestPathRemainder) - t.Run("TestEmptyPathRemainder", TestEmptyPathRemainder) - t.Run("TestInvalidPathRemainder", TestInvalidPathRemainder) - t.Run("TestPathRoot", TestPathRoot) +func (tp *provider) TestPath(t *testing.T) { + t.Run("TestMutablePath", tp.TestMutablePath) + t.Run("TestPathRemainder", tp.TestPathRemainder) + t.Run("TestEmptyPathRemainder", tp.TestEmptyPathRemainder) + t.Run("TestInvalidPathRemainder", tp.TestInvalidPathRemainder) + t.Run("TestPathRoot", tp.TestPathRoot) } -func TestMutablePath(t *testing.T) { +func (tp *provider) TestMutablePath(t *testing.T) { ctx := context.Background() - api, err := makeAPI(ctx) + api, err := tp.makeAPI(ctx) if err != nil { t.Fatal(err) } @@ -44,9 +44,9 @@ func TestMutablePath(t *testing.T) { } } -func TestPathRemainder(t *testing.T) { +func (tp *provider) TestPathRemainder(t *testing.T) { ctx := context.Background() - api, err := makeAPI(ctx) + api, err := tp.makeAPI(ctx) if err != nil { t.Fatal(err) } @@ -71,9 +71,9 @@ func TestPathRemainder(t *testing.T) { } } -func TestEmptyPathRemainder(t *testing.T) { +func (tp *provider) TestEmptyPathRemainder(t *testing.T) { ctx := context.Background() - api, err := makeAPI(ctx) + api, err := tp.makeAPI(ctx) if err != nil { t.Fatal(err) } @@ -102,9 +102,9 @@ func TestEmptyPathRemainder(t *testing.T) { } } -func TestInvalidPathRemainder(t *testing.T) { +func (tp *provider) TestInvalidPathRemainder(t *testing.T) { ctx := context.Background() - api, err := makeAPI(ctx) + api, err := tp.makeAPI(ctx) if err != nil { t.Fatal(err) } @@ -125,9 +125,9 @@ func TestInvalidPathRemainder(t *testing.T) { } } -func TestPathRoot(t *testing.T) { +func (tp *provider) TestPathRoot(t *testing.T) { ctx := context.Background() - api, err := makeAPI(ctx) + api, err := tp.makeAPI(ctx) if err != nil { t.Fatal(err) } diff --git a/core/coreiface/tests/pin.go b/core/coreiface/tests/pin.go index 344cd0db7..8c659ba35 100644 --- a/core/coreiface/tests/pin.go +++ b/core/coreiface/tests/pin.go @@ -8,15 +8,15 @@ import ( opt "github.com/ipfs/go-ipfs/core/coreapi/interface/options" ) -func TestPin(t *testing.T) { - t.Run("TestPinAdd", TestPinAdd) - t.Run("TestPinSimple", TestPinSimple) - t.Run("TestPinRecursive", TestPinRecursive) +func (tp *provider) TestPin(t *testing.T) { + t.Run("TestPinAdd", tp.TestPinAdd) + t.Run("TestPinSimple", tp.TestPinSimple) + t.Run("TestPinRecursive", tp.TestPinRecursive) } -func TestPinAdd(t *testing.T) { +func (tp *provider) TestPinAdd(t *testing.T) { ctx := context.Background() - api, err := makeAPI(ctx) + api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) } @@ -32,9 +32,9 @@ func TestPinAdd(t *testing.T) { } } -func TestPinSimple(t *testing.T) { +func (tp *provider) TestPinSimple(t *testing.T) { ctx := context.Background() - api, err := makeAPI(ctx) + api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) } @@ -81,9 +81,9 @@ func TestPinSimple(t *testing.T) { } } -func TestPinRecursive(t *testing.T) { +func (tp *provider) TestPinRecursive(t *testing.T) { ctx := context.Background() - api, err := makeAPI(ctx) + api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) } diff --git a/core/coreiface/tests/pubsub.go b/core/coreiface/tests/pubsub.go index 3ecd80274..3462b4755 100644 --- a/core/coreiface/tests/pubsub.go +++ b/core/coreiface/tests/pubsub.go @@ -7,15 +7,15 @@ import ( "time" ) -func TestPubSub(t *testing.T) { - t.Run("TestBasicPubSub", TestBasicPubSub) +func (tp *provider) TestPubSub(t *testing.T) { + t.Run("TestBasicPubSub", tp.TestBasicPubSub) } -func TestBasicPubSub(t *testing.T) { +func (tp *provider) TestBasicPubSub(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - apis, err := makeAPISwarm(ctx, true, 2) + apis, err := tp.MakeAPISwarm(ctx, true, 2) if err != nil { t.Fatal(err) } diff --git a/core/coreiface/tests/unixfs.go b/core/coreiface/tests/unixfs.go index 1ca0b282a..b31a55d4c 100644 --- a/core/coreiface/tests/unixfs.go +++ b/core/coreiface/tests/unixfs.go @@ -23,22 +23,20 @@ import ( mh "gx/ipfs/QmerPMzPk1mJVowm8KgmoknWa4yCYvvugMPsgWmDNUvDLW/go-multihash" ) -func TestUnixfs(t *testing.T) { - t.Run("TestAdd", TestAdd) - t.Run("TestAddPinned", TestAddPinned) - t.Run("TestAddHashOnly", TestAddHashOnly) - t.Run("TestGetEmptyFile", TestGetEmptyFile) - t.Run("TestGetDir", TestGetDir) - t.Run("TestGetNonUnixfs", TestGetNonUnixfs) - t.Run("TestLs", TestLs) - t.Run("TestEntriesExpired", TestEntriesExpired) - t.Run("TestLsEmptyDir", TestLsEmptyDir) - t.Run("TestLsNonUnixfs", TestLsNonUnixfs) - t.Run("TestAddCloses", TestAddCloses) +func (tp *provider) TestUnixfs(t *testing.T) { + t.Run("TestAdd", tp.TestAdd) + t.Run("TestAddPinned", tp.TestAddPinned) + t.Run("TestAddHashOnly", tp.TestAddHashOnly) + t.Run("TestGetEmptyFile", tp.TestGetEmptyFile) + t.Run("TestGetDir", tp.TestGetDir) + t.Run("TestGetNonUnixfs", tp.TestGetNonUnixfs) + t.Run("TestLs", tp.TestLs) + t.Run("TestEntriesExpired", tp.TestEntriesExpired) + t.Run("TestLsEmptyDir", tp.TestLsEmptyDir) + t.Run("TestLsNonUnixfs", tp.TestLsNonUnixfs) + t.Run("TestAddCloses", tp.TestAddCloses) } -const testPeerID = "QmTFauExutTsy4XP6JbMFcw2Wa9645HJt2bTqL6qYDCKfe" - // `echo -n 'hello, world!' | ipfs add` var hello = "/ipfs/QmQy2Dw4Wk7rdJKjThjYXzfFJNaRKRHhHP5gHHXroJMYxk" var helloStr = "hello, world!" @@ -80,9 +78,9 @@ func wrapped(name string) func(f files.Node) files.Node { } } -func TestAdd(t *testing.T) { +func (tp *provider) TestAdd(t *testing.T) { ctx := context.Background() - api, err := makeAPI(ctx) + api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) } @@ -537,9 +535,9 @@ func TestAdd(t *testing.T) { } } -func TestAddPinned(t *testing.T) { +func (tp *provider) TestAddPinned(t *testing.T) { ctx := context.Background() - api, err := makeAPI(ctx) + api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) } @@ -559,9 +557,9 @@ func TestAddPinned(t *testing.T) { } } -func TestAddHashOnly(t *testing.T) { +func (tp *provider) TestAddHashOnly(t *testing.T) { ctx := context.Background() - api, err := makeAPI(ctx) + api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) } @@ -584,9 +582,9 @@ func TestAddHashOnly(t *testing.T) { } } -func TestGetEmptyFile(t *testing.T) { +func (tp *provider) TestGetEmptyFile(t *testing.T) { ctx := context.Background() - api, err := makeAPI(ctx) + api, err := tp.makeAPI(ctx) if err != nil { t.Fatal(err) } @@ -616,9 +614,9 @@ func TestGetEmptyFile(t *testing.T) { } } -func TestGetDir(t *testing.T) { +func (tp *provider) TestGetDir(t *testing.T) { ctx := context.Background() - api, err := makeAPI(ctx) + api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) } @@ -648,9 +646,9 @@ func TestGetDir(t *testing.T) { } } -func TestGetNonUnixfs(t *testing.T) { +func (tp *provider) TestGetNonUnixfs(t *testing.T) { ctx := context.Background() - api, err := makeAPI(ctx) + api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) } @@ -667,9 +665,9 @@ func TestGetNonUnixfs(t *testing.T) { } } -func TestLs(t *testing.T) { +func (tp *provider) TestLs(t *testing.T) { ctx := context.Background() - api, err := makeAPI(ctx) + api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) } @@ -703,9 +701,9 @@ func TestLs(t *testing.T) { } } -func TestEntriesExpired(t *testing.T) { +func (tp *provider) TestEntriesExpired(t *testing.T) { ctx := context.Background() - api, err := makeAPI(ctx) + api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) } @@ -746,9 +744,9 @@ func TestEntriesExpired(t *testing.T) { } } -func TestLsEmptyDir(t *testing.T) { +func (tp *provider) TestLsEmptyDir(t *testing.T) { ctx := context.Background() - api, err := makeAPI(ctx) + api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) } @@ -774,9 +772,9 @@ func TestLsEmptyDir(t *testing.T) { } // TODO(lgierth) this should test properly, with len(links) > 0 -func TestLsNonUnixfs(t *testing.T) { +func (tp *provider) TestLsNonUnixfs(t *testing.T) { ctx := context.Background() - api, err := makeAPI(ctx) + api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) } @@ -831,9 +829,9 @@ func (f *closeTestF) Close() error { return nil } -func TestAddCloses(t *testing.T) { +func (tp *provider) TestAddCloses(t *testing.T) { ctx := context.Background() - api, err := makeAPI(ctx) + api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) } From e5a2d8e6f6ac387985f52ccb9eaf3172dc5b88ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 20 Dec 2018 22:27:59 +0100 Subject: [PATCH 0168/1212] coreapi: make sure to cancel context in tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@aa64f771136226accbcae0213eb929ff79697046 This commit was moved from ipfs/boxo@23069a4c459b67e966fa5370e980aaab410e718b --- core/coreiface/tests/api.go | 37 +++++++++++++++++++++++++- core/coreiface/tests/block.go | 18 ++++++++----- core/coreiface/tests/dag.go | 15 +++++++---- core/coreiface/tests/dht.go | 9 ++++--- core/coreiface/tests/key.go | 48 ++++++++++++++++++++++------------ core/coreiface/tests/name.go | 9 ++++--- core/coreiface/tests/object.go | 36 ++++++++++++++++--------- core/coreiface/tests/path.go | 15 +++++++---- core/coreiface/tests/pin.go | 9 ++++--- core/coreiface/tests/unixfs.go | 35 ++++++++++++++++--------- 10 files changed, 165 insertions(+), 66 deletions(-) diff --git a/core/coreiface/tests/api.go b/core/coreiface/tests/api.go index a4b0312f6..ab1feff5b 100644 --- a/core/coreiface/tests/api.go +++ b/core/coreiface/tests/api.go @@ -3,6 +3,7 @@ package tests import ( "context" "testing" + "time" coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface" ) @@ -21,12 +22,37 @@ type Provider interface { MakeAPISwarm(ctx context.Context, fullIdentity bool, n int) ([]coreiface.CoreAPI, error) } +func (tp *provider) MakeAPISwarm(ctx context.Context, fullIdentity bool, n int) ([]coreiface.CoreAPI, error) { + tp.apis <- 1 + go func() { + <-ctx.Done() + tp.apis <- -1 + }() + + return tp.Provider.MakeAPISwarm(ctx, fullIdentity, n) +} + type provider struct { Provider + + apis chan int } func TestApi(p Provider) func(t *testing.T) { - tp := &provider{p} + running := 1 + apis := make(chan int) + zeroRunning := make(chan struct{}) + go func() { + for i := range apis { + running += i + if running < 1 { + close(zeroRunning) + return + } + } + }() + + tp := &provider{Provider: p, apis: apis} return func(t *testing.T) { t.Run("Block", tp.TestBlock) @@ -39,5 +65,14 @@ func TestApi(p Provider) func(t *testing.T) { t.Run("Pin", tp.TestPin) t.Run("PubSub", tp.TestPubSub) t.Run("Unixfs", tp.TestUnixfs) + + apis <- -1 + t.Run("TestsCancelCtx", func(t *testing.T) { + select { + case <-zeroRunning: + case <-time.After(time.Second): + t.Errorf("%d node(s) not closed", running) + } + }) } } diff --git a/core/coreiface/tests/block.go b/core/coreiface/tests/block.go index 0ee968860..a3a5f93aa 100644 --- a/core/coreiface/tests/block.go +++ b/core/coreiface/tests/block.go @@ -22,7 +22,8 @@ func (tp *provider) TestBlock(t *testing.T) { } func (tp *provider) TestBlockPut(t *testing.T) { - ctx := context.Background() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) @@ -39,7 +40,8 @@ func (tp *provider) TestBlockPut(t *testing.T) { } func (tp *provider) TestBlockPutFormat(t *testing.T) { - ctx := context.Background() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) @@ -56,7 +58,8 @@ func (tp *provider) TestBlockPutFormat(t *testing.T) { } func (tp *provider) TestBlockPutHash(t *testing.T) { - ctx := context.Background() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) @@ -73,7 +76,8 @@ func (tp *provider) TestBlockPutHash(t *testing.T) { } func (tp *provider) TestBlockGet(t *testing.T) { - ctx := context.Background() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) @@ -113,7 +117,8 @@ func (tp *provider) TestBlockGet(t *testing.T) { } func (tp *provider) TestBlockRm(t *testing.T) { - ctx := context.Background() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) @@ -166,7 +171,8 @@ func (tp *provider) TestBlockRm(t *testing.T) { } func (tp *provider) TestBlockStat(t *testing.T) { - ctx := context.Background() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) diff --git a/core/coreiface/tests/dag.go b/core/coreiface/tests/dag.go index f19216221..636c38699 100644 --- a/core/coreiface/tests/dag.go +++ b/core/coreiface/tests/dag.go @@ -31,7 +31,8 @@ var ( ) func (tp *provider) TestPut(t *testing.T) { - ctx := context.Background() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) @@ -48,7 +49,8 @@ func (tp *provider) TestPut(t *testing.T) { } func (tp *provider) TestPutWithHash(t *testing.T) { - ctx := context.Background() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) @@ -65,7 +67,8 @@ func (tp *provider) TestPutWithHash(t *testing.T) { } func (tp *provider) TestDagPath(t *testing.T) { - ctx := context.Background() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) @@ -97,7 +100,8 @@ func (tp *provider) TestDagPath(t *testing.T) { } func (tp *provider) TestTree(t *testing.T) { - ctx := context.Background() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) @@ -126,7 +130,8 @@ func (tp *provider) TestTree(t *testing.T) { } func (tp *provider) TestBatch(t *testing.T) { - ctx := context.Background() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) diff --git a/core/coreiface/tests/dht.go b/core/coreiface/tests/dht.go index 9269bc4c5..9b77f1679 100644 --- a/core/coreiface/tests/dht.go +++ b/core/coreiface/tests/dht.go @@ -15,7 +15,8 @@ func (tp *provider) TestDht(t *testing.T) { } func (tp *provider) TestDhtFindPeer(t *testing.T) { - ctx := context.Background() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() apis, err := tp.MakeAPISwarm(ctx, true, 5) if err != nil { t.Fatal(err) @@ -51,7 +52,8 @@ func (tp *provider) TestDhtFindPeer(t *testing.T) { } func (tp *provider) TestDhtFindProviders(t *testing.T) { - ctx := context.Background() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() apis, err := tp.MakeAPISwarm(ctx, true, 5) if err != nil { t.Fatal(err) @@ -80,7 +82,8 @@ func (tp *provider) TestDhtFindProviders(t *testing.T) { } func (tp *provider) TestDhtProvide(t *testing.T) { - ctx := context.Background() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() apis, err := tp.MakeAPISwarm(ctx, true, 5) if err != nil { t.Fatal(err) diff --git a/core/coreiface/tests/key.go b/core/coreiface/tests/key.go index c2b892599..99c30c302 100644 --- a/core/coreiface/tests/key.go +++ b/core/coreiface/tests/key.go @@ -28,7 +28,8 @@ func (tp *provider) TestKey(t *testing.T) { } func (tp *provider) TestListSelf(t *testing.T) { - ctx := context.Background() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() api, err := tp.makeAPI(ctx) if err != nil { t.Fatal(err) @@ -61,7 +62,8 @@ func (tp *provider) TestListSelf(t *testing.T) { } func (tp *provider) TestRenameSelf(t *testing.T) { - ctx := context.Background() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() api, err := tp.makeAPI(ctx) if err != nil { t.Fatal(err) @@ -88,7 +90,8 @@ func (tp *provider) TestRenameSelf(t *testing.T) { } func (tp *provider) TestRemoveSelf(t *testing.T) { - ctx := context.Background() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() api, err := tp.makeAPI(ctx) if err != nil { t.Fatal(err) @@ -106,7 +109,8 @@ func (tp *provider) TestRemoveSelf(t *testing.T) { } func (tp *provider) TestGenerate(t *testing.T) { - ctx := context.Background() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) @@ -128,7 +132,8 @@ func (tp *provider) TestGenerate(t *testing.T) { } func (tp *provider) TestGenerateSize(t *testing.T) { - ctx := context.Background() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) @@ -150,7 +155,8 @@ func (tp *provider) TestGenerateSize(t *testing.T) { } func (tp *provider) TestGenerateType(t *testing.T) { - ctx := context.Background() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() t.Skip("disabled until libp2p/specs#111 is fixed") api, err := tp.makeAPI(ctx) @@ -175,7 +181,8 @@ func (tp *provider) TestGenerateType(t *testing.T) { } func (tp *provider) TestGenerateExisting(t *testing.T) { - ctx := context.Background() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) @@ -207,7 +214,8 @@ func (tp *provider) TestGenerateExisting(t *testing.T) { } func (tp *provider) TestList(t *testing.T) { - ctx := context.Background() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) @@ -252,7 +260,8 @@ func (tp *provider) TestList(t *testing.T) { } func (tp *provider) TestRename(t *testing.T) { - ctx := context.Background() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) @@ -280,7 +289,8 @@ func (tp *provider) TestRename(t *testing.T) { } func (tp *provider) TestRenameToSelf(t *testing.T) { - ctx := context.Background() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) @@ -303,7 +313,8 @@ func (tp *provider) TestRenameToSelf(t *testing.T) { } func (tp *provider) TestRenameToSelfForce(t *testing.T) { - ctx := context.Background() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) @@ -326,7 +337,8 @@ func (tp *provider) TestRenameToSelfForce(t *testing.T) { } func (tp *provider) TestRenameOverwriteNoForce(t *testing.T) { - ctx := context.Background() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) @@ -355,7 +367,8 @@ func (tp *provider) TestRenameOverwriteNoForce(t *testing.T) { } func (tp *provider) TestRenameOverwrite(t *testing.T) { - ctx := context.Background() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) @@ -393,7 +406,8 @@ func (tp *provider) TestRenameOverwrite(t *testing.T) { } func (tp *provider) TestRenameSameNameNoForce(t *testing.T) { - ctx := context.Background() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) @@ -421,7 +435,8 @@ func (tp *provider) TestRenameSameNameNoForce(t *testing.T) { } func (tp *provider) TestRenameSameName(t *testing.T) { - ctx := context.Background() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) @@ -449,7 +464,8 @@ func (tp *provider) TestRenameSameName(t *testing.T) { } func (tp *provider) TestRemove(t *testing.T) { - ctx := context.Background() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) diff --git a/core/coreiface/tests/name.go b/core/coreiface/tests/name.go index ecb06ddde..e114b26de 100644 --- a/core/coreiface/tests/name.go +++ b/core/coreiface/tests/name.go @@ -36,7 +36,8 @@ func appendPath(p coreiface.Path, sub string) coreiface.Path { } func (tp *provider) TestPublishResolve(t *testing.T) { - ctx := context.Background() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() init := func() (coreiface.CoreAPI, coreiface.Path) { apis, err := tp.MakeAPISwarm(ctx, true, 5) if err != nil { @@ -185,7 +186,8 @@ func (tp *provider) TestPublishResolve(t *testing.T) { } func (tp *provider) TestBasicPublishResolveKey(t *testing.T) { - ctx := context.Background() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() apis, err := tp.MakeAPISwarm(ctx, true, 5) if err != nil { t.Fatal(err) @@ -228,7 +230,8 @@ func (tp *provider) TestBasicPublishResolveKey(t *testing.T) { func (tp *provider) TestBasicPublishResolveTimeout(t *testing.T) { t.Skip("ValidTime doesn't appear to work at this time resolution") - ctx := context.Background() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() apis, err := tp.MakeAPISwarm(ctx, true, 5) if err != nil { t.Fatal(err) diff --git a/core/coreiface/tests/object.go b/core/coreiface/tests/object.go index 349b4a8f5..1cd24aac2 100644 --- a/core/coreiface/tests/object.go +++ b/core/coreiface/tests/object.go @@ -28,7 +28,8 @@ func (tp *provider) TestObject(t *testing.T) { } func (tp *provider) TestNew(t *testing.T) { - ctx := context.Background() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() api, err := tp.makeAPI(ctx) if err != nil { t.Fatal(err) @@ -54,7 +55,8 @@ func (tp *provider) TestNew(t *testing.T) { } func (tp *provider) TestObjectPut(t *testing.T) { - ctx := context.Background() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() api, err := tp.makeAPI(ctx) if err != nil { t.Fatal(err) @@ -94,7 +96,8 @@ func (tp *provider) TestObjectPut(t *testing.T) { } func (tp *provider) TestObjectGet(t *testing.T) { - ctx := context.Background() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() api, err := tp.makeAPI(ctx) if err != nil { t.Fatal(err) @@ -116,7 +119,8 @@ func (tp *provider) TestObjectGet(t *testing.T) { } func (tp *provider) TestObjectData(t *testing.T) { - ctx := context.Background() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() api, err := tp.makeAPI(ctx) if err != nil { t.Fatal(err) @@ -143,7 +147,8 @@ func (tp *provider) TestObjectData(t *testing.T) { } func (tp *provider) TestObjectLinks(t *testing.T) { - ctx := context.Background() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() api, err := tp.makeAPI(ctx) if err != nil { t.Fatal(err) @@ -178,7 +183,8 @@ func (tp *provider) TestObjectLinks(t *testing.T) { } func (tp *provider) TestObjectStat(t *testing.T) { - ctx := context.Background() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() api, err := tp.makeAPI(ctx) if err != nil { t.Fatal(err) @@ -225,7 +231,8 @@ func (tp *provider) TestObjectStat(t *testing.T) { } func (tp *provider) TestObjectAddLink(t *testing.T) { - ctx := context.Background() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() api, err := tp.makeAPI(ctx) if err != nil { t.Fatal(err) @@ -265,7 +272,8 @@ func (tp *provider) TestObjectAddLink(t *testing.T) { } func (tp *provider) TestObjectAddLinkCreate(t *testing.T) { - ctx := context.Background() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() api, err := tp.makeAPI(ctx) if err != nil { t.Fatal(err) @@ -313,7 +321,8 @@ func (tp *provider) TestObjectAddLinkCreate(t *testing.T) { } func (tp *provider) TestObjectRmLink(t *testing.T) { - ctx := context.Background() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() api, err := tp.makeAPI(ctx) if err != nil { t.Fatal(err) @@ -345,7 +354,8 @@ func (tp *provider) TestObjectRmLink(t *testing.T) { } func (tp *provider) TestObjectAddData(t *testing.T) { - ctx := context.Background() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() api, err := tp.makeAPI(ctx) if err != nil { t.Fatal(err) @@ -374,7 +384,8 @@ func (tp *provider) TestObjectAddData(t *testing.T) { } func (tp *provider) TestObjectSetData(t *testing.T) { - ctx := context.Background() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() api, err := tp.makeAPI(ctx) if err != nil { t.Fatal(err) @@ -403,7 +414,8 @@ func (tp *provider) TestObjectSetData(t *testing.T) { } func (tp *provider) TestDiffTest(t *testing.T) { - ctx := context.Background() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() api, err := tp.makeAPI(ctx) if err != nil { t.Fatal(err) diff --git a/core/coreiface/tests/path.go b/core/coreiface/tests/path.go index cb1246366..e74053c04 100644 --- a/core/coreiface/tests/path.go +++ b/core/coreiface/tests/path.go @@ -18,7 +18,8 @@ func (tp *provider) TestPath(t *testing.T) { } func (tp *provider) TestMutablePath(t *testing.T) { - ctx := context.Background() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() api, err := tp.makeAPI(ctx) if err != nil { t.Fatal(err) @@ -45,7 +46,8 @@ func (tp *provider) TestMutablePath(t *testing.T) { } func (tp *provider) TestPathRemainder(t *testing.T) { - ctx := context.Background() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() api, err := tp.makeAPI(ctx) if err != nil { t.Fatal(err) @@ -72,7 +74,8 @@ func (tp *provider) TestPathRemainder(t *testing.T) { } func (tp *provider) TestEmptyPathRemainder(t *testing.T) { - ctx := context.Background() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() api, err := tp.makeAPI(ctx) if err != nil { t.Fatal(err) @@ -103,7 +106,8 @@ func (tp *provider) TestEmptyPathRemainder(t *testing.T) { } func (tp *provider) TestInvalidPathRemainder(t *testing.T) { - ctx := context.Background() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() api, err := tp.makeAPI(ctx) if err != nil { t.Fatal(err) @@ -126,7 +130,8 @@ func (tp *provider) TestInvalidPathRemainder(t *testing.T) { } func (tp *provider) TestPathRoot(t *testing.T) { - ctx := context.Background() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() api, err := tp.makeAPI(ctx) if err != nil { t.Fatal(err) diff --git a/core/coreiface/tests/pin.go b/core/coreiface/tests/pin.go index 8c659ba35..823281ab1 100644 --- a/core/coreiface/tests/pin.go +++ b/core/coreiface/tests/pin.go @@ -15,7 +15,8 @@ func (tp *provider) TestPin(t *testing.T) { } func (tp *provider) TestPinAdd(t *testing.T) { - ctx := context.Background() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) @@ -33,7 +34,8 @@ func (tp *provider) TestPinAdd(t *testing.T) { } func (tp *provider) TestPinSimple(t *testing.T) { - ctx := context.Background() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) @@ -82,7 +84,8 @@ func (tp *provider) TestPinSimple(t *testing.T) { } func (tp *provider) TestPinRecursive(t *testing.T) { - ctx := context.Background() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) diff --git a/core/coreiface/tests/unixfs.go b/core/coreiface/tests/unixfs.go index b31a55d4c..f411ad24d 100644 --- a/core/coreiface/tests/unixfs.go +++ b/core/coreiface/tests/unixfs.go @@ -79,7 +79,8 @@ func wrapped(name string) func(f files.Node) files.Node { } func (tp *provider) TestAdd(t *testing.T) { - ctx := context.Background() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) @@ -536,7 +537,8 @@ func (tp *provider) TestAdd(t *testing.T) { } func (tp *provider) TestAddPinned(t *testing.T) { - ctx := context.Background() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) @@ -558,7 +560,8 @@ func (tp *provider) TestAddPinned(t *testing.T) { } func (tp *provider) TestAddHashOnly(t *testing.T) { - ctx := context.Background() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) @@ -583,7 +586,8 @@ func (tp *provider) TestAddHashOnly(t *testing.T) { } func (tp *provider) TestGetEmptyFile(t *testing.T) { - ctx := context.Background() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() api, err := tp.makeAPI(ctx) if err != nil { t.Fatal(err) @@ -615,7 +619,8 @@ func (tp *provider) TestGetEmptyFile(t *testing.T) { } func (tp *provider) TestGetDir(t *testing.T) { - ctx := context.Background() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) @@ -647,7 +652,8 @@ func (tp *provider) TestGetDir(t *testing.T) { } func (tp *provider) TestGetNonUnixfs(t *testing.T) { - ctx := context.Background() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) @@ -666,7 +672,8 @@ func (tp *provider) TestGetNonUnixfs(t *testing.T) { } func (tp *provider) TestLs(t *testing.T) { - ctx := context.Background() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) @@ -702,7 +709,8 @@ func (tp *provider) TestLs(t *testing.T) { } func (tp *provider) TestEntriesExpired(t *testing.T) { - ctx := context.Background() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) @@ -718,7 +726,7 @@ func (tp *provider) TestEntriesExpired(t *testing.T) { t.Error(err) } - ctx, cancel := context.WithCancel(ctx) + ctx, cancel = context.WithCancel(ctx) nd, err := api.Unixfs().Get(ctx, p) if err != nil { @@ -745,7 +753,8 @@ func (tp *provider) TestEntriesExpired(t *testing.T) { } func (tp *provider) TestLsEmptyDir(t *testing.T) { - ctx := context.Background() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) @@ -773,7 +782,8 @@ func (tp *provider) TestLsEmptyDir(t *testing.T) { // TODO(lgierth) this should test properly, with len(links) > 0 func (tp *provider) TestLsNonUnixfs(t *testing.T) { - ctx := context.Background() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) @@ -830,7 +840,8 @@ func (f *closeTestF) Close() error { } func (tp *provider) TestAddCloses(t *testing.T) { - ctx := context.Background() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() api, err := tp.makeAPI(ctx) if err != nil { t.Error(err) From f012ef096aa03a5815189dc04f7bb502cfe3e097 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 2 Jan 2019 17:41:12 +0100 Subject: [PATCH 0169/1212] coreapi: don't panic as much in tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@89157f98eeb09c4653c098eb4e438741cbdbd21a This commit was moved from ipfs/boxo@27609c7a833ec02858ad16464eb40946f7ddeae3 --- core/coreiface/tests/api.go | 2 +- core/coreiface/tests/block.go | 12 ++++++------ core/coreiface/tests/dag.go | 12 ++++++------ 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/core/coreiface/tests/api.go b/core/coreiface/tests/api.go index ab1feff5b..23ec0612b 100644 --- a/core/coreiface/tests/api.go +++ b/core/coreiface/tests/api.go @@ -71,7 +71,7 @@ func TestApi(p Provider) func(t *testing.T) { select { case <-zeroRunning: case <-time.After(time.Second): - t.Errorf("%d node(s) not closed", running) + t.Errorf("%d test swarms(s) not closed", running) } }) } diff --git a/core/coreiface/tests/block.go b/core/coreiface/tests/block.go index a3a5f93aa..d1117cc50 100644 --- a/core/coreiface/tests/block.go +++ b/core/coreiface/tests/block.go @@ -26,12 +26,12 @@ func (tp *provider) TestBlockPut(t *testing.T) { defer cancel() api, err := tp.makeAPI(ctx) if err != nil { - t.Error(err) + t.Fatal(err) } res, err := api.Block().Put(ctx, strings.NewReader(`Hello`)) if err != nil { - t.Error(err) + t.Fatal(err) } if res.Path().Cid().String() != "QmPyo15ynbVrSTVdJL9th7JysHaAbXt9dM9tXk1bMHbRtk" { @@ -49,7 +49,7 @@ func (tp *provider) TestBlockPutFormat(t *testing.T) { res, err := api.Block().Put(ctx, strings.NewReader(`Hello`), opt.Block.Format("cbor")) if err != nil { - t.Error(err) + t.Fatal(err) } if res.Path().Cid().String() != "zdpuAn4amuLWo8Widi5v6VQpuo2dnpnwbVE3oB6qqs7mDSeoa" { @@ -85,7 +85,7 @@ func (tp *provider) TestBlockGet(t *testing.T) { res, err := api.Block().Put(ctx, strings.NewReader(`Hello`), opt.Block.Hash(mh.KECCAK_512, -1)) if err != nil { - t.Error(err) + t.Fatal(err) } r, err := api.Block().Get(ctx, res.Path()) @@ -126,7 +126,7 @@ func (tp *provider) TestBlockRm(t *testing.T) { res, err := api.Block().Put(ctx, strings.NewReader(`Hello`)) if err != nil { - t.Error(err) + t.Fatal(err) } r, err := api.Block().Get(ctx, res.Path()) @@ -180,7 +180,7 @@ func (tp *provider) TestBlockStat(t *testing.T) { res, err := api.Block().Put(ctx, strings.NewReader(`Hello`)) if err != nil { - t.Error(err) + t.Fatal(err) } stat, err := api.Block().Stat(ctx, res.Path()) diff --git a/core/coreiface/tests/dag.go b/core/coreiface/tests/dag.go index 636c38699..d50263943 100644 --- a/core/coreiface/tests/dag.go +++ b/core/coreiface/tests/dag.go @@ -40,7 +40,7 @@ func (tp *provider) TestPut(t *testing.T) { res, err := api.Dag().Put(ctx, strings.NewReader(`"Hello"`)) if err != nil { - t.Error(err) + t.Fatal(err) } if res.Cid().String() != "zdpuAqckYF3ToF3gcJNxPZXmnmGuXd3gxHCXhq81HGxBejEvv" { @@ -58,7 +58,7 @@ func (tp *provider) TestPutWithHash(t *testing.T) { res, err := api.Dag().Put(ctx, strings.NewReader(`"Hello"`), opt.Dag.Hash(mh.ID, -1)) if err != nil { - t.Error(err) + t.Fatal(err) } if res.Cid().String() != "z5hRLNd2sv4z1c" { @@ -76,12 +76,12 @@ func (tp *provider) TestDagPath(t *testing.T) { sub, err := api.Dag().Put(ctx, strings.NewReader(`"foo"`)) if err != nil { - t.Error(err) + t.Fatal(err) } res, err := api.Dag().Put(ctx, strings.NewReader(`{"lnk": {"/": "`+sub.Cid().String()+`"}}`)) if err != nil { - t.Error(err) + t.Fatal(err) } p, err := coreiface.ParsePath(path.Join(res.Cid().String(), "lnk")) @@ -109,7 +109,7 @@ func (tp *provider) TestTree(t *testing.T) { c, err := api.Dag().Put(ctx, strings.NewReader(`{"a": 123, "b": "foo", "c": {"d": 321, "e": 111}}`)) if err != nil { - t.Error(err) + t.Fatal(err) } res, err := api.Dag().Get(ctx, c) @@ -141,7 +141,7 @@ func (tp *provider) TestBatch(t *testing.T) { c, err := batch.Put(ctx, strings.NewReader(`"Hello"`)) if err != nil { - t.Error(err) + t.Fatal(err) } if c.Cid().String() != "zdpuAqckYF3ToF3gcJNxPZXmnmGuXd3gxHCXhq81HGxBejEvv" { From 80aace0fa25dcc9d89aff8f3b767852c2935685f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 4 Jan 2019 02:35:40 +0100 Subject: [PATCH 0170/1212] Fix offline gateway directory logic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@360e8bbf0b798f4c52541d9116e3b2d240c71a9a This commit was moved from ipfs/boxo@aecc5aa1ac7d14502faf74530e73fb801aed4158 --- core/coreiface/path.go | 9 +++++++-- core/coreiface/tests/path.go | 12 ++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/core/coreiface/path.go b/core/coreiface/path.go index 01dda97d5..96f30852d 100644 --- a/core/coreiface/path.go +++ b/core/coreiface/path.go @@ -1,9 +1,8 @@ package iface import ( + "gx/ipfs/QmR8BauakNcBa3RbE4nbQu76PDiJgoQgz8AJdhJuiU4TAw/go-cid" ipfspath "gx/ipfs/QmZErC2Ay6WuGi96CPg316PwitdwgLo6RxZRqVjJjRj2MR/go-path" - - cid "gx/ipfs/QmR8BauakNcBa3RbE4nbQu76PDiJgoQgz8AJdhJuiU4TAw/go-cid" ) //TODO: merge with ipfspath so we don't depend on it @@ -106,6 +105,12 @@ type resolvedPath struct { remainder string } +// Join appends provided segments to the base path +func Join(base Path, a ...string) Path { + s := ipfspath.Join(append([]string{base.String()}, a...)) + return &path{path: ipfspath.FromString(s)} +} + // IpfsPath creates new /ipfs path from the provided CID func IpfsPath(c cid.Cid) ResolvedPath { return &resolvedPath{ diff --git a/core/coreiface/tests/path.go b/core/coreiface/tests/path.go index e74053c04..7057d6286 100644 --- a/core/coreiface/tests/path.go +++ b/core/coreiface/tests/path.go @@ -15,6 +15,7 @@ func (tp *provider) TestPath(t *testing.T) { t.Run("TestEmptyPathRemainder", tp.TestEmptyPathRemainder) t.Run("TestInvalidPathRemainder", tp.TestInvalidPathRemainder) t.Run("TestPathRoot", tp.TestPathRoot) + t.Run("TestPathJoin", tp.TestPathJoin) } func (tp *provider) TestMutablePath(t *testing.T) { @@ -165,3 +166,14 @@ func (tp *provider) TestPathRoot(t *testing.T) { t.Error("unexpected path cid") } } + +func (tp *provider) TestPathJoin(t *testing.T) { + p1, err := coreiface.ParsePath("/ipfs/QmYNmQKp6SuaVrpgWRsPTgCQCnpxUYGq76YEKBXuj2N4H6/bar/baz") + if err != nil { + t.Error(err) + } + + if coreiface.Join(p1, "foo").String() != "/ipfs/QmYNmQKp6SuaVrpgWRsPTgCQCnpxUYGq76YEKBXuj2N4H6/bar/baz/foo" { + t.Error("unexpected path") + } +} From 3702f185fb7543de86260e52fb22b6a32add1bbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 4 Jan 2019 15:40:15 +0100 Subject: [PATCH 0171/1212] coreapi: FetchBlocks option MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@6800f56736680add20352d2348a59a1a41f7808e This commit was moved from ipfs/boxo@030083beef42fd48df466a4a97ea0f51fb1dfbc6 --- core/coreiface/options/global.go | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/core/coreiface/options/global.go b/core/coreiface/options/global.go index 93d635e41..90e2586f1 100644 --- a/core/coreiface/options/global.go +++ b/core/coreiface/options/global.go @@ -1,14 +1,16 @@ package options type ApiSettings struct { - Offline bool + Offline bool + FetchBlocks bool } type ApiOption func(*ApiSettings) error func ApiOptions(opts ...ApiOption) (*ApiSettings, error) { options := &ApiSettings{ - Offline: false, + Offline: false, + FetchBlocks: true, } return ApiOptionsTo(options, opts...) @@ -34,3 +36,12 @@ func (apiOpts) Offline(offline bool) ApiOption { return nil } } + +// FetchBlocks when set to false prevents api from fetching blocks from the +// network while allowing other services such as IPNS to still be online +func (apiOpts) FetchBlocks(fetch bool) ApiOption { + return func(settings *ApiSettings) error { + settings.FetchBlocks = fetch + return nil + } +} From e8da6e2cf9a8fd40c5fd960a60ce1b1b27ada713 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 7 Jan 2019 23:44:43 +0100 Subject: [PATCH 0172/1212] Block API This commit was moved from ipfs/go-ipfs-http-client@d0c98b870e55bed78fa777793e520f08157deb4f --- client/httpapi/api.go | 2 +- client/httpapi/api_test.go | 11 +++- client/httpapi/block.go | 109 ++++++++++++++++++++++++++++--- client/httpapi/requestbuilder.go | 12 ++++ 4 files changed, 121 insertions(+), 13 deletions(-) diff --git a/client/httpapi/api.go b/client/httpapi/api.go index 63ea3aad7..1768e8477 100644 --- a/client/httpapi/api.go +++ b/client/httpapi/api.go @@ -118,7 +118,7 @@ func (api *HttpApi) Dag() iface.DagAPI { } func (api *HttpApi) Name() iface.NameAPI { - return (*NameAPI)(api) + return nil } func (api *HttpApi) Key() iface.KeyAPI { diff --git a/client/httpapi/api_test.go b/client/httpapi/api_test.go index b925b5c34..e32c456e5 100644 --- a/client/httpapi/api_test.go +++ b/client/httpapi/api_test.go @@ -3,7 +3,6 @@ package httpapi import ( "context" "fmt" - "github.com/ipfs/iptb/testbed/interfaces" "io/ioutil" "os" "path" @@ -16,6 +15,7 @@ import ( local "github.com/ipfs/iptb-plugins/local" "github.com/ipfs/iptb/cli" "github.com/ipfs/iptb/testbed" + "github.com/ipfs/iptb/testbed/interfaces" ) type NodeProvider struct{} @@ -39,7 +39,14 @@ func (NodeProvider) MakeAPISwarm(ctx context.Context, fullIdentity bool, n int) } c := cli.NewCli() - if err := c.Run([]string{"iptb", "--IPTB_ROOT", dir, "auto", "-type", "localipfs", "-count", strconv.FormatInt(int64(n), 10), "--start"}); err != nil { + + initArgs := []string{"iptb", "--IPTB_ROOT", dir, "auto", "-type", "localipfs", "-count", strconv.FormatInt(int64(n), 10)} + if err := c.Run(initArgs); err != nil { + return nil, err + } + + startArgs := []string{"iptb", "--IPTB_ROOT", dir, "start", "-wait", "--", "--offline=" + strconv.FormatBool(n == 1)} + if err := c.Run(startArgs); err != nil { return nil, err } diff --git a/client/httpapi/block.go b/client/httpapi/block.go index 8bdb4c502..185aa0a42 100644 --- a/client/httpapi/block.go +++ b/client/httpapi/block.go @@ -1,17 +1,69 @@ package httpapi import ( + "bytes" "context" + "errors" + "fmt" "io" + "github.com/ipfs/go-cid" "github.com/ipfs/go-ipfs/core/coreapi/interface" - "github.com/ipfs/go-ipfs/core/coreapi/interface/options" + caopts "github.com/ipfs/go-ipfs/core/coreapi/interface/options" + mh "github.com/multiformats/go-multihash" ) type BlockAPI HttpApi -func (api *BlockAPI) Put(ctx context.Context, r io.Reader, opts ...options.BlockPutOption) (iface.BlockStat, error) { - return nil, ErrNotImplemented +type blockStat struct { + Key string + BSize int `json:"Size"` +} + +func (s *blockStat) Size() int { + return s.BSize +} + +func (s *blockStat) valid() (iface.ResolvedPath, error) { + c, err := cid.Parse(s.Key) + if err != nil { + return nil, err + } + + return iface.IpldPath(c), nil +} + +func (s *blockStat) Path() iface.ResolvedPath { + p, _ := s.valid() + return p +} + +func (api *BlockAPI) Put(ctx context.Context, r io.Reader, opts ...caopts.BlockPutOption) (iface.BlockStat, error) { + options, _, err := caopts.BlockPutOptions(opts...) + if err != nil { + return nil, err + } + + mht, ok := mh.Codes[options.MhType] + if !ok { + return nil, fmt.Errorf("unknowm mhType %d", options.MhType) + } + + req := api.core().request("block/put"). + Option("mhtype", mht). + Option("mhlen", options.MhLength). + Option("format", options.Codec). + FileBody(r) + + var out blockStat + if err := req.Exec(ctx, &out); err != nil { + return nil, err + } + if _, err := out.valid(); err != nil { + return nil, err + } + + return &out, nil } func (api *BlockAPI) Get(ctx context.Context, p iface.Path) (io.Reader, error) { @@ -19,20 +71,57 @@ func (api *BlockAPI) Get(ctx context.Context, p iface.Path) (io.Reader, error) { if err != nil { return nil, err } + if resp.Error != nil { + return nil, resp.Error + } - //TODO: is close on the reader enough? - //defer resp.Close() + //TODO: make get return ReadCloser to avoid copying + defer resp.Close() + b := new(bytes.Buffer) + if _, err := io.Copy(b, resp.Output); err != nil { + return nil, err + } - //TODO: make blockApi return ReadCloser - return resp.Output, resp.Error + return b, nil } -func (api *BlockAPI) Rm(ctx context.Context, p iface.Path, opts ...options.BlockRmOption) error { - return ErrNotImplemented +func (api *BlockAPI) Rm(ctx context.Context, p iface.Path, opts ...caopts.BlockRmOption) error { + options, err := caopts.BlockRmOptions(opts...) + if err != nil { + return err + } + + removedBlock := struct { + Hash string `json:",omitempty"` + Error string `json:",omitempty"` + }{} + + req := api.core().request("block/rm"). + Option("force", options.Force). + Arguments(p.String()) + + if err := req.Exec(ctx, &removedBlock); err != nil { + return err + } + + if removedBlock.Error != "" { + return errors.New(removedBlock.Error) + } + + return nil } func (api *BlockAPI) Stat(ctx context.Context, p iface.Path) (iface.BlockStat, error) { - return nil, ErrNotImplemented + var out blockStat + err := api.core().request("block/stat", p.String()).Exec(ctx, &out) + if err != nil { + return nil, err + } + if _, err := out.valid(); err != nil { + return nil, err + } + + return &out, nil } func (api *BlockAPI) core() *HttpApi { diff --git a/client/httpapi/requestbuilder.go b/client/httpapi/requestbuilder.go index 9ccc8cf97..6e5a89ebd 100644 --- a/client/httpapi/requestbuilder.go +++ b/client/httpapi/requestbuilder.go @@ -5,8 +5,11 @@ import ( "context" "fmt" "io" + "io/ioutil" "strconv" "strings" + + "github.com/ipfs/go-ipfs-files" ) // RequestBuilder is an IPFS commands request builder. @@ -42,6 +45,15 @@ func (r *RequestBuilder) Body(body io.Reader) *RequestBuilder { return r } +// FileBody sets the request body to the given reader wrapped into multipartreader. +func (r *RequestBuilder) FileBody(body io.Reader) *RequestBuilder { + pr, _ := files.NewReaderPathFile("/dev/stdin", ioutil.NopCloser(body), nil) + d := files.NewMapDirectory(map[string]files.Node{"": pr}) + r.body = files.NewMultiFileReader(d, false) + + return r +} + // Option sets the given option. func (r *RequestBuilder) Option(key string, value interface{}) *RequestBuilder { var s string From ab89e0abf99a0bc42ee2d8fb55a9b3de79573635 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 8 Jan 2019 00:30:22 +0100 Subject: [PATCH 0173/1212] Partial Unixfs.Add This commit was moved from ipfs/go-ipfs-http-client@44696b84f59f6f707858787c9a0750f224596635 --- client/httpapi/api.go | 4 +- client/httpapi/unixfs.go | 95 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+), 2 deletions(-) create mode 100644 client/httpapi/unixfs.go diff --git a/client/httpapi/api.go b/client/httpapi/api.go index 1768e8477..099b45123 100644 --- a/client/httpapi/api.go +++ b/client/httpapi/api.go @@ -106,7 +106,7 @@ func (api *HttpApi) request(command string, args ...string) *RequestBuilder { } func (api *HttpApi) Unixfs() iface.UnixfsAPI { - return nil + return (*UnixfsAPI)(api) } func (api *HttpApi) Block() iface.BlockAPI { @@ -118,7 +118,7 @@ func (api *HttpApi) Dag() iface.DagAPI { } func (api *HttpApi) Name() iface.NameAPI { - return nil + return (*NameAPI)(api) } func (api *HttpApi) Key() iface.KeyAPI { diff --git a/client/httpapi/unixfs.go b/client/httpapi/unixfs.go new file mode 100644 index 000000000..567f60284 --- /dev/null +++ b/client/httpapi/unixfs.go @@ -0,0 +1,95 @@ +package httpapi + +import ( + "context" + "fmt" + "github.com/ipfs/go-cid" + + "github.com/ipfs/go-ipfs/core/coreapi/interface" + caopts "github.com/ipfs/go-ipfs/core/coreapi/interface/options" + + "github.com/ipfs/go-ipfs-files" + "github.com/ipfs/go-ipld-format" + mh "github.com/multiformats/go-multihash" +) + +type addEvent struct { + Name string + Hash string `json:",omitempty"` + Bytes int64 `json:",omitempty"` + Size string `json:",omitempty"` +} + +type UnixfsAPI HttpApi + +func (api *UnixfsAPI) Add(ctx context.Context, f files.Node, opts ...caopts.UnixfsAddOption) (iface.ResolvedPath, error) { + options, _, err := caopts.UnixfsAddOptions(opts...) + if err != nil { + return nil, err + } + + mht, ok := mh.Codes[options.MhType] + if !ok { + return nil, fmt.Errorf("unknowm mhType %d", options.MhType) + } + + req := api.core().request("add"). + Option("hash", mht). + Option("chunker", options.Chunker). + Option("cid-version", options.CidVersion). + //Option("", options.Events). + Option("fscache", options.FsCache). + Option("hidden", options.Hidden). + Option("inline", options.Inline). + Option("inline-limit", options.InlineLimit). + Option("nocopy", options.NoCopy). + Option("only-hash", options.OnlyHash). + Option("pin", options.Pin). + //Option("", options.Progress). + Option("silent", options.Silent). + Option("stdin-name", options.StdinName). + Option("wrap-with-directory", options.Wrap). + Option("quieter", true) // TODO: rm after event impl + + if options.RawLeavesSet { + req.Option("raw-leaves", options.RawLeaves) + } + + switch options.Layout { + case caopts.BalancedLayout: + // noop, default + case caopts.TrickleLayout: + req.Option("trickle", true) + } + + switch c := f.(type) { + case files.Directory: + req.Body(files.NewMultiFileReader(c, false)) + case files.File: + req.Body(c) + } + + var out addEvent + if err := req.Exec(ctx, &out); err != nil { //TODO: ndjson events + return nil, err + } + + c, err := cid.Parse(out.Hash) + if err != nil { + return nil, err + } + + return iface.IpfsPath(c), nil +} + +func (api *UnixfsAPI) Get(context.Context, iface.Path) (files.Node, error) { + panic("implement me") +} + +func (api *UnixfsAPI) Ls(context.Context, iface.Path) ([]*format.Link, error) { + panic("implement me") +} + +func (api *UnixfsAPI) core() *HttpApi { + return (*HttpApi)(api) +} From cf74d391603457ad626b7f6b27ff0655bc946ee4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 8 Jan 2019 02:07:21 +0100 Subject: [PATCH 0174/1212] Partial Key API, ApiAddr funcion This commit was moved from ipfs/go-ipfs-http-client@0ffdef159261e19cfd76edabb394179aa9295003 --- client/httpapi/api.go | 13 ++++++- client/httpapi/key.go | 86 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+), 2 deletions(-) create mode 100644 client/httpapi/key.go diff --git a/client/httpapi/api.go b/client/httpapi/api.go index 099b45123..d104d98df 100644 --- a/client/httpapi/api.go +++ b/client/httpapi/api.go @@ -29,6 +29,7 @@ type HttpApi struct { httpcli *gohttp.Client } +//TODO: Return errors here func NewLocalApi() iface.CoreAPI { baseDir := os.Getenv(EnvDir) if baseDir == "" { @@ -39,6 +40,14 @@ func NewLocalApi() iface.CoreAPI { } func NewPathApi(p string) iface.CoreAPI { + a := ApiAddr(p) + if a == nil { + return nil + } + return NewApi(a) +} + +func ApiAddr(p string) ma.Multiaddr { baseDir, err := homedir.Expand(p) if err != nil { return nil @@ -60,7 +69,7 @@ func NewPathApi(p string) iface.CoreAPI { return nil } - return NewApi(maddr) + return maddr } func NewApi(a ma.Multiaddr) *HttpApi { // TODO: should be MAddr? @@ -122,7 +131,7 @@ func (api *HttpApi) Name() iface.NameAPI { } func (api *HttpApi) Key() iface.KeyAPI { - return nil + return (*KeyAPI)(api) } func (api *HttpApi) Pin() iface.PinAPI { diff --git a/client/httpapi/key.go b/client/httpapi/key.go new file mode 100644 index 000000000..87b573f98 --- /dev/null +++ b/client/httpapi/key.go @@ -0,0 +1,86 @@ +package httpapi + +import ( + "context" + + "github.com/ipfs/go-ipfs/core/coreapi/interface" + caopts "github.com/ipfs/go-ipfs/core/coreapi/interface/options" + + "github.com/libp2p/go-libp2p-peer" +) + +type KeyAPI HttpApi + +type keyOutput struct { + JName string `json:"Name"` + Id string +} + +func (k *keyOutput) Name() string { + return k.JName +} + +func (k *keyOutput) Path() iface.Path { + p, _ := iface.ParsePath("/ipns/" + k.Id) + return p +} + +func (k *keyOutput) ID() peer.ID { + p, _ := peer.IDB58Decode(k.Id) + return p +} + +func (k *keyOutput) valid() error { + _, err := peer.IDB58Decode(k.Id) + return err +} + + +func (api *KeyAPI) Generate(ctx context.Context, name string, opts ...caopts.KeyGenerateOption) (iface.Key, error) { + options, err := caopts.KeyGenerateOptions(opts...) + if err != nil { + return nil, err + } + + var out keyOutput + err = api.core().request("key/gen", name). + Option("type", options.Algorithm). + Option("size", options.Size). + Exec(ctx, &out) + if err != nil { + return nil, err + } + if err := out.valid(); err != nil { + return nil, err + } + return &out, nil +} + +func (api *KeyAPI) Rename(ctx context.Context, oldName string, newName string, opts ...caopts.KeyRenameOption) (iface.Key, bool, error) { + panic("implement me") +} + +func (api *KeyAPI) List(ctx context.Context) ([]iface.Key, error) { + panic("implement me") +} + +func (api *KeyAPI) Self(ctx context.Context) (iface.Key, error) { + var id struct{ID string} + if err := api.core().request("id").Exec(ctx, &id); err != nil { + return nil, err + } + + out := keyOutput{JName: "self", Id: id.ID} + if err := out.valid(); err != nil { + return nil, err + } + return &out, nil +} + +func (api *KeyAPI) Remove(ctx context.Context, name string) (iface.Key, error) { + panic("implement me") +} + +func (api *KeyAPI) core() *HttpApi { + return (*HttpApi)(api) +} From c236393733bf3491c45002d67189ba78303332a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 8 Jan 2019 02:08:18 +0100 Subject: [PATCH 0175/1212] Connect test swarms, don't compress api calls This commit was moved from ipfs/go-ipfs-http-client@c6472d9b8286c932492db4d6bf03f890bf97759c --- client/httpapi/api_test.go | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/client/httpapi/api_test.go b/client/httpapi/api_test.go index e32c456e5..02c7830bb 100644 --- a/client/httpapi/api_test.go +++ b/client/httpapi/api_test.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "io/ioutil" + gohttp "net/http" "os" "path" "strconv" @@ -50,6 +51,13 @@ func (NodeProvider) MakeAPISwarm(ctx context.Context, fullIdentity bool, n int) return nil, err } + if n > 1 { + connectArgs := []string{"iptb", "--IPTB_ROOT", dir, "connect", fmt.Sprintf("[1-%d]", n - 1), "0"} + if err := c.Run(connectArgs); err != nil { + return nil, err + } + } + go func() { <-ctx.Done() @@ -80,7 +88,18 @@ func (NodeProvider) MakeAPISwarm(ctx context.Context, fullIdentity bool, n int) return nil, err } - apis[i] = NewPathApi(pth) + a := ApiAddr(pth) + if a == nil { + return nil, fmt.Errorf("nil addr for node") + } + c := &gohttp.Client{ + Transport: &gohttp.Transport{ + Proxy: gohttp.ProxyFromEnvironment, + DisableKeepAlives: true, + DisableCompression: true, + }, + } + apis[i] = NewApiWithClient(a, c) } return apis, nil From 7861315f49398e20e7e1189671e42d0a16adbef0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 8 Jan 2019 02:09:00 +0100 Subject: [PATCH 0176/1212] Wrap single files in Unixfs.Add This commit was moved from ipfs/go-ipfs-http-client@16f77b24a1b150e7ec624d5675ded478ac6cb853 --- client/httpapi/unixfs.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/httpapi/unixfs.go b/client/httpapi/unixfs.go index 567f60284..21f75f85a 100644 --- a/client/httpapi/unixfs.go +++ b/client/httpapi/unixfs.go @@ -66,7 +66,8 @@ func (api *UnixfsAPI) Add(ctx context.Context, f files.Node, opts ...caopts.Unix case files.Directory: req.Body(files.NewMultiFileReader(c, false)) case files.File: - req.Body(c) + d := files.NewMapDirectory(map[string]files.Node{"": c}) // unwrapped on the other side + req.Body(files.NewMultiFileReader(d, false)) } var out addEvent From f638bae3a960a74d284503c30086f0bbffbe73c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 8 Jan 2019 02:09:17 +0100 Subject: [PATCH 0177/1212] implement .Name This commit was moved from ipfs/go-ipfs-http-client@e19e5f54e48d0909796add6d57e3e74e84eba85e --- client/httpapi/name.go | 72 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 63 insertions(+), 9 deletions(-) diff --git a/client/httpapi/name.go b/client/httpapi/name.go index 7315ac2c3..fbc440b96 100644 --- a/client/httpapi/name.go +++ b/client/httpapi/name.go @@ -2,26 +2,80 @@ package httpapi import ( "context" + "fmt" + "github.com/ipfs/go-ipfs/namesys/opts" "github.com/ipfs/go-ipfs/core/coreapi/interface" - "github.com/ipfs/go-ipfs/core/coreapi/interface/options" + caopts "github.com/ipfs/go-ipfs/core/coreapi/interface/options" ) type NameAPI HttpApi -func (api *NameAPI) Publish(ctx context.Context, p iface.Path, opts ...options.NamePublishOption) (iface.IpnsEntry, error) { +type ipnsEntry struct { + JName string `json:"Name"` + JValue string `json:"Value"` +} + +func (e *ipnsEntry) valid() (iface.Path, error) { + return iface.ParsePath(e.JValue) +} + +func (e *ipnsEntry) Name() string { + return e.JName +} + +func (e *ipnsEntry) Value() iface.Path { + p, _ := e.valid() + return p +} + +func (api *NameAPI) Publish(ctx context.Context, p iface.Path, opts ...caopts.NamePublishOption) (iface.IpnsEntry, error) { + options, err := caopts.NamePublishOptions(opts...) + if err != nil { + return nil, err + } + + req := api.core().request("name/publish", p.String()). + Option("key", options.Key). + Option("allow-offline", options.AllowOffline). + Option("lifetime", options.ValidTime.String()). + Option("resolve", false) + + if options.TTL != nil { + req.Option("ttl", options.TTL.String()) + } + + var out ipnsEntry + if err := req.Exec(ctx, &out); err != nil { + return nil, err + } + if _, err := out.valid(); err != nil { + return nil, err + } + + return &out, nil +} + +func (api *NameAPI) Search(ctx context.Context, name string, opts ...caopts.NameResolveOption) (<-chan iface.IpnsResult, error) { return nil, ErrNotImplemented } -func (api *NameAPI) Search(ctx context.Context, name string, opts ...options.NameResolveOption) (<-chan iface.IpnsResult, error) { - return nil, ErrNotImplemented -} +func (api *NameAPI) Resolve(ctx context.Context, name string, opts ...caopts.NameResolveOption) (iface.Path, error) { + options, err := caopts.NameResolveOptions(opts...) + if err != nil { + return nil, err + } -func (api *NameAPI) Resolve(ctx context.Context, name string, opts ...options.NameResolveOption) (iface.Path, error) { - // TODO: options! + ropts := nsopts.ProcessOpts(options.ResolveOpts) + if ropts.Depth != nsopts.DefaultDepthLimit && ropts.Depth != 1 { + return nil, fmt.Errorf("Name.Resolve: depth other than 1 or %d not supported", nsopts.DefaultDepthLimit) + } - req := api.core().request("name/resolve") - req.Arguments(name) + req := api.core().request("name/resolve", name). + Option("nocache", !options.Cache). + Option("recursive", ropts.Depth != 1). + Option("dht-record-count", ropts.DhtRecordCount). + Option("dht-timeout", ropts.DhtTimeout.String()) var out struct{ Path string } if err := req.Exec(ctx, &out); err != nil { From 1acf4163902ae3b9e0e182761deafee5e67415ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 8 Jan 2019 02:53:24 +0100 Subject: [PATCH 0178/1212] Implement .Unixfs.Ls() This commit was moved from ipfs/go-ipfs-http-client@eb1944fae32f4ccc43969ecd632681c2f2cbfa00 --- client/httpapi/response.go | 14 ++++++++++++- client/httpapi/unixfs.go | 43 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 54 insertions(+), 3 deletions(-) diff --git a/client/httpapi/response.go b/client/httpapi/response.go index 27709769b..5749ca29e 100644 --- a/client/httpapi/response.go +++ b/client/httpapi/response.go @@ -33,7 +33,19 @@ func (r *Response) Decode(dec interface{}) error { return r.Error } - return json.NewDecoder(r.Output).Decode(dec) + n := 0 + var err error + for { + err = json.NewDecoder(r.Output).Decode(dec) + if err != nil { + break + } + n++ + } + if n > 0 && err == io.EOF { + err = nil + } + return err } type Error struct { diff --git a/client/httpapi/unixfs.go b/client/httpapi/unixfs.go index 21f75f85a..75e565a4a 100644 --- a/client/httpapi/unixfs.go +++ b/client/httpapi/unixfs.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "github.com/ipfs/go-cid" + "github.com/pkg/errors" "github.com/ipfs/go-ipfs/core/coreapi/interface" caopts "github.com/ipfs/go-ipfs/core/coreapi/interface/options" @@ -11,6 +12,7 @@ import ( "github.com/ipfs/go-ipfs-files" "github.com/ipfs/go-ipld-format" mh "github.com/multiformats/go-multihash" + unixfspb "gx/ipfs/Qmbvw7kpSM2p6rbQ57WGRhhqNfCiNGW6EKH4xgHLw4bsnB/go-unixfs/pb" ) type addEvent struct { @@ -87,8 +89,45 @@ func (api *UnixfsAPI) Get(context.Context, iface.Path) (files.Node, error) { panic("implement me") } -func (api *UnixfsAPI) Ls(context.Context, iface.Path) ([]*format.Link, error) { - panic("implement me") +type lsLink struct { + Name, Hash string + Size uint64 + Type unixfspb.Data_DataType +} + +type lsObject struct { + Hash string + Links []lsLink +} + +type lsOutput struct { + Objects []lsObject +} + +func (api *UnixfsAPI) Ls(ctx context.Context, p iface.Path) ([]*format.Link, error) { + var out lsOutput + err := api.core().request("ls", p.String()).Exec(ctx, &out) + if err != nil { + return nil, err + } + + if len(out.Objects) != 1 { + return nil, errors.New("unexpected objects len") + } + + links := make([]*format.Link, len(out.Objects[0].Links)) + for i, l := range out.Objects[0].Links { + c, err := cid.Parse(l.Hash) + if err != nil { + return nil, err + } + links[i] = &format.Link{ + Name: l.Name, + Size: l.Size, + Cid: c, + } + } + return links, nil } func (api *UnixfsAPI) core() *HttpApi { From a6636aac599a1a8a4802ccadb885909f0ab88629 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 8 Jan 2019 03:18:21 +0100 Subject: [PATCH 0179/1212] Imprement partian Pin API This commit was moved from ipfs/go-ipfs-http-client@dbf90eac67d95722e88056ca16fa769a32dcd48f --- client/httpapi/api.go | 2 +- client/httpapi/api_test.go | 16 +++++++- client/httpapi/pin.go | 78 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 94 insertions(+), 2 deletions(-) create mode 100644 client/httpapi/pin.go diff --git a/client/httpapi/api.go b/client/httpapi/api.go index d104d98df..d5741da08 100644 --- a/client/httpapi/api.go +++ b/client/httpapi/api.go @@ -135,7 +135,7 @@ func (api *HttpApi) Key() iface.KeyAPI { } func (api *HttpApi) Pin() iface.PinAPI { - return nil + return (*PinAPI)(api) } func (api *HttpApi) Object() iface.ObjectAPI { diff --git a/client/httpapi/api_test.go b/client/httpapi/api_test.go index 02c7830bb..5fdf18352 100644 --- a/client/httpapi/api_test.go +++ b/client/httpapi/api_test.go @@ -11,6 +11,7 @@ import ( "testing" "github.com/ipfs/go-ipfs/core/coreapi/interface" + "github.com/ipfs/go-ipfs/core/coreapi/interface/options" "github.com/ipfs/go-ipfs/core/coreapi/interface/tests" local "github.com/ipfs/iptb-plugins/local" @@ -39,7 +40,7 @@ func (NodeProvider) MakeAPISwarm(ctx context.Context, fullIdentity bool, n int) return nil, err } - c := cli.NewCli() + c := cli.NewCli() //TODO: is there a better way? initArgs := []string{"iptb", "--IPTB_ROOT", dir, "auto", "-type", "localipfs", "-count", strconv.FormatInt(int64(n), 10)} if err := c.Run(initArgs); err != nil { @@ -100,6 +101,19 @@ func (NodeProvider) MakeAPISwarm(ctx context.Context, fullIdentity bool, n int) }, } apis[i] = NewApiWithClient(a, c) + + // node cleanup + // TODO: pass --empty-repo somehow (how?) + pins, err := apis[i].Pin().Ls(ctx, options.Pin.Type.Recursive()) + if err != nil { + return nil, err + } + for _, pin := range pins { //TODO: parallel + if err := apis[i].Pin().Rm(ctx, pin.Path()); err != nil { + return nil, err + } + } + } return apis, nil diff --git a/client/httpapi/pin.go b/client/httpapi/pin.go new file mode 100644 index 000000000..02dcc4222 --- /dev/null +++ b/client/httpapi/pin.go @@ -0,0 +1,78 @@ +package httpapi + +import ( + "context" + "github.com/ipfs/go-cid" + + "github.com/ipfs/go-ipfs/core/coreapi/interface" + caopts "github.com/ipfs/go-ipfs/core/coreapi/interface/options" +) + +type PinAPI HttpApi + +type pinRefKeyObject struct { + Type string +} + +type pinRefKeyList struct { + Keys map[string]pinRefKeyObject +} + +type pin struct { + path iface.ResolvedPath + typ string +} + +func (p *pin) Path() iface.ResolvedPath { + return p.path +} + +func (p *pin) Type() string { + return p.typ +} + + +func (api *PinAPI) Add(context.Context, iface.Path, ...caopts.PinAddOption) error { + panic("implement me") +} + +func (api *PinAPI) Ls(ctx context.Context, opts ...caopts.PinLsOption) ([]iface.Pin, error) { + options, err := caopts.PinLsOptions(opts...) + if err != nil { + return nil, err + } + + var out pinRefKeyList + err = api.core().request("pin/ls"). + Option("type", options.Type).Exec(ctx, &out) + if err != nil { + return nil, err + } + + pins := make([]iface.Pin, 0, len(out.Keys)) + for hash, p := range out.Keys { + c, err := cid.Parse(hash) + if err != nil { + return nil, err + } + pins = append(pins, &pin{typ: p.Type, path: iface.IpldPath(c)}) + } + + return pins, nil +} + +func (api *PinAPI) Rm(ctx context.Context, p iface.Path) error { + return api.core().request("pin/rm", p.String()).Exec(ctx, nil) +} + +func (api *PinAPI) Update(ctx context.Context, from iface.Path, to iface.Path, opts ...caopts.PinUpdateOption) error { + panic("implement me") +} + +func (api *PinAPI) Verify(context.Context) (<-chan iface.PinStatus, error) { + panic("implement me") +} + +func (api *PinAPI) core() *HttpApi { + return (*HttpApi)(api) +} From 0f7c83956b2d769c801c270fe01d4819cb070881 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 8 Jan 2019 03:20:04 +0100 Subject: [PATCH 0180/1212] Import missing unixfs dep This commit was moved from ipfs/go-ipfs-http-client@6169321d1df6495cbd1c06cca9f2e0777a00f638 --- client/httpapi/unixfs.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/httpapi/unixfs.go b/client/httpapi/unixfs.go index 75e565a4a..5a1495c24 100644 --- a/client/httpapi/unixfs.go +++ b/client/httpapi/unixfs.go @@ -11,8 +11,8 @@ import ( "github.com/ipfs/go-ipfs-files" "github.com/ipfs/go-ipld-format" + unixfspb "github.com/ipfs/go-unixfs/pb" mh "github.com/multiformats/go-multihash" - unixfspb "gx/ipfs/Qmbvw7kpSM2p6rbQ57WGRhhqNfCiNGW6EKH4xgHLw4bsnB/go-unixfs/pb" ) type addEvent struct { From af197cb6d90da1b51525e68f97a30ebfc322e134 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 8 Jan 2019 14:46:52 +0100 Subject: [PATCH 0181/1212] api.WithOption This commit was moved from ipfs/go-ipfs-http-client@634b00bf1a42dc7f2a2dc75f85c77e5bb5ef727c --- client/httpapi/api.go | 21 ++++++++++++++++++--- client/httpapi/api_test.go | 4 ++-- client/httpapi/requestbuilder.go | 2 ++ client/httpapi/response.go | 2 +- 4 files changed, 23 insertions(+), 6 deletions(-) diff --git a/client/httpapi/api.go b/client/httpapi/api.go index d5741da08..3df45f38c 100644 --- a/client/httpapi/api.go +++ b/client/httpapi/api.go @@ -9,7 +9,7 @@ import ( "strings" "github.com/ipfs/go-ipfs/core/coreapi/interface" - "github.com/ipfs/go-ipfs/core/coreapi/interface/options" + caopts "github.com/ipfs/go-ipfs/core/coreapi/interface/options" homedir "github.com/mitchellh/go-homedir" ma "github.com/multiformats/go-multiaddr" manet "github.com/multiformats/go-multiaddr-net" @@ -27,6 +27,8 @@ var ErrNotImplemented = errors.New("not implemented") type HttpApi struct { url string httpcli *gohttp.Client + + applyGlobal func(*RequestBuilder) } //TODO: Return errors here @@ -99,11 +101,24 @@ func NewApiWithClient(a ma.Multiaddr, c *gohttp.Client) *HttpApi { return &HttpApi{ url: url, httpcli: c, + applyGlobal: func(*RequestBuilder) {}, } } -func (api *HttpApi) WithOptions(...options.ApiOption) (iface.CoreAPI, error) { - return nil, ErrNotImplemented +func (api *HttpApi) WithOptions(opts ...caopts.ApiOption) (iface.CoreAPI, error) { + options, err := caopts.ApiOptions(opts...) + if err != nil { + return nil, err + } + + subApi := *api + subApi.applyGlobal = func(req *RequestBuilder) { + if options.Offline { + req.Option("offline", options.Offline) + } + } + + return &subApi, nil } func (api *HttpApi) request(command string, args ...string) *RequestBuilder { diff --git a/client/httpapi/api_test.go b/client/httpapi/api_test.go index 5fdf18352..67a2dbdce 100644 --- a/client/httpapi/api_test.go +++ b/client/httpapi/api_test.go @@ -11,7 +11,7 @@ import ( "testing" "github.com/ipfs/go-ipfs/core/coreapi/interface" - "github.com/ipfs/go-ipfs/core/coreapi/interface/options" + caopts "github.com/ipfs/go-ipfs/core/coreapi/interface/options" "github.com/ipfs/go-ipfs/core/coreapi/interface/tests" local "github.com/ipfs/iptb-plugins/local" @@ -104,7 +104,7 @@ func (NodeProvider) MakeAPISwarm(ctx context.Context, fullIdentity bool, n int) // node cleanup // TODO: pass --empty-repo somehow (how?) - pins, err := apis[i].Pin().Ls(ctx, options.Pin.Type.Recursive()) + pins, err := apis[i].Pin().Ls(ctx, caopts.Pin.Type.Recursive()) if err != nil { return nil, err } diff --git a/client/httpapi/requestbuilder.go b/client/httpapi/requestbuilder.go index 6e5a89ebd..831e6d71c 100644 --- a/client/httpapi/requestbuilder.go +++ b/client/httpapi/requestbuilder.go @@ -86,6 +86,8 @@ func (r *RequestBuilder) Header(name, value string) *RequestBuilder { // Send sends the request and return the response. func (r *RequestBuilder) Send(ctx context.Context) (*Response, error) { + r.shell.applyGlobal(r) + req := NewRequest(ctx, r.shell.url, r.command, r.args...) req.Opts = r.opts req.Headers = r.headers diff --git a/client/httpapi/response.go b/client/httpapi/response.go index 5749ca29e..f6e7f3ab7 100644 --- a/client/httpapi/response.go +++ b/client/httpapi/response.go @@ -21,7 +21,7 @@ type Response struct { func (r *Response) Close() error { if r.Output != nil { // always drain output (response body) - ioutil.ReadAll(r.Output) + //ioutil.ReadAll(r.Output) // TODO: might not be a good idea in case there is a lot of data return r.Output.Close() } return nil From 6d9dea62825012678ab0f117ec3cfe28c96fdaf0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 8 Jan 2019 17:47:22 +0100 Subject: [PATCH 0182/1212] Implement Unixfs.Get() This commit was moved from ipfs/go-ipfs-http-client@b31bee083d1fc5002779d755b6a624b517d2b10c --- client/httpapi/apifile.go | 231 ++++++++++++++++++++++++++++++++++++++ client/httpapi/unixfs.go | 4 - 2 files changed, 231 insertions(+), 4 deletions(-) create mode 100644 client/httpapi/apifile.go diff --git a/client/httpapi/apifile.go b/client/httpapi/apifile.go new file mode 100644 index 000000000..541189b60 --- /dev/null +++ b/client/httpapi/apifile.go @@ -0,0 +1,231 @@ +package httpapi + +import ( + "context" + "encoding/json" + "fmt" + "github.com/ipfs/go-cid" + "io" + + "github.com/ipfs/go-ipfs/core/coreapi/interface" + + "github.com/ipfs/go-ipfs-files" + unixfspb "github.com/ipfs/go-unixfs/pb" +) + +func (api *UnixfsAPI) Get(ctx context.Context, p iface.Path) (files.Node, error) { + if p.Mutable() { // use resolved path in case we are dealing with IPNS / MFS + var err error + p, err = api.core().ResolvePath(ctx, p) + if err != nil { + return nil, err + } + } + + var stat struct{ + Hash string + Type string + Size int64 // unixfs size + } + err := api.core().request("files/stat", p.String()). Exec(ctx, &stat) + if err != nil { + return nil, err + } + + switch stat.Type { + case "file": + return api.getFile(ctx, p, stat.Size) + case "directory": + return api.getDir(ctx, p, stat.Size) + default: + return nil, fmt.Errorf("unsupported file type '%s'", stat.Type) + } +} + +type apiFile struct { + ctx context.Context + core *HttpApi + size int64 + path iface.Path + + r io.ReadCloser + at int64 +} + +func (f *apiFile) reset() error { + if f.r != nil { + f.r.Close() + } + req := f.core.request("cat", f.path.String()) + if f.at != 0 { + req.Option("offset", f.at) + } + resp, err := req.Send(f.ctx) + if err != nil { + return err + } + if resp.Error != nil { + return resp.Error + } + f.r = resp.Output + return nil +} + +func (f *apiFile) Read(p []byte) (int, error) { + n, err := f.r.Read(p) + if n > 0 { + f.at += int64(n) + } + return n, err +} + +func (f *apiFile) Seek(offset int64, whence int) (int64, error) { + panic("implement me") //TODO +} + +func (f *apiFile) Close() error { + if f.r != nil { + return f.r.Close() + } + return nil +} + +func (f *apiFile) Size() (int64, error) { + return f.size, nil +} + +func (api *UnixfsAPI) getFile(ctx context.Context, p iface.Path, size int64) (files.Node, error) { + f := &apiFile{ + ctx: ctx, + core: api.core(), + size: size, + path: p, + } + + return f, f.reset() +} + +type apiIter struct { + ctx context.Context + core *UnixfsAPI + + err error + + dec *json.Decoder + curFile files.Node + cur lsLink +} + +func (it *apiIter) Err() error { + return it.err +} + +func (it *apiIter) Name() string { + return it.cur.Name +} + +func (it *apiIter) Next() bool { + var out lsOutput + if err := it.dec.Decode(&out); err != nil { + if err != io.EOF { + it.err = err + } + return false + } + + if len(out.Objects) != 1 { + it.err = fmt.Errorf("len(out.Objects) != 1 (is %d)", len(out.Objects)) + return false + } + + if len(out.Objects[0].Links) != 1 { + it.err = fmt.Errorf("len(out.Objects[0].Links) != 1 (is %d)", len(out.Objects[0].Links)) + return false + } + + it.cur = out.Objects[0].Links[0] + c, err := cid.Parse(it.cur.Hash) + if err != nil { + it.err = err + return false + } + + switch it.cur.Type { + case unixfspb.Data_HAMTShard: + fallthrough + case unixfspb.Data_Metadata: + fallthrough + case unixfspb.Data_Directory: + it.curFile, err = it.core.getDir(it.ctx, iface.IpfsPath(c), int64(it.cur.Size)) + if err != nil { + it.err = err + return false + } + case unixfspb.Data_File: + it.curFile, err = it.core.getFile(it.ctx, iface.IpfsPath(c), int64(it.cur.Size)) + if err != nil { + it.err = err + return false + } + default: + it.err = fmt.Errorf("file type %d not supported", it.cur.Type) + return false + } + return true +} + +func (it *apiIter) Node() files.Node { + return it.curFile +} + +type apiDir struct { + ctx context.Context + core *UnixfsAPI + size int64 + path iface.Path + + dec *json.Decoder +} + +func (d *apiDir) Close() error { + return nil +} + +func (d *apiDir) Size() (int64, error) { + return d.size, nil +} + +func (d *apiDir) Entries() files.DirIterator { + return &apiIter{ + ctx: d.ctx, + core: d.core, + dec: d.dec, + } +} + +func (api *UnixfsAPI) getDir(ctx context.Context, p iface.Path, size int64) (files.Node, error) { + resp, err := api.core().request("ls", p.String()). + Option("resolve-size", true). + Option("stream", true).Send(ctx) + + if err != nil { + return nil, err + } + if resp.Error != nil { + return nil, resp.Error + } + + d := &apiDir{ + ctx: ctx, + core: api, + size: size, + path: p, + + dec: json.NewDecoder(resp.Output), + } + + return d, nil +} + +var _ files.File = &apiFile{} +var _ files.Directory = &apiDir{} diff --git a/client/httpapi/unixfs.go b/client/httpapi/unixfs.go index 5a1495c24..77daf7b9b 100644 --- a/client/httpapi/unixfs.go +++ b/client/httpapi/unixfs.go @@ -85,10 +85,6 @@ func (api *UnixfsAPI) Add(ctx context.Context, f files.Node, opts ...caopts.Unix return iface.IpfsPath(c), nil } -func (api *UnixfsAPI) Get(context.Context, iface.Path) (files.Node, error) { - panic("implement me") -} - type lsLink struct { Name, Hash string Size uint64 From dfd6253ba8498af122a35929870657e5a8b29744 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 7 Jan 2019 16:19:55 +0100 Subject: [PATCH 0183/1212] CoreAPI: Don't panic when testing incomplete implementions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@d7a89ddb0258cbc54631924688e6f23bc02709d5 This commit was moved from ipfs/boxo@9845df2662de30cb8d0030bd280e2b58247a0ef0 --- core/coreiface/tests/api.go | 16 +++++++++++++ core/coreiface/tests/block.go | 7 ++++++ core/coreiface/tests/dag.go | 7 ++++++ core/coreiface/tests/dht.go | 8 +++++++ core/coreiface/tests/key.go | 8 +++++++ core/coreiface/tests/name.go | 7 ++++++ core/coreiface/tests/object.go | 7 ++++++ core/coreiface/tests/path.go | 44 ++++++++++++++++++++++++++-------- core/coreiface/tests/pin.go | 8 +++++++ core/coreiface/tests/pubsub.go | 8 +++++++ core/coreiface/tests/unixfs.go | 7 ++++++ 11 files changed, 117 insertions(+), 10 deletions(-) diff --git a/core/coreiface/tests/api.go b/core/coreiface/tests/api.go index 23ec0612b..7a4bd7386 100644 --- a/core/coreiface/tests/api.go +++ b/core/coreiface/tests/api.go @@ -2,12 +2,15 @@ package tests import ( "context" + "errors" "testing" "time" coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface" ) +var apiNotImplemented = errors.New("api not implemented") + func (tp *provider) makeAPI(ctx context.Context) (coreiface.CoreAPI, error) { api, err := tp.MakeAPISwarm(ctx, false, 1) if err != nil { @@ -76,3 +79,16 @@ func TestApi(p Provider) func(t *testing.T) { }) } } + +func (tp *provider) hasApi(t *testing.T, tf func(coreiface.CoreAPI) error) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + api, err := tp.makeAPI(ctx) + if err != nil { + t.Fatal(err) + } + + if err := tf(api); err != nil { + t.Fatal(api) + } +} diff --git a/core/coreiface/tests/block.go b/core/coreiface/tests/block.go index d1117cc50..81a6fb061 100644 --- a/core/coreiface/tests/block.go +++ b/core/coreiface/tests/block.go @@ -13,6 +13,13 @@ import ( ) func (tp *provider) TestBlock(t *testing.T) { + tp.hasApi(t, func(api coreiface.CoreAPI) error { + if api.Block() == nil { + return apiNotImplemented + } + return nil + }) + t.Run("TestBlockPut", tp.TestBlockPut) t.Run("TestBlockPutFormat", tp.TestBlockPutFormat) t.Run("TestBlockPutHash", tp.TestBlockPutHash) diff --git a/core/coreiface/tests/dag.go b/core/coreiface/tests/dag.go index d50263943..70a45aa20 100644 --- a/core/coreiface/tests/dag.go +++ b/core/coreiface/tests/dag.go @@ -13,6 +13,13 @@ import ( ) func (tp *provider) TestDag(t *testing.T) { + tp.hasApi(t, func(api coreiface.CoreAPI) error { + if api.Dag() == nil { + return apiNotImplemented + } + return nil + }) + t.Run("TestPut", tp.TestPut) t.Run("TestPutWithHash", tp.TestPutWithHash) t.Run("TestPath", tp.TestDagPath) diff --git a/core/coreiface/tests/dht.go b/core/coreiface/tests/dht.go index 9b77f1679..3ec77d33b 100644 --- a/core/coreiface/tests/dht.go +++ b/core/coreiface/tests/dht.go @@ -5,10 +5,18 @@ import ( "io" "testing" + "github.com/ipfs/go-ipfs/core/coreapi/interface" "github.com/ipfs/go-ipfs/core/coreapi/interface/options" ) func (tp *provider) TestDht(t *testing.T) { + tp.hasApi(t, func(api iface.CoreAPI) error { + if api.Dht() == nil { + return apiNotImplemented + } + return nil + }) + t.Run("TestDhtFindPeer", tp.TestDhtFindPeer) t.Run("TestDhtFindProviders", tp.TestDhtFindProviders) t.Run("TestDhtProvide", tp.TestDhtProvide) diff --git a/core/coreiface/tests/key.go b/core/coreiface/tests/key.go index 99c30c302..8dd6af57f 100644 --- a/core/coreiface/tests/key.go +++ b/core/coreiface/tests/key.go @@ -5,10 +5,18 @@ import ( "strings" "testing" + "github.com/ipfs/go-ipfs/core/coreapi/interface" opt "github.com/ipfs/go-ipfs/core/coreapi/interface/options" ) func (tp *provider) TestKey(t *testing.T) { + tp.hasApi(t, func(api iface.CoreAPI) error { + if api.Key() == nil { + return apiNotImplemented + } + return nil + }) + t.Run("TestListSelf", tp.TestListSelf) t.Run("TestRenameSelf", tp.TestRenameSelf) t.Run("TestRemoveSelf", tp.TestRemoveSelf) diff --git a/core/coreiface/tests/name.go b/core/coreiface/tests/name.go index e114b26de..639e72c3d 100644 --- a/core/coreiface/tests/name.go +++ b/core/coreiface/tests/name.go @@ -16,6 +16,13 @@ import ( ) func (tp *provider) TestName(t *testing.T) { + tp.hasApi(t, func(api coreiface.CoreAPI) error { + if api.Name() == nil { + return apiNotImplemented + } + return nil + }) + t.Run("TestPublishResolve", tp.TestPublishResolve) t.Run("TestBasicPublishResolveKey", tp.TestBasicPublishResolveKey) t.Run("TestBasicPublishResolveTimeout", tp.TestBasicPublishResolveTimeout) diff --git a/core/coreiface/tests/object.go b/core/coreiface/tests/object.go index 1cd24aac2..81d5b4117 100644 --- a/core/coreiface/tests/object.go +++ b/core/coreiface/tests/object.go @@ -13,6 +13,13 @@ import ( ) func (tp *provider) TestObject(t *testing.T) { + tp.hasApi(t, func(api iface.CoreAPI) error { + if api.Object() == nil { + return apiNotImplemented + } + return nil + }) + t.Run("TestNew", tp.TestNew) t.Run("TestObjectPut", tp.TestObjectPut) t.Run("TestObjectGet", tp.TestObjectGet) diff --git a/core/coreiface/tests/path.go b/core/coreiface/tests/path.go index 7057d6286..50a1977d5 100644 --- a/core/coreiface/tests/path.go +++ b/core/coreiface/tests/path.go @@ -26,7 +26,20 @@ func (tp *provider) TestMutablePath(t *testing.T) { t.Fatal(err) } + blk, err := api.Block().Put(ctx, strings.NewReader(`foo`)) + if err != nil { + t.Fatal(err) + } + + if blk.Path().Mutable() { + t.Error("expected /ipld path to be immutable") + } + // get self /ipns path + if api.Key() == nil { + t.Fatal(".Key not implemented") + } + keys, err := api.Key().List(ctx) if err != nil { t.Fatal(err) @@ -35,15 +48,6 @@ func (tp *provider) TestMutablePath(t *testing.T) { if !keys[0].Path().Mutable() { t.Error("expected self /ipns path to be mutable") } - - blk, err := api.Block().Put(ctx, strings.NewReader(`foo`)) - if err != nil { - t.Error(err) - } - - if blk.Path().Mutable() { - t.Error("expected /ipld path to be immutable") - } } func (tp *provider) TestPathRemainder(t *testing.T) { @@ -54,6 +58,10 @@ func (tp *provider) TestPathRemainder(t *testing.T) { t.Fatal(err) } + if api.Dag() == nil { + t.Fatal(".Dag not implemented") + } + obj, err := api.Dag().Put(ctx, strings.NewReader(`{"foo": {"bar": "baz"}}`)) if err != nil { t.Fatal(err) @@ -82,6 +90,10 @@ func (tp *provider) TestEmptyPathRemainder(t *testing.T) { t.Fatal(err) } + if api.Dag() == nil { + t.Fatal(".Dag not implemented") + } + obj, err := api.Dag().Put(ctx, strings.NewReader(`{"foo": {"bar": "baz"}}`)) if err != nil { t.Fatal(err) @@ -114,6 +126,10 @@ func (tp *provider) TestInvalidPathRemainder(t *testing.T) { t.Fatal(err) } + if api.Dag() == nil { + t.Fatal(".Dag not implemented") + } + obj, err := api.Dag().Put(ctx, strings.NewReader(`{"foo": {"bar": "baz"}}`)) if err != nil { t.Fatal(err) @@ -138,9 +154,17 @@ func (tp *provider) TestPathRoot(t *testing.T) { t.Fatal(err) } + if api.Block() == nil { + t.Fatal(".Block not implemented") + } + blk, err := api.Block().Put(ctx, strings.NewReader(`foo`), options.Block.Format("raw")) if err != nil { - t.Error(err) + t.Fatal(err) + } + + if api.Dag() == nil { + t.Fatal(".Dag not implemented") } obj, err := api.Dag().Put(ctx, strings.NewReader(`{"foo": {"/": "`+blk.Path().Cid().String()+`"}}`)) diff --git a/core/coreiface/tests/pin.go b/core/coreiface/tests/pin.go index 823281ab1..87ad8a004 100644 --- a/core/coreiface/tests/pin.go +++ b/core/coreiface/tests/pin.go @@ -2,6 +2,7 @@ package tests import ( "context" + "github.com/ipfs/go-ipfs/core/coreapi/interface" "strings" "testing" @@ -9,6 +10,13 @@ import ( ) func (tp *provider) TestPin(t *testing.T) { + tp.hasApi(t, func(api iface.CoreAPI) error { + if api.Pin() == nil { + return apiNotImplemented + } + return nil + }) + t.Run("TestPinAdd", tp.TestPinAdd) t.Run("TestPinSimple", tp.TestPinSimple) t.Run("TestPinRecursive", tp.TestPinRecursive) diff --git a/core/coreiface/tests/pubsub.go b/core/coreiface/tests/pubsub.go index 3462b4755..b993f51dc 100644 --- a/core/coreiface/tests/pubsub.go +++ b/core/coreiface/tests/pubsub.go @@ -2,12 +2,20 @@ package tests import ( "context" + "github.com/ipfs/go-ipfs/core/coreapi/interface" "github.com/ipfs/go-ipfs/core/coreapi/interface/options" "testing" "time" ) func (tp *provider) TestPubSub(t *testing.T) { + tp.hasApi(t, func(api iface.CoreAPI) error { + if api.PubSub() == nil { + return apiNotImplemented + } + return nil + }) + t.Run("TestBasicPubSub", tp.TestBasicPubSub) } diff --git a/core/coreiface/tests/unixfs.go b/core/coreiface/tests/unixfs.go index f411ad24d..ddb3145f7 100644 --- a/core/coreiface/tests/unixfs.go +++ b/core/coreiface/tests/unixfs.go @@ -24,6 +24,13 @@ import ( ) func (tp *provider) TestUnixfs(t *testing.T) { + tp.hasApi(t, func(api coreiface.CoreAPI) error { + if api.Unixfs() == nil { + return apiNotImplemented + } + return nil + }) + t.Run("TestAdd", tp.TestAdd) t.Run("TestAddPinned", tp.TestAddPinned) t.Run("TestAddHashOnly", tp.TestAddHashOnly) From 12b64d0d401e83617eae0e45590c7d8f96e89a48 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Tue, 8 Jan 2019 19:19:34 -0800 Subject: [PATCH 0184/1212] gx: update deps Importantly: * fixes a bunch of MFS bugs * pulls in some bitswap improvements License: MIT Signed-off-by: Steven Allen This commit was moved from ipfs/interface-go-ipfs-core@e51dd550f4404781592f8d911ba822512039f304 This commit was moved from ipfs/boxo@551b466a611343bda0eb37d646ef753153919d2a --- core/coreiface/dht.go | 2 +- core/coreiface/options/unixfs.go | 2 +- core/coreiface/path.go | 2 +- core/coreiface/swarm.go | 6 +++--- core/coreiface/tests/name.go | 2 +- core/coreiface/tests/unixfs.go | 4 ++-- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/core/coreiface/dht.go b/core/coreiface/dht.go index e39be92c5..ec8bd92c3 100644 --- a/core/coreiface/dht.go +++ b/core/coreiface/dht.go @@ -5,8 +5,8 @@ import ( "github.com/ipfs/go-ipfs/core/coreapi/interface/options" + pstore "gx/ipfs/QmPiemjiKBC9VA7vZF82m4x1oygtg2c2YVqag8PX7dN1BD/go-libp2p-peerstore" peer "gx/ipfs/QmY5Grm8pJdiSSVsYxx4uNRgweY72EmYwuSDbRnbFok3iY/go-libp2p-peer" - pstore "gx/ipfs/QmZ9zH2FnLcxv1xyzFeUpDUeo55xEhZQHgveZijcxr7TLj/go-libp2p-peerstore" ) // DhtAPI specifies the interface to the DHT diff --git a/core/coreiface/options/unixfs.go b/core/coreiface/options/unixfs.go index fd748bb4a..5f92f3eea 100644 --- a/core/coreiface/options/unixfs.go +++ b/core/coreiface/options/unixfs.go @@ -5,7 +5,7 @@ import ( "fmt" cid "gx/ipfs/QmR8BauakNcBa3RbE4nbQu76PDiJgoQgz8AJdhJuiU4TAw/go-cid" - dag "gx/ipfs/QmdV35UHnL1FM52baPkeUo6u7Fxm2CRUkPTLRPxeF8a4Ap/go-merkledag" + dag "gx/ipfs/QmTQdH4848iTVCJmKXYyRiK72HufWTLYQQ8iN3JaQ8K1Hq/go-merkledag" mh "gx/ipfs/QmerPMzPk1mJVowm8KgmoknWa4yCYvvugMPsgWmDNUvDLW/go-multihash" ) diff --git a/core/coreiface/path.go b/core/coreiface/path.go index 96f30852d..580703a73 100644 --- a/core/coreiface/path.go +++ b/core/coreiface/path.go @@ -1,8 +1,8 @@ package iface import ( + ipfspath "gx/ipfs/QmNYPETsdAu2uQ1k9q9S1jYEGURaLHV6cbYRSVFVRftpF8/go-path" "gx/ipfs/QmR8BauakNcBa3RbE4nbQu76PDiJgoQgz8AJdhJuiU4TAw/go-cid" - ipfspath "gx/ipfs/QmZErC2Ay6WuGi96CPg316PwitdwgLo6RxZRqVjJjRj2MR/go-path" ) //TODO: merge with ipfspath so we don't depend on it diff --git a/core/coreiface/swarm.go b/core/coreiface/swarm.go index 63d20f035..83e207282 100644 --- a/core/coreiface/swarm.go +++ b/core/coreiface/swarm.go @@ -5,10 +5,10 @@ import ( "errors" "time" - net "gx/ipfs/QmPtFaR7BWHLAjSwLh9kXcyrgTzDpuhcWLkx8ioa9RMYnx/go-libp2p-net" - ma "gx/ipfs/QmRKLtwMw131aK7ugC3G7ybpumMz78YrJe5dzneyindvG1/go-multiaddr" + ma "gx/ipfs/QmNTCey11oxhb1AxDnQBRHtdhap6Ctud872NjAYPYYXPuc/go-multiaddr" + net "gx/ipfs/QmNgLg1NTw37iWbYPKcyK85YJ9Whs1MkPtJwhfqbNYAyKg/go-libp2p-net" + pstore "gx/ipfs/QmPiemjiKBC9VA7vZF82m4x1oygtg2c2YVqag8PX7dN1BD/go-libp2p-peerstore" "gx/ipfs/QmY5Grm8pJdiSSVsYxx4uNRgweY72EmYwuSDbRnbFok3iY/go-libp2p-peer" - pstore "gx/ipfs/QmZ9zH2FnLcxv1xyzFeUpDUeo55xEhZQHgveZijcxr7TLj/go-libp2p-peerstore" "gx/ipfs/QmZNkThpqfVXs9GNbexPrfBbXSLNYeKrE7jwFM2oqHbyqN/go-libp2p-protocol" ) diff --git a/core/coreiface/tests/name.go b/core/coreiface/tests/name.go index 639e72c3d..2e43a12ee 100644 --- a/core/coreiface/tests/name.go +++ b/core/coreiface/tests/name.go @@ -8,8 +8,8 @@ import ( "testing" "time" + ipath "gx/ipfs/QmNYPETsdAu2uQ1k9q9S1jYEGURaLHV6cbYRSVFVRftpF8/go-path" "gx/ipfs/QmXWZCd8jfaHmt4UDSnjKmGcrQMw95bDGWqEeVLVJjoANX/go-ipfs-files" - ipath "gx/ipfs/QmZErC2Ay6WuGi96CPg316PwitdwgLo6RxZRqVjJjRj2MR/go-path" coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface" opt "github.com/ipfs/go-ipfs/core/coreapi/interface/options" diff --git a/core/coreiface/tests/unixfs.go b/core/coreiface/tests/unixfs.go index ddb3145f7..e8a1aba32 100644 --- a/core/coreiface/tests/unixfs.go +++ b/core/coreiface/tests/unixfs.go @@ -15,11 +15,11 @@ import ( coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface" "github.com/ipfs/go-ipfs/core/coreapi/interface/options" + "gx/ipfs/QmQXze9tG878pa4Euya4rrDpyTNX3kQe4dhCaBzBozGgpe/go-unixfs" "gx/ipfs/QmR8BauakNcBa3RbE4nbQu76PDiJgoQgz8AJdhJuiU4TAw/go-cid" cbor "gx/ipfs/QmRoARq3nkUb13HSKZGepCZSWe5GrVPwx7xURJGZ7KWv9V/go-ipld-cbor" + mdag "gx/ipfs/QmTQdH4848iTVCJmKXYyRiK72HufWTLYQQ8iN3JaQ8K1Hq/go-merkledag" "gx/ipfs/QmXWZCd8jfaHmt4UDSnjKmGcrQMw95bDGWqEeVLVJjoANX/go-ipfs-files" - "gx/ipfs/Qmbvw7kpSM2p6rbQ57WGRhhqNfCiNGW6EKH4xgHLw4bsnB/go-unixfs" - mdag "gx/ipfs/QmdV35UHnL1FM52baPkeUo6u7Fxm2CRUkPTLRPxeF8a4Ap/go-merkledag" mh "gx/ipfs/QmerPMzPk1mJVowm8KgmoknWa4yCYvvugMPsgWmDNUvDLW/go-multihash" ) From 00597e6dff81846a2dbf742dd1ab9bf546b856e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 9 Jan 2019 09:04:22 +0100 Subject: [PATCH 0185/1212] Dag.Put This commit was moved from ipfs/go-ipfs-http-client@3217104469020f0c66d8457842f8221b64289d74 --- client/httpapi/api.go | 2 +- client/httpapi/dag.go | 69 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 client/httpapi/dag.go diff --git a/client/httpapi/api.go b/client/httpapi/api.go index 3df45f38c..c2ec1ad67 100644 --- a/client/httpapi/api.go +++ b/client/httpapi/api.go @@ -138,7 +138,7 @@ func (api *HttpApi) Block() iface.BlockAPI { } func (api *HttpApi) Dag() iface.DagAPI { - return nil + return (*DagAPI)(api) } func (api *HttpApi) Name() iface.NameAPI { diff --git a/client/httpapi/dag.go b/client/httpapi/dag.go new file mode 100644 index 000000000..c3b29e7ee --- /dev/null +++ b/client/httpapi/dag.go @@ -0,0 +1,69 @@ +package httpapi + +import ( + "context" + "fmt" + "github.com/ipfs/go-cid" + "io" + + "github.com/ipfs/go-ipfs/core/coreapi/interface" + "github.com/ipfs/go-ipfs/core/coreapi/interface/options" + + caopts "github.com/ipfs/go-ipfs/core/coreapi/interface/options" + "github.com/ipfs/go-ipld-format" + mh "github.com/multiformats/go-multihash" +) + +type DagAPI HttpApi + +func (api *DagAPI) Put(ctx context.Context, src io.Reader, opts ...options.DagPutOption) (iface.ResolvedPath, error) { + options, err := caopts.DagPutOptions(opts...) + if err != nil { + return nil, err + } + + mht, ok := mh.Codes[options.MhType] + if !ok { + return nil, fmt.Errorf("unknowm mhType %d", options.MhType) + } + + codec, ok := cid.CodecToStr[options.Codec] + if !ok { + return nil, fmt.Errorf("unknowm codec %d", options.MhType) + } + + if options.MhLength != -1 { + return nil, fmt.Errorf("setting hash len is not supported yet") + } + + var out struct{ + Cid cid.Cid + } + err = api.core().request("dht/put"). + Option("hash", mht). + Option("format", codec). + Option("input-enc", options.InputEnc). + FileBody(src). + Exec(ctx, &out) + if err != nil { + return nil, err + } + + return iface.IpldPath(out.Cid), nil +} + +func (api *DagAPI) Get(ctx context.Context, path iface.Path) (format.Node, error) { + panic("implement me") +} + +func (api *DagAPI) Tree(ctx context.Context, path iface.Path, opts ...options.DagTreeOption) ([]iface.Path, error) { + panic("implement me") +} + +func (api *DagAPI) Batch(ctx context.Context) iface.DagBatch { + panic("implement me") +} + +func (api *DagAPI) core() *HttpApi { + return (*HttpApi)(api) +} From 101910f04ed0575be19efaacb44b1bce73717033 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 9 Jan 2019 09:22:10 +0100 Subject: [PATCH 0186/1212] Object.New This commit was moved from ipfs/go-ipfs-http-client@60321ed42fd8f42e964e37ab5e96839fb8fd77b6 --- client/httpapi/api.go | 2 +- client/httpapi/ipldnode.go | 8 ++++ client/httpapi/object.go | 82 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 client/httpapi/object.go diff --git a/client/httpapi/api.go b/client/httpapi/api.go index c2ec1ad67..cf9a633bc 100644 --- a/client/httpapi/api.go +++ b/client/httpapi/api.go @@ -154,7 +154,7 @@ func (api *HttpApi) Pin() iface.PinAPI { } func (api *HttpApi) Object() iface.ObjectAPI { - return nil + return (*ObjectAPI)(api) } func (api *HttpApi) Dht() iface.DhtAPI { diff --git a/client/httpapi/ipldnode.go b/client/httpapi/ipldnode.go index b8e6fba01..1f584ac07 100644 --- a/client/httpapi/ipldnode.go +++ b/client/httpapi/ipldnode.go @@ -20,6 +20,14 @@ type ipldNode struct { api *HttpApi } +func (a *HttpApi) nodeFromPath(ctx context.Context, p iface.ResolvedPath) ipld.Node { + return &ipldNode{ + ctx: ctx, + path: p, + api: a, + } +} + func (n *ipldNode) RawData() []byte { r, err := n.api.Block().Get(n.ctx, n.path) if err != nil { diff --git a/client/httpapi/object.go b/client/httpapi/object.go new file mode 100644 index 000000000..9c1063af9 --- /dev/null +++ b/client/httpapi/object.go @@ -0,0 +1,82 @@ +package httpapi + +import ( + "context" + "github.com/ipfs/go-cid" + "io" + + "github.com/ipfs/go-ipfs/core/coreapi/interface" + caopts "github.com/ipfs/go-ipfs/core/coreapi/interface/options" + + "github.com/ipfs/go-ipld-format" +) + +type ObjectAPI HttpApi + +type objectOut struct { + Hash string +} + +func (api *ObjectAPI) New(ctx context.Context, opts ...caopts.ObjectNewOption) (format.Node, error) { + options, err := caopts.ObjectNewOptions(opts...) + if err != nil { + return nil, err + } + + var out objectOut + err = api.core().request("object/new", options.Type).Exec(ctx, &out) + if err != nil { + return nil, err + } + + c, err := cid.Parse(out.Hash) + if err != nil { + return nil, err + } + + return api.core().nodeFromPath(ctx, iface.IpfsPath(c)), nil +} + +func (api *ObjectAPI) Put(context.Context, io.Reader, ...caopts.ObjectPutOption) (iface.ResolvedPath, error) { + panic("implement me") +} + +func (api *ObjectAPI) Get(context.Context, iface.Path) (format.Node, error) { + panic("implement me") +} + +func (api *ObjectAPI) Data(context.Context, iface.Path) (io.Reader, error) { + panic("implement me") +} + +func (api *ObjectAPI) Links(context.Context, iface.Path) ([]*format.Link, error) { + panic("implement me") +} + +func (api *ObjectAPI) Stat(context.Context, iface.Path) (*iface.ObjectStat, error) { + panic("implement me") +} + +func (api *ObjectAPI) AddLink(ctx context.Context, base iface.Path, name string, child iface.Path, opts ...caopts.ObjectAddLinkOption) (iface.ResolvedPath, error) { + panic("implement me") +} + +func (api *ObjectAPI) RmLink(ctx context.Context, base iface.Path, link string) (iface.ResolvedPath, error) { + panic("implement me") +} + +func (api *ObjectAPI) AppendData(context.Context, iface.Path, io.Reader) (iface.ResolvedPath, error) { + panic("implement me") +} + +func (api *ObjectAPI) SetData(context.Context, iface.Path, io.Reader) (iface.ResolvedPath, error) { + panic("implement me") +} + +func (api *ObjectAPI) Diff(context.Context, iface.Path, iface.Path) ([]iface.ObjectChange, error) { + panic("implement me") +} + +func (api *ObjectAPI) core() *HttpApi { + return (*HttpApi)(api) +} From 31a4c3754b87e68f60525533ba9c6bb9c0b1021e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 9 Jan 2019 09:47:32 +0100 Subject: [PATCH 0187/1212] Fix Dag.Put This commit was moved from ipfs/go-ipfs-http-client@5b2c99abdedaf464f061511bc7b24b1ade66546f --- client/httpapi/dag.go | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/client/httpapi/dag.go b/client/httpapi/dag.go index c3b29e7ee..152d2c6b0 100644 --- a/client/httpapi/dag.go +++ b/client/httpapi/dag.go @@ -3,30 +3,25 @@ package httpapi import ( "context" "fmt" - "github.com/ipfs/go-cid" "io" + "math" "github.com/ipfs/go-ipfs/core/coreapi/interface" - "github.com/ipfs/go-ipfs/core/coreapi/interface/options" - caopts "github.com/ipfs/go-ipfs/core/coreapi/interface/options" + + "github.com/ipfs/go-cid" "github.com/ipfs/go-ipld-format" mh "github.com/multiformats/go-multihash" ) type DagAPI HttpApi -func (api *DagAPI) Put(ctx context.Context, src io.Reader, opts ...options.DagPutOption) (iface.ResolvedPath, error) { +func (api *DagAPI) Put(ctx context.Context, src io.Reader, opts ...caopts.DagPutOption) (iface.ResolvedPath, error) { options, err := caopts.DagPutOptions(opts...) if err != nil { return nil, err } - mht, ok := mh.Codes[options.MhType] - if !ok { - return nil, fmt.Errorf("unknowm mhType %d", options.MhType) - } - codec, ok := cid.CodecToStr[options.Codec] if !ok { return nil, fmt.Errorf("unknowm codec %d", options.MhType) @@ -39,12 +34,19 @@ func (api *DagAPI) Put(ctx context.Context, src io.Reader, opts ...options.DagPu var out struct{ Cid cid.Cid } - err = api.core().request("dht/put"). - Option("hash", mht). + req := api.core().request("dag/put"). Option("format", codec). - Option("input-enc", options.InputEnc). - FileBody(src). - Exec(ctx, &out) + Option("input-enc", options.InputEnc) + + if options.MhType != math.MaxUint64 { + mht, ok := mh.Codes[options.MhType] + if !ok { + return nil, fmt.Errorf("unknowm mhType %d", options.MhType) + } + req.Option("hash", mht) + } + + err = req.FileBody(src).Exec(ctx, &out) if err != nil { return nil, err } @@ -56,7 +58,7 @@ func (api *DagAPI) Get(ctx context.Context, path iface.Path) (format.Node, error panic("implement me") } -func (api *DagAPI) Tree(ctx context.Context, path iface.Path, opts ...options.DagTreeOption) ([]iface.Path, error) { +func (api *DagAPI) Tree(ctx context.Context, path iface.Path, opts ...caopts.DagTreeOption) ([]iface.Path, error) { panic("implement me") } From c213e2654235ffbdb6ce2f3a7df3c027ba53e02f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 9 Jan 2019 21:55:45 +0100 Subject: [PATCH 0188/1212] Unixfs.Add progress events This commit was moved from ipfs/go-ipfs-http-client@2f3a77b686ee8c4194ee6c21cbdecd57f2081519 --- client/httpapi/api.go | 4 +-- client/httpapi/api_test.go | 6 ++--- client/httpapi/apifile.go | 24 +++++++++--------- client/httpapi/block.go | 2 +- client/httpapi/dag.go | 2 +- client/httpapi/ipldnode.go | 4 +-- client/httpapi/key.go | 5 ++-- client/httpapi/object.go | 2 +- client/httpapi/pin.go | 3 +-- client/httpapi/unixfs.go | 51 ++++++++++++++++++++++++++++++++++---- 10 files changed, 71 insertions(+), 32 deletions(-) diff --git a/client/httpapi/api.go b/client/httpapi/api.go index cf9a633bc..c686a8d0d 100644 --- a/client/httpapi/api.go +++ b/client/httpapi/api.go @@ -99,8 +99,8 @@ func NewApiWithClient(a ma.Multiaddr, c *gohttp.Client) *HttpApi { } return &HttpApi{ - url: url, - httpcli: c, + url: url, + httpcli: c, applyGlobal: func(*RequestBuilder) {}, } } diff --git a/client/httpapi/api_test.go b/client/httpapi/api_test.go index 67a2dbdce..b822378f7 100644 --- a/client/httpapi/api_test.go +++ b/client/httpapi/api_test.go @@ -53,7 +53,7 @@ func (NodeProvider) MakeAPISwarm(ctx context.Context, fullIdentity bool, n int) } if n > 1 { - connectArgs := []string{"iptb", "--IPTB_ROOT", dir, "connect", fmt.Sprintf("[1-%d]", n - 1), "0"} + connectArgs := []string{"iptb", "--IPTB_ROOT", dir, "connect", fmt.Sprintf("[1-%d]", n-1), "0"} if err := c.Run(connectArgs); err != nil { return nil, err } @@ -95,8 +95,8 @@ func (NodeProvider) MakeAPISwarm(ctx context.Context, fullIdentity bool, n int) } c := &gohttp.Client{ Transport: &gohttp.Transport{ - Proxy: gohttp.ProxyFromEnvironment, - DisableKeepAlives: true, + Proxy: gohttp.ProxyFromEnvironment, + DisableKeepAlives: true, DisableCompression: true, }, } diff --git a/client/httpapi/apifile.go b/client/httpapi/apifile.go index 541189b60..d9da23975 100644 --- a/client/httpapi/apifile.go +++ b/client/httpapi/apifile.go @@ -22,12 +22,12 @@ func (api *UnixfsAPI) Get(ctx context.Context, p iface.Path) (files.Node, error) } } - var stat struct{ + var stat struct { Hash string Type string Size int64 // unixfs size } - err := api.core().request("files/stat", p.String()). Exec(ctx, &stat) + err := api.core().request("files/stat", p.String()).Exec(ctx, &stat) if err != nil { return nil, err } @@ -43,12 +43,12 @@ func (api *UnixfsAPI) Get(ctx context.Context, p iface.Path) (files.Node, error) } type apiFile struct { - ctx context.Context + ctx context.Context core *HttpApi size int64 path iface.Path - r io.ReadCloser + r io.ReadCloser at int64 } @@ -96,7 +96,7 @@ func (f *apiFile) Size() (int64, error) { func (api *UnixfsAPI) getFile(ctx context.Context, p iface.Path, size int64) (files.Node, error) { f := &apiFile{ - ctx: ctx, + ctx: ctx, core: api.core(), size: size, path: p, @@ -106,14 +106,14 @@ func (api *UnixfsAPI) getFile(ctx context.Context, p iface.Path, size int64) (fi } type apiIter struct { - ctx context.Context + ctx context.Context core *UnixfsAPI err error - dec *json.Decoder + dec *json.Decoder curFile files.Node - cur lsLink + cur lsLink } func (it *apiIter) Err() error { @@ -179,7 +179,7 @@ func (it *apiIter) Node() files.Node { } type apiDir struct { - ctx context.Context + ctx context.Context core *UnixfsAPI size int64 path iface.Path @@ -197,9 +197,9 @@ func (d *apiDir) Size() (int64, error) { func (d *apiDir) Entries() files.DirIterator { return &apiIter{ - ctx: d.ctx, + ctx: d.ctx, core: d.core, - dec: d.dec, + dec: d.dec, } } @@ -216,7 +216,7 @@ func (api *UnixfsAPI) getDir(ctx context.Context, p iface.Path, size int64) (fil } d := &apiDir{ - ctx: ctx, + ctx: ctx, core: api, size: size, path: p, diff --git a/client/httpapi/block.go b/client/httpapi/block.go index 185aa0a42..f933d3c4a 100644 --- a/client/httpapi/block.go +++ b/client/httpapi/block.go @@ -16,7 +16,7 @@ import ( type BlockAPI HttpApi type blockStat struct { - Key string + Key string BSize int `json:"Size"` } diff --git a/client/httpapi/dag.go b/client/httpapi/dag.go index 152d2c6b0..20c233196 100644 --- a/client/httpapi/dag.go +++ b/client/httpapi/dag.go @@ -31,7 +31,7 @@ func (api *DagAPI) Put(ctx context.Context, src io.Reader, opts ...caopts.DagPut return nil, fmt.Errorf("setting hash len is not supported yet") } - var out struct{ + var out struct { Cid cid.Cid } req := api.core().request("dag/put"). diff --git a/client/httpapi/ipldnode.go b/client/httpapi/ipldnode.go index 1f584ac07..8e028e1a7 100644 --- a/client/httpapi/ipldnode.go +++ b/client/httpapi/ipldnode.go @@ -22,9 +22,9 @@ type ipldNode struct { func (a *HttpApi) nodeFromPath(ctx context.Context, p iface.ResolvedPath) ipld.Node { return &ipldNode{ - ctx: ctx, + ctx: ctx, path: p, - api: a, + api: a, } } diff --git a/client/httpapi/key.go b/client/httpapi/key.go index 87b573f98..3653526eb 100644 --- a/client/httpapi/key.go +++ b/client/httpapi/key.go @@ -13,7 +13,7 @@ type KeyAPI HttpApi type keyOutput struct { JName string `json:"Name"` - Id string + Id string } func (k *keyOutput) Name() string { @@ -35,7 +35,6 @@ func (k *keyOutput) valid() error { return err } - func (api *KeyAPI) Generate(ctx context.Context, name string, opts ...caopts.KeyGenerateOption) (iface.Key, error) { options, err := caopts.KeyGenerateOptions(opts...) if err != nil { @@ -65,7 +64,7 @@ func (api *KeyAPI) List(ctx context.Context) ([]iface.Key, error) { } func (api *KeyAPI) Self(ctx context.Context) (iface.Key, error) { - var id struct{ID string} + var id struct{ ID string } if err := api.core().request("id").Exec(ctx, &id); err != nil { return nil, err } diff --git a/client/httpapi/object.go b/client/httpapi/object.go index 9c1063af9..6259473c7 100644 --- a/client/httpapi/object.go +++ b/client/httpapi/object.go @@ -14,7 +14,7 @@ import ( type ObjectAPI HttpApi type objectOut struct { - Hash string + Hash string } func (api *ObjectAPI) New(ctx context.Context, opts ...caopts.ObjectNewOption) (format.Node, error) { diff --git a/client/httpapi/pin.go b/client/httpapi/pin.go index 02dcc4222..ea34dc540 100644 --- a/client/httpapi/pin.go +++ b/client/httpapi/pin.go @@ -20,7 +20,7 @@ type pinRefKeyList struct { type pin struct { path iface.ResolvedPath - typ string + typ string } func (p *pin) Path() iface.ResolvedPath { @@ -31,7 +31,6 @@ func (p *pin) Type() string { return p.typ } - func (api *PinAPI) Add(context.Context, iface.Path, ...caopts.PinAddOption) error { panic("implement me") } diff --git a/client/httpapi/unixfs.go b/client/httpapi/unixfs.go index 77daf7b9b..7e63d241f 100644 --- a/client/httpapi/unixfs.go +++ b/client/httpapi/unixfs.go @@ -2,9 +2,11 @@ package httpapi import ( "context" + "encoding/json" "fmt" "github.com/ipfs/go-cid" "github.com/pkg/errors" + "io" "github.com/ipfs/go-ipfs/core/coreapi/interface" caopts "github.com/ipfs/go-ipfs/core/coreapi/interface/options" @@ -39,7 +41,6 @@ func (api *UnixfsAPI) Add(ctx context.Context, f files.Node, opts ...caopts.Unix Option("hash", mht). Option("chunker", options.Chunker). Option("cid-version", options.CidVersion). - //Option("", options.Events). Option("fscache", options.FsCache). Option("hidden", options.Hidden). Option("inline", options.Inline). @@ -47,11 +48,10 @@ func (api *UnixfsAPI) Add(ctx context.Context, f files.Node, opts ...caopts.Unix Option("nocopy", options.NoCopy). Option("only-hash", options.OnlyHash). Option("pin", options.Pin). - //Option("", options.Progress). Option("silent", options.Silent). Option("stdin-name", options.StdinName). Option("wrap-with-directory", options.Wrap). - Option("quieter", true) // TODO: rm after event impl + Option("progress", options.Progress) if options.RawLeavesSet { req.Option("raw-leaves", options.RawLeaves) @@ -73,9 +73,50 @@ func (api *UnixfsAPI) Add(ctx context.Context, f files.Node, opts ...caopts.Unix } var out addEvent - if err := req.Exec(ctx, &out); err != nil { //TODO: ndjson events + resp, err := req.Send(ctx) + if err != nil { return nil, err } + if resp.Error != nil { + return nil, resp.Error + } + defer resp.Output.Close() + dec := json.NewDecoder(resp.Output) +loop: + for { + var evt addEvent + switch err := dec.Decode(&evt); err { + case nil: + case io.EOF: + break loop + default: + return nil, err + } + out = evt + + if options.Events != nil { + ifevt := &iface.AddEvent{ + Name: out.Name, + Size: out.Size, + Bytes: out.Bytes, + } + + if out.Hash != "" { + c, err := cid.Parse(out.Hash) + if err != nil { + return nil, err + } + + ifevt.Path = iface.IpfsPath(c) + } + + select { + case options.Events <- ifevt: + case <-ctx.Done(): + return nil, ctx.Err() + } + } + } c, err := cid.Parse(out.Hash) if err != nil { @@ -120,7 +161,7 @@ func (api *UnixfsAPI) Ls(ctx context.Context, p iface.Path) ([]*format.Link, err links[i] = &format.Link{ Name: l.Name, Size: l.Size, - Cid: c, + Cid: c, } } return links, nil From ba369e588d63c47bef4252593027cfe363ac54a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Sat, 12 Jan 2019 15:41:19 +0100 Subject: [PATCH 0189/1212] coreapi: replace coreiface.DagAPI with ipld.DAGService MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@8e049b49d6e97f38c682aed4b2c18cdb557b3b84 This commit was moved from ipfs/boxo@30ccbef95ef833214b85ad077614b4b07b85c9f1 --- core/coreiface/coreapi.go | 2 +- core/coreiface/dag.go | 41 --------------- core/coreiface/options/dag.go | 95 ---------------------------------- core/coreiface/tests/dag.go | 93 +++++++++++++++++++++------------ core/coreiface/tests/path.go | 40 +++++++++----- core/coreiface/tests/pin.go | 24 +++++---- core/coreiface/tests/unixfs.go | 6 +-- 7 files changed, 107 insertions(+), 194 deletions(-) delete mode 100644 core/coreiface/dag.go delete mode 100644 core/coreiface/options/dag.go diff --git a/core/coreiface/coreapi.go b/core/coreiface/coreapi.go index 226399967..9d2100fcc 100644 --- a/core/coreiface/coreapi.go +++ b/core/coreiface/coreapi.go @@ -19,7 +19,7 @@ type CoreAPI interface { Block() BlockAPI // Dag returns an implementation of Dag API - Dag() DagAPI + Dag() ipld.DAGService // Name returns an implementation of Name API Name() NameAPI diff --git a/core/coreiface/dag.go b/core/coreiface/dag.go deleted file mode 100644 index eb9e2da4a..000000000 --- a/core/coreiface/dag.go +++ /dev/null @@ -1,41 +0,0 @@ -package iface - -import ( - "context" - "io" - - "github.com/ipfs/go-ipfs/core/coreapi/interface/options" - - ipld "gx/ipfs/QmcKKBwfz6FyQdHR2jsXrrF6XeSBXYL86anmWNewpFpoF5/go-ipld-format" -) - -// DagOps groups operations that can be batched together -type DagOps interface { - // Put inserts data using specified format and input encoding. - // Unless used with WithCodec or WithHash, the defaults "dag-cbor" and - // "sha256" are used. - Put(ctx context.Context, src io.Reader, opts ...options.DagPutOption) (ResolvedPath, error) -} - -// DagBatch is the batching version of DagAPI. All implementations of DagBatch -// should be threadsafe -type DagBatch interface { - DagOps - - // Commit commits nodes to the datastore and announces them to the network - Commit(ctx context.Context) error -} - -// DagAPI specifies the interface to IPLD -type DagAPI interface { - DagOps - - // Get attempts to resolve and get the node specified by the path - Get(ctx context.Context, path Path) (ipld.Node, error) - - // Tree returns list of paths within a node specified by the path. - Tree(ctx context.Context, path Path, opts ...options.DagTreeOption) ([]Path, error) - - // Batch creates new DagBatch - Batch(ctx context.Context) DagBatch -} diff --git a/core/coreiface/options/dag.go b/core/coreiface/options/dag.go deleted file mode 100644 index 9cccba585..000000000 --- a/core/coreiface/options/dag.go +++ /dev/null @@ -1,95 +0,0 @@ -package options - -import ( - "math" - - cid "gx/ipfs/QmR8BauakNcBa3RbE4nbQu76PDiJgoQgz8AJdhJuiU4TAw/go-cid" -) - -type DagPutSettings struct { - InputEnc string - Codec uint64 - MhType uint64 - MhLength int -} - -type DagTreeSettings struct { - Depth int -} - -type DagPutOption func(*DagPutSettings) error -type DagTreeOption func(*DagTreeSettings) error - -func DagPutOptions(opts ...DagPutOption) (*DagPutSettings, error) { - options := &DagPutSettings{ - InputEnc: "json", - Codec: cid.DagCBOR, - MhType: math.MaxUint64, - MhLength: -1, - } - - for _, opt := range opts { - err := opt(options) - if err != nil { - return nil, err - } - } - return options, nil -} - -func DagTreeOptions(opts ...DagTreeOption) (*DagTreeSettings, error) { - options := &DagTreeSettings{ - Depth: -1, - } - - for _, opt := range opts { - err := opt(options) - if err != nil { - return nil, err - } - } - return options, nil -} - -type dagOpts struct{} - -var Dag dagOpts - -// InputEnc is an option for Dag.Put which specifies the input encoding of the -// data. Default is "json", most formats/codecs support "raw" -func (dagOpts) InputEnc(enc string) DagPutOption { - return func(settings *DagPutSettings) error { - settings.InputEnc = enc - return nil - } -} - -// Codec is an option for Dag.Put which specifies the multicodec to use to -// serialize the object. Default is cid.DagCBOR (0x71) -func (dagOpts) Codec(codec uint64) DagPutOption { - return func(settings *DagPutSettings) error { - settings.Codec = codec - return nil - } -} - -// Hash is an option for Dag.Put which specifies the multihash settings to use -// when hashing the object. Default is based on the codec used -// (mh.SHA2_256 (0x12) for DagCBOR). If mhLen is set to -1, default length for -// the hash will be used -func (dagOpts) Hash(mhType uint64, mhLen int) DagPutOption { - return func(settings *DagPutSettings) error { - settings.MhType = mhType - settings.MhLength = mhLen - return nil - } -} - -// Depth is an option for Dag.Tree which specifies maximum depth of the -// returned tree. Default is -1 (no depth limit) -func (dagOpts) Depth(depth int) DagTreeOption { - return func(settings *DagTreeSettings) error { - settings.Depth = depth - return nil - } -} diff --git a/core/coreiface/tests/dag.go b/core/coreiface/tests/dag.go index 70a45aa20..e66106c33 100644 --- a/core/coreiface/tests/dag.go +++ b/core/coreiface/tests/dag.go @@ -2,12 +2,13 @@ package tests import ( "context" + "math" "path" "strings" "testing" coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface" - opt "github.com/ipfs/go-ipfs/core/coreapi/interface/options" + coredag "github.com/ipfs/go-ipfs/core/coredag" mh "gx/ipfs/QmerPMzPk1mJVowm8KgmoknWa4yCYvvugMPsgWmDNUvDLW/go-multihash" ) @@ -45,13 +46,18 @@ func (tp *provider) TestPut(t *testing.T) { t.Error(err) } - res, err := api.Dag().Put(ctx, strings.NewReader(`"Hello"`)) + nds, err := coredag.ParseInputs("json", "dag-cbor", strings.NewReader(`"Hello"`), math.MaxUint64, -1) + if err != nil { + t.Error(err) + } + + err = api.Dag().Add(ctx, nds[0]) if err != nil { t.Fatal(err) } - if res.Cid().String() != "zdpuAqckYF3ToF3gcJNxPZXmnmGuXd3gxHCXhq81HGxBejEvv" { - t.Errorf("got wrong cid: %s", res.Cid().String()) + if nds[0].Cid().String() != "zdpuAqckYF3ToF3gcJNxPZXmnmGuXd3gxHCXhq81HGxBejEvv" { + t.Errorf("got wrong cid: %s", nds[0].Cid().String()) } } @@ -63,13 +69,18 @@ func (tp *provider) TestPutWithHash(t *testing.T) { t.Error(err) } - res, err := api.Dag().Put(ctx, strings.NewReader(`"Hello"`), opt.Dag.Hash(mh.ID, -1)) + nds, err := coredag.ParseInputs("json", "dag-cbor", strings.NewReader(`"Hello"`), mh.ID, -1) + if err != nil { + t.Error(err) + } + + err = api.Dag().Add(ctx, nds[0]) if err != nil { t.Fatal(err) } - if res.Cid().String() != "z5hRLNd2sv4z1c" { - t.Errorf("got wrong cid: %s", res.Cid().String()) + if nds[0].Cid().String() != "z5hRLNd2sv4z1c" { + t.Errorf("got wrong cid: %s", nds[0].Cid().String()) } } @@ -81,28 +92,43 @@ func (tp *provider) TestDagPath(t *testing.T) { t.Error(err) } - sub, err := api.Dag().Put(ctx, strings.NewReader(`"foo"`)) - if err != nil { - t.Fatal(err) - } - - res, err := api.Dag().Put(ctx, strings.NewReader(`{"lnk": {"/": "`+sub.Cid().String()+`"}}`)) - if err != nil { - t.Fatal(err) - } - - p, err := coreiface.ParsePath(path.Join(res.Cid().String(), "lnk")) + snds, err := coredag.ParseInputs("json", "dag-cbor", strings.NewReader(`"foo"`), math.MaxUint64, -1) if err != nil { t.Error(err) } - nd, err := api.Dag().Get(ctx, p) + err = api.Dag().Add(ctx, snds[0]) + if err != nil { + t.Fatal(err) + } + + nds, err := coredag.ParseInputs("json", "dag-cbor", strings.NewReader(`{"lnk": {"/": "`+snds[0].Cid().String()+`"}}`), math.MaxUint64, -1) if err != nil { t.Error(err) } - if nd.Cid().String() != sub.Cid().String() { - t.Errorf("got unexpected cid %s, expected %s", nd.Cid().String(), sub.Cid().String()) + err = api.Dag().Add(ctx, nds[0]) + if err != nil { + t.Fatal(err) + } + + p, err := coreiface.ParsePath(path.Join(nds[0].Cid().String(), "lnk")) + if err != nil { + t.Error(err) + } + + rp, err := api.ResolvePath(ctx, p) + if err != nil { + t.Error(err) + } + + nd, err := api.Dag().Get(ctx, rp.Cid()) + if err != nil { + t.Error(err) + } + + if nd.Cid().String() != snds[0].Cid().String() { + t.Errorf("got unexpected cid %s, expected %s", nd.Cid().String(), snds[0].Cid().String()) } } @@ -114,12 +140,17 @@ func (tp *provider) TestTree(t *testing.T) { t.Error(err) } - c, err := api.Dag().Put(ctx, strings.NewReader(`{"a": 123, "b": "foo", "c": {"d": 321, "e": 111}}`)) + nds, err := coredag.ParseInputs("json", "dag-cbor", strings.NewReader(`{"a": 123, "b": "foo", "c": {"d": 321, "e": 111}}`), math.MaxUint64, -1) + if err != nil { + t.Error(err) + } + + err = api.Dag().Add(ctx, nds[0]) if err != nil { t.Fatal(err) } - res, err := api.Dag().Get(ctx, c) + res, err := api.Dag().Get(ctx, nds[0].Cid()) if err != nil { t.Error(err) } @@ -144,27 +175,25 @@ func (tp *provider) TestBatch(t *testing.T) { t.Error(err) } - batch := api.Dag().Batch(ctx) - - c, err := batch.Put(ctx, strings.NewReader(`"Hello"`)) + nds, err := coredag.ParseInputs("json", "dag-cbor", strings.NewReader(`"Hello"`), math.MaxUint64, -1) if err != nil { - t.Fatal(err) + t.Error(err) } - if c.Cid().String() != "zdpuAqckYF3ToF3gcJNxPZXmnmGuXd3gxHCXhq81HGxBejEvv" { - t.Errorf("got wrong cid: %s", c.Cid().String()) + if nds[0].Cid().String() != "zdpuAqckYF3ToF3gcJNxPZXmnmGuXd3gxHCXhq81HGxBejEvv" { + t.Errorf("got wrong cid: %s", nds[0].Cid().String()) } - _, err = api.Dag().Get(ctx, c) + _, err = api.Dag().Get(ctx, nds[0].Cid()) if err == nil || err.Error() != "merkledag: not found" { t.Error(err) } - if err := batch.Commit(ctx); err != nil { + if err := api.Dag().AddMany(ctx, nds); err != nil { t.Error(err) } - _, err = api.Dag().Get(ctx, c) + _, err = api.Dag().Get(ctx, nds[0].Cid()) if err != nil { t.Error(err) } diff --git a/core/coreiface/tests/path.go b/core/coreiface/tests/path.go index 50a1977d5..01f2e6f36 100644 --- a/core/coreiface/tests/path.go +++ b/core/coreiface/tests/path.go @@ -2,11 +2,13 @@ package tests import ( "context" + "math" "strings" "testing" coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface" "github.com/ipfs/go-ipfs/core/coreapi/interface/options" + "github.com/ipfs/go-ipfs/core/coredag" ) func (tp *provider) TestPath(t *testing.T) { @@ -62,12 +64,16 @@ func (tp *provider) TestPathRemainder(t *testing.T) { t.Fatal(".Dag not implemented") } - obj, err := api.Dag().Put(ctx, strings.NewReader(`{"foo": {"bar": "baz"}}`)) + nds, err := coredag.ParseInputs("json", "dag-cbor", strings.NewReader(`{"foo": {"bar": "baz"}}`), math.MaxUint64, -1) if err != nil { + t.Error(err) + } + + if err := api.Dag().AddMany(ctx, nds); err != nil { t.Fatal(err) } - p1, err := coreiface.ParsePath(obj.String() + "/foo/bar") + p1, err := coreiface.ParsePath(nds[0].String() + "/foo/bar") if err != nil { t.Error(err) } @@ -94,16 +100,16 @@ func (tp *provider) TestEmptyPathRemainder(t *testing.T) { t.Fatal(".Dag not implemented") } - obj, err := api.Dag().Put(ctx, strings.NewReader(`{"foo": {"bar": "baz"}}`)) + nds, err := coredag.ParseInputs("json", "dag-cbor", strings.NewReader(`{"foo": {"bar": "baz"}}`), math.MaxUint64, -1) if err != nil { + t.Error(err) + } + + if err := api.Dag().AddMany(ctx, nds); err != nil { t.Fatal(err) } - if obj.Remainder() != "" { - t.Error("expected the resolved path to not have a remainder") - } - - p1, err := coreiface.ParsePath(obj.String()) + p1, err := coreiface.ParsePath(nds[0].Cid().String()) if err != nil { t.Error(err) } @@ -130,12 +136,16 @@ func (tp *provider) TestInvalidPathRemainder(t *testing.T) { t.Fatal(".Dag not implemented") } - obj, err := api.Dag().Put(ctx, strings.NewReader(`{"foo": {"bar": "baz"}}`)) + nds, err := coredag.ParseInputs("json", "dag-cbor", strings.NewReader(`{"foo": {"bar": "baz"}}`), math.MaxUint64, -1) if err != nil { + t.Error(err) + } + + if err := api.Dag().AddMany(ctx, nds); err != nil { t.Fatal(err) } - p1, err := coreiface.ParsePath(obj.String() + "/bar/baz") + p1, err := coreiface.ParsePath("/ipld/" + nds[0].Cid().String() + "/bar/baz") if err != nil { t.Error(err) } @@ -167,12 +177,16 @@ func (tp *provider) TestPathRoot(t *testing.T) { t.Fatal(".Dag not implemented") } - obj, err := api.Dag().Put(ctx, strings.NewReader(`{"foo": {"/": "`+blk.Path().Cid().String()+`"}}`)) + nds, err := coredag.ParseInputs("json", "dag-cbor", strings.NewReader(`{"foo": {"/": "`+blk.Path().Cid().String()+`"}}`), math.MaxUint64, -1) if err != nil { + t.Error(err) + } + + if err := api.Dag().AddMany(ctx, nds); err != nil { t.Fatal(err) } - p1, err := coreiface.ParsePath(obj.String() + "/foo") + p1, err := coreiface.ParsePath("/ipld/" + nds[0].Cid().String() + "/foo") if err != nil { t.Error(err) } @@ -182,7 +196,7 @@ func (tp *provider) TestPathRoot(t *testing.T) { t.Fatal(err) } - if rp.Root().String() != obj.Cid().String() { + if rp.Root().String() != nds[0].Cid().String() { t.Error("unexpected path root") } diff --git a/core/coreiface/tests/pin.go b/core/coreiface/tests/pin.go index 87ad8a004..250799222 100644 --- a/core/coreiface/tests/pin.go +++ b/core/coreiface/tests/pin.go @@ -2,11 +2,13 @@ package tests import ( "context" - "github.com/ipfs/go-ipfs/core/coreapi/interface" + "math" "strings" "testing" + "github.com/ipfs/go-ipfs/core/coreapi/interface" opt "github.com/ipfs/go-ipfs/core/coreapi/interface/options" + "github.com/ipfs/go-ipfs/core/coredag" ) func (tp *provider) TestPin(t *testing.T) { @@ -109,22 +111,26 @@ func (tp *provider) TestPinRecursive(t *testing.T) { t.Error(err) } - p2, err := api.Dag().Put(ctx, strings.NewReader(`{"lnk": {"/": "`+p0.Cid().String()+`"}}`)) + nd2, err := coredag.ParseInputs("json", "dag-cbor", strings.NewReader(`{"lnk": {"/": "`+p0.Cid().String()+`"}}`), math.MaxUint64, -1) if err != nil { t.Error(err) } - p3, err := api.Dag().Put(ctx, strings.NewReader(`{"lnk": {"/": "`+p1.Cid().String()+`"}}`)) + nd3, err := coredag.ParseInputs("json", "dag-cbor", strings.NewReader(`{"lnk": {"/": "`+p1.Cid().String()+`"}}`), math.MaxUint64, -1) if err != nil { t.Error(err) } - err = api.Pin().Add(ctx, p2) + if err := api.Dag().AddMany(ctx, append(nd2, nd3...)); err != nil { + t.Fatal(err) + } + + err = api.Pin().Add(ctx, iface.IpldPath(nd2[0].Cid())) if err != nil { t.Error(err) } - err = api.Pin().Add(ctx, p3, opt.Pin.Recursive(false)) + err = api.Pin().Add(ctx, iface.IpldPath(nd3[0].Cid()), opt.Pin.Recursive(false)) if err != nil { t.Error(err) } @@ -147,8 +153,8 @@ func (tp *provider) TestPinRecursive(t *testing.T) { t.Errorf("unexpected pin list len: %d", len(list)) } - if list[0].Path().String() != p3.String() { - t.Error("unexpected path") + if list[0].Path().String() != iface.IpldPath(nd3[0].Cid()).String() { + t.Errorf("unexpected path, %s != %s", list[0].Path().String(), iface.IpfsPath(nd2[0].Cid()).String()) } list, err = api.Pin().Ls(ctx, opt.Pin.Type.Recursive()) @@ -160,8 +166,8 @@ func (tp *provider) TestPinRecursive(t *testing.T) { t.Errorf("unexpected pin list len: %d", len(list)) } - if list[0].Path().String() != p2.String() { - t.Error("unexpected path") + if list[0].Path().String() != iface.IpldPath(nd2[0].Cid()).String() { + t.Errorf("unexpected path, %s != %s", list[0].Path().String(), iface.IpldPath(nd3[0].Cid()).String()) } list, err = api.Pin().Ls(ctx, opt.Pin.Type.Indirect()) diff --git a/core/coreiface/tests/unixfs.go b/core/coreiface/tests/unixfs.go index e8a1aba32..fce41ae84 100644 --- a/core/coreiface/tests/unixfs.go +++ b/core/coreiface/tests/unixfs.go @@ -633,7 +633,7 @@ func (tp *provider) TestGetDir(t *testing.T) { t.Error(err) } edir := unixfs.EmptyDirNode() - _, err = api.Dag().Put(ctx, bytes.NewReader(edir.RawData()), options.Dag.Codec(cid.DagProtobuf), options.Dag.InputEnc("raw")) + err = api.Dag().Add(ctx, edir) if err != nil { t.Error(err) } @@ -667,7 +667,7 @@ func (tp *provider) TestGetNonUnixfs(t *testing.T) { } nd := new(mdag.ProtoNode) - _, err = api.Dag().Put(ctx, bytes.NewReader(nd.RawData()), options.Dag.Codec(nd.CidBuilder().GetCodec()), options.Dag.InputEnc("raw")) + err = api.Dag().Add(ctx, nd) if err != nil { t.Error(err) } @@ -801,7 +801,7 @@ func (tp *provider) TestLsNonUnixfs(t *testing.T) { t.Fatal(err) } - _, err = api.Dag().Put(ctx, bytes.NewReader(nd.RawData()), options.Dag.Codec(cid.DagCBOR), options.Dag.InputEnc("raw")) + err = api.Dag().Add(ctx, nd) if err != nil { t.Error(err) } From 266c2f92c50df9b50bbc5aa093c793bb5d1a2265 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 15 Jan 2019 14:33:03 +0100 Subject: [PATCH 0190/1212] Implement Key API This commit was moved from ipfs/go-ipfs-http-client@281b2bf65b19b17e4f0c047ac8f9901306bf171f --- client/httpapi/key.go | 57 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 46 insertions(+), 11 deletions(-) diff --git a/client/httpapi/key.go b/client/httpapi/key.go index 3653526eb..417415ddb 100644 --- a/client/httpapi/key.go +++ b/client/httpapi/key.go @@ -2,6 +2,7 @@ package httpapi import ( "context" + "errors" "github.com/ipfs/go-ipfs/core/coreapi/interface" caopts "github.com/ipfs/go-ipfs/core/coreapi/interface/options" @@ -49,18 +50,47 @@ func (api *KeyAPI) Generate(ctx context.Context, name string, opts ...caopts.Key if err != nil { return nil, err } - if err := out.valid(); err != nil { - return nil, err - } - return &out, nil + return &out, out.valid() } func (api *KeyAPI) Rename(ctx context.Context, oldName string, newName string, opts ...caopts.KeyRenameOption) (iface.Key, bool, error) { - panic("implement me") + options, err := caopts.KeyRenameOptions(opts...) + if err != nil { + return nil, false, err + } + + var out struct{ + Was string + Now string + Id string + Overwrite bool + } + err = api.core().request("key/rename", oldName, newName). + Option("force", options.Force). + Exec(ctx, &out) + if err != nil { + return nil, false, err + } + + id := &keyOutput{JName: out.Now, Id: out.Id} + return id, out.Overwrite, id.valid() } func (api *KeyAPI) List(ctx context.Context) ([]iface.Key, error) { - panic("implement me") + var out struct{ Keys []*keyOutput } + if err := api.core().request("key/list").Exec(ctx, &out); err != nil { + return nil, err + } + + res := make([]iface.Key, len(out.Keys)) + for i, k := range out.Keys { + if err := k.valid(); err != nil { + return nil, err + } + res[i] = k + } + + return res, nil } func (api *KeyAPI) Self(ctx context.Context) (iface.Key, error) { @@ -70,14 +100,19 @@ func (api *KeyAPI) Self(ctx context.Context) (iface.Key, error) { } out := keyOutput{JName: "self", Id: id.ID} - if err := out.valid(); err != nil { - return nil, err - } - return &out, nil + return &out, out.valid() } func (api *KeyAPI) Remove(ctx context.Context, name string) (iface.Key, error) { - panic("implement me") + var out struct{ Keys []keyOutput } + if err := api.core().request("key/rm", name).Exec(ctx, &out); err != nil { + return nil, err + } + if len(out.Keys) != 1 { + return nil, errors.New("got unexpected number of keys back") + } + + return &out.Keys[0], out.Keys[0].valid() } func (api *KeyAPI) core() *HttpApi { From 9d647d011efa551bae28c50cafb402a35d33b04a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 15 Jan 2019 15:02:15 +0100 Subject: [PATCH 0191/1212] Implement Pin API This commit was moved from ipfs/go-ipfs-http-client@5bb7a581323aad4dd765a0916f6552cd5902d1e2 --- client/httpapi/pin.go | 92 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 87 insertions(+), 5 deletions(-) diff --git a/client/httpapi/pin.go b/client/httpapi/pin.go index ea34dc540..34cafad71 100644 --- a/client/httpapi/pin.go +++ b/client/httpapi/pin.go @@ -2,7 +2,9 @@ package httpapi import ( "context" + "encoding/json" "github.com/ipfs/go-cid" + "github.com/pkg/errors" "github.com/ipfs/go-ipfs/core/coreapi/interface" caopts "github.com/ipfs/go-ipfs/core/coreapi/interface/options" @@ -31,8 +33,14 @@ func (p *pin) Type() string { return p.typ } -func (api *PinAPI) Add(context.Context, iface.Path, ...caopts.PinAddOption) error { - panic("implement me") +func (api *PinAPI) Add(ctx context.Context, p iface.Path, opts ...caopts.PinAddOption) error { + options, err := caopts.PinAddOptions(opts...) + if err != nil { + return err + } + + return api.core().request("pin/add", p.String()). + Option("recursive", options.Recursive).Exec(ctx, nil) } func (api *PinAPI) Ls(ctx context.Context, opts ...caopts.PinLsOption) ([]iface.Pin, error) { @@ -65,11 +73,85 @@ func (api *PinAPI) Rm(ctx context.Context, p iface.Path) error { } func (api *PinAPI) Update(ctx context.Context, from iface.Path, to iface.Path, opts ...caopts.PinUpdateOption) error { - panic("implement me") + options, err := caopts.PinUpdateOptions(opts...) + if err != nil { + return err + } + + return api.core().request("pin/update"). + Option("unpin", options.Unpin).Exec(ctx, nil) } -func (api *PinAPI) Verify(context.Context) (<-chan iface.PinStatus, error) { - panic("implement me") +type pinVerifyRes struct { + Cid string + JOk bool `json:"Ok"` + JBadNodes []*badNode `json:"BadNodes,omitempty"` +} + +func (r *pinVerifyRes) Ok() bool { + return r.JOk +} + +func (r *pinVerifyRes) BadNodes() []iface.BadPinNode { + out := make([]iface.BadPinNode, len(r.JBadNodes)) + for i, n := range r.JBadNodes { + out[i] = n + } + return out +} + +type badNode struct { + Cid string + JErr string `json:"Err"` +} + +func (n *badNode) Path() iface.ResolvedPath { + c, err := cid.Parse(n.Cid) + if err != nil { + return nil // todo: handle this better + } + return iface.IpldPath(c) +} + +func (n *badNode) Err() error { + if n.JErr != "" { + return errors.New(n.JErr) + } + if _, err := cid.Parse(n.Cid); err != nil { + return err + } + return nil +} + +func (api *PinAPI) Verify(ctx context.Context) (<-chan iface.PinStatus, error) { + resp, err := api.core().request("pin/verify").Option("verbose", true).Send(ctx) + if err != nil { + return nil, err + } + if resp.Error != nil { + return nil, resp.Error + } + res := make(chan iface.PinStatus) + + go func() { + defer resp.Close() + defer close(res) + dec := json.NewDecoder(resp.Output) + for { + var out pinVerifyRes + if err := dec.Decode(&out); err != nil { + return // todo: handle non io.EOF somehow + } + + select { + case res <- &out: + case <-ctx.Done(): + return + } + } + }() + + return res, nil } func (api *PinAPI) core() *HttpApi { From eaa19388d4d86eebf09d93a3a637e0690df722bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 15 Jan 2019 16:31:07 +0100 Subject: [PATCH 0192/1212] Implement Object API This commit was moved from ipfs/go-ipfs-http-client@38149e46c8c3a1544dc3e3108ef72ffbc885e410 --- client/httpapi/block.go | 2 +- client/httpapi/ipldnode.go | 7 +- client/httpapi/key.go | 8 +- client/httpapi/object.go | 216 +++++++++++++++++++++++++++++++++---- client/httpapi/pin.go | 6 +- 5 files changed, 208 insertions(+), 31 deletions(-) diff --git a/client/httpapi/block.go b/client/httpapi/block.go index f933d3c4a..f8334a109 100644 --- a/client/httpapi/block.go +++ b/client/httpapi/block.go @@ -67,7 +67,7 @@ func (api *BlockAPI) Put(ctx context.Context, r io.Reader, opts ...caopts.BlockP } func (api *BlockAPI) Get(ctx context.Context, p iface.Path) (io.Reader, error) { - resp, err := api.core().request("block/get", p.String()).Send(context.Background()) + resp, err := api.core().request("block/get", p.String()).Send(ctx) if err != nil { return nil, err } diff --git a/client/httpapi/ipldnode.go b/client/httpapi/ipldnode.go index 8e028e1a7..2294a95b4 100644 --- a/client/httpapi/ipldnode.go +++ b/client/httpapi/ipldnode.go @@ -3,7 +3,6 @@ package httpapi import ( "context" "errors" - "fmt" "io/ioutil" "strconv" @@ -20,11 +19,11 @@ type ipldNode struct { api *HttpApi } -func (a *HttpApi) nodeFromPath(ctx context.Context, p iface.ResolvedPath) ipld.Node { +func (api *HttpApi) nodeFromPath(ctx context.Context, p iface.ResolvedPath) ipld.Node { return &ipldNode{ ctx: ctx, path: p, - api: a, + api: api, } } @@ -47,7 +46,7 @@ func (n *ipldNode) Cid() cid.Cid { } func (n *ipldNode) String() string { - return fmt.Sprintf("[Block %s]", n.Cid()) + return n.Cid().String() } func (n *ipldNode) Loggable() map[string]interface{} { diff --git a/client/httpapi/key.go b/client/httpapi/key.go index 417415ddb..5087b6d99 100644 --- a/client/httpapi/key.go +++ b/client/httpapi/key.go @@ -59,10 +59,10 @@ func (api *KeyAPI) Rename(ctx context.Context, oldName string, newName string, o return nil, false, err } - var out struct{ - Was string - Now string - Id string + var out struct { + Was string + Now string + Id string Overwrite bool } err = api.core().request("key/rename", oldName, newName). diff --git a/client/httpapi/object.go b/client/httpapi/object.go index 6259473c7..4bc787991 100644 --- a/client/httpapi/object.go +++ b/client/httpapi/object.go @@ -1,14 +1,17 @@ package httpapi import ( + "bytes" "context" - "github.com/ipfs/go-cid" "io" + "io/ioutil" "github.com/ipfs/go-ipfs/core/coreapi/interface" caopts "github.com/ipfs/go-ipfs/core/coreapi/interface/options" + "github.com/ipfs/go-cid" "github.com/ipfs/go-ipld-format" + "github.com/ipfs/go-merkledag" ) type ObjectAPI HttpApi @@ -37,44 +40,219 @@ func (api *ObjectAPI) New(ctx context.Context, opts ...caopts.ObjectNewOption) ( return api.core().nodeFromPath(ctx, iface.IpfsPath(c)), nil } -func (api *ObjectAPI) Put(context.Context, io.Reader, ...caopts.ObjectPutOption) (iface.ResolvedPath, error) { - panic("implement me") +func (api *ObjectAPI) Put(ctx context.Context, r io.Reader, opts ...caopts.ObjectPutOption) (iface.ResolvedPath, error) { + options, err := caopts.ObjectPutOptions(opts...) + if err != nil { + return nil, err + } + + var out objectOut + err = api.core().request("object/put"). + Option("inputenc", options.InputEnc). + Option("datafieldenc", options.DataType). + Option("pin", options.Pin). + FileBody(r). + Exec(ctx, &out) + if err != nil { + return nil, err + } + + c, err := cid.Parse(out.Hash) + if err != nil { + return nil, err + } + + return iface.IpfsPath(c), nil } -func (api *ObjectAPI) Get(context.Context, iface.Path) (format.Node, error) { - panic("implement me") +func (api *ObjectAPI) Get(ctx context.Context, p iface.Path) (format.Node, error) { + r, err := api.core().Block().Get(ctx, p) + if err != nil { + return nil, err + } + b, err := ioutil.ReadAll(r) + if err != nil { + return nil, err + } + + return merkledag.DecodeProtobuf(b) } -func (api *ObjectAPI) Data(context.Context, iface.Path) (io.Reader, error) { - panic("implement me") +func (api *ObjectAPI) Data(ctx context.Context, p iface.Path) (io.Reader, error) { + resp, err := api.core().request("object/data", p.String()).Send(ctx) + if err != nil { + return nil, err + } + if resp.Error != nil { + return nil, resp.Error + } + + //TODO: make Data return ReadCloser to avoid copying + defer resp.Close() + b := new(bytes.Buffer) + if _, err := io.Copy(b, resp.Output); err != nil { + return nil, err + } + + return b, nil } -func (api *ObjectAPI) Links(context.Context, iface.Path) ([]*format.Link, error) { - panic("implement me") +func (api *ObjectAPI) Links(ctx context.Context, p iface.Path) ([]*format.Link, error) { + var out struct { + Links []struct { + Name string + Hash string + Size uint64 + } + } + if err := api.core().request("object/links", p.String()).Exec(ctx, &out); err != nil { + return nil, err + } + res := make([]*format.Link, len(out.Links)) + for i, l := range out.Links { + c, err := cid.Parse(l.Hash) + if err != nil { + return nil, err + } + + res[i] = &format.Link{ + Cid: c, + Name: l.Name, + Size: l.Size, + } + } + + return res, nil } -func (api *ObjectAPI) Stat(context.Context, iface.Path) (*iface.ObjectStat, error) { - panic("implement me") +func (api *ObjectAPI) Stat(ctx context.Context, p iface.Path) (*iface.ObjectStat, error) { + var out struct { + Hash string + NumLinks int + BlockSize int + LinksSize int + DataSize int + CumulativeSize int + } + if err := api.core().request("object/stat", p.String()).Exec(ctx, &out); err != nil { + return nil, err + } + + c, err := cid.Parse(out.Hash) + if err != nil { + return nil, err + } + + return &iface.ObjectStat{ + Cid: c, + NumLinks: out.NumLinks, + BlockSize: out.BlockSize, + LinksSize: out.LinksSize, + DataSize: out.DataSize, + CumulativeSize: out.CumulativeSize, + }, nil } func (api *ObjectAPI) AddLink(ctx context.Context, base iface.Path, name string, child iface.Path, opts ...caopts.ObjectAddLinkOption) (iface.ResolvedPath, error) { - panic("implement me") + options, err := caopts.ObjectAddLinkOptions(opts...) + if err != nil { + return nil, err + } + + var out objectOut + err = api.core().request("object/patch/add-link", base.String(), name, child.String()). + Option("create", options.Create). + Exec(ctx, &out) + if err != nil { + return nil, err + } + + c, err := cid.Parse(out.Hash) + if err != nil { + return nil, err + } + + return iface.IpfsPath(c), nil } func (api *ObjectAPI) RmLink(ctx context.Context, base iface.Path, link string) (iface.ResolvedPath, error) { - panic("implement me") + var out objectOut + err := api.core().request("object/patch/rm-link", base.String(), link). + Exec(ctx, &out) + if err != nil { + return nil, err + } + + c, err := cid.Parse(out.Hash) + if err != nil { + return nil, err + } + + return iface.IpfsPath(c), nil } -func (api *ObjectAPI) AppendData(context.Context, iface.Path, io.Reader) (iface.ResolvedPath, error) { - panic("implement me") +func (api *ObjectAPI) AppendData(ctx context.Context, p iface.Path, r io.Reader) (iface.ResolvedPath, error) { + var out objectOut + err := api.core().request("object/patch/append-data", p.String()). + FileBody(r). + Exec(ctx, &out) + if err != nil { + return nil, err + } + + c, err := cid.Parse(out.Hash) + if err != nil { + return nil, err + } + + return iface.IpfsPath(c), nil } -func (api *ObjectAPI) SetData(context.Context, iface.Path, io.Reader) (iface.ResolvedPath, error) { - panic("implement me") +func (api *ObjectAPI) SetData(ctx context.Context, p iface.Path, r io.Reader) (iface.ResolvedPath, error) { + var out objectOut + err := api.core().request("object/patch/set-data", p.String()). + FileBody(r). + Exec(ctx, &out) + if err != nil { + return nil, err + } + + c, err := cid.Parse(out.Hash) + if err != nil { + return nil, err + } + + return iface.IpfsPath(c), nil } -func (api *ObjectAPI) Diff(context.Context, iface.Path, iface.Path) ([]iface.ObjectChange, error) { - panic("implement me") +type change struct { + Type iface.ChangeType + Path string + Before cid.Cid + After cid.Cid +} + +func (api *ObjectAPI) Diff(ctx context.Context, a iface.Path, b iface.Path) ([]iface.ObjectChange, error) { + var out struct { + Changes []change + } + if err := api.core().request("object/diff", a.String(), b.String()).Exec(ctx, &out); err != nil { + return nil, err + } + res := make([]iface.ObjectChange, len(out.Changes)) + for i, ch := range out.Changes { + res[i] = iface.ObjectChange{ + Type: ch.Type, + Path: ch.Path, + } + if ch.Before != cid.Undef { + res[i].Before = iface.IpfsPath(ch.Before) + } + if ch.After != cid.Undef { + res[i].After = iface.IpfsPath(ch.After) + } + } + return res, nil } func (api *ObjectAPI) core() *HttpApi { diff --git a/client/httpapi/pin.go b/client/httpapi/pin.go index 34cafad71..1624b7867 100644 --- a/client/httpapi/pin.go +++ b/client/httpapi/pin.go @@ -83,8 +83,8 @@ func (api *PinAPI) Update(ctx context.Context, from iface.Path, to iface.Path, o } type pinVerifyRes struct { - Cid string - JOk bool `json:"Ok"` + Cid string + JOk bool `json:"Ok"` JBadNodes []*badNode `json:"BadNodes,omitempty"` } @@ -101,7 +101,7 @@ func (r *pinVerifyRes) BadNodes() []iface.BadPinNode { } type badNode struct { - Cid string + Cid string JErr string `json:"Err"` } From ed9f2dd091693e914e9de072b2c23c2f991210a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 15 Jan 2019 17:01:33 +0100 Subject: [PATCH 0193/1212] Implement DHT Api This commit was moved from ipfs/go-ipfs-http-client@c77355067a22300a8abe6b93b354de0ae0a3b548 --- client/httpapi/api.go | 2 +- client/httpapi/dht.go | 98 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 client/httpapi/dht.go diff --git a/client/httpapi/api.go b/client/httpapi/api.go index c686a8d0d..208b958e9 100644 --- a/client/httpapi/api.go +++ b/client/httpapi/api.go @@ -158,7 +158,7 @@ func (api *HttpApi) Object() iface.ObjectAPI { } func (api *HttpApi) Dht() iface.DhtAPI { - return nil + return (*DhtAPI)(api) } func (api *HttpApi) Swarm() iface.SwarmAPI { diff --git a/client/httpapi/dht.go b/client/httpapi/dht.go new file mode 100644 index 000000000..17d3b0500 --- /dev/null +++ b/client/httpapi/dht.go @@ -0,0 +1,98 @@ +package httpapi + +import ( + "context" + "encoding/json" + "github.com/ipfs/go-ipfs/core/coreapi/interface" + caopts "github.com/ipfs/go-ipfs/core/coreapi/interface/options" + + "github.com/libp2p/go-libp2p-peer" + "github.com/libp2p/go-libp2p-peerstore" + notif "github.com/libp2p/go-libp2p-routing/notifications" +) + +type DhtAPI HttpApi + +func (api *DhtAPI) FindPeer(ctx context.Context, p peer.ID) (peerstore.PeerInfo, error) { + var out struct { + Type notif.QueryEventType + Responses []peerstore.PeerInfo + } + resp, err := api.core().request("dht/findpeer", p.Pretty()).Send(ctx) + if err != nil { + return peerstore.PeerInfo{}, err + } + if resp.Error != nil { + return peerstore.PeerInfo{}, resp.Error + } + defer resp.Close() + dec := json.NewDecoder(resp.Output) + for { + if err := dec.Decode(&out); err != nil { + return peerstore.PeerInfo{}, err + } + if out.Type == notif.FinalPeer { + return out.Responses[0], nil + } + } +} + +func (api *DhtAPI) FindProviders(ctx context.Context, p iface.Path, opts ...caopts.DhtFindProvidersOption) (<-chan peerstore.PeerInfo, error) { + options, err := caopts.DhtFindProvidersOptions(opts...) + if err != nil { + return nil, err + } + resp, err := api.core().request("dht/findprovs", p.String()). + Option("num-providers", options.NumProviders). + Send(ctx) + if err != nil { + return nil, err + } + if resp.Error != nil { + return nil, resp.Error + } + res := make(chan peerstore.PeerInfo) + + go func() { + defer resp.Close() + defer close(res) + dec := json.NewDecoder(resp.Output) + + for { + var out struct { + Type notif.QueryEventType + Responses []peerstore.PeerInfo + } + + if err := dec.Decode(&out); err != nil { + return // todo: handle this somehow + } + if out.Type == notif.Provider { + for _, pi := range out.Responses { + select { + case res <- pi: + case <-ctx.Done(): + return + } + } + } + } + }() + + return res, nil +} + +func (api *DhtAPI) Provide(ctx context.Context, p iface.Path, opts ...caopts.DhtProvideOption) error { + options, err := caopts.DhtProvideOptions(opts...) + if err != nil { + return err + } + + return api.core().request("dht/provide", p.String()). + Option("recursive", options.Recursive). + Exec(ctx, nil) +} + +func (api *DhtAPI) core() *HttpApi { + return (*HttpApi)(api) +} From cae0ff2379f29a205426f7a8199c398885f33897 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 15 Jan 2019 17:36:35 +0100 Subject: [PATCH 0194/1212] Implement Swarm Api This commit was moved from ipfs/go-ipfs-http-client@01105690d2da6e3f3581fa364c6284248a251a35 --- client/httpapi/api.go | 2 +- client/httpapi/swarm.go | 176 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 177 insertions(+), 1 deletion(-) create mode 100644 client/httpapi/swarm.go diff --git a/client/httpapi/api.go b/client/httpapi/api.go index 208b958e9..a5b56eff6 100644 --- a/client/httpapi/api.go +++ b/client/httpapi/api.go @@ -162,7 +162,7 @@ func (api *HttpApi) Dht() iface.DhtAPI { } func (api *HttpApi) Swarm() iface.SwarmAPI { - return nil + return (*SwarmAPI)(api) } func (api *HttpApi) PubSub() iface.PubSubAPI { diff --git a/client/httpapi/swarm.go b/client/httpapi/swarm.go new file mode 100644 index 000000000..cf0ee2a9b --- /dev/null +++ b/client/httpapi/swarm.go @@ -0,0 +1,176 @@ +package httpapi + +import ( + "context" + "github.com/libp2p/go-libp2p-protocol" + "time" + + "github.com/ipfs/go-ipfs/core/coreapi/interface" + + inet "github.com/libp2p/go-libp2p-net" + "github.com/libp2p/go-libp2p-peer" + "github.com/libp2p/go-libp2p-peerstore" + "github.com/multiformats/go-multiaddr" +) + +type SwarmAPI HttpApi + +func (api *SwarmAPI) Connect(ctx context.Context, pi peerstore.PeerInfo) error { + saddrs := make([]string, len(pi.Addrs)) + for i, addr := range pi.Addrs { + saddrs[i] = addr.String() + } + + return api.core().request("swarm/connect", saddrs...).Exec(ctx, nil) +} + +func (api *SwarmAPI) Disconnect(ctx context.Context, addr multiaddr.Multiaddr) error { + return api.core().request("swarm/disconnect", addr.String()).Exec(ctx, nil) +} + +type streamInfo struct { + Protocol string +} + +type connInfo struct { + Addr string + Peer string + JLatency time.Duration `json:"Latency"` + Muxer string + JDirection inet.Direction `json:"Direction"` + JStreams []streamInfo `json:"Streams"` +} + +func (c *connInfo) valid() error { + _, err := multiaddr.NewMultiaddr(c.Addr) + if err != nil { + return err + } + + _, err = peer.IDB58Decode(c.Peer) + return err +} + +func (c *connInfo) ID() peer.ID { + id, _ := peer.IDB58Decode(c.Peer) + return id +} + +func (c *connInfo) Address() multiaddr.Multiaddr { + a, _ := multiaddr.NewMultiaddr(c.Addr) + return a +} + +func (c *connInfo) Direction() inet.Direction { + return c.JDirection +} + +func (c *connInfo) Latency() (time.Duration, error) { + return c.JLatency, nil +} + +func (c *connInfo) Streams() ([]protocol.ID, error) { + res := make([]protocol.ID, len(c.JStreams)) + for i, stream := range c.JStreams { + res[i] = protocol.ID(stream.Protocol) + } + return res, nil +} + +func (api *SwarmAPI) Peers(ctx context.Context) ([]iface.ConnectionInfo, error) { + var out struct { + Peers []*connInfo + } + + err := api.core().request("swarm/peers"). + Option("streams", true). + Option("latency", true). + Exec(ctx, &out) + if err != nil { + return nil, err + } + + res := make([]iface.ConnectionInfo, len(out.Peers)) + for i, conn := range out.Peers { + if err := conn.valid(); err != nil { + return nil, err + } + res[i] = conn + } + + return res, nil +} + +func (api *SwarmAPI) KnownAddrs(ctx context.Context) (map[peer.ID][]multiaddr.Multiaddr, error) { + var out struct { + Addrs map[string][]string + } + if err := api.core().request("swarm/addrs").Exec(ctx, &out); err != nil { + return nil, err + } + res := map[peer.ID][]multiaddr.Multiaddr{} + for spid, saddrs := range out.Addrs { + addrs := make([]multiaddr.Multiaddr, len(saddrs)) + + for i, addr := range saddrs { + a, err := multiaddr.NewMultiaddr(addr) + if err != nil { + return nil, err + } + addrs[i] = a + } + + pid, err := peer.IDB58Decode(spid) + if err != nil { + return nil, err + } + + res[pid] = addrs + } + + return res, nil +} + +func (api *SwarmAPI) LocalAddrs(ctx context.Context) ([]multiaddr.Multiaddr, error) { + var out struct { + Strings []string + } + + if err := api.core().request("swarm/addrs/local").Exec(ctx, &out); err != nil { + return nil, err + } + + res := make([]multiaddr.Multiaddr, len(out.Strings)) + for i, addr := range out.Strings { + ma, err := multiaddr.NewMultiaddr(addr) + if err != nil { + return nil, err + } + res[i] = ma + } + return res, nil +} + +func (api *SwarmAPI) ListenAddrs(ctx context.Context) ([]multiaddr.Multiaddr, error) { + var out struct { + Strings []string + } + + if err := api.core().request("swarm/addrs/listen").Exec(ctx, &out); err != nil { + return nil, err + } + + res := make([]multiaddr.Multiaddr, len(out.Strings)) + for i, addr := range out.Strings { + ma, err := multiaddr.NewMultiaddr(addr) + if err != nil { + return nil, err + } + res[i] = ma + } + return res, nil +} + +func (api *SwarmAPI) core() *HttpApi { + return (*HttpApi)(api) +} From c2e0872f6dfba6f6d3f74a4b9eb755053a3f483e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 15 Jan 2019 18:19:50 +0100 Subject: [PATCH 0195/1212] Implement PubSub Api This commit was moved from ipfs/go-ipfs-http-client@7abddda1d33595dffb0e0da782b52660147f6855 --- client/httpapi/api.go | 2 +- client/httpapi/api_test.go | 2 +- client/httpapi/pubsub.go | 129 +++++++++++++++++++++++++++++++++++++ 3 files changed, 131 insertions(+), 2 deletions(-) create mode 100644 client/httpapi/pubsub.go diff --git a/client/httpapi/api.go b/client/httpapi/api.go index a5b56eff6..3a8e0e003 100644 --- a/client/httpapi/api.go +++ b/client/httpapi/api.go @@ -166,5 +166,5 @@ func (api *HttpApi) Swarm() iface.SwarmAPI { } func (api *HttpApi) PubSub() iface.PubSubAPI { - return nil + return (*PubsubAPI)(api) } diff --git a/client/httpapi/api_test.go b/client/httpapi/api_test.go index b822378f7..1acece88c 100644 --- a/client/httpapi/api_test.go +++ b/client/httpapi/api_test.go @@ -47,7 +47,7 @@ func (NodeProvider) MakeAPISwarm(ctx context.Context, fullIdentity bool, n int) return nil, err } - startArgs := []string{"iptb", "--IPTB_ROOT", dir, "start", "-wait", "--", "--offline=" + strconv.FormatBool(n == 1)} + startArgs := []string{"iptb", "--IPTB_ROOT", dir, "start", "-wait", "--", "--enable-pubsub-experiment", "--offline=" + strconv.FormatBool(n == 1)} if err := c.Run(startArgs); err != nil { return nil, err } diff --git a/client/httpapi/pubsub.go b/client/httpapi/pubsub.go new file mode 100644 index 000000000..3c5e3c50d --- /dev/null +++ b/client/httpapi/pubsub.go @@ -0,0 +1,129 @@ +package httpapi + +import ( + "bytes" + "context" + "encoding/json" + "io" + + "github.com/ipfs/go-ipfs/core/coreapi/interface" + caopts "github.com/ipfs/go-ipfs/core/coreapi/interface/options" + + "github.com/libp2p/go-libp2p-peer" +) + +type PubsubAPI HttpApi + +func (api *PubsubAPI) Ls(ctx context.Context) ([]string, error) { + var out struct { + Strings []string + } + + if err := api.core().request("pubsub/ls").Exec(ctx, &out); err != nil { + return nil, err + } + + return out.Strings, nil +} + +func (api *PubsubAPI) Peers(ctx context.Context, opts ...caopts.PubSubPeersOption) ([]peer.ID, error) { + options, err := caopts.PubSubPeersOptions(opts...) + if err != nil { + return nil, err + } + + var out struct { + Strings []string + } + + if err := api.core().request("pubsub/peers", options.Topic).Exec(ctx, &out); err != nil { + return nil, err + } + + res := make([]peer.ID, len(out.Strings)) + for i, sid := range out.Strings { + id, err := peer.IDB58Decode(sid) + if err != nil { + return nil, err + } + res[i] = id + } + return res, nil +} + +func (api *PubsubAPI) Publish(ctx context.Context, topic string, message []byte) error { + return api.core().request("pubsub/pub", topic). + FileBody(bytes.NewReader(message)). + Exec(ctx, nil) +} + +type pubsubSub struct { + io.Closer + dec *json.Decoder +} + +type pubsubMessage struct { + JFrom []byte `json:"from,omitempty"` + JData []byte `json:"data,omitempty"` + JSeqno []byte `json:"seqno,omitempty"` + JTopicIDs []string `json:"topicIDs,omitempty"` +} + +func (msg *pubsubMessage) valid() error { + _, err := peer.IDFromBytes(msg.JFrom) + return err +} + +func (msg *pubsubMessage) From() peer.ID { + id, _ := peer.IDFromBytes(msg.JFrom) + return id +} + +func (msg *pubsubMessage) Data() []byte { + return msg.JData +} + +func (msg *pubsubMessage) Seq() []byte { + return msg.JSeqno +} + +func (msg *pubsubMessage) Topics() []string { + return msg.JTopicIDs +} + +func (s *pubsubSub) Next(ctx context.Context) (iface.PubSubMessage, error) { + // TODO: handle ctx + + var msg pubsubMessage + if err := s.dec.Decode(&msg); err != nil { + return nil, err + } + return &msg, msg.valid() +} + +func (api *PubsubAPI) Subscribe(ctx context.Context, topic string, opts ...caopts.PubSubSubscribeOption) (iface.PubSubSubscription, error) { + options, err := caopts.PubSubSubscribeOptions(opts...) + if err != nil { + return nil, err + } + + resp, err := api.core().request("pubsub/sub", topic). + Option("discover", options.Discover). + Send(ctx) + if err != nil { + return nil, err + } + if resp.Error != nil { + return nil, resp.Error + } + + return &pubsubSub{ + Closer: resp, + dec: json.NewDecoder(resp.Output), + }, nil +} + +func (api *PubsubAPI) core() *HttpApi { + return (*HttpApi)(api) +} + From 9b24cf0aafa94a7b4cb4401b6fbb9c959bde09b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 15 Jan 2019 18:49:11 +0100 Subject: [PATCH 0196/1212] Use cids in DHT calls This commit was moved from ipfs/go-ipfs-http-client@163b25f8b88eb98ddae50978440e3940070fabc0 --- client/httpapi/dht.go | 20 ++++++++++++++++++-- client/httpapi/pubsub.go | 3 +-- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/client/httpapi/dht.go b/client/httpapi/dht.go index 17d3b0500..8fedabbf8 100644 --- a/client/httpapi/dht.go +++ b/client/httpapi/dht.go @@ -42,7 +42,13 @@ func (api *DhtAPI) FindProviders(ctx context.Context, p iface.Path, opts ...caop if err != nil { return nil, err } - resp, err := api.core().request("dht/findprovs", p.String()). + + rp, err := api.core().ResolvePath(ctx, p) + if err != nil { + return nil, err + } + + resp, err := api.core().request("dht/findprovs", rp.Cid().String()). Option("num-providers", options.NumProviders). Send(ctx) if err != nil { @@ -60,6 +66,7 @@ func (api *DhtAPI) FindProviders(ctx context.Context, p iface.Path, opts ...caop for { var out struct { + Extra string Type notif.QueryEventType Responses []peerstore.PeerInfo } @@ -67,6 +74,10 @@ func (api *DhtAPI) FindProviders(ctx context.Context, p iface.Path, opts ...caop if err := dec.Decode(&out); err != nil { return // todo: handle this somehow } + if out.Type == notif.QueryError { + return // usually a 'not found' error + // todo: handle other errors + } if out.Type == notif.Provider { for _, pi := range out.Responses { select { @@ -88,7 +99,12 @@ func (api *DhtAPI) Provide(ctx context.Context, p iface.Path, opts ...caopts.Dht return err } - return api.core().request("dht/provide", p.String()). + rp, err := api.core().ResolvePath(ctx, p) + if err != nil { + return err + } + + return api.core().request("dht/provide", rp.Cid().String()). Option("recursive", options.Recursive). Exec(ctx, nil) } diff --git a/client/httpapi/pubsub.go b/client/httpapi/pubsub.go index 3c5e3c50d..fb9bb7460 100644 --- a/client/httpapi/pubsub.go +++ b/client/httpapi/pubsub.go @@ -119,11 +119,10 @@ func (api *PubsubAPI) Subscribe(ctx context.Context, topic string, opts ...caopt return &pubsubSub{ Closer: resp, - dec: json.NewDecoder(resp.Output), + dec: json.NewDecoder(resp.Output), }, nil } func (api *PubsubAPI) core() *HttpApi { return (*HttpApi)(api) } - From c1541fd86aa57b888199ad17018a99365ecd5af9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 15 Jan 2019 18:51:29 +0100 Subject: [PATCH 0197/1212] coreapi: adjust some tests for go-ipfs-http-api MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@fb15570caa8ff7cb9defce24198738273b23aa16 This commit was moved from ipfs/boxo@6d44270b3a49474f67a51f0fcddfbf40766363be --- core/coreiface/tests/block.go | 4 ++-- core/coreiface/tests/dht.go | 20 ++++++++++++++++++-- core/coreiface/tests/key.go | 16 ++++++++-------- core/coreiface/tests/object.go | 2 +- 4 files changed, 29 insertions(+), 13 deletions(-) diff --git a/core/coreiface/tests/block.go b/core/coreiface/tests/block.go index 81a6fb061..427ad3357 100644 --- a/core/coreiface/tests/block.go +++ b/core/coreiface/tests/block.go @@ -159,7 +159,7 @@ func (tp *provider) TestBlockRm(t *testing.T) { if err == nil { t.Error("expected err to exist") } - if err.Error() != "blockservice: key not found" { + if !strings.Contains(err.Error(), "blockservice: key not found") { t.Errorf("unexpected error; %s", err.Error()) } @@ -167,7 +167,7 @@ func (tp *provider) TestBlockRm(t *testing.T) { if err == nil { t.Error("expected err to exist") } - if err.Error() != "blockstore: block not found" { + if !strings.Contains(err.Error(), "blockstore: block not found") { t.Errorf("unexpected error; %s", err.Error()) } diff --git a/core/coreiface/tests/dht.go b/core/coreiface/tests/dht.go index 3ec77d33b..d2eae1af4 100644 --- a/core/coreiface/tests/dht.go +++ b/core/coreiface/tests/dht.go @@ -35,12 +35,20 @@ func (tp *provider) TestDhtFindPeer(t *testing.T) { t.Fatal(err) } + laddrs0, err := apis[0].Swarm().LocalAddrs(ctx) + if err != nil { + t.Fatal(err) + } + if len(laddrs0) != 1 { + t.Fatal("unexpected number of local addrs") + } + pi, err := apis[2].Dht().FindPeer(ctx, self0.ID()) if err != nil { t.Fatal(err) } - if pi.Addrs[0].String() != "/ip4/127.0.0.1/tcp/4001" { + if pi.Addrs[0].String() != laddrs0[0].String() { t.Errorf("got unexpected address from FindPeer: %s", pi.Addrs[0].String()) } @@ -54,7 +62,15 @@ func (tp *provider) TestDhtFindPeer(t *testing.T) { t.Fatal(err) } - if pi.Addrs[0].String() != "/ip4/127.0.2.1/tcp/4001" { + laddrs2, err := apis[2].Swarm().LocalAddrs(ctx) + if err != nil { + t.Fatal(err) + } + if len(laddrs2) != 1 { + t.Fatal("unexpected number of local addrs") + } + + if pi.Addrs[0].String() != laddrs2[0].String() { t.Errorf("got unexpected address from FindPeer: %s", pi.Addrs[0].String()) } } diff --git a/core/coreiface/tests/key.go b/core/coreiface/tests/key.go index 8dd6af57f..66011f99f 100644 --- a/core/coreiface/tests/key.go +++ b/core/coreiface/tests/key.go @@ -82,7 +82,7 @@ func (tp *provider) TestRenameSelf(t *testing.T) { if err == nil { t.Error("expected error to not be nil") } else { - if err.Error() != "cannot rename key with name 'self'" { + if !strings.Contains(err.Error(), "cannot rename key with name 'self'") { t.Fatalf("expected error 'cannot rename key with name 'self'', got '%s'", err.Error()) } } @@ -91,7 +91,7 @@ func (tp *provider) TestRenameSelf(t *testing.T) { if err == nil { t.Error("expected error to not be nil") } else { - if err.Error() != "cannot rename key with name 'self'" { + if !strings.Contains(err.Error(), "cannot rename key with name 'self'") { t.Fatalf("expected error 'cannot rename key with name 'self'', got '%s'", err.Error()) } } @@ -110,7 +110,7 @@ func (tp *provider) TestRemoveSelf(t *testing.T) { if err == nil { t.Error("expected error to not be nil") } else { - if err.Error() != "cannot remove key with name 'self'" { + if !strings.Contains(err.Error(), "cannot remove key with name 'self'") { t.Fatalf("expected error 'cannot remove key with name 'self'', got '%s'", err.Error()) } } @@ -206,7 +206,7 @@ func (tp *provider) TestGenerateExisting(t *testing.T) { if err == nil { t.Error("expected error to not be nil") } else { - if err.Error() != "key with name 'foo' already exists" { + if !strings.Contains(err.Error(), "key with name 'foo' already exists") { t.Fatalf("expected error 'key with name 'foo' already exists', got '%s'", err.Error()) } } @@ -215,7 +215,7 @@ func (tp *provider) TestGenerateExisting(t *testing.T) { if err == nil { t.Error("expected error to not be nil") } else { - if err.Error() != "cannot create key with name 'self'" { + if !strings.Contains(err.Error(), "cannot create key with name 'self'") { t.Fatalf("expected error 'cannot create key with name 'self'', got '%s'", err.Error()) } } @@ -314,7 +314,7 @@ func (tp *provider) TestRenameToSelf(t *testing.T) { if err == nil { t.Error("expected error to not be nil") } else { - if err.Error() != "cannot overwrite key with name 'self'" { + if !strings.Contains(err.Error(), "cannot overwrite key with name 'self'") { t.Fatalf("expected error 'cannot overwrite key with name 'self'', got '%s'", err.Error()) } } @@ -338,7 +338,7 @@ func (tp *provider) TestRenameToSelfForce(t *testing.T) { if err == nil { t.Error("expected error to not be nil") } else { - if err.Error() != "cannot overwrite key with name 'self'" { + if !strings.Contains(err.Error(), "cannot overwrite key with name 'self'") { t.Fatalf("expected error 'cannot overwrite key with name 'self'', got '%s'", err.Error()) } } @@ -368,7 +368,7 @@ func (tp *provider) TestRenameOverwriteNoForce(t *testing.T) { if err == nil { t.Error("expected error to not be nil") } else { - if err.Error() != "key by that name already exists, refusing to overwrite" { + if !strings.Contains(err.Error(), "key by that name already exists, refusing to overwrite") { t.Fatalf("expected error 'key by that name already exists, refusing to overwrite', got '%s'", err.Error()) } } diff --git a/core/coreiface/tests/object.go b/core/coreiface/tests/object.go index 81d5b4117..2a3b1bd5c 100644 --- a/core/coreiface/tests/object.go +++ b/core/coreiface/tests/object.go @@ -300,7 +300,7 @@ func (tp *provider) TestObjectAddLinkCreate(t *testing.T) { if err == nil { t.Fatal("expected an error") } - if err.Error() != "no link by that name" { + if !strings.Contains(err.Error(), "no link by that name") { t.Fatalf("unexpected error: %s", err.Error()) } From f2b47a6665c0ef780d1329b85cb251f8e368ae99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 11 Jan 2019 12:49:50 +0100 Subject: [PATCH 0198/1212] ls: report real size by default MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@d48b9e1c1f2c70766f5fd1cb13f872ec86075d4d This commit was moved from ipfs/boxo@b1caa58eae01f9d6623c504be4085c32ebc675f5 --- core/coreiface/tests/unixfs.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/coreiface/tests/unixfs.go b/core/coreiface/tests/unixfs.go index e8a1aba32..9e1454c41 100644 --- a/core/coreiface/tests/unixfs.go +++ b/core/coreiface/tests/unixfs.go @@ -704,8 +704,8 @@ func (tp *provider) TestLs(t *testing.T) { if len(links) != 1 { t.Fatalf("expected 1 link, got %d", len(links)) } - if links[0].Size != 23 { - t.Fatalf("expected size = 23, got %d", links[0].Size) + if links[0].Size != 15 { + t.Fatalf("expected size = 15, got %d", links[0].Size) } if links[0].Name != "name-of-file" { t.Fatalf("expected name = name-of-file, got %s", links[0].Name) From dbeaf11b3970d6597b0b013712eda5b73b52242b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 11 Jan 2019 13:16:47 +0100 Subject: [PATCH 0199/1212] ls: skip size for directories MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@6c323ff16d39002eec98b8ae6337f7050937e0d8 This commit was moved from ipfs/boxo@100779d936550209ee7020525cb7b3ff0639787f --- core/coreiface/tests/unixfs.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/coreiface/tests/unixfs.go b/core/coreiface/tests/unixfs.go index 9e1454c41..e8a1aba32 100644 --- a/core/coreiface/tests/unixfs.go +++ b/core/coreiface/tests/unixfs.go @@ -704,8 +704,8 @@ func (tp *provider) TestLs(t *testing.T) { if len(links) != 1 { t.Fatalf("expected 1 link, got %d", len(links)) } - if links[0].Size != 15 { - t.Fatalf("expected size = 15, got %d", links[0].Size) + if links[0].Size != 23 { + t.Fatalf("expected size = 23, got %d", links[0].Size) } if links[0].Name != "name-of-file" { t.Fatalf("expected name = name-of-file, got %s", links[0].Name) From b7e258cc1015e518198c50b02fcc6ebdd8767375 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 21 Jan 2019 21:31:09 +0100 Subject: [PATCH 0200/1212] Reimplement DAG as DAGService This commit was moved from ipfs/go-ipfs-http-client@f34a5f6d2569bb21f022d3231e811b3db6262ca8 --- client/httpapi/api.go | 6 +- client/httpapi/apifile.go | 5 ++ client/httpapi/dag.go | 115 ++++++++++++++++++++++++-------------- 3 files changed, 83 insertions(+), 43 deletions(-) diff --git a/client/httpapi/api.go b/client/httpapi/api.go index 3a8e0e003..7d4fbd0e0 100644 --- a/client/httpapi/api.go +++ b/client/httpapi/api.go @@ -10,6 +10,8 @@ import ( "github.com/ipfs/go-ipfs/core/coreapi/interface" caopts "github.com/ipfs/go-ipfs/core/coreapi/interface/options" + + "github.com/ipfs/go-ipld-format" homedir "github.com/mitchellh/go-homedir" ma "github.com/multiformats/go-multiaddr" manet "github.com/multiformats/go-multiaddr-net" @@ -137,8 +139,8 @@ func (api *HttpApi) Block() iface.BlockAPI { return (*BlockAPI)(api) } -func (api *HttpApi) Dag() iface.DagAPI { - return (*DagAPI)(api) +func (api *HttpApi) Dag() format.DAGService { + return (*HttpDagServ)(api) } func (api *HttpApi) Name() iface.NameAPI { diff --git a/client/httpapi/apifile.go b/client/httpapi/apifile.go index d9da23975..99ae72059 100644 --- a/client/httpapi/apifile.go +++ b/client/httpapi/apifile.go @@ -125,6 +125,11 @@ func (it *apiIter) Name() string { } func (it *apiIter) Next() bool { + if it.ctx.Err() != nil { + it.err = it.ctx.Err() + return false + } + var out lsOutput if err := it.dec.Decode(&out); err != nil { if err != io.EOF { diff --git a/client/httpapi/dag.go b/client/httpapi/dag.go index 20c233196..de2934c2f 100644 --- a/client/httpapi/dag.go +++ b/client/httpapi/dag.go @@ -1,71 +1,104 @@ package httpapi import ( + "bytes" "context" "fmt" - "io" - "math" + "io/ioutil" + "sync" "github.com/ipfs/go-ipfs/core/coreapi/interface" - caopts "github.com/ipfs/go-ipfs/core/coreapi/interface/options" + "github.com/ipfs/go-ipfs/core/coreapi/interface/options" + "github.com/ipfs/go-block-format" "github.com/ipfs/go-cid" "github.com/ipfs/go-ipld-format" - mh "github.com/multiformats/go-multihash" ) -type DagAPI HttpApi +type HttpDagServ HttpApi -func (api *DagAPI) Put(ctx context.Context, src io.Reader, opts ...caopts.DagPutOption) (iface.ResolvedPath, error) { - options, err := caopts.DagPutOptions(opts...) +func (api *HttpDagServ) Get(ctx context.Context, c cid.Cid) (format.Node, error) { + r, err := api.core().Block().Get(ctx, iface.IpldPath(c)) if err != nil { return nil, err } - codec, ok := cid.CodecToStr[options.Codec] - if !ok { - return nil, fmt.Errorf("unknowm codec %d", options.MhType) + data, err := ioutil.ReadAll(r) + if err != nil { + return nil, err } - if options.MhLength != -1 { - return nil, fmt.Errorf("setting hash len is not supported yet") + blk, err := blocks.NewBlockWithCid(data, c) + if err != nil { + return nil, err } - var out struct { - Cid cid.Cid - } - req := api.core().request("dag/put"). - Option("format", codec). - Option("input-enc", options.InputEnc) + return format.DefaultBlockDecoder.Decode(blk) +} - if options.MhType != math.MaxUint64 { - mht, ok := mh.Codes[options.MhType] - if !ok { - return nil, fmt.Errorf("unknowm mhType %d", options.MhType) +func (api *HttpDagServ) GetMany(ctx context.Context, cids []cid.Cid) <-chan *format.NodeOption { + out := make(chan *format.NodeOption) + wg := sync.WaitGroup{} + wg.Add(len(cids)) + + for _, c := range cids { + // TODO: Consider limiting concurrency of this somehow + go func() { + defer wg.Done() + n, err := api.Get(ctx, c) + + select { + case out <- &format.NodeOption{Node: n, Err: err}: + case <-ctx.Done(): + } + }() + } + return out +} + +func (api *HttpDagServ) Add(ctx context.Context, nd format.Node) error { + c := nd.Cid() + prefix := c.Prefix() + format := cid.CodecToStr[prefix.Codec] + if prefix.Version == 0 { + format = "v0" + } + + stat, err := api.core().Block().Put(ctx, bytes.NewReader(nd.RawData()), + options.Block.Hash(prefix.MhType, prefix.MhLength), options.Block.Format(format)) + if err != nil { + return err + } + if !stat.Path().Cid().Equals(c) { + return fmt.Errorf("cids didn't match - local %s, remote %s", c.String(), stat.Path().Cid().String()) + } + return nil +} + +func (api *HttpDagServ) AddMany(ctx context.Context, nds []format.Node) error { + for _, nd := range nds { + // TODO: optimize + if err := api.Add(ctx, nd); err != nil { + return err } - req.Option("hash", mht) } + return nil +} - err = req.FileBody(src).Exec(ctx, &out) - if err != nil { - return nil, err +func (api *HttpDagServ) Remove(ctx context.Context, c cid.Cid) error { + return api.core().Block().Rm(ctx, iface.IpldPath(c)) //TODO: should we force rm? +} + +func (api *HttpDagServ) RemoveMany(ctx context.Context, cids []cid.Cid) error { + for _, c := range cids { + // TODO: optimize + if err := api.Remove(ctx, c); err != nil { + return err + } } - - return iface.IpldPath(out.Cid), nil + return nil } -func (api *DagAPI) Get(ctx context.Context, path iface.Path) (format.Node, error) { - panic("implement me") -} - -func (api *DagAPI) Tree(ctx context.Context, path iface.Path, opts ...caopts.DagTreeOption) ([]iface.Path, error) { - panic("implement me") -} - -func (api *DagAPI) Batch(ctx context.Context) iface.DagBatch { - panic("implement me") -} - -func (api *DagAPI) core() *HttpApi { +func (api *HttpDagServ) core() *HttpApi { return (*HttpApi)(api) } From 20eafc59a59e7a5fc86f98603ad90b59450d1810 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 21 Jan 2019 21:31:52 +0100 Subject: [PATCH 0201/1212] coreapi: few more error check fixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@b4e7753bacca7684d5e70294f766948fd77bf1c7 This commit was moved from ipfs/boxo@b92dcf5817ba9154db34f6156ad70836b7669b03 --- core/coreiface/tests/dag.go | 2 +- core/coreiface/tests/path.go | 2 +- core/coreiface/tests/unixfs.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/core/coreiface/tests/dag.go b/core/coreiface/tests/dag.go index e66106c33..10fab125a 100644 --- a/core/coreiface/tests/dag.go +++ b/core/coreiface/tests/dag.go @@ -185,7 +185,7 @@ func (tp *provider) TestBatch(t *testing.T) { } _, err = api.Dag().Get(ctx, nds[0].Cid()) - if err == nil || err.Error() != "merkledag: not found" { + if err == nil || !strings.Contains(err.Error(), "not found") { t.Error(err) } diff --git a/core/coreiface/tests/path.go b/core/coreiface/tests/path.go index 01f2e6f36..e7df6f1fb 100644 --- a/core/coreiface/tests/path.go +++ b/core/coreiface/tests/path.go @@ -151,7 +151,7 @@ func (tp *provider) TestInvalidPathRemainder(t *testing.T) { } _, err = api.ResolvePath(ctx, p1) - if err == nil || err.Error() != "no such link found" { + if err == nil || !strings.Contains(err.Error(), "no such link found") { t.Fatalf("unexpected error: %s", err) } } diff --git a/core/coreiface/tests/unixfs.go b/core/coreiface/tests/unixfs.go index fce41ae84..0ef3f031e 100644 --- a/core/coreiface/tests/unixfs.go +++ b/core/coreiface/tests/unixfs.go @@ -587,7 +587,7 @@ func (tp *provider) TestAddHashOnly(t *testing.T) { if err == nil { t.Fatal("expected an error") } - if err.Error() != "blockservice: key not found" { + if !strings.Contains(err.Error(), "blockservice: key not found") { t.Errorf("unxepected error: %s", err.Error()) } } From 75fce9a3291127ed14cee84d4de50c2b0e3d9c1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 22 Jan 2019 21:01:19 +0100 Subject: [PATCH 0202/1212] Port dag commansds to CoreAPI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@f40d44ddbfd929eb84316d66e895f93dedf47424 This commit was moved from ipfs/boxo@9eb0432c770d33d2b1c15ea25e5d3974654e843f --- core/coreiface/coreapi.go | 2 +- core/coreiface/dag.go | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 core/coreiface/dag.go diff --git a/core/coreiface/coreapi.go b/core/coreiface/coreapi.go index 9d2100fcc..16b28182e 100644 --- a/core/coreiface/coreapi.go +++ b/core/coreiface/coreapi.go @@ -19,7 +19,7 @@ type CoreAPI interface { Block() BlockAPI // Dag returns an implementation of Dag API - Dag() ipld.DAGService + Dag() APIDagService // Name returns an implementation of Name API Name() NameAPI diff --git a/core/coreiface/dag.go b/core/coreiface/dag.go new file mode 100644 index 000000000..455d00450 --- /dev/null +++ b/core/coreiface/dag.go @@ -0,0 +1,13 @@ +package iface + +import ( + ipld "gx/ipfs/QmcKKBwfz6FyQdHR2jsXrrF6XeSBXYL86anmWNewpFpoF5/go-ipld-format" +) + +// APIDagService extends ipld.DAGService +type APIDagService interface { + ipld.DAGService + + // Pinning returns special NodeAdder which recursively pins added nodes + Pinning() ipld.NodeAdder +} From a437ea3e4e7ccf705adb78a7203fb9856861b7a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 14 Jan 2019 21:01:39 +0100 Subject: [PATCH 0203/1212] Unixfs.Add nocopy test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@e49c3d2211a09a5bfa5c5eceeeaf08715b230313 This commit was moved from ipfs/boxo@f542e9c788b6601c072ec7408e73a9057921a0b2 --- core/coreiface/tests/unixfs.go | 42 ++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/core/coreiface/tests/unixfs.go b/core/coreiface/tests/unixfs.go index 0ef3f031e..0ceae06e1 100644 --- a/core/coreiface/tests/unixfs.go +++ b/core/coreiface/tests/unixfs.go @@ -101,6 +101,34 @@ func (tp *provider) TestAdd(t *testing.T) { return coreiface.IpfsPath(c) } + rf, err := ioutil.TempFile(os.TempDir(), "unixfs-add-real") + if err != nil { + t.Fatal(err) + } + rfp := rf.Name() + + if _, err := rf.Write([]byte(helloStr)); err != nil { + t.Fatal(err) + } + + stat, err := rf.Stat() + if err != nil { + t.Fatal(err) + } + + if err := rf.Close(); err != nil { + t.Fatal(err) + } + defer os.Remove(rfp) + + realFile := func() files.Node { + n, err := files.NewReaderPathFile(rfp, ioutil.NopCloser(strings.NewReader(helloStr)), stat) + if err != nil { + t.Fatal(err) + } + return n + } + cases := []struct { name string data func() files.Node @@ -323,6 +351,20 @@ func (tp *provider) TestAdd(t *testing.T) { path: "/ipfs/QmRKGpFfR32FVXdvJiHfo4WJ5TDYBsM1P9raAp1p6APWSp", opts: []options.UnixfsAddOption{options.Unixfs.Hidden(false)}, }, + // NoCopy + { + name: "simpleNoCopy", + data: realFile, + path: "/ipfs/zb2rhdhmJjJZs9qkhQCpCQ7VREFkqWw3h1r8utjVvQugwHPFd", + opts: []options.UnixfsAddOption{options.Unixfs.Nocopy(true)}, + }, + { + name: "noCopyNoRaw", + data: realFile, + path: "/ipfs/zb2rhdhmJjJZs9qkhQCpCQ7VREFkqWw3h1r8utjVvQugwHPFd", + opts: []options.UnixfsAddOption{options.Unixfs.Nocopy(true), options.Unixfs.RawLeaves(false)}, + err: "nocopy option requires '--raw-leaves' to be enabled as well", + }, // Events / Progress { name: "simpleAddEvent", From f590838d14beed45d05b5db680eb4d010470123d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 14 Jan 2019 22:00:57 +0100 Subject: [PATCH 0204/1212] Unixfs: enforce refs on files when using nocopy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@3de10ba1bd3faefa63d1c9353a7ac47c5de45d2d This commit was moved from ipfs/boxo@089430e39729baec439315f08826de38643a99fb --- core/coreiface/tests/unixfs.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/core/coreiface/tests/unixfs.go b/core/coreiface/tests/unixfs.go index 0ceae06e1..fdc1a08cd 100644 --- a/core/coreiface/tests/unixfs.go +++ b/core/coreiface/tests/unixfs.go @@ -16,6 +16,7 @@ import ( "github.com/ipfs/go-ipfs/core/coreapi/interface/options" "gx/ipfs/QmQXze9tG878pa4Euya4rrDpyTNX3kQe4dhCaBzBozGgpe/go-unixfs" + "gx/ipfs/QmQXze9tG878pa4Euya4rrDpyTNX3kQe4dhCaBzBozGgpe/go-unixfs/importer/helpers" "gx/ipfs/QmR8BauakNcBa3RbE4nbQu76PDiJgoQgz8AJdhJuiU4TAw/go-cid" cbor "gx/ipfs/QmRoARq3nkUb13HSKZGepCZSWe5GrVPwx7xURJGZ7KWv9V/go-ipld-cbor" mdag "gx/ipfs/QmTQdH4848iTVCJmKXYyRiK72HufWTLYQQ8iN3JaQ8K1Hq/go-merkledag" @@ -365,6 +366,13 @@ func (tp *provider) TestAdd(t *testing.T) { opts: []options.UnixfsAddOption{options.Unixfs.Nocopy(true), options.Unixfs.RawLeaves(false)}, err: "nocopy option requires '--raw-leaves' to be enabled as well", }, + { + name: "noCopyNoPath", + data: strFile(helloStr), + path: "/ipfs/zb2rhdhmJjJZs9qkhQCpCQ7VREFkqWw3h1r8utjVvQugwHPFd", + opts: []options.UnixfsAddOption{options.Unixfs.Nocopy(true)}, + err: helpers.ErrMissingFsRef.Error(), + }, // Events / Progress { name: "simpleAddEvent", From d40a54caaf9cfee2f0efb3412c3eb6094e838c79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 14 Jan 2019 22:05:10 +0100 Subject: [PATCH 0205/1212] gx: update go-unixfs to 1.2.14 and go-bitswap to 1.1.21 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (and everything else...) License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@3cc6578657ac8580d77f93a681f80ceeba1d6389 This commit was moved from ipfs/boxo@99fe5e7502f9c05b67e338490b47816d4434aa71 --- core/coreiface/coreapi.go | 2 +- core/coreiface/dag.go | 2 +- core/coreiface/object.go | 2 +- core/coreiface/options/unixfs.go | 2 +- core/coreiface/path.go | 2 +- core/coreiface/tests/name.go | 2 +- core/coreiface/tests/unixfs.go | 8 ++++---- core/coreiface/unixfs.go | 2 +- 8 files changed, 11 insertions(+), 11 deletions(-) diff --git a/core/coreiface/coreapi.go b/core/coreiface/coreapi.go index 16b28182e..d26ec4f7d 100644 --- a/core/coreiface/coreapi.go +++ b/core/coreiface/coreapi.go @@ -7,7 +7,7 @@ import ( "github.com/ipfs/go-ipfs/core/coreapi/interface/options" - ipld "gx/ipfs/QmcKKBwfz6FyQdHR2jsXrrF6XeSBXYL86anmWNewpFpoF5/go-ipld-format" + ipld "gx/ipfs/QmRL22E4paat7ky7vx9MLpR97JHHbFPrg3ytFQw6qp1y1s/go-ipld-format" ) // CoreAPI defines an unified interface to IPFS for Go programs diff --git a/core/coreiface/dag.go b/core/coreiface/dag.go index 455d00450..d15e24360 100644 --- a/core/coreiface/dag.go +++ b/core/coreiface/dag.go @@ -1,7 +1,7 @@ package iface import ( - ipld "gx/ipfs/QmcKKBwfz6FyQdHR2jsXrrF6XeSBXYL86anmWNewpFpoF5/go-ipld-format" + ipld "gx/ipfs/QmRL22E4paat7ky7vx9MLpR97JHHbFPrg3ytFQw6qp1y1s/go-ipld-format" ) // APIDagService extends ipld.DAGService diff --git a/core/coreiface/object.go b/core/coreiface/object.go index ba6f5a95d..2ed357cb6 100644 --- a/core/coreiface/object.go +++ b/core/coreiface/object.go @@ -7,7 +7,7 @@ import ( options "github.com/ipfs/go-ipfs/core/coreapi/interface/options" cid "gx/ipfs/QmR8BauakNcBa3RbE4nbQu76PDiJgoQgz8AJdhJuiU4TAw/go-cid" - ipld "gx/ipfs/QmcKKBwfz6FyQdHR2jsXrrF6XeSBXYL86anmWNewpFpoF5/go-ipld-format" + ipld "gx/ipfs/QmRL22E4paat7ky7vx9MLpR97JHHbFPrg3ytFQw6qp1y1s/go-ipld-format" ) // ObjectStat provides information about dag nodes diff --git a/core/coreiface/options/unixfs.go b/core/coreiface/options/unixfs.go index 5f92f3eea..109a63f1d 100644 --- a/core/coreiface/options/unixfs.go +++ b/core/coreiface/options/unixfs.go @@ -5,7 +5,7 @@ import ( "fmt" cid "gx/ipfs/QmR8BauakNcBa3RbE4nbQu76PDiJgoQgz8AJdhJuiU4TAw/go-cid" - dag "gx/ipfs/QmTQdH4848iTVCJmKXYyRiK72HufWTLYQQ8iN3JaQ8K1Hq/go-merkledag" + dag "gx/ipfs/Qmb2UEG2TAeVrEJSjqsZF7Y2he7wRDkrdt6c3bECxwZf4k/go-merkledag" mh "gx/ipfs/QmerPMzPk1mJVowm8KgmoknWa4yCYvvugMPsgWmDNUvDLW/go-multihash" ) diff --git a/core/coreiface/path.go b/core/coreiface/path.go index 580703a73..b96e0e775 100644 --- a/core/coreiface/path.go +++ b/core/coreiface/path.go @@ -1,8 +1,8 @@ package iface import ( - ipfspath "gx/ipfs/QmNYPETsdAu2uQ1k9q9S1jYEGURaLHV6cbYRSVFVRftpF8/go-path" "gx/ipfs/QmR8BauakNcBa3RbE4nbQu76PDiJgoQgz8AJdhJuiU4TAw/go-cid" + ipfspath "gx/ipfs/QmWqh9oob7ZHQRwU5CdTqpnC8ip8BEkFNrwXRxeNo5Y7vA/go-path" ) //TODO: merge with ipfspath so we don't depend on it diff --git a/core/coreiface/tests/name.go b/core/coreiface/tests/name.go index 2e43a12ee..7b0a5d8f0 100644 --- a/core/coreiface/tests/name.go +++ b/core/coreiface/tests/name.go @@ -8,7 +8,7 @@ import ( "testing" "time" - ipath "gx/ipfs/QmNYPETsdAu2uQ1k9q9S1jYEGURaLHV6cbYRSVFVRftpF8/go-path" + ipath "gx/ipfs/QmWqh9oob7ZHQRwU5CdTqpnC8ip8BEkFNrwXRxeNo5Y7vA/go-path" "gx/ipfs/QmXWZCd8jfaHmt4UDSnjKmGcrQMw95bDGWqEeVLVJjoANX/go-ipfs-files" coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface" diff --git a/core/coreiface/tests/unixfs.go b/core/coreiface/tests/unixfs.go index fdc1a08cd..6f10406eb 100644 --- a/core/coreiface/tests/unixfs.go +++ b/core/coreiface/tests/unixfs.go @@ -15,12 +15,12 @@ import ( coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface" "github.com/ipfs/go-ipfs/core/coreapi/interface/options" - "gx/ipfs/QmQXze9tG878pa4Euya4rrDpyTNX3kQe4dhCaBzBozGgpe/go-unixfs" - "gx/ipfs/QmQXze9tG878pa4Euya4rrDpyTNX3kQe4dhCaBzBozGgpe/go-unixfs/importer/helpers" "gx/ipfs/QmR8BauakNcBa3RbE4nbQu76PDiJgoQgz8AJdhJuiU4TAw/go-cid" - cbor "gx/ipfs/QmRoARq3nkUb13HSKZGepCZSWe5GrVPwx7xURJGZ7KWv9V/go-ipld-cbor" - mdag "gx/ipfs/QmTQdH4848iTVCJmKXYyRiK72HufWTLYQQ8iN3JaQ8K1Hq/go-merkledag" + cbor "gx/ipfs/QmRZxJ7oybgnnwriuRub9JXp5YdFM9wiGSyRq38QC7swpS/go-ipld-cbor" + "gx/ipfs/QmSMJ4rZbCJaih3y82Ebq7BZqK6vU2FHsKcWKQiE1DPTpS/go-unixfs" + "gx/ipfs/QmSMJ4rZbCJaih3y82Ebq7BZqK6vU2FHsKcWKQiE1DPTpS/go-unixfs/importer/helpers" "gx/ipfs/QmXWZCd8jfaHmt4UDSnjKmGcrQMw95bDGWqEeVLVJjoANX/go-ipfs-files" + mdag "gx/ipfs/Qmb2UEG2TAeVrEJSjqsZF7Y2he7wRDkrdt6c3bECxwZf4k/go-merkledag" mh "gx/ipfs/QmerPMzPk1mJVowm8KgmoknWa4yCYvvugMPsgWmDNUvDLW/go-multihash" ) diff --git a/core/coreiface/unixfs.go b/core/coreiface/unixfs.go index b42b454cc..3c2788196 100644 --- a/core/coreiface/unixfs.go +++ b/core/coreiface/unixfs.go @@ -5,8 +5,8 @@ import ( "github.com/ipfs/go-ipfs/core/coreapi/interface/options" + ipld "gx/ipfs/QmRL22E4paat7ky7vx9MLpR97JHHbFPrg3ytFQw6qp1y1s/go-ipld-format" files "gx/ipfs/QmXWZCd8jfaHmt4UDSnjKmGcrQMw95bDGWqEeVLVJjoANX/go-ipfs-files" - ipld "gx/ipfs/QmcKKBwfz6FyQdHR2jsXrrF6XeSBXYL86anmWNewpFpoF5/go-ipld-format" ) type AddEvent struct { From 0f40b6847509dd7a52c54d9931dc9230e39ed4f3 Mon Sep 17 00:00:00 2001 From: Overbool Date: Thu, 13 Dec 2018 23:02:55 +0800 Subject: [PATCH 0206/1212] cmds/pin: use coreapi/pin License: MIT Signed-off-by: Overbool This commit was moved from ipfs/interface-go-ipfs-core@3e1cd71bb97f70a6309fa31f3d9e719c7b38f254 This commit was moved from ipfs/boxo@6b2d6ab3cdddb3db4b653e82ac78560e2c1b842f --- core/coreiface/options/pin.go | 36 ++++++++++++++++++++++++++++++++++- core/coreiface/pin.go | 2 +- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/core/coreiface/options/pin.go b/core/coreiface/options/pin.go index 9d1107f92..630b561de 100644 --- a/core/coreiface/options/pin.go +++ b/core/coreiface/options/pin.go @@ -8,12 +8,23 @@ type PinLsSettings struct { Type string } +// PinRmSettings represents the settings of pin rm command +type PinRmSettings struct { + Recursive bool + Force bool +} + type PinUpdateSettings struct { Unpin bool } type PinAddOption func(*PinAddSettings) error -type PinLsOption func(settings *PinLsSettings) error + +// PinRmOption pin rm option func +type PinRmOption func(*PinRmSettings) error + +// PinLsOption pin ls option func +type PinLsOption func(*PinLsSettings) error type PinUpdateOption func(*PinUpdateSettings) error func PinAddOptions(opts ...PinAddOption) (*PinAddSettings, error) { @@ -31,6 +42,21 @@ func PinAddOptions(opts ...PinAddOption) (*PinAddSettings, error) { return options, nil } +// PinRmOptions pin rm options +func PinRmOptions(opts ...PinRmOption) (*PinRmSettings, error) { + options := &PinRmSettings{ + Recursive: true, + } + + for _, opt := range opts { + if err := opt(options); err != nil { + return nil, err + } + } + + return options, nil +} + func PinLsOptions(opts ...PinLsOption) (*PinLsSettings, error) { options := &PinLsSettings{ Type: "all", @@ -102,6 +128,14 @@ func (pinOpts) Recursive(recursive bool) PinAddOption { } } +// RmRecursive is an option for Pin.Rm +func (pinOpts) RmRecursive(recursive bool) PinRmOption { + return func(settings *PinRmSettings) error { + settings.Recursive = recursive + return nil + } +} + // Type is an option for Pin.Ls which allows to specify which pin types should // be returned // diff --git a/core/coreiface/pin.go b/core/coreiface/pin.go index 2e119cbea..6e13def8f 100644 --- a/core/coreiface/pin.go +++ b/core/coreiface/pin.go @@ -43,7 +43,7 @@ type PinAPI interface { Ls(context.Context, ...options.PinLsOption) ([]Pin, error) // Rm removes pin for object specified by the path - Rm(context.Context, Path) error + Rm(context.Context, Path, ...options.PinRmOption) error // Update changes one pin to another, skipping checks for matching paths in // the old tree From bcc6216709b9f782931d640abeaa7f14563f5d06 Mon Sep 17 00:00:00 2001 From: Overbool Date: Sat, 15 Dec 2018 11:14:29 +0800 Subject: [PATCH 0207/1212] cmds/pin: modify test License: MIT Signed-off-by: Overbool This commit was moved from ipfs/interface-go-ipfs-core@8e9e8d1b419aa93da6f3573bf424db57a60399ae This commit was moved from ipfs/boxo@e3960a2b9f8f40403f8ffbce29e576a217dbbf74 --- core/coreiface/options/pin.go | 1 - 1 file changed, 1 deletion(-) diff --git a/core/coreiface/options/pin.go b/core/coreiface/options/pin.go index 630b561de..cc4a8ef29 100644 --- a/core/coreiface/options/pin.go +++ b/core/coreiface/options/pin.go @@ -11,7 +11,6 @@ type PinLsSettings struct { // PinRmSettings represents the settings of pin rm command type PinRmSettings struct { Recursive bool - Force bool } type PinUpdateSettings struct { From e00e0dfed2c142410b5878783818ba29569acad6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 30 Jan 2019 17:42:14 +0100 Subject: [PATCH 0208/1212] gx: update go-unixfs to propagate archive changes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@fbde8e2781a69d29530a3a55c8007f135d65e25e This commit was moved from ipfs/boxo@c6503a1ba9fa4f111fd0ca2975a9f7285d5d4768 --- core/coreiface/tests/name.go | 2 +- core/coreiface/tests/unixfs.go | 6 +++--- core/coreiface/unixfs.go | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/core/coreiface/tests/name.go b/core/coreiface/tests/name.go index 7b0a5d8f0..8690f22c3 100644 --- a/core/coreiface/tests/name.go +++ b/core/coreiface/tests/name.go @@ -9,7 +9,7 @@ import ( "time" ipath "gx/ipfs/QmWqh9oob7ZHQRwU5CdTqpnC8ip8BEkFNrwXRxeNo5Y7vA/go-path" - "gx/ipfs/QmXWZCd8jfaHmt4UDSnjKmGcrQMw95bDGWqEeVLVJjoANX/go-ipfs-files" + "gx/ipfs/QmaXvvAVAQ5ABqM5xtjYmV85xmN5MkWAZsX9H9Fwo4FVXp/go-ipfs-files" coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface" opt "github.com/ipfs/go-ipfs/core/coreapi/interface/options" diff --git a/core/coreiface/tests/unixfs.go b/core/coreiface/tests/unixfs.go index 6f10406eb..2f1ab90a4 100644 --- a/core/coreiface/tests/unixfs.go +++ b/core/coreiface/tests/unixfs.go @@ -15,11 +15,11 @@ import ( coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface" "github.com/ipfs/go-ipfs/core/coreapi/interface/options" + "gx/ipfs/QmQ1JnYpnzkaurjW1yxkQxC2w3K1PorNE1nv1vaP5Le7sq/go-unixfs" + "gx/ipfs/QmQ1JnYpnzkaurjW1yxkQxC2w3K1PorNE1nv1vaP5Le7sq/go-unixfs/importer/helpers" "gx/ipfs/QmR8BauakNcBa3RbE4nbQu76PDiJgoQgz8AJdhJuiU4TAw/go-cid" cbor "gx/ipfs/QmRZxJ7oybgnnwriuRub9JXp5YdFM9wiGSyRq38QC7swpS/go-ipld-cbor" - "gx/ipfs/QmSMJ4rZbCJaih3y82Ebq7BZqK6vU2FHsKcWKQiE1DPTpS/go-unixfs" - "gx/ipfs/QmSMJ4rZbCJaih3y82Ebq7BZqK6vU2FHsKcWKQiE1DPTpS/go-unixfs/importer/helpers" - "gx/ipfs/QmXWZCd8jfaHmt4UDSnjKmGcrQMw95bDGWqEeVLVJjoANX/go-ipfs-files" + "gx/ipfs/QmaXvvAVAQ5ABqM5xtjYmV85xmN5MkWAZsX9H9Fwo4FVXp/go-ipfs-files" mdag "gx/ipfs/Qmb2UEG2TAeVrEJSjqsZF7Y2he7wRDkrdt6c3bECxwZf4k/go-merkledag" mh "gx/ipfs/QmerPMzPk1mJVowm8KgmoknWa4yCYvvugMPsgWmDNUvDLW/go-multihash" ) diff --git a/core/coreiface/unixfs.go b/core/coreiface/unixfs.go index 3c2788196..408280cbc 100644 --- a/core/coreiface/unixfs.go +++ b/core/coreiface/unixfs.go @@ -6,7 +6,7 @@ import ( "github.com/ipfs/go-ipfs/core/coreapi/interface/options" ipld "gx/ipfs/QmRL22E4paat7ky7vx9MLpR97JHHbFPrg3ytFQw6qp1y1s/go-ipld-format" - files "gx/ipfs/QmXWZCd8jfaHmt4UDSnjKmGcrQMw95bDGWqEeVLVJjoANX/go-ipfs-files" + files "gx/ipfs/QmaXvvAVAQ5ABqM5xtjYmV85xmN5MkWAZsX9H9Fwo4FVXp/go-ipfs-files" ) type AddEvent struct { From 8f0b53d1f78c8eb7c2977416ba492ad6c21be47e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 21 Jan 2019 12:30:34 +0100 Subject: [PATCH 0209/1212] coreapi: add some seeker tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@be8e8d1aebcd3b544b0b9c345338ed9c55bbfe1c This commit was moved from ipfs/boxo@ac20c6ad8101683bb28e0a57955bcefc454a959f --- core/coreiface/tests/unixfs.go | 107 ++++++++++++++++++++++++++++++++- 1 file changed, 106 insertions(+), 1 deletion(-) diff --git a/core/coreiface/tests/unixfs.go b/core/coreiface/tests/unixfs.go index 2f1ab90a4..5ae273987 100644 --- a/core/coreiface/tests/unixfs.go +++ b/core/coreiface/tests/unixfs.go @@ -3,9 +3,11 @@ package tests import ( "bytes" "context" + "fmt" "io" "io/ioutil" "math" + "math/rand" "os" "strconv" "strings" @@ -43,6 +45,7 @@ func (tp *provider) TestUnixfs(t *testing.T) { t.Run("TestLsEmptyDir", tp.TestLsEmptyDir) t.Run("TestLsNonUnixfs", tp.TestLsNonUnixfs) t.Run("TestAddCloses", tp.TestAddCloses) + t.Run("TestGetSeek", tp.TestGetSeek) } // `echo -n 'hello, world!' | ipfs add` @@ -934,5 +937,107 @@ func (tp *provider) TestAddCloses(t *testing.T) { t.Errorf("dir %d not closed!", i) } } - +} + +func (tp *provider) TestGetSeek(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + api, err := tp.makeAPI(ctx) + if err != nil { + t.Error(err) + } + + dataSize := int64(100000) + tf := files.NewReaderFile(io.LimitReader(rand.New(rand.NewSource(1403768328)), dataSize)) + + p, err := api.Unixfs().Add(ctx, tf, options.Unixfs.Chunker("size-100")) + if err != nil { + t.Fatal(err) + } + + r, err := api.Unixfs().Get(ctx, p) + if err != nil { + t.Fatal(err) + } + + f := files.ToFile(r) + if f == nil { + t.Fatal("not a file") + } + + orig := make([]byte, dataSize) + if _, err := f.Read(orig); err != nil { + t.Fatal(err) + } + f.Close() + + origR := bytes.NewReader(orig) + + r, err = api.Unixfs().Get(ctx, p) + if err != nil { + t.Fatal(err) + } + + f = files.ToFile(r) + if f == nil { + t.Fatal("not a file") + } + + test := func(offset int64, whence int, read int, expect int64, shouldEof bool) { + t.Run(fmt.Sprintf("seek%d+%d-r%d-%d", whence, offset, read, expect), func(t *testing.T) { + n, err := f.Seek(offset, whence) + if err != nil { + t.Fatal(err) + } + origN, err := origR.Seek(offset, whence) + if err != nil { + t.Fatal(err) + } + + if n != origN { + t.Fatalf("offsets didn't match, expected %d, got %d", origN, n) + } + + buf := make([]byte, read) + origBuf := make([]byte, read) + origRead, err := origR.Read(origBuf) + if err != nil { + t.Fatalf("orig: %s", err) + } + r, err := f.Read(buf) + switch { + case shouldEof && err != nil && err != io.EOF: + fallthrough + case !shouldEof && err != nil: + t.Fatalf("f: %s", err) + case shouldEof: + _, err := f.Read([]byte{0}) + if err != io.EOF { + t.Fatal("expected EOF") + } + _, err = origR.Read([]byte{0}) + if err != io.EOF { + t.Fatal("expected EOF (orig)") + } + } + + if int64(r) != expect { + t.Fatal("read wrong amount of data") + } + if r != origRead { + t.Fatal("read different amount of data than bytes.Reader") + } + if !bytes.Equal(buf, origBuf) { + t.Fatal("data didn't match") + } + }) + } + + test(3, io.SeekCurrent, 10, 10, false) + test(3, io.SeekCurrent, 10, 10, false) + test(500, io.SeekCurrent, 10, 10, false) + test(350, io.SeekStart, 100, 100, false) + test(-123, io.SeekCurrent, 100, 100, false) + test(dataSize-50, io.SeekStart, 100, 50, true) + test(-5, io.SeekEnd, 100, 5, true) } From aeb9cdfae0878d4954ecc2cdc570168449887463 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 1 Feb 2019 19:48:43 +0100 Subject: [PATCH 0210/1212] coreapi: use chan for returning results in Unixfs.Ls MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@93175e9900f58425d3868381c3a8668500ac39a9 This commit was moved from ipfs/boxo@3afaf889d4d49000482655a90591acdd3eb16349 --- core/coreiface/tests/unixfs.go | 18 ++++++++++-------- core/coreiface/unixfs.go | 2 +- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/core/coreiface/tests/unixfs.go b/core/coreiface/tests/unixfs.go index 5ae273987..68d408e6c 100644 --- a/core/coreiface/tests/unixfs.go +++ b/core/coreiface/tests/unixfs.go @@ -754,18 +754,20 @@ func (tp *provider) TestLs(t *testing.T) { t.Error(err) } - if len(links) != 1 { - t.Fatalf("expected 1 link, got %d", len(links)) + link := <- links + if link.Size != 23 { + t.Fatalf("expected size = 23, got %d", link.Size) } - if links[0].Size != 23 { - t.Fatalf("expected size = 23, got %d", links[0].Size) + if link.Name != "name-of-file" { + t.Fatalf("expected name = name-of-file, got %s", link.Name) } - if links[0].Name != "name-of-file" { - t.Fatalf("expected name = name-of-file, got %s", links[0].Name) + if link.Cid.String() != "QmX3qQVKxDGz3URVC3861Z3CKtQKGBn6ffXRBBWGMFz9Lr" { + t.Fatalf("expected cid = QmX3qQVKxDGz3URVC3861Z3CKtQKGBn6ffXRBBWGMFz9Lr, got %s", link.Cid) } - if links[0].Cid.String() != "QmX3qQVKxDGz3URVC3861Z3CKtQKGBn6ffXRBBWGMFz9Lr" { - t.Fatalf("expected cid = QmX3qQVKxDGz3URVC3861Z3CKtQKGBn6ffXRBBWGMFz9Lr, got %s", links[0].Cid) + if _, ok := <-links; ok { + t.Errorf("didn't expect a second link") } + } func (tp *provider) TestEntriesExpired(t *testing.T) { diff --git a/core/coreiface/unixfs.go b/core/coreiface/unixfs.go index 408280cbc..cdb6a1e0c 100644 --- a/core/coreiface/unixfs.go +++ b/core/coreiface/unixfs.go @@ -31,5 +31,5 @@ type UnixfsAPI interface { Get(context.Context, Path) (files.Node, error) // Ls returns the list of links in a directory - Ls(context.Context, Path) ([]*ipld.Link, error) + Ls(context.Context, Path) (<-chan *ipld.Link, error) } From 9f4c14741c76ab5c65de43a7871bbb24609b72d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 1 Feb 2019 20:12:48 +0100 Subject: [PATCH 0211/1212] coreapi: asunc ls option MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@72006bfe2d78cd6cb507ff0265cd1844521d190e This commit was moved from ipfs/boxo@db66d03977366d25aa6b91f30a6ec7a9fcae9037 --- core/coreiface/options/unixfs.go | 30 ++++++++++++++++++++++++++++++ core/coreiface/tests/unixfs.go | 22 ++++++++++++++++++++-- core/coreiface/unixfs.go | 6 +++--- 3 files changed, 53 insertions(+), 5 deletions(-) diff --git a/core/coreiface/options/unixfs.go b/core/coreiface/options/unixfs.go index 109a63f1d..819cc3b6b 100644 --- a/core/coreiface/options/unixfs.go +++ b/core/coreiface/options/unixfs.go @@ -42,7 +42,12 @@ type UnixfsAddSettings struct { Progress bool } +type UnixfsLsSettings struct { + Async bool +} + type UnixfsAddOption func(*UnixfsAddSettings) error +type UnixfsLsOption func(*UnixfsLsSettings) error func UnixfsAddOptions(opts ...UnixfsAddOption) (*UnixfsAddSettings, cid.Prefix, error) { options := &UnixfsAddSettings{ @@ -122,6 +127,21 @@ func UnixfsAddOptions(opts ...UnixfsAddOption) (*UnixfsAddSettings, cid.Prefix, return options, prefix, nil } +func UnixfsLsOptions(opts ...UnixfsLsOption) (*UnixfsLsSettings, error) { + options := &UnixfsLsSettings{ + Async: true, + } + + for _, opt := range opts { + err := opt(options) + if err != nil { + return nil, err + } + } + + return options, nil +} + type unixfsOpts struct{} var Unixfs unixfsOpts @@ -290,3 +310,13 @@ func (unixfsOpts) Nocopy(enable bool) UnixfsAddOption { return nil } } + +// Async tells ls to return results as soon as they are available, which can be +// useful for listing HAMT directories. When this option is set to true returned +// results won't be returned in order +func (unixfsOpts) Async(async bool) UnixfsLsOption { + return func(settings *UnixfsLsSettings) error { + settings.Async = async + return nil + } +} diff --git a/core/coreiface/tests/unixfs.go b/core/coreiface/tests/unixfs.go index 68d408e6c..b2b5a9ebb 100644 --- a/core/coreiface/tests/unixfs.go +++ b/core/coreiface/tests/unixfs.go @@ -749,12 +749,12 @@ func (tp *provider) TestLs(t *testing.T) { t.Error(err) } - links, err := api.Unixfs().Ls(ctx, p) + links, err := api.Unixfs().Ls(ctx, p, options.Unixfs.Async(false)) if err != nil { t.Error(err) } - link := <- links + link := (<-links).Link if link.Size != 23 { t.Fatalf("expected size = 23, got %d", link.Size) } @@ -768,6 +768,24 @@ func (tp *provider) TestLs(t *testing.T) { t.Errorf("didn't expect a second link") } + links, err = api.Unixfs().Ls(ctx, p, options.Unixfs.Async(true)) + if err != nil { + t.Error(err) + } + + link = (<-links).Link + if link.Size != 23 { + t.Fatalf("expected size = 23, got %d", link.Size) + } + if link.Name != "name-of-file" { + t.Fatalf("expected name = name-of-file, got %s", link.Name) + } + if link.Cid.String() != "QmX3qQVKxDGz3URVC3861Z3CKtQKGBn6ffXRBBWGMFz9Lr" { + t.Fatalf("expected cid = QmX3qQVKxDGz3URVC3861Z3CKtQKGBn6ffXRBBWGMFz9Lr, got %s", link.Cid) + } + if _, ok := <-links; ok { + t.Errorf("didn't expect a second link") + } } func (tp *provider) TestEntriesExpired(t *testing.T) { diff --git a/core/coreiface/unixfs.go b/core/coreiface/unixfs.go index cdb6a1e0c..ba2673fee 100644 --- a/core/coreiface/unixfs.go +++ b/core/coreiface/unixfs.go @@ -5,8 +5,8 @@ import ( "github.com/ipfs/go-ipfs/core/coreapi/interface/options" - ipld "gx/ipfs/QmRL22E4paat7ky7vx9MLpR97JHHbFPrg3ytFQw6qp1y1s/go-ipld-format" - files "gx/ipfs/QmaXvvAVAQ5ABqM5xtjYmV85xmN5MkWAZsX9H9Fwo4FVXp/go-ipfs-files" + ft "gx/ipfs/QmQ1JnYpnzkaurjW1yxkQxC2w3K1PorNE1nv1vaP5Le7sq/go-unixfs" + "gx/ipfs/QmaXvvAVAQ5ABqM5xtjYmV85xmN5MkWAZsX9H9Fwo4FVXp/go-ipfs-files" ) type AddEvent struct { @@ -31,5 +31,5 @@ type UnixfsAPI interface { Get(context.Context, Path) (files.Node, error) // Ls returns the list of links in a directory - Ls(context.Context, Path) (<-chan *ipld.Link, error) + Ls(context.Context, Path, ...options.UnixfsLsOption) (<-chan ft.LinkResult, error) } From ef5879661a0feb801ce0463548ca60cf06c9d3a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 1 Feb 2019 23:07:19 +0100 Subject: [PATCH 0212/1212] coreapi: resolve type/size in Unixfs.Ls MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@01bbf29cf470532d94aba2bc5a912eb44d9997d0 This commit was moved from ipfs/boxo@54f7855257d69f5f79fe37d7896ddff4e0d1c2f7 --- core/coreiface/options/unixfs.go | 17 +++++++++++++++++ core/coreiface/unixfs.go | 14 +++++++++++--- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/core/coreiface/options/unixfs.go b/core/coreiface/options/unixfs.go index 819cc3b6b..6dbab93b6 100644 --- a/core/coreiface/options/unixfs.go +++ b/core/coreiface/options/unixfs.go @@ -44,6 +44,9 @@ type UnixfsAddSettings struct { type UnixfsLsSettings struct { Async bool + + ResolveType bool + ResolveSize bool } type UnixfsAddOption func(*UnixfsAddSettings) error @@ -320,3 +323,17 @@ func (unixfsOpts) Async(async bool) UnixfsLsOption { return nil } } + +func (unixfsOpts) ResolveSize(resolve bool) UnixfsLsOption { + return func(settings *UnixfsLsSettings) error { + settings.ResolveSize = resolve + return nil + } +} + +func (unixfsOpts) ResolveType(resolve bool) UnixfsLsOption { + return func(settings *UnixfsLsSettings) error { + settings.ResolveSize = resolve + return nil + } +} \ No newline at end of file diff --git a/core/coreiface/unixfs.go b/core/coreiface/unixfs.go index ba2673fee..846b74629 100644 --- a/core/coreiface/unixfs.go +++ b/core/coreiface/unixfs.go @@ -2,10 +2,10 @@ package iface import ( "context" - "github.com/ipfs/go-ipfs/core/coreapi/interface/options" - ft "gx/ipfs/QmQ1JnYpnzkaurjW1yxkQxC2w3K1PorNE1nv1vaP5Le7sq/go-unixfs" + "gx/ipfs/QmQ1JnYpnzkaurjW1yxkQxC2w3K1PorNE1nv1vaP5Le7sq/go-unixfs/pb" + ipld "gx/ipfs/QmRL22E4paat7ky7vx9MLpR97JHHbFPrg3ytFQw6qp1y1s/go-ipld-format" "gx/ipfs/QmaXvvAVAQ5ABqM5xtjYmV85xmN5MkWAZsX9H9Fwo4FVXp/go-ipfs-files" ) @@ -16,6 +16,14 @@ type AddEvent struct { Size string `json:",omitempty"` } +type LsLink struct { + Link *ipld.Link + Size uint64 + Type unixfs_pb.Data_DataType + + Err error +} + // UnixfsAPI is the basic interface to immutable files in IPFS // NOTE: This API is heavily WIP, things are guaranteed to break frequently type UnixfsAPI interface { @@ -31,5 +39,5 @@ type UnixfsAPI interface { Get(context.Context, Path) (files.Node, error) // Ls returns the list of links in a directory - Ls(context.Context, Path, ...options.UnixfsLsOption) (<-chan ft.LinkResult, error) + Ls(context.Context, Path, ...options.UnixfsLsOption) (<-chan LsLink, error) } From 3dab84314914893061a215ef9cc56f154f9a343c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Sat, 2 Feb 2019 00:18:44 +0100 Subject: [PATCH 0213/1212] ls: use CoreAPI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@fad4bd392abb9eb689687497d89d9e51e56486fb This commit was moved from ipfs/boxo@966d0008c10b29c04075261e3c59b0cab8953faa --- core/coreiface/options/unixfs.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/core/coreiface/options/unixfs.go b/core/coreiface/options/unixfs.go index 6dbab93b6..4ff5cdb3f 100644 --- a/core/coreiface/options/unixfs.go +++ b/core/coreiface/options/unixfs.go @@ -133,6 +133,9 @@ func UnixfsAddOptions(opts ...UnixfsAddOption) (*UnixfsAddSettings, cid.Prefix, func UnixfsLsOptions(opts ...UnixfsLsOption) (*UnixfsLsSettings, error) { options := &UnixfsLsSettings{ Async: true, + + ResolveSize: true, + ResolveType: true, } for _, opt := range opts { @@ -333,7 +336,7 @@ func (unixfsOpts) ResolveSize(resolve bool) UnixfsLsOption { func (unixfsOpts) ResolveType(resolve bool) UnixfsLsOption { return func(settings *UnixfsLsSettings) error { - settings.ResolveSize = resolve + settings.ResolveType = resolve return nil } -} \ No newline at end of file +} From 9f41461f572ba3ed3e2a9c247521690595705d3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Sat, 2 Feb 2019 03:42:00 +0100 Subject: [PATCH 0214/1212] coreapi: stream only ls, handle storting in command MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@a62acc82d4b5f8135f1d1249a22e91572a9a03c0 This commit was moved from ipfs/boxo@328e6f8ac9b4229e990201a93954213be992c45d --- core/coreiface/options/unixfs.go | 14 -------------- core/coreiface/tests/unixfs.go | 21 +-------------------- core/coreiface/unixfs.go | 3 ++- 3 files changed, 3 insertions(+), 35 deletions(-) diff --git a/core/coreiface/options/unixfs.go b/core/coreiface/options/unixfs.go index 4ff5cdb3f..7e77410bc 100644 --- a/core/coreiface/options/unixfs.go +++ b/core/coreiface/options/unixfs.go @@ -43,8 +43,6 @@ type UnixfsAddSettings struct { } type UnixfsLsSettings struct { - Async bool - ResolveType bool ResolveSize bool } @@ -132,8 +130,6 @@ func UnixfsAddOptions(opts ...UnixfsAddOption) (*UnixfsAddSettings, cid.Prefix, func UnixfsLsOptions(opts ...UnixfsLsOption) (*UnixfsLsSettings, error) { options := &UnixfsLsSettings{ - Async: true, - ResolveSize: true, ResolveType: true, } @@ -317,16 +313,6 @@ func (unixfsOpts) Nocopy(enable bool) UnixfsAddOption { } } -// Async tells ls to return results as soon as they are available, which can be -// useful for listing HAMT directories. When this option is set to true returned -// results won't be returned in order -func (unixfsOpts) Async(async bool) UnixfsLsOption { - return func(settings *UnixfsLsSettings) error { - settings.Async = async - return nil - } -} - func (unixfsOpts) ResolveSize(resolve bool) UnixfsLsOption { return func(settings *UnixfsLsSettings) error { settings.ResolveSize = resolve diff --git a/core/coreiface/tests/unixfs.go b/core/coreiface/tests/unixfs.go index b2b5a9ebb..054461de1 100644 --- a/core/coreiface/tests/unixfs.go +++ b/core/coreiface/tests/unixfs.go @@ -749,7 +749,7 @@ func (tp *provider) TestLs(t *testing.T) { t.Error(err) } - links, err := api.Unixfs().Ls(ctx, p, options.Unixfs.Async(false)) + links, err := api.Unixfs().Ls(ctx, p) if err != nil { t.Error(err) } @@ -767,25 +767,6 @@ func (tp *provider) TestLs(t *testing.T) { if _, ok := <-links; ok { t.Errorf("didn't expect a second link") } - - links, err = api.Unixfs().Ls(ctx, p, options.Unixfs.Async(true)) - if err != nil { - t.Error(err) - } - - link = (<-links).Link - if link.Size != 23 { - t.Fatalf("expected size = 23, got %d", link.Size) - } - if link.Name != "name-of-file" { - t.Fatalf("expected name = name-of-file, got %s", link.Name) - } - if link.Cid.String() != "QmX3qQVKxDGz3URVC3861Z3CKtQKGBn6ffXRBBWGMFz9Lr" { - t.Fatalf("expected cid = QmX3qQVKxDGz3URVC3861Z3CKtQKGBn6ffXRBBWGMFz9Lr, got %s", link.Cid) - } - if _, ok := <-links; ok { - t.Errorf("didn't expect a second link") - } } func (tp *provider) TestEntriesExpired(t *testing.T) { diff --git a/core/coreiface/unixfs.go b/core/coreiface/unixfs.go index 846b74629..a77011988 100644 --- a/core/coreiface/unixfs.go +++ b/core/coreiface/unixfs.go @@ -38,6 +38,7 @@ type UnixfsAPI interface { // to operations performed on the returned file Get(context.Context, Path) (files.Node, error) - // Ls returns the list of links in a directory + // Ls returns the list of links in a directory. Links aren't guaranteed to be + // returned in order Ls(context.Context, Path, ...options.UnixfsLsOption) (<-chan LsLink, error) } From 39204505d087da8853f0800111b03348d5d896ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Sat, 2 Feb 2019 17:13:28 +0100 Subject: [PATCH 0215/1212] coreapi ls: merge ResolveType and ResolveSize MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@d93b9f110ec9df2fb0e4f840974243ae878ffdf6 This commit was moved from ipfs/boxo@8d88635d4a9ae6462528d7a6cd7737ecbd5716de --- core/coreiface/options/unixfs.go | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/core/coreiface/options/unixfs.go b/core/coreiface/options/unixfs.go index 7e77410bc..015c2dca3 100644 --- a/core/coreiface/options/unixfs.go +++ b/core/coreiface/options/unixfs.go @@ -43,8 +43,7 @@ type UnixfsAddSettings struct { } type UnixfsLsSettings struct { - ResolveType bool - ResolveSize bool + ResolveChildren bool } type UnixfsAddOption func(*UnixfsAddSettings) error @@ -130,8 +129,7 @@ func UnixfsAddOptions(opts ...UnixfsAddOption) (*UnixfsAddSettings, cid.Prefix, func UnixfsLsOptions(opts ...UnixfsLsOption) (*UnixfsLsSettings, error) { options := &UnixfsLsSettings{ - ResolveSize: true, - ResolveType: true, + ResolveChildren: true, } for _, opt := range opts { @@ -313,16 +311,9 @@ func (unixfsOpts) Nocopy(enable bool) UnixfsAddOption { } } -func (unixfsOpts) ResolveSize(resolve bool) UnixfsLsOption { +func (unixfsOpts) ResolveChildren(resolve bool) UnixfsLsOption { return func(settings *UnixfsLsSettings) error { - settings.ResolveSize = resolve - return nil - } -} - -func (unixfsOpts) ResolveType(resolve bool) UnixfsLsOption { - return func(settings *UnixfsLsSettings) error { - settings.ResolveType = resolve + settings.ResolveChildren = resolve return nil } } From eac8515c0b25512058d104042fdfde3e7d63d34b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Sat, 2 Feb 2019 17:27:54 +0100 Subject: [PATCH 0216/1212] coreapi: mirror unixfs file types MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@e8196db410d2fc38fb64613bebedccc79c1ecaec This commit was moved from ipfs/boxo@e47af31e2d3e5b497f91392603ed5f6b760f6eff --- core/coreiface/unixfs.go | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/core/coreiface/unixfs.go b/core/coreiface/unixfs.go index a77011988..1fb07638f 100644 --- a/core/coreiface/unixfs.go +++ b/core/coreiface/unixfs.go @@ -4,7 +4,7 @@ import ( "context" "github.com/ipfs/go-ipfs/core/coreapi/interface/options" - "gx/ipfs/QmQ1JnYpnzkaurjW1yxkQxC2w3K1PorNE1nv1vaP5Le7sq/go-unixfs/pb" + "gx/ipfs/QmQ1JnYpnzkaurjW1yxkQxC2w3K1PorNE1nv1vaP5Le7sq/go-unixfs" ipld "gx/ipfs/QmRL22E4paat7ky7vx9MLpR97JHHbFPrg3ytFQw6qp1y1s/go-ipld-format" "gx/ipfs/QmaXvvAVAQ5ABqM5xtjYmV85xmN5MkWAZsX9H9Fwo4FVXp/go-ipfs-files" ) @@ -16,10 +16,21 @@ type AddEvent struct { Size string `json:",omitempty"` } +type FileType int32 + +const ( + TRaw = FileType(unixfs.TRaw) + TFile = FileType(unixfs.TFile) + TDirectory = FileType(unixfs.TDirectory) + TMetadata = FileType(unixfs.TMetadata) + TSymlink = FileType(unixfs.TSymlink) + THAMTShard = FileType(unixfs.THAMTShard) +) + type LsLink struct { Link *ipld.Link Size uint64 - Type unixfs_pb.Data_DataType + Type FileType Err error } From abebd4e1d81dc18a53db02f740784084c7ab3a05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 4 Feb 2019 18:05:05 +0100 Subject: [PATCH 0217/1212] block put --pin option MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@005752045c872e4dabb17e5c9ba1732f3cf04ea6 This commit was moved from ipfs/boxo@9ea89f38600dab60d9a09740c28d935ef9bfc202 --- core/coreiface/options/block.go | 11 ++++++++++ core/coreiface/tests/block.go | 38 +++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/core/coreiface/options/block.go b/core/coreiface/options/block.go index ea4ae26bb..40dfba79a 100644 --- a/core/coreiface/options/block.go +++ b/core/coreiface/options/block.go @@ -10,6 +10,7 @@ type BlockPutSettings struct { Codec string MhType uint64 MhLength int + Pin bool } type BlockRmSettings struct { @@ -24,6 +25,7 @@ func BlockPutOptions(opts ...BlockPutOption) (*BlockPutSettings, cid.Prefix, err Codec: "", MhType: mh.SHA2_256, MhLength: -1, + Pin: false, } for _, opt := range opts { @@ -105,6 +107,15 @@ func (blockOpts) Hash(mhType uint64, mhLen int) BlockPutOption { } } +// Pin is an option for Block.Put which specifies whether to (recursively) pin +// added blocks +func (blockOpts) Pin(pin bool) BlockPutOption { + return func(settings *BlockPutSettings) error { + settings.Pin = pin + return nil + } +} + // Force is an option for Block.Rm which, when set to true, will ignore // non-existing blocks func (blockOpts) Force(force bool) BlockRmOption { diff --git a/core/coreiface/tests/block.go b/core/coreiface/tests/block.go index 427ad3357..c2ee70a3a 100644 --- a/core/coreiface/tests/block.go +++ b/core/coreiface/tests/block.go @@ -26,6 +26,7 @@ func (tp *provider) TestBlock(t *testing.T) { t.Run("TestBlockGet", tp.TestBlockGet) t.Run("TestBlockRm", tp.TestBlockRm) t.Run("TestBlockStat", tp.TestBlockStat) + t.Run("TestBlockPin", tp.TestBlockPin) } func (tp *provider) TestBlockPut(t *testing.T) { @@ -203,3 +204,40 @@ func (tp *provider) TestBlockStat(t *testing.T) { t.Error("length doesn't match") } } + +func (tp *provider) TestBlockPin(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + api, err := tp.makeAPI(ctx) + if err != nil { + t.Error(err) + } + + _, err = api.Block().Put(ctx, strings.NewReader(`Hello`)) + if err != nil { + t.Fatal(err) + } + + if pins, err := api.Pin().Ls(ctx); err != nil || len(pins) != 0 { + t.Fatal("expected 0 pins") + } + + res, err := api.Block().Put(ctx, strings.NewReader(`Hello`), opt.Block.Pin(true)) + if err != nil { + t.Fatal(err) + } + + pins, err := api.Pin().Ls(ctx) + if err != nil { + return + } + if len(pins) != 1 { + t.Fatal("expected 1 pin") + } + if pins[0].Type() != "recursive" { + t.Error("expected a recursive pin") + } + if pins[0].Path().String() != res.Path().String() { + t.Error("pin path didn't match") + } +} From c3f2970f8a7302344154e6d7fe74485f0dd272c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 4 Feb 2019 19:42:32 +0100 Subject: [PATCH 0218/1212] block: Pin option This commit was moved from ipfs/go-ipfs-http-client@def66919dfbee162595852334468719f57158121 --- client/httpapi/block.go | 1 + 1 file changed, 1 insertion(+) diff --git a/client/httpapi/block.go b/client/httpapi/block.go index f8334a109..24df9629e 100644 --- a/client/httpapi/block.go +++ b/client/httpapi/block.go @@ -53,6 +53,7 @@ func (api *BlockAPI) Put(ctx context.Context, r io.Reader, opts ...caopts.BlockP Option("mhtype", mht). Option("mhlen", options.MhLength). Option("format", options.Codec). + Option("pin", options.Pin). FileBody(r) var out blockStat From af2edd12eb44f477ef2e0dc22ae31a75df645b9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 4 Feb 2019 19:43:00 +0100 Subject: [PATCH 0219/1212] tests: enable filestore This commit was moved from ipfs/go-ipfs-http-client@904e8eeeb1b677d458c819122d91264040120d3b --- client/httpapi/api_test.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/client/httpapi/api_test.go b/client/httpapi/api_test.go index 1acece88c..bf1d6b9b0 100644 --- a/client/httpapi/api_test.go +++ b/client/httpapi/api_test.go @@ -47,6 +47,11 @@ func (NodeProvider) MakeAPISwarm(ctx context.Context, fullIdentity bool, n int) return nil, err } + filestoreArgs := []string{"iptb", "--IPTB_ROOT", dir, "run", fmt.Sprintf("[0-%d]", n-1), "--", "ipfs", "config", "--json", "Experimental.FilestoreEnabled", "true"} + if err := c.Run(filestoreArgs); err != nil { + return nil, err + } + startArgs := []string{"iptb", "--IPTB_ROOT", dir, "start", "-wait", "--", "--enable-pubsub-experiment", "--offline=" + strconv.FormatBool(n == 1)} if err := c.Run(startArgs); err != nil { return nil, err From 75cf2be1026a7f206e61d164342dae4807d36bf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 4 Feb 2019 19:43:26 +0100 Subject: [PATCH 0220/1212] apifile: Implement Seek This commit was moved from ipfs/go-ipfs-http-client@69cc3e8106552605ecfdfa5c6f352996dc6f9497 --- client/httpapi/apifile.go | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/client/httpapi/apifile.go b/client/httpapi/apifile.go index 99ae72059..ec916d8e2 100644 --- a/client/httpapi/apifile.go +++ b/client/httpapi/apifile.go @@ -6,13 +6,15 @@ import ( "fmt" "github.com/ipfs/go-cid" "io" + "io/ioutil" "github.com/ipfs/go-ipfs/core/coreapi/interface" "github.com/ipfs/go-ipfs-files" - unixfspb "github.com/ipfs/go-unixfs/pb" ) +const forwardSeekLimit = 1 << 14 //16k + func (api *UnixfsAPI) Get(ctx context.Context, p iface.Path) (files.Node, error) { if p.Mutable() { // use resolved path in case we are dealing with IPNS / MFS var err error @@ -80,7 +82,24 @@ func (f *apiFile) Read(p []byte) (int, error) { } func (f *apiFile) Seek(offset int64, whence int) (int64, error) { - panic("implement me") //TODO + switch whence { + case io.SeekEnd: + offset = f.size + offset + case io.SeekCurrent: + offset = f.at + offset + } + if f.at == offset { //noop + return offset, nil + } + + if f.at < offset && offset - f.at < forwardSeekLimit { //forward skip + r, err := io.CopyN(ioutil.Discard, f.r, offset - f.at) + + f.at += r + return f.at, err + } + f.at = offset + return f.at, f.reset() } func (f *apiFile) Close() error { @@ -156,17 +175,17 @@ func (it *apiIter) Next() bool { } switch it.cur.Type { - case unixfspb.Data_HAMTShard: + case iface.THAMTShard: fallthrough - case unixfspb.Data_Metadata: + case iface.TMetadata: fallthrough - case unixfspb.Data_Directory: + case iface.TDirectory: it.curFile, err = it.core.getDir(it.ctx, iface.IpfsPath(c), int64(it.cur.Size)) if err != nil { it.err = err return false } - case unixfspb.Data_File: + case iface.TFile: it.curFile, err = it.core.getFile(it.ctx, iface.IpfsPath(c), int64(it.cur.Size)) if err != nil { it.err = err From bb83ccb15feb4854c7bdb4821fbcf90b89f36163 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 4 Feb 2019 19:44:48 +0100 Subject: [PATCH 0221/1212] response: read trailing error headers This commit was moved from ipfs/go-ipfs-http-client@83dfd84ba8bf2341478bb98d437ae1f14fe29e18 --- client/httpapi/response.go | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/client/httpapi/response.go b/client/httpapi/response.go index f6e7f3ab7..745c9a2a9 100644 --- a/client/httpapi/response.go +++ b/client/httpapi/response.go @@ -2,6 +2,7 @@ package httpapi import ( "encoding/json" + "errors" "fmt" "io" "io/ioutil" @@ -13,6 +14,24 @@ import ( files "github.com/ipfs/go-ipfs-files" ) +type trailerReader struct { + resp *http.Response +} + +func (r *trailerReader) Read(b []byte) (int, error) { + n, err := r.resp.Body.Read(b) + if err != nil { + if e := r.resp.Trailer.Get("X-Stream-Error"); e != "" { + err = errors.New(e) + } + } + return n, err +} + +func (r *trailerReader) Close() error { + return r.resp.Body.Close() +} + type Response struct { Output io.ReadCloser Error *Error @@ -56,9 +75,6 @@ type Error struct { func (e *Error) Error() string { var out string - if e.Command != "" { - out = e.Command + ": " - } if e.Code != 0 { out = fmt.Sprintf("%s%d: ", out, e.Code) } @@ -93,7 +109,7 @@ func (r *Request) Send(c *http.Client) (*Response, error) { nresp := new(Response) - nresp.Output = resp.Body + nresp.Output = &trailerReader{resp} if resp.StatusCode >= http.StatusBadRequest { e := &Error{ Command: r.Command, From 88139ddc50e111e39721990bb86bb1c018c488b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 4 Feb 2019 19:45:24 +0100 Subject: [PATCH 0222/1212] dag: Interface updates This commit was moved from ipfs/go-ipfs-http-client@7bea2efb45cba072b4e24c20b46a4372be3a716d --- client/httpapi/api.go | 3 +-- client/httpapi/dag.go | 38 +++++++++++++++++++++++++++++++++----- 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/client/httpapi/api.go b/client/httpapi/api.go index 7d4fbd0e0..2c7a97c99 100644 --- a/client/httpapi/api.go +++ b/client/httpapi/api.go @@ -11,7 +11,6 @@ import ( "github.com/ipfs/go-ipfs/core/coreapi/interface" caopts "github.com/ipfs/go-ipfs/core/coreapi/interface/options" - "github.com/ipfs/go-ipld-format" homedir "github.com/mitchellh/go-homedir" ma "github.com/multiformats/go-multiaddr" manet "github.com/multiformats/go-multiaddr-net" @@ -139,7 +138,7 @@ func (api *HttpApi) Block() iface.BlockAPI { return (*BlockAPI)(api) } -func (api *HttpApi) Dag() format.DAGService { +func (api *HttpApi) Dag() iface.APIDagService { return (*HttpDagServ)(api) } diff --git a/client/httpapi/dag.go b/client/httpapi/dag.go index de2934c2f..eacf631b9 100644 --- a/client/httpapi/dag.go +++ b/client/httpapi/dag.go @@ -15,7 +15,9 @@ import ( "github.com/ipfs/go-ipld-format" ) -type HttpDagServ HttpApi +type httpNodeAdder HttpApi +type HttpDagServ httpNodeAdder +type pinningHttpNodeAdder httpNodeAdder func (api *HttpDagServ) Get(ctx context.Context, c cid.Cid) (format.Node, error) { r, err := api.core().Block().Get(ctx, iface.IpldPath(c)) @@ -56,7 +58,7 @@ func (api *HttpDagServ) GetMany(ctx context.Context, cids []cid.Cid) <-chan *for return out } -func (api *HttpDagServ) Add(ctx context.Context, nd format.Node) error { +func (api *httpNodeAdder) add(ctx context.Context, nd format.Node, pin bool) error { c := nd.Cid() prefix := c.Prefix() format := cid.CodecToStr[prefix.Codec] @@ -65,7 +67,9 @@ func (api *HttpDagServ) Add(ctx context.Context, nd format.Node) error { } stat, err := api.core().Block().Put(ctx, bytes.NewReader(nd.RawData()), - options.Block.Hash(prefix.MhType, prefix.MhLength), options.Block.Format(format)) + options.Block.Hash(prefix.MhType, prefix.MhLength), + options.Block.Format(format), + options.Block.Pin(pin)) if err != nil { return err } @@ -75,16 +79,36 @@ func (api *HttpDagServ) Add(ctx context.Context, nd format.Node) error { return nil } -func (api *HttpDagServ) AddMany(ctx context.Context, nds []format.Node) error { +func (api *httpNodeAdder) addMany(ctx context.Context, nds []format.Node, pin bool) error { for _, nd := range nds { // TODO: optimize - if err := api.Add(ctx, nd); err != nil { + if err := api.add(ctx, nd, pin); err != nil { return err } } return nil } +func (api *HttpDagServ) AddMany(ctx context.Context, nds []format.Node) error { + return (*httpNodeAdder)(api).addMany(ctx, nds, false) +} + +func (api *HttpDagServ) Add(ctx context.Context, nd format.Node) error { + return (*httpNodeAdder)(api).add(ctx, nd, false) +} + +func (api *pinningHttpNodeAdder) Add(ctx context.Context, nd format.Node) error { + return (*httpNodeAdder)(api).add(ctx, nd, true) +} + +func (api *pinningHttpNodeAdder) AddMany(ctx context.Context, nds []format.Node) error { + return (*httpNodeAdder)(api).addMany(ctx, nds, true) +} + +func (api *HttpDagServ) Pinning() format.NodeAdder { + return (*pinningHttpNodeAdder)(api) +} + func (api *HttpDagServ) Remove(ctx context.Context, c cid.Cid) error { return api.core().Block().Rm(ctx, iface.IpldPath(c)) //TODO: should we force rm? } @@ -99,6 +123,10 @@ func (api *HttpDagServ) RemoveMany(ctx context.Context, cids []cid.Cid) error { return nil } +func (api *httpNodeAdder) core() *HttpApi { + return (*HttpApi)(api) +} + func (api *HttpDagServ) core() *HttpApi { return (*HttpApi)(api) } From 93bfcf91cf979b267758c04aa14c6435a687fc36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 4 Feb 2019 19:46:00 +0100 Subject: [PATCH 0223/1212] unixfs: updated ls This commit was moved from ipfs/go-ipfs-http-client@bb8d9d1a60e4161c4cf3a33c468746050f267a12 --- client/httpapi/unixfs.go | 94 ++++++++++++++++++++++++++++++++-------- 1 file changed, 75 insertions(+), 19 deletions(-) diff --git a/client/httpapi/unixfs.go b/client/httpapi/unixfs.go index 7e63d241f..67d05309b 100644 --- a/client/httpapi/unixfs.go +++ b/client/httpapi/unixfs.go @@ -13,7 +13,6 @@ import ( "github.com/ipfs/go-ipfs-files" "github.com/ipfs/go-ipld-format" - unixfspb "github.com/ipfs/go-unixfs/pb" mh "github.com/multiformats/go-multihash" ) @@ -129,7 +128,7 @@ loop: type lsLink struct { Name, Hash string Size uint64 - Type unixfspb.Data_DataType + Type iface.FileType } type lsObject struct { @@ -141,30 +140,87 @@ type lsOutput struct { Objects []lsObject } -func (api *UnixfsAPI) Ls(ctx context.Context, p iface.Path) ([]*format.Link, error) { - var out lsOutput - err := api.core().request("ls", p.String()).Exec(ctx, &out) +func (api *UnixfsAPI) Ls(ctx context.Context, p iface.Path, opts ...caopts.UnixfsLsOption) (<-chan iface.LsLink, error) { + options, err := caopts.UnixfsLsOptions(opts...) if err != nil { return nil, err } - if len(out.Objects) != 1 { - return nil, errors.New("unexpected objects len") + resp, err := api.core().request("ls", p.String()). + Option("resolve-type", options.ResolveChildren). + Option("size", options.ResolveChildren). + Option("stream", true). + Send(ctx) + if err != nil { + return nil, err + } + if resp.Error != nil { + return nil, resp.Error } - links := make([]*format.Link, len(out.Objects[0].Links)) - for i, l := range out.Objects[0].Links { - c, err := cid.Parse(l.Hash) - if err != nil { - return nil, err + dec := json.NewDecoder(resp.Output) + out := make(chan iface.LsLink) + + go func() { + defer resp.Close() + defer close(out) + + for { + var link lsOutput + if err := dec.Decode(&link); err != nil { + if err == io.EOF { + return + } + select { + case out <- iface.LsLink{Err: err}: + case <-ctx.Done(): + } + return + } + + if len(link.Objects) != 1 { + select { + case out <- iface.LsLink{Err: errors.New("unexpected Objects len")}: + case <-ctx.Done(): + } + return + } + + if len(link.Objects[0].Links) != 1 { + select { + case out <- iface.LsLink{Err: errors.New("unexpected Links len")}: + case <-ctx.Done(): + } + return + } + + l0 := link.Objects[0].Links[0] + + c, err := cid.Decode(l0.Hash) + if err != nil { + select { + case out <- iface.LsLink{Err: err}: + case <-ctx.Done(): + } + return + } + + select { + case out <- iface.LsLink{ + Link: &format.Link{ + Cid: c, + Name: l0.Name, + Size: l0.Size, + }, + Size: l0.Size, + Type: l0.Type, + }: + case <-ctx.Done(): + } } - links[i] = &format.Link{ - Name: l.Name, - Size: l.Size, - Cid: c, - } - } - return links, nil + }() + + return out, nil } func (api *UnixfsAPI) core() *HttpApi { From 1bc854bf2169f82d2275232e123adae721b8dc0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 4 Feb 2019 19:53:02 +0100 Subject: [PATCH 0224/1212] pin: handle Rm options This commit was moved from ipfs/go-ipfs-http-client@e85e856ea2841cd3e0cf4cb7b87441539af42bbe --- client/httpapi/pin.go | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/client/httpapi/pin.go b/client/httpapi/pin.go index 1624b7867..237b32329 100644 --- a/client/httpapi/pin.go +++ b/client/httpapi/pin.go @@ -68,8 +68,15 @@ func (api *PinAPI) Ls(ctx context.Context, opts ...caopts.PinLsOption) ([]iface. return pins, nil } -func (api *PinAPI) Rm(ctx context.Context, p iface.Path) error { - return api.core().request("pin/rm", p.String()).Exec(ctx, nil) +func (api *PinAPI) Rm(ctx context.Context, p iface.Path, opts ...caopts.PinRmOption) error { + options, err := caopts.PinRmOptions(opts...) + if err != nil { + return err + } + + return api.core().request("pin/rm", p.String()). + Option("recursive", options.Recursive). + Exec(ctx, nil) } func (api *PinAPI) Update(ctx context.Context, from iface.Path, to iface.Path, opts ...caopts.PinUpdateOption) error { From 6e4a14d89d5e8c88c29b026056606bc57d196499 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 5 Feb 2019 20:20:27 +0100 Subject: [PATCH 0225/1212] coreapi: fix seek test on http impl MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@3291f565631f8ccbb1d09bb71e686265cc00803d This commit was moved from ipfs/boxo@1e59d281dfae25d81b2f2dba9ca6138537c431a6 --- core/coreiface/tests/unixfs.go | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/core/coreiface/tests/unixfs.go b/core/coreiface/tests/unixfs.go index 054461de1..1c21f4fd0 100644 --- a/core/coreiface/tests/unixfs.go +++ b/core/coreiface/tests/unixfs.go @@ -3,6 +3,7 @@ package tests import ( "bytes" "context" + "encoding/hex" "fmt" "io" "io/ioutil" @@ -754,9 +755,13 @@ func (tp *provider) TestLs(t *testing.T) { t.Error(err) } - link := (<-links).Link - if link.Size != 23 { - t.Fatalf("expected size = 23, got %d", link.Size) + linkRes := <-links + if linkRes.Err != nil { + t.Fatal(linkRes.Err) + } + link := linkRes.Link + if linkRes.Size != 15 { + t.Fatalf("expected size = 15, got %d", link.Size) } if link.Name != "name-of-file" { t.Fatalf("expected name = name-of-file, got %s", link.Name) @@ -764,8 +769,11 @@ func (tp *provider) TestLs(t *testing.T) { if link.Cid.String() != "QmX3qQVKxDGz3URVC3861Z3CKtQKGBn6ffXRBBWGMFz9Lr" { t.Fatalf("expected cid = QmX3qQVKxDGz3URVC3861Z3CKtQKGBn6ffXRBBWGMFz9Lr, got %s", link.Cid) } - if _, ok := <-links; ok { + if l, ok := <-links; ok { t.Errorf("didn't expect a second link") + if l.Err != nil { + t.Error(l.Err) + } } } @@ -967,7 +975,7 @@ func (tp *provider) TestGetSeek(t *testing.T) { } orig := make([]byte, dataSize) - if _, err := f.Read(orig); err != nil { + if _, err := io.ReadFull(f, orig); err != nil { t.Fatal(err) } f.Close() @@ -1005,9 +1013,9 @@ func (tp *provider) TestGetSeek(t *testing.T) { if err != nil { t.Fatalf("orig: %s", err) } - r, err := f.Read(buf) + r, err := io.ReadFull(f, buf) switch { - case shouldEof && err != nil && err != io.EOF: + case shouldEof && err != nil && err != io.ErrUnexpectedEOF: fallthrough case !shouldEof && err != nil: t.Fatalf("f: %s", err) @@ -1029,6 +1037,8 @@ func (tp *provider) TestGetSeek(t *testing.T) { t.Fatal("read different amount of data than bytes.Reader") } if !bytes.Equal(buf, origBuf) { + fmt.Fprintf(os.Stderr, "original:\n%s\n", hex.Dump(origBuf)) + fmt.Fprintf(os.Stderr, "got:\n%s\n", hex.Dump(buf)) t.Fatal("data didn't match") } }) @@ -1039,6 +1049,7 @@ func (tp *provider) TestGetSeek(t *testing.T) { test(500, io.SeekCurrent, 10, 10, false) test(350, io.SeekStart, 100, 100, false) test(-123, io.SeekCurrent, 100, 100, false) + test(0, io.SeekStart, int(dataSize), dataSize, false) test(dataSize-50, io.SeekStart, 100, 50, true) test(-5, io.SeekEnd, 100, 5, true) } From c543354b1772323cb2cfbf41c06522297bf27667 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 6 Feb 2019 22:36:30 +0100 Subject: [PATCH 0226/1212] Check for redirects This commit was moved from ipfs/go-ipfs-http-client@19c65db4f0fd1549fc6f224efd868d4f00da997d --- client/httpapi/api.go | 18 +++++++++++++----- client/httpapi/requestbuilder.go | 2 +- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/client/httpapi/api.go b/client/httpapi/api.go index 2c7a97c99..da0836d4a 100644 --- a/client/httpapi/api.go +++ b/client/httpapi/api.go @@ -2,6 +2,7 @@ package httpapi import ( "errors" + "fmt" "io/ioutil" gohttp "net/http" "os" @@ -27,7 +28,7 @@ var ErrNotImplemented = errors.New("not implemented") type HttpApi struct { url string - httpcli *gohttp.Client + httpcli gohttp.Client applyGlobal func(*RequestBuilder) } @@ -50,8 +51,8 @@ func NewPathApi(p string) iface.CoreAPI { return NewApi(a) } -func ApiAddr(p string) ma.Multiaddr { - baseDir, err := homedir.Expand(p) +func ApiAddr(ipfspath string) ma.Multiaddr { + baseDir, err := homedir.Expand(ipfspath) if err != nil { return nil } @@ -99,11 +100,18 @@ func NewApiWithClient(a ma.Multiaddr, c *gohttp.Client) *HttpApi { } } - return &HttpApi{ + api := &HttpApi{ url: url, - httpcli: c, + httpcli: *c, applyGlobal: func(*RequestBuilder) {}, } + + // We don't support redirects. + api.httpcli.CheckRedirect = func(_ *gohttp.Request, _ []*gohttp.Request) error { + return fmt.Errorf("unexpected redirect") + } + + return api } func (api *HttpApi) WithOptions(opts ...caopts.ApiOption) (iface.CoreAPI, error) { diff --git a/client/httpapi/requestbuilder.go b/client/httpapi/requestbuilder.go index 831e6d71c..628ad03cd 100644 --- a/client/httpapi/requestbuilder.go +++ b/client/httpapi/requestbuilder.go @@ -92,7 +92,7 @@ func (r *RequestBuilder) Send(ctx context.Context) (*Response, error) { req.Opts = r.opts req.Headers = r.headers req.Body = r.body - return req.Send(r.shell.httpcli) + return req.Send(&r.shell.httpcli) } // Exec sends the request a request and decodes the response. From be9d4de4d421fd9883404935b23c206e21021829 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Thu, 7 Feb 2019 17:11:29 -0800 Subject: [PATCH 0227/1212] gx: update go-libp2p-peer Switch _back_ to the 0.4.18 style of peer IDs while we figure things out. See https://github.com/libp2p/specs/issues/138. License: MIT Signed-off-by: Steven Allen This commit was moved from ipfs/interface-go-ipfs-core@67fd754fced65b8d75a92217fe265af48822cef1 This commit was moved from ipfs/boxo@132387d33db2093e89e1b97dbe292ba780debf0f --- core/coreiface/dht.go | 4 ++-- core/coreiface/key.go | 2 +- core/coreiface/options/unixfs.go | 2 +- core/coreiface/path.go | 2 +- core/coreiface/pubsub.go | 2 +- core/coreiface/swarm.go | 6 +++--- core/coreiface/tests/name.go | 2 +- core/coreiface/tests/unixfs.go | 6 +++--- core/coreiface/unixfs.go | 2 +- 9 files changed, 14 insertions(+), 14 deletions(-) diff --git a/core/coreiface/dht.go b/core/coreiface/dht.go index ec8bd92c3..94fb3779f 100644 --- a/core/coreiface/dht.go +++ b/core/coreiface/dht.go @@ -5,8 +5,8 @@ import ( "github.com/ipfs/go-ipfs/core/coreapi/interface/options" - pstore "gx/ipfs/QmPiemjiKBC9VA7vZF82m4x1oygtg2c2YVqag8PX7dN1BD/go-libp2p-peerstore" - peer "gx/ipfs/QmY5Grm8pJdiSSVsYxx4uNRgweY72EmYwuSDbRnbFok3iY/go-libp2p-peer" + peer "gx/ipfs/QmPJxxDsX2UbchSHobbYuvz7qnyJTFKvaKMzE2rZWJ4x5B/go-libp2p-peer" + pstore "gx/ipfs/QmQFFp4ntkd4C14sP3FaH9WJyBuetuGUVo6dShNHvnoEvC/go-libp2p-peerstore" ) // DhtAPI specifies the interface to the DHT diff --git a/core/coreiface/key.go b/core/coreiface/key.go index f310c3cc2..69857e613 100644 --- a/core/coreiface/key.go +++ b/core/coreiface/key.go @@ -5,7 +5,7 @@ import ( options "github.com/ipfs/go-ipfs/core/coreapi/interface/options" - "gx/ipfs/QmY5Grm8pJdiSSVsYxx4uNRgweY72EmYwuSDbRnbFok3iY/go-libp2p-peer" + "gx/ipfs/QmPJxxDsX2UbchSHobbYuvz7qnyJTFKvaKMzE2rZWJ4x5B/go-libp2p-peer" ) // Key specifies the interface to Keys in KeyAPI Keystore diff --git a/core/coreiface/options/unixfs.go b/core/coreiface/options/unixfs.go index 015c2dca3..0dd129609 100644 --- a/core/coreiface/options/unixfs.go +++ b/core/coreiface/options/unixfs.go @@ -5,7 +5,7 @@ import ( "fmt" cid "gx/ipfs/QmR8BauakNcBa3RbE4nbQu76PDiJgoQgz8AJdhJuiU4TAw/go-cid" - dag "gx/ipfs/Qmb2UEG2TAeVrEJSjqsZF7Y2he7wRDkrdt6c3bECxwZf4k/go-merkledag" + dag "gx/ipfs/QmUtsx89yiCY6F8mbpP6ecXckiSzCBH7EvkKZuZEHBcr1m/go-merkledag" mh "gx/ipfs/QmerPMzPk1mJVowm8KgmoknWa4yCYvvugMPsgWmDNUvDLW/go-multihash" ) diff --git a/core/coreiface/path.go b/core/coreiface/path.go index b96e0e775..d59a851b4 100644 --- a/core/coreiface/path.go +++ b/core/coreiface/path.go @@ -1,8 +1,8 @@ package iface import ( + ipfspath "gx/ipfs/QmQ3YSqfxunT5QBg6KBVskKyRE26q6hjSMyhpxchpm7jEN/go-path" "gx/ipfs/QmR8BauakNcBa3RbE4nbQu76PDiJgoQgz8AJdhJuiU4TAw/go-cid" - ipfspath "gx/ipfs/QmWqh9oob7ZHQRwU5CdTqpnC8ip8BEkFNrwXRxeNo5Y7vA/go-path" ) //TODO: merge with ipfspath so we don't depend on it diff --git a/core/coreiface/pubsub.go b/core/coreiface/pubsub.go index 867c8adc4..933673826 100644 --- a/core/coreiface/pubsub.go +++ b/core/coreiface/pubsub.go @@ -6,7 +6,7 @@ import ( options "github.com/ipfs/go-ipfs/core/coreapi/interface/options" - peer "gx/ipfs/QmY5Grm8pJdiSSVsYxx4uNRgweY72EmYwuSDbRnbFok3iY/go-libp2p-peer" + peer "gx/ipfs/QmPJxxDsX2UbchSHobbYuvz7qnyJTFKvaKMzE2rZWJ4x5B/go-libp2p-peer" ) // PubSubSubscription is an active PubSub subscription diff --git a/core/coreiface/swarm.go b/core/coreiface/swarm.go index 83e207282..3af078f17 100644 --- a/core/coreiface/swarm.go +++ b/core/coreiface/swarm.go @@ -6,9 +6,9 @@ import ( "time" ma "gx/ipfs/QmNTCey11oxhb1AxDnQBRHtdhap6Ctud872NjAYPYYXPuc/go-multiaddr" - net "gx/ipfs/QmNgLg1NTw37iWbYPKcyK85YJ9Whs1MkPtJwhfqbNYAyKg/go-libp2p-net" - pstore "gx/ipfs/QmPiemjiKBC9VA7vZF82m4x1oygtg2c2YVqag8PX7dN1BD/go-libp2p-peerstore" - "gx/ipfs/QmY5Grm8pJdiSSVsYxx4uNRgweY72EmYwuSDbRnbFok3iY/go-libp2p-peer" + "gx/ipfs/QmPJxxDsX2UbchSHobbYuvz7qnyJTFKvaKMzE2rZWJ4x5B/go-libp2p-peer" + pstore "gx/ipfs/QmQFFp4ntkd4C14sP3FaH9WJyBuetuGUVo6dShNHvnoEvC/go-libp2p-peerstore" + net "gx/ipfs/QmZ7cBWUXkyWTMN4qH6NGoyMVs7JugyFChBNP4ZUp5rJHH/go-libp2p-net" "gx/ipfs/QmZNkThpqfVXs9GNbexPrfBbXSLNYeKrE7jwFM2oqHbyqN/go-libp2p-protocol" ) diff --git a/core/coreiface/tests/name.go b/core/coreiface/tests/name.go index 8690f22c3..8d87bd495 100644 --- a/core/coreiface/tests/name.go +++ b/core/coreiface/tests/name.go @@ -8,7 +8,7 @@ import ( "testing" "time" - ipath "gx/ipfs/QmWqh9oob7ZHQRwU5CdTqpnC8ip8BEkFNrwXRxeNo5Y7vA/go-path" + ipath "gx/ipfs/QmQ3YSqfxunT5QBg6KBVskKyRE26q6hjSMyhpxchpm7jEN/go-path" "gx/ipfs/QmaXvvAVAQ5ABqM5xtjYmV85xmN5MkWAZsX9H9Fwo4FVXp/go-ipfs-files" coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface" diff --git a/core/coreiface/tests/unixfs.go b/core/coreiface/tests/unixfs.go index 1c21f4fd0..f5ce85b78 100644 --- a/core/coreiface/tests/unixfs.go +++ b/core/coreiface/tests/unixfs.go @@ -18,12 +18,12 @@ import ( coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface" "github.com/ipfs/go-ipfs/core/coreapi/interface/options" - "gx/ipfs/QmQ1JnYpnzkaurjW1yxkQxC2w3K1PorNE1nv1vaP5Le7sq/go-unixfs" - "gx/ipfs/QmQ1JnYpnzkaurjW1yxkQxC2w3K1PorNE1nv1vaP5Le7sq/go-unixfs/importer/helpers" "gx/ipfs/QmR8BauakNcBa3RbE4nbQu76PDiJgoQgz8AJdhJuiU4TAw/go-cid" cbor "gx/ipfs/QmRZxJ7oybgnnwriuRub9JXp5YdFM9wiGSyRq38QC7swpS/go-ipld-cbor" + mdag "gx/ipfs/QmUtsx89yiCY6F8mbpP6ecXckiSzCBH7EvkKZuZEHBcr1m/go-merkledag" + "gx/ipfs/QmZArMcsVDsXdcLbUx4844CuqKXBpbxdeiryM4cnmGTNRq/go-unixfs" + "gx/ipfs/QmZArMcsVDsXdcLbUx4844CuqKXBpbxdeiryM4cnmGTNRq/go-unixfs/importer/helpers" "gx/ipfs/QmaXvvAVAQ5ABqM5xtjYmV85xmN5MkWAZsX9H9Fwo4FVXp/go-ipfs-files" - mdag "gx/ipfs/Qmb2UEG2TAeVrEJSjqsZF7Y2he7wRDkrdt6c3bECxwZf4k/go-merkledag" mh "gx/ipfs/QmerPMzPk1mJVowm8KgmoknWa4yCYvvugMPsgWmDNUvDLW/go-multihash" ) diff --git a/core/coreiface/unixfs.go b/core/coreiface/unixfs.go index 1fb07638f..8e559022c 100644 --- a/core/coreiface/unixfs.go +++ b/core/coreiface/unixfs.go @@ -4,8 +4,8 @@ import ( "context" "github.com/ipfs/go-ipfs/core/coreapi/interface/options" - "gx/ipfs/QmQ1JnYpnzkaurjW1yxkQxC2w3K1PorNE1nv1vaP5Le7sq/go-unixfs" ipld "gx/ipfs/QmRL22E4paat7ky7vx9MLpR97JHHbFPrg3ytFQw6qp1y1s/go-ipld-format" + "gx/ipfs/QmZArMcsVDsXdcLbUx4844CuqKXBpbxdeiryM4cnmGTNRq/go-unixfs" "gx/ipfs/QmaXvvAVAQ5ABqM5xtjYmV85xmN5MkWAZsX9H9Fwo4FVXp/go-ipfs-files" ) From 23d84ed3ef15cb86a8c41d0db2db1007d650414f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 8 Feb 2019 17:58:56 +0100 Subject: [PATCH 0228/1212] coreapi: cleanup coredag references in interface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@c3fa814784e5a96d5baeb5722bc51da7750a09ce This commit was moved from ipfs/boxo@d15daa504fd1884c0e2a9c57ae3ae42343ec482e --- core/coreiface/tests/dag.go | 53 ++++++++++++++++++------------------ core/coreiface/tests/path.go | 32 ++++++++++++---------- core/coreiface/tests/pin.go | 22 ++++++++------- 3 files changed, 56 insertions(+), 51 deletions(-) diff --git a/core/coreiface/tests/dag.go b/core/coreiface/tests/dag.go index 10fab125a..4decfebb4 100644 --- a/core/coreiface/tests/dag.go +++ b/core/coreiface/tests/dag.go @@ -8,8 +8,9 @@ import ( "testing" coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface" - coredag "github.com/ipfs/go-ipfs/core/coredag" + ipld "gx/ipfs/QmRL22E4paat7ky7vx9MLpR97JHHbFPrg3ytFQw6qp1y1s/go-ipld-format" + ipldcbor "gx/ipfs/QmRZxJ7oybgnnwriuRub9JXp5YdFM9wiGSyRq38QC7swpS/go-ipld-cbor" mh "gx/ipfs/QmerPMzPk1mJVowm8KgmoknWa4yCYvvugMPsgWmDNUvDLW/go-multihash" ) @@ -46,18 +47,18 @@ func (tp *provider) TestPut(t *testing.T) { t.Error(err) } - nds, err := coredag.ParseInputs("json", "dag-cbor", strings.NewReader(`"Hello"`), math.MaxUint64, -1) + nd, err := ipldcbor.FromJSON(strings.NewReader(`"Hello"`), math.MaxUint64, -1) if err != nil { t.Error(err) } - err = api.Dag().Add(ctx, nds[0]) + err = api.Dag().Add(ctx, nd) if err != nil { t.Fatal(err) } - if nds[0].Cid().String() != "zdpuAqckYF3ToF3gcJNxPZXmnmGuXd3gxHCXhq81HGxBejEvv" { - t.Errorf("got wrong cid: %s", nds[0].Cid().String()) + if nd.Cid().String() != "zdpuAqckYF3ToF3gcJNxPZXmnmGuXd3gxHCXhq81HGxBejEvv" { + t.Errorf("got wrong cid: %s", nd.Cid().String()) } } @@ -69,18 +70,18 @@ func (tp *provider) TestPutWithHash(t *testing.T) { t.Error(err) } - nds, err := coredag.ParseInputs("json", "dag-cbor", strings.NewReader(`"Hello"`), mh.ID, -1) + nd, err := ipldcbor.FromJSON(strings.NewReader(`"Hello"`), mh.ID, -1) if err != nil { t.Error(err) } - err = api.Dag().Add(ctx, nds[0]) + err = api.Dag().Add(ctx, nd) if err != nil { t.Fatal(err) } - if nds[0].Cid().String() != "z5hRLNd2sv4z1c" { - t.Errorf("got wrong cid: %s", nds[0].Cid().String()) + if nd.Cid().String() != "z5hRLNd2sv4z1c" { + t.Errorf("got wrong cid: %s", nd.Cid().String()) } } @@ -92,27 +93,27 @@ func (tp *provider) TestDagPath(t *testing.T) { t.Error(err) } - snds, err := coredag.ParseInputs("json", "dag-cbor", strings.NewReader(`"foo"`), math.MaxUint64, -1) + snd, err := ipldcbor.FromJSON(strings.NewReader(`"foo"`), math.MaxUint64, -1) if err != nil { t.Error(err) } - err = api.Dag().Add(ctx, snds[0]) + err = api.Dag().Add(ctx, snd) if err != nil { t.Fatal(err) } - nds, err := coredag.ParseInputs("json", "dag-cbor", strings.NewReader(`{"lnk": {"/": "`+snds[0].Cid().String()+`"}}`), math.MaxUint64, -1) + nd, err := ipldcbor.FromJSON(strings.NewReader(`{"lnk": {"/": "`+snd.Cid().String()+`"}}`), math.MaxUint64, -1) if err != nil { t.Error(err) } - err = api.Dag().Add(ctx, nds[0]) + err = api.Dag().Add(ctx, nd) if err != nil { t.Fatal(err) } - p, err := coreiface.ParsePath(path.Join(nds[0].Cid().String(), "lnk")) + p, err := coreiface.ParsePath(path.Join(nd.Cid().String(), "lnk")) if err != nil { t.Error(err) } @@ -122,13 +123,13 @@ func (tp *provider) TestDagPath(t *testing.T) { t.Error(err) } - nd, err := api.Dag().Get(ctx, rp.Cid()) + ndd, err := api.Dag().Get(ctx, rp.Cid()) if err != nil { t.Error(err) } - if nd.Cid().String() != snds[0].Cid().String() { - t.Errorf("got unexpected cid %s, expected %s", nd.Cid().String(), snds[0].Cid().String()) + if nd.Cid().String() != snd.Cid().String() { + t.Errorf("got unexpected cid %s, expected %s", ndd.Cid().String(), snd.Cid().String()) } } @@ -140,17 +141,17 @@ func (tp *provider) TestTree(t *testing.T) { t.Error(err) } - nds, err := coredag.ParseInputs("json", "dag-cbor", strings.NewReader(`{"a": 123, "b": "foo", "c": {"d": 321, "e": 111}}`), math.MaxUint64, -1) + nd, err := ipldcbor.FromJSON(strings.NewReader(`{"a": 123, "b": "foo", "c": {"d": 321, "e": 111}}`), math.MaxUint64, -1) if err != nil { t.Error(err) } - err = api.Dag().Add(ctx, nds[0]) + err = api.Dag().Add(ctx, nd) if err != nil { t.Fatal(err) } - res, err := api.Dag().Get(ctx, nds[0].Cid()) + res, err := api.Dag().Get(ctx, nd.Cid()) if err != nil { t.Error(err) } @@ -175,25 +176,25 @@ func (tp *provider) TestBatch(t *testing.T) { t.Error(err) } - nds, err := coredag.ParseInputs("json", "dag-cbor", strings.NewReader(`"Hello"`), math.MaxUint64, -1) + nd, err := ipldcbor.FromJSON(strings.NewReader(`"Hello"`), math.MaxUint64, -1) if err != nil { t.Error(err) } - if nds[0].Cid().String() != "zdpuAqckYF3ToF3gcJNxPZXmnmGuXd3gxHCXhq81HGxBejEvv" { - t.Errorf("got wrong cid: %s", nds[0].Cid().String()) + if nd.Cid().String() != "zdpuAqckYF3ToF3gcJNxPZXmnmGuXd3gxHCXhq81HGxBejEvv" { + t.Errorf("got wrong cid: %s", nd.Cid().String()) } - _, err = api.Dag().Get(ctx, nds[0].Cid()) + _, err = api.Dag().Get(ctx, nd.Cid()) if err == nil || !strings.Contains(err.Error(), "not found") { t.Error(err) } - if err := api.Dag().AddMany(ctx, nds); err != nil { + if err := api.Dag().AddMany(ctx, []ipld.Node{nd}); err != nil { t.Error(err) } - _, err = api.Dag().Get(ctx, nds[0].Cid()) + _, err = api.Dag().Get(ctx, nd.Cid()) if err != nil { t.Error(err) } diff --git a/core/coreiface/tests/path.go b/core/coreiface/tests/path.go index e7df6f1fb..5594cf0da 100644 --- a/core/coreiface/tests/path.go +++ b/core/coreiface/tests/path.go @@ -8,7 +8,8 @@ import ( coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface" "github.com/ipfs/go-ipfs/core/coreapi/interface/options" - "github.com/ipfs/go-ipfs/core/coredag" + + ipldcbor "gx/ipfs/QmRZxJ7oybgnnwriuRub9JXp5YdFM9wiGSyRq38QC7swpS/go-ipld-cbor" ) func (tp *provider) TestPath(t *testing.T) { @@ -37,7 +38,8 @@ func (tp *provider) TestMutablePath(t *testing.T) { t.Error("expected /ipld path to be immutable") } - // get self /ipns path + // get self /ipns path ipldcbor "gx/ipfs/QmRZxJ7oybgnnwriuRub9JXp5YdFM9wiGSyRq38QC7swpS/go-ipld-cbor" + if api.Key() == nil { t.Fatal(".Key not implemented") } @@ -64,16 +66,16 @@ func (tp *provider) TestPathRemainder(t *testing.T) { t.Fatal(".Dag not implemented") } - nds, err := coredag.ParseInputs("json", "dag-cbor", strings.NewReader(`{"foo": {"bar": "baz"}}`), math.MaxUint64, -1) + nd, err := ipldcbor.FromJSON(strings.NewReader(`{"foo": {"bar": "baz"}}`), math.MaxUint64, -1) if err != nil { t.Error(err) } - if err := api.Dag().AddMany(ctx, nds); err != nil { + if err := api.Dag().Add(ctx, nd); err != nil { t.Fatal(err) } - p1, err := coreiface.ParsePath(nds[0].String() + "/foo/bar") + p1, err := coreiface.ParsePath(nd.String() + "/foo/bar") if err != nil { t.Error(err) } @@ -100,16 +102,16 @@ func (tp *provider) TestEmptyPathRemainder(t *testing.T) { t.Fatal(".Dag not implemented") } - nds, err := coredag.ParseInputs("json", "dag-cbor", strings.NewReader(`{"foo": {"bar": "baz"}}`), math.MaxUint64, -1) + nd, err := ipldcbor.FromJSON(strings.NewReader(`{"foo": {"bar": "baz"}}`), math.MaxUint64, -1) if err != nil { t.Error(err) } - if err := api.Dag().AddMany(ctx, nds); err != nil { + if err := api.Dag().Add(ctx, nd); err != nil { t.Fatal(err) } - p1, err := coreiface.ParsePath(nds[0].Cid().String()) + p1, err := coreiface.ParsePath(nd.Cid().String()) if err != nil { t.Error(err) } @@ -136,16 +138,16 @@ func (tp *provider) TestInvalidPathRemainder(t *testing.T) { t.Fatal(".Dag not implemented") } - nds, err := coredag.ParseInputs("json", "dag-cbor", strings.NewReader(`{"foo": {"bar": "baz"}}`), math.MaxUint64, -1) + nd, err := ipldcbor.FromJSON(strings.NewReader(`{"foo": {"bar": "baz"}}`), math.MaxUint64, -1) if err != nil { t.Error(err) } - if err := api.Dag().AddMany(ctx, nds); err != nil { + if err := api.Dag().Add(ctx, nd); err != nil { t.Fatal(err) } - p1, err := coreiface.ParsePath("/ipld/" + nds[0].Cid().String() + "/bar/baz") + p1, err := coreiface.ParsePath("/ipld/" + nd.Cid().String() + "/bar/baz") if err != nil { t.Error(err) } @@ -177,16 +179,16 @@ func (tp *provider) TestPathRoot(t *testing.T) { t.Fatal(".Dag not implemented") } - nds, err := coredag.ParseInputs("json", "dag-cbor", strings.NewReader(`{"foo": {"/": "`+blk.Path().Cid().String()+`"}}`), math.MaxUint64, -1) + nd, err := ipldcbor.FromJSON(strings.NewReader(`{"foo": {"/": "`+blk.Path().Cid().String()+`"}}`), math.MaxUint64, -1) if err != nil { t.Error(err) } - if err := api.Dag().AddMany(ctx, nds); err != nil { + if err := api.Dag().Add(ctx, nd); err != nil { t.Fatal(err) } - p1, err := coreiface.ParsePath("/ipld/" + nds[0].Cid().String() + "/foo") + p1, err := coreiface.ParsePath("/ipld/" + nd.Cid().String() + "/foo") if err != nil { t.Error(err) } @@ -196,7 +198,7 @@ func (tp *provider) TestPathRoot(t *testing.T) { t.Fatal(err) } - if rp.Root().String() != nds[0].Cid().String() { + if rp.Root().String() != nd.Cid().String() { t.Error("unexpected path root") } diff --git a/core/coreiface/tests/pin.go b/core/coreiface/tests/pin.go index 250799222..35c913618 100644 --- a/core/coreiface/tests/pin.go +++ b/core/coreiface/tests/pin.go @@ -8,7 +8,9 @@ import ( "github.com/ipfs/go-ipfs/core/coreapi/interface" opt "github.com/ipfs/go-ipfs/core/coreapi/interface/options" - "github.com/ipfs/go-ipfs/core/coredag" + + ipld "gx/ipfs/QmRL22E4paat7ky7vx9MLpR97JHHbFPrg3ytFQw6qp1y1s/go-ipld-format" + ipldcbor "gx/ipfs/QmRZxJ7oybgnnwriuRub9JXp5YdFM9wiGSyRq38QC7swpS/go-ipld-cbor" ) func (tp *provider) TestPin(t *testing.T) { @@ -111,26 +113,26 @@ func (tp *provider) TestPinRecursive(t *testing.T) { t.Error(err) } - nd2, err := coredag.ParseInputs("json", "dag-cbor", strings.NewReader(`{"lnk": {"/": "`+p0.Cid().String()+`"}}`), math.MaxUint64, -1) + nd2, err := ipldcbor.FromJSON(strings.NewReader(`{"lnk": {"/": "`+p0.Cid().String()+`"}}`), math.MaxUint64, -1) if err != nil { t.Error(err) } - nd3, err := coredag.ParseInputs("json", "dag-cbor", strings.NewReader(`{"lnk": {"/": "`+p1.Cid().String()+`"}}`), math.MaxUint64, -1) + nd3, err := ipldcbor.FromJSON(strings.NewReader(`{"lnk": {"/": "`+p1.Cid().String()+`"}}`), math.MaxUint64, -1) if err != nil { t.Error(err) } - if err := api.Dag().AddMany(ctx, append(nd2, nd3...)); err != nil { + if err := api.Dag().AddMany(ctx, []ipld.Node{nd2, nd3}); err != nil { t.Fatal(err) } - err = api.Pin().Add(ctx, iface.IpldPath(nd2[0].Cid())) + err = api.Pin().Add(ctx, iface.IpldPath(nd2.Cid())) if err != nil { t.Error(err) } - err = api.Pin().Add(ctx, iface.IpldPath(nd3[0].Cid()), opt.Pin.Recursive(false)) + err = api.Pin().Add(ctx, iface.IpldPath(nd3.Cid()), opt.Pin.Recursive(false)) if err != nil { t.Error(err) } @@ -153,8 +155,8 @@ func (tp *provider) TestPinRecursive(t *testing.T) { t.Errorf("unexpected pin list len: %d", len(list)) } - if list[0].Path().String() != iface.IpldPath(nd3[0].Cid()).String() { - t.Errorf("unexpected path, %s != %s", list[0].Path().String(), iface.IpfsPath(nd2[0].Cid()).String()) + if list[0].Path().String() != iface.IpldPath(nd3.Cid()).String() { + t.Errorf("unexpected path, %s != %s", list[0].Path().String(), iface.IpfsPath(nd2.Cid()).String()) } list, err = api.Pin().Ls(ctx, opt.Pin.Type.Recursive()) @@ -166,8 +168,8 @@ func (tp *provider) TestPinRecursive(t *testing.T) { t.Errorf("unexpected pin list len: %d", len(list)) } - if list[0].Path().String() != iface.IpldPath(nd2[0].Cid()).String() { - t.Errorf("unexpected path, %s != %s", list[0].Path().String(), iface.IpldPath(nd3[0].Cid()).String()) + if list[0].Path().String() != iface.IpldPath(nd2.Cid()).String() { + t.Errorf("unexpected path, %s != %s", list[0].Path().String(), iface.IpldPath(nd3.Cid()).String()) } list, err = api.Pin().Ls(ctx, opt.Pin.Type.Indirect()) From 97c433323baad09ba2dbcea901cd3acc5bbdc9d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 8 Feb 2019 19:23:01 +0100 Subject: [PATCH 0229/1212] coreapi: move namesys options to coreapi MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@263199d56ec6e7f2dab7c8619b75e2a6fbcf5f15 This commit was moved from ipfs/boxo@a2f6e434b94663fc953c37e74156ee27b8ab73fe --- core/coreiface/options/name.go | 2 +- core/coreiface/options/namesys/opts.go | 74 ++++++++++++++++++++++++++ 2 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 core/coreiface/options/namesys/opts.go diff --git a/core/coreiface/options/name.go b/core/coreiface/options/name.go index e2a0fc164..e07ef8a59 100644 --- a/core/coreiface/options/name.go +++ b/core/coreiface/options/name.go @@ -3,7 +3,7 @@ package options import ( "time" - ropts "github.com/ipfs/go-ipfs/namesys/opts" + ropts "github.com/ipfs/go-ipfs/core/coreapi/interface/options/namesys" ) const ( diff --git a/core/coreiface/options/namesys/opts.go b/core/coreiface/options/namesys/opts.go new file mode 100644 index 000000000..ee2bd5ac2 --- /dev/null +++ b/core/coreiface/options/namesys/opts.go @@ -0,0 +1,74 @@ +package nsopts + +import ( + "time" +) + +const ( + // DefaultDepthLimit is the default depth limit used by Resolve. + DefaultDepthLimit = 32 + + // UnlimitedDepth allows infinite recursion in Resolve. You + // probably don't want to use this, but it's here if you absolutely + // trust resolution to eventually complete and can't put an upper + // limit on how many steps it will take. + UnlimitedDepth = 0 +) + +// ResolveOpts specifies options for resolving an IPNS path +type ResolveOpts struct { + // Recursion depth limit + Depth uint + // The number of IPNS records to retrieve from the DHT + // (the best record is selected from this set) + DhtRecordCount uint + // The amount of time to wait for DHT records to be fetched + // and verified. A zero value indicates that there is no explicit + // timeout (although there is an implicit timeout due to dial + // timeouts within the DHT) + DhtTimeout time.Duration +} + +// DefaultResolveOpts returns the default options for resolving +// an IPNS path +func DefaultResolveOpts() ResolveOpts { + return ResolveOpts{ + Depth: DefaultDepthLimit, + DhtRecordCount: 16, + DhtTimeout: time.Minute, + } +} + +// ResolveOpt is used to set an option +type ResolveOpt func(*ResolveOpts) + +// Depth is the recursion depth limit +func Depth(depth uint) ResolveOpt { + return func(o *ResolveOpts) { + o.Depth = depth + } +} + +// DhtRecordCount is the number of IPNS records to retrieve from the DHT +func DhtRecordCount(count uint) ResolveOpt { + return func(o *ResolveOpts) { + o.DhtRecordCount = count + } +} + +// DhtTimeout is the amount of time to wait for DHT records to be fetched +// and verified. A zero value indicates that there is no explicit timeout +func DhtTimeout(timeout time.Duration) ResolveOpt { + return func(o *ResolveOpts) { + o.DhtTimeout = timeout + } +} + +// ProcessOpts converts an array of ResolveOpt into a ResolveOpts object +func ProcessOpts(opts []ResolveOpt) ResolveOpts { + rsopts := DefaultResolveOpts() + for _, option := range opts { + option(&rsopts) + } + return rsopts +} From 46dbdf4d64dee7706d3c22804179bdfb2080a8c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 8 Feb 2019 20:38:21 +0100 Subject: [PATCH 0230/1212] coreapi: fix failing dag test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera This commit was moved from ipfs/interface-go-ipfs-core@268b4fdbf1604d9296e09fe2cf1cf3328f498898 This commit was moved from ipfs/boxo@ea6b30e219991d9a4125537ac16e3e50df0650d8 --- core/coreiface/tests/dag.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/coreiface/tests/dag.go b/core/coreiface/tests/dag.go index 4decfebb4..cf332027c 100644 --- a/core/coreiface/tests/dag.go +++ b/core/coreiface/tests/dag.go @@ -128,7 +128,7 @@ func (tp *provider) TestDagPath(t *testing.T) { t.Error(err) } - if nd.Cid().String() != snd.Cid().String() { + if ndd.Cid().String() != snd.Cid().String() { t.Errorf("got unexpected cid %s, expected %s", ndd.Cid().String(), snd.Cid().String()) } } From af23d0324bce51a7e51a56f6f514bb84d519664c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Sat, 9 Feb 2019 01:15:09 +0100 Subject: [PATCH 0231/1212] Update imports This commit was moved from ipfs/interface-go-ipfs-core@515a114be219fdfdeed3f26c56c91fb7477439bb This commit was moved from ipfs/boxo@5c537a46d37b548c6a830a7ea9ca8aca833e9acc --- core/coreiface/block.go | 2 +- core/coreiface/coreapi.go | 2 +- core/coreiface/dht.go | 2 +- core/coreiface/key.go | 2 +- core/coreiface/name.go | 2 +- core/coreiface/object.go | 2 +- core/coreiface/options/name.go | 2 +- core/coreiface/pin.go | 2 +- core/coreiface/pubsub.go | 2 +- core/coreiface/tests/api.go | 2 +- core/coreiface/tests/block.go | 4 ++-- core/coreiface/tests/dag.go | 2 +- core/coreiface/tests/dht.go | 4 ++-- core/coreiface/tests/key.go | 4 ++-- core/coreiface/tests/name.go | 4 ++-- core/coreiface/tests/object.go | 4 ++-- core/coreiface/tests/path.go | 4 ++-- core/coreiface/tests/pin.go | 4 ++-- core/coreiface/tests/pubsub.go | 5 +++-- core/coreiface/tests/unixfs.go | 4 ++-- core/coreiface/unixfs.go | 2 +- 21 files changed, 31 insertions(+), 30 deletions(-) diff --git a/core/coreiface/block.go b/core/coreiface/block.go index b99b05fdb..587ad339f 100644 --- a/core/coreiface/block.go +++ b/core/coreiface/block.go @@ -4,7 +4,7 @@ import ( "context" "io" - options "github.com/ipfs/go-ipfs/core/coreapi/interface/options" + options "github.com/ipfs/interface-go-ipfs-core/options" ) // BlockStat contains information about a block diff --git a/core/coreiface/coreapi.go b/core/coreiface/coreapi.go index d26ec4f7d..651af8bf0 100644 --- a/core/coreiface/coreapi.go +++ b/core/coreiface/coreapi.go @@ -5,7 +5,7 @@ package iface import ( "context" - "github.com/ipfs/go-ipfs/core/coreapi/interface/options" + "github.com/ipfs/interface-go-ipfs-core/options" ipld "gx/ipfs/QmRL22E4paat7ky7vx9MLpR97JHHbFPrg3ytFQw6qp1y1s/go-ipld-format" ) diff --git a/core/coreiface/dht.go b/core/coreiface/dht.go index 94fb3779f..b3f7879e3 100644 --- a/core/coreiface/dht.go +++ b/core/coreiface/dht.go @@ -3,7 +3,7 @@ package iface import ( "context" - "github.com/ipfs/go-ipfs/core/coreapi/interface/options" + "github.com/ipfs/interface-go-ipfs-core/options" peer "gx/ipfs/QmPJxxDsX2UbchSHobbYuvz7qnyJTFKvaKMzE2rZWJ4x5B/go-libp2p-peer" pstore "gx/ipfs/QmQFFp4ntkd4C14sP3FaH9WJyBuetuGUVo6dShNHvnoEvC/go-libp2p-peerstore" diff --git a/core/coreiface/key.go b/core/coreiface/key.go index 69857e613..154f82b66 100644 --- a/core/coreiface/key.go +++ b/core/coreiface/key.go @@ -3,7 +3,7 @@ package iface import ( "context" - options "github.com/ipfs/go-ipfs/core/coreapi/interface/options" + options "github.com/ipfs/interface-go-ipfs-core/options" "gx/ipfs/QmPJxxDsX2UbchSHobbYuvz7qnyJTFKvaKMzE2rZWJ4x5B/go-libp2p-peer" ) diff --git a/core/coreiface/name.go b/core/coreiface/name.go index a02bc0787..51b005b7e 100644 --- a/core/coreiface/name.go +++ b/core/coreiface/name.go @@ -4,7 +4,7 @@ import ( "context" "errors" - options "github.com/ipfs/go-ipfs/core/coreapi/interface/options" + options "github.com/ipfs/interface-go-ipfs-core/options" ) var ErrResolveFailed = errors.New("could not resolve name") diff --git a/core/coreiface/object.go b/core/coreiface/object.go index 2ed357cb6..28613aaa0 100644 --- a/core/coreiface/object.go +++ b/core/coreiface/object.go @@ -4,7 +4,7 @@ import ( "context" "io" - options "github.com/ipfs/go-ipfs/core/coreapi/interface/options" + options "github.com/ipfs/interface-go-ipfs-core/options" cid "gx/ipfs/QmR8BauakNcBa3RbE4nbQu76PDiJgoQgz8AJdhJuiU4TAw/go-cid" ipld "gx/ipfs/QmRL22E4paat7ky7vx9MLpR97JHHbFPrg3ytFQw6qp1y1s/go-ipld-format" diff --git a/core/coreiface/options/name.go b/core/coreiface/options/name.go index e07ef8a59..59aaf2ca3 100644 --- a/core/coreiface/options/name.go +++ b/core/coreiface/options/name.go @@ -3,7 +3,7 @@ package options import ( "time" - ropts "github.com/ipfs/go-ipfs/core/coreapi/interface/options/namesys" + ropts "github.com/ipfs/interface-go-ipfs-core/options/namesys" ) const ( diff --git a/core/coreiface/pin.go b/core/coreiface/pin.go index 6e13def8f..6a7dab413 100644 --- a/core/coreiface/pin.go +++ b/core/coreiface/pin.go @@ -3,7 +3,7 @@ package iface import ( "context" - options "github.com/ipfs/go-ipfs/core/coreapi/interface/options" + options "github.com/ipfs/interface-go-ipfs-core/options" ) // Pin holds information about pinned resource diff --git a/core/coreiface/pubsub.go b/core/coreiface/pubsub.go index 933673826..40cea689a 100644 --- a/core/coreiface/pubsub.go +++ b/core/coreiface/pubsub.go @@ -4,7 +4,7 @@ import ( "context" "io" - options "github.com/ipfs/go-ipfs/core/coreapi/interface/options" + options "github.com/ipfs/interface-go-ipfs-core/options" peer "gx/ipfs/QmPJxxDsX2UbchSHobbYuvz7qnyJTFKvaKMzE2rZWJ4x5B/go-libp2p-peer" ) diff --git a/core/coreiface/tests/api.go b/core/coreiface/tests/api.go index 7a4bd7386..5e7c1f541 100644 --- a/core/coreiface/tests/api.go +++ b/core/coreiface/tests/api.go @@ -6,7 +6,7 @@ import ( "testing" "time" - coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface" + coreiface "github.com/ipfs/interface-go-ipfs-core" ) var apiNotImplemented = errors.New("api not implemented") diff --git a/core/coreiface/tests/block.go b/core/coreiface/tests/block.go index c2ee70a3a..2e0a84b40 100644 --- a/core/coreiface/tests/block.go +++ b/core/coreiface/tests/block.go @@ -6,8 +6,8 @@ import ( "strings" "testing" - coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface" - opt "github.com/ipfs/go-ipfs/core/coreapi/interface/options" + coreiface "github.com/ipfs/interface-go-ipfs-core" + opt "github.com/ipfs/interface-go-ipfs-core/options" mh "gx/ipfs/QmerPMzPk1mJVowm8KgmoknWa4yCYvvugMPsgWmDNUvDLW/go-multihash" ) diff --git a/core/coreiface/tests/dag.go b/core/coreiface/tests/dag.go index cf332027c..9e0bc34ba 100644 --- a/core/coreiface/tests/dag.go +++ b/core/coreiface/tests/dag.go @@ -7,7 +7,7 @@ import ( "strings" "testing" - coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface" + coreiface "github.com/ipfs/interface-go-ipfs-core" ipld "gx/ipfs/QmRL22E4paat7ky7vx9MLpR97JHHbFPrg3ytFQw6qp1y1s/go-ipld-format" ipldcbor "gx/ipfs/QmRZxJ7oybgnnwriuRub9JXp5YdFM9wiGSyRq38QC7swpS/go-ipld-cbor" diff --git a/core/coreiface/tests/dht.go b/core/coreiface/tests/dht.go index d2eae1af4..1793cd738 100644 --- a/core/coreiface/tests/dht.go +++ b/core/coreiface/tests/dht.go @@ -5,8 +5,8 @@ import ( "io" "testing" - "github.com/ipfs/go-ipfs/core/coreapi/interface" - "github.com/ipfs/go-ipfs/core/coreapi/interface/options" + "github.com/ipfs/interface-go-ipfs-core" + "github.com/ipfs/interface-go-ipfs-core/options" ) func (tp *provider) TestDht(t *testing.T) { diff --git a/core/coreiface/tests/key.go b/core/coreiface/tests/key.go index 66011f99f..dbbfce059 100644 --- a/core/coreiface/tests/key.go +++ b/core/coreiface/tests/key.go @@ -5,8 +5,8 @@ import ( "strings" "testing" - "github.com/ipfs/go-ipfs/core/coreapi/interface" - opt "github.com/ipfs/go-ipfs/core/coreapi/interface/options" + "github.com/ipfs/interface-go-ipfs-core" + opt "github.com/ipfs/interface-go-ipfs-core/options" ) func (tp *provider) TestKey(t *testing.T) { diff --git a/core/coreiface/tests/name.go b/core/coreiface/tests/name.go index 8d87bd495..eb5cd1e3a 100644 --- a/core/coreiface/tests/name.go +++ b/core/coreiface/tests/name.go @@ -11,8 +11,8 @@ import ( ipath "gx/ipfs/QmQ3YSqfxunT5QBg6KBVskKyRE26q6hjSMyhpxchpm7jEN/go-path" "gx/ipfs/QmaXvvAVAQ5ABqM5xtjYmV85xmN5MkWAZsX9H9Fwo4FVXp/go-ipfs-files" - coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface" - opt "github.com/ipfs/go-ipfs/core/coreapi/interface/options" + coreiface "github.com/ipfs/interface-go-ipfs-core" + opt "github.com/ipfs/interface-go-ipfs-core/options" ) func (tp *provider) TestName(t *testing.T) { diff --git a/core/coreiface/tests/object.go b/core/coreiface/tests/object.go index 2a3b1bd5c..026def73b 100644 --- a/core/coreiface/tests/object.go +++ b/core/coreiface/tests/object.go @@ -8,8 +8,8 @@ import ( "strings" "testing" - "github.com/ipfs/go-ipfs/core/coreapi/interface" - opt "github.com/ipfs/go-ipfs/core/coreapi/interface/options" + "github.com/ipfs/interface-go-ipfs-core" + opt "github.com/ipfs/interface-go-ipfs-core/options" ) func (tp *provider) TestObject(t *testing.T) { diff --git a/core/coreiface/tests/path.go b/core/coreiface/tests/path.go index 5594cf0da..01841d869 100644 --- a/core/coreiface/tests/path.go +++ b/core/coreiface/tests/path.go @@ -6,8 +6,8 @@ import ( "strings" "testing" - coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface" - "github.com/ipfs/go-ipfs/core/coreapi/interface/options" + coreiface "github.com/ipfs/interface-go-ipfs-core" + "github.com/ipfs/interface-go-ipfs-core/options" ipldcbor "gx/ipfs/QmRZxJ7oybgnnwriuRub9JXp5YdFM9wiGSyRq38QC7swpS/go-ipld-cbor" ) diff --git a/core/coreiface/tests/pin.go b/core/coreiface/tests/pin.go index 35c913618..27ed2ad5d 100644 --- a/core/coreiface/tests/pin.go +++ b/core/coreiface/tests/pin.go @@ -6,8 +6,8 @@ import ( "strings" "testing" - "github.com/ipfs/go-ipfs/core/coreapi/interface" - opt "github.com/ipfs/go-ipfs/core/coreapi/interface/options" + "github.com/ipfs/interface-go-ipfs-core" + opt "github.com/ipfs/interface-go-ipfs-core/options" ipld "gx/ipfs/QmRL22E4paat7ky7vx9MLpR97JHHbFPrg3ytFQw6qp1y1s/go-ipld-format" ipldcbor "gx/ipfs/QmRZxJ7oybgnnwriuRub9JXp5YdFM9wiGSyRq38QC7swpS/go-ipld-cbor" diff --git a/core/coreiface/tests/pubsub.go b/core/coreiface/tests/pubsub.go index b993f51dc..14e3545a9 100644 --- a/core/coreiface/tests/pubsub.go +++ b/core/coreiface/tests/pubsub.go @@ -2,10 +2,11 @@ package tests import ( "context" - "github.com/ipfs/go-ipfs/core/coreapi/interface" - "github.com/ipfs/go-ipfs/core/coreapi/interface/options" "testing" "time" + + "github.com/ipfs/interface-go-ipfs-core" + "github.com/ipfs/interface-go-ipfs-core/options" ) func (tp *provider) TestPubSub(t *testing.T) { diff --git a/core/coreiface/tests/unixfs.go b/core/coreiface/tests/unixfs.go index f5ce85b78..cb5897b69 100644 --- a/core/coreiface/tests/unixfs.go +++ b/core/coreiface/tests/unixfs.go @@ -15,8 +15,8 @@ import ( "sync" "testing" - coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface" - "github.com/ipfs/go-ipfs/core/coreapi/interface/options" + coreiface "github.com/ipfs/interface-go-ipfs-core" + "github.com/ipfs/interface-go-ipfs-core/options" "gx/ipfs/QmR8BauakNcBa3RbE4nbQu76PDiJgoQgz8AJdhJuiU4TAw/go-cid" cbor "gx/ipfs/QmRZxJ7oybgnnwriuRub9JXp5YdFM9wiGSyRq38QC7swpS/go-ipld-cbor" diff --git a/core/coreiface/unixfs.go b/core/coreiface/unixfs.go index 8e559022c..c01ccde78 100644 --- a/core/coreiface/unixfs.go +++ b/core/coreiface/unixfs.go @@ -2,7 +2,7 @@ package iface import ( "context" - "github.com/ipfs/go-ipfs/core/coreapi/interface/options" + "github.com/ipfs/interface-go-ipfs-core/options" ipld "gx/ipfs/QmRL22E4paat7ky7vx9MLpR97JHHbFPrg3ytFQw6qp1y1s/go-ipld-format" "gx/ipfs/QmZArMcsVDsXdcLbUx4844CuqKXBpbxdeiryM4cnmGTNRq/go-unixfs" From 152a54ad8586075d70a281587489740137802e46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Sat, 9 Feb 2019 01:23:13 +0100 Subject: [PATCH 0232/1212] gx-go uw This commit was moved from ipfs/interface-go-ipfs-core@93299fcb14d845e3ed4c128f0792f18458794c62 This commit was moved from ipfs/boxo@def3b3d8058572379b772d2db227011fd45662ee --- core/coreiface/coreapi.go | 2 +- core/coreiface/dag.go | 2 +- core/coreiface/dht.go | 4 ++-- core/coreiface/key.go | 2 +- core/coreiface/object.go | 4 ++-- core/coreiface/options/block.go | 4 ++-- core/coreiface/options/unixfs.go | 6 +++--- core/coreiface/path.go | 4 ++-- core/coreiface/pubsub.go | 2 +- core/coreiface/swarm.go | 10 +++++----- core/coreiface/tests/block.go | 2 +- core/coreiface/tests/dag.go | 6 +++--- core/coreiface/tests/name.go | 4 ++-- core/coreiface/tests/path.go | 4 ++-- core/coreiface/tests/pin.go | 4 ++-- core/coreiface/tests/unixfs.go | 14 +++++++------- core/coreiface/unixfs.go | 6 +++--- 17 files changed, 40 insertions(+), 40 deletions(-) diff --git a/core/coreiface/coreapi.go b/core/coreiface/coreapi.go index 651af8bf0..f3433c089 100644 --- a/core/coreiface/coreapi.go +++ b/core/coreiface/coreapi.go @@ -7,7 +7,7 @@ import ( "github.com/ipfs/interface-go-ipfs-core/options" - ipld "gx/ipfs/QmRL22E4paat7ky7vx9MLpR97JHHbFPrg3ytFQw6qp1y1s/go-ipld-format" + ipld "github.com/ipfs/go-ipld-format" ) // CoreAPI defines an unified interface to IPFS for Go programs diff --git a/core/coreiface/dag.go b/core/coreiface/dag.go index d15e24360..3cc3aeb4d 100644 --- a/core/coreiface/dag.go +++ b/core/coreiface/dag.go @@ -1,7 +1,7 @@ package iface import ( - ipld "gx/ipfs/QmRL22E4paat7ky7vx9MLpR97JHHbFPrg3ytFQw6qp1y1s/go-ipld-format" + ipld "github.com/ipfs/go-ipld-format" ) // APIDagService extends ipld.DAGService diff --git a/core/coreiface/dht.go b/core/coreiface/dht.go index b3f7879e3..d1ae05125 100644 --- a/core/coreiface/dht.go +++ b/core/coreiface/dht.go @@ -5,8 +5,8 @@ import ( "github.com/ipfs/interface-go-ipfs-core/options" - peer "gx/ipfs/QmPJxxDsX2UbchSHobbYuvz7qnyJTFKvaKMzE2rZWJ4x5B/go-libp2p-peer" - pstore "gx/ipfs/QmQFFp4ntkd4C14sP3FaH9WJyBuetuGUVo6dShNHvnoEvC/go-libp2p-peerstore" + peer "github.com/libp2p/go-libp2p-peer" + pstore "github.com/libp2p/go-libp2p-peerstore" ) // DhtAPI specifies the interface to the DHT diff --git a/core/coreiface/key.go b/core/coreiface/key.go index 154f82b66..78c29d268 100644 --- a/core/coreiface/key.go +++ b/core/coreiface/key.go @@ -5,7 +5,7 @@ import ( options "github.com/ipfs/interface-go-ipfs-core/options" - "gx/ipfs/QmPJxxDsX2UbchSHobbYuvz7qnyJTFKvaKMzE2rZWJ4x5B/go-libp2p-peer" + "github.com/libp2p/go-libp2p-peer" ) // Key specifies the interface to Keys in KeyAPI Keystore diff --git a/core/coreiface/object.go b/core/coreiface/object.go index 28613aaa0..4f9652fb1 100644 --- a/core/coreiface/object.go +++ b/core/coreiface/object.go @@ -6,8 +6,8 @@ import ( options "github.com/ipfs/interface-go-ipfs-core/options" - cid "gx/ipfs/QmR8BauakNcBa3RbE4nbQu76PDiJgoQgz8AJdhJuiU4TAw/go-cid" - ipld "gx/ipfs/QmRL22E4paat7ky7vx9MLpR97JHHbFPrg3ytFQw6qp1y1s/go-ipld-format" + cid "github.com/ipfs/go-cid" + ipld "github.com/ipfs/go-ipld-format" ) // ObjectStat provides information about dag nodes diff --git a/core/coreiface/options/block.go b/core/coreiface/options/block.go index 40dfba79a..043dfdea4 100644 --- a/core/coreiface/options/block.go +++ b/core/coreiface/options/block.go @@ -2,8 +2,8 @@ package options import ( "fmt" - cid "gx/ipfs/QmR8BauakNcBa3RbE4nbQu76PDiJgoQgz8AJdhJuiU4TAw/go-cid" - mh "gx/ipfs/QmerPMzPk1mJVowm8KgmoknWa4yCYvvugMPsgWmDNUvDLW/go-multihash" + cid "github.com/ipfs/go-cid" + mh "github.com/multiformats/go-multihash" ) type BlockPutSettings struct { diff --git a/core/coreiface/options/unixfs.go b/core/coreiface/options/unixfs.go index 0dd129609..b76b01adf 100644 --- a/core/coreiface/options/unixfs.go +++ b/core/coreiface/options/unixfs.go @@ -4,9 +4,9 @@ import ( "errors" "fmt" - cid "gx/ipfs/QmR8BauakNcBa3RbE4nbQu76PDiJgoQgz8AJdhJuiU4TAw/go-cid" - dag "gx/ipfs/QmUtsx89yiCY6F8mbpP6ecXckiSzCBH7EvkKZuZEHBcr1m/go-merkledag" - mh "gx/ipfs/QmerPMzPk1mJVowm8KgmoknWa4yCYvvugMPsgWmDNUvDLW/go-multihash" + cid "github.com/ipfs/go-cid" + dag "github.com/ipfs/go-merkledag" + mh "github.com/multiformats/go-multihash" ) type Layout int diff --git a/core/coreiface/path.go b/core/coreiface/path.go index d59a851b4..4e86172ac 100644 --- a/core/coreiface/path.go +++ b/core/coreiface/path.go @@ -1,8 +1,8 @@ package iface import ( - ipfspath "gx/ipfs/QmQ3YSqfxunT5QBg6KBVskKyRE26q6hjSMyhpxchpm7jEN/go-path" - "gx/ipfs/QmR8BauakNcBa3RbE4nbQu76PDiJgoQgz8AJdhJuiU4TAw/go-cid" + "github.com/ipfs/go-cid" + ipfspath "github.com/ipfs/go-path" ) //TODO: merge with ipfspath so we don't depend on it diff --git a/core/coreiface/pubsub.go b/core/coreiface/pubsub.go index 40cea689a..212e77225 100644 --- a/core/coreiface/pubsub.go +++ b/core/coreiface/pubsub.go @@ -6,7 +6,7 @@ import ( options "github.com/ipfs/interface-go-ipfs-core/options" - peer "gx/ipfs/QmPJxxDsX2UbchSHobbYuvz7qnyJTFKvaKMzE2rZWJ4x5B/go-libp2p-peer" + peer "github.com/libp2p/go-libp2p-peer" ) // PubSubSubscription is an active PubSub subscription diff --git a/core/coreiface/swarm.go b/core/coreiface/swarm.go index 3af078f17..2e00ecbd3 100644 --- a/core/coreiface/swarm.go +++ b/core/coreiface/swarm.go @@ -5,11 +5,11 @@ import ( "errors" "time" - ma "gx/ipfs/QmNTCey11oxhb1AxDnQBRHtdhap6Ctud872NjAYPYYXPuc/go-multiaddr" - "gx/ipfs/QmPJxxDsX2UbchSHobbYuvz7qnyJTFKvaKMzE2rZWJ4x5B/go-libp2p-peer" - pstore "gx/ipfs/QmQFFp4ntkd4C14sP3FaH9WJyBuetuGUVo6dShNHvnoEvC/go-libp2p-peerstore" - net "gx/ipfs/QmZ7cBWUXkyWTMN4qH6NGoyMVs7JugyFChBNP4ZUp5rJHH/go-libp2p-net" - "gx/ipfs/QmZNkThpqfVXs9GNbexPrfBbXSLNYeKrE7jwFM2oqHbyqN/go-libp2p-protocol" + net "github.com/libp2p/go-libp2p-net" + "github.com/libp2p/go-libp2p-peer" + pstore "github.com/libp2p/go-libp2p-peerstore" + "github.com/libp2p/go-libp2p-protocol" + ma "github.com/multiformats/go-multiaddr" ) var ( diff --git a/core/coreiface/tests/block.go b/core/coreiface/tests/block.go index 2e0a84b40..3cd74358d 100644 --- a/core/coreiface/tests/block.go +++ b/core/coreiface/tests/block.go @@ -9,7 +9,7 @@ import ( coreiface "github.com/ipfs/interface-go-ipfs-core" opt "github.com/ipfs/interface-go-ipfs-core/options" - mh "gx/ipfs/QmerPMzPk1mJVowm8KgmoknWa4yCYvvugMPsgWmDNUvDLW/go-multihash" + mh "github.com/multiformats/go-multihash" ) func (tp *provider) TestBlock(t *testing.T) { diff --git a/core/coreiface/tests/dag.go b/core/coreiface/tests/dag.go index 9e0bc34ba..7446c20de 100644 --- a/core/coreiface/tests/dag.go +++ b/core/coreiface/tests/dag.go @@ -9,9 +9,9 @@ import ( coreiface "github.com/ipfs/interface-go-ipfs-core" - ipld "gx/ipfs/QmRL22E4paat7ky7vx9MLpR97JHHbFPrg3ytFQw6qp1y1s/go-ipld-format" - ipldcbor "gx/ipfs/QmRZxJ7oybgnnwriuRub9JXp5YdFM9wiGSyRq38QC7swpS/go-ipld-cbor" - mh "gx/ipfs/QmerPMzPk1mJVowm8KgmoknWa4yCYvvugMPsgWmDNUvDLW/go-multihash" + ipldcbor "github.com/ipfs/go-ipld-cbor" + ipld "github.com/ipfs/go-ipld-format" + mh "github.com/multiformats/go-multihash" ) func (tp *provider) TestDag(t *testing.T) { diff --git a/core/coreiface/tests/name.go b/core/coreiface/tests/name.go index eb5cd1e3a..1eb2dd513 100644 --- a/core/coreiface/tests/name.go +++ b/core/coreiface/tests/name.go @@ -8,8 +8,8 @@ import ( "testing" "time" - ipath "gx/ipfs/QmQ3YSqfxunT5QBg6KBVskKyRE26q6hjSMyhpxchpm7jEN/go-path" - "gx/ipfs/QmaXvvAVAQ5ABqM5xtjYmV85xmN5MkWAZsX9H9Fwo4FVXp/go-ipfs-files" + "github.com/ipfs/go-ipfs-files" + ipath "github.com/ipfs/go-path" coreiface "github.com/ipfs/interface-go-ipfs-core" opt "github.com/ipfs/interface-go-ipfs-core/options" diff --git a/core/coreiface/tests/path.go b/core/coreiface/tests/path.go index 01841d869..4da1a5181 100644 --- a/core/coreiface/tests/path.go +++ b/core/coreiface/tests/path.go @@ -9,7 +9,7 @@ import ( coreiface "github.com/ipfs/interface-go-ipfs-core" "github.com/ipfs/interface-go-ipfs-core/options" - ipldcbor "gx/ipfs/QmRZxJ7oybgnnwriuRub9JXp5YdFM9wiGSyRq38QC7swpS/go-ipld-cbor" + ipldcbor "github.com/ipfs/go-ipld-cbor" ) func (tp *provider) TestPath(t *testing.T) { @@ -38,7 +38,7 @@ func (tp *provider) TestMutablePath(t *testing.T) { t.Error("expected /ipld path to be immutable") } - // get self /ipns path ipldcbor "gx/ipfs/QmRZxJ7oybgnnwriuRub9JXp5YdFM9wiGSyRq38QC7swpS/go-ipld-cbor" + // get self /ipns path if api.Key() == nil { t.Fatal(".Key not implemented") diff --git a/core/coreiface/tests/pin.go b/core/coreiface/tests/pin.go index 27ed2ad5d..eed542283 100644 --- a/core/coreiface/tests/pin.go +++ b/core/coreiface/tests/pin.go @@ -9,8 +9,8 @@ import ( "github.com/ipfs/interface-go-ipfs-core" opt "github.com/ipfs/interface-go-ipfs-core/options" - ipld "gx/ipfs/QmRL22E4paat7ky7vx9MLpR97JHHbFPrg3ytFQw6qp1y1s/go-ipld-format" - ipldcbor "gx/ipfs/QmRZxJ7oybgnnwriuRub9JXp5YdFM9wiGSyRq38QC7swpS/go-ipld-cbor" + ipldcbor "github.com/ipfs/go-ipld-cbor" + ipld "github.com/ipfs/go-ipld-format" ) func (tp *provider) TestPin(t *testing.T) { diff --git a/core/coreiface/tests/unixfs.go b/core/coreiface/tests/unixfs.go index cb5897b69..bcb5331d5 100644 --- a/core/coreiface/tests/unixfs.go +++ b/core/coreiface/tests/unixfs.go @@ -18,13 +18,13 @@ import ( coreiface "github.com/ipfs/interface-go-ipfs-core" "github.com/ipfs/interface-go-ipfs-core/options" - "gx/ipfs/QmR8BauakNcBa3RbE4nbQu76PDiJgoQgz8AJdhJuiU4TAw/go-cid" - cbor "gx/ipfs/QmRZxJ7oybgnnwriuRub9JXp5YdFM9wiGSyRq38QC7swpS/go-ipld-cbor" - mdag "gx/ipfs/QmUtsx89yiCY6F8mbpP6ecXckiSzCBH7EvkKZuZEHBcr1m/go-merkledag" - "gx/ipfs/QmZArMcsVDsXdcLbUx4844CuqKXBpbxdeiryM4cnmGTNRq/go-unixfs" - "gx/ipfs/QmZArMcsVDsXdcLbUx4844CuqKXBpbxdeiryM4cnmGTNRq/go-unixfs/importer/helpers" - "gx/ipfs/QmaXvvAVAQ5ABqM5xtjYmV85xmN5MkWAZsX9H9Fwo4FVXp/go-ipfs-files" - mh "gx/ipfs/QmerPMzPk1mJVowm8KgmoknWa4yCYvvugMPsgWmDNUvDLW/go-multihash" + "github.com/ipfs/go-cid" + "github.com/ipfs/go-ipfs-files" + cbor "github.com/ipfs/go-ipld-cbor" + mdag "github.com/ipfs/go-merkledag" + "github.com/ipfs/go-unixfs" + "github.com/ipfs/go-unixfs/importer/helpers" + mh "github.com/multiformats/go-multihash" ) func (tp *provider) TestUnixfs(t *testing.T) { diff --git a/core/coreiface/unixfs.go b/core/coreiface/unixfs.go index c01ccde78..5aae00dc4 100644 --- a/core/coreiface/unixfs.go +++ b/core/coreiface/unixfs.go @@ -4,9 +4,9 @@ import ( "context" "github.com/ipfs/interface-go-ipfs-core/options" - ipld "gx/ipfs/QmRL22E4paat7ky7vx9MLpR97JHHbFPrg3ytFQw6qp1y1s/go-ipld-format" - "gx/ipfs/QmZArMcsVDsXdcLbUx4844CuqKXBpbxdeiryM4cnmGTNRq/go-unixfs" - "gx/ipfs/QmaXvvAVAQ5ABqM5xtjYmV85xmN5MkWAZsX9H9Fwo4FVXp/go-ipfs-files" + "github.com/ipfs/go-ipfs-files" + ipld "github.com/ipfs/go-ipld-format" + "github.com/ipfs/go-unixfs" ) type AddEvent struct { From ef5bf40df1d0d790aeb213147c53412145894bf0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 11 Feb 2019 18:40:38 +0100 Subject: [PATCH 0233/1212] Update imports to use extracted interface This commit was moved from ipfs/go-ipfs-http-client@fad467bc437a1282ed3813d828c6f8ec5b7b2d7a --- client/httpapi/api.go | 5 ++--- client/httpapi/api_test.go | 7 +++---- client/httpapi/apifile.go | 9 ++++----- client/httpapi/block.go | 4 ++-- client/httpapi/dag.go | 5 ++--- client/httpapi/dht.go | 4 ++-- client/httpapi/ipldnode.go | 3 +-- client/httpapi/key.go | 5 ++--- client/httpapi/name.go | 6 +++--- client/httpapi/object.go | 5 ++--- client/httpapi/path.go | 3 +-- client/httpapi/pin.go | 8 ++++---- client/httpapi/pubsub.go | 5 ++--- client/httpapi/swarm.go | 5 ++--- client/httpapi/unixfs.go | 11 +++++------ 15 files changed, 37 insertions(+), 48 deletions(-) diff --git a/client/httpapi/api.go b/client/httpapi/api.go index da0836d4a..698e36524 100644 --- a/client/httpapi/api.go +++ b/client/httpapi/api.go @@ -9,9 +9,8 @@ import ( "path" "strings" - "github.com/ipfs/go-ipfs/core/coreapi/interface" - caopts "github.com/ipfs/go-ipfs/core/coreapi/interface/options" - + iface "github.com/ipfs/interface-go-ipfs-core" + caopts "github.com/ipfs/interface-go-ipfs-core/options" homedir "github.com/mitchellh/go-homedir" ma "github.com/multiformats/go-multiaddr" manet "github.com/multiformats/go-multiaddr-net" diff --git a/client/httpapi/api_test.go b/client/httpapi/api_test.go index bf1d6b9b0..5621ab87f 100644 --- a/client/httpapi/api_test.go +++ b/client/httpapi/api_test.go @@ -10,10 +10,9 @@ import ( "strconv" "testing" - "github.com/ipfs/go-ipfs/core/coreapi/interface" - caopts "github.com/ipfs/go-ipfs/core/coreapi/interface/options" - "github.com/ipfs/go-ipfs/core/coreapi/interface/tests" - + "github.com/ipfs/interface-go-ipfs-core" + caopts "github.com/ipfs/interface-go-ipfs-core/options" + "github.com/ipfs/interface-go-ipfs-core/tests" local "github.com/ipfs/iptb-plugins/local" "github.com/ipfs/iptb/cli" "github.com/ipfs/iptb/testbed" diff --git a/client/httpapi/apifile.go b/client/httpapi/apifile.go index ec916d8e2..1e5f61a9a 100644 --- a/client/httpapi/apifile.go +++ b/client/httpapi/apifile.go @@ -4,13 +4,12 @@ import ( "context" "encoding/json" "fmt" - "github.com/ipfs/go-cid" "io" "io/ioutil" - "github.com/ipfs/go-ipfs/core/coreapi/interface" - + "github.com/ipfs/go-cid" "github.com/ipfs/go-ipfs-files" + "github.com/ipfs/interface-go-ipfs-core" ) const forwardSeekLimit = 1 << 14 //16k @@ -92,8 +91,8 @@ func (f *apiFile) Seek(offset int64, whence int) (int64, error) { return offset, nil } - if f.at < offset && offset - f.at < forwardSeekLimit { //forward skip - r, err := io.CopyN(ioutil.Discard, f.r, offset - f.at) + if f.at < offset && offset-f.at < forwardSeekLimit { //forward skip + r, err := io.CopyN(ioutil.Discard, f.r, offset-f.at) f.at += r return f.at, err diff --git a/client/httpapi/block.go b/client/httpapi/block.go index 24df9629e..45c73472c 100644 --- a/client/httpapi/block.go +++ b/client/httpapi/block.go @@ -8,8 +8,8 @@ import ( "io" "github.com/ipfs/go-cid" - "github.com/ipfs/go-ipfs/core/coreapi/interface" - caopts "github.com/ipfs/go-ipfs/core/coreapi/interface/options" + "github.com/ipfs/interface-go-ipfs-core" + caopts "github.com/ipfs/interface-go-ipfs-core/options" mh "github.com/multiformats/go-multihash" ) diff --git a/client/httpapi/dag.go b/client/httpapi/dag.go index eacf631b9..d0059698a 100644 --- a/client/httpapi/dag.go +++ b/client/httpapi/dag.go @@ -7,12 +7,11 @@ import ( "io/ioutil" "sync" - "github.com/ipfs/go-ipfs/core/coreapi/interface" - "github.com/ipfs/go-ipfs/core/coreapi/interface/options" - "github.com/ipfs/go-block-format" "github.com/ipfs/go-cid" "github.com/ipfs/go-ipld-format" + "github.com/ipfs/interface-go-ipfs-core" + "github.com/ipfs/interface-go-ipfs-core/options" ) type httpNodeAdder HttpApi diff --git a/client/httpapi/dht.go b/client/httpapi/dht.go index 8fedabbf8..dc7dd6bea 100644 --- a/client/httpapi/dht.go +++ b/client/httpapi/dht.go @@ -3,9 +3,9 @@ package httpapi import ( "context" "encoding/json" - "github.com/ipfs/go-ipfs/core/coreapi/interface" - caopts "github.com/ipfs/go-ipfs/core/coreapi/interface/options" + "github.com/ipfs/interface-go-ipfs-core" + caopts "github.com/ipfs/interface-go-ipfs-core/options" "github.com/libp2p/go-libp2p-peer" "github.com/libp2p/go-libp2p-peerstore" notif "github.com/libp2p/go-libp2p-routing/notifications" diff --git a/client/httpapi/ipldnode.go b/client/httpapi/ipldnode.go index 2294a95b4..43fa5d50d 100644 --- a/client/httpapi/ipldnode.go +++ b/client/httpapi/ipldnode.go @@ -6,11 +6,10 @@ import ( "io/ioutil" "strconv" - "github.com/ipfs/go-ipfs/core/coreapi/interface" - "github.com/ipfs/go-cid" ipld "github.com/ipfs/go-ipld-format" ipfspath "github.com/ipfs/go-path" + "github.com/ipfs/interface-go-ipfs-core" ) type ipldNode struct { diff --git a/client/httpapi/key.go b/client/httpapi/key.go index 5087b6d99..dc2adf8b7 100644 --- a/client/httpapi/key.go +++ b/client/httpapi/key.go @@ -4,9 +4,8 @@ import ( "context" "errors" - "github.com/ipfs/go-ipfs/core/coreapi/interface" - caopts "github.com/ipfs/go-ipfs/core/coreapi/interface/options" - + "github.com/ipfs/interface-go-ipfs-core" + caopts "github.com/ipfs/interface-go-ipfs-core/options" "github.com/libp2p/go-libp2p-peer" ) diff --git a/client/httpapi/name.go b/client/httpapi/name.go index fbc440b96..d760e6188 100644 --- a/client/httpapi/name.go +++ b/client/httpapi/name.go @@ -3,10 +3,10 @@ package httpapi import ( "context" "fmt" - "github.com/ipfs/go-ipfs/namesys/opts" - "github.com/ipfs/go-ipfs/core/coreapi/interface" - caopts "github.com/ipfs/go-ipfs/core/coreapi/interface/options" + "github.com/ipfs/interface-go-ipfs-core" + caopts "github.com/ipfs/interface-go-ipfs-core/options" + "github.com/ipfs/interface-go-ipfs-core/options/namesys" ) type NameAPI HttpApi diff --git a/client/httpapi/object.go b/client/httpapi/object.go index 4bc787991..3b648d82b 100644 --- a/client/httpapi/object.go +++ b/client/httpapi/object.go @@ -6,12 +6,11 @@ import ( "io" "io/ioutil" - "github.com/ipfs/go-ipfs/core/coreapi/interface" - caopts "github.com/ipfs/go-ipfs/core/coreapi/interface/options" - "github.com/ipfs/go-cid" "github.com/ipfs/go-ipld-format" "github.com/ipfs/go-merkledag" + "github.com/ipfs/interface-go-ipfs-core" + caopts "github.com/ipfs/interface-go-ipfs-core/options" ) type ObjectAPI HttpApi diff --git a/client/httpapi/path.go b/client/httpapi/path.go index 5701326fc..68dc2633d 100644 --- a/client/httpapi/path.go +++ b/client/httpapi/path.go @@ -3,11 +3,10 @@ package httpapi import ( "context" - "github.com/ipfs/go-ipfs/core/coreapi/interface" - cid "github.com/ipfs/go-cid" ipld "github.com/ipfs/go-ipld-format" ipfspath "github.com/ipfs/go-path" + "github.com/ipfs/interface-go-ipfs-core" ) func (api *HttpApi) ResolvePath(ctx context.Context, path iface.Path) (iface.ResolvedPath, error) { diff --git a/client/httpapi/pin.go b/client/httpapi/pin.go index 237b32329..4c4e5713c 100644 --- a/client/httpapi/pin.go +++ b/client/httpapi/pin.go @@ -3,11 +3,11 @@ package httpapi import ( "context" "encoding/json" - "github.com/ipfs/go-cid" - "github.com/pkg/errors" - "github.com/ipfs/go-ipfs/core/coreapi/interface" - caopts "github.com/ipfs/go-ipfs/core/coreapi/interface/options" + "github.com/ipfs/go-cid" + "github.com/ipfs/interface-go-ipfs-core" + caopts "github.com/ipfs/interface-go-ipfs-core/options" + "github.com/pkg/errors" ) type PinAPI HttpApi diff --git a/client/httpapi/pubsub.go b/client/httpapi/pubsub.go index fb9bb7460..334509780 100644 --- a/client/httpapi/pubsub.go +++ b/client/httpapi/pubsub.go @@ -6,9 +6,8 @@ import ( "encoding/json" "io" - "github.com/ipfs/go-ipfs/core/coreapi/interface" - caopts "github.com/ipfs/go-ipfs/core/coreapi/interface/options" - + "github.com/ipfs/interface-go-ipfs-core" + caopts "github.com/ipfs/interface-go-ipfs-core/options" "github.com/libp2p/go-libp2p-peer" ) diff --git a/client/httpapi/swarm.go b/client/httpapi/swarm.go index cf0ee2a9b..d179b6540 100644 --- a/client/httpapi/swarm.go +++ b/client/httpapi/swarm.go @@ -2,14 +2,13 @@ package httpapi import ( "context" - "github.com/libp2p/go-libp2p-protocol" "time" - "github.com/ipfs/go-ipfs/core/coreapi/interface" - + "github.com/ipfs/interface-go-ipfs-core" inet "github.com/libp2p/go-libp2p-net" "github.com/libp2p/go-libp2p-peer" "github.com/libp2p/go-libp2p-peerstore" + "github.com/libp2p/go-libp2p-protocol" "github.com/multiformats/go-multiaddr" ) diff --git a/client/httpapi/unixfs.go b/client/httpapi/unixfs.go index 67d05309b..1f340b657 100644 --- a/client/httpapi/unixfs.go +++ b/client/httpapi/unixfs.go @@ -3,16 +3,15 @@ package httpapi import ( "context" "encoding/json" + "errors" "fmt" - "github.com/ipfs/go-cid" - "github.com/pkg/errors" "io" - "github.com/ipfs/go-ipfs/core/coreapi/interface" - caopts "github.com/ipfs/go-ipfs/core/coreapi/interface/options" - + "github.com/ipfs/go-cid" "github.com/ipfs/go-ipfs-files" "github.com/ipfs/go-ipld-format" + "github.com/ipfs/interface-go-ipfs-core" + caopts "github.com/ipfs/interface-go-ipfs-core/options" mh "github.com/multiformats/go-multihash" ) @@ -208,7 +207,7 @@ func (api *UnixfsAPI) Ls(ctx context.Context, p iface.Path, opts ...caopts.Unixf select { case out <- iface.LsLink{ Link: &format.Link{ - Cid: c, + Cid: c, Name: l0.Name, Size: l0.Size, }, From 0813d808b54341414441a56e5cd3a7722a516a14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 12 Feb 2019 12:29:31 +0100 Subject: [PATCH 0234/1212] Fix govet warning in Dag This commit was moved from ipfs/go-ipfs-http-client@62552b33959401c7a9d9463dffba433e522b2f15 --- client/httpapi/dag.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/httpapi/dag.go b/client/httpapi/dag.go index d0059698a..3f54ced34 100644 --- a/client/httpapi/dag.go +++ b/client/httpapi/dag.go @@ -44,7 +44,7 @@ func (api *HttpDagServ) GetMany(ctx context.Context, cids []cid.Cid) <-chan *for for _, c := range cids { // TODO: Consider limiting concurrency of this somehow - go func() { + go func(c cid.Cid) { defer wg.Done() n, err := api.Get(ctx, c) @@ -52,7 +52,7 @@ func (api *HttpDagServ) GetMany(ctx context.Context, cids []cid.Cid) <-chan *for case out <- &format.NodeOption{Node: n, Err: err}: case <-ctx.Done(): } - }() + }(c) } return out } From abc30e384fafe157490df0dae80a22ddeb6255a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 12 Feb 2019 12:48:04 +0100 Subject: [PATCH 0235/1212] Register iptb plugin once This commit was moved from ipfs/go-ipfs-http-client@d6c8cbd5e643d2131477120a76159074d1a07cd3 --- client/httpapi/api_test.go | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/client/httpapi/api_test.go b/client/httpapi/api_test.go index 5621ab87f..fa38866e1 100644 --- a/client/httpapi/api_test.go +++ b/client/httpapi/api_test.go @@ -19,9 +19,7 @@ import ( "github.com/ipfs/iptb/testbed/interfaces" ) -type NodeProvider struct{} - -func (NodeProvider) MakeAPISwarm(ctx context.Context, fullIdentity bool, n int) ([]iface.CoreAPI, error) { +func init() { _, err := testbed.RegisterPlugin(testbed.IptbPlugin{ From: "", NewNode: local.NewNode, @@ -31,8 +29,13 @@ func (NodeProvider) MakeAPISwarm(ctx context.Context, fullIdentity bool, n int) BuiltIn: true, }, false) if err != nil { - return nil, err + panic(err) } +} + +type NodeProvider struct{} + +func (NodeProvider) MakeAPISwarm(ctx context.Context, fullIdentity bool, n int) ([]iface.CoreAPI, error) { dir, err := ioutil.TempDir("", "httpapi-tb-") if err != nil { From 0a6bdbaa6cfa478a88b43a724695698e2e53414c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 12 Feb 2019 13:30:07 +0100 Subject: [PATCH 0236/1212] pubsub: fix race in test This commit was moved from ipfs/interface-go-ipfs-core@a84bfa1f4055bb15e3727841df03c3f306ed5cfc This commit was moved from ipfs/boxo@bc7e36143ffe315dc853eecd39d4be5e9b1ab425 --- core/coreiface/tests/pubsub.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/coreiface/tests/pubsub.go b/core/coreiface/tests/pubsub.go index 14e3545a9..bb870de6c 100644 --- a/core/coreiface/tests/pubsub.go +++ b/core/coreiface/tests/pubsub.go @@ -38,7 +38,7 @@ func (tp *provider) TestBasicPubSub(t *testing.T) { tick := time.Tick(100 * time.Millisecond) for { - err = apis[1].PubSub().Publish(ctx, "testch", []byte("hello world")) + err := apis[1].PubSub().Publish(ctx, "testch", []byte("hello world")) if err != nil { t.Fatal(err) } From 9a6ee6f5e153b96afda0f4ca1ee893cf28aa4f57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 14 Feb 2019 17:30:04 +0100 Subject: [PATCH 0237/1212] Improve test node spawning This commit was moved from ipfs/go-ipfs-http-client@6bb2a287a6f5090792e07f3e3a74871c459b395f --- client/httpapi/api_test.go | 198 ++++++++++++++++++++++++------------- 1 file changed, 131 insertions(+), 67 deletions(-) diff --git a/client/httpapi/api_test.go b/client/httpapi/api_test.go index fa38866e1..af2180384 100644 --- a/client/httpapi/api_test.go +++ b/client/httpapi/api_test.go @@ -2,23 +2,23 @@ package httpapi import ( "context" - "fmt" "io/ioutil" gohttp "net/http" "os" - "path" "strconv" + "sync" "testing" "github.com/ipfs/interface-go-ipfs-core" - caopts "github.com/ipfs/interface-go-ipfs-core/options" "github.com/ipfs/interface-go-ipfs-core/tests" local "github.com/ipfs/iptb-plugins/local" - "github.com/ipfs/iptb/cli" "github.com/ipfs/iptb/testbed" "github.com/ipfs/iptb/testbed/interfaces" + ma "github.com/multiformats/go-multiaddr" ) +const parallelSpeculativeNodes = 15 // 15 seems to work best + func init() { _, err := testbed.RegisterPlugin(testbed.IptbPlugin{ From: "", @@ -33,99 +33,163 @@ func init() { } } -type NodeProvider struct{} +type NodeProvider struct { + simple <-chan func(context.Context) ([]iface.CoreAPI, error) +} -func (NodeProvider) MakeAPISwarm(ctx context.Context, fullIdentity bool, n int) ([]iface.CoreAPI, error) { +func newNodeProvider(ctx context.Context) *NodeProvider { + simpleNodes := make(chan func(context.Context) ([]iface.CoreAPI, error), parallelSpeculativeNodes) + + np := &NodeProvider{ + simple: simpleNodes, + } + + // start basic nodes speculatively in parallel + for i := 0; i < parallelSpeculativeNodes; i++ { + go func() { + for { + ctx, cancel := context.WithCancel(ctx) + + snd, err := np.makeAPISwarm(ctx, false, 1) + + res := func(ctx context.Context) ([]iface.CoreAPI, error) { + if err != nil { + return nil, err + } + + go func() { + <-ctx.Done() + cancel() + }() + + return snd, nil + } + + select { + case simpleNodes <- res: + case <-ctx.Done(): + return + } + } + }() + } + + return np +} + +func (np *NodeProvider) MakeAPISwarm(ctx context.Context, fullIdentity bool, n int) ([]iface.CoreAPI, error) { + if !fullIdentity && n == 1 { + return (<-np.simple)(ctx) + } + return np.makeAPISwarm(ctx, fullIdentity, n) +} + +func (NodeProvider) makeAPISwarm(ctx context.Context, fullIdentity bool, n int) ([]iface.CoreAPI, error) { dir, err := ioutil.TempDir("", "httpapi-tb-") if err != nil { return nil, err } - c := cli.NewCli() //TODO: is there a better way? + tb := testbed.NewTestbed(dir) - initArgs := []string{"iptb", "--IPTB_ROOT", dir, "auto", "-type", "localipfs", "-count", strconv.FormatInt(int64(n), 10)} - if err := c.Run(initArgs); err != nil { + specs, err := testbed.BuildSpecs(tb.Dir(), n, "localipfs", nil) + if err != nil { return nil, err } - filestoreArgs := []string{"iptb", "--IPTB_ROOT", dir, "run", fmt.Sprintf("[0-%d]", n-1), "--", "ipfs", "config", "--json", "Experimental.FilestoreEnabled", "true"} - if err := c.Run(filestoreArgs); err != nil { + if err := testbed.WriteNodeSpecs(tb.Dir(), specs); err != nil { return nil, err } - startArgs := []string{"iptb", "--IPTB_ROOT", dir, "start", "-wait", "--", "--enable-pubsub-experiment", "--offline=" + strconv.FormatBool(n == 1)} - if err := c.Run(startArgs); err != nil { + nodes, err := tb.Nodes() + if err != nil { return nil, err } - if n > 1 { - connectArgs := []string{"iptb", "--IPTB_ROOT", dir, "connect", fmt.Sprintf("[1-%d]", n-1), "0"} - if err := c.Run(connectArgs); err != nil { - return nil, err - } + apis := make([]iface.CoreAPI, n) + + wg := sync.WaitGroup{} + zero := sync.WaitGroup{} + + wg.Add(len(nodes)) + zero.Add(1) + + for i, nd := range nodes { + go func(i int, nd testbedi.Core) { + defer wg.Done() + + if _, err := nd.Init(ctx, "--empty-repo"); err != nil { + panic(err) + } + + if _, err := nd.RunCmd(ctx, nil, "ipfs", "config", "--json", "Experimental.FilestoreEnabled", "true"); err != nil { + panic(err) + } + + if _, err := nd.Start(ctx, true, "--enable-pubsub-experiment", "--offline="+strconv.FormatBool(n == 1)); err != nil { + panic(err) + } + + if i > 0 { + zero.Wait() + if err := nd.Connect(ctx, nodes[0]); err != nil { + panic(err) + } + } else { + zero.Done() + } + + addr, err := nd.APIAddr() + if err != nil { + panic(err) + } + + maddr, err := ma.NewMultiaddr(addr) + if err != nil { + panic(err) + } + + c := &gohttp.Client{ + Transport: &gohttp.Transport{ + Proxy: gohttp.ProxyFromEnvironment, + DisableKeepAlives: true, + DisableCompression: true, + }, + } + apis[i] = NewApiWithClient(maddr, c) + + // empty node is pinned even with --empty-repo, we don't want that + emptyNode, err := iface.ParsePath("/ipfs/QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn") + if err != nil { + panic(err) + } + if err := apis[i].Pin().Rm(ctx, emptyNode); err != nil { + panic(err) + } + }(i, nd) } + wg.Wait() + go func() { <-ctx.Done() defer os.Remove(dir) defer func() { - _ = c.Run([]string{"iptb", "--IPTB_ROOT", dir, "stop"}) + for _, nd := range nodes { + _ = nd.Stop(context.Background()) + } }() }() - apis := make([]iface.CoreAPI, n) - - for i := range apis { - tb := testbed.NewTestbed(path.Join(dir, "testbeds", "default")) - - node, err := tb.Node(i) - if err != nil { - return nil, err - } - - attrNode, ok := node.(testbedi.Attribute) - if !ok { - return nil, fmt.Errorf("node does not implement attributes") - } - - pth, err := attrNode.Attr("path") - if err != nil { - return nil, err - } - - a := ApiAddr(pth) - if a == nil { - return nil, fmt.Errorf("nil addr for node") - } - c := &gohttp.Client{ - Transport: &gohttp.Transport{ - Proxy: gohttp.ProxyFromEnvironment, - DisableKeepAlives: true, - DisableCompression: true, - }, - } - apis[i] = NewApiWithClient(a, c) - - // node cleanup - // TODO: pass --empty-repo somehow (how?) - pins, err := apis[i].Pin().Ls(ctx, caopts.Pin.Type.Recursive()) - if err != nil { - return nil, err - } - for _, pin := range pins { //TODO: parallel - if err := apis[i].Pin().Rm(ctx, pin.Path()); err != nil { - return nil, err - } - } - - } - return apis, nil } func TestHttpApi(t *testing.T) { - tests.TestApi(&NodeProvider{})(t) + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + tests.TestApi(newNodeProvider(ctx))(t) } From f7dd0c690960ea79a7aad7f40b11362512d173bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 14 Feb 2019 18:12:02 +0100 Subject: [PATCH 0238/1212] Improve apifile error messages This commit was moved from ipfs/go-ipfs-http-client@3393b8379021695126da83afdf3bf54eaff828f4 --- client/httpapi/apifile.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/httpapi/apifile.go b/client/httpapi/apifile.go index 1e5f61a9a..864760684 100644 --- a/client/httpapi/apifile.go +++ b/client/httpapi/apifile.go @@ -157,12 +157,12 @@ func (it *apiIter) Next() bool { } if len(out.Objects) != 1 { - it.err = fmt.Errorf("len(out.Objects) != 1 (is %d)", len(out.Objects)) + it.err = fmt.Errorf("ls returned more objects than expected (%d)", len(out.Objects)) return false } if len(out.Objects[0].Links) != 1 { - it.err = fmt.Errorf("len(out.Objects[0].Links) != 1 (is %d)", len(out.Objects[0].Links)) + it.err = fmt.Errorf("ls returned more links than expected (%d)", len(out.Objects[0].Links)) return false } From e1b14d78c72edf0a782e362afb0e818e032c31cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 14 Feb 2019 18:45:19 +0100 Subject: [PATCH 0239/1212] Implement missing methods This commit was moved from ipfs/go-ipfs-http-client@b76413dfe55fd33d39a680458282d85565cc1c69 --- client/httpapi/api.go | 3 -- client/httpapi/name.go | 63 +++++++++++++++++++++++++++++++++++++++--- client/httpapi/path.go | 9 ++++-- 3 files changed, 66 insertions(+), 9 deletions(-) diff --git a/client/httpapi/api.go b/client/httpapi/api.go index 698e36524..e106d8d87 100644 --- a/client/httpapi/api.go +++ b/client/httpapi/api.go @@ -1,7 +1,6 @@ package httpapi import ( - "errors" "fmt" "io/ioutil" gohttp "net/http" @@ -23,8 +22,6 @@ const ( EnvDir = "IPFS_PATH" ) -var ErrNotImplemented = errors.New("not implemented") - type HttpApi struct { url string httpcli gohttp.Client diff --git a/client/httpapi/name.go b/client/httpapi/name.go index d760e6188..58fb59249 100644 --- a/client/httpapi/name.go +++ b/client/httpapi/name.go @@ -2,7 +2,9 @@ package httpapi import ( "context" + "encoding/json" "fmt" + "io" "github.com/ipfs/interface-go-ipfs-core" caopts "github.com/ipfs/interface-go-ipfs-core/options" @@ -38,11 +40,11 @@ func (api *NameAPI) Publish(ctx context.Context, p iface.Path, opts ...caopts.Na req := api.core().request("name/publish", p.String()). Option("key", options.Key). Option("allow-offline", options.AllowOffline). - Option("lifetime", options.ValidTime.String()). + Option("lifetime", options.ValidTime). Option("resolve", false) if options.TTL != nil { - req.Option("ttl", options.TTL.String()) + req.Option("ttl", options.TTL) } var out ipnsEntry @@ -57,7 +59,60 @@ func (api *NameAPI) Publish(ctx context.Context, p iface.Path, opts ...caopts.Na } func (api *NameAPI) Search(ctx context.Context, name string, opts ...caopts.NameResolveOption) (<-chan iface.IpnsResult, error) { - return nil, ErrNotImplemented + options, err := caopts.NameResolveOptions(opts...) + if err != nil { + return nil, err + } + + ropts := nsopts.ProcessOpts(options.ResolveOpts) + if ropts.Depth != nsopts.DefaultDepthLimit && ropts.Depth != 1 { + return nil, fmt.Errorf("Name.Resolve: depth other than 1 or %d not supported", nsopts.DefaultDepthLimit) + } + + req := api.core().request("name/resolve", name). + Option("nocache", !options.Cache). + Option("recursive", ropts.Depth != 1). + Option("dht-record-count", ropts.DhtRecordCount). + Option("dht-timeout", ropts.DhtTimeout). + Option("stream", true) + resp, err := req.Send(ctx) + if err != nil { + return nil, err + } + if resp.Error != nil { + return nil, resp.Error + } + + res := make(chan iface.IpnsResult) + + go func() { + defer close(res) + defer resp.Close() + + dec := json.NewDecoder(resp.Output) + + for { + var out struct{ Path string } + err := dec.Decode(&out) + if err == io.EOF { + return + } + var ires iface.IpnsResult + if err == nil { + ires.Path, err = iface.ParsePath(out.Path) + } + + select { + case res <- ires: + case <-ctx.Done(): + } + if err != nil { + return + } + } + }() + + return res, nil } func (api *NameAPI) Resolve(ctx context.Context, name string, opts ...caopts.NameResolveOption) (iface.Path, error) { @@ -75,7 +130,7 @@ func (api *NameAPI) Resolve(ctx context.Context, name string, opts ...caopts.Nam Option("nocache", !options.Cache). Option("recursive", ropts.Depth != 1). Option("dht-record-count", ropts.DhtRecordCount). - Option("dht-timeout", ropts.DhtTimeout.String()) + Option("dht-timeout", ropts.DhtTimeout) var out struct{ Path string } if err := req.Exec(ctx, &out); err != nil { diff --git a/client/httpapi/path.go b/client/httpapi/path.go index 68dc2633d..8c819121a 100644 --- a/client/httpapi/path.go +++ b/client/httpapi/path.go @@ -42,6 +42,11 @@ func (api *HttpApi) ResolvePath(ctx context.Context, path iface.Path) (iface.Res return iface.NewResolvedPath(ipath, out.Cid, root, out.RemPath), nil } -func (api *HttpApi) ResolveNode(context.Context, iface.Path) (ipld.Node, error) { - return nil, ErrNotImplemented +func (api *HttpApi) ResolveNode(ctx context.Context, p iface.Path) (ipld.Node, error) { + rp, err := api.ResolvePath(ctx, p) + if err != nil { + return nil, err + } + + return api.Dag().Get(ctx, rp.Cid()) } From 42273cab06348b19a813dee77f7cbe5ed7cc78d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 14 Feb 2019 19:05:17 +0100 Subject: [PATCH 0240/1212] Don't use valid() pattern This commit was moved from ipfs/go-ipfs-http-client@4d07c48f98b0af0b18c6c13f80f04c966fc43bdc --- client/httpapi/block.go | 20 +++++++------------- client/httpapi/key.go | 28 ++++++++++++++++------------ client/httpapi/name.go | 14 ++++---------- client/httpapi/pubsub.go | 12 +++++------- 4 files changed, 32 insertions(+), 42 deletions(-) diff --git a/client/httpapi/block.go b/client/httpapi/block.go index 45c73472c..fd4d9bab9 100644 --- a/client/httpapi/block.go +++ b/client/httpapi/block.go @@ -18,24 +18,16 @@ type BlockAPI HttpApi type blockStat struct { Key string BSize int `json:"Size"` + + cid cid.Cid } func (s *blockStat) Size() int { return s.BSize } -func (s *blockStat) valid() (iface.ResolvedPath, error) { - c, err := cid.Parse(s.Key) - if err != nil { - return nil, err - } - - return iface.IpldPath(c), nil -} - func (s *blockStat) Path() iface.ResolvedPath { - p, _ := s.valid() - return p + return iface.IpldPath(s.cid) } func (api *BlockAPI) Put(ctx context.Context, r io.Reader, opts ...caopts.BlockPutOption) (iface.BlockStat, error) { @@ -60,7 +52,8 @@ func (api *BlockAPI) Put(ctx context.Context, r io.Reader, opts ...caopts.BlockP if err := req.Exec(ctx, &out); err != nil { return nil, err } - if _, err := out.valid(); err != nil { + out.cid, err = cid.Parse(out.Key) + if err != nil { return nil, err } @@ -118,7 +111,8 @@ func (api *BlockAPI) Stat(ctx context.Context, p iface.Path) (iface.BlockStat, e if err != nil { return nil, err } - if _, err := out.valid(); err != nil { + out.cid, err = cid.Parse(out.Key) + if err != nil { return nil, err } diff --git a/client/httpapi/key.go b/client/httpapi/key.go index dc2adf8b7..a16c30d8e 100644 --- a/client/httpapi/key.go +++ b/client/httpapi/key.go @@ -14,6 +14,8 @@ type KeyAPI HttpApi type keyOutput struct { JName string `json:"Name"` Id string + + pid peer.ID } func (k *keyOutput) Name() string { @@ -26,13 +28,7 @@ func (k *keyOutput) Path() iface.Path { } func (k *keyOutput) ID() peer.ID { - p, _ := peer.IDB58Decode(k.Id) - return p -} - -func (k *keyOutput) valid() error { - _, err := peer.IDB58Decode(k.Id) - return err + return k.pid } func (api *KeyAPI) Generate(ctx context.Context, name string, opts ...caopts.KeyGenerateOption) (iface.Key, error) { @@ -49,7 +45,8 @@ func (api *KeyAPI) Generate(ctx context.Context, name string, opts ...caopts.Key if err != nil { return nil, err } - return &out, out.valid() + out.pid, err = peer.IDB58Decode(out.Id) + return &out, err } func (api *KeyAPI) Rename(ctx context.Context, oldName string, newName string, opts ...caopts.KeyRenameOption) (iface.Key, bool, error) { @@ -72,7 +69,8 @@ func (api *KeyAPI) Rename(ctx context.Context, oldName string, newName string, o } id := &keyOutput{JName: out.Now, Id: out.Id} - return id, out.Overwrite, id.valid() + id.pid, err = peer.IDB58Decode(id.Id) + return id, out.Overwrite, err } func (api *KeyAPI) List(ctx context.Context) ([]iface.Key, error) { @@ -83,7 +81,9 @@ func (api *KeyAPI) List(ctx context.Context) ([]iface.Key, error) { res := make([]iface.Key, len(out.Keys)) for i, k := range out.Keys { - if err := k.valid(); err != nil { + var err error + k.pid, err = peer.IDB58Decode(k.Id) + if err != nil { return nil, err } res[i] = k @@ -98,8 +98,10 @@ func (api *KeyAPI) Self(ctx context.Context) (iface.Key, error) { return nil, err } + var err error out := keyOutput{JName: "self", Id: id.ID} - return &out, out.valid() + out.pid, err = peer.IDB58Decode(out.Id) + return &out, err } func (api *KeyAPI) Remove(ctx context.Context, name string) (iface.Key, error) { @@ -111,7 +113,9 @@ func (api *KeyAPI) Remove(ctx context.Context, name string) (iface.Key, error) { return nil, errors.New("got unexpected number of keys back") } - return &out.Keys[0], out.Keys[0].valid() + var err error + out.Keys[0].pid, err = peer.IDB58Decode(out.Keys[0].Id) + return &out.Keys[0], err } func (api *KeyAPI) core() *HttpApi { diff --git a/client/httpapi/name.go b/client/httpapi/name.go index 58fb59249..b848aa819 100644 --- a/client/httpapi/name.go +++ b/client/httpapi/name.go @@ -16,10 +16,8 @@ type NameAPI HttpApi type ipnsEntry struct { JName string `json:"Name"` JValue string `json:"Value"` -} -func (e *ipnsEntry) valid() (iface.Path, error) { - return iface.ParsePath(e.JValue) + path iface.Path } func (e *ipnsEntry) Name() string { @@ -27,8 +25,7 @@ func (e *ipnsEntry) Name() string { } func (e *ipnsEntry) Value() iface.Path { - p, _ := e.valid() - return p + return e.path } func (api *NameAPI) Publish(ctx context.Context, p iface.Path, opts ...caopts.NamePublishOption) (iface.IpnsEntry, error) { @@ -51,11 +48,8 @@ func (api *NameAPI) Publish(ctx context.Context, p iface.Path, opts ...caopts.Na if err := req.Exec(ctx, &out); err != nil { return nil, err } - if _, err := out.valid(); err != nil { - return nil, err - } - - return &out, nil + out.path, err = iface.ParsePath(out.JValue) + return &out, err } func (api *NameAPI) Search(ctx context.Context, name string, opts ...caopts.NameResolveOption) (<-chan iface.IpnsResult, error) { diff --git a/client/httpapi/pubsub.go b/client/httpapi/pubsub.go index 334509780..e27cb5655 100644 --- a/client/httpapi/pubsub.go +++ b/client/httpapi/pubsub.go @@ -66,16 +66,12 @@ type pubsubMessage struct { JData []byte `json:"data,omitempty"` JSeqno []byte `json:"seqno,omitempty"` JTopicIDs []string `json:"topicIDs,omitempty"` -} -func (msg *pubsubMessage) valid() error { - _, err := peer.IDFromBytes(msg.JFrom) - return err + from peer.ID } func (msg *pubsubMessage) From() peer.ID { - id, _ := peer.IDFromBytes(msg.JFrom) - return id + return msg.from } func (msg *pubsubMessage) Data() []byte { @@ -97,7 +93,9 @@ func (s *pubsubSub) Next(ctx context.Context) (iface.PubSubMessage, error) { if err := s.dec.Decode(&msg); err != nil { return nil, err } - return &msg, msg.valid() + var err error + msg.from, err = peer.IDFromBytes(msg.JFrom) + return &msg, err } func (api *PubsubAPI) Subscribe(ctx context.Context, topic string, opts ...caopts.PubSubSubscribeOption) (iface.PubSubSubscription, error) { From 93f684617a3adbd7cba751ee421e32b75cd3dafa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 14 Feb 2019 19:07:45 +0100 Subject: [PATCH 0241/1212] dag: remove unused waitgroup This commit was moved from ipfs/go-ipfs-http-client@934fc60a7c41a14b679fd89fec3b349650a76c81 --- client/httpapi/dag.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/client/httpapi/dag.go b/client/httpapi/dag.go index 3f54ced34..a613d18de 100644 --- a/client/httpapi/dag.go +++ b/client/httpapi/dag.go @@ -39,13 +39,10 @@ func (api *HttpDagServ) Get(ctx context.Context, c cid.Cid) (format.Node, error) func (api *HttpDagServ) GetMany(ctx context.Context, cids []cid.Cid) <-chan *format.NodeOption { out := make(chan *format.NodeOption) - wg := sync.WaitGroup{} - wg.Add(len(cids)) for _, c := range cids { // TODO: Consider limiting concurrency of this somehow go func(c cid.Cid) { - defer wg.Done() n, err := api.Get(ctx, c) select { From cc964b4ab8ea5d059be2c05e64ecdca851dcd8b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 14 Feb 2019 19:15:21 +0100 Subject: [PATCH 0242/1212] Simplify Object.New, remove ipldnode.go This commit was moved from ipfs/go-ipfs-http-client@0752a6ee63a2ec42aabb6c9acac6ef6c4a94af38 --- client/httpapi/dag.go | 1 - client/httpapi/ipldnode.go | 113 ------------------------------------- client/httpapi/object.go | 34 +++++------ 3 files changed, 18 insertions(+), 130 deletions(-) delete mode 100644 client/httpapi/ipldnode.go diff --git a/client/httpapi/dag.go b/client/httpapi/dag.go index a613d18de..669b5f893 100644 --- a/client/httpapi/dag.go +++ b/client/httpapi/dag.go @@ -5,7 +5,6 @@ import ( "context" "fmt" "io/ioutil" - "sync" "github.com/ipfs/go-block-format" "github.com/ipfs/go-cid" diff --git a/client/httpapi/ipldnode.go b/client/httpapi/ipldnode.go deleted file mode 100644 index 43fa5d50d..000000000 --- a/client/httpapi/ipldnode.go +++ /dev/null @@ -1,113 +0,0 @@ -package httpapi - -import ( - "context" - "errors" - "io/ioutil" - "strconv" - - "github.com/ipfs/go-cid" - ipld "github.com/ipfs/go-ipld-format" - ipfspath "github.com/ipfs/go-path" - "github.com/ipfs/interface-go-ipfs-core" -) - -type ipldNode struct { - ctx context.Context //TODO: should we re-consider adding ctx to ipld interfaces? - path iface.ResolvedPath - api *HttpApi -} - -func (api *HttpApi) nodeFromPath(ctx context.Context, p iface.ResolvedPath) ipld.Node { - return &ipldNode{ - ctx: ctx, - path: p, - api: api, - } -} - -func (n *ipldNode) RawData() []byte { - r, err := n.api.Block().Get(n.ctx, n.path) - if err != nil { - panic(err) // TODO: eww, should we add errors too / better ideas? - } - - b, err := ioutil.ReadAll(r) - if err != nil { - panic(err) - } - - return b -} - -func (n *ipldNode) Cid() cid.Cid { - return n.path.Cid() -} - -func (n *ipldNode) String() string { - return n.Cid().String() -} - -func (n *ipldNode) Loggable() map[string]interface{} { - return nil //TODO: we can't really do better here, can we? -} - -// TODO: should we use 'full'/real ipld codecs for this? js-ipfs-api does that. -// We can also give people a choice -func (n *ipldNode) Resolve(path []string) (interface{}, []string, error) { - p := ipfspath.Join([]string{n.path.String(), ipfspath.Join(path)}) - - var out interface{} - n.api.request("dag/get", p).Exec(n.ctx, &out) - - // TODO: this is more than likely wrong, fix if we decide to stick with this 'http-ipld-node' hack - for len(path) > 0 { - switch o := out.(type) { - case map[string]interface{}: - v, ok := o[path[0]] - if !ok { - // TODO: ipld links - return nil, nil, errors.New("no element under this path") - } - out = v - case []interface{}: - n, err := strconv.ParseUint(path[0], 10, 32) - if err != nil { - return nil, nil, err - } - if len(o) < int(n) { - return nil, nil, errors.New("no element under this path") - } - out = o[n] - } - path = path[1:] - } - - return out, path, nil -} - -func (n *ipldNode) Tree(path string, depth int) []string { - panic("implement me") -} - -func (n *ipldNode) ResolveLink(path []string) (*ipld.Link, []string, error) { - panic("implement me") -} - -func (n *ipldNode) Copy() ipld.Node { - panic("implement me") -} - -func (n *ipldNode) Links() []*ipld.Link { - panic("implement me") -} - -func (n *ipldNode) Stat() (*ipld.NodeStat, error) { - panic("implement me") -} - -func (n *ipldNode) Size() (uint64, error) { - panic("implement me") -} - -var _ ipld.Node = &ipldNode{} diff --git a/client/httpapi/object.go b/client/httpapi/object.go index 3b648d82b..5a06f74d9 100644 --- a/client/httpapi/object.go +++ b/client/httpapi/object.go @@ -3,12 +3,15 @@ package httpapi import ( "bytes" "context" + "fmt" "io" "io/ioutil" "github.com/ipfs/go-cid" - "github.com/ipfs/go-ipld-format" + ipld "github.com/ipfs/go-ipld-format" "github.com/ipfs/go-merkledag" + dag "github.com/ipfs/go-merkledag" + ft "github.com/ipfs/go-unixfs" "github.com/ipfs/interface-go-ipfs-core" caopts "github.com/ipfs/interface-go-ipfs-core/options" ) @@ -19,24 +22,23 @@ type objectOut struct { Hash string } -func (api *ObjectAPI) New(ctx context.Context, opts ...caopts.ObjectNewOption) (format.Node, error) { +func (api *ObjectAPI) New(ctx context.Context, opts ...caopts.ObjectNewOption) (ipld.Node, error) { options, err := caopts.ObjectNewOptions(opts...) if err != nil { return nil, err } - var out objectOut - err = api.core().request("object/new", options.Type).Exec(ctx, &out) - if err != nil { - return nil, err + var n ipld.Node + switch options.Type { + case "empty": + n = new(dag.ProtoNode) + case "unixfs-dir": + n = ft.EmptyDirNode() + default: + return nil, fmt.Errorf("unknown object type: %s", options.Type) } - c, err := cid.Parse(out.Hash) - if err != nil { - return nil, err - } - - return api.core().nodeFromPath(ctx, iface.IpfsPath(c)), nil + return n, nil } func (api *ObjectAPI) Put(ctx context.Context, r io.Reader, opts ...caopts.ObjectPutOption) (iface.ResolvedPath, error) { @@ -64,7 +66,7 @@ func (api *ObjectAPI) Put(ctx context.Context, r io.Reader, opts ...caopts.Objec return iface.IpfsPath(c), nil } -func (api *ObjectAPI) Get(ctx context.Context, p iface.Path) (format.Node, error) { +func (api *ObjectAPI) Get(ctx context.Context, p iface.Path) (ipld.Node, error) { r, err := api.core().Block().Get(ctx, p) if err != nil { return nil, err @@ -96,7 +98,7 @@ func (api *ObjectAPI) Data(ctx context.Context, p iface.Path) (io.Reader, error) return b, nil } -func (api *ObjectAPI) Links(ctx context.Context, p iface.Path) ([]*format.Link, error) { +func (api *ObjectAPI) Links(ctx context.Context, p iface.Path) ([]*ipld.Link, error) { var out struct { Links []struct { Name string @@ -107,14 +109,14 @@ func (api *ObjectAPI) Links(ctx context.Context, p iface.Path) ([]*format.Link, if err := api.core().request("object/links", p.String()).Exec(ctx, &out); err != nil { return nil, err } - res := make([]*format.Link, len(out.Links)) + res := make([]*ipld.Link, len(out.Links)) for i, l := range out.Links { c, err := cid.Parse(l.Hash) if err != nil { return nil, err } - res[i] = &format.Link{ + res[i] = &ipld.Link{ Cid: c, Name: l.Name, Size: l.Size, From a23da822de54922faf1f82a86c25660e8cca8bcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 14 Feb 2019 19:35:32 +0100 Subject: [PATCH 0243/1212] swarm: attach peerid if needed This commit was moved from ipfs/go-ipfs-http-client@aa88b18ac497400d16b36af6489af50a003c298c --- client/httpapi/swarm.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/client/httpapi/swarm.go b/client/httpapi/swarm.go index d179b6540..0bb36aca3 100644 --- a/client/httpapi/swarm.go +++ b/client/httpapi/swarm.go @@ -17,6 +17,13 @@ type SwarmAPI HttpApi func (api *SwarmAPI) Connect(ctx context.Context, pi peerstore.PeerInfo) error { saddrs := make([]string, len(pi.Addrs)) for i, addr := range pi.Addrs { + if _, err := addr.ValueForProtocol(multiaddr.P_P2P); err == multiaddr.ErrProtocolNotFound { + pidma, err := multiaddr.NewComponent("p2p", pi.ID.Pretty()) + if err != nil { + return err + } + addr = addr.Encapsulate(pidma) + } saddrs[i] = addr.String() } From f005b8dc5666916ff2a0ff1eef58b7795670ec73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 18 Feb 2019 16:39:00 +0100 Subject: [PATCH 0244/1212] pin: verify: parse bad node cids early This commit was moved from ipfs/go-ipfs-http-client@7032dfc9b016f2c584e2102e80fb60c3ecf573ea --- client/httpapi/pin.go | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/client/httpapi/pin.go b/client/httpapi/pin.go index 4c4e5713c..b11efd35c 100644 --- a/client/httpapi/pin.go +++ b/client/httpapi/pin.go @@ -110,23 +110,18 @@ func (r *pinVerifyRes) BadNodes() []iface.BadPinNode { type badNode struct { Cid string JErr string `json:"Err"` + + cid cid.Cid } func (n *badNode) Path() iface.ResolvedPath { - c, err := cid.Parse(n.Cid) - if err != nil { - return nil // todo: handle this better - } - return iface.IpldPath(c) + return iface.IpldPath(n.cid) } func (n *badNode) Err() error { if n.JErr != "" { return errors.New(n.JErr) } - if _, err := cid.Parse(n.Cid); err != nil { - return err - } return nil } @@ -150,6 +145,13 @@ func (api *PinAPI) Verify(ctx context.Context) (<-chan iface.PinStatus, error) { return // todo: handle non io.EOF somehow } + for i, n := range out.JBadNodes { + out.JBadNodes[i].cid, err = cid.Decode(n.Cid) + if err != nil { + return + } + } + select { case res <- &out: case <-ctx.Done(): From 4a6d36d98b6527e9c13918ac901c4cbc68630b7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 18 Feb 2019 17:02:13 +0100 Subject: [PATCH 0245/1212] pubsub: handle ctx This commit was moved from ipfs/go-ipfs-http-client@d451a4943c5311d7e32fcf86f56bdc1eda977fc7 --- client/httpapi/pubsub.go | 70 ++++++++++++++++++++++++++++++++-------- 1 file changed, 56 insertions(+), 14 deletions(-) diff --git a/client/httpapi/pubsub.go b/client/httpapi/pubsub.go index e27cb5655..edc1a9709 100644 --- a/client/httpapi/pubsub.go +++ b/client/httpapi/pubsub.go @@ -57,8 +57,10 @@ func (api *PubsubAPI) Publish(ctx context.Context, topic string, message []byte) } type pubsubSub struct { - io.Closer - dec *json.Decoder + messages chan pubsubMessage + + done chan struct{} + rcloser io.Closer } type pubsubMessage struct { @@ -68,6 +70,7 @@ type pubsubMessage struct { JTopicIDs []string `json:"topicIDs,omitempty"` from peer.ID + err error } func (msg *pubsubMessage) From() peer.ID { @@ -87,15 +90,20 @@ func (msg *pubsubMessage) Topics() []string { } func (s *pubsubSub) Next(ctx context.Context) (iface.PubSubMessage, error) { - // TODO: handle ctx - - var msg pubsubMessage - if err := s.dec.Decode(&msg); err != nil { - return nil, err + select { + case msg, ok := <-s.messages: + if !ok { + return nil, io.EOF + } + if msg.err != nil { + return nil, msg.err + } + var err error + msg.from, err = peer.IDFromBytes(msg.JFrom) + return &msg, err + case <-ctx.Done(): + return nil, ctx.Err() } - var err error - msg.from, err = peer.IDFromBytes(msg.JFrom) - return &msg, err } func (api *PubsubAPI) Subscribe(ctx context.Context, topic string, opts ...caopts.PubSubSubscribeOption) (iface.PubSubSubscription, error) { @@ -114,10 +122,44 @@ func (api *PubsubAPI) Subscribe(ctx context.Context, topic string, opts ...caopt return nil, resp.Error } - return &pubsubSub{ - Closer: resp, - dec: json.NewDecoder(resp.Output), - }, nil + sub := &pubsubSub{ + messages: make(chan pubsubMessage), + done: make(chan struct{}), + } + + dec := json.NewDecoder(resp.Output) + + go func() { + defer close(sub.messages) + + for { + var msg pubsubMessage + if err := dec.Decode(&msg); err != nil { + if err == io.EOF { + return + } + msg.err = err + } + + select { + case sub.messages <- msg: + case <-sub.done: + return + case <-ctx.Done(): + return + } + } + }() + + return sub, nil +} + +func (s*pubsubSub) Close() error { + if s.done != nil { + close(s.done) + s.done = nil + } + return s.rcloser.Close() } func (api *PubsubAPI) core() *HttpApi { From 7229dbbf73fd925da390fc5db5a25caf398b1fe8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 18 Feb 2019 17:04:33 +0100 Subject: [PATCH 0246/1212] don't read all and then throw away the buffer This commit was moved from ipfs/go-ipfs-http-client@5c96c2954a5d45dd907dca9942d2773d76b8a71b --- client/httpapi/response.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/httpapi/response.go b/client/httpapi/response.go index 745c9a2a9..b9e83eb3d 100644 --- a/client/httpapi/response.go +++ b/client/httpapi/response.go @@ -139,7 +139,7 @@ func (r *Request) Send(c *http.Client) (*Response, error) { nresp.Output = nil // drain body and close - ioutil.ReadAll(resp.Body) + io.Copy(ioutil.Discard, resp.Body) resp.Body.Close() } From b6ace8dd401321b842c5f0054d9ed025fd19cd89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 18 Feb 2019 17:12:37 +0100 Subject: [PATCH 0247/1212] response: handle late errors This commit was moved from ipfs/go-ipfs-http-client@139e9e5ff1b52a92c169d28bf56ff58e36b49ca3 --- client/httpapi/requestbuilder.go | 4 ++-- client/httpapi/response.go | 11 ++++++++--- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/client/httpapi/requestbuilder.go b/client/httpapi/requestbuilder.go index 628ad03cd..af43ce236 100644 --- a/client/httpapi/requestbuilder.go +++ b/client/httpapi/requestbuilder.go @@ -103,11 +103,11 @@ func (r *RequestBuilder) Exec(ctx context.Context, res interface{}) error { } if res == nil { - httpRes.Close() + lateErr := httpRes.Close() if httpRes.Error != nil { return httpRes.Error } - return nil + return lateErr } return httpRes.Decode(res) diff --git a/client/httpapi/response.go b/client/httpapi/response.go index b9e83eb3d..f773130e8 100644 --- a/client/httpapi/response.go +++ b/client/httpapi/response.go @@ -39,9 +39,14 @@ type Response struct { func (r *Response) Close() error { if r.Output != nil { - // always drain output (response body) - //ioutil.ReadAll(r.Output) // TODO: might not be a good idea in case there is a lot of data - return r.Output.Close() + + // always drain output (response body) //TODO: make optional for things like cat + _, err1 := io.Copy(ioutil.Discard, r.Output) + err2 := r.Output.Close() + if err1 != nil { + return err1 + } + return err2 } return nil } From 7be8d01ee732be71f08f4482e0d5c5b61731ee81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 18 Feb 2019 17:27:12 +0100 Subject: [PATCH 0248/1212] response: option to disable output draining This commit was moved from ipfs/go-ipfs-http-client@9f3d9635fa4e977b6ec202c9e4f78ca1c64fc0dd --- client/httpapi/api.go | 1 + client/httpapi/apifile.go | 2 +- client/httpapi/pubsub.go | 4 ++-- client/httpapi/request.go | 2 ++ client/httpapi/requestbuilder.go | 7 +++++++ client/httpapi/response.go | 10 ++++++++-- 6 files changed, 21 insertions(+), 5 deletions(-) diff --git a/client/httpapi/api.go b/client/httpapi/api.go index e106d8d87..f74300216 100644 --- a/client/httpapi/api.go +++ b/client/httpapi/api.go @@ -131,6 +131,7 @@ func (api *HttpApi) request(command string, args ...string) *RequestBuilder { command: command, args: args, shell: api, + drainOut: true, } } diff --git a/client/httpapi/apifile.go b/client/httpapi/apifile.go index 864760684..e3cb85ea4 100644 --- a/client/httpapi/apifile.go +++ b/client/httpapi/apifile.go @@ -57,7 +57,7 @@ func (f *apiFile) reset() error { if f.r != nil { f.r.Close() } - req := f.core.request("cat", f.path.String()) + req := f.core.request("cat", f.path.String()).NoDrain() if f.at != 0 { req.Option("offset", f.at) } diff --git a/client/httpapi/pubsub.go b/client/httpapi/pubsub.go index edc1a9709..b3e45ed36 100644 --- a/client/httpapi/pubsub.go +++ b/client/httpapi/pubsub.go @@ -113,8 +113,8 @@ func (api *PubsubAPI) Subscribe(ctx context.Context, topic string, opts ...caopt } resp, err := api.core().request("pubsub/sub", topic). - Option("discover", options.Discover). - Send(ctx) + Option("discover", options.Discover).NoDrain().Send(ctx) + if err != nil { return nil, err } diff --git a/client/httpapi/request.go b/client/httpapi/request.go index 58c61ac67..18cfb7fd0 100644 --- a/client/httpapi/request.go +++ b/client/httpapi/request.go @@ -13,6 +13,7 @@ type Request struct { Opts map[string]string Body io.Reader Headers map[string]string + DrainOut bool // if set, resp.Close will read all remaining data } func NewRequest(ctx context.Context, url, command string, args ...string) *Request { @@ -30,5 +31,6 @@ func NewRequest(ctx context.Context, url, command string, args ...string) *Reque Args: args, Opts: opts, Headers: make(map[string]string), + DrainOut: true, } } diff --git a/client/httpapi/requestbuilder.go b/client/httpapi/requestbuilder.go index af43ce236..8b040522e 100644 --- a/client/httpapi/requestbuilder.go +++ b/client/httpapi/requestbuilder.go @@ -19,6 +19,7 @@ type RequestBuilder struct { opts map[string]string headers map[string]string body io.Reader + drainOut bool shell *HttpApi } @@ -84,6 +85,12 @@ func (r *RequestBuilder) Header(name, value string) *RequestBuilder { return r } +// NoDrain disables output draining in response closer +func (r *RequestBuilder) NoDrain() *RequestBuilder { + r.drainOut = false + return r +} + // Send sends the request and return the response. func (r *RequestBuilder) Send(ctx context.Context) (*Response, error) { r.shell.applyGlobal(r) diff --git a/client/httpapi/response.go b/client/httpapi/response.go index f773130e8..cd3cc2b71 100644 --- a/client/httpapi/response.go +++ b/client/httpapi/response.go @@ -35,13 +35,18 @@ func (r *trailerReader) Close() error { type Response struct { Output io.ReadCloser Error *Error + + drainOutput bool } func (r *Response) Close() error { if r.Output != nil { - // always drain output (response body) //TODO: make optional for things like cat - _, err1 := io.Copy(ioutil.Discard, r.Output) + // always drain output (response body) + var err1 error + if r.drainOutput { + _, err1 = io.Copy(ioutil.Discard, r.Output) + } err2 := r.Output.Close() if err1 != nil { return err1 @@ -114,6 +119,7 @@ func (r *Request) Send(c *http.Client) (*Response, error) { nresp := new(Response) + nresp.drainOutput = r.DrainOut nresp.Output = &trailerReader{resp} if resp.StatusCode >= http.StatusBadRequest { e := &Error{ From 3088776f8150fe6967a245cf0360f5219e2dc9b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 18 Feb 2019 17:30:02 +0100 Subject: [PATCH 0249/1212] swarm: always append peer IDs This commit was moved from ipfs/go-ipfs-http-client@49267901c71f77f098deaf8966aa2dcecf22c2df --- client/httpapi/swarm.go | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/client/httpapi/swarm.go b/client/httpapi/swarm.go index 0bb36aca3..13a814bc4 100644 --- a/client/httpapi/swarm.go +++ b/client/httpapi/swarm.go @@ -15,16 +15,14 @@ import ( type SwarmAPI HttpApi func (api *SwarmAPI) Connect(ctx context.Context, pi peerstore.PeerInfo) error { + pidma, err := multiaddr.NewComponent("p2p", pi.ID.Pretty()) + if err != nil { + return err + } + saddrs := make([]string, len(pi.Addrs)) for i, addr := range pi.Addrs { - if _, err := addr.ValueForProtocol(multiaddr.P_P2P); err == multiaddr.ErrProtocolNotFound { - pidma, err := multiaddr.NewComponent("p2p", pi.ID.Pretty()) - if err != nil { - return err - } - addr = addr.Encapsulate(pidma) - } - saddrs[i] = addr.String() + saddrs[i] = addr.Encapsulate(pidma).String() } return api.core().request("swarm/connect", saddrs...).Exec(ctx, nil) From 745bf92506bd488bde4f695c4d644e7d3b58f0a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 18 Feb 2019 17:32:40 +0100 Subject: [PATCH 0250/1212] gofmt This commit was moved from ipfs/go-ipfs-http-client@f3c2c350861470c05617cf74e7b78d06782bb706 --- client/httpapi/api.go | 6 +++--- client/httpapi/pubsub.go | 8 ++++---- client/httpapi/request.go | 22 +++++++++++----------- client/httpapi/requestbuilder.go | 10 +++++----- 4 files changed, 23 insertions(+), 23 deletions(-) diff --git a/client/httpapi/api.go b/client/httpapi/api.go index f74300216..6dbfe3b6a 100644 --- a/client/httpapi/api.go +++ b/client/httpapi/api.go @@ -128,9 +128,9 @@ func (api *HttpApi) WithOptions(opts ...caopts.ApiOption) (iface.CoreAPI, error) func (api *HttpApi) request(command string, args ...string) *RequestBuilder { return &RequestBuilder{ - command: command, - args: args, - shell: api, + command: command, + args: args, + shell: api, drainOut: true, } } diff --git a/client/httpapi/pubsub.go b/client/httpapi/pubsub.go index b3e45ed36..49c58ab88 100644 --- a/client/httpapi/pubsub.go +++ b/client/httpapi/pubsub.go @@ -59,7 +59,7 @@ func (api *PubsubAPI) Publish(ctx context.Context, topic string, message []byte) type pubsubSub struct { messages chan pubsubMessage - done chan struct{} + done chan struct{} rcloser io.Closer } @@ -70,7 +70,7 @@ type pubsubMessage struct { JTopicIDs []string `json:"topicIDs,omitempty"` from peer.ID - err error + err error } func (msg *pubsubMessage) From() peer.ID { @@ -124,7 +124,7 @@ func (api *PubsubAPI) Subscribe(ctx context.Context, topic string, opts ...caopt sub := &pubsubSub{ messages: make(chan pubsubMessage), - done: make(chan struct{}), + done: make(chan struct{}), } dec := json.NewDecoder(resp.Output) @@ -154,7 +154,7 @@ func (api *PubsubAPI) Subscribe(ctx context.Context, topic string, opts ...caopt return sub, nil } -func (s*pubsubSub) Close() error { +func (s *pubsubSub) Close() error { if s.done != nil { close(s.done) s.done = nil diff --git a/client/httpapi/request.go b/client/httpapi/request.go index 18cfb7fd0..d65d63835 100644 --- a/client/httpapi/request.go +++ b/client/httpapi/request.go @@ -7,12 +7,12 @@ import ( ) type Request struct { - ApiBase string - Command string - Args []string - Opts map[string]string - Body io.Reader - Headers map[string]string + ApiBase string + Command string + Args []string + Opts map[string]string + Body io.Reader + Headers map[string]string DrainOut bool // if set, resp.Close will read all remaining data } @@ -26,11 +26,11 @@ func NewRequest(ctx context.Context, url, command string, args ...string) *Reque "stream-channels": "true", } return &Request{ - ApiBase: url + "/api/v0", - Command: command, - Args: args, - Opts: opts, - Headers: make(map[string]string), + ApiBase: url + "/api/v0", + Command: command, + Args: args, + Opts: opts, + Headers: make(map[string]string), DrainOut: true, } } diff --git a/client/httpapi/requestbuilder.go b/client/httpapi/requestbuilder.go index 8b040522e..c5bc44124 100644 --- a/client/httpapi/requestbuilder.go +++ b/client/httpapi/requestbuilder.go @@ -14,11 +14,11 @@ import ( // RequestBuilder is an IPFS commands request builder. type RequestBuilder struct { - command string - args []string - opts map[string]string - headers map[string]string - body io.Reader + command string + args []string + opts map[string]string + headers map[string]string + body io.Reader drainOut bool shell *HttpApi From 8542b6569a6169c39694cda227378484b6b40e18 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Tue, 19 Feb 2019 02:39:21 -0800 Subject: [PATCH 0251/1212] errors: introduce a 'not supported' error This commit was moved from ipfs/interface-go-ipfs-core@a81e4359ce5808c1de22b5ec3c6f05b83d86499d This commit was moved from ipfs/boxo@2c70ad1761014168a0bdd27b6ec4628cb08e1001 --- core/coreiface/errors.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/core/coreiface/errors.go b/core/coreiface/errors.go index 234abe566..e0bd7805d 100644 --- a/core/coreiface/errors.go +++ b/core/coreiface/errors.go @@ -3,7 +3,8 @@ package iface import "errors" var ( - ErrIsDir = errors.New("this dag node is a directory") - ErrNotFile = errors.New("this dag node is not a regular file") - ErrOffline = errors.New("this action must be run in online mode, try running 'ipfs daemon' first") + ErrIsDir = errors.New("this dag node is a directory") + ErrNotFile = errors.New("this dag node is not a regular file") + ErrOffline = errors.New("this action must be run in online mode, try running 'ipfs daemon' first") + ErrNotSupported = errors.New("operation not supported") ) From 27aa13fe44561e8d9469ce537e64baa60d17a705 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 19 Feb 2019 21:53:17 +0100 Subject: [PATCH 0252/1212] return errors from constructor methods This commit was moved from ipfs/go-ipfs-http-client@dbee4e27aaf9ef8e3fa7e25ac1f4f28df8a31e0d --- client/httpapi/api.go | 39 ++++++++++++++++---------------------- client/httpapi/api_test.go | 5 ++++- 2 files changed, 20 insertions(+), 24 deletions(-) diff --git a/client/httpapi/api.go b/client/httpapi/api.go index 6dbfe3b6a..e4603bd38 100644 --- a/client/httpapi/api.go +++ b/client/httpapi/api.go @@ -29,8 +29,7 @@ type HttpApi struct { applyGlobal func(*RequestBuilder) } -//TODO: Return errors here -func NewLocalApi() iface.CoreAPI { +func NewLocalApi() (iface.CoreAPI, error) { baseDir := os.Getenv(EnvDir) if baseDir == "" { baseDir = DefaultPathRoot @@ -39,40 +38,34 @@ func NewLocalApi() iface.CoreAPI { return NewPathApi(baseDir) } -func NewPathApi(p string) iface.CoreAPI { - a := ApiAddr(p) - if a == nil { - return nil +func NewPathApi(p string) (iface.CoreAPI, error) { + a, err := ApiAddr(p) + if err != nil { + if err == os.ErrNotExist { + err = nil + } + return nil, err } return NewApi(a) } -func ApiAddr(ipfspath string) ma.Multiaddr { +func ApiAddr(ipfspath string) (ma.Multiaddr, error) { baseDir, err := homedir.Expand(ipfspath) if err != nil { - return nil + return nil, err } apiFile := path.Join(baseDir, DefaultApiFile) - if _, err := os.Stat(apiFile); err != nil { - return nil - } - api, err := ioutil.ReadFile(apiFile) if err != nil { - return nil + return nil, err } - maddr, err := ma.NewMultiaddr(strings.TrimSpace(string(api))) - if err != nil { - return nil - } - - return maddr + return ma.NewMultiaddr(strings.TrimSpace(string(api))) } -func NewApi(a ma.Multiaddr) *HttpApi { // TODO: should be MAddr? +func NewApi(a ma.Multiaddr) (*HttpApi, error) { c := &gohttp.Client{ Transport: &gohttp.Transport{ Proxy: gohttp.ProxyFromEnvironment, @@ -83,10 +76,10 @@ func NewApi(a ma.Multiaddr) *HttpApi { // TODO: should be MAddr? return NewApiWithClient(a, c) } -func NewApiWithClient(a ma.Multiaddr, c *gohttp.Client) *HttpApi { +func NewApiWithClient(a ma.Multiaddr, c *gohttp.Client) (*HttpApi, error) { _, url, err := manet.DialArgs(a) if err != nil { - return nil // TODO: return that error + return nil, err } if a, err := ma.NewMultiaddr(url); err == nil { @@ -107,7 +100,7 @@ func NewApiWithClient(a ma.Multiaddr, c *gohttp.Client) *HttpApi { return fmt.Errorf("unexpected redirect") } - return api + return api, nil } func (api *HttpApi) WithOptions(opts ...caopts.ApiOption) (iface.CoreAPI, error) { diff --git a/client/httpapi/api_test.go b/client/httpapi/api_test.go index af2180384..2f6d47c58 100644 --- a/client/httpapi/api_test.go +++ b/client/httpapi/api_test.go @@ -157,7 +157,10 @@ func (NodeProvider) makeAPISwarm(ctx context.Context, fullIdentity bool, n int) DisableCompression: true, }, } - apis[i] = NewApiWithClient(maddr, c) + apis[i], err = NewApiWithClient(maddr, c) + if err != nil { + panic(err) + } // empty node is pinned even with --empty-repo, we don't want that emptyNode, err := iface.ParsePath("/ipfs/QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn") From fc299e7e849d46e364204234f9ea3d3aa52e42cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 19 Feb 2019 22:19:56 +0100 Subject: [PATCH 0253/1212] pin verify: use temporary struct This commit was moved from ipfs/go-ipfs-http-client@e400fa3b380b589c2ae385a66a007d685147e4c7 --- client/httpapi/pin.go | 57 +++++++++++++++++++++++++++---------------- 1 file changed, 36 insertions(+), 21 deletions(-) diff --git a/client/httpapi/pin.go b/client/httpapi/pin.go index b11efd35c..f667a5487 100644 --- a/client/httpapi/pin.go +++ b/client/httpapi/pin.go @@ -90,27 +90,20 @@ func (api *PinAPI) Update(ctx context.Context, from iface.Path, to iface.Path, o } type pinVerifyRes struct { - Cid string - JOk bool `json:"Ok"` - JBadNodes []*badNode `json:"BadNodes,omitempty"` + ok bool + badNodes []iface.BadPinNode } func (r *pinVerifyRes) Ok() bool { - return r.JOk + return r.ok } func (r *pinVerifyRes) BadNodes() []iface.BadPinNode { - out := make([]iface.BadPinNode, len(r.JBadNodes)) - for i, n := range r.JBadNodes { - out[i] = n - } - return out + return r.badNodes } type badNode struct { - Cid string - JErr string `json:"Err"` - + err error cid cid.Cid } @@ -119,10 +112,7 @@ func (n *badNode) Path() iface.ResolvedPath { } func (n *badNode) Err() error { - if n.JErr != "" { - return errors.New(n.JErr) - } - return nil + return n.err } func (api *PinAPI) Verify(ctx context.Context) (<-chan iface.PinStatus, error) { @@ -140,20 +130,45 @@ func (api *PinAPI) Verify(ctx context.Context) (<-chan iface.PinStatus, error) { defer close(res) dec := json.NewDecoder(resp.Output) for { - var out pinVerifyRes + var out struct { + Cid string + Ok bool + + BadNodes []struct{ + Cid string + Err string + } + } if err := dec.Decode(&out); err != nil { return // todo: handle non io.EOF somehow } - for i, n := range out.JBadNodes { - out.JBadNodes[i].cid, err = cid.Decode(n.Cid) + badNodes := make([]iface.BadPinNode, len(out.BadNodes)) + for i, n := range out.BadNodes { + c, err := cid.Decode(n.Cid) if err != nil { - return + badNodes[i] = &badNode{ + cid: c, + err: err, + } + continue + } + + if n.Err != "" { + err = errors.New(n.Err) + } + badNodes[i] = &badNode{ + cid: c, + err: err, } } select { - case res <- &out: + case res <- &pinVerifyRes{ + ok: out.Ok, + + badNodes: badNodes, + }: case <-ctx.Done(): return } From a058e7d31a32d1bca98e41886a310149b872af84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 19 Feb 2019 22:27:48 +0100 Subject: [PATCH 0254/1212] response: Document zero-result Decode behaviour This commit was moved from ipfs/go-ipfs-http-client@902bc5ef8c1b9595e97728dca3da0d0da124f142 --- client/httpapi/response.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/client/httpapi/response.go b/client/httpapi/response.go index cd3cc2b71..26f549c9a 100644 --- a/client/httpapi/response.go +++ b/client/httpapi/response.go @@ -71,6 +71,9 @@ func (r *Response) Decode(dec interface{}) error { } n++ } + + // Decode expects at least one result. For calls where zero results are valid, + // use Send and construct json Decoder manually. if n > 0 && err == io.EOF { err = nil } From db1af499c9d661a70ac6fcce9cc7347b934385e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 19 Feb 2019 22:33:57 +0100 Subject: [PATCH 0255/1212] use mime.ParseMediaType for Content-Type response parsing This commit was moved from ipfs/go-ipfs-http-client@217d1945237321c12f96abef82707217a30813b0 --- client/httpapi/response.go | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/client/httpapi/response.go b/client/httpapi/response.go index 26f549c9a..708d2714f 100644 --- a/client/httpapi/response.go +++ b/client/httpapi/response.go @@ -4,14 +4,13 @@ import ( "encoding/json" "errors" "fmt" + "github.com/ipfs/go-ipfs-files" "io" "io/ioutil" + "mime" "net/http" "net/url" "os" - "strings" - - files "github.com/ipfs/go-ipfs-files" ) type trailerReader struct { @@ -116,9 +115,11 @@ func (r *Request) Send(c *http.Client) (*Response, error) { return nil, err } - contentType := resp.Header.Get("Content-Type") - parts := strings.Split(contentType, ";") - contentType = parts[0] + + contentType, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return nil, err + } nresp := new(Response) From f34788e6ee61aad0ee1970a4f3d004bdebdbcd27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 19 Feb 2019 23:11:08 +0100 Subject: [PATCH 0256/1212] cleanup Swarm.Peers This commit was moved from ipfs/go-ipfs-http-client@fd7858dc57b86761599b0e844f3536f2d4a0d953 --- client/httpapi/api.go | 1 - client/httpapi/apifile.go | 14 +++--- client/httpapi/pubsub.go | 9 ++-- client/httpapi/request.go | 2 - client/httpapi/requestbuilder.go | 7 --- client/httpapi/response.go | 19 +++++--- client/httpapi/swarm.go | 83 +++++++++++++++++--------------- 7 files changed, 69 insertions(+), 66 deletions(-) diff --git a/client/httpapi/api.go b/client/httpapi/api.go index e4603bd38..c5a706d05 100644 --- a/client/httpapi/api.go +++ b/client/httpapi/api.go @@ -124,7 +124,6 @@ func (api *HttpApi) request(command string, args ...string) *RequestBuilder { command: command, args: args, shell: api, - drainOut: true, } } diff --git a/client/httpapi/apifile.go b/client/httpapi/apifile.go index e3cb85ea4..a8eb0de1a 100644 --- a/client/httpapi/apifile.go +++ b/client/httpapi/apifile.go @@ -49,15 +49,15 @@ type apiFile struct { size int64 path iface.Path - r io.ReadCloser + r *Response at int64 } func (f *apiFile) reset() error { if f.r != nil { - f.r.Close() + f.r.Cancel() } - req := f.core.request("cat", f.path.String()).NoDrain() + req := f.core.request("cat", f.path.String()) if f.at != 0 { req.Option("offset", f.at) } @@ -68,12 +68,12 @@ func (f *apiFile) reset() error { if resp.Error != nil { return resp.Error } - f.r = resp.Output + f.r = resp return nil } func (f *apiFile) Read(p []byte) (int, error) { - n, err := f.r.Read(p) + n, err := f.r.Output.Read(p) if n > 0 { f.at += int64(n) } @@ -92,7 +92,7 @@ func (f *apiFile) Seek(offset int64, whence int) (int64, error) { } if f.at < offset && offset-f.at < forwardSeekLimit { //forward skip - r, err := io.CopyN(ioutil.Discard, f.r, offset-f.at) + r, err := io.CopyN(ioutil.Discard, f.r.Output, offset-f.at) f.at += r return f.at, err @@ -103,7 +103,7 @@ func (f *apiFile) Seek(offset int64, whence int) (int64, error) { func (f *apiFile) Close() error { if f.r != nil { - return f.r.Close() + return f.r.Cancel() } return nil } diff --git a/client/httpapi/pubsub.go b/client/httpapi/pubsub.go index 49c58ab88..2ac04b53c 100644 --- a/client/httpapi/pubsub.go +++ b/client/httpapi/pubsub.go @@ -60,7 +60,7 @@ type pubsubSub struct { messages chan pubsubMessage done chan struct{} - rcloser io.Closer + rcloser func() error } type pubsubMessage struct { @@ -113,7 +113,7 @@ func (api *PubsubAPI) Subscribe(ctx context.Context, topic string, opts ...caopt } resp, err := api.core().request("pubsub/sub", topic). - Option("discover", options.Discover).NoDrain().Send(ctx) + Option("discover", options.Discover).Send(ctx) if err != nil { return nil, err @@ -125,6 +125,9 @@ func (api *PubsubAPI) Subscribe(ctx context.Context, topic string, opts ...caopt sub := &pubsubSub{ messages: make(chan pubsubMessage), done: make(chan struct{}), + rcloser: func() error { + return resp.Cancel() + }, } dec := json.NewDecoder(resp.Output) @@ -159,7 +162,7 @@ func (s *pubsubSub) Close() error { close(s.done) s.done = nil } - return s.rcloser.Close() + return s.rcloser() } func (api *PubsubAPI) core() *HttpApi { diff --git a/client/httpapi/request.go b/client/httpapi/request.go index d65d63835..f6f7ee486 100644 --- a/client/httpapi/request.go +++ b/client/httpapi/request.go @@ -13,7 +13,6 @@ type Request struct { Opts map[string]string Body io.Reader Headers map[string]string - DrainOut bool // if set, resp.Close will read all remaining data } func NewRequest(ctx context.Context, url, command string, args ...string) *Request { @@ -31,6 +30,5 @@ func NewRequest(ctx context.Context, url, command string, args ...string) *Reque Args: args, Opts: opts, Headers: make(map[string]string), - DrainOut: true, } } diff --git a/client/httpapi/requestbuilder.go b/client/httpapi/requestbuilder.go index c5bc44124..ba407217f 100644 --- a/client/httpapi/requestbuilder.go +++ b/client/httpapi/requestbuilder.go @@ -19,7 +19,6 @@ type RequestBuilder struct { opts map[string]string headers map[string]string body io.Reader - drainOut bool shell *HttpApi } @@ -85,12 +84,6 @@ func (r *RequestBuilder) Header(name, value string) *RequestBuilder { return r } -// NoDrain disables output draining in response closer -func (r *RequestBuilder) NoDrain() *RequestBuilder { - r.drainOut = false - return r -} - // Send sends the request and return the response. func (r *RequestBuilder) Send(ctx context.Context) (*Response, error) { r.shell.applyGlobal(r) diff --git a/client/httpapi/response.go b/client/httpapi/response.go index 708d2714f..c9f178f9c 100644 --- a/client/httpapi/response.go +++ b/client/httpapi/response.go @@ -34,18 +34,13 @@ func (r *trailerReader) Close() error { type Response struct { Output io.ReadCloser Error *Error - - drainOutput bool } func (r *Response) Close() error { if r.Output != nil { - // always drain output (response body) - var err1 error - if r.drainOutput { - _, err1 = io.Copy(ioutil.Discard, r.Output) - } + // drain output (response body) + _, err1 := io.Copy(ioutil.Discard, r.Output) err2 := r.Output.Close() if err1 != nil { return err1 @@ -55,6 +50,15 @@ func (r *Response) Close() error { return nil } +// Cancel aborts running request (without draining request body) +func (r *Response) Cancel() error { + if r.Output != nil { + return r.Output.Close() + } + + return nil +} + func (r *Response) Decode(dec interface{}) error { defer r.Close() if r.Error != nil { @@ -123,7 +127,6 @@ func (r *Request) Send(c *http.Client) (*Response, error) { nresp := new(Response) - nresp.drainOutput = r.DrainOut nresp.Output = &trailerReader{resp} if resp.StatusCode >= http.StatusBadRequest { e := &Error{ diff --git a/client/httpapi/swarm.go b/client/httpapi/swarm.go index 13a814bc4..882711917 100644 --- a/client/httpapi/swarm.go +++ b/client/httpapi/swarm.go @@ -32,74 +32,81 @@ func (api *SwarmAPI) Disconnect(ctx context.Context, addr multiaddr.Multiaddr) e return api.core().request("swarm/disconnect", addr.String()).Exec(ctx, nil) } -type streamInfo struct { - Protocol string -} - type connInfo struct { - Addr string - Peer string - JLatency time.Duration `json:"Latency"` - Muxer string - JDirection inet.Direction `json:"Direction"` - JStreams []streamInfo `json:"Streams"` -} - -func (c *connInfo) valid() error { - _, err := multiaddr.NewMultiaddr(c.Addr) - if err != nil { - return err - } - - _, err = peer.IDB58Decode(c.Peer) - return err + addr multiaddr.Multiaddr + peer peer.ID + latency time.Duration + muxer string + direction inet.Direction + streams []protocol.ID } func (c *connInfo) ID() peer.ID { - id, _ := peer.IDB58Decode(c.Peer) - return id + return c.peer } func (c *connInfo) Address() multiaddr.Multiaddr { - a, _ := multiaddr.NewMultiaddr(c.Addr) - return a + return c.addr } func (c *connInfo) Direction() inet.Direction { - return c.JDirection + return c.direction } func (c *connInfo) Latency() (time.Duration, error) { - return c.JLatency, nil + return c.latency, nil } func (c *connInfo) Streams() ([]protocol.ID, error) { - res := make([]protocol.ID, len(c.JStreams)) - for i, stream := range c.JStreams { - res[i] = protocol.ID(stream.Protocol) - } - return res, nil + return c.streams, nil } func (api *SwarmAPI) Peers(ctx context.Context) ([]iface.ConnectionInfo, error) { - var out struct { - Peers []*connInfo + var resp struct { + Peers []struct{ + Addr string + Peer string + Latency time.Duration + Muxer string + Direction inet.Direction + Streams []struct { + Protocol string + } + } } err := api.core().request("swarm/peers"). Option("streams", true). Option("latency", true). - Exec(ctx, &out) + Exec(ctx, &resp) if err != nil { return nil, err } - res := make([]iface.ConnectionInfo, len(out.Peers)) - for i, conn := range out.Peers { - if err := conn.valid(); err != nil { + res := make([]iface.ConnectionInfo, len(resp.Peers)) + for i, conn := range resp.Peers { + out := &connInfo{ + latency: conn.Latency, + muxer: conn.Muxer, + direction: conn.Direction, + } + + out.peer, err = peer.IDB58Decode(conn.Peer) + if err != nil { return nil, err } - res[i] = conn + + out.addr, err = multiaddr.NewMultiaddr(conn.Addr) + if err != nil { + return nil, err + } + + out.streams = make([]protocol.ID, len(conn.Streams)) + for i, p := range conn.Streams { + out.streams[i] = protocol.ID(p.Protocol) + } + + res[i] = out } return res, nil From aa4d6e16f13bd753b77d0a8fc2174e41af89310e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 19 Feb 2019 23:26:34 +0100 Subject: [PATCH 0257/1212] Add some docs to constructors This commit was moved from ipfs/go-ipfs-http-client@e34cd600e690bfa9bd20d6089b9335ac6090d4dd --- client/httpapi/api.go | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/client/httpapi/api.go b/client/httpapi/api.go index c5a706d05..9e8d55188 100644 --- a/client/httpapi/api.go +++ b/client/httpapi/api.go @@ -22,6 +22,11 @@ const ( EnvDir = "IPFS_PATH" ) +// HttpApi implements github.com/ipfs/interface-go-ipfs-core/CoreAPI using +// IPFS HTTP API. +// +// For interface docs see +// https://godoc.org/github.com/ipfs/interface-go-ipfs-core#CoreAPI type HttpApi struct { url string httpcli gohttp.Client @@ -29,6 +34,11 @@ type HttpApi struct { applyGlobal func(*RequestBuilder) } +// NewLocalApi tries to construct new HttpApi instance communicating with local +// IPFS daemon +// +// Daemon api address is pulled from the $IPFS_PATH/api file. +// If $IPFS_PATH env var is not present, it defaults to ~/.ipfs func NewLocalApi() (iface.CoreAPI, error) { baseDir := os.Getenv(EnvDir) if baseDir == "" { @@ -38,8 +48,10 @@ func NewLocalApi() (iface.CoreAPI, error) { return NewPathApi(baseDir) } -func NewPathApi(p string) (iface.CoreAPI, error) { - a, err := ApiAddr(p) +// NewPathApi constructs new HttpApi by pulling api address from specified +// ipfspath. Api file should be located at $ipfspath/api +func NewPathApi(ipfspath string) (iface.CoreAPI, error) { + a, err := ApiAddr(ipfspath) if err != nil { if err == os.ErrNotExist { err = nil @@ -49,6 +61,7 @@ func NewPathApi(p string) (iface.CoreAPI, error) { return NewApi(a) } +// ApiAddr reads api file in specified ipfs path func ApiAddr(ipfspath string) (ma.Multiaddr, error) { baseDir, err := homedir.Expand(ipfspath) if err != nil { @@ -65,6 +78,7 @@ func ApiAddr(ipfspath string) (ma.Multiaddr, error) { return ma.NewMultiaddr(strings.TrimSpace(string(api))) } +// NewApi constructs HttpApi with specified endpoint func NewApi(a ma.Multiaddr) (*HttpApi, error) { c := &gohttp.Client{ Transport: &gohttp.Transport{ @@ -76,6 +90,7 @@ func NewApi(a ma.Multiaddr) (*HttpApi, error) { return NewApiWithClient(a, c) } +// NewApiWithClient constructs HttpApi with specified endpoint and custom http client func NewApiWithClient(a ma.Multiaddr, c *gohttp.Client) (*HttpApi, error) { _, url, err := manet.DialArgs(a) if err != nil { From f6a3a4fb2d715ffc0394408287b23eae0d322631 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 19 Feb 2019 23:28:39 +0100 Subject: [PATCH 0258/1212] gofmt This commit was moved from ipfs/go-ipfs-http-client@65cd935e13a2ea05befbc69d72d64a89056952ea --- client/httpapi/api.go | 6 +++--- client/httpapi/pin.go | 4 ++-- client/httpapi/request.go | 22 +++++++++++----------- client/httpapi/requestbuilder.go | 10 +++++----- client/httpapi/response.go | 1 - client/httpapi/swarm.go | 18 +++++++++--------- 6 files changed, 30 insertions(+), 31 deletions(-) diff --git a/client/httpapi/api.go b/client/httpapi/api.go index 9e8d55188..b67fb0b48 100644 --- a/client/httpapi/api.go +++ b/client/httpapi/api.go @@ -136,9 +136,9 @@ func (api *HttpApi) WithOptions(opts ...caopts.ApiOption) (iface.CoreAPI, error) func (api *HttpApi) request(command string, args ...string) *RequestBuilder { return &RequestBuilder{ - command: command, - args: args, - shell: api, + command: command, + args: args, + shell: api, } } diff --git a/client/httpapi/pin.go b/client/httpapi/pin.go index f667a5487..0111d626a 100644 --- a/client/httpapi/pin.go +++ b/client/httpapi/pin.go @@ -132,9 +132,9 @@ func (api *PinAPI) Verify(ctx context.Context) (<-chan iface.PinStatus, error) { for { var out struct { Cid string - Ok bool + Ok bool - BadNodes []struct{ + BadNodes []struct { Cid string Err string } diff --git a/client/httpapi/request.go b/client/httpapi/request.go index f6f7ee486..58c61ac67 100644 --- a/client/httpapi/request.go +++ b/client/httpapi/request.go @@ -7,12 +7,12 @@ import ( ) type Request struct { - ApiBase string - Command string - Args []string - Opts map[string]string - Body io.Reader - Headers map[string]string + ApiBase string + Command string + Args []string + Opts map[string]string + Body io.Reader + Headers map[string]string } func NewRequest(ctx context.Context, url, command string, args ...string) *Request { @@ -25,10 +25,10 @@ func NewRequest(ctx context.Context, url, command string, args ...string) *Reque "stream-channels": "true", } return &Request{ - ApiBase: url + "/api/v0", - Command: command, - Args: args, - Opts: opts, - Headers: make(map[string]string), + ApiBase: url + "/api/v0", + Command: command, + Args: args, + Opts: opts, + Headers: make(map[string]string), } } diff --git a/client/httpapi/requestbuilder.go b/client/httpapi/requestbuilder.go index ba407217f..af43ce236 100644 --- a/client/httpapi/requestbuilder.go +++ b/client/httpapi/requestbuilder.go @@ -14,11 +14,11 @@ import ( // RequestBuilder is an IPFS commands request builder. type RequestBuilder struct { - command string - args []string - opts map[string]string - headers map[string]string - body io.Reader + command string + args []string + opts map[string]string + headers map[string]string + body io.Reader shell *HttpApi } diff --git a/client/httpapi/response.go b/client/httpapi/response.go index c9f178f9c..84f28214d 100644 --- a/client/httpapi/response.go +++ b/client/httpapi/response.go @@ -119,7 +119,6 @@ func (r *Request) Send(c *http.Client) (*Response, error) { return nil, err } - contentType, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) if err != nil { return nil, err diff --git a/client/httpapi/swarm.go b/client/httpapi/swarm.go index 882711917..0814debee 100644 --- a/client/httpapi/swarm.go +++ b/client/httpapi/swarm.go @@ -33,10 +33,10 @@ func (api *SwarmAPI) Disconnect(ctx context.Context, addr multiaddr.Multiaddr) e } type connInfo struct { - addr multiaddr.Multiaddr - peer peer.ID + addr multiaddr.Multiaddr + peer peer.ID latency time.Duration - muxer string + muxer string direction inet.Direction streams []protocol.ID } @@ -63,11 +63,11 @@ func (c *connInfo) Streams() ([]protocol.ID, error) { func (api *SwarmAPI) Peers(ctx context.Context) ([]iface.ConnectionInfo, error) { var resp struct { - Peers []struct{ - Addr string - Peer string + Peers []struct { + Addr string + Peer string Latency time.Duration - Muxer string + Muxer string Direction inet.Direction Streams []struct { Protocol string @@ -86,8 +86,8 @@ func (api *SwarmAPI) Peers(ctx context.Context) ([]iface.ConnectionInfo, error) res := make([]iface.ConnectionInfo, len(resp.Peers)) for i, conn := range resp.Peers { out := &connInfo{ - latency: conn.Latency, - muxer: conn.Muxer, + latency: conn.Latency, + muxer: conn.Muxer, direction: conn.Direction, } From ad844e3d0b0221333c04896ed80f11afed301495 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 20 Feb 2019 16:50:38 +0100 Subject: [PATCH 0259/1212] response: simplify Decode This commit was moved from ipfs/go-ipfs-http-client@adbfda4c1c6ee037df3f91ca73f60de1f4620d67 --- client/httpapi/api.go | 2 +- client/httpapi/requestbuilder.go | 2 +- client/httpapi/response.go | 20 +++----------------- 3 files changed, 5 insertions(+), 19 deletions(-) diff --git a/client/httpapi/api.go b/client/httpapi/api.go index b67fb0b48..17a289cc5 100644 --- a/client/httpapi/api.go +++ b/client/httpapi/api.go @@ -53,7 +53,7 @@ func NewLocalApi() (iface.CoreAPI, error) { func NewPathApi(ipfspath string) (iface.CoreAPI, error) { a, err := ApiAddr(ipfspath) if err != nil { - if err == os.ErrNotExist { + if os.IsNotExist(err) { err = nil } return nil, err diff --git a/client/httpapi/requestbuilder.go b/client/httpapi/requestbuilder.go index af43ce236..2ffed7a0a 100644 --- a/client/httpapi/requestbuilder.go +++ b/client/httpapi/requestbuilder.go @@ -110,5 +110,5 @@ func (r *RequestBuilder) Exec(ctx context.Context, res interface{}) error { return lateErr } - return httpRes.Decode(res) + return httpRes.decode(res) } diff --git a/client/httpapi/response.go b/client/httpapi/response.go index 84f28214d..794cd1470 100644 --- a/client/httpapi/response.go +++ b/client/httpapi/response.go @@ -59,28 +59,14 @@ func (r *Response) Cancel() error { return nil } -func (r *Response) Decode(dec interface{}) error { +// Decode reads request body and decodes it as json +func (r *Response) decode(dec interface{}) error { defer r.Close() if r.Error != nil { return r.Error } - n := 0 - var err error - for { - err = json.NewDecoder(r.Output).Decode(dec) - if err != nil { - break - } - n++ - } - - // Decode expects at least one result. For calls where zero results are valid, - // use Send and construct json Decoder manually. - if n > 0 && err == io.EOF { - err = nil - } - return err + return json.NewDecoder(r.Output).Decode(dec) } type Error struct { From 19d91fbb259220e91c8887ee8a09218865418720 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 20 Feb 2019 22:08:02 +0100 Subject: [PATCH 0260/1212] response: pass close error in decode This commit was moved from ipfs/go-ipfs-http-client@4a87232ecaa96246f038d15eb7ee6094216a201e --- client/httpapi/response.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/client/httpapi/response.go b/client/httpapi/response.go index 794cd1470..624a488d7 100644 --- a/client/httpapi/response.go +++ b/client/httpapi/response.go @@ -61,12 +61,17 @@ func (r *Response) Cancel() error { // Decode reads request body and decodes it as json func (r *Response) decode(dec interface{}) error { - defer r.Close() if r.Error != nil { return r.Error } - return json.NewDecoder(r.Output).Decode(dec) + err := json.NewDecoder(r.Output).Decode(dec) + err2 := r.Close() + if err != nil { + return err + } + + return err2 } type Error struct { From cc9968d5dda71c21b3c90eb376458cacadb59e12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 21 Feb 2019 14:39:12 +0100 Subject: [PATCH 0261/1212] request: fix Content-Disposition header in Send This commit was moved from ipfs/go-ipfs-http-client@b7db17c63b69dc4fbb726dc720e9c594fa9ed495 --- client/httpapi/response.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/httpapi/response.go b/client/httpapi/response.go index 624a488d7..339c73658 100644 --- a/client/httpapi/response.go +++ b/client/httpapi/response.go @@ -102,7 +102,7 @@ func (r *Request) Send(c *http.Client) (*Response, error) { if fr, ok := r.Body.(*files.MultiFileReader); ok { req.Header.Set("Content-Type", "multipart/form-data; boundary="+fr.Boundary()) - req.Header.Set("Content-Disposition", "form-data: name=\"files\"") + req.Header.Set("Content-Disposition", "form-data; name=\"files\"") } resp, err := c.Do(req) From 47b820150bddb9868274ed2c6faf79c6b8cbe369 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 21 Feb 2019 14:46:18 +0100 Subject: [PATCH 0262/1212] test: don't panic on errors in async node construction This commit was moved from ipfs/go-ipfs-http-client@95ce0f3949da47b2db92508b8c7b0a00f502682b --- client/httpapi/api_test.go | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/client/httpapi/api_test.go b/client/httpapi/api_test.go index 2f6d47c58..df45c15af 100644 --- a/client/httpapi/api_test.go +++ b/client/httpapi/api_test.go @@ -114,27 +114,32 @@ func (NodeProvider) makeAPISwarm(ctx context.Context, fullIdentity bool, n int) wg.Add(len(nodes)) zero.Add(1) + errs := make(chan error, len(nodes)) for i, nd := range nodes { go func(i int, nd testbedi.Core) { defer wg.Done() if _, err := nd.Init(ctx, "--empty-repo"); err != nil { - panic(err) + errs <- err + return } if _, err := nd.RunCmd(ctx, nil, "ipfs", "config", "--json", "Experimental.FilestoreEnabled", "true"); err != nil { - panic(err) + errs <- err + return } if _, err := nd.Start(ctx, true, "--enable-pubsub-experiment", "--offline="+strconv.FormatBool(n == 1)); err != nil { - panic(err) + errs <- err + return } if i > 0 { zero.Wait() if err := nd.Connect(ctx, nodes[0]); err != nil { - panic(err) + errs <- err + return } } else { zero.Done() @@ -142,12 +147,14 @@ func (NodeProvider) makeAPISwarm(ctx context.Context, fullIdentity bool, n int) addr, err := nd.APIAddr() if err != nil { - panic(err) + errs <- err + return } maddr, err := ma.NewMultiaddr(addr) if err != nil { - panic(err) + errs <- err + return } c := &gohttp.Client{ @@ -159,16 +166,19 @@ func (NodeProvider) makeAPISwarm(ctx context.Context, fullIdentity bool, n int) } apis[i], err = NewApiWithClient(maddr, c) if err != nil { - panic(err) + errs <- err + return } // empty node is pinned even with --empty-repo, we don't want that emptyNode, err := iface.ParsePath("/ipfs/QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn") if err != nil { - panic(err) + errs <- err + return } if err := apis[i].Pin().Rm(ctx, emptyNode); err != nil { - panic(err) + errs <- err + return } }(i, nd) } @@ -187,7 +197,12 @@ func (NodeProvider) makeAPISwarm(ctx context.Context, fullIdentity bool, n int) }() }() - return apis, nil + select { + case err = <-errs: + default: + } + + return apis, err } func TestHttpApi(t *testing.T) { From 987a46a697747db37898d501e7efeed72e4989c4 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Mon, 4 Mar 2019 20:11:38 -0800 Subject: [PATCH 0263/1212] tweak the Ls interface 1. Avoid `ipld.Link`. This is a protodag specific thing that will go away in future IPLD versions. 2. Avoid exposing the underlying file types. The user shouldn't care if they're dealing with a hamt, etc. 3. Add a field for a symlink's target. 4. Rename LsLink to DirEntry to better this type's role. This commit was moved from ipfs/interface-go-ipfs-core@dbee8cc1adb3b53a10ea33add0584b030f92106a This commit was moved from ipfs/boxo@9c3cf70c5f23696257374f5f42212364d706d427 --- core/coreiface/tests/unixfs.go | 23 +++++++++++----------- core/coreiface/unixfs.go | 36 +++++++++++++++++++++------------- 2 files changed, 33 insertions(+), 26 deletions(-) diff --git a/core/coreiface/tests/unixfs.go b/core/coreiface/tests/unixfs.go index bcb5331d5..a0c33c0b0 100644 --- a/core/coreiface/tests/unixfs.go +++ b/core/coreiface/tests/unixfs.go @@ -750,26 +750,25 @@ func (tp *provider) TestLs(t *testing.T) { t.Error(err) } - links, err := api.Unixfs().Ls(ctx, p) + entries, err := api.Unixfs().Ls(ctx, p) if err != nil { t.Error(err) } - linkRes := <-links - if linkRes.Err != nil { - t.Fatal(linkRes.Err) + entry := <-entries + if entry.Err != nil { + t.Fatal(entry.Err) } - link := linkRes.Link - if linkRes.Size != 15 { - t.Fatalf("expected size = 15, got %d", link.Size) + if entry.Size != 15 { + t.Fatalf("expected size = 15, got %d", entry.Size) } - if link.Name != "name-of-file" { - t.Fatalf("expected name = name-of-file, got %s", link.Name) + if entry.Name != "name-of-file" { + t.Fatalf("expected name = name-of-file, got %s", entry.Name) } - if link.Cid.String() != "QmX3qQVKxDGz3URVC3861Z3CKtQKGBn6ffXRBBWGMFz9Lr" { - t.Fatalf("expected cid = QmX3qQVKxDGz3URVC3861Z3CKtQKGBn6ffXRBBWGMFz9Lr, got %s", link.Cid) + if entry.Cid.String() != "QmX3qQVKxDGz3URVC3861Z3CKtQKGBn6ffXRBBWGMFz9Lr" { + t.Fatalf("expected cid = QmX3qQVKxDGz3URVC3861Z3CKtQKGBn6ffXRBBWGMFz9Lr, got %s", entry.Cid) } - if l, ok := <-links; ok { + if l, ok := <-entries; ok { t.Errorf("didn't expect a second link") if l.Err != nil { t.Error(l.Err) diff --git a/core/coreiface/unixfs.go b/core/coreiface/unixfs.go index 5aae00dc4..bdf08b5c3 100644 --- a/core/coreiface/unixfs.go +++ b/core/coreiface/unixfs.go @@ -4,9 +4,8 @@ import ( "context" "github.com/ipfs/interface-go-ipfs-core/options" - "github.com/ipfs/go-ipfs-files" - ipld "github.com/ipfs/go-ipld-format" - "github.com/ipfs/go-unixfs" + cid "github.com/ipfs/go-cid" + files "github.com/ipfs/go-ipfs-files" ) type AddEvent struct { @@ -16,21 +15,30 @@ type AddEvent struct { Size string `json:",omitempty"` } +// FileType is an enum of possible UnixFS file types. type FileType int32 const ( - TRaw = FileType(unixfs.TRaw) - TFile = FileType(unixfs.TFile) - TDirectory = FileType(unixfs.TDirectory) - TMetadata = FileType(unixfs.TMetadata) - TSymlink = FileType(unixfs.TSymlink) - THAMTShard = FileType(unixfs.THAMTShard) + // TUnknown means the file type isn't known (e.g., it hasn't been + // resolved). + TUnknown FileType = iota + // TFile is a regular file. + TFile + // TDirectory is a directory. + TDirectory + // TSymlink is a symlink. + TSymlink ) -type LsLink struct { - Link *ipld.Link - Size uint64 - Type FileType +// DirEntry is a directory entry returned by `Ls`. +type DirEntry struct { + Name string + Cid cid.Cid + + // Only filled when asked to resolve the directory entry. + Size uint64 // The size of the file in bytes (or the size of the symlink). + Type FileType // The type of the file. + Target Path // The symlink target (if a symlink). Err error } @@ -51,5 +59,5 @@ type UnixfsAPI interface { // Ls returns the list of links in a directory. Links aren't guaranteed to be // returned in order - Ls(context.Context, Path, ...options.UnixfsLsOption) (<-chan LsLink, error) + Ls(context.Context, Path, ...options.UnixfsLsOption) (<-chan DirEntry, error) } From 483caf76fd36aeebc9d4ea2caf02e007271c5fd1 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Tue, 5 Mar 2019 09:36:58 -0800 Subject: [PATCH 0264/1212] file type: add stringer This commit was moved from ipfs/interface-go-ipfs-core@4e99a8e9250040b9cfc9600641d138fca8ff01f9 This commit was moved from ipfs/boxo@ee697a3b097c25457cccf63c42ba03fadde9d4ef --- core/coreiface/unixfs.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/core/coreiface/unixfs.go b/core/coreiface/unixfs.go index bdf08b5c3..d0e3ec572 100644 --- a/core/coreiface/unixfs.go +++ b/core/coreiface/unixfs.go @@ -30,6 +30,21 @@ const ( TSymlink ) +func (t FileType) String() string { + switch t { + case TUnknown: + return "unknown" + case TFile: + return "file" + case TDirectory: + return "directory" + case TSymlink: + return "symlink" + default: + return "" + } +} + // DirEntry is a directory entry returned by `Ls`. type DirEntry struct { Name string From cc2b187d07091d649f29f129bcd57078cbec9aba Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Tue, 5 Mar 2019 09:37:40 -0800 Subject: [PATCH 0265/1212] tests: add symlink target test (also, fix some error versus fatal nits) This commit was moved from ipfs/interface-go-ipfs-core@5c6a751986f6d5fe1174819442fcd5f60e0a6f7d This commit was moved from ipfs/boxo@4be6e60dbea5e9dd8cf37d1f7a5b038e2a18dbf7 --- core/coreiface/tests/unixfs.go | 35 +++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/core/coreiface/tests/unixfs.go b/core/coreiface/tests/unixfs.go index a0c33c0b0..b8b22e50a 100644 --- a/core/coreiface/tests/unixfs.go +++ b/core/coreiface/tests/unixfs.go @@ -737,22 +737,23 @@ func (tp *provider) TestLs(t *testing.T) { defer cancel() api, err := tp.makeAPI(ctx) if err != nil { - t.Error(err) + t.Fatal(err) } r := strings.NewReader("content-of-file") p, err := api.Unixfs().Add(ctx, files.NewMapDirectory(map[string]files.Node{ "0": files.NewMapDirectory(map[string]files.Node{ - "name-of-file": files.NewReaderFile(r), + "name-of-file": files.NewReaderFile(r), + "name-of-symlink": files.NewLinkFile("/foo/bar", nil), }), })) if err != nil { - t.Error(err) + t.Fatal(err) } entries, err := api.Unixfs().Ls(ctx, p) if err != nil { - t.Error(err) + t.Fatal(err) } entry := <-entries @@ -760,13 +761,33 @@ func (tp *provider) TestLs(t *testing.T) { t.Fatal(entry.Err) } if entry.Size != 15 { - t.Fatalf("expected size = 15, got %d", entry.Size) + t.Errorf("expected size = 15, got %d", entry.Size) } if entry.Name != "name-of-file" { - t.Fatalf("expected name = name-of-file, got %s", entry.Name) + t.Errorf("expected name = name-of-file, got %s", entry.Name) + } + if entry.Type != coreiface.TFile { + t.Errorf("wrong type %s", entry.Type) } if entry.Cid.String() != "QmX3qQVKxDGz3URVC3861Z3CKtQKGBn6ffXRBBWGMFz9Lr" { - t.Fatalf("expected cid = QmX3qQVKxDGz3URVC3861Z3CKtQKGBn6ffXRBBWGMFz9Lr, got %s", entry.Cid) + t.Errorf("expected cid = QmX3qQVKxDGz3URVC3861Z3CKtQKGBn6ffXRBBWGMFz9Lr, got %s", entry.Cid) + } + entry = <-entries + if entry.Err != nil { + t.Fatal(entry.Err) + } + if entry.Type != coreiface.TSymlink { + t.Errorf("wrong type %s", entry.Type) + } + if entry.Name != "name-of-symlink" { + t.Errorf("expected name = name-of-symlink, got %s", entry.Name) + } + if entry.Target.String() != "/foo/bar" { + t.Errorf("expected symlink target to be /foo/bar, got %s", entry.Target) + } + + if int(entry.Size) != len(entry.Target.String()) { + t.Errorf("expected size = %d, got %d", len(entry.Target.String()), entry.Size) } if l, ok := <-entries; ok { t.Errorf("didn't expect a second link") From 30b344a5af44bae2c7606e18126f0cf66f73915e Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Tue, 5 Mar 2019 09:54:43 -0800 Subject: [PATCH 0266/1212] switch symlink target type to string (path can't represent relative paths) This commit was moved from ipfs/interface-go-ipfs-core@368881fa4a30814112d1b2096c37c91f5fd16976 This commit was moved from ipfs/boxo@e2900773a64d532ccbbabd5ed23c048270bfbefe --- core/coreiface/tests/unixfs.go | 6 +++--- core/coreiface/unixfs.go | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/core/coreiface/tests/unixfs.go b/core/coreiface/tests/unixfs.go index b8b22e50a..79dedf155 100644 --- a/core/coreiface/tests/unixfs.go +++ b/core/coreiface/tests/unixfs.go @@ -782,12 +782,12 @@ func (tp *provider) TestLs(t *testing.T) { if entry.Name != "name-of-symlink" { t.Errorf("expected name = name-of-symlink, got %s", entry.Name) } - if entry.Target.String() != "/foo/bar" { + if entry.Target != "/foo/bar" { t.Errorf("expected symlink target to be /foo/bar, got %s", entry.Target) } - if int(entry.Size) != len(entry.Target.String()) { - t.Errorf("expected size = %d, got %d", len(entry.Target.String()), entry.Size) + if int(entry.Size) != len(entry.Target) { + t.Errorf("expected size = %d, got %d", len(entry.Target), entry.Size) } if l, ok := <-entries; ok { t.Errorf("didn't expect a second link") diff --git a/core/coreiface/unixfs.go b/core/coreiface/unixfs.go index d0e3ec572..f9508f138 100644 --- a/core/coreiface/unixfs.go +++ b/core/coreiface/unixfs.go @@ -53,7 +53,7 @@ type DirEntry struct { // Only filled when asked to resolve the directory entry. Size uint64 // The size of the file in bytes (or the size of the symlink). Type FileType // The type of the file. - Target Path // The symlink target (if a symlink). + Target string // The symlink target (if a symlink). Err error } From 5cdd4b3d81e43fb3a8d794315ce3b34d59afbbce Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Wed, 6 Mar 2019 16:41:05 -0800 Subject: [PATCH 0267/1212] remove target size requirement It's complicated. We need to carefully think through how sizes work. This commit was moved from ipfs/interface-go-ipfs-core@7a7cf9694be27b62820f05e2ac11bb4a57bab982 This commit was moved from ipfs/boxo@f5117736743ee8753e359aa7e7dbcaf602d75224 --- core/coreiface/tests/unixfs.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/core/coreiface/tests/unixfs.go b/core/coreiface/tests/unixfs.go index 79dedf155..bbcb66899 100644 --- a/core/coreiface/tests/unixfs.go +++ b/core/coreiface/tests/unixfs.go @@ -786,9 +786,6 @@ func (tp *provider) TestLs(t *testing.T) { t.Errorf("expected symlink target to be /foo/bar, got %s", entry.Target) } - if int(entry.Size) != len(entry.Target) { - t.Errorf("expected size = %d, got %d", len(entry.Target), entry.Size) - } if l, ok := <-entries; ok { t.Errorf("didn't expect a second link") if l.Err != nil { From 01b61d76346799d4f762b7527466871aa6ad66d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 25 Feb 2019 17:10:23 +0100 Subject: [PATCH 0268/1212] unixfs add: Changes for fixed wrap logic This commit was moved from ipfs/interface-go-ipfs-core@e87318a2c3620d2402517a6833e21749c065a397 This commit was moved from ipfs/boxo@1ec848f9a24d9c67927520cedcce7c2393893b9a --- core/coreiface/options/unixfs.go | 11 +++ core/coreiface/tests/unixfs.go | 116 ++++++++++++++++++------------- 2 files changed, 80 insertions(+), 47 deletions(-) diff --git a/core/coreiface/options/unixfs.go b/core/coreiface/options/unixfs.go index b76b01adf..44ba8c7cd 100644 --- a/core/coreiface/options/unixfs.go +++ b/core/coreiface/options/unixfs.go @@ -35,6 +35,7 @@ type UnixfsAddSettings struct { Wrap bool Hidden bool + TopHidden bool StdinName string Events chan<- interface{} @@ -69,6 +70,7 @@ func UnixfsAddOptions(opts ...UnixfsAddOption) (*UnixfsAddSettings, cid.Prefix, Wrap: false, Hidden: false, + TopHidden: false, StdinName: "", Events: nil, @@ -255,6 +257,15 @@ func (unixfsOpts) Hidden(hidden bool) UnixfsAddOption { } } +// TopHidden enables adding of hidden files in top-level directory (files +// prefixed with '.') +func (unixfsOpts) TopHidden(hidden bool) UnixfsAddOption { + return func(settings *UnixfsAddSettings) error { + settings.TopHidden = hidden + return nil + } +} + // StdinName is the name set for files which don specify FilePath as // os.Stdin.Name() func (unixfsOpts) StdinName(name string) UnixfsAddOption { diff --git a/core/coreiface/tests/unixfs.go b/core/coreiface/tests/unixfs.go index bbcb66899..1ad319333 100644 --- a/core/coreiface/tests/unixfs.go +++ b/core/coreiface/tests/unixfs.go @@ -82,11 +82,14 @@ func flatDir() files.Node { }) } -func wrapped(name string) func(f files.Node) files.Node { +func wrapped(names ...string) func(f files.Node) files.Node { return func(f files.Node) files.Node { - return files.NewMapDirectory(map[string]files.Node{ - name: f, - }) + for i := range names { + f = files.NewMapDirectory(map[string]files.Node{ + names[len(names)-i-1]: f, + }) + } + return f } } @@ -241,16 +244,30 @@ func (tp *provider) TestAdd(t *testing.T) { }, // multi file { - name: "simpleDir", + name: "simpleDirNoWrap", data: flatDir, - wrap: "t", path: "/ipfs/QmRKGpFfR32FVXdvJiHfo4WJ5TDYBsM1P9raAp1p6APWSp", }, { - name: "twoLevelDir", - data: twoLevelDir(), - wrap: "t", - path: "/ipfs/QmVG2ZYCkV1S4TK8URA3a4RupBF17A8yAr4FqsRDXVJASr", + name: "simpleDirWrap", + data: flatDir, + expect: wrapped("QmRKGpFfR32FVXdvJiHfo4WJ5TDYBsM1P9raAp1p6APWSp"), + path: "/ipfs/QmXxCaQkC8Z6Qws1nTkTQfCsL9y4XvWXnrPokp9bhmjC1L", + opts: []options.UnixfsAddOption{options.Unixfs.Wrap(true)}, + }, + { + name: "simpleDir", + data: flatDir, + wrap: "t", + expect: wrapped("t"), + path: "/ipfs/Qmc3nGXm1HtUVCmnXLQHvWcNwfdZGpfg2SRm1CxLf7Q2Rm", + }, + { + name: "twoLevelDir", + data: twoLevelDir(), + wrap: "t", + expect: wrapped("t"), + path: "/ipfs/QmPwsL3T5sWhDmmAWZHAzyjKtMVDS9a11aHNRqb3xoVnmg", }, // wrapped { @@ -261,15 +278,6 @@ func (tp *provider) TestAdd(t *testing.T) { }, wrap: "foo", expect: wrapped("foo"), - opts: []options.UnixfsAddOption{options.Unixfs.Wrap(true)}, - }, - { - name: "addNotWrappedDirFile", - path: hello, - data: func() files.Node { - return files.NewBytesFile([]byte(helloStr)) - }, - wrap: "foo", }, { name: "stdinWrapped", @@ -306,16 +314,16 @@ func (tp *provider) TestAdd(t *testing.T) { name: "twoLevelDirWrapped", data: twoLevelDir(), wrap: "t", - expect: wrapped("t"), - path: "/ipfs/QmPwsL3T5sWhDmmAWZHAzyjKtMVDS9a11aHNRqb3xoVnmg", + expect: wrapped("QmPwsL3T5sWhDmmAWZHAzyjKtMVDS9a11aHNRqb3xoVnmg", "t"), + path: "/ipfs/QmXzZwAh34pmNjuKsVGZfpbByis5S5qeZjCCUxa1ajZqzH", opts: []options.UnixfsAddOption{options.Unixfs.Wrap(true)}, }, { name: "twoLevelInlineHash", data: twoLevelDir(), wrap: "t", - expect: wrapped("t"), - path: "/ipfs/zBunoruKoyCHKkALNSWxDvj4L7yuQnMgQ4hUa9j1Z64tVcDEcu6Zdetyu7eeFCxMPfxb7YJvHeFHoFoHMkBUQf6vfdhmi", + expect: wrapped("zBunoruKoyCHKkALNSWxDvj4L7yuQnMgQ4hUa9j1Z64tVcDEcu6Zdetyu7eeFCxMPfxb7YJvHeFHoFoHMkBUQf6vfdhmi", "t"), + path: "/ipfs/QmUX6GykDGHTMtLmDkfjqs48QwQK82vou51xwaY9TSU7Zo", opts: []options.UnixfsAddOption{options.Unixfs.Wrap(true), options.Unixfs.Inline(true), options.Unixfs.RawLeaves(true), options.Unixfs.Hash(mh.SHA3)}, }, // hidden @@ -328,17 +336,20 @@ func (tp *provider) TestAdd(t *testing.T) { "foo": files.NewBytesFile([]byte("hello1")), }) }, - wrap: "t", - path: "/ipfs/QmehGvpf2hY196MzDFmjL8Wy27S4jbgGDUAhBJyvXAwr3g", - opts: []options.UnixfsAddOption{options.Unixfs.Hidden(true)}, + wrap: "t", + expect: wrapped("t"), + path: "/ipfs/QmPXLSBX382vJDLrGakcbrZDkU3grfkjMox7EgSC9KFbtQ", + opts: []options.UnixfsAddOption{options.Unixfs.Hidden(true)}, }, { - name: "hiddenFileAlwaysAdded", + name: "topHiddenFileAdded", data: func() files.Node { return files.NewBytesFile([]byte(helloStr)) }, - wrap: ".foo", - path: hello, + wrap: ".foo", + expect: wrapped(".foo"), + path: "/ipfs/QmciAVG3krCbvzUaK9gr6jUgfEjQtYmuuXi1n67teQ4Ni2", + opts: []options.UnixfsAddOption{options.Unixfs.TopHidden(true)}, }, { name: "hiddenFilesNotAdded", @@ -352,10 +363,25 @@ func (tp *provider) TestAdd(t *testing.T) { expect: func(files.Node) files.Node { return flatDir() }, - wrap: "t", path: "/ipfs/QmRKGpFfR32FVXdvJiHfo4WJ5TDYBsM1P9raAp1p6APWSp", opts: []options.UnixfsAddOption{options.Unixfs.Hidden(false)}, }, + { + name: "hiddenFilesWrappedNotAdded", + data: func() files.Node { + return files.NewMapDirectory(map[string]files.Node{ + ".bar": files.NewBytesFile([]byte("hello2")), + "bar": files.NewBytesFile([]byte("hello2")), + "foo": files.NewBytesFile([]byte("hello1")), + }) + }, + expect: func(files.Node) files.Node { + return wrapped("t")(flatDir()) + }, + wrap: "t", + path: "/ipfs/Qmc3nGXm1HtUVCmnXLQHvWcNwfdZGpfg2SRm1CxLf7Q2Rm", + opts: []options.UnixfsAddOption{options.Unixfs.Hidden(false)}, + }, // NoCopy { name: "simpleNoCopy", @@ -392,10 +418,9 @@ func (tp *provider) TestAdd(t *testing.T) { data: twoLevelDir(), path: "/ipfs/QmVG2ZYCkV1S4TK8URA3a4RupBF17A8yAr4FqsRDXVJASr", events: []coreiface.AddEvent{ - {Name: "t/abc", Path: p("QmU7nuGs2djqK99UNsNgEPGh6GV4662p6WtsgccBNGTDxt"), Size: "62"}, - {Name: "t", Path: p("QmVG2ZYCkV1S4TK8URA3a4RupBF17A8yAr4FqsRDXVJASr"), Size: "229"}, + {Name: "abc", Path: p("QmU7nuGs2djqK99UNsNgEPGh6GV4662p6WtsgccBNGTDxt"), Size: "62"}, + {Name: "", Path: p("QmVG2ZYCkV1S4TK8URA3a4RupBF17A8yAr4FqsRDXVJASr"), Size: "229"}, }, - wrap: "t", opts: []options.UnixfsAddOption{options.Unixfs.Silent(true)}, }, { @@ -403,13 +428,12 @@ func (tp *provider) TestAdd(t *testing.T) { data: twoLevelDir(), path: "/ipfs/QmVG2ZYCkV1S4TK8URA3a4RupBF17A8yAr4FqsRDXVJASr", events: []coreiface.AddEvent{ - {Name: "t/abc/def", Path: p("QmNyJpQkU1cEkBwMDhDNFstr42q55mqG5GE5Mgwug4xyGk"), Size: "13"}, - {Name: "t/bar", Path: p("QmS21GuXiRMvJKHos4ZkEmQDmRBqRaF5tQS2CQCu2ne9sY"), Size: "14"}, - {Name: "t/foo", Path: p("QmfAjGiVpTN56TXi6SBQtstit5BEw3sijKj1Qkxn6EXKzJ"), Size: "14"}, - {Name: "t/abc", Path: p("QmU7nuGs2djqK99UNsNgEPGh6GV4662p6WtsgccBNGTDxt"), Size: "62"}, - {Name: "t", Path: p("QmVG2ZYCkV1S4TK8URA3a4RupBF17A8yAr4FqsRDXVJASr"), Size: "229"}, + {Name: "abc/def", Path: p("QmNyJpQkU1cEkBwMDhDNFstr42q55mqG5GE5Mgwug4xyGk"), Size: "13"}, + {Name: "bar", Path: p("QmS21GuXiRMvJKHos4ZkEmQDmRBqRaF5tQS2CQCu2ne9sY"), Size: "14"}, + {Name: "foo", Path: p("QmfAjGiVpTN56TXi6SBQtstit5BEw3sijKj1Qkxn6EXKzJ"), Size: "14"}, + {Name: "abc", Path: p("QmU7nuGs2djqK99UNsNgEPGh6GV4662p6WtsgccBNGTDxt"), Size: "62"}, + {Name: "", Path: p("QmVG2ZYCkV1S4TK8URA3a4RupBF17A8yAr4FqsRDXVJASr"), Size: "229"}, }, - wrap: "t", }, { name: "progress1M", @@ -528,14 +552,14 @@ func (tp *provider) TestAdd(t *testing.T) { _, origDir := orig.(files.Directory) _, gotDir := got.(files.Directory) - if origDir != gotDir { - t.Fatal("file type mismatch") - } - if origName != gotName { t.Errorf("file name mismatch, orig='%s', got='%s'", origName, gotName) } + if origDir != gotDir { + t.Fatalf("file type mismatch on %s", origName) + } + if !gotDir { defer orig.Close() defer got.Close() @@ -804,9 +828,7 @@ func (tp *provider) TestEntriesExpired(t *testing.T) { r := strings.NewReader("content-of-file") p, err := api.Unixfs().Add(ctx, files.NewMapDirectory(map[string]files.Node{ - "0": files.NewMapDirectory(map[string]files.Node{ - "name-of-file": files.NewReaderFile(r), - }), + "name-of-file": files.NewReaderFile(r), })) if err != nil { t.Error(err) @@ -846,7 +868,7 @@ func (tp *provider) TestLsEmptyDir(t *testing.T) { t.Error(err) } - _, err = api.Unixfs().Add(ctx, files.NewMapDirectory(map[string]files.Node{"0": files.NewSliceDirectory([]files.DirEntry{})})) + _, err = api.Unixfs().Add(ctx, files.NewSliceDirectory([]files.DirEntry{})) if err != nil { t.Error(err) } From a6fe80000c9e7d17491adc25a02882af3d53a829 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Sun, 10 Mar 2019 22:10:02 +0100 Subject: [PATCH 0269/1212] unixfs add: Remove hidden file handling This commit was moved from ipfs/interface-go-ipfs-core@56944d64d1ad4bb349a3d1a30633d5bea06d6a2e This commit was moved from ipfs/boxo@4274224bd095962491241080f0b1fc794d999239 --- core/coreiface/options/unixfs.go | 21 --------------- core/coreiface/tests/unixfs.go | 44 +------------------------------- 2 files changed, 1 insertion(+), 64 deletions(-) diff --git a/core/coreiface/options/unixfs.go b/core/coreiface/options/unixfs.go index 44ba8c7cd..574d46b98 100644 --- a/core/coreiface/options/unixfs.go +++ b/core/coreiface/options/unixfs.go @@ -34,8 +34,6 @@ type UnixfsAddSettings struct { NoCopy bool Wrap bool - Hidden bool - TopHidden bool StdinName string Events chan<- interface{} @@ -69,8 +67,6 @@ func UnixfsAddOptions(opts ...UnixfsAddOption) (*UnixfsAddSettings, cid.Prefix, NoCopy: false, Wrap: false, - Hidden: false, - TopHidden: false, StdinName: "", Events: nil, @@ -249,23 +245,6 @@ func (unixfsOpts) Wrap(wrap bool) UnixfsAddOption { } } -// Hidden enables adding of hidden files (files prefixed with '.') -func (unixfsOpts) Hidden(hidden bool) UnixfsAddOption { - return func(settings *UnixfsAddSettings) error { - settings.Hidden = hidden - return nil - } -} - -// TopHidden enables adding of hidden files in top-level directory (files -// prefixed with '.') -func (unixfsOpts) TopHidden(hidden bool) UnixfsAddOption { - return func(settings *UnixfsAddSettings) error { - settings.TopHidden = hidden - return nil - } -} - // StdinName is the name set for files which don specify FilePath as // os.Stdin.Name() func (unixfsOpts) StdinName(name string) UnixfsAddOption { diff --git a/core/coreiface/tests/unixfs.go b/core/coreiface/tests/unixfs.go index 1ad319333..0defd2f32 100644 --- a/core/coreiface/tests/unixfs.go +++ b/core/coreiface/tests/unixfs.go @@ -328,7 +328,7 @@ func (tp *provider) TestAdd(t *testing.T) { }, // hidden { - name: "hiddenFiles", + name: "hiddenFilesAdded", data: func() files.Node { return files.NewMapDirectory(map[string]files.Node{ ".bar": files.NewBytesFile([]byte("hello2")), @@ -339,48 +339,6 @@ func (tp *provider) TestAdd(t *testing.T) { wrap: "t", expect: wrapped("t"), path: "/ipfs/QmPXLSBX382vJDLrGakcbrZDkU3grfkjMox7EgSC9KFbtQ", - opts: []options.UnixfsAddOption{options.Unixfs.Hidden(true)}, - }, - { - name: "topHiddenFileAdded", - data: func() files.Node { - return files.NewBytesFile([]byte(helloStr)) - }, - wrap: ".foo", - expect: wrapped(".foo"), - path: "/ipfs/QmciAVG3krCbvzUaK9gr6jUgfEjQtYmuuXi1n67teQ4Ni2", - opts: []options.UnixfsAddOption{options.Unixfs.TopHidden(true)}, - }, - { - name: "hiddenFilesNotAdded", - data: func() files.Node { - return files.NewMapDirectory(map[string]files.Node{ - ".bar": files.NewBytesFile([]byte("hello2")), - "bar": files.NewBytesFile([]byte("hello2")), - "foo": files.NewBytesFile([]byte("hello1")), - }) - }, - expect: func(files.Node) files.Node { - return flatDir() - }, - path: "/ipfs/QmRKGpFfR32FVXdvJiHfo4WJ5TDYBsM1P9raAp1p6APWSp", - opts: []options.UnixfsAddOption{options.Unixfs.Hidden(false)}, - }, - { - name: "hiddenFilesWrappedNotAdded", - data: func() files.Node { - return files.NewMapDirectory(map[string]files.Node{ - ".bar": files.NewBytesFile([]byte("hello2")), - "bar": files.NewBytesFile([]byte("hello2")), - "foo": files.NewBytesFile([]byte("hello1")), - }) - }, - expect: func(files.Node) files.Node { - return wrapped("t")(flatDir()) - }, - wrap: "t", - path: "/ipfs/Qmc3nGXm1HtUVCmnXLQHvWcNwfdZGpfg2SRm1CxLf7Q2Rm", - opts: []options.UnixfsAddOption{options.Unixfs.Hidden(false)}, }, // NoCopy { From 726e8c0db1b97af0b40f26ae6447662651d01ebc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 11 Mar 2019 13:36:57 +0100 Subject: [PATCH 0270/1212] unixfs: fix ls test for new add This commit was moved from ipfs/interface-go-ipfs-core@91f8aac428155f9f302c3d6327c5f8659742013f This commit was moved from ipfs/boxo@bd1689b886cda8cd5095b711df1eba9d15cabc7f --- core/coreiface/tests/unixfs.go | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/core/coreiface/tests/unixfs.go b/core/coreiface/tests/unixfs.go index 0defd2f32..d4af7c3f0 100644 --- a/core/coreiface/tests/unixfs.go +++ b/core/coreiface/tests/unixfs.go @@ -724,10 +724,8 @@ func (tp *provider) TestLs(t *testing.T) { r := strings.NewReader("content-of-file") p, err := api.Unixfs().Add(ctx, files.NewMapDirectory(map[string]files.Node{ - "0": files.NewMapDirectory(map[string]files.Node{ - "name-of-file": files.NewReaderFile(r), - "name-of-symlink": files.NewLinkFile("/foo/bar", nil), - }), + "name-of-file": files.NewReaderFile(r), + "name-of-symlink": files.NewLinkFile("/foo/bar", nil), })) if err != nil { t.Fatal(err) From 905898b66787e0970c3e26f1072e8d2471c644db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 11 Mar 2019 15:58:40 +0100 Subject: [PATCH 0271/1212] unixfs add: remove StdinName This commit was moved from ipfs/interface-go-ipfs-core@e12c21afc03931525ceefc18be0bda8c71818d29 This commit was moved from ipfs/boxo@f3f74adfdbb7715898650b91985c61e3ba7a2788 --- core/coreiface/options/unixfs.go | 15 ++------------- core/coreiface/tests/unixfs.go | 18 ------------------ 2 files changed, 2 insertions(+), 31 deletions(-) diff --git a/core/coreiface/options/unixfs.go b/core/coreiface/options/unixfs.go index 574d46b98..578eb5320 100644 --- a/core/coreiface/options/unixfs.go +++ b/core/coreiface/options/unixfs.go @@ -33,8 +33,7 @@ type UnixfsAddSettings struct { FsCache bool NoCopy bool - Wrap bool - StdinName string + Wrap bool Events chan<- interface{} Silent bool @@ -66,8 +65,7 @@ func UnixfsAddOptions(opts ...UnixfsAddOption) (*UnixfsAddSettings, cid.Prefix, FsCache: false, NoCopy: false, - Wrap: false, - StdinName: "", + Wrap: false, Events: nil, Silent: false, @@ -245,15 +243,6 @@ func (unixfsOpts) Wrap(wrap bool) UnixfsAddOption { } } -// StdinName is the name set for files which don specify FilePath as -// os.Stdin.Name() -func (unixfsOpts) StdinName(name string) UnixfsAddOption { - return func(settings *UnixfsAddSettings) error { - settings.StdinName = name - return nil - } -} - // Events specifies channel which will be used to report events about ongoing // Add operation. // diff --git a/core/coreiface/tests/unixfs.go b/core/coreiface/tests/unixfs.go index d4af7c3f0..c27826b51 100644 --- a/core/coreiface/tests/unixfs.go +++ b/core/coreiface/tests/unixfs.go @@ -292,24 +292,6 @@ func (tp *provider) TestAdd(t *testing.T) { }, opts: []options.UnixfsAddOption{options.Unixfs.Wrap(true)}, }, - { - name: "stdinNamed", - path: "/ipfs/QmQ6cGBmb3ZbdrQW1MRm1RJnYnaxCqfssz7CrTa9NEhQyS", - data: func() files.Node { - rf, err := files.NewReaderPathFile(os.Stdin.Name(), ioutil.NopCloser(strings.NewReader(helloStr)), nil) - if err != nil { - panic(err) - } - - return rf - }, - expect: func(files.Node) files.Node { - return files.NewMapDirectory(map[string]files.Node{ - "test": files.NewBytesFile([]byte(helloStr)), - }) - }, - opts: []options.UnixfsAddOption{options.Unixfs.Wrap(true), options.Unixfs.StdinName("test")}, - }, { name: "twoLevelDirWrapped", data: twoLevelDir(), From 84faa010ce5dbb944845c22658025f4a0523ab6d Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Fri, 22 Mar 2019 15:05:41 -0700 Subject: [PATCH 0272/1212] remove Wrap This can be trivially implemented by the end-user if desired. The best the CoreAPI can do is name the file with it's own hash so this isn't really all that helpful either. Note: This differs from js-ipfs because _there_, all files have paths (even outside directories). This commit was moved from ipfs/interface-go-ipfs-core@ac37dde21aaeea010bbe50c8c37155e4471c0000 This commit was moved from ipfs/boxo@a0c8ed395649c7fcda2ceaccdd65aa13feb2d2ae --- core/coreiface/options/unixfs.go | 13 ------------ core/coreiface/tests/unixfs.go | 36 -------------------------------- 2 files changed, 49 deletions(-) diff --git a/core/coreiface/options/unixfs.go b/core/coreiface/options/unixfs.go index 578eb5320..3fd96f772 100644 --- a/core/coreiface/options/unixfs.go +++ b/core/coreiface/options/unixfs.go @@ -33,8 +33,6 @@ type UnixfsAddSettings struct { FsCache bool NoCopy bool - Wrap bool - Events chan<- interface{} Silent bool Progress bool @@ -65,8 +63,6 @@ func UnixfsAddOptions(opts ...UnixfsAddOption) (*UnixfsAddSettings, cid.Prefix, FsCache: false, NoCopy: false, - Wrap: false, - Events: nil, Silent: false, Progress: false, @@ -234,15 +230,6 @@ func (unixfsOpts) HashOnly(hashOnly bool) UnixfsAddOption { } } -// Wrap tells the adder to wrap the added file structure with an additional -// directory. -func (unixfsOpts) Wrap(wrap bool) UnixfsAddOption { - return func(settings *UnixfsAddSettings) error { - settings.Wrap = wrap - return nil - } -} - // Events specifies channel which will be used to report events about ongoing // Add operation. // diff --git a/core/coreiface/tests/unixfs.go b/core/coreiface/tests/unixfs.go index c27826b51..0fd494f66 100644 --- a/core/coreiface/tests/unixfs.go +++ b/core/coreiface/tests/unixfs.go @@ -248,13 +248,6 @@ func (tp *provider) TestAdd(t *testing.T) { data: flatDir, path: "/ipfs/QmRKGpFfR32FVXdvJiHfo4WJ5TDYBsM1P9raAp1p6APWSp", }, - { - name: "simpleDirWrap", - data: flatDir, - expect: wrapped("QmRKGpFfR32FVXdvJiHfo4WJ5TDYBsM1P9raAp1p6APWSp"), - path: "/ipfs/QmXxCaQkC8Z6Qws1nTkTQfCsL9y4XvWXnrPokp9bhmjC1L", - opts: []options.UnixfsAddOption{options.Unixfs.Wrap(true)}, - }, { name: "simpleDir", data: flatDir, @@ -279,35 +272,6 @@ func (tp *provider) TestAdd(t *testing.T) { wrap: "foo", expect: wrapped("foo"), }, - { - name: "stdinWrapped", - path: "/ipfs/QmU3r81oZycjHS9oaSHw37ootMFuFUw1DvMLKXPsezdtqU", - data: func() files.Node { - return files.NewBytesFile([]byte(helloStr)) - }, - expect: func(files.Node) files.Node { - return files.NewMapDirectory(map[string]files.Node{ - "QmQy2Dw4Wk7rdJKjThjYXzfFJNaRKRHhHP5gHHXroJMYxk": files.NewBytesFile([]byte(helloStr)), - }) - }, - opts: []options.UnixfsAddOption{options.Unixfs.Wrap(true)}, - }, - { - name: "twoLevelDirWrapped", - data: twoLevelDir(), - wrap: "t", - expect: wrapped("QmPwsL3T5sWhDmmAWZHAzyjKtMVDS9a11aHNRqb3xoVnmg", "t"), - path: "/ipfs/QmXzZwAh34pmNjuKsVGZfpbByis5S5qeZjCCUxa1ajZqzH", - opts: []options.UnixfsAddOption{options.Unixfs.Wrap(true)}, - }, - { - name: "twoLevelInlineHash", - data: twoLevelDir(), - wrap: "t", - expect: wrapped("zBunoruKoyCHKkALNSWxDvj4L7yuQnMgQ4hUa9j1Z64tVcDEcu6Zdetyu7eeFCxMPfxb7YJvHeFHoFoHMkBUQf6vfdhmi", "t"), - path: "/ipfs/QmUX6GykDGHTMtLmDkfjqs48QwQK82vou51xwaY9TSU7Zo", - opts: []options.UnixfsAddOption{options.Unixfs.Wrap(true), options.Unixfs.Inline(true), options.Unixfs.RawLeaves(true), options.Unixfs.Hash(mh.SHA3)}, - }, // hidden { name: "hiddenFilesAdded", From 6190be29b97faebf6537ecf3eedb942d5c9eff08 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Tue, 26 Mar 2019 18:27:35 +0000 Subject: [PATCH 0273/1212] make unrecoverable test errors fatal Otherwise, we can get random panics form dereferencing nil pointers. This commit was moved from ipfs/interface-go-ipfs-core@6d166d40d8d347faa4a10aec30444999d5d7b85b This commit was moved from ipfs/boxo@35272d3a3b89759460bf3fb96c15e36019036da4 --- core/coreiface/tests/block.go | 28 +++++++++---------- core/coreiface/tests/dag.go | 36 ++++++++++++------------ core/coreiface/tests/key.go | 26 ++++++++--------- core/coreiface/tests/path.go | 18 ++++++------ core/coreiface/tests/pin.go | 26 ++++++++--------- core/coreiface/tests/unixfs.go | 51 ++++++++++++++++++---------------- 6 files changed, 94 insertions(+), 91 deletions(-) diff --git a/core/coreiface/tests/block.go b/core/coreiface/tests/block.go index 3cd74358d..d584ac98a 100644 --- a/core/coreiface/tests/block.go +++ b/core/coreiface/tests/block.go @@ -52,7 +52,7 @@ func (tp *provider) TestBlockPutFormat(t *testing.T) { defer cancel() api, err := tp.makeAPI(ctx) if err != nil { - t.Error(err) + t.Fatal(err) } res, err := api.Block().Put(ctx, strings.NewReader(`Hello`), opt.Block.Format("cbor")) @@ -70,7 +70,7 @@ func (tp *provider) TestBlockPutHash(t *testing.T) { defer cancel() api, err := tp.makeAPI(ctx) if err != nil { - t.Error(err) + t.Fatal(err) } res, err := api.Block().Put(ctx, strings.NewReader(`Hello`), opt.Block.Hash(mh.KECCAK_512, -1)) @@ -88,7 +88,7 @@ func (tp *provider) TestBlockGet(t *testing.T) { defer cancel() api, err := tp.makeAPI(ctx) if err != nil { - t.Error(err) + t.Fatal(err) } res, err := api.Block().Put(ctx, strings.NewReader(`Hello`), opt.Block.Hash(mh.KECCAK_512, -1)) @@ -98,12 +98,12 @@ func (tp *provider) TestBlockGet(t *testing.T) { r, err := api.Block().Get(ctx, res.Path()) if err != nil { - t.Error(err) + t.Fatal(err) } d, err := ioutil.ReadAll(r) if err != nil { - t.Error(err) + t.Fatal(err) } if string(d) != "Hello" { @@ -112,7 +112,7 @@ func (tp *provider) TestBlockGet(t *testing.T) { p, err := coreiface.ParsePath("/ipfs/" + res.Path().Cid().String()) if err != nil { - t.Error(err) + t.Fatal(err) } rp, err := api.ResolvePath(ctx, p) @@ -129,7 +129,7 @@ func (tp *provider) TestBlockRm(t *testing.T) { defer cancel() api, err := tp.makeAPI(ctx) if err != nil { - t.Error(err) + t.Fatal(err) } res, err := api.Block().Put(ctx, strings.NewReader(`Hello`)) @@ -139,12 +139,12 @@ func (tp *provider) TestBlockRm(t *testing.T) { r, err := api.Block().Get(ctx, res.Path()) if err != nil { - t.Error(err) + t.Fatal(err) } d, err := ioutil.ReadAll(r) if err != nil { - t.Error(err) + t.Fatal(err) } if string(d) != "Hello" { @@ -153,7 +153,7 @@ func (tp *provider) TestBlockRm(t *testing.T) { err = api.Block().Rm(ctx, res.Path()) if err != nil { - t.Error(err) + t.Fatal(err) } _, err = api.Block().Get(ctx, res.Path()) @@ -174,7 +174,7 @@ func (tp *provider) TestBlockRm(t *testing.T) { err = api.Block().Rm(ctx, res.Path(), opt.Block.Force(true)) if err != nil { - t.Error(err) + t.Fatal(err) } } @@ -183,7 +183,7 @@ func (tp *provider) TestBlockStat(t *testing.T) { defer cancel() api, err := tp.makeAPI(ctx) if err != nil { - t.Error(err) + t.Fatal(err) } res, err := api.Block().Put(ctx, strings.NewReader(`Hello`)) @@ -193,7 +193,7 @@ func (tp *provider) TestBlockStat(t *testing.T) { stat, err := api.Block().Stat(ctx, res.Path()) if err != nil { - t.Error(err) + t.Fatal(err) } if stat.Path().String() != res.Path().String() { @@ -210,7 +210,7 @@ func (tp *provider) TestBlockPin(t *testing.T) { defer cancel() api, err := tp.makeAPI(ctx) if err != nil { - t.Error(err) + t.Fatal(err) } _, err = api.Block().Put(ctx, strings.NewReader(`Hello`)) diff --git a/core/coreiface/tests/dag.go b/core/coreiface/tests/dag.go index 7446c20de..ff034beec 100644 --- a/core/coreiface/tests/dag.go +++ b/core/coreiface/tests/dag.go @@ -44,12 +44,12 @@ func (tp *provider) TestPut(t *testing.T) { defer cancel() api, err := tp.makeAPI(ctx) if err != nil { - t.Error(err) + t.Fatal(err) } nd, err := ipldcbor.FromJSON(strings.NewReader(`"Hello"`), math.MaxUint64, -1) if err != nil { - t.Error(err) + t.Fatal(err) } err = api.Dag().Add(ctx, nd) @@ -67,12 +67,12 @@ func (tp *provider) TestPutWithHash(t *testing.T) { defer cancel() api, err := tp.makeAPI(ctx) if err != nil { - t.Error(err) + t.Fatal(err) } nd, err := ipldcbor.FromJSON(strings.NewReader(`"Hello"`), mh.ID, -1) if err != nil { - t.Error(err) + t.Fatal(err) } err = api.Dag().Add(ctx, nd) @@ -90,12 +90,12 @@ func (tp *provider) TestDagPath(t *testing.T) { defer cancel() api, err := tp.makeAPI(ctx) if err != nil { - t.Error(err) + t.Fatal(err) } snd, err := ipldcbor.FromJSON(strings.NewReader(`"foo"`), math.MaxUint64, -1) if err != nil { - t.Error(err) + t.Fatal(err) } err = api.Dag().Add(ctx, snd) @@ -105,7 +105,7 @@ func (tp *provider) TestDagPath(t *testing.T) { nd, err := ipldcbor.FromJSON(strings.NewReader(`{"lnk": {"/": "`+snd.Cid().String()+`"}}`), math.MaxUint64, -1) if err != nil { - t.Error(err) + t.Fatal(err) } err = api.Dag().Add(ctx, nd) @@ -115,17 +115,17 @@ func (tp *provider) TestDagPath(t *testing.T) { p, err := coreiface.ParsePath(path.Join(nd.Cid().String(), "lnk")) if err != nil { - t.Error(err) + t.Fatal(err) } rp, err := api.ResolvePath(ctx, p) if err != nil { - t.Error(err) + t.Fatal(err) } ndd, err := api.Dag().Get(ctx, rp.Cid()) if err != nil { - t.Error(err) + t.Fatal(err) } if ndd.Cid().String() != snd.Cid().String() { @@ -138,12 +138,12 @@ func (tp *provider) TestTree(t *testing.T) { defer cancel() api, err := tp.makeAPI(ctx) if err != nil { - t.Error(err) + t.Fatal(err) } nd, err := ipldcbor.FromJSON(strings.NewReader(`{"a": 123, "b": "foo", "c": {"d": 321, "e": 111}}`), math.MaxUint64, -1) if err != nil { - t.Error(err) + t.Fatal(err) } err = api.Dag().Add(ctx, nd) @@ -153,7 +153,7 @@ func (tp *provider) TestTree(t *testing.T) { res, err := api.Dag().Get(ctx, nd.Cid()) if err != nil { - t.Error(err) + t.Fatal(err) } lst := res.Tree("", -1) @@ -173,12 +173,12 @@ func (tp *provider) TestBatch(t *testing.T) { defer cancel() api, err := tp.makeAPI(ctx) if err != nil { - t.Error(err) + t.Fatal(err) } nd, err := ipldcbor.FromJSON(strings.NewReader(`"Hello"`), math.MaxUint64, -1) if err != nil { - t.Error(err) + t.Fatal(err) } if nd.Cid().String() != "zdpuAqckYF3ToF3gcJNxPZXmnmGuXd3gxHCXhq81HGxBejEvv" { @@ -187,15 +187,15 @@ func (tp *provider) TestBatch(t *testing.T) { _, err = api.Dag().Get(ctx, nd.Cid()) if err == nil || !strings.Contains(err.Error(), "not found") { - t.Error(err) + t.Fatal(err) } if err := api.Dag().AddMany(ctx, []ipld.Node{nd}); err != nil { - t.Error(err) + t.Fatal(err) } _, err = api.Dag().Get(ctx, nd.Cid()) if err != nil { - t.Error(err) + t.Fatal(err) } } diff --git a/core/coreiface/tests/key.go b/core/coreiface/tests/key.go index dbbfce059..7ff5f3330 100644 --- a/core/coreiface/tests/key.go +++ b/core/coreiface/tests/key.go @@ -121,7 +121,7 @@ func (tp *provider) TestGenerate(t *testing.T) { defer cancel() api, err := tp.makeAPI(ctx) if err != nil { - t.Error(err) + t.Fatal(err) } k, err := api.Key().Generate(ctx, "foo") @@ -144,7 +144,7 @@ func (tp *provider) TestGenerateSize(t *testing.T) { defer cancel() api, err := tp.makeAPI(ctx) if err != nil { - t.Error(err) + t.Fatal(err) } k, err := api.Key().Generate(ctx, "foo", opt.Key.Size(1024)) @@ -169,7 +169,7 @@ func (tp *provider) TestGenerateType(t *testing.T) { api, err := tp.makeAPI(ctx) if err != nil { - t.Error(err) + t.Fatal(err) } k, err := api.Key().Generate(ctx, "bar", opt.Key.Type(opt.Ed25519Key)) @@ -193,7 +193,7 @@ func (tp *provider) TestGenerateExisting(t *testing.T) { defer cancel() api, err := tp.makeAPI(ctx) if err != nil { - t.Error(err) + t.Fatal(err) } _, err = api.Key().Generate(ctx, "foo") @@ -226,7 +226,7 @@ func (tp *provider) TestList(t *testing.T) { defer cancel() api, err := tp.makeAPI(ctx) if err != nil { - t.Error(err) + t.Fatal(err) } _, err = api.Key().Generate(ctx, "foo") @@ -272,7 +272,7 @@ func (tp *provider) TestRename(t *testing.T) { defer cancel() api, err := tp.makeAPI(ctx) if err != nil { - t.Error(err) + t.Fatal(err) } _, err = api.Key().Generate(ctx, "foo") @@ -301,7 +301,7 @@ func (tp *provider) TestRenameToSelf(t *testing.T) { defer cancel() api, err := tp.makeAPI(ctx) if err != nil { - t.Error(err) + t.Fatal(err) } _, err = api.Key().Generate(ctx, "foo") @@ -325,7 +325,7 @@ func (tp *provider) TestRenameToSelfForce(t *testing.T) { defer cancel() api, err := tp.makeAPI(ctx) if err != nil { - t.Error(err) + t.Fatal(err) } _, err = api.Key().Generate(ctx, "foo") @@ -349,7 +349,7 @@ func (tp *provider) TestRenameOverwriteNoForce(t *testing.T) { defer cancel() api, err := tp.makeAPI(ctx) if err != nil { - t.Error(err) + t.Fatal(err) } _, err = api.Key().Generate(ctx, "foo") @@ -379,7 +379,7 @@ func (tp *provider) TestRenameOverwrite(t *testing.T) { defer cancel() api, err := tp.makeAPI(ctx) if err != nil { - t.Error(err) + t.Fatal(err) } kfoo, err := api.Key().Generate(ctx, "foo") @@ -418,7 +418,7 @@ func (tp *provider) TestRenameSameNameNoForce(t *testing.T) { defer cancel() api, err := tp.makeAPI(ctx) if err != nil { - t.Error(err) + t.Fatal(err) } _, err = api.Key().Generate(ctx, "foo") @@ -447,7 +447,7 @@ func (tp *provider) TestRenameSameName(t *testing.T) { defer cancel() api, err := tp.makeAPI(ctx) if err != nil { - t.Error(err) + t.Fatal(err) } _, err = api.Key().Generate(ctx, "foo") @@ -476,7 +476,7 @@ func (tp *provider) TestRemove(t *testing.T) { defer cancel() api, err := tp.makeAPI(ctx) if err != nil { - t.Error(err) + t.Fatal(err) } k, err := api.Key().Generate(ctx, "foo") diff --git a/core/coreiface/tests/path.go b/core/coreiface/tests/path.go index 4da1a5181..b99e8ab9c 100644 --- a/core/coreiface/tests/path.go +++ b/core/coreiface/tests/path.go @@ -68,7 +68,7 @@ func (tp *provider) TestPathRemainder(t *testing.T) { nd, err := ipldcbor.FromJSON(strings.NewReader(`{"foo": {"bar": "baz"}}`), math.MaxUint64, -1) if err != nil { - t.Error(err) + t.Fatal(err) } if err := api.Dag().Add(ctx, nd); err != nil { @@ -77,7 +77,7 @@ func (tp *provider) TestPathRemainder(t *testing.T) { p1, err := coreiface.ParsePath(nd.String() + "/foo/bar") if err != nil { - t.Error(err) + t.Fatal(err) } rp1, err := api.ResolvePath(ctx, p1) @@ -104,7 +104,7 @@ func (tp *provider) TestEmptyPathRemainder(t *testing.T) { nd, err := ipldcbor.FromJSON(strings.NewReader(`{"foo": {"bar": "baz"}}`), math.MaxUint64, -1) if err != nil { - t.Error(err) + t.Fatal(err) } if err := api.Dag().Add(ctx, nd); err != nil { @@ -113,7 +113,7 @@ func (tp *provider) TestEmptyPathRemainder(t *testing.T) { p1, err := coreiface.ParsePath(nd.Cid().String()) if err != nil { - t.Error(err) + t.Fatal(err) } rp1, err := api.ResolvePath(ctx, p1) @@ -140,7 +140,7 @@ func (tp *provider) TestInvalidPathRemainder(t *testing.T) { nd, err := ipldcbor.FromJSON(strings.NewReader(`{"foo": {"bar": "baz"}}`), math.MaxUint64, -1) if err != nil { - t.Error(err) + t.Fatal(err) } if err := api.Dag().Add(ctx, nd); err != nil { @@ -149,7 +149,7 @@ func (tp *provider) TestInvalidPathRemainder(t *testing.T) { p1, err := coreiface.ParsePath("/ipld/" + nd.Cid().String() + "/bar/baz") if err != nil { - t.Error(err) + t.Fatal(err) } _, err = api.ResolvePath(ctx, p1) @@ -181,7 +181,7 @@ func (tp *provider) TestPathRoot(t *testing.T) { nd, err := ipldcbor.FromJSON(strings.NewReader(`{"foo": {"/": "`+blk.Path().Cid().String()+`"}}`), math.MaxUint64, -1) if err != nil { - t.Error(err) + t.Fatal(err) } if err := api.Dag().Add(ctx, nd); err != nil { @@ -190,7 +190,7 @@ func (tp *provider) TestPathRoot(t *testing.T) { p1, err := coreiface.ParsePath("/ipld/" + nd.Cid().String() + "/foo") if err != nil { - t.Error(err) + t.Fatal(err) } rp, err := api.ResolvePath(ctx, p1) @@ -210,7 +210,7 @@ func (tp *provider) TestPathRoot(t *testing.T) { func (tp *provider) TestPathJoin(t *testing.T) { p1, err := coreiface.ParsePath("/ipfs/QmYNmQKp6SuaVrpgWRsPTgCQCnpxUYGq76YEKBXuj2N4H6/bar/baz") if err != nil { - t.Error(err) + t.Fatal(err) } if coreiface.Join(p1, "foo").String() != "/ipfs/QmYNmQKp6SuaVrpgWRsPTgCQCnpxUYGq76YEKBXuj2N4H6/bar/baz/foo" { diff --git a/core/coreiface/tests/pin.go b/core/coreiface/tests/pin.go index eed542283..ff6f98e35 100644 --- a/core/coreiface/tests/pin.go +++ b/core/coreiface/tests/pin.go @@ -31,17 +31,17 @@ func (tp *provider) TestPinAdd(t *testing.T) { defer cancel() api, err := tp.makeAPI(ctx) if err != nil { - t.Error(err) + t.Fatal(err) } p, err := api.Unixfs().Add(ctx, strFile("foo")()) if err != nil { - t.Error(err) + t.Fatal(err) } err = api.Pin().Add(ctx, p) if err != nil { - t.Error(err) + t.Fatal(err) } } @@ -50,17 +50,17 @@ func (tp *provider) TestPinSimple(t *testing.T) { defer cancel() api, err := tp.makeAPI(ctx) if err != nil { - t.Error(err) + t.Fatal(err) } p, err := api.Unixfs().Add(ctx, strFile("foo")()) if err != nil { - t.Error(err) + t.Fatal(err) } err = api.Pin().Add(ctx, p) if err != nil { - t.Error(err) + t.Fatal(err) } list, err := api.Pin().Ls(ctx) @@ -100,27 +100,27 @@ func (tp *provider) TestPinRecursive(t *testing.T) { defer cancel() api, err := tp.makeAPI(ctx) if err != nil { - t.Error(err) + t.Fatal(err) } p0, err := api.Unixfs().Add(ctx, strFile("foo")()) if err != nil { - t.Error(err) + t.Fatal(err) } p1, err := api.Unixfs().Add(ctx, strFile("bar")()) if err != nil { - t.Error(err) + t.Fatal(err) } nd2, err := ipldcbor.FromJSON(strings.NewReader(`{"lnk": {"/": "`+p0.Cid().String()+`"}}`), math.MaxUint64, -1) if err != nil { - t.Error(err) + t.Fatal(err) } nd3, err := ipldcbor.FromJSON(strings.NewReader(`{"lnk": {"/": "`+p1.Cid().String()+`"}}`), math.MaxUint64, -1) if err != nil { - t.Error(err) + t.Fatal(err) } if err := api.Dag().AddMany(ctx, []ipld.Node{nd2, nd3}); err != nil { @@ -129,12 +129,12 @@ func (tp *provider) TestPinRecursive(t *testing.T) { err = api.Pin().Add(ctx, iface.IpldPath(nd2.Cid())) if err != nil { - t.Error(err) + t.Fatal(err) } err = api.Pin().Add(ctx, iface.IpldPath(nd3.Cid()), opt.Pin.Recursive(false)) if err != nil { - t.Error(err) + t.Fatal(err) } list, err := api.Pin().Ls(ctx) diff --git a/core/coreiface/tests/unixfs.go b/core/coreiface/tests/unixfs.go index c27826b51..e99bf4429 100644 --- a/core/coreiface/tests/unixfs.go +++ b/core/coreiface/tests/unixfs.go @@ -98,7 +98,7 @@ func (tp *provider) TestAdd(t *testing.T) { defer cancel() api, err := tp.makeAPI(ctx) if err != nil { - t.Error(err) + t.Fatal(err) } p := func(h string) coreiface.ResolvedPath { @@ -566,15 +566,18 @@ func (tp *provider) TestAddPinned(t *testing.T) { defer cancel() api, err := tp.makeAPI(ctx) if err != nil { - t.Error(err) + t.Fatal(err) } _, err = api.Unixfs().Add(ctx, strFile(helloStr)(), options.Unixfs.Pin(true)) if err != nil { - t.Error(err) + t.Fatal(err) } pins, err := api.Pin().Ls(ctx) + if err != nil { + t.Fatal(err) + } if len(pins) != 1 { t.Fatalf("expected 1 pin, got %d", len(pins)) } @@ -589,12 +592,12 @@ func (tp *provider) TestAddHashOnly(t *testing.T) { defer cancel() api, err := tp.makeAPI(ctx) if err != nil { - t.Error(err) + t.Fatal(err) } p, err := api.Unixfs().Add(ctx, strFile(helloStr)(), options.Unixfs.HashOnly(true)) if err != nil { - t.Error(err) + t.Fatal(err) } if p.String() != hello { @@ -648,18 +651,18 @@ func (tp *provider) TestGetDir(t *testing.T) { defer cancel() api, err := tp.makeAPI(ctx) if err != nil { - t.Error(err) + t.Fatal(err) } edir := unixfs.EmptyDirNode() err = api.Dag().Add(ctx, edir) if err != nil { - t.Error(err) + t.Fatal(err) } p := coreiface.IpfsPath(edir.Cid()) emptyDir, err := api.Object().New(ctx, options.Object.Type("unixfs-dir")) if err != nil { - t.Error(err) + t.Fatal(err) } if p.String() != coreiface.IpfsPath(emptyDir.Cid()).String() { @@ -668,7 +671,7 @@ func (tp *provider) TestGetDir(t *testing.T) { r, err := api.Unixfs().Get(ctx, coreiface.IpfsPath(emptyDir.Cid())) if err != nil { - t.Error(err) + t.Fatal(err) } if _, ok := r.(files.Directory); !ok { @@ -681,13 +684,13 @@ func (tp *provider) TestGetNonUnixfs(t *testing.T) { defer cancel() api, err := tp.makeAPI(ctx) if err != nil { - t.Error(err) + t.Fatal(err) } nd := new(mdag.ProtoNode) err = api.Dag().Add(ctx, nd) if err != nil { - t.Error(err) + t.Fatal(err) } _, err = api.Unixfs().Get(ctx, coreiface.IpfsPath(nd.Cid())) @@ -761,7 +764,7 @@ func (tp *provider) TestEntriesExpired(t *testing.T) { defer cancel() api, err := tp.makeAPI(ctx) if err != nil { - t.Error(err) + t.Fatal(err) } r := strings.NewReader("content-of-file") @@ -769,14 +772,14 @@ func (tp *provider) TestEntriesExpired(t *testing.T) { "name-of-file": files.NewReaderFile(r), })) if err != nil { - t.Error(err) + t.Fatal(err) } ctx, cancel = context.WithCancel(ctx) nd, err := api.Unixfs().Get(ctx, p) if err != nil { - t.Error(err) + t.Fatal(err) } cancel() @@ -803,22 +806,22 @@ func (tp *provider) TestLsEmptyDir(t *testing.T) { defer cancel() api, err := tp.makeAPI(ctx) if err != nil { - t.Error(err) + t.Fatal(err) } _, err = api.Unixfs().Add(ctx, files.NewSliceDirectory([]files.DirEntry{})) if err != nil { - t.Error(err) + t.Fatal(err) } emptyDir, err := api.Object().New(ctx, options.Object.Type("unixfs-dir")) if err != nil { - t.Error(err) + t.Fatal(err) } links, err := api.Unixfs().Ls(ctx, coreiface.IpfsPath(emptyDir.Cid())) if err != nil { - t.Error(err) + t.Fatal(err) } if len(links) != 0 { @@ -832,7 +835,7 @@ func (tp *provider) TestLsNonUnixfs(t *testing.T) { defer cancel() api, err := tp.makeAPI(ctx) if err != nil { - t.Error(err) + t.Fatal(err) } nd, err := cbor.WrapObject(map[string]interface{}{"foo": "bar"}, math.MaxUint64, -1) @@ -842,12 +845,12 @@ func (tp *provider) TestLsNonUnixfs(t *testing.T) { err = api.Dag().Add(ctx, nd) if err != nil { - t.Error(err) + t.Fatal(err) } links, err := api.Unixfs().Ls(ctx, coreiface.IpfsPath(nd.Cid())) if err != nil { - t.Error(err) + t.Fatal(err) } if len(links) != 0 { @@ -890,7 +893,7 @@ func (tp *provider) TestAddCloses(t *testing.T) { defer cancel() api, err := tp.makeAPI(ctx) if err != nil { - t.Error(err) + t.Fatal(err) } n4 := &closeTestF{files.NewBytesFile([]byte("foo")), false, t} @@ -907,7 +910,7 @@ func (tp *provider) TestAddCloses(t *testing.T) { _, err = api.Unixfs().Add(ctx, d0) if err != nil { - t.Error(err) + t.Fatal(err) } d0.Close() // Adder doesn't close top-level file @@ -930,7 +933,7 @@ func (tp *provider) TestGetSeek(t *testing.T) { defer cancel() api, err := tp.makeAPI(ctx) if err != nil { - t.Error(err) + t.Fatal(err) } dataSize := int64(100000) From 1f87fa6168ea5ffcba06e5fb0de0ad9324b8d09b Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Tue, 26 Mar 2019 18:35:13 +0000 Subject: [PATCH 0274/1212] tests: remove t.Fatal from goroutines This commit was moved from ipfs/interface-go-ipfs-core@5f17f8346b441a6105b569084fa020af989b0f4c This commit was moved from ipfs/boxo@ccb4a5c183b98b9dcf40eee0c0ac8e4a317b4ed8 --- core/coreiface/tests/pubsub.go | 4 +++- core/coreiface/tests/unixfs.go | 8 +++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/core/coreiface/tests/pubsub.go b/core/coreiface/tests/pubsub.go index bb870de6c..dd05b73cf 100644 --- a/core/coreiface/tests/pubsub.go +++ b/core/coreiface/tests/pubsub.go @@ -40,7 +40,9 @@ func (tp *provider) TestBasicPubSub(t *testing.T) { for { err := apis[1].PubSub().Publish(ctx, "testch", []byte("hello world")) if err != nil { - t.Fatal(err) + t.Error(err) + cancel() + return } select { case <-tick: diff --git a/core/coreiface/tests/unixfs.go b/core/coreiface/tests/unixfs.go index e99bf4429..576160500 100644 --- a/core/coreiface/tests/unixfs.go +++ b/core/coreiface/tests/unixfs.go @@ -423,11 +423,13 @@ func (tp *provider) TestAdd(t *testing.T) { for evt := range eventOut { event, ok := evt.(*coreiface.AddEvent) if !ok { - t.Fatal("unexpected event type") + t.Error("unexpected event type") + continue } if len(expected) < 1 { - t.Fatal("got more events than expected") + t.Error("got more events than expected") + continue } if expected[0].Size != event.Size { @@ -453,7 +455,7 @@ func (tp *provider) TestAdd(t *testing.T) { } if len(expected) > 0 { - t.Fatalf("%d event(s) didn't arrive", len(expected)) + t.Errorf("%d event(s) didn't arrive", len(expected)) } }() } From ba5e78a4c5de8bc560ba0579887f80aa47844419 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Tue, 26 Mar 2019 18:37:40 +0000 Subject: [PATCH 0275/1212] tests: remove ticker leak This commit was moved from ipfs/interface-go-ipfs-core@a7d4a7199895a4bd66fa655b73f94ecea4540fdf This commit was moved from ipfs/boxo@b75b1243fb9738e1b5eb6fd19bca980bd156299c --- core/coreiface/tests/pubsub.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/core/coreiface/tests/pubsub.go b/core/coreiface/tests/pubsub.go index dd05b73cf..418fc4867 100644 --- a/core/coreiface/tests/pubsub.go +++ b/core/coreiface/tests/pubsub.go @@ -35,7 +35,8 @@ func (tp *provider) TestBasicPubSub(t *testing.T) { } go func() { - tick := time.Tick(100 * time.Millisecond) + ticker := time.NewTicker(100 * time.Millisecond) + defer ticker.Stop() for { err := apis[1].PubSub().Publish(ctx, "testch", []byte("hello world")) @@ -45,7 +46,7 @@ func (tp *provider) TestBasicPubSub(t *testing.T) { return } select { - case <-tick: + case <-ticker.C: case <-ctx.Done(): return } From adddfdf0f7f8c50957d4581c04db4711ddb4f925 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Tue, 26 Mar 2019 18:38:02 +0000 Subject: [PATCH 0276/1212] tests: fix unused variable lints This commit was moved from ipfs/interface-go-ipfs-core@5d6a474f3191362120268fa1b0396823013fbe41 This commit was moved from ipfs/boxo@bbf450e3e44f7595a128eba9b7578a412ddcd551 --- core/coreiface/tests/object.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/core/coreiface/tests/object.go b/core/coreiface/tests/object.go index 026def73b..8682a2edc 100644 --- a/core/coreiface/tests/object.go +++ b/core/coreiface/tests/object.go @@ -296,7 +296,7 @@ func (tp *provider) TestObjectAddLinkCreate(t *testing.T) { t.Fatal(err) } - p3, err := api.Object().AddLink(ctx, p2, "abc/d", p2) + _, err = api.Object().AddLink(ctx, p2, "abc/d", p2) if err == nil { t.Fatal("expected an error") } @@ -304,7 +304,7 @@ func (tp *provider) TestObjectAddLinkCreate(t *testing.T) { t.Fatalf("unexpected error: %s", err.Error()) } - p3, err = api.Object().AddLink(ctx, p2, "abc/d", p2, opt.Object.Create(true)) + p3, err := api.Object().AddLink(ctx, p2, "abc/d", p2, opt.Object.Create(true)) if err != nil { t.Fatal(err) } @@ -384,6 +384,9 @@ func (tp *provider) TestObjectAddData(t *testing.T) { } data, err := ioutil.ReadAll(r) + if err != nil { + t.Fatal(err) + } if string(data) != "foobar" { t.Error("unexpected data") @@ -414,6 +417,9 @@ func (tp *provider) TestObjectSetData(t *testing.T) { } data, err := ioutil.ReadAll(r) + if err != nil { + t.Fatal(err) + } if string(data) != "bar" { t.Error("unexpected data") From 6c4219a102a7cb05ec824fc035e01abe79b8e072 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Tue, 26 Mar 2019 19:01:23 +0000 Subject: [PATCH 0277/1212] don't close the top-level addr See https://github.com/ipfs/go-ipfs-http-client/pull/10/files#r269268326 This commit was moved from ipfs/interface-go-ipfs-core@1b707f294336a6eaf3274e27ab0ce85a2b374fbe This commit was moved from ipfs/boxo@21ade61b10b9757f9dfd2dafdb3c95a0ec00ccb1 --- core/coreiface/tests/unixfs.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/core/coreiface/tests/unixfs.go b/core/coreiface/tests/unixfs.go index 0fd494f66..ea36b7330 100644 --- a/core/coreiface/tests/unixfs.go +++ b/core/coreiface/tests/unixfs.go @@ -834,6 +834,7 @@ type closeTestD struct { } func (f *closeTestD) Close() error { + f.t.Helper() if f.closed { f.t.Fatal("already closed") } @@ -874,8 +875,6 @@ func (tp *provider) TestAddCloses(t *testing.T) { t.Error(err) } - d0.Close() // Adder doesn't close top-level file - for i, n := range []*closeTestF{n1, n2, n4} { if !n.closed { t.Errorf("file %d not closed!", i) From 0e800c3d8431fdcdc22ee2a2ac3337cb009553c3 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Tue, 26 Mar 2019 18:15:37 +0000 Subject: [PATCH 0278/1212] update interface-go-ipfs-core and handle breaking changes * No more Hidden, StdinName, and Wrap options. * LsLink -> DirEntry with file types that don't expose internals. This commit was moved from ipfs/go-ipfs-http-client@5a7161eeab7127da4348dda6a6dc16f07b051f36 --- client/httpapi/apifile.go | 13 ++++----- client/httpapi/unixfs.go | 58 ++++++++++++++++++++------------------- 2 files changed, 35 insertions(+), 36 deletions(-) diff --git a/client/httpapi/apifile.go b/client/httpapi/apifile.go index a8eb0de1a..e0c0c9e1b 100644 --- a/client/httpapi/apifile.go +++ b/client/httpapi/apifile.go @@ -8,8 +8,9 @@ import ( "io/ioutil" "github.com/ipfs/go-cid" - "github.com/ipfs/go-ipfs-files" - "github.com/ipfs/interface-go-ipfs-core" + files "github.com/ipfs/go-ipfs-files" + unixfs "github.com/ipfs/go-unixfs" + iface "github.com/ipfs/interface-go-ipfs-core" ) const forwardSeekLimit = 1 << 14 //16k @@ -174,17 +175,13 @@ func (it *apiIter) Next() bool { } switch it.cur.Type { - case iface.THAMTShard: - fallthrough - case iface.TMetadata: - fallthrough - case iface.TDirectory: + case unixfs.THAMTShard, unixfs.TMetadata, unixfs.TDirectory: it.curFile, err = it.core.getDir(it.ctx, iface.IpfsPath(c), int64(it.cur.Size)) if err != nil { it.err = err return false } - case iface.TFile: + case unixfs.TFile: it.curFile, err = it.core.getFile(it.ctx, iface.IpfsPath(c), int64(it.cur.Size)) if err != nil { it.err = err diff --git a/client/httpapi/unixfs.go b/client/httpapi/unixfs.go index 1f340b657..4f717b129 100644 --- a/client/httpapi/unixfs.go +++ b/client/httpapi/unixfs.go @@ -8,9 +8,10 @@ import ( "io" "github.com/ipfs/go-cid" - "github.com/ipfs/go-ipfs-files" - "github.com/ipfs/go-ipld-format" - "github.com/ipfs/interface-go-ipfs-core" + files "github.com/ipfs/go-ipfs-files" + unixfs "github.com/ipfs/go-unixfs" + unixfs_pb "github.com/ipfs/go-unixfs/pb" + iface "github.com/ipfs/interface-go-ipfs-core" caopts "github.com/ipfs/interface-go-ipfs-core/options" mh "github.com/multiformats/go-multihash" ) @@ -40,15 +41,12 @@ func (api *UnixfsAPI) Add(ctx context.Context, f files.Node, opts ...caopts.Unix Option("chunker", options.Chunker). Option("cid-version", options.CidVersion). Option("fscache", options.FsCache). - Option("hidden", options.Hidden). Option("inline", options.Inline). Option("inline-limit", options.InlineLimit). Option("nocopy", options.NoCopy). Option("only-hash", options.OnlyHash). Option("pin", options.Pin). Option("silent", options.Silent). - Option("stdin-name", options.StdinName). - Option("wrap-with-directory", options.Wrap). Option("progress", options.Progress) if options.RawLeavesSet { @@ -62,13 +60,8 @@ func (api *UnixfsAPI) Add(ctx context.Context, f files.Node, opts ...caopts.Unix req.Option("trickle", true) } - switch c := f.(type) { - case files.Directory: - req.Body(files.NewMultiFileReader(c, false)) - case files.File: - d := files.NewMapDirectory(map[string]files.Node{"": c}) // unwrapped on the other side - req.Body(files.NewMultiFileReader(d, false)) - } + d := files.NewMapDirectory(map[string]files.Node{"": f}) // unwrapped on the other side + req.Body(files.NewMultiFileReader(d, false)) var out addEvent resp, err := req.Send(ctx) @@ -127,7 +120,8 @@ loop: type lsLink struct { Name, Hash string Size uint64 - Type iface.FileType + Type unixfs_pb.Data_DataType + Target string } type lsObject struct { @@ -139,7 +133,7 @@ type lsOutput struct { Objects []lsObject } -func (api *UnixfsAPI) Ls(ctx context.Context, p iface.Path, opts ...caopts.UnixfsLsOption) (<-chan iface.LsLink, error) { +func (api *UnixfsAPI) Ls(ctx context.Context, p iface.Path, opts ...caopts.UnixfsLsOption) (<-chan iface.DirEntry, error) { options, err := caopts.UnixfsLsOptions(opts...) if err != nil { return nil, err @@ -158,7 +152,7 @@ func (api *UnixfsAPI) Ls(ctx context.Context, p iface.Path, opts ...caopts.Unixf } dec := json.NewDecoder(resp.Output) - out := make(chan iface.LsLink) + out := make(chan iface.DirEntry) go func() { defer resp.Close() @@ -171,7 +165,7 @@ func (api *UnixfsAPI) Ls(ctx context.Context, p iface.Path, opts ...caopts.Unixf return } select { - case out <- iface.LsLink{Err: err}: + case out <- iface.DirEntry{Err: err}: case <-ctx.Done(): } return @@ -179,7 +173,7 @@ func (api *UnixfsAPI) Ls(ctx context.Context, p iface.Path, opts ...caopts.Unixf if len(link.Objects) != 1 { select { - case out <- iface.LsLink{Err: errors.New("unexpected Objects len")}: + case out <- iface.DirEntry{Err: errors.New("unexpected Objects len")}: case <-ctx.Done(): } return @@ -187,7 +181,7 @@ func (api *UnixfsAPI) Ls(ctx context.Context, p iface.Path, opts ...caopts.Unixf if len(link.Objects[0].Links) != 1 { select { - case out <- iface.LsLink{Err: errors.New("unexpected Links len")}: + case out <- iface.DirEntry{Err: errors.New("unexpected Links len")}: case <-ctx.Done(): } return @@ -198,21 +192,29 @@ func (api *UnixfsAPI) Ls(ctx context.Context, p iface.Path, opts ...caopts.Unixf c, err := cid.Decode(l0.Hash) if err != nil { select { - case out <- iface.LsLink{Err: err}: + case out <- iface.DirEntry{Err: err}: case <-ctx.Done(): } return } + var ftype iface.FileType + switch l0.Type { + case unixfs.TRaw, unixfs.TFile: + ftype = iface.TFile + case unixfs.THAMTShard, unixfs.TDirectory, unixfs.TMetadata: + ftype = iface.TDirectory + case unixfs.TSymlink: + ftype = iface.TSymlink + } + select { - case out <- iface.LsLink{ - Link: &format.Link{ - Cid: c, - Name: l0.Name, - Size: l0.Size, - }, - Size: l0.Size, - Type: l0.Type, + case out <- iface.DirEntry{ + Name: l0.Name, + Cid: c, + Size: l0.Size, + Type: ftype, + Target: l0.Target, }: case <-ctx.Done(): } From e76ecd30384799dfe388671ebd153e88903d9388 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Tue, 26 Mar 2019 16:54:05 +0000 Subject: [PATCH 0279/1212] nit: return concrete types This is generally considered the "better" way to do things in go. It also allows us to expose functions like `request` at some point without changing the API interface itself. This commit was moved from ipfs/go-ipfs-http-client@524e5d82e6bcd2c4956151a4811addad656d7bf0 --- client/httpapi/api.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/httpapi/api.go b/client/httpapi/api.go index 17a289cc5..ef6eff3e8 100644 --- a/client/httpapi/api.go +++ b/client/httpapi/api.go @@ -39,7 +39,7 @@ type HttpApi struct { // // Daemon api address is pulled from the $IPFS_PATH/api file. // If $IPFS_PATH env var is not present, it defaults to ~/.ipfs -func NewLocalApi() (iface.CoreAPI, error) { +func NewLocalApi() (*HttpApi, error) { baseDir := os.Getenv(EnvDir) if baseDir == "" { baseDir = DefaultPathRoot @@ -50,7 +50,7 @@ func NewLocalApi() (iface.CoreAPI, error) { // NewPathApi constructs new HttpApi by pulling api address from specified // ipfspath. Api file should be located at $ipfspath/api -func NewPathApi(ipfspath string) (iface.CoreAPI, error) { +func NewPathApi(ipfspath string) (*HttpApi, error) { a, err := ApiAddr(ipfspath) if err != nil { if os.IsNotExist(err) { From c6f704b453cd72734ca03793cd370021f4a39db9 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Tue, 26 Mar 2019 17:02:04 +0000 Subject: [PATCH 0280/1212] return an error when the API file isn't found fixes #7 This commit was moved from ipfs/go-ipfs-http-client@897d1b1bcdbf9f6616991366e66ac55e18a99a9c --- client/httpapi/api.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/client/httpapi/api.go b/client/httpapi/api.go index ef6eff3e8..6c41ef3ab 100644 --- a/client/httpapi/api.go +++ b/client/httpapi/api.go @@ -1,6 +1,7 @@ package httpapi import ( + "errors" "fmt" "io/ioutil" gohttp "net/http" @@ -22,6 +23,9 @@ const ( EnvDir = "IPFS_PATH" ) +// ErrApiNotFound if we fail to find a running daemon. +var ErrApiNotFound = errors.New("ipfs api address could not be found") + // HttpApi implements github.com/ipfs/interface-go-ipfs-core/CoreAPI using // IPFS HTTP API. // @@ -54,7 +58,7 @@ func NewPathApi(ipfspath string) (*HttpApi, error) { a, err := ApiAddr(ipfspath) if err != nil { if os.IsNotExist(err) { - err = nil + err = ErrApiNotFound } return nil, err } From 40f40b5a6593af189b81f43e393316b381bd541d Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Tue, 26 Mar 2019 17:04:33 +0000 Subject: [PATCH 0281/1212] fix golang-ci lint nits This commit was moved from ipfs/go-ipfs-http-client@ccf20b0ef5f440aca754f94325fca7202275ba8b --- client/httpapi/apifile.go | 2 +- client/httpapi/response.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/client/httpapi/apifile.go b/client/httpapi/apifile.go index e0c0c9e1b..1fd751ede 100644 --- a/client/httpapi/apifile.go +++ b/client/httpapi/apifile.go @@ -56,7 +56,7 @@ type apiFile struct { func (f *apiFile) reset() error { if f.r != nil { - f.r.Cancel() + _ = f.r.Cancel() } req := f.core.request("cat", f.path.String()) if f.at != 0 { diff --git a/client/httpapi/response.go b/client/httpapi/response.go index 339c73658..ed3033886 100644 --- a/client/httpapi/response.go +++ b/client/httpapi/response.go @@ -147,8 +147,8 @@ func (r *Request) Send(c *http.Client) (*Response, error) { nresp.Output = nil // drain body and close - io.Copy(ioutil.Discard, resp.Body) - resp.Body.Close() + _, _ = io.Copy(ioutil.Discard, resp.Body) + _ = resp.Body.Close() } return nresp, nil From c791d73355e33139e2face5fc96884c5444f96c7 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Tue, 26 Mar 2019 17:05:02 +0000 Subject: [PATCH 0282/1212] avoid canceling multiple times This commit was moved from ipfs/go-ipfs-http-client@fe16408225d4c9b688528f67ffabe08198b53ab5 --- client/httpapi/apifile.go | 1 + 1 file changed, 1 insertion(+) diff --git a/client/httpapi/apifile.go b/client/httpapi/apifile.go index 1fd751ede..9e6df95c2 100644 --- a/client/httpapi/apifile.go +++ b/client/httpapi/apifile.go @@ -57,6 +57,7 @@ type apiFile struct { func (f *apiFile) reset() error { if f.r != nil { _ = f.r.Cancel() + f.r = nil } req := f.core.request("cat", f.path.String()) if f.at != 0 { From 686f55459c5747fac06c8b76810a371c9e635d9b Mon Sep 17 00:00:00 2001 From: Edgar Lee Date: Fri, 29 Mar 2019 16:16:16 -0700 Subject: [PATCH 0283/1212] Update Pin.RmRecursive docs to clarify shared indirect pins are not removed This commit was moved from ipfs/interface-go-ipfs-core@c908a059feab33b74ce66dca01fd521389372942 This commit was moved from ipfs/boxo@ea26ae5e0535dc2429c8c2797b79982317cc9bb3 --- core/coreiface/options/pin.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core/coreiface/options/pin.go b/core/coreiface/options/pin.go index cc4a8ef29..6b211bb73 100644 --- a/core/coreiface/options/pin.go +++ b/core/coreiface/options/pin.go @@ -127,7 +127,9 @@ func (pinOpts) Recursive(recursive bool) PinAddOption { } } -// RmRecursive is an option for Pin.Rm +// RmRecursive is an option for Pin.Rm which specifies whether to recursively +// unpin the object linked to by the specified object(s). This does not remove +// indirect pins referenced by other recursive pins. func (pinOpts) RmRecursive(recursive bool) PinRmOption { return func(settings *PinRmSettings) error { settings.Recursive = recursive From 1c07bed90465210c27dba3cda850913cf397b5c5 Mon Sep 17 00:00:00 2001 From: Edgar Lee Date: Mon, 1 Apr 2019 17:13:39 -0700 Subject: [PATCH 0284/1212] Export (*HttpApi).request to enable building custom requests This commit was moved from ipfs/go-ipfs-http-client@8c9ed7dbc284b4d112f6805914a43e63f234df78 --- client/httpapi/api.go | 2 +- client/httpapi/apifile.go | 6 +++--- client/httpapi/block.go | 8 ++++---- client/httpapi/dht.go | 6 +++--- client/httpapi/key.go | 10 +++++----- client/httpapi/name.go | 6 +++--- client/httpapi/object.go | 18 +++++++++--------- client/httpapi/path.go | 2 +- client/httpapi/pin.go | 10 +++++----- client/httpapi/pubsub.go | 8 ++++---- client/httpapi/swarm.go | 12 ++++++------ client/httpapi/unixfs.go | 4 ++-- 12 files changed, 46 insertions(+), 46 deletions(-) diff --git a/client/httpapi/api.go b/client/httpapi/api.go index 6c41ef3ab..dad205fd0 100644 --- a/client/httpapi/api.go +++ b/client/httpapi/api.go @@ -138,7 +138,7 @@ func (api *HttpApi) WithOptions(opts ...caopts.ApiOption) (iface.CoreAPI, error) return &subApi, nil } -func (api *HttpApi) request(command string, args ...string) *RequestBuilder { +func (api *HttpApi) Request(command string, args ...string) *RequestBuilder { return &RequestBuilder{ command: command, args: args, diff --git a/client/httpapi/apifile.go b/client/httpapi/apifile.go index 9e6df95c2..6e3433a51 100644 --- a/client/httpapi/apifile.go +++ b/client/httpapi/apifile.go @@ -29,7 +29,7 @@ func (api *UnixfsAPI) Get(ctx context.Context, p iface.Path) (files.Node, error) Type string Size int64 // unixfs size } - err := api.core().request("files/stat", p.String()).Exec(ctx, &stat) + err := api.core().Request("files/stat", p.String()).Exec(ctx, &stat) if err != nil { return nil, err } @@ -59,7 +59,7 @@ func (f *apiFile) reset() error { _ = f.r.Cancel() f.r = nil } - req := f.core.request("cat", f.path.String()) + req := f.core.Request("cat", f.path.String()) if f.at != 0 { req.Option("offset", f.at) } @@ -225,7 +225,7 @@ func (d *apiDir) Entries() files.DirIterator { } func (api *UnixfsAPI) getDir(ctx context.Context, p iface.Path, size int64) (files.Node, error) { - resp, err := api.core().request("ls", p.String()). + resp, err := api.core().Request("ls", p.String()). Option("resolve-size", true). Option("stream", true).Send(ctx) diff --git a/client/httpapi/block.go b/client/httpapi/block.go index fd4d9bab9..3389f4c31 100644 --- a/client/httpapi/block.go +++ b/client/httpapi/block.go @@ -41,7 +41,7 @@ func (api *BlockAPI) Put(ctx context.Context, r io.Reader, opts ...caopts.BlockP return nil, fmt.Errorf("unknowm mhType %d", options.MhType) } - req := api.core().request("block/put"). + req := api.core().Request("block/put"). Option("mhtype", mht). Option("mhlen", options.MhLength). Option("format", options.Codec). @@ -61,7 +61,7 @@ func (api *BlockAPI) Put(ctx context.Context, r io.Reader, opts ...caopts.BlockP } func (api *BlockAPI) Get(ctx context.Context, p iface.Path) (io.Reader, error) { - resp, err := api.core().request("block/get", p.String()).Send(ctx) + resp, err := api.core().Request("block/get", p.String()).Send(ctx) if err != nil { return nil, err } @@ -90,7 +90,7 @@ func (api *BlockAPI) Rm(ctx context.Context, p iface.Path, opts ...caopts.BlockR Error string `json:",omitempty"` }{} - req := api.core().request("block/rm"). + req := api.core().Request("block/rm"). Option("force", options.Force). Arguments(p.String()) @@ -107,7 +107,7 @@ func (api *BlockAPI) Rm(ctx context.Context, p iface.Path, opts ...caopts.BlockR func (api *BlockAPI) Stat(ctx context.Context, p iface.Path) (iface.BlockStat, error) { var out blockStat - err := api.core().request("block/stat", p.String()).Exec(ctx, &out) + err := api.core().Request("block/stat", p.String()).Exec(ctx, &out) if err != nil { return nil, err } diff --git a/client/httpapi/dht.go b/client/httpapi/dht.go index dc7dd6bea..f7417cb7f 100644 --- a/client/httpapi/dht.go +++ b/client/httpapi/dht.go @@ -18,7 +18,7 @@ func (api *DhtAPI) FindPeer(ctx context.Context, p peer.ID) (peerstore.PeerInfo, Type notif.QueryEventType Responses []peerstore.PeerInfo } - resp, err := api.core().request("dht/findpeer", p.Pretty()).Send(ctx) + resp, err := api.core().Request("dht/findpeer", p.Pretty()).Send(ctx) if err != nil { return peerstore.PeerInfo{}, err } @@ -48,7 +48,7 @@ func (api *DhtAPI) FindProviders(ctx context.Context, p iface.Path, opts ...caop return nil, err } - resp, err := api.core().request("dht/findprovs", rp.Cid().String()). + resp, err := api.core().Request("dht/findprovs", rp.Cid().String()). Option("num-providers", options.NumProviders). Send(ctx) if err != nil { @@ -104,7 +104,7 @@ func (api *DhtAPI) Provide(ctx context.Context, p iface.Path, opts ...caopts.Dht return err } - return api.core().request("dht/provide", rp.Cid().String()). + return api.core().Request("dht/provide", rp.Cid().String()). Option("recursive", options.Recursive). Exec(ctx, nil) } diff --git a/client/httpapi/key.go b/client/httpapi/key.go index a16c30d8e..1571a3350 100644 --- a/client/httpapi/key.go +++ b/client/httpapi/key.go @@ -38,7 +38,7 @@ func (api *KeyAPI) Generate(ctx context.Context, name string, opts ...caopts.Key } var out keyOutput - err = api.core().request("key/gen", name). + err = api.core().Request("key/gen", name). Option("type", options.Algorithm). Option("size", options.Size). Exec(ctx, &out) @@ -61,7 +61,7 @@ func (api *KeyAPI) Rename(ctx context.Context, oldName string, newName string, o Id string Overwrite bool } - err = api.core().request("key/rename", oldName, newName). + err = api.core().Request("key/rename", oldName, newName). Option("force", options.Force). Exec(ctx, &out) if err != nil { @@ -75,7 +75,7 @@ func (api *KeyAPI) Rename(ctx context.Context, oldName string, newName string, o func (api *KeyAPI) List(ctx context.Context) ([]iface.Key, error) { var out struct{ Keys []*keyOutput } - if err := api.core().request("key/list").Exec(ctx, &out); err != nil { + if err := api.core().Request("key/list").Exec(ctx, &out); err != nil { return nil, err } @@ -94,7 +94,7 @@ func (api *KeyAPI) List(ctx context.Context) ([]iface.Key, error) { func (api *KeyAPI) Self(ctx context.Context) (iface.Key, error) { var id struct{ ID string } - if err := api.core().request("id").Exec(ctx, &id); err != nil { + if err := api.core().Request("id").Exec(ctx, &id); err != nil { return nil, err } @@ -106,7 +106,7 @@ func (api *KeyAPI) Self(ctx context.Context) (iface.Key, error) { func (api *KeyAPI) Remove(ctx context.Context, name string) (iface.Key, error) { var out struct{ Keys []keyOutput } - if err := api.core().request("key/rm", name).Exec(ctx, &out); err != nil { + if err := api.core().Request("key/rm", name).Exec(ctx, &out); err != nil { return nil, err } if len(out.Keys) != 1 { diff --git a/client/httpapi/name.go b/client/httpapi/name.go index b848aa819..0641d1a22 100644 --- a/client/httpapi/name.go +++ b/client/httpapi/name.go @@ -34,7 +34,7 @@ func (api *NameAPI) Publish(ctx context.Context, p iface.Path, opts ...caopts.Na return nil, err } - req := api.core().request("name/publish", p.String()). + req := api.core().Request("name/publish", p.String()). Option("key", options.Key). Option("allow-offline", options.AllowOffline). Option("lifetime", options.ValidTime). @@ -63,7 +63,7 @@ func (api *NameAPI) Search(ctx context.Context, name string, opts ...caopts.Name return nil, fmt.Errorf("Name.Resolve: depth other than 1 or %d not supported", nsopts.DefaultDepthLimit) } - req := api.core().request("name/resolve", name). + req := api.core().Request("name/resolve", name). Option("nocache", !options.Cache). Option("recursive", ropts.Depth != 1). Option("dht-record-count", ropts.DhtRecordCount). @@ -120,7 +120,7 @@ func (api *NameAPI) Resolve(ctx context.Context, name string, opts ...caopts.Nam return nil, fmt.Errorf("Name.Resolve: depth other than 1 or %d not supported", nsopts.DefaultDepthLimit) } - req := api.core().request("name/resolve", name). + req := api.core().Request("name/resolve", name). Option("nocache", !options.Cache). Option("recursive", ropts.Depth != 1). Option("dht-record-count", ropts.DhtRecordCount). diff --git a/client/httpapi/object.go b/client/httpapi/object.go index 5a06f74d9..a1ee486b3 100644 --- a/client/httpapi/object.go +++ b/client/httpapi/object.go @@ -48,7 +48,7 @@ func (api *ObjectAPI) Put(ctx context.Context, r io.Reader, opts ...caopts.Objec } var out objectOut - err = api.core().request("object/put"). + err = api.core().Request("object/put"). Option("inputenc", options.InputEnc). Option("datafieldenc", options.DataType). Option("pin", options.Pin). @@ -80,7 +80,7 @@ func (api *ObjectAPI) Get(ctx context.Context, p iface.Path) (ipld.Node, error) } func (api *ObjectAPI) Data(ctx context.Context, p iface.Path) (io.Reader, error) { - resp, err := api.core().request("object/data", p.String()).Send(ctx) + resp, err := api.core().Request("object/data", p.String()).Send(ctx) if err != nil { return nil, err } @@ -106,7 +106,7 @@ func (api *ObjectAPI) Links(ctx context.Context, p iface.Path) ([]*ipld.Link, er Size uint64 } } - if err := api.core().request("object/links", p.String()).Exec(ctx, &out); err != nil { + if err := api.core().Request("object/links", p.String()).Exec(ctx, &out); err != nil { return nil, err } res := make([]*ipld.Link, len(out.Links)) @@ -135,7 +135,7 @@ func (api *ObjectAPI) Stat(ctx context.Context, p iface.Path) (*iface.ObjectStat DataSize int CumulativeSize int } - if err := api.core().request("object/stat", p.String()).Exec(ctx, &out); err != nil { + if err := api.core().Request("object/stat", p.String()).Exec(ctx, &out); err != nil { return nil, err } @@ -161,7 +161,7 @@ func (api *ObjectAPI) AddLink(ctx context.Context, base iface.Path, name string, } var out objectOut - err = api.core().request("object/patch/add-link", base.String(), name, child.String()). + err = api.core().Request("object/patch/add-link", base.String(), name, child.String()). Option("create", options.Create). Exec(ctx, &out) if err != nil { @@ -178,7 +178,7 @@ func (api *ObjectAPI) AddLink(ctx context.Context, base iface.Path, name string, func (api *ObjectAPI) RmLink(ctx context.Context, base iface.Path, link string) (iface.ResolvedPath, error) { var out objectOut - err := api.core().request("object/patch/rm-link", base.String(), link). + err := api.core().Request("object/patch/rm-link", base.String(), link). Exec(ctx, &out) if err != nil { return nil, err @@ -194,7 +194,7 @@ func (api *ObjectAPI) RmLink(ctx context.Context, base iface.Path, link string) func (api *ObjectAPI) AppendData(ctx context.Context, p iface.Path, r io.Reader) (iface.ResolvedPath, error) { var out objectOut - err := api.core().request("object/patch/append-data", p.String()). + err := api.core().Request("object/patch/append-data", p.String()). FileBody(r). Exec(ctx, &out) if err != nil { @@ -211,7 +211,7 @@ func (api *ObjectAPI) AppendData(ctx context.Context, p iface.Path, r io.Reader) func (api *ObjectAPI) SetData(ctx context.Context, p iface.Path, r io.Reader) (iface.ResolvedPath, error) { var out objectOut - err := api.core().request("object/patch/set-data", p.String()). + err := api.core().Request("object/patch/set-data", p.String()). FileBody(r). Exec(ctx, &out) if err != nil { @@ -237,7 +237,7 @@ func (api *ObjectAPI) Diff(ctx context.Context, a iface.Path, b iface.Path) ([]i var out struct { Changes []change } - if err := api.core().request("object/diff", a.String(), b.String()).Exec(ctx, &out); err != nil { + if err := api.core().Request("object/diff", a.String(), b.String()).Exec(ctx, &out); err != nil { return nil, err } res := make([]iface.ObjectChange, len(out.Changes)) diff --git a/client/httpapi/path.go b/client/httpapi/path.go index 8c819121a..639ca2f8e 100644 --- a/client/httpapi/path.go +++ b/client/httpapi/path.go @@ -24,7 +24,7 @@ func (api *HttpApi) ResolvePath(ctx context.Context, path iface.Path) (iface.Res } } - if err := api.request("dag/resolve", path.String()).Exec(ctx, &out); err != nil { + if err := api.Request("dag/resolve", path.String()).Exec(ctx, &out); err != nil { return nil, err } diff --git a/client/httpapi/pin.go b/client/httpapi/pin.go index 0111d626a..f779640f1 100644 --- a/client/httpapi/pin.go +++ b/client/httpapi/pin.go @@ -39,7 +39,7 @@ func (api *PinAPI) Add(ctx context.Context, p iface.Path, opts ...caopts.PinAddO return err } - return api.core().request("pin/add", p.String()). + return api.core().Request("pin/add", p.String()). Option("recursive", options.Recursive).Exec(ctx, nil) } @@ -50,7 +50,7 @@ func (api *PinAPI) Ls(ctx context.Context, opts ...caopts.PinLsOption) ([]iface. } var out pinRefKeyList - err = api.core().request("pin/ls"). + err = api.core().Request("pin/ls"). Option("type", options.Type).Exec(ctx, &out) if err != nil { return nil, err @@ -74,7 +74,7 @@ func (api *PinAPI) Rm(ctx context.Context, p iface.Path, opts ...caopts.PinRmOpt return err } - return api.core().request("pin/rm", p.String()). + return api.core().Request("pin/rm", p.String()). Option("recursive", options.Recursive). Exec(ctx, nil) } @@ -85,7 +85,7 @@ func (api *PinAPI) Update(ctx context.Context, from iface.Path, to iface.Path, o return err } - return api.core().request("pin/update"). + return api.core().Request("pin/update"). Option("unpin", options.Unpin).Exec(ctx, nil) } @@ -116,7 +116,7 @@ func (n *badNode) Err() error { } func (api *PinAPI) Verify(ctx context.Context) (<-chan iface.PinStatus, error) { - resp, err := api.core().request("pin/verify").Option("verbose", true).Send(ctx) + resp, err := api.core().Request("pin/verify").Option("verbose", true).Send(ctx) if err != nil { return nil, err } diff --git a/client/httpapi/pubsub.go b/client/httpapi/pubsub.go index 2ac04b53c..380b933dc 100644 --- a/client/httpapi/pubsub.go +++ b/client/httpapi/pubsub.go @@ -18,7 +18,7 @@ func (api *PubsubAPI) Ls(ctx context.Context) ([]string, error) { Strings []string } - if err := api.core().request("pubsub/ls").Exec(ctx, &out); err != nil { + if err := api.core().Request("pubsub/ls").Exec(ctx, &out); err != nil { return nil, err } @@ -35,7 +35,7 @@ func (api *PubsubAPI) Peers(ctx context.Context, opts ...caopts.PubSubPeersOptio Strings []string } - if err := api.core().request("pubsub/peers", options.Topic).Exec(ctx, &out); err != nil { + if err := api.core().Request("pubsub/peers", options.Topic).Exec(ctx, &out); err != nil { return nil, err } @@ -51,7 +51,7 @@ func (api *PubsubAPI) Peers(ctx context.Context, opts ...caopts.PubSubPeersOptio } func (api *PubsubAPI) Publish(ctx context.Context, topic string, message []byte) error { - return api.core().request("pubsub/pub", topic). + return api.core().Request("pubsub/pub", topic). FileBody(bytes.NewReader(message)). Exec(ctx, nil) } @@ -112,7 +112,7 @@ func (api *PubsubAPI) Subscribe(ctx context.Context, topic string, opts ...caopt return nil, err } - resp, err := api.core().request("pubsub/sub", topic). + resp, err := api.core().Request("pubsub/sub", topic). Option("discover", options.Discover).Send(ctx) if err != nil { diff --git a/client/httpapi/swarm.go b/client/httpapi/swarm.go index 0814debee..0e47df2ab 100644 --- a/client/httpapi/swarm.go +++ b/client/httpapi/swarm.go @@ -25,11 +25,11 @@ func (api *SwarmAPI) Connect(ctx context.Context, pi peerstore.PeerInfo) error { saddrs[i] = addr.Encapsulate(pidma).String() } - return api.core().request("swarm/connect", saddrs...).Exec(ctx, nil) + return api.core().Request("swarm/connect", saddrs...).Exec(ctx, nil) } func (api *SwarmAPI) Disconnect(ctx context.Context, addr multiaddr.Multiaddr) error { - return api.core().request("swarm/disconnect", addr.String()).Exec(ctx, nil) + return api.core().Request("swarm/disconnect", addr.String()).Exec(ctx, nil) } type connInfo struct { @@ -75,7 +75,7 @@ func (api *SwarmAPI) Peers(ctx context.Context) ([]iface.ConnectionInfo, error) } } - err := api.core().request("swarm/peers"). + err := api.core().Request("swarm/peers"). Option("streams", true). Option("latency", true). Exec(ctx, &resp) @@ -116,7 +116,7 @@ func (api *SwarmAPI) KnownAddrs(ctx context.Context) (map[peer.ID][]multiaddr.Mu var out struct { Addrs map[string][]string } - if err := api.core().request("swarm/addrs").Exec(ctx, &out); err != nil { + if err := api.core().Request("swarm/addrs").Exec(ctx, &out); err != nil { return nil, err } res := map[peer.ID][]multiaddr.Multiaddr{} @@ -147,7 +147,7 @@ func (api *SwarmAPI) LocalAddrs(ctx context.Context) ([]multiaddr.Multiaddr, err Strings []string } - if err := api.core().request("swarm/addrs/local").Exec(ctx, &out); err != nil { + if err := api.core().Request("swarm/addrs/local").Exec(ctx, &out); err != nil { return nil, err } @@ -167,7 +167,7 @@ func (api *SwarmAPI) ListenAddrs(ctx context.Context) ([]multiaddr.Multiaddr, er Strings []string } - if err := api.core().request("swarm/addrs/listen").Exec(ctx, &out); err != nil { + if err := api.core().Request("swarm/addrs/listen").Exec(ctx, &out); err != nil { return nil, err } diff --git a/client/httpapi/unixfs.go b/client/httpapi/unixfs.go index 4f717b129..84609194b 100644 --- a/client/httpapi/unixfs.go +++ b/client/httpapi/unixfs.go @@ -36,7 +36,7 @@ func (api *UnixfsAPI) Add(ctx context.Context, f files.Node, opts ...caopts.Unix return nil, fmt.Errorf("unknowm mhType %d", options.MhType) } - req := api.core().request("add"). + req := api.core().Request("add"). Option("hash", mht). Option("chunker", options.Chunker). Option("cid-version", options.CidVersion). @@ -139,7 +139,7 @@ func (api *UnixfsAPI) Ls(ctx context.Context, p iface.Path, opts ...caopts.Unixf return nil, err } - resp, err := api.core().request("ls", p.String()). + resp, err := api.core().Request("ls", p.String()). Option("resolve-type", options.ResolveChildren). Option("size", options.ResolveChildren). Option("stream", true). From 1a2e8ce6d76f9517240ca53339937d4e07dcfe96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 25 Mar 2019 17:03:44 +0100 Subject: [PATCH 0285/1212] path: drop error from ParsePath This commit was moved from ipfs/interface-go-ipfs-core@2b9bff7523c812447641aa70c39ec0b096f5b5c4 This commit was moved from ipfs/boxo@31071e1f5e59a62d53e2c2c7e259eedff6d49f6f --- core/coreiface/path.go | 51 +++++++++++++++++++++++++++++------------- 1 file changed, 35 insertions(+), 16 deletions(-) diff --git a/core/coreiface/path.go b/core/coreiface/path.go index 4e86172ac..ede190df7 100644 --- a/core/coreiface/path.go +++ b/core/coreiface/path.go @@ -1,7 +1,9 @@ package iface import ( - "github.com/ipfs/go-cid" + "strings" + + cid "github.com/ipfs/go-cid" ipfspath "github.com/ipfs/go-path" ) @@ -23,6 +25,9 @@ type Path interface { // Namespace returns the first component of the path. // // For example path "/ipfs/QmHash", calling Namespace() will return "ipfs" + // + // Calling this method on invalid paths (IsValid() != nil) will result in + // empty string Namespace() string // Mutable returns false if the data pointed to by this path in guaranteed @@ -30,9 +35,14 @@ type Path interface { // // Note that resolved mutable path can be immutable. Mutable() bool + + // IsValid checks if this path is a valid ipfs Path, returning nil iff it is + // valid + IsValid() error } -// ResolvedPath is a path which was resolved to the last resolvable node +// ResolvedPath is a path which was resolved to the last resolvable node. +// ResolvedPaths are guaranteed to return nil from `IsValid` type ResolvedPath interface { // Cid returns the CID of the node referenced by the path. Remainder of the // path is guaranteed to be within the node. @@ -94,7 +104,7 @@ type ResolvedPath interface { // path implements coreiface.Path type path struct { - path ipfspath.Path + path string } // resolvedPath implements coreiface.resolvedPath @@ -107,14 +117,14 @@ type resolvedPath struct { // Join appends provided segments to the base path func Join(base Path, a ...string) Path { - s := ipfspath.Join(append([]string{base.String()}, a...)) - return &path{path: ipfspath.FromString(s)} + s := strings.Join(append([]string{base.String()}, a...), "/") + return &path{path: s} } // IpfsPath creates new /ipfs path from the provided CID func IpfsPath(c cid.Cid) ResolvedPath { return &resolvedPath{ - path: path{ipfspath.Path("/ipfs/" + c.String())}, + path: path{"/ipfs/" + c.String()}, cid: c, root: c, remainder: "", @@ -124,7 +134,7 @@ func IpfsPath(c cid.Cid) ResolvedPath { // IpldPath creates new /ipld path from the provided CID func IpldPath(c cid.Cid) ResolvedPath { return &resolvedPath{ - path: path{ipfspath.Path("/ipld/" + c.String())}, + path: path{"/ipld/" + c.String()}, cid: c, root: c, remainder: "", @@ -132,13 +142,12 @@ func IpldPath(c cid.Cid) ResolvedPath { } // ParsePath parses string path to a Path -func ParsePath(p string) (Path, error) { - pp, err := ipfspath.ParsePath(p) - if err != nil { - return nil, err +func ParsePath(p string) Path { + if pp, err := ipfspath.ParsePath(p); err == nil { + p = pp.String() } - return &path{path: pp}, nil + return &path{path: p} } // NewResolvedPath creates new ResolvedPath. This function performs no checks @@ -146,7 +155,7 @@ func ParsePath(p string) (Path, error) { // cause panics. Handle with care. func NewResolvedPath(ipath ipfspath.Path, c cid.Cid, root cid.Cid, remainder string) ResolvedPath { return &resolvedPath{ - path: path{ipath}, + path: path{ipath.String()}, cid: c, root: root, remainder: remainder, @@ -154,14 +163,19 @@ func NewResolvedPath(ipath ipfspath.Path, c cid.Cid, root cid.Cid, remainder str } func (p *path) String() string { - return p.path.String() + return p.path } func (p *path) Namespace() string { - if len(p.path.Segments()) < 1 { + ip, err := ipfspath.ParsePath(p.path) + if err != nil { + return "" + } + + if len(ip.Segments()) < 1 { panic("path without namespace") //this shouldn't happen under any scenario } - return p.path.Segments()[0] + return ip.Segments()[0] } func (p *path) Mutable() bool { @@ -169,6 +183,11 @@ func (p *path) Mutable() bool { return p.Namespace() == "ipns" } +func (p *path) IsValid() error { + _, err := ipfspath.ParsePath(p.path) + return err +} + func (p *resolvedPath) Cid() cid.Cid { return p.cid } From aca6f61a63b790c779744a6cca8d058ac6388973 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 25 Mar 2019 17:03:53 +0100 Subject: [PATCH 0286/1212] path: fix tests This commit was moved from ipfs/interface-go-ipfs-core@33d445a6140b26da90a07d2bf86c8827d74284b6 This commit was moved from ipfs/boxo@1497150b1f90816ac7b117fbe0b2fb6aacaa7968 --- core/coreiface/tests/block.go | 5 +---- core/coreiface/tests/dag.go | 5 +---- core/coreiface/tests/name.go | 6 +----- core/coreiface/tests/path.go | 33 +++++---------------------------- core/coreiface/tests/unixfs.go | 5 +---- 5 files changed, 9 insertions(+), 45 deletions(-) diff --git a/core/coreiface/tests/block.go b/core/coreiface/tests/block.go index d584ac98a..96319b488 100644 --- a/core/coreiface/tests/block.go +++ b/core/coreiface/tests/block.go @@ -110,10 +110,7 @@ func (tp *provider) TestBlockGet(t *testing.T) { t.Error("didn't get correct data back") } - p, err := coreiface.ParsePath("/ipfs/" + res.Path().Cid().String()) - if err != nil { - t.Fatal(err) - } + p := coreiface.ParsePath("/ipfs/" + res.Path().Cid().String()) rp, err := api.ResolvePath(ctx, p) if err != nil { diff --git a/core/coreiface/tests/dag.go b/core/coreiface/tests/dag.go index ff034beec..a17296d1d 100644 --- a/core/coreiface/tests/dag.go +++ b/core/coreiface/tests/dag.go @@ -113,10 +113,7 @@ func (tp *provider) TestDagPath(t *testing.T) { t.Fatal(err) } - p, err := coreiface.ParsePath(path.Join(nd.Cid().String(), "lnk")) - if err != nil { - t.Fatal(err) - } + p := coreiface.ParsePath(path.Join(nd.Cid().String(), "lnk")) rp, err := api.ResolvePath(ctx, p) if err != nil { diff --git a/core/coreiface/tests/name.go b/core/coreiface/tests/name.go index 1eb2dd513..c9e99a584 100644 --- a/core/coreiface/tests/name.go +++ b/core/coreiface/tests/name.go @@ -35,11 +35,7 @@ func addTestObject(ctx context.Context, api coreiface.CoreAPI) (coreiface.Path, } func appendPath(p coreiface.Path, sub string) coreiface.Path { - p, err := coreiface.ParsePath(path.Join(p.String(), sub)) - if err != nil { - panic(err) - } - return p + return coreiface.ParsePath(path.Join(p.String(), sub)) } func (tp *provider) TestPublishResolve(t *testing.T) { diff --git a/core/coreiface/tests/path.go b/core/coreiface/tests/path.go index b99e8ab9c..f5b0ee348 100644 --- a/core/coreiface/tests/path.go +++ b/core/coreiface/tests/path.go @@ -75,12 +75,7 @@ func (tp *provider) TestPathRemainder(t *testing.T) { t.Fatal(err) } - p1, err := coreiface.ParsePath(nd.String() + "/foo/bar") - if err != nil { - t.Fatal(err) - } - - rp1, err := api.ResolvePath(ctx, p1) + rp1, err := api.ResolvePath(ctx, coreiface.ParsePath(nd.String()+"/foo/bar")) if err != nil { t.Fatal(err) } @@ -111,12 +106,7 @@ func (tp *provider) TestEmptyPathRemainder(t *testing.T) { t.Fatal(err) } - p1, err := coreiface.ParsePath(nd.Cid().String()) - if err != nil { - t.Fatal(err) - } - - rp1, err := api.ResolvePath(ctx, p1) + rp1, err := api.ResolvePath(ctx, coreiface.ParsePath(nd.Cid().String())) if err != nil { t.Fatal(err) } @@ -147,12 +137,7 @@ func (tp *provider) TestInvalidPathRemainder(t *testing.T) { t.Fatal(err) } - p1, err := coreiface.ParsePath("/ipld/" + nd.Cid().String() + "/bar/baz") - if err != nil { - t.Fatal(err) - } - - _, err = api.ResolvePath(ctx, p1) + _, err = api.ResolvePath(ctx, coreiface.ParsePath("/ipld/"+nd.Cid().String()+"/bar/baz")) if err == nil || !strings.Contains(err.Error(), "no such link found") { t.Fatalf("unexpected error: %s", err) } @@ -188,12 +173,7 @@ func (tp *provider) TestPathRoot(t *testing.T) { t.Fatal(err) } - p1, err := coreiface.ParsePath("/ipld/" + nd.Cid().String() + "/foo") - if err != nil { - t.Fatal(err) - } - - rp, err := api.ResolvePath(ctx, p1) + rp, err := api.ResolvePath(ctx, coreiface.ParsePath("/ipld/"+nd.Cid().String()+"/foo")) if err != nil { t.Fatal(err) } @@ -208,10 +188,7 @@ func (tp *provider) TestPathRoot(t *testing.T) { } func (tp *provider) TestPathJoin(t *testing.T) { - p1, err := coreiface.ParsePath("/ipfs/QmYNmQKp6SuaVrpgWRsPTgCQCnpxUYGq76YEKBXuj2N4H6/bar/baz") - if err != nil { - t.Fatal(err) - } + p1 := coreiface.ParsePath("/ipfs/QmYNmQKp6SuaVrpgWRsPTgCQCnpxUYGq76YEKBXuj2N4H6/bar/baz") if coreiface.Join(p1, "foo").String() != "/ipfs/QmYNmQKp6SuaVrpgWRsPTgCQCnpxUYGq76YEKBXuj2N4H6/bar/baz/foo" { t.Error("unexpected path") diff --git a/core/coreiface/tests/unixfs.go b/core/coreiface/tests/unixfs.go index 611ea5476..15cb8abc8 100644 --- a/core/coreiface/tests/unixfs.go +++ b/core/coreiface/tests/unixfs.go @@ -592,10 +592,7 @@ func (tp *provider) TestGetEmptyFile(t *testing.T) { t.Fatal(err) } - emptyFilePath, err := coreiface.ParsePath(emptyFile) - if err != nil { - t.Fatal(err) - } + emptyFilePath := coreiface.ParsePath(emptyFile) r, err := api.Unixfs().Get(ctx, emptyFilePath) if err != nil { From 51a937fffd45edbc0543fe4a2338b6034e5ea2a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 25 Mar 2019 19:37:28 +0100 Subject: [PATCH 0287/1212] path: WIP This commit was moved from ipfs/interface-go-ipfs-core@5a836515396273412794edaaba72ef0cf3ead46d This commit was moved from ipfs/boxo@b8463e7c123e4ff15fd8fdd33a02a6414682ca9a --- core/coreiface/block.go | 11 +- core/coreiface/coreapi.go | 5 +- core/coreiface/dht.go | 7 +- core/coreiface/key.go | 5 +- core/coreiface/name.go | 11 +- core/coreiface/object.go | 29 ++--- core/coreiface/path.go | 197 -------------------------------- core/coreiface/path/path.go | 199 +++++++++++++++++++++++++++++++++ core/coreiface/pin.go | 13 ++- core/coreiface/tests/block.go | 3 +- core/coreiface/tests/dag.go | 5 +- core/coreiface/tests/name.go | 12 +- core/coreiface/tests/path.go | 14 +-- core/coreiface/tests/pin.go | 13 ++- core/coreiface/tests/unixfs.go | 19 ++-- core/coreiface/unixfs.go | 17 +-- 16 files changed, 287 insertions(+), 273 deletions(-) create mode 100644 core/coreiface/path/path.go diff --git a/core/coreiface/block.go b/core/coreiface/block.go index 587ad339f..9f0ad9cbb 100644 --- a/core/coreiface/block.go +++ b/core/coreiface/block.go @@ -2,9 +2,10 @@ package iface import ( "context" + path "github.com/ipfs/interface-go-ipfs-core/path" "io" - options "github.com/ipfs/interface-go-ipfs-core/options" + "github.com/ipfs/interface-go-ipfs-core/options" ) // BlockStat contains information about a block @@ -13,7 +14,7 @@ type BlockStat interface { Size() int // Path returns path to the block - Path() ResolvedPath + Path() path.ResolvedPath } // BlockAPI specifies the interface to the block layer @@ -22,15 +23,15 @@ type BlockAPI interface { Put(context.Context, io.Reader, ...options.BlockPutOption) (BlockStat, error) // Get attempts to resolve the path and return a reader for data in the block - Get(context.Context, Path) (io.Reader, error) + Get(context.Context, path.Path) (io.Reader, error) // Rm removes the block specified by the path from local blockstore. // By default an error will be returned if the block can't be found locally. // // NOTE: If the specified block is pinned it won't be removed and no error // will be returned - Rm(context.Context, Path, ...options.BlockRmOption) error + Rm(context.Context, path.Path, ...options.BlockRmOption) error // Stat returns information on - Stat(context.Context, Path) (BlockStat, error) + Stat(context.Context, path.Path) (BlockStat, error) } diff --git a/core/coreiface/coreapi.go b/core/coreiface/coreapi.go index f3433c089..bef3ce01f 100644 --- a/core/coreiface/coreapi.go +++ b/core/coreiface/coreapi.go @@ -4,6 +4,7 @@ package iface import ( "context" + path "github.com/ipfs/interface-go-ipfs-core/path" "github.com/ipfs/interface-go-ipfs-core/options" @@ -43,11 +44,11 @@ type CoreAPI interface { PubSub() PubSubAPI // ResolvePath resolves the path using Unixfs resolver - ResolvePath(context.Context, Path) (ResolvedPath, error) + ResolvePath(context.Context, path.Path) (path.ResolvedPath, error) // ResolveNode resolves the path (if not resolved already) using Unixfs // resolver, gets and returns the resolved Node - ResolveNode(context.Context, Path) (ipld.Node, error) + ResolveNode(context.Context, path.Path) (ipld.Node, error) // WithOptions creates new instance of CoreAPI based on this instance with // a set of options applied diff --git a/core/coreiface/dht.go b/core/coreiface/dht.go index d1ae05125..0cb7893ef 100644 --- a/core/coreiface/dht.go +++ b/core/coreiface/dht.go @@ -2,10 +2,11 @@ package iface import ( "context" + path "github.com/ipfs/interface-go-ipfs-core/path" "github.com/ipfs/interface-go-ipfs-core/options" - peer "github.com/libp2p/go-libp2p-peer" + "github.com/libp2p/go-libp2p-peer" pstore "github.com/libp2p/go-libp2p-peerstore" ) @@ -19,8 +20,8 @@ type DhtAPI interface { // FindProviders finds peers in the DHT who can provide a specific value // given a key. - FindProviders(context.Context, Path, ...options.DhtFindProvidersOption) (<-chan pstore.PeerInfo, error) + FindProviders(context.Context, path.Path, ...options.DhtFindProvidersOption) (<-chan pstore.PeerInfo, error) // Provide announces to the network that you are providing given values - Provide(context.Context, Path, ...options.DhtProvideOption) error + Provide(context.Context, path.Path, ...options.DhtProvideOption) error } diff --git a/core/coreiface/key.go b/core/coreiface/key.go index 78c29d268..e7fb3f442 100644 --- a/core/coreiface/key.go +++ b/core/coreiface/key.go @@ -2,8 +2,9 @@ package iface import ( "context" + path "github.com/ipfs/interface-go-ipfs-core/path" - options "github.com/ipfs/interface-go-ipfs-core/options" + "github.com/ipfs/interface-go-ipfs-core/options" "github.com/libp2p/go-libp2p-peer" ) @@ -14,7 +15,7 @@ type Key interface { Name() string // Path returns key path - Path() Path + Path() path.Path // ID returns key PeerID ID() peer.ID diff --git a/core/coreiface/name.go b/core/coreiface/name.go index 51b005b7e..3dc9f6878 100644 --- a/core/coreiface/name.go +++ b/core/coreiface/name.go @@ -3,8 +3,9 @@ package iface import ( "context" "errors" + path "github.com/ipfs/interface-go-ipfs-core/path" - options "github.com/ipfs/interface-go-ipfs-core/options" + "github.com/ipfs/interface-go-ipfs-core/options" ) var ErrResolveFailed = errors.New("could not resolve name") @@ -14,11 +15,11 @@ type IpnsEntry interface { // Name returns IpnsEntry name Name() string // Value returns IpnsEntry value - Value() Path + Value() path.Path } type IpnsResult struct { - Path + path.Path Err error } @@ -32,10 +33,10 @@ type IpnsResult struct { // You can use .Key API to list and generate more names and their respective keys. type NameAPI interface { // Publish announces new IPNS name - Publish(ctx context.Context, path Path, opts ...options.NamePublishOption) (IpnsEntry, error) + Publish(ctx context.Context, path path.Path, opts ...options.NamePublishOption) (IpnsEntry, error) // Resolve attempts to resolve the newest version of the specified name - Resolve(ctx context.Context, name string, opts ...options.NameResolveOption) (Path, error) + Resolve(ctx context.Context, name string, opts ...options.NameResolveOption) (path.Path, error) // Search is a version of Resolve which outputs paths as they are discovered, // reducing the time to first entry diff --git a/core/coreiface/object.go b/core/coreiface/object.go index 4f9652fb1..3e4b7e087 100644 --- a/core/coreiface/object.go +++ b/core/coreiface/object.go @@ -2,11 +2,12 @@ package iface import ( "context" + path "github.com/ipfs/interface-go-ipfs-core/path" "io" - options "github.com/ipfs/interface-go-ipfs-core/options" + "github.com/ipfs/interface-go-ipfs-core/options" - cid "github.com/ipfs/go-cid" + "github.com/ipfs/go-cid" ipld "github.com/ipfs/go-ipld-format" ) @@ -58,11 +59,11 @@ type ObjectChange struct { // Before holds the link path before the change. Note that when a link is // added, this will be nil. - Before ResolvedPath + Before path.ResolvedPath // After holds the link path after the change. Note that when a link is // removed, this will be nil. - After ResolvedPath + After path.ResolvedPath } // ObjectAPI specifies the interface to MerkleDAG and contains useful utilities @@ -72,35 +73,35 @@ type ObjectAPI interface { New(context.Context, ...options.ObjectNewOption) (ipld.Node, error) // Put imports the data into merkledag - Put(context.Context, io.Reader, ...options.ObjectPutOption) (ResolvedPath, error) + Put(context.Context, io.Reader, ...options.ObjectPutOption) (path.ResolvedPath, error) // Get returns the node for the path - Get(context.Context, Path) (ipld.Node, error) + Get(context.Context, path.Path) (ipld.Node, error) // Data returns reader for data of the node - Data(context.Context, Path) (io.Reader, error) + Data(context.Context, path.Path) (io.Reader, error) // Links returns lint or links the node contains - Links(context.Context, Path) ([]*ipld.Link, error) + Links(context.Context, path.Path) ([]*ipld.Link, error) // Stat returns information about the node - Stat(context.Context, Path) (*ObjectStat, error) + Stat(context.Context, path.Path) (*ObjectStat, error) // AddLink adds a link under the specified path. child path can point to a // subdirectory within the patent which must be present (can be overridden // with WithCreate option). - AddLink(ctx context.Context, base Path, name string, child Path, opts ...options.ObjectAddLinkOption) (ResolvedPath, error) + AddLink(ctx context.Context, base path.Path, name string, child path.Path, opts ...options.ObjectAddLinkOption) (path.ResolvedPath, error) // RmLink removes a link from the node - RmLink(ctx context.Context, base Path, link string) (ResolvedPath, error) + RmLink(ctx context.Context, base path.Path, link string) (path.ResolvedPath, error) // AppendData appends data to the node - AppendData(context.Context, Path, io.Reader) (ResolvedPath, error) + AppendData(context.Context, path.Path, io.Reader) (path.ResolvedPath, error) // SetData sets the data contained in the node - SetData(context.Context, Path, io.Reader) (ResolvedPath, error) + SetData(context.Context, path.Path, io.Reader) (path.ResolvedPath, error) // Diff returns a set of changes needed to transform the first object into the // second. - Diff(context.Context, Path, Path) ([]ObjectChange, error) + Diff(context.Context, path.Path, path.Path) ([]ObjectChange, error) } diff --git a/core/coreiface/path.go b/core/coreiface/path.go index ede190df7..198651129 100644 --- a/core/coreiface/path.go +++ b/core/coreiface/path.go @@ -1,201 +1,4 @@ package iface -import ( - "strings" - - cid "github.com/ipfs/go-cid" - ipfspath "github.com/ipfs/go-path" -) - //TODO: merge with ipfspath so we don't depend on it -// Path is a generic wrapper for paths used in the API. A path can be resolved -// to a CID using one of Resolve functions in the API. -// -// Paths must be prefixed with a valid prefix: -// -// * /ipfs - Immutable unixfs path (files) -// * /ipld - Immutable ipld path (data) -// * /ipns - Mutable names. Usually resolves to one of the immutable paths -//TODO: /local (MFS) -type Path interface { - // String returns the path as a string. - String() string - - // Namespace returns the first component of the path. - // - // For example path "/ipfs/QmHash", calling Namespace() will return "ipfs" - // - // Calling this method on invalid paths (IsValid() != nil) will result in - // empty string - Namespace() string - - // Mutable returns false if the data pointed to by this path in guaranteed - // to not change. - // - // Note that resolved mutable path can be immutable. - Mutable() bool - - // IsValid checks if this path is a valid ipfs Path, returning nil iff it is - // valid - IsValid() error -} - -// ResolvedPath is a path which was resolved to the last resolvable node. -// ResolvedPaths are guaranteed to return nil from `IsValid` -type ResolvedPath interface { - // Cid returns the CID of the node referenced by the path. Remainder of the - // path is guaranteed to be within the node. - // - // Examples: - // If you have 3 linked objects: QmRoot -> A -> B: - // - // cidB := {"foo": {"bar": 42 }} - // cidA := {"B": {"/": cidB }} - // cidRoot := {"A": {"/": cidA }} - // - // And resolve paths: - // - // * "/ipfs/${cidRoot}" - // * Calling Cid() will return `cidRoot` - // * Calling Root() will return `cidRoot` - // * Calling Remainder() will return `` - // - // * "/ipfs/${cidRoot}/A" - // * Calling Cid() will return `cidA` - // * Calling Root() will return `cidRoot` - // * Calling Remainder() will return `` - // - // * "/ipfs/${cidRoot}/A/B/foo" - // * Calling Cid() will return `cidB` - // * Calling Root() will return `cidRoot` - // * Calling Remainder() will return `foo` - // - // * "/ipfs/${cidRoot}/A/B/foo/bar" - // * Calling Cid() will return `cidB` - // * Calling Root() will return `cidRoot` - // * Calling Remainder() will return `foo/bar` - Cid() cid.Cid - - // Root returns the CID of the root object of the path - // - // Example: - // If you have 3 linked objects: QmRoot -> A -> B, and resolve path - // "/ipfs/QmRoot/A/B", the Root method will return the CID of object QmRoot - // - // For more examples see the documentation of Cid() method - Root() cid.Cid - - // Remainder returns unresolved part of the path - // - // Example: - // If you have 2 linked objects: QmRoot -> A, where A is a CBOR node - // containing the following data: - // - // {"foo": {"bar": 42 }} - // - // When resolving "/ipld/QmRoot/A/foo/bar", Remainder will return "foo/bar" - // - // For more examples see the documentation of Cid() method - Remainder() string - - Path -} - -// path implements coreiface.Path -type path struct { - path string -} - -// resolvedPath implements coreiface.resolvedPath -type resolvedPath struct { - path - cid cid.Cid - root cid.Cid - remainder string -} - -// Join appends provided segments to the base path -func Join(base Path, a ...string) Path { - s := strings.Join(append([]string{base.String()}, a...), "/") - return &path{path: s} -} - -// IpfsPath creates new /ipfs path from the provided CID -func IpfsPath(c cid.Cid) ResolvedPath { - return &resolvedPath{ - path: path{"/ipfs/" + c.String()}, - cid: c, - root: c, - remainder: "", - } -} - -// IpldPath creates new /ipld path from the provided CID -func IpldPath(c cid.Cid) ResolvedPath { - return &resolvedPath{ - path: path{"/ipld/" + c.String()}, - cid: c, - root: c, - remainder: "", - } -} - -// ParsePath parses string path to a Path -func ParsePath(p string) Path { - if pp, err := ipfspath.ParsePath(p); err == nil { - p = pp.String() - } - - return &path{path: p} -} - -// NewResolvedPath creates new ResolvedPath. This function performs no checks -// and is intended to be used by resolver implementations. Incorrect inputs may -// cause panics. Handle with care. -func NewResolvedPath(ipath ipfspath.Path, c cid.Cid, root cid.Cid, remainder string) ResolvedPath { - return &resolvedPath{ - path: path{ipath.String()}, - cid: c, - root: root, - remainder: remainder, - } -} - -func (p *path) String() string { - return p.path -} - -func (p *path) Namespace() string { - ip, err := ipfspath.ParsePath(p.path) - if err != nil { - return "" - } - - if len(ip.Segments()) < 1 { - panic("path without namespace") //this shouldn't happen under any scenario - } - return ip.Segments()[0] -} - -func (p *path) Mutable() bool { - //TODO: MFS: check for /local - return p.Namespace() == "ipns" -} - -func (p *path) IsValid() error { - _, err := ipfspath.ParsePath(p.path) - return err -} - -func (p *resolvedPath) Cid() cid.Cid { - return p.cid -} - -func (p *resolvedPath) Root() cid.Cid { - return p.root -} - -func (p *resolvedPath) Remainder() string { - return p.remainder -} diff --git a/core/coreiface/path/path.go b/core/coreiface/path/path.go new file mode 100644 index 000000000..414d454fa --- /dev/null +++ b/core/coreiface/path/path.go @@ -0,0 +1,199 @@ +package path + +import ( + "strings" + + cid "github.com/ipfs/go-cid" + ipfspath "github.com/ipfs/go-path" +) + +// Path is a generic wrapper for paths used in the API. A path can be resolved +// to a CID using one of Resolve functions in the API. +// +// Paths must be prefixed with a valid prefix: +// +// * /ipfs - Immutable unixfs path (files) +// * /ipld - Immutable ipld path (data) +// * /ipns - Mutable names. Usually resolves to one of the immutable paths +//TODO: /local (MFS) +type Path interface { + // String returns the path as a string. + String() string + + // Namespace returns the first component of the path. + // + // For example path "/ipfs/QmHash", calling Namespace() will return "ipfs" + // + // Calling this method on invalid paths (IsValid() != nil) will result in + // empty string + Namespace() string + + // Mutable returns false if the data pointed to by this path in guaranteed + // to not change. + // + // Note that resolved mutable path can be immutable. + Mutable() bool + + // IsValid checks if this path is a valid ipfs Path, returning nil iff it is + // valid + IsValid() error +} + +// ResolvedPath is a path which was resolved to the last resolvable node. +// ResolvedPaths are guaranteed to return nil from `IsValid` +type ResolvedPath interface { + // Cid returns the CID of the node referenced by the path. Remainder of the + // path is guaranteed to be within the node. + // + // Examples: + // If you have 3 linked objects: QmRoot -> A -> B: + // + // cidB := {"foo": {"bar": 42 }} + // cidA := {"B": {"/": cidB }} + // cidRoot := {"A": {"/": cidA }} + // + // And resolve paths: + // + // * "/ipfs/${cidRoot}" + // * Calling Cid() will return `cidRoot` + // * Calling Root() will return `cidRoot` + // * Calling Remainder() will return `` + // + // * "/ipfs/${cidRoot}/A" + // * Calling Cid() will return `cidA` + // * Calling Root() will return `cidRoot` + // * Calling Remainder() will return `` + // + // * "/ipfs/${cidRoot}/A/B/foo" + // * Calling Cid() will return `cidB` + // * Calling Root() will return `cidRoot` + // * Calling Remainder() will return `foo` + // + // * "/ipfs/${cidRoot}/A/B/foo/bar" + // * Calling Cid() will return `cidB` + // * Calling Root() will return `cidRoot` + // * Calling Remainder() will return `foo/bar` + Cid() cid.Cid + + // Root returns the CID of the root object of the path + // + // Example: + // If you have 3 linked objects: QmRoot -> A -> B, and resolve path + // "/ipfs/QmRoot/A/B", the Root method will return the CID of object QmRoot + // + // For more examples see the documentation of Cid() method + Root() cid.Cid + + // Remainder returns unresolved part of the path + // + // Example: + // If you have 2 linked objects: QmRoot -> A, where A is a CBOR node + // containing the following data: + // + // {"foo": {"bar": 42 }} + // + // When resolving "/ipld/QmRoot/A/foo/bar", Remainder will return "foo/bar" + // + // For more examples see the documentation of Cid() method + Remainder() string + + Path +} + +// path implements coreiface.Path +type path struct { + path string +} + +// resolvedPath implements coreiface.resolvedPath +type resolvedPath struct { + path + cid cid.Cid + root cid.Cid + remainder string +} + +// Join appends provided segments to the base path +func Join(base Path, a ...string) Path { + s := strings.Join(append([]string{base.String()}, a...), "/") + return &path{path: s} +} + +// IpfsPath creates new /ipfs path from the provided CID +func IpfsPath(c cid.Cid) ResolvedPath { + return &resolvedPath{ + path: path{"/ipfs/" + c.String()}, + cid: c, + root: c, + remainder: "", + } +} + +// IpldPath creates new /ipld path from the provided CID +func IpldPath(c cid.Cid) ResolvedPath { + return &resolvedPath{ + path: path{"/ipld/" + c.String()}, + cid: c, + root: c, + remainder: "", + } +} + +// ParsePath parses string path to a Path +func ParsePath(p string) Path { + if pp, err := ipfspath.ParsePath(p); err == nil { + p = pp.String() + } + + return &path{path: p} +} + +// NewResolvedPath creates new ResolvedPath. This function performs no checks +// and is intended to be used by resolver implementations. Incorrect inputs may +// cause panics. Handle with care. +func NewResolvedPath(ipath ipfspath.Path, c cid.Cid, root cid.Cid, remainder string) ResolvedPath { + return &resolvedPath{ + path: path{ipath.String()}, + cid: c, + root: root, + remainder: remainder, + } +} + +func (p *path) String() string { + return p.path +} + +func (p *path) Namespace() string { + ip, err := ipfspath.ParsePath(p.path) + if err != nil { + return "" + } + + if len(ip.Segments()) < 1 { + panic("path without namespace") // this shouldn't happen under any scenario + } + return ip.Segments()[0] +} + +func (p *path) Mutable() bool { + // TODO: MFS: check for /local + return p.Namespace() == "ipns" +} + +func (p *path) IsValid() error { + _, err := ipfspath.ParsePath(p.path) + return err +} + +func (p *resolvedPath) Cid() cid.Cid { + return p.cid +} + +func (p *resolvedPath) Root() cid.Cid { + return p.root +} + +func (p *resolvedPath) Remainder() string { + return p.remainder +} diff --git a/core/coreiface/pin.go b/core/coreiface/pin.go index 6a7dab413..736b2d68b 100644 --- a/core/coreiface/pin.go +++ b/core/coreiface/pin.go @@ -2,14 +2,15 @@ package iface import ( "context" + path "github.com/ipfs/interface-go-ipfs-core/path" - options "github.com/ipfs/interface-go-ipfs-core/options" + "github.com/ipfs/interface-go-ipfs-core/options" ) // Pin holds information about pinned resource type Pin interface { // Path to the pinned object - Path() ResolvedPath + Path() path.ResolvedPath // Type of the pin Type() string @@ -27,7 +28,7 @@ type PinStatus interface { // BadPinNode is a node that has been marked as bad by Pin.Verify type BadPinNode interface { // Path is the path of the node - Path() ResolvedPath + Path() path.ResolvedPath // Err is the reason why the node has been marked as bad Err() error @@ -37,17 +38,17 @@ type BadPinNode interface { type PinAPI interface { // Add creates new pin, be default recursive - pinning the whole referenced // tree - Add(context.Context, Path, ...options.PinAddOption) error + Add(context.Context, path.Path, ...options.PinAddOption) error // Ls returns list of pinned objects on this node Ls(context.Context, ...options.PinLsOption) ([]Pin, error) // Rm removes pin for object specified by the path - Rm(context.Context, Path, ...options.PinRmOption) error + Rm(context.Context, path.Path, ...options.PinRmOption) error // Update changes one pin to another, skipping checks for matching paths in // the old tree - Update(ctx context.Context, from Path, to Path, opts ...options.PinUpdateOption) error + Update(ctx context.Context, from path.Path, to path.Path, opts ...options.PinUpdateOption) error // Verify verifies the integrity of pinned objects Verify(context.Context) (<-chan PinStatus, error) diff --git a/core/coreiface/tests/block.go b/core/coreiface/tests/block.go index 96319b488..59b49d567 100644 --- a/core/coreiface/tests/block.go +++ b/core/coreiface/tests/block.go @@ -2,6 +2,7 @@ package tests import ( "context" + "github.com/ipfs/interface-go-ipfs-core/path" "io/ioutil" "strings" "testing" @@ -110,7 +111,7 @@ func (tp *provider) TestBlockGet(t *testing.T) { t.Error("didn't get correct data back") } - p := coreiface.ParsePath("/ipfs/" + res.Path().Cid().String()) + p := path.ParsePath("/ipfs/" + res.Path().Cid().String()) rp, err := api.ResolvePath(ctx, p) if err != nil { diff --git a/core/coreiface/tests/dag.go b/core/coreiface/tests/dag.go index a17296d1d..0abcee32f 100644 --- a/core/coreiface/tests/dag.go +++ b/core/coreiface/tests/dag.go @@ -2,8 +2,9 @@ package tests import ( "context" + path "github.com/ipfs/interface-go-ipfs-core/path" "math" - "path" + gopath "path" "strings" "testing" @@ -113,7 +114,7 @@ func (tp *provider) TestDagPath(t *testing.T) { t.Fatal(err) } - p := coreiface.ParsePath(path.Join(nd.Cid().String(), "lnk")) + p := path.ParsePath(gopath.Join(nd.Cid().String(), "lnk")) rp, err := api.ResolvePath(ctx, p) if err != nil { diff --git a/core/coreiface/tests/name.go b/core/coreiface/tests/name.go index c9e99a584..98ae6853e 100644 --- a/core/coreiface/tests/name.go +++ b/core/coreiface/tests/name.go @@ -2,9 +2,10 @@ package tests import ( "context" + path "github.com/ipfs/interface-go-ipfs-core/path" "io" "math/rand" - "path" + gopath "path" "testing" "time" @@ -30,18 +31,18 @@ func (tp *provider) TestName(t *testing.T) { var rnd = rand.New(rand.NewSource(0x62796532303137)) -func addTestObject(ctx context.Context, api coreiface.CoreAPI) (coreiface.Path, error) { +func addTestObject(ctx context.Context, api coreiface.CoreAPI) (path.Path, error) { return api.Unixfs().Add(ctx, files.NewReaderFile(&io.LimitedReader{R: rnd, N: 4092})) } -func appendPath(p coreiface.Path, sub string) coreiface.Path { - return coreiface.ParsePath(path.Join(p.String(), sub)) +func appendPath(p path.Path, sub string) path.Path { + return path.ParsePath(gopath.Join(p.String(), sub)) } func (tp *provider) TestPublishResolve(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - init := func() (coreiface.CoreAPI, coreiface.Path) { + init := func() (coreiface.CoreAPI, path.Path) { apis, err := tp.MakeAPISwarm(ctx, true, 5) if err != nil { t.Fatal(err) @@ -56,7 +57,6 @@ func (tp *provider) TestPublishResolve(t *testing.T) { } return api, p } - run := func(t *testing.T, ropts []opt.NameResolveOption) { t.Run("basic", func(t *testing.T) { api, p := init() diff --git a/core/coreiface/tests/path.go b/core/coreiface/tests/path.go index f5b0ee348..685f46998 100644 --- a/core/coreiface/tests/path.go +++ b/core/coreiface/tests/path.go @@ -2,11 +2,11 @@ package tests import ( "context" + "github.com/ipfs/interface-go-ipfs-core/path" "math" "strings" "testing" - coreiface "github.com/ipfs/interface-go-ipfs-core" "github.com/ipfs/interface-go-ipfs-core/options" ipldcbor "github.com/ipfs/go-ipld-cbor" @@ -75,7 +75,7 @@ func (tp *provider) TestPathRemainder(t *testing.T) { t.Fatal(err) } - rp1, err := api.ResolvePath(ctx, coreiface.ParsePath(nd.String()+"/foo/bar")) + rp1, err := api.ResolvePath(ctx, path.ParsePath(nd.String()+"/foo/bar")) if err != nil { t.Fatal(err) } @@ -106,7 +106,7 @@ func (tp *provider) TestEmptyPathRemainder(t *testing.T) { t.Fatal(err) } - rp1, err := api.ResolvePath(ctx, coreiface.ParsePath(nd.Cid().String())) + rp1, err := api.ResolvePath(ctx, path.ParsePath(nd.Cid().String())) if err != nil { t.Fatal(err) } @@ -137,7 +137,7 @@ func (tp *provider) TestInvalidPathRemainder(t *testing.T) { t.Fatal(err) } - _, err = api.ResolvePath(ctx, coreiface.ParsePath("/ipld/"+nd.Cid().String()+"/bar/baz")) + _, err = api.ResolvePath(ctx, path.ParsePath("/ipld/"+nd.Cid().String()+"/bar/baz")) if err == nil || !strings.Contains(err.Error(), "no such link found") { t.Fatalf("unexpected error: %s", err) } @@ -173,7 +173,7 @@ func (tp *provider) TestPathRoot(t *testing.T) { t.Fatal(err) } - rp, err := api.ResolvePath(ctx, coreiface.ParsePath("/ipld/"+nd.Cid().String()+"/foo")) + rp, err := api.ResolvePath(ctx, path.ParsePath("/ipld/"+nd.Cid().String()+"/foo")) if err != nil { t.Fatal(err) } @@ -188,9 +188,9 @@ func (tp *provider) TestPathRoot(t *testing.T) { } func (tp *provider) TestPathJoin(t *testing.T) { - p1 := coreiface.ParsePath("/ipfs/QmYNmQKp6SuaVrpgWRsPTgCQCnpxUYGq76YEKBXuj2N4H6/bar/baz") + p1 := path.ParsePath("/ipfs/QmYNmQKp6SuaVrpgWRsPTgCQCnpxUYGq76YEKBXuj2N4H6/bar/baz") - if coreiface.Join(p1, "foo").String() != "/ipfs/QmYNmQKp6SuaVrpgWRsPTgCQCnpxUYGq76YEKBXuj2N4H6/bar/baz/foo" { + if path.Join(p1, "foo").String() != "/ipfs/QmYNmQKp6SuaVrpgWRsPTgCQCnpxUYGq76YEKBXuj2N4H6/bar/baz/foo" { t.Error("unexpected path") } } diff --git a/core/coreiface/tests/pin.go b/core/coreiface/tests/pin.go index ff6f98e35..344db65e2 100644 --- a/core/coreiface/tests/pin.go +++ b/core/coreiface/tests/pin.go @@ -2,6 +2,7 @@ package tests import ( "context" + "github.com/ipfs/interface-go-ipfs-core/path" "math" "strings" "testing" @@ -127,12 +128,12 @@ func (tp *provider) TestPinRecursive(t *testing.T) { t.Fatal(err) } - err = api.Pin().Add(ctx, iface.IpldPath(nd2.Cid())) + err = api.Pin().Add(ctx, path.IpldPath(nd2.Cid())) if err != nil { t.Fatal(err) } - err = api.Pin().Add(ctx, iface.IpldPath(nd3.Cid()), opt.Pin.Recursive(false)) + err = api.Pin().Add(ctx, path.IpldPath(nd3.Cid()), opt.Pin.Recursive(false)) if err != nil { t.Fatal(err) } @@ -155,8 +156,8 @@ func (tp *provider) TestPinRecursive(t *testing.T) { t.Errorf("unexpected pin list len: %d", len(list)) } - if list[0].Path().String() != iface.IpldPath(nd3.Cid()).String() { - t.Errorf("unexpected path, %s != %s", list[0].Path().String(), iface.IpfsPath(nd2.Cid()).String()) + if list[0].Path().String() != path.IpldPath(nd3.Cid()).String() { + t.Errorf("unexpected path, %s != %s", list[0].Path().String(), path.IpfsPath(nd2.Cid()).String()) } list, err = api.Pin().Ls(ctx, opt.Pin.Type.Recursive()) @@ -168,8 +169,8 @@ func (tp *provider) TestPinRecursive(t *testing.T) { t.Errorf("unexpected pin list len: %d", len(list)) } - if list[0].Path().String() != iface.IpldPath(nd2.Cid()).String() { - t.Errorf("unexpected path, %s != %s", list[0].Path().String(), iface.IpldPath(nd3.Cid()).String()) + if list[0].Path().String() != path.IpldPath(nd2.Cid()).String() { + t.Errorf("unexpected path, %s != %s", list[0].Path().String(), path.IpldPath(nd3.Cid()).String()) } list, err = api.Pin().Ls(ctx, opt.Pin.Type.Indirect()) diff --git a/core/coreiface/tests/unixfs.go b/core/coreiface/tests/unixfs.go index 15cb8abc8..d2d9f85b8 100644 --- a/core/coreiface/tests/unixfs.go +++ b/core/coreiface/tests/unixfs.go @@ -5,6 +5,7 @@ import ( "context" "encoding/hex" "fmt" + "github.com/ipfs/interface-go-ipfs-core/path" "io" "io/ioutil" "math" @@ -101,12 +102,12 @@ func (tp *provider) TestAdd(t *testing.T) { t.Fatal(err) } - p := func(h string) coreiface.ResolvedPath { + p := func(h string) path.ResolvedPath { c, err := cid.Parse(h) if err != nil { t.Fatal(err) } - return coreiface.IpfsPath(c) + return path.IpfsPath(c) } rf, err := ioutil.TempFile(os.TempDir(), "unixfs-add-real") @@ -592,7 +593,7 @@ func (tp *provider) TestGetEmptyFile(t *testing.T) { t.Fatal(err) } - emptyFilePath := coreiface.ParsePath(emptyFile) + emptyFilePath := path.ParsePath(emptyFile) r, err := api.Unixfs().Get(ctx, emptyFilePath) if err != nil { @@ -621,18 +622,18 @@ func (tp *provider) TestGetDir(t *testing.T) { if err != nil { t.Fatal(err) } - p := coreiface.IpfsPath(edir.Cid()) + p := path.IpfsPath(edir.Cid()) emptyDir, err := api.Object().New(ctx, options.Object.Type("unixfs-dir")) if err != nil { t.Fatal(err) } - if p.String() != coreiface.IpfsPath(emptyDir.Cid()).String() { + if p.String() != path.IpfsPath(emptyDir.Cid()).String() { t.Fatalf("expected path %s, got: %s", emptyDir.Cid(), p.String()) } - r, err := api.Unixfs().Get(ctx, coreiface.IpfsPath(emptyDir.Cid())) + r, err := api.Unixfs().Get(ctx, path.IpfsPath(emptyDir.Cid())) if err != nil { t.Fatal(err) } @@ -656,7 +657,7 @@ func (tp *provider) TestGetNonUnixfs(t *testing.T) { t.Fatal(err) } - _, err = api.Unixfs().Get(ctx, coreiface.IpfsPath(nd.Cid())) + _, err = api.Unixfs().Get(ctx, path.IpfsPath(nd.Cid())) if !strings.Contains(err.Error(), "proto: required field") { t.Fatalf("expected protobuf error, got: %s", err) } @@ -782,7 +783,7 @@ func (tp *provider) TestLsEmptyDir(t *testing.T) { t.Fatal(err) } - links, err := api.Unixfs().Ls(ctx, coreiface.IpfsPath(emptyDir.Cid())) + links, err := api.Unixfs().Ls(ctx, path.IpfsPath(emptyDir.Cid())) if err != nil { t.Fatal(err) } @@ -811,7 +812,7 @@ func (tp *provider) TestLsNonUnixfs(t *testing.T) { t.Fatal(err) } - links, err := api.Unixfs().Ls(ctx, coreiface.IpfsPath(nd.Cid())) + links, err := api.Unixfs().Ls(ctx, path.IpfsPath(nd.Cid())) if err != nil { t.Fatal(err) } diff --git a/core/coreiface/unixfs.go b/core/coreiface/unixfs.go index f9508f138..0b27519f3 100644 --- a/core/coreiface/unixfs.go +++ b/core/coreiface/unixfs.go @@ -3,16 +3,17 @@ package iface import ( "context" "github.com/ipfs/interface-go-ipfs-core/options" + path "github.com/ipfs/interface-go-ipfs-core/path" - cid "github.com/ipfs/go-cid" - files "github.com/ipfs/go-ipfs-files" + "github.com/ipfs/go-cid" + "github.com/ipfs/go-ipfs-files" ) type AddEvent struct { Name string - Path ResolvedPath `json:",omitempty"` - Bytes int64 `json:",omitempty"` - Size string `json:",omitempty"` + Path path.ResolvedPath `json:",omitempty"` + Bytes int64 `json:",omitempty"` + Size string `json:",omitempty"` } // FileType is an enum of possible UnixFS file types. @@ -64,15 +65,15 @@ type UnixfsAPI interface { // Add imports the data from the reader into merkledag file // // TODO: a long useful comment on how to use this for many different scenarios - Add(context.Context, files.Node, ...options.UnixfsAddOption) (ResolvedPath, error) + Add(context.Context, files.Node, ...options.UnixfsAddOption) (path.ResolvedPath, error) // Get returns a read-only handle to a file tree referenced by a path // // Note that some implementations of this API may apply the specified context // to operations performed on the returned file - Get(context.Context, Path) (files.Node, error) + Get(context.Context, path.Path) (files.Node, error) // Ls returns the list of links in a directory. Links aren't guaranteed to be // returned in order - Ls(context.Context, Path, ...options.UnixfsLsOption) (<-chan DirEntry, error) + Ls(context.Context, path.Path, ...options.UnixfsLsOption) (<-chan DirEntry, error) } From 3669a774ffa2b3c545baf3f80f77c6d792295e34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 26 Mar 2019 15:09:08 +0100 Subject: [PATCH 0288/1212] path: rename ParsePath and ResolvedPath This commit was moved from ipfs/interface-go-ipfs-core@21a72398d98125cae4fcef33cc80ed4a1f3be22c This commit was moved from ipfs/boxo@fbc9ab8769cbaac70a6459c33973c0d894e85126 --- core/coreiface/block.go | 2 +- core/coreiface/coreapi.go | 2 +- core/coreiface/object.go | 14 +++++++------- core/coreiface/path.go | 4 ---- core/coreiface/path/path.go | 16 ++++++++-------- core/coreiface/pin.go | 4 ++-- core/coreiface/tests/block.go | 2 +- core/coreiface/tests/dag.go | 2 +- core/coreiface/tests/name.go | 2 +- core/coreiface/tests/path.go | 10 +++++----- core/coreiface/tests/unixfs.go | 4 ++-- core/coreiface/unixfs.go | 8 ++++---- 12 files changed, 33 insertions(+), 37 deletions(-) delete mode 100644 core/coreiface/path.go diff --git a/core/coreiface/block.go b/core/coreiface/block.go index 9f0ad9cbb..b105b079d 100644 --- a/core/coreiface/block.go +++ b/core/coreiface/block.go @@ -14,7 +14,7 @@ type BlockStat interface { Size() int // Path returns path to the block - Path() path.ResolvedPath + Path() path.Resolved } // BlockAPI specifies the interface to the block layer diff --git a/core/coreiface/coreapi.go b/core/coreiface/coreapi.go index bef3ce01f..12cb166a8 100644 --- a/core/coreiface/coreapi.go +++ b/core/coreiface/coreapi.go @@ -44,7 +44,7 @@ type CoreAPI interface { PubSub() PubSubAPI // ResolvePath resolves the path using Unixfs resolver - ResolvePath(context.Context, path.Path) (path.ResolvedPath, error) + ResolvePath(context.Context, path.Path) (path.Resolved, error) // ResolveNode resolves the path (if not resolved already) using Unixfs // resolver, gets and returns the resolved Node diff --git a/core/coreiface/object.go b/core/coreiface/object.go index 3e4b7e087..86536d421 100644 --- a/core/coreiface/object.go +++ b/core/coreiface/object.go @@ -59,11 +59,11 @@ type ObjectChange struct { // Before holds the link path before the change. Note that when a link is // added, this will be nil. - Before path.ResolvedPath + Before path.Resolved // After holds the link path after the change. Note that when a link is // removed, this will be nil. - After path.ResolvedPath + After path.Resolved } // ObjectAPI specifies the interface to MerkleDAG and contains useful utilities @@ -73,7 +73,7 @@ type ObjectAPI interface { New(context.Context, ...options.ObjectNewOption) (ipld.Node, error) // Put imports the data into merkledag - Put(context.Context, io.Reader, ...options.ObjectPutOption) (path.ResolvedPath, error) + Put(context.Context, io.Reader, ...options.ObjectPutOption) (path.Resolved, error) // Get returns the node for the path Get(context.Context, path.Path) (ipld.Node, error) @@ -90,16 +90,16 @@ type ObjectAPI interface { // AddLink adds a link under the specified path. child path can point to a // subdirectory within the patent which must be present (can be overridden // with WithCreate option). - AddLink(ctx context.Context, base path.Path, name string, child path.Path, opts ...options.ObjectAddLinkOption) (path.ResolvedPath, error) + AddLink(ctx context.Context, base path.Path, name string, child path.Path, opts ...options.ObjectAddLinkOption) (path.Resolved, error) // RmLink removes a link from the node - RmLink(ctx context.Context, base path.Path, link string) (path.ResolvedPath, error) + RmLink(ctx context.Context, base path.Path, link string) (path.Resolved, error) // AppendData appends data to the node - AppendData(context.Context, path.Path, io.Reader) (path.ResolvedPath, error) + AppendData(context.Context, path.Path, io.Reader) (path.Resolved, error) // SetData sets the data contained in the node - SetData(context.Context, path.Path, io.Reader) (path.ResolvedPath, error) + SetData(context.Context, path.Path, io.Reader) (path.Resolved, error) // Diff returns a set of changes needed to transform the first object into the // second. diff --git a/core/coreiface/path.go b/core/coreiface/path.go deleted file mode 100644 index 198651129..000000000 --- a/core/coreiface/path.go +++ /dev/null @@ -1,4 +0,0 @@ -package iface - -//TODO: merge with ipfspath so we don't depend on it - diff --git a/core/coreiface/path/path.go b/core/coreiface/path/path.go index 414d454fa..01b1673b1 100644 --- a/core/coreiface/path/path.go +++ b/core/coreiface/path/path.go @@ -39,9 +39,9 @@ type Path interface { IsValid() error } -// ResolvedPath is a path which was resolved to the last resolvable node. +// Resolved is a path which was resolved to the last resolvable node. // ResolvedPaths are guaranteed to return nil from `IsValid` -type ResolvedPath interface { +type Resolved interface { // Cid returns the CID of the node referenced by the path. Remainder of the // path is guaranteed to be within the node. // @@ -120,7 +120,7 @@ func Join(base Path, a ...string) Path { } // IpfsPath creates new /ipfs path from the provided CID -func IpfsPath(c cid.Cid) ResolvedPath { +func IpfsPath(c cid.Cid) Resolved { return &resolvedPath{ path: path{"/ipfs/" + c.String()}, cid: c, @@ -130,7 +130,7 @@ func IpfsPath(c cid.Cid) ResolvedPath { } // IpldPath creates new /ipld path from the provided CID -func IpldPath(c cid.Cid) ResolvedPath { +func IpldPath(c cid.Cid) Resolved { return &resolvedPath{ path: path{"/ipld/" + c.String()}, cid: c, @@ -139,8 +139,8 @@ func IpldPath(c cid.Cid) ResolvedPath { } } -// ParsePath parses string path to a Path -func ParsePath(p string) Path { +// New parses string path to a Path +func New(p string) Path { if pp, err := ipfspath.ParsePath(p); err == nil { p = pp.String() } @@ -148,10 +148,10 @@ func ParsePath(p string) Path { return &path{path: p} } -// NewResolvedPath creates new ResolvedPath. This function performs no checks +// NewResolvedPath creates new Resolved path. This function performs no checks // and is intended to be used by resolver implementations. Incorrect inputs may // cause panics. Handle with care. -func NewResolvedPath(ipath ipfspath.Path, c cid.Cid, root cid.Cid, remainder string) ResolvedPath { +func NewResolvedPath(ipath ipfspath.Path, c cid.Cid, root cid.Cid, remainder string) Resolved { return &resolvedPath{ path: path{ipath.String()}, cid: c, diff --git a/core/coreiface/pin.go b/core/coreiface/pin.go index 736b2d68b..7df2956f0 100644 --- a/core/coreiface/pin.go +++ b/core/coreiface/pin.go @@ -10,7 +10,7 @@ import ( // Pin holds information about pinned resource type Pin interface { // Path to the pinned object - Path() path.ResolvedPath + Path() path.Resolved // Type of the pin Type() string @@ -28,7 +28,7 @@ type PinStatus interface { // BadPinNode is a node that has been marked as bad by Pin.Verify type BadPinNode interface { // Path is the path of the node - Path() path.ResolvedPath + Path() path.Resolved // Err is the reason why the node has been marked as bad Err() error diff --git a/core/coreiface/tests/block.go b/core/coreiface/tests/block.go index 59b49d567..961ac722d 100644 --- a/core/coreiface/tests/block.go +++ b/core/coreiface/tests/block.go @@ -111,7 +111,7 @@ func (tp *provider) TestBlockGet(t *testing.T) { t.Error("didn't get correct data back") } - p := path.ParsePath("/ipfs/" + res.Path().Cid().String()) + p := path.New("/ipfs/" + res.Path().Cid().String()) rp, err := api.ResolvePath(ctx, p) if err != nil { diff --git a/core/coreiface/tests/dag.go b/core/coreiface/tests/dag.go index 0abcee32f..fe92641f4 100644 --- a/core/coreiface/tests/dag.go +++ b/core/coreiface/tests/dag.go @@ -114,7 +114,7 @@ func (tp *provider) TestDagPath(t *testing.T) { t.Fatal(err) } - p := path.ParsePath(gopath.Join(nd.Cid().String(), "lnk")) + p := path.New(gopath.Join(nd.Cid().String(), "lnk")) rp, err := api.ResolvePath(ctx, p) if err != nil { diff --git a/core/coreiface/tests/name.go b/core/coreiface/tests/name.go index 98ae6853e..efaf1d3ae 100644 --- a/core/coreiface/tests/name.go +++ b/core/coreiface/tests/name.go @@ -36,7 +36,7 @@ func addTestObject(ctx context.Context, api coreiface.CoreAPI) (path.Path, error } func appendPath(p path.Path, sub string) path.Path { - return path.ParsePath(gopath.Join(p.String(), sub)) + return path.New(gopath.Join(p.String(), sub)) } func (tp *provider) TestPublishResolve(t *testing.T) { diff --git a/core/coreiface/tests/path.go b/core/coreiface/tests/path.go index 685f46998..4fd18bd20 100644 --- a/core/coreiface/tests/path.go +++ b/core/coreiface/tests/path.go @@ -75,7 +75,7 @@ func (tp *provider) TestPathRemainder(t *testing.T) { t.Fatal(err) } - rp1, err := api.ResolvePath(ctx, path.ParsePath(nd.String()+"/foo/bar")) + rp1, err := api.ResolvePath(ctx, path.New(nd.String()+"/foo/bar")) if err != nil { t.Fatal(err) } @@ -106,7 +106,7 @@ func (tp *provider) TestEmptyPathRemainder(t *testing.T) { t.Fatal(err) } - rp1, err := api.ResolvePath(ctx, path.ParsePath(nd.Cid().String())) + rp1, err := api.ResolvePath(ctx, path.New(nd.Cid().String())) if err != nil { t.Fatal(err) } @@ -137,7 +137,7 @@ func (tp *provider) TestInvalidPathRemainder(t *testing.T) { t.Fatal(err) } - _, err = api.ResolvePath(ctx, path.ParsePath("/ipld/"+nd.Cid().String()+"/bar/baz")) + _, err = api.ResolvePath(ctx, path.New("/ipld/"+nd.Cid().String()+"/bar/baz")) if err == nil || !strings.Contains(err.Error(), "no such link found") { t.Fatalf("unexpected error: %s", err) } @@ -173,7 +173,7 @@ func (tp *provider) TestPathRoot(t *testing.T) { t.Fatal(err) } - rp, err := api.ResolvePath(ctx, path.ParsePath("/ipld/"+nd.Cid().String()+"/foo")) + rp, err := api.ResolvePath(ctx, path.New("/ipld/"+nd.Cid().String()+"/foo")) if err != nil { t.Fatal(err) } @@ -188,7 +188,7 @@ func (tp *provider) TestPathRoot(t *testing.T) { } func (tp *provider) TestPathJoin(t *testing.T) { - p1 := path.ParsePath("/ipfs/QmYNmQKp6SuaVrpgWRsPTgCQCnpxUYGq76YEKBXuj2N4H6/bar/baz") + p1 := path.New("/ipfs/QmYNmQKp6SuaVrpgWRsPTgCQCnpxUYGq76YEKBXuj2N4H6/bar/baz") if path.Join(p1, "foo").String() != "/ipfs/QmYNmQKp6SuaVrpgWRsPTgCQCnpxUYGq76YEKBXuj2N4H6/bar/baz/foo" { t.Error("unexpected path") diff --git a/core/coreiface/tests/unixfs.go b/core/coreiface/tests/unixfs.go index d2d9f85b8..38fab7cd8 100644 --- a/core/coreiface/tests/unixfs.go +++ b/core/coreiface/tests/unixfs.go @@ -102,7 +102,7 @@ func (tp *provider) TestAdd(t *testing.T) { t.Fatal(err) } - p := func(h string) path.ResolvedPath { + p := func(h string) path.Resolved { c, err := cid.Parse(h) if err != nil { t.Fatal(err) @@ -593,7 +593,7 @@ func (tp *provider) TestGetEmptyFile(t *testing.T) { t.Fatal(err) } - emptyFilePath := path.ParsePath(emptyFile) + emptyFilePath := path.New(emptyFile) r, err := api.Unixfs().Get(ctx, emptyFilePath) if err != nil { diff --git a/core/coreiface/unixfs.go b/core/coreiface/unixfs.go index 0b27519f3..686c40298 100644 --- a/core/coreiface/unixfs.go +++ b/core/coreiface/unixfs.go @@ -11,9 +11,9 @@ import ( type AddEvent struct { Name string - Path path.ResolvedPath `json:",omitempty"` - Bytes int64 `json:",omitempty"` - Size string `json:",omitempty"` + Path path.Resolved `json:",omitempty"` + Bytes int64 `json:",omitempty"` + Size string `json:",omitempty"` } // FileType is an enum of possible UnixFS file types. @@ -65,7 +65,7 @@ type UnixfsAPI interface { // Add imports the data from the reader into merkledag file // // TODO: a long useful comment on how to use this for many different scenarios - Add(context.Context, files.Node, ...options.UnixfsAddOption) (path.ResolvedPath, error) + Add(context.Context, files.Node, ...options.UnixfsAddOption) (path.Resolved, error) // Get returns a read-only handle to a file tree referenced by a path // From 70158edd5950671a26631788d15204350d174f52 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Thu, 4 Apr 2019 00:36:32 -0700 Subject: [PATCH 0289/1212] feed through context see https://github.com/ipfs/go-ipfs-api/pull/173 all credit to @optman This commit was moved from ipfs/go-ipfs-http-client@7b75a8c577988e4728474a02144bf5bf83260527 --- client/httpapi/request.go | 2 ++ client/httpapi/response.go | 2 ++ 2 files changed, 4 insertions(+) diff --git a/client/httpapi/request.go b/client/httpapi/request.go index 58c61ac67..dd5293b7a 100644 --- a/client/httpapi/request.go +++ b/client/httpapi/request.go @@ -7,6 +7,7 @@ import ( ) type Request struct { + Ctx context.Context ApiBase string Command string Args []string @@ -25,6 +26,7 @@ func NewRequest(ctx context.Context, url, command string, args ...string) *Reque "stream-channels": "true", } return &Request{ + Ctx: ctx, ApiBase: url + "/api/v0", Command: command, Args: args, diff --git a/client/httpapi/response.go b/client/httpapi/response.go index 339c73658..29ae38c69 100644 --- a/client/httpapi/response.go +++ b/client/httpapi/response.go @@ -95,6 +95,8 @@ func (r *Request) Send(c *http.Client) (*Response, error) { return nil, err } + req = req.WithContext(r.Ctx) + // Add any headers that were supplied via the RequestBuilder. for k, v := range r.Headers { req.Header.Add(k, v) From 3b02ea46462d1f87a64e3fe23f73ee0f186b40d5 Mon Sep 17 00:00:00 2001 From: Alex Date: Tue, 9 Apr 2019 19:53:07 -0700 Subject: [PATCH 0290/1212] api: add authenticated transport, and direct connection This commit was moved from ipfs/go-ipfs-http-client@d04afa02b059d2c6a631f23a6923eb57ecb21015 --- client/httpapi/api.go | 36 ++++++++++++++++++++++++++++++++++++ client/httpapi/api_test.go | 25 +++++++++++++++++++++++-- client/httpapi/transport.go | 21 +++++++++++++++++++++ 3 files changed, 80 insertions(+), 2 deletions(-) create mode 100644 client/httpapi/transport.go diff --git a/client/httpapi/api.go b/client/httpapi/api.go index dad205fd0..c0eacd7cb 100644 --- a/client/httpapi/api.go +++ b/client/httpapi/api.go @@ -122,6 +122,42 @@ func NewApiWithClient(a ma.Multiaddr, c *gohttp.Client) (*HttpApi, error) { return api, nil } +// NewDirectAPIClient is used to instantiate a HttpApi client +// that connects to an endpoint which leverages additional http paths. +// +// If you need to connect to a IPFS HTTP API located at https://foo.bar/baz/api/v0 +// you should use NewDirectAPIClient. +func NewDirectAPIClient(url string) (*HttpApi, error) { + api := &HttpApi{ + url: url, + httpcli: gohttp.Client{ + Transport: &gohttp.Transport{ + Proxy: gohttp.ProxyFromEnvironment, + DisableKeepAlives: true, + }, + }, + applyGlobal: func(*RequestBuilder) {}, + } + + // We don't support redirects. + api.httpcli.CheckRedirect = func(_ *gohttp.Request, _ []*gohttp.Request) error { + return fmt.Errorf("unexpected redirect") + } + + return api, nil +} + +// WithAuthorization is used to wrap an instance of HttpApi +// with an authenticated transport, such as JWT +func (api *HttpApi) WithAuthorization(header, value string) *HttpApi { + return &HttpApi{ + url: api.url, + httpcli: gohttp.Client{ + Transport: newAuthenticatedTransport(api.httpcli.Transport, header, value), + }, + } +} + func (api *HttpApi) WithOptions(opts ...caopts.ApiOption) (iface.CoreAPI, error) { options, err := caopts.ApiOptions(opts...) if err != nil { diff --git a/client/httpapi/api_test.go b/client/httpapi/api_test.go index df45c15af..f1b1bf269 100644 --- a/client/httpapi/api_test.go +++ b/client/httpapi/api_test.go @@ -9,11 +9,11 @@ import ( "sync" "testing" - "github.com/ipfs/interface-go-ipfs-core" + iface "github.com/ipfs/interface-go-ipfs-core" "github.com/ipfs/interface-go-ipfs-core/tests" local "github.com/ipfs/iptb-plugins/local" "github.com/ipfs/iptb/testbed" - "github.com/ipfs/iptb/testbed/interfaces" + testbedi "github.com/ipfs/iptb/testbed/interfaces" ma "github.com/multiformats/go-multiaddr" ) @@ -211,3 +211,24 @@ func TestHttpApi(t *testing.T) { tests.TestApi(newNodeProvider(ctx))(t) } + +func TestDirectAPI(t *testing.T) { + type args struct { + url, header, value string + } + tests := []struct { + name string + args args + }{ + {"Success", args{"http://127.0.0.1:5001/foo/bar/api/v0", "Authorization", "Bearer token"}}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + api, err := NewDirectAPIClient(tt.args.url) + if err != nil { + t.Fatal(err) + } + api = api.WithAuthorization(tt.args.header, tt.args.value) + }) + } +} diff --git a/client/httpapi/transport.go b/client/httpapi/transport.go new file mode 100644 index 000000000..3fb0e6e00 --- /dev/null +++ b/client/httpapi/transport.go @@ -0,0 +1,21 @@ +package httpapi + +import "net/http" + +type transport struct { + header, value string + httptr http.RoundTripper +} + +func newAuthenticatedTransport(tr http.RoundTripper, header, value string) *transport { + return &transport{ + header: header, + value: value, + httptr: tr, + } +} + +func (t *transport) RoundTrip(req *http.Request) (*http.Response, error) { + req.Header.Set(t.header, t.value) + return t.httptr.RoundTrip(req) +} From eb58ebe446c0d2d3aad742719c65e8f693f7ce68 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Mon, 15 Apr 2019 21:58:51 -0700 Subject: [PATCH 0291/1212] fix: cleanup TestDhtProvide And fix for peer ID formatting changes. fixes https://github.com/ipfs/go-ipfs/pull/6222#issuecomment-483479039 This commit was moved from ipfs/interface-go-ipfs-core@29b26f5bcb322e936e67dfbb7b0a5264b7e23089 This commit was moved from ipfs/boxo@d493b701942234de0168890c2625082ff382e1b3 --- core/coreiface/tests/dht.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/core/coreiface/tests/dht.go b/core/coreiface/tests/dht.go index 1793cd738..5482b50b1 100644 --- a/core/coreiface/tests/dht.go +++ b/core/coreiface/tests/dht.go @@ -130,17 +130,17 @@ func (tp *provider) TestDhtProvide(t *testing.T) { t.Fatal(err) } - provider := <-out + _, ok := <-out + + if ok { + t.Fatal("did not expect to find any providers") + } self0, err := apis[0].Key().Self(ctx) if err != nil { t.Fatal(err) } - if provider.ID.String() != "" { - t.Errorf("got wrong provider: %s != %s", provider.ID.String(), self0.ID().String()) - } - err = apis[0].Dht().Provide(ctx, p) if err != nil { t.Fatal(err) @@ -151,7 +151,7 @@ func (tp *provider) TestDhtProvide(t *testing.T) { t.Fatal(err) } - provider = <-out + provider := <-out if provider.ID.String() != self0.ID().String() { t.Errorf("got wrong provider: %s != %s", provider.ID.String(), self0.ID().String()) From 3b67615201cd38aceb6de61e87da1552be7689fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 26 Apr 2019 20:30:55 +0200 Subject: [PATCH 0292/1212] gomod: update iface with path refactor This commit was moved from ipfs/go-ipfs-http-client@0bd65a67ee2994966538fae6d034ddb9fac466e6 --- client/httpapi/api_test.go | 7 ++----- client/httpapi/apifile.go | 16 ++++++++-------- client/httpapi/block.go | 11 ++++++----- client/httpapi/dag.go | 6 +++--- client/httpapi/dht.go | 6 +++--- client/httpapi/key.go | 6 +++--- client/httpapi/name.go | 17 +++++++++-------- client/httpapi/object.go | 35 ++++++++++++++++++----------------- client/httpapi/path.go | 18 +++++++++--------- client/httpapi/pin.go | 17 +++++++++-------- client/httpapi/unixfs.go | 9 +++++---- 11 files changed, 75 insertions(+), 73 deletions(-) diff --git a/client/httpapi/api_test.go b/client/httpapi/api_test.go index df45c15af..b1bae5565 100644 --- a/client/httpapi/api_test.go +++ b/client/httpapi/api_test.go @@ -10,6 +10,7 @@ import ( "testing" "github.com/ipfs/interface-go-ipfs-core" + "github.com/ipfs/interface-go-ipfs-core/path" "github.com/ipfs/interface-go-ipfs-core/tests" local "github.com/ipfs/iptb-plugins/local" "github.com/ipfs/iptb/testbed" @@ -171,11 +172,7 @@ func (NodeProvider) makeAPISwarm(ctx context.Context, fullIdentity bool, n int) } // empty node is pinned even with --empty-repo, we don't want that - emptyNode, err := iface.ParsePath("/ipfs/QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn") - if err != nil { - errs <- err - return - } + emptyNode := path.New("/ipfs/QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn") if err := apis[i].Pin().Rm(ctx, emptyNode); err != nil { errs <- err return diff --git a/client/httpapi/apifile.go b/client/httpapi/apifile.go index 6e3433a51..afd9934e6 100644 --- a/client/httpapi/apifile.go +++ b/client/httpapi/apifile.go @@ -10,12 +10,12 @@ import ( "github.com/ipfs/go-cid" files "github.com/ipfs/go-ipfs-files" unixfs "github.com/ipfs/go-unixfs" - iface "github.com/ipfs/interface-go-ipfs-core" + "github.com/ipfs/interface-go-ipfs-core/path" ) const forwardSeekLimit = 1 << 14 //16k -func (api *UnixfsAPI) Get(ctx context.Context, p iface.Path) (files.Node, error) { +func (api *UnixfsAPI) Get(ctx context.Context, p path.Path) (files.Node, error) { if p.Mutable() { // use resolved path in case we are dealing with IPNS / MFS var err error p, err = api.core().ResolvePath(ctx, p) @@ -48,7 +48,7 @@ type apiFile struct { ctx context.Context core *HttpApi size int64 - path iface.Path + path path.Path r *Response at int64 @@ -114,7 +114,7 @@ func (f *apiFile) Size() (int64, error) { return f.size, nil } -func (api *UnixfsAPI) getFile(ctx context.Context, p iface.Path, size int64) (files.Node, error) { +func (api *UnixfsAPI) getFile(ctx context.Context, p path.Path, size int64) (files.Node, error) { f := &apiFile{ ctx: ctx, core: api.core(), @@ -177,13 +177,13 @@ func (it *apiIter) Next() bool { switch it.cur.Type { case unixfs.THAMTShard, unixfs.TMetadata, unixfs.TDirectory: - it.curFile, err = it.core.getDir(it.ctx, iface.IpfsPath(c), int64(it.cur.Size)) + it.curFile, err = it.core.getDir(it.ctx, path.IpfsPath(c), int64(it.cur.Size)) if err != nil { it.err = err return false } case unixfs.TFile: - it.curFile, err = it.core.getFile(it.ctx, iface.IpfsPath(c), int64(it.cur.Size)) + it.curFile, err = it.core.getFile(it.ctx, path.IpfsPath(c), int64(it.cur.Size)) if err != nil { it.err = err return false @@ -203,7 +203,7 @@ type apiDir struct { ctx context.Context core *UnixfsAPI size int64 - path iface.Path + path path.Path dec *json.Decoder } @@ -224,7 +224,7 @@ func (d *apiDir) Entries() files.DirIterator { } } -func (api *UnixfsAPI) getDir(ctx context.Context, p iface.Path, size int64) (files.Node, error) { +func (api *UnixfsAPI) getDir(ctx context.Context, p path.Path, size int64) (files.Node, error) { resp, err := api.core().Request("ls", p.String()). Option("resolve-size", true). Option("stream", true).Send(ctx) diff --git a/client/httpapi/block.go b/client/httpapi/block.go index 3389f4c31..640f186f5 100644 --- a/client/httpapi/block.go +++ b/client/httpapi/block.go @@ -10,6 +10,7 @@ import ( "github.com/ipfs/go-cid" "github.com/ipfs/interface-go-ipfs-core" caopts "github.com/ipfs/interface-go-ipfs-core/options" + "github.com/ipfs/interface-go-ipfs-core/path" mh "github.com/multiformats/go-multihash" ) @@ -26,8 +27,8 @@ func (s *blockStat) Size() int { return s.BSize } -func (s *blockStat) Path() iface.ResolvedPath { - return iface.IpldPath(s.cid) +func (s *blockStat) Path() path.Resolved { + return path.IpldPath(s.cid) } func (api *BlockAPI) Put(ctx context.Context, r io.Reader, opts ...caopts.BlockPutOption) (iface.BlockStat, error) { @@ -60,7 +61,7 @@ func (api *BlockAPI) Put(ctx context.Context, r io.Reader, opts ...caopts.BlockP return &out, nil } -func (api *BlockAPI) Get(ctx context.Context, p iface.Path) (io.Reader, error) { +func (api *BlockAPI) Get(ctx context.Context, p path.Path) (io.Reader, error) { resp, err := api.core().Request("block/get", p.String()).Send(ctx) if err != nil { return nil, err @@ -79,7 +80,7 @@ func (api *BlockAPI) Get(ctx context.Context, p iface.Path) (io.Reader, error) { return b, nil } -func (api *BlockAPI) Rm(ctx context.Context, p iface.Path, opts ...caopts.BlockRmOption) error { +func (api *BlockAPI) Rm(ctx context.Context, p path.Path, opts ...caopts.BlockRmOption) error { options, err := caopts.BlockRmOptions(opts...) if err != nil { return err @@ -105,7 +106,7 @@ func (api *BlockAPI) Rm(ctx context.Context, p iface.Path, opts ...caopts.BlockR return nil } -func (api *BlockAPI) Stat(ctx context.Context, p iface.Path) (iface.BlockStat, error) { +func (api *BlockAPI) Stat(ctx context.Context, p path.Path) (iface.BlockStat, error) { var out blockStat err := api.core().Request("block/stat", p.String()).Exec(ctx, &out) if err != nil { diff --git a/client/httpapi/dag.go b/client/httpapi/dag.go index 669b5f893..15d9a9c62 100644 --- a/client/httpapi/dag.go +++ b/client/httpapi/dag.go @@ -9,8 +9,8 @@ import ( "github.com/ipfs/go-block-format" "github.com/ipfs/go-cid" "github.com/ipfs/go-ipld-format" - "github.com/ipfs/interface-go-ipfs-core" "github.com/ipfs/interface-go-ipfs-core/options" + "github.com/ipfs/interface-go-ipfs-core/path" ) type httpNodeAdder HttpApi @@ -18,7 +18,7 @@ type HttpDagServ httpNodeAdder type pinningHttpNodeAdder httpNodeAdder func (api *HttpDagServ) Get(ctx context.Context, c cid.Cid) (format.Node, error) { - r, err := api.core().Block().Get(ctx, iface.IpldPath(c)) + r, err := api.core().Block().Get(ctx, path.IpldPath(c)) if err != nil { return nil, err } @@ -105,7 +105,7 @@ func (api *HttpDagServ) Pinning() format.NodeAdder { } func (api *HttpDagServ) Remove(ctx context.Context, c cid.Cid) error { - return api.core().Block().Rm(ctx, iface.IpldPath(c)) //TODO: should we force rm? + return api.core().Block().Rm(ctx, path.IpldPath(c)) //TODO: should we force rm? } func (api *HttpDagServ) RemoveMany(ctx context.Context, cids []cid.Cid) error { diff --git a/client/httpapi/dht.go b/client/httpapi/dht.go index f7417cb7f..e12caa1c5 100644 --- a/client/httpapi/dht.go +++ b/client/httpapi/dht.go @@ -4,8 +4,8 @@ import ( "context" "encoding/json" - "github.com/ipfs/interface-go-ipfs-core" caopts "github.com/ipfs/interface-go-ipfs-core/options" + "github.com/ipfs/interface-go-ipfs-core/path" "github.com/libp2p/go-libp2p-peer" "github.com/libp2p/go-libp2p-peerstore" notif "github.com/libp2p/go-libp2p-routing/notifications" @@ -37,7 +37,7 @@ func (api *DhtAPI) FindPeer(ctx context.Context, p peer.ID) (peerstore.PeerInfo, } } -func (api *DhtAPI) FindProviders(ctx context.Context, p iface.Path, opts ...caopts.DhtFindProvidersOption) (<-chan peerstore.PeerInfo, error) { +func (api *DhtAPI) FindProviders(ctx context.Context, p path.Path, opts ...caopts.DhtFindProvidersOption) (<-chan peerstore.PeerInfo, error) { options, err := caopts.DhtFindProvidersOptions(opts...) if err != nil { return nil, err @@ -93,7 +93,7 @@ func (api *DhtAPI) FindProviders(ctx context.Context, p iface.Path, opts ...caop return res, nil } -func (api *DhtAPI) Provide(ctx context.Context, p iface.Path, opts ...caopts.DhtProvideOption) error { +func (api *DhtAPI) Provide(ctx context.Context, p path.Path, opts ...caopts.DhtProvideOption) error { options, err := caopts.DhtProvideOptions(opts...) if err != nil { return err diff --git a/client/httpapi/key.go b/client/httpapi/key.go index 1571a3350..9a47e2ed0 100644 --- a/client/httpapi/key.go +++ b/client/httpapi/key.go @@ -6,6 +6,7 @@ import ( "github.com/ipfs/interface-go-ipfs-core" caopts "github.com/ipfs/interface-go-ipfs-core/options" + "github.com/ipfs/interface-go-ipfs-core/path" "github.com/libp2p/go-libp2p-peer" ) @@ -22,9 +23,8 @@ func (k *keyOutput) Name() string { return k.JName } -func (k *keyOutput) Path() iface.Path { - p, _ := iface.ParsePath("/ipns/" + k.Id) - return p +func (k *keyOutput) Path() path.Path { + return path.New("/ipns/" + k.Id) } func (k *keyOutput) ID() peer.ID { diff --git a/client/httpapi/name.go b/client/httpapi/name.go index 0641d1a22..47227a2ab 100644 --- a/client/httpapi/name.go +++ b/client/httpapi/name.go @@ -9,6 +9,7 @@ import ( "github.com/ipfs/interface-go-ipfs-core" caopts "github.com/ipfs/interface-go-ipfs-core/options" "github.com/ipfs/interface-go-ipfs-core/options/namesys" + "github.com/ipfs/interface-go-ipfs-core/path" ) type NameAPI HttpApi @@ -17,18 +18,18 @@ type ipnsEntry struct { JName string `json:"Name"` JValue string `json:"Value"` - path iface.Path + path path.Path } func (e *ipnsEntry) Name() string { return e.JName } -func (e *ipnsEntry) Value() iface.Path { +func (e *ipnsEntry) Value() path.Path { return e.path } -func (api *NameAPI) Publish(ctx context.Context, p iface.Path, opts ...caopts.NamePublishOption) (iface.IpnsEntry, error) { +func (api *NameAPI) Publish(ctx context.Context, p path.Path, opts ...caopts.NamePublishOption) (iface.IpnsEntry, error) { options, err := caopts.NamePublishOptions(opts...) if err != nil { return nil, err @@ -48,8 +49,8 @@ func (api *NameAPI) Publish(ctx context.Context, p iface.Path, opts ...caopts.Na if err := req.Exec(ctx, &out); err != nil { return nil, err } - out.path, err = iface.ParsePath(out.JValue) - return &out, err + out.path = path.New(out.JValue) + return &out, out.path.IsValid() } func (api *NameAPI) Search(ctx context.Context, name string, opts ...caopts.NameResolveOption) (<-chan iface.IpnsResult, error) { @@ -93,7 +94,7 @@ func (api *NameAPI) Search(ctx context.Context, name string, opts ...caopts.Name } var ires iface.IpnsResult if err == nil { - ires.Path, err = iface.ParsePath(out.Path) + ires.Path = path.New(out.Path) } select { @@ -109,7 +110,7 @@ func (api *NameAPI) Search(ctx context.Context, name string, opts ...caopts.Name return res, nil } -func (api *NameAPI) Resolve(ctx context.Context, name string, opts ...caopts.NameResolveOption) (iface.Path, error) { +func (api *NameAPI) Resolve(ctx context.Context, name string, opts ...caopts.NameResolveOption) (path.Path, error) { options, err := caopts.NameResolveOptions(opts...) if err != nil { return nil, err @@ -131,7 +132,7 @@ func (api *NameAPI) Resolve(ctx context.Context, name string, opts ...caopts.Nam return nil, err } - return iface.ParsePath(out.Path) + return path.New(out.Path), nil } func (api *NameAPI) core() *HttpApi { diff --git a/client/httpapi/object.go b/client/httpapi/object.go index a1ee486b3..280b2490f 100644 --- a/client/httpapi/object.go +++ b/client/httpapi/object.go @@ -14,6 +14,7 @@ import ( ft "github.com/ipfs/go-unixfs" "github.com/ipfs/interface-go-ipfs-core" caopts "github.com/ipfs/interface-go-ipfs-core/options" + "github.com/ipfs/interface-go-ipfs-core/path" ) type ObjectAPI HttpApi @@ -41,7 +42,7 @@ func (api *ObjectAPI) New(ctx context.Context, opts ...caopts.ObjectNewOption) ( return n, nil } -func (api *ObjectAPI) Put(ctx context.Context, r io.Reader, opts ...caopts.ObjectPutOption) (iface.ResolvedPath, error) { +func (api *ObjectAPI) Put(ctx context.Context, r io.Reader, opts ...caopts.ObjectPutOption) (path.Resolved, error) { options, err := caopts.ObjectPutOptions(opts...) if err != nil { return nil, err @@ -63,10 +64,10 @@ func (api *ObjectAPI) Put(ctx context.Context, r io.Reader, opts ...caopts.Objec return nil, err } - return iface.IpfsPath(c), nil + return path.IpfsPath(c), nil } -func (api *ObjectAPI) Get(ctx context.Context, p iface.Path) (ipld.Node, error) { +func (api *ObjectAPI) Get(ctx context.Context, p path.Path) (ipld.Node, error) { r, err := api.core().Block().Get(ctx, p) if err != nil { return nil, err @@ -79,7 +80,7 @@ func (api *ObjectAPI) Get(ctx context.Context, p iface.Path) (ipld.Node, error) return merkledag.DecodeProtobuf(b) } -func (api *ObjectAPI) Data(ctx context.Context, p iface.Path) (io.Reader, error) { +func (api *ObjectAPI) Data(ctx context.Context, p path.Path) (io.Reader, error) { resp, err := api.core().Request("object/data", p.String()).Send(ctx) if err != nil { return nil, err @@ -98,7 +99,7 @@ func (api *ObjectAPI) Data(ctx context.Context, p iface.Path) (io.Reader, error) return b, nil } -func (api *ObjectAPI) Links(ctx context.Context, p iface.Path) ([]*ipld.Link, error) { +func (api *ObjectAPI) Links(ctx context.Context, p path.Path) ([]*ipld.Link, error) { var out struct { Links []struct { Name string @@ -126,7 +127,7 @@ func (api *ObjectAPI) Links(ctx context.Context, p iface.Path) ([]*ipld.Link, er return res, nil } -func (api *ObjectAPI) Stat(ctx context.Context, p iface.Path) (*iface.ObjectStat, error) { +func (api *ObjectAPI) Stat(ctx context.Context, p path.Path) (*iface.ObjectStat, error) { var out struct { Hash string NumLinks int @@ -154,7 +155,7 @@ func (api *ObjectAPI) Stat(ctx context.Context, p iface.Path) (*iface.ObjectStat }, nil } -func (api *ObjectAPI) AddLink(ctx context.Context, base iface.Path, name string, child iface.Path, opts ...caopts.ObjectAddLinkOption) (iface.ResolvedPath, error) { +func (api *ObjectAPI) AddLink(ctx context.Context, base path.Path, name string, child path.Path, opts ...caopts.ObjectAddLinkOption) (path.Resolved, error) { options, err := caopts.ObjectAddLinkOptions(opts...) if err != nil { return nil, err @@ -173,10 +174,10 @@ func (api *ObjectAPI) AddLink(ctx context.Context, base iface.Path, name string, return nil, err } - return iface.IpfsPath(c), nil + return path.IpfsPath(c), nil } -func (api *ObjectAPI) RmLink(ctx context.Context, base iface.Path, link string) (iface.ResolvedPath, error) { +func (api *ObjectAPI) RmLink(ctx context.Context, base path.Path, link string) (path.Resolved, error) { var out objectOut err := api.core().Request("object/patch/rm-link", base.String(), link). Exec(ctx, &out) @@ -189,10 +190,10 @@ func (api *ObjectAPI) RmLink(ctx context.Context, base iface.Path, link string) return nil, err } - return iface.IpfsPath(c), nil + return path.IpfsPath(c), nil } -func (api *ObjectAPI) AppendData(ctx context.Context, p iface.Path, r io.Reader) (iface.ResolvedPath, error) { +func (api *ObjectAPI) AppendData(ctx context.Context, p path.Path, r io.Reader) (path.Resolved, error) { var out objectOut err := api.core().Request("object/patch/append-data", p.String()). FileBody(r). @@ -206,10 +207,10 @@ func (api *ObjectAPI) AppendData(ctx context.Context, p iface.Path, r io.Reader) return nil, err } - return iface.IpfsPath(c), nil + return path.IpfsPath(c), nil } -func (api *ObjectAPI) SetData(ctx context.Context, p iface.Path, r io.Reader) (iface.ResolvedPath, error) { +func (api *ObjectAPI) SetData(ctx context.Context, p path.Path, r io.Reader) (path.Resolved, error) { var out objectOut err := api.core().Request("object/patch/set-data", p.String()). FileBody(r). @@ -223,7 +224,7 @@ func (api *ObjectAPI) SetData(ctx context.Context, p iface.Path, r io.Reader) (i return nil, err } - return iface.IpfsPath(c), nil + return path.IpfsPath(c), nil } type change struct { @@ -233,7 +234,7 @@ type change struct { After cid.Cid } -func (api *ObjectAPI) Diff(ctx context.Context, a iface.Path, b iface.Path) ([]iface.ObjectChange, error) { +func (api *ObjectAPI) Diff(ctx context.Context, a path.Path, b path.Path) ([]iface.ObjectChange, error) { var out struct { Changes []change } @@ -247,10 +248,10 @@ func (api *ObjectAPI) Diff(ctx context.Context, a iface.Path, b iface.Path) ([]i Path: ch.Path, } if ch.Before != cid.Undef { - res[i].Before = iface.IpfsPath(ch.Before) + res[i].Before = path.IpfsPath(ch.Before) } if ch.After != cid.Undef { - res[i].After = iface.IpfsPath(ch.After) + res[i].After = path.IpfsPath(ch.After) } } return res, nil diff --git a/client/httpapi/path.go b/client/httpapi/path.go index 639ca2f8e..619dd0e0d 100644 --- a/client/httpapi/path.go +++ b/client/httpapi/path.go @@ -6,10 +6,10 @@ import ( cid "github.com/ipfs/go-cid" ipld "github.com/ipfs/go-ipld-format" ipfspath "github.com/ipfs/go-path" - "github.com/ipfs/interface-go-ipfs-core" + "github.com/ipfs/interface-go-ipfs-core/path" ) -func (api *HttpApi) ResolvePath(ctx context.Context, path iface.Path) (iface.ResolvedPath, error) { +func (api *HttpApi) ResolvePath(ctx context.Context, p path.Path) (path.Resolved, error) { var out struct { Cid cid.Cid RemPath string @@ -18,31 +18,31 @@ func (api *HttpApi) ResolvePath(ctx context.Context, path iface.Path) (iface.Res //TODO: this is hacky, fixing https://github.com/ipfs/go-ipfs/issues/5703 would help var err error - if path.Namespace() == "ipns" { - if path, err = api.Name().Resolve(ctx, path.String()); err != nil { + if p.Namespace() == "ipns" { + if p, err = api.Name().Resolve(ctx, p.String()); err != nil { return nil, err } } - if err := api.Request("dag/resolve", path.String()).Exec(ctx, &out); err != nil { + if err := api.Request("dag/resolve", p.String()).Exec(ctx, &out); err != nil { return nil, err } // TODO: - ipath, err := ipfspath.FromSegments("/"+path.Namespace()+"/", out.Cid.String(), out.RemPath) + ipath, err := ipfspath.FromSegments("/"+p.Namespace()+"/", out.Cid.String(), out.RemPath) if err != nil { return nil, err } - root, err := cid.Parse(ipfspath.Path(path.String()).Segments()[1]) + root, err := cid.Parse(ipfspath.Path(p.String()).Segments()[1]) if err != nil { return nil, err } - return iface.NewResolvedPath(ipath, out.Cid, root, out.RemPath), nil + return path.NewResolvedPath(ipath, out.Cid, root, out.RemPath), nil } -func (api *HttpApi) ResolveNode(ctx context.Context, p iface.Path) (ipld.Node, error) { +func (api *HttpApi) ResolveNode(ctx context.Context, p path.Path) (ipld.Node, error) { rp, err := api.ResolvePath(ctx, p) if err != nil { return nil, err diff --git a/client/httpapi/pin.go b/client/httpapi/pin.go index f779640f1..ec0fc91a8 100644 --- a/client/httpapi/pin.go +++ b/client/httpapi/pin.go @@ -7,6 +7,7 @@ import ( "github.com/ipfs/go-cid" "github.com/ipfs/interface-go-ipfs-core" caopts "github.com/ipfs/interface-go-ipfs-core/options" + "github.com/ipfs/interface-go-ipfs-core/path" "github.com/pkg/errors" ) @@ -21,11 +22,11 @@ type pinRefKeyList struct { } type pin struct { - path iface.ResolvedPath + path path.Resolved typ string } -func (p *pin) Path() iface.ResolvedPath { +func (p *pin) Path() path.Resolved { return p.path } @@ -33,7 +34,7 @@ func (p *pin) Type() string { return p.typ } -func (api *PinAPI) Add(ctx context.Context, p iface.Path, opts ...caopts.PinAddOption) error { +func (api *PinAPI) Add(ctx context.Context, p path.Path, opts ...caopts.PinAddOption) error { options, err := caopts.PinAddOptions(opts...) if err != nil { return err @@ -62,13 +63,13 @@ func (api *PinAPI) Ls(ctx context.Context, opts ...caopts.PinLsOption) ([]iface. if err != nil { return nil, err } - pins = append(pins, &pin{typ: p.Type, path: iface.IpldPath(c)}) + pins = append(pins, &pin{typ: p.Type, path: path.IpldPath(c)}) } return pins, nil } -func (api *PinAPI) Rm(ctx context.Context, p iface.Path, opts ...caopts.PinRmOption) error { +func (api *PinAPI) Rm(ctx context.Context, p path.Path, opts ...caopts.PinRmOption) error { options, err := caopts.PinRmOptions(opts...) if err != nil { return err @@ -79,7 +80,7 @@ func (api *PinAPI) Rm(ctx context.Context, p iface.Path, opts ...caopts.PinRmOpt Exec(ctx, nil) } -func (api *PinAPI) Update(ctx context.Context, from iface.Path, to iface.Path, opts ...caopts.PinUpdateOption) error { +func (api *PinAPI) Update(ctx context.Context, from path.Path, to path.Path, opts ...caopts.PinUpdateOption) error { options, err := caopts.PinUpdateOptions(opts...) if err != nil { return err @@ -107,8 +108,8 @@ type badNode struct { cid cid.Cid } -func (n *badNode) Path() iface.ResolvedPath { - return iface.IpldPath(n.cid) +func (n *badNode) Path() path.Resolved { + return path.IpldPath(n.cid) } func (n *badNode) Err() error { diff --git a/client/httpapi/unixfs.go b/client/httpapi/unixfs.go index 84609194b..5e27fb036 100644 --- a/client/httpapi/unixfs.go +++ b/client/httpapi/unixfs.go @@ -13,6 +13,7 @@ import ( unixfs_pb "github.com/ipfs/go-unixfs/pb" iface "github.com/ipfs/interface-go-ipfs-core" caopts "github.com/ipfs/interface-go-ipfs-core/options" + "github.com/ipfs/interface-go-ipfs-core/path" mh "github.com/multiformats/go-multihash" ) @@ -25,7 +26,7 @@ type addEvent struct { type UnixfsAPI HttpApi -func (api *UnixfsAPI) Add(ctx context.Context, f files.Node, opts ...caopts.UnixfsAddOption) (iface.ResolvedPath, error) { +func (api *UnixfsAPI) Add(ctx context.Context, f files.Node, opts ...caopts.UnixfsAddOption) (path.Resolved, error) { options, _, err := caopts.UnixfsAddOptions(opts...) if err != nil { return nil, err @@ -98,7 +99,7 @@ loop: return nil, err } - ifevt.Path = iface.IpfsPath(c) + ifevt.Path = path.IpfsPath(c) } select { @@ -114,7 +115,7 @@ loop: return nil, err } - return iface.IpfsPath(c), nil + return path.IpfsPath(c), nil } type lsLink struct { @@ -133,7 +134,7 @@ type lsOutput struct { Objects []lsObject } -func (api *UnixfsAPI) Ls(ctx context.Context, p iface.Path, opts ...caopts.UnixfsLsOption) (<-chan iface.DirEntry, error) { +func (api *UnixfsAPI) Ls(ctx context.Context, p path.Path, opts ...caopts.UnixfsLsOption) (<-chan iface.DirEntry, error) { options, err := caopts.UnixfsLsOptions(opts...) if err != nil { return nil, err From 11a990c7b12db59d9d03cbd9b28c2b8c75abfa26 Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 1 May 2019 13:13:59 -0700 Subject: [PATCH 0293/1212] api: expose headers via HttpApi, copy headers during request build This commit was moved from ipfs/go-ipfs-http-client@033befdef3f06a4a80fb9cf7c3afecc1a383700c --- client/httpapi/api.go | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/client/httpapi/api.go b/client/httpapi/api.go index c0eacd7cb..712801d53 100644 --- a/client/httpapi/api.go +++ b/client/httpapi/api.go @@ -4,6 +4,7 @@ import ( "errors" "fmt" "io/ioutil" + "net/http" gohttp "net/http" "os" "path" @@ -32,9 +33,9 @@ var ErrApiNotFound = errors.New("ipfs api address could not be found") // For interface docs see // https://godoc.org/github.com/ipfs/interface-go-ipfs-core#CoreAPI type HttpApi struct { - url string - httpcli gohttp.Client - + url string + httpcli gohttp.Client + Headers http.Header applyGlobal func(*RequestBuilder) } @@ -175,10 +176,17 @@ func (api *HttpApi) WithOptions(opts ...caopts.ApiOption) (iface.CoreAPI, error) } func (api *HttpApi) Request(command string, args ...string) *RequestBuilder { + var headers map[string]string + if api.Headers != nil { + for k := range api.Headers { + headers[k] = api.Headers.Get(k) + } + } return &RequestBuilder{ command: command, args: args, shell: api, + headers: headers, } } From d8c286bb15e628dbe7ddd2370c77ef02a5dc16b2 Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 1 May 2019 13:41:15 -0700 Subject: [PATCH 0294/1212] api: remove WithAuthorization, DirectAPI client, instantiate header map This commit was moved from ipfs/go-ipfs-http-client@9c7d495b03db4d130a8fd87217093beb33e6fdb7 --- client/httpapi/api.go | 32 ++++++-------------------------- 1 file changed, 6 insertions(+), 26 deletions(-) diff --git a/client/httpapi/api.go b/client/httpapi/api.go index 712801d53..ffcc85f2b 100644 --- a/client/httpapi/api.go +++ b/client/httpapi/api.go @@ -112,6 +112,7 @@ func NewApiWithClient(a ma.Multiaddr, c *gohttp.Client) (*HttpApi, error) { api := &HttpApi{ url: url, httpcli: *c, + Headers: make(map[string][]string), applyGlobal: func(*RequestBuilder) {}, } @@ -123,20 +124,11 @@ func NewApiWithClient(a ma.Multiaddr, c *gohttp.Client) (*HttpApi, error) { return api, nil } -// NewDirectAPIClient is used to instantiate a HttpApi client -// that connects to an endpoint which leverages additional http paths. -// -// If you need to connect to a IPFS HTTP API located at https://foo.bar/baz/api/v0 -// you should use NewDirectAPIClient. -func NewDirectAPIClient(url string) (*HttpApi, error) { +func NewURLApiWithClient(url string, c *gohttp.Client) (*HttpApi, error) { api := &HttpApi{ - url: url, - httpcli: gohttp.Client{ - Transport: &gohttp.Transport{ - Proxy: gohttp.ProxyFromEnvironment, - DisableKeepAlives: true, - }, - }, + url: url, + httpcli: *c, + Headers: make(map[string][]string), applyGlobal: func(*RequestBuilder) {}, } @@ -144,21 +136,9 @@ func NewDirectAPIClient(url string) (*HttpApi, error) { api.httpcli.CheckRedirect = func(_ *gohttp.Request, _ []*gohttp.Request) error { return fmt.Errorf("unexpected redirect") } - return api, nil } -// WithAuthorization is used to wrap an instance of HttpApi -// with an authenticated transport, such as JWT -func (api *HttpApi) WithAuthorization(header, value string) *HttpApi { - return &HttpApi{ - url: api.url, - httpcli: gohttp.Client{ - Transport: newAuthenticatedTransport(api.httpcli.Transport, header, value), - }, - } -} - func (api *HttpApi) WithOptions(opts ...caopts.ApiOption) (iface.CoreAPI, error) { options, err := caopts.ApiOptions(opts...) if err != nil { @@ -176,7 +156,7 @@ func (api *HttpApi) WithOptions(opts ...caopts.ApiOption) (iface.CoreAPI, error) } func (api *HttpApi) Request(command string, args ...string) *RequestBuilder { - var headers map[string]string + headers := make(map[string]string) if api.Headers != nil { for k := range api.Headers { headers[k] = api.Headers.Get(k) From 89600e62ce160cf5f3aa2a752b3806a273d1d142 Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 1 May 2019 13:41:37 -0700 Subject: [PATCH 0295/1212] api: add wip api test This commit was moved from ipfs/go-ipfs-http-client@2b48dd36ad170149bd4c62a4194587bf7c704f7e --- client/httpapi/api_test.go | 62 ++++++++++++++++++++++++++++---------- 1 file changed, 46 insertions(+), 16 deletions(-) diff --git a/client/httpapi/api_test.go b/client/httpapi/api_test.go index f1b1bf269..7b519ce7d 100644 --- a/client/httpapi/api_test.go +++ b/client/httpapi/api_test.go @@ -3,11 +3,13 @@ package httpapi import ( "context" "io/ioutil" + "net/http" gohttp "net/http" "os" "strconv" "sync" "testing" + "time" iface "github.com/ipfs/interface-go-ipfs-core" "github.com/ipfs/interface-go-ipfs-core/tests" @@ -212,23 +214,51 @@ func TestHttpApi(t *testing.T) { tests.TestApi(newNodeProvider(ctx))(t) } -func TestDirectAPI(t *testing.T) { - type args struct { - url, header, value string +func Test_NewURLApiWithClient(t *testing.T) { + t.Skip() + var ( + url = "127.0.0.1:65501" + headerToTest = "Test-Header" + expectedHeaderValue = "thisisaheadertest" + ) + server, err := testHTTPServer(url, headerToTest, expectedHeaderValue) + if err != nil { + t.Fatal(err) } - tests := []struct { - name string - args args - }{ - {"Success", args{"http://127.0.0.1:5001/foo/bar/api/v0", "Authorization", "Bearer token"}}, + defer server.Close() + go func() { + server.ListenAndServe() + }() + time.Sleep(time.Second * 2) + api, err := NewURLApiWithClient(url, &http.Client{ + Transport: &http.Transport{ + Proxy: http.ProxyFromEnvironment, + DisableKeepAlives: true, + }, + }) + if err != nil { + t.Fatal(err) } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - api, err := NewDirectAPIClient(tt.args.url) - if err != nil { - t.Fatal(err) - } - api = api.WithAuthorization(tt.args.header, tt.args.value) - }) + api.Headers.Set(headerToTest, expectedHeaderValue) + if _, err := api.Pin().Ls(context.Background()); err != nil { + t.Fatal(err) } } + +/// testHTTPServer spins up a test go http server +// used to check headers +func testHTTPServer(url, headerToTest, expectedHeaderValue string) (*http.Server, error) { + r := http.NewServeMux() + r.HandleFunc("/api/v0/pin/ls", func(w http.ResponseWriter, r *http.Request) { + val := r.Header.Get(headerToTest) + if val == expectedHeaderValue { + w.WriteHeader(400) + return + } + w.WriteHeader(200) + }) + return &http.Server{ + Handler: r, + Addr: url, + }, nil +} From efe3b6054e8f62191e74e6664adec06c306c06aa Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 1 May 2019 16:00:48 -0700 Subject: [PATCH 0296/1212] api: call NewURLApiWithClient from NewApiWithClient This commit was moved from ipfs/go-ipfs-http-client@aea6890f36001f15d24a4b373979bb1b9bf81483 --- client/httpapi/api.go | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/client/httpapi/api.go b/client/httpapi/api.go index ffcc85f2b..eb99230eb 100644 --- a/client/httpapi/api.go +++ b/client/httpapi/api.go @@ -109,19 +109,7 @@ func NewApiWithClient(a ma.Multiaddr, c *gohttp.Client) (*HttpApi, error) { } } - api := &HttpApi{ - url: url, - httpcli: *c, - Headers: make(map[string][]string), - applyGlobal: func(*RequestBuilder) {}, - } - - // We don't support redirects. - api.httpcli.CheckRedirect = func(_ *gohttp.Request, _ []*gohttp.Request) error { - return fmt.Errorf("unexpected redirect") - } - - return api, nil + return NewURLApiWithClient(url, c) } func NewURLApiWithClient(url string, c *gohttp.Client) (*HttpApi, error) { From fd5010bd2a852ea8fa3a2b08e199312fb3b71097 Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 1 May 2019 16:13:47 -0700 Subject: [PATCH 0297/1212] api: cleanup header and NewURLApiWithClient test This commit was moved from ipfs/go-ipfs-http-client@b8b55cb89a5dd830915f83e43e8afa7a01597905 --- client/httpapi/api_test.go | 46 +++++++++++++------------------------- 1 file changed, 15 insertions(+), 31 deletions(-) diff --git a/client/httpapi/api_test.go b/client/httpapi/api_test.go index 52fa67d0e..fadd9663e 100644 --- a/client/httpapi/api_test.go +++ b/client/httpapi/api_test.go @@ -5,13 +5,14 @@ import ( "io/ioutil" "net/http" gohttp "net/http" + "net/http/httptest" "os" "strconv" "sync" "testing" "time" - "github.com/ipfs/interface-go-ipfs-core" + iface "github.com/ipfs/interface-go-ipfs-core" "github.com/ipfs/interface-go-ipfs-core/path" "github.com/ipfs/interface-go-ipfs-core/tests" @@ -212,23 +213,24 @@ func TestHttpApi(t *testing.T) { tests.TestApi(newNodeProvider(ctx))(t) } -func Test_NewURLApiWithClient(t *testing.T) { - t.Skip() +func Test_NewURLApiWithClient_With_Headers(t *testing.T) { var ( - url = "127.0.0.1:65501" headerToTest = "Test-Header" expectedHeaderValue = "thisisaheadertest" ) - server, err := testHTTPServer(url, headerToTest, expectedHeaderValue) - if err != nil { - t.Fatal(err) - } - defer server.Close() - go func() { - server.ListenAndServe() - }() + ts := httptest.NewServer( + http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + val := r.Header.Get(headerToTest) + if val == expectedHeaderValue { + w.WriteHeader(400) + return + } + w.WriteHeader(200) + }), + ) + defer ts.Close() time.Sleep(time.Second * 2) - api, err := NewURLApiWithClient(url, &http.Client{ + api, err := NewURLApiWithClient(ts.URL, &http.Client{ Transport: &http.Transport{ Proxy: http.ProxyFromEnvironment, DisableKeepAlives: true, @@ -242,21 +244,3 @@ func Test_NewURLApiWithClient(t *testing.T) { t.Fatal(err) } } - -/// testHTTPServer spins up a test go http server -// used to check headers -func testHTTPServer(url, headerToTest, expectedHeaderValue string) (*http.Server, error) { - r := http.NewServeMux() - r.HandleFunc("/api/v0/pin/ls", func(w http.ResponseWriter, r *http.Request) { - val := r.Header.Get(headerToTest) - if val == expectedHeaderValue { - w.WriteHeader(400) - return - } - w.WriteHeader(200) - }) - return &http.Server{ - Handler: r, - Addr: url, - }, nil -} From daf1b72809a3d1af819d7ff44aabcc6bc6471fe8 Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 1 May 2019 17:19:35 -0700 Subject: [PATCH 0298/1212] api: fix failing test This commit was moved from ipfs/go-ipfs-http-client@ea507216d821455c351440ba33775f564ea18ea8 --- client/httpapi/api_test.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/client/httpapi/api_test.go b/client/httpapi/api_test.go index fadd9663e..5f012b476 100644 --- a/client/httpapi/api_test.go +++ b/client/httpapi/api_test.go @@ -8,6 +8,7 @@ import ( "net/http/httptest" "os" "strconv" + "strings" "sync" "testing" "time" @@ -221,15 +222,14 @@ func Test_NewURLApiWithClient_With_Headers(t *testing.T) { ts := httptest.NewServer( http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { val := r.Header.Get(headerToTest) - if val == expectedHeaderValue { + if val != expectedHeaderValue { w.WriteHeader(400) return } - w.WriteHeader(200) + http.ServeContent(w, r, "", time.Now(), strings.NewReader("test")) }), ) defer ts.Close() - time.Sleep(time.Second * 2) api, err := NewURLApiWithClient(ts.URL, &http.Client{ Transport: &http.Transport{ Proxy: http.ProxyFromEnvironment, @@ -240,7 +240,7 @@ func Test_NewURLApiWithClient_With_Headers(t *testing.T) { t.Fatal(err) } api.Headers.Set(headerToTest, expectedHeaderValue) - if _, err := api.Pin().Ls(context.Background()); err != nil { + if err := api.Pin().Rm(context.Background(), path.New("/ipfs/QmS4ustL54uo8FzR9455qaxZwuMiUhyvMcX9Ba8nUH4uVv")); err != nil { t.Fatal(err) } } From 8b9e189169b51c46956a18e08f9dc7bc668401b4 Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 1 May 2019 19:14:15 -0700 Subject: [PATCH 0299/1212] remove unused transport.go file This commit was moved from ipfs/go-ipfs-http-client@320130421f4727d72d68a3c6a5c0e633e1dabc38 --- client/httpapi/transport.go | 21 --------------------- 1 file changed, 21 deletions(-) delete mode 100644 client/httpapi/transport.go diff --git a/client/httpapi/transport.go b/client/httpapi/transport.go deleted file mode 100644 index 3fb0e6e00..000000000 --- a/client/httpapi/transport.go +++ /dev/null @@ -1,21 +0,0 @@ -package httpapi - -import "net/http" - -type transport struct { - header, value string - httptr http.RoundTripper -} - -func newAuthenticatedTransport(tr http.RoundTripper, header, value string) *transport { - return &transport{ - header: header, - value: value, - httptr: tr, - } -} - -func (t *transport) RoundTrip(req *http.Request) (*http.Response, error) { - req.Header.Set(t.header, t.value) - return t.httptr.RoundTrip(req) -} From ce49669839c31312bbcff89cda410c46a842a026 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Tue, 7 May 2019 00:57:21 -0700 Subject: [PATCH 0300/1212] switch to base32 cidv1 by default This commit was moved from ipfs/interface-go-ipfs-core@6287246646853656271cbd190acab071950d4060 This commit was moved from ipfs/boxo@763b3d8a00d19fd1ba9d5b5b8825cbd7a7f01d1e --- core/coreiface/tests/block.go | 4 ++-- core/coreiface/tests/dag.go | 6 +++--- core/coreiface/tests/unixfs.go | 24 ++++++++++++------------ 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/core/coreiface/tests/block.go b/core/coreiface/tests/block.go index 961ac722d..34e47e90c 100644 --- a/core/coreiface/tests/block.go +++ b/core/coreiface/tests/block.go @@ -61,7 +61,7 @@ func (tp *provider) TestBlockPutFormat(t *testing.T) { t.Fatal(err) } - if res.Path().Cid().String() != "zdpuAn4amuLWo8Widi5v6VQpuo2dnpnwbVE3oB6qqs7mDSeoa" { + if res.Path().Cid().String() != "bafyreiayl6g3gitr7ys7kyng7sjywlrgimdoymco3jiyab6rozecmoazne" { t.Errorf("got wrong cid: %s", res.Path().Cid().String()) } } @@ -79,7 +79,7 @@ func (tp *provider) TestBlockPutHash(t *testing.T) { t.Fatal(err) } - if res.Path().Cid().String() != "zBurKB9YZkcDf6xa53WBE8CFX4ydVqAyf9KPXBFZt5stJzEstaS8Hukkhu4gwpMtc1xHNDbzP7sPtQKyWsP3C8fbhkmrZ" { + if res.Path().Cid().String() != "bafyb2qgdh7w6dcq24u65xbtdoehyavegnpvxcqce7ttvs6ielgmwdfxrahmu37d33atik57x5y6s7d7qz32aasuwgirh3ocn6ywswqdifvu6e" { t.Errorf("got wrong cid: %s", res.Path().Cid().String()) } } diff --git a/core/coreiface/tests/dag.go b/core/coreiface/tests/dag.go index fe92641f4..0bb3aa487 100644 --- a/core/coreiface/tests/dag.go +++ b/core/coreiface/tests/dag.go @@ -58,7 +58,7 @@ func (tp *provider) TestPut(t *testing.T) { t.Fatal(err) } - if nd.Cid().String() != "zdpuAqckYF3ToF3gcJNxPZXmnmGuXd3gxHCXhq81HGxBejEvv" { + if nd.Cid().String() != "bafyreicnga62zhxnmnlt6ymq5hcbsg7gdhqdu6z4ehu3wpjhvqnflfy6nm" { t.Errorf("got wrong cid: %s", nd.Cid().String()) } } @@ -81,7 +81,7 @@ func (tp *provider) TestPutWithHash(t *testing.T) { t.Fatal(err) } - if nd.Cid().String() != "z5hRLNd2sv4z1c" { + if nd.Cid().String() != "bafyqabtfjbswy3dp" { t.Errorf("got wrong cid: %s", nd.Cid().String()) } } @@ -179,7 +179,7 @@ func (tp *provider) TestBatch(t *testing.T) { t.Fatal(err) } - if nd.Cid().String() != "zdpuAqckYF3ToF3gcJNxPZXmnmGuXd3gxHCXhq81HGxBejEvv" { + if nd.Cid().String() != "bafyreicnga62zhxnmnlt6ymq5hcbsg7gdhqdu6z4ehu3wpjhvqnflfy6nm" { t.Errorf("got wrong cid: %s", nd.Cid().String()) } diff --git a/core/coreiface/tests/unixfs.go b/core/coreiface/tests/unixfs.go index 38fab7cd8..c810167e8 100644 --- a/core/coreiface/tests/unixfs.go +++ b/core/coreiface/tests/unixfs.go @@ -170,20 +170,20 @@ func (tp *provider) TestAdd(t *testing.T) { { name: "addCidV1", data: strFile(helloStr), - path: "/ipfs/zb2rhdhmJjJZs9qkhQCpCQ7VREFkqWw3h1r8utjVvQugwHPFd", + path: "/ipfs/bafkreidi4zlleupgp2bvrpxyja5lbvi4mym7hz5bvhyoowby2qp7g2hxfa", opts: []options.UnixfsAddOption{options.Unixfs.CidVersion(1)}, }, { name: "addCidV1NoLeaves", data: strFile(helloStr), - path: "/ipfs/zdj7WY4GbN8NDbTW1dfCShAQNVovams2xhq9hVCx5vXcjvT8g", + path: "/ipfs/bafybeibhbcn7k7o2m6xsqkrlfiokod3nxwe47viteynhruh6uqx7hvkjfu", opts: []options.UnixfsAddOption{options.Unixfs.CidVersion(1), options.Unixfs.RawLeaves(false)}, }, // Non sha256 hash vs CID { name: "addCidSha3", data: strFile(helloStr), - path: "/ipfs/zb2wwnYtXBxpndNABjtYxWAPt3cwWNRnc11iT63fvkYV78iRb", + path: "/ipfs/bafkrmichjflejeh6aren53o7pig7zk3m3vxqcoc2i5dv326k3x6obh7jry", opts: []options.UnixfsAddOption{options.Unixfs.Hash(mh.SHA3_256)}, }, { @@ -196,25 +196,25 @@ func (tp *provider) TestAdd(t *testing.T) { { name: "addInline", data: strFile(helloStr), - path: "/ipfs/zaYomJdLndMku8P9LHngHB5w2CQ7NenLbv", + path: "/ipfs/bafyaafikcmeaeeqnnbswy3dpfqqho33snrsccgan", opts: []options.UnixfsAddOption{options.Unixfs.Inline(true)}, }, { name: "addInlineLimit", data: strFile(helloStr), - path: "/ipfs/zaYomJdLndMku8P9LHngHB5w2CQ7NenLbv", + path: "/ipfs/bafyaafikcmeaeeqnnbswy3dpfqqho33snrsccgan", opts: []options.UnixfsAddOption{options.Unixfs.InlineLimit(32), options.Unixfs.Inline(true)}, }, { name: "addInlineZero", data: strFile(""), - path: "/ipfs/z2yYDV", + path: "/ipfs/bafkqaaa", opts: []options.UnixfsAddOption{options.Unixfs.InlineLimit(0), options.Unixfs.Inline(true), options.Unixfs.RawLeaves(true)}, }, { //TODO: after coreapi add is used in `ipfs add`, consider making this default for inline name: "addInlineRaw", data: strFile(helloStr), - path: "/ipfs/zj7Gr8AcBreqGEfrnR5kPFe", + path: "/ipfs/bafkqadlimvwgy3zmeb3w64tmmqqq", opts: []options.UnixfsAddOption{options.Unixfs.InlineLimit(32), options.Unixfs.Inline(true), options.Unixfs.RawLeaves(true)}, }, // Chunker / Layout @@ -291,20 +291,20 @@ func (tp *provider) TestAdd(t *testing.T) { { name: "simpleNoCopy", data: realFile, - path: "/ipfs/zb2rhdhmJjJZs9qkhQCpCQ7VREFkqWw3h1r8utjVvQugwHPFd", + path: "/ipfs/bafkreidi4zlleupgp2bvrpxyja5lbvi4mym7hz5bvhyoowby2qp7g2hxfa", opts: []options.UnixfsAddOption{options.Unixfs.Nocopy(true)}, }, { name: "noCopyNoRaw", data: realFile, - path: "/ipfs/zb2rhdhmJjJZs9qkhQCpCQ7VREFkqWw3h1r8utjVvQugwHPFd", + path: "/ipfs/bafkreidi4zlleupgp2bvrpxyja5lbvi4mym7hz5bvhyoowby2qp7g2hxfa", opts: []options.UnixfsAddOption{options.Unixfs.Nocopy(true), options.Unixfs.RawLeaves(false)}, err: "nocopy option requires '--raw-leaves' to be enabled as well", }, { name: "noCopyNoPath", data: strFile(helloStr), - path: "/ipfs/zb2rhdhmJjJZs9qkhQCpCQ7VREFkqWw3h1r8utjVvQugwHPFd", + path: "/ipfs/bafkreidi4zlleupgp2bvrpxyja5lbvi4mym7hz5bvhyoowby2qp7g2hxfa", opts: []options.UnixfsAddOption{options.Unixfs.Nocopy(true)}, err: helpers.ErrMissingFsRef.Error(), }, @@ -312,9 +312,9 @@ func (tp *provider) TestAdd(t *testing.T) { { name: "simpleAddEvent", data: strFile(helloStr), - path: "/ipfs/zb2rhdhmJjJZs9qkhQCpCQ7VREFkqWw3h1r8utjVvQugwHPFd", + path: "/ipfs/bafkreidi4zlleupgp2bvrpxyja5lbvi4mym7hz5bvhyoowby2qp7g2hxfa", events: []coreiface.AddEvent{ - {Name: "zb2rhdhmJjJZs9qkhQCpCQ7VREFkqWw3h1r8utjVvQugwHPFd", Path: p("zb2rhdhmJjJZs9qkhQCpCQ7VREFkqWw3h1r8utjVvQugwHPFd"), Size: strconv.Itoa(len(helloStr))}, + {Name: "bafkreidi4zlleupgp2bvrpxyja5lbvi4mym7hz5bvhyoowby2qp7g2hxfa", Path: p("bafkreidi4zlleupgp2bvrpxyja5lbvi4mym7hz5bvhyoowby2qp7g2hxfa"), Size: strconv.Itoa(len(helloStr))}, }, opts: []options.UnixfsAddOption{options.Unixfs.RawLeaves(true)}, }, From 8d953a7359c488cde5299ca704594bd8e1349ab2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 10 May 2019 15:38:20 +0200 Subject: [PATCH 0301/1212] Use interface for RequestBuilder This commit was moved from ipfs/go-ipfs-http-client@0534b7ca8319329459c505a546f3025862a735f5 --- client/httpapi/api.go | 10 ++++----- client/httpapi/requestbuilder.go | 36 ++++++++++++++++++++++---------- client/httpapi/response.go | 2 +- 3 files changed, 31 insertions(+), 17 deletions(-) diff --git a/client/httpapi/api.go b/client/httpapi/api.go index eb99230eb..5c2eb76d6 100644 --- a/client/httpapi/api.go +++ b/client/httpapi/api.go @@ -36,7 +36,7 @@ type HttpApi struct { url string httpcli gohttp.Client Headers http.Header - applyGlobal func(*RequestBuilder) + applyGlobal func(*requestBuilder) } // NewLocalApi tries to construct new HttpApi instance communicating with local @@ -117,7 +117,7 @@ func NewURLApiWithClient(url string, c *gohttp.Client) (*HttpApi, error) { url: url, httpcli: *c, Headers: make(map[string][]string), - applyGlobal: func(*RequestBuilder) {}, + applyGlobal: func(*requestBuilder) {}, } // We don't support redirects. @@ -134,7 +134,7 @@ func (api *HttpApi) WithOptions(opts ...caopts.ApiOption) (iface.CoreAPI, error) } subApi := *api - subApi.applyGlobal = func(req *RequestBuilder) { + subApi.applyGlobal = func(req *requestBuilder) { if options.Offline { req.Option("offline", options.Offline) } @@ -143,14 +143,14 @@ func (api *HttpApi) WithOptions(opts ...caopts.ApiOption) (iface.CoreAPI, error) return &subApi, nil } -func (api *HttpApi) Request(command string, args ...string) *RequestBuilder { +func (api *HttpApi) Request(command string, args ...string) RequestBuilder { headers := make(map[string]string) if api.Headers != nil { for k := range api.Headers { headers[k] = api.Headers.Get(k) } } - return &RequestBuilder{ + return &requestBuilder{ command: command, args: args, shell: api, diff --git a/client/httpapi/requestbuilder.go b/client/httpapi/requestbuilder.go index 2ffed7a0a..7012a8935 100644 --- a/client/httpapi/requestbuilder.go +++ b/client/httpapi/requestbuilder.go @@ -12,8 +12,20 @@ import ( "github.com/ipfs/go-ipfs-files" ) -// RequestBuilder is an IPFS commands request builder. -type RequestBuilder struct { +type RequestBuilder interface { + Arguments(args ...string) RequestBuilder + BodyString(body string) RequestBuilder + BodyBytes(body []byte) RequestBuilder + Body(body io.Reader) RequestBuilder + FileBody(body io.Reader) RequestBuilder + Option(key string, value interface{}) RequestBuilder + Header(name, value string) RequestBuilder + Send(ctx context.Context) (*Response, error) + Exec(ctx context.Context, res interface{}) error +} + +// requestBuilder is an IPFS commands request builder. +type requestBuilder struct { command string args []string opts map[string]string @@ -24,29 +36,29 @@ type RequestBuilder struct { } // Arguments adds the arguments to the args. -func (r *RequestBuilder) Arguments(args ...string) *RequestBuilder { +func (r *requestBuilder) Arguments(args ...string) RequestBuilder { r.args = append(r.args, args...) return r } // BodyString sets the request body to the given string. -func (r *RequestBuilder) BodyString(body string) *RequestBuilder { +func (r *requestBuilder) BodyString(body string) RequestBuilder { return r.Body(strings.NewReader(body)) } // BodyBytes sets the request body to the given buffer. -func (r *RequestBuilder) BodyBytes(body []byte) *RequestBuilder { +func (r *requestBuilder) BodyBytes(body []byte) RequestBuilder { return r.Body(bytes.NewReader(body)) } // Body sets the request body to the given reader. -func (r *RequestBuilder) Body(body io.Reader) *RequestBuilder { +func (r *requestBuilder) Body(body io.Reader) RequestBuilder { r.body = body return r } // FileBody sets the request body to the given reader wrapped into multipartreader. -func (r *RequestBuilder) FileBody(body io.Reader) *RequestBuilder { +func (r *requestBuilder) FileBody(body io.Reader) RequestBuilder { pr, _ := files.NewReaderPathFile("/dev/stdin", ioutil.NopCloser(body), nil) d := files.NewMapDirectory(map[string]files.Node{"": pr}) r.body = files.NewMultiFileReader(d, false) @@ -55,7 +67,7 @@ func (r *RequestBuilder) FileBody(body io.Reader) *RequestBuilder { } // Option sets the given option. -func (r *RequestBuilder) Option(key string, value interface{}) *RequestBuilder { +func (r *requestBuilder) Option(key string, value interface{}) RequestBuilder { var s string switch v := value.(type) { case bool: @@ -76,7 +88,7 @@ func (r *RequestBuilder) Option(key string, value interface{}) *RequestBuilder { } // Header sets the given header. -func (r *RequestBuilder) Header(name, value string) *RequestBuilder { +func (r *requestBuilder) Header(name, value string) RequestBuilder { if r.headers == nil { r.headers = make(map[string]string, 1) } @@ -85,7 +97,7 @@ func (r *RequestBuilder) Header(name, value string) *RequestBuilder { } // Send sends the request and return the response. -func (r *RequestBuilder) Send(ctx context.Context) (*Response, error) { +func (r *requestBuilder) Send(ctx context.Context) (*Response, error) { r.shell.applyGlobal(r) req := NewRequest(ctx, r.shell.url, r.command, r.args...) @@ -96,7 +108,7 @@ func (r *RequestBuilder) Send(ctx context.Context) (*Response, error) { } // Exec sends the request a request and decodes the response. -func (r *RequestBuilder) Exec(ctx context.Context, res interface{}) error { +func (r *requestBuilder) Exec(ctx context.Context, res interface{}) error { httpRes, err := r.Send(ctx) if err != nil { return err @@ -112,3 +124,5 @@ func (r *RequestBuilder) Exec(ctx context.Context, res interface{}) error { return httpRes.decode(res) } + +var _ RequestBuilder = &requestBuilder{} diff --git a/client/httpapi/response.go b/client/httpapi/response.go index 2d6af49d2..db22a66fa 100644 --- a/client/httpapi/response.go +++ b/client/httpapi/response.go @@ -97,7 +97,7 @@ func (r *Request) Send(c *http.Client) (*Response, error) { req = req.WithContext(r.Ctx) - // Add any headers that were supplied via the RequestBuilder. + // Add any headers that were supplied via the requestBuilder. for k, v := range r.Headers { req.Header.Add(k, v) } From 79958dc097b5b6399e4b4e0af859e711d0f6726e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 17 May 2019 18:57:15 +0200 Subject: [PATCH 0302/1212] tests: expose TestSuite This commit was moved from ipfs/interface-go-ipfs-core@6fe8577a835a24bf8a38de0d5ee9d1fe6ca9e913 This commit was moved from ipfs/boxo@3d72707f576f881c01bc5fc9ffb97ece3456c014 --- core/coreiface/tests/api.go | 22 ++++++++++++---------- core/coreiface/tests/block.go | 16 ++++++++-------- core/coreiface/tests/dag.go | 12 ++++++------ core/coreiface/tests/dht.go | 8 ++++---- core/coreiface/tests/key.go | 34 +++++++++++++++++----------------- core/coreiface/tests/name.go | 8 ++++---- core/coreiface/tests/object.go | 26 +++++++++++++------------- core/coreiface/tests/path.go | 14 +++++++------- core/coreiface/tests/pin.go | 8 ++++---- core/coreiface/tests/pubsub.go | 4 ++-- core/coreiface/tests/unixfs.go | 26 +++++++++++++------------- 11 files changed, 90 insertions(+), 88 deletions(-) diff --git a/core/coreiface/tests/api.go b/core/coreiface/tests/api.go index 5e7c1f541..1af3a83b3 100644 --- a/core/coreiface/tests/api.go +++ b/core/coreiface/tests/api.go @@ -11,7 +11,7 @@ import ( var apiNotImplemented = errors.New("api not implemented") -func (tp *provider) makeAPI(ctx context.Context) (coreiface.CoreAPI, error) { +func (tp *TestSuite) makeAPI(ctx context.Context) (coreiface.CoreAPI, error) { api, err := tp.MakeAPISwarm(ctx, false, 1) if err != nil { return nil, err @@ -25,17 +25,19 @@ type Provider interface { MakeAPISwarm(ctx context.Context, fullIdentity bool, n int) ([]coreiface.CoreAPI, error) } -func (tp *provider) MakeAPISwarm(ctx context.Context, fullIdentity bool, n int) ([]coreiface.CoreAPI, error) { - tp.apis <- 1 - go func() { - <-ctx.Done() - tp.apis <- -1 - }() +func (tp *TestSuite) MakeAPISwarm(ctx context.Context, fullIdentity bool, n int) ([]coreiface.CoreAPI, error) { + if tp.apis != nil { + tp.apis <- 1 + go func() { + <-ctx.Done() + tp.apis <- -1 + }() + } return tp.Provider.MakeAPISwarm(ctx, fullIdentity, n) } -type provider struct { +type TestSuite struct { Provider apis chan int @@ -55,7 +57,7 @@ func TestApi(p Provider) func(t *testing.T) { } }() - tp := &provider{Provider: p, apis: apis} + tp := &TestSuite{Provider: p, apis: apis} return func(t *testing.T) { t.Run("Block", tp.TestBlock) @@ -80,7 +82,7 @@ func TestApi(p Provider) func(t *testing.T) { } } -func (tp *provider) hasApi(t *testing.T, tf func(coreiface.CoreAPI) error) { +func (tp *TestSuite) hasApi(t *testing.T, tf func(coreiface.CoreAPI) error) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() api, err := tp.makeAPI(ctx) diff --git a/core/coreiface/tests/block.go b/core/coreiface/tests/block.go index 34e47e90c..6b648f394 100644 --- a/core/coreiface/tests/block.go +++ b/core/coreiface/tests/block.go @@ -13,7 +13,7 @@ import ( mh "github.com/multiformats/go-multihash" ) -func (tp *provider) TestBlock(t *testing.T) { +func (tp *TestSuite) TestBlock(t *testing.T) { tp.hasApi(t, func(api coreiface.CoreAPI) error { if api.Block() == nil { return apiNotImplemented @@ -30,7 +30,7 @@ func (tp *provider) TestBlock(t *testing.T) { t.Run("TestBlockPin", tp.TestBlockPin) } -func (tp *provider) TestBlockPut(t *testing.T) { +func (tp *TestSuite) TestBlockPut(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() api, err := tp.makeAPI(ctx) @@ -48,7 +48,7 @@ func (tp *provider) TestBlockPut(t *testing.T) { } } -func (tp *provider) TestBlockPutFormat(t *testing.T) { +func (tp *TestSuite) TestBlockPutFormat(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() api, err := tp.makeAPI(ctx) @@ -66,7 +66,7 @@ func (tp *provider) TestBlockPutFormat(t *testing.T) { } } -func (tp *provider) TestBlockPutHash(t *testing.T) { +func (tp *TestSuite) TestBlockPutHash(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() api, err := tp.makeAPI(ctx) @@ -84,7 +84,7 @@ func (tp *provider) TestBlockPutHash(t *testing.T) { } } -func (tp *provider) TestBlockGet(t *testing.T) { +func (tp *TestSuite) TestBlockGet(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() api, err := tp.makeAPI(ctx) @@ -122,7 +122,7 @@ func (tp *provider) TestBlockGet(t *testing.T) { } } -func (tp *provider) TestBlockRm(t *testing.T) { +func (tp *TestSuite) TestBlockRm(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() api, err := tp.makeAPI(ctx) @@ -176,7 +176,7 @@ func (tp *provider) TestBlockRm(t *testing.T) { } } -func (tp *provider) TestBlockStat(t *testing.T) { +func (tp *TestSuite) TestBlockStat(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() api, err := tp.makeAPI(ctx) @@ -203,7 +203,7 @@ func (tp *provider) TestBlockStat(t *testing.T) { } } -func (tp *provider) TestBlockPin(t *testing.T) { +func (tp *TestSuite) TestBlockPin(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() api, err := tp.makeAPI(ctx) diff --git a/core/coreiface/tests/dag.go b/core/coreiface/tests/dag.go index 0bb3aa487..1ccd45d59 100644 --- a/core/coreiface/tests/dag.go +++ b/core/coreiface/tests/dag.go @@ -15,7 +15,7 @@ import ( mh "github.com/multiformats/go-multihash" ) -func (tp *provider) TestDag(t *testing.T) { +func (tp *TestSuite) TestDag(t *testing.T) { tp.hasApi(t, func(api coreiface.CoreAPI) error { if api.Dag() == nil { return apiNotImplemented @@ -40,7 +40,7 @@ var ( } ) -func (tp *provider) TestPut(t *testing.T) { +func (tp *TestSuite) TestPut(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() api, err := tp.makeAPI(ctx) @@ -63,7 +63,7 @@ func (tp *provider) TestPut(t *testing.T) { } } -func (tp *provider) TestPutWithHash(t *testing.T) { +func (tp *TestSuite) TestPutWithHash(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() api, err := tp.makeAPI(ctx) @@ -86,7 +86,7 @@ func (tp *provider) TestPutWithHash(t *testing.T) { } } -func (tp *provider) TestDagPath(t *testing.T) { +func (tp *TestSuite) TestDagPath(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() api, err := tp.makeAPI(ctx) @@ -131,7 +131,7 @@ func (tp *provider) TestDagPath(t *testing.T) { } } -func (tp *provider) TestTree(t *testing.T) { +func (tp *TestSuite) TestTree(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() api, err := tp.makeAPI(ctx) @@ -166,7 +166,7 @@ func (tp *provider) TestTree(t *testing.T) { } } -func (tp *provider) TestBatch(t *testing.T) { +func (tp *TestSuite) TestBatch(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() api, err := tp.makeAPI(ctx) diff --git a/core/coreiface/tests/dht.go b/core/coreiface/tests/dht.go index 5482b50b1..33b4ff14c 100644 --- a/core/coreiface/tests/dht.go +++ b/core/coreiface/tests/dht.go @@ -9,7 +9,7 @@ import ( "github.com/ipfs/interface-go-ipfs-core/options" ) -func (tp *provider) TestDht(t *testing.T) { +func (tp *TestSuite) TestDht(t *testing.T) { tp.hasApi(t, func(api iface.CoreAPI) error { if api.Dht() == nil { return apiNotImplemented @@ -22,7 +22,7 @@ func (tp *provider) TestDht(t *testing.T) { t.Run("TestDhtProvide", tp.TestDhtProvide) } -func (tp *provider) TestDhtFindPeer(t *testing.T) { +func (tp *TestSuite) TestDhtFindPeer(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() apis, err := tp.MakeAPISwarm(ctx, true, 5) @@ -75,7 +75,7 @@ func (tp *provider) TestDhtFindPeer(t *testing.T) { } } -func (tp *provider) TestDhtFindProviders(t *testing.T) { +func (tp *TestSuite) TestDhtFindProviders(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() apis, err := tp.MakeAPISwarm(ctx, true, 5) @@ -105,7 +105,7 @@ func (tp *provider) TestDhtFindProviders(t *testing.T) { } } -func (tp *provider) TestDhtProvide(t *testing.T) { +func (tp *TestSuite) TestDhtProvide(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() apis, err := tp.MakeAPISwarm(ctx, true, 5) diff --git a/core/coreiface/tests/key.go b/core/coreiface/tests/key.go index 7ff5f3330..e3461f971 100644 --- a/core/coreiface/tests/key.go +++ b/core/coreiface/tests/key.go @@ -9,7 +9,7 @@ import ( opt "github.com/ipfs/interface-go-ipfs-core/options" ) -func (tp *provider) TestKey(t *testing.T) { +func (tp *TestSuite) TestKey(t *testing.T) { tp.hasApi(t, func(api iface.CoreAPI) error { if api.Key() == nil { return apiNotImplemented @@ -35,7 +35,7 @@ func (tp *provider) TestKey(t *testing.T) { t.Run("TestRemove", tp.TestRemove) } -func (tp *provider) TestListSelf(t *testing.T) { +func (tp *TestSuite) TestListSelf(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() api, err := tp.makeAPI(ctx) @@ -69,7 +69,7 @@ func (tp *provider) TestListSelf(t *testing.T) { } } -func (tp *provider) TestRenameSelf(t *testing.T) { +func (tp *TestSuite) TestRenameSelf(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() api, err := tp.makeAPI(ctx) @@ -97,7 +97,7 @@ func (tp *provider) TestRenameSelf(t *testing.T) { } } -func (tp *provider) TestRemoveSelf(t *testing.T) { +func (tp *TestSuite) TestRemoveSelf(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() api, err := tp.makeAPI(ctx) @@ -116,7 +116,7 @@ func (tp *provider) TestRemoveSelf(t *testing.T) { } } -func (tp *provider) TestGenerate(t *testing.T) { +func (tp *TestSuite) TestGenerate(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() api, err := tp.makeAPI(ctx) @@ -139,7 +139,7 @@ func (tp *provider) TestGenerate(t *testing.T) { } } -func (tp *provider) TestGenerateSize(t *testing.T) { +func (tp *TestSuite) TestGenerateSize(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() api, err := tp.makeAPI(ctx) @@ -162,7 +162,7 @@ func (tp *provider) TestGenerateSize(t *testing.T) { } } -func (tp *provider) TestGenerateType(t *testing.T) { +func (tp *TestSuite) TestGenerateType(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() t.Skip("disabled until libp2p/specs#111 is fixed") @@ -188,7 +188,7 @@ func (tp *provider) TestGenerateType(t *testing.T) { } } -func (tp *provider) TestGenerateExisting(t *testing.T) { +func (tp *TestSuite) TestGenerateExisting(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() api, err := tp.makeAPI(ctx) @@ -221,7 +221,7 @@ func (tp *provider) TestGenerateExisting(t *testing.T) { } } -func (tp *provider) TestList(t *testing.T) { +func (tp *TestSuite) TestList(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() api, err := tp.makeAPI(ctx) @@ -267,7 +267,7 @@ func (tp *provider) TestList(t *testing.T) { } } -func (tp *provider) TestRename(t *testing.T) { +func (tp *TestSuite) TestRename(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() api, err := tp.makeAPI(ctx) @@ -296,7 +296,7 @@ func (tp *provider) TestRename(t *testing.T) { } } -func (tp *provider) TestRenameToSelf(t *testing.T) { +func (tp *TestSuite) TestRenameToSelf(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() api, err := tp.makeAPI(ctx) @@ -320,7 +320,7 @@ func (tp *provider) TestRenameToSelf(t *testing.T) { } } -func (tp *provider) TestRenameToSelfForce(t *testing.T) { +func (tp *TestSuite) TestRenameToSelfForce(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() api, err := tp.makeAPI(ctx) @@ -344,7 +344,7 @@ func (tp *provider) TestRenameToSelfForce(t *testing.T) { } } -func (tp *provider) TestRenameOverwriteNoForce(t *testing.T) { +func (tp *TestSuite) TestRenameOverwriteNoForce(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() api, err := tp.makeAPI(ctx) @@ -374,7 +374,7 @@ func (tp *provider) TestRenameOverwriteNoForce(t *testing.T) { } } -func (tp *provider) TestRenameOverwrite(t *testing.T) { +func (tp *TestSuite) TestRenameOverwrite(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() api, err := tp.makeAPI(ctx) @@ -413,7 +413,7 @@ func (tp *provider) TestRenameOverwrite(t *testing.T) { } } -func (tp *provider) TestRenameSameNameNoForce(t *testing.T) { +func (tp *TestSuite) TestRenameSameNameNoForce(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() api, err := tp.makeAPI(ctx) @@ -442,7 +442,7 @@ func (tp *provider) TestRenameSameNameNoForce(t *testing.T) { } } -func (tp *provider) TestRenameSameName(t *testing.T) { +func (tp *TestSuite) TestRenameSameName(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() api, err := tp.makeAPI(ctx) @@ -471,7 +471,7 @@ func (tp *provider) TestRenameSameName(t *testing.T) { } } -func (tp *provider) TestRemove(t *testing.T) { +func (tp *TestSuite) TestRemove(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() api, err := tp.makeAPI(ctx) diff --git a/core/coreiface/tests/name.go b/core/coreiface/tests/name.go index efaf1d3ae..31a5c1466 100644 --- a/core/coreiface/tests/name.go +++ b/core/coreiface/tests/name.go @@ -16,7 +16,7 @@ import ( opt "github.com/ipfs/interface-go-ipfs-core/options" ) -func (tp *provider) TestName(t *testing.T) { +func (tp *TestSuite) TestName(t *testing.T) { tp.hasApi(t, func(api coreiface.CoreAPI) error { if api.Name() == nil { return apiNotImplemented @@ -39,7 +39,7 @@ func appendPath(p path.Path, sub string) path.Path { return path.New(gopath.Join(p.String(), sub)) } -func (tp *provider) TestPublishResolve(t *testing.T) { +func (tp *TestSuite) TestPublishResolve(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() init := func() (coreiface.CoreAPI, path.Path) { @@ -188,7 +188,7 @@ func (tp *provider) TestPublishResolve(t *testing.T) { }) } -func (tp *provider) TestBasicPublishResolveKey(t *testing.T) { +func (tp *TestSuite) TestBasicPublishResolveKey(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() apis, err := tp.MakeAPISwarm(ctx, true, 5) @@ -230,7 +230,7 @@ func (tp *provider) TestBasicPublishResolveKey(t *testing.T) { } } -func (tp *provider) TestBasicPublishResolveTimeout(t *testing.T) { +func (tp *TestSuite) TestBasicPublishResolveTimeout(t *testing.T) { t.Skip("ValidTime doesn't appear to work at this time resolution") ctx, cancel := context.WithCancel(context.Background()) diff --git a/core/coreiface/tests/object.go b/core/coreiface/tests/object.go index 8682a2edc..2e066ca71 100644 --- a/core/coreiface/tests/object.go +++ b/core/coreiface/tests/object.go @@ -12,7 +12,7 @@ import ( opt "github.com/ipfs/interface-go-ipfs-core/options" ) -func (tp *provider) TestObject(t *testing.T) { +func (tp *TestSuite) TestObject(t *testing.T) { tp.hasApi(t, func(api iface.CoreAPI) error { if api.Object() == nil { return apiNotImplemented @@ -34,7 +34,7 @@ func (tp *provider) TestObject(t *testing.T) { t.Run("TestDiffTest", tp.TestDiffTest) } -func (tp *provider) TestNew(t *testing.T) { +func (tp *TestSuite) TestNew(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() api, err := tp.makeAPI(ctx) @@ -61,7 +61,7 @@ func (tp *provider) TestNew(t *testing.T) { } } -func (tp *provider) TestObjectPut(t *testing.T) { +func (tp *TestSuite) TestObjectPut(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() api, err := tp.makeAPI(ctx) @@ -102,7 +102,7 @@ func (tp *provider) TestObjectPut(t *testing.T) { } } -func (tp *provider) TestObjectGet(t *testing.T) { +func (tp *TestSuite) TestObjectGet(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() api, err := tp.makeAPI(ctx) @@ -125,7 +125,7 @@ func (tp *provider) TestObjectGet(t *testing.T) { } } -func (tp *provider) TestObjectData(t *testing.T) { +func (tp *TestSuite) TestObjectData(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() api, err := tp.makeAPI(ctx) @@ -153,7 +153,7 @@ func (tp *provider) TestObjectData(t *testing.T) { } } -func (tp *provider) TestObjectLinks(t *testing.T) { +func (tp *TestSuite) TestObjectLinks(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() api, err := tp.makeAPI(ctx) @@ -189,7 +189,7 @@ func (tp *provider) TestObjectLinks(t *testing.T) { } } -func (tp *provider) TestObjectStat(t *testing.T) { +func (tp *TestSuite) TestObjectStat(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() api, err := tp.makeAPI(ctx) @@ -237,7 +237,7 @@ func (tp *provider) TestObjectStat(t *testing.T) { } } -func (tp *provider) TestObjectAddLink(t *testing.T) { +func (tp *TestSuite) TestObjectAddLink(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() api, err := tp.makeAPI(ctx) @@ -278,7 +278,7 @@ func (tp *provider) TestObjectAddLink(t *testing.T) { } } -func (tp *provider) TestObjectAddLinkCreate(t *testing.T) { +func (tp *TestSuite) TestObjectAddLinkCreate(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() api, err := tp.makeAPI(ctx) @@ -327,7 +327,7 @@ func (tp *provider) TestObjectAddLinkCreate(t *testing.T) { } } -func (tp *provider) TestObjectRmLink(t *testing.T) { +func (tp *TestSuite) TestObjectRmLink(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() api, err := tp.makeAPI(ctx) @@ -360,7 +360,7 @@ func (tp *provider) TestObjectRmLink(t *testing.T) { } } -func (tp *provider) TestObjectAddData(t *testing.T) { +func (tp *TestSuite) TestObjectAddData(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() api, err := tp.makeAPI(ctx) @@ -393,7 +393,7 @@ func (tp *provider) TestObjectAddData(t *testing.T) { } } -func (tp *provider) TestObjectSetData(t *testing.T) { +func (tp *TestSuite) TestObjectSetData(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() api, err := tp.makeAPI(ctx) @@ -426,7 +426,7 @@ func (tp *provider) TestObjectSetData(t *testing.T) { } } -func (tp *provider) TestDiffTest(t *testing.T) { +func (tp *TestSuite) TestDiffTest(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() api, err := tp.makeAPI(ctx) diff --git a/core/coreiface/tests/path.go b/core/coreiface/tests/path.go index 4fd18bd20..2d9497244 100644 --- a/core/coreiface/tests/path.go +++ b/core/coreiface/tests/path.go @@ -12,7 +12,7 @@ import ( ipldcbor "github.com/ipfs/go-ipld-cbor" ) -func (tp *provider) TestPath(t *testing.T) { +func (tp *TestSuite) TestPath(t *testing.T) { t.Run("TestMutablePath", tp.TestMutablePath) t.Run("TestPathRemainder", tp.TestPathRemainder) t.Run("TestEmptyPathRemainder", tp.TestEmptyPathRemainder) @@ -21,7 +21,7 @@ func (tp *provider) TestPath(t *testing.T) { t.Run("TestPathJoin", tp.TestPathJoin) } -func (tp *provider) TestMutablePath(t *testing.T) { +func (tp *TestSuite) TestMutablePath(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() api, err := tp.makeAPI(ctx) @@ -54,7 +54,7 @@ func (tp *provider) TestMutablePath(t *testing.T) { } } -func (tp *provider) TestPathRemainder(t *testing.T) { +func (tp *TestSuite) TestPathRemainder(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() api, err := tp.makeAPI(ctx) @@ -85,7 +85,7 @@ func (tp *provider) TestPathRemainder(t *testing.T) { } } -func (tp *provider) TestEmptyPathRemainder(t *testing.T) { +func (tp *TestSuite) TestEmptyPathRemainder(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() api, err := tp.makeAPI(ctx) @@ -116,7 +116,7 @@ func (tp *provider) TestEmptyPathRemainder(t *testing.T) { } } -func (tp *provider) TestInvalidPathRemainder(t *testing.T) { +func (tp *TestSuite) TestInvalidPathRemainder(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() api, err := tp.makeAPI(ctx) @@ -143,7 +143,7 @@ func (tp *provider) TestInvalidPathRemainder(t *testing.T) { } } -func (tp *provider) TestPathRoot(t *testing.T) { +func (tp *TestSuite) TestPathRoot(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() api, err := tp.makeAPI(ctx) @@ -187,7 +187,7 @@ func (tp *provider) TestPathRoot(t *testing.T) { } } -func (tp *provider) TestPathJoin(t *testing.T) { +func (tp *TestSuite) TestPathJoin(t *testing.T) { p1 := path.New("/ipfs/QmYNmQKp6SuaVrpgWRsPTgCQCnpxUYGq76YEKBXuj2N4H6/bar/baz") if path.Join(p1, "foo").String() != "/ipfs/QmYNmQKp6SuaVrpgWRsPTgCQCnpxUYGq76YEKBXuj2N4H6/bar/baz/foo" { diff --git a/core/coreiface/tests/pin.go b/core/coreiface/tests/pin.go index 344db65e2..9b28a682a 100644 --- a/core/coreiface/tests/pin.go +++ b/core/coreiface/tests/pin.go @@ -14,7 +14,7 @@ import ( ipld "github.com/ipfs/go-ipld-format" ) -func (tp *provider) TestPin(t *testing.T) { +func (tp *TestSuite) TestPin(t *testing.T) { tp.hasApi(t, func(api iface.CoreAPI) error { if api.Pin() == nil { return apiNotImplemented @@ -27,7 +27,7 @@ func (tp *provider) TestPin(t *testing.T) { t.Run("TestPinRecursive", tp.TestPinRecursive) } -func (tp *provider) TestPinAdd(t *testing.T) { +func (tp *TestSuite) TestPinAdd(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() api, err := tp.makeAPI(ctx) @@ -46,7 +46,7 @@ func (tp *provider) TestPinAdd(t *testing.T) { } } -func (tp *provider) TestPinSimple(t *testing.T) { +func (tp *TestSuite) TestPinSimple(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() api, err := tp.makeAPI(ctx) @@ -96,7 +96,7 @@ func (tp *provider) TestPinSimple(t *testing.T) { } } -func (tp *provider) TestPinRecursive(t *testing.T) { +func (tp *TestSuite) TestPinRecursive(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() api, err := tp.makeAPI(ctx) diff --git a/core/coreiface/tests/pubsub.go b/core/coreiface/tests/pubsub.go index 418fc4867..e66291572 100644 --- a/core/coreiface/tests/pubsub.go +++ b/core/coreiface/tests/pubsub.go @@ -9,7 +9,7 @@ import ( "github.com/ipfs/interface-go-ipfs-core/options" ) -func (tp *provider) TestPubSub(t *testing.T) { +func (tp *TestSuite) TestPubSub(t *testing.T) { tp.hasApi(t, func(api iface.CoreAPI) error { if api.PubSub() == nil { return apiNotImplemented @@ -20,7 +20,7 @@ func (tp *provider) TestPubSub(t *testing.T) { t.Run("TestBasicPubSub", tp.TestBasicPubSub) } -func (tp *provider) TestBasicPubSub(t *testing.T) { +func (tp *TestSuite) TestBasicPubSub(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() diff --git a/core/coreiface/tests/unixfs.go b/core/coreiface/tests/unixfs.go index c810167e8..47ce505c8 100644 --- a/core/coreiface/tests/unixfs.go +++ b/core/coreiface/tests/unixfs.go @@ -28,7 +28,7 @@ import ( mh "github.com/multiformats/go-multihash" ) -func (tp *provider) TestUnixfs(t *testing.T) { +func (tp *TestSuite) TestUnixfs(t *testing.T) { tp.hasApi(t, func(api coreiface.CoreAPI) error { if api.Unixfs() == nil { return apiNotImplemented @@ -94,7 +94,7 @@ func wrapped(names ...string) func(f files.Node) files.Node { } } -func (tp *provider) TestAdd(t *testing.T) { +func (tp *TestSuite) TestAdd(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() api, err := tp.makeAPI(ctx) @@ -528,7 +528,7 @@ func (tp *provider) TestAdd(t *testing.T) { } } -func (tp *provider) TestAddPinned(t *testing.T) { +func (tp *TestSuite) TestAddPinned(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() api, err := tp.makeAPI(ctx) @@ -554,7 +554,7 @@ func (tp *provider) TestAddPinned(t *testing.T) { } } -func (tp *provider) TestAddHashOnly(t *testing.T) { +func (tp *TestSuite) TestAddHashOnly(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() api, err := tp.makeAPI(ctx) @@ -580,7 +580,7 @@ func (tp *provider) TestAddHashOnly(t *testing.T) { } } -func (tp *provider) TestGetEmptyFile(t *testing.T) { +func (tp *TestSuite) TestGetEmptyFile(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() api, err := tp.makeAPI(ctx) @@ -610,7 +610,7 @@ func (tp *provider) TestGetEmptyFile(t *testing.T) { } } -func (tp *provider) TestGetDir(t *testing.T) { +func (tp *TestSuite) TestGetDir(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() api, err := tp.makeAPI(ctx) @@ -643,7 +643,7 @@ func (tp *provider) TestGetDir(t *testing.T) { } } -func (tp *provider) TestGetNonUnixfs(t *testing.T) { +func (tp *TestSuite) TestGetNonUnixfs(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() api, err := tp.makeAPI(ctx) @@ -663,7 +663,7 @@ func (tp *provider) TestGetNonUnixfs(t *testing.T) { } } -func (tp *provider) TestLs(t *testing.T) { +func (tp *TestSuite) TestLs(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() api, err := tp.makeAPI(ctx) @@ -723,7 +723,7 @@ func (tp *provider) TestLs(t *testing.T) { } } -func (tp *provider) TestEntriesExpired(t *testing.T) { +func (tp *TestSuite) TestEntriesExpired(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() api, err := tp.makeAPI(ctx) @@ -765,7 +765,7 @@ func (tp *provider) TestEntriesExpired(t *testing.T) { } } -func (tp *provider) TestLsEmptyDir(t *testing.T) { +func (tp *TestSuite) TestLsEmptyDir(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() api, err := tp.makeAPI(ctx) @@ -794,7 +794,7 @@ func (tp *provider) TestLsEmptyDir(t *testing.T) { } // TODO(lgierth) this should test properly, with len(links) > 0 -func (tp *provider) TestLsNonUnixfs(t *testing.T) { +func (tp *TestSuite) TestLsNonUnixfs(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() api, err := tp.makeAPI(ctx) @@ -853,7 +853,7 @@ func (f *closeTestF) Close() error { return nil } -func (tp *provider) TestAddCloses(t *testing.T) { +func (tp *TestSuite) TestAddCloses(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() api, err := tp.makeAPI(ctx) @@ -891,7 +891,7 @@ func (tp *provider) TestAddCloses(t *testing.T) { } } -func (tp *provider) TestGetSeek(t *testing.T) { +func (tp *TestSuite) TestGetSeek(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() api, err := tp.makeAPI(ctx) From 1f4d8c7243039855f5c62f043168815d057777f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Kripalani?= Date: Tue, 28 May 2019 17:09:34 +0100 Subject: [PATCH 0303/1212] migrate to go-libp2p-core. This commit was moved from ipfs/interface-go-ipfs-core@2cc0c497f2b0b14a4ac22989a3861c1a2b0038c4 This commit was moved from ipfs/boxo@1f2b5ca04f4cb9d5fe9b11d4c58edb91bab8b2a1 --- core/coreiface/dht.go | 7 +++---- core/coreiface/key.go | 2 +- core/coreiface/pubsub.go | 2 +- core/coreiface/swarm.go | 12 ++++++------ 4 files changed, 11 insertions(+), 12 deletions(-) diff --git a/core/coreiface/dht.go b/core/coreiface/dht.go index 0cb7893ef..5f49e74a3 100644 --- a/core/coreiface/dht.go +++ b/core/coreiface/dht.go @@ -6,8 +6,7 @@ import ( "github.com/ipfs/interface-go-ipfs-core/options" - "github.com/libp2p/go-libp2p-peer" - pstore "github.com/libp2p/go-libp2p-peerstore" + "github.com/libp2p/go-libp2p-core/peer" ) // DhtAPI specifies the interface to the DHT @@ -16,11 +15,11 @@ import ( type DhtAPI interface { // FindPeer queries the DHT for all of the multiaddresses associated with a // Peer ID - FindPeer(context.Context, peer.ID) (pstore.PeerInfo, error) + FindPeer(context.Context, peer.ID) (peer.AddrInfo, error) // FindProviders finds peers in the DHT who can provide a specific value // given a key. - FindProviders(context.Context, path.Path, ...options.DhtFindProvidersOption) (<-chan pstore.PeerInfo, error) + FindProviders(context.Context, path.Path, ...options.DhtFindProvidersOption) (<-chan peer.AddrInfo, error) // Provide announces to the network that you are providing given values Provide(context.Context, path.Path, ...options.DhtProvideOption) error diff --git a/core/coreiface/key.go b/core/coreiface/key.go index e7fb3f442..db729b3b4 100644 --- a/core/coreiface/key.go +++ b/core/coreiface/key.go @@ -6,7 +6,7 @@ import ( "github.com/ipfs/interface-go-ipfs-core/options" - "github.com/libp2p/go-libp2p-peer" + "github.com/libp2p/go-libp2p-core/peer" ) // Key specifies the interface to Keys in KeyAPI Keystore diff --git a/core/coreiface/pubsub.go b/core/coreiface/pubsub.go index 212e77225..d9826551d 100644 --- a/core/coreiface/pubsub.go +++ b/core/coreiface/pubsub.go @@ -6,7 +6,7 @@ import ( options "github.com/ipfs/interface-go-ipfs-core/options" - peer "github.com/libp2p/go-libp2p-peer" + "github.com/libp2p/go-libp2p-core/peer" ) // PubSubSubscription is an active PubSub subscription diff --git a/core/coreiface/swarm.go b/core/coreiface/swarm.go index 2e00ecbd3..d7b25d5e8 100644 --- a/core/coreiface/swarm.go +++ b/core/coreiface/swarm.go @@ -5,10 +5,10 @@ import ( "errors" "time" - net "github.com/libp2p/go-libp2p-net" - "github.com/libp2p/go-libp2p-peer" - pstore "github.com/libp2p/go-libp2p-peerstore" - "github.com/libp2p/go-libp2p-protocol" + "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/protocol" + ma "github.com/multiformats/go-multiaddr" ) @@ -26,7 +26,7 @@ type ConnectionInfo interface { Address() ma.Multiaddr // Direction returns which way the connection was established - Direction() net.Direction + Direction() network.Direction // Latency returns last known round trip time to the peer Latency() (time.Duration, error) @@ -38,7 +38,7 @@ type ConnectionInfo interface { // SwarmAPI specifies the interface to libp2p swarm type SwarmAPI interface { // Connect to a given peer - Connect(context.Context, pstore.PeerInfo) error + Connect(context.Context, peer.AddrInfo) error // Disconnect from a given address Disconnect(context.Context, ma.Multiaddr) error From 1b81f2ef10c40b5ba5a50ae545a62cc050c11813 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Tue, 11 Jun 2019 17:41:49 -0700 Subject: [PATCH 0304/1212] add extended error handling fixes #19 This commit was moved from ipfs/go-ipfs-http-client@8e3552ac1e6ea18ffd5f49918eef578de2b224fb --- client/httpapi/response.go | 62 +++++++++++++++++++++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) diff --git a/client/httpapi/response.go b/client/httpapi/response.go index db22a66fa..056b2d68d 100644 --- a/client/httpapi/response.go +++ b/client/httpapi/response.go @@ -13,6 +13,48 @@ import ( "os" ) +// Error codes adapted from go-ipfs-cmds. We should find a better solution. + +// ErrorType signfies a category of errors +type ErrorType uint + +// ErrorTypes convey what category of error ocurred +const ( + // ErrNormal is a normal error. The command failed for some reason that's not a bug. + ErrNormal ErrorType = iota + // ErrClient means the client made an invalid request. + ErrClient + // ErrImplementation means there's a bug in the implementation. + ErrImplementation + // ErrRateLimited is returned when the operation has been rate-limited. + ErrRateLimited + // ErrForbidden is returned when the client doesn't have permission to + // perform the requested operation. + ErrForbidden +) + +func (e ErrorType) Error() string { + return e.String() +} + +func (e ErrorType) String() string { + switch e { + case ErrNormal: + return "command failed" + case ErrClient: + return "invalid argument" + case ErrImplementation: + return "internal error" + case ErrRateLimited: + return "rate limited" + case ErrForbidden: + return "request forbidden" + default: + return "unknown error code" + } + +} + type trailerReader struct { resp *http.Response } @@ -77,7 +119,13 @@ func (r *Response) decode(dec interface{}) error { type Error struct { Command string Message string - Code int + Code ErrorType +} + +// Unwrap returns the base error (an ErrorType). Works with go 1.14 error +// helpers. +func (e *Error) Unwrap() error { + return e.Code } func (e *Error) Error() string { @@ -133,11 +181,23 @@ func (r *Request) Send(c *http.Client) (*Response, error) { fmt.Fprintf(os.Stderr, "ipfs-shell: warning! response (%d) read error: %s\n", resp.StatusCode, err) } e.Message = string(out) + + // set special status codes. + switch resp.StatusCode { + case http.StatusNotFound, http.StatusBadRequest: + e.Code = ErrClient + case http.StatusTooManyRequests: + e.Code = ErrRateLimited + case http.StatusForbidden: + e.Code = ErrForbidden + } case contentType == "application/json": if err = json.NewDecoder(resp.Body).Decode(e); err != nil { fmt.Fprintf(os.Stderr, "ipfs-shell: warning! response (%d) unmarshall error: %s\n", resp.StatusCode, err) } default: + // This is a server-side bug (probably). + e.Code = ErrImplementation fmt.Fprintf(os.Stderr, "ipfs-shell: warning! unhandled response (%d) encoding: %s", resp.StatusCode, contentType) out, err := ioutil.ReadAll(resp.Body) if err != nil { From 2612353d85385a595e889dfa247363a8a4ab02c3 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Thu, 13 Jun 2019 12:00:58 -0700 Subject: [PATCH 0305/1212] use error from go-ipfs-cmds note: this drops the Command field This commit was moved from ipfs/go-ipfs-http-client@523a26f0a853a2d6779a21d7bad239bf2012833b --- client/httpapi/response.go | 81 ++++++-------------------------------- 1 file changed, 11 insertions(+), 70 deletions(-) diff --git a/client/httpapi/response.go b/client/httpapi/response.go index 056b2d68d..95cbf13ec 100644 --- a/client/httpapi/response.go +++ b/client/httpapi/response.go @@ -4,56 +4,19 @@ import ( "encoding/json" "errors" "fmt" - "github.com/ipfs/go-ipfs-files" "io" "io/ioutil" "mime" "net/http" "net/url" "os" + + cmds "github.com/ipfs/go-ipfs-cmds" + cmdhttp "github.com/ipfs/go-ipfs-cmds/http" + files "github.com/ipfs/go-ipfs-files" ) -// Error codes adapted from go-ipfs-cmds. We should find a better solution. - -// ErrorType signfies a category of errors -type ErrorType uint - -// ErrorTypes convey what category of error ocurred -const ( - // ErrNormal is a normal error. The command failed for some reason that's not a bug. - ErrNormal ErrorType = iota - // ErrClient means the client made an invalid request. - ErrClient - // ErrImplementation means there's a bug in the implementation. - ErrImplementation - // ErrRateLimited is returned when the operation has been rate-limited. - ErrRateLimited - // ErrForbidden is returned when the client doesn't have permission to - // perform the requested operation. - ErrForbidden -) - -func (e ErrorType) Error() string { - return e.String() -} - -func (e ErrorType) String() string { - switch e { - case ErrNormal: - return "command failed" - case ErrClient: - return "invalid argument" - case ErrImplementation: - return "internal error" - case ErrRateLimited: - return "rate limited" - case ErrForbidden: - return "request forbidden" - default: - return "unknown error code" - } - -} +type Error = cmds.Error type trailerReader struct { resp *http.Response @@ -62,7 +25,7 @@ type trailerReader struct { func (r *trailerReader) Read(b []byte) (int, error) { n, err := r.resp.Body.Read(b) if err != nil { - if e := r.resp.Trailer.Get("X-Stream-Error"); e != "" { + if e := r.resp.Trailer.Get(cmdhttp.StreamErrHeader); e != "" { err = errors.New(e) } } @@ -116,26 +79,6 @@ func (r *Response) decode(dec interface{}) error { return err2 } -type Error struct { - Command string - Message string - Code ErrorType -} - -// Unwrap returns the base error (an ErrorType). Works with go 1.14 error -// helpers. -func (e *Error) Unwrap() error { - return e.Code -} - -func (e *Error) Error() string { - var out string - if e.Code != 0 { - out = fmt.Sprintf("%s%d: ", out, e.Code) - } - return out + e.Message -} - func (r *Request) Send(c *http.Client) (*Response, error) { url := r.getURL() req, err := http.NewRequest("POST", url, r.Body) @@ -169,9 +112,7 @@ func (r *Request) Send(c *http.Client) (*Response, error) { nresp.Output = &trailerReader{resp} if resp.StatusCode >= http.StatusBadRequest { - e := &Error{ - Command: r.Command, - } + e := new(Error) switch { case resp.StatusCode == http.StatusNotFound: e.Message = "command not found" @@ -185,11 +126,11 @@ func (r *Request) Send(c *http.Client) (*Response, error) { // set special status codes. switch resp.StatusCode { case http.StatusNotFound, http.StatusBadRequest: - e.Code = ErrClient + e.Code = cmds.ErrClient case http.StatusTooManyRequests: - e.Code = ErrRateLimited + e.Code = cmds.ErrRateLimited case http.StatusForbidden: - e.Code = ErrForbidden + e.Code = cmds.ErrForbidden } case contentType == "application/json": if err = json.NewDecoder(resp.Body).Decode(e); err != nil { @@ -197,7 +138,7 @@ func (r *Request) Send(c *http.Client) (*Response, error) { } default: // This is a server-side bug (probably). - e.Code = ErrImplementation + e.Code = cmds.ErrImplementation fmt.Fprintf(os.Stderr, "ipfs-shell: warning! unhandled response (%d) encoding: %s", resp.StatusCode, contentType) out, err := ioutil.ReadAll(resp.Body) if err != nil { From 9345cfa7b83d3fb2fb470fa1e77e7af89087452b Mon Sep 17 00:00:00 2001 From: godcong Date: Sun, 21 Jul 2019 12:33:35 +0800 Subject: [PATCH 0306/1212] update to consolidated libp2p interface package (#21) and fix parsing of connection latencies This commit was moved from ipfs/go-ipfs-http-client@fd5cce4cbc9d95617ded33849c437a492f5e9d96 --- client/httpapi/dht.go | 31 +++++++++++++++---------------- client/httpapi/key.go | 2 +- client/httpapi/pubsub.go | 2 +- client/httpapi/swarm.go | 20 ++++++++++---------- 4 files changed, 27 insertions(+), 28 deletions(-) diff --git a/client/httpapi/dht.go b/client/httpapi/dht.go index e12caa1c5..0a78514f9 100644 --- a/client/httpapi/dht.go +++ b/client/httpapi/dht.go @@ -6,38 +6,37 @@ import ( caopts "github.com/ipfs/interface-go-ipfs-core/options" "github.com/ipfs/interface-go-ipfs-core/path" - "github.com/libp2p/go-libp2p-peer" - "github.com/libp2p/go-libp2p-peerstore" - notif "github.com/libp2p/go-libp2p-routing/notifications" + "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/routing" ) type DhtAPI HttpApi -func (api *DhtAPI) FindPeer(ctx context.Context, p peer.ID) (peerstore.PeerInfo, error) { +func (api *DhtAPI) FindPeer(ctx context.Context, p peer.ID) (peer.AddrInfo, error) { var out struct { - Type notif.QueryEventType - Responses []peerstore.PeerInfo + Type routing.QueryEventType + Responses []peer.AddrInfo } resp, err := api.core().Request("dht/findpeer", p.Pretty()).Send(ctx) if err != nil { - return peerstore.PeerInfo{}, err + return peer.AddrInfo{}, err } if resp.Error != nil { - return peerstore.PeerInfo{}, resp.Error + return peer.AddrInfo{}, resp.Error } defer resp.Close() dec := json.NewDecoder(resp.Output) for { if err := dec.Decode(&out); err != nil { - return peerstore.PeerInfo{}, err + return peer.AddrInfo{}, err } - if out.Type == notif.FinalPeer { + if out.Type == routing.FinalPeer { return out.Responses[0], nil } } } -func (api *DhtAPI) FindProviders(ctx context.Context, p path.Path, opts ...caopts.DhtFindProvidersOption) (<-chan peerstore.PeerInfo, error) { +func (api *DhtAPI) FindProviders(ctx context.Context, p path.Path, opts ...caopts.DhtFindProvidersOption) (<-chan peer.AddrInfo, error) { options, err := caopts.DhtFindProvidersOptions(opts...) if err != nil { return nil, err @@ -57,7 +56,7 @@ func (api *DhtAPI) FindProviders(ctx context.Context, p path.Path, opts ...caopt if resp.Error != nil { return nil, resp.Error } - res := make(chan peerstore.PeerInfo) + res := make(chan peer.AddrInfo) go func() { defer resp.Close() @@ -67,18 +66,18 @@ func (api *DhtAPI) FindProviders(ctx context.Context, p path.Path, opts ...caopt for { var out struct { Extra string - Type notif.QueryEventType - Responses []peerstore.PeerInfo + Type routing.QueryEventType + Responses []peer.AddrInfo } if err := dec.Decode(&out); err != nil { return // todo: handle this somehow } - if out.Type == notif.QueryError { + if out.Type == routing.QueryError { return // usually a 'not found' error // todo: handle other errors } - if out.Type == notif.Provider { + if out.Type == routing.Provider { for _, pi := range out.Responses { select { case res <- pi: diff --git a/client/httpapi/key.go b/client/httpapi/key.go index 9a47e2ed0..cf22c6108 100644 --- a/client/httpapi/key.go +++ b/client/httpapi/key.go @@ -7,7 +7,7 @@ import ( "github.com/ipfs/interface-go-ipfs-core" caopts "github.com/ipfs/interface-go-ipfs-core/options" "github.com/ipfs/interface-go-ipfs-core/path" - "github.com/libp2p/go-libp2p-peer" + "github.com/libp2p/go-libp2p-core/peer" ) type KeyAPI HttpApi diff --git a/client/httpapi/pubsub.go b/client/httpapi/pubsub.go index 380b933dc..81ddb5211 100644 --- a/client/httpapi/pubsub.go +++ b/client/httpapi/pubsub.go @@ -8,7 +8,7 @@ import ( "github.com/ipfs/interface-go-ipfs-core" caopts "github.com/ipfs/interface-go-ipfs-core/options" - "github.com/libp2p/go-libp2p-peer" + "github.com/libp2p/go-libp2p-core/peer" ) type PubsubAPI HttpApi diff --git a/client/httpapi/swarm.go b/client/httpapi/swarm.go index 0e47df2ab..10280c39f 100644 --- a/client/httpapi/swarm.go +++ b/client/httpapi/swarm.go @@ -5,16 +5,15 @@ import ( "time" "github.com/ipfs/interface-go-ipfs-core" - inet "github.com/libp2p/go-libp2p-net" - "github.com/libp2p/go-libp2p-peer" - "github.com/libp2p/go-libp2p-peerstore" - "github.com/libp2p/go-libp2p-protocol" + "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/protocol" "github.com/multiformats/go-multiaddr" ) type SwarmAPI HttpApi -func (api *SwarmAPI) Connect(ctx context.Context, pi peerstore.PeerInfo) error { +func (api *SwarmAPI) Connect(ctx context.Context, pi peer.AddrInfo) error { pidma, err := multiaddr.NewComponent("p2p", pi.ID.Pretty()) if err != nil { return err @@ -37,7 +36,7 @@ type connInfo struct { peer peer.ID latency time.Duration muxer string - direction inet.Direction + direction network.Direction streams []protocol.ID } @@ -49,7 +48,7 @@ func (c *connInfo) Address() multiaddr.Multiaddr { return c.addr } -func (c *connInfo) Direction() inet.Direction { +func (c *connInfo) Direction() network.Direction { return c.direction } @@ -66,9 +65,9 @@ func (api *SwarmAPI) Peers(ctx context.Context) ([]iface.ConnectionInfo, error) Peers []struct { Addr string Peer string - Latency time.Duration + Latency string Muxer string - Direction inet.Direction + Direction network.Direction Streams []struct { Protocol string } @@ -85,8 +84,9 @@ func (api *SwarmAPI) Peers(ctx context.Context) ([]iface.ConnectionInfo, error) res := make([]iface.ConnectionInfo, len(resp.Peers)) for i, conn := range resp.Peers { + latency, _ := time.ParseDuration(conn.Latency) out := &connInfo{ - latency: conn.Latency, + latency: latency, muxer: conn.Muxer, direction: conn.Direction, } From fafbedb658bbc4e4f317c8c8395794f3617647ba Mon Sep 17 00:00:00 2001 From: Cole Brown Date: Fri, 2 Aug 2019 21:09:17 -0400 Subject: [PATCH 0307/1212] Bump go-libp2p-core, up test key size to 2048 This commit was moved from ipfs/interface-go-ipfs-core@6ba366dd626d3b605a67d7ade24b3065bc4d9694 This commit was moved from ipfs/boxo@98cec339880e00290049245fc50acf6fc2874701 --- core/coreiface/tests/key.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/coreiface/tests/key.go b/core/coreiface/tests/key.go index e3461f971..265a8f060 100644 --- a/core/coreiface/tests/key.go +++ b/core/coreiface/tests/key.go @@ -147,7 +147,7 @@ func (tp *TestSuite) TestGenerateSize(t *testing.T) { t.Fatal(err) } - k, err := api.Key().Generate(ctx, "foo", opt.Key.Size(1024)) + k, err := api.Key().Generate(ctx, "foo", opt.Key.Size(2048)) if err != nil { t.Fatal(err) return From be8f80237d4ba8ed8d2ef278180b2b3d446c60f0 Mon Sep 17 00:00:00 2001 From: godcong Date: Tue, 13 Aug 2019 07:16:47 +0800 Subject: [PATCH 0308/1212] fix path miss in windows/add a new api create function (#23) * fix path was not always correct in windows * add new api create function for if the port was different with api file. * Update api.go remove no need commit This commit was moved from ipfs/go-ipfs-http-client@8c87debb1233f2af7a0cd102a934b630d8a12147 --- client/httpapi/api.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/httpapi/api.go b/client/httpapi/api.go index 5c2eb76d6..ec16c4b2d 100644 --- a/client/httpapi/api.go +++ b/client/httpapi/api.go @@ -7,12 +7,12 @@ import ( "net/http" gohttp "net/http" "os" - "path" + "path/filepath" "strings" iface "github.com/ipfs/interface-go-ipfs-core" caopts "github.com/ipfs/interface-go-ipfs-core/options" - homedir "github.com/mitchellh/go-homedir" + "github.com/mitchellh/go-homedir" ma "github.com/multiformats/go-multiaddr" manet "github.com/multiformats/go-multiaddr-net" ) @@ -73,7 +73,7 @@ func ApiAddr(ipfspath string) (ma.Multiaddr, error) { return nil, err } - apiFile := path.Join(baseDir, DefaultApiFile) + apiFile := filepath.Join(baseDir, DefaultApiFile) api, err := ioutil.ReadFile(apiFile) if err != nil { From 09a4311db7804b6d511ce99e65029bdb283b2c4d Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Fri, 23 Aug 2019 16:22:22 -0700 Subject: [PATCH 0309/1212] test: fix put with hash test We just changed ID/"id" to IDENTITY/"identity" to match the multicodec table and avoid confusion with peer IDs, CIDs, etc. Unfortunately, this breaks the `--hash=id` flag. Luckily, I'm pretty sure nobody's actually using this. As putting a block with an identity hash is useless. If they are users, we can go about adding in backwards compatibility hacks later. This commit was moved from ipfs/interface-go-ipfs-core@6ebdbe7ef3eadc7f832592abb3b1b151d9b4febf This commit was moved from ipfs/boxo@3b9a723861fa7b8069ac6a0c698f83a8b6e82237 --- core/coreiface/tests/dag.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/coreiface/tests/dag.go b/core/coreiface/tests/dag.go index 1ccd45d59..2f68bbf05 100644 --- a/core/coreiface/tests/dag.go +++ b/core/coreiface/tests/dag.go @@ -71,7 +71,7 @@ func (tp *TestSuite) TestPutWithHash(t *testing.T) { t.Fatal(err) } - nd, err := ipldcbor.FromJSON(strings.NewReader(`"Hello"`), mh.ID, -1) + nd, err := ipldcbor.FromJSON(strings.NewReader(`"Hello"`), mh.SHA3_256, -1) if err != nil { t.Fatal(err) } @@ -81,7 +81,7 @@ func (tp *TestSuite) TestPutWithHash(t *testing.T) { t.Fatal(err) } - if nd.Cid().String() != "bafyqabtfjbswy3dp" { + if nd.Cid().String() != "bafyrmifu7haikttpqqgc5ewvmp76z3z4ebp7h2ph4memw7dq4nt6btmxny" { t.Errorf("got wrong cid: %s", nd.Cid().String()) } } From b6b2ae355bf86c4859f234240b44b35656685ece Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Fri, 30 Aug 2019 18:44:24 -0700 Subject: [PATCH 0310/1212] doc: mark this package experimental instead of WIP (#30) We're at a point where this package works pretty well and users should consider using it. This commit was moved from ipfs/go-ipfs-http-client@3e8506bbecd9b77ae30d04c7b997d9d612654beb --- client/httpapi/README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/client/httpapi/README.md b/client/httpapi/README.md index dd09142e3..e5ab1c612 100644 --- a/client/httpapi/README.md +++ b/client/httpapi/README.md @@ -8,7 +8,10 @@ > IPFS CoreAPI implementation using HTTP API -This project is WIP, use https://github.com/ipfs/go-ipfs-api for now +This package is experimental and subject to change. If you need to depend on +something less likely to change, please use +[go-ipfs-api](https://github.com/ipfs/go-ipfs-api). If you'd like the latest and +greatest features, please use _this_ package. ## Documentation From 5168b591dc343f345b0074bcbee870888a7e001d Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Tue, 10 Sep 2019 18:23:14 -0700 Subject: [PATCH 0311/1212] test: test ReadAt if implemented (I plan on adding support to the http client, at least) This commit was moved from ipfs/interface-go-ipfs-core@ae838686170af209e0a9b29aa1a59b64346b5de1 This commit was moved from ipfs/boxo@a8c5ec606246224d3f0dfadfc627a9f90d9b53df --- core/coreiface/tests/unixfs.go | 82 ++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/core/coreiface/tests/unixfs.go b/core/coreiface/tests/unixfs.go index 47ce505c8..aac7fa92f 100644 --- a/core/coreiface/tests/unixfs.go +++ b/core/coreiface/tests/unixfs.go @@ -48,6 +48,7 @@ func (tp *TestSuite) TestUnixfs(t *testing.T) { t.Run("TestLsNonUnixfs", tp.TestLsNonUnixfs) t.Run("TestAddCloses", tp.TestAddCloses) t.Run("TestGetSeek", tp.TestGetSeek) + t.Run("TestGetReadAt", tp.TestGetReadAt) } // `echo -n 'hello, world!' | ipfs add` @@ -996,3 +997,84 @@ func (tp *TestSuite) TestGetSeek(t *testing.T) { test(dataSize-50, io.SeekStart, 100, 50, true) test(-5, io.SeekEnd, 100, 5, true) } + +func (tp *TestSuite) TestGetReadAt(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + api, err := tp.makeAPI(ctx) + if err != nil { + t.Fatal(err) + } + + dataSize := int64(100000) + tf := files.NewReaderFile(io.LimitReader(rand.New(rand.NewSource(1403768328)), dataSize)) + + p, err := api.Unixfs().Add(ctx, tf, options.Unixfs.Chunker("size-100")) + if err != nil { + t.Fatal(err) + } + + r, err := api.Unixfs().Get(ctx, p) + if err != nil { + t.Fatal(err) + } + + f, ok := r.(interface { + files.File + io.ReaderAt + }) + if !ok { + t.Skip("ReaderAt not implemented") + } + + orig := make([]byte, dataSize) + if _, err := io.ReadFull(f, orig); err != nil { + t.Fatal(err) + } + f.Close() + + origR := bytes.NewReader(orig) + + r, err = api.Unixfs().Get(ctx, p) + if err != nil { + t.Fatal(err) + } + + test := func(offset int64, read int, expect int64, shouldEof bool) { + t.Run(fmt.Sprintf("readat%d-r%d-%d", offset, read, expect), func(t *testing.T) { + origBuf := make([]byte, read) + origRead, err := origR.ReadAt(origBuf, offset) + if err != nil && err != io.EOF { + t.Fatalf("orig: %s", err) + } + buf := make([]byte, read) + r, err := f.ReadAt(buf, offset) + if shouldEof { + if err != io.EOF { + t.Fatal("expected EOF, got: ", err) + } + } else if err != nil { + t.Fatal("got: ", err) + } + + if int64(r) != expect { + t.Fatal("read wrong amount of data") + } + if r != origRead { + t.Fatal("read different amount of data than bytes.Reader") + } + if !bytes.Equal(buf, origBuf) { + fmt.Fprintf(os.Stderr, "original:\n%s\n", hex.Dump(origBuf)) + fmt.Fprintf(os.Stderr, "got:\n%s\n", hex.Dump(buf)) + t.Fatal("data didn't match") + } + }) + } + + test(3, 10, 10, false) + test(13, 10, 10, false) + test(513, 10, 10, false) + test(350, 100, 100, false) + test(0, int(dataSize), dataSize, false) + test(dataSize-50, 100, 50, true) +} From d48f8fce64d6496a18b442c74021829554151823 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Tue, 10 Sep 2019 18:07:48 -0700 Subject: [PATCH 0312/1212] file: implement ReadAt This commit was moved from ipfs/go-ipfs-http-client@88a9b615205816ea20ea38fbee170b3256e51b94 --- client/httpapi/apifile.go | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/client/httpapi/apifile.go b/client/httpapi/apifile.go index afd9934e6..ec2f7588d 100644 --- a/client/httpapi/apifile.go +++ b/client/httpapi/apifile.go @@ -82,6 +82,25 @@ func (f *apiFile) Read(p []byte) (int, error) { return n, err } +func (f *apiFile) ReadAt(p []byte, off int64) (int, error) { + // Always make a new request. This method should be parallel-safe. + resp, err := f.core.Request("cat", f.path.String()). + Option("offset", off).Option("length", len(p)).Send(f.ctx) + if err != nil { + return 0, err + } + if resp.Error != nil { + return 0, resp.Error + } + defer resp.Output.Close() + + n, err := io.ReadFull(resp.Output, p) + if err == io.ErrUnexpectedEOF { + err = io.EOF + } + return n, err +} + func (f *apiFile) Seek(offset int64, whence int) (int64, error) { switch whence { case io.SeekEnd: From 58df273d66f263915aad240a414df15ac538a0e2 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Fri, 27 Sep 2019 16:21:44 -0700 Subject: [PATCH 0313/1212] fix(test): fix a flaky pubsub test This commit was moved from ipfs/interface-go-ipfs-core@00de46e290cf0a47bb78a9e8aa264f4b6ce941cd This commit was moved from ipfs/boxo@125f06e6af82e7502de7596d9cfb5a3b560df4e5 --- core/coreiface/tests/pubsub.go | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/core/coreiface/tests/pubsub.go b/core/coreiface/tests/pubsub.go index e66291572..36353f836 100644 --- a/core/coreiface/tests/pubsub.go +++ b/core/coreiface/tests/pubsub.go @@ -34,13 +34,20 @@ func (tp *TestSuite) TestBasicPubSub(t *testing.T) { t.Fatal(err) } + done := make(chan struct{}) go func() { + defer close(done) + ticker := time.NewTicker(100 * time.Millisecond) defer ticker.Stop() for { err := apis[1].PubSub().Publish(ctx, "testch", []byte("hello world")) - if err != nil { + switch err { + case nil: + case context.Canceled: + return + default: t.Error(err) cancel() return @@ -53,6 +60,13 @@ func (tp *TestSuite) TestBasicPubSub(t *testing.T) { } }() + // Wait for the sender to finish before we return. + // Otherwise, we can get random errors as publish fails. + defer func() { + cancel() + <-done + }() + m, err := sub.Next(ctx) if err != nil { t.Fatal(err) From c23fa6e2f1f8732794fcb227ce109a5d04f5ed0f Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Fri, 11 Oct 2019 11:14:39 -0400 Subject: [PATCH 0314/1212] test(pinning): add pin ls tests for indirect pin traversal and pin type precedence This commit was moved from ipfs/interface-go-ipfs-core@cd7be61c71d8169a47604247588b258699f45b5d This commit was moved from ipfs/boxo@30eb9c7c432be938b40951a4c98b8cfbe67899cc --- core/coreiface/tests/pin.go | 269 +++++++++++++++++++++++++++++++++++- 1 file changed, 268 insertions(+), 1 deletion(-) diff --git a/core/coreiface/tests/pin.go b/core/coreiface/tests/pin.go index 9b28a682a..7e574fa0d 100644 --- a/core/coreiface/tests/pin.go +++ b/core/coreiface/tests/pin.go @@ -2,14 +2,15 @@ package tests import ( "context" - "github.com/ipfs/interface-go-ipfs-core/path" "math" "strings" "testing" "github.com/ipfs/interface-go-ipfs-core" opt "github.com/ipfs/interface-go-ipfs-core/options" + "github.com/ipfs/interface-go-ipfs-core/path" + "github.com/ipfs/go-cid" ipldcbor "github.com/ipfs/go-ipld-cbor" ipld "github.com/ipfs/go-ipld-format" ) @@ -25,6 +26,8 @@ func (tp *TestSuite) TestPin(t *testing.T) { t.Run("TestPinAdd", tp.TestPinAdd) t.Run("TestPinSimple", tp.TestPinSimple) t.Run("TestPinRecursive", tp.TestPinRecursive) + t.Run("TestPinLsIndirect", tp.TestPinLsIndirect) + t.Run("TestPinLsPrecedence", tp.TestPinLsPrecedence) } func (tp *TestSuite) TestPinAdd(t *testing.T) { @@ -238,3 +241,267 @@ func (tp *TestSuite) TestPinRecursive(t *testing.T) { } */ } + +// TestPinLsIndirect verifies that indirect nodes are listed by pin ls even if a parent node is directly pinned +func (tp *TestSuite) TestPinLsIndirect(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + api, err := tp.makeAPI(ctx) + if err != nil { + t.Fatal(err) + } + + leaf, parent, grandparent := getThreeChainedNodes(t, ctx, api, "foo") + + err = api.Pin().Add(ctx, path.IpldPath(grandparent.Cid())) + if err != nil { + t.Fatal(err) + } + + err = api.Pin().Add(ctx, path.IpldPath(parent.Cid()), opt.Pin.Recursive(false)) + if err != nil { + t.Fatal(err) + } + + assertPinTypes(t, ctx, api, []cidContainer{grandparent}, []cidContainer{parent}, []cidContainer{leaf}) +} + +// TestPinLsPrecedence verifies the precedence of pins (recursive > direct > indirect) +func (tp *TestSuite) TestPinLsPrecedence(t *testing.T) { + // Testing precedence of recursive, direct and indirect pins + // Results should be recursive > indirect, direct > indirect, and recursive > direct + + t.Run("TestPinLsPredenceRecursiveIndirect", tp.TestPinLsPredenceRecursiveIndirect) + t.Run("TestPinLsPrecedenceDirectIndirect", tp.TestPinLsPrecedenceDirectIndirect) + t.Run("TestPinLsPrecedenceRecursiveDirect", tp.TestPinLsPrecedenceRecursiveDirect) +} + +func (tp *TestSuite) TestPinLsPredenceRecursiveIndirect(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + api, err := tp.makeAPI(ctx) + if err != nil { + t.Fatal(err) + } + + // Test recursive > indirect + leaf, parent, grandparent := getThreeChainedNodes(t, ctx, api, "recursive > indirect") + + err = api.Pin().Add(ctx, path.IpldPath(grandparent.Cid())) + if err != nil { + t.Fatal(err) + } + + err = api.Pin().Add(ctx, path.IpldPath(parent.Cid())) + if err != nil { + t.Fatal(err) + } + + assertPinTypes(t, ctx, api, []cidContainer{grandparent, parent}, []cidContainer{}, []cidContainer{leaf}) +} + +func (tp *TestSuite) TestPinLsPrecedenceDirectIndirect(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + api, err := tp.makeAPI(ctx) + if err != nil { + t.Fatal(err) + } + + // Test direct > indirect + leaf, parent, grandparent := getThreeChainedNodes(t, ctx, api, "direct > indirect") + + err = api.Pin().Add(ctx, path.IpldPath(grandparent.Cid())) + if err != nil { + t.Fatal(err) + } + + err = api.Pin().Add(ctx, path.IpldPath(parent.Cid()), opt.Pin.Recursive(false)) + if err != nil { + t.Fatal(err) + } + + assertPinTypes(t, ctx, api, []cidContainer{grandparent}, []cidContainer{parent}, []cidContainer{leaf}) +} + +func (tp *TestSuite) TestPinLsPrecedenceRecursiveDirect(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + api, err := tp.makeAPI(ctx) + if err != nil { + t.Fatal(err) + } + + // Test recursive > direct + leaf, parent, grandparent := getThreeChainedNodes(t, ctx, api, "recursive + direct = error") + + err = api.Pin().Add(ctx, path.IpldPath(parent.Cid())) + if err != nil { + t.Fatal(err) + } + + err = api.Pin().Add(ctx, path.IpldPath(parent.Cid()), opt.Pin.Recursive(false)) + if err == nil { + t.Fatal("expected error directly pinning a recursively pinned node") + } + + assertPinTypes(t, ctx, api, []cidContainer{parent}, []cidContainer{}, []cidContainer{leaf}) + + err = api.Pin().Add(ctx, path.IpldPath(grandparent.Cid()), opt.Pin.Recursive(false)) + if err != nil { + t.Fatal(err) + } + + err = api.Pin().Add(ctx, path.IpldPath(grandparent.Cid())) + if err != nil { + t.Fatal(err) + } + + assertPinTypes(t, ctx, api, []cidContainer{grandparent, parent}, []cidContainer{}, []cidContainer{leaf}) +} + +type cidContainer interface { + Cid() cid.Cid +} + +func getThreeChainedNodes(t *testing.T, ctx context.Context, api iface.CoreAPI, leafData string) (cidContainer, cidContainer, cidContainer) { + leaf, err := api.Unixfs().Add(ctx, strFile(leafData)()) + if err != nil { + t.Fatal(err) + } + + parent, err := ipldcbor.FromJSON(strings.NewReader(`{"lnk": {"/": "`+leaf.Cid().String()+`"}}`), math.MaxUint64, -1) + if err != nil { + t.Fatal(err) + } + + grandparent, err := ipldcbor.FromJSON(strings.NewReader(`{"lnk": {"/": "`+parent.Cid().String()+`"}}`), math.MaxUint64, -1) + if err != nil { + t.Fatal(err) + } + + if err := api.Dag().AddMany(ctx, []ipld.Node{parent, grandparent}); err != nil { + t.Fatal(err) + } + + return leaf, parent, grandparent +} + +func assertPinTypes(t *testing.T, ctx context.Context, api iface.CoreAPI, recusive, direct, indirect []cidContainer) { + assertPinLsAllConsistency(t, ctx, api) + + list, err := api.Pin().Ls(ctx, opt.Pin.Type.Recursive()) + if err != nil { + t.Fatal(err) + } + + assertPinCids(t, list, recusive...) + + list, err = api.Pin().Ls(ctx, opt.Pin.Type.Direct()) + if err != nil { + t.Fatal(err) + } + + assertPinCids(t, list, direct...) + + list, err = api.Pin().Ls(ctx, opt.Pin.Type.Indirect()) + if err != nil { + t.Fatal(err) + } + + assertPinCids(t, list, indirect...) +} + +// assertPinCids verifies that the pins match the expected cids +func assertPinCids(t *testing.T, pins []iface.Pin, cids ...cidContainer) { + t.Helper() + + if expected, actual := len(cids), len(pins); expected != actual { + t.Fatalf("expected pin list to have len %d, was %d", expected, actual) + } + + cSet := cid.NewSet() + for _, c := range cids { + cSet.Add(c.Cid()) + } + + valid := true + for _, p := range pins { + c := p.Path().Cid() + if cSet.Has(c) { + cSet.Remove(c) + } else { + valid = false + break + } + } + + valid = valid && cSet.Len() == 0 + + if !valid { + pinStrs := make([]string, len(pins)) + for i, p := range pins { + pinStrs[i] = p.Path().Cid().String() + } + pathStrs := make([]string, len(cids)) + for i, c := range cids { + pathStrs[i] = c.Cid().String() + } + t.Fatalf("expected: %s \nactual: %s", strings.Join(pathStrs, ", "), strings.Join(pinStrs, ", ")) + } +} + +// assertPinLsAllConsistency verifies that listing all pins gives the same result as listing the pin types individually +func assertPinLsAllConsistency(t *testing.T, ctx context.Context, api iface.CoreAPI) { + t.Helper() + allPins, err := api.Pin().Ls(ctx) + if err != nil { + t.Fatal(err) + } + + type pinTypeProps struct { + *cid.Set + opt.PinLsOption + } + + all, recursive, direct, indirect := cid.NewSet(), cid.NewSet(), cid.NewSet(), cid.NewSet() + typeMap := map[string]*pinTypeProps{ + "recursive": {recursive, opt.Pin.Type.Recursive()}, + "direct": {direct, opt.Pin.Type.Direct()}, + "indirect": {indirect, opt.Pin.Type.Indirect()}, + } + + for _, p := range allPins { + if !all.Visit(p.Path().Cid()) { + t.Fatalf("pin ls returned the same cid multiple times") + } + + typeStr := p.Type() + if typeSet, ok := typeMap[p.Type()]; ok { + typeSet.Add(p.Path().Cid()) + } else { + t.Fatalf("unknown pin type: %s", typeStr) + } + } + + for typeStr, pinProps := range typeMap { + pins, err := api.Pin().Ls(ctx, pinProps.PinLsOption) + if err != nil { + t.Fatal(err) + } + + if expected, actual := len(pins), pinProps.Set.Len(); expected != actual { + t.Fatalf("pin ls all has %d pins of type %s, but pin ls for the type has %d", expected, typeStr, actual) + } + + for _, p := range pins { + if pinType := p.Type(); pinType != typeStr { + t.Fatalf("returned wrong pin type: expected %s, got %s", typeStr, pinType) + } + + if c := p.Path().Cid(); !pinProps.Has(c) { + t.Fatalf("%s expected to be in pin ls all as type %s", c.String(), typeStr) + } + } + } +} From e3b5686710f471a15d736c62ef2f6e66bbbec8a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Mur=C3=A9?= Date: Wed, 27 Nov 2019 21:40:22 +0100 Subject: [PATCH 0315/1212] feat: make the CoreAPI expose a streaming pin interface This commit was moved from ipfs/interface-go-ipfs-core@f976af7ba62d0209b53aeef72fb102c4387d3f00 This commit was moved from ipfs/boxo@6eb5c9791b91da125d269d84b201d0acc8e7657a --- core/coreiface/pin.go | 5 ++++- core/coreiface/tests/block.go | 2 +- core/coreiface/tests/pin.go | 39 ++++++++++++++++++++++++---------- core/coreiface/tests/unixfs.go | 2 +- 4 files changed, 34 insertions(+), 14 deletions(-) diff --git a/core/coreiface/pin.go b/core/coreiface/pin.go index 7df2956f0..27f9355d3 100644 --- a/core/coreiface/pin.go +++ b/core/coreiface/pin.go @@ -14,6 +14,9 @@ type Pin interface { // Type of the pin Type() string + + // if not nil, an error happened. Everything else should be ignored. + Err() error } // PinStatus holds information about pin health @@ -41,7 +44,7 @@ type PinAPI interface { Add(context.Context, path.Path, ...options.PinAddOption) error // Ls returns list of pinned objects on this node - Ls(context.Context, ...options.PinLsOption) ([]Pin, error) + Ls(context.Context, ...options.PinLsOption) (<-chan Pin, error) // Rm removes pin for object specified by the path Rm(context.Context, path.Path, ...options.PinRmOption) error diff --git a/core/coreiface/tests/block.go b/core/coreiface/tests/block.go index 6b648f394..2048dd4c2 100644 --- a/core/coreiface/tests/block.go +++ b/core/coreiface/tests/block.go @@ -225,7 +225,7 @@ func (tp *TestSuite) TestBlockPin(t *testing.T) { t.Fatal(err) } - pins, err := api.Pin().Ls(ctx) + pins, err := accPins(api.Pin().Ls(ctx)) if err != nil { return } diff --git a/core/coreiface/tests/pin.go b/core/coreiface/tests/pin.go index 7e574fa0d..a968490d3 100644 --- a/core/coreiface/tests/pin.go +++ b/core/coreiface/tests/pin.go @@ -67,7 +67,7 @@ func (tp *TestSuite) TestPinSimple(t *testing.T) { t.Fatal(err) } - list, err := api.Pin().Ls(ctx) + list, err := accPins(api.Pin().Ls(ctx)) if err != nil { t.Fatal(err) } @@ -89,7 +89,7 @@ func (tp *TestSuite) TestPinSimple(t *testing.T) { t.Fatal(err) } - list, err = api.Pin().Ls(ctx) + list, err = accPins(api.Pin().Ls(ctx)) if err != nil { t.Fatal(err) } @@ -141,7 +141,7 @@ func (tp *TestSuite) TestPinRecursive(t *testing.T) { t.Fatal(err) } - list, err := api.Pin().Ls(ctx) + list, err := accPins(api.Pin().Ls(ctx)) if err != nil { t.Fatal(err) } @@ -150,7 +150,7 @@ func (tp *TestSuite) TestPinRecursive(t *testing.T) { t.Errorf("unexpected pin list len: %d", len(list)) } - list, err = api.Pin().Ls(ctx, opt.Pin.Type.Direct()) + list, err = accPins(api.Pin().Ls(ctx, opt.Pin.Type.Direct())) if err != nil { t.Fatal(err) } @@ -163,7 +163,7 @@ func (tp *TestSuite) TestPinRecursive(t *testing.T) { t.Errorf("unexpected path, %s != %s", list[0].Path().String(), path.IpfsPath(nd2.Cid()).String()) } - list, err = api.Pin().Ls(ctx, opt.Pin.Type.Recursive()) + list, err = accPins(api.Pin().Ls(ctx, opt.Pin.Type.Recursive())) if err != nil { t.Fatal(err) } @@ -176,7 +176,7 @@ func (tp *TestSuite) TestPinRecursive(t *testing.T) { t.Errorf("unexpected path, %s != %s", list[0].Path().String(), path.IpldPath(nd3.Cid()).String()) } - list, err = api.Pin().Ls(ctx, opt.Pin.Type.Indirect()) + list, err = accPins(api.Pin().Ls(ctx, opt.Pin.Type.Indirect())) if err != nil { t.Fatal(err) } @@ -390,21 +390,21 @@ func getThreeChainedNodes(t *testing.T, ctx context.Context, api iface.CoreAPI, func assertPinTypes(t *testing.T, ctx context.Context, api iface.CoreAPI, recusive, direct, indirect []cidContainer) { assertPinLsAllConsistency(t, ctx, api) - list, err := api.Pin().Ls(ctx, opt.Pin.Type.Recursive()) + list, err := accPins(api.Pin().Ls(ctx, opt.Pin.Type.Recursive())) if err != nil { t.Fatal(err) } assertPinCids(t, list, recusive...) - list, err = api.Pin().Ls(ctx, opt.Pin.Type.Direct()) + list, err = accPins(api.Pin().Ls(ctx, opt.Pin.Type.Direct())) if err != nil { t.Fatal(err) } assertPinCids(t, list, direct...) - list, err = api.Pin().Ls(ctx, opt.Pin.Type.Indirect()) + list, err = accPins(api.Pin().Ls(ctx, opt.Pin.Type.Indirect())) if err != nil { t.Fatal(err) } @@ -454,7 +454,7 @@ func assertPinCids(t *testing.T, pins []iface.Pin, cids ...cidContainer) { // assertPinLsAllConsistency verifies that listing all pins gives the same result as listing the pin types individually func assertPinLsAllConsistency(t *testing.T, ctx context.Context, api iface.CoreAPI) { t.Helper() - allPins, err := api.Pin().Ls(ctx) + allPins, err := accPins(api.Pin().Ls(ctx)) if err != nil { t.Fatal(err) } @@ -485,7 +485,7 @@ func assertPinLsAllConsistency(t *testing.T, ctx context.Context, api iface.Core } for typeStr, pinProps := range typeMap { - pins, err := api.Pin().Ls(ctx, pinProps.PinLsOption) + pins, err := accPins(api.Pin().Ls(ctx, pinProps.PinLsOption)) if err != nil { t.Fatal(err) } @@ -505,3 +505,20 @@ func assertPinLsAllConsistency(t *testing.T, ctx context.Context, api iface.Core } } } + +func accPins(pins <-chan iface.Pin, err error) ([]iface.Pin, error) { + if err != nil { + return nil, err + } + + var result []iface.Pin + + for pin := range pins { + if pin.Err() != nil { + return nil, pin.Err() + } + result = append(result, pin) + } + + return result, nil +} diff --git a/core/coreiface/tests/unixfs.go b/core/coreiface/tests/unixfs.go index aac7fa92f..1ed80e873 100644 --- a/core/coreiface/tests/unixfs.go +++ b/core/coreiface/tests/unixfs.go @@ -542,7 +542,7 @@ func (tp *TestSuite) TestAddPinned(t *testing.T) { t.Fatal(err) } - pins, err := api.Pin().Ls(ctx) + pins, err := accPins(api.Pin().Ls(ctx)) if err != nil { t.Fatal(err) } From 8eff544241ee85a27617c0146dcaaae8054e4b8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Mur=C3=A9?= Date: Fri, 29 Nov 2019 22:21:29 +0100 Subject: [PATCH 0316/1212] fix some tests This commit was moved from ipfs/interface-go-ipfs-core@48dcedecd468c06e3321b4217b51f67180d07eec This commit was moved from ipfs/boxo@689e92b560ca2404db9edd1e8b65cd1a5e929881 --- core/coreiface/tests/block.go | 2 +- core/coreiface/tests/pin.go | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/core/coreiface/tests/block.go b/core/coreiface/tests/block.go index 2048dd4c2..51c099bd0 100644 --- a/core/coreiface/tests/block.go +++ b/core/coreiface/tests/block.go @@ -227,7 +227,7 @@ func (tp *TestSuite) TestBlockPin(t *testing.T) { pins, err := accPins(api.Pin().Ls(ctx)) if err != nil { - return + t.Skip(err) } if len(pins) != 1 { t.Fatal("expected 1 pin") diff --git a/core/coreiface/tests/pin.go b/core/coreiface/tests/pin.go index a968490d3..58e812084 100644 --- a/core/coreiface/tests/pin.go +++ b/core/coreiface/tests/pin.go @@ -160,7 +160,7 @@ func (tp *TestSuite) TestPinRecursive(t *testing.T) { } if list[0].Path().String() != path.IpldPath(nd3.Cid()).String() { - t.Errorf("unexpected path, %s != %s", list[0].Path().String(), path.IpfsPath(nd2.Cid()).String()) + t.Errorf("unexpected path, %s != %s", list[0].Path().String(), path.IpfsPath(nd3.Cid()).String()) } list, err = accPins(api.Pin().Ls(ctx, opt.Pin.Type.Recursive())) @@ -173,7 +173,7 @@ func (tp *TestSuite) TestPinRecursive(t *testing.T) { } if list[0].Path().String() != path.IpldPath(nd2.Cid()).String() { - t.Errorf("unexpected path, %s != %s", list[0].Path().String(), path.IpldPath(nd3.Cid()).String()) + t.Errorf("unexpected path, %s != %s", list[0].Path().String(), path.IpldPath(nd2.Cid()).String()) } list, err = accPins(api.Pin().Ls(ctx, opt.Pin.Type.Indirect())) @@ -186,7 +186,7 @@ func (tp *TestSuite) TestPinRecursive(t *testing.T) { } if list[0].Path().Cid().String() != p0.Cid().String() { - t.Error("unexpected path") + t.Errorf("unexpected path, %s != %s", list[0].Path().Cid().String(), p0.Cid().String()) } res, err := api.Pin().Verify(ctx) From e5059d9e1de51229ce49b275665903d9511adffb Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Mon, 2 Dec 2019 15:04:28 -0500 Subject: [PATCH 0317/1212] fix(tests): put valid blocks This commit was moved from ipfs/interface-go-ipfs-core@16127b291793c593b78fb2909bbaf106612ffc30 This commit was moved from ipfs/boxo@b1c5044d1541aa39ed8e6fff8f47c71bf012a7eb --- core/coreiface/tests/block.go | 52 ++++++++++++++++++++++++++--------- 1 file changed, 39 insertions(+), 13 deletions(-) diff --git a/core/coreiface/tests/block.go b/core/coreiface/tests/block.go index 51c099bd0..09a36b5fe 100644 --- a/core/coreiface/tests/block.go +++ b/core/coreiface/tests/block.go @@ -1,18 +1,34 @@ package tests import ( + "bytes" "context" - "github.com/ipfs/interface-go-ipfs-core/path" + "io" "io/ioutil" "strings" "testing" coreiface "github.com/ipfs/interface-go-ipfs-core" opt "github.com/ipfs/interface-go-ipfs-core/options" + "github.com/ipfs/interface-go-ipfs-core/path" mh "github.com/multiformats/go-multihash" ) +var ( + pbCid = "QmZULkCELmmk5XNfCgTnCyFgAVxBRBXyDHGGMVoLFLiXEN" + cborCid = "bafyreicnga62zhxnmnlt6ymq5hcbsg7gdhqdu6z4ehu3wpjhvqnflfy6nm" + cborKCid = "bafyr2qgsohbwdlk7ajmmbb4lhoytmest4wdbe5xnexfvtxeatuyqqmwv3fgxp3pmhpc27gwey2cct56gloqefoqwcf3yqiqzsaqb7p4jefhcw" +) + +func pbBlock() io.Reader { + return bytes.NewReader([]byte{10, 12, 8, 2, 18, 6, 104, 101, 108, 108, 111, 10, 24, 6}) +} + +func cborBlock() io.Reader { + return bytes.NewReader([]byte{101, 72, 101, 108, 108, 111}) +} + func (tp *TestSuite) TestBlock(t *testing.T) { tp.hasApi(t, func(api coreiface.CoreAPI) error { if api.Block() == nil { @@ -38,12 +54,12 @@ func (tp *TestSuite) TestBlockPut(t *testing.T) { t.Fatal(err) } - res, err := api.Block().Put(ctx, strings.NewReader(`Hello`)) + res, err := api.Block().Put(ctx, pbBlock()) if err != nil { t.Fatal(err) } - if res.Path().Cid().String() != "QmPyo15ynbVrSTVdJL9th7JysHaAbXt9dM9tXk1bMHbRtk" { + if res.Path().Cid().String() != pbCid { t.Errorf("got wrong cid: %s", res.Path().Cid().String()) } } @@ -56,12 +72,12 @@ func (tp *TestSuite) TestBlockPutFormat(t *testing.T) { t.Fatal(err) } - res, err := api.Block().Put(ctx, strings.NewReader(`Hello`), opt.Block.Format("cbor")) + res, err := api.Block().Put(ctx, cborBlock(), opt.Block.Format("cbor")) if err != nil { t.Fatal(err) } - if res.Path().Cid().String() != "bafyreiayl6g3gitr7ys7kyng7sjywlrgimdoymco3jiyab6rozecmoazne" { + if res.Path().Cid().String() != cborCid { t.Errorf("got wrong cid: %s", res.Path().Cid().String()) } } @@ -74,12 +90,17 @@ func (tp *TestSuite) TestBlockPutHash(t *testing.T) { t.Fatal(err) } - res, err := api.Block().Put(ctx, strings.NewReader(`Hello`), opt.Block.Hash(mh.KECCAK_512, -1)) + res, err := api.Block().Put( + ctx, + cborBlock(), + opt.Block.Hash(mh.KECCAK_512, -1), + opt.Block.Format("cbor"), + ) if err != nil { t.Fatal(err) } - if res.Path().Cid().String() != "bafyb2qgdh7w6dcq24u65xbtdoehyavegnpvxcqce7ttvs6ielgmwdfxrahmu37d33atik57x5y6s7d7qz32aasuwgirh3ocn6ywswqdifvu6e" { + if res.Path().Cid().String() != cborKCid { t.Errorf("got wrong cid: %s", res.Path().Cid().String()) } } @@ -92,7 +113,7 @@ func (tp *TestSuite) TestBlockGet(t *testing.T) { t.Fatal(err) } - res, err := api.Block().Put(ctx, strings.NewReader(`Hello`), opt.Block.Hash(mh.KECCAK_512, -1)) + res, err := api.Block().Put(ctx, strings.NewReader(`Hello`), opt.Block.Format("raw")) if err != nil { t.Fatal(err) } @@ -130,7 +151,7 @@ func (tp *TestSuite) TestBlockRm(t *testing.T) { t.Fatal(err) } - res, err := api.Block().Put(ctx, strings.NewReader(`Hello`)) + res, err := api.Block().Put(ctx, strings.NewReader(`Hello`), opt.Block.Format("raw")) if err != nil { t.Fatal(err) } @@ -184,7 +205,7 @@ func (tp *TestSuite) TestBlockStat(t *testing.T) { t.Fatal(err) } - res, err := api.Block().Put(ctx, strings.NewReader(`Hello`)) + res, err := api.Block().Put(ctx, strings.NewReader(`Hello`), opt.Block.Format("raw")) if err != nil { t.Fatal(err) } @@ -211,7 +232,7 @@ func (tp *TestSuite) TestBlockPin(t *testing.T) { t.Fatal(err) } - _, err = api.Block().Put(ctx, strings.NewReader(`Hello`)) + _, err = api.Block().Put(ctx, strings.NewReader(`Hello`), opt.Block.Format("raw")) if err != nil { t.Fatal(err) } @@ -220,14 +241,19 @@ func (tp *TestSuite) TestBlockPin(t *testing.T) { t.Fatal("expected 0 pins") } - res, err := api.Block().Put(ctx, strings.NewReader(`Hello`), opt.Block.Pin(true)) + res, err := api.Block().Put( + ctx, + strings.NewReader(`Hello`), + opt.Block.Pin(true), + opt.Block.Format("raw"), + ) if err != nil { t.Fatal(err) } pins, err := accPins(api.Pin().Ls(ctx)) if err != nil { - t.Skip(err) + t.Fatal(err) } if len(pins) != 1 { t.Fatal("expected 1 pin") From 8f9306304efdc60147eccbb49380b83e3c7cb4ea Mon Sep 17 00:00:00 2001 From: Joel Gustafson Date: Sat, 7 Dec 2019 01:08:48 -0500 Subject: [PATCH 0318/1212] Update pin.go This commit was moved from ipfs/go-ipfs-http-client@31b4e60d961ada25cb7b40317b18011b284436a7 --- client/httpapi/pin.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/httpapi/pin.go b/client/httpapi/pin.go index ec0fc91a8..6026c71b3 100644 --- a/client/httpapi/pin.go +++ b/client/httpapi/pin.go @@ -86,7 +86,7 @@ func (api *PinAPI) Update(ctx context.Context, from path.Path, to path.Path, opt return err } - return api.core().Request("pin/update"). + return api.core().Request("pin/update", from.String(), to.String()). Option("unpin", options.Unpin).Exec(ctx, nil) } From 80a898dd552426b37593889eaa68b870f4c0cfe6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Mur=C3=A9?= Date: Wed, 22 Jan 2020 17:11:19 +0100 Subject: [PATCH 0319/1212] test: fail early on err to avoid an unrelated panic This commit was moved from ipfs/interface-go-ipfs-core@df21c57e0f09b481b02f09cf3da20d17d25414e9 This commit was moved from ipfs/boxo@7a2fc1b8165e4079351f62ed4eec6a3fd9bd0aac --- core/coreiface/tests/block.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/coreiface/tests/block.go b/core/coreiface/tests/block.go index 6b648f394..3777d2259 100644 --- a/core/coreiface/tests/block.go +++ b/core/coreiface/tests/block.go @@ -156,7 +156,7 @@ func (tp *TestSuite) TestBlockRm(t *testing.T) { _, err = api.Block().Get(ctx, res.Path()) if err == nil { - t.Error("expected err to exist") + t.Fatal("expected err to exist") } if !strings.Contains(err.Error(), "blockservice: key not found") { t.Errorf("unexpected error; %s", err.Error()) @@ -164,7 +164,7 @@ func (tp *TestSuite) TestBlockRm(t *testing.T) { err = api.Block().Rm(ctx, res.Path()) if err == nil { - t.Error("expected err to exist") + t.Fatal("expected err to exist") } if !strings.Contains(err.Error(), "blockstore: block not found") { t.Errorf("unexpected error; %s", err.Error()) From b52034068c6f306f3d111b3dfce9427535127e2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Mur=C3=A9?= Date: Fri, 29 Nov 2019 22:33:13 +0100 Subject: [PATCH 0320/1212] pin: add a IsPinned method This commit was moved from ipfs/interface-go-ipfs-core@c82db2ef2270a228185aaba6b08ecd7157a7ebee This commit was moved from ipfs/boxo@e84cc0569818ce3b28ff7ea27b5077fe17232163 --- core/coreiface/options/pin.go | 198 ++++++++++++++++++++++++++-------- core/coreiface/pin.go | 4 + core/coreiface/tests/pin.go | 95 ++++++++++++++-- 3 files changed, 244 insertions(+), 53 deletions(-) diff --git a/core/coreiface/options/pin.go b/core/coreiface/options/pin.go index 6b211bb73..231f0d11a 100644 --- a/core/coreiface/options/pin.go +++ b/core/coreiface/options/pin.go @@ -1,13 +1,23 @@ package options +import "fmt" + type PinAddSettings struct { Recursive bool } +type TypeSettings struct { + Type string +} + type PinLsSettings struct { Type string } +type PinIsPinnedSettings struct { + WithType string +} + // PinRmSettings represents the settings of pin rm command type PinRmSettings struct { Recursive bool @@ -17,13 +27,19 @@ type PinUpdateSettings struct { Unpin bool } +// PinAddOption pin add option func type PinAddOption func(*PinAddSettings) error +// PinLsOption pin ls option func +type PinLsOption func(*PinLsSettings) error + +// PinIsPinnedOption pin isPinned option func +type PinIsPinnedOption func(*PinIsPinnedSettings) error + // PinRmOption pin rm option func type PinRmOption func(*PinRmSettings) error -// PinLsOption pin ls option func -type PinLsOption func(*PinLsSettings) error +// PinUpdateOption pin update option func type PinUpdateOption func(*PinUpdateSettings) error func PinAddOptions(opts ...PinAddOption) (*PinAddSettings, error) { @@ -41,6 +57,36 @@ func PinAddOptions(opts ...PinAddOption) (*PinAddSettings, error) { return options, nil } +func PinLsOptions(opts ...PinLsOption) (*PinLsSettings, error) { + options := &PinLsSettings{ + Type: "all", + } + + for _, opt := range opts { + err := opt(options) + if err != nil { + return nil, err + } + } + + return options, nil +} + +func PinIsPinnedOptions(opts ...PinIsPinnedOption) (*PinIsPinnedSettings, error) { + options := &PinIsPinnedSettings{ + WithType: "all", + } + + for _, opt := range opts { + err := opt(options) + if err != nil { + return nil, err + } + } + + return options, nil +} + // PinRmOptions pin rm options func PinRmOptions(opts ...PinRmOption) (*PinRmSettings, error) { options := &PinRmSettings{ @@ -56,21 +102,6 @@ func PinRmOptions(opts ...PinRmOption) (*PinRmSettings, error) { return options, nil } -func PinLsOptions(opts ...PinLsOption) (*PinLsSettings, error) { - options := &PinLsSettings{ - Type: "all", - } - - for _, opt := range opts { - err := opt(options) - if err != nil { - return nil, err - } - } - - return options, nil -} - func PinUpdateOptions(opts ...PinUpdateOption) (*PinUpdateSettings, error) { options := &PinUpdateSettings{ Unpin: true, @@ -86,36 +117,131 @@ func PinUpdateOptions(opts ...PinUpdateOption) (*PinUpdateSettings, error) { return options, nil } -type pinType struct{} - type pinOpts struct { - Type pinType + Ls pinLsOpts + IsPinned pinIsPinnedOpts } var Pin pinOpts +type pinLsOpts struct{} + // All is an option for Pin.Ls which will make it return all pins. It is // the default -func (pinType) All() PinLsOption { - return Pin.pinType("all") +func (pinLsOpts) All() PinLsOption { + return Pin.Ls.pinType("all") } // Recursive is an option for Pin.Ls which will make it only return recursive // pins -func (pinType) Recursive() PinLsOption { - return Pin.pinType("recursive") +func (pinLsOpts) Recursive() PinLsOption { + return Pin.Ls.pinType("recursive") } // Direct is an option for Pin.Ls which will make it only return direct (non // recursive) pins -func (pinType) Direct() PinLsOption { - return Pin.pinType("direct") +func (pinLsOpts) Direct() PinLsOption { + return Pin.Ls.pinType("direct") } // Indirect is an option for Pin.Ls which will make it only return indirect pins // (objects referenced by other recursively pinned objects) -func (pinType) Indirect() PinLsOption { - return Pin.pinType("indirect") +func (pinLsOpts) Indirect() PinLsOption { + return Pin.Ls.pinType("indirect") +} + +// Type is an option for Pin.Ls which will make it only return pins of the given +// type. +// +// Supported values: +// * "direct" - directly pinned objects +// * "recursive" - roots of recursive pins +// * "indirect" - indirectly pinned objects (referenced by recursively pinned +// objects) +// * "all" - all pinned objects (default) +func (pinLsOpts) Type(typeStr string) (PinLsOption, error) { + switch typeStr { + case "all", "direct", "indirect", "recursive": + return Pin.Ls.pinType(typeStr), nil + default: + return nil, fmt.Errorf("invalid type '%s', must be one of {direct, indirect, recursive, all}", typeStr) + } +} + +// pinType is an option for Pin.Ls which allows to specify which pin types should +// be returned +// +// Supported values: +// * "direct" - directly pinned objects +// * "recursive" - roots of recursive pins +// * "indirect" - indirectly pinned objects (referenced by recursively pinned +// objects) +// * "all" - all pinned objects (default) +func (pinLsOpts) pinType(t string) PinLsOption { + return func(settings *PinLsSettings) error { + settings.Type = t + return nil + } +} + +type pinIsPinnedOpts struct{} + +// All is an option for Pin.IsPinned which will make it search in all type of pins. +// It is the default +func (pinIsPinnedOpts) All() PinIsPinnedOption { + return Pin.IsPinned.pinType("all") +} + +// Recursive is an option for Pin.IsPinned which will make it only search in +// recursive pins +func (pinIsPinnedOpts) Recursive() PinIsPinnedOption { + return Pin.IsPinned.pinType("recursive") +} + +// Direct is an option for Pin.IsPinned which will make it only search in direct +// (non recursive) pins +func (pinIsPinnedOpts) Direct() PinIsPinnedOption { + return Pin.IsPinned.pinType("direct") +} + +// Indirect is an option for Pin.IsPinned which will make it only search indirect +// pins (objects referenced by other recursively pinned objects) +func (pinIsPinnedOpts) Indirect() PinIsPinnedOption { + return Pin.IsPinned.pinType("indirect") +} + +// Type is an option for Pin.IsPinned which will make it only search pins of the given +// type. +// +// Supported values: +// * "direct" - directly pinned objects +// * "recursive" - roots of recursive pins +// * "indirect" - indirectly pinned objects (referenced by recursively pinned +// objects) +// * "all" - all pinned objects (default) +func (pinIsPinnedOpts) Type(typeStr string) (PinIsPinnedOption, error) { + switch typeStr { + case "all", "direct", "indirect", "recursive": + return Pin.IsPinned.pinType(typeStr), nil + default: + return nil, fmt.Errorf("invalid type '%s', must be one of {direct, indirect, recursive, all}", typeStr) + } +} + +// pinType is an option for Pin.IsPinned which allows to specify which pin type the given +// pin is expected to be, speeding up the research. +// +// Supported values: +// * "direct" - directly pinned objects +// * "recursive" - roots of recursive pins +// * "indirect" - indirectly pinned objects (referenced by recursively pinned +// objects) +// * "all" - all pinned objects (default) +func (pinIsPinnedOpts) pinType(t string) PinIsPinnedOption { + return func(settings *PinIsPinnedSettings) error { + settings.WithType = t + return nil + } } // Recursive is an option for Pin.Add which specifies whether to pin an entire @@ -137,22 +263,6 @@ func (pinOpts) RmRecursive(recursive bool) PinRmOption { } } -// Type is an option for Pin.Ls which allows to specify which pin types should -// be returned -// -// Supported values: -// * "direct" - directly pinned objects -// * "recursive" - roots of recursive pins -// * "indirect" - indirectly pinned objects (referenced by recursively pinned -// objects) -// * "all" - all pinned objects (default) -func (pinOpts) pinType(t string) PinLsOption { - return func(settings *PinLsSettings) error { - settings.Type = t - return nil - } -} - // Unpin is an option for Pin.Update which specifies whether to remove the old pin. // Default is true. func (pinOpts) Unpin(unpin bool) PinUpdateOption { diff --git a/core/coreiface/pin.go b/core/coreiface/pin.go index 27f9355d3..4c1788c68 100644 --- a/core/coreiface/pin.go +++ b/core/coreiface/pin.go @@ -46,6 +46,10 @@ type PinAPI interface { // Ls returns list of pinned objects on this node Ls(context.Context, ...options.PinLsOption) (<-chan Pin, error) + // IsPinned returns whether or not the given cid is pinned + // and an explanation of why its pinned + IsPinned(context.Context, path.Path, ...options.PinIsPinnedOption) (string, bool, error) + // Rm removes pin for object specified by the path Rm(context.Context, path.Path, ...options.PinRmOption) error diff --git a/core/coreiface/tests/pin.go b/core/coreiface/tests/pin.go index 58e812084..e16d6460b 100644 --- a/core/coreiface/tests/pin.go +++ b/core/coreiface/tests/pin.go @@ -28,6 +28,7 @@ func (tp *TestSuite) TestPin(t *testing.T) { t.Run("TestPinRecursive", tp.TestPinRecursive) t.Run("TestPinLsIndirect", tp.TestPinLsIndirect) t.Run("TestPinLsPrecedence", tp.TestPinLsPrecedence) + t.Run("TestPinIsPinned", tp.TestPinIsPinned) } func (tp *TestSuite) TestPinAdd(t *testing.T) { @@ -84,6 +85,8 @@ func (tp *TestSuite) TestPinSimple(t *testing.T) { t.Error("unexpected pin type") } + assertIsPinned(t, ctx, api, p, "recursive") + err = api.Pin().Rm(ctx, p) if err != nil { t.Fatal(err) @@ -150,7 +153,7 @@ func (tp *TestSuite) TestPinRecursive(t *testing.T) { t.Errorf("unexpected pin list len: %d", len(list)) } - list, err = accPins(api.Pin().Ls(ctx, opt.Pin.Type.Direct())) + list, err = accPins(api.Pin().Ls(ctx, opt.Pin.Ls.Direct())) if err != nil { t.Fatal(err) } @@ -163,7 +166,7 @@ func (tp *TestSuite) TestPinRecursive(t *testing.T) { t.Errorf("unexpected path, %s != %s", list[0].Path().String(), path.IpfsPath(nd3.Cid()).String()) } - list, err = accPins(api.Pin().Ls(ctx, opt.Pin.Type.Recursive())) + list, err = accPins(api.Pin().Ls(ctx, opt.Pin.Ls.Recursive())) if err != nil { t.Fatal(err) } @@ -176,7 +179,7 @@ func (tp *TestSuite) TestPinRecursive(t *testing.T) { t.Errorf("unexpected path, %s != %s", list[0].Path().String(), path.IpldPath(nd2.Cid()).String()) } - list, err = accPins(api.Pin().Ls(ctx, opt.Pin.Type.Indirect())) + list, err = accPins(api.Pin().Ls(ctx, opt.Pin.Ls.Indirect())) if err != nil { t.Fatal(err) } @@ -360,6 +363,39 @@ func (tp *TestSuite) TestPinLsPrecedenceRecursiveDirect(t *testing.T) { assertPinTypes(t, ctx, api, []cidContainer{grandparent, parent}, []cidContainer{}, []cidContainer{leaf}) } +func (tp *TestSuite) TestPinIsPinned(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + api, err := tp.makeAPI(ctx) + if err != nil { + t.Fatal(err) + } + + leaf, parent, grandparent := getThreeChainedNodes(t, ctx, api, "foofoo") + + assertNotPinned(t, ctx, api, path.IpldPath(grandparent.Cid())) + assertNotPinned(t, ctx, api, path.IpldPath(parent.Cid())) + assertNotPinned(t, ctx, api, path.IpldPath(leaf.Cid())) + + err = api.Pin().Add(ctx, path.IpldPath(parent.Cid()), opt.Pin.Recursive(true)) + if err != nil { + t.Fatal(err) + } + + assertNotPinned(t, ctx, api, path.IpldPath(grandparent.Cid())) + assertIsPinned(t, ctx, api, path.IpldPath(parent.Cid()), "recursive") + assertIsPinned(t, ctx, api, path.IpldPath(leaf.Cid()), "indirect") + + err = api.Pin().Add(ctx, path.IpldPath(grandparent.Cid()), opt.Pin.Recursive(false)) + if err != nil { + t.Fatal(err) + } + + assertIsPinned(t, ctx, api, path.IpldPath(grandparent.Cid()), "direct") + assertIsPinned(t, ctx, api, path.IpldPath(parent.Cid()), "recursive") + assertIsPinned(t, ctx, api, path.IpldPath(leaf.Cid()), "indirect") +} + type cidContainer interface { Cid() cid.Cid } @@ -390,21 +426,21 @@ func getThreeChainedNodes(t *testing.T, ctx context.Context, api iface.CoreAPI, func assertPinTypes(t *testing.T, ctx context.Context, api iface.CoreAPI, recusive, direct, indirect []cidContainer) { assertPinLsAllConsistency(t, ctx, api) - list, err := accPins(api.Pin().Ls(ctx, opt.Pin.Type.Recursive())) + list, err := accPins(api.Pin().Ls(ctx, opt.Pin.Ls.Recursive())) if err != nil { t.Fatal(err) } assertPinCids(t, list, recusive...) - list, err = accPins(api.Pin().Ls(ctx, opt.Pin.Type.Direct())) + list, err = accPins(api.Pin().Ls(ctx, opt.Pin.Ls.Direct())) if err != nil { t.Fatal(err) } assertPinCids(t, list, direct...) - list, err = accPins(api.Pin().Ls(ctx, opt.Pin.Type.Indirect())) + list, err = accPins(api.Pin().Ls(ctx, opt.Pin.Ls.Indirect())) if err != nil { t.Fatal(err) } @@ -466,9 +502,9 @@ func assertPinLsAllConsistency(t *testing.T, ctx context.Context, api iface.Core all, recursive, direct, indirect := cid.NewSet(), cid.NewSet(), cid.NewSet(), cid.NewSet() typeMap := map[string]*pinTypeProps{ - "recursive": {recursive, opt.Pin.Type.Recursive()}, - "direct": {direct, opt.Pin.Type.Direct()}, - "indirect": {indirect, opt.Pin.Type.Indirect()}, + "recursive": {recursive, opt.Pin.Ls.Recursive()}, + "direct": {direct, opt.Pin.Ls.Direct()}, + "indirect": {indirect, opt.Pin.Ls.Indirect()}, } for _, p := range allPins { @@ -506,6 +542,47 @@ func assertPinLsAllConsistency(t *testing.T, ctx context.Context, api iface.Core } } +func assertIsPinned(t *testing.T, ctx context.Context, api iface.CoreAPI, p path.Path, typeStr string) { + t.Helper() + withType, err := opt.Pin.IsPinned.Type(typeStr) + if err != nil { + panic("unhandled pin type") + } + + whyPinned, pinned, err := api.Pin().IsPinned(ctx, p, withType) + if err != nil { + t.Fatal(err) + } + + if !pinned { + t.Fatalf("%s expected to be pinned with type %s", p, typeStr) + } + + switch typeStr { + case "recursive", "direct": + if typeStr != whyPinned { + t.Fatalf("reason for pinning expected to be %s for %s, got %s", typeStr, p, whyPinned) + } + case "indirect": + if whyPinned == "" { + t.Fatalf("expected to have a pin reason for %s", p) + } + } +} + +func assertNotPinned(t *testing.T, ctx context.Context, api iface.CoreAPI, p path.Path) { + t.Helper() + + _, pinned, err := api.Pin().IsPinned(ctx, p) + if err != nil { + t.Fatal(err) + } + + if pinned { + t.Fatalf("%s expected to not be pinned", p) + } +} + func accPins(pins <-chan iface.Pin, err error) ([]iface.Pin, error) { if err != nil { return nil, err From 7f07bf09966647107c25bbe8e60be1803c7496fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Mur=C3=A9?= Date: Mon, 30 Mar 2020 16:20:15 +0200 Subject: [PATCH 0321/1212] pin: better doc, small cleaning This commit was moved from ipfs/interface-go-ipfs-core@478caf05ab8fd3b33ae80f8792be2cb7c7a92b45 This commit was moved from ipfs/boxo@bffa011f0a0f01646bcecbc003552941ca31860b --- core/coreiface/options/pin.go | 32 +++++++++++++++++++++----------- core/coreiface/tests/pin.go | 2 +- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/core/coreiface/options/pin.go b/core/coreiface/options/pin.go index 231f0d11a..5014a2d2b 100644 --- a/core/coreiface/options/pin.go +++ b/core/coreiface/options/pin.go @@ -2,46 +2,48 @@ package options import "fmt" +// PinAddSettings represent the settings for PinAPI.Add type PinAddSettings struct { Recursive bool } -type TypeSettings struct { - Type string -} - +// PinLsSettings represent the settings for PinAPI.Ls type PinLsSettings struct { Type string } +// PinIsPinnedSettings represent the settings for PinAPI.IsPinned type PinIsPinnedSettings struct { WithType string } -// PinRmSettings represents the settings of pin rm command +// PinRmSettings represents the settings for PinAPI.Rm type PinRmSettings struct { Recursive bool } +// PinUpdateSettings represent the settings for PinAPI.Update type PinUpdateSettings struct { Unpin bool } -// PinAddOption pin add option func +// PinAddOption is the signature of an option for PinAPI.Add type PinAddOption func(*PinAddSettings) error -// PinLsOption pin ls option func +// PinLsOption is the signature of an option for PinAPI.Ls type PinLsOption func(*PinLsSettings) error -// PinIsPinnedOption pin isPinned option func +// PinIsPinnedOption is the signature of an option for PinAPI.IsPinned type PinIsPinnedOption func(*PinIsPinnedSettings) error -// PinRmOption pin rm option func +// PinRmOption is the signature of an option for PinAPI.Rm type PinRmOption func(*PinRmSettings) error -// PinUpdateOption pin update option func +// PinUpdateOption is the signature of an option for PinAPI.Update type PinUpdateOption func(*PinUpdateSettings) error +// PinAddOptions compile a series of PinAddOption into a ready to use +// PinAddSettings and set the default values. func PinAddOptions(opts ...PinAddOption) (*PinAddSettings, error) { options := &PinAddSettings{ Recursive: true, @@ -57,6 +59,8 @@ func PinAddOptions(opts ...PinAddOption) (*PinAddSettings, error) { return options, nil } +// PinLsOptions compile a series of PinLsOption into a ready to use +// PinLsSettings and set the default values. func PinLsOptions(opts ...PinLsOption) (*PinLsSettings, error) { options := &PinLsSettings{ Type: "all", @@ -72,6 +76,8 @@ func PinLsOptions(opts ...PinLsOption) (*PinLsSettings, error) { return options, nil } +// PinIsPinnedOptions compile a series of PinIsPinnedOption into a ready to use +// PinIsPinnedSettings and set the default values. func PinIsPinnedOptions(opts ...PinIsPinnedOption) (*PinIsPinnedSettings, error) { options := &PinIsPinnedSettings{ WithType: "all", @@ -87,7 +93,8 @@ func PinIsPinnedOptions(opts ...PinIsPinnedOption) (*PinIsPinnedSettings, error) return options, nil } -// PinRmOptions pin rm options +// PinRmOptions compile a series of PinRmOption into a ready to use +// PinRmSettings and set the default values. func PinRmOptions(opts ...PinRmOption) (*PinRmSettings, error) { options := &PinRmSettings{ Recursive: true, @@ -102,6 +109,8 @@ func PinRmOptions(opts ...PinRmOption) (*PinRmSettings, error) { return options, nil } +// PinUpdateOptions compile a series of PinUpdateOption into a ready to use +// PinUpdateSettings and set the default values. func PinUpdateOptions(opts ...PinUpdateOption) (*PinUpdateSettings, error) { options := &PinUpdateSettings{ Unpin: true, @@ -122,6 +131,7 @@ type pinOpts struct { IsPinned pinIsPinnedOpts } +// Pin provide an access to all the options for the Pin API. var Pin pinOpts type pinLsOpts struct{} diff --git a/core/coreiface/tests/pin.go b/core/coreiface/tests/pin.go index e16d6460b..476bbea6b 100644 --- a/core/coreiface/tests/pin.go +++ b/core/coreiface/tests/pin.go @@ -546,7 +546,7 @@ func assertIsPinned(t *testing.T, ctx context.Context, api iface.CoreAPI, p path t.Helper() withType, err := opt.Pin.IsPinned.Type(typeStr) if err != nil { - panic("unhandled pin type") + t.Fatal("unhandled pin type") } whyPinned, pinned, err := api.Pin().IsPinned(ctx, p, withType) From 3a48c527193cc7688f488da875bb065459a12809 Mon Sep 17 00:00:00 2001 From: Will Scott Date: Tue, 21 Apr 2020 08:40:13 -0700 Subject: [PATCH 0322/1212] extra time for dht spin-up This commit was moved from ipfs/interface-go-ipfs-core@9160e645322d5779c687e0e60cbec5a5932d5c27 This commit was moved from ipfs/boxo@0ed0b6f39d3ab3b20bd6dd2232de03a9513b139c --- core/coreiface/tests/dht.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/core/coreiface/tests/dht.go b/core/coreiface/tests/dht.go index 33b4ff14c..a957d66d7 100644 --- a/core/coreiface/tests/dht.go +++ b/core/coreiface/tests/dht.go @@ -4,8 +4,9 @@ import ( "context" "io" "testing" + "time" - "github.com/ipfs/interface-go-ipfs-core" + iface "github.com/ipfs/interface-go-ipfs-core" "github.com/ipfs/interface-go-ipfs-core/options" ) @@ -43,6 +44,8 @@ func (tp *TestSuite) TestDhtFindPeer(t *testing.T) { t.Fatal("unexpected number of local addrs") } + time.Sleep(3 * time.Second) + pi, err := apis[2].Dht().FindPeer(ctx, self0.ID()) if err != nil { t.Fatal(err) @@ -88,6 +91,8 @@ func (tp *TestSuite) TestDhtFindProviders(t *testing.T) { t.Fatal(err) } + time.Sleep(3 * time.Second) + out, err := apis[2].Dht().FindProviders(ctx, p, options.Dht.NumProviders(1)) if err != nil { t.Fatal(err) @@ -125,6 +130,8 @@ func (tp *TestSuite) TestDhtProvide(t *testing.T) { p := s.Path() + time.Sleep(3 * time.Second) + out, err := apis[2].Dht().FindProviders(ctx, p, options.Dht.NumProviders(1)) if err != nil { t.Fatal(err) From d9004a9061070263dcc01976334836acb9493530 Mon Sep 17 00:00:00 2001 From: Will Scott Date: Sun, 3 May 2020 12:04:04 -0700 Subject: [PATCH 0323/1212] IDB58Decode -> Decode Allow Non-RSA keys to be decoded by the HTTP client This commit was moved from ipfs/go-ipfs-http-client@b0549d86231d69a933b0e4b771c350cf1bf5c27b --- client/httpapi/key.go | 12 ++++++------ client/httpapi/pubsub.go | 4 ++-- client/httpapi/swarm.go | 6 +++--- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/client/httpapi/key.go b/client/httpapi/key.go index cf22c6108..78b67517c 100644 --- a/client/httpapi/key.go +++ b/client/httpapi/key.go @@ -4,7 +4,7 @@ import ( "context" "errors" - "github.com/ipfs/interface-go-ipfs-core" + iface "github.com/ipfs/interface-go-ipfs-core" caopts "github.com/ipfs/interface-go-ipfs-core/options" "github.com/ipfs/interface-go-ipfs-core/path" "github.com/libp2p/go-libp2p-core/peer" @@ -45,7 +45,7 @@ func (api *KeyAPI) Generate(ctx context.Context, name string, opts ...caopts.Key if err != nil { return nil, err } - out.pid, err = peer.IDB58Decode(out.Id) + out.pid, err = peer.Decode(out.Id) return &out, err } @@ -69,7 +69,7 @@ func (api *KeyAPI) Rename(ctx context.Context, oldName string, newName string, o } id := &keyOutput{JName: out.Now, Id: out.Id} - id.pid, err = peer.IDB58Decode(id.Id) + id.pid, err = peer.Decode(id.Id) return id, out.Overwrite, err } @@ -82,7 +82,7 @@ func (api *KeyAPI) List(ctx context.Context) ([]iface.Key, error) { res := make([]iface.Key, len(out.Keys)) for i, k := range out.Keys { var err error - k.pid, err = peer.IDB58Decode(k.Id) + k.pid, err = peer.Decode(k.Id) if err != nil { return nil, err } @@ -100,7 +100,7 @@ func (api *KeyAPI) Self(ctx context.Context) (iface.Key, error) { var err error out := keyOutput{JName: "self", Id: id.ID} - out.pid, err = peer.IDB58Decode(out.Id) + out.pid, err = peer.Decode(out.Id) return &out, err } @@ -114,7 +114,7 @@ func (api *KeyAPI) Remove(ctx context.Context, name string) (iface.Key, error) { } var err error - out.Keys[0].pid, err = peer.IDB58Decode(out.Keys[0].Id) + out.Keys[0].pid, err = peer.Decode(out.Keys[0].Id) return &out.Keys[0], err } diff --git a/client/httpapi/pubsub.go b/client/httpapi/pubsub.go index 81ddb5211..da7c59ef1 100644 --- a/client/httpapi/pubsub.go +++ b/client/httpapi/pubsub.go @@ -6,7 +6,7 @@ import ( "encoding/json" "io" - "github.com/ipfs/interface-go-ipfs-core" + iface "github.com/ipfs/interface-go-ipfs-core" caopts "github.com/ipfs/interface-go-ipfs-core/options" "github.com/libp2p/go-libp2p-core/peer" ) @@ -41,7 +41,7 @@ func (api *PubsubAPI) Peers(ctx context.Context, opts ...caopts.PubSubPeersOptio res := make([]peer.ID, len(out.Strings)) for i, sid := range out.Strings { - id, err := peer.IDB58Decode(sid) + id, err := peer.Decode(sid) if err != nil { return nil, err } diff --git a/client/httpapi/swarm.go b/client/httpapi/swarm.go index 10280c39f..1cb0d91df 100644 --- a/client/httpapi/swarm.go +++ b/client/httpapi/swarm.go @@ -4,7 +4,7 @@ import ( "context" "time" - "github.com/ipfs/interface-go-ipfs-core" + iface "github.com/ipfs/interface-go-ipfs-core" "github.com/libp2p/go-libp2p-core/network" "github.com/libp2p/go-libp2p-core/peer" "github.com/libp2p/go-libp2p-core/protocol" @@ -91,7 +91,7 @@ func (api *SwarmAPI) Peers(ctx context.Context) ([]iface.ConnectionInfo, error) direction: conn.Direction, } - out.peer, err = peer.IDB58Decode(conn.Peer) + out.peer, err = peer.Decode(conn.Peer) if err != nil { return nil, err } @@ -131,7 +131,7 @@ func (api *SwarmAPI) KnownAddrs(ctx context.Context) (map[peer.ID][]multiaddr.Mu addrs[i] = a } - pid, err := peer.IDB58Decode(spid) + pid, err := peer.Decode(spid) if err != nil { return nil, err } From 7ebef96ba12bfdfc550412748ee16eadcaffd25d Mon Sep 17 00:00:00 2001 From: Bryan Stenson Date: Tue, 12 May 2020 20:09:16 +0000 Subject: [PATCH 0324/1212] update contributing link This commit was moved from ipfs/go-ipfs-http-client@ef2a556e19e8d9ebafcb24b3574724c6d7718bc8 --- client/httpapi/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/httpapi/README.md b/client/httpapi/README.md index e5ab1c612..376e6590e 100644 --- a/client/httpapi/README.md +++ b/client/httpapi/README.md @@ -25,7 +25,7 @@ This repository falls under the IPFS [Code of Conduct](https://github.com/ipfs/c ### Want to hack on IPFS? -[![](https://cdn.rawgit.com/jbenet/contribute-ipfs-gif/master/img/contribute.gif)](https://github.com/ipfs/community/blob/master/contributing.md) +[![](https://cdn.rawgit.com/jbenet/contribute-ipfs-gif/master/img/contribute.gif)](https://github.com/ipfs/community/blob/master/CONTRIBUTING.md) ## License From 2517d0b9d49911add8b923a48030e4f7cbf0a0b9 Mon Sep 17 00:00:00 2001 From: Petar Maymounkov Date: Wed, 22 Jul 2020 09:05:14 -0700 Subject: [PATCH 0325/1212] add id and key formatting utils; format keys as b36cid by default; update tests This commit was moved from ipfs/interface-go-ipfs-core@c604c5b0338c075046d7ddf0b60c5927500607d3 This commit was moved from ipfs/boxo@7bcd64373825dfda1ef91c9d9157a5328928cc09 --- core/coreiface/idfmt.go | 19 ++++++++++++++ core/coreiface/tests/key.go | 49 +++++++++++++++++++++++------------- core/coreiface/tests/name.go | 30 +++++++++++----------- 3 files changed, 66 insertions(+), 32 deletions(-) create mode 100644 core/coreiface/idfmt.go diff --git a/core/coreiface/idfmt.go b/core/coreiface/idfmt.go new file mode 100644 index 000000000..1ba79e602 --- /dev/null +++ b/core/coreiface/idfmt.go @@ -0,0 +1,19 @@ +package iface + +import ( + peer "github.com/libp2p/go-libp2p-core/peer" + mbase "github.com/multiformats/go-multibase" +) + +func FormatKeyID(id peer.ID) string { + if s, err := peer.ToCid(id).StringOfBase(mbase.Base36); err != nil { + panic(err) + } else { + return s + } +} + +// FormatKey formats the given IPNS key in a canonical way. +func FormatKey(key Key) string { + return FormatKeyID(key.ID()) +} diff --git a/core/coreiface/tests/key.go b/core/coreiface/tests/key.go index 265a8f060..c3cd8626f 100644 --- a/core/coreiface/tests/key.go +++ b/core/coreiface/tests/key.go @@ -5,8 +5,11 @@ import ( "strings" "testing" - "github.com/ipfs/interface-go-ipfs-core" + cid "github.com/ipfs/go-cid" + coreiface "github.com/ipfs/interface-go-ipfs-core" + iface "github.com/ipfs/interface-go-ipfs-core" opt "github.com/ipfs/interface-go-ipfs-core/options" + mbase "github.com/multiformats/go-multibase" ) func (tp *TestSuite) TestKey(t *testing.T) { @@ -64,8 +67,8 @@ func (tp *TestSuite) TestListSelf(t *testing.T) { t.Errorf("expected the key to be called 'self', got '%s'", keys[0].Name()) } - if keys[0].Path().String() != "/ipns/"+self.ID().Pretty() { - t.Errorf("expected the key to have path '/ipns/%s', got '%s'", self.ID().Pretty(), keys[0].Path().String()) + if keys[0].Path().String() != "/ipns/"+coreiface.FormatKeyID(self.ID()) { + t.Errorf("expected the key to have path '/ipns/%s', got '%s'", coreiface.FormatKeyID(self.ID()), keys[0].Path().String()) } } @@ -134,9 +137,30 @@ func (tp *TestSuite) TestGenerate(t *testing.T) { t.Errorf("expected the key to be called 'foo', got '%s'", k.Name()) } - if !strings.HasPrefix(k.Path().String(), "/ipns/Qm") { - t.Errorf("expected the key to be prefixed with '/ipns/Qm', got '%s'", k.Path().String()) + verifyIPNSPath(t, k.Path().String()) +} + +func verifyIPNSPath(t *testing.T, p string) bool { + t.Helper() + if !strings.HasPrefix(p, "/ipns/") { + t.Errorf("path %q does not look like an IPNS path", p) + return false } + k := p[len("/ipns/"):] + c, err := cid.Decode(k) + if err != nil { + t.Errorf("failed to decode IPNS key %q (%v)", k, err) + return false + } + b36, err := c.StringOfBase(mbase.Base36) + if err != nil { + t.Fatalf("cid cannot format itself in b36") + return false + } + if b36 != k { + t.Errorf("IPNS key is not base36") + } + return true } func (tp *TestSuite) TestGenerateSize(t *testing.T) { @@ -157,9 +181,7 @@ func (tp *TestSuite) TestGenerateSize(t *testing.T) { t.Errorf("expected the key to be called 'foo', got '%s'", k.Name()) } - if !strings.HasPrefix(k.Path().String(), "/ipns/Qm") { - t.Errorf("expected the key to be prefixed with '/ipns/Qm', got '%s'", k.Path().String()) - } + verifyIPNSPath(t, k.Path().String()) } func (tp *TestSuite) TestGenerateType(t *testing.T) { @@ -256,15 +278,8 @@ func (tp *TestSuite) TestList(t *testing.T) { return } - if !strings.HasPrefix(l[0].Path().String(), "/ipns/Qm") { - t.Fatalf("expected key 0 to be prefixed with '/ipns/Qm', got '%s'", l[0].Name()) - return - } - - if !strings.HasPrefix(l[1].Path().String(), "/ipns/Qm") { - t.Fatalf("expected key 1 to be prefixed with '/ipns/Qm', got '%s'", l[1].Name()) - return - } + verifyIPNSPath(t, l[0].Path().String()) + verifyIPNSPath(t, l[1].Path().String()) } func (tp *TestSuite) TestRename(t *testing.T) { diff --git a/core/coreiface/tests/name.go b/core/coreiface/tests/name.go index 31a5c1466..021c1bb97 100644 --- a/core/coreiface/tests/name.go +++ b/core/coreiface/tests/name.go @@ -2,15 +2,15 @@ package tests import ( "context" - path "github.com/ipfs/interface-go-ipfs-core/path" "io" "math/rand" gopath "path" "testing" "time" - "github.com/ipfs/go-ipfs-files" - ipath "github.com/ipfs/go-path" + path "github.com/ipfs/interface-go-ipfs-core/path" + + files "github.com/ipfs/go-ipfs-files" coreiface "github.com/ipfs/interface-go-ipfs-core" opt "github.com/ipfs/interface-go-ipfs-core/options" @@ -70,8 +70,8 @@ func (tp *TestSuite) TestPublishResolve(t *testing.T) { t.Fatal(err) } - if e.Name() != self.ID().Pretty() { - t.Errorf("expected e.Name to equal '%s', got '%s'", self.ID().Pretty(), e.Name()) + if e.Name() != coreiface.FormatKeyID(self.ID()) { + t.Errorf("expected e.Name to equal '%s', got '%s'", coreiface.FormatKeyID(self.ID()), e.Name()) } if e.Value().String() != p.String() { @@ -100,8 +100,8 @@ func (tp *TestSuite) TestPublishResolve(t *testing.T) { t.Fatal(err) } - if e.Name() != self.ID().Pretty() { - t.Errorf("expected e.Name to equal '%s', got '%s'", self.ID().Pretty(), e.Name()) + if e.Name() != coreiface.FormatKeyID(self.ID()) { + t.Errorf("expected e.Name to equal '%s', got '%s'", coreiface.FormatKeyID(self.ID()), e.Name()) } if e.Value().String() != p.String()+"/test" { @@ -130,8 +130,8 @@ func (tp *TestSuite) TestPublishResolve(t *testing.T) { t.Fatal(err) } - if e.Name() != self.ID().Pretty() { - t.Errorf("expected e.Name to equal '%s', got '%s'", self.ID().Pretty(), e.Name()) + if e.Name() != coreiface.FormatKeyID(self.ID()) { + t.Errorf("expected e.Name to equal '%s', got '%s'", coreiface.FormatKeyID(self.ID()), e.Name()) } if e.Value().String() != p.String() { @@ -160,8 +160,8 @@ func (tp *TestSuite) TestPublishResolve(t *testing.T) { t.Fatal(err) } - if e.Name() != self.ID().Pretty() { - t.Errorf("expected e.Name to equal '%s', got '%s'", self.ID().Pretty(), e.Name()) + if e.Name() != coreiface.FormatKeyID(self.ID()) { + t.Errorf("expected e.Name to equal '%s', got '%s'", coreiface.FormatKeyID(self.ID()), e.Name()) } if e.Value().String() != p.String()+"/a" { @@ -212,8 +212,8 @@ func (tp *TestSuite) TestBasicPublishResolveKey(t *testing.T) { t.Fatal(err) } - if ipath.Join([]string{"/ipns", e.Name()}) != k.Path().String() { - t.Errorf("expected e.Name to equal '%s', got '%s'", e.Name(), k.Path().String()) + if e.Name() != coreiface.FormatKey(k) { + t.Errorf("expected e.Name to equal %s, got '%s'", e.Name(), coreiface.FormatKey(k)) } if e.Value().String() != p.String() { @@ -255,8 +255,8 @@ func (tp *TestSuite) TestBasicPublishResolveTimeout(t *testing.T) { t.Fatal(err) } - if e.Name() != self.ID().Pretty() { - t.Errorf("expected e.Name to equal '%s', got '%s'", self.ID().Pretty(), e.Name()) + if e.Name() != coreiface.FormatKeyID(self.ID()) { + t.Errorf("expected e.Name to equal '%s', got '%s'", coreiface.FormatKeyID(self.ID()), e.Name()) } if e.Value().String() != p.String() { From 247cb05fbc4fa3863542ecd9e0e5109c927790c6 Mon Sep 17 00:00:00 2001 From: Petar Maymounkov Date: Fri, 31 Jul 2020 10:20:59 -0700 Subject: [PATCH 0326/1212] Bump interface-go-ipfs-core version (#117) * fix issues #26 Implement an IsPinned function * fix issues #113 Implement interface v0.3.0 * ci: update to use go-ipfs v0.6.0 * ci: bump go version Co-authored-by: godcong Co-authored-by: Adin Schmahmann This commit was moved from ipfs/go-ipfs-http-client@4e8a6c8b981f808062caa4ef7481babc0a39f298 --- client/httpapi/pin.go | 54 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 45 insertions(+), 9 deletions(-) diff --git a/client/httpapi/pin.go b/client/httpapi/pin.go index 6026c71b3..bd3e5423b 100644 --- a/client/httpapi/pin.go +++ b/client/httpapi/pin.go @@ -3,9 +3,10 @@ package httpapi import ( "context" "encoding/json" + "strings" "github.com/ipfs/go-cid" - "github.com/ipfs/interface-go-ipfs-core" + iface "github.com/ipfs/interface-go-ipfs-core" caopts "github.com/ipfs/interface-go-ipfs-core/options" "github.com/ipfs/interface-go-ipfs-core/path" "github.com/pkg/errors" @@ -24,6 +25,11 @@ type pinRefKeyList struct { type pin struct { path path.Resolved typ string + err error +} + +func (p *pin) Err() error { + return p.err } func (p *pin) Path() path.Resolved { @@ -44,7 +50,7 @@ func (api *PinAPI) Add(ctx context.Context, p path.Path, opts ...caopts.PinAddOp Option("recursive", options.Recursive).Exec(ctx, nil) } -func (api *PinAPI) Ls(ctx context.Context, opts ...caopts.PinLsOption) ([]iface.Pin, error) { +func (api *PinAPI) Ls(ctx context.Context, opts ...caopts.PinLsOption) (<-chan iface.Pin, error) { options, err := caopts.PinLsOptions(opts...) if err != nil { return nil, err @@ -57,16 +63,46 @@ func (api *PinAPI) Ls(ctx context.Context, opts ...caopts.PinLsOption) ([]iface. return nil, err } - pins := make([]iface.Pin, 0, len(out.Keys)) - for hash, p := range out.Keys { - c, err := cid.Parse(hash) - if err != nil { - return nil, err + pins := make(chan iface.Pin) + go func(ch chan<- iface.Pin) { + defer close(ch) + for hash, p := range out.Keys { + c, e := cid.Parse(hash) + if e != nil { + ch <- &pin{typ: p.Type, err: e} + return + } + ch <- &pin{typ: p.Type, path: path.IpldPath(c), err: e} } - pins = append(pins, &pin{typ: p.Type, path: path.IpldPath(c)}) + }(pins) + return pins, nil +} + +// IsPinned returns whether or not the given cid is pinned +// and an explanation of why its pinned +func (api *PinAPI) IsPinned(ctx context.Context, p path.Path, opts ...caopts.PinIsPinnedOption) (string, bool, error) { + options, err := caopts.PinIsPinnedOptions(opts...) + if err != nil { + return "", false, err + } + var out pinRefKeyList + err = api.core().Request("pin/ls"). + Option("type", options.WithType). + Option("arg", p.String()). + Exec(ctx, &out) + if err != nil { + // TODO: This error-type discrimination based on sub-string matching is brittle. + // It is addressed by this open issue: https://github.com/ipfs/go-ipfs/issues/7563 + if strings.Index(err.Error(), "is not pinned") != -1 { + return "", false, nil + } + return "", false, err } - return pins, nil + for _, obj := range out.Keys { + return obj.Type, true, nil + } + return "", false, errors.New("http api returned no error and no results") } func (api *PinAPI) Rm(ctx context.Context, p path.Path, opts ...caopts.PinRmOption) error { From ea2a35686db523b544245cbaea5592021d0cd163 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Sat, 15 May 2021 18:21:24 -0700 Subject: [PATCH 0327/1212] fix staticcheck This commit was moved from ipfs/go-ipfs-http-client@4461a0bb952ce0a05a5bab9728cc64b658375068 --- client/httpapi/api.go | 17 ++++++++--------- client/httpapi/api_test.go | 7 +++---- client/httpapi/object.go | 3 +-- client/httpapi/pin.go | 2 +- 4 files changed, 13 insertions(+), 16 deletions(-) diff --git a/client/httpapi/api.go b/client/httpapi/api.go index ec16c4b2d..f589e4267 100644 --- a/client/httpapi/api.go +++ b/client/httpapi/api.go @@ -5,7 +5,6 @@ import ( "fmt" "io/ioutil" "net/http" - gohttp "net/http" "os" "path/filepath" "strings" @@ -14,7 +13,7 @@ import ( caopts "github.com/ipfs/interface-go-ipfs-core/options" "github.com/mitchellh/go-homedir" ma "github.com/multiformats/go-multiaddr" - manet "github.com/multiformats/go-multiaddr-net" + manet "github.com/multiformats/go-multiaddr/net" ) const ( @@ -34,7 +33,7 @@ var ErrApiNotFound = errors.New("ipfs api address could not be found") // https://godoc.org/github.com/ipfs/interface-go-ipfs-core#CoreAPI type HttpApi struct { url string - httpcli gohttp.Client + httpcli http.Client Headers http.Header applyGlobal func(*requestBuilder) } @@ -85,9 +84,9 @@ func ApiAddr(ipfspath string) (ma.Multiaddr, error) { // NewApi constructs HttpApi with specified endpoint func NewApi(a ma.Multiaddr) (*HttpApi, error) { - c := &gohttp.Client{ - Transport: &gohttp.Transport{ - Proxy: gohttp.ProxyFromEnvironment, + c := &http.Client{ + Transport: &http.Transport{ + Proxy: http.ProxyFromEnvironment, DisableKeepAlives: true, }, } @@ -96,7 +95,7 @@ func NewApi(a ma.Multiaddr) (*HttpApi, error) { } // NewApiWithClient constructs HttpApi with specified endpoint and custom http client -func NewApiWithClient(a ma.Multiaddr, c *gohttp.Client) (*HttpApi, error) { +func NewApiWithClient(a ma.Multiaddr, c *http.Client) (*HttpApi, error) { _, url, err := manet.DialArgs(a) if err != nil { return nil, err @@ -112,7 +111,7 @@ func NewApiWithClient(a ma.Multiaddr, c *gohttp.Client) (*HttpApi, error) { return NewURLApiWithClient(url, c) } -func NewURLApiWithClient(url string, c *gohttp.Client) (*HttpApi, error) { +func NewURLApiWithClient(url string, c *http.Client) (*HttpApi, error) { api := &HttpApi{ url: url, httpcli: *c, @@ -121,7 +120,7 @@ func NewURLApiWithClient(url string, c *gohttp.Client) (*HttpApi, error) { } // We don't support redirects. - api.httpcli.CheckRedirect = func(_ *gohttp.Request, _ []*gohttp.Request) error { + api.httpcli.CheckRedirect = func(_ *http.Request, _ []*http.Request) error { return fmt.Errorf("unexpected redirect") } return api, nil diff --git a/client/httpapi/api_test.go b/client/httpapi/api_test.go index 5f012b476..35a57d2c0 100644 --- a/client/httpapi/api_test.go +++ b/client/httpapi/api_test.go @@ -4,7 +4,6 @@ import ( "context" "io/ioutil" "net/http" - gohttp "net/http" "net/http/httptest" "os" "strconv" @@ -163,9 +162,9 @@ func (NodeProvider) makeAPISwarm(ctx context.Context, fullIdentity bool, n int) return } - c := &gohttp.Client{ - Transport: &gohttp.Transport{ - Proxy: gohttp.ProxyFromEnvironment, + c := &http.Client{ + Transport: &http.Transport{ + Proxy: http.ProxyFromEnvironment, DisableKeepAlives: true, DisableCompression: true, }, diff --git a/client/httpapi/object.go b/client/httpapi/object.go index 280b2490f..6ec7f5503 100644 --- a/client/httpapi/object.go +++ b/client/httpapi/object.go @@ -10,7 +10,6 @@ import ( "github.com/ipfs/go-cid" ipld "github.com/ipfs/go-ipld-format" "github.com/ipfs/go-merkledag" - dag "github.com/ipfs/go-merkledag" ft "github.com/ipfs/go-unixfs" "github.com/ipfs/interface-go-ipfs-core" caopts "github.com/ipfs/interface-go-ipfs-core/options" @@ -32,7 +31,7 @@ func (api *ObjectAPI) New(ctx context.Context, opts ...caopts.ObjectNewOption) ( var n ipld.Node switch options.Type { case "empty": - n = new(dag.ProtoNode) + n = new(merkledag.ProtoNode) case "unixfs-dir": n = ft.EmptyDirNode() default: diff --git a/client/httpapi/pin.go b/client/httpapi/pin.go index bd3e5423b..13de2d389 100644 --- a/client/httpapi/pin.go +++ b/client/httpapi/pin.go @@ -93,7 +93,7 @@ func (api *PinAPI) IsPinned(ctx context.Context, p path.Path, opts ...caopts.Pin if err != nil { // TODO: This error-type discrimination based on sub-string matching is brittle. // It is addressed by this open issue: https://github.com/ipfs/go-ipfs/issues/7563 - if strings.Index(err.Error(), "is not pinned") != -1 { + if strings.Contains(err.Error(), "is not pinned") { return "", false, nil } return "", false, err From fb0a7edf12a24be1b80fc5a487c183e70048062a Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Wed, 2 Jun 2021 09:11:14 -0700 Subject: [PATCH 0328/1212] fix staticcheck This commit was moved from ipfs/interface-go-ipfs-core@08bd316e61238880f341d7061c518c2a62830bd9 This commit was moved from ipfs/boxo@5df09f84256c8b490f356c161c96b49d3a46bfd0 --- core/coreiface/tests/api.go | 2 +- core/coreiface/tests/block.go | 2 +- core/coreiface/tests/dag.go | 2 +- core/coreiface/tests/dht.go | 2 +- core/coreiface/tests/key.go | 12 ++++++------ core/coreiface/tests/name.go | 2 +- core/coreiface/tests/object.go | 2 +- core/coreiface/tests/pin.go | 2 +- core/coreiface/tests/pubsub.go | 2 +- core/coreiface/tests/unixfs.go | 5 ++--- 10 files changed, 16 insertions(+), 17 deletions(-) diff --git a/core/coreiface/tests/api.go b/core/coreiface/tests/api.go index 1af3a83b3..0801b3ca7 100644 --- a/core/coreiface/tests/api.go +++ b/core/coreiface/tests/api.go @@ -9,7 +9,7 @@ import ( coreiface "github.com/ipfs/interface-go-ipfs-core" ) -var apiNotImplemented = errors.New("api not implemented") +var errAPINotImplemented = errors.New("api not implemented") func (tp *TestSuite) makeAPI(ctx context.Context) (coreiface.CoreAPI, error) { api, err := tp.MakeAPISwarm(ctx, false, 1) diff --git a/core/coreiface/tests/block.go b/core/coreiface/tests/block.go index 1f7252547..7dbfa4df0 100644 --- a/core/coreiface/tests/block.go +++ b/core/coreiface/tests/block.go @@ -32,7 +32,7 @@ func cborBlock() io.Reader { func (tp *TestSuite) TestBlock(t *testing.T) { tp.hasApi(t, func(api coreiface.CoreAPI) error { if api.Block() == nil { - return apiNotImplemented + return errAPINotImplemented } return nil }) diff --git a/core/coreiface/tests/dag.go b/core/coreiface/tests/dag.go index 2f68bbf05..6f9d9659e 100644 --- a/core/coreiface/tests/dag.go +++ b/core/coreiface/tests/dag.go @@ -18,7 +18,7 @@ import ( func (tp *TestSuite) TestDag(t *testing.T) { tp.hasApi(t, func(api coreiface.CoreAPI) error { if api.Dag() == nil { - return apiNotImplemented + return errAPINotImplemented } return nil }) diff --git a/core/coreiface/tests/dht.go b/core/coreiface/tests/dht.go index a957d66d7..c2e6d690f 100644 --- a/core/coreiface/tests/dht.go +++ b/core/coreiface/tests/dht.go @@ -13,7 +13,7 @@ import ( func (tp *TestSuite) TestDht(t *testing.T) { tp.hasApi(t, func(api iface.CoreAPI) error { if api.Dht() == nil { - return apiNotImplemented + return errAPINotImplemented } return nil }) diff --git a/core/coreiface/tests/key.go b/core/coreiface/tests/key.go index c3cd8626f..47f278f97 100644 --- a/core/coreiface/tests/key.go +++ b/core/coreiface/tests/key.go @@ -5,8 +5,7 @@ import ( "strings" "testing" - cid "github.com/ipfs/go-cid" - coreiface "github.com/ipfs/interface-go-ipfs-core" + "github.com/ipfs/go-cid" iface "github.com/ipfs/interface-go-ipfs-core" opt "github.com/ipfs/interface-go-ipfs-core/options" mbase "github.com/multiformats/go-multibase" @@ -15,7 +14,7 @@ import ( func (tp *TestSuite) TestKey(t *testing.T) { tp.hasApi(t, func(api iface.CoreAPI) error { if api.Key() == nil { - return apiNotImplemented + return errAPINotImplemented } return nil }) @@ -67,8 +66,8 @@ func (tp *TestSuite) TestListSelf(t *testing.T) { t.Errorf("expected the key to be called 'self', got '%s'", keys[0].Name()) } - if keys[0].Path().String() != "/ipns/"+coreiface.FormatKeyID(self.ID()) { - t.Errorf("expected the key to have path '/ipns/%s', got '%s'", coreiface.FormatKeyID(self.ID()), keys[0].Path().String()) + if keys[0].Path().String() != "/ipns/"+iface.FormatKeyID(self.ID()) { + t.Errorf("expected the key to have path '/ipns/%s', got '%s'", iface.FormatKeyID(self.ID()), keys[0].Path().String()) } } @@ -185,9 +184,10 @@ func (tp *TestSuite) TestGenerateSize(t *testing.T) { } func (tp *TestSuite) TestGenerateType(t *testing.T) { + t.Skip("disabled until libp2p/specs#111 is fixed") + ctx, cancel := context.WithCancel(context.Background()) defer cancel() - t.Skip("disabled until libp2p/specs#111 is fixed") api, err := tp.makeAPI(ctx) if err != nil { diff --git a/core/coreiface/tests/name.go b/core/coreiface/tests/name.go index 021c1bb97..2a8b4d76a 100644 --- a/core/coreiface/tests/name.go +++ b/core/coreiface/tests/name.go @@ -19,7 +19,7 @@ import ( func (tp *TestSuite) TestName(t *testing.T) { tp.hasApi(t, func(api coreiface.CoreAPI) error { if api.Name() == nil { - return apiNotImplemented + return errAPINotImplemented } return nil }) diff --git a/core/coreiface/tests/object.go b/core/coreiface/tests/object.go index 2e066ca71..e8ab1a7f4 100644 --- a/core/coreiface/tests/object.go +++ b/core/coreiface/tests/object.go @@ -15,7 +15,7 @@ import ( func (tp *TestSuite) TestObject(t *testing.T) { tp.hasApi(t, func(api iface.CoreAPI) error { if api.Object() == nil { - return apiNotImplemented + return errAPINotImplemented } return nil }) diff --git a/core/coreiface/tests/pin.go b/core/coreiface/tests/pin.go index 476bbea6b..d378d1015 100644 --- a/core/coreiface/tests/pin.go +++ b/core/coreiface/tests/pin.go @@ -18,7 +18,7 @@ import ( func (tp *TestSuite) TestPin(t *testing.T) { tp.hasApi(t, func(api iface.CoreAPI) error { if api.Pin() == nil { - return apiNotImplemented + return errAPINotImplemented } return nil }) diff --git a/core/coreiface/tests/pubsub.go b/core/coreiface/tests/pubsub.go index 36353f836..f8339f228 100644 --- a/core/coreiface/tests/pubsub.go +++ b/core/coreiface/tests/pubsub.go @@ -12,7 +12,7 @@ import ( func (tp *TestSuite) TestPubSub(t *testing.T) { tp.hasApi(t, func(api iface.CoreAPI) error { if api.PubSub() == nil { - return apiNotImplemented + return errAPINotImplemented } return nil }) diff --git a/core/coreiface/tests/unixfs.go b/core/coreiface/tests/unixfs.go index 1ed80e873..4273386aa 100644 --- a/core/coreiface/tests/unixfs.go +++ b/core/coreiface/tests/unixfs.go @@ -31,7 +31,7 @@ import ( func (tp *TestSuite) TestUnixfs(t *testing.T) { tp.hasApi(t, func(api coreiface.CoreAPI) error { if api.Unixfs() == nil { - return apiNotImplemented + return errAPINotImplemented } return nil }) @@ -1035,8 +1035,7 @@ func (tp *TestSuite) TestGetReadAt(t *testing.T) { origR := bytes.NewReader(orig) - r, err = api.Unixfs().Get(ctx, p) - if err != nil { + if _, err := api.Unixfs().Get(ctx, p); err != nil { t.Fatal(err) } From 58c9824ce49e83378d63d6c3a1aa9ed2f2417a5b Mon Sep 17 00:00:00 2001 From: Hannah Howard Date: Thu, 12 Aug 2021 09:35:49 -0700 Subject: [PATCH 0329/1212] IPLD In IPFS: Target Merge Branch (#67) * update go-path and error message * add node api for prime interactions * use go-unixfsnode * update against fetcher Co-authored-by: acruikshank This commit was moved from ipfs/interface-go-ipfs-core@49cdff8024e607072e57a7f7556e9875d2aa0412 This commit was moved from ipfs/boxo@8f0db8f18428127afb5e6c114ada8c751d5116de --- core/coreiface/coreapi.go | 1 + core/coreiface/tests/path.go | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/core/coreiface/coreapi.go b/core/coreiface/coreapi.go index 12cb166a8..aacda0459 100644 --- a/core/coreiface/coreapi.go +++ b/core/coreiface/coreapi.go @@ -4,6 +4,7 @@ package iface import ( "context" + path "github.com/ipfs/interface-go-ipfs-core/path" "github.com/ipfs/interface-go-ipfs-core/options" diff --git a/core/coreiface/tests/path.go b/core/coreiface/tests/path.go index 2d9497244..5a249fabf 100644 --- a/core/coreiface/tests/path.go +++ b/core/coreiface/tests/path.go @@ -2,11 +2,14 @@ package tests import ( "context" - "github.com/ipfs/interface-go-ipfs-core/path" + "errors" "math" "strings" "testing" + "github.com/ipfs/go-path/resolver" + "github.com/ipfs/interface-go-ipfs-core/path" + "github.com/ipfs/interface-go-ipfs-core/options" ipldcbor "github.com/ipfs/go-ipld-cbor" @@ -138,7 +141,7 @@ func (tp *TestSuite) TestInvalidPathRemainder(t *testing.T) { } _, err = api.ResolvePath(ctx, path.New("/ipld/"+nd.Cid().String()+"/bar/baz")) - if err == nil || !strings.Contains(err.Error(), "no such link found") { + if err == nil || !errors.As(err, &resolver.ErrNoLink{}) { t.Fatalf("unexpected error: %s", err) } } From f909368aa097438d3ae19dc4c8f3b0512b79e540 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Tue, 17 Aug 2021 13:10:26 -0700 Subject: [PATCH 0330/1212] fix: check errors by string Unfortunately, we return errors over the HTTP API and lose the type. This commit was moved from ipfs/interface-go-ipfs-core@98e72571bc4514239cbe7bba4321ab5da4194366 This commit was moved from ipfs/boxo@b722930c08cda76a887769564a94055f41268c38 --- core/coreiface/tests/path.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/core/coreiface/tests/path.go b/core/coreiface/tests/path.go index 5a249fabf..f6d05372e 100644 --- a/core/coreiface/tests/path.go +++ b/core/coreiface/tests/path.go @@ -2,12 +2,10 @@ package tests import ( "context" - "errors" "math" "strings" "testing" - "github.com/ipfs/go-path/resolver" "github.com/ipfs/interface-go-ipfs-core/path" "github.com/ipfs/interface-go-ipfs-core/options" @@ -141,7 +139,7 @@ func (tp *TestSuite) TestInvalidPathRemainder(t *testing.T) { } _, err = api.ResolvePath(ctx, path.New("/ipld/"+nd.Cid().String()+"/bar/baz")) - if err == nil || !errors.As(err, &resolver.ErrNoLink{}) { + if err == nil || !strings.Contains(err.Error(), `no link named "bar"`) { t.Fatalf("unexpected error: %s", err) } } From 5322cf89e45197afb74cc36104ee581ca179c1d6 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Mon, 29 Nov 2021 22:24:27 +0100 Subject: [PATCH 0331/1212] feat: pubsub http rpc with multibase (#151) * feat: pubsub http rpc with multibase This updates HTTP RPC wire format to one from https://github.com/ipfs/go-ipfs/pull/8183 * chore: use updated go-ipfs * chore: switch ci to go-ipfs master This commit was moved from ipfs/go-ipfs-http-client@c832fc0ce1d8235c830fecd0dd44dda04a9fba37 --- client/httpapi/README.md | 6 ++-- client/httpapi/pubsub.go | 78 +++++++++++++++++++++++++++++++--------- 2 files changed, 64 insertions(+), 20 deletions(-) diff --git a/client/httpapi/README.md b/client/httpapi/README.md index 376e6590e..d3e14ac3f 100644 --- a/client/httpapi/README.md +++ b/client/httpapi/README.md @@ -1,8 +1,8 @@ # go-ipfs-http-api -[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://ipn.io) -[![](https://img.shields.io/badge/project-IPFS-blue.svg?style=flat-square)](http://ipfs.io/) -[![](https://img.shields.io/badge/freenode-%23ipfs-blue.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23ipfs) +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](https://protocol.ai) +[![](https://img.shields.io/badge/project-IPFS-blue.svg?style=flat-square)](https://ipfs.io/) +[![](https://img.shields.io/badge/matrix-%23ipfs-blue.svg?style=flat-square)](https://app.element.io/#/room/#ipfs:matrix.org) [![standard-readme compliant](https://img.shields.io/badge/standard--readme-OK-green.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme) [![GoDoc](https://godoc.org/github.com/ipfs/go-ipfs-http-api?status.svg)](https://godoc.org/github.com/ipfs/go-ipfs-http-api) diff --git a/client/httpapi/pubsub.go b/client/httpapi/pubsub.go index da7c59ef1..72f592376 100644 --- a/client/httpapi/pubsub.go +++ b/client/httpapi/pubsub.go @@ -9,6 +9,7 @@ import ( iface "github.com/ipfs/interface-go-ipfs-core" caopts "github.com/ipfs/interface-go-ipfs-core/options" "github.com/libp2p/go-libp2p-core/peer" + mbase "github.com/multiformats/go-multibase" ) type PubsubAPI HttpApi @@ -21,8 +22,15 @@ func (api *PubsubAPI) Ls(ctx context.Context) ([]string, error) { if err := api.core().Request("pubsub/ls").Exec(ctx, &out); err != nil { return nil, err } - - return out.Strings, nil + topics := make([]string, len(out.Strings)) + for n, mb := range out.Strings { + _, topic, err := mbase.Decode(mb) + if err != nil { + return nil, err + } + topics[n] = string(topic) + } + return topics, nil } func (api *PubsubAPI) Peers(ctx context.Context, opts ...caopts.PubSubPeersOption) ([]peer.ID, error) { @@ -35,7 +43,11 @@ func (api *PubsubAPI) Peers(ctx context.Context, opts ...caopts.PubSubPeersOptio Strings []string } - if err := api.core().Request("pubsub/peers", options.Topic).Exec(ctx, &out); err != nil { + var optionalTopic string + if len(options.Topic) > 0 { + optionalTopic = toMultibase([]byte(options.Topic)) + } + if err := api.core().Request("pubsub/peers", optionalTopic).Exec(ctx, &out); err != nil { return nil, err } @@ -51,7 +63,7 @@ func (api *PubsubAPI) Peers(ctx context.Context, opts ...caopts.PubSubPeersOptio } func (api *PubsubAPI) Publish(ctx context.Context, topic string, message []byte) error { - return api.core().Request("pubsub/pub", topic). + return api.core().Request("pubsub/pub", toMultibase([]byte(topic))). FileBody(bytes.NewReader(message)). Exec(ctx, nil) } @@ -64,13 +76,18 @@ type pubsubSub struct { } type pubsubMessage struct { - JFrom []byte `json:"from,omitempty"` - JData []byte `json:"data,omitempty"` - JSeqno []byte `json:"seqno,omitempty"` + JFrom string `json:"from,omitempty"` + JData string `json:"data,omitempty"` + JSeqno string `json:"seqno,omitempty"` JTopicIDs []string `json:"topicIDs,omitempty"` - from peer.ID - err error + // real values after unpacking from text/multibase envelopes + from peer.ID + data []byte + seqno []byte + topics []string + + err error } func (msg *pubsubMessage) From() peer.ID { @@ -78,15 +95,17 @@ func (msg *pubsubMessage) From() peer.ID { } func (msg *pubsubMessage) Data() []byte { - return msg.JData + return msg.data } func (msg *pubsubMessage) Seq() []byte { - return msg.JSeqno + return msg.seqno } +// TODO: do we want to keep this interface as []string, +// or change to more correct [][]byte? func (msg *pubsubMessage) Topics() []string { - return msg.JTopicIDs + return msg.topics } func (s *pubsubSub) Next(ctx context.Context) (iface.PubSubMessage, error) { @@ -98,22 +117,41 @@ func (s *pubsubSub) Next(ctx context.Context) (iface.PubSubMessage, error) { if msg.err != nil { return nil, msg.err } + // unpack values from text/multibase envelopes var err error - msg.from, err = peer.IDFromBytes(msg.JFrom) - return &msg, err + msg.from, err = peer.Decode(msg.JFrom) + if err != nil { + return nil, err + } + _, msg.data, err = mbase.Decode(msg.JData) + if err != nil { + return nil, err + } + _, msg.seqno, err = mbase.Decode(msg.JSeqno) + if err != nil { + return nil, err + } + for _, mbt := range msg.JTopicIDs { + _, topic, err := mbase.Decode(mbt) + if err != nil { + return nil, err + } + msg.topics = append(msg.topics, string(topic)) + } + return &msg, nil case <-ctx.Done(): return nil, ctx.Err() } } func (api *PubsubAPI) Subscribe(ctx context.Context, topic string, opts ...caopts.PubSubSubscribeOption) (iface.PubSubSubscription, error) { + /* right now we have no options (discover got deprecated) options, err := caopts.PubSubSubscribeOptions(opts...) if err != nil { return nil, err } - - resp, err := api.core().Request("pubsub/sub", topic). - Option("discover", options.Discover).Send(ctx) + */ + resp, err := api.core().Request("pubsub/sub", toMultibase([]byte(topic))).Send(ctx) if err != nil { return nil, err @@ -168,3 +206,9 @@ func (s *pubsubSub) Close() error { func (api *PubsubAPI) core() *HttpApi { return (*HttpApi)(api) } + +// Encodes bytes into URL-safe multibase that can be sent over HTTP RPC (URL or body) +func toMultibase(data []byte) string { + mb, _ := mbase.Encode(mbase.Base64url, data) + return mb +} From b52c80ca4da5730f47674946025c9490fcd50e1f Mon Sep 17 00:00:00 2001 From: galargh Date: Fri, 14 Jan 2022 16:16:26 +0100 Subject: [PATCH 0332/1212] skip TestHttpApi on Windows This commit was moved from ipfs/go-ipfs-http-client@a41c7956c0da2a4c51e15794b22dea09395cc7ef --- client/httpapi/api_test.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/client/httpapi/api_test.go b/client/httpapi/api_test.go index 35a57d2c0..d5f27f0ec 100644 --- a/client/httpapi/api_test.go +++ b/client/httpapi/api_test.go @@ -6,6 +6,7 @@ import ( "net/http" "net/http/httptest" "os" + "runtime" "strconv" "strings" "sync" @@ -207,6 +208,10 @@ func (NodeProvider) makeAPISwarm(ctx context.Context, fullIdentity bool, n int) } func TestHttpApi(t *testing.T) { + if runtime.GOOS == "windows" { + t.Skip("skipping due to #142") + } + ctx, cancel := context.WithCancel(context.Background()) defer cancel() From 49e2b34be58f7132851388652ec1da250bf13c20 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Wed, 2 Mar 2022 16:44:11 +0100 Subject: [PATCH 0333/1212] Update tests to use ipld.IsNotFound to check for notfound errors This commit was moved from ipfs/interface-go-ipfs-core@01ee9419a28353cab04979f0791133df9869f30a This commit was moved from ipfs/boxo@2263eca4a44789edb3c0d244c961c12bcb1585ad --- core/coreiface/tests/block.go | 5 +++-- core/coreiface/tests/unixfs.go | 8 +++++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/core/coreiface/tests/block.go b/core/coreiface/tests/block.go index 7dbfa4df0..8d0243e7e 100644 --- a/core/coreiface/tests/block.go +++ b/core/coreiface/tests/block.go @@ -8,6 +8,7 @@ import ( "strings" "testing" + ipld "github.com/ipfs/go-ipld-format" coreiface "github.com/ipfs/interface-go-ipfs-core" opt "github.com/ipfs/interface-go-ipfs-core/options" "github.com/ipfs/interface-go-ipfs-core/path" @@ -179,7 +180,7 @@ func (tp *TestSuite) TestBlockRm(t *testing.T) { if err == nil { t.Fatal("expected err to exist") } - if !strings.Contains(err.Error(), "blockservice: key not found") { + if !ipld.IsNotFound(err) { t.Errorf("unexpected error; %s", err.Error()) } @@ -187,7 +188,7 @@ func (tp *TestSuite) TestBlockRm(t *testing.T) { if err == nil { t.Fatal("expected err to exist") } - if !strings.Contains(err.Error(), "blockstore: block not found") { + if !strings.Contains(err.Error(), "not found") { t.Errorf("unexpected error; %s", err.Error()) } diff --git a/core/coreiface/tests/unixfs.go b/core/coreiface/tests/unixfs.go index 4273386aa..f47d34d0a 100644 --- a/core/coreiface/tests/unixfs.go +++ b/core/coreiface/tests/unixfs.go @@ -5,7 +5,6 @@ import ( "context" "encoding/hex" "fmt" - "github.com/ipfs/interface-go-ipfs-core/path" "io" "io/ioutil" "math" @@ -16,12 +15,15 @@ import ( "sync" "testing" + "github.com/ipfs/interface-go-ipfs-core/path" + coreiface "github.com/ipfs/interface-go-ipfs-core" "github.com/ipfs/interface-go-ipfs-core/options" "github.com/ipfs/go-cid" - "github.com/ipfs/go-ipfs-files" + files "github.com/ipfs/go-ipfs-files" cbor "github.com/ipfs/go-ipld-cbor" + ipld "github.com/ipfs/go-ipld-format" mdag "github.com/ipfs/go-merkledag" "github.com/ipfs/go-unixfs" "github.com/ipfs/go-unixfs/importer/helpers" @@ -576,7 +578,7 @@ func (tp *TestSuite) TestAddHashOnly(t *testing.T) { if err == nil { t.Fatal("expected an error") } - if !strings.Contains(err.Error(), "blockservice: key not found") { + if !ipld.IsNotFound(err) { t.Errorf("unxepected error: %s", err.Error()) } } From 29d037909ba8e25f5a62b240ac2b09c1d6591b03 Mon Sep 17 00:00:00 2001 From: godcong Date: Fri, 25 Mar 2022 22:32:10 +0800 Subject: [PATCH 0334/1212] fix: document error (#74) This commit was moved from ipfs/interface-go-ipfs-core@e9a299166898903a08f98e766aa23f452170496a This commit was moved from ipfs/boxo@f9d0ad972ce79a1fca890370606d585cf49416fe --- core/coreiface/coreapi.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/coreiface/coreapi.go b/core/coreiface/coreapi.go index aacda0459..894ffb318 100644 --- a/core/coreiface/coreapi.go +++ b/core/coreiface/coreapi.go @@ -32,7 +32,7 @@ type CoreAPI interface { // Pin returns an implementation of Pin API Pin() PinAPI - // ObjectAPI returns an implementation of Object API + // Object returns an implementation of Object API Object() ObjectAPI // Dht returns an implementation of Dht API From b85aa9639f861d659b49e0396b409398462226a2 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Sun, 27 Mar 2022 14:11:47 +0200 Subject: [PATCH 0335/1212] fix: make Block().* return correct ABI based ipld.ErrNotFound errors This commit was moved from ipfs/go-ipfs-http-client@4f5f8e9b144d1f38e0fc37c5080845611dcbcf1e --- client/httpapi/abyfy_errors.go | 104 ++++++++++++++++++++++++++++ client/httpapi/abyfy_errors_test.go | 60 ++++++++++++++++ client/httpapi/block.go | 11 +-- 3 files changed, 167 insertions(+), 8 deletions(-) create mode 100644 client/httpapi/abyfy_errors.go create mode 100644 client/httpapi/abyfy_errors_test.go diff --git a/client/httpapi/abyfy_errors.go b/client/httpapi/abyfy_errors.go new file mode 100644 index 000000000..e4f4afb7c --- /dev/null +++ b/client/httpapi/abyfy_errors.go @@ -0,0 +1,104 @@ +package httpapi + +import ( + "errors" + "strings" + + "github.com/ipfs/go-cid" + ipld "github.com/ipfs/go-ipld-format" +) + +type prePostWrappedNotFoundError struct { + pre string + post string + + wrapped ipld.ErrNotFound +} + +func (e prePostWrappedNotFoundError) String() string { + return e.Error() +} + +func (e prePostWrappedNotFoundError) Error() string { + return e.pre + e.wrapped.Error() + e.post +} + +func (e prePostWrappedNotFoundError) Unwrap() error { + return e.wrapped +} + +func abyfyIpldNotFoundFallbackToMSG(msg string) error { + err, handled := abyfyIpldNotFound(msg) + if handled { + return err + } + + return errors.New(msg) +} + +func abyfyIpldNotFoundFallbackToError(msg error) error { + err, handled := abyfyIpldNotFound(msg.Error()) + if handled { + return err + } + + return msg +} + +// This file handle parsing and returning the correct ABI based errors from error messages +//lint:ignore ST1008 this function is not using the error as a mean to return failure but it massages it to return the correct type +func abyfyIpldNotFound(msg string) (error, bool) { + if msg == "" { + return nil, true // Fast path + } + + // The patern we search for is: + // node not found (fallback) + // or + // CID not found (here we parse the CID) + notFoundIndex := strings.LastIndex(msg, " not found") + + if notFoundIndex == -1 { + // Unknown, ot found not found + return nil, false + } + + preNotFound := msg[:notFoundIndex] + + var c cid.Cid + var preIndex int + if strings.HasSuffix(preNotFound, "node") { + // Fallback case + c = cid.Undef + preIndex = notFoundIndex - len("node") + } else { + // Assume that CIDs does not include whitespace to pull out the CID + preIndex = strings.LastIndexByte(preNotFound, ' ') + // + 1 is to normalise not founds to zeros and point to the start of the CID, not the previous space + preIndex++ + var err error + c, err = cid.Decode(preNotFound[preIndex:]) + if err != nil { + // Unknown + return nil, false + } + } + + postIndex := notFoundIndex + len(" not found") + + err := ipld.ErrNotFound{Cid: c} + + pre := msg[:preIndex] + post := msg[postIndex:] + + if len(pre) > 0 || len(post) > 0 { + // We have some text to wrap arround the ErrNotFound one + return prePostWrappedNotFoundError{ + pre: pre, + post: post, + wrapped: err, + }, true + } + + return err, true +} diff --git a/client/httpapi/abyfy_errors_test.go b/client/httpapi/abyfy_errors_test.go new file mode 100644 index 000000000..fe1cf0707 --- /dev/null +++ b/client/httpapi/abyfy_errors_test.go @@ -0,0 +1,60 @@ +package httpapi + +import ( + "errors" + "fmt" + "testing" + + "github.com/ipfs/go-cid" + ipld "github.com/ipfs/go-ipld-format" + mh "github.com/multiformats/go-multihash" +) + +var randomSha256MH = mh.Multihash{0x12, 0x20, 0x88, 0x82, 0x73, 0x37, 0x7c, 0xc1, 0xc9, 0x96, 0xad, 0xee, 0xd, 0x26, 0x84, 0x2, 0xc9, 0xc9, 0x5c, 0xf9, 0x5c, 0x4d, 0x9b, 0xc3, 0x3f, 0xfb, 0x4a, 0xd8, 0xaf, 0x28, 0x6b, 0xca, 0x1a, 0xf2} + +func doAbyfyIpldNotFoundTest(t *testing.T, original error) { + originalMsg := original.Error() + + rebuilt := abyfyIpldNotFoundFallbackToMSG(originalMsg) + + rebuiltMsg := rebuilt.Error() + + if originalMsg != rebuiltMsg { + t.Errorf("expected message to be %q; got %q", originalMsg, rebuiltMsg) + } + + originalNotFound := ipld.IsNotFound(original) + rebuiltNotFound := ipld.IsNotFound(original) + if originalNotFound != rebuiltNotFound { + t.Errorf("expected Ipld.IsNotFound to be %t; got %t", originalNotFound, rebuiltNotFound) + } +} + +func TestAbyfyIpldNotFound(t *testing.T) { + if err := abyfyIpldNotFoundFallbackToMSG(""); err != nil { + t.Errorf("expected empty string to give no error; got %T %q", err, err.Error()) + } + + for _, wrap := range [...]string{ + "", + "merkledag: %w", + "testing: %w the test", + "%w is wrong", + } { + for _, err := range [...]error{ + errors.New("file not found"), + errors.New(" not found"), + errors.New("Bad_CID not found"), + errors.New("network connection timeout"), + ipld.ErrNotFound{Cid: cid.Undef}, + ipld.ErrNotFound{Cid: cid.NewCidV0(randomSha256MH)}, + ipld.ErrNotFound{Cid: cid.NewCidV1(cid.Raw, randomSha256MH)}, + } { + if wrap != "" { + err = fmt.Errorf(wrap, err) + } + + doAbyfyIpldNotFoundTest(t, err) + } + } +} diff --git a/client/httpapi/block.go b/client/httpapi/block.go index 640f186f5..e78ba2281 100644 --- a/client/httpapi/block.go +++ b/client/httpapi/block.go @@ -3,7 +3,6 @@ package httpapi import ( "bytes" "context" - "errors" "fmt" "io" @@ -67,7 +66,7 @@ func (api *BlockAPI) Get(ctx context.Context, p path.Path) (io.Reader, error) { return nil, err } if resp.Error != nil { - return nil, resp.Error + return nil, abyfyIpldNotFoundFallbackToError(resp.Error) } //TODO: make get return ReadCloser to avoid copying @@ -99,18 +98,14 @@ func (api *BlockAPI) Rm(ctx context.Context, p path.Path, opts ...caopts.BlockRm return err } - if removedBlock.Error != "" { - return errors.New(removedBlock.Error) - } - - return nil + return abyfyIpldNotFoundFallbackToMSG(removedBlock.Error) } func (api *BlockAPI) Stat(ctx context.Context, p path.Path) (iface.BlockStat, error) { var out blockStat err := api.core().Request("block/stat", p.String()).Exec(ctx, &out) if err != nil { - return nil, err + return nil, abyfyIpldNotFoundFallbackToError(err) } out.cid, err = cid.Parse(out.Key) if err != nil { From 5a8e2b77c0e4361a0dd6e57a7f4129adba2f4d8a Mon Sep 17 00:00:00 2001 From: Jorropo Date: Wed, 30 Mar 2022 04:32:12 +0200 Subject: [PATCH 0336/1212] chore: rename abyfyIpldErrNotFound to parseIPLDErrNotFound This commit was moved from ipfs/go-ipfs-http-client@7aa002992970058e37bb82f9837a442227562d33 --- client/httpapi/block.go | 6 +++--- client/httpapi/{abyfy_errors.go => errors.go} | 10 +++++----- .../httpapi/{abyfy_errors_test.go => errors_test.go} | 10 +++++----- 3 files changed, 13 insertions(+), 13 deletions(-) rename client/httpapi/{abyfy_errors.go => errors.go} (88%) rename client/httpapi/{abyfy_errors_test.go => errors_test.go} (84%) diff --git a/client/httpapi/block.go b/client/httpapi/block.go index e78ba2281..0ee838e83 100644 --- a/client/httpapi/block.go +++ b/client/httpapi/block.go @@ -66,7 +66,7 @@ func (api *BlockAPI) Get(ctx context.Context, p path.Path) (io.Reader, error) { return nil, err } if resp.Error != nil { - return nil, abyfyIpldNotFoundFallbackToError(resp.Error) + return nil, parseIPLDNotFoundWithFallbackToError(resp.Error) } //TODO: make get return ReadCloser to avoid copying @@ -98,14 +98,14 @@ func (api *BlockAPI) Rm(ctx context.Context, p path.Path, opts ...caopts.BlockRm return err } - return abyfyIpldNotFoundFallbackToMSG(removedBlock.Error) + return parseIPLDNotFoundWithFallbackToMSG(removedBlock.Error) } func (api *BlockAPI) Stat(ctx context.Context, p path.Path) (iface.BlockStat, error) { var out blockStat err := api.core().Request("block/stat", p.String()).Exec(ctx, &out) if err != nil { - return nil, abyfyIpldNotFoundFallbackToError(err) + return nil, parseIPLDNotFoundWithFallbackToError(err) } out.cid, err = cid.Parse(out.Key) if err != nil { diff --git a/client/httpapi/abyfy_errors.go b/client/httpapi/errors.go similarity index 88% rename from client/httpapi/abyfy_errors.go rename to client/httpapi/errors.go index e4f4afb7c..a527e5452 100644 --- a/client/httpapi/abyfy_errors.go +++ b/client/httpapi/errors.go @@ -27,8 +27,8 @@ func (e prePostWrappedNotFoundError) Unwrap() error { return e.wrapped } -func abyfyIpldNotFoundFallbackToMSG(msg string) error { - err, handled := abyfyIpldNotFound(msg) +func parseIPLDNotFoundWithFallbackToMSG(msg string) error { + err, handled := parseIPLDNotFound(msg) if handled { return err } @@ -36,8 +36,8 @@ func abyfyIpldNotFoundFallbackToMSG(msg string) error { return errors.New(msg) } -func abyfyIpldNotFoundFallbackToError(msg error) error { - err, handled := abyfyIpldNotFound(msg.Error()) +func parseIPLDNotFoundWithFallbackToError(msg error) error { + err, handled := parseIPLDNotFound(msg.Error()) if handled { return err } @@ -47,7 +47,7 @@ func abyfyIpldNotFoundFallbackToError(msg error) error { // This file handle parsing and returning the correct ABI based errors from error messages //lint:ignore ST1008 this function is not using the error as a mean to return failure but it massages it to return the correct type -func abyfyIpldNotFound(msg string) (error, bool) { +func parseIPLDNotFound(msg string) (error, bool) { if msg == "" { return nil, true // Fast path } diff --git a/client/httpapi/abyfy_errors_test.go b/client/httpapi/errors_test.go similarity index 84% rename from client/httpapi/abyfy_errors_test.go rename to client/httpapi/errors_test.go index fe1cf0707..08def204d 100644 --- a/client/httpapi/abyfy_errors_test.go +++ b/client/httpapi/errors_test.go @@ -12,10 +12,10 @@ import ( var randomSha256MH = mh.Multihash{0x12, 0x20, 0x88, 0x82, 0x73, 0x37, 0x7c, 0xc1, 0xc9, 0x96, 0xad, 0xee, 0xd, 0x26, 0x84, 0x2, 0xc9, 0xc9, 0x5c, 0xf9, 0x5c, 0x4d, 0x9b, 0xc3, 0x3f, 0xfb, 0x4a, 0xd8, 0xaf, 0x28, 0x6b, 0xca, 0x1a, 0xf2} -func doAbyfyIpldNotFoundTest(t *testing.T, original error) { +func doParseIpldNotFoundTest(t *testing.T, original error) { originalMsg := original.Error() - rebuilt := abyfyIpldNotFoundFallbackToMSG(originalMsg) + rebuilt := parseIPLDNotFoundWithFallbackToMSG(originalMsg) rebuiltMsg := rebuilt.Error() @@ -30,8 +30,8 @@ func doAbyfyIpldNotFoundTest(t *testing.T, original error) { } } -func TestAbyfyIpldNotFound(t *testing.T) { - if err := abyfyIpldNotFoundFallbackToMSG(""); err != nil { +func TestParseIPLDNotFound(t *testing.T) { + if err := parseIPLDNotFoundWithFallbackToMSG(""); err != nil { t.Errorf("expected empty string to give no error; got %T %q", err, err.Error()) } @@ -54,7 +54,7 @@ func TestAbyfyIpldNotFound(t *testing.T) { err = fmt.Errorf(wrap, err) } - doAbyfyIpldNotFoundTest(t, err) + doParseIpldNotFoundTest(t, err) } } } From a2a60768ea7e5d5dad1ad1f0dcf8811cca24d3eb Mon Sep 17 00:00:00 2001 From: Jorropo Date: Thu, 31 Mar 2022 23:36:11 +0200 Subject: [PATCH 0337/1212] fix: parseIPLDErrNotFound test This commit was moved from ipfs/go-ipfs-http-client@2e09c4b3ab580f71c652c82926ba7b1580a2b495 --- client/httpapi/errors_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/httpapi/errors_test.go b/client/httpapi/errors_test.go index 08def204d..502c10966 100644 --- a/client/httpapi/errors_test.go +++ b/client/httpapi/errors_test.go @@ -24,9 +24,9 @@ func doParseIpldNotFoundTest(t *testing.T, original error) { } originalNotFound := ipld.IsNotFound(original) - rebuiltNotFound := ipld.IsNotFound(original) + rebuiltNotFound := ipld.IsNotFound(rebuilt) if originalNotFound != rebuiltNotFound { - t.Errorf("expected Ipld.IsNotFound to be %t; got %t", originalNotFound, rebuiltNotFound) + t.Errorf("for %q expected Ipld.IsNotFound to be %t; got %t", originalMsg, originalNotFound, rebuiltNotFound) } } From 9120e3f1f96ec178225cabaac3aba45942f93895 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Thu, 31 Mar 2022 23:55:17 +0200 Subject: [PATCH 0338/1212] fix: use IPLD.ErrNotFound instead of string comparison in tests This commit was moved from ipfs/interface-go-ipfs-core@03f4e9cca18f0882ae13f718d4b3e18ef1f361ca This commit was moved from ipfs/boxo@548e3d4298370c022c6e79dbe5614d8c80ea90b9 --- core/coreiface/tests/block.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/coreiface/tests/block.go b/core/coreiface/tests/block.go index 8d0243e7e..87fa90b65 100644 --- a/core/coreiface/tests/block.go +++ b/core/coreiface/tests/block.go @@ -188,7 +188,7 @@ func (tp *TestSuite) TestBlockRm(t *testing.T) { if err == nil { t.Fatal("expected err to exist") } - if !strings.Contains(err.Error(), "not found") { + if !ipld.IsNotFound(err) { t.Errorf("unexpected error; %s", err.Error()) } From ddd36645b25c97651deb81c092c7669efabd959e Mon Sep 17 00:00:00 2001 From: Jorropo Date: Thu, 31 Mar 2022 23:43:27 +0200 Subject: [PATCH 0339/1212] feat: update the error parsing for go-ipld-format to v0.4.0 This commit was moved from ipfs/go-ipfs-http-client@296534fd1647a1ec9cae08314daf41ec96d55763 --- client/httpapi/errors.go | 54 +++++++++++++++++++++-------------- client/httpapi/errors_test.go | 14 +++++++-- 2 files changed, 44 insertions(+), 24 deletions(-) diff --git a/client/httpapi/errors.go b/client/httpapi/errors.go index a527e5452..f42d92575 100644 --- a/client/httpapi/errors.go +++ b/client/httpapi/errors.go @@ -45,6 +45,18 @@ func parseIPLDNotFoundWithFallbackToError(msg error) error { return msg } +// Use a string to move it into RODATA +// print("".join("\\x01" if chr(i) not in string.ascii_letters + string.digits else "\\x00" for i in range(ord('z')+1))) +const notAsciiLetterOrDigitsLUT = "\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01\x01\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + +func notAsciiLetterOrDigits(r rune) bool { + if r > 'z' { + return true + } + + return notAsciiLetterOrDigitsLUT[r] > 0 +} + // This file handle parsing and returning the correct ABI based errors from error messages //lint:ignore ST1008 this function is not using the error as a mean to return failure but it massages it to return the correct type func parseIPLDNotFound(msg string) (error, bool) { @@ -53,46 +65,46 @@ func parseIPLDNotFound(msg string) (error, bool) { } // The patern we search for is: - // node not found (fallback) - // or - // CID not found (here we parse the CID) - notFoundIndex := strings.LastIndex(msg, " not found") + const ipldErrNotFoundKey = "ipld: could not find " /*CID*/ + // We try to parse the CID, if it's invalid we give up and return a simple text error. + // We also accept "node" in place of the CID because that means it's an Undefined CID. - if notFoundIndex == -1 { - // Unknown, ot found not found + keyIndex := strings.Index(msg, ipldErrNotFoundKey) + + if keyIndex < 0 { // Unknown error return nil, false } - preNotFound := msg[:notFoundIndex] + cidStart := keyIndex + len(ipldErrNotFoundKey) + msgPostKey := msg[cidStart:] var c cid.Cid - var preIndex int - if strings.HasSuffix(preNotFound, "node") { + var postIndex int + if strings.HasPrefix(msgPostKey, "node") { // Fallback case c = cid.Undef - preIndex = notFoundIndex - len("node") + postIndex = len("node") } else { - // Assume that CIDs does not include whitespace to pull out the CID - preIndex = strings.LastIndexByte(preNotFound, ' ') - // + 1 is to normalise not founds to zeros and point to the start of the CID, not the previous space - preIndex++ + // Assume that CIDs only contain a-zA-Z0-9 characters. + // This is true because go-ipld-format use go-cid#Cid.String which use base{3{2,6},58}. + postIndex = strings.IndexFunc(msgPostKey, notAsciiLetterOrDigits) + if postIndex < 0 { + postIndex = len(msgPostKey) + } + var err error - c, err = cid.Decode(preNotFound[preIndex:]) + c, err = cid.Decode(msgPostKey[:postIndex]) if err != nil { // Unknown return nil, false } } - postIndex := notFoundIndex + len(" not found") - err := ipld.ErrNotFound{Cid: c} - - pre := msg[:preIndex] - post := msg[postIndex:] + pre := msg[:keyIndex] + post := msgPostKey[postIndex:] if len(pre) > 0 || len(post) > 0 { - // We have some text to wrap arround the ErrNotFound one return prePostWrappedNotFoundError{ pre: pre, post: post, diff --git a/client/httpapi/errors_test.go b/client/httpapi/errors_test.go index 502c10966..1b7de8798 100644 --- a/client/httpapi/errors_test.go +++ b/client/httpapi/errors_test.go @@ -3,6 +3,7 @@ package httpapi import ( "errors" "fmt" + "strings" "testing" "github.com/ipfs/go-cid" @@ -42,9 +43,8 @@ func TestParseIPLDNotFound(t *testing.T) { "%w is wrong", } { for _, err := range [...]error{ - errors.New("file not found"), - errors.New(" not found"), - errors.New("Bad_CID not found"), + errors.New("ipld: could not find "), + errors.New("ipld: could not find Bad_CID"), errors.New("network connection timeout"), ipld.ErrNotFound{Cid: cid.Undef}, ipld.ErrNotFound{Cid: cid.NewCidV0(randomSha256MH)}, @@ -58,3 +58,11 @@ func TestParseIPLDNotFound(t *testing.T) { } } } + +func TestNotAsciiLetterOrDigits(t *testing.T) { + for i := rune(0); i <= 256; i++ { + if notAsciiLetterOrDigits(i) != !strings.ContainsAny(string(i), "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789") { + t.Errorf("%q is incorrectly identified", i) + } + } +} From 775bcb7f09de0d13a64b013ccaefa253e44c3403 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Fri, 1 Apr 2022 00:23:55 +0200 Subject: [PATCH 0340/1212] feat: add blockstore: block not found matching too This commit was moved from ipfs/go-ipfs-http-client@a3354f062c97bcb6412e74ecfb24e84208edc479 --- client/httpapi/block.go | 6 ++-- client/httpapi/errors.go | 56 +++++++++++++++++++++++++++++++---- client/httpapi/errors_test.go | 25 ++++++++++++++-- 3 files changed, 76 insertions(+), 11 deletions(-) diff --git a/client/httpapi/block.go b/client/httpapi/block.go index 0ee838e83..c074f7940 100644 --- a/client/httpapi/block.go +++ b/client/httpapi/block.go @@ -66,7 +66,7 @@ func (api *BlockAPI) Get(ctx context.Context, p path.Path) (io.Reader, error) { return nil, err } if resp.Error != nil { - return nil, parseIPLDNotFoundWithFallbackToError(resp.Error) + return nil, parseErrNotFoundWithFallbackToError(resp.Error) } //TODO: make get return ReadCloser to avoid copying @@ -98,14 +98,14 @@ func (api *BlockAPI) Rm(ctx context.Context, p path.Path, opts ...caopts.BlockRm return err } - return parseIPLDNotFoundWithFallbackToMSG(removedBlock.Error) + return parseErrNotFoundWithFallbackToMSG(removedBlock.Error) } func (api *BlockAPI) Stat(ctx context.Context, p path.Path) (iface.BlockStat, error) { var out blockStat err := api.core().Request("block/stat", p.String()).Exec(ctx, &out) if err != nil { - return nil, parseIPLDNotFoundWithFallbackToError(err) + return nil, parseErrNotFoundWithFallbackToError(err) } out.cid, err = cid.Parse(out.Key) if err != nil { diff --git a/client/httpapi/errors.go b/client/httpapi/errors.go index f42d92575..b2a6f86de 100644 --- a/client/httpapi/errors.go +++ b/client/httpapi/errors.go @@ -8,6 +8,8 @@ import ( ipld "github.com/ipfs/go-ipld-format" ) +// This file handle parsing and returning the correct ABI based errors from error messages + type prePostWrappedNotFoundError struct { pre string post string @@ -27,8 +29,8 @@ func (e prePostWrappedNotFoundError) Unwrap() error { return e.wrapped } -func parseIPLDNotFoundWithFallbackToMSG(msg string) error { - err, handled := parseIPLDNotFound(msg) +func parseErrNotFoundWithFallbackToMSG(msg string) error { + err, handled := parseErrNotFound(msg) if handled { return err } @@ -36,8 +38,8 @@ func parseIPLDNotFoundWithFallbackToMSG(msg string) error { return errors.New(msg) } -func parseIPLDNotFoundWithFallbackToError(msg error) error { - err, handled := parseIPLDNotFound(msg.Error()) +func parseErrNotFoundWithFallbackToError(msg error) error { + err, handled := parseErrNotFound(msg.Error()) if handled { return err } @@ -57,13 +59,25 @@ func notAsciiLetterOrDigits(r rune) bool { return notAsciiLetterOrDigitsLUT[r] > 0 } -// This file handle parsing and returning the correct ABI based errors from error messages //lint:ignore ST1008 this function is not using the error as a mean to return failure but it massages it to return the correct type -func parseIPLDNotFound(msg string) (error, bool) { +func parseErrNotFound(msg string) (error, bool) { if msg == "" { return nil, true // Fast path } + if err, handled := parseIPLDErrNotFound(msg); handled { + return err, true + } + + if err, handled := parseBlockstoreNotFound(msg); handled { + return err, true + } + + return nil, false +} + +//lint:ignore ST1008 using error as values +func parseIPLDErrNotFound(msg string) (error, bool) { // The patern we search for is: const ipldErrNotFoundKey = "ipld: could not find " /*CID*/ // We try to parse the CID, if it's invalid we give up and return a simple text error. @@ -114,3 +128,33 @@ func parseIPLDNotFound(msg string) (error, bool) { return err, true } + +// This is a simple error type that just return msg as Error(). +// But that also match ipld.ErrNotFound when called with Is(err). +// That is needed to keep compatiblity with code that use string.Contains(err.Error(), "blockstore: block not found") +// and code using ipld.ErrNotFound +type blockstoreNotFoundMatchingIPLDErrNotFound struct { + msg string +} + +func (e blockstoreNotFoundMatchingIPLDErrNotFound) String() string { + return e.Error() +} + +func (e blockstoreNotFoundMatchingIPLDErrNotFound) Error() string { + return e.msg +} + +func (e blockstoreNotFoundMatchingIPLDErrNotFound) Is(err error) bool { + _, ok := err.(ipld.ErrNotFound) + return ok +} + +//lint:ignore ST1008 using error as values +func parseBlockstoreNotFound(msg string) (error, bool) { + if !strings.Contains(msg, "blockstore: block not found") { + return nil, false + } + + return blockstoreNotFoundMatchingIPLDErrNotFound{msg: msg}, true +} diff --git a/client/httpapi/errors_test.go b/client/httpapi/errors_test.go index 1b7de8798..09437bfbf 100644 --- a/client/httpapi/errors_test.go +++ b/client/httpapi/errors_test.go @@ -16,7 +16,7 @@ var randomSha256MH = mh.Multihash{0x12, 0x20, 0x88, 0x82, 0x73, 0x37, 0x7c, 0xc1 func doParseIpldNotFoundTest(t *testing.T, original error) { originalMsg := original.Error() - rebuilt := parseIPLDNotFoundWithFallbackToMSG(originalMsg) + rebuilt := parseErrNotFoundWithFallbackToMSG(originalMsg) rebuiltMsg := rebuilt.Error() @@ -32,7 +32,7 @@ func doParseIpldNotFoundTest(t *testing.T, original error) { } func TestParseIPLDNotFound(t *testing.T) { - if err := parseIPLDNotFoundWithFallbackToMSG(""); err != nil { + if err := parseErrNotFoundWithFallbackToMSG(""); err != nil { t.Errorf("expected empty string to give no error; got %T %q", err, err.Error()) } @@ -59,6 +59,27 @@ func TestParseIPLDNotFound(t *testing.T) { } } +func TestBlockstoreNotFoundMatchingIPLDErrNotFound(t *testing.T) { + if !ipld.IsNotFound(blockstoreNotFoundMatchingIPLDErrNotFound{}) { + t.Fatalf("expected blockstoreNotFoundMatchingIPLDErrNotFound to match ipld.IsNotFound; got false") + } + + for _, wrap := range [...]string{ + "", + "merkledag: %w", + "testing: %w the test", + "%w is wrong", + } { + var err error = blockstoreNotFoundMatchingIPLDErrNotFound{"blockstore: block not found"} + + if wrap != "" { + err = fmt.Errorf(wrap, err) + } + + doParseIpldNotFoundTest(t, err) + } +} + func TestNotAsciiLetterOrDigits(t *testing.T) { for i := rune(0); i <= 256; i++ { if notAsciiLetterOrDigits(i) != !strings.ContainsAny(string(i), "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789") { From 54f6e90870c61a686f57b0bd0f1ad4923615897b Mon Sep 17 00:00:00 2001 From: Jorropo Date: Sat, 2 Apr 2022 03:25:39 +0200 Subject: [PATCH 0341/1212] fix: change CID breaking logic when parsing ipld.ErrNotFound This commit was moved from ipfs/go-ipfs-http-client@a3b49352bfd1b885567018092a06f303de18b7aa --- client/httpapi/errors.go | 24 +++++++++--------------- client/httpapi/errors_test.go | 18 +++++++----------- 2 files changed, 16 insertions(+), 26 deletions(-) diff --git a/client/httpapi/errors.go b/client/httpapi/errors.go index b2a6f86de..f1a57a049 100644 --- a/client/httpapi/errors.go +++ b/client/httpapi/errors.go @@ -47,18 +47,6 @@ func parseErrNotFoundWithFallbackToError(msg error) error { return msg } -// Use a string to move it into RODATA -// print("".join("\\x01" if chr(i) not in string.ascii_letters + string.digits else "\\x00" for i in range(ord('z')+1))) -const notAsciiLetterOrDigitsLUT = "\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01\x01\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" - -func notAsciiLetterOrDigits(r rune) bool { - if r > 'z' { - return true - } - - return notAsciiLetterOrDigitsLUT[r] > 0 -} - //lint:ignore ST1008 this function is not using the error as a mean to return failure but it massages it to return the correct type func parseErrNotFound(msg string) (error, bool) { if msg == "" { @@ -76,6 +64,12 @@ func parseErrNotFound(msg string) (error, bool) { return nil, false } +// Assume CIDs break on: +// - Whitespaces: " \t\n\r\v\f" +// - Semicolon: ";" this is to parse ipld.ErrNotFound wrapped in multierr +// - Double Quotes: "\"" this is for parsing %q and %#v formating +const cidBreakSet = " \t\n\r\v\f;\"" + //lint:ignore ST1008 using error as values func parseIPLDErrNotFound(msg string) (error, bool) { // The patern we search for is: @@ -99,9 +93,9 @@ func parseIPLDErrNotFound(msg string) (error, bool) { c = cid.Undef postIndex = len("node") } else { - // Assume that CIDs only contain a-zA-Z0-9 characters. - // This is true because go-ipld-format use go-cid#Cid.String which use base{3{2,6},58}. - postIndex = strings.IndexFunc(msgPostKey, notAsciiLetterOrDigits) + postIndex = strings.IndexFunc(msgPostKey, func(r rune) bool { + return strings.ContainsAny(string(r), cidBreakSet) + }) if postIndex < 0 { postIndex = len(msgPostKey) } diff --git a/client/httpapi/errors_test.go b/client/httpapi/errors_test.go index 09437bfbf..86f91cdf5 100644 --- a/client/httpapi/errors_test.go +++ b/client/httpapi/errors_test.go @@ -3,7 +3,6 @@ package httpapi import ( "errors" "fmt" - "strings" "testing" "github.com/ipfs/go-cid" @@ -36,12 +35,17 @@ func TestParseIPLDNotFound(t *testing.T) { t.Errorf("expected empty string to give no error; got %T %q", err, err.Error()) } - for _, wrap := range [...]string{ + cidBreaks := make([]string, len(cidBreakSet)) + for i, v := range cidBreakSet { + cidBreaks[i] = "%w" + string(v) + } + + for _, wrap := range append(cidBreaks, "", "merkledag: %w", "testing: %w the test", "%w is wrong", - } { + ) { for _, err := range [...]error{ errors.New("ipld: could not find "), errors.New("ipld: could not find Bad_CID"), @@ -79,11 +83,3 @@ func TestBlockstoreNotFoundMatchingIPLDErrNotFound(t *testing.T) { doParseIpldNotFoundTest(t, err) } } - -func TestNotAsciiLetterOrDigits(t *testing.T) { - for i := rune(0); i <= 256; i++ { - if notAsciiLetterOrDigits(i) != !strings.ContainsAny(string(i), "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789") { - t.Errorf("%q is incorrectly identified", i) - } - } -} From f2f2109bc1e8f5b9c636597eb7478e0a4ddca427 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Sat, 2 Apr 2022 04:24:12 +0200 Subject: [PATCH 0342/1212] test: add a false case test to blockstore parsing This commit was moved from ipfs/go-ipfs-http-client@75f597aa16c512ec02f549836e998f1fc29a3846 --- client/httpapi/errors_test.go | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/client/httpapi/errors_test.go b/client/httpapi/errors_test.go index 86f91cdf5..7709fc9c5 100644 --- a/client/httpapi/errors_test.go +++ b/client/httpapi/errors_test.go @@ -74,12 +74,15 @@ func TestBlockstoreNotFoundMatchingIPLDErrNotFound(t *testing.T) { "testing: %w the test", "%w is wrong", } { - var err error = blockstoreNotFoundMatchingIPLDErrNotFound{"blockstore: block not found"} + for _, err := range [...]error{ + errors.New("network connection timeout"), + blockstoreNotFoundMatchingIPLDErrNotFound{"blockstore: block not found"}, + } { + if wrap != "" { + err = fmt.Errorf(wrap, err) + } - if wrap != "" { - err = fmt.Errorf(wrap, err) + doParseIpldNotFoundTest(t, err) } - - doParseIpldNotFoundTest(t, err) } } From 60a548b621ff229a648a268c4d06f6e206ad6099 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Tue, 5 Apr 2022 20:11:06 +0200 Subject: [PATCH 0343/1212] correctness: only match CIDs matching go-cid.Cid.String output This commit was moved from ipfs/go-ipfs-http-client@34cc489461985cf4139819e589fdd09bdc034c24 --- client/httpapi/errors.go | 19 +++++++++++++++++-- client/httpapi/errors_test.go | 7 +++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/client/httpapi/errors.go b/client/httpapi/errors.go index f1a57a049..1ccf6182c 100644 --- a/client/httpapi/errors.go +++ b/client/httpapi/errors.go @@ -3,9 +3,11 @@ package httpapi import ( "errors" "strings" + "unicode/utf8" "github.com/ipfs/go-cid" ipld "github.com/ipfs/go-ipld-format" + mbase "github.com/multiformats/go-multibase" ) // This file handle parsing and returning the correct ABI based errors from error messages @@ -97,15 +99,28 @@ func parseIPLDErrNotFound(msg string) (error, bool) { return strings.ContainsAny(string(r), cidBreakSet) }) if postIndex < 0 { + // no breakage meaning the string look like this something + "ipld: could not find bafy" postIndex = len(msgPostKey) } + cidStr := msgPostKey[:postIndex] + var err error - c, err = cid.Decode(msgPostKey[:postIndex]) + c, err = cid.Decode(cidStr) if err != nil { - // Unknown + // failed to decode CID give up return nil, false } + + // check that the CID is either a CIDv0 or a base32 multibase + // because that what ipld.ErrNotFound.Error() -> cid.Cid.String() do currently + if c.Version() != 0 { + baseRune, _ := utf8.DecodeRuneInString(cidStr) + if baseRune == utf8.RuneError || baseRune != mbase.Base32 { + // not a multibase we expect, give up + return nil, false + } + } } err := ipld.ErrNotFound{Cid: c} diff --git a/client/httpapi/errors_test.go b/client/httpapi/errors_test.go index 7709fc9c5..c8b98d08e 100644 --- a/client/httpapi/errors_test.go +++ b/client/httpapi/errors_test.go @@ -7,6 +7,7 @@ import ( "github.com/ipfs/go-cid" ipld "github.com/ipfs/go-ipld-format" + mbase "github.com/multiformats/go-multibase" mh "github.com/multiformats/go-multihash" ) @@ -40,6 +41,11 @@ func TestParseIPLDNotFound(t *testing.T) { cidBreaks[i] = "%w" + string(v) } + base58BTCEncoder, err := mbase.NewEncoder(mbase.Base58BTC) + if err != nil { + t.Fatalf("expected to find Base58BTC encoder; got error %q", err.Error()) + } + for _, wrap := range append(cidBreaks, "", "merkledag: %w", @@ -49,6 +55,7 @@ func TestParseIPLDNotFound(t *testing.T) { for _, err := range [...]error{ errors.New("ipld: could not find "), errors.New("ipld: could not find Bad_CID"), + errors.New("ipld: could not find " + cid.NewCidV1(cid.Raw, randomSha256MH).Encode(base58BTCEncoder)), // Test that we only accept CIDv0 and base32 CIDs errors.New("network connection timeout"), ipld.ErrNotFound{Cid: cid.Undef}, ipld.ErrNotFound{Cid: cid.NewCidV0(randomSha256MH)}, From caa42b563414150604234fbe9b7588b240187aaa Mon Sep 17 00:00:00 2001 From: Lucas Molas Date: Thu, 21 Apr 2022 12:41:58 -0300 Subject: [PATCH 0344/1212] refactor(block): CIDv1 and BlockPutSettings CidPrefix (#80) * feat(block options): add store codec * refactor: BlockPutSettings.CidPrefix Removes duplicated fields and replaces them with cid.Prefix Codec, MhType and MhLength were already in prefix, and we already return prefix. A lot of duplicated values and code responsible for syncing them did not really need to exist. * test: CIDv1 raw and dag-pb cases * chore: release 0.7.0 Co-authored-by: Marcin Rataj This commit was moved from ipfs/interface-go-ipfs-core@a3374d99028d96a1ef262b81acb385690eb36f97 This commit was moved from ipfs/boxo@aca3a1839f42a590b5fa7ce30e743232c9336023 --- core/coreiface/options/block.go | 134 ++++++++++++++++++++------------ core/coreiface/tests/block.go | 103 ++++++++++++++++++++++-- 2 files changed, 181 insertions(+), 56 deletions(-) diff --git a/core/coreiface/options/block.go b/core/coreiface/options/block.go index 043dfdea4..130648682 100644 --- a/core/coreiface/options/block.go +++ b/core/coreiface/options/block.go @@ -2,15 +2,15 @@ package options import ( "fmt" + cid "github.com/ipfs/go-cid" + mc "github.com/multiformats/go-multicodec" mh "github.com/multiformats/go-multihash" ) type BlockPutSettings struct { - Codec string - MhType uint64 - MhLength int - Pin bool + CidPrefix cid.Prefix + Pin bool } type BlockRmSettings struct { @@ -20,53 +20,29 @@ type BlockRmSettings struct { type BlockPutOption func(*BlockPutSettings) error type BlockRmOption func(*BlockRmSettings) error -func BlockPutOptions(opts ...BlockPutOption) (*BlockPutSettings, cid.Prefix, error) { +func BlockPutOptions(opts ...BlockPutOption) (*BlockPutSettings, error) { + var cidPrefix cid.Prefix + + // Baseline is CIDv1 raw sha2-255-32 (can be tweaked later via opts) + cidPrefix.Version = 1 + cidPrefix.Codec = uint64(mc.Raw) + cidPrefix.MhType = mh.SHA2_256 + cidPrefix.MhLength = -1 // -1 means len is to be calculated during mh.Sum() + options := &BlockPutSettings{ - Codec: "", - MhType: mh.SHA2_256, - MhLength: -1, - Pin: false, + CidPrefix: cidPrefix, + Pin: false, } + // Apply any overrides for _, opt := range opts { err := opt(options) if err != nil { - return nil, cid.Prefix{}, err + return nil, err } } - var pref cid.Prefix - pref.Version = 1 - - if options.Codec == "" { - if options.MhType != mh.SHA2_256 || (options.MhLength != -1 && options.MhLength != 32) { - options.Codec = "protobuf" - } else { - options.Codec = "v0" - } - } - - if options.Codec == "v0" && options.MhType == mh.SHA2_256 { - pref.Version = 0 - } - - formatval, ok := cid.Codecs[options.Codec] - if !ok { - return nil, cid.Prefix{}, fmt.Errorf("unrecognized format: %s", options.Codec) - } - - if options.Codec == "v0" { - if options.MhType != mh.SHA2_256 || (options.MhLength != -1 && options.MhLength != 32) { - return nil, cid.Prefix{}, fmt.Errorf("only sha2-255-32 is allowed with CIDv0") - } - } - - pref.Codec = formatval - - pref.MhType = options.MhType - pref.MhLength = options.MhLength - - return options, pref, nil + return options, nil } func BlockRmOptions(opts ...BlockRmOption) (*BlockRmSettings, error) { @@ -87,22 +63,84 @@ type blockOpts struct{} var Block blockOpts -// Format is an option for Block.Put which specifies the multicodec to use to -// serialize the object. Default is "v0" -func (blockOpts) Format(codec string) BlockPutOption { +// CidCodec is the modern option for Block.Put which specifies the multicodec to use +// in the CID returned by the Block.Put operation. +// It uses correct codes from go-multicodec and replaces the old Format now with CIDv1 as the default. +func (blockOpts) CidCodec(codecName string) BlockPutOption { return func(settings *BlockPutSettings) error { - settings.Codec = codec + if codecName == "" { + return nil + } + code, err := codeFromName(codecName) + if err != nil { + return err + } + settings.CidPrefix.Codec = uint64(code) return nil } } +// Map string to code from go-multicodec +func codeFromName(codecName string) (mc.Code, error) { + var cidCodec mc.Code + err := cidCodec.Set(codecName) + return cidCodec, err +} + +// Format is a legacy option for Block.Put which specifies the multicodec to +// use to serialize the object. +// Provided for backward-compatibility only. Use CidCodec instead. +func (blockOpts) Format(format string) BlockPutOption { + return func(settings *BlockPutSettings) error { + if format == "" { + return nil + } + // Opt-in CIDv0 support for backward-compatibility + if format == "v0" { + settings.CidPrefix.Version = 0 + } + + // Fixup a legacy (invalid) names for dag-pb (0x70) + if format == "v0" || format == "protobuf" { + format = "dag-pb" + } + + // Fixup invalid name for dag-cbor (0x71) + if format == "cbor" { + format = "dag-cbor" + } + + // Set code based on name passed as "format" + code, err := codeFromName(format) + if err != nil { + return err + } + settings.CidPrefix.Codec = uint64(code) + + // If CIDv0, ensure all parameters are compatible + // (in theory go-cid would validate this anyway, but we want to provide better errors) + pref := settings.CidPrefix + if pref.Version == 0 { + if pref.Codec != uint64(mc.DagPb) { + return fmt.Errorf("only dag-pb is allowed with CIDv0") + } + if pref.MhType != mh.SHA2_256 || (pref.MhLength != -1 && pref.MhLength != 32) { + return fmt.Errorf("only sha2-255-32 is allowed with CIDv0") + } + } + + return nil + } + +} + // Hash is an option for Block.Put which specifies the multihash settings to use // when hashing the object. Default is mh.SHA2_256 (0x12). // If mhLen is set to -1, default length for the hash will be used func (blockOpts) Hash(mhType uint64, mhLen int) BlockPutOption { return func(settings *BlockPutSettings) error { - settings.MhType = mhType - settings.MhLength = mhLen + settings.CidPrefix.MhType = mhType + settings.CidPrefix.MhLength = mhLen return nil } } diff --git a/core/coreiface/tests/block.go b/core/coreiface/tests/block.go index 87fa90b65..916e52dd3 100644 --- a/core/coreiface/tests/block.go +++ b/core/coreiface/tests/block.go @@ -17,15 +17,19 @@ import ( ) var ( - pbCid = "QmZULkCELmmk5XNfCgTnCyFgAVxBRBXyDHGGMVoLFLiXEN" - cborCid = "bafyreicnga62zhxnmnlt6ymq5hcbsg7gdhqdu6z4ehu3wpjhvqnflfy6nm" - cborKCid = "bafyr2qgsohbwdlk7ajmmbb4lhoytmest4wdbe5xnexfvtxeatuyqqmwv3fgxp3pmhpc27gwey2cct56gloqefoqwcf3yqiqzsaqb7p4jefhcw" + pbCidV0 = "QmZULkCELmmk5XNfCgTnCyFgAVxBRBXyDHGGMVoLFLiXEN" // dag-pb + pbCid = "bafybeiffndsajwhk3lwjewwdxqntmjm4b5wxaaanokonsggenkbw6slwk4" // dag-pb + rawCid = "bafkreiffndsajwhk3lwjewwdxqntmjm4b5wxaaanokonsggenkbw6slwk4" // raw bytes + cborCid = "bafyreicnga62zhxnmnlt6ymq5hcbsg7gdhqdu6z4ehu3wpjhvqnflfy6nm" // dag-cbor + cborKCid = "bafyr2qgsohbwdlk7ajmmbb4lhoytmest4wdbe5xnexfvtxeatuyqqmwv3fgxp3pmhpc27gwey2cct56gloqefoqwcf3yqiqzsaqb7p4jefhcw" // dag-cbor keccak-512 ) +// dag-pb func pbBlock() io.Reader { return bytes.NewReader([]byte{10, 12, 8, 2, 18, 6, 104, 101, 108, 108, 111, 10, 24, 6}) } +// dag-cbor func cborBlock() io.Reader { return bytes.NewReader([]byte{101, 72, 101, 108, 108, 111}) } @@ -38,8 +42,12 @@ func (tp *TestSuite) TestBlock(t *testing.T) { return nil }) - t.Run("TestBlockPut", tp.TestBlockPut) - t.Run("TestBlockPutFormat", tp.TestBlockPutFormat) + t.Run("TestBlockPut (get raw CIDv1)", tp.TestBlockPut) + t.Run("TestBlockPutCidCodec: dag-pb", tp.TestBlockPutCidCodecDagPb) + t.Run("TestBlockPutCidCodec: dag-cbor", tp.TestBlockPutCidCodecDagCbor) + t.Run("TestBlockPutFormat (legacy): cbor → dag-cbor", tp.TestBlockPutFormatDagCbor) + t.Run("TestBlockPutFormat (legacy): protobuf → dag-pb", tp.TestBlockPutFormatDagPb) + t.Run("TestBlockPutFormat (legacy): v0 → CIDv0", tp.TestBlockPutFormatV0) t.Run("TestBlockPutHash", tp.TestBlockPutHash) t.Run("TestBlockGet", tp.TestBlockGet) t.Run("TestBlockRm", tp.TestBlockRm) @@ -47,6 +55,7 @@ func (tp *TestSuite) TestBlock(t *testing.T) { t.Run("TestBlockPin", tp.TestBlockPin) } +// when no opts are passed, produced CID has 'raw' codec func (tp *TestSuite) TestBlockPut(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() @@ -60,12 +69,14 @@ func (tp *TestSuite) TestBlockPut(t *testing.T) { t.Fatal(err) } - if res.Path().Cid().String() != pbCid { + if res.Path().Cid().String() != rawCid { t.Errorf("got wrong cid: %s", res.Path().Cid().String()) } } -func (tp *TestSuite) TestBlockPutFormat(t *testing.T) { +// Format is deprecated, it used invalid codec names. +// Confirm 'cbor' gets fixed to 'dag-cbor' +func (tp *TestSuite) TestBlockPutFormatDagCbor(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() api, err := tp.makeAPI(ctx) @@ -83,6 +94,82 @@ func (tp *TestSuite) TestBlockPutFormat(t *testing.T) { } } +// Format is deprecated, it used invalid codec names. +// Confirm 'protobuf' got fixed to 'dag-pb' +func (tp *TestSuite) TestBlockPutFormatDagPb(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + api, err := tp.makeAPI(ctx) + if err != nil { + t.Fatal(err) + } + + res, err := api.Block().Put(ctx, pbBlock(), opt.Block.Format("protobuf")) + if err != nil { + t.Fatal(err) + } + + if res.Path().Cid().String() != pbCid { + t.Errorf("got wrong cid: %s", res.Path().Cid().String()) + } +} + +// Format is deprecated, it used invalid codec names. +// Confirm fake codec 'v0' got fixed to CIDv0 (with implicit dag-pb codec) +func (tp *TestSuite) TestBlockPutFormatV0(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + api, err := tp.makeAPI(ctx) + if err != nil { + t.Fatal(err) + } + + res, err := api.Block().Put(ctx, pbBlock(), opt.Block.Format("v0")) + if err != nil { + t.Fatal(err) + } + + if res.Path().Cid().String() != pbCidV0 { + t.Errorf("got wrong cid: %s", res.Path().Cid().String()) + } +} + +func (tp *TestSuite) TestBlockPutCidCodecDagCbor(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + api, err := tp.makeAPI(ctx) + if err != nil { + t.Fatal(err) + } + + res, err := api.Block().Put(ctx, cborBlock(), opt.Block.CidCodec("dag-cbor")) + if err != nil { + t.Fatal(err) + } + + if res.Path().Cid().String() != cborCid { + t.Errorf("got wrong cid: %s", res.Path().Cid().String()) + } +} + +func (tp *TestSuite) TestBlockPutCidCodecDagPb(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + api, err := tp.makeAPI(ctx) + if err != nil { + t.Fatal(err) + } + + res, err := api.Block().Put(ctx, pbBlock(), opt.Block.CidCodec("dag-pb")) + if err != nil { + t.Fatal(err) + } + + if res.Path().Cid().String() != pbCid { + t.Errorf("got wrong cid: %s", res.Path().Cid().String()) + } +} + func (tp *TestSuite) TestBlockPutHash(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() @@ -95,7 +182,7 @@ func (tp *TestSuite) TestBlockPutHash(t *testing.T) { ctx, cborBlock(), opt.Block.Hash(mh.KECCAK_512, -1), - opt.Block.Format("cbor"), + opt.Block.CidCodec("dag-cbor"), ) if err != nil { t.Fatal(err) From fd209019f27c7a16f94bfc41ebc7b815daee9903 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Thu, 21 Apr 2022 22:18:19 +0200 Subject: [PATCH 0345/1212] fix: interop with 'block put' from go-ipfs 0.13 (#158) * chore: interop with go-ipfs 0.13 Applies necessary changes to ensure 'block/put' works and is backward-compatible. Context: https://github.com/ipfs/go-ipfs/pull/8568 * chore: 0.3.1 bumping as patch because we bumped to 0.3.0 recently, as part of other (unreleased) go-ipfs 0.13 work This commit was moved from ipfs/go-ipfs-http-client@ecf364c9898d78034e3232574aae70d1bf85357c --- client/httpapi/block.go | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/client/httpapi/block.go b/client/httpapi/block.go index c074f7940..7b4cf0eda 100644 --- a/client/httpapi/block.go +++ b/client/httpapi/block.go @@ -7,9 +7,10 @@ import ( "io" "github.com/ipfs/go-cid" - "github.com/ipfs/interface-go-ipfs-core" + iface "github.com/ipfs/interface-go-ipfs-core" caopts "github.com/ipfs/interface-go-ipfs-core/options" "github.com/ipfs/interface-go-ipfs-core/path" + mc "github.com/multiformats/go-multicodec" mh "github.com/multiformats/go-multihash" ) @@ -31,20 +32,33 @@ func (s *blockStat) Path() path.Resolved { } func (api *BlockAPI) Put(ctx context.Context, r io.Reader, opts ...caopts.BlockPutOption) (iface.BlockStat, error) { - options, _, err := caopts.BlockPutOptions(opts...) + options, err := caopts.BlockPutOptions(opts...) + px := options.CidPrefix if err != nil { return nil, err } - mht, ok := mh.Codes[options.MhType] + mht, ok := mh.Codes[px.MhType] if !ok { - return nil, fmt.Errorf("unknowm mhType %d", options.MhType) + return nil, fmt.Errorf("unknowm mhType %d", px.MhType) + } + + var cidOptKey, cidOptVal string + switch { + case px.Version == 0 && px.Codec == cid.DagProtobuf: + // ensure legacy --format=v0 passes as BlockPutOption still works + cidOptKey = "format" + cidOptVal = "v0" + default: + // pass codec as string + cidOptKey = "cid-codec" + cidOptVal = mc.Code(px.Codec).String() } req := api.core().Request("block/put"). Option("mhtype", mht). - Option("mhlen", options.MhLength). - Option("format", options.Codec). + Option("mhlen", px.MhLength). + Option(cidOptKey, cidOptVal). Option("pin", options.Pin). FileBody(r) From 1cdb9adf898a8a2b9d2cd0d3fe8ba6467a822166 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Thu, 23 Jun 2022 22:39:01 +0200 Subject: [PATCH 0346/1212] fix: interop with go-ipfs 0.13 (#160) This ensures cid-codec introduced in https://github.com/ipfs/go-ipfs/pull/8568 gets correctly passed (+ we maintain backward-compatibility with CIDv0) This commit was moved from ipfs/go-ipfs-http-client@9c9f43fd9ca36c7ebdc664bb6936a6fe9881255b --- client/httpapi/dag.go | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/client/httpapi/dag.go b/client/httpapi/dag.go index 15d9a9c62..879c1e499 100644 --- a/client/httpapi/dag.go +++ b/client/httpapi/dag.go @@ -6,11 +6,12 @@ import ( "fmt" "io/ioutil" - "github.com/ipfs/go-block-format" + blocks "github.com/ipfs/go-block-format" "github.com/ipfs/go-cid" - "github.com/ipfs/go-ipld-format" + format "github.com/ipfs/go-ipld-format" "github.com/ipfs/interface-go-ipfs-core/options" "github.com/ipfs/interface-go-ipfs-core/path" + multicodec "github.com/multiformats/go-multicodec" ) type httpNodeAdder HttpApi @@ -56,13 +57,21 @@ func (api *HttpDagServ) GetMany(ctx context.Context, cids []cid.Cid) <-chan *for func (api *httpNodeAdder) add(ctx context.Context, nd format.Node, pin bool) error { c := nd.Cid() prefix := c.Prefix() - format := cid.CodecToStr[prefix.Codec] + + // preserve 'cid-codec' when sent over HTTP + cidCodec := multicodec.Code(prefix.Codec).String() + + // 'format' got replaced by 'cid-codec' in https://github.com/ipfs/interface-go-ipfs-core/pull/80 + // but we still support it here for backward-compatibility with use of CIDv0 + format := "" if prefix.Version == 0 { + cidCodec = "" format = "v0" } stat, err := api.core().Block().Put(ctx, bytes.NewReader(nd.RawData()), options.Block.Hash(prefix.MhType, prefix.MhLength), + options.Block.CidCodec(cidCodec), options.Block.Format(format), options.Block.Pin(pin)) if err != nil { From f2614d979edfef6bb4ee6c3465aa3636c9f95850 Mon Sep 17 00:00:00 2001 From: web3-bot <81333946+web3-bot@users.noreply.github.com> Date: Thu, 25 Aug 2022 15:07:58 +0200 Subject: [PATCH 0347/1212] sync: update CI config files (#87) This commit was moved from ipfs/interface-go-ipfs-core@de3410bbe2bbdbf50e090a06eda0f741cad5381c This commit was moved from ipfs/boxo@ea6ac8cb6aa02f6cd88cb141f3f077e206277829 --- core/coreiface/block.go | 3 ++- core/coreiface/dht.go | 1 + core/coreiface/key.go | 1 + core/coreiface/name.go | 1 + core/coreiface/object.go | 3 ++- core/coreiface/options/key.go | 2 +- core/coreiface/options/name.go | 1 - core/coreiface/options/pin.go | 40 +++++++++++++++++----------------- core/coreiface/path/path.go | 2 +- core/coreiface/pin.go | 1 + core/coreiface/tests/block.go | 5 ++--- core/coreiface/tests/dag.go | 3 ++- core/coreiface/tests/object.go | 10 ++++----- core/coreiface/tests/pin.go | 2 +- core/coreiface/tests/pubsub.go | 2 +- core/coreiface/tests/unixfs.go | 9 ++++---- core/coreiface/unixfs.go | 3 ++- 17 files changed, 47 insertions(+), 42 deletions(-) diff --git a/core/coreiface/block.go b/core/coreiface/block.go index b105b079d..49ffe75d7 100644 --- a/core/coreiface/block.go +++ b/core/coreiface/block.go @@ -2,9 +2,10 @@ package iface import ( "context" - path "github.com/ipfs/interface-go-ipfs-core/path" "io" + path "github.com/ipfs/interface-go-ipfs-core/path" + "github.com/ipfs/interface-go-ipfs-core/options" ) diff --git a/core/coreiface/dht.go b/core/coreiface/dht.go index 5f49e74a3..81a20ee2b 100644 --- a/core/coreiface/dht.go +++ b/core/coreiface/dht.go @@ -2,6 +2,7 @@ package iface import ( "context" + path "github.com/ipfs/interface-go-ipfs-core/path" "github.com/ipfs/interface-go-ipfs-core/options" diff --git a/core/coreiface/key.go b/core/coreiface/key.go index db729b3b4..967255665 100644 --- a/core/coreiface/key.go +++ b/core/coreiface/key.go @@ -2,6 +2,7 @@ package iface import ( "context" + path "github.com/ipfs/interface-go-ipfs-core/path" "github.com/ipfs/interface-go-ipfs-core/options" diff --git a/core/coreiface/name.go b/core/coreiface/name.go index 3dc9f6878..d2725e028 100644 --- a/core/coreiface/name.go +++ b/core/coreiface/name.go @@ -3,6 +3,7 @@ package iface import ( "context" "errors" + path "github.com/ipfs/interface-go-ipfs-core/path" "github.com/ipfs/interface-go-ipfs-core/options" diff --git a/core/coreiface/object.go b/core/coreiface/object.go index 86536d421..733dc2bee 100644 --- a/core/coreiface/object.go +++ b/core/coreiface/object.go @@ -2,9 +2,10 @@ package iface import ( "context" - path "github.com/ipfs/interface-go-ipfs-core/path" "io" + path "github.com/ipfs/interface-go-ipfs-core/path" + "github.com/ipfs/interface-go-ipfs-core/options" "github.com/ipfs/go-cid" diff --git a/core/coreiface/options/key.go b/core/coreiface/options/key.go index 80beea352..4bc53a65f 100644 --- a/core/coreiface/options/key.go +++ b/core/coreiface/options/key.go @@ -69,7 +69,7 @@ func (keyOpts) Type(algorithm string) KeyGenerateOption { // generated. Default is -1 // // value of -1 means 'use default size for key type': -// * 2048 for RSA +// - 2048 for RSA func (keyOpts) Size(size int) KeyGenerateOption { return func(settings *KeyGenerateSettings) error { settings.Size = size diff --git a/core/coreiface/options/name.go b/core/coreiface/options/name.go index 59aaf2ca3..aa8082863 100644 --- a/core/coreiface/options/name.go +++ b/core/coreiface/options/name.go @@ -113,7 +113,6 @@ func (nameOpts) Cache(cache bool) NameResolveOption { } } -// func (nameOpts) ResolveOption(opt ropts.ResolveOpt) NameResolveOption { return func(settings *NameResolveSettings) error { settings.ResolveOpts = append(settings.ResolveOpts, opt) diff --git a/core/coreiface/options/pin.go b/core/coreiface/options/pin.go index 5014a2d2b..75c2b8a26 100644 --- a/core/coreiface/options/pin.go +++ b/core/coreiface/options/pin.go @@ -164,11 +164,11 @@ func (pinLsOpts) Indirect() PinLsOption { // type. // // Supported values: -// * "direct" - directly pinned objects -// * "recursive" - roots of recursive pins -// * "indirect" - indirectly pinned objects (referenced by recursively pinned -// objects) -// * "all" - all pinned objects (default) +// - "direct" - directly pinned objects +// - "recursive" - roots of recursive pins +// - "indirect" - indirectly pinned objects (referenced by recursively pinned +// objects) +// - "all" - all pinned objects (default) func (pinLsOpts) Type(typeStr string) (PinLsOption, error) { switch typeStr { case "all", "direct", "indirect", "recursive": @@ -182,11 +182,11 @@ func (pinLsOpts) Type(typeStr string) (PinLsOption, error) { // be returned // // Supported values: -// * "direct" - directly pinned objects -// * "recursive" - roots of recursive pins -// * "indirect" - indirectly pinned objects (referenced by recursively pinned -// objects) -// * "all" - all pinned objects (default) +// - "direct" - directly pinned objects +// - "recursive" - roots of recursive pins +// - "indirect" - indirectly pinned objects (referenced by recursively pinned +// objects) +// - "all" - all pinned objects (default) func (pinLsOpts) pinType(t string) PinLsOption { return func(settings *PinLsSettings) error { settings.Type = t @@ -224,11 +224,11 @@ func (pinIsPinnedOpts) Indirect() PinIsPinnedOption { // type. // // Supported values: -// * "direct" - directly pinned objects -// * "recursive" - roots of recursive pins -// * "indirect" - indirectly pinned objects (referenced by recursively pinned -// objects) -// * "all" - all pinned objects (default) +// - "direct" - directly pinned objects +// - "recursive" - roots of recursive pins +// - "indirect" - indirectly pinned objects (referenced by recursively pinned +// objects) +// - "all" - all pinned objects (default) func (pinIsPinnedOpts) Type(typeStr string) (PinIsPinnedOption, error) { switch typeStr { case "all", "direct", "indirect", "recursive": @@ -242,11 +242,11 @@ func (pinIsPinnedOpts) Type(typeStr string) (PinIsPinnedOption, error) { // pin is expected to be, speeding up the research. // // Supported values: -// * "direct" - directly pinned objects -// * "recursive" - roots of recursive pins -// * "indirect" - indirectly pinned objects (referenced by recursively pinned -// objects) -// * "all" - all pinned objects (default) +// - "direct" - directly pinned objects +// - "recursive" - roots of recursive pins +// - "indirect" - indirectly pinned objects (referenced by recursively pinned +// objects) +// - "all" - all pinned objects (default) func (pinIsPinnedOpts) pinType(t string) PinIsPinnedOption { return func(settings *PinIsPinnedSettings) error { settings.WithType = t diff --git a/core/coreiface/path/path.go b/core/coreiface/path/path.go index 01b1673b1..e2562936d 100644 --- a/core/coreiface/path/path.go +++ b/core/coreiface/path/path.go @@ -15,7 +15,7 @@ import ( // * /ipfs - Immutable unixfs path (files) // * /ipld - Immutable ipld path (data) // * /ipns - Mutable names. Usually resolves to one of the immutable paths -//TODO: /local (MFS) +// TODO: /local (MFS) type Path interface { // String returns the path as a string. String() string diff --git a/core/coreiface/pin.go b/core/coreiface/pin.go index 4c1788c68..6205a9b20 100644 --- a/core/coreiface/pin.go +++ b/core/coreiface/pin.go @@ -2,6 +2,7 @@ package iface import ( "context" + path "github.com/ipfs/interface-go-ipfs-core/path" "github.com/ipfs/interface-go-ipfs-core/options" diff --git a/core/coreiface/tests/block.go b/core/coreiface/tests/block.go index 916e52dd3..a81969916 100644 --- a/core/coreiface/tests/block.go +++ b/core/coreiface/tests/block.go @@ -4,7 +4,6 @@ import ( "bytes" "context" "io" - "io/ioutil" "strings" "testing" @@ -211,7 +210,7 @@ func (tp *TestSuite) TestBlockGet(t *testing.T) { t.Fatal(err) } - d, err := ioutil.ReadAll(r) + d, err := io.ReadAll(r) if err != nil { t.Fatal(err) } @@ -249,7 +248,7 @@ func (tp *TestSuite) TestBlockRm(t *testing.T) { t.Fatal(err) } - d, err := ioutil.ReadAll(r) + d, err := io.ReadAll(r) if err != nil { t.Fatal(err) } diff --git a/core/coreiface/tests/dag.go b/core/coreiface/tests/dag.go index 6f9d9659e..5ea0d3eb1 100644 --- a/core/coreiface/tests/dag.go +++ b/core/coreiface/tests/dag.go @@ -2,12 +2,13 @@ package tests import ( "context" - path "github.com/ipfs/interface-go-ipfs-core/path" "math" gopath "path" "strings" "testing" + path "github.com/ipfs/interface-go-ipfs-core/path" + coreiface "github.com/ipfs/interface-go-ipfs-core" ipldcbor "github.com/ipfs/go-ipld-cbor" diff --git a/core/coreiface/tests/object.go b/core/coreiface/tests/object.go index e8ab1a7f4..c3437853c 100644 --- a/core/coreiface/tests/object.go +++ b/core/coreiface/tests/object.go @@ -4,11 +4,11 @@ import ( "bytes" "context" "encoding/hex" - "io/ioutil" + "io" "strings" "testing" - "github.com/ipfs/interface-go-ipfs-core" + iface "github.com/ipfs/interface-go-ipfs-core" opt "github.com/ipfs/interface-go-ipfs-core/options" ) @@ -143,7 +143,7 @@ func (tp *TestSuite) TestObjectData(t *testing.T) { t.Fatal(err) } - data, err := ioutil.ReadAll(r) + data, err := io.ReadAll(r) if err != nil { t.Fatal(err) } @@ -383,7 +383,7 @@ func (tp *TestSuite) TestObjectAddData(t *testing.T) { t.Fatal(err) } - data, err := ioutil.ReadAll(r) + data, err := io.ReadAll(r) if err != nil { t.Fatal(err) } @@ -416,7 +416,7 @@ func (tp *TestSuite) TestObjectSetData(t *testing.T) { t.Fatal(err) } - data, err := ioutil.ReadAll(r) + data, err := io.ReadAll(r) if err != nil { t.Fatal(err) } diff --git a/core/coreiface/tests/pin.go b/core/coreiface/tests/pin.go index d378d1015..ad1a0fdd2 100644 --- a/core/coreiface/tests/pin.go +++ b/core/coreiface/tests/pin.go @@ -6,7 +6,7 @@ import ( "strings" "testing" - "github.com/ipfs/interface-go-ipfs-core" + iface "github.com/ipfs/interface-go-ipfs-core" opt "github.com/ipfs/interface-go-ipfs-core/options" "github.com/ipfs/interface-go-ipfs-core/path" diff --git a/core/coreiface/tests/pubsub.go b/core/coreiface/tests/pubsub.go index f8339f228..18da2103d 100644 --- a/core/coreiface/tests/pubsub.go +++ b/core/coreiface/tests/pubsub.go @@ -5,7 +5,7 @@ import ( "testing" "time" - "github.com/ipfs/interface-go-ipfs-core" + iface "github.com/ipfs/interface-go-ipfs-core" "github.com/ipfs/interface-go-ipfs-core/options" ) diff --git a/core/coreiface/tests/unixfs.go b/core/coreiface/tests/unixfs.go index f47d34d0a..05226dbbf 100644 --- a/core/coreiface/tests/unixfs.go +++ b/core/coreiface/tests/unixfs.go @@ -6,7 +6,6 @@ import ( "encoding/hex" "fmt" "io" - "io/ioutil" "math" "math/rand" "os" @@ -113,7 +112,7 @@ func (tp *TestSuite) TestAdd(t *testing.T) { return path.IpfsPath(c) } - rf, err := ioutil.TempFile(os.TempDir(), "unixfs-add-real") + rf, err := os.CreateTemp(os.TempDir(), "unixfs-add-real") if err != nil { t.Fatal(err) } @@ -134,7 +133,7 @@ func (tp *TestSuite) TestAdd(t *testing.T) { defer os.Remove(rfp) realFile := func() files.Node { - n, err := files.NewReaderPathFile(rfp, ioutil.NopCloser(strings.NewReader(helloStr)), stat) + n, err := files.NewReaderPathFile(rfp, io.NopCloser(strings.NewReader(helloStr)), stat) if err != nil { t.Fatal(err) } @@ -474,12 +473,12 @@ func (tp *TestSuite) TestAdd(t *testing.T) { defer orig.Close() defer got.Close() - do, err := ioutil.ReadAll(orig.(files.File)) + do, err := io.ReadAll(orig.(files.File)) if err != nil { t.Fatal(err) } - dg, err := ioutil.ReadAll(got.(files.File)) + dg, err := io.ReadAll(got.(files.File)) if err != nil { t.Fatal(err) } diff --git a/core/coreiface/unixfs.go b/core/coreiface/unixfs.go index 686c40298..c398b6722 100644 --- a/core/coreiface/unixfs.go +++ b/core/coreiface/unixfs.go @@ -2,11 +2,12 @@ package iface import ( "context" + "github.com/ipfs/interface-go-ipfs-core/options" path "github.com/ipfs/interface-go-ipfs-core/path" "github.com/ipfs/go-cid" - "github.com/ipfs/go-ipfs-files" + files "github.com/ipfs/go-ipfs-files" ) type AddEvent struct { From 0fff1d5d8e4cb2debaff1ee4e85b1266907101af Mon Sep 17 00:00:00 2001 From: web3-bot Date: Fri, 23 Sep 2022 07:43:33 +0000 Subject: [PATCH 0348/1212] stop using the deprecated io/ioutil package This commit was moved from ipfs/go-ipfs-http-client@026ba730a1fe9a4a25a22449bec8d69c2262ccfc --- client/httpapi/api.go | 3 +-- client/httpapi/api_test.go | 3 +-- client/httpapi/apifile.go | 3 +-- client/httpapi/dag.go | 4 ++-- client/httpapi/name.go | 4 ++-- client/httpapi/object.go | 5 ++--- client/httpapi/requestbuilder.go | 5 ++--- client/httpapi/response.go | 9 ++++----- 8 files changed, 15 insertions(+), 21 deletions(-) diff --git a/client/httpapi/api.go b/client/httpapi/api.go index f589e4267..97440a724 100644 --- a/client/httpapi/api.go +++ b/client/httpapi/api.go @@ -3,7 +3,6 @@ package httpapi import ( "errors" "fmt" - "io/ioutil" "net/http" "os" "path/filepath" @@ -74,7 +73,7 @@ func ApiAddr(ipfspath string) (ma.Multiaddr, error) { apiFile := filepath.Join(baseDir, DefaultApiFile) - api, err := ioutil.ReadFile(apiFile) + api, err := os.ReadFile(apiFile) if err != nil { return nil, err } diff --git a/client/httpapi/api_test.go b/client/httpapi/api_test.go index d5f27f0ec..5960ea2c0 100644 --- a/client/httpapi/api_test.go +++ b/client/httpapi/api_test.go @@ -2,7 +2,6 @@ package httpapi import ( "context" - "io/ioutil" "net/http" "net/http/httptest" "os" @@ -92,7 +91,7 @@ func (np *NodeProvider) MakeAPISwarm(ctx context.Context, fullIdentity bool, n i func (NodeProvider) makeAPISwarm(ctx context.Context, fullIdentity bool, n int) ([]iface.CoreAPI, error) { - dir, err := ioutil.TempDir("", "httpapi-tb-") + dir, err := os.MkdirTemp("", "httpapi-tb-") if err != nil { return nil, err } diff --git a/client/httpapi/apifile.go b/client/httpapi/apifile.go index ec2f7588d..c4884b924 100644 --- a/client/httpapi/apifile.go +++ b/client/httpapi/apifile.go @@ -5,7 +5,6 @@ import ( "encoding/json" "fmt" "io" - "io/ioutil" "github.com/ipfs/go-cid" files "github.com/ipfs/go-ipfs-files" @@ -113,7 +112,7 @@ func (f *apiFile) Seek(offset int64, whence int) (int64, error) { } if f.at < offset && offset-f.at < forwardSeekLimit { //forward skip - r, err := io.CopyN(ioutil.Discard, f.r.Output, offset-f.at) + r, err := io.CopyN(io.Discard, f.r.Output, offset-f.at) f.at += r return f.at, err diff --git a/client/httpapi/dag.go b/client/httpapi/dag.go index 879c1e499..f32c67c42 100644 --- a/client/httpapi/dag.go +++ b/client/httpapi/dag.go @@ -4,7 +4,7 @@ import ( "bytes" "context" "fmt" - "io/ioutil" + "io" blocks "github.com/ipfs/go-block-format" "github.com/ipfs/go-cid" @@ -24,7 +24,7 @@ func (api *HttpDagServ) Get(ctx context.Context, c cid.Cid) (format.Node, error) return nil, err } - data, err := ioutil.ReadAll(r) + data, err := io.ReadAll(r) if err != nil { return nil, err } diff --git a/client/httpapi/name.go b/client/httpapi/name.go index 47227a2ab..b6a783603 100644 --- a/client/httpapi/name.go +++ b/client/httpapi/name.go @@ -6,9 +6,9 @@ import ( "fmt" "io" - "github.com/ipfs/interface-go-ipfs-core" + iface "github.com/ipfs/interface-go-ipfs-core" caopts "github.com/ipfs/interface-go-ipfs-core/options" - "github.com/ipfs/interface-go-ipfs-core/options/namesys" + nsopts "github.com/ipfs/interface-go-ipfs-core/options/namesys" "github.com/ipfs/interface-go-ipfs-core/path" ) diff --git a/client/httpapi/object.go b/client/httpapi/object.go index 6ec7f5503..894369223 100644 --- a/client/httpapi/object.go +++ b/client/httpapi/object.go @@ -5,13 +5,12 @@ import ( "context" "fmt" "io" - "io/ioutil" "github.com/ipfs/go-cid" ipld "github.com/ipfs/go-ipld-format" "github.com/ipfs/go-merkledag" ft "github.com/ipfs/go-unixfs" - "github.com/ipfs/interface-go-ipfs-core" + iface "github.com/ipfs/interface-go-ipfs-core" caopts "github.com/ipfs/interface-go-ipfs-core/options" "github.com/ipfs/interface-go-ipfs-core/path" ) @@ -71,7 +70,7 @@ func (api *ObjectAPI) Get(ctx context.Context, p path.Path) (ipld.Node, error) { if err != nil { return nil, err } - b, err := ioutil.ReadAll(r) + b, err := io.ReadAll(r) if err != nil { return nil, err } diff --git a/client/httpapi/requestbuilder.go b/client/httpapi/requestbuilder.go index 7012a8935..039bca036 100644 --- a/client/httpapi/requestbuilder.go +++ b/client/httpapi/requestbuilder.go @@ -5,11 +5,10 @@ import ( "context" "fmt" "io" - "io/ioutil" "strconv" "strings" - "github.com/ipfs/go-ipfs-files" + files "github.com/ipfs/go-ipfs-files" ) type RequestBuilder interface { @@ -59,7 +58,7 @@ func (r *requestBuilder) Body(body io.Reader) RequestBuilder { // FileBody sets the request body to the given reader wrapped into multipartreader. func (r *requestBuilder) FileBody(body io.Reader) RequestBuilder { - pr, _ := files.NewReaderPathFile("/dev/stdin", ioutil.NopCloser(body), nil) + pr, _ := files.NewReaderPathFile("/dev/stdin", io.NopCloser(body), nil) d := files.NewMapDirectory(map[string]files.Node{"": pr}) r.body = files.NewMultiFileReader(d, false) diff --git a/client/httpapi/response.go b/client/httpapi/response.go index 95cbf13ec..8a491ab73 100644 --- a/client/httpapi/response.go +++ b/client/httpapi/response.go @@ -5,7 +5,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "mime" "net/http" "net/url" @@ -45,7 +44,7 @@ func (r *Response) Close() error { if r.Output != nil { // drain output (response body) - _, err1 := io.Copy(ioutil.Discard, r.Output) + _, err1 := io.Copy(io.Discard, r.Output) err2 := r.Output.Close() if err1 != nil { return err1 @@ -117,7 +116,7 @@ func (r *Request) Send(c *http.Client) (*Response, error) { case resp.StatusCode == http.StatusNotFound: e.Message = "command not found" case contentType == "text/plain": - out, err := ioutil.ReadAll(resp.Body) + out, err := io.ReadAll(resp.Body) if err != nil { fmt.Fprintf(os.Stderr, "ipfs-shell: warning! response (%d) read error: %s\n", resp.StatusCode, err) } @@ -140,7 +139,7 @@ func (r *Request) Send(c *http.Client) (*Response, error) { // This is a server-side bug (probably). e.Code = cmds.ErrImplementation fmt.Fprintf(os.Stderr, "ipfs-shell: warning! unhandled response (%d) encoding: %s", resp.StatusCode, contentType) - out, err := ioutil.ReadAll(resp.Body) + out, err := io.ReadAll(resp.Body) if err != nil { fmt.Fprintf(os.Stderr, "ipfs-shell: response (%d) read error: %s\n", resp.StatusCode, err) } @@ -150,7 +149,7 @@ func (r *Request) Send(c *http.Client) (*Response, error) { nresp.Output = nil // drain body and close - _, _ = io.Copy(ioutil.Discard, resp.Body) + _, _ = io.Copy(io.Discard, resp.Body) _ = resp.Body.Close() } From 1193b2978f7859ed8e1df4be50e980ff1bde7015 Mon Sep 17 00:00:00 2001 From: galargh Date: Sat, 1 Oct 2022 17:37:23 +0200 Subject: [PATCH 0349/1212] chore: remove unused linter directives This commit was moved from ipfs/go-ipfs-http-client@c4fc1a7740bfaad2abcba2563d569422e525324c --- client/httpapi/errors.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/client/httpapi/errors.go b/client/httpapi/errors.go index 1ccf6182c..59e4ad705 100644 --- a/client/httpapi/errors.go +++ b/client/httpapi/errors.go @@ -49,7 +49,6 @@ func parseErrNotFoundWithFallbackToError(msg error) error { return msg } -//lint:ignore ST1008 this function is not using the error as a mean to return failure but it massages it to return the correct type func parseErrNotFound(msg string) (error, bool) { if msg == "" { return nil, true // Fast path @@ -72,7 +71,6 @@ func parseErrNotFound(msg string) (error, bool) { // - Double Quotes: "\"" this is for parsing %q and %#v formating const cidBreakSet = " \t\n\r\v\f;\"" -//lint:ignore ST1008 using error as values func parseIPLDErrNotFound(msg string) (error, bool) { // The patern we search for is: const ipldErrNotFoundKey = "ipld: could not find " /*CID*/ @@ -159,7 +157,6 @@ func (e blockstoreNotFoundMatchingIPLDErrNotFound) Is(err error) bool { return ok } -//lint:ignore ST1008 using error as values func parseBlockstoreNotFound(msg string) (error, bool) { if !strings.Contains(msg, "blockstore: block not found") { return nil, false From 2d00514e229e30761d0c36b6bfcfce3178925fcc Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 3 Nov 2022 23:36:53 +0200 Subject: [PATCH 0350/1212] build: harden docker-image.yml permissions Signed-off-by: Alex --- .github/workflows/docker-image.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index 76e0c1c11..1d7237c5b 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -9,6 +9,9 @@ on: tags: - 'v*' +permissions: + contents: read # to fetch code (actions/checkout) + jobs: push_to_registry: if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' From d0afd218e179edc124b3bc2fe4738da817fce948 Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 3 Nov 2022 23:37:27 +0200 Subject: [PATCH 0351/1212] build: harden golang-analysis.yml permissions Signed-off-by: Alex --- .github/workflows/golang-analysis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/golang-analysis.yml b/.github/workflows/golang-analysis.yml index 3a74e61a2..b9476f94e 100644 --- a/.github/workflows/golang-analysis.yml +++ b/.github/workflows/golang-analysis.yml @@ -1,6 +1,9 @@ on: [push, pull_request] name: Go Checks +permissions: + contents: read # to fetch code (actions/checkout) + jobs: unit: runs-on: ubuntu-latest From c9f944cd624c7801c9790995b2d175131021bd06 Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 3 Nov 2022 23:51:49 +0200 Subject: [PATCH 0352/1212] build: harden sync-release-assets.yml permissions Signed-off-by: Alex --- .github/workflows/sync-release-assets.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/sync-release-assets.yml b/.github/workflows/sync-release-assets.yml index da3ca9582..269352bac 100644 --- a/.github/workflows/sync-release-assets.yml +++ b/.github/workflows/sync-release-assets.yml @@ -9,8 +9,12 @@ concurrency: group: release-assets-dist-sync cancel-in-progress: true +permissions: {} jobs: sync-github-and-dist-ipfs-tech: + permissions: + contents: write # to upload release asset + if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' runs-on: "ubuntu-latest" steps: From 9653185048dd9e4fdb2dc75e3c751a4072b73bb7 Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 3 Nov 2022 23:52:00 +0200 Subject: [PATCH 0353/1212] build: harden codeql-analysis.yml permissions Signed-off-by: Alex --- .github/workflows/codeql-analysis.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index af9006adf..4923571a6 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -11,8 +11,15 @@ on: schedule: - cron: '30 12 * * 2' +permissions: + contents: read # to fetch code (actions/checkout) + jobs: analyze: + permissions: + contents: read # to fetch code (actions/checkout) + security-events: write # (github/codeql-action/autobuild) + if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' name: Analyze runs-on: ubuntu-latest From 71b098e25fefe5017dac823f3516ec53bdbed6d2 Mon Sep 17 00:00:00 2001 From: Kubo Mage Date: Thu, 8 Dec 2022 15:25:33 +0000 Subject: [PATCH 0354/1212] 'docs: update RELEASE_ISSUE_TEMPLATE.md' --- docs/RELEASE_ISSUE_TEMPLATE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/RELEASE_ISSUE_TEMPLATE.md b/docs/RELEASE_ISSUE_TEMPLATE.md index 13b14c8a4..6ea6a3f25 100644 --- a/docs/RELEASE_ISSUE_TEMPLATE.md +++ b/docs/RELEASE_ISSUE_TEMPLATE.md @@ -1,4 +1,4 @@ - + > Release Issue Template. If doing a patch release, see [here](https://github.com/ipfs/kubo/blob/master/docs/PATCH_RELEASE_TEMPLATE.md) From 46577b15b76c8c9666f4112d034463076cd2604e Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Mon, 21 Nov 2022 09:38:01 +1300 Subject: [PATCH 0355/1212] chore: update go-libp2p to v0.23.4 This commit was moved from ipfs/interface-go-ipfs-core@96e9f233339ef16c3f1be4db6ced89ff82accfbb This commit was moved from ipfs/boxo@90ca296f80108f2fd10943895a8df31e28967850 --- core/coreiface/dht.go | 4 ++-- core/coreiface/idfmt.go | 2 +- core/coreiface/key.go | 4 ++-- core/coreiface/pubsub.go | 4 ++-- core/coreiface/swarm.go | 6 +++--- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/core/coreiface/dht.go b/core/coreiface/dht.go index 81a20ee2b..73bf48305 100644 --- a/core/coreiface/dht.go +++ b/core/coreiface/dht.go @@ -3,11 +3,11 @@ package iface import ( "context" - path "github.com/ipfs/interface-go-ipfs-core/path" + "github.com/ipfs/interface-go-ipfs-core/path" "github.com/ipfs/interface-go-ipfs-core/options" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/peer" ) // DhtAPI specifies the interface to the DHT diff --git a/core/coreiface/idfmt.go b/core/coreiface/idfmt.go index 1ba79e602..80fd0f822 100644 --- a/core/coreiface/idfmt.go +++ b/core/coreiface/idfmt.go @@ -1,7 +1,7 @@ package iface import ( - peer "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/peer" mbase "github.com/multiformats/go-multibase" ) diff --git a/core/coreiface/key.go b/core/coreiface/key.go index 967255665..b0e739cb8 100644 --- a/core/coreiface/key.go +++ b/core/coreiface/key.go @@ -3,11 +3,11 @@ package iface import ( "context" - path "github.com/ipfs/interface-go-ipfs-core/path" + "github.com/ipfs/interface-go-ipfs-core/path" "github.com/ipfs/interface-go-ipfs-core/options" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/peer" ) // Key specifies the interface to Keys in KeyAPI Keystore diff --git a/core/coreiface/pubsub.go b/core/coreiface/pubsub.go index d9826551d..427256251 100644 --- a/core/coreiface/pubsub.go +++ b/core/coreiface/pubsub.go @@ -4,9 +4,9 @@ import ( "context" "io" - options "github.com/ipfs/interface-go-ipfs-core/options" + "github.com/ipfs/interface-go-ipfs-core/options" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/peer" ) // PubSubSubscription is an active PubSub subscription diff --git a/core/coreiface/swarm.go b/core/coreiface/swarm.go index d7b25d5e8..9aa5466ba 100644 --- a/core/coreiface/swarm.go +++ b/core/coreiface/swarm.go @@ -5,9 +5,9 @@ import ( "errors" "time" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/protocol" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/protocol" ma "github.com/multiformats/go-multiaddr" ) From d2edb2ea7859d83a501c455ae054350c3622b83b Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Mon, 12 Dec 2022 21:09:45 +0100 Subject: [PATCH 0356/1212] feat: add UseCumulativeSize UnixfsLs option (#95) This commit was moved from ipfs/interface-go-ipfs-core@b1299abda0c69529c7efa02d5efb9f8905fdd4fe This commit was moved from ipfs/boxo@ff2eb2bff265f34012cca335447987da546ecee2 --- core/coreiface/options/unixfs.go | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/core/coreiface/options/unixfs.go b/core/coreiface/options/unixfs.go index 3fd96f772..cd15991e2 100644 --- a/core/coreiface/options/unixfs.go +++ b/core/coreiface/options/unixfs.go @@ -39,7 +39,8 @@ type UnixfsAddSettings struct { } type UnixfsLsSettings struct { - ResolveChildren bool + ResolveChildren bool + UseCumulativeSize bool } type UnixfsAddOption func(*UnixfsAddSettings) error @@ -283,3 +284,10 @@ func (unixfsOpts) ResolveChildren(resolve bool) UnixfsLsOption { return nil } } + +func (unixfsOpts) UseCumulativeSize(use bool) UnixfsLsOption { + return func(settings *UnixfsLsSettings) error { + settings.UseCumulativeSize = use + return nil + } +} From ef83ce0912daa6772d613bb8ab43599fc7fa10cf Mon Sep 17 00:00:00 2001 From: Kubo Mage Date: Tue, 13 Dec 2022 09:08:33 +0000 Subject: [PATCH 0357/1212] 'chore: update version.go' --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index 2762442ee..2ded5ffbf 100644 --- a/version.go +++ b/version.go @@ -11,7 +11,7 @@ import ( var CurrentCommit string // CurrentVersionNumber is the current application's version literal -const CurrentVersionNumber = "0.18.0-dev" +const CurrentVersionNumber = "v0.18.0-rc1" const ApiVersion = "/kubo/" + CurrentVersionNumber + "/" //nolint From 1ca3ea4a53a7d9857cbfe7c23d0cf9b0cdf29639 Mon Sep 17 00:00:00 2001 From: Piotr Galar Date: Tue, 13 Dec 2022 10:58:37 +0100 Subject: [PATCH 0358/1212] docs: enrich release issue template with initial set of mage commands --- docs/RELEASE_ISSUE_TEMPLATE.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/RELEASE_ISSUE_TEMPLATE.md b/docs/RELEASE_ISSUE_TEMPLATE.md index 6ea6a3f25..1938a338b 100644 --- a/docs/RELEASE_ISSUE_TEMPLATE.md +++ b/docs/RELEASE_ISSUE_TEMPLATE.md @@ -46,6 +46,7 @@ Checklist: - [ ] Mention @protocol/bifrost-team in the issue and let them know the expected date of the release - Issue link: - [ ] Ensure that the `What's left for release` section has all the checkboxes checked. If that's not the case, discuss the open items with Kubo maintainers and update the release schedule accordingly. + - `go run main.go kubo:issue:checkOutstandingTasks v0.18.0` - [ ] Create `docs-release-vX.Y.Z` branch, open a draft PR and keep updating `docs/RELEASE_ISSUE_TEMPLATE.md` on that branch as you go. - [ ] Link it in the "Meta" section above. - [ ] Ensure you have a [GPG key generated](https://docs.github.com/en/authentication/managing-commit-signature-verification/generating-a-new-gpg-key) and [added to your GitHub account](https://docs.github.com/en/authentication/managing-commit-signature-verification/adding-a-gpg-key-to-your-github-account). This will enable you to created signed tags. @@ -69,13 +70,18 @@ Checklist: - [ ] [ipfs/kubo](https://github.com/ipfs/kubo): [example PR](https://github.com/ipfs/kubo/pull/8599) - [ ] [ipfs/ipfs-docs](https://github.com/ipfs/ipfs-docs): [example PR](https://github.com/ipfs/ipfs-docs/pull/1298) - only if the major version changed - [ ] Fork a new branch (`release-vX.Y.Z`) from `master`. + - `go run main.go kubo:release:cutReleaseBranch v0.18.0` - [ ] Bump the version in `version.go` in the `master` branch to `vX.(Y+1).0-dev` via a PR ([example](https://github.com/ipfs/kubo/pull/9305)). + - `go run main.go kubo:main:updateVersion v0.18.0` - [ ] **Stage 2 - Release Candidate** - _if any [non-trivial](docs/releases.md#footnotes) changes need to be included in the release, return to this stage_ - [ ] If it's not a first RC, add new commits to the `release-vX.Y.Z` branch from `master` using `git cherry-pick -x ...` - Note: `release-*` branches are protected. You can do all needed updates on a separated branch (e.g. `wip-release-vX.Y.Z`) and when everything is settled push to `release-vX.Y.Z` - [ ] Bump the version in `version.go` in the `release-vX.Y.Z` branch to `vX.Y.Z-rcN`. + - `go run main.go kubo:release:updateReleaseVersion v0.18.0-rc1` - [ ] If it's a first RC, create a draft PR targetting `release` branch if it doesn't exist yet ([example](https://github.com/ipfs/kubo/pull/9306)). + - `go run main.go kubo:release:createReleasePR v0.18.0` - [ ] Wait for CI to run and complete PR checks. All checks should pass. + - `go run main.go kubo:release:checkCI v0.18.0` - [ ] Create a signed tag for the release candidate. - [ ] This is a dangerous operation, as it is difficult to reverse due to Go modules and automated Docker image publishing. Remember to verify the commands you intend to run for items marked with ⚠️ with the release reviewer. - [ ] ⚠️ Tag HEAD `release-vX.Y.Z` commit with `vX.Y.Z-rcN` (`git tag -s vX.Y.Z-rcN -m 'Pre-release X.Y.Z-rcn'`) From ae774a3548dfc08ae8fb3493d96864df31682fb0 Mon Sep 17 00:00:00 2001 From: Piotr Galar Date: Tue, 13 Dec 2022 11:19:59 +0100 Subject: [PATCH 0359/1212] Update version.go --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index 2ded5ffbf..63839b84b 100644 --- a/version.go +++ b/version.go @@ -11,7 +11,7 @@ import ( var CurrentCommit string // CurrentVersionNumber is the current application's version literal -const CurrentVersionNumber = "v0.18.0-rc1" +const CurrentVersionNumber = "0.18.0-rc1" const ApiVersion = "/kubo/" + CurrentVersionNumber + "/" //nolint From fe542db0617d5b20cca63bdee4cc70c1d30dac63 Mon Sep 17 00:00:00 2001 From: Piotr Galar Date: Tue, 13 Dec 2022 16:55:20 +0100 Subject: [PATCH 0360/1212] docs: add more automation commands to the release template --- docs/RELEASE_ISSUE_TEMPLATE.md | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/docs/RELEASE_ISSUE_TEMPLATE.md b/docs/RELEASE_ISSUE_TEMPLATE.md index 1938a338b..dd547760d 100644 --- a/docs/RELEASE_ISSUE_TEMPLATE.md +++ b/docs/RELEASE_ISSUE_TEMPLATE.md @@ -46,9 +46,9 @@ Checklist: - [ ] Mention @protocol/bifrost-team in the issue and let them know the expected date of the release - Issue link: - [ ] Ensure that the `What's left for release` section has all the checkboxes checked. If that's not the case, discuss the open items with Kubo maintainers and update the release schedule accordingly. - - `go run main.go kubo:issue:checkOutstandingTasks v0.18.0` + - `go run main.go kubo:issue:checkOutstandingTasks v0.18.0` - [ ] Create `docs-release-vX.Y.Z` branch, open a draft PR and keep updating `docs/RELEASE_ISSUE_TEMPLATE.md` on that branch as you go. - - [ ] Link it in the "Meta" section above. + - [ ] Link it in the "Meta" section above. - [ ] Ensure you have a [GPG key generated](https://docs.github.com/en/authentication/managing-commit-signature-verification/generating-a-new-gpg-key) and [added to your GitHub account](https://docs.github.com/en/authentication/managing-commit-signature-verification/adding-a-gpg-key-to-your-github-account). This will enable you to created signed tags. - [ ] Ensure you have [admin access](https://discuss.ipfs.tech/g/admins) to [IPFS Discourse](https://discuss.ipfs.tech/). Admin access is required to globally pin posts and create banners. @2color might be able to assist you. - [ ] Access to [#bifrost](https://filecoinproject.slack.com/archives/C03MMMF606T) channel in FIL Slack might come in handy. Ask the release reviewer to invite you over. @@ -70,24 +70,26 @@ Checklist: - [ ] [ipfs/kubo](https://github.com/ipfs/kubo): [example PR](https://github.com/ipfs/kubo/pull/8599) - [ ] [ipfs/ipfs-docs](https://github.com/ipfs/ipfs-docs): [example PR](https://github.com/ipfs/ipfs-docs/pull/1298) - only if the major version changed - [ ] Fork a new branch (`release-vX.Y.Z`) from `master`. - - `go run main.go kubo:release:cutReleaseBranch v0.18.0` + - `go run main.go kubo:release:cutReleaseBranch v0.18.0` - [ ] Bump the version in `version.go` in the `master` branch to `vX.(Y+1).0-dev` via a PR ([example](https://github.com/ipfs/kubo/pull/9305)). - - `go run main.go kubo:main:updateVersion v0.18.0` + - `go run main.go kubo:main:updateVersion v0.18.0` - [ ] **Stage 2 - Release Candidate** - _if any [non-trivial](docs/releases.md#footnotes) changes need to be included in the release, return to this stage_ - [ ] If it's not a first RC, add new commits to the `release-vX.Y.Z` branch from `master` using `git cherry-pick -x ...` - - Note: `release-*` branches are protected. You can do all needed updates on a separated branch (e.g. `wip-release-vX.Y.Z`) and when everything is settled push to `release-vX.Y.Z` + - Note: `release-*` branches are protected. You can do all needed updates on a separated branch (e.g. `wip-release-vX.Y.Z`) and when everything is settled push to `release-vX.Y.Z` - [ ] Bump the version in `version.go` in the `release-vX.Y.Z` branch to `vX.Y.Z-rcN`. - - `go run main.go kubo:release:updateReleaseVersion v0.18.0-rc1` + - `go run main.go kubo:release:updateReleaseVersion v0.18.0-rc1` - [ ] If it's a first RC, create a draft PR targetting `release` branch if it doesn't exist yet ([example](https://github.com/ipfs/kubo/pull/9306)). - `go run main.go kubo:release:createReleasePR v0.18.0` - [ ] Wait for CI to run and complete PR checks. All checks should pass. - - `go run main.go kubo:release:checkCI v0.18.0` + - `go run main.go kubo:release:checkReleaseCI v0.18.0` - [ ] Create a signed tag for the release candidate. - - [ ] This is a dangerous operation, as it is difficult to reverse due to Go modules and automated Docker image publishing. Remember to verify the commands you intend to run for items marked with ⚠️ with the release reviewer. + - `go run main.go kubo:release:createReleaseTag v0.18.0-rc1` + - This is a dangerous operation, as it is difficult to reverse due to Go modules and automated Docker image publishing. Remember to verify the commands you intend to run for items marked with ⚠️ with the release reviewer. - [ ] ⚠️ Tag HEAD `release-vX.Y.Z` commit with `vX.Y.Z-rcN` (`git tag -s vX.Y.Z-rcN -m 'Pre-release X.Y.Z-rcn'`) - [ ] Run `git show vX.Y.Z-rcN` to ensure the tag is correct. - [ ] ⚠️ Push the `vX.Y.Z-rcN` tag to GitHub (`git push origin vX.Y.Z-rcN`; DO NOT USE `git push --tags` because it pushes all your local tags). - [ ] Add artifacts to https://dist.ipfs.tech by making a PR against [ipfs/distributions](https://github.com/ipfs/distributions) + - `go run main.go dist:dist:createDistPR v0.18.0-rc1` - [ ] Clone the `ipfs/distributions` repo locally. - [ ] Create a new branch (`kubo-release-vX.Y.Z-rcn`) from `master`. - [ ] Run `./dist.sh add-version kubo vX.Y.Z-rcN` to add the new version to the `versions` file ([instructions](https://github.com/ipfs/distributions#usage)). @@ -99,6 +101,7 @@ Checklist: - PR will be merged automatically once the diff is approved - `master` build will publish the artifacts to https://dist.ipfs.io in around 30 minutes - [ ] Ensure that the artifacts are available at https://dist.ipfs.io + - `go run main.go dist:dist:checkIPFSTech v0.18.0-rc1` - [ ] Publish the RC to [the NPM package](https://www.npmjs.com/package/go-ipfs?activeTab=versions) by running https://github.com/ipfs/npm-go-ipfs/actions/workflows/main.yml (it happens automatically but it is safe to speed up the process and kick of a run manually) - [ ] Cut a pre-release on [GitHub](https://github.com/ipfs/kubo/releases) ([instructions](https://docs.github.com/en/repositories/releasing-projects-on-github/managing-releases-in-a-repository#creating-a-release), [example](https://github.com/ipfs/kubo/releases/tag/v0.17.0-rc1)) - Use `vX.Y.Z-rcN` as the tag. From 7db059b493c9547ebd80eeaee48cabe1b88263c8 Mon Sep 17 00:00:00 2001 From: Piotr Galar Date: Tue, 13 Dec 2022 22:09:55 +0100 Subject: [PATCH 0361/1212] Update RELEASE_ISSUE_TEMPLATE.md --- docs/RELEASE_ISSUE_TEMPLATE.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/RELEASE_ISSUE_TEMPLATE.md b/docs/RELEASE_ISSUE_TEMPLATE.md index dd547760d..ef2a22803 100644 --- a/docs/RELEASE_ISSUE_TEMPLATE.md +++ b/docs/RELEASE_ISSUE_TEMPLATE.md @@ -103,12 +103,16 @@ Checklist: - [ ] Ensure that the artifacts are available at https://dist.ipfs.io - `go run main.go dist:dist:checkIPFSTech v0.18.0-rc1` - [ ] Publish the RC to [the NPM package](https://www.npmjs.com/package/go-ipfs?activeTab=versions) by running https://github.com/ipfs/npm-go-ipfs/actions/workflows/main.yml (it happens automatically but it is safe to speed up the process and kick of a run manually) + - `go run main.go npm:npm:publishToNPM v0.18.0-rc1` + - `go run main.go npm:npm:checkNPM v0.18.0-rc1` - [ ] Cut a pre-release on [GitHub](https://github.com/ipfs/kubo/releases) ([instructions](https://docs.github.com/en/repositories/releasing-projects-on-github/managing-releases-in-a-repository#creating-a-release), [example](https://github.com/ipfs/kubo/releases/tag/v0.17.0-rc1)) + - `go run main.go kubo:createGitHubRelease v0.18.0-rc1` - Use `vX.Y.Z-rcN` as the tag. - Link to the release issue in the description. - Link to the relevant [changelog](https://github.com/ipfs/kubo/blob/master/docs/changelogs/) in the description. - Check `This is a pre-release`. - [ ] Synchronize release artifacts by running [sync-release-assets](https://github.com/ipfs/kubo/actions/workflows/sync-release-assets.yml) workflow. + - `go run main.go kubo:syncGitHubRelease v0.18.0-rc1` - [ ] Announce the RC - [ ] Create a new post on [IPFS Discourse](https://discuss.ipfs.tech). ([example](https://discuss.ipfs.tech/t/kubo-v0-16-0-rc1-release-candidate-is-out/15248)) - Use `Kubo vX.Y.Z-rcn Release Candidate is out!` as the title. From d6069b93ee8a2f23ca478fbc5938b5e9231a0f22 Mon Sep 17 00:00:00 2001 From: Antonio Navarro Perez Date: Tue, 3 Jan 2023 21:10:33 +0100 Subject: [PATCH 0362/1212] fix: disable provide over HTTP with Routing.Type=auto (#9511) Closes https://github.com/ipfs/kubo/issues/9504 --- core/node/libp2p/routingopt.go | 20 ++++++- docs/environment-variables.md | 17 ++++++ docs/examples/kubo-as-a-library/go.mod | 4 +- docs/examples/kubo-as-a-library/go.sum | 8 +-- go.mod | 4 +- go.sum | 8 +-- routing/composer.go | 9 ++++ .../t0172-content-routing-over-http.sh | 54 +++++++++++++++++++ 8 files changed, 111 insertions(+), 13 deletions(-) create mode 100755 test/sharness/t0172-content-routing-over-http.sh diff --git a/core/node/libp2p/routingopt.go b/core/node/libp2p/routingopt.go index 2d2b7570c..bfb45971c 100644 --- a/core/node/libp2p/routingopt.go +++ b/core/node/libp2p/routingopt.go @@ -2,6 +2,8 @@ package libp2p import ( "context" + "os" + "strings" "time" "github.com/ipfs/go-datastore" @@ -30,6 +32,13 @@ var defaultHTTPRouters = []string{ // TODO: add an independent router from Cloudflare } +func init() { + // Override HTTP routers if custom ones were passed via env + if routers := os.Getenv("IPFS_HTTP_ROUTERS"); routers != "" { + defaultHTTPRouters = strings.Split(routers, " ") + } +} + // ConstructDefaultRouting returns routers used when Routing.Type is unset or set to "auto" func ConstructDefaultRouting(peerID string, addrs []string, privKey string) func( ctx context.Context, @@ -67,8 +76,17 @@ func ConstructDefaultRouting(peerID string, addrs []string, privKey string) func if err != nil { return nil, err } + + r := &irouting.Composer{ + GetValueRouter: routinghelpers.Null{}, + PutValueRouter: routinghelpers.Null{}, + ProvideRouter: routinghelpers.Null{}, // modify this when indexers supports provide + FindPeersRouter: routinghelpers.Null{}, + FindProvidersRouter: httpRouter, + } + routers = append(routers, &routinghelpers.ParallelRouter{ - Router: httpRouter, + Router: r, IgnoreError: true, // https://github.com/ipfs/kubo/pull/9475#discussion_r1042507387 Timeout: 15 * time.Second, // 5x server value from https://github.com/ipfs/kubo/pull/9475#discussion_r1042428529 ExecuteAfter: 0, diff --git a/docs/environment-variables.md b/docs/environment-variables.md index 98b449054..add8592a0 100644 --- a/docs/environment-variables.md +++ b/docs/environment-variables.md @@ -114,6 +114,23 @@ $ ipfs resolve -r /ipns/dnslink-test2.example.com /ipfs/bafkreicysg23kiwv34eg2d7qweipxwosdo2py4ldv42nbauguluen5v6am ``` +## `IPFS_HTTP_ROUTERS` + +Overrides all implicit HTTP routers enabled when `Routing.Type=auto` with +the space-separated list of URLs provided in this variable. +Useful for testing and debugging in offline contexts. + +Example: + +```console +$ ipfs config Routing.Type auto +$ IPFS_HTTP_ROUTERS="http://127.0.0.1:7423" ipfs daemon +``` + +The above will replace implicit HTTP routers with single one, allowing for +inspection/debug of HTTP requests sent by Kubo via `while true ; do nc -l 7423; done` +or more advanced tools like [mitmproxy](https://docs.mitmproxy.org/stable/#mitmproxy). + ## `LIBP2P_TCP_REUSEPORT` Kubo tries to reuse the same source port for all connections to improve NAT diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 1c40cfe81..1846a1ea9 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -127,7 +127,7 @@ require ( github.com/libp2p/go-libp2p-pubsub v0.8.2 // indirect github.com/libp2p/go-libp2p-pubsub-router v0.6.0 // indirect github.com/libp2p/go-libp2p-record v0.2.0 // indirect - github.com/libp2p/go-libp2p-routing-helpers v0.4.1 // indirect + github.com/libp2p/go-libp2p-routing-helpers v0.5.0 // indirect github.com/libp2p/go-libp2p-xor v0.1.0 // indirect github.com/libp2p/go-mplex v0.7.0 // indirect github.com/libp2p/go-msgio v0.2.0 // indirect @@ -198,7 +198,7 @@ require ( go.uber.org/atomic v1.10.0 // indirect go.uber.org/dig v1.15.0 // indirect go.uber.org/fx v1.18.2 // indirect - go.uber.org/multierr v1.8.0 // indirect + go.uber.org/multierr v1.9.0 // indirect go.uber.org/zap v1.24.0 // indirect go4.org v0.0.0-20200411211856-f5505b9728dd // indirect golang.org/x/crypto v0.3.0 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index f2d9d7ebd..fa464c50e 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -793,8 +793,8 @@ github.com/libp2p/go-libp2p-quic-transport v0.10.0/go.mod h1:RfJbZ8IqXIhxBRm5hqU github.com/libp2p/go-libp2p-record v0.1.0/go.mod h1:ujNc8iuE5dlKWVy6wuL6dd58t0n7xI4hAIl8pE6wu5Q= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= github.com/libp2p/go-libp2p-record v0.2.0/go.mod h1:I+3zMkvvg5m2OcSdoL0KPljyJyvNDFGKX7QdlpYUcwk= -github.com/libp2p/go-libp2p-routing-helpers v0.4.1 h1:rOlZiFpUt7SgHm4w62MBvWaQ4UHh7bVJnSnor6RN7j8= -github.com/libp2p/go-libp2p-routing-helpers v0.4.1/go.mod h1:dYEAgkVhqho3/YKxfOEGdFMIcWfAFNlZX8iAIihYA2E= +github.com/libp2p/go-libp2p-routing-helpers v0.5.0 h1:Byujua1X9MeTzbF54i5OwjUNopeg7PYBykuNow/w3p4= +github.com/libp2p/go-libp2p-routing-helpers v0.5.0/go.mod h1:wwK/XSLt6njjO7sRbjhf8w7PGBOfdntMQ2mOQPZ5s/Q= github.com/libp2p/go-libp2p-secio v0.1.0/go.mod h1:tMJo2w7h3+wN4pgU2LSYeiKPrfqBgkOsdiKK77hE7c8= github.com/libp2p/go-libp2p-secio v0.2.0/go.mod h1:2JdZepB8J5V9mBp79BmwsaPQhRPNN2NrnB2lKQcdy6g= github.com/libp2p/go-libp2p-secio v0.2.1/go.mod h1:cWtZpILJqkqrSkiYcDBh5lA3wbT2Q+hz3rJQq3iftD8= @@ -1377,8 +1377,8 @@ go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+ go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/multierr v1.7.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= -go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8= -go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= +go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= +go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= diff --git a/go.mod b/go.mod index f214d5743..bb0dd2930 100644 --- a/go.mod +++ b/go.mod @@ -79,7 +79,7 @@ require ( github.com/libp2p/go-libp2p-pubsub v0.8.2 github.com/libp2p/go-libp2p-pubsub-router v0.6.0 github.com/libp2p/go-libp2p-record v0.2.0 - github.com/libp2p/go-libp2p-routing-helpers v0.4.0 + github.com/libp2p/go-libp2p-routing-helpers v0.5.0 github.com/libp2p/go-libp2p-testing v0.12.0 github.com/libp2p/go-socket-activation v0.1.0 github.com/miekg/dns v1.1.50 @@ -231,7 +231,7 @@ require ( go.opentelemetry.io/otel/metric v0.30.0 // indirect go.opentelemetry.io/proto/otlp v0.16.0 // indirect go.uber.org/atomic v1.10.0 // indirect - go.uber.org/multierr v1.8.0 // indirect + go.uber.org/multierr v1.9.0 // indirect go4.org v0.0.0-20200411211856-f5505b9728dd // indirect golang.org/x/exp v0.0.0-20221205204356-47842c84f3db // indirect golang.org/x/net v0.3.0 // indirect diff --git a/go.sum b/go.sum index f890f22b0..435c88bc2 100644 --- a/go.sum +++ b/go.sum @@ -828,8 +828,8 @@ github.com/libp2p/go-libp2p-quic-transport v0.10.0/go.mod h1:RfJbZ8IqXIhxBRm5hqU github.com/libp2p/go-libp2p-record v0.1.0/go.mod h1:ujNc8iuE5dlKWVy6wuL6dd58t0n7xI4hAIl8pE6wu5Q= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= github.com/libp2p/go-libp2p-record v0.2.0/go.mod h1:I+3zMkvvg5m2OcSdoL0KPljyJyvNDFGKX7QdlpYUcwk= -github.com/libp2p/go-libp2p-routing-helpers v0.4.0 h1:b7y4aixQ7AwbqYfcOQ6wTw8DQvuRZeTAA0Od3YYN5yc= -github.com/libp2p/go-libp2p-routing-helpers v0.4.0/go.mod h1:dYEAgkVhqho3/YKxfOEGdFMIcWfAFNlZX8iAIihYA2E= +github.com/libp2p/go-libp2p-routing-helpers v0.5.0 h1:Byujua1X9MeTzbF54i5OwjUNopeg7PYBykuNow/w3p4= +github.com/libp2p/go-libp2p-routing-helpers v0.5.0/go.mod h1:wwK/XSLt6njjO7sRbjhf8w7PGBOfdntMQ2mOQPZ5s/Q= github.com/libp2p/go-libp2p-secio v0.1.0/go.mod h1:tMJo2w7h3+wN4pgU2LSYeiKPrfqBgkOsdiKK77hE7c8= github.com/libp2p/go-libp2p-secio v0.2.0/go.mod h1:2JdZepB8J5V9mBp79BmwsaPQhRPNN2NrnB2lKQcdy6g= github.com/libp2p/go-libp2p-secio v0.2.1/go.mod h1:cWtZpILJqkqrSkiYcDBh5lA3wbT2Q+hz3rJQq3iftD8= @@ -1441,8 +1441,8 @@ go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+ go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/multierr v1.7.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= -go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8= -go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= +go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= +go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= diff --git a/routing/composer.go b/routing/composer.go index f2f1f65e6..f54d954bd 100644 --- a/routing/composer.go +++ b/routing/composer.go @@ -100,9 +100,18 @@ func (c *Composer) GetValue(ctx context.Context, key string, opts ...routing.Opt func (c *Composer) SearchValue(ctx context.Context, key string, opts ...routing.Option) (<-chan []byte, error) { log.Debug("composer: calling searchValue: ", key) ch, err := c.GetValueRouter.SearchValue(ctx, key, opts...) + + // avoid nil channels on implementations not supporting SearchValue method. + if err == routing.ErrNotFound && ch == nil { + out := make(chan []byte) + close(out) + return out, err + } + if err != nil { log.Debug("composer: calling searchValue error: ", key, err) } + return ch, err } diff --git a/test/sharness/t0172-content-routing-over-http.sh b/test/sharness/t0172-content-routing-over-http.sh new file mode 100755 index 000000000..bc35c6328 --- /dev/null +++ b/test/sharness/t0172-content-routing-over-http.sh @@ -0,0 +1,54 @@ +#!/usr/bin/env bash + +test_description="Test content routing over HTTP" + +. lib/test-lib.sh + + +if ! test_have_prereq SOCAT; then + skip_all="skipping '$test_description': socat is not available" + test_done +fi + +test_init_ipfs + +# Run listener on a free port to log HTTP requests sent by Kubo in Routing.Type=auto mode +export ROUTER_PORT=$(comm -23 <(seq 49152 65535 | sort) <(ss -Htan | awk '{print $4}' | cut -d':' -f2) | head -n 1) +export IPFS_HTTP_ROUTERS="http://127.0.0.1:$ROUTER_PORT" + +test_launch_ipfs_daemon + +test_expect_success "start HTTP router proxy" ' + socat TCP-LISTEN:$ROUTER_PORT,reuseaddr,fork,bind=127.0.0.1 STDOUT > http_requests & + NCPID=$! +' + +## HTTP GETs + +test_expect_success 'create unique CID without adding it to the local datastore' ' + WANT_CID=$(date +"%FT%T.%N%z" | ipfs add -qn) +' + +test_expect_success 'expect HTTP request for unknown CID' ' + ipfs routing findprovs --timeout 3s "$WANT_CID" && + test_should_contain "GET /routing/v1/providers/$WANT_CID" http_requests +' + +## HTTP PUTs + +test_expect_success 'add new CID to the local datastore' ' + ADD_CID=$(date +"%FT%T.%N%z" | ipfs add -q) +' + +# cid.contact supports GET-only: https://github.com/ipfs/kubo/issues/9504 +# which means no announcements over HTTP should be made. +test_expect_success 'expect no HTTP requests to be sent with locally added CID' ' + test_should_not_contain "$ADD_CID" http_requests +' + +test_expect_success "stop nc" ' + kill "$NCPID" && wait "$NCPID" || true +' + +test_kill_ipfs_daemon +test_done From e44a4d922853c56a8db5193990a0179af89dd083 Mon Sep 17 00:00:00 2001 From: Piotr Galar Date: Wed, 14 Dec 2022 10:38:00 +0100 Subject: [PATCH 0363/1212] Merge pull request #9503 from ipfs/docs/early-testers-remove-qri Removing QRI from early tester --- docs/EARLY_TESTERS.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/EARLY_TESTERS.md b/docs/EARLY_TESTERS.md index ee008c1a2..fb2fedc2a 100644 --- a/docs/EARLY_TESTERS.md +++ b/docs/EARLY_TESTERS.md @@ -27,7 +27,6 @@ We will ask early testers to participate at two points in the process: - [ ] Textile (@sanderpick) - [ ] Pinata (@obo20) - [ ] RTrade (@postables) -- [ ] QRI (@b5) - [ ] Siderus (@koalalorenzo) - [ ] Charity Engine (@rytiss, @tristanolive) - [ ] Fission (@bmann) From c8442bcf191419b7b22ef82775fd97fe991e2fc9 Mon Sep 17 00:00:00 2001 From: Gus Eggert Date: Mon, 12 Dec 2022 09:16:55 -0500 Subject: [PATCH 0364/1212] feat: port pins CLI test --- test/cli/pins_test.go | 214 +++++++++++++++++++++ test/cli/testutils/files.go | 37 ++++ test/cli/testutils/json.go | 13 ++ test/cli/testutils/random.go | 12 ++ test/cli/testutils/{util.go => strings.go} | 56 +----- test/sharness/t0085-pins.sh | 201 ------------------- 6 files changed, 282 insertions(+), 251 deletions(-) create mode 100644 test/cli/pins_test.go create mode 100644 test/cli/testutils/files.go create mode 100644 test/cli/testutils/json.go create mode 100644 test/cli/testutils/random.go rename test/cli/testutils/{util.go => strings.go} (59%) delete mode 100755 test/sharness/t0085-pins.sh diff --git a/test/cli/pins_test.go b/test/cli/pins_test.go new file mode 100644 index 000000000..14a3dc238 --- /dev/null +++ b/test/cli/pins_test.go @@ -0,0 +1,214 @@ +package cli + +import ( + "fmt" + "strings" + "testing" + + "github.com/ipfs/go-cid" + "github.com/ipfs/kubo/test/cli/harness" + . "github.com/ipfs/kubo/test/cli/testutils" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +type testPinsArgs struct { + runDaemon bool + pinArg string + lsArg string + baseArg string +} + +func testPins(t *testing.T, args testPinsArgs) { + t.Run(fmt.Sprintf("test pins with args=%+v", args), func(t *testing.T) { + t.Parallel() + node := harness.NewT(t).NewNode().Init() + if args.runDaemon { + node.StartDaemon("--offline") + } + + strs := []string{"a", "b", "c", "d", "e", "f", "g"} + dataToCid := map[string]string{} + cids := []string{} + + ipfsAdd := func(t *testing.T, content string) string { + cidStr := node.IPFSAddStr(content, StrCat(args.baseArg, "--pin=false")...) + + _, err := cid.Decode(cidStr) + require.NoError(t, err) + dataToCid[content] = cidStr + cids = append(cids, cidStr) + return cidStr + } + + ipfsPinAdd := func(cids []string) []string { + input := strings.Join(cids, "\n") + return node.PipeStrToIPFS(input, StrCat("pin", "add", args.pinArg, args.baseArg)...).Stdout.Lines() + } + + ipfsPinLS := func() string { + return node.IPFS(StrCat("pin", "ls", args.lsArg, args.baseArg)...).Stdout.Trimmed() + } + + for _, s := range strs { + ipfsAdd(t, s) + } + + // these subtests run sequentially since they depend on state + + t.Run("check output of pin command", func(t *testing.T) { + resLines := ipfsPinAdd(cids) + + for i, s := range resLines { + assert.Equal(t, + fmt.Sprintf("pinned %s recursively", cids[i]), + s, + ) + } + }) + + t.Run("pin verify should succeed", func(t *testing.T) { + node.IPFS("pin", "verify") + }) + + t.Run("'pin verify --verbose' should include all the cids", func(t *testing.T) { + verboseVerifyOut := node.IPFS(StrCat("pin", "verify", "--verbose", args.baseArg)...).Stdout.String() + for _, cid := range cids { + assert.Contains(t, verboseVerifyOut, fmt.Sprintf("%s ok", cid)) + } + + }) + t.Run("ls output should contain the cids", func(t *testing.T) { + lsOut := ipfsPinLS() + for _, cid := range cids { + assert.Contains(t, lsOut, cid) + } + }) + + t.Run("check 'pin ls hash' output", func(t *testing.T) { + lsHashOut := node.IPFS(StrCat("pin", "ls", args.lsArg, args.baseArg, dataToCid["b"])...) + lsHashOutStr := lsHashOut.Stdout.String() + assert.Equal(t, fmt.Sprintf("%s recursive\n", dataToCid["b"]), lsHashOutStr) + }) + + t.Run("unpinning works", func(t *testing.T) { + node.PipeStrToIPFS(strings.Join(cids, "\n"), "pin", "rm") + }) + + t.Run("test pin update", func(t *testing.T) { + cidA := dataToCid["a"] + cidB := dataToCid["b"] + + ipfsPinAdd([]string{cidA}) + beforeUpdate := ipfsPinLS() + + assert.Contains(t, beforeUpdate, cidA) + assert.NotContains(t, beforeUpdate, cidB) + + node.IPFS("pin", "update", "--unpin=true", cidA, cidB) + afterUpdate := ipfsPinLS() + + assert.NotContains(t, afterUpdate, cidA) + assert.Contains(t, afterUpdate, cidB) + + node.IPFS("pin", "update", "--unpin=true", cidB, cidB) + afterIdempotentUpdate := ipfsPinLS() + + assert.Contains(t, afterIdempotentUpdate, cidB) + + node.IPFS("pin", "rm", cidB) + }) + }) +} + +func testPinsErrorReporting(t *testing.T, args testPinsArgs) { + t.Run(fmt.Sprintf("test pins error reporting with args=%+v", args), func(t *testing.T) { + t.Parallel() + node := harness.NewT(t).NewNode().Init() + if args.runDaemon { + node.StartDaemon("--offline") + } + randomCID := "Qme8uX5n9hn15pw9p6WcVKoziyyC9LXv4LEgvsmKMULjnV" + res := node.RunIPFS(StrCat("pin", "add", args.pinArg, randomCID)...) + assert.NotEqual(t, 0, res.ExitErr.ExitCode()) + assert.Contains(t, res.Stderr.String(), "ipld: could not find") + }) +} + +func testPinDAG(t *testing.T, args testPinsArgs) { + t.Run(fmt.Sprintf("test pin DAG with args=%+v", args), func(t *testing.T) { + t.Parallel() + h := harness.NewT(t) + node := h.NewNode().Init() + if args.runDaemon { + node.StartDaemon("--offline") + } + bytes := RandomBytes(1 << 20) // 1 MiB + tmpFile := h.WriteToTemp(string(bytes)) + cid := node.IPFS(StrCat("add", args.pinArg, "--pin=false", "-q", tmpFile)...).Stdout.Trimmed() + + node.IPFS("pin", "add", "--recursive=true", cid) + node.IPFS("pin", "rm", cid) + + // remove part of the DAG + part := node.IPFS("refs", cid).Stdout.Lines()[0] + node.IPFS("block", "rm", part) + + res := node.RunIPFS("pin", "add", "--recursive=true", cid) + assert.NotEqual(t, 0, res) + assert.Contains(t, res.Stderr.String(), "ipld: could not find") + }) +} + +func testPinProgress(t *testing.T, args testPinsArgs) { + t.Run(fmt.Sprintf("test pin progress with args=%+v", args), func(t *testing.T) { + t.Parallel() + h := harness.NewT(t) + node := h.NewNode().Init() + + if args.runDaemon { + node.StartDaemon("--offline") + } + + bytes := RandomBytes(1 << 20) // 1 MiB + tmpFile := h.WriteToTemp(string(bytes)) + cid := node.IPFS(StrCat("add", args.pinArg, "--pin=false", "-q", tmpFile)...).Stdout.Trimmed() + + res := node.RunIPFS("pin", "add", "--progress", cid) + node.Runner.AssertNoError(res) + + assert.Contains(t, res.Stderr.String(), " 5 nodes") + }) +} + +func TestPins(t *testing.T) { + t.Parallel() + t.Run("test pinning without daemon running", func(t *testing.T) { + t.Parallel() + testPinsErrorReporting(t, testPinsArgs{}) + testPinsErrorReporting(t, testPinsArgs{pinArg: "--progress"}) + testPinDAG(t, testPinsArgs{}) + testPinDAG(t, testPinsArgs{pinArg: "--raw-leaves"}) + testPinProgress(t, testPinsArgs{}) + testPins(t, testPinsArgs{}) + testPins(t, testPinsArgs{pinArg: "--progress"}) + testPins(t, testPinsArgs{pinArg: "--progress", lsArg: "--stream"}) + testPins(t, testPinsArgs{baseArg: "--cid-base=base32"}) + testPins(t, testPinsArgs{lsArg: "--stream", baseArg: "--cid-base=base32"}) + + }) + + t.Run("test pinning with daemon running without network", func(t *testing.T) { + t.Parallel() + testPinsErrorReporting(t, testPinsArgs{runDaemon: true}) + testPinsErrorReporting(t, testPinsArgs{runDaemon: true, pinArg: "--progress"}) + testPinDAG(t, testPinsArgs{runDaemon: true}) + testPinDAG(t, testPinsArgs{runDaemon: true, pinArg: "--raw-leaves"}) + testPinProgress(t, testPinsArgs{runDaemon: true}) + testPins(t, testPinsArgs{runDaemon: true}) + testPins(t, testPinsArgs{runDaemon: true, pinArg: "--progress"}) + testPins(t, testPinsArgs{runDaemon: true, pinArg: "--progress", lsArg: "--stream"}) + testPins(t, testPinsArgs{runDaemon: true, baseArg: "--cid-base=base32"}) + testPins(t, testPinsArgs{runDaemon: true, lsArg: "--stream", baseArg: "--cid-base=base32"}) + }) +} diff --git a/test/cli/testutils/files.go b/test/cli/testutils/files.go new file mode 100644 index 000000000..e17c98adf --- /dev/null +++ b/test/cli/testutils/files.go @@ -0,0 +1,37 @@ +package testutils + +import ( + "log" + "os" + "path/filepath" +) + +func MustOpen(name string) *os.File { + f, err := os.Open(name) + if err != nil { + log.Panicf("opening %s: %s", name, err) + } + return f +} + +// Searches for a file in a dir, then the parent dir, etc. +// If the file is not found, an empty string is returned. +func FindUp(name, dir string) string { + curDir := dir + for { + entries, err := os.ReadDir(curDir) + if err != nil { + panic(err) + } + for _, e := range entries { + if name == e.Name() { + return filepath.Join(curDir, name) + } + } + newDir := filepath.Dir(curDir) + if newDir == curDir { + return "" + } + curDir = newDir + } +} diff --git a/test/cli/testutils/json.go b/test/cli/testutils/json.go new file mode 100644 index 000000000..bc3093f13 --- /dev/null +++ b/test/cli/testutils/json.go @@ -0,0 +1,13 @@ +package testutils + +import "encoding/json" + +type JSONObj map[string]interface{} + +func ToJSONStr(m JSONObj) string { + b, err := json.Marshal(m) + if err != nil { + panic(err) + } + return string(b) +} diff --git a/test/cli/testutils/random.go b/test/cli/testutils/random.go new file mode 100644 index 000000000..00bb9de49 --- /dev/null +++ b/test/cli/testutils/random.go @@ -0,0 +1,12 @@ +package testutils + +import "crypto/rand" + +func RandomBytes(n int) []byte { + bytes := make([]byte, n) + _, err := rand.Read(bytes) + if err != nil { + panic(err) + } + return bytes +} diff --git a/test/cli/testutils/util.go b/test/cli/testutils/strings.go similarity index 59% rename from test/cli/testutils/util.go rename to test/cli/testutils/strings.go index 2c013f5b9..529948d3f 100644 --- a/test/cli/testutils/util.go +++ b/test/cli/testutils/strings.go @@ -2,31 +2,10 @@ package testutils import ( "bufio" - "encoding/json" "fmt" - "log" - "os" - "path/filepath" "strings" ) -func SplitLines(s string) []string { - var lines []string - scanner := bufio.NewScanner(strings.NewReader(s)) - for scanner.Scan() { - lines = append(lines, scanner.Text()) - } - return lines -} - -func MustOpen(name string) *os.File { - f, err := os.Open(name) - if err != nil { - log.Panicf("opening %s: %s", name, err) - } - return f -} - // StrCat takes a bunch of strings or string slices // and concats them all together into one string slice. // If an arg is not one of those types, this panics. @@ -64,34 +43,11 @@ func PreviewStr(s string) string { return s[0:previewLength] + suffix } -type JSONObj map[string]interface{} - -func ToJSONStr(m JSONObj) string { - b, err := json.Marshal(m) - if err != nil { - panic(err) - } - return string(b) -} - -// Searches for a file in a dir, then the parent dir, etc. -// If the file is not found, an empty string is returned. -func FindUp(name, dir string) string { - curDir := dir - for { - entries, err := os.ReadDir(curDir) - if err != nil { - panic(err) - } - for _, e := range entries { - if name == e.Name() { - return filepath.Join(curDir, name) - } - } - newDir := filepath.Dir(curDir) - if newDir == curDir { - return "" - } - curDir = newDir +func SplitLines(s string) []string { + var lines []string + scanner := bufio.NewScanner(strings.NewReader(s)) + for scanner.Scan() { + lines = append(lines, scanner.Text()) } + return lines } diff --git a/test/sharness/t0085-pins.sh b/test/sharness/t0085-pins.sh deleted file mode 100755 index c83c51368..000000000 --- a/test/sharness/t0085-pins.sh +++ /dev/null @@ -1,201 +0,0 @@ -#!/usr/bin/env bash -# -# Copyright (c) 2016 Jeromy Johnson -# MIT Licensed; see the LICENSE file in this repository. -# - -test_description="Test ipfs pinning operations" - -. lib/test-lib.sh - - -test_pins() { - PIN_ARGS="$1" - LS_ARGS="$2" - BASE=$3 - if [ -n "$BASE" ]; then - BASE_ARGS="--cid-base=$BASE" - fi - - test_expect_success "create some hashes $BASE" ' - HASH_A=$(echo "A" | ipfs add $BASE_ARGS -q --pin=false) && - HASH_B=$(echo "B" | ipfs add $BASE_ARGS -q --pin=false) && - HASH_C=$(echo "C" | ipfs add $BASE_ARGS -q --pin=false) && - HASH_D=$(echo "D" | ipfs add $BASE_ARGS -q --pin=false) && - HASH_E=$(echo "E" | ipfs add $BASE_ARGS -q --pin=false) && - HASH_F=$(echo "F" | ipfs add $BASE_ARGS -q --pin=false) && - HASH_G=$(echo "G" | ipfs add $BASE_ARGS -q --pin=false) - ' - - test_expect_success "put all those hashes in a file" ' - echo $HASH_A > hashes && - echo $HASH_B >> hashes && - echo $HASH_C >> hashes && - echo $HASH_D >> hashes && - echo $HASH_E >> hashes && - echo $HASH_F >> hashes && - echo $HASH_G >> hashes - ' - - if [ -n "$BASE" ]; then - test_expect_success "make sure hashes are in $BASE" ' - cat hashes | xargs cid-fmt %b | sort -u > actual - echo base32 > expected - test_cmp expected actual - ' - fi - - test_expect_success "'ipfs pin add $PIN_ARGS' via stdin" ' - cat hashes | ipfs pin add $PIN_ARGS $BASE_ARGS | tee actual - ' - - test_expect_success "'ipfs pin add $PIN_ARGS' output looks good" ' - sed -e "s/^/pinned /; s/$/ recursively/" hashes > expected && - test_cmp expected actual - ' - - test_expect_success "see if verify works" ' - ipfs pin verify - ' - - test_expect_success "see if verify --verbose $BASE_ARGS works" ' - ipfs pin verify --verbose $BASE_ARGS > verify_out && - test $(cat verify_out | wc -l) -ge 7 && - test_should_contain "$HASH_A ok" verify_out && - test_should_contain "$HASH_B ok" verify_out && - test_should_contain "$HASH_C ok" verify_out && - test_should_contain "$HASH_D ok" verify_out && - test_should_contain "$HASH_E ok" verify_out && - test_should_contain "$HASH_F ok" verify_out && - test_should_contain "$HASH_G ok" verify_out - ' - - test_expect_success "ipfs pin ls $LS_ARGS $BASE_ARGS works" ' - ipfs pin ls $LS_ARGS $BASE_ARGS > ls_out && - test_should_contain "$HASH_A" ls_out && - test_should_contain "$HASH_B" ls_out && - test_should_contain "$HASH_C" ls_out && - test_should_contain "$HASH_D" ls_out && - test_should_contain "$HASH_E" ls_out && - test_should_contain "$HASH_F" ls_out && - test_should_contain "$HASH_G" ls_out - ' - - test_expect_success "test pin ls $LS_ARGS $BASE_ARGS hash" ' - echo $HASH_B | test_must_fail grep /ipfs && # just to be sure - ipfs pin ls $LS_ARGS $BASE_ARGS $HASH_B > ls_hash_out && - echo "$HASH_B recursive" > ls_hash_exp && - test_cmp ls_hash_exp ls_hash_out - ' - - test_expect_success "unpin those hashes" ' - cat hashes | ipfs pin rm - ' - - test_expect_success "test pin update" ' - ipfs pin add "$HASH_A" && - ipfs pin ls $LS_ARGS $BASE_ARGS | tee before_update && - test_should_contain "$HASH_A" before_update && - test_must_fail grep -q "$HASH_B" before_update && - ipfs pin update --unpin=true "$HASH_A" "$HASH_B" && - ipfs pin ls $LS_ARGS $BASE_ARGS > after_update && - test_must_fail grep -q "$HASH_A" after_update && - test_should_contain "$HASH_B" after_update && - ipfs pin update --unpin=true "$HASH_B" "$HASH_B" && - ipfs pin ls $LS_ARGS $BASE_ARGS > after_idempotent_update && - test_should_contain "$HASH_B" after_idempotent_update && - ipfs pin rm "$HASH_B" - ' -} - -RANDOM_HASH=Qme8uX5n9hn15pw9p6WcVKoziyyC9LXv4LEgvsmKMULjnV - -test_pins_error_reporting() { - PIN_ARGS=$1 - - test_expect_success "'ipfs pin add $PIN_ARGS' on non-existent hash should fail" ' - test_must_fail ipfs pin add $PIN_ARGS $RANDOM_HASH 2> err && - grep -q "ipld: could not find" err - ' -} - -test_pin_dag_init() { - PIN_ARGS=$1 - - test_expect_success "'ipfs add $PIN_ARGS --pin=false' 1MB file" ' - random 1048576 56 > afile && - HASH=`ipfs add $PIN_ARGS --pin=false -q afile` - ' -} - -test_pin_dag() { - test_pin_dag_init $1 - - test_expect_success "'ipfs pin add --progress' file" ' - ipfs pin add --recursive=true $HASH - ' - - test_expect_success "'ipfs pin rm' file" ' - ipfs pin rm $HASH - ' - - test_expect_success "remove part of the dag" ' - PART=`ipfs refs $HASH | head -1` && - ipfs block rm $PART - ' - - test_expect_success "pin file, should fail" ' - test_must_fail ipfs pin add --recursive=true $HASH 2> err && - cat err && - grep -q "ipld: could not find" err - ' -} - -test_pin_progress() { - test_pin_dag_init - - test_expect_success "'ipfs pin add --progress' file" ' - ipfs pin add --progress $HASH 2> err - ' - - test_expect_success "pin progress reported correctly" ' - cat err - grep -q " 5 nodes" err - ' -} - -test_init_ipfs - -test_pins '' '' '' -test_pins --progress '' '' -test_pins --progress --stream '' -test_pins '' '' base32 -test_pins '' --stream base32 - -test_pins_error_reporting -test_pins_error_reporting --progress - -test_pin_dag -test_pin_dag --raw-leaves - -test_pin_progress - -test_launch_ipfs_daemon_without_network - -test_pins '' '' '' -test_pins --progress '' '' -test_pins --progress --stream '' -test_pins '' '' base32 -test_pins '' --stream base32 - -test_pins_error_reporting -test_pins_error_reporting --progress - -test_pin_dag -test_pin_dag --raw-leaves - -test_pin_progress - -test_kill_ipfs_daemon - -test_done From 15ed4c1c022245f845cdd3edebf0f5d2c229b0f2 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Mon, 2 Jan 2023 04:53:58 -0800 Subject: [PATCH 0365/1212] fix: update go-libp2p to v0.24.2 (#9522) https://github.com/libp2p/go-libp2p/releases/tag/v0.24.2 --- docs/examples/kubo-as-a-library/go.mod | 4 ++-- docs/examples/kubo-as-a-library/go.sum | 8 ++++---- go.mod | 4 ++-- go.sum | 8 ++++---- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 1846a1ea9..079d5c727 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -10,7 +10,7 @@ require ( github.com/ipfs/go-ipfs-files v0.2.0 github.com/ipfs/interface-go-ipfs-core v0.8.1 github.com/ipfs/kubo v0.14.0-rc1 - github.com/libp2p/go-libp2p v0.24.1 + github.com/libp2p/go-libp2p v0.24.2 github.com/multiformats/go-multiaddr v0.8.0 ) @@ -142,7 +142,7 @@ require ( github.com/marten-seemann/qtls-go1-18 v0.1.3 // indirect github.com/marten-seemann/qtls-go1-19 v0.1.1 // indirect github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect - github.com/marten-seemann/webtransport-go v0.4.2 // indirect + github.com/marten-seemann/webtransport-go v0.4.3 // indirect github.com/mattn/go-isatty v0.0.16 // indirect github.com/mattn/go-pointer v0.0.1 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index fa464c50e..e0669a13c 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -714,8 +714,8 @@ github.com/libp2p/go-libp2p v0.7.0/go.mod h1:hZJf8txWeCduQRDC/WSqBGMxaTHCOYHt2xS github.com/libp2p/go-libp2p v0.7.4/go.mod h1:oXsBlTLF1q7pxr+9w6lqzS1ILpyHsaBPniVO7zIHGMw= github.com/libp2p/go-libp2p v0.8.1/go.mod h1:QRNH9pwdbEBpx5DTJYg+qxcVaDMAz3Ee/qDKwXujH5o= github.com/libp2p/go-libp2p v0.14.3/go.mod h1:d12V4PdKbpL0T1/gsUNN8DfgMuRPDX8bS2QxCZlwRH0= -github.com/libp2p/go-libp2p v0.24.1 h1:+lS4fqj7RF9egcPq9Yo3iqdRTcDMApzoBbQMhxtwOVw= -github.com/libp2p/go-libp2p v0.24.1/go.mod h1:5LJqbrqFsUzWrq70JHCYqjATlX4ey8Klpct3OEe8hSI= +github.com/libp2p/go-libp2p v0.24.2 h1:iMViPIcLY0D6zr/f+1Yq9EavCZu2i7eDstsr1nEwSAk= +github.com/libp2p/go-libp2p v0.24.2/go.mod h1:WuxtL2V8yGjam03D93ZBC19tvOUiPpewYv1xdFGWu1k= github.com/libp2p/go-libp2p-asn-util v0.2.0 h1:rg3+Os8jbnO5DxkC7K/Utdi+DkY3q/d1/1q+8WeNAsw= github.com/libp2p/go-libp2p-asn-util v0.2.0/go.mod h1:WoaWxbHKBymSN41hWSq/lGKJEca7TNm58+gGJi2WsLI= github.com/libp2p/go-libp2p-autonat v0.1.0/go.mod h1:1tLf2yXxiE/oKGtDwPYWTSYG3PtvYlJmg7NeVtPRqH8= @@ -921,8 +921,8 @@ github.com/marten-seemann/qtls-go1-19 v0.1.1 h1:mnbxeq3oEyQxQXwI4ReCgW9DPoPR94sN github.com/marten-seemann/qtls-go1-19 v0.1.1/go.mod h1:5HTDWtVudo/WFsHKRNuOhWlbdjrfs5JHrYb0wIJqGpI= 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/marten-seemann/webtransport-go v0.4.2 h1:8ZRr9AsPuDiLQwnX2PxGs2t35GPvUaqPJnvk+c2SFSs= -github.com/marten-seemann/webtransport-go v0.4.2/go.mod h1:4xcfySgZMLP4aG5GBGj1egP7NlpfwgYJ1WJMvPPiVMU= +github.com/marten-seemann/webtransport-go v0.4.3 h1:vkt5o/Ci+luknRteWdYGYH1KcB7ziup+J+1PzZJIvmg= +github.com/marten-seemann/webtransport-go v0.4.3/go.mod h1:4xcfySgZMLP4aG5GBGj1egP7NlpfwgYJ1WJMvPPiVMU= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= diff --git a/go.mod b/go.mod index bb0dd2930..cb399de99 100644 --- a/go.mod +++ b/go.mod @@ -72,7 +72,7 @@ require ( 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.24.1 + github.com/libp2p/go-libp2p v0.24.2 github.com/libp2p/go-libp2p-http v0.4.0 github.com/libp2p/go-libp2p-kad-dht v0.20.0 github.com/libp2p/go-libp2p-kbucket v0.5.0 @@ -189,7 +189,7 @@ require ( github.com/marten-seemann/qtls-go1-18 v0.1.3 // indirect github.com/marten-seemann/qtls-go1-19 v0.1.1 // indirect github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect - github.com/marten-seemann/webtransport-go v0.4.2 // indirect + github.com/marten-seemann/webtransport-go v0.4.3 // indirect github.com/mattn/go-colorable v0.1.4 // indirect github.com/mattn/go-isatty v0.0.16 // indirect github.com/mattn/go-pointer v0.0.1 // indirect diff --git a/go.sum b/go.sum index 435c88bc2..65831c18b 100644 --- a/go.sum +++ b/go.sum @@ -745,8 +745,8 @@ github.com/libp2p/go-libp2p v0.7.0/go.mod h1:hZJf8txWeCduQRDC/WSqBGMxaTHCOYHt2xS github.com/libp2p/go-libp2p v0.7.4/go.mod h1:oXsBlTLF1q7pxr+9w6lqzS1ILpyHsaBPniVO7zIHGMw= github.com/libp2p/go-libp2p v0.8.1/go.mod h1:QRNH9pwdbEBpx5DTJYg+qxcVaDMAz3Ee/qDKwXujH5o= github.com/libp2p/go-libp2p v0.14.3/go.mod h1:d12V4PdKbpL0T1/gsUNN8DfgMuRPDX8bS2QxCZlwRH0= -github.com/libp2p/go-libp2p v0.24.1 h1:+lS4fqj7RF9egcPq9Yo3iqdRTcDMApzoBbQMhxtwOVw= -github.com/libp2p/go-libp2p v0.24.1/go.mod h1:5LJqbrqFsUzWrq70JHCYqjATlX4ey8Klpct3OEe8hSI= +github.com/libp2p/go-libp2p v0.24.2 h1:iMViPIcLY0D6zr/f+1Yq9EavCZu2i7eDstsr1nEwSAk= +github.com/libp2p/go-libp2p v0.24.2/go.mod h1:WuxtL2V8yGjam03D93ZBC19tvOUiPpewYv1xdFGWu1k= github.com/libp2p/go-libp2p-asn-util v0.2.0 h1:rg3+Os8jbnO5DxkC7K/Utdi+DkY3q/d1/1q+8WeNAsw= github.com/libp2p/go-libp2p-asn-util v0.2.0/go.mod h1:WoaWxbHKBymSN41hWSq/lGKJEca7TNm58+gGJi2WsLI= github.com/libp2p/go-libp2p-autonat v0.1.0/go.mod h1:1tLf2yXxiE/oKGtDwPYWTSYG3PtvYlJmg7NeVtPRqH8= @@ -959,8 +959,8 @@ github.com/marten-seemann/qtls-go1-19 v0.1.1 h1:mnbxeq3oEyQxQXwI4ReCgW9DPoPR94sN github.com/marten-seemann/qtls-go1-19 v0.1.1/go.mod h1:5HTDWtVudo/WFsHKRNuOhWlbdjrfs5JHrYb0wIJqGpI= 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/marten-seemann/webtransport-go v0.4.2 h1:8ZRr9AsPuDiLQwnX2PxGs2t35GPvUaqPJnvk+c2SFSs= -github.com/marten-seemann/webtransport-go v0.4.2/go.mod h1:4xcfySgZMLP4aG5GBGj1egP7NlpfwgYJ1WJMvPPiVMU= +github.com/marten-seemann/webtransport-go v0.4.3 h1:vkt5o/Ci+luknRteWdYGYH1KcB7ziup+J+1PzZJIvmg= +github.com/marten-seemann/webtransport-go v0.4.3/go.mod h1:4xcfySgZMLP4aG5GBGj1egP7NlpfwgYJ1WJMvPPiVMU= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= From 648f765afa429fd35302fd168c2a9559ae621276 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Mon, 2 Jan 2023 14:51:02 +0100 Subject: [PATCH 0366/1212] fix(test): stabilize flaky provider tests --- test/sharness/t0175-provider.sh | 2 +- test/sharness/t0240-republisher.sh | 4 ++-- test/sharness/t0600-issues-and-regressions-online.sh | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/test/sharness/t0175-provider.sh b/test/sharness/t0175-provider.sh index 364df60e9..cca110fe1 100755 --- a/test/sharness/t0175-provider.sh +++ b/test/sharness/t0175-provider.sh @@ -22,7 +22,7 @@ test_expect_success 'use strategic providing' ' startup_cluster ${NUM_NODES} test_expect_success 'add test object' ' - HASH_0=$(echo "foo" | ipfsi 0 add -q) + HASH_0=$(date +"%FT%T.%N%z" | ipfsi 0 add -q) ' findprovs_expect '$HASH_0' '$PEERID_0' diff --git a/test/sharness/t0240-republisher.sh b/test/sharness/t0240-republisher.sh index e498007a8..e52b8bee5 100755 --- a/test/sharness/t0240-republisher.sh +++ b/test/sharness/t0240-republisher.sh @@ -74,7 +74,7 @@ num_test_nodes=4 setup_iptb "$num_test_nodes" test_expect_success "publish succeeds" ' - HASH=$(echo "foobar" | ipfsi 1 add -q) && + HASH=$(date +"%FT%T.%N%z" | ipfsi 1 add -q) && ipfsi 1 name publish -t 10s $HASH ' @@ -99,7 +99,7 @@ KEY2=`ipfsi 1 key gen beepboop --type ed25519` ' test_expect_success "publish with new key succeeds" ' - HASH=$(echo "barfoo" | ipfsi 1 add -q) && + HASH=$(date +"%FT%T.%N%z" | ipfsi 1 add -q) && ipfsi 1 name publish -t 10s -k "$KEY2" $HASH ' diff --git a/test/sharness/t0600-issues-and-regressions-online.sh b/test/sharness/t0600-issues-and-regressions-online.sh index 315a9d117..3468f23d6 100755 --- a/test/sharness/t0600-issues-and-regressions-online.sh +++ b/test/sharness/t0600-issues-and-regressions-online.sh @@ -34,15 +34,15 @@ test_expect_success "metrics work" ' ' test_expect_success "pin add api looks right - #3753" ' - HASH=$(echo "foo" | ipfs add -q) && + HASH=$(date +"%FT%T.%N%z" | ipfs add -q) && curl -X POST "http://$API_ADDR/api/v0/pin/add/$HASH" > pinadd_out && - echo "{\"Pins\":[\"QmYNmQKp6SuaVrpgWRsPTgCQCnpxUYGq76YEKBXuj2N4H6\"]}" > pinadd_exp && + echo "{\"Pins\":[\"$HASH\"]}" > pinadd_exp && test_cmp pinadd_out pinadd_exp ' test_expect_success "pin add api looks right - #3753" ' curl -X POST "http://$API_ADDR/api/v0/pin/rm/$HASH" > pinrm_out && - echo "{\"Pins\":[\"QmYNmQKp6SuaVrpgWRsPTgCQCnpxUYGq76YEKBXuj2N4H6\"]}" > pinrm_exp && + echo "{\"Pins\":[\"$HASH\"]}" > pinrm_exp && test_cmp pinrm_out pinrm_exp ' From 60092924a9135583fc8e1952c7a9c593851b2aec Mon Sep 17 00:00:00 2001 From: galargh Date: Wed, 4 Jan 2023 09:04:09 +0000 Subject: [PATCH 0367/1212] chore: update version.go --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index 63839b84b..81f938646 100644 --- a/version.go +++ b/version.go @@ -11,7 +11,7 @@ import ( var CurrentCommit string // CurrentVersionNumber is the current application's version literal -const CurrentVersionNumber = "0.18.0-rc1" +const CurrentVersionNumber = "0.18.0-rc2" const ApiVersion = "/kubo/" + CurrentVersionNumber + "/" //nolint From 8cdc86d8c4328f25390e44aa7edf2a3b84215f78 Mon Sep 17 00:00:00 2001 From: Antonio Navarro Perez Date: Tue, 3 Jan 2023 21:10:33 +0100 Subject: [PATCH 0368/1212] fix: disable provide over HTTP with Routing.Type=auto (#9511) Closes https://github.com/ipfs/kubo/issues/9504 --- core/node/libp2p/routingopt.go | 20 ++++++- docs/environment-variables.md | 17 ++++++ docs/examples/kubo-as-a-library/go.mod | 4 +- docs/examples/kubo-as-a-library/go.sum | 8 +-- go.mod | 4 +- go.sum | 8 +-- routing/composer.go | 9 ++++ .../t0172-content-routing-over-http.sh | 54 +++++++++++++++++++ 8 files changed, 111 insertions(+), 13 deletions(-) create mode 100755 test/sharness/t0172-content-routing-over-http.sh diff --git a/core/node/libp2p/routingopt.go b/core/node/libp2p/routingopt.go index 2d2b7570c..bfb45971c 100644 --- a/core/node/libp2p/routingopt.go +++ b/core/node/libp2p/routingopt.go @@ -2,6 +2,8 @@ package libp2p import ( "context" + "os" + "strings" "time" "github.com/ipfs/go-datastore" @@ -30,6 +32,13 @@ var defaultHTTPRouters = []string{ // TODO: add an independent router from Cloudflare } +func init() { + // Override HTTP routers if custom ones were passed via env + if routers := os.Getenv("IPFS_HTTP_ROUTERS"); routers != "" { + defaultHTTPRouters = strings.Split(routers, " ") + } +} + // ConstructDefaultRouting returns routers used when Routing.Type is unset or set to "auto" func ConstructDefaultRouting(peerID string, addrs []string, privKey string) func( ctx context.Context, @@ -67,8 +76,17 @@ func ConstructDefaultRouting(peerID string, addrs []string, privKey string) func if err != nil { return nil, err } + + r := &irouting.Composer{ + GetValueRouter: routinghelpers.Null{}, + PutValueRouter: routinghelpers.Null{}, + ProvideRouter: routinghelpers.Null{}, // modify this when indexers supports provide + FindPeersRouter: routinghelpers.Null{}, + FindProvidersRouter: httpRouter, + } + routers = append(routers, &routinghelpers.ParallelRouter{ - Router: httpRouter, + Router: r, IgnoreError: true, // https://github.com/ipfs/kubo/pull/9475#discussion_r1042507387 Timeout: 15 * time.Second, // 5x server value from https://github.com/ipfs/kubo/pull/9475#discussion_r1042428529 ExecuteAfter: 0, diff --git a/docs/environment-variables.md b/docs/environment-variables.md index 98b449054..add8592a0 100644 --- a/docs/environment-variables.md +++ b/docs/environment-variables.md @@ -114,6 +114,23 @@ $ ipfs resolve -r /ipns/dnslink-test2.example.com /ipfs/bafkreicysg23kiwv34eg2d7qweipxwosdo2py4ldv42nbauguluen5v6am ``` +## `IPFS_HTTP_ROUTERS` + +Overrides all implicit HTTP routers enabled when `Routing.Type=auto` with +the space-separated list of URLs provided in this variable. +Useful for testing and debugging in offline contexts. + +Example: + +```console +$ ipfs config Routing.Type auto +$ IPFS_HTTP_ROUTERS="http://127.0.0.1:7423" ipfs daemon +``` + +The above will replace implicit HTTP routers with single one, allowing for +inspection/debug of HTTP requests sent by Kubo via `while true ; do nc -l 7423; done` +or more advanced tools like [mitmproxy](https://docs.mitmproxy.org/stable/#mitmproxy). + ## `LIBP2P_TCP_REUSEPORT` Kubo tries to reuse the same source port for all connections to improve NAT diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 2f61b8aa5..079d5c727 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -127,7 +127,7 @@ require ( github.com/libp2p/go-libp2p-pubsub v0.8.2 // indirect github.com/libp2p/go-libp2p-pubsub-router v0.6.0 // indirect github.com/libp2p/go-libp2p-record v0.2.0 // indirect - github.com/libp2p/go-libp2p-routing-helpers v0.4.1 // indirect + github.com/libp2p/go-libp2p-routing-helpers v0.5.0 // indirect github.com/libp2p/go-libp2p-xor v0.1.0 // indirect github.com/libp2p/go-mplex v0.7.0 // indirect github.com/libp2p/go-msgio v0.2.0 // indirect @@ -198,7 +198,7 @@ require ( go.uber.org/atomic v1.10.0 // indirect go.uber.org/dig v1.15.0 // indirect go.uber.org/fx v1.18.2 // indirect - go.uber.org/multierr v1.8.0 // indirect + go.uber.org/multierr v1.9.0 // indirect go.uber.org/zap v1.24.0 // indirect go4.org v0.0.0-20200411211856-f5505b9728dd // indirect golang.org/x/crypto v0.3.0 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 1addcac12..e0669a13c 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -793,8 +793,8 @@ github.com/libp2p/go-libp2p-quic-transport v0.10.0/go.mod h1:RfJbZ8IqXIhxBRm5hqU github.com/libp2p/go-libp2p-record v0.1.0/go.mod h1:ujNc8iuE5dlKWVy6wuL6dd58t0n7xI4hAIl8pE6wu5Q= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= github.com/libp2p/go-libp2p-record v0.2.0/go.mod h1:I+3zMkvvg5m2OcSdoL0KPljyJyvNDFGKX7QdlpYUcwk= -github.com/libp2p/go-libp2p-routing-helpers v0.4.1 h1:rOlZiFpUt7SgHm4w62MBvWaQ4UHh7bVJnSnor6RN7j8= -github.com/libp2p/go-libp2p-routing-helpers v0.4.1/go.mod h1:dYEAgkVhqho3/YKxfOEGdFMIcWfAFNlZX8iAIihYA2E= +github.com/libp2p/go-libp2p-routing-helpers v0.5.0 h1:Byujua1X9MeTzbF54i5OwjUNopeg7PYBykuNow/w3p4= +github.com/libp2p/go-libp2p-routing-helpers v0.5.0/go.mod h1:wwK/XSLt6njjO7sRbjhf8w7PGBOfdntMQ2mOQPZ5s/Q= github.com/libp2p/go-libp2p-secio v0.1.0/go.mod h1:tMJo2w7h3+wN4pgU2LSYeiKPrfqBgkOsdiKK77hE7c8= github.com/libp2p/go-libp2p-secio v0.2.0/go.mod h1:2JdZepB8J5V9mBp79BmwsaPQhRPNN2NrnB2lKQcdy6g= github.com/libp2p/go-libp2p-secio v0.2.1/go.mod h1:cWtZpILJqkqrSkiYcDBh5lA3wbT2Q+hz3rJQq3iftD8= @@ -1377,8 +1377,8 @@ go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+ go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/multierr v1.7.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= -go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8= -go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= +go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= +go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= diff --git a/go.mod b/go.mod index 39087e0fe..cb399de99 100644 --- a/go.mod +++ b/go.mod @@ -79,7 +79,7 @@ require ( github.com/libp2p/go-libp2p-pubsub v0.8.2 github.com/libp2p/go-libp2p-pubsub-router v0.6.0 github.com/libp2p/go-libp2p-record v0.2.0 - github.com/libp2p/go-libp2p-routing-helpers v0.4.0 + github.com/libp2p/go-libp2p-routing-helpers v0.5.0 github.com/libp2p/go-libp2p-testing v0.12.0 github.com/libp2p/go-socket-activation v0.1.0 github.com/miekg/dns v1.1.50 @@ -231,7 +231,7 @@ require ( go.opentelemetry.io/otel/metric v0.30.0 // indirect go.opentelemetry.io/proto/otlp v0.16.0 // indirect go.uber.org/atomic v1.10.0 // indirect - go.uber.org/multierr v1.8.0 // indirect + go.uber.org/multierr v1.9.0 // indirect go4.org v0.0.0-20200411211856-f5505b9728dd // indirect golang.org/x/exp v0.0.0-20221205204356-47842c84f3db // indirect golang.org/x/net v0.3.0 // indirect diff --git a/go.sum b/go.sum index 061801f7e..65831c18b 100644 --- a/go.sum +++ b/go.sum @@ -828,8 +828,8 @@ github.com/libp2p/go-libp2p-quic-transport v0.10.0/go.mod h1:RfJbZ8IqXIhxBRm5hqU github.com/libp2p/go-libp2p-record v0.1.0/go.mod h1:ujNc8iuE5dlKWVy6wuL6dd58t0n7xI4hAIl8pE6wu5Q= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= github.com/libp2p/go-libp2p-record v0.2.0/go.mod h1:I+3zMkvvg5m2OcSdoL0KPljyJyvNDFGKX7QdlpYUcwk= -github.com/libp2p/go-libp2p-routing-helpers v0.4.0 h1:b7y4aixQ7AwbqYfcOQ6wTw8DQvuRZeTAA0Od3YYN5yc= -github.com/libp2p/go-libp2p-routing-helpers v0.4.0/go.mod h1:dYEAgkVhqho3/YKxfOEGdFMIcWfAFNlZX8iAIihYA2E= +github.com/libp2p/go-libp2p-routing-helpers v0.5.0 h1:Byujua1X9MeTzbF54i5OwjUNopeg7PYBykuNow/w3p4= +github.com/libp2p/go-libp2p-routing-helpers v0.5.0/go.mod h1:wwK/XSLt6njjO7sRbjhf8w7PGBOfdntMQ2mOQPZ5s/Q= github.com/libp2p/go-libp2p-secio v0.1.0/go.mod h1:tMJo2w7h3+wN4pgU2LSYeiKPrfqBgkOsdiKK77hE7c8= github.com/libp2p/go-libp2p-secio v0.2.0/go.mod h1:2JdZepB8J5V9mBp79BmwsaPQhRPNN2NrnB2lKQcdy6g= github.com/libp2p/go-libp2p-secio v0.2.1/go.mod h1:cWtZpILJqkqrSkiYcDBh5lA3wbT2Q+hz3rJQq3iftD8= @@ -1441,8 +1441,8 @@ go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+ go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/multierr v1.7.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= -go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8= -go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= +go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= +go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= diff --git a/routing/composer.go b/routing/composer.go index f2f1f65e6..f54d954bd 100644 --- a/routing/composer.go +++ b/routing/composer.go @@ -100,9 +100,18 @@ func (c *Composer) GetValue(ctx context.Context, key string, opts ...routing.Opt func (c *Composer) SearchValue(ctx context.Context, key string, opts ...routing.Option) (<-chan []byte, error) { log.Debug("composer: calling searchValue: ", key) ch, err := c.GetValueRouter.SearchValue(ctx, key, opts...) + + // avoid nil channels on implementations not supporting SearchValue method. + if err == routing.ErrNotFound && ch == nil { + out := make(chan []byte) + close(out) + return out, err + } + if err != nil { log.Debug("composer: calling searchValue error: ", key, err) } + return ch, err } diff --git a/test/sharness/t0172-content-routing-over-http.sh b/test/sharness/t0172-content-routing-over-http.sh new file mode 100755 index 000000000..bc35c6328 --- /dev/null +++ b/test/sharness/t0172-content-routing-over-http.sh @@ -0,0 +1,54 @@ +#!/usr/bin/env bash + +test_description="Test content routing over HTTP" + +. lib/test-lib.sh + + +if ! test_have_prereq SOCAT; then + skip_all="skipping '$test_description': socat is not available" + test_done +fi + +test_init_ipfs + +# Run listener on a free port to log HTTP requests sent by Kubo in Routing.Type=auto mode +export ROUTER_PORT=$(comm -23 <(seq 49152 65535 | sort) <(ss -Htan | awk '{print $4}' | cut -d':' -f2) | head -n 1) +export IPFS_HTTP_ROUTERS="http://127.0.0.1:$ROUTER_PORT" + +test_launch_ipfs_daemon + +test_expect_success "start HTTP router proxy" ' + socat TCP-LISTEN:$ROUTER_PORT,reuseaddr,fork,bind=127.0.0.1 STDOUT > http_requests & + NCPID=$! +' + +## HTTP GETs + +test_expect_success 'create unique CID without adding it to the local datastore' ' + WANT_CID=$(date +"%FT%T.%N%z" | ipfs add -qn) +' + +test_expect_success 'expect HTTP request for unknown CID' ' + ipfs routing findprovs --timeout 3s "$WANT_CID" && + test_should_contain "GET /routing/v1/providers/$WANT_CID" http_requests +' + +## HTTP PUTs + +test_expect_success 'add new CID to the local datastore' ' + ADD_CID=$(date +"%FT%T.%N%z" | ipfs add -q) +' + +# cid.contact supports GET-only: https://github.com/ipfs/kubo/issues/9504 +# which means no announcements over HTTP should be made. +test_expect_success 'expect no HTTP requests to be sent with locally added CID' ' + test_should_not_contain "$ADD_CID" http_requests +' + +test_expect_success "stop nc" ' + kill "$NCPID" && wait "$NCPID" || true +' + +test_kill_ipfs_daemon +test_done From 746f14c881447b14529bdb4ffdd1ccde30d80dad Mon Sep 17 00:00:00 2001 From: Vladimir Ivanov Date: Wed, 4 Jan 2023 18:47:32 +0300 Subject: [PATCH 0369/1212] docs: clarify debug environment variables --- docs/environment-variables.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/environment-variables.md b/docs/environment-variables.md index add8592a0..ba1cce166 100644 --- a/docs/environment-variables.md +++ b/docs/environment-variables.md @@ -75,13 +75,13 @@ Warning: Enabling tracing will likely affect performance. ## `IPFS_FUSE_DEBUG` -Enables fuse debug logging. +If SET, enables fuse debug logging. Default: false ## `YAMUX_DEBUG` -Enables debug logging for the yamux stream muxer. +If SET, enables debug logging for the yamux stream muxer. Default: false From faaac6e4cd80d0b473fab86ec123d9f220c552a8 Mon Sep 17 00:00:00 2001 From: galargh Date: Wed, 4 Jan 2023 18:59:21 +0100 Subject: [PATCH 0370/1212] chore: combined improvements from v0.18.0-rc2 --- docs/RELEASE_ISSUE_TEMPLATE.md | 38 ++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/docs/RELEASE_ISSUE_TEMPLATE.md b/docs/RELEASE_ISSUE_TEMPLATE.md index ef2a22803..ad0ff060d 100644 --- a/docs/RELEASE_ISSUE_TEMPLATE.md +++ b/docs/RELEASE_ISSUE_TEMPLATE.md @@ -46,7 +46,7 @@ Checklist: - [ ] Mention @protocol/bifrost-team in the issue and let them know the expected date of the release - Issue link: - [ ] Ensure that the `What's left for release` section has all the checkboxes checked. If that's not the case, discuss the open items with Kubo maintainers and update the release schedule accordingly. - - `go run main.go kubo:issue:checkOutstandingTasks v0.18.0` + - `km kubo:issue:checkOutstandingTasks v0.18.0` - [ ] Create `docs-release-vX.Y.Z` branch, open a draft PR and keep updating `docs/RELEASE_ISSUE_TEMPLATE.md` on that branch as you go. - [ ] Link it in the "Meta" section above. - [ ] Ensure you have a [GPG key generated](https://docs.github.com/en/authentication/managing-commit-signature-verification/generating-a-new-gpg-key) and [added to your GitHub account](https://docs.github.com/en/authentication/managing-commit-signature-verification/adding-a-gpg-key-to-your-github-account). This will enable you to created signed tags. @@ -70,26 +70,26 @@ Checklist: - [ ] [ipfs/kubo](https://github.com/ipfs/kubo): [example PR](https://github.com/ipfs/kubo/pull/8599) - [ ] [ipfs/ipfs-docs](https://github.com/ipfs/ipfs-docs): [example PR](https://github.com/ipfs/ipfs-docs/pull/1298) - only if the major version changed - [ ] Fork a new branch (`release-vX.Y.Z`) from `master`. - - `go run main.go kubo:release:cutReleaseBranch v0.18.0` + - `km kubo:release:cutReleaseBranch v0.18.0` - [ ] Bump the version in `version.go` in the `master` branch to `vX.(Y+1).0-dev` via a PR ([example](https://github.com/ipfs/kubo/pull/9305)). - - `go run main.go kubo:main:updateVersion v0.18.0` + - `km kubo:main:updateVersion v0.18.0` - [ ] **Stage 2 - Release Candidate** - _if any [non-trivial](docs/releases.md#footnotes) changes need to be included in the release, return to this stage_ - [ ] If it's not a first RC, add new commits to the `release-vX.Y.Z` branch from `master` using `git cherry-pick -x ...` - Note: `release-*` branches are protected. You can do all needed updates on a separated branch (e.g. `wip-release-vX.Y.Z`) and when everything is settled push to `release-vX.Y.Z` - [ ] Bump the version in `version.go` in the `release-vX.Y.Z` branch to `vX.Y.Z-rcN`. - - `go run main.go kubo:release:updateReleaseVersion v0.18.0-rc1` + - `km kubo:release:updateReleaseVersion v0.18.0-rc1` - [ ] If it's a first RC, create a draft PR targetting `release` branch if it doesn't exist yet ([example](https://github.com/ipfs/kubo/pull/9306)). - - `go run main.go kubo:release:createReleasePR v0.18.0` + - `km kubo:release:createReleasePR v0.18.0` - [ ] Wait for CI to run and complete PR checks. All checks should pass. - - `go run main.go kubo:release:checkReleaseCI v0.18.0` + - `km kubo:release:checkCI v0.18.0` - [ ] Create a signed tag for the release candidate. - - `go run main.go kubo:release:createReleaseTag v0.18.0-rc1` + - `km kubo:release:createReleaseTag v0.18.0-rc1` - This is a dangerous operation, as it is difficult to reverse due to Go modules and automated Docker image publishing. Remember to verify the commands you intend to run for items marked with ⚠️ with the release reviewer. - [ ] ⚠️ Tag HEAD `release-vX.Y.Z` commit with `vX.Y.Z-rcN` (`git tag -s vX.Y.Z-rcN -m 'Pre-release X.Y.Z-rcn'`) - [ ] Run `git show vX.Y.Z-rcN` to ensure the tag is correct. - [ ] ⚠️ Push the `vX.Y.Z-rcN` tag to GitHub (`git push origin vX.Y.Z-rcN`; DO NOT USE `git push --tags` because it pushes all your local tags). - [ ] Add artifacts to https://dist.ipfs.tech by making a PR against [ipfs/distributions](https://github.com/ipfs/distributions) - - `go run main.go dist:dist:createDistPR v0.18.0-rc1` + - `km dist:dist:createDistPR v0.18.0-rc1` - [ ] Clone the `ipfs/distributions` repo locally. - [ ] Create a new branch (`kubo-release-vX.Y.Z-rcn`) from `master`. - [ ] Run `./dist.sh add-version kubo vX.Y.Z-rcN` to add the new version to the `versions` file ([instructions](https://github.com/ipfs/distributions#usage)). @@ -101,24 +101,25 @@ Checklist: - PR will be merged automatically once the diff is approved - `master` build will publish the artifacts to https://dist.ipfs.io in around 30 minutes - [ ] Ensure that the artifacts are available at https://dist.ipfs.io - - `go run main.go dist:dist:checkIPFSTech v0.18.0-rc1` + - `km dist:dist:checkIPFSTech v0.18.0-rc1` - [ ] Publish the RC to [the NPM package](https://www.npmjs.com/package/go-ipfs?activeTab=versions) by running https://github.com/ipfs/npm-go-ipfs/actions/workflows/main.yml (it happens automatically but it is safe to speed up the process and kick of a run manually) - - `go run main.go npm:npm:publishToNPM v0.18.0-rc1` - - `go run main.go npm:npm:checkNPM v0.18.0-rc1` + - `km npm:npm:publishToNPM v0.18.0-rc1` + - `km npm:npm:checkNPM v0.18.0-rc1` - [ ] Cut a pre-release on [GitHub](https://github.com/ipfs/kubo/releases) ([instructions](https://docs.github.com/en/repositories/releasing-projects-on-github/managing-releases-in-a-repository#creating-a-release), [example](https://github.com/ipfs/kubo/releases/tag/v0.17.0-rc1)) - - `go run main.go kubo:createGitHubRelease v0.18.0-rc1` + - `km kubo:createGitHubRelease v0.18.0-rc1` - Use `vX.Y.Z-rcN` as the tag. - Link to the release issue in the description. - Link to the relevant [changelog](https://github.com/ipfs/kubo/blob/master/docs/changelogs/) in the description. - Check `This is a pre-release`. - [ ] Synchronize release artifacts by running [sync-release-assets](https://github.com/ipfs/kubo/actions/workflows/sync-release-assets.yml) workflow. - - `go run main.go kubo:syncGitHubRelease v0.18.0-rc1` + - `km kubo:syncGitHubRelease v0.18.0-rc1` - [ ] Announce the RC - [ ] Create a new post on [IPFS Discourse](https://discuss.ipfs.tech). ([example](https://discuss.ipfs.tech/t/kubo-v0-16-0-rc1-release-candidate-is-out/15248)) - Use `Kubo vX.Y.Z-rcn Release Candidate is out!` as the title. + - `km discourse:post:getTitle v0.18.0-rc1` - Use `kubo` and `go-ipfs` as topics. - - Repeat the title as a heading (`##`) in the description. - - Link to the GitHub Release, binaries on IPNS, docker pull command and release notes in the description. + - Repeat the title as a heading (`##`) in the description. Link to the GitHub Release, binaries on IPNS, docker pull command and release notes in the description. + - `km discourse:post:getBody v0.18.0-rc1` - [ ] Pin the topic globally so that it stays at the top of the category. - [ ] If there is no more important banner currently set on Discourse (e.g. IPFS Camp announcement), make the topic into a banner. - [ ] Check if Discourse post was automatically copied to: @@ -127,8 +128,9 @@ Checklist: - [ ] Matrix https://matrix.to/#/#ipfs-chatter:ipfs.io - [ ] Mention [early testers](https://github.com/ipfs/go-ipfs/tree/master/docs/EARLY_TESTERS.md) in the comment under the release issue ([example](https://github.com/ipfs/kubo/issues/9319#issuecomment-1311002478)). - [ ] **Stage 3 - Internal Testing** - - [ ] Infrastructure Testing. + - [ ] Infrastructure Testing (see [Kubo Gateway Release Notes](https://www.notion.so/pl-strflt/Kubo-Gateway-Release-Notes-6e0efff28ee540be9ccb8f2b85104c42) by bifrost team if you want to learn more about the process). - [ ] Update the issue against [bifrost-infra](https://github.com/protocol/bifrost-infra) ([example](https://github.com/protocol/bifrost-infra/issues/2109)). + - `km bifrost:issue:createIssueComment v0.18.0-rc1` - [ ] Mention @protocol/bifrost-team in the issue to let them know the release is ready - [ ] [Optional] Reply under a message about the issue in the #bifrost channel on FIL Slack once the RC is out. Send the message to the channel. - [ ] Check [metrics](https://protocollabs.grafana.net/d/8zlhkKTZk/gateway-slis-precomputed?orgId=1) every day. @@ -136,12 +138,16 @@ Checklist: - If there is an unexpected variation in the trend, message the #bifrost channel on FIL Slack and ask for help investigation the cause. - [ ] IPFS Application Testing. - [ ] [IPFS Desktop](https://github.com/ipfs-shipyard/ipfs-desktop) + - `km desktop:main:createOrUpdateUpgradePR v0.18.0-rc1` + - `km desktop:main:checkCI v0.18.0-rc1` - [ ] Upgrade to the RC in [ipfs-desktop](https://github.com/ipfs-shipyard/ipfs-desktop) - [ ] Run `npm install` to update `package-lock.json`. - [ ] Push to a branch ([example](https://github.com/ipfs/ipfs-desktop/pull/1826/commits/b0a23db31ce942b46d95965ee6fe770fb24d6bde)) - [ ] Open a draft PR to track through the final release ([example](https://github.com/ipfs/ipfs-desktop/pull/1826)) - [ ] Ensure CI tests pass - [ ] [IPFS Companion](https://github.com/ipfs-shipyard/ipfs-companion) + - `km companion:test:initTest v0.18.0-rc2` + - `km companion:test:checkTest v0.18.0-rc2` - [ ] Start kubo daemon of the version to release. - [ ] Start a fresh chromium or chrome instance using `chromium --user-data-dir=$(mktemp -d)` (macos `/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --user-data-dir=$(mktemp -d)`) - [ ] Start a fresh firefox instance using `firefox --profile $(mktemp -d)` (macos `/Applications/Firefox.app/Contents/MacOS/firefox --profile $(mktemp -d)`) From d386c431171f1d919bcbe58d548b8b789da87105 Mon Sep 17 00:00:00 2001 From: Antonio Navarro Perez Date: Wed, 4 Jan 2023 20:44:37 +0100 Subject: [PATCH 0371/1212] docs(config): ProviderSearchDelay (#9526) Signed-off-by: Antonio Navarro Perez Co-authored-by: Marcin Rataj --- docs/config.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/docs/config.md b/docs/config.md index 87f2cf1dc..aae2017d0 100644 --- a/docs/config.md +++ b/docs/config.md @@ -71,6 +71,7 @@ config file at runtime. - [`Internal.Bitswap.EngineBlockstoreWorkerCount`](#internalbitswapengineblockstoreworkercount) - [`Internal.Bitswap.EngineTaskWorkerCount`](#internalbitswapenginetaskworkercount) - [`Internal.Bitswap.MaxOutstandingBytesPerPeer`](#internalbitswapmaxoutstandingbytesperpeer) + - [`Internal.Bitswap.ProviderSearchDelay`](#internalbitswapprovidersearchdelay) - [`Internal.UnixFSShardingSizeThreshold`](#internalunixfsshardingsizethreshold) - [`Ipns`](#ipns) - [`Ipns.RepublishPeriod`](#ipnsrepublishperiod) @@ -153,7 +154,6 @@ config file at runtime. - [`Swarm.Transports.Network.QUIC`](#swarmtransportsnetworkquic) - [`Swarm.Transports.Network.Relay`](#swarmtransportsnetworkrelay) - [`Swarm.Transports.Network.WebTransport`](#swarmtransportsnetworkwebtransport) - - [How to enable WebTransport](#how-to-enable-webtransport) - [`Swarm.Transports.Security`](#swarmtransportssecurity) - [`Swarm.Transports.Security.TLS`](#swarmtransportssecuritytls) - [`Swarm.Transports.Security.SECIO`](#swarmtransportssecuritysecio) @@ -970,6 +970,14 @@ deteriorate the quality provided to less aggressively-wanting peers. Type: `optionalInteger` (byte count, `null` means default which is 1MB) +### `Internal.Bitswap.ProviderSearchDelay` + +This parameter determines how long to wait before looking for providers outside of bitswap. +Other routing systems like the DHT are able to provide results in less than a second, so lowering +this number will allow faster peers lookups in some cases. + +Type: `optionalDuration` (`null` means default which is 1s) + ### `Internal.UnixFSShardingSizeThreshold` The sharding threshold used internally to decide whether a UnixFS directory should be sharded or not. From 13155e56cd61f7f3e8dcb265b896826b4106c670 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Thu, 5 Jan 2023 00:08:05 +0100 Subject: [PATCH 0372/1212] fix(ci): flaky sharness test --- test/sharness/t0172-content-routing-over-http.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/sharness/t0172-content-routing-over-http.sh b/test/sharness/t0172-content-routing-over-http.sh index bc35c6328..d7028071f 100755 --- a/test/sharness/t0172-content-routing-over-http.sh +++ b/test/sharness/t0172-content-routing-over-http.sh @@ -21,6 +21,7 @@ test_launch_ipfs_daemon test_expect_success "start HTTP router proxy" ' socat TCP-LISTEN:$ROUTER_PORT,reuseaddr,fork,bind=127.0.0.1 STDOUT > http_requests & NCPID=$! + test_wait_for_file 50 100ms http_requests ' ## HTTP GETs @@ -30,7 +31,8 @@ test_expect_success 'create unique CID without adding it to the local datastore' ' test_expect_success 'expect HTTP request for unknown CID' ' - ipfs routing findprovs --timeout 3s "$WANT_CID" && + ipfs block stat "$WANT_CID" & + test_wait_output_n_lines_60_sec http_requests 3 && test_should_contain "GET /routing/v1/providers/$WANT_CID" http_requests ' From ca0396ea1c2d7c87057ae95514a64d3e76440931 Mon Sep 17 00:00:00 2001 From: Antonio Navarro Perez Date: Thu, 5 Jan 2023 13:30:24 +0100 Subject: [PATCH 0373/1212] docs: fix Router config Godoc (#9528) Co-authored-by: Marcin Rataj --- config/routing.go | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/config/routing.go b/config/routing.go index 983e8606d..f19414ff3 100644 --- a/config/routing.go +++ b/config/routing.go @@ -22,10 +22,7 @@ type Routing struct { type Router struct { - // Currenly supported Types are "reframe", "dht", "parallel", "sequential". - // Reframe type allows to add other resolvers using the Reframe spec: - // https://github.com/ipfs/specs/tree/main/reframe - // In the future we will support "dht" and other Types here. + // Router type ID. See RouterType for more info. Type RouterType // Parameters are extra configuration that this router might need. @@ -107,11 +104,11 @@ func (r *RouterParser) UnmarshalJSON(b []byte) error { type RouterType string const ( - RouterTypeReframe RouterType = "reframe" - RouterTypeHTTP RouterType = "http" - RouterTypeDHT RouterType = "dht" - RouterTypeSequential RouterType = "sequential" - RouterTypeParallel RouterType = "parallel" + RouterTypeReframe RouterType = "reframe" // More info here: https://github.com/ipfs/specs/tree/main/reframe . Actually deprecated. + RouterTypeHTTP RouterType = "http" // HTTP JSON API for delegated routing systems (IPIP-337). + RouterTypeDHT RouterType = "dht" // DHT router. + RouterTypeSequential RouterType = "sequential" // Router helper to execute several routers sequentially. + RouterTypeParallel RouterType = "parallel" // Router helper to execute several routers in parallel. ) type DHTMode string From 73e6ade109e735415e98bc7f1296d8cb12ac47dc Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Thu, 8 Dec 2022 21:12:34 +0100 Subject: [PATCH 0374/1212] fix(test): retry flaky t0125-twonode.sh This makes is clear why test failed, and what were values. Fixes flaky test: It will re-run flaky advanced test until bitswap stats match expected value (something team has been doing anyway for the past year). It also adds /quic-v1 and /webtransport tests --- test/sharness/t0125-twonode.sh | 84 +++++++++++++------ .../t0172-content-routing-over-http.sh | 2 +- 2 files changed, 61 insertions(+), 25 deletions(-) diff --git a/test/sharness/t0125-twonode.sh b/test/sharness/t0125-twonode.sh index 6f819400a..dcf5c88ce 100755 --- a/test/sharness/t0125-twonode.sh +++ b/test/sharness/t0125-twonode.sh @@ -52,7 +52,7 @@ run_random_dir_test() { check_dir_fetch 1 $DIR_HASH } -run_advanced_test() { +flaky_advanced_test() { startup_cluster 2 "$@" test_expect_success "clean repo before test" ' @@ -64,20 +64,9 @@ run_advanced_test() { run_random_dir_test - test_expect_success "node0 data transferred looks correct" ' - ipfsi 0 bitswap stat > stat0 && - grep "blocks sent: 126" stat0 > /dev/null && - grep "blocks received: 5" stat0 > /dev/null && - grep "data sent: 228113" stat0 > /dev/null && - grep "data received: 1000256" stat0 > /dev/null - ' - - test_expect_success "node1 data transferred looks correct" ' - ipfsi 1 bitswap stat > stat1 && - grep "blocks received: 126" stat1 > /dev/null && - grep "blocks sent: 5" stat1 > /dev/null && - grep "data received: 228113" stat1 > /dev/null && - grep "data sent: 1000256" stat1 > /dev/null + test_expect_success "gather bitswap stats" ' + ipfsi 0 bitswap stat -v > stat0 && + ipfsi 1 bitswap stat -v > stat1 ' test_expect_success "shut down nodes" ' @@ -85,27 +74,62 @@ run_advanced_test() { ' } +run_advanced_test() { + # TODO: investigate why flaky_advanced_test is flaky + # Context: https://github.com/ipfs/kubo/pull/9486 + # sometimes, bitswap status returns unexpected block transfers + # and everyone has been re-running circleci until is passes for at least a year. + # this re-runs test until it passes or a timeout hits + + BLOCKS_0=126 + BLOCKS_1=5 + DATA_0=228113 + DATA_1=1000256 + for i in $(test_seq 1 600); do + flaky_advanced_test + (grep -q "$DATA_0" stat0 && grep -q "$DATA_1" stat1) && break + go-sleep 100ms + done + + test_expect_success "node0 data transferred looks correct" ' + test_should_contain "blocks sent: $BLOCKS_0" stat0 && + test_should_contain "blocks received: $BLOCKS_1" stat0 && + test_should_contain "data sent: $DATA_0" stat0 && + test_should_contain "data received: $DATA_1" stat0 + ' + + test_expect_success "node1 data transferred looks correct" ' + test_should_contain "blocks received: $BLOCKS_0" stat1 && + test_should_contain "blocks sent: $BLOCKS_1" stat1 && + test_should_contain "data received: $DATA_0" stat1 && + test_should_contain "data sent: $DATA_1" stat1 + ' + +} + test_expect_success "set up tcp testbed" ' iptb testbed create -type localipfs -count 2 -force -init ' -addrs='"[\"/ip4/127.0.0.1/tcp/0\", \"/ip4/127.0.0.1/udp/0/quic\"]"' -test_expect_success "configure addresses" ' - ipfsi 0 config --json Addresses.Swarm '"${addrs}"' && - ipfsi 1 config --json Addresses.Swarm '"${addrs}"' +test_expect_success "disable routing, use direct peering" ' + iptb run -- ipfs config Routing.Type none && + iptb run -- ipfs config --json Bootstrap "[]" ' # Test TCP transport echo "Testing TCP" +addrs='"[\"/ip4/127.0.0.1/tcp/0\"]"' test_expect_success "use TCP only" ' + iptb run -- ipfs config --json Addresses.Swarm '"${addrs}"' && iptb run -- ipfs config --json Swarm.Transports.Network.QUIC false && iptb run -- ipfs config --json Swarm.Transports.Network.Relay false && + iptb run -- ipfs config --json Swarm.Transports.Network.WebTransport false && iptb run -- ipfs config --json Swarm.Transports.Network.Websocket false ' run_advanced_test # test multiplex muxer -echo "Running advanced tests with mplex" +echo "Running TCP tests with mplex" test_expect_success "disable yamux" ' iptb run -- ipfs config --json Swarm.Transports.Multiplexers.Yamux false ' @@ -114,23 +138,35 @@ run_advanced_test test_expect_success "re-enable yamux" ' iptb run -- ipfs config --json Swarm.Transports.Multiplexers.Yamux null ' - # test Noise - -echo "Running advanced tests with NOISE" +echo "Running TCP tests with NOISE" test_expect_success "use noise only" ' iptb run -- ipfs config --json Swarm.Transports.Security.TLS false ' - run_advanced_test +test_expect_success "re-enable TLS" ' + iptb run -- ipfs config --json Swarm.Transports.Security.TLS null +' + # test QUIC echo "Running advanced tests over QUIC" +addrs='"[\"/ip4/127.0.0.1/udp/0/quic-v1\"]"' test_expect_success "use QUIC only" ' + iptb run -- ipfs config --json Addresses.Swarm '"${addrs}"' && iptb run -- ipfs config --json Swarm.Transports.Network.QUIC true && iptb run -- ipfs config --json Swarm.Transports.Network.TCP false ' +run_advanced_test +# test WebTransport +echo "Running advanced tests over WebTransport" +addrs='"[\"/ip4/127.0.0.1/udp/0/quic-v1/webtransport\"]"' +test_expect_success "use WebTransport only" ' + iptb run -- ipfs config --json Addresses.Swarm '"${addrs}"' && + iptb run -- ipfs config --json Swarm.Transports.Network.QUIC true && + iptb run -- ipfs config --json Swarm.Transports.Network.WebTransport true +' run_advanced_test test_done diff --git a/test/sharness/t0172-content-routing-over-http.sh b/test/sharness/t0172-content-routing-over-http.sh index d7028071f..b173ca053 100755 --- a/test/sharness/t0172-content-routing-over-http.sh +++ b/test/sharness/t0172-content-routing-over-http.sh @@ -19,7 +19,7 @@ export IPFS_HTTP_ROUTERS="http://127.0.0.1:$ROUTER_PORT" test_launch_ipfs_daemon test_expect_success "start HTTP router proxy" ' - socat TCP-LISTEN:$ROUTER_PORT,reuseaddr,fork,bind=127.0.0.1 STDOUT > http_requests & + socat TCP-LISTEN:$ROUTER_PORT,reuseaddr,fork,bind=127.0.0.1,retry=10 STDOUT > http_requests & NCPID=$! test_wait_for_file 50 100ms http_requests ' From f6825ab662c8ec097fd7bfd8ad0c5193960f5c7b Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Wed, 11 Jan 2023 03:40:58 +0100 Subject: [PATCH 0375/1212] fix(gateway): JSON when Accept is a list Block/CAR responses always had single explicit type, and we did not bother with implementing/testing lists. With the introduction of JSON people may start passing a list. This is the most basic fix which will return on the first matching type (in order). This does not implements weights (can be added in future, if needed). Closes #9520 --- core/corehttp/gateway_handler.go | 26 ++++++++++++++---------- test/sharness/t0123-gateway-json-cbor.sh | 5 +++++ 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/core/corehttp/gateway_handler.go b/core/corehttp/gateway_handler.go index 1222b17bc..64c388df4 100644 --- a/core/corehttp/gateway_handler.go +++ b/core/corehttp/gateway_handler.go @@ -890,18 +890,22 @@ func customResponseFormat(r *http.Request) (mediaType string, params map[string] } // Browsers and other user agents will send Accept header with generic types like: // Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8 - // We only care about explicit, vendor-specific content-types. - for _, accept := range r.Header.Values("Accept") { - // respond to the very first ipld content type - if strings.HasPrefix(accept, "application/vnd.ipld") || - strings.HasPrefix(accept, "application/x-tar") || - strings.HasPrefix(accept, "application/json") || - strings.HasPrefix(accept, "application/cbor") { - mediatype, params, err := mime.ParseMediaType(accept) - if err != nil { - return "", nil, err + // We only care about explicit, vendor-specific content-types and respond to the first match (in order). + // TODO: make this RFC compliant and respect weights (eg. return CAR for Accept:application/vnd.ipld.dag-json;q=0.1,application/vnd.ipld.car;q=0.2) + for _, header := range r.Header.Values("Accept") { + for _, value := range strings.Split(header, ",") { + accept := strings.TrimSpace(value) + // respond to the very first matching content type + if strings.HasPrefix(accept, "application/vnd.ipld") || + strings.HasPrefix(accept, "application/x-tar") || + strings.HasPrefix(accept, "application/json") || + strings.HasPrefix(accept, "application/cbor") { + mediatype, params, err := mime.ParseMediaType(accept) + if err != nil { + return "", nil, err + } + return mediatype, params, nil } - return mediatype, params, nil } } return "", nil, nil diff --git a/test/sharness/t0123-gateway-json-cbor.sh b/test/sharness/t0123-gateway-json-cbor.sh index 812d90f24..f4ebca19d 100755 --- a/test/sharness/t0123-gateway-json-cbor.sh +++ b/test/sharness/t0123-gateway-json-cbor.sh @@ -56,6 +56,11 @@ test_dag_pb_headers () { test_should_contain "Content-Type: application/$format" curl_output && test_should_not_contain "Content-Type: application/vnd.ipld.dag-$format" curl_output ' + + test_expect_success "GET UnixFS as $name with 'Accept: foo, application/$format,bar' has expected Content-Type" ' + curl -sD - -H "Accept: foo, application/$format,text/plain" "http://127.0.0.1:$GWAY_PORT/ipfs/$FILE_CID" > curl_output 2>&1 && + test_should_contain "Content-Type: application/$format" curl_output + ' } test_dag_pb_headers "DAG-JSON" "json" "inline" From f54b2bcf6061219f7f481e8660e6707ae3bc3c38 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Wed, 14 Dec 2022 18:56:13 +0100 Subject: [PATCH 0376/1212] fix: hint people to changing from RSA peer ids --- cmd/ipfs/daemon.go | 17 +++++++++++++++++ docs/changelogs/v0.18.md | 2 +- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/cmd/ipfs/daemon.go b/cmd/ipfs/daemon.go index af105589d..12b3f4d9c 100644 --- a/cmd/ipfs/daemon.go +++ b/cmd/ipfs/daemon.go @@ -30,6 +30,7 @@ import ( fsrepo "github.com/ipfs/kubo/repo/fsrepo" "github.com/ipfs/kubo/repo/fsrepo/migrations" "github.com/ipfs/kubo/repo/fsrepo/migrations/ipfsfetcher" + p2pcrypto "github.com/libp2p/go-libp2p/core/crypto" pnet "github.com/libp2p/go-libp2p/core/pnet" sockets "github.com/libp2p/go-socket-activation" @@ -459,6 +460,22 @@ func daemonFunc(req *cmds.Request, re cmds.ResponseEmitter, env cmds.Environment printSwarmAddrs(node) + if node.PrivateKey.Type() == p2pcrypto.RSA { + fmt.Print(` +Warning: You are using an RSA Peer ID, which was replaced by Ed25519 +as the default recommended in Kubo since September 2020. Signing with +RSA Peer IDs is more CPU-intensive than with other key types. +It is recommended that you change your public key type to ed25519 +by using the following command: + + ipfs key rotate -o rsa-key-backup -t ed25519 + +After changing your key type, restart your node for the changes to +take effect. + +`) + } + defer func() { // We wait for the node to close first, as the node has children // that it will wait for before closing, such as the API server. diff --git a/docs/changelogs/v0.18.md b/docs/changelogs/v0.18.md index 58077e214..e99cd5c94 100644 --- a/docs/changelogs/v0.18.md +++ b/docs/changelogs/v0.18.md @@ -159,7 +159,7 @@ To support QUICv1 and WebTransport by default a new config migration (`v13`) is To help protect nodes from DoS (resource exhaustion) and eclipse attacks, Kubo enabled the [go-libp2p Network Resource Manager](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager) by default in [Kubo 0.17](https://github.com/ipfs/kubo/blob/master/docs/changelogs/v0.17.md#libp2p-resource-management-enabled-by-default). - + Introducing limits like this by default after the fact is tricky, and various improvements have been made to improve the UX including: 1. [Dedicated docs concerning the resource manager integration](https://github.com/ipfs/kubo/blob/master/docs/libp2p-resource-management.md). This is a great place to go to learn more or get your FAQs answered. From 587075204dfbd96441b4d787646b87a878ad30c9 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Thu, 12 Jan 2023 11:45:13 +0100 Subject: [PATCH 0377/1212] chore: migrate files (#97) This commit was moved from ipfs/interface-go-ipfs-core@f7b346b76c5724489877c511754f0f11923d3214 This commit was moved from ipfs/boxo@01de18ff3f4ccd639e02226048fda8a8f140941c --- core/coreiface/tests/name.go | 2 +- core/coreiface/tests/unixfs.go | 2 +- core/coreiface/unixfs.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/core/coreiface/tests/name.go b/core/coreiface/tests/name.go index 2a8b4d76a..2e648baba 100644 --- a/core/coreiface/tests/name.go +++ b/core/coreiface/tests/name.go @@ -10,7 +10,7 @@ import ( path "github.com/ipfs/interface-go-ipfs-core/path" - files "github.com/ipfs/go-ipfs-files" + "github.com/ipfs/go-libipfs/files" coreiface "github.com/ipfs/interface-go-ipfs-core" opt "github.com/ipfs/interface-go-ipfs-core/options" diff --git a/core/coreiface/tests/unixfs.go b/core/coreiface/tests/unixfs.go index 05226dbbf..121d3db69 100644 --- a/core/coreiface/tests/unixfs.go +++ b/core/coreiface/tests/unixfs.go @@ -20,9 +20,9 @@ import ( "github.com/ipfs/interface-go-ipfs-core/options" "github.com/ipfs/go-cid" - files "github.com/ipfs/go-ipfs-files" cbor "github.com/ipfs/go-ipld-cbor" ipld "github.com/ipfs/go-ipld-format" + "github.com/ipfs/go-libipfs/files" mdag "github.com/ipfs/go-merkledag" "github.com/ipfs/go-unixfs" "github.com/ipfs/go-unixfs/importer/helpers" diff --git a/core/coreiface/unixfs.go b/core/coreiface/unixfs.go index c398b6722..3b21a8e23 100644 --- a/core/coreiface/unixfs.go +++ b/core/coreiface/unixfs.go @@ -7,7 +7,7 @@ import ( path "github.com/ipfs/interface-go-ipfs-core/path" "github.com/ipfs/go-cid" - files "github.com/ipfs/go-ipfs-files" + "github.com/ipfs/go-libipfs/files" ) type AddEvent struct { From 3bc9b675a03622273f8b33ee5856a164df871371 Mon Sep 17 00:00:00 2001 From: Antonio Navarro Perez Date: Fri, 13 Jan 2023 00:38:38 +0100 Subject: [PATCH 0378/1212] fix: stats dht command when Routing.Type=auto (#9538) Fixes default auto mode, but Routing.Type=custom needs more work. Continued in https://github.com/ipfs/kubo/issues/9482 --- core/node/libp2p/routing.go | 28 +++++++++++++++++++------- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- test/cli/stats_test.go | 24 ++++++++++++++++++++++ 6 files changed, 51 insertions(+), 13 deletions(-) create mode 100644 test/cli/stats_test.go diff --git a/core/node/libp2p/routing.go b/core/node/libp2p/routing.go index 21afe292d..f16fec5a1 100644 --- a/core/node/libp2p/routing.go +++ b/core/node/libp2p/routing.go @@ -7,13 +7,9 @@ import ( "sort" "time" - "github.com/ipfs/kubo/core/node/helpers" - irouting "github.com/ipfs/kubo/routing" - + "github.com/cenkalti/backoff/v4" ds "github.com/ipfs/go-datastore" offroute "github.com/ipfs/go-ipfs-routing/offline" - config "github.com/ipfs/kubo/config" - "github.com/ipfs/kubo/repo" dht "github.com/libp2p/go-libp2p-kad-dht" ddht "github.com/libp2p/go-libp2p-kad-dht/dual" "github.com/libp2p/go-libp2p-kad-dht/fullrt" @@ -24,9 +20,12 @@ import ( "github.com/libp2p/go-libp2p/core/host" "github.com/libp2p/go-libp2p/core/peer" "github.com/libp2p/go-libp2p/core/routing" - - "github.com/cenkalti/backoff/v4" "go.uber.org/fx" + + config "github.com/ipfs/kubo/config" + "github.com/ipfs/kubo/core/node/helpers" + "github.com/ipfs/kubo/repo" + irouting "github.com/ipfs/kubo/routing" ) type Router struct { @@ -77,6 +76,21 @@ func BaseRouting(experimentalDHTClient bool) interface{} { }) } + if pr, ok := in.Router.(routinghelpers.ComposableRouter); ok { + for _, r := range pr.Routers() { + if dht, ok := r.(*ddht.DHT); ok { + dr = dht + lc.Append(fx.Hook{ + OnStop: func(ctx context.Context) error { + return dr.Close() + }, + }) + + break + } + } + } + if dr != nil && experimentalDHTClient { cfg, err := in.Repo.Config() if err != nil { diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 079d5c727..7285936d6 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -127,7 +127,7 @@ require ( github.com/libp2p/go-libp2p-pubsub v0.8.2 // indirect github.com/libp2p/go-libp2p-pubsub-router v0.6.0 // indirect github.com/libp2p/go-libp2p-record v0.2.0 // indirect - github.com/libp2p/go-libp2p-routing-helpers v0.5.0 // indirect + github.com/libp2p/go-libp2p-routing-helpers v0.6.0 // indirect github.com/libp2p/go-libp2p-xor v0.1.0 // indirect github.com/libp2p/go-mplex v0.7.0 // indirect github.com/libp2p/go-msgio v0.2.0 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index e0669a13c..45176636f 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -793,8 +793,8 @@ github.com/libp2p/go-libp2p-quic-transport v0.10.0/go.mod h1:RfJbZ8IqXIhxBRm5hqU github.com/libp2p/go-libp2p-record v0.1.0/go.mod h1:ujNc8iuE5dlKWVy6wuL6dd58t0n7xI4hAIl8pE6wu5Q= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= github.com/libp2p/go-libp2p-record v0.2.0/go.mod h1:I+3zMkvvg5m2OcSdoL0KPljyJyvNDFGKX7QdlpYUcwk= -github.com/libp2p/go-libp2p-routing-helpers v0.5.0 h1:Byujua1X9MeTzbF54i5OwjUNopeg7PYBykuNow/w3p4= -github.com/libp2p/go-libp2p-routing-helpers v0.5.0/go.mod h1:wwK/XSLt6njjO7sRbjhf8w7PGBOfdntMQ2mOQPZ5s/Q= +github.com/libp2p/go-libp2p-routing-helpers v0.6.0 h1:Rfyd+wp/cU0PjNjCphGzLYzd7Q51fjOMs5Sjj6zWGT0= +github.com/libp2p/go-libp2p-routing-helpers v0.6.0/go.mod h1:wwK/XSLt6njjO7sRbjhf8w7PGBOfdntMQ2mOQPZ5s/Q= github.com/libp2p/go-libp2p-secio v0.1.0/go.mod h1:tMJo2w7h3+wN4pgU2LSYeiKPrfqBgkOsdiKK77hE7c8= github.com/libp2p/go-libp2p-secio v0.2.0/go.mod h1:2JdZepB8J5V9mBp79BmwsaPQhRPNN2NrnB2lKQcdy6g= github.com/libp2p/go-libp2p-secio v0.2.1/go.mod h1:cWtZpILJqkqrSkiYcDBh5lA3wbT2Q+hz3rJQq3iftD8= diff --git a/go.mod b/go.mod index cb399de99..55e770587 100644 --- a/go.mod +++ b/go.mod @@ -79,7 +79,7 @@ require ( github.com/libp2p/go-libp2p-pubsub v0.8.2 github.com/libp2p/go-libp2p-pubsub-router v0.6.0 github.com/libp2p/go-libp2p-record v0.2.0 - github.com/libp2p/go-libp2p-routing-helpers v0.5.0 + github.com/libp2p/go-libp2p-routing-helpers v0.6.0 github.com/libp2p/go-libp2p-testing v0.12.0 github.com/libp2p/go-socket-activation v0.1.0 github.com/miekg/dns v1.1.50 diff --git a/go.sum b/go.sum index 65831c18b..6f75ebb82 100644 --- a/go.sum +++ b/go.sum @@ -828,8 +828,8 @@ github.com/libp2p/go-libp2p-quic-transport v0.10.0/go.mod h1:RfJbZ8IqXIhxBRm5hqU github.com/libp2p/go-libp2p-record v0.1.0/go.mod h1:ujNc8iuE5dlKWVy6wuL6dd58t0n7xI4hAIl8pE6wu5Q= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= github.com/libp2p/go-libp2p-record v0.2.0/go.mod h1:I+3zMkvvg5m2OcSdoL0KPljyJyvNDFGKX7QdlpYUcwk= -github.com/libp2p/go-libp2p-routing-helpers v0.5.0 h1:Byujua1X9MeTzbF54i5OwjUNopeg7PYBykuNow/w3p4= -github.com/libp2p/go-libp2p-routing-helpers v0.5.0/go.mod h1:wwK/XSLt6njjO7sRbjhf8w7PGBOfdntMQ2mOQPZ5s/Q= +github.com/libp2p/go-libp2p-routing-helpers v0.6.0 h1:Rfyd+wp/cU0PjNjCphGzLYzd7Q51fjOMs5Sjj6zWGT0= +github.com/libp2p/go-libp2p-routing-helpers v0.6.0/go.mod h1:wwK/XSLt6njjO7sRbjhf8w7PGBOfdntMQ2mOQPZ5s/Q= github.com/libp2p/go-libp2p-secio v0.1.0/go.mod h1:tMJo2w7h3+wN4pgU2LSYeiKPrfqBgkOsdiKK77hE7c8= github.com/libp2p/go-libp2p-secio v0.2.0/go.mod h1:2JdZepB8J5V9mBp79BmwsaPQhRPNN2NrnB2lKQcdy6g= github.com/libp2p/go-libp2p-secio v0.2.1/go.mod h1:cWtZpILJqkqrSkiYcDBh5lA3wbT2Q+hz3rJQq3iftD8= diff --git a/test/cli/stats_test.go b/test/cli/stats_test.go new file mode 100644 index 000000000..05c1702b4 --- /dev/null +++ b/test/cli/stats_test.go @@ -0,0 +1,24 @@ +package cli + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/ipfs/kubo/test/cli/harness" +) + +func TestStats(t *testing.T) { + t.Parallel() + + t.Run("stats dht", func(t *testing.T) { + t.Parallel() + nodes := harness.NewT(t).NewNodes(2).Init().StartDaemons().Connect() + node1 := nodes[0] + + res := node1.IPFS("stats", "dht") + assert.NoError(t, res.Err) + assert.Equal(t, 0, len(res.Stderr.Lines())) + assert.NotEqual(t, 0, len(res.Stdout.Lines())) + }) +} From 255e64e49e837afce534555f3451e2cffe9f0dcb Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Fri, 13 Jan 2023 14:27:03 +0100 Subject: [PATCH 0379/1212] chore: migrate from go-ipfs-files to go-libipfs/files (#9535) --- assets/assets.go | 2 +- cmd/ipfs/add_migrations.go | 2 +- cmd/ipfs/init.go | 2 +- cmd/ipfswatch/main.go | 2 +- core/commands/add.go | 2 +- core/commands/block.go | 2 +- core/commands/cat.go | 6 ++-- core/commands/cmdenv/file.go | 2 +- core/commands/dag/import.go | 2 +- core/commands/dag/put.go | 2 +- core/commands/get.go | 2 +- core/commands/swarm.go | 2 +- core/commands/urlstore.go | 2 +- core/coreapi/test/path_test.go | 2 +- core/coreapi/unixfs.go | 2 +- core/corehttp/gateway_handler.go | 2 +- core/corehttp/gateway_handler_tar.go | 2 +- core/corehttp/gateway_handler_unixfs.go | 2 +- .../gateway_handler_unixfs__redirects.go | 2 +- core/corehttp/gateway_handler_unixfs_dir.go | 2 +- core/corehttp/gateway_handler_unixfs_file.go | 2 +- core/corehttp/gateway_test.go | 2 +- core/corehttp/hostname_test.go | 2 +- core/coreunix/add.go | 2 +- core/coreunix/add_test.go | 2 +- docs/examples/kubo-as-a-library/go.mod | 13 ++++--- docs/examples/kubo-as-a-library/go.sum | 26 +++++++------- docs/examples/kubo-as-a-library/main.go | 2 +- fuse/readonly/ipfs_test.go | 2 +- go.mod | 17 +++++---- go.sum | 35 +++++++++---------- .../migrations/ipfsfetcher/ipfsfetcher.go | 2 +- test/integration/addcat_test.go | 2 +- test/integration/bench_cat_test.go | 2 +- test/integration/three_legged_cat_test.go | 2 +- 35 files changed, 75 insertions(+), 82 deletions(-) diff --git a/assets/assets.go b/assets/assets.go index cf3418cb0..37cbbfad5 100644 --- a/assets/assets.go +++ b/assets/assets.go @@ -14,7 +14,7 @@ import ( "github.com/cespare/xxhash" cid "github.com/ipfs/go-cid" - files "github.com/ipfs/go-ipfs-files" + "github.com/ipfs/go-libipfs/files" options "github.com/ipfs/interface-go-ipfs-core/options" "github.com/ipfs/interface-go-ipfs-core/path" ) diff --git a/cmd/ipfs/add_migrations.go b/cmd/ipfs/add_migrations.go index 6d62b4d6b..50ea9ad1c 100644 --- a/cmd/ipfs/add_migrations.go +++ b/cmd/ipfs/add_migrations.go @@ -8,7 +8,7 @@ import ( "os" "path/filepath" - files "github.com/ipfs/go-ipfs-files" + "github.com/ipfs/go-libipfs/files" coreiface "github.com/ipfs/interface-go-ipfs-core" "github.com/ipfs/interface-go-ipfs-core/options" ipath "github.com/ipfs/interface-go-ipfs-core/path" diff --git a/cmd/ipfs/init.go b/cmd/ipfs/init.go index 745ceb3e2..4232cc262 100644 --- a/cmd/ipfs/init.go +++ b/cmd/ipfs/init.go @@ -19,7 +19,7 @@ import ( fsrepo "github.com/ipfs/kubo/repo/fsrepo" cmds "github.com/ipfs/go-ipfs-cmds" - files "github.com/ipfs/go-ipfs-files" + "github.com/ipfs/go-libipfs/files" options "github.com/ipfs/interface-go-ipfs-core/options" config "github.com/ipfs/kubo/config" ) diff --git a/cmd/ipfswatch/main.go b/cmd/ipfswatch/main.go index d555f14b9..06215687c 100644 --- a/cmd/ipfswatch/main.go +++ b/cmd/ipfswatch/main.go @@ -19,7 +19,7 @@ import ( fsrepo "github.com/ipfs/kubo/repo/fsrepo" fsnotify "github.com/fsnotify/fsnotify" - files "github.com/ipfs/go-ipfs-files" + "github.com/ipfs/go-libipfs/files" process "github.com/jbenet/goprocess" homedir "github.com/mitchellh/go-homedir" ) diff --git a/core/commands/add.go b/core/commands/add.go index 9f686e14b..7afe10f1e 100644 --- a/core/commands/add.go +++ b/core/commands/add.go @@ -12,8 +12,8 @@ import ( "github.com/cheggaaa/pb" cmds "github.com/ipfs/go-ipfs-cmds" - files "github.com/ipfs/go-ipfs-files" ipld "github.com/ipfs/go-ipld-format" + "github.com/ipfs/go-libipfs/files" mfs "github.com/ipfs/go-mfs" coreiface "github.com/ipfs/interface-go-ipfs-core" "github.com/ipfs/interface-go-ipfs-core/options" diff --git a/core/commands/block.go b/core/commands/block.go index b0591b002..c8001b49c 100644 --- a/core/commands/block.go +++ b/core/commands/block.go @@ -6,7 +6,7 @@ import ( "io" "os" - files "github.com/ipfs/go-ipfs-files" + "github.com/ipfs/go-libipfs/files" cmdenv "github.com/ipfs/kubo/core/commands/cmdenv" "github.com/ipfs/kubo/core/commands/cmdutils" diff --git a/core/commands/cat.go b/core/commands/cat.go index 151ac126e..c80bacf02 100644 --- a/core/commands/cat.go +++ b/core/commands/cat.go @@ -9,9 +9,9 @@ import ( "github.com/ipfs/kubo/core/commands/cmdenv" "github.com/cheggaaa/pb" - "github.com/ipfs/go-ipfs-cmds" - "github.com/ipfs/go-ipfs-files" - "github.com/ipfs/interface-go-ipfs-core" + cmds "github.com/ipfs/go-ipfs-cmds" + "github.com/ipfs/go-libipfs/files" + iface "github.com/ipfs/interface-go-ipfs-core" "github.com/ipfs/interface-go-ipfs-core/path" ) diff --git a/core/commands/cmdenv/file.go b/core/commands/cmdenv/file.go index 50ce748eb..43c12abc4 100644 --- a/core/commands/cmdenv/file.go +++ b/core/commands/cmdenv/file.go @@ -3,7 +3,7 @@ package cmdenv import ( "fmt" - files "github.com/ipfs/go-ipfs-files" + "github.com/ipfs/go-libipfs/files" ) // GetFileArg returns the next file from the directory or an error diff --git a/core/commands/dag/import.go b/core/commands/dag/import.go index 87daaae11..c9f0ebbde 100644 --- a/core/commands/dag/import.go +++ b/core/commands/dag/import.go @@ -6,9 +6,9 @@ import ( "io" cid "github.com/ipfs/go-cid" - files "github.com/ipfs/go-ipfs-files" ipld "github.com/ipfs/go-ipld-format" ipldlegacy "github.com/ipfs/go-ipld-legacy" + "github.com/ipfs/go-libipfs/files" iface "github.com/ipfs/interface-go-ipfs-core" "github.com/ipfs/interface-go-ipfs-core/options" "github.com/ipfs/kubo/core/commands/cmdenv" diff --git a/core/commands/dag/put.go b/core/commands/dag/put.go index d8dbaa3f1..ed00c5bee 100644 --- a/core/commands/dag/put.go +++ b/core/commands/dag/put.go @@ -13,8 +13,8 @@ import ( basicnode "github.com/ipld/go-ipld-prime/node/basic" cmds "github.com/ipfs/go-ipfs-cmds" - files "github.com/ipfs/go-ipfs-files" ipld "github.com/ipfs/go-ipld-format" + "github.com/ipfs/go-libipfs/files" mc "github.com/multiformats/go-multicodec" // Expected minimal set of available format/ienc codecs. diff --git a/core/commands/get.go b/core/commands/get.go index 7e915ea29..e5648b28f 100644 --- a/core/commands/get.go +++ b/core/commands/get.go @@ -16,7 +16,7 @@ import ( "github.com/cheggaaa/pb" cmds "github.com/ipfs/go-ipfs-cmds" - files "github.com/ipfs/go-ipfs-files" + "github.com/ipfs/go-libipfs/files" "github.com/ipfs/go-libipfs/tar" "github.com/ipfs/interface-go-ipfs-core/path" ) diff --git a/core/commands/swarm.go b/core/commands/swarm.go index d06f74579..d00291f78 100644 --- a/core/commands/swarm.go +++ b/core/commands/swarm.go @@ -12,7 +12,7 @@ import ( "sync" "time" - files "github.com/ipfs/go-ipfs-files" + "github.com/ipfs/go-libipfs/files" "github.com/ipfs/kubo/commands" "github.com/ipfs/kubo/config" "github.com/ipfs/kubo/core/commands/cmdenv" diff --git a/core/commands/urlstore.go b/core/commands/urlstore.go index bd67c56ff..b17dc713a 100644 --- a/core/commands/urlstore.go +++ b/core/commands/urlstore.go @@ -9,7 +9,7 @@ import ( cmdenv "github.com/ipfs/kubo/core/commands/cmdenv" cmds "github.com/ipfs/go-ipfs-cmds" - files "github.com/ipfs/go-ipfs-files" + "github.com/ipfs/go-libipfs/files" "github.com/ipfs/interface-go-ipfs-core/options" ) diff --git a/core/coreapi/test/path_test.go b/core/coreapi/test/path_test.go index bf26b39ce..acba1c47f 100644 --- a/core/coreapi/test/path_test.go +++ b/core/coreapi/test/path_test.go @@ -6,7 +6,7 @@ import ( "testing" "time" - files "github.com/ipfs/go-ipfs-files" + "github.com/ipfs/go-libipfs/files" "github.com/ipfs/go-merkledag" uio "github.com/ipfs/go-unixfs/io" "github.com/ipfs/interface-go-ipfs-core/options" diff --git a/core/coreapi/unixfs.go b/core/coreapi/unixfs.go index 753a3d3a0..7ab7d34d6 100644 --- a/core/coreapi/unixfs.go +++ b/core/coreapi/unixfs.go @@ -17,8 +17,8 @@ import ( cidutil "github.com/ipfs/go-cidutil" filestore "github.com/ipfs/go-filestore" bstore "github.com/ipfs/go-ipfs-blockstore" - files "github.com/ipfs/go-ipfs-files" ipld "github.com/ipfs/go-ipld-format" + "github.com/ipfs/go-libipfs/files" merkledag "github.com/ipfs/go-merkledag" dagtest "github.com/ipfs/go-merkledag/test" mfs "github.com/ipfs/go-mfs" diff --git a/core/corehttp/gateway_handler.go b/core/corehttp/gateway_handler.go index 64c388df4..c20f112d7 100644 --- a/core/corehttp/gateway_handler.go +++ b/core/corehttp/gateway_handler.go @@ -17,8 +17,8 @@ import ( "time" cid "github.com/ipfs/go-cid" - files "github.com/ipfs/go-ipfs-files" ipld "github.com/ipfs/go-ipld-format" + "github.com/ipfs/go-libipfs/files" dag "github.com/ipfs/go-merkledag" mfs "github.com/ipfs/go-mfs" path "github.com/ipfs/go-path" diff --git a/core/corehttp/gateway_handler_tar.go b/core/corehttp/gateway_handler_tar.go index 532d88757..14edf4fbf 100644 --- a/core/corehttp/gateway_handler_tar.go +++ b/core/corehttp/gateway_handler_tar.go @@ -6,7 +6,7 @@ import ( "net/http" "time" - files "github.com/ipfs/go-ipfs-files" + "github.com/ipfs/go-libipfs/files" ipath "github.com/ipfs/interface-go-ipfs-core/path" "github.com/ipfs/kubo/tracing" "go.opentelemetry.io/otel/attribute" diff --git a/core/corehttp/gateway_handler_unixfs.go b/core/corehttp/gateway_handler_unixfs.go index 75d51d93a..045c0f81d 100644 --- a/core/corehttp/gateway_handler_unixfs.go +++ b/core/corehttp/gateway_handler_unixfs.go @@ -7,7 +7,7 @@ import ( "net/http" "time" - files "github.com/ipfs/go-ipfs-files" + "github.com/ipfs/go-libipfs/files" ipath "github.com/ipfs/interface-go-ipfs-core/path" "github.com/ipfs/kubo/tracing" "go.opentelemetry.io/otel/attribute" diff --git a/core/corehttp/gateway_handler_unixfs__redirects.go b/core/corehttp/gateway_handler_unixfs__redirects.go index 81cf05731..6906683a6 100644 --- a/core/corehttp/gateway_handler_unixfs__redirects.go +++ b/core/corehttp/gateway_handler_unixfs__redirects.go @@ -8,8 +8,8 @@ import ( "strconv" "strings" - files "github.com/ipfs/go-ipfs-files" redirects "github.com/ipfs/go-ipfs-redirects-file" + "github.com/ipfs/go-libipfs/files" ipath "github.com/ipfs/interface-go-ipfs-core/path" "go.uber.org/zap" ) diff --git a/core/corehttp/gateway_handler_unixfs_dir.go b/core/corehttp/gateway_handler_unixfs_dir.go index 5e90a8a79..03d67e1c0 100644 --- a/core/corehttp/gateway_handler_unixfs_dir.go +++ b/core/corehttp/gateway_handler_unixfs_dir.go @@ -10,7 +10,7 @@ import ( "github.com/dustin/go-humanize" cid "github.com/ipfs/go-cid" - files "github.com/ipfs/go-ipfs-files" + "github.com/ipfs/go-libipfs/files" path "github.com/ipfs/go-path" "github.com/ipfs/go-path/resolver" options "github.com/ipfs/interface-go-ipfs-core/options" diff --git a/core/corehttp/gateway_handler_unixfs_file.go b/core/corehttp/gateway_handler_unixfs_file.go index 9463be1ac..1abdc823e 100644 --- a/core/corehttp/gateway_handler_unixfs_file.go +++ b/core/corehttp/gateway_handler_unixfs_file.go @@ -11,7 +11,7 @@ import ( "time" "github.com/gabriel-vasile/mimetype" - files "github.com/ipfs/go-ipfs-files" + "github.com/ipfs/go-libipfs/files" ipath "github.com/ipfs/interface-go-ipfs-core/path" "github.com/ipfs/kubo/tracing" "go.opentelemetry.io/otel/attribute" diff --git a/core/corehttp/gateway_test.go b/core/corehttp/gateway_test.go index 0d2f07dbe..74723579d 100644 --- a/core/corehttp/gateway_test.go +++ b/core/corehttp/gateway_test.go @@ -19,7 +19,7 @@ import ( datastore "github.com/ipfs/go-datastore" syncds "github.com/ipfs/go-datastore/sync" - files "github.com/ipfs/go-ipfs-files" + "github.com/ipfs/go-libipfs/files" path "github.com/ipfs/go-path" iface "github.com/ipfs/interface-go-ipfs-core" nsopts "github.com/ipfs/interface-go-ipfs-core/options/namesys" diff --git a/core/corehttp/hostname_test.go b/core/corehttp/hostname_test.go index 6f0713528..b4a8b8d16 100644 --- a/core/corehttp/hostname_test.go +++ b/core/corehttp/hostname_test.go @@ -7,7 +7,7 @@ import ( "testing" cid "github.com/ipfs/go-cid" - files "github.com/ipfs/go-ipfs-files" + "github.com/ipfs/go-libipfs/files" path "github.com/ipfs/go-path" config "github.com/ipfs/kubo/config" coreapi "github.com/ipfs/kubo/core/coreapi" diff --git a/core/coreunix/add.go b/core/coreunix/add.go index 16ccbaefa..f895baf73 100644 --- a/core/coreunix/add.go +++ b/core/coreunix/add.go @@ -11,10 +11,10 @@ import ( "github.com/ipfs/go-cid" bstore "github.com/ipfs/go-ipfs-blockstore" chunker "github.com/ipfs/go-ipfs-chunker" - files "github.com/ipfs/go-ipfs-files" pin "github.com/ipfs/go-ipfs-pinner" posinfo "github.com/ipfs/go-ipfs-posinfo" ipld "github.com/ipfs/go-ipld-format" + "github.com/ipfs/go-libipfs/files" logging "github.com/ipfs/go-log" dag "github.com/ipfs/go-merkledag" "github.com/ipfs/go-mfs" diff --git a/core/coreunix/add_test.go b/core/coreunix/add_test.go index 6d5d941f7..1ba1b2f0e 100644 --- a/core/coreunix/add_test.go +++ b/core/coreunix/add_test.go @@ -20,8 +20,8 @@ import ( "github.com/ipfs/go-datastore" syncds "github.com/ipfs/go-datastore/sync" blockstore "github.com/ipfs/go-ipfs-blockstore" - files "github.com/ipfs/go-ipfs-files" pi "github.com/ipfs/go-ipfs-posinfo" + "github.com/ipfs/go-libipfs/files" dag "github.com/ipfs/go-merkledag" coreiface "github.com/ipfs/interface-go-ipfs-core" config "github.com/ipfs/kubo/config" diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 7285936d6..040cec571 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,8 +7,8 @@ go 1.18 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/go-ipfs-files v0.2.0 - github.com/ipfs/interface-go-ipfs-core v0.8.1 + github.com/ipfs/go-libipfs v0.1.0 + github.com/ipfs/interface-go-ipfs-core v0.8.2 github.com/ipfs/kubo v0.14.0-rc1 github.com/libp2p/go-libp2p v0.24.2 github.com/multiformats/go-multiaddr v0.8.0 @@ -77,7 +77,7 @@ require ( github.com/ipfs/go-fetcher v1.6.1 // indirect github.com/ipfs/go-filestore v1.2.0 // indirect github.com/ipfs/go-fs-lock v0.0.7 // indirect - github.com/ipfs/go-graphsync v0.14.1-0.20221120210616-975d7aaeb15b // indirect + github.com/ipfs/go-graphsync v0.14.1 // indirect github.com/ipfs/go-ipfs-blockstore v1.2.0 // indirect github.com/ipfs/go-ipfs-chunker v0.0.5 // indirect github.com/ipfs/go-ipfs-delay v0.0.1 // indirect @@ -96,7 +96,6 @@ require ( github.com/ipfs/go-ipld-git v0.1.1 // indirect github.com/ipfs/go-ipld-legacy v0.1.1 // indirect github.com/ipfs/go-ipns v0.3.0 // indirect - github.com/ipfs/go-libipfs v0.0.0-20221208220359-356ce09dd4a1 // indirect github.com/ipfs/go-log v1.0.5 // indirect github.com/ipfs/go-log/v2 v2.5.1 // indirect github.com/ipfs/go-merkledag v0.8.1 // indirect @@ -105,11 +104,11 @@ require ( github.com/ipfs/go-namesys v0.6.0 // indirect github.com/ipfs/go-path v0.3.0 // indirect github.com/ipfs/go-peertaskqueue v0.8.0 // indirect - github.com/ipfs/go-unixfs v0.4.1 // indirect + github.com/ipfs/go-unixfs v0.4.2 // indirect github.com/ipfs/go-unixfsnode v1.4.0 // indirect github.com/ipfs/go-verifcid v0.0.2 // indirect github.com/ipld/edelweiss v0.2.0 // indirect - github.com/ipld/go-codec-dagpb v1.4.1 // indirect + github.com/ipld/go-codec-dagpb v1.5.0 // indirect github.com/ipld/go-ipld-prime v0.19.0 // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect @@ -206,7 +205,7 @@ require ( golang.org/x/mod v0.7.0 // indirect golang.org/x/net v0.3.0 // indirect golang.org/x/sync v0.1.0 // indirect - golang.org/x/sys v0.3.0 // indirect + golang.org/x/sys v0.4.0 // indirect golang.org/x/text v0.5.0 // indirect golang.org/x/tools v0.3.0 // indirect golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 45176636f..b35804386 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -486,8 +486,8 @@ github.com/ipfs/go-filestore v1.2.0 h1:O2wg7wdibwxkEDcl7xkuQsPvJFRBVgVSsOJ/GP6z3 github.com/ipfs/go-filestore v1.2.0/go.mod h1:HLJrCxRXquTeEEpde4lTLMaE/MYJZD7WHLkp9z6+FF8= github.com/ipfs/go-fs-lock v0.0.7 h1:6BR3dajORFrFTkb5EpCUFIAypsoxpGpDSVUdFwzgL9U= github.com/ipfs/go-fs-lock v0.0.7/go.mod h1:Js8ka+FNYmgQRLrRXzU3CB/+Csr1BwrRilEcvYrHhhc= -github.com/ipfs/go-graphsync v0.14.1-0.20221120210616-975d7aaeb15b h1:h+U91xq+a2jQh4oI0ZvxnaJ7s+6VAI8yyQE9jXEiSD0= -github.com/ipfs/go-graphsync v0.14.1-0.20221120210616-975d7aaeb15b/go.mod h1:Esdasda7sNmIlauOhqBG+J4yw60sE3EUftEpuOGX9to= +github.com/ipfs/go-graphsync v0.14.1 h1:tvFpBY9LcehIB7zi5SZIa+7aoxBOrGbdekhOXdnlT70= +github.com/ipfs/go-graphsync v0.14.1/go.mod h1:S6O/c5iXOXqDgrQgiZSgOTRUSiVvpKEhrzqFHKnLVcs= github.com/ipfs/go-ipfs-blockstore v0.0.1/go.mod h1:d3WClOmRQKFnJ0Jz/jj/zmksX0ma1gROTlovZKBmN08= github.com/ipfs/go-ipfs-blockstore v0.1.0/go.mod h1:5aD0AvHPi7mZc6Ci1WCAhiBQu2IsfTduLl+422H6Rqw= github.com/ipfs/go-ipfs-blockstore v0.2.1/go.mod h1:jGesd8EtCM3/zPgx+qr0/feTXGUeRai6adgwC+Q+JvE= @@ -516,8 +516,6 @@ github.com/ipfs/go-ipfs-exchange-offline v0.2.0/go.mod h1:HjwBeW0dvZvfOMwDP0TSKX github.com/ipfs/go-ipfs-exchange-offline v0.3.0 h1:c/Dg8GDPzixGd0MC8Jh6mjOwU57uYokgWRFidfvEkuA= github.com/ipfs/go-ipfs-exchange-offline v0.3.0/go.mod h1:MOdJ9DChbb5u37M1IcbrRB02e++Z7521fMxqCNRrz9s= github.com/ipfs/go-ipfs-files v0.0.3/go.mod h1:INEFm0LL2LWXBhNJ2PMIIb2w45hpXgPjNoE7yA8Y1d4= -github.com/ipfs/go-ipfs-files v0.2.0 h1:z6MCYHQSZpDWpUSK59Kf0ajP1fi4gLCf6fIulVsp8A8= -github.com/ipfs/go-ipfs-files v0.2.0/go.mod h1:vT7uaQfIsprKktzbTPLnIsd+NGw9ZbYwSq0g3N74u0M= github.com/ipfs/go-ipfs-keystore v0.1.0 h1:gfuQUO/cyGZgZIHE6OrJas4OnwuxXCqJG7tI0lrB5Qc= github.com/ipfs/go-ipfs-keystore v0.1.0/go.mod h1:LvLw7Qhnb0RlMOfCzK6OmyWxICip6lQ06CCmdbee75U= github.com/ipfs/go-ipfs-pinner v0.2.1 h1:kw9hiqh2p8TatILYZ3WAfQQABby7SQARdrdA+5Z5QfY= @@ -553,8 +551,8 @@ github.com/ipfs/go-ipld-legacy v0.1.1 h1:BvD8PEuqwBHLTKqlGFTHSwrwFOMkVESEvwIYwR2 github.com/ipfs/go-ipld-legacy v0.1.1/go.mod h1:8AyKFCjgRPsQFf15ZQgDB8Din4DML/fOmKZkkFkrIEg= github.com/ipfs/go-ipns v0.3.0 h1:ai791nTgVo+zTuq2bLvEGmWP1M0A6kGTXUsgv/Yq67A= github.com/ipfs/go-ipns v0.3.0/go.mod h1:3cLT2rbvgPZGkHJoPO1YMJeh6LtkxopCkKFcio/wE24= -github.com/ipfs/go-libipfs v0.0.0-20221208220359-356ce09dd4a1 h1:p/eMmtJfOliZh/SCVv239Wxj2lCo5IN4j5bdNmeGueM= -github.com/ipfs/go-libipfs v0.0.0-20221208220359-356ce09dd4a1/go.mod h1:blLqyfvHD86wgXMJ8GR4QQWYeg1ZvFHOhX3DT340Nj8= +github.com/ipfs/go-libipfs v0.1.0 h1:I6CrHHp4cIiqsWJPVU3QBH4BZrRWSljS2aAbA3Eg9AY= +github.com/ipfs/go-libipfs v0.1.0/go.mod h1:qX0d9h+wu53PFtCTXxdXVBakd6ZCvGDdkZUKmdLMLx0= github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= github.com/ipfs/go-log v1.0.2/go.mod h1:1MNjMxe0u6xvJZgeqbJ8vdo2TKaGwZ1a0Bpza+sr2Sk= github.com/ipfs/go-log v1.0.3/go.mod h1:OsLySYkwIbiSUR/yBTdv1qPtcE4FW3WPWk/ewz9Ru+A= @@ -590,24 +588,24 @@ github.com/ipfs/go-peertaskqueue v0.8.0 h1:JyNO144tfu9bx6Hpo119zvbEL9iQ760FHOiJY github.com/ipfs/go-peertaskqueue v0.8.0/go.mod h1:cz8hEnnARq4Du5TGqiWKgMr/BOSQ5XOgMOh1K5YYKKM= github.com/ipfs/go-unixfs v0.2.4/go.mod h1:SUdisfUjNoSDzzhGVxvCL9QO/nKdwXdr+gbMUdqcbYw= github.com/ipfs/go-unixfs v0.3.1/go.mod h1:h4qfQYzghiIc8ZNFKiLMFWOTzrWIAtzYQ59W/pCFf1o= -github.com/ipfs/go-unixfs v0.4.1 h1:nmJFKvF+khK03PIWyCxxydD/nkQX315NZDcgvRqMXf0= -github.com/ipfs/go-unixfs v0.4.1/go.mod h1:2SUDFhUSzrcL408B1qpIkJJ5HznnyTzweViPXUAvkNg= +github.com/ipfs/go-unixfs v0.4.2 h1:hdQlsHHK5tek9gC9mjGVua8xyTqC+eopGseCRcbCZNg= +github.com/ipfs/go-unixfs v0.4.2/go.mod h1:L+x6JRlFE0PfyMqeoLYVOKLhn5IeZHvNT7ZI51Y9Qyc= github.com/ipfs/go-unixfsnode v1.1.2/go.mod h1:5dcE2x03pyjHk4JjamXmunTMzz+VUtqvPwZjIEkfV6s= github.com/ipfs/go-unixfsnode v1.4.0 h1:9BUxHBXrbNi8mWHc6j+5C580WJqtVw9uoeEKn4tMhwA= github.com/ipfs/go-unixfsnode v1.4.0/go.mod h1:qc7YFFZ8tABc58p62HnIYbUMwj9chhUuFWmxSokfePo= github.com/ipfs/go-verifcid v0.0.1/go.mod h1:5Hrva5KBeIog4A+UpqlaIU+DEstipcJYQQZc0g37pY0= github.com/ipfs/go-verifcid v0.0.2 h1:XPnUv0XmdH+ZIhLGKg6U2vaPaRDXb9urMyNVCE7uvTs= github.com/ipfs/go-verifcid v0.0.2/go.mod h1:40cD9x1y4OWnFXbLNJYRe7MpNvWlMn3LZAG5Wb4xnPU= -github.com/ipfs/interface-go-ipfs-core v0.8.1 h1:nuFG0YJ429Wd5gtRb3ivlblpknZ5VfDVKZkmOG2TnNQ= -github.com/ipfs/interface-go-ipfs-core v0.8.1/go.mod h1:WYC2H6Mu7aGqhlupi/CVawcs0X1Me4uRvV0rcTlo3zM= +github.com/ipfs/interface-go-ipfs-core v0.8.2 h1:WDeCBnE4MENVOXbtfwwdAPJ2nBBS8PTmhZWWpm24HRM= +github.com/ipfs/interface-go-ipfs-core v0.8.2/go.mod h1:F3EcmDy53GFkF0H3iEJpfJC320fZ/4G60eftnItrrJ0= github.com/ipld/edelweiss v0.2.0 h1:KfAZBP8eeJtrLxLhi7r3N0cBCo7JmwSRhOJp3WSpNjk= github.com/ipld/edelweiss v0.2.0/go.mod h1:FJAzJRCep4iI8FOFlRriN9n0b7OuX3T/S9++NpBDmA4= github.com/ipld/go-car v0.4.0 h1:U6W7F1aKF/OJMHovnOVdst2cpQE5GhmHibQkAixgNcQ= github.com/ipld/go-car/v2 v2.1.1/go.mod h1:+2Yvf0Z3wzkv7NeI69i8tuZ+ft7jyjPYIWZzeVNeFcI= github.com/ipld/go-car/v2 v2.4.0 h1:8jI6/iKlyLqRZzLz31jFWTqKvslaVzFsin305sOuqNQ= github.com/ipld/go-codec-dagpb v1.3.0/go.mod h1:ga4JTU3abYApDC3pZ00BC2RSvC3qfBb9MSJkMLSwnhA= -github.com/ipld/go-codec-dagpb v1.4.1 h1:CUQJaOPRgSZ27OUPgUWtvdvvd2d17/IGGAIMOo4yYp0= -github.com/ipld/go-codec-dagpb v1.4.1/go.mod h1:XdXTO/TUD/ra9RcK/NfmwBfr1JpFxM2uRKaB9oe4LxE= +github.com/ipld/go-codec-dagpb v1.5.0 h1:RspDRdsJpLfgCI0ONhTAnbHdySGD4t+LHSPK4X1+R0k= +github.com/ipld/go-codec-dagpb v1.5.0/go.mod h1:0yRIutEFD8o1DGVqw4RSHh+BUTlJA9XWldxaaWR/o4g= 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.14.0/go.mod h1:9ASQLwUFLptCov6lIYc70GRB4V7UTyLD0IJtrDJe6ZM= @@ -1633,8 +1631,8 @@ golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ= -golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18= +golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= diff --git a/docs/examples/kubo-as-a-library/main.go b/docs/examples/kubo-as-a-library/main.go index 08a80bdef..8bd9f8f9c 100644 --- a/docs/examples/kubo-as-a-library/main.go +++ b/docs/examples/kubo-as-a-library/main.go @@ -11,7 +11,7 @@ import ( "strings" "sync" - files "github.com/ipfs/go-ipfs-files" + "github.com/ipfs/go-libipfs/files" icore "github.com/ipfs/interface-go-ipfs-core" icorepath "github.com/ipfs/interface-go-ipfs-core/path" ma "github.com/multiformats/go-multiaddr" diff --git a/fuse/readonly/ipfs_test.go b/fuse/readonly/ipfs_test.go index 7e79b9cf6..04fc07f73 100644 --- a/fuse/readonly/ipfs_test.go +++ b/fuse/readonly/ipfs_test.go @@ -24,9 +24,9 @@ import ( fstest "bazil.org/fuse/fs/fstestutil" chunker "github.com/ipfs/go-ipfs-chunker" - files "github.com/ipfs/go-ipfs-files" u "github.com/ipfs/go-ipfs-util" ipld "github.com/ipfs/go-ipld-format" + "github.com/ipfs/go-libipfs/files" dag "github.com/ipfs/go-merkledag" importer "github.com/ipfs/go-unixfs/importer" uio "github.com/ipfs/go-unixfs/io" diff --git a/go.mod b/go.mod index 55e770587..238774683 100644 --- a/go.mod +++ b/go.mod @@ -32,13 +32,12 @@ require ( github.com/ipfs/go-fetcher v1.6.1 github.com/ipfs/go-filestore v1.2.0 github.com/ipfs/go-fs-lock v0.0.7 - github.com/ipfs/go-graphsync v0.14.0 + github.com/ipfs/go-graphsync v0.14.1 github.com/ipfs/go-ipfs-blockstore v1.2.0 github.com/ipfs/go-ipfs-chunker v0.0.5 - github.com/ipfs/go-ipfs-cmds v0.8.1 + github.com/ipfs/go-ipfs-cmds v0.8.2 github.com/ipfs/go-ipfs-exchange-interface v0.2.0 github.com/ipfs/go-ipfs-exchange-offline v0.3.0 - github.com/ipfs/go-ipfs-files v0.2.0 github.com/ipfs/go-ipfs-keystore v0.1.0 github.com/ipfs/go-ipfs-pinner v0.2.1 github.com/ipfs/go-ipfs-posinfo v0.0.1 @@ -50,7 +49,7 @@ require ( github.com/ipfs/go-ipld-git v0.1.1 github.com/ipfs/go-ipld-legacy v0.1.1 github.com/ipfs/go-ipns v0.3.0 - github.com/ipfs/go-libipfs v0.0.0-20221208220359-356ce09dd4a1 + github.com/ipfs/go-libipfs v0.1.0 github.com/ipfs/go-log v1.0.5 github.com/ipfs/go-log/v2 v2.5.1 github.com/ipfs/go-merkledag v0.8.1 @@ -60,13 +59,13 @@ require ( github.com/ipfs/go-namesys v0.6.0 github.com/ipfs/go-path v0.3.0 github.com/ipfs/go-pinning-service-http-client v0.1.2 - github.com/ipfs/go-unixfs v0.4.1 + github.com/ipfs/go-unixfs v0.4.2 github.com/ipfs/go-unixfsnode v1.4.0 github.com/ipfs/go-verifcid v0.0.2 - github.com/ipfs/interface-go-ipfs-core v0.8.1 + github.com/ipfs/interface-go-ipfs-core v0.8.2 github.com/ipld/go-car v0.4.0 github.com/ipld/go-car/v2 v2.4.0 - github.com/ipld/go-codec-dagpb v1.4.1 + github.com/ipld/go-codec-dagpb v1.5.0 github.com/ipld/go-ipld-prime v0.19.0 github.com/jbenet/go-random v0.0.0-20190219211222-123a90aedc0c github.com/jbenet/go-temp-err-catcher v0.1.0 @@ -113,7 +112,7 @@ require ( golang.org/x/crypto v0.3.0 golang.org/x/mod v0.7.0 golang.org/x/sync v0.1.0 - golang.org/x/sys v0.3.0 + golang.org/x/sys v0.4.0 ) require ( @@ -236,7 +235,7 @@ require ( golang.org/x/exp v0.0.0-20221205204356-47842c84f3db // indirect golang.org/x/net v0.3.0 // indirect golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b // indirect - golang.org/x/term v0.3.0 // indirect + golang.org/x/term v0.4.0 // indirect golang.org/x/text v0.5.0 // indirect golang.org/x/tools v0.3.0 // indirect golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f // indirect diff --git a/go.sum b/go.sum index 6f75ebb82..605ea36c3 100644 --- a/go.sum +++ b/go.sum @@ -504,8 +504,8 @@ github.com/ipfs/go-filestore v1.2.0 h1:O2wg7wdibwxkEDcl7xkuQsPvJFRBVgVSsOJ/GP6z3 github.com/ipfs/go-filestore v1.2.0/go.mod h1:HLJrCxRXquTeEEpde4lTLMaE/MYJZD7WHLkp9z6+FF8= github.com/ipfs/go-fs-lock v0.0.7 h1:6BR3dajORFrFTkb5EpCUFIAypsoxpGpDSVUdFwzgL9U= github.com/ipfs/go-fs-lock v0.0.7/go.mod h1:Js8ka+FNYmgQRLrRXzU3CB/+Csr1BwrRilEcvYrHhhc= -github.com/ipfs/go-graphsync v0.14.0 h1:f5KYkc8GpwwE1BrjBOWxIkRivXIw7fVqGZlnILpvbSc= -github.com/ipfs/go-graphsync v0.14.0/go.mod h1:1LDVVnNHjit8ddJOtw3Jq9epP792xWFXXL3dJWIBIkM= +github.com/ipfs/go-graphsync v0.14.1 h1:tvFpBY9LcehIB7zi5SZIa+7aoxBOrGbdekhOXdnlT70= +github.com/ipfs/go-graphsync v0.14.1/go.mod h1:S6O/c5iXOXqDgrQgiZSgOTRUSiVvpKEhrzqFHKnLVcs= github.com/ipfs/go-ipfs-blockstore v0.0.1/go.mod h1:d3WClOmRQKFnJ0Jz/jj/zmksX0ma1gROTlovZKBmN08= github.com/ipfs/go-ipfs-blockstore v0.1.0/go.mod h1:5aD0AvHPi7mZc6Ci1WCAhiBQu2IsfTduLl+422H6Rqw= github.com/ipfs/go-ipfs-blockstore v0.2.1/go.mod h1:jGesd8EtCM3/zPgx+qr0/feTXGUeRai6adgwC+Q+JvE= @@ -517,8 +517,8 @@ github.com/ipfs/go-ipfs-blocksutil v0.0.1/go.mod h1:Yq4M86uIOmxmGPUHv/uI7uKqZNtL github.com/ipfs/go-ipfs-chunker v0.0.1/go.mod h1:tWewYK0we3+rMbOh7pPFGDyypCtvGcBFymgY4rSDLAw= github.com/ipfs/go-ipfs-chunker v0.0.5 h1:ojCf7HV/m+uS2vhUGWcogIIxiO5ubl5O57Q7NapWLY8= github.com/ipfs/go-ipfs-chunker v0.0.5/go.mod h1:jhgdF8vxRHycr00k13FM8Y0E+6BoalYeobXmUyTreP8= -github.com/ipfs/go-ipfs-cmds v0.8.1 h1:El661DBWqdqwgz7B9xwKyUpigwqk6BBBHb5B8DfJP00= -github.com/ipfs/go-ipfs-cmds v0.8.1/go.mod h1:y0bflH6m4g6ary4HniYt98UqbrVnRxmRarzeMdLIUn0= +github.com/ipfs/go-ipfs-cmds v0.8.2 h1:WmehvYWkxch8dTw0bdF51R8lqbyl+3H8e6pIACzT/ds= +github.com/ipfs/go-ipfs-cmds v0.8.2/go.mod h1:/b17Davff0E0Wh/hhXsN1Pgxxbkm26k3PV+G4EDiC/s= github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= github.com/ipfs/go-ipfs-delay v0.0.1 h1:r/UXYyRcddO6thwOnhiznIAiSvxMECGgtv35Xs1IeRQ= github.com/ipfs/go-ipfs-delay v0.0.1/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= @@ -536,9 +536,6 @@ github.com/ipfs/go-ipfs-exchange-offline v0.2.0/go.mod h1:HjwBeW0dvZvfOMwDP0TSKX github.com/ipfs/go-ipfs-exchange-offline v0.3.0 h1:c/Dg8GDPzixGd0MC8Jh6mjOwU57uYokgWRFidfvEkuA= github.com/ipfs/go-ipfs-exchange-offline v0.3.0/go.mod h1:MOdJ9DChbb5u37M1IcbrRB02e++Z7521fMxqCNRrz9s= github.com/ipfs/go-ipfs-files v0.0.3/go.mod h1:INEFm0LL2LWXBhNJ2PMIIb2w45hpXgPjNoE7yA8Y1d4= -github.com/ipfs/go-ipfs-files v0.0.8/go.mod h1:wiN/jSG8FKyk7N0WyctKSvq3ljIa2NNTiZB55kpTdOs= -github.com/ipfs/go-ipfs-files v0.2.0 h1:z6MCYHQSZpDWpUSK59Kf0ajP1fi4gLCf6fIulVsp8A8= -github.com/ipfs/go-ipfs-files v0.2.0/go.mod h1:vT7uaQfIsprKktzbTPLnIsd+NGw9ZbYwSq0g3N74u0M= github.com/ipfs/go-ipfs-keystore v0.1.0 h1:gfuQUO/cyGZgZIHE6OrJas4OnwuxXCqJG7tI0lrB5Qc= github.com/ipfs/go-ipfs-keystore v0.1.0/go.mod h1:LvLw7Qhnb0RlMOfCzK6OmyWxICip6lQ06CCmdbee75U= github.com/ipfs/go-ipfs-pinner v0.2.1 h1:kw9hiqh2p8TatILYZ3WAfQQABby7SQARdrdA+5Z5QfY= @@ -576,8 +573,8 @@ github.com/ipfs/go-ipld-legacy v0.1.1 h1:BvD8PEuqwBHLTKqlGFTHSwrwFOMkVESEvwIYwR2 github.com/ipfs/go-ipld-legacy v0.1.1/go.mod h1:8AyKFCjgRPsQFf15ZQgDB8Din4DML/fOmKZkkFkrIEg= github.com/ipfs/go-ipns v0.3.0 h1:ai791nTgVo+zTuq2bLvEGmWP1M0A6kGTXUsgv/Yq67A= github.com/ipfs/go-ipns v0.3.0/go.mod h1:3cLT2rbvgPZGkHJoPO1YMJeh6LtkxopCkKFcio/wE24= -github.com/ipfs/go-libipfs v0.0.0-20221208220359-356ce09dd4a1 h1:p/eMmtJfOliZh/SCVv239Wxj2lCo5IN4j5bdNmeGueM= -github.com/ipfs/go-libipfs v0.0.0-20221208220359-356ce09dd4a1/go.mod h1:blLqyfvHD86wgXMJ8GR4QQWYeg1ZvFHOhX3DT340Nj8= +github.com/ipfs/go-libipfs v0.1.0 h1:I6CrHHp4cIiqsWJPVU3QBH4BZrRWSljS2aAbA3Eg9AY= +github.com/ipfs/go-libipfs v0.1.0/go.mod h1:qX0d9h+wu53PFtCTXxdXVBakd6ZCvGDdkZUKmdLMLx0= github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= github.com/ipfs/go-log v1.0.2/go.mod h1:1MNjMxe0u6xvJZgeqbJ8vdo2TKaGwZ1a0Bpza+sr2Sk= github.com/ipfs/go-log v1.0.3/go.mod h1:OsLySYkwIbiSUR/yBTdv1qPtcE4FW3WPWk/ewz9Ru+A= @@ -617,16 +614,16 @@ github.com/ipfs/go-pinning-service-http-client v0.1.2 h1:jdr7KelhL9gNHTU8jbqPMwI github.com/ipfs/go-pinning-service-http-client v0.1.2/go.mod h1:6wd5mjYhXJTiWU8b4RSWPpWdlzE5/csoXV0dWWMjun4= github.com/ipfs/go-unixfs v0.2.4/go.mod h1:SUdisfUjNoSDzzhGVxvCL9QO/nKdwXdr+gbMUdqcbYw= github.com/ipfs/go-unixfs v0.3.1/go.mod h1:h4qfQYzghiIc8ZNFKiLMFWOTzrWIAtzYQ59W/pCFf1o= -github.com/ipfs/go-unixfs v0.4.1 h1:nmJFKvF+khK03PIWyCxxydD/nkQX315NZDcgvRqMXf0= -github.com/ipfs/go-unixfs v0.4.1/go.mod h1:2SUDFhUSzrcL408B1qpIkJJ5HznnyTzweViPXUAvkNg= +github.com/ipfs/go-unixfs v0.4.2 h1:hdQlsHHK5tek9gC9mjGVua8xyTqC+eopGseCRcbCZNg= +github.com/ipfs/go-unixfs v0.4.2/go.mod h1:L+x6JRlFE0PfyMqeoLYVOKLhn5IeZHvNT7ZI51Y9Qyc= github.com/ipfs/go-unixfsnode v1.1.2/go.mod h1:5dcE2x03pyjHk4JjamXmunTMzz+VUtqvPwZjIEkfV6s= github.com/ipfs/go-unixfsnode v1.4.0 h1:9BUxHBXrbNi8mWHc6j+5C580WJqtVw9uoeEKn4tMhwA= github.com/ipfs/go-unixfsnode v1.4.0/go.mod h1:qc7YFFZ8tABc58p62HnIYbUMwj9chhUuFWmxSokfePo= github.com/ipfs/go-verifcid v0.0.1/go.mod h1:5Hrva5KBeIog4A+UpqlaIU+DEstipcJYQQZc0g37pY0= github.com/ipfs/go-verifcid v0.0.2 h1:XPnUv0XmdH+ZIhLGKg6U2vaPaRDXb9urMyNVCE7uvTs= github.com/ipfs/go-verifcid v0.0.2/go.mod h1:40cD9x1y4OWnFXbLNJYRe7MpNvWlMn3LZAG5Wb4xnPU= -github.com/ipfs/interface-go-ipfs-core v0.8.1 h1:nuFG0YJ429Wd5gtRb3ivlblpknZ5VfDVKZkmOG2TnNQ= -github.com/ipfs/interface-go-ipfs-core v0.8.1/go.mod h1:WYC2H6Mu7aGqhlupi/CVawcs0X1Me4uRvV0rcTlo3zM= +github.com/ipfs/interface-go-ipfs-core v0.8.2 h1:WDeCBnE4MENVOXbtfwwdAPJ2nBBS8PTmhZWWpm24HRM= +github.com/ipfs/interface-go-ipfs-core v0.8.2/go.mod h1:F3EcmDy53GFkF0H3iEJpfJC320fZ/4G60eftnItrrJ0= github.com/ipld/edelweiss v0.2.0 h1:KfAZBP8eeJtrLxLhi7r3N0cBCo7JmwSRhOJp3WSpNjk= github.com/ipld/edelweiss v0.2.0/go.mod h1:FJAzJRCep4iI8FOFlRriN9n0b7OuX3T/S9++NpBDmA4= github.com/ipld/go-car v0.4.0 h1:U6W7F1aKF/OJMHovnOVdst2cpQE5GhmHibQkAixgNcQ= @@ -635,8 +632,8 @@ github.com/ipld/go-car/v2 v2.1.1/go.mod h1:+2Yvf0Z3wzkv7NeI69i8tuZ+ft7jyjPYIWZze github.com/ipld/go-car/v2 v2.4.0 h1:8jI6/iKlyLqRZzLz31jFWTqKvslaVzFsin305sOuqNQ= github.com/ipld/go-car/v2 v2.4.0/go.mod h1:zjpRf0Jew9gHqSvjsKVyoq9OY9SWoEKdYCQUKVaaPT0= github.com/ipld/go-codec-dagpb v1.3.0/go.mod h1:ga4JTU3abYApDC3pZ00BC2RSvC3qfBb9MSJkMLSwnhA= -github.com/ipld/go-codec-dagpb v1.4.1 h1:CUQJaOPRgSZ27OUPgUWtvdvvd2d17/IGGAIMOo4yYp0= -github.com/ipld/go-codec-dagpb v1.4.1/go.mod h1:XdXTO/TUD/ra9RcK/NfmwBfr1JpFxM2uRKaB9oe4LxE= +github.com/ipld/go-codec-dagpb v1.5.0 h1:RspDRdsJpLfgCI0ONhTAnbHdySGD4t+LHSPK4X1+R0k= +github.com/ipld/go-codec-dagpb v1.5.0/go.mod h1:0yRIutEFD8o1DGVqw4RSHh+BUTlJA9XWldxaaWR/o4g= 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.14.0/go.mod h1:9ASQLwUFLptCov6lIYc70GRB4V7UTyLD0IJtrDJe6ZM= @@ -1701,13 +1698,13 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ= -golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18= +golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.3.0 h1:qoo4akIqOcDME5bhc/NgxUdovd6BSS2uMsVjB56q1xI= -golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= +golang.org/x/term v0.4.0 h1:O7UWfv5+A2qiuulQk30kVinPoMtoIPeVaKLEgLpVkvg= +golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/repo/fsrepo/migrations/ipfsfetcher/ipfsfetcher.go b/repo/fsrepo/migrations/ipfsfetcher/ipfsfetcher.go index d13eaf148..52cd354d3 100644 --- a/repo/fsrepo/migrations/ipfsfetcher/ipfsfetcher.go +++ b/repo/fsrepo/migrations/ipfsfetcher/ipfsfetcher.go @@ -11,7 +11,7 @@ import ( "strings" "sync" - files "github.com/ipfs/go-ipfs-files" + "github.com/ipfs/go-libipfs/files" iface "github.com/ipfs/interface-go-ipfs-core" "github.com/ipfs/interface-go-ipfs-core/options" ipath "github.com/ipfs/interface-go-ipfs-core/path" diff --git a/test/integration/addcat_test.go b/test/integration/addcat_test.go index 45e8729ac..6f306d2bf 100644 --- a/test/integration/addcat_test.go +++ b/test/integration/addcat_test.go @@ -11,7 +11,7 @@ import ( "testing" "time" - files "github.com/ipfs/go-ipfs-files" + "github.com/ipfs/go-libipfs/files" logging "github.com/ipfs/go-log" "github.com/ipfs/kubo/core" "github.com/ipfs/kubo/core/bootstrap" diff --git a/test/integration/bench_cat_test.go b/test/integration/bench_cat_test.go index d7e37dbb9..12c4d8dea 100644 --- a/test/integration/bench_cat_test.go +++ b/test/integration/bench_cat_test.go @@ -8,7 +8,7 @@ import ( "math" "testing" - files "github.com/ipfs/go-ipfs-files" + "github.com/ipfs/go-libipfs/files" "github.com/ipfs/kubo/core" "github.com/ipfs/kubo/core/bootstrap" "github.com/ipfs/kubo/core/coreapi" diff --git a/test/integration/three_legged_cat_test.go b/test/integration/three_legged_cat_test.go index f0358272b..c788bfb5e 100644 --- a/test/integration/three_legged_cat_test.go +++ b/test/integration/three_legged_cat_test.go @@ -14,7 +14,7 @@ import ( mock "github.com/ipfs/kubo/core/mock" "github.com/ipfs/kubo/thirdparty/unit" - files "github.com/ipfs/go-ipfs-files" + "github.com/ipfs/go-libipfs/files" testutil "github.com/libp2p/go-libp2p-testing/net" "github.com/libp2p/go-libp2p/core/peer" mocknet "github.com/libp2p/go-libp2p/p2p/net/mock" From d4cd414b5eaa3c6f1a1a27bdba323e27d19678d2 Mon Sep 17 00:00:00 2001 From: Piotr Galar Date: Sat, 14 Jan 2023 00:49:52 +0100 Subject: [PATCH 0380/1212] test: port CircleCI to GH Actions and improve sharness reporting (#9355) Closes https://github.com/ipfs/kubo/issues/8991 Part of https://github.com/ipfs/kubo/issues/8804 --- .circleci/config.yml | 2 +- .circleci/main.yml | 17 +- .github/workflows/build.yml | 200 ++++++++++++++ .github/workflows/codeql-analysis.yml | 2 +- .github/workflows/docker-build.yml | 25 ++ .github/workflows/docker-image.yml | 2 +- .github/workflows/gobuild.yml | 39 +++ .github/workflows/golang-analysis.yml | 9 +- .github/workflows/golint.yml | 32 +++ .github/workflows/gotest.yml | 65 +++++ .github/workflows/runner.yml | 33 +++ .github/workflows/sharness.yml | 124 +++++++++ Rules.mk | 3 +- appveyor.yml | 18 +- codecov.yml | 1 + coverage/Rules.mk | 2 +- test/sharness/.gitignore | 9 + test/sharness/README.md | 2 +- test/sharness/Rules.mk | 28 +- .../0001-Generate-partial-JUnit-reports.patch | 250 ------------------ test/sharness/lib/gen-junit-report.sh | 8 - test/sharness/lib/install-sharness.sh | 72 +++-- .../lib/test-aggregate-junit-reports.sh | 17 ++ test/sharness/lib/test-generate-junit-html.sh | 58 ++++ test/sharness/lib/test-lib.sh | 17 +- test/sharness/t0110-gateway.sh | 4 +- test/sharness/t0118-gateway-car.sh | 2 +- test/sharness/t0125-twonode.sh | 6 + test/sharness/t0160-resolve.sh | 42 +-- test/sharness/t0300-docker-image.sh | 7 +- 30 files changed, 712 insertions(+), 384 deletions(-) create mode 100644 .github/workflows/build.yml create mode 100644 .github/workflows/docker-build.yml create mode 100644 .github/workflows/gobuild.yml create mode 100644 .github/workflows/golint.yml create mode 100644 .github/workflows/gotest.yml create mode 100644 .github/workflows/runner.yml create mode 100644 .github/workflows/sharness.yml delete mode 100644 test/sharness/lib/0001-Generate-partial-JUnit-reports.patch delete mode 100755 test/sharness/lib/gen-junit-report.sh create mode 100755 test/sharness/lib/test-aggregate-junit-reports.sh create mode 100755 test/sharness/lib/test-generate-junit-html.sh diff --git a/.circleci/config.yml b/.circleci/config.yml index a40a162aa..3da57d246 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -7,7 +7,7 @@ jobs: executor: continuation/default steps: - checkout - - run: + - run: name: Generate params # for builds on the ipfs/kubo repo, use 2xlarge for faster builds # but since this is not available for many contributors, we otherwise use medium diff --git a/.circleci/main.yml b/.circleci/main.yml index 08e176656..6406c6655 100644 --- a/.circleci/main.yml +++ b/.circleci/main.yml @@ -143,14 +143,17 @@ jobs: path: /tmp/circleci-test-results sharness: machine: - image: ubuntu-2004:202010-01 + image: ubuntu-2204:2022.10.1 resource_class: << pipeline.parameters.resource_class >> working_directory: ~/ipfs/kubo environment: <<: *default_environment TEST_NO_DOCKER: 0 + TEST_NO_PLUGIN: 1 TEST_NO_FUSE: 1 TEST_VERBOSE: 1 + TEST_JUNIT: 1 + TEST_EXPENSIVE: 1 steps: - run: sudo apt update - run: | @@ -159,7 +162,7 @@ jobs: tar xfz go1.19.1.linux-amd64.tar.gz echo "export PATH=$(pwd)/go/bin:\$PATH" >> ~/.bashrc - run: go version - - run: sudo apt install socat net-tools fish + - run: sudo apt install socat net-tools fish libxml2-utils - checkout - run: @@ -183,7 +186,7 @@ jobs: command: echo "export TEST_DOCKER_HOST=$(ip -4 addr show docker0 | grep -Po 'inet \K[\d.]+')" >> $BASH_ENV - run: echo TEST_DOCKER_HOST=$TEST_DOCKER_HOST && - make -O -j << pipeline.parameters.make_jobs >> coverage/sharness_tests.coverprofile test/sharness/test-results/sharness.xml TEST_GENERATE_JUNIT=1 CONTINUE_ON_S_FAILURE=1 TEST_DOCKER_HOST=$TEST_DOCKER_HOST + make -O -j << pipeline.parameters.make_jobs >> test_sharness coverage/sharness_tests.coverprofile test/sharness/test-results/sharness.xml CONTINUE_ON_S_FAILURE=1 TEST_DOCKER_HOST=$TEST_DOCKER_HOST - run: when: always command: bash <(curl -s https://codecov.io/bash) -cF sharness -X search -f coverage/sharness_tests.coverprofile @@ -345,13 +348,13 @@ jobs: npx playwright install working_directory: ~/ipfs/kubo/ipfs-webui - run: - name: Running upstream tests (finish early if they fail) + name: Run ipfs-webui@main build and smoke-test to confirm the upstream repo is not broken command: | - npm test || circleci-agent step halt + npm test working_directory: ~/ipfs/kubo/ipfs-webui - run: - name: Running tests with kubo built from current commit - command: npm test + name: Test ipfs-webui@main E2E against the locally built Kubo binary + command: npm run test:e2e working_directory: ~/ipfs/kubo/ipfs-webui environment: IPFS_GO_EXEC: /tmp/circleci-workspace/bin/ipfs diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 000000000..d0b4194b7 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,200 @@ +name: 'ci/gh-experiment: interop' + +on: + workflow_dispatch: + pull_request: + push: + branches: + - 'master' + +env: + GO_VERSION: 1.19.1 + +jobs: + prepare: + if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' + runs-on: ubuntu-latest + env: + TEST_NO_DOCKER: 1 + TEST_NO_FUSE: 1 + TEST_VERBOSE: 1 + TRAVIS: 1 + GIT_PAGER: cat + IPFS_CHECK_RCMGR_DEFAULTS: 1 + defaults: + run: + shell: bash + steps: + - uses: actions/setup-go@v3 + with: + go-version: ${{ env.GO_VERSION }} + - uses: actions/checkout@v3 + - uses: protocol/cache-go-action@v1 + with: + name: ${{ github.job }} + - run: make build + - uses: actions/upload-artifact@v3 + with: + name: kubo + path: cmd/ipfs/ipfs + ipfs-interop: + needs: [prepare] + runs-on: ubuntu-latest + strategy: + matrix: + suites: + - 'exchange-files' + - 'files pin circuit ipns cid-version-agnostic ipns-pubsub pubsub' + fail-fast: false + defaults: + run: + shell: bash + steps: + - uses: actions/setup-node@v3 + with: + node-version: 16.12.0 + - uses: actions/download-artifact@v3 + with: + name: kubo + path: cmd/ipfs + - run: chmod +x cmd/ipfs/ipfs + - run: | + echo "dir=$(npm config get cache)" >> $GITHUB_OUTPUT + id: npm-cache-dir + - uses: actions/cache@v3 + with: + path: ${{ steps.npm-cache-dir.outputs.dir }} + key: ${{ runner.os }}-${{ github.job }}-${{ hashFiles('**/package-lock.json') }} + restore-keys: | + ${{ runner.os }}-${{ github.job }}- + - run: mkdir interop + - run: | + npm init -y + npm install ipfs@^0.61.0 + npm install ipfs-interop@^8.0.10 + working-directory: interop + - run: npx ipfs-interop -- -t node $(sed -e 's#[^ ]*#-f test/&.js#g' <<< '${{ matrix.suites }}') + env: + LIBP2P_TCP_REUSEPORT: false + LIBP2P_ALLOW_WEAK_RSA_KEYS: 1 + IPFS_GO_EXEC: ${{ github.workspace }}/cmd/ipfs/ipfs + working-directory: interop + go-ipfs-api: + needs: [prepare] + runs-on: ubuntu-latest + env: + TEST_NO_DOCKER: 1 + TEST_NO_FUSE: 1 + TEST_VERBOSE: 1 + TRAVIS: 1 + GIT_PAGER: cat + IPFS_CHECK_RCMGR_DEFAULTS: 1 + defaults: + run: + shell: bash + steps: + - uses: actions/setup-go@v3 + with: + go-version: ${{ env.GO_VERSION }} + - uses: actions/download-artifact@v3 + with: + name: kubo + path: cmd/ipfs + - run: chmod +x cmd/ipfs/ipfs + - uses: actions/checkout@v3 + with: + repository: ipfs/go-ipfs-api + path: go-ipfs-api + - run: cmd/ipfs/ipfs daemon --init --enable-namesys-pubsub & + - run: | + while ! cmd/ipfs/ipfs id --api=/ip4/127.0.0.1/tcp/5001 2>/dev/null; do + sleep 1 + done + timeout-minutes: 5 + - uses: protocol/cache-go-action@v1 + with: + name: ${{ github.job }} + - run: go test -count=1 -v ./... + working-directory: go-ipfs-api + - run: cmd/ipfs/ipfs shutdown + if: always() + go-ipfs-http-client: + needs: [prepare] + runs-on: ubuntu-latest + env: + TEST_NO_DOCKER: 1 + TEST_NO_FUSE: 1 + TEST_VERBOSE: 1 + TRAVIS: 1 + GIT_PAGER: cat + IPFS_CHECK_RCMGR_DEFAULTS: 1 + defaults: + run: + shell: bash + steps: + - uses: actions/setup-go@v3 + with: + go-version: ${{ env.GO_VERSION }} + - uses: actions/download-artifact@v3 + with: + name: kubo + path: cmd/ipfs + - run: chmod +x cmd/ipfs/ipfs + - uses: actions/checkout@v3 + with: + repository: ipfs/go-ipfs-http-client + path: go-ipfs-http-client + - uses: protocol/cache-go-action@v1 + with: + name: ${{ github.job }} + - run: echo '${{ github.workspace }}/cmd/ipfs' >> $GITHUB_PATH + - run: go test -count=1 -v ./... + working-directory: go-ipfs-http-client + ipfs-webui: + needs: [prepare] + runs-on: ubuntu-latest + env: + NO_SANDBOX: true + LIBP2P_TCP_REUSEPORT: false + LIBP2P_ALLOW_WEAK_RSA_KEYS: 1 + E2E_IPFSD_TYPE: go + TRAVIS: 1 + GIT_PAGER: cat + IPFS_CHECK_RCMGR_DEFAULTS: 1 + defaults: + run: + shell: bash + steps: + - uses: actions/setup-node@v3 + with: + node-version: 16.12.0 + - uses: actions/download-artifact@v3 + with: + name: kubo + path: cmd/ipfs + - run: chmod +x cmd/ipfs/ipfs + - uses: actions/checkout@v3 + with: + repository: ipfs/ipfs-webui + path: ipfs-webui + - run: | + echo "dir=$(npm config get cache)" >> $GITHUB_OUTPUT + id: npm-cache-dir + - uses: actions/cache@v3 + with: + path: ${{ steps.npm-cache-dir.outputs.dir }} + key: ${{ runner.os }}-${{ github.job }}-${{ hashFiles('**/package-lock.json') }} + restore-keys: | + ${{ runner.os }}-${{ github.job }}- + - run: | + npm ci --prefer-offline --no-audit --progress=false + npx playwright install + working-directory: ipfs-webui + - name: Run ipfs-webui@main build and smoke-test to confirm the upstream repo is not broken + run: npm test + working-directory: ipfs-webui + - name: Test ipfs-webui@main E2E against the locally built Kubo binary + run: npm run test:e2e + env: + IPFS_GO_EXEC: ${{ github.workspace }}/cmd/ipfs/ipfs + working-directory: ipfs-webui diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index af9006adf..e12af6b4e 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -1,5 +1,5 @@ # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed -name: "CodeQL" +name: CodeQL on: workflow_dispatch: diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml new file mode 100644 index 000000000..86c50bec7 --- /dev/null +++ b/.github/workflows/docker-build.yml @@ -0,0 +1,25 @@ +name: 'ci/gh-experiment: docker-build' + +on: + workflow_dispatch: + pull_request: + push: + branches: + - 'master' + +jobs: + docker-build: + if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' + runs-on: ubuntu-latest + env: + IMAGE_NAME: ipfs/kubo + WIP_IMAGE_TAG: wip + defaults: + run: + shell: bash + steps: + - uses: actions/setup-go@v3 + with: + go-version: 1.19.1 + - uses: actions/checkout@v3 + - run: docker build -t $IMAGE_NAME:$WIP_IMAGE_TAG . diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index 76e0c1c11..8a90910f7 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -32,7 +32,7 @@ jobs: run: | TAGS="$(./bin/get-docker-tags.sh $(date -u +%F))" TAGS="${TAGS//$'\n'/'%0A'}" - echo "::set-output name=value::$(echo $TAGS)" + echo "value=$(echo $TAGS)" >> $GITHUB_OUTPUT shell: bash - name: Log in to Docker Hub diff --git a/.github/workflows/gobuild.yml b/.github/workflows/gobuild.yml new file mode 100644 index 000000000..edacc269b --- /dev/null +++ b/.github/workflows/gobuild.yml @@ -0,0 +1,39 @@ +name: 'ci/gh-experiment: go build' + +on: + workflow_dispatch: + pull_request: + push: + branches: + - 'master' + +jobs: + runner: + if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' + uses: ipfs/kubo/.github/workflows/runner.yml@ci/move-to-github-actions # TODO: change to master + gobuild: + needs: [runner] + runs-on: ${{ fromJSON(needs.runner.outputs.config).labels }} + env: + TEST_NO_DOCKER: 1 + TEST_VERBOSE: 1 + TRAVIS: 1 + GIT_PAGER: cat + IPFS_CHECK_RCMGR_DEFAULTS: 1 + defaults: + run: + shell: bash + steps: + - uses: actions/setup-go@v3 + with: + go-version: 1.19.1 + - uses: actions/checkout@v3 + - uses: protocol/cache-go-action@v1 + with: + name: ${{ github.job }} + - run: make cmd/ipfs-try-build + env: + TEST_NO_FUSE: 0 + - run: make cmd/ipfs-try-build + env: + TEST_NO_FUSE: 1 diff --git a/.github/workflows/golang-analysis.yml b/.github/workflows/golang-analysis.yml index 3a74e61a2..958ece668 100644 --- a/.github/workflows/golang-analysis.yml +++ b/.github/workflows/golang-analysis.yml @@ -1,8 +1,15 @@ -on: [push, pull_request] name: Go Checks +on: + workflow_dispatch: + pull_request: + push: + branches: + - 'master' + jobs: unit: + if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' runs-on: ubuntu-latest name: All steps: diff --git a/.github/workflows/golint.yml b/.github/workflows/golint.yml new file mode 100644 index 000000000..9623ae4b6 --- /dev/null +++ b/.github/workflows/golint.yml @@ -0,0 +1,32 @@ +name: 'ci/gh-experiment: go lint' + +on: + workflow_dispatch: + pull_request: + push: + branches: + - 'master' + +jobs: + golint: + if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' + runs-on: ubuntu-latest + env: + TEST_NO_DOCKER: 1 + TEST_NO_FUSE: 1 + TEST_VERBOSE: 1 + TRAVIS: 1 + GIT_PAGER: cat + IPFS_CHECK_RCMGR_DEFAULTS: 1 + defaults: + run: + shell: bash + steps: + - uses: actions/setup-go@v3 + with: + go-version: 1.19.1 + - uses: actions/checkout@v3 + - uses: protocol/cache-go-action@v1 + with: + name: ${{ github.job }} + - run: make -O test_go_lint diff --git a/.github/workflows/gotest.yml b/.github/workflows/gotest.yml new file mode 100644 index 000000000..2c50fd3e5 --- /dev/null +++ b/.github/workflows/gotest.yml @@ -0,0 +1,65 @@ +name: 'ci/gh-experiment: go test' + +on: + workflow_dispatch: + pull_request: + push: + branches: + - 'master' + +jobs: + gotest: + if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' + runs-on: ubuntu-latest + env: + TEST_NO_DOCKER: 1 + TEST_NO_FUSE: 1 + TEST_VERBOSE: 1 + TRAVIS: 1 + GIT_PAGER: cat + IPFS_CHECK_RCMGR_DEFAULTS: 1 + defaults: + run: + shell: bash + steps: + - uses: actions/setup-go@v3 + with: + go-version: 1.19.1 + - uses: actions/checkout@v3 + - uses: protocol/cache-go-action@v1 + with: + name: ${{ github.job }} + - run: | + make -j 1 test/unit/gotest.junit.xml && + [[ ! $(jq -s -c 'map(select(.Action == "fail")) | .[]' test/unit/gotest.json) ]] + - uses: codecov/codecov-action@81cd2dc8148241f03f5839d295e000b8f761e378 # v3.1.0 + if: always() + with: + name: unittests + files: coverage/unit_tests.coverprofile + - run: | + # we want to first test with the kubo version in the go.mod file + go test -v ./... + + # we also want to test the examples against the current version of kubo + # however, that version might be in a fork so we need to replace the dependency + + # backup the go.mod and go.sum files to restore them after we run the tests + cp go.mod go.mod.bak + cp go.sum go.sum.bak + + # make sure the examples run against the current version of kubo + go mod edit -replace github.com/ipfs/kubo=./../../.. + go mod tidy + + go test -v ./... + + # restore the go.mod and go.sum files to their original state + mv go.mod.bak go.mod + mv go.sum.bak go.sum + working-directory: docs/examples/kubo-as-a-library + - uses: actions/upload-artifact@v3 + with: + name: unit + path: test/unit/gotest.junit.xml + if: always() diff --git a/.github/workflows/runner.yml b/.github/workflows/runner.yml new file mode 100644 index 000000000..afb4d740d --- /dev/null +++ b/.github/workflows/runner.yml @@ -0,0 +1,33 @@ +name: 'ci/gh-experiment: choose runner' + +on: + workflow_call: + outputs: + config: + description: "The runner's configuration" + value: ${{ jobs.choose.outputs.config }} + +jobs: + choose: + runs-on: ubuntu-latest + outputs: + config: ${{ steps.config.outputs.result }} + steps: + - uses: actions/github-script@v6 + id: config + with: + script: | + if (`${context.repo.owner}/${context.repo.repo}` === 'ipfs/kubo') { + return { + labels: ['self-hosted', 'linux', 'x64', 'kubo'], + parallel: 10, + aws: true + } + } else { + return { + labels: ['ubuntu-latest'], + parallel: 3, + aws: false + } + } + - run: echo ${{ steps.config.outputs.result }} diff --git a/.github/workflows/sharness.yml b/.github/workflows/sharness.yml new file mode 100644 index 000000000..044e55560 --- /dev/null +++ b/.github/workflows/sharness.yml @@ -0,0 +1,124 @@ +name: 'ci/gh-experiment: sharness' + +on: + workflow_dispatch: + pull_request: + push: + branches: + - 'master' + +jobs: + runner: + if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' + uses: ipfs/kubo/.github/workflows/runner.yml@ci/move-to-github-actions # TODO: change to master + sharness: + needs: [runner] + runs-on: ${{ fromJSON(needs.runner.outputs.config).labels }} + defaults: + run: + shell: bash + steps: + - name: Setup Go + uses: actions/setup-go@v3 + with: + go-version: 1.19.1 + - name: Checkout Kubo + uses: actions/checkout@v3 + with: + path: kubo + - name: Install missing tools + run: sudo apt install -y socat net-tools fish libxml2-utils + - name: Checkout IPFS Pinning Service API + uses: actions/checkout@v3 + with: + repository: ipfs-shipyard/rb-pinning-service-api + ref: 773c3adbb421c551d2d89288abac3e01e1f7c3a8 + path: rb-pinning-service-api + # TODO: check if docker compose (not docker-compose) is available on default gh runners + - name: Start IPFS Pinning Service API + run: | + (for i in {1..3}; do docker compose pull && break || sleep 5; done) && + docker compose up -d + working-directory: rb-pinning-service-api + - name: Restore Go Cache + uses: protocol/cache-go-action@v1 + with: + name: ${{ github.job }} + - name: Find IPFS Pinning Service API address + run: echo "TEST_DOCKER_HOST=$(ip -4 addr show docker0 | grep -Po 'inet \K[\d.]+')" >> $GITHUB_ENV + - uses: actions/cache@v3 + with: + path: test/sharness/lib/dependencies + key: ${{ runner.os }}-test-generate-junit-html-${{ hashFiles('test/sharness/lib/test-generate-junit-html.sh') }} + - name: Run Sharness tests + run: | + make -O -j "$PARALLEL" \ + test_sharness \ + coverage/sharness_tests.coverprofile \ + test/sharness/test-results/sharness.xml \ + test/sharness/test-results/sharness.html \ + test/sharness/test-results/sharness-html + working-directory: kubo + env: + TEST_NO_DOCKER: 0 + TEST_NO_PLUGIN: 1 + TEST_NO_FUSE: 1 + TEST_VERBOSE: 1 + TEST_JUNIT: 1 + TEST_EXPENSIVE: 1 + IPFS_CHECK_RCMGR_DEFAULTS: 1 + CONTINUE_ON_S_FAILURE: 1 + PARALLEL: ${{ fromJSON(needs.runner.outputs.config).parallel }} + - name: Upload coverage report + uses: codecov/codecov-action@81cd2dc8148241f03f5839d295e000b8f761e378 # v3.1.0 + if: failure() || success() + with: + name: sharness + files: kubo/coverage/sharness_tests.coverprofile + - name: Aggregate results + run: find kubo/test/sharness/test-results -name 't*-*.sh.*.counts' | kubo/test/sharness/lib/sharness/aggregate-results.sh > kubo/test/sharness/test-results/summary.txt + - name: 👉️ If this step failed, go to «Summary» (top left) → «HTML Report» → inspect the «Failures» column + run: | + cat kubo/test/sharness/test-results/summary.txt && + grep 'failed\s*0' kubo/test/sharness/test-results/summary.txt + - name: Add aggregate results to the summary + if: failure() || success() + run: | + echo "# Summary" >> $GITHUB_STEP_SUMMARY + echo >> $GITHUB_STEP_SUMMARY + cat kubo/test/sharness/test-results/summary.txt >> $GITHUB_STEP_SUMMARY + - name: Upload one-page HTML report to S3 + id: one-page + uses: pl-strflt/tf-aws-gh-runner/.github/actions/upload-artifact@main + if: fromJSON(needs.runner.outputs.config).aws && (failure() || success()) + with: + source: kubo/test/sharness/test-results/sharness.html + destination: sharness.html + - name: Upload one-page HTML report + if: (! fromJSON(needs.runner.outputs.config).aws) && (failure() || success()) + uses: actions/upload-artifact@v3 + with: + name: sharness.html + path: kubo/test/sharness/test-results/sharness.html + - name: Upload full HTML report to S3 + id: full + uses: pl-strflt/tf-aws-gh-runner/.github/actions/upload-artifact@main + if: fromJSON(needs.runner.outputs.config).aws && (failure() || success()) + with: + source: kubo/test/sharness/test-results/sharness-html + destination: sharness-html/ + - name: Upload full HTML report + if: (! fromJSON(needs.runner.outputs.config).aws) && (failure() || success()) + uses: actions/upload-artifact@v3 + with: + name: sharness-html + path: kubo/test/sharness/test-results/sharness-html + - name: Add S3 links to the summary + if: fromJSON(needs.runner.outputs.config).aws && (failure() || success()) + run: echo "$MD" >> $GITHUB_STEP_SUMMARY + env: + MD: | + # HTML Reports + + - View the [one page HTML report](${{ steps.one-page.outputs.url }}) + - View the [full HTML report](${{ steps.full.outputs.url }}index.html) diff --git a/Rules.mk b/Rules.mk index 3d6f621cc..f7e962549 100644 --- a/Rules.mk +++ b/Rules.mk @@ -136,8 +136,7 @@ help: @echo ' test_go_expensive - Run all go tests and compile on all platforms' @echo ' test_go_race - Run go tests with the race detector enabled' @echo ' test_go_lint - Run the `golangci-lint` vetting tool' - @echo ' test_sharness_short - Run short sharness tests' - @echo ' test_sharness_expensive - Run all sharness tests' + @echo ' test_sharness - Run sharness tests' @echo ' coverage - Collects coverage info from unit tests and sharness' @echo .PHONY: help diff --git a/appveyor.yml b/appveyor.yml index 696102ffc..5f2907d00 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -14,8 +14,8 @@ environment: GOPATH: c:\gopath TEST_VERBOSE: 1 #TEST_NO_FUSE: 1 - #TEST_SUITE: test_sharness_expensive - #GOFLAGS: -tags nofuse + #TEST_SUITE: test_sharness + #GOFLAGS: -tags nofuse global: BASH: C:\cygwin\bin\bash matrix: @@ -23,27 +23,27 @@ environment: GOVERSION: 1.5.1 GOROOT: c:\go DOWNLOADPLATFORM: "x64" - + install: # Enable make #- SET PATH=c:\MinGW\bin;%PATH% #- copy c:\MinGW\bin\mingw32-make.exe c:\MinGW\bin\make.exe - go version - go env - + # Cygwin build script # # NOTES: # # The stdin/stdout file descriptor appears not to be valid for the Appveyor -# build which causes failures as certain functions attempt to redirect +# build which causes failures as certain functions attempt to redirect # default file handles. Ensure a dummy file descriptor is opened with 'exec'. -# +# build_script: - '%BASH% -lc "cd $APPVEYOR_BUILD_FOLDER; exec 0 $@ diff --git a/test/sharness/.gitignore b/test/sharness/.gitignore index c7ab08146..b9a5a21ae 100644 --- a/test/sharness/.gitignore +++ b/test/sharness/.gitignore @@ -1,5 +1,14 @@ +# symlinks to lib/sharness +/sharness.sh +/lib-sharness +# clone of sharness lib/sharness/ +# deps downloaded by lib/*.sh scripts +lib/dependencies/ +# sharness files test-results/ trash directory.*.sh/ +# makefile files plugins +# macos files *.DS_Store diff --git a/test/sharness/README.md b/test/sharness/README.md index 16cb508c1..9358fcf9c 100644 --- a/test/sharness/README.md +++ b/test/sharness/README.md @@ -1,4 +1,4 @@ -# ipfs whole tests using the [sharness framework](https://github.com/mlafeldt/sharness/) +# ipfs whole tests using the [sharness framework](https://github.com/pl-strflt/sharness/tree/feat/junit) ## Running all the tests diff --git a/test/sharness/Rules.mk b/test/sharness/Rules.mk index 49e41824c..3b7708b60 100644 --- a/test/sharness/Rules.mk +++ b/test/sharness/Rules.mk @@ -42,10 +42,20 @@ $(d)/aggregate: $(T_$(d)) @(cd $(@D) && ./lib/test-aggregate-results.sh) .PHONY: $(d)/aggregate -$(d)/test-results/sharness.xml: export TEST_GENERATE_JUNIT=1 -$(d)/test-results/sharness.xml: test_sharness_expensive +$(d)/test-results/sharness.xml: $(T_$(d)) @echo "*** $@ ***" - @(cd $(@D)/.. && ./lib/gen-junit-report.sh) + @(cd $(@D)/.. && ./lib/test-aggregate-junit-reports.sh) +.PHONY: $(d)/test-results/sharness.xml + +$(d)/test-results/sharness-html: $(d)/test-results/sharness.xml + @echo "*** $@ ***" + @(cd $(@D)/.. && ./lib/test-generate-junit-html.sh frames) +.PHONY: $(d)/test-results/sharness-html + +$(d)/test-results/sharness.html: $(d)/test-results/sharness.xml + @echo "*** $@ ***" + @(cd $(@D)/.. && ./lib/test-generate-junit-html.sh no-frames) +.PHONY: $(d)/test-results/sharness.html $(d)/clean-test-results: rm -rf $(@D)/test-results @@ -62,16 +72,10 @@ $(d)/deps: $(SHARNESS_$(d)) $$(DEPS_$(d)) # use second expansion so coverage can test_sharness_deps: $(d)/deps .PHONY: test_sharness_deps -test_sharness_short: $(d)/aggregate -.PHONY: test_sharness_short +test_sharness: $(d)/aggregate +.PHONY: test_sharness - -test_sharness_expensive: export TEST_EXPENSIVE=1 -test_sharness_expensive: test_sharness_short -.PHONY: test_sharness_expensive - -TEST += test_sharness_expensive -TEST_SHORT += test_sharness_short +TEST += test_sharness include mk/footer.mk diff --git a/test/sharness/lib/0001-Generate-partial-JUnit-reports.patch b/test/sharness/lib/0001-Generate-partial-JUnit-reports.patch deleted file mode 100644 index 1a8b5f21b..000000000 --- a/test/sharness/lib/0001-Generate-partial-JUnit-reports.patch +++ /dev/null @@ -1,250 +0,0 @@ -From bc6bf844ef4e4cd468bc1ec96f2d6af738eb8d2f Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?=C5=81ukasz=20Magiera?= -Date: Sat, 21 Apr 2018 22:01:45 +0200 -Subject: [PATCH] Generate partial JUnit reports - ---- - sharness.sh | 114 +++++++++++++++++++++++++++++++++++++++++++++++++--- - 1 file changed, 108 insertions(+), 6 deletions(-) - -diff --git a/sharness.sh b/sharness.sh -index 6750ff7..336e426 100644 ---- a/sharness.sh -+++ b/sharness.sh -@@ -1,4 +1,4 @@ --#!/bin/sh -+#!/usr/bin/env bash - # - # Copyright (c) 2011-2012 Mathias Lafeldt - # Copyright (c) 2005-2012 Git project -@@ -106,6 +106,10 @@ if test -n "$color"; then - test -n "$quiet" && return;; - esac - shift -+ -+ if test -n "$TEST_GENERATE_JUNIT"; then -+ echo "$*" >> .junit/tout -+ fi - printf "%s" "$*" - tput sgr0 - echo -@@ -115,6 +119,10 @@ else - say_color() { - test -z "$1" && test -n "$quiet" && return - shift -+ -+ if test -n "$TEST_GENERATE_JUNIT"; then -+ echo "$*" >> .junit/tout -+ fi - printf "%s\n" "$*" - } - fi -@@ -129,6 +137,12 @@ say() { - say_color info "$*" - } - -+esc=$(printf '\033') -+ -+esc_xml() { -+ sed 's/&/\&/g; s//\>/g; s/"/\"/g; s/'"$esc"'//g; s///g;' -+} -+ - test -n "$test_description" || error "Test script did not set test_description." - - if test "$help" = "t"; then -@@ -251,30 +265,78 @@ test_have_prereq() { - test $total_prereq = $ok_prereq - } - -+# junit_testcase generates a testcase xml file after each test -+ -+junit_testcase() { -+ if test -z "$TEST_GENERATE_JUNIT"; then -+ return -+ fi -+ -+ test_name=$1 -+ tc_file=".junit/case-$(printf "%04d" $test_count)" -+ time_sec="$(cat .junit/time | xargs printf '%04d' | sed -e 's/\(...\)$/.\1/g')" -+ -+ echo "$(expr $(cat .junit/time_total) + $(cat .junit/time) )" > .junit/time_total -+ -+ shift -+ cat > "$tc_file" <<-EOF -+ -+ $@ -+ EOF -+ -+ if test -f .junit/tout; then -+ cat >> "$tc_file" <<-EOF -+ -+ $(cat .junit/tout | esc_xml) -+ -+ EOF -+ fi -+ -+ if test -f .junit/terr; then -+ cat >> "$tc_file" <<-EOF -+ -+ $(cat .junit/terr | esc_xml) -+ -+ EOF -+ fi -+ -+ echo "" >> "$tc_file" -+ rm -f .junit/tout .junit/terr .junit/time -+} -+ - # You are not expected to call test_ok_ and test_failure_ directly, use - # the text_expect_* functions instead. - - test_ok_() { - test_success=$(($test_success + 1)) - say_color "" "ok $test_count - $@" -+ -+ junit_testcase "$@" - } - - test_failure_() { - test_failure=$(($test_failure + 1)) - say_color error "not ok $test_count - $1" -+ test_name=$1 - shift - echo "$@" | sed -e 's/^/# /' -+ junit_testcase "$test_name" ''$(echo $@ | esc_xml)'' -+ - test "$immediate" = "" || { EXIT_OK=t; exit 1; } - } - - test_known_broken_ok_() { - test_fixed=$(($test_fixed + 1)) - say_color error "ok $test_count - $@ # TODO known breakage vanished" -+ -+ junit_testcase "$@" '' - } - - test_known_broken_failure_() { - test_broken=$(($test_broken + 1)) - say_color warn "not ok $test_count - $@ # TODO known breakage" -+ -+ junit_testcase "$@" - } - - # Public: Execute commands in debug mode. -@@ -310,15 +372,25 @@ test_pause() { - test_eval_() { - # This is a separate function because some tests use - # "return" to end a test_expect_success block early. -- eval &3 2>&4 "$*" -+ if test -n "$TEST_GENERATE_JUNIT"; then -+ eval >(tee -a .junit/tout >&3) 2> >(tee -a .junit/terr >&4) "$*" -+ else -+ eval &3 2>&4 "$*" -+ fi - } - - test_run_() { - test_cleanup=: - expecting_failure=$2 -+ -+ start_time_ms=$(date "+%s%3N"); - test_eval_ "$1" - eval_ret=$? - -+ if test -n "$TEST_GENERATE_JUNIT"; then -+ echo $(expr $(date "+%s%3N") - ${start_time_ms} ) > .junit/time; -+ fi -+ - if test "$chain_lint" = "t"; then - test_eval_ "(exit 117) && $1" - if test "$?" != 117; then -@@ -355,8 +427,18 @@ test_skip_() { - of_prereq=" of $test_prereq" - fi - -- say_color skip >&3 "skipping test: $@" -- say_color skip "ok $test_count # skip $1 (missing $missing_prereq${of_prereq})" -+ say_color skip >&3 "skipping test: $1" -+ say_color skip "ok $test_count # skip $1 (missing $missing_prereqm${of_prereq})" -+ -+ if test -n "$TEST_GENERATE_JUNIT"; then -+ cat > ".junit/case-$(printf "%04d" $test_count)" <<-EOF -+ -+ -+ skip $(echo $1 | esc_xml) (missing $missing_prereq${of_prereq}) -+ -+ -+ EOF -+ fi - : true - ;; - *) -@@ -403,7 +485,7 @@ test_expect_success() { - test "$#" = 3 && { test_prereq=$1; shift; } || test_prereq= - test "$#" = 2 || error "bug in the test script: not 2 or 3 parameters to test_expect_success" - export test_prereq -- if ! test_skip_ "$@"; then -+ if ! test_skip_ "$@" "$1"; then - say >&3 "expecting success: $2" - if test_run_ "$2"; then - test_ok_ "$1" -@@ -442,7 +524,7 @@ test_expect_failure() { - test "$#" = 3 && { test_prereq=$1; shift; } || test_prereq= - test "$#" = 2 || error "bug in the test script: not 2 or 3 parameters to test_expect_failure" - export test_prereq -- if ! test_skip_ "$@"; then -+ if ! test_skip_ "$@" "$1"; then - say >&3 "checking known breakage: $2" - if test_run_ "$2" expecting_failure; then - test_known_broken_ok_ "$1" -@@ -675,6 +757,7 @@ test_done() { - test_results_dir="$SHARNESS_TEST_DIRECTORY/test-results" - mkdir -p "$test_results_dir" - test_results_path="$test_results_dir/${SHARNESS_TEST_FILE%.$SHARNESS_TEST_EXTENSION}.$$.counts" -+ junit_results_path="$test_results_dir/${SHARNESS_TEST_FILE%.$SHARNESS_TEST_EXTENSION}.$$.xml.part" - - cat >>"$test_results_path" <<-EOF - total $test_count -@@ -684,6 +767,16 @@ test_done() { - failed $test_failure - - EOF -+ -+ if test -n "$TEST_GENERATE_JUNIT"; then -+ time_sec="$(cat .junit/time_total | xargs printf "%04d" | sed -e 's/\(...\)$/.\1/g')" -+ -+ cat >>"$junit_results_path" <<-EOF -+ -+ $(find .junit -name 'case-*' | sort | xargs cat) -+ -+ EOF -+ fi - fi - - if test "$test_fixed" != 0; then -@@ -745,6 +838,9 @@ export PATH SHARNESS_BUILD_DIRECTORY - SHARNESS_TEST_FILE="$0" - export SHARNESS_TEST_FILE - -+SHARNESS_TEST_NAME=$(basename ${SHARNESS_TEST_FILE} ".sh") -+export SHARNESS_TEST_NAME -+ - # Prepare test area. - test_dir="trash directory.$(basename "$SHARNESS_TEST_FILE" ".$SHARNESS_TEST_EXTENSION")" - test -n "$root" && test_dir="$root/$test_dir" -@@ -771,6 +867,12 @@ mkdir -p "$test_dir" || exit 1 - # in subprocesses like git equals our $PWD (for pathname comparisons). - cd -P "$test_dir" || exit 1 - -+# Prepare JUnit report dir -+if test -n "$TEST_GENERATE_JUNIT"; then -+ mkdir -p .junit -+ echo 0 > .junit/time_total -+fi -+ - this_test=${SHARNESS_TEST_FILE##*/} - this_test=${this_test%.$SHARNESS_TEST_EXTENSION} - for skp in $SKIP_TESTS; do --- -2.17.0 - diff --git a/test/sharness/lib/gen-junit-report.sh b/test/sharness/lib/gen-junit-report.sh deleted file mode 100755 index c69f39adb..000000000 --- a/test/sharness/lib/gen-junit-report.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env bash - -cat > test-results/sharness.xml <<-EOF - - - $(find test-results -name '*.xml.part' | sort | xargs cat) - -EOF diff --git a/test/sharness/lib/install-sharness.sh b/test/sharness/lib/install-sharness.sh index ac6cb2f74..41b27188c 100755 --- a/test/sharness/lib/install-sharness.sh +++ b/test/sharness/lib/install-sharness.sh @@ -1,60 +1,50 @@ #!/bin/sh # install sharness.sh # -# Copyright (c) 2014 Juan Batiz-Benet +# Copyright (c) 2014, 2022 Juan Batiz-Benet, Piotr Galar # MIT Licensed; see the LICENSE file in this repository. # -# settings -version=5eee9b51b5621cec95a64018f0cc779963b230d2 -patch_version=17 +gitrepo=pl-strflt/sharness +githash=803df39d3cba16bb7d493dd6cd8bc5e29826da61 -urlprefix=https://github.com/mlafeldt/sharness.git if test ! -n "$clonedir" ; then clonedir=lib fi sharnessdir=sharness - -if test -f "$clonedir/$sharnessdir/SHARNESS_VERSION_${version}_p${patch_version}" -then - # There is the right version file. Great, we are done! - exit 0 -fi +gitdir="$clonedir/$sharnessdir/.git" die() { echo >&2 "$@" exit 1 } -apply_patches() { - git config --local user.email "noone@nowhere" - git config --local user.name "No One" - git am ../0001-Generate-partial-JUnit-reports.patch - - touch "SHARNESS_VERSION_${version}_p${patch_version}" || die "Could not create 'SHARNESS_VERSION_${version}_p${patch_version}'" -} - -checkout_version() { - git checkout "$version" || die "Could not checkout '$version'" - rm -f SHARNESS_VERSION_* || die "Could not remove 'SHARNESS_VERSION_*'" - echo "Sharness version $version is checked out!" - - apply_patches -} - -if test -d "$clonedir/$sharnessdir/.git" -then - # We need to update sharness! - cd "$clonedir/$sharnessdir" || die "Could not cd into '$clonedir/$sharnessdir' directory" - git fetch || die "Could not fetch to update sharness" - checkout_version -else - # We need to clone sharness! - mkdir -p "$clonedir" || die "Could not create '$clonedir' directory" - cd "$clonedir" || die "Could not cd into '$clonedir' directory" - - git clone "$urlprefix" || die "Could not clone '$urlprefix'" - cd "$sharnessdir" || die "Could not cd into '$sharnessdir' directory" - checkout_version +if test -d "$clonedir/$sharnessdir"; then + giturl="git@github.com:${gitrepo}.git" + echo "Checking if $giturl is already cloned (and if its origin is correct)" + if ! test -d "$gitdir" || test "$(git --git-dir "$gitdir" remote get-url origin)" != "$giturl"; then + echo "Removing $clonedir/$sharnessdir" + rm -rf "$clonedir/$sharnessdir" || die "Could not remove $clonedir/$sharnessdir" + fi fi + +if ! test -d "$clonedir/$sharnessdir"; then + giturl="https://github.com/${gitrepo}.git" + echo "Cloning $giturl into $clonedir/$sharnessdir" + git clone "$giturl" "$clonedir/$sharnessdir" || die "Could not clone $giturl into $clonedir/$sharnessdir" +fi + + +echo "Changing directory to $clonedir/$sharnessdir" +cd "$clonedir/$sharnessdir" || die "Could not cd into '$clonedir/$sharnessdir' directory" + +echo "Checking if $githash is already fetched" +if ! git show "$githash" >/dev/null 2>&1; then + echo "Fetching $githash" + git fetch origin "$githash" || die "Could not fetch $githash" +fi + +echo "Resetting to $githash" +git reset --hard "$githash" || die "Could not reset to $githash" + exit 0 diff --git a/test/sharness/lib/test-aggregate-junit-reports.sh b/test/sharness/lib/test-aggregate-junit-reports.sh new file mode 100755 index 000000000..ad39e5668 --- /dev/null +++ b/test/sharness/lib/test-aggregate-junit-reports.sh @@ -0,0 +1,17 @@ +#!/bin/sh +# +# Script to aggregate results using Sharness +# +# Copyright (c) 2014, 2022 Christian Couder, Piotr Galar +# MIT Licensed; see the LICENSE file in this repository. +# + +SHARNESS_AGGREGATE_JUNIT="lib/sharness/aggregate-junit-reports.sh" + +test -f "$SHARNESS_AGGREGATE_JUNIT" || { + echo >&2 "Cannot find: $SHARNESS_AGGREGATE_JUNIT" + echo >&2 "Please check Sharness installation." + exit 1 +} + +ls test-results/t*-*.sh.*.xml.part | "$SHARNESS_AGGREGATE_JUNIT" > test-results/sharness.xml diff --git a/test/sharness/lib/test-generate-junit-html.sh b/test/sharness/lib/test-generate-junit-html.sh new file mode 100755 index 000000000..cc18762cb --- /dev/null +++ b/test/sharness/lib/test-generate-junit-html.sh @@ -0,0 +1,58 @@ +#!/bin/bash + +dependencies=( + "url=https://sourceforge.net/projects/saxon/files/Saxon-HE/11/Java/SaxonHE11-4J.zip;md5=8a4783d307c32c898f8995b8f337fd6b" + "url=https://raw.githubusercontent.com/pl-strflt/ant/c781f7d79b92cc55530245d9554682a47f46851e/src/etc/junit-frames-saxon.xsl;md5=6eb013566903a91e4959413f6ff144d0" + "url=https://raw.githubusercontent.com/pl-strflt/ant/c781f7d79b92cc55530245d9554682a47f46851e/src/etc/junit-noframes-saxon.xsl;md5=8d54882d5f9d32a7743ec675cc2e30ac" +) + +dependenciesdir="lib/dependencies" +mkdir -p "$dependenciesdir" + +get_md5() { + md5sum "$1" | cut -d ' ' -f 1 +} + +for dependency in "${dependencies[@]}"; do + url="$(echo "$dependency" | cut -d ';' -f 1 | cut -d '=' -f 2)" + md5="$(echo "$dependency" | cut -d ';' -f 2 | cut -d '=' -f 2)" + filename="$(basename "$url")" + if test -f "$dependenciesdir/$filename" && test "$(get_md5 "$dependenciesdir/$filename")" = "$md5"; then + echo "Using cached $filename" + else + echo "Downloading $filename" + curl -L --max-redirs 5 --retry 5 --no-progress-meter --output "$dependenciesdir/$filename" "$url" + actual_md5="$(get_md5 "$dependenciesdir/$filename")" + if test "$actual_md5" != "$md5"; then + echo "Downloaded $filename has wrong md5sum ('$actual_md5' != '$md5')" + exit 1 + fi + dirname=${filename%.*} + extension=${filename#$dirname.} + if test "$extension" = "zip"; then + echo "Removing old $dependenciesdir/$dirname" + rm -rf "$dependenciesdir/$dirname" + echo "Unzipping $dependenciesdir/$filename" + unzip "$dependenciesdir/$filename" -d "$dependenciesdir/$dirname" + fi + fi +done + +case "$1" in + "frames") + java -jar lib/dependencies/SaxonHE11-4J/saxon-he-11.4.jar \ + -s:test-results/sharness.xml \ + -xsl:lib/dependencies/junit-frames-saxon.xsl \ + output.dir=$(pwd)/test-results/sharness-html + ;; + "no-frames") + java -jar lib/dependencies/SaxonHE11-4J/saxon-he-11.4.jar \ + -s:test-results/sharness.xml \ + -xsl:lib/dependencies/junit-noframes-saxon.xsl \ + -o:test-results/sharness.html + ;; + *) + echo "Usage: $0 [frames|no-frames]" + exit 1 + ;; +esac diff --git a/test/sharness/lib/test-lib.sh b/test/sharness/lib/test-lib.sh index 0757c323c..4ce2a6027 100644 --- a/test/sharness/lib/test-lib.sh +++ b/test/sharness/lib/test-lib.sh @@ -3,7 +3,7 @@ # Copyright (c) 2014 Christian Couder # MIT Licensed; see the LICENSE file in this repository. # -# We are using sharness (https://github.com/mlafeldt/sharness) +# We are using sharness (https://github.com/pl-strflt/sharness/tree/feat/junit) # which was extracted from the Git test framework. # use the ipfs tool to test against @@ -27,14 +27,17 @@ fi # to pass through in some cases. test "$TEST_VERBOSE" = 1 && verbose=t test "$TEST_IMMEDIATE" = 1 && immediate=t +test "$TEST_JUNIT" = 1 && junit=t +test "$TEST_NO_COLOR" = 1 && no_color=t # source the common hashes first. . lib/test-lib-hashes.sh -SHARNESS_LIB="lib/sharness/sharness.sh" +ln -sf lib/sharness/sharness.sh . +ln -sf lib/sharness/lib-sharness . -. "$SHARNESS_LIB" || { - echo >&2 "Cannot source: $SHARNESS_LIB" +. "sharness.sh" || { + echo >&2 "Cannot source: sharness.sh" echo >&2 "Please check Sharness installation." exit 1 } @@ -106,10 +109,15 @@ expr "$TEST_OS" : "CYGWIN_NT" >/dev/null || test_set_prereq STD_ERR_MSG if test "$TEST_VERBOSE" = 1; then echo '# TEST_VERBOSE='"$TEST_VERBOSE" + echo '# TEST_IMMEDIATE='"$TEST_IMMEDIATE" echo '# TEST_NO_FUSE='"$TEST_NO_FUSE" + echo '# TEST_NO_DOCKER='"$TEST_NO_DOCKER" echo '# TEST_NO_PLUGIN='"$TEST_NO_PLUGIN" echo '# TEST_EXPENSIVE='"$TEST_EXPENSIVE" echo '# TEST_OS='"$TEST_OS" + echo '# TEST_JUNIT='"$TEST_JUNIT" + echo '# TEST_NO_COLOR='"$TEST_NO_COLOR" + echo '# TEST_ULIMIT_PRESET='"$TEST_ULIMIT_PRESET" fi # source our generic test lib @@ -541,4 +549,3 @@ purge_blockstore() { [[ -z "$( ipfs repo gc )" ]] ' } - diff --git a/test/sharness/t0110-gateway.sh b/test/sharness/t0110-gateway.sh index 87aa61c70..5244bd214 100755 --- a/test/sharness/t0110-gateway.sh +++ b/test/sharness/t0110-gateway.sh @@ -121,14 +121,14 @@ test_expect_success "GET invalid IPNS root returns 400 (Bad Request)" ' test_curl_resp_http_code "http://127.0.0.1:$port/ipns/QmInvalid/pleaseDontAddMe" "HTTP/1.1 400 Bad Request" ' -test_expect_failure "GET IPNS path succeeds" ' +test_expect_success "GET IPNS path succeeds" ' ipfs name publish --allow-offline "$HASH" && PEERID=$(ipfs config Identity.PeerID) && test_check_peerid "$PEERID" && curl -sfo actual "http://127.0.0.1:$port/ipns/$PEERID" ' -test_expect_failure "GET IPNS path output looks good" ' +test_expect_success "GET IPNS path output looks good" ' test_cmp expected actual ' diff --git a/test/sharness/t0118-gateway-car.sh b/test/sharness/t0118-gateway-car.sh index 3d8d7b08f..62b2725d0 100755 --- a/test/sharness/t0118-gateway-car.sh +++ b/test/sharness/t0118-gateway-car.sh @@ -111,7 +111,7 @@ test_launch_ipfs_daemon_without_network ' test_expect_success "GET for application/vnd.ipld.car with query filename includes Content-Disposition with custom filename" ' - curl -svX GET -H "Accept: application/vnd.ipld.car" "http://127.0.0.1:$GWAY_PORT/ipfs/$ROOT_DIR_CID/subdir/ascii.txt?filename=foobar.car" > curl_output_filename 2>&1 && + curl -svX GET -H "Accept: application/vnd.ipld.car" "http://127.0.0.1:$GWAY_PORT/ipfs/$ROOT_DIR_CID/subdir/ascii.txt?filename=foobar.car" >/dev/null 2>curl_output_filename && cat curl_output_filename && grep "< Content-Disposition: attachment\; filename=\"foobar.car\"" curl_output_filename ' diff --git a/test/sharness/t0125-twonode.sh b/test/sharness/t0125-twonode.sh index dcf5c88ce..8ea1c9e5d 100755 --- a/test/sharness/t0125-twonode.sh +++ b/test/sharness/t0125-twonode.sh @@ -72,6 +72,12 @@ flaky_advanced_test() { test_expect_success "shut down nodes" ' iptb stop && iptb_wait_stop ' + + # NOTE: data transferred stats checks are flaky + # trying to debug them by printing out the stats hides the flakiness + # my theory is that the extra time cat calls take to print out the stats + # allow for proper cleanup to happen + go-sleep 1s } run_advanced_test() { diff --git a/test/sharness/t0160-resolve.sh b/test/sharness/t0160-resolve.sh index ca11947b0..f65b29c11 100755 --- a/test/sharness/t0160-resolve.sh +++ b/test/sharness/t0160-resolve.sh @@ -35,15 +35,6 @@ test_resolve_setup_name() { ' } -test_resolve_setup_name_fail() { - local key="$1" - local ref="$2" - - test_expect_failure "resolve: prepare $key" ' - ipfs name publish --key="$key" --allow-offline "$ref" - ' -} - test_resolve() { src=$1 dst=$2 @@ -129,23 +120,7 @@ test_resolve_cmd_b32() { ' } - -#todo remove this once the online resolve is fixed -test_resolve_fail() { - src=$1 - dst=$2 - - test_expect_failure "resolve succeeds: $src" ' - ipfs resolve "$src" >actual - ' - - test_expect_failure "resolved correctly: $src -> $dst" ' - printf "$dst" >expected && - test_cmp expected actual - ' -} - -test_resolve_cmd_fail() { +test_resolve_cmd_success() { test_resolve "/ipfs/$a_hash" "/ipfs/$a_hash" test_resolve "/ipfs/$a_hash/b" "/ipfs/$b_hash" test_resolve "/ipfs/$a_hash/b/c" "/ipfs/$c_hash" @@ -155,23 +130,16 @@ test_resolve_cmd_fail() { test_resolve "/ipld/$dag_hash/i/j" "/ipld/$dag_hash/i/j" test_resolve "/ipld/$dag_hash/i" "/ipld/$dag_hash/i" - # At the moment, publishing _fails_ because we fail to put to the DHT. - # However, resolving succeeds because we resolve the record we put to our own - # node. - # - # We should find a nice way to truly support offline publishing. But this - # behavior isn't terrible. - - test_resolve_setup_name_fail "self" "/ipfs/$a_hash" + test_resolve_setup_name "self" "/ipfs/$a_hash" test_resolve "/ipns/$self_hash" "/ipfs/$a_hash" test_resolve "/ipns/$self_hash/b" "/ipfs/$b_hash" test_resolve "/ipns/$self_hash/b/c" "/ipfs/$c_hash" - test_resolve_setup_name_fail "self" "/ipfs/$b_hash" + test_resolve_setup_name "self" "/ipfs/$b_hash" test_resolve "/ipns/$self_hash" "/ipfs/$b_hash" test_resolve "/ipns/$self_hash/c" "/ipfs/$c_hash" - test_resolve_setup_name_fail "self" "/ipfs/$c_hash" + test_resolve_setup_name "self" "/ipfs/$c_hash" test_resolve "/ipns/$self_hash" "/ipfs/$c_hash" } @@ -181,7 +149,7 @@ test_resolve_cmd_b32 # should work online test_launch_ipfs_daemon -test_resolve_cmd_fail +test_resolve_cmd_success test_kill_ipfs_daemon test_done diff --git a/test/sharness/t0300-docker-image.sh b/test/sharness/t0300-docker-image.sh index a3a802b28..3c390a453 100755 --- a/test/sharness/t0300-docker-image.sh +++ b/test/sharness/t0300-docker-image.sh @@ -79,9 +79,9 @@ test_expect_success "check that init script configs were applied" ' ' test_expect_success "simple ipfs add/cat can be run in docker container" ' - expected="Hello Worlds" && - HASH=$(docker_exec "$DOC_ID" "echo $(cat expected) | ipfs add | cut -d' ' -f2") && - docker_exec "$DOC_ID" "ipfs cat $HASH" >actual && + echo "Hello Worlds" | tr -d "[:cntrl:]" > expected && + HASH=$(docker_exec "$DOC_ID" "echo $(cat expected) | ipfs add -q" | tr -d "[:cntrl:]") && + docker_exec "$DOC_ID" "ipfs cat $HASH" | tr -d "[:cntrl:]" > actual && test_cmp expected actual ' @@ -102,4 +102,3 @@ test_expect_success "stop docker container" ' docker_rm "$DOC_ID" docker_rmi "$IMAGE_ID" test_done - From cab044171d28dbe5ae8857a4bec0d80d30910ad1 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Sat, 14 Jan 2023 01:08:42 +0100 Subject: [PATCH 0381/1212] chore: switch actions to master --- .github/workflows/gobuild.yml | 2 +- .github/workflows/sharness.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/gobuild.yml b/.github/workflows/gobuild.yml index edacc269b..91147a7d3 100644 --- a/.github/workflows/gobuild.yml +++ b/.github/workflows/gobuild.yml @@ -10,7 +10,7 @@ on: jobs: runner: if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' - uses: ipfs/kubo/.github/workflows/runner.yml@ci/move-to-github-actions # TODO: change to master + uses: ipfs/kubo/.github/workflows/runner.yml gobuild: needs: [runner] runs-on: ${{ fromJSON(needs.runner.outputs.config).labels }} diff --git a/.github/workflows/sharness.yml b/.github/workflows/sharness.yml index 044e55560..74810eeaa 100644 --- a/.github/workflows/sharness.yml +++ b/.github/workflows/sharness.yml @@ -10,7 +10,7 @@ on: jobs: runner: if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' - uses: ipfs/kubo/.github/workflows/runner.yml@ci/move-to-github-actions # TODO: change to master + uses: ipfs/kubo/.github/workflows/runner.yml sharness: needs: [runner] runs-on: ${{ fromJSON(needs.runner.outputs.config).labels }} From b74377c6f899c03e961529e7e146a6ff7af5ee4d Mon Sep 17 00:00:00 2001 From: Antonio Navarro Perez Date: Sat, 14 Jan 2023 01:30:48 +0100 Subject: [PATCH 0382/1212] docs: improve docs/README (#9539) Avoid confusion about what kind of documentation we have on this folder. --- docs/README.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/docs/README.md b/docs/README.md index 78235622a..ab7ac9cc3 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,11 +1,17 @@ # Developer Documentation and Guides -If you are looking for User Documentation & Guides, please visit [docs.ipfs.tech](https://docs.ipfs.tech/). +If you are looking for User Documentation & Guides, please visit [docs.ipfs.tech](https://docs.ipfs.tech/) or check [General Documentation](#general-documentation). If you’re experiencing an issue with IPFS, **please follow [our issue guide](github-issue-guide.md) when filing an issue!** Otherwise, check out the following guides to using and developing IPFS: +## General Documentation + +- [Configuration reference](config.md) + - [Datastore configuration](datastores.md) + - [Experimental features](experimental-features.md) + ## Developing `kubo` - First, please read the Contributing Guidelines [for IPFS projects](https://github.com/ipfs/community/blob/master/CONTRIBUTING.md) and then the Contributing Guidelines for [Go code specifically](https://github.com/ipfs/community/blob/master/CONTRIBUTING_GO.md) @@ -22,9 +28,6 @@ Otherwise, check out the following guides to using and developing IPFS: ## Advanced User Guides - [Transferring a File Over IPFS](file-transfer.md) -- [Configuration reference](config.md) - - [Datastore configuration](datastores.md) - - [Experimental features](experimental-features.md) - [Installing command completion](command-completion.md) - [Mounting IPFS with FUSE](fuse.md) - [Installing plugins](plugins.md) From c9ec418e7161baeb382c703508d3914fea8f8248 Mon Sep 17 00:00:00 2001 From: galargh Date: Sat, 14 Jan 2023 11:29:55 +0100 Subject: [PATCH 0383/1212] fix: docker image publishing --- .github/workflows/docker-image.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index 8a90910f7..27f6b71b5 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -30,9 +30,9 @@ jobs: - name: Get tags id: tags run: | - TAGS="$(./bin/get-docker-tags.sh $(date -u +%F))" - TAGS="${TAGS//$'\n'/'%0A'}" - echo "value=$(echo $TAGS)" >> $GITHUB_OUTPUT + echo "value=<> $GITHUB_OUTPUT + ./bin/get-docker-tags.sh "$(date -u +%F)" >> $GITHUB_OUTPUT + echo "EOF" >> $GITHUB_OUTPUT shell: bash - name: Log in to Docker Hub From dc14ccd7fdcadd5b88f2002f45fafea3623a8e7f Mon Sep 17 00:00:00 2001 From: galargh Date: Sat, 14 Jan 2023 11:30:59 +0100 Subject: [PATCH 0384/1212] chore: use DOCKER_USERNAME from vars rather than secrets --- .github/workflows/docker-image.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index 27f6b71b5..9f6dd5b3f 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -38,7 +38,7 @@ jobs: - name: Log in to Docker Hub uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9 with: - username: ${{ secrets.DOCKER_USERNAME }} + username: ${{ vars.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} - name: Build Docker image and publish to Docker Hub From 3e24898488b8efa7380bd5a1dcd4ad039ac1dc1d Mon Sep 17 00:00:00 2001 From: galargh Date: Sat, 14 Jan 2023 11:34:28 +0100 Subject: [PATCH 0385/1212] fix: multiline output in docker image workflow --- .github/workflows/docker-image.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index 9f6dd5b3f..a7416e388 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -30,7 +30,7 @@ jobs: - name: Get tags id: tags run: | - echo "value=<> $GITHUB_OUTPUT + echo "value<> $GITHUB_OUTPUT ./bin/get-docker-tags.sh "$(date -u +%F)" >> $GITHUB_OUTPUT echo "EOF" >> $GITHUB_OUTPUT shell: bash From 289b490b1bd4dc644e8c61b234e147888e2790ea Mon Sep 17 00:00:00 2001 From: galargh Date: Sat, 14 Jan 2023 11:41:20 +0100 Subject: [PATCH 0386/1212] fix: source of the runner workflow --- .github/workflows/gobuild.yml | 2 +- .github/workflows/sharness.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/gobuild.yml b/.github/workflows/gobuild.yml index 91147a7d3..120e94693 100644 --- a/.github/workflows/gobuild.yml +++ b/.github/workflows/gobuild.yml @@ -10,7 +10,7 @@ on: jobs: runner: if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' - uses: ipfs/kubo/.github/workflows/runner.yml + uses: ipfs/kubo/.github/workflows/runner.yml@master gobuild: needs: [runner] runs-on: ${{ fromJSON(needs.runner.outputs.config).labels }} diff --git a/.github/workflows/sharness.yml b/.github/workflows/sharness.yml index 74810eeaa..6241e3fe6 100644 --- a/.github/workflows/sharness.yml +++ b/.github/workflows/sharness.yml @@ -10,7 +10,7 @@ on: jobs: runner: if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' - uses: ipfs/kubo/.github/workflows/runner.yml + uses: ipfs/kubo/.github/workflows/runner.yml@master sharness: needs: [runner] runs-on: ${{ fromJSON(needs.runner.outputs.config).labels }} From d90a9b5b3363a239804ed88a555b7c89e060b6ec Mon Sep 17 00:00:00 2001 From: galargh Date: Sun, 15 Jan 2023 11:59:55 +0100 Subject: [PATCH 0387/1212] fix: do not download saxon in parallel --- test/sharness/Rules.mk | 9 ++++- test/sharness/lib/download-saxon.sh | 39 +++++++++++++++++++ test/sharness/lib/test-generate-junit-html.sh | 38 ------------------ 3 files changed, 46 insertions(+), 40 deletions(-) create mode 100755 test/sharness/lib/download-saxon.sh diff --git a/test/sharness/Rules.mk b/test/sharness/Rules.mk index 3b7708b60..20b2634db 100644 --- a/test/sharness/Rules.mk +++ b/test/sharness/Rules.mk @@ -47,12 +47,17 @@ $(d)/test-results/sharness.xml: $(T_$(d)) @(cd $(@D)/.. && ./lib/test-aggregate-junit-reports.sh) .PHONY: $(d)/test-results/sharness.xml -$(d)/test-results/sharness-html: $(d)/test-results/sharness.xml +$(d)/download-saxon: + @echo "*** $@ ***" + @(cd $(@D) && ./lib/download-saxon.sh) +.PHONY: $(d)/download-saxon + +$(d)/test-results/sharness-html: $(d)/test-results/sharness.xml $(d)/download-saxon @echo "*** $@ ***" @(cd $(@D)/.. && ./lib/test-generate-junit-html.sh frames) .PHONY: $(d)/test-results/sharness-html -$(d)/test-results/sharness.html: $(d)/test-results/sharness.xml +$(d)/test-results/sharness.html: $(d)/test-results/sharness.xml $(d)/download-saxon @echo "*** $@ ***" @(cd $(@D)/.. && ./lib/test-generate-junit-html.sh no-frames) .PHONY: $(d)/test-results/sharness.html diff --git a/test/sharness/lib/download-saxon.sh b/test/sharness/lib/download-saxon.sh new file mode 100755 index 000000000..195630804 --- /dev/null +++ b/test/sharness/lib/download-saxon.sh @@ -0,0 +1,39 @@ +#!/bin/bash + +dependencies=( + "url=https://sourceforge.net/projects/saxon/files/Saxon-HE/11/Java/SaxonHE11-4J.zip;md5=8a4783d307c32c898f8995b8f337fd6b" + "url=https://raw.githubusercontent.com/pl-strflt/ant/c781f7d79b92cc55530245d9554682a47f46851e/src/etc/junit-frames-saxon.xsl;md5=6eb013566903a91e4959413f6ff144d0" + "url=https://raw.githubusercontent.com/pl-strflt/ant/c781f7d79b92cc55530245d9554682a47f46851e/src/etc/junit-noframes-saxon.xsl;md5=8d54882d5f9d32a7743ec675cc2e30ac" +) + +dependenciesdir="lib/dependencies" +mkdir -p "$dependenciesdir" + +get_md5() { + md5sum "$1" | cut -d ' ' -f 1 +} + +for dependency in "${dependencies[@]}"; do + url="$(echo "$dependency" | cut -d ';' -f 1 | cut -d '=' -f 2)" + md5="$(echo "$dependency" | cut -d ';' -f 2 | cut -d '=' -f 2)" + filename="$(basename "$url")" + if test -f "$dependenciesdir/$filename" && test "$(get_md5 "$dependenciesdir/$filename")" = "$md5"; then + echo "Using cached $filename" + else + echo "Downloading $filename" + curl -L --max-redirs 5 --retry 5 --no-progress-meter --output "$dependenciesdir/$filename" "$url" + actual_md5="$(get_md5 "$dependenciesdir/$filename")" + if test "$actual_md5" != "$md5"; then + echo "Downloaded $filename has wrong md5sum ('$actual_md5' != '$md5')" + exit 1 + fi + dirname=${filename%.*} + extension=${filename#$dirname.} + if test "$extension" = "zip"; then + echo "Removing old $dependenciesdir/$dirname" + rm -rf "$dependenciesdir/$dirname" + echo "Unzipping $dependenciesdir/$filename" + unzip "$dependenciesdir/$filename" -d "$dependenciesdir/$dirname" + fi + fi +done diff --git a/test/sharness/lib/test-generate-junit-html.sh b/test/sharness/lib/test-generate-junit-html.sh index cc18762cb..2790a7b9d 100755 --- a/test/sharness/lib/test-generate-junit-html.sh +++ b/test/sharness/lib/test-generate-junit-html.sh @@ -1,43 +1,5 @@ #!/bin/bash -dependencies=( - "url=https://sourceforge.net/projects/saxon/files/Saxon-HE/11/Java/SaxonHE11-4J.zip;md5=8a4783d307c32c898f8995b8f337fd6b" - "url=https://raw.githubusercontent.com/pl-strflt/ant/c781f7d79b92cc55530245d9554682a47f46851e/src/etc/junit-frames-saxon.xsl;md5=6eb013566903a91e4959413f6ff144d0" - "url=https://raw.githubusercontent.com/pl-strflt/ant/c781f7d79b92cc55530245d9554682a47f46851e/src/etc/junit-noframes-saxon.xsl;md5=8d54882d5f9d32a7743ec675cc2e30ac" -) - -dependenciesdir="lib/dependencies" -mkdir -p "$dependenciesdir" - -get_md5() { - md5sum "$1" | cut -d ' ' -f 1 -} - -for dependency in "${dependencies[@]}"; do - url="$(echo "$dependency" | cut -d ';' -f 1 | cut -d '=' -f 2)" - md5="$(echo "$dependency" | cut -d ';' -f 2 | cut -d '=' -f 2)" - filename="$(basename "$url")" - if test -f "$dependenciesdir/$filename" && test "$(get_md5 "$dependenciesdir/$filename")" = "$md5"; then - echo "Using cached $filename" - else - echo "Downloading $filename" - curl -L --max-redirs 5 --retry 5 --no-progress-meter --output "$dependenciesdir/$filename" "$url" - actual_md5="$(get_md5 "$dependenciesdir/$filename")" - if test "$actual_md5" != "$md5"; then - echo "Downloaded $filename has wrong md5sum ('$actual_md5' != '$md5')" - exit 1 - fi - dirname=${filename%.*} - extension=${filename#$dirname.} - if test "$extension" = "zip"; then - echo "Removing old $dependenciesdir/$dirname" - rm -rf "$dependenciesdir/$dirname" - echo "Unzipping $dependenciesdir/$filename" - unzip "$dependenciesdir/$filename" -d "$dependenciesdir/$dirname" - fi - fi -done - case "$1" in "frames") java -jar lib/dependencies/SaxonHE11-4J/saxon-he-11.4.jar \ From 5d864faac71b877ae30bd7b2f01c9dfaba68d8eb Mon Sep 17 00:00:00 2001 From: Gus Eggert Date: Wed, 14 Dec 2022 11:10:48 -0500 Subject: [PATCH 0388/1212] test: port gateway sharness tests to Go tests --- test/cli/gateway_test.go | 492 ++++++++++++++++++ test/cli/harness/harness.go | 13 +- test/cli/harness/http_client.go | 116 +++++ test/cli/harness/node.go | 80 ++- test/cli/harness/nodes.go | 21 +- test/cli/testutils/strings.go | 24 + test/sharness/t0110-gateway-data/foo.block | 2 - test/sharness/t0110-gateway-data/foofoo.block | Bin 82 -> 0 bytes test/sharness/t0110-gateway.sh | 357 ------------- 9 files changed, 727 insertions(+), 378 deletions(-) create mode 100644 test/cli/gateway_test.go create mode 100644 test/cli/harness/http_client.go delete mode 100644 test/sharness/t0110-gateway-data/foo.block delete mode 100644 test/sharness/t0110-gateway-data/foofoo.block delete mode 100755 test/sharness/t0110-gateway.sh diff --git a/test/cli/gateway_test.go b/test/cli/gateway_test.go new file mode 100644 index 000000000..6e8ef516a --- /dev/null +++ b/test/cli/gateway_test.go @@ -0,0 +1,492 @@ +package cli + +import ( + "context" + "encoding/json" + "fmt" + "net/http" + "os" + "path/filepath" + "regexp" + "testing" + + "github.com/ipfs/kubo/config" + "github.com/ipfs/kubo/test/cli/harness" + . "github.com/ipfs/kubo/test/cli/testutils" + "github.com/multiformats/go-multiaddr" + manet "github.com/multiformats/go-multiaddr/net" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestGateway(t *testing.T) { + t.Parallel() + h := harness.NewT(t) + node := h.NewNode().Init().StartDaemon("--offline") + cid := node.IPFSAddStr("Hello Worlds!") + + client := node.GatewayClient() + client.TemplateData = map[string]string{ + "CID": cid, + "PeerID": node.PeerID().String(), + } + + t.Run("GET IPFS path succeeds", func(t *testing.T) { + t.Parallel() + resp := client.Get("/ipfs/{{.CID}}") + assert.Equal(t, 200, resp.StatusCode) + }) + + t.Run("GET IPFS path with explicit ?filename succeeds with proper header", func(t *testing.T) { + t.Parallel() + resp := client.Get("/ipfs/{{.CID}}?filename=testтест.pdf") + assert.Equal(t, 200, resp.StatusCode) + assert.Equal(t, + `inline; filename="test____.pdf"; filename*=UTF-8''test%D1%82%D0%B5%D1%81%D1%82.pdf`, + resp.Headers.Get("Content-Disposition"), + ) + }) + + t.Run("GET IPFS path with explicit ?filename and &download=true succeeds with proper header", func(t *testing.T) { + t.Parallel() + resp := client.Get("/ipfs/{{.CID}}?filename=testтест.mp4&download=true") + assert.Equal(t, 200, resp.StatusCode) + assert.Equal(t, + `attachment; filename="test____.mp4"; filename*=UTF-8''test%D1%82%D0%B5%D1%81%D1%82.mp4`, + resp.Headers.Get("Content-Disposition"), + ) + }) + + // https://github.com/ipfs/go-ipfs/issues/4025#issuecomment-342250616 + t.Run("GET for Server Worker registration outside of an IPFS content root errors", func(t *testing.T) { + t.Parallel() + resp := client.Get("/ipfs/{{.CID}}?filename=sw.js", client.WithHeader("Service-Worker", "script")) + assert.Equal(t, 400, resp.StatusCode) + assert.Contains(t, resp.Body, "navigator.serviceWorker: registration is not allowed for this scope") + }) + + t.Run("GET IPFS directory path succeeds", func(t *testing.T) { + t.Parallel() + client := node.GatewayClient().DisableRedirects() + + pageContents := "hello i am a webpage" + fileContents := "12345" + h.WriteFile("dir/test", fileContents) + h.WriteFile("dir/dirwithindex/index.html", pageContents) + cids := node.IPFS("add", "-r", "-q", filepath.Join(h.Dir, "dir")).Stdout.Lines() + + rootCID := cids[len(cids)-1] + client.TemplateData = map[string]string{ + "IndexFileCID": cids[0], + "TestFileCID": cids[1], + "RootCID": rootCID, + } + + t.Run("GET IPFS the index file CID", func(t *testing.T) { + t.Parallel() + resp := client.Get("/ipfs/{{.IndexFileCID}}") + assert.Equal(t, 200, resp.StatusCode) + assert.Equal(t, pageContents, resp.Body) + }) + + t.Run("GET IPFS the test file CID", func(t *testing.T) { + t.Parallel() + resp := client.Get("/ipfs/{{.TestFileCID}}") + assert.Equal(t, 200, resp.StatusCode) + assert.Equal(t, fileContents, resp.Body) + }) + + t.Run("GET IPFS directory with index.html returns redirect to add trailing slash", func(t *testing.T) { + t.Parallel() + resp := client.Head("/ipfs/{{.RootCID}}/dirwithindex?query=to-remember") + assert.Equal(t, 301, resp.StatusCode) + assert.Equal(t, + fmt.Sprintf("/ipfs/%s/dirwithindex/?query=to-remember", rootCID), + resp.Headers.Get("Location"), + ) + }) + + // This enables go get to parse go-import meta tags from index.html files stored in IPFS + // https://github.com/ipfs/kubo/pull/3963 + t.Run("GET IPFS directory with index.html and no trailing slash returns expected output when go-get is passed", func(t *testing.T) { + t.Parallel() + resp := client.Get("/ipfs/{{.RootCID}}/dirwithindex?go-get=1") + assert.Equal(t, pageContents, resp.Body) + }) + + t.Run("GET IPFS directory with index.html and trailing slash returns expected output", func(t *testing.T) { + t.Parallel() + resp := client.Get("/ipfs/{{.RootCID}}/dirwithindex/?query=to-remember") + assert.Equal(t, pageContents, resp.Body) + }) + + t.Run("GET IPFS nonexistent file returns 404 (Not Found)", func(t *testing.T) { + t.Parallel() + resp := client.Get("/ipfs/{{.RootCID}}/pleaseDontAddMe") + assert.Equal(t, 404, resp.StatusCode) + }) + + t.Run("GET IPFS invalid CID returns 400 (Bad Request)", func(t *testing.T) { + t.Parallel() + resp := client.Get("/ipfs/QmInvalid/pleaseDontAddMe") + assert.Equal(t, 400, resp.StatusCode) + }) + + t.Run("GET IPFS inlined zero-length data object returns ok code (200)", func(t *testing.T) { + t.Parallel() + resp := client.Get("/ipfs/bafkqaaa") + assert.Equal(t, 200, resp.StatusCode) + assert.Equal(t, "0", resp.Resp.Header.Get("Content-Length")) + assert.Equal(t, "", resp.Body) + }) + + t.Run("GET IPFS inlined zero-length data object with byte range returns ok code (200)", func(t *testing.T) { + t.Parallel() + resp := client.Get("/ipfs/bafkqaaa", client.WithHeader("Range", "bytes=0-1048575")) + assert.Equal(t, 200, resp.StatusCode) + assert.Equal(t, "0", resp.Resp.Header.Get("Content-Length")) + assert.Equal(t, "text/plain", resp.Resp.Header.Get("Content-Type")) + }) + + t.Run("GET /ipfs/ipfs/{cid} returns redirect to the valid path", func(t *testing.T) { + t.Parallel() + resp := client.Get("/ipfs/ipfs/bafkqaaa?query=to-remember") + assert.Contains(t, + resp.Body, + ``, + ) + assert.Contains(t, + resp.Body, + ``, + ) + }) + }) + + t.Run("IPNS", func(t *testing.T) { + t.Parallel() + node.IPFS("name", "publish", "--allow-offline", cid) + + t.Run("GET invalid IPNS root returns 400 (Bad Request)", func(t *testing.T) { + t.Parallel() + resp := client.Get("/ipns/QmInvalid/pleaseDontAddMe") + assert.Equal(t, 400, resp.StatusCode) + }) + + t.Run("GET IPNS path succeeds", func(t *testing.T) { + t.Parallel() + resp := client.Get("/ipns/{{.PeerID}}") + assert.Equal(t, 200, resp.StatusCode) + assert.Equal(t, "Hello Worlds!", resp.Body) + }) + + t.Run("GET /ipfs/ipns/{peerid} returns redirect to the valid path", func(t *testing.T) { + t.Parallel() + resp := client.Get("/ipfs/ipns/{{.PeerID}}?query=to-remember") + peerID := node.PeerID().String() + assert.Contains(t, + resp.Body, + fmt.Sprintf(``, peerID), + ) + assert.Contains(t, + resp.Body, + fmt.Sprintf(``, peerID), + ) + + }) + + }) + + t.Run("GET invalid IPFS path errors", func(t *testing.T) { + t.Parallel() + assert.Equal(t, 400, client.Get("/ipfs/12345").StatusCode) + }) + + t.Run("GET invalid path errors", func(t *testing.T) { + t.Parallel() + assert.Equal(t, 404, client.Get("/12345").StatusCode) + }) + + // TODO: these tests that use the API URL shouldn't be part of gateway tests... + t.Run("GET /webui returns 301 or 302", func(t *testing.T) { + t.Parallel() + resp := node.APIClient().DisableRedirects().Get("/webui") + assert.Contains(t, []int{302, 301}, resp.StatusCode) + }) + + t.Run("GET /webui/ returns 301 or 302", func(t *testing.T) { + t.Parallel() + resp := node.APIClient().DisableRedirects().Get("/webui/") + assert.Contains(t, []int{302, 301}, resp.StatusCode) + }) + + t.Run("GET /logs returns logs", func(t *testing.T) { + t.Parallel() + apiClient := node.APIClient() + reqURL := apiClient.BuildURL("/logs") + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + req, err := http.NewRequestWithContext(ctx, http.MethodGet, reqURL, nil) + require.NoError(t, err) + + resp, err := apiClient.Client.Do(req) + require.NoError(t, err) + defer resp.Body.Close() + + // read the first line of the output and parse its JSON + dec := json.NewDecoder(resp.Body) + event := struct{ Event string }{} + err = dec.Decode(&event) + require.NoError(t, err) + + assert.Equal(t, "log API client connected", event.Event) + }) + + t.Run("POST /api/v0/version succeeds", func(t *testing.T) { + t.Parallel() + resp := node.APIClient().Post("/api/v0/version", nil) + assert.Equal(t, 200, resp.StatusCode) + + assert.Len(t, resp.Resp.TransferEncoding, 1) + assert.Equal(t, "chunked", resp.Resp.TransferEncoding[0]) + + vers := struct{ Version string }{} + err := json.Unmarshal([]byte(resp.Body), &vers) + require.NoError(t, err) + assert.NotEmpty(t, vers.Version) + }) + + t.Run("pprof", func(t *testing.T) { + t.Parallel() + node := harness.NewT(t).NewNode().Init().StartDaemon() + apiClient := node.APIClient() + t.Run("mutex", func(t *testing.T) { + t.Parallel() + t.Run("setting the mutex fraction works (negative so it doesn't enable)", func(t *testing.T) { + t.Parallel() + resp := apiClient.Post("/debug/pprof-mutex/?fraction=-1", nil) + assert.Equal(t, 200, resp.StatusCode) + }) + t.Run("mutex endpoint doesn't accept a string as an argument", func(t *testing.T) { + t.Parallel() + resp := apiClient.Post("/debug/pprof-mutex/?fraction=that_is_a_string", nil) + assert.Equal(t, 400, resp.StatusCode) + }) + t.Run("mutex endpoint returns 405 on GET", func(t *testing.T) { + t.Parallel() + resp := apiClient.Get("/debug/pprof-mutex/?fraction=-1") + assert.Equal(t, 405, resp.StatusCode) + }) + }) + t.Run("block", func(t *testing.T) { + t.Parallel() + t.Run("setting the block profiler rate works (0 so it doesn't enable)", func(t *testing.T) { + t.Parallel() + resp := apiClient.Post("/debug/pprof-block/?rate=0", nil) + assert.Equal(t, 200, resp.StatusCode) + }) + t.Run("block profiler endpoint doesn't accept a string as an argument", func(t *testing.T) { + t.Parallel() + resp := apiClient.Post("/debug/pprof-block/?rate=that_is_a_string", nil) + assert.Equal(t, 400, resp.StatusCode) + }) + t.Run("block profiler endpoint returns 405 on GET", func(t *testing.T) { + t.Parallel() + resp := apiClient.Get("/debug/pprof-block/?rate=0") + assert.Equal(t, 405, resp.StatusCode) + }) + }) + }) + + t.Run("index content types", func(t *testing.T) { + t.Parallel() + h := harness.NewT(t) + node := h.NewNode().Init().StartDaemon() + + h.WriteFile("index/index.html", "

") + cid := node.IPFS("add", "-Q", "-r", filepath.Join(h.Dir, "index")).Stderr.Trimmed() + + apiClient := node.APIClient() + apiClient.TemplateData = map[string]string{"CID": cid} + + t.Run("GET index.html has correct content type", func(t *testing.T) { + t.Parallel() + res := apiClient.Get("/ipfs/{{.CID}}/") + assert.Equal(t, "text/html; charset=utf-8", res.Resp.Header.Get("Content-Type")) + }) + + t.Run("HEAD index.html has no content", func(t *testing.T) { + t.Parallel() + res := apiClient.Head("/ipfs/{{.CID}}/") + assert.Equal(t, "", res.Body) + assert.Equal(t, "", res.Resp.Header.Get("Content-Length")) + }) + }) + + t.Run("readonly API", func(t *testing.T) { + t.Parallel() + + client := node.GatewayClient() + + fileContents := "12345" + h.WriteFile("readonly/dir/test", fileContents) + cids := node.IPFS("add", "-r", "-q", filepath.Join(h.Dir, "readonly/dir")).Stdout.Lines() + + rootCID := cids[len(cids)-1] + client.TemplateData = map[string]string{"RootCID": rootCID} + + t.Run("Get IPFS directory file through readonly API succeeds", func(t *testing.T) { + t.Parallel() + resp := client.Get("/api/v0/cat?arg={{.RootCID}}/test") + assert.Equal(t, 200, resp.StatusCode) + assert.Equal(t, fileContents, resp.Body) + }) + + t.Run("refs IPFS directory file through readonly API succeeds", func(t *testing.T) { + t.Parallel() + resp := client.Get("/api/v0/refs?arg={{.RootCID}}/test") + assert.Equal(t, 200, resp.StatusCode) + }) + + t.Run("test gateway API is sanitized", func(t *testing.T) { + t.Parallel() + for _, cmd := range []string{ + "add", + "block/put", + "bootstrap", + "config", + "dag/put", + "dag/import", + "dht", + "diag", + "id", + "mount", + "name/publish", + "object/put", + "object/new", + "object/patch", + "pin", + "ping", + "repo", + "stats", + "swarm", + "file", + "update", + "bitswap", + } { + t.Run(cmd, func(t *testing.T) { + cmd := cmd + t.Parallel() + assert.Equal(t, 404, client.Get("/api/v0/"+cmd).StatusCode) + }) + } + }) + }) + + t.Run("refs/local", func(t *testing.T) { + t.Parallel() + gatewayAddr := URLStrToMultiaddr(node.GatewayURL()) + res := node.RunIPFS("--api", gatewayAddr.String(), "refs", "local") + assert.Equal(t, + `Error: invalid path "local": selected encoding not supported`, + res.Stderr.Trimmed(), + ) + }) + + t.Run("raw leaves node", func(t *testing.T) { + t.Parallel() + contents := "This is RAW!" + cid := node.IPFSAddStr(contents, "--raw-leaves") + assert.Equal(t, contents, client.Get("/ipfs/"+cid).Body) + }) + + t.Run("compact blocks", func(t *testing.T) { + t.Parallel() + block1 := "\x0a\x09\x08\x02\x12\x03\x66\x6f\x6f\x18\x03" + block2 := "\x0a\x04\x08\x02\x18\x06\x12\x24\x0a\x22\x12\x20\xcf\x92\xfd\xef\xcd\xc3\x4c\xac\x00\x9c" + + "\x8b\x05\xeb\x66\x2b\xe0\x61\x8d\xb9\xde\x55\xec\xd4\x27\x85\xe9\xec\x67\x12\xf8\xdf\x65" + + "\x12\x24\x0a\x22\x12\x20\xcf\x92\xfd\xef\xcd\xc3\x4c\xac\x00\x9c\x8b\x05\xeb\x66\x2b\xe0" + + "\x61\x8d\xb9\xde\x55\xec\xd4\x27\x85\xe9\xec\x67\x12\xf8\xdf\x65" + + node.PipeStrToIPFS(block1, "block", "put") + block2CID := node.PipeStrToIPFS(block2, "block", "put", "--cid-codec=dag-pb").Stdout.Trimmed() + + resp := client.Get("/ipfs/" + block2CID) + assert.Equal(t, 200, resp.StatusCode) + assert.Equal(t, "foofoo", resp.Body) + }) + + t.Run("verify gateway file", func(t *testing.T) { + t.Parallel() + r := regexp.MustCompile(`Gateway \(readonly\) server listening on (?P.+)\s`) + matches := r.FindStringSubmatch(node.Daemon.Stdout.String()) + ma, err := multiaddr.NewMultiaddr(matches[1]) + require.NoError(t, err) + netAddr, err := manet.ToNetAddr(ma) + require.NoError(t, err) + expURL := "http://" + netAddr.String() + + b, err := os.ReadFile(filepath.Join(node.Dir, "gateway")) + require.NoError(t, err) + + assert.Equal(t, expURL, string(b)) + }) + + t.Run("verify gateway file diallable while on unspecified", func(t *testing.T) { + t.Parallel() + node := harness.NewT(t).NewNode().Init() + node.UpdateConfig(func(cfg *config.Config) { + cfg.Addresses.Gateway = config.Strings{"/ip4/127.0.0.1/tcp/32563"} + }) + node.StartDaemon() + + b, err := os.ReadFile(filepath.Join(node.Dir, "gateway")) + require.NoError(t, err) + + assert.Equal(t, "http://127.0.0.1:32563", string(b)) + }) + + t.Run("NoFetch", func(t *testing.T) { + t.Parallel() + nodes := harness.NewT(t).NewNodes(2).Init() + node1 := nodes[0] + node2 := nodes[1] + + node1.UpdateConfig(func(cfg *config.Config) { + cfg.Gateway.NoFetch = true + }) + + nodes.StartDaemons().Connect() + + t.Run("not present", func(t *testing.T) { + cidFoo := node2.IPFSAddStr("foo") + + t.Run("not present key from node 1", func(t *testing.T) { + t.Parallel() + assert.Equal(t, 404, node1.GatewayClient().Get("/ipfs/"+cidFoo).StatusCode) + }) + + t.Run("not present IPNS key from node 1", func(t *testing.T) { + t.Parallel() + assert.Equal(t, 400, node1.GatewayClient().Get("/ipns/"+node2.PeerID().String()).StatusCode) + }) + }) + + t.Run("present", func(t *testing.T) { + cidBar := node1.IPFSAddStr("bar") + + t.Run("present key from node 1", func(t *testing.T) { + t.Parallel() + assert.Equal(t, 200, node1.GatewayClient().Get("/ipfs/"+cidBar).StatusCode) + }) + + t.Run("present IPNS key from node 1", func(t *testing.T) { + t.Parallel() + node2.IPFS("name", "publish", "/ipfs/"+cidBar) + assert.Equal(t, 200, node1.GatewayClient().Get("/ipns/"+node2.PeerID().String()).StatusCode) + + }) + }) + }) +} diff --git a/test/cli/harness/harness.go b/test/cli/harness/harness.go index dd9f38ec3..de962e1c1 100644 --- a/test/cli/harness/harness.go +++ b/test/cli/harness/harness.go @@ -119,15 +119,19 @@ func (h *Harness) TempFile() *os.File { } // WriteFile writes a file given a filename and its contents. -// The filename should be a relative path. +// The filename must be a relative path, or this panics. func (h *Harness) WriteFile(filename, contents string) { if filepath.IsAbs(filename) { log.Panicf("%s must be a relative path", filename) } absPath := filepath.Join(h.Runner.Dir, filename) - err := os.WriteFile(absPath, []byte(contents), 0644) + err := os.MkdirAll(filepath.Dir(absPath), 0777) if err != nil { - log.Panicf("writing '%s' ('%s'): %s", filename, absPath, err.Error()) + log.Panicf("creating intermediate dirs for %q: %s", filename, err.Error()) + } + err = os.WriteFile(absPath, []byte(contents), 0644) + if err != nil { + log.Panicf("writing %q (%q): %s", filename, absPath, err.Error()) } } @@ -140,8 +144,7 @@ func WaitForFile(path string, timeout time.Duration) error { for { select { case <-timer.C: - end := time.Now() - return fmt.Errorf("timeout waiting for %s after %v", path, end.Sub(start)) + return fmt.Errorf("timeout waiting for %s after %v", path, time.Since(start)) case <-ticker.C: _, err := os.Stat(path) if err == nil { diff --git a/test/cli/harness/http_client.go b/test/cli/harness/http_client.go new file mode 100644 index 000000000..83aa1bff1 --- /dev/null +++ b/test/cli/harness/http_client.go @@ -0,0 +1,116 @@ +package harness + +import ( + "io" + "net/http" + "strings" + "text/template" + "time" +) + +// HTTPClient is an HTTP client with some conveniences for testing. +// URLs are constructed from a base URL. +// The response body is buffered into a string. +// Internal errors cause panics so that tests don't need to check errors. +// The paths are evaluated as Go templates for readable string interpolation. +type HTTPClient struct { + Client *http.Client + BaseURL string + + Timeout time.Duration + TemplateData any +} + +type HTTPResponse struct { + Body string + StatusCode int + Headers http.Header + + // The raw response. The body will be closed on this response. + Resp *http.Response +} + +func (c *HTTPClient) WithHeader(k, v string) func(h *http.Request) { + return func(h *http.Request) { + h.Header.Add(k, v) + } +} + +func (c *HTTPClient) DisableRedirects() *HTTPClient { + c.Client.CheckRedirect = func(req *http.Request, via []*http.Request) error { + return http.ErrUseLastResponse + } + return c +} + +// Do executes the request unchanged. +func (c *HTTPClient) Do(req *http.Request) *HTTPResponse { + log.Debugf("making HTTP req %s to %q with headers %+v", req.Method, req.URL.String(), req.Header) + resp, err := c.Client.Do(req) + if resp != nil && resp.Body != nil { + defer resp.Body.Close() + } + if err != nil { + panic(err) + } + bodyStr, err := io.ReadAll(resp.Body) + if err != nil { + panic(err) + } + + return &HTTPResponse{ + Body: string(bodyStr), + StatusCode: resp.StatusCode, + Headers: resp.Header, + Resp: resp, + } +} + +// BuildURL constructs a request URL from the given path by interpolating the string and then appending it to the base URL. +func (c *HTTPClient) BuildURL(urlPath string) string { + sb := &strings.Builder{} + err := template.Must(template.New("test").Parse(urlPath)).Execute(sb, c.TemplateData) + if err != nil { + panic(err) + } + renderedPath := sb.String() + return c.BaseURL + renderedPath +} + +func (c *HTTPClient) Get(urlPath string, opts ...func(*http.Request)) *HTTPResponse { + req, err := http.NewRequest(http.MethodGet, c.BuildURL(urlPath), nil) + if err != nil { + panic(err) + } + for _, o := range opts { + o(req) + } + return c.Do(req) +} + +func (c *HTTPClient) Post(urlPath string, body io.Reader, opts ...func(*http.Request)) *HTTPResponse { + req, err := http.NewRequest(http.MethodPost, c.BuildURL(urlPath), body) + if err != nil { + panic(err) + } + for _, o := range opts { + o(req) + } + return c.Do(req) +} + +func (c *HTTPClient) PostStr(urlpath, body string, opts ...func(*http.Request)) *HTTPResponse { + r := strings.NewReader(body) + return c.Post(urlpath, r, opts...) +} + +func (c *HTTPClient) Head(urlPath string, opts ...func(*http.Request)) *HTTPResponse { + req, err := http.NewRequest(http.MethodHead, c.BuildURL(urlPath), nil) + if err != nil { + panic(err) + } + for _, o := range opts { + o(req) + } + return c.Do(req) +} diff --git a/test/cli/harness/node.go b/test/cli/harness/node.go index 227737eb9..26a66ddd9 100644 --- a/test/cli/harness/node.go +++ b/test/cli/harness/node.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "io" + "io/fs" "net/http" "os" "os/exec" @@ -19,6 +20,7 @@ import ( serial "github.com/ipfs/kubo/config/serialize" "github.com/libp2p/go-libp2p/core/peer" "github.com/multiformats/go-multiaddr" + manet "github.com/multiformats/go-multiaddr/net" ) var log = logging.Logger("testharness") @@ -29,14 +31,15 @@ type Node struct { ID int Dir string - APIListenAddr multiaddr.Multiaddr - SwarmAddr multiaddr.Multiaddr - EnableMDNS bool + APIListenAddr multiaddr.Multiaddr + GatewayListenAddr multiaddr.Multiaddr + SwarmAddr multiaddr.Multiaddr + EnableMDNS bool IPFSBin string Runner *Runner - daemon *RunResult + Daemon *RunResult } func BuildNode(ipfsBin, baseDir string, id int) *Node { @@ -134,11 +137,19 @@ func (n *Node) Init(ipfsArgs ...string) *Node { n.APIListenAddr = apiAddr } + if n.GatewayListenAddr == nil { + gatewayAddr, err := multiaddr.NewMultiaddr("/ip4/127.0.0.1/tcp/0") + if err != nil { + panic(err) + } + n.GatewayListenAddr = gatewayAddr + } + n.UpdateConfig(func(cfg *config.Config) { cfg.Bootstrap = []string{} cfg.Addresses.Swarm = []string{n.SwarmAddr.String()} cfg.Addresses.API = []string{n.APIListenAddr.String()} - cfg.Addresses.Gateway = []string{""} + cfg.Addresses.Gateway = []string{n.GatewayListenAddr.String()} cfg.Swarm.DisableNatPortMap = true cfg.Discovery.MDNS.Enabled = n.EnableMDNS }) @@ -159,7 +170,7 @@ func (n *Node) StartDaemon(ipfsArgs ...string) *Node { RunFunc: (*exec.Cmd).Start, }) - n.daemon = &res + n.Daemon = &res log.Debugf("node %d started, checking API", n.ID) n.WaitOnAPI() @@ -167,7 +178,7 @@ func (n *Node) StartDaemon(ipfsArgs ...string) *Node { } func (n *Node) signalAndWait(watch <-chan struct{}, signal os.Signal, t time.Duration) bool { - err := n.daemon.Cmd.Process.Signal(signal) + err := n.Daemon.Cmd.Process.Signal(signal) if err != nil { if errors.Is(err, os.ErrProcessDone) { log.Debugf("process for node %d has already finished", n.ID) @@ -187,13 +198,13 @@ func (n *Node) signalAndWait(watch <-chan struct{}, signal os.Signal, t time.Dur func (n *Node) StopDaemon() *Node { log.Debugf("stopping node %d", n.ID) - if n.daemon == nil { + if n.Daemon == nil { log.Debugf("didn't stop node %d since no daemon present", n.ID) return n } watch := make(chan struct{}, 1) go func() { - _, _ = n.daemon.Cmd.Process.Wait() + _, _ = n.Daemon.Cmd.Process.Wait() watch <- struct{}{} }() log.Debugf("signaling node %d with SIGTERM", n.ID) @@ -224,6 +235,15 @@ func (n *Node) APIAddr() multiaddr.Multiaddr { return ma } +func (n *Node) APIURL() string { + apiAddr := n.APIAddr() + netAddr, err := manet.ToNetAddr(apiAddr) + if err != nil { + panic(err) + } + return "http://" + netAddr.String() +} + func (n *Node) TryAPIAddr() (multiaddr.Multiaddr, error) { b, err := os.ReadFile(filepath.Join(n.Dir, "api")) if err != nil { @@ -305,20 +325,21 @@ func (n *Node) WaitOnAPI() *Node { log.Debugf("waiting on API for node %d", n.ID) for i := 0; i < 50; i++ { if n.checkAPI() { + log.Debugf("daemon API found, daemon stdout: %s", n.Daemon.Stdout.String()) return n } time.Sleep(400 * time.Millisecond) } - log.Panicf("node %d with peer ID %s failed to come online: \n%s\n\n%s", n.ID, n.PeerID(), n.daemon.Stderr.String(), n.daemon.Stdout.String()) + log.Panicf("node %d with peer ID %s failed to come online: \n%s\n\n%s", n.ID, n.PeerID(), n.Daemon.Stderr.String(), n.Daemon.Stdout.String()) return n } func (n *Node) IsAlive() bool { - if n.daemon == nil || n.daemon.Cmd == nil || n.daemon.Cmd.Process == nil { + if n.Daemon == nil || n.Daemon.Cmd == nil || n.Daemon.Cmd.Process == nil { return false } log.Debugf("signaling node %d daemon process for liveness check", n.ID) - err := n.daemon.Cmd.Process.Signal(syscall.Signal(0)) + err := n.Daemon.Cmd.Process.Signal(syscall.Signal(0)) if err == nil { log.Debugf("node %d daemon is alive", n.ID) return true @@ -381,3 +402,38 @@ func (n *Node) Peers() []multiaddr.Multiaddr { } return addrs } + +// GatewayURL waits for the gateway file and then returns its contents or times out. +func (n *Node) GatewayURL() string { + timer := time.NewTimer(1 * time.Second) + defer timer.Stop() + for { + select { + case <-timer.C: + panic("timeout waiting for gateway file") + default: + b, err := os.ReadFile(filepath.Join(n.Dir, "gateway")) + if err == nil { + return strings.TrimSpace(string(b)) + } + if !errors.Is(err, fs.ErrNotExist) { + panic(err) + } + time.Sleep(1 * time.Millisecond) + } + } +} + +func (n *Node) GatewayClient() *HTTPClient { + return &HTTPClient{ + Client: http.DefaultClient, + BaseURL: n.GatewayURL(), + } +} + +func (n *Node) APIClient() *HTTPClient { + return &HTTPClient{ + Client: http.DefaultClient, + BaseURL: n.APIURL(), + } +} diff --git a/test/cli/harness/nodes.go b/test/cli/harness/nodes.go index b142e3d8f..dbc7de16b 100644 --- a/test/cli/harness/nodes.go +++ b/test/cli/harness/nodes.go @@ -1,6 +1,8 @@ package harness import ( + "sync" + "github.com/multiformats/go-multiaddr" ) @@ -15,14 +17,22 @@ func (n Nodes) Init(args ...string) Nodes { } func (n Nodes) Connect() Nodes { + wg := sync.WaitGroup{} for i, node := range n { for j, otherNode := range n { if i == j { continue } - node.Connect(otherNode) + node := node + otherNode := otherNode + wg.Add(1) + go func() { + defer wg.Done() + node.Connect(otherNode) + }() } } + wg.Wait() for _, node := range n { firstPeer := node.Peers()[0] if _, err := firstPeer.ValueForProtocol(multiaddr.P_P2P); err != nil { @@ -33,9 +43,16 @@ func (n Nodes) Connect() Nodes { } func (n Nodes) StartDaemons() Nodes { + wg := sync.WaitGroup{} for _, node := range n { - node.StartDaemon() + wg.Add(1) + node := node + go func() { + defer wg.Done() + node.StartDaemon() + }() } + wg.Wait() return n } diff --git a/test/cli/testutils/strings.go b/test/cli/testutils/strings.go index 529948d3f..1fb151248 100644 --- a/test/cli/testutils/strings.go +++ b/test/cli/testutils/strings.go @@ -3,7 +3,13 @@ package testutils import ( "bufio" "fmt" + "net" + "net/netip" + "net/url" "strings" + + "github.com/multiformats/go-multiaddr" + manet "github.com/multiformats/go-multiaddr/net" ) // StrCat takes a bunch of strings or string slices @@ -51,3 +57,21 @@ func SplitLines(s string) []string { } return lines } + +// URLStrToMultiaddr converts a URL string like http://localhost:80 to a multiaddr. +func URLStrToMultiaddr(u string) multiaddr.Multiaddr { + parsedURL, err := url.Parse(u) + if err != nil { + panic(err) + } + addrPort, err := netip.ParseAddrPort(parsedURL.Host) + if err != nil { + panic(err) + } + tcpAddr := net.TCPAddrFromAddrPort(addrPort) + ma, err := manet.FromNetAddr(tcpAddr) + if err != nil { + panic(err) + } + return ma +} diff --git a/test/sharness/t0110-gateway-data/foo.block b/test/sharness/t0110-gateway-data/foo.block deleted file mode 100644 index 39c7ef60b..000000000 --- a/test/sharness/t0110-gateway-data/foo.block +++ /dev/null @@ -1,2 +0,0 @@ - - foo \ No newline at end of file diff --git a/test/sharness/t0110-gateway-data/foofoo.block b/test/sharness/t0110-gateway-data/foofoo.block deleted file mode 100644 index 9e5177b183ca963f4b15a2e8ee981f55bded1bcd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 82 zcmd;L;b4+r6H?()5>hxn>F@iqhke#C%;{!*ou>UDv3KXa&^K4qTVK9O7y5BOl{i%Z Ds+T9Z diff --git a/test/sharness/t0110-gateway.sh b/test/sharness/t0110-gateway.sh deleted file mode 100755 index 5244bd214..000000000 --- a/test/sharness/t0110-gateway.sh +++ /dev/null @@ -1,357 +0,0 @@ -#!/usr/bin/env bash -# -# Copyright (c) 2015 Matt Bell -# MIT Licensed; see the LICENSE file in this repository. -# - -test_description="Test HTTP Gateway" - -. lib/test-lib.sh - -test_init_ipfs -test_launch_ipfs_daemon - -port=$GWAY_PORT -apiport=$API_PORT - -# TODO check both 5001 and 5002. -# 5001 should have a readable gateway (part of the API) -# 5002 should have a readable gateway (using ipfs config Addresses.Gateway) -# but ideally we should only write the tests once. so maybe we need to -# define a function to test a gateway, and do so for each port. -# for now we check 5001 here as 5002 will be checked in gateway-writable. - -test_expect_success "Make a file to test with" ' - echo "Hello Worlds!" >expected && - HASH=$(ipfs add -q expected) || - test_fsh cat daemon_err -' - -test_expect_success "GET IPFS path succeeds" ' - curl -sfo actual "http://127.0.0.1:$port/ipfs/$HASH" -' - -test_expect_success "GET IPFS path with explicit ?filename succeeds with proper header" " - curl -fo actual -D actual_headers 'http://127.0.0.1:$port/ipfs/$HASH?filename=testтест.pdf' && - grep -F 'Content-Disposition: inline; filename=\"test____.pdf\"; filename*=UTF-8'\'\''test%D1%82%D0%B5%D1%81%D1%82.pdf' actual_headers -" - -test_expect_success "GET IPFS path with explicit ?filename and &download=true succeeds with proper header" " - curl -fo actual -D actual_headers 'http://127.0.0.1:$port/ipfs/$HASH?filename=testтест.mp4&download=true' && - grep -F 'Content-Disposition: attachment; filename=\"test____.mp4\"; filename*=UTF-8'\'\''test%D1%82%D0%B5%D1%81%D1%82.mp4' actual_headers -" - -# https://github.com/ipfs/go-ipfs/issues/4025#issuecomment-342250616 -test_expect_success "GET for Service Worker registration outside of an IPFS content root errors" " - curl -H 'Service-Worker: script' -svX GET 'http://127.0.0.1:$port/ipfs/$HASH?filename=sw.js' > curl_sw_out 2>&1 && - grep 'HTTP/1.1 400 Bad Request' curl_sw_out && - grep 'navigator.serviceWorker: registration is not allowed for this scope' curl_sw_out -" - -test_expect_success "GET IPFS path output looks good" ' - test_cmp expected actual && - rm actual -' - -test_expect_success "GET IPFS directory path succeeds" ' - mkdir -p dir/dirwithindex && - echo "12345" >dir/test && - echo "hello i am a webpage" >dir/dirwithindex/index.html && - ipfs add -r -q dir >actual && - HASH2=$(tail -n 1 actual) && - curl -sf "http://127.0.0.1:$port/ipfs/$HASH2" -' - -test_expect_success "GET IPFS directory file succeeds" ' - curl -sfo actual "http://127.0.0.1:$port/ipfs/$HASH2/test" -' - -test_expect_success "GET IPFS directory file output looks good" ' - test_cmp dir/test actual -' - -test_expect_success "GET IPFS directory with index.html returns redirect to add trailing slash" " - curl -sI -o response_without_slash \"http://127.0.0.1:$port/ipfs/$HASH2/dirwithindex?query=to-remember\" && - test_should_contain \"HTTP/1.1 301 Moved Permanently\" response_without_slash && - test_should_contain \"Location: /ipfs/$HASH2/dirwithindex/?query=to-remember\" response_without_slash -" - -# This enables go get to parse go-import meta tags from index.html files stored in IPFS -# https://github.com/ipfs/kubo/pull/3963 -test_expect_success "GET IPFS directory with index.html and no trailing slash returns expected output when go-get is passed" " - curl -s -o response_with_slash \"http://127.0.0.1:$port/ipfs/$HASH2/dirwithindex?go-get=1\" && - test_should_contain \"hello i am a webpage\" response_with_slash -" - -test_expect_success "GET IPFS directory with index.html and trailing slash returns expected output" " - curl -s -o response_with_slash \"http://127.0.0.1:$port/ipfs/$HASH2/dirwithindex/?query=to-remember\" && - test_should_contain \"hello i am a webpage\" response_with_slash -" - -test_expect_success "GET IPFS nonexistent file returns 404 (Not Found)" ' - test_curl_resp_http_code "http://127.0.0.1:$port/ipfs/$HASH2/pleaseDontAddMe" "HTTP/1.1 404 Not Found" -' - -test_expect_success "GET IPFS invalid CID returns 400 (Bad Request)" ' - test_curl_resp_http_code "http://127.0.0.1:$port/ipfs/QmInvalid/pleaseDontAddMe" "HTTP/1.1 400 Bad Request" -' - -# https://github.com/ipfs/go-ipfs/issues/8230 -test_expect_success "GET IPFS inlined zero-length data object returns ok code (200)" ' - curl -sD - "http://127.0.0.1:$port/ipfs/bafkqaaa" > empty_ok_response && - test_should_contain "HTTP/1.1 200 OK" empty_ok_response && - test_should_contain "Content-Length: 0" empty_ok_response -' - -# https://github.com/ipfs/kubo/issues/9238 -test_expect_success "GET IPFS inlined zero-length data object with byte range returns ok code (200)" ' - curl -sD - "http://127.0.0.1:$port/ipfs/bafkqaaa" -H "Range: bytes=0-1048575" > empty_ok_response && - test_should_contain "HTTP/1.1 200 OK" empty_ok_response && - test_should_contain "Content-Length: 0" empty_ok_response && - test_should_contain "Content-Type: text/plain" empty_ok_response -' - -test_expect_success "GET /ipfs/ipfs/{cid} returns redirect to the valid path" ' - curl -sD - "http://127.0.0.1:$port/ipfs/ipfs/bafkqaaa?query=to-remember" > response_with_double_ipfs_ns && - test_should_contain "" response_with_double_ipfs_ns && - test_should_contain "" response_with_double_ipfs_ns -' - -test_expect_success "GET invalid IPNS root returns 400 (Bad Request)" ' - test_curl_resp_http_code "http://127.0.0.1:$port/ipns/QmInvalid/pleaseDontAddMe" "HTTP/1.1 400 Bad Request" -' - -test_expect_success "GET IPNS path succeeds" ' - ipfs name publish --allow-offline "$HASH" && - PEERID=$(ipfs config Identity.PeerID) && - test_check_peerid "$PEERID" && - curl -sfo actual "http://127.0.0.1:$port/ipns/$PEERID" -' - -test_expect_success "GET IPNS path output looks good" ' - test_cmp expected actual -' - -test_expect_success "GET /ipfs/ipns/{peerid} returns redirect to the valid path" ' - PEERID=$(ipfs config Identity.PeerID) && - curl -sD - "http://127.0.0.1:$port/ipfs/ipns/${PEERID}?query=to-remember" > response_with_ipfs_ipns_ns && - test_should_contain "" response_with_ipfs_ipns_ns && - test_should_contain "" response_with_ipfs_ipns_ns -' - -test_expect_success "GET invalid IPFS path errors" ' - test_must_fail curl -sf "http://127.0.0.1:$port/ipfs/12345" -' - -test_expect_success "GET invalid path errors" ' - test_must_fail curl -sf "http://127.0.0.1:$port/12345" -' - -test_expect_success "GET /webui returns code expected" ' - test_curl_resp_http_code "http://127.0.0.1:$apiport/webui" "HTTP/1.1 302 Found" "HTTP/1.1 301 Moved Permanently" -' - -test_expect_success "GET /webui/ returns code expected" ' - test_curl_resp_http_code "http://127.0.0.1:$apiport/webui/" "HTTP/1.1 302 Found" "HTTP/1.1 301 Moved Permanently" -' - -test_expect_success "GET /logs returns logs" ' - test_expect_code 28 curl http://127.0.0.1:$apiport/logs -m1 > log_out -' - -test_expect_success "log output looks good" ' - grep "log API client connected" log_out -' - -test_expect_success "GET /api/v0/version succeeds" ' - curl -X POST -v "http://127.0.0.1:$apiport/api/v0/version" 2> version_out -' - -test_expect_success "output only has one transfer encoding header" ' - grep "Transfer-Encoding: chunked" version_out | wc -l | xargs echo > tecount_out && - echo "1" > tecount_exp && - test_cmp tecount_out tecount_exp -' - -curl_pprofmutex() { - curl -f -X POST "http://127.0.0.1:$apiport/debug/pprof-mutex/?fraction=$1" -} - -test_expect_success "set mutex fraction for pprof (negative so it doesn't enable)" ' - curl_pprofmutex -1 -' - -test_expect_success "test failure conditions of mutex pprof endpoint" ' - test_must_fail curl_pprofmutex && - test_must_fail curl_pprofmutex that_is_string && - test_must_fail curl -f -X GET "http://127.0.0.1:$apiport/debug/pprof-mutex/?fraction=-1" -' - -curl_pprofblock() { - curl -f -X POST "http://127.0.0.1:$apiport/debug/pprof-block/?rate=$1" -} - -test_expect_success "set blocking profiler rate for pprof (0 so it doesn't enable)" ' - curl_pprofblock 0 -' - -test_expect_success "test failure conditions of mutex block endpoint" ' - test_must_fail curl_pprofblock && - test_must_fail curl_pprofblock that_is_string && - test_must_fail curl -f -X GET "http://127.0.0.1:$apiport/debug/pprof-block/?rate=0" -' - -test_expect_success "setup index hash" ' - mkdir index && - echo "

" > index/index.html && - INDEXHASH=$(ipfs add -Q -r index) - echo index: $INDEXHASH -' - -test_expect_success "GET 'index.html' has correct content type" ' - curl -I "http://127.0.0.1:$port/ipfs/$INDEXHASH/" > indexout -' - -test_expect_success "output looks good" ' - grep "Content-Type: text/html" indexout -' - -test_expect_success "HEAD 'index.html' has no content" ' - curl -X HEAD --max-time 1 http://127.0.0.1:$port/ipfs/$INDEXHASH/ > output; - [ ! -s output ] -' - -# test ipfs readonly api - -test_curl_gateway_api() { - curl -sfo actual "http://127.0.0.1:$port/api/v0/$1" -} - -test_expect_success "get IPFS directory file through readonly API succeeds" ' - test_curl_gateway_api "cat?arg=$HASH2/test" -' - -test_expect_success "get IPFS directory file through readonly API output looks good" ' - test_cmp dir/test actual -' - -test_expect_success "refs IPFS directory file through readonly API succeeds" ' - test_curl_gateway_api "refs?arg=$HASH2/test" -' - -for cmd in add \ - block/put \ - bootstrap \ - config \ - dag/put \ - dag/import \ - dht \ - diag \ - id \ - mount \ - name/publish \ - object/put \ - object/new \ - object/patch \ - pin \ - ping \ - repo \ - stats \ - swarm \ - file \ - update \ - bitswap -do - test_expect_success "test gateway api is sanitized: $cmd" ' - test_curl_resp_http_code "http://127.0.0.1:$port/api/v0/$cmd" "HTTP/1.1 404 Not Found" - ' -done - -# This one is different. `local` will be interpreted as a path if the command isn't defined. -test_expect_success "test gateway api is sanitized: refs/local" ' - echo "Error: invalid path \"local\": selected encoding not supported" > refs_local_expected && - ! ipfs --api /ip4/127.0.0.1/tcp/$port refs local > refs_local_actual 2>&1 && - test_cmp refs_local_expected refs_local_actual - ' - -test_expect_success "create raw-leaves node" ' - echo "This is RAW!" > rfile && - echo "This is RAW!" | ipfs add --raw-leaves -q > rhash -' - -test_expect_success "try fetching it from gateway" ' - curl http://127.0.0.1:$port/ipfs/$(cat rhash) > ffile && - test_cmp rfile ffile -' - -test_expect_success "Add compact blocks" ' - ipfs block put ../t0110-gateway-data/foo.block && - FOO2_HASH=$(ipfs block put --cid-codec=dag-pb ../t0110-gateway-data/foofoo.block) && - printf "foofoo" > expected -' - -test_expect_success "GET compact blocks succeeds" ' - curl -o actual "http://127.0.0.1:$port/ipfs/$FOO2_HASH" && - test_cmp expected actual -' - -test_expect_success "Verify gateway file" ' - cat "$IPFS_PATH/gateway" > gateway_file_actual && - echo -n "http://$GWAY_ADDR" > gateway_daemon_actual && - test_cmp gateway_daemon_actual gateway_file_actual -' - -test_kill_ipfs_daemon - -GWPORT=32563 - -test_expect_success "Verify gateway file diallable while on unspecified" ' - ipfs config Addresses.Gateway /ip4/0.0.0.0/tcp/$GWPORT && - test_launch_ipfs_daemon && - cat "$IPFS_PATH/gateway" > gateway_file_actual && - echo -n "http://127.0.0.1:$GWPORT" > gateway_file_expected && - test_cmp gateway_file_expected gateway_file_actual -' - -test_kill_ipfs_daemon - -test_expect_success "set up iptb testbed" ' - iptb testbed create -type localipfs -count 5 -force -init && - ipfsi 0 config Addresses.Gateway /ip4/127.0.0.1/tcp/$GWPORT && - PEERID_1=$(iptb attr get 1 id) -' - -test_expect_success "set NoFetch to true in config of node 0" ' - ipfsi 0 config --bool=true Gateway.NoFetch true -' - -test_expect_success "start ipfs nodes" ' - iptb start -wait && - iptb connect 0 1 -' - -test_expect_success "try fetching not present key from node 0" ' - FOO=$(echo "foo" | ipfsi 1 add -Q) && - test_expect_code 22 curl -f "http://127.0.0.1:$GWPORT/ipfs/$FOO" -' - -test_expect_success "try fetching not present ipns key from node 0" ' - ipfsi 1 name publish /ipfs/$FOO && - test_expect_code 22 curl -f "http://127.0.0.1:$GWPORT/ipns/$PEERID_1" -' - -test_expect_success "try fetching present key from node 0" ' - BAR=$(echo "bar" | ipfsi 0 add -Q) && - curl -f "http://127.0.0.1:$GWPORT/ipfs/$BAR" -' - -test_expect_success "try fetching present ipns key from node 0" ' - ipfsi 1 name publish /ipfs/$BAR && - curl "http://127.0.0.1:$GWPORT/ipns/$PEERID_1" -' - -test_expect_success "stop testbed" ' - iptb stop -' - -test_done From 1fa3a789d48708187211f5263285839cc9c28cd5 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Sat, 14 Jan 2023 22:49:07 +0100 Subject: [PATCH 0389/1212] fix: User-Agent sent to HTTP routers See https://github.com/ipfs/go-libipfs/issues/17 and https://github.com/ipfs/go-libipfs/pull/31 --- docs/examples/kubo-as-a-library/go.mod | 15 ++--- docs/examples/kubo-as-a-library/go.sum | 62 +++++------------- go.mod | 17 +++-- go.sum | 64 +++++-------------- routing/delegated.go | 2 + test/sharness/lib/test-lib.sh | 4 +- .../t0172-content-routing-over-http.sh | 13 ++-- 7 files changed, 59 insertions(+), 118 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 040cec571..edc684831 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.18 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/go-libipfs v0.1.0 + github.com/ipfs/go-libipfs v0.2.0 github.com/ipfs/interface-go-ipfs-core v0.8.2 github.com/ipfs/kubo v0.14.0-rc1 github.com/libp2p/go-libp2p v0.24.2 @@ -17,7 +17,6 @@ require ( require ( bazil.org/fuse v0.0.0-20200117225306-7b5117fecadc // indirect github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 // indirect - github.com/Stebalien/go-bitfield v0.0.1 // indirect github.com/alecthomas/units v0.0.0-20210927113745-59d0afb8317a // indirect github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5 // indirect github.com/benbjohnson/clock v1.3.0 // indirect @@ -91,21 +90,21 @@ require ( github.com/ipfs/go-ipfs-provider v0.8.1 // indirect github.com/ipfs/go-ipfs-routing v0.3.0 // indirect github.com/ipfs/go-ipfs-util v0.0.2 // indirect - github.com/ipfs/go-ipld-cbor v0.0.5 // indirect + github.com/ipfs/go-ipld-cbor v0.0.6 // indirect github.com/ipfs/go-ipld-format v0.4.0 // indirect github.com/ipfs/go-ipld-git v0.1.1 // indirect github.com/ipfs/go-ipld-legacy v0.1.1 // indirect github.com/ipfs/go-ipns v0.3.0 // indirect github.com/ipfs/go-log v1.0.5 // indirect github.com/ipfs/go-log/v2 v2.5.1 // indirect - github.com/ipfs/go-merkledag v0.8.1 // indirect + github.com/ipfs/go-merkledag v0.9.0 // indirect github.com/ipfs/go-metrics-interface v0.0.1 // indirect github.com/ipfs/go-mfs v0.2.1 // indirect github.com/ipfs/go-namesys v0.6.0 // indirect github.com/ipfs/go-path v0.3.0 // indirect github.com/ipfs/go-peertaskqueue v0.8.0 // indirect github.com/ipfs/go-unixfs v0.4.2 // indirect - github.com/ipfs/go-unixfsnode v1.4.0 // indirect + github.com/ipfs/go-unixfsnode v1.5.1 // indirect github.com/ipfs/go-verifcid v0.0.2 // indirect github.com/ipld/edelweiss v0.2.0 // indirect github.com/ipld/go-codec-dagpb v1.5.0 // indirect @@ -142,7 +141,7 @@ require ( github.com/marten-seemann/qtls-go1-19 v0.1.1 // indirect github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect github.com/marten-seemann/webtransport-go v0.4.3 // indirect - github.com/mattn/go-isatty v0.0.16 // indirect + github.com/mattn/go-isatty v0.0.17 // indirect github.com/mattn/go-pointer v0.0.1 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/miekg/dns v1.1.50 // indirect @@ -177,7 +176,7 @@ require ( github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc // indirect - github.com/whyrusleeping/cbor-gen v0.0.0-20210219115102-f37d292932f2 // indirect + github.com/whyrusleeping/cbor-gen v0.0.0-20221220214510-0333c149dec0 // indirect github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f // indirect github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 // indirect @@ -208,7 +207,7 @@ require ( golang.org/x/sys v0.4.0 // indirect golang.org/x/text v0.5.0 // indirect golang.org/x/tools v0.3.0 // indirect - golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f // indirect + golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1 // indirect google.golang.org/grpc v1.47.0 // indirect google.golang.org/protobuf v1.28.1 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index b35804386..fa6c022f3 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -36,7 +36,6 @@ cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RX cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -dmitri.shuralyov.com/gpu/mtl v0.0.0-20201218220906-28db891af037/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU= dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4= dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU= @@ -55,7 +54,6 @@ github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWX github.com/Shopify/sarama v1.30.0/go.mod h1:zujlQQx1kzHsh4jfV1USnptCQrHAEZ2Hk8fTKCulPVs= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/Shopify/toxiproxy/v2 v2.1.6-0.20210914104332-15ea381dcdae/go.mod h1:/cvHQkZ1fst0EmZnA5dFtiQdWCNCFYzb+uE2vqVgvx0= -github.com/Stebalien/go-bitfield v0.0.1 h1:X3kbSSPUaJK60wV2hjOPZwmpljr6VGCqdq4cBLhbQBo= github.com/Stebalien/go-bitfield v0.0.1/go.mod h1:GNjFpasyUVkHMsfEOk8EFLJ9syQ6SI+XWrX9Wf2XH0s= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= @@ -150,7 +148,6 @@ github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3Ee github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= @@ -223,7 +220,6 @@ github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVB github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/frankban/quicktest v1.14.0/go.mod h1:NeW+ay9A/U67EYXNFA1nPE8e/tnQv/09mUdL/ijj8og= -github.com/frankban/quicktest v1.14.2/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps= github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= @@ -244,7 +240,6 @@ github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9 github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= -github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= @@ -491,7 +486,6 @@ github.com/ipfs/go-graphsync v0.14.1/go.mod h1:S6O/c5iXOXqDgrQgiZSgOTRUSiVvpKEhr github.com/ipfs/go-ipfs-blockstore v0.0.1/go.mod h1:d3WClOmRQKFnJ0Jz/jj/zmksX0ma1gROTlovZKBmN08= github.com/ipfs/go-ipfs-blockstore v0.1.0/go.mod h1:5aD0AvHPi7mZc6Ci1WCAhiBQu2IsfTduLl+422H6Rqw= github.com/ipfs/go-ipfs-blockstore v0.2.1/go.mod h1:jGesd8EtCM3/zPgx+qr0/feTXGUeRai6adgwC+Q+JvE= -github.com/ipfs/go-ipfs-blockstore v1.1.2/go.mod h1:w51tNR9y5+QXB0wkNcHt4O2aSZjTdqaEWaQdSxEyUOY= github.com/ipfs/go-ipfs-blockstore v1.2.0 h1:n3WTeJ4LdICWs/0VSfjHrlqpPpl6MZ+ySd3j8qz0ykw= github.com/ipfs/go-ipfs-blockstore v1.2.0/go.mod h1:eh8eTFLiINYNSNawfZOC7HOxNTxpB1PFuA5E1m/7exE= github.com/ipfs/go-ipfs-blocksutil v0.0.1 h1:Eh/H4pc1hsvhzsQoMEP3Bke/aW5P5rVM1IWFJMcGIPQ= @@ -536,8 +530,9 @@ github.com/ipfs/go-ipfs-util v0.0.2 h1:59Sswnk1MFaiq+VcaknX7aYEyGyGDAA73ilhEK2PO github.com/ipfs/go-ipfs-util v0.0.2/go.mod h1:CbPtkWJzjLdEcezDns2XYaehFVNXG9zrdrtMecczcsQ= github.com/ipfs/go-ipld-cbor v0.0.2/go.mod h1:wTBtrQZA3SoFKMVkp6cn6HMRteIB1VsmHA0AQFOn7Nc= github.com/ipfs/go-ipld-cbor v0.0.3/go.mod h1:wTBtrQZA3SoFKMVkp6cn6HMRteIB1VsmHA0AQFOn7Nc= -github.com/ipfs/go-ipld-cbor v0.0.5 h1:ovz4CHKogtG2KB/h1zUp5U0c/IzZrL435rCh5+K/5G8= github.com/ipfs/go-ipld-cbor v0.0.5/go.mod h1:BkCduEx3XBCO6t2Sfo5BaHzuok7hbhdMm9Oh8B2Ftq4= +github.com/ipfs/go-ipld-cbor v0.0.6 h1:pYuWHyvSpIsOOLw4Jy7NbBkCyzLDcl64Bf/LZW7eBQ0= +github.com/ipfs/go-ipld-cbor v0.0.6/go.mod h1:ssdxxaLJPXH7OjF5V4NSjBbcfh+evoR4ukuru0oPXMA= github.com/ipfs/go-ipld-format v0.0.1/go.mod h1:kyJtbkDALmFHv3QR6et67i35QzO3S0dCDnkOJhcZkms= github.com/ipfs/go-ipld-format v0.0.2/go.mod h1:4B6+FM2u9OJ9zCV+kSbgFAZlOrv1Hqbf0INGQgiKf9k= github.com/ipfs/go-ipld-format v0.2.0/go.mod h1:3l3C1uKoadTPbeNfrDi+xMInYKlx2Cvg1BuydPSdzQs= @@ -551,8 +546,8 @@ github.com/ipfs/go-ipld-legacy v0.1.1 h1:BvD8PEuqwBHLTKqlGFTHSwrwFOMkVESEvwIYwR2 github.com/ipfs/go-ipld-legacy v0.1.1/go.mod h1:8AyKFCjgRPsQFf15ZQgDB8Din4DML/fOmKZkkFkrIEg= github.com/ipfs/go-ipns v0.3.0 h1:ai791nTgVo+zTuq2bLvEGmWP1M0A6kGTXUsgv/Yq67A= github.com/ipfs/go-ipns v0.3.0/go.mod h1:3cLT2rbvgPZGkHJoPO1YMJeh6LtkxopCkKFcio/wE24= -github.com/ipfs/go-libipfs v0.1.0 h1:I6CrHHp4cIiqsWJPVU3QBH4BZrRWSljS2aAbA3Eg9AY= -github.com/ipfs/go-libipfs v0.1.0/go.mod h1:qX0d9h+wu53PFtCTXxdXVBakd6ZCvGDdkZUKmdLMLx0= +github.com/ipfs/go-libipfs v0.2.0 h1:MedvelDEddPYL3iDLoqAsviLeXUiwB1F2t8fkzx9/EU= +github.com/ipfs/go-libipfs v0.2.0/go.mod h1:qX0d9h+wu53PFtCTXxdXVBakd6ZCvGDdkZUKmdLMLx0= github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= github.com/ipfs/go-log v1.0.2/go.mod h1:1MNjMxe0u6xvJZgeqbJ8vdo2TKaGwZ1a0Bpza+sr2Sk= github.com/ipfs/go-log v1.0.3/go.mod h1:OsLySYkwIbiSUR/yBTdv1qPtcE4FW3WPWk/ewz9Ru+A= @@ -571,8 +566,8 @@ github.com/ipfs/go-merkledag v0.2.3/go.mod h1:SQiXrtSts3KGNmgOzMICy5c0POOpUNQLvB github.com/ipfs/go-merkledag v0.3.2/go.mod h1:fvkZNNZixVW6cKSZ/JfLlON5OlgTXNdRLz0p6QG/I2M= github.com/ipfs/go-merkledag v0.5.1/go.mod h1:cLMZXx8J08idkp5+id62iVftUQV+HlYJ3PIhDfZsjA4= github.com/ipfs/go-merkledag v0.6.0/go.mod h1:9HSEwRd5sV+lbykiYP+2NC/3o6MZbKNaa4hfNcH5iH0= -github.com/ipfs/go-merkledag v0.8.1 h1:N3yrqSre/ffvdwtHL4MXy0n7XH+VzN8DlzDrJySPa94= -github.com/ipfs/go-merkledag v0.8.1/go.mod h1:uYUlWE34GhbcTjGuUDEcdPzsEtOdnOupL64NgSRjmWI= +github.com/ipfs/go-merkledag v0.9.0 h1:DFC8qZ96Dz1hMT7dtIpcY524eFFDiEWAF8hNJHWW2pk= +github.com/ipfs/go-merkledag v0.9.0/go.mod h1:bPHqkHt5OZ0p1n3iqPeDiw2jIBkjAytRjS3WSBwjq90= github.com/ipfs/go-metrics-interface v0.0.1 h1:j+cpbjYvu4R8zbleSs36gvB7jR+wsL2fGD6n0jO4kdg= github.com/ipfs/go-metrics-interface v0.0.1/go.mod h1:6s6euYU4zowdslK0GKHmqaIZ3j/b/tL7HTWtJ4VPgWY= github.com/ipfs/go-mfs v0.2.1 h1:5jz8+ukAg/z6jTkollzxGzhkl3yxm022Za9f2nL5ab8= @@ -591,8 +586,8 @@ github.com/ipfs/go-unixfs v0.3.1/go.mod h1:h4qfQYzghiIc8ZNFKiLMFWOTzrWIAtzYQ59W/ github.com/ipfs/go-unixfs v0.4.2 h1:hdQlsHHK5tek9gC9mjGVua8xyTqC+eopGseCRcbCZNg= github.com/ipfs/go-unixfs v0.4.2/go.mod h1:L+x6JRlFE0PfyMqeoLYVOKLhn5IeZHvNT7ZI51Y9Qyc= github.com/ipfs/go-unixfsnode v1.1.2/go.mod h1:5dcE2x03pyjHk4JjamXmunTMzz+VUtqvPwZjIEkfV6s= -github.com/ipfs/go-unixfsnode v1.4.0 h1:9BUxHBXrbNi8mWHc6j+5C580WJqtVw9uoeEKn4tMhwA= -github.com/ipfs/go-unixfsnode v1.4.0/go.mod h1:qc7YFFZ8tABc58p62HnIYbUMwj9chhUuFWmxSokfePo= +github.com/ipfs/go-unixfsnode v1.5.1 h1:JcR3t5C2nM1V7PMzhJ/Qmo19NkoFIKweDSZyDx+CjkI= +github.com/ipfs/go-unixfsnode v1.5.1/go.mod h1:ed79DaG9IEuZITJVQn4U6MZDftv6I3ygUBLPfhEbHvk= github.com/ipfs/go-verifcid v0.0.1/go.mod h1:5Hrva5KBeIog4A+UpqlaIU+DEstipcJYQQZc0g37pY0= github.com/ipfs/go-verifcid v0.0.2 h1:XPnUv0XmdH+ZIhLGKg6U2vaPaRDXb9urMyNVCE7uvTs= github.com/ipfs/go-verifcid v0.0.2/go.mod h1:40cD9x1y4OWnFXbLNJYRe7MpNvWlMn3LZAG5Wb4xnPU= @@ -601,19 +596,15 @@ github.com/ipfs/interface-go-ipfs-core v0.8.2/go.mod h1:F3EcmDy53GFkF0H3iEJpfJC3 github.com/ipld/edelweiss v0.2.0 h1:KfAZBP8eeJtrLxLhi7r3N0cBCo7JmwSRhOJp3WSpNjk= github.com/ipld/edelweiss v0.2.0/go.mod h1:FJAzJRCep4iI8FOFlRriN9n0b7OuX3T/S9++NpBDmA4= github.com/ipld/go-car v0.4.0 h1:U6W7F1aKF/OJMHovnOVdst2cpQE5GhmHibQkAixgNcQ= -github.com/ipld/go-car/v2 v2.1.1/go.mod h1:+2Yvf0Z3wzkv7NeI69i8tuZ+ft7jyjPYIWZzeVNeFcI= -github.com/ipld/go-car/v2 v2.4.0 h1:8jI6/iKlyLqRZzLz31jFWTqKvslaVzFsin305sOuqNQ= +github.com/ipld/go-car/v2 v2.5.1 h1:U2ux9JS23upEgrJScW8VQuxmE94560kYxj9CQUpcfmk= github.com/ipld/go-codec-dagpb v1.3.0/go.mod h1:ga4JTU3abYApDC3pZ00BC2RSvC3qfBb9MSJkMLSwnhA= github.com/ipld/go-codec-dagpb v1.5.0 h1:RspDRdsJpLfgCI0ONhTAnbHdySGD4t+LHSPK4X1+R0k= github.com/ipld/go-codec-dagpb v1.5.0/go.mod h1:0yRIutEFD8o1DGVqw4RSHh+BUTlJA9XWldxaaWR/o4g= 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.14.0/go.mod h1:9ASQLwUFLptCov6lIYc70GRB4V7UTyLD0IJtrDJe6ZM= github.com/ipld/go-ipld-prime v0.14.1/go.mod h1:QcE4Y9n/ZZr8Ijg5bGPT0GqYWgZ1704nH0RDcQtgTP0= -github.com/ipld/go-ipld-prime v0.16.0/go.mod h1:axSCuOCBPqrH+gvXr2w9uAOulJqBPhHPT2PjoiiU1qA= github.com/ipld/go-ipld-prime v0.19.0 h1:5axC7rJmPc17Emw6TelxGwnzALk0PdupZ2oj2roDj04= github.com/ipld/go-ipld-prime v0.19.0/go.mod h1:Q9j3BaVXwaA3o5JUDNvptDDr/x8+F7FG6XJ8WI3ILg4= -github.com/ipld/go-ipld-prime/storage/bsadapter v0.0.0-20211210234204-ce2a1c70cd73/go.mod h1:2PJ0JgxyB08t0b2WKrcuqI3di0V+5n6RS/LTUJhkoxY= 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= @@ -665,7 +656,6 @@ github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47e github.com/klauspost/compress v1.15.12 h1:YClS/PImqYbn+UILDnqxQCZ3RehC9N318SU3kElDUEM= github.com/klauspost/compress v1.15.12/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= 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/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.1 h1:U33DW0aiEj633gHYw3LoDNfkDiYnE5Q8M/TKJn2f2jI= github.com/klauspost/cpuid/v2 v2.2.1/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= @@ -930,8 +920,8 @@ github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hd github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= +github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-pointer v0.0.1 h1:n+XhsuGeVO6MEAp7xyEukFINEa+Quek5psIR/ylA6o0= github.com/mattn/go-pointer v0.0.1/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= @@ -1022,8 +1012,6 @@ github.com/multiformats/go-multibase v0.0.3/go.mod h1:5+1R4eQrT3PkYZ24C3W2Ue2tPw github.com/multiformats/go-multibase v0.1.1 h1:3ASCDsuLX8+j4kx58qnJ4YFq/JWTJpCyDW27ztsVTOI= github.com/multiformats/go-multibase v0.1.1/go.mod h1:ZEjHE+IsUrgp5mhlEAYjMtZwK1k4haNkcaPg9aoe1a8= github.com/multiformats/go-multicodec v0.3.0/go.mod h1:qGGaQmioCDh+TeFOnxrbU0DaIPw8yFgAZgFG0V7p1qQ= -github.com/multiformats/go-multicodec v0.3.1-0.20210902112759-1539a079fd61/go.mod h1:1Hj/eHRaVWSXiSNNfcEPcwZleTmdNP81xlxDLnWU9GQ= -github.com/multiformats/go-multicodec v0.3.1-0.20211210143421-a526f306ed2c/go.mod h1:1Hj/eHRaVWSXiSNNfcEPcwZleTmdNP81xlxDLnWU9GQ= github.com/multiformats/go-multicodec v0.7.0 h1:rTUjGOwjlhGHbEMbPoSUJowG1spZTVsITRANCjKTUAQ= github.com/multiformats/go-multicodec v0.7.0/go.mod h1:GUC8upxSBE4oG+q3kWZRw/+6yC1BqO550bjhWsJbZlw= github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= @@ -1108,7 +1096,6 @@ github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtP 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= github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 h1:1/WtZae0yGtPq+TI6+Tv1WTxkukpXeMlviSxvL7SRgk= -github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9/go.mod h1:x3N5drFsm2uilKKuuYo6LdyD8vZAW55sH/9w+pbo1sw= github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pierrec/lz4 v2.6.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= @@ -1174,8 +1161,6 @@ github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6L github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= -github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= -github.com/rs/zerolog v1.21.0/go.mod h1:ZPhntP/xmq1nnND05hhpAh2QMhSsA4UN3MGZ6O2J3hM= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd/go.mod h1:hPqNNc0+uJM6H+SuU8sEs5K5IQeKccPqeSjfgcKGgPk= @@ -1284,10 +1269,9 @@ github.com/warpfork/go-wish v0.0.0-20200122115046-b9ea61034e4a/go.mod h1:x6AKhvS github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc h1:BCPnHtcboadS0DvysUuJXZ4lWVv5Bh5i7+tbIyi+ck4= github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc/go.mod h1:r45hJU7yEoA81k6MWNhpMj/kms0n14dkzkxYHoB96UM= github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11 h1:5HZfQkwe0mIfyDmc1Em5GqlNRzcdtlv4HTNmdpt7XH0= -github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11/go.mod h1:Wlo/SzPmxVp6vXpGt/zaXhHH0fn4IxgqZc82aKg6bpQ= github.com/whyrusleeping/cbor-gen v0.0.0-20200123233031-1cdf64d27158/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI= -github.com/whyrusleeping/cbor-gen v0.0.0-20210219115102-f37d292932f2 h1:bsUlNhdmbtlfdLVXAVfuvKQ01RnWAM09TVrJkI7NZs4= -github.com/whyrusleeping/cbor-gen v0.0.0-20210219115102-f37d292932f2/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= +github.com/whyrusleeping/cbor-gen v0.0.0-20221220214510-0333c149dec0 h1:obKzQ1ey5AJg5NKjgtTo/CKwLImVP4ETLRcsmzFJ4Qw= +github.com/whyrusleeping/cbor-gen v0.0.0-20221220214510-0333c149dec0/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f h1:jQa4QT2UP9WYv2nzyawpKMOCl+Z/jW7djv2/J50lj9E= github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f/go.mod h1:p9UJB6dDgdPgMJZs7UjUOdulKyRr9fqkS+6JKAInPy8= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 h1:EKhdznlJHPMoKr0XTrX+IlJs1LH3lyx2nfr1dOlZ79k= @@ -1327,7 +1311,6 @@ go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/otel v0.20.0/go.mod h1:Y3ugLH2oa81t5QO+Lty+zXf8zC9L26ax4Nzoxm/dooo= go.opentelemetry.io/otel v1.7.0 h1:Z2lA3Tdch0iDcrhJXDIlC94XE+bxok1F9B+4Lz/lGsM= go.opentelemetry.io/otel v1.7.0/go.mod h1:5BdUoMIz5WEs0vt0CUEMtSSaTSHBBVwrhnz7+nrD5xk= go.opentelemetry.io/otel/exporters/jaeger v1.7.0 h1:wXgjiRldljksZkZrldGVe6XrG9u3kYDyQmkZwmm5dI0= @@ -1344,12 +1327,8 @@ go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.7.0 h1:8hPcgCg0rUJiKE6V go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.7.0/go.mod h1:K4GDXPY6TjUiwbOh+DkKaEdCF8y+lvMoM6SeAPyfCCM= go.opentelemetry.io/otel/exporters/zipkin v1.7.0 h1:X0FZj+kaIdLi29UiyrEGDhRTYsEXj9GdEW5Y39UQFEE= go.opentelemetry.io/otel/exporters/zipkin v1.7.0/go.mod h1:9YBXeOMFLQGwNEjsxMRiWPGoJX83usGMhbCmxUbNe5I= -go.opentelemetry.io/otel/metric v0.20.0/go.mod h1:598I5tYlH1vzBjn+BTuhzTCSb/9debfNp6R3s7Pr1eU= -go.opentelemetry.io/otel/oteltest v0.20.0/go.mod h1:L7bgKf9ZB7qCwT9Up7i9/pn0PWIa9FqQ2IQ8LoxiGnw= -go.opentelemetry.io/otel/sdk v0.20.0/go.mod h1:g/IcepuwNsoiX5Byy2nNV0ySUF1em498m7hBWC279Yc= go.opentelemetry.io/otel/sdk v1.7.0 h1:4OmStpcKVOfvDOgCt7UriAPtKolwIhxpnSNI/yK+1B0= go.opentelemetry.io/otel/sdk v1.7.0/go.mod h1:uTEOTwaqIVuTGiJN7ii13Ibp75wJmYUDe374q6cZwUU= -go.opentelemetry.io/otel/trace v0.20.0/go.mod h1:6GjCW8zgDjwGHGa6GkyeB8+/5vjT16gUEi0Nf1iBdgw= go.opentelemetry.io/otel/trace v1.7.0 h1:O37Iogk1lEkMRXewVtZ1BBTVn5JEp8GrJvP92bJqC6o= go.opentelemetry.io/otel/trace v1.7.0/go.mod h1:fzLSB9nqR2eXzxPXb2JW9IKE+ScyXA48yyE4TNvoHqU= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= @@ -1374,7 +1353,6 @@ go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/ go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= -go.uber.org/multierr v1.7.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= @@ -1418,15 +1396,12 @@ golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210506145944-38f3c27a63bf/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= -golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= -golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210920023735-84f357641f63/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.3.0 h1:a06MkbcxBrEFc0w0QIZWXrH/9cCX6KJyWbBOIwAn+7A= golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= @@ -1434,7 +1409,6 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20210615023648-acb5c1269671/go.mod h1:DVyR6MI7P4kEQgvZJSj1fQGrWIi2RzIrfYWycwheUAc= golang.org/x/exp v0.0.0-20221205204356-47842c84f3db h1:D/cFflL63o2KSLJIwjlcIt8PR064j/xsmdEJL/YvY/o= golang.org/x/exp v0.0.0-20221205204356-47842c84f3db/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= @@ -1452,12 +1426,10 @@ golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPI golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= -golang.org/x/mobile v0.0.0-20201217150744-e6ae53a27f4f/go.mod h1:skQtrUTUwhdJvXM/2KKJzY8pDgNr9I/FOMqDVRPBUS4= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.1.1-0.20191209134235-331c550502dd/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= @@ -1623,7 +1595,6 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210426080607-c94f62235c83/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1683,7 +1654,6 @@ golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapK golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200117012304-6edc0a871e69/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= @@ -1705,7 +1675,6 @@ golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= @@ -1715,8 +1684,8 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f h1:uF6paiQQebLeSXkrTqHqz0MXhXXS1KgF41eUdBNvxK0= -golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y= @@ -1870,7 +1839,6 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= lukechampine.com/blake3 v1.1.6/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= lukechampine.com/blake3 v1.1.7 h1:GgRMhmdsuK8+ii6UZFDL8Nb+VyMwadAgcJyfYHxG6n0= lukechampine.com/blake3 v1.1.7/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= diff --git a/go.mod b/go.mod index 238774683..b837fa504 100644 --- a/go.mod +++ b/go.mod @@ -49,10 +49,10 @@ require ( github.com/ipfs/go-ipld-git v0.1.1 github.com/ipfs/go-ipld-legacy v0.1.1 github.com/ipfs/go-ipns v0.3.0 - github.com/ipfs/go-libipfs v0.1.0 + github.com/ipfs/go-libipfs v0.2.0 github.com/ipfs/go-log v1.0.5 github.com/ipfs/go-log/v2 v2.5.1 - github.com/ipfs/go-merkledag v0.8.1 + github.com/ipfs/go-merkledag v0.9.0 github.com/ipfs/go-metrics-interface v0.0.1 github.com/ipfs/go-metrics-prometheus v0.0.2 github.com/ipfs/go-mfs v0.2.1 @@ -60,11 +60,11 @@ require ( github.com/ipfs/go-path v0.3.0 github.com/ipfs/go-pinning-service-http-client v0.1.2 github.com/ipfs/go-unixfs v0.4.2 - github.com/ipfs/go-unixfsnode v1.4.0 + github.com/ipfs/go-unixfsnode v1.5.1 github.com/ipfs/go-verifcid v0.0.2 github.com/ipfs/interface-go-ipfs-core v0.8.2 github.com/ipld/go-car v0.4.0 - github.com/ipld/go-car/v2 v2.4.0 + github.com/ipld/go-car/v2 v2.5.1 github.com/ipld/go-codec-dagpb v1.5.0 github.com/ipld/go-ipld-prime v0.19.0 github.com/jbenet/go-random v0.0.0-20190219211222-123a90aedc0c @@ -118,7 +118,6 @@ require ( require ( github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 // indirect github.com/Kubuxu/go-os-helper v0.0.1 // indirect - github.com/Stebalien/go-bitfield v0.0.1 // indirect github.com/alecthomas/units v0.0.0-20210927113745-59d0afb8317a // indirect github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5 // indirect github.com/beorn7/perks v1.0.1 // indirect @@ -162,7 +161,7 @@ require ( github.com/ipfs/go-ipfs-delay v0.0.1 // indirect github.com/ipfs/go-ipfs-ds-help v1.1.0 // indirect github.com/ipfs/go-ipfs-pq v0.0.2 // indirect - github.com/ipfs/go-ipld-cbor v0.0.5 // indirect + github.com/ipfs/go-ipld-cbor v0.0.6 // indirect github.com/ipfs/go-peertaskqueue v0.8.0 // indirect github.com/ipld/edelweiss v0.2.0 // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect @@ -190,7 +189,7 @@ require ( github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect github.com/marten-seemann/webtransport-go v0.4.3 // indirect github.com/mattn/go-colorable v0.1.4 // indirect - github.com/mattn/go-isatty v0.0.16 // indirect + github.com/mattn/go-isatty v0.0.17 // indirect github.com/mattn/go-pointer v0.0.1 // indirect github.com/mattn/go-runewidth v0.0.4 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect @@ -221,7 +220,7 @@ require ( github.com/texttheater/golang-levenshtein v0.0.0-20180516184445-d188e65d659e // indirect github.com/ucarion/urlpath v0.0.0-20200424170820-7ccc79b76bbb // indirect github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc // indirect - github.com/whyrusleeping/cbor-gen v0.0.0-20200710004633-5379fc63235d // indirect + github.com/whyrusleeping/cbor-gen v0.0.0-20221220214510-0333c149dec0 // indirect github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f // indirect github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect github.com/whyrusleeping/timecache v0.0.0-20160911033111-cfcb2f1abfee // indirect @@ -238,7 +237,7 @@ require ( golang.org/x/term v0.4.0 // indirect golang.org/x/text v0.5.0 // indirect golang.org/x/tools v0.3.0 // indirect - golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f // indirect + golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/appengine v1.6.6 // indirect google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1 // indirect google.golang.org/grpc v1.46.0 // indirect diff --git a/go.sum b/go.sum index 605ea36c3..6274ef85b 100644 --- a/go.sum +++ b/go.sum @@ -38,7 +38,6 @@ contrib.go.opencensus.io/exporter/prometheus v0.4.0 h1:0QfIkj9z/iVZgK31D9H9ohjjI contrib.go.opencensus.io/exporter/prometheus v0.4.0/go.mod h1:o7cosnyfuPVK0tB8q0QmaQNhGnptITnPQB+z1+qeFB0= dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -dmitri.shuralyov.com/gpu/mtl v0.0.0-20201218220906-28db891af037/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU= dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4= dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU= @@ -58,7 +57,6 @@ github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWX github.com/Shopify/sarama v1.30.0/go.mod h1:zujlQQx1kzHsh4jfV1USnptCQrHAEZ2Hk8fTKCulPVs= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/Shopify/toxiproxy/v2 v2.1.6-0.20210914104332-15ea381dcdae/go.mod h1:/cvHQkZ1fst0EmZnA5dFtiQdWCNCFYzb+uE2vqVgvx0= -github.com/Stebalien/go-bitfield v0.0.1 h1:X3kbSSPUaJK60wV2hjOPZwmpljr6VGCqdq4cBLhbQBo= github.com/Stebalien/go-bitfield v0.0.1/go.mod h1:GNjFpasyUVkHMsfEOk8EFLJ9syQ6SI+XWrX9Wf2XH0s= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= @@ -155,7 +153,6 @@ github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3Ee github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/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.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= @@ -235,7 +232,6 @@ github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVB github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/frankban/quicktest v1.14.0/go.mod h1:NeW+ay9A/U67EYXNFA1nPE8e/tnQv/09mUdL/ijj8og= -github.com/frankban/quicktest v1.14.2/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps= github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= @@ -261,7 +257,6 @@ github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA= github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= -github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= @@ -509,7 +504,6 @@ github.com/ipfs/go-graphsync v0.14.1/go.mod h1:S6O/c5iXOXqDgrQgiZSgOTRUSiVvpKEhr github.com/ipfs/go-ipfs-blockstore v0.0.1/go.mod h1:d3WClOmRQKFnJ0Jz/jj/zmksX0ma1gROTlovZKBmN08= github.com/ipfs/go-ipfs-blockstore v0.1.0/go.mod h1:5aD0AvHPi7mZc6Ci1WCAhiBQu2IsfTduLl+422H6Rqw= github.com/ipfs/go-ipfs-blockstore v0.2.1/go.mod h1:jGesd8EtCM3/zPgx+qr0/feTXGUeRai6adgwC+Q+JvE= -github.com/ipfs/go-ipfs-blockstore v1.1.2/go.mod h1:w51tNR9y5+QXB0wkNcHt4O2aSZjTdqaEWaQdSxEyUOY= github.com/ipfs/go-ipfs-blockstore v1.2.0 h1:n3WTeJ4LdICWs/0VSfjHrlqpPpl6MZ+ySd3j8qz0ykw= github.com/ipfs/go-ipfs-blockstore v1.2.0/go.mod h1:eh8eTFLiINYNSNawfZOC7HOxNTxpB1PFuA5E1m/7exE= github.com/ipfs/go-ipfs-blocksutil v0.0.1 h1:Eh/H4pc1hsvhzsQoMEP3Bke/aW5P5rVM1IWFJMcGIPQ= @@ -558,8 +552,9 @@ github.com/ipfs/go-ipfs-util v0.0.2 h1:59Sswnk1MFaiq+VcaknX7aYEyGyGDAA73ilhEK2PO github.com/ipfs/go-ipfs-util v0.0.2/go.mod h1:CbPtkWJzjLdEcezDns2XYaehFVNXG9zrdrtMecczcsQ= github.com/ipfs/go-ipld-cbor v0.0.2/go.mod h1:wTBtrQZA3SoFKMVkp6cn6HMRteIB1VsmHA0AQFOn7Nc= github.com/ipfs/go-ipld-cbor v0.0.3/go.mod h1:wTBtrQZA3SoFKMVkp6cn6HMRteIB1VsmHA0AQFOn7Nc= -github.com/ipfs/go-ipld-cbor v0.0.5 h1:ovz4CHKogtG2KB/h1zUp5U0c/IzZrL435rCh5+K/5G8= github.com/ipfs/go-ipld-cbor v0.0.5/go.mod h1:BkCduEx3XBCO6t2Sfo5BaHzuok7hbhdMm9Oh8B2Ftq4= +github.com/ipfs/go-ipld-cbor v0.0.6 h1:pYuWHyvSpIsOOLw4Jy7NbBkCyzLDcl64Bf/LZW7eBQ0= +github.com/ipfs/go-ipld-cbor v0.0.6/go.mod h1:ssdxxaLJPXH7OjF5V4NSjBbcfh+evoR4ukuru0oPXMA= github.com/ipfs/go-ipld-format v0.0.1/go.mod h1:kyJtbkDALmFHv3QR6et67i35QzO3S0dCDnkOJhcZkms= github.com/ipfs/go-ipld-format v0.0.2/go.mod h1:4B6+FM2u9OJ9zCV+kSbgFAZlOrv1Hqbf0INGQgiKf9k= github.com/ipfs/go-ipld-format v0.2.0/go.mod h1:3l3C1uKoadTPbeNfrDi+xMInYKlx2Cvg1BuydPSdzQs= @@ -573,8 +568,8 @@ github.com/ipfs/go-ipld-legacy v0.1.1 h1:BvD8PEuqwBHLTKqlGFTHSwrwFOMkVESEvwIYwR2 github.com/ipfs/go-ipld-legacy v0.1.1/go.mod h1:8AyKFCjgRPsQFf15ZQgDB8Din4DML/fOmKZkkFkrIEg= github.com/ipfs/go-ipns v0.3.0 h1:ai791nTgVo+zTuq2bLvEGmWP1M0A6kGTXUsgv/Yq67A= github.com/ipfs/go-ipns v0.3.0/go.mod h1:3cLT2rbvgPZGkHJoPO1YMJeh6LtkxopCkKFcio/wE24= -github.com/ipfs/go-libipfs v0.1.0 h1:I6CrHHp4cIiqsWJPVU3QBH4BZrRWSljS2aAbA3Eg9AY= -github.com/ipfs/go-libipfs v0.1.0/go.mod h1:qX0d9h+wu53PFtCTXxdXVBakd6ZCvGDdkZUKmdLMLx0= +github.com/ipfs/go-libipfs v0.2.0 h1:MedvelDEddPYL3iDLoqAsviLeXUiwB1F2t8fkzx9/EU= +github.com/ipfs/go-libipfs v0.2.0/go.mod h1:qX0d9h+wu53PFtCTXxdXVBakd6ZCvGDdkZUKmdLMLx0= github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= github.com/ipfs/go-log v1.0.2/go.mod h1:1MNjMxe0u6xvJZgeqbJ8vdo2TKaGwZ1a0Bpza+sr2Sk= github.com/ipfs/go-log v1.0.3/go.mod h1:OsLySYkwIbiSUR/yBTdv1qPtcE4FW3WPWk/ewz9Ru+A= @@ -593,8 +588,8 @@ github.com/ipfs/go-merkledag v0.2.3/go.mod h1:SQiXrtSts3KGNmgOzMICy5c0POOpUNQLvB github.com/ipfs/go-merkledag v0.3.2/go.mod h1:fvkZNNZixVW6cKSZ/JfLlON5OlgTXNdRLz0p6QG/I2M= github.com/ipfs/go-merkledag v0.5.1/go.mod h1:cLMZXx8J08idkp5+id62iVftUQV+HlYJ3PIhDfZsjA4= github.com/ipfs/go-merkledag v0.6.0/go.mod h1:9HSEwRd5sV+lbykiYP+2NC/3o6MZbKNaa4hfNcH5iH0= -github.com/ipfs/go-merkledag v0.8.1 h1:N3yrqSre/ffvdwtHL4MXy0n7XH+VzN8DlzDrJySPa94= -github.com/ipfs/go-merkledag v0.8.1/go.mod h1:uYUlWE34GhbcTjGuUDEcdPzsEtOdnOupL64NgSRjmWI= +github.com/ipfs/go-merkledag v0.9.0 h1:DFC8qZ96Dz1hMT7dtIpcY524eFFDiEWAF8hNJHWW2pk= +github.com/ipfs/go-merkledag v0.9.0/go.mod h1:bPHqkHt5OZ0p1n3iqPeDiw2jIBkjAytRjS3WSBwjq90= github.com/ipfs/go-metrics-interface v0.0.1 h1:j+cpbjYvu4R8zbleSs36gvB7jR+wsL2fGD6n0jO4kdg= github.com/ipfs/go-metrics-interface v0.0.1/go.mod h1:6s6euYU4zowdslK0GKHmqaIZ3j/b/tL7HTWtJ4VPgWY= github.com/ipfs/go-metrics-prometheus v0.0.2 h1:9i2iljLg12S78OhC6UAiXi176xvQGiZaGVF1CUVdE+s= @@ -617,8 +612,8 @@ github.com/ipfs/go-unixfs v0.3.1/go.mod h1:h4qfQYzghiIc8ZNFKiLMFWOTzrWIAtzYQ59W/ github.com/ipfs/go-unixfs v0.4.2 h1:hdQlsHHK5tek9gC9mjGVua8xyTqC+eopGseCRcbCZNg= github.com/ipfs/go-unixfs v0.4.2/go.mod h1:L+x6JRlFE0PfyMqeoLYVOKLhn5IeZHvNT7ZI51Y9Qyc= github.com/ipfs/go-unixfsnode v1.1.2/go.mod h1:5dcE2x03pyjHk4JjamXmunTMzz+VUtqvPwZjIEkfV6s= -github.com/ipfs/go-unixfsnode v1.4.0 h1:9BUxHBXrbNi8mWHc6j+5C580WJqtVw9uoeEKn4tMhwA= -github.com/ipfs/go-unixfsnode v1.4.0/go.mod h1:qc7YFFZ8tABc58p62HnIYbUMwj9chhUuFWmxSokfePo= +github.com/ipfs/go-unixfsnode v1.5.1 h1:JcR3t5C2nM1V7PMzhJ/Qmo19NkoFIKweDSZyDx+CjkI= +github.com/ipfs/go-unixfsnode v1.5.1/go.mod h1:ed79DaG9IEuZITJVQn4U6MZDftv6I3ygUBLPfhEbHvk= github.com/ipfs/go-verifcid v0.0.1/go.mod h1:5Hrva5KBeIog4A+UpqlaIU+DEstipcJYQQZc0g37pY0= github.com/ipfs/go-verifcid v0.0.2 h1:XPnUv0XmdH+ZIhLGKg6U2vaPaRDXb9urMyNVCE7uvTs= github.com/ipfs/go-verifcid v0.0.2/go.mod h1:40cD9x1y4OWnFXbLNJYRe7MpNvWlMn3LZAG5Wb4xnPU= @@ -628,21 +623,17 @@ github.com/ipld/edelweiss v0.2.0 h1:KfAZBP8eeJtrLxLhi7r3N0cBCo7JmwSRhOJp3WSpNjk= github.com/ipld/edelweiss v0.2.0/go.mod h1:FJAzJRCep4iI8FOFlRriN9n0b7OuX3T/S9++NpBDmA4= github.com/ipld/go-car v0.4.0 h1:U6W7F1aKF/OJMHovnOVdst2cpQE5GhmHibQkAixgNcQ= github.com/ipld/go-car v0.4.0/go.mod h1:Uslcn4O9cBKK9wqHm/cLTFacg6RAPv6LZx2mxd2Ypl4= -github.com/ipld/go-car/v2 v2.1.1/go.mod h1:+2Yvf0Z3wzkv7NeI69i8tuZ+ft7jyjPYIWZzeVNeFcI= -github.com/ipld/go-car/v2 v2.4.0 h1:8jI6/iKlyLqRZzLz31jFWTqKvslaVzFsin305sOuqNQ= -github.com/ipld/go-car/v2 v2.4.0/go.mod h1:zjpRf0Jew9gHqSvjsKVyoq9OY9SWoEKdYCQUKVaaPT0= +github.com/ipld/go-car/v2 v2.5.1 h1:U2ux9JS23upEgrJScW8VQuxmE94560kYxj9CQUpcfmk= +github.com/ipld/go-car/v2 v2.5.1/go.mod h1:jKjGOqoCj5zn6KjnabD6JbnCsMntqU2hLiU6baZVO3E= github.com/ipld/go-codec-dagpb v1.3.0/go.mod h1:ga4JTU3abYApDC3pZ00BC2RSvC3qfBb9MSJkMLSwnhA= github.com/ipld/go-codec-dagpb v1.5.0 h1:RspDRdsJpLfgCI0ONhTAnbHdySGD4t+LHSPK4X1+R0k= github.com/ipld/go-codec-dagpb v1.5.0/go.mod h1:0yRIutEFD8o1DGVqw4RSHh+BUTlJA9XWldxaaWR/o4g= 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.14.0/go.mod h1:9ASQLwUFLptCov6lIYc70GRB4V7UTyLD0IJtrDJe6ZM= github.com/ipld/go-ipld-prime v0.14.1/go.mod h1:QcE4Y9n/ZZr8Ijg5bGPT0GqYWgZ1704nH0RDcQtgTP0= -github.com/ipld/go-ipld-prime v0.16.0/go.mod h1:axSCuOCBPqrH+gvXr2w9uAOulJqBPhHPT2PjoiiU1qA= github.com/ipld/go-ipld-prime v0.19.0 h1:5axC7rJmPc17Emw6TelxGwnzALk0PdupZ2oj2roDj04= github.com/ipld/go-ipld-prime v0.19.0/go.mod h1:Q9j3BaVXwaA3o5JUDNvptDDr/x8+F7FG6XJ8WI3ILg4= github.com/ipld/go-ipld-prime/storage/bsadapter v0.0.0-20211210234204-ce2a1c70cd73 h1:TsyATB2ZRRQGTwafJdgEUQkmjOExRV0DNokcihZxbnQ= -github.com/ipld/go-ipld-prime/storage/bsadapter v0.0.0-20211210234204-ce2a1c70cd73/go.mod h1:2PJ0JgxyB08t0b2WKrcuqI3di0V+5n6RS/LTUJhkoxY= 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= @@ -695,7 +686,6 @@ github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47e github.com/klauspost/compress v1.15.12 h1:YClS/PImqYbn+UILDnqxQCZ3RehC9N318SU3kElDUEM= github.com/klauspost/compress v1.15.12/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= 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/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.1 h1:U33DW0aiEj633gHYw3LoDNfkDiYnE5Q8M/TKJn2f2jI= github.com/klauspost/cpuid/v2 v2.2.1/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= @@ -970,8 +960,8 @@ github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hd github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= +github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-pointer v0.0.1 h1:n+XhsuGeVO6MEAp7xyEukFINEa+Quek5psIR/ylA6o0= github.com/mattn/go-pointer v0.0.1/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= @@ -1066,8 +1056,6 @@ github.com/multiformats/go-multibase v0.0.3/go.mod h1:5+1R4eQrT3PkYZ24C3W2Ue2tPw github.com/multiformats/go-multibase v0.1.1 h1:3ASCDsuLX8+j4kx58qnJ4YFq/JWTJpCyDW27ztsVTOI= github.com/multiformats/go-multibase v0.1.1/go.mod h1:ZEjHE+IsUrgp5mhlEAYjMtZwK1k4haNkcaPg9aoe1a8= github.com/multiformats/go-multicodec v0.3.0/go.mod h1:qGGaQmioCDh+TeFOnxrbU0DaIPw8yFgAZgFG0V7p1qQ= -github.com/multiformats/go-multicodec v0.3.1-0.20210902112759-1539a079fd61/go.mod h1:1Hj/eHRaVWSXiSNNfcEPcwZleTmdNP81xlxDLnWU9GQ= -github.com/multiformats/go-multicodec v0.3.1-0.20211210143421-a526f306ed2c/go.mod h1:1Hj/eHRaVWSXiSNNfcEPcwZleTmdNP81xlxDLnWU9GQ= github.com/multiformats/go-multicodec v0.7.0 h1:rTUjGOwjlhGHbEMbPoSUJowG1spZTVsITRANCjKTUAQ= github.com/multiformats/go-multicodec v0.7.0/go.mod h1:GUC8upxSBE4oG+q3kWZRw/+6yC1BqO550bjhWsJbZlw= github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= @@ -1152,7 +1140,6 @@ github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtP 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= github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 h1:1/WtZae0yGtPq+TI6+Tv1WTxkukpXeMlviSxvL7SRgk= -github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9/go.mod h1:x3N5drFsm2uilKKuuYo6LdyD8vZAW55sH/9w+pbo1sw= github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pierrec/lz4 v2.6.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= @@ -1226,8 +1213,6 @@ github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBO github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= -github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= -github.com/rs/zerolog v1.21.0/go.mod h1:ZPhntP/xmq1nnND05hhpAh2QMhSsA4UN3MGZ6O2J3hM= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd/go.mod h1:hPqNNc0+uJM6H+SuU8sEs5K5IQeKccPqeSjfgcKGgPk= @@ -1341,10 +1326,9 @@ github.com/warpfork/go-wish v0.0.0-20200122115046-b9ea61034e4a/go.mod h1:x6AKhvS github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc h1:BCPnHtcboadS0DvysUuJXZ4lWVv5Bh5i7+tbIyi+ck4= github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc/go.mod h1:r45hJU7yEoA81k6MWNhpMj/kms0n14dkzkxYHoB96UM= github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11 h1:5HZfQkwe0mIfyDmc1Em5GqlNRzcdtlv4HTNmdpt7XH0= -github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11/go.mod h1:Wlo/SzPmxVp6vXpGt/zaXhHH0fn4IxgqZc82aKg6bpQ= github.com/whyrusleeping/cbor-gen v0.0.0-20200123233031-1cdf64d27158/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI= -github.com/whyrusleeping/cbor-gen v0.0.0-20200710004633-5379fc63235d h1:wSxKhvbN7kUoP0sfRS+w2tWr45qlU8409i94hHLOT8w= -github.com/whyrusleeping/cbor-gen v0.0.0-20200710004633-5379fc63235d/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= +github.com/whyrusleeping/cbor-gen v0.0.0-20221220214510-0333c149dec0 h1:obKzQ1ey5AJg5NKjgtTo/CKwLImVP4ETLRcsmzFJ4Qw= +github.com/whyrusleeping/cbor-gen v0.0.0-20221220214510-0333c149dec0/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f h1:jQa4QT2UP9WYv2nzyawpKMOCl+Z/jW7djv2/J50lj9E= github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f/go.mod h1:p9UJB6dDgdPgMJZs7UjUOdulKyRr9fqkS+6JKAInPy8= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 h1:EKhdznlJHPMoKr0XTrX+IlJs1LH3lyx2nfr1dOlZ79k= @@ -1388,7 +1372,6 @@ go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.32.0 h1:mac9BKRqwaX6zxHPDe3pvmWpwuuIM0vuXv2juCnQevE= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.32.0/go.mod h1:5eCOqeGphOyz6TsY3ZDNjE33SM/TFAK3RGuCL2naTgY= -go.opentelemetry.io/otel v0.20.0/go.mod h1:Y3ugLH2oa81t5QO+Lty+zXf8zC9L26ax4Nzoxm/dooo= go.opentelemetry.io/otel v1.7.0 h1:Z2lA3Tdch0iDcrhJXDIlC94XE+bxok1F9B+4Lz/lGsM= go.opentelemetry.io/otel v1.7.0/go.mod h1:5BdUoMIz5WEs0vt0CUEMtSSaTSHBBVwrhnz7+nrD5xk= go.opentelemetry.io/otel/exporters/jaeger v1.7.0 h1:wXgjiRldljksZkZrldGVe6XrG9u3kYDyQmkZwmm5dI0= @@ -1405,14 +1388,10 @@ go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.7.0 h1:8hPcgCg0rUJiKE6V go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.7.0/go.mod h1:K4GDXPY6TjUiwbOh+DkKaEdCF8y+lvMoM6SeAPyfCCM= go.opentelemetry.io/otel/exporters/zipkin v1.7.0 h1:X0FZj+kaIdLi29UiyrEGDhRTYsEXj9GdEW5Y39UQFEE= go.opentelemetry.io/otel/exporters/zipkin v1.7.0/go.mod h1:9YBXeOMFLQGwNEjsxMRiWPGoJX83usGMhbCmxUbNe5I= -go.opentelemetry.io/otel/metric v0.20.0/go.mod h1:598I5tYlH1vzBjn+BTuhzTCSb/9debfNp6R3s7Pr1eU= go.opentelemetry.io/otel/metric v0.30.0 h1:Hs8eQZ8aQgs0U49diZoaS6Uaxw3+bBE3lcMUKBFIk3c= go.opentelemetry.io/otel/metric v0.30.0/go.mod h1:/ShZ7+TS4dHzDFmfi1kSXMhMVubNoP0oIaBp70J6UXU= -go.opentelemetry.io/otel/oteltest v0.20.0/go.mod h1:L7bgKf9ZB7qCwT9Up7i9/pn0PWIa9FqQ2IQ8LoxiGnw= -go.opentelemetry.io/otel/sdk v0.20.0/go.mod h1:g/IcepuwNsoiX5Byy2nNV0ySUF1em498m7hBWC279Yc= go.opentelemetry.io/otel/sdk v1.7.0 h1:4OmStpcKVOfvDOgCt7UriAPtKolwIhxpnSNI/yK+1B0= go.opentelemetry.io/otel/sdk v1.7.0/go.mod h1:uTEOTwaqIVuTGiJN7ii13Ibp75wJmYUDe374q6cZwUU= -go.opentelemetry.io/otel/trace v0.20.0/go.mod h1:6GjCW8zgDjwGHGa6GkyeB8+/5vjT16gUEi0Nf1iBdgw= go.opentelemetry.io/otel/trace v1.7.0 h1:O37Iogk1lEkMRXewVtZ1BBTVn5JEp8GrJvP92bJqC6o= go.opentelemetry.io/otel/trace v1.7.0/go.mod h1:fzLSB9nqR2eXzxPXb2JW9IKE+ScyXA48yyE4TNvoHqU= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= @@ -1437,7 +1416,6 @@ go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/ go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= -go.uber.org/multierr v1.7.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= @@ -1481,15 +1459,12 @@ golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210506145944-38f3c27a63bf/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= -golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= -golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210920023735-84f357641f63/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.3.0 h1:a06MkbcxBrEFc0w0QIZWXrH/9cCX6KJyWbBOIwAn+7A= golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= @@ -1497,7 +1472,6 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20210615023648-acb5c1269671/go.mod h1:DVyR6MI7P4kEQgvZJSj1fQGrWIi2RzIrfYWycwheUAc= golang.org/x/exp v0.0.0-20221205204356-47842c84f3db h1:D/cFflL63o2KSLJIwjlcIt8PR064j/xsmdEJL/YvY/o= golang.org/x/exp v0.0.0-20221205204356-47842c84f3db/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= @@ -1515,12 +1489,10 @@ golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPI golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= -golang.org/x/mobile v0.0.0-20201217150744-e6ae53a27f4f/go.mod h1:skQtrUTUwhdJvXM/2KKJzY8pDgNr9I/FOMqDVRPBUS4= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.1.1-0.20191209134235-331c550502dd/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= @@ -1688,7 +1660,6 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210426080607-c94f62235c83/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1752,7 +1723,6 @@ golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapK golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200117012304-6edc0a871e69/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= @@ -1774,7 +1744,6 @@ golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= @@ -1784,8 +1753,8 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f h1:GGU+dLjvlC3qDwqYgL6UgRmHXhOOgns0bZu2Ty5mm6U= -golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y= @@ -1939,7 +1908,6 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= lukechampine.com/blake3 v1.1.6/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= lukechampine.com/blake3 v1.1.7 h1:GgRMhmdsuK8+ii6UZFDL8Nb+VyMwadAgcJyfYHxG6n0= lukechampine.com/blake3 v1.1.7/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= diff --git a/routing/delegated.go b/routing/delegated.go index d95053fd3..1e8d7efa0 100644 --- a/routing/delegated.go +++ b/routing/delegated.go @@ -13,6 +13,7 @@ import ( drclient "github.com/ipfs/go-libipfs/routing/http/client" "github.com/ipfs/go-libipfs/routing/http/contentrouter" logging "github.com/ipfs/go-log" + version "github.com/ipfs/kubo" "github.com/ipfs/kubo/config" dht "github.com/libp2p/go-libp2p-kad-dht" "github.com/libp2p/go-libp2p-kad-dht/dual" @@ -208,6 +209,7 @@ func httpRoutingFromConfig(conf config.Router, extraHTTP *ExtraHTTPParams) (rout drclient.WithHTTPClient(delegateHTTPClient), drclient.WithIdentity(key), drclient.WithProviderInfo(addrInfo.ID, addrInfo.Addrs), + drclient.WithUserAgent(version.GetUserAgentVersion()), ) if err != nil { return nil, err diff --git a/test/sharness/lib/test-lib.sh b/test/sharness/lib/test-lib.sh index 4ce2a6027..3aecaec99 100644 --- a/test/sharness/lib/test-lib.sh +++ b/test/sharness/lib/test-lib.sh @@ -144,8 +144,8 @@ test_run_repeat_60_sec() { return 1 # failed } -test_wait_output_n_lines_60_sec() { - for i in $(test_seq 1 600) +test_wait_output_n_lines() { + for i in $(test_seq 1 3600) do test $(cat "$1" | wc -l | tr -d " ") -ge $2 && return go-sleep 100ms diff --git a/test/sharness/t0172-content-routing-over-http.sh b/test/sharness/t0172-content-routing-over-http.sh index b173ca053..2dac04e7d 100755 --- a/test/sharness/t0172-content-routing-over-http.sh +++ b/test/sharness/t0172-content-routing-over-http.sh @@ -19,9 +19,9 @@ export IPFS_HTTP_ROUTERS="http://127.0.0.1:$ROUTER_PORT" test_launch_ipfs_daemon test_expect_success "start HTTP router proxy" ' - socat TCP-LISTEN:$ROUTER_PORT,reuseaddr,fork,bind=127.0.0.1,retry=10 STDOUT > http_requests & + touch http_requests + socat -u TCP-LISTEN:$ROUTER_PORT,reuseaddr,fork,bind=127.0.0.1,retry=10 CREATE:http_requests & NCPID=$! - test_wait_for_file 50 100ms http_requests ' ## HTTP GETs @@ -30,12 +30,16 @@ test_expect_success 'create unique CID without adding it to the local datastore' WANT_CID=$(date +"%FT%T.%N%z" | ipfs add -qn) ' -test_expect_success 'expect HTTP request for unknown CID' ' +test_expect_success 'expect HTTP lookup when CID is not in the local datastore' ' ipfs block stat "$WANT_CID" & - test_wait_output_n_lines_60_sec http_requests 3 && + test_wait_output_n_lines http_requests 4 && test_should_contain "GET /routing/v1/providers/$WANT_CID" http_requests ' +test_expect_success 'expect HTTP request User-Agent to match Kubo version' ' + test_should_contain "User-Agent: $(ipfs id -f "")" http_requests +' + ## HTTP PUTs test_expect_success 'add new CID to the local datastore' ' @@ -50,6 +54,7 @@ test_expect_success 'expect no HTTP requests to be sent with locally added CID' test_expect_success "stop nc" ' kill "$NCPID" && wait "$NCPID" || true + rm -f http_requests || true ' test_kill_ipfs_daemon From 73ebad1892611a4b45b35798fe2d36cba2ec3bf6 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Tue, 17 Jan 2023 19:18:39 +0100 Subject: [PATCH 0390/1212] fix: refuse to start if connmgr is smaller than ressource limits and not using none connmgr Fixes: #9548 --- core/node/libp2p/rcmgr.go | 42 ++++++++++++++++++++++++++++++ test/sharness/t0139-swarm-rcmgr.sh | 28 ++++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/core/node/libp2p/rcmgr.go b/core/node/libp2p/rcmgr.go index 5d23a874d..321ffbf19 100644 --- a/core/node/libp2p/rcmgr.go +++ b/core/node/libp2p/rcmgr.go @@ -67,6 +67,10 @@ func ResourceManager(cfg config.SwarmConfig) interface{} { limitConfig = l } + if err := ensureConnMgrMakeSenseVsRessourcesMgr(limitConfig, cfg.ConnMgr); err != nil { + return nil, opts, err + } + limiter := rcmgr.NewFixedLimiter(limitConfig) str, err := rcmgrObs.NewStatsTraceReporter() @@ -598,3 +602,41 @@ func NetResetLimit(mgr network.ResourceManager, repo repo.Repo, scope string) (r return result, nil } + +func ensureConnMgrMakeSenseVsRessourcesMgr(rcm rcmgr.LimitConfig, cmgr config.ConnMgr) error { + if cmgr.Type.WithDefault(config.DefaultConnMgrType) == "none" { + return nil // none connmgr, no checks to do + } + highWater := cmgr.HighWater.WithDefault(config.DefaultConnMgrHighWater) + if rcm.System.ConnsInbound <= rcm.System.Conns { + if int64(rcm.System.ConnsInbound) <= highWater { + // nolint + return fmt.Errorf(` +Unable to initialize libp2p due to conflicting limit configuration: +ResourceMgr.Limits.System.ConnsInbound (%d) must be bigger than ConnMgr.HighWater (%d) +`, rcm.System.ConnsInbound, highWater) + } + } else if int64(rcm.System.Conns) <= highWater { + // nolint + return fmt.Errorf(` +Unable to initialize libp2p due to conflicting limit configuration: +ResourceMgr.Limits.System.Conns (%d) must be bigger than ConnMgr.HighWater (%d) +`, rcm.System.Conns, highWater) + } + if rcm.System.StreamsInbound <= rcm.System.Streams { + if int64(rcm.System.StreamsInbound) <= highWater { + // nolint + return fmt.Errorf(` +Unable to initialize libp2p due to conflicting limit configuration: +ResourceMgr.Limits.System.StreamsInbound (%d) must be bigger than ConnMgr.HighWater (%d) +`, rcm.System.StreamsInbound, highWater) + } + } else if int64(rcm.System.Streams) <= highWater { + // nolint + return fmt.Errorf(` +Unable to initialize libp2p due to conflicting limit configuration: +ResourceMgr.Limits.System.Streams (%d) must be bigger than ConnMgr.HighWater (%d) +`, rcm.System.Streams, highWater) + } + return nil +} diff --git a/test/sharness/t0139-swarm-rcmgr.sh b/test/sharness/t0139-swarm-rcmgr.sh index c36ddd3d8..69c5e4600 100755 --- a/test/sharness/t0139-swarm-rcmgr.sh +++ b/test/sharness/t0139-swarm-rcmgr.sh @@ -227,4 +227,32 @@ test_expect_success 'stop iptb' ' iptb stop 2 ' +## Test daemon refuse to start if connmgr.highwater < ressources inbound + +test_expect_success "node refuse to start if Swarm.ResourceMgr.Limits.System.Conns <= Swarm.ConnMgr.HighWater" ' + ipfs config --json Swarm.ResourceMgr.Limits.System.Conns 128 && + ipfs config --json Swarm.ConnMgr.HighWater 128 && + ipfs config --json Swarm.ConnMgr.LowWater 64 && + test_expect_code 1 ipfs daemon && + ipfs config --json Swarm.ResourceMgr.Limits.System.Conns 256 +' + +test_expect_success "node refuse to start if Swarm.ResourceMgr.Limits.System.ConnsInbound <= Swarm.ConnMgr.HighWater" ' + ipfs config --json Swarm.ResourceMgr.Limits.System.ConnsInbound 128 && + test_expect_code 1 ipfs daemon && + ipfs config --json Swarm.ResourceMgr.Limits.System.ConnsInbound 256 +' + +test_expect_success "node refuse to start if Swarm.ResourceMgr.Limits.System.Streams <= Swarm.ConnMgr.HighWater" ' + ipfs config --json Swarm.ResourceMgr.Limits.System.Streams 128 && + test_expect_code 1 ipfs daemon && + ipfs config --json Swarm.ResourceMgr.Limits.System.Streams 256 +' + +test_expect_success "node refuse to start if Swarm.ResourceMgr.Limits.System.StreamsInbound <= Swarm.ConnMgr.HighWater" ' + ipfs config --json Swarm.ResourceMgr.Limits.System.StreamsInbound 128 && + test_expect_code 1 ipfs daemon && + ipfs config --json Swarm.ResourceMgr.Limits.System.StreamsInbound 256 +' + test_done From c69632d75bd7026df2668200c6fffd7345d34fa0 Mon Sep 17 00:00:00 2001 From: galargh Date: Thu, 19 Jan 2023 16:54:21 +0100 Subject: [PATCH 0391/1212] fix: update saxon download path --- test/sharness/lib/download-saxon.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/sharness/lib/download-saxon.sh b/test/sharness/lib/download-saxon.sh index 195630804..cc645238f 100755 --- a/test/sharness/lib/download-saxon.sh +++ b/test/sharness/lib/download-saxon.sh @@ -1,7 +1,7 @@ #!/bin/bash dependencies=( - "url=https://sourceforge.net/projects/saxon/files/Saxon-HE/11/Java/SaxonHE11-4J.zip;md5=8a4783d307c32c898f8995b8f337fd6b" + "url=https://raw.githubusercontent.com/pl-strflt/Saxon-HE/3e039cdbccf4efb9643736f34c839a3bae3402ae/11/Java/SaxonHE11-4J.zip;md5=8a4783d307c32c898f8995b8f337fd6b" "url=https://raw.githubusercontent.com/pl-strflt/ant/c781f7d79b92cc55530245d9554682a47f46851e/src/etc/junit-frames-saxon.xsl;md5=6eb013566903a91e4959413f6ff144d0" "url=https://raw.githubusercontent.com/pl-strflt/ant/c781f7d79b92cc55530245d9554682a47f46851e/src/etc/junit-noframes-saxon.xsl;md5=8d54882d5f9d32a7743ec675cc2e30ac" ) From 92c76cc91e84113e03d14ad49f0cfc972c61aae9 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Fri, 20 Jan 2023 11:24:45 +0100 Subject: [PATCH 0392/1212] docs: clarify browser descriptions for webtransport --- docs/changelogs/v0.18.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/changelogs/v0.18.md b/docs/changelogs/v0.18.md index e99cd5c94..cca07ecfb 100644 --- a/docs/changelogs/v0.18.md +++ b/docs/changelogs/v0.18.md @@ -130,7 +130,7 @@ since Kubo 0.13, but in this release it will also include the size column. ##### WebTransport enabled by default [WebTransport](https://docs.libp2p.io/concepts/transports/webtransport/) is a new libp2p transport that [was introduced in v0.16](https://github.com/ipfs/kubo/blob/master/docs/changelogs/v0.16.md#-webtransport-new-experimental-transport) that is based on top of QUIC and HTTP3. -This allows browsers to contact Kubo nodes, so now instead of just serving requests for other system level applicative nodes, you can also serve requests directly to a browser. +This allows browser-based nodes to contact Kubo nodes, so now instead of just serving requests for other system-level application nodes, you can also serve requests directly to a node running inside a browser page. For the full story see [connectivity.libp2p.io](https://connectivity.libp2p.io/). From b84cd115662d968d6fc51a46eb4319d97cee9979 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Fri, 20 Jan 2023 15:29:54 +0100 Subject: [PATCH 0393/1212] fix: typo in ensureConnMgrMakeSenseVsResourcesMgr --- core/node/libp2p/rcmgr.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/node/libp2p/rcmgr.go b/core/node/libp2p/rcmgr.go index 321ffbf19..fe7fc635e 100644 --- a/core/node/libp2p/rcmgr.go +++ b/core/node/libp2p/rcmgr.go @@ -67,7 +67,7 @@ func ResourceManager(cfg config.SwarmConfig) interface{} { limitConfig = l } - if err := ensureConnMgrMakeSenseVsRessourcesMgr(limitConfig, cfg.ConnMgr); err != nil { + if err := ensureConnMgrMakeSenseVsResourceMgr(limitConfig, cfg.ConnMgr); err != nil { return nil, opts, err } @@ -603,7 +603,7 @@ func NetResetLimit(mgr network.ResourceManager, repo repo.Repo, scope string) (r return result, nil } -func ensureConnMgrMakeSenseVsRessourcesMgr(rcm rcmgr.LimitConfig, cmgr config.ConnMgr) error { +func ensureConnMgrMakeSenseVsResourceMgr(rcm rcmgr.LimitConfig, cmgr config.ConnMgr) error { if cmgr.Type.WithDefault(config.DefaultConnMgrType) == "none" { return nil // none connmgr, no checks to do } From 8328bab28d489b145963f05b7bc3defccf22366b Mon Sep 17 00:00:00 2001 From: Jorropo Date: Mon, 16 Jan 2023 12:02:40 +0100 Subject: [PATCH 0394/1212] fix: ensure connmgr is smaller then autoscalled ressource limits Fixes #9545 --- config/init.go | 4 ++++ core/node/libp2p/rcmgr_defaults.go | 19 +++++++++++++++++ docs/libp2p-resource-management.md | 34 ++++++++++++++++++------------ test/sharness/t0139-swarm-rcmgr.sh | 28 +++++++++++++++++++++++- 4 files changed, 71 insertions(+), 14 deletions(-) diff --git a/config/init.go b/config/init.go index e91b24871..621ff95f3 100644 --- a/config/init.go +++ b/config/init.go @@ -110,6 +110,10 @@ const DefaultConnMgrGracePeriod = time.Second * 20 // type. const DefaultConnMgrType = "basic" +// DefaultResourceMgrMinInboundConns is a MAGIC number that probably a good +// enough number of inbound conns to be a good network citizen. +const DefaultResourceMgrMinInboundConns = 800 + func addressesConfig() Addresses { return Addresses{ Swarm: []string{ diff --git a/core/node/libp2p/rcmgr_defaults.go b/core/node/libp2p/rcmgr_defaults.go index d3c294258..4d578a9b6 100644 --- a/core/node/libp2p/rcmgr_defaults.go +++ b/core/node/libp2p/rcmgr_defaults.go @@ -186,5 +186,24 @@ Run 'ipfs swarm limit all' to see the resulting limits. defaultLimitConfig := scalingLimitConfig.Scale(int64(maxMemory), int(numFD)) + // Simple checks to overide autoscaling ensuring limits make sense versus the connmgr values. + // There are ways to break this, but this should catch most problems already. + // We might improve this in the future. + // See: https://github.com/ipfs/kubo/issues/9545 + if cfg.ConnMgr.Type.WithDefault(config.DefaultConnMgrType) != "none" { + maxInboundConns := int64(defaultLimitConfig.System.ConnsInbound) + if connmgrHighWaterTimesTwo := cfg.ConnMgr.HighWater.WithDefault(config.DefaultConnMgrHighWater) * 2; maxInboundConns < connmgrHighWaterTimesTwo { + maxInboundConns = connmgrHighWaterTimesTwo + } + + if maxInboundConns < config.DefaultResourceMgrMinInboundConns { + maxInboundConns = config.DefaultResourceMgrMinInboundConns + } + + // Scale System.StreamsInbound as well, but use the existing ratio of StreamsInbound to ConnsInbound + defaultLimitConfig.System.StreamsInbound = int(maxInboundConns * int64(defaultLimitConfig.System.StreamsInbound) / int64(defaultLimitConfig.System.ConnsInbound)) + defaultLimitConfig.System.ConnsInbound = int(maxInboundConns) + } + return defaultLimitConfig, nil } diff --git a/docs/libp2p-resource-management.md b/docs/libp2p-resource-management.md index 83c44251d..d6b782da1 100644 --- a/docs/libp2p-resource-management.md +++ b/docs/libp2p-resource-management.md @@ -40,19 +40,19 @@ libp2p's resource manager provides tremendous flexibility but also adds complexi 1. "The user who does nothing" - In this case Kubo attempts to give some sane defaults discussed below based on the amount of memory and file descriptors their system has. This should protect the node from many attacks. - + 1. "Slightly more advanced user" - They can tweak the default limits discussed below. Where the defaults aren't good enough, a good set of higher-level "knobs" are exposed to satisfy most use cases without requiring users to wade into all the intricacies of libp2p's resource manager. - The "knobs"/inputs are `Swarm.ResourceMgr.MaxMemory` and `Swarm.ResourceMgr.MaxFileDescriptors` as described below. + The "knobs"/inputs are `Swarm.ResourceMgr.MaxMemory` and `Swarm.ResourceMgr.MaxFileDescriptors` as described below. 1. "Power user" - They specify overrides to computed default limits via `ipfs swarm limit` and `Swarm.ResourceMgr.Limits`; ### Computed Default Limits With the `Swarm.ResourceMgr.MaxMemory` and `Swarm.ResourceMgr.MaxFileDescriptors` inputs defined, -[resource manager limits](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#limits) are created at the -[system](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#the-system-scope), -[transient](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#the-transient-scope), +[resource manager limits](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#limits) are created at the +[system](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#the-system-scope), +[transient](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#the-transient-scope), and [peer](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#peer-scopes) scopes. Other scopes are ignored (by being set to "[~infinity](#infinite-limits])". @@ -68,11 +68,15 @@ The reason these scopes are chosen is because: (e.g., bug in a peer which is causing it to "misbehave"). In the unintional case, we want to make sure a "misbehaving" node doesn't consume more resources than necessary. -Within these scopes, limits are just set on -[memory](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#memory), +Within these scopes, limits are just set on +[memory](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#memory), [file descriptors (FD)](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#file-descriptors), [*inbound* connections](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#connections), and [*inbound* streams](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#streams). Limits are set based on the `Swarm.ResourceMgr.MaxMemory` and `Swarm.ResourceMgr.MaxFileDescriptors` inputs above. + +There are also some special cases where minimum values are enforced. +For example, Kubo maintainers have found in practice that it's a footgun to have too low of a value for `Swarm.ResourceMgr.Limits.System.ConnsInbound` and a default minimum is used. (See [core/node/libp2p/rcmgr_defaults.go](https://github.com/ipfs/kubo/blob/master/core/node/libp2p/rcmgr_defaults.go) for specifics.) + We trust this node to behave properly and thus don't limit *outbound* connection/stream limits. We apply any limits that libp2p has for its protocols/services since we assume libp2p knows best here. @@ -139,13 +143,17 @@ There is a go-libp2p issue ([#1928](https://github.com/libp2p/go-libp2p/issues/1 ### How does the resource manager (ResourceMgr) relate to the connection manager (ConnMgr)? As discussed [here](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#connmanager-vs-resource-manager) these are separate systems in go-libp2p. -Kubo also configures the ConnMgr separately from ResourceMgr. There is no checking to make sure the limits between the systems are congruent. +Kubo performs sanity checks to ensure that some of the hard limits of the ResourceMgr are sufficiently greater than the soft limits of the ConnMgr. -Ideally `Swarm.ConnMgr.HighWater` is less than `Swarm.ResourceMgr.Limits.System.ConnsInbound`. -This is so the ConnMgr can kick in and cleanup connections based on connection priorities before the hard limits of the ResourceMgr are applied. +The soft limit of `Swarm.ConnMgr.HighWater` needs to be less than the hard limit `Swarm.ResourceMgr.Limits.System.ConnsInbound` for the configuration to make sense. +This ensures the ConnMgr cleans up connections based on connection priorities before the hard limits of the ResourceMgr are applied. If `Swarm.ConnMgr.HighWater` is greater than `Swarm.ResourceMgr.Limits.System.ConnsInbound`, existing low priority idle connections can prevent new high priority connections from being established. -The ResourceMgr doesn't know that the new connection is high priority and simply blocks it because of the limit its enforcing. +The ResourceMgr doesn't know that the new connection is high priority and simply blocks it because of the limit its enforcing. + +To ensure the ConnMgr and ResourceMgr are congruent, the ResourceMgr [computed default limts](#computed-default-limits) are adjusted such that: +1. `Swarm.ResourceMgr.Limits.System.ConnsInbound` >= `max(Swarm.ConnMgr.HighWater * 2, 800)` AND +2. `Swarm.ResourceMgr.Limits.System.StreamsInbound` is greater than any new/adjusted `Swarm.ResourceMgr.Limits.System.ConnsInbound` value so that there's enough streams per connection. ### How does one see the Active Limits? A dump of what limits are actually being used by the resource manager ([Computed Default Limits](#computed-default-limits) + [User Supplied Override Limits](#user-supplied-override-limits)) @@ -156,9 +164,9 @@ This can be observed with an empty [`Swarm.ResourceMgr.Limits`](https://github.c and then [seeing the active limits](#how-does-one-see-the-active-limits). ### How does one monitor libp2p resource usage? -For [monitoring libp2p resource usage](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#monitoring), +For [monitoring libp2p resource usage](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#monitoring), various `*rcmgr_*` metrics can be accessed as the prometheus endpoint at `{Addresses.API}/debug/metrics/prometheus` (default: `http://127.0.0.1:5001/debug/metrics/prometheus`). -There are also [pre-built Grafana dashboards](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager/obs/grafana-dashboards) that can be added to a Grafana instance. +There are also [pre-built Grafana dashboards](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager/obs/grafana-dashboards) that can be added to a Grafana instance. A textual view of current resource usage and a list of services, protocols, and peers can be obtained via `ipfs swarm stats --help` diff --git a/test/sharness/t0139-swarm-rcmgr.sh b/test/sharness/t0139-swarm-rcmgr.sh index 69c5e4600..1b870abb7 100755 --- a/test/sharness/t0139-swarm-rcmgr.sh +++ b/test/sharness/t0139-swarm-rcmgr.sh @@ -40,9 +40,35 @@ test_expect_success 'disconnected: swarm stats requires running daemon' ' test_should_contain "missing ResourceMgr" actual ' +# test sanity scaling +test_expect_success 'set very high connmgr highwater' ' + ipfs config --json Swarm.ConnMgr.HighWater 1000 +' + +test_launch_ipfs_daemon + +test_expect_success 'conns and streams are above 2000' ' + ipfs swarm limit system --enc=json | tee json && + [ "$(jq -r .ConnsInbound < json)" -ge 2000 ] && + [ "$(jq -r .StreamsInbound < json)" -ge 2000 ] +' + +test_kill_ipfs_daemon + +test_expect_success 'set previous connmgr highwater' ' + ipfs config --json Swarm.ConnMgr.HighWater 96 +' + +test_launch_ipfs_daemon + +test_expect_success 'conns and streams are above 800' ' + ipfs swarm limit system --enc=json | tee json && + [ "$(jq -r .ConnsInbound < json)" -ge 800 ] && + [ "$(jq -r .StreamsInbound < json)" -ge 800 ] +' + # swarm limit|stats should succeed in online mode by default # because Resource Manager is opt-out -test_launch_ipfs_daemon # every scope has the same fields, so we only inspect System test_expect_success 'ResourceMgr enabled: swarm limit' ' From ad9b4865111aff204877a5561da18f749b90ce73 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Fri, 20 Jan 2023 22:40:49 +0100 Subject: [PATCH 0395/1212] fix(ci): work around bifrost-infra/issues/2300 https://github.com/protocol/bifrost-infra/issues/2300#issuecomment-1398946009 --- .circleci/main.yml | 4 ++++ .github/workflows/build.yml | 2 ++ 2 files changed, 6 insertions(+) diff --git a/.circleci/main.yml b/.circleci/main.yml index 6406c6655..9bf48ebea 100644 --- a/.circleci/main.yml +++ b/.circleci/main.yml @@ -228,6 +228,8 @@ jobs: - image: cimg/go:1.19.1-node parallelism: 4 resource_class: 2xlarge+ + environment: + GO_IPFS_DIST_URL: https://dist-ipfs-tech.ipns.cf-ipfs.com # TODO remove this line when https://github.com/protocol/bifrost-infra/issues/2300 is closed steps: - *make_out_dirs - attach_workspace: @@ -328,6 +330,8 @@ jobs: ipfs-webui: executor: node-browsers resource_class: 2xlarge+ + environment: + GO_IPFS_DIST_URL: https://dist-ipfs-tech.ipns.cf-ipfs.com # TODO remove this line when https://github.com/protocol/bifrost-infra/issues/2300 is closed steps: - *make_out_dirs - attach_workspace: diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d0b4194b7..997067ad8 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -78,6 +78,7 @@ jobs: LIBP2P_TCP_REUSEPORT: false LIBP2P_ALLOW_WEAK_RSA_KEYS: 1 IPFS_GO_EXEC: ${{ github.workspace }}/cmd/ipfs/ipfs + GO_IPFS_DIST_URL: https://dist-ipfs-tech.ipns.cf-ipfs.com # TODO: remove this line when https://github.com/protocol/bifrost-infra/issues/2300 is closed working-directory: interop go-ipfs-api: needs: [prepare] @@ -161,6 +162,7 @@ jobs: TRAVIS: 1 GIT_PAGER: cat IPFS_CHECK_RCMGR_DEFAULTS: 1 + GO_IPFS_DIST_URL: https://dist-ipfs-tech.ipns.cf-ipfs.com # TODO: remove this line when https://github.com/protocol/bifrost-infra/issues/2300 is closed defaults: run: shell: bash From c706c638fc33f2ad28110858f6e25de32a7eac7f Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Sat, 21 Jan 2023 04:21:18 +0100 Subject: [PATCH 0396/1212] fix(gateway): undesired conversions to dag-json and friends (#9566) * fix(gateway): do not convert unixfs/raw into dag-* unless explicit * fix(gateway): keep only dag-json|dag-cbor handling * fix: allow requesting dag-json as application/json - adds bunch of additional tests including JSON file on UnixFS - fix: dag-json codec (0x0129) can be returned as plain json - fix: json codec (0x0200) cna be retrurned as plain json * fix: using ?format|Accept with CID w/ codec works * docs(changelog): cbor and json on gateway Co-authored-by: Marcin Rataj --- core/corehttp/gateway_handler.go | 21 +- core/corehttp/gateway_handler_codec.go | 83 ++++---- docs/changelogs/v0.18.md | 79 ++++++- test/sharness/t0123-gateway-json-cbor.sh | 250 +++++++++++------------ 4 files changed, 242 insertions(+), 191 deletions(-) diff --git a/core/corehttp/gateway_handler.go b/core/corehttp/gateway_handler.go index c20f112d7..1c6797e68 100644 --- a/core/corehttp/gateway_handler.go +++ b/core/corehttp/gateway_handler.go @@ -418,9 +418,9 @@ func (i *gatewayHandler) getOrHeadHandler(w http.ResponseWriter, r *http.Request // Support custom response formats passed via ?format or Accept HTTP header switch responseFormat { - case "": - switch resolvedPath.Cid().Prefix().Codec { - case uint64(mc.Json), uint64(mc.DagJson), uint64(mc.Cbor), uint64(mc.DagCbor): + case "", "application/json", "application/cbor": + switch mc.Code(resolvedPath.Cid().Prefix().Codec) { + case mc.Json, mc.DagJson, mc.Cbor, mc.DagCbor: logger.Debugw("serving codec", "path", contentPath) i.serveCodec(r.Context(), w, r, resolvedPath, contentPath, begin, responseFormat) default: @@ -441,14 +441,13 @@ func (i *gatewayHandler) getOrHeadHandler(w http.ResponseWriter, r *http.Request logger.Debugw("serving tar file", "path", contentPath) i.serveTAR(r.Context(), w, r, resolvedPath, contentPath, begin, logger) return - case "application/json", "application/vnd.ipld.dag-json", - "application/cbor", "application/vnd.ipld.dag-cbor": + case "application/vnd.ipld.dag-json", "application/vnd.ipld.dag-cbor": logger.Debugw("serving codec", "path", contentPath) i.serveCodec(r.Context(), w, r, resolvedPath, contentPath, begin, responseFormat) return default: // catch-all for unsuported application/vnd.* err := fmt.Errorf("unsupported format %q", responseFormat) - webError(w, "failed respond with requested content type", err, http.StatusBadRequest) + webError(w, "failed to respond with requested content type", err, http.StatusBadRequest) return } } @@ -878,14 +877,14 @@ func customResponseFormat(r *http.Request) (mediaType string, params map[string] return "application/vnd.ipld.car", nil, nil case "tar": return "application/x-tar", nil, nil - case "dag-json": - return "application/vnd.ipld.dag-json", nil, nil case "json": return "application/json", nil, nil - case "dag-cbor": - return "application/vnd.ipld.dag-cbor", nil, nil case "cbor": return "application/cbor", nil, nil + case "dag-json": + return "application/vnd.ipld.dag-json", nil, nil + case "dag-cbor": + return "application/vnd.ipld.dag-cbor", nil, nil } } // Browsers and other user agents will send Accept header with generic types like: @@ -908,6 +907,8 @@ func customResponseFormat(r *http.Request) (mediaType string, params map[string] } } } + // If none of special-cased content types is found, return empty string + // to indicate default, implicit UnixFS response should be prepared return "", nil, nil } diff --git a/core/corehttp/gateway_handler_codec.go b/core/corehttp/gateway_handler_codec.go index 95a151c79..93e9593b7 100644 --- a/core/corehttp/gateway_handler_codec.go +++ b/core/corehttp/gateway_handler_codec.go @@ -25,22 +25,25 @@ import ( // codecToContentType maps the supported IPLD codecs to the HTTP Content // Type they should have. -var codecToContentType = map[uint64]string{ - uint64(mc.Json): "application/json", - uint64(mc.Cbor): "application/cbor", - uint64(mc.DagJson): "application/vnd.ipld.dag-json", - uint64(mc.DagCbor): "application/vnd.ipld.dag-cbor", +var codecToContentType = map[mc.Code]string{ + mc.Json: "application/json", + mc.Cbor: "application/cbor", + mc.DagJson: "application/vnd.ipld.dag-json", + mc.DagCbor: "application/vnd.ipld.dag-cbor", } -// contentTypeToCodecs maps the HTTP Content Type to the respective -// possible codecs. If the original data is in one of those codecs, -// we stream the raw bytes. Otherwise, we encode in the last codec -// of the list. -var contentTypeToCodecs = map[string][]uint64{ - "application/json": {uint64(mc.Json), uint64(mc.DagJson)}, - "application/vnd.ipld.dag-json": {uint64(mc.DagJson)}, - "application/cbor": {uint64(mc.Cbor), uint64(mc.DagCbor)}, - "application/vnd.ipld.dag-cbor": {uint64(mc.DagCbor)}, +// contentTypeToRaw maps the HTTP Content Type to the respective codec that +// allows raw response without any conversion. +var contentTypeToRaw = map[string][]mc.Code{ + "application/json": {mc.Json, mc.DagJson}, + "application/cbor": {mc.Cbor, mc.DagCbor}, +} + +// contentTypeToCodec maps the HTTP Content Type to the respective codec. We +// only add here the codecs that we want to convert-to-from. +var contentTypeToCodec = map[string]mc.Code{ + "application/vnd.ipld.dag-json": mc.DagJson, + "application/vnd.ipld.dag-cbor": mc.DagCbor, } // contentTypeToExtension maps the HTTP Content Type to the respective file @@ -56,7 +59,7 @@ func (i *gatewayHandler) serveCodec(ctx context.Context, w http.ResponseWriter, ctx, span := tracing.Span(ctx, "Gateway", "ServeCodec", trace.WithAttributes(attribute.String("path", resolvedPath.String()), attribute.String("requestedContentType", requestedContentType))) defer span.End() - cidCodec := resolvedPath.Cid().Prefix().Codec + cidCodec := mc.Code(resolvedPath.Cid().Prefix().Codec) responseContentType := requestedContentType // If the resolved path still has some remainder, return error for now. @@ -90,22 +93,36 @@ func (i *gatewayHandler) serveCodec(ctx context.Context, w http.ResponseWriter, // No content type is specified by the user (via Accept, or format=). However, // we support this format. Let's handle it. if requestedContentType == "" { - isDAG := cidCodec == uint64(mc.DagJson) || cidCodec == uint64(mc.DagCbor) + isDAG := cidCodec == mc.DagJson || cidCodec == mc.DagCbor acceptsHTML := strings.Contains(r.Header.Get("Accept"), "text/html") download := r.URL.Query().Get("download") == "true" if isDAG && acceptsHTML && !download { i.serveCodecHTML(ctx, w, r, resolvedPath, contentPath) } else { + // This covers CIDs with codec 'json' and 'cbor' as those do not have + // an explicit requested content type. i.serveCodecRaw(ctx, w, r, resolvedPath, contentPath, name, modtime) } return } - // Otherwise, the user has requested a specific content type. Let's first get - // the codecs that can be used with this content type. - codecs, ok := contentTypeToCodecs[requestedContentType] + // If DAG-JSON or DAG-CBOR was requested using corresponding plain content type + // return raw block as-is, without conversion + skipCodecs, ok := contentTypeToRaw[requestedContentType] + if ok { + for _, skipCodec := range skipCodecs { + if skipCodec == cidCodec { + i.serveCodecRaw(ctx, w, r, resolvedPath, contentPath, name, modtime) + return + } + } + } + + // Otherwise, the user has requested a specific content type (a DAG-* variant). + // Let's first get the codecs that can be used with this content type. + toCodec, ok := contentTypeToCodec[requestedContentType] if !ok { // This is never supposed to happen unless function is called with wrong parameters. err := fmt.Errorf("unsupported content type: %s", requestedContentType) @@ -113,27 +130,7 @@ func (i *gatewayHandler) serveCodec(ctx context.Context, w http.ResponseWriter, return } - // If we need to convert, use the last codec (strict dag- variant) - toCodec := codecs[len(codecs)-1] - - // If the requested content type has "dag-", ALWAYS go through the encoding - // process in order to validate the content. - if strings.Contains(requestedContentType, "dag-") { - i.serveCodecConverted(ctx, w, r, resolvedPath, contentPath, toCodec, modtime) - return - } - - // Otherwise, check if the data is encoded with the requested content type. - // If so, we can directly stream the raw data. serveRawBlock cannot be directly - // used here as it sets different headers. - for _, codec := range codecs { - if resolvedPath.Cid().Prefix().Codec == codec { - i.serveCodecRaw(ctx, w, r, resolvedPath, contentPath, name, modtime) - return - } - } - - // Finally, if nothing of the above is true, we have to actually convert the codec. + // This handles DAG-* conversions and validations. i.serveCodecConverted(ctx, w, r, resolvedPath, contentPath, toCodec, modtime) } @@ -165,6 +162,7 @@ func (i *gatewayHandler) serveCodecHTML(ctx context.Context, w http.ResponseWrit } } +// serveCodecRaw returns the raw block without any conversion func (i *gatewayHandler) serveCodecRaw(ctx context.Context, w http.ResponseWriter, r *http.Request, resolvedPath ipath.Resolved, contentPath ipath.Path, name string, modtime time.Time) { blockCid := resolvedPath.Cid() blockReader, err := i.api.Block().Get(ctx, resolvedPath) @@ -184,7 +182,8 @@ func (i *gatewayHandler) serveCodecRaw(ctx context.Context, w http.ResponseWrite _, _, _ = ServeContent(w, r, name, modtime, content) } -func (i *gatewayHandler) serveCodecConverted(ctx context.Context, w http.ResponseWriter, r *http.Request, resolvedPath ipath.Resolved, contentPath ipath.Path, toCodec uint64, modtime time.Time) { +// serveCodecConverted returns payload converted to codec specified in toCodec +func (i *gatewayHandler) serveCodecConverted(ctx context.Context, w http.ResponseWriter, r *http.Request, resolvedPath ipath.Resolved, contentPath ipath.Path, toCodec mc.Code, modtime time.Time) { obj, err := i.api.Dag().Get(ctx, resolvedPath.Cid()) if err != nil { webError(w, "ipfs dag get "+html.EscapeString(resolvedPath.String()), err, http.StatusInternalServerError) @@ -199,7 +198,7 @@ func (i *gatewayHandler) serveCodecConverted(ctx context.Context, w http.Respons } finalNode := universal.(ipld.Node) - encoder, err := multicodec.LookupEncoder(toCodec) + encoder, err := multicodec.LookupEncoder(uint64(toCodec)) if err != nil { webError(w, err.Error(), err, http.StatusInternalServerError) return diff --git a/docs/changelogs/v0.18.md b/docs/changelogs/v0.18.md index cca07ecfb..d10f56d77 100644 --- a/docs/changelogs/v0.18.md +++ b/docs/changelogs/v0.18.md @@ -64,19 +64,74 @@ Learn more in the [`Reprovider` config](https://github.com/ipfs/go-ipfs/blob/mas ##### (DAG-)JSON and (DAG-)CBOR response formats -Implemented [IPIP-328](https://github.com/ipfs/specs/pull/328) which adds support -for DAG-JSON and DAG-CBOR, as well as their non-DAG variants, to the gateway. Now, -CIDs that encode JSON, CBOR, DAG-JSON and DAG-CBOR objects can be retrieved, and -traversed thanks to the [special meaning of CBOR Tag 42](https://github.com/ipld/cid-cbor/). +The IPFS project has reserved the corresponding media types at IANA: +- [`application/vnd.ipld.dag-json`](https://www.iana.org/assignments/media-types/application/vnd.ipld.dag-json) +- [`application/vnd.ipld.dag-cbor`](https://www.iana.org/assignments/media-types/application/vnd.ipld.dag-cbor) -HTTP clients can request JSON, CBOR, DAG-JSON, and DAG-CBOR responses by either -passing the query parameter `?format` or setting the `Accept` HTTP header to the -following values: +This release implements them as part of [IPIP-328](https://github.com/ipfs/specs/pull/328) +and adds Gateway support for CIDs with `json` (0x0200), `cbor` (0x51), +[`dag-json`](https://ipld.io/specs/codecs/dag-json/) (0x0129) +and [`dag-cbor`](https://ipld.io/specs/codecs/dag-cbor/spec/) (0x71) codecs. -- JSON: `?format=json`, or `Accept: application/json` -- CBOR: `?format=cbor`, or `Accept: application/cbor` -- DAG-JSON: `?format=dag-json`, or `Accept: application/vnd.ipld.dag-json` -- DAG-JSON: `?format=dag-cbor`, or `Accept: application/vnd.ipld.dag-cbor` +To specify the response `Content-Type` explicitly, the HTTP client can override +the codec present in the CID by using the `format` parameter +or setting the `Accept` HTTP header: + +- Plain JSON: `?format=json` or `Accept: application/json` +- Plain CBOR: `?format=cbor` or `Accept: application/cbor` +- DAG-JSON: `?format=dag-json` or `Accept: application/vnd.ipld.dag-json` +- DAG-CBOR: `?format=dag-cbor` or `Accept: application/vnd.ipld.dag-cbor` + +In addition, when DAG-JSON or DAG-CBOR is requested with the `Accept` header +set to `text/html`, the Gateway will return a basic HTML page with download +options, improving the user experience in web browsers. + +###### Example 1: DAG-CBOR and DAG-JSON Conversion on Gateway + +The Gateway supports conversion between DAG-CBOR and DAG-JSON for efficient +end-to-end data structure management: author in CBOR or JSON, store as binary +CBOR and retrieve as JSON via HTTP: + +```console +$ echo '{"test": "json"}' | ipfs dag put # implicit --input-codec dag-json --store-codec dag-cbor +bafyreico7mjtqtqhvawro3yud5uqn6sc33nzqb7b5j2d7pdmzer5nab4t4 + +$ ipfs block get bafyreico7mjtqtqhvawro3yud5uqn6sc33nzqb7b5j2d7pdmzer5nab4t4 | xxd +00000000: a164 7465 7374 646a 736f 6e .dtestdjson + +$ ipfs dag get bafyreico7mjtqtqhvawro3yud5uqn6sc33nzqb7b5j2d7pdmzer5nab4t4 # implicit --output-codec dag-json +{"test":"json"} + +$ curl "http://127.0.0.1:8080/ipfs/bafyreico7mjtqtqhvawro3yud5uqn6sc33nzqb7b5j2d7pdmzer5nab4t4?format=dag-json" +{"test":"json"} +``` + +###### Example 2: Traversing CBOR DAGs + +Placing a CID in [CBOR Tag 42](https://github.com/ipld/cid-cbor/) enables the +creation of arbitrary DAGs. The equivalent DAG-JSON notation for linking +to different blocks is represented by `{ "/": "cid" }`. + +The Gateway supports traversing these links, enabling access to data +referenced by structures other than regular UnixFS directories: + +```console +$ echo '{"test.jpg": {"/": "bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi"}}' | ipfs dag put +bafyreihspwy3zlkzgphmec5d3xb5g5njrqwotd46lyubnelbzktnmsxkq4 # dag-cbor document linking to unixfs file + +$ ipfs resolve /ipfs/bafyreihspwy3zlkzgphmec5d3xb5g5njrqwotd46lyubnelbzktnmsxkq4/test.jpg +/ipfs/bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi + +$ ipfs dag stat bafyreihspwy3zlkzgphmec5d3xb5g5njrqwotd46lyubnelbzktnmsxkq4 +Size: 119827, NumBlocks: 2 + +$ curl "http://127.0.0.1:8080/ipfs/bafyreihspwy3zlkzgphmec5d3xb5g5njrqwotd46lyubnelbzktnmsxkq4/test.jpg" > test.jpg +``` + +###### Example 3: UnixFS directory listing as JSON + +Finally, Gateway now supports the same [logical format projection](https://ipld.io/specs/codecs/dag-pb/spec/#logical-format) from +DAG-PB to DAG-JSON as the `ipfs dag get` command, enabling the retrieval of directory listings as JSON instead of HTML: ```console $ export DIR_CID=bafybeigccimv3zqm5g4jt363faybagywkvqbrismoquogimy7kvz2sj7sq @@ -112,6 +167,8 @@ $ curl "http://127.0.0.1:8080/ipfs/$DIR_CID?format=dag-json" | jq } ] } +$ ipfs dag get $DIR_CID +{"Data":{"/":{"bytes":"CAE"}},"Links":[{"Hash":{"/":"Qmc3zqKcwzbbvw3MQm3hXdg8BQoFjGdZiGdAfXAyAGGdLi"},"Name":"1 - Barrel - Part 1 - alt.txt","Tsize":21},{"Hash":{"/":"QmdMxMx29KVYhHnaCc1icWYxQqXwUNCae6t1wS2NqruiHd"},"Name":"1 - Barrel - Part 1 - transcript.txt","Tsize":195},{"Hash":{"/":"QmawceGscqN4o8Y8Fv26UUmB454kn2bnkXV5tEQYc4jBd6"},"Name":"1 - Barrel - Part 1.png","Tsize":24862}]} ``` ##### 🐎 Fast directory listings with DAG sizes diff --git a/test/sharness/t0123-gateway-json-cbor.sh b/test/sharness/t0123-gateway-json-cbor.sh index f4ebca19d..704d075f9 100755 --- a/test/sharness/t0123-gateway-json-cbor.sh +++ b/test/sharness/t0123-gateway-json-cbor.sh @@ -12,158 +12,150 @@ test_expect_success "Add the test directory" ' mkdir -p rootDir/ipns && mkdir -p rootDir/api && mkdir -p rootDir/ą/ę && + echo "{ \"test\": \"i am a plain json file\" }" > rootDir/ą/ę/t.json && echo "I am a txt file on path with utf8" > rootDir/ą/ę/file-źł.txt && echo "I am a txt file in confusing /api dir" > rootDir/api/file.txt && echo "I am a txt file in confusing /ipfs dir" > rootDir/ipfs/file.txt && echo "I am a txt file in confusing /ipns dir" > rootDir/ipns/file.txt && DIR_CID=$(ipfs add -Qr --cid-version 1 rootDir) && + FILE_JSON_CID=$(ipfs files stat --enc=json /ipfs/$DIR_CID/ą/ę/t.json | jq -r .Hash) && FILE_CID=$(ipfs files stat --enc=json /ipfs/$DIR_CID/ą/ę/file-źł.txt | jq -r .Hash) && FILE_SIZE=$(ipfs files stat --enc=json /ipfs/$DIR_CID/ą/ę/file-źł.txt | jq -r .Size) echo "$FILE_CID / $FILE_SIZE" ' -## Reading UnixFS (data encoded with dag-pb codec) as DAG-CBOR and DAG-JSON +## Quick regression check for JSON stored on UnixFS: +## it has nothing to do with DAG-JSON and JSON codecs, +## but a lot of JSON data is stored on UnixFS and is requested with or without various hints +## and we want to avoid surprises like https://github.com/protocol/bifrost-infra/issues/2290 +test_expect_success "GET UnixFS file with JSON bytes is returned with application/json Content-Type" ' + curl -sD headers "http://127.0.0.1:$GWAY_PORT/ipfs/$FILE_JSON_CID" > curl_output 2>&1 && + curl -sD headers_accept -H "Accept: application/json" "http://127.0.0.1:$GWAY_PORT/ipfs/$FILE_JSON_CID" > curl_output_accept 2>&1 && + ipfs cat $FILE_JSON_CID > ipfs_cat_output 2>&1 && + test_should_contain "Content-Type: application/json" headers && + test_should_contain "Content-Type: application/json" headers_accept && + test_cmp ipfs_cat_output curl_output && + test_cmp curl_output curl_output_accept +' -test_dag_pb_headers () { + +## Reading UnixFS (data encoded with dag-pb codec) as DAG-CBOR and DAG-JSON +## (returns representation defined in https://ipld.io/specs/codecs/dag-pb/spec/#logical-format) + +test_dag_pb_conversion () { name=$1 format=$2 disposition=$3 - test_expect_success "GET UnixFS as $name with format=dag-$format has expected Content-Type" ' - curl -sD - "http://127.0.0.1:$GWAY_PORT/ipfs/$FILE_CID?format=dag-$format" > curl_output 2>&1 && - test_should_contain "Content-Type: application/vnd.ipld.dag-$format" curl_output && - test_should_contain "Content-Disposition: ${disposition}\; filename=\"${FILE_CID}.${format}\"" curl_output && - test_should_not_contain "Content-Type: application/$format" curl_output + test_expect_success "GET UnixFS file as $name with format=dag-$format converts to the expected Content-Type" ' + curl -sD headers "http://127.0.0.1:$GWAY_PORT/ipfs/$FILE_CID?format=dag-$format" > curl_output 2>&1 && + ipfs dag get --output-codec dag-$format $FILE_CID > ipfs_dag_get_output 2>&1 && + test_cmp ipfs_dag_get_output curl_output && + test_should_contain "Content-Type: application/vnd.ipld.dag-$format" headers && + test_should_contain "Content-Disposition: ${disposition}\; filename=\"${FILE_CID}.${format}\"" headers && + test_should_not_contain "Content-Type: application/$format" headers ' - test_expect_success "GET UnixFS as $name with 'Accept: application/vnd.ipld.dag-$format' has expected Content-Type" ' + test_expect_success "GET UnixFS directory as $name with format=dag-$format converts to the expected Content-Type" ' + curl -sD headers "http://127.0.0.1:$GWAY_PORT/ipfs/$DIR_CID?format=dag-$format" > curl_output 2>&1 && + ipfs dag get --output-codec dag-$format $DIR_CID > ipfs_dag_get_output 2>&1 && + test_cmp ipfs_dag_get_output curl_output && + test_should_contain "Content-Type: application/vnd.ipld.dag-$format" headers && + test_should_contain "Content-Disposition: ${disposition}\; filename=\"${DIR_CID}.${format}\"" headers && + test_should_not_contain "Content-Type: application/$format" headers + ' + + test_expect_success "GET UnixFS as $name with 'Accept: application/vnd.ipld.dag-$format' converts to the expected Content-Type" ' curl -sD - -H "Accept: application/vnd.ipld.dag-$format" "http://127.0.0.1:$GWAY_PORT/ipfs/$FILE_CID" > curl_output 2>&1 && test_should_contain "Content-Disposition: ${disposition}\; filename=\"${FILE_CID}.${format}\"" curl_output && test_should_contain "Content-Type: application/vnd.ipld.dag-$format" curl_output && test_should_not_contain "Content-Type: application/$format" curl_output ' - test_expect_success "GET UnixFS as $name with format=$format has expected Content-Type" ' - curl -sD - "http://127.0.0.1:$GWAY_PORT/ipfs/$FILE_CID?format=$format" > curl_output 2>&1 && - test_should_contain "Content-Disposition: ${disposition}\; filename=\"${FILE_CID}.${format}\"" curl_output && - test_should_contain "Content-Type: application/$format" curl_output && - test_should_not_contain "Content-Type: application/vnd.ipld.dag-$format" curl_output + test_expect_success "GET UnixFS as $name with 'Accept: foo, application/vnd.ipld.dag-$format,bar' converts to the expected Content-Type" ' + curl -sD - -H "Accept: foo, application/vnd.ipld.dag-$format,text/plain" "http://127.0.0.1:$GWAY_PORT/ipfs/$FILE_CID" > curl_output 2>&1 && + test_should_contain "Content-Type: application/vnd.ipld.dag-$format" curl_output ' - test_expect_success "GET UnixFS as $name with 'Accept: application/$format' has expected Content-Type" ' - curl -sD - -H "Accept: application/$format" "http://127.0.0.1:$GWAY_PORT/ipfs/$FILE_CID" > curl_output 2>&1 && - test_should_contain "Content-Disposition: ${disposition}\; filename=\"${FILE_CID}.${format}\"" curl_output && - test_should_contain "Content-Type: application/$format" curl_output && - test_should_not_contain "Content-Type: application/vnd.ipld.dag-$format" curl_output + test_expect_success "GET UnixFS with format=$format (not dag-$format) is no-op (no conversion)" ' + curl -sD headers "http://127.0.0.1:$GWAY_PORT/ipfs/$FILE_CID?format=$format" > curl_output 2>&1 && + ipfs cat $FILE_CID > cat_output && + test_cmp cat_output curl_output && + test_should_contain "Content-Type: text/plain" headers && + test_should_not_contain "Content-Type: application/$format" headers && + test_should_not_contain "Content-Type: application/vnd.ipld.dag-$format" headers ' - test_expect_success "GET UnixFS as $name with 'Accept: foo, application/$format,bar' has expected Content-Type" ' - curl -sD - -H "Accept: foo, application/$format,text/plain" "http://127.0.0.1:$GWAY_PORT/ipfs/$FILE_CID" > curl_output 2>&1 && - test_should_contain "Content-Type: application/$format" curl_output + test_expect_success "GET UnixFS with 'Accept: application/$format' (not dag-$format) is no-op (no conversion)" ' + curl -sD headers -H "Accept: application/$format" "http://127.0.0.1:$GWAY_PORT/ipfs/$FILE_CID" > curl_output 2>&1 && + ipfs cat $FILE_CID > cat_output && + test_cmp cat_output curl_output && + test_should_contain "Content-Type: text/plain" headers && + test_should_not_contain "Content-Type: application/$format" headers && + test_should_not_contain "Content-Type: application/vnd.ipld.dag-$format" headers ' } -test_dag_pb_headers "DAG-JSON" "json" "inline" -test_dag_pb_headers "DAG-CBOR" "cbor" "attachment" +test_dag_pb_conversion "DAG-JSON" "json" "inline" +test_dag_pb_conversion "DAG-CBOR" "cbor" "attachment" -test_dag_pb () { - name=$1 - format=$2 - test_expect_success "GET UnixFS as $name has expected output for file" ' - curl -s "http://127.0.0.1:$GWAY_PORT/ipfs/$FILE_CID?format=dag-$format" > curl_output 2>&1 && - ipfs dag get --output-codec dag-$format $FILE_CID > ipfs_dag_get_output 2>&1 && - test_cmp ipfs_dag_get_output curl_output - ' - - test_expect_success "GET UnixFS as $name has expected output for directory" ' - curl -s "http://127.0.0.1:$GWAY_PORT/ipfs/$DIR_CID?format=dag-$format" > curl_output 2>&1 && - ipfs dag get --output-codec dag-$format $DIR_CID > ipfs_dag_get_output 2>&1 && - test_cmp ipfs_dag_get_output curl_output - ' - - test_expect_success "GET UnixFS as $name with format=dag-$format and format=$format produce same output" ' - curl -s "http://127.0.0.1:$GWAY_PORT/ipfs/$DIR_CID?format=dag-$format" > curl_output_1 2>&1 && - curl -s "http://127.0.0.1:$GWAY_PORT/ipfs/$DIR_CID?format=$format" > curl_output_2 2>&1 && - test_cmp curl_output_1 curl_output_2 - ' -} - -test_dag_pb "DAG-JSON" "json" -test_dag_pb "DAG-CBOR" "cbor" - -## Content-Type response based on Accept header and ?format= parameter - -test_cmp_dag_get () { +# Requesting CID with plain json (0x0200) and cbor (0x51) codecs +# (note these are not UnixFS, not DAG-* variants, just raw block identified by a CID with a special codec) +test_plain_codec () { name=$1 format=$2 disposition=$3 - test_expect_success "GET $name without Accept or format= has expected Content-Type" ' - CID=$(echo "{ \"test\": \"json\" }" | ipfs dag put --input-codec json --store-codec $format) && - curl -sD - "http://127.0.0.1:$GWAY_PORT/ipfs/$CID" > curl_output 2>&1 && - test_should_contain "Content-Disposition: ${disposition}\; filename=\"${CID}.${format}\"" curl_output && - test_should_contain "Content-Type: application/$format" curl_output + # no explicit format, just codec in CID + test_expect_success "GET $name without Accept or format= has expected $format Content-Type and body as-is" ' + CID=$(echo "{ \"test\": \"plain json\" }" | ipfs dag put --input-codec json --store-codec $format) && + curl -sD headers "http://127.0.0.1:$GWAY_PORT/ipfs/$CID" > curl_output 2>&1 && + ipfs block get $CID > ipfs_block_output 2>&1 && + test_cmp ipfs_block_output curl_output && + test_should_contain "Content-Disposition: ${disposition}\; filename=\"${CID}.${format}\"" headers && + test_should_contain "Content-Type: application/$format" headers ' - test_expect_success "GET $name without Accept or format= produces correct output" ' - CID=$(echo "{ \"test\": \"json\" }" | ipfs dag put --input-codec json --store-codec $format) && - curl -s "http://127.0.0.1:$GWAY_PORT/ipfs/$CID" > curl_output 2>&1 && - ipfs dag get --output-codec $format $CID > ipfs_dag_get_output 2>&1 && - test_cmp ipfs_dag_get_output curl_output + # explicit format still gives correct output, just codec in CID + test_expect_success "GET $name with ?format= has expected $format Content-Type and body as-is" ' + CID=$(echo "{ \"test\": \"plain json\" }" | ipfs dag put --input-codec json --store-codec $format) && + curl -sD headers "http://127.0.0.1:$GWAY_PORT/ipfs/$CID?format=$format" > curl_output 2>&1 && + ipfs block get $CID > ipfs_block_output 2>&1 && + test_cmp ipfs_block_output curl_output && + test_should_contain "Content-Disposition: ${disposition}\; filename=\"${CID}.${format}\"" headers && + test_should_contain "Content-Type: application/$format" headers ' - test_expect_success "GET $name with format=$format produces expected Content-Type" ' - CID=$(echo "{ \"test\": \"json\" }" | ipfs dag put --input-codec json --store-codec $format) && - curl -sD- "http://127.0.0.1:$GWAY_PORT/ipfs/$CID?format=$format" > curl_output 2>&1 && - test_should_contain "Content-Disposition: ${disposition}\; filename=\"${CID}.${format}\"" curl_output && - test_should_contain "Content-Type: application/$format" curl_output + # explicit format still gives correct output, just codec in CID + test_expect_success "GET $name with Accept has expected $format Content-Type and body as-is" ' + CID=$(echo "{ \"test\": \"plain json\" }" | ipfs dag put --input-codec json --store-codec $format) && + curl -sD headers -H "Accept: application/$format" "http://127.0.0.1:$GWAY_PORT/ipfs/$CID" > curl_output 2>&1 && + ipfs block get $CID > ipfs_block_output 2>&1 && + test_cmp ipfs_block_output curl_output && + test_should_contain "Content-Disposition: ${disposition}\; filename=\"${CID}.${format}\"" headers && + test_should_contain "Content-Type: application/$format" headers ' - test_expect_success "GET $name with format=$format produces correct output" ' - CID=$(echo "{ \"test\": \"json\" }" | ipfs dag put --input-codec json --store-codec $format) && - curl -s "http://127.0.0.1:$GWAY_PORT/ipfs/$CID?format=$format" > curl_output 2>&1 && - ipfs dag get --output-codec $format $CID > ipfs_dag_get_output 2>&1 && - test_cmp ipfs_dag_get_output curl_output - ' - - test_expect_success "GET $name with format=dag-$format produces expected Content-Type" ' - CID=$(echo "{ \"test\": \"json\" }" | ipfs dag put --input-codec json --store-codec $format) && - curl -sD- "http://127.0.0.1:$GWAY_PORT/ipfs/$CID?format=dag-$format" > curl_output 2>&1 && - test_should_contain "Content-Disposition: ${disposition}\; filename=\"${CID}.${format}\"" curl_output && - test_should_contain "Content-Type: application/vnd.ipld.dag-$format" curl_output - ' - - test_expect_success "GET $name with format=dag-$format produces correct output" ' - CID=$(echo "{ \"test\": \"json\" }" | ipfs dag put --input-codec json --store-codec $format) && - curl -s "http://127.0.0.1:$GWAY_PORT/ipfs/$CID?format=dag-$format" > curl_output 2>&1 && + # explicit dag-* format passed, attempt to parse as dag* variant + ## Note: this works only for simple JSON that can be upgraded to DAG-JSON. + test_expect_success "GET $name with format=dag-$format interprets $format as dag-* variant and produces expected Content-Type and body" ' + CID=$(echo "{ \"test\": \"plain-json-that-can-also-be-dag-json\" }" | ipfs dag put --input-codec json --store-codec $format) && + curl -sD headers "http://127.0.0.1:$GWAY_PORT/ipfs/$CID?format=dag-$format" > curl_output_param 2>&1 && ipfs dag get --output-codec dag-$format $CID > ipfs_dag_get_output 2>&1 && - test_cmp ipfs_dag_get_output curl_output + test_cmp ipfs_dag_get_output curl_output_param && + test_should_contain "Content-Disposition: ${disposition}\; filename=\"${CID}.${format}\"" headers && + test_should_contain "Content-Type: application/vnd.ipld.dag-$format" headers && + curl -s -H "Accept: application/vnd.ipld.dag-$format" "http://127.0.0.1:$GWAY_PORT/ipfs/$CID" > curl_output_accept 2>&1 && + test_cmp curl_output_param curl_output_accept ' + } -test_cmp_dag_get "JSON" "json" "inline" -test_cmp_dag_get "CBOR" "cbor" "attachment" +test_plain_codec "plain JSON codec" "json" "inline" +test_plain_codec "plain CBOR codec" "cbor" "attachment" - -## Lossless conversion between JSON and CBOR - -test_expect_success "GET JSON as CBOR produces DAG-CBOR output" ' - CID=$(echo "{ \"test\": \"json\" }" | ipfs dag put --input-codec json --store-codec json) && - curl -s "http://127.0.0.1:$GWAY_PORT/ipfs/$CID?format=cbor" > curl_output 2>&1 && - ipfs dag get --output-codec dag-cbor $CID > ipfs_dag_get_output 2>&1 && - test_cmp ipfs_dag_get_output curl_output -' - -test_expect_success "GET CBOR as JSON produces DAG-JSON output" ' - CID=$(echo "{ \"test\": \"json\" }" | ipfs dag put --input-codec json --store-codec cbor) && - curl -s "http://127.0.0.1:$GWAY_PORT/ipfs/$CID?format=json" > curl_output 2>&1 && - ipfs dag get --output-codec dag-json $CID > ipfs_dag_get_output 2>&1 && - test_cmp ipfs_dag_get_output curl_output -' - - -## Pathing, traversal +## Pathing, traversal over DAG-JSON and DAG-CBOR DAG_CBOR_TRAVERSAL_CID="bafyreibs4utpgbn7uqegmd2goqz4bkyflre2ek2iwv743fhvylwi4zeeim" DAG_JSON_TRAVERSAL_CID="baguqeeram5ujjqrwheyaty3w5gdsmoz6vittchvhk723jjqxk7hakxkd47xq" @@ -204,17 +196,9 @@ test_expect_success "GET DAG-CBOR traverses multiple links" ' test_cmp expected actual ' -# test_expect_success "GET DAG-PB has expected output" ' -# curl -s "http://127.0.0.1:$GWAY_PORT/ipfs/$DAG_PB_CID?format=dag-json" > curl_output 2>&1 && -# jq --sort-keys . curl_output > actual && -# test_cmp ../t0123-gateway-json-cbor/dag-pb.json actual -# ' - - -## NATIVE TESTS: +## NATIVE TESTS for DAG-JSON (0x0129) and DAG-CBOR (0x71): ## DAG- regression tests for core behaviors when native DAG-(CBOR|JSON) is requested - test_native_dag () { name=$1 format=$2 @@ -237,10 +221,10 @@ test_native_dag () { test_cmp expected curl_ipfs_dag_param_output ' - test_expect_success "GET $name from /ipfs with format=$format returns the same payload as format=dag-$format" ' + test_expect_success "GET $name from /ipfs for application/$format returns the same payload as format=dag-$format" ' curl -sX GET "http://127.0.0.1:$GWAY_PORT/ipfs/$CID?format=dag-$format" -o expected && - curl -sX GET "http://127.0.0.1:$GWAY_PORT/ipfs/$CID?format=dag-$format" -o curl_ipfs_dag_param_output && - test_cmp expected curl_ipfs_dag_param_output + curl -sX GET "http://127.0.0.1:$GWAY_PORT/ipfs/$CID?format=$format" -o plain_output && + test_cmp expected plain_output ' test_expect_success "GET $name from /ipfs with application/vnd.ipld.dag-$format returns the same payload as the raw block" ' @@ -249,6 +233,23 @@ test_native_dag () { test_cmp expected_block curl_ipfs_dag_block_accept_output ' + # Make sure DAG-* can be requested as plain JSON or CBOR and response has plain Content-Type for interop purposes + + test_expect_success "GET $name with format=$format returns same payload as format=dag-$format but with plain Content-Type" ' + curl -s "http://127.0.0.1:$GWAY_PORT/ipfs/$CID?format=dag-$format" -o expected && + curl -sD plain_headers "http://127.0.0.1:$GWAY_PORT/ipfs/$CID?format=$format" -o plain_output && + test_should_contain "Content-Type: application/$format" plain_headers && + test_cmp expected plain_output + ' + + test_expect_success "GET $name with Accept: application/$format returns same payload as application/vnd.ipld.dag-$format but with plain Content-Type" ' + curl -s -H "Accept: application/vnd.ipld.dag-$format" "http://127.0.0.1:$GWAY_PORT/ipfs/$CID" > expected && + curl -sD plain_headers -H "Accept: application/$format" "http://127.0.0.1:$GWAY_PORT/ipfs/$CID" > plain_output && + test_should_contain "Content-Type: application/$format" plain_headers && + test_cmp expected plain_output + ' + + # Make sure expected HTTP headers are returned with the dag- block test_expect_success "GET response for application/vnd.ipld.dag-$format has expected Content-Type" ' @@ -302,18 +303,11 @@ test_native_dag () { test_should_contain "Content-Type: application/vnd.ipld.dag-$format" output && test_should_contain "Content-Length: " output ' - test_expect_success "HEAD $name with an explicit JSON format returns HTTP 200" ' - curl -I "http://127.0.0.1:$GWAY_PORT/ipfs/$CID?format=json" -o output && + test_expect_success "HEAD $name with an explicit DAG-JSON format returns HTTP 200" ' + curl -I "http://127.0.0.1:$GWAY_PORT/ipfs/$CID?format=dag-json" -o output && test_should_contain "HTTP/1.1 200 OK" output && - test_should_contain "Etag: \"$CID.json\"" output && - test_should_contain "Content-Type: application/json" output && - test_should_contain "Content-Length: " output - ' - test_expect_success "HEAD dag-pb with ?format=$format returns HTTP 200" ' - curl -I "http://127.0.0.1:$GWAY_PORT/ipfs/$FILE_CID?format=$format" -o output && - test_should_contain "HTTP/1.1 200 OK" output && - test_should_contain "Etag: \"$FILE_CID.$format\"" output && - test_should_contain "Content-Type: application/$format" output && + test_should_contain "Etag: \"$CID.dag-json\"" output && + test_should_contain "Content-Type: application/vnd.ipld.dag-json" output && test_should_contain "Content-Length: " output ' test_expect_success "HEAD $name with only-if-cached for missing block returns HTTP 412 Precondition Failed" ' From 9327ee64ce96ca6da29bb2a099e0e0930b0d9e09 Mon Sep 17 00:00:00 2001 From: Steve Loeppky Date: Sun, 22 Jan 2023 11:04:18 -0800 Subject: [PATCH 0397/1212] fix: clarity: no user supplied rcmgr limits of 0 (#9563) Co-authored-by: Antonio Navarro Perez Co-authored-by: Marcin Rataj --- core/node/libp2p/rcmgr.go | 16 +++++++++++----- docs/config.md | 3 +++ 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/core/node/libp2p/rcmgr.go b/core/node/libp2p/rcmgr.go index fe7fc635e..e0ce4693b 100644 --- a/core/node/libp2p/rcmgr.go +++ b/core/node/libp2p/rcmgr.go @@ -52,7 +52,8 @@ func ResourceManager(cfg config.SwarmConfig) interface{} { return nil, opts, fmt.Errorf("opening IPFS_PATH: %w", err) } - limitConfig, err := createDefaultLimitConfig(cfg) + var limitConfig rcmgr.LimitConfig + defaultComputedLimitConfig, err := createDefaultLimitConfig(cfg) if err != nil { return nil, opts, err } @@ -61,10 +62,15 @@ func ResourceManager(cfg config.SwarmConfig) interface{} { // is documented in docs/config.md. // Any changes here should be reflected there. if cfg.ResourceMgr.Limits != nil { - l := *cfg.ResourceMgr.Limits - // This effectively overrides the computed default LimitConfig with any vlues from cfg.ResourceMgr.Limits - l.Apply(limitConfig) - limitConfig = l + userSuppliedOverrideLimitConfig := *cfg.ResourceMgr.Limits + // This effectively overrides the computed default LimitConfig with any non-zero values from cfg.ResourceMgr.Limits. + // Because of how how Apply works, any 0 value for a user supplied override + // will be overriden with a computed default value. + // There currently isn't a way for a user to supply a 0-value override. + userSuppliedOverrideLimitConfig.Apply(defaultComputedLimitConfig) + limitConfig = userSuppliedOverrideLimitConfig + } else { + limitConfig = defaultComputedLimitConfig } if err := ensureConnMgrMakeSenseVsResourceMgr(limitConfig, cfg.ConnMgr); err != nil { diff --git a/docs/config.md b/docs/config.md index aae2017d0..da919d844 100644 --- a/docs/config.md +++ b/docs/config.md @@ -1844,6 +1844,9 @@ The `Swarm.ResourceMgr.Limits` override the default limits described above. Any override `BaseLimits` or limit s from `Swarm.ResourceMgr.Limits` that aren't specified will use the [computed default limits](./libp2p-resource-management.md#computed-default-limits). +Until [ipfs/kubo#9564](https://github.com/ipfs/kubo/issues/9564) is addressed, there isn't a way to set an override limit of zero. +0 is currently ignored. 0 currently means use to use the [computed default limits](./libp2p-resource-management.md#computed-default-limits). + Example #1: setting limits for a specific scope ```json { From 26edc75eaae9a24936731a6da28e37b080fedef3 Mon Sep 17 00:00:00 2001 From: Vladimir Ivanov Date: Wed, 4 Jan 2023 18:47:32 +0300 Subject: [PATCH 0398/1212] docs: clarify debug environment variables --- docs/environment-variables.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/environment-variables.md b/docs/environment-variables.md index add8592a0..ba1cce166 100644 --- a/docs/environment-variables.md +++ b/docs/environment-variables.md @@ -75,13 +75,13 @@ Warning: Enabling tracing will likely affect performance. ## `IPFS_FUSE_DEBUG` -Enables fuse debug logging. +If SET, enables fuse debug logging. Default: false ## `YAMUX_DEBUG` -Enables debug logging for the yamux stream muxer. +If SET, enables debug logging for the yamux stream muxer. Default: false From 04931b042d88753c1f2dc7846b4b5925ba816948 Mon Sep 17 00:00:00 2001 From: Antonio Navarro Perez Date: Wed, 4 Jan 2023 20:44:37 +0100 Subject: [PATCH 0399/1212] docs(config): ProviderSearchDelay (#9526) Signed-off-by: Antonio Navarro Perez Co-authored-by: Marcin Rataj --- docs/config.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/docs/config.md b/docs/config.md index 87f2cf1dc..aae2017d0 100644 --- a/docs/config.md +++ b/docs/config.md @@ -71,6 +71,7 @@ config file at runtime. - [`Internal.Bitswap.EngineBlockstoreWorkerCount`](#internalbitswapengineblockstoreworkercount) - [`Internal.Bitswap.EngineTaskWorkerCount`](#internalbitswapenginetaskworkercount) - [`Internal.Bitswap.MaxOutstandingBytesPerPeer`](#internalbitswapmaxoutstandingbytesperpeer) + - [`Internal.Bitswap.ProviderSearchDelay`](#internalbitswapprovidersearchdelay) - [`Internal.UnixFSShardingSizeThreshold`](#internalunixfsshardingsizethreshold) - [`Ipns`](#ipns) - [`Ipns.RepublishPeriod`](#ipnsrepublishperiod) @@ -153,7 +154,6 @@ config file at runtime. - [`Swarm.Transports.Network.QUIC`](#swarmtransportsnetworkquic) - [`Swarm.Transports.Network.Relay`](#swarmtransportsnetworkrelay) - [`Swarm.Transports.Network.WebTransport`](#swarmtransportsnetworkwebtransport) - - [How to enable WebTransport](#how-to-enable-webtransport) - [`Swarm.Transports.Security`](#swarmtransportssecurity) - [`Swarm.Transports.Security.TLS`](#swarmtransportssecuritytls) - [`Swarm.Transports.Security.SECIO`](#swarmtransportssecuritysecio) @@ -970,6 +970,14 @@ deteriorate the quality provided to less aggressively-wanting peers. Type: `optionalInteger` (byte count, `null` means default which is 1MB) +### `Internal.Bitswap.ProviderSearchDelay` + +This parameter determines how long to wait before looking for providers outside of bitswap. +Other routing systems like the DHT are able to provide results in less than a second, so lowering +this number will allow faster peers lookups in some cases. + +Type: `optionalDuration` (`null` means default which is 1s) + ### `Internal.UnixFSShardingSizeThreshold` The sharding threshold used internally to decide whether a UnixFS directory should be sharded or not. From 9d8d2748b1adbf5613050c364b51739ae45c7067 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Thu, 5 Jan 2023 00:08:05 +0100 Subject: [PATCH 0400/1212] fix(ci): flaky sharness test --- test/sharness/t0172-content-routing-over-http.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/sharness/t0172-content-routing-over-http.sh b/test/sharness/t0172-content-routing-over-http.sh index bc35c6328..d7028071f 100755 --- a/test/sharness/t0172-content-routing-over-http.sh +++ b/test/sharness/t0172-content-routing-over-http.sh @@ -21,6 +21,7 @@ test_launch_ipfs_daemon test_expect_success "start HTTP router proxy" ' socat TCP-LISTEN:$ROUTER_PORT,reuseaddr,fork,bind=127.0.0.1 STDOUT > http_requests & NCPID=$! + test_wait_for_file 50 100ms http_requests ' ## HTTP GETs @@ -30,7 +31,8 @@ test_expect_success 'create unique CID without adding it to the local datastore' ' test_expect_success 'expect HTTP request for unknown CID' ' - ipfs routing findprovs --timeout 3s "$WANT_CID" && + ipfs block stat "$WANT_CID" & + test_wait_output_n_lines_60_sec http_requests 3 && test_should_contain "GET /routing/v1/providers/$WANT_CID" http_requests ' From 1f3e1d1120e902f5b759d0d0c202349ccf14d634 Mon Sep 17 00:00:00 2001 From: Antonio Navarro Perez Date: Thu, 5 Jan 2023 13:30:24 +0100 Subject: [PATCH 0401/1212] docs: fix Router config Godoc (#9528) Co-authored-by: Marcin Rataj --- config/routing.go | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/config/routing.go b/config/routing.go index 983e8606d..f19414ff3 100644 --- a/config/routing.go +++ b/config/routing.go @@ -22,10 +22,7 @@ type Routing struct { type Router struct { - // Currenly supported Types are "reframe", "dht", "parallel", "sequential". - // Reframe type allows to add other resolvers using the Reframe spec: - // https://github.com/ipfs/specs/tree/main/reframe - // In the future we will support "dht" and other Types here. + // Router type ID. See RouterType for more info. Type RouterType // Parameters are extra configuration that this router might need. @@ -107,11 +104,11 @@ func (r *RouterParser) UnmarshalJSON(b []byte) error { type RouterType string const ( - RouterTypeReframe RouterType = "reframe" - RouterTypeHTTP RouterType = "http" - RouterTypeDHT RouterType = "dht" - RouterTypeSequential RouterType = "sequential" - RouterTypeParallel RouterType = "parallel" + RouterTypeReframe RouterType = "reframe" // More info here: https://github.com/ipfs/specs/tree/main/reframe . Actually deprecated. + RouterTypeHTTP RouterType = "http" // HTTP JSON API for delegated routing systems (IPIP-337). + RouterTypeDHT RouterType = "dht" // DHT router. + RouterTypeSequential RouterType = "sequential" // Router helper to execute several routers sequentially. + RouterTypeParallel RouterType = "parallel" // Router helper to execute several routers in parallel. ) type DHTMode string From b22aae76a49c4686fc7a475620e1bc2e42bf1e9d Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Thu, 8 Dec 2022 21:12:34 +0100 Subject: [PATCH 0402/1212] fix(test): retry flaky t0125-twonode.sh This makes is clear why test failed, and what were values. Fixes flaky test: It will re-run flaky advanced test until bitswap stats match expected value (something team has been doing anyway for the past year). It also adds /quic-v1 and /webtransport tests --- test/sharness/t0125-twonode.sh | 84 +++++++++++++------ .../t0172-content-routing-over-http.sh | 2 +- 2 files changed, 61 insertions(+), 25 deletions(-) diff --git a/test/sharness/t0125-twonode.sh b/test/sharness/t0125-twonode.sh index 6f819400a..dcf5c88ce 100755 --- a/test/sharness/t0125-twonode.sh +++ b/test/sharness/t0125-twonode.sh @@ -52,7 +52,7 @@ run_random_dir_test() { check_dir_fetch 1 $DIR_HASH } -run_advanced_test() { +flaky_advanced_test() { startup_cluster 2 "$@" test_expect_success "clean repo before test" ' @@ -64,20 +64,9 @@ run_advanced_test() { run_random_dir_test - test_expect_success "node0 data transferred looks correct" ' - ipfsi 0 bitswap stat > stat0 && - grep "blocks sent: 126" stat0 > /dev/null && - grep "blocks received: 5" stat0 > /dev/null && - grep "data sent: 228113" stat0 > /dev/null && - grep "data received: 1000256" stat0 > /dev/null - ' - - test_expect_success "node1 data transferred looks correct" ' - ipfsi 1 bitswap stat > stat1 && - grep "blocks received: 126" stat1 > /dev/null && - grep "blocks sent: 5" stat1 > /dev/null && - grep "data received: 228113" stat1 > /dev/null && - grep "data sent: 1000256" stat1 > /dev/null + test_expect_success "gather bitswap stats" ' + ipfsi 0 bitswap stat -v > stat0 && + ipfsi 1 bitswap stat -v > stat1 ' test_expect_success "shut down nodes" ' @@ -85,27 +74,62 @@ run_advanced_test() { ' } +run_advanced_test() { + # TODO: investigate why flaky_advanced_test is flaky + # Context: https://github.com/ipfs/kubo/pull/9486 + # sometimes, bitswap status returns unexpected block transfers + # and everyone has been re-running circleci until is passes for at least a year. + # this re-runs test until it passes or a timeout hits + + BLOCKS_0=126 + BLOCKS_1=5 + DATA_0=228113 + DATA_1=1000256 + for i in $(test_seq 1 600); do + flaky_advanced_test + (grep -q "$DATA_0" stat0 && grep -q "$DATA_1" stat1) && break + go-sleep 100ms + done + + test_expect_success "node0 data transferred looks correct" ' + test_should_contain "blocks sent: $BLOCKS_0" stat0 && + test_should_contain "blocks received: $BLOCKS_1" stat0 && + test_should_contain "data sent: $DATA_0" stat0 && + test_should_contain "data received: $DATA_1" stat0 + ' + + test_expect_success "node1 data transferred looks correct" ' + test_should_contain "blocks received: $BLOCKS_0" stat1 && + test_should_contain "blocks sent: $BLOCKS_1" stat1 && + test_should_contain "data received: $DATA_0" stat1 && + test_should_contain "data sent: $DATA_1" stat1 + ' + +} + test_expect_success "set up tcp testbed" ' iptb testbed create -type localipfs -count 2 -force -init ' -addrs='"[\"/ip4/127.0.0.1/tcp/0\", \"/ip4/127.0.0.1/udp/0/quic\"]"' -test_expect_success "configure addresses" ' - ipfsi 0 config --json Addresses.Swarm '"${addrs}"' && - ipfsi 1 config --json Addresses.Swarm '"${addrs}"' +test_expect_success "disable routing, use direct peering" ' + iptb run -- ipfs config Routing.Type none && + iptb run -- ipfs config --json Bootstrap "[]" ' # Test TCP transport echo "Testing TCP" +addrs='"[\"/ip4/127.0.0.1/tcp/0\"]"' test_expect_success "use TCP only" ' + iptb run -- ipfs config --json Addresses.Swarm '"${addrs}"' && iptb run -- ipfs config --json Swarm.Transports.Network.QUIC false && iptb run -- ipfs config --json Swarm.Transports.Network.Relay false && + iptb run -- ipfs config --json Swarm.Transports.Network.WebTransport false && iptb run -- ipfs config --json Swarm.Transports.Network.Websocket false ' run_advanced_test # test multiplex muxer -echo "Running advanced tests with mplex" +echo "Running TCP tests with mplex" test_expect_success "disable yamux" ' iptb run -- ipfs config --json Swarm.Transports.Multiplexers.Yamux false ' @@ -114,23 +138,35 @@ run_advanced_test test_expect_success "re-enable yamux" ' iptb run -- ipfs config --json Swarm.Transports.Multiplexers.Yamux null ' - # test Noise - -echo "Running advanced tests with NOISE" +echo "Running TCP tests with NOISE" test_expect_success "use noise only" ' iptb run -- ipfs config --json Swarm.Transports.Security.TLS false ' - run_advanced_test +test_expect_success "re-enable TLS" ' + iptb run -- ipfs config --json Swarm.Transports.Security.TLS null +' + # test QUIC echo "Running advanced tests over QUIC" +addrs='"[\"/ip4/127.0.0.1/udp/0/quic-v1\"]"' test_expect_success "use QUIC only" ' + iptb run -- ipfs config --json Addresses.Swarm '"${addrs}"' && iptb run -- ipfs config --json Swarm.Transports.Network.QUIC true && iptb run -- ipfs config --json Swarm.Transports.Network.TCP false ' +run_advanced_test +# test WebTransport +echo "Running advanced tests over WebTransport" +addrs='"[\"/ip4/127.0.0.1/udp/0/quic-v1/webtransport\"]"' +test_expect_success "use WebTransport only" ' + iptb run -- ipfs config --json Addresses.Swarm '"${addrs}"' && + iptb run -- ipfs config --json Swarm.Transports.Network.QUIC true && + iptb run -- ipfs config --json Swarm.Transports.Network.WebTransport true +' run_advanced_test test_done diff --git a/test/sharness/t0172-content-routing-over-http.sh b/test/sharness/t0172-content-routing-over-http.sh index d7028071f..b173ca053 100755 --- a/test/sharness/t0172-content-routing-over-http.sh +++ b/test/sharness/t0172-content-routing-over-http.sh @@ -19,7 +19,7 @@ export IPFS_HTTP_ROUTERS="http://127.0.0.1:$ROUTER_PORT" test_launch_ipfs_daemon test_expect_success "start HTTP router proxy" ' - socat TCP-LISTEN:$ROUTER_PORT,reuseaddr,fork,bind=127.0.0.1 STDOUT > http_requests & + socat TCP-LISTEN:$ROUTER_PORT,reuseaddr,fork,bind=127.0.0.1,retry=10 STDOUT > http_requests & NCPID=$! test_wait_for_file 50 100ms http_requests ' From b333740468fc6bd249878f8b82ef59a431879a6a Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Wed, 11 Jan 2023 03:40:58 +0100 Subject: [PATCH 0403/1212] fix(gateway): JSON when Accept is a list Block/CAR responses always had single explicit type, and we did not bother with implementing/testing lists. With the introduction of JSON people may start passing a list. This is the most basic fix which will return on the first matching type (in order). This does not implements weights (can be added in future, if needed). Closes #9520 --- core/corehttp/gateway_handler.go | 26 ++++++++++++++---------- test/sharness/t0123-gateway-json-cbor.sh | 5 +++++ 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/core/corehttp/gateway_handler.go b/core/corehttp/gateway_handler.go index 1222b17bc..64c388df4 100644 --- a/core/corehttp/gateway_handler.go +++ b/core/corehttp/gateway_handler.go @@ -890,18 +890,22 @@ func customResponseFormat(r *http.Request) (mediaType string, params map[string] } // Browsers and other user agents will send Accept header with generic types like: // Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8 - // We only care about explicit, vendor-specific content-types. - for _, accept := range r.Header.Values("Accept") { - // respond to the very first ipld content type - if strings.HasPrefix(accept, "application/vnd.ipld") || - strings.HasPrefix(accept, "application/x-tar") || - strings.HasPrefix(accept, "application/json") || - strings.HasPrefix(accept, "application/cbor") { - mediatype, params, err := mime.ParseMediaType(accept) - if err != nil { - return "", nil, err + // We only care about explicit, vendor-specific content-types and respond to the first match (in order). + // TODO: make this RFC compliant and respect weights (eg. return CAR for Accept:application/vnd.ipld.dag-json;q=0.1,application/vnd.ipld.car;q=0.2) + for _, header := range r.Header.Values("Accept") { + for _, value := range strings.Split(header, ",") { + accept := strings.TrimSpace(value) + // respond to the very first matching content type + if strings.HasPrefix(accept, "application/vnd.ipld") || + strings.HasPrefix(accept, "application/x-tar") || + strings.HasPrefix(accept, "application/json") || + strings.HasPrefix(accept, "application/cbor") { + mediatype, params, err := mime.ParseMediaType(accept) + if err != nil { + return "", nil, err + } + return mediatype, params, nil } - return mediatype, params, nil } } return "", nil, nil diff --git a/test/sharness/t0123-gateway-json-cbor.sh b/test/sharness/t0123-gateway-json-cbor.sh index 812d90f24..f4ebca19d 100755 --- a/test/sharness/t0123-gateway-json-cbor.sh +++ b/test/sharness/t0123-gateway-json-cbor.sh @@ -56,6 +56,11 @@ test_dag_pb_headers () { test_should_contain "Content-Type: application/$format" curl_output && test_should_not_contain "Content-Type: application/vnd.ipld.dag-$format" curl_output ' + + test_expect_success "GET UnixFS as $name with 'Accept: foo, application/$format,bar' has expected Content-Type" ' + curl -sD - -H "Accept: foo, application/$format,text/plain" "http://127.0.0.1:$GWAY_PORT/ipfs/$FILE_CID" > curl_output 2>&1 && + test_should_contain "Content-Type: application/$format" curl_output + ' } test_dag_pb_headers "DAG-JSON" "json" "inline" From 5138e7ba072384eadecf826a8a613503e9169c14 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Wed, 14 Dec 2022 18:56:13 +0100 Subject: [PATCH 0404/1212] fix: hint people to changing from RSA peer ids --- cmd/ipfs/daemon.go | 17 +++++++++++++++++ docs/changelogs/v0.18.md | 2 +- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/cmd/ipfs/daemon.go b/cmd/ipfs/daemon.go index af105589d..12b3f4d9c 100644 --- a/cmd/ipfs/daemon.go +++ b/cmd/ipfs/daemon.go @@ -30,6 +30,7 @@ import ( fsrepo "github.com/ipfs/kubo/repo/fsrepo" "github.com/ipfs/kubo/repo/fsrepo/migrations" "github.com/ipfs/kubo/repo/fsrepo/migrations/ipfsfetcher" + p2pcrypto "github.com/libp2p/go-libp2p/core/crypto" pnet "github.com/libp2p/go-libp2p/core/pnet" sockets "github.com/libp2p/go-socket-activation" @@ -459,6 +460,22 @@ func daemonFunc(req *cmds.Request, re cmds.ResponseEmitter, env cmds.Environment printSwarmAddrs(node) + if node.PrivateKey.Type() == p2pcrypto.RSA { + fmt.Print(` +Warning: You are using an RSA Peer ID, which was replaced by Ed25519 +as the default recommended in Kubo since September 2020. Signing with +RSA Peer IDs is more CPU-intensive than with other key types. +It is recommended that you change your public key type to ed25519 +by using the following command: + + ipfs key rotate -o rsa-key-backup -t ed25519 + +After changing your key type, restart your node for the changes to +take effect. + +`) + } + defer func() { // We wait for the node to close first, as the node has children // that it will wait for before closing, such as the API server. diff --git a/docs/changelogs/v0.18.md b/docs/changelogs/v0.18.md index 58077e214..e99cd5c94 100644 --- a/docs/changelogs/v0.18.md +++ b/docs/changelogs/v0.18.md @@ -159,7 +159,7 @@ To support QUICv1 and WebTransport by default a new config migration (`v13`) is To help protect nodes from DoS (resource exhaustion) and eclipse attacks, Kubo enabled the [go-libp2p Network Resource Manager](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager) by default in [Kubo 0.17](https://github.com/ipfs/kubo/blob/master/docs/changelogs/v0.17.md#libp2p-resource-management-enabled-by-default). - + Introducing limits like this by default after the fact is tricky, and various improvements have been made to improve the UX including: 1. [Dedicated docs concerning the resource manager integration](https://github.com/ipfs/kubo/blob/master/docs/libp2p-resource-management.md). This is a great place to go to learn more or get your FAQs answered. From 2759a229c709c1f9693610103906800f7e199c9a Mon Sep 17 00:00:00 2001 From: Antonio Navarro Perez Date: Fri, 13 Jan 2023 00:38:38 +0100 Subject: [PATCH 0405/1212] fix: stats dht command when Routing.Type=auto (#9538) Fixes default auto mode, but Routing.Type=custom needs more work. Continued in https://github.com/ipfs/kubo/issues/9482 --- core/node/libp2p/routing.go | 28 +++++++++++++++++++------- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- test/cli/stats_test.go | 24 ++++++++++++++++++++++ 6 files changed, 51 insertions(+), 13 deletions(-) create mode 100644 test/cli/stats_test.go diff --git a/core/node/libp2p/routing.go b/core/node/libp2p/routing.go index 21afe292d..f16fec5a1 100644 --- a/core/node/libp2p/routing.go +++ b/core/node/libp2p/routing.go @@ -7,13 +7,9 @@ import ( "sort" "time" - "github.com/ipfs/kubo/core/node/helpers" - irouting "github.com/ipfs/kubo/routing" - + "github.com/cenkalti/backoff/v4" ds "github.com/ipfs/go-datastore" offroute "github.com/ipfs/go-ipfs-routing/offline" - config "github.com/ipfs/kubo/config" - "github.com/ipfs/kubo/repo" dht "github.com/libp2p/go-libp2p-kad-dht" ddht "github.com/libp2p/go-libp2p-kad-dht/dual" "github.com/libp2p/go-libp2p-kad-dht/fullrt" @@ -24,9 +20,12 @@ import ( "github.com/libp2p/go-libp2p/core/host" "github.com/libp2p/go-libp2p/core/peer" "github.com/libp2p/go-libp2p/core/routing" - - "github.com/cenkalti/backoff/v4" "go.uber.org/fx" + + config "github.com/ipfs/kubo/config" + "github.com/ipfs/kubo/core/node/helpers" + "github.com/ipfs/kubo/repo" + irouting "github.com/ipfs/kubo/routing" ) type Router struct { @@ -77,6 +76,21 @@ func BaseRouting(experimentalDHTClient bool) interface{} { }) } + if pr, ok := in.Router.(routinghelpers.ComposableRouter); ok { + for _, r := range pr.Routers() { + if dht, ok := r.(*ddht.DHT); ok { + dr = dht + lc.Append(fx.Hook{ + OnStop: func(ctx context.Context) error { + return dr.Close() + }, + }) + + break + } + } + } + if dr != nil && experimentalDHTClient { cfg, err := in.Repo.Config() if err != nil { diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 079d5c727..7285936d6 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -127,7 +127,7 @@ require ( github.com/libp2p/go-libp2p-pubsub v0.8.2 // indirect github.com/libp2p/go-libp2p-pubsub-router v0.6.0 // indirect github.com/libp2p/go-libp2p-record v0.2.0 // indirect - github.com/libp2p/go-libp2p-routing-helpers v0.5.0 // indirect + github.com/libp2p/go-libp2p-routing-helpers v0.6.0 // indirect github.com/libp2p/go-libp2p-xor v0.1.0 // indirect github.com/libp2p/go-mplex v0.7.0 // indirect github.com/libp2p/go-msgio v0.2.0 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index e0669a13c..45176636f 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -793,8 +793,8 @@ github.com/libp2p/go-libp2p-quic-transport v0.10.0/go.mod h1:RfJbZ8IqXIhxBRm5hqU github.com/libp2p/go-libp2p-record v0.1.0/go.mod h1:ujNc8iuE5dlKWVy6wuL6dd58t0n7xI4hAIl8pE6wu5Q= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= github.com/libp2p/go-libp2p-record v0.2.0/go.mod h1:I+3zMkvvg5m2OcSdoL0KPljyJyvNDFGKX7QdlpYUcwk= -github.com/libp2p/go-libp2p-routing-helpers v0.5.0 h1:Byujua1X9MeTzbF54i5OwjUNopeg7PYBykuNow/w3p4= -github.com/libp2p/go-libp2p-routing-helpers v0.5.0/go.mod h1:wwK/XSLt6njjO7sRbjhf8w7PGBOfdntMQ2mOQPZ5s/Q= +github.com/libp2p/go-libp2p-routing-helpers v0.6.0 h1:Rfyd+wp/cU0PjNjCphGzLYzd7Q51fjOMs5Sjj6zWGT0= +github.com/libp2p/go-libp2p-routing-helpers v0.6.0/go.mod h1:wwK/XSLt6njjO7sRbjhf8w7PGBOfdntMQ2mOQPZ5s/Q= github.com/libp2p/go-libp2p-secio v0.1.0/go.mod h1:tMJo2w7h3+wN4pgU2LSYeiKPrfqBgkOsdiKK77hE7c8= github.com/libp2p/go-libp2p-secio v0.2.0/go.mod h1:2JdZepB8J5V9mBp79BmwsaPQhRPNN2NrnB2lKQcdy6g= github.com/libp2p/go-libp2p-secio v0.2.1/go.mod h1:cWtZpILJqkqrSkiYcDBh5lA3wbT2Q+hz3rJQq3iftD8= diff --git a/go.mod b/go.mod index cb399de99..55e770587 100644 --- a/go.mod +++ b/go.mod @@ -79,7 +79,7 @@ require ( github.com/libp2p/go-libp2p-pubsub v0.8.2 github.com/libp2p/go-libp2p-pubsub-router v0.6.0 github.com/libp2p/go-libp2p-record v0.2.0 - github.com/libp2p/go-libp2p-routing-helpers v0.5.0 + github.com/libp2p/go-libp2p-routing-helpers v0.6.0 github.com/libp2p/go-libp2p-testing v0.12.0 github.com/libp2p/go-socket-activation v0.1.0 github.com/miekg/dns v1.1.50 diff --git a/go.sum b/go.sum index 65831c18b..6f75ebb82 100644 --- a/go.sum +++ b/go.sum @@ -828,8 +828,8 @@ github.com/libp2p/go-libp2p-quic-transport v0.10.0/go.mod h1:RfJbZ8IqXIhxBRm5hqU github.com/libp2p/go-libp2p-record v0.1.0/go.mod h1:ujNc8iuE5dlKWVy6wuL6dd58t0n7xI4hAIl8pE6wu5Q= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= github.com/libp2p/go-libp2p-record v0.2.0/go.mod h1:I+3zMkvvg5m2OcSdoL0KPljyJyvNDFGKX7QdlpYUcwk= -github.com/libp2p/go-libp2p-routing-helpers v0.5.0 h1:Byujua1X9MeTzbF54i5OwjUNopeg7PYBykuNow/w3p4= -github.com/libp2p/go-libp2p-routing-helpers v0.5.0/go.mod h1:wwK/XSLt6njjO7sRbjhf8w7PGBOfdntMQ2mOQPZ5s/Q= +github.com/libp2p/go-libp2p-routing-helpers v0.6.0 h1:Rfyd+wp/cU0PjNjCphGzLYzd7Q51fjOMs5Sjj6zWGT0= +github.com/libp2p/go-libp2p-routing-helpers v0.6.0/go.mod h1:wwK/XSLt6njjO7sRbjhf8w7PGBOfdntMQ2mOQPZ5s/Q= github.com/libp2p/go-libp2p-secio v0.1.0/go.mod h1:tMJo2w7h3+wN4pgU2LSYeiKPrfqBgkOsdiKK77hE7c8= github.com/libp2p/go-libp2p-secio v0.2.0/go.mod h1:2JdZepB8J5V9mBp79BmwsaPQhRPNN2NrnB2lKQcdy6g= github.com/libp2p/go-libp2p-secio v0.2.1/go.mod h1:cWtZpILJqkqrSkiYcDBh5lA3wbT2Q+hz3rJQq3iftD8= diff --git a/test/cli/stats_test.go b/test/cli/stats_test.go new file mode 100644 index 000000000..05c1702b4 --- /dev/null +++ b/test/cli/stats_test.go @@ -0,0 +1,24 @@ +package cli + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/ipfs/kubo/test/cli/harness" +) + +func TestStats(t *testing.T) { + t.Parallel() + + t.Run("stats dht", func(t *testing.T) { + t.Parallel() + nodes := harness.NewT(t).NewNodes(2).Init().StartDaemons().Connect() + node1 := nodes[0] + + res := node1.IPFS("stats", "dht") + assert.NoError(t, res.Err) + assert.Equal(t, 0, len(res.Stderr.Lines())) + assert.NotEqual(t, 0, len(res.Stdout.Lines())) + }) +} From 4ddeda55c04f50a21a6991071fad3f699e008aa6 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Fri, 13 Jan 2023 14:27:03 +0100 Subject: [PATCH 0406/1212] chore: migrate from go-ipfs-files to go-libipfs/files (#9535) --- assets/assets.go | 2 +- cmd/ipfs/add_migrations.go | 2 +- cmd/ipfs/init.go | 2 +- cmd/ipfswatch/main.go | 2 +- core/commands/add.go | 2 +- core/commands/block.go | 2 +- core/commands/cat.go | 6 ++-- core/commands/cmdenv/file.go | 2 +- core/commands/dag/import.go | 2 +- core/commands/dag/put.go | 2 +- core/commands/get.go | 2 +- core/commands/swarm.go | 2 +- core/commands/urlstore.go | 2 +- core/coreapi/test/path_test.go | 2 +- core/coreapi/unixfs.go | 2 +- core/corehttp/gateway_handler.go | 2 +- core/corehttp/gateway_handler_tar.go | 2 +- core/corehttp/gateway_handler_unixfs.go | 2 +- .../gateway_handler_unixfs__redirects.go | 2 +- core/corehttp/gateway_handler_unixfs_dir.go | 2 +- core/corehttp/gateway_handler_unixfs_file.go | 2 +- core/corehttp/gateway_test.go | 2 +- core/corehttp/hostname_test.go | 2 +- core/coreunix/add.go | 2 +- core/coreunix/add_test.go | 2 +- docs/examples/kubo-as-a-library/go.mod | 13 ++++--- docs/examples/kubo-as-a-library/go.sum | 26 +++++++------- docs/examples/kubo-as-a-library/main.go | 2 +- fuse/readonly/ipfs_test.go | 2 +- go.mod | 17 +++++---- go.sum | 35 +++++++++---------- .../migrations/ipfsfetcher/ipfsfetcher.go | 2 +- test/integration/addcat_test.go | 2 +- test/integration/bench_cat_test.go | 2 +- test/integration/three_legged_cat_test.go | 2 +- 35 files changed, 75 insertions(+), 82 deletions(-) diff --git a/assets/assets.go b/assets/assets.go index cf3418cb0..37cbbfad5 100644 --- a/assets/assets.go +++ b/assets/assets.go @@ -14,7 +14,7 @@ import ( "github.com/cespare/xxhash" cid "github.com/ipfs/go-cid" - files "github.com/ipfs/go-ipfs-files" + "github.com/ipfs/go-libipfs/files" options "github.com/ipfs/interface-go-ipfs-core/options" "github.com/ipfs/interface-go-ipfs-core/path" ) diff --git a/cmd/ipfs/add_migrations.go b/cmd/ipfs/add_migrations.go index 6d62b4d6b..50ea9ad1c 100644 --- a/cmd/ipfs/add_migrations.go +++ b/cmd/ipfs/add_migrations.go @@ -8,7 +8,7 @@ import ( "os" "path/filepath" - files "github.com/ipfs/go-ipfs-files" + "github.com/ipfs/go-libipfs/files" coreiface "github.com/ipfs/interface-go-ipfs-core" "github.com/ipfs/interface-go-ipfs-core/options" ipath "github.com/ipfs/interface-go-ipfs-core/path" diff --git a/cmd/ipfs/init.go b/cmd/ipfs/init.go index 745ceb3e2..4232cc262 100644 --- a/cmd/ipfs/init.go +++ b/cmd/ipfs/init.go @@ -19,7 +19,7 @@ import ( fsrepo "github.com/ipfs/kubo/repo/fsrepo" cmds "github.com/ipfs/go-ipfs-cmds" - files "github.com/ipfs/go-ipfs-files" + "github.com/ipfs/go-libipfs/files" options "github.com/ipfs/interface-go-ipfs-core/options" config "github.com/ipfs/kubo/config" ) diff --git a/cmd/ipfswatch/main.go b/cmd/ipfswatch/main.go index d555f14b9..06215687c 100644 --- a/cmd/ipfswatch/main.go +++ b/cmd/ipfswatch/main.go @@ -19,7 +19,7 @@ import ( fsrepo "github.com/ipfs/kubo/repo/fsrepo" fsnotify "github.com/fsnotify/fsnotify" - files "github.com/ipfs/go-ipfs-files" + "github.com/ipfs/go-libipfs/files" process "github.com/jbenet/goprocess" homedir "github.com/mitchellh/go-homedir" ) diff --git a/core/commands/add.go b/core/commands/add.go index 9f686e14b..7afe10f1e 100644 --- a/core/commands/add.go +++ b/core/commands/add.go @@ -12,8 +12,8 @@ import ( "github.com/cheggaaa/pb" cmds "github.com/ipfs/go-ipfs-cmds" - files "github.com/ipfs/go-ipfs-files" ipld "github.com/ipfs/go-ipld-format" + "github.com/ipfs/go-libipfs/files" mfs "github.com/ipfs/go-mfs" coreiface "github.com/ipfs/interface-go-ipfs-core" "github.com/ipfs/interface-go-ipfs-core/options" diff --git a/core/commands/block.go b/core/commands/block.go index b0591b002..c8001b49c 100644 --- a/core/commands/block.go +++ b/core/commands/block.go @@ -6,7 +6,7 @@ import ( "io" "os" - files "github.com/ipfs/go-ipfs-files" + "github.com/ipfs/go-libipfs/files" cmdenv "github.com/ipfs/kubo/core/commands/cmdenv" "github.com/ipfs/kubo/core/commands/cmdutils" diff --git a/core/commands/cat.go b/core/commands/cat.go index 151ac126e..c80bacf02 100644 --- a/core/commands/cat.go +++ b/core/commands/cat.go @@ -9,9 +9,9 @@ import ( "github.com/ipfs/kubo/core/commands/cmdenv" "github.com/cheggaaa/pb" - "github.com/ipfs/go-ipfs-cmds" - "github.com/ipfs/go-ipfs-files" - "github.com/ipfs/interface-go-ipfs-core" + cmds "github.com/ipfs/go-ipfs-cmds" + "github.com/ipfs/go-libipfs/files" + iface "github.com/ipfs/interface-go-ipfs-core" "github.com/ipfs/interface-go-ipfs-core/path" ) diff --git a/core/commands/cmdenv/file.go b/core/commands/cmdenv/file.go index 50ce748eb..43c12abc4 100644 --- a/core/commands/cmdenv/file.go +++ b/core/commands/cmdenv/file.go @@ -3,7 +3,7 @@ package cmdenv import ( "fmt" - files "github.com/ipfs/go-ipfs-files" + "github.com/ipfs/go-libipfs/files" ) // GetFileArg returns the next file from the directory or an error diff --git a/core/commands/dag/import.go b/core/commands/dag/import.go index 87daaae11..c9f0ebbde 100644 --- a/core/commands/dag/import.go +++ b/core/commands/dag/import.go @@ -6,9 +6,9 @@ import ( "io" cid "github.com/ipfs/go-cid" - files "github.com/ipfs/go-ipfs-files" ipld "github.com/ipfs/go-ipld-format" ipldlegacy "github.com/ipfs/go-ipld-legacy" + "github.com/ipfs/go-libipfs/files" iface "github.com/ipfs/interface-go-ipfs-core" "github.com/ipfs/interface-go-ipfs-core/options" "github.com/ipfs/kubo/core/commands/cmdenv" diff --git a/core/commands/dag/put.go b/core/commands/dag/put.go index d8dbaa3f1..ed00c5bee 100644 --- a/core/commands/dag/put.go +++ b/core/commands/dag/put.go @@ -13,8 +13,8 @@ import ( basicnode "github.com/ipld/go-ipld-prime/node/basic" cmds "github.com/ipfs/go-ipfs-cmds" - files "github.com/ipfs/go-ipfs-files" ipld "github.com/ipfs/go-ipld-format" + "github.com/ipfs/go-libipfs/files" mc "github.com/multiformats/go-multicodec" // Expected minimal set of available format/ienc codecs. diff --git a/core/commands/get.go b/core/commands/get.go index 7e915ea29..e5648b28f 100644 --- a/core/commands/get.go +++ b/core/commands/get.go @@ -16,7 +16,7 @@ import ( "github.com/cheggaaa/pb" cmds "github.com/ipfs/go-ipfs-cmds" - files "github.com/ipfs/go-ipfs-files" + "github.com/ipfs/go-libipfs/files" "github.com/ipfs/go-libipfs/tar" "github.com/ipfs/interface-go-ipfs-core/path" ) diff --git a/core/commands/swarm.go b/core/commands/swarm.go index d06f74579..d00291f78 100644 --- a/core/commands/swarm.go +++ b/core/commands/swarm.go @@ -12,7 +12,7 @@ import ( "sync" "time" - files "github.com/ipfs/go-ipfs-files" + "github.com/ipfs/go-libipfs/files" "github.com/ipfs/kubo/commands" "github.com/ipfs/kubo/config" "github.com/ipfs/kubo/core/commands/cmdenv" diff --git a/core/commands/urlstore.go b/core/commands/urlstore.go index bd67c56ff..b17dc713a 100644 --- a/core/commands/urlstore.go +++ b/core/commands/urlstore.go @@ -9,7 +9,7 @@ import ( cmdenv "github.com/ipfs/kubo/core/commands/cmdenv" cmds "github.com/ipfs/go-ipfs-cmds" - files "github.com/ipfs/go-ipfs-files" + "github.com/ipfs/go-libipfs/files" "github.com/ipfs/interface-go-ipfs-core/options" ) diff --git a/core/coreapi/test/path_test.go b/core/coreapi/test/path_test.go index bf26b39ce..acba1c47f 100644 --- a/core/coreapi/test/path_test.go +++ b/core/coreapi/test/path_test.go @@ -6,7 +6,7 @@ import ( "testing" "time" - files "github.com/ipfs/go-ipfs-files" + "github.com/ipfs/go-libipfs/files" "github.com/ipfs/go-merkledag" uio "github.com/ipfs/go-unixfs/io" "github.com/ipfs/interface-go-ipfs-core/options" diff --git a/core/coreapi/unixfs.go b/core/coreapi/unixfs.go index 753a3d3a0..7ab7d34d6 100644 --- a/core/coreapi/unixfs.go +++ b/core/coreapi/unixfs.go @@ -17,8 +17,8 @@ import ( cidutil "github.com/ipfs/go-cidutil" filestore "github.com/ipfs/go-filestore" bstore "github.com/ipfs/go-ipfs-blockstore" - files "github.com/ipfs/go-ipfs-files" ipld "github.com/ipfs/go-ipld-format" + "github.com/ipfs/go-libipfs/files" merkledag "github.com/ipfs/go-merkledag" dagtest "github.com/ipfs/go-merkledag/test" mfs "github.com/ipfs/go-mfs" diff --git a/core/corehttp/gateway_handler.go b/core/corehttp/gateway_handler.go index 64c388df4..c20f112d7 100644 --- a/core/corehttp/gateway_handler.go +++ b/core/corehttp/gateway_handler.go @@ -17,8 +17,8 @@ import ( "time" cid "github.com/ipfs/go-cid" - files "github.com/ipfs/go-ipfs-files" ipld "github.com/ipfs/go-ipld-format" + "github.com/ipfs/go-libipfs/files" dag "github.com/ipfs/go-merkledag" mfs "github.com/ipfs/go-mfs" path "github.com/ipfs/go-path" diff --git a/core/corehttp/gateway_handler_tar.go b/core/corehttp/gateway_handler_tar.go index 532d88757..14edf4fbf 100644 --- a/core/corehttp/gateway_handler_tar.go +++ b/core/corehttp/gateway_handler_tar.go @@ -6,7 +6,7 @@ import ( "net/http" "time" - files "github.com/ipfs/go-ipfs-files" + "github.com/ipfs/go-libipfs/files" ipath "github.com/ipfs/interface-go-ipfs-core/path" "github.com/ipfs/kubo/tracing" "go.opentelemetry.io/otel/attribute" diff --git a/core/corehttp/gateway_handler_unixfs.go b/core/corehttp/gateway_handler_unixfs.go index 75d51d93a..045c0f81d 100644 --- a/core/corehttp/gateway_handler_unixfs.go +++ b/core/corehttp/gateway_handler_unixfs.go @@ -7,7 +7,7 @@ import ( "net/http" "time" - files "github.com/ipfs/go-ipfs-files" + "github.com/ipfs/go-libipfs/files" ipath "github.com/ipfs/interface-go-ipfs-core/path" "github.com/ipfs/kubo/tracing" "go.opentelemetry.io/otel/attribute" diff --git a/core/corehttp/gateway_handler_unixfs__redirects.go b/core/corehttp/gateway_handler_unixfs__redirects.go index 81cf05731..6906683a6 100644 --- a/core/corehttp/gateway_handler_unixfs__redirects.go +++ b/core/corehttp/gateway_handler_unixfs__redirects.go @@ -8,8 +8,8 @@ import ( "strconv" "strings" - files "github.com/ipfs/go-ipfs-files" redirects "github.com/ipfs/go-ipfs-redirects-file" + "github.com/ipfs/go-libipfs/files" ipath "github.com/ipfs/interface-go-ipfs-core/path" "go.uber.org/zap" ) diff --git a/core/corehttp/gateway_handler_unixfs_dir.go b/core/corehttp/gateway_handler_unixfs_dir.go index 5e90a8a79..03d67e1c0 100644 --- a/core/corehttp/gateway_handler_unixfs_dir.go +++ b/core/corehttp/gateway_handler_unixfs_dir.go @@ -10,7 +10,7 @@ import ( "github.com/dustin/go-humanize" cid "github.com/ipfs/go-cid" - files "github.com/ipfs/go-ipfs-files" + "github.com/ipfs/go-libipfs/files" path "github.com/ipfs/go-path" "github.com/ipfs/go-path/resolver" options "github.com/ipfs/interface-go-ipfs-core/options" diff --git a/core/corehttp/gateway_handler_unixfs_file.go b/core/corehttp/gateway_handler_unixfs_file.go index 9463be1ac..1abdc823e 100644 --- a/core/corehttp/gateway_handler_unixfs_file.go +++ b/core/corehttp/gateway_handler_unixfs_file.go @@ -11,7 +11,7 @@ import ( "time" "github.com/gabriel-vasile/mimetype" - files "github.com/ipfs/go-ipfs-files" + "github.com/ipfs/go-libipfs/files" ipath "github.com/ipfs/interface-go-ipfs-core/path" "github.com/ipfs/kubo/tracing" "go.opentelemetry.io/otel/attribute" diff --git a/core/corehttp/gateway_test.go b/core/corehttp/gateway_test.go index 0d2f07dbe..74723579d 100644 --- a/core/corehttp/gateway_test.go +++ b/core/corehttp/gateway_test.go @@ -19,7 +19,7 @@ import ( datastore "github.com/ipfs/go-datastore" syncds "github.com/ipfs/go-datastore/sync" - files "github.com/ipfs/go-ipfs-files" + "github.com/ipfs/go-libipfs/files" path "github.com/ipfs/go-path" iface "github.com/ipfs/interface-go-ipfs-core" nsopts "github.com/ipfs/interface-go-ipfs-core/options/namesys" diff --git a/core/corehttp/hostname_test.go b/core/corehttp/hostname_test.go index 6f0713528..b4a8b8d16 100644 --- a/core/corehttp/hostname_test.go +++ b/core/corehttp/hostname_test.go @@ -7,7 +7,7 @@ import ( "testing" cid "github.com/ipfs/go-cid" - files "github.com/ipfs/go-ipfs-files" + "github.com/ipfs/go-libipfs/files" path "github.com/ipfs/go-path" config "github.com/ipfs/kubo/config" coreapi "github.com/ipfs/kubo/core/coreapi" diff --git a/core/coreunix/add.go b/core/coreunix/add.go index 16ccbaefa..f895baf73 100644 --- a/core/coreunix/add.go +++ b/core/coreunix/add.go @@ -11,10 +11,10 @@ import ( "github.com/ipfs/go-cid" bstore "github.com/ipfs/go-ipfs-blockstore" chunker "github.com/ipfs/go-ipfs-chunker" - files "github.com/ipfs/go-ipfs-files" pin "github.com/ipfs/go-ipfs-pinner" posinfo "github.com/ipfs/go-ipfs-posinfo" ipld "github.com/ipfs/go-ipld-format" + "github.com/ipfs/go-libipfs/files" logging "github.com/ipfs/go-log" dag "github.com/ipfs/go-merkledag" "github.com/ipfs/go-mfs" diff --git a/core/coreunix/add_test.go b/core/coreunix/add_test.go index 6d5d941f7..1ba1b2f0e 100644 --- a/core/coreunix/add_test.go +++ b/core/coreunix/add_test.go @@ -20,8 +20,8 @@ import ( "github.com/ipfs/go-datastore" syncds "github.com/ipfs/go-datastore/sync" blockstore "github.com/ipfs/go-ipfs-blockstore" - files "github.com/ipfs/go-ipfs-files" pi "github.com/ipfs/go-ipfs-posinfo" + "github.com/ipfs/go-libipfs/files" dag "github.com/ipfs/go-merkledag" coreiface "github.com/ipfs/interface-go-ipfs-core" config "github.com/ipfs/kubo/config" diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 7285936d6..040cec571 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,8 +7,8 @@ go 1.18 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/go-ipfs-files v0.2.0 - github.com/ipfs/interface-go-ipfs-core v0.8.1 + github.com/ipfs/go-libipfs v0.1.0 + github.com/ipfs/interface-go-ipfs-core v0.8.2 github.com/ipfs/kubo v0.14.0-rc1 github.com/libp2p/go-libp2p v0.24.2 github.com/multiformats/go-multiaddr v0.8.0 @@ -77,7 +77,7 @@ require ( github.com/ipfs/go-fetcher v1.6.1 // indirect github.com/ipfs/go-filestore v1.2.0 // indirect github.com/ipfs/go-fs-lock v0.0.7 // indirect - github.com/ipfs/go-graphsync v0.14.1-0.20221120210616-975d7aaeb15b // indirect + github.com/ipfs/go-graphsync v0.14.1 // indirect github.com/ipfs/go-ipfs-blockstore v1.2.0 // indirect github.com/ipfs/go-ipfs-chunker v0.0.5 // indirect github.com/ipfs/go-ipfs-delay v0.0.1 // indirect @@ -96,7 +96,6 @@ require ( github.com/ipfs/go-ipld-git v0.1.1 // indirect github.com/ipfs/go-ipld-legacy v0.1.1 // indirect github.com/ipfs/go-ipns v0.3.0 // indirect - github.com/ipfs/go-libipfs v0.0.0-20221208220359-356ce09dd4a1 // indirect github.com/ipfs/go-log v1.0.5 // indirect github.com/ipfs/go-log/v2 v2.5.1 // indirect github.com/ipfs/go-merkledag v0.8.1 // indirect @@ -105,11 +104,11 @@ require ( github.com/ipfs/go-namesys v0.6.0 // indirect github.com/ipfs/go-path v0.3.0 // indirect github.com/ipfs/go-peertaskqueue v0.8.0 // indirect - github.com/ipfs/go-unixfs v0.4.1 // indirect + github.com/ipfs/go-unixfs v0.4.2 // indirect github.com/ipfs/go-unixfsnode v1.4.0 // indirect github.com/ipfs/go-verifcid v0.0.2 // indirect github.com/ipld/edelweiss v0.2.0 // indirect - github.com/ipld/go-codec-dagpb v1.4.1 // indirect + github.com/ipld/go-codec-dagpb v1.5.0 // indirect github.com/ipld/go-ipld-prime v0.19.0 // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect @@ -206,7 +205,7 @@ require ( golang.org/x/mod v0.7.0 // indirect golang.org/x/net v0.3.0 // indirect golang.org/x/sync v0.1.0 // indirect - golang.org/x/sys v0.3.0 // indirect + golang.org/x/sys v0.4.0 // indirect golang.org/x/text v0.5.0 // indirect golang.org/x/tools v0.3.0 // indirect golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 45176636f..b35804386 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -486,8 +486,8 @@ github.com/ipfs/go-filestore v1.2.0 h1:O2wg7wdibwxkEDcl7xkuQsPvJFRBVgVSsOJ/GP6z3 github.com/ipfs/go-filestore v1.2.0/go.mod h1:HLJrCxRXquTeEEpde4lTLMaE/MYJZD7WHLkp9z6+FF8= github.com/ipfs/go-fs-lock v0.0.7 h1:6BR3dajORFrFTkb5EpCUFIAypsoxpGpDSVUdFwzgL9U= github.com/ipfs/go-fs-lock v0.0.7/go.mod h1:Js8ka+FNYmgQRLrRXzU3CB/+Csr1BwrRilEcvYrHhhc= -github.com/ipfs/go-graphsync v0.14.1-0.20221120210616-975d7aaeb15b h1:h+U91xq+a2jQh4oI0ZvxnaJ7s+6VAI8yyQE9jXEiSD0= -github.com/ipfs/go-graphsync v0.14.1-0.20221120210616-975d7aaeb15b/go.mod h1:Esdasda7sNmIlauOhqBG+J4yw60sE3EUftEpuOGX9to= +github.com/ipfs/go-graphsync v0.14.1 h1:tvFpBY9LcehIB7zi5SZIa+7aoxBOrGbdekhOXdnlT70= +github.com/ipfs/go-graphsync v0.14.1/go.mod h1:S6O/c5iXOXqDgrQgiZSgOTRUSiVvpKEhrzqFHKnLVcs= github.com/ipfs/go-ipfs-blockstore v0.0.1/go.mod h1:d3WClOmRQKFnJ0Jz/jj/zmksX0ma1gROTlovZKBmN08= github.com/ipfs/go-ipfs-blockstore v0.1.0/go.mod h1:5aD0AvHPi7mZc6Ci1WCAhiBQu2IsfTduLl+422H6Rqw= github.com/ipfs/go-ipfs-blockstore v0.2.1/go.mod h1:jGesd8EtCM3/zPgx+qr0/feTXGUeRai6adgwC+Q+JvE= @@ -516,8 +516,6 @@ github.com/ipfs/go-ipfs-exchange-offline v0.2.0/go.mod h1:HjwBeW0dvZvfOMwDP0TSKX github.com/ipfs/go-ipfs-exchange-offline v0.3.0 h1:c/Dg8GDPzixGd0MC8Jh6mjOwU57uYokgWRFidfvEkuA= github.com/ipfs/go-ipfs-exchange-offline v0.3.0/go.mod h1:MOdJ9DChbb5u37M1IcbrRB02e++Z7521fMxqCNRrz9s= github.com/ipfs/go-ipfs-files v0.0.3/go.mod h1:INEFm0LL2LWXBhNJ2PMIIb2w45hpXgPjNoE7yA8Y1d4= -github.com/ipfs/go-ipfs-files v0.2.0 h1:z6MCYHQSZpDWpUSK59Kf0ajP1fi4gLCf6fIulVsp8A8= -github.com/ipfs/go-ipfs-files v0.2.0/go.mod h1:vT7uaQfIsprKktzbTPLnIsd+NGw9ZbYwSq0g3N74u0M= github.com/ipfs/go-ipfs-keystore v0.1.0 h1:gfuQUO/cyGZgZIHE6OrJas4OnwuxXCqJG7tI0lrB5Qc= github.com/ipfs/go-ipfs-keystore v0.1.0/go.mod h1:LvLw7Qhnb0RlMOfCzK6OmyWxICip6lQ06CCmdbee75U= github.com/ipfs/go-ipfs-pinner v0.2.1 h1:kw9hiqh2p8TatILYZ3WAfQQABby7SQARdrdA+5Z5QfY= @@ -553,8 +551,8 @@ github.com/ipfs/go-ipld-legacy v0.1.1 h1:BvD8PEuqwBHLTKqlGFTHSwrwFOMkVESEvwIYwR2 github.com/ipfs/go-ipld-legacy v0.1.1/go.mod h1:8AyKFCjgRPsQFf15ZQgDB8Din4DML/fOmKZkkFkrIEg= github.com/ipfs/go-ipns v0.3.0 h1:ai791nTgVo+zTuq2bLvEGmWP1M0A6kGTXUsgv/Yq67A= github.com/ipfs/go-ipns v0.3.0/go.mod h1:3cLT2rbvgPZGkHJoPO1YMJeh6LtkxopCkKFcio/wE24= -github.com/ipfs/go-libipfs v0.0.0-20221208220359-356ce09dd4a1 h1:p/eMmtJfOliZh/SCVv239Wxj2lCo5IN4j5bdNmeGueM= -github.com/ipfs/go-libipfs v0.0.0-20221208220359-356ce09dd4a1/go.mod h1:blLqyfvHD86wgXMJ8GR4QQWYeg1ZvFHOhX3DT340Nj8= +github.com/ipfs/go-libipfs v0.1.0 h1:I6CrHHp4cIiqsWJPVU3QBH4BZrRWSljS2aAbA3Eg9AY= +github.com/ipfs/go-libipfs v0.1.0/go.mod h1:qX0d9h+wu53PFtCTXxdXVBakd6ZCvGDdkZUKmdLMLx0= github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= github.com/ipfs/go-log v1.0.2/go.mod h1:1MNjMxe0u6xvJZgeqbJ8vdo2TKaGwZ1a0Bpza+sr2Sk= github.com/ipfs/go-log v1.0.3/go.mod h1:OsLySYkwIbiSUR/yBTdv1qPtcE4FW3WPWk/ewz9Ru+A= @@ -590,24 +588,24 @@ github.com/ipfs/go-peertaskqueue v0.8.0 h1:JyNO144tfu9bx6Hpo119zvbEL9iQ760FHOiJY github.com/ipfs/go-peertaskqueue v0.8.0/go.mod h1:cz8hEnnARq4Du5TGqiWKgMr/BOSQ5XOgMOh1K5YYKKM= github.com/ipfs/go-unixfs v0.2.4/go.mod h1:SUdisfUjNoSDzzhGVxvCL9QO/nKdwXdr+gbMUdqcbYw= github.com/ipfs/go-unixfs v0.3.1/go.mod h1:h4qfQYzghiIc8ZNFKiLMFWOTzrWIAtzYQ59W/pCFf1o= -github.com/ipfs/go-unixfs v0.4.1 h1:nmJFKvF+khK03PIWyCxxydD/nkQX315NZDcgvRqMXf0= -github.com/ipfs/go-unixfs v0.4.1/go.mod h1:2SUDFhUSzrcL408B1qpIkJJ5HznnyTzweViPXUAvkNg= +github.com/ipfs/go-unixfs v0.4.2 h1:hdQlsHHK5tek9gC9mjGVua8xyTqC+eopGseCRcbCZNg= +github.com/ipfs/go-unixfs v0.4.2/go.mod h1:L+x6JRlFE0PfyMqeoLYVOKLhn5IeZHvNT7ZI51Y9Qyc= github.com/ipfs/go-unixfsnode v1.1.2/go.mod h1:5dcE2x03pyjHk4JjamXmunTMzz+VUtqvPwZjIEkfV6s= github.com/ipfs/go-unixfsnode v1.4.0 h1:9BUxHBXrbNi8mWHc6j+5C580WJqtVw9uoeEKn4tMhwA= github.com/ipfs/go-unixfsnode v1.4.0/go.mod h1:qc7YFFZ8tABc58p62HnIYbUMwj9chhUuFWmxSokfePo= github.com/ipfs/go-verifcid v0.0.1/go.mod h1:5Hrva5KBeIog4A+UpqlaIU+DEstipcJYQQZc0g37pY0= github.com/ipfs/go-verifcid v0.0.2 h1:XPnUv0XmdH+ZIhLGKg6U2vaPaRDXb9urMyNVCE7uvTs= github.com/ipfs/go-verifcid v0.0.2/go.mod h1:40cD9x1y4OWnFXbLNJYRe7MpNvWlMn3LZAG5Wb4xnPU= -github.com/ipfs/interface-go-ipfs-core v0.8.1 h1:nuFG0YJ429Wd5gtRb3ivlblpknZ5VfDVKZkmOG2TnNQ= -github.com/ipfs/interface-go-ipfs-core v0.8.1/go.mod h1:WYC2H6Mu7aGqhlupi/CVawcs0X1Me4uRvV0rcTlo3zM= +github.com/ipfs/interface-go-ipfs-core v0.8.2 h1:WDeCBnE4MENVOXbtfwwdAPJ2nBBS8PTmhZWWpm24HRM= +github.com/ipfs/interface-go-ipfs-core v0.8.2/go.mod h1:F3EcmDy53GFkF0H3iEJpfJC320fZ/4G60eftnItrrJ0= github.com/ipld/edelweiss v0.2.0 h1:KfAZBP8eeJtrLxLhi7r3N0cBCo7JmwSRhOJp3WSpNjk= github.com/ipld/edelweiss v0.2.0/go.mod h1:FJAzJRCep4iI8FOFlRriN9n0b7OuX3T/S9++NpBDmA4= github.com/ipld/go-car v0.4.0 h1:U6W7F1aKF/OJMHovnOVdst2cpQE5GhmHibQkAixgNcQ= github.com/ipld/go-car/v2 v2.1.1/go.mod h1:+2Yvf0Z3wzkv7NeI69i8tuZ+ft7jyjPYIWZzeVNeFcI= github.com/ipld/go-car/v2 v2.4.0 h1:8jI6/iKlyLqRZzLz31jFWTqKvslaVzFsin305sOuqNQ= github.com/ipld/go-codec-dagpb v1.3.0/go.mod h1:ga4JTU3abYApDC3pZ00BC2RSvC3qfBb9MSJkMLSwnhA= -github.com/ipld/go-codec-dagpb v1.4.1 h1:CUQJaOPRgSZ27OUPgUWtvdvvd2d17/IGGAIMOo4yYp0= -github.com/ipld/go-codec-dagpb v1.4.1/go.mod h1:XdXTO/TUD/ra9RcK/NfmwBfr1JpFxM2uRKaB9oe4LxE= +github.com/ipld/go-codec-dagpb v1.5.0 h1:RspDRdsJpLfgCI0ONhTAnbHdySGD4t+LHSPK4X1+R0k= +github.com/ipld/go-codec-dagpb v1.5.0/go.mod h1:0yRIutEFD8o1DGVqw4RSHh+BUTlJA9XWldxaaWR/o4g= 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.14.0/go.mod h1:9ASQLwUFLptCov6lIYc70GRB4V7UTyLD0IJtrDJe6ZM= @@ -1633,8 +1631,8 @@ golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ= -golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18= +golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= diff --git a/docs/examples/kubo-as-a-library/main.go b/docs/examples/kubo-as-a-library/main.go index 08a80bdef..8bd9f8f9c 100644 --- a/docs/examples/kubo-as-a-library/main.go +++ b/docs/examples/kubo-as-a-library/main.go @@ -11,7 +11,7 @@ import ( "strings" "sync" - files "github.com/ipfs/go-ipfs-files" + "github.com/ipfs/go-libipfs/files" icore "github.com/ipfs/interface-go-ipfs-core" icorepath "github.com/ipfs/interface-go-ipfs-core/path" ma "github.com/multiformats/go-multiaddr" diff --git a/fuse/readonly/ipfs_test.go b/fuse/readonly/ipfs_test.go index 7e79b9cf6..04fc07f73 100644 --- a/fuse/readonly/ipfs_test.go +++ b/fuse/readonly/ipfs_test.go @@ -24,9 +24,9 @@ import ( fstest "bazil.org/fuse/fs/fstestutil" chunker "github.com/ipfs/go-ipfs-chunker" - files "github.com/ipfs/go-ipfs-files" u "github.com/ipfs/go-ipfs-util" ipld "github.com/ipfs/go-ipld-format" + "github.com/ipfs/go-libipfs/files" dag "github.com/ipfs/go-merkledag" importer "github.com/ipfs/go-unixfs/importer" uio "github.com/ipfs/go-unixfs/io" diff --git a/go.mod b/go.mod index 55e770587..238774683 100644 --- a/go.mod +++ b/go.mod @@ -32,13 +32,12 @@ require ( github.com/ipfs/go-fetcher v1.6.1 github.com/ipfs/go-filestore v1.2.0 github.com/ipfs/go-fs-lock v0.0.7 - github.com/ipfs/go-graphsync v0.14.0 + github.com/ipfs/go-graphsync v0.14.1 github.com/ipfs/go-ipfs-blockstore v1.2.0 github.com/ipfs/go-ipfs-chunker v0.0.5 - github.com/ipfs/go-ipfs-cmds v0.8.1 + github.com/ipfs/go-ipfs-cmds v0.8.2 github.com/ipfs/go-ipfs-exchange-interface v0.2.0 github.com/ipfs/go-ipfs-exchange-offline v0.3.0 - github.com/ipfs/go-ipfs-files v0.2.0 github.com/ipfs/go-ipfs-keystore v0.1.0 github.com/ipfs/go-ipfs-pinner v0.2.1 github.com/ipfs/go-ipfs-posinfo v0.0.1 @@ -50,7 +49,7 @@ require ( github.com/ipfs/go-ipld-git v0.1.1 github.com/ipfs/go-ipld-legacy v0.1.1 github.com/ipfs/go-ipns v0.3.0 - github.com/ipfs/go-libipfs v0.0.0-20221208220359-356ce09dd4a1 + github.com/ipfs/go-libipfs v0.1.0 github.com/ipfs/go-log v1.0.5 github.com/ipfs/go-log/v2 v2.5.1 github.com/ipfs/go-merkledag v0.8.1 @@ -60,13 +59,13 @@ require ( github.com/ipfs/go-namesys v0.6.0 github.com/ipfs/go-path v0.3.0 github.com/ipfs/go-pinning-service-http-client v0.1.2 - github.com/ipfs/go-unixfs v0.4.1 + github.com/ipfs/go-unixfs v0.4.2 github.com/ipfs/go-unixfsnode v1.4.0 github.com/ipfs/go-verifcid v0.0.2 - github.com/ipfs/interface-go-ipfs-core v0.8.1 + github.com/ipfs/interface-go-ipfs-core v0.8.2 github.com/ipld/go-car v0.4.0 github.com/ipld/go-car/v2 v2.4.0 - github.com/ipld/go-codec-dagpb v1.4.1 + github.com/ipld/go-codec-dagpb v1.5.0 github.com/ipld/go-ipld-prime v0.19.0 github.com/jbenet/go-random v0.0.0-20190219211222-123a90aedc0c github.com/jbenet/go-temp-err-catcher v0.1.0 @@ -113,7 +112,7 @@ require ( golang.org/x/crypto v0.3.0 golang.org/x/mod v0.7.0 golang.org/x/sync v0.1.0 - golang.org/x/sys v0.3.0 + golang.org/x/sys v0.4.0 ) require ( @@ -236,7 +235,7 @@ require ( golang.org/x/exp v0.0.0-20221205204356-47842c84f3db // indirect golang.org/x/net v0.3.0 // indirect golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b // indirect - golang.org/x/term v0.3.0 // indirect + golang.org/x/term v0.4.0 // indirect golang.org/x/text v0.5.0 // indirect golang.org/x/tools v0.3.0 // indirect golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f // indirect diff --git a/go.sum b/go.sum index 6f75ebb82..605ea36c3 100644 --- a/go.sum +++ b/go.sum @@ -504,8 +504,8 @@ github.com/ipfs/go-filestore v1.2.0 h1:O2wg7wdibwxkEDcl7xkuQsPvJFRBVgVSsOJ/GP6z3 github.com/ipfs/go-filestore v1.2.0/go.mod h1:HLJrCxRXquTeEEpde4lTLMaE/MYJZD7WHLkp9z6+FF8= github.com/ipfs/go-fs-lock v0.0.7 h1:6BR3dajORFrFTkb5EpCUFIAypsoxpGpDSVUdFwzgL9U= github.com/ipfs/go-fs-lock v0.0.7/go.mod h1:Js8ka+FNYmgQRLrRXzU3CB/+Csr1BwrRilEcvYrHhhc= -github.com/ipfs/go-graphsync v0.14.0 h1:f5KYkc8GpwwE1BrjBOWxIkRivXIw7fVqGZlnILpvbSc= -github.com/ipfs/go-graphsync v0.14.0/go.mod h1:1LDVVnNHjit8ddJOtw3Jq9epP792xWFXXL3dJWIBIkM= +github.com/ipfs/go-graphsync v0.14.1 h1:tvFpBY9LcehIB7zi5SZIa+7aoxBOrGbdekhOXdnlT70= +github.com/ipfs/go-graphsync v0.14.1/go.mod h1:S6O/c5iXOXqDgrQgiZSgOTRUSiVvpKEhrzqFHKnLVcs= github.com/ipfs/go-ipfs-blockstore v0.0.1/go.mod h1:d3WClOmRQKFnJ0Jz/jj/zmksX0ma1gROTlovZKBmN08= github.com/ipfs/go-ipfs-blockstore v0.1.0/go.mod h1:5aD0AvHPi7mZc6Ci1WCAhiBQu2IsfTduLl+422H6Rqw= github.com/ipfs/go-ipfs-blockstore v0.2.1/go.mod h1:jGesd8EtCM3/zPgx+qr0/feTXGUeRai6adgwC+Q+JvE= @@ -517,8 +517,8 @@ github.com/ipfs/go-ipfs-blocksutil v0.0.1/go.mod h1:Yq4M86uIOmxmGPUHv/uI7uKqZNtL github.com/ipfs/go-ipfs-chunker v0.0.1/go.mod h1:tWewYK0we3+rMbOh7pPFGDyypCtvGcBFymgY4rSDLAw= github.com/ipfs/go-ipfs-chunker v0.0.5 h1:ojCf7HV/m+uS2vhUGWcogIIxiO5ubl5O57Q7NapWLY8= github.com/ipfs/go-ipfs-chunker v0.0.5/go.mod h1:jhgdF8vxRHycr00k13FM8Y0E+6BoalYeobXmUyTreP8= -github.com/ipfs/go-ipfs-cmds v0.8.1 h1:El661DBWqdqwgz7B9xwKyUpigwqk6BBBHb5B8DfJP00= -github.com/ipfs/go-ipfs-cmds v0.8.1/go.mod h1:y0bflH6m4g6ary4HniYt98UqbrVnRxmRarzeMdLIUn0= +github.com/ipfs/go-ipfs-cmds v0.8.2 h1:WmehvYWkxch8dTw0bdF51R8lqbyl+3H8e6pIACzT/ds= +github.com/ipfs/go-ipfs-cmds v0.8.2/go.mod h1:/b17Davff0E0Wh/hhXsN1Pgxxbkm26k3PV+G4EDiC/s= github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= github.com/ipfs/go-ipfs-delay v0.0.1 h1:r/UXYyRcddO6thwOnhiznIAiSvxMECGgtv35Xs1IeRQ= github.com/ipfs/go-ipfs-delay v0.0.1/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= @@ -536,9 +536,6 @@ github.com/ipfs/go-ipfs-exchange-offline v0.2.0/go.mod h1:HjwBeW0dvZvfOMwDP0TSKX github.com/ipfs/go-ipfs-exchange-offline v0.3.0 h1:c/Dg8GDPzixGd0MC8Jh6mjOwU57uYokgWRFidfvEkuA= github.com/ipfs/go-ipfs-exchange-offline v0.3.0/go.mod h1:MOdJ9DChbb5u37M1IcbrRB02e++Z7521fMxqCNRrz9s= github.com/ipfs/go-ipfs-files v0.0.3/go.mod h1:INEFm0LL2LWXBhNJ2PMIIb2w45hpXgPjNoE7yA8Y1d4= -github.com/ipfs/go-ipfs-files v0.0.8/go.mod h1:wiN/jSG8FKyk7N0WyctKSvq3ljIa2NNTiZB55kpTdOs= -github.com/ipfs/go-ipfs-files v0.2.0 h1:z6MCYHQSZpDWpUSK59Kf0ajP1fi4gLCf6fIulVsp8A8= -github.com/ipfs/go-ipfs-files v0.2.0/go.mod h1:vT7uaQfIsprKktzbTPLnIsd+NGw9ZbYwSq0g3N74u0M= github.com/ipfs/go-ipfs-keystore v0.1.0 h1:gfuQUO/cyGZgZIHE6OrJas4OnwuxXCqJG7tI0lrB5Qc= github.com/ipfs/go-ipfs-keystore v0.1.0/go.mod h1:LvLw7Qhnb0RlMOfCzK6OmyWxICip6lQ06CCmdbee75U= github.com/ipfs/go-ipfs-pinner v0.2.1 h1:kw9hiqh2p8TatILYZ3WAfQQABby7SQARdrdA+5Z5QfY= @@ -576,8 +573,8 @@ github.com/ipfs/go-ipld-legacy v0.1.1 h1:BvD8PEuqwBHLTKqlGFTHSwrwFOMkVESEvwIYwR2 github.com/ipfs/go-ipld-legacy v0.1.1/go.mod h1:8AyKFCjgRPsQFf15ZQgDB8Din4DML/fOmKZkkFkrIEg= github.com/ipfs/go-ipns v0.3.0 h1:ai791nTgVo+zTuq2bLvEGmWP1M0A6kGTXUsgv/Yq67A= github.com/ipfs/go-ipns v0.3.0/go.mod h1:3cLT2rbvgPZGkHJoPO1YMJeh6LtkxopCkKFcio/wE24= -github.com/ipfs/go-libipfs v0.0.0-20221208220359-356ce09dd4a1 h1:p/eMmtJfOliZh/SCVv239Wxj2lCo5IN4j5bdNmeGueM= -github.com/ipfs/go-libipfs v0.0.0-20221208220359-356ce09dd4a1/go.mod h1:blLqyfvHD86wgXMJ8GR4QQWYeg1ZvFHOhX3DT340Nj8= +github.com/ipfs/go-libipfs v0.1.0 h1:I6CrHHp4cIiqsWJPVU3QBH4BZrRWSljS2aAbA3Eg9AY= +github.com/ipfs/go-libipfs v0.1.0/go.mod h1:qX0d9h+wu53PFtCTXxdXVBakd6ZCvGDdkZUKmdLMLx0= github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= github.com/ipfs/go-log v1.0.2/go.mod h1:1MNjMxe0u6xvJZgeqbJ8vdo2TKaGwZ1a0Bpza+sr2Sk= github.com/ipfs/go-log v1.0.3/go.mod h1:OsLySYkwIbiSUR/yBTdv1qPtcE4FW3WPWk/ewz9Ru+A= @@ -617,16 +614,16 @@ github.com/ipfs/go-pinning-service-http-client v0.1.2 h1:jdr7KelhL9gNHTU8jbqPMwI github.com/ipfs/go-pinning-service-http-client v0.1.2/go.mod h1:6wd5mjYhXJTiWU8b4RSWPpWdlzE5/csoXV0dWWMjun4= github.com/ipfs/go-unixfs v0.2.4/go.mod h1:SUdisfUjNoSDzzhGVxvCL9QO/nKdwXdr+gbMUdqcbYw= github.com/ipfs/go-unixfs v0.3.1/go.mod h1:h4qfQYzghiIc8ZNFKiLMFWOTzrWIAtzYQ59W/pCFf1o= -github.com/ipfs/go-unixfs v0.4.1 h1:nmJFKvF+khK03PIWyCxxydD/nkQX315NZDcgvRqMXf0= -github.com/ipfs/go-unixfs v0.4.1/go.mod h1:2SUDFhUSzrcL408B1qpIkJJ5HznnyTzweViPXUAvkNg= +github.com/ipfs/go-unixfs v0.4.2 h1:hdQlsHHK5tek9gC9mjGVua8xyTqC+eopGseCRcbCZNg= +github.com/ipfs/go-unixfs v0.4.2/go.mod h1:L+x6JRlFE0PfyMqeoLYVOKLhn5IeZHvNT7ZI51Y9Qyc= github.com/ipfs/go-unixfsnode v1.1.2/go.mod h1:5dcE2x03pyjHk4JjamXmunTMzz+VUtqvPwZjIEkfV6s= github.com/ipfs/go-unixfsnode v1.4.0 h1:9BUxHBXrbNi8mWHc6j+5C580WJqtVw9uoeEKn4tMhwA= github.com/ipfs/go-unixfsnode v1.4.0/go.mod h1:qc7YFFZ8tABc58p62HnIYbUMwj9chhUuFWmxSokfePo= github.com/ipfs/go-verifcid v0.0.1/go.mod h1:5Hrva5KBeIog4A+UpqlaIU+DEstipcJYQQZc0g37pY0= github.com/ipfs/go-verifcid v0.0.2 h1:XPnUv0XmdH+ZIhLGKg6U2vaPaRDXb9urMyNVCE7uvTs= github.com/ipfs/go-verifcid v0.0.2/go.mod h1:40cD9x1y4OWnFXbLNJYRe7MpNvWlMn3LZAG5Wb4xnPU= -github.com/ipfs/interface-go-ipfs-core v0.8.1 h1:nuFG0YJ429Wd5gtRb3ivlblpknZ5VfDVKZkmOG2TnNQ= -github.com/ipfs/interface-go-ipfs-core v0.8.1/go.mod h1:WYC2H6Mu7aGqhlupi/CVawcs0X1Me4uRvV0rcTlo3zM= +github.com/ipfs/interface-go-ipfs-core v0.8.2 h1:WDeCBnE4MENVOXbtfwwdAPJ2nBBS8PTmhZWWpm24HRM= +github.com/ipfs/interface-go-ipfs-core v0.8.2/go.mod h1:F3EcmDy53GFkF0H3iEJpfJC320fZ/4G60eftnItrrJ0= github.com/ipld/edelweiss v0.2.0 h1:KfAZBP8eeJtrLxLhi7r3N0cBCo7JmwSRhOJp3WSpNjk= github.com/ipld/edelweiss v0.2.0/go.mod h1:FJAzJRCep4iI8FOFlRriN9n0b7OuX3T/S9++NpBDmA4= github.com/ipld/go-car v0.4.0 h1:U6W7F1aKF/OJMHovnOVdst2cpQE5GhmHibQkAixgNcQ= @@ -635,8 +632,8 @@ github.com/ipld/go-car/v2 v2.1.1/go.mod h1:+2Yvf0Z3wzkv7NeI69i8tuZ+ft7jyjPYIWZze github.com/ipld/go-car/v2 v2.4.0 h1:8jI6/iKlyLqRZzLz31jFWTqKvslaVzFsin305sOuqNQ= github.com/ipld/go-car/v2 v2.4.0/go.mod h1:zjpRf0Jew9gHqSvjsKVyoq9OY9SWoEKdYCQUKVaaPT0= github.com/ipld/go-codec-dagpb v1.3.0/go.mod h1:ga4JTU3abYApDC3pZ00BC2RSvC3qfBb9MSJkMLSwnhA= -github.com/ipld/go-codec-dagpb v1.4.1 h1:CUQJaOPRgSZ27OUPgUWtvdvvd2d17/IGGAIMOo4yYp0= -github.com/ipld/go-codec-dagpb v1.4.1/go.mod h1:XdXTO/TUD/ra9RcK/NfmwBfr1JpFxM2uRKaB9oe4LxE= +github.com/ipld/go-codec-dagpb v1.5.0 h1:RspDRdsJpLfgCI0ONhTAnbHdySGD4t+LHSPK4X1+R0k= +github.com/ipld/go-codec-dagpb v1.5.0/go.mod h1:0yRIutEFD8o1DGVqw4RSHh+BUTlJA9XWldxaaWR/o4g= 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.14.0/go.mod h1:9ASQLwUFLptCov6lIYc70GRB4V7UTyLD0IJtrDJe6ZM= @@ -1701,13 +1698,13 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ= -golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18= +golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.3.0 h1:qoo4akIqOcDME5bhc/NgxUdovd6BSS2uMsVjB56q1xI= -golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= +golang.org/x/term v0.4.0 h1:O7UWfv5+A2qiuulQk30kVinPoMtoIPeVaKLEgLpVkvg= +golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/repo/fsrepo/migrations/ipfsfetcher/ipfsfetcher.go b/repo/fsrepo/migrations/ipfsfetcher/ipfsfetcher.go index d13eaf148..52cd354d3 100644 --- a/repo/fsrepo/migrations/ipfsfetcher/ipfsfetcher.go +++ b/repo/fsrepo/migrations/ipfsfetcher/ipfsfetcher.go @@ -11,7 +11,7 @@ import ( "strings" "sync" - files "github.com/ipfs/go-ipfs-files" + "github.com/ipfs/go-libipfs/files" iface "github.com/ipfs/interface-go-ipfs-core" "github.com/ipfs/interface-go-ipfs-core/options" ipath "github.com/ipfs/interface-go-ipfs-core/path" diff --git a/test/integration/addcat_test.go b/test/integration/addcat_test.go index 45e8729ac..6f306d2bf 100644 --- a/test/integration/addcat_test.go +++ b/test/integration/addcat_test.go @@ -11,7 +11,7 @@ import ( "testing" "time" - files "github.com/ipfs/go-ipfs-files" + "github.com/ipfs/go-libipfs/files" logging "github.com/ipfs/go-log" "github.com/ipfs/kubo/core" "github.com/ipfs/kubo/core/bootstrap" diff --git a/test/integration/bench_cat_test.go b/test/integration/bench_cat_test.go index d7e37dbb9..12c4d8dea 100644 --- a/test/integration/bench_cat_test.go +++ b/test/integration/bench_cat_test.go @@ -8,7 +8,7 @@ import ( "math" "testing" - files "github.com/ipfs/go-ipfs-files" + "github.com/ipfs/go-libipfs/files" "github.com/ipfs/kubo/core" "github.com/ipfs/kubo/core/bootstrap" "github.com/ipfs/kubo/core/coreapi" diff --git a/test/integration/three_legged_cat_test.go b/test/integration/three_legged_cat_test.go index f0358272b..c788bfb5e 100644 --- a/test/integration/three_legged_cat_test.go +++ b/test/integration/three_legged_cat_test.go @@ -14,7 +14,7 @@ import ( mock "github.com/ipfs/kubo/core/mock" "github.com/ipfs/kubo/thirdparty/unit" - files "github.com/ipfs/go-ipfs-files" + "github.com/ipfs/go-libipfs/files" testutil "github.com/libp2p/go-libp2p-testing/net" "github.com/libp2p/go-libp2p/core/peer" mocknet "github.com/libp2p/go-libp2p/p2p/net/mock" From d889a0767191b08c932a47acabc43231ed73b4a3 Mon Sep 17 00:00:00 2001 From: Piotr Galar Date: Sat, 14 Jan 2023 00:49:52 +0100 Subject: [PATCH 0407/1212] test: port CircleCI to GH Actions and improve sharness reporting (#9355) Closes https://github.com/ipfs/kubo/issues/8991 Part of https://github.com/ipfs/kubo/issues/8804 --- .circleci/config.yml | 2 +- .circleci/main.yml | 17 +- .github/workflows/build.yml | 200 ++++++++++++++ .github/workflows/codeql-analysis.yml | 2 +- .github/workflows/docker-build.yml | 25 ++ .github/workflows/docker-image.yml | 2 +- .github/workflows/gobuild.yml | 39 +++ .github/workflows/golang-analysis.yml | 9 +- .github/workflows/golint.yml | 32 +++ .github/workflows/gotest.yml | 65 +++++ .github/workflows/runner.yml | 33 +++ .github/workflows/sharness.yml | 124 +++++++++ Rules.mk | 3 +- appveyor.yml | 18 +- codecov.yml | 1 + coverage/Rules.mk | 2 +- test/sharness/.gitignore | 9 + test/sharness/README.md | 2 +- test/sharness/Rules.mk | 28 +- .../0001-Generate-partial-JUnit-reports.patch | 250 ------------------ test/sharness/lib/gen-junit-report.sh | 8 - test/sharness/lib/install-sharness.sh | 72 +++-- .../lib/test-aggregate-junit-reports.sh | 17 ++ test/sharness/lib/test-generate-junit-html.sh | 58 ++++ test/sharness/lib/test-lib.sh | 17 +- test/sharness/t0110-gateway.sh | 4 +- test/sharness/t0118-gateway-car.sh | 2 +- test/sharness/t0125-twonode.sh | 6 + test/sharness/t0160-resolve.sh | 42 +-- test/sharness/t0300-docker-image.sh | 7 +- 30 files changed, 712 insertions(+), 384 deletions(-) create mode 100644 .github/workflows/build.yml create mode 100644 .github/workflows/docker-build.yml create mode 100644 .github/workflows/gobuild.yml create mode 100644 .github/workflows/golint.yml create mode 100644 .github/workflows/gotest.yml create mode 100644 .github/workflows/runner.yml create mode 100644 .github/workflows/sharness.yml delete mode 100644 test/sharness/lib/0001-Generate-partial-JUnit-reports.patch delete mode 100755 test/sharness/lib/gen-junit-report.sh create mode 100755 test/sharness/lib/test-aggregate-junit-reports.sh create mode 100755 test/sharness/lib/test-generate-junit-html.sh diff --git a/.circleci/config.yml b/.circleci/config.yml index a40a162aa..3da57d246 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -7,7 +7,7 @@ jobs: executor: continuation/default steps: - checkout - - run: + - run: name: Generate params # for builds on the ipfs/kubo repo, use 2xlarge for faster builds # but since this is not available for many contributors, we otherwise use medium diff --git a/.circleci/main.yml b/.circleci/main.yml index 08e176656..6406c6655 100644 --- a/.circleci/main.yml +++ b/.circleci/main.yml @@ -143,14 +143,17 @@ jobs: path: /tmp/circleci-test-results sharness: machine: - image: ubuntu-2004:202010-01 + image: ubuntu-2204:2022.10.1 resource_class: << pipeline.parameters.resource_class >> working_directory: ~/ipfs/kubo environment: <<: *default_environment TEST_NO_DOCKER: 0 + TEST_NO_PLUGIN: 1 TEST_NO_FUSE: 1 TEST_VERBOSE: 1 + TEST_JUNIT: 1 + TEST_EXPENSIVE: 1 steps: - run: sudo apt update - run: | @@ -159,7 +162,7 @@ jobs: tar xfz go1.19.1.linux-amd64.tar.gz echo "export PATH=$(pwd)/go/bin:\$PATH" >> ~/.bashrc - run: go version - - run: sudo apt install socat net-tools fish + - run: sudo apt install socat net-tools fish libxml2-utils - checkout - run: @@ -183,7 +186,7 @@ jobs: command: echo "export TEST_DOCKER_HOST=$(ip -4 addr show docker0 | grep -Po 'inet \K[\d.]+')" >> $BASH_ENV - run: echo TEST_DOCKER_HOST=$TEST_DOCKER_HOST && - make -O -j << pipeline.parameters.make_jobs >> coverage/sharness_tests.coverprofile test/sharness/test-results/sharness.xml TEST_GENERATE_JUNIT=1 CONTINUE_ON_S_FAILURE=1 TEST_DOCKER_HOST=$TEST_DOCKER_HOST + make -O -j << pipeline.parameters.make_jobs >> test_sharness coverage/sharness_tests.coverprofile test/sharness/test-results/sharness.xml CONTINUE_ON_S_FAILURE=1 TEST_DOCKER_HOST=$TEST_DOCKER_HOST - run: when: always command: bash <(curl -s https://codecov.io/bash) -cF sharness -X search -f coverage/sharness_tests.coverprofile @@ -345,13 +348,13 @@ jobs: npx playwright install working_directory: ~/ipfs/kubo/ipfs-webui - run: - name: Running upstream tests (finish early if they fail) + name: Run ipfs-webui@main build and smoke-test to confirm the upstream repo is not broken command: | - npm test || circleci-agent step halt + npm test working_directory: ~/ipfs/kubo/ipfs-webui - run: - name: Running tests with kubo built from current commit - command: npm test + name: Test ipfs-webui@main E2E against the locally built Kubo binary + command: npm run test:e2e working_directory: ~/ipfs/kubo/ipfs-webui environment: IPFS_GO_EXEC: /tmp/circleci-workspace/bin/ipfs diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 000000000..d0b4194b7 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,200 @@ +name: 'ci/gh-experiment: interop' + +on: + workflow_dispatch: + pull_request: + push: + branches: + - 'master' + +env: + GO_VERSION: 1.19.1 + +jobs: + prepare: + if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' + runs-on: ubuntu-latest + env: + TEST_NO_DOCKER: 1 + TEST_NO_FUSE: 1 + TEST_VERBOSE: 1 + TRAVIS: 1 + GIT_PAGER: cat + IPFS_CHECK_RCMGR_DEFAULTS: 1 + defaults: + run: + shell: bash + steps: + - uses: actions/setup-go@v3 + with: + go-version: ${{ env.GO_VERSION }} + - uses: actions/checkout@v3 + - uses: protocol/cache-go-action@v1 + with: + name: ${{ github.job }} + - run: make build + - uses: actions/upload-artifact@v3 + with: + name: kubo + path: cmd/ipfs/ipfs + ipfs-interop: + needs: [prepare] + runs-on: ubuntu-latest + strategy: + matrix: + suites: + - 'exchange-files' + - 'files pin circuit ipns cid-version-agnostic ipns-pubsub pubsub' + fail-fast: false + defaults: + run: + shell: bash + steps: + - uses: actions/setup-node@v3 + with: + node-version: 16.12.0 + - uses: actions/download-artifact@v3 + with: + name: kubo + path: cmd/ipfs + - run: chmod +x cmd/ipfs/ipfs + - run: | + echo "dir=$(npm config get cache)" >> $GITHUB_OUTPUT + id: npm-cache-dir + - uses: actions/cache@v3 + with: + path: ${{ steps.npm-cache-dir.outputs.dir }} + key: ${{ runner.os }}-${{ github.job }}-${{ hashFiles('**/package-lock.json') }} + restore-keys: | + ${{ runner.os }}-${{ github.job }}- + - run: mkdir interop + - run: | + npm init -y + npm install ipfs@^0.61.0 + npm install ipfs-interop@^8.0.10 + working-directory: interop + - run: npx ipfs-interop -- -t node $(sed -e 's#[^ ]*#-f test/&.js#g' <<< '${{ matrix.suites }}') + env: + LIBP2P_TCP_REUSEPORT: false + LIBP2P_ALLOW_WEAK_RSA_KEYS: 1 + IPFS_GO_EXEC: ${{ github.workspace }}/cmd/ipfs/ipfs + working-directory: interop + go-ipfs-api: + needs: [prepare] + runs-on: ubuntu-latest + env: + TEST_NO_DOCKER: 1 + TEST_NO_FUSE: 1 + TEST_VERBOSE: 1 + TRAVIS: 1 + GIT_PAGER: cat + IPFS_CHECK_RCMGR_DEFAULTS: 1 + defaults: + run: + shell: bash + steps: + - uses: actions/setup-go@v3 + with: + go-version: ${{ env.GO_VERSION }} + - uses: actions/download-artifact@v3 + with: + name: kubo + path: cmd/ipfs + - run: chmod +x cmd/ipfs/ipfs + - uses: actions/checkout@v3 + with: + repository: ipfs/go-ipfs-api + path: go-ipfs-api + - run: cmd/ipfs/ipfs daemon --init --enable-namesys-pubsub & + - run: | + while ! cmd/ipfs/ipfs id --api=/ip4/127.0.0.1/tcp/5001 2>/dev/null; do + sleep 1 + done + timeout-minutes: 5 + - uses: protocol/cache-go-action@v1 + with: + name: ${{ github.job }} + - run: go test -count=1 -v ./... + working-directory: go-ipfs-api + - run: cmd/ipfs/ipfs shutdown + if: always() + go-ipfs-http-client: + needs: [prepare] + runs-on: ubuntu-latest + env: + TEST_NO_DOCKER: 1 + TEST_NO_FUSE: 1 + TEST_VERBOSE: 1 + TRAVIS: 1 + GIT_PAGER: cat + IPFS_CHECK_RCMGR_DEFAULTS: 1 + defaults: + run: + shell: bash + steps: + - uses: actions/setup-go@v3 + with: + go-version: ${{ env.GO_VERSION }} + - uses: actions/download-artifact@v3 + with: + name: kubo + path: cmd/ipfs + - run: chmod +x cmd/ipfs/ipfs + - uses: actions/checkout@v3 + with: + repository: ipfs/go-ipfs-http-client + path: go-ipfs-http-client + - uses: protocol/cache-go-action@v1 + with: + name: ${{ github.job }} + - run: echo '${{ github.workspace }}/cmd/ipfs' >> $GITHUB_PATH + - run: go test -count=1 -v ./... + working-directory: go-ipfs-http-client + ipfs-webui: + needs: [prepare] + runs-on: ubuntu-latest + env: + NO_SANDBOX: true + LIBP2P_TCP_REUSEPORT: false + LIBP2P_ALLOW_WEAK_RSA_KEYS: 1 + E2E_IPFSD_TYPE: go + TRAVIS: 1 + GIT_PAGER: cat + IPFS_CHECK_RCMGR_DEFAULTS: 1 + defaults: + run: + shell: bash + steps: + - uses: actions/setup-node@v3 + with: + node-version: 16.12.0 + - uses: actions/download-artifact@v3 + with: + name: kubo + path: cmd/ipfs + - run: chmod +x cmd/ipfs/ipfs + - uses: actions/checkout@v3 + with: + repository: ipfs/ipfs-webui + path: ipfs-webui + - run: | + echo "dir=$(npm config get cache)" >> $GITHUB_OUTPUT + id: npm-cache-dir + - uses: actions/cache@v3 + with: + path: ${{ steps.npm-cache-dir.outputs.dir }} + key: ${{ runner.os }}-${{ github.job }}-${{ hashFiles('**/package-lock.json') }} + restore-keys: | + ${{ runner.os }}-${{ github.job }}- + - run: | + npm ci --prefer-offline --no-audit --progress=false + npx playwright install + working-directory: ipfs-webui + - name: Run ipfs-webui@main build and smoke-test to confirm the upstream repo is not broken + run: npm test + working-directory: ipfs-webui + - name: Test ipfs-webui@main E2E against the locally built Kubo binary + run: npm run test:e2e + env: + IPFS_GO_EXEC: ${{ github.workspace }}/cmd/ipfs/ipfs + working-directory: ipfs-webui diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index af9006adf..e12af6b4e 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -1,5 +1,5 @@ # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed -name: "CodeQL" +name: CodeQL on: workflow_dispatch: diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml new file mode 100644 index 000000000..86c50bec7 --- /dev/null +++ b/.github/workflows/docker-build.yml @@ -0,0 +1,25 @@ +name: 'ci/gh-experiment: docker-build' + +on: + workflow_dispatch: + pull_request: + push: + branches: + - 'master' + +jobs: + docker-build: + if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' + runs-on: ubuntu-latest + env: + IMAGE_NAME: ipfs/kubo + WIP_IMAGE_TAG: wip + defaults: + run: + shell: bash + steps: + - uses: actions/setup-go@v3 + with: + go-version: 1.19.1 + - uses: actions/checkout@v3 + - run: docker build -t $IMAGE_NAME:$WIP_IMAGE_TAG . diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index 76e0c1c11..8a90910f7 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -32,7 +32,7 @@ jobs: run: | TAGS="$(./bin/get-docker-tags.sh $(date -u +%F))" TAGS="${TAGS//$'\n'/'%0A'}" - echo "::set-output name=value::$(echo $TAGS)" + echo "value=$(echo $TAGS)" >> $GITHUB_OUTPUT shell: bash - name: Log in to Docker Hub diff --git a/.github/workflows/gobuild.yml b/.github/workflows/gobuild.yml new file mode 100644 index 000000000..edacc269b --- /dev/null +++ b/.github/workflows/gobuild.yml @@ -0,0 +1,39 @@ +name: 'ci/gh-experiment: go build' + +on: + workflow_dispatch: + pull_request: + push: + branches: + - 'master' + +jobs: + runner: + if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' + uses: ipfs/kubo/.github/workflows/runner.yml@ci/move-to-github-actions # TODO: change to master + gobuild: + needs: [runner] + runs-on: ${{ fromJSON(needs.runner.outputs.config).labels }} + env: + TEST_NO_DOCKER: 1 + TEST_VERBOSE: 1 + TRAVIS: 1 + GIT_PAGER: cat + IPFS_CHECK_RCMGR_DEFAULTS: 1 + defaults: + run: + shell: bash + steps: + - uses: actions/setup-go@v3 + with: + go-version: 1.19.1 + - uses: actions/checkout@v3 + - uses: protocol/cache-go-action@v1 + with: + name: ${{ github.job }} + - run: make cmd/ipfs-try-build + env: + TEST_NO_FUSE: 0 + - run: make cmd/ipfs-try-build + env: + TEST_NO_FUSE: 1 diff --git a/.github/workflows/golang-analysis.yml b/.github/workflows/golang-analysis.yml index 3a74e61a2..958ece668 100644 --- a/.github/workflows/golang-analysis.yml +++ b/.github/workflows/golang-analysis.yml @@ -1,8 +1,15 @@ -on: [push, pull_request] name: Go Checks +on: + workflow_dispatch: + pull_request: + push: + branches: + - 'master' + jobs: unit: + if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' runs-on: ubuntu-latest name: All steps: diff --git a/.github/workflows/golint.yml b/.github/workflows/golint.yml new file mode 100644 index 000000000..9623ae4b6 --- /dev/null +++ b/.github/workflows/golint.yml @@ -0,0 +1,32 @@ +name: 'ci/gh-experiment: go lint' + +on: + workflow_dispatch: + pull_request: + push: + branches: + - 'master' + +jobs: + golint: + if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' + runs-on: ubuntu-latest + env: + TEST_NO_DOCKER: 1 + TEST_NO_FUSE: 1 + TEST_VERBOSE: 1 + TRAVIS: 1 + GIT_PAGER: cat + IPFS_CHECK_RCMGR_DEFAULTS: 1 + defaults: + run: + shell: bash + steps: + - uses: actions/setup-go@v3 + with: + go-version: 1.19.1 + - uses: actions/checkout@v3 + - uses: protocol/cache-go-action@v1 + with: + name: ${{ github.job }} + - run: make -O test_go_lint diff --git a/.github/workflows/gotest.yml b/.github/workflows/gotest.yml new file mode 100644 index 000000000..2c50fd3e5 --- /dev/null +++ b/.github/workflows/gotest.yml @@ -0,0 +1,65 @@ +name: 'ci/gh-experiment: go test' + +on: + workflow_dispatch: + pull_request: + push: + branches: + - 'master' + +jobs: + gotest: + if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' + runs-on: ubuntu-latest + env: + TEST_NO_DOCKER: 1 + TEST_NO_FUSE: 1 + TEST_VERBOSE: 1 + TRAVIS: 1 + GIT_PAGER: cat + IPFS_CHECK_RCMGR_DEFAULTS: 1 + defaults: + run: + shell: bash + steps: + - uses: actions/setup-go@v3 + with: + go-version: 1.19.1 + - uses: actions/checkout@v3 + - uses: protocol/cache-go-action@v1 + with: + name: ${{ github.job }} + - run: | + make -j 1 test/unit/gotest.junit.xml && + [[ ! $(jq -s -c 'map(select(.Action == "fail")) | .[]' test/unit/gotest.json) ]] + - uses: codecov/codecov-action@81cd2dc8148241f03f5839d295e000b8f761e378 # v3.1.0 + if: always() + with: + name: unittests + files: coverage/unit_tests.coverprofile + - run: | + # we want to first test with the kubo version in the go.mod file + go test -v ./... + + # we also want to test the examples against the current version of kubo + # however, that version might be in a fork so we need to replace the dependency + + # backup the go.mod and go.sum files to restore them after we run the tests + cp go.mod go.mod.bak + cp go.sum go.sum.bak + + # make sure the examples run against the current version of kubo + go mod edit -replace github.com/ipfs/kubo=./../../.. + go mod tidy + + go test -v ./... + + # restore the go.mod and go.sum files to their original state + mv go.mod.bak go.mod + mv go.sum.bak go.sum + working-directory: docs/examples/kubo-as-a-library + - uses: actions/upload-artifact@v3 + with: + name: unit + path: test/unit/gotest.junit.xml + if: always() diff --git a/.github/workflows/runner.yml b/.github/workflows/runner.yml new file mode 100644 index 000000000..afb4d740d --- /dev/null +++ b/.github/workflows/runner.yml @@ -0,0 +1,33 @@ +name: 'ci/gh-experiment: choose runner' + +on: + workflow_call: + outputs: + config: + description: "The runner's configuration" + value: ${{ jobs.choose.outputs.config }} + +jobs: + choose: + runs-on: ubuntu-latest + outputs: + config: ${{ steps.config.outputs.result }} + steps: + - uses: actions/github-script@v6 + id: config + with: + script: | + if (`${context.repo.owner}/${context.repo.repo}` === 'ipfs/kubo') { + return { + labels: ['self-hosted', 'linux', 'x64', 'kubo'], + parallel: 10, + aws: true + } + } else { + return { + labels: ['ubuntu-latest'], + parallel: 3, + aws: false + } + } + - run: echo ${{ steps.config.outputs.result }} diff --git a/.github/workflows/sharness.yml b/.github/workflows/sharness.yml new file mode 100644 index 000000000..044e55560 --- /dev/null +++ b/.github/workflows/sharness.yml @@ -0,0 +1,124 @@ +name: 'ci/gh-experiment: sharness' + +on: + workflow_dispatch: + pull_request: + push: + branches: + - 'master' + +jobs: + runner: + if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' + uses: ipfs/kubo/.github/workflows/runner.yml@ci/move-to-github-actions # TODO: change to master + sharness: + needs: [runner] + runs-on: ${{ fromJSON(needs.runner.outputs.config).labels }} + defaults: + run: + shell: bash + steps: + - name: Setup Go + uses: actions/setup-go@v3 + with: + go-version: 1.19.1 + - name: Checkout Kubo + uses: actions/checkout@v3 + with: + path: kubo + - name: Install missing tools + run: sudo apt install -y socat net-tools fish libxml2-utils + - name: Checkout IPFS Pinning Service API + uses: actions/checkout@v3 + with: + repository: ipfs-shipyard/rb-pinning-service-api + ref: 773c3adbb421c551d2d89288abac3e01e1f7c3a8 + path: rb-pinning-service-api + # TODO: check if docker compose (not docker-compose) is available on default gh runners + - name: Start IPFS Pinning Service API + run: | + (for i in {1..3}; do docker compose pull && break || sleep 5; done) && + docker compose up -d + working-directory: rb-pinning-service-api + - name: Restore Go Cache + uses: protocol/cache-go-action@v1 + with: + name: ${{ github.job }} + - name: Find IPFS Pinning Service API address + run: echo "TEST_DOCKER_HOST=$(ip -4 addr show docker0 | grep -Po 'inet \K[\d.]+')" >> $GITHUB_ENV + - uses: actions/cache@v3 + with: + path: test/sharness/lib/dependencies + key: ${{ runner.os }}-test-generate-junit-html-${{ hashFiles('test/sharness/lib/test-generate-junit-html.sh') }} + - name: Run Sharness tests + run: | + make -O -j "$PARALLEL" \ + test_sharness \ + coverage/sharness_tests.coverprofile \ + test/sharness/test-results/sharness.xml \ + test/sharness/test-results/sharness.html \ + test/sharness/test-results/sharness-html + working-directory: kubo + env: + TEST_NO_DOCKER: 0 + TEST_NO_PLUGIN: 1 + TEST_NO_FUSE: 1 + TEST_VERBOSE: 1 + TEST_JUNIT: 1 + TEST_EXPENSIVE: 1 + IPFS_CHECK_RCMGR_DEFAULTS: 1 + CONTINUE_ON_S_FAILURE: 1 + PARALLEL: ${{ fromJSON(needs.runner.outputs.config).parallel }} + - name: Upload coverage report + uses: codecov/codecov-action@81cd2dc8148241f03f5839d295e000b8f761e378 # v3.1.0 + if: failure() || success() + with: + name: sharness + files: kubo/coverage/sharness_tests.coverprofile + - name: Aggregate results + run: find kubo/test/sharness/test-results -name 't*-*.sh.*.counts' | kubo/test/sharness/lib/sharness/aggregate-results.sh > kubo/test/sharness/test-results/summary.txt + - name: 👉️ If this step failed, go to «Summary» (top left) → «HTML Report» → inspect the «Failures» column + run: | + cat kubo/test/sharness/test-results/summary.txt && + grep 'failed\s*0' kubo/test/sharness/test-results/summary.txt + - name: Add aggregate results to the summary + if: failure() || success() + run: | + echo "# Summary" >> $GITHUB_STEP_SUMMARY + echo >> $GITHUB_STEP_SUMMARY + cat kubo/test/sharness/test-results/summary.txt >> $GITHUB_STEP_SUMMARY + - name: Upload one-page HTML report to S3 + id: one-page + uses: pl-strflt/tf-aws-gh-runner/.github/actions/upload-artifact@main + if: fromJSON(needs.runner.outputs.config).aws && (failure() || success()) + with: + source: kubo/test/sharness/test-results/sharness.html + destination: sharness.html + - name: Upload one-page HTML report + if: (! fromJSON(needs.runner.outputs.config).aws) && (failure() || success()) + uses: actions/upload-artifact@v3 + with: + name: sharness.html + path: kubo/test/sharness/test-results/sharness.html + - name: Upload full HTML report to S3 + id: full + uses: pl-strflt/tf-aws-gh-runner/.github/actions/upload-artifact@main + if: fromJSON(needs.runner.outputs.config).aws && (failure() || success()) + with: + source: kubo/test/sharness/test-results/sharness-html + destination: sharness-html/ + - name: Upload full HTML report + if: (! fromJSON(needs.runner.outputs.config).aws) && (failure() || success()) + uses: actions/upload-artifact@v3 + with: + name: sharness-html + path: kubo/test/sharness/test-results/sharness-html + - name: Add S3 links to the summary + if: fromJSON(needs.runner.outputs.config).aws && (failure() || success()) + run: echo "$MD" >> $GITHUB_STEP_SUMMARY + env: + MD: | + # HTML Reports + + - View the [one page HTML report](${{ steps.one-page.outputs.url }}) + - View the [full HTML report](${{ steps.full.outputs.url }}index.html) diff --git a/Rules.mk b/Rules.mk index 3d6f621cc..f7e962549 100644 --- a/Rules.mk +++ b/Rules.mk @@ -136,8 +136,7 @@ help: @echo ' test_go_expensive - Run all go tests and compile on all platforms' @echo ' test_go_race - Run go tests with the race detector enabled' @echo ' test_go_lint - Run the `golangci-lint` vetting tool' - @echo ' test_sharness_short - Run short sharness tests' - @echo ' test_sharness_expensive - Run all sharness tests' + @echo ' test_sharness - Run sharness tests' @echo ' coverage - Collects coverage info from unit tests and sharness' @echo .PHONY: help diff --git a/appveyor.yml b/appveyor.yml index 696102ffc..5f2907d00 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -14,8 +14,8 @@ environment: GOPATH: c:\gopath TEST_VERBOSE: 1 #TEST_NO_FUSE: 1 - #TEST_SUITE: test_sharness_expensive - #GOFLAGS: -tags nofuse + #TEST_SUITE: test_sharness + #GOFLAGS: -tags nofuse global: BASH: C:\cygwin\bin\bash matrix: @@ -23,27 +23,27 @@ environment: GOVERSION: 1.5.1 GOROOT: c:\go DOWNLOADPLATFORM: "x64" - + install: # Enable make #- SET PATH=c:\MinGW\bin;%PATH% #- copy c:\MinGW\bin\mingw32-make.exe c:\MinGW\bin\make.exe - go version - go env - + # Cygwin build script # # NOTES: # # The stdin/stdout file descriptor appears not to be valid for the Appveyor -# build which causes failures as certain functions attempt to redirect +# build which causes failures as certain functions attempt to redirect # default file handles. Ensure a dummy file descriptor is opened with 'exec'. -# +# build_script: - '%BASH% -lc "cd $APPVEYOR_BUILD_FOLDER; exec 0 $@ diff --git a/test/sharness/.gitignore b/test/sharness/.gitignore index c7ab08146..b9a5a21ae 100644 --- a/test/sharness/.gitignore +++ b/test/sharness/.gitignore @@ -1,5 +1,14 @@ +# symlinks to lib/sharness +/sharness.sh +/lib-sharness +# clone of sharness lib/sharness/ +# deps downloaded by lib/*.sh scripts +lib/dependencies/ +# sharness files test-results/ trash directory.*.sh/ +# makefile files plugins +# macos files *.DS_Store diff --git a/test/sharness/README.md b/test/sharness/README.md index 16cb508c1..9358fcf9c 100644 --- a/test/sharness/README.md +++ b/test/sharness/README.md @@ -1,4 +1,4 @@ -# ipfs whole tests using the [sharness framework](https://github.com/mlafeldt/sharness/) +# ipfs whole tests using the [sharness framework](https://github.com/pl-strflt/sharness/tree/feat/junit) ## Running all the tests diff --git a/test/sharness/Rules.mk b/test/sharness/Rules.mk index 49e41824c..3b7708b60 100644 --- a/test/sharness/Rules.mk +++ b/test/sharness/Rules.mk @@ -42,10 +42,20 @@ $(d)/aggregate: $(T_$(d)) @(cd $(@D) && ./lib/test-aggregate-results.sh) .PHONY: $(d)/aggregate -$(d)/test-results/sharness.xml: export TEST_GENERATE_JUNIT=1 -$(d)/test-results/sharness.xml: test_sharness_expensive +$(d)/test-results/sharness.xml: $(T_$(d)) @echo "*** $@ ***" - @(cd $(@D)/.. && ./lib/gen-junit-report.sh) + @(cd $(@D)/.. && ./lib/test-aggregate-junit-reports.sh) +.PHONY: $(d)/test-results/sharness.xml + +$(d)/test-results/sharness-html: $(d)/test-results/sharness.xml + @echo "*** $@ ***" + @(cd $(@D)/.. && ./lib/test-generate-junit-html.sh frames) +.PHONY: $(d)/test-results/sharness-html + +$(d)/test-results/sharness.html: $(d)/test-results/sharness.xml + @echo "*** $@ ***" + @(cd $(@D)/.. && ./lib/test-generate-junit-html.sh no-frames) +.PHONY: $(d)/test-results/sharness.html $(d)/clean-test-results: rm -rf $(@D)/test-results @@ -62,16 +72,10 @@ $(d)/deps: $(SHARNESS_$(d)) $$(DEPS_$(d)) # use second expansion so coverage can test_sharness_deps: $(d)/deps .PHONY: test_sharness_deps -test_sharness_short: $(d)/aggregate -.PHONY: test_sharness_short +test_sharness: $(d)/aggregate +.PHONY: test_sharness - -test_sharness_expensive: export TEST_EXPENSIVE=1 -test_sharness_expensive: test_sharness_short -.PHONY: test_sharness_expensive - -TEST += test_sharness_expensive -TEST_SHORT += test_sharness_short +TEST += test_sharness include mk/footer.mk diff --git a/test/sharness/lib/0001-Generate-partial-JUnit-reports.patch b/test/sharness/lib/0001-Generate-partial-JUnit-reports.patch deleted file mode 100644 index 1a8b5f21b..000000000 --- a/test/sharness/lib/0001-Generate-partial-JUnit-reports.patch +++ /dev/null @@ -1,250 +0,0 @@ -From bc6bf844ef4e4cd468bc1ec96f2d6af738eb8d2f Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?=C5=81ukasz=20Magiera?= -Date: Sat, 21 Apr 2018 22:01:45 +0200 -Subject: [PATCH] Generate partial JUnit reports - ---- - sharness.sh | 114 +++++++++++++++++++++++++++++++++++++++++++++++++--- - 1 file changed, 108 insertions(+), 6 deletions(-) - -diff --git a/sharness.sh b/sharness.sh -index 6750ff7..336e426 100644 ---- a/sharness.sh -+++ b/sharness.sh -@@ -1,4 +1,4 @@ --#!/bin/sh -+#!/usr/bin/env bash - # - # Copyright (c) 2011-2012 Mathias Lafeldt - # Copyright (c) 2005-2012 Git project -@@ -106,6 +106,10 @@ if test -n "$color"; then - test -n "$quiet" && return;; - esac - shift -+ -+ if test -n "$TEST_GENERATE_JUNIT"; then -+ echo "$*" >> .junit/tout -+ fi - printf "%s" "$*" - tput sgr0 - echo -@@ -115,6 +119,10 @@ else - say_color() { - test -z "$1" && test -n "$quiet" && return - shift -+ -+ if test -n "$TEST_GENERATE_JUNIT"; then -+ echo "$*" >> .junit/tout -+ fi - printf "%s\n" "$*" - } - fi -@@ -129,6 +137,12 @@ say() { - say_color info "$*" - } - -+esc=$(printf '\033') -+ -+esc_xml() { -+ sed 's/&/\&/g; s//\>/g; s/"/\"/g; s/'"$esc"'//g; s///g;' -+} -+ - test -n "$test_description" || error "Test script did not set test_description." - - if test "$help" = "t"; then -@@ -251,30 +265,78 @@ test_have_prereq() { - test $total_prereq = $ok_prereq - } - -+# junit_testcase generates a testcase xml file after each test -+ -+junit_testcase() { -+ if test -z "$TEST_GENERATE_JUNIT"; then -+ return -+ fi -+ -+ test_name=$1 -+ tc_file=".junit/case-$(printf "%04d" $test_count)" -+ time_sec="$(cat .junit/time | xargs printf '%04d' | sed -e 's/\(...\)$/.\1/g')" -+ -+ echo "$(expr $(cat .junit/time_total) + $(cat .junit/time) )" > .junit/time_total -+ -+ shift -+ cat > "$tc_file" <<-EOF -+ -+ $@ -+ EOF -+ -+ if test -f .junit/tout; then -+ cat >> "$tc_file" <<-EOF -+ -+ $(cat .junit/tout | esc_xml) -+ -+ EOF -+ fi -+ -+ if test -f .junit/terr; then -+ cat >> "$tc_file" <<-EOF -+ -+ $(cat .junit/terr | esc_xml) -+ -+ EOF -+ fi -+ -+ echo "" >> "$tc_file" -+ rm -f .junit/tout .junit/terr .junit/time -+} -+ - # You are not expected to call test_ok_ and test_failure_ directly, use - # the text_expect_* functions instead. - - test_ok_() { - test_success=$(($test_success + 1)) - say_color "" "ok $test_count - $@" -+ -+ junit_testcase "$@" - } - - test_failure_() { - test_failure=$(($test_failure + 1)) - say_color error "not ok $test_count - $1" -+ test_name=$1 - shift - echo "$@" | sed -e 's/^/# /' -+ junit_testcase "$test_name" ''$(echo $@ | esc_xml)'' -+ - test "$immediate" = "" || { EXIT_OK=t; exit 1; } - } - - test_known_broken_ok_() { - test_fixed=$(($test_fixed + 1)) - say_color error "ok $test_count - $@ # TODO known breakage vanished" -+ -+ junit_testcase "$@" '' - } - - test_known_broken_failure_() { - test_broken=$(($test_broken + 1)) - say_color warn "not ok $test_count - $@ # TODO known breakage" -+ -+ junit_testcase "$@" - } - - # Public: Execute commands in debug mode. -@@ -310,15 +372,25 @@ test_pause() { - test_eval_() { - # This is a separate function because some tests use - # "return" to end a test_expect_success block early. -- eval &3 2>&4 "$*" -+ if test -n "$TEST_GENERATE_JUNIT"; then -+ eval >(tee -a .junit/tout >&3) 2> >(tee -a .junit/terr >&4) "$*" -+ else -+ eval &3 2>&4 "$*" -+ fi - } - - test_run_() { - test_cleanup=: - expecting_failure=$2 -+ -+ start_time_ms=$(date "+%s%3N"); - test_eval_ "$1" - eval_ret=$? - -+ if test -n "$TEST_GENERATE_JUNIT"; then -+ echo $(expr $(date "+%s%3N") - ${start_time_ms} ) > .junit/time; -+ fi -+ - if test "$chain_lint" = "t"; then - test_eval_ "(exit 117) && $1" - if test "$?" != 117; then -@@ -355,8 +427,18 @@ test_skip_() { - of_prereq=" of $test_prereq" - fi - -- say_color skip >&3 "skipping test: $@" -- say_color skip "ok $test_count # skip $1 (missing $missing_prereq${of_prereq})" -+ say_color skip >&3 "skipping test: $1" -+ say_color skip "ok $test_count # skip $1 (missing $missing_prereqm${of_prereq})" -+ -+ if test -n "$TEST_GENERATE_JUNIT"; then -+ cat > ".junit/case-$(printf "%04d" $test_count)" <<-EOF -+ -+ -+ skip $(echo $1 | esc_xml) (missing $missing_prereq${of_prereq}) -+ -+ -+ EOF -+ fi - : true - ;; - *) -@@ -403,7 +485,7 @@ test_expect_success() { - test "$#" = 3 && { test_prereq=$1; shift; } || test_prereq= - test "$#" = 2 || error "bug in the test script: not 2 or 3 parameters to test_expect_success" - export test_prereq -- if ! test_skip_ "$@"; then -+ if ! test_skip_ "$@" "$1"; then - say >&3 "expecting success: $2" - if test_run_ "$2"; then - test_ok_ "$1" -@@ -442,7 +524,7 @@ test_expect_failure() { - test "$#" = 3 && { test_prereq=$1; shift; } || test_prereq= - test "$#" = 2 || error "bug in the test script: not 2 or 3 parameters to test_expect_failure" - export test_prereq -- if ! test_skip_ "$@"; then -+ if ! test_skip_ "$@" "$1"; then - say >&3 "checking known breakage: $2" - if test_run_ "$2" expecting_failure; then - test_known_broken_ok_ "$1" -@@ -675,6 +757,7 @@ test_done() { - test_results_dir="$SHARNESS_TEST_DIRECTORY/test-results" - mkdir -p "$test_results_dir" - test_results_path="$test_results_dir/${SHARNESS_TEST_FILE%.$SHARNESS_TEST_EXTENSION}.$$.counts" -+ junit_results_path="$test_results_dir/${SHARNESS_TEST_FILE%.$SHARNESS_TEST_EXTENSION}.$$.xml.part" - - cat >>"$test_results_path" <<-EOF - total $test_count -@@ -684,6 +767,16 @@ test_done() { - failed $test_failure - - EOF -+ -+ if test -n "$TEST_GENERATE_JUNIT"; then -+ time_sec="$(cat .junit/time_total | xargs printf "%04d" | sed -e 's/\(...\)$/.\1/g')" -+ -+ cat >>"$junit_results_path" <<-EOF -+ -+ $(find .junit -name 'case-*' | sort | xargs cat) -+ -+ EOF -+ fi - fi - - if test "$test_fixed" != 0; then -@@ -745,6 +838,9 @@ export PATH SHARNESS_BUILD_DIRECTORY - SHARNESS_TEST_FILE="$0" - export SHARNESS_TEST_FILE - -+SHARNESS_TEST_NAME=$(basename ${SHARNESS_TEST_FILE} ".sh") -+export SHARNESS_TEST_NAME -+ - # Prepare test area. - test_dir="trash directory.$(basename "$SHARNESS_TEST_FILE" ".$SHARNESS_TEST_EXTENSION")" - test -n "$root" && test_dir="$root/$test_dir" -@@ -771,6 +867,12 @@ mkdir -p "$test_dir" || exit 1 - # in subprocesses like git equals our $PWD (for pathname comparisons). - cd -P "$test_dir" || exit 1 - -+# Prepare JUnit report dir -+if test -n "$TEST_GENERATE_JUNIT"; then -+ mkdir -p .junit -+ echo 0 > .junit/time_total -+fi -+ - this_test=${SHARNESS_TEST_FILE##*/} - this_test=${this_test%.$SHARNESS_TEST_EXTENSION} - for skp in $SKIP_TESTS; do --- -2.17.0 - diff --git a/test/sharness/lib/gen-junit-report.sh b/test/sharness/lib/gen-junit-report.sh deleted file mode 100755 index c69f39adb..000000000 --- a/test/sharness/lib/gen-junit-report.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env bash - -cat > test-results/sharness.xml <<-EOF - - - $(find test-results -name '*.xml.part' | sort | xargs cat) - -EOF diff --git a/test/sharness/lib/install-sharness.sh b/test/sharness/lib/install-sharness.sh index ac6cb2f74..41b27188c 100755 --- a/test/sharness/lib/install-sharness.sh +++ b/test/sharness/lib/install-sharness.sh @@ -1,60 +1,50 @@ #!/bin/sh # install sharness.sh # -# Copyright (c) 2014 Juan Batiz-Benet +# Copyright (c) 2014, 2022 Juan Batiz-Benet, Piotr Galar # MIT Licensed; see the LICENSE file in this repository. # -# settings -version=5eee9b51b5621cec95a64018f0cc779963b230d2 -patch_version=17 +gitrepo=pl-strflt/sharness +githash=803df39d3cba16bb7d493dd6cd8bc5e29826da61 -urlprefix=https://github.com/mlafeldt/sharness.git if test ! -n "$clonedir" ; then clonedir=lib fi sharnessdir=sharness - -if test -f "$clonedir/$sharnessdir/SHARNESS_VERSION_${version}_p${patch_version}" -then - # There is the right version file. Great, we are done! - exit 0 -fi +gitdir="$clonedir/$sharnessdir/.git" die() { echo >&2 "$@" exit 1 } -apply_patches() { - git config --local user.email "noone@nowhere" - git config --local user.name "No One" - git am ../0001-Generate-partial-JUnit-reports.patch - - touch "SHARNESS_VERSION_${version}_p${patch_version}" || die "Could not create 'SHARNESS_VERSION_${version}_p${patch_version}'" -} - -checkout_version() { - git checkout "$version" || die "Could not checkout '$version'" - rm -f SHARNESS_VERSION_* || die "Could not remove 'SHARNESS_VERSION_*'" - echo "Sharness version $version is checked out!" - - apply_patches -} - -if test -d "$clonedir/$sharnessdir/.git" -then - # We need to update sharness! - cd "$clonedir/$sharnessdir" || die "Could not cd into '$clonedir/$sharnessdir' directory" - git fetch || die "Could not fetch to update sharness" - checkout_version -else - # We need to clone sharness! - mkdir -p "$clonedir" || die "Could not create '$clonedir' directory" - cd "$clonedir" || die "Could not cd into '$clonedir' directory" - - git clone "$urlprefix" || die "Could not clone '$urlprefix'" - cd "$sharnessdir" || die "Could not cd into '$sharnessdir' directory" - checkout_version +if test -d "$clonedir/$sharnessdir"; then + giturl="git@github.com:${gitrepo}.git" + echo "Checking if $giturl is already cloned (and if its origin is correct)" + if ! test -d "$gitdir" || test "$(git --git-dir "$gitdir" remote get-url origin)" != "$giturl"; then + echo "Removing $clonedir/$sharnessdir" + rm -rf "$clonedir/$sharnessdir" || die "Could not remove $clonedir/$sharnessdir" + fi fi + +if ! test -d "$clonedir/$sharnessdir"; then + giturl="https://github.com/${gitrepo}.git" + echo "Cloning $giturl into $clonedir/$sharnessdir" + git clone "$giturl" "$clonedir/$sharnessdir" || die "Could not clone $giturl into $clonedir/$sharnessdir" +fi + + +echo "Changing directory to $clonedir/$sharnessdir" +cd "$clonedir/$sharnessdir" || die "Could not cd into '$clonedir/$sharnessdir' directory" + +echo "Checking if $githash is already fetched" +if ! git show "$githash" >/dev/null 2>&1; then + echo "Fetching $githash" + git fetch origin "$githash" || die "Could not fetch $githash" +fi + +echo "Resetting to $githash" +git reset --hard "$githash" || die "Could not reset to $githash" + exit 0 diff --git a/test/sharness/lib/test-aggregate-junit-reports.sh b/test/sharness/lib/test-aggregate-junit-reports.sh new file mode 100755 index 000000000..ad39e5668 --- /dev/null +++ b/test/sharness/lib/test-aggregate-junit-reports.sh @@ -0,0 +1,17 @@ +#!/bin/sh +# +# Script to aggregate results using Sharness +# +# Copyright (c) 2014, 2022 Christian Couder, Piotr Galar +# MIT Licensed; see the LICENSE file in this repository. +# + +SHARNESS_AGGREGATE_JUNIT="lib/sharness/aggregate-junit-reports.sh" + +test -f "$SHARNESS_AGGREGATE_JUNIT" || { + echo >&2 "Cannot find: $SHARNESS_AGGREGATE_JUNIT" + echo >&2 "Please check Sharness installation." + exit 1 +} + +ls test-results/t*-*.sh.*.xml.part | "$SHARNESS_AGGREGATE_JUNIT" > test-results/sharness.xml diff --git a/test/sharness/lib/test-generate-junit-html.sh b/test/sharness/lib/test-generate-junit-html.sh new file mode 100755 index 000000000..cc18762cb --- /dev/null +++ b/test/sharness/lib/test-generate-junit-html.sh @@ -0,0 +1,58 @@ +#!/bin/bash + +dependencies=( + "url=https://sourceforge.net/projects/saxon/files/Saxon-HE/11/Java/SaxonHE11-4J.zip;md5=8a4783d307c32c898f8995b8f337fd6b" + "url=https://raw.githubusercontent.com/pl-strflt/ant/c781f7d79b92cc55530245d9554682a47f46851e/src/etc/junit-frames-saxon.xsl;md5=6eb013566903a91e4959413f6ff144d0" + "url=https://raw.githubusercontent.com/pl-strflt/ant/c781f7d79b92cc55530245d9554682a47f46851e/src/etc/junit-noframes-saxon.xsl;md5=8d54882d5f9d32a7743ec675cc2e30ac" +) + +dependenciesdir="lib/dependencies" +mkdir -p "$dependenciesdir" + +get_md5() { + md5sum "$1" | cut -d ' ' -f 1 +} + +for dependency in "${dependencies[@]}"; do + url="$(echo "$dependency" | cut -d ';' -f 1 | cut -d '=' -f 2)" + md5="$(echo "$dependency" | cut -d ';' -f 2 | cut -d '=' -f 2)" + filename="$(basename "$url")" + if test -f "$dependenciesdir/$filename" && test "$(get_md5 "$dependenciesdir/$filename")" = "$md5"; then + echo "Using cached $filename" + else + echo "Downloading $filename" + curl -L --max-redirs 5 --retry 5 --no-progress-meter --output "$dependenciesdir/$filename" "$url" + actual_md5="$(get_md5 "$dependenciesdir/$filename")" + if test "$actual_md5" != "$md5"; then + echo "Downloaded $filename has wrong md5sum ('$actual_md5' != '$md5')" + exit 1 + fi + dirname=${filename%.*} + extension=${filename#$dirname.} + if test "$extension" = "zip"; then + echo "Removing old $dependenciesdir/$dirname" + rm -rf "$dependenciesdir/$dirname" + echo "Unzipping $dependenciesdir/$filename" + unzip "$dependenciesdir/$filename" -d "$dependenciesdir/$dirname" + fi + fi +done + +case "$1" in + "frames") + java -jar lib/dependencies/SaxonHE11-4J/saxon-he-11.4.jar \ + -s:test-results/sharness.xml \ + -xsl:lib/dependencies/junit-frames-saxon.xsl \ + output.dir=$(pwd)/test-results/sharness-html + ;; + "no-frames") + java -jar lib/dependencies/SaxonHE11-4J/saxon-he-11.4.jar \ + -s:test-results/sharness.xml \ + -xsl:lib/dependencies/junit-noframes-saxon.xsl \ + -o:test-results/sharness.html + ;; + *) + echo "Usage: $0 [frames|no-frames]" + exit 1 + ;; +esac diff --git a/test/sharness/lib/test-lib.sh b/test/sharness/lib/test-lib.sh index 0757c323c..4ce2a6027 100644 --- a/test/sharness/lib/test-lib.sh +++ b/test/sharness/lib/test-lib.sh @@ -3,7 +3,7 @@ # Copyright (c) 2014 Christian Couder # MIT Licensed; see the LICENSE file in this repository. # -# We are using sharness (https://github.com/mlafeldt/sharness) +# We are using sharness (https://github.com/pl-strflt/sharness/tree/feat/junit) # which was extracted from the Git test framework. # use the ipfs tool to test against @@ -27,14 +27,17 @@ fi # to pass through in some cases. test "$TEST_VERBOSE" = 1 && verbose=t test "$TEST_IMMEDIATE" = 1 && immediate=t +test "$TEST_JUNIT" = 1 && junit=t +test "$TEST_NO_COLOR" = 1 && no_color=t # source the common hashes first. . lib/test-lib-hashes.sh -SHARNESS_LIB="lib/sharness/sharness.sh" +ln -sf lib/sharness/sharness.sh . +ln -sf lib/sharness/lib-sharness . -. "$SHARNESS_LIB" || { - echo >&2 "Cannot source: $SHARNESS_LIB" +. "sharness.sh" || { + echo >&2 "Cannot source: sharness.sh" echo >&2 "Please check Sharness installation." exit 1 } @@ -106,10 +109,15 @@ expr "$TEST_OS" : "CYGWIN_NT" >/dev/null || test_set_prereq STD_ERR_MSG if test "$TEST_VERBOSE" = 1; then echo '# TEST_VERBOSE='"$TEST_VERBOSE" + echo '# TEST_IMMEDIATE='"$TEST_IMMEDIATE" echo '# TEST_NO_FUSE='"$TEST_NO_FUSE" + echo '# TEST_NO_DOCKER='"$TEST_NO_DOCKER" echo '# TEST_NO_PLUGIN='"$TEST_NO_PLUGIN" echo '# TEST_EXPENSIVE='"$TEST_EXPENSIVE" echo '# TEST_OS='"$TEST_OS" + echo '# TEST_JUNIT='"$TEST_JUNIT" + echo '# TEST_NO_COLOR='"$TEST_NO_COLOR" + echo '# TEST_ULIMIT_PRESET='"$TEST_ULIMIT_PRESET" fi # source our generic test lib @@ -541,4 +549,3 @@ purge_blockstore() { [[ -z "$( ipfs repo gc )" ]] ' } - diff --git a/test/sharness/t0110-gateway.sh b/test/sharness/t0110-gateway.sh index 87aa61c70..5244bd214 100755 --- a/test/sharness/t0110-gateway.sh +++ b/test/sharness/t0110-gateway.sh @@ -121,14 +121,14 @@ test_expect_success "GET invalid IPNS root returns 400 (Bad Request)" ' test_curl_resp_http_code "http://127.0.0.1:$port/ipns/QmInvalid/pleaseDontAddMe" "HTTP/1.1 400 Bad Request" ' -test_expect_failure "GET IPNS path succeeds" ' +test_expect_success "GET IPNS path succeeds" ' ipfs name publish --allow-offline "$HASH" && PEERID=$(ipfs config Identity.PeerID) && test_check_peerid "$PEERID" && curl -sfo actual "http://127.0.0.1:$port/ipns/$PEERID" ' -test_expect_failure "GET IPNS path output looks good" ' +test_expect_success "GET IPNS path output looks good" ' test_cmp expected actual ' diff --git a/test/sharness/t0118-gateway-car.sh b/test/sharness/t0118-gateway-car.sh index 3d8d7b08f..62b2725d0 100755 --- a/test/sharness/t0118-gateway-car.sh +++ b/test/sharness/t0118-gateway-car.sh @@ -111,7 +111,7 @@ test_launch_ipfs_daemon_without_network ' test_expect_success "GET for application/vnd.ipld.car with query filename includes Content-Disposition with custom filename" ' - curl -svX GET -H "Accept: application/vnd.ipld.car" "http://127.0.0.1:$GWAY_PORT/ipfs/$ROOT_DIR_CID/subdir/ascii.txt?filename=foobar.car" > curl_output_filename 2>&1 && + curl -svX GET -H "Accept: application/vnd.ipld.car" "http://127.0.0.1:$GWAY_PORT/ipfs/$ROOT_DIR_CID/subdir/ascii.txt?filename=foobar.car" >/dev/null 2>curl_output_filename && cat curl_output_filename && grep "< Content-Disposition: attachment\; filename=\"foobar.car\"" curl_output_filename ' diff --git a/test/sharness/t0125-twonode.sh b/test/sharness/t0125-twonode.sh index dcf5c88ce..8ea1c9e5d 100755 --- a/test/sharness/t0125-twonode.sh +++ b/test/sharness/t0125-twonode.sh @@ -72,6 +72,12 @@ flaky_advanced_test() { test_expect_success "shut down nodes" ' iptb stop && iptb_wait_stop ' + + # NOTE: data transferred stats checks are flaky + # trying to debug them by printing out the stats hides the flakiness + # my theory is that the extra time cat calls take to print out the stats + # allow for proper cleanup to happen + go-sleep 1s } run_advanced_test() { diff --git a/test/sharness/t0160-resolve.sh b/test/sharness/t0160-resolve.sh index ca11947b0..f65b29c11 100755 --- a/test/sharness/t0160-resolve.sh +++ b/test/sharness/t0160-resolve.sh @@ -35,15 +35,6 @@ test_resolve_setup_name() { ' } -test_resolve_setup_name_fail() { - local key="$1" - local ref="$2" - - test_expect_failure "resolve: prepare $key" ' - ipfs name publish --key="$key" --allow-offline "$ref" - ' -} - test_resolve() { src=$1 dst=$2 @@ -129,23 +120,7 @@ test_resolve_cmd_b32() { ' } - -#todo remove this once the online resolve is fixed -test_resolve_fail() { - src=$1 - dst=$2 - - test_expect_failure "resolve succeeds: $src" ' - ipfs resolve "$src" >actual - ' - - test_expect_failure "resolved correctly: $src -> $dst" ' - printf "$dst" >expected && - test_cmp expected actual - ' -} - -test_resolve_cmd_fail() { +test_resolve_cmd_success() { test_resolve "/ipfs/$a_hash" "/ipfs/$a_hash" test_resolve "/ipfs/$a_hash/b" "/ipfs/$b_hash" test_resolve "/ipfs/$a_hash/b/c" "/ipfs/$c_hash" @@ -155,23 +130,16 @@ test_resolve_cmd_fail() { test_resolve "/ipld/$dag_hash/i/j" "/ipld/$dag_hash/i/j" test_resolve "/ipld/$dag_hash/i" "/ipld/$dag_hash/i" - # At the moment, publishing _fails_ because we fail to put to the DHT. - # However, resolving succeeds because we resolve the record we put to our own - # node. - # - # We should find a nice way to truly support offline publishing. But this - # behavior isn't terrible. - - test_resolve_setup_name_fail "self" "/ipfs/$a_hash" + test_resolve_setup_name "self" "/ipfs/$a_hash" test_resolve "/ipns/$self_hash" "/ipfs/$a_hash" test_resolve "/ipns/$self_hash/b" "/ipfs/$b_hash" test_resolve "/ipns/$self_hash/b/c" "/ipfs/$c_hash" - test_resolve_setup_name_fail "self" "/ipfs/$b_hash" + test_resolve_setup_name "self" "/ipfs/$b_hash" test_resolve "/ipns/$self_hash" "/ipfs/$b_hash" test_resolve "/ipns/$self_hash/c" "/ipfs/$c_hash" - test_resolve_setup_name_fail "self" "/ipfs/$c_hash" + test_resolve_setup_name "self" "/ipfs/$c_hash" test_resolve "/ipns/$self_hash" "/ipfs/$c_hash" } @@ -181,7 +149,7 @@ test_resolve_cmd_b32 # should work online test_launch_ipfs_daemon -test_resolve_cmd_fail +test_resolve_cmd_success test_kill_ipfs_daemon test_done diff --git a/test/sharness/t0300-docker-image.sh b/test/sharness/t0300-docker-image.sh index a3a802b28..3c390a453 100755 --- a/test/sharness/t0300-docker-image.sh +++ b/test/sharness/t0300-docker-image.sh @@ -79,9 +79,9 @@ test_expect_success "check that init script configs were applied" ' ' test_expect_success "simple ipfs add/cat can be run in docker container" ' - expected="Hello Worlds" && - HASH=$(docker_exec "$DOC_ID" "echo $(cat expected) | ipfs add | cut -d' ' -f2") && - docker_exec "$DOC_ID" "ipfs cat $HASH" >actual && + echo "Hello Worlds" | tr -d "[:cntrl:]" > expected && + HASH=$(docker_exec "$DOC_ID" "echo $(cat expected) | ipfs add -q" | tr -d "[:cntrl:]") && + docker_exec "$DOC_ID" "ipfs cat $HASH" | tr -d "[:cntrl:]" > actual && test_cmp expected actual ' @@ -102,4 +102,3 @@ test_expect_success "stop docker container" ' docker_rm "$DOC_ID" docker_rmi "$IMAGE_ID" test_done - From 8b2d21c235272dc1ca58b16c8dea159d2ff218a3 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Sat, 14 Jan 2023 01:08:42 +0100 Subject: [PATCH 0408/1212] chore: switch actions to master --- .github/workflows/gobuild.yml | 2 +- .github/workflows/sharness.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/gobuild.yml b/.github/workflows/gobuild.yml index edacc269b..91147a7d3 100644 --- a/.github/workflows/gobuild.yml +++ b/.github/workflows/gobuild.yml @@ -10,7 +10,7 @@ on: jobs: runner: if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' - uses: ipfs/kubo/.github/workflows/runner.yml@ci/move-to-github-actions # TODO: change to master + uses: ipfs/kubo/.github/workflows/runner.yml gobuild: needs: [runner] runs-on: ${{ fromJSON(needs.runner.outputs.config).labels }} diff --git a/.github/workflows/sharness.yml b/.github/workflows/sharness.yml index 044e55560..74810eeaa 100644 --- a/.github/workflows/sharness.yml +++ b/.github/workflows/sharness.yml @@ -10,7 +10,7 @@ on: jobs: runner: if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' - uses: ipfs/kubo/.github/workflows/runner.yml@ci/move-to-github-actions # TODO: change to master + uses: ipfs/kubo/.github/workflows/runner.yml sharness: needs: [runner] runs-on: ${{ fromJSON(needs.runner.outputs.config).labels }} From 89cdd8264f68aaaa2546d45cd01019394afc3701 Mon Sep 17 00:00:00 2001 From: Antonio Navarro Perez Date: Sat, 14 Jan 2023 01:30:48 +0100 Subject: [PATCH 0409/1212] docs: improve docs/README (#9539) Avoid confusion about what kind of documentation we have on this folder. --- docs/README.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/docs/README.md b/docs/README.md index 78235622a..ab7ac9cc3 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,11 +1,17 @@ # Developer Documentation and Guides -If you are looking for User Documentation & Guides, please visit [docs.ipfs.tech](https://docs.ipfs.tech/). +If you are looking for User Documentation & Guides, please visit [docs.ipfs.tech](https://docs.ipfs.tech/) or check [General Documentation](#general-documentation). If you’re experiencing an issue with IPFS, **please follow [our issue guide](github-issue-guide.md) when filing an issue!** Otherwise, check out the following guides to using and developing IPFS: +## General Documentation + +- [Configuration reference](config.md) + - [Datastore configuration](datastores.md) + - [Experimental features](experimental-features.md) + ## Developing `kubo` - First, please read the Contributing Guidelines [for IPFS projects](https://github.com/ipfs/community/blob/master/CONTRIBUTING.md) and then the Contributing Guidelines for [Go code specifically](https://github.com/ipfs/community/blob/master/CONTRIBUTING_GO.md) @@ -22,9 +28,6 @@ Otherwise, check out the following guides to using and developing IPFS: ## Advanced User Guides - [Transferring a File Over IPFS](file-transfer.md) -- [Configuration reference](config.md) - - [Datastore configuration](datastores.md) - - [Experimental features](experimental-features.md) - [Installing command completion](command-completion.md) - [Mounting IPFS with FUSE](fuse.md) - [Installing plugins](plugins.md) From bfdaf2ffbf3c91478c7e8c79cd92e852011f036c Mon Sep 17 00:00:00 2001 From: galargh Date: Sat, 14 Jan 2023 11:29:55 +0100 Subject: [PATCH 0410/1212] fix: docker image publishing --- .github/workflows/docker-image.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index 8a90910f7..27f6b71b5 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -30,9 +30,9 @@ jobs: - name: Get tags id: tags run: | - TAGS="$(./bin/get-docker-tags.sh $(date -u +%F))" - TAGS="${TAGS//$'\n'/'%0A'}" - echo "value=$(echo $TAGS)" >> $GITHUB_OUTPUT + echo "value=<> $GITHUB_OUTPUT + ./bin/get-docker-tags.sh "$(date -u +%F)" >> $GITHUB_OUTPUT + echo "EOF" >> $GITHUB_OUTPUT shell: bash - name: Log in to Docker Hub From b11a8a960f66ff6614f36fb606906a51962f4dd0 Mon Sep 17 00:00:00 2001 From: Piotr Galar Date: Sat, 14 Jan 2023 12:02:53 +0100 Subject: [PATCH 0411/1212] Merge pull request #9546 from ipfs/docker-image fix: docker image publishing and experimental gh workflow --- .github/workflows/docker-image.yml | 4 ++-- .github/workflows/gobuild.yml | 2 +- .github/workflows/sharness.yml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index 27f6b71b5..a7416e388 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -30,7 +30,7 @@ jobs: - name: Get tags id: tags run: | - echo "value=<> $GITHUB_OUTPUT + echo "value<> $GITHUB_OUTPUT ./bin/get-docker-tags.sh "$(date -u +%F)" >> $GITHUB_OUTPUT echo "EOF" >> $GITHUB_OUTPUT shell: bash @@ -38,7 +38,7 @@ jobs: - name: Log in to Docker Hub uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9 with: - username: ${{ secrets.DOCKER_USERNAME }} + username: ${{ vars.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} - name: Build Docker image and publish to Docker Hub diff --git a/.github/workflows/gobuild.yml b/.github/workflows/gobuild.yml index 91147a7d3..120e94693 100644 --- a/.github/workflows/gobuild.yml +++ b/.github/workflows/gobuild.yml @@ -10,7 +10,7 @@ on: jobs: runner: if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' - uses: ipfs/kubo/.github/workflows/runner.yml + uses: ipfs/kubo/.github/workflows/runner.yml@master gobuild: needs: [runner] runs-on: ${{ fromJSON(needs.runner.outputs.config).labels }} diff --git a/.github/workflows/sharness.yml b/.github/workflows/sharness.yml index 74810eeaa..6241e3fe6 100644 --- a/.github/workflows/sharness.yml +++ b/.github/workflows/sharness.yml @@ -10,7 +10,7 @@ on: jobs: runner: if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' - uses: ipfs/kubo/.github/workflows/runner.yml + uses: ipfs/kubo/.github/workflows/runner.yml@master sharness: needs: [runner] runs-on: ${{ fromJSON(needs.runner.outputs.config).labels }} From a7b23d8a4927f01913702588c8832dff52480381 Mon Sep 17 00:00:00 2001 From: galargh Date: Sun, 15 Jan 2023 11:59:55 +0100 Subject: [PATCH 0412/1212] fix: do not download saxon in parallel --- test/sharness/Rules.mk | 9 ++++- test/sharness/lib/download-saxon.sh | 39 +++++++++++++++++++ test/sharness/lib/test-generate-junit-html.sh | 38 ------------------ 3 files changed, 46 insertions(+), 40 deletions(-) create mode 100755 test/sharness/lib/download-saxon.sh diff --git a/test/sharness/Rules.mk b/test/sharness/Rules.mk index 3b7708b60..20b2634db 100644 --- a/test/sharness/Rules.mk +++ b/test/sharness/Rules.mk @@ -47,12 +47,17 @@ $(d)/test-results/sharness.xml: $(T_$(d)) @(cd $(@D)/.. && ./lib/test-aggregate-junit-reports.sh) .PHONY: $(d)/test-results/sharness.xml -$(d)/test-results/sharness-html: $(d)/test-results/sharness.xml +$(d)/download-saxon: + @echo "*** $@ ***" + @(cd $(@D) && ./lib/download-saxon.sh) +.PHONY: $(d)/download-saxon + +$(d)/test-results/sharness-html: $(d)/test-results/sharness.xml $(d)/download-saxon @echo "*** $@ ***" @(cd $(@D)/.. && ./lib/test-generate-junit-html.sh frames) .PHONY: $(d)/test-results/sharness-html -$(d)/test-results/sharness.html: $(d)/test-results/sharness.xml +$(d)/test-results/sharness.html: $(d)/test-results/sharness.xml $(d)/download-saxon @echo "*** $@ ***" @(cd $(@D)/.. && ./lib/test-generate-junit-html.sh no-frames) .PHONY: $(d)/test-results/sharness.html diff --git a/test/sharness/lib/download-saxon.sh b/test/sharness/lib/download-saxon.sh new file mode 100755 index 000000000..195630804 --- /dev/null +++ b/test/sharness/lib/download-saxon.sh @@ -0,0 +1,39 @@ +#!/bin/bash + +dependencies=( + "url=https://sourceforge.net/projects/saxon/files/Saxon-HE/11/Java/SaxonHE11-4J.zip;md5=8a4783d307c32c898f8995b8f337fd6b" + "url=https://raw.githubusercontent.com/pl-strflt/ant/c781f7d79b92cc55530245d9554682a47f46851e/src/etc/junit-frames-saxon.xsl;md5=6eb013566903a91e4959413f6ff144d0" + "url=https://raw.githubusercontent.com/pl-strflt/ant/c781f7d79b92cc55530245d9554682a47f46851e/src/etc/junit-noframes-saxon.xsl;md5=8d54882d5f9d32a7743ec675cc2e30ac" +) + +dependenciesdir="lib/dependencies" +mkdir -p "$dependenciesdir" + +get_md5() { + md5sum "$1" | cut -d ' ' -f 1 +} + +for dependency in "${dependencies[@]}"; do + url="$(echo "$dependency" | cut -d ';' -f 1 | cut -d '=' -f 2)" + md5="$(echo "$dependency" | cut -d ';' -f 2 | cut -d '=' -f 2)" + filename="$(basename "$url")" + if test -f "$dependenciesdir/$filename" && test "$(get_md5 "$dependenciesdir/$filename")" = "$md5"; then + echo "Using cached $filename" + else + echo "Downloading $filename" + curl -L --max-redirs 5 --retry 5 --no-progress-meter --output "$dependenciesdir/$filename" "$url" + actual_md5="$(get_md5 "$dependenciesdir/$filename")" + if test "$actual_md5" != "$md5"; then + echo "Downloaded $filename has wrong md5sum ('$actual_md5' != '$md5')" + exit 1 + fi + dirname=${filename%.*} + extension=${filename#$dirname.} + if test "$extension" = "zip"; then + echo "Removing old $dependenciesdir/$dirname" + rm -rf "$dependenciesdir/$dirname" + echo "Unzipping $dependenciesdir/$filename" + unzip "$dependenciesdir/$filename" -d "$dependenciesdir/$dirname" + fi + fi +done diff --git a/test/sharness/lib/test-generate-junit-html.sh b/test/sharness/lib/test-generate-junit-html.sh index cc18762cb..2790a7b9d 100755 --- a/test/sharness/lib/test-generate-junit-html.sh +++ b/test/sharness/lib/test-generate-junit-html.sh @@ -1,43 +1,5 @@ #!/bin/bash -dependencies=( - "url=https://sourceforge.net/projects/saxon/files/Saxon-HE/11/Java/SaxonHE11-4J.zip;md5=8a4783d307c32c898f8995b8f337fd6b" - "url=https://raw.githubusercontent.com/pl-strflt/ant/c781f7d79b92cc55530245d9554682a47f46851e/src/etc/junit-frames-saxon.xsl;md5=6eb013566903a91e4959413f6ff144d0" - "url=https://raw.githubusercontent.com/pl-strflt/ant/c781f7d79b92cc55530245d9554682a47f46851e/src/etc/junit-noframes-saxon.xsl;md5=8d54882d5f9d32a7743ec675cc2e30ac" -) - -dependenciesdir="lib/dependencies" -mkdir -p "$dependenciesdir" - -get_md5() { - md5sum "$1" | cut -d ' ' -f 1 -} - -for dependency in "${dependencies[@]}"; do - url="$(echo "$dependency" | cut -d ';' -f 1 | cut -d '=' -f 2)" - md5="$(echo "$dependency" | cut -d ';' -f 2 | cut -d '=' -f 2)" - filename="$(basename "$url")" - if test -f "$dependenciesdir/$filename" && test "$(get_md5 "$dependenciesdir/$filename")" = "$md5"; then - echo "Using cached $filename" - else - echo "Downloading $filename" - curl -L --max-redirs 5 --retry 5 --no-progress-meter --output "$dependenciesdir/$filename" "$url" - actual_md5="$(get_md5 "$dependenciesdir/$filename")" - if test "$actual_md5" != "$md5"; then - echo "Downloaded $filename has wrong md5sum ('$actual_md5' != '$md5')" - exit 1 - fi - dirname=${filename%.*} - extension=${filename#$dirname.} - if test "$extension" = "zip"; then - echo "Removing old $dependenciesdir/$dirname" - rm -rf "$dependenciesdir/$dirname" - echo "Unzipping $dependenciesdir/$filename" - unzip "$dependenciesdir/$filename" -d "$dependenciesdir/$dirname" - fi - fi -done - case "$1" in "frames") java -jar lib/dependencies/SaxonHE11-4J/saxon-he-11.4.jar \ From 02d4a0100f5b50d556cbbf3a95c1b949b3e8a2ef Mon Sep 17 00:00:00 2001 From: Gus Eggert Date: Wed, 14 Dec 2022 11:10:48 -0500 Subject: [PATCH 0413/1212] test: port gateway sharness tests to Go tests --- test/cli/gateway_test.go | 492 ++++++++++++++++++ test/cli/harness/harness.go | 13 +- test/cli/harness/http_client.go | 116 +++++ test/cli/harness/node.go | 80 ++- test/cli/harness/nodes.go | 21 +- test/cli/testutils/strings.go | 24 + test/sharness/t0110-gateway-data/foo.block | 2 - test/sharness/t0110-gateway-data/foofoo.block | Bin 82 -> 0 bytes test/sharness/t0110-gateway.sh | 357 ------------- 9 files changed, 727 insertions(+), 378 deletions(-) create mode 100644 test/cli/gateway_test.go create mode 100644 test/cli/harness/http_client.go delete mode 100644 test/sharness/t0110-gateway-data/foo.block delete mode 100644 test/sharness/t0110-gateway-data/foofoo.block delete mode 100755 test/sharness/t0110-gateway.sh diff --git a/test/cli/gateway_test.go b/test/cli/gateway_test.go new file mode 100644 index 000000000..6e8ef516a --- /dev/null +++ b/test/cli/gateway_test.go @@ -0,0 +1,492 @@ +package cli + +import ( + "context" + "encoding/json" + "fmt" + "net/http" + "os" + "path/filepath" + "regexp" + "testing" + + "github.com/ipfs/kubo/config" + "github.com/ipfs/kubo/test/cli/harness" + . "github.com/ipfs/kubo/test/cli/testutils" + "github.com/multiformats/go-multiaddr" + manet "github.com/multiformats/go-multiaddr/net" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestGateway(t *testing.T) { + t.Parallel() + h := harness.NewT(t) + node := h.NewNode().Init().StartDaemon("--offline") + cid := node.IPFSAddStr("Hello Worlds!") + + client := node.GatewayClient() + client.TemplateData = map[string]string{ + "CID": cid, + "PeerID": node.PeerID().String(), + } + + t.Run("GET IPFS path succeeds", func(t *testing.T) { + t.Parallel() + resp := client.Get("/ipfs/{{.CID}}") + assert.Equal(t, 200, resp.StatusCode) + }) + + t.Run("GET IPFS path with explicit ?filename succeeds with proper header", func(t *testing.T) { + t.Parallel() + resp := client.Get("/ipfs/{{.CID}}?filename=testтест.pdf") + assert.Equal(t, 200, resp.StatusCode) + assert.Equal(t, + `inline; filename="test____.pdf"; filename*=UTF-8''test%D1%82%D0%B5%D1%81%D1%82.pdf`, + resp.Headers.Get("Content-Disposition"), + ) + }) + + t.Run("GET IPFS path with explicit ?filename and &download=true succeeds with proper header", func(t *testing.T) { + t.Parallel() + resp := client.Get("/ipfs/{{.CID}}?filename=testтест.mp4&download=true") + assert.Equal(t, 200, resp.StatusCode) + assert.Equal(t, + `attachment; filename="test____.mp4"; filename*=UTF-8''test%D1%82%D0%B5%D1%81%D1%82.mp4`, + resp.Headers.Get("Content-Disposition"), + ) + }) + + // https://github.com/ipfs/go-ipfs/issues/4025#issuecomment-342250616 + t.Run("GET for Server Worker registration outside of an IPFS content root errors", func(t *testing.T) { + t.Parallel() + resp := client.Get("/ipfs/{{.CID}}?filename=sw.js", client.WithHeader("Service-Worker", "script")) + assert.Equal(t, 400, resp.StatusCode) + assert.Contains(t, resp.Body, "navigator.serviceWorker: registration is not allowed for this scope") + }) + + t.Run("GET IPFS directory path succeeds", func(t *testing.T) { + t.Parallel() + client := node.GatewayClient().DisableRedirects() + + pageContents := "hello i am a webpage" + fileContents := "12345" + h.WriteFile("dir/test", fileContents) + h.WriteFile("dir/dirwithindex/index.html", pageContents) + cids := node.IPFS("add", "-r", "-q", filepath.Join(h.Dir, "dir")).Stdout.Lines() + + rootCID := cids[len(cids)-1] + client.TemplateData = map[string]string{ + "IndexFileCID": cids[0], + "TestFileCID": cids[1], + "RootCID": rootCID, + } + + t.Run("GET IPFS the index file CID", func(t *testing.T) { + t.Parallel() + resp := client.Get("/ipfs/{{.IndexFileCID}}") + assert.Equal(t, 200, resp.StatusCode) + assert.Equal(t, pageContents, resp.Body) + }) + + t.Run("GET IPFS the test file CID", func(t *testing.T) { + t.Parallel() + resp := client.Get("/ipfs/{{.TestFileCID}}") + assert.Equal(t, 200, resp.StatusCode) + assert.Equal(t, fileContents, resp.Body) + }) + + t.Run("GET IPFS directory with index.html returns redirect to add trailing slash", func(t *testing.T) { + t.Parallel() + resp := client.Head("/ipfs/{{.RootCID}}/dirwithindex?query=to-remember") + assert.Equal(t, 301, resp.StatusCode) + assert.Equal(t, + fmt.Sprintf("/ipfs/%s/dirwithindex/?query=to-remember", rootCID), + resp.Headers.Get("Location"), + ) + }) + + // This enables go get to parse go-import meta tags from index.html files stored in IPFS + // https://github.com/ipfs/kubo/pull/3963 + t.Run("GET IPFS directory with index.html and no trailing slash returns expected output when go-get is passed", func(t *testing.T) { + t.Parallel() + resp := client.Get("/ipfs/{{.RootCID}}/dirwithindex?go-get=1") + assert.Equal(t, pageContents, resp.Body) + }) + + t.Run("GET IPFS directory with index.html and trailing slash returns expected output", func(t *testing.T) { + t.Parallel() + resp := client.Get("/ipfs/{{.RootCID}}/dirwithindex/?query=to-remember") + assert.Equal(t, pageContents, resp.Body) + }) + + t.Run("GET IPFS nonexistent file returns 404 (Not Found)", func(t *testing.T) { + t.Parallel() + resp := client.Get("/ipfs/{{.RootCID}}/pleaseDontAddMe") + assert.Equal(t, 404, resp.StatusCode) + }) + + t.Run("GET IPFS invalid CID returns 400 (Bad Request)", func(t *testing.T) { + t.Parallel() + resp := client.Get("/ipfs/QmInvalid/pleaseDontAddMe") + assert.Equal(t, 400, resp.StatusCode) + }) + + t.Run("GET IPFS inlined zero-length data object returns ok code (200)", func(t *testing.T) { + t.Parallel() + resp := client.Get("/ipfs/bafkqaaa") + assert.Equal(t, 200, resp.StatusCode) + assert.Equal(t, "0", resp.Resp.Header.Get("Content-Length")) + assert.Equal(t, "", resp.Body) + }) + + t.Run("GET IPFS inlined zero-length data object with byte range returns ok code (200)", func(t *testing.T) { + t.Parallel() + resp := client.Get("/ipfs/bafkqaaa", client.WithHeader("Range", "bytes=0-1048575")) + assert.Equal(t, 200, resp.StatusCode) + assert.Equal(t, "0", resp.Resp.Header.Get("Content-Length")) + assert.Equal(t, "text/plain", resp.Resp.Header.Get("Content-Type")) + }) + + t.Run("GET /ipfs/ipfs/{cid} returns redirect to the valid path", func(t *testing.T) { + t.Parallel() + resp := client.Get("/ipfs/ipfs/bafkqaaa?query=to-remember") + assert.Contains(t, + resp.Body, + ``, + ) + assert.Contains(t, + resp.Body, + ``, + ) + }) + }) + + t.Run("IPNS", func(t *testing.T) { + t.Parallel() + node.IPFS("name", "publish", "--allow-offline", cid) + + t.Run("GET invalid IPNS root returns 400 (Bad Request)", func(t *testing.T) { + t.Parallel() + resp := client.Get("/ipns/QmInvalid/pleaseDontAddMe") + assert.Equal(t, 400, resp.StatusCode) + }) + + t.Run("GET IPNS path succeeds", func(t *testing.T) { + t.Parallel() + resp := client.Get("/ipns/{{.PeerID}}") + assert.Equal(t, 200, resp.StatusCode) + assert.Equal(t, "Hello Worlds!", resp.Body) + }) + + t.Run("GET /ipfs/ipns/{peerid} returns redirect to the valid path", func(t *testing.T) { + t.Parallel() + resp := client.Get("/ipfs/ipns/{{.PeerID}}?query=to-remember") + peerID := node.PeerID().String() + assert.Contains(t, + resp.Body, + fmt.Sprintf(``, peerID), + ) + assert.Contains(t, + resp.Body, + fmt.Sprintf(``, peerID), + ) + + }) + + }) + + t.Run("GET invalid IPFS path errors", func(t *testing.T) { + t.Parallel() + assert.Equal(t, 400, client.Get("/ipfs/12345").StatusCode) + }) + + t.Run("GET invalid path errors", func(t *testing.T) { + t.Parallel() + assert.Equal(t, 404, client.Get("/12345").StatusCode) + }) + + // TODO: these tests that use the API URL shouldn't be part of gateway tests... + t.Run("GET /webui returns 301 or 302", func(t *testing.T) { + t.Parallel() + resp := node.APIClient().DisableRedirects().Get("/webui") + assert.Contains(t, []int{302, 301}, resp.StatusCode) + }) + + t.Run("GET /webui/ returns 301 or 302", func(t *testing.T) { + t.Parallel() + resp := node.APIClient().DisableRedirects().Get("/webui/") + assert.Contains(t, []int{302, 301}, resp.StatusCode) + }) + + t.Run("GET /logs returns logs", func(t *testing.T) { + t.Parallel() + apiClient := node.APIClient() + reqURL := apiClient.BuildURL("/logs") + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + req, err := http.NewRequestWithContext(ctx, http.MethodGet, reqURL, nil) + require.NoError(t, err) + + resp, err := apiClient.Client.Do(req) + require.NoError(t, err) + defer resp.Body.Close() + + // read the first line of the output and parse its JSON + dec := json.NewDecoder(resp.Body) + event := struct{ Event string }{} + err = dec.Decode(&event) + require.NoError(t, err) + + assert.Equal(t, "log API client connected", event.Event) + }) + + t.Run("POST /api/v0/version succeeds", func(t *testing.T) { + t.Parallel() + resp := node.APIClient().Post("/api/v0/version", nil) + assert.Equal(t, 200, resp.StatusCode) + + assert.Len(t, resp.Resp.TransferEncoding, 1) + assert.Equal(t, "chunked", resp.Resp.TransferEncoding[0]) + + vers := struct{ Version string }{} + err := json.Unmarshal([]byte(resp.Body), &vers) + require.NoError(t, err) + assert.NotEmpty(t, vers.Version) + }) + + t.Run("pprof", func(t *testing.T) { + t.Parallel() + node := harness.NewT(t).NewNode().Init().StartDaemon() + apiClient := node.APIClient() + t.Run("mutex", func(t *testing.T) { + t.Parallel() + t.Run("setting the mutex fraction works (negative so it doesn't enable)", func(t *testing.T) { + t.Parallel() + resp := apiClient.Post("/debug/pprof-mutex/?fraction=-1", nil) + assert.Equal(t, 200, resp.StatusCode) + }) + t.Run("mutex endpoint doesn't accept a string as an argument", func(t *testing.T) { + t.Parallel() + resp := apiClient.Post("/debug/pprof-mutex/?fraction=that_is_a_string", nil) + assert.Equal(t, 400, resp.StatusCode) + }) + t.Run("mutex endpoint returns 405 on GET", func(t *testing.T) { + t.Parallel() + resp := apiClient.Get("/debug/pprof-mutex/?fraction=-1") + assert.Equal(t, 405, resp.StatusCode) + }) + }) + t.Run("block", func(t *testing.T) { + t.Parallel() + t.Run("setting the block profiler rate works (0 so it doesn't enable)", func(t *testing.T) { + t.Parallel() + resp := apiClient.Post("/debug/pprof-block/?rate=0", nil) + assert.Equal(t, 200, resp.StatusCode) + }) + t.Run("block profiler endpoint doesn't accept a string as an argument", func(t *testing.T) { + t.Parallel() + resp := apiClient.Post("/debug/pprof-block/?rate=that_is_a_string", nil) + assert.Equal(t, 400, resp.StatusCode) + }) + t.Run("block profiler endpoint returns 405 on GET", func(t *testing.T) { + t.Parallel() + resp := apiClient.Get("/debug/pprof-block/?rate=0") + assert.Equal(t, 405, resp.StatusCode) + }) + }) + }) + + t.Run("index content types", func(t *testing.T) { + t.Parallel() + h := harness.NewT(t) + node := h.NewNode().Init().StartDaemon() + + h.WriteFile("index/index.html", "

") + cid := node.IPFS("add", "-Q", "-r", filepath.Join(h.Dir, "index")).Stderr.Trimmed() + + apiClient := node.APIClient() + apiClient.TemplateData = map[string]string{"CID": cid} + + t.Run("GET index.html has correct content type", func(t *testing.T) { + t.Parallel() + res := apiClient.Get("/ipfs/{{.CID}}/") + assert.Equal(t, "text/html; charset=utf-8", res.Resp.Header.Get("Content-Type")) + }) + + t.Run("HEAD index.html has no content", func(t *testing.T) { + t.Parallel() + res := apiClient.Head("/ipfs/{{.CID}}/") + assert.Equal(t, "", res.Body) + assert.Equal(t, "", res.Resp.Header.Get("Content-Length")) + }) + }) + + t.Run("readonly API", func(t *testing.T) { + t.Parallel() + + client := node.GatewayClient() + + fileContents := "12345" + h.WriteFile("readonly/dir/test", fileContents) + cids := node.IPFS("add", "-r", "-q", filepath.Join(h.Dir, "readonly/dir")).Stdout.Lines() + + rootCID := cids[len(cids)-1] + client.TemplateData = map[string]string{"RootCID": rootCID} + + t.Run("Get IPFS directory file through readonly API succeeds", func(t *testing.T) { + t.Parallel() + resp := client.Get("/api/v0/cat?arg={{.RootCID}}/test") + assert.Equal(t, 200, resp.StatusCode) + assert.Equal(t, fileContents, resp.Body) + }) + + t.Run("refs IPFS directory file through readonly API succeeds", func(t *testing.T) { + t.Parallel() + resp := client.Get("/api/v0/refs?arg={{.RootCID}}/test") + assert.Equal(t, 200, resp.StatusCode) + }) + + t.Run("test gateway API is sanitized", func(t *testing.T) { + t.Parallel() + for _, cmd := range []string{ + "add", + "block/put", + "bootstrap", + "config", + "dag/put", + "dag/import", + "dht", + "diag", + "id", + "mount", + "name/publish", + "object/put", + "object/new", + "object/patch", + "pin", + "ping", + "repo", + "stats", + "swarm", + "file", + "update", + "bitswap", + } { + t.Run(cmd, func(t *testing.T) { + cmd := cmd + t.Parallel() + assert.Equal(t, 404, client.Get("/api/v0/"+cmd).StatusCode) + }) + } + }) + }) + + t.Run("refs/local", func(t *testing.T) { + t.Parallel() + gatewayAddr := URLStrToMultiaddr(node.GatewayURL()) + res := node.RunIPFS("--api", gatewayAddr.String(), "refs", "local") + assert.Equal(t, + `Error: invalid path "local": selected encoding not supported`, + res.Stderr.Trimmed(), + ) + }) + + t.Run("raw leaves node", func(t *testing.T) { + t.Parallel() + contents := "This is RAW!" + cid := node.IPFSAddStr(contents, "--raw-leaves") + assert.Equal(t, contents, client.Get("/ipfs/"+cid).Body) + }) + + t.Run("compact blocks", func(t *testing.T) { + t.Parallel() + block1 := "\x0a\x09\x08\x02\x12\x03\x66\x6f\x6f\x18\x03" + block2 := "\x0a\x04\x08\x02\x18\x06\x12\x24\x0a\x22\x12\x20\xcf\x92\xfd\xef\xcd\xc3\x4c\xac\x00\x9c" + + "\x8b\x05\xeb\x66\x2b\xe0\x61\x8d\xb9\xde\x55\xec\xd4\x27\x85\xe9\xec\x67\x12\xf8\xdf\x65" + + "\x12\x24\x0a\x22\x12\x20\xcf\x92\xfd\xef\xcd\xc3\x4c\xac\x00\x9c\x8b\x05\xeb\x66\x2b\xe0" + + "\x61\x8d\xb9\xde\x55\xec\xd4\x27\x85\xe9\xec\x67\x12\xf8\xdf\x65" + + node.PipeStrToIPFS(block1, "block", "put") + block2CID := node.PipeStrToIPFS(block2, "block", "put", "--cid-codec=dag-pb").Stdout.Trimmed() + + resp := client.Get("/ipfs/" + block2CID) + assert.Equal(t, 200, resp.StatusCode) + assert.Equal(t, "foofoo", resp.Body) + }) + + t.Run("verify gateway file", func(t *testing.T) { + t.Parallel() + r := regexp.MustCompile(`Gateway \(readonly\) server listening on (?P.+)\s`) + matches := r.FindStringSubmatch(node.Daemon.Stdout.String()) + ma, err := multiaddr.NewMultiaddr(matches[1]) + require.NoError(t, err) + netAddr, err := manet.ToNetAddr(ma) + require.NoError(t, err) + expURL := "http://" + netAddr.String() + + b, err := os.ReadFile(filepath.Join(node.Dir, "gateway")) + require.NoError(t, err) + + assert.Equal(t, expURL, string(b)) + }) + + t.Run("verify gateway file diallable while on unspecified", func(t *testing.T) { + t.Parallel() + node := harness.NewT(t).NewNode().Init() + node.UpdateConfig(func(cfg *config.Config) { + cfg.Addresses.Gateway = config.Strings{"/ip4/127.0.0.1/tcp/32563"} + }) + node.StartDaemon() + + b, err := os.ReadFile(filepath.Join(node.Dir, "gateway")) + require.NoError(t, err) + + assert.Equal(t, "http://127.0.0.1:32563", string(b)) + }) + + t.Run("NoFetch", func(t *testing.T) { + t.Parallel() + nodes := harness.NewT(t).NewNodes(2).Init() + node1 := nodes[0] + node2 := nodes[1] + + node1.UpdateConfig(func(cfg *config.Config) { + cfg.Gateway.NoFetch = true + }) + + nodes.StartDaemons().Connect() + + t.Run("not present", func(t *testing.T) { + cidFoo := node2.IPFSAddStr("foo") + + t.Run("not present key from node 1", func(t *testing.T) { + t.Parallel() + assert.Equal(t, 404, node1.GatewayClient().Get("/ipfs/"+cidFoo).StatusCode) + }) + + t.Run("not present IPNS key from node 1", func(t *testing.T) { + t.Parallel() + assert.Equal(t, 400, node1.GatewayClient().Get("/ipns/"+node2.PeerID().String()).StatusCode) + }) + }) + + t.Run("present", func(t *testing.T) { + cidBar := node1.IPFSAddStr("bar") + + t.Run("present key from node 1", func(t *testing.T) { + t.Parallel() + assert.Equal(t, 200, node1.GatewayClient().Get("/ipfs/"+cidBar).StatusCode) + }) + + t.Run("present IPNS key from node 1", func(t *testing.T) { + t.Parallel() + node2.IPFS("name", "publish", "/ipfs/"+cidBar) + assert.Equal(t, 200, node1.GatewayClient().Get("/ipns/"+node2.PeerID().String()).StatusCode) + + }) + }) + }) +} diff --git a/test/cli/harness/harness.go b/test/cli/harness/harness.go index dd9f38ec3..de962e1c1 100644 --- a/test/cli/harness/harness.go +++ b/test/cli/harness/harness.go @@ -119,15 +119,19 @@ func (h *Harness) TempFile() *os.File { } // WriteFile writes a file given a filename and its contents. -// The filename should be a relative path. +// The filename must be a relative path, or this panics. func (h *Harness) WriteFile(filename, contents string) { if filepath.IsAbs(filename) { log.Panicf("%s must be a relative path", filename) } absPath := filepath.Join(h.Runner.Dir, filename) - err := os.WriteFile(absPath, []byte(contents), 0644) + err := os.MkdirAll(filepath.Dir(absPath), 0777) if err != nil { - log.Panicf("writing '%s' ('%s'): %s", filename, absPath, err.Error()) + log.Panicf("creating intermediate dirs for %q: %s", filename, err.Error()) + } + err = os.WriteFile(absPath, []byte(contents), 0644) + if err != nil { + log.Panicf("writing %q (%q): %s", filename, absPath, err.Error()) } } @@ -140,8 +144,7 @@ func WaitForFile(path string, timeout time.Duration) error { for { select { case <-timer.C: - end := time.Now() - return fmt.Errorf("timeout waiting for %s after %v", path, end.Sub(start)) + return fmt.Errorf("timeout waiting for %s after %v", path, time.Since(start)) case <-ticker.C: _, err := os.Stat(path) if err == nil { diff --git a/test/cli/harness/http_client.go b/test/cli/harness/http_client.go new file mode 100644 index 000000000..83aa1bff1 --- /dev/null +++ b/test/cli/harness/http_client.go @@ -0,0 +1,116 @@ +package harness + +import ( + "io" + "net/http" + "strings" + "text/template" + "time" +) + +// HTTPClient is an HTTP client with some conveniences for testing. +// URLs are constructed from a base URL. +// The response body is buffered into a string. +// Internal errors cause panics so that tests don't need to check errors. +// The paths are evaluated as Go templates for readable string interpolation. +type HTTPClient struct { + Client *http.Client + BaseURL string + + Timeout time.Duration + TemplateData any +} + +type HTTPResponse struct { + Body string + StatusCode int + Headers http.Header + + // The raw response. The body will be closed on this response. + Resp *http.Response +} + +func (c *HTTPClient) WithHeader(k, v string) func(h *http.Request) { + return func(h *http.Request) { + h.Header.Add(k, v) + } +} + +func (c *HTTPClient) DisableRedirects() *HTTPClient { + c.Client.CheckRedirect = func(req *http.Request, via []*http.Request) error { + return http.ErrUseLastResponse + } + return c +} + +// Do executes the request unchanged. +func (c *HTTPClient) Do(req *http.Request) *HTTPResponse { + log.Debugf("making HTTP req %s to %q with headers %+v", req.Method, req.URL.String(), req.Header) + resp, err := c.Client.Do(req) + if resp != nil && resp.Body != nil { + defer resp.Body.Close() + } + if err != nil { + panic(err) + } + bodyStr, err := io.ReadAll(resp.Body) + if err != nil { + panic(err) + } + + return &HTTPResponse{ + Body: string(bodyStr), + StatusCode: resp.StatusCode, + Headers: resp.Header, + Resp: resp, + } +} + +// BuildURL constructs a request URL from the given path by interpolating the string and then appending it to the base URL. +func (c *HTTPClient) BuildURL(urlPath string) string { + sb := &strings.Builder{} + err := template.Must(template.New("test").Parse(urlPath)).Execute(sb, c.TemplateData) + if err != nil { + panic(err) + } + renderedPath := sb.String() + return c.BaseURL + renderedPath +} + +func (c *HTTPClient) Get(urlPath string, opts ...func(*http.Request)) *HTTPResponse { + req, err := http.NewRequest(http.MethodGet, c.BuildURL(urlPath), nil) + if err != nil { + panic(err) + } + for _, o := range opts { + o(req) + } + return c.Do(req) +} + +func (c *HTTPClient) Post(urlPath string, body io.Reader, opts ...func(*http.Request)) *HTTPResponse { + req, err := http.NewRequest(http.MethodPost, c.BuildURL(urlPath), body) + if err != nil { + panic(err) + } + for _, o := range opts { + o(req) + } + return c.Do(req) +} + +func (c *HTTPClient) PostStr(urlpath, body string, opts ...func(*http.Request)) *HTTPResponse { + r := strings.NewReader(body) + return c.Post(urlpath, r, opts...) +} + +func (c *HTTPClient) Head(urlPath string, opts ...func(*http.Request)) *HTTPResponse { + req, err := http.NewRequest(http.MethodHead, c.BuildURL(urlPath), nil) + if err != nil { + panic(err) + } + for _, o := range opts { + o(req) + } + return c.Do(req) +} diff --git a/test/cli/harness/node.go b/test/cli/harness/node.go index 227737eb9..26a66ddd9 100644 --- a/test/cli/harness/node.go +++ b/test/cli/harness/node.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "io" + "io/fs" "net/http" "os" "os/exec" @@ -19,6 +20,7 @@ import ( serial "github.com/ipfs/kubo/config/serialize" "github.com/libp2p/go-libp2p/core/peer" "github.com/multiformats/go-multiaddr" + manet "github.com/multiformats/go-multiaddr/net" ) var log = logging.Logger("testharness") @@ -29,14 +31,15 @@ type Node struct { ID int Dir string - APIListenAddr multiaddr.Multiaddr - SwarmAddr multiaddr.Multiaddr - EnableMDNS bool + APIListenAddr multiaddr.Multiaddr + GatewayListenAddr multiaddr.Multiaddr + SwarmAddr multiaddr.Multiaddr + EnableMDNS bool IPFSBin string Runner *Runner - daemon *RunResult + Daemon *RunResult } func BuildNode(ipfsBin, baseDir string, id int) *Node { @@ -134,11 +137,19 @@ func (n *Node) Init(ipfsArgs ...string) *Node { n.APIListenAddr = apiAddr } + if n.GatewayListenAddr == nil { + gatewayAddr, err := multiaddr.NewMultiaddr("/ip4/127.0.0.1/tcp/0") + if err != nil { + panic(err) + } + n.GatewayListenAddr = gatewayAddr + } + n.UpdateConfig(func(cfg *config.Config) { cfg.Bootstrap = []string{} cfg.Addresses.Swarm = []string{n.SwarmAddr.String()} cfg.Addresses.API = []string{n.APIListenAddr.String()} - cfg.Addresses.Gateway = []string{""} + cfg.Addresses.Gateway = []string{n.GatewayListenAddr.String()} cfg.Swarm.DisableNatPortMap = true cfg.Discovery.MDNS.Enabled = n.EnableMDNS }) @@ -159,7 +170,7 @@ func (n *Node) StartDaemon(ipfsArgs ...string) *Node { RunFunc: (*exec.Cmd).Start, }) - n.daemon = &res + n.Daemon = &res log.Debugf("node %d started, checking API", n.ID) n.WaitOnAPI() @@ -167,7 +178,7 @@ func (n *Node) StartDaemon(ipfsArgs ...string) *Node { } func (n *Node) signalAndWait(watch <-chan struct{}, signal os.Signal, t time.Duration) bool { - err := n.daemon.Cmd.Process.Signal(signal) + err := n.Daemon.Cmd.Process.Signal(signal) if err != nil { if errors.Is(err, os.ErrProcessDone) { log.Debugf("process for node %d has already finished", n.ID) @@ -187,13 +198,13 @@ func (n *Node) signalAndWait(watch <-chan struct{}, signal os.Signal, t time.Dur func (n *Node) StopDaemon() *Node { log.Debugf("stopping node %d", n.ID) - if n.daemon == nil { + if n.Daemon == nil { log.Debugf("didn't stop node %d since no daemon present", n.ID) return n } watch := make(chan struct{}, 1) go func() { - _, _ = n.daemon.Cmd.Process.Wait() + _, _ = n.Daemon.Cmd.Process.Wait() watch <- struct{}{} }() log.Debugf("signaling node %d with SIGTERM", n.ID) @@ -224,6 +235,15 @@ func (n *Node) APIAddr() multiaddr.Multiaddr { return ma } +func (n *Node) APIURL() string { + apiAddr := n.APIAddr() + netAddr, err := manet.ToNetAddr(apiAddr) + if err != nil { + panic(err) + } + return "http://" + netAddr.String() +} + func (n *Node) TryAPIAddr() (multiaddr.Multiaddr, error) { b, err := os.ReadFile(filepath.Join(n.Dir, "api")) if err != nil { @@ -305,20 +325,21 @@ func (n *Node) WaitOnAPI() *Node { log.Debugf("waiting on API for node %d", n.ID) for i := 0; i < 50; i++ { if n.checkAPI() { + log.Debugf("daemon API found, daemon stdout: %s", n.Daemon.Stdout.String()) return n } time.Sleep(400 * time.Millisecond) } - log.Panicf("node %d with peer ID %s failed to come online: \n%s\n\n%s", n.ID, n.PeerID(), n.daemon.Stderr.String(), n.daemon.Stdout.String()) + log.Panicf("node %d with peer ID %s failed to come online: \n%s\n\n%s", n.ID, n.PeerID(), n.Daemon.Stderr.String(), n.Daemon.Stdout.String()) return n } func (n *Node) IsAlive() bool { - if n.daemon == nil || n.daemon.Cmd == nil || n.daemon.Cmd.Process == nil { + if n.Daemon == nil || n.Daemon.Cmd == nil || n.Daemon.Cmd.Process == nil { return false } log.Debugf("signaling node %d daemon process for liveness check", n.ID) - err := n.daemon.Cmd.Process.Signal(syscall.Signal(0)) + err := n.Daemon.Cmd.Process.Signal(syscall.Signal(0)) if err == nil { log.Debugf("node %d daemon is alive", n.ID) return true @@ -381,3 +402,38 @@ func (n *Node) Peers() []multiaddr.Multiaddr { } return addrs } + +// GatewayURL waits for the gateway file and then returns its contents or times out. +func (n *Node) GatewayURL() string { + timer := time.NewTimer(1 * time.Second) + defer timer.Stop() + for { + select { + case <-timer.C: + panic("timeout waiting for gateway file") + default: + b, err := os.ReadFile(filepath.Join(n.Dir, "gateway")) + if err == nil { + return strings.TrimSpace(string(b)) + } + if !errors.Is(err, fs.ErrNotExist) { + panic(err) + } + time.Sleep(1 * time.Millisecond) + } + } +} + +func (n *Node) GatewayClient() *HTTPClient { + return &HTTPClient{ + Client: http.DefaultClient, + BaseURL: n.GatewayURL(), + } +} + +func (n *Node) APIClient() *HTTPClient { + return &HTTPClient{ + Client: http.DefaultClient, + BaseURL: n.APIURL(), + } +} diff --git a/test/cli/harness/nodes.go b/test/cli/harness/nodes.go index b142e3d8f..dbc7de16b 100644 --- a/test/cli/harness/nodes.go +++ b/test/cli/harness/nodes.go @@ -1,6 +1,8 @@ package harness import ( + "sync" + "github.com/multiformats/go-multiaddr" ) @@ -15,14 +17,22 @@ func (n Nodes) Init(args ...string) Nodes { } func (n Nodes) Connect() Nodes { + wg := sync.WaitGroup{} for i, node := range n { for j, otherNode := range n { if i == j { continue } - node.Connect(otherNode) + node := node + otherNode := otherNode + wg.Add(1) + go func() { + defer wg.Done() + node.Connect(otherNode) + }() } } + wg.Wait() for _, node := range n { firstPeer := node.Peers()[0] if _, err := firstPeer.ValueForProtocol(multiaddr.P_P2P); err != nil { @@ -33,9 +43,16 @@ func (n Nodes) Connect() Nodes { } func (n Nodes) StartDaemons() Nodes { + wg := sync.WaitGroup{} for _, node := range n { - node.StartDaemon() + wg.Add(1) + node := node + go func() { + defer wg.Done() + node.StartDaemon() + }() } + wg.Wait() return n } diff --git a/test/cli/testutils/strings.go b/test/cli/testutils/strings.go index 529948d3f..1fb151248 100644 --- a/test/cli/testutils/strings.go +++ b/test/cli/testutils/strings.go @@ -3,7 +3,13 @@ package testutils import ( "bufio" "fmt" + "net" + "net/netip" + "net/url" "strings" + + "github.com/multiformats/go-multiaddr" + manet "github.com/multiformats/go-multiaddr/net" ) // StrCat takes a bunch of strings or string slices @@ -51,3 +57,21 @@ func SplitLines(s string) []string { } return lines } + +// URLStrToMultiaddr converts a URL string like http://localhost:80 to a multiaddr. +func URLStrToMultiaddr(u string) multiaddr.Multiaddr { + parsedURL, err := url.Parse(u) + if err != nil { + panic(err) + } + addrPort, err := netip.ParseAddrPort(parsedURL.Host) + if err != nil { + panic(err) + } + tcpAddr := net.TCPAddrFromAddrPort(addrPort) + ma, err := manet.FromNetAddr(tcpAddr) + if err != nil { + panic(err) + } + return ma +} diff --git a/test/sharness/t0110-gateway-data/foo.block b/test/sharness/t0110-gateway-data/foo.block deleted file mode 100644 index 39c7ef60b..000000000 --- a/test/sharness/t0110-gateway-data/foo.block +++ /dev/null @@ -1,2 +0,0 @@ - - foo \ No newline at end of file diff --git a/test/sharness/t0110-gateway-data/foofoo.block b/test/sharness/t0110-gateway-data/foofoo.block deleted file mode 100644 index 9e5177b183ca963f4b15a2e8ee981f55bded1bcd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 82 zcmd;L;b4+r6H?()5>hxn>F@iqhke#C%;{!*ou>UDv3KXa&^K4qTVK9O7y5BOl{i%Z Ds+T9Z diff --git a/test/sharness/t0110-gateway.sh b/test/sharness/t0110-gateway.sh deleted file mode 100755 index 5244bd214..000000000 --- a/test/sharness/t0110-gateway.sh +++ /dev/null @@ -1,357 +0,0 @@ -#!/usr/bin/env bash -# -# Copyright (c) 2015 Matt Bell -# MIT Licensed; see the LICENSE file in this repository. -# - -test_description="Test HTTP Gateway" - -. lib/test-lib.sh - -test_init_ipfs -test_launch_ipfs_daemon - -port=$GWAY_PORT -apiport=$API_PORT - -# TODO check both 5001 and 5002. -# 5001 should have a readable gateway (part of the API) -# 5002 should have a readable gateway (using ipfs config Addresses.Gateway) -# but ideally we should only write the tests once. so maybe we need to -# define a function to test a gateway, and do so for each port. -# for now we check 5001 here as 5002 will be checked in gateway-writable. - -test_expect_success "Make a file to test with" ' - echo "Hello Worlds!" >expected && - HASH=$(ipfs add -q expected) || - test_fsh cat daemon_err -' - -test_expect_success "GET IPFS path succeeds" ' - curl -sfo actual "http://127.0.0.1:$port/ipfs/$HASH" -' - -test_expect_success "GET IPFS path with explicit ?filename succeeds with proper header" " - curl -fo actual -D actual_headers 'http://127.0.0.1:$port/ipfs/$HASH?filename=testтест.pdf' && - grep -F 'Content-Disposition: inline; filename=\"test____.pdf\"; filename*=UTF-8'\'\''test%D1%82%D0%B5%D1%81%D1%82.pdf' actual_headers -" - -test_expect_success "GET IPFS path with explicit ?filename and &download=true succeeds with proper header" " - curl -fo actual -D actual_headers 'http://127.0.0.1:$port/ipfs/$HASH?filename=testтест.mp4&download=true' && - grep -F 'Content-Disposition: attachment; filename=\"test____.mp4\"; filename*=UTF-8'\'\''test%D1%82%D0%B5%D1%81%D1%82.mp4' actual_headers -" - -# https://github.com/ipfs/go-ipfs/issues/4025#issuecomment-342250616 -test_expect_success "GET for Service Worker registration outside of an IPFS content root errors" " - curl -H 'Service-Worker: script' -svX GET 'http://127.0.0.1:$port/ipfs/$HASH?filename=sw.js' > curl_sw_out 2>&1 && - grep 'HTTP/1.1 400 Bad Request' curl_sw_out && - grep 'navigator.serviceWorker: registration is not allowed for this scope' curl_sw_out -" - -test_expect_success "GET IPFS path output looks good" ' - test_cmp expected actual && - rm actual -' - -test_expect_success "GET IPFS directory path succeeds" ' - mkdir -p dir/dirwithindex && - echo "12345" >dir/test && - echo "hello i am a webpage" >dir/dirwithindex/index.html && - ipfs add -r -q dir >actual && - HASH2=$(tail -n 1 actual) && - curl -sf "http://127.0.0.1:$port/ipfs/$HASH2" -' - -test_expect_success "GET IPFS directory file succeeds" ' - curl -sfo actual "http://127.0.0.1:$port/ipfs/$HASH2/test" -' - -test_expect_success "GET IPFS directory file output looks good" ' - test_cmp dir/test actual -' - -test_expect_success "GET IPFS directory with index.html returns redirect to add trailing slash" " - curl -sI -o response_without_slash \"http://127.0.0.1:$port/ipfs/$HASH2/dirwithindex?query=to-remember\" && - test_should_contain \"HTTP/1.1 301 Moved Permanently\" response_without_slash && - test_should_contain \"Location: /ipfs/$HASH2/dirwithindex/?query=to-remember\" response_without_slash -" - -# This enables go get to parse go-import meta tags from index.html files stored in IPFS -# https://github.com/ipfs/kubo/pull/3963 -test_expect_success "GET IPFS directory with index.html and no trailing slash returns expected output when go-get is passed" " - curl -s -o response_with_slash \"http://127.0.0.1:$port/ipfs/$HASH2/dirwithindex?go-get=1\" && - test_should_contain \"hello i am a webpage\" response_with_slash -" - -test_expect_success "GET IPFS directory with index.html and trailing slash returns expected output" " - curl -s -o response_with_slash \"http://127.0.0.1:$port/ipfs/$HASH2/dirwithindex/?query=to-remember\" && - test_should_contain \"hello i am a webpage\" response_with_slash -" - -test_expect_success "GET IPFS nonexistent file returns 404 (Not Found)" ' - test_curl_resp_http_code "http://127.0.0.1:$port/ipfs/$HASH2/pleaseDontAddMe" "HTTP/1.1 404 Not Found" -' - -test_expect_success "GET IPFS invalid CID returns 400 (Bad Request)" ' - test_curl_resp_http_code "http://127.0.0.1:$port/ipfs/QmInvalid/pleaseDontAddMe" "HTTP/1.1 400 Bad Request" -' - -# https://github.com/ipfs/go-ipfs/issues/8230 -test_expect_success "GET IPFS inlined zero-length data object returns ok code (200)" ' - curl -sD - "http://127.0.0.1:$port/ipfs/bafkqaaa" > empty_ok_response && - test_should_contain "HTTP/1.1 200 OK" empty_ok_response && - test_should_contain "Content-Length: 0" empty_ok_response -' - -# https://github.com/ipfs/kubo/issues/9238 -test_expect_success "GET IPFS inlined zero-length data object with byte range returns ok code (200)" ' - curl -sD - "http://127.0.0.1:$port/ipfs/bafkqaaa" -H "Range: bytes=0-1048575" > empty_ok_response && - test_should_contain "HTTP/1.1 200 OK" empty_ok_response && - test_should_contain "Content-Length: 0" empty_ok_response && - test_should_contain "Content-Type: text/plain" empty_ok_response -' - -test_expect_success "GET /ipfs/ipfs/{cid} returns redirect to the valid path" ' - curl -sD - "http://127.0.0.1:$port/ipfs/ipfs/bafkqaaa?query=to-remember" > response_with_double_ipfs_ns && - test_should_contain "" response_with_double_ipfs_ns && - test_should_contain "" response_with_double_ipfs_ns -' - -test_expect_success "GET invalid IPNS root returns 400 (Bad Request)" ' - test_curl_resp_http_code "http://127.0.0.1:$port/ipns/QmInvalid/pleaseDontAddMe" "HTTP/1.1 400 Bad Request" -' - -test_expect_success "GET IPNS path succeeds" ' - ipfs name publish --allow-offline "$HASH" && - PEERID=$(ipfs config Identity.PeerID) && - test_check_peerid "$PEERID" && - curl -sfo actual "http://127.0.0.1:$port/ipns/$PEERID" -' - -test_expect_success "GET IPNS path output looks good" ' - test_cmp expected actual -' - -test_expect_success "GET /ipfs/ipns/{peerid} returns redirect to the valid path" ' - PEERID=$(ipfs config Identity.PeerID) && - curl -sD - "http://127.0.0.1:$port/ipfs/ipns/${PEERID}?query=to-remember" > response_with_ipfs_ipns_ns && - test_should_contain "" response_with_ipfs_ipns_ns && - test_should_contain "" response_with_ipfs_ipns_ns -' - -test_expect_success "GET invalid IPFS path errors" ' - test_must_fail curl -sf "http://127.0.0.1:$port/ipfs/12345" -' - -test_expect_success "GET invalid path errors" ' - test_must_fail curl -sf "http://127.0.0.1:$port/12345" -' - -test_expect_success "GET /webui returns code expected" ' - test_curl_resp_http_code "http://127.0.0.1:$apiport/webui" "HTTP/1.1 302 Found" "HTTP/1.1 301 Moved Permanently" -' - -test_expect_success "GET /webui/ returns code expected" ' - test_curl_resp_http_code "http://127.0.0.1:$apiport/webui/" "HTTP/1.1 302 Found" "HTTP/1.1 301 Moved Permanently" -' - -test_expect_success "GET /logs returns logs" ' - test_expect_code 28 curl http://127.0.0.1:$apiport/logs -m1 > log_out -' - -test_expect_success "log output looks good" ' - grep "log API client connected" log_out -' - -test_expect_success "GET /api/v0/version succeeds" ' - curl -X POST -v "http://127.0.0.1:$apiport/api/v0/version" 2> version_out -' - -test_expect_success "output only has one transfer encoding header" ' - grep "Transfer-Encoding: chunked" version_out | wc -l | xargs echo > tecount_out && - echo "1" > tecount_exp && - test_cmp tecount_out tecount_exp -' - -curl_pprofmutex() { - curl -f -X POST "http://127.0.0.1:$apiport/debug/pprof-mutex/?fraction=$1" -} - -test_expect_success "set mutex fraction for pprof (negative so it doesn't enable)" ' - curl_pprofmutex -1 -' - -test_expect_success "test failure conditions of mutex pprof endpoint" ' - test_must_fail curl_pprofmutex && - test_must_fail curl_pprofmutex that_is_string && - test_must_fail curl -f -X GET "http://127.0.0.1:$apiport/debug/pprof-mutex/?fraction=-1" -' - -curl_pprofblock() { - curl -f -X POST "http://127.0.0.1:$apiport/debug/pprof-block/?rate=$1" -} - -test_expect_success "set blocking profiler rate for pprof (0 so it doesn't enable)" ' - curl_pprofblock 0 -' - -test_expect_success "test failure conditions of mutex block endpoint" ' - test_must_fail curl_pprofblock && - test_must_fail curl_pprofblock that_is_string && - test_must_fail curl -f -X GET "http://127.0.0.1:$apiport/debug/pprof-block/?rate=0" -' - -test_expect_success "setup index hash" ' - mkdir index && - echo "

" > index/index.html && - INDEXHASH=$(ipfs add -Q -r index) - echo index: $INDEXHASH -' - -test_expect_success "GET 'index.html' has correct content type" ' - curl -I "http://127.0.0.1:$port/ipfs/$INDEXHASH/" > indexout -' - -test_expect_success "output looks good" ' - grep "Content-Type: text/html" indexout -' - -test_expect_success "HEAD 'index.html' has no content" ' - curl -X HEAD --max-time 1 http://127.0.0.1:$port/ipfs/$INDEXHASH/ > output; - [ ! -s output ] -' - -# test ipfs readonly api - -test_curl_gateway_api() { - curl -sfo actual "http://127.0.0.1:$port/api/v0/$1" -} - -test_expect_success "get IPFS directory file through readonly API succeeds" ' - test_curl_gateway_api "cat?arg=$HASH2/test" -' - -test_expect_success "get IPFS directory file through readonly API output looks good" ' - test_cmp dir/test actual -' - -test_expect_success "refs IPFS directory file through readonly API succeeds" ' - test_curl_gateway_api "refs?arg=$HASH2/test" -' - -for cmd in add \ - block/put \ - bootstrap \ - config \ - dag/put \ - dag/import \ - dht \ - diag \ - id \ - mount \ - name/publish \ - object/put \ - object/new \ - object/patch \ - pin \ - ping \ - repo \ - stats \ - swarm \ - file \ - update \ - bitswap -do - test_expect_success "test gateway api is sanitized: $cmd" ' - test_curl_resp_http_code "http://127.0.0.1:$port/api/v0/$cmd" "HTTP/1.1 404 Not Found" - ' -done - -# This one is different. `local` will be interpreted as a path if the command isn't defined. -test_expect_success "test gateway api is sanitized: refs/local" ' - echo "Error: invalid path \"local\": selected encoding not supported" > refs_local_expected && - ! ipfs --api /ip4/127.0.0.1/tcp/$port refs local > refs_local_actual 2>&1 && - test_cmp refs_local_expected refs_local_actual - ' - -test_expect_success "create raw-leaves node" ' - echo "This is RAW!" > rfile && - echo "This is RAW!" | ipfs add --raw-leaves -q > rhash -' - -test_expect_success "try fetching it from gateway" ' - curl http://127.0.0.1:$port/ipfs/$(cat rhash) > ffile && - test_cmp rfile ffile -' - -test_expect_success "Add compact blocks" ' - ipfs block put ../t0110-gateway-data/foo.block && - FOO2_HASH=$(ipfs block put --cid-codec=dag-pb ../t0110-gateway-data/foofoo.block) && - printf "foofoo" > expected -' - -test_expect_success "GET compact blocks succeeds" ' - curl -o actual "http://127.0.0.1:$port/ipfs/$FOO2_HASH" && - test_cmp expected actual -' - -test_expect_success "Verify gateway file" ' - cat "$IPFS_PATH/gateway" > gateway_file_actual && - echo -n "http://$GWAY_ADDR" > gateway_daemon_actual && - test_cmp gateway_daemon_actual gateway_file_actual -' - -test_kill_ipfs_daemon - -GWPORT=32563 - -test_expect_success "Verify gateway file diallable while on unspecified" ' - ipfs config Addresses.Gateway /ip4/0.0.0.0/tcp/$GWPORT && - test_launch_ipfs_daemon && - cat "$IPFS_PATH/gateway" > gateway_file_actual && - echo -n "http://127.0.0.1:$GWPORT" > gateway_file_expected && - test_cmp gateway_file_expected gateway_file_actual -' - -test_kill_ipfs_daemon - -test_expect_success "set up iptb testbed" ' - iptb testbed create -type localipfs -count 5 -force -init && - ipfsi 0 config Addresses.Gateway /ip4/127.0.0.1/tcp/$GWPORT && - PEERID_1=$(iptb attr get 1 id) -' - -test_expect_success "set NoFetch to true in config of node 0" ' - ipfsi 0 config --bool=true Gateway.NoFetch true -' - -test_expect_success "start ipfs nodes" ' - iptb start -wait && - iptb connect 0 1 -' - -test_expect_success "try fetching not present key from node 0" ' - FOO=$(echo "foo" | ipfsi 1 add -Q) && - test_expect_code 22 curl -f "http://127.0.0.1:$GWPORT/ipfs/$FOO" -' - -test_expect_success "try fetching not present ipns key from node 0" ' - ipfsi 1 name publish /ipfs/$FOO && - test_expect_code 22 curl -f "http://127.0.0.1:$GWPORT/ipns/$PEERID_1" -' - -test_expect_success "try fetching present key from node 0" ' - BAR=$(echo "bar" | ipfsi 0 add -Q) && - curl -f "http://127.0.0.1:$GWPORT/ipfs/$BAR" -' - -test_expect_success "try fetching present ipns key from node 0" ' - ipfsi 1 name publish /ipfs/$BAR && - curl "http://127.0.0.1:$GWPORT/ipns/$PEERID_1" -' - -test_expect_success "stop testbed" ' - iptb stop -' - -test_done From 7bcca5fcd43e0c54931ff2f00a26e58c587323aa Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Sat, 14 Jan 2023 22:49:07 +0100 Subject: [PATCH 0414/1212] fix: User-Agent sent to HTTP routers See https://github.com/ipfs/go-libipfs/issues/17 and https://github.com/ipfs/go-libipfs/pull/31 --- docs/examples/kubo-as-a-library/go.mod | 15 ++--- docs/examples/kubo-as-a-library/go.sum | 62 +++++------------- go.mod | 17 +++-- go.sum | 64 +++++-------------- routing/delegated.go | 2 + test/sharness/lib/test-lib.sh | 4 +- .../t0172-content-routing-over-http.sh | 13 ++-- 7 files changed, 59 insertions(+), 118 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 040cec571..edc684831 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.18 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/go-libipfs v0.1.0 + github.com/ipfs/go-libipfs v0.2.0 github.com/ipfs/interface-go-ipfs-core v0.8.2 github.com/ipfs/kubo v0.14.0-rc1 github.com/libp2p/go-libp2p v0.24.2 @@ -17,7 +17,6 @@ require ( require ( bazil.org/fuse v0.0.0-20200117225306-7b5117fecadc // indirect github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 // indirect - github.com/Stebalien/go-bitfield v0.0.1 // indirect github.com/alecthomas/units v0.0.0-20210927113745-59d0afb8317a // indirect github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5 // indirect github.com/benbjohnson/clock v1.3.0 // indirect @@ -91,21 +90,21 @@ require ( github.com/ipfs/go-ipfs-provider v0.8.1 // indirect github.com/ipfs/go-ipfs-routing v0.3.0 // indirect github.com/ipfs/go-ipfs-util v0.0.2 // indirect - github.com/ipfs/go-ipld-cbor v0.0.5 // indirect + github.com/ipfs/go-ipld-cbor v0.0.6 // indirect github.com/ipfs/go-ipld-format v0.4.0 // indirect github.com/ipfs/go-ipld-git v0.1.1 // indirect github.com/ipfs/go-ipld-legacy v0.1.1 // indirect github.com/ipfs/go-ipns v0.3.0 // indirect github.com/ipfs/go-log v1.0.5 // indirect github.com/ipfs/go-log/v2 v2.5.1 // indirect - github.com/ipfs/go-merkledag v0.8.1 // indirect + github.com/ipfs/go-merkledag v0.9.0 // indirect github.com/ipfs/go-metrics-interface v0.0.1 // indirect github.com/ipfs/go-mfs v0.2.1 // indirect github.com/ipfs/go-namesys v0.6.0 // indirect github.com/ipfs/go-path v0.3.0 // indirect github.com/ipfs/go-peertaskqueue v0.8.0 // indirect github.com/ipfs/go-unixfs v0.4.2 // indirect - github.com/ipfs/go-unixfsnode v1.4.0 // indirect + github.com/ipfs/go-unixfsnode v1.5.1 // indirect github.com/ipfs/go-verifcid v0.0.2 // indirect github.com/ipld/edelweiss v0.2.0 // indirect github.com/ipld/go-codec-dagpb v1.5.0 // indirect @@ -142,7 +141,7 @@ require ( github.com/marten-seemann/qtls-go1-19 v0.1.1 // indirect github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect github.com/marten-seemann/webtransport-go v0.4.3 // indirect - github.com/mattn/go-isatty v0.0.16 // indirect + github.com/mattn/go-isatty v0.0.17 // indirect github.com/mattn/go-pointer v0.0.1 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/miekg/dns v1.1.50 // indirect @@ -177,7 +176,7 @@ require ( github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc // indirect - github.com/whyrusleeping/cbor-gen v0.0.0-20210219115102-f37d292932f2 // indirect + github.com/whyrusleeping/cbor-gen v0.0.0-20221220214510-0333c149dec0 // indirect github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f // indirect github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 // indirect @@ -208,7 +207,7 @@ require ( golang.org/x/sys v0.4.0 // indirect golang.org/x/text v0.5.0 // indirect golang.org/x/tools v0.3.0 // indirect - golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f // indirect + golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1 // indirect google.golang.org/grpc v1.47.0 // indirect google.golang.org/protobuf v1.28.1 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index b35804386..fa6c022f3 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -36,7 +36,6 @@ cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RX cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -dmitri.shuralyov.com/gpu/mtl v0.0.0-20201218220906-28db891af037/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU= dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4= dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU= @@ -55,7 +54,6 @@ github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWX github.com/Shopify/sarama v1.30.0/go.mod h1:zujlQQx1kzHsh4jfV1USnptCQrHAEZ2Hk8fTKCulPVs= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/Shopify/toxiproxy/v2 v2.1.6-0.20210914104332-15ea381dcdae/go.mod h1:/cvHQkZ1fst0EmZnA5dFtiQdWCNCFYzb+uE2vqVgvx0= -github.com/Stebalien/go-bitfield v0.0.1 h1:X3kbSSPUaJK60wV2hjOPZwmpljr6VGCqdq4cBLhbQBo= github.com/Stebalien/go-bitfield v0.0.1/go.mod h1:GNjFpasyUVkHMsfEOk8EFLJ9syQ6SI+XWrX9Wf2XH0s= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= @@ -150,7 +148,6 @@ github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3Ee github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= @@ -223,7 +220,6 @@ github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVB github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/frankban/quicktest v1.14.0/go.mod h1:NeW+ay9A/U67EYXNFA1nPE8e/tnQv/09mUdL/ijj8og= -github.com/frankban/quicktest v1.14.2/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps= github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= @@ -244,7 +240,6 @@ github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9 github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= -github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= @@ -491,7 +486,6 @@ github.com/ipfs/go-graphsync v0.14.1/go.mod h1:S6O/c5iXOXqDgrQgiZSgOTRUSiVvpKEhr github.com/ipfs/go-ipfs-blockstore v0.0.1/go.mod h1:d3WClOmRQKFnJ0Jz/jj/zmksX0ma1gROTlovZKBmN08= github.com/ipfs/go-ipfs-blockstore v0.1.0/go.mod h1:5aD0AvHPi7mZc6Ci1WCAhiBQu2IsfTduLl+422H6Rqw= github.com/ipfs/go-ipfs-blockstore v0.2.1/go.mod h1:jGesd8EtCM3/zPgx+qr0/feTXGUeRai6adgwC+Q+JvE= -github.com/ipfs/go-ipfs-blockstore v1.1.2/go.mod h1:w51tNR9y5+QXB0wkNcHt4O2aSZjTdqaEWaQdSxEyUOY= github.com/ipfs/go-ipfs-blockstore v1.2.0 h1:n3WTeJ4LdICWs/0VSfjHrlqpPpl6MZ+ySd3j8qz0ykw= github.com/ipfs/go-ipfs-blockstore v1.2.0/go.mod h1:eh8eTFLiINYNSNawfZOC7HOxNTxpB1PFuA5E1m/7exE= github.com/ipfs/go-ipfs-blocksutil v0.0.1 h1:Eh/H4pc1hsvhzsQoMEP3Bke/aW5P5rVM1IWFJMcGIPQ= @@ -536,8 +530,9 @@ github.com/ipfs/go-ipfs-util v0.0.2 h1:59Sswnk1MFaiq+VcaknX7aYEyGyGDAA73ilhEK2PO github.com/ipfs/go-ipfs-util v0.0.2/go.mod h1:CbPtkWJzjLdEcezDns2XYaehFVNXG9zrdrtMecczcsQ= github.com/ipfs/go-ipld-cbor v0.0.2/go.mod h1:wTBtrQZA3SoFKMVkp6cn6HMRteIB1VsmHA0AQFOn7Nc= github.com/ipfs/go-ipld-cbor v0.0.3/go.mod h1:wTBtrQZA3SoFKMVkp6cn6HMRteIB1VsmHA0AQFOn7Nc= -github.com/ipfs/go-ipld-cbor v0.0.5 h1:ovz4CHKogtG2KB/h1zUp5U0c/IzZrL435rCh5+K/5G8= github.com/ipfs/go-ipld-cbor v0.0.5/go.mod h1:BkCduEx3XBCO6t2Sfo5BaHzuok7hbhdMm9Oh8B2Ftq4= +github.com/ipfs/go-ipld-cbor v0.0.6 h1:pYuWHyvSpIsOOLw4Jy7NbBkCyzLDcl64Bf/LZW7eBQ0= +github.com/ipfs/go-ipld-cbor v0.0.6/go.mod h1:ssdxxaLJPXH7OjF5V4NSjBbcfh+evoR4ukuru0oPXMA= github.com/ipfs/go-ipld-format v0.0.1/go.mod h1:kyJtbkDALmFHv3QR6et67i35QzO3S0dCDnkOJhcZkms= github.com/ipfs/go-ipld-format v0.0.2/go.mod h1:4B6+FM2u9OJ9zCV+kSbgFAZlOrv1Hqbf0INGQgiKf9k= github.com/ipfs/go-ipld-format v0.2.0/go.mod h1:3l3C1uKoadTPbeNfrDi+xMInYKlx2Cvg1BuydPSdzQs= @@ -551,8 +546,8 @@ github.com/ipfs/go-ipld-legacy v0.1.1 h1:BvD8PEuqwBHLTKqlGFTHSwrwFOMkVESEvwIYwR2 github.com/ipfs/go-ipld-legacy v0.1.1/go.mod h1:8AyKFCjgRPsQFf15ZQgDB8Din4DML/fOmKZkkFkrIEg= github.com/ipfs/go-ipns v0.3.0 h1:ai791nTgVo+zTuq2bLvEGmWP1M0A6kGTXUsgv/Yq67A= github.com/ipfs/go-ipns v0.3.0/go.mod h1:3cLT2rbvgPZGkHJoPO1YMJeh6LtkxopCkKFcio/wE24= -github.com/ipfs/go-libipfs v0.1.0 h1:I6CrHHp4cIiqsWJPVU3QBH4BZrRWSljS2aAbA3Eg9AY= -github.com/ipfs/go-libipfs v0.1.0/go.mod h1:qX0d9h+wu53PFtCTXxdXVBakd6ZCvGDdkZUKmdLMLx0= +github.com/ipfs/go-libipfs v0.2.0 h1:MedvelDEddPYL3iDLoqAsviLeXUiwB1F2t8fkzx9/EU= +github.com/ipfs/go-libipfs v0.2.0/go.mod h1:qX0d9h+wu53PFtCTXxdXVBakd6ZCvGDdkZUKmdLMLx0= github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= github.com/ipfs/go-log v1.0.2/go.mod h1:1MNjMxe0u6xvJZgeqbJ8vdo2TKaGwZ1a0Bpza+sr2Sk= github.com/ipfs/go-log v1.0.3/go.mod h1:OsLySYkwIbiSUR/yBTdv1qPtcE4FW3WPWk/ewz9Ru+A= @@ -571,8 +566,8 @@ github.com/ipfs/go-merkledag v0.2.3/go.mod h1:SQiXrtSts3KGNmgOzMICy5c0POOpUNQLvB github.com/ipfs/go-merkledag v0.3.2/go.mod h1:fvkZNNZixVW6cKSZ/JfLlON5OlgTXNdRLz0p6QG/I2M= github.com/ipfs/go-merkledag v0.5.1/go.mod h1:cLMZXx8J08idkp5+id62iVftUQV+HlYJ3PIhDfZsjA4= github.com/ipfs/go-merkledag v0.6.0/go.mod h1:9HSEwRd5sV+lbykiYP+2NC/3o6MZbKNaa4hfNcH5iH0= -github.com/ipfs/go-merkledag v0.8.1 h1:N3yrqSre/ffvdwtHL4MXy0n7XH+VzN8DlzDrJySPa94= -github.com/ipfs/go-merkledag v0.8.1/go.mod h1:uYUlWE34GhbcTjGuUDEcdPzsEtOdnOupL64NgSRjmWI= +github.com/ipfs/go-merkledag v0.9.0 h1:DFC8qZ96Dz1hMT7dtIpcY524eFFDiEWAF8hNJHWW2pk= +github.com/ipfs/go-merkledag v0.9.0/go.mod h1:bPHqkHt5OZ0p1n3iqPeDiw2jIBkjAytRjS3WSBwjq90= github.com/ipfs/go-metrics-interface v0.0.1 h1:j+cpbjYvu4R8zbleSs36gvB7jR+wsL2fGD6n0jO4kdg= github.com/ipfs/go-metrics-interface v0.0.1/go.mod h1:6s6euYU4zowdslK0GKHmqaIZ3j/b/tL7HTWtJ4VPgWY= github.com/ipfs/go-mfs v0.2.1 h1:5jz8+ukAg/z6jTkollzxGzhkl3yxm022Za9f2nL5ab8= @@ -591,8 +586,8 @@ github.com/ipfs/go-unixfs v0.3.1/go.mod h1:h4qfQYzghiIc8ZNFKiLMFWOTzrWIAtzYQ59W/ github.com/ipfs/go-unixfs v0.4.2 h1:hdQlsHHK5tek9gC9mjGVua8xyTqC+eopGseCRcbCZNg= github.com/ipfs/go-unixfs v0.4.2/go.mod h1:L+x6JRlFE0PfyMqeoLYVOKLhn5IeZHvNT7ZI51Y9Qyc= github.com/ipfs/go-unixfsnode v1.1.2/go.mod h1:5dcE2x03pyjHk4JjamXmunTMzz+VUtqvPwZjIEkfV6s= -github.com/ipfs/go-unixfsnode v1.4.0 h1:9BUxHBXrbNi8mWHc6j+5C580WJqtVw9uoeEKn4tMhwA= -github.com/ipfs/go-unixfsnode v1.4.0/go.mod h1:qc7YFFZ8tABc58p62HnIYbUMwj9chhUuFWmxSokfePo= +github.com/ipfs/go-unixfsnode v1.5.1 h1:JcR3t5C2nM1V7PMzhJ/Qmo19NkoFIKweDSZyDx+CjkI= +github.com/ipfs/go-unixfsnode v1.5.1/go.mod h1:ed79DaG9IEuZITJVQn4U6MZDftv6I3ygUBLPfhEbHvk= github.com/ipfs/go-verifcid v0.0.1/go.mod h1:5Hrva5KBeIog4A+UpqlaIU+DEstipcJYQQZc0g37pY0= github.com/ipfs/go-verifcid v0.0.2 h1:XPnUv0XmdH+ZIhLGKg6U2vaPaRDXb9urMyNVCE7uvTs= github.com/ipfs/go-verifcid v0.0.2/go.mod h1:40cD9x1y4OWnFXbLNJYRe7MpNvWlMn3LZAG5Wb4xnPU= @@ -601,19 +596,15 @@ github.com/ipfs/interface-go-ipfs-core v0.8.2/go.mod h1:F3EcmDy53GFkF0H3iEJpfJC3 github.com/ipld/edelweiss v0.2.0 h1:KfAZBP8eeJtrLxLhi7r3N0cBCo7JmwSRhOJp3WSpNjk= github.com/ipld/edelweiss v0.2.0/go.mod h1:FJAzJRCep4iI8FOFlRriN9n0b7OuX3T/S9++NpBDmA4= github.com/ipld/go-car v0.4.0 h1:U6W7F1aKF/OJMHovnOVdst2cpQE5GhmHibQkAixgNcQ= -github.com/ipld/go-car/v2 v2.1.1/go.mod h1:+2Yvf0Z3wzkv7NeI69i8tuZ+ft7jyjPYIWZzeVNeFcI= -github.com/ipld/go-car/v2 v2.4.0 h1:8jI6/iKlyLqRZzLz31jFWTqKvslaVzFsin305sOuqNQ= +github.com/ipld/go-car/v2 v2.5.1 h1:U2ux9JS23upEgrJScW8VQuxmE94560kYxj9CQUpcfmk= github.com/ipld/go-codec-dagpb v1.3.0/go.mod h1:ga4JTU3abYApDC3pZ00BC2RSvC3qfBb9MSJkMLSwnhA= github.com/ipld/go-codec-dagpb v1.5.0 h1:RspDRdsJpLfgCI0ONhTAnbHdySGD4t+LHSPK4X1+R0k= github.com/ipld/go-codec-dagpb v1.5.0/go.mod h1:0yRIutEFD8o1DGVqw4RSHh+BUTlJA9XWldxaaWR/o4g= 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.14.0/go.mod h1:9ASQLwUFLptCov6lIYc70GRB4V7UTyLD0IJtrDJe6ZM= github.com/ipld/go-ipld-prime v0.14.1/go.mod h1:QcE4Y9n/ZZr8Ijg5bGPT0GqYWgZ1704nH0RDcQtgTP0= -github.com/ipld/go-ipld-prime v0.16.0/go.mod h1:axSCuOCBPqrH+gvXr2w9uAOulJqBPhHPT2PjoiiU1qA= github.com/ipld/go-ipld-prime v0.19.0 h1:5axC7rJmPc17Emw6TelxGwnzALk0PdupZ2oj2roDj04= github.com/ipld/go-ipld-prime v0.19.0/go.mod h1:Q9j3BaVXwaA3o5JUDNvptDDr/x8+F7FG6XJ8WI3ILg4= -github.com/ipld/go-ipld-prime/storage/bsadapter v0.0.0-20211210234204-ce2a1c70cd73/go.mod h1:2PJ0JgxyB08t0b2WKrcuqI3di0V+5n6RS/LTUJhkoxY= 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= @@ -665,7 +656,6 @@ github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47e github.com/klauspost/compress v1.15.12 h1:YClS/PImqYbn+UILDnqxQCZ3RehC9N318SU3kElDUEM= github.com/klauspost/compress v1.15.12/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= 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/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.1 h1:U33DW0aiEj633gHYw3LoDNfkDiYnE5Q8M/TKJn2f2jI= github.com/klauspost/cpuid/v2 v2.2.1/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= @@ -930,8 +920,8 @@ github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hd github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= +github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-pointer v0.0.1 h1:n+XhsuGeVO6MEAp7xyEukFINEa+Quek5psIR/ylA6o0= github.com/mattn/go-pointer v0.0.1/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= @@ -1022,8 +1012,6 @@ github.com/multiformats/go-multibase v0.0.3/go.mod h1:5+1R4eQrT3PkYZ24C3W2Ue2tPw github.com/multiformats/go-multibase v0.1.1 h1:3ASCDsuLX8+j4kx58qnJ4YFq/JWTJpCyDW27ztsVTOI= github.com/multiformats/go-multibase v0.1.1/go.mod h1:ZEjHE+IsUrgp5mhlEAYjMtZwK1k4haNkcaPg9aoe1a8= github.com/multiformats/go-multicodec v0.3.0/go.mod h1:qGGaQmioCDh+TeFOnxrbU0DaIPw8yFgAZgFG0V7p1qQ= -github.com/multiformats/go-multicodec v0.3.1-0.20210902112759-1539a079fd61/go.mod h1:1Hj/eHRaVWSXiSNNfcEPcwZleTmdNP81xlxDLnWU9GQ= -github.com/multiformats/go-multicodec v0.3.1-0.20211210143421-a526f306ed2c/go.mod h1:1Hj/eHRaVWSXiSNNfcEPcwZleTmdNP81xlxDLnWU9GQ= github.com/multiformats/go-multicodec v0.7.0 h1:rTUjGOwjlhGHbEMbPoSUJowG1spZTVsITRANCjKTUAQ= github.com/multiformats/go-multicodec v0.7.0/go.mod h1:GUC8upxSBE4oG+q3kWZRw/+6yC1BqO550bjhWsJbZlw= github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= @@ -1108,7 +1096,6 @@ github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtP 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= github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 h1:1/WtZae0yGtPq+TI6+Tv1WTxkukpXeMlviSxvL7SRgk= -github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9/go.mod h1:x3N5drFsm2uilKKuuYo6LdyD8vZAW55sH/9w+pbo1sw= github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pierrec/lz4 v2.6.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= @@ -1174,8 +1161,6 @@ github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6L github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= -github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= -github.com/rs/zerolog v1.21.0/go.mod h1:ZPhntP/xmq1nnND05hhpAh2QMhSsA4UN3MGZ6O2J3hM= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd/go.mod h1:hPqNNc0+uJM6H+SuU8sEs5K5IQeKccPqeSjfgcKGgPk= @@ -1284,10 +1269,9 @@ github.com/warpfork/go-wish v0.0.0-20200122115046-b9ea61034e4a/go.mod h1:x6AKhvS github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc h1:BCPnHtcboadS0DvysUuJXZ4lWVv5Bh5i7+tbIyi+ck4= github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc/go.mod h1:r45hJU7yEoA81k6MWNhpMj/kms0n14dkzkxYHoB96UM= github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11 h1:5HZfQkwe0mIfyDmc1Em5GqlNRzcdtlv4HTNmdpt7XH0= -github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11/go.mod h1:Wlo/SzPmxVp6vXpGt/zaXhHH0fn4IxgqZc82aKg6bpQ= github.com/whyrusleeping/cbor-gen v0.0.0-20200123233031-1cdf64d27158/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI= -github.com/whyrusleeping/cbor-gen v0.0.0-20210219115102-f37d292932f2 h1:bsUlNhdmbtlfdLVXAVfuvKQ01RnWAM09TVrJkI7NZs4= -github.com/whyrusleeping/cbor-gen v0.0.0-20210219115102-f37d292932f2/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= +github.com/whyrusleeping/cbor-gen v0.0.0-20221220214510-0333c149dec0 h1:obKzQ1ey5AJg5NKjgtTo/CKwLImVP4ETLRcsmzFJ4Qw= +github.com/whyrusleeping/cbor-gen v0.0.0-20221220214510-0333c149dec0/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f h1:jQa4QT2UP9WYv2nzyawpKMOCl+Z/jW7djv2/J50lj9E= github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f/go.mod h1:p9UJB6dDgdPgMJZs7UjUOdulKyRr9fqkS+6JKAInPy8= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 h1:EKhdznlJHPMoKr0XTrX+IlJs1LH3lyx2nfr1dOlZ79k= @@ -1327,7 +1311,6 @@ go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/otel v0.20.0/go.mod h1:Y3ugLH2oa81t5QO+Lty+zXf8zC9L26ax4Nzoxm/dooo= go.opentelemetry.io/otel v1.7.0 h1:Z2lA3Tdch0iDcrhJXDIlC94XE+bxok1F9B+4Lz/lGsM= go.opentelemetry.io/otel v1.7.0/go.mod h1:5BdUoMIz5WEs0vt0CUEMtSSaTSHBBVwrhnz7+nrD5xk= go.opentelemetry.io/otel/exporters/jaeger v1.7.0 h1:wXgjiRldljksZkZrldGVe6XrG9u3kYDyQmkZwmm5dI0= @@ -1344,12 +1327,8 @@ go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.7.0 h1:8hPcgCg0rUJiKE6V go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.7.0/go.mod h1:K4GDXPY6TjUiwbOh+DkKaEdCF8y+lvMoM6SeAPyfCCM= go.opentelemetry.io/otel/exporters/zipkin v1.7.0 h1:X0FZj+kaIdLi29UiyrEGDhRTYsEXj9GdEW5Y39UQFEE= go.opentelemetry.io/otel/exporters/zipkin v1.7.0/go.mod h1:9YBXeOMFLQGwNEjsxMRiWPGoJX83usGMhbCmxUbNe5I= -go.opentelemetry.io/otel/metric v0.20.0/go.mod h1:598I5tYlH1vzBjn+BTuhzTCSb/9debfNp6R3s7Pr1eU= -go.opentelemetry.io/otel/oteltest v0.20.0/go.mod h1:L7bgKf9ZB7qCwT9Up7i9/pn0PWIa9FqQ2IQ8LoxiGnw= -go.opentelemetry.io/otel/sdk v0.20.0/go.mod h1:g/IcepuwNsoiX5Byy2nNV0ySUF1em498m7hBWC279Yc= go.opentelemetry.io/otel/sdk v1.7.0 h1:4OmStpcKVOfvDOgCt7UriAPtKolwIhxpnSNI/yK+1B0= go.opentelemetry.io/otel/sdk v1.7.0/go.mod h1:uTEOTwaqIVuTGiJN7ii13Ibp75wJmYUDe374q6cZwUU= -go.opentelemetry.io/otel/trace v0.20.0/go.mod h1:6GjCW8zgDjwGHGa6GkyeB8+/5vjT16gUEi0Nf1iBdgw= go.opentelemetry.io/otel/trace v1.7.0 h1:O37Iogk1lEkMRXewVtZ1BBTVn5JEp8GrJvP92bJqC6o= go.opentelemetry.io/otel/trace v1.7.0/go.mod h1:fzLSB9nqR2eXzxPXb2JW9IKE+ScyXA48yyE4TNvoHqU= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= @@ -1374,7 +1353,6 @@ go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/ go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= -go.uber.org/multierr v1.7.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= @@ -1418,15 +1396,12 @@ golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210506145944-38f3c27a63bf/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= -golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= -golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210920023735-84f357641f63/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.3.0 h1:a06MkbcxBrEFc0w0QIZWXrH/9cCX6KJyWbBOIwAn+7A= golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= @@ -1434,7 +1409,6 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20210615023648-acb5c1269671/go.mod h1:DVyR6MI7P4kEQgvZJSj1fQGrWIi2RzIrfYWycwheUAc= golang.org/x/exp v0.0.0-20221205204356-47842c84f3db h1:D/cFflL63o2KSLJIwjlcIt8PR064j/xsmdEJL/YvY/o= golang.org/x/exp v0.0.0-20221205204356-47842c84f3db/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= @@ -1452,12 +1426,10 @@ golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPI golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= -golang.org/x/mobile v0.0.0-20201217150744-e6ae53a27f4f/go.mod h1:skQtrUTUwhdJvXM/2KKJzY8pDgNr9I/FOMqDVRPBUS4= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.1.1-0.20191209134235-331c550502dd/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= @@ -1623,7 +1595,6 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210426080607-c94f62235c83/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1683,7 +1654,6 @@ golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapK golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200117012304-6edc0a871e69/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= @@ -1705,7 +1675,6 @@ golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= @@ -1715,8 +1684,8 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f h1:uF6paiQQebLeSXkrTqHqz0MXhXXS1KgF41eUdBNvxK0= -golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y= @@ -1870,7 +1839,6 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= lukechampine.com/blake3 v1.1.6/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= lukechampine.com/blake3 v1.1.7 h1:GgRMhmdsuK8+ii6UZFDL8Nb+VyMwadAgcJyfYHxG6n0= lukechampine.com/blake3 v1.1.7/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= diff --git a/go.mod b/go.mod index 238774683..b837fa504 100644 --- a/go.mod +++ b/go.mod @@ -49,10 +49,10 @@ require ( github.com/ipfs/go-ipld-git v0.1.1 github.com/ipfs/go-ipld-legacy v0.1.1 github.com/ipfs/go-ipns v0.3.0 - github.com/ipfs/go-libipfs v0.1.0 + github.com/ipfs/go-libipfs v0.2.0 github.com/ipfs/go-log v1.0.5 github.com/ipfs/go-log/v2 v2.5.1 - github.com/ipfs/go-merkledag v0.8.1 + github.com/ipfs/go-merkledag v0.9.0 github.com/ipfs/go-metrics-interface v0.0.1 github.com/ipfs/go-metrics-prometheus v0.0.2 github.com/ipfs/go-mfs v0.2.1 @@ -60,11 +60,11 @@ require ( github.com/ipfs/go-path v0.3.0 github.com/ipfs/go-pinning-service-http-client v0.1.2 github.com/ipfs/go-unixfs v0.4.2 - github.com/ipfs/go-unixfsnode v1.4.0 + github.com/ipfs/go-unixfsnode v1.5.1 github.com/ipfs/go-verifcid v0.0.2 github.com/ipfs/interface-go-ipfs-core v0.8.2 github.com/ipld/go-car v0.4.0 - github.com/ipld/go-car/v2 v2.4.0 + github.com/ipld/go-car/v2 v2.5.1 github.com/ipld/go-codec-dagpb v1.5.0 github.com/ipld/go-ipld-prime v0.19.0 github.com/jbenet/go-random v0.0.0-20190219211222-123a90aedc0c @@ -118,7 +118,6 @@ require ( require ( github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 // indirect github.com/Kubuxu/go-os-helper v0.0.1 // indirect - github.com/Stebalien/go-bitfield v0.0.1 // indirect github.com/alecthomas/units v0.0.0-20210927113745-59d0afb8317a // indirect github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5 // indirect github.com/beorn7/perks v1.0.1 // indirect @@ -162,7 +161,7 @@ require ( github.com/ipfs/go-ipfs-delay v0.0.1 // indirect github.com/ipfs/go-ipfs-ds-help v1.1.0 // indirect github.com/ipfs/go-ipfs-pq v0.0.2 // indirect - github.com/ipfs/go-ipld-cbor v0.0.5 // indirect + github.com/ipfs/go-ipld-cbor v0.0.6 // indirect github.com/ipfs/go-peertaskqueue v0.8.0 // indirect github.com/ipld/edelweiss v0.2.0 // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect @@ -190,7 +189,7 @@ require ( github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect github.com/marten-seemann/webtransport-go v0.4.3 // indirect github.com/mattn/go-colorable v0.1.4 // indirect - github.com/mattn/go-isatty v0.0.16 // indirect + github.com/mattn/go-isatty v0.0.17 // indirect github.com/mattn/go-pointer v0.0.1 // indirect github.com/mattn/go-runewidth v0.0.4 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect @@ -221,7 +220,7 @@ require ( github.com/texttheater/golang-levenshtein v0.0.0-20180516184445-d188e65d659e // indirect github.com/ucarion/urlpath v0.0.0-20200424170820-7ccc79b76bbb // indirect github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc // indirect - github.com/whyrusleeping/cbor-gen v0.0.0-20200710004633-5379fc63235d // indirect + github.com/whyrusleeping/cbor-gen v0.0.0-20221220214510-0333c149dec0 // indirect github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f // indirect github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect github.com/whyrusleeping/timecache v0.0.0-20160911033111-cfcb2f1abfee // indirect @@ -238,7 +237,7 @@ require ( golang.org/x/term v0.4.0 // indirect golang.org/x/text v0.5.0 // indirect golang.org/x/tools v0.3.0 // indirect - golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f // indirect + golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/appengine v1.6.6 // indirect google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1 // indirect google.golang.org/grpc v1.46.0 // indirect diff --git a/go.sum b/go.sum index 605ea36c3..6274ef85b 100644 --- a/go.sum +++ b/go.sum @@ -38,7 +38,6 @@ contrib.go.opencensus.io/exporter/prometheus v0.4.0 h1:0QfIkj9z/iVZgK31D9H9ohjjI contrib.go.opencensus.io/exporter/prometheus v0.4.0/go.mod h1:o7cosnyfuPVK0tB8q0QmaQNhGnptITnPQB+z1+qeFB0= dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -dmitri.shuralyov.com/gpu/mtl v0.0.0-20201218220906-28db891af037/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU= dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4= dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU= @@ -58,7 +57,6 @@ github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWX github.com/Shopify/sarama v1.30.0/go.mod h1:zujlQQx1kzHsh4jfV1USnptCQrHAEZ2Hk8fTKCulPVs= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/Shopify/toxiproxy/v2 v2.1.6-0.20210914104332-15ea381dcdae/go.mod h1:/cvHQkZ1fst0EmZnA5dFtiQdWCNCFYzb+uE2vqVgvx0= -github.com/Stebalien/go-bitfield v0.0.1 h1:X3kbSSPUaJK60wV2hjOPZwmpljr6VGCqdq4cBLhbQBo= github.com/Stebalien/go-bitfield v0.0.1/go.mod h1:GNjFpasyUVkHMsfEOk8EFLJ9syQ6SI+XWrX9Wf2XH0s= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= @@ -155,7 +153,6 @@ github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3Ee github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/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.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= @@ -235,7 +232,6 @@ github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVB github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/frankban/quicktest v1.14.0/go.mod h1:NeW+ay9A/U67EYXNFA1nPE8e/tnQv/09mUdL/ijj8og= -github.com/frankban/quicktest v1.14.2/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps= github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= @@ -261,7 +257,6 @@ github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA= github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= -github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= @@ -509,7 +504,6 @@ github.com/ipfs/go-graphsync v0.14.1/go.mod h1:S6O/c5iXOXqDgrQgiZSgOTRUSiVvpKEhr github.com/ipfs/go-ipfs-blockstore v0.0.1/go.mod h1:d3WClOmRQKFnJ0Jz/jj/zmksX0ma1gROTlovZKBmN08= github.com/ipfs/go-ipfs-blockstore v0.1.0/go.mod h1:5aD0AvHPi7mZc6Ci1WCAhiBQu2IsfTduLl+422H6Rqw= github.com/ipfs/go-ipfs-blockstore v0.2.1/go.mod h1:jGesd8EtCM3/zPgx+qr0/feTXGUeRai6adgwC+Q+JvE= -github.com/ipfs/go-ipfs-blockstore v1.1.2/go.mod h1:w51tNR9y5+QXB0wkNcHt4O2aSZjTdqaEWaQdSxEyUOY= github.com/ipfs/go-ipfs-blockstore v1.2.0 h1:n3WTeJ4LdICWs/0VSfjHrlqpPpl6MZ+ySd3j8qz0ykw= github.com/ipfs/go-ipfs-blockstore v1.2.0/go.mod h1:eh8eTFLiINYNSNawfZOC7HOxNTxpB1PFuA5E1m/7exE= github.com/ipfs/go-ipfs-blocksutil v0.0.1 h1:Eh/H4pc1hsvhzsQoMEP3Bke/aW5P5rVM1IWFJMcGIPQ= @@ -558,8 +552,9 @@ github.com/ipfs/go-ipfs-util v0.0.2 h1:59Sswnk1MFaiq+VcaknX7aYEyGyGDAA73ilhEK2PO github.com/ipfs/go-ipfs-util v0.0.2/go.mod h1:CbPtkWJzjLdEcezDns2XYaehFVNXG9zrdrtMecczcsQ= github.com/ipfs/go-ipld-cbor v0.0.2/go.mod h1:wTBtrQZA3SoFKMVkp6cn6HMRteIB1VsmHA0AQFOn7Nc= github.com/ipfs/go-ipld-cbor v0.0.3/go.mod h1:wTBtrQZA3SoFKMVkp6cn6HMRteIB1VsmHA0AQFOn7Nc= -github.com/ipfs/go-ipld-cbor v0.0.5 h1:ovz4CHKogtG2KB/h1zUp5U0c/IzZrL435rCh5+K/5G8= github.com/ipfs/go-ipld-cbor v0.0.5/go.mod h1:BkCduEx3XBCO6t2Sfo5BaHzuok7hbhdMm9Oh8B2Ftq4= +github.com/ipfs/go-ipld-cbor v0.0.6 h1:pYuWHyvSpIsOOLw4Jy7NbBkCyzLDcl64Bf/LZW7eBQ0= +github.com/ipfs/go-ipld-cbor v0.0.6/go.mod h1:ssdxxaLJPXH7OjF5V4NSjBbcfh+evoR4ukuru0oPXMA= github.com/ipfs/go-ipld-format v0.0.1/go.mod h1:kyJtbkDALmFHv3QR6et67i35QzO3S0dCDnkOJhcZkms= github.com/ipfs/go-ipld-format v0.0.2/go.mod h1:4B6+FM2u9OJ9zCV+kSbgFAZlOrv1Hqbf0INGQgiKf9k= github.com/ipfs/go-ipld-format v0.2.0/go.mod h1:3l3C1uKoadTPbeNfrDi+xMInYKlx2Cvg1BuydPSdzQs= @@ -573,8 +568,8 @@ github.com/ipfs/go-ipld-legacy v0.1.1 h1:BvD8PEuqwBHLTKqlGFTHSwrwFOMkVESEvwIYwR2 github.com/ipfs/go-ipld-legacy v0.1.1/go.mod h1:8AyKFCjgRPsQFf15ZQgDB8Din4DML/fOmKZkkFkrIEg= github.com/ipfs/go-ipns v0.3.0 h1:ai791nTgVo+zTuq2bLvEGmWP1M0A6kGTXUsgv/Yq67A= github.com/ipfs/go-ipns v0.3.0/go.mod h1:3cLT2rbvgPZGkHJoPO1YMJeh6LtkxopCkKFcio/wE24= -github.com/ipfs/go-libipfs v0.1.0 h1:I6CrHHp4cIiqsWJPVU3QBH4BZrRWSljS2aAbA3Eg9AY= -github.com/ipfs/go-libipfs v0.1.0/go.mod h1:qX0d9h+wu53PFtCTXxdXVBakd6ZCvGDdkZUKmdLMLx0= +github.com/ipfs/go-libipfs v0.2.0 h1:MedvelDEddPYL3iDLoqAsviLeXUiwB1F2t8fkzx9/EU= +github.com/ipfs/go-libipfs v0.2.0/go.mod h1:qX0d9h+wu53PFtCTXxdXVBakd6ZCvGDdkZUKmdLMLx0= github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= github.com/ipfs/go-log v1.0.2/go.mod h1:1MNjMxe0u6xvJZgeqbJ8vdo2TKaGwZ1a0Bpza+sr2Sk= github.com/ipfs/go-log v1.0.3/go.mod h1:OsLySYkwIbiSUR/yBTdv1qPtcE4FW3WPWk/ewz9Ru+A= @@ -593,8 +588,8 @@ github.com/ipfs/go-merkledag v0.2.3/go.mod h1:SQiXrtSts3KGNmgOzMICy5c0POOpUNQLvB github.com/ipfs/go-merkledag v0.3.2/go.mod h1:fvkZNNZixVW6cKSZ/JfLlON5OlgTXNdRLz0p6QG/I2M= github.com/ipfs/go-merkledag v0.5.1/go.mod h1:cLMZXx8J08idkp5+id62iVftUQV+HlYJ3PIhDfZsjA4= github.com/ipfs/go-merkledag v0.6.0/go.mod h1:9HSEwRd5sV+lbykiYP+2NC/3o6MZbKNaa4hfNcH5iH0= -github.com/ipfs/go-merkledag v0.8.1 h1:N3yrqSre/ffvdwtHL4MXy0n7XH+VzN8DlzDrJySPa94= -github.com/ipfs/go-merkledag v0.8.1/go.mod h1:uYUlWE34GhbcTjGuUDEcdPzsEtOdnOupL64NgSRjmWI= +github.com/ipfs/go-merkledag v0.9.0 h1:DFC8qZ96Dz1hMT7dtIpcY524eFFDiEWAF8hNJHWW2pk= +github.com/ipfs/go-merkledag v0.9.0/go.mod h1:bPHqkHt5OZ0p1n3iqPeDiw2jIBkjAytRjS3WSBwjq90= github.com/ipfs/go-metrics-interface v0.0.1 h1:j+cpbjYvu4R8zbleSs36gvB7jR+wsL2fGD6n0jO4kdg= github.com/ipfs/go-metrics-interface v0.0.1/go.mod h1:6s6euYU4zowdslK0GKHmqaIZ3j/b/tL7HTWtJ4VPgWY= github.com/ipfs/go-metrics-prometheus v0.0.2 h1:9i2iljLg12S78OhC6UAiXi176xvQGiZaGVF1CUVdE+s= @@ -617,8 +612,8 @@ github.com/ipfs/go-unixfs v0.3.1/go.mod h1:h4qfQYzghiIc8ZNFKiLMFWOTzrWIAtzYQ59W/ github.com/ipfs/go-unixfs v0.4.2 h1:hdQlsHHK5tek9gC9mjGVua8xyTqC+eopGseCRcbCZNg= github.com/ipfs/go-unixfs v0.4.2/go.mod h1:L+x6JRlFE0PfyMqeoLYVOKLhn5IeZHvNT7ZI51Y9Qyc= github.com/ipfs/go-unixfsnode v1.1.2/go.mod h1:5dcE2x03pyjHk4JjamXmunTMzz+VUtqvPwZjIEkfV6s= -github.com/ipfs/go-unixfsnode v1.4.0 h1:9BUxHBXrbNi8mWHc6j+5C580WJqtVw9uoeEKn4tMhwA= -github.com/ipfs/go-unixfsnode v1.4.0/go.mod h1:qc7YFFZ8tABc58p62HnIYbUMwj9chhUuFWmxSokfePo= +github.com/ipfs/go-unixfsnode v1.5.1 h1:JcR3t5C2nM1V7PMzhJ/Qmo19NkoFIKweDSZyDx+CjkI= +github.com/ipfs/go-unixfsnode v1.5.1/go.mod h1:ed79DaG9IEuZITJVQn4U6MZDftv6I3ygUBLPfhEbHvk= github.com/ipfs/go-verifcid v0.0.1/go.mod h1:5Hrva5KBeIog4A+UpqlaIU+DEstipcJYQQZc0g37pY0= github.com/ipfs/go-verifcid v0.0.2 h1:XPnUv0XmdH+ZIhLGKg6U2vaPaRDXb9urMyNVCE7uvTs= github.com/ipfs/go-verifcid v0.0.2/go.mod h1:40cD9x1y4OWnFXbLNJYRe7MpNvWlMn3LZAG5Wb4xnPU= @@ -628,21 +623,17 @@ github.com/ipld/edelweiss v0.2.0 h1:KfAZBP8eeJtrLxLhi7r3N0cBCo7JmwSRhOJp3WSpNjk= github.com/ipld/edelweiss v0.2.0/go.mod h1:FJAzJRCep4iI8FOFlRriN9n0b7OuX3T/S9++NpBDmA4= github.com/ipld/go-car v0.4.0 h1:U6W7F1aKF/OJMHovnOVdst2cpQE5GhmHibQkAixgNcQ= github.com/ipld/go-car v0.4.0/go.mod h1:Uslcn4O9cBKK9wqHm/cLTFacg6RAPv6LZx2mxd2Ypl4= -github.com/ipld/go-car/v2 v2.1.1/go.mod h1:+2Yvf0Z3wzkv7NeI69i8tuZ+ft7jyjPYIWZzeVNeFcI= -github.com/ipld/go-car/v2 v2.4.0 h1:8jI6/iKlyLqRZzLz31jFWTqKvslaVzFsin305sOuqNQ= -github.com/ipld/go-car/v2 v2.4.0/go.mod h1:zjpRf0Jew9gHqSvjsKVyoq9OY9SWoEKdYCQUKVaaPT0= +github.com/ipld/go-car/v2 v2.5.1 h1:U2ux9JS23upEgrJScW8VQuxmE94560kYxj9CQUpcfmk= +github.com/ipld/go-car/v2 v2.5.1/go.mod h1:jKjGOqoCj5zn6KjnabD6JbnCsMntqU2hLiU6baZVO3E= github.com/ipld/go-codec-dagpb v1.3.0/go.mod h1:ga4JTU3abYApDC3pZ00BC2RSvC3qfBb9MSJkMLSwnhA= github.com/ipld/go-codec-dagpb v1.5.0 h1:RspDRdsJpLfgCI0ONhTAnbHdySGD4t+LHSPK4X1+R0k= github.com/ipld/go-codec-dagpb v1.5.0/go.mod h1:0yRIutEFD8o1DGVqw4RSHh+BUTlJA9XWldxaaWR/o4g= 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.14.0/go.mod h1:9ASQLwUFLptCov6lIYc70GRB4V7UTyLD0IJtrDJe6ZM= github.com/ipld/go-ipld-prime v0.14.1/go.mod h1:QcE4Y9n/ZZr8Ijg5bGPT0GqYWgZ1704nH0RDcQtgTP0= -github.com/ipld/go-ipld-prime v0.16.0/go.mod h1:axSCuOCBPqrH+gvXr2w9uAOulJqBPhHPT2PjoiiU1qA= github.com/ipld/go-ipld-prime v0.19.0 h1:5axC7rJmPc17Emw6TelxGwnzALk0PdupZ2oj2roDj04= github.com/ipld/go-ipld-prime v0.19.0/go.mod h1:Q9j3BaVXwaA3o5JUDNvptDDr/x8+F7FG6XJ8WI3ILg4= github.com/ipld/go-ipld-prime/storage/bsadapter v0.0.0-20211210234204-ce2a1c70cd73 h1:TsyATB2ZRRQGTwafJdgEUQkmjOExRV0DNokcihZxbnQ= -github.com/ipld/go-ipld-prime/storage/bsadapter v0.0.0-20211210234204-ce2a1c70cd73/go.mod h1:2PJ0JgxyB08t0b2WKrcuqI3di0V+5n6RS/LTUJhkoxY= 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= @@ -695,7 +686,6 @@ github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47e github.com/klauspost/compress v1.15.12 h1:YClS/PImqYbn+UILDnqxQCZ3RehC9N318SU3kElDUEM= github.com/klauspost/compress v1.15.12/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= 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/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.1 h1:U33DW0aiEj633gHYw3LoDNfkDiYnE5Q8M/TKJn2f2jI= github.com/klauspost/cpuid/v2 v2.2.1/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= @@ -970,8 +960,8 @@ github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hd github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= +github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-pointer v0.0.1 h1:n+XhsuGeVO6MEAp7xyEukFINEa+Quek5psIR/ylA6o0= github.com/mattn/go-pointer v0.0.1/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= @@ -1066,8 +1056,6 @@ github.com/multiformats/go-multibase v0.0.3/go.mod h1:5+1R4eQrT3PkYZ24C3W2Ue2tPw github.com/multiformats/go-multibase v0.1.1 h1:3ASCDsuLX8+j4kx58qnJ4YFq/JWTJpCyDW27ztsVTOI= github.com/multiformats/go-multibase v0.1.1/go.mod h1:ZEjHE+IsUrgp5mhlEAYjMtZwK1k4haNkcaPg9aoe1a8= github.com/multiformats/go-multicodec v0.3.0/go.mod h1:qGGaQmioCDh+TeFOnxrbU0DaIPw8yFgAZgFG0V7p1qQ= -github.com/multiformats/go-multicodec v0.3.1-0.20210902112759-1539a079fd61/go.mod h1:1Hj/eHRaVWSXiSNNfcEPcwZleTmdNP81xlxDLnWU9GQ= -github.com/multiformats/go-multicodec v0.3.1-0.20211210143421-a526f306ed2c/go.mod h1:1Hj/eHRaVWSXiSNNfcEPcwZleTmdNP81xlxDLnWU9GQ= github.com/multiformats/go-multicodec v0.7.0 h1:rTUjGOwjlhGHbEMbPoSUJowG1spZTVsITRANCjKTUAQ= github.com/multiformats/go-multicodec v0.7.0/go.mod h1:GUC8upxSBE4oG+q3kWZRw/+6yC1BqO550bjhWsJbZlw= github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= @@ -1152,7 +1140,6 @@ github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtP 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= github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 h1:1/WtZae0yGtPq+TI6+Tv1WTxkukpXeMlviSxvL7SRgk= -github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9/go.mod h1:x3N5drFsm2uilKKuuYo6LdyD8vZAW55sH/9w+pbo1sw= github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pierrec/lz4 v2.6.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= @@ -1226,8 +1213,6 @@ github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBO github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= -github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= -github.com/rs/zerolog v1.21.0/go.mod h1:ZPhntP/xmq1nnND05hhpAh2QMhSsA4UN3MGZ6O2J3hM= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd/go.mod h1:hPqNNc0+uJM6H+SuU8sEs5K5IQeKccPqeSjfgcKGgPk= @@ -1341,10 +1326,9 @@ github.com/warpfork/go-wish v0.0.0-20200122115046-b9ea61034e4a/go.mod h1:x6AKhvS github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc h1:BCPnHtcboadS0DvysUuJXZ4lWVv5Bh5i7+tbIyi+ck4= github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc/go.mod h1:r45hJU7yEoA81k6MWNhpMj/kms0n14dkzkxYHoB96UM= github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11 h1:5HZfQkwe0mIfyDmc1Em5GqlNRzcdtlv4HTNmdpt7XH0= -github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11/go.mod h1:Wlo/SzPmxVp6vXpGt/zaXhHH0fn4IxgqZc82aKg6bpQ= github.com/whyrusleeping/cbor-gen v0.0.0-20200123233031-1cdf64d27158/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI= -github.com/whyrusleeping/cbor-gen v0.0.0-20200710004633-5379fc63235d h1:wSxKhvbN7kUoP0sfRS+w2tWr45qlU8409i94hHLOT8w= -github.com/whyrusleeping/cbor-gen v0.0.0-20200710004633-5379fc63235d/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= +github.com/whyrusleeping/cbor-gen v0.0.0-20221220214510-0333c149dec0 h1:obKzQ1ey5AJg5NKjgtTo/CKwLImVP4ETLRcsmzFJ4Qw= +github.com/whyrusleeping/cbor-gen v0.0.0-20221220214510-0333c149dec0/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f h1:jQa4QT2UP9WYv2nzyawpKMOCl+Z/jW7djv2/J50lj9E= github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f/go.mod h1:p9UJB6dDgdPgMJZs7UjUOdulKyRr9fqkS+6JKAInPy8= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 h1:EKhdznlJHPMoKr0XTrX+IlJs1LH3lyx2nfr1dOlZ79k= @@ -1388,7 +1372,6 @@ go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.32.0 h1:mac9BKRqwaX6zxHPDe3pvmWpwuuIM0vuXv2juCnQevE= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.32.0/go.mod h1:5eCOqeGphOyz6TsY3ZDNjE33SM/TFAK3RGuCL2naTgY= -go.opentelemetry.io/otel v0.20.0/go.mod h1:Y3ugLH2oa81t5QO+Lty+zXf8zC9L26ax4Nzoxm/dooo= go.opentelemetry.io/otel v1.7.0 h1:Z2lA3Tdch0iDcrhJXDIlC94XE+bxok1F9B+4Lz/lGsM= go.opentelemetry.io/otel v1.7.0/go.mod h1:5BdUoMIz5WEs0vt0CUEMtSSaTSHBBVwrhnz7+nrD5xk= go.opentelemetry.io/otel/exporters/jaeger v1.7.0 h1:wXgjiRldljksZkZrldGVe6XrG9u3kYDyQmkZwmm5dI0= @@ -1405,14 +1388,10 @@ go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.7.0 h1:8hPcgCg0rUJiKE6V go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.7.0/go.mod h1:K4GDXPY6TjUiwbOh+DkKaEdCF8y+lvMoM6SeAPyfCCM= go.opentelemetry.io/otel/exporters/zipkin v1.7.0 h1:X0FZj+kaIdLi29UiyrEGDhRTYsEXj9GdEW5Y39UQFEE= go.opentelemetry.io/otel/exporters/zipkin v1.7.0/go.mod h1:9YBXeOMFLQGwNEjsxMRiWPGoJX83usGMhbCmxUbNe5I= -go.opentelemetry.io/otel/metric v0.20.0/go.mod h1:598I5tYlH1vzBjn+BTuhzTCSb/9debfNp6R3s7Pr1eU= go.opentelemetry.io/otel/metric v0.30.0 h1:Hs8eQZ8aQgs0U49diZoaS6Uaxw3+bBE3lcMUKBFIk3c= go.opentelemetry.io/otel/metric v0.30.0/go.mod h1:/ShZ7+TS4dHzDFmfi1kSXMhMVubNoP0oIaBp70J6UXU= -go.opentelemetry.io/otel/oteltest v0.20.0/go.mod h1:L7bgKf9ZB7qCwT9Up7i9/pn0PWIa9FqQ2IQ8LoxiGnw= -go.opentelemetry.io/otel/sdk v0.20.0/go.mod h1:g/IcepuwNsoiX5Byy2nNV0ySUF1em498m7hBWC279Yc= go.opentelemetry.io/otel/sdk v1.7.0 h1:4OmStpcKVOfvDOgCt7UriAPtKolwIhxpnSNI/yK+1B0= go.opentelemetry.io/otel/sdk v1.7.0/go.mod h1:uTEOTwaqIVuTGiJN7ii13Ibp75wJmYUDe374q6cZwUU= -go.opentelemetry.io/otel/trace v0.20.0/go.mod h1:6GjCW8zgDjwGHGa6GkyeB8+/5vjT16gUEi0Nf1iBdgw= go.opentelemetry.io/otel/trace v1.7.0 h1:O37Iogk1lEkMRXewVtZ1BBTVn5JEp8GrJvP92bJqC6o= go.opentelemetry.io/otel/trace v1.7.0/go.mod h1:fzLSB9nqR2eXzxPXb2JW9IKE+ScyXA48yyE4TNvoHqU= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= @@ -1437,7 +1416,6 @@ go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/ go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= -go.uber.org/multierr v1.7.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= @@ -1481,15 +1459,12 @@ golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210506145944-38f3c27a63bf/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= -golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= -golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210920023735-84f357641f63/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.3.0 h1:a06MkbcxBrEFc0w0QIZWXrH/9cCX6KJyWbBOIwAn+7A= golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= @@ -1497,7 +1472,6 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20210615023648-acb5c1269671/go.mod h1:DVyR6MI7P4kEQgvZJSj1fQGrWIi2RzIrfYWycwheUAc= golang.org/x/exp v0.0.0-20221205204356-47842c84f3db h1:D/cFflL63o2KSLJIwjlcIt8PR064j/xsmdEJL/YvY/o= golang.org/x/exp v0.0.0-20221205204356-47842c84f3db/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= @@ -1515,12 +1489,10 @@ golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPI golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= -golang.org/x/mobile v0.0.0-20201217150744-e6ae53a27f4f/go.mod h1:skQtrUTUwhdJvXM/2KKJzY8pDgNr9I/FOMqDVRPBUS4= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.1.1-0.20191209134235-331c550502dd/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= @@ -1688,7 +1660,6 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210426080607-c94f62235c83/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1752,7 +1723,6 @@ golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapK golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200117012304-6edc0a871e69/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= @@ -1774,7 +1744,6 @@ golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= @@ -1784,8 +1753,8 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f h1:GGU+dLjvlC3qDwqYgL6UgRmHXhOOgns0bZu2Ty5mm6U= -golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y= @@ -1939,7 +1908,6 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= lukechampine.com/blake3 v1.1.6/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= lukechampine.com/blake3 v1.1.7 h1:GgRMhmdsuK8+ii6UZFDL8Nb+VyMwadAgcJyfYHxG6n0= lukechampine.com/blake3 v1.1.7/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= diff --git a/routing/delegated.go b/routing/delegated.go index d95053fd3..1e8d7efa0 100644 --- a/routing/delegated.go +++ b/routing/delegated.go @@ -13,6 +13,7 @@ import ( drclient "github.com/ipfs/go-libipfs/routing/http/client" "github.com/ipfs/go-libipfs/routing/http/contentrouter" logging "github.com/ipfs/go-log" + version "github.com/ipfs/kubo" "github.com/ipfs/kubo/config" dht "github.com/libp2p/go-libp2p-kad-dht" "github.com/libp2p/go-libp2p-kad-dht/dual" @@ -208,6 +209,7 @@ func httpRoutingFromConfig(conf config.Router, extraHTTP *ExtraHTTPParams) (rout drclient.WithHTTPClient(delegateHTTPClient), drclient.WithIdentity(key), drclient.WithProviderInfo(addrInfo.ID, addrInfo.Addrs), + drclient.WithUserAgent(version.GetUserAgentVersion()), ) if err != nil { return nil, err diff --git a/test/sharness/lib/test-lib.sh b/test/sharness/lib/test-lib.sh index 4ce2a6027..3aecaec99 100644 --- a/test/sharness/lib/test-lib.sh +++ b/test/sharness/lib/test-lib.sh @@ -144,8 +144,8 @@ test_run_repeat_60_sec() { return 1 # failed } -test_wait_output_n_lines_60_sec() { - for i in $(test_seq 1 600) +test_wait_output_n_lines() { + for i in $(test_seq 1 3600) do test $(cat "$1" | wc -l | tr -d " ") -ge $2 && return go-sleep 100ms diff --git a/test/sharness/t0172-content-routing-over-http.sh b/test/sharness/t0172-content-routing-over-http.sh index b173ca053..2dac04e7d 100755 --- a/test/sharness/t0172-content-routing-over-http.sh +++ b/test/sharness/t0172-content-routing-over-http.sh @@ -19,9 +19,9 @@ export IPFS_HTTP_ROUTERS="http://127.0.0.1:$ROUTER_PORT" test_launch_ipfs_daemon test_expect_success "start HTTP router proxy" ' - socat TCP-LISTEN:$ROUTER_PORT,reuseaddr,fork,bind=127.0.0.1,retry=10 STDOUT > http_requests & + touch http_requests + socat -u TCP-LISTEN:$ROUTER_PORT,reuseaddr,fork,bind=127.0.0.1,retry=10 CREATE:http_requests & NCPID=$! - test_wait_for_file 50 100ms http_requests ' ## HTTP GETs @@ -30,12 +30,16 @@ test_expect_success 'create unique CID without adding it to the local datastore' WANT_CID=$(date +"%FT%T.%N%z" | ipfs add -qn) ' -test_expect_success 'expect HTTP request for unknown CID' ' +test_expect_success 'expect HTTP lookup when CID is not in the local datastore' ' ipfs block stat "$WANT_CID" & - test_wait_output_n_lines_60_sec http_requests 3 && + test_wait_output_n_lines http_requests 4 && test_should_contain "GET /routing/v1/providers/$WANT_CID" http_requests ' +test_expect_success 'expect HTTP request User-Agent to match Kubo version' ' + test_should_contain "User-Agent: $(ipfs id -f "")" http_requests +' + ## HTTP PUTs test_expect_success 'add new CID to the local datastore' ' @@ -50,6 +54,7 @@ test_expect_success 'expect no HTTP requests to be sent with locally added CID' test_expect_success "stop nc" ' kill "$NCPID" && wait "$NCPID" || true + rm -f http_requests || true ' test_kill_ipfs_daemon From c4cc21dcca8747f2cbd61280a76714136381852c Mon Sep 17 00:00:00 2001 From: Jorropo Date: Tue, 17 Jan 2023 19:18:39 +0100 Subject: [PATCH 0415/1212] fix: refuse to start if connmgr is smaller than ressource limits and not using none connmgr Fixes: #9548 --- core/node/libp2p/rcmgr.go | 42 ++++++++++++++++++++++++++++++ test/sharness/t0139-swarm-rcmgr.sh | 28 ++++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/core/node/libp2p/rcmgr.go b/core/node/libp2p/rcmgr.go index 5d23a874d..321ffbf19 100644 --- a/core/node/libp2p/rcmgr.go +++ b/core/node/libp2p/rcmgr.go @@ -67,6 +67,10 @@ func ResourceManager(cfg config.SwarmConfig) interface{} { limitConfig = l } + if err := ensureConnMgrMakeSenseVsRessourcesMgr(limitConfig, cfg.ConnMgr); err != nil { + return nil, opts, err + } + limiter := rcmgr.NewFixedLimiter(limitConfig) str, err := rcmgrObs.NewStatsTraceReporter() @@ -598,3 +602,41 @@ func NetResetLimit(mgr network.ResourceManager, repo repo.Repo, scope string) (r return result, nil } + +func ensureConnMgrMakeSenseVsRessourcesMgr(rcm rcmgr.LimitConfig, cmgr config.ConnMgr) error { + if cmgr.Type.WithDefault(config.DefaultConnMgrType) == "none" { + return nil // none connmgr, no checks to do + } + highWater := cmgr.HighWater.WithDefault(config.DefaultConnMgrHighWater) + if rcm.System.ConnsInbound <= rcm.System.Conns { + if int64(rcm.System.ConnsInbound) <= highWater { + // nolint + return fmt.Errorf(` +Unable to initialize libp2p due to conflicting limit configuration: +ResourceMgr.Limits.System.ConnsInbound (%d) must be bigger than ConnMgr.HighWater (%d) +`, rcm.System.ConnsInbound, highWater) + } + } else if int64(rcm.System.Conns) <= highWater { + // nolint + return fmt.Errorf(` +Unable to initialize libp2p due to conflicting limit configuration: +ResourceMgr.Limits.System.Conns (%d) must be bigger than ConnMgr.HighWater (%d) +`, rcm.System.Conns, highWater) + } + if rcm.System.StreamsInbound <= rcm.System.Streams { + if int64(rcm.System.StreamsInbound) <= highWater { + // nolint + return fmt.Errorf(` +Unable to initialize libp2p due to conflicting limit configuration: +ResourceMgr.Limits.System.StreamsInbound (%d) must be bigger than ConnMgr.HighWater (%d) +`, rcm.System.StreamsInbound, highWater) + } + } else if int64(rcm.System.Streams) <= highWater { + // nolint + return fmt.Errorf(` +Unable to initialize libp2p due to conflicting limit configuration: +ResourceMgr.Limits.System.Streams (%d) must be bigger than ConnMgr.HighWater (%d) +`, rcm.System.Streams, highWater) + } + return nil +} diff --git a/test/sharness/t0139-swarm-rcmgr.sh b/test/sharness/t0139-swarm-rcmgr.sh index c36ddd3d8..69c5e4600 100755 --- a/test/sharness/t0139-swarm-rcmgr.sh +++ b/test/sharness/t0139-swarm-rcmgr.sh @@ -227,4 +227,32 @@ test_expect_success 'stop iptb' ' iptb stop 2 ' +## Test daemon refuse to start if connmgr.highwater < ressources inbound + +test_expect_success "node refuse to start if Swarm.ResourceMgr.Limits.System.Conns <= Swarm.ConnMgr.HighWater" ' + ipfs config --json Swarm.ResourceMgr.Limits.System.Conns 128 && + ipfs config --json Swarm.ConnMgr.HighWater 128 && + ipfs config --json Swarm.ConnMgr.LowWater 64 && + test_expect_code 1 ipfs daemon && + ipfs config --json Swarm.ResourceMgr.Limits.System.Conns 256 +' + +test_expect_success "node refuse to start if Swarm.ResourceMgr.Limits.System.ConnsInbound <= Swarm.ConnMgr.HighWater" ' + ipfs config --json Swarm.ResourceMgr.Limits.System.ConnsInbound 128 && + test_expect_code 1 ipfs daemon && + ipfs config --json Swarm.ResourceMgr.Limits.System.ConnsInbound 256 +' + +test_expect_success "node refuse to start if Swarm.ResourceMgr.Limits.System.Streams <= Swarm.ConnMgr.HighWater" ' + ipfs config --json Swarm.ResourceMgr.Limits.System.Streams 128 && + test_expect_code 1 ipfs daemon && + ipfs config --json Swarm.ResourceMgr.Limits.System.Streams 256 +' + +test_expect_success "node refuse to start if Swarm.ResourceMgr.Limits.System.StreamsInbound <= Swarm.ConnMgr.HighWater" ' + ipfs config --json Swarm.ResourceMgr.Limits.System.StreamsInbound 128 && + test_expect_code 1 ipfs daemon && + ipfs config --json Swarm.ResourceMgr.Limits.System.StreamsInbound 256 +' + test_done From 37059b82f7536ca5804bfcad2542ce043e45efc5 Mon Sep 17 00:00:00 2001 From: galargh Date: Thu, 19 Jan 2023 16:54:21 +0100 Subject: [PATCH 0416/1212] fix: update saxon download path --- test/sharness/lib/download-saxon.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/sharness/lib/download-saxon.sh b/test/sharness/lib/download-saxon.sh index 195630804..cc645238f 100755 --- a/test/sharness/lib/download-saxon.sh +++ b/test/sharness/lib/download-saxon.sh @@ -1,7 +1,7 @@ #!/bin/bash dependencies=( - "url=https://sourceforge.net/projects/saxon/files/Saxon-HE/11/Java/SaxonHE11-4J.zip;md5=8a4783d307c32c898f8995b8f337fd6b" + "url=https://raw.githubusercontent.com/pl-strflt/Saxon-HE/3e039cdbccf4efb9643736f34c839a3bae3402ae/11/Java/SaxonHE11-4J.zip;md5=8a4783d307c32c898f8995b8f337fd6b" "url=https://raw.githubusercontent.com/pl-strflt/ant/c781f7d79b92cc55530245d9554682a47f46851e/src/etc/junit-frames-saxon.xsl;md5=6eb013566903a91e4959413f6ff144d0" "url=https://raw.githubusercontent.com/pl-strflt/ant/c781f7d79b92cc55530245d9554682a47f46851e/src/etc/junit-noframes-saxon.xsl;md5=8d54882d5f9d32a7743ec675cc2e30ac" ) From 0ae3285a76b4f754dee8a4d58990e0e38d24bb89 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Fri, 20 Jan 2023 11:24:45 +0100 Subject: [PATCH 0417/1212] docs: clarify browser descriptions for webtransport --- docs/changelogs/v0.18.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/changelogs/v0.18.md b/docs/changelogs/v0.18.md index e99cd5c94..cca07ecfb 100644 --- a/docs/changelogs/v0.18.md +++ b/docs/changelogs/v0.18.md @@ -130,7 +130,7 @@ since Kubo 0.13, but in this release it will also include the size column. ##### WebTransport enabled by default [WebTransport](https://docs.libp2p.io/concepts/transports/webtransport/) is a new libp2p transport that [was introduced in v0.16](https://github.com/ipfs/kubo/blob/master/docs/changelogs/v0.16.md#-webtransport-new-experimental-transport) that is based on top of QUIC and HTTP3. -This allows browsers to contact Kubo nodes, so now instead of just serving requests for other system level applicative nodes, you can also serve requests directly to a browser. +This allows browser-based nodes to contact Kubo nodes, so now instead of just serving requests for other system-level application nodes, you can also serve requests directly to a node running inside a browser page. For the full story see [connectivity.libp2p.io](https://connectivity.libp2p.io/). From 5bbc5212ee638b110bf0b2ab83ccb28beec46bc1 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Fri, 20 Jan 2023 15:29:54 +0100 Subject: [PATCH 0418/1212] fix: typo in ensureConnMgrMakeSenseVsResourcesMgr --- core/node/libp2p/rcmgr.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/node/libp2p/rcmgr.go b/core/node/libp2p/rcmgr.go index 321ffbf19..fe7fc635e 100644 --- a/core/node/libp2p/rcmgr.go +++ b/core/node/libp2p/rcmgr.go @@ -67,7 +67,7 @@ func ResourceManager(cfg config.SwarmConfig) interface{} { limitConfig = l } - if err := ensureConnMgrMakeSenseVsRessourcesMgr(limitConfig, cfg.ConnMgr); err != nil { + if err := ensureConnMgrMakeSenseVsResourceMgr(limitConfig, cfg.ConnMgr); err != nil { return nil, opts, err } @@ -603,7 +603,7 @@ func NetResetLimit(mgr network.ResourceManager, repo repo.Repo, scope string) (r return result, nil } -func ensureConnMgrMakeSenseVsRessourcesMgr(rcm rcmgr.LimitConfig, cmgr config.ConnMgr) error { +func ensureConnMgrMakeSenseVsResourceMgr(rcm rcmgr.LimitConfig, cmgr config.ConnMgr) error { if cmgr.Type.WithDefault(config.DefaultConnMgrType) == "none" { return nil // none connmgr, no checks to do } From 486c4b52567eead7b7b531894e22bc2d9d255380 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Mon, 16 Jan 2023 12:02:40 +0100 Subject: [PATCH 0419/1212] fix: ensure connmgr is smaller then autoscalled ressource limits Fixes #9545 --- config/init.go | 4 ++++ core/node/libp2p/rcmgr_defaults.go | 19 +++++++++++++++++ docs/libp2p-resource-management.md | 34 ++++++++++++++++++------------ test/sharness/t0139-swarm-rcmgr.sh | 28 +++++++++++++++++++++++- 4 files changed, 71 insertions(+), 14 deletions(-) diff --git a/config/init.go b/config/init.go index e91b24871..621ff95f3 100644 --- a/config/init.go +++ b/config/init.go @@ -110,6 +110,10 @@ const DefaultConnMgrGracePeriod = time.Second * 20 // type. const DefaultConnMgrType = "basic" +// DefaultResourceMgrMinInboundConns is a MAGIC number that probably a good +// enough number of inbound conns to be a good network citizen. +const DefaultResourceMgrMinInboundConns = 800 + func addressesConfig() Addresses { return Addresses{ Swarm: []string{ diff --git a/core/node/libp2p/rcmgr_defaults.go b/core/node/libp2p/rcmgr_defaults.go index d3c294258..4d578a9b6 100644 --- a/core/node/libp2p/rcmgr_defaults.go +++ b/core/node/libp2p/rcmgr_defaults.go @@ -186,5 +186,24 @@ Run 'ipfs swarm limit all' to see the resulting limits. defaultLimitConfig := scalingLimitConfig.Scale(int64(maxMemory), int(numFD)) + // Simple checks to overide autoscaling ensuring limits make sense versus the connmgr values. + // There are ways to break this, but this should catch most problems already. + // We might improve this in the future. + // See: https://github.com/ipfs/kubo/issues/9545 + if cfg.ConnMgr.Type.WithDefault(config.DefaultConnMgrType) != "none" { + maxInboundConns := int64(defaultLimitConfig.System.ConnsInbound) + if connmgrHighWaterTimesTwo := cfg.ConnMgr.HighWater.WithDefault(config.DefaultConnMgrHighWater) * 2; maxInboundConns < connmgrHighWaterTimesTwo { + maxInboundConns = connmgrHighWaterTimesTwo + } + + if maxInboundConns < config.DefaultResourceMgrMinInboundConns { + maxInboundConns = config.DefaultResourceMgrMinInboundConns + } + + // Scale System.StreamsInbound as well, but use the existing ratio of StreamsInbound to ConnsInbound + defaultLimitConfig.System.StreamsInbound = int(maxInboundConns * int64(defaultLimitConfig.System.StreamsInbound) / int64(defaultLimitConfig.System.ConnsInbound)) + defaultLimitConfig.System.ConnsInbound = int(maxInboundConns) + } + return defaultLimitConfig, nil } diff --git a/docs/libp2p-resource-management.md b/docs/libp2p-resource-management.md index 83c44251d..d6b782da1 100644 --- a/docs/libp2p-resource-management.md +++ b/docs/libp2p-resource-management.md @@ -40,19 +40,19 @@ libp2p's resource manager provides tremendous flexibility but also adds complexi 1. "The user who does nothing" - In this case Kubo attempts to give some sane defaults discussed below based on the amount of memory and file descriptors their system has. This should protect the node from many attacks. - + 1. "Slightly more advanced user" - They can tweak the default limits discussed below. Where the defaults aren't good enough, a good set of higher-level "knobs" are exposed to satisfy most use cases without requiring users to wade into all the intricacies of libp2p's resource manager. - The "knobs"/inputs are `Swarm.ResourceMgr.MaxMemory` and `Swarm.ResourceMgr.MaxFileDescriptors` as described below. + The "knobs"/inputs are `Swarm.ResourceMgr.MaxMemory` and `Swarm.ResourceMgr.MaxFileDescriptors` as described below. 1. "Power user" - They specify overrides to computed default limits via `ipfs swarm limit` and `Swarm.ResourceMgr.Limits`; ### Computed Default Limits With the `Swarm.ResourceMgr.MaxMemory` and `Swarm.ResourceMgr.MaxFileDescriptors` inputs defined, -[resource manager limits](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#limits) are created at the -[system](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#the-system-scope), -[transient](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#the-transient-scope), +[resource manager limits](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#limits) are created at the +[system](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#the-system-scope), +[transient](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#the-transient-scope), and [peer](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#peer-scopes) scopes. Other scopes are ignored (by being set to "[~infinity](#infinite-limits])". @@ -68,11 +68,15 @@ The reason these scopes are chosen is because: (e.g., bug in a peer which is causing it to "misbehave"). In the unintional case, we want to make sure a "misbehaving" node doesn't consume more resources than necessary. -Within these scopes, limits are just set on -[memory](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#memory), +Within these scopes, limits are just set on +[memory](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#memory), [file descriptors (FD)](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#file-descriptors), [*inbound* connections](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#connections), and [*inbound* streams](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#streams). Limits are set based on the `Swarm.ResourceMgr.MaxMemory` and `Swarm.ResourceMgr.MaxFileDescriptors` inputs above. + +There are also some special cases where minimum values are enforced. +For example, Kubo maintainers have found in practice that it's a footgun to have too low of a value for `Swarm.ResourceMgr.Limits.System.ConnsInbound` and a default minimum is used. (See [core/node/libp2p/rcmgr_defaults.go](https://github.com/ipfs/kubo/blob/master/core/node/libp2p/rcmgr_defaults.go) for specifics.) + We trust this node to behave properly and thus don't limit *outbound* connection/stream limits. We apply any limits that libp2p has for its protocols/services since we assume libp2p knows best here. @@ -139,13 +143,17 @@ There is a go-libp2p issue ([#1928](https://github.com/libp2p/go-libp2p/issues/1 ### How does the resource manager (ResourceMgr) relate to the connection manager (ConnMgr)? As discussed [here](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#connmanager-vs-resource-manager) these are separate systems in go-libp2p. -Kubo also configures the ConnMgr separately from ResourceMgr. There is no checking to make sure the limits between the systems are congruent. +Kubo performs sanity checks to ensure that some of the hard limits of the ResourceMgr are sufficiently greater than the soft limits of the ConnMgr. -Ideally `Swarm.ConnMgr.HighWater` is less than `Swarm.ResourceMgr.Limits.System.ConnsInbound`. -This is so the ConnMgr can kick in and cleanup connections based on connection priorities before the hard limits of the ResourceMgr are applied. +The soft limit of `Swarm.ConnMgr.HighWater` needs to be less than the hard limit `Swarm.ResourceMgr.Limits.System.ConnsInbound` for the configuration to make sense. +This ensures the ConnMgr cleans up connections based on connection priorities before the hard limits of the ResourceMgr are applied. If `Swarm.ConnMgr.HighWater` is greater than `Swarm.ResourceMgr.Limits.System.ConnsInbound`, existing low priority idle connections can prevent new high priority connections from being established. -The ResourceMgr doesn't know that the new connection is high priority and simply blocks it because of the limit its enforcing. +The ResourceMgr doesn't know that the new connection is high priority and simply blocks it because of the limit its enforcing. + +To ensure the ConnMgr and ResourceMgr are congruent, the ResourceMgr [computed default limts](#computed-default-limits) are adjusted such that: +1. `Swarm.ResourceMgr.Limits.System.ConnsInbound` >= `max(Swarm.ConnMgr.HighWater * 2, 800)` AND +2. `Swarm.ResourceMgr.Limits.System.StreamsInbound` is greater than any new/adjusted `Swarm.ResourceMgr.Limits.System.ConnsInbound` value so that there's enough streams per connection. ### How does one see the Active Limits? A dump of what limits are actually being used by the resource manager ([Computed Default Limits](#computed-default-limits) + [User Supplied Override Limits](#user-supplied-override-limits)) @@ -156,9 +164,9 @@ This can be observed with an empty [`Swarm.ResourceMgr.Limits`](https://github.c and then [seeing the active limits](#how-does-one-see-the-active-limits). ### How does one monitor libp2p resource usage? -For [monitoring libp2p resource usage](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#monitoring), +For [monitoring libp2p resource usage](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#monitoring), various `*rcmgr_*` metrics can be accessed as the prometheus endpoint at `{Addresses.API}/debug/metrics/prometheus` (default: `http://127.0.0.1:5001/debug/metrics/prometheus`). -There are also [pre-built Grafana dashboards](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager/obs/grafana-dashboards) that can be added to a Grafana instance. +There are also [pre-built Grafana dashboards](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager/obs/grafana-dashboards) that can be added to a Grafana instance. A textual view of current resource usage and a list of services, protocols, and peers can be obtained via `ipfs swarm stats --help` diff --git a/test/sharness/t0139-swarm-rcmgr.sh b/test/sharness/t0139-swarm-rcmgr.sh index 69c5e4600..1b870abb7 100755 --- a/test/sharness/t0139-swarm-rcmgr.sh +++ b/test/sharness/t0139-swarm-rcmgr.sh @@ -40,9 +40,35 @@ test_expect_success 'disconnected: swarm stats requires running daemon' ' test_should_contain "missing ResourceMgr" actual ' +# test sanity scaling +test_expect_success 'set very high connmgr highwater' ' + ipfs config --json Swarm.ConnMgr.HighWater 1000 +' + +test_launch_ipfs_daemon + +test_expect_success 'conns and streams are above 2000' ' + ipfs swarm limit system --enc=json | tee json && + [ "$(jq -r .ConnsInbound < json)" -ge 2000 ] && + [ "$(jq -r .StreamsInbound < json)" -ge 2000 ] +' + +test_kill_ipfs_daemon + +test_expect_success 'set previous connmgr highwater' ' + ipfs config --json Swarm.ConnMgr.HighWater 96 +' + +test_launch_ipfs_daemon + +test_expect_success 'conns and streams are above 800' ' + ipfs swarm limit system --enc=json | tee json && + [ "$(jq -r .ConnsInbound < json)" -ge 800 ] && + [ "$(jq -r .StreamsInbound < json)" -ge 800 ] +' + # swarm limit|stats should succeed in online mode by default # because Resource Manager is opt-out -test_launch_ipfs_daemon # every scope has the same fields, so we only inspect System test_expect_success 'ResourceMgr enabled: swarm limit' ' From a9fdf26eeb94ef6d548aeb6dabb04ddce86df6ec Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Fri, 20 Jan 2023 22:40:49 +0100 Subject: [PATCH 0420/1212] fix(ci): work around bifrost-infra/issues/2300 https://github.com/protocol/bifrost-infra/issues/2300#issuecomment-1398946009 --- .circleci/main.yml | 4 ++++ .github/workflows/build.yml | 2 ++ 2 files changed, 6 insertions(+) diff --git a/.circleci/main.yml b/.circleci/main.yml index 6406c6655..9bf48ebea 100644 --- a/.circleci/main.yml +++ b/.circleci/main.yml @@ -228,6 +228,8 @@ jobs: - image: cimg/go:1.19.1-node parallelism: 4 resource_class: 2xlarge+ + environment: + GO_IPFS_DIST_URL: https://dist-ipfs-tech.ipns.cf-ipfs.com # TODO remove this line when https://github.com/protocol/bifrost-infra/issues/2300 is closed steps: - *make_out_dirs - attach_workspace: @@ -328,6 +330,8 @@ jobs: ipfs-webui: executor: node-browsers resource_class: 2xlarge+ + environment: + GO_IPFS_DIST_URL: https://dist-ipfs-tech.ipns.cf-ipfs.com # TODO remove this line when https://github.com/protocol/bifrost-infra/issues/2300 is closed steps: - *make_out_dirs - attach_workspace: diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d0b4194b7..997067ad8 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -78,6 +78,7 @@ jobs: LIBP2P_TCP_REUSEPORT: false LIBP2P_ALLOW_WEAK_RSA_KEYS: 1 IPFS_GO_EXEC: ${{ github.workspace }}/cmd/ipfs/ipfs + GO_IPFS_DIST_URL: https://dist-ipfs-tech.ipns.cf-ipfs.com # TODO: remove this line when https://github.com/protocol/bifrost-infra/issues/2300 is closed working-directory: interop go-ipfs-api: needs: [prepare] @@ -161,6 +162,7 @@ jobs: TRAVIS: 1 GIT_PAGER: cat IPFS_CHECK_RCMGR_DEFAULTS: 1 + GO_IPFS_DIST_URL: https://dist-ipfs-tech.ipns.cf-ipfs.com # TODO: remove this line when https://github.com/protocol/bifrost-infra/issues/2300 is closed defaults: run: shell: bash From 14703e19e31b78b2170e3a7ee7bc209249c9575f Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Sat, 21 Jan 2023 04:21:18 +0100 Subject: [PATCH 0421/1212] fix(gateway): undesired conversions to dag-json and friends (#9566) * fix(gateway): do not convert unixfs/raw into dag-* unless explicit * fix(gateway): keep only dag-json|dag-cbor handling * fix: allow requesting dag-json as application/json - adds bunch of additional tests including JSON file on UnixFS - fix: dag-json codec (0x0129) can be returned as plain json - fix: json codec (0x0200) cna be retrurned as plain json * fix: using ?format|Accept with CID w/ codec works * docs(changelog): cbor and json on gateway Co-authored-by: Marcin Rataj --- core/corehttp/gateway_handler.go | 21 +- core/corehttp/gateway_handler_codec.go | 83 ++++---- docs/changelogs/v0.18.md | 79 ++++++- test/sharness/t0123-gateway-json-cbor.sh | 250 +++++++++++------------ 4 files changed, 242 insertions(+), 191 deletions(-) diff --git a/core/corehttp/gateway_handler.go b/core/corehttp/gateway_handler.go index c20f112d7..1c6797e68 100644 --- a/core/corehttp/gateway_handler.go +++ b/core/corehttp/gateway_handler.go @@ -418,9 +418,9 @@ func (i *gatewayHandler) getOrHeadHandler(w http.ResponseWriter, r *http.Request // Support custom response formats passed via ?format or Accept HTTP header switch responseFormat { - case "": - switch resolvedPath.Cid().Prefix().Codec { - case uint64(mc.Json), uint64(mc.DagJson), uint64(mc.Cbor), uint64(mc.DagCbor): + case "", "application/json", "application/cbor": + switch mc.Code(resolvedPath.Cid().Prefix().Codec) { + case mc.Json, mc.DagJson, mc.Cbor, mc.DagCbor: logger.Debugw("serving codec", "path", contentPath) i.serveCodec(r.Context(), w, r, resolvedPath, contentPath, begin, responseFormat) default: @@ -441,14 +441,13 @@ func (i *gatewayHandler) getOrHeadHandler(w http.ResponseWriter, r *http.Request logger.Debugw("serving tar file", "path", contentPath) i.serveTAR(r.Context(), w, r, resolvedPath, contentPath, begin, logger) return - case "application/json", "application/vnd.ipld.dag-json", - "application/cbor", "application/vnd.ipld.dag-cbor": + case "application/vnd.ipld.dag-json", "application/vnd.ipld.dag-cbor": logger.Debugw("serving codec", "path", contentPath) i.serveCodec(r.Context(), w, r, resolvedPath, contentPath, begin, responseFormat) return default: // catch-all for unsuported application/vnd.* err := fmt.Errorf("unsupported format %q", responseFormat) - webError(w, "failed respond with requested content type", err, http.StatusBadRequest) + webError(w, "failed to respond with requested content type", err, http.StatusBadRequest) return } } @@ -878,14 +877,14 @@ func customResponseFormat(r *http.Request) (mediaType string, params map[string] return "application/vnd.ipld.car", nil, nil case "tar": return "application/x-tar", nil, nil - case "dag-json": - return "application/vnd.ipld.dag-json", nil, nil case "json": return "application/json", nil, nil - case "dag-cbor": - return "application/vnd.ipld.dag-cbor", nil, nil case "cbor": return "application/cbor", nil, nil + case "dag-json": + return "application/vnd.ipld.dag-json", nil, nil + case "dag-cbor": + return "application/vnd.ipld.dag-cbor", nil, nil } } // Browsers and other user agents will send Accept header with generic types like: @@ -908,6 +907,8 @@ func customResponseFormat(r *http.Request) (mediaType string, params map[string] } } } + // If none of special-cased content types is found, return empty string + // to indicate default, implicit UnixFS response should be prepared return "", nil, nil } diff --git a/core/corehttp/gateway_handler_codec.go b/core/corehttp/gateway_handler_codec.go index 95a151c79..93e9593b7 100644 --- a/core/corehttp/gateway_handler_codec.go +++ b/core/corehttp/gateway_handler_codec.go @@ -25,22 +25,25 @@ import ( // codecToContentType maps the supported IPLD codecs to the HTTP Content // Type they should have. -var codecToContentType = map[uint64]string{ - uint64(mc.Json): "application/json", - uint64(mc.Cbor): "application/cbor", - uint64(mc.DagJson): "application/vnd.ipld.dag-json", - uint64(mc.DagCbor): "application/vnd.ipld.dag-cbor", +var codecToContentType = map[mc.Code]string{ + mc.Json: "application/json", + mc.Cbor: "application/cbor", + mc.DagJson: "application/vnd.ipld.dag-json", + mc.DagCbor: "application/vnd.ipld.dag-cbor", } -// contentTypeToCodecs maps the HTTP Content Type to the respective -// possible codecs. If the original data is in one of those codecs, -// we stream the raw bytes. Otherwise, we encode in the last codec -// of the list. -var contentTypeToCodecs = map[string][]uint64{ - "application/json": {uint64(mc.Json), uint64(mc.DagJson)}, - "application/vnd.ipld.dag-json": {uint64(mc.DagJson)}, - "application/cbor": {uint64(mc.Cbor), uint64(mc.DagCbor)}, - "application/vnd.ipld.dag-cbor": {uint64(mc.DagCbor)}, +// contentTypeToRaw maps the HTTP Content Type to the respective codec that +// allows raw response without any conversion. +var contentTypeToRaw = map[string][]mc.Code{ + "application/json": {mc.Json, mc.DagJson}, + "application/cbor": {mc.Cbor, mc.DagCbor}, +} + +// contentTypeToCodec maps the HTTP Content Type to the respective codec. We +// only add here the codecs that we want to convert-to-from. +var contentTypeToCodec = map[string]mc.Code{ + "application/vnd.ipld.dag-json": mc.DagJson, + "application/vnd.ipld.dag-cbor": mc.DagCbor, } // contentTypeToExtension maps the HTTP Content Type to the respective file @@ -56,7 +59,7 @@ func (i *gatewayHandler) serveCodec(ctx context.Context, w http.ResponseWriter, ctx, span := tracing.Span(ctx, "Gateway", "ServeCodec", trace.WithAttributes(attribute.String("path", resolvedPath.String()), attribute.String("requestedContentType", requestedContentType))) defer span.End() - cidCodec := resolvedPath.Cid().Prefix().Codec + cidCodec := mc.Code(resolvedPath.Cid().Prefix().Codec) responseContentType := requestedContentType // If the resolved path still has some remainder, return error for now. @@ -90,22 +93,36 @@ func (i *gatewayHandler) serveCodec(ctx context.Context, w http.ResponseWriter, // No content type is specified by the user (via Accept, or format=). However, // we support this format. Let's handle it. if requestedContentType == "" { - isDAG := cidCodec == uint64(mc.DagJson) || cidCodec == uint64(mc.DagCbor) + isDAG := cidCodec == mc.DagJson || cidCodec == mc.DagCbor acceptsHTML := strings.Contains(r.Header.Get("Accept"), "text/html") download := r.URL.Query().Get("download") == "true" if isDAG && acceptsHTML && !download { i.serveCodecHTML(ctx, w, r, resolvedPath, contentPath) } else { + // This covers CIDs with codec 'json' and 'cbor' as those do not have + // an explicit requested content type. i.serveCodecRaw(ctx, w, r, resolvedPath, contentPath, name, modtime) } return } - // Otherwise, the user has requested a specific content type. Let's first get - // the codecs that can be used with this content type. - codecs, ok := contentTypeToCodecs[requestedContentType] + // If DAG-JSON or DAG-CBOR was requested using corresponding plain content type + // return raw block as-is, without conversion + skipCodecs, ok := contentTypeToRaw[requestedContentType] + if ok { + for _, skipCodec := range skipCodecs { + if skipCodec == cidCodec { + i.serveCodecRaw(ctx, w, r, resolvedPath, contentPath, name, modtime) + return + } + } + } + + // Otherwise, the user has requested a specific content type (a DAG-* variant). + // Let's first get the codecs that can be used with this content type. + toCodec, ok := contentTypeToCodec[requestedContentType] if !ok { // This is never supposed to happen unless function is called with wrong parameters. err := fmt.Errorf("unsupported content type: %s", requestedContentType) @@ -113,27 +130,7 @@ func (i *gatewayHandler) serveCodec(ctx context.Context, w http.ResponseWriter, return } - // If we need to convert, use the last codec (strict dag- variant) - toCodec := codecs[len(codecs)-1] - - // If the requested content type has "dag-", ALWAYS go through the encoding - // process in order to validate the content. - if strings.Contains(requestedContentType, "dag-") { - i.serveCodecConverted(ctx, w, r, resolvedPath, contentPath, toCodec, modtime) - return - } - - // Otherwise, check if the data is encoded with the requested content type. - // If so, we can directly stream the raw data. serveRawBlock cannot be directly - // used here as it sets different headers. - for _, codec := range codecs { - if resolvedPath.Cid().Prefix().Codec == codec { - i.serveCodecRaw(ctx, w, r, resolvedPath, contentPath, name, modtime) - return - } - } - - // Finally, if nothing of the above is true, we have to actually convert the codec. + // This handles DAG-* conversions and validations. i.serveCodecConverted(ctx, w, r, resolvedPath, contentPath, toCodec, modtime) } @@ -165,6 +162,7 @@ func (i *gatewayHandler) serveCodecHTML(ctx context.Context, w http.ResponseWrit } } +// serveCodecRaw returns the raw block without any conversion func (i *gatewayHandler) serveCodecRaw(ctx context.Context, w http.ResponseWriter, r *http.Request, resolvedPath ipath.Resolved, contentPath ipath.Path, name string, modtime time.Time) { blockCid := resolvedPath.Cid() blockReader, err := i.api.Block().Get(ctx, resolvedPath) @@ -184,7 +182,8 @@ func (i *gatewayHandler) serveCodecRaw(ctx context.Context, w http.ResponseWrite _, _, _ = ServeContent(w, r, name, modtime, content) } -func (i *gatewayHandler) serveCodecConverted(ctx context.Context, w http.ResponseWriter, r *http.Request, resolvedPath ipath.Resolved, contentPath ipath.Path, toCodec uint64, modtime time.Time) { +// serveCodecConverted returns payload converted to codec specified in toCodec +func (i *gatewayHandler) serveCodecConverted(ctx context.Context, w http.ResponseWriter, r *http.Request, resolvedPath ipath.Resolved, contentPath ipath.Path, toCodec mc.Code, modtime time.Time) { obj, err := i.api.Dag().Get(ctx, resolvedPath.Cid()) if err != nil { webError(w, "ipfs dag get "+html.EscapeString(resolvedPath.String()), err, http.StatusInternalServerError) @@ -199,7 +198,7 @@ func (i *gatewayHandler) serveCodecConverted(ctx context.Context, w http.Respons } finalNode := universal.(ipld.Node) - encoder, err := multicodec.LookupEncoder(toCodec) + encoder, err := multicodec.LookupEncoder(uint64(toCodec)) if err != nil { webError(w, err.Error(), err, http.StatusInternalServerError) return diff --git a/docs/changelogs/v0.18.md b/docs/changelogs/v0.18.md index cca07ecfb..d10f56d77 100644 --- a/docs/changelogs/v0.18.md +++ b/docs/changelogs/v0.18.md @@ -64,19 +64,74 @@ Learn more in the [`Reprovider` config](https://github.com/ipfs/go-ipfs/blob/mas ##### (DAG-)JSON and (DAG-)CBOR response formats -Implemented [IPIP-328](https://github.com/ipfs/specs/pull/328) which adds support -for DAG-JSON and DAG-CBOR, as well as their non-DAG variants, to the gateway. Now, -CIDs that encode JSON, CBOR, DAG-JSON and DAG-CBOR objects can be retrieved, and -traversed thanks to the [special meaning of CBOR Tag 42](https://github.com/ipld/cid-cbor/). +The IPFS project has reserved the corresponding media types at IANA: +- [`application/vnd.ipld.dag-json`](https://www.iana.org/assignments/media-types/application/vnd.ipld.dag-json) +- [`application/vnd.ipld.dag-cbor`](https://www.iana.org/assignments/media-types/application/vnd.ipld.dag-cbor) -HTTP clients can request JSON, CBOR, DAG-JSON, and DAG-CBOR responses by either -passing the query parameter `?format` or setting the `Accept` HTTP header to the -following values: +This release implements them as part of [IPIP-328](https://github.com/ipfs/specs/pull/328) +and adds Gateway support for CIDs with `json` (0x0200), `cbor` (0x51), +[`dag-json`](https://ipld.io/specs/codecs/dag-json/) (0x0129) +and [`dag-cbor`](https://ipld.io/specs/codecs/dag-cbor/spec/) (0x71) codecs. -- JSON: `?format=json`, or `Accept: application/json` -- CBOR: `?format=cbor`, or `Accept: application/cbor` -- DAG-JSON: `?format=dag-json`, or `Accept: application/vnd.ipld.dag-json` -- DAG-JSON: `?format=dag-cbor`, or `Accept: application/vnd.ipld.dag-cbor` +To specify the response `Content-Type` explicitly, the HTTP client can override +the codec present in the CID by using the `format` parameter +or setting the `Accept` HTTP header: + +- Plain JSON: `?format=json` or `Accept: application/json` +- Plain CBOR: `?format=cbor` or `Accept: application/cbor` +- DAG-JSON: `?format=dag-json` or `Accept: application/vnd.ipld.dag-json` +- DAG-CBOR: `?format=dag-cbor` or `Accept: application/vnd.ipld.dag-cbor` + +In addition, when DAG-JSON or DAG-CBOR is requested with the `Accept` header +set to `text/html`, the Gateway will return a basic HTML page with download +options, improving the user experience in web browsers. + +###### Example 1: DAG-CBOR and DAG-JSON Conversion on Gateway + +The Gateway supports conversion between DAG-CBOR and DAG-JSON for efficient +end-to-end data structure management: author in CBOR or JSON, store as binary +CBOR and retrieve as JSON via HTTP: + +```console +$ echo '{"test": "json"}' | ipfs dag put # implicit --input-codec dag-json --store-codec dag-cbor +bafyreico7mjtqtqhvawro3yud5uqn6sc33nzqb7b5j2d7pdmzer5nab4t4 + +$ ipfs block get bafyreico7mjtqtqhvawro3yud5uqn6sc33nzqb7b5j2d7pdmzer5nab4t4 | xxd +00000000: a164 7465 7374 646a 736f 6e .dtestdjson + +$ ipfs dag get bafyreico7mjtqtqhvawro3yud5uqn6sc33nzqb7b5j2d7pdmzer5nab4t4 # implicit --output-codec dag-json +{"test":"json"} + +$ curl "http://127.0.0.1:8080/ipfs/bafyreico7mjtqtqhvawro3yud5uqn6sc33nzqb7b5j2d7pdmzer5nab4t4?format=dag-json" +{"test":"json"} +``` + +###### Example 2: Traversing CBOR DAGs + +Placing a CID in [CBOR Tag 42](https://github.com/ipld/cid-cbor/) enables the +creation of arbitrary DAGs. The equivalent DAG-JSON notation for linking +to different blocks is represented by `{ "/": "cid" }`. + +The Gateway supports traversing these links, enabling access to data +referenced by structures other than regular UnixFS directories: + +```console +$ echo '{"test.jpg": {"/": "bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi"}}' | ipfs dag put +bafyreihspwy3zlkzgphmec5d3xb5g5njrqwotd46lyubnelbzktnmsxkq4 # dag-cbor document linking to unixfs file + +$ ipfs resolve /ipfs/bafyreihspwy3zlkzgphmec5d3xb5g5njrqwotd46lyubnelbzktnmsxkq4/test.jpg +/ipfs/bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi + +$ ipfs dag stat bafyreihspwy3zlkzgphmec5d3xb5g5njrqwotd46lyubnelbzktnmsxkq4 +Size: 119827, NumBlocks: 2 + +$ curl "http://127.0.0.1:8080/ipfs/bafyreihspwy3zlkzgphmec5d3xb5g5njrqwotd46lyubnelbzktnmsxkq4/test.jpg" > test.jpg +``` + +###### Example 3: UnixFS directory listing as JSON + +Finally, Gateway now supports the same [logical format projection](https://ipld.io/specs/codecs/dag-pb/spec/#logical-format) from +DAG-PB to DAG-JSON as the `ipfs dag get` command, enabling the retrieval of directory listings as JSON instead of HTML: ```console $ export DIR_CID=bafybeigccimv3zqm5g4jt363faybagywkvqbrismoquogimy7kvz2sj7sq @@ -112,6 +167,8 @@ $ curl "http://127.0.0.1:8080/ipfs/$DIR_CID?format=dag-json" | jq } ] } +$ ipfs dag get $DIR_CID +{"Data":{"/":{"bytes":"CAE"}},"Links":[{"Hash":{"/":"Qmc3zqKcwzbbvw3MQm3hXdg8BQoFjGdZiGdAfXAyAGGdLi"},"Name":"1 - Barrel - Part 1 - alt.txt","Tsize":21},{"Hash":{"/":"QmdMxMx29KVYhHnaCc1icWYxQqXwUNCae6t1wS2NqruiHd"},"Name":"1 - Barrel - Part 1 - transcript.txt","Tsize":195},{"Hash":{"/":"QmawceGscqN4o8Y8Fv26UUmB454kn2bnkXV5tEQYc4jBd6"},"Name":"1 - Barrel - Part 1.png","Tsize":24862}]} ``` ##### 🐎 Fast directory listings with DAG sizes diff --git a/test/sharness/t0123-gateway-json-cbor.sh b/test/sharness/t0123-gateway-json-cbor.sh index f4ebca19d..704d075f9 100755 --- a/test/sharness/t0123-gateway-json-cbor.sh +++ b/test/sharness/t0123-gateway-json-cbor.sh @@ -12,158 +12,150 @@ test_expect_success "Add the test directory" ' mkdir -p rootDir/ipns && mkdir -p rootDir/api && mkdir -p rootDir/ą/ę && + echo "{ \"test\": \"i am a plain json file\" }" > rootDir/ą/ę/t.json && echo "I am a txt file on path with utf8" > rootDir/ą/ę/file-źł.txt && echo "I am a txt file in confusing /api dir" > rootDir/api/file.txt && echo "I am a txt file in confusing /ipfs dir" > rootDir/ipfs/file.txt && echo "I am a txt file in confusing /ipns dir" > rootDir/ipns/file.txt && DIR_CID=$(ipfs add -Qr --cid-version 1 rootDir) && + FILE_JSON_CID=$(ipfs files stat --enc=json /ipfs/$DIR_CID/ą/ę/t.json | jq -r .Hash) && FILE_CID=$(ipfs files stat --enc=json /ipfs/$DIR_CID/ą/ę/file-źł.txt | jq -r .Hash) && FILE_SIZE=$(ipfs files stat --enc=json /ipfs/$DIR_CID/ą/ę/file-źł.txt | jq -r .Size) echo "$FILE_CID / $FILE_SIZE" ' -## Reading UnixFS (data encoded with dag-pb codec) as DAG-CBOR and DAG-JSON +## Quick regression check for JSON stored on UnixFS: +## it has nothing to do with DAG-JSON and JSON codecs, +## but a lot of JSON data is stored on UnixFS and is requested with or without various hints +## and we want to avoid surprises like https://github.com/protocol/bifrost-infra/issues/2290 +test_expect_success "GET UnixFS file with JSON bytes is returned with application/json Content-Type" ' + curl -sD headers "http://127.0.0.1:$GWAY_PORT/ipfs/$FILE_JSON_CID" > curl_output 2>&1 && + curl -sD headers_accept -H "Accept: application/json" "http://127.0.0.1:$GWAY_PORT/ipfs/$FILE_JSON_CID" > curl_output_accept 2>&1 && + ipfs cat $FILE_JSON_CID > ipfs_cat_output 2>&1 && + test_should_contain "Content-Type: application/json" headers && + test_should_contain "Content-Type: application/json" headers_accept && + test_cmp ipfs_cat_output curl_output && + test_cmp curl_output curl_output_accept +' -test_dag_pb_headers () { + +## Reading UnixFS (data encoded with dag-pb codec) as DAG-CBOR and DAG-JSON +## (returns representation defined in https://ipld.io/specs/codecs/dag-pb/spec/#logical-format) + +test_dag_pb_conversion () { name=$1 format=$2 disposition=$3 - test_expect_success "GET UnixFS as $name with format=dag-$format has expected Content-Type" ' - curl -sD - "http://127.0.0.1:$GWAY_PORT/ipfs/$FILE_CID?format=dag-$format" > curl_output 2>&1 && - test_should_contain "Content-Type: application/vnd.ipld.dag-$format" curl_output && - test_should_contain "Content-Disposition: ${disposition}\; filename=\"${FILE_CID}.${format}\"" curl_output && - test_should_not_contain "Content-Type: application/$format" curl_output + test_expect_success "GET UnixFS file as $name with format=dag-$format converts to the expected Content-Type" ' + curl -sD headers "http://127.0.0.1:$GWAY_PORT/ipfs/$FILE_CID?format=dag-$format" > curl_output 2>&1 && + ipfs dag get --output-codec dag-$format $FILE_CID > ipfs_dag_get_output 2>&1 && + test_cmp ipfs_dag_get_output curl_output && + test_should_contain "Content-Type: application/vnd.ipld.dag-$format" headers && + test_should_contain "Content-Disposition: ${disposition}\; filename=\"${FILE_CID}.${format}\"" headers && + test_should_not_contain "Content-Type: application/$format" headers ' - test_expect_success "GET UnixFS as $name with 'Accept: application/vnd.ipld.dag-$format' has expected Content-Type" ' + test_expect_success "GET UnixFS directory as $name with format=dag-$format converts to the expected Content-Type" ' + curl -sD headers "http://127.0.0.1:$GWAY_PORT/ipfs/$DIR_CID?format=dag-$format" > curl_output 2>&1 && + ipfs dag get --output-codec dag-$format $DIR_CID > ipfs_dag_get_output 2>&1 && + test_cmp ipfs_dag_get_output curl_output && + test_should_contain "Content-Type: application/vnd.ipld.dag-$format" headers && + test_should_contain "Content-Disposition: ${disposition}\; filename=\"${DIR_CID}.${format}\"" headers && + test_should_not_contain "Content-Type: application/$format" headers + ' + + test_expect_success "GET UnixFS as $name with 'Accept: application/vnd.ipld.dag-$format' converts to the expected Content-Type" ' curl -sD - -H "Accept: application/vnd.ipld.dag-$format" "http://127.0.0.1:$GWAY_PORT/ipfs/$FILE_CID" > curl_output 2>&1 && test_should_contain "Content-Disposition: ${disposition}\; filename=\"${FILE_CID}.${format}\"" curl_output && test_should_contain "Content-Type: application/vnd.ipld.dag-$format" curl_output && test_should_not_contain "Content-Type: application/$format" curl_output ' - test_expect_success "GET UnixFS as $name with format=$format has expected Content-Type" ' - curl -sD - "http://127.0.0.1:$GWAY_PORT/ipfs/$FILE_CID?format=$format" > curl_output 2>&1 && - test_should_contain "Content-Disposition: ${disposition}\; filename=\"${FILE_CID}.${format}\"" curl_output && - test_should_contain "Content-Type: application/$format" curl_output && - test_should_not_contain "Content-Type: application/vnd.ipld.dag-$format" curl_output + test_expect_success "GET UnixFS as $name with 'Accept: foo, application/vnd.ipld.dag-$format,bar' converts to the expected Content-Type" ' + curl -sD - -H "Accept: foo, application/vnd.ipld.dag-$format,text/plain" "http://127.0.0.1:$GWAY_PORT/ipfs/$FILE_CID" > curl_output 2>&1 && + test_should_contain "Content-Type: application/vnd.ipld.dag-$format" curl_output ' - test_expect_success "GET UnixFS as $name with 'Accept: application/$format' has expected Content-Type" ' - curl -sD - -H "Accept: application/$format" "http://127.0.0.1:$GWAY_PORT/ipfs/$FILE_CID" > curl_output 2>&1 && - test_should_contain "Content-Disposition: ${disposition}\; filename=\"${FILE_CID}.${format}\"" curl_output && - test_should_contain "Content-Type: application/$format" curl_output && - test_should_not_contain "Content-Type: application/vnd.ipld.dag-$format" curl_output + test_expect_success "GET UnixFS with format=$format (not dag-$format) is no-op (no conversion)" ' + curl -sD headers "http://127.0.0.1:$GWAY_PORT/ipfs/$FILE_CID?format=$format" > curl_output 2>&1 && + ipfs cat $FILE_CID > cat_output && + test_cmp cat_output curl_output && + test_should_contain "Content-Type: text/plain" headers && + test_should_not_contain "Content-Type: application/$format" headers && + test_should_not_contain "Content-Type: application/vnd.ipld.dag-$format" headers ' - test_expect_success "GET UnixFS as $name with 'Accept: foo, application/$format,bar' has expected Content-Type" ' - curl -sD - -H "Accept: foo, application/$format,text/plain" "http://127.0.0.1:$GWAY_PORT/ipfs/$FILE_CID" > curl_output 2>&1 && - test_should_contain "Content-Type: application/$format" curl_output + test_expect_success "GET UnixFS with 'Accept: application/$format' (not dag-$format) is no-op (no conversion)" ' + curl -sD headers -H "Accept: application/$format" "http://127.0.0.1:$GWAY_PORT/ipfs/$FILE_CID" > curl_output 2>&1 && + ipfs cat $FILE_CID > cat_output && + test_cmp cat_output curl_output && + test_should_contain "Content-Type: text/plain" headers && + test_should_not_contain "Content-Type: application/$format" headers && + test_should_not_contain "Content-Type: application/vnd.ipld.dag-$format" headers ' } -test_dag_pb_headers "DAG-JSON" "json" "inline" -test_dag_pb_headers "DAG-CBOR" "cbor" "attachment" +test_dag_pb_conversion "DAG-JSON" "json" "inline" +test_dag_pb_conversion "DAG-CBOR" "cbor" "attachment" -test_dag_pb () { - name=$1 - format=$2 - test_expect_success "GET UnixFS as $name has expected output for file" ' - curl -s "http://127.0.0.1:$GWAY_PORT/ipfs/$FILE_CID?format=dag-$format" > curl_output 2>&1 && - ipfs dag get --output-codec dag-$format $FILE_CID > ipfs_dag_get_output 2>&1 && - test_cmp ipfs_dag_get_output curl_output - ' - - test_expect_success "GET UnixFS as $name has expected output for directory" ' - curl -s "http://127.0.0.1:$GWAY_PORT/ipfs/$DIR_CID?format=dag-$format" > curl_output 2>&1 && - ipfs dag get --output-codec dag-$format $DIR_CID > ipfs_dag_get_output 2>&1 && - test_cmp ipfs_dag_get_output curl_output - ' - - test_expect_success "GET UnixFS as $name with format=dag-$format and format=$format produce same output" ' - curl -s "http://127.0.0.1:$GWAY_PORT/ipfs/$DIR_CID?format=dag-$format" > curl_output_1 2>&1 && - curl -s "http://127.0.0.1:$GWAY_PORT/ipfs/$DIR_CID?format=$format" > curl_output_2 2>&1 && - test_cmp curl_output_1 curl_output_2 - ' -} - -test_dag_pb "DAG-JSON" "json" -test_dag_pb "DAG-CBOR" "cbor" - -## Content-Type response based on Accept header and ?format= parameter - -test_cmp_dag_get () { +# Requesting CID with plain json (0x0200) and cbor (0x51) codecs +# (note these are not UnixFS, not DAG-* variants, just raw block identified by a CID with a special codec) +test_plain_codec () { name=$1 format=$2 disposition=$3 - test_expect_success "GET $name without Accept or format= has expected Content-Type" ' - CID=$(echo "{ \"test\": \"json\" }" | ipfs dag put --input-codec json --store-codec $format) && - curl -sD - "http://127.0.0.1:$GWAY_PORT/ipfs/$CID" > curl_output 2>&1 && - test_should_contain "Content-Disposition: ${disposition}\; filename=\"${CID}.${format}\"" curl_output && - test_should_contain "Content-Type: application/$format" curl_output + # no explicit format, just codec in CID + test_expect_success "GET $name without Accept or format= has expected $format Content-Type and body as-is" ' + CID=$(echo "{ \"test\": \"plain json\" }" | ipfs dag put --input-codec json --store-codec $format) && + curl -sD headers "http://127.0.0.1:$GWAY_PORT/ipfs/$CID" > curl_output 2>&1 && + ipfs block get $CID > ipfs_block_output 2>&1 && + test_cmp ipfs_block_output curl_output && + test_should_contain "Content-Disposition: ${disposition}\; filename=\"${CID}.${format}\"" headers && + test_should_contain "Content-Type: application/$format" headers ' - test_expect_success "GET $name without Accept or format= produces correct output" ' - CID=$(echo "{ \"test\": \"json\" }" | ipfs dag put --input-codec json --store-codec $format) && - curl -s "http://127.0.0.1:$GWAY_PORT/ipfs/$CID" > curl_output 2>&1 && - ipfs dag get --output-codec $format $CID > ipfs_dag_get_output 2>&1 && - test_cmp ipfs_dag_get_output curl_output + # explicit format still gives correct output, just codec in CID + test_expect_success "GET $name with ?format= has expected $format Content-Type and body as-is" ' + CID=$(echo "{ \"test\": \"plain json\" }" | ipfs dag put --input-codec json --store-codec $format) && + curl -sD headers "http://127.0.0.1:$GWAY_PORT/ipfs/$CID?format=$format" > curl_output 2>&1 && + ipfs block get $CID > ipfs_block_output 2>&1 && + test_cmp ipfs_block_output curl_output && + test_should_contain "Content-Disposition: ${disposition}\; filename=\"${CID}.${format}\"" headers && + test_should_contain "Content-Type: application/$format" headers ' - test_expect_success "GET $name with format=$format produces expected Content-Type" ' - CID=$(echo "{ \"test\": \"json\" }" | ipfs dag put --input-codec json --store-codec $format) && - curl -sD- "http://127.0.0.1:$GWAY_PORT/ipfs/$CID?format=$format" > curl_output 2>&1 && - test_should_contain "Content-Disposition: ${disposition}\; filename=\"${CID}.${format}\"" curl_output && - test_should_contain "Content-Type: application/$format" curl_output + # explicit format still gives correct output, just codec in CID + test_expect_success "GET $name with Accept has expected $format Content-Type and body as-is" ' + CID=$(echo "{ \"test\": \"plain json\" }" | ipfs dag put --input-codec json --store-codec $format) && + curl -sD headers -H "Accept: application/$format" "http://127.0.0.1:$GWAY_PORT/ipfs/$CID" > curl_output 2>&1 && + ipfs block get $CID > ipfs_block_output 2>&1 && + test_cmp ipfs_block_output curl_output && + test_should_contain "Content-Disposition: ${disposition}\; filename=\"${CID}.${format}\"" headers && + test_should_contain "Content-Type: application/$format" headers ' - test_expect_success "GET $name with format=$format produces correct output" ' - CID=$(echo "{ \"test\": \"json\" }" | ipfs dag put --input-codec json --store-codec $format) && - curl -s "http://127.0.0.1:$GWAY_PORT/ipfs/$CID?format=$format" > curl_output 2>&1 && - ipfs dag get --output-codec $format $CID > ipfs_dag_get_output 2>&1 && - test_cmp ipfs_dag_get_output curl_output - ' - - test_expect_success "GET $name with format=dag-$format produces expected Content-Type" ' - CID=$(echo "{ \"test\": \"json\" }" | ipfs dag put --input-codec json --store-codec $format) && - curl -sD- "http://127.0.0.1:$GWAY_PORT/ipfs/$CID?format=dag-$format" > curl_output 2>&1 && - test_should_contain "Content-Disposition: ${disposition}\; filename=\"${CID}.${format}\"" curl_output && - test_should_contain "Content-Type: application/vnd.ipld.dag-$format" curl_output - ' - - test_expect_success "GET $name with format=dag-$format produces correct output" ' - CID=$(echo "{ \"test\": \"json\" }" | ipfs dag put --input-codec json --store-codec $format) && - curl -s "http://127.0.0.1:$GWAY_PORT/ipfs/$CID?format=dag-$format" > curl_output 2>&1 && + # explicit dag-* format passed, attempt to parse as dag* variant + ## Note: this works only for simple JSON that can be upgraded to DAG-JSON. + test_expect_success "GET $name with format=dag-$format interprets $format as dag-* variant and produces expected Content-Type and body" ' + CID=$(echo "{ \"test\": \"plain-json-that-can-also-be-dag-json\" }" | ipfs dag put --input-codec json --store-codec $format) && + curl -sD headers "http://127.0.0.1:$GWAY_PORT/ipfs/$CID?format=dag-$format" > curl_output_param 2>&1 && ipfs dag get --output-codec dag-$format $CID > ipfs_dag_get_output 2>&1 && - test_cmp ipfs_dag_get_output curl_output + test_cmp ipfs_dag_get_output curl_output_param && + test_should_contain "Content-Disposition: ${disposition}\; filename=\"${CID}.${format}\"" headers && + test_should_contain "Content-Type: application/vnd.ipld.dag-$format" headers && + curl -s -H "Accept: application/vnd.ipld.dag-$format" "http://127.0.0.1:$GWAY_PORT/ipfs/$CID" > curl_output_accept 2>&1 && + test_cmp curl_output_param curl_output_accept ' + } -test_cmp_dag_get "JSON" "json" "inline" -test_cmp_dag_get "CBOR" "cbor" "attachment" +test_plain_codec "plain JSON codec" "json" "inline" +test_plain_codec "plain CBOR codec" "cbor" "attachment" - -## Lossless conversion between JSON and CBOR - -test_expect_success "GET JSON as CBOR produces DAG-CBOR output" ' - CID=$(echo "{ \"test\": \"json\" }" | ipfs dag put --input-codec json --store-codec json) && - curl -s "http://127.0.0.1:$GWAY_PORT/ipfs/$CID?format=cbor" > curl_output 2>&1 && - ipfs dag get --output-codec dag-cbor $CID > ipfs_dag_get_output 2>&1 && - test_cmp ipfs_dag_get_output curl_output -' - -test_expect_success "GET CBOR as JSON produces DAG-JSON output" ' - CID=$(echo "{ \"test\": \"json\" }" | ipfs dag put --input-codec json --store-codec cbor) && - curl -s "http://127.0.0.1:$GWAY_PORT/ipfs/$CID?format=json" > curl_output 2>&1 && - ipfs dag get --output-codec dag-json $CID > ipfs_dag_get_output 2>&1 && - test_cmp ipfs_dag_get_output curl_output -' - - -## Pathing, traversal +## Pathing, traversal over DAG-JSON and DAG-CBOR DAG_CBOR_TRAVERSAL_CID="bafyreibs4utpgbn7uqegmd2goqz4bkyflre2ek2iwv743fhvylwi4zeeim" DAG_JSON_TRAVERSAL_CID="baguqeeram5ujjqrwheyaty3w5gdsmoz6vittchvhk723jjqxk7hakxkd47xq" @@ -204,17 +196,9 @@ test_expect_success "GET DAG-CBOR traverses multiple links" ' test_cmp expected actual ' -# test_expect_success "GET DAG-PB has expected output" ' -# curl -s "http://127.0.0.1:$GWAY_PORT/ipfs/$DAG_PB_CID?format=dag-json" > curl_output 2>&1 && -# jq --sort-keys . curl_output > actual && -# test_cmp ../t0123-gateway-json-cbor/dag-pb.json actual -# ' - - -## NATIVE TESTS: +## NATIVE TESTS for DAG-JSON (0x0129) and DAG-CBOR (0x71): ## DAG- regression tests for core behaviors when native DAG-(CBOR|JSON) is requested - test_native_dag () { name=$1 format=$2 @@ -237,10 +221,10 @@ test_native_dag () { test_cmp expected curl_ipfs_dag_param_output ' - test_expect_success "GET $name from /ipfs with format=$format returns the same payload as format=dag-$format" ' + test_expect_success "GET $name from /ipfs for application/$format returns the same payload as format=dag-$format" ' curl -sX GET "http://127.0.0.1:$GWAY_PORT/ipfs/$CID?format=dag-$format" -o expected && - curl -sX GET "http://127.0.0.1:$GWAY_PORT/ipfs/$CID?format=dag-$format" -o curl_ipfs_dag_param_output && - test_cmp expected curl_ipfs_dag_param_output + curl -sX GET "http://127.0.0.1:$GWAY_PORT/ipfs/$CID?format=$format" -o plain_output && + test_cmp expected plain_output ' test_expect_success "GET $name from /ipfs with application/vnd.ipld.dag-$format returns the same payload as the raw block" ' @@ -249,6 +233,23 @@ test_native_dag () { test_cmp expected_block curl_ipfs_dag_block_accept_output ' + # Make sure DAG-* can be requested as plain JSON or CBOR and response has plain Content-Type for interop purposes + + test_expect_success "GET $name with format=$format returns same payload as format=dag-$format but with plain Content-Type" ' + curl -s "http://127.0.0.1:$GWAY_PORT/ipfs/$CID?format=dag-$format" -o expected && + curl -sD plain_headers "http://127.0.0.1:$GWAY_PORT/ipfs/$CID?format=$format" -o plain_output && + test_should_contain "Content-Type: application/$format" plain_headers && + test_cmp expected plain_output + ' + + test_expect_success "GET $name with Accept: application/$format returns same payload as application/vnd.ipld.dag-$format but with plain Content-Type" ' + curl -s -H "Accept: application/vnd.ipld.dag-$format" "http://127.0.0.1:$GWAY_PORT/ipfs/$CID" > expected && + curl -sD plain_headers -H "Accept: application/$format" "http://127.0.0.1:$GWAY_PORT/ipfs/$CID" > plain_output && + test_should_contain "Content-Type: application/$format" plain_headers && + test_cmp expected plain_output + ' + + # Make sure expected HTTP headers are returned with the dag- block test_expect_success "GET response for application/vnd.ipld.dag-$format has expected Content-Type" ' @@ -302,18 +303,11 @@ test_native_dag () { test_should_contain "Content-Type: application/vnd.ipld.dag-$format" output && test_should_contain "Content-Length: " output ' - test_expect_success "HEAD $name with an explicit JSON format returns HTTP 200" ' - curl -I "http://127.0.0.1:$GWAY_PORT/ipfs/$CID?format=json" -o output && + test_expect_success "HEAD $name with an explicit DAG-JSON format returns HTTP 200" ' + curl -I "http://127.0.0.1:$GWAY_PORT/ipfs/$CID?format=dag-json" -o output && test_should_contain "HTTP/1.1 200 OK" output && - test_should_contain "Etag: \"$CID.json\"" output && - test_should_contain "Content-Type: application/json" output && - test_should_contain "Content-Length: " output - ' - test_expect_success "HEAD dag-pb with ?format=$format returns HTTP 200" ' - curl -I "http://127.0.0.1:$GWAY_PORT/ipfs/$FILE_CID?format=$format" -o output && - test_should_contain "HTTP/1.1 200 OK" output && - test_should_contain "Etag: \"$FILE_CID.$format\"" output && - test_should_contain "Content-Type: application/$format" output && + test_should_contain "Etag: \"$CID.dag-json\"" output && + test_should_contain "Content-Type: application/vnd.ipld.dag-json" output && test_should_contain "Content-Length: " output ' test_expect_success "HEAD $name with only-if-cached for missing block returns HTTP 412 Precondition Failed" ' From 0aa23b3ed8c9989cd97f72e813483643752751b9 Mon Sep 17 00:00:00 2001 From: Steve Loeppky Date: Sun, 22 Jan 2023 11:04:18 -0800 Subject: [PATCH 0422/1212] fix: clarity: no user supplied rcmgr limits of 0 (#9563) Co-authored-by: Antonio Navarro Perez Co-authored-by: Marcin Rataj --- core/node/libp2p/rcmgr.go | 16 +++++++++++----- docs/config.md | 3 +++ 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/core/node/libp2p/rcmgr.go b/core/node/libp2p/rcmgr.go index fe7fc635e..e0ce4693b 100644 --- a/core/node/libp2p/rcmgr.go +++ b/core/node/libp2p/rcmgr.go @@ -52,7 +52,8 @@ func ResourceManager(cfg config.SwarmConfig) interface{} { return nil, opts, fmt.Errorf("opening IPFS_PATH: %w", err) } - limitConfig, err := createDefaultLimitConfig(cfg) + var limitConfig rcmgr.LimitConfig + defaultComputedLimitConfig, err := createDefaultLimitConfig(cfg) if err != nil { return nil, opts, err } @@ -61,10 +62,15 @@ func ResourceManager(cfg config.SwarmConfig) interface{} { // is documented in docs/config.md. // Any changes here should be reflected there. if cfg.ResourceMgr.Limits != nil { - l := *cfg.ResourceMgr.Limits - // This effectively overrides the computed default LimitConfig with any vlues from cfg.ResourceMgr.Limits - l.Apply(limitConfig) - limitConfig = l + userSuppliedOverrideLimitConfig := *cfg.ResourceMgr.Limits + // This effectively overrides the computed default LimitConfig with any non-zero values from cfg.ResourceMgr.Limits. + // Because of how how Apply works, any 0 value for a user supplied override + // will be overriden with a computed default value. + // There currently isn't a way for a user to supply a 0-value override. + userSuppliedOverrideLimitConfig.Apply(defaultComputedLimitConfig) + limitConfig = userSuppliedOverrideLimitConfig + } else { + limitConfig = defaultComputedLimitConfig } if err := ensureConnMgrMakeSenseVsResourceMgr(limitConfig, cfg.ConnMgr); err != nil { diff --git a/docs/config.md b/docs/config.md index aae2017d0..da919d844 100644 --- a/docs/config.md +++ b/docs/config.md @@ -1844,6 +1844,9 @@ The `Swarm.ResourceMgr.Limits` override the default limits described above. Any override `BaseLimits` or limit s from `Swarm.ResourceMgr.Limits` that aren't specified will use the [computed default limits](./libp2p-resource-management.md#computed-default-limits). +Until [ipfs/kubo#9564](https://github.com/ipfs/kubo/issues/9564) is addressed, there isn't a way to set an override limit of zero. +0 is currently ignored. 0 currently means use to use the [computed default limits](./libp2p-resource-management.md#computed-default-limits). + Example #1: setting limits for a specific scope ```json { From 816904386bf6888140edd2d55fdfca6b99300f69 Mon Sep 17 00:00:00 2001 From: galargh Date: Mon, 23 Jan 2023 13:41:02 +0100 Subject: [PATCH 0423/1212] chore: update version.go --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index 81f938646..fd7416303 100644 --- a/version.go +++ b/version.go @@ -11,7 +11,7 @@ import ( var CurrentCommit string // CurrentVersionNumber is the current application's version literal -const CurrentVersionNumber = "0.18.0-rc2" +const CurrentVersionNumber = "0.18.0" const ApiVersion = "/kubo/" + CurrentVersionNumber + "/" //nolint From 7edf86c3b3bd210b65ba58ef439408e46afbfbb5 Mon Sep 17 00:00:00 2001 From: galargh Date: Mon, 23 Jan 2023 14:18:01 +0100 Subject: [PATCH 0424/1212] docs: update changelog --- docs/changelogs/v0.18.md | 537 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 537 insertions(+) diff --git a/docs/changelogs/v0.18.md b/docs/changelogs/v0.18.md index d10f56d77..e51c6d3b5 100644 --- a/docs/changelogs/v0.18.md +++ b/docs/changelogs/v0.18.md @@ -227,4 +227,541 @@ and various improvements have been made to improve the UX including: ### 📝 Changelog +
Full Changelog + +- github.com/ipfs/kubo: + - fix: clarity: no user supplied rcmgr limits of 0 (#9563) ([ipfs/kubo#9563](https://github.com/ipfs/kubo/pull/9563)) + - fix(gateway): undesired conversions to dag-json and friends (#9566) ([ipfs/kubo#9566](https://github.com/ipfs/kubo/pull/9566)) + - fix: ensure connmgr is smaller then autoscalled ressource limits + - fix: typo in ensureConnMgrMakeSenseVsResourcesMgr + - docs: clarify browser descriptions for webtransport + - fix: update saxon download path + - fix: refuse to start if connmgr is smaller than ressource limits and not using none connmgr + - fix: User-Agent sent to HTTP routers + - test: port gateway sharness tests to Go tests + - fix: do not download saxon in parallel + - docs: improve docs/README (#9539) ([ipfs/kubo#9539](https://github.com/ipfs/kubo/pull/9539)) + - test: port CircleCI to GH Actions and improve sharness reporting (#9355) ([ipfs/kubo#9355](https://github.com/ipfs/kubo/pull/9355)) + - chore: migrate from go-ipfs-files to go-libipfs/files (#9535) ([ipfs/kubo#9535](https://github.com/ipfs/kubo/pull/9535)) + - fix: stats dht command when Routing.Type=auto (#9538) ([ipfs/kubo#9538](https://github.com/ipfs/kubo/pull/9538)) + - fix: hint people to changing from RSA peer ids + - fix(gateway): JSON when Accept is a list + - fix(test): retry flaky t0125-twonode.sh + - docs: fix Router config Godoc (#9528) ([ipfs/kubo#9528](https://github.com/ipfs/kubo/pull/9528)) + - fix(ci): flaky sharness test + - docs(config): ProviderSearchDelay (#9526) ([ipfs/kubo#9526](https://github.com/ipfs/kubo/pull/9526)) + - docs: clarify debug environment variables + - chore: update version.go + - fix(test): stabilize flaky provider tests + - feat: port pins CLI test + - Removing QRI from early tester ([ipfs/kubo#9503](https://github.com/ipfs/kubo/pull/9503)) + - fix: disable provide over HTTP with Routing.Type=auto (#9511) ([ipfs/kubo#9511](https://github.com/ipfs/kubo/pull/9511)) + - Update version.go + - 'chore: update version.go' + - Clened up 0.18 changelog for release ([ipfs/kubo#9497](https://github.com/ipfs/kubo/pull/9497)) + - feat: turn on WebTransport by default ([ipfs/kubo#9492](https://github.com/ipfs/kubo/pull/9492)) + - feat: fast directory listings with DAG Size column (#9481) ([ipfs/kubo#9481](https://github.com/ipfs/kubo/pull/9481)) + - feat: add basic CLI tests using Go Test + - Changelog: v0.18.0 ([ipfs/kubo#9485](https://github.com/ipfs/kubo/pull/9485)) + - feat: go-libp2p-kad-dht with expiration 48h + - chore: update go-libp2p to v0.24.1 + - fix: remove the imports work-around + - fix: replace quic to quic-v1 for webtransport sharness + - fix: silence staticcheck warning for fx.Extract usage + - update go-libp2p to v0.24.0 + - stop using the deprecated go-libp2p-loggables package + - docs(readme): update package managers section (#9488) ([ipfs/kubo#9488](https://github.com/ipfs/kubo/pull/9488)) + - fix: support /quic-v1 in webui v0.21 + - feat: Routing.Type=auto (DHT+IPNI) (#9475) ([ipfs/kubo#9475](https://github.com/ipfs/kubo/pull/9475)) + - feat: adjust ConnMgr target to 32-96 (#9483) ([ipfs/kubo#9483](https://github.com/ipfs/kubo/pull/9483)) + - feat: increase default Reprovider.Interval (#9326) ([ipfs/kubo#9326](https://github.com/ipfs/kubo/pull/9326)) + - feat: add response body limiter to routing HTTP client (#9478) ([ipfs/kubo#9478](https://github.com/ipfs/kubo/pull/9478)) + - docs: libp2p resource management (#9468) ([ipfs/kubo#9468](https://github.com/ipfs/kubo/pull/9468)) + - chore: upgrade libipfs for routing HTTP API schema changes (#9477) ([ipfs/kubo#9477](https://github.com/ipfs/kubo/pull/9477)) + - feat: lower connection pool + - Add missing && + - Fix sharness test + - Added a message when RM is disabled. + - Requested changes. + - Fix sharness checking daemon output + - Update test/sharness/t0060-daemon.sh + - Try to fix sharness test. + - Fix: RM: Improve init RM message and fix final memory value. + - Fix: Resource Manager: Filter stats correctly by % + - Apply suggestions from code review + - Increase MaxMemory param to use half of total memory. + - Update libipfs dependency. + - Add sharness tests and documentation + - Fix variable name + - feature: delegated-routing: Add HTTP delegated routing. + - Fix: Change RM log output to WARN level + - Fix: RM: Set no-limit value to 1e9 (1000000000). + - Partial Revert "Revert "fix: ensure hasher is registered when using a hashing function"" + - Add logs to the routing system + - fix: apply agent-version-suffix to libp2p identify + - chore: migrate ipfs/tar-utils to libipfs + - feat(gateway): JSON and CBOR response formats (IPIP-328) (#9335) ([ipfs/kubo#9335](https://github.com/ipfs/kubo/pull/9335)) + - ([ipfs/kubo#9318](https://github.com/ipfs/kubo/pull/9318)) + - docs: release process updates from v0.17.0 ([ipfs/kubo#9391](https://github.com/ipfs/kubo/pull/9391)) + - fix(rcmgr): improve error phrasing + - docs: Update CHANGELOG.md adding 0.17 link + - feat(config): Pubsub.SeenMessagesTTL (#9372) ([ipfs/kubo#9372](https://github.com/ipfs/kubo/pull/9372)) + - docs: remove snap and chocolatey packages + - Merge release v0.17.0 ([ipfs/kubo#9431](https://github.com/ipfs/kubo/pull/9431)) + - docs: ipfs-http-client -> kubo-rpc-client (#9331) ([ipfs/kubo#9331](https://github.com/ipfs/kubo/pull/9331)) + - docs(readme): improve tldr + - Update config.md for resource management limits (#9421) ([ipfs/kubo#9421](https://github.com/ipfs/kubo/pull/9421)) + - Doc improvements and changelog for resource manager (#9413) ([ipfs/kubo#9413](https://github.com/ipfs/kubo/pull/9413)) + - Revert "Doc improvements for rcmgr" + - Doc improvements for rcmgr + - docs: document /wss fixes in 0.17 + - refactor(config): remove Swarm.ConnMgr defaults + - fix(config): skip nulls in ResourceMgr + - docs: replace tabcat with aphelionz in EARLY_TESTERS.md (#9404) ([ipfs/kubo#9404](https://github.com/ipfs/kubo/pull/9404)) + - docs: fix spoiler for 0.13.1 changelog + - fix(docs): typo + - chore: bump version to v0.18.0-dev ([ipfs/kubo#9393](https://github.com/ipfs/kubo/pull/9393)) +- github.com/ipfs/go-bitswap (v0.10.2 -> v0.11.0): + - chore: release v0.11.0 +- github.com/ipfs/go-blockservice (v0.4.0 -> v0.5.0): + - chore: release v0.5.0 +- github.com/ipfs/go-graphsync (v0.13.1 -> v0.14.1): + - chore: version 0.14.1 (#400) ([ipfs/go-graphsync#400](https://github.com/ipfs/go-graphsync/pull/400)) + - chore: migrate files (#399) ([ipfs/go-graphsync#399](https://github.com/ipfs/go-graphsync/pull/399)) + - docs(CHANGELOG): update for v0.14.0 release + - updates for libp2p v0.22 (#392) ([ipfs/go-graphsync#392](https://github.com/ipfs/go-graphsync/pull/392)) + - feat(ipld): use bindnode/registry (#386) ([ipfs/go-graphsync#386](https://github.com/ipfs/go-graphsync/pull/386)) + - Accept/Reject requests up front (#384) ([ipfs/go-graphsync#384](https://github.com/ipfs/go-graphsync/pull/384)) + - Remove protobuf protocol (#385) ([ipfs/go-graphsync#385](https://github.com/ipfs/go-graphsync/pull/385)) + - docs(CHANGELOG): update for v0.13.2 + - chore(deps): upgrade libp2p & ipld-prime (#389) ([ipfs/go-graphsync#389](https://github.com/ipfs/go-graphsync/pull/389)) + - chore(ipld): switch to using top-level ipld-prime codec helpers (#383) ([ipfs/go-graphsync#383](https://github.com/ipfs/go-graphsync/pull/383)) + - feat(requestmanager): read request from context (#381) ([ipfs/go-graphsync#381](https://github.com/ipfs/go-graphsync/pull/381)) + - fix: minor typo in error msg + - fix(panics): lift panic recovery up to top of network handling + - feat: expand use of panic handler to cover network and codec interaction + - feat(panics): capture panics from selector execution +- github.com/ipfs/go-ipfs-cmds (v0.8.1 -> v0.8.2): + - chore: version v0.8.2 (#235) ([ipfs/go-ipfs-cmds#235](https://github.com/ipfs/go-ipfs-cmds/pull/235)) + - chore: migrate files (#233) ([ipfs/go-ipfs-cmds#233](https://github.com/ipfs/go-ipfs-cmds/pull/233)) + - sync: update CI config files (#229) ([ipfs/go-ipfs-cmds#229](https://github.com/ipfs/go-ipfs-cmds/pull/229)) +- github.com/ipfs/go-ipfs-keystore (v0.0.2 -> v0.1.0): + - chore: release v0.1.0 + - chore: update go-libp2p + - sync: update CI config files ([ipfs/go-ipfs-keystore#10](https://github.com/ipfs/go-ipfs-keystore/pull/10)) + - sync: update CI config files ([ipfs/go-ipfs-keystore#8](https://github.com/ipfs/go-ipfs-keystore/pull/8)) + - Add link to pkg.go.dev + - README: this module does not use Gx +- github.com/ipfs/go-ipfs-provider (v0.7.1 -> v0.8.1): + - chore: release v0.8.1 + - fix: make queue 64bits on 32bits platforms too + - sync: update CI config files ([ipfs/go-ipfs-provider#36](https://github.com/ipfs/go-ipfs-provider/pull/36)) + - chore: update go-lib2p, avoid depending on go-libp2p-core, bump go.mod version +- github.com/ipfs/go-ipfs-routing (v0.2.1 -> v0.3.0): + - release v0.3.0 ([ipfs/go-ipfs-routing#36](https://github.com/ipfs/go-ipfs-routing/pull/36)) + - chore: update go-libp2p to v0.22.0 ([ipfs/go-ipfs-routing#35](https://github.com/ipfs/go-ipfs-routing/pull/35)) + - sync: update CI config files (#34) ([ipfs/go-ipfs-routing#34](https://github.com/ipfs/go-ipfs-routing/pull/34)) +- github.com/ipfs/go-ipld-cbor (v0.0.5 -> v0.0.6): + - Add contexts to IpldBlockstore ([ipfs/go-ipld-cbor#82](https://github.com/ipfs/go-ipld-cbor/pull/82)) + - sync: update CI config files (#81) ([ipfs/go-ipld-cbor#81](https://github.com/ipfs/go-ipld-cbor/pull/81)) + - sync: update CI config files ([ipfs/go-ipld-cbor#79](https://github.com/ipfs/go-ipld-cbor/pull/79)) + - Fix lint errors ([ipfs/go-ipld-cbor#78](https://github.com/ipfs/go-ipld-cbor/pull/78)) + - Add notice directing new projects to codec/dagcbor ([ipfs/go-ipld-cbor#77](https://github.com/ipfs/go-ipld-cbor/pull/77)) +- github.com/ipfs/go-merkledag (v0.6.0 -> v0.9.0): + - chore: bump version to 0.9.0 + - chore: bump version to 0.8.1 + - feat: remove panic() from non-error methods + - feat: improve broken cid.Builder testing for CidBuilder + - chore: bump version to 0.8.0 + - doc: document potential panics and how to avoid them + - fix: simplify Cid generation cache & usage + - feat: check links on setting and sanitise on encoding + - feat: check that the CidBuilder hasher is usable + - chore: bump version to 0.7.0 + - fix: remove use of ioutil + - run gofmt -s + - fix!: keep deserialised state stable until explicit mutation + - sync: update CI config files ([ipfs/go-merkledag#84](https://github.com/ipfs/go-merkledag/pull/84)) +- github.com/ipfs/go-namesys (v0.5.0 -> v0.6.0): + - chore: release v0.6.0 + - chore: update go-libp2p to v0.23.4, update go.mod version to 1.18 + - stop using the deprecated io/ioutil package +- github.com/ipfs/go-peertaskqueue (v0.7.1 -> v0.8.0): + - Release v0.8.0 ([ipfs/go-peertaskqueue#25](https://github.com/ipfs/go-peertaskqueue/pull/25)) + - chore: update go-libp2p to v0.22.0 ([ipfs/go-peertaskqueue#24](https://github.com/ipfs/go-peertaskqueue/pull/24)) + - sync: update CI config files (#23) ([ipfs/go-peertaskqueue#23](https://github.com/ipfs/go-peertaskqueue/pull/23)) + - sync: update CI config files (#21) ([ipfs/go-peertaskqueue#21](https://github.com/ipfs/go-peertaskqueue/pull/21)) +- github.com/ipfs/go-unixfs (v0.4.1 -> v0.4.2): + - chore: version 0.4.2 (#136) ([ipfs/go-unixfs#136](https://github.com/ipfs/go-unixfs/pull/136)) + - chore: migrate files (#134) ([ipfs/go-unixfs#134](https://github.com/ipfs/go-unixfs/pull/134)) + - ([ipfs/go-unixfs#128](https://github.com/ipfs/go-unixfs/pull/128)) +- github.com/ipfs/go-unixfsnode (v1.4.0 -> v1.5.1): + - v1.5.1 + - fix a possible `index out of range` crash ([ipfs/go-unixfsnode#39](https://github.com/ipfs/go-unixfsnode/pull/39)) + - add an ADL to preload hamt loading ([ipfs/go-unixfsnode#38](https://github.com/ipfs/go-unixfsnode/pull/38)) + - chore: bump version to 1.5.0 + - fix: remove use of ioutil + - run gofmt -s + - bump go.mod to Go 1.18 and run go fix + - test for reader / sizing behavior on large files ([ipfs/go-unixfsnode#34](https://github.com/ipfs/go-unixfsnode/pull/34)) + - add helper to approximate test creation patter from ipfs-files ([ipfs/go-unixfsnode#32](https://github.com/ipfs/go-unixfsnode/pull/32)) + - chore: remove Stebalien/go-bitfield in favour of ipfs/go-bitfield +- github.com/ipfs/interface-go-ipfs-core (v0.7.0 -> v0.8.2): + - chore: version 0.8.2 (#100) ([ipfs/interface-go-ipfs-core#100](https://github.com/ipfs/interface-go-ipfs-core/pull/100)) + - chore: migrate files (#97) ([ipfs/interface-go-ipfs-core#97](https://github.com/ipfs/interface-go-ipfs-core/pull/97)) + - chore: release v0.8.1 + - feat: add UseCumulativeSize UnixfsLs option (#95) ([ipfs/interface-go-ipfs-core#95](https://github.com/ipfs/interface-go-ipfs-core/pull/95)) + - chore: release v0.8.0 + - chore: update go-libp2p to v0.23.4 + - sync: update CI config files (#87) ([ipfs/interface-go-ipfs-core#87](https://github.com/ipfs/interface-go-ipfs-core/pull/87)) +- github.com/ipld/go-car/v2 (v2.4.0 -> v2.5.1): + - add a `SkipNext` method on block reader (#338) ([ipld/go-car#338](https://github.com/ipld/go-car/pull/338)) + - feat: Has() and Get() will respect StoreIdentityCIDs option + - chore: bump version to 0.5.0 + - fix: remove use of ioutil + - run gofmt -s + - bump go.mod to Go 1.18 and run go fix + - bump go.mod to Go 1.18 and run go fix + - OpenReadWriteFile: add test + - blockstore: allow to pass a file to write in (#323) ([ipld/go-car#323](https://github.com/ipld/go-car/pull/323)) + - feat: add `car inspect` command to cmd pkg (#320) ([ipld/go-car#320](https://github.com/ipld/go-car/pull/320)) + - Separate `index.ReadFrom` tests + - Only read index codec during inspection + - Upgrade to the latest `go-car/v2` + - Empty identity CID should be indexed when options are set +- github.com/ipld/go-codec-dagpb (v1.4.1 -> v1.5.0): + - chore: version bump to 1.5.0 + - fix: replace io/ioutil with io + - bump go.mod to Go 1.18 and run go fix + - v1.4.2 bump +- github.com/libp2p/go-libp2p (v0.23.4 -> v0.24.2): + - release v0.24.2 (#1969) ([libp2p/go-libp2p#1969](https://github.com/libp2p/go-libp2p/pull/1969)) + - webtransport: initialize a NullResourceManager if none is provided (#1962) ([libp2p/go-libp2p#1962](https://github.com/libp2p/go-libp2p/pull/1962)) + - release v0.24.1 (#1945) ([libp2p/go-libp2p#1945](https://github.com/libp2p/go-libp2p/pull/1945)) + - routed host: return Connect error if FindPeer doesn't yield new addresses (#1946) ([libp2p/go-libp2p#1946](https://github.com/libp2p/go-libp2p/pull/1946)) + - chore: update examples to v0.24.0 (#1936) ([libp2p/go-libp2p#1936](https://github.com/libp2p/go-libp2p/pull/1936)) + - webtransport: fix flaky accept queue test (#1938) ([libp2p/go-libp2p#1938](https://github.com/libp2p/go-libp2p/pull/1938)) + - quic: fix race condition in TestClientCanDialDifferentQUICVersions (#1937) ([libp2p/go-libp2p#1937](https://github.com/libp2p/go-libp2p/pull/1937)) + - quic: update quic-go to v0.31.1 (#1942) ([libp2p/go-libp2p#1942](https://github.com/libp2p/go-libp2p/pull/1942)) + - release v0.24.0 (#1934) ([libp2p/go-libp2p#1934](https://github.com/libp2p/go-libp2p/pull/1934)) + - Disable support for signed/static TLS certificates in WebTransport (#1927) ([libp2p/go-libp2p#1927](https://github.com/libp2p/go-libp2p/pull/1927)) + - webtransport: add PSK to constructor, and fail if it is used (#1929) ([libp2p/go-libp2p#1929](https://github.com/libp2p/go-libp2p/pull/1929)) + - use a different set of default transports when PSK is enabled (#1921) ([libp2p/go-libp2p#1921](https://github.com/libp2p/go-libp2p/pull/1921)) + - transport.Listener,quic: Support multiple QUIC versions with the same Listener. Only return a single multiaddr per listener. (#1923) ([libp2p/go-libp2p#1923](https://github.com/libp2p/go-libp2p/pull/1923)) + - quic / webtransport: make it possible to listen on the same address / port (#1905) ([libp2p/go-libp2p#1905](https://github.com/libp2p/go-libp2p/pull/1905)) + - autorelay: fix flaky TestReconnectToStaticRelays (#1903) ([libp2p/go-libp2p#1903](https://github.com/libp2p/go-libp2p/pull/1903)) + - swarm / rcmgr: synchronize the concurrent outbound dials with limits (#1898) ([libp2p/go-libp2p#1898](https://github.com/libp2p/go-libp2p/pull/1898)) + - add QUIC v1 addresses to the default listen addresses (#1914) ([libp2p/go-libp2p#1914](https://github.com/libp2p/go-libp2p/pull/1914)) + - webtransport: update webtransport-go to v0.3.0 (#1895) ([libp2p/go-libp2p#1895](https://github.com/libp2p/go-libp2p/pull/1895)) + - tls: fix flaky TestHandshakeConnectionCancellations test (#1896) ([libp2p/go-libp2p#1896](https://github.com/libp2p/go-libp2p/pull/1896)) + - holepunch: disable the resource manager in tests (#1897) ([libp2p/go-libp2p#1897](https://github.com/libp2p/go-libp2p/pull/1897)) + - transports: expose the name of the transport in the ConnectionState (#1911) ([libp2p/go-libp2p#1911](https://github.com/libp2p/go-libp2p/pull/1911)) + - respect the user's security protocol preference order ([libp2p/go-libp2p#1912](https://github.com/libp2p/go-libp2p/pull/1912)) + - circuitv2: disable the resource manager in tests (#1899) ([libp2p/go-libp2p#1899](https://github.com/libp2p/go-libp2p/pull/1899)) + - expose the security protocol on the ConnectionState ([libp2p/go-libp2p#1907](https://github.com/libp2p/go-libp2p/pull/1907)) + - fix: autorelay: treat static relays as just another peer source (#1875) ([libp2p/go-libp2p#1875](https://github.com/libp2p/go-libp2p/pull/1875)) + - feat: quic,webtransport: enable both quic-draft29 and quic-v1 addrs on quic. only quic-v1 on webtransport (#1881) ([libp2p/go-libp2p#1881](https://github.com/libp2p/go-libp2p/pull/1881)) + - holepunch: add multiaddress filter (#1839) ([libp2p/go-libp2p#1839](https://github.com/libp2p/go-libp2p/pull/1839)) + - README: remove broken links from table of contents (#1893) ([libp2p/go-libp2p#1893](https://github.com/libp2p/go-libp2p/pull/1893)) + - quic: update quic-go to v0.31.0 (#1882) ([libp2p/go-libp2p#1882](https://github.com/libp2p/go-libp2p/pull/1882)) + - add an integration test for muxer selection ([libp2p/go-libp2p#1887](https://github.com/libp2p/go-libp2p/pull/1887)) + - core/network: fix typo + - tls / noise: prefer the client's muxer preferences ([libp2p/go-libp2p#1888](https://github.com/libp2p/go-libp2p/pull/1888)) + - upgrader: absorb the muxer_multistream.Transport into the upgrader (#1885) ([libp2p/go-libp2p#1885](https://github.com/libp2p/go-libp2p/pull/1885)) + - Apply service peer default (#1878) ([libp2p/go-libp2p#1878](https://github.com/libp2p/go-libp2p/pull/1878)) + - webtransport: use deterministic TLS certificates (#1833) ([libp2p/go-libp2p#1833](https://github.com/libp2p/go-libp2p/pull/1833)) + - remove deprecated StaticRelays option (#1868) ([libp2p/go-libp2p#1868](https://github.com/libp2p/go-libp2p/pull/1868)) + - autorelay: remove the default static relay option (#1867) ([libp2p/go-libp2p#1867](https://github.com/libp2p/go-libp2p/pull/1867)) + - core/protocol: remove deprecated Negotiator.NegotiateLazy (#1869) ([libp2p/go-libp2p#1869](https://github.com/libp2p/go-libp2p/pull/1869)) + - config: use fx dependency injection to construct transports ([libp2p/go-libp2p#1858](https://github.com/libp2p/go-libp2p/pull/1858)) + - noise: add an option to allow unknown peer ID in SecureOutbound (#1823) ([libp2p/go-libp2p#1823](https://github.com/libp2p/go-libp2p/pull/1823)) + - Add some guard rails and docs (#1863) ([libp2p/go-libp2p#1863](https://github.com/libp2p/go-libp2p/pull/1863)) + - Fix concurrent map access in connmgr (#1860) ([libp2p/go-libp2p#1860](https://github.com/libp2p/go-libp2p/pull/1860)) + - fix: return filtered addrs (#1855) ([libp2p/go-libp2p#1855](https://github.com/libp2p/go-libp2p/pull/1855)) + - chore: preallocate slices (#1842) ([libp2p/go-libp2p#1842](https://github.com/libp2p/go-libp2p/pull/1842)) + - Close ping stream when we exit the loop (#1853) ([libp2p/go-libp2p#1853](https://github.com/libp2p/go-libp2p/pull/1853)) + - tls: don't set the deprecated tls.Config.PreferServerCipherSuites field (#1845) ([libp2p/go-libp2p#1845](https://github.com/libp2p/go-libp2p/pull/1845)) + - routed host: search for new multi addresses upon connect failure (#1835) ([libp2p/go-libp2p#1835](https://github.com/libp2p/go-libp2p/pull/1835)) + - core/peerstore: removed unused provider addr ttl constant (#1848) ([libp2p/go-libp2p#1848](https://github.com/libp2p/go-libp2p/pull/1848)) + - basichost: improve protocol negotiation debug message (#1846) ([libp2p/go-libp2p#1846](https://github.com/libp2p/go-libp2p/pull/1846)) + - noise: use Noise Extension to negotiate the muxer during the handshake (#1813) ([libp2p/go-libp2p#1813](https://github.com/libp2p/go-libp2p/pull/1813)) + - webtransport: use the rcmgr to control flow control window increases ([libp2p/go-libp2p#1832](https://github.com/libp2p/go-libp2p/pull/1832)) + - chore: update quic-go to v0.30.0 (#1838) ([libp2p/go-libp2p#1838](https://github.com/libp2p/go-libp2p/pull/1838)) + - roadmap: reorder priority, reorganize sections (#1831) ([libp2p/go-libp2p#1831](https://github.com/libp2p/go-libp2p/pull/1831)) + - websocket: set the HTTP host header in WSS(#1834) ([libp2p/go-libp2p#1834](https://github.com/libp2p/go-libp2p/pull/1834)) + - webtransport: make it possible to record qlogs (controlled by QLOGDIR env) ([libp2p/go-libp2p#1828](https://github.com/libp2p/go-libp2p/pull/1828)) + - ipfs /api/v0/id is post (#1819) ([libp2p/go-libp2p#1819](https://github.com/libp2p/go-libp2p/pull/1819)) + - examples: connect to all peers in example mdns chat app (#1798) ([libp2p/go-libp2p#1798](https://github.com/libp2p/go-libp2p/pull/1798)) + - roadmap: fix header level on "Mid Q4" (#1818) ([libp2p/go-libp2p#1818](https://github.com/libp2p/go-libp2p/pull/1818)) + - examples: use circuitv2 in relay example (#1795) ([libp2p/go-libp2p#1795](https://github.com/libp2p/go-libp2p/pull/1795)) + - add a roadmap for the next 6 months (#1784) ([libp2p/go-libp2p#1784](https://github.com/libp2p/go-libp2p/pull/1784)) + - tls: use ALPN to negotiate the stream multiplexer (#1772) ([libp2p/go-libp2p#1772](https://github.com/libp2p/go-libp2p/pull/1772)) + - tls: add tests for test vector from the spec (#1788) ([libp2p/go-libp2p#1788](https://github.com/libp2p/go-libp2p/pull/1788)) + - examples: update go-libp2p to v0.23.x (#1803) ([libp2p/go-libp2p#1803](https://github.com/libp2p/go-libp2p/pull/1803)) + - Try increasing timeouts if we're in CI for this test (#1796) ([libp2p/go-libp2p#1796](https://github.com/libp2p/go-libp2p/pull/1796)) + - Don't use rcmgr in this test (#1799) ([libp2p/go-libp2p#1799](https://github.com/libp2p/go-libp2p/pull/1799)) + - Bump timeout in CI for flaky test (#1800) ([libp2p/go-libp2p#1800](https://github.com/libp2p/go-libp2p/pull/1800)) + - Bump timeout in CI for flaky test (#1801) ([libp2p/go-libp2p#1801](https://github.com/libp2p/go-libp2p/pull/1801)) + - Fix comment in webtransport client auth handshake (#1793) ([libp2p/go-libp2p#1793](https://github.com/libp2p/go-libp2p/pull/1793)) + - examples: add basic pubsub-with-rendezvous example (#1738) ([libp2p/go-libp2p#1738](https://github.com/libp2p/go-libp2p/pull/1738)) + - quic: speed up the stateless reset test case (#1778) ([libp2p/go-libp2p#1778](https://github.com/libp2p/go-libp2p/pull/1778)) + - tls: fix flaky handshake cancellation test (#1779) ([libp2p/go-libp2p#1779](https://github.com/libp2p/go-libp2p/pull/1779)) +- github.com/libp2p/go-libp2p-gostream (v0.3.0 -> v0.5.0): + - release v0.5.0 (#74) ([libp2p/go-libp2p-gostream#74](https://github.com/libp2p/go-libp2p-gostream/pull/74)) + - update go-libp2p to v0.22.0 (#73) ([libp2p/go-libp2p-gostream#73](https://github.com/libp2p/go-libp2p-gostream/pull/73)) + - Expose some read-only methods on the underlying Stream interface (#67) ([libp2p/go-libp2p-gostream#67](https://github.com/libp2p/go-libp2p-gostream/pull/67)) + - Update libp2p ([libp2p/go-libp2p-gostream#69](https://github.com/libp2p/go-libp2p-gostream/pull/69)) + - sync: update CI config files (#65) ([libp2p/go-libp2p-gostream#65](https://github.com/libp2p/go-libp2p-gostream/pull/65)) + - sync: update CI config files ([libp2p/go-libp2p-gostream#62](https://github.com/libp2p/go-libp2p-gostream/pull/62)) + - fix staticcheck ([libp2p/go-libp2p-gostream#61](https://github.com/libp2p/go-libp2p-gostream/pull/61)) +- github.com/libp2p/go-libp2p-http (v0.2.1 -> v0.4.0): + - release v0.4.0 ([libp2p/go-libp2p-http#81](https://github.com/libp2p/go-libp2p-http/pull/81)) + - sync: update CI config files ([libp2p/go-libp2p-http#79](https://github.com/libp2p/go-libp2p-http/pull/79)) + - Update to latest go-libp2p ([libp2p/go-libp2p-http#80](https://github.com/libp2p/go-libp2p-http/pull/80)) + - Update to latest go-libp2p ([libp2p/go-libp2p-http#78](https://github.com/libp2p/go-libp2p-http/pull/78)) + - sync: update CI config files (#73) ([libp2p/go-libp2p-http#73](https://github.com/libp2p/go-libp2p-http/pull/73)) +- github.com/libp2p/go-libp2p-kad-dht (v0.18.0 -> v0.20.0): + - release v0.20.0 (#803) ([libp2p/go-libp2p-kad-dht#803](https://github.com/libp2p/go-libp2p-kad-dht/pull/803)) + - feat: increase the max record age to 48h (PUT_VALUE, RFM17) (#794) ([libp2p/go-libp2p-kad-dht#794](https://github.com/libp2p/go-libp2p-kad-dht/pull/794)) + - feat: increase expiration time for Provider Records to 48h (RFM17) + - release v0.19.0 (#801) ([libp2p/go-libp2p-kad-dht#801](https://github.com/libp2p/go-libp2p-kad-dht/pull/801)) + - define the ProviderAddrTTL in this repo (#797) ([libp2p/go-libp2p-kad-dht#797](https://github.com/libp2p/go-libp2p-kad-dht/pull/797)) +- github.com/libp2p/go-libp2p-kbucket (v0.4.7 -> v0.5.0): + - chore: release 0.5.0 (#111) ([libp2p/go-libp2p-kbucket#111](https://github.com/libp2p/go-libp2p-kbucket/pull/111)) + - deprecate go-libp2p-core and use go-libp2p instead (#109) ([libp2p/go-libp2p-kbucket#109](https://github.com/libp2p/go-libp2p-kbucket/pull/109)) + - sync: update CI config files (#108) ([libp2p/go-libp2p-kbucket#108](https://github.com/libp2p/go-libp2p-kbucket/pull/108)) + - sync: update CI config files ([libp2p/go-libp2p-kbucket#107](https://github.com/libp2p/go-libp2p-kbucket/pull/107)) + - sync: update CI config files (#104) ([libp2p/go-libp2p-kbucket#104](https://github.com/libp2p/go-libp2p-kbucket/pull/104)) + - sync: update CI config files ([libp2p/go-libp2p-kbucket#101](https://github.com/libp2p/go-libp2p-kbucket/pull/101)) + - sync: update CI config files ([libp2p/go-libp2p-kbucket#99](https://github.com/libp2p/go-libp2p-kbucket/pull/99)) + - fix staticcheck ([libp2p/go-libp2p-kbucket#98](https://github.com/libp2p/go-libp2p-kbucket/pull/98)) +- github.com/libp2p/go-libp2p-pubsub (v0.6.1 -> v0.8.2): + - Add docstring for WithAppSpecificRPCInspector (#510) ([libp2p/go-libp2p-pubsub#510](https://github.com/libp2p/go-libp2p-pubsub/pull/510)) + - Adds Application Specific RPC Inspector (#509) ([libp2p/go-libp2p-pubsub#509](https://github.com/libp2p/go-libp2p-pubsub/pull/509)) + - chore: ignore signing keys during WithLocalPublication publishing (#497) ([libp2p/go-libp2p-pubsub#497](https://github.com/libp2p/go-libp2p-pubsub/pull/497)) + - improve handling of dead peers (#508) ([libp2p/go-libp2p-pubsub#508](https://github.com/libp2p/go-libp2p-pubsub/pull/508)) + - perf: use pooled buffers for message writes (#507) ([libp2p/go-libp2p-pubsub#507](https://github.com/libp2p/go-libp2p-pubsub/pull/507)) + - perf: use msgio pooled buffers for received msgs (#500) ([libp2p/go-libp2p-pubsub#500](https://github.com/libp2p/go-libp2p-pubsub/pull/500)) + - Enables injectable GossipSub router (#503) ([libp2p/go-libp2p-pubsub#503](https://github.com/libp2p/go-libp2p-pubsub/pull/503)) + - Enables non-atomic validation for peer scoring parameters (#499) ([libp2p/go-libp2p-pubsub#499](https://github.com/libp2p/go-libp2p-pubsub/pull/499)) + - update go-libp2p to v0.22.0 (#498) ([libp2p/go-libp2p-pubsub#498](https://github.com/libp2p/go-libp2p-pubsub/pull/498)) + - fix handling of dead peers (#492) ([libp2p/go-libp2p-pubsub#492](https://github.com/libp2p/go-libp2p-pubsub/pull/492)) + - feat: WithLocalPublication option to enable local only publishing on a topic (#481) ([libp2p/go-libp2p-pubsub#481](https://github.com/libp2p/go-libp2p-pubsub/pull/481)) + - update pubsub deps (#491) ([libp2p/go-libp2p-pubsub#491](https://github.com/libp2p/go-libp2p-pubsub/pull/491)) + - Gossipsub: Unsubscribe backoff (#488) ([libp2p/go-libp2p-pubsub#488](https://github.com/libp2p/go-libp2p-pubsub/pull/488)) + - Adds exponential backoff to re-spawing new streams for supposedly dead peers (#483) ([libp2p/go-libp2p-pubsub#483](https://github.com/libp2p/go-libp2p-pubsub/pull/483)) + - Publishing option for signing a message with a custom private key (#486) ([libp2p/go-libp2p-pubsub#486](https://github.com/libp2p/go-libp2p-pubsub/pull/486)) + - fix unused GossipSubHistoryGossip, make seenMessages ttl configurable, make score params SeenMsgTTL configurable + - Update README.md + - Add in Backoff Check + - Modify comment + - Add Backoff For Pruned Peers + - tests: new test for WithTopicMsgIdFunction + - chore: better name + - feat: detach WithMsgIdFunction + - fix: use RawID in traceRPCMeta to avoid allocations + - feat: extract RawID from ID + - chore: hello mister mutex hat + - chore: go fmt and return timecache named import + - feat: new WithMsgIdFunction topic option to enable topics to have own msg id generation rules + - feat: integrate msgIdGenerator + - feat: introduce msgIdGenerator and add ID field to Message wrapper +- github.com/libp2p/go-libp2p-pubsub-router (v0.5.0 -> v0.6.0): + - release v0.6.0 (#99) ([libp2p/go-libp2p-pubsub-router#99](https://github.com/libp2p/go-libp2p-pubsub-router/pull/99)) + - sync: update CI config files (#93) ([libp2p/go-libp2p-pubsub-router#93](https://github.com/libp2p/go-libp2p-pubsub-router/pull/93)) +- github.com/libp2p/go-libp2p-routing-helpers (v0.4.0 -> v0.6.0): + - Update version.json + - Change interface name + - Add tests + - Feat: retrieve routers from composable routers + - Update version.json + - Update version.json + - chore: add regression test for compparallel deadlock + - Add logs to composable parallel + - Bump version to v0.4.1 + - ([libp2p/go-libp2p-routing-helpers#64](https://github.com/libp2p/go-libp2p-routing-helpers/pull/64)) +- github.com/lucas-clemente/quic-go (v0.29.1 -> v0.31.1): + - qerr: include role (remote / local) in error string representations (#3629) ([lucas-clemente/quic-go#3629](https://github.com/lucas-clemente/quic-go/pull/3629)) + - introduce a type for the stateless reset key (#3621) ([lucas-clemente/quic-go#3621](https://github.com/lucas-clemente/quic-go/pull/3621)) + - limit the exponential PTO backoff to 60s (#3595) ([lucas-clemente/quic-go#3595](https://github.com/lucas-clemente/quic-go/pull/3595)) + - expose the QUIC version of a connection (#3620) ([lucas-clemente/quic-go#3620](https://github.com/lucas-clemente/quic-go/pull/3620)) + - expose function to convert byte slice to a connection ID (#3614) ([lucas-clemente/quic-go#3614](https://github.com/lucas-clemente/quic-go/pull/3614)) + - use `go run` for mockgen, goimports and ginkgo (#3616) ([lucas-clemente/quic-go#3616](https://github.com/lucas-clemente/quic-go/pull/3616)) + - fix client SNI handling (#3613) ([lucas-clemente/quic-go#3613](https://github.com/lucas-clemente/quic-go/pull/3613)) + - chore: fix multiple typos in comments (#3612) ([lucas-clemente/quic-go#3612](https://github.com/lucas-clemente/quic-go/pull/3612)) + - use the new zero-allocation control message parsing function from x/sys (#3609) ([lucas-clemente/quic-go#3609](https://github.com/lucas-clemente/quic-go/pull/3609)) + - http3: add support for parsing and writing HTTP/3 capsules (#3607) ([lucas-clemente/quic-go#3607](https://github.com/lucas-clemente/quic-go/pull/3607)) + - http3: add request to response (#3608) ([lucas-clemente/quic-go#3608](https://github.com/lucas-clemente/quic-go/pull/3608)) + - fix availability signaling of the send queue (#3597) ([lucas-clemente/quic-go#3597](https://github.com/lucas-clemente/quic-go/pull/3597)) + - http3: add a ConnectionState method to the StreamCreator interface (#3600) ([lucas-clemente/quic-go#3600](https://github.com/lucas-clemente/quic-go/pull/3600)) + - http3: add a Context method to the StreamCreator interface (#3601) ([lucas-clemente/quic-go#3601](https://github.com/lucas-clemente/quic-go/pull/3601)) + - rename the variable in quic.Config.AllowConnectionWindowIncrease (#3602) ([lucas-clemente/quic-go#3602](https://github.com/lucas-clemente/quic-go/pull/3602)) + - migrate to Ginkgo v2, remove benchmark test ([lucas-clemente/quic-go#3589](https://github.com/lucas-clemente/quic-go/pull/3589)) + - don't drop more than 10 consecutive packets in drop test (#3584) ([lucas-clemente/quic-go#3584](https://github.com/lucas-clemente/quic-go/pull/3584)) + - use a monotonous timer for the connection (#3570) ([lucas-clemente/quic-go#3570](https://github.com/lucas-clemente/quic-go/pull/3570)) + - http3: add http3.Server.ServeQUICConn to serve a single QUIC connection (#3587) ([lucas-clemente/quic-go#3587](https://github.com/lucas-clemente/quic-go/pull/3587)) + - http3: expose ALPN values (#3580) ([lucas-clemente/quic-go#3580](https://github.com/lucas-clemente/quic-go/pull/3580)) + - log the size of buffered packets (#3571) ([lucas-clemente/quic-go#3571](https://github.com/lucas-clemente/quic-go/pull/3571)) + - ackhandler: reject duplicate packets in ReceivedPacket (#3568) ([lucas-clemente/quic-go#3568](https://github.com/lucas-clemente/quic-go/pull/3568)) + - reduce max DATAGRAM frame size, so that DATAGRAMs fit in IPv6 packets (#3581) ([lucas-clemente/quic-go#3581](https://github.com/lucas-clemente/quic-go/pull/3581)) + - use a Peek / Pop API for the datagram queue (#3582) ([lucas-clemente/quic-go#3582](https://github.com/lucas-clemente/quic-go/pull/3582)) + - http3: handle ErrAbortHandler when the handler panics (#3575) ([lucas-clemente/quic-go#3575](https://github.com/lucas-clemente/quic-go/pull/3575)) + - http3: fix double close of chan when using DontCloseRequestStream (#3561) ([lucas-clemente/quic-go#3561](https://github.com/lucas-clemente/quic-go/pull/3561)) + - qlog: rename key_retired to key_discarded (#3463) ([lucas-clemente/quic-go#3463](https://github.com/lucas-clemente/quic-go/pull/3463)) + - simplify packing of ACK-only packets ([lucas-clemente/quic-go#3545](https://github.com/lucas-clemente/quic-go/pull/3545)) + - use a sync.Pool for ACK frames ([lucas-clemente/quic-go#3547](https://github.com/lucas-clemente/quic-go/pull/3547)) + - prioritize sending ACKs over sending new DATAGRAM frames (#3544) ([lucas-clemente/quic-go#3544](https://github.com/lucas-clemente/quic-go/pull/3544)) + - http3: reduce usage of bytes.Buffer (#3539) ([lucas-clemente/quic-go#3539](https://github.com/lucas-clemente/quic-go/pull/3539)) + - use a single bytes.Reader for frame parsing (#3536) ([lucas-clemente/quic-go#3536](https://github.com/lucas-clemente/quic-go/pull/3536)) + - split code paths for packing 0-RTT and 1-RTT packets in packet packer (#3540) ([lucas-clemente/quic-go#3540](https://github.com/lucas-clemente/quic-go/pull/3540)) + - remove the wire.ShortHeader in favor of more return values (#3535) ([lucas-clemente/quic-go#3535](https://github.com/lucas-clemente/quic-go/pull/3535)) + - preallocate the message buffers of the ipv4.Message passed to ReadBatch (#3541) ([lucas-clemente/quic-go#3541](https://github.com/lucas-clemente/quic-go/pull/3541)) + - introduce a separate code paths for Short Header packet handling ([lucas-clemente/quic-go#3534](https://github.com/lucas-clemente/quic-go/pull/3534)) + - fix usage of ackhandler.Packet pool for non-ack-eliciting packets (#3538) ([lucas-clemente/quic-go#3538](https://github.com/lucas-clemente/quic-go/pull/3538)) + - return an error when parsing a too long connection ID from a header (#3533) ([lucas-clemente/quic-go#3533](https://github.com/lucas-clemente/quic-go/pull/3533)) + - speed up marshaling of transport parameters (#3531) ([lucas-clemente/quic-go#3531](https://github.com/lucas-clemente/quic-go/pull/3531)) + - use a struct containing an array to represent Connection IDs ([lucas-clemente/quic-go#3529](https://github.com/lucas-clemente/quic-go/pull/3529)) + - reduce allocations of ackhandler.Packet ([lucas-clemente/quic-go#3525](https://github.com/lucas-clemente/quic-go/pull/3525)) + - serialize frames by appending to a byte slice, not to a bytes.Buffer ([lucas-clemente/quic-go#3530](https://github.com/lucas-clemente/quic-go/pull/3530)) + - fix datagram RFC number in documentation for quic.Config (#3523) ([lucas-clemente/quic-go#3523](https://github.com/lucas-clemente/quic-go/pull/3523)) + - add DPLPMTUD (RFC 8899) to list of supported RFCs in README (#3520) ([lucas-clemente/quic-go#3520](https://github.com/lucas-clemente/quic-go/pull/3520)) + - use the null tracers in the tracer integration tests (#3528) ([lucas-clemente/quic-go#3528](https://github.com/lucas-clemente/quic-go/pull/3528)) +- github.com/marten-seemann/webtransport-go (v0.1.1 -> v0.4.3): + - release v0.4.3 (#57) ([marten-seemann/webtransport-go#57](https://github.com/marten-seemann/webtransport-go/pull/57)) + - return the correct error from OpenStreamSync when context is canceled (#55) ([marten-seemann/webtransport-go#55](https://github.com/marten-seemann/webtransport-go/pull/55)) + - release v0.4.2 (#54) ([marten-seemann/webtransport-go#54](https://github.com/marten-seemann/webtransport-go/pull/54)) + - use a buffered channel in the acceptQueue (#53) ([marten-seemann/webtransport-go#53](https://github.com/marten-seemann/webtransport-go/pull/53)) + - add a comment why using (a blocking) Read in the StreamHijacker is fine + - release v0.4.1 (#52) ([marten-seemann/webtransport-go#52](https://github.com/marten-seemann/webtransport-go/pull/52)) + - release session mutex when an error occurs when closing (#51) ([marten-seemann/webtransport-go#51](https://github.com/marten-seemann/webtransport-go/pull/51)) + - release v0.4.0 (#48) ([marten-seemann/webtransport-go#48](https://github.com/marten-seemann/webtransport-go/pull/48)) + - add a Server.ServeQUICConn method (#47) ([marten-seemann/webtransport-go#47](https://github.com/marten-seemann/webtransport-go/pull/47)) + - release v0.3.0 (#46) ([marten-seemann/webtransport-go#46](https://github.com/marten-seemann/webtransport-go/pull/46)) + - read and write CLOSE_WEBTRANSPORT_SESSION capsules ([marten-seemann/webtransport-go#40](https://github.com/marten-seemann/webtransport-go/pull/40)) + - implement the SetDeadline method on the stream (#44) ([marten-seemann/webtransport-go#44](https://github.com/marten-seemann/webtransport-go/pull/44)) + - expose the QUIC stream ID on the stream interfaces (#43) ([marten-seemann/webtransport-go#43](https://github.com/marten-seemann/webtransport-go/pull/43)) + - release v0.2.0 (#38) ([marten-seemann/webtransport-go#38](https://github.com/marten-seemann/webtransport-go/pull/38)) + - expose quic-go's connection tracing ID on the Session.Context (#35) ([marten-seemann/webtransport-go#35](https://github.com/marten-seemann/webtransport-go/pull/35)) + - add a ConnectionState method to the Session (#33) ([marten-seemann/webtransport-go#33](https://github.com/marten-seemann/webtransport-go/pull/33)) + - chore: update quic-go to v0.30.0 (#36) ([marten-seemann/webtransport-go#36](https://github.com/marten-seemann/webtransport-go/pull/36)) + - fix interop build (#37) ([marten-seemann/webtransport-go#37](https://github.com/marten-seemann/webtransport-go/pull/37)) + - rename session receiver variable (#34) ([marten-seemann/webtransport-go#34](https://github.com/marten-seemann/webtransport-go/pull/34)) + - fix double close of chan when using DontCloseRequestStream (#30) ([marten-seemann/webtransport-go#30](https://github.com/marten-seemann/webtransport-go/pull/30)) + - add a simple integration test using Selenium and a headless Chrome (#28) ([marten-seemann/webtransport-go#28](https://github.com/marten-seemann/webtransport-go/pull/28)) + - use a generic accept queue for uni- and bidirectional streams (#26) ([marten-seemann/webtransport-go#26](https://github.com/marten-seemann/webtransport-go/pull/26)) +- github.com/multiformats/go-base36 (v0.1.0 -> v0.2.0): + - v0.2.0 + - sync: update CI config files (#11) ([multiformats/go-base36#11](https://github.com/multiformats/go-base36/pull/11)) + - fix link to documentation (#9) ([multiformats/go-base36#9](https://github.com/multiformats/go-base36/pull/9)) + - sync: update CI config files (#8) ([multiformats/go-base36#8](https://github.com/multiformats/go-base36/pull/8)) + - Address `staticcheck` issue ([multiformats/go-base36#5](https://github.com/multiformats/go-base36/pull/5)) + - Feat/fasterer ([multiformats/go-base36#4](https://github.com/multiformats/go-base36/pull/4)) +- github.com/multiformats/go-multiaddr (v0.7.0 -> v0.8.0): + - release v0.8.0 ([multiformats/go-multiaddr#187](https://github.com/multiformats/go-multiaddr/pull/187)) + - Add quic-v1 component ([multiformats/go-multiaddr#186](https://github.com/multiformats/go-multiaddr/pull/186)) +- github.com/multiformats/go-varint (v0.0.6 -> v0.0.7): + - v0.0.7 ([multiformats/go-varint#18](https://github.com/multiformats/go-varint/pull/18)) + - feat: optimize decoding (#15) ([multiformats/go-varint#15](https://github.com/multiformats/go-varint/pull/15)) + - sync: update CI config files (#13) ([multiformats/go-varint#13](https://github.com/multiformats/go-varint/pull/13)) + - fix staticcheck ([multiformats/go-varint#9](https://github.com/multiformats/go-varint/pull/9)) + - tests for unbounded uvarint streams. ([multiformats/go-varint#7](https://github.com/multiformats/go-varint/pull/7)) +- github.com/whyrusleeping/cbor-gen (v0.0.0-20210219115102-f37d292932f2 -> v0.0.0-20221220214510-0333c149dec0): + - fix bug in consts code + - Allow 'const' fields to be declared ([whyrusleeping/cbor-gen#78](https://github.com/whyrusleeping/cbor-gen/pull/78)) + - support omitting empty fields on map encoders ([whyrusleeping/cbor-gen#77](https://github.com/whyrusleeping/cbor-gen/pull/77)) + - support string pointers + - feat: add the ability to encode a byte array (#76) ([whyrusleeping/cbor-gen#76](https://github.com/whyrusleeping/cbor-gen/pull/76)) + - support string slices (#73) ([whyrusleeping/cbor-gen#73](https://github.com/whyrusleeping/cbor-gen/pull/73)) + - Feat/size types ([whyrusleeping/cbor-gen#69](https://github.com/whyrusleeping/cbor-gen/pull/69)) + - Add CborReader and CborWriter (#67) ([whyrusleeping/cbor-gen#67](https://github.com/whyrusleeping/cbor-gen/pull/67)) + - Fix broken TestTimeIsh (#66) ([whyrusleeping/cbor-gen#66](https://github.com/whyrusleeping/cbor-gen/pull/66)) + - Return EOF and ErrUnexpectedEOF correctly (#64) ([whyrusleeping/cbor-gen#64](https://github.com/whyrusleeping/cbor-gen/pull/64)) + - fix: don't fail if we try to discard nothing at the end of an object ([whyrusleeping/cbor-gen#63](https://github.com/whyrusleeping/cbor-gen/pull/63)) + - Make peeker.ReadByte follow buffer.ReadByte semantics ([whyrusleeping/cbor-gen#61](https://github.com/whyrusleeping/cbor-gen/pull/61)) + - Fix read bug in readByteBuf ([whyrusleeping/cbor-gen#60](https://github.com/whyrusleeping/cbor-gen/pull/60)) + - support for cborgen struct field tags ([whyrusleeping/cbor-gen#58](https://github.com/whyrusleeping/cbor-gen/pull/58)) + - feat: take cbor adapters by-value when encoding ([whyrusleeping/cbor-gen#55](https://github.com/whyrusleeping/cbor-gen/pull/55)) + - fix: import "math" in generated code for uint8 unmarshalling ([whyrusleeping/cbor-gen#53](https://github.com/whyrusleeping/cbor-gen/pull/53)) + - doc: document Write*EncodersToFile functions ([whyrusleeping/cbor-gen#52](https://github.com/whyrusleeping/cbor-gen/pull/52)) + +
+ ### 👨‍👩‍👧‍👦 Contributors + +| Contributor | Commits | Lines ± | Files Changed | +|-------------|---------|---------|---------------| +| Marten Seemann | 154 | +8826/-6369 | 911 | +| Gus Eggert | 7 | +2792/-1444 | 40 | +| Marco Munizaga | 26 | +2324/-752 | 101 | +| hannahhoward | 7 | +695/-1587 | 50 | +| Rod Vagg | 30 | +1508/-668 | 106 | +| Henrique Dias | 13 | +1321/-431 | 85 | +| Yahya Hassanzadeh | 4 | +984/-158 | 9 | +| galargh | 17 | +519/-520 | 20 | +| Steve Loeppky | 11 | +612/-418 | 25 | +| Antonio Navarro Perez | 30 | +742/-88 | 47 | +| Marcin Rataj | 19 | +377/-407 | 52 | +| Ian Davis | 2 | +419/-307 | 7 | +| whyrusleeping | 5 | +670/-28 | 17 | +| Piotr Galar | 8 | +211/-417 | 25 | +| web3-bot | 28 | +282/-264 | 75 | +| Will Scott | 10 | +428/-103 | 19 | +| julian88110 | 2 | +367/-55 | 27 | +| Will | 5 | +282/-131 | 65 | +| Jorropo | 25 | +263/-94 | 38 | +| Wondertan | 10 | +203/-87 | 24 | +| Mohsin Zaidi | 1 | +269/-0 | 4 | +| Dennis Trautwein | 3 | +230/-21 | 7 | +| Prithvi Shahi | 1 | +116/-77 | 1 | +| Masih H. Derkani | 5 | +130/-37 | 11 | +| Iulian Pascalau | 1 | +151/-16 | 2 | +| Scott Martin | 1 | +166/-0 | 3 | +| Daniel Vernall | 1 | +92/-45 | 2 | +| Steven Allen | 7 | +114/-15 | 11 | +| Hlib Kanunnikov | 4 | +100/-28 | 6 | +| Peter Rabbitson | 4 | +59/-65 | 5 | +| Lucas Molas | 1 | +60/-57 | 7 | +| nisdas | 3 | +107/-6 | 5 | +| why | 2 | +80/-20 | 5 | +| ShengTao | 2 | +46/-45 | 16 | +| nisainan | 2 | +40/-50 | 12 | +| Mikel Cortes | 3 | +44/-36 | 10 | +| Chinmay Kousik | 1 | +64/-14 | 6 | +| ZenGround0 | 2 | +62/-15 | 6 | +| Antonio Navarro | 3 | +58/-3 | 8 | +| Michael Muré | 2 | +49/-2 | 2 | +| Dirk McCormick | 1 | +3/-42 | 1 | +| kixelated | 1 | +20/-20 | 4 | +| Russell Dempsey | 1 | +19/-17 | 3 | +| Karthik Nallabolu | 1 | +17/-17 | 1 | +| protolambda | 1 | +26/-4 | 4 | +| cliffc-spirent | 1 | +25/-5 | 2 | +| Raúl Kripalani | 1 | +29/-0 | 1 | +| Håvard Anda Estensen | 1 | +9/-19 | 6 | +| vyzo | 1 | +11/-12 | 1 | +| anorth | 1 | +15/-8 | 3 | +| shade34321 | 1 | +21/-1 | 2 | +| Toby | 2 | +9/-13 | 6 | +| Nishant Das | 1 | +9/-9 | 5 | +| Jeromy Johnson | 1 | +17/-0 | 3 | +| Oleg | 1 | +14/-1 | 1 | +| Hector Sanjuan | 6 | +4/-11 | 6 | +| Łukasz Magiera | 2 | +10/-4 | 2 | +| Aayush Rajasekaran | 1 | +7/-7 | 1 | +| Adin Schmahmann | 1 | +4/-3 | 1 | +| Stojan Dimitrovski | 1 | +6/-0 | 1 | +| Mathew Jacob | 1 | +3/-3 | 1 | +| Vladimir Ivanov | 1 | +2/-2 | 1 | +| Nex Zhu | 1 | +4/-0 | 2 | +| Michele Mastrogiovanni | 1 | +2/-2 | 1 | +| Louis Thibault | 1 | +4/-0 | 1 | +| Eric Myhre | 1 | +3/-1 | 1 | +| Kubo Mage | 2 | +2/-1 | 2 | +| tabcat | 1 | +1/-1 | 1 | +| Viacheslav | 1 | +1/-1 | 1 | +| Max Inden | 1 | +1/-1 | 1 | +| Manic Security | 1 | +1/-1 | 1 | +| Jc0803kevin | 1 | +1/-1 | 1 | +| David Brouwer | 1 | +2/-0 | 2 | +| Rong Zhou | 1 | +1/-0 | 1 | +| Neel Virdy | 1 | +1/-0 | 1 | From b3cc938630bc7607f86afed9ba4c1cdfda07e828 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Tue, 24 Jan 2023 23:44:55 +0100 Subject: [PATCH 0425/1212] feat: add namesys publish options (#94) * feat: add namesys publish options * feat: export DefaultIPNSRecordEOL * feat: export DefaultIPNSRecordTTL This commit was moved from ipfs/interface-go-ipfs-core@468dea4bb45aec6ddce2a6225334dcc062d6e752 This commit was moved from ipfs/boxo@bcb9190c2bdbc0ad4823a1b1785fb87ec8014723 --- core/coreiface/options/namesys/opts.go | 49 ++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/core/coreiface/options/namesys/opts.go b/core/coreiface/options/namesys/opts.go index ee2bd5ac2..0cd1ba778 100644 --- a/core/coreiface/options/namesys/opts.go +++ b/core/coreiface/options/namesys/opts.go @@ -13,6 +13,15 @@ const ( // trust resolution to eventually complete and can't put an upper // limit on how many steps it will take. UnlimitedDepth = 0 + + // DefaultIPNSRecordTTL specifies the time that the record can be cached + // before checking if its validity again. + DefaultIPNSRecordTTL = time.Minute + + // DefaultIPNSRecordEOL specifies the time that the network will cache IPNS + // records after being published. Records should be re-published before this + // interval expires. We use the same default expiration as the DHT. + DefaultIPNSRecordEOL = 48 * time.Hour ) // ResolveOpts specifies options for resolving an IPNS path @@ -72,3 +81,43 @@ func ProcessOpts(opts []ResolveOpt) ResolveOpts { } return rsopts } + +// PublishOptions specifies options for publishing an IPNS record. +type PublishOptions struct { + EOL time.Time + TTL time.Duration +} + +// DefaultPublishOptions returns the default options for publishing an IPNS record. +func DefaultPublishOptions() PublishOptions { + return PublishOptions{ + EOL: time.Now().Add(DefaultIPNSRecordEOL), + TTL: DefaultIPNSRecordTTL, + } +} + +// PublishOption is used to set an option for PublishOpts. +type PublishOption func(*PublishOptions) + +// PublishWithEOL sets an EOL. +func PublishWithEOL(eol time.Time) PublishOption { + return func(o *PublishOptions) { + o.EOL = eol + } +} + +// PublishWithEOL sets a TTL. +func PublishWithTTL(ttl time.Duration) PublishOption { + return func(o *PublishOptions) { + o.TTL = ttl + } +} + +// ProcessPublishOptions converts an array of PublishOpt into a PublishOpts object. +func ProcessPublishOptions(opts []PublishOption) PublishOptions { + rsopts := DefaultPublishOptions() + for _, option := range opts { + option(&rsopts) + } + return rsopts +} From b0296bbea61533efa8b9b6900935a1aaa7a2e8e6 Mon Sep 17 00:00:00 2001 From: galargh Date: Thu, 26 Jan 2023 11:12:29 +0100 Subject: [PATCH 0426/1212] feat: structure release checklist around kuboreleaser commands --- docs/RELEASE_ISSUE_TEMPLATE.md | 263 ++++++++++++++------------------- 1 file changed, 108 insertions(+), 155 deletions(-) diff --git a/docs/RELEASE_ISSUE_TEMPLATE.md b/docs/RELEASE_ISSUE_TEMPLATE.md index ad0ff060d..1fc391f67 100644 --- a/docs/RELEASE_ISSUE_TEMPLATE.md +++ b/docs/RELEASE_ISSUE_TEMPLATE.md @@ -15,6 +15,7 @@ * Expected RC date: week of YYYY-MM-DD * 🚢 Expected final release date: YYYY-MM-DD * Accompanying PR for improving the release process: (example: https://github.com/ipfs/kubo/pull/9391) +* Accompanying Issue for updating the infra: (example: https://github.com/protocol/bifrost-infra/issues/2221) See the [Kubo release process](https://pl-strflt.notion.site/Kubo-Release-Process-5a5d066264704009a28a79cff93062c4) for more info. @@ -38,195 +39,147 @@ As usual, this release includes important fixes, some of which may be critical f ## ✅ Release Checklist -Checklist: - -- [ ] **Stage 0 - Prerequisites** - - [ ] Open an issue against [bifrost-infra](https://github.com/protocol/bifrost-infra) ahead of the release ([example](https://github.com/protocol/bifrost-infra/issues/2109)). **Idealy, do this multiple days in advance of the RC** to give Bifrost the heads up that asks will be coming their way. - - [ ] Spell out all that we want updated - gateways, the bootstraper and the cluster/preload nodes - - [ ] Mention @protocol/bifrost-team in the issue and let them know the expected date of the release - - Issue link: - - [ ] Ensure that the `What's left for release` section has all the checkboxes checked. If that's not the case, discuss the open items with Kubo maintainers and update the release schedule accordingly. - - `km kubo:issue:checkOutstandingTasks v0.18.0` - - [ ] Create `docs-release-vX.Y.Z` branch, open a draft PR and keep updating `docs/RELEASE_ISSUE_TEMPLATE.md` on that branch as you go. - - [ ] Link it in the "Meta" section above. +- [ ] Verify you have all the access and tools you need to perform the release - [ ] Ensure you have a [GPG key generated](https://docs.github.com/en/authentication/managing-commit-signature-verification/generating-a-new-gpg-key) and [added to your GitHub account](https://docs.github.com/en/authentication/managing-commit-signature-verification/adding-a-gpg-key-to-your-github-account). This will enable you to created signed tags. - [ ] Ensure you have [admin access](https://discuss.ipfs.tech/g/admins) to [IPFS Discourse](https://discuss.ipfs.tech/). Admin access is required to globally pin posts and create banners. @2color might be able to assist you. - [ ] Access to [#bifrost](https://filecoinproject.slack.com/archives/C03MMMF606T) channel in FIL Slack might come in handy. Ask the release reviewer to invite you over. - [ ] Access to [#shared-pl-marketing-requests](https://filecoinproject.slack.com/archives/C018EJ8LWH1) channel in FIL Slack will be required to request social shares. Ask the release reviewer to invite you over. - [ ] After the release is deployed to our internal infrastructure, you're going to need read access to [IPFS network metrics](https://github.com/protocol/pldw/blob/624f47cf4ec14ad2cec6adf601a9f7b203ef770d/docs/sources/ipfs.md#ipfs-network-metrics) dashboards. Open an access request in https://github.com/protocol/pldw/issues/new/choose if you don't have it yet ([example](https://github.com/protocol/pldw/issues/158)). - [ ] You're also going to need NPM installed on your system. See [here](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) for instructions. - - [ ] Prepare changelog proposal in [docs/changelogs/vX.Y.md](https://github.com/ipfs/kubo/blob/master/docs/changelogs/). - - Skip filling out the `### Changelog` section (the one where which lists all the commits and contributors) for now. We will populate it after the release branch is cut. - - PR link: - - [ ] Ensure the new changelog is linked in the [CHANGELOG.md](CHANGELOG.md) file. - [ ] Install ZSH ([instructions](https://github.com/ohmyzsh/ohmyzsh/wiki/Installing-ZSH#install-and-set-up-zsh-as-default)). It is needed by the changelog creation script. - [ ] Ensure you have `kubo` checked out under `$(go env GOPATH)/src/github.com/ipfs/kubo`. This is required by the changelog creation script. - If you want your clone to live in a different location, you can symlink it to the expected location by running `mkdir -p $(go env GOPATH)/src/github.com/ipfs && ln -s $(pwd) $(go env GOPATH)/src/github.com/ipfs/kubo`. - - [ ] Ensure that [README.md](https://github.com/ipfs/go-ipfs/tree/master/README.md) is up to date. -- [ ] **Stage 1 - Initial Preparations** - - [ ] Upgrade to the latest patch release of Go that CircleCI has published (currently used version: `1.19.1`) - - [ ] See the list here: https://hub.docker.com/r/cimg/go/tags - - [ ] [ipfs/distributions](https://github.com/ipfs/distributions): bump [this version](https://github.com/ipfs/distributions/blob/master/.tool-versions#L2) - - [ ] [ipfs/kubo](https://github.com/ipfs/kubo): [example PR](https://github.com/ipfs/kubo/pull/8599) - - [ ] [ipfs/ipfs-docs](https://github.com/ipfs/ipfs-docs): [example PR](https://github.com/ipfs/ipfs-docs/pull/1298) - only if the major version changed +- [ ] Upgrade to the latest patch release of Go that CircleCI has published (currently used version: `1.19.1`) + - See the list here: https://hub.docker.com/r/cimg/go/tags + - [ipfs/distributions](https://github.com/ipfs/distributions): bump [this version](https://github.com/ipfs/distributions/blob/master/.tool-versions#L2) + - [ipfs/kubo](https://github.com/ipfs/kubo): [example PR](https://github.com/ipfs/kubo/pull/8599) + - [ipfs/ipfs-docs](https://github.com/ipfs/ipfs-docs): [example PR](https://github.com/ipfs/ipfs-docs/pull/1298) - only if the major version changed +- [ ] `kuboreleaser release --version vX.Y.Z(-RCN) notify-bifrost --date YYYY-MM-DD` + - [ ] Open an issue against [bifrost-infra](https://github.com/protocol/bifrost-infra) ahead of the release ([example](https://github.com/protocol/bifrost-infra/issues/2221)). + - **Idealy, do this multiple days in advance of the RC** to give Bifrost the heads up that asks will be coming their way. + - Spell out all that we want updated - gateways, the bootstraper and the cluster/preload nodes + - Mention @protocol/bifrost-team in the issue and let them know the expected date of the release + - Link it in the "Meta" section above +- [ ] Ensure that the `What's left for release` section has all the checkboxes checked. If that's not the case, discuss the open items with Kubo maintainers and update the release schedule accordingly. +- [ ] Create `docs-release-vX.Y.Z` branch, open a draft PR and keep updating `docs/RELEASE_ISSUE_TEMPLATE.md` on that branch as you go. + - Link it in the "Meta" section above. +- [ ] `kuboreleaser release --version vX.Y.Z(-RCN) cut-branch` - [ ] Fork a new branch (`release-vX.Y.Z`) from `master`. - - `km kubo:release:cutReleaseBranch v0.18.0` - [ ] Bump the version in `version.go` in the `master` branch to `vX.(Y+1).0-dev` via a PR ([example](https://github.com/ipfs/kubo/pull/9305)). - - `km kubo:main:updateVersion v0.18.0` -- [ ] **Stage 2 - Release Candidate** - _if any [non-trivial](docs/releases.md#footnotes) changes need to be included in the release, return to this stage_ - - [ ] If it's not a first RC, add new commits to the `release-vX.Y.Z` branch from `master` using `git cherry-pick -x ...` - - Note: `release-*` branches are protected. You can do all needed updates on a separated branch (e.g. `wip-release-vX.Y.Z`) and when everything is settled push to `release-vX.Y.Z` - [ ] Bump the version in `version.go` in the `release-vX.Y.Z` branch to `vX.Y.Z-rcN`. - - `km kubo:release:updateReleaseVersion v0.18.0-rc1` - [ ] If it's a first RC, create a draft PR targetting `release` branch if it doesn't exist yet ([example](https://github.com/ipfs/kubo/pull/9306)). - - `km kubo:release:createReleasePR v0.18.0` - [ ] Wait for CI to run and complete PR checks. All checks should pass. - - `km kubo:release:checkCI v0.18.0` +- [ ] If it's not a first RC, add new commits to the `release-vX.Y.Z` branch from `master` using `git cherry-pick -x ...` + - Note: `release-*` branches are protected. You can do all needed updates on a separated branch (e.g. `wip-release-vX.Y.Z`) and when everything is settled push to `release-vX.Y.Z` +- [ ] Update the [docs/changelogs/vX.Y.md](docs/changelogs) with the new commits and contributors. + - [ ] Run `./bin/mkreleaselog` twice to generate the changelog and copy the output. + - The first run of the script might be poluted with `git clone` output. + - [ ] Paste the output into the `### Changelog` section of the changelog file inside the `
` block. + - [ ] Commit the changelog changes. + - [ ] Push the `release-vX.Y.Z` branch to GitHub (`git push origin release-vX.Y.Z`) +- [ ] Mark the PR created from `release-vX.Y.Z` as ready for review. + - [ ] Ensure the PR is targetting `release` branch. + - [ ] Ensure that CI is green. + - [ ] Have release reviewer review the PR. +- [ ] Merge the PR into `release` branch using the `Create a merge commit` (do **NOT** use `Squash and merge` nor `Rebase and merge` because we need to be able to sign the merge commit). + - Do not delete the `release-vX.Y.Z` branch. +- [ ] `kuboreleaser release --version vX.Y.Z(-RCN) tag` - [ ] Create a signed tag for the release candidate. - - `km kubo:release:createReleaseTag v0.18.0-rc1` - This is a dangerous operation, as it is difficult to reverse due to Go modules and automated Docker image publishing. Remember to verify the commands you intend to run for items marked with ⚠️ with the release reviewer. - - [ ] ⚠️ Tag HEAD `release-vX.Y.Z` commit with `vX.Y.Z-rcN` (`git tag -s vX.Y.Z-rcN -m 'Pre-release X.Y.Z-rcn'`) - - [ ] Run `git show vX.Y.Z-rcN` to ensure the tag is correct. - - [ ] ⚠️ Push the `vX.Y.Z-rcN` tag to GitHub (`git push origin vX.Y.Z-rcN`; DO NOT USE `git push --tags` because it pushes all your local tags). + - ⚠️ Tag HEAD `release-vX.Y.Z`/`release` commit with `vX.Y.Z(-RCN)` (`git tag -s vX.Y.Z(-RCN) -m 'Release X.Y.Z(-RCN)'`) + - Run `git show vX.Y.Z(-RCN)` to ensure the tag is correct. + - ⚠️ Push the `vX.Y.Z(-RCN)` tag to GitHub (`git push origin vX.Y.Z(-RCN)`; DO NOT USE `git push --tags` because it pushes all your local tags). +- [ ] Wait for [Publish docker image](https://github.com/ipfs/kubo/actions/workflows/docker-image.yml) workflow run initiated by the tag push to finish. +- [ ] `kuboreleaser release --version vX.Y.Z(-RCN) publish-to-distributions` - [ ] Add artifacts to https://dist.ipfs.tech by making a PR against [ipfs/distributions](https://github.com/ipfs/distributions) - - `km dist:dist:createDistPR v0.18.0-rc1` - - [ ] Clone the `ipfs/distributions` repo locally. - - [ ] Create a new branch (`kubo-release-vX.Y.Z-rcn`) from `master`. - - [ ] Run `./dist.sh add-version kubo vX.Y.Z-rcN` to add the new version to the `versions` file ([instructions](https://github.com/ipfs/distributions#usage)). + - Clone the `ipfs/distributions` repo locally. + - Create a new branch (`kubo-release-vX.Y.Z-rcn`) from `master`. + - Run `./dist.sh add-version kubo vX.Y.Z-rcN` to add the new version to the `versions` file ([instructions](https://github.com/ipfs/distributions#usage)). - `dist.sh` will print _WARNING: not marking pre-release kubo vX.Y.Z-rcN as the current version._. - - [ ] Push the `kubo-release-vX.Y.Z-rcn` branch to GitHub and create a PR from that branch ([example](https://github.com/ipfs/distributions/pull/760)). - - [ ] Ask for a review from the release reviewer. - - [ ] Enable auto-merge for the PR. + - Push the `kubo-release-vX.Y.Z-rcn` branch to GitHub and create a PR from that branch ([example](https://github.com/ipfs/distributions/pull/760)). + - Ask for a review from the release reviewer. + - Enable auto-merge for the PR. - PR build will build the artifacts and generate a diff in around 30 minutes - PR will be merged automatically once the diff is approved - `master` build will publish the artifacts to https://dist.ipfs.io in around 30 minutes - - [ ] Ensure that the artifacts are available at https://dist.ipfs.io - - `km dist:dist:checkIPFSTech v0.18.0-rc1` + - Ensure that the artifacts are available at https://dist.ipfs.io +- [ ] `kuboreleaser release --version vX.Y.Z(-RCN) publish-to-npm` - [ ] Publish the RC to [the NPM package](https://www.npmjs.com/package/go-ipfs?activeTab=versions) by running https://github.com/ipfs/npm-go-ipfs/actions/workflows/main.yml (it happens automatically but it is safe to speed up the process and kick of a run manually) - - `km npm:npm:publishToNPM v0.18.0-rc1` - - `km npm:npm:checkNPM v0.18.0-rc1` +- [ ] `kuboreleaser release --version vX.Y.Z(-RCN) publish-to-github` - [ ] Cut a pre-release on [GitHub](https://github.com/ipfs/kubo/releases) ([instructions](https://docs.github.com/en/repositories/releasing-projects-on-github/managing-releases-in-a-repository#creating-a-release), [example](https://github.com/ipfs/kubo/releases/tag/v0.17.0-rc1)) - `km kubo:createGitHubRelease v0.18.0-rc1` - Use `vX.Y.Z-rcN` as the tag. - Link to the release issue in the description. - Link to the relevant [changelog](https://github.com/ipfs/kubo/blob/master/docs/changelogs/) in the description. - - Check `This is a pre-release`. - - [ ] Synchronize release artifacts by running [sync-release-assets](https://github.com/ipfs/kubo/actions/workflows/sync-release-assets.yml) workflow. - - `km kubo:syncGitHubRelease v0.18.0-rc1` - - [ ] Announce the RC - - [ ] Create a new post on [IPFS Discourse](https://discuss.ipfs.tech). ([example](https://discuss.ipfs.tech/t/kubo-v0-16-0-rc1-release-candidate-is-out/15248)) - - Use `Kubo vX.Y.Z-rcn Release Candidate is out!` as the title. - - `km discourse:post:getTitle v0.18.0-rc1` - - Use `kubo` and `go-ipfs` as topics. - - Repeat the title as a heading (`##`) in the description. Link to the GitHub Release, binaries on IPNS, docker pull command and release notes in the description. - - `km discourse:post:getBody v0.18.0-rc1` - - [ ] Pin the topic globally so that it stays at the top of the category. - - [ ] If there is no more important banner currently set on Discourse (e.g. IPFS Camp announcement), make the topic into a banner. - - [ ] Check if Discourse post was automatically copied to: - - [ ] IPFS Discord #ipfs-chatter - - [ ] FIL Slack #ipfs-chatter - - [ ] Matrix https://matrix.to/#/#ipfs-chatter:ipfs.io - - [ ] Mention [early testers](https://github.com/ipfs/go-ipfs/tree/master/docs/EARLY_TESTERS.md) in the comment under the release issue ([example](https://github.com/ipfs/kubo/issues/9319#issuecomment-1311002478)). -- [ ] **Stage 3 - Internal Testing** - - [ ] Infrastructure Testing (see [Kubo Gateway Release Notes](https://www.notion.so/pl-strflt/Kubo-Gateway-Release-Notes-6e0efff28ee540be9ccb8f2b85104c42) by bifrost team if you want to learn more about the process). - - [ ] Update the issue against [bifrost-infra](https://github.com/protocol/bifrost-infra) ([example](https://github.com/protocol/bifrost-infra/issues/2109)). - - `km bifrost:issue:createIssueComment v0.18.0-rc1` - - [ ] Mention @protocol/bifrost-team in the issue to let them know the release is ready - - [ ] [Optional] Reply under a message about the issue in the #bifrost channel on FIL Slack once the RC is out. Send the message to the channel. - - [ ] Check [metrics](https://protocollabs.grafana.net/d/8zlhkKTZk/gateway-slis-precomputed?orgId=1) every day. - - Compare the metrics trends week over week. - - If there is an unexpected variation in the trend, message the #bifrost channel on FIL Slack and ask for help investigation the cause. - - [ ] IPFS Application Testing. - - [ ] [IPFS Desktop](https://github.com/ipfs-shipyard/ipfs-desktop) - - `km desktop:main:createOrUpdateUpgradePR v0.18.0-rc1` - - `km desktop:main:checkCI v0.18.0-rc1` - - [ ] Upgrade to the RC in [ipfs-desktop](https://github.com/ipfs-shipyard/ipfs-desktop) - - [ ] Run `npm install` to update `package-lock.json`. - - [ ] Push to a branch ([example](https://github.com/ipfs/ipfs-desktop/pull/1826/commits/b0a23db31ce942b46d95965ee6fe770fb24d6bde)) - - [ ] Open a draft PR to track through the final release ([example](https://github.com/ipfs/ipfs-desktop/pull/1826)) - - [ ] Ensure CI tests pass - - [ ] [IPFS Companion](https://github.com/ipfs-shipyard/ipfs-companion) - - `km companion:test:initTest v0.18.0-rc2` - - `km companion:test:checkTest v0.18.0-rc2` - - [ ] Start kubo daemon of the version to release. - - [ ] Start a fresh chromium or chrome instance using `chromium --user-data-dir=$(mktemp -d)` (macos `/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --user-data-dir=$(mktemp -d)`) - - [ ] Start a fresh firefox instance using `firefox --profile $(mktemp -d)` (macos `/Applications/Firefox.app/Contents/MacOS/firefox --profile $(mktemp -d)`) - - [ ] Install IPFS Companion from [vendor-specific store](https://github.com/ipfs/ipfs-companion/#readme). - - [ ] Check that the comunication between Kubo daemon and IPFS companion is working properly checking if the number of connected peers changes. -- [ ] **Stage 5 - Release** - _ONLY FOR FINAL RELEASE_ - - [ ] Prepare the `release` branch. - - [ ] Bump the version in `version.go` in the `release-vX.Y.Z` branch to `X.Y.Z`. - - [ ] Update the [docs/changelogs/vX.Y.md](docs/changelogs) with the new commits and contributors. - - [ ] Run `./bin/mkreleaselog` twice to generate the changelog and copy the output. - - The first run of the script might be poluted with `git clone` output. - - [ ] Paste the output into the `### Changelog` section of the changelog file inside the `
` block. - - [ ] Commit the changelog changes. - - [ ] Push the `release-vX.Y.Z` branch to GitHub (`git push origin release-vX.Y.Z`) - - [ ] Mark the PR created from `release-vX.Y.Z` as ready for review. - - [ ] Ensure the PR is targetting `release` branch. - - [ ] Ensure that CI is green. - - [ ] Have release reviewer review the PR. - - [ ] Merge the PR into `release` branch using the `Create a merge commit` (do **NOT** use `Squash and merge` nor `Rebase and merge` because we need to be able to sign the merge commit). - - Do not delete the `release-vX.Y.Z` branch. - - [ ] Checkout the `release` branch locally. - - Remember to pull the latest changes. - - [ ] Create a signed tag for the release. - - [ ] This is a dangerous operation, as it is difficult to reverse due to Go modules and automated Docker image publishing. Remember to verify the commands you intend to run for items marked with ⚠️ with the release reviewer. - - [ ] ⚠️ Tag HEAD `release` commit with `vX.Y.Z` (`git tag -s vX.Y.Z -m 'Release X.Y.Z'`) - - [ ] Run `git show vX.Y.Z` to ensure the tag is correct. - - [ ] ⚠️ Push the `vX.Y.Z` tag to GitHub (`git push origin vX.Y.Z`; DO NOT USE `git push --tags` because it pushes all your local tags). - - [ ] Publish the release. - - [ ] Wait for [Publish docker image](https://github.com/ipfs/kubo/actions/workflows/docker-image.yml) workflow run initiated by the tag push to finish. - - [ ] Add artifacts to https://dist.ipfs.tech by making a PR against [ipfs/distributions](https://github.com/ipfs/distributions) - - [ ] Clone the `ipfs/distributions` repo locally. - - [ ] Create a new branch (`kubo-release-vX.Y.Z`) from `master`. - - [ ] Run `./dist.sh add-version kubo vX.Y.Z` to add the new version to the `versions` file ([instructions](https://github.com/ipfs/distributions#usage)). - - [ ] Push the `kubo-release-vX.Y.Z` branch to GitHub and create a PR from that branch ([example](https://github.com/ipfs/distributions/pull/768)). - - [ ] Ask for a review from the release reviewer. - - [ ] Enable auto-merge for the PR. - - PR build will build the artifacts and generate a diff in around 30 minutes - - PR will be merged automatically once the diff is approved - - `master` build will publish the artifacts to https://dist.ipfs.io in around 30 minutes - - [ ] Ensure that the artifacts are available at https://dist.ipfs.io - - [ ] Publish the release to [the NPM package](https://www.npmjs.com/package/go-ipfs?activeTab=versions) by running https://github.com/ipfs/npm-go-ipfs/actions/workflows/main.yml (it happens automatically but it is safe to speed up the process and kick of a run manually) - - [ ] Cut the release on [GitHub](https://github.com/ipfs/kubo/releases) ([instructions](https://docs.github.com/en/repositories/releasing-projects-on-github/managing-releases-in-a-repository#creating-a-release), [example](https://github.com/ipfs/kubo/releases/tag/v0.17.0)) - - Use `vX.Y.Z` as the tag. - Copy the relevant [changelog](https://github.com/ipfs/kubo/blob/release/docs/changelogs/) into the release description. - Keep the release notes as trim as possible (e.g. remove top headers where possible, [example](https://github.com/ipfs/kubo/releases/tag/v0.17.0)) + - Check `This is a pre-release`. - [ ] Synchronize release artifacts by running [sync-release-assets](https://github.com/ipfs/kubo/actions/workflows/sync-release-assets.yml) workflow. - - [ ] TODO: https://github.com/protocol/bifrost-infra/issues/2184#issuecomment-1315279257 - - [ ] Announce the release - - [ ] Add a link to the release to this release issue as a comment. - - [ ] Create a new post on [IPFS Discourse](https://discuss.ipfs.tech). ([example](https://discuss.ipfs.tech/t/kubo-v0-16-0-release-is-out/15286)) - - Use `Kubo vX.Y.Z Release is out!` as the title. - - Use `kubo` and `go-ipfs` as topics. - - Repeat the title as a heading (`##`) in the description. - - Link to the GitHub Release, binaries on IPNS, docker pull command and release notes in the description. - - [ ] Pin the topic globally so that it stays at the top of the category. - - [ ] If there is no more important banner currently set on Discourse (e.g. IPFS Camp announcement), make the topic into a banner. - - [ ] Check if Discourse post was automatically copied to: - - [ ] IPFS Discord #ipfs-chatter - - [ ] FIL Slack #ipfs-chatter - - [ ] Matrix - - [ ] Add a link from release notes to Discuss post (like we did here: https://github.com/ipfs/kubo/releases/tag/v0.17.0) - - [ ] Update the draft PR created for [interop](https://github.com/ipfs/interop) to use the new release and mark it as ready for review. - - [ ] Update the draft PR created for [IPFS Desktop](https://github.com/ipfs-shipyard/ipfs-desktop) to use the new release and mark it as ready for review. - - [ ] Update docs - - [ ] Run https://github.com/ipfs/ipfs-docs/actions/workflows/update-on-new-ipfs-tag.yml to generate a PR to the docs repo - - [ ] Merge the auto-created PR in https://github.com/ipfs/ipfs-docs/pulls ([example](https://github.com/ipfs/ipfs-docs/pull/1263)) - - [ ] Get the blog post created - - [ ] Submit a request for blog post creation using [the form](https://airtable.com/shrNH8YWole1xc70I). - - Title: Just released: Kubo X.Y.Z! - - Link type: Release notes - - URL: https://github.com/ipfs/kubo/releases/tag/vX.Y.Z - - [ ] The post is live on https://blog.ipfs.io +- [ ] `kuboreleaser release --version vX.Y.Z(-RCN) notify-bifrost --date YYYY-MM-DD` + - [ ] Update the issue against [bifrost-infra](https://github.com/protocol/bifrost-infra) ([example](https://github.com/protocol/bifrost-infra/issues/2109)). + - [ ] Mention @protocol/bifrost-team in the issue to let them know the release is ready + - [ ] [Optional] Reply under a message about the issue in the #bifrost channel on FIL Slack once the RC is out. Send the message to the channel. +- [ ] `kuboreleaser release --version vX.Y.Z(-RCN) promote` + - [ ] Create a new post on [IPFS Discourse](https://discuss.ipfs.tech). ([example](https://discuss.ipfs.tech/t/kubo-v0-16-0-rc1-release-candidate-is-out/15248)) + - Use `Kubo vX.Y.Z-rcn Release Candidate is out!` as the title. + - `km discourse:post:getTitle v0.18.0-rc1` + - Use `kubo` and `go-ipfs` as topics. + - Repeat the title as a heading (`##`) in the description. Link to the GitHub Release, binaries on IPNS, docker pull command and release notes in the description. + - Use `Kubo vX.Y.Z Release is out!` as the title. + - Use `kubo` and `go-ipfs` as topics. + - Repeat the title as a heading (`##`) in the description. + - Link to the GitHub Release, binaries on IPNS, docker pull command and release notes in the description. + - [ ] Pin the topic globally so that it stays at the top of the category. + - If there is no more important banner currently set on Discourse (e.g. IPFS Camp announcement), make the topic into a banner. + - [ ] Check if Discourse post was automatically copied to: + - [ ] IPFS Discord #ipfs-chatter + - [ ] FIL Slack #ipfs-chatter + - [ ] Matrix https://matrix.to/#/#ipfs-chatter:ipfs.io + - [ ] Mention [early testers](https://github.com/ipfs/go-ipfs/tree/master/docs/EARLY_TESTERS.md) in the comment under the release issue ([example](https://github.com/ipfs/kubo/issues/9319#issuecomment-1311002478)). + - [ ] Add a link to the release to this release issue as a comment. - [ ] Share the link to the GitHub release - [ ] Twitter (request in Filecoin Slack channel #shared-pl-marketing-requests; [example](https://filecoinproject.slack.com/archives/C018EJ8LWH1/p1664903524843269?thread_ts=1664885305.374909&cid=C018EJ8LWH1)) - [ ] [Reddit](https://reddit.com/r/ipfs) -- [ ] **Stage 6 - Post-Release** +- [ ] Add a link from release notes to Discuss post (like we did here: https://github.com/ipfs/kubo/releases/tag/v0.17.0) +- [ ] `kuboreleaser release --version vX.Y.Z(-RCN) test-ipfs-companion` + - [ ] Start kubo daemon of the version to release. + - [ ] Start a fresh chromium or chrome instance using `chromium --user-data-dir=$(mktemp -d)` (macos `/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --user-data-dir=$(mktemp -d)`) + - [ ] Start a fresh firefox instance using `firefox --profile $(mktemp -d)` (macos `/Applications/Firefox.app/Contents/MacOS/firefox --profile $(mktemp -d)`) + - [ ] Install IPFS Companion from [vendor-specific store](https://github.com/ipfs/ipfs-companion/#readme). + - [ ] Check that the comunication between Kubo daemon and IPFS companion is working properly checking if the number of connected peers changes. +- [ ] `kuboreleaser release --version vX.Y.Z(-RCN) update-interop` + - [ ] Upgrade to the RC in [ipfs-desktop](https://github.com/ipfs-shipyard/ipfs-desktop) + - [ ] Run `npm install` to update `package-lock.json`. + - [ ] Push to a branch + - [ ] Open a PR + - [ ] Ensure CI tests pass +- [ ] `kuboreleaser release --version vX.Y.Z(-RCN) update-ipfs-desktop` + - [ ] Upgrade to the RC in [ipfs-desktop](https://github.com/ipfs-shipyard/ipfs-desktop) + - [ ] Run `npm install` to update `package-lock.json`. + - [ ] Push to a branch ([example](https://github.com/ipfs/ipfs-desktop/pull/1826/commits/b0a23db31ce942b46d95965ee6fe770fb24d6bde)) + - [ ] Open a draft PR to track through the final release ([example](https://github.com/ipfs/ipfs-desktop/pull/1826)) + - [ ] Mark the PR as ready for review + - [ ] Ensure CI tests pass +- [ ] `kuboreleaser release --version vX.Y.Z(-RCN) update-ipfs-docs` + - [ ] Run https://github.com/ipfs/ipfs-docs/actions/workflows/update-on-new-ipfs-tag.yml to generate a PR to the docs repo + - [ ] Merge the auto-created PR in https://github.com/ipfs/ipfs-docs/pulls ([example](https://github.com/ipfs/ipfs-docs/pull/1263)) +- [ ] `kuboreleaser release --version vX.Y.Z(-RCN) update-ipfs-blog --date YYYY-MM-DD` + - [ ] Submit a request for blog post creation using [the form](https://airtable.com/shrNH8YWole1xc70I). + - Title: Just released: Kubo X.Y.Z! + - Link type: Release notes + - URL: https://github.com/ipfs/kubo/releases/tag/vX.Y.Z + - [ ] The post is live on https://blog.ipfs.io +- [ ] Infrastructure Testing (see [Kubo Gateway Release Notes](https://www.notion.so/pl-strflt/Kubo-Gateway-Release-Notes-6e0efff28ee540be9ccb8f2b85104c42) by bifrost team if you want to learn more about the process). + - Check [metrics](https://protocollabs.grafana.net/d/8zlhkKTZk/gateway-slis-precomputed?orgId=1) every day. + - Compare the metrics trends week over week. + - If there is an unexpected variation in the trend, message the #bifrost channel on FIL Slack and ask for help investigation the cause. +- [ ] `kuboreleaser release --version vX.Y.Z(-RCN) merge-branch` - [ ] Merge the `release` branch back into `master`, ignoring the changes to `version.go` (keep the `-dev` version from master). - - [ ] Create an issue using this release issue template for the _next_ release. - - [ ] Close this release issue. +- [ ] Prepare changelog proposal in [docs/changelogs/vX.Y.md](https://github.com/ipfs/kubo/blob/master/docs/changelogs/). + - Skip filling out the `### Changelog` section (the one where which lists all the commits and contributors) for now. We will populate it after the release branch is cut. + - Ensure the new changelog is linked in the [CHANGELOG.md](CHANGELOG.md) file. +- [ ] Create an issue using this release issue template for the _next_ release. +- [ ] Close this release issue. ## How to contribute? From feea7d36f6e79f4c7925f0a6d49e1ff984b5972b Mon Sep 17 00:00:00 2001 From: galargh Date: Thu, 26 Jan 2023 13:15:08 +0100 Subject: [PATCH 0427/1212] chore: reword release checklist --- docs/RELEASE_ISSUE_TEMPLATE.md | 275 ++++++++++++++++----------------- 1 file changed, 135 insertions(+), 140 deletions(-) diff --git a/docs/RELEASE_ISSUE_TEMPLATE.md b/docs/RELEASE_ISSUE_TEMPLATE.md index 1fc391f67..bcfcf6524 100644 --- a/docs/RELEASE_ISSUE_TEMPLATE.md +++ b/docs/RELEASE_ISSUE_TEMPLATE.md @@ -39,147 +39,142 @@ As usual, this release includes important fixes, some of which may be critical f ## ✅ Release Checklist -- [ ] Verify you have all the access and tools you need to perform the release - - [ ] Ensure you have a [GPG key generated](https://docs.github.com/en/authentication/managing-commit-signature-verification/generating-a-new-gpg-key) and [added to your GitHub account](https://docs.github.com/en/authentication/managing-commit-signature-verification/adding-a-gpg-key-to-your-github-account). This will enable you to created signed tags. - - [ ] Ensure you have [admin access](https://discuss.ipfs.tech/g/admins) to [IPFS Discourse](https://discuss.ipfs.tech/). Admin access is required to globally pin posts and create banners. @2color might be able to assist you. - - [ ] Access to [#bifrost](https://filecoinproject.slack.com/archives/C03MMMF606T) channel in FIL Slack might come in handy. Ask the release reviewer to invite you over. - - [ ] Access to [#shared-pl-marketing-requests](https://filecoinproject.slack.com/archives/C018EJ8LWH1) channel in FIL Slack will be required to request social shares. Ask the release reviewer to invite you over. - - [ ] After the release is deployed to our internal infrastructure, you're going to need read access to [IPFS network metrics](https://github.com/protocol/pldw/blob/624f47cf4ec14ad2cec6adf601a9f7b203ef770d/docs/sources/ipfs.md#ipfs-network-metrics) dashboards. Open an access request in https://github.com/protocol/pldw/issues/new/choose if you don't have it yet ([example](https://github.com/protocol/pldw/issues/158)). - - [ ] You're also going to need NPM installed on your system. See [here](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) for instructions. - - [ ] Install ZSH ([instructions](https://github.com/ohmyzsh/ohmyzsh/wiki/Installing-ZSH#install-and-set-up-zsh-as-default)). It is needed by the changelog creation script. - - [ ] Ensure you have `kubo` checked out under `$(go env GOPATH)/src/github.com/ipfs/kubo`. This is required by the changelog creation script. - - If you want your clone to live in a different location, you can symlink it to the expected location by running `mkdir -p $(go env GOPATH)/src/github.com/ipfs && ln -s $(pwd) $(go env GOPATH)/src/github.com/ipfs/kubo`. -- [ ] Upgrade to the latest patch release of Go that CircleCI has published (currently used version: `1.19.1`) - - See the list here: https://hub.docker.com/r/cimg/go/tags - - [ipfs/distributions](https://github.com/ipfs/distributions): bump [this version](https://github.com/ipfs/distributions/blob/master/.tool-versions#L2) - - [ipfs/kubo](https://github.com/ipfs/kubo): [example PR](https://github.com/ipfs/kubo/pull/8599) - - [ipfs/ipfs-docs](https://github.com/ipfs/ipfs-docs): [example PR](https://github.com/ipfs/ipfs-docs/pull/1298) - only if the major version changed -- [ ] `kuboreleaser release --version vX.Y.Z(-RCN) notify-bifrost --date YYYY-MM-DD` - - [ ] Open an issue against [bifrost-infra](https://github.com/protocol/bifrost-infra) ahead of the release ([example](https://github.com/protocol/bifrost-infra/issues/2221)). - - **Idealy, do this multiple days in advance of the RC** to give Bifrost the heads up that asks will be coming their way. - - Spell out all that we want updated - gateways, the bootstraper and the cluster/preload nodes - - Mention @protocol/bifrost-team in the issue and let them know the expected date of the release - - Link it in the "Meta" section above -- [ ] Ensure that the `What's left for release` section has all the checkboxes checked. If that's not the case, discuss the open items with Kubo maintainers and update the release schedule accordingly. -- [ ] Create `docs-release-vX.Y.Z` branch, open a draft PR and keep updating `docs/RELEASE_ISSUE_TEMPLATE.md` on that branch as you go. - - Link it in the "Meta" section above. -- [ ] `kuboreleaser release --version vX.Y.Z(-RCN) cut-branch` - - [ ] Fork a new branch (`release-vX.Y.Z`) from `master`. - - [ ] Bump the version in `version.go` in the `master` branch to `vX.(Y+1).0-dev` via a PR ([example](https://github.com/ipfs/kubo/pull/9305)). - - [ ] Bump the version in `version.go` in the `release-vX.Y.Z` branch to `vX.Y.Z-rcN`. - - [ ] If it's a first RC, create a draft PR targetting `release` branch if it doesn't exist yet ([example](https://github.com/ipfs/kubo/pull/9306)). - - [ ] Wait for CI to run and complete PR checks. All checks should pass. -- [ ] If it's not a first RC, add new commits to the `release-vX.Y.Z` branch from `master` using `git cherry-pick -x ...` - - Note: `release-*` branches are protected. You can do all needed updates on a separated branch (e.g. `wip-release-vX.Y.Z`) and when everything is settled push to `release-vX.Y.Z` -- [ ] Update the [docs/changelogs/vX.Y.md](docs/changelogs) with the new commits and contributors. - - [ ] Run `./bin/mkreleaselog` twice to generate the changelog and copy the output. - - The first run of the script might be poluted with `git clone` output. - - [ ] Paste the output into the `### Changelog` section of the changelog file inside the `
` block. - - [ ] Commit the changelog changes. - - [ ] Push the `release-vX.Y.Z` branch to GitHub (`git push origin release-vX.Y.Z`) -- [ ] Mark the PR created from `release-vX.Y.Z` as ready for review. - - [ ] Ensure the PR is targetting `release` branch. - - [ ] Ensure that CI is green. - - [ ] Have release reviewer review the PR. -- [ ] Merge the PR into `release` branch using the `Create a merge commit` (do **NOT** use `Squash and merge` nor `Rebase and merge` because we need to be able to sign the merge commit). - - Do not delete the `release-vX.Y.Z` branch. -- [ ] `kuboreleaser release --version vX.Y.Z(-RCN) tag` - - [ ] Create a signed tag for the release candidate. - - This is a dangerous operation, as it is difficult to reverse due to Go modules and automated Docker image publishing. Remember to verify the commands you intend to run for items marked with ⚠️ with the release reviewer. - - ⚠️ Tag HEAD `release-vX.Y.Z`/`release` commit with `vX.Y.Z(-RCN)` (`git tag -s vX.Y.Z(-RCN) -m 'Release X.Y.Z(-RCN)'`) - - Run `git show vX.Y.Z(-RCN)` to ensure the tag is correct. - - ⚠️ Push the `vX.Y.Z(-RCN)` tag to GitHub (`git push origin vX.Y.Z(-RCN)`; DO NOT USE `git push --tags` because it pushes all your local tags). -- [ ] Wait for [Publish docker image](https://github.com/ipfs/kubo/actions/workflows/docker-image.yml) workflow run initiated by the tag push to finish. -- [ ] `kuboreleaser release --version vX.Y.Z(-RCN) publish-to-distributions` - - [ ] Add artifacts to https://dist.ipfs.tech by making a PR against [ipfs/distributions](https://github.com/ipfs/distributions) - - Clone the `ipfs/distributions` repo locally. - - Create a new branch (`kubo-release-vX.Y.Z-rcn`) from `master`. - - Run `./dist.sh add-version kubo vX.Y.Z-rcN` to add the new version to the `versions` file ([instructions](https://github.com/ipfs/distributions#usage)). - - `dist.sh` will print _WARNING: not marking pre-release kubo vX.Y.Z-rcN as the current version._. - - Push the `kubo-release-vX.Y.Z-rcn` branch to GitHub and create a PR from that branch ([example](https://github.com/ipfs/distributions/pull/760)). - - Ask for a review from the release reviewer. - - Enable auto-merge for the PR. - - PR build will build the artifacts and generate a diff in around 30 minutes - - PR will be merged automatically once the diff is approved - - `master` build will publish the artifacts to https://dist.ipfs.io in around 30 minutes - - Ensure that the artifacts are available at https://dist.ipfs.io -- [ ] `kuboreleaser release --version vX.Y.Z(-RCN) publish-to-npm` - - [ ] Publish the RC to [the NPM package](https://www.npmjs.com/package/go-ipfs?activeTab=versions) by running https://github.com/ipfs/npm-go-ipfs/actions/workflows/main.yml (it happens automatically but it is safe to speed up the process and kick of a run manually) -- [ ] `kuboreleaser release --version vX.Y.Z(-RCN) publish-to-github` - - [ ] Cut a pre-release on [GitHub](https://github.com/ipfs/kubo/releases) ([instructions](https://docs.github.com/en/repositories/releasing-projects-on-github/managing-releases-in-a-repository#creating-a-release), [example](https://github.com/ipfs/kubo/releases/tag/v0.17.0-rc1)) - - `km kubo:createGitHubRelease v0.18.0-rc1` - - Use `vX.Y.Z-rcN` as the tag. - - Link to the release issue in the description. - - Link to the relevant [changelog](https://github.com/ipfs/kubo/blob/master/docs/changelogs/) in the description. - - Copy the relevant [changelog](https://github.com/ipfs/kubo/blob/release/docs/changelogs/) into the release description. - - Keep the release notes as trim as possible (e.g. remove top headers where possible, [example](https://github.com/ipfs/kubo/releases/tag/v0.17.0)) - - Check `This is a pre-release`. - - [ ] Synchronize release artifacts by running [sync-release-assets](https://github.com/ipfs/kubo/actions/workflows/sync-release-assets.yml) workflow. -- [ ] `kuboreleaser release --version vX.Y.Z(-RCN) notify-bifrost --date YYYY-MM-DD` - - [ ] Update the issue against [bifrost-infra](https://github.com/protocol/bifrost-infra) ([example](https://github.com/protocol/bifrost-infra/issues/2109)). - - [ ] Mention @protocol/bifrost-team in the issue to let them know the release is ready - - [ ] [Optional] Reply under a message about the issue in the #bifrost channel on FIL Slack once the RC is out. Send the message to the channel. -- [ ] `kuboreleaser release --version vX.Y.Z(-RCN) promote` - - [ ] Create a new post on [IPFS Discourse](https://discuss.ipfs.tech). ([example](https://discuss.ipfs.tech/t/kubo-v0-16-0-rc1-release-candidate-is-out/15248)) - - Use `Kubo vX.Y.Z-rcn Release Candidate is out!` as the title. - - `km discourse:post:getTitle v0.18.0-rc1` - - Use `kubo` and `go-ipfs` as topics. - - Repeat the title as a heading (`##`) in the description. Link to the GitHub Release, binaries on IPNS, docker pull command and release notes in the description. - - Use `Kubo vX.Y.Z Release is out!` as the title. - - Use `kubo` and `go-ipfs` as topics. - - Repeat the title as a heading (`##`) in the description. - - Link to the GitHub Release, binaries on IPNS, docker pull command and release notes in the description. - - [ ] Pin the topic globally so that it stays at the top of the category. - - If there is no more important banner currently set on Discourse (e.g. IPFS Camp announcement), make the topic into a banner. - - [ ] Check if Discourse post was automatically copied to: - - [ ] IPFS Discord #ipfs-chatter - - [ ] FIL Slack #ipfs-chatter - - [ ] Matrix https://matrix.to/#/#ipfs-chatter:ipfs.io - - [ ] Mention [early testers](https://github.com/ipfs/go-ipfs/tree/master/docs/EARLY_TESTERS.md) in the comment under the release issue ([example](https://github.com/ipfs/kubo/issues/9319#issuecomment-1311002478)). - - [ ] Add a link to the release to this release issue as a comment. - - [ ] Share the link to the GitHub release - - [ ] Twitter (request in Filecoin Slack channel #shared-pl-marketing-requests; [example](https://filecoinproject.slack.com/archives/C018EJ8LWH1/p1664903524843269?thread_ts=1664885305.374909&cid=C018EJ8LWH1)) - - [ ] [Reddit](https://reddit.com/r/ipfs) -- [ ] Add a link from release notes to Discuss post (like we did here: https://github.com/ipfs/kubo/releases/tag/v0.17.0) +- [ ] Verify you have access to all the services and tools required for the release + - [ ] [GPG signature](https://docs.github.com/en/authentication/managing-commit-signature-verification) configured in local git and in GitHub + - [ ] [admin access to IPFS Discourse](https://discuss.ipfs.tech/g/admins) + - ask the previous release owner (or @2color) for an invite + - [ ] [access to #bifrost](https://filecoinproject.slack.com/archives/C03MMMF606T) channel in FIL Slack + - ask the previous release owner for an invite + - [ ] [access to #shared-pl-marketing-requests](https://filecoinproject.slack.com/archives/C018EJ8LWH1) channel in FIL Slack + - ask the previous release owner for an invite + - [ ] [access to IPFS network metrics](https://github.com/protocol/pldw/blob/624f47cf4ec14ad2cec6adf601a9f7b203ef770d/docs/sources/ipfs.md#ipfs-network-metrics) dashboards in Grafana + - open an access request in the [pldw](https://github.com/protocol/pldw/issues/new/choose) + - [example](https://github.com/protocol/pldw/issues/158) + - [ ] [npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) installed on your system (_only if you're not using [kuboreleaser](https://github.com/ipfs/kuboreleaser)_) + - [ ] [zsh](https://github.com/ohmyzsh/ohmyzsh/wiki/Installing-ZSH#install-and-set-up-zsh-as-default) installed on your system (_only if you're not using [kuboreleaser](https://github.com/ipfs/kuboreleaser)_) + - [ ] [kubo](https://github.com/ipfs/kubo) checked out under `$(go env GOPATH)/src/github.com/ipfs/kubo` (_only if you're not using [kuboreleaser](https://github.com/ipfs/kuboreleaser)_) + - you can also symlink your clone to the expected location by running `mkdir -p $(go env GOPATH)/src/github.com/ipfs && ln -s $(pwd) $(go env GOPATH)/src/github.com/ipfs/kubo` + - [ ] [Reddit](https://www.reddit.com) account +- [ ] Upgrade Go used in CI to the latest patch release available in [CircleCI](https://hub.docker.com/r/cimg/go/tags) + - [ ] [ipfs/distributions](https://github.com/ipfs/distributions) + - [example](https://github.com/ipfs/distributions/pull/756) + - [ ] [ipfs/ipfs-docs](https://github.com/ipfs/ipfs-docs) + - [example](https://github.com/ipfs/ipfs-docs/pull/1298) +- [ ] Notify the bifrost team about the upcoming release using `kuboreleaser release --version vX.Y.Z(-RCN) notify-bifrost --date YYYY-MM-DD` + - [ ] open an issue against [bifrost-infra](https://github.com/protocol/bifrost-infra) + - [example](https://github.com/protocol/bifrost-infra/issues/2221) + - [ ] link the issue in the [Meta](#meta) section +- [ ] Verify there is nothing [left for release](-what-s-left-for-release) +- [ ] Create a release process improvement PR + - [ ] update the [release issue template](docs/RELEASE_ISSUE_TEMPLATE.md) as you go + - [ ] link it in the [Meta](#meta) section +- [ ] Cut the release branch and update version numbers accordingly using `kuboreleaser release --version vX.Y.Z(-RCN) cut-branch` + - [ ] create a new branch `release-vX.Y` from `master` + - [ ] update the `CurrentVersionNumber` in [version.go](version.go) in the `master` branch to `vX.(Y+1).0-dev` + - [example](https://github.com/ipfs/kubo/pull/9305) + - [ ] update the `CurrentVersionNumber` in [version.go](version.go) in the `release-vX.Y` branch to `vX.Y.Z(-RCN)` + - [example](https://github.com/ipfs/kubo/pull/9394) + - [ ] create a draft PR from `release-vX.Y` to `release` + - [example](https://github.com/ipfs/kubo/pull/9306) + - [ ] verify all CI checks on the PR from `release-vX.Y` to `release` are passing +- [ ] Cherry-pick commits from `master` to the `release-vX.Y` using `git cherry-pick -x ` +- [ ] Add full changelog and contributors to the [changelog](docs/changelogs/vX.Y.md) +- [ ] Merge the PR from `release-vX.Y` to `release` using the `Create a merge commit` + - do **NOT** use `Squash and merge` nor `Rebase and merge` because we need to be able to sign the merge commit + - do **NOT** delete the `release-vX.Y` branch +- [ ] Create the release tag using `kuboreleaser release --version vX.Y.Z(-RCN) tag` + - This is a dangerous operation! Go and Docker publishing are difficult to reverse! Have the release reviewer verify all the commands marked with ⚠️! + - [ ] ⚠️ tag the HEAD commit of the `release-vX.Y` branch using `git tag -s vX.Y.Z(-RCN) -m 'Prerelease X.Y.Z(-RCN)'` + - [ ] ⚠️ tag the HEAD commit of the `release` branch using `git tag -s vX.Y.Z(-RCN) -m 'Release X.Y.Z(-RCN)'` + - [ ] ⚠️ verify the tag is signed and tied to the correct commit using `git show vX.Y.Z(-RCN)` + - [ ] ⚠️ push the tag to GitHub using `git push origin vX.Y.Z(-RCN)` + - do **NOT** use `git push --tags` because it pushes all your local tags +- [ ] Wait for [Publish docker image](https://github.com/ipfs/kubo/actions/workflows/docker-image.yml) workflow run initiated by the tag push to finish + - [ ] verify the image is available on [Docker Hub](https://hub.docker.com/r/ipfs/kubo/tags) +- [ ] Publish the release to [ipfs.tech](https://dist.ipfs.tech) using `kuboreleaser release --version vX.Y.Z(-RCN) publish-to-distributions` + - [ ] check out [ipfs/distributions](https://github.com/ipfs/distributions) + - [ ] run `./dist.sh add-version kubo vX.Y.Z(-RCN)` to add the new version to the `versions` file + - [usage](https://github.com/ipfs/distributions#usage) + - [ ] create and merge the PR which updates `dists/kubo/versions` and `dists/go-ipfs/versions` + - [example](https://github.com/ipfs/distributions/pull/760) + - [ ] wait for the [CI](https://github.com/ipfs/distributions/actions/workflows/main.yml) workflow run initiated by the merge to master to finish + - [ ] verify the release is available on [dist.ipfs.io](https://dist.ipfs.io/#kubo) +- [ ] Publish the release to [NPM](https://www.npmjs.com/package/go-ipfs?activeTab=versions) using `kuboreleaser release --version vX.Y.Z(-RCN) publish-to-npm` + - [ ] run the [Release to npm](https://github.com/ipfs/npm-go-ipfs/actions/workflows/main.yml) workflow + - [ ] check [Release to npm](https://github.com/ipfs/npm-go-ipfs/actions/workflows/main.yml) workflow run logs to verify it discovered the new release + - [ ] verify the release is available on [NPM](https://www.npmjs.com/package/go-ipfs?activeTab=versions) +- [ ] Publish the release to [GitHub](https://github.com/ipfs/kubo/releases) using `kuboreleaser release --version vX.Y.Z(-RCN) publish-to-github` + - [ ] create a new release on [GitHub](https://docs.github.com/en/repositories/releasing-projects-on-github/managing-releases-in-a-repository#creating-a-release) + - [prerelease example](https://github.com/ipfs/kubo/releases/tag/v0.17.0-rc1) + - use the `vX.Y.Z(-RCN)` tag + - link to the release issue + - link to the changelog in the description + - check the `This is a pre-release` checkbox + - [release example](https://github.com/ipfs/kubo/releases/tag/v0.17.0) + - use the `vX.Y.Z(-RCN)` tag + - link to the release issue + - copy the changelog (without the header) in the description + - do **NOT** check the `This is a pre-release` checkbox + - [ ] run the [sync-release-assets](https://github.com/ipfs/kubo/actions/workflows/sync-release-assets.yml) workflow + - [ ] wait for the [sync-release-assets](https://github.com/ipfs/kubo/actions/workflows/sync-release-assets.yml) workflow run to finish + - [ ] verify the release assets are present in the [GitHub release](https://github.com/ipfs/kubo/releases/tag/vX.Y.Z(-RCN)) +- [ ] Notify the bifrost team about the release using `kuboreleaser release --version vX.Y.Z(-RCN) notify-bifrost --date YYYY-MM-DD` + - [ ] create an issue comment on the issue in the [bifrost-infra](https://github/com/protocol/bifrost-infra) +- [ ] Promote the release using `kuboreleaser release --version vX.Y.Z(-RCN) promote` + - [ ] create an [IPFS Discourse](https://discuss.ipfs.tech) topic + - [prerelease example](https://discuss.ipfs.tech/t/kubo-v0-16-0-rc1-release-candidate-is-out/15248) + - [release example](https://discuss.ipfs.tech/t/kubo-v0-16-0-release-is-out/15249) + - use `Kubo vX.Y.Z(-RCN) is out!` as the title + - use `kubo` and `go-ipfs` as topics + - repeat the title as a heading (`##`) in the description + - link to the GitHub Release, binaries on IPNS, docker pull command and release notes in the description + - [ ] pin the [IPFS Discourse](https://discuss.ipfs.tech) topic globally + - you can make the topic a banner if there is no banner already + - verify the [IPFS Discourse](https://discuss.ipfs.tech) topic was copied to: + - [ ] [#ipfs-chatter](https://discord.com/channels/669268347736686612/669268347736686615) in IPFS Discord + - [ ] [#ipfs-chatter](https://filecoinproject.slack.com/archives/C018EJ8LWH1) in FIL Slack + - [ ] [#ipfs-chatter:ipfs.io](https://matrix.to/#/#ipfs-chatter:ipfs.io) in Matrix + - [ ] create an issue comment mentioning early testers on the release issue + - [example](https://github.com/ipfs/kubo/issues/9319#issuecomment-1311002478) + - [ ] create an issue comment linking to the release on the release issue + - [example](https://github.com/ipfs/kubo/issues/9417#issuecomment-1400740975) + - [ ] ask the marketing team to tweet about the release in [#shared-pl-marketing-requests](https://filecoinproject.slack.com/archives/C018EJ8LWH1) in FIL Slack + - [example](https://filecoinproject.slack.com/archives/C018EJ8LWH1/p1664885305374900) + - [ ] post the link to the [GitHub Release](https://github.com/ipfs/kubo/releases/tag/vX.Y.Z(-RCN)) to [Reddit](https://reddit.com/r/ipfs) + - [example](https://www.reddit.com/r/ipfs/comments/9x0q0k/kubo_v0160_release_is_out/) +- [ ] Add the link to the [IPFS Discourse](https://discuss.ipfs.tech) topic to the [GitHub Release](https://github.com/ipfs/kubo/releases/tag/vX.Y.Z(-RCN)) description + - [example](https://github.com/ipfs/kubo/releases/tag/v0.17.0) - [ ] `kuboreleaser release --version vX.Y.Z(-RCN) test-ipfs-companion` - - [ ] Start kubo daemon of the version to release. - - [ ] Start a fresh chromium or chrome instance using `chromium --user-data-dir=$(mktemp -d)` (macos `/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --user-data-dir=$(mktemp -d)`) - - [ ] Start a fresh firefox instance using `firefox --profile $(mktemp -d)` (macos `/Applications/Firefox.app/Contents/MacOS/firefox --profile $(mktemp -d)`) - - [ ] Install IPFS Companion from [vendor-specific store](https://github.com/ipfs/ipfs-companion/#readme). - - [ ] Check that the comunication between Kubo daemon and IPFS companion is working properly checking if the number of connected peers changes. -- [ ] `kuboreleaser release --version vX.Y.Z(-RCN) update-interop` - - [ ] Upgrade to the RC in [ipfs-desktop](https://github.com/ipfs-shipyard/ipfs-desktop) - - [ ] Run `npm install` to update `package-lock.json`. - - [ ] Push to a branch - - [ ] Open a PR - - [ ] Ensure CI tests pass -- [ ] `kuboreleaser release --version vX.Y.Z(-RCN) update-ipfs-desktop` - - [ ] Upgrade to the RC in [ipfs-desktop](https://github.com/ipfs-shipyard/ipfs-desktop) - - [ ] Run `npm install` to update `package-lock.json`. - - [ ] Push to a branch ([example](https://github.com/ipfs/ipfs-desktop/pull/1826/commits/b0a23db31ce942b46d95965ee6fe770fb24d6bde)) - - [ ] Open a draft PR to track through the final release ([example](https://github.com/ipfs/ipfs-desktop/pull/1826)) - - [ ] Mark the PR as ready for review - - [ ] Ensure CI tests pass -- [ ] `kuboreleaser release --version vX.Y.Z(-RCN) update-ipfs-docs` - - [ ] Run https://github.com/ipfs/ipfs-docs/actions/workflows/update-on-new-ipfs-tag.yml to generate a PR to the docs repo - - [ ] Merge the auto-created PR in https://github.com/ipfs/ipfs-docs/pulls ([example](https://github.com/ipfs/ipfs-docs/pull/1263)) -- [ ] `kuboreleaser release --version vX.Y.Z(-RCN) update-ipfs-blog --date YYYY-MM-DD` - - [ ] Submit a request for blog post creation using [the form](https://airtable.com/shrNH8YWole1xc70I). - - Title: Just released: Kubo X.Y.Z! - - Link type: Release notes - - URL: https://github.com/ipfs/kubo/releases/tag/vX.Y.Z - - [ ] The post is live on https://blog.ipfs.io -- [ ] Infrastructure Testing (see [Kubo Gateway Release Notes](https://www.notion.so/pl-strflt/Kubo-Gateway-Release-Notes-6e0efff28ee540be9ccb8f2b85104c42) by bifrost team if you want to learn more about the process). - - Check [metrics](https://protocollabs.grafana.net/d/8zlhkKTZk/gateway-slis-precomputed?orgId=1) every day. - - Compare the metrics trends week over week. - - If there is an unexpected variation in the trend, message the #bifrost channel on FIL Slack and ask for help investigation the cause. -- [ ] `kuboreleaser release --version vX.Y.Z(-RCN) merge-branch` - - [ ] Merge the `release` branch back into `master`, ignoring the changes to `version.go` (keep the `-dev` version from master). -- [ ] Prepare changelog proposal in [docs/changelogs/vX.Y.md](https://github.com/ipfs/kubo/blob/master/docs/changelogs/). - - Skip filling out the `### Changelog` section (the one where which lists all the commits and contributors) for now. We will populate it after the release branch is cut. - - Ensure the new changelog is linked in the [CHANGELOG.md](CHANGELOG.md) file. -- [ ] Create an issue using this release issue template for the _next_ release. -- [ ] Close this release issue. + - [ ] run the [e2e](https://github.com/ipfs/ipfs-companion/actions/workflows/e2e.yml) + - use `vX.Y.Z(-RCN)` as the Kubo image version + - [ ] wait for the [e2e](https://github.com/ipfs/ipfs-companion/actions/workflows/e2e.yml) workflow run to finish +- [ ] Update Kubo in [interop](https://github.com/ipfs/interop) using `kuboreleaser release --version vX.Y.Z(-RCN) update-interop` + - [ ] check out [ipfs/interop](https://github.com/ipfs/interop) + - [ ] run `npm install` + - [ ] create a PR which updates `package.json` and `package-lock.json` + - [ ] merge the PR +- [ ] Update Kubo in [ipfs-desktop](https://github.com/ipfs/ipfs-desktop) using `kuboreleaser release --version vX.Y.Z(-RCN) update-ipfs-desktop` + - [ ] check out [ipfs/ipfs-desktop](https://github.com/ipfs/ipfs-desktop) + - [ ] run `npm install` + - [ ] create a PR which updates `package.json` and `package-lock.json` + - [ ] merge the PR +- [ ] Update Kubo docs using `kuboreleaser release --version vX.Y.Z(-RCN) update-ipfs-docs` + - [ ] run the [update-on-new-ipfs-tag.yml](https://github.com/ipfs/ipfs-docs/actions/workflows/update-on-new-ipfs-tag.yml) workflow + - [ ] merge the PR created by the [update-on-new-ipfs-tag.yml](https://github.com/ipfs/ipfs-docs/actions/workflows/update-on-new-ipfs-tag.yml) workflow run +- [ ] Create a blog entry on [ipfs.tech](https://blog.ipfs.tech) `kuboreleaser release --version vX.Y.Z(-RCN) update-ipfs-blog --date YYYY-MM-DD` + - [ ] create a PR which adds a release note for the new Kubo version + - [example](https://github.com/ipfs/ipfs-blog/pull/529) + - [ ] merge the PR + - [ ] verify the blog entry was published +- [ ] Keep checking the [metrics](https://protocollabs.grafana.net/d/8zlhkKTZk/gateway-slis-precomputed?orgId=1) until the release issue is closed + - [release notes](https://www.notion.so/pl-strflt/Kubo-Gateway-Release-Notes-6e0efff28ee540be9ccb8f2b85104c42) + - post in the [#bifrost](https://filecoinproject.slack.com/archives/C018EJ8LWH1) channel in FIL Slack if there is a problem +- [ ] Merge the [release](https://github.com/ipfs/kubo/tree/release) back into [master](https://github.com/ipfs/kubo/tree/master) using `kuboreleaser release --version vX.Y.Z(-RCN) merge-branch` + - ignore the changes to [version.go](version.go) (keep the `-dev` version) +- [ ] Create the next [changelog](https://github.com/ipfs/kubo/blob/master/docs/changelogs/vX.(Y+1).md) + - link to the new changelog in the [CHANGELOG.md](CHANGELOG.md) file +- [ ] Create the next release issue +- [ ] Close the release issue ## How to contribute? From a3f7e84d6267a445654ad4ba4234b8485fd8f657 Mon Sep 17 00:00:00 2001 From: galargh Date: Thu, 26 Jan 2023 16:29:43 +0100 Subject: [PATCH 0428/1212] chore: label release checklist items --- docs/RELEASE_ISSUE_TEMPLATE.md | 110 ++++++++++++++++++++------------- 1 file changed, 66 insertions(+), 44 deletions(-) diff --git a/docs/RELEASE_ISSUE_TEMPLATE.md b/docs/RELEASE_ISSUE_TEMPLATE.md index bcfcf6524..013ee7c17 100644 --- a/docs/RELEASE_ISSUE_TEMPLATE.md +++ b/docs/RELEASE_ISSUE_TEMPLATE.md @@ -39,6 +39,23 @@ As usual, this release includes important fixes, some of which may be critical f ## ✅ Release Checklist +### Labels + +If an item should be executed for a specific release type, it should be labeled with one of the following labels: + +- ![](https://img.shields.io/badge/only-RC-blue?style=flat-square) execute **ONLY** when releasing a Release Candidate +- ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) execute **ONLY** when releasing a Final Release + +Otherwise, it means it should be executed for **ALL** release types. + +Patch releases should follow the same process as `.0` releases. If some item should **NOT** be executed for a Patch Release, it should be labeled with: + +- ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) do **NOT** execute when releasing a Patch Release + +### Before the release + +This section covers tasks to be done ahead of the release. + - [ ] Verify you have access to all the services and tools required for the release - [ ] [GPG signature](https://docs.github.com/en/authentication/managing-commit-signature-verification) configured in local git and in GitHub - [ ] [admin access to IPFS Discourse](https://discuss.ipfs.tech/g/admins) @@ -68,24 +85,31 @@ As usual, this release includes important fixes, some of which may be critical f - [ ] Create a release process improvement PR - [ ] update the [release issue template](docs/RELEASE_ISSUE_TEMPLATE.md) as you go - [ ] link it in the [Meta](#meta) section + +### The release + +This section covers tasks to be done during each release. + - [ ] Cut the release branch and update version numbers accordingly using `kuboreleaser release --version vX.Y.Z(-RCN) cut-branch` - - [ ] create a new branch `release-vX.Y` from `master` - - [ ] update the `CurrentVersionNumber` in [version.go](version.go) in the `master` branch to `vX.(Y+1).0-dev` + - [ ] create a new branch `release-vX.Y.Z` + - use `master` as base if `Z == 0` + - use `release` as base if `Z > 0` + - [ ] ![](https://img.shields.io/badge/only-RC-blue?style=flat-square) update the `CurrentVersionNumber` in [version.go](version.go) in the `master` branch to `vX.(Y+1).0-dev` - [example](https://github.com/ipfs/kubo/pull/9305) - [ ] update the `CurrentVersionNumber` in [version.go](version.go) in the `release-vX.Y` branch to `vX.Y.Z(-RCN)` - [example](https://github.com/ipfs/kubo/pull/9394) - [ ] create a draft PR from `release-vX.Y` to `release` - [example](https://github.com/ipfs/kubo/pull/9306) - [ ] verify all CI checks on the PR from `release-vX.Y` to `release` are passing -- [ ] Cherry-pick commits from `master` to the `release-vX.Y` using `git cherry-pick -x ` -- [ ] Add full changelog and contributors to the [changelog](docs/changelogs/vX.Y.md) -- [ ] Merge the PR from `release-vX.Y` to `release` using the `Create a merge commit` +- [ ] Cherry-pick commits from `master` to the `release-vX.Y.Z` using `git cherry-pick -x ` +- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Add full changelog and contributors to the [changelog](docs/changelogs/vX.Y.md) +- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Merge the PR from `release-vX.Y` to `release` using the `Create a merge commit` - do **NOT** use `Squash and merge` nor `Rebase and merge` because we need to be able to sign the merge commit - do **NOT** delete the `release-vX.Y` branch - [ ] Create the release tag using `kuboreleaser release --version vX.Y.Z(-RCN) tag` - This is a dangerous operation! Go and Docker publishing are difficult to reverse! Have the release reviewer verify all the commands marked with ⚠️! - - [ ] ⚠️ tag the HEAD commit of the `release-vX.Y` branch using `git tag -s vX.Y.Z(-RCN) -m 'Prerelease X.Y.Z(-RCN)'` - - [ ] ⚠️ tag the HEAD commit of the `release` branch using `git tag -s vX.Y.Z(-RCN) -m 'Release X.Y.Z(-RCN)'` + - [ ] ![](https://img.shields.io/badge/only-RC-blue?style=flat-square) ⚠️ tag the HEAD commit using `git tag -s vX.Y.Z(-RCN) -m 'Prerelease X.Y.Z(-RCN)'` + - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ⚠️ tag the HEAD commit of the `release` branch using `git tag -s vX.Y.Z(-RCN) -m 'Release X.Y.Z(-RCN)'` - [ ] ⚠️ verify the tag is signed and tied to the correct commit using `git show vX.Y.Z(-RCN)` - [ ] ⚠️ push the tag to GitHub using `git push origin vX.Y.Z(-RCN)` - do **NOT** use `git push --tags` because it pushes all your local tags @@ -105,16 +129,14 @@ As usual, this release includes important fixes, some of which may be critical f - [ ] verify the release is available on [NPM](https://www.npmjs.com/package/go-ipfs?activeTab=versions) - [ ] Publish the release to [GitHub](https://github.com/ipfs/kubo/releases) using `kuboreleaser release --version vX.Y.Z(-RCN) publish-to-github` - [ ] create a new release on [GitHub](https://docs.github.com/en/repositories/releasing-projects-on-github/managing-releases-in-a-repository#creating-a-release) - - [prerelease example](https://github.com/ipfs/kubo/releases/tag/v0.17.0-rc1) - - use the `vX.Y.Z(-RCN)` tag - - link to the release issue - - link to the changelog in the description - - check the `This is a pre-release` checkbox - - [release example](https://github.com/ipfs/kubo/releases/tag/v0.17.0) - - use the `vX.Y.Z(-RCN)` tag - - link to the release issue - - copy the changelog (without the header) in the description - - do **NOT** check the `This is a pre-release` checkbox + - [RC example](https://github.com/ipfs/kubo/releases/tag/v0.17.0-rc1) + - [FINAL example](https://github.com/ipfs/kubo/releases/tag/v0.17.0) + - [ ] use the `vX.Y.Z(-RCN)` tag + - [ ] link to the release issue + - [ ] ![](https://img.shields.io/badge/only-RC-blue?style=flat-square) link to the changelog in the description + - [ ] ![](https://img.shields.io/badge/only-RC-blue?style=flat-square) check the `This is a pre-release` checkbox + - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) copy the changelog (without the header) in the description + - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) do **NOT** check the `This is a pre-release` checkbox - [ ] run the [sync-release-assets](https://github.com/ipfs/kubo/actions/workflows/sync-release-assets.yml) workflow - [ ] wait for the [sync-release-assets](https://github.com/ipfs/kubo/actions/workflows/sync-release-assets.yml) workflow run to finish - [ ] verify the release assets are present in the [GitHub release](https://github.com/ipfs/kubo/releases/tag/vX.Y.Z(-RCN)) @@ -124,57 +146,57 @@ As usual, this release includes important fixes, some of which may be critical f - [ ] create an [IPFS Discourse](https://discuss.ipfs.tech) topic - [prerelease example](https://discuss.ipfs.tech/t/kubo-v0-16-0-rc1-release-candidate-is-out/15248) - [release example](https://discuss.ipfs.tech/t/kubo-v0-16-0-release-is-out/15249) - - use `Kubo vX.Y.Z(-RCN) is out!` as the title - - use `kubo` and `go-ipfs` as topics - - repeat the title as a heading (`##`) in the description - - link to the GitHub Release, binaries on IPNS, docker pull command and release notes in the description + - [ ] use `Kubo vX.Y.Z(-RCN) is out!` as the title + - [ ] use `kubo` and `go-ipfs` as topics + - [ ] repeat the title as a heading (`##`) in the description + - [ ] link to the GitHub Release, binaries on IPNS, docker pull command and release notes in the description - [ ] pin the [IPFS Discourse](https://discuss.ipfs.tech) topic globally - you can make the topic a banner if there is no banner already - verify the [IPFS Discourse](https://discuss.ipfs.tech) topic was copied to: - [ ] [#ipfs-chatter](https://discord.com/channels/669268347736686612/669268347736686615) in IPFS Discord - [ ] [#ipfs-chatter](https://filecoinproject.slack.com/archives/C018EJ8LWH1) in FIL Slack - [ ] [#ipfs-chatter:ipfs.io](https://matrix.to/#/#ipfs-chatter:ipfs.io) in Matrix - - [ ] create an issue comment mentioning early testers on the release issue + - [ ] ![](https://img.shields.io/badge/only-RC-blue?style=flat-square) create an issue comment mentioning early testers on the release issue - [example](https://github.com/ipfs/kubo/issues/9319#issuecomment-1311002478) - - [ ] create an issue comment linking to the release on the release issue + - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) create an issue comment linking to the release on the release issue - [example](https://github.com/ipfs/kubo/issues/9417#issuecomment-1400740975) - - [ ] ask the marketing team to tweet about the release in [#shared-pl-marketing-requests](https://filecoinproject.slack.com/archives/C018EJ8LWH1) in FIL Slack + - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ask the marketing team to tweet about the release in [#shared-pl-marketing-requests](https://filecoinproject.slack.com/archives/C018EJ8LWH1) in FIL Slack - [example](https://filecoinproject.slack.com/archives/C018EJ8LWH1/p1664885305374900) - - [ ] post the link to the [GitHub Release](https://github.com/ipfs/kubo/releases/tag/vX.Y.Z(-RCN)) to [Reddit](https://reddit.com/r/ipfs) + - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) post the link to the [GitHub Release](https://github.com/ipfs/kubo/releases/tag/vX.Y.Z(-RCN)) to [Reddit](https://reddit.com/r/ipfs) - [example](https://www.reddit.com/r/ipfs/comments/9x0q0k/kubo_v0160_release_is_out/) -- [ ] Add the link to the [IPFS Discourse](https://discuss.ipfs.tech) topic to the [GitHub Release](https://github.com/ipfs/kubo/releases/tag/vX.Y.Z(-RCN)) description +- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Add the link to the [IPFS Discourse](https://discuss.ipfs.tech) topic to the [GitHub Release](https://github.com/ipfs/kubo/releases/tag/vX.Y.Z(-RCN)) description - [example](https://github.com/ipfs/kubo/releases/tag/v0.17.0) -- [ ] `kuboreleaser release --version vX.Y.Z(-RCN) test-ipfs-companion` +- [ ] Test the new version with `ipfs-companion` using `kuboreleaser release --version vX.Y.Z(-RCN) test-ipfs-companion` - [ ] run the [e2e](https://github.com/ipfs/ipfs-companion/actions/workflows/e2e.yml) - use `vX.Y.Z(-RCN)` as the Kubo image version - [ ] wait for the [e2e](https://github.com/ipfs/ipfs-companion/actions/workflows/e2e.yml) workflow run to finish -- [ ] Update Kubo in [interop](https://github.com/ipfs/interop) using `kuboreleaser release --version vX.Y.Z(-RCN) update-interop` - - [ ] check out [ipfs/interop](https://github.com/ipfs/interop) - - [ ] run `npm install` - - [ ] create a PR which updates `package.json` and `package-lock.json` - - [ ] merge the PR +- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Update Kubo in [interop](https://github.com/ipfs/interop) using `kuboreleaser release --version vX.Y.Z(-RCN) update-interop` + - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) check out [ipfs/interop](https://github.com/ipfs/interop) + - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) run `npm install` + - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) create a PR which updates `package.json` and `package-lock.json` + - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) merge the PR - [ ] Update Kubo in [ipfs-desktop](https://github.com/ipfs/ipfs-desktop) using `kuboreleaser release --version vX.Y.Z(-RCN) update-ipfs-desktop` - [ ] check out [ipfs/ipfs-desktop](https://github.com/ipfs/ipfs-desktop) - [ ] run `npm install` - [ ] create a PR which updates `package.json` and `package-lock.json` - - [ ] merge the PR -- [ ] Update Kubo docs using `kuboreleaser release --version vX.Y.Z(-RCN) update-ipfs-docs` - - [ ] run the [update-on-new-ipfs-tag.yml](https://github.com/ipfs/ipfs-docs/actions/workflows/update-on-new-ipfs-tag.yml) workflow - - [ ] merge the PR created by the [update-on-new-ipfs-tag.yml](https://github.com/ipfs/ipfs-docs/actions/workflows/update-on-new-ipfs-tag.yml) workflow run -- [ ] Create a blog entry on [ipfs.tech](https://blog.ipfs.tech) `kuboreleaser release --version vX.Y.Z(-RCN) update-ipfs-blog --date YYYY-MM-DD` - - [ ] create a PR which adds a release note for the new Kubo version + - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) merge the PR +- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Update Kubo docs using `kuboreleaser release --version vX.Y.Z(-RCN) update-ipfs-docs` + - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) run the [update-on-new-ipfs-tag.yml](https://github.com/ipfs/ipfs-docs/actions/workflows/update-on-new-ipfs-tag.yml) workflow + - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) merge the PR created by the [update-on-new-ipfs-tag.yml](https://github.com/ipfs/ipfs-docs/actions/workflows/update-on-new-ipfs-tag.yml) workflow run +- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Create a blog entry on [ipfs.tech](https://blog.ipfs.tech) `kuboreleaser release --version vX.Y.Z(-RCN) update-ipfs-blog --date YYYY-MM-DD` + - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) create a PR which adds a release note for the new Kubo version - [example](https://github.com/ipfs/ipfs-blog/pull/529) - - [ ] merge the PR - - [ ] verify the blog entry was published + - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) merge the PR + - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) verify the blog entry was published - [ ] Keep checking the [metrics](https://protocollabs.grafana.net/d/8zlhkKTZk/gateway-slis-precomputed?orgId=1) until the release issue is closed - [release notes](https://www.notion.so/pl-strflt/Kubo-Gateway-Release-Notes-6e0efff28ee540be9ccb8f2b85104c42) - post in the [#bifrost](https://filecoinproject.slack.com/archives/C018EJ8LWH1) channel in FIL Slack if there is a problem -- [ ] Merge the [release](https://github.com/ipfs/kubo/tree/release) back into [master](https://github.com/ipfs/kubo/tree/master) using `kuboreleaser release --version vX.Y.Z(-RCN) merge-branch` +- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Merge the [release](https://github.com/ipfs/kubo/tree/release) back into [master](https://github.com/ipfs/kubo/tree/master) using `kuboreleaser release --version vX.Y.Z(-RCN) merge-branch` - ignore the changes to [version.go](version.go) (keep the `-dev` version) -- [ ] Create the next [changelog](https://github.com/ipfs/kubo/blob/master/docs/changelogs/vX.(Y+1).md) +- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) Create the next [changelog](https://github.com/ipfs/kubo/blob/master/docs/changelogs/vX.(Y+1).md) - link to the new changelog in the [CHANGELOG.md](CHANGELOG.md) file -- [ ] Create the next release issue -- [ ] Close the release issue +- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) Create the next release issue +- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Close the release issue ## How to contribute? From e1d0e13fe9ca2c0edf35338d85b7c1c69ab64d36 Mon Sep 17 00:00:00 2001 From: galargh Date: Thu, 26 Jan 2023 16:30:27 +0100 Subject: [PATCH 0429/1212] chore: remove obsolete PATCH_RELEASE_TEMPLATE.md --- docs/PATCH_RELEASE_TEMPLATE.md | 30 ------------------------------ 1 file changed, 30 deletions(-) delete mode 100644 docs/PATCH_RELEASE_TEMPLATE.md diff --git a/docs/PATCH_RELEASE_TEMPLATE.md b/docs/PATCH_RELEASE_TEMPLATE.md deleted file mode 100644 index a2599d9fd..000000000 --- a/docs/PATCH_RELEASE_TEMPLATE.md +++ /dev/null @@ -1,30 +0,0 @@ -# Patch Release Checklist - -This process handles patch releases from version `vX.Y.Z` to `vX.Y.Z+1` assuming that `vX.Y.Z` is the latest released version of Kubo. - -- [ ] Get temporary permissions to force-push to `release-*` branches -- [ ] Fork a new branch (`release-vX.Y.Z`) from `release` and cherry-pick the relevant commits from master (or custom fixes) onto this branch - - [ ] Use `git cherry-pick -x` so that the commit message says `(cherry picked from commit ...)` -- [ ] Make a minimal changelog update tracking the relevant fixes to CHANGELOG, as its own commit e.g. `docs: update changelog vX.Y.Z+1` -- [ ] version string in `version.go` has been updated (in the `release-vX.Y.Z+1` branch), as its own commit. -- [ ] Make a PR merging `release-vX.Y.Z+1` into the release branch - - This may be unnecessary, e.g. for backports -- [ ] Tag the merge commit in the `release` branch with `vX.Y.Z+1` (ensure the tag is signed) -- [ ] Add artifacts to https://dist.ipfs.tech/kubo - 1. Make a PR against [ipfs/distributions](https://github.com/ipfs/distributions) with local changes produced by `add-version` (see [usage](https://github.com/ipfs/distributions#usage)) - 2. Wait for PR to build artifacts and generate diff - 3. Inspect results, merge if CI is green and the diff looks ok - 4. Wait for `master` branch to build and update DNSLink at https://dist.ipfs.tech -- [ ] Cut a release on [github](https://github.com/ipfs/kubo/releases) and reuse signed artifacts from https://dist.ipfs.tech/kubo (run [sync-release-assets.yml workflow](https://github.com/ipfs/kubo/actions/workflows/sync-release-assets.yml)). -- [ ] Announce the Release: - - [ ] On [discuss.ipfs.tech](https://discuss.ipfs.tech) - - This will automatically post to Matrix (`#lobby:ipfs.io`) and IPFS Discord (`#ipfs-chatter`) - - Examples from the past: [0.13.1](https://discuss.ipfs.tech/t/go-ipfs-v0-13-1-has-been-released/14599) - - [ ] Pin the discuss topic -- [ ] Release published - - [ ] to [dist.ipfs.tech](https://dist.ipfs.tech) - - [ ] to [npm-go-ipfs](https://www.npmjs.com/package/go-ipfs) (should be done by [ipfs/npm-go-ipfs](https://github.com/ipfs/npm-go-ipfs), but ok to dispatch [this job](https://github.com/ipfs/npm-go-ipfs/actions/workflows/main.yml) manually) - - [ ] to [github](https://github.com/ipfs/kubo/releases) - - [ ] to [arch](https://www.archlinux.org/packages/community/x86_64/go-ipfs/) (flag it out of date) -- [ ] Cut a new ipfs-desktop release -- [ ] Merge the `release` branch back into `master`, ignoring the changes to `version.go` (keep the `-dev` version from master). From f20c980f2d60347b0c971c11b48a9fdd2ab11ecd Mon Sep 17 00:00:00 2001 From: Jorropo Date: Thu, 26 Jan 2023 16:24:40 +0100 Subject: [PATCH 0430/1212] chore: bump go-libipfs to replace go-block-format Includes changes from: - https://github.com/ipfs/go-block-format/pull/37 - https://github.com/ipfs/go-libipfs/pull/58 --- core/commands/dag/export.go | 2 +- core/commands/dag/put.go | 2 +- core/coreapi/block.go | 2 +- core/corehttp/gateway_handler_car.go | 2 +- core/coreunix/add_test.go | 2 +- docs/examples/kubo-as-a-library/go.mod | 4 +- docs/examples/kubo-as-a-library/go.sum | 7 +- go.mod | 4 +- go.sum | 7 +- test/integration/bitswap_wo_routing_test.go | 2 +- testplans/bitswap/go.mod | 11 +-- testplans/bitswap/go.sum | 86 +++++++++++++++------ testplans/bitswap/main.go | 2 +- thirdparty/verifbs/verifbs.go | 2 +- 14 files changed, 90 insertions(+), 45 deletions(-) diff --git a/core/commands/dag/export.go b/core/commands/dag/export.go index e9d120e87..b78523ce5 100644 --- a/core/commands/dag/export.go +++ b/core/commands/dag/export.go @@ -9,9 +9,9 @@ import ( "time" "github.com/cheggaaa/pb" - blocks "github.com/ipfs/go-block-format" cid "github.com/ipfs/go-cid" ipld "github.com/ipfs/go-ipld-format" + blocks "github.com/ipfs/go-libipfs/blocks" iface "github.com/ipfs/interface-go-ipfs-core" "github.com/ipfs/kubo/core/commands/cmdenv" diff --git a/core/commands/dag/put.go b/core/commands/dag/put.go index ed00c5bee..351b9cacd 100644 --- a/core/commands/dag/put.go +++ b/core/commands/dag/put.go @@ -4,9 +4,9 @@ import ( "bytes" "fmt" - blocks "github.com/ipfs/go-block-format" "github.com/ipfs/go-cid" ipldlegacy "github.com/ipfs/go-ipld-legacy" + blocks "github.com/ipfs/go-libipfs/blocks" "github.com/ipfs/kubo/core/commands/cmdenv" "github.com/ipfs/kubo/core/commands/cmdutils" "github.com/ipld/go-ipld-prime/multicodec" diff --git a/core/coreapi/block.go b/core/coreapi/block.go index 886a21bf4..4f086ae86 100644 --- a/core/coreapi/block.go +++ b/core/coreapi/block.go @@ -6,9 +6,9 @@ import ( "errors" "io" - blocks "github.com/ipfs/go-block-format" cid "github.com/ipfs/go-cid" pin "github.com/ipfs/go-ipfs-pinner" + blocks "github.com/ipfs/go-libipfs/blocks" coreiface "github.com/ipfs/interface-go-ipfs-core" caopts "github.com/ipfs/interface-go-ipfs-core/options" path "github.com/ipfs/interface-go-ipfs-core/path" diff --git a/core/corehttp/gateway_handler_car.go b/core/corehttp/gateway_handler_car.go index 3363c5199..9f704d6ca 100644 --- a/core/corehttp/gateway_handler_car.go +++ b/core/corehttp/gateway_handler_car.go @@ -6,8 +6,8 @@ import ( "net/http" "time" - blocks "github.com/ipfs/go-block-format" cid "github.com/ipfs/go-cid" + blocks "github.com/ipfs/go-libipfs/blocks" coreiface "github.com/ipfs/interface-go-ipfs-core" ipath "github.com/ipfs/interface-go-ipfs-core/path" "github.com/ipfs/kubo/tracing" diff --git a/core/coreunix/add_test.go b/core/coreunix/add_test.go index 1ba1b2f0e..e64d41001 100644 --- a/core/coreunix/add_test.go +++ b/core/coreunix/add_test.go @@ -14,13 +14,13 @@ import ( "github.com/ipfs/kubo/gc" "github.com/ipfs/kubo/repo" - blocks "github.com/ipfs/go-block-format" "github.com/ipfs/go-blockservice" "github.com/ipfs/go-cid" "github.com/ipfs/go-datastore" syncds "github.com/ipfs/go-datastore/sync" blockstore "github.com/ipfs/go-ipfs-blockstore" pi "github.com/ipfs/go-ipfs-posinfo" + blocks "github.com/ipfs/go-libipfs/blocks" "github.com/ipfs/go-libipfs/files" dag "github.com/ipfs/go-merkledag" coreiface "github.com/ipfs/interface-go-ipfs-core" diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index edc684831..309f06aa9 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.18 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/go-libipfs v0.2.0 + github.com/ipfs/go-libipfs v0.3.0 github.com/ipfs/interface-go-ipfs-core v0.8.2 github.com/ipfs/kubo v0.14.0-rc1 github.com/libp2p/go-libp2p v0.24.2 @@ -63,7 +63,7 @@ require ( github.com/ipfs/bbloom v0.0.4 // indirect github.com/ipfs/go-bitfield v1.0.0 // indirect github.com/ipfs/go-bitswap v0.11.0 // indirect - github.com/ipfs/go-block-format v0.0.3 // indirect + github.com/ipfs/go-block-format v0.1.0 // indirect github.com/ipfs/go-blockservice v0.5.0 // indirect github.com/ipfs/go-cid v0.3.2 // indirect github.com/ipfs/go-cidutil v0.1.0 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index fa6c022f3..e194ef92e 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -423,8 +423,9 @@ github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1Hy github.com/ipfs/go-bitswap v0.11.0/go.mod h1:05aE8H3XOU+LXpTedeAS0OZpcO1WFsj5niYQH9a1Tmk= github.com/ipfs/go-block-format v0.0.1/go.mod h1:DK/YYcsSUIVAFNwo/KZCdIIbpN0ROH/baNLgayt4pFc= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= -github.com/ipfs/go-block-format v0.0.3 h1:r8t66QstRp/pd/or4dpnbVfXT5Gt7lOqRvC+/dDTpMc= github.com/ipfs/go-block-format v0.0.3/go.mod h1:4LmD4ZUw0mhO+JSKdpWwrzATiEfM7WWgQ8H5l6P8MVk= +github.com/ipfs/go-block-format v0.1.0 h1:1DYLENGQUVWVvZ9tMmZX2KVi0ALyPxxyP6jn8NuCxZY= +github.com/ipfs/go-block-format v0.1.0/go.mod h1:+McEIT+g52p+zz5xGAABGSOKrzmrdX97bc0USBdWPUs= github.com/ipfs/go-blockservice v0.1.0/go.mod h1:hzmMScl1kXHg3M2BjTymbVPjv627N7sYcvYaKbop39M= github.com/ipfs/go-blockservice v0.2.1/go.mod h1:k6SiwmgyYgs4M/qt+ww6amPeUH9EISLRBnvUurKJhi8= github.com/ipfs/go-blockservice v0.3.0/go.mod h1:P5ppi8IHDC7O+pA0AlGTF09jruB2h+oP3wVVaZl8sfk= @@ -546,8 +547,8 @@ github.com/ipfs/go-ipld-legacy v0.1.1 h1:BvD8PEuqwBHLTKqlGFTHSwrwFOMkVESEvwIYwR2 github.com/ipfs/go-ipld-legacy v0.1.1/go.mod h1:8AyKFCjgRPsQFf15ZQgDB8Din4DML/fOmKZkkFkrIEg= github.com/ipfs/go-ipns v0.3.0 h1:ai791nTgVo+zTuq2bLvEGmWP1M0A6kGTXUsgv/Yq67A= github.com/ipfs/go-ipns v0.3.0/go.mod h1:3cLT2rbvgPZGkHJoPO1YMJeh6LtkxopCkKFcio/wE24= -github.com/ipfs/go-libipfs v0.2.0 h1:MedvelDEddPYL3iDLoqAsviLeXUiwB1F2t8fkzx9/EU= -github.com/ipfs/go-libipfs v0.2.0/go.mod h1:qX0d9h+wu53PFtCTXxdXVBakd6ZCvGDdkZUKmdLMLx0= +github.com/ipfs/go-libipfs v0.3.0 h1:YvzFWGcl88eiz2tjOheNqaeQseH+dW3fUKrSaHOG/dU= +github.com/ipfs/go-libipfs v0.3.0/go.mod h1:pSUHZ5qPJTAidsxe9bAeHp3KIiw2ODEW2a2kM3v+iXI= github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= github.com/ipfs/go-log v1.0.2/go.mod h1:1MNjMxe0u6xvJZgeqbJ8vdo2TKaGwZ1a0Bpza+sr2Sk= github.com/ipfs/go-log v1.0.3/go.mod h1:OsLySYkwIbiSUR/yBTdv1qPtcE4FW3WPWk/ewz9Ru+A= diff --git a/go.mod b/go.mod index b837fa504..273c01510 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,6 @@ require ( github.com/google/uuid v1.3.0 github.com/hashicorp/go-multierror v1.1.1 github.com/ipfs/go-bitswap v0.11.0 - github.com/ipfs/go-block-format v0.0.3 github.com/ipfs/go-blockservice v0.5.0 github.com/ipfs/go-cid v0.3.2 github.com/ipfs/go-cidutil v0.1.0 @@ -49,7 +48,7 @@ require ( github.com/ipfs/go-ipld-git v0.1.1 github.com/ipfs/go-ipld-legacy v0.1.1 github.com/ipfs/go-ipns v0.3.0 - github.com/ipfs/go-libipfs v0.2.0 + github.com/ipfs/go-libipfs v0.3.0 github.com/ipfs/go-log v1.0.5 github.com/ipfs/go-log/v2 v2.5.1 github.com/ipfs/go-merkledag v0.9.0 @@ -158,6 +157,7 @@ require ( github.com/huin/goupnp v1.0.3 // indirect github.com/ipfs/bbloom v0.0.4 // indirect github.com/ipfs/go-bitfield v1.0.0 // indirect + github.com/ipfs/go-block-format v0.1.0 // indirect github.com/ipfs/go-ipfs-delay v0.0.1 // indirect github.com/ipfs/go-ipfs-ds-help v1.1.0 // indirect github.com/ipfs/go-ipfs-pq v0.0.2 // indirect diff --git a/go.sum b/go.sum index 6274ef85b..ab1548f37 100644 --- a/go.sum +++ b/go.sum @@ -441,8 +441,9 @@ github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1Hy github.com/ipfs/go-bitswap v0.11.0/go.mod h1:05aE8H3XOU+LXpTedeAS0OZpcO1WFsj5niYQH9a1Tmk= github.com/ipfs/go-block-format v0.0.1/go.mod h1:DK/YYcsSUIVAFNwo/KZCdIIbpN0ROH/baNLgayt4pFc= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= -github.com/ipfs/go-block-format v0.0.3 h1:r8t66QstRp/pd/or4dpnbVfXT5Gt7lOqRvC+/dDTpMc= github.com/ipfs/go-block-format v0.0.3/go.mod h1:4LmD4ZUw0mhO+JSKdpWwrzATiEfM7WWgQ8H5l6P8MVk= +github.com/ipfs/go-block-format v0.1.0 h1:1DYLENGQUVWVvZ9tMmZX2KVi0ALyPxxyP6jn8NuCxZY= +github.com/ipfs/go-block-format v0.1.0/go.mod h1:+McEIT+g52p+zz5xGAABGSOKrzmrdX97bc0USBdWPUs= github.com/ipfs/go-blockservice v0.1.0/go.mod h1:hzmMScl1kXHg3M2BjTymbVPjv627N7sYcvYaKbop39M= github.com/ipfs/go-blockservice v0.2.1/go.mod h1:k6SiwmgyYgs4M/qt+ww6amPeUH9EISLRBnvUurKJhi8= github.com/ipfs/go-blockservice v0.3.0/go.mod h1:P5ppi8IHDC7O+pA0AlGTF09jruB2h+oP3wVVaZl8sfk= @@ -568,8 +569,8 @@ github.com/ipfs/go-ipld-legacy v0.1.1 h1:BvD8PEuqwBHLTKqlGFTHSwrwFOMkVESEvwIYwR2 github.com/ipfs/go-ipld-legacy v0.1.1/go.mod h1:8AyKFCjgRPsQFf15ZQgDB8Din4DML/fOmKZkkFkrIEg= github.com/ipfs/go-ipns v0.3.0 h1:ai791nTgVo+zTuq2bLvEGmWP1M0A6kGTXUsgv/Yq67A= github.com/ipfs/go-ipns v0.3.0/go.mod h1:3cLT2rbvgPZGkHJoPO1YMJeh6LtkxopCkKFcio/wE24= -github.com/ipfs/go-libipfs v0.2.0 h1:MedvelDEddPYL3iDLoqAsviLeXUiwB1F2t8fkzx9/EU= -github.com/ipfs/go-libipfs v0.2.0/go.mod h1:qX0d9h+wu53PFtCTXxdXVBakd6ZCvGDdkZUKmdLMLx0= +github.com/ipfs/go-libipfs v0.3.0 h1:YvzFWGcl88eiz2tjOheNqaeQseH+dW3fUKrSaHOG/dU= +github.com/ipfs/go-libipfs v0.3.0/go.mod h1:pSUHZ5qPJTAidsxe9bAeHp3KIiw2ODEW2a2kM3v+iXI= github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= github.com/ipfs/go-log v1.0.2/go.mod h1:1MNjMxe0u6xvJZgeqbJ8vdo2TKaGwZ1a0Bpza+sr2Sk= github.com/ipfs/go-log v1.0.3/go.mod h1:OsLySYkwIbiSUR/yBTdv1qPtcE4FW3WPWk/ewz9Ru+A= diff --git a/test/integration/bitswap_wo_routing_test.go b/test/integration/bitswap_wo_routing_test.go index fa4e8d513..6a6fca4b7 100644 --- a/test/integration/bitswap_wo_routing_test.go +++ b/test/integration/bitswap_wo_routing_test.go @@ -5,8 +5,8 @@ import ( "context" "testing" - blocks "github.com/ipfs/go-block-format" "github.com/ipfs/go-cid" + blocks "github.com/ipfs/go-libipfs/blocks" "github.com/ipfs/kubo/core" coremock "github.com/ipfs/kubo/core/mock" "github.com/ipfs/kubo/core/node/libp2p" diff --git a/testplans/bitswap/go.mod b/testplans/bitswap/go.mod index 3ae17384c..92cf8f199 100644 --- a/testplans/bitswap/go.mod +++ b/testplans/bitswap/go.mod @@ -3,16 +3,17 @@ module github.com/ipfs/go-ipfs/testplans/bitswap require ( github.com/gopherjs/gopherjs v0.0.0-20190812055157-5d271430af9f // indirect github.com/ipfs/go-bitswap v0.10.1 - github.com/ipfs/go-block-format v0.0.3 - github.com/ipfs/go-cid v0.2.0 - github.com/ipfs/go-datastore v0.5.1 + github.com/ipfs/go-block-format v0.1.0 // indirect + github.com/ipfs/go-cid v0.3.2 + github.com/ipfs/go-datastore v0.6.0 github.com/ipfs/go-ipfs-blockstore v1.2.0 github.com/ipfs/go-ipfs-exchange-interface v0.2.0 github.com/ipfs/go-ipfs-regression v0.0.1 + github.com/ipfs/go-libipfs v0.3.0 github.com/ipld/go-ipld-prime v0.9.1-0.20210324083106-dc342a9917db // indirect - github.com/libp2p/go-libp2p v0.22.0 + github.com/libp2p/go-libp2p v0.23.4 github.com/libp2p/go-libp2p-kad-dht v0.18.0 - github.com/multiformats/go-multiaddr v0.6.0 + github.com/multiformats/go-multiaddr v0.8.0 github.com/multiformats/go-multihash v0.2.1 github.com/polydawn/refmt v0.0.0-20201211092308-30ac6d18308e // indirect github.com/smartystreets/assertions v1.0.1 // indirect diff --git a/testplans/bitswap/go.sum b/testplans/bitswap/go.sum index c71296c05..c9f0bc166 100644 --- a/testplans/bitswap/go.sum +++ b/testplans/bitswap/go.sum @@ -87,7 +87,6 @@ github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghf github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cheekybits/genny v1.0.0 h1:uGGa4nei+j20rOSeDeP5Of12XVm7TGUd4dJA9RDitfE= github.com/cheekybits/genny v1.0.0/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ= 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= @@ -106,11 +105,14 @@ github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3Ee 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.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/go-systemd/v22 v22.4.0 h1:y9YHcjnjynCd/DVbg5j9L/33jQM3MxJlbj/zWskzfGU= +github.com/coreos/go-systemd/v22 v22.4.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= 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/go.mod h1:p1d6YEZWvFzEh4KLyvBcVSnrfNDDvK2zfK/4x2v/4pE= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cskr/pubsub v1.0.2 h1:vlOzMhl6PFn60gRlTQQsIfVwaPB/B/8MziK8FhEPt/0= github.com/cskr/pubsub v1.0.2/go.mod h1:/8MzYXk/NJAz782G8RPkFzXTZVu63VotefPnR9TIRis= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -130,8 +132,9 @@ github.com/dgraph-io/badger v1.6.1/go.mod h1:FRmFw3uxvcpa8zG3Rxs0th+hCLIuaQg8HlN github.com/dgraph-io/badger v1.6.2/go.mod h1:JW2yswe3V058sS0kZ2h/AXeDSqFjxnZcRrVH//y2UQE= github.com/dgraph-io/ristretto v0.0.2/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= 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/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= +github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/elastic/gosigar v0.12.0/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= @@ -262,6 +265,7 @@ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5m github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20190812055157-5d271430af9f h1:KMlcu9X58lhTA/KrfX8Bi1LQSO4pzoVjTiL3h4Jk+Zk= github.com/gopherjs/gopherjs v0.0.0-20190812055157-5d271430af9f/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= @@ -292,23 +296,26 @@ github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyq github.com/ipfs/go-bitswap v0.10.1 h1:XaMmwMR8NgxpzB2hVtZsVLPJPTn2pfAA66GN8gZJTl8= github.com/ipfs/go-bitswap v0.10.1/go.mod h1:+fZEvycxviZ7c+5KlKwTzLm0M28g2ukCPqiuLfJk4KA= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= -github.com/ipfs/go-block-format v0.0.3 h1:r8t66QstRp/pd/or4dpnbVfXT5Gt7lOqRvC+/dDTpMc= github.com/ipfs/go-block-format v0.0.3/go.mod h1:4LmD4ZUw0mhO+JSKdpWwrzATiEfM7WWgQ8H5l6P8MVk= +github.com/ipfs/go-block-format v0.1.0 h1:1DYLENGQUVWVvZ9tMmZX2KVi0ALyPxxyP6jn8NuCxZY= +github.com/ipfs/go-block-format v0.1.0/go.mod h1:+McEIT+g52p+zz5xGAABGSOKrzmrdX97bc0USBdWPUs= github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.2/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.3/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.4/go.mod h1:4LLaPOQwmk5z9LBgQnpkivrx8BJjUyGwTXCd5Xfj6+M= github.com/ipfs/go-cid v0.0.5/go.mod h1:plgt+Y5MnOey4vO4UlUazGqdbEXuFYitED67FexhXog= github.com/ipfs/go-cid v0.0.7/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I= -github.com/ipfs/go-cid v0.2.0 h1:01JTiihFq9en9Vz0lc0VDWvZe/uBonGpzo4THP0vcQ0= github.com/ipfs/go-cid v0.2.0/go.mod h1:P+HXFDF4CVhaVayiEb4wkAy7zBHxBwsJyt0Y5U6MLro= +github.com/ipfs/go-cid v0.3.2 h1:OGgOd+JCFM+y1DjWPmVH+2/4POtpDzwcr7VgnB7mZXc= +github.com/ipfs/go-cid v0.3.2/go.mod h1:gQ8pKqT/sUxGY+tIwy1RPpAojYu7jAyCp5Tz1svoupw= github.com/ipfs/go-datastore v0.1.0/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= github.com/ipfs/go-datastore v0.1.1/go.mod h1:w38XXW9kVFNp57Zj5knbKWM2T+KOZCGDRVNdgPHtbHw= github.com/ipfs/go-datastore v0.4.1/go.mod h1:SX/xMIKoCszPqp+z9JhPYCmoOoXTvaa13XEbGtsFUhA= github.com/ipfs/go-datastore v0.4.4/go.mod h1:SX/xMIKoCszPqp+z9JhPYCmoOoXTvaa13XEbGtsFUhA= github.com/ipfs/go-datastore v0.5.0/go.mod h1:9zhEApYMTl17C8YDp7JmU7sQZi2/wqiYh73hakZ90Bk= -github.com/ipfs/go-datastore v0.5.1 h1:WkRhLuISI+XPD0uk3OskB0fYFSyqK8Ob5ZYew9Qa1nQ= github.com/ipfs/go-datastore v0.5.1/go.mod h1:9zhEApYMTl17C8YDp7JmU7sQZi2/wqiYh73hakZ90Bk= +github.com/ipfs/go-datastore v0.6.0 h1:JKyz+Gvz1QEZw0LsX1IBn+JFCJQH4SJVFtM4uWU0Myk= +github.com/ipfs/go-datastore v0.6.0/go.mod h1:rt5M3nNbSO/8q1t4LNkLyUwRs8HupMeN/8O4Vn9YAT8= github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk= github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps= github.com/ipfs/go-ds-badger v0.0.7/go.mod h1:qt0/fWzZDoPW6jpQeqUjR5kBfhDNB65jd9YlmAvpQBk= @@ -340,8 +347,11 @@ github.com/ipfs/go-ipfs-util v0.0.2 h1:59Sswnk1MFaiq+VcaknX7aYEyGyGDAA73ilhEK2PO github.com/ipfs/go-ipfs-util v0.0.2/go.mod h1:CbPtkWJzjLdEcezDns2XYaehFVNXG9zrdrtMecczcsQ= github.com/ipfs/go-ipld-format v0.3.0 h1:Mwm2oRLzIuUwEPewWAWyMuuBQUsn3awfFEYVb8akMOQ= github.com/ipfs/go-ipld-format v0.3.0/go.mod h1:co/SdBE8h99968X0hViiw1MNlh6fvxxnHpvVLnH7jSM= -github.com/ipfs/go-ipns v0.2.0 h1:BgmNtQhqOw5XEZ8RAfWEpK4DhqaYiuP6h71MhIp7xXU= github.com/ipfs/go-ipns v0.2.0/go.mod h1:3cLT2rbvgPZGkHJoPO1YMJeh6LtkxopCkKFcio/wE24= +github.com/ipfs/go-ipns v0.3.0 h1:ai791nTgVo+zTuq2bLvEGmWP1M0A6kGTXUsgv/Yq67A= +github.com/ipfs/go-ipns v0.3.0/go.mod h1:3cLT2rbvgPZGkHJoPO1YMJeh6LtkxopCkKFcio/wE24= +github.com/ipfs/go-libipfs v0.3.0 h1:YvzFWGcl88eiz2tjOheNqaeQseH+dW3fUKrSaHOG/dU= +github.com/ipfs/go-libipfs v0.3.0/go.mod h1:pSUHZ5qPJTAidsxe9bAeHp3KIiw2ODEW2a2kM3v+iXI= github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= github.com/ipfs/go-log v1.0.3/go.mod h1:OsLySYkwIbiSUR/yBTdv1qPtcE4FW3WPWk/ewz9Ru+A= github.com/ipfs/go-log v1.0.4/go.mod h1:oDCg2FkjogeFOhqqb+N39l2RpTNPL6F/StPkB3kPgcs= @@ -390,12 +400,14 @@ github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQL 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.15.1 h1:y9FcTHGyrebwfP0ZZqFiaxTaiDnUrGkJkI+f583BL1A= github.com/klauspost/compress v1.15.1/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/klauspost/compress v1.15.10 h1:Ai8UzuomSCDw90e1qNMtb15msBXsNpH6gzkkENQNcJo= +github.com/klauspost/compress v1.15.10/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.1.0 h1:eyi1Ad2aNJMW95zcSbmGg7Cg6cq3ADwLpMAP96d8rF0= github.com/klauspost/cpuid/v2 v2.1.0/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= +github.com/klauspost/cpuid/v2 v2.1.1 h1:t0wUqjowdm8ezddV5k0tLWVklVuvLJpoHeb4WBdydm0= +github.com/klauspost/cpuid/v2 v2.1.1/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/koron/go-ssdp v0.0.0-20191105050749-2e1c40ed0b5d/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk= @@ -408,8 +420,9 @@ github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/libp2p/go-buffer-pool v0.0.1/go.mod h1:xtyIz9PMobb13WaxR6Zo1Pd1zXJKYg0a8KiIvDp3TzQ= github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM= github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= @@ -421,8 +434,9 @@ github.com/libp2p/go-flow-metrics v0.0.2/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.22.0 h1:2Tce0kHOp5zASFKJbNzRElvh0iZwdtG5uZheNW8chIw= github.com/libp2p/go-libp2p v0.22.0/go.mod h1:UDolmweypBSjQb2f7xutPnwZ/fxioLbMBxSjRksxxU4= +github.com/libp2p/go-libp2p v0.23.4 h1:hWi9XHSOVFR1oDWRk7rigfyA4XNMuYL20INNybP9LP8= +github.com/libp2p/go-libp2p v0.23.4/go.mod h1:s9DEa5NLR4g+LZS+md5uGU4emjMWFiqkZr6hBTY8UxI= 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.2.0 h1:rg3+Os8jbnO5DxkC7K/Utdi+DkY3q/d1/1q+8WeNAsw= github.com/libp2p/go-libp2p-asn-util v0.2.0/go.mod h1:WoaWxbHKBymSN41hWSq/lGKJEca7TNm58+gGJi2WsLI= @@ -475,19 +489,20 @@ github.com/libp2p/go-openssl v0.1.0/go.mod h1:OiOxwPpL3n4xlenjx2h7AwSGaFSC/KZvf6 github.com/libp2p/go-reuseport v0.2.0 h1:18PRvIMlpY6ZK85nIAicSBuXXvrYoSw3dsBAR7zc560= github.com/libp2p/go-reuseport v0.2.0/go.mod h1:bvVho6eLMm6Bz5hmU0LYN3ixd3nPPvtIlaURZZgOY4k= github.com/libp2p/go-sockaddr v0.0.2/go.mod h1:syPvOmNs24S3dFVGJA1/mrqdeijPxLV2Le3BRLKd68k= -github.com/libp2p/go-yamux/v3 v3.1.2 h1:lNEy28MBk1HavUAlzKgShp+F6mn/ea1nDYWftZhFW9Q= github.com/libp2p/go-yamux/v3 v3.1.2/go.mod h1:jeLEQgLXqE2YqX1ilAClIfCMDY+0uXQUKmmb/qp0gT4= +github.com/libp2p/go-yamux/v4 v4.0.0 h1:+Y80dV2Yx/kv7Y7JKu0LECyVdMXm1VUoko+VQ9rBfZQ= +github.com/libp2p/go-yamux/v4 v4.0.0/go.mod h1:NWjl8ZTLOGlozrXSOZ/HlfG++39iKNnM5wwmtQP1YB4= github.com/libp2p/zeroconf/v2 v2.2.0/go.mod h1:fuJqLnUwZTshS3U/bMRJ3+ow/v9oid1n0DmyYyNO1Xs= -github.com/lucas-clemente/quic-go v0.28.1 h1:Uo0lvVxWg5la9gflIF9lwa39ONq85Xq2D91YNEIslzU= github.com/lucas-clemente/quic-go v0.28.1/go.mod h1:oGz5DKK41cJt5+773+BSO9BXDsREY4HLf7+0odGAPO0= +github.com/lucas-clemente/quic-go v0.29.1 h1:Z+WMJ++qMLhvpFkRZA+jl3BTxUjm415YBmWanXB8zP0= +github.com/lucas-clemente/quic-go v0.29.1/go.mod h1:CTcNfLYJS2UuRNB+zcNlgvkjBhxX6Hm3WUxxAQx2mgE= github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/marten-seemann/qpack v0.2.1 h1:jvTsT/HpCn2UZJdP+UUB53FfUUgeOyG5K1ns0OJOGVs= github.com/marten-seemann/qpack v0.2.1/go.mod h1:F7Gl5L1jIgN1D11ucXefiuJS9UMVP2opoCp2jDKb7wc= -github.com/marten-seemann/qtls-go1-16 v0.1.5 h1:o9JrYPPco/Nukd/HpOHMHZoBDXQqoNtUCmny98/1uqQ= github.com/marten-seemann/qtls-go1-16 v0.1.5/go.mod h1:gNpI2Ol+lRS3WwSOtIUUtRwZEQMXjYK+dQSBFbethAk= -github.com/marten-seemann/qtls-go1-17 v0.1.2 h1:JADBlm0LYiVbuSySCHeY863dNkcpMmDR7s0bLKJeYlQ= github.com/marten-seemann/qtls-go1-17 v0.1.2/go.mod h1:C2ekUKcDdz9SDWxec1N/MvcXBpaX9l3Nx67XaR84L5s= github.com/marten-seemann/qtls-go1-18 v0.1.2 h1:JH6jmzbduz0ITVQ7ShevK10Av5+jBEKAHMntXmIV7kM= github.com/marten-seemann/qtls-go1-18 v0.1.2/go.mod h1:mJttiymBAByA49mhlNZZGrH5u1uXYZJ+RW28Py7f4m4= @@ -496,6 +511,8 @@ github.com/marten-seemann/qtls-go1-19 v0.1.0 h1:rLFKD/9mp/uq1SYGYuVZhm83wkmU95pK github.com/marten-seemann/qtls-go1-19 v0.1.0/go.mod h1:5HTDWtVudo/WFsHKRNuOhWlbdjrfs5JHrYb0wIJqGpI= 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/marten-seemann/webtransport-go v0.1.1 h1:TnyKp3pEXcDooTaNn4s9dYpMJ7kMnTp7k5h+SgYP/mc= +github.com/marten-seemann/webtransport-go v0.1.1/go.mod h1:kBEh5+RSvOA4troP1vyOVBWK4MIMzDICXVrvCPrYcrM= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= @@ -540,8 +557,9 @@ github.com/mr-tron/base58 v1.1.3/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjW github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= -github.com/multiformats/go-base32 v0.0.4 h1:+qMh4a2f37b4xTNs6mqitDinryCI+tfO2dRVMN9mjSE= github.com/multiformats/go-base32 v0.0.4/go.mod h1:jNLFzjPZtp3aIARHbJRZIaPuspdH0J6q39uUM5pnABM= +github.com/multiformats/go-base32 v0.1.0 h1:pVx9xoSPqEIQG8o+UbAe7DNi51oej1NtK+aGkbLYxPE= +github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYgtWibDcT0rExnbI= github.com/multiformats/go-base36 v0.1.0 h1:JR6TyF7JjGd3m6FbLU2cOxhC0Li8z8dLNGQ89tUg4F4= github.com/multiformats/go-base36 v0.1.0/go.mod h1:kFGE83c6s80PklsHO9sRn2NCoffoRdUUOENyW/Vv6sM= github.com/multiformats/go-multiaddr v0.0.2/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= @@ -554,8 +572,10 @@ github.com/multiformats/go-multiaddr v0.2.2/go.mod h1:NtfXiOtHvghW9KojvtySjH5y0u github.com/multiformats/go-multiaddr v0.3.0/go.mod h1:dF9kph9wfJ+3VLAaeBqo9Of8x4fJxp6ggJGteB8HQTI= github.com/multiformats/go-multiaddr v0.3.1/go.mod h1:uPbspcUPd5AfaP6ql3ujFY+QWzmBD8uLLL4bXW0XfGc= github.com/multiformats/go-multiaddr v0.4.1/go.mod h1:3afI9HfVW8csiF8UZqtpYRiDyew8pRX7qLIGHu9FLuM= -github.com/multiformats/go-multiaddr v0.6.0 h1:qMnoOPj2s8xxPU5kZ57Cqdr0hHhARz7mFsPMIiYNqzg= github.com/multiformats/go-multiaddr v0.6.0/go.mod h1:F4IpaKZuPP360tOMn2Tpyu0At8w23aRyVqeK0DbFeGM= +github.com/multiformats/go-multiaddr v0.7.0/go.mod h1:Fs50eBDWvZu+l3/9S6xAE7ZYj6yhxlvaVZjakWN7xRs= +github.com/multiformats/go-multiaddr v0.8.0 h1:aqjksEcqK+iD/Foe1RRFsGZh8+XFiGo7FgUCZlpv3LU= +github.com/multiformats/go-multiaddr v0.8.0/go.mod h1:Fs50eBDWvZu+l3/9S6xAE7ZYj6yhxlvaVZjakWN7xRs= github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A= github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk= github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E= @@ -568,8 +588,9 @@ github.com/multiformats/go-multibase v0.0.3/go.mod h1:5+1R4eQrT3PkYZ24C3W2Ue2tPw github.com/multiformats/go-multibase v0.1.1 h1:3ASCDsuLX8+j4kx58qnJ4YFq/JWTJpCyDW27ztsVTOI= github.com/multiformats/go-multibase v0.1.1/go.mod h1:ZEjHE+IsUrgp5mhlEAYjMtZwK1k4haNkcaPg9aoe1a8= github.com/multiformats/go-multicodec v0.4.1/go.mod h1:1Hj/eHRaVWSXiSNNfcEPcwZleTmdNP81xlxDLnWU9GQ= -github.com/multiformats/go-multicodec v0.5.0 h1:EgU6cBe/D7WRwQb1KmnBvU7lrcFGMggZVTPtOW9dDHs= github.com/multiformats/go-multicodec v0.5.0/go.mod h1:DiY2HFaEp5EhEXb/iYzVAunmyX/aSFMxq2KMKfWEues= +github.com/multiformats/go-multicodec v0.6.0 h1:KhH2kSuCARyuJraYMFxrNO3DqIaYhOdS039kbhgVwpE= +github.com/multiformats/go-multicodec v0.6.0/go.mod h1:GUC8upxSBE4oG+q3kWZRw/+6yC1BqO550bjhWsJbZlw= github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= github.com/multiformats/go-multihash v0.0.5/go.mod h1:lt/HCbqlQwlPBz7lv0sQCdtfcMtlJvakRUn/0Ual8po= github.com/multiformats/go-multihash v0.0.8/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= @@ -591,6 +612,7 @@ github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRW github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= @@ -634,8 +656,9 @@ github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXP github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -github.com/prometheus/client_golang v1.12.1 h1:ZiaPsmm9uiBeaSMRznKsCDNtPCS0T3JVDGF+06gjBzk= github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= +github.com/prometheus/client_golang v1.13.0 h1:b71QUfeo5M8gq2+evJdTPfZhYMAU0uKPkyPJ7TPsloU= +github.com/prometheus/client_golang v1.13.0/go.mod h1:vTeo+zgvILHsnnj/39Ou/1fPN5nJFOEMgftOUOmlvYQ= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -663,6 +686,7 @@ github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0/go.mod h1:bCqn github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/samber/lo v1.36.0/go.mod h1:HLeWcJRRyLKp3+/XBJvOrerCQn9mhdKMHyd7IRlgeQ8= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY= github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM= @@ -716,6 +740,7 @@ github.com/src-d/envconfig v1.0.0/go.mod h1:Q9YQZ7BKITldTBnoxsE5gOeB5y66RyPXeue/ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -723,12 +748,14 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= github.com/testground/sdk-go v0.2.7 h1:SDLDukPZIaZOeG2gQjCNsh5EB3QL3mOhOM4p0BMpqlc= github.com/testground/sdk-go v0.2.7/go.mod h1:Q4dnWsUBH+dZ1u7aEGDBHWGUaLfhitjUq3UJQqxeTmk= +github.com/thoas/go-funk v0.9.1/go.mod h1:+IWnUfUmFO1+WVYQWQtIJHeRRdaIyyYglZN7xzUPe4Q= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU= @@ -746,6 +773,7 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= @@ -781,8 +809,9 @@ go.uber.org/zap v1.14.1/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= 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.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= -go.uber.org/zap v1.22.0 h1:Zcye5DUgBloQ9BaT4qc9BnjOFog5TvBSAGkJ3Nf70c0= go.uber.org/zap v1.22.0/go.mod h1:H4siCOZOrAolnUPJEkfaSjDqyP+BDS0DdDWzwcgt3+U= +go.uber.org/zap v1.23.0 h1:OjGQ5KQDEUawVHxNwQgPpiypGHOxo2mNZsOqTak4fFY= +go.uber.org/zap v1.23.0/go.mod h1:D+nX8jyLsMHMYrln8A0rJjFt/T/9/bGgIhAqxv5URuY= go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -820,6 +849,10 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17/go.mod h1:lgLbSvA5ygNOMpwM/9anMpWVlVJ7Z+cHWq/eFuinpGE= +golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA= +golang.org/x/exp v0.0.0-20220916125017-b168a2c6b86b h1:SCE/18RnFsLrjydh/R/s5EVvHoZprqEQUuoxK8q2Pc4= +golang.org/x/exp v0.0.0-20220916125017-b168a2c6b86b/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -844,6 +877,9 @@ golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= +golang.org/x/mod v0.6.0-dev.0.20211013180041-c96bc1413d57/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= +golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -892,14 +928,16 @@ golang.org/x/net v0.0.0-20210423184538-5f58ad60dda6/go.mod h1:OJAsFXCWl8Ukc7SiCT golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.0.0-20220812174116-3211cb980234 h1:RDqmgfe7SvlMWoqC3xwQ2blLO3fcWcxMa3eBLRdRW7E= golang.org/x/net v0.0.0-20220812174116-3211cb980234/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.0.0-20220920183852-bf014ff85ad5 h1:KafLifaRFIuSJ5C+7CyFJOF9haxKNC1CEIDk8GX6X0k= +golang.org/x/net v0.0.0-20220920183852-bf014ff85ad5/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -986,6 +1024,7 @@ golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1066,6 +1105,8 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.8-0.20211029000441-d6a9af8af023/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= +golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1166,6 +1207,7 @@ gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLks gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= diff --git a/testplans/bitswap/main.go b/testplans/bitswap/main.go index 95eb47f03..a0a77f741 100644 --- a/testplans/bitswap/main.go +++ b/testplans/bitswap/main.go @@ -14,7 +14,7 @@ import ( bitswap "github.com/ipfs/go-bitswap" bsnet "github.com/ipfs/go-bitswap/network" - block "github.com/ipfs/go-block-format" + block "github.com/ipfs/go-libipfs/blocks" "github.com/ipfs/go-cid" datastore "github.com/ipfs/go-datastore" blockstore "github.com/ipfs/go-ipfs-blockstore" diff --git a/thirdparty/verifbs/verifbs.go b/thirdparty/verifbs/verifbs.go index 7be5348a8..ca2f5d839 100644 --- a/thirdparty/verifbs/verifbs.go +++ b/thirdparty/verifbs/verifbs.go @@ -3,9 +3,9 @@ package verifbs import ( "context" - blocks "github.com/ipfs/go-block-format" cid "github.com/ipfs/go-cid" bstore "github.com/ipfs/go-ipfs-blockstore" + blocks "github.com/ipfs/go-libipfs/blocks" "github.com/ipfs/go-verifcid" ) From a567ac52bae16bf16e428a598f14864c1c45bdee Mon Sep 17 00:00:00 2001 From: galargh Date: Thu, 26 Jan 2023 17:00:45 +0100 Subject: [PATCH 0431/1212] chore: hide release instructions which can be skipped --- docs/RELEASE_ISSUE_TEMPLATE.md | 53 ++++++++++++++++++++++------------ 1 file changed, 35 insertions(+), 18 deletions(-) diff --git a/docs/RELEASE_ISSUE_TEMPLATE.md b/docs/RELEASE_ISSUE_TEMPLATE.md index 013ee7c17..4f26d02ea 100644 --- a/docs/RELEASE_ISSUE_TEMPLATE.md +++ b/docs/RELEASE_ISSUE_TEMPLATE.md @@ -77,10 +77,11 @@ This section covers tasks to be done ahead of the release. - [example](https://github.com/ipfs/distributions/pull/756) - [ ] [ipfs/ipfs-docs](https://github.com/ipfs/ipfs-docs) - [example](https://github.com/ipfs/ipfs-docs/pull/1298) -- [ ] Notify the bifrost team about the upcoming release using `kuboreleaser release --version vX.Y.Z(-RCN) notify-bifrost --date YYYY-MM-DD` +- [ ] Notify the bifrost team about the upcoming release
using `kuboreleaser release --version vX.Y.Z(-RCN) notify-bifrost --date YYYY-MM-DD` or ... - [ ] open an issue against [bifrost-infra](https://github.com/protocol/bifrost-infra) - [example](https://github.com/protocol/bifrost-infra/issues/2221) - - [ ] link the issue in the [Meta](#meta) section +
+- [ ] Link the [bifrost-infra](https://github.com/protocol/bifrost-infra) issue in the [Meta](#meta) section - [ ] Verify there is nothing [left for release](-what-s-left-for-release) - [ ] Create a release process improvement PR - [ ] update the [release issue template](docs/RELEASE_ISSUE_TEMPLATE.md) as you go @@ -90,7 +91,7 @@ This section covers tasks to be done ahead of the release. This section covers tasks to be done during each release. -- [ ] Cut the release branch and update version numbers accordingly using `kuboreleaser release --version vX.Y.Z(-RCN) cut-branch` +- [ ] Cut the release branch and update version numbers accordingly
using `kuboreleaser release --version vX.Y.Z(-RCN) cut-branch` or ... - [ ] create a new branch `release-vX.Y.Z` - use `master` as base if `Z == 0` - use `release` as base if `Z > 0` @@ -101,21 +102,25 @@ This section covers tasks to be done during each release. - [ ] create a draft PR from `release-vX.Y` to `release` - [example](https://github.com/ipfs/kubo/pull/9306) - [ ] verify all CI checks on the PR from `release-vX.Y` to `release` are passing +
- [ ] Cherry-pick commits from `master` to the `release-vX.Y.Z` using `git cherry-pick -x ` - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Add full changelog and contributors to the [changelog](docs/changelogs/vX.Y.md) + - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Paste the stdout of `./bin/mkreleaselog` at the end of the [changelog](docs/changelogs/vX.Y.md) + - do **NOT** copy the stderr - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Merge the PR from `release-vX.Y` to `release` using the `Create a merge commit` - do **NOT** use `Squash and merge` nor `Rebase and merge` because we need to be able to sign the merge commit - do **NOT** delete the `release-vX.Y` branch -- [ ] Create the release tag using `kuboreleaser release --version vX.Y.Z(-RCN) tag` +- [ ] Create the release tag
using `kuboreleaser release --version vX.Y.Z(-RCN) tag` or ... - This is a dangerous operation! Go and Docker publishing are difficult to reverse! Have the release reviewer verify all the commands marked with ⚠️! - - [ ] ![](https://img.shields.io/badge/only-RC-blue?style=flat-square) ⚠️ tag the HEAD commit using `git tag -s vX.Y.Z(-RCN) -m 'Prerelease X.Y.Z(-RCN)'` - - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ⚠️ tag the HEAD commit of the `release` branch using `git tag -s vX.Y.Z(-RCN) -m 'Release X.Y.Z(-RCN)'` + - [ ] ⚠️ ![](https://img.shields.io/badge/only-RC-blue?style=flat-square) tag the HEAD commit using `git tag -s vX.Y.Z(-RCN) -m 'Prerelease X.Y.Z(-RCN)'` + - [ ] ⚠️ ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) tag the HEAD commit of the `release` branch using `git tag -s vX.Y.Z(-RCN) -m 'Release X.Y.Z(-RCN)'` - [ ] ⚠️ verify the tag is signed and tied to the correct commit using `git show vX.Y.Z(-RCN)` - [ ] ⚠️ push the tag to GitHub using `git push origin vX.Y.Z(-RCN)` - do **NOT** use `git push --tags` because it pushes all your local tags +
- [ ] Wait for [Publish docker image](https://github.com/ipfs/kubo/actions/workflows/docker-image.yml) workflow run initiated by the tag push to finish - [ ] verify the image is available on [Docker Hub](https://hub.docker.com/r/ipfs/kubo/tags) -- [ ] Publish the release to [ipfs.tech](https://dist.ipfs.tech) using `kuboreleaser release --version vX.Y.Z(-RCN) publish-to-distributions` +- [ ] Publish the release to [ipfs.tech](https://dist.ipfs.tech)
using `kuboreleaser release --version vX.Y.Z(-RCN) publish-to-distributions` or ... - [ ] check out [ipfs/distributions](https://github.com/ipfs/distributions) - [ ] run `./dist.sh add-version kubo vX.Y.Z(-RCN)` to add the new version to the `versions` file - [usage](https://github.com/ipfs/distributions#usage) @@ -123,11 +128,13 @@ This section covers tasks to be done during each release. - [example](https://github.com/ipfs/distributions/pull/760) - [ ] wait for the [CI](https://github.com/ipfs/distributions/actions/workflows/main.yml) workflow run initiated by the merge to master to finish - [ ] verify the release is available on [dist.ipfs.io](https://dist.ipfs.io/#kubo) -- [ ] Publish the release to [NPM](https://www.npmjs.com/package/go-ipfs?activeTab=versions) using `kuboreleaser release --version vX.Y.Z(-RCN) publish-to-npm` +
+- [ ] Publish the release to [NPM](https://www.npmjs.com/package/go-ipfs?activeTab=versions)
using `kuboreleaser release --version vX.Y.Z(-RCN) publish-to-npm` or ... - [ ] run the [Release to npm](https://github.com/ipfs/npm-go-ipfs/actions/workflows/main.yml) workflow - [ ] check [Release to npm](https://github.com/ipfs/npm-go-ipfs/actions/workflows/main.yml) workflow run logs to verify it discovered the new release - [ ] verify the release is available on [NPM](https://www.npmjs.com/package/go-ipfs?activeTab=versions) -- [ ] Publish the release to [GitHub](https://github.com/ipfs/kubo/releases) using `kuboreleaser release --version vX.Y.Z(-RCN) publish-to-github` +
+- [ ] Publish the release to [GitHub](https://github.com/ipfs/kubo/releases)
using `kuboreleaser release --version vX.Y.Z(-RCN) publish-to-github` or ... - [ ] create a new release on [GitHub](https://docs.github.com/en/repositories/releasing-projects-on-github/managing-releases-in-a-repository#creating-a-release) - [RC example](https://github.com/ipfs/kubo/releases/tag/v0.17.0-rc1) - [FINAL example](https://github.com/ipfs/kubo/releases/tag/v0.17.0) @@ -140,9 +147,11 @@ This section covers tasks to be done during each release. - [ ] run the [sync-release-assets](https://github.com/ipfs/kubo/actions/workflows/sync-release-assets.yml) workflow - [ ] wait for the [sync-release-assets](https://github.com/ipfs/kubo/actions/workflows/sync-release-assets.yml) workflow run to finish - [ ] verify the release assets are present in the [GitHub release](https://github.com/ipfs/kubo/releases/tag/vX.Y.Z(-RCN)) -- [ ] Notify the bifrost team about the release using `kuboreleaser release --version vX.Y.Z(-RCN) notify-bifrost --date YYYY-MM-DD` +
+- [ ] Notify the bifrost team about the release
using `kuboreleaser release --version vX.Y.Z(-RCN) notify-bifrost --date YYYY-MM-DD` or ... - [ ] create an issue comment on the issue in the [bifrost-infra](https://github/com/protocol/bifrost-infra) -- [ ] Promote the release using `kuboreleaser release --version vX.Y.Z(-RCN) promote` +
+- [ ] Promote the release
using `kuboreleaser release --version vX.Y.Z(-RCN) promote` or ... - [ ] create an [IPFS Discourse](https://discuss.ipfs.tech) topic - [prerelease example](https://discuss.ipfs.tech/t/kubo-v0-16-0-rc1-release-candidate-is-out/15248) - [release example](https://discuss.ipfs.tech/t/kubo-v0-16-0-release-is-out/15249) @@ -164,35 +173,43 @@ This section covers tasks to be done during each release. - [example](https://filecoinproject.slack.com/archives/C018EJ8LWH1/p1664885305374900) - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) post the link to the [GitHub Release](https://github.com/ipfs/kubo/releases/tag/vX.Y.Z(-RCN)) to [Reddit](https://reddit.com/r/ipfs) - [example](https://www.reddit.com/r/ipfs/comments/9x0q0k/kubo_v0160_release_is_out/) +
- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Add the link to the [IPFS Discourse](https://discuss.ipfs.tech) topic to the [GitHub Release](https://github.com/ipfs/kubo/releases/tag/vX.Y.Z(-RCN)) description - [example](https://github.com/ipfs/kubo/releases/tag/v0.17.0) -- [ ] Test the new version with `ipfs-companion` using `kuboreleaser release --version vX.Y.Z(-RCN) test-ipfs-companion` +- [ ] Test the new version with `ipfs-companion`
using `kuboreleaser release --version vX.Y.Z(-RCN) test-ipfs-companion` or ... - [ ] run the [e2e](https://github.com/ipfs/ipfs-companion/actions/workflows/e2e.yml) - use `vX.Y.Z(-RCN)` as the Kubo image version - [ ] wait for the [e2e](https://github.com/ipfs/ipfs-companion/actions/workflows/e2e.yml) workflow run to finish -- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Update Kubo in [interop](https://github.com/ipfs/interop) using `kuboreleaser release --version vX.Y.Z(-RCN) update-interop` +
+- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Update Kubo in [interop](https://github.com/ipfs/interop)
using `kuboreleaser release --version vX.Y.Z(-RCN) update-interop` or ... - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) check out [ipfs/interop](https://github.com/ipfs/interop) - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) run `npm install` - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) create a PR which updates `package.json` and `package-lock.json` - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) merge the PR -- [ ] Update Kubo in [ipfs-desktop](https://github.com/ipfs/ipfs-desktop) using `kuboreleaser release --version vX.Y.Z(-RCN) update-ipfs-desktop` +
+- [ ] Update Kubo in [ipfs-desktop](https://github.com/ipfs/ipfs-desktop)
using `kuboreleaser release --version vX.Y.Z(-RCN) update-ipfs-desktop` or ... - [ ] check out [ipfs/ipfs-desktop](https://github.com/ipfs/ipfs-desktop) - [ ] run `npm install` - [ ] create a PR which updates `package.json` and `package-lock.json` - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) merge the PR -- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Update Kubo docs using `kuboreleaser release --version vX.Y.Z(-RCN) update-ipfs-docs` +
+- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Update Kubo docs
using `kuboreleaser release --version vX.Y.Z(-RCN) update-ipfs-docs` or ... - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) run the [update-on-new-ipfs-tag.yml](https://github.com/ipfs/ipfs-docs/actions/workflows/update-on-new-ipfs-tag.yml) workflow - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) merge the PR created by the [update-on-new-ipfs-tag.yml](https://github.com/ipfs/ipfs-docs/actions/workflows/update-on-new-ipfs-tag.yml) workflow run -- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Create a blog entry on [ipfs.tech](https://blog.ipfs.tech) `kuboreleaser release --version vX.Y.Z(-RCN) update-ipfs-blog --date YYYY-MM-DD` +
+- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Create a blog entry on [ipfs.tech](https://blog.ipfs.tech)
using `kuboreleaser release --version vX.Y.Z(-RCN) update-ipfs-blog --date YYYY-MM-DD` or ... - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) create a PR which adds a release note for the new Kubo version - [example](https://github.com/ipfs/ipfs-blog/pull/529) - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) merge the PR - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) verify the blog entry was published +
- [ ] Keep checking the [metrics](https://protocollabs.grafana.net/d/8zlhkKTZk/gateway-slis-precomputed?orgId=1) until the release issue is closed - [release notes](https://www.notion.so/pl-strflt/Kubo-Gateway-Release-Notes-6e0efff28ee540be9ccb8f2b85104c42) - post in the [#bifrost](https://filecoinproject.slack.com/archives/C018EJ8LWH1) channel in FIL Slack if there is a problem -- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Merge the [release](https://github.com/ipfs/kubo/tree/release) back into [master](https://github.com/ipfs/kubo/tree/master) using `kuboreleaser release --version vX.Y.Z(-RCN) merge-branch` - - ignore the changes to [version.go](version.go) (keep the `-dev` version) +- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Merge the [release](https://github.com/ipfs/kubo/tree/release) branch back into [master](https://github.com/ipfs/kubo/tree/master), ignoring the changes to [version.go](version.go) (keep the `-dev`) version,
using `kuboreleaser release --version vX.Y.Z(-RCN) merge-branch` or ... + - [ ] create a new branch `merge-release-vX.Y.Z` from `release` + - [ ] create and merge a PR from `merge-release-vX.Y.Z` to `master` +
- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) Create the next [changelog](https://github.com/ipfs/kubo/blob/master/docs/changelogs/vX.(Y+1).md) - link to the new changelog in the [CHANGELOG.md](CHANGELOG.md) file - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) Create the next release issue From 50bbaf99c1a61d06999f03c834c0c94b1a03f47f Mon Sep 17 00:00:00 2001 From: galargh Date: Thu, 26 Jan 2023 17:30:14 +0100 Subject: [PATCH 0432/1212] feat: create dependency update PR during release --- docs/RELEASE_ISSUE_TEMPLATE.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/RELEASE_ISSUE_TEMPLATE.md b/docs/RELEASE_ISSUE_TEMPLATE.md index 4f26d02ea..8da4faa3f 100644 --- a/docs/RELEASE_ISSUE_TEMPLATE.md +++ b/docs/RELEASE_ISSUE_TEMPLATE.md @@ -213,6 +213,11 @@ This section covers tasks to be done during each release. - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) Create the next [changelog](https://github.com/ipfs/kubo/blob/master/docs/changelogs/vX.(Y+1).md) - link to the new changelog in the [CHANGELOG.md](CHANGELOG.md) file - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) Create the next release issue +- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) Create a dependency update PR + - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) check out [ipfs/kubo](https://github.com/ipfs/kubo) + - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) run `go get -t -u ./...` + - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) create a PR which updates `go.mod` and `go.sum` + - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) add the PR to the next release milestone - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Close the release issue ## How to contribute? From 0ad00f62b2179b644cf49431ceab443f235a05da Mon Sep 17 00:00:00 2001 From: galargh Date: Thu, 26 Jan 2023 17:35:42 +0100 Subject: [PATCH 0433/1212] chore: remove obsolete release issue template header --- docs/RELEASE_ISSUE_TEMPLATE.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/RELEASE_ISSUE_TEMPLATE.md b/docs/RELEASE_ISSUE_TEMPLATE.md index 8da4faa3f..7671a818e 100644 --- a/docs/RELEASE_ISSUE_TEMPLATE.md +++ b/docs/RELEASE_ISSUE_TEMPLATE.md @@ -1,7 +1,5 @@ -> Release Issue Template. If doing a patch release, see [here](https://github.com/ipfs/kubo/blob/master/docs/PATCH_RELEASE_TEMPLATE.md) - # Items to do upon creating the release issue - [ ] Fill in the Meta section - [ ] Assign the issue to the release owner and reviewer. From 9652f24f6c1dce639444b8bb39caa0a9cd375870 Mon Sep 17 00:00:00 2001 From: Mohsin Zaidi <2236875+smrz2001@users.noreply.github.com> Date: Thu, 26 Jan 2023 18:24:35 -0500 Subject: [PATCH 0434/1212] feat: Pubsub.SeenMessagesStrategy (#9543) * feat: expire messages from the cache based on last seen time * docs: Pubsub.SeenMessagesStrategy Ref. https://github.com/libp2p/go-libp2p-pubsub/pull/513 Co-authored-by: Marcin Rataj --- config/pubsub.go | 27 ++++- core/node/groups.go | 13 ++ docs/changelogs/v0.18.md | 38 ++++++ docs/config.md | 28 ++++- docs/examples/kubo-as-a-library/go.mod | 4 +- docs/examples/kubo-as-a-library/go.sum | 8 +- go.mod | 4 +- go.sum | 8 +- .../integration/pubsub_msg_seen_cache_test.go | 114 ++++++++++++------ 9 files changed, 191 insertions(+), 53 deletions(-) diff --git a/config/pubsub.go b/config/pubsub.go index ba8084300..36f9a9881 100644 --- a/config/pubsub.go +++ b/config/pubsub.go @@ -1,5 +1,24 @@ package config +const ( + // LastSeenMessagesStrategy is a strategy that calculates the TTL countdown + // based on the last time a Pubsub message is seen. This means that if a message + // is received and then seen again within the specified TTL window, it + // won't be emitted until the TTL countdown expires from the last time the + // message was seen. + LastSeenMessagesStrategy = "last-seen" + + // FirstSeenMessagesStrategy is a strategy that calculates the TTL + // countdown based on the first time a Pubsub message is seen. This means that if + // a message is received and then seen again within the specified TTL + // window, it won't be emitted. + FirstSeenMessagesStrategy = "first-seen" + + // DefaultSeenMessagesStrategy is the strategy that is used by default if + // no Pubsub.SeenMessagesStrategy is specified. + DefaultSeenMessagesStrategy = LastSeenMessagesStrategy +) + type PubsubConfig struct { // Router can be either floodsub (legacy) or gossipsub (new and // backwards compatible). @@ -12,7 +31,11 @@ type PubsubConfig struct { // Enable pubsub (--enable-pubsub-experiment) Enabled Flag `json:",omitempty"` - // SeenMessagesTTL configures the duration after which a previously seen - // message ID can be forgotten about. + // SeenMessagesTTL is a value that controls the time window within which + // duplicate messages will be identified and won't be emitted. SeenMessagesTTL *OptionalDuration `json:",omitempty"` + + // SeenMessagesStrategy is a setting that determines how the time-to-live + // (TTL) countdown for deduplicating messages is calculated. + SeenMessagesStrategy *OptionalString `json:",omitempty"` } diff --git a/core/node/groups.go b/core/node/groups.go index aa650ddf5..e640feff1 100644 --- a/core/node/groups.go +++ b/core/node/groups.go @@ -11,6 +11,7 @@ import ( "github.com/ipfs/go-log" "github.com/ipfs/kubo/config" pubsub "github.com/libp2p/go-libp2p-pubsub" + "github.com/libp2p/go-libp2p-pubsub/timecache" "github.com/libp2p/go-libp2p/core/peer" "github.com/ipfs/kubo/core/node/libp2p" @@ -66,6 +67,18 @@ func LibP2P(bcfg *BuildCfg, cfg *config.Config) fx.Option { pubsub.WithSeenMessagesTTL(cfg.Pubsub.SeenMessagesTTL.WithDefault(pubsub.TimeCacheDuration)), ) + var seenMessagesStrategy timecache.Strategy + configSeenMessagesStrategy := cfg.Pubsub.SeenMessagesStrategy.WithDefault(config.DefaultSeenMessagesStrategy) + switch configSeenMessagesStrategy { + case config.LastSeenMessagesStrategy: + seenMessagesStrategy = timecache.Strategy_LastSeen + case config.FirstSeenMessagesStrategy: + seenMessagesStrategy = timecache.Strategy_FirstSeen + default: + return fx.Error(fmt.Errorf("unsupported Pubsub.SeenMessagesStrategy %q", configSeenMessagesStrategy)) + } + pubsubOptions = append(pubsubOptions, pubsub.WithSeenMessagesStrategy(seenMessagesStrategy)) + switch cfg.Pubsub.Router { case "": fallthrough diff --git a/docs/changelogs/v0.18.md b/docs/changelogs/v0.18.md index e51c6d3b5..376658fd9 100644 --- a/docs/changelogs/v0.18.md +++ b/docs/changelogs/v0.18.md @@ -1,5 +1,43 @@ # Kubo changelog v0.18 +## v0.18.1 + +This release includes improvements around Pubsub message deduplication, and more. + + + + +- [Overview](#overview) +- [🔦 Highlights](#-highlights) + - [New default Pubsub.SeenMessagesStrategy](#new-default-pubsubseenmessagesstrategy) +- [📝 Changelog](#-changelog) +- [👨‍👩‍👧‍👦 Contributors](#-contributors) + + + +### 🔦 Highlights + +#### New default `Pubsub.SeenMessagesStrategy` + +A new optional [`Pubsub.SeenMessagesStrategy`](../config.md#pubsubseenmessagesstrategy) configuration option has been added. + +This option allows you to choose between two different strategies for +deduplicating messages: `first-seen` and `last-seen`. + +When unset, the default strategy is `last-seen`, which calculates the +time-to-live (TTL) countdown based on the last time a message is seen. This +means that if a message is received and then seen again within the specified +TTL window based on the last time it was seen, it won't be emitted. + +If you prefer the old behavior, which calculates the TTL countdown based on the +first time a message is seen, you can set `Pubsub.SeenMessagesStrategy` to +`first-seen`. + +### 📝 Changelog + +### 👨‍👩‍👧‍👦 Contributors + + ## v0.18.0 ### Overview diff --git a/docs/config.md b/docs/config.md index da919d844..94d8094af 100644 --- a/docs/config.md +++ b/docs/config.md @@ -100,6 +100,7 @@ config file at runtime. - [`Pubsub.Router`](#pubsubrouter) - [`Pubsub.DisableSigning`](#pubsubdisablesigning) - [`Pubsub.SeenMessagesTTL`](#pubsubseenmessagesttl) + - [`Pubsub.SeenMessagesStrategy`](#pubsubseenmessagesstrategy) - [`Peering`](#peering) - [`Peering.Peers`](#peeringpeers) - [`Reprovider`](#reprovider) @@ -1206,8 +1207,8 @@ Type: `bool` ### `Pubsub.SeenMessagesTTL` -Configures the duration after which a previously seen Pubsub Message ID can be -forgotten about. +Controls the time window within which duplicate messages, identified by Message +ID, will be identified and won't be emitted again. A smaller value for this parameter means that Pubsub messages in the cache will be garbage collected sooner, which can result in a smaller cache. At the same @@ -1223,6 +1224,29 @@ Default: see `TimeCacheDuration` from [go-libp2p-pubsub](https://github.com/libp Type: `optionalDuration` +### `Pubsub.SeenMessagesStrategy` + +Determines how the time-to-live (TTL) countdown for deduplicating Pubsub +messages is calculated. + +The Pubsub seen messages cache is a LRU cache that keeps messages for up to a +specified time duration. After this duration has elapsed, expired messages will +be purged from the cache. + +The `last-seen` cache is a sliding-window cache. Every time a message is seen +again with the SeenMessagesTTL duration, its timestamp slides forward. This +keeps frequently occurring messages cached and prevents them from being +continually propagated, especially because of issues that might increase the +number of duplicate messages in the network. + +The `first-seen` cache will store new messages and purge them after the +SeenMessagesTTL duration, even if they are seen multiple times within this +duration. + +Default: `last-seen` (see [go-libp2p-pubsub](https://github.com/libp2p/go-libp2p-pubsub)) + +Type: `optionalString` + ## `Peering` Configures the peering subsystem. The peering subsystem configures Kubo to diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 309f06aa9..66cc238d6 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -38,6 +38,7 @@ require ( github.com/docker/go-units v0.5.0 // indirect github.com/dustin/go-humanize v1.0.0 // indirect github.com/elastic/gosigar v0.14.2 // indirect + github.com/emirpasic/gods v1.18.1 // indirect github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5 // indirect github.com/flynn/noise v1.0.0 // indirect github.com/francoispqt/gojay v1.2.13 // indirect @@ -122,7 +123,7 @@ require ( github.com/libp2p/go-libp2p-asn-util v0.2.0 // indirect github.com/libp2p/go-libp2p-kad-dht v0.20.0 // indirect github.com/libp2p/go-libp2p-kbucket v0.5.0 // indirect - github.com/libp2p/go-libp2p-pubsub v0.8.2 // indirect + github.com/libp2p/go-libp2p-pubsub v0.8.3 // indirect github.com/libp2p/go-libp2p-pubsub-router v0.6.0 // indirect github.com/libp2p/go-libp2p-record v0.2.0 // indirect github.com/libp2p/go-libp2p-routing-helpers v0.6.0 // indirect @@ -180,7 +181,6 @@ require ( github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f // indirect github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 // indirect - github.com/whyrusleeping/timecache v0.0.0-20160911033111-cfcb2f1abfee // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/otel v1.7.0 // indirect go.opentelemetry.io/otel/exporters/jaeger v1.7.0 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index e194ef92e..073bf7072 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -198,6 +198,8 @@ github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaB github.com/elastic/gosigar v0.12.0/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= github.com/elastic/gosigar v0.14.2 h1:Dg80n8cr90OZ7x+bAax/QjoW/XqTI11RmA79ZwIm9/4= github.com/elastic/gosigar v0.14.2/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= +github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= +github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -774,8 +776,8 @@ 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-pnet v0.2.0/go.mod h1:Qqvq6JH/oMZGwqs3N1Fqhv8NVhrdYcO0BW4wssv21LA= -github.com/libp2p/go-libp2p-pubsub v0.8.2 h1:QLGUmkgKmwEVxVDYGsqc5t9CykOMY2Y21cXQHjR462I= -github.com/libp2p/go-libp2p-pubsub v0.8.2/go.mod h1:e4kT+DYjzPUYGZeWk4I+oxCSYTXizzXii5LDRRhjKSw= +github.com/libp2p/go-libp2p-pubsub v0.8.3 h1:T4+pcfcFm1K2v5oFyk68peSjVroaoM8zFygf6Y5WOww= +github.com/libp2p/go-libp2p-pubsub v0.8.3/go.mod h1:eje970FXxjhtFbVEoiae+VUw24ZoSlk67BsiZPLRzlw= github.com/libp2p/go-libp2p-pubsub-router v0.6.0 h1:D30iKdlqDt5ZmLEYhHELCMRj8b4sFAqrUcshIUvVP/s= github.com/libp2p/go-libp2p-pubsub-router v0.6.0/go.mod h1:FY/q0/RBTKsLA7l4vqC2cbRbOvyDotg8PJQ7j8FDudE= github.com/libp2p/go-libp2p-quic-transport v0.10.0/go.mod h1:RfJbZ8IqXIhxBRm5hqUEJqjiiY8xmEuq3HUDS993MkA= @@ -1285,8 +1287,6 @@ github.com/whyrusleeping/mdns v0.0.0-20180901202407-ef14215e6b30/go.mod h1:j4l84 github.com/whyrusleeping/mdns v0.0.0-20190826153040-b9b60ed33aa9/go.mod h1:j4l84WPFclQPj320J9gp0XwNKBb3U0zt5CBqjPp22G4= github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 h1:E9S12nwJwEOXe2d6gT6qxdvqMnNq+VnSsKPgm2ZZNds= github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7/go.mod h1:X2c0RVCI1eSUFI8eLcY3c0423ykwiUdxLJtkDvruhjI= -github.com/whyrusleeping/timecache v0.0.0-20160911033111-cfcb2f1abfee h1:lYbXeSvJi5zk5GLKVuid9TVjS9a0OmLIDKTfoZBL6Ow= -github.com/whyrusleeping/timecache v0.0.0-20160911033111-cfcb2f1abfee/go.mod h1:m2aV4LZI4Aez7dP5PMyVKEHhUyEJ/RjmPEDOpDvudHg= github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE= github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= diff --git a/go.mod b/go.mod index 273c01510..f0b992f30 100644 --- a/go.mod +++ b/go.mod @@ -74,7 +74,7 @@ require ( github.com/libp2p/go-libp2p-http v0.4.0 github.com/libp2p/go-libp2p-kad-dht v0.20.0 github.com/libp2p/go-libp2p-kbucket v0.5.0 - github.com/libp2p/go-libp2p-pubsub v0.8.2 + github.com/libp2p/go-libp2p-pubsub v0.8.3 github.com/libp2p/go-libp2p-pubsub-router v0.6.0 github.com/libp2p/go-libp2p-record v0.2.0 github.com/libp2p/go-libp2p-routing-helpers v0.6.0 @@ -132,6 +132,7 @@ require ( github.com/dgraph-io/ristretto v0.0.2 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/elastic/gosigar v0.14.2 // indirect + github.com/emirpasic/gods v1.18.1 // indirect github.com/felixge/httpsnoop v1.0.2 // indirect github.com/flynn/noise v1.0.0 // indirect github.com/francoispqt/gojay v1.2.13 // indirect @@ -223,7 +224,6 @@ require ( github.com/whyrusleeping/cbor-gen v0.0.0-20221220214510-0333c149dec0 // indirect github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f // indirect github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect - github.com/whyrusleeping/timecache v0.0.0-20160911033111-cfcb2f1abfee // indirect go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.7.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.7.0 // indirect go.opentelemetry.io/otel/metric v0.30.0 // indirect diff --git a/go.sum b/go.sum index ab1548f37..057b7f21b 100644 --- a/go.sum +++ b/go.sum @@ -206,6 +206,8 @@ github.com/elastic/gosigar v0.14.2 h1:Dg80n8cr90OZ7x+bAax/QjoW/XqTI11RmA79ZwIm9/ github.com/elastic/gosigar v0.14.2/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/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= +github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -808,8 +810,8 @@ 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-pnet v0.2.0/go.mod h1:Qqvq6JH/oMZGwqs3N1Fqhv8NVhrdYcO0BW4wssv21LA= -github.com/libp2p/go-libp2p-pubsub v0.8.2 h1:QLGUmkgKmwEVxVDYGsqc5t9CykOMY2Y21cXQHjR462I= -github.com/libp2p/go-libp2p-pubsub v0.8.2/go.mod h1:e4kT+DYjzPUYGZeWk4I+oxCSYTXizzXii5LDRRhjKSw= +github.com/libp2p/go-libp2p-pubsub v0.8.3 h1:T4+pcfcFm1K2v5oFyk68peSjVroaoM8zFygf6Y5WOww= +github.com/libp2p/go-libp2p-pubsub v0.8.3/go.mod h1:eje970FXxjhtFbVEoiae+VUw24ZoSlk67BsiZPLRzlw= github.com/libp2p/go-libp2p-pubsub-router v0.6.0 h1:D30iKdlqDt5ZmLEYhHELCMRj8b4sFAqrUcshIUvVP/s= github.com/libp2p/go-libp2p-pubsub-router v0.6.0/go.mod h1:FY/q0/RBTKsLA7l4vqC2cbRbOvyDotg8PJQ7j8FDudE= github.com/libp2p/go-libp2p-quic-transport v0.10.0/go.mod h1:RfJbZ8IqXIhxBRm5hqUEJqjiiY8xmEuq3HUDS993MkA= @@ -1344,8 +1346,6 @@ github.com/whyrusleeping/mdns v0.0.0-20180901202407-ef14215e6b30/go.mod h1:j4l84 github.com/whyrusleeping/mdns v0.0.0-20190826153040-b9b60ed33aa9/go.mod h1:j4l84WPFclQPj320J9gp0XwNKBb3U0zt5CBqjPp22G4= github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 h1:E9S12nwJwEOXe2d6gT6qxdvqMnNq+VnSsKPgm2ZZNds= github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7/go.mod h1:X2c0RVCI1eSUFI8eLcY3c0423ykwiUdxLJtkDvruhjI= -github.com/whyrusleeping/timecache v0.0.0-20160911033111-cfcb2f1abfee h1:lYbXeSvJi5zk5GLKVuid9TVjS9a0OmLIDKTfoZBL6Ow= -github.com/whyrusleeping/timecache v0.0.0-20160911033111-cfcb2f1abfee/go.mod h1:m2aV4LZI4Aez7dP5PMyVKEHhUyEJ/RjmPEDOpDvudHg= github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE= github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= diff --git a/test/integration/pubsub_msg_seen_cache_test.go b/test/integration/pubsub_msg_seen_cache_test.go index 394cda5b1..749508089 100644 --- a/test/integration/pubsub_msg_seen_cache_test.go +++ b/test/integration/pubsub_msg_seen_cache_test.go @@ -22,6 +22,7 @@ import ( "github.com/libp2p/go-libp2p-pubsub" "github.com/libp2p/go-libp2p-pubsub/pb" + "github.com/libp2p/go-libp2p-pubsub/timecache" "github.com/libp2p/go-libp2p/core/peer" mock "github.com/ipfs/kubo/core/mock" @@ -76,7 +77,6 @@ func RunMessageSeenCacheTTLTest(t *testing.T, seenMessagesCacheTTL string) error var bootstrapNode, consumerNode, producerNode *core.IpfsNode var bootstrapPeerID, consumerPeerID, producerPeerID peer.ID - sendDupMsg := false mn := mocknet.New() bootstrapNode, err := mockNode(ctx, mn, false, "") // no need for PubSub configuration @@ -98,6 +98,12 @@ func RunMessageSeenCacheTTLTest(t *testing.T, seenMessagesCacheTTL string) error t.Fatal(err) } + // Used for logging the timeline + startTime := time.Time{} + + // Used for overriding the message ID + sendMsgID := "" + // Set up the pubsub message ID generation override for the producer core.RegisterFXOptionFunc(func(info core.FXNodeInfo) ([]fx.Option, error) { var pubsubOptions []pubsub.Option @@ -105,19 +111,23 @@ func RunMessageSeenCacheTTLTest(t *testing.T, seenMessagesCacheTTL string) error pubsubOptions, pubsub.WithSeenMessagesTTL(ttl), pubsub.WithMessageIdFn(func(pmsg *pubsub_pb.Message) string { - now := time.Now().Format(time.StampMilli) + now := time.Now() + if startTime.Second() == 0 { + startTime = now + } + timeElapsed := now.Sub(startTime).Seconds() msg := string(pmsg.Data) - var msgID string from, _ := peer.IDFromBytes(pmsg.From) - if (from == producerPeerID) && sendDupMsg { - msgID = "DupMsg" - t.Logf("sending [%s] with duplicate message ID at [%s]", msg, now) + var msgID string + if from == producerPeerID { + msgID = sendMsgID + t.Logf("sending [%s] with message ID [%s] at T%fs", msg, msgID, timeElapsed) } else { msgID = pubsub.DefaultMsgIdFn(pmsg) - t.Logf("sending [%s] with unique message ID at [%s]", msg, now) } return msgID }), + pubsub.WithSeenMessagesStrategy(timecache.Strategy_LastSeen), ) return append( info.FXOptions, @@ -165,8 +175,8 @@ func RunMessageSeenCacheTTLTest(t *testing.T, seenMessagesCacheTTL string) error t.Fatal(err) } // Utility functions defined inline to include context in closure - now := func() string { - return time.Now().Format(time.StampMilli) + now := func() float64 { + return time.Since(startTime).Seconds() } ctr := 0 msgGen := func() string { @@ -188,57 +198,87 @@ func RunMessageSeenCacheTTLTest(t *testing.T, seenMessagesCacheTTL string) error msg, err := consumerSubscription.Next(rxCtx) if shouldFind { if err != nil { - t.Logf("did not receive [%s] by [%s]", msgTxt, now()) + t.Logf("expected but did not receive [%s] at T%fs", msgTxt, now()) t.Fatal(err) } - t.Logf("received [%s] at [%s]", string(msg.Data()), now()) + t.Logf("received [%s] at T%fs", string(msg.Data()), now()) if !bytes.Equal(msg.Data(), []byte(msgTxt)) { t.Fatalf("consumed data [%s] does not match published data [%s]", string(msg.Data()), msgTxt) } } else { if err == nil { - t.Logf("received [%s] at [%s]", string(msg.Data()), now()) + t.Logf("not expected but received [%s] at T%fs", string(msg.Data()), now()) t.Fail() } - t.Logf("did not receive [%s] by [%s]", msgTxt, now()) + t.Logf("did not receive [%s] at T%fs", msgTxt, now()) } } - // Send message 1 with the message ID we're going to duplicate later - sendDupMsg = true + const MsgID1 = "MsgID1" + const MsgID2 = "MsgID2" + const MsgID3 = "MsgID3" + + // Send message 1 with the message ID we're going to duplicate + sentMsg1 := time.Now() + sendMsgID = MsgID1 msgTxt := produceMessage() - consumeMessage(msgTxt, true) // should find message + // Should find the message because it's new + consumeMessage(msgTxt, true) - // Send message 2 with the same message ID as before - sendDupMsg = true + // Send message 2 with a duplicate message ID + sendMsgID = MsgID1 msgTxt = produceMessage() - consumeMessage(msgTxt, false) // should NOT find message, because it got deduplicated (sent twice within the SeenMessagesTTL window) - - // Wait for seen cache TTL time to let seen cache entries time out - time.Sleep(ttl) + // Should NOT find message because it got deduplicated (sent 2 times within the SeenMessagesTTL window). + consumeMessage(msgTxt, false) // Send message 3 with a new message ID - // - // This extra step is necessary for testing the cache TTL because the PubSub code only garbage collects when a - // message ID was not already present in the cache. This means that message 2's cache entry, even though it has - // technically timed out, will still cause the message to be considered duplicate. When a message with a different - // ID passes through, it will be added to the cache and garbage collection will clean up message 2's entry. This is - // another bug in the pubsub/cache implementation that will be fixed once the code is refactored for this issue: - // https://github.com/libp2p/go-libp2p-pubsub/issues/502 - sendDupMsg = false + sendMsgID = MsgID2 msgTxt = produceMessage() - consumeMessage(msgTxt, true) // should find message + // Should find the message because it's new + consumeMessage(msgTxt, true) - // Send message 4 with the same message ID as before - sendDupMsg = true + // Wait till just before the SeenMessagesTTL window has passed since message 1 was sent + time.Sleep(time.Until(sentMsg1.Add(ttl - 100*time.Millisecond))) + + // Send message 4 with a duplicate message ID + sendMsgID = MsgID1 msgTxt = produceMessage() - consumeMessage(msgTxt, true) // should find message again (time since the last read > SeenMessagesTTL, so it looks like a new message). + // Should NOT find the message because it got deduplicated (sent 3 times within the SeenMessagesTTL window). This + // time, however, the expiration for the message should also get pushed out for a whole SeenMessagesTTL window since + // the default time cache now implements a sliding window algorithm. + consumeMessage(msgTxt, false) - // Send message 5 with a new message ID + // Send message 5 with a duplicate message ID. This will be a second after the last attempt above since NOT finding + // a message takes a second to determine. That would put this attempt at ~1 second after the SeenMessagesTTL window + // starting at message 1 has expired. + sentMsg5 := time.Now() + sendMsgID = MsgID1 + msgTxt = produceMessage() + // Should NOT find the message, because it got deduplicated (sent 2 times since the updated SeenMessagesTTL window + // started). This time again, the expiration should get pushed out for another SeenMessagesTTL window. + consumeMessage(msgTxt, false) + + // Send message 6 with a message ID that hasn't been seen within a SeenMessagesTTL window + sendMsgID = MsgID2 + msgTxt = produceMessage() + // Should find the message since last read > SeenMessagesTTL, so it looks like a new message. + consumeMessage(msgTxt, true) + + // Sleep for a full SeenMessagesTTL window to let cache entries time out + time.Sleep(time.Until(sentMsg5.Add(ttl + 100*time.Millisecond))) + + // Send message 7 with a duplicate message ID + sendMsgID = MsgID1 + msgTxt = produceMessage() + // Should find the message this time since last read > SeenMessagesTTL, so it looks like a new message. + consumeMessage(msgTxt, true) + + // Send message 8 with a brand new message ID // // This step is not strictly necessary, but has been added for good measure. - sendDupMsg = false + sendMsgID = MsgID3 msgTxt = produceMessage() - consumeMessage(msgTxt, true) // should find message + // Should find the message because it's new + consumeMessage(msgTxt, true) return nil } From 132206b573c44164a6571a551cf1b2c3acbcb438 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Mon, 14 Nov 2022 17:18:43 +0100 Subject: [PATCH 0435/1212] feat: add RoutingAPI to CoreAPI This commit was moved from ipfs/interface-go-ipfs-core@177d25ba92ed67ab4916cb13827321c389961de0 This commit was moved from ipfs/boxo@b3ab88834562c689b5eadfed2e08e732fea4392a --- core/coreiface/coreapi.go | 3 +++ core/coreiface/routing.go | 14 ++++++++++++++ 2 files changed, 17 insertions(+) create mode 100644 core/coreiface/routing.go diff --git a/core/coreiface/coreapi.go b/core/coreiface/coreapi.go index 894ffb318..722c00a0f 100644 --- a/core/coreiface/coreapi.go +++ b/core/coreiface/coreapi.go @@ -44,6 +44,9 @@ type CoreAPI interface { // PubSub returns an implementation of PubSub API PubSub() PubSubAPI + // Routing returns an implementation of Routing API + Routing() RoutingAPI + // ResolvePath resolves the path using Unixfs resolver ResolvePath(context.Context, path.Path) (path.Resolved, error) diff --git a/core/coreiface/routing.go b/core/coreiface/routing.go new file mode 100644 index 000000000..a28ceb9e7 --- /dev/null +++ b/core/coreiface/routing.go @@ -0,0 +1,14 @@ +package iface + +import ( + "context" +) + +// RoutingAPI specifies the interface to the routing layer. +type RoutingAPI interface { + // Get retrieves the best value for a given key + Get(context.Context, string) ([]byte, error) + + // Put sets a value for a given key + Put(ctx context.Context, key string, value []byte) error +} From 94e7f79805d08e07bd67eaaa1dad58a4d764226b Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Fri, 27 Jan 2023 02:33:13 +0100 Subject: [PATCH 0436/1212] fix(ipns): honour --ttl flag in 'ipfs name publish' (#9471) * fix: honour --ttl flag in 'ipfs name publish' * docs(cli): ipfs name inspect --help Co-authored-by: Marcin Rataj --- core/commands/commands_test.go | 1 + core/commands/name/name.go | 219 ++++++++++++++++++++++++- core/coreapi/name.go | 17 +- core/corehttp/gateway_test.go | 7 +- docs/examples/kubo-as-a-library/go.mod | 8 +- docs/examples/kubo-as-a-library/go.sum | 11 +- go.mod | 6 +- go.sum | 8 +- test/sharness/t0100-name.sh | 24 +++ 9 files changed, 270 insertions(+), 31 deletions(-) diff --git a/core/commands/commands_test.go b/core/commands/commands_test.go index ec4cc1bb6..8f94e5d64 100644 --- a/core/commands/commands_test.go +++ b/core/commands/commands_test.go @@ -173,6 +173,7 @@ func TestCommands(t *testing.T) { "/multibase/transcode", "/multibase/list", "/name", + "/name/inspect", "/name/publish", "/name/pubsub", "/name/pubsub/cancel", diff --git a/core/commands/name/name.go b/core/commands/name/name.go index d9e3de57f..7999aee3d 100644 --- a/core/commands/name/name.go +++ b/core/commands/name/name.go @@ -1,7 +1,25 @@ package name import ( - "github.com/ipfs/go-ipfs-cmds" + "bytes" + "encoding/json" + "fmt" + "io" + "strings" + "text/tabwriter" + "time" + + "github.com/gogo/protobuf/proto" + cmds "github.com/ipfs/go-ipfs-cmds" + "github.com/ipfs/go-ipns" + ipns_pb "github.com/ipfs/go-ipns/pb" + cmdenv "github.com/ipfs/kubo/core/commands/cmdenv" + "github.com/ipld/go-ipld-prime" + "github.com/ipld/go-ipld-prime/codec/dagcbor" + "github.com/ipld/go-ipld-prime/codec/dagjson" + ic "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/peer" + mbase "github.com/multiformats/go-multibase" ) type IpnsEntry struct { @@ -62,5 +80,204 @@ Resolve the value of a dnslink: "publish": PublishCmd, "resolve": IpnsCmd, "pubsub": IpnsPubsubCmd, + "inspect": IpnsInspectCmd, + }, +} + +type IpnsInspectValidation struct { + Valid bool + Reason string + PublicKey peer.ID +} + +// IpnsInspectEntry contains the deserialized values from an IPNS Entry: +// https://github.com/ipfs/specs/blob/main/ipns/IPNS.md#record-serialization-format +type IpnsInspectEntry struct { + Value string + ValidityType *ipns_pb.IpnsEntry_ValidityType + Validity *time.Time + Sequence uint64 + TTL *uint64 + PublicKey string + SignatureV1 string + SignatureV2 string + Data interface{} +} + +type IpnsInspectResult struct { + Entry IpnsInspectEntry + Validation *IpnsInspectValidation +} + +var IpnsInspectCmd = &cmds.Command{ + Status: cmds.Experimental, + Helptext: cmds.HelpText{ + Tagline: "Inspects an IPNS Record", + ShortDescription: ` +Prints values inside of IPNS Record protobuf and its DAG-CBOR Data field. +Passing --verify will verify signature against provided public key. +`, + LongDescription: ` +Prints values inside of IPNS Record protobuf and its DAG-CBOR Data field. + +The input can be a file or STDIN, the output can be JSON: + + $ ipfs routing get "/ipns/$PEERID" > ipns_record + $ ipfs name inspect --enc=json < ipns_record + +Values in PublicKey, SignatureV1 and SignatureV2 fields are raw bytes encoded +in Multibase. The Data field is DAG-CBOR represented as DAG-JSON. + +Passing --verify will verify signature against provided public key. + +`, + }, + Arguments: []cmds.Argument{ + cmds.FileArg("record", true, false, "The IPNS record payload to be verified.").EnableStdin(), + }, + Options: []cmds.Option{ + cmds.StringOption("verify", "CID of the public IPNS key to validate against."), + }, + Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { + file, err := cmdenv.GetFileArg(req.Files.Entries()) + if err != nil { + return err + } + defer file.Close() + + var b bytes.Buffer + + _, err = io.Copy(&b, file) + if err != nil { + return err + } + + var entry ipns_pb.IpnsEntry + err = proto.Unmarshal(b.Bytes(), &entry) + if err != nil { + return err + } + + encoder, err := mbase.EncoderByName("base64") + if err != nil { + return err + } + + result := &IpnsInspectResult{ + Entry: IpnsInspectEntry{ + Value: string(entry.Value), + ValidityType: entry.ValidityType, + Sequence: *entry.Sequence, + TTL: entry.Ttl, + PublicKey: encoder.Encode(entry.PubKey), + SignatureV1: encoder.Encode(entry.SignatureV1), + SignatureV2: encoder.Encode(entry.SignatureV2), + Data: nil, + }, + } + + if len(entry.Data) != 0 { + // This is hacky. The variable node (datamodel.Node) doesn't directly marshal + // to JSON. Therefore, we need to first decode from DAG-CBOR, then encode in + // DAG-JSON and finally unmarshal it from JSON. Since DAG-JSON is a subset + // of JSON, that should work. Then, we can store the final value in the + // result.Entry.Data for further inspection. + node, err := ipld.Decode(entry.Data, dagcbor.Decode) + if err != nil { + return err + } + + var buf bytes.Buffer + err = dagjson.Encode(node, &buf) + if err != nil { + return err + } + + err = json.Unmarshal(buf.Bytes(), &result.Entry.Data) + if err != nil { + return err + } + } + + validity, err := ipns.GetEOL(&entry) + if err == nil { + result.Entry.Validity = &validity + } + + verify, ok := req.Options["verify"].(string) + if ok { + key := strings.TrimPrefix(verify, "/ipns/") + id, err := peer.Decode(key) + if err != nil { + return err + } + + result.Validation = &IpnsInspectValidation{ + PublicKey: id, + } + + pub, err := id.ExtractPublicKey() + if err != nil { + // Make sure it works with all those RSA that cannot be embedded into the + // Peer ID. + if len(entry.PubKey) > 0 { + pub, err = ic.UnmarshalPublicKey(entry.PubKey) + } + } + if err != nil { + return err + } + + err = ipns.Validate(pub, &entry) + if err == nil { + result.Validation.Valid = true + } else { + result.Validation.Reason = err.Error() + } + } + + return cmds.EmitOnce(res, result) + }, + Type: IpnsInspectResult{}, + Encoders: cmds.EncoderMap{ + cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *IpnsInspectResult) error { + tw := tabwriter.NewWriter(w, 0, 0, 1, ' ', 0) + defer tw.Flush() + + fmt.Fprintf(tw, "Value:\t%q\n", string(out.Entry.Value)) + fmt.Fprintf(tw, "Validity Type:\t%q\n", out.Entry.ValidityType) + if out.Entry.Validity != nil { + fmt.Fprintf(tw, "Validity:\t%s\n", out.Entry.Validity.Format(time.RFC3339Nano)) + } + fmt.Fprintf(tw, "Sequence:\t%d\n", out.Entry.Sequence) + if out.Entry.TTL != nil { + fmt.Fprintf(tw, "TTL:\t%d\n", *out.Entry.TTL) + } + fmt.Fprintf(tw, "PublicKey:\t%q\n", out.Entry.PublicKey) + fmt.Fprintf(tw, "Signature V1:\t%q\n", out.Entry.SignatureV1) + fmt.Fprintf(tw, "Signature V2:\t%q\n", out.Entry.SignatureV2) + + data, err := json.Marshal(out.Entry.Data) + if err != nil { + return err + } + fmt.Fprintf(tw, "Data:\t%s\n", string(data)) + + if out.Validation == nil { + tw.Flush() + fmt.Fprintf(w, "\nThis record was not validated.\n") + } else { + tw.Flush() + fmt.Fprintf(w, "\nValidation results:\n") + + fmt.Fprintf(tw, "\tValid:\t%v\n", out.Validation.Valid) + if out.Validation.Reason != "" { + fmt.Fprintf(tw, "\tReason:\t%s\n", out.Validation.Reason) + } + fmt.Fprintf(tw, "\tPublicKey:\t%s\n", out.Validation.PublicKey) + } + + return nil + }), }, } diff --git a/core/coreapi/name.go b/core/coreapi/name.go index 69dc1137b..87af34af4 100644 --- a/core/coreapi/name.go +++ b/core/coreapi/name.go @@ -15,6 +15,7 @@ import ( ipath "github.com/ipfs/go-path" coreiface "github.com/ipfs/interface-go-ipfs-core" caopts "github.com/ipfs/interface-go-ipfs-core/options" + nsopts "github.com/ipfs/interface-go-ipfs-core/options/namesys" path "github.com/ipfs/interface-go-ipfs-core/path" ci "github.com/libp2p/go-libp2p/core/crypto" peer "github.com/libp2p/go-libp2p/core/peer" @@ -37,8 +38,6 @@ func (e *ipnsEntry) Value() path.Path { return e.value } -type requestContextKey string - // Publish announces new IPNS name and returns the new IPNS entry. func (api *NameAPI) Publish(ctx context.Context, p path.Path, opts ...caopts.NamePublishOption) (coreiface.IpnsEntry, error) { ctx, span := tracing.Span(ctx, "CoreAPI.NameAPI", "Publish", trace.WithAttributes(attribute.String("path", p.String()))) @@ -76,13 +75,17 @@ func (api *NameAPI) Publish(ctx context.Context, p path.Path, opts ...caopts.Nam return nil, err } - if options.TTL != nil { - // nolint: staticcheck // non-backward compatible change - ctx = context.WithValue(ctx, requestContextKey("ipns-publish-ttl"), *options.TTL) + eol := time.Now().Add(options.ValidTime) + + publishOptions := []nsopts.PublishOption{ + nsopts.PublishWithEOL(eol), } - eol := time.Now().Add(options.ValidTime) - err = api.namesys.PublishWithEOL(ctx, k, pth, eol) + if options.TTL != nil { + publishOptions = append(publishOptions, nsopts.PublishWithTTL(*options.TTL)) + } + + err = api.namesys.Publish(ctx, k, pth, publishOptions...) if err != nil { return nil, err } diff --git a/core/corehttp/gateway_test.go b/core/corehttp/gateway_test.go index 74723579d..877ac9739 100644 --- a/core/corehttp/gateway_test.go +++ b/core/corehttp/gateway_test.go @@ -9,7 +9,6 @@ import ( "regexp" "strings" "testing" - "time" namesys "github.com/ipfs/go-namesys" version "github.com/ipfs/kubo" @@ -68,11 +67,7 @@ func (m mockNamesys) ResolveAsync(ctx context.Context, name string, opts ...nsop return out } -func (m mockNamesys) Publish(ctx context.Context, name ci.PrivKey, value path.Path) error { - return errors.New("not implemented for mockNamesys") -} - -func (m mockNamesys) PublishWithEOL(ctx context.Context, name ci.PrivKey, value path.Path, _ time.Time) error { +func (m mockNamesys) Publish(ctx context.Context, name ci.PrivKey, value path.Path, opts ...nsopts.PublishOption) error { return errors.New("not implemented for mockNamesys") } diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 66cc238d6..29b99699e 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -8,8 +8,8 @@ replace github.com/ipfs/kubo => ./../../.. require ( github.com/ipfs/go-libipfs v0.3.0 - github.com/ipfs/interface-go-ipfs-core v0.8.2 - github.com/ipfs/kubo v0.14.0-rc1 + github.com/ipfs/interface-go-ipfs-core v0.9.0 + github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.24.2 github.com/multiformats/go-multiaddr v0.8.0 ) @@ -101,7 +101,7 @@ require ( github.com/ipfs/go-merkledag v0.9.0 // indirect github.com/ipfs/go-metrics-interface v0.0.1 // indirect github.com/ipfs/go-mfs v0.2.1 // indirect - github.com/ipfs/go-namesys v0.6.0 // indirect + github.com/ipfs/go-namesys v0.7.0 // indirect github.com/ipfs/go-path v0.3.0 // indirect github.com/ipfs/go-peertaskqueue v0.8.0 // indirect github.com/ipfs/go-unixfs v0.4.2 // indirect @@ -209,7 +209,7 @@ require ( golang.org/x/tools v0.3.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1 // indirect - google.golang.org/grpc v1.47.0 // indirect + google.golang.org/grpc v1.46.0 // indirect google.golang.org/protobuf v1.28.1 // indirect gopkg.in/square/go-jose.v2 v2.5.1 // indirect lukechampine.com/blake3 v1.1.7 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 073bf7072..75135d8be 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -575,8 +575,8 @@ github.com/ipfs/go-metrics-interface v0.0.1 h1:j+cpbjYvu4R8zbleSs36gvB7jR+wsL2fG github.com/ipfs/go-metrics-interface v0.0.1/go.mod h1:6s6euYU4zowdslK0GKHmqaIZ3j/b/tL7HTWtJ4VPgWY= github.com/ipfs/go-mfs v0.2.1 h1:5jz8+ukAg/z6jTkollzxGzhkl3yxm022Za9f2nL5ab8= github.com/ipfs/go-mfs v0.2.1/go.mod h1:Woj80iuw4ajDnIP6+seRaoHpPsc9hmL0pk/nDNDWP88= -github.com/ipfs/go-namesys v0.6.0 h1:w4+Wq9bCILnuZRT1RBBdzZQFqtJeDG1duzN8mIDnHZ0= -github.com/ipfs/go-namesys v0.6.0/go.mod h1:0L+3CHBgHxr08Cg+chVo9Ew285PGQfToThjll4g0/d4= +github.com/ipfs/go-namesys v0.7.0 h1:xqosk71GIVRkFDtF2UNRcXn4LdNeo7tzuy8feHD6NbU= +github.com/ipfs/go-namesys v0.7.0/go.mod h1:KYSZBVZG3VJC34EfqqJPG7T48aWgxseoMPAPA5gLyyQ= github.com/ipfs/go-path v0.2.1/go.mod h1:NOScsVgxfC/eIw4nz6OiGwK42PjaSJ4Y/ZFPn1Xe07I= github.com/ipfs/go-path v0.3.0 h1:tkjga3MtpXyM5v+3EbRvOHEoo+frwi4oumw5K+KYWyA= github.com/ipfs/go-path v0.3.0/go.mod h1:NOScsVgxfC/eIw4nz6OiGwK42PjaSJ4Y/ZFPn1Xe07I= @@ -594,8 +594,8 @@ github.com/ipfs/go-unixfsnode v1.5.1/go.mod h1:ed79DaG9IEuZITJVQn4U6MZDftv6I3ygU github.com/ipfs/go-verifcid v0.0.1/go.mod h1:5Hrva5KBeIog4A+UpqlaIU+DEstipcJYQQZc0g37pY0= github.com/ipfs/go-verifcid v0.0.2 h1:XPnUv0XmdH+ZIhLGKg6U2vaPaRDXb9urMyNVCE7uvTs= github.com/ipfs/go-verifcid v0.0.2/go.mod h1:40cD9x1y4OWnFXbLNJYRe7MpNvWlMn3LZAG5Wb4xnPU= -github.com/ipfs/interface-go-ipfs-core v0.8.2 h1:WDeCBnE4MENVOXbtfwwdAPJ2nBBS8PTmhZWWpm24HRM= -github.com/ipfs/interface-go-ipfs-core v0.8.2/go.mod h1:F3EcmDy53GFkF0H3iEJpfJC320fZ/4G60eftnItrrJ0= +github.com/ipfs/interface-go-ipfs-core v0.9.0 h1:+RCouVtSU/SldgkqWufjIu1smmGaSyKgUIfbYwLukgI= +github.com/ipfs/interface-go-ipfs-core v0.9.0/go.mod h1:F3EcmDy53GFkF0H3iEJpfJC320fZ/4G60eftnItrrJ0= github.com/ipld/edelweiss v0.2.0 h1:KfAZBP8eeJtrLxLhi7r3N0cBCo7JmwSRhOJp3WSpNjk= github.com/ipld/edelweiss v0.2.0/go.mod h1:FJAzJRCep4iI8FOFlRriN9n0b7OuX3T/S9++NpBDmA4= github.com/ipld/go-car v0.4.0 h1:U6W7F1aKF/OJMHovnOVdst2cpQE5GhmHibQkAixgNcQ= @@ -1779,9 +1779,8 @@ google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAG google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k= google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= +google.golang.org/grpc v1.46.0 h1:oCjezcn6g6A75TGoKYBPgKmVBLexhYLM6MebdrPApP8= google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.47.0 h1:9n77onPX5F3qfFCqjy9dhn8PbNQsIKeVU04J9G7umt8= -google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/go.mod b/go.mod index f0b992f30..fbc56cc84 100644 --- a/go.mod +++ b/go.mod @@ -15,6 +15,7 @@ require ( github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5 github.com/fsnotify/fsnotify v1.6.0 github.com/gabriel-vasile/mimetype v1.4.1 + github.com/gogo/protobuf v1.3.2 github.com/google/uuid v1.3.0 github.com/hashicorp/go-multierror v1.1.1 github.com/ipfs/go-bitswap v0.11.0 @@ -55,13 +56,13 @@ require ( github.com/ipfs/go-metrics-interface v0.0.1 github.com/ipfs/go-metrics-prometheus v0.0.2 github.com/ipfs/go-mfs v0.2.1 - github.com/ipfs/go-namesys v0.6.0 + github.com/ipfs/go-namesys v0.7.0 github.com/ipfs/go-path v0.3.0 github.com/ipfs/go-pinning-service-http-client v0.1.2 github.com/ipfs/go-unixfs v0.4.2 github.com/ipfs/go-unixfsnode v1.5.1 github.com/ipfs/go-verifcid v0.0.2 - github.com/ipfs/interface-go-ipfs-core v0.8.2 + github.com/ipfs/interface-go-ipfs-core v0.9.0 github.com/ipld/go-car v0.4.0 github.com/ipld/go-car/v2 v2.5.1 github.com/ipld/go-codec-dagpb v1.5.0 @@ -142,7 +143,6 @@ require ( github.com/go-logr/stdr v1.2.2 // indirect github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect github.com/godbus/dbus/v5 v5.1.0 // indirect - github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/mock v1.6.0 // indirect github.com/golang/protobuf v1.5.2 // indirect diff --git a/go.sum b/go.sum index 057b7f21b..27674871f 100644 --- a/go.sum +++ b/go.sum @@ -599,8 +599,8 @@ github.com/ipfs/go-metrics-prometheus v0.0.2 h1:9i2iljLg12S78OhC6UAiXi176xvQGiZa github.com/ipfs/go-metrics-prometheus v0.0.2/go.mod h1:ELLU99AQQNi+zX6GCGm2lAgnzdSH3u5UVlCdqSXnEks= github.com/ipfs/go-mfs v0.2.1 h1:5jz8+ukAg/z6jTkollzxGzhkl3yxm022Za9f2nL5ab8= github.com/ipfs/go-mfs v0.2.1/go.mod h1:Woj80iuw4ajDnIP6+seRaoHpPsc9hmL0pk/nDNDWP88= -github.com/ipfs/go-namesys v0.6.0 h1:w4+Wq9bCILnuZRT1RBBdzZQFqtJeDG1duzN8mIDnHZ0= -github.com/ipfs/go-namesys v0.6.0/go.mod h1:0L+3CHBgHxr08Cg+chVo9Ew285PGQfToThjll4g0/d4= +github.com/ipfs/go-namesys v0.7.0 h1:xqosk71GIVRkFDtF2UNRcXn4LdNeo7tzuy8feHD6NbU= +github.com/ipfs/go-namesys v0.7.0/go.mod h1:KYSZBVZG3VJC34EfqqJPG7T48aWgxseoMPAPA5gLyyQ= github.com/ipfs/go-path v0.2.1/go.mod h1:NOScsVgxfC/eIw4nz6OiGwK42PjaSJ4Y/ZFPn1Xe07I= github.com/ipfs/go-path v0.3.0 h1:tkjga3MtpXyM5v+3EbRvOHEoo+frwi4oumw5K+KYWyA= github.com/ipfs/go-path v0.3.0/go.mod h1:NOScsVgxfC/eIw4nz6OiGwK42PjaSJ4Y/ZFPn1Xe07I= @@ -620,8 +620,8 @@ github.com/ipfs/go-unixfsnode v1.5.1/go.mod h1:ed79DaG9IEuZITJVQn4U6MZDftv6I3ygU github.com/ipfs/go-verifcid v0.0.1/go.mod h1:5Hrva5KBeIog4A+UpqlaIU+DEstipcJYQQZc0g37pY0= github.com/ipfs/go-verifcid v0.0.2 h1:XPnUv0XmdH+ZIhLGKg6U2vaPaRDXb9urMyNVCE7uvTs= github.com/ipfs/go-verifcid v0.0.2/go.mod h1:40cD9x1y4OWnFXbLNJYRe7MpNvWlMn3LZAG5Wb4xnPU= -github.com/ipfs/interface-go-ipfs-core v0.8.2 h1:WDeCBnE4MENVOXbtfwwdAPJ2nBBS8PTmhZWWpm24HRM= -github.com/ipfs/interface-go-ipfs-core v0.8.2/go.mod h1:F3EcmDy53GFkF0H3iEJpfJC320fZ/4G60eftnItrrJ0= +github.com/ipfs/interface-go-ipfs-core v0.9.0 h1:+RCouVtSU/SldgkqWufjIu1smmGaSyKgUIfbYwLukgI= +github.com/ipfs/interface-go-ipfs-core v0.9.0/go.mod h1:F3EcmDy53GFkF0H3iEJpfJC320fZ/4G60eftnItrrJ0= github.com/ipld/edelweiss v0.2.0 h1:KfAZBP8eeJtrLxLhi7r3N0cBCo7JmwSRhOJp3WSpNjk= github.com/ipld/edelweiss v0.2.0/go.mod h1:FJAzJRCep4iI8FOFlRriN9n0b7OuX3T/S9++NpBDmA4= github.com/ipld/go-car v0.4.0 h1:U6W7F1aKF/OJMHovnOVdst2cpQE5GhmHibQkAixgNcQ= diff --git a/test/sharness/t0100-name.sh b/test/sharness/t0100-name.sh index 934cc0127..44c2afb2d 100755 --- a/test/sharness/t0100-name.sh +++ b/test/sharness/t0100-name.sh @@ -225,6 +225,30 @@ test_name_with_self() { grep "argument \"ipfs-path\" is required" curl_out ' + # Test Publishing with TTL and Inspecting Records + test_expect_success "'ipfs name publish --ttl=30m' succeeds" ' + ipfs name publish --ttl=30m --allow-offline "/ipfs/$HASH_WELCOME_DOCS" + ' + + test_expect_success "retrieve IPNS key for further inspection" ' + ipfs routing get "/ipns/$PEERID" > ipns_record + ' + + test_expect_success "'ipfs name inspect' has correct TTL (30m)" ' + ipfs name inspect < ipns_record > verify_output && + test_should_contain "This record was not validated." verify_output && + test_should_contain "$HASH_WELCOME_DOCS" verify_output && + test_should_contain "1800000000000" verify_output + ' + + test_expect_success "'ipfs name inspect --verify' has '.Validation.Validity' set to 'true' with correct Peer ID" ' + ipfs name inspect --verify $PEERID --enc json < ipns_record | jq -e ".Validation.Valid == true and .Entry.TTL == .Entry.Data.TTL" + ' + + test_expect_success "'ipfs name inspect --verify' has '.Validation.Validity' set to 'false' with incorrect Peer ID" ' + ipfs name inspect --verify 12D3KooWRirYjmmQATx2kgHBfky6DADsLP7ex1t7BRxJ6nqLs9WH --enc json < ipns_record | jq -e ".Validation.Valid == false" + ' + test_kill_ipfs_daemon # Test daemon in offline mode From a3c70a11e68bae6f56763bf971a9477762dd22fe Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Fri, 27 Jan 2023 04:46:50 +0100 Subject: [PATCH 0437/1212] feat(gateway): IPNS record response format (IPIP-351) (#9399) * feat(gateway): IPNS record response format * docs(rpc): mark as experimental: routing provide, get, put Co-authored-by: Marcin Rataj --- core/commands/routing.go | 127 +++---------------- core/coreapi/coreapi.go | 5 + core/coreapi/routing.go | 53 ++++++++ core/corehttp/gateway.go | 4 + core/corehttp/gateway_handler.go | 8 +- core/corehttp/gateway_handler_ipns_record.go | 71 +++++++++++ docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 +- go.mod | 2 +- go.sum | 4 +- test/sharness/t0124-gateway-ipns-record.sh | 52 ++++++++ test/sharness/t0170-legacy-dht.sh | 2 +- test/sharness/t0170-routing-dht.sh | 2 +- 13 files changed, 219 insertions(+), 117 deletions(-) create mode 100644 core/coreapi/routing.go create mode 100644 core/corehttp/gateway_handler_ipns_record.go create mode 100755 test/sharness/t0124-gateway-ipns-record.sh diff --git a/core/commands/routing.go b/core/commands/routing.go index bf7d2a699..d0f13c556 100644 --- a/core/commands/routing.go +++ b/core/commands/routing.go @@ -2,7 +2,6 @@ package commands import ( "context" - "encoding/base64" "errors" "fmt" "io" @@ -135,6 +134,7 @@ const ( ) var provideRefRoutingCmd = &cmds.Command{ + Status: cmds.Experimental, Helptext: cmds.HelpText{ Tagline: "Announce to the network that you are providing given values.", }, @@ -346,6 +346,7 @@ var findPeerRoutingCmd = &cmds.Command{ } var getValueRoutingCmd = &cmds.Command{ + Status: cmds.Experimental, Helptext: cmds.HelpText{ Tagline: "Given a key, query the routing system for its best value.", ShortDescription: ` @@ -362,78 +363,30 @@ Different key types can specify other 'best' rules. Arguments: []cmds.Argument{ cmds.StringArg("key", true, true, "The key to find a value for."), }, - Options: []cmds.Option{ - cmds.BoolOption(dhtVerboseOptionName, "v", "Print extra information."), - }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - nd, err := cmdenv.GetNode(env) + api, err := cmdenv.GetApi(env, req) if err != nil { return err } - if !nd.IsOnline { - return ErrNotOnline - } - - dhtkey, err := escapeDhtKey(req.Arguments[0]) + r, err := api.Routing().Get(req.Context, req.Arguments[0]) if err != nil { return err } - ctx, cancel := context.WithCancel(req.Context) - ctx, events := routing.RegisterForQueryEvents(ctx) - - var getErr error - go func() { - defer cancel() - var val []byte - val, getErr = nd.Routing.GetValue(ctx, dhtkey) - if getErr != nil { - routing.PublishQueryEvent(ctx, &routing.QueryEvent{ - Type: routing.QueryError, - Extra: getErr.Error(), - }) - } else { - routing.PublishQueryEvent(ctx, &routing.QueryEvent{ - Type: routing.Value, - Extra: base64.StdEncoding.EncodeToString(val), - }) - } - }() - - for e := range events { - if err := res.Emit(e); err != nil { - return err - } - } - - return getErr + return res.Emit(r) }, Encoders: cmds.EncoderMap{ - cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *routing.QueryEvent) error { - pfm := pfuncMap{ - routing.Value: func(obj *routing.QueryEvent, out io.Writer, verbose bool) error { - if verbose { - _, err := fmt.Fprintf(out, "got value: '%s'\n", obj.Extra) - return err - } - res, err := base64.StdEncoding.DecodeString(obj.Extra) - if err != nil { - return err - } - _, err = out.Write(res) - return err - }, - } - - verbose, _ := req.Options[dhtVerboseOptionName].(bool) - return printEvent(out, w, verbose, pfm) + cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out []byte) error { + _, err := w.Write(out) + return err }), }, - Type: routing.QueryEvent{}, + Type: []byte{}, } var putValueRoutingCmd = &cmds.Command{ + Status: cmds.Experimental, Helptext: cmds.HelpText{ Tagline: "Write a key/value pair to the routing system.", ShortDescription: ` @@ -459,20 +412,8 @@ identified by QmFoo. cmds.StringArg("key", true, false, "The key to store the value at."), cmds.FileArg("value-file", true, false, "A path to a file containing the value to store.").EnableStdin(), }, - Options: []cmds.Option{ - cmds.BoolOption(dhtVerboseOptionName, "v", "Print extra information."), - }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - nd, err := cmdenv.GetNode(env) - if err != nil { - return err - } - - if !nd.IsOnline { - return ErrNotOnline - } - - key, err := escapeDhtKey(req.Arguments[0]) + api, err := cmdenv.GetApi(env, req) if err != nil { return err } @@ -488,50 +429,20 @@ identified by QmFoo. return err } - ctx, cancel := context.WithCancel(req.Context) - ctx, events := routing.RegisterForQueryEvents(ctx) - - var putErr error - go func() { - defer cancel() - putErr = nd.Routing.PutValue(ctx, key, []byte(data)) - if putErr != nil { - routing.PublishQueryEvent(ctx, &routing.QueryEvent{ - Type: routing.QueryError, - Extra: putErr.Error(), - }) - } - }() - - for e := range events { - if err := res.Emit(e); err != nil { - return err - } + err = api.Routing().Put(req.Context, req.Arguments[0], data) + if err != nil { + return err } - return putErr + return res.Emit([]byte(fmt.Sprintf("%s added", req.Arguments[0]))) }, Encoders: cmds.EncoderMap{ - cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *routing.QueryEvent) error { - pfm := pfuncMap{ - routing.FinalPeer: func(obj *routing.QueryEvent, out io.Writer, verbose bool) error { - if verbose { - fmt.Fprintf(out, "* closest peer %s\n", obj.ID) - } - return nil - }, - routing.Value: func(obj *routing.QueryEvent, out io.Writer, verbose bool) error { - fmt.Fprintf(out, "%s\n", obj.ID.Pretty()) - return nil - }, - } - - verbose, _ := req.Options[dhtVerboseOptionName].(bool) - - return printEvent(out, w, verbose, pfm) + cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out []byte) error { + _, err := w.Write(out) + return err }), }, - Type: routing.QueryEvent{}, + Type: []byte{}, } type printFunc func(obj *routing.QueryEvent, out io.Writer, verbose bool) error diff --git a/core/coreapi/coreapi.go b/core/coreapi/coreapi.go index fb549171a..85bd60c12 100644 --- a/core/coreapi/coreapi.go +++ b/core/coreapi/coreapi.go @@ -144,6 +144,11 @@ func (api *CoreAPI) PubSub() coreiface.PubSubAPI { return (*PubSubAPI)(api) } +// Routing returns the RoutingAPI interface implementation backed by the kubo node +func (api *CoreAPI) Routing() coreiface.RoutingAPI { + return (*RoutingAPI)(api) +} + // WithOptions returns api with global options applied func (api *CoreAPI) WithOptions(opts ...options.ApiOption) (coreiface.CoreAPI, error) { settings := api.parentOpts // make sure to copy diff --git a/core/coreapi/routing.go b/core/coreapi/routing.go new file mode 100644 index 000000000..78f21c429 --- /dev/null +++ b/core/coreapi/routing.go @@ -0,0 +1,53 @@ +package coreapi + +import ( + "context" + "errors" + + "github.com/ipfs/go-path" + coreiface "github.com/ipfs/interface-go-ipfs-core" + peer "github.com/libp2p/go-libp2p/core/peer" +) + +type RoutingAPI CoreAPI + +func (r *RoutingAPI) Get(ctx context.Context, key string) ([]byte, error) { + if !r.nd.IsOnline { + return nil, coreiface.ErrOffline + } + + dhtKey, err := normalizeKey(key) + if err != nil { + return nil, err + } + + return r.routing.GetValue(ctx, dhtKey) +} + +func (r *RoutingAPI) Put(ctx context.Context, key string, value []byte) error { + if !r.nd.IsOnline { + return coreiface.ErrOffline + } + + dhtKey, err := normalizeKey(key) + if err != nil { + return err + } + + return r.routing.PutValue(ctx, dhtKey, value) +} + +func normalizeKey(s string) (string, error) { + parts := path.SplitList(s) + if len(parts) != 3 || + parts[0] != "" || + !(parts[1] == "ipns" || parts[1] == "pk") { + return "", errors.New("invalid key") + } + + k, err := peer.Decode(parts[2]) + if err != nil { + return "", err + } + return path.Join(append(parts[:2], string(k))), nil +} diff --git a/core/corehttp/gateway.go b/core/corehttp/gateway.go index 334000b5a..00c2f7483 100644 --- a/core/corehttp/gateway.go +++ b/core/corehttp/gateway.go @@ -33,6 +33,10 @@ type NodeAPI interface { // Dag returns an implementation of Dag API Dag() coreiface.APIDagService + // Routing returns an implementation of Routing API. + // Used for returning signed IPNS records, see IPIP-0328 + Routing() coreiface.RoutingAPI + // ResolvePath resolves the path using Unixfs resolver ResolvePath(context.Context, path.Path) (path.Resolved, error) } diff --git a/core/corehttp/gateway_handler.go b/core/corehttp/gateway_handler.go index 1c6797e68..c3e8fa0d6 100644 --- a/core/corehttp/gateway_handler.go +++ b/core/corehttp/gateway_handler.go @@ -444,6 +444,9 @@ func (i *gatewayHandler) getOrHeadHandler(w http.ResponseWriter, r *http.Request case "application/vnd.ipld.dag-json", "application/vnd.ipld.dag-cbor": logger.Debugw("serving codec", "path", contentPath) i.serveCodec(r.Context(), w, r, resolvedPath, contentPath, begin, responseFormat) + case "application/vnd.ipfs.ipns-record": + logger.Debugw("serving ipns record", "path", contentPath) + i.serveIpnsRecord(r.Context(), w, r, resolvedPath, contentPath, begin, logger) return default: // catch-all for unsuported application/vnd.* err := fmt.Errorf("unsupported format %q", responseFormat) @@ -885,6 +888,8 @@ func customResponseFormat(r *http.Request) (mediaType string, params map[string] return "application/vnd.ipld.dag-json", nil, nil case "dag-cbor": return "application/vnd.ipld.dag-cbor", nil, nil + case "ipns-record": + return "application/vnd.ipfs.ipns-record", nil, nil } } // Browsers and other user agents will send Accept header with generic types like: @@ -898,7 +903,8 @@ func customResponseFormat(r *http.Request) (mediaType string, params map[string] if strings.HasPrefix(accept, "application/vnd.ipld") || strings.HasPrefix(accept, "application/x-tar") || strings.HasPrefix(accept, "application/json") || - strings.HasPrefix(accept, "application/cbor") { + strings.HasPrefix(accept, "application/cbor") || + strings.HasPrefix(accept, "application/vnd.ipfs") { mediatype, params, err := mime.ParseMediaType(accept) if err != nil { return "", nil, err diff --git a/core/corehttp/gateway_handler_ipns_record.go b/core/corehttp/gateway_handler_ipns_record.go new file mode 100644 index 000000000..16d9663fa --- /dev/null +++ b/core/corehttp/gateway_handler_ipns_record.go @@ -0,0 +1,71 @@ +package corehttp + +import ( + "context" + "errors" + "fmt" + "net/http" + "strings" + "time" + + "github.com/gogo/protobuf/proto" + ipns_pb "github.com/ipfs/go-ipns/pb" + path "github.com/ipfs/go-path" + ipath "github.com/ipfs/interface-go-ipfs-core/path" + "go.uber.org/zap" +) + +func (i *gatewayHandler) serveIpnsRecord(ctx context.Context, w http.ResponseWriter, r *http.Request, resolvedPath ipath.Resolved, contentPath ipath.Path, begin time.Time, logger *zap.SugaredLogger) { + if contentPath.Namespace() != "ipns" { + err := fmt.Errorf("%s is not an IPNS link", contentPath.String()) + webError(w, err.Error(), err, http.StatusBadRequest) + return + } + + key := contentPath.String() + key = strings.TrimSuffix(key, "/") + if strings.Count(key, "/") > 2 { + err := errors.New("cannot find ipns key for subpath") + webError(w, err.Error(), err, http.StatusBadRequest) + return + } + + rawRecord, err := i.api.Routing().Get(ctx, key) + if err != nil { + webError(w, err.Error(), err, http.StatusInternalServerError) + return + } + + var record ipns_pb.IpnsEntry + err = proto.Unmarshal(rawRecord, &record) + if err != nil { + webError(w, err.Error(), err, http.StatusInternalServerError) + return + } + + // Set cache control headers based on the TTL set in the IPNS record. If the + // TTL is not present, we use the Last-Modified tag. We are tracking IPNS + // caching on: https://github.com/ipfs/kubo/issues/1818. + // TODO: use addCacheControlHeaders once #1818 is fixed. + w.Header().Set("Etag", getEtag(r, resolvedPath.Cid())) + if record.Ttl != nil { + seconds := int(time.Duration(*record.Ttl).Seconds()) + w.Header().Set("Cache-Control", fmt.Sprintf("public, max-age=%d", seconds)) + } else { + w.Header().Set("Last-Modified", time.Now().UTC().Format(http.TimeFormat)) + } + + // Set Content-Disposition + var name string + if urlFilename := r.URL.Query().Get("filename"); urlFilename != "" { + name = urlFilename + } else { + name = path.SplitList(key)[2] + ".ipns-record" + } + setContentDispositionHeader(w, name, "attachment") + + w.Header().Set("Content-Type", "application/vnd.ipfs.ipns-record") + w.Header().Set("X-Content-Type-Options", "nosniff") + + _, _ = w.Write(rawRecord) +} diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 29b99699e..c90c4b2d8 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -8,7 +8,7 @@ replace github.com/ipfs/kubo => ./../../.. require ( github.com/ipfs/go-libipfs v0.3.0 - github.com/ipfs/interface-go-ipfs-core v0.9.0 + github.com/ipfs/interface-go-ipfs-core v0.10.0 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.24.2 github.com/multiformats/go-multiaddr v0.8.0 diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 75135d8be..456c31105 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -594,8 +594,8 @@ github.com/ipfs/go-unixfsnode v1.5.1/go.mod h1:ed79DaG9IEuZITJVQn4U6MZDftv6I3ygU github.com/ipfs/go-verifcid v0.0.1/go.mod h1:5Hrva5KBeIog4A+UpqlaIU+DEstipcJYQQZc0g37pY0= github.com/ipfs/go-verifcid v0.0.2 h1:XPnUv0XmdH+ZIhLGKg6U2vaPaRDXb9urMyNVCE7uvTs= github.com/ipfs/go-verifcid v0.0.2/go.mod h1:40cD9x1y4OWnFXbLNJYRe7MpNvWlMn3LZAG5Wb4xnPU= -github.com/ipfs/interface-go-ipfs-core v0.9.0 h1:+RCouVtSU/SldgkqWufjIu1smmGaSyKgUIfbYwLukgI= -github.com/ipfs/interface-go-ipfs-core v0.9.0/go.mod h1:F3EcmDy53GFkF0H3iEJpfJC320fZ/4G60eftnItrrJ0= +github.com/ipfs/interface-go-ipfs-core v0.10.0 h1:b/psL1oqJcySdQAsIBfW5ZJJkOAsYlhWtC0/Qvr4WiM= +github.com/ipfs/interface-go-ipfs-core v0.10.0/go.mod h1:F3EcmDy53GFkF0H3iEJpfJC320fZ/4G60eftnItrrJ0= github.com/ipld/edelweiss v0.2.0 h1:KfAZBP8eeJtrLxLhi7r3N0cBCo7JmwSRhOJp3WSpNjk= github.com/ipld/edelweiss v0.2.0/go.mod h1:FJAzJRCep4iI8FOFlRriN9n0b7OuX3T/S9++NpBDmA4= github.com/ipld/go-car v0.4.0 h1:U6W7F1aKF/OJMHovnOVdst2cpQE5GhmHibQkAixgNcQ= diff --git a/go.mod b/go.mod index fbc56cc84..82d0b1053 100644 --- a/go.mod +++ b/go.mod @@ -62,7 +62,7 @@ require ( github.com/ipfs/go-unixfs v0.4.2 github.com/ipfs/go-unixfsnode v1.5.1 github.com/ipfs/go-verifcid v0.0.2 - github.com/ipfs/interface-go-ipfs-core v0.9.0 + github.com/ipfs/interface-go-ipfs-core v0.10.0 github.com/ipld/go-car v0.4.0 github.com/ipld/go-car/v2 v2.5.1 github.com/ipld/go-codec-dagpb v1.5.0 diff --git a/go.sum b/go.sum index 27674871f..7c6d714d2 100644 --- a/go.sum +++ b/go.sum @@ -620,8 +620,8 @@ github.com/ipfs/go-unixfsnode v1.5.1/go.mod h1:ed79DaG9IEuZITJVQn4U6MZDftv6I3ygU github.com/ipfs/go-verifcid v0.0.1/go.mod h1:5Hrva5KBeIog4A+UpqlaIU+DEstipcJYQQZc0g37pY0= github.com/ipfs/go-verifcid v0.0.2 h1:XPnUv0XmdH+ZIhLGKg6U2vaPaRDXb9urMyNVCE7uvTs= github.com/ipfs/go-verifcid v0.0.2/go.mod h1:40cD9x1y4OWnFXbLNJYRe7MpNvWlMn3LZAG5Wb4xnPU= -github.com/ipfs/interface-go-ipfs-core v0.9.0 h1:+RCouVtSU/SldgkqWufjIu1smmGaSyKgUIfbYwLukgI= -github.com/ipfs/interface-go-ipfs-core v0.9.0/go.mod h1:F3EcmDy53GFkF0H3iEJpfJC320fZ/4G60eftnItrrJ0= +github.com/ipfs/interface-go-ipfs-core v0.10.0 h1:b/psL1oqJcySdQAsIBfW5ZJJkOAsYlhWtC0/Qvr4WiM= +github.com/ipfs/interface-go-ipfs-core v0.10.0/go.mod h1:F3EcmDy53GFkF0H3iEJpfJC320fZ/4G60eftnItrrJ0= github.com/ipld/edelweiss v0.2.0 h1:KfAZBP8eeJtrLxLhi7r3N0cBCo7JmwSRhOJp3WSpNjk= github.com/ipld/edelweiss v0.2.0/go.mod h1:FJAzJRCep4iI8FOFlRriN9n0b7OuX3T/S9++NpBDmA4= github.com/ipld/go-car v0.4.0 h1:U6W7F1aKF/OJMHovnOVdst2cpQE5GhmHibQkAixgNcQ= diff --git a/test/sharness/t0124-gateway-ipns-record.sh b/test/sharness/t0124-gateway-ipns-record.sh new file mode 100755 index 000000000..cff00aa84 --- /dev/null +++ b/test/sharness/t0124-gateway-ipns-record.sh @@ -0,0 +1,52 @@ +#!/usr/bin/env bash + +test_description="Test HTTP Gateway IPNS Record (application/vnd.ipfs.ipns-record) Support" + +. lib/test-lib.sh + +test_init_ipfs +test_launch_ipfs_daemon + +test_expect_success "Create and Publish IPNS Key" ' + FILE_CID=$(echo "Hello IPFS" | ipfs add --cid-version 1 -q) && + IPNS_KEY=$(ipfs key gen ipns-record) && + ipfs name publish /ipfs/$FILE_CID --key=ipns-record --ttl=30m && + curl "http://127.0.0.1:$GWAY_PORT/ipns/$IPNS_KEY" > curl_output_filename && + test_should_contain "Hello IPFS" curl_output_filename +' + +test_expect_success "GET KEY with format=ipns-record and validate key" ' + curl "http://127.0.0.1:$GWAY_PORT/ipns/$IPNS_KEY?format=ipns-record" > curl_output_filename && + ipfs name inspect --verify $IPNS_KEY < curl_output_filename > verify_output && + test_should_contain "$FILE_CID" verify_output +' + +test_expect_success "GET KEY with 'Accept: application/vnd.ipfs.ipns-record' and validate key" ' + curl -H "Accept: application/vnd.ipfs.ipns-record" "http://127.0.0.1:$GWAY_PORT/ipns/$IPNS_KEY" > curl_output_filename && + ipfs name inspect --verify $IPNS_KEY < curl_output_filename > verify_output && + test_should_contain "$FILE_CID" verify_output +' + +test_expect_success "GET KEY with format=ipns-record has expected HTTP headers" ' + curl -sD - "http://127.0.0.1:$GWAY_PORT/ipns/$IPNS_KEY?format=ipns-record" > curl_output_filename 2>&1 && + test_should_contain "Content-Disposition: attachment;" curl_output_filename && + test_should_contain "Content-Type: application/vnd.ipfs.ipns-record" curl_output_filename && + test_should_contain "Cache-Control: public, max-age=1800" curl_output_filename +' + +test_expect_success "GET KEY with 'Accept: application/vnd.ipfs.ipns-record' has expected HTTP headers" ' + curl -H "Accept: application/vnd.ipfs.ipns-record" -sD - "http://127.0.0.1:$GWAY_PORT/ipns/$IPNS_KEY" > curl_output_filename 2>&1 && + test_should_contain "Content-Disposition: attachment;" curl_output_filename && + test_should_contain "Content-Type: application/vnd.ipfs.ipns-record" curl_output_filename && + test_should_contain "Cache-Control: public, max-age=1800" curl_output_filename +' + +test_expect_success "GET KEY with expliciy ?filename= succeeds with modified Content-Disposition header" ' + curl -sD - "http://127.0.0.1:$GWAY_PORT/ipns/$IPNS_KEY?format=ipns-record&filename=testтест.ipns-record" > curl_output_filename 2>&1 && + grep -F "Content-Disposition: attachment; filename=\"test____.ipns-record\"; filename*=UTF-8'\'\''test%D1%82%D0%B5%D1%81%D1%82.ipns-record" curl_output_filename && + test_should_contain "Content-Type: application/vnd.ipfs.ipns-record" curl_output_filename +' + +test_kill_ipfs_daemon + +test_done diff --git a/test/sharness/t0170-legacy-dht.sh b/test/sharness/t0170-legacy-dht.sh index a4dffb34c..fc11b9044 100755 --- a/test/sharness/t0170-legacy-dht.sh +++ b/test/sharness/t0170-legacy-dht.sh @@ -111,7 +111,7 @@ test_dht() { test_must_fail ipfsi 0 dht put "/ipns/$PEERID_2" "get_result" 2>err_put && test_should_contain "this command must be run in online mode" err_findprovs && test_should_contain "this command must be run in online mode" err_findpeer && - test_should_contain "this command must be run in online mode" err_put + test_should_contain "this action must be run in online mode" err_put ' } diff --git a/test/sharness/t0170-routing-dht.sh b/test/sharness/t0170-routing-dht.sh index 2ef0a9cd1..85462dcc2 100755 --- a/test/sharness/t0170-routing-dht.sh +++ b/test/sharness/t0170-routing-dht.sh @@ -112,7 +112,7 @@ test_dht() { test_must_fail ipfsi 0 routing put "/ipns/$PEERID_2" "get_result" 2>err_put && test_should_contain "this command must be run in online mode" err_findprovs && test_should_contain "this command must be run in online mode" err_findpeer && - test_should_contain "this command must be run in online mode" err_put + test_should_contain "this action must be run in online mode" err_put ' } From f2dab48e66ab35bced3bf41451e089ed44eb0e0a Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Fri, 27 Jan 2023 16:57:03 +0100 Subject: [PATCH 0438/1212] docs: DefaultResourceMgrMinInboundConns --- docs/libp2p-resource-management.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/libp2p-resource-management.md b/docs/libp2p-resource-management.md index d6b782da1..b3eb48ce1 100644 --- a/docs/libp2p-resource-management.md +++ b/docs/libp2p-resource-management.md @@ -152,7 +152,7 @@ existing low priority idle connections can prevent new high priority connections The ResourceMgr doesn't know that the new connection is high priority and simply blocks it because of the limit its enforcing. To ensure the ConnMgr and ResourceMgr are congruent, the ResourceMgr [computed default limts](#computed-default-limits) are adjusted such that: -1. `Swarm.ResourceMgr.Limits.System.ConnsInbound` >= `max(Swarm.ConnMgr.HighWater * 2, 800)` AND +1. `Swarm.ResourceMgr.Limits.System.ConnsInbound` >= `max(Swarm.ConnMgr.HighWater * 2, DefaultResourceMgrMinInboundConns)` AND 2. `Swarm.ResourceMgr.Limits.System.StreamsInbound` is greater than any new/adjusted `Swarm.ResourceMgr.Limits.System.ConnsInbound` value so that there's enough streams per connection. ### How does one see the Active Limits? From b3c98bb0850c5527307262d3f1ab110ba77f9a36 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Fri, 27 Jan 2023 22:55:02 +0100 Subject: [PATCH 0439/1212] chore: bump go-libipfs remove go-bitswap --- core/commands/bitswap.go | 4 +-- core/node/bitswap.go | 4 +-- docs/examples/kubo-as-a-library/go.mod | 5 ++-- docs/examples/kubo-as-a-library/go.sum | 9 +++---- go.mod | 5 ++-- go.sum | 9 +++---- testplans/bitswap/go.mod | 4 +-- testplans/bitswap/go.sum | 34 ++++++-------------------- testplans/bitswap/main.go | 4 +-- 9 files changed, 27 insertions(+), 51 deletions(-) diff --git a/core/commands/bitswap.go b/core/commands/bitswap.go index d524263be..a7e8965b1 100644 --- a/core/commands/bitswap.go +++ b/core/commands/bitswap.go @@ -8,10 +8,10 @@ import ( e "github.com/ipfs/kubo/core/commands/e" humanize "github.com/dustin/go-humanize" - bitswap "github.com/ipfs/go-bitswap" - decision "github.com/ipfs/go-bitswap/decision" cidutil "github.com/ipfs/go-cidutil" cmds "github.com/ipfs/go-ipfs-cmds" + bitswap "github.com/ipfs/go-libipfs/bitswap" + decision "github.com/ipfs/go-libipfs/bitswap/decision" peer "github.com/libp2p/go-libp2p/core/peer" ) diff --git a/core/node/bitswap.go b/core/node/bitswap.go index 42b948f75..f78703039 100644 --- a/core/node/bitswap.go +++ b/core/node/bitswap.go @@ -4,10 +4,10 @@ import ( "context" "time" - "github.com/ipfs/go-bitswap" - "github.com/ipfs/go-bitswap/network" blockstore "github.com/ipfs/go-ipfs-blockstore" exchange "github.com/ipfs/go-ipfs-exchange-interface" + "github.com/ipfs/go-libipfs/bitswap" + "github.com/ipfs/go-libipfs/bitswap/network" "github.com/ipfs/kubo/config" irouting "github.com/ipfs/kubo/routing" "github.com/libp2p/go-libp2p/core/host" diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index c90c4b2d8..3294cd137 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.18 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/go-libipfs v0.3.0 + github.com/ipfs/go-libipfs v0.4.0 github.com/ipfs/interface-go-ipfs-core v0.10.0 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.24.2 @@ -63,8 +63,7 @@ require ( github.com/huin/goupnp v1.0.3 // indirect github.com/ipfs/bbloom v0.0.4 // indirect github.com/ipfs/go-bitfield v1.0.0 // indirect - github.com/ipfs/go-bitswap v0.11.0 // indirect - github.com/ipfs/go-block-format v0.1.0 // indirect + github.com/ipfs/go-block-format v0.1.1 // indirect github.com/ipfs/go-blockservice v0.5.0 // indirect github.com/ipfs/go-cid v0.3.2 // indirect github.com/ipfs/go-cidutil v0.1.0 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 456c31105..ece45c198 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -422,12 +422,11 @@ github.com/ipfs/go-bitswap v0.1.2/go.mod h1:qxSWS4NXGs7jQ6zQvoPY3+NmOfHHG47mhkiL github.com/ipfs/go-bitswap v0.5.1/go.mod h1:P+ckC87ri1xFLvk74NlXdP0Kj9RmWAh4+H78sC6Qopo= github.com/ipfs/go-bitswap v0.6.0/go.mod h1:Hj3ZXdOC5wBJvENtdqsixmzzRukqd8EHLxZLZc3mzRA= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= -github.com/ipfs/go-bitswap v0.11.0/go.mod h1:05aE8H3XOU+LXpTedeAS0OZpcO1WFsj5niYQH9a1Tmk= github.com/ipfs/go-block-format v0.0.1/go.mod h1:DK/YYcsSUIVAFNwo/KZCdIIbpN0ROH/baNLgayt4pFc= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= github.com/ipfs/go-block-format v0.0.3/go.mod h1:4LmD4ZUw0mhO+JSKdpWwrzATiEfM7WWgQ8H5l6P8MVk= -github.com/ipfs/go-block-format v0.1.0 h1:1DYLENGQUVWVvZ9tMmZX2KVi0ALyPxxyP6jn8NuCxZY= -github.com/ipfs/go-block-format v0.1.0/go.mod h1:+McEIT+g52p+zz5xGAABGSOKrzmrdX97bc0USBdWPUs= +github.com/ipfs/go-block-format v0.1.1 h1:129vSO3zwbsYADcyQWcOYiuCpAqt462SFfqFHdFJhhI= +github.com/ipfs/go-block-format v0.1.1/go.mod h1:+McEIT+g52p+zz5xGAABGSOKrzmrdX97bc0USBdWPUs= github.com/ipfs/go-blockservice v0.1.0/go.mod h1:hzmMScl1kXHg3M2BjTymbVPjv627N7sYcvYaKbop39M= github.com/ipfs/go-blockservice v0.2.1/go.mod h1:k6SiwmgyYgs4M/qt+ww6amPeUH9EISLRBnvUurKJhi8= github.com/ipfs/go-blockservice v0.3.0/go.mod h1:P5ppi8IHDC7O+pA0AlGTF09jruB2h+oP3wVVaZl8sfk= @@ -549,8 +548,8 @@ github.com/ipfs/go-ipld-legacy v0.1.1 h1:BvD8PEuqwBHLTKqlGFTHSwrwFOMkVESEvwIYwR2 github.com/ipfs/go-ipld-legacy v0.1.1/go.mod h1:8AyKFCjgRPsQFf15ZQgDB8Din4DML/fOmKZkkFkrIEg= github.com/ipfs/go-ipns v0.3.0 h1:ai791nTgVo+zTuq2bLvEGmWP1M0A6kGTXUsgv/Yq67A= github.com/ipfs/go-ipns v0.3.0/go.mod h1:3cLT2rbvgPZGkHJoPO1YMJeh6LtkxopCkKFcio/wE24= -github.com/ipfs/go-libipfs v0.3.0 h1:YvzFWGcl88eiz2tjOheNqaeQseH+dW3fUKrSaHOG/dU= -github.com/ipfs/go-libipfs v0.3.0/go.mod h1:pSUHZ5qPJTAidsxe9bAeHp3KIiw2ODEW2a2kM3v+iXI= +github.com/ipfs/go-libipfs v0.4.0 h1:TkUxJGjtPnSzAgkw7VjS0/DBay3MPjmTBa4dGdUQCDE= +github.com/ipfs/go-libipfs v0.4.0/go.mod h1:XsU2cP9jBhDrXoJDe0WxikB8XcVmD3k2MEZvB3dbYu8= github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= github.com/ipfs/go-log v1.0.2/go.mod h1:1MNjMxe0u6xvJZgeqbJ8vdo2TKaGwZ1a0Bpza+sr2Sk= github.com/ipfs/go-log v1.0.3/go.mod h1:OsLySYkwIbiSUR/yBTdv1qPtcE4FW3WPWk/ewz9Ru+A= diff --git a/go.mod b/go.mod index 82d0b1053..3d91f40e7 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,6 @@ require ( github.com/gogo/protobuf v1.3.2 github.com/google/uuid v1.3.0 github.com/hashicorp/go-multierror v1.1.1 - github.com/ipfs/go-bitswap v0.11.0 github.com/ipfs/go-blockservice v0.5.0 github.com/ipfs/go-cid v0.3.2 github.com/ipfs/go-cidutil v0.1.0 @@ -49,7 +48,7 @@ require ( github.com/ipfs/go-ipld-git v0.1.1 github.com/ipfs/go-ipld-legacy v0.1.1 github.com/ipfs/go-ipns v0.3.0 - github.com/ipfs/go-libipfs v0.3.0 + github.com/ipfs/go-libipfs v0.4.0 github.com/ipfs/go-log v1.0.5 github.com/ipfs/go-log/v2 v2.5.1 github.com/ipfs/go-merkledag v0.9.0 @@ -158,7 +157,7 @@ require ( github.com/huin/goupnp v1.0.3 // indirect github.com/ipfs/bbloom v0.0.4 // indirect github.com/ipfs/go-bitfield v1.0.0 // indirect - github.com/ipfs/go-block-format v0.1.0 // indirect + github.com/ipfs/go-block-format v0.1.1 // indirect github.com/ipfs/go-ipfs-delay v0.0.1 // indirect github.com/ipfs/go-ipfs-ds-help v1.1.0 // indirect github.com/ipfs/go-ipfs-pq v0.0.2 // indirect diff --git a/go.sum b/go.sum index 7c6d714d2..471acc808 100644 --- a/go.sum +++ b/go.sum @@ -440,12 +440,11 @@ github.com/ipfs/go-bitswap v0.1.2/go.mod h1:qxSWS4NXGs7jQ6zQvoPY3+NmOfHHG47mhkiL github.com/ipfs/go-bitswap v0.5.1/go.mod h1:P+ckC87ri1xFLvk74NlXdP0Kj9RmWAh4+H78sC6Qopo= github.com/ipfs/go-bitswap v0.6.0/go.mod h1:Hj3ZXdOC5wBJvENtdqsixmzzRukqd8EHLxZLZc3mzRA= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= -github.com/ipfs/go-bitswap v0.11.0/go.mod h1:05aE8H3XOU+LXpTedeAS0OZpcO1WFsj5niYQH9a1Tmk= github.com/ipfs/go-block-format v0.0.1/go.mod h1:DK/YYcsSUIVAFNwo/KZCdIIbpN0ROH/baNLgayt4pFc= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= github.com/ipfs/go-block-format v0.0.3/go.mod h1:4LmD4ZUw0mhO+JSKdpWwrzATiEfM7WWgQ8H5l6P8MVk= -github.com/ipfs/go-block-format v0.1.0 h1:1DYLENGQUVWVvZ9tMmZX2KVi0ALyPxxyP6jn8NuCxZY= -github.com/ipfs/go-block-format v0.1.0/go.mod h1:+McEIT+g52p+zz5xGAABGSOKrzmrdX97bc0USBdWPUs= +github.com/ipfs/go-block-format v0.1.1 h1:129vSO3zwbsYADcyQWcOYiuCpAqt462SFfqFHdFJhhI= +github.com/ipfs/go-block-format v0.1.1/go.mod h1:+McEIT+g52p+zz5xGAABGSOKrzmrdX97bc0USBdWPUs= github.com/ipfs/go-blockservice v0.1.0/go.mod h1:hzmMScl1kXHg3M2BjTymbVPjv627N7sYcvYaKbop39M= github.com/ipfs/go-blockservice v0.2.1/go.mod h1:k6SiwmgyYgs4M/qt+ww6amPeUH9EISLRBnvUurKJhi8= github.com/ipfs/go-blockservice v0.3.0/go.mod h1:P5ppi8IHDC7O+pA0AlGTF09jruB2h+oP3wVVaZl8sfk= @@ -571,8 +570,8 @@ github.com/ipfs/go-ipld-legacy v0.1.1 h1:BvD8PEuqwBHLTKqlGFTHSwrwFOMkVESEvwIYwR2 github.com/ipfs/go-ipld-legacy v0.1.1/go.mod h1:8AyKFCjgRPsQFf15ZQgDB8Din4DML/fOmKZkkFkrIEg= github.com/ipfs/go-ipns v0.3.0 h1:ai791nTgVo+zTuq2bLvEGmWP1M0A6kGTXUsgv/Yq67A= github.com/ipfs/go-ipns v0.3.0/go.mod h1:3cLT2rbvgPZGkHJoPO1YMJeh6LtkxopCkKFcio/wE24= -github.com/ipfs/go-libipfs v0.3.0 h1:YvzFWGcl88eiz2tjOheNqaeQseH+dW3fUKrSaHOG/dU= -github.com/ipfs/go-libipfs v0.3.0/go.mod h1:pSUHZ5qPJTAidsxe9bAeHp3KIiw2ODEW2a2kM3v+iXI= +github.com/ipfs/go-libipfs v0.4.0 h1:TkUxJGjtPnSzAgkw7VjS0/DBay3MPjmTBa4dGdUQCDE= +github.com/ipfs/go-libipfs v0.4.0/go.mod h1:XsU2cP9jBhDrXoJDe0WxikB8XcVmD3k2MEZvB3dbYu8= github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= github.com/ipfs/go-log v1.0.2/go.mod h1:1MNjMxe0u6xvJZgeqbJ8vdo2TKaGwZ1a0Bpza+sr2Sk= github.com/ipfs/go-log v1.0.3/go.mod h1:OsLySYkwIbiSUR/yBTdv1qPtcE4FW3WPWk/ewz9Ru+A= diff --git a/testplans/bitswap/go.mod b/testplans/bitswap/go.mod index 92cf8f199..79925df14 100644 --- a/testplans/bitswap/go.mod +++ b/testplans/bitswap/go.mod @@ -2,14 +2,12 @@ module github.com/ipfs/go-ipfs/testplans/bitswap require ( github.com/gopherjs/gopherjs v0.0.0-20190812055157-5d271430af9f // indirect - github.com/ipfs/go-bitswap v0.10.1 - github.com/ipfs/go-block-format v0.1.0 // indirect github.com/ipfs/go-cid v0.3.2 github.com/ipfs/go-datastore v0.6.0 github.com/ipfs/go-ipfs-blockstore v1.2.0 github.com/ipfs/go-ipfs-exchange-interface v0.2.0 github.com/ipfs/go-ipfs-regression v0.0.1 - github.com/ipfs/go-libipfs v0.3.0 + github.com/ipfs/go-libipfs v0.4.0 github.com/ipld/go-ipld-prime v0.9.1-0.20210324083106-dc342a9917db // indirect github.com/libp2p/go-libp2p v0.23.4 github.com/libp2p/go-libp2p-kad-dht v0.18.0 diff --git a/testplans/bitswap/go.sum b/testplans/bitswap/go.sum index c9f0bc166..5cb07e8c0 100644 --- a/testplans/bitswap/go.sum +++ b/testplans/bitswap/go.sum @@ -61,8 +61,6 @@ github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+Ce github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= -github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= -github.com/btcsuite/btcd v0.0.0-20190523000118-16327141da8c/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= github.com/btcsuite/btcd v0.0.0-20190824003749-130ea5bddde3/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= github.com/btcsuite/btcd v0.22.1/go.mod h1:wqgTSL29+50LRkmOVknEdmt8ZojIzhuWvgu/iptuN7Y= @@ -70,7 +68,6 @@ github.com/btcsuite/btcd/btcec/v2 v2.1.3/go.mod h1:ctjw4H1kknNJmRN4iP1R7bTQ+v3GJ github.com/btcsuite/btcd/chaincfg/chainhash v1.0.0/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= -github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce/go.mod h1:0DVlHczLPewLcPGEIeUEzfOJhqGPQ0mJJRDBtD307+o= github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= @@ -293,12 +290,10 @@ github.com/influxdata/influxdb1-client v0.0.0-20200515024757-02f0bf5dbca3 h1:k3/ github.com/influxdata/influxdb1-client v0.0.0-20200515024757-02f0bf5dbca3/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/go-bitswap v0.10.1 h1:XaMmwMR8NgxpzB2hVtZsVLPJPTn2pfAA66GN8gZJTl8= -github.com/ipfs/go-bitswap v0.10.1/go.mod h1:+fZEvycxviZ7c+5KlKwTzLm0M28g2ukCPqiuLfJk4KA= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= github.com/ipfs/go-block-format v0.0.3/go.mod h1:4LmD4ZUw0mhO+JSKdpWwrzATiEfM7WWgQ8H5l6P8MVk= -github.com/ipfs/go-block-format v0.1.0 h1:1DYLENGQUVWVvZ9tMmZX2KVi0ALyPxxyP6jn8NuCxZY= -github.com/ipfs/go-block-format v0.1.0/go.mod h1:+McEIT+g52p+zz5xGAABGSOKrzmrdX97bc0USBdWPUs= +github.com/ipfs/go-block-format v0.1.1 h1:129vSO3zwbsYADcyQWcOYiuCpAqt462SFfqFHdFJhhI= +github.com/ipfs/go-block-format v0.1.1/go.mod h1:+McEIT+g52p+zz5xGAABGSOKrzmrdX97bc0USBdWPUs= github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.2/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.3/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= @@ -331,7 +326,6 @@ github.com/ipfs/go-ipfs-blocksutil v0.0.1/go.mod h1:Yq4M86uIOmxmGPUHv/uI7uKqZNtL github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= github.com/ipfs/go-ipfs-delay v0.0.1 h1:r/UXYyRcddO6thwOnhiznIAiSvxMECGgtv35Xs1IeRQ= github.com/ipfs/go-ipfs-delay v0.0.1/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= -github.com/ipfs/go-ipfs-ds-help v0.1.1/go.mod h1:SbBafGJuGsPI/QL3j9Fc5YPLeAu+SzOkI0gFwAg+mOs= github.com/ipfs/go-ipfs-ds-help v1.1.0 h1:yLE2w9RAsl31LtfMt91tRZcrx+e61O5mDxFRR994w4Q= github.com/ipfs/go-ipfs-ds-help v1.1.0/go.mod h1:YR5+6EaebOhfcqVCyqemItCLthrpVNot+rsOU/5IatU= github.com/ipfs/go-ipfs-exchange-interface v0.2.0 h1:8lMSJmKogZYNo2jjhUs0izT+dck05pqUw4mWNW9Pw6Y= @@ -340,8 +334,8 @@ github.com/ipfs/go-ipfs-pq v0.0.2 h1:e1vOOW6MuOwG2lqxcLA+wEn93i/9laCY8sXAw76jFOY github.com/ipfs/go-ipfs-pq v0.0.2/go.mod h1:LWIqQpqfRG3fNc5XsnIhz/wQ2XXGyugQwls7BgUmUfY= github.com/ipfs/go-ipfs-regression v0.0.1 h1:LX3lrYYgiCE9QmL/qlc4Mh0cewdOHRl5pArbeQRllsU= github.com/ipfs/go-ipfs-regression v0.0.1/go.mod h1:I9yKzBjbirC5D0ND0DBkiQ5PPSQ2R2YjhcqHPj8L28A= -github.com/ipfs/go-ipfs-routing v0.2.1 h1:E+whHWhJkdN9YeoHZNj5itzc+OR292AJ2uE9FFiW0BY= -github.com/ipfs/go-ipfs-routing v0.2.1/go.mod h1:xiNNiwgjmLqPS1cimvAw6EyB9rkVDbiocA4yY+wRNLM= +github.com/ipfs/go-ipfs-routing v0.3.0 h1:9W/W3N+g+y4ZDeffSgqhgo7BsBSJwPMcyssET9OWevc= +github.com/ipfs/go-ipfs-routing v0.3.0/go.mod h1:dKqtTFIql7e1zYsEuWLyuOU+E0WJWW8JjbTPLParDWo= github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyBCNzQxlJBc= github.com/ipfs/go-ipfs-util v0.0.2 h1:59Sswnk1MFaiq+VcaknX7aYEyGyGDAA73ilhEK2POp8= github.com/ipfs/go-ipfs-util v0.0.2/go.mod h1:CbPtkWJzjLdEcezDns2XYaehFVNXG9zrdrtMecczcsQ= @@ -350,8 +344,9 @@ github.com/ipfs/go-ipld-format v0.3.0/go.mod h1:co/SdBE8h99968X0hViiw1MNlh6fvxxn github.com/ipfs/go-ipns v0.2.0/go.mod h1:3cLT2rbvgPZGkHJoPO1YMJeh6LtkxopCkKFcio/wE24= github.com/ipfs/go-ipns v0.3.0 h1:ai791nTgVo+zTuq2bLvEGmWP1M0A6kGTXUsgv/Yq67A= github.com/ipfs/go-ipns v0.3.0/go.mod h1:3cLT2rbvgPZGkHJoPO1YMJeh6LtkxopCkKFcio/wE24= -github.com/ipfs/go-libipfs v0.3.0 h1:YvzFWGcl88eiz2tjOheNqaeQseH+dW3fUKrSaHOG/dU= github.com/ipfs/go-libipfs v0.3.0/go.mod h1:pSUHZ5qPJTAidsxe9bAeHp3KIiw2ODEW2a2kM3v+iXI= +github.com/ipfs/go-libipfs v0.4.0 h1:TkUxJGjtPnSzAgkw7VjS0/DBay3MPjmTBa4dGdUQCDE= +github.com/ipfs/go-libipfs v0.4.0/go.mod h1:XsU2cP9jBhDrXoJDe0WxikB8XcVmD3k2MEZvB3dbYu8= github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= github.com/ipfs/go-log v1.0.3/go.mod h1:OsLySYkwIbiSUR/yBTdv1qPtcE4FW3WPWk/ewz9Ru+A= github.com/ipfs/go-log v1.0.4/go.mod h1:oDCg2FkjogeFOhqqb+N39l2RpTNPL6F/StPkB3kPgcs= @@ -365,8 +360,8 @@ github.com/ipfs/go-log/v2 v2.5.1 h1:1XdUzF7048prq4aBjDQQ4SL5RxftpRGdXhNRwKSAlcY= github.com/ipfs/go-log/v2 v2.5.1/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOLU9U5UI= github.com/ipfs/go-metrics-interface v0.0.1 h1:j+cpbjYvu4R8zbleSs36gvB7jR+wsL2fGD6n0jO4kdg= github.com/ipfs/go-metrics-interface v0.0.1/go.mod h1:6s6euYU4zowdslK0GKHmqaIZ3j/b/tL7HTWtJ4VPgWY= -github.com/ipfs/go-peertaskqueue v0.7.0 h1:VyO6G4sbzX80K58N60cCaHsSsypbUNs1GjO5seGNsQ0= -github.com/ipfs/go-peertaskqueue v0.7.0/go.mod h1:M/akTIE/z1jGNXMU7kFB4TeSEFvj68ow0Rrb04donIU= +github.com/ipfs/go-peertaskqueue v0.8.0 h1:JyNO144tfu9bx6Hpo119zvbEL9iQ760FHOiJYsUjqaU= +github.com/ipfs/go-peertaskqueue v0.8.0/go.mod h1:cz8hEnnARq4Du5TGqiWKgMr/BOSQ5XOgMOh1K5YYKKM= github.com/ipld/go-ipld-prime v0.9.0/go.mod h1:KvBLMr4PX1gWptgkzRjVZCrLmSGcZCb/jioOQwCqZN8= github.com/ipld/go-ipld-prime v0.9.1-0.20210324083106-dc342a9917db h1:kFwGn8rXa/Z31ev1OFNQsYeNKNCdifnTPl/NvPy5L38= github.com/ipld/go-ipld-prime v0.9.1-0.20210324083106-dc342a9917db/go.mod h1:KvBLMr4PX1gWptgkzRjVZCrLmSGcZCb/jioOQwCqZN8= @@ -440,8 +435,6 @@ github.com/libp2p/go-libp2p v0.23.4/go.mod h1:s9DEa5NLR4g+LZS+md5uGU4emjMWFiqkZr 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.2.0 h1:rg3+Os8jbnO5DxkC7K/Utdi+DkY3q/d1/1q+8WeNAsw= github.com/libp2p/go-libp2p-asn-util v0.2.0/go.mod h1:WoaWxbHKBymSN41hWSq/lGKJEca7TNm58+gGJi2WsLI= -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.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= github.com/libp2p/go-libp2p-core v0.2.5/go.mod h1:6+5zJmKhsf7yHn1RbmYDu08qDUpIUxGdqHuEZckmZOA= github.com/libp2p/go-libp2p-core v0.3.0/go.mod h1:ACp3DmS3/N64c2jDzcV429ukDpicbL6+TrrxANBjPGw= @@ -460,12 +453,10 @@ github.com/libp2p/go-libp2p-peerstore v0.1.4/go.mod h1:+4BDbDiiKf4PzpANZDAT+knVd github.com/libp2p/go-libp2p-peerstore v0.2.6/go.mod h1:ss/TWTgHZTMpsU/oKVVPQCGuDHItOpf2W8RxAi50P2s= github.com/libp2p/go-libp2p-peerstore v0.8.0 h1:bzTG693TA1Ju/zKmUCQzDLSqiJnyRFVwPpuloZ/OZtI= github.com/libp2p/go-libp2p-peerstore v0.8.0/go.mod h1:9geHWmNA3YDlQBjL/uPEJD6vpDK12aDNlUNHJ6kio/s= -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.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= github.com/libp2p/go-libp2p-record v0.2.0/go.mod h1:I+3zMkvvg5m2OcSdoL0KPljyJyvNDFGKX7QdlpYUcwk= github.com/libp2p/go-libp2p-routing-helpers v0.2.3/go.mod h1:795bh+9YeoFl99rMASoiVgHdi5bjack0N1+AFAdbvBw= -github.com/libp2p/go-libp2p-testing v0.0.3/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= github.com/libp2p/go-libp2p-testing v0.11.0/go.mod h1:qG4sF27dfKFoK9KlVzK2y52LQKhp0VEmLjV5aDqr1Hg= github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA= github.com/libp2p/go-libp2p-testing v0.12.0/go.mod h1:KcGDRXyN7sQCllucn1cOOS+Dmm7ujhfEyXQL5lvkcPg= @@ -538,7 +529,6 @@ github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc h1:PTfri+PuQmWDqERdn github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc/go.mod h1:cGKTAVKx4SxOuR/czcZ/E2RSJ3sfHs8FpHhQ5CWMf9s= github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= -github.com/minio/sha256-simd v0.0.0-20190328051042-05b4dd3047e5/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g= @@ -551,7 +541,6 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= -github.com/mr-tron/base58 v1.1.1/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mr-tron/base58 v1.1.3/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= @@ -562,8 +551,6 @@ github.com/multiformats/go-base32 v0.1.0 h1:pVx9xoSPqEIQG8o+UbAe7DNi51oej1NtK+aG github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYgtWibDcT0rExnbI= github.com/multiformats/go-base36 v0.1.0 h1:JR6TyF7JjGd3m6FbLU2cOxhC0Li8z8dLNGQ89tUg4F4= github.com/multiformats/go-base36 v0.1.0/go.mod h1:kFGE83c6s80PklsHO9sRn2NCoffoRdUUOENyW/Vv6sM= -github.com/multiformats/go-multiaddr v0.0.2/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= -github.com/multiformats/go-multiaddr v0.0.4/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= github.com/multiformats/go-multiaddr v0.1.0/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo= github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4= @@ -592,7 +579,6 @@ github.com/multiformats/go-multicodec v0.5.0/go.mod h1:DiY2HFaEp5EhEXb/iYzVAunmy github.com/multiformats/go-multicodec v0.6.0 h1:KhH2kSuCARyuJraYMFxrNO3DqIaYhOdS039kbhgVwpE= github.com/multiformats/go-multicodec v0.6.0/go.mod h1:GUC8upxSBE4oG+q3kWZRw/+6yC1BqO550bjhWsJbZlw= github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= -github.com/multiformats/go-multihash v0.0.5/go.mod h1:lt/HCbqlQwlPBz7lv0sQCdtfcMtlJvakRUn/0Ual8po= github.com/multiformats/go-multihash v0.0.8/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= github.com/multiformats/go-multihash v0.0.9/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= github.com/multiformats/go-multihash v0.0.10/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= @@ -724,7 +710,6 @@ github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9 github.com/smola/gocompat v0.2.0/go.mod h1:1B0MlxbmoZNo3h8guHp8HztB3BSYR5itql9qtVc0ypY= github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE= github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA= -github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a/go.mod h1:7AyxJNCJ7SBZ1MfVQCWD6Uqo2oubI2Eq2y2eqf+A5r0= github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU= github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= @@ -819,12 +804,9 @@ golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= diff --git a/testplans/bitswap/main.go b/testplans/bitswap/main.go index a0a77f741..aa98d4f31 100644 --- a/testplans/bitswap/main.go +++ b/testplans/bitswap/main.go @@ -12,8 +12,8 @@ import ( "github.com/testground/sdk-go/runtime" "github.com/testground/sdk-go/sync" - bitswap "github.com/ipfs/go-bitswap" - bsnet "github.com/ipfs/go-bitswap/network" + bitswap "github.com/ipfs/go-libipfs/bitswap" + bsnet "github.com/ipfs/go-libipfs/bitswap/network" block "github.com/ipfs/go-libipfs/blocks" "github.com/ipfs/go-cid" datastore "github.com/ipfs/go-datastore" From 7cb8082bbe8b4900692c9f7085406eea283d70c8 Mon Sep 17 00:00:00 2001 From: Dan McQuillan Date: Fri, 27 Jan 2023 23:32:50 -0800 Subject: [PATCH 0440/1212] feat: ipfs-webui 2.22.0 --- core/corehttp/webui.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/corehttp/webui.go b/core/corehttp/webui.go index e8531459d..f7b27c939 100644 --- a/core/corehttp/webui.go +++ b/core/corehttp/webui.go @@ -1,11 +1,12 @@ package corehttp // TODO: move to IPNS -const WebUIPath = "/ipfs/bafybeiequgo72mrvuml56j4gk7crewig5bavumrrzhkqbim6b3s2yqi7ty" // v2.21.0 +const WebUIPath = "/ipfs/bafybeifeqt7mvxaniphyu2i3qhovjaf3sayooxbh5enfdqtiehxjv2ldte" // v2.22.0 // WebUIPaths is a list of all past webUI paths. var WebUIPaths = []string{ WebUIPath, + "/ipfs/bafybeiequgo72mrvuml56j4gk7crewig5bavumrrzhkqbim6b3s2yqi7ty", "/ipfs/bafybeibjbq3tmmy7wuihhhwvbladjsd3gx3kfjepxzkq6wylik6wc3whzy", "/ipfs/bafybeiavrvt53fks6u32n5p2morgblcmck4bh4ymf4rrwu7ah5zsykmqqa", "/ipfs/bafybeiageaoxg6d7npaof6eyzqbwvbubyler7bq44hayik2hvqcggg7d2y", From 633c497f63e377602adebdaaaaea7dc0d6d0beef Mon Sep 17 00:00:00 2001 From: Antonio Navarro Perez Date: Fri, 27 Jan 2023 16:47:00 +0100 Subject: [PATCH 0441/1212] Adjust inbound connection limits depending on memory. --- core/node/libp2p/rcmgr_defaults.go | 71 +++++++++++++----------------- docs/changelogs/v0.18.md | 36 ++++++++++----- docs/config.md | 2 +- docs/libp2p-resource-management.md | 4 +- 4 files changed, 56 insertions(+), 57 deletions(-) diff --git a/core/node/libp2p/rcmgr_defaults.go b/core/node/libp2p/rcmgr_defaults.go index 4d578a9b6..9a3825108 100644 --- a/core/node/libp2p/rcmgr_defaults.go +++ b/core/node/libp2p/rcmgr_defaults.go @@ -44,17 +44,18 @@ var noLimitIncrease = rcmgr.BaseLimitIncrease{ // This file defines implicit limit defaults used when Swarm.ResourceMgr.Enabled // createDefaultLimitConfig creates LimitConfig to pass to libp2p's resource manager. -// The defaults follow the documentation in docs/config.md. +// The defaults follow the documentation in docs/libp2p-resource-management.md. // Any changes in the logic here should be reflected there. func createDefaultLimitConfig(cfg config.SwarmConfig) (rcmgr.LimitConfig, error) { - maxMemoryDefaultString := humanize.Bytes(uint64(memory.TotalMemory()) / 4) + maxMemoryDefaultString := humanize.Bytes(uint64(memory.TotalMemory()) / 2) maxMemoryString := cfg.ResourceMgr.MaxMemory.WithDefault(maxMemoryDefaultString) maxMemory, err := humanize.ParseBytes(maxMemoryString) if err != nil { return rcmgr.LimitConfig{}, err } - numFD := cfg.ResourceMgr.MaxFileDescriptors.WithDefault(int64(fd.GetNumFDs()) / 2) + maxMemoryMB := maxMemory / (1024 * 1024) + maxFD := int(cfg.ResourceMgr.MaxFileDescriptors.WithDefault(int64(fd.GetNumFDs()) / 2)) // We want to see this message on startup, that's why we are using fmt instead of log. fmt.Printf(` @@ -65,65 +66,53 @@ Computing default go-libp2p Resource Manager limits based on: Applying any user-supplied overrides on top. Run 'ipfs swarm limit all' to see the resulting limits. -`, maxMemoryString, numFD) +`, maxMemoryString, maxFD) + + // At least as of 2023-01-25, it's possible to open a connection that + // doesn't ask for any memory usage with the libp2p Resource Manager/Accountant + // (see https://github.com/libp2p/go-libp2p/issues/2010#issuecomment-1404280736). + // As a result, we can't curretly rely on Memory limits to full protect us. + // Until https://github.com/libp2p/go-libp2p/issues/2010 is addressed, + // we take a proxy now of restricting to 1 inbound connection per MB. + // Note: this is more generous than go-libp2p's default autoscaled limits which do + // 64 connections per 1GB + // (see https://github.com/libp2p/go-libp2p/blob/master/p2p/host/resource-manager/limit_defaults.go#L357 ). + systemConnsInbound := int(1 * maxMemoryMB) scalingLimitConfig := rcmgr.ScalingLimitConfig{ SystemBaseLimit: rcmgr.BaseLimit{ Memory: int64(maxMemory), - FD: int(numFD), + FD: maxFD, // By default, we just limit connections on the inbound side. Conns: bigEnough, - ConnsInbound: rcmgr.DefaultLimits.SystemBaseLimit.ConnsInbound, // same as libp2p default + ConnsInbound: systemConnsInbound, ConnsOutbound: bigEnough, - // We limit streams since they not only take up memory and CPU. - // The Memory limit protects us on the memory side, - // but a StreamsInbound limit helps protect against unbound CPU consumption from stream processing. Streams: bigEnough, - StreamsInbound: rcmgr.DefaultLimits.SystemBaseLimit.StreamsInbound, + StreamsInbound: bigEnough, StreamsOutbound: bigEnough, }, - // Most limits don't see an increase because they're already infinite/bigEnough or at their max value. - // The values that should scale based on the amount of memory allocated to libp2p need to increase accordingly. - SystemLimitIncrease: rcmgr.BaseLimitIncrease{ - Memory: 0, - FDFraction: 0, - - Conns: 0, - ConnsInbound: rcmgr.DefaultLimits.SystemLimitIncrease.ConnsInbound, - ConnsOutbound: 0, - - Streams: 0, - StreamsInbound: rcmgr.DefaultLimits.SystemLimitIncrease.StreamsInbound, - StreamsOutbound: 0, - }, + SystemLimitIncrease: noLimitIncrease, + // Transient connections won't cause any memory to accounted for by the resource manager. + // Only established connections do. + // As a result, we can't rely on System.Memory to protect us from a bunch of transient connection being opened. + // We limit the same values as the System scope, but only allow the Transient scope to take 25% of what is allowed for the System scope. TransientBaseLimit: rcmgr.BaseLimit{ - Memory: rcmgr.DefaultLimits.TransientBaseLimit.Memory, - FD: rcmgr.DefaultLimits.TransientBaseLimit.FD, + Memory: int64(maxMemory / 4), + FD: maxFD / 4, Conns: bigEnough, - ConnsInbound: rcmgr.DefaultLimits.TransientBaseLimit.ConnsInbound, + ConnsInbound: systemConnsInbound / 4, ConnsOutbound: bigEnough, Streams: bigEnough, - StreamsInbound: rcmgr.DefaultLimits.TransientBaseLimit.StreamsInbound, + StreamsInbound: bigEnough, StreamsOutbound: bigEnough, }, - TransientLimitIncrease: rcmgr.BaseLimitIncrease{ - Memory: rcmgr.DefaultLimits.TransientLimitIncrease.Memory, - FDFraction: rcmgr.DefaultLimits.TransientLimitIncrease.FDFraction, - - Conns: 0, - ConnsInbound: rcmgr.DefaultLimits.TransientLimitIncrease.ConnsInbound, - ConnsOutbound: 0, - - Streams: 0, - StreamsInbound: rcmgr.DefaultLimits.TransientLimitIncrease.StreamsInbound, - StreamsOutbound: 0, - }, + TransientLimitIncrease: noLimitIncrease, // Lets get out of the way of the allow list functionality. // If someone specified "Swarm.ResourceMgr.Allowlist" we should let it go through. @@ -184,7 +173,7 @@ Run 'ipfs swarm limit all' to see the resulting limits. // Whatever limits libp2p has specifically tuned for its protocols/services we'll apply. libp2p.SetDefaultServiceLimits(&scalingLimitConfig) - defaultLimitConfig := scalingLimitConfig.Scale(int64(maxMemory), int(numFD)) + defaultLimitConfig := scalingLimitConfig.Scale(int64(maxMemory), maxFD) // Simple checks to overide autoscaling ensuring limits make sense versus the connmgr values. // There are ways to break this, but this should catch most problems already. diff --git a/docs/changelogs/v0.18.md b/docs/changelogs/v0.18.md index 376658fd9..a9d9e0301 100644 --- a/docs/changelogs/v0.18.md +++ b/docs/changelogs/v0.18.md @@ -2,14 +2,14 @@ ## v0.18.1 -This release includes improvements around Pubsub message deduplication, and more. - +This release includes improvements around Pubsub message deduplication, libp2p resource management, and more. - [Overview](#overview) - [🔦 Highlights](#-highlights) - [New default Pubsub.SeenMessagesStrategy](#new-default-pubsubseenmessagesstrategy) + - [Improving libp2p resource management integration](#improving-libp2p-resource-management-integration) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -33,11 +33,24 @@ If you prefer the old behavior, which calculates the TTL countdown based on the first time a message is seen, you can set `Pubsub.SeenMessagesStrategy` to `first-seen`. +#### Improving libp2p resource management integration + +This builds on the default protection nodes get against DoS (resource exhaustion) and eclipse attacks +with the [go-libp2p Network Resource Manager/Accountant](https://github.com/ipfs/kubo/blob/master/docs/libp2p-resource-management.md) +that was fine-tuned in [Kubo 0.18](https://github.com/ipfs/kubo/blob/biglep/resource-manager-example-of-what-want/docs/changelogs/v0.18.md#improving-libp2p-resource-management-integration). + +Adding default hard-limits from the Resource Manager/Accountant after the fact is tricky, +and some additional improvements have been made to improve the [computed defaults](https://github.com/ipfs/kubo/blob/master/docs/libp2p-resource-management.md#computed-default-limits). +As much as possible, the aim is for a user to only think about how much memory they want to bound libp2p to, +and not need to think about translating that to hard numbers for connections, streams, etc. +More updates are likely in future Kubo releases, but with this release: +1. ``System.StreamsInbound`` is no longer bounded directly +2. ``System.ConnsInbound``, ``Transient.Memory``, ``Transiet.ConnsInbound`` have higher default computed values. + ### 📝 Changelog ### 👨‍👩‍👧‍👦 Contributors - ## v0.18.0 ### Overview @@ -46,22 +59,21 @@ Below is an outline of all that is in this release, so you get a sense of all th -- [Overview](#overview) -- [🔦 Highlights](#-highlights) - - [Content routing](#content-routing) + - [🔦 Highlights](#-highlights) + - [Content routing](#content-routing) - [Default InterPlanetary Network Indexer](#default-interplanetary-network-indexer) - [Increase provider record republish interval and expiration](#increase-provider-record-republish-interval-and-expiration) - - [Gateways](#gateways) - - [DAG-JSON and DAG-CBOR response formats](#dag-json-and-dag-cbor-response-formats) + - [Gateways](#gateways) + - [(DAG-)JSON and (DAG-)CBOR response formats](#dag-json-and-dag-cbor-response-formats) - [🐎 Fast directory listings with DAG sizes](#-fast-directory-listings-with-dag-sizes) - - [QUIC and WebTransport](#quic-and-webtransport) + - [QUIC and WebTransport](#quic-and-webtransport) - [WebTransport enabled by default](#webtransport-enabled-by-default) - [QUIC and WebTransport share a single port](#quic-and-webtransport-share-a-single-port) - [Differentiating QUIC versions](#differentiating-quic-versions) - [QUICv1 and WebTransport config migration](#quicv1-and-webtransport-config-migration) - - [Improving libp2p resource management integration](#improving-libp2p-resource-management-integration) -- [📝 Changelog](#-changelog) -- [👨‍👩‍👧‍👦 Contributors](#-contributors) + - [Improving libp2p resource management integration](#improving-libp2p-resource-management-integration) + - [📝 Changelog](#-changelog) + - [👨‍👩‍👧‍👦 Contributors](#-contributors) diff --git a/docs/config.md b/docs/config.md index 94d8094af..995872c4f 100644 --- a/docs/config.md +++ b/docs/config.md @@ -1843,7 +1843,7 @@ This value is also used to scale the limit on various resources at various scope when the default limits (discussed in [libp2p resource management](./libp2p-resource-management.md)) are used. For example, increasing this value will increase the default limit for incoming connections. -Default: `[TOTAL_SYSTEM_MEMORY]/4` +Default: `[TOTAL_SYSTEM_MEMORY]/2` Type: `optionalBytes` #### `Swarm.ResourceMgr.MaxFileDescriptors` diff --git a/docs/libp2p-resource-management.md b/docs/libp2p-resource-management.md index b3eb48ce1..f15be20c5 100644 --- a/docs/libp2p-resource-management.md +++ b/docs/libp2p-resource-management.md @@ -70,8 +70,7 @@ The reason these scopes are chosen is because: Within these scopes, limits are just set on [memory](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#memory), -[file descriptors (FD)](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#file-descriptors), [*inbound* connections](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#connections), -and [*inbound* streams](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#streams). +[file descriptors (FD)](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#file-descriptors), and [*inbound* connections](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#connections). Limits are set based on the `Swarm.ResourceMgr.MaxMemory` and `Swarm.ResourceMgr.MaxFileDescriptors` inputs above. There are also some special cases where minimum values are enforced. @@ -89,7 +88,6 @@ These become the [active limits](#how-does-one-see-the-active-limits). While `Swarm.ResourceMgr.Limits` can be edited directly, it is also possible to use `ipfs swarm limit` command to inspect and tweak specific limits at runtime. - To see all resources that are close to hitting their respective limit: ```console From 3fb644a5e603a462f532b53c112c4a093093f74d Mon Sep 17 00:00:00 2001 From: Antonio Navarro Perez Date: Fri, 27 Jan 2023 16:49:55 +0100 Subject: [PATCH 0442/1212] Add overview section --- docs/changelogs/v0.18.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/changelogs/v0.18.md b/docs/changelogs/v0.18.md index a9d9e0301..eda531614 100644 --- a/docs/changelogs/v0.18.md +++ b/docs/changelogs/v0.18.md @@ -59,6 +59,7 @@ Below is an outline of all that is in this release, so you get a sense of all th + - [Overview](#overview) - [🔦 Highlights](#-highlights) - [Content routing](#content-routing) - [Default InterPlanetary Network Indexer](#default-interplanetary-network-indexer) From abd6343e41d6c3bcb520d96976e2fb14858590ba Mon Sep 17 00:00:00 2001 From: galargh Date: Mon, 30 Jan 2023 11:20:13 +0000 Subject: [PATCH 0443/1212] chore: update version --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index fd7416303..b03eff4a9 100644 --- a/version.go +++ b/version.go @@ -11,7 +11,7 @@ import ( var CurrentCommit string // CurrentVersionNumber is the current application's version literal -const CurrentVersionNumber = "0.18.0" +const CurrentVersionNumber = "0.18.1" const ApiVersion = "/kubo/" + CurrentVersionNumber + "/" //nolint From ed2b7eb48859e449d5feba8fc9021ff146a70df9 Mon Sep 17 00:00:00 2001 From: galargh Date: Mon, 30 Jan 2023 12:48:02 +0100 Subject: [PATCH 0444/1212] chore: prepare branch --- docs/RELEASE_ISSUE_TEMPLATE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/RELEASE_ISSUE_TEMPLATE.md b/docs/RELEASE_ISSUE_TEMPLATE.md index 7671a818e..c12e85057 100644 --- a/docs/RELEASE_ISSUE_TEMPLATE.md +++ b/docs/RELEASE_ISSUE_TEMPLATE.md @@ -89,7 +89,7 @@ This section covers tasks to be done ahead of the release. This section covers tasks to be done during each release. -- [ ] Cut the release branch and update version numbers accordingly
using `kuboreleaser release --version vX.Y.Z(-RCN) cut-branch` or ... +- [ ] Prepare the release branch and update version numbers accordingly
using `kuboreleaser release --version vX.Y.Z(-RCN) prepare-branch` or ... - [ ] create a new branch `release-vX.Y.Z` - use `master` as base if `Z == 0` - use `release` as base if `Z > 0` From 2c623b663e7b3e1c6ffd9fde67c95c5efa132d08 Mon Sep 17 00:00:00 2001 From: Mohsin Zaidi <2236875+smrz2001@users.noreply.github.com> Date: Thu, 26 Jan 2023 18:24:35 -0500 Subject: [PATCH 0445/1212] feat: Pubsub.SeenMessagesStrategy (#9543) * feat: expire messages from the cache based on last seen time * docs: Pubsub.SeenMessagesStrategy Ref. https://github.com/libp2p/go-libp2p-pubsub/pull/513 Co-authored-by: Marcin Rataj --- config/pubsub.go | 27 ++++- core/node/groups.go | 13 ++ docs/changelogs/v0.18.md | 38 ++++++ docs/config.md | 28 ++++- docs/examples/kubo-as-a-library/go.mod | 4 +- docs/examples/kubo-as-a-library/go.sum | 8 +- go.mod | 4 +- go.sum | 8 +- .../integration/pubsub_msg_seen_cache_test.go | 114 ++++++++++++------ 9 files changed, 191 insertions(+), 53 deletions(-) diff --git a/config/pubsub.go b/config/pubsub.go index ba8084300..36f9a9881 100644 --- a/config/pubsub.go +++ b/config/pubsub.go @@ -1,5 +1,24 @@ package config +const ( + // LastSeenMessagesStrategy is a strategy that calculates the TTL countdown + // based on the last time a Pubsub message is seen. This means that if a message + // is received and then seen again within the specified TTL window, it + // won't be emitted until the TTL countdown expires from the last time the + // message was seen. + LastSeenMessagesStrategy = "last-seen" + + // FirstSeenMessagesStrategy is a strategy that calculates the TTL + // countdown based on the first time a Pubsub message is seen. This means that if + // a message is received and then seen again within the specified TTL + // window, it won't be emitted. + FirstSeenMessagesStrategy = "first-seen" + + // DefaultSeenMessagesStrategy is the strategy that is used by default if + // no Pubsub.SeenMessagesStrategy is specified. + DefaultSeenMessagesStrategy = LastSeenMessagesStrategy +) + type PubsubConfig struct { // Router can be either floodsub (legacy) or gossipsub (new and // backwards compatible). @@ -12,7 +31,11 @@ type PubsubConfig struct { // Enable pubsub (--enable-pubsub-experiment) Enabled Flag `json:",omitempty"` - // SeenMessagesTTL configures the duration after which a previously seen - // message ID can be forgotten about. + // SeenMessagesTTL is a value that controls the time window within which + // duplicate messages will be identified and won't be emitted. SeenMessagesTTL *OptionalDuration `json:",omitempty"` + + // SeenMessagesStrategy is a setting that determines how the time-to-live + // (TTL) countdown for deduplicating messages is calculated. + SeenMessagesStrategy *OptionalString `json:",omitempty"` } diff --git a/core/node/groups.go b/core/node/groups.go index aa650ddf5..e640feff1 100644 --- a/core/node/groups.go +++ b/core/node/groups.go @@ -11,6 +11,7 @@ import ( "github.com/ipfs/go-log" "github.com/ipfs/kubo/config" pubsub "github.com/libp2p/go-libp2p-pubsub" + "github.com/libp2p/go-libp2p-pubsub/timecache" "github.com/libp2p/go-libp2p/core/peer" "github.com/ipfs/kubo/core/node/libp2p" @@ -66,6 +67,18 @@ func LibP2P(bcfg *BuildCfg, cfg *config.Config) fx.Option { pubsub.WithSeenMessagesTTL(cfg.Pubsub.SeenMessagesTTL.WithDefault(pubsub.TimeCacheDuration)), ) + var seenMessagesStrategy timecache.Strategy + configSeenMessagesStrategy := cfg.Pubsub.SeenMessagesStrategy.WithDefault(config.DefaultSeenMessagesStrategy) + switch configSeenMessagesStrategy { + case config.LastSeenMessagesStrategy: + seenMessagesStrategy = timecache.Strategy_LastSeen + case config.FirstSeenMessagesStrategy: + seenMessagesStrategy = timecache.Strategy_FirstSeen + default: + return fx.Error(fmt.Errorf("unsupported Pubsub.SeenMessagesStrategy %q", configSeenMessagesStrategy)) + } + pubsubOptions = append(pubsubOptions, pubsub.WithSeenMessagesStrategy(seenMessagesStrategy)) + switch cfg.Pubsub.Router { case "": fallthrough diff --git a/docs/changelogs/v0.18.md b/docs/changelogs/v0.18.md index e51c6d3b5..376658fd9 100644 --- a/docs/changelogs/v0.18.md +++ b/docs/changelogs/v0.18.md @@ -1,5 +1,43 @@ # Kubo changelog v0.18 +## v0.18.1 + +This release includes improvements around Pubsub message deduplication, and more. + + + + +- [Overview](#overview) +- [🔦 Highlights](#-highlights) + - [New default Pubsub.SeenMessagesStrategy](#new-default-pubsubseenmessagesstrategy) +- [📝 Changelog](#-changelog) +- [👨‍👩‍👧‍👦 Contributors](#-contributors) + + + +### 🔦 Highlights + +#### New default `Pubsub.SeenMessagesStrategy` + +A new optional [`Pubsub.SeenMessagesStrategy`](../config.md#pubsubseenmessagesstrategy) configuration option has been added. + +This option allows you to choose between two different strategies for +deduplicating messages: `first-seen` and `last-seen`. + +When unset, the default strategy is `last-seen`, which calculates the +time-to-live (TTL) countdown based on the last time a message is seen. This +means that if a message is received and then seen again within the specified +TTL window based on the last time it was seen, it won't be emitted. + +If you prefer the old behavior, which calculates the TTL countdown based on the +first time a message is seen, you can set `Pubsub.SeenMessagesStrategy` to +`first-seen`. + +### 📝 Changelog + +### 👨‍👩‍👧‍👦 Contributors + + ## v0.18.0 ### Overview diff --git a/docs/config.md b/docs/config.md index da919d844..94d8094af 100644 --- a/docs/config.md +++ b/docs/config.md @@ -100,6 +100,7 @@ config file at runtime. - [`Pubsub.Router`](#pubsubrouter) - [`Pubsub.DisableSigning`](#pubsubdisablesigning) - [`Pubsub.SeenMessagesTTL`](#pubsubseenmessagesttl) + - [`Pubsub.SeenMessagesStrategy`](#pubsubseenmessagesstrategy) - [`Peering`](#peering) - [`Peering.Peers`](#peeringpeers) - [`Reprovider`](#reprovider) @@ -1206,8 +1207,8 @@ Type: `bool` ### `Pubsub.SeenMessagesTTL` -Configures the duration after which a previously seen Pubsub Message ID can be -forgotten about. +Controls the time window within which duplicate messages, identified by Message +ID, will be identified and won't be emitted again. A smaller value for this parameter means that Pubsub messages in the cache will be garbage collected sooner, which can result in a smaller cache. At the same @@ -1223,6 +1224,29 @@ Default: see `TimeCacheDuration` from [go-libp2p-pubsub](https://github.com/libp Type: `optionalDuration` +### `Pubsub.SeenMessagesStrategy` + +Determines how the time-to-live (TTL) countdown for deduplicating Pubsub +messages is calculated. + +The Pubsub seen messages cache is a LRU cache that keeps messages for up to a +specified time duration. After this duration has elapsed, expired messages will +be purged from the cache. + +The `last-seen` cache is a sliding-window cache. Every time a message is seen +again with the SeenMessagesTTL duration, its timestamp slides forward. This +keeps frequently occurring messages cached and prevents them from being +continually propagated, especially because of issues that might increase the +number of duplicate messages in the network. + +The `first-seen` cache will store new messages and purge them after the +SeenMessagesTTL duration, even if they are seen multiple times within this +duration. + +Default: `last-seen` (see [go-libp2p-pubsub](https://github.com/libp2p/go-libp2p-pubsub)) + +Type: `optionalString` + ## `Peering` Configures the peering subsystem. The peering subsystem configures Kubo to diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index edc684831..0a4a436d9 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -38,6 +38,7 @@ require ( github.com/docker/go-units v0.5.0 // indirect github.com/dustin/go-humanize v1.0.0 // indirect github.com/elastic/gosigar v0.14.2 // indirect + github.com/emirpasic/gods v1.18.1 // indirect github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5 // indirect github.com/flynn/noise v1.0.0 // indirect github.com/francoispqt/gojay v1.2.13 // indirect @@ -122,7 +123,7 @@ require ( github.com/libp2p/go-libp2p-asn-util v0.2.0 // indirect github.com/libp2p/go-libp2p-kad-dht v0.20.0 // indirect github.com/libp2p/go-libp2p-kbucket v0.5.0 // indirect - github.com/libp2p/go-libp2p-pubsub v0.8.2 // indirect + github.com/libp2p/go-libp2p-pubsub v0.8.3 // indirect github.com/libp2p/go-libp2p-pubsub-router v0.6.0 // indirect github.com/libp2p/go-libp2p-record v0.2.0 // indirect github.com/libp2p/go-libp2p-routing-helpers v0.6.0 // indirect @@ -180,7 +181,6 @@ require ( github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f // indirect github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 // indirect - github.com/whyrusleeping/timecache v0.0.0-20160911033111-cfcb2f1abfee // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/otel v1.7.0 // indirect go.opentelemetry.io/otel/exporters/jaeger v1.7.0 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index fa6c022f3..eb52ab5e8 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -198,6 +198,8 @@ github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaB github.com/elastic/gosigar v0.12.0/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= github.com/elastic/gosigar v0.14.2 h1:Dg80n8cr90OZ7x+bAax/QjoW/XqTI11RmA79ZwIm9/4= github.com/elastic/gosigar v0.14.2/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= +github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= +github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -773,8 +775,8 @@ 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-pnet v0.2.0/go.mod h1:Qqvq6JH/oMZGwqs3N1Fqhv8NVhrdYcO0BW4wssv21LA= -github.com/libp2p/go-libp2p-pubsub v0.8.2 h1:QLGUmkgKmwEVxVDYGsqc5t9CykOMY2Y21cXQHjR462I= -github.com/libp2p/go-libp2p-pubsub v0.8.2/go.mod h1:e4kT+DYjzPUYGZeWk4I+oxCSYTXizzXii5LDRRhjKSw= +github.com/libp2p/go-libp2p-pubsub v0.8.3 h1:T4+pcfcFm1K2v5oFyk68peSjVroaoM8zFygf6Y5WOww= +github.com/libp2p/go-libp2p-pubsub v0.8.3/go.mod h1:eje970FXxjhtFbVEoiae+VUw24ZoSlk67BsiZPLRzlw= github.com/libp2p/go-libp2p-pubsub-router v0.6.0 h1:D30iKdlqDt5ZmLEYhHELCMRj8b4sFAqrUcshIUvVP/s= github.com/libp2p/go-libp2p-pubsub-router v0.6.0/go.mod h1:FY/q0/RBTKsLA7l4vqC2cbRbOvyDotg8PJQ7j8FDudE= github.com/libp2p/go-libp2p-quic-transport v0.10.0/go.mod h1:RfJbZ8IqXIhxBRm5hqUEJqjiiY8xmEuq3HUDS993MkA= @@ -1284,8 +1286,6 @@ github.com/whyrusleeping/mdns v0.0.0-20180901202407-ef14215e6b30/go.mod h1:j4l84 github.com/whyrusleeping/mdns v0.0.0-20190826153040-b9b60ed33aa9/go.mod h1:j4l84WPFclQPj320J9gp0XwNKBb3U0zt5CBqjPp22G4= github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 h1:E9S12nwJwEOXe2d6gT6qxdvqMnNq+VnSsKPgm2ZZNds= github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7/go.mod h1:X2c0RVCI1eSUFI8eLcY3c0423ykwiUdxLJtkDvruhjI= -github.com/whyrusleeping/timecache v0.0.0-20160911033111-cfcb2f1abfee h1:lYbXeSvJi5zk5GLKVuid9TVjS9a0OmLIDKTfoZBL6Ow= -github.com/whyrusleeping/timecache v0.0.0-20160911033111-cfcb2f1abfee/go.mod h1:m2aV4LZI4Aez7dP5PMyVKEHhUyEJ/RjmPEDOpDvudHg= github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE= github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= diff --git a/go.mod b/go.mod index b837fa504..5120159fd 100644 --- a/go.mod +++ b/go.mod @@ -75,7 +75,7 @@ require ( github.com/libp2p/go-libp2p-http v0.4.0 github.com/libp2p/go-libp2p-kad-dht v0.20.0 github.com/libp2p/go-libp2p-kbucket v0.5.0 - github.com/libp2p/go-libp2p-pubsub v0.8.2 + github.com/libp2p/go-libp2p-pubsub v0.8.3 github.com/libp2p/go-libp2p-pubsub-router v0.6.0 github.com/libp2p/go-libp2p-record v0.2.0 github.com/libp2p/go-libp2p-routing-helpers v0.6.0 @@ -133,6 +133,7 @@ require ( github.com/dgraph-io/ristretto v0.0.2 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/elastic/gosigar v0.14.2 // indirect + github.com/emirpasic/gods v1.18.1 // indirect github.com/felixge/httpsnoop v1.0.2 // indirect github.com/flynn/noise v1.0.0 // indirect github.com/francoispqt/gojay v1.2.13 // indirect @@ -223,7 +224,6 @@ require ( github.com/whyrusleeping/cbor-gen v0.0.0-20221220214510-0333c149dec0 // indirect github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f // indirect github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect - github.com/whyrusleeping/timecache v0.0.0-20160911033111-cfcb2f1abfee // indirect go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.7.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.7.0 // indirect go.opentelemetry.io/otel/metric v0.30.0 // indirect diff --git a/go.sum b/go.sum index 6274ef85b..e044b9a00 100644 --- a/go.sum +++ b/go.sum @@ -206,6 +206,8 @@ github.com/elastic/gosigar v0.14.2 h1:Dg80n8cr90OZ7x+bAax/QjoW/XqTI11RmA79ZwIm9/ github.com/elastic/gosigar v0.14.2/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/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= +github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -807,8 +809,8 @@ 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-pnet v0.2.0/go.mod h1:Qqvq6JH/oMZGwqs3N1Fqhv8NVhrdYcO0BW4wssv21LA= -github.com/libp2p/go-libp2p-pubsub v0.8.2 h1:QLGUmkgKmwEVxVDYGsqc5t9CykOMY2Y21cXQHjR462I= -github.com/libp2p/go-libp2p-pubsub v0.8.2/go.mod h1:e4kT+DYjzPUYGZeWk4I+oxCSYTXizzXii5LDRRhjKSw= +github.com/libp2p/go-libp2p-pubsub v0.8.3 h1:T4+pcfcFm1K2v5oFyk68peSjVroaoM8zFygf6Y5WOww= +github.com/libp2p/go-libp2p-pubsub v0.8.3/go.mod h1:eje970FXxjhtFbVEoiae+VUw24ZoSlk67BsiZPLRzlw= github.com/libp2p/go-libp2p-pubsub-router v0.6.0 h1:D30iKdlqDt5ZmLEYhHELCMRj8b4sFAqrUcshIUvVP/s= github.com/libp2p/go-libp2p-pubsub-router v0.6.0/go.mod h1:FY/q0/RBTKsLA7l4vqC2cbRbOvyDotg8PJQ7j8FDudE= github.com/libp2p/go-libp2p-quic-transport v0.10.0/go.mod h1:RfJbZ8IqXIhxBRm5hqUEJqjiiY8xmEuq3HUDS993MkA= @@ -1343,8 +1345,6 @@ github.com/whyrusleeping/mdns v0.0.0-20180901202407-ef14215e6b30/go.mod h1:j4l84 github.com/whyrusleeping/mdns v0.0.0-20190826153040-b9b60ed33aa9/go.mod h1:j4l84WPFclQPj320J9gp0XwNKBb3U0zt5CBqjPp22G4= github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 h1:E9S12nwJwEOXe2d6gT6qxdvqMnNq+VnSsKPgm2ZZNds= github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7/go.mod h1:X2c0RVCI1eSUFI8eLcY3c0423ykwiUdxLJtkDvruhjI= -github.com/whyrusleeping/timecache v0.0.0-20160911033111-cfcb2f1abfee h1:lYbXeSvJi5zk5GLKVuid9TVjS9a0OmLIDKTfoZBL6Ow= -github.com/whyrusleeping/timecache v0.0.0-20160911033111-cfcb2f1abfee/go.mod h1:m2aV4LZI4Aez7dP5PMyVKEHhUyEJ/RjmPEDOpDvudHg= github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE= github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= diff --git a/test/integration/pubsub_msg_seen_cache_test.go b/test/integration/pubsub_msg_seen_cache_test.go index 394cda5b1..749508089 100644 --- a/test/integration/pubsub_msg_seen_cache_test.go +++ b/test/integration/pubsub_msg_seen_cache_test.go @@ -22,6 +22,7 @@ import ( "github.com/libp2p/go-libp2p-pubsub" "github.com/libp2p/go-libp2p-pubsub/pb" + "github.com/libp2p/go-libp2p-pubsub/timecache" "github.com/libp2p/go-libp2p/core/peer" mock "github.com/ipfs/kubo/core/mock" @@ -76,7 +77,6 @@ func RunMessageSeenCacheTTLTest(t *testing.T, seenMessagesCacheTTL string) error var bootstrapNode, consumerNode, producerNode *core.IpfsNode var bootstrapPeerID, consumerPeerID, producerPeerID peer.ID - sendDupMsg := false mn := mocknet.New() bootstrapNode, err := mockNode(ctx, mn, false, "") // no need for PubSub configuration @@ -98,6 +98,12 @@ func RunMessageSeenCacheTTLTest(t *testing.T, seenMessagesCacheTTL string) error t.Fatal(err) } + // Used for logging the timeline + startTime := time.Time{} + + // Used for overriding the message ID + sendMsgID := "" + // Set up the pubsub message ID generation override for the producer core.RegisterFXOptionFunc(func(info core.FXNodeInfo) ([]fx.Option, error) { var pubsubOptions []pubsub.Option @@ -105,19 +111,23 @@ func RunMessageSeenCacheTTLTest(t *testing.T, seenMessagesCacheTTL string) error pubsubOptions, pubsub.WithSeenMessagesTTL(ttl), pubsub.WithMessageIdFn(func(pmsg *pubsub_pb.Message) string { - now := time.Now().Format(time.StampMilli) + now := time.Now() + if startTime.Second() == 0 { + startTime = now + } + timeElapsed := now.Sub(startTime).Seconds() msg := string(pmsg.Data) - var msgID string from, _ := peer.IDFromBytes(pmsg.From) - if (from == producerPeerID) && sendDupMsg { - msgID = "DupMsg" - t.Logf("sending [%s] with duplicate message ID at [%s]", msg, now) + var msgID string + if from == producerPeerID { + msgID = sendMsgID + t.Logf("sending [%s] with message ID [%s] at T%fs", msg, msgID, timeElapsed) } else { msgID = pubsub.DefaultMsgIdFn(pmsg) - t.Logf("sending [%s] with unique message ID at [%s]", msg, now) } return msgID }), + pubsub.WithSeenMessagesStrategy(timecache.Strategy_LastSeen), ) return append( info.FXOptions, @@ -165,8 +175,8 @@ func RunMessageSeenCacheTTLTest(t *testing.T, seenMessagesCacheTTL string) error t.Fatal(err) } // Utility functions defined inline to include context in closure - now := func() string { - return time.Now().Format(time.StampMilli) + now := func() float64 { + return time.Since(startTime).Seconds() } ctr := 0 msgGen := func() string { @@ -188,57 +198,87 @@ func RunMessageSeenCacheTTLTest(t *testing.T, seenMessagesCacheTTL string) error msg, err := consumerSubscription.Next(rxCtx) if shouldFind { if err != nil { - t.Logf("did not receive [%s] by [%s]", msgTxt, now()) + t.Logf("expected but did not receive [%s] at T%fs", msgTxt, now()) t.Fatal(err) } - t.Logf("received [%s] at [%s]", string(msg.Data()), now()) + t.Logf("received [%s] at T%fs", string(msg.Data()), now()) if !bytes.Equal(msg.Data(), []byte(msgTxt)) { t.Fatalf("consumed data [%s] does not match published data [%s]", string(msg.Data()), msgTxt) } } else { if err == nil { - t.Logf("received [%s] at [%s]", string(msg.Data()), now()) + t.Logf("not expected but received [%s] at T%fs", string(msg.Data()), now()) t.Fail() } - t.Logf("did not receive [%s] by [%s]", msgTxt, now()) + t.Logf("did not receive [%s] at T%fs", msgTxt, now()) } } - // Send message 1 with the message ID we're going to duplicate later - sendDupMsg = true + const MsgID1 = "MsgID1" + const MsgID2 = "MsgID2" + const MsgID3 = "MsgID3" + + // Send message 1 with the message ID we're going to duplicate + sentMsg1 := time.Now() + sendMsgID = MsgID1 msgTxt := produceMessage() - consumeMessage(msgTxt, true) // should find message + // Should find the message because it's new + consumeMessage(msgTxt, true) - // Send message 2 with the same message ID as before - sendDupMsg = true + // Send message 2 with a duplicate message ID + sendMsgID = MsgID1 msgTxt = produceMessage() - consumeMessage(msgTxt, false) // should NOT find message, because it got deduplicated (sent twice within the SeenMessagesTTL window) - - // Wait for seen cache TTL time to let seen cache entries time out - time.Sleep(ttl) + // Should NOT find message because it got deduplicated (sent 2 times within the SeenMessagesTTL window). + consumeMessage(msgTxt, false) // Send message 3 with a new message ID - // - // This extra step is necessary for testing the cache TTL because the PubSub code only garbage collects when a - // message ID was not already present in the cache. This means that message 2's cache entry, even though it has - // technically timed out, will still cause the message to be considered duplicate. When a message with a different - // ID passes through, it will be added to the cache and garbage collection will clean up message 2's entry. This is - // another bug in the pubsub/cache implementation that will be fixed once the code is refactored for this issue: - // https://github.com/libp2p/go-libp2p-pubsub/issues/502 - sendDupMsg = false + sendMsgID = MsgID2 msgTxt = produceMessage() - consumeMessage(msgTxt, true) // should find message + // Should find the message because it's new + consumeMessage(msgTxt, true) - // Send message 4 with the same message ID as before - sendDupMsg = true + // Wait till just before the SeenMessagesTTL window has passed since message 1 was sent + time.Sleep(time.Until(sentMsg1.Add(ttl - 100*time.Millisecond))) + + // Send message 4 with a duplicate message ID + sendMsgID = MsgID1 msgTxt = produceMessage() - consumeMessage(msgTxt, true) // should find message again (time since the last read > SeenMessagesTTL, so it looks like a new message). + // Should NOT find the message because it got deduplicated (sent 3 times within the SeenMessagesTTL window). This + // time, however, the expiration for the message should also get pushed out for a whole SeenMessagesTTL window since + // the default time cache now implements a sliding window algorithm. + consumeMessage(msgTxt, false) - // Send message 5 with a new message ID + // Send message 5 with a duplicate message ID. This will be a second after the last attempt above since NOT finding + // a message takes a second to determine. That would put this attempt at ~1 second after the SeenMessagesTTL window + // starting at message 1 has expired. + sentMsg5 := time.Now() + sendMsgID = MsgID1 + msgTxt = produceMessage() + // Should NOT find the message, because it got deduplicated (sent 2 times since the updated SeenMessagesTTL window + // started). This time again, the expiration should get pushed out for another SeenMessagesTTL window. + consumeMessage(msgTxt, false) + + // Send message 6 with a message ID that hasn't been seen within a SeenMessagesTTL window + sendMsgID = MsgID2 + msgTxt = produceMessage() + // Should find the message since last read > SeenMessagesTTL, so it looks like a new message. + consumeMessage(msgTxt, true) + + // Sleep for a full SeenMessagesTTL window to let cache entries time out + time.Sleep(time.Until(sentMsg5.Add(ttl + 100*time.Millisecond))) + + // Send message 7 with a duplicate message ID + sendMsgID = MsgID1 + msgTxt = produceMessage() + // Should find the message this time since last read > SeenMessagesTTL, so it looks like a new message. + consumeMessage(msgTxt, true) + + // Send message 8 with a brand new message ID // // This step is not strictly necessary, but has been added for good measure. - sendDupMsg = false + sendMsgID = MsgID3 msgTxt = produceMessage() - consumeMessage(msgTxt, true) // should find message + // Should find the message because it's new + consumeMessage(msgTxt, true) return nil } From bcac3f5677ef2a1b2695ad08a9b30c1c31ed51b7 Mon Sep 17 00:00:00 2001 From: Antonio Navarro Perez Date: Fri, 27 Jan 2023 16:47:00 +0100 Subject: [PATCH 0446/1212] Adjust inbound connection limits depending on memory. --- core/node/libp2p/rcmgr_defaults.go | 71 +++++++++++++----------------- docs/changelogs/v0.18.md | 36 ++++++++++----- docs/config.md | 2 +- docs/libp2p-resource-management.md | 4 +- 4 files changed, 56 insertions(+), 57 deletions(-) diff --git a/core/node/libp2p/rcmgr_defaults.go b/core/node/libp2p/rcmgr_defaults.go index 4d578a9b6..9a3825108 100644 --- a/core/node/libp2p/rcmgr_defaults.go +++ b/core/node/libp2p/rcmgr_defaults.go @@ -44,17 +44,18 @@ var noLimitIncrease = rcmgr.BaseLimitIncrease{ // This file defines implicit limit defaults used when Swarm.ResourceMgr.Enabled // createDefaultLimitConfig creates LimitConfig to pass to libp2p's resource manager. -// The defaults follow the documentation in docs/config.md. +// The defaults follow the documentation in docs/libp2p-resource-management.md. // Any changes in the logic here should be reflected there. func createDefaultLimitConfig(cfg config.SwarmConfig) (rcmgr.LimitConfig, error) { - maxMemoryDefaultString := humanize.Bytes(uint64(memory.TotalMemory()) / 4) + maxMemoryDefaultString := humanize.Bytes(uint64(memory.TotalMemory()) / 2) maxMemoryString := cfg.ResourceMgr.MaxMemory.WithDefault(maxMemoryDefaultString) maxMemory, err := humanize.ParseBytes(maxMemoryString) if err != nil { return rcmgr.LimitConfig{}, err } - numFD := cfg.ResourceMgr.MaxFileDescriptors.WithDefault(int64(fd.GetNumFDs()) / 2) + maxMemoryMB := maxMemory / (1024 * 1024) + maxFD := int(cfg.ResourceMgr.MaxFileDescriptors.WithDefault(int64(fd.GetNumFDs()) / 2)) // We want to see this message on startup, that's why we are using fmt instead of log. fmt.Printf(` @@ -65,65 +66,53 @@ Computing default go-libp2p Resource Manager limits based on: Applying any user-supplied overrides on top. Run 'ipfs swarm limit all' to see the resulting limits. -`, maxMemoryString, numFD) +`, maxMemoryString, maxFD) + + // At least as of 2023-01-25, it's possible to open a connection that + // doesn't ask for any memory usage with the libp2p Resource Manager/Accountant + // (see https://github.com/libp2p/go-libp2p/issues/2010#issuecomment-1404280736). + // As a result, we can't curretly rely on Memory limits to full protect us. + // Until https://github.com/libp2p/go-libp2p/issues/2010 is addressed, + // we take a proxy now of restricting to 1 inbound connection per MB. + // Note: this is more generous than go-libp2p's default autoscaled limits which do + // 64 connections per 1GB + // (see https://github.com/libp2p/go-libp2p/blob/master/p2p/host/resource-manager/limit_defaults.go#L357 ). + systemConnsInbound := int(1 * maxMemoryMB) scalingLimitConfig := rcmgr.ScalingLimitConfig{ SystemBaseLimit: rcmgr.BaseLimit{ Memory: int64(maxMemory), - FD: int(numFD), + FD: maxFD, // By default, we just limit connections on the inbound side. Conns: bigEnough, - ConnsInbound: rcmgr.DefaultLimits.SystemBaseLimit.ConnsInbound, // same as libp2p default + ConnsInbound: systemConnsInbound, ConnsOutbound: bigEnough, - // We limit streams since they not only take up memory and CPU. - // The Memory limit protects us on the memory side, - // but a StreamsInbound limit helps protect against unbound CPU consumption from stream processing. Streams: bigEnough, - StreamsInbound: rcmgr.DefaultLimits.SystemBaseLimit.StreamsInbound, + StreamsInbound: bigEnough, StreamsOutbound: bigEnough, }, - // Most limits don't see an increase because they're already infinite/bigEnough or at their max value. - // The values that should scale based on the amount of memory allocated to libp2p need to increase accordingly. - SystemLimitIncrease: rcmgr.BaseLimitIncrease{ - Memory: 0, - FDFraction: 0, - - Conns: 0, - ConnsInbound: rcmgr.DefaultLimits.SystemLimitIncrease.ConnsInbound, - ConnsOutbound: 0, - - Streams: 0, - StreamsInbound: rcmgr.DefaultLimits.SystemLimitIncrease.StreamsInbound, - StreamsOutbound: 0, - }, + SystemLimitIncrease: noLimitIncrease, + // Transient connections won't cause any memory to accounted for by the resource manager. + // Only established connections do. + // As a result, we can't rely on System.Memory to protect us from a bunch of transient connection being opened. + // We limit the same values as the System scope, but only allow the Transient scope to take 25% of what is allowed for the System scope. TransientBaseLimit: rcmgr.BaseLimit{ - Memory: rcmgr.DefaultLimits.TransientBaseLimit.Memory, - FD: rcmgr.DefaultLimits.TransientBaseLimit.FD, + Memory: int64(maxMemory / 4), + FD: maxFD / 4, Conns: bigEnough, - ConnsInbound: rcmgr.DefaultLimits.TransientBaseLimit.ConnsInbound, + ConnsInbound: systemConnsInbound / 4, ConnsOutbound: bigEnough, Streams: bigEnough, - StreamsInbound: rcmgr.DefaultLimits.TransientBaseLimit.StreamsInbound, + StreamsInbound: bigEnough, StreamsOutbound: bigEnough, }, - TransientLimitIncrease: rcmgr.BaseLimitIncrease{ - Memory: rcmgr.DefaultLimits.TransientLimitIncrease.Memory, - FDFraction: rcmgr.DefaultLimits.TransientLimitIncrease.FDFraction, - - Conns: 0, - ConnsInbound: rcmgr.DefaultLimits.TransientLimitIncrease.ConnsInbound, - ConnsOutbound: 0, - - Streams: 0, - StreamsInbound: rcmgr.DefaultLimits.TransientLimitIncrease.StreamsInbound, - StreamsOutbound: 0, - }, + TransientLimitIncrease: noLimitIncrease, // Lets get out of the way of the allow list functionality. // If someone specified "Swarm.ResourceMgr.Allowlist" we should let it go through. @@ -184,7 +173,7 @@ Run 'ipfs swarm limit all' to see the resulting limits. // Whatever limits libp2p has specifically tuned for its protocols/services we'll apply. libp2p.SetDefaultServiceLimits(&scalingLimitConfig) - defaultLimitConfig := scalingLimitConfig.Scale(int64(maxMemory), int(numFD)) + defaultLimitConfig := scalingLimitConfig.Scale(int64(maxMemory), maxFD) // Simple checks to overide autoscaling ensuring limits make sense versus the connmgr values. // There are ways to break this, but this should catch most problems already. diff --git a/docs/changelogs/v0.18.md b/docs/changelogs/v0.18.md index 376658fd9..a9d9e0301 100644 --- a/docs/changelogs/v0.18.md +++ b/docs/changelogs/v0.18.md @@ -2,14 +2,14 @@ ## v0.18.1 -This release includes improvements around Pubsub message deduplication, and more. - +This release includes improvements around Pubsub message deduplication, libp2p resource management, and more. - [Overview](#overview) - [🔦 Highlights](#-highlights) - [New default Pubsub.SeenMessagesStrategy](#new-default-pubsubseenmessagesstrategy) + - [Improving libp2p resource management integration](#improving-libp2p-resource-management-integration) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -33,11 +33,24 @@ If you prefer the old behavior, which calculates the TTL countdown based on the first time a message is seen, you can set `Pubsub.SeenMessagesStrategy` to `first-seen`. +#### Improving libp2p resource management integration + +This builds on the default protection nodes get against DoS (resource exhaustion) and eclipse attacks +with the [go-libp2p Network Resource Manager/Accountant](https://github.com/ipfs/kubo/blob/master/docs/libp2p-resource-management.md) +that was fine-tuned in [Kubo 0.18](https://github.com/ipfs/kubo/blob/biglep/resource-manager-example-of-what-want/docs/changelogs/v0.18.md#improving-libp2p-resource-management-integration). + +Adding default hard-limits from the Resource Manager/Accountant after the fact is tricky, +and some additional improvements have been made to improve the [computed defaults](https://github.com/ipfs/kubo/blob/master/docs/libp2p-resource-management.md#computed-default-limits). +As much as possible, the aim is for a user to only think about how much memory they want to bound libp2p to, +and not need to think about translating that to hard numbers for connections, streams, etc. +More updates are likely in future Kubo releases, but with this release: +1. ``System.StreamsInbound`` is no longer bounded directly +2. ``System.ConnsInbound``, ``Transient.Memory``, ``Transiet.ConnsInbound`` have higher default computed values. + ### 📝 Changelog ### 👨‍👩‍👧‍👦 Contributors - ## v0.18.0 ### Overview @@ -46,22 +59,21 @@ Below is an outline of all that is in this release, so you get a sense of all th -- [Overview](#overview) -- [🔦 Highlights](#-highlights) - - [Content routing](#content-routing) + - [🔦 Highlights](#-highlights) + - [Content routing](#content-routing) - [Default InterPlanetary Network Indexer](#default-interplanetary-network-indexer) - [Increase provider record republish interval and expiration](#increase-provider-record-republish-interval-and-expiration) - - [Gateways](#gateways) - - [DAG-JSON and DAG-CBOR response formats](#dag-json-and-dag-cbor-response-formats) + - [Gateways](#gateways) + - [(DAG-)JSON and (DAG-)CBOR response formats](#dag-json-and-dag-cbor-response-formats) - [🐎 Fast directory listings with DAG sizes](#-fast-directory-listings-with-dag-sizes) - - [QUIC and WebTransport](#quic-and-webtransport) + - [QUIC and WebTransport](#quic-and-webtransport) - [WebTransport enabled by default](#webtransport-enabled-by-default) - [QUIC and WebTransport share a single port](#quic-and-webtransport-share-a-single-port) - [Differentiating QUIC versions](#differentiating-quic-versions) - [QUICv1 and WebTransport config migration](#quicv1-and-webtransport-config-migration) - - [Improving libp2p resource management integration](#improving-libp2p-resource-management-integration) -- [📝 Changelog](#-changelog) -- [👨‍👩‍👧‍👦 Contributors](#-contributors) + - [Improving libp2p resource management integration](#improving-libp2p-resource-management-integration) + - [📝 Changelog](#-changelog) + - [👨‍👩‍👧‍👦 Contributors](#-contributors) diff --git a/docs/config.md b/docs/config.md index 94d8094af..995872c4f 100644 --- a/docs/config.md +++ b/docs/config.md @@ -1843,7 +1843,7 @@ This value is also used to scale the limit on various resources at various scope when the default limits (discussed in [libp2p resource management](./libp2p-resource-management.md)) are used. For example, increasing this value will increase the default limit for incoming connections. -Default: `[TOTAL_SYSTEM_MEMORY]/4` +Default: `[TOTAL_SYSTEM_MEMORY]/2` Type: `optionalBytes` #### `Swarm.ResourceMgr.MaxFileDescriptors` diff --git a/docs/libp2p-resource-management.md b/docs/libp2p-resource-management.md index d6b782da1..7924849d8 100644 --- a/docs/libp2p-resource-management.md +++ b/docs/libp2p-resource-management.md @@ -70,8 +70,7 @@ The reason these scopes are chosen is because: Within these scopes, limits are just set on [memory](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#memory), -[file descriptors (FD)](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#file-descriptors), [*inbound* connections](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#connections), -and [*inbound* streams](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#streams). +[file descriptors (FD)](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#file-descriptors), and [*inbound* connections](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#connections). Limits are set based on the `Swarm.ResourceMgr.MaxMemory` and `Swarm.ResourceMgr.MaxFileDescriptors` inputs above. There are also some special cases where minimum values are enforced. @@ -89,7 +88,6 @@ These become the [active limits](#how-does-one-see-the-active-limits). While `Swarm.ResourceMgr.Limits` can be edited directly, it is also possible to use `ipfs swarm limit` command to inspect and tweak specific limits at runtime. - To see all resources that are close to hitting their respective limit: ```console From 9c1a803f1991e3064f033cb2df26b0f09bbacb0f Mon Sep 17 00:00:00 2001 From: Antonio Navarro Perez Date: Fri, 27 Jan 2023 16:49:55 +0100 Subject: [PATCH 0447/1212] Add overview section --- docs/changelogs/v0.18.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/changelogs/v0.18.md b/docs/changelogs/v0.18.md index a9d9e0301..eda531614 100644 --- a/docs/changelogs/v0.18.md +++ b/docs/changelogs/v0.18.md @@ -59,6 +59,7 @@ Below is an outline of all that is in this release, so you get a sense of all th + - [Overview](#overview) - [🔦 Highlights](#-highlights) - [Content routing](#content-routing) - [Default InterPlanetary Network Indexer](#default-interplanetary-network-indexer) From 505f072d2871c7a27011bd2279b5d3880756abc1 Mon Sep 17 00:00:00 2001 From: galargh Date: Mon, 30 Jan 2023 12:53:20 +0100 Subject: [PATCH 0448/1212] docs: add full v0.18.1 changelog --- docs/changelogs/v0.18.md | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/docs/changelogs/v0.18.md b/docs/changelogs/v0.18.md index eda531614..352077e65 100644 --- a/docs/changelogs/v0.18.md +++ b/docs/changelogs/v0.18.md @@ -41,15 +41,33 @@ that was fine-tuned in [Kubo 0.18](https://github.com/ipfs/kubo/blob/biglep/reso Adding default hard-limits from the Resource Manager/Accountant after the fact is tricky, and some additional improvements have been made to improve the [computed defaults](https://github.com/ipfs/kubo/blob/master/docs/libp2p-resource-management.md#computed-default-limits). -As much as possible, the aim is for a user to only think about how much memory they want to bound libp2p to, +As much as possible, the aim is for a user to only think about how much memory they want to bound libp2p to, and not need to think about translating that to hard numbers for connections, streams, etc. -More updates are likely in future Kubo releases, but with this release: +More updates are likely in future Kubo releases, but with this release: 1. ``System.StreamsInbound`` is no longer bounded directly 2. ``System.ConnsInbound``, ``Transient.Memory``, ``Transiet.ConnsInbound`` have higher default computed values. -### 📝 Changelog +### Changelog -### 👨‍👩‍👧‍👦 Contributors +
Full Changelog + +- github.com/ipfs/kubo: + - Add overview section + - Adjust inbound connection limits depending on memory. + - feat: Pubsub.SeenMessagesStrategy (#9543) ([ipfs/kubo#9543](https://github.com/ipfs/kubo/pull/9543)) + - chore: update version +- github.com/libp2p/go-libp2p-pubsub (v0.8.2 -> v0.8.3): + - feat: expire messages from the cache based on last seen time (#513) ([libp2p/go-libp2p-pubsub#513](https://github.com/libp2p/go-libp2p-pubsub/pull/513)) + +
+ +### Contributors + +| Contributor | Commits | Lines ± | Files Changed | +|-------------|---------|---------|---------------| +| Mohsin Zaidi | 2 | +511/-55 | 12 | +| Antonio Navarro Perez | 2 | +57/-57 | 5 | +| galargh | 1 | +1/-1 | 1 | ## v0.18.0 From 6819d9a64d42e077033738dea54f26ccd3515739 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Tue, 31 Jan 2023 01:42:40 +0100 Subject: [PATCH 0449/1212] fix(ci): revert fix for bifrost-infra/issues/2300 (#9614) This reverts commit a9fdf26eeb94ef6d548aeb6dabb04ddce86df6ec. --- .circleci/main.yml | 4 ---- .github/workflows/build.yml | 2 -- 2 files changed, 6 deletions(-) diff --git a/.circleci/main.yml b/.circleci/main.yml index 9bf48ebea..6406c6655 100644 --- a/.circleci/main.yml +++ b/.circleci/main.yml @@ -228,8 +228,6 @@ jobs: - image: cimg/go:1.19.1-node parallelism: 4 resource_class: 2xlarge+ - environment: - GO_IPFS_DIST_URL: https://dist-ipfs-tech.ipns.cf-ipfs.com # TODO remove this line when https://github.com/protocol/bifrost-infra/issues/2300 is closed steps: - *make_out_dirs - attach_workspace: @@ -330,8 +328,6 @@ jobs: ipfs-webui: executor: node-browsers resource_class: 2xlarge+ - environment: - GO_IPFS_DIST_URL: https://dist-ipfs-tech.ipns.cf-ipfs.com # TODO remove this line when https://github.com/protocol/bifrost-infra/issues/2300 is closed steps: - *make_out_dirs - attach_workspace: diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 997067ad8..d0b4194b7 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -78,7 +78,6 @@ jobs: LIBP2P_TCP_REUSEPORT: false LIBP2P_ALLOW_WEAK_RSA_KEYS: 1 IPFS_GO_EXEC: ${{ github.workspace }}/cmd/ipfs/ipfs - GO_IPFS_DIST_URL: https://dist-ipfs-tech.ipns.cf-ipfs.com # TODO: remove this line when https://github.com/protocol/bifrost-infra/issues/2300 is closed working-directory: interop go-ipfs-api: needs: [prepare] @@ -162,7 +161,6 @@ jobs: TRAVIS: 1 GIT_PAGER: cat IPFS_CHECK_RCMGR_DEFAULTS: 1 - GO_IPFS_DIST_URL: https://dist-ipfs-tech.ipns.cf-ipfs.com # TODO: remove this line when https://github.com/protocol/bifrost-infra/issues/2300 is closed defaults: run: shell: bash From c1e1d5e04043f45065dd8a4960d1adcf1645ae01 Mon Sep 17 00:00:00 2001 From: galargh Date: Tue, 31 Jan 2023 10:30:26 +0100 Subject: [PATCH 0450/1212] chore: update after v0.18.1 --- bin/mkreleaselog | 4 ++-- docs/RELEASE_ISSUE_TEMPLATE.md | 29 +++++++++++++++-------------- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/bin/mkreleaselog b/bin/mkreleaselog index 1b31854a7..f53850c4c 100755 --- a/bin/mkreleaselog +++ b/bin/mkreleaselog @@ -261,7 +261,7 @@ recursive_release_log() { printf -- "Generating Changelog for %s %s..%s\n" "$module" "$start" "$end" >&2 - echo "### Changelog" + echo "### 📝 Changelog" echo echo "
Full Changelog" echo @@ -293,7 +293,7 @@ recursive_release_log() { echo echo "
" echo - echo "### Contributors" + echo "### 👨‍👩‍👧‍👦 Contributors" echo echo "| Contributor | Commits | Lines ± | Files Changed |" diff --git a/docs/RELEASE_ISSUE_TEMPLATE.md b/docs/RELEASE_ISSUE_TEMPLATE.md index c12e85057..4eadf9caa 100644 --- a/docs/RELEASE_ISSUE_TEMPLATE.md +++ b/docs/RELEASE_ISSUE_TEMPLATE.md @@ -60,22 +60,23 @@ This section covers tasks to be done ahead of the release. - ask the previous release owner (or @2color) for an invite - [ ] [access to #bifrost](https://filecoinproject.slack.com/archives/C03MMMF606T) channel in FIL Slack - ask the previous release owner for an invite - - [ ] [access to #shared-pl-marketing-requests](https://filecoinproject.slack.com/archives/C018EJ8LWH1) channel in FIL Slack + - [ ] ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) [access to #shared-pl-marketing-requests](https://filecoinproject.slack.com/archives/C018EJ8LWH1) channel in FIL Slack - ask the previous release owner for an invite - [ ] [access to IPFS network metrics](https://github.com/protocol/pldw/blob/624f47cf4ec14ad2cec6adf601a9f7b203ef770d/docs/sources/ipfs.md#ipfs-network-metrics) dashboards in Grafana - open an access request in the [pldw](https://github.com/protocol/pldw/issues/new/choose) - [example](https://github.com/protocol/pldw/issues/158) - - [ ] [npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) installed on your system (_only if you're not using [kuboreleaser](https://github.com/ipfs/kuboreleaser)_) - - [ ] [zsh](https://github.com/ohmyzsh/ohmyzsh/wiki/Installing-ZSH#install-and-set-up-zsh-as-default) installed on your system (_only if you're not using [kuboreleaser](https://github.com/ipfs/kuboreleaser)_) - - [ ] [kubo](https://github.com/ipfs/kubo) checked out under `$(go env GOPATH)/src/github.com/ipfs/kubo` (_only if you're not using [kuboreleaser](https://github.com/ipfs/kuboreleaser)_) + - [ ] [docker](https://docs.docker.com/get-docker/) installed on your system (_only if you're using [kuboreleaser](https://github.com/ipfs/kuboreleaser)_) + - [ ] [npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) installed on your system (_only if you're **NOT** using [kuboreleaser](https://github.com/ipfs/kuboreleaser)_) + - [ ] [zsh](https://github.com/ohmyzsh/ohmyzsh/wiki/Installing-ZSH#install-and-set-up-zsh-as-default) installed on your system + - [ ] [kubo](https://github.com/ipfs/kubo) checked out under `$(go env GOPATH)/src/github.com/ipfs/kubo` - you can also symlink your clone to the expected location by running `mkdir -p $(go env GOPATH)/src/github.com/ipfs && ln -s $(pwd) $(go env GOPATH)/src/github.com/ipfs/kubo` - - [ ] [Reddit](https://www.reddit.com) account -- [ ] Upgrade Go used in CI to the latest patch release available in [CircleCI](https://hub.docker.com/r/cimg/go/tags) - - [ ] [ipfs/distributions](https://github.com/ipfs/distributions) + - [ ] ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) [Reddit](https://www.reddit.com) account +- ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) Upgrade Go used in CI to the latest patch release available in [CircleCI](https://hub.docker.com/r/cimg/go/tags) in: + - [ ] ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) [ipfs/distributions](https://github.com/ipfs/distributions) - [example](https://github.com/ipfs/distributions/pull/756) - - [ ] [ipfs/ipfs-docs](https://github.com/ipfs/ipfs-docs) + - [ ] ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) [ipfs/ipfs-docs](https://github.com/ipfs/ipfs-docs) - [example](https://github.com/ipfs/ipfs-docs/pull/1298) -- [ ] Notify the bifrost team about the upcoming release
using `kuboreleaser release --version vX.Y.Z(-RCN) notify-bifrost --date YYYY-MM-DD` or ... +- [ ] Notify the bifrost team about the upcoming release
using `kuboreleaser release --version vX.Y.Z(-RCN) notify-bifrost --date YYYY-MM-DD` or ... (_only if it is not the day of the release yet_) - [ ] open an issue against [bifrost-infra](https://github.com/protocol/bifrost-infra) - [example](https://github.com/protocol/bifrost-infra/issues/2221)
@@ -103,7 +104,7 @@ This section covers tasks to be done during each release.
- [ ] Cherry-pick commits from `master` to the `release-vX.Y.Z` using `git cherry-pick -x ` - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Add full changelog and contributors to the [changelog](docs/changelogs/vX.Y.md) - - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Paste the stdout of `./bin/mkreleaselog` at the end of the [changelog](docs/changelogs/vX.Y.md) + - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Replace the `Changelog` and `Contributors` sections of the [changelog](docs/changelogs/vX.Y.md) with the stdout of `./bin/mkreleaselog` - do **NOT** copy the stderr - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Merge the PR from `release-vX.Y` to `release` using the `Create a merge commit` - do **NOT** use `Squash and merge` nor `Rebase and merge` because we need to be able to sign the merge commit @@ -122,7 +123,7 @@ This section covers tasks to be done during each release. - [ ] check out [ipfs/distributions](https://github.com/ipfs/distributions) - [ ] run `./dist.sh add-version kubo vX.Y.Z(-RCN)` to add the new version to the `versions` file - [usage](https://github.com/ipfs/distributions#usage) - - [ ] create and merge the PR which updates `dists/kubo/versions` and `dists/go-ipfs/versions` + - [ ] create and merge the PR which updates `dists/kubo/versions` and `dists/go-ipfs/versions` (![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) and `dists/kubo/current_version` and `dists/go-ipfs/current_version`) - [example](https://github.com/ipfs/distributions/pull/760) - [ ] wait for the [CI](https://github.com/ipfs/distributions/actions/workflows/main.yml) workflow run initiated by the merge to master to finish - [ ] verify the release is available on [dist.ipfs.io](https://dist.ipfs.io/#kubo) @@ -167,9 +168,9 @@ This section covers tasks to be done during each release. - [example](https://github.com/ipfs/kubo/issues/9319#issuecomment-1311002478) - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) create an issue comment linking to the release on the release issue - [example](https://github.com/ipfs/kubo/issues/9417#issuecomment-1400740975) - - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ask the marketing team to tweet about the release in [#shared-pl-marketing-requests](https://filecoinproject.slack.com/archives/C018EJ8LWH1) in FIL Slack + - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) ask the marketing team to tweet about the release in [#shared-pl-marketing-requests](https://filecoinproject.slack.com/archives/C018EJ8LWH1) in FIL Slack - [example](https://filecoinproject.slack.com/archives/C018EJ8LWH1/p1664885305374900) - - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) post the link to the [GitHub Release](https://github.com/ipfs/kubo/releases/tag/vX.Y.Z(-RCN)) to [Reddit](https://reddit.com/r/ipfs) + - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) post the link to the [GitHub Release](https://github.com/ipfs/kubo/releases/tag/vX.Y.Z(-RCN)) to [Reddit](https://reddit.com/r/ipfs) - [example](https://www.reddit.com/r/ipfs/comments/9x0q0k/kubo_v0160_release_is_out/)
- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Add the link to the [IPFS Discourse](https://discuss.ipfs.tech) topic to the [GitHub Release](https://github.com/ipfs/kubo/releases/tag/vX.Y.Z(-RCN)) description @@ -201,7 +202,7 @@ This section covers tasks to be done during each release. - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) merge the PR - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) verify the blog entry was published
-- [ ] Keep checking the [metrics](https://protocollabs.grafana.net/d/8zlhkKTZk/gateway-slis-precomputed?orgId=1) until the release issue is closed +- [ ] ![](https://img.shields.io/badge/only-RC-blue?style=flat-square) Keep checking the [metrics](https://protocollabs.grafana.net/d/8zlhkKTZk/gateway-slis-precomputed?orgId=1) until the release issue is closed - [release notes](https://www.notion.so/pl-strflt/Kubo-Gateway-Release-Notes-6e0efff28ee540be9ccb8f2b85104c42) - post in the [#bifrost](https://filecoinproject.slack.com/archives/C018EJ8LWH1) channel in FIL Slack if there is a problem - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Merge the [release](https://github.com/ipfs/kubo/tree/release) branch back into [master](https://github.com/ipfs/kubo/tree/master), ignoring the changes to [version.go](version.go) (keep the `-dev`) version,
using `kuboreleaser release --version vX.Y.Z(-RCN) merge-branch` or ... From 8d3b3154c914f0a0d4a9ec0997855253f4cae4ab Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Tue, 31 Jan 2023 11:02:31 +0100 Subject: [PATCH 0451/1212] refactor: use gateway from go-libipfs (#9588) --- assets/README.md | 10 - assets/assets.go | 36 +- assets/dag-index-html/README.md | 3 - assets/dag-index-html/index.go | 81 -- assets/dir-index-html/README.md | 26 - assets/dir-index-html/dir-index.html | 99 -- assets/dir-index-html/index.go | 1 - assets/dir-index-html/knownIcons.txt | 65 - assets/dir-index-html/package.json | 17 - assets/dir-index-html/src/dir-index.html | 98 -- assets/dir-index-html/src/icons.css | 403 ------ assets/dir-index-html/src/style.css | 212 ---- assets/dir-index-html/test/go.mod | 3 - assets/dir-index-html/test/main.go | 116 -- core/corehttp/gateway.go | 97 +- core/corehttp/gateway_handler.go | 1117 ----------------- core/corehttp/gateway_handler_block.go | 55 - core/corehttp/gateway_handler_car.go | 99 -- core/corehttp/gateway_handler_codec.go | 257 ---- core/corehttp/gateway_handler_ipns_record.go | 71 -- core/corehttp/gateway_handler_tar.go | 92 -- core/corehttp/gateway_handler_unixfs.go | 46 - .../gateway_handler_unixfs__redirects.go | 287 ----- core/corehttp/gateway_handler_unixfs_dir.go | 210 ---- core/corehttp/gateway_handler_unixfs_file.go | 104 -- core/corehttp/gateway_indexPage.go | 133 -- core/corehttp/gateway_test.go | 25 - core/corehttp/hostname.go | 7 +- core/corehttp/lazyseek.go | 60 - core/corehttp/lazyseek_test.go | 136 -- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 6 +- go.mod | 10 +- go.sum | 8 +- 34 files changed, 20 insertions(+), 3972 deletions(-) delete mode 100644 assets/dag-index-html/README.md delete mode 100644 assets/dag-index-html/index.go delete mode 100644 assets/dir-index-html/README.md delete mode 100644 assets/dir-index-html/dir-index.html delete mode 100644 assets/dir-index-html/index.go delete mode 100644 assets/dir-index-html/knownIcons.txt delete mode 100644 assets/dir-index-html/package.json delete mode 100644 assets/dir-index-html/src/dir-index.html delete mode 100644 assets/dir-index-html/src/icons.css delete mode 100644 assets/dir-index-html/src/style.css delete mode 100644 assets/dir-index-html/test/go.mod delete mode 100644 assets/dir-index-html/test/main.go delete mode 100644 core/corehttp/gateway_handler.go delete mode 100644 core/corehttp/gateway_handler_block.go delete mode 100644 core/corehttp/gateway_handler_car.go delete mode 100644 core/corehttp/gateway_handler_codec.go delete mode 100644 core/corehttp/gateway_handler_ipns_record.go delete mode 100644 core/corehttp/gateway_handler_tar.go delete mode 100644 core/corehttp/gateway_handler_unixfs.go delete mode 100644 core/corehttp/gateway_handler_unixfs__redirects.go delete mode 100644 core/corehttp/gateway_handler_unixfs_dir.go delete mode 100644 core/corehttp/gateway_handler_unixfs_file.go delete mode 100644 core/corehttp/gateway_indexPage.go delete mode 100644 core/corehttp/lazyseek.go delete mode 100644 core/corehttp/lazyseek_test.go diff --git a/assets/README.md b/assets/README.md index 02af2f19c..b342d0801 100644 --- a/assets/README.md +++ b/assets/README.md @@ -3,13 +3,3 @@ This directory contains the go-ipfs assets: * Getting started documentation (`init-doc`). -* Directory listing HTML template (`dir-index-html`). - -## Re-generating - -Edit the source files and use `go generate` from within the -assets directory: - -``` -go generate . -``` diff --git a/assets/assets.go b/assets/assets.go index 37cbbfad5..00792d511 100644 --- a/assets/assets.go +++ b/assets/assets.go @@ -1,30 +1,22 @@ -//go:generate npm run build --prefix ./dir-index-html/ package assets import ( "embed" "fmt" - "io" - "io/fs" gopath "path" - "strconv" "github.com/ipfs/kubo/core" "github.com/ipfs/kubo/core/coreapi" - "github.com/cespare/xxhash" cid "github.com/ipfs/go-cid" "github.com/ipfs/go-libipfs/files" options "github.com/ipfs/interface-go-ipfs-core/options" "github.com/ipfs/interface-go-ipfs-core/path" ) -//go:embed init-doc dir-index-html/dir-index.html dir-index-html/knownIcons.txt +//go:embed init-doc var Asset embed.FS -// AssetHash a non-cryptographic hash of all embedded assets -var AssetHash string - // initDocPaths lists the paths for the docs we want to seed during --init var initDocPaths = []string{ gopath.Join("init-doc", "about"), @@ -36,32 +28,6 @@ var initDocPaths = []string{ gopath.Join("init-doc", "ping"), } -func init() { - sum := xxhash.New() - err := fs.WalkDir(Asset, ".", func(path string, d fs.DirEntry, err error) error { - if err != nil { - return err - } - - if d.IsDir() { - return nil - } - - file, err := Asset.Open(path) - if err != nil { - return err - } - defer file.Close() - _, err = io.Copy(sum, file) - return err - }) - if err != nil { - panic("error creating asset sum: " + err.Error()) - } - - AssetHash = strconv.FormatUint(sum.Sum64(), 32) -} - // SeedInitDocs adds the list of embedded init documentation to the passed node, pins it and returns the root key func SeedInitDocs(nd *core.IpfsNode) (cid.Cid, error) { return addAssetList(nd, initDocPaths) diff --git a/assets/dag-index-html/README.md b/assets/dag-index-html/README.md deleted file mode 100644 index de38a9504..000000000 --- a/assets/dag-index-html/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# dag-index-html - -> HTML representation for non-UnixFS DAGs such as DAG-CBOR. diff --git a/assets/dag-index-html/index.go b/assets/dag-index-html/index.go deleted file mode 100644 index 214b06a38..000000000 --- a/assets/dag-index-html/index.go +++ /dev/null @@ -1,81 +0,0 @@ -package dagindexhtml - -import "html/template" - -// TODO: DagIndexTemplate - replace static CSS with shared one with ../dir-index-html - -// DagIndexTemplate is HTML-based template for non-UnixFS DAGs when request was -// made with Accept: text/html (web browsers). -var DagIndexTemplate = template.Must(template.New("redirect").Parse(` - - - - - - - - - - - - - - - - - - {{ .Path }} - - - - -
-
-

CID: {{.CID}}
- Codec: {{.CodecName}} ({{.CodecHex}})

-
-
- - - - - - - -
-

Preview as JSON
(application/json)

-
-

Or download as: -

-

-
-
-
- -`)) - -type DagIndexTemplateData struct { - Path string - CID string - CodecName string - CodecHex string -} diff --git a/assets/dir-index-html/README.md b/assets/dir-index-html/README.md deleted file mode 100644 index 3dd45eb59..000000000 --- a/assets/dir-index-html/README.md +++ /dev/null @@ -1,26 +0,0 @@ -# dir-index-html - -> Directory listing HTML for HTTP gateway - -![](https://user-images.githubusercontent.com/157609/88379209-ce6f0600-cda2-11ea-9620-20b9237bb441.png) - -## Updating - -When making updates to the directory listing page template, please note the following: - -1. Make your changes to the (human-friendly) source documents in the `src` directory and run `npm run build` -3. Before testing or releasing, go to the top-level `./assets` directory and make sure to run the `go generate .` script to update the bindata version - -## Testing - -1. Make sure you have [Go](https://golang.org/dl/) installed -2. Start the test server, which lives in its own directory: - -```bash -> cd test -> go run . -``` -This will listen on [`localhost:3000`](http://localhost:3000/) and reload the template every time you refresh the page. - -If you get a "no such file or directory" error upon trying `go run .`, make sure you ran `npm run build` to generate the minified artifact that the test is looking for. - diff --git a/assets/dir-index-html/dir-index.html b/assets/dir-index-html/dir-index.html deleted file mode 100644 index d861cb657..000000000 --- a/assets/dir-index-html/dir-index.html +++ /dev/null @@ -1,99 +0,0 @@ - -{{ $root := . }} - - - - - - - - - - - - - - - - - -{{ .Path }} - - - - -
-
-
- - Index of - {{ range .Breadcrumbs -}} - /{{ if .Path }}{{ .Name }}{{ else }}{{ .Name }}{{ end }} - {{- else }} - {{ .Path }} - {{ end }} - - {{ if .Hash }} -
- {{ .Hash }} -
- {{ end }} -
- {{ if .Size }} -
-  {{ .Size }} -
- {{ end }} -
-
- - {{ if .BackLink }} - - - - - - - {{ end }} - {{ range .Listing }} - - - - - - - {{ end }} -
-
 
-
- .. -
-
 
-
- {{ .Name }} - - {{ if .Hash }} - - {{ .ShortHash }} - - {{ end }} - {{ .Size }}
-
-
- - diff --git a/assets/dir-index-html/index.go b/assets/dir-index-html/index.go deleted file mode 100644 index 98933e3f6..000000000 --- a/assets/dir-index-html/index.go +++ /dev/null @@ -1 +0,0 @@ -package dirindexhtml diff --git a/assets/dir-index-html/knownIcons.txt b/assets/dir-index-html/knownIcons.txt deleted file mode 100644 index c110530ea..000000000 --- a/assets/dir-index-html/knownIcons.txt +++ /dev/null @@ -1,65 +0,0 @@ -.aac -.aiff -.ai -.avi -.bmp -.c -.cpp -.css -.dat -.dmg -.doc -.dotx -.dwg -.dxf -.eps -.exe -.flv -.gif -.h -.hpp -.html -.ics -.iso -.java -.jpg -.jpeg -.js -.key -.less -.mid -.mkv -.mov -.mp3 -.mp4 -.mpg -.odf -.ods -.odt -.otp -.ots -.ott -.pdf -.php -.png -.ppt -.psd -.py -.qt -.rar -.rb -.rtf -.sass -.scss -.sql -.tga -.tgz -.tiff -.txt -.wav -.wmv -.xls -.xlsx -.xml -.yml -.zip diff --git a/assets/dir-index-html/package.json b/assets/dir-index-html/package.json deleted file mode 100644 index 4b2427574..000000000 --- a/assets/dir-index-html/package.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "name": "dir-index-html", - "description": "Directory listing HTML for go-ipfs gateways", - "version": "1.3.0", - "private": true, - "homepage": "https://github.com/ipfs/go-ipfs", - "license": "MIT", - "scripts": { - "start": "cd test && go run .", - "build": "npm run build:clean && npm run build:remove-style-links && npm run build:minify-wrap-css && npm run build:combine-html-css && npm run build:remove-unused", - "build:clean": "rm dir-index.html", - "build:remove-style-links": "sed '/ ./base-html.html", - "build:minify-wrap-css": "(echo \"\") > ./minified-wrapped-style.html", - "build:combine-html-css": "sed '/<\\/title>/ r ./minified-wrapped-style.html' ./base-html.html > ./dir-index.html", - "build:remove-unused": "rm ./base-html.html && rm ./minified-wrapped-style.html" - } -} diff --git a/assets/dir-index-html/src/dir-index.html b/assets/dir-index-html/src/dir-index.html deleted file mode 100644 index 109c7afbf..000000000 --- a/assets/dir-index-html/src/dir-index.html +++ /dev/null @@ -1,98 +0,0 @@ - -{{ $root := . }} - - - - - - - - - - - - - - - - - - - -{{ .Path }} - - - -
-
-
- - Index of - {{ range .Breadcrumbs -}} - /{{ if .Path }}{{ .Name }}{{ else }}{{ .Name }}{{ end }} - {{- else }} - {{ .Path }} - {{ end }} - - {{ if .Hash }} -
- {{ .Hash }} -
- {{ end }} -
- {{ if .Size }} -
-  {{ .Size }} -
- {{ end }} -
-
- - {{ if .BackLink }} - - - - - - - {{ end }} - {{ range .Listing }} - - - - - - - {{ end }} -
-
 
-
- .. -
-
 
-
- {{ .Name }} - - {{ if .Hash }} - - {{ .ShortHash }} - - {{ end }} - {{ .Size }}
-
-
- - diff --git a/assets/dir-index-html/src/icons.css b/assets/dir-index-html/src/icons.css deleted file mode 100644 index dcdbd3cd9..000000000 --- a/assets/dir-index-html/src/icons.css +++ /dev/null @@ -1,403 +0,0 @@ -/* Source - fileicons.org */ - -.ipfs-_blank { - background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAWBJREFUeNqEUj1LxEAQnd1MVA4lyIEWx6UIKEGUExGsbC3tLfwJ/hT/g7VlCnubqxXBwg/Q4hQP/LhKL5nZuBsvuGfW5MGyuzM7jzdvVuR5DgYnZ+f99ai7Vt5t9K9unu4HLweI3qWYxI6PDosdy0fhcntxO44CcOBzPA7mfEyuHwf7ntQk4jcnywOxIlfxOCNYaLVgb6cXbkTdhJXq2SIlNMC0xIqhHczDbi8OVzpLSUa0WebRfmigLHqj1EcPZnwf7gbDIrYVRyEinurj6jTBHyI7pqVrFQqEbt6TEmZ9v1NRAJNC1xTYxIQh/MmRUlmFQE3qWOW1nqB2TWk1/3tgJV0waVvkFIEeZbHq4ElyKzAmEXOx6gnEVJuWBzmkRJBRPYGZBDsVaOlpSgVJE2yVaAe/0kx/3azBRO0VsbMFZE3CDSZKweZfYIVg+DZ6v7h9GDVOwZPw/PoxKu/fAgwALbDAXf7DdQkAAAAASUVORK5CYII=); - background-repeat:no-repeat; - background-size:contain -} - -.ipfs-_page { - background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAmhJREFUeNpsUztv01AYPfdhOy/XTZ80VV1VoCqlA2zQqUgwMEErWBALv4GJDfEDmOEHsFTqVCTExAiiSI2QEKJKESVFFBWo04TESRzfy2c7LY/kLtf2d8+555zvM9NaI1ora5svby9OnbUEBxgDlIKiWjXQeLy19/X17sEtcPY2rtHS96/Hu0RvXXLz+cUzM87zShsI29DpHCYt4E6Box4IZzTnbDx7V74GjhOSfwgE0H2638K9h08A3iHGVbjTw7g6YmAyw/BgecHNGGJjvfQhIfmfIFDAXJpjuugi7djIFVI4P0plctgJQ0xnFe5eOO02OwEp2VkhSCnC8WOCdqgwnzFx4/IyppwRVN+XYXsecqZA1pB48ekAnw9/4GZx3L04N/GoTwEjX4cNH5vlPfjtAIYp8cWrQutxrC5Mod3VsXVTMFSqtaE+gl9dhaUxE2tXZiF7nYiiatJ3v5s8R/1yOCNLOuwjkELiTbmC9dJHpIaGASsDkoFQGJQwHWMcHWJYOmUj1OjvQotuytt5nHMLEGkCyx6QU384jwkUAd2sxJbS/QShZtg/8rHzzQOzSaFhxQrA6YgQMQHojCUlgnCAAvKFBoXXaHfArSCZDE0gyWJgFIKmvUFKO4MUNIk2a4+hODtDUVuJ/J732AKS6ZtImdTyAQQB3bZN8l9t75IFh0JMUdVKsohsUPqRgnka0tYgggYpCHkKGTsHI5NOMojB4iTICCepvX53AIEfQta1iUCmoTiBmdEri2RgddKFhuJoqb/af/yw/d3zTNM6UkaOfis62aUgddAbnz+rXuPY+Vnzjt9/CzAAbmLjCrfBiRgAAAAASUVORK5CYII=); - background-repeat:no-repeat; - background-size:contain -} - -.ipfs-aac { - background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAnhJREFUeNp0Uk1PE0EYftruVlvAUkhVEPoBcsEoLRJBY01MPHjCs3cvogcT/4qJJN5NvHhoohcOnPw4YEGIkCh+oLGBKm3Z7nZ3dme2vjOhTcjiJJvZzPvOM8/HG2q325Dr3kLp7Y1ibpIxjs4KhQBZfvV6s7K5Vb0bjeof5ZlcGysP1a51mifODybvzE8mzCbrAoTDIThMoGXZiZ4YSiurf+Z1XeuCqJ7Oj+sK3jQcNAmg8xkGQ71mYejcAB49vpmeuzJccl0+dUj6KIAvfHCPg3N+uAv4vg9BOxcCmfEzuP/genpmeqhEMgude10Jwm+DuUIyUdTlqu2byoMfX/dRermBeExHsTiWNi3+lMpzRwDki8zxCIATmzbevfmClukiP5NFhJgwkjeRTeLShdOoVJqnAgwkgCAZ6+UdLC9twjQZ8pdzioFkZBHY3q6B3l4dJEEEPOCeD4cYVH7Xsf15F+FImC775INAJBJSkVoWo0QY9YqgiR4ZZzRaGBkdwK3bFxGLRZUfB3Rm2x4x9CGtsUxH9QYkKICDFuLxKAozGZwdTqBRs2FbLlXbiPdECMCHadj/AaDXZNFqedCIvnRcS4UpRo7+hC5zUmw8Ope9wUFinvpmZ7NKt2RTmB4hKZo6n8qP4Oq1HBkKlVYAQBrUlziB0XQSif4YmQhksgNIJk9iaLhPaV9b/Um+uJSCdzyDbGZQRSkvjo+n4JNxubGUSsCj+ZCpODYjkGMAND2k7exUsfhkCd+29yguB88Wl7FW/o6tT7/gcXqAgGv7hhx1LWBireHVn79YP6ChQ3njb/eFlfWqGqT3H3ZlGIhGI2i2UO/U/wkwAAmoalcxlNA1AAAAAElFTkSuQmCC); - background-repeat:no-repeat; - background-size:contain -} - -.ipfs-ai { - background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAk5JREFUeNpsU01vElEUPTPzZqBAQaSFQiJYUmlKYhoTF41L3Tbu/Q/+AvsX3Bp/gPsuWLrqyqQ7TUxMtAvF1tYGoXwNw7wv7zwYgtKX3Lw379575p5z77O01ohW+/DVh8zj7aYKhflGdG9ZsGwLNydffgVfr19YHvsEa+Zu/nxndob5StQK+dyzvZzyw/gKlmMj7IygFM+xvNcanp4/t5dAomXHBy2UUBOO2MAl/B9/cPb6PULuoHx0WM0e3GvpUOxD3wZAJWutZqYUYmqpSg5OMgH3YQObL59W0/ullpryR3HegkKEqiWBSGV4R3vQ7sIhScTZFTpHx3A215B5sluVY/WWMg7+ATB/lcLsKpTonHzD+OMFEuTz8ikkt9Kwt9YJZB38cpBdoQAZJdLvCGByfoPB6Xdk90pYy6Xg3c/DaWwArg09DaG5lCsUFN0pckZAojdC8m4auBqaALuSgez7VB1RtDSUWOQvUaBLFUzJBMJ2DwmPgd1Jwm0WoSgJfjDvrTKxtwAIyEkAOQ5hU//Zdg5uowDlUNMnwZLW0sSuUuACYhwQRwFvJxupCjEYUUccOkoaKmdOlZnY1TkgAcXAhxhOwLsDsHoN3u4O5JTDfVCH6I9nfjId3gIgSUATFJk/hVevGtOMwS0XwQ3AzB/FrlKg8Q27I2javVoZrFgwD4qVipAEyMlnaFArzaj/D0DiMXlJAFQyK2r8fnMMRZp4lQ1MaSL5tU/1kqAkMCh2tYI+7+kh70cjPbr4bEZ51jZr8TJnB9PJXpz3V4ABAPOQVJn2Q60GAAAAAElFTkSuQmCC); - background-repeat:no-repeat; - background-size:contain -} - -.ipfs-aiff { - background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAohJREFUeNpkU9tqE1EUXZmZpE3aTBLbJFPTtFURtSCthr7UCyKKFJ/9An3og6Ag/oXfoUj7og9asCBYKT6UIPHaWtpq7NU2aZK5z5wZ9xxMpMwZDuewz9prr32ZiO/7CNaDx3OLt6fOjBqGg/aKRCIInp8+KzfKH7fudnVF58nE16el+/yU2mBFSWZKpWJKVc0OgUBo02K4NDmU6o75Mx+Wdu9IUXFeiOA/pn1xHeYaugVDdzpbp91qGlAKGTx8dC19/Wpxhjnsxj/RRwk85hGJC9d1O6fneWAuoztDYSSLe9OT6SuXB2ccx73Z9uukwDwfls1g0xZIY/Ad/Gnyt/XVfbyYrSDRE8PExHB6/8B6QuaxIwRBFMt0iIAiMx+LCys8jfGJEUik2WpZOD2SQf9oDtVqQwopCAiY66FS/om3b75CVS2MlU7AJ2WiJBCZjZ2dJuRkDJZFwFAR7UCBja3fNfxY2YEoCtRCj9em3Tpds6FpJseGCBxS0GgYGBzqw62p84gnYnAI2CSbSbPhEpFAaE2zODaUAlWWwDoS5DheGqbWpVE/0CmqCY9qkEyINBceb2uADRNQ8bSWAVVzIFKomCQim+0luS4yKYlsHlRyZo7EsSEC23K5vAsXh/H92zZkuRvxeBS5nEx2yp2KqhxPoV5TYS/8CtdApylM9sZQKKSQzyeRTseRV2QoAzIYY8jme5DN9fI0dQoUIjANGydP9VM7PZw9p/AiBpNYrdbw/t0yTJqRtdU9UrfJCUMpSJIgbWzsYe51BcViHzLHeqCRqhZ1YX1tFwNfZBxS9O3NWkAcHqR606k/n/3coKAoV/Y7vQ/OYCZevlrmv3c0GsFh06u3/f4KMABvSWfDHmbK2gAAAABJRU5ErkJggg==); - background-repeat:no-repeat; - background-size:contain -} - -.ipfs-avi { - background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAm1JREFUeNpsU8tu00AUPXZcN0nzTpq2KQ3pAwkIAnWHqCoeexBb+AQ+ABZ8A2s+AIkdm266QUJIFWKBkHg1KpRHi5omJGkbJ3bGHj+4M1EQrTvSyGPPueeec++1EgQBxHp+/9mbyuriRZdxjJaiKBD3W+u1+p9a856max+gDO8ebT+WT20Ezi9NZi/crqadvn2MQBAGfpCOpqNru2937vxPIpY6Onjccx3Twck9MBiSU0ncfHirXFmZX3Md9wqCUwiEVN/zaQfHt0vfbBe5uQyuPVgpl5Zn11ybL4/i/lkICOw5niQRGQShoiqI6Bo43W2ub8n3hRtLZT7gTynk6gkCX9gAOxpAnxhHZDwC1/aI1EViJolu/QhKRMHZ1UX0Gr1USIEn5FPWHy+/wTokkrQOq2vBaHZBN4hmY9Jwfr4An/teiEB45ZZDwDiMhoExT0N+sYDCuUkkplLIlXP4/XEXdo+RUhdhBSSfUwtVTUG8MIHK9QVqI7D/uY6vr2pwmCPrkz+Tk9gwARWQ9WxppbXZhNnpw+ya4A5HZi6L4lIR8WyCcL6sTZiAWjWgAmpxkn5+kqTamK6WkCwmERmLDLvjB0ML9ikWXPLFuozYOap3L8HYN6DHdbS/d5CeTVBndBz87FCBLYkNTyIjBQemnIEsSY5lYrK1+UoWcToLMjEHAyIQ2BCBSx/NVh+ZUhrqmEqBebS3WyhdLg0zt/ugAaIklsSGLHCLa6zDMGhZ2HjyGsnpFPqNHnY2fmHv3R5SMymYbROszSQ2ROAY9qHiofvlxSc5xsKKqqnY3diRE9h4X5d/pzg7lnM4ivsrwADe9Wg/CQJgFAAAAABJRU5ErkJggg==); - background-repeat:no-repeat; - background-size:contain -} - -.ipfs-bmp { - background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAmZJREFUeNp0U+1rUlEY/13v9YV0vq2wttI5CdpL9aEGBZUDv0df668I6n+or0UQ/RuuD0EgVDAZrsKF4AR1a6COKW5qXvXec27PuVeda3bgcF6e8/ye5/d7niMZhgExnK9fbTrm5pbBGMZDkgCyq+VyhTUaT6Eo2ZHJePPWXJXRhez3B1yxmM/QdctXUSCgtV4Py4CvY3cky4e1x5DlLCaGbbzjXDcousG5OQe5HPRSCQPK4PpsEM/XH4WvhS4noeu3JwHGGRiULhsMoKZS4I0GtEIB9mgULJGA0+9DPBpBT7sffvf1W/Lg6OgJufw8C0CRGEXWazUwiiyFQjA8bsjVKjaJzovMD/Q5gxyJhG2cvyeXe2cAuADQNGBmBvLaGuTFRaDfh31lBTWi9pumjbK0B4JQul3vOQpM8JdskOLrdCvDcDjAsjtg5TIkoiKLaokMNR2cnZbqNAMycqG7XbHKR2fMzwO/dsxSwu0BiBJsNsv2LwAJAJCI5ux2gXYbqNetcz5PoORI1cDS0n8AxGW7A+zvEYBKZ2ZlcsEtJLbedMjePBaCTQMghx45ulyWkzxMVUQ2RMQhLfFO16YAqCrixPnm6iqKrRb2W23EfF4cUNSrHg90cr7hDyB33MTnSmUKALVs4uIlROjxg+AsPhGVl3fuIl2tIOB0Ya91gkOi9mxhAal0ekork1ic/kGLBORMxy2K1qS9V1ZQbNThIj2EGh+2tsyOnSai8r1UxMNIBB+LRTTULr4Uds0K1tU/uOLxIrmbNz8XXSrnASSpubG9fbKRyVh1n/zSw29t9oC1b47MfwUYAAUsLiWr4QUJAAAAAElFTkSuQmCC); - background-repeat:no-repeat; - background-size:contain -} - -.ipfs-c { - background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAcxJREFUeNqEUk1rE0EYfmZnkgoJCaGNCehuJTalhJZSUZB66a0HwXsP/Qn+FM+9+hty0LNYCr2I7UVLIW0Fc0hpQpSS7O7MrO9MspuvVV8YMnk/nn2e5x0WRRFMvP/w6WSz5jbi/9NxfP693Wp3DrJCnMW5d28P7a+IE15lufR8o1ZEStwPhkWHsWbrZ+eNEPxsuubEF6m0TBv2Q4liPofXuzveulttSqW2UwH+GjqC0horpSL2njU89+FyMwjlTlxOJMTa9ZQHzDQIjgwdom9zLzfXPc75kbnOAswBJTlC2XrqQRMLxhi442DgB4UFBhgPpm3B5pgBHNUUxQKAHs8pHf3TEuFMetM9IKr/i2mWMwC0SnuSFTG2YKyppwKYVdGO7TFhzBqGIenVeLCUtfURgErucx5ECKREKBU4d3B718PHz6cICGT/1Qs8qpQtGOdyhtGEARWDQFqQJSeDL98u4VbLaKw9IRAJPwjtoJGlVAoDQ800+fRFTTYXcjlcXN2g++s36p5Lzzlve1iEROa8BGH1EbrSAeqrjxEqicHQt8/YSDHMpaNs7wJAp9vvfb287idboAVkRAa5fBYXP9rxO4Mgf0xvPPdHgAEA8OoGd40i1j0AAAAASUVORK5CYII=); - background-repeat:no-repeat; - background-size:contain -} - -.ipfs-cpp { - background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAfJJREFUeNqEUs9PE0EU/mZ2WgqpXX+QIDFdalVslh8NlAOQaOKFAwfvHvwT/FM8e/U/MOnBmwcj8WD0ACEGghIkbU0baaEthe3OTJ0ZWV26q37JZt68ee/b9733yGAwgMbL12/fz+azbnAPY2Nrt7Zfqz9JMrYZ+J4/e2pOFjiciRvXlgp5GzHonXk2o6S8V6k/TjBrM/xGA4MLyeOSPZ8jkx7D+uqCU3Amy1yIYizB36AlCSkwfjWDR4uu40yMl/s+XwjeWThQQ4Z6QNSnSkYykcDXasP4lmfvOZTSF9q8TDBEFPbN5bOqCglCCCxK0TvvZyIV4CIxbgpC+4gm/PUmFCIE8iJPyME/e8Lon9j4HvyHYLjKSwRCSEUgf9+15mFbx8QS6CZJMzJ9SlBCwX3fJDLG4PX7ykcwkmQmJtpEhWa7g1dvNlSwjwelebz7tAXLolh0p/Fxe9fErK2WDFGEgKjxfNjegX0lDTc/heNuF99/HGEslcKXwyoazWNDdlCr6+DoJgrBzdI0T9rYO6yg2zszMlaKM3Dv5OBzbuyZuzm1B16U4Nzz2f3cFOx0Gq12F9cztpExncsqYoaHpSIKtx0zJdVIFpHQ6py29muNk1uTN829o/6SHEnh80HFaE6NjmLnWxUJy1LyTltB3k8BBgBeEeQTiWRskAAAAABJRU5ErkJggg==); - background-repeat:no-repeat; - background-size:contain -} - -.ipfs-css { - background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAk1JREFUeNpsUktvUlEQ/u5DoCLl/RAKKKUvWmIxjYntQtcu3LvwJ/hTXLt16coFC2PsojEaMKZtCqFaTdGmjbS0CG3By+vei3OOBSGXSU7uzNyZ78z3zRF6vR6YvXzzPrMUCyf68bB9zO+VfpROn5hkOdfPPX/2lH/lfiLidztX5mN2jLGG0rKLENIE8liWpdzwP7HvqJqujmvudFU4bFY8Wk1FZsOBtKppd8YCDNu77CZevd3gflfTUFcUhP0ePLibiIR9rjSBpgwAfe4dVcV6dhtep4PH5msylGYLrzeybErcT85FYiH/CyPAf74gObC2vMhzsiRhPhpC6eQUM+EA1pJzILEnjRSuJsju7MJqsUCSRei6Dp3yXqcdGlHZ/rLPazQWGCn8+6YW4pAkEW0SjzUzanWlCa/LgcR0lNfovTEi6lcIkzesnM/R8RlN0INGp3h4DHoDsE5YRvQyiKiRSMzikRAOS2WoqoZWu41K7RwzlOOAVDMMMHhIGvFlRxJFrKYW0ep0IYgC3SDh4b1lTJjNfENsrazOAMAw680mPuW+8lFno1P4XDigRhOiwQAyJK7TbsNS/PaA7giAIAhYz2yRgBIfsVA8wIetPG6FAqhdNrC5u0f+TUyHgyMTDDToEt/ftQsEvW4EPG5OZcrvw0mlimarTXkPfpXPcNlQoGtjACgpryQXsPNtH/nvRXqBJpoKHMzGNkNB0Odls7LNyAYKpUq1dt1iuvB7fRDp9kr9D1xOFwkpoksXusmXaZWFn0coV89r/b6/AgwAkUENaQaRxswAAAAASUVORK5CYII=); - background-repeat:no-repeat; - background-size:contain -} - -.ipfs-dat { - background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAfVJREFUeNqMU01PE1EUPe/Na0uptmlASg3MoiZgCA3hQ8PHAjbqwsS9C3+CP8W1W/+BSReyYUPwI4QAVkAgUEgIbVIg1FZb2pl5b3zv2cHBjsaTTOa+e989OffcGeK6LhTevFv+OJoZHPHOfrz/sl86KpWfhxnLe7lXL1/oN/MSZqonOXU/k0AA6lfNhEFIrlAsP2PMyPtr1AscLpyg5pbtIHErhqez4+awmc45nI8FEvwNaiQuBHqTcSxMjJhmX0/Osp1xr878FxWEzwMinxAzEA4xFIpnOjedHTKpYbxW4U2CP4j8uWxmUKsghMCgFI2mFe9QgHZj0Ba4yhFF+KvGJToIRLuPC/efnjD6+26wB1Lq/xgbSCBXKeWJG/OTdky8cWTdT3C9RmWSGk2XCLlWo4xTNbfN5qh7PpXM72GjZeHt0gpq9QbmH4whGb+NpU/reDQ7hcWVVXxvXOHxzCQopQEKXKEbL6o1ZIcy+LC5g62DY2zsHeC0fA4zndIrHOjvg2XbAQRSfsuy9XxC2qzi/H5B6/68W0AsGkW0KyJPBLbDO0fg3JX/CUM81i0bD6WKe6j9qOPJ3EMcF0tSNsFA6g6alqW+VtZBUL78Vtk+Oqne7U9rs5qOQCjSheJFBeFIFOfVujSUYu3rIc4uqxWv76cAAwCwbvRb3SgYxQAAAABJRU5ErkJggg==); - background-repeat:no-repeat; - background-size:contain -} - -.ipfs-dmg { - background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAn9JREFUeNpsU01rE1EUPe9lkk47yWTStCmtNhFSWxos2EXVhSsRcasuxYV05V8Qf4DgD/AvCK5EV1oFI7iUBqmCNdDvppq2mWSSzEzy3vPOpFFq+uDNfR/3nnvueXeYUgrBWH1/9/NE7k5BKRnuRcfF2qdnmJq9DeF9tQ+2isuMsxXGWHh/a1mEVsPJSI5fSU3OPEj291IIlN49RXz0KqzEQjIeZS/L5Y/3wPGhDxIM/i/A7fZWgVG0t5EaG0ZUa0JGM8gvPrZmLt58QYwv91mfAqCIE0sAqgumBFITGQzpUYhuF0KfRa7waDyXXXolpVrsh/0tgSLDr5I+wUZo1UHCSkAficPzY6juFSmbRPrC/azjq+fkcO00gAqoU7B0ETKkfWbuCTjTYeq5oESAauexcTScX+ZACWFm0YQSLZKhHdr67+/wW0e0dgjYo3sCEXXybYtBDVSHLp2es3IpsILS24c42lkBg6DzRjgRzCDZ/xr0GNRJwwYiWgzt+hYMawleu0V3wbkT+kUirOc7IGJAz68R/Qak1BAlx3hqASPGBJRXpXOv58dkz3eAgQoOm4hyj57NgZm0MHvpBmK6QdUdg/DAg9cRkhicBSDaKJdeo1bdxmR2DtWDDUxl51HZ+QHTysD3XdQO95Gfv06aeGcAdBrY3Chi8lwO3768QWX7J5q1XWyVSxgajiOXLyBG2hzurRKV9lmt7ISNkkjo6HhNyjoK+2gXRsKE57ZIE2ot10Z1fz0Ue4ABVw3NMjnW14rInh8jTYywoTg3EOFpOM4mXNfH9PQUfGlrAwBOs3I8ljbtuMWhRWzIIPrkn+GcYcgIWEowbZ+0qB334/4IMADESjqbnHbH0gAAAABJRU5ErkJggg==); - background-repeat:no-repeat; - background-size:contain -} - -.ipfs-doc { - background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAppJREFUeNpsU79PFEEU/mZ39vZu77g7DokcP04BBSUmiEKCSCxs7Ei00JAYO2NlTKyMrX+CJhaGwopSQ0dMtFEsbDRBgiZEQIF4IHcg+2t2Z8eZ5QDlnM1mZ9+8973vfe8NEUJArfSNhzPG0VIfeIiDRSDkw1cWVt3N8rhG6SdSO2Gvn8dfuueqZwuNZqk3Jxg7iNcIfBbgXD6ZC8u5qffzX8eoYeyDxC77uygKhcouovgVUQj1H4YB2ovNuD9+tTTU0zMVBmG/+C8AIYh8F361DL/yE5HnADKYlVdg6MDAmW7cuz5WGuw+PsWDYGAvbL8ECFUt4K7/AHd/I9c7BLaxinD2Ld5Zo7g78RLuRhlBS2cpWbGfStfhfwCEpK0nUjCbWuGsLciSOELPhkq/YgdY3l6HsLfRcLYf+pHNbH0JigEPkLAyMsiEJ7NrqQzM1i7wyhoMZqOhvQs6Z0ovXgdAJACRoulEg5HOwrOroKk0zOY2BDtVpTF0CU6kLkQJXa+BNEoG0lMSsBBKQXWNQktmoGcaYeSaQCIVWOvUYQAiWZFQtk5mSMoSzEILtBrTfEcviC5bwVwQmoh96wA0ic5dB57ngeoaTIPCdb34zDITYNLOOIeVSsW+dQC+7+NSWx6jJ4tY/rWNV7PfcGv0tBoPTM7M4eKJVgx2FTE9u4QPS6x+kHzfw/mOAjarW2hJG3hy8zIceweuY+PRtREMdzbjzcd5WBqPB6xeRGUMGRzHjWvMmxQ7tiOF1JBN6FiTd6Sy9RuFbHpX7MMMqOD088Ii+op5OUAO7jyeRGfBwrF8Cg8mXuDL4neMXzgFwhwZz+hf7a9d5yu3Z6DTPjVQIY9k7erO7Y63Lvc8ErEeyq6JaM6efjai4v4IMABI0DEPqPKkigAAAABJRU5ErkJggg==); - background-repeat:no-repeat; - background-size:contain -} - -.ipfs-dotx { - background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAndJREFUeNpsU01rE1EUPTPzJk0y+WhMStW2qdVWxUVEQUF0I+4ELQiC7lz4N9z0T+hG9wrdZKUgLqulhrbSag1CKpT0g7RpYjqZmffle5NEKdMHlzfvvXvPPffcO4aUEno9f3Vt4dTp+BXOe+fB0u/NbVpv7h89NU1j1TCM8H7+xY9wJwPHZMbOjRadLAvE/2gToJTiTPx89k+OlVd/LT+0TPIPpO/SzyQk40xCMxBSZ9Z3CoAx5DOjeHT7SbE0XSpzwa8OWB9jINELolQg8AR0EgUKn1PIlIWpkUt4cPNxkTOU12trs8p95RiAXpqaztqou8q6SKQJJmZSqGwsodFsIJk1kcyLYv7IeafcLx4HUNkFF4jFTExMZ0B9DrfD4HUEusYhWs4GPEJg5wly/tBYRIOeDhpEwlS34xcyajdQr3UwOT2MlJOEBRuGNHWp9AQRVXDfQiFV/U5GBSiQ5p6ngBEa5z3fiIhC6g6IMDBwOdoHPkYnHPVyhN0tF7E4QSpr94CEOKELffq+y9Bq+DCJ7rWBoQQBVbPR2O6G4OlsLASJMtCZfQqm0NP5IVWnamdAkUxbyuIYtD7wWegb0YAzAVMkkI6NwPM9xEwHloyDGAmk7AKS9rAS0FKOdugbYeAHPu7OPEM+MY7q3hIKqTFQHmC3XcONc/fxdfMDrk/ew/edzyhvvTmBAddocVRqH3Frahau56qpZDho7+PnTgXffi/gbHYmLEvPSIQBp5JU62sYz13G609zKBXvoOMdYn2zgm7Xg2MVML/4Eu3uPgxhk2gXmNl8v/i2pcXTP8tKdTEcbWLZqDQXwu/l6pfwbEnSGsT9FWAA4mdHv2/9YJ4AAAAASUVORK5CYII=); - background-repeat:no-repeat; - background-size:contain -} - -.ipfs-dwg { - background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAoFJREFUeNpsU0tPE2EUPfOg006hD4rQh8WgbCSwkKgbF2owujaCiQsXxpX+D6MmbtXEsHCLmIAbE6NLo8YlGIxREIshIqVl+mQ6j8/zFVCb4UtuZua795577rl3FCEE5Bl79vPd5LHYiOP7cH1AUWi85ytmvlas1bJ9E5ryBntH3BpuP/X9i7ovkluuiE8N9SDepaLpCcRCCqa/VDCaMuIjSWP25Upl6n+QDoCz6Yh7KKzh3sI2LuUimPtRRyaqodj0MDloYiITSTi+mH29Wu0AUf9CsZPJoW5czJl48LmCc5kIKo5Al67B9gUGYxrun+5NnMlFZ+GKiQADj2a7AquseLIvjMv5KMaSBu4sWVir+3i8VIVKYSby0UTdFU8Znu8AYBHQgVOJEN5uOXi4UsdawwU0FSf6TaSoyw6DRvukPkgGWpDKy4F8a3jImCrqFDFn6rhKPR4VGnhvOTAY3WLcjifcQAsqRfhUc/Gq1MKNbBh9nIAMDjEppocxs9HCMktfGTCwP/oOBkUKNk/qF3pDYC6Ktk8RfWzyaaoKrqdDaBDwya8W1m0/CPCR3kFy7CcnmWQRUJqcRJFUKtTnPCeR71LwoeYF92CYyVnCFZpCTrRtCv5to2St8SOrKxiPqEEA4fkYT+mI0rdoeUiH1XZVuQPpsIKqw2QmfifTsnOABiWySlH9uU0Hh2MqjsZV5LtpPSoGeN9rKnhBX7ehoOSLIIPfnGONXGMMWN7xUfVldYDbjM3mrh5HCDgS17DhHgDQcIU+XbBxnDTn1x1UuQcJ9iv7l5Q5e1zLGri92EDJFnoAgHtcfr6wbbVXUqq193+0z97n3UJt1+d51n7aHwEGAAHXJoAuZNlzAAAAAElFTkSuQmCC); - background-repeat:no-repeat; - background-size:contain -} - -.ipfs-dxf { - background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAo5JREFUeNpsU0trE1EYPfNMmtdoH2kDNmJbaVFcaBVFpAsREQpFwY0bu3HjQnTj1mVd+ANcuC3qQixmry6E0kWFVIQ+bKy2tbFJm3emyXTujGca+4DkwsedfLnn3POd77uS67rw1vC79ek7fZEzpu3AYUqS9tKQGZPLpa3VXP0uFCmJ/8t9OLC3q/uJbcs5bkIybvdHoMsSbLKENRmvU2WcNnTjRFD7ML1WGSPJHI6sA4KRWMAWVDPxLYex3iCmfpuIh1QsFSyMxQO4GvXHHwOJ6XWSyIck8v6HQsnjAxFc7vTj2VwBg4aG78VdBHQFCk+dbVcxMdwev9gTSEC455sIBOu2KLsoJFzqasP9vjCeDBlYqzn4VXXwarGKZN7Crd5QfLDT/7KpBM84c9fFUFjFp2wdk6smflRsKKqMa7EgfJJ3Ac2OKlit2pEmBTQfngdpnupoU7BUtRGiiTe7fXiRqmK+KuDn6TpvYogmBRJcrOwIJLIWxmM+dOsyLKryQAaJpjJ1/AxrGO3SqdZt7kKZJrzJWBg5piHENuY8vV6e0UOye1TyftvC5l+gZB8SHJTwpSx4q4JeTUKaxhXoR57h7Rn+3iFolJ3xvPhab6HgJG/pJ7jsNP4sUX+jZiCgEsWd/DjH5IrSYpBUAr0yHpzSoXKOP25a6OBhndh0zcX1qIYM2RIbu6i0KiHD5B/GTMHG03kTGpEL7H80wHFOWwhqDZ+SpkBOtCDYJDhZE4gRcKNbYynAqbCMbXpwpVPFbEng0aKJGbYzK1p4wIegLlcEPmdt+DjXbzcsxFlCynRwwVAwW6hjqeg0Zt521SYCWCJvbe0Un29UDx7Hgrs3IEitHXkw3jOv2fl92D8BBgAJeyqBh90ENQAAAABJRU5ErkJggg==); - background-repeat:no-repeat; - background-size:contain -} - -.ipfs-eps { - background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAmlJREFUeNp0U01vElEUPfMFCEVArdoSqEA0KV246UJdUJM2Lo2JK/9FjXu3utJqTNz4D9worrsQExbFpAFT0TYp0CZ8pIAiyMfMvBnvm2Foa9uX3Lw7c98979x77hNM0wRf7ufPsq7Z2SQYw2QJAkDxQalUZa3WI8hy3gmZr15bu+z8kILBkCeRCJi6bufKMji0NhwiCQR6iitdatTvQ5LyOLLEiWcYukm3m4Zhmbq1BX13FyoxuH7xAlbvpqKRK1fT0PWbRwEmDEyiy1QVg/V1GO02tO1tKLEY2PIy3KEAlmJRDLXb0TeZL+n9g4MHlLJ5HIBuYnSzXq+DlcsQLk/D9Hoh1WrIUjlPcpsYGQzS3LWoaBhvKeXWMQCDA1D9pt8PaXERUjwOjEZQFhZQp9L2yERiqYRCkPt/z58ogTGqHQLE1BLgUmC6XGD5AlipBIFKkbhanKHGYLBDqQ4ZED0OAbfLlo8OIxwGvhVgyTHlA3xkomjH/gegBgDURMv6faDbBZpN+/tHkUApkdTA/PwZAPxntwdUyjYA/+ZMqJHjLgM9iv/6zRt2GgMaIE21aVIjnSm0DGPfmhzyde0UAE2Dj+p7urKCPvkZku9eJILOSMUnkvVhIo7GYIB3xSKYdhoA1erXGVKXpvFxZwdBonnD68PQ7YEwM4O4xwMPxc8RYE87g4FIcz+kvfmnA0YzIJIy77/m0OCqsTkkCTysKPjJG3viLei63Gm3kCO6UWqcMejjxecMPmxsoFKtYop6UNirYL9Wtc5OHqzznIXHq1na7OfMJROcK8a6O7MjW7nfzZdrd7jzT4ABACh3NGsh3GcdAAAAAElFTkSuQmCC); - background-repeat:no-repeat; - background-size:contain -} - -.ipfs-exe { - background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAo1JREFUeNp0k8tPE1EUxr+ZzvRJO62lUAQaKIQ0FVJFjBBdoIkrDDHuXJi4NnHtX+HCjW408Q/QmHTRaCRRohIJifgiiBICTQu29mHfnc7MHc+MlECKdxZz595zf+c737nD6boOYzxJLC6Nhwej7e/24HkO779s7G6mMjcEwfKZ21+/d+em+RbagaFev28qEpZwzKg3ZckqCPH1nfS8hScIdyhBe6JqTG3PfyTTeLrwFhvbKdy9/xi5QglXL0yGJsKDccZY7LDIAwWHpSferWBh+RN8ni4UylVER8MY6PHj0uSpUK0hxzfTmWsUtnoEwO3rer64jEyxim6/Hy67DXaHExvJX3jw7CX8XjfORUdDlOohhU4fAVjILCPbm9V1yIqK2FgYt+ZmsZcv4lH8Nb5upXD7+hVMjIRQa8qeDg8UTYPU5cTcxSk4nS709XTD53ZhpD+IYMAPj+TBz93fZiz5oHV4AP1fGdlyHZIkIZkrI7GyhnK9CZXy+Aig6p1+HQAY003AcF8AVtGGfLWG9XTO4MLZ5cL0WAixoT4zVmPHADSiMo3hzHA/xgeDWFjbNg8H3A7kKnX0koEcPdTu/ylgRGZgOjNv38zoSXC8BZJDRKOlwGEV0VJVGM0y4joAPO1spXbx6sNHeD1uRIYGUCxVSRlDt1fC8rfvcDnsmJ+dOaLgoAs6AVLZPJJ7WdhEkUyT8GJpBflSBcVKDTvpDBw2GzQqQT1OgaZqUOhtFQUTUKnVTVWNpgy51YLVKph7sqKYkA4A1ScEfT66vm5kC3+ofh6Xz59FQ5bpkvE4QW3M5Apoyorhl9ABIKnFgNdTOh2NkJG6WSf9eRBJtmFwLDJmriUzeaOkYvvcXwEGAIVNH6cDA1DkAAAAAElFTkSuQmCC); - background-repeat:no-repeat; - background-size:contain -} - -.ipfs-flv { - background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAmtJREFUeNpsUl1PE0EUPbssLYUCXdpaC9gWoSTgAyFigiRGY+KjvuuTr/4A44MP/gx/gMYfwIsan0RjIjGiJIZgSIGFIoXSD0t3Z3dnd70zpITazuZmJzP3nnvumaMEQQCx3jx69SV3a3KWMxetpSgKxP3m242Do43SQy2k/YRydvds67n8a63k+FRSn7l/bdg5tdsAuM3he/5weDC8vLdqPLgIIpba2niux52mg//DqlsYSg3iztO7mczN3DJ3+ByCLgCBH4hOFEF7cDpzPCRyOpaeLGXSc2PL3HbnW3XaRQCPEgWI2MsRVAVqrwbX9bHxbhOKpiJ/bzpDOr2k68V2BtRNzMtqDEqPejY/4zSGjb54BM0mQ8k4xsDoIMauXxnqYOD7PmwScP31d0SS/eAuh1lrolFpIBQNQw2pqJdqsAlIceB1AJCIkkE/FZskXDQVRXw6IYHiE0nBEcaPXSSvJnGwWkQXAE4acAhbxPMJpOdHweoMhc9b2F8zwKizbdlyPLVH7QLg+JKBYzoorxzjz3oRzUoToaEw9KyO8XQW5AE5jrFT6AbAYVVNxCZ0Ka3So+DSTAoDiej5ywTySbls1OEDobhFlMcXxrHw+AbINEjNXgb7y6BndLhk8cRkHHbD7g4gEhiJFxsdhrDqaamBaDKKerGGSKwPI9kR9EZCaNA5ubE7A5s8IFhsrxQkgJhZoa/06xC5xRz2v+3BOjFlbqcGlquxsondT9vY+2pAJdeZR6fI355CgQCN2A4O1w7gkQ7cdLUOAKdhV6uFSv3kd/n8mT68eC8dKWLnY4FsfeZQh7nVVt0/AQYAsf5g+SvepeQAAAAASUVORK5CYII=); - background-repeat:no-repeat; - background-size:contain -} - -.ipfs-gif { - background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAmVJREFUeNp0U0tPE1EU/trplAqlL0laiw40xASByEJIZFGVnSvj1j+gWxNXJq7VrbrwF7h10cSNhMRHojEuACVBKmH6SJQyJeXRxzzv9dyZPiCtN5lMe8853znf953xcc4hztDzZ1+C6fQMHAfd4/MBFG+p6h/n4OAeAoGNToi/eOm+A50LKRaLh6amoty2vVpZdotNXccMEK3LwZxa2bsDSdrAqePv/mLM5tSdMwYBYqyvw9zdhUn/L59P4OGtG8qlZCoH254/DdCdQBCxqZu+ugqnWoW9swN5ehp2NotgIo6bGQWGtaS8+vQ5V9a0u5S+1gfABEilAqdUgm98HDwUQkDT8JXoPPq+BoM5kCYmFT9jryn1+hkAt7heBx8dhbSwACmTAUwTgdlZ/CVKJaLnI1GD8TikZiPSR8Gxib8chH95mZTxgwWHwH7+gFMswqcokIRbjMO2HDCnZ1VvArpjEmnKZc8+cZJJYGsLsMiZ8AgwEqaY6Mb6RQR33JFhGECzCRyfAFXNu9v+RVNRZWIMuDJNuYMAaDycUFGhCOgtuAtFVDA83G5A8TrFDw+F5QMAxAKJJxz2xnW3RPJGbm+rCyjotZetH4DGzaSSeDA3h4Zl4R0JOEZWTpIzF4n/m995bNdqZwB6m0gFft3Ak6vz+KYWwFsGlqIxXItEcDt1ARMEtKdVgZb+fwA0G2C2hXM0ZTZNRcSf0b1pmXi7uYnjI+Lfanm5fRQsK8BIxKcrK7i/uIgP+Tw+FlREqHN5fx/vyU4uHBE6UO4gDWqk/JFaLuMxcXeFk6TuJ90V0HOk1in7J8AAjmgkPfjU+isAAAAASUVORK5CYII=); - background-repeat:no-repeat; - background-size:contain -} - -.ipfs-h { - background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAbRJREFUeNqMUk1Lw0AQnf0woK0ttVqp0hwqVCl+UBERT94F7x78Cf4Uz179DT14F8WbYHtRkBYRLNqDtdaPZLObuLs1NGlXcWDJZGbey+x7QUEQgIqT07PL5WKhHL5H46J+22q22vsWpbWwdnR4oJ80LNiz2czGUjENhvj4ctIE4Wrj8XmPUlKL9nCYcOFzE9j1OKSTCdjdrtiLdr7KhVgzEvwW6krC92E6k4Kd9bJt57JV5vFK2KfRQRV+RAMkzxglYI1RaDy2dW1rpWRjQo5VGicYIorWVooFvQVCCAjG8Omw1MgG8AM0uSBUDSnCfk/IGCHwf3DCD/7UhOLBrFkDuep/hDUSSCv1iYo4rIfqGwmUSNJjfYbBcQKhZw0aBMA4B48LwBhBt/cON80HmM9NQ6fXg/Wlku4TwmNWDzaQqzHG+0PSKod5cH5Vh2RiAhYKc8DlV1UPSyuFMGygVlMg1/P6BC6DqXQK8jNZDXAYA1f21V34wMXYFaiyVw0rJyzLgs3VMkxOjGtix/V0XWChZ0cI2i/dzvXdfTd0Qf91BMPrhyNzgKfOmxaWypqaDXHfAgwAtCL8XOfF47gAAAAASUVORK5CYII=); - background-repeat:no-repeat; - background-size:contain -} - -.ipfs-hpp { - background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAehJREFUeNqEUk1v00AUHK/XKf1yZdESVRBXjRSRFqMQVBA5Ic5I3DnwE/gpnLnyG3LgXglx4UDDLZS0RWkDLiRxSusk9u6GXSembmLgWZbX7+2bnZl92mg0goo3b3ffO/ncdvyfjHef6q2Dlvs8Q2ktzr16+SL60jhhZ69bO8X8ClLC7w9XdKJVG8fuM0r1WrJG4gXjgqU1D0MGc2kBTytl+7a9XmWcl1IB/hZKEhccq5aJJ/e3bTu7Wg1CVo7rNLlRhUh4oMnXoDoyhoHGyWmUe+QUbELIa7W8CjAFlMzdzeckCwFN06ATAn8QmDMMMGlMuwWucpoCHNe4jBkAMenjYvRPTyi53JvuwX8AplleAeBcRFrH6rXIxLim9I/pi3QA1RhKaYxdjkN8IwalCMIwWs9ljMkh0wzk+9M7w179C3LZNXxve2h+c3Hu91HeKmD/6zHOLnw83ilB1/V0CeqU3Q81LC/O41b2Btx2N2JVP2riR8eTUxmi0TzBwrKZMsqMoz8MsDh/DWuWhUBKURLKxQIeOMWoptYPnS1c+INZBkwISomOSsmBZS7B+3WOzZvrKGzkMAiGqNy7g+LmRkRfekBnANy2163PZXrSbrQ6vch19Xz8fPDHyL39QzkHBKedXjfu+y3AAGU37INBJto1AAAAAElFTkSuQmCC); - background-repeat:no-repeat; - background-size:contain -} - -.ipfs-html { - background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAmBJREFUeNqEUktPE1EU/mY605a+hhZTBNKRDApNrWIRA4nEBUZdmCgLNi4MK5f+FNdu3bFv1J1EXODCR1JJSMTwpqUP6NiCpe10Zjz3hj5Mm3iSybl37jnf+c53jmDbNpi9eb+6Ftcisea909bWNzNb6dwzSXKkhIt/r14+515qBqmDA8HpqKagh53XaopblpIbe+knDpFAhPab2Dw0TKvRK7lmNODzePBgZlK9oUWSpmVNdpIU8T+jaMsyMaD4MDcZVa+NhJMN00w0n6V2nN3yQgdHWZag+LzYPTomIAtT0THVtPGanmb/BbjwLFkvn2IttYGYplKyDzsHh7gdmyAWfh5zVq0Guhg4RAHFUhmfvq3j134aXo8bd+ITnMFOOovU5jbGRoZwNxFn1cxuAIcDW/sZDjA/c4u+BNxOJyxqaenpI3z88gMfPn9Hv98HQZS6RazW6kjExvFi8TGdDSy/W0Emf4LS6R8sv11BmfzSwkPcm74Jo9Ei0GZgmkw8QCOao8OXcaz/5vSZnPdnp3ApqBBLkWJE0Ci7ASzbIhCLLQ1E0iOkBDh9NpUgiUejo8oNuJwyn0YPABtn51UYFFivG3yBGCNZkuDtc/MW+ZQI3OrYpBaARCKufk3B5XIiWyhiL5ODp8+FfFHH+KiKSqWKUL8fC/NznGlPBmz+24dZjKnD0CJDcMoyW0SqXuMtHBFw7rhIAD1ErNUNafxKBNevapwu65NpEQ4FqXIA+RMd6VwBP3cPSERb6gLIFIq61+UqGWaFdcrVt/lmAuWjAi2aiMFwmOYuIJ/N6M28vwIMAMoNDyg4rcU9AAAAAElFTkSuQmCC); - background-repeat:no-repeat; - background-size:contain -} - -.ipfs-ics { - background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAhRJREFUeNqEUkFPE0EU/mZ2dra7bLNpi2AxQFKalkJrohICiYkXPagXrx78Df4K48GDBzmQePLMhUODNxQ5ciEkJVqDtJGmMWrCATRbd2ecoS5u3aovmezsvu9973vfPiKlhI4XL7c2r5YL81LIELEghLA3u/udxmHnPmfGW/Wuv+LpwwdneRYBx7PeWK0wOYYhcXxyckGV1fdbnbuMsXcklqPRJQxFMKz4RxDCtVO4s3xlRjWoB0FYjlQPEEBieChwKCRGMx5uLtaKs1P5ei8IKlGa/YkXMXYtlTEDlsnw/mMXhBJcqxSK6vlcpa4PEpCooUyIqs5M6hG1o2CUwqA091cFcYLf/sjzcX75EiQIojI9779CTYR4jwTBf+r7GAwh0AxCiL6JMT/04vQ79u8aI2O/7Jzg69o6Go8ewycUahtBpADhHKLnK/eVbkMdtROWIv80NQ2sPhncA9Htwn+9hZG0rY6DzFwJl+7dhs0ZstUy8rduwPS/wd/ehmi3kwq4zTHiWUgXp+EuL8FvNvFl5Rn4xAS86iyI2kY3n0Mv48ByrOQmancdi8I0Kcj3U5iuA29xAelKCUHrEIayzltagG2E4IwkFaQgSC6lYI09iN0d8It5uNV5nG5sgJdKYC0G8WoTOZvBISFNEBxnsuzD3GX4vfDsszzqAu0jkJQDedCGbB6AWg54pYbPo+NGVPdTgAEAqQq70PytIL0AAAAASUVORK5CYII=); - background-repeat:no-repeat; - background-size:contain -} - -.ipfs-iso { - background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAjlJREFUeNp0kstrU0EUxr/k5qbJzdPYpGkpsUJoA2q1oLjTdiGiIC5cuXHlxv9BEOrStTvBnQvRrSAIsejCrlqpsURq2hCJNQ+TNLm5uc/x3MmzJh34mDNnvvnNzOE4GGOwx8+t9XQkfn0VE0Y5/7Z+kHm+dvOhtd3P9c/xwNZh7nWaMYtNUmX/Fct/vlN7/8J5aRRgyzm8xzpRDjGE2aVH4VTqdnoUYg/XkEhmy+Cx3DhA5tMzdFolvg5Mx3Fx9SmH0JIg79Zo3j4GADMIokJTKtjbfAKXU4Y/2NvSfyH75TFOxa9Cmr0XnlPFl5ReOQ6wNMDsoFX6AElqQlNV1KsOuNwS/AGFjEUIDhmn5+/DMM16/9igBowAzFKIswPJr6MjlxFP3sV04gaP7RzMPe6xvWM1gNUBM2UKYlBau3QghGphg29J3gDlLLilWNdD3gkvIIDRhD9yGe2mCV0V4HFXuCxT5Dlv8Dz3sIkAs03FalDxBMQSt9BRBMhNncuO7dyU28c9tnf8C/Q0ZtR4GImeQSj8APLRH772BWcgiFODffCv/t8H9tO0v3RjV7VqkeeXLlzDfvYjj88uXhl4JwIsrYxmLY/M1gYclIvGE9jZfNPrSCD3/QgLyeWTADV6wW9AryIcCkB0u1Aq/oCPumlufoF72vIheaLDr4wCLIOqrYnULA14PSoqpSJEAUilZrD77Sv3LK+cI0+Be8cAbbmAOrob0agtD491LYfkoqvnyZLsWRkA/gkwABL4S3L78XYyAAAAAElFTkSuQmCC); - background-repeat:no-repeat; - background-size:contain -} - -.ipfs-java { - background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAjxJREFUeNp8U01v00AUnNiOEyepQyhQobRBSlVIoRCBEPTAjQsSEneE+An8FM5cuXLNoQduIAE3qopKNJAIIppA2jrOR93aa6/N8yZuUxyxkrXr3ffmzczbTQRBgHC83nj3ca28dD36nx6fvnzrNNrdp4oibyUmey9fPBezEgWVFuYLdyvlPGaMY4fl1aRS+9pqP5ElAkmcnknRwuO+Nyt5u/ETYfyj9WrpZnmpxn2/Ok1Swn/GvtnH5k4TLue4kNfxoFoprRQv1TzOb8cAIu3+ZD7oD/Hm7XuxzqRUNDtdkuLiTmW5tFxceBXlnXgQTAORSMt2oGezUJJJrK9dFWdEH7Ik4dB29LiESeUEJXd7/dAT3L+1ivlCHr8NEzutXTBvbJPPSdO/AH5wysChwM/1HzCGlmAzOrKxu2eCud6Z2Jke2MwThpUXL6Nn2ZAVFTlNw70bK0iRnGAq9qwHtOmTRpsx1NsHyKRVnNPnoMoK9kc2BjbD4vk5JGV5NkBoEPM4FFnCteJFWOS4ntHEfphQyKaFTWFLw704AJ26ZFx/ZEEi3YyY0O1Dmr4EKTUHA8hUnS6siI0DEHLYog+b28RCRuNXR/iQUpPUEQ+NVht6Lodnjx+GXYgDSFRnq97Ed2pXSlXhUSeGhxYc5sKlNXM5DGLR2TMwfZVPAIi+otGNWy1fEZUKeo4qc4ysI+F8VksLIJfYcD9QYgB/DNPMptWBlsnBIS86xmDMTBo/PWd0LB6VZfdEbJT3V4ABAA5HIzlv9dtdAAAAAElFTkSuQmCC); - background-repeat:no-repeat; - background-size:contain -} - -.ipfs-jpeg, -.ipfs-jpg { - background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAmlJREFUeNpsU8luUlEY/s4dmMpkWxRopGJNNbiwhk1tItbGtXHr0hcwmvgOdWld6Bu4coXumtREE3ZKu8FgOlC1kIoXtC3jPfdc/8PUIpzkBM7wf+f/hsts24YczuerGUc0moBlYTAYA+i8sbdXtAzjITRtq39kr73s/Gr9DTUYPOeamwvYnHdrdR0SnDebuCbswJGqpX+Uf92Hqm7hzFAG/4TgNr1uCwEJ0trcBC8U0Kb1/PQkHt9JxSLnL6TB+Y2zAIMOJBGLXmtsbEAYBsx8HnqCGKVScAX8uHf5EpqmGXv18VO6VDEe0PXsKABN8+AAgiabmYFNNJTDQ2RUFc8+Z9G0OPR4PKYwvKari0MAgiY/OQGCAajhMNR4nDZMaInrKBGl70SPMScck1NQG3X/CAWLE3/dAWV5hRRVIJxOWNksrP19sFgMqqAebUGYHMI6teq0A9oTVAhqu2sfbYYjsL7lCZ3683gA70T3TK7/B4BNoO020GwB9TpwfAz8LgMtWn/NkV8EHgoB81c7nYwCyBZlEVkHcqMTKFnkmehJTOPvEfCnKi0fAyADJKfXC/h83TaZTJjaa5lANLpOFqAXtlEAorAwO9u5syT5UxLfU0e3o1FMu1x4u7ODYq02BKAMAVSrSNLrK1MhLPj8mNF0vFm+C1ZvwKBwXXE4AGn1WAASazESwUW3BzUSMeJ2o1Aq4sPurvQYSRLwlhRR6mSaYyi0WlpAJrFRx3ouh5/lMt5lv8BLwXp0M4lSpYL17e2uK5wP6lj/c2ZPn2RI+YT8fDvqoyegVLyfG5kBKaQQOfvF2pLc+ifAABiQH3PEc1i/AAAAAElFTkSuQmCC); - background-repeat:no-repeat; - background-size:contain -} - -.ipfs-js { - background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6RUQ5ODY5Q0NGMTE4MTFFMTlDRjlDN0VBQTY3QTk0MTEiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6RUQ5ODY5Q0RGMTE4MTFFMTlDRjlDN0VBQTY3QTk0MTEiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpFRDk4NjlDQUYxMTgxMUUxOUNGOUM3RUFBNjdBOTQxMSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpFRDk4NjlDQkYxMTgxMUUxOUNGOUM3RUFBNjdBOTQxMSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PoT8zQ8AAAJdSURBVHjadFNbTxNREP52t7S0bktbKFAvTUVaw60YqkExUTD6oD74qC/yD/wp/gh885XEEI0RAyYQUiMpIBGMkYR6o23abi+73e2uc04v1LROMtnZPTPffvPNHMGyLDB7sbJ2ciUSli3U35smkK9t7x9v7n2dD/g8KUkUwWqeP3vKz23NxJGzgwOx0RC6mSgIo+WKuvP56MeUzy2nJEk8PWsGJVVTuhWbpgmHw47FB7d98Wg4mVWK52o1sxOg3Va3PmFp+Q2PdUquaFUM9/vw+O6cP3bxwm46Xwh1ALR3/vL1e+hGjcc9koScUsTSq3coVDQsXJ3wzo5HEs3clgZNMTVdx1T0Ep7cn6//QRQwMhzA6uZHLD5cIFEFSKIU+G8LK+tb0KsGZKcTJoEyP08AbpcLy6sbPKdQrigdAGaDwWxsDH1uGbliCYIgcM8WFPg8Mq5Pjzdyu4jYbCE44EepXMHuwXe+A8x3KKYxYsjvbUzmlPGpBmYdgI1oYjSMbL4Ao1YXMkcM2Dd2xnbAamPQAqg1GORLZdycmYTdJqFKk2DPR3fmwI4zBDrg9RADqxPAbPBif2WTSB584/3/TGegEOit+DRcvQ4OZJi1LgwIQKVCg2i6nb1I7H3Br3QWqT9pBAP9uDY5xjdSM3RqxeoUkfVnEOW8UkLykERTNXjkM7h3Iw6NNvHw6JjuhAhVrba0+QeALozcI9nQR0VvNxJc/ZmxCNGvIBQcpDG6udA22kyW29HC72wu8yG579ZoiSYuR/ly2+y9CA4NceWLmo717T1i5ULqJNtapL8CDACskxPFZRxLwQAAAABJRU5ErkJggg==); - background-repeat:no-repeat; - background-size:contain -} - -.ipfs-key { - background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAlZJREFUeNpsU11PE0EUPbM7u/2AtJUWU6qiiSYYo5EmmPDCD9AH46sx8cEnja/+CB989z+Y+MKPgMiDsYQACcbaWBBogYD92t2Zud7ZlQZsbzKZ3bl3zj3n3IwgItjYeDO3MlWme0bjUth8e8/fO2tHzx3XqUEk50uft+Ndnhdmc3SlfNPkVZT8Cy600DoIISvVfKYtlvfX1p66XmoIYsMZdjJQWvEFbbsC/S5g2QhSkKUK7rx6OzvzqLpsovAhaAxA3DUBQn2TUFsl7KwTfm4Z9DoO5LW7uPXi9Wxpfn7ZKF09vyPxX2iWcNRkKGZz0mQWKoNs8AVB6x1yRY2pYnc2LLofuXTxMgAlmlXIfngCxNxEzM+DPv6NQa2BygLgZyX6JT83ngHTN5GAL0WSoUQkSQnXkyBh/k0GegTAaldM20sTKvet+yyhIZApECamL0jUSe3oFChx3TopM4TeEQP2gc6BgGIwb4KGNXRhCkMGxgg2kJeybRiZM45D8W61qEAknSmpHStBhywu0nFVupSCTAcM4ECwqapv+NQ6LS9JGALoMIIoPYDjZiEL1xHtbyO39AQUDaA7R1AH23DSeSA4hv5RG/VAhxomPYP8sw9A4TaC9iHkjUWmrtGvbyC18BLe3GP0m3WW4I5hEBEnPIStXzyuFIxb4EkMEJ79Qa/xHbKxCdM7xeCwzUZOjgEwnuzt7qLz6T3cySmQP43uzjeIiTJM6io6W19B/NLCKMVGCzkCoLR/0lrfOI2fNy/huKC1FTsK/rbGNeMRC8dHpHByfu+vAAMAL/0jvAVZQl0AAAAASUVORK5CYII=); - background-repeat:no-repeat; - background-size:contain -} - -.ipfs-less { - background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6RjZERjZENTJGMTE4MTFFMUIwOEVERjQ5MTZEMkVBREUiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6RjZERjZENTNGMTE4MTFFMUIwOEVERjQ5MTZEMkVBREUiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpGNkRGNkQ1MEYxMTgxMUUxQjA4RURGNDkxNkQyRUFERSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpGNkRGNkQ1MUYxMTgxMUUxQjA4RURGNDkxNkQyRUFERSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pl1w97IAAAJhSURBVHjahJNLbxJRFMf/wPAIMIxMkUI7tS0VYqlGDLGhjdKkqyZ24cJFN925de+XcONHaHRj4k7TND6SGo1VWwmp2kSLhlqMDbQ87gzPYcY7k4GgoJ6bmdw598zvnvM/95pUVYVma+svcovx8yMnFZHAMJPJBJfDzq5vpX6+/vD5qo/z7DOMBdo/d26t6jFMJ3iY51jBz4M+LP6wxEw40Gy23qYzB3HO7fpmpZCOmfEfa7Xb4NxOrC4lvbPToe2yKE3K1PdPwNOtHdx79ESfq4qKkijB5/XgevIyHxEC24USmewDqD2ABxubaLRkfW6zMqjWGlh7/ByyAtxYnOPnL0Q2+gGGmKRaw8zUBJaTiS5QOO1FJnuIAM8hciaIWHgi8NcSNt+loVDY8JBXh2ojJAR1HbTSNFMUpV8Dxcjg0nSYBrtBxdLbqI1iheCUh9XXNGurAwCdEkb9QyBSFam9TDfoPZ1LUg1BH28IiwEARTVAQOzcFKRaHZpLoa9avY6L1Gfs0c32t4PU6W2lWsV8LAorw0Cs1nXftYWE3qZGqwWHzYp2zzlgetuolVFvtiDLbRRKFTAWCxx2G/KlMtXFhWPqOzsWHJwBx7rxKv2R7mwFz3lw9/5DLC/M4Us2RwV0g3U58XJnF7dvrsBOoX0Abbej/DFKRMKI30fTVGC32WA2m5H9cQQvhYi0vE/7Wdgczn6ARA9QPBrBszcp/XvpyqxebzQ0Tlsq6llxLhe9bD4cFMr9XdjLHpLv+SLGBYHAYiVu1kNOpAaRTWbCejgiw0zGhFGSK1aw+zXbvfK/BBgAPwADAs5GpGsAAAAASUVORK5CYII=); - background-repeat:no-repeat; - background-size:contain -} - -.ipfs-logo { - background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 553 235.3'%3E%3Cdefs%3E%3C/defs%3E%3Cpath fill='%23ffffff' d='M239 63h17.8v105H239V63zm35.6 0h36.3c7.9 0 14.5.9 19.6 2.6s9.2 4.1 12.1 7.1a24.45 24.45 0 0 1 6.2 10.2 40.75 40.75 0 0 1 1.8 12.1 45.69 45.69 0 0 1-1.8 12.9 26.58 26.58 0 0 1-6.2 10.8 30.59 30.59 0 0 1-12.1 7.3c-5.1 1.8-11.5 2.7-19.3 2.7h-19.1V168h-17.5V63zm36.2 51a38.37 38.37 0 0 0 11.1-1.3 16.3 16.3 0 0 0 6.8-3.7 13.34 13.34 0 0 0 3.5-5.8 29.75 29.75 0 0 0 1-7.6 25.68 25.68 0 0 0-1-7.7 12 12 0 0 0-3.6-5.5 17.15 17.15 0 0 0-6.9-3.4 41.58 41.58 0 0 0-10.9-1.2h-18.5V114h18.5zm119.9-51v15.3h-49.2V108h46.3v15.4h-46.3V168h-17.8V63h67zm26.2 72.9c.8 6.9 3.3 11.9 7.4 15s10.4 4.7 18.6 4.7a32.61 32.61 0 0 0 10.1-1.3 20.52 20.52 0 0 0 6.6-3.5 12 12 0 0 0 3.5-5.2 19.08 19.08 0 0 0 1-6.4 16.14 16.14 0 0 0-.7-4.9 12.87 12.87 0 0 0-2.6-4.5 16.59 16.59 0 0 0-5.1-3.6 35 35 0 0 0-8.2-2.4l-13.4-2.5a89.76 89.76 0 0 1-14.1-3.7 33.51 33.51 0 0 1-10.4-5.8 22.28 22.28 0 0 1-6.3-8.8 34.1 34.1 0 0 1-2.1-12.7 26 26 0 0 1 11.3-22.4 36.35 36.35 0 0 1 12.6-5.6 65.89 65.89 0 0 1 15.8-1.8c7.2 0 13.3.8 18.2 2.5a34.46 34.46 0 0 1 11.9 6.5 28.21 28.21 0 0 1 6.9 9.3 42.1 42.1 0 0 1 3.2 11l-16.8 2.6c-1.4-5.9-3.7-10.2-7.1-13.1s-8.7-4.3-16.1-4.3a43.9 43.9 0 0 0-10.5 1.1 19.47 19.47 0 0 0-6.8 3.1 11.63 11.63 0 0 0-3.7 4.6 14.08 14.08 0 0 0-1.1 5.4c0 4.6 1.2 8 3.7 10.3s6.9 4 13.2 5.3l14.5 2.8c11.1 2.1 19.2 5.6 24.4 10.5s7.8 12.1 7.8 21.4a31.37 31.37 0 0 1-2.4 12.3 25.27 25.27 0 0 1-7.4 9.8 36.58 36.58 0 0 1-12.4 6.6 56 56 0 0 1-17.3 2.4c-13.4 0-24-2.8-31.6-8.5s-11.9-14.4-12.6-26.2h18z'/%3E%3Cpath fill='%23469ea2' d='M30.3 164l84 48.5 84-48.5V67l-84-48.5-84 48.5v97z'/%3E%3Cpath fill='%236acad1' d='M105.7 30.1l-61 35.2a18.19 18.19 0 0 1 0 3.3l60.9 35.2a14.55 14.55 0 0 1 17.3 0l60.9-35.2a18.19 18.19 0 0 1 0-3.3L123 30.1a14.55 14.55 0 0 1-17.3 0zm84 48.2l-61 35.6a14.73 14.73 0 0 1-8.6 15l.1 70a15.57 15.57 0 0 1 2.8 1.6l60.9-35.2a14.73 14.73 0 0 1 8.6-15V79.9a20 20 0 0 1-2.8-1.6zm-150.8.4a15.57 15.57 0 0 1-2.8 1.6v70.4a14.38 14.38 0 0 1 8.6 15l60.9 35.2a15.57 15.57 0 0 1 2.8-1.6v-70.4a14.38 14.38 0 0 1-8.6-15L38.9 78.7z'/%3E%3Cpath fill='%23469ea2' d='M114.3 29l75.1 43.4v86.7l-75.1 43.4-75.1-43.4V72.3L114.3 29m0-10.3l-84 48.5v97l84 48.5 84-48.5v-97l-84-48.5z'/%3E%3Cpath fill='%23469ea2' d='M114.9 132h-1.2A15.66 15.66 0 0 1 98 116.3v-1.2a15.66 15.66 0 0 1 15.7-15.7h1.2a15.66 15.66 0 0 1 15.7 15.7v1.2a15.66 15.66 0 0 1-15.7 15.7zm0 64.5h-1.2a15.65 15.65 0 0 0-13.7 8l14.3 8.2 14.3-8.2a15.65 15.65 0 0 0-13.7-8zm83.5-48.5h-.6a15.66 15.66 0 0 0-15.7 15.7v1.2a15.13 15.13 0 0 0 2 7.6l14.3-8.3V148zm-14.3-89a15.4 15.4 0 0 0-2 7.6v1.2a15.66 15.66 0 0 0 15.7 15.7h.6V67.2L184.1 59zm-69.8-40.3L100 26.9a15.73 15.73 0 0 0 13.7 8.1h1.2a15.65 15.65 0 0 0 13.7-8l-14.3-8.3zM44.6 58.9l-14.3 8.3v16.3h.6a15.66 15.66 0 0 0 15.7-15.7v-1.2a16.63 16.63 0 0 0-2-7.7zM30.9 148h-.6v16.2l14.3 8.3a15.4 15.4 0 0 0 2-7.6v-1.2A15.66 15.66 0 0 0 30.9 148z'/%3E%3Cpath fill='%23083b54' fill-opacity='0.15' d='M114.3 213.2v-97.1l-84-48.5v97.1z'/%3E%3Cpath fill='%23083b54' fill-opacity='0.05' d='M198.4 163.8v-97l-84 48.5v97.1z'/%3E%3C/svg%3E%0A"); - background-repeat:no-repeat; - background-size:contain -} - -.ipfs-mid { - background-repeat:no-repeat; - background-size:contain -} - -.ipfs-mkv { - background-image:url("data:image/svg+xml;charset=utf8,%3Csvg id='Layer_2' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 72 100'%3E%3Cstyle/%3E%3ClinearGradient id='SVGID_1_' gradientUnits='userSpaceOnUse' x1='36.2' y1='101' x2='36.2' y2='3.005' gradientTransform='matrix(1 0 0 -1 0 102)'%3E%3Cstop offset='0' stop-color='%23e2cde4'/%3E%3Cstop offset='.17' stop-color='%23e0cae2'/%3E%3Cstop offset='.313' stop-color='%23dbc0dd'/%3E%3Cstop offset='.447' stop-color='%23d2b1d4'/%3E%3Cstop offset='.575' stop-color='%23c79dc7'/%3E%3Cstop offset='.698' stop-color='%23ba84b9'/%3E%3Cstop offset='.819' stop-color='%23ab68a9'/%3E%3Cstop offset='.934' stop-color='%239c4598'/%3E%3Cstop offset='1' stop-color='%23932a8e'/%3E%3C/linearGradient%3E%3Cpath d='M45.2 1l27 26.7V99H.2V1h45z' fill='url(%23SVGID_1_)'/%3E%3Cpath d='M45.2 1l27 26.7V99H.2V1h45z' fill-opacity='0' stroke='%23882383' stroke-width='2'/%3E%3Cpath d='M7.5 91.1V71.2h6.1l3.6 13.5 3.6-13.5h6.1V91h-3.8V75.4l-4 15.6h-3.9l-4-15.6V91H7.5zm23.5 0V71.2h4V80l8.2-8.8h5.4L41.1 79l8 12.1h-5.2l-5.5-9.3-3.4 3.3v6h-4zm25.2 0L49 71.3h4.4L58.5 86l4.9-14.7h4.3l-7.2 19.8h-4.3z' fill='%23fff'/%3E%3ClinearGradient id='SVGID_2_' gradientUnits='userSpaceOnUse' x1='18.2' y1='50.023' x2='18.2' y2='50.023' gradientTransform='matrix(1 0 0 -1 0 102)'%3E%3Cstop offset='.005' stop-color='%23963491'/%3E%3Cstop offset='1' stop-color='%2370136b'/%3E%3C/linearGradient%3E%3ClinearGradient id='SVGID_3_' gradientUnits='userSpaceOnUse' x1='11.511' y1='51.716' x2='65.211' y2='51.716' gradientTransform='matrix(1 0 0 -1 0 102)'%3E%3Cstop offset='.005' stop-color='%23963491'/%3E%3Cstop offset='1' stop-color='%2370136b'/%3E%3C/linearGradient%3E%3Cpath d='M64.3 55.5c-1.7-.2-3.4-.3-5.1-.3-7.3-.1-13.3 1.6-18.8 3.7S29.6 63.6 23.3 64c-3.4.2-7.3-.6-8.5-2.4-.8-1.3-.8-3.5-1-5.7-.6-5.7-1.6-11.7-2.4-17.3.8-.9 2.1-1.3 3.4-1.7.4 1.1.2 2.7.6 3.8 7.1.7 13.6-.4 20-1.5 6.3-1.1 12.4-2.2 19.4-2.6 3.4-.2 6.9-.2 10.3 0m-9.9 15.3c.5-.2 1.1-.3 1.9-.2.2-3.7.3-7.3.3-11.2-6.2.2-11.9.9-17 2.2.2 4 .4 7.8.3 12 4-1.1 7.7-2.5 12.6-2.7m2-12.1h1.1c.4-.4.2-1.2.2-1.9-1.5-.6-1.8 1-1.3 1.9zm3.9-.2h1.5V38h-1.3c0 .7-.4.9-.2 1.7zm4 0c.5-.1.8 0 1.1.2.4-.3.2-1.2.2-1.9h-1.3v1.7zm-11.5.3h.9c.4-.3.2-1.2.2-1.9-1.4-.4-1.6 1.2-1.1 1.9zm-4 .4c.7.2.8-.3 1.5-.2v-1.7c-1.5-.4-1.7.6-1.5 1.9zm-3.6-1.1c0 .6-.1 1.4.2 1.7.5.1.5-.4 1.1-.2-.2-.6.5-2-.4-1.9-.1.4-.8.1-.9.4zm-31.5.8c.4-.1 1.1.6 1.3 0-.5 0-.1-.8-.2-1.1-.7.2-1.3.3-1.1 1.1zm28.3-.4c-.3.3.2 1.1 0 1.9.6.2.6-.3 1.1-.2-.2-.6.5-2-.4-1.9-.1.3-.4.2-.7.2zm-3.5 2.8c.5-.1.9-.2 1.3-.4.2-.8-.4-.9-.2-1.7h-.9c-.3.3-.1 1.3-.2 2.1zm26.9-1.8c-2.1-.1-3.3-.2-5.5-.2-.5 3.4 0 7.8-.5 11.2 2.4 0 3.6.1 5.8.3M33.4 41.6c.5.2.1 1.2.2 1.7.5-.1 1.1-.2 1.5-.4.6-1.9-.9-2.4-1.7-1.3zm-4.7.6v1.9c.9.2 1.2-.2 1.9-.2-.1-.7.2-1.7-.2-2.1-.5.2-1.3.1-1.7.4zm-5.3.6c.3.5 0 1.6.4 2.1.7.1.8-.4 1.5-.2-.1-.7-.3-1.2-.2-2.1-.8-.2-.9.3-1.7.2zm-7.5 2H17c.2-.9-.4-1.2-.2-2.1-.4.1-1.2-.3-1.3.2.6.2-.1 1.7.4 1.9zm3.4 1c.1 4.1.9 9.3 1.4 13.7 8 .1 13.1-2.7 19.2-4.5-.5-3.9.1-8.7-.7-12.2-6.2 1.6-12.1 3.2-19.9 3zm.5-.8h1.1c.4-.5-.2-1.2 0-2.1h-1.5c.1.7.1 1.6.4 2.1zm-5.4 7.8c.2 0 .3.2.4.4-.4-.7-.7.5-.2.6.1-.2 0-.4.2-.4.3.5-.8.7-.2.8.7-.5 1.3-1.2 2.4-1.5-.1 1.5.4 2.4.4 3.8-.7.5-1.7.7-1.9 1.7 1.2.7 2.5 1.2 4.2 1.3-.7-4.9-1.1-8.8-1.6-13.7-2.2.3-4-.8-5.1-.9.9.8.6 2.5.8 3.6 0-.2 0-.4.2-.4-.1.7.1 1.7-.2 2.1.7.3.5-.2.4.9m44.6 3.2h1.1c.3-.3.2-1.1.2-1.7h-1.3v1.7zm-4-1.4v1.3c.4.4.7-.2 1.5 0v-1.5c-.6 0-1.2 0-1.5.2zm7.6 1.4h1.3v-1.5h-1.3c.1.5 0 1 0 1.5zm-11-1v1.3h1.1c.3-.3.4-1.7-.2-1.7-.1.4-.8.1-.9.4zm-3.6.4c.1.6-.3 1.7.4 1.7 0-.3.5-.2.9-.2-.2-.5.4-1.8-.4-1.7-.1.3-.6.2-.9.2zm-3.4 1v1.5c.7.2.6-.4 1.3-.2-.2-.5.4-1.8-.4-1.7-.1.3-.8.2-.9.4zM15 57c.7-.5 1.3-1.7.2-2.3-.7.4-.8 1.6-.2 2.3zm26.1-1.3c-.1.7.4.8.2 1.5.9 0 1.2-.6 1.1-1.7-.4-.5-.8.1-1.3.2zm-3 2.7c1 0 1.2-.8 1.1-1.9h-.9c-.3.4-.1 1.3-.2 1.9zm-3.6-.4v1.7c.6-.1 1.3-.2 1.5-.8-.6 0 .3-1.6-.6-1.3 0 .4-.7.1-.9.4zM16 60.8c-.4-.7-.2-2-1.3-1.9.2.7.2 2.7 1.3 1.9zm13.8-.9c.5 0 .1.9.2 1.3.8.1 1.2-.2 1.7-.4v-1.7c-.9-.1-1.6.1-1.9.8zm-4.7.6c0 .8-.1 1.7.4 1.9 0-.5.8-.1 1.1-.2.3-.3-.2-1.1 0-1.9-.7-.2-1 .1-1.5.2zM19 62.3v-1.7c-.5 0-.6-.4-1.3-.2-.1 1.1 0 2.1 1.3 1.9zm2.5.2h1.3c.2-.9-.3-1.1-.2-1.9h-1.3c-.1.9.2 1.2.2 1.9z' fill='url(%23SVGID_3_)'/%3E%3ClinearGradient id='SVGID_4_' gradientUnits='userSpaceOnUse' x1='45.269' y1='74.206' x2='58.769' y2='87.706' gradientTransform='matrix(1 0 0 -1 0 102)'%3E%3Cstop offset='0' stop-color='%23f9eff6'/%3E%3Cstop offset='.378' stop-color='%23f8edf5'/%3E%3Cstop offset='.515' stop-color='%23f3e6f1'/%3E%3Cstop offset='.612' stop-color='%23ecdbeb'/%3E%3Cstop offset='.69' stop-color='%23e3cce2'/%3E%3Cstop offset='.757' stop-color='%23d7b8d7'/%3E%3Cstop offset='.817' stop-color='%23caa1c9'/%3E%3Cstop offset='.871' stop-color='%23bc88bb'/%3E%3Cstop offset='.921' stop-color='%23ae6cab'/%3E%3Cstop offset='.965' stop-color='%239f4d9b'/%3E%3Cstop offset='1' stop-color='%23932a8e'/%3E%3C/linearGradient%3E%3Cpath d='M45.2 1l27 26.7h-27V1z' fill='url(%23SVGID_4_)'/%3E%3Cpath d='M45.2 1l27 26.7h-27V1z' fill-opacity='0' stroke='%23882383' stroke-width='2' stroke-linejoin='bevel'/%3E%3C/svg%3E"); - background-repeat:no-repeat; - background-size:contain -} - -.ipfs-mov { - background-image:url("data:image/svg+xml;charset=utf8,%3Csvg id='Layer_2' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 72 100'%3E%3Cstyle/%3E%3ClinearGradient id='SVGID_1_' gradientUnits='userSpaceOnUse' x1='36.2' y1='101' x2='36.2' y2='3.005' gradientTransform='matrix(1 0 0 -1 0 102)'%3E%3Cstop offset='0' stop-color='%23e2cde4'/%3E%3Cstop offset='.17' stop-color='%23e0cae2'/%3E%3Cstop offset='.313' stop-color='%23dbc0dd'/%3E%3Cstop offset='.447' stop-color='%23d2b1d4'/%3E%3Cstop offset='.575' stop-color='%23c79dc7'/%3E%3Cstop offset='.698' stop-color='%23ba84b9'/%3E%3Cstop offset='.819' stop-color='%23ab68a9'/%3E%3Cstop offset='.934' stop-color='%239c4598'/%3E%3Cstop offset='1' stop-color='%23932a8e'/%3E%3C/linearGradient%3E%3Cpath d='M45.2 1l27 26.7V99H.2V1h45z' fill='url(%23SVGID_1_)'/%3E%3Cpath d='M45.2 1l27 26.7V99H.2V1h45z' fill-opacity='0' stroke='%23882383' stroke-width='2'/%3E%3Cpath d='M6.1 91.1V71.2h6.1l3.6 13.5 3.6-13.5h6.1V91h-3.8V75.4l-4 15.6h-3.9l-4-15.6V91H6.1zm22.6-9.8c0-2 .3-3.7.9-5.1.5-1 1.1-1.9 1.9-2.7.8-.8 1.7-1.4 2.6-1.8 1.2-.5 2.7-.8 4.3-.8 3 0 5.3.9 7.1 2.7 1.8 1.8 2.7 4.3 2.7 7.6 0 3.2-.9 5.7-2.6 7.5-1.8 1.8-4.1 2.7-7.1 2.7s-5.4-.9-7.1-2.7c-1.8-1.8-2.7-4.3-2.7-7.4zm4.1-.2c0 2.2.5 4 1.6 5.1 1 1.2 2.4 1.7 4 1.7s2.9-.6 4-1.7c1-1.2 1.6-2.9 1.6-5.2 0-2.3-.5-4-1.5-5.1-1-1.1-2.3-1.7-4-1.7s-3 .6-4 1.7c-1.1 1.2-1.7 3-1.7 5.2zm23.6 10l-7.2-19.8h4.4L58.7 86l4.9-14.7h4.3l-7.2 19.8h-4.3z' fill='%23fff'/%3E%3ClinearGradient id='SVGID_2_' gradientUnits='userSpaceOnUse' x1='18.2' y1='50.023' x2='18.2' y2='50.023' gradientTransform='matrix(1 0 0 -1 0 102)'%3E%3Cstop offset='.005' stop-color='%23963491'/%3E%3Cstop offset='1' stop-color='%2370136b'/%3E%3C/linearGradient%3E%3ClinearGradient id='SVGID_3_' gradientUnits='userSpaceOnUse' x1='11.511' y1='51.716' x2='65.211' y2='51.716' gradientTransform='matrix(1 0 0 -1 0 102)'%3E%3Cstop offset='.005' stop-color='%23963491'/%3E%3Cstop offset='1' stop-color='%2370136b'/%3E%3C/linearGradient%3E%3Cpath d='M64.3 55.5c-1.7-.2-3.4-.3-5.1-.3-7.3-.1-13.3 1.6-18.8 3.7S29.6 63.6 23.3 64c-3.4.2-7.3-.6-8.5-2.4-.8-1.3-.8-3.5-1-5.7-.6-5.7-1.6-11.7-2.4-17.3.8-.9 2.1-1.3 3.4-1.7.4 1.1.2 2.7.6 3.8 7.1.7 13.6-.4 20-1.5 6.3-1.1 12.4-2.2 19.4-2.6 3.4-.2 6.9-.2 10.3 0m-9.9 15.3c.5-.2 1.1-.3 1.9-.2.2-3.7.3-7.3.3-11.2-6.2.2-11.9.9-17 2.2.2 4 .4 7.8.3 12 4-1.1 7.7-2.5 12.6-2.7m2-12.1h1.1c.4-.4.2-1.2.2-1.9-1.5-.6-1.8 1-1.3 1.9zm3.9-.2h1.5V38h-1.3c0 .7-.4.9-.2 1.7zm4 0c.5-.1.8 0 1.1.2.4-.3.2-1.2.2-1.9h-1.3v1.7zm-11.5.3h.9c.4-.3.2-1.2.2-1.9-1.4-.4-1.6 1.2-1.1 1.9zm-4 .4c.7.2.8-.3 1.5-.2v-1.7c-1.5-.4-1.7.6-1.5 1.9zm-3.6-1.1c0 .6-.1 1.4.2 1.7.5.1.5-.4 1.1-.2-.2-.6.5-2-.4-1.9-.1.4-.8.1-.9.4zm-31.5.8c.4-.1 1.1.6 1.3 0-.5 0-.1-.8-.2-1.1-.7.2-1.3.3-1.1 1.1zm28.3-.4c-.3.3.2 1.1 0 1.9.6.2.6-.3 1.1-.2-.2-.6.5-2-.4-1.9-.1.3-.4.2-.7.2zm-3.5 2.8c.5-.1.9-.2 1.3-.4.2-.8-.4-.9-.2-1.7h-.9c-.3.3-.1 1.3-.2 2.1zm26.9-1.8c-2.1-.1-3.3-.2-5.5-.2-.5 3.4 0 7.8-.5 11.2 2.4 0 3.6.1 5.8.3M33.4 41.6c.5.2.1 1.2.2 1.7.5-.1 1.1-.2 1.5-.4.6-1.9-.9-2.4-1.7-1.3zm-4.7.6v1.9c.9.2 1.2-.2 1.9-.2-.1-.7.2-1.7-.2-2.1-.5.2-1.3.1-1.7.4zm-5.3.6c.3.5 0 1.6.4 2.1.7.1.8-.4 1.5-.2-.1-.7-.3-1.2-.2-2.1-.8-.2-.9.3-1.7.2zm-7.5 2H17c.2-.9-.4-1.2-.2-2.1-.4.1-1.2-.3-1.3.2.6.2-.1 1.7.4 1.9zm3.4 1c.1 4.1.9 9.3 1.4 13.7 8 .1 13.1-2.7 19.2-4.5-.5-3.9.1-8.7-.7-12.2-6.2 1.6-12.1 3.2-19.9 3zm.5-.8h1.1c.4-.5-.2-1.2 0-2.1h-1.5c.1.7.1 1.6.4 2.1zm-5.4 7.8c.2 0 .3.2.4.4-.4-.7-.7.5-.2.6.1-.2 0-.4.2-.4.3.5-.8.7-.2.8.7-.5 1.3-1.2 2.4-1.5-.1 1.5.4 2.4.4 3.8-.7.5-1.7.7-1.9 1.7 1.2.7 2.5 1.2 4.2 1.3-.7-4.9-1.1-8.8-1.6-13.7-2.2.3-4-.8-5.1-.9.9.8.6 2.5.8 3.6 0-.2 0-.4.2-.4-.1.7.1 1.7-.2 2.1.7.3.5-.2.4.9m44.6 3.2h1.1c.3-.3.2-1.1.2-1.7h-1.3v1.7zm-4-1.4v1.3c.4.4.7-.2 1.5 0v-1.5c-.6 0-1.2 0-1.5.2zm7.6 1.4h1.3v-1.5h-1.3c.1.5 0 1 0 1.5zm-11-1v1.3h1.1c.3-.3.4-1.7-.2-1.7-.1.4-.8.1-.9.4zm-3.6.4c.1.6-.3 1.7.4 1.7 0-.3.5-.2.9-.2-.2-.5.4-1.8-.4-1.7-.1.3-.6.2-.9.2zm-3.4 1v1.5c.7.2.6-.4 1.3-.2-.2-.5.4-1.8-.4-1.7-.1.3-.8.2-.9.4zM15 57c.7-.5 1.3-1.7.2-2.3-.7.4-.8 1.6-.2 2.3zm26.1-1.3c-.1.7.4.8.2 1.5.9 0 1.2-.6 1.1-1.7-.4-.5-.8.1-1.3.2zm-3 2.7c1 0 1.2-.8 1.1-1.9h-.9c-.3.4-.1 1.3-.2 1.9zm-3.6-.4v1.7c.6-.1 1.3-.2 1.5-.8-.6 0 .3-1.6-.6-1.3 0 .4-.7.1-.9.4zM16 60.8c-.4-.7-.2-2-1.3-1.9.2.7.2 2.7 1.3 1.9zm13.8-.9c.5 0 .1.9.2 1.3.8.1 1.2-.2 1.7-.4v-1.7c-.9-.1-1.6.1-1.9.8zm-4.7.6c0 .8-.1 1.7.4 1.9 0-.5.8-.1 1.1-.2.3-.3-.2-1.1 0-1.9-.7-.2-1 .1-1.5.2zM19 62.3v-1.7c-.5 0-.6-.4-1.3-.2-.1 1.1 0 2.1 1.3 1.9zm2.5.2h1.3c.2-.9-.3-1.1-.2-1.9h-1.3c-.1.9.2 1.2.2 1.9z' fill='url(%23SVGID_3_)'/%3E%3ClinearGradient id='SVGID_4_' gradientUnits='userSpaceOnUse' x1='45.269' y1='74.206' x2='58.769' y2='87.706' gradientTransform='matrix(1 0 0 -1 0 102)'%3E%3Cstop offset='0' stop-color='%23f9eff6'/%3E%3Cstop offset='.378' stop-color='%23f8edf5'/%3E%3Cstop offset='.515' stop-color='%23f3e6f1'/%3E%3Cstop offset='.612' stop-color='%23ecdbeb'/%3E%3Cstop offset='.69' stop-color='%23e3cce2'/%3E%3Cstop offset='.757' stop-color='%23d7b8d7'/%3E%3Cstop offset='.817' stop-color='%23caa1c9'/%3E%3Cstop offset='.871' stop-color='%23bc88bb'/%3E%3Cstop offset='.921' stop-color='%23ae6cab'/%3E%3Cstop offset='.965' stop-color='%239f4d9b'/%3E%3Cstop offset='1' stop-color='%23932a8e'/%3E%3C/linearGradient%3E%3Cpath d='M45.2 1l27 26.7h-27V1z' fill='url(%23SVGID_4_)'/%3E%3Cpath d='M45.2 1l27 26.7h-27V1z' fill-opacity='0' stroke='%23882383' stroke-width='2' stroke-linejoin='bevel'/%3E%3C/svg%3E"); - background-repeat:no-repeat; - background-size:contain -} - -.ipfs-mp3 { - background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAnxJREFUeNp0U89PE0EU/ra7XWxpSsFYIbVQf9REFBHkYBRIPJh4wrN3DsZ4MPGP8b/wUCIHEw5EY0w04o9ILcREGmwVgaXbbXdnd2bXNxPahGyczebtzrz3ve99740WRRHkWn5cebu4cH6SMY7e0jRAHr9c3WxsVvcemmbys9yT6+uHJ8oaPefypdPDD5Ymh5w26wMkEho8JtDtuEOZFCrvN/4uJZNGH0T59D58X/C27aFNAL3Xthmsww5GCyN4+uzu+OLtQsUPxPQx6ZMAoQjBAw7O+bEVCMMQgqygs+LFs1h+dGd8bna0QmXO9OL6JYgwAvOFZKKoy3V44CgNfv7Yx8oLH+lUEgvzF8Ydhz+n41snAGRG5gUEwClzhHdvttFxfNyYK0EnJozKK5eGcf1qHo1GOxtjwI+pfvm4g/W1qtJgerYE2SXJSIL9+W0jk0mCShAxDXgQKgbNXxZq35vQKCiKQkSUXdc1+gcch1FHGPmKuIgBCdc66qJQHMG9+1NIpUylxxHtuW6gEiTIu+N4yjdWgty0yTmdNjFzcwKjY0MU7MLt+IjoSad16FoIx3b/A0DZ7FYXnsdpAjUMDOjI5zPgfoBsRodhhGhZHfBBU/nGAGRtxWIOg5lT2NtrI5dL0SB5KJzLodloqXaOEatPGztKq5gG3S5DNjuAK5NjKJfPYKI0okBkSdemCiSgS/rkQNLSePtxBj4LSCwfFtE0krqqX7ZVMnu9XlMXy2l7ME0dzA3iANQyY6vWxC61UY41zTyNcYh6/QCNXQvzi5dR39nHVq1BUyuMGAARsF6tbbe4iKD1r7Om5iFBdmW1SsDflLiuB6sX90+AAQDHAW7dW0YnzgAAAABJRU5ErkJggg==); - background-repeat:no-repeat; - background-size:contain -} - -.ipfs-mp4 { - background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAnBJREFUeNpsk99r01AUx79psrTrujVtbceabnZs4DYRHSoMh6Dgq77rn+AfoA/+If4Bok+C0CfxVRDBh+I2NqZzrpS1DVvbtU3SJPcm8SSlsJlecsn9dT73nO85V/B9H0H78OLdt/LDlQ1uMYybIAgI9n99OWxoe83nkiz9hDDae330JvxL48O51Xxm/enNtKPbVwAh0Ec6kYpXat9Pnl2GBC02HrjM5Y7h4P8+7FtIFVJ49OrxUnl7ucIdfhv+BIDv+fBcj7p/tXMPrs2RXVTw4OX2UnFTrXCbbY7tpMsA13FDSDAOQ4gJEGUJLs0PPh9CkESsPrmxxEz2lra3rnpAt3G6adgdQhBpmeLkFodNmsjpOPoXBrQTDcmFFNS7i3MRDzzPCw/vva8ikU+COQxm14BBhvJcHLGpGPTOAJxxeLbrRgAkYujBdH4G5oWJWXUW19YL4XqunAMFhnq1BqWYgaY1MAHASQOiU96zKzkU76mwehaOvx6h9uMv7KFN3RopL4oTAI4HRh4wSl399xla+00YbR3yrIzM9SzSqgJJnoKcklGrH08CcJjnBtLLCsSEGGpSWJvHtDKNoFippsJ0ulIsDDUCCATMlBQkNuahEyiZTcLsmFBKaQxaOk53TlHeKkM70AjAooCghBOk9sKtIvqtPqS4FBaRnJSRX8tj2DOh3lFB5Qw2ZNFK5LRo6w4sKt2ggAzywidAMN/9uIPSZglBLDO5FF3mRD3wHE9qVRvoHrUpfn+UEQK0/7ShtwboHJ6jdH8RZxSC57hSVETb7e5/2u0FxqPHJow+8iZ4lYY2QGu3idhIxO7Y7p8AAwALCGZKEPBGCgAAAABJRU5ErkJggg==); - background-repeat:no-repeat; - background-size:contain -} - -.ipfs-mpg { - background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAnxJREFUeNpsU0tPE1EU/ubRdlqmnUBboa0UeUQDiUGCC1+JmrhxoXt/gBvXJi74If4AV0Y3sNKF0YUaICqoIfjgVShEiGF4tDOdO/fOeOaSKtie5GZu7pzz3e/c7ztKGIaI4vn9p+/P3h4e4a6Pv6EoQBDiy7P5rc1P1Xt6XP8M5ejXo6UJ+dWbuemeTGdpvNdiNe9YvQLe4Bi4PmTpRmyq8m71rp74BxKF2twIHvAo+f/l1T2Yp0zceHizfOZa/xRnfBRhG4CQqAYioBWeXDyA8Di6ei1ceXC1XBwrTXHPH2vW6ccBBBMI6BsSUEQzakGL6xB0tvjyBxRNxdCtc2Xf8R9TyaWTDOg2TjfVdw6hqIoE9B2GxkEDWlLH7s4ette2kSp0oDRezrQwCIIA3oGHr0/mKMmE53qo23W4+w5S+Q5ohob9X3tgHgO8ULQACC7gMx9mKQP30EW6mEHpYi8xcJEdzMucjfkKcrTfmqmiFYBxCF/Id+gayKJwoQjHdrA5v4HK7Cq44KjZNWpagaqp7QACks0H9znW365ia24DzoEDozOJbH8eVtGShXHTwNracnsG7q6LzsEuaAlNPm9h7DSSVjLyCMkppDI+GS2StQWA1RlKo0X56n2X+6QHkmkDakxF9WMVqWyK+s/BrthYfvWz1Ug+zUDcjMPMm0h3pxEjFma3CbIuCud7oMc0LL1ZgmElpGJtW3B+15HIGNITrMYIlOH7i0U41NrInREylYbu4R5qQbQBaAh95fVKZCnpQCnb9DrWZyrRERS6NDeUw+yHaXh7rt4C4B8y+9vkwn7kwKNRpDoa9aiFKBYnF+RcREqQ2e1m3R8BBgAy9kz9ysCE6QAAAABJRU5ErkJggg==); - background-repeat:no-repeat; - background-size:contain -} - -.ipfs-odf { - background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAi5JREFUeNp0UktrU0EU/mbu3FfE1KRRUpWYheALNBURUVy7cy9UkO6KW/+Lbt0IPsFui4gLBbUqFaUuXETUKCYa0jS5yZ2ZO557b5MmTXpgmDPnfOc7jznMGINYPi0de5UvmpORxpjE/kbNqW005DVu8TWw1H758ZfkFgNgJmtyxSPRjJIj0QTW/RDiYGXGb7Dl32/eXrVsd0gSCx9miqC0ooCdp69g5Q/h6OLN0ty5ynIkwzMwUwh2FwMdcbDiCZQXlkqFCpEoPT/wih1YjLInANcD+/Ua9bu3wJlGvrBZCmet2+S6ME5g4oGlZ9A/I70XCDhhDexPNTFmswJBwcnuXkF86VSNZxVu0ukLSGnBcqlnN4HoCQIaIuIv7LUooMOgQ7q75LAAb59B9gCBHSKgqemRr94mMKmD24CfM8nb7THYGQNLpAkUkcb66JyGBFFEWRVL57gFEH5qj8Lxwca2qS3EZaugmzAw24dR/XQgwtsCSBjPIdWbUoE2UJLBnV8Ac/ciWHsK9/glWLnD6K2vgPszsOdOQdfeQ1c/ThKoTgDn9A3KUED/52d45xchZsvorD6Bf/Z60riV3Q9Z/0bbGU1uopYGkfERSQ3VbsMwl0qlqoIARmSoPYXWy0dor79LfBMEEd8jGs/uQ3Yl7PJFNFbuEXiV2riCf88fovXhBbo/vqP3t02/ZYmJFqTkzY160Go9uEMbFK8hR/NrdXtFuUVmnmySVGgO4v4LMAAjRgmO+SJJiQAAAABJRU5ErkJggg==); - background-repeat:no-repeat; - background-size:contain -} - -.ipfs-ods { - background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAetJREFUeNqMUj1IHEEU/i7u7Z23e8tGgneGQPw3hZDkkhQiSuwMQREba4uUgpVlCrvEQhurkCoWqcQQ0oTAaYKNqJygGEwgHCSB6Knn7eXcdX/GmdHVPWYFP3gw78173/vmvYkQQsAwNvckq96UnyIEh7/d4t7uUd/8y+85P+bXSX4grkhI6nJYPW7LrXpBK2YxiSoShhu4Buq1NPofDeqdrZ3Z4cl7D4J3UtA5VyVAlmJoru9Af2ZAp1lcCQ3nqgiuKmbY3l/BH+MnHM9GVLP0Ww3KNA33CQoQQnL834Fj74PUGkANEIkCSSsa8gQqgYTIcB0PVsXB318GInRiCVWCkpRFAs+j5gKlA4t29Ggh4d0t04FKt9PQqF4UFgumSEA8ApeaElilWbYRVy/lsns/N1QBkxtENF4jxPxcgcB1CZVOrvMteK5IQDtJJIGh++PcX9iYwWjXK37+vP0WdYk0Ht99jtX8JywWFkQChw4tc+cZcvlF7rMze+ubbxN40fMalRMDP/6twaiUeK7wlZ0TD0a5hLTWxo2d45KKprqHKJslTsy209s2wnMFBTYNZjc/oLt9gPvLOx+hxVJIKS2YW5pCbSyJTGMK775O8VyBwDJd2LTDl/X5i8v3S7NVw9vJb51tITDEUwEGANCx2/rXEEFFAAAAAElFTkSuQmCC); - background-repeat:no-repeat; - background-size:contain -} - -.ipfs-odt { - background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAepJREFUeNqMkz1II1EQx/+7Ca6JkqyYiJ8cKEpAQbBQFDm0sVOsFBS9wt5KOTgEG5twxVlZ+XEnKNiIghYKxx5nwEpIIXaiSAgKGmMi0d23u8+3T7OaZJEMLG9mmPnN/w1vBUopLPNNhRWXHOyDg0nx82TiJtZPlPVoNpftc2cTotcHtxx06kdXpSQ/BvzKESZzIDmAz6y+NojOjpDMZiqRPIgNoFyWM8DrKUV7axO+gcp4g7AzmquAdVNqOgL2z2I4id1B0wgeygOyt/rLL5buLwAIDgA9dY+L+DkuDQOCrkMgBsRglcMOqAGwIstMg8AkGsuZMNUMRMkLqE+QGloglvlA7uIOAKvZajR0qJkUj/XHe0BTIclVKKlrfKsj9qA8gA6wqSJzPaXlr7ky//tdLEUfawsBjExUFGVWbT7AxSa42H2LMfODmvd3wKb7RAMLYwM8nts8xJ/pEe7/3PmP2eGv3D+9usb35W0bINoA7RmjXSHsH0f5Z/mUSZ0Ir2JmsBtD80s8/rGyzWsLFTD5yUQCbfUBHl9d38LvkdDTXIuHVBo0k+bbt06qO+yAPGXwe/cA4wO9PN44jKDG70GougIzi2tQ00ms7/3lpwnBBgjZ37Kkd1Shht5XzBIFl/ufFtniT/lFgAEAU//g6kvdGBMAAAAASUVORK5CYII=); - background-repeat:no-repeat; - background-size:contain -} - -.ipfs-otp { - background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAcJJREFUeNqMkssvA1EUxr+ZjkdbrfFKVD12ErYSRELY2fkH+BMsLcQaSwsrSzZi47EjJEQkEhYkFlhYSVtFpdqOqpk717l3jKZmiC+5mZlzv/s795wzCuccQncz3YeRBj4KHz0/RrOZe2NsZPP20o255zQ3EAxzEAC+6uzTw13G4TFQAakA/CWtIYbY0KBOrx7IvwDQqlHV1o3YxKTOvyAUvfQCfqmA3e4ikyS/zRAKvOot7eoSHEgZIHrCfQAfBqBaKQQDKScQAExd8emBANg+2U2CvNMkkgSqBmrCxFB8mujeoJBWwEqARcssKTAJEGrmaGrjqK1zvNknH4BtyxKl2VUpRxmj5W+x73q9AEaZrR/ND1EJluIpS3i9JQiA+a+hSq8HwJjTsLrRaWitPTCOlhEZn5N75sM1qigmlN+dB3u++Qao5W4TtbEXXIsiszGL4PA00itTsu6XnQWo0TjMTAJqfMDx/ryBJcaVzSNSH4fW0Q+rkIf5rsjRiid7yyN7uoXS3Zn0egE0NiORAN9bQ017D1Lri7CLlP2EDr3Rf7C/itzV2bfXA/igLDaRixfngFhSCooH2xVPCWBlwKcAAwBX1suA6te+hAAAAABJRU5ErkJggg==); - background-repeat:no-repeat; - background-size:contain -} - -.ipfs-ots { - background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAfZJREFUeNqMUk1rE1EUPS8zmabJdDKB2glEwY9ExJYiBUEQpV25qgtBXfgbpEtXuujKf+AfEKRddOdOGHClbYVCvyKWaijT2mhjphk7Sd7Me76ZONp0EsiBYWbOvfe88+69hHOOAE9f3zTVnDKNHvhlsfqPw/rM0ovyWsRFdXJEpDIyRnSlVz0KSkmvabaJeXSJBEhgAJzTDNybmtUnS5Pmg/lrN07H5NM/f13FoMgpXDSuhiIiK3Qi6LUugX7FAbaPPsJqfIHHKCStqRsXVFPQuZgD9BBxjikSiRq41AAkgCQBzVf0+BWEBX7GBm0xgHHUqk1UbBuEcIydzyCZlOI9YEGuDxwduCCitS3Xh3viCZ4jrcq4PJ6DLHd67tjtuAAXib54dCPVEfQ5XIcik/0/2iDeOYz3ceCxrisMi904y0XiMQFfkB7lg6xFHwFxEqUMV0anUNBLWKm8xd3i4zBWOzmASx0UsiW831mA59Xjm+h7HCOygduXHqJatzA7Poey9QnXjTuoVD/j/sRcmDOWLgqnLC5A2wwST+Pn8T629lahSCo291bwu9XA7vcy3m2+gTaUR14thrk9BXasbdiOjSe3nmPpwys0xSi/HpbDd3bIQC6dx/q3ZbRb/j8BEi3Po5cTJpHI9CBNDEa++GyDBN9/BBgAwfDlCVUQaNAAAAAASUVORK5CYII=); - background-repeat:no-repeat; - background-size:contain -} - -.ipfs-ott { - background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAdFJREFUeNqMU89r02AYfpJ0iVm7EqhVOxw7dDBEdpiCE1RoEZRddvUgbIex/Rs7eehppyF4LOzQu4MxwYp0HgShIuwwUVSCVtl0s13afl+SzzcpyZYmyF74eN583/s+PO+PSEIIeJZdrtQVI19Cgmk/Ph39bpllXq82g7sgLxVcyKNZpIx8Uj5u5zSjc9Gov8ZihCRC8D+7On4JczevGeTGSEIC4ctKJtB1DTPXi1iCCEkIm1EFlC2Em0iwtWfinXkIzjiO0jljtDC5TtflGIGUQMB+mfja/oPv2Rx9MMjpMdJxOXyXTwkcwIkewfqQ1QtQNB385zcI14FrtQexsSb6SRysZ4Fbf+F6eHwATc9gJGNAm5iCTL5n/LCVRGADNoeaGoHqyaXj5gqQlTODovcwNk5Aj6wXqV8eCo7EDhMonEHpW+dZC7gUG98D3geo7vkb01h9cAvPdt76OGy1xntUd3bjUxAk3+l2sHJ/FgtrT0MUJNfDSm0bjQ/72Hzxxo+NK+h3B7XRNO4UrwymQtMIkdTBU0m+sBOayLsn8Ka78mQDjx/e87HXPkb1+UsfP37+AmZ1fP/suknBb6nefVQXjl06TxMlJfWKNWr+Kv8TYAAkUueexJF47QAAAABJRU5ErkJggg==); - background-repeat:no-repeat; - background-size:contain -} - -.ipfs-pdf { - background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAmhJREFUeNp0U0trU0EYPTP35qYxaW6TlDapNKWGbgo2FkF8rARB6rboXusf0F/hyq2U4krFqugqSBeuAyL4SERBstHa0iR9JKZJ7mvu+M0tqZGkH3x8987jzDnnm2FSSqh4ns0VU1ybFzj674Wa3uWiWbfsFQb+jrGj8Xvbm0HlvYVRxhJprpmTlGmum+OMm5uNPZNbtjk3l82ey8++8oW4Jv/H/wdA456g2kvH99FyHNiuAz2dwflbN8YW8zMK5Go/CMfQkAhpGsyQgRCtlpE4jIULyC9fHzu7MPPEl/5ib6WOE0JJNRiHHg6j86mMjw/2gG4bkbY4PW4Yj2j64skA5FTHdaEMPiAJszt1sK0d4suJmY4k0+IDDGRfqmh0u5gejQc+fG8eYCIahRQCEfgQnIuhEkgtONE+dGxYxEDj1DhiEycZ+1YXdUpHCqTMJIYyEES5aXXQsi2kYlGEia5GtHVKn+amPBeCutPgfLALPuVu+xDVPw2EQyFEjHDghbpYNm1yKVVnYjTOerepn4E6XQmLGSPkPkOXWATMSDcjQEkAaqOu6+i/rccALtFL53LI3r0Nq1ZD4/MXZJaWYFer+PXiJc6s3IEgY3+uPYZHTAcAHM+DTE8gnM1CSyaCulv+GrRy8uYyElcu4XfhLVpkpNtn/DGA5Uu0abFH36WnzzCayWAkmYJvWeCkfb9SwY+NDbSoOx4bYqJF8rZqVRRXV/HhzWtUSmWwmWl0RmN4v76OUqGASrmMOkntSHF8MOs954dT08W248wzYsJDOujRBAaqqikTpRo/qqd0/dv97c3Lat9fAQYA4z8bX9nTsb8AAAAASUVORK5CYII=); - background-repeat:no-repeat; - background-size:contain -} - -.ipfs-php { - background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAhNJREFUeNqMkltrE0EUx//ZbDaXNrvZzdIkbYOXGgxYQlCK2IIY6EufxGdB8Av44AdR8AP44JOPBR+Ego0PClUKTTXQSmkTYtOkmubSJrQ1e3H2yJSEJNIDs3PmP+f89pyZcdm2DcdWvn7LzkxFHmCIra7nm9ulg8yLZ09yXON55Dgjt1PM2iPs0+aW/frdh8bzV2/SvQBnCLiEqcFxLKSSodlrU9leiGPihWePBkgeEZO6ShC2dCAZNuf6ADb+ldQ5PUPx4BCFcgXfdwq4Ph1Dtd5CZi4Nw7SQiMdCXkl6yVIy/QBWgcU+yx/XsLK2cdHndqlK/lZxH/OpJO7fnsWY3z/YAq+g0TmHpoUH2vB5PXi8RD9Fo10aAmDJTgWyIuOupmK38rsPcOvqJO33XWEvwLJsmKxHRVEwf/MKWl/yUMf8mIloWN8rw+sP0D6PHQmYuzGNgCRiMZVA17IQV4OIaTI8buH/AJMFd02Tkp05PO4jnWvc57EDAINt7u1X8Pb9KgI+Lxbv3cFR8xjx6AQ+b+Txs/qL9KePlih2CMBCq92hg2qzt1AoV7H5YxdhdqhHzRbgcpFeqdUplpvQW4FhmAixZ/sws4BoWCM/qmsE5XqE3dDQCrqGAYWdejqZgK6GUD8+IV9VghBFN1RZJv3sT5diBwC15gncggCPJKF0WCPN8dun55jQdVpz3Ynl9leAAQAJhiGatD9AOgAAAABJRU5ErkJggg==); - background-repeat:no-repeat; - background-size:contain -} - -.ipfs-png { - background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAmtJREFUeNpsU9tOE1EUXXPp0CAUWmJbC04xBANNTF+kKhG8fID6aqL/gPEj9E0lIf6Dj30HL03wxQtVIC0QKrWxNG1Dk9Z2Oj1zxn1m0oIZTnIyZ8/ee+211z5Hsm0bYg29fLGpxWIJWBYGS5IA8ncKhT9Wvf4Yqprtu+w3q85X7f9QxseD/pmZMZsxN9fnc5JNw0ACGGv6tPSvyvEDKEoWZ5Y8OHHObKpucw4B0t3agnl4CJPs2YkQVu4s61ORaBqMJc8CDBiIRhhVM9bXYdVqYAcH8M3NgS0tQQsFcfdKHEbvlr6WyaR/V6uPKPy7B4DT7lUq4MUipMlJ2MPDUKtVfKZ2nn/5BoNbkONxXeb8LYXe/A9AJLNWCxgdhZJagDI9DZg9qIkEytRSkdqTSFQtGILSbgc8LViM+tc0yPfukzIyOJ359k9YR0eQdB2KmBbpwXoM3Dod1SkD+scpEapCI5DdpsJhIJcjajQZagcjI+5oLe4VkeQnyiZgdIH2X6BJ7dSqQLfrggjw0AQwP+/GegCIHppNoFAgEMO1RZKo7BQgRi3yN05cnwdA0BQMAgF3C6pnbuNg92M9AFT1diSCh6kb+FGvo2MxnBB9ocZxp4Mns1cde213B81e7xwAcl4jkaa0IUSjUdLJwkL0Ej6VSvArCt7l81iku6GrKnYEU89VJlSJRmR0Dax+fI9suYxSo4HlWIw6M3FBlnD9YhiXabyOsOeIqG7TzDeIYo6EDGp+ZPb2kKKqH8h+mkxiI5/D1/19J3bwYPvPWXq2skkiJVxesqt0XzghpKM8nRVV2Lv2q9eLIvSfAAMAaacnllcFBmYAAAAASUVORK5CYII=); - background-repeat:no-repeat; - background-size:contain -} - -.ipfs-ppt { - background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAkhJREFUeNpsU11rE0EUPTM7ySZpmzT9DNamWAtFfSiCigr+AxF9zKtv/hvf/Aki+FEi6ov4ItWHPGiwiBUKoUqqTUJImmR3M7Mz3t0kNe1m4LIwc+65595zlxljEJzdR5uf5nLmsvZx6gSvtd9W9bjhF7jg5dH9nRc/wq8YXaTSJptb0xklx7IZoKUEz1zJ2DUU69/37vFYrDxegJ9U0lC+AoIIVGg9CL+vIObP48KDQn7x0sWiVnJrnEDg7KGk+i/Ac4iUM/R7BsmrSSxtXMfa3X7el8+Kjf3KfUJ+iRJQw4w0Tc8BRyWGRAZY3rBR/VlC+XED2ayDhZyXl03+hNA3TxNQshlGLAnE44zCIL1goXZwiMNvB1i6zbC0KuAsxNITWwgNMYPeLVJiFEO9ArjHAivrAjNzBr4f4vwIgdGD4YUACsZCE8AtYGWT5jCsGQw5wEYJzP/pj5RwYTA1b07eQmfZ8P0sgdaM2FlYwWkMgMpl6NQAO33GKM0wsQWflkh1uqGVmVWblsiDkQyqxwfag35SqcktaEWTUTHYNx4iGU/C29+BvX4Lpu/C7zYgFjegSY63WySsHyXwpYHU00ieu0bAOuJbBTArBkiXKiaAmTzcvRJUV9E8rOgqBwqlY8ASs/AadbRLb8CzeTjVClqft6FdB17tL7yeCbFRBYoLr6vR/PiSEl5BZJaBD0/R2nkOZqfQ2fsKt+0SEQ+GLSIEUvJm+6jbah2+pS2aon+4g/afd4SYJVuA7vvXdC/IHQtSoTnK+yfAAIEaId1m+vudAAAAAElFTkSuQmCC); - background-repeat:no-repeat; - background-size:contain -} - -.ipfs-psd { - background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAqxJREFUeNpsU01ME0EYfbtdKKWGtoItRWgJHApCBE2I0YuoiSaaeDJeOJh41YN3TfTixcRwMfEk8eDJGA+Eg0YTTRRMg02KKFooCBbTlkJLS7f7P+u3K9Xo8iWT3Zn55s173/uGM00TVlwZfzJztD92iKO5ouvQGQPHcQDN380vlDPr65fdLj4Oa41i9sFt+ytgN7o7woGOrqgvvpLBaF8vWj1NUAwGTVNRM3mf5vU/zaU+XySQuTqIFXz9hxmGLkoS7r+YxvVnrzGzlgXPDOzUZPT4m3Dt/KlIuH9oUjXYEHZZ/wOgGQZi4TZcGI5hLb+FO++TSOSKcLtcMA0dI0EPrp4+HtnfG5skiUecDGwQE2MjAwiGWlFVNDz+tIyCokJhPKYSX7Gdz2I01hOJdnY9rJ/7UwPGTEiqjtbmJtw4MYx78S/4Wa3h5UoOYwPdIOp2Xi/t18rlFgcDw6o+ydiWVRwOBnCpL0oOAMmNEhLZIgSeoxwGSWcERon/M9DoBknTIdNQNAMnO4PIVGpIFXcwndlA2OtGc4MAxml27p4AIulWSIa9QVadiYSoJxhqBJivKgh5ad3k9gaw6JdlDaqq7q5wINY4F22HaLHSDZQkBW72O9cBYFEviBIURQH7a7MN0uDisUW12ZZcaGlmdq4DwCqeTo1zNtZuW7hUqGIw7MNqSUS2ImNsKEpSdEwt5lGhfQdAkQBEoub3NNrDJfAIeBuRrcrY5xGQ2RFJAjl00I8PCckJUCB9q1URBnk38XEJEuk41tmGwZAf66s1VOh2keqwoUnYpFxHH4iKIixkN3HzVQKP3iQR/5GDKMuYmE3h+fx3MHqh1sMafztHLuiCg0FAk0uFdLqcpGY5QEXbTC/j7mIaVjc18DxufUtBJ/vcggs+3ijVz/0SYABsJHPUtu/OYwAAAABJRU5ErkJggg==); - background-repeat:no-repeat; - background-size:contain -} - -.ipfs-py { - background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAlVJREFUeNpsUktvEmEUPTPzTUFmgJK2UqXQFG3pA6OBLrQxamJcaYwuu3Dp0l9iXLvVtRuDpgt3JIYaTVSaxtRHsJq2xEJBHgXmifebMhECXzKZme+ee+65516h2+2Cn2cb2VwyHl12//vP2/zOQaF4uD7GWN69e/LogfNm7kUsPBFaXYwHMeK0OlpQEJApHJTuykzK98dE98O0bLM/UNgr4v32Dj1fwSQRt9dSsfmZcMa0rIv9ODaqYrPVxuPnL1Cu1aEbJu7fvIZUIo4bqeVYRzcyv/8c3SPYpwECt/dmu4ON3Ed4TymI+hQc1ZqoE+F+uQLDsnHlwkKMscJTgl4eJOi9fxZLePNhGx6ZQRRFqH4VjZaGSv0Y6cQcJLpra0ZguIWegqDiw7lYBBZV6xiGk9DQDLzK5bEyF4Hi9VLMsoYI7J6Es5PjeHjnOl5ubqHaaJGBEkzbxplQAKIgDmBHekDTgI+qKKqKLvNApgmEgyquLs1CoFn2Y4cIeLJpkjoCLkWnUSIF3JxISIUsCjAoxhWNJLBIJs3YeXj/08oYZkOKY65HllE/bkMmY504YUd40HUq2JSSyW6iVPmLiXE/ZMYQCU+hXK3h1toqdNN0sEObyKtqtDQ6kXDwcadDS2TBryp4nX2HxXjsJK6bDnZIAZem6Tp5YMMmicn5OC4lztNWtvB9cg+hQABtWjKL2jH/T3GgBcYDXEE6mcDM6SlaJAGMWkivLBC54ZgniZaDHSI4rNSqn7/t1vgkGJPwZXffSeCjk2iUWz9+nSTQN8e6ef8EGAClUi/qoiOc3wAAAABJRU5ErkJggg==); - background-repeat:no-repeat; - background-size:contain -} - -.ipfs-qt { - background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAnVJREFUeNpsU8tu00AUPU5sp41NkzRxpfSZqi0VIIQqEEJUZYXECvbwCWxYsuBD+ABUFrDrCnWBQEJdIWigBSr6pqRJ1ebhxrE9M7aZmSrQ4o505fHMnXPPPWdGiaIIYrx89GKpNDdxmXkU3aEoCsT+z8W1Sm21+jCpJctQTvaerj+TX7WbnJ+0cpfuX8mQtn8GgJ4AZtIFY2Hz3foDVRcgyt+cRHcS0IARh+D/8G0PpmVi7smd0dLs+AIjwTVEiANEYYQwCHlEZyJgIQKfoX84g9uPZ0cHZ4YWmE9nuufU0wABCSSImMsWEgqSuoqA/39/swZFTWLy7vQo7dDnfPvWWQa8GuOV3IYLJXmyzDzG2/ChZ3pwbHdQ267BKJoYuj7SF2MQhiF8LuDK/Gf0DKTBKINz1IbTbEMzU1ANDW7LAfEIQKIgBsBFlAx6LYOz6MAcvoDCtAVGGPKlAiIu/F55F33FDA6W93EOAOMaMOl7biKPwRtD8Foetj5sYPfTDtxjl1f3Ubo5jkQieQ4ACSUD2iE4XDpAdbUiW9D7UsiN9WNkZgxajwbd0LGzt3keAJPUc1N5SVeENT0Ao2BKV6QzwlZeRBSKAYhe3aYHcZWn7l1EfjyPypcK9LQGa8qCvW9j9+MvaasQOHaRhGWdhsNLR8hwodYWf6B4tYjDjSOovRqq32rSYq/lytw4A77o1V2ERiAtzY5kkUrrsH+3QF2KY87ArTtQuQ6nAf4x6FCV1D001+vYersBM2vA4y1Rm2D7/Rac/TZIw4d/6MrcGAPf9htN0miJh7Lyuoyvr8rQeP9iVJcrSKgJ+TrFcyYebXTP/RFgAFQobmIOBxbsAAAAAElFTkSuQmCC); - background-repeat:no-repeat; - background-size:contain -} - -.ipfs-rar { - background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAnpJREFUeNpsUktPE1EU/u68OgylZXi0hZACQU1LEKKCMcat7jTRnQsXxsQtv4E/4M74P1iriUaNCw1FgxpjCJQKKAU60+m8mJnrmSll4XCTc8+959zz3e88GOcc8aq9evChOHl/lvMoubvWX/z4+BwTlbvw7bXdg8b7h6LE1gGW+O88CRMt4XTlR6/rYxce5Xv3jlHH19fPkBu+gWy5mlcFb3Wn/umeKOEMJF5C7xCFbtA9dRXjFoYKGiTRAlPGUV1aKU9O3VwNQ74A8DQAIZxqAuAhBPIMFYpQVAVB4CPSZjEzv1weH5tbDQN+JQ2Abu488mnzIbAAA3o/VK2PwDJo7r5Fy7ZRuvi4PFS6+qIXdVYD8Jg6BUcuOD8BozSLlRWyicgVKkTMQWwUlFF0Ooe5FIPk57BD7G0SiywyjD8bCDyHsOkeeeR3SUxEkROmU6BfQYFJMHfhWXV8efkUrb13VPMTsrcTQSzxZ/+n0GVA6EGbSGdgG9vo15fg2nFgbO8k70SRdd+mahDT81vUxTZRlJBRMsjq89C0EXCvSf7TIBZ136YZUJEiE7LgJ2dN01BZuE0dkIhxE7KcQTK1QUj+cwAEyrPZ+IydzRoyah+mLy2isbWBweESJEnB9q+1RM9Ub9GQOWkABg8HjRr2d9Yh0hTlBlRsfn+D4vg0BvUC9rZqECUJuk7Tzr1zahCYlB6HJAREPwfbbMBzLBzsbUKVI0qBgQkc+SxgWUYaIAqOpKwKXJ6bgGlaaDV/YvHaFNrtDsKTfVSrJeqIg/bRNwjclFIALeP3saybhu8SC4VBHwnhBXXIKocYRXD9QzBi4Xgchmkd9+L+CTAAMqwy+ZzluBgAAAAASUVORK5CYII=); - background-repeat:no-repeat; - background-size:contain -} - -.ipfs-rb { - background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAixJREFUeNqEUktvElEU/mag5f2yJhXLwxIt0kiqsVEXujP+A925cu1Pce3WtXVtYuJCF7KtTY0NrVQIpRVKeXTkMcO9F8+9ZVooJJ5kcmbmfOe733fO1YbDIWS8+/g1dycVX7W/xyO3vdsuVKqvnE7HZ230783rlyo7bVBicSGyfjsVwozomVbIPe/c+FmsPHfoRKJd1HT7hXHBZjVbA4aA14NnD9bC2VR8gwuxPi5Sx39Cp+M0XUP0ahhP1jLhW7HFD4zze3b93ILtXYyyVKlR8/5hFbnvO9gtlrGSjOF+OpXkYviWyo8mCS4R6bqO4p86vm3v4fC4DrPfw4unj1XN6JvBaQtjChzUXK43sVU4wNFJA43Tv/B73edQwTmfIhAjCVL6UdPAj1IVFSKhCdAcAI9rnjBiAjtBYEu3GEeh1sKJ0YXR68sVIujzIhzwY8DEBHZqiLRKkicQDfvABxaiQTc4Y/C65pCOXwcjcmlvJgHtlwi4epYifiQWgmoLZwPW6HQG07LgcOgKO0UglAKOTt/E+09fwAiUWU7QAE9xUK3jbvomsispZVHMVEDSZdHo9rCZ/4VIMKAu0XGjpU7d2S8hk0pCELHEzrjKnCQOYJoD+Dxu1RyiwUm5LaMDo9NFt2cqDLvY4oQFp/QpfT/MrmI5FkWebt+NpWto0j2QmQkOjZ9hpwhqjXZzM/+7LU+cc7lRrjXh8/lVLRK5ovLWXglOsiOxdt8/AQYAzv8qbmu6vgEAAAAASUVORK5CYII=); - background-repeat:no-repeat; - background-size:contain -} - -.ipfs-rtf { - background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAe5JREFUeNqEU01PE0EYfnZmd5FSvgLYFuwWt9EgHyEaox68eDJevHvwJ/hTPHv1N/QgZ2NC4g3kUAQKFKGhjVKqRrvbnRlnht262FHfy+y8877PPM8z71pCCKh4/ebt+rJfXEz26Vjf2mnsN5rPKKWbVpx7+eK5Xu2kyMtNTd5d8MdhiJ9BOO7atFI9ajy1UyAqSPIRMR6ZmoNehNHMMB7fX/UWvEKFMbYKE8DfQnAhwRmmJkbx6M6S5+WmK2Evup2c9yUk2nnKA0XVcSiGXAe1k5beP1i+4RFCXqnPywB/AKVzK34RjHNYlgVKCH50w7EBBogbTa/AVM5SgBdn0gc2AMDjPsbFPz2xye9asweS6n+NTbG8BCCfUtLjff2WoVnVpAH6z6hMUtJE3EykYfpF4vUiL3QNS7FMeSAQRBHW3r1Hq91B+VoBQRji4+ExFsvz6Hz7jm7Yw5OH92AcJKW9G4SoHhzhy/lXbB98Qmm2oCXN5WawsV2TACEoJXqwTKOsb3BtR2ucmZxANpPB8JUhyPnHWDaDpfJ1eZFALzJJ4MKO5MEtv4TSXB7V/br8iQLMz+almRZWbvoo5q9qRlxwewCgeXbe3qrVO5ZkUD/9jJGRLPaOm6COi92TU1DbxYe9umRD0DrrtJO+XwIMABWp9nS+FgaoAAAAAElFTkSuQmCC); - background-repeat:no-repeat; - background-size:contain -} - -.ipfs-sass { - background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MDNDMTBBM0JGMTE5MTFFMTg3N0NFOTIyMTQ2QzhBNkQiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MDNDMTBBM0NGMTE5MTFFMTg3N0NFOTIyMTQ2QzhBNkQiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDowM0MxMEEzOUYxMTkxMUUxODc3Q0U5MjIxNDZDOEE2RCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDowM0MxMEEzQUYxMTkxMUUxODc3Q0U5MjIxNDZDOEE2RCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Po72XUcAAAJcSURBVHjahFJdTxNBFD1bykc/ttvdtttWGgI0bYrUgDZoNYqRJ014kMRXHvwB/hQTH/wFhMREJfFBQxBjhMRIFEQSCAlQxKYGggiU3e3HbnfX2bFt1EU9k9m9mblz5p4zlzFNExYmpue/jmTSZw5PZAl1MAwDT0c7O72wvPdudeNakPNtOZ0tsM7cvzdOc5yN5LDAsTFRAJks/kC2PxFRVe39Si6f4byez62EpAEH/gNN18F53Ri/Ocxf7OtdLMpKT42s/ZPg1cISJp/P0tg0TBzLCoK8D7eHh4RkLLJ4cCz12AjMXwgez8yhqtVo3NbqRKlcxcSL16gZwJ2Ry8KVc8kZO0HdTKlURn+8G6PD2SZhLMQj96WAiMAh2RXFYKI78lcJcx9WYBCycICnpNbojUWpD5Y0C4Zh2D0w6hWc70uQZC+IWfQZrXF0IsHvY+meBd08haAhoVMMQFJKWF7PNZM+klhRyogGhbqxOIXAMOtEwGAqDqVcgbVkkE+5UsEAWavf0az2t0ZqvK2qabh6IU3joizDwTgwej1LdVfJXkdbK8mt2QkayO99A0/0trQ46I1lVcX+UREhnsP34yLp1AD1xibBMuntpzU8mJyi3Tc1O4+l9U06n7x8Q/8PHz1DrrALt8tlr0CrkbJMHTop9Sk5sLa1g8L+ARJdnShKClY3tunN69t5iGLYTlCtakjFY7gxNABdN3B37BaqqoYT8pyX0in4ORbRkIA46YlDRbUTbBZ2Jb/Pw4qiKFnapcpPo9pdbrg8DjAOBsFgELJmsGs7eWkkc5bu/xBgAHkWC6UPADTOAAAAAElFTkSuQmCC); - background-repeat:no-repeat; - background-size:contain -} - -.ipfs-scss { - background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6RkM4QjYyNDVGMTE4MTFFMTlBREZCNDNEM0ExMTk0MUIiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6RkM4QjYyNDZGMTE4MTFFMTlBREZCNDNEM0ExMTk0MUIiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpGQzhCNjI0M0YxMTgxMUUxOUFERkI0M0QzQTExOTQxQiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpGQzhCNjI0NEYxMTgxMUUxOUFERkI0M0QzQTExOTQxQiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pkf1yeMAAAJbSURBVHjahFNdTxNBFD0tLULpB91uodVWPmorUIxo0VSiNSExMYYHE33l0Ud/in+C+OSjYgjRGDBRCKJIUkIEWi0WKlja0ul22+5219lJ26gLeiezuXvn7rnnnrlrUFUVms3Mvd2bjIyezRVLBA0zGAzo6jhjm1te+7EU37rFO+w7JlMbtG+ePJ5mOaZmci/nsPl6ONBtw18WDQc9tZq0sp7YjTisXV/NFKRpRvzHpHodDqsF03djzuvDg6vHJWFAprF/Arxe/oins6+YryoqCiUBvNOO+7FrXMjnWc0WyIAOQP0N4Nn8IqqSzPx2swllsYqZl28gK8DDyRvcxKXQvB6gISYpiwgH+jEVi7YAfW4nEqk0PJwDofNejAX7Pae2sPhhHQoF63U5Gai2Bn1epoPWmmaKoug1UBoMrgwHabIVVCx2jdrKFwm67TZ2plldPQGg2cK5HheIUMbaZqKV9In6giDCy3MNYXECgKI2gICxoQAEsQItpNCHWKngMo01arTY/jFIzbutShJuXh1Fm9FImYiM7tTtKOtbO+toN9Nc+fQ5SGUOIVYl7HzPIH2YRZ0y2KZ+sVzBHn2v1mpMGx0DTaR3nzfwfGEJdybGkdo/wEigDyvxLzg4yiESvojZhfd49OAeLJ2degaSLIPOO6vwgiYaaRErTRREEdn8MeJbSVZ5M7nLdNExqFLaQwEfFfACQn1+HBWKSKb3MT4Sgstuh9vVDa+bQ4DORE6o6RlspzMk9TOPfr+fiLJCLFYr3TZSKNcI7+aJwWQmPM+TkqRg49tu65f/JcAAMwMas6WUKd8AAAAASUVORK5CYII=); - background-repeat:no-repeat; - background-size:contain -} - -.ipfs-sql { - background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAh5JREFUeNp8kctrE1EUxr+ZyXMkoa1NBROaSkpTBE23PhZ25cql2y5duvAPUdGFS1FxIRRBXZlFQ9GVdDENIhGJxkDsw2mneZnM83ruNZlOmNoDhzlzz3d/9zv3Sowx8Ch/qlYK2XM3cEJsbH0+qjV/rd6/u6aN18b7RMFT+9aosP/Ex+0ae/puw7j36PlKEMAzctKJ3aGFamMHjV0d+wcGitkMrpWWp6hVIciEk2MAOwbUWjosx0UiFoWqJpGMx5DNzODq5aIPoa82AWBg/lyKLMH1PMp/a9XvLXLzG1cuFlBaWpiKxaIPSLY6CaC93ggQjyiQZRkeQSzLRovGaPciWLt5faSWEBoh6KBvOhiaNga0+Y9pwaFxvu7rfp8F5pWDt+qNMp2IijHGwddWCvN+33/CoAOP5nVdT9SdoQ1JkggiQ6Yvr7V60+9z7akA2gfH9cRF8hO5F5Ve4lQAF9uuK+qFsylkzsQxrcaQm04hdWkR83Mzfp9rQ3fAFzu9Ph6+WMfjl6/pGBdb2jbKmx8QlRjWy5vkyhUZBPgOeGNHN9AbDLGUz6He2hVj3Ll9C8/evsdgaMK0HV8bcmDTU0UUBYXcedR+NLGnH0I3jvDk1Rsy46FP4C/1BtrdntCGHNiOAzWZgEKQ5Qt5lIqLojbaXSQTcRy2OwT4SZqk0IYAOgkVWUE+lxX/zb0DpFNpkTzmZmfFtzewhHYcfwUYAMZmVaZQlLFHAAAAAElFTkSuQmCC); - background-repeat:no-repeat; - background-size:contain -} - -.ipfs-tga { - background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAnxJREFUeNp0U89PE0EU/ra725K22ILRGipb22pMG6JcSEQTbUIwnozxpBcvepeEP0KPogcT/wlNT17kIKbEmChFUYKGVtL0R2gLtNCl3Z1Z3+zSAlonmezOe/O+973vvZEsy4JYnqdPMu6RkSQYQ29JEkB+PZcrslrtPhQl23VZc8/tr9I1yMHg0EA8HrBM04lVFAhoY38fSSDQVN3pfKV8G7KcxZHl6v1xblqU3eLc3p2VFZjr6+gQgwsnhzGTuq6Nhs6kYZqXjwL0GFhEl3U60OfnwWs1GGtrUKNRsKkpeIIBpKIRtI1J7cX7hXRhc/MOhXw5DkCZGG2zXAajzFIoBMvng1ypIKOqmP30GW3OIEcimovzlxRy5RgAFwDEAIODkCcmIMdiQLsNdWwMZdJlg8pzEUt1aBhKq3XinxKYqF9yQbqRIqsMy+0Gyy47bKgUWXSLtDENE5wdtuqQATm50F1VnPbRGeEw8HXZbiV8fsDvI9ldju9vADAyihLEbrWAZhOoVp3z6iqBUiB1A4nEfwCEsbkL/M4TgE5n5jDx+oTEzp1d8m9tC8H6MaAB0imzx0NU/WKUYE+loEyawDBo2ui6TGfT6ANAxrvx87gYCGCxXEKVJvCWFsG3eh1vN/J4OD6Od4UC8o0G3TX7TGLHwI9iEQmvF9X6Fh7F4/iYy+GcLOMSlfEgGsP0qdNOmX0BiGKpVkV1bw/1nW2b/gCpf1PTcI+Y7eg6ps+G4bG4PR99SjAVo9HE4q+fKNE0vl5awuSohjeijbRefVjAtUgEQRK7Yhi9OKn7nKWZxxlSPWl3QwgnaIrW8QMhD542vUbx/W49m7sq4v4IMABOqi3Ej7bAEAAAAABJRU5ErkJggg==); - background-repeat:no-repeat; - background-size:contain -} - -.ipfs-tgz { - background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAnhJREFUeNpsU1trE0EYPbMzSTfdtInFtkkpiaXVWou2FRUEn/so6JugL/oH/Af+B1988if40jcFERQURNBSQdDWlLQN2lsue8neZsZvc7FoOrDszM75znfOmVmmtUYyvry++36yfOeS1qqzDtvH2P76ApPlW3Drb2sHex/uccHWAdbZX30kO2+B3siN3zhTnHuQ66+95i423jzFzOVljBdKOZNHazvVT7e5wF+SZBj9iZJ+3J11mbW2kR8T4LwFli5i4fqTUvnczTUp9RLtDhKgJx0q4dEwWAxrREKICHEsoYYXMXvlcWmquLgmY71yCkG/c0AkARgLMZpnMDMpGNzEYe0dGp6HwvmHpbHC1Wf9MnFCkHQOyYEPzSJwQ2B65Tm5NZG3Fshim6wbMNJn4bpHowMKtIqo2COgR2IcAptwjvcgo6i77igjEmVDqbY8xQJ1VwRULhiBI6+G9Zf3cbTziuzIDkmHSNqECTFgQScEcYuc2NA8TcdYwXD+GkK/TYVN+u72WrIudiAD8o6oAR2RRCmQMjis3CIy1iSpPySCXhFTXeyAgh4BR+JVw8pauLi0Cp4yCX9A90FQhnSBYtnF/k+Q+HYam9itfIZB3QvT8zj8XSW5EhNTs9ivbSLwPUzPLNPJBIMEKnaQYg6aB9+RGR5F5VsNgnNKXMI1NdJGG5WfHzFVLJ7k8c8xUngpVodlDSGbFYj8Y4yMpOG09lHf3yIFPzA3fwHZTAQVtU4JUTeFDrdgDdlI8wAz5Qy2KxswReI7QODZcOr0ZH3q2hIDBI7zq16tuk3FNPxAI4wN+pkoccYoE4YJU5EdUtM4Qst26v26PwIMAKj3P/2YUKgYAAAAAElFTkSuQmCC); - background-repeat:no-repeat; - background-size:contain -} - -.ipfs-tiff { - background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAmRJREFUeNp0UktPE1EU/qYzHWstlrYJNcWUElyUJsaNGh9B0g1Lo0v9Ey78EbrVxBhXuHShm25YGBJRQpAYBDEWpaEPEhksdVpbyjzveO4MfZDCTWbauefc736PIziOA77OPH2yJCcSGdg2uksQAKofFou/7VrtASRpvVNynj13f6XOhjg8HAlMTIQdy/LO+v3uYUPTkAHCTb+cK+0pdyGK6+hbvu4/xiyHbncYAwfR19ZgbG/DoO9LsSgeTd9JXoxfyMG2rvQDdBlwIZauQ5ufh12twioU4E+nYU1NIRCNIDs+Bt28mXzx8VNuZ796j9q/DgAwomwqClilAmF0FE4wCInAlkjO4y+r0JgNX2os6XPYS2q/cQyAcQatFjA0BPH6NYipccAwIGUy2CVJFZInkKlyJAqx3T4/IMGmJkeWIWSz5KgI5pdhb3yDXS5DSCYh8rTID8s0wexeVD0GtMd85KkkefFxUfE47M1NokbJkByEQl6tL+ouAI+MUwbFhnYbaJKc/Sqg0x4H4eDRGDA56fUOABA9/GsCpaIHwr8FOhQ823O5RfW66tUGADhNy3RNRDjcN41HLxdQ8J6jYTsOQLfOJBK4f+s2/uoathoNGKT1MtFeVHZxdWTEZfEq/wMKl3rCJOIzTV6ADs2R5ulYDDNkYjp0DhrF+zCVgkw31+v1UxjQZkNV0SADd2o1MIuc9gmY+/kLxb0/UFoHePd9A1qzeUoKpilx9xcLWzgg+u/zeVfuQqkM9bCN1ysrWKXxdtPgvScwUAm58XZ52W16QyPtifRUzi588GbEi1ztHPsvwAC4uC9qhnsZvwAAAABJRU5ErkJggg==); - background-repeat:no-repeat; - background-size:contain -} - -.ipfs-txt { - background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAeJJREFUeNp8UrtOG1EQPfsyXiyzBguIJSyChZBBEFCKpKHLo6egpErNn8CHgH8gkZIiTSIXLhJAWCgkoMgRMSiRBSK29z4y9+I1d/HCrFb3MTPnnjkzlpQSynY+fP70fGF2gQuByCz6lfdd9Uurfvrrjes6762eb3tzQ69uFJwPsqOPC+MBEmxxphi4tlU5OGmsOzaBWLc+O9oIIVhScidkyGZ8vH62nHtSKlaI4cse6TjAfSaFBBcco0EWqyvzubmpyQrj/FXk75cQaSEMeMXU8xykPA/Hjd/6/LRcyjEpt2i7HAe4A2TeLZWKUOJaVLxj27j813EHGKCXaAJExu/4BOdiAED08riQD2riOrexyRoYc3CvsAbLGAAjZga7vgZG23WMCdBvoxKJc36TRBlMiaa2JByjNqqD8qkYc1pjDK7abey+/YhrWlfKswhpiCR96aEU9o5+QE3g2ovVWDm2Sc22bBQm8vrVpbkS9r+doPr1EOWZaQ0yFoxg2PcREosEAI4uvZhJpzFMP+cSXRbq+043RManez+tNWKMI6GN0g0Z04HFR+NoNC/0yx717efZOSbzY3AcR4Op2AGA5p/W31r9e0vNgSrh9OwCrpeCkqvZuqTybnpRqx/r2CjvvwADAJC/7lzAzQmwAAAAAElFTkSuQmCC); - background-repeat:no-repeat; - background-size:contain -} - -.ipfs-wav { - background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAApFJREFUeNpsU1tPE0EYPXtpKbX0wqUQKVQMFdIXQBNCQBs06KP+B8ODGh+Mf4b/4IsGE54kxhcMBrkp7YOQgBRvSKG73fvsrt8Otoask0xmd+b7zpxzvm8E3/cRjPkniyulW0NFy2JoDkEAguOlpXJ9p3L8MBqVl4O9YHxae8pXuRlcGO7KPLhfTDVUqwUgigJMy4Whm6lEXHjxYf3XnByRN0QB/2KaH7btMlUxoRJAcyqKhdOaht7+DJ49n+2cvTnwynXcsb+kLwJ4rgfmMDDGWqvneXCZS9ND7mov5h9ND85M9y86Dpto5rUkuJ4Py3YDJpy6QGJPayqB+Njf+43XL220t0cwOZkfrNXsBUqZugDA6CbLdAiAwaek1ZU9LmP8Rh6S78GsGxjOp9FdzKJaVZIhBgGASzK21w/wbrnCk8euX+EMAjaaZuPHdwUdHVFYluuGPGCORwwYjg5rqOwccRk+3Ux0IEvntmsNG4ZmUayL/wAwKHUNfZfTKN0ZRaw9Cof8qJ/pMAyHy5KkAMTksSEJtnMenM7EMVMawbejMzJRh67bXEYiIXEAVTW50SEAhzqwfqrBcXx4VOhYm4RsNgHbsJFOyZTsQ1MN+hcohoUlkFiMT+TQFpMwXOjGpXgE+XwGk1N5pFJtKNCequgYGupCRBbCDOp0KBJc4VoP3dyBONW8uydBgBHUThqQKCk3mEZ/LoUG+RBioJO7VarAwEAntjYPiUUW9Hh4b2R7k9j98hN37xWx8fGAt3eIAdVMLn+uUv+b2KReSCZjZJiB9bV9jIz2ofr1BKvvd7G9dRC80lae0HzOt+cWVnrSKDrMJykifwNBpCgE/UAllEXufmDu8Zlffvvm8XSQ90eAAQA0pF7c08o4PAAAAABJRU5ErkJggg==); - background-repeat:no-repeat; - background-size:contain -} - -.ipfs-wmv { - background-image:url("data:image/svg+xml;charset=utf8,%3Csvg id='Layer_2' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 72 100'%3E%3Cstyle/%3E%3ClinearGradient id='SVGID_1_' gradientUnits='userSpaceOnUse' x1='36.2' y1='101' x2='36.2' y2='3.005' gradientTransform='matrix(1 0 0 -1 0 102)'%3E%3Cstop offset='0' stop-color='%23e2cde4'/%3E%3Cstop offset='.17' stop-color='%23e0cae2'/%3E%3Cstop offset='.313' stop-color='%23dbc0dd'/%3E%3Cstop offset='.447' stop-color='%23d2b1d4'/%3E%3Cstop offset='.575' stop-color='%23c79dc7'/%3E%3Cstop offset='.698' stop-color='%23ba84b9'/%3E%3Cstop offset='.819' stop-color='%23ab68a9'/%3E%3Cstop offset='.934' stop-color='%239c4598'/%3E%3Cstop offset='1' stop-color='%23932a8e'/%3E%3C/linearGradient%3E%3Cpath d='M45.2 1l27 26.7V99H.2V1h45z' fill='url(%23SVGID_1_)'/%3E%3Cpath d='M45.2 1l27 26.7V99H.2V1h45z' fill-opacity='0' stroke='%23882383' stroke-width='2'/%3E%3Cpath d='M9.1 91.1L4.7 72.5h3.9l2.8 12.8 3.4-12.8h4.5l3.3 13 2.9-13h3.8l-4.6 18.6h-4L17 77.2l-3.7 13.9H9.1zm22.1 0V72.5h5.7l3.4 12.7 3.4-12.7h5.7v18.6h-3.5V76.4l-3.7 14.7h-3.7l-3.7-14.7v14.7h-3.6zm26.7 0l-6.7-18.6h4.1l4.8 13.8 4.6-13.8h4L62 91.1h-4.1z' fill='%23fff'/%3E%3ClinearGradient id='SVGID_2_' gradientUnits='userSpaceOnUse' x1='18.2' y1='50.023' x2='18.2' y2='50.023' gradientTransform='matrix(1 0 0 -1 0 102)'%3E%3Cstop offset='.005' stop-color='%23963491'/%3E%3Cstop offset='1' stop-color='%2370136b'/%3E%3C/linearGradient%3E%3ClinearGradient id='SVGID_3_' gradientUnits='userSpaceOnUse' x1='11.511' y1='51.716' x2='65.211' y2='51.716' gradientTransform='matrix(1 0 0 -1 0 102)'%3E%3Cstop offset='.005' stop-color='%23963491'/%3E%3Cstop offset='1' stop-color='%2370136b'/%3E%3C/linearGradient%3E%3Cpath d='M64.3 55.5c-1.7-.2-3.4-.3-5.1-.3-7.3-.1-13.3 1.6-18.8 3.7S29.6 63.6 23.3 64c-3.4.2-7.3-.6-8.5-2.4-.8-1.3-.8-3.5-1-5.7-.6-5.7-1.6-11.7-2.4-17.3.8-.9 2.1-1.3 3.4-1.7.4 1.1.2 2.7.6 3.8 7.1.7 13.6-.4 20-1.5 6.3-1.1 12.4-2.2 19.4-2.6 3.4-.2 6.9-.2 10.3 0m-9.9 15.3c.5-.2 1.1-.3 1.9-.2.2-3.7.3-7.3.3-11.2-6.2.2-11.9.9-17 2.2.2 4 .4 7.8.3 12 4-1.1 7.7-2.5 12.6-2.7m2-12.1h1.1c.4-.4.2-1.2.2-1.9-1.5-.6-1.8 1-1.3 1.9zm3.9-.2h1.5V38h-1.3c0 .7-.4.9-.2 1.7zm4 0c.5-.1.8 0 1.1.2.4-.3.2-1.2.2-1.9h-1.3v1.7zm-11.5.3h.9c.4-.3.2-1.2.2-1.9-1.4-.4-1.6 1.2-1.1 1.9zm-4 .4c.7.2.8-.3 1.5-.2v-1.7c-1.5-.4-1.7.6-1.5 1.9zm-3.6-1.1c0 .6-.1 1.4.2 1.7.5.1.5-.4 1.1-.2-.2-.6.5-2-.4-1.9-.1.4-.8.1-.9.4zm-31.5.8c.4-.1 1.1.6 1.3 0-.5 0-.1-.8-.2-1.1-.7.2-1.3.3-1.1 1.1zm28.3-.4c-.3.3.2 1.1 0 1.9.6.2.6-.3 1.1-.2-.2-.6.5-2-.4-1.9-.1.3-.4.2-.7.2zm-3.5 2.8c.5-.1.9-.2 1.3-.4.2-.8-.4-.9-.2-1.7h-.9c-.3.3-.1 1.3-.2 2.1zm26.9-1.8c-2.1-.1-3.3-.2-5.5-.2-.5 3.4 0 7.8-.5 11.2 2.4 0 3.6.1 5.8.3M33.4 41.6c.5.2.1 1.2.2 1.7.5-.1 1.1-.2 1.5-.4.6-1.9-.9-2.4-1.7-1.3zm-4.7.6v1.9c.9.2 1.2-.2 1.9-.2-.1-.7.2-1.7-.2-2.1-.5.2-1.3.1-1.7.4zm-5.3.6c.3.5 0 1.6.4 2.1.7.1.8-.4 1.5-.2-.1-.7-.3-1.2-.2-2.1-.8-.2-.9.3-1.7.2zm-7.5 2H17c.2-.9-.4-1.2-.2-2.1-.4.1-1.2-.3-1.3.2.6.2-.1 1.7.4 1.9zm3.4 1c.1 4.1.9 9.3 1.4 13.7 8 .1 13.1-2.7 19.2-4.5-.5-3.9.1-8.7-.7-12.2-6.2 1.6-12.1 3.2-19.9 3zm.5-.8h1.1c.4-.5-.2-1.2 0-2.1h-1.5c.1.7.1 1.6.4 2.1zm-5.4 7.8c.2 0 .3.2.4.4-.4-.7-.7.5-.2.6.1-.2 0-.4.2-.4.3.5-.8.7-.2.8.7-.5 1.3-1.2 2.4-1.5-.1 1.5.4 2.4.4 3.8-.7.5-1.7.7-1.9 1.7 1.2.7 2.5 1.2 4.2 1.3-.7-4.9-1.1-8.8-1.6-13.7-2.2.3-4-.8-5.1-.9.9.8.6 2.5.8 3.6 0-.2 0-.4.2-.4-.1.7.1 1.7-.2 2.1.7.3.5-.2.4.9m44.6 3.2h1.1c.3-.3.2-1.1.2-1.7h-1.3v1.7zm-4-1.4v1.3c.4.4.7-.2 1.5 0v-1.5c-.6 0-1.2 0-1.5.2zm7.6 1.4h1.3v-1.5h-1.3c.1.5 0 1 0 1.5zm-11-1v1.3h1.1c.3-.3.4-1.7-.2-1.7-.1.4-.8.1-.9.4zm-3.6.4c.1.6-.3 1.7.4 1.7 0-.3.5-.2.9-.2-.2-.5.4-1.8-.4-1.7-.1.3-.6.2-.9.2zm-3.4 1v1.5c.7.2.6-.4 1.3-.2-.2-.5.4-1.8-.4-1.7-.1.3-.8.2-.9.4zM15 57c.7-.5 1.3-1.7.2-2.3-.7.4-.8 1.6-.2 2.3zm26.1-1.3c-.1.7.4.8.2 1.5.9 0 1.2-.6 1.1-1.7-.4-.5-.8.1-1.3.2zm-3 2.7c1 0 1.2-.8 1.1-1.9h-.9c-.3.4-.1 1.3-.2 1.9zm-3.6-.4v1.7c.6-.1 1.3-.2 1.5-.8-.6 0 .3-1.6-.6-1.3 0 .4-.7.1-.9.4zM16 60.8c-.4-.7-.2-2-1.3-1.9.2.7.2 2.7 1.3 1.9zm13.8-.9c.5 0 .1.9.2 1.3.8.1 1.2-.2 1.7-.4v-1.7c-.9-.1-1.6.1-1.9.8zm-4.7.6c0 .8-.1 1.7.4 1.9 0-.5.8-.1 1.1-.2.3-.3-.2-1.1 0-1.9-.7-.2-1 .1-1.5.2zM19 62.3v-1.7c-.5 0-.6-.4-1.3-.2-.1 1.1 0 2.1 1.3 1.9zm2.5.2h1.3c.2-.9-.3-1.1-.2-1.9h-1.3c-.1.9.2 1.2.2 1.9z' fill='url(%23SVGID_3_)'/%3E%3ClinearGradient id='SVGID_4_' gradientUnits='userSpaceOnUse' x1='45.269' y1='74.206' x2='58.769' y2='87.706' gradientTransform='matrix(1 0 0 -1 0 102)'%3E%3Cstop offset='0' stop-color='%23f9eff6'/%3E%3Cstop offset='.378' stop-color='%23f8edf5'/%3E%3Cstop offset='.515' stop-color='%23f3e6f1'/%3E%3Cstop offset='.612' stop-color='%23ecdbeb'/%3E%3Cstop offset='.69' stop-color='%23e3cce2'/%3E%3Cstop offset='.757' stop-color='%23d7b8d7'/%3E%3Cstop offset='.817' stop-color='%23caa1c9'/%3E%3Cstop offset='.871' stop-color='%23bc88bb'/%3E%3Cstop offset='.921' stop-color='%23ae6cab'/%3E%3Cstop offset='.965' stop-color='%239f4d9b'/%3E%3Cstop offset='1' stop-color='%23932a8e'/%3E%3C/linearGradient%3E%3Cpath d='M45.2 1l27 26.7h-27V1z' fill='url(%23SVGID_4_)'/%3E%3Cpath d='M45.2 1l27 26.7h-27V1z' fill-opacity='0' stroke='%23882383' stroke-width='2' stroke-linejoin='bevel'/%3E%3C/svg%3E"); - background-repeat:no-repeat; - background-size:contain -} - -.ipfs-xls { - background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAmxJREFUeNpsU0trFEEQ/mamZ3Y2+0zIC2MmITEkUYgERFQErx5E8KTi1b/h79A/4SW3nCNeYggBYZVEMU/y3N3Z7M7OTD/G6lk2ruw20zRdU/XV91VVG0mSQK/3n1a/jky6d6Xs3G8WXS+Pw5N6LXjLLGuna/78oZKerGsYKtrDE16uJGL1L9gEOOcYd2dL1fNwrbL//aXN7J1efPMmkUqEFAk0A0VZNbFEaQCBscIkXj975y3NLq9xye8PBkAniHOFph+j2eC4rsdoB4LsFubGl/Hq8RtvYWpxTQi52o1jvWiGYaRZL0/auDgOkC/Z8BYL2Pqxidp1FZkhoDxpeaXA/Ujuj/4HoOxKKjiOiek7RUShRNQWaNYFQuMafrYCxiw4ozZKfqbYJ0EvRdl1DQyyTs8XCNTA6UELMwvDyLpZWIZNNlNLlQOK2LMJRJ+5AkuZ1S7CFFzJzk56GnUjQWlYkqCoBWFbonEVYcLLA4dNnB624GQsDBWIgfZJEgxkoChzSFWvn4VpQemDm2VwXQsXJwF1h6c+gxlQ5jgSiEUEt0wdIe7tMES+nEG2aCLiJMOIIWIr9e0DEELAMUrwRuchVAyTKimUwO75Jm6VF3Bv7imOaj+xd7UFKVS/BPJF1b/E4tgTrE49J60O5kceoNqowiuuYKa8ghHXA48U9MT2AQgyRvTThE30bQiaSGa4yLMJNFo+Dq/2cHt4CYlwyFf2S6BHwwrMw/avDbR5C1k7h1YQ4KH3Amf+AcZyEbZPv9CItzQD1l9EbtYOjv74v/d3O9RMPTDrsEwGIWN8q2yk7XNYRs9JrRv3V4ABADSGR6eQ0/NQAAAAAElFTkSuQmCC); - background-repeat:no-repeat; - background-size:contain -} - -.ipfs-xlsx { - background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAmlJREFUeNpsU8tqFEEUPVXdPY/ueWZIoiYZiSYKYhJc6EbduHOhgijo3t/wH1z6B0JAhOyMILhxo4kJGk1ASTAxwWF0Mpp5dHc9vFUzYwidaoqmq+8959xzbzGtNcx69PTS26ETmQtS9r4Hy/xv7MW7jV+th5yzVcaYPX/++It9u4NAv+CVR6tBUUTqMJsDcRzjZOZM8W9ZLKx+/XDb4e5/kH5In0lpIYWGUaC0YTZnBCAEKoVR3L36oDo7NbsglZwbqD6iQKOXFMcKUVfBkBAoQhlD5xxMDp/HrSv3q1JgYW3z0x0KXzkCYJaRZljru23aHWTzLiamAyytv0O9UYdf5PArqlppBfMUfu4oALErqZBKcUxMFRCHEp0DgW5Lo4N9NIN1dF0XXsVFOUyPJTzo+WBANDidjp8tgHGG3c0DnJ4uIRf4cOCBaW5KjY8xkZL72xpJ9QcFz5bVqHUJGHZL2YtNmKi06YCyiVFb4s/vEKMTAf1p4edOG6mMi1zR6wEpdUwX+vLDtkCzHoK7ptcM6ayLmGajvtex4PliyoIkFRjmUEASelB2rXQRSfjUCT9PlWpmW21iTGzCAyEkUixPRqXhe2V4zKczbdmybgkpJ0cGOuA6Y2MTCsKoi5HsNK7N3MN+uwYaWbxYfoLLkzdxcew6lrYWaZhm8PHHG3zffp1UwJSHz9vvkU8PodbcQYYYS5lxYkxTkGdVDQdV1Js1qPgYD6JIuIE7gsXVefIhIuM05k7dwMbeMmh87a18ufIMaVYyprrJLgje2Nr+1tzYXANnDnr3zRhHj37Vvy2wpXHtNAd5/wQYAD6WMuT2CwoVAAAAAElFTkSuQmCC); - background-repeat:no-repeat; - background-size:contain -} - -.ipfs-xml { - background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAilJREFUeNqMks1PE0EYxh+g3W2t1G0sEqyISynUFJsSOShNwCamiYZED3LgIkcuxoN/iCZePZiYGD2aGD+i0F5KMChxlVaakAK2ykcAt+WzdLu7zkxo3WZL4pu8mXfmeeY3885ug67roPFh5nvc62m9hjoR+5LMp7MrkYf370qVtco+VtCUFpbj+jGR+JbWn76OyQ8ePwsZATQb8R/hanZgINgj9IqeuBFCw1Kt9OMBnNWCs24XwkG/QKYUEiGjVAPQof/rq0783pShET3ULQo8xz0iS5FaANmrHQH2DoqY+DSLSz6RzecWlnD9ymU47LYjd4O5BXqDTG4FM3NpTEkpdJ5rw0AowLRMbhUfp58gTOaD/UHmNQPI6YmvKWRX1zESHUJ/oBs2nmPa+Mgw0ZIM3tZyGoJwygzQNB2jNyJIZX7iB0lpPoM70UGmPX8zCU+rG8NDVxHwdiC5mKsPUFUN/gvtLLf39sFzVqaN3YrC6TjBauqhXhNA1TQoqloV7Da+pjZq1FsXUCamF29j6LvYhf3iISamZ3Fv9DZevouhRzzPfOG+3hpA9U9UyioOlTJ7pFeTCQS6RGzIebyf+oz5pSzWtmSW1EO9phvQ00slBRt/8qR3DoWdXbiczUiTzd52D+tdLmyTB14mx1rMAKVcRpEATjrsuElee/HXGmnFRyBOGD30C/nEDjNgs7CDpsYmnHG3YPegBCvHs9oYfm8nG9dJa5X4K8AAQzQX4KSN3wcAAAAASUVORK5CYII=); - background-repeat:no-repeat; - background-size:contain -} - -.ipfs-yml { - background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAdxJREFUeNqMUl1rE0EUPbM7m5Y0Zptu21AwWwhYpfSDFh+kvvRd8N0Hf4I/xWdf/Q158F0QoQ+CVsFKaLSQpt/dpmvztTOzzky6cetOpWcZZvbO3MO5514SxzEU3r57/3GpWllM/tP4sL3TarROXuSo/SWJvX71Uu80Cfhlr/T4UdWFAVfdnmsTUtvdP35OUyQKVnJgXDBTcj9icAsTeLax7j/052qM81UjwW1QJXEhMF0qYnN90fdnvdogYmvJPU0/VBApD4hcDrWRcyikfB17srzgW7b9Rh1vEvxDlI4tVytaBSEEtmWh0xsUMwpwnWjqAlcxogiHd1wiQyCu87iI/+sJtf6+NXsgpd7FWCMB50KvkYMGMbLdZgLlfj+K9K4+FnFQ2x7WntIs50AbmiGwLILt+k+EvzvSNIHzdigdJ/AmXQRhiHv5POSwYmG+cqPVo0HqDxj8uTK2vn1Hfa+JmdIkvtZ/4fOPXU3WPDpFeNWVyUKryCiIGMN4zsH98gym3CIcOTwT+XHdXrdQQHAZotE8kBPpSqPNHtBOr48HUmLOcXRJT9dWNMGYJFby91pHOAvaykSaITg+bwefdhrteDRTMSwyrFCgI88E056Hy+4Ah2cXQZL3R4ABALUe7fqXWFN6AAAAAElFTkSuQmCC); - background-repeat:no-repeat; - background-size:contain -} - -.ipfs-zip { - background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAm9JREFUeNpsk0tv00AUhc+MY6dOmgeFJg1FoVVpUWlFC0s2IFF1jxBbhKj4BSxYdscPYcEmQmIDq0gsERIViy4TpD7VFzF1Ho5je2a4thOqNhlp5Mz4zudzzp0wpRTC8fPrk0/TC6+fDtYicLH97T1Kc2vQDcs+rH3eUAxVznn0fn1DRM8E+iOdv5ct3XmZG6yVlNj6solUbgVTt0q5FGtX6vXqC6VklTE+KAO/OODHSIQPRQpsXC+kkEz2ELA0ystv84tLzyucsbWByisAGf+QAS2CCDRRLMJMmxC+i8C4jdLCm/zM7OOKFGptcO6/BTpJ0yeQB0Y+mfKQuZZG0jQgeRbW8Xdomobs9LN8scc+UPHNy4Dwq8IljotIIQEm59/RoSyM1CKkXKZNBm7kIVgyM6wgAnSgRK9vqQfHPiMFDHqyFVsLR9Cm0o4YzoAASrSjCelQfRPb1Vc4qn0EY5L2W9GEaBLcxQgFHpGbkMIDJ69e+wjJ8VXqRgKid0r7ftQdxkRs9SqA2kgAm14SSIQh9uhuLGPMnKJs/5KquL1x0N0RCsizigoDaLqBdHoMiyvrlBsHVx1wphD4BCewoqxGKKDwAgtOy8JufYuk+5golGGaGZwc1sIGoDz3AOPZSVLaHgVwydoJDM1H4DbQODughB3YpOD44HfoHgnu4e7So0uAi0stHLJ3Aud8B9bpHu6vPoSu9TtDl6tUuoFiIYOgu0+158MKmOxomtyD3Qi/3MTR7i8K0EDG1GHO5DE3X4DvNahZlJOwEkOATvdPc2//hx3mXJ5lFJaF8K8bStd0YGfnOJbMGex21x6c+yfAAOlIPDJzr7cLAAAAAElFTkSuQmCC); - background-repeat:no-repeat; - background-size:contain -} diff --git a/assets/dir-index-html/src/style.css b/assets/dir-index-html/src/style.css deleted file mode 100644 index 3e7b8a734..000000000 --- a/assets/dir-index-html/src/style.css +++ /dev/null @@ -1,212 +0,0 @@ -body { - color:#34373f; - font-family:"Helvetica Neue", Helvetica, Arial, sans-serif; - font-size:14px; - line-height:1.43; - margin:0; - word-break:break-all; - -webkit-text-size-adjust:100%; - -ms-text-size-adjust:100%; - -webkit-tap-highlight-color:transparent -} - -a { - color:#117eb3; - text-decoration:none -} - -a:hover { - color:#00b0e9; - text-decoration:underline -} - -a:active, -a:visited { - color:#00b0e9 -} - -strong { - font-weight:700 -} - -table { - border-collapse:collapse; - border-spacing:0; - max-width:100%; - width:100% -} - -table:last-child { - border-bottom-left-radius:3px; - border-bottom-right-radius:3px -} - -tr:first-child td { - border-top:0 -} - -tr:nth-of-type(even) { - background-color:#f7f8fa -} - -td { - border-top:1px solid #d9dbe2; - padding:.65em; - vertical-align:top -} - -#page-header { - align-items:center; - background:#0b3a53; - border-bottom:4px solid #69c4cd; - color:#fff; - display:flex; - font-size:1.12em; - font-weight:500; - justify-content:space-between; - padding:0 1em -} - -#page-header a { - color:#69c4cd -} - -#page-header a:active { - color:#9ad4db -} - -#page-header a:hover { - color:#fff -} - -#page-header-logo { - height:2.25em; - margin:.7em .7em .7em 0; - width:7.15em -} - -#page-header-menu { - align-items:center; - display:flex; - margin:.65em 0 -} - -#page-header-menu div { - margin:0 .6em -} - -#page-header-menu div:last-child { - margin:0 0 0 .6em -} - -#page-header-menu svg { - fill:#69c4cd; - height:1.8em; - margin-top:.125em -} - -#page-header-menu svg:hover { - fill:#fff -} - -.menu-item-narrow { - display:none -} - -#content { - border:1px solid #d9dbe2; - border-radius:4px; - margin:1em -} - -#content-header { - background-color:#edf0f4; - border-bottom:1px solid #d9dbe2; - border-top-left-radius:3px; - border-top-right-radius:3px; - padding:.7em 1em -} - -.type-icon, -.type-icon>* { - width:1.15em -} - -.no-linebreak { - white-space:nowrap -} - -.ipfs-hash { - color:#7f8491; - font-family:monospace -} - -@media only screen and (max-width:500px) { - .menu-item-narrow { - display:inline - } - .menu-item-wide { - display:none - } -} - -@media print { - #page-header { - display:none - } - #content-header, - .ipfs-hash, - body { - color:#000 - } - #content-header { - border-bottom:1px solid #000 - } - #content { - border:1px solid #000 - } - a, - a:visited { - color:#000; - text-decoration:underline - } - a[href]:after { - content:" (" attr(href) ")" - } - tr { - page-break-inside:avoid - } - tr:nth-of-type(even) { - background-color:transparent - } - td { - border-top:1px solid #000 - } -} - -@-ms-viewport { - width:device-width -} - -.d-flex { - display:flex -} - -.flex-wrap { - flex-flow:wrap -} - -.flex-shrink-1 { - flex-shrink:1 -} - -.ml-auto { - margin-left:auto -} - -.table-responsive { - display:block; - width:100%; - overflow-x:auto; - -webkit-overflow-scrolling:touch -} diff --git a/assets/dir-index-html/test/go.mod b/assets/dir-index-html/test/go.mod deleted file mode 100644 index c1cff1b74..000000000 --- a/assets/dir-index-html/test/go.mod +++ /dev/null @@ -1,3 +0,0 @@ -module github.com/ipfs/dir-index-html/test - -go 1.17 diff --git a/assets/dir-index-html/test/main.go b/assets/dir-index-html/test/main.go deleted file mode 100644 index c02523a9f..000000000 --- a/assets/dir-index-html/test/main.go +++ /dev/null @@ -1,116 +0,0 @@ -package main - -import ( - "fmt" - "net/http" - "net/url" - "os" - "text/template" -) - -const templateFile = "../dir-index.html" - -// Copied from go-ipfs/core/corehttp/gateway_indexPage.go -type listingTemplateData struct { - GatewayURL string - DNSLink bool - Listing []directoryItem - Size string - Path string - Breadcrumbs []breadcrumb - BackLink string - Hash string -} - -type directoryItem struct { - Size string - Name string - Path string - Hash string - ShortHash string -} - -type breadcrumb struct { - Name string - Path string -} - -var testPath = "/ipfs/QmFooBarQXB2mzChmMeKY47C43LxUdg1NDJ5MWcKMKxDu7/a/b/c" -var testData = listingTemplateData{ - GatewayURL: "//localhost:3000", - DNSLink: true, - Listing: []directoryItem{{ - Size: "25 MiB", - Name: "short-film.mov", - Path: testPath + "/short-film.mov", - Hash: "QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR", - ShortHash: "QmbW\u2026sMnR", - }, { - Size: "23 KiB", - Name: "250pxيوسف_الوزاني_صورة_ملتقطة_بواسطة_مرصد_هابل_الفضائي_توضح_سديم_السرطان،_وهو_بقايا_مستعر_أعظم._.jpg", - Path: testPath + "/250pxيوسف_الوزاني_صورة_ملتقطة_بواسطة_مرصد_هابل_الفضائي_توضح_سديم_السرطان،_وهو_بقايا_مستعر_أعظم._.jpg", - Hash: "QmUwrKrMTrNv8QjWGKMMH5QV9FMPUtRCoQ6zxTdgxATQW6", - ShortHash: "QmUw\u2026TQW6", - }, { - Size: "1 KiB", - Name: "this-piece-of-papers-got-47-words-37-sentences-58-words-we-wanna-know.txt", - Path: testPath + "/this-piece-of-papers-got-47-words-37-sentences-58-words-we-wanna-know.txt", - Hash: "bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi", - ShortHash: "bafy\u2026bzdi", - }}, - Size: "25 MiB", - Path: testPath, - Breadcrumbs: []breadcrumb{{ - Name: "ipfs", - }, { - Name: "QmFooBarQXB2mzChmMeKY47C43LxUdg1NDJ5MWcKMKxDu7", - Path: testPath + "/../../..", - }, { - Name: "a", - Path: testPath + "/../..", - }, { - Name: "b", - Path: testPath + "/..", - }, { - Name: "c", - Path: testPath, - }}, - BackLink: testPath + "/..", - Hash: "QmFooBazBar2mzChmMeKY47C43LxUdg1NDJ5MWcKMKxDu7", -} - -func main() { - mux := http.NewServeMux() - mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { - if r.URL.Path != "/" { - http.Error(w, "Ha-ha, tricked you! There are no files here!", http.StatusNotFound) - return - } - listingTemplate, err := template.New("dir-index.html").Funcs(template.FuncMap{ - "iconFromExt": func(name string) string { - return "ipfs-_blank" // place-holder - }, - "urlEscape": func(rawUrl string) string { - pathUrl := url.URL{Path: rawUrl} - return pathUrl.String() - }, - }).ParseFiles(templateFile) - if err != nil { - http.Error(w, fmt.Sprintf("failed to parse template file: %s", err), http.StatusInternalServerError) - return - } - err = listingTemplate.Execute(w, &testData) - if err != nil { - http.Error(w, fmt.Sprintf("failed to execute template: %s", err), http.StatusInternalServerError) - return - } - w.WriteHeader(http.StatusOK) - }) - if _, err := os.Stat(templateFile); err != nil { - wd, _ := os.Getwd() - fmt.Printf("could not open template file %q, relative to %q: %s\n", templateFile, wd, err) - os.Exit(1) - } - fmt.Printf("listening on localhost:3000\n") - http.ListenAndServe("localhost:3000", mux) -} diff --git a/core/corehttp/gateway.go b/core/corehttp/gateway.go index 00c2f7483..d5eccf73c 100644 --- a/core/corehttp/gateway.go +++ b/core/corehttp/gateway.go @@ -1,15 +1,12 @@ package corehttp import ( - "context" "fmt" "net" "net/http" - "sort" - coreiface "github.com/ipfs/interface-go-ipfs-core" + "github.com/ipfs/go-libipfs/gateway" options "github.com/ipfs/interface-go-ipfs-core/options" - path "github.com/ipfs/interface-go-ipfs-core/path" version "github.com/ipfs/kubo" core "github.com/ipfs/kubo/core" coreapi "github.com/ipfs/kubo/core/coreapi" @@ -17,50 +14,6 @@ import ( "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" ) -type GatewayConfig struct { - Headers map[string][]string - Writable bool -} - -// NodeAPI defines the minimal set of API services required by a gateway handler -type NodeAPI interface { - // Unixfs returns an implementation of Unixfs API - Unixfs() coreiface.UnixfsAPI - - // Block returns an implementation of Block API - Block() coreiface.BlockAPI - - // Dag returns an implementation of Dag API - Dag() coreiface.APIDagService - - // Routing returns an implementation of Routing API. - // Used for returning signed IPNS records, see IPIP-0328 - Routing() coreiface.RoutingAPI - - // ResolvePath resolves the path using Unixfs resolver - ResolvePath(context.Context, path.Path) (path.Resolved, error) -} - -// A helper function to clean up a set of headers: -// 1. Canonicalizes. -// 2. Deduplicates. -// 3. Sorts. -func cleanHeaderSet(headers []string) []string { - // Deduplicate and canonicalize. - m := make(map[string]struct{}, len(headers)) - for _, h := range headers { - m[http.CanonicalHeaderKey(h)] = struct{}{} - } - result := make([]string, 0, len(m)) - for k := range m { - result = append(result, k) - } - - // Sort - sort.Strings(result) - return result -} - func GatewayOption(writable bool, paths ...string) ServeOption { return func(n *core.IpfsNode, _ net.Listener, mux *http.ServeMux) (*http.ServeMux, error) { cfg, err := n.Repo.Config() @@ -78,14 +31,14 @@ func GatewayOption(writable bool, paths ...string) ServeOption { headers[http.CanonicalHeaderKey(h)] = v } - AddAccessControlHeaders(headers) + gateway.AddAccessControlHeaders(headers) offlineAPI, err := api.WithOptions(options.Api.Offline(true)) if err != nil { return nil, err } - gateway := NewGatewayHandler(GatewayConfig{ + gateway := gateway.NewHandler(gateway.Config{ Headers: headers, Writable: writable, }, api, offlineAPI) @@ -99,50 +52,6 @@ func GatewayOption(writable bool, paths ...string) ServeOption { } } -// AddAccessControlHeaders adds default headers used for controlling -// cross-origin requests. This function adds several values to the -// Access-Control-Allow-Headers and Access-Control-Expose-Headers entries. -// If the Access-Control-Allow-Origin entry is missing a value of '*' is -// added, indicating that browsers should allow requesting code from any -// origin to access the resource. -// If the Access-Control-Allow-Methods entry is missing a value of 'GET' is -// added, indicating that browsers may use the GET method when issuing cross -// origin requests. -func AddAccessControlHeaders(headers map[string][]string) { - // Hard-coded headers. - const ACAHeadersName = "Access-Control-Allow-Headers" - const ACEHeadersName = "Access-Control-Expose-Headers" - const ACAOriginName = "Access-Control-Allow-Origin" - const ACAMethodsName = "Access-Control-Allow-Methods" - - if _, ok := headers[ACAOriginName]; !ok { - // Default to *all* - headers[ACAOriginName] = []string{"*"} - } - if _, ok := headers[ACAMethodsName]; !ok { - // Default to GET - headers[ACAMethodsName] = []string{http.MethodGet} - } - - headers[ACAHeadersName] = cleanHeaderSet( - append([]string{ - "Content-Type", - "User-Agent", - "Range", - "X-Requested-With", - }, headers[ACAHeadersName]...)) - - headers[ACEHeadersName] = cleanHeaderSet( - append([]string{ - "Content-Length", - "Content-Range", - "X-Chunked-Output", - "X-Stream-Output", - "X-Ipfs-Path", - "X-Ipfs-Roots", - }, headers[ACEHeadersName]...)) -} - func VersionOption() ServeOption { return func(_ *core.IpfsNode, _ net.Listener, mux *http.ServeMux) (*http.ServeMux, error) { mux.HandleFunc("/version", func(w http.ResponseWriter, r *http.Request) { diff --git a/core/corehttp/gateway_handler.go b/core/corehttp/gateway_handler.go deleted file mode 100644 index c3e8fa0d6..000000000 --- a/core/corehttp/gateway_handler.go +++ /dev/null @@ -1,1117 +0,0 @@ -package corehttp - -import ( - "context" - "fmt" - "html/template" - "io" - "mime" - "net/http" - "net/textproto" - "net/url" - "os" - gopath "path" - "regexp" - "runtime/debug" - "strings" - "time" - - cid "github.com/ipfs/go-cid" - ipld "github.com/ipfs/go-ipld-format" - "github.com/ipfs/go-libipfs/files" - dag "github.com/ipfs/go-merkledag" - mfs "github.com/ipfs/go-mfs" - path "github.com/ipfs/go-path" - "github.com/ipfs/go-path/resolver" - coreiface "github.com/ipfs/interface-go-ipfs-core" - ipath "github.com/ipfs/interface-go-ipfs-core/path" - routing "github.com/libp2p/go-libp2p/core/routing" - mc "github.com/multiformats/go-multicodec" - prometheus "github.com/prometheus/client_golang/prometheus" - "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/trace" - "go.uber.org/zap" -) - -const ( - ipfsPathPrefix = "/ipfs/" - ipnsPathPrefix = "/ipns/" - immutableCacheControl = "public, max-age=29030400, immutable" -) - -var ( - onlyASCII = regexp.MustCompile("[[:^ascii:]]") - noModtime = time.Unix(0, 0) // disables Last-Modified header if passed as modtime -) - -// HTML-based redirect for errors which can be recovered from, but we want -// to provide hint to people that they should fix things on their end. -var redirectTemplate = template.Must(template.New("redirect").Parse(` - - - - - - - -
{{.ErrorMsg}}
(if a redirect does not happen in 10 seconds, use "{{.SuggestedPath}}" instead)
- -`)) - -type redirectTemplateData struct { - RedirectURL string - SuggestedPath string - ErrorMsg string -} - -// gatewayHandler is a HTTP handler that serves IPFS objects (accessible by default at /ipfs/) -// (it serves requests like GET /ipfs/QmVRzPKPzNtSrEzBFm2UZfxmPAgnaLke4DMcerbsGGSaFe/link) -type gatewayHandler struct { - config GatewayConfig - api NodeAPI - offlineAPI NodeAPI - - // generic metrics - firstContentBlockGetMetric *prometheus.HistogramVec - unixfsGetMetric *prometheus.SummaryVec // deprecated, use firstContentBlockGetMetric - - // response type metrics - unixfsFileGetMetric *prometheus.HistogramVec - unixfsGenDirGetMetric *prometheus.HistogramVec - carStreamGetMetric *prometheus.HistogramVec - rawBlockGetMetric *prometheus.HistogramVec -} - -// StatusResponseWriter enables us to override HTTP Status Code passed to -// WriteHeader function inside of http.ServeContent. Decision is based on -// presence of HTTP Headers such as Location. -type statusResponseWriter struct { - http.ResponseWriter -} - -// Custom type for collecting error details to be handled by `webRequestError` -type requestError struct { - Message string - StatusCode int - Err error -} - -func (r *requestError) Error() string { - return r.Err.Error() -} - -func newRequestError(message string, err error, statusCode int) *requestError { - return &requestError{ - Message: message, - Err: err, - StatusCode: statusCode, - } -} - -func (sw *statusResponseWriter) WriteHeader(code int) { - // Check if we need to adjust Status Code to account for scheduled redirect - // This enables us to return payload along with HTTP 301 - // for subdomain redirect in web browsers while also returning body for cli - // tools which do not follow redirects by default (curl, wget). - redirect := sw.ResponseWriter.Header().Get("Location") - if redirect != "" && code == http.StatusOK { - code = http.StatusMovedPermanently - log.Debugw("subdomain redirect", "location", redirect, "status", code) - } - sw.ResponseWriter.WriteHeader(code) -} - -// ServeContent replies to the request using the content in the provided ReadSeeker -// and returns the status code written and any error encountered during a write. -// It wraps http.ServeContent which takes care of If-None-Match+Etag, -// Content-Length and range requests. -func ServeContent(w http.ResponseWriter, req *http.Request, name string, modtime time.Time, content io.ReadSeeker) (int, bool, error) { - ew := &errRecordingResponseWriter{ResponseWriter: w} - http.ServeContent(ew, req, name, modtime, content) - - // When we calculate some metrics we want a flag that lets us to ignore - // errors and 304 Not Modified, and only care when requested data - // was sent in full. - dataSent := ew.code/100 == 2 && ew.err == nil - - return ew.code, dataSent, ew.err -} - -// errRecordingResponseWriter wraps a ResponseWriter to record the status code and any write error. -type errRecordingResponseWriter struct { - http.ResponseWriter - code int - err error -} - -func (w *errRecordingResponseWriter) WriteHeader(code int) { - if w.code == 0 { - w.code = code - } - w.ResponseWriter.WriteHeader(code) -} - -func (w *errRecordingResponseWriter) Write(p []byte) (int, error) { - n, err := w.ResponseWriter.Write(p) - if err != nil && w.err == nil { - w.err = err - } - return n, err -} - -// ReadFrom exposes errRecordingResponseWriter's underlying ResponseWriter to io.Copy -// to allow optimized methods to be taken advantage of. -func (w *errRecordingResponseWriter) ReadFrom(r io.Reader) (n int64, err error) { - n, err = io.Copy(w.ResponseWriter, r) - if err != nil && w.err == nil { - w.err = err - } - return n, err -} - -func newGatewaySummaryMetric(name string, help string) *prometheus.SummaryVec { - summaryMetric := prometheus.NewSummaryVec( - prometheus.SummaryOpts{ - Namespace: "ipfs", - Subsystem: "http", - Name: name, - Help: help, - }, - []string{"gateway"}, - ) - if err := prometheus.Register(summaryMetric); err != nil { - if are, ok := err.(prometheus.AlreadyRegisteredError); ok { - summaryMetric = are.ExistingCollector.(*prometheus.SummaryVec) - } else { - log.Errorf("failed to register ipfs_http_%s: %v", name, err) - } - } - return summaryMetric -} - -func newGatewayHistogramMetric(name string, help string) *prometheus.HistogramVec { - // We can add buckets as a parameter in the future, but for now using static defaults - // suggested in https://github.com/ipfs/kubo/issues/8441 - defaultBuckets := []float64{0.05, 0.1, 0.25, 0.5, 1, 2, 5, 10, 30, 60} - histogramMetric := prometheus.NewHistogramVec( - prometheus.HistogramOpts{ - Namespace: "ipfs", - Subsystem: "http", - Name: name, - Help: help, - Buckets: defaultBuckets, - }, - []string{"gateway"}, - ) - if err := prometheus.Register(histogramMetric); err != nil { - if are, ok := err.(prometheus.AlreadyRegisteredError); ok { - histogramMetric = are.ExistingCollector.(*prometheus.HistogramVec) - } else { - log.Errorf("failed to register ipfs_http_%s: %v", name, err) - } - } - return histogramMetric -} - -// NewGatewayHandler returns an http.Handler that can act as a gateway to IPFS content -// offlineApi is a version of the API that should not make network requests for missing data -func NewGatewayHandler(c GatewayConfig, api NodeAPI, offlineAPI NodeAPI) http.Handler { - return newGatewayHandler(c, api, offlineAPI) -} - -func newGatewayHandler(c GatewayConfig, api NodeAPI, offlineAPI NodeAPI) *gatewayHandler { - i := &gatewayHandler{ - config: c, - api: api, - offlineAPI: offlineAPI, - // Improved Metrics - // ---------------------------- - // Time till the first content block (bar in /ipfs/cid/foo/bar) - // (format-agnostic, across all response types) - firstContentBlockGetMetric: newGatewayHistogramMetric( - "gw_first_content_block_get_latency_seconds", - "The time till the first content block is received on GET from the gateway.", - ), - - // Response-type specific metrics - // ---------------------------- - // UnixFS: time it takes to return a file - unixfsFileGetMetric: newGatewayHistogramMetric( - "gw_unixfs_file_get_duration_seconds", - "The time to serve an entire UnixFS file from the gateway.", - ), - // UnixFS: time it takes to generate static HTML with directory listing - unixfsGenDirGetMetric: newGatewayHistogramMetric( - "gw_unixfs_gen_dir_listing_get_duration_seconds", - "The time to serve a generated UnixFS HTML directory listing from the gateway.", - ), - // CAR: time it takes to return requested CAR stream - carStreamGetMetric: newGatewayHistogramMetric( - "gw_car_stream_get_duration_seconds", - "The time to GET an entire CAR stream from the gateway.", - ), - // Block: time it takes to return requested Block - rawBlockGetMetric: newGatewayHistogramMetric( - "gw_raw_block_get_duration_seconds", - "The time to GET an entire raw Block from the gateway.", - ), - - // Legacy Metrics - // ---------------------------- - unixfsGetMetric: newGatewaySummaryMetric( // TODO: remove? - // (deprecated, use firstContentBlockGetMetric instead) - "unixfs_get_latency_seconds", - "The time to receive the first UnixFS node on a GET from the gateway.", - ), - } - return i -} - -func parseIpfsPath(p string) (cid.Cid, string, error) { - rootPath, err := path.ParsePath(p) - if err != nil { - return cid.Cid{}, "", err - } - - // Check the path. - rsegs := rootPath.Segments() - if rsegs[0] != "ipfs" { - return cid.Cid{}, "", fmt.Errorf("WritableGateway: only ipfs paths supported") - } - - rootCid, err := cid.Decode(rsegs[1]) - if err != nil { - return cid.Cid{}, "", err - } - - return rootCid, path.Join(rsegs[2:]), nil -} - -func (i *gatewayHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { - // the hour is a hard fallback, we don't expect it to happen, but just in case - ctx, cancel := context.WithTimeout(r.Context(), time.Hour) - defer cancel() - r = r.WithContext(ctx) - - defer func() { - if r := recover(); r != nil { - log.Error("A panic occurred in the gateway handler!") - log.Error(r) - debug.PrintStack() - } - }() - - if i.config.Writable { - switch r.Method { - case http.MethodPost: - i.postHandler(w, r) - return - case http.MethodPut: - i.putHandler(w, r) - return - case http.MethodDelete: - i.deleteHandler(w, r) - return - } - } - - switch r.Method { - case http.MethodGet, http.MethodHead: - i.getOrHeadHandler(w, r) - return - case http.MethodOptions: - i.optionsHandler(w, r) - return - } - - errmsg := "Method " + r.Method + " not allowed: " - var status int - if !i.config.Writable { - status = http.StatusMethodNotAllowed - errmsg = errmsg + "read only access" - w.Header().Add("Allow", http.MethodGet) - w.Header().Add("Allow", http.MethodHead) - w.Header().Add("Allow", http.MethodOptions) - } else { - status = http.StatusBadRequest - errmsg = errmsg + "bad request for " + r.URL.Path - } - http.Error(w, errmsg, status) -} - -func (i *gatewayHandler) optionsHandler(w http.ResponseWriter, r *http.Request) { - /* - OPTIONS is a noop request that is used by the browsers to check - if server accepts cross-site XMLHttpRequest (indicated by the presence of CORS headers) - https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Preflighted_requests - */ - i.addUserHeaders(w) // return all custom headers (including CORS ones, if set) -} - -func (i *gatewayHandler) getOrHeadHandler(w http.ResponseWriter, r *http.Request) { - begin := time.Now() - - logger := log.With("from", r.RequestURI) - logger.Debug("http request received") - - if err := handleUnsupportedHeaders(r); err != nil { - webRequestError(w, err) - return - } - - if requestHandled := handleProtocolHandlerRedirect(w, r, logger); requestHandled { - return - } - - if err := handleServiceWorkerRegistration(r); err != nil { - webRequestError(w, err) - return - } - - contentPath := ipath.New(r.URL.Path) - - if requestHandled := i.handleOnlyIfCached(w, r, contentPath, logger); requestHandled { - return - } - - if requestHandled := handleSuperfluousNamespace(w, r, contentPath); requestHandled { - return - } - - // Detect when explicit Accept header or ?format parameter are present - responseFormat, formatParams, err := customResponseFormat(r) - if err != nil { - webError(w, "error while processing the Accept header", err, http.StatusBadRequest) - return - } - trace.SpanFromContext(r.Context()).SetAttributes(attribute.String("ResponseFormat", responseFormat)) - - resolvedPath, contentPath, ok := i.handlePathResolution(w, r, responseFormat, contentPath, logger) - if !ok { - return - } - trace.SpanFromContext(r.Context()).SetAttributes(attribute.String("ResolvedPath", resolvedPath.String())) - - // Detect when If-None-Match HTTP header allows returning HTTP 304 Not Modified - if inm := r.Header.Get("If-None-Match"); inm != "" { - pathCid := resolvedPath.Cid() - // need to check against both File and Dir Etag variants - // because this inexpensive check happens before we do any I/O - cidEtag := getEtag(r, pathCid) - dirEtag := getDirListingEtag(pathCid) - if etagMatch(inm, cidEtag, dirEtag) { - // Finish early if client already has a matching Etag - w.WriteHeader(http.StatusNotModified) - return - } - } - - if err := i.handleGettingFirstBlock(r, begin, contentPath, resolvedPath); err != nil { - webRequestError(w, err) - return - } - - if err := i.setCommonHeaders(w, r, contentPath); err != nil { - webRequestError(w, err) - return - } - - // Support custom response formats passed via ?format or Accept HTTP header - switch responseFormat { - case "", "application/json", "application/cbor": - switch mc.Code(resolvedPath.Cid().Prefix().Codec) { - case mc.Json, mc.DagJson, mc.Cbor, mc.DagCbor: - logger.Debugw("serving codec", "path", contentPath) - i.serveCodec(r.Context(), w, r, resolvedPath, contentPath, begin, responseFormat) - default: - logger.Debugw("serving unixfs", "path", contentPath) - i.serveUnixFS(r.Context(), w, r, resolvedPath, contentPath, begin, logger) - } - return - case "application/vnd.ipld.raw": - logger.Debugw("serving raw block", "path", contentPath) - i.serveRawBlock(r.Context(), w, r, resolvedPath, contentPath, begin) - return - case "application/vnd.ipld.car": - logger.Debugw("serving car stream", "path", contentPath) - carVersion := formatParams["version"] - i.serveCAR(r.Context(), w, r, resolvedPath, contentPath, carVersion, begin) - return - case "application/x-tar": - logger.Debugw("serving tar file", "path", contentPath) - i.serveTAR(r.Context(), w, r, resolvedPath, contentPath, begin, logger) - return - case "application/vnd.ipld.dag-json", "application/vnd.ipld.dag-cbor": - logger.Debugw("serving codec", "path", contentPath) - i.serveCodec(r.Context(), w, r, resolvedPath, contentPath, begin, responseFormat) - case "application/vnd.ipfs.ipns-record": - logger.Debugw("serving ipns record", "path", contentPath) - i.serveIpnsRecord(r.Context(), w, r, resolvedPath, contentPath, begin, logger) - return - default: // catch-all for unsuported application/vnd.* - err := fmt.Errorf("unsupported format %q", responseFormat) - webError(w, "failed to respond with requested content type", err, http.StatusBadRequest) - return - } -} - -func (i *gatewayHandler) postHandler(w http.ResponseWriter, r *http.Request) { - p, err := i.api.Unixfs().Add(r.Context(), files.NewReaderFile(r.Body)) - if err != nil { - internalWebError(w, err) - return - } - - i.addUserHeaders(w) // ok, _now_ write user's headers. - w.Header().Set("IPFS-Hash", p.Cid().String()) - log.Debugw("CID created, http redirect", "from", r.URL, "to", p, "status", http.StatusCreated) - http.Redirect(w, r, p.String(), http.StatusCreated) -} - -func (i *gatewayHandler) putHandler(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() - ds := i.api.Dag() - - // Parse the path - rootCid, newPath, err := parseIpfsPath(r.URL.Path) - if err != nil { - webError(w, "WritableGateway: failed to parse the path", err, http.StatusBadRequest) - return - } - if newPath == "" || newPath == "/" { - http.Error(w, "WritableGateway: empty path", http.StatusBadRequest) - return - } - newDirectory, newFileName := gopath.Split(newPath) - - // Resolve the old root. - - rnode, err := ds.Get(ctx, rootCid) - if err != nil { - webError(w, "WritableGateway: Could not create DAG from request", err, http.StatusInternalServerError) - return - } - - pbnd, ok := rnode.(*dag.ProtoNode) - if !ok { - webError(w, "Cannot read non protobuf nodes through gateway", dag.ErrNotProtobuf, http.StatusBadRequest) - return - } - - // Create the new file. - newFilePath, err := i.api.Unixfs().Add(ctx, files.NewReaderFile(r.Body)) - if err != nil { - webError(w, "WritableGateway: could not create DAG from request", err, http.StatusInternalServerError) - return - } - - newFile, err := ds.Get(ctx, newFilePath.Cid()) - if err != nil { - webError(w, "WritableGateway: failed to resolve new file", err, http.StatusInternalServerError) - return - } - - // Patch the new file into the old root. - - root, err := mfs.NewRoot(ctx, ds, pbnd, nil) - if err != nil { - webError(w, "WritableGateway: failed to create MFS root", err, http.StatusBadRequest) - return - } - - if newDirectory != "" { - err := mfs.Mkdir(root, newDirectory, mfs.MkdirOpts{Mkparents: true, Flush: false}) - if err != nil { - webError(w, "WritableGateway: failed to create MFS directory", err, http.StatusInternalServerError) - return - } - } - dirNode, err := mfs.Lookup(root, newDirectory) - if err != nil { - webError(w, "WritableGateway: failed to lookup directory", err, http.StatusInternalServerError) - return - } - dir, ok := dirNode.(*mfs.Directory) - if !ok { - http.Error(w, "WritableGateway: target directory is not a directory", http.StatusBadRequest) - return - } - err = dir.Unlink(newFileName) - switch err { - case os.ErrNotExist, nil: - default: - webError(w, "WritableGateway: failed to replace existing file", err, http.StatusBadRequest) - return - } - err = dir.AddChild(newFileName, newFile) - if err != nil { - webError(w, "WritableGateway: failed to link file into directory", err, http.StatusInternalServerError) - return - } - nnode, err := root.GetDirectory().GetNode() - if err != nil { - webError(w, "WritableGateway: failed to finalize", err, http.StatusInternalServerError) - return - } - newcid := nnode.Cid() - - i.addUserHeaders(w) // ok, _now_ write user's headers. - w.Header().Set("IPFS-Hash", newcid.String()) - - redirectURL := gopath.Join(ipfsPathPrefix, newcid.String(), newPath) - log.Debugw("CID replaced, redirect", "from", r.URL, "to", redirectURL, "status", http.StatusCreated) - http.Redirect(w, r, redirectURL, http.StatusCreated) -} - -func (i *gatewayHandler) deleteHandler(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() - - // parse the path - - rootCid, newPath, err := parseIpfsPath(r.URL.Path) - if err != nil { - webError(w, "WritableGateway: failed to parse the path", err, http.StatusBadRequest) - return - } - if newPath == "" || newPath == "/" { - http.Error(w, "WritableGateway: empty path", http.StatusBadRequest) - return - } - directory, filename := gopath.Split(newPath) - - // lookup the root - - rootNodeIPLD, err := i.api.Dag().Get(ctx, rootCid) - if err != nil { - webError(w, "WritableGateway: failed to resolve root CID", err, http.StatusInternalServerError) - return - } - rootNode, ok := rootNodeIPLD.(*dag.ProtoNode) - if !ok { - http.Error(w, "WritableGateway: empty path", http.StatusInternalServerError) - return - } - - // construct the mfs root - - root, err := mfs.NewRoot(ctx, i.api.Dag(), rootNode, nil) - if err != nil { - webError(w, "WritableGateway: failed to construct the MFS root", err, http.StatusBadRequest) - return - } - - // lookup the parent directory - - parentNode, err := mfs.Lookup(root, directory) - if err != nil { - webError(w, "WritableGateway: failed to look up parent", err, http.StatusInternalServerError) - return - } - - parent, ok := parentNode.(*mfs.Directory) - if !ok { - http.Error(w, "WritableGateway: parent is not a directory", http.StatusInternalServerError) - return - } - - // delete the file - - switch parent.Unlink(filename) { - case nil, os.ErrNotExist: - default: - webError(w, "WritableGateway: failed to remove file", err, http.StatusInternalServerError) - return - } - - nnode, err := root.GetDirectory().GetNode() - if err != nil { - webError(w, "WritableGateway: failed to finalize", err, http.StatusInternalServerError) - return - } - ncid := nnode.Cid() - - i.addUserHeaders(w) // ok, _now_ write user's headers. - w.Header().Set("IPFS-Hash", ncid.String()) - - redirectURL := gopath.Join(ipfsPathPrefix+ncid.String(), directory) - // note: StatusCreated is technically correct here as we created a new resource. - log.Debugw("CID deleted, redirect", "from", r.RequestURI, "to", redirectURL, "status", http.StatusCreated) - http.Redirect(w, r, redirectURL, http.StatusCreated) -} - -func (i *gatewayHandler) addUserHeaders(w http.ResponseWriter) { - for k, v := range i.config.Headers { - w.Header()[k] = v - } -} - -func addCacheControlHeaders(w http.ResponseWriter, r *http.Request, contentPath ipath.Path, fileCid cid.Cid) (modtime time.Time) { - // Set Etag to based on CID (override whatever was set before) - w.Header().Set("Etag", getEtag(r, fileCid)) - - // Set Cache-Control and Last-Modified based on contentPath properties - if contentPath.Mutable() { - // mutable namespaces such as /ipns/ can't be cached forever - - /* For now we set Last-Modified to Now() to leverage caching heuristics built into modern browsers: - * https://github.com/ipfs/kubo/pull/8074#pullrequestreview-645196768 - * but we should not set it to fake values and use Cache-Control based on TTL instead */ - modtime = time.Now() - - // TODO: set Cache-Control based on TTL of IPNS/DNSLink: https://github.com/ipfs/kubo/issues/1818#issuecomment-1015849462 - // TODO: set Last-Modified based on /ipns/ publishing timestamp? - } else { - // immutable! CACHE ALL THE THINGS, FOREVER! wolololol - w.Header().Set("Cache-Control", immutableCacheControl) - - // Set modtime to 'zero time' to disable Last-Modified header (superseded by Cache-Control) - modtime = noModtime - - // TODO: set Last-Modified? - TBD - /ipfs/ modification metadata is present in unixfs 1.5 https://github.com/ipfs/kubo/issues/6920? - } - - return modtime -} - -// Set Content-Disposition if filename URL query param is present, return preferred filename -func addContentDispositionHeader(w http.ResponseWriter, r *http.Request, contentPath ipath.Path) string { - /* This logic enables: - * - creation of HTML links that trigger "Save As.." dialog instead of being rendered by the browser - * - overriding the filename used when saving subresource assets on HTML page - * - providing a default filename for HTTP clients when downloading direct /ipfs/CID without any subpath - */ - - // URL param ?filename=cat.jpg triggers Content-Disposition: [..] filename - // which impacts default name used in "Save As.." dialog - name := getFilename(contentPath) - urlFilename := r.URL.Query().Get("filename") - if urlFilename != "" { - disposition := "inline" - // URL param ?download=true triggers Content-Disposition: [..] attachment - // which skips rendering and forces "Save As.." dialog in browsers - if r.URL.Query().Get("download") == "true" { - disposition = "attachment" - } - setContentDispositionHeader(w, urlFilename, disposition) - name = urlFilename - } - return name -} - -// Set Content-Disposition to arbitrary filename and disposition -func setContentDispositionHeader(w http.ResponseWriter, filename string, disposition string) { - utf8Name := url.PathEscape(filename) - asciiName := url.PathEscape(onlyASCII.ReplaceAllLiteralString(filename, "_")) - w.Header().Set("Content-Disposition", fmt.Sprintf("%s; filename=\"%s\"; filename*=UTF-8''%s", disposition, asciiName, utf8Name)) -} - -// Set X-Ipfs-Roots with logical CID array for efficient HTTP cache invalidation. -func (i *gatewayHandler) buildIpfsRootsHeader(contentPath string, r *http.Request) (string, error) { - /* - These are logical roots where each CID represent one path segment - and resolves to either a directory or the root block of a file. - The main purpose of this header is allow HTTP caches to do smarter decisions - around cache invalidation (eg. keep specific subdirectory/file if it did not change) - - A good example is Wikipedia, which is HAMT-sharded, but we only care about - logical roots that represent each segment of the human-readable content - path: - - Given contentPath = /ipns/en.wikipedia-on-ipfs.org/wiki/Block_of_Wikipedia_in_Turkey - rootCidList is a generated by doing `ipfs resolve -r` on each sub path: - /ipns/en.wikipedia-on-ipfs.org → bafybeiaysi4s6lnjev27ln5icwm6tueaw2vdykrtjkwiphwekaywqhcjze - /ipns/en.wikipedia-on-ipfs.org/wiki/ → bafybeihn2f7lhumh4grizksi2fl233cyszqadkn424ptjajfenykpsaiw4 - /ipns/en.wikipedia-on-ipfs.org/wiki/Block_of_Wikipedia_in_Turkey → bafkreibn6euazfvoghepcm4efzqx5l3hieof2frhp254hio5y7n3hv5rma - - The result is an ordered array of values: - X-Ipfs-Roots: bafybeiaysi4s6lnjev27ln5icwm6tueaw2vdykrtjkwiphwekaywqhcjze,bafybeihn2f7lhumh4grizksi2fl233cyszqadkn424ptjajfenykpsaiw4,bafkreibn6euazfvoghepcm4efzqx5l3hieof2frhp254hio5y7n3hv5rma - - Note that while the top one will change every time any article is changed, - the last root (responsible for specific article) may not change at all. - */ - var sp strings.Builder - var pathRoots []string - pathSegments := strings.Split(contentPath[6:], "/") - sp.WriteString(contentPath[:5]) // /ipfs or /ipns - for _, root := range pathSegments { - if root == "" { - continue - } - sp.WriteString("/") - sp.WriteString(root) - resolvedSubPath, err := i.api.ResolvePath(r.Context(), ipath.New(sp.String())) - if err != nil { - return "", err - } - pathRoots = append(pathRoots, resolvedSubPath.Cid().String()) - } - rootCidList := strings.Join(pathRoots, ",") // convention from rfc2616#sec4.2 - return rootCidList, nil -} - -func webRequestError(w http.ResponseWriter, err *requestError) { - webError(w, err.Message, err.Err, err.StatusCode) -} - -func webError(w http.ResponseWriter, message string, err error, defaultCode int) { - if _, ok := err.(resolver.ErrNoLink); ok { - webErrorWithCode(w, message, err, http.StatusNotFound) - } else if err == routing.ErrNotFound { - webErrorWithCode(w, message, err, http.StatusNotFound) - } else if ipld.IsNotFound(err) { - webErrorWithCode(w, message, err, http.StatusNotFound) - } else if err == context.DeadlineExceeded { - webErrorWithCode(w, message, err, http.StatusRequestTimeout) - } else { - webErrorWithCode(w, message, err, defaultCode) - } -} - -func webErrorWithCode(w http.ResponseWriter, message string, err error, code int) { - http.Error(w, fmt.Sprintf("%s: %s", message, err), code) - if code >= 500 { - log.Warnf("server error: %s: %s", message, err) - } -} - -// return a 500 error and log -func internalWebError(w http.ResponseWriter, err error) { - webErrorWithCode(w, "internalWebError", err, http.StatusInternalServerError) -} - -func getFilename(contentPath ipath.Path) string { - s := contentPath.String() - if (strings.HasPrefix(s, ipfsPathPrefix) || strings.HasPrefix(s, ipnsPathPrefix)) && strings.Count(gopath.Clean(s), "/") <= 2 { - // Don't want to treat ipfs.io in /ipns/ipfs.io as a filename. - return "" - } - return gopath.Base(s) -} - -// etagMatch evaluates if we can respond with HTTP 304 Not Modified -// It supports multiple weak and strong etags passed in If-None-Matc stringh -// including the wildcard one. -func etagMatch(ifNoneMatchHeader string, cidEtag string, dirEtag string) bool { - buf := ifNoneMatchHeader - for { - buf = textproto.TrimString(buf) - if len(buf) == 0 { - break - } - if buf[0] == ',' { - buf = buf[1:] - continue - } - // If-None-Match: * should match against any etag - if buf[0] == '*' { - return true - } - etag, remain := scanETag(buf) - if etag == "" { - break - } - // Check for match both strong and weak etags - if etagWeakMatch(etag, cidEtag) || etagWeakMatch(etag, dirEtag) { - return true - } - buf = remain - } - return false -} - -// scanETag determines if a syntactically valid ETag is present at s. If so, -// the ETag and remaining text after consuming ETag is returned. Otherwise, -// it returns "", "". -// (This is the same logic as one executed inside of http.ServeContent) -func scanETag(s string) (etag string, remain string) { - s = textproto.TrimString(s) - start := 0 - if strings.HasPrefix(s, "W/") { - start = 2 - } - if len(s[start:]) < 2 || s[start] != '"' { - return "", "" - } - // ETag is either W/"text" or "text". - // See RFC 7232 2.3. - for i := start + 1; i < len(s); i++ { - c := s[i] - switch { - // Character values allowed in ETags. - case c == 0x21 || c >= 0x23 && c <= 0x7E || c >= 0x80: - case c == '"': - return s[:i+1], s[i+1:] - default: - return "", "" - } - } - return "", "" -} - -// etagWeakMatch reports whether a and b match using weak ETag comparison. -func etagWeakMatch(a, b string) bool { - return strings.TrimPrefix(a, "W/") == strings.TrimPrefix(b, "W/") -} - -// generate Etag value based on HTTP request and CID -func getEtag(r *http.Request, cid cid.Cid) string { - prefix := `"` - suffix := `"` - responseFormat, _, err := customResponseFormat(r) - if err == nil && responseFormat != "" { - // application/vnd.ipld.foo → foo - // application/x-bar → x-bar - shortFormat := responseFormat[strings.LastIndexAny(responseFormat, "/.")+1:] - // Etag: "cid.shortFmt" (gives us nice compression together with Content-Disposition in block (raw) and car responses) - suffix = `.` + shortFormat + suffix - } - // TODO: include selector suffix when https://github.com/ipfs/kubo/issues/8769 lands - return prefix + cid.String() + suffix -} - -// return explicit response format if specified in request as query parameter or via Accept HTTP header -func customResponseFormat(r *http.Request) (mediaType string, params map[string]string, err error) { - if formatParam := r.URL.Query().Get("format"); formatParam != "" { - // translate query param to a content type - switch formatParam { - case "raw": - return "application/vnd.ipld.raw", nil, nil - case "car": - return "application/vnd.ipld.car", nil, nil - case "tar": - return "application/x-tar", nil, nil - case "json": - return "application/json", nil, nil - case "cbor": - return "application/cbor", nil, nil - case "dag-json": - return "application/vnd.ipld.dag-json", nil, nil - case "dag-cbor": - return "application/vnd.ipld.dag-cbor", nil, nil - case "ipns-record": - return "application/vnd.ipfs.ipns-record", nil, nil - } - } - // Browsers and other user agents will send Accept header with generic types like: - // Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8 - // We only care about explicit, vendor-specific content-types and respond to the first match (in order). - // TODO: make this RFC compliant and respect weights (eg. return CAR for Accept:application/vnd.ipld.dag-json;q=0.1,application/vnd.ipld.car;q=0.2) - for _, header := range r.Header.Values("Accept") { - for _, value := range strings.Split(header, ",") { - accept := strings.TrimSpace(value) - // respond to the very first matching content type - if strings.HasPrefix(accept, "application/vnd.ipld") || - strings.HasPrefix(accept, "application/x-tar") || - strings.HasPrefix(accept, "application/json") || - strings.HasPrefix(accept, "application/cbor") || - strings.HasPrefix(accept, "application/vnd.ipfs") { - mediatype, params, err := mime.ParseMediaType(accept) - if err != nil { - return "", nil, err - } - return mediatype, params, nil - } - } - } - // If none of special-cased content types is found, return empty string - // to indicate default, implicit UnixFS response should be prepared - return "", nil, nil -} - -// returns unquoted path with all special characters revealed as \u codes -func debugStr(path string) string { - q := fmt.Sprintf("%+q", path) - if len(q) >= 3 { - q = q[1 : len(q)-1] - } - return q -} - -// Resolve the provided contentPath including any special handling related to -// the requested responseFormat. Returned ok flag indicates if gateway handler -// should continue processing the request. -func (i *gatewayHandler) handlePathResolution(w http.ResponseWriter, r *http.Request, responseFormat string, contentPath ipath.Path, logger *zap.SugaredLogger) (resolvedPath ipath.Resolved, newContentPath ipath.Path, ok bool) { - // Attempt to resolve the provided path. - resolvedPath, err := i.api.ResolvePath(r.Context(), contentPath) - - switch err { - case nil: - return resolvedPath, contentPath, true - case coreiface.ErrOffline: - webError(w, "ipfs resolve -r "+debugStr(contentPath.String()), err, http.StatusServiceUnavailable) - return nil, nil, false - default: - // The path can't be resolved. - if isUnixfsResponseFormat(responseFormat) { - // If we have origin isolation (subdomain gw, DNSLink website), - // and response type is UnixFS (default for website hosting) - // check for presence of _redirects file and apply rules defined there. - // See: https://github.com/ipfs/specs/pull/290 - if hasOriginIsolation(r) { - resolvedPath, newContentPath, ok, hadMatchingRule := i.serveRedirectsIfPresent(w, r, resolvedPath, contentPath, logger) - if hadMatchingRule { - logger.Debugw("applied a rule from _redirects file") - return resolvedPath, newContentPath, ok - } - } - - // if Accept is text/html, see if ipfs-404.html is present - // This logic isn't documented and will likely be removed at some point. - // Any 404 logic in _redirects above will have already run by this time, so it's really an extra fall back - if i.serveLegacy404IfPresent(w, r, contentPath) { - logger.Debugw("served legacy 404") - return nil, nil, false - } - } - - // Note: webError will replace http.StatusBadRequest with StatusNotFound if necessary - webError(w, "ipfs resolve -r "+debugStr(contentPath.String()), err, http.StatusBadRequest) - return nil, nil, false - } -} - -// Detect 'Cache-Control: only-if-cached' in request and return data if it is already in the local datastore. -// https://github.com/ipfs/specs/blob/main/http-gateways/PATH_GATEWAY.md#cache-control-request-header -func (i *gatewayHandler) handleOnlyIfCached(w http.ResponseWriter, r *http.Request, contentPath ipath.Path, logger *zap.SugaredLogger) (requestHandled bool) { - if r.Header.Get("Cache-Control") == "only-if-cached" { - _, err := i.offlineAPI.Block().Stat(r.Context(), contentPath) - if err != nil { - if r.Method == http.MethodHead { - w.WriteHeader(http.StatusPreconditionFailed) - return true - } - errMsg := fmt.Sprintf("%q not in local datastore", contentPath.String()) - http.Error(w, errMsg, http.StatusPreconditionFailed) - return true - } - if r.Method == http.MethodHead { - w.WriteHeader(http.StatusOK) - return true - } - } - return false -} - -func handleUnsupportedHeaders(r *http.Request) (err *requestError) { - // X-Ipfs-Gateway-Prefix was removed (https://github.com/ipfs/kubo/issues/7702) - // TODO: remove this after go-ipfs 0.13 ships - if prfx := r.Header.Get("X-Ipfs-Gateway-Prefix"); prfx != "" { - err := fmt.Errorf("X-Ipfs-Gateway-Prefix support was removed: https://github.com/ipfs/kubo/issues/7702") - return newRequestError("unsupported HTTP header", err, http.StatusBadRequest) - } - return nil -} - -// ?uri query param support for requests produced by web browsers -// via navigator.registerProtocolHandler Web API -// https://developer.mozilla.org/en-US/docs/Web/API/Navigator/registerProtocolHandler -// TLDR: redirect /ipfs/?uri=ipfs%3A%2F%2Fcid%3Fquery%3Dval to /ipfs/cid?query=val -func handleProtocolHandlerRedirect(w http.ResponseWriter, r *http.Request, logger *zap.SugaredLogger) (requestHandled bool) { - if uriParam := r.URL.Query().Get("uri"); uriParam != "" { - u, err := url.Parse(uriParam) - if err != nil { - webError(w, "failed to parse uri query parameter", err, http.StatusBadRequest) - return true - } - if u.Scheme != "ipfs" && u.Scheme != "ipns" { - webError(w, "uri query parameter scheme must be ipfs or ipns", err, http.StatusBadRequest) - return true - } - path := u.Path - if u.RawQuery != "" { // preserve query if present - path = path + "?" + u.RawQuery - } - - redirectURL := gopath.Join("/", u.Scheme, u.Host, path) - logger.Debugw("uri param, redirect", "to", redirectURL, "status", http.StatusMovedPermanently) - http.Redirect(w, r, redirectURL, http.StatusMovedPermanently) - return true - } - - return false -} - -// Disallow Service Worker registration on namespace roots -// https://github.com/ipfs/kubo/issues/4025 -func handleServiceWorkerRegistration(r *http.Request) (err *requestError) { - if r.Header.Get("Service-Worker") == "script" { - matched, _ := regexp.MatchString(`^/ip[fn]s/[^/]+$`, r.URL.Path) - if matched { - err := fmt.Errorf("registration is not allowed for this scope") - return newRequestError("navigator.serviceWorker", err, http.StatusBadRequest) - } - } - - return nil -} - -// Attempt to fix redundant /ipfs/ namespace as long as resulting -// 'intended' path is valid. This is in case gremlins were tickled -// wrong way and user ended up at /ipfs/ipfs/{cid} or /ipfs/ipns/{id} -// like in bafybeien3m7mdn6imm425vc2s22erzyhbvk5n3ofzgikkhmdkh5cuqbpbq :^)) -func handleSuperfluousNamespace(w http.ResponseWriter, r *http.Request, contentPath ipath.Path) (requestHandled bool) { - // If the path is valid, there's nothing to do - if pathErr := contentPath.IsValid(); pathErr == nil { - return false - } - - // If there's no superflous namespace, there's nothing to do - if !(strings.HasPrefix(r.URL.Path, "/ipfs/ipfs/") || strings.HasPrefix(r.URL.Path, "/ipfs/ipns/")) { - return false - } - - // Attempt to fix the superflous namespace - intendedPath := ipath.New(strings.TrimPrefix(r.URL.Path, "/ipfs")) - if err := intendedPath.IsValid(); err != nil { - webError(w, "invalid ipfs path", err, http.StatusBadRequest) - return true - } - intendedURL := intendedPath.String() - if r.URL.RawQuery != "" { - // we render HTML, so ensure query entries are properly escaped - q, _ := url.ParseQuery(r.URL.RawQuery) - intendedURL = intendedURL + "?" + q.Encode() - } - // return HTTP 400 (Bad Request) with HTML error page that: - // - points at correct canonical path via header - // - displays human-readable error - // - redirects to intendedURL after a short delay - - w.WriteHeader(http.StatusBadRequest) - if err := redirectTemplate.Execute(w, redirectTemplateData{ - RedirectURL: intendedURL, - SuggestedPath: intendedPath.String(), - ErrorMsg: fmt.Sprintf("invalid path: %q should be %q", r.URL.Path, intendedPath.String()), - }); err != nil { - webError(w, "failed to redirect when fixing superfluous namespace", err, http.StatusBadRequest) - } - - return true -} - -func (i *gatewayHandler) handleGettingFirstBlock(r *http.Request, begin time.Time, contentPath ipath.Path, resolvedPath ipath.Resolved) *requestError { - // Update the global metric of the time it takes to read the final root block of the requested resource - // NOTE: for legacy reasons this happens before we go into content-type specific code paths - _, err := i.api.Block().Get(r.Context(), resolvedPath) - if err != nil { - return newRequestError("ipfs block get "+resolvedPath.Cid().String(), err, http.StatusInternalServerError) - } - ns := contentPath.Namespace() - timeToGetFirstContentBlock := time.Since(begin).Seconds() - i.unixfsGetMetric.WithLabelValues(ns).Observe(timeToGetFirstContentBlock) // deprecated, use firstContentBlockGetMetric instead - i.firstContentBlockGetMetric.WithLabelValues(ns).Observe(timeToGetFirstContentBlock) - return nil -} - -func (i *gatewayHandler) setCommonHeaders(w http.ResponseWriter, r *http.Request, contentPath ipath.Path) *requestError { - i.addUserHeaders(w) // ok, _now_ write user's headers. - w.Header().Set("X-Ipfs-Path", contentPath.String()) - - if rootCids, err := i.buildIpfsRootsHeader(contentPath.String(), r); err == nil { - w.Header().Set("X-Ipfs-Roots", rootCids) - } else { // this should never happen, as we resolved the contentPath already - return newRequestError("error while resolving X-Ipfs-Roots", err, http.StatusInternalServerError) - } - - return nil -} diff --git a/core/corehttp/gateway_handler_block.go b/core/corehttp/gateway_handler_block.go deleted file mode 100644 index 3bf7c76be..000000000 --- a/core/corehttp/gateway_handler_block.go +++ /dev/null @@ -1,55 +0,0 @@ -package corehttp - -import ( - "bytes" - "context" - "io" - "net/http" - "time" - - ipath "github.com/ipfs/interface-go-ipfs-core/path" - "github.com/ipfs/kubo/tracing" - "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/trace" -) - -// serveRawBlock returns bytes behind a raw block -func (i *gatewayHandler) serveRawBlock(ctx context.Context, w http.ResponseWriter, r *http.Request, resolvedPath ipath.Resolved, contentPath ipath.Path, begin time.Time) { - ctx, span := tracing.Span(ctx, "Gateway", "ServeRawBlock", trace.WithAttributes(attribute.String("path", resolvedPath.String()))) - defer span.End() - blockCid := resolvedPath.Cid() - blockReader, err := i.api.Block().Get(ctx, resolvedPath) - if err != nil { - webError(w, "ipfs block get "+blockCid.String(), err, http.StatusInternalServerError) - return - } - block, err := io.ReadAll(blockReader) - if err != nil { - webError(w, "ipfs block get "+blockCid.String(), err, http.StatusInternalServerError) - return - } - content := bytes.NewReader(block) - - // Set Content-Disposition - var name string - if urlFilename := r.URL.Query().Get("filename"); urlFilename != "" { - name = urlFilename - } else { - name = blockCid.String() + ".bin" - } - setContentDispositionHeader(w, name, "attachment") - - // Set remaining headers - modtime := addCacheControlHeaders(w, r, contentPath, blockCid) - w.Header().Set("Content-Type", "application/vnd.ipld.raw") - w.Header().Set("X-Content-Type-Options", "nosniff") // no funny business in the browsers :^) - - // ServeContent will take care of - // If-None-Match+Etag, Content-Length and range requests - _, dataSent, _ := ServeContent(w, r, name, modtime, content) - - if dataSent { - // Update metrics - i.rawBlockGetMetric.WithLabelValues(contentPath.Namespace()).Observe(time.Since(begin).Seconds()) - } -} diff --git a/core/corehttp/gateway_handler_car.go b/core/corehttp/gateway_handler_car.go deleted file mode 100644 index 9f704d6ca..000000000 --- a/core/corehttp/gateway_handler_car.go +++ /dev/null @@ -1,99 +0,0 @@ -package corehttp - -import ( - "context" - "fmt" - "net/http" - "time" - - cid "github.com/ipfs/go-cid" - blocks "github.com/ipfs/go-libipfs/blocks" - coreiface "github.com/ipfs/interface-go-ipfs-core" - ipath "github.com/ipfs/interface-go-ipfs-core/path" - "github.com/ipfs/kubo/tracing" - gocar "github.com/ipld/go-car" - selectorparse "github.com/ipld/go-ipld-prime/traversal/selector/parse" - "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/trace" -) - -// serveCAR returns a CAR stream for specific DAG+selector -func (i *gatewayHandler) serveCAR(ctx context.Context, w http.ResponseWriter, r *http.Request, resolvedPath ipath.Resolved, contentPath ipath.Path, carVersion string, begin time.Time) { - ctx, span := tracing.Span(ctx, "Gateway", "ServeCAR", trace.WithAttributes(attribute.String("path", resolvedPath.String()))) - defer span.End() - ctx, cancel := context.WithCancel(ctx) - defer cancel() - - switch carVersion { - case "": // noop, client does not care about version - case "1": // noop, we support this - default: - err := fmt.Errorf("only version=1 is supported") - webError(w, "unsupported CAR version", err, http.StatusBadRequest) - return - } - rootCid := resolvedPath.Cid() - - // Set Content-Disposition - var name string - if urlFilename := r.URL.Query().Get("filename"); urlFilename != "" { - name = urlFilename - } else { - name = rootCid.String() + ".car" - } - setContentDispositionHeader(w, name, "attachment") - - // Set Cache-Control (same logic as for a regular files) - addCacheControlHeaders(w, r, contentPath, rootCid) - - // Weak Etag W/ because we can't guarantee byte-for-byte identical - // responses, but still want to benefit from HTTP Caching. Two CAR - // responses for the same CID and selector will be logically equivalent, - // but when CAR is streamed, then in theory, blocks may arrive from - // datastore in non-deterministic order. - etag := `W/` + getEtag(r, rootCid) - w.Header().Set("Etag", etag) - - // Finish early if Etag match - if r.Header.Get("If-None-Match") == etag { - w.WriteHeader(http.StatusNotModified) - return - } - - // Make it clear we don't support range-requests over a car stream - // Partial downloads and resumes should be handled using requests for - // sub-DAGs and IPLD selectors: https://github.com/ipfs/go-ipfs/issues/8769 - w.Header().Set("Accept-Ranges", "none") - - w.Header().Set("Content-Type", "application/vnd.ipld.car; version=1") - w.Header().Set("X-Content-Type-Options", "nosniff") // no funny business in the browsers :^) - - // Same go-car settings as dag.export command - store := dagStore{dag: i.api.Dag(), ctx: ctx} - - // TODO: support selectors passed as request param: https://github.com/ipfs/kubo/issues/8769 - dag := gocar.Dag{Root: rootCid, Selector: selectorparse.CommonSelector_ExploreAllRecursively} - car := gocar.NewSelectiveCar(ctx, store, []gocar.Dag{dag}, gocar.TraverseLinksOnlyOnce()) - - if err := car.Write(w); err != nil { - // We return error as a trailer, however it is not something browsers can access - // (https://github.com/mdn/browser-compat-data/issues/14703) - // Due to this, we suggest client always verify that - // the received CAR stream response is matching requested DAG selector - w.Header().Set("X-Stream-Error", err.Error()) - return - } - - // Update metrics - i.carStreamGetMetric.WithLabelValues(contentPath.Namespace()).Observe(time.Since(begin).Seconds()) -} - -// FIXME(@Jorropo): https://github.com/ipld/go-car/issues/315 -type dagStore struct { - dag coreiface.APIDagService - ctx context.Context -} - -func (ds dagStore) Get(_ context.Context, c cid.Cid) (blocks.Block, error) { - return ds.dag.Get(ds.ctx, c) -} diff --git a/core/corehttp/gateway_handler_codec.go b/core/corehttp/gateway_handler_codec.go deleted file mode 100644 index 93e9593b7..000000000 --- a/core/corehttp/gateway_handler_codec.go +++ /dev/null @@ -1,257 +0,0 @@ -package corehttp - -import ( - "bytes" - "context" - "fmt" - "html" - "io" - "net/http" - "strings" - "time" - - cid "github.com/ipfs/go-cid" - ipldlegacy "github.com/ipfs/go-ipld-legacy" - ipath "github.com/ipfs/interface-go-ipfs-core/path" - "github.com/ipfs/kubo/assets" - dih "github.com/ipfs/kubo/assets/dag-index-html" - "github.com/ipfs/kubo/tracing" - "github.com/ipld/go-ipld-prime" - "github.com/ipld/go-ipld-prime/multicodec" - mc "github.com/multiformats/go-multicodec" - "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/trace" -) - -// codecToContentType maps the supported IPLD codecs to the HTTP Content -// Type they should have. -var codecToContentType = map[mc.Code]string{ - mc.Json: "application/json", - mc.Cbor: "application/cbor", - mc.DagJson: "application/vnd.ipld.dag-json", - mc.DagCbor: "application/vnd.ipld.dag-cbor", -} - -// contentTypeToRaw maps the HTTP Content Type to the respective codec that -// allows raw response without any conversion. -var contentTypeToRaw = map[string][]mc.Code{ - "application/json": {mc.Json, mc.DagJson}, - "application/cbor": {mc.Cbor, mc.DagCbor}, -} - -// contentTypeToCodec maps the HTTP Content Type to the respective codec. We -// only add here the codecs that we want to convert-to-from. -var contentTypeToCodec = map[string]mc.Code{ - "application/vnd.ipld.dag-json": mc.DagJson, - "application/vnd.ipld.dag-cbor": mc.DagCbor, -} - -// contentTypeToExtension maps the HTTP Content Type to the respective file -// extension, used in Content-Disposition header when downloading the file. -var contentTypeToExtension = map[string]string{ - "application/json": ".json", - "application/vnd.ipld.dag-json": ".json", - "application/cbor": ".cbor", - "application/vnd.ipld.dag-cbor": ".cbor", -} - -func (i *gatewayHandler) serveCodec(ctx context.Context, w http.ResponseWriter, r *http.Request, resolvedPath ipath.Resolved, contentPath ipath.Path, begin time.Time, requestedContentType string) { - ctx, span := tracing.Span(ctx, "Gateway", "ServeCodec", trace.WithAttributes(attribute.String("path", resolvedPath.String()), attribute.String("requestedContentType", requestedContentType))) - defer span.End() - - cidCodec := mc.Code(resolvedPath.Cid().Prefix().Codec) - responseContentType := requestedContentType - - // If the resolved path still has some remainder, return error for now. - // TODO: handle this when we have IPLD Patch (https://ipld.io/specs/patch/) via HTTP PUT - // TODO: (depends on https://github.com/ipfs/kubo/issues/4801 and https://github.com/ipfs/kubo/issues/4782) - if resolvedPath.Remainder() != "" { - path := strings.TrimSuffix(resolvedPath.String(), resolvedPath.Remainder()) - err := fmt.Errorf("%q of %q could not be returned: reading IPLD Kinds other than Links (CBOR Tag 42) is not implemented: try reading %q instead", resolvedPath.Remainder(), resolvedPath.String(), path) - webError(w, "unsupported pathing", err, http.StatusNotImplemented) - return - } - - // If no explicit content type was requested, the response will have one based on the codec from the CID - if requestedContentType == "" { - cidContentType, ok := codecToContentType[cidCodec] - if !ok { - // Should not happen unless function is called with wrong parameters. - err := fmt.Errorf("content type not found for codec: %v", cidCodec) - webError(w, "internal error", err, http.StatusInternalServerError) - return - } - responseContentType = cidContentType - } - - // Set HTTP headers (for caching etc) - modtime := addCacheControlHeaders(w, r, contentPath, resolvedPath.Cid()) - name := setCodecContentDisposition(w, r, resolvedPath, responseContentType) - w.Header().Set("Content-Type", responseContentType) - w.Header().Set("X-Content-Type-Options", "nosniff") - - // No content type is specified by the user (via Accept, or format=). However, - // we support this format. Let's handle it. - if requestedContentType == "" { - isDAG := cidCodec == mc.DagJson || cidCodec == mc.DagCbor - acceptsHTML := strings.Contains(r.Header.Get("Accept"), "text/html") - download := r.URL.Query().Get("download") == "true" - - if isDAG && acceptsHTML && !download { - i.serveCodecHTML(ctx, w, r, resolvedPath, contentPath) - } else { - // This covers CIDs with codec 'json' and 'cbor' as those do not have - // an explicit requested content type. - i.serveCodecRaw(ctx, w, r, resolvedPath, contentPath, name, modtime) - } - - return - } - - // If DAG-JSON or DAG-CBOR was requested using corresponding plain content type - // return raw block as-is, without conversion - skipCodecs, ok := contentTypeToRaw[requestedContentType] - if ok { - for _, skipCodec := range skipCodecs { - if skipCodec == cidCodec { - i.serveCodecRaw(ctx, w, r, resolvedPath, contentPath, name, modtime) - return - } - } - } - - // Otherwise, the user has requested a specific content type (a DAG-* variant). - // Let's first get the codecs that can be used with this content type. - toCodec, ok := contentTypeToCodec[requestedContentType] - if !ok { - // This is never supposed to happen unless function is called with wrong parameters. - err := fmt.Errorf("unsupported content type: %s", requestedContentType) - webError(w, err.Error(), err, http.StatusInternalServerError) - return - } - - // This handles DAG-* conversions and validations. - i.serveCodecConverted(ctx, w, r, resolvedPath, contentPath, toCodec, modtime) -} - -func (i *gatewayHandler) serveCodecHTML(ctx context.Context, w http.ResponseWriter, r *http.Request, resolvedPath ipath.Resolved, contentPath ipath.Path) { - // A HTML directory index will be presented, be sure to set the correct - // type instead of relying on autodetection (which may fail). - w.Header().Set("Content-Type", "text/html") - - // Clear Content-Disposition -- we want HTML to be rendered inline - w.Header().Del("Content-Disposition") - - // Generated index requires custom Etag (output may change between Kubo versions) - dagEtag := getDagIndexEtag(resolvedPath.Cid()) - w.Header().Set("Etag", dagEtag) - - // Remove Cache-Control for now to match UnixFS dir-index-html responses - // (we don't want browser to cache HTML forever) - // TODO: if we ever change behavior for UnixFS dir listings, same changes should be applied here - w.Header().Del("Cache-Control") - - cidCodec := mc.Code(resolvedPath.Cid().Prefix().Codec) - if err := dih.DagIndexTemplate.Execute(w, dih.DagIndexTemplateData{ - Path: contentPath.String(), - CID: resolvedPath.Cid().String(), - CodecName: cidCodec.String(), - CodecHex: fmt.Sprintf("0x%x", uint64(cidCodec)), - }); err != nil { - webError(w, "failed to generate HTML listing for this DAG: try fetching raw block with ?format=raw", err, http.StatusInternalServerError) - } -} - -// serveCodecRaw returns the raw block without any conversion -func (i *gatewayHandler) serveCodecRaw(ctx context.Context, w http.ResponseWriter, r *http.Request, resolvedPath ipath.Resolved, contentPath ipath.Path, name string, modtime time.Time) { - blockCid := resolvedPath.Cid() - blockReader, err := i.api.Block().Get(ctx, resolvedPath) - if err != nil { - webError(w, "ipfs block get "+blockCid.String(), err, http.StatusInternalServerError) - return - } - block, err := io.ReadAll(blockReader) - if err != nil { - webError(w, "ipfs block get "+blockCid.String(), err, http.StatusInternalServerError) - return - } - content := bytes.NewReader(block) - - // ServeContent will take care of - // If-None-Match+Etag, Content-Length and range requests - _, _, _ = ServeContent(w, r, name, modtime, content) -} - -// serveCodecConverted returns payload converted to codec specified in toCodec -func (i *gatewayHandler) serveCodecConverted(ctx context.Context, w http.ResponseWriter, r *http.Request, resolvedPath ipath.Resolved, contentPath ipath.Path, toCodec mc.Code, modtime time.Time) { - obj, err := i.api.Dag().Get(ctx, resolvedPath.Cid()) - if err != nil { - webError(w, "ipfs dag get "+html.EscapeString(resolvedPath.String()), err, http.StatusInternalServerError) - return - } - - universal, ok := obj.(ipldlegacy.UniversalNode) - if !ok { - err = fmt.Errorf("%T is not a valid IPLD node", obj) - webError(w, err.Error(), err, http.StatusInternalServerError) - return - } - finalNode := universal.(ipld.Node) - - encoder, err := multicodec.LookupEncoder(uint64(toCodec)) - if err != nil { - webError(w, err.Error(), err, http.StatusInternalServerError) - return - } - - // Ensure IPLD node conforms to the codec specification. - var buf bytes.Buffer - err = encoder(finalNode, &buf) - if err != nil { - webError(w, err.Error(), err, http.StatusInternalServerError) - return - } - - // Sets correct Last-Modified header. This code is borrowed from the standard - // library (net/http/server.go) as we cannot use serveFile. - if !(modtime.IsZero() || modtime.Equal(unixEpochTime)) { - w.Header().Set("Last-Modified", modtime.UTC().Format(http.TimeFormat)) - } - - _, _ = w.Write(buf.Bytes()) -} - -func setCodecContentDisposition(w http.ResponseWriter, r *http.Request, resolvedPath ipath.Resolved, contentType string) string { - var dispType, name string - - ext, ok := contentTypeToExtension[contentType] - if !ok { - // Should never happen. - ext = ".bin" - } - - if urlFilename := r.URL.Query().Get("filename"); urlFilename != "" { - name = urlFilename - } else { - name = resolvedPath.Cid().String() + ext - } - - // JSON should be inlined, but ?download=true should still override - if r.URL.Query().Get("download") == "true" { - dispType = "attachment" - } else { - switch ext { - case ".json": // codecs that serialize to JSON can be rendered by browsers - dispType = "inline" - default: // everything else is assumed binary / opaque bytes - dispType = "attachment" - } - } - - setContentDispositionHeader(w, name, dispType) - return name -} - -func getDagIndexEtag(dagCid cid.Cid) string { - return `"DagIndex-` + assets.AssetHash + `_CID-` + dagCid.String() + `"` -} diff --git a/core/corehttp/gateway_handler_ipns_record.go b/core/corehttp/gateway_handler_ipns_record.go deleted file mode 100644 index 16d9663fa..000000000 --- a/core/corehttp/gateway_handler_ipns_record.go +++ /dev/null @@ -1,71 +0,0 @@ -package corehttp - -import ( - "context" - "errors" - "fmt" - "net/http" - "strings" - "time" - - "github.com/gogo/protobuf/proto" - ipns_pb "github.com/ipfs/go-ipns/pb" - path "github.com/ipfs/go-path" - ipath "github.com/ipfs/interface-go-ipfs-core/path" - "go.uber.org/zap" -) - -func (i *gatewayHandler) serveIpnsRecord(ctx context.Context, w http.ResponseWriter, r *http.Request, resolvedPath ipath.Resolved, contentPath ipath.Path, begin time.Time, logger *zap.SugaredLogger) { - if contentPath.Namespace() != "ipns" { - err := fmt.Errorf("%s is not an IPNS link", contentPath.String()) - webError(w, err.Error(), err, http.StatusBadRequest) - return - } - - key := contentPath.String() - key = strings.TrimSuffix(key, "/") - if strings.Count(key, "/") > 2 { - err := errors.New("cannot find ipns key for subpath") - webError(w, err.Error(), err, http.StatusBadRequest) - return - } - - rawRecord, err := i.api.Routing().Get(ctx, key) - if err != nil { - webError(w, err.Error(), err, http.StatusInternalServerError) - return - } - - var record ipns_pb.IpnsEntry - err = proto.Unmarshal(rawRecord, &record) - if err != nil { - webError(w, err.Error(), err, http.StatusInternalServerError) - return - } - - // Set cache control headers based on the TTL set in the IPNS record. If the - // TTL is not present, we use the Last-Modified tag. We are tracking IPNS - // caching on: https://github.com/ipfs/kubo/issues/1818. - // TODO: use addCacheControlHeaders once #1818 is fixed. - w.Header().Set("Etag", getEtag(r, resolvedPath.Cid())) - if record.Ttl != nil { - seconds := int(time.Duration(*record.Ttl).Seconds()) - w.Header().Set("Cache-Control", fmt.Sprintf("public, max-age=%d", seconds)) - } else { - w.Header().Set("Last-Modified", time.Now().UTC().Format(http.TimeFormat)) - } - - // Set Content-Disposition - var name string - if urlFilename := r.URL.Query().Get("filename"); urlFilename != "" { - name = urlFilename - } else { - name = path.SplitList(key)[2] + ".ipns-record" - } - setContentDispositionHeader(w, name, "attachment") - - w.Header().Set("Content-Type", "application/vnd.ipfs.ipns-record") - w.Header().Set("X-Content-Type-Options", "nosniff") - - _, _ = w.Write(rawRecord) -} diff --git a/core/corehttp/gateway_handler_tar.go b/core/corehttp/gateway_handler_tar.go deleted file mode 100644 index 14edf4fbf..000000000 --- a/core/corehttp/gateway_handler_tar.go +++ /dev/null @@ -1,92 +0,0 @@ -package corehttp - -import ( - "context" - "html" - "net/http" - "time" - - "github.com/ipfs/go-libipfs/files" - ipath "github.com/ipfs/interface-go-ipfs-core/path" - "github.com/ipfs/kubo/tracing" - "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/trace" - "go.uber.org/zap" -) - -var unixEpochTime = time.Unix(0, 0) - -func (i *gatewayHandler) serveTAR(ctx context.Context, w http.ResponseWriter, r *http.Request, resolvedPath ipath.Resolved, contentPath ipath.Path, begin time.Time, logger *zap.SugaredLogger) { - ctx, span := tracing.Span(ctx, "Gateway", "ServeTAR", trace.WithAttributes(attribute.String("path", resolvedPath.String()))) - defer span.End() - - ctx, cancel := context.WithCancel(ctx) - defer cancel() - - // Get Unixfs file - file, err := i.api.Unixfs().Get(ctx, resolvedPath) - if err != nil { - webError(w, "ipfs cat "+html.EscapeString(contentPath.String()), err, http.StatusBadRequest) - return - } - defer file.Close() - - rootCid := resolvedPath.Cid() - - // Set Cache-Control and read optional Last-Modified time - modtime := addCacheControlHeaders(w, r, contentPath, rootCid) - - // Weak Etag W/ because we can't guarantee byte-for-byte identical - // responses, but still want to benefit from HTTP Caching. Two TAR - // responses for the same CID will be logically equivalent, - // but when TAR is streamed, then in theory, files and directories - // may arrive in different order (depends on TAR lib and filesystem/inodes). - etag := `W/` + getEtag(r, rootCid) - w.Header().Set("Etag", etag) - - // Finish early if Etag match - if r.Header.Get("If-None-Match") == etag { - w.WriteHeader(http.StatusNotModified) - return - } - - // Set Content-Disposition - var name string - if urlFilename := r.URL.Query().Get("filename"); urlFilename != "" { - name = urlFilename - } else { - name = rootCid.String() + ".tar" - } - setContentDispositionHeader(w, name, "attachment") - - // Construct the TAR writer - tarw, err := files.NewTarWriter(w) - if err != nil { - webError(w, "could not build tar writer", err, http.StatusInternalServerError) - return - } - defer tarw.Close() - - // Sets correct Last-Modified header. This code is borrowed from the standard - // library (net/http/server.go) as we cannot use serveFile without throwing the entire - // TAR into the memory first. - if !(modtime.IsZero() || modtime.Equal(unixEpochTime)) { - w.Header().Set("Last-Modified", modtime.UTC().Format(http.TimeFormat)) - } - - w.Header().Set("Content-Type", "application/x-tar") - w.Header().Set("X-Content-Type-Options", "nosniff") // no funny business in the browsers :^) - - // The TAR has a top-level directory (or file) named by the CID. - if err := tarw.WriteFile(file, rootCid.String()); err != nil { - w.Header().Set("X-Stream-Error", err.Error()) - // Trailer headers do not work in web browsers - // (see https://github.com/mdn/browser-compat-data/issues/14703) - // and we have limited options around error handling in browser contexts. - // To improve UX/DX, we finish response stream with error message, allowing client to - // (1) detect error by having corrupted TAR - // (2) be able to reason what went wrong by instecting the tail of TAR stream - _, _ = w.Write([]byte(err.Error())) - return - } -} diff --git a/core/corehttp/gateway_handler_unixfs.go b/core/corehttp/gateway_handler_unixfs.go deleted file mode 100644 index 045c0f81d..000000000 --- a/core/corehttp/gateway_handler_unixfs.go +++ /dev/null @@ -1,46 +0,0 @@ -package corehttp - -import ( - "context" - "fmt" - "html" - "net/http" - "time" - - "github.com/ipfs/go-libipfs/files" - ipath "github.com/ipfs/interface-go-ipfs-core/path" - "github.com/ipfs/kubo/tracing" - "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/trace" - "go.uber.org/zap" -) - -func (i *gatewayHandler) serveUnixFS(ctx context.Context, w http.ResponseWriter, r *http.Request, resolvedPath ipath.Resolved, contentPath ipath.Path, begin time.Time, logger *zap.SugaredLogger) { - ctx, span := tracing.Span(ctx, "Gateway", "ServeUnixFS", trace.WithAttributes(attribute.String("path", resolvedPath.String()))) - defer span.End() - - // Handling UnixFS - dr, err := i.api.Unixfs().Get(ctx, resolvedPath) - if err != nil { - webError(w, "ipfs cat "+html.EscapeString(contentPath.String()), err, http.StatusBadRequest) - return - } - defer dr.Close() - - // Handling Unixfs file - if f, ok := dr.(files.File); ok { - logger.Debugw("serving unixfs file", "path", contentPath) - i.serveFile(ctx, w, r, resolvedPath, contentPath, f, begin) - return - } - - // Handling Unixfs directory - dir, ok := dr.(files.Directory) - if !ok { - internalWebError(w, fmt.Errorf("unsupported UnixFS type")) - return - } - - logger.Debugw("serving unixfs directory", "path", contentPath) - i.serveDirectory(ctx, w, r, resolvedPath, contentPath, dir, begin, logger) -} diff --git a/core/corehttp/gateway_handler_unixfs__redirects.go b/core/corehttp/gateway_handler_unixfs__redirects.go deleted file mode 100644 index 6906683a6..000000000 --- a/core/corehttp/gateway_handler_unixfs__redirects.go +++ /dev/null @@ -1,287 +0,0 @@ -package corehttp - -import ( - "fmt" - "io" - "net/http" - gopath "path" - "strconv" - "strings" - - redirects "github.com/ipfs/go-ipfs-redirects-file" - "github.com/ipfs/go-libipfs/files" - ipath "github.com/ipfs/interface-go-ipfs-core/path" - "go.uber.org/zap" -) - -// Resolving a UnixFS path involves determining if the provided `path.Path` exists and returning the `path.Resolved` -// corresponding to that path. For UnixFS, path resolution is more involved. -// -// When a path under requested CID does not exist, Gateway will check if a `_redirects` file exists -// underneath the root CID of the path, and apply rules defined there. -// See sepcification introduced in: https://github.com/ipfs/specs/pull/290 -// -// Scenario 1: -// If a path exists, we always return the `path.Resolved` corresponding to that path, regardless of the existence of a `_redirects` file. -// -// Scenario 2: -// If a path does not exist, usually we should return a `nil` resolution path and an error indicating that the path -// doesn't exist. However, a `_redirects` file may exist and contain a redirect rule that redirects that path to a different path. -// We need to evaluate the rule and perform the redirect if present. -// -// Scenario 3: -// Another possibility is that the path corresponds to a rewrite rule (i.e. a rule with a status of 200). -// In this case, we don't perform a redirect, but do need to return a `path.Resolved` and `path.Path` corresponding to -// the rewrite destination path. -// -// Note that for security reasons, redirect rules are only processed when the request has origin isolation. -// See https://github.com/ipfs/specs/pull/290 for more information. -func (i *gatewayHandler) serveRedirectsIfPresent(w http.ResponseWriter, r *http.Request, resolvedPath ipath.Resolved, contentPath ipath.Path, logger *zap.SugaredLogger) (newResolvedPath ipath.Resolved, newContentPath ipath.Path, continueProcessing bool, hadMatchingRule bool) { - redirectsFile := i.getRedirectsFile(r, contentPath, logger) - if redirectsFile != nil { - redirectRules, err := i.getRedirectRules(r, redirectsFile) - if err != nil { - internalWebError(w, err) - return nil, nil, false, true - } - - redirected, newPath, err := i.handleRedirectsFileRules(w, r, contentPath, redirectRules) - if err != nil { - err = fmt.Errorf("trouble processing _redirects file at %q: %w", redirectsFile.String(), err) - internalWebError(w, err) - return nil, nil, false, true - } - - if redirected { - return nil, nil, false, true - } - - // 200 is treated as a rewrite, so update the path and continue - if newPath != "" { - // Reassign contentPath and resolvedPath since the URL was rewritten - contentPath = ipath.New(newPath) - resolvedPath, err = i.api.ResolvePath(r.Context(), contentPath) - if err != nil { - internalWebError(w, err) - return nil, nil, false, true - } - - return resolvedPath, contentPath, true, true - } - } - // No matching rule, paths remain the same, continue regular processing - return resolvedPath, contentPath, true, false -} - -func (i *gatewayHandler) handleRedirectsFileRules(w http.ResponseWriter, r *http.Request, contentPath ipath.Path, redirectRules []redirects.Rule) (redirected bool, newContentPath string, err error) { - // Attempt to match a rule to the URL path, and perform the corresponding redirect or rewrite - pathParts := strings.Split(contentPath.String(), "/") - if len(pathParts) > 3 { - // All paths should start with /ipfs/cid/, so get the path after that - urlPath := "/" + strings.Join(pathParts[3:], "/") - rootPath := strings.Join(pathParts[:3], "/") - // Trim off the trailing / - urlPath = strings.TrimSuffix(urlPath, "/") - - for _, rule := range redirectRules { - // Error right away if the rule is invalid - if !rule.MatchAndExpandPlaceholders(urlPath) { - continue - } - - // We have a match! - - // Rewrite - if rule.Status == 200 { - // Prepend the rootPath - toPath := rootPath + rule.To - return false, toPath, nil - } - - // Or 4xx - if rule.Status == 404 || rule.Status == 410 || rule.Status == 451 { - toPath := rootPath + rule.To - content4xxPath := ipath.New(toPath) - err := i.serve4xx(w, r, content4xxPath, rule.Status) - return true, toPath, err - } - - // Or redirect - if rule.Status >= 301 && rule.Status <= 308 { - http.Redirect(w, r, rule.To, rule.Status) - return true, "", nil - } - } - } - - // No redirects matched - return false, "", nil -} - -func (i *gatewayHandler) getRedirectRules(r *http.Request, redirectsFilePath ipath.Resolved) ([]redirects.Rule, error) { - // Convert the path into a file node - node, err := i.api.Unixfs().Get(r.Context(), redirectsFilePath) - if err != nil { - return nil, fmt.Errorf("could not get _redirects: %w", err) - } - defer node.Close() - - // Convert the node into a file - f, ok := node.(files.File) - if !ok { - return nil, fmt.Errorf("could not parse _redirects: %w", err) - } - - // Parse redirect rules from file - redirectRules, err := redirects.Parse(f) - if err != nil { - return nil, fmt.Errorf("could not parse _redirects: %w", err) - } - - return redirectRules, nil -} - -// Returns a resolved path to the _redirects file located in the root CID path of the requested path -func (i *gatewayHandler) getRedirectsFile(r *http.Request, contentPath ipath.Path, logger *zap.SugaredLogger) ipath.Resolved { - // contentPath is the full ipfs path to the requested resource, - // regardless of whether path or subdomain resolution is used. - rootPath := getRootPath(contentPath) - - // Check for _redirects file. - // Any path resolution failures are ignored and we just assume there's no _redirects file. - // Note that ignoring these errors also ensures that the use of the empty CID (bafkqaaa) in tests doesn't fail. - path := ipath.Join(rootPath, "_redirects") - resolvedPath, err := i.api.ResolvePath(r.Context(), path) - if err != nil { - return nil - } - return resolvedPath -} - -// Returns the root CID Path for the given path -func getRootPath(path ipath.Path) ipath.Path { - parts := strings.Split(path.String(), "/") - return ipath.New(gopath.Join("/", path.Namespace(), parts[2])) -} - -func (i *gatewayHandler) serve4xx(w http.ResponseWriter, r *http.Request, content4xxPath ipath.Path, status int) error { - resolved4xxPath, err := i.api.ResolvePath(r.Context(), content4xxPath) - if err != nil { - return err - } - - node, err := i.api.Unixfs().Get(r.Context(), resolved4xxPath) - if err != nil { - return err - } - defer node.Close() - - f, ok := node.(files.File) - if !ok { - return fmt.Errorf("could not convert node for %d page to file", status) - } - - size, err := f.Size() - if err != nil { - return fmt.Errorf("could not get size of %d page", status) - } - - log.Debugf("using _redirects: custom %d file at %q", status, content4xxPath) - w.Header().Set("Content-Type", "text/html") - w.Header().Set("Content-Length", strconv.FormatInt(size, 10)) - addCacheControlHeaders(w, r, content4xxPath, resolved4xxPath.Cid()) - w.WriteHeader(status) - _, err = io.CopyN(w, f, size) - return err -} - -func hasOriginIsolation(r *http.Request) bool { - _, gw := r.Context().Value(requestContextKey("gw-hostname")).(string) - _, dnslink := r.Context().Value("dnslink-hostname").(string) - - if gw || dnslink { - return true - } - - return false -} - -func isUnixfsResponseFormat(responseFormat string) bool { - // The implicit response format is UnixFS - return responseFormat == "" -} - -// Deprecated: legacy ipfs-404.html files are superseded by _redirects file -// This is provided only for backward-compatibility, until websites migrate -// to 404s managed via _redirects file (https://github.com/ipfs/specs/pull/290) -func (i *gatewayHandler) serveLegacy404IfPresent(w http.ResponseWriter, r *http.Request, contentPath ipath.Path) bool { - resolved404Path, ctype, err := i.searchUpTreeFor404(r, contentPath) - if err != nil { - return false - } - - dr, err := i.api.Unixfs().Get(r.Context(), resolved404Path) - if err != nil { - return false - } - defer dr.Close() - - f, ok := dr.(files.File) - if !ok { - return false - } - - size, err := f.Size() - if err != nil { - return false - } - - log.Debugw("using pretty 404 file", "path", contentPath) - w.Header().Set("Content-Type", ctype) - w.Header().Set("Content-Length", strconv.FormatInt(size, 10)) - w.WriteHeader(http.StatusNotFound) - _, err = io.CopyN(w, f, size) - return err == nil -} - -func (i *gatewayHandler) searchUpTreeFor404(r *http.Request, contentPath ipath.Path) (ipath.Resolved, string, error) { - filename404, ctype, err := preferred404Filename(r.Header.Values("Accept")) - if err != nil { - return nil, "", err - } - - pathComponents := strings.Split(contentPath.String(), "/") - - for idx := len(pathComponents); idx >= 3; idx-- { - pretty404 := gopath.Join(append(pathComponents[0:idx], filename404)...) - parsed404Path := ipath.New("/" + pretty404) - if parsed404Path.IsValid() != nil { - break - } - resolvedPath, err := i.api.ResolvePath(r.Context(), parsed404Path) - if err != nil { - continue - } - return resolvedPath, ctype, nil - } - - return nil, "", fmt.Errorf("no pretty 404 in any parent folder") -} - -func preferred404Filename(acceptHeaders []string) (string, string, error) { - // If we ever want to offer a 404 file for a different content type - // then this function will need to parse q weightings, but for now - // the presence of anything matching HTML is enough. - for _, acceptHeader := range acceptHeaders { - accepted := strings.Split(acceptHeader, ",") - for _, spec := range accepted { - contentType := strings.SplitN(spec, ";", 1)[0] - switch contentType { - case "*/*", "text/*", "text/html": - return "ipfs-404.html", "text/html", nil - } - } - } - - return "", "", fmt.Errorf("there is no 404 file for the requested content types") -} diff --git a/core/corehttp/gateway_handler_unixfs_dir.go b/core/corehttp/gateway_handler_unixfs_dir.go deleted file mode 100644 index 03d67e1c0..000000000 --- a/core/corehttp/gateway_handler_unixfs_dir.go +++ /dev/null @@ -1,210 +0,0 @@ -package corehttp - -import ( - "context" - "net/http" - "net/url" - gopath "path" - "strings" - "time" - - "github.com/dustin/go-humanize" - cid "github.com/ipfs/go-cid" - "github.com/ipfs/go-libipfs/files" - path "github.com/ipfs/go-path" - "github.com/ipfs/go-path/resolver" - options "github.com/ipfs/interface-go-ipfs-core/options" - ipath "github.com/ipfs/interface-go-ipfs-core/path" - "github.com/ipfs/kubo/assets" - "github.com/ipfs/kubo/tracing" - "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/trace" - "go.uber.org/zap" -) - -// serveDirectory returns the best representation of UnixFS directory -// -// It will return index.html if present, or generate directory listing otherwise. -func (i *gatewayHandler) serveDirectory(ctx context.Context, w http.ResponseWriter, r *http.Request, resolvedPath ipath.Resolved, contentPath ipath.Path, dir files.Directory, begin time.Time, logger *zap.SugaredLogger) { - ctx, span := tracing.Span(ctx, "Gateway", "ServeDirectory", trace.WithAttributes(attribute.String("path", resolvedPath.String()))) - defer span.End() - - // HostnameOption might have constructed an IPNS/IPFS path using the Host header. - // In this case, we need the original path for constructing redirects - // and links that match the requested URL. - // For example, http://example.net would become /ipns/example.net, and - // the redirects and links would end up as http://example.net/ipns/example.net - requestURI, err := url.ParseRequestURI(r.RequestURI) - if err != nil { - webError(w, "failed to parse request path", err, http.StatusInternalServerError) - return - } - originalURLPath := requestURI.Path - - // Ensure directory paths end with '/' - if originalURLPath[len(originalURLPath)-1] != '/' { - // don't redirect to trailing slash if it's go get - // https://github.com/ipfs/kubo/pull/3963 - goget := r.URL.Query().Get("go-get") == "1" - if !goget { - suffix := "/" - // preserve query parameters - if r.URL.RawQuery != "" { - suffix = suffix + "?" + r.URL.RawQuery - } - // /ipfs/cid/foo?bar must be redirected to /ipfs/cid/foo/?bar - redirectURL := originalURLPath + suffix - logger.Debugw("directory location moved permanently", "status", http.StatusMovedPermanently) - http.Redirect(w, r, redirectURL, http.StatusMovedPermanently) - return - } - } - - // Check if directory has index.html, if so, serveFile - idxPath := ipath.Join(contentPath, "index.html") - idx, err := i.api.Unixfs().Get(ctx, idxPath) - switch err.(type) { - case nil: - f, ok := idx.(files.File) - if !ok { - internalWebError(w, files.ErrNotReader) - return - } - - logger.Debugw("serving index.html file", "path", idxPath) - // write to request - i.serveFile(ctx, w, r, resolvedPath, idxPath, f, begin) - return - case resolver.ErrNoLink: - logger.Debugw("no index.html; noop", "path", idxPath) - default: - internalWebError(w, err) - return - } - - // See statusResponseWriter.WriteHeader - // and https://github.com/ipfs/kubo/issues/7164 - // Note: this needs to occur before listingTemplate.Execute otherwise we get - // superfluous response.WriteHeader call from prometheus/client_golang - if w.Header().Get("Location") != "" { - logger.Debugw("location moved permanently", "status", http.StatusMovedPermanently) - w.WriteHeader(http.StatusMovedPermanently) - return - } - - // A HTML directory index will be presented, be sure to set the correct - // type instead of relying on autodetection (which may fail). - w.Header().Set("Content-Type", "text/html") - - // Generated dir index requires custom Etag (output may change between go-ipfs versions) - dirEtag := getDirListingEtag(resolvedPath.Cid()) - w.Header().Set("Etag", dirEtag) - - if r.Method == http.MethodHead { - logger.Debug("return as request's HTTP method is HEAD") - return - } - - // Optimization: use Unixfs.Ls without resolving children, but using the - // cumulative DAG size as the file size. This allows for a fast listing - // while keeping a good enough Size field. - results, err := i.api.Unixfs().Ls(ctx, - resolvedPath, - options.Unixfs.ResolveChildren(false), - options.Unixfs.UseCumulativeSize(true), - ) - if err != nil { - internalWebError(w, err) - return - } - - dirListing := make([]directoryItem, 0, len(results)) - for link := range results { - if link.Err != nil { - internalWebError(w, err) - return - } - - hash := link.Cid.String() - di := directoryItem{ - Size: humanize.Bytes(uint64(link.Size)), - Name: link.Name, - Path: gopath.Join(originalURLPath, link.Name), - Hash: hash, - ShortHash: shortHash(hash), - } - dirListing = append(dirListing, di) - } - - // construct the correct back link - // https://github.com/ipfs/kubo/issues/1365 - backLink := originalURLPath - - // don't go further up than /ipfs/$hash/ - pathSplit := path.SplitList(contentPath.String()) - switch { - // skip backlink when listing a content root - case len(pathSplit) == 3: // url: /ipfs/$hash - backLink = "" - - // skip backlink when listing a content root - case len(pathSplit) == 4 && pathSplit[3] == "": // url: /ipfs/$hash/ - backLink = "" - - // add the correct link depending on whether the path ends with a slash - default: - if strings.HasSuffix(backLink, "/") { - backLink += ".." - } else { - backLink += "/.." - } - } - - size := "?" - if s, err := dir.Size(); err == nil { - // Size may not be defined/supported. Continue anyways. - size = humanize.Bytes(uint64(s)) - } - - hash := resolvedPath.Cid().String() - - // Gateway root URL to be used when linking to other rootIDs. - // This will be blank unless subdomain or DNSLink resolution is being used - // for this request. - var gwURL string - - // Get gateway hostname and build gateway URL. - if h, ok := r.Context().Value(requestContextKey("gw-hostname")).(string); ok { - gwURL = "//" + h - } else { - gwURL = "" - } - - dnslink := hasDNSLinkOrigin(gwURL, contentPath.String()) - - // See comment above where originalUrlPath is declared. - tplData := listingTemplateData{ - GatewayURL: gwURL, - DNSLink: dnslink, - Listing: dirListing, - Size: size, - Path: contentPath.String(), - Breadcrumbs: breadcrumbs(contentPath.String(), dnslink), - BackLink: backLink, - Hash: hash, - } - - logger.Debugw("request processed", "tplDataDNSLink", dnslink, "tplDataSize", size, "tplDataBackLink", backLink, "tplDataHash", hash) - - if err := listingTemplate.Execute(w, tplData); err != nil { - internalWebError(w, err) - return - } - - // Update metrics - i.unixfsGenDirGetMetric.WithLabelValues(contentPath.Namespace()).Observe(time.Since(begin).Seconds()) -} - -func getDirListingEtag(dirCid cid.Cid) string { - return `"DirIndex-` + assets.AssetHash + `_CID-` + dirCid.String() + `"` -} diff --git a/core/corehttp/gateway_handler_unixfs_file.go b/core/corehttp/gateway_handler_unixfs_file.go deleted file mode 100644 index 1abdc823e..000000000 --- a/core/corehttp/gateway_handler_unixfs_file.go +++ /dev/null @@ -1,104 +0,0 @@ -package corehttp - -import ( - "context" - "fmt" - "io" - "mime" - "net/http" - gopath "path" - "strings" - "time" - - "github.com/gabriel-vasile/mimetype" - "github.com/ipfs/go-libipfs/files" - ipath "github.com/ipfs/interface-go-ipfs-core/path" - "github.com/ipfs/kubo/tracing" - "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/trace" -) - -// serveFile returns data behind a file along with HTTP headers based on -// the file itself, its CID and the contentPath used for accessing it. -func (i *gatewayHandler) serveFile(ctx context.Context, w http.ResponseWriter, r *http.Request, resolvedPath ipath.Resolved, contentPath ipath.Path, file files.File, begin time.Time) { - _, span := tracing.Span(ctx, "Gateway", "ServeFile", trace.WithAttributes(attribute.String("path", resolvedPath.String()))) - defer span.End() - - // Set Cache-Control and read optional Last-Modified time - modtime := addCacheControlHeaders(w, r, contentPath, resolvedPath.Cid()) - - // Set Content-Disposition - name := addContentDispositionHeader(w, r, contentPath) - - // Prepare size value for Content-Length HTTP header (set inside of http.ServeContent) - size, err := file.Size() - if err != nil { - http.Error(w, "cannot serve files with unknown sizes", http.StatusBadGateway) - return - } - - if size == 0 { - // We override null files to 200 to avoid issues with fragment caching reverse proxies. - // Also whatever you are asking for, it's cheaper to just give you the complete file (nothing). - // TODO: remove this if clause once https://github.com/golang/go/issues/54794 is fixed in two latest releases of go - w.Header().Set("Content-Type", "text/plain") - w.WriteHeader(http.StatusOK) - return - } - - // Lazy seeker enables efficient range-requests and HTTP HEAD responses - content := &lazySeeker{ - size: size, - reader: file, - } - - // Calculate deterministic value for Content-Type HTTP header - // (we prefer to do it here, rather than using implicit sniffing in http.ServeContent) - var ctype string - if _, isSymlink := file.(*files.Symlink); isSymlink { - // We should be smarter about resolving symlinks but this is the - // "most correct" we can be without doing that. - ctype = "inode/symlink" - } else { - ctype = mime.TypeByExtension(gopath.Ext(name)) - if ctype == "" { - // uses https://github.com/gabriel-vasile/mimetype library to determine the content type. - // Fixes https://github.com/ipfs/kubo/issues/7252 - mimeType, err := mimetype.DetectReader(content) - if err != nil { - http.Error(w, fmt.Sprintf("cannot detect content-type: %s", err.Error()), http.StatusInternalServerError) - return - } - - ctype = mimeType.String() - _, err = content.Seek(0, io.SeekStart) - if err != nil { - http.Error(w, "seeker can't seek", http.StatusInternalServerError) - return - } - } - // Strip the encoding from the HTML Content-Type header and let the - // browser figure it out. - // - // Fixes https://github.com/ipfs/kubo/issues/2203 - if strings.HasPrefix(ctype, "text/html;") { - ctype = "text/html" - } - } - // Setting explicit Content-Type to avoid mime-type sniffing on the client - // (unifies behavior across gateways and web browsers) - w.Header().Set("Content-Type", ctype) - - // special fixup around redirects - w = &statusResponseWriter{w} - - // ServeContent will take care of - // If-None-Match+Etag, Content-Length and range requests - _, dataSent, _ := ServeContent(w, r, name, modtime, content) - - // Was response successful? - if dataSent { - // Update metrics - i.unixfsFileGetMetric.WithLabelValues(contentPath.Namespace()).Observe(time.Since(begin).Seconds()) - } -} diff --git a/core/corehttp/gateway_indexPage.go b/core/corehttp/gateway_indexPage.go deleted file mode 100644 index b0db8ac1a..000000000 --- a/core/corehttp/gateway_indexPage.go +++ /dev/null @@ -1,133 +0,0 @@ -package corehttp - -import ( - "html/template" - "net/url" - "path" - "strings" - - ipfspath "github.com/ipfs/go-path" - "github.com/ipfs/kubo/assets" -) - -// structs for directory listing -type listingTemplateData struct { - GatewayURL string - DNSLink bool - Listing []directoryItem - Size string - Path string - Breadcrumbs []breadcrumb - BackLink string - Hash string -} - -type directoryItem struct { - Size string - Name string - Path string - Hash string - ShortHash string -} - -type breadcrumb struct { - Name string - Path string -} - -func breadcrumbs(urlPath string, dnslinkOrigin bool) []breadcrumb { - var ret []breadcrumb - - p, err := ipfspath.ParsePath(urlPath) - if err != nil { - // No breadcrumbs, fallback to bare Path in template - return ret - } - segs := p.Segments() - contentRoot := segs[1] - for i, seg := range segs { - if i == 0 { - ret = append(ret, breadcrumb{Name: seg}) - } else { - ret = append(ret, breadcrumb{ - Name: seg, - Path: "/" + strings.Join(segs[0:i+1], "/"), - }) - } - } - - // Drop the /ipns/ prefix from breadcrumb Paths when directory - // listing on a DNSLink website (loaded due to Host header in HTTP - // request). Necessary because the hostname most likely won't have a - // public gateway mounted. - if dnslinkOrigin { - prefix := "/ipns/" + contentRoot - for i, crumb := range ret { - if strings.HasPrefix(crumb.Path, prefix) { - ret[i].Path = strings.Replace(crumb.Path, prefix, "", 1) - } - } - // Make contentRoot breadcrumb link to the website root - ret[1].Path = "/" - } - - return ret -} - -func shortHash(hash string) string { - if len(hash) <= 8 { - return hash - } - return (hash[0:4] + "\u2026" + hash[len(hash)-4:]) -} - -// helper to detect DNSLink website context -// (when hostname from gwURL is matching /ipns/ in path) -func hasDNSLinkOrigin(gwURL string, path string) bool { - if gwURL != "" { - fqdn := stripPort(strings.TrimPrefix(gwURL, "//")) - return strings.HasPrefix(path, "/ipns/"+fqdn) - } - return false -} - -var listingTemplate *template.Template - -func init() { - knownIconsBytes, err := assets.Asset.ReadFile("dir-index-html/knownIcons.txt") - if err != nil { - panic(err) - } - knownIcons := make(map[string]struct{}) - for _, ext := range strings.Split(strings.TrimSuffix(string(knownIconsBytes), "\n"), "\n") { - knownIcons[ext] = struct{}{} - } - - // helper to guess the type/icon for it by the extension name - iconFromExt := func(name string) string { - ext := path.Ext(name) - _, ok := knownIcons[ext] - if !ok { - // default blank icon - return "ipfs-_blank" - } - return "ipfs-" + ext[1:] // slice of the first dot - } - - // custom template-escaping function to escape a full path, including '#' and '?' - urlEscape := func(rawUrl string) string { - pathURL := url.URL{Path: rawUrl} - return pathURL.String() - } - - // Directory listing template - dirIndexBytes, err := assets.Asset.ReadFile("dir-index-html/dir-index.html") - if err != nil { - panic(err) - } - - listingTemplate = template.Must(template.New("dir").Funcs(template.FuncMap{ - "iconFromExt": iconFromExt, - "urlEscape": urlEscape, - }).Parse(string(dirIndexBytes))) -} diff --git a/core/corehttp/gateway_test.go b/core/corehttp/gateway_test.go index 877ac9739..49fa519fb 100644 --- a/core/corehttp/gateway_test.go +++ b/core/corehttp/gateway_test.go @@ -651,28 +651,3 @@ func TestVersion(t *testing.T) { t.Fatalf("response doesn't contain protocol version:\n%s", s) } } - -func TestEtagMatch(t *testing.T) { - for _, test := range []struct { - header string // value in If-None-Match HTTP header - cidEtag string - dirEtag string - expected bool // expected result of etagMatch(header, cidEtag, dirEtag) - }{ - {"", `"etag"`, "", false}, // no If-None-Match - {"", "", `"etag"`, false}, // no If-None-Match - {`"etag"`, `"etag"`, "", true}, // file etag match - {`W/"etag"`, `"etag"`, "", true}, // file etag match - {`"foo", W/"bar", W/"etag"`, `"etag"`, "", true}, // file etag match (array) - {`"foo",W/"bar",W/"etag"`, `"etag"`, "", true}, // file etag match (compact array) - {`"etag"`, "", `W/"etag"`, true}, // dir etag match - {`"etag"`, "", `W/"etag"`, true}, // dir etag match - {`W/"etag"`, "", `W/"etag"`, true}, // dir etag match - {`*`, `"etag"`, "", true}, // wildcard etag match - } { - result := etagMatch(test.header, test.cidEtag, test.dirEtag) - if result != test.expected { - t.Fatalf("unexpected result of etagMatch(%q, %q, %q), got %t, expected %t", test.header, test.cidEtag, test.dirEtag, result, test.expected) - } - } -} diff --git a/core/corehttp/hostname.go b/core/corehttp/hostname.go index 39e857aad..adc47ab4d 100644 --- a/core/corehttp/hostname.go +++ b/core/corehttp/hostname.go @@ -10,6 +10,7 @@ import ( "strings" cid "github.com/ipfs/go-cid" + "github.com/ipfs/go-libipfs/gateway" namesys "github.com/ipfs/go-namesys" core "github.com/ipfs/kubo/core" coreapi "github.com/ipfs/kubo/core/coreapi" @@ -225,7 +226,7 @@ func HostnameOption() ServeOption { if !cfg.Gateway.NoDNSLink && isDNSLinkName(r.Context(), coreAPI, host) { // rewrite path and handle as DNSLink r.URL.Path = "/ipns/" + stripPort(host) + r.URL.Path - ctx := context.WithValue(r.Context(), requestContextKey("dnslink-hostname"), host) + ctx := context.WithValue(r.Context(), gateway.DNSLinkHostnameKey, host) childMux.ServeHTTP(w, withHostnameContext(r.WithContext(ctx), host)) return } @@ -247,8 +248,6 @@ type wildcardHost struct { spec *config.GatewaySpec } -type requestContextKey string - // Extends request context to include hostname of a canonical gateway root // (subdomain root or dnslink fqdn) func withHostnameContext(r *http.Request, hostname string) *http.Request { @@ -257,7 +256,7 @@ func withHostnameContext(r *http.Request, hostname string) *http.Request { // Host header, subdomain gateways have more comples rules (knownSubdomainDetails) // More: https://github.com/ipfs/dir-index-html/issues/42 // nolint: staticcheck // non-backward compatible change - ctx := context.WithValue(r.Context(), requestContextKey("gw-hostname"), hostname) + ctx := context.WithValue(r.Context(), gateway.GatewayHostnameKey, hostname) return r.WithContext(ctx) } diff --git a/core/corehttp/lazyseek.go b/core/corehttp/lazyseek.go deleted file mode 100644 index 2a379dc91..000000000 --- a/core/corehttp/lazyseek.go +++ /dev/null @@ -1,60 +0,0 @@ -package corehttp - -import ( - "fmt" - "io" -) - -// The HTTP server uses seek to determine the file size. Actually _seeking_ can -// be slow so we wrap the seeker in a _lazy_ seeker. -type lazySeeker struct { - reader io.ReadSeeker - - size int64 - offset int64 - realOffset int64 -} - -func (s *lazySeeker) Seek(offset int64, whence int) (int64, error) { - switch whence { - case io.SeekEnd: - return s.Seek(s.size+offset, io.SeekStart) - case io.SeekCurrent: - return s.Seek(s.offset+offset, io.SeekStart) - case io.SeekStart: - if offset < 0 { - return s.offset, fmt.Errorf("invalid seek offset") - } - s.offset = offset - return s.offset, nil - default: - return s.offset, fmt.Errorf("invalid whence: %d", whence) - } -} - -func (s *lazySeeker) Read(b []byte) (int, error) { - // If we're past the end, EOF. - if s.offset >= s.size { - return 0, io.EOF - } - - // actually seek - for s.offset != s.realOffset { - off, err := s.reader.Seek(s.offset, io.SeekStart) - if err != nil { - return 0, err - } - s.realOffset = off - } - off, err := s.reader.Read(b) - s.realOffset += int64(off) - s.offset += int64(off) - return off, err -} - -func (s *lazySeeker) Close() error { - if closer, ok := s.reader.(io.Closer); ok { - return closer.Close() - } - return nil -} diff --git a/core/corehttp/lazyseek_test.go b/core/corehttp/lazyseek_test.go deleted file mode 100644 index 49aca0a0e..000000000 --- a/core/corehttp/lazyseek_test.go +++ /dev/null @@ -1,136 +0,0 @@ -package corehttp - -import ( - "fmt" - "io" - "strings" - "testing" -) - -type badSeeker struct { - io.ReadSeeker -} - -var errBadSeek = fmt.Errorf("bad seeker") - -func (bs badSeeker) Seek(offset int64, whence int) (int64, error) { - off, err := bs.ReadSeeker.Seek(0, io.SeekCurrent) - if err != nil { - panic(err) - } - return off, errBadSeek -} - -func TestLazySeekerError(t *testing.T) { - underlyingBuffer := strings.NewReader("fubar") - s := &lazySeeker{ - reader: badSeeker{underlyingBuffer}, - size: underlyingBuffer.Size(), - } - off, err := s.Seek(0, io.SeekEnd) - if err != nil { - t.Fatal(err) - } - if off != s.size { - t.Fatal("expected to seek to the end") - } - - // shouldn't have actually seeked. - b, err := io.ReadAll(s) - if err != nil { - t.Fatal(err) - } - if len(b) != 0 { - t.Fatal("expected to read nothing") - } - - // shouldn't need to actually seek. - off, err = s.Seek(0, io.SeekStart) - if err != nil { - t.Fatal(err) - } - if off != 0 { - t.Fatal("expected to seek to the start") - } - b, err = io.ReadAll(s) - if err != nil { - t.Fatal(err) - } - if string(b) != "fubar" { - t.Fatal("expected to read string") - } - - // should fail the second time. - off, err = s.Seek(0, io.SeekStart) - if err != nil { - t.Fatal(err) - } - if off != 0 { - t.Fatal("expected to seek to the start") - } - // right here... - b, err = io.ReadAll(s) - if err == nil { - t.Fatalf("expected an error, got output %s", string(b)) - } - if err != errBadSeek { - t.Fatalf("expected a bad seek error, got %s", err) - } - if len(b) != 0 { - t.Fatalf("expected to read nothing") - } -} - -func TestLazySeeker(t *testing.T) { - underlyingBuffer := strings.NewReader("fubar") - s := &lazySeeker{ - reader: underlyingBuffer, - size: underlyingBuffer.Size(), - } - expectByte := func(b byte) { - t.Helper() - var buf [1]byte - n, err := io.ReadFull(s, buf[:]) - if err != nil { - t.Fatal(err) - } - if n != 1 { - t.Fatalf("expected to read one byte, read %d", n) - } - if buf[0] != b { - t.Fatalf("expected %b, got %b", b, buf[0]) - } - } - expectSeek := func(whence int, off, expOff int64, expErr string) { - t.Helper() - n, err := s.Seek(off, whence) - if expErr == "" { - if err != nil { - t.Fatal("unexpected seek error: ", err) - } - } else { - if err == nil || err.Error() != expErr { - t.Fatalf("expected %s, got %s", err, expErr) - } - } - if n != expOff { - t.Fatalf("expected offset %d, got, %d", expOff, n) - } - } - - expectSeek(io.SeekEnd, 0, s.size, "") - b, err := io.ReadAll(s) - if err != nil { - t.Fatal(err) - } - if len(b) != 0 { - t.Fatal("expected to read nothing") - } - expectSeek(io.SeekEnd, -1, s.size-1, "") - expectByte('r') - expectSeek(io.SeekStart, 0, 0, "") - expectByte('f') - expectSeek(io.SeekCurrent, 1, 2, "") - expectByte('b') - expectSeek(io.SeekCurrent, -100, 3, "invalid seek offset") -} diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 3294cd137..a74bfbf3e 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.18 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/go-libipfs v0.4.0 + github.com/ipfs/go-libipfs v0.4.1-0.20230130233950-a005a5006496 github.com/ipfs/interface-go-ipfs-core v0.10.0 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.24.2 diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index ece45c198..eb37654f7 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -548,8 +548,8 @@ github.com/ipfs/go-ipld-legacy v0.1.1 h1:BvD8PEuqwBHLTKqlGFTHSwrwFOMkVESEvwIYwR2 github.com/ipfs/go-ipld-legacy v0.1.1/go.mod h1:8AyKFCjgRPsQFf15ZQgDB8Din4DML/fOmKZkkFkrIEg= github.com/ipfs/go-ipns v0.3.0 h1:ai791nTgVo+zTuq2bLvEGmWP1M0A6kGTXUsgv/Yq67A= github.com/ipfs/go-ipns v0.3.0/go.mod h1:3cLT2rbvgPZGkHJoPO1YMJeh6LtkxopCkKFcio/wE24= -github.com/ipfs/go-libipfs v0.4.0 h1:TkUxJGjtPnSzAgkw7VjS0/DBay3MPjmTBa4dGdUQCDE= -github.com/ipfs/go-libipfs v0.4.0/go.mod h1:XsU2cP9jBhDrXoJDe0WxikB8XcVmD3k2MEZvB3dbYu8= +github.com/ipfs/go-libipfs v0.4.1-0.20230130233950-a005a5006496 h1:RVI31GQCFODREpasIFyVFkS6PjJT2bMwr/Bgr9Ryql4= +github.com/ipfs/go-libipfs v0.4.1-0.20230130233950-a005a5006496/go.mod h1:AAPvZADZ80i+QhGCWNWCsx8IGY0t9C+IBEngLeYtySY= github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= github.com/ipfs/go-log v1.0.2/go.mod h1:1MNjMxe0u6xvJZgeqbJ8vdo2TKaGwZ1a0Bpza+sr2Sk= github.com/ipfs/go-log v1.0.3/go.mod h1:OsLySYkwIbiSUR/yBTdv1qPtcE4FW3WPWk/ewz9Ru+A= @@ -597,7 +597,7 @@ github.com/ipfs/interface-go-ipfs-core v0.10.0 h1:b/psL1oqJcySdQAsIBfW5ZJJkOAsYl github.com/ipfs/interface-go-ipfs-core v0.10.0/go.mod h1:F3EcmDy53GFkF0H3iEJpfJC320fZ/4G60eftnItrrJ0= github.com/ipld/edelweiss v0.2.0 h1:KfAZBP8eeJtrLxLhi7r3N0cBCo7JmwSRhOJp3WSpNjk= github.com/ipld/edelweiss v0.2.0/go.mod h1:FJAzJRCep4iI8FOFlRriN9n0b7OuX3T/S9++NpBDmA4= -github.com/ipld/go-car v0.4.0 h1:U6W7F1aKF/OJMHovnOVdst2cpQE5GhmHibQkAixgNcQ= +github.com/ipld/go-car v0.5.0 h1:kcCEa3CvYMs0iE5BzD5sV7O2EwMiCIp3uF8tA6APQT8= github.com/ipld/go-car/v2 v2.5.1 h1:U2ux9JS23upEgrJScW8VQuxmE94560kYxj9CQUpcfmk= github.com/ipld/go-codec-dagpb v1.3.0/go.mod h1:ga4JTU3abYApDC3pZ00BC2RSvC3qfBb9MSJkMLSwnhA= github.com/ipld/go-codec-dagpb v1.5.0 h1:RspDRdsJpLfgCI0ONhTAnbHdySGD4t+LHSPK4X1+R0k= diff --git a/go.mod b/go.mod index 3d91f40e7..5edf9f68a 100644 --- a/go.mod +++ b/go.mod @@ -7,14 +7,12 @@ require ( github.com/blang/semver/v4 v4.0.0 github.com/cenkalti/backoff/v4 v4.1.3 github.com/ceramicnetwork/go-dag-jose v0.1.0 - github.com/cespare/xxhash v1.1.0 github.com/cheggaaa/pb v1.0.29 github.com/coreos/go-systemd/v22 v22.5.0 github.com/dustin/go-humanize v1.0.0 github.com/elgris/jsondiff v0.0.0-20160530203242-765b5c24c302 github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5 github.com/fsnotify/fsnotify v1.6.0 - github.com/gabriel-vasile/mimetype v1.4.1 github.com/gogo/protobuf v1.3.2 github.com/google/uuid v1.3.0 github.com/hashicorp/go-multierror v1.1.1 @@ -41,14 +39,13 @@ require ( github.com/ipfs/go-ipfs-pinner v0.2.1 github.com/ipfs/go-ipfs-posinfo v0.0.1 github.com/ipfs/go-ipfs-provider v0.8.1 - github.com/ipfs/go-ipfs-redirects-file v0.1.1 github.com/ipfs/go-ipfs-routing v0.3.0 github.com/ipfs/go-ipfs-util v0.0.2 github.com/ipfs/go-ipld-format v0.4.0 github.com/ipfs/go-ipld-git v0.1.1 github.com/ipfs/go-ipld-legacy v0.1.1 github.com/ipfs/go-ipns v0.3.0 - github.com/ipfs/go-libipfs v0.4.0 + github.com/ipfs/go-libipfs v0.4.1-0.20230130233950-a005a5006496 github.com/ipfs/go-log v1.0.5 github.com/ipfs/go-log/v2 v2.5.1 github.com/ipfs/go-merkledag v0.9.0 @@ -62,7 +59,7 @@ require ( github.com/ipfs/go-unixfsnode v1.5.1 github.com/ipfs/go-verifcid v0.0.2 github.com/ipfs/interface-go-ipfs-core v0.10.0 - github.com/ipld/go-car v0.4.0 + github.com/ipld/go-car v0.5.0 github.com/ipld/go-car/v2 v2.5.1 github.com/ipld/go-codec-dagpb v1.5.0 github.com/ipld/go-ipld-prime v0.19.0 @@ -121,6 +118,7 @@ require ( github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cenkalti/backoff v2.2.1+incompatible // indirect + github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/containerd/cgroups v1.0.4 // indirect github.com/crackcomm/go-gitignore v0.0.0-20170627025303-887ab5e44cc3 // indirect @@ -136,6 +134,7 @@ require ( github.com/felixge/httpsnoop v1.0.2 // indirect github.com/flynn/noise v1.0.0 // indirect github.com/francoispqt/gojay v1.2.13 // indirect + github.com/gabriel-vasile/mimetype v1.4.1 // indirect github.com/go-kit/log v0.2.0 // indirect github.com/go-logfmt/logfmt v0.5.1 // indirect github.com/go-logr/logr v1.2.3 // indirect @@ -161,6 +160,7 @@ require ( github.com/ipfs/go-ipfs-delay v0.0.1 // indirect github.com/ipfs/go-ipfs-ds-help v1.1.0 // indirect github.com/ipfs/go-ipfs-pq v0.0.2 // indirect + github.com/ipfs/go-ipfs-redirects-file v0.1.1 // indirect github.com/ipfs/go-ipld-cbor v0.0.6 // indirect github.com/ipfs/go-peertaskqueue v0.8.0 // indirect github.com/ipld/edelweiss v0.2.0 // indirect diff --git a/go.sum b/go.sum index 471acc808..fefe9bf71 100644 --- a/go.sum +++ b/go.sum @@ -570,8 +570,8 @@ github.com/ipfs/go-ipld-legacy v0.1.1 h1:BvD8PEuqwBHLTKqlGFTHSwrwFOMkVESEvwIYwR2 github.com/ipfs/go-ipld-legacy v0.1.1/go.mod h1:8AyKFCjgRPsQFf15ZQgDB8Din4DML/fOmKZkkFkrIEg= github.com/ipfs/go-ipns v0.3.0 h1:ai791nTgVo+zTuq2bLvEGmWP1M0A6kGTXUsgv/Yq67A= github.com/ipfs/go-ipns v0.3.0/go.mod h1:3cLT2rbvgPZGkHJoPO1YMJeh6LtkxopCkKFcio/wE24= -github.com/ipfs/go-libipfs v0.4.0 h1:TkUxJGjtPnSzAgkw7VjS0/DBay3MPjmTBa4dGdUQCDE= -github.com/ipfs/go-libipfs v0.4.0/go.mod h1:XsU2cP9jBhDrXoJDe0WxikB8XcVmD3k2MEZvB3dbYu8= +github.com/ipfs/go-libipfs v0.4.1-0.20230130233950-a005a5006496 h1:RVI31GQCFODREpasIFyVFkS6PjJT2bMwr/Bgr9Ryql4= +github.com/ipfs/go-libipfs v0.4.1-0.20230130233950-a005a5006496/go.mod h1:AAPvZADZ80i+QhGCWNWCsx8IGY0t9C+IBEngLeYtySY= github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= github.com/ipfs/go-log v1.0.2/go.mod h1:1MNjMxe0u6xvJZgeqbJ8vdo2TKaGwZ1a0Bpza+sr2Sk= github.com/ipfs/go-log v1.0.3/go.mod h1:OsLySYkwIbiSUR/yBTdv1qPtcE4FW3WPWk/ewz9Ru+A= @@ -623,8 +623,8 @@ github.com/ipfs/interface-go-ipfs-core v0.10.0 h1:b/psL1oqJcySdQAsIBfW5ZJJkOAsYl github.com/ipfs/interface-go-ipfs-core v0.10.0/go.mod h1:F3EcmDy53GFkF0H3iEJpfJC320fZ/4G60eftnItrrJ0= github.com/ipld/edelweiss v0.2.0 h1:KfAZBP8eeJtrLxLhi7r3N0cBCo7JmwSRhOJp3WSpNjk= github.com/ipld/edelweiss v0.2.0/go.mod h1:FJAzJRCep4iI8FOFlRriN9n0b7OuX3T/S9++NpBDmA4= -github.com/ipld/go-car v0.4.0 h1:U6W7F1aKF/OJMHovnOVdst2cpQE5GhmHibQkAixgNcQ= -github.com/ipld/go-car v0.4.0/go.mod h1:Uslcn4O9cBKK9wqHm/cLTFacg6RAPv6LZx2mxd2Ypl4= +github.com/ipld/go-car v0.5.0 h1:kcCEa3CvYMs0iE5BzD5sV7O2EwMiCIp3uF8tA6APQT8= +github.com/ipld/go-car v0.5.0/go.mod h1:ppiN5GWpjOZU9PgpAZ9HbZd9ZgSpwPMr48fGRJOWmvE= github.com/ipld/go-car/v2 v2.5.1 h1:U2ux9JS23upEgrJScW8VQuxmE94560kYxj9CQUpcfmk= github.com/ipld/go-car/v2 v2.5.1/go.mod h1:jKjGOqoCj5zn6KjnabD6JbnCsMntqU2hLiU6baZVO3E= github.com/ipld/go-codec-dagpb v1.3.0/go.mod h1:ga4JTU3abYApDC3pZ00BC2RSvC3qfBb9MSJkMLSwnhA= From c155e40072a695649aa1effda419cbf8b06cd37a Mon Sep 17 00:00:00 2001 From: galargh Date: Tue, 31 Jan 2023 13:12:25 +0000 Subject: [PATCH 0452/1212] chore: create next changelog --- CHANGELOG.md | 1 + docs/changelogs/v0.19.md | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 docs/changelogs/v0.19.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b5a5769f..16e72bcb1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ # Kubo Changelogs +- [v0.19](docs/changelogs/v0.19.md) - [v0.18](docs/changelogs/v0.18.md) - [v0.17](docs/changelogs/v0.17.md) - [v0.16](docs/changelogs/v0.16.md) diff --git a/docs/changelogs/v0.19.md b/docs/changelogs/v0.19.md new file mode 100644 index 000000000..e1c28482d --- /dev/null +++ b/docs/changelogs/v0.19.md @@ -0,0 +1,18 @@ +# Kubo changelog v0.19 + +- [v0.19.0](#v0190) + +## v0.19.0 + +- [Overview](#overview) +- [🔦 Highlights](#-highlights) +- [📝 Changelog](#-changelog) +- [👨‍👩‍👧‍👦 Contributors](#-contributors) + +### Overview + +### 🔦 Highlights + +### 📝 Changelog + +### 👨‍👩‍👧‍👦 Contributors From bcf446d1a1478e863f98e5f3af3d569d68e30a6e Mon Sep 17 00:00:00 2001 From: galargh Date: Tue, 31 Jan 2023 14:31:36 +0100 Subject: [PATCH 0453/1212] chore: hide manual steps now that commands request them themselves --- docs/RELEASE_ISSUE_TEMPLATE.md | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/docs/RELEASE_ISSUE_TEMPLATE.md b/docs/RELEASE_ISSUE_TEMPLATE.md index 4eadf9caa..250b08ba2 100644 --- a/docs/RELEASE_ISSUE_TEMPLATE.md +++ b/docs/RELEASE_ISSUE_TEMPLATE.md @@ -76,7 +76,7 @@ This section covers tasks to be done ahead of the release. - [example](https://github.com/ipfs/distributions/pull/756) - [ ] ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) [ipfs/ipfs-docs](https://github.com/ipfs/ipfs-docs) - [example](https://github.com/ipfs/ipfs-docs/pull/1298) -- [ ] Notify the bifrost team about the upcoming release
using `kuboreleaser release --version vX.Y.Z(-RCN) notify-bifrost --date YYYY-MM-DD` or ... (_only if it is not the day of the release yet_) +- [ ] Notify the bifrost team about the upcoming release (_only if it is not the day of the release yet_)
using `kuboreleaser release --version vX.Y.Z(-RCN) notify-bifrost --date YYYY-MM-DD` or ... - [ ] open an issue against [bifrost-infra](https://github.com/protocol/bifrost-infra) - [example](https://github.com/protocol/bifrost-infra/issues/2221)
@@ -94,21 +94,21 @@ This section covers tasks to be done during each release. - [ ] create a new branch `release-vX.Y.Z` - use `master` as base if `Z == 0` - use `release` as base if `Z > 0` - - [ ] ![](https://img.shields.io/badge/only-RC-blue?style=flat-square) update the `CurrentVersionNumber` in [version.go](version.go) in the `master` branch to `vX.(Y+1).0-dev` + - [ ] ![](https://img.shields.io/badge/only-RC-blue?style=flat-square) update the `CurrentVersionNumber` in [version.go](version.go) in the `master` branch to `vX.Y+1.0-dev` - [example](https://github.com/ipfs/kubo/pull/9305) - [ ] update the `CurrentVersionNumber` in [version.go](version.go) in the `release-vX.Y` branch to `vX.Y.Z(-RCN)` - [example](https://github.com/ipfs/kubo/pull/9394) - [ ] create a draft PR from `release-vX.Y` to `release` - [example](https://github.com/ipfs/kubo/pull/9306) + - [ ] Cherry-pick commits from `master` to the `release-vX.Y.Z` using `git cherry-pick -x ` + - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Add full changelog and contributors to the [changelog](docs/changelogs/vX.Y.md) + - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Replace the `Changelog` and `Contributors` sections of the [changelog](docs/changelogs/vX.Y.md) with the stdout of `./bin/mkreleaselog` + - do **NOT** copy the stderr - [ ] verify all CI checks on the PR from `release-vX.Y` to `release` are passing + - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Merge the PR from `release-vX.Y` to `release` using the `Create a merge commit` + - do **NOT** use `Squash and merge` nor `Rebase and merge` because we need to be able to sign the merge commit + - do **NOT** delete the `release-vX.Y` branch
-- [ ] Cherry-pick commits from `master` to the `release-vX.Y.Z` using `git cherry-pick -x ` -- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Add full changelog and contributors to the [changelog](docs/changelogs/vX.Y.md) - - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Replace the `Changelog` and `Contributors` sections of the [changelog](docs/changelogs/vX.Y.md) with the stdout of `./bin/mkreleaselog` - - do **NOT** copy the stderr -- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Merge the PR from `release-vX.Y` to `release` using the `Create a merge commit` - - do **NOT** use `Squash and merge` nor `Rebase and merge` because we need to be able to sign the merge commit - - do **NOT** delete the `release-vX.Y` branch - [ ] Create the release tag
using `kuboreleaser release --version vX.Y.Z(-RCN) tag` or ... - This is a dangerous operation! Go and Docker publishing are difficult to reverse! Have the release reviewer verify all the commands marked with ⚠️! - [ ] ⚠️ ![](https://img.shields.io/badge/only-RC-blue?style=flat-square) tag the HEAD commit using `git tag -s vX.Y.Z(-RCN) -m 'Prerelease X.Y.Z(-RCN)'` @@ -117,7 +117,8 @@ This section covers tasks to be done during each release. - [ ] ⚠️ push the tag to GitHub using `git push origin vX.Y.Z(-RCN)` - do **NOT** use `git push --tags` because it pushes all your local tags
-- [ ] Wait for [Publish docker image](https://github.com/ipfs/kubo/actions/workflows/docker-image.yml) workflow run initiated by the tag push to finish +- [ ] Publish the release to [DockerHub](https://hub.docker.com/r/ipfs/kubo/)
using `kuboreleaser --skip-check-before --skip-run release --version vX.Y.Z(-RCN) publish-to-dockerhub` or ... + - [ ] Wait for [Publish docker image](https://github.com/ipfs/kubo/actions/workflows/docker-image.yml) workflow run initiated by the tag push to finish - [ ] verify the image is available on [Docker Hub](https://hub.docker.com/r/ipfs/kubo/tags) - [ ] Publish the release to [ipfs.tech](https://dist.ipfs.tech)
using `kuboreleaser release --version vX.Y.Z(-RCN) publish-to-distributions` or ... - [ ] check out [ipfs/distributions](https://github.com/ipfs/distributions) @@ -164,6 +165,8 @@ This section covers tasks to be done during each release. - [ ] [#ipfs-chatter](https://discord.com/channels/669268347736686612/669268347736686615) in IPFS Discord - [ ] [#ipfs-chatter](https://filecoinproject.slack.com/archives/C018EJ8LWH1) in FIL Slack - [ ] [#ipfs-chatter:ipfs.io](https://matrix.to/#/#ipfs-chatter:ipfs.io) in Matrix + - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Add the link to the [IPFS Discourse](https://discuss.ipfs.tech) topic to the [GitHub Release](https://github.com/ipfs/kubo/releases/tag/vX.Y.Z(-RCN)) description + - [example](https://github.com/ipfs/kubo/releases/tag/v0.17.0) - [ ] ![](https://img.shields.io/badge/only-RC-blue?style=flat-square) create an issue comment mentioning early testers on the release issue - [example](https://github.com/ipfs/kubo/issues/9319#issuecomment-1311002478) - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) create an issue comment linking to the release on the release issue @@ -173,8 +176,6 @@ This section covers tasks to be done during each release. - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) post the link to the [GitHub Release](https://github.com/ipfs/kubo/releases/tag/vX.Y.Z(-RCN)) to [Reddit](https://reddit.com/r/ipfs) - [example](https://www.reddit.com/r/ipfs/comments/9x0q0k/kubo_v0160_release_is_out/)
-- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Add the link to the [IPFS Discourse](https://discuss.ipfs.tech) topic to the [GitHub Release](https://github.com/ipfs/kubo/releases/tag/vX.Y.Z(-RCN)) description - - [example](https://github.com/ipfs/kubo/releases/tag/v0.17.0) - [ ] Test the new version with `ipfs-companion`
using `kuboreleaser release --version vX.Y.Z(-RCN) test-ipfs-companion` or ... - [ ] run the [e2e](https://github.com/ipfs/ipfs-companion/actions/workflows/e2e.yml) - use `vX.Y.Z(-RCN)` as the Kubo image version @@ -209,9 +210,11 @@ This section covers tasks to be done during each release. - [ ] create a new branch `merge-release-vX.Y.Z` from `release` - [ ] create and merge a PR from `merge-release-vX.Y.Z` to `master`
-- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) Create the next [changelog](https://github.com/ipfs/kubo/blob/master/docs/changelogs/vX.(Y+1).md) - - link to the new changelog in the [CHANGELOG.md](CHANGELOG.md) file -- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) Create the next release issue +- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) Prepare for the next release
using `kuboreleaser release --version vX.Y.Z(-RCN) prepare-next` or ... + - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) Create the next [changelog](https://github.com/ipfs/kubo/blob/master/docs/changelogs/vX.(Y+1).md) + - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) Link to the new changelog in the [CHANGELOG.md](CHANGELOG.md) file + - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) Create the next release issue +
- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) Create a dependency update PR - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) check out [ipfs/kubo](https://github.com/ipfs/kubo) - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) run `go get -t -u ./...` From cf2f378b9dffd71f275e0fccc40024ce46027687 Mon Sep 17 00:00:00 2001 From: Piotr Galar Date: Tue, 31 Jan 2023 16:08:16 +0100 Subject: [PATCH 0454/1212] Update docs/RELEASE_ISSUE_TEMPLATE.md --- docs/RELEASE_ISSUE_TEMPLATE.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/RELEASE_ISSUE_TEMPLATE.md b/docs/RELEASE_ISSUE_TEMPLATE.md index 250b08ba2..5e2f94a3f 100644 --- a/docs/RELEASE_ISSUE_TEMPLATE.md +++ b/docs/RELEASE_ISSUE_TEMPLATE.md @@ -217,7 +217,9 @@ This section covers tasks to be done during each release.
- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) Create a dependency update PR - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) check out [ipfs/kubo](https://github.com/ipfs/kubo) - - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) run `go get -t -u ./...` + - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) run `go get -u` in root directory + - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) run `go mod tidy` in root directory + - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) run `go mod tidy` in `docs/examples/kubo-as-a-library` directory - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) create a PR which updates `go.mod` and `go.sum` - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) add the PR to the next release milestone - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Close the release issue From 01eaa11d2733a3f8f2355ff852857e46c15d5ee3 Mon Sep 17 00:00:00 2001 From: galargh Date: Tue, 31 Jan 2023 16:12:58 +0100 Subject: [PATCH 0455/1212] docs: add kuboreleaser to the release issue template --- docs/RELEASE_ISSUE_TEMPLATE.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/RELEASE_ISSUE_TEMPLATE.md b/docs/RELEASE_ISSUE_TEMPLATE.md index 5e2f94a3f..b591fdd5b 100644 --- a/docs/RELEASE_ISSUE_TEMPLATE.md +++ b/docs/RELEASE_ISSUE_TEMPLATE.md @@ -65,6 +65,7 @@ This section covers tasks to be done ahead of the release. - [ ] [access to IPFS network metrics](https://github.com/protocol/pldw/blob/624f47cf4ec14ad2cec6adf601a9f7b203ef770d/docs/sources/ipfs.md#ipfs-network-metrics) dashboards in Grafana - open an access request in the [pldw](https://github.com/protocol/pldw/issues/new/choose) - [example](https://github.com/protocol/pldw/issues/158) + - [ ] [kuboreleaser](https://github.com/ipfs/kuboreleaser) checked out on your system (_only if you're using [kuboreleaser](https://github.com/ipfs/kuboreleaser)_) - [ ] [docker](https://docs.docker.com/get-docker/) installed on your system (_only if you're using [kuboreleaser](https://github.com/ipfs/kuboreleaser)_) - [ ] [npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) installed on your system (_only if you're **NOT** using [kuboreleaser](https://github.com/ipfs/kuboreleaser)_) - [ ] [zsh](https://github.com/ohmyzsh/ohmyzsh/wiki/Installing-ZSH#install-and-set-up-zsh-as-default) installed on your system From 14649aa8ba8d7612ce9e35bba776fe7e7498b343 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Thu, 2 Feb 2023 02:50:46 +0100 Subject: [PATCH 0456/1212] refactor: new go-libipfs/gateway API, deprecate Gateway.Writable (#9616) --- cmd/ipfs/daemon.go | 8 +- config/gateway.go | 6 +- config/init.go | 1 - core/corehttp/gateway.go | 93 +++++++- core/corehttp/gateway_writable.go | 265 +++++++++++++++++++++++ docs/config.md | 5 +- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 +- go.mod | 2 +- go.sum | 4 +- test/sharness/t0111-gateway-writeable.sh | 4 + 11 files changed, 376 insertions(+), 18 deletions(-) create mode 100644 core/corehttp/gateway_writable.go diff --git a/cmd/ipfs/daemon.go b/cmd/ipfs/daemon.go index 12b3f4d9c..21495c498 100644 --- a/cmd/ipfs/daemon.go +++ b/cmd/ipfs/daemon.go @@ -162,7 +162,7 @@ Headers. cmds.StringOption(initProfileOptionKwd, "Configuration profiles to apply for --init. See ipfs init --help for more"), cmds.StringOption(routingOptionKwd, "Overrides the routing option").WithDefault(routingOptionDefaultKwd), cmds.BoolOption(mountKwd, "Mounts IPFS to the filesystem using FUSE (experimental)"), - cmds.BoolOption(writableKwd, "Enable writing objects (with POST, PUT and DELETE)"), + cmds.BoolOption(writableKwd, "Enable legacy Gateway.Writable (deprecated)"), cmds.StringOption(ipfsMountKwd, "Path to the mountpoint for IPFS (if using --mount). Defaults to config setting."), cmds.StringOption(ipnsMountKwd, "Path to the mountpoint for IPNS (if using --mount). Defaults to config setting."), cmds.BoolOption(unrestrictedAPIAccessKwd, "Allow API access to unlisted hashes"), @@ -791,7 +791,11 @@ func serveHTTPGateway(req *cmds.Request, cctx *oldcmds.Context) (<-chan error, e writable, writableOptionFound := req.Options[writableKwd].(bool) if !writableOptionFound { - writable = cfg.Gateway.Writable + writable = cfg.Gateway.Writable.WithDefault(false) + } + + if writable { + log.Error("serveHTTPGateway: legacy Gateway.Writable is DEPRECATED and will be removed or changed in future versions. If you are still using this, provide feedback in https://github.com/ipfs/specs/issues/375") } listeners, err := sockets.TakeListeners("io.ipfs.gateway") diff --git a/config/gateway.go b/config/gateway.go index ad01b263b..de43dd39e 100644 --- a/config/gateway.go +++ b/config/gateway.go @@ -38,9 +38,9 @@ type Gateway struct { // should be redirected. RootRedirect string - // Writable enables PUT/POST request handling by this gateway. Usually, - // writing is done through the API, not the gateway. - Writable bool + // DEPRECATED: Enables legacy PUT/POST request handling. + // Modern replacement tracked in https://github.com/ipfs/specs/issues/375 + Writable Flag `json:",omitempty"` // PathPrefixes was removed: https://github.com/ipfs/go-ipfs/issues/7702 PathPrefixes []string diff --git a/config/init.go b/config/init.go index 621ff95f3..288f8a1d5 100644 --- a/config/init.go +++ b/config/init.go @@ -65,7 +65,6 @@ func InitWithIdentity(identity Identity) (*Config, error) { Gateway: Gateway{ RootRedirect: "", - Writable: false, NoFetch: false, PathPrefixes: []string{}, HTTPHeaders: map[string][]string{ diff --git a/core/corehttp/gateway.go b/core/corehttp/gateway.go index d5eccf73c..3c7803036 100644 --- a/core/corehttp/gateway.go +++ b/core/corehttp/gateway.go @@ -1,12 +1,19 @@ package corehttp import ( + "context" "fmt" + "io" "net" "net/http" + cid "github.com/ipfs/go-cid" + "github.com/ipfs/go-libipfs/blocks" + "github.com/ipfs/go-libipfs/files" "github.com/ipfs/go-libipfs/gateway" + iface "github.com/ipfs/interface-go-ipfs-core" options "github.com/ipfs/interface-go-ipfs-core/options" + "github.com/ipfs/interface-go-ipfs-core/path" version "github.com/ipfs/kubo" core "github.com/ipfs/kubo/core" coreapi "github.com/ipfs/kubo/core/coreapi" @@ -38,15 +45,45 @@ func GatewayOption(writable bool, paths ...string) ServeOption { return nil, err } - gateway := gateway.NewHandler(gateway.Config{ - Headers: headers, - Writable: writable, - }, api, offlineAPI) + gatewayConfig := gateway.Config{ + Headers: headers, + } + gatewayAPI := &gatewayAPI{ + api: api, + offlineAPI: offlineAPI, + } + + gateway := gateway.NewHandler(gatewayConfig, gatewayAPI) gateway = otelhttp.NewHandler(gateway, "Gateway.Request") + var writableGateway *writableGatewayHandler + if writable { + writableGateway = &writableGatewayHandler{ + config: &gatewayConfig, + api: api, + } + } + for _, p := range paths { - mux.Handle(p+"/", gateway) + mux.HandleFunc(p+"/", func(w http.ResponseWriter, r *http.Request) { + if writable { + switch r.Method { + case http.MethodPost: + writableGateway.postHandler(w, r) + case http.MethodDelete: + writableGateway.deleteHandler(w, r) + case http.MethodPut: + writableGateway.putHandler(w, r) + default: + gateway.ServeHTTP(w, r) + } + + return + } + + gateway.ServeHTTP(w, r) + }) } return mux, nil } @@ -62,3 +99,49 @@ func VersionOption() ServeOption { return mux, nil } } + +type gatewayAPI struct { + api iface.CoreAPI + offlineAPI iface.CoreAPI +} + +func (gw *gatewayAPI) GetUnixFsNode(ctx context.Context, pth path.Resolved) (files.Node, error) { + return gw.api.Unixfs().Get(ctx, pth) +} + +func (gw *gatewayAPI) LsUnixFsDir(ctx context.Context, pth path.Resolved) (<-chan iface.DirEntry, error) { + // Optimization: use Unixfs.Ls without resolving children, but using the + // cumulative DAG size as the file size. This allows for a fast listing + // while keeping a good enough Size field. + return gw.api.Unixfs().Ls(ctx, pth, + options.Unixfs.ResolveChildren(false), + options.Unixfs.UseCumulativeSize(true), + ) +} + +func (gw *gatewayAPI) GetBlock(ctx context.Context, cid cid.Cid) (blocks.Block, error) { + r, err := gw.api.Block().Get(ctx, path.IpfsPath(cid)) + if err != nil { + return nil, err + } + + data, err := io.ReadAll(r) + if err != nil { + return nil, err + } + + return blocks.NewBlockWithCid(data, cid) +} + +func (gw *gatewayAPI) GetIPNSRecord(ctx context.Context, c cid.Cid) ([]byte, error) { + return gw.api.Routing().Get(ctx, "/ipns/"+c.String()) +} + +func (gw *gatewayAPI) IsCached(ctx context.Context, pth path.Path) bool { + _, err := gw.offlineAPI.Block().Stat(ctx, pth) + return err == nil +} + +func (gw *gatewayAPI) ResolvePath(ctx context.Context, pth path.Path) (path.Resolved, error) { + return gw.api.ResolvePath(ctx, pth) +} diff --git a/core/corehttp/gateway_writable.go b/core/corehttp/gateway_writable.go new file mode 100644 index 000000000..89a2973ac --- /dev/null +++ b/core/corehttp/gateway_writable.go @@ -0,0 +1,265 @@ +package corehttp + +import ( + "context" + "fmt" + "net/http" + "os" + gopath "path" + + cid "github.com/ipfs/go-cid" + ipld "github.com/ipfs/go-ipld-format" + "github.com/ipfs/go-libipfs/files" + "github.com/ipfs/go-libipfs/gateway" + dag "github.com/ipfs/go-merkledag" + "github.com/ipfs/go-mfs" + path "github.com/ipfs/go-path" + "github.com/ipfs/go-path/resolver" + iface "github.com/ipfs/interface-go-ipfs-core" + routing "github.com/libp2p/go-libp2p/core/routing" +) + +const ( + ipfsPathPrefix = "/ipfs/" +) + +type writableGatewayHandler struct { + api iface.CoreAPI + config *gateway.Config +} + +func (i *writableGatewayHandler) addUserHeaders(w http.ResponseWriter) { + for k, v := range i.config.Headers { + w.Header()[k] = v + } +} + +func (i *writableGatewayHandler) postHandler(w http.ResponseWriter, r *http.Request) { + p, err := i.api.Unixfs().Add(r.Context(), files.NewReaderFile(r.Body)) + if err != nil { + internalWebError(w, err) + return + } + + i.addUserHeaders(w) // ok, _now_ write user's headers. + w.Header().Set("IPFS-Hash", p.Cid().String()) + log.Debugw("CID created, http redirect", "from", r.URL, "to", p, "status", http.StatusCreated) + http.Redirect(w, r, p.String(), http.StatusCreated) +} + +func (i *writableGatewayHandler) putHandler(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() + ds := i.api.Dag() + + // Parse the path + rootCid, newPath, err := parseIpfsPath(r.URL.Path) + if err != nil { + webError(w, "WritableGateway: failed to parse the path", err, http.StatusBadRequest) + return + } + if newPath == "" || newPath == "/" { + http.Error(w, "WritableGateway: empty path", http.StatusBadRequest) + return + } + newDirectory, newFileName := gopath.Split(newPath) + + // Resolve the old root. + + rnode, err := ds.Get(ctx, rootCid) + if err != nil { + webError(w, "WritableGateway: Could not create DAG from request", err, http.StatusInternalServerError) + return + } + + pbnd, ok := rnode.(*dag.ProtoNode) + if !ok { + webError(w, "Cannot read non protobuf nodes through gateway", dag.ErrNotProtobuf, http.StatusBadRequest) + return + } + + // Create the new file. + newFilePath, err := i.api.Unixfs().Add(ctx, files.NewReaderFile(r.Body)) + if err != nil { + webError(w, "WritableGateway: could not create DAG from request", err, http.StatusInternalServerError) + return + } + + newFile, err := ds.Get(ctx, newFilePath.Cid()) + if err != nil { + webError(w, "WritableGateway: failed to resolve new file", err, http.StatusInternalServerError) + return + } + + // Patch the new file into the old root. + + root, err := mfs.NewRoot(ctx, ds, pbnd, nil) + if err != nil { + webError(w, "WritableGateway: failed to create MFS root", err, http.StatusBadRequest) + return + } + + if newDirectory != "" { + err := mfs.Mkdir(root, newDirectory, mfs.MkdirOpts{Mkparents: true, Flush: false}) + if err != nil { + webError(w, "WritableGateway: failed to create MFS directory", err, http.StatusInternalServerError) + return + } + } + dirNode, err := mfs.Lookup(root, newDirectory) + if err != nil { + webError(w, "WritableGateway: failed to lookup directory", err, http.StatusInternalServerError) + return + } + dir, ok := dirNode.(*mfs.Directory) + if !ok { + http.Error(w, "WritableGateway: target directory is not a directory", http.StatusBadRequest) + return + } + err = dir.Unlink(newFileName) + switch err { + case os.ErrNotExist, nil: + default: + webError(w, "WritableGateway: failed to replace existing file", err, http.StatusBadRequest) + return + } + err = dir.AddChild(newFileName, newFile) + if err != nil { + webError(w, "WritableGateway: failed to link file into directory", err, http.StatusInternalServerError) + return + } + nnode, err := root.GetDirectory().GetNode() + if err != nil { + webError(w, "WritableGateway: failed to finalize", err, http.StatusInternalServerError) + return + } + newcid := nnode.Cid() + + i.addUserHeaders(w) // ok, _now_ write user's headers. + w.Header().Set("IPFS-Hash", newcid.String()) + + redirectURL := gopath.Join(ipfsPathPrefix, newcid.String(), newPath) + log.Debugw("CID replaced, redirect", "from", r.URL, "to", redirectURL, "status", http.StatusCreated) + http.Redirect(w, r, redirectURL, http.StatusCreated) +} + +func (i *writableGatewayHandler) deleteHandler(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() + + // parse the path + + rootCid, newPath, err := parseIpfsPath(r.URL.Path) + if err != nil { + webError(w, "WritableGateway: failed to parse the path", err, http.StatusBadRequest) + return + } + if newPath == "" || newPath == "/" { + http.Error(w, "WritableGateway: empty path", http.StatusBadRequest) + return + } + directory, filename := gopath.Split(newPath) + + // lookup the root + + rootNodeIPLD, err := i.api.Dag().Get(ctx, rootCid) + if err != nil { + webError(w, "WritableGateway: failed to resolve root CID", err, http.StatusInternalServerError) + return + } + rootNode, ok := rootNodeIPLD.(*dag.ProtoNode) + if !ok { + http.Error(w, "WritableGateway: empty path", http.StatusInternalServerError) + return + } + + // construct the mfs root + + root, err := mfs.NewRoot(ctx, i.api.Dag(), rootNode, nil) + if err != nil { + webError(w, "WritableGateway: failed to construct the MFS root", err, http.StatusBadRequest) + return + } + + // lookup the parent directory + + parentNode, err := mfs.Lookup(root, directory) + if err != nil { + webError(w, "WritableGateway: failed to look up parent", err, http.StatusInternalServerError) + return + } + + parent, ok := parentNode.(*mfs.Directory) + if !ok { + http.Error(w, "WritableGateway: parent is not a directory", http.StatusInternalServerError) + return + } + + // delete the file + + switch parent.Unlink(filename) { + case nil, os.ErrNotExist: + default: + webError(w, "WritableGateway: failed to remove file", err, http.StatusInternalServerError) + return + } + + nnode, err := root.GetDirectory().GetNode() + if err != nil { + webError(w, "WritableGateway: failed to finalize", err, http.StatusInternalServerError) + return + } + ncid := nnode.Cid() + + i.addUserHeaders(w) // ok, _now_ write user's headers. + w.Header().Set("IPFS-Hash", ncid.String()) + + redirectURL := gopath.Join(ipfsPathPrefix+ncid.String(), directory) + // note: StatusCreated is technically correct here as we created a new resource. + log.Debugw("CID deleted, redirect", "from", r.RequestURI, "to", redirectURL, "status", http.StatusCreated) + http.Redirect(w, r, redirectURL, http.StatusCreated) +} + +func parseIpfsPath(p string) (cid.Cid, string, error) { + rootPath, err := path.ParsePath(p) + if err != nil { + return cid.Cid{}, "", err + } + + // Check the path. + rsegs := rootPath.Segments() + if rsegs[0] != "ipfs" { + return cid.Cid{}, "", fmt.Errorf("WritableGateway: only ipfs paths supported") + } + + rootCid, err := cid.Decode(rsegs[1]) + if err != nil { + return cid.Cid{}, "", err + } + + return rootCid, path.Join(rsegs[2:]), nil +} + +func webError(w http.ResponseWriter, message string, err error, defaultCode int) { + if _, ok := err.(resolver.ErrNoLink); ok { + webErrorWithCode(w, message, err, http.StatusNotFound) + } else if err == routing.ErrNotFound { + webErrorWithCode(w, message, err, http.StatusNotFound) + } else if ipld.IsNotFound(err) { + webErrorWithCode(w, message, err, http.StatusNotFound) + } else if err == context.DeadlineExceeded { + webErrorWithCode(w, message, err, http.StatusRequestTimeout) + } else { + webErrorWithCode(w, message, err, defaultCode) + } +} + +func webErrorWithCode(w http.ResponseWriter, message string, err error, code int) { + http.Error(w, fmt.Sprintf("%s: %s", message, err), code) + if code >= 500 { + log.Warnf("server error: %s: %s", message, err) + } +} + +// return a 500 error and log +func internalWebError(w http.ResponseWriter, err error) { + webErrorWithCode(w, "internalWebError", err, http.StatusInternalServerError) +} diff --git a/docs/config.md b/docs/config.md index 995872c4f..e1188b23a 100644 --- a/docs/config.md +++ b/docs/config.md @@ -682,7 +682,10 @@ Type: `string` (url) ### `Gateway.Writable` -A boolean to configure whether the gateway is writeable or not. +**DEPRECATED**: Enables legacy PUT/POST request handling. + +This API is not standardized, and should not be used for new projects. +We are working on a modern replacement. IPIP can be tracked in [ipfs/specs#375](https://github.com/ipfs/specs/issues/375). Default: `false` diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index a74bfbf3e..2b739db84 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.18 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/go-libipfs v0.4.1-0.20230130233950-a005a5006496 + github.com/ipfs/go-libipfs v0.4.1-0.20230202010411-6399b73f974c github.com/ipfs/interface-go-ipfs-core v0.10.0 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.24.2 diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index eb37654f7..f286c50ad 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -548,8 +548,8 @@ github.com/ipfs/go-ipld-legacy v0.1.1 h1:BvD8PEuqwBHLTKqlGFTHSwrwFOMkVESEvwIYwR2 github.com/ipfs/go-ipld-legacy v0.1.1/go.mod h1:8AyKFCjgRPsQFf15ZQgDB8Din4DML/fOmKZkkFkrIEg= github.com/ipfs/go-ipns v0.3.0 h1:ai791nTgVo+zTuq2bLvEGmWP1M0A6kGTXUsgv/Yq67A= github.com/ipfs/go-ipns v0.3.0/go.mod h1:3cLT2rbvgPZGkHJoPO1YMJeh6LtkxopCkKFcio/wE24= -github.com/ipfs/go-libipfs v0.4.1-0.20230130233950-a005a5006496 h1:RVI31GQCFODREpasIFyVFkS6PjJT2bMwr/Bgr9Ryql4= -github.com/ipfs/go-libipfs v0.4.1-0.20230130233950-a005a5006496/go.mod h1:AAPvZADZ80i+QhGCWNWCsx8IGY0t9C+IBEngLeYtySY= +github.com/ipfs/go-libipfs v0.4.1-0.20230202010411-6399b73f974c h1:Z8GrWoG3VZWj0RvHnzKlyIyXh8sgCIw62O9t3jnhqyk= +github.com/ipfs/go-libipfs v0.4.1-0.20230202010411-6399b73f974c/go.mod h1:S5wg08D/FkeYxeMf8adgt6Mi6ttbA7kSFcQYlmeGHMU= github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= github.com/ipfs/go-log v1.0.2/go.mod h1:1MNjMxe0u6xvJZgeqbJ8vdo2TKaGwZ1a0Bpza+sr2Sk= github.com/ipfs/go-log v1.0.3/go.mod h1:OsLySYkwIbiSUR/yBTdv1qPtcE4FW3WPWk/ewz9Ru+A= diff --git a/go.mod b/go.mod index 5edf9f68a..cf7a72f75 100644 --- a/go.mod +++ b/go.mod @@ -45,7 +45,7 @@ require ( github.com/ipfs/go-ipld-git v0.1.1 github.com/ipfs/go-ipld-legacy v0.1.1 github.com/ipfs/go-ipns v0.3.0 - github.com/ipfs/go-libipfs v0.4.1-0.20230130233950-a005a5006496 + github.com/ipfs/go-libipfs v0.4.1-0.20230202010411-6399b73f974c github.com/ipfs/go-log v1.0.5 github.com/ipfs/go-log/v2 v2.5.1 github.com/ipfs/go-merkledag v0.9.0 diff --git a/go.sum b/go.sum index fefe9bf71..1243d7896 100644 --- a/go.sum +++ b/go.sum @@ -570,8 +570,8 @@ github.com/ipfs/go-ipld-legacy v0.1.1 h1:BvD8PEuqwBHLTKqlGFTHSwrwFOMkVESEvwIYwR2 github.com/ipfs/go-ipld-legacy v0.1.1/go.mod h1:8AyKFCjgRPsQFf15ZQgDB8Din4DML/fOmKZkkFkrIEg= github.com/ipfs/go-ipns v0.3.0 h1:ai791nTgVo+zTuq2bLvEGmWP1M0A6kGTXUsgv/Yq67A= github.com/ipfs/go-ipns v0.3.0/go.mod h1:3cLT2rbvgPZGkHJoPO1YMJeh6LtkxopCkKFcio/wE24= -github.com/ipfs/go-libipfs v0.4.1-0.20230130233950-a005a5006496 h1:RVI31GQCFODREpasIFyVFkS6PjJT2bMwr/Bgr9Ryql4= -github.com/ipfs/go-libipfs v0.4.1-0.20230130233950-a005a5006496/go.mod h1:AAPvZADZ80i+QhGCWNWCsx8IGY0t9C+IBEngLeYtySY= +github.com/ipfs/go-libipfs v0.4.1-0.20230202010411-6399b73f974c h1:Z8GrWoG3VZWj0RvHnzKlyIyXh8sgCIw62O9t3jnhqyk= +github.com/ipfs/go-libipfs v0.4.1-0.20230202010411-6399b73f974c/go.mod h1:S5wg08D/FkeYxeMf8adgt6Mi6ttbA7kSFcQYlmeGHMU= github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= github.com/ipfs/go-log v1.0.2/go.mod h1:1MNjMxe0u6xvJZgeqbJ8vdo2TKaGwZ1a0Bpza+sr2Sk= github.com/ipfs/go-log v1.0.3/go.mod h1:OsLySYkwIbiSUR/yBTdv1qPtcE4FW3WPWk/ewz9Ru+A= diff --git a/test/sharness/t0111-gateway-writeable.sh b/test/sharness/t0111-gateway-writeable.sh index 53d4fc1aa..115114c89 100755 --- a/test/sharness/t0111-gateway-writeable.sh +++ b/test/sharness/t0111-gateway-writeable.sh @@ -34,6 +34,10 @@ test_expect_success "ipfs daemon up" ' test_fsh cat poll_apierr || test_fsh cat poll_apiout ' +test_expect_success "deprecation notice is printed when Gateway.Writable=true" ' + test_should_contain "legacy Gateway.Writable is DEPRECATED and will be removed or changed in future versions. If you are still using this, provide feedback in https://github.com/ipfs/specs/issues/375" daemon_err +' + test_expect_success "HTTP gateway gives access to sample file" ' curl -s -o welcome "http://$GWAY_ADDR/ipfs/$HASH_WELCOME_DOCS/readme" && grep "Hello and Welcome to IPFS!" welcome From b58356939e92729ab34e6c5e2615c67c7c4c1292 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Tue, 7 Feb 2023 03:44:24 +0100 Subject: [PATCH 0457/1212] refactor(gw): move Host (DNSLink and subdomain) handling to go-libipfs (#9624) Co-authored-by: Marcin Rataj --- core/corehttp/gateway.go | 152 +++++-- core/corehttp/hostname.go | 602 ------------------------- core/corehttp/hostname_test.go | 307 ------------- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 +- go.mod | 2 +- go.sum | 4 +- 7 files changed, 126 insertions(+), 947 deletions(-) delete mode 100644 core/corehttp/hostname.go delete mode 100644 core/corehttp/hostname_test.go diff --git a/core/corehttp/gateway.go b/core/corehttp/gateway.go index 3c7803036..c20ab6e4a 100644 --- a/core/corehttp/gateway.go +++ b/core/corehttp/gateway.go @@ -11,10 +11,13 @@ import ( "github.com/ipfs/go-libipfs/blocks" "github.com/ipfs/go-libipfs/files" "github.com/ipfs/go-libipfs/gateway" + "github.com/ipfs/go-namesys" iface "github.com/ipfs/interface-go-ipfs-core" options "github.com/ipfs/interface-go-ipfs-core/options" + nsopts "github.com/ipfs/interface-go-ipfs-core/options/namesys" "github.com/ipfs/interface-go-ipfs-core/path" version "github.com/ipfs/kubo" + config "github.com/ipfs/kubo/config" core "github.com/ipfs/kubo/core" coreapi "github.com/ipfs/kubo/core/coreapi" id "github.com/libp2p/go-libp2p/p2p/protocol/identify" @@ -40,55 +43,70 @@ func GatewayOption(writable bool, paths ...string) ServeOption { gateway.AddAccessControlHeaders(headers) - offlineAPI, err := api.WithOptions(options.Api.Offline(true)) + gwConfig := gateway.Config{ + Headers: headers, + } + + gwAPI, err := newGatewayAPI(n) if err != nil { return nil, err } - gatewayConfig := gateway.Config{ - Headers: headers, - } + gw := gateway.NewHandler(gwConfig, gwAPI) + gw = otelhttp.NewHandler(gw, "Gateway.Request") - gatewayAPI := &gatewayAPI{ - api: api, - offlineAPI: offlineAPI, - } + // By default, our HTTP handler is the gateway handler. + handler := gw.ServeHTTP - gateway := gateway.NewHandler(gatewayConfig, gatewayAPI) - gateway = otelhttp.NewHandler(gateway, "Gateway.Request") - - var writableGateway *writableGatewayHandler + // If we have the writable gateway enabled, we have to replace our + // http handler by a handler that takes care of the different methods. if writable { - writableGateway = &writableGatewayHandler{ - config: &gatewayConfig, + writableGw := &writableGatewayHandler{ + config: &gwConfig, api: api, } + + handler = func(w http.ResponseWriter, r *http.Request) { + switch r.Method { + case http.MethodPost: + writableGw.postHandler(w, r) + case http.MethodDelete: + writableGw.deleteHandler(w, r) + case http.MethodPut: + writableGw.putHandler(w, r) + default: + gw.ServeHTTP(w, r) + } + } } for _, p := range paths { - mux.HandleFunc(p+"/", func(w http.ResponseWriter, r *http.Request) { - if writable { - switch r.Method { - case http.MethodPost: - writableGateway.postHandler(w, r) - case http.MethodDelete: - writableGateway.deleteHandler(w, r) - case http.MethodPut: - writableGateway.putHandler(w, r) - default: - gateway.ServeHTTP(w, r) - } - - return - } - - gateway.ServeHTTP(w, r) - }) + mux.HandleFunc(p+"/", handler) } + return mux, nil } } +func HostnameOption() ServeOption { + return func(n *core.IpfsNode, _ net.Listener, mux *http.ServeMux) (*http.ServeMux, error) { + cfg, err := n.Repo.Config() + if err != nil { + return nil, err + } + + gwAPI, err := newGatewayAPI(n) + if err != nil { + return nil, err + } + + publicGateways := convertPublicGateways(cfg.Gateway.PublicGateways) + childMux := http.NewServeMux() + mux.HandleFunc("/", gateway.WithHostname(childMux, gwAPI, publicGateways, cfg.Gateway.NoDNSLink).ServeHTTP) + return childMux, nil + } +} + func VersionOption() ServeOption { return func(_ *core.IpfsNode, _ net.Listener, mux *http.ServeMux) (*http.ServeMux, error) { mux.HandleFunc("/version", func(w http.ResponseWriter, r *http.Request) { @@ -101,10 +119,33 @@ func VersionOption() ServeOption { } type gatewayAPI struct { + ns namesys.NameSystem api iface.CoreAPI offlineAPI iface.CoreAPI } +func newGatewayAPI(n *core.IpfsNode) (*gatewayAPI, error) { + cfg, err := n.Repo.Config() + if err != nil { + return nil, err + } + + api, err := coreapi.NewCoreAPI(n, options.Api.FetchBlocks(!cfg.Gateway.NoFetch)) + if err != nil { + return nil, err + } + offlineAPI, err := api.WithOptions(options.Api.Offline(true)) + if err != nil { + return nil, err + } + + return &gatewayAPI{ + ns: n.Namesys, + api: api, + offlineAPI: offlineAPI, + }, nil +} + func (gw *gatewayAPI) GetUnixFsNode(ctx context.Context, pth path.Resolved) (files.Node, error) { return gw.api.Unixfs().Get(ctx, pth) } @@ -137,6 +178,14 @@ func (gw *gatewayAPI) GetIPNSRecord(ctx context.Context, c cid.Cid) ([]byte, err return gw.api.Routing().Get(ctx, "/ipns/"+c.String()) } +func (gw *gatewayAPI) GetDNSLinkRecord(ctx context.Context, hostname string) (path.Path, error) { + p, err := gw.ns.Resolve(ctx, "/ipns/"+hostname, nsopts.Depth(1)) + if err == namesys.ErrResolveRecursion { + err = nil + } + return path.New(p.String()), err +} + func (gw *gatewayAPI) IsCached(ctx context.Context, pth path.Path) bool { _, err := gw.offlineAPI.Block().Stat(ctx, pth) return err == nil @@ -145,3 +194,42 @@ func (gw *gatewayAPI) IsCached(ctx context.Context, pth path.Path) bool { func (gw *gatewayAPI) ResolvePath(ctx context.Context, pth path.Path) (path.Resolved, error) { return gw.api.ResolvePath(ctx, pth) } + +var defaultPaths = []string{"/ipfs/", "/ipns/", "/api/", "/p2p/"} + +var subdomainGatewaySpec = &gateway.Specification{ + Paths: defaultPaths, + UseSubdomains: true, +} + +var defaultKnownGateways = map[string]*gateway.Specification{ + "localhost": subdomainGatewaySpec, +} + +func convertPublicGateways(publicGateways map[string]*config.GatewaySpec) map[string]*gateway.Specification { + gws := map[string]*gateway.Specification{} + + // First, implicit defaults such as subdomain gateway on localhost + for hostname, gw := range defaultKnownGateways { + gws[hostname] = gw + } + + // Then apply values from Gateway.PublicGateways, if present in the config + for hostname, gw := range publicGateways { + if gw == nil { + // Remove any implicit defaults, if present. This is useful when one + // wants to disable subdomain gateway on localhost etc. + delete(gws, hostname) + continue + } + + gws[hostname] = &gateway.Specification{ + Paths: gw.Paths, + NoDNSLink: gw.NoDNSLink, + UseSubdomains: gw.UseSubdomains, + InlineDNSLink: gw.InlineDNSLink.WithDefault(config.DefaultInlineDNSLink), + } + } + + return gws +} diff --git a/core/corehttp/hostname.go b/core/corehttp/hostname.go deleted file mode 100644 index adc47ab4d..000000000 --- a/core/corehttp/hostname.go +++ /dev/null @@ -1,602 +0,0 @@ -package corehttp - -import ( - "context" - "fmt" - "net" - "net/http" - "net/url" - "regexp" - "strings" - - cid "github.com/ipfs/go-cid" - "github.com/ipfs/go-libipfs/gateway" - namesys "github.com/ipfs/go-namesys" - core "github.com/ipfs/kubo/core" - coreapi "github.com/ipfs/kubo/core/coreapi" - "github.com/libp2p/go-libp2p/core/peer" - dns "github.com/miekg/dns" - - mbase "github.com/multiformats/go-multibase" - - iface "github.com/ipfs/interface-go-ipfs-core" - options "github.com/ipfs/interface-go-ipfs-core/options" - nsopts "github.com/ipfs/interface-go-ipfs-core/options/namesys" - config "github.com/ipfs/kubo/config" -) - -var defaultPaths = []string{"/ipfs/", "/ipns/", "/api/", "/p2p/"} - -var subdomainGatewaySpec = &config.GatewaySpec{ - Paths: defaultPaths, - UseSubdomains: true, -} - -var defaultKnownGateways = map[string]*config.GatewaySpec{ - "localhost": subdomainGatewaySpec, -} - -// Label's max length in DNS (https://tools.ietf.org/html/rfc1034#page-7) -const dnsLabelMaxLength int = 63 - -// HostnameOption rewrites an incoming request based on the Host header. -func HostnameOption() ServeOption { - return func(n *core.IpfsNode, _ net.Listener, mux *http.ServeMux) (*http.ServeMux, error) { - childMux := http.NewServeMux() - - coreAPI, err := coreapi.NewCoreAPI(n) - if err != nil { - return nil, err - } - - cfg, err := n.Repo.Config() - if err != nil { - return nil, err - } - - knownGateways := prepareKnownGateways(cfg.Gateway.PublicGateways) - - mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { - // Unfortunately, many (well, ipfs.io) gateways use - // DNSLink so if we blindly rewrite with DNSLink, we'll - // break /ipfs links. - // - // We fix this by maintaining a list of known gateways - // and the paths that they serve "gateway" content on. - // That way, we can use DNSLink for everything else. - - // Support X-Forwarded-Host if added by a reverse proxy - // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Host - host := r.Host - if xHost := r.Header.Get("X-Forwarded-Host"); xHost != "" { - host = xHost - } - - // HTTP Host & Path check: is this one of our "known gateways"? - if gw, ok := isKnownHostname(host, knownGateways); ok { - // This is a known gateway but request is not using - // the subdomain feature. - - // Does this gateway _handle_ this path? - if hasPrefix(r.URL.Path, gw.Paths...) { - // It does. - - // Should this gateway use subdomains instead of paths? - if gw.UseSubdomains { - // Yes, redirect if applicable - // Example: dweb.link/ipfs/{cid} → {cid}.ipfs.dweb.link - useInlinedDNSLink := gw.InlineDNSLink.WithDefault(config.DefaultInlineDNSLink) - newURL, err := toSubdomainURL(host, r.URL.Path, r, useInlinedDNSLink, coreAPI) - if err != nil { - http.Error(w, err.Error(), http.StatusBadRequest) - return - } - if newURL != "" { - // Set "Location" header with redirect destination. - // It is ignored by curl in default mode, but will - // be respected by user agents that follow - // redirects by default, namely web browsers - w.Header().Set("Location", newURL) - - // Note: we continue regular gateway processing: - // HTTP Status Code http.StatusMovedPermanently - // will be set later, in statusResponseWriter - } - } - - // Not a subdomain resource, continue with path processing - // Example: 127.0.0.1:8080/ipfs/{CID}, ipfs.io/ipfs/{CID} etc - childMux.ServeHTTP(w, r) - return - } - // Not a whitelisted path - - // Try DNSLink, if it was not explicitly disabled for the hostname - if !gw.NoDNSLink && isDNSLinkName(r.Context(), coreAPI, host) { - // rewrite path and handle as DNSLink - r.URL.Path = "/ipns/" + stripPort(host) + r.URL.Path - childMux.ServeHTTP(w, withHostnameContext(r, host)) - return - } - - // If not, resource does not exist on the hostname, return 404 - http.NotFound(w, r) - return - } - - // HTTP Host check: is this one of our subdomain-based "known gateways"? - // IPFS details extracted from the host: {rootID}.{ns}.{gwHostname} - // /ipfs/ example: {cid}.ipfs.localhost:8080, {cid}.ipfs.dweb.link - // /ipns/ example: {libp2p-key}.ipns.localhost:8080, {inlined-dnslink-fqdn}.ipns.dweb.link - if gw, gwHostname, ns, rootID, ok := knownSubdomainDetails(host, knownGateways); ok { - // Looks like we're using a known gateway in subdomain mode. - - // Assemble original path prefix. - pathPrefix := "/" + ns + "/" + rootID - - // Retrieve whether or not we should inline DNSLink. - useInlinedDNSLink := gw.InlineDNSLink.WithDefault(config.DefaultInlineDNSLink) - - // Does this gateway _handle_ subdomains AND this path? - if !(gw.UseSubdomains && hasPrefix(pathPrefix, gw.Paths...)) { - // If not, resource does not exist, return 404 - http.NotFound(w, r) - return - } - - // Check if rootID is a valid CID - if rootCID, err := cid.Decode(rootID); err == nil { - // Do we need to redirect root CID to a canonical DNS representation? - dnsCID, err := toDNSLabel(rootID, rootCID) - if err != nil { - http.Error(w, err.Error(), http.StatusBadRequest) - return - } - if !strings.HasPrefix(r.Host, dnsCID) { - dnsPrefix := "/" + ns + "/" + dnsCID - newURL, err := toSubdomainURL(gwHostname, dnsPrefix+r.URL.Path, r, useInlinedDNSLink, coreAPI) - if err != nil { - http.Error(w, err.Error(), http.StatusBadRequest) - return - } - if newURL != "" { - // Redirect to deterministic CID to ensure CID - // always gets the same Origin on the web - http.Redirect(w, r, newURL, http.StatusMovedPermanently) - return - } - } - - // Do we need to fix multicodec in PeerID represented as CIDv1? - if isPeerIDNamespace(ns) { - if rootCID.Type() != cid.Libp2pKey { - newURL, err := toSubdomainURL(gwHostname, pathPrefix+r.URL.Path, r, useInlinedDNSLink, coreAPI) - if err != nil { - http.Error(w, err.Error(), http.StatusBadRequest) - return - } - if newURL != "" { - // Redirect to CID fixed inside of toSubdomainURL() - http.Redirect(w, r, newURL, http.StatusMovedPermanently) - return - } - } - } - } else { // rootID is not a CID.. - - // Check if rootID is a single DNS label with an inlined - // DNSLink FQDN a single DNS label. We support this so - // loading DNSLink names over TLS "just works" on public - // HTTP gateways. - // - // Rationale for doing this can be found under "Option C" - // at: https://github.com/ipfs/in-web-browsers/issues/169 - // - // TLDR is: - // https://dweb.link/ipns/my.v-long.example.com - // can be loaded from a subdomain gateway with a wildcard - // TLS cert if represented as a single DNS label: - // https://my-v--long-example-com.ipns.dweb.link - if ns == "ipns" && !strings.Contains(rootID, ".") { - // if there is no TXT recordfor rootID - if !isDNSLinkName(r.Context(), coreAPI, rootID) { - // my-v--long-example-com → my.v-long.example.com - dnslinkFQDN := toDNSLinkFQDN(rootID) - if isDNSLinkName(r.Context(), coreAPI, dnslinkFQDN) { - // update path prefix to use real FQDN with DNSLink - pathPrefix = "/ipns/" + dnslinkFQDN - } - } - } - } - - // Rewrite the path to not use subdomains - r.URL.Path = pathPrefix + r.URL.Path - - // Serve path request - childMux.ServeHTTP(w, withHostnameContext(r, gwHostname)) - return - } - // We don't have a known gateway. Fallback on DNSLink lookup - - // Wildcard HTTP Host check: - // 1. is wildcard DNSLink enabled (Gateway.NoDNSLink=false)? - // 2. does Host header include a fully qualified domain name (FQDN)? - // 3. does DNSLink record exist in DNS? - if !cfg.Gateway.NoDNSLink && isDNSLinkName(r.Context(), coreAPI, host) { - // rewrite path and handle as DNSLink - r.URL.Path = "/ipns/" + stripPort(host) + r.URL.Path - ctx := context.WithValue(r.Context(), gateway.DNSLinkHostnameKey, host) - childMux.ServeHTTP(w, withHostnameContext(r.WithContext(ctx), host)) - return - } - - // else, treat it as an old school gateway, I guess. - childMux.ServeHTTP(w, r) - }) - return childMux, nil - } -} - -type gatewayHosts struct { - exact map[string]*config.GatewaySpec - wildcard []wildcardHost -} - -type wildcardHost struct { - re *regexp.Regexp - spec *config.GatewaySpec -} - -// Extends request context to include hostname of a canonical gateway root -// (subdomain root or dnslink fqdn) -func withHostnameContext(r *http.Request, hostname string) *http.Request { - // This is required for links on directory listing pages to work correctly - // on subdomain and dnslink gateways. While DNSlink could read value from - // Host header, subdomain gateways have more comples rules (knownSubdomainDetails) - // More: https://github.com/ipfs/dir-index-html/issues/42 - // nolint: staticcheck // non-backward compatible change - ctx := context.WithValue(r.Context(), gateway.GatewayHostnameKey, hostname) - return r.WithContext(ctx) -} - -func prepareKnownGateways(publicGateways map[string]*config.GatewaySpec) gatewayHosts { - var hosts gatewayHosts - - hosts.exact = make(map[string]*config.GatewaySpec, len(publicGateways)+len(defaultKnownGateways)) - - // First, implicit defaults such as subdomain gateway on localhost - for hostname, gw := range defaultKnownGateways { - hosts.exact[hostname] = gw - } - - // Then apply values from Gateway.PublicGateways, if present in the config - for hostname, gw := range publicGateways { - if gw == nil { - // Remove any implicit defaults, if present. This is useful when one - // wants to disable subdomain gateway on localhost etc. - delete(hosts.exact, hostname) - continue - } - if strings.Contains(hostname, "*") { - // from *.domain.tld, construct a regexp that match any direct subdomain - // of .domain.tld. - // - // Regexp will be in the form of ^[^.]+\.domain.tld(?::\d+)?$ - - escaped := strings.ReplaceAll(hostname, ".", `\.`) - regexed := strings.ReplaceAll(escaped, "*", "[^.]+") - - re, err := regexp.Compile(fmt.Sprintf(`^%s(?::\d+)?$`, regexed)) - if err != nil { - log.Warn("invalid wildcard gateway hostname \"%s\"", hostname) - } - - hosts.wildcard = append(hosts.wildcard, wildcardHost{re: re, spec: gw}) - } else { - hosts.exact[hostname] = gw - } - } - - return hosts -} - -// isKnownHostname checks Gateway.PublicGateways and returns matching -// GatewaySpec with graceful fallback to version without port -func isKnownHostname(hostname string, knownGateways gatewayHosts) (gw *config.GatewaySpec, ok bool) { - // Try hostname (host+optional port - value from Host header as-is) - if gw, ok := knownGateways.exact[hostname]; ok { - return gw, ok - } - // Also test without port - if gw, ok = knownGateways.exact[stripPort(hostname)]; ok { - return gw, ok - } - - // Wildcard support. Test both with and without port. - for _, host := range knownGateways.wildcard { - if host.re.MatchString(hostname) { - return host.spec, true - } - } - - return nil, false -} - -// Parses Host header and looks for a known gateway matching subdomain host. -// If found, returns GatewaySpec and subdomain components extracted from Host -// header: {rootID}.{ns}.{gwHostname} -// Note: hostname is host + optional port -func knownSubdomainDetails(hostname string, knownGateways gatewayHosts) (gw *config.GatewaySpec, gwHostname, ns, rootID string, ok bool) { - labels := strings.Split(hostname, ".") - // Look for FQDN of a known gateway hostname. - // Example: given "dist.ipfs.tech.ipns.dweb.link": - // 1. Lookup "link" TLD in knownGateways: negative - // 2. Lookup "dweb.link" in knownGateways: positive - // - // Stops when we have 2 or fewer labels left as we need at least a - // rootId and a namespace. - for i := len(labels) - 1; i >= 2; i-- { - fqdn := strings.Join(labels[i:], ".") - gw, ok := isKnownHostname(fqdn, knownGateways) - if !ok { - continue - } - - ns := labels[i-1] - if !isSubdomainNamespace(ns) { - continue - } - - // Merge remaining labels (could be a FQDN with DNSLink) - rootID := strings.Join(labels[:i-1], ".") - return gw, fqdn, ns, rootID, true - } - // no match - return nil, "", "", "", false -} - -// isDomainNameAndNotPeerID returns bool if string looks like a valid DNS name AND is not a PeerID -func isDomainNameAndNotPeerID(hostname string) bool { - if len(hostname) == 0 { - return false - } - if _, err := peer.Decode(hostname); err == nil { - return false - } - _, ok := dns.IsDomainName(hostname) - return ok -} - -// isDNSLinkName returns bool if a valid DNS TXT record exist for provided host -func isDNSLinkName(ctx context.Context, ipfs iface.CoreAPI, host string) bool { - dnslinkName := stripPort(host) - - if !isDomainNameAndNotPeerID(dnslinkName) { - return false - } - - name := "/ipns/" + dnslinkName - // check if DNSLink exists - depth := options.Name.ResolveOption(nsopts.Depth(1)) - _, err := ipfs.Name().Resolve(ctx, name, depth) - return err == nil || err == namesys.ErrResolveRecursion -} - -func isSubdomainNamespace(ns string) bool { - switch ns { - case "ipfs", "ipns", "p2p", "ipld": - return true - default: - return false - } -} - -func isPeerIDNamespace(ns string) bool { - switch ns { - case "ipns", "p2p": - return true - default: - return false - } -} - -// Converts a CID to DNS-safe representation that fits in 63 characters -func toDNSLabel(rootID string, rootCID cid.Cid) (dnsCID string, err error) { - // Return as-is if things fit - if len(rootID) <= dnsLabelMaxLength { - return rootID, nil - } - - // Convert to Base36 and see if that helped - rootID, err = cid.NewCidV1(rootCID.Type(), rootCID.Hash()).StringOfBase(mbase.Base36) - if err != nil { - return "", err - } - if len(rootID) <= dnsLabelMaxLength { - return rootID, nil - } - - // Can't win with DNS at this point, return error - return "", fmt.Errorf("CID incompatible with DNS label length limit of 63: %s", rootID) -} - -// Returns true if HTTP request involves TLS certificate. -// See https://github.com/ipfs/in-web-browsers/issues/169 to understand how it -// impacts DNSLink websites on public gateways. -func isHTTPSRequest(r *http.Request) bool { - // X-Forwarded-Proto if added by a reverse proxy - // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Proto - xproto := r.Header.Get("X-Forwarded-Proto") - // Is request a native TLS (not used atm, but future-proofing) - // or a proxied HTTPS (eg. go-ipfs behind nginx at a public gw)? - return r.URL.Scheme == "https" || xproto == "https" -} - -// Converts a FQDN to DNS-safe representation that fits in 63 characters: -// my.v-long.example.com → my-v--long-example-com -func toDNSLinkDNSLabel(fqdn string) (dnsLabel string, err error) { - dnsLabel = strings.ReplaceAll(fqdn, "-", "--") - dnsLabel = strings.ReplaceAll(dnsLabel, ".", "-") - if len(dnsLabel) > dnsLabelMaxLength { - return "", fmt.Errorf("DNSLink representation incompatible with DNS label length limit of 63: %s", dnsLabel) - } - return dnsLabel, nil -} - -// Converts a DNS-safe representation of DNSLink FQDN to real FQDN: -// my-v--long-example-com → my.v-long.example.com -func toDNSLinkFQDN(dnsLabel string) (fqdn string) { - fqdn = strings.ReplaceAll(dnsLabel, "--", "@") // @ placeholder is unused in DNS labels - fqdn = strings.ReplaceAll(fqdn, "-", ".") - fqdn = strings.ReplaceAll(fqdn, "@", "-") - return fqdn -} - -// Converts a hostname/path to a subdomain-based URL, if applicable. -func toSubdomainURL(hostname, path string, r *http.Request, inlineDNSLink bool, ipfs iface.CoreAPI) (redirURL string, err error) { - var scheme, ns, rootID, rest string - - query := r.URL.RawQuery - parts := strings.SplitN(path, "/", 4) - isHTTPS := isHTTPSRequest(r) - safeRedirectURL := func(in string) (out string, err error) { - safeURI, err := url.ParseRequestURI(in) - if err != nil { - return "", err - } - return safeURI.String(), nil - } - - if isHTTPS { - scheme = "https:" - } else { - scheme = "http:" - } - - switch len(parts) { - case 4: - rest = parts[3] - fallthrough - case 3: - ns = parts[1] - rootID = parts[2] - default: - return "", nil - } - - if !isSubdomainNamespace(ns) { - return "", nil - } - - // add prefix if query is present - if query != "" { - query = "?" + query - } - - // Normalize problematic PeerIDs (eg. ed25519+identity) to CID representation - if isPeerIDNamespace(ns) && !isDomainNameAndNotPeerID(rootID) { - peerID, err := peer.Decode(rootID) - // Note: PeerID CIDv1 with protobuf multicodec will fail, but we fix it - // in the next block - if err == nil { - rootID = peer.ToCid(peerID).String() - } - } - - // If rootID is a CID, ensure it uses DNS-friendly text representation - if rootCID, err := cid.Decode(rootID); err == nil { - multicodec := rootCID.Type() - var base mbase.Encoding = mbase.Base32 - - // Normalizations specific to /ipns/{libp2p-key} - if isPeerIDNamespace(ns) { - // Using Base36 for /ipns/ for consistency - // Context: https://github.com/ipfs/kubo/pull/7441#discussion_r452372828 - base = mbase.Base36 - - // PeerIDs represented as CIDv1 are expected to have libp2p-key - // multicodec (https://github.com/libp2p/specs/pull/209). - // We ease the transition by fixing multicodec on the fly: - // https://github.com/ipfs/kubo/issues/5287#issuecomment-492163929 - if multicodec != cid.Libp2pKey { - multicodec = cid.Libp2pKey - } - } - - // Ensure CID text representation used in subdomain is compatible - // with the way DNS and URIs are implemented in user agents. - // - // 1. Switch to CIDv1 and enable case-insensitive Base encoding - // to avoid issues when user agent force-lowercases the hostname - // before making the request - // (https://github.com/ipfs/in-web-browsers/issues/89) - rootCID = cid.NewCidV1(multicodec, rootCID.Hash()) - rootID, err = rootCID.StringOfBase(base) - if err != nil { - return "", err - } - // 2. Make sure CID fits in a DNS label, adjust encoding if needed - // (https://github.com/ipfs/kubo/issues/7318) - rootID, err = toDNSLabel(rootID, rootCID) - if err != nil { - return "", err - } - } else { // rootID is not a CID - - // Check if rootID is a FQDN with DNSLink and convert it to TLS-safe - // representation that fits in a single DNS label. We support this so - // loading DNSLink names over TLS "just works" on public HTTP gateways - // that pass 'https' in X-Forwarded-Proto to go-ipfs. - // - // Rationale can be found under "Option C" - // at: https://github.com/ipfs/in-web-browsers/issues/169 - // - // TLDR is: - // /ipns/my.v-long.example.com - // can be loaded from a subdomain gateway with a wildcard TLS cert if - // represented as a single DNS label: - // https://my-v--long-example-com.ipns.dweb.link - if (inlineDNSLink || isHTTPS) && ns == "ipns" && strings.Contains(rootID, ".") { - if isDNSLinkName(r.Context(), ipfs, rootID) { - // my.v-long.example.com → my-v--long-example-com - dnsLabel, err := toDNSLinkDNSLabel(rootID) - if err != nil { - return "", err - } - // update path prefix to use real FQDN with DNSLink - rootID = dnsLabel - } - } - } - - return safeRedirectURL(fmt.Sprintf( - "%s//%s.%s.%s/%s%s", - scheme, - rootID, - ns, - hostname, - rest, - query, - )) -} - -func hasPrefix(path string, prefixes ...string) bool { - for _, prefix := range prefixes { - // Assume people are creative with trailing slashes in Gateway config - p := strings.TrimSuffix(prefix, "/") - // Support for both /version and /ipfs/$cid - if p == path || strings.HasPrefix(path, p+"/") { - return true - } - } - return false -} - -func stripPort(hostname string) string { - host, _, err := net.SplitHostPort(hostname) - if err == nil { - return host - } - return hostname -} diff --git a/core/corehttp/hostname_test.go b/core/corehttp/hostname_test.go deleted file mode 100644 index b4a8b8d16..000000000 --- a/core/corehttp/hostname_test.go +++ /dev/null @@ -1,307 +0,0 @@ -package corehttp - -import ( - "errors" - "net/http" - "net/http/httptest" - "testing" - - cid "github.com/ipfs/go-cid" - "github.com/ipfs/go-libipfs/files" - path "github.com/ipfs/go-path" - config "github.com/ipfs/kubo/config" - coreapi "github.com/ipfs/kubo/core/coreapi" -) - -func TestToSubdomainURL(t *testing.T) { - ns := mockNamesys{} - n, err := newNodeWithMockNamesys(ns) - if err != nil { - t.Fatal(err) - } - coreAPI, err := coreapi.NewCoreAPI(n) - if err != nil { - t.Fatal(err) - } - testCID, err := coreAPI.Unixfs().Add(n.Context(), files.NewBytesFile([]byte("fnord"))) - if err != nil { - t.Fatal(err) - } - ns["/ipns/dnslink.long-name.example.com"] = path.FromString(testCID.String()) - ns["/ipns/dnslink.too-long.f1siqrebi3vir8sab33hu5vcy008djegvay6atmz91ojesyjs8lx350b7y7i1nvyw2haytfukfyu2f2x4tocdrfa0zgij6p4zpl4u5o.example.com"] = path.FromString(testCID.String()) - httpRequest := httptest.NewRequest("GET", "http://127.0.0.1:8080", nil) - httpsRequest := httptest.NewRequest("GET", "https://https-request-stub.example.com", nil) - httpsProxiedRequest := httptest.NewRequest("GET", "http://proxied-https-request-stub.example.com", nil) - httpsProxiedRequest.Header.Set("X-Forwarded-Proto", "https") - - for _, test := range []struct { - // in: - request *http.Request - gwHostname string - inlineDNSLink bool - path string - // out: - url string - err error - }{ - // DNSLink - {httpRequest, "localhost", false, "/ipns/dnslink.io", "http://dnslink.io.ipns.localhost/", nil}, - // Hostname with port - {httpRequest, "localhost:8080", false, "/ipns/dnslink.io", "http://dnslink.io.ipns.localhost:8080/", nil}, - // CIDv0 → CIDv1base32 - {httpRequest, "localhost", false, "/ipfs/QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n", "http://bafybeif7a7gdklt6hodwdrmwmxnhksctcuav6lfxlcyfz4khzl3qfmvcgu.ipfs.localhost/", nil}, - // CIDv1 with long sha512 - {httpRequest, "localhost", false, "/ipfs/bafkrgqe3ohjcjplc6n4f3fwunlj6upltggn7xqujbsvnvyw764srszz4u4rshq6ztos4chl4plgg4ffyyxnayrtdi5oc4xb2332g645433aeg", "", errors.New("CID incompatible with DNS label length limit of 63: kf1siqrebi3vir8sab33hu5vcy008djegvay6atmz91ojesyjs8lx350b7y7i1nvyw2haytfukfyu2f2x4tocdrfa0zgij6p4zpl4u5oj")}, - // PeerID as CIDv1 needs to have libp2p-key multicodec - {httpRequest, "localhost", false, "/ipns/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", "http://k2k4r8n0flx3ra0y5dr8fmyvwbzy3eiztmtq6th694k5a3rznayp3e4o.ipns.localhost/", nil}, - {httpRequest, "localhost", false, "/ipns/bafybeickencdqw37dpz3ha36ewrh4undfjt2do52chtcky4rxkj447qhdm", "http://k2k4r8l9ja7hkzynavdqup76ou46tnvuaqegbd04a4o1mpbsey0meucb.ipns.localhost/", nil}, - // PeerID: ed25519+identity multihash → CIDv1Base36 - {httpRequest, "localhost", false, "/ipns/12D3KooWFB51PRY9BxcXSH6khFXw1BZeszeLDy7C8GciskqCTZn5", "http://k51qzi5uqu5di608geewp3nqkg0bpujoasmka7ftkyxgcm3fh1aroup0gsdrna.ipns.localhost/", nil}, - {httpRequest, "sub.localhost", false, "/ipfs/QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n", "http://bafybeif7a7gdklt6hodwdrmwmxnhksctcuav6lfxlcyfz4khzl3qfmvcgu.ipfs.sub.localhost/", nil}, - // HTTPS requires DNSLink name to fit in a single DNS label – see "Option C" from https://github.com/ipfs/in-web-browsers/issues/169 - {httpRequest, "dweb.link", false, "/ipns/dnslink.long-name.example.com", "http://dnslink.long-name.example.com.ipns.dweb.link/", nil}, - {httpsRequest, "dweb.link", false, "/ipns/dnslink.long-name.example.com", "https://dnslink-long--name-example-com.ipns.dweb.link/", nil}, - {httpsProxiedRequest, "dweb.link", false, "/ipns/dnslink.long-name.example.com", "https://dnslink-long--name-example-com.ipns.dweb.link/", nil}, - // HTTP requests can also be converted to fit into a single DNS label - https://github.com/ipfs/kubo/issues/9243 - {httpRequest, "localhost", true, "/ipns/dnslink.long-name.example.com", "http://dnslink-long--name-example-com.ipns.localhost/", nil}, - {httpRequest, "dweb.link", true, "/ipns/dnslink.long-name.example.com", "http://dnslink-long--name-example-com.ipns.dweb.link/", nil}, - } { - url, err := toSubdomainURL(test.gwHostname, test.path, test.request, test.inlineDNSLink, coreAPI) - if url != test.url || !equalError(err, test.err) { - t.Errorf("(%s, %v, %s) returned (%s, %v), expected (%s, %v)", test.gwHostname, test.inlineDNSLink, test.path, url, err, test.url, test.err) - } - } -} - -func TestToDNSLinkDNSLabel(t *testing.T) { - for _, test := range []struct { - in string - out string - err error - }{ - {"dnslink.long-name.example.com", "dnslink-long--name-example-com", nil}, - {"dnslink.too-long.f1siqrebi3vir8sab33hu5vcy008djegvay6atmz91ojesyjs8lx350b7y7i1nvyw2haytfukfyu2f2x4tocdrfa0zgij6p4zpl4u5o.example.com", "", errors.New("DNSLink representation incompatible with DNS label length limit of 63: dnslink-too--long-f1siqrebi3vir8sab33hu5vcy008djegvay6atmz91ojesyjs8lx350b7y7i1nvyw2haytfukfyu2f2x4tocdrfa0zgij6p4zpl4u5o-example-com")}, - } { - out, err := toDNSLinkDNSLabel(test.in) - if out != test.out || !equalError(err, test.err) { - t.Errorf("(%s) returned (%s, %v), expected (%s, %v)", test.in, out, err, test.out, test.err) - } - } -} - -func TestToDNSLinkFQDN(t *testing.T) { - for _, test := range []struct { - in string - out string - }{ - {"singlelabel", "singlelabel"}, - {"docs-ipfs-tech", "docs.ipfs.tech"}, - {"dnslink-long--name-example-com", "dnslink.long-name.example.com"}, - } { - out := toDNSLinkFQDN(test.in) - if out != test.out { - t.Errorf("(%s) returned (%s), expected (%s)", test.in, out, test.out) - } - } -} - -func TestIsHTTPSRequest(t *testing.T) { - httpRequest := httptest.NewRequest("GET", "http://127.0.0.1:8080", nil) - httpsRequest := httptest.NewRequest("GET", "https://https-request-stub.example.com", nil) - httpsProxiedRequest := httptest.NewRequest("GET", "http://proxied-https-request-stub.example.com", nil) - httpsProxiedRequest.Header.Set("X-Forwarded-Proto", "https") - httpProxiedRequest := httptest.NewRequest("GET", "http://proxied-http-request-stub.example.com", nil) - httpProxiedRequest.Header.Set("X-Forwarded-Proto", "http") - oddballRequest := httptest.NewRequest("GET", "foo://127.0.0.1:8080", nil) - for _, test := range []struct { - in *http.Request - out bool - }{ - {httpRequest, false}, - {httpsRequest, true}, - {httpsProxiedRequest, true}, - {httpProxiedRequest, false}, - {oddballRequest, false}, - } { - out := isHTTPSRequest(test.in) - if out != test.out { - t.Errorf("(%+v): returned %t, expected %t", test.in, out, test.out) - } - } -} - -func TestHasPrefix(t *testing.T) { - for _, test := range []struct { - prefixes []string - path string - out bool - }{ - {[]string{"/ipfs"}, "/ipfs/cid", true}, - {[]string{"/ipfs/"}, "/ipfs/cid", true}, - {[]string{"/version/"}, "/version", true}, - {[]string{"/version"}, "/version", true}, - } { - out := hasPrefix(test.path, test.prefixes...) - if out != test.out { - t.Errorf("(%+v, %s) returned '%t', expected '%t'", test.prefixes, test.path, out, test.out) - } - } -} - -func TestIsDomainNameAndNotPeerID(t *testing.T) { - for _, test := range []struct { - hostname string - out bool - }{ - {"", false}, - {"example.com", true}, - {"non-icann.something", true}, - {"..", false}, - {"12D3KooWFB51PRY9BxcXSH6khFXw1BZeszeLDy7C8GciskqCTZn5", false}, // valid peerid - {"k51qzi5uqu5di608geewp3nqkg0bpujoasmka7ftkyxgcm3fh1aroup0gsdrna", false}, // valid peerid - } { - out := isDomainNameAndNotPeerID(test.hostname) - if out != test.out { - t.Errorf("(%s) returned '%t', expected '%t'", test.hostname, out, test.out) - } - } -} - -func TestPortStripping(t *testing.T) { - for _, test := range []struct { - in string - out string - }{ - {"localhost:8080", "localhost"}, - {"bafkreicysg23kiwv34eg2d7qweipxwosdo2py4ldv42nbauguluen5v6am.ipfs.localhost:8080", "bafkreicysg23kiwv34eg2d7qweipxwosdo2py4ldv42nbauguluen5v6am.ipfs.localhost"}, - {"example.com:443", "example.com"}, - {"example.com", "example.com"}, - {"foo-dweb.ipfs.pvt.k12.ma.us:8080", "foo-dweb.ipfs.pvt.k12.ma.us"}, - {"localhost", "localhost"}, - {"[::1]:8080", "::1"}, - } { - out := stripPort(test.in) - if out != test.out { - t.Errorf("(%s): returned '%s', expected '%s'", test.in, out, test.out) - } - } -} - -func TestToDNSLabel(t *testing.T) { - for _, test := range []struct { - in string - out string - err error - }{ - // <= 63 - {"QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n", "QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n", nil}, - {"bafybeickencdqw37dpz3ha36ewrh4undfjt2do52chtcky4rxkj447qhdm", "bafybeickencdqw37dpz3ha36ewrh4undfjt2do52chtcky4rxkj447qhdm", nil}, - // > 63 - // PeerID: ed25519+identity multihash → CIDv1Base36 - {"bafzaajaiaejca4syrpdu6gdx4wsdnokxkprgzxf4wrstuc34gxw5k5jrag2so5gk", "k51qzi5uqu5dj16qyiq0tajolkojyl9qdkr254920wxv7ghtuwcz593tp69z9m", nil}, - // CIDv1 with long sha512 → error - {"bafkrgqe3ohjcjplc6n4f3fwunlj6upltggn7xqujbsvnvyw764srszz4u4rshq6ztos4chl4plgg4ffyyxnayrtdi5oc4xb2332g645433aeg", "", errors.New("CID incompatible with DNS label length limit of 63: kf1siqrebi3vir8sab33hu5vcy008djegvay6atmz91ojesyjs8lx350b7y7i1nvyw2haytfukfyu2f2x4tocdrfa0zgij6p4zpl4u5oj")}, - } { - inCID, _ := cid.Decode(test.in) - out, err := toDNSLabel(test.in, inCID) - if out != test.out || !equalError(err, test.err) { - t.Errorf("(%s): returned (%s, %v) expected (%s, %v)", test.in, out, err, test.out, test.err) - } - } - -} - -func TestKnownSubdomainDetails(t *testing.T) { - gwLocalhost := &config.GatewaySpec{Paths: []string{"/ipfs", "/ipns", "/api"}, UseSubdomains: true} - gwDweb := &config.GatewaySpec{Paths: []string{"/ipfs", "/ipns", "/api"}, UseSubdomains: true} - gwLong := &config.GatewaySpec{Paths: []string{"/ipfs", "/ipns", "/api"}, UseSubdomains: true} - gwWildcard1 := &config.GatewaySpec{Paths: []string{"/ipfs", "/ipns", "/api"}, UseSubdomains: true} - gwWildcard2 := &config.GatewaySpec{Paths: []string{"/ipfs", "/ipns", "/api"}, UseSubdomains: true} - - knownGateways := prepareKnownGateways(map[string]*config.GatewaySpec{ - "localhost": gwLocalhost, - "dweb.link": gwDweb, - "devgateway.dweb.link": gwDweb, - "dweb.ipfs.pvt.k12.ma.us": gwLong, // note the sneaky ".ipfs." ;-) - "*.wildcard1.tld": gwWildcard1, - "*.*.wildcard2.tld": gwWildcard2, - }) - - for _, test := range []struct { - // in: - hostHeader string - // out: - gw *config.GatewaySpec - hostname string - ns string - rootID string - ok bool - }{ - // no subdomain - {"127.0.0.1:8080", nil, "", "", "", false}, - {"[::1]:8080", nil, "", "", "", false}, - {"hey.look.example.com", nil, "", "", "", false}, - {"dweb.link", nil, "", "", "", false}, - // malformed Host header - {".....dweb.link", nil, "", "", "", false}, - {"link", nil, "", "", "", false}, - {"8080:dweb.link", nil, "", "", "", false}, - {" ", nil, "", "", "", false}, - {"", nil, "", "", "", false}, - // unknown gateway host - {"bafkreicysg23kiwv34eg2d7qweipxwosdo2py4ldv42nbauguluen5v6am.ipfs.unknown.example.com", nil, "", "", "", false}, - // cid in subdomain, known gateway - {"bafkreicysg23kiwv34eg2d7qweipxwosdo2py4ldv42nbauguluen5v6am.ipfs.localhost:8080", gwLocalhost, "localhost:8080", "ipfs", "bafkreicysg23kiwv34eg2d7qweipxwosdo2py4ldv42nbauguluen5v6am", true}, - {"bafkreicysg23kiwv34eg2d7qweipxwosdo2py4ldv42nbauguluen5v6am.ipfs.dweb.link", gwDweb, "dweb.link", "ipfs", "bafkreicysg23kiwv34eg2d7qweipxwosdo2py4ldv42nbauguluen5v6am", true}, - {"bafkreicysg23kiwv34eg2d7qweipxwosdo2py4ldv42nbauguluen5v6am.ipfs.devgateway.dweb.link", gwDweb, "devgateway.dweb.link", "ipfs", "bafkreicysg23kiwv34eg2d7qweipxwosdo2py4ldv42nbauguluen5v6am", true}, - // capture everything before .ipfs. - {"foo.bar.boo-buzz.ipfs.dweb.link", gwDweb, "dweb.link", "ipfs", "foo.bar.boo-buzz", true}, - // ipns - {"bafzbeihe35nmjqar22thmxsnlsgxppd66pseq6tscs4mo25y55juhh6bju.ipns.localhost:8080", gwLocalhost, "localhost:8080", "ipns", "bafzbeihe35nmjqar22thmxsnlsgxppd66pseq6tscs4mo25y55juhh6bju", true}, - {"bafzbeihe35nmjqar22thmxsnlsgxppd66pseq6tscs4mo25y55juhh6bju.ipns.dweb.link", gwDweb, "dweb.link", "ipns", "bafzbeihe35nmjqar22thmxsnlsgxppd66pseq6tscs4mo25y55juhh6bju", true}, - // edge case check: public gateway under long TLD (see: https://publicsuffix.org) - {"bafkreicysg23kiwv34eg2d7qweipxwosdo2py4ldv42nbauguluen5v6am.ipfs.dweb.ipfs.pvt.k12.ma.us", gwLong, "dweb.ipfs.pvt.k12.ma.us", "ipfs", "bafkreicysg23kiwv34eg2d7qweipxwosdo2py4ldv42nbauguluen5v6am", true}, - {"bafzbeihe35nmjqar22thmxsnlsgxppd66pseq6tscs4mo25y55juhh6bju.ipns.dweb.ipfs.pvt.k12.ma.us", gwLong, "dweb.ipfs.pvt.k12.ma.us", "ipns", "bafzbeihe35nmjqar22thmxsnlsgxppd66pseq6tscs4mo25y55juhh6bju", true}, - // dnslink in subdomain - {"en.wikipedia-on-ipfs.org.ipns.localhost:8080", gwLocalhost, "localhost:8080", "ipns", "en.wikipedia-on-ipfs.org", true}, - {"en.wikipedia-on-ipfs.org.ipns.localhost", gwLocalhost, "localhost", "ipns", "en.wikipedia-on-ipfs.org", true}, - {"dist.ipfs.tech.ipns.localhost:8080", gwLocalhost, "localhost:8080", "ipns", "dist.ipfs.tech", true}, - {"en.wikipedia-on-ipfs.org.ipns.dweb.link", gwDweb, "dweb.link", "ipns", "en.wikipedia-on-ipfs.org", true}, - // edge case check: public gateway under long TLD (see: https://publicsuffix.org) - {"foo.dweb.ipfs.pvt.k12.ma.us", nil, "", "", "", false}, - {"bafkreicysg23kiwv34eg2d7qweipxwosdo2py4ldv42nbauguluen5v6am.ipfs.dweb.ipfs.pvt.k12.ma.us", gwLong, "dweb.ipfs.pvt.k12.ma.us", "ipfs", "bafkreicysg23kiwv34eg2d7qweipxwosdo2py4ldv42nbauguluen5v6am", true}, - {"bafzbeihe35nmjqar22thmxsnlsgxppd66pseq6tscs4mo25y55juhh6bju.ipns.dweb.ipfs.pvt.k12.ma.us", gwLong, "dweb.ipfs.pvt.k12.ma.us", "ipns", "bafzbeihe35nmjqar22thmxsnlsgxppd66pseq6tscs4mo25y55juhh6bju", true}, - // other namespaces - {"api.localhost", nil, "", "", "", false}, - {"peerid.p2p.localhost", gwLocalhost, "localhost", "p2p", "peerid", true}, - // wildcards - {"wildcard1.tld", nil, "", "", "", false}, - {".wildcard1.tld", nil, "", "", "", false}, - {"bafkreicysg23kiwv34eg2d7qweipxwosdo2py4ldv42nbauguluen5v6am.ipfs.wildcard1.tld", nil, "", "", "", false}, - {"bafkreicysg23kiwv34eg2d7qweipxwosdo2py4ldv42nbauguluen5v6am.ipfs.sub.wildcard1.tld", gwWildcard1, "sub.wildcard1.tld", "ipfs", "bafkreicysg23kiwv34eg2d7qweipxwosdo2py4ldv42nbauguluen5v6am", true}, - {"bafkreicysg23kiwv34eg2d7qweipxwosdo2py4ldv42nbauguluen5v6am.ipfs.sub1.sub2.wildcard1.tld", nil, "", "", "", false}, - {"bafkreicysg23kiwv34eg2d7qweipxwosdo2py4ldv42nbauguluen5v6am.ipfs.sub1.sub2.wildcard2.tld", gwWildcard2, "sub1.sub2.wildcard2.tld", "ipfs", "bafkreicysg23kiwv34eg2d7qweipxwosdo2py4ldv42nbauguluen5v6am", true}, - } { - gw, hostname, ns, rootID, ok := knownSubdomainDetails(test.hostHeader, knownGateways) - if ok != test.ok { - t.Errorf("knownSubdomainDetails(%s): ok is %t, expected %t", test.hostHeader, ok, test.ok) - } - if rootID != test.rootID { - t.Errorf("knownSubdomainDetails(%s): rootID is '%s', expected '%s'", test.hostHeader, rootID, test.rootID) - } - if ns != test.ns { - t.Errorf("knownSubdomainDetails(%s): ns is '%s', expected '%s'", test.hostHeader, ns, test.ns) - } - if hostname != test.hostname { - t.Errorf("knownSubdomainDetails(%s): hostname is '%s', expected '%s'", test.hostHeader, hostname, test.hostname) - } - if gw != test.gw { - t.Errorf("knownSubdomainDetails(%s): gw is %+v, expected %+v", test.hostHeader, gw, test.gw) - } - } - -} - -func equalError(a, b error) bool { - return (a == nil && b == nil) || (a != nil && b != nil && a.Error() == b.Error()) -} diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 2b739db84..59788314a 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.18 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/go-libipfs v0.4.1-0.20230202010411-6399b73f974c + github.com/ipfs/go-libipfs v0.4.1-0.20230207021459-1a932f7bb3c1 github.com/ipfs/interface-go-ipfs-core v0.10.0 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.24.2 diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index f286c50ad..38c57bd0d 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -548,8 +548,8 @@ github.com/ipfs/go-ipld-legacy v0.1.1 h1:BvD8PEuqwBHLTKqlGFTHSwrwFOMkVESEvwIYwR2 github.com/ipfs/go-ipld-legacy v0.1.1/go.mod h1:8AyKFCjgRPsQFf15ZQgDB8Din4DML/fOmKZkkFkrIEg= github.com/ipfs/go-ipns v0.3.0 h1:ai791nTgVo+zTuq2bLvEGmWP1M0A6kGTXUsgv/Yq67A= github.com/ipfs/go-ipns v0.3.0/go.mod h1:3cLT2rbvgPZGkHJoPO1YMJeh6LtkxopCkKFcio/wE24= -github.com/ipfs/go-libipfs v0.4.1-0.20230202010411-6399b73f974c h1:Z8GrWoG3VZWj0RvHnzKlyIyXh8sgCIw62O9t3jnhqyk= -github.com/ipfs/go-libipfs v0.4.1-0.20230202010411-6399b73f974c/go.mod h1:S5wg08D/FkeYxeMf8adgt6Mi6ttbA7kSFcQYlmeGHMU= +github.com/ipfs/go-libipfs v0.4.1-0.20230207021459-1a932f7bb3c1 h1:drLEvJmJM0UrXvQfMF84EqSeGSXl5Elk/PAcc0XnNb4= +github.com/ipfs/go-libipfs v0.4.1-0.20230207021459-1a932f7bb3c1/go.mod h1:XKRXmSlJ32qlpxGN+mdGJJXUl/Z055etN1xpMEaANQ8= github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= github.com/ipfs/go-log v1.0.2/go.mod h1:1MNjMxe0u6xvJZgeqbJ8vdo2TKaGwZ1a0Bpza+sr2Sk= github.com/ipfs/go-log v1.0.3/go.mod h1:OsLySYkwIbiSUR/yBTdv1qPtcE4FW3WPWk/ewz9Ru+A= diff --git a/go.mod b/go.mod index cf7a72f75..3211f4e12 100644 --- a/go.mod +++ b/go.mod @@ -45,7 +45,7 @@ require ( github.com/ipfs/go-ipld-git v0.1.1 github.com/ipfs/go-ipld-legacy v0.1.1 github.com/ipfs/go-ipns v0.3.0 - github.com/ipfs/go-libipfs v0.4.1-0.20230202010411-6399b73f974c + github.com/ipfs/go-libipfs v0.4.1-0.20230207021459-1a932f7bb3c1 github.com/ipfs/go-log v1.0.5 github.com/ipfs/go-log/v2 v2.5.1 github.com/ipfs/go-merkledag v0.9.0 diff --git a/go.sum b/go.sum index 1243d7896..dd5945e44 100644 --- a/go.sum +++ b/go.sum @@ -570,8 +570,8 @@ github.com/ipfs/go-ipld-legacy v0.1.1 h1:BvD8PEuqwBHLTKqlGFTHSwrwFOMkVESEvwIYwR2 github.com/ipfs/go-ipld-legacy v0.1.1/go.mod h1:8AyKFCjgRPsQFf15ZQgDB8Din4DML/fOmKZkkFkrIEg= github.com/ipfs/go-ipns v0.3.0 h1:ai791nTgVo+zTuq2bLvEGmWP1M0A6kGTXUsgv/Yq67A= github.com/ipfs/go-ipns v0.3.0/go.mod h1:3cLT2rbvgPZGkHJoPO1YMJeh6LtkxopCkKFcio/wE24= -github.com/ipfs/go-libipfs v0.4.1-0.20230202010411-6399b73f974c h1:Z8GrWoG3VZWj0RvHnzKlyIyXh8sgCIw62O9t3jnhqyk= -github.com/ipfs/go-libipfs v0.4.1-0.20230202010411-6399b73f974c/go.mod h1:S5wg08D/FkeYxeMf8adgt6Mi6ttbA7kSFcQYlmeGHMU= +github.com/ipfs/go-libipfs v0.4.1-0.20230207021459-1a932f7bb3c1 h1:drLEvJmJM0UrXvQfMF84EqSeGSXl5Elk/PAcc0XnNb4= +github.com/ipfs/go-libipfs v0.4.1-0.20230207021459-1a932f7bb3c1/go.mod h1:XKRXmSlJ32qlpxGN+mdGJJXUl/Z055etN1xpMEaANQ8= github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= github.com/ipfs/go-log v1.0.2/go.mod h1:1MNjMxe0u6xvJZgeqbJ8vdo2TKaGwZ1a0Bpza+sr2Sk= github.com/ipfs/go-log v1.0.3/go.mod h1:OsLySYkwIbiSUR/yBTdv1qPtcE4FW3WPWk/ewz9Ru+A= From 799e5ac0a5a6600e844aad585282ad23789a88e7 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Wed, 8 Feb 2023 04:21:06 +0100 Subject: [PATCH 0458/1212] chore: update go-libipfs for more gateway metrics (#9626) --- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 59788314a..df5abfdc6 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.18 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/go-libipfs v0.4.1-0.20230207021459-1a932f7bb3c1 + github.com/ipfs/go-libipfs v0.4.1-0.20230208022905-378aaf777cf9 github.com/ipfs/interface-go-ipfs-core v0.10.0 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.24.2 diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 38c57bd0d..53c239273 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -548,8 +548,8 @@ github.com/ipfs/go-ipld-legacy v0.1.1 h1:BvD8PEuqwBHLTKqlGFTHSwrwFOMkVESEvwIYwR2 github.com/ipfs/go-ipld-legacy v0.1.1/go.mod h1:8AyKFCjgRPsQFf15ZQgDB8Din4DML/fOmKZkkFkrIEg= github.com/ipfs/go-ipns v0.3.0 h1:ai791nTgVo+zTuq2bLvEGmWP1M0A6kGTXUsgv/Yq67A= github.com/ipfs/go-ipns v0.3.0/go.mod h1:3cLT2rbvgPZGkHJoPO1YMJeh6LtkxopCkKFcio/wE24= -github.com/ipfs/go-libipfs v0.4.1-0.20230207021459-1a932f7bb3c1 h1:drLEvJmJM0UrXvQfMF84EqSeGSXl5Elk/PAcc0XnNb4= -github.com/ipfs/go-libipfs v0.4.1-0.20230207021459-1a932f7bb3c1/go.mod h1:XKRXmSlJ32qlpxGN+mdGJJXUl/Z055etN1xpMEaANQ8= +github.com/ipfs/go-libipfs v0.4.1-0.20230208022905-378aaf777cf9 h1:m3h1qk9cuH2aqiILynVqF69UmmdOiNTSq6CnHK9GVuQ= +github.com/ipfs/go-libipfs v0.4.1-0.20230208022905-378aaf777cf9/go.mod h1:XKRXmSlJ32qlpxGN+mdGJJXUl/Z055etN1xpMEaANQ8= github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= github.com/ipfs/go-log v1.0.2/go.mod h1:1MNjMxe0u6xvJZgeqbJ8vdo2TKaGwZ1a0Bpza+sr2Sk= github.com/ipfs/go-log v1.0.3/go.mod h1:OsLySYkwIbiSUR/yBTdv1qPtcE4FW3WPWk/ewz9Ru+A= diff --git a/go.mod b/go.mod index 3211f4e12..e724c0888 100644 --- a/go.mod +++ b/go.mod @@ -45,7 +45,7 @@ require ( github.com/ipfs/go-ipld-git v0.1.1 github.com/ipfs/go-ipld-legacy v0.1.1 github.com/ipfs/go-ipns v0.3.0 - github.com/ipfs/go-libipfs v0.4.1-0.20230207021459-1a932f7bb3c1 + github.com/ipfs/go-libipfs v0.4.1-0.20230208022905-378aaf777cf9 github.com/ipfs/go-log v1.0.5 github.com/ipfs/go-log/v2 v2.5.1 github.com/ipfs/go-merkledag v0.9.0 diff --git a/go.sum b/go.sum index dd5945e44..67126741a 100644 --- a/go.sum +++ b/go.sum @@ -570,8 +570,8 @@ github.com/ipfs/go-ipld-legacy v0.1.1 h1:BvD8PEuqwBHLTKqlGFTHSwrwFOMkVESEvwIYwR2 github.com/ipfs/go-ipld-legacy v0.1.1/go.mod h1:8AyKFCjgRPsQFf15ZQgDB8Din4DML/fOmKZkkFkrIEg= github.com/ipfs/go-ipns v0.3.0 h1:ai791nTgVo+zTuq2bLvEGmWP1M0A6kGTXUsgv/Yq67A= github.com/ipfs/go-ipns v0.3.0/go.mod h1:3cLT2rbvgPZGkHJoPO1YMJeh6LtkxopCkKFcio/wE24= -github.com/ipfs/go-libipfs v0.4.1-0.20230207021459-1a932f7bb3c1 h1:drLEvJmJM0UrXvQfMF84EqSeGSXl5Elk/PAcc0XnNb4= -github.com/ipfs/go-libipfs v0.4.1-0.20230207021459-1a932f7bb3c1/go.mod h1:XKRXmSlJ32qlpxGN+mdGJJXUl/Z055etN1xpMEaANQ8= +github.com/ipfs/go-libipfs v0.4.1-0.20230208022905-378aaf777cf9 h1:m3h1qk9cuH2aqiILynVqF69UmmdOiNTSq6CnHK9GVuQ= +github.com/ipfs/go-libipfs v0.4.1-0.20230208022905-378aaf777cf9/go.mod h1:XKRXmSlJ32qlpxGN+mdGJJXUl/Z055etN1xpMEaANQ8= github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= github.com/ipfs/go-log v1.0.2/go.mod h1:1MNjMxe0u6xvJZgeqbJ8vdo2TKaGwZ1a0Bpza+sr2Sk= github.com/ipfs/go-log v1.0.3/go.mod h1:OsLySYkwIbiSUR/yBTdv1qPtcE4FW3WPWk/ewz9Ru+A= From 3ff72a1b95cf74f037a8dfa06ccd01fefc8f5e87 Mon Sep 17 00:00:00 2001 From: galargh Date: Wed, 8 Feb 2023 15:11:31 +0100 Subject: [PATCH 0459/1212] docs: add a step for verifying infra config --- docs/RELEASE_ISSUE_TEMPLATE.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/RELEASE_ISSUE_TEMPLATE.md b/docs/RELEASE_ISSUE_TEMPLATE.md index b591fdd5b..c38b8eae9 100644 --- a/docs/RELEASE_ISSUE_TEMPLATE.md +++ b/docs/RELEASE_ISSUE_TEMPLATE.md @@ -29,6 +29,8 @@ As usual, this release includes important fixes, some of which may be critical f ### Required +- [ ] Do we need to make any changes to the [infrastructure configuration](https://github.com/protocol/bifrost-infra/tree/master/ansible/inventories/bifrost/group_vars)? + ### Nice to have ## 🔦 Highlights From 3f7c35bdb9239717c6e7f807e4effb6302842562 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Wed, 8 Feb 2023 08:37:20 +0100 Subject: [PATCH 0460/1212] test: basic routing interface test This commit was moved from ipfs/interface-go-ipfs-core@d069f41be1eea938a4bbaa16dae953eed24bc945 This commit was moved from ipfs/boxo@48f8c69a903b1e66f8725f6b5ce9741b8e88c5a1 --- core/coreiface/tests/api.go | 1 + core/coreiface/tests/routing.go | 92 +++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+) create mode 100644 core/coreiface/tests/routing.go diff --git a/core/coreiface/tests/api.go b/core/coreiface/tests/api.go index 0801b3ca7..ec1f63ae6 100644 --- a/core/coreiface/tests/api.go +++ b/core/coreiface/tests/api.go @@ -69,6 +69,7 @@ func TestApi(p Provider) func(t *testing.T) { t.Run("Path", tp.TestPath) t.Run("Pin", tp.TestPin) t.Run("PubSub", tp.TestPubSub) + t.Run("Routing", tp.TestRouting) t.Run("Unixfs", tp.TestUnixfs) apis <- -1 diff --git a/core/coreiface/tests/routing.go b/core/coreiface/tests/routing.go new file mode 100644 index 000000000..14e0d2e66 --- /dev/null +++ b/core/coreiface/tests/routing.go @@ -0,0 +1,92 @@ +package tests + +import ( + "context" + "testing" + "time" + + "github.com/gogo/protobuf/proto" + ipns_pb "github.com/ipfs/go-ipns/pb" + iface "github.com/ipfs/interface-go-ipfs-core" +) + +func (tp *TestSuite) TestRouting(t *testing.T) { + tp.hasApi(t, func(api iface.CoreAPI) error { + if api.Routing() == nil { + return errAPINotImplemented + } + return nil + }) + + t.Run("TestRoutingGet", tp.TestRoutingGet) + t.Run("TestRoutingPut", tp.TestRoutingPut) +} + +func (tp *TestSuite) testRoutingPublishKey(t *testing.T, ctx context.Context, api iface.CoreAPI) iface.IpnsEntry { + p, err := addTestObject(ctx, api) + if err != nil { + t.Fatal(err) + } + + entry, err := api.Name().Publish(ctx, p) + if err != nil { + t.Fatal(err) + } + + time.Sleep(3 * time.Second) + return entry +} + +func (tp *TestSuite) TestRoutingGet(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + apis, err := tp.MakeAPISwarm(ctx, true, 2) + if err != nil { + t.Fatal(err) + } + + // Node 1: publishes an IPNS name + ipnsEntry := tp.testRoutingPublishKey(t, ctx, apis[0]) + + // Node 2: retrieves the best value for the IPNS name. + data, err := apis[1].Routing().Get(ctx, "/ipns/"+ipnsEntry.Name()) + if err != nil { + t.Fatal(err) + } + + // Checks if values match. + var entry ipns_pb.IpnsEntry + err = proto.Unmarshal(data, &entry) + if err != nil { + t.Fatal(err) + } + + if string(entry.GetValue()) != ipnsEntry.Value().String() { + t.Fatalf("routing key has wrong value, expected %s, got %s", ipnsEntry.Value().String(), string(entry.GetValue())) + } +} + +func (tp *TestSuite) TestRoutingPut(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + apis, err := tp.MakeAPISwarm(ctx, true, 1) + if err != nil { + t.Fatal(err) + } + + // Create and publish IPNS entry. + ipnsEntry := tp.testRoutingPublishKey(t, ctx, apis[0]) + + // Get valid routing value. + data, err := apis[0].Routing().Get(ctx, "/ipns/"+ipnsEntry.Name()) + if err != nil { + t.Fatal(err) + } + + // Put routing value. + err = apis[0].Routing().Put(ctx, "/ipns/"+ipnsEntry.Name(), data) + if err != nil { + t.Fatal(err) + } +} From af0fe194f5135b172879c92d4dfa0ba384ac76eb Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Wed, 8 Feb 2023 08:43:23 +0100 Subject: [PATCH 0461/1212] chore: update iface with routing tests --- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index df5abfdc6..48b4effe0 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -8,7 +8,7 @@ replace github.com/ipfs/kubo => ./../../.. require ( github.com/ipfs/go-libipfs v0.4.1-0.20230208022905-378aaf777cf9 - github.com/ipfs/interface-go-ipfs-core v0.10.0 + github.com/ipfs/interface-go-ipfs-core v0.11.0 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.24.2 github.com/multiformats/go-multiaddr v0.8.0 diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 53c239273..39ec7db66 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -593,8 +593,8 @@ github.com/ipfs/go-unixfsnode v1.5.1/go.mod h1:ed79DaG9IEuZITJVQn4U6MZDftv6I3ygU github.com/ipfs/go-verifcid v0.0.1/go.mod h1:5Hrva5KBeIog4A+UpqlaIU+DEstipcJYQQZc0g37pY0= github.com/ipfs/go-verifcid v0.0.2 h1:XPnUv0XmdH+ZIhLGKg6U2vaPaRDXb9urMyNVCE7uvTs= github.com/ipfs/go-verifcid v0.0.2/go.mod h1:40cD9x1y4OWnFXbLNJYRe7MpNvWlMn3LZAG5Wb4xnPU= -github.com/ipfs/interface-go-ipfs-core v0.10.0 h1:b/psL1oqJcySdQAsIBfW5ZJJkOAsYlhWtC0/Qvr4WiM= -github.com/ipfs/interface-go-ipfs-core v0.10.0/go.mod h1:F3EcmDy53GFkF0H3iEJpfJC320fZ/4G60eftnItrrJ0= +github.com/ipfs/interface-go-ipfs-core v0.11.0 h1:n1tplrwsz7oZXkpkZM5a3MDBxksMfSQ103ej4e+l7NA= +github.com/ipfs/interface-go-ipfs-core v0.11.0/go.mod h1:xmnoccUXY7N/Q8AIx0vFqgW926/FAZ8+do/1NTEHKsU= github.com/ipld/edelweiss v0.2.0 h1:KfAZBP8eeJtrLxLhi7r3N0cBCo7JmwSRhOJp3WSpNjk= github.com/ipld/edelweiss v0.2.0/go.mod h1:FJAzJRCep4iI8FOFlRriN9n0b7OuX3T/S9++NpBDmA4= github.com/ipld/go-car v0.5.0 h1:kcCEa3CvYMs0iE5BzD5sV7O2EwMiCIp3uF8tA6APQT8= diff --git a/go.mod b/go.mod index e724c0888..f104f5332 100644 --- a/go.mod +++ b/go.mod @@ -58,7 +58,7 @@ require ( github.com/ipfs/go-unixfs v0.4.2 github.com/ipfs/go-unixfsnode v1.5.1 github.com/ipfs/go-verifcid v0.0.2 - github.com/ipfs/interface-go-ipfs-core v0.10.0 + github.com/ipfs/interface-go-ipfs-core v0.11.0 github.com/ipld/go-car v0.5.0 github.com/ipld/go-car/v2 v2.5.1 github.com/ipld/go-codec-dagpb v1.5.0 diff --git a/go.sum b/go.sum index 67126741a..4f180c1fd 100644 --- a/go.sum +++ b/go.sum @@ -619,8 +619,8 @@ github.com/ipfs/go-unixfsnode v1.5.1/go.mod h1:ed79DaG9IEuZITJVQn4U6MZDftv6I3ygU github.com/ipfs/go-verifcid v0.0.1/go.mod h1:5Hrva5KBeIog4A+UpqlaIU+DEstipcJYQQZc0g37pY0= github.com/ipfs/go-verifcid v0.0.2 h1:XPnUv0XmdH+ZIhLGKg6U2vaPaRDXb9urMyNVCE7uvTs= github.com/ipfs/go-verifcid v0.0.2/go.mod h1:40cD9x1y4OWnFXbLNJYRe7MpNvWlMn3LZAG5Wb4xnPU= -github.com/ipfs/interface-go-ipfs-core v0.10.0 h1:b/psL1oqJcySdQAsIBfW5ZJJkOAsYlhWtC0/Qvr4WiM= -github.com/ipfs/interface-go-ipfs-core v0.10.0/go.mod h1:F3EcmDy53GFkF0H3iEJpfJC320fZ/4G60eftnItrrJ0= +github.com/ipfs/interface-go-ipfs-core v0.11.0 h1:n1tplrwsz7oZXkpkZM5a3MDBxksMfSQ103ej4e+l7NA= +github.com/ipfs/interface-go-ipfs-core v0.11.0/go.mod h1:xmnoccUXY7N/Q8AIx0vFqgW926/FAZ8+do/1NTEHKsU= github.com/ipld/edelweiss v0.2.0 h1:KfAZBP8eeJtrLxLhi7r3N0cBCo7JmwSRhOJp3WSpNjk= github.com/ipld/edelweiss v0.2.0/go.mod h1:FJAzJRCep4iI8FOFlRriN9n0b7OuX3T/S9++NpBDmA4= github.com/ipld/go-car v0.5.0 h1:kcCEa3CvYMs0iE5BzD5sV7O2EwMiCIp3uF8tA6APQT8= From 82ede56636d487aa4f4bb895dc41cd740efca786 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Thu, 9 Feb 2023 19:23:13 +0100 Subject: [PATCH 0462/1212] chore: bump go-libp2p-routing-helpers to v0.6.1 This include a fix where FindProvidersAsync with the parallel composer would not close the channel ASAP when the count was reached, this save finality time when count is reached. --- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 48b4effe0..644bee498 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -125,7 +125,7 @@ require ( github.com/libp2p/go-libp2p-pubsub v0.8.3 // indirect github.com/libp2p/go-libp2p-pubsub-router v0.6.0 // indirect github.com/libp2p/go-libp2p-record v0.2.0 // indirect - github.com/libp2p/go-libp2p-routing-helpers v0.6.0 // indirect + github.com/libp2p/go-libp2p-routing-helpers v0.6.1 // indirect github.com/libp2p/go-libp2p-xor v0.1.0 // indirect github.com/libp2p/go-mplex v0.7.0 // indirect github.com/libp2p/go-msgio v0.2.0 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 39ec7db66..e58ded225 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -783,8 +783,8 @@ github.com/libp2p/go-libp2p-quic-transport v0.10.0/go.mod h1:RfJbZ8IqXIhxBRm5hqU github.com/libp2p/go-libp2p-record v0.1.0/go.mod h1:ujNc8iuE5dlKWVy6wuL6dd58t0n7xI4hAIl8pE6wu5Q= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= github.com/libp2p/go-libp2p-record v0.2.0/go.mod h1:I+3zMkvvg5m2OcSdoL0KPljyJyvNDFGKX7QdlpYUcwk= -github.com/libp2p/go-libp2p-routing-helpers v0.6.0 h1:Rfyd+wp/cU0PjNjCphGzLYzd7Q51fjOMs5Sjj6zWGT0= -github.com/libp2p/go-libp2p-routing-helpers v0.6.0/go.mod h1:wwK/XSLt6njjO7sRbjhf8w7PGBOfdntMQ2mOQPZ5s/Q= +github.com/libp2p/go-libp2p-routing-helpers v0.6.1 h1:tI3rHOf/FDQsxC2pHBaOZiqPJ0MZYyzGAf4V45xla4U= +github.com/libp2p/go-libp2p-routing-helpers v0.6.1/go.mod h1:R289GUxUMzRXIbWGSuUUTPrlVJZ3Y/pPz495+qgXJX8= github.com/libp2p/go-libp2p-secio v0.1.0/go.mod h1:tMJo2w7h3+wN4pgU2LSYeiKPrfqBgkOsdiKK77hE7c8= github.com/libp2p/go-libp2p-secio v0.2.0/go.mod h1:2JdZepB8J5V9mBp79BmwsaPQhRPNN2NrnB2lKQcdy6g= github.com/libp2p/go-libp2p-secio v0.2.1/go.mod h1:cWtZpILJqkqrSkiYcDBh5lA3wbT2Q+hz3rJQq3iftD8= diff --git a/go.mod b/go.mod index f104f5332..c722407d5 100644 --- a/go.mod +++ b/go.mod @@ -74,7 +74,7 @@ require ( github.com/libp2p/go-libp2p-pubsub v0.8.3 github.com/libp2p/go-libp2p-pubsub-router v0.6.0 github.com/libp2p/go-libp2p-record v0.2.0 - github.com/libp2p/go-libp2p-routing-helpers v0.6.0 + github.com/libp2p/go-libp2p-routing-helpers v0.6.1 github.com/libp2p/go-libp2p-testing v0.12.0 github.com/libp2p/go-socket-activation v0.1.0 github.com/miekg/dns v1.1.50 diff --git a/go.sum b/go.sum index 4f180c1fd..01edc2416 100644 --- a/go.sum +++ b/go.sum @@ -817,8 +817,8 @@ github.com/libp2p/go-libp2p-quic-transport v0.10.0/go.mod h1:RfJbZ8IqXIhxBRm5hqU github.com/libp2p/go-libp2p-record v0.1.0/go.mod h1:ujNc8iuE5dlKWVy6wuL6dd58t0n7xI4hAIl8pE6wu5Q= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= github.com/libp2p/go-libp2p-record v0.2.0/go.mod h1:I+3zMkvvg5m2OcSdoL0KPljyJyvNDFGKX7QdlpYUcwk= -github.com/libp2p/go-libp2p-routing-helpers v0.6.0 h1:Rfyd+wp/cU0PjNjCphGzLYzd7Q51fjOMs5Sjj6zWGT0= -github.com/libp2p/go-libp2p-routing-helpers v0.6.0/go.mod h1:wwK/XSLt6njjO7sRbjhf8w7PGBOfdntMQ2mOQPZ5s/Q= +github.com/libp2p/go-libp2p-routing-helpers v0.6.1 h1:tI3rHOf/FDQsxC2pHBaOZiqPJ0MZYyzGAf4V45xla4U= +github.com/libp2p/go-libp2p-routing-helpers v0.6.1/go.mod h1:R289GUxUMzRXIbWGSuUUTPrlVJZ3Y/pPz495+qgXJX8= github.com/libp2p/go-libp2p-secio v0.1.0/go.mod h1:tMJo2w7h3+wN4pgU2LSYeiKPrfqBgkOsdiKK77hE7c8= github.com/libp2p/go-libp2p-secio v0.2.0/go.mod h1:2JdZepB8J5V9mBp79BmwsaPQhRPNN2NrnB2lKQcdy6g= github.com/libp2p/go-libp2p-secio v0.2.1/go.mod h1:cWtZpILJqkqrSkiYcDBh5lA3wbT2Q+hz3rJQq3iftD8= From fb7f7b15b39cfc6f026bf0d518a669005be94709 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Fri, 10 Feb 2023 02:41:45 +0100 Subject: [PATCH 0463/1212] fix: restore wire format for /api/v0/routing/get|put (#9639) Closes #9638 --- core/commands/routing.go | 48 ++++++++++++++++++++++++------ test/sharness/t0170-routing-dht.sh | 24 +++++++++------ 2 files changed, 54 insertions(+), 18 deletions(-) diff --git a/core/commands/routing.go b/core/commands/routing.go index d0f13c556..460abb97a 100644 --- a/core/commands/routing.go +++ b/core/commands/routing.go @@ -2,6 +2,7 @@ package commands import ( "context" + "encoding/base64" "errors" "fmt" "io" @@ -374,15 +375,22 @@ Different key types can specify other 'best' rules. return err } - return res.Emit(r) + return res.Emit(routing.QueryEvent{ + Extra: base64.StdEncoding.EncodeToString(r), + Type: routing.Value, + }) }, Encoders: cmds.EncoderMap{ - cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out []byte) error { - _, err := w.Write(out) + cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, obj *routing.QueryEvent) error { + res, err := base64.StdEncoding.DecodeString(obj.Extra) + if err != nil { + return err + } + _, err = w.Write(res) return err }), }, - Type: []byte{}, + Type: routing.QueryEvent{}, } var putValueRoutingCmd = &cmds.Command{ @@ -434,15 +442,37 @@ identified by QmFoo. return err } - return res.Emit([]byte(fmt.Sprintf("%s added", req.Arguments[0]))) + id, err := api.Key().Self(req.Context) + if err != nil { + return err + } + + return res.Emit(routing.QueryEvent{ + Type: routing.Value, + ID: id.ID(), + }) }, Encoders: cmds.EncoderMap{ - cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out []byte) error { - _, err := w.Write(out) - return err + cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *routing.QueryEvent) error { + pfm := pfuncMap{ + routing.FinalPeer: func(obj *routing.QueryEvent, out io.Writer, verbose bool) error { + if verbose { + fmt.Fprintf(out, "* closest peer %s\n", obj.ID) + } + return nil + }, + routing.Value: func(obj *routing.QueryEvent, out io.Writer, verbose bool) error { + fmt.Fprintf(out, "%s\n", obj.ID.Pretty()) + return nil + }, + } + + verbose, _ := req.Options[dhtVerboseOptionName].(bool) + + return printEvent(out, w, verbose, pfm) }), }, - Type: []byte{}, + Type: routing.QueryEvent{}, } type printFunc func(obj *routing.QueryEvent, out io.Writer, verbose bool) error diff --git a/test/sharness/t0170-routing-dht.sh b/test/sharness/t0170-routing-dht.sh index 85462dcc2..e6e9940f2 100755 --- a/test/sharness/t0170-routing-dht.sh +++ b/test/sharness/t0170-routing-dht.sh @@ -24,14 +24,14 @@ test_dht() { PEERID_0=$(iptb attr get 0 id) && PEERID_2=$(iptb attr get 2 id) ' - + # ipfs routing findpeer test_expect_success 'findpeer' ' ipfsi 1 routing findpeer $PEERID_0 | sort >actual && ipfsi 0 id -f "" | cut -d / -f 1-5 | sort >expected && test_cmp actual expected ' - + # ipfs routing get test_expect_success 'get with good keys works' ' HASH="$(echo "hello world" | ipfsi 2 add -q)" && @@ -48,7 +48,7 @@ test_dht() { [ -s putted ] || test_fsh cat putted ' - + test_expect_success 'put with bad keys fails (issue #5113)' ' ipfsi 0 routing put "foo" <<putted ipfsi 0 routing put "/pk/foo" <<>putted @@ -56,31 +56,37 @@ test_dht() { [ ! -s putted ] || test_fsh cat putted ' - + test_expect_success 'put with bad keys returns error (issue #4611)' ' test_must_fail ipfsi 0 routing put "foo" << afile && HASH=$(ipfsi 3 add -q afile) ' - + # ipfs routing findprovs test_expect_success 'findprovs' ' ipfsi 4 routing findprovs $HASH > provs && iptb attr get 3 id > expected && test_cmp provs expected ' - - + + # ipfs routing get --enc=json has correct properties + test_expect_success 'routing get --enc=json has correct properties' ' + HASH="$(echo "hello world" | ipfsi 2 add -q)" && + ipfsi 2 name publish "/ipfs/$HASH" && + ipfsi 1 routing get --enc=json "/ipns/$PEERID_2" | jq -e "has(\"Extra\") and has(\"Type\")" + ' + # ipfs dht query # # We test all nodes. 4 nodes should see the same peer ID, one node (the From 3b6647ffdc86bfe219a52ccb9b48d4f4608d5bb7 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Fri, 10 Feb 2023 03:25:12 +0100 Subject: [PATCH 0464/1212] test: use two nodes in publish This spin up online nodes instead of offline ones. This commit was moved from ipfs/interface-go-ipfs-core@a8d2741bbe08a6ba54cf4a4e229eff6978be1b77 This commit was moved from ipfs/boxo@54d20f01739e73f7c770db8f2dc0be1c2185ce20 --- core/coreiface/tests/routing.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/coreiface/tests/routing.go b/core/coreiface/tests/routing.go index 14e0d2e66..64287487e 100644 --- a/core/coreiface/tests/routing.go +++ b/core/coreiface/tests/routing.go @@ -70,7 +70,7 @@ func (tp *TestSuite) TestRoutingGet(t *testing.T) { func (tp *TestSuite) TestRoutingPut(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - apis, err := tp.MakeAPISwarm(ctx, true, 1) + apis, err := tp.MakeAPISwarm(ctx, true, 2) if err != nil { t.Fatal(err) } @@ -85,7 +85,7 @@ func (tp *TestSuite) TestRoutingPut(t *testing.T) { } // Put routing value. - err = apis[0].Routing().Put(ctx, "/ipns/"+ipnsEntry.Name(), data) + err = apis[1].Routing().Put(ctx, "/ipns/"+ipnsEntry.Name(), data) if err != nil { t.Fatal(err) } From 75b6f45f765237d611168a5e1c09915f380e7bd7 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Mon, 6 Feb 2023 15:32:57 +0100 Subject: [PATCH 0465/1212] chore: bumps for Kubo 0.18 and Routing API with stub for Put This commit was moved from ipfs/go-ipfs-http-client@c076c3cb71d08fb9448ae9bf6916dab137322722 --- client/httpapi/api.go | 4 +++ client/httpapi/apifile.go | 2 +- client/httpapi/dag.go | 2 +- client/httpapi/dht.go | 4 +-- client/httpapi/key.go | 2 +- client/httpapi/pubsub.go | 2 +- client/httpapi/requestbuilder.go | 2 +- client/httpapi/response.go | 2 +- client/httpapi/routing.go | 55 ++++++++++++++++++++++++++++++++ client/httpapi/swarm.go | 6 ++-- client/httpapi/unixfs.go | 2 +- 11 files changed, 71 insertions(+), 12 deletions(-) create mode 100644 client/httpapi/routing.go diff --git a/client/httpapi/api.go b/client/httpapi/api.go index 97440a724..10df94603 100644 --- a/client/httpapi/api.go +++ b/client/httpapi/api.go @@ -195,3 +195,7 @@ func (api *HttpApi) Swarm() iface.SwarmAPI { func (api *HttpApi) PubSub() iface.PubSubAPI { return (*PubsubAPI)(api) } + +func (api *HttpApi) Routing() iface.RoutingAPI { + return (*RoutingAPI)(api) +} diff --git a/client/httpapi/apifile.go b/client/httpapi/apifile.go index c4884b924..80fd13cd4 100644 --- a/client/httpapi/apifile.go +++ b/client/httpapi/apifile.go @@ -7,7 +7,7 @@ import ( "io" "github.com/ipfs/go-cid" - files "github.com/ipfs/go-ipfs-files" + "github.com/ipfs/go-libipfs/files" unixfs "github.com/ipfs/go-unixfs" "github.com/ipfs/interface-go-ipfs-core/path" ) diff --git a/client/httpapi/dag.go b/client/httpapi/dag.go index f32c67c42..2fbfea1ff 100644 --- a/client/httpapi/dag.go +++ b/client/httpapi/dag.go @@ -6,9 +6,9 @@ import ( "fmt" "io" - blocks "github.com/ipfs/go-block-format" "github.com/ipfs/go-cid" format "github.com/ipfs/go-ipld-format" + "github.com/ipfs/go-libipfs/blocks" "github.com/ipfs/interface-go-ipfs-core/options" "github.com/ipfs/interface-go-ipfs-core/path" multicodec "github.com/multiformats/go-multicodec" diff --git a/client/httpapi/dht.go b/client/httpapi/dht.go index 0a78514f9..ebecfcaeb 100644 --- a/client/httpapi/dht.go +++ b/client/httpapi/dht.go @@ -6,8 +6,8 @@ import ( caopts "github.com/ipfs/interface-go-ipfs-core/options" "github.com/ipfs/interface-go-ipfs-core/path" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/routing" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/routing" ) type DhtAPI HttpApi diff --git a/client/httpapi/key.go b/client/httpapi/key.go index 78b67517c..b785bbf45 100644 --- a/client/httpapi/key.go +++ b/client/httpapi/key.go @@ -7,7 +7,7 @@ import ( iface "github.com/ipfs/interface-go-ipfs-core" caopts "github.com/ipfs/interface-go-ipfs-core/options" "github.com/ipfs/interface-go-ipfs-core/path" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/peer" ) type KeyAPI HttpApi diff --git a/client/httpapi/pubsub.go b/client/httpapi/pubsub.go index 72f592376..ec45d1a51 100644 --- a/client/httpapi/pubsub.go +++ b/client/httpapi/pubsub.go @@ -8,7 +8,7 @@ import ( iface "github.com/ipfs/interface-go-ipfs-core" caopts "github.com/ipfs/interface-go-ipfs-core/options" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/peer" mbase "github.com/multiformats/go-multibase" ) diff --git a/client/httpapi/requestbuilder.go b/client/httpapi/requestbuilder.go index 039bca036..bc6f4c8a9 100644 --- a/client/httpapi/requestbuilder.go +++ b/client/httpapi/requestbuilder.go @@ -8,7 +8,7 @@ import ( "strconv" "strings" - files "github.com/ipfs/go-ipfs-files" + "github.com/ipfs/go-libipfs/files" ) type RequestBuilder interface { diff --git a/client/httpapi/response.go b/client/httpapi/response.go index 8a491ab73..99932ca0d 100644 --- a/client/httpapi/response.go +++ b/client/httpapi/response.go @@ -12,7 +12,7 @@ import ( cmds "github.com/ipfs/go-ipfs-cmds" cmdhttp "github.com/ipfs/go-ipfs-cmds/http" - files "github.com/ipfs/go-ipfs-files" + "github.com/ipfs/go-libipfs/files" ) type Error = cmds.Error diff --git a/client/httpapi/routing.go b/client/httpapi/routing.go new file mode 100644 index 000000000..18f533276 --- /dev/null +++ b/client/httpapi/routing.go @@ -0,0 +1,55 @@ +package httpapi + +import ( + "bytes" + "context" + "encoding/base64" + "encoding/json" + + "github.com/libp2p/go-libp2p/core/routing" +) + +type RoutingAPI HttpApi + +func (api *RoutingAPI) Get(ctx context.Context, key string) ([]byte, error) { + resp, err := api.core().Request("routing/get", key).Send(ctx) + if err != nil { + return nil, err + } + if resp.Error != nil { + return nil, resp.Error + } + defer resp.Close() + + var out routing.QueryEvent + + dec := json.NewDecoder(resp.Output) + if err := dec.Decode(&out); err != nil { + return nil, err + } + + res, err := base64.StdEncoding.DecodeString(out.Extra) + if err != nil { + return nil, err + } + + return res, nil +} + +func (api *RoutingAPI) Put(ctx context.Context, key string, value []byte) error { + resp, err := api.core().Request("routing/put", key). + FileBody(bytes.NewReader(value)). + Send(ctx) + + if err != nil { + return err + } + if resp.Error != nil { + return resp.Error + } + return nil +} + +func (api *RoutingAPI) core() *HttpApi { + return (*HttpApi)(api) +} diff --git a/client/httpapi/swarm.go b/client/httpapi/swarm.go index 1cb0d91df..c5dfbe564 100644 --- a/client/httpapi/swarm.go +++ b/client/httpapi/swarm.go @@ -5,9 +5,9 @@ import ( "time" iface "github.com/ipfs/interface-go-ipfs-core" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/protocol" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/protocol" "github.com/multiformats/go-multiaddr" ) diff --git a/client/httpapi/unixfs.go b/client/httpapi/unixfs.go index 5e27fb036..38f23d5b9 100644 --- a/client/httpapi/unixfs.go +++ b/client/httpapi/unixfs.go @@ -8,7 +8,7 @@ import ( "io" "github.com/ipfs/go-cid" - files "github.com/ipfs/go-ipfs-files" + "github.com/ipfs/go-libipfs/files" unixfs "github.com/ipfs/go-unixfs" unixfs_pb "github.com/ipfs/go-unixfs/pb" iface "github.com/ipfs/interface-go-ipfs-core" From 627a34c712fd0877e94696c7529023e3cda9678b Mon Sep 17 00:00:00 2001 From: Guillaume Renault Date: Sat, 11 Feb 2023 17:32:34 +0100 Subject: [PATCH 0466/1212] fix: dereference int64 pointer in OptionalInteger.String() (#9640) --- config/types.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/types.go b/config/types.go index 1af244f9c..b0e493bfd 100644 --- a/config/types.go +++ b/config/types.go @@ -345,7 +345,7 @@ func (p OptionalInteger) String() string { if p.value == nil { return "default" } - return fmt.Sprintf("%d", p.value) + return fmt.Sprintf("%d", *p.value) } var _ json.Unmarshaler = (*OptionalInteger)(nil) From 89826a39b08ea186118bc7d0fb507c53388166f5 Mon Sep 17 00:00:00 2001 From: myml Date: Sat, 11 Feb 2023 13:58:02 +0800 Subject: [PATCH 0467/1212] feat: add NewOptionalInteger function Missing method to create OptionalInteger --- config/types.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/config/types.go b/config/types.go index b0e493bfd..f753827ab 100644 --- a/config/types.go +++ b/config/types.go @@ -306,6 +306,11 @@ type OptionalInteger struct { value *int64 } +// NewOptionalInteger returns an OptionalInteger from a int64 +func NewOptionalInteger(v int64) *OptionalInteger { + return &OptionalInteger{value: &v} +} + // WithDefault resolves the integer with the given default. func (p *OptionalInteger) WithDefault(defaultValue int64) (value int64) { if p == nil || p.value == nil { From e59c605f2a6e17d7caf4710035cf05e426a29b2d Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Mon, 13 Feb 2023 15:20:59 +0100 Subject: [PATCH 0468/1212] docs(0.18.1): guide users to clean up limits (#9644) --- docs/changelogs/v0.18.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/docs/changelogs/v0.18.md b/docs/changelogs/v0.18.md index b9d023639..3ea6ffef0 100644 --- a/docs/changelogs/v0.18.md +++ b/docs/changelogs/v0.18.md @@ -35,7 +35,17 @@ first time a message is seen, you can set `Pubsub.SeenMessagesStrategy` to #### Improving libp2p resource management integration -This builds on the default protection nodes get against DoS (resource exhaustion) and eclipse attacks +TL;DR: limit autoscaling improved, most users should start with default settings. +If you have old configuration, switch to implicit defaults: + +``` +ipfs config --json -- Swarm.ResourceMgr '{}' +ipfs config --json -- Swarm.ConnMgr '{}' +``` + +IF you run a server and want to utilize more than half of memory and file descriptors to p2p work, adjust [`Swarm.ResourceMgr.MaxMemory`](https://github.com/ipfs/kubo/blob/master/docs/config.md#swarmresourcemgrmaxmemory) and [`Swarm.ResourceMgr.MaxFileDescriptors`](https://github.com/ipfs/kubo/blob/master/docs/config.md#swarmresourcemgrmaxfiledescriptors). + +The 0.18.1 builds on the default protection nodes get against DoS (resource exhaustion) and eclipse attacks with the [go-libp2p Network Resource Manager/Accountant](https://github.com/ipfs/kubo/blob/master/docs/libp2p-resource-management.md) that was fine-tuned in [Kubo 0.18](https://github.com/ipfs/kubo/blob/biglep/resource-manager-example-of-what-want/docs/changelogs/v0.18.md#improving-libp2p-resource-management-integration). From a00f5cae233f7c1da5f1c2ec3dc79a5bc6734a21 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Thu, 2 Feb 2023 11:05:30 +1300 Subject: [PATCH 0469/1212] chore: update go-libp2p to v0.25.1 --- core/commands/id.go | 23 +++++----- core/node/libp2p/rcmgr.go | 6 --- core/node/libp2p/relay.go | 52 ++++++++++++---------- go.mod | 33 +++++++------- go.sum | 93 +++++++++++++++++++++++++-------------- p2p/listener.go | 12 ++--- p2p/local.go | 8 ++-- p2p/p2p.go | 5 ++- p2p/remote.go | 6 +-- 9 files changed, 132 insertions(+), 106 deletions(-) diff --git a/core/commands/id.go b/core/commands/id.go index 887f93efe..2c4223bb4 100644 --- a/core/commands/id.go +++ b/core/commands/id.go @@ -10,28 +10,29 @@ import ( "strings" version "github.com/ipfs/kubo" - core "github.com/ipfs/kubo/core" - cmdenv "github.com/ipfs/kubo/core/commands/cmdenv" + "github.com/ipfs/kubo/core" + "github.com/ipfs/kubo/core/commands/cmdenv" cmds "github.com/ipfs/go-ipfs-cmds" ke "github.com/ipfs/kubo/core/commands/keyencode" kb "github.com/libp2p/go-libp2p-kbucket" ic "github.com/libp2p/go-libp2p/core/crypto" "github.com/libp2p/go-libp2p/core/host" - peer "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/peer" pstore "github.com/libp2p/go-libp2p/core/peerstore" - identify "github.com/libp2p/go-libp2p/p2p/protocol/identify" + "github.com/libp2p/go-libp2p/core/protocol" + "github.com/libp2p/go-libp2p/p2p/protocol/identify" ) const offlineIDErrorMessage = "'ipfs id' cannot query information on remote peers without a running daemon; if you only want to convert --peerid-base, pass --offline option" -type IdOutput struct { //nolint +type IdOutput struct { // nolint ID string PublicKey string Addresses []string AgentVersion string ProtocolVersion string - Protocols []string + Protocols []protocol.ID } const ( @@ -129,7 +130,7 @@ EXAMPLE: output = strings.Replace(output, "", out.ProtocolVersion, -1) output = strings.Replace(output, "", out.PublicKey, -1) output = strings.Replace(output, "", strings.Join(out.Addresses, "\n"), -1) - output = strings.Replace(output, "", strings.Join(out.Protocols, "\n"), -1) + output = strings.Replace(output, "", strings.Join(protocol.ConvertToStrings(out.Protocols), "\n"), -1) output = strings.Replace(output, "\\n", "\n", -1) output = strings.Replace(output, "\\t", "\t", -1) fmt.Fprint(w, output) @@ -175,10 +176,8 @@ func printPeer(keyEnc ke.KeyEncoder, ps pstore.Peerstore, p peer.ID) (interface{ sort.Strings(info.Addresses) protocols, _ := ps.GetProtocols(p) // don't care about errors here. - for _, p := range protocols { - info.Protocols = append(info.Protocols, string(p)) - } - sort.Strings(info.Protocols) + info.Protocols = append(info.Protocols, protocols...) + sort.Slice(info.Protocols, func(i, j int) bool { return info.Protocols[i] < info.Protocols[j] }) if v, err := ps.Get(p, "ProtocolVersion"); err == nil { if vs, ok := v.(string); ok { @@ -216,7 +215,7 @@ func printSelf(keyEnc ke.KeyEncoder, node *core.IpfsNode) (interface{}, error) { } sort.Strings(info.Addresses) info.Protocols = node.PeerHost.Mux().Protocols() - sort.Strings(info.Protocols) + sort.Slice(info.Protocols, func(i, j int) bool { return info.Protocols[i] < info.Protocols[j] }) } info.ProtocolVersion = identify.DefaultProtocolVersion info.AgentVersion = version.GetUserAgentVersion() diff --git a/core/node/libp2p/rcmgr.go b/core/node/libp2p/rcmgr.go index e0ce4693b..205dfe26b 100644 --- a/core/node/libp2p/rcmgr.go +++ b/core/node/libp2p/rcmgr.go @@ -16,7 +16,6 @@ import ( rcmgr "github.com/libp2p/go-libp2p/p2p/host/resource-manager" rcmgrObs "github.com/libp2p/go-libp2p/p2p/host/resource-manager/obs" "github.com/multiformats/go-multiaddr" - "go.opencensus.io/stats/view" "go.uber.org/fx" "github.com/ipfs/kubo/config" @@ -100,11 +99,6 @@ func ResourceManager(cfg config.SwarmConfig) interface{} { log.Infof("Setting allowlist to: %v", mas) } - err = view.Register(rcmgrObs.DefaultViews...) - if err != nil { - return nil, opts, fmt.Errorf("registering rcmgr obs views: %w", err) - } - if os.Getenv("LIBP2P_DEBUG_RCMGR") != "" { traceFilePath := filepath.Join(repoPath, NetLimitTraceFilename) ropts = append(ropts, rcmgr.WithTrace(traceFilePath)) diff --git a/core/node/libp2p/relay.go b/core/node/libp2p/relay.go index c39b2fae8..fc362cc53 100644 --- a/core/node/libp2p/relay.go +++ b/core/node/libp2p/relay.go @@ -63,8 +63,8 @@ func MaybeAutoRelay(staticRelays []string, cfgPeering config.Peering, enabled bo } static = append(static, *addr) } - opts.Opts = append(opts.Opts, libp2p.EnableAutoRelay( - autorelay.WithStaticRelays(static), + opts.Opts = append(opts.Opts, libp2p.EnableAutoRelayWithStaticRelays( + static, autorelay.WithCircuitV1Support(), )) } @@ -76,29 +76,33 @@ func MaybeAutoRelay(staticRelays []string, cfgPeering config.Peering, enabled bo return fx.Options( // Provide AutoRelay option fx.Provide(func() (opts Libp2pOpts, err error) { - opts.Opts = append(opts.Opts, libp2p.EnableAutoRelay(autorelay.WithPeerSource(func(ctx context.Context, numPeers int) <-chan peer.AddrInfo { - // TODO(9257): make this code smarter (have a state and actually try to grow the search outward) instead of a long running task just polling our K cluster. - r := make(chan peer.AddrInfo) - go func() { - defer close(r) - for ; numPeers != 0; numPeers-- { - select { - case v, ok := <-peerChan: - if !ok { - return + opts.Opts = append(opts.Opts, + libp2p.EnableAutoRelayWithPeerSource( + func(ctx context.Context, numPeers int) <-chan peer.AddrInfo { + // TODO(9257): make this code smarter (have a state and actually try to grow the search outward) instead of a long running task just polling our K cluster. + r := make(chan peer.AddrInfo) + go func() { + defer close(r) + for ; numPeers != 0; numPeers-- { + select { + case v, ok := <-peerChan: + if !ok { + return + } + select { + case r <- v: + case <-ctx.Done(): + return + } + case <-ctx.Done(): + return + } } - select { - case r <- v: - case <-ctx.Done(): - return - } - case <-ctx.Done(): - return - } - } - }() - return r - }, 0))) + }() + return r + }, + autorelay.WithMinInterval(0), + )) return }), autoRelayFeeder(cfgPeering, peerChan), diff --git a/go.mod b/go.mod index c722407d5..d35ddb910 100644 --- a/go.mod +++ b/go.mod @@ -45,7 +45,7 @@ require ( github.com/ipfs/go-ipld-git v0.1.1 github.com/ipfs/go-ipld-legacy v0.1.1 github.com/ipfs/go-ipns v0.3.0 - github.com/ipfs/go-libipfs v0.4.1-0.20230208022905-378aaf777cf9 + github.com/ipfs/go-libipfs v0.4.1-0.20230201214832-687c0b0f1531 github.com/ipfs/go-log v1.0.5 github.com/ipfs/go-log/v2 v2.5.1 github.com/ipfs/go-merkledag v0.9.0 @@ -67,11 +67,11 @@ require ( 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.24.2 + github.com/libp2p/go-libp2p v0.25.1 github.com/libp2p/go-libp2p-http v0.4.0 - github.com/libp2p/go-libp2p-kad-dht v0.20.0 + github.com/libp2p/go-libp2p-kad-dht v0.21.0 github.com/libp2p/go-libp2p-kbucket v0.5.0 - github.com/libp2p/go-libp2p-pubsub v0.8.3 + github.com/libp2p/go-libp2p-pubsub v0.9.0 github.com/libp2p/go-libp2p-pubsub-router v0.6.0 github.com/libp2p/go-libp2p-record v0.2.0 github.com/libp2p/go-libp2p-routing-helpers v0.6.1 @@ -105,7 +105,7 @@ require ( go.uber.org/dig v1.15.0 go.uber.org/fx v1.18.2 go.uber.org/zap v1.24.0 - golang.org/x/crypto v0.3.0 + golang.org/x/crypto v0.4.0 golang.org/x/mod v0.7.0 golang.org/x/sync v0.1.0 golang.org/x/sys v0.4.0 @@ -148,11 +148,11 @@ require ( github.com/google/gopacket v1.1.19 // indirect github.com/google/pprof v0.0.0-20221203041831-ce31453925ec // indirect github.com/gorilla/mux v1.8.0 // indirect - github.com/gorilla/websocket v1.5.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 // indirect github.com/hannahhoward/go-pubsub v0.0.0-20200423002714-8d62886cc36e // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/golang-lru v0.5.4 // indirect + github.com/hashicorp/golang-lru/v2 v2.0.1 // indirect github.com/huin/goupnp v1.0.3 // indirect github.com/ipfs/bbloom v0.0.4 // indirect github.com/ipfs/go-bitfield v1.0.0 // indirect @@ -175,22 +175,15 @@ require ( github.com/libp2p/go-libp2p-gostream v0.5.0 // indirect github.com/libp2p/go-libp2p-xor v0.1.0 // indirect github.com/libp2p/go-mplex v0.7.0 // indirect - github.com/libp2p/go-msgio v0.2.0 // indirect + github.com/libp2p/go-msgio v0.3.0 // indirect github.com/libp2p/go-nat v0.1.0 // indirect github.com/libp2p/go-netroute v0.2.1 // indirect - github.com/libp2p/go-openssl v0.1.0 // indirect github.com/libp2p/go-reuseport v0.2.0 // indirect github.com/libp2p/go-yamux/v4 v4.0.0 // indirect github.com/libp2p/zeroconf/v2 v2.2.0 // indirect - github.com/lucas-clemente/quic-go v0.31.1 // indirect - github.com/marten-seemann/qpack v0.3.0 // indirect - github.com/marten-seemann/qtls-go1-18 v0.1.3 // indirect - github.com/marten-seemann/qtls-go1-19 v0.1.1 // indirect github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect - github.com/marten-seemann/webtransport-go v0.4.3 // indirect github.com/mattn/go-colorable v0.1.4 // indirect github.com/mattn/go-isatty v0.0.17 // indirect - github.com/mattn/go-pointer v0.0.1 // indirect github.com/mattn/go-runewidth v0.0.4 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect @@ -201,7 +194,7 @@ require ( github.com/multiformats/go-base32 v0.1.0 // indirect github.com/multiformats/go-base36 v0.2.0 // indirect github.com/multiformats/go-multiaddr-fmt v0.1.0 // indirect - github.com/multiformats/go-multistream v0.3.3 // indirect + github.com/multiformats/go-multistream v0.4.1 // indirect github.com/multiformats/go-varint v0.0.7 // indirect github.com/onsi/ginkgo/v2 v2.5.1 // indirect github.com/opencontainers/runtime-spec v1.0.2 // indirect @@ -212,10 +205,15 @@ require ( github.com/prometheus/common v0.37.0 // indirect github.com/prometheus/procfs v0.8.0 // indirect github.com/prometheus/statsd_exporter v0.21.0 // indirect + github.com/quic-go/qpack v0.4.0 // indirect + github.com/quic-go/qtls-go1-18 v0.2.0 // indirect + github.com/quic-go/qtls-go1-19 v0.2.0 // indirect + github.com/quic-go/qtls-go1-20 v0.1.0 // indirect + github.com/quic-go/quic-go v0.32.0 // indirect + github.com/quic-go/webtransport-go v0.5.1 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/rs/cors v1.7.0 // indirect github.com/samber/lo v1.36.0 // indirect - github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/texttheater/golang-levenshtein v0.0.0-20180516184445-d188e65d659e // indirect github.com/ucarion/urlpath v0.0.0-20200424170820-7ccc79b76bbb // indirect @@ -231,7 +229,7 @@ require ( go.uber.org/multierr v1.9.0 // indirect go4.org v0.0.0-20200411211856-f5505b9728dd // indirect golang.org/x/exp v0.0.0-20221205204356-47842c84f3db // indirect - golang.org/x/net v0.3.0 // indirect + golang.org/x/net v0.4.0 // indirect golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b // indirect golang.org/x/term v0.4.0 // indirect golang.org/x/text v0.5.0 // indirect @@ -245,6 +243,7 @@ require ( gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect lukechampine.com/blake3 v1.1.7 // indirect + nhooyr.io/websocket v1.8.7 // indirect ) go 1.18 diff --git a/go.sum b/go.sum index 01edc2416..d451a06ab 100644 --- a/go.sum +++ b/go.sum @@ -242,6 +242,10 @@ github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbS github.com/gabriel-vasile/mimetype v1.4.1 h1:TRWk7se+TOjCYgRth7+1/OYLNiRNIotknkFtf/dnN7Q= github.com/gabriel-vasile/mimetype v1.4.1/go.mod h1:05Vi0w3Y9c/lNvJOdmIwvrrAhX3rYhfQQCaf9VJcv7M= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= +github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14= +github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= @@ -264,10 +268,23 @@ github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= +github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= +github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= +github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= +github.com/go-playground/validator/v10 v10.2.0 h1:KgJ0snyC2R9VXYN2rneOtQcw5aHQB1Vv0sFl1UcHBOY= +github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= 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/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0= +github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= +github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8= +github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= +github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo= +github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= @@ -380,7 +397,6 @@ github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoA github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= -github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= @@ -416,6 +432,8 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/golang-lru/v2 v2.0.1 h1:5pv5N1lT1fjLg2VQ5KWc7kmucp2x/kvFOnxuVTqZ6x4= +github.com/hashicorp/golang-lru/v2 v2.0.1/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= @@ -570,8 +588,8 @@ github.com/ipfs/go-ipld-legacy v0.1.1 h1:BvD8PEuqwBHLTKqlGFTHSwrwFOMkVESEvwIYwR2 github.com/ipfs/go-ipld-legacy v0.1.1/go.mod h1:8AyKFCjgRPsQFf15ZQgDB8Din4DML/fOmKZkkFkrIEg= github.com/ipfs/go-ipns v0.3.0 h1:ai791nTgVo+zTuq2bLvEGmWP1M0A6kGTXUsgv/Yq67A= github.com/ipfs/go-ipns v0.3.0/go.mod h1:3cLT2rbvgPZGkHJoPO1YMJeh6LtkxopCkKFcio/wE24= -github.com/ipfs/go-libipfs v0.4.1-0.20230208022905-378aaf777cf9 h1:m3h1qk9cuH2aqiILynVqF69UmmdOiNTSq6CnHK9GVuQ= -github.com/ipfs/go-libipfs v0.4.1-0.20230208022905-378aaf777cf9/go.mod h1:XKRXmSlJ32qlpxGN+mdGJJXUl/Z055etN1xpMEaANQ8= +github.com/ipfs/go-libipfs v0.4.1-0.20230201214832-687c0b0f1531 h1:uDnDGKAuoOiNROG4yoWT39Xsjzvf3Z65fJRfG1caruo= +github.com/ipfs/go-libipfs v0.4.1-0.20230201214832-687c0b0f1531/go.mod h1:97CmQJmnJUSQwTSDZEXlKCNOCDD6HDKCGwKaJzHkc+U= github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= github.com/ipfs/go-log v1.0.2/go.mod h1:1MNjMxe0u6xvJZgeqbJ8vdo2TKaGwZ1a0Bpza+sr2Sk= github.com/ipfs/go-log v1.0.3/go.mod h1:OsLySYkwIbiSUR/yBTdv1qPtcE4FW3WPWk/ewz9Ru+A= @@ -668,8 +686,10 @@ github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlT github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= @@ -684,6 +704,7 @@ github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQL 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.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/compress v1.15.12 h1:YClS/PImqYbn+UILDnqxQCZ3RehC9N318SU3kElDUEM= github.com/klauspost/compress v1.15.12/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= @@ -708,6 +729,8 @@ github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= +github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= 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-buffer-pool v0.0.1/go.mod h1:xtyIz9PMobb13WaxR6Zo1Pd1zXJKYg0a8KiIvDp3TzQ= @@ -734,8 +757,8 @@ github.com/libp2p/go-libp2p v0.7.0/go.mod h1:hZJf8txWeCduQRDC/WSqBGMxaTHCOYHt2xS github.com/libp2p/go-libp2p v0.7.4/go.mod h1:oXsBlTLF1q7pxr+9w6lqzS1ILpyHsaBPniVO7zIHGMw= github.com/libp2p/go-libp2p v0.8.1/go.mod h1:QRNH9pwdbEBpx5DTJYg+qxcVaDMAz3Ee/qDKwXujH5o= github.com/libp2p/go-libp2p v0.14.3/go.mod h1:d12V4PdKbpL0T1/gsUNN8DfgMuRPDX8bS2QxCZlwRH0= -github.com/libp2p/go-libp2p v0.24.2 h1:iMViPIcLY0D6zr/f+1Yq9EavCZu2i7eDstsr1nEwSAk= -github.com/libp2p/go-libp2p v0.24.2/go.mod h1:WuxtL2V8yGjam03D93ZBC19tvOUiPpewYv1xdFGWu1k= +github.com/libp2p/go-libp2p v0.25.1 h1:YK+YDCHpYyTvitKWVxa5PfElgIpOONU01X5UcLEwJGA= +github.com/libp2p/go-libp2p v0.25.1/go.mod h1:xnK9/1d9+jeQCVvi/f1g12KqtVi/jP/SijtKV1hML3g= github.com/libp2p/go-libp2p-asn-util v0.2.0 h1:rg3+Os8jbnO5DxkC7K/Utdi+DkY3q/d1/1q+8WeNAsw= github.com/libp2p/go-libp2p-asn-util v0.2.0/go.mod h1:WoaWxbHKBymSN41hWSq/lGKJEca7TNm58+gGJi2WsLI= github.com/libp2p/go-libp2p-autonat v0.1.0/go.mod h1:1tLf2yXxiE/oKGtDwPYWTSYG3PtvYlJmg7NeVtPRqH8= @@ -782,8 +805,8 @@ github.com/libp2p/go-libp2p-gostream v0.5.0 h1:niNGTUrFoUDP/8jxMgu97zngMO+UGYBpV github.com/libp2p/go-libp2p-gostream v0.5.0/go.mod h1:rXrb0CqfcRRxa7m3RSKORQiKiWgk3IPeXWda66ZXKsA= github.com/libp2p/go-libp2p-http v0.4.0 h1:V+f9Rhe/8GkColmXoyJyA0NVsN9F3TCLZgW2hwjoX5w= github.com/libp2p/go-libp2p-http v0.4.0/go.mod h1:92tmLGrlBliQFDlZRpBXT3BJM7rGFONy0vsNrG/bMPg= -github.com/libp2p/go-libp2p-kad-dht v0.20.0 h1:1bcMa74JFwExCHZMFEmjtHzxX5DovhJ07EtR6UOTEpc= -github.com/libp2p/go-libp2p-kad-dht v0.20.0/go.mod h1:qPIXdiZsLczhV4/+4EO1jE8ae0YCW4ZOogc4WVIyTEU= +github.com/libp2p/go-libp2p-kad-dht v0.21.0 h1:J0Yd22VA+sk0CJRGMgtfHvLVIkZDyJ3AJGiljywIw5U= +github.com/libp2p/go-libp2p-kad-dht v0.21.0/go.mod h1:Bhm9diAFmc6qcWAr084bHNL159srVZRKADdp96Qqd1I= github.com/libp2p/go-libp2p-kbucket v0.3.1/go.mod h1:oyjT5O7tS9CQurok++ERgc46YLwEpuGoFq9ubvoUOio= github.com/libp2p/go-libp2p-kbucket v0.5.0 h1:g/7tVm8ACHDxH29BGrpsQlnNeu+6OF1A9bno/4/U1oA= github.com/libp2p/go-libp2p-kbucket v0.5.0/go.mod h1:zGzGCpQd78b5BNTDGHNDLaTt9aDK/A02xeZp9QeFC4U= @@ -809,8 +832,8 @@ 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-pnet v0.2.0/go.mod h1:Qqvq6JH/oMZGwqs3N1Fqhv8NVhrdYcO0BW4wssv21LA= -github.com/libp2p/go-libp2p-pubsub v0.8.3 h1:T4+pcfcFm1K2v5oFyk68peSjVroaoM8zFygf6Y5WOww= -github.com/libp2p/go-libp2p-pubsub v0.8.3/go.mod h1:eje970FXxjhtFbVEoiae+VUw24ZoSlk67BsiZPLRzlw= +github.com/libp2p/go-libp2p-pubsub v0.9.0 h1:mcLb4WzwhUG4OKb0rp1/bYMd/DYhvMyzJheQH3LMd1s= +github.com/libp2p/go-libp2p-pubsub v0.9.0/go.mod h1:OEsj0Cc/BpkqikXRTrVspWU/Hx7bMZwHP+6vNMd+c7I= github.com/libp2p/go-libp2p-pubsub-router v0.6.0 h1:D30iKdlqDt5ZmLEYhHELCMRj8b4sFAqrUcshIUvVP/s= github.com/libp2p/go-libp2p-pubsub-router v0.6.0/go.mod h1:FY/q0/RBTKsLA7l4vqC2cbRbOvyDotg8PJQ7j8FDudE= github.com/libp2p/go-libp2p-quic-transport v0.10.0/go.mod h1:RfJbZ8IqXIhxBRm5hqUEJqjiiY8xmEuq3HUDS993MkA= @@ -870,8 +893,8 @@ github.com/libp2p/go-msgio v0.0.2/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+ 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= github.com/libp2p/go-msgio v0.0.6/go.mod h1:4ecVB6d9f4BDSL5fqvPiC4A3KivjWn+Venn/1ALLMWA= -github.com/libp2p/go-msgio v0.2.0 h1:W6shmB+FeynDrUVl2dgFQvzfBZcXiyqY4VmpQLu9FqU= -github.com/libp2p/go-msgio v0.2.0/go.mod h1:dBVM1gW3Jk9XqHkU4eKdGvVHdLa51hoGfll6jMJMSlY= +github.com/libp2p/go-msgio v0.3.0 h1:mf3Z8B1xcFN314sWX+2vOTShIE0Mmn2TXn3YCUQGNj0= +github.com/libp2p/go-msgio v0.3.0/go.mod h1:nyRM819GmVaF9LX3l03RMh10QdOroF++NBbxAb0mmDM= github.com/libp2p/go-nat v0.0.3/go.mod h1:88nUEt0k0JD45Bk93NIwDqjlhiOwOoV36GchpcVc1yI= github.com/libp2p/go-nat v0.0.4/go.mod h1:Nmw50VAvKuk38jUBcmNh6p9lUJLoODbJRvYAa/+KSDo= github.com/libp2p/go-nat v0.0.5/go.mod h1:B7NxsVNPZmRLvMOwiEO1scOSyjA56zxYAGv1yQgRkEU= @@ -888,8 +911,6 @@ github.com/libp2p/go-openssl v0.0.3/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO github.com/libp2p/go-openssl v0.0.4/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= github.com/libp2p/go-openssl v0.0.5/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= github.com/libp2p/go-openssl v0.0.7/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= -github.com/libp2p/go-openssl v0.1.0 h1:LBkKEcUv6vtZIQLVTegAil8jbNpJErQ9AnT+bWV+Ooo= -github.com/libp2p/go-openssl v0.1.0/go.mod h1:OiOxwPpL3n4xlenjx2h7AwSGaFSC/KZvf6gNdOBQMtc= github.com/libp2p/go-reuseport v0.0.1/go.mod h1:jn6RmB1ufnQwl0Q1f+YxAj8isJgDCQzaaxIFYDhcYEA= github.com/libp2p/go-reuseport v0.0.2/go.mod h1:SPD+5RwGC7rcnzngoYC86GjPzjSywuQyMVAheVBD9nQ= github.com/libp2p/go-reuseport v0.2.0 h1:18PRvIMlpY6ZK85nIAicSBuXXvrYoSw3dsBAR7zc560= @@ -930,26 +951,16 @@ github.com/libp2p/zeroconf/v2 v2.2.0/go.mod h1:fuJqLnUwZTshS3U/bMRJ3+ow/v9oid1n0 github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= github.com/lucas-clemente/quic-go v0.19.3/go.mod h1:ADXpNbTQjq1hIzCpB+y/k5iz4n4z4IwqoLb94Kh5Hu8= -github.com/lucas-clemente/quic-go v0.31.1 h1:O8Od7hfioqq0PMYHDyBkxU2aA7iZ2W9pjbrWuja2YR4= -github.com/lucas-clemente/quic-go v0.31.1/go.mod h1:0wFbizLgYzqHqtlyxyCaJKlE7bYgE6JQ+54TLd/Dq2g= 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= github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/marten-seemann/qpack v0.2.1/go.mod h1:F7Gl5L1jIgN1D11ucXefiuJS9UMVP2opoCp2jDKb7wc= -github.com/marten-seemann/qpack v0.3.0 h1:UiWstOgT8+znlkDPOg2+3rIuYXJ2CnGDkGUXN6ki6hE= -github.com/marten-seemann/qpack v0.3.0/go.mod h1:cGfKPBiP4a9EQdxCwEwI/GEeWAsjSekBvx/X8mh58+g= github.com/marten-seemann/qtls v0.10.0/go.mod h1:UvMd1oaYDACI99/oZUYLzMCkBXQVT0aGm99sJhbT8hs= github.com/marten-seemann/qtls-go1-15 v0.1.1/go.mod h1:GyFwywLKkRt+6mfU99csTEY1joMZz5vmB1WNZH3P81I= -github.com/marten-seemann/qtls-go1-18 v0.1.3 h1:R4H2Ks8P6pAtUagjFty2p7BVHn3XiwDAl7TTQf5h7TI= -github.com/marten-seemann/qtls-go1-18 v0.1.3/go.mod h1:mJttiymBAByA49mhlNZZGrH5u1uXYZJ+RW28Py7f4m4= -github.com/marten-seemann/qtls-go1-19 v0.1.1 h1:mnbxeq3oEyQxQXwI4ReCgW9DPoPR94sNlqWoDZnjRIE= -github.com/marten-seemann/qtls-go1-19 v0.1.1/go.mod h1:5HTDWtVudo/WFsHKRNuOhWlbdjrfs5JHrYb0wIJqGpI= 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/marten-seemann/webtransport-go v0.4.3 h1:vkt5o/Ci+luknRteWdYGYH1KcB7ziup+J+1PzZJIvmg= -github.com/marten-seemann/webtransport-go v0.4.3/go.mod h1:4xcfySgZMLP4aG5GBGj1egP7NlpfwgYJ1WJMvPPiVMU= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= @@ -960,12 +971,11 @@ 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.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-pointer v0.0.1 h1:n+XhsuGeVO6MEAp7xyEukFINEa+Quek5psIR/ylA6o0= -github.com/mattn/go-pointer v0.0.1/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc= 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= @@ -1006,9 +1016,11 @@ github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0Qu github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= github.com/mr-tron/base58 v1.1.1/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= @@ -1074,8 +1086,8 @@ github.com/multiformats/go-multistream v0.1.0/go.mod h1:fJTiDfXJVmItycydCnNx4+wS github.com/multiformats/go-multistream v0.1.1/go.mod h1:KmHZ40hzVxiaiwlj3MEbYgK9JFk2/9UktWZAF54Du38= github.com/multiformats/go-multistream v0.2.1/go.mod h1:5GZPQZbkWOLOn3J2y4Y99vVW7vOfsAflxARk3x14o6k= github.com/multiformats/go-multistream v0.2.2/go.mod h1:UIcnm7Zuo8HKG+HkWgfQsGL+/MIEhyTqbODbIUwSXKs= -github.com/multiformats/go-multistream v0.3.3 h1:d5PZpjwRgVlbwfdTDjife7XszfZd8KYWfROYFlGcR8o= -github.com/multiformats/go-multistream v0.3.3/go.mod h1:ODRoqamLUsETKS9BNcII4gcRsJBU5VAwRIv7O39cEXg= +github.com/multiformats/go-multistream v0.4.1 h1:rFy0Iiyn3YT0asivDUIR05leAdwZq3de4741sbiSdfo= +github.com/multiformats/go-multistream v0.4.1/go.mod h1:Mz5eykRVAjJWckE2U78c6xqdtyNUEhKSM0Lwar2p77Q= github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/multiformats/go-varint v0.0.2/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= @@ -1203,6 +1215,18 @@ github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5 github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= 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/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= +github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= +github.com/quic-go/qtls-go1-18 v0.2.0 h1:5ViXqBZ90wpUcZS0ge79rf029yx0dYB0McyPJwqqj7U= +github.com/quic-go/qtls-go1-18 v0.2.0/go.mod h1:moGulGHK7o6O8lSPSZNoOwcLvJKJ85vVNc7oJFD65bc= +github.com/quic-go/qtls-go1-19 v0.2.0 h1:Cvn2WdhyViFUHoOqK52i51k4nDX8EwIh5VJiVM4nttk= +github.com/quic-go/qtls-go1-19 v0.2.0/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI= +github.com/quic-go/qtls-go1-20 v0.1.0 h1:d1PK3ErFy9t7zxKsG3NXBJXZjp/kMLoIb3y/kV54oAI= +github.com/quic-go/qtls-go1-20 v0.1.0/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= +github.com/quic-go/quic-go v0.32.0 h1:lY02md31s1JgPiiyfqJijpu/UX/Iun304FI3yUqX7tA= +github.com/quic-go/quic-go v0.32.0/go.mod h1:/fCsKANhQIeD5l76c2JFU+07gVE3KaA0FP+0zMWwfwo= +github.com/quic-go/webtransport-go v0.5.1 h1:1eVb7WDWCRoaeTtFHpFBJ6WDN1bSrPrRoW6tZgSw0Ow= +github.com/quic-go/webtransport-go v0.5.1/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= github.com/rabbitmq/amqp091-go v1.1.0/go.mod h1:ogQDLSOACsLPsIq0NpbtiifNZi2YOz0VTJ0kHRghqbM= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU= @@ -1265,7 +1289,6 @@ github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJ github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE= github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA= github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a/go.mod h1:7AyxJNCJ7SBZ1MfVQCWD6Uqo2oubI2Eq2y2eqf+A5r0= -github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU= github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= @@ -1310,7 +1333,11 @@ github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c h1:u6SKchux2yDvFQnDH github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM= github.com/ucarion/urlpath v0.0.0-20200424170820-7ccc79b76bbb h1:Ywfo8sUltxogBpFuMOFRrrSifO788kAFxmvVw31PtQQ= github.com/ucarion/urlpath v0.0.0-20200424170820-7ccc79b76bbb/go.mod h1:ikPs9bRWicNw3S7XpJ8sK/smGwU9WcSVU3dy9qahYBM= +github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= +github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= +github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= 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= @@ -1460,8 +1487,8 @@ golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWP golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210506145944-38f3c27a63bf/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= golang.org/x/crypto v0.0.0-20210920023735-84f357641f63/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.3.0 h1:a06MkbcxBrEFc0w0QIZWXrH/9cCX6KJyWbBOIwAn+7A= -golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= +golang.org/x/crypto v0.4.0 h1:UVQgzMY87xqpKNgb+kDsll2Igd33HszWHFLmpaRMq/8= +golang.org/x/crypto v0.4.0/go.mod h1:3quD/ATkf6oY+rnes5c3ExXTbLc8mueNue5/DoinL80= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1557,8 +1584,8 @@ golang.org/x/net v0.0.0-20210917221730-978cfadd31cf/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.3.0 h1:VWL6FNY2bEEmsGVKabSlHu5Irp34xmMRoqb/9lF9lxk= -golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= +golang.org/x/net v0.4.0 h1:Q5QPcMlvfxFTAPV0+07Xz/MpK9NTXu2VDUuy0FeMfaU= +golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1911,6 +1938,8 @@ honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9 lukechampine.com/blake3 v1.1.6/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= lukechampine.com/blake3 v1.1.7 h1:GgRMhmdsuK8+ii6UZFDL8Nb+VyMwadAgcJyfYHxG6n0= lukechampine.com/blake3 v1.1.7/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= +nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g= +nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= pgregory.net/rapid v0.4.7 h1:MTNRktPuv5FNqOO151TM9mDTa+XHcX6ypYeISDVD14g= pgregory.net/rapid v0.4.7/go.mod h1:UYpPVyjFHzYBGHIxLFoupi8vwk6rXNzRY9OMvVxFIOU= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= diff --git a/p2p/listener.go b/p2p/listener.go index 9b140023b..906137ea1 100644 --- a/p2p/listener.go +++ b/p2p/listener.go @@ -16,7 +16,7 @@ type Listener interface { ListenAddress() ma.Multiaddr TargetAddress() ma.Multiaddr - key() string + key() protocol.ID // close closes the listener. Does not affect child streams close() @@ -27,21 +27,21 @@ type Listener interface { type Listeners struct { sync.RWMutex - Listeners map[string]Listener + Listeners map[protocol.ID]Listener } func newListenersLocal() *Listeners { return &Listeners{ - Listeners: map[string]Listener{}, + Listeners: map[protocol.ID]Listener{}, } } func newListenersP2P(host p2phost.Host) *Listeners { reg := &Listeners{ - Listeners: map[string]Listener{}, + Listeners: map[protocol.ID]Listener{}, } - host.SetStreamHandlerMatch("/x/", func(p string) bool { + host.SetStreamHandlerMatch("/x/", func(p protocol.ID) bool { reg.RLock() defer reg.RUnlock() @@ -51,7 +51,7 @@ func newListenersP2P(host p2phost.Host) *Listeners { reg.RLock() defer reg.RUnlock() - l := reg.Listeners[string(stream.Protocol())] + l := reg.Listeners[stream.Protocol()] if l != nil { go l.(*remoteListener).handleStream(stream) } diff --git a/p2p/local.go b/p2p/local.go index 17e1f1aee..85baf948b 100644 --- a/p2p/local.go +++ b/p2p/local.go @@ -9,7 +9,7 @@ import ( "github.com/libp2p/go-libp2p/core/peer" "github.com/libp2p/go-libp2p/core/protocol" ma "github.com/multiformats/go-multiaddr" - "github.com/multiformats/go-multiaddr/net" + manet "github.com/multiformats/go-multiaddr/net" ) // localListener manet streams and proxies them to libp2p services @@ -52,7 +52,7 @@ func (p2p *P2P) ForwardLocal(ctx context.Context, peer peer.ID, proto protocol.I } func (l *localListener) dial(ctx context.Context) (net.Stream, error) { - cctx, cancel := context.WithTimeout(ctx, time.Second*30) //TODO: configurable? + cctx, cancel := context.WithTimeout(ctx, time.Second*30) // TODO: configurable? defer cancel() return l.p2p.peerHost.NewStream(cctx, l.peer, l.proto) @@ -116,6 +116,6 @@ func (l *localListener) TargetAddress() ma.Multiaddr { return addr } -func (l *localListener) key() string { - return l.ListenAddress().String() +func (l *localListener) key() protocol.ID { + return protocol.ID(l.ListenAddress().String()) } diff --git a/p2p/p2p.go b/p2p/p2p.go index c429760b0..e18488c2d 100644 --- a/p2p/p2p.go +++ b/p2p/p2p.go @@ -3,8 +3,9 @@ package p2p import ( logging "github.com/ipfs/go-log" p2phost "github.com/libp2p/go-libp2p/core/host" - peer "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/peer" pstore "github.com/libp2p/go-libp2p/core/peerstore" + "github.com/libp2p/go-libp2p/core/protocol" ) var log = logging.Logger("p2p-mount") @@ -40,7 +41,7 @@ func New(identity peer.ID, peerHost p2phost.Host, peerstore pstore.Peerstore) *P // CheckProtoExists checks whether a proto handler is registered to // mux handler -func (p2p *P2P) CheckProtoExists(proto string) bool { +func (p2p *P2P) CheckProtoExists(proto protocol.ID) bool { protos := p2p.peerHost.Mux().Protocols() for _, p := range protos { diff --git a/p2p/remote.go b/p2p/remote.go index d10600486..ac540e9a5 100644 --- a/p2p/remote.go +++ b/p2p/remote.go @@ -5,7 +5,7 @@ import ( "fmt" net "github.com/libp2p/go-libp2p/core/network" - protocol "github.com/libp2p/go-libp2p/core/protocol" + "github.com/libp2p/go-libp2p/core/protocol" ma "github.com/multiformats/go-multiaddr" manet "github.com/multiformats/go-multiaddr/net" ) @@ -101,6 +101,6 @@ func (l *remoteListener) TargetAddress() ma.Multiaddr { func (l *remoteListener) close() {} -func (l *remoteListener) key() string { - return string(l.proto) +func (l *remoteListener) key() protocol.ID { + return l.proto } From 0ff406170dd9fe010a5ff9d02a8776c47e4711a3 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Tue, 14 Feb 2023 10:42:53 +0100 Subject: [PATCH 0470/1212] fix: update rcmgr for go-libp2p v0.25 --- config/swarm.go | 4 +- core/commands/swarm.go | 19 +- core/node/libp2p/rcmgr.go | 252 ++++++++++-------- core/node/libp2p/rcmgr_defaults.go | 13 +- core/node/libp2p/rcmgr_logging_test.go | 5 +- docs/examples/kubo-as-a-library/go.mod | 33 ++- docs/examples/kubo-as-a-library/go.sum | 93 ++++--- go.mod | 4 +- go.sum | 4 +- .../t0116-prometheus-data/prometheus_metrics | 193 ++------------ test/sharness/t0139-swarm-rcmgr.sh | 20 +- 11 files changed, 274 insertions(+), 366 deletions(-) diff --git a/config/swarm.go b/config/swarm.go index d8fd17e94..abff91422 100644 --- a/config/swarm.go +++ b/config/swarm.go @@ -141,8 +141,8 @@ type ConnMgr struct { // type ResourceMgr struct { // Enables the Network Resource Manager feature, default to on. - Enabled Flag `json:",omitempty"` - Limits *rcmgr.LimitConfig `json:",omitempty"` + Enabled Flag `json:",omitempty"` + Limits *rcmgr.PartialLimitConfig `json:",omitempty"` MaxMemory *OptionalString `json:",omitempty"` MaxFileDescriptors *OptionalInteger `json:",omitempty"` diff --git a/core/commands/swarm.go b/core/commands/swarm.go index d00291f78..a4bb705f9 100644 --- a/core/commands/swarm.go +++ b/core/commands/swarm.go @@ -80,8 +80,8 @@ var swarmPeeringCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "Modify the peering subsystem.", ShortDescription: ` -'ipfs swarm peering' manages the peering subsystem. -Peers in the peering subsystem are maintained to be connected, reconnected +'ipfs swarm peering' manages the peering subsystem. +Peers in the peering subsystem are maintained to be connected, reconnected on disconnect with a back-off. The changes are not saved to the config. `, @@ -430,7 +430,7 @@ Changes made via command line are persisted in the Swarm.ResourceMgr.Limits fiel // set scope limit to new values (when limit.json is passed as a second arg) if req.Files != nil { - var newLimit rcmgr.BaseLimit + var newLimit rcmgr.ResourceLimits it := req.Files.Entries() if it.Next() { file := files.FileFromEntry(it) @@ -451,20 +451,23 @@ Changes made via command line are persisted in the Swarm.ResourceMgr.Limits fiel } var result interface{} - _, reset := req.Options[swarmResetLimitsOptionName] - if reset { + switch _, reset := req.Options[swarmResetLimitsOptionName]; { + case reset: result, err = libp2p.NetResetLimit(node.ResourceManager, node.Repo, scope) - } else if scope == "all" { + case scope == "all": result, err = libp2p.NetLimitAll(node.ResourceManager) - } else { + default: // get scope limit result, err = libp2p.NetLimit(node.ResourceManager, scope) } - if err != nil { return err } + if base, ok := result.(rcmgr.BaseLimit); ok { + result = base.ToResourceLimits() + } + b := new(bytes.Buffer) enc := json.NewEncoder(b) err = enc.Encode(result) diff --git a/core/node/libp2p/rcmgr.go b/core/node/libp2p/rcmgr.go index 205dfe26b..0d7ac761c 100644 --- a/core/node/libp2p/rcmgr.go +++ b/core/node/libp2p/rcmgr.go @@ -17,12 +17,15 @@ import ( rcmgrObs "github.com/libp2p/go-libp2p/p2p/host/resource-manager/obs" "github.com/multiformats/go-multiaddr" "go.uber.org/fx" + "golang.org/x/exp/constraints" "github.com/ipfs/kubo/config" "github.com/ipfs/kubo/core/node/helpers" "github.com/ipfs/kubo/repo" ) +// FIXME(@Jorropo): for go-libp2p v0.26.0 use .MustConcrete and .MustBaseLimit instead of .Build(rcmgr.BaseLimit{}). + const NetLimitDefaultFilename = "limit.json" const NetLimitTraceFilename = "rcmgr.json.gz" @@ -51,7 +54,7 @@ func ResourceManager(cfg config.SwarmConfig) interface{} { return nil, opts, fmt.Errorf("opening IPFS_PATH: %w", err) } - var limitConfig rcmgr.LimitConfig + var limitConfig rcmgr.ConcreteLimitConfig defaultComputedLimitConfig, err := createDefaultLimitConfig(cfg) if err != nil { return nil, opts, err @@ -66,8 +69,7 @@ func ResourceManager(cfg config.SwarmConfig) interface{} { // Because of how how Apply works, any 0 value for a user supplied override // will be overriden with a computed default value. // There currently isn't a way for a user to supply a 0-value override. - userSuppliedOverrideLimitConfig.Apply(defaultComputedLimitConfig) - limitConfig = userSuppliedOverrideLimitConfig + limitConfig = userSuppliedOverrideLimitConfig.Build(defaultComputedLimitConfig) } else { limitConfig = defaultComputedLimitConfig } @@ -131,12 +133,36 @@ func ResourceManager(cfg config.SwarmConfig) interface{} { } } +type notOmitEmptyResourceLimit struct { + Streams rcmgr.LimitVal + StreamsInbound rcmgr.LimitVal + StreamsOutbound rcmgr.LimitVal + Conns rcmgr.LimitVal + ConnsInbound rcmgr.LimitVal + ConnsOutbound rcmgr.LimitVal + FD rcmgr.LimitVal + Memory rcmgr.LimitVal64 +} + +func resourceLimitsToNotOmitEmpty(r rcmgr.ResourceLimits) notOmitEmptyResourceLimit { + return notOmitEmptyResourceLimit{ + Streams: r.Streams, + StreamsInbound: r.StreamsInbound, + StreamsOutbound: r.StreamsOutbound, + Conns: r.Conns, + ConnsInbound: r.ConnsInbound, + ConnsOutbound: r.ConnsOutbound, + FD: r.FD, + Memory: r.Memory, + } +} + type NetStatOut struct { - System *rcmgr.BaseLimit `json:",omitempty"` - Transient *rcmgr.BaseLimit `json:",omitempty"` - Services map[string]rcmgr.BaseLimit `json:",omitempty"` - Protocols map[string]rcmgr.BaseLimit `json:",omitempty"` - Peers map[string]rcmgr.BaseLimit `json:",omitempty"` + System *notOmitEmptyResourceLimit `json:",omitempty"` + Transient *notOmitEmptyResourceLimit `json:",omitempty"` + Services map[string]notOmitEmptyResourceLimit `json:",omitempty"` + Protocols map[string]notOmitEmptyResourceLimit `json:",omitempty"` + Peers map[string]notOmitEmptyResourceLimit `json:",omitempty"` } func NetStat(mgr network.ResourceManager, scope string, percentage int) (NetStatOut, error) { @@ -155,35 +181,36 @@ func NetStat(mgr network.ResourceManager, scope string, percentage int) (NetStat } stat := rapi.Stat() - result.System = compareLimits(scopeToLimit(&stat.System), limits.System, percentage) - result.Transient = compareLimits(scopeToLimit(&stat.Transient), limits.Transient, percentage) + if s := scopeToLimit(stat.System); compareLimits(s, *limits.System, percentage) { + result.System = &s + } + if s := scopeToLimit(stat.Transient); compareLimits(s, *limits.Transient, percentage) { + result.Transient = &s + } if len(stat.Services) > 0 { - result.Services = make(map[string]rcmgr.BaseLimit, len(stat.Services)) - for srv, stat := range stat.Services { + result.Services = make(map[string]notOmitEmptyResourceLimit, len(stat.Services)) + for srv, s := range stat.Services { ls := limits.Services[srv] - fstat := compareLimits(scopeToLimit(&stat), &ls, percentage) - if fstat != nil { - result.Services[srv] = *fstat + if stat := scopeToLimit(s); compareLimits(stat, ls, percentage) { + result.Services[srv] = stat } } } if len(stat.Protocols) > 0 { - result.Protocols = make(map[string]rcmgr.BaseLimit, len(stat.Protocols)) - for proto, stat := range stat.Protocols { + result.Protocols = make(map[string]notOmitEmptyResourceLimit, len(stat.Protocols)) + for proto, s := range stat.Protocols { ls := limits.Protocols[string(proto)] - fstat := compareLimits(scopeToLimit(&stat), &ls, percentage) - if fstat != nil { - result.Protocols[string(proto)] = *fstat + if stat := scopeToLimit(s); compareLimits(stat, ls, percentage) { + result.Protocols[string(proto)] = stat } } } if len(stat.Peers) > 0 { - result.Peers = make(map[string]rcmgr.BaseLimit, len(stat.Peers)) - for p, stat := range stat.Peers { + result.Peers = make(map[string]notOmitEmptyResourceLimit, len(stat.Peers)) + for p, s := range stat.Peers { ls := limits.Peers[p.Pretty()] - fstat := compareLimits(scopeToLimit(&stat), &ls, percentage) - if fstat != nil { - result.Peers[p.Pretty()] = *fstat + if stat := scopeToLimit(s); compareLimits(stat, ls, percentage) { + result.Peers[p.Pretty()] = stat } } } @@ -192,16 +219,16 @@ func NetStat(mgr network.ResourceManager, scope string, percentage int) (NetStat case scope == config.ResourceMgrSystemScope: err = mgr.ViewSystem(func(s network.ResourceScope) error { - stat := s.Stat() - result.System = scopeToLimit(&stat) + stat := scopeToLimit(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 = scopeToLimit(&stat) + stat := scopeToLimit(s.Stat()) + result.Transient = &stat return nil }) return result, err @@ -209,9 +236,8 @@ func NetStat(mgr network.ResourceManager, scope string, percentage int) (NetStat case strings.HasPrefix(scope, config.ResourceMgrServiceScopePrefix): svc := strings.TrimPrefix(scope, config.ResourceMgrServiceScopePrefix) err = mgr.ViewService(svc, func(s network.ServiceScope) error { - stat := s.Stat() - result.Services = map[string]rcmgr.BaseLimit{ - svc: *scopeToLimit(&stat), + result.Services = map[string]notOmitEmptyResourceLimit{ + svc: scopeToLimit(s.Stat()), } return nil }) @@ -220,9 +246,8 @@ func NetStat(mgr network.ResourceManager, scope string, percentage int) (NetStat case strings.HasPrefix(scope, config.ResourceMgrProtocolScopePrefix): proto := strings.TrimPrefix(scope, config.ResourceMgrProtocolScopePrefix) err = mgr.ViewProtocol(protocol.ID(proto), func(s network.ProtocolScope) error { - stat := s.Stat() - result.Protocols = map[string]rcmgr.BaseLimit{ - proto: *scopeToLimit(&stat), + result.Protocols = map[string]notOmitEmptyResourceLimit{ + proto: scopeToLimit(s.Stat()), } return nil }) @@ -235,9 +260,8 @@ func NetStat(mgr network.ResourceManager, scope string, percentage int) (NetStat 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]rcmgr.BaseLimit{ - p: *scopeToLimit(&stat), + result.Peers = map[string]notOmitEmptyResourceLimit{ + p: scopeToLimit(s.Stat()), } return nil }) @@ -256,55 +280,52 @@ var scopes = []string{ config.ResourceMgrPeerScopePrefix, } -func scopeToLimit(s *network.ScopeStat) *rcmgr.BaseLimit { - return &rcmgr.BaseLimit{ - Streams: s.NumStreamsInbound + s.NumStreamsOutbound, - StreamsInbound: s.NumStreamsInbound, - StreamsOutbound: s.NumStreamsOutbound, - Conns: s.NumConnsInbound + s.NumConnsOutbound, - ConnsInbound: s.NumConnsInbound, - ConnsOutbound: s.NumConnsOutbound, - FD: s.NumFD, - Memory: s.Memory, +func scopeToLimit(s network.ScopeStat) notOmitEmptyResourceLimit { + return notOmitEmptyResourceLimit{ + Streams: rcmgr.LimitVal(s.NumStreamsInbound + s.NumStreamsOutbound), + StreamsInbound: rcmgr.LimitVal(s.NumStreamsInbound), + StreamsOutbound: rcmgr.LimitVal(s.NumStreamsOutbound), + Conns: rcmgr.LimitVal(s.NumConnsInbound + s.NumConnsOutbound), + ConnsInbound: rcmgr.LimitVal(s.NumConnsInbound), + ConnsOutbound: rcmgr.LimitVal(s.NumConnsOutbound), + FD: rcmgr.LimitVal(s.NumFD), + Memory: rcmgr.LimitVal64(s.Memory), } } // compareLimits compares stat and limit. // If any of the stats value are equals or above the specified percentage, -// stat object is returned. -func compareLimits(stat, limit *rcmgr.BaseLimit, percentage int) *rcmgr.BaseLimit { - if stat == nil || limit == nil { - return nil - } +// it returns true. +func compareLimits(stat, limit notOmitEmptyResourceLimit, percentage int) bool { if abovePercentage(int(stat.Memory), int(limit.Memory), percentage) { - return stat + return true } if abovePercentage(stat.ConnsInbound, limit.ConnsInbound, percentage) { - return stat + return true } if abovePercentage(stat.ConnsOutbound, limit.ConnsOutbound, percentage) { - return stat + return true } if abovePercentage(stat.Conns, limit.Conns, percentage) { - return stat + return true } if abovePercentage(stat.FD, limit.FD, percentage) { - return stat + return true } if abovePercentage(stat.StreamsInbound, limit.StreamsInbound, percentage) { - return stat + return true } if abovePercentage(stat.StreamsOutbound, limit.StreamsOutbound, percentage) { - return stat + return true } if abovePercentage(stat.Streams, limit.Streams, percentage) { - return stat + return true } - return nil + return false } -func abovePercentage(v1, v2, percentage int) bool { +func abovePercentage[T constraints.Integer | constraints.Float](v1, v2 T, percentage int) bool { if percentage == 0 { return true } @@ -338,7 +359,7 @@ func NetLimitAll(mgr network.ResourceManager) (*NetStatOut, error) { } result.Transient = &s case config.ResourceMgrServiceScopePrefix: - result.Services = make(map[string]rcmgr.BaseLimit) + result.Services = make(map[string]notOmitEmptyResourceLimit) for _, serv := range lister.ListServices() { s, err := NetLimit(mgr, config.ResourceMgrServiceScopePrefix+serv) if err != nil { @@ -347,7 +368,7 @@ func NetLimitAll(mgr network.ResourceManager) (*NetStatOut, error) { result.Services[serv] = s } case config.ResourceMgrProtocolScopePrefix: - result.Protocols = make(map[string]rcmgr.BaseLimit) + result.Protocols = make(map[string]notOmitEmptyResourceLimit) for _, prot := range lister.ListProtocols() { ps := string(prot) s, err := NetLimit(mgr, config.ResourceMgrProtocolScopePrefix+ps) @@ -357,7 +378,7 @@ func NetLimitAll(mgr network.ResourceManager) (*NetStatOut, error) { result.Protocols[ps] = s } case config.ResourceMgrPeerScopePrefix: - result.Peers = make(map[string]rcmgr.BaseLimit) + result.Peers = make(map[string]notOmitEmptyResourceLimit) for _, peer := range lister.ListPeers() { ps := peer.Pretty() s, err := NetLimit(mgr, config.ResourceMgrPeerScopePrefix+ps) @@ -372,24 +393,19 @@ func NetLimitAll(mgr network.ResourceManager) (*NetStatOut, error) { return result, nil } -func NetLimit(mgr network.ResourceManager, scope string) (rcmgr.BaseLimit, error) { - var result rcmgr.BaseLimit +func NetLimit(mgr network.ResourceManager, scope string) (notOmitEmptyResourceLimit, error) { + var result rcmgr.ResourceLimits getLimit := func(s network.ResourceScope) error { limiter, ok := s.(rcmgr.ResourceScopeLimiter) if !ok { // NullResourceManager return ErrNoResourceMgr } - limit := limiter.Limit() - switch l := limit.(type) { + + switch limit := limiter.Limit(); l := limit.(type) { case *rcmgr.BaseLimit: - result.Memory = l.Memory - result.Streams = l.Streams - result.StreamsInbound = l.StreamsInbound - result.StreamsOutbound = l.StreamsOutbound - result.Conns = l.Conns - result.ConnsInbound = l.ConnsInbound - result.ConnsOutbound = l.ConnsOutbound - result.FD = l.FD + result = l.ToResourceLimits() + case rcmgr.BaseLimit: + result = l.ToResourceLimits() default: return fmt.Errorf("unknown limit type %T", limit) } @@ -397,38 +413,42 @@ func NetLimit(mgr network.ResourceManager, scope string) (rcmgr.BaseLimit, error return nil } + var err error switch { case scope == config.ResourceMgrSystemScope: - return result, mgr.ViewSystem(func(s network.ResourceScope) error { return getLimit(s) }) + err = mgr.ViewSystem(func(s network.ResourceScope) error { return getLimit(s) }) case scope == config.ResourceMgrTransientScope: - return result, mgr.ViewTransient(func(s network.ResourceScope) error { return getLimit(s) }) + err = mgr.ViewTransient(func(s network.ResourceScope) error { return getLimit(s) }) case strings.HasPrefix(scope, config.ResourceMgrServiceScopePrefix): svc := strings.TrimPrefix(scope, config.ResourceMgrServiceScopePrefix) - return result, mgr.ViewService(svc, func(s network.ServiceScope) error { return getLimit(s) }) + err = mgr.ViewService(svc, func(s network.ServiceScope) error { return getLimit(s) }) case strings.HasPrefix(scope, config.ResourceMgrProtocolScopePrefix): proto := strings.TrimPrefix(scope, config.ResourceMgrProtocolScopePrefix) - return result, mgr.ViewProtocol(protocol.ID(proto), func(s network.ProtocolScope) error { return getLimit(s) }) + err = mgr.ViewProtocol(protocol.ID(proto), func(s network.ProtocolScope) error { return getLimit(s) }) case strings.HasPrefix(scope, config.ResourceMgrPeerScopePrefix): p := strings.TrimPrefix(scope, config.ResourceMgrPeerScopePrefix) - pid, err := peer.Decode(p) + var pid peer.ID + pid, err = peer.Decode(p) if err != nil { - return result, fmt.Errorf("invalid peer ID: %q: %w", p, err) + return notOmitEmptyResourceLimit{}, fmt.Errorf("invalid peer ID: %q: %w", p, err) } - return result, mgr.ViewPeer(pid, func(s network.PeerScope) error { return getLimit(s) }) + err = mgr.ViewPeer(pid, func(s network.PeerScope) error { return getLimit(s) }) default: - return result, fmt.Errorf("invalid scope %q", scope) + err = fmt.Errorf("invalid scope %q", scope) } + return resourceLimitsToNotOmitEmpty(result), err } // NetSetLimit sets new ResourceManager limits for the given scope. The limits take effect immediately, and are also persisted to the repo config. -func NetSetLimit(mgr network.ResourceManager, repo repo.Repo, scope string, limit rcmgr.BaseLimit) error { +func NetSetLimit(mgr network.ResourceManager, repo repo.Repo, scope string, limit rcmgr.ResourceLimits) error { setLimit := func(s network.ResourceScope) error { limiter, ok := s.(rcmgr.ResourceScopeLimiter) if !ok { // NullResourceManager return ErrNoResourceMgr } - limiter.SetLimit(&limit) + l := rcmgr.InfiniteLimits.ToPartialLimitConfig().System + limiter.SetLimit(limit.Build(l.Build(rcmgr.BaseLimit{}))) return nil } @@ -438,7 +458,7 @@ func NetSetLimit(mgr network.ResourceManager, repo repo.Repo, scope string, limi } if cfg.Swarm.ResourceMgr.Limits == nil { - cfg.Swarm.ResourceMgr.Limits = &rcmgr.LimitConfig{} + cfg.Swarm.ResourceMgr.Limits = &rcmgr.PartialLimitConfig{} } configLimits := cfg.Swarm.ResourceMgr.Limits @@ -455,7 +475,7 @@ func NetSetLimit(mgr network.ResourceManager, repo repo.Repo, scope string, limi err = mgr.ViewService(svc, func(s network.ServiceScope) error { return setLimit(s) }) setConfigFunc = func() { if configLimits.Service == nil { - configLimits.Service = map[string]rcmgr.BaseLimit{} + configLimits.Service = map[string]rcmgr.ResourceLimits{} } configLimits.Service[svc] = limit } @@ -464,7 +484,7 @@ func NetSetLimit(mgr network.ResourceManager, repo repo.Repo, scope string, limi err = mgr.ViewProtocol(protocol.ID(proto), func(s network.ProtocolScope) error { return setLimit(s) }) setConfigFunc = func() { if configLimits.Protocol == nil { - configLimits.Protocol = map[protocol.ID]rcmgr.BaseLimit{} + configLimits.Protocol = map[protocol.ID]rcmgr.ResourceLimits{} } configLimits.Protocol[protocol.ID(proto)] = limit } @@ -478,7 +498,7 @@ func NetSetLimit(mgr network.ResourceManager, repo repo.Repo, scope string, limi err = mgr.ViewPeer(pid, func(s network.PeerScope) error { return setLimit(s) }) setConfigFunc = func() { if configLimits.Peer == nil { - configLimits.Peer = map[peer.ID]rcmgr.BaseLimit{} + configLimits.Peer = map[peer.ID]rcmgr.ResourceLimits{} } configLimits.Peer[pid] = limit } @@ -491,7 +511,7 @@ func NetSetLimit(mgr network.ResourceManager, repo repo.Repo, scope string, limi } if cfg.Swarm.ResourceMgr.Limits == nil { - cfg.Swarm.ResourceMgr.Limits = &rcmgr.LimitConfig{} + cfg.Swarm.ResourceMgr.Limits = &rcmgr.PartialLimitConfig{} } setConfigFunc() @@ -518,55 +538,62 @@ func NetResetLimit(mgr network.ResourceManager, repo repo.Repo, scope string) (r cfg, err := repo.Config() if err != nil { - return result, fmt.Errorf("reading config to reset limit: %w", err) + return rcmgr.BaseLimit{}, fmt.Errorf("reading config to reset limit: %w", err) } - defaults, err := createDefaultLimitConfig(cfg.Swarm) + defaultsOrig, err := createDefaultLimitConfig(cfg.Swarm) if err != nil { - return result, fmt.Errorf("creating default limit config: %w", err) + return rcmgr.BaseLimit{}, fmt.Errorf("creating default limit config: %w", err) } + defaults := defaultsOrig.ToPartialLimitConfig() + + // INVESTIGATE(@Jorropo): Why do we save scaled configs in the repo ? if cfg.Swarm.ResourceMgr.Limits == nil { - cfg.Swarm.ResourceMgr.Limits = &rcmgr.LimitConfig{} + cfg.Swarm.ResourceMgr.Limits = &rcmgr.PartialLimitConfig{} } configLimits := cfg.Swarm.ResourceMgr.Limits var setConfigFunc func() rcmgr.BaseLimit switch { case scope == config.ResourceMgrSystemScope: - err = mgr.ViewSystem(func(s network.ResourceScope) error { return setLimit(s, &defaults.System) }) + err = mgr.ViewSystem(func(s network.ResourceScope) error { return setLimit(s, defaults.System.Build(rcmgr.BaseLimit{})) }) setConfigFunc = func() rcmgr.BaseLimit { configLimits.System = defaults.System - return defaults.System + return defaults.System.Build(rcmgr.BaseLimit{}) } case scope == config.ResourceMgrTransientScope: - err = mgr.ViewTransient(func(s network.ResourceScope) error { return setLimit(s, &defaults.Transient) }) + err = mgr.ViewTransient(func(s network.ResourceScope) error { return setLimit(s, defaults.Transient.Build(rcmgr.BaseLimit{})) }) setConfigFunc = func() rcmgr.BaseLimit { configLimits.Transient = defaults.Transient - return defaults.Transient + return defaults.Transient.Build(rcmgr.BaseLimit{}) } case strings.HasPrefix(scope, config.ResourceMgrServiceScopePrefix): svc := strings.TrimPrefix(scope, config.ResourceMgrServiceScopePrefix) - err = mgr.ViewService(svc, func(s network.ServiceScope) error { return setLimit(s, &defaults.ServiceDefault) }) + err = mgr.ViewService(svc, func(s network.ServiceScope) error { + return setLimit(s, defaults.ServiceDefault.Build(rcmgr.BaseLimit{})) + }) setConfigFunc = func() rcmgr.BaseLimit { if configLimits.Service == nil { - configLimits.Service = map[string]rcmgr.BaseLimit{} + configLimits.Service = map[string]rcmgr.ResourceLimits{} } configLimits.Service[svc] = defaults.ServiceDefault - return defaults.ServiceDefault + return defaults.ServiceDefault.Build(rcmgr.BaseLimit{}) } case strings.HasPrefix(scope, config.ResourceMgrProtocolScopePrefix): proto := strings.TrimPrefix(scope, config.ResourceMgrProtocolScopePrefix) - err = mgr.ViewProtocol(protocol.ID(proto), func(s network.ProtocolScope) error { return setLimit(s, &defaults.ProtocolDefault) }) + err = mgr.ViewProtocol(protocol.ID(proto), func(s network.ProtocolScope) error { + return setLimit(s, defaults.ProtocolDefault.Build(rcmgr.BaseLimit{})) + }) setConfigFunc = func() rcmgr.BaseLimit { if configLimits.Protocol == nil { - configLimits.Protocol = map[protocol.ID]rcmgr.BaseLimit{} + configLimits.Protocol = map[protocol.ID]rcmgr.ResourceLimits{} } configLimits.Protocol[protocol.ID(proto)] = defaults.ProtocolDefault - return defaults.ProtocolDefault + return defaults.ProtocolDefault.Build(rcmgr.BaseLimit{}) } case strings.HasPrefix(scope, config.ResourceMgrPeerScopePrefix): p := strings.TrimPrefix(scope, config.ResourceMgrPeerScopePrefix) @@ -577,14 +604,14 @@ func NetResetLimit(mgr network.ResourceManager, repo repo.Repo, scope string) (r return result, fmt.Errorf("invalid peer ID: %q: %w", p, err) } - err = mgr.ViewPeer(pid, func(s network.PeerScope) error { return setLimit(s, &defaults.PeerDefault) }) + err = mgr.ViewPeer(pid, func(s network.PeerScope) error { return setLimit(s, defaults.PeerDefault.Build(rcmgr.BaseLimit{})) }) setConfigFunc = func() rcmgr.BaseLimit { if configLimits.Peer == nil { - configLimits.Peer = map[peer.ID]rcmgr.BaseLimit{} + configLimits.Peer = map[peer.ID]rcmgr.ResourceLimits{} } configLimits.Peer[pid] = defaults.PeerDefault - return defaults.PeerDefault + return defaults.PeerDefault.Build(rcmgr.BaseLimit{}) } default: return result, fmt.Errorf("invalid scope %q", scope) @@ -603,10 +630,13 @@ func NetResetLimit(mgr network.ResourceManager, repo repo.Repo, scope string) (r return result, nil } -func ensureConnMgrMakeSenseVsResourceMgr(rcm rcmgr.LimitConfig, cmgr config.ConnMgr) error { +func ensureConnMgrMakeSenseVsResourceMgr(orig rcmgr.ConcreteLimitConfig, cmgr config.ConnMgr) error { if cmgr.Type.WithDefault(config.DefaultConnMgrType) == "none" { return nil // none connmgr, no checks to do } + + rcm := orig.ToPartialLimitConfig() + highWater := cmgr.HighWater.WithDefault(config.DefaultConnMgrHighWater) if rcm.System.ConnsInbound <= rcm.System.Conns { if int64(rcm.System.ConnsInbound) <= highWater { diff --git a/core/node/libp2p/rcmgr_defaults.go b/core/node/libp2p/rcmgr_defaults.go index 9a3825108..05dda7745 100644 --- a/core/node/libp2p/rcmgr_defaults.go +++ b/core/node/libp2p/rcmgr_defaults.go @@ -46,12 +46,12 @@ var noLimitIncrease = rcmgr.BaseLimitIncrease{ // createDefaultLimitConfig creates LimitConfig to pass to libp2p's resource manager. // The defaults follow the documentation in docs/libp2p-resource-management.md. // Any changes in the logic here should be reflected there. -func createDefaultLimitConfig(cfg config.SwarmConfig) (rcmgr.LimitConfig, error) { +func createDefaultLimitConfig(cfg config.SwarmConfig) (rcmgr.ConcreteLimitConfig, error) { maxMemoryDefaultString := humanize.Bytes(uint64(memory.TotalMemory()) / 2) maxMemoryString := cfg.ResourceMgr.MaxMemory.WithDefault(maxMemoryDefaultString) maxMemory, err := humanize.ParseBytes(maxMemoryString) if err != nil { - return rcmgr.LimitConfig{}, err + return rcmgr.ConcreteLimitConfig{}, err } maxMemoryMB := maxMemory / (1024 * 1024) @@ -173,7 +173,8 @@ Run 'ipfs swarm limit all' to see the resulting limits. // Whatever limits libp2p has specifically tuned for its protocols/services we'll apply. libp2p.SetDefaultServiceLimits(&scalingLimitConfig) - defaultLimitConfig := scalingLimitConfig.Scale(int64(maxMemory), maxFD) + orig := scalingLimitConfig.Scale(int64(maxMemory), maxFD) + defaultLimitConfig := orig.ToPartialLimitConfig() // Simple checks to overide autoscaling ensuring limits make sense versus the connmgr values. // There are ways to break this, but this should catch most problems already. @@ -190,9 +191,9 @@ Run 'ipfs swarm limit all' to see the resulting limits. } // Scale System.StreamsInbound as well, but use the existing ratio of StreamsInbound to ConnsInbound - defaultLimitConfig.System.StreamsInbound = int(maxInboundConns * int64(defaultLimitConfig.System.StreamsInbound) / int64(defaultLimitConfig.System.ConnsInbound)) - defaultLimitConfig.System.ConnsInbound = int(maxInboundConns) + defaultLimitConfig.System.StreamsInbound = rcmgr.LimitVal(maxInboundConns * int64(defaultLimitConfig.System.StreamsInbound) / int64(defaultLimitConfig.System.ConnsInbound)) + defaultLimitConfig.System.ConnsInbound = rcmgr.LimitVal(maxInboundConns) } - return defaultLimitConfig, nil + return defaultLimitConfig.Build(orig), nil } diff --git a/core/node/libp2p/rcmgr_logging_test.go b/core/node/libp2p/rcmgr_logging_test.go index 512168d4a..559a3fec3 100644 --- a/core/node/libp2p/rcmgr_logging_test.go +++ b/core/node/libp2p/rcmgr_logging_test.go @@ -16,11 +16,12 @@ import ( func TestLoggingResourceManager(t *testing.T) { clock := clock.NewMock() - limits := rcmgr.DefaultLimits.AutoScale() + orig := rcmgr.DefaultLimits.AutoScale() + limits := orig.ToPartialLimitConfig() limits.System.Conns = 1 limits.System.ConnsInbound = 1 limits.System.ConnsOutbound = 1 - limiter := rcmgr.NewFixedLimiter(limits) + limiter := rcmgr.NewFixedLimiter(limits.Build(orig)) rm, err := rcmgr.NewResourceManager(limiter) if err != nil { t.Fatal(err) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 644bee498..981af294c 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,10 +7,10 @@ go 1.18 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/go-libipfs v0.4.1-0.20230208022905-378aaf777cf9 + github.com/ipfs/go-libipfs v0.5.0 github.com/ipfs/interface-go-ipfs-core v0.11.0 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 - github.com/libp2p/go-libp2p v0.24.2 + github.com/libp2p/go-libp2p v0.25.2-0.20230214091718-aef956be688d github.com/multiformats/go-multiaddr v0.8.0 ) @@ -54,12 +54,12 @@ require ( github.com/google/pprof v0.0.0-20221203041831-ce31453925ec // indirect github.com/google/uuid v1.3.0 // indirect github.com/gorilla/mux v1.8.0 // indirect - github.com/gorilla/websocket v1.5.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 // indirect github.com/hannahhoward/go-pubsub v0.0.0-20200423002714-8d62886cc36e // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/golang-lru v0.5.4 // indirect + github.com/hashicorp/golang-lru/v2 v2.0.1 // indirect github.com/huin/goupnp v1.0.3 // indirect github.com/ipfs/bbloom v0.0.4 // indirect github.com/ipfs/go-bitfield v1.0.0 // indirect @@ -120,29 +120,22 @@ require ( github.com/libp2p/go-doh-resolver v0.4.0 // indirect github.com/libp2p/go-flow-metrics v0.1.0 // indirect github.com/libp2p/go-libp2p-asn-util v0.2.0 // indirect - github.com/libp2p/go-libp2p-kad-dht v0.20.0 // indirect + github.com/libp2p/go-libp2p-kad-dht v0.21.0 // indirect github.com/libp2p/go-libp2p-kbucket v0.5.0 // indirect - github.com/libp2p/go-libp2p-pubsub v0.8.3 // indirect + github.com/libp2p/go-libp2p-pubsub v0.9.0 // indirect github.com/libp2p/go-libp2p-pubsub-router v0.6.0 // indirect github.com/libp2p/go-libp2p-record v0.2.0 // indirect github.com/libp2p/go-libp2p-routing-helpers v0.6.1 // indirect github.com/libp2p/go-libp2p-xor v0.1.0 // indirect github.com/libp2p/go-mplex v0.7.0 // indirect - github.com/libp2p/go-msgio v0.2.0 // indirect + github.com/libp2p/go-msgio v0.3.0 // indirect github.com/libp2p/go-nat v0.1.0 // indirect github.com/libp2p/go-netroute v0.2.1 // indirect - github.com/libp2p/go-openssl v0.1.0 // indirect github.com/libp2p/go-reuseport v0.2.0 // indirect github.com/libp2p/go-yamux/v4 v4.0.0 // indirect github.com/libp2p/zeroconf/v2 v2.2.0 // indirect - github.com/lucas-clemente/quic-go v0.31.1 // indirect - github.com/marten-seemann/qpack v0.3.0 // indirect - github.com/marten-seemann/qtls-go1-18 v0.1.3 // indirect - github.com/marten-seemann/qtls-go1-19 v0.1.1 // indirect github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect - github.com/marten-seemann/webtransport-go v0.4.3 // indirect github.com/mattn/go-isatty v0.0.17 // indirect - github.com/mattn/go-pointer v0.0.1 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/miekg/dns v1.1.50 // indirect github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect @@ -157,7 +150,7 @@ require ( github.com/multiformats/go-multibase v0.1.1 // indirect github.com/multiformats/go-multicodec v0.7.0 // indirect github.com/multiformats/go-multihash v0.2.1 // indirect - github.com/multiformats/go-multistream v0.3.3 // indirect + github.com/multiformats/go-multistream v0.4.1 // indirect github.com/multiformats/go-varint v0.0.7 // indirect github.com/onsi/ginkgo/v2 v2.5.1 // indirect github.com/opencontainers/runtime-spec v1.0.2 // indirect @@ -170,9 +163,14 @@ require ( github.com/prometheus/client_model v0.3.0 // indirect github.com/prometheus/common v0.37.0 // indirect github.com/prometheus/procfs v0.8.0 // indirect + github.com/quic-go/qpack v0.4.0 // indirect + github.com/quic-go/qtls-go1-18 v0.2.0 // indirect + github.com/quic-go/qtls-go1-19 v0.2.0 // indirect + github.com/quic-go/qtls-go1-20 v0.1.0 // indirect + github.com/quic-go/quic-go v0.32.0 // indirect + github.com/quic-go/webtransport-go v0.5.1 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/samber/lo v1.36.0 // indirect - github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc // indirect @@ -198,10 +196,10 @@ require ( go.uber.org/multierr v1.9.0 // indirect go.uber.org/zap v1.24.0 // indirect go4.org v0.0.0-20200411211856-f5505b9728dd // indirect - golang.org/x/crypto v0.3.0 // indirect + golang.org/x/crypto v0.4.0 // indirect golang.org/x/exp v0.0.0-20221205204356-47842c84f3db // indirect golang.org/x/mod v0.7.0 // indirect - golang.org/x/net v0.3.0 // indirect + golang.org/x/net v0.4.0 // indirect golang.org/x/sync v0.1.0 // indirect golang.org/x/sys v0.4.0 // indirect golang.org/x/text v0.5.0 // indirect @@ -212,4 +210,5 @@ require ( google.golang.org/protobuf v1.28.1 // indirect gopkg.in/square/go-jose.v2 v2.5.1 // indirect lukechampine.com/blake3 v1.1.7 // indirect + nhooyr.io/websocket v1.8.7 // indirect ) diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index e58ded225..9570851fb 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -227,6 +227,10 @@ github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMo github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= +github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14= +github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= @@ -247,10 +251,23 @@ github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= +github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= +github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= +github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= +github.com/go-playground/validator/v10 v10.2.0 h1:KgJ0snyC2R9VXYN2rneOtQcw5aHQB1Vv0sFl1UcHBOY= +github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= 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/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0= +github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= +github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8= +github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= +github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo= +github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= @@ -362,7 +379,6 @@ github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoA github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= -github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= @@ -398,6 +414,8 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/golang-lru/v2 v2.0.1 h1:5pv5N1lT1fjLg2VQ5KWc7kmucp2x/kvFOnxuVTqZ6x4= +github.com/hashicorp/golang-lru/v2 v2.0.1/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= @@ -548,8 +566,8 @@ github.com/ipfs/go-ipld-legacy v0.1.1 h1:BvD8PEuqwBHLTKqlGFTHSwrwFOMkVESEvwIYwR2 github.com/ipfs/go-ipld-legacy v0.1.1/go.mod h1:8AyKFCjgRPsQFf15ZQgDB8Din4DML/fOmKZkkFkrIEg= github.com/ipfs/go-ipns v0.3.0 h1:ai791nTgVo+zTuq2bLvEGmWP1M0A6kGTXUsgv/Yq67A= github.com/ipfs/go-ipns v0.3.0/go.mod h1:3cLT2rbvgPZGkHJoPO1YMJeh6LtkxopCkKFcio/wE24= -github.com/ipfs/go-libipfs v0.4.1-0.20230208022905-378aaf777cf9 h1:m3h1qk9cuH2aqiILynVqF69UmmdOiNTSq6CnHK9GVuQ= -github.com/ipfs/go-libipfs v0.4.1-0.20230208022905-378aaf777cf9/go.mod h1:XKRXmSlJ32qlpxGN+mdGJJXUl/Z055etN1xpMEaANQ8= +github.com/ipfs/go-libipfs v0.5.0 h1:gtvzeoTdUHPUN4B5izzyBS3Cxtpvi+l7hd2mmjN+teM= +github.com/ipfs/go-libipfs v0.5.0/go.mod h1:iZ9QyhzNr3AkxRXrbQYb//rv7iLyvZJX0GNuc3lJDiQ= github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= github.com/ipfs/go-log v1.0.2/go.mod h1:1MNjMxe0u6xvJZgeqbJ8vdo2TKaGwZ1a0Bpza+sr2Sk= github.com/ipfs/go-log v1.0.3/go.mod h1:OsLySYkwIbiSUR/yBTdv1qPtcE4FW3WPWk/ewz9Ru+A= @@ -638,8 +656,10 @@ github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlT github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= @@ -654,6 +674,7 @@ github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQL 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.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/compress v1.15.12 h1:YClS/PImqYbn+UILDnqxQCZ3RehC9N318SU3kElDUEM= github.com/klauspost/compress v1.15.12/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= @@ -678,6 +699,8 @@ github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= +github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= 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-buffer-pool v0.0.1/go.mod h1:xtyIz9PMobb13WaxR6Zo1Pd1zXJKYg0a8KiIvDp3TzQ= @@ -704,8 +727,8 @@ github.com/libp2p/go-libp2p v0.7.0/go.mod h1:hZJf8txWeCduQRDC/WSqBGMxaTHCOYHt2xS github.com/libp2p/go-libp2p v0.7.4/go.mod h1:oXsBlTLF1q7pxr+9w6lqzS1ILpyHsaBPniVO7zIHGMw= github.com/libp2p/go-libp2p v0.8.1/go.mod h1:QRNH9pwdbEBpx5DTJYg+qxcVaDMAz3Ee/qDKwXujH5o= github.com/libp2p/go-libp2p v0.14.3/go.mod h1:d12V4PdKbpL0T1/gsUNN8DfgMuRPDX8bS2QxCZlwRH0= -github.com/libp2p/go-libp2p v0.24.2 h1:iMViPIcLY0D6zr/f+1Yq9EavCZu2i7eDstsr1nEwSAk= -github.com/libp2p/go-libp2p v0.24.2/go.mod h1:WuxtL2V8yGjam03D93ZBC19tvOUiPpewYv1xdFGWu1k= +github.com/libp2p/go-libp2p v0.25.2-0.20230214091718-aef956be688d h1:OeFN5DlT447jgmKB9LnzUkpykEw8FMuy7wWTL0rAK30= +github.com/libp2p/go-libp2p v0.25.2-0.20230214091718-aef956be688d/go.mod h1:xnK9/1d9+jeQCVvi/f1g12KqtVi/jP/SijtKV1hML3g= github.com/libp2p/go-libp2p-asn-util v0.2.0 h1:rg3+Os8jbnO5DxkC7K/Utdi+DkY3q/d1/1q+8WeNAsw= github.com/libp2p/go-libp2p-asn-util v0.2.0/go.mod h1:WoaWxbHKBymSN41hWSq/lGKJEca7TNm58+gGJi2WsLI= github.com/libp2p/go-libp2p-autonat v0.1.0/go.mod h1:1tLf2yXxiE/oKGtDwPYWTSYG3PtvYlJmg7NeVtPRqH8= @@ -748,8 +771,8 @@ github.com/libp2p/go-libp2p-discovery v0.1.0/go.mod h1:4F/x+aldVHjHDHuX85x1zWoFT github.com/libp2p/go-libp2p-discovery v0.2.0/go.mod h1:s4VGaxYMbw4+4+tsoQTqh7wfxg97AEdo4GYBt6BadWg= github.com/libp2p/go-libp2p-discovery v0.3.0/go.mod h1:o03drFnz9BVAZdzC/QUQ+NeQOu38Fu7LJGEOK2gQltw= github.com/libp2p/go-libp2p-discovery v0.5.0/go.mod h1:+srtPIU9gDaBNu//UHvcdliKBIcr4SfDcm0/PfPJLug= -github.com/libp2p/go-libp2p-kad-dht v0.20.0 h1:1bcMa74JFwExCHZMFEmjtHzxX5DovhJ07EtR6UOTEpc= -github.com/libp2p/go-libp2p-kad-dht v0.20.0/go.mod h1:qPIXdiZsLczhV4/+4EO1jE8ae0YCW4ZOogc4WVIyTEU= +github.com/libp2p/go-libp2p-kad-dht v0.21.0 h1:J0Yd22VA+sk0CJRGMgtfHvLVIkZDyJ3AJGiljywIw5U= +github.com/libp2p/go-libp2p-kad-dht v0.21.0/go.mod h1:Bhm9diAFmc6qcWAr084bHNL159srVZRKADdp96Qqd1I= github.com/libp2p/go-libp2p-kbucket v0.3.1/go.mod h1:oyjT5O7tS9CQurok++ERgc46YLwEpuGoFq9ubvoUOio= github.com/libp2p/go-libp2p-kbucket v0.5.0 h1:g/7tVm8ACHDxH29BGrpsQlnNeu+6OF1A9bno/4/U1oA= github.com/libp2p/go-libp2p-kbucket v0.5.0/go.mod h1:zGzGCpQd78b5BNTDGHNDLaTt9aDK/A02xeZp9QeFC4U= @@ -775,8 +798,8 @@ 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-pnet v0.2.0/go.mod h1:Qqvq6JH/oMZGwqs3N1Fqhv8NVhrdYcO0BW4wssv21LA= -github.com/libp2p/go-libp2p-pubsub v0.8.3 h1:T4+pcfcFm1K2v5oFyk68peSjVroaoM8zFygf6Y5WOww= -github.com/libp2p/go-libp2p-pubsub v0.8.3/go.mod h1:eje970FXxjhtFbVEoiae+VUw24ZoSlk67BsiZPLRzlw= +github.com/libp2p/go-libp2p-pubsub v0.9.0 h1:mcLb4WzwhUG4OKb0rp1/bYMd/DYhvMyzJheQH3LMd1s= +github.com/libp2p/go-libp2p-pubsub v0.9.0/go.mod h1:OEsj0Cc/BpkqikXRTrVspWU/Hx7bMZwHP+6vNMd+c7I= github.com/libp2p/go-libp2p-pubsub-router v0.6.0 h1:D30iKdlqDt5ZmLEYhHELCMRj8b4sFAqrUcshIUvVP/s= github.com/libp2p/go-libp2p-pubsub-router v0.6.0/go.mod h1:FY/q0/RBTKsLA7l4vqC2cbRbOvyDotg8PJQ7j8FDudE= github.com/libp2p/go-libp2p-quic-transport v0.10.0/go.mod h1:RfJbZ8IqXIhxBRm5hqUEJqjiiY8xmEuq3HUDS993MkA= @@ -835,8 +858,8 @@ github.com/libp2p/go-msgio v0.0.2/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+ 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= github.com/libp2p/go-msgio v0.0.6/go.mod h1:4ecVB6d9f4BDSL5fqvPiC4A3KivjWn+Venn/1ALLMWA= -github.com/libp2p/go-msgio v0.2.0 h1:W6shmB+FeynDrUVl2dgFQvzfBZcXiyqY4VmpQLu9FqU= -github.com/libp2p/go-msgio v0.2.0/go.mod h1:dBVM1gW3Jk9XqHkU4eKdGvVHdLa51hoGfll6jMJMSlY= +github.com/libp2p/go-msgio v0.3.0 h1:mf3Z8B1xcFN314sWX+2vOTShIE0Mmn2TXn3YCUQGNj0= +github.com/libp2p/go-msgio v0.3.0/go.mod h1:nyRM819GmVaF9LX3l03RMh10QdOroF++NBbxAb0mmDM= github.com/libp2p/go-nat v0.0.3/go.mod h1:88nUEt0k0JD45Bk93NIwDqjlhiOwOoV36GchpcVc1yI= github.com/libp2p/go-nat v0.0.4/go.mod h1:Nmw50VAvKuk38jUBcmNh6p9lUJLoODbJRvYAa/+KSDo= github.com/libp2p/go-nat v0.0.5/go.mod h1:B7NxsVNPZmRLvMOwiEO1scOSyjA56zxYAGv1yQgRkEU= @@ -853,8 +876,6 @@ github.com/libp2p/go-openssl v0.0.3/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO github.com/libp2p/go-openssl v0.0.4/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= github.com/libp2p/go-openssl v0.0.5/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= github.com/libp2p/go-openssl v0.0.7/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= -github.com/libp2p/go-openssl v0.1.0 h1:LBkKEcUv6vtZIQLVTegAil8jbNpJErQ9AnT+bWV+Ooo= -github.com/libp2p/go-openssl v0.1.0/go.mod h1:OiOxwPpL3n4xlenjx2h7AwSGaFSC/KZvf6gNdOBQMtc= github.com/libp2p/go-reuseport v0.0.1/go.mod h1:jn6RmB1ufnQwl0Q1f+YxAj8isJgDCQzaaxIFYDhcYEA= github.com/libp2p/go-reuseport v0.0.2/go.mod h1:SPD+5RwGC7rcnzngoYC86GjPzjSywuQyMVAheVBD9nQ= github.com/libp2p/go-reuseport v0.2.0 h1:18PRvIMlpY6ZK85nIAicSBuXXvrYoSw3dsBAR7zc560= @@ -893,26 +914,16 @@ github.com/libp2p/zeroconf/v2 v2.2.0/go.mod h1:fuJqLnUwZTshS3U/bMRJ3+ow/v9oid1n0 github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= github.com/lucas-clemente/quic-go v0.19.3/go.mod h1:ADXpNbTQjq1hIzCpB+y/k5iz4n4z4IwqoLb94Kh5Hu8= -github.com/lucas-clemente/quic-go v0.31.1 h1:O8Od7hfioqq0PMYHDyBkxU2aA7iZ2W9pjbrWuja2YR4= -github.com/lucas-clemente/quic-go v0.31.1/go.mod h1:0wFbizLgYzqHqtlyxyCaJKlE7bYgE6JQ+54TLd/Dq2g= 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= github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/marten-seemann/qpack v0.2.1/go.mod h1:F7Gl5L1jIgN1D11ucXefiuJS9UMVP2opoCp2jDKb7wc= -github.com/marten-seemann/qpack v0.3.0 h1:UiWstOgT8+znlkDPOg2+3rIuYXJ2CnGDkGUXN6ki6hE= -github.com/marten-seemann/qpack v0.3.0/go.mod h1:cGfKPBiP4a9EQdxCwEwI/GEeWAsjSekBvx/X8mh58+g= github.com/marten-seemann/qtls v0.10.0/go.mod h1:UvMd1oaYDACI99/oZUYLzMCkBXQVT0aGm99sJhbT8hs= github.com/marten-seemann/qtls-go1-15 v0.1.1/go.mod h1:GyFwywLKkRt+6mfU99csTEY1joMZz5vmB1WNZH3P81I= -github.com/marten-seemann/qtls-go1-18 v0.1.3 h1:R4H2Ks8P6pAtUagjFty2p7BVHn3XiwDAl7TTQf5h7TI= -github.com/marten-seemann/qtls-go1-18 v0.1.3/go.mod h1:mJttiymBAByA49mhlNZZGrH5u1uXYZJ+RW28Py7f4m4= -github.com/marten-seemann/qtls-go1-19 v0.1.1 h1:mnbxeq3oEyQxQXwI4ReCgW9DPoPR94sNlqWoDZnjRIE= -github.com/marten-seemann/qtls-go1-19 v0.1.1/go.mod h1:5HTDWtVudo/WFsHKRNuOhWlbdjrfs5JHrYb0wIJqGpI= 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/marten-seemann/webtransport-go v0.4.3 h1:vkt5o/Ci+luknRteWdYGYH1KcB7ziup+J+1PzZJIvmg= -github.com/marten-seemann/webtransport-go v0.4.3/go.mod h1:4xcfySgZMLP4aG5GBGj1egP7NlpfwgYJ1WJMvPPiVMU= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= @@ -920,12 +931,11 @@ github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNx github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= 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.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-pointer v0.0.1 h1:n+XhsuGeVO6MEAp7xyEukFINEa+Quek5psIR/ylA6o0= -github.com/mattn/go-pointer v0.0.1/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= @@ -963,9 +973,11 @@ github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0Qu github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= github.com/mr-tron/base58 v1.1.1/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= @@ -1030,8 +1042,8 @@ github.com/multiformats/go-multistream v0.1.0/go.mod h1:fJTiDfXJVmItycydCnNx4+wS github.com/multiformats/go-multistream v0.1.1/go.mod h1:KmHZ40hzVxiaiwlj3MEbYgK9JFk2/9UktWZAF54Du38= github.com/multiformats/go-multistream v0.2.1/go.mod h1:5GZPQZbkWOLOn3J2y4Y99vVW7vOfsAflxARk3x14o6k= github.com/multiformats/go-multistream v0.2.2/go.mod h1:UIcnm7Zuo8HKG+HkWgfQsGL+/MIEhyTqbODbIUwSXKs= -github.com/multiformats/go-multistream v0.3.3 h1:d5PZpjwRgVlbwfdTDjife7XszfZd8KYWfROYFlGcR8o= -github.com/multiformats/go-multistream v0.3.3/go.mod h1:ODRoqamLUsETKS9BNcII4gcRsJBU5VAwRIv7O39cEXg= +github.com/multiformats/go-multistream v0.4.1 h1:rFy0Iiyn3YT0asivDUIR05leAdwZq3de4741sbiSdfo= +github.com/multiformats/go-multistream v0.4.1/go.mod h1:Mz5eykRVAjJWckE2U78c6xqdtyNUEhKSM0Lwar2p77Q= github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/multiformats/go-varint v0.0.2/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= @@ -1153,6 +1165,18 @@ github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1 github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo= github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= +github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= +github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= +github.com/quic-go/qtls-go1-18 v0.2.0 h1:5ViXqBZ90wpUcZS0ge79rf029yx0dYB0McyPJwqqj7U= +github.com/quic-go/qtls-go1-18 v0.2.0/go.mod h1:moGulGHK7o6O8lSPSZNoOwcLvJKJ85vVNc7oJFD65bc= +github.com/quic-go/qtls-go1-19 v0.2.0 h1:Cvn2WdhyViFUHoOqK52i51k4nDX8EwIh5VJiVM4nttk= +github.com/quic-go/qtls-go1-19 v0.2.0/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI= +github.com/quic-go/qtls-go1-20 v0.1.0 h1:d1PK3ErFy9t7zxKsG3NXBJXZjp/kMLoIb3y/kV54oAI= +github.com/quic-go/qtls-go1-20 v0.1.0/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= +github.com/quic-go/quic-go v0.32.0 h1:lY02md31s1JgPiiyfqJijpu/UX/Iun304FI3yUqX7tA= +github.com/quic-go/quic-go v0.32.0/go.mod h1:/fCsKANhQIeD5l76c2JFU+07gVE3KaA0FP+0zMWwfwo= +github.com/quic-go/webtransport-go v0.5.1 h1:1eVb7WDWCRoaeTtFHpFBJ6WDN1bSrPrRoW6tZgSw0Ow= +github.com/quic-go/webtransport-go v0.5.1/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= github.com/rabbitmq/amqp091-go v1.1.0/go.mod h1:ogQDLSOACsLPsIq0NpbtiifNZi2YOz0VTJ0kHRghqbM= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU= @@ -1213,7 +1237,6 @@ github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJ github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE= github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA= github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a/go.mod h1:7AyxJNCJ7SBZ1MfVQCWD6Uqo2oubI2Eq2y2eqf+A5r0= -github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU= github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= @@ -1253,7 +1276,11 @@ github.com/thoas/go-funk v0.9.1 h1:O549iLZqPpTUQ10ykd26sZhzD+rmR5pWhuElrhbC20M= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c h1:u6SKchux2yDvFQnDHS3lPnIRmfVJ5Sxy3ao2SIdysLQ= github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM= +github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= +github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= +github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= 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= @@ -1397,8 +1424,8 @@ golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWP golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210506145944-38f3c27a63bf/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= golang.org/x/crypto v0.0.0-20210920023735-84f357641f63/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.3.0 h1:a06MkbcxBrEFc0w0QIZWXrH/9cCX6KJyWbBOIwAn+7A= -golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= +golang.org/x/crypto v0.4.0 h1:UVQgzMY87xqpKNgb+kDsll2Igd33HszWHFLmpaRMq/8= +golang.org/x/crypto v0.4.0/go.mod h1:3quD/ATkf6oY+rnes5c3ExXTbLc8mueNue5/DoinL80= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1493,8 +1520,8 @@ golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20210917221730-978cfadd31cf/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.3.0 h1:VWL6FNY2bEEmsGVKabSlHu5Irp34xmMRoqb/9lF9lxk= -golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= +golang.org/x/net v0.4.0 h1:Q5QPcMlvfxFTAPV0+07Xz/MpK9NTXu2VDUuy0FeMfaU= +golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1841,6 +1868,8 @@ honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9 lukechampine.com/blake3 v1.1.6/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= lukechampine.com/blake3 v1.1.7 h1:GgRMhmdsuK8+ii6UZFDL8Nb+VyMwadAgcJyfYHxG6n0= lukechampine.com/blake3 v1.1.7/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= +nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g= +nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= pgregory.net/rapid v0.4.7 h1:MTNRktPuv5FNqOO151TM9mDTa+XHcX6ypYeISDVD14g= pgregory.net/rapid v0.4.7/go.mod h1:UYpPVyjFHzYBGHIxLFoupi8vwk6rXNzRY9OMvVxFIOU= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= diff --git a/go.mod b/go.mod index d35ddb910..287f4f13a 100644 --- a/go.mod +++ b/go.mod @@ -45,7 +45,7 @@ require ( github.com/ipfs/go-ipld-git v0.1.1 github.com/ipfs/go-ipld-legacy v0.1.1 github.com/ipfs/go-ipns v0.3.0 - github.com/ipfs/go-libipfs v0.4.1-0.20230201214832-687c0b0f1531 + github.com/ipfs/go-libipfs v0.5.0 github.com/ipfs/go-log v1.0.5 github.com/ipfs/go-log/v2 v2.5.1 github.com/ipfs/go-merkledag v0.9.0 @@ -106,6 +106,7 @@ require ( go.uber.org/fx v1.18.2 go.uber.org/zap v1.24.0 golang.org/x/crypto v0.4.0 + golang.org/x/exp v0.0.0-20221205204356-47842c84f3db golang.org/x/mod v0.7.0 golang.org/x/sync v0.1.0 golang.org/x/sys v0.4.0 @@ -228,7 +229,6 @@ require ( go.uber.org/atomic v1.10.0 // indirect go.uber.org/multierr v1.9.0 // indirect go4.org v0.0.0-20200411211856-f5505b9728dd // indirect - golang.org/x/exp v0.0.0-20221205204356-47842c84f3db // indirect golang.org/x/net v0.4.0 // indirect golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b // indirect golang.org/x/term v0.4.0 // indirect diff --git a/go.sum b/go.sum index d451a06ab..cdd338ec4 100644 --- a/go.sum +++ b/go.sum @@ -588,8 +588,8 @@ github.com/ipfs/go-ipld-legacy v0.1.1 h1:BvD8PEuqwBHLTKqlGFTHSwrwFOMkVESEvwIYwR2 github.com/ipfs/go-ipld-legacy v0.1.1/go.mod h1:8AyKFCjgRPsQFf15ZQgDB8Din4DML/fOmKZkkFkrIEg= github.com/ipfs/go-ipns v0.3.0 h1:ai791nTgVo+zTuq2bLvEGmWP1M0A6kGTXUsgv/Yq67A= github.com/ipfs/go-ipns v0.3.0/go.mod h1:3cLT2rbvgPZGkHJoPO1YMJeh6LtkxopCkKFcio/wE24= -github.com/ipfs/go-libipfs v0.4.1-0.20230201214832-687c0b0f1531 h1:uDnDGKAuoOiNROG4yoWT39Xsjzvf3Z65fJRfG1caruo= -github.com/ipfs/go-libipfs v0.4.1-0.20230201214832-687c0b0f1531/go.mod h1:97CmQJmnJUSQwTSDZEXlKCNOCDD6HDKCGwKaJzHkc+U= +github.com/ipfs/go-libipfs v0.5.0 h1:gtvzeoTdUHPUN4B5izzyBS3Cxtpvi+l7hd2mmjN+teM= +github.com/ipfs/go-libipfs v0.5.0/go.mod h1:iZ9QyhzNr3AkxRXrbQYb//rv7iLyvZJX0GNuc3lJDiQ= github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= github.com/ipfs/go-log v1.0.2/go.mod h1:1MNjMxe0u6xvJZgeqbJ8vdo2TKaGwZ1a0Bpza+sr2Sk= github.com/ipfs/go-log v1.0.3/go.mod h1:OsLySYkwIbiSUR/yBTdv1qPtcE4FW3WPWk/ewz9Ru+A= diff --git a/test/sharness/t0116-prometheus-data/prometheus_metrics b/test/sharness/t0116-prometheus-data/prometheus_metrics index 32c0d8e43..fc6e96e8d 100644 --- a/test/sharness/t0116-prometheus-data/prometheus_metrics +++ b/test/sharness/t0116-prometheus-data/prometheus_metrics @@ -576,6 +576,25 @@ leveldb_datastore_sync_latency_seconds_bucket leveldb_datastore_sync_latency_seconds_count leveldb_datastore_sync_latency_seconds_sum leveldb_datastore_sync_total +libp2p_eventbus_events_emitted_total +libp2p_eventbus_events_emitted_total +libp2p_eventbus_subscriber_event_queued +libp2p_eventbus_subscriber_event_queued +libp2p_eventbus_subscriber_event_queued +libp2p_eventbus_subscriber_queue_full +libp2p_eventbus_subscriber_queue_full +libp2p_eventbus_subscriber_queue_full +libp2p_eventbus_subscriber_queue_length +libp2p_eventbus_subscriber_queue_length +libp2p_eventbus_subscriber_queue_length +libp2p_eventbus_subscribers_total +libp2p_eventbus_subscribers_total +libp2p_eventbus_subscribers_total +libp2p_eventbus_subscribers_total +libp2p_eventbus_subscribers_total +libp2p_eventbus_subscribers_total +libp2p_identify_identify_pushes_triggered_total +libp2p_identify_identify_pushes_triggered_total process_cpu_seconds_total process_max_fds process_open_fds @@ -583,177 +602,3 @@ process_resident_memory_bytes process_start_time_seconds process_virtual_memory_bytes process_virtual_memory_max_bytes -quic_connection_duration_bucket -quic_connection_duration_bucket -quic_connection_duration_bucket -quic_connection_duration_bucket -quic_connection_duration_bucket -quic_connection_duration_bucket -quic_connection_duration_bucket -quic_connection_duration_bucket -quic_connection_duration_bucket -quic_connection_duration_bucket -quic_connection_duration_bucket -quic_connection_duration_bucket -quic_connection_duration_bucket -quic_connection_duration_bucket -quic_connection_duration_bucket -quic_connection_duration_bucket -quic_connection_duration_bucket -quic_connection_duration_bucket -quic_connection_duration_bucket -quic_connection_duration_bucket -quic_connection_duration_bucket -quic_connection_duration_bucket -quic_connection_duration_bucket -quic_connection_duration_bucket -quic_connection_duration_bucket -quic_connection_duration_bucket -quic_connection_duration_bucket -quic_connection_duration_bucket -quic_connection_duration_bucket -quic_connection_duration_bucket -quic_connection_duration_bucket -quic_connection_duration_bucket -quic_connection_duration_bucket -quic_connection_duration_bucket -quic_connection_duration_bucket -quic_connection_duration_bucket -quic_connection_duration_bucket -quic_connection_duration_bucket -quic_connection_duration_bucket -quic_connection_duration_bucket -quic_connection_duration_bucket -quic_connection_duration_count -quic_connection_duration_sum -quic_smoothed_rtt_bucket -quic_smoothed_rtt_bucket -quic_smoothed_rtt_bucket -quic_smoothed_rtt_bucket -quic_smoothed_rtt_bucket -quic_smoothed_rtt_bucket -quic_smoothed_rtt_bucket -quic_smoothed_rtt_bucket -quic_smoothed_rtt_bucket -quic_smoothed_rtt_bucket -quic_smoothed_rtt_bucket -quic_smoothed_rtt_bucket -quic_smoothed_rtt_bucket -quic_smoothed_rtt_bucket -quic_smoothed_rtt_bucket -quic_smoothed_rtt_bucket -quic_smoothed_rtt_bucket -quic_smoothed_rtt_bucket -quic_smoothed_rtt_bucket -quic_smoothed_rtt_bucket -quic_smoothed_rtt_bucket -quic_smoothed_rtt_bucket -quic_smoothed_rtt_bucket -quic_smoothed_rtt_bucket -quic_smoothed_rtt_bucket -quic_smoothed_rtt_bucket -quic_smoothed_rtt_bucket -quic_smoothed_rtt_bucket -quic_smoothed_rtt_bucket -quic_smoothed_rtt_bucket -quic_smoothed_rtt_bucket -quic_smoothed_rtt_bucket -quic_smoothed_rtt_bucket -quic_smoothed_rtt_bucket -quic_smoothed_rtt_bucket -quic_smoothed_rtt_bucket -quic_smoothed_rtt_bucket -quic_smoothed_rtt_bucket -quic_smoothed_rtt_bucket -quic_smoothed_rtt_bucket -quic_smoothed_rtt_bucket -quic_smoothed_rtt_count -quic_smoothed_rtt_sum -tcp_connection_duration_bucket -tcp_connection_duration_bucket -tcp_connection_duration_bucket -tcp_connection_duration_bucket -tcp_connection_duration_bucket -tcp_connection_duration_bucket -tcp_connection_duration_bucket -tcp_connection_duration_bucket -tcp_connection_duration_bucket -tcp_connection_duration_bucket -tcp_connection_duration_bucket -tcp_connection_duration_bucket -tcp_connection_duration_bucket -tcp_connection_duration_bucket -tcp_connection_duration_bucket -tcp_connection_duration_bucket -tcp_connection_duration_bucket -tcp_connection_duration_bucket -tcp_connection_duration_bucket -tcp_connection_duration_bucket -tcp_connection_duration_bucket -tcp_connection_duration_bucket -tcp_connection_duration_bucket -tcp_connection_duration_bucket -tcp_connection_duration_bucket -tcp_connection_duration_bucket -tcp_connection_duration_bucket -tcp_connection_duration_bucket -tcp_connection_duration_bucket -tcp_connection_duration_bucket -tcp_connection_duration_bucket -tcp_connection_duration_bucket -tcp_connection_duration_bucket -tcp_connection_duration_bucket -tcp_connection_duration_bucket -tcp_connection_duration_bucket -tcp_connection_duration_bucket -tcp_connection_duration_bucket -tcp_connection_duration_bucket -tcp_connection_duration_bucket -tcp_connection_duration_bucket -tcp_connection_duration_count -tcp_connection_duration_sum -tcp_rcvd_segments_total -tcp_rtt_bucket -tcp_rtt_bucket -tcp_rtt_bucket -tcp_rtt_bucket -tcp_rtt_bucket -tcp_rtt_bucket -tcp_rtt_bucket -tcp_rtt_bucket -tcp_rtt_bucket -tcp_rtt_bucket -tcp_rtt_bucket -tcp_rtt_bucket -tcp_rtt_bucket -tcp_rtt_bucket -tcp_rtt_bucket -tcp_rtt_bucket -tcp_rtt_bucket -tcp_rtt_bucket -tcp_rtt_bucket -tcp_rtt_bucket -tcp_rtt_bucket -tcp_rtt_bucket -tcp_rtt_bucket -tcp_rtt_bucket -tcp_rtt_bucket -tcp_rtt_bucket -tcp_rtt_bucket -tcp_rtt_bucket -tcp_rtt_bucket -tcp_rtt_bucket -tcp_rtt_bucket -tcp_rtt_bucket -tcp_rtt_bucket -tcp_rtt_bucket -tcp_rtt_bucket -tcp_rtt_bucket -tcp_rtt_bucket -tcp_rtt_bucket -tcp_rtt_bucket -tcp_rtt_bucket -tcp_rtt_bucket -tcp_rtt_count -tcp_rtt_sum -tcp_sent_segments_total diff --git a/test/sharness/t0139-swarm-rcmgr.sh b/test/sharness/t0139-swarm-rcmgr.sh index 1b870abb7..d450c0908 100755 --- a/test/sharness/t0139-swarm-rcmgr.sh +++ b/test/sharness/t0139-swarm-rcmgr.sh @@ -147,36 +147,36 @@ test_expect_success 'Set system memory limit while the daemon is running' ' ' test_expect_success 'The new system limits were written to the config' ' - jq -e ".Swarm.ResourceMgr.Limits.System.Memory == 99998" < "$IPFS_PATH/config" + jq -e ".Swarm.ResourceMgr.Limits.System.Memory == \"99998\"" < "$IPFS_PATH/config" ' test_expect_success 'The new system limits are in the swarm limit output' ' - ipfs swarm limit system --enc=json | jq -e ".Memory == 99998" + ipfs swarm limit system --enc=json | jq -e ".Memory == \"99998\"" ' # now test all the other scopes test_expect_success 'Set limit on transient scope' ' ipfs swarm limit transient | jq ".Memory = 88888" > transient.json && ipfs swarm limit transient transient.json && - jq -e ".Swarm.ResourceMgr.Limits.Transient.Memory == 88888" < "$IPFS_PATH/config" && + jq -e ".Swarm.ResourceMgr.Limits.Transient.Memory == \"88888\"" < "$IPFS_PATH/config" && ipfs swarm limit transient --enc=json | tee limits && - jq -e ".Memory == 88888" < limits + jq -e ".Memory == \"88888\"" < limits ' test_expect_success 'Set limit on service scope' ' ipfs swarm limit svc:foo | jq ".Memory = 77777" > service-foo.json && ipfs swarm limit svc:foo service-foo.json --enc=json && - jq -e ".Swarm.ResourceMgr.Limits.Service.foo.Memory == 77777" < "$IPFS_PATH/config" && + jq -e ".Swarm.ResourceMgr.Limits.Service.foo.Memory == \"77777\"" < "$IPFS_PATH/config" && ipfs swarm limit svc:foo --enc=json | tee limits && - jq -e ".Memory == 77777" < limits + jq -e ".Memory == \"77777\"" < limits ' test_expect_success 'Set limit on protocol scope' ' ipfs swarm limit proto:foo | jq ".Memory = 66666" > proto-foo.json && ipfs swarm limit proto:foo proto-foo.json --enc=json && - jq -e ".Swarm.ResourceMgr.Limits.Protocol.foo.Memory == 66666" < "$IPFS_PATH/config" && + jq -e ".Swarm.ResourceMgr.Limits.Protocol.foo.Memory == \"66666\"" < "$IPFS_PATH/config" && ipfs swarm limit proto:foo --enc=json | tee limits && - jq -e ".Memory == 66666" < limits + jq -e ".Memory == \"66666\"" < limits ' # any valid peer id @@ -185,9 +185,9 @@ PEER_ID=QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN test_expect_success 'Set limit on peer scope' ' ipfs swarm limit peer:$PEER_ID | jq ".Memory = 66666" > peer-$PEER_ID.json && ipfs swarm limit peer:$PEER_ID peer-$PEER_ID.json --enc=json && - jq -e ".Swarm.ResourceMgr.Limits.Peer.${PEER_ID}.Memory == 66666" < "$IPFS_PATH/config" && + jq -e ".Swarm.ResourceMgr.Limits.Peer.${PEER_ID}.Memory == \"66666\"" < "$IPFS_PATH/config" && ipfs swarm limit peer:$PEER_ID --enc=json | tee limits && - jq -e ".Memory == 66666" < limits + jq -e ".Memory == \"66666\"" < limits ' test_expect_success 'Get limit for peer scope with an invalid peer ID' ' From ed4d6b7d4187512ede4aeb19188a383d9aa55d45 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Tue, 7 Feb 2023 12:40:58 +0100 Subject: [PATCH 0471/1212] test: remove gateway tests migrated to go-libipfs --- core/corehttp/gateway_test.go | 478 ---------------------------------- 1 file changed, 478 deletions(-) diff --git a/core/corehttp/gateway_test.go b/core/corehttp/gateway_test.go index 49fa519fb..d4e357740 100644 --- a/core/corehttp/gateway_test.go +++ b/core/corehttp/gateway_test.go @@ -6,7 +6,6 @@ import ( "io" "net/http" "net/http/httptest" - "regexp" "strings" "testing" @@ -18,19 +17,14 @@ import ( datastore "github.com/ipfs/go-datastore" syncds "github.com/ipfs/go-datastore/sync" - "github.com/ipfs/go-libipfs/files" path "github.com/ipfs/go-path" iface "github.com/ipfs/interface-go-ipfs-core" nsopts "github.com/ipfs/interface-go-ipfs-core/options/namesys" - ipath "github.com/ipfs/interface-go-ipfs-core/path" config "github.com/ipfs/kubo/config" ci "github.com/libp2p/go-libp2p/core/crypto" id "github.com/libp2p/go-libp2p/p2p/protocol/identify" ) -// `ipfs object new unixfs-dir` -var emptyDir = "/ipfs/QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn" - type mockNamesys map[string]path.Path func (m mockNamesys) Resolve(ctx context.Context, name string, opts ...nsopts.ResolveOpt) (value path.Path, err error) { @@ -145,478 +139,6 @@ func newTestServerAndNode(t *testing.T, ns mockNamesys) (*httptest.Server, iface return ts, api, n.Context() } -func matchPathOrBreadcrumbs(s string, expected string) bool { - matched, _ := regexp.MatchString("Index of\n[\t ]*"+regexp.QuoteMeta(expected), s) - return matched -} - -func TestUriQueryRedirect(t *testing.T) { - ts, _, _ := newTestServerAndNode(t, mockNamesys{}) - - cid := "QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR" - for i, test := range []struct { - path string - status int - location string - }{ - // - Browsers will send original URI in URL-escaped form - // - We expect query parameters to be persisted - // - We drop fragments, as those should not be sent by a browser - {"/ipfs/?uri=ipfs%3A%2F%2FQmXoypizjW3WknFiJnKLwHCnL72vedxjQkDDP1mXWo6uco%2Fwiki%2FFoo_%C4%85%C4%99.html%3Ffilename%3Dtest-%C4%99.html%23header-%C4%85", http.StatusMovedPermanently, "/ipfs/QmXoypizjW3WknFiJnKLwHCnL72vedxjQkDDP1mXWo6uco/wiki/Foo_%c4%85%c4%99.html?filename=test-%c4%99.html"}, - {"/ipfs/?uri=ipns%3A%2F%2Fexample.com%2Fwiki%2FFoo_%C4%85%C4%99.html%3Ffilename%3Dtest-%C4%99.html", http.StatusMovedPermanently, "/ipns/example.com/wiki/Foo_%c4%85%c4%99.html?filename=test-%c4%99.html"}, - {"/ipfs/?uri=ipfs://" + cid, http.StatusMovedPermanently, "/ipfs/" + cid}, - {"/ipfs?uri=ipfs://" + cid, http.StatusMovedPermanently, "/ipfs/?uri=ipfs://" + cid}, - {"/ipfs/?uri=ipns://" + cid, http.StatusMovedPermanently, "/ipns/" + cid}, - {"/ipns/?uri=ipfs%3A%2F%2FQmXoypizjW3WknFiJnKLwHCnL72vedxjQkDDP1mXWo6uco%2Fwiki%2FFoo_%C4%85%C4%99.html%3Ffilename%3Dtest-%C4%99.html%23header-%C4%85", http.StatusMovedPermanently, "/ipfs/QmXoypizjW3WknFiJnKLwHCnL72vedxjQkDDP1mXWo6uco/wiki/Foo_%c4%85%c4%99.html?filename=test-%c4%99.html"}, - {"/ipns/?uri=ipns%3A%2F%2Fexample.com%2Fwiki%2FFoo_%C4%85%C4%99.html%3Ffilename%3Dtest-%C4%99.html", http.StatusMovedPermanently, "/ipns/example.com/wiki/Foo_%c4%85%c4%99.html?filename=test-%c4%99.html"}, - {"/ipns?uri=ipns://" + cid, http.StatusMovedPermanently, "/ipns/?uri=ipns://" + cid}, - {"/ipns/?uri=ipns://" + cid, http.StatusMovedPermanently, "/ipns/" + cid}, - {"/ipns/?uri=ipfs://" + cid, http.StatusMovedPermanently, "/ipfs/" + cid}, - {"/ipfs/?uri=unsupported://" + cid, http.StatusBadRequest, ""}, - {"/ipfs/?uri=invaliduri", http.StatusBadRequest, ""}, - {"/ipfs/?uri=" + cid, http.StatusBadRequest, ""}, - } { - - r, err := http.NewRequest(http.MethodGet, ts.URL+test.path, nil) - if err != nil { - t.Fatal(err) - } - resp, err := doWithoutRedirect(r) - if err != nil { - t.Fatal(err) - } - defer resp.Body.Close() - - if resp.StatusCode != test.status { - t.Errorf("(%d) got %d, expected %d from %s", i, resp.StatusCode, test.status, ts.URL+test.path) - } - - locHdr := resp.Header.Get("Location") - if locHdr != test.location { - t.Errorf("(%d) location header got %s, expected %s from %s", i, locHdr, test.location, ts.URL+test.path) - } - } -} - -func TestGatewayGet(t *testing.T) { - ns := mockNamesys{} - ts, api, ctx := newTestServerAndNode(t, ns) - - k, err := api.Unixfs().Add(ctx, files.NewBytesFile([]byte("fnord"))) - if err != nil { - t.Fatal(err) - } - ns["/ipns/example.com"] = path.FromString(k.String()) - ns["/ipns/working.example.com"] = path.FromString(k.String()) - ns["/ipns/double.example.com"] = path.FromString("/ipns/working.example.com") - ns["/ipns/triple.example.com"] = path.FromString("/ipns/double.example.com") - ns["/ipns/broken.example.com"] = path.FromString("/ipns/" + k.Cid().String()) - // We picked .man because: - // 1. It's a valid TLD. - // 2. Go treats it as the file extension for "man" files (even though - // nobody actually *uses* this extension, AFAIK). - // - // Unfortunately, this may not work on all platforms as file type - // detection is platform dependent. - ns["/ipns/example.man"] = path.FromString(k.String()) - - t.Log(ts.URL) - for i, test := range []struct { - host string - path string - status int - text string - }{ - {"127.0.0.1:8080", "/", http.StatusNotFound, "404 page not found\n"}, - {"127.0.0.1:8080", "/" + k.Cid().String(), http.StatusNotFound, "404 page not found\n"}, - {"127.0.0.1:8080", k.String(), http.StatusOK, "fnord"}, - {"127.0.0.1:8080", "/ipns/nxdomain.example.com", http.StatusBadRequest, "ipfs resolve -r /ipns/nxdomain.example.com: " + namesys.ErrResolveFailed.Error() + "\n"}, - {"127.0.0.1:8080", "/ipns/%0D%0A%0D%0Ahello", http.StatusBadRequest, "ipfs resolve -r /ipns/\\r\\n\\r\\nhello: " + namesys.ErrResolveFailed.Error() + "\n"}, - {"127.0.0.1:8080", "/ipns/example.com", http.StatusOK, "fnord"}, - {"example.com", "/", http.StatusOK, "fnord"}, - - {"working.example.com", "/", http.StatusOK, "fnord"}, - {"double.example.com", "/", http.StatusOK, "fnord"}, - {"triple.example.com", "/", http.StatusOK, "fnord"}, - {"working.example.com", k.String(), http.StatusNotFound, "ipfs resolve -r /ipns/working.example.com" + k.String() + ": no link named \"ipfs\" under " + k.Cid().String() + "\n"}, - {"broken.example.com", "/", http.StatusBadRequest, "ipfs resolve -r /ipns/broken.example.com/: " + namesys.ErrResolveFailed.Error() + "\n"}, - {"broken.example.com", k.String(), http.StatusBadRequest, "ipfs resolve -r /ipns/broken.example.com" + k.String() + ": " + namesys.ErrResolveFailed.Error() + "\n"}, - // This test case ensures we don't treat the TLD as a file extension. - {"example.man", "/", http.StatusOK, "fnord"}, - } { - var c http.Client - r, err := http.NewRequest(http.MethodGet, ts.URL+test.path, nil) - if err != nil { - t.Fatal(err) - } - r.Host = test.host - resp, err := c.Do(r) - - urlstr := "http://" + test.host + test.path - if err != nil { - t.Errorf("error requesting %s: %s", urlstr, err) - continue - } - defer resp.Body.Close() - contentType := resp.Header.Get("Content-Type") - if contentType != "text/plain; charset=utf-8" { - t.Errorf("expected content type to be text/plain, got %s", contentType) - } - body, err := io.ReadAll(resp.Body) - if resp.StatusCode != test.status { - t.Errorf("(%d) got %d, expected %d from %s", i, resp.StatusCode, test.status, urlstr) - t.Errorf("Body: %s", body) - continue - } - if err != nil { - t.Fatalf("error reading response from %s: %s", urlstr, err) - } - if string(body) != test.text { - t.Errorf("unexpected response body from %s: expected %q; got %q", urlstr, test.text, body) - continue - } - } -} - -func TestPretty404(t *testing.T) { - ns := mockNamesys{} - ts, api, ctx := newTestServerAndNode(t, ns) - - f1 := files.NewMapDirectory(map[string]files.Node{ - "ipfs-404.html": files.NewBytesFile([]byte("Custom 404")), - "deeper": files.NewMapDirectory(map[string]files.Node{ - "ipfs-404.html": files.NewBytesFile([]byte("Deep custom 404")), - }), - }) - - k, err := api.Unixfs().Add(ctx, f1) - if err != nil { - t.Fatal(err) - } - - host := "example.net" - ns["/ipns/"+host] = path.FromString(k.String()) - - for _, test := range []struct { - path string - accept string - status int - text string - }{ - {"/ipfs-404.html", "text/html", http.StatusOK, "Custom 404"}, - {"/nope", "text/html", http.StatusNotFound, "Custom 404"}, - {"/nope", "text/*", http.StatusNotFound, "Custom 404"}, - {"/nope", "*/*", http.StatusNotFound, "Custom 404"}, - {"/nope", "application/json", http.StatusNotFound, "ipfs resolve -r /ipns/example.net/nope: no link named \"nope\" under QmcmnF7XG5G34RdqYErYDwCKNFQ6jb8oKVR21WAJgubiaj\n"}, - {"/deeper/nope", "text/html", http.StatusNotFound, "Deep custom 404"}, - {"/deeper/", "text/html", http.StatusOK, ""}, - {"/deeper", "text/html", http.StatusOK, ""}, - {"/nope/nope", "text/html", http.StatusNotFound, "Custom 404"}, - } { - var c http.Client - req, err := http.NewRequest("GET", ts.URL+test.path, nil) - if err != nil { - t.Fatal(err) - } - req.Header.Add("Accept", test.accept) - req.Host = host - resp, err := c.Do(req) - - if err != nil { - t.Fatalf("error requesting %s: %s", test.path, err) - } - - defer resp.Body.Close() - if resp.StatusCode != test.status { - t.Fatalf("got %d, expected %d, from %s", resp.StatusCode, test.status, test.path) - } - body, err := io.ReadAll(resp.Body) - if err != nil { - t.Fatalf("error reading response from %s: %s", test.path, err) - } - - if test.text != "" && string(body) != test.text { - t.Fatalf("unexpected response body from %s: got %q, expected %q", test.path, body, test.text) - } - } -} - -func TestIPNSHostnameRedirect(t *testing.T) { - ns := mockNamesys{} - ts, api, ctx := newTestServerAndNode(t, ns) - t.Logf("test server url: %s", ts.URL) - - // create /ipns/example.net/foo/index.html - - f1 := files.NewMapDirectory(map[string]files.Node{ - "_": files.NewBytesFile([]byte("_")), - "foo": files.NewMapDirectory(map[string]files.Node{ - "index.html": files.NewBytesFile([]byte("_")), - }), - }) - - k, err := api.Unixfs().Add(ctx, f1) - if err != nil { - t.Fatal(err) - } - - t.Logf("k: %s\n", k) - ns["/ipns/example.net"] = path.FromString(k.String()) - - // make request to directory containing index.html - req, err := http.NewRequest(http.MethodGet, ts.URL+"/foo", nil) - if err != nil { - t.Fatal(err) - } - req.Host = "example.net" - - res, err := doWithoutRedirect(req) - if err != nil { - t.Fatal(err) - } - - // expect 301 redirect to same path, but with trailing slash - if res.StatusCode != 301 { - t.Errorf("status is %d, expected 301", res.StatusCode) - } - hdr := res.Header["Location"] - if len(hdr) < 1 { - t.Errorf("location header not present") - } else if hdr[0] != "/foo/" { - t.Errorf("location header is %v, expected /foo/", hdr[0]) - } - - // make request with prefix to directory containing index.html - req, err = http.NewRequest(http.MethodGet, ts.URL+"/foo", nil) - if err != nil { - t.Fatal(err) - } - req.Host = "example.net" - - res, err = doWithoutRedirect(req) - if err != nil { - t.Fatal(err) - } - - // expect 301 redirect to same path, but with prefix and trailing slash - if res.StatusCode != 301 { - t.Errorf("status is %d, expected 301", res.StatusCode) - } - hdr = res.Header["Location"] - if len(hdr) < 1 { - t.Errorf("location header not present") - } else if hdr[0] != "/foo/" { - t.Errorf("location header is %v, expected /foo/", hdr[0]) - } - - // make sure /version isn't exposed - req, err = http.NewRequest(http.MethodGet, ts.URL+"/version", nil) - if err != nil { - t.Fatal(err) - } - req.Host = "example.net" - - res, err = doWithoutRedirect(req) - if err != nil { - t.Fatal(err) - } - - if res.StatusCode != 404 { - t.Fatalf("expected a 404 error, got: %s", res.Status) - } -} - -// Test directory listing on DNSLink website -// (scenario when Host header is the same as URL hostname) -// This is basic regression test: additional end-to-end tests -// can be found in test/sharness/t0115-gateway-dir-listing.sh -func TestIPNSHostnameBacklinks(t *testing.T) { - ns := mockNamesys{} - ts, api, ctx := newTestServerAndNode(t, ns) - t.Logf("test server url: %s", ts.URL) - - f1 := files.NewMapDirectory(map[string]files.Node{ - "file.txt": files.NewBytesFile([]byte("1")), - "foo? #<'": files.NewMapDirectory(map[string]files.Node{ - "file.txt": files.NewBytesFile([]byte("2")), - "bar": files.NewMapDirectory(map[string]files.Node{ - "file.txt": files.NewBytesFile([]byte("3")), - }), - }), - }) - - // create /ipns/example.net/foo/ - k, err := api.Unixfs().Add(ctx, f1) - if err != nil { - t.Fatal(err) - } - - k2, err := api.ResolvePath(ctx, ipath.Join(k, "foo? #<'")) - if err != nil { - t.Fatal(err) - } - - k3, err := api.ResolvePath(ctx, ipath.Join(k, "foo? #<'/bar")) - if err != nil { - t.Fatal(err) - } - - t.Logf("k: %s\n", k) - ns["/ipns/example.net"] = path.FromString(k.String()) - - // make request to directory listing - req, err := http.NewRequest(http.MethodGet, ts.URL+"/foo%3F%20%23%3C%27/", nil) - if err != nil { - t.Fatal(err) - } - req.Host = "example.net" - - res, err := doWithoutRedirect(req) - if err != nil { - t.Fatal(err) - } - - // expect correct links - body, err := io.ReadAll(res.Body) - if err != nil { - t.Fatalf("error reading response: %s", err) - } - s := string(body) - t.Logf("body: %s\n", string(body)) - - if !matchPathOrBreadcrumbs(s, "/ipns/example.net/foo? #<'") { - t.Fatalf("expected a path in directory listing") - } - if !strings.Contains(s, "") { - t.Fatalf("expected backlink in directory listing") - } - if !strings.Contains(s, "") { - t.Fatalf("expected file in directory listing") - } - if !strings.Contains(s, "") { - t.Fatalf("expected no backlink in directory listing of the root CID") - } - if !strings.Contains(s, "") { - t.Fatalf("expected file in directory listing") - } - if !strings.Contains(s, "example.net/foo? #<'/bar") { - t.Fatalf("expected a path in directory listing") - } - if !strings.Contains(s, "") { - t.Fatalf("expected backlink in directory listing") - } - if !strings.Contains(s, "") { - t.Fatalf("expected file in directory listing") - } - if !strings.Contains(s, k3.Cid().String()) { - t.Fatalf("expected hash in directory listing") - } -} - -func TestCacheControlImmutable(t *testing.T) { - ts, _, _ := newTestServerAndNode(t, nil) - t.Logf("test server url: %s", ts.URL) - - req, err := http.NewRequest(http.MethodGet, ts.URL+emptyDir+"/", nil) - if err != nil { - t.Fatal(err) - } - - res, err := doWithoutRedirect(req) - if err != nil { - t.Fatal(err) - } - - // check the immutable tag isn't set - hdrs, ok := res.Header["Cache-Control"] - if ok { - for _, hdr := range hdrs { - if strings.Contains(hdr, "immutable") { - t.Fatalf("unexpected Cache-Control: immutable on directory listing: %s", hdr) - } - } - } -} - -func TestGoGetSupport(t *testing.T) { - ts, _, _ := newTestServerAndNode(t, nil) - t.Logf("test server url: %s", ts.URL) - - // mimic go-get - req, err := http.NewRequest(http.MethodGet, ts.URL+emptyDir+"?go-get=1", nil) - if err != nil { - t.Fatal(err) - } - - res, err := doWithoutRedirect(req) - if err != nil { - t.Fatal(err) - } - - if res.StatusCode != 200 { - t.Errorf("status is %d, expected 200", res.StatusCode) - } -} - func TestVersion(t *testing.T) { version.CurrentCommit = "theshortcommithash" From 05afb879f3f5f1d6fcd4646523dc3eda32ac8901 Mon Sep 17 00:00:00 2001 From: Steve Loeppky Date: Thu, 16 Feb 2023 13:17:18 -0800 Subject: [PATCH 0472/1212] docs: "remote" errors from resource manager (#9653) Being more clear that the "remote" string means its from a remote peer. This came up in: https://github.com/ipfs/kubo/issues/9432#issuecomment-1402022085 https://github.com/ipfs/kubo/issues/9432#issuecomment-1402276883 https://github.com/ipfs/kubo/issues/9432#issuecomment-1410444354 --- docs/libp2p-resource-management.md | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/docs/libp2p-resource-management.md b/docs/libp2p-resource-management.md index f15be20c5..f8a7e58d5 100644 --- a/docs/libp2p-resource-management.md +++ b/docs/libp2p-resource-management.md @@ -12,22 +12,26 @@ Good places to start are: 3. Understand [how to inspect and change limits](#user-supplied-override-limits) ## Table of Contents + -- [libp2p Network Resource Manager (`Swarm.ResourceMgr`)](#libp2p-network-resource-manager-smallswarmresourcemgrsmall) - - [Purpose](#purpose) - - [Levels of Configuration](#levels-of-configuration) +- [Purpose](#purpose) +- [🙋 Help! The resource manager is protecting my node but I want to understand more](#-help--the-resource-manager-is-protecting-my-node-but-i-want-to-understand-more) +- [Table of Contents](#table-of-contents) +- [Levels of Configuration](#levels-of-configuration) - [Approach](#approach) - [Computed Default Limits](#computed-default-limits) - [User Supplied Override Limits](#user-supplied-override-limits) - [Infinite limits](#infinite-limits) - - [FAQ](#faq) +- [FAQ](#faq) - [What do these "Protected from exceeding resource limits" log messages mean?](#what-do-these-protected-from-exceeding-resource-limits-log-messages-mean) - - [What are the "Application error ... cannot reserve ..." messages?](#what-are-the-application-error--cannot-reserve--messages) - - [How does the resource manager (ResourceMgr) relate to the connection manager (ConnMgr)?](#how-does-the-resource-manager-resourcemgr-relate-to-the-connection-manager-connmgr) + - [What are the "Application error 0x0 remote ... cannot reserve ..." messages?](#what-are-the-application-error-0x0-remote--cannot-reserve--messages) + - [How does the resource manager ResourceMgr relate to the connection manager ConnMgr?](#how-does-the-resource-manager-resourcemgr-relate-to-the-connection-manager-connmgr) - [How does one see the Active Limits?](#how-does-one-see-the-active-limits) - [How does one see the Computed Default Limits?](#how-does-one-see-the-computed-default-limits) - [How does one monitor libp2p resource usage?](#how-does-one-monitor-libp2p-resource-usage) - - [History](#history) +- [History](#history) + + ## Levels of Configuration @@ -128,15 +132,15 @@ Sources: * [kubo resource manager logging](https://github.com/ipfs/kubo/blob/master/core/node/libp2p/rcmgr_logging.go) * [libp2p resource manager messages](https://github.com/libp2p/go-libp2p/blob/master/p2p/host/resource-manager/scope.go) -### What are the "Application error ... cannot reserve ..." messages? -These are messages from a *remote* go-libp2p peer (likely another Kubo node) with the resource manager enabled on why it failed to establish a connection. +### What are the "Application error 0x0 (remote) ... cannot reserve ..." messages? +These are messages coming from a *remote* go-libp2p peer (likely another Kubo node) with the resource manager enabled on why it failed to establish a connection. -This can be confusing, but these `Application error ... cannot reserve ...` messages can occur even if your local node has the resoure manager disabled. +This can be confusing, but these `Application error 0x0 (remote) ... cannot reserve ...` messages can occur even if your local node has the resoure manager disabled. You can distinguish resource manager messages originating from your local node if they're from the `resourcemanager` / `libp2p/rcmgr_logging.go` logger or you see the string that is unique to Kubo (and not in go-libp2p): "Protected from exceeding resource limits". -There is a go-libp2p issue ([#1928](https://github.com/libp2p/go-libp2p/issues/1928)) to make it clearer that this is an error message originating from a remote peer. +There is a go-libp2p issue ([#1928](https://github.com/libp2p/go-libp2p/issues/1928)) to make it even clearer that this is an error message originating from a remote peer. ### How does the resource manager (ResourceMgr) relate to the connection manager (ConnMgr)? As discussed [here](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#connmanager-vs-resource-manager) From 19feb15833c6f4d6e7f1e1b132efaae96d76481d Mon Sep 17 00:00:00 2001 From: Jorropo Date: Fri, 17 Feb 2023 19:58:48 +0100 Subject: [PATCH 0473/1212] chore: bump go-libipfs v0.6.0 --- docs/examples/kubo-as-a-library/go.mod | 20 +++++------ docs/examples/kubo-as-a-library/go.sum | 49 +++++++++++++++----------- go.mod | 20 +++++------ go.sum | 49 +++++++++++++++----------- 4 files changed, 76 insertions(+), 62 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 981af294c..ff040fdba 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.18 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/go-libipfs v0.5.0 + github.com/ipfs/go-libipfs v0.6.0 github.com/ipfs/interface-go-ipfs-core v0.11.0 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.25.2-0.20230214091718-aef956be688d @@ -86,7 +86,7 @@ require ( github.com/ipfs/go-ipfs-keystore v0.1.0 // indirect github.com/ipfs/go-ipfs-pinner v0.2.1 // indirect github.com/ipfs/go-ipfs-posinfo v0.0.1 // indirect - github.com/ipfs/go-ipfs-pq v0.0.2 // indirect + github.com/ipfs/go-ipfs-pq v0.0.3 // indirect github.com/ipfs/go-ipfs-provider v0.8.1 // indirect github.com/ipfs/go-ipfs-routing v0.3.0 // indirect github.com/ipfs/go-ipfs-util v0.0.2 // indirect @@ -102,7 +102,7 @@ require ( github.com/ipfs/go-mfs v0.2.1 // indirect github.com/ipfs/go-namesys v0.7.0 // indirect github.com/ipfs/go-path v0.3.0 // indirect - github.com/ipfs/go-peertaskqueue v0.8.0 // indirect + github.com/ipfs/go-peertaskqueue v0.8.1 // indirect github.com/ipfs/go-unixfs v0.4.2 // indirect github.com/ipfs/go-unixfsnode v1.5.1 // indirect github.com/ipfs/go-verifcid v0.0.2 // indirect @@ -113,7 +113,7 @@ require ( github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect github.com/jbenet/goprocess v0.1.4 // indirect github.com/klauspost/compress v1.15.12 // indirect - github.com/klauspost/cpuid/v2 v2.2.1 // indirect + github.com/klauspost/cpuid/v2 v2.2.3 // indirect github.com/koron/go-ssdp v0.0.3 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/libp2p/go-cidranger v1.1.0 // indirect @@ -158,7 +158,7 @@ require ( github.com/openzipkin/zipkin-go v0.4.0 // indirect github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect github.com/pkg/errors v0.9.1 // indirect - github.com/polydawn/refmt v0.0.0-20201211092308-30ac6d18308e // indirect + github.com/polydawn/refmt v0.89.0 // indirect github.com/prometheus/client_golang v1.14.0 // indirect github.com/prometheus/client_model v0.3.0 // indirect github.com/prometheus/common v0.37.0 // indirect @@ -174,7 +174,7 @@ require ( github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc // indirect - github.com/whyrusleeping/cbor-gen v0.0.0-20221220214510-0333c149dec0 // indirect + github.com/whyrusleeping/cbor-gen v0.0.0-20230126041949-52956bd4c9aa // indirect github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f // indirect github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 // indirect @@ -196,13 +196,13 @@ require ( go.uber.org/multierr v1.9.0 // indirect go.uber.org/zap v1.24.0 // indirect go4.org v0.0.0-20200411211856-f5505b9728dd // indirect - golang.org/x/crypto v0.4.0 // indirect - golang.org/x/exp v0.0.0-20221205204356-47842c84f3db // indirect + golang.org/x/crypto v0.5.0 // indirect + golang.org/x/exp v0.0.0-20230129154200-a960b3787bd2 // indirect golang.org/x/mod v0.7.0 // indirect - golang.org/x/net v0.4.0 // indirect + golang.org/x/net v0.5.0 // indirect golang.org/x/sync v0.1.0 // indirect golang.org/x/sys v0.4.0 // indirect - golang.org/x/text v0.5.0 // indirect + golang.org/x/text v0.6.0 // indirect golang.org/x/tools v0.3.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 9570851fb..0c1c2abf5 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -262,6 +262,7 @@ github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= 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/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8= @@ -537,8 +538,9 @@ github.com/ipfs/go-ipfs-pinner v0.2.1/go.mod h1:l1AtLL5bovb7opnG77sh4Y10waINz3Y1 github.com/ipfs/go-ipfs-posinfo v0.0.1 h1:Esoxj+1JgSjX0+ylc0hUmJCOv6V2vFoZiETLR6OtpRs= github.com/ipfs/go-ipfs-posinfo v0.0.1/go.mod h1:SwyeVP+jCwiDu0C313l/8jg6ZxM0qqtlt2a0vILTc1A= github.com/ipfs/go-ipfs-pq v0.0.1/go.mod h1:LWIqQpqfRG3fNc5XsnIhz/wQ2XXGyugQwls7BgUmUfY= -github.com/ipfs/go-ipfs-pq v0.0.2 h1:e1vOOW6MuOwG2lqxcLA+wEn93i/9laCY8sXAw76jFOY= github.com/ipfs/go-ipfs-pq v0.0.2/go.mod h1:LWIqQpqfRG3fNc5XsnIhz/wQ2XXGyugQwls7BgUmUfY= +github.com/ipfs/go-ipfs-pq v0.0.3 h1:YpoHVJB+jzK15mr/xsWC574tyDLkezVrDNeaalQBsTE= +github.com/ipfs/go-ipfs-pq v0.0.3/go.mod h1:btNw5hsHBpRcSSgZtiNm/SLj5gYIZ18AKtv3kERkRb4= github.com/ipfs/go-ipfs-provider v0.8.1 h1:qt670pYmcNH3BCjyXDgg07o2WsTRsOdMwYc25ukCdjQ= github.com/ipfs/go-ipfs-provider v0.8.1/go.mod h1:qCpwpoohIRVXvNzkygzsM3qdqP/sXlrogtA5I45tClc= github.com/ipfs/go-ipfs-routing v0.1.0/go.mod h1:hYoUkJLyAUKhF58tysKpids8RNDPO42BVMgK5dNsoqY= @@ -566,8 +568,8 @@ github.com/ipfs/go-ipld-legacy v0.1.1 h1:BvD8PEuqwBHLTKqlGFTHSwrwFOMkVESEvwIYwR2 github.com/ipfs/go-ipld-legacy v0.1.1/go.mod h1:8AyKFCjgRPsQFf15ZQgDB8Din4DML/fOmKZkkFkrIEg= github.com/ipfs/go-ipns v0.3.0 h1:ai791nTgVo+zTuq2bLvEGmWP1M0A6kGTXUsgv/Yq67A= github.com/ipfs/go-ipns v0.3.0/go.mod h1:3cLT2rbvgPZGkHJoPO1YMJeh6LtkxopCkKFcio/wE24= -github.com/ipfs/go-libipfs v0.5.0 h1:gtvzeoTdUHPUN4B5izzyBS3Cxtpvi+l7hd2mmjN+teM= -github.com/ipfs/go-libipfs v0.5.0/go.mod h1:iZ9QyhzNr3AkxRXrbQYb//rv7iLyvZJX0GNuc3lJDiQ= +github.com/ipfs/go-libipfs v0.6.0 h1:3FuckAJEm+zdHbHbf6lAyk0QUzc45LsFcGw102oBCZM= +github.com/ipfs/go-libipfs v0.6.0/go.mod h1:UjjDIuehp2GzlNP0HEr5I9GfFT7zWgst+YfpUEIThtw= github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= github.com/ipfs/go-log v1.0.2/go.mod h1:1MNjMxe0u6xvJZgeqbJ8vdo2TKaGwZ1a0Bpza+sr2Sk= github.com/ipfs/go-log v1.0.3/go.mod h1:OsLySYkwIbiSUR/yBTdv1qPtcE4FW3WPWk/ewz9Ru+A= @@ -599,8 +601,8 @@ github.com/ipfs/go-path v0.3.0 h1:tkjga3MtpXyM5v+3EbRvOHEoo+frwi4oumw5K+KYWyA= github.com/ipfs/go-path v0.3.0/go.mod h1:NOScsVgxfC/eIw4nz6OiGwK42PjaSJ4Y/ZFPn1Xe07I= github.com/ipfs/go-peertaskqueue v0.1.0/go.mod h1:Jmk3IyCcfl1W3jTW3YpghSwSEC6IJ3Vzz/jUmWw8Z0U= github.com/ipfs/go-peertaskqueue v0.7.0/go.mod h1:M/akTIE/z1jGNXMU7kFB4TeSEFvj68ow0Rrb04donIU= -github.com/ipfs/go-peertaskqueue v0.8.0 h1:JyNO144tfu9bx6Hpo119zvbEL9iQ760FHOiJYsUjqaU= -github.com/ipfs/go-peertaskqueue v0.8.0/go.mod h1:cz8hEnnARq4Du5TGqiWKgMr/BOSQ5XOgMOh1K5YYKKM= +github.com/ipfs/go-peertaskqueue v0.8.1 h1:YhxAs1+wxb5jk7RvS0LHdyiILpNmRIRnZVztekOF0pg= +github.com/ipfs/go-peertaskqueue v0.8.1/go.mod h1:Oxxd3eaK279FxeydSPPVGHzbwVeHjatZ2GA8XD+KbPU= github.com/ipfs/go-unixfs v0.2.4/go.mod h1:SUdisfUjNoSDzzhGVxvCL9QO/nKdwXdr+gbMUdqcbYw= github.com/ipfs/go-unixfs v0.3.1/go.mod h1:h4qfQYzghiIc8ZNFKiLMFWOTzrWIAtzYQ59W/pCFf1o= github.com/ipfs/go-unixfs v0.4.2 h1:hdQlsHHK5tek9gC9mjGVua8xyTqC+eopGseCRcbCZNg= @@ -680,8 +682,8 @@ github.com/klauspost/compress v1.15.12 h1:YClS/PImqYbn+UILDnqxQCZ3RehC9N318SU3kE github.com/klauspost/compress v1.15.12/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.2.1 h1:U33DW0aiEj633gHYw3LoDNfkDiYnE5Q8M/TKJn2f2jI= -github.com/klauspost/cpuid/v2 v2.2.1/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= +github.com/klauspost/cpuid/v2 v2.2.3 h1:sxCkb+qR91z4vsqw4vGGZlDgPz3G7gjaLyK3V8y70BU= +github.com/klauspost/cpuid/v2 v2.2.3/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/koron/go-ssdp v0.0.0-20180514024734-4a0ed625a78b/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk= @@ -1123,8 +1125,9 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/polydawn/refmt v0.0.0-20190221155625-df39d6c2d992/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= github.com/polydawn/refmt v0.0.0-20190408063855-01bf1e26dd14/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= github.com/polydawn/refmt v0.0.0-20190807091052-3d65705ee9f1/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= -github.com/polydawn/refmt v0.0.0-20201211092308-30ac6d18308e h1:ZOcivgkkFRnjfoTcGsDq3UQYiBmekwLA+qg0OjyB/ls= github.com/polydawn/refmt v0.0.0-20201211092308-30ac6d18308e/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= +github.com/polydawn/refmt v0.89.0 h1:ADJTApkvkeBZsN0tBTx8QjpD9JkmxbKp0cxfr9qszm4= +github.com/polydawn/refmt v0.89.0/go.mod h1:/zvteZs/GwLtCgZ4BL6CBsk9IKIlexP43ObX9AxTqTw= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= @@ -1225,12 +1228,14 @@ github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrf github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.8.1/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= +github.com/smartystreets/assertions v1.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N3yZFZkDFs= +github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo= github.com/smartystreets/goconvey v0.0.0-20190222223459-a17d461953aa/go.mod h1:2RVY1rIf+2J2o/IM9+vPq9RzmHDSseB7FoXiSNIUsoU= github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/smartystreets/goconvey v1.7.2 h1:9RBaZCeXEQ3UselpuwUQHltGVXvdwm6cv1hgR6gDIPg= +github.com/smartystreets/goconvey v1.7.2/go.mod h1:Vw0tHAZW6lzCRk3xgdin6fKYcG+G3Pg9vgXWeJpQFMM= github.com/smola/gocompat v0.2.0/go.mod h1:1B0MlxbmoZNo3h8guHp8HztB3BSYR5itql9qtVc0ypY= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= @@ -1284,6 +1289,7 @@ github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLY 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 v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU= github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM= @@ -1293,14 +1299,15 @@ github.com/warpfork/go-testmark v0.9.0/go.mod h1:jhEf8FVxd+F17juRubpmut64NEG6I2r github.com/warpfork/go-testmark v0.10.0 h1:E86YlUMYfwIacEsQGlnTvjk1IgYkyTGjPhF0RnwTCmw= github.com/warpfork/go-wish v0.0.0-20180510122957-5ad1f5abf436/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= github.com/warpfork/go-wish v0.0.0-20190328234359-8b3e70f8e830/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= -github.com/warpfork/go-wish v0.0.0-20200122115046-b9ea61034e4a h1:G++j5e0OC488te356JvdhaM8YS6nMsjLAYF7JxCv07w= github.com/warpfork/go-wish v0.0.0-20200122115046-b9ea61034e4a/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= +github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0 h1:GDDkbFiaK8jsSDJfjId/PEGEShv6ugrt4kYsC5UIDaQ= +github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc h1:BCPnHtcboadS0DvysUuJXZ4lWVv5Bh5i7+tbIyi+ck4= github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc/go.mod h1:r45hJU7yEoA81k6MWNhpMj/kms0n14dkzkxYHoB96UM= github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11 h1:5HZfQkwe0mIfyDmc1Em5GqlNRzcdtlv4HTNmdpt7XH0= github.com/whyrusleeping/cbor-gen v0.0.0-20200123233031-1cdf64d27158/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI= -github.com/whyrusleeping/cbor-gen v0.0.0-20221220214510-0333c149dec0 h1:obKzQ1ey5AJg5NKjgtTo/CKwLImVP4ETLRcsmzFJ4Qw= -github.com/whyrusleeping/cbor-gen v0.0.0-20221220214510-0333c149dec0/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= +github.com/whyrusleeping/cbor-gen v0.0.0-20230126041949-52956bd4c9aa h1:EyA027ZAkuaCLoxVX4r1TZMPy1d31fM6hbfQ4OU4I5o= +github.com/whyrusleeping/cbor-gen v0.0.0-20230126041949-52956bd4c9aa/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f h1:jQa4QT2UP9WYv2nzyawpKMOCl+Z/jW7djv2/J50lj9E= github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f/go.mod h1:p9UJB6dDgdPgMJZs7UjUOdulKyRr9fqkS+6JKAInPy8= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 h1:EKhdznlJHPMoKr0XTrX+IlJs1LH3lyx2nfr1dOlZ79k= @@ -1424,8 +1431,8 @@ golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWP golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210506145944-38f3c27a63bf/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= golang.org/x/crypto v0.0.0-20210920023735-84f357641f63/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.4.0 h1:UVQgzMY87xqpKNgb+kDsll2Igd33HszWHFLmpaRMq/8= -golang.org/x/crypto v0.4.0/go.mod h1:3quD/ATkf6oY+rnes5c3ExXTbLc8mueNue5/DoinL80= +golang.org/x/crypto v0.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE= +golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1436,8 +1443,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20221205204356-47842c84f3db h1:D/cFflL63o2KSLJIwjlcIt8PR064j/xsmdEJL/YvY/o= -golang.org/x/exp v0.0.0-20221205204356-47842c84f3db/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= +golang.org/x/exp v0.0.0-20230129154200-a960b3787bd2 h1:5sPMf9HJXrvBWIamTw+rTST0bZ3Mho2n1p58M0+W99c= +golang.org/x/exp v0.0.0-20230129154200-a960b3787bd2/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1520,8 +1527,8 @@ golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20210917221730-978cfadd31cf/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.4.0 h1:Q5QPcMlvfxFTAPV0+07Xz/MpK9NTXu2VDUuy0FeMfaU= -golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= +golang.org/x/net v0.5.0 h1:GyT4nK/YDHSqa1c4753ouYCDajOYKTja9Xb/OHtgvSw= +golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1642,8 +1649,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM= -golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.6.0 h1:3XmdazWV+ubf7QgHSTWeykHOci5oeekaGJBLkrkaw4k= +golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= diff --git a/go.mod b/go.mod index 287f4f13a..aa5e1b379 100644 --- a/go.mod +++ b/go.mod @@ -45,7 +45,7 @@ require ( github.com/ipfs/go-ipld-git v0.1.1 github.com/ipfs/go-ipld-legacy v0.1.1 github.com/ipfs/go-ipns v0.3.0 - github.com/ipfs/go-libipfs v0.5.0 + github.com/ipfs/go-libipfs v0.6.0 github.com/ipfs/go-log v1.0.5 github.com/ipfs/go-log/v2 v2.5.1 github.com/ipfs/go-merkledag v0.9.0 @@ -105,8 +105,8 @@ require ( go.uber.org/dig v1.15.0 go.uber.org/fx v1.18.2 go.uber.org/zap v1.24.0 - golang.org/x/crypto v0.4.0 - golang.org/x/exp v0.0.0-20221205204356-47842c84f3db + golang.org/x/crypto v0.5.0 + golang.org/x/exp v0.0.0-20230129154200-a960b3787bd2 golang.org/x/mod v0.7.0 golang.org/x/sync v0.1.0 golang.org/x/sys v0.4.0 @@ -160,14 +160,14 @@ require ( github.com/ipfs/go-block-format v0.1.1 // indirect github.com/ipfs/go-ipfs-delay v0.0.1 // indirect github.com/ipfs/go-ipfs-ds-help v1.1.0 // indirect - github.com/ipfs/go-ipfs-pq v0.0.2 // indirect + github.com/ipfs/go-ipfs-pq v0.0.3 // indirect github.com/ipfs/go-ipfs-redirects-file v0.1.1 // indirect github.com/ipfs/go-ipld-cbor v0.0.6 // indirect - github.com/ipfs/go-peertaskqueue v0.8.0 // indirect + github.com/ipfs/go-peertaskqueue v0.8.1 // indirect github.com/ipld/edelweiss v0.2.0 // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/klauspost/compress v1.15.12 // indirect - github.com/klauspost/cpuid/v2 v2.2.1 // indirect + github.com/klauspost/cpuid/v2 v2.2.3 // indirect github.com/koron/go-ssdp v0.0.3 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/libp2p/go-cidranger v1.1.0 // indirect @@ -201,7 +201,7 @@ require ( github.com/opencontainers/runtime-spec v1.0.2 // indirect github.com/openzipkin/zipkin-go v0.4.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/polydawn/refmt v0.0.0-20201211092308-30ac6d18308e // indirect + github.com/polydawn/refmt v0.89.0 // indirect github.com/prometheus/client_model v0.3.0 // indirect github.com/prometheus/common v0.37.0 // indirect github.com/prometheus/procfs v0.8.0 // indirect @@ -219,7 +219,7 @@ require ( github.com/texttheater/golang-levenshtein v0.0.0-20180516184445-d188e65d659e // indirect github.com/ucarion/urlpath v0.0.0-20200424170820-7ccc79b76bbb // indirect github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc // indirect - github.com/whyrusleeping/cbor-gen v0.0.0-20221220214510-0333c149dec0 // indirect + github.com/whyrusleeping/cbor-gen v0.0.0-20230126041949-52956bd4c9aa // indirect github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f // indirect github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.7.0 // indirect @@ -229,10 +229,10 @@ require ( go.uber.org/atomic v1.10.0 // indirect go.uber.org/multierr v1.9.0 // indirect go4.org v0.0.0-20200411211856-f5505b9728dd // indirect - golang.org/x/net v0.4.0 // indirect + golang.org/x/net v0.5.0 // indirect golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b // indirect golang.org/x/term v0.4.0 // indirect - golang.org/x/text v0.5.0 // indirect + golang.org/x/text v0.6.0 // indirect golang.org/x/tools v0.3.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/appengine v1.6.6 // indirect diff --git a/go.sum b/go.sum index cdd338ec4..818458b78 100644 --- a/go.sum +++ b/go.sum @@ -279,6 +279,7 @@ github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= 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/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8= @@ -557,8 +558,9 @@ github.com/ipfs/go-ipfs-pinner v0.2.1/go.mod h1:l1AtLL5bovb7opnG77sh4Y10waINz3Y1 github.com/ipfs/go-ipfs-posinfo v0.0.1 h1:Esoxj+1JgSjX0+ylc0hUmJCOv6V2vFoZiETLR6OtpRs= github.com/ipfs/go-ipfs-posinfo v0.0.1/go.mod h1:SwyeVP+jCwiDu0C313l/8jg6ZxM0qqtlt2a0vILTc1A= github.com/ipfs/go-ipfs-pq v0.0.1/go.mod h1:LWIqQpqfRG3fNc5XsnIhz/wQ2XXGyugQwls7BgUmUfY= -github.com/ipfs/go-ipfs-pq v0.0.2 h1:e1vOOW6MuOwG2lqxcLA+wEn93i/9laCY8sXAw76jFOY= github.com/ipfs/go-ipfs-pq v0.0.2/go.mod h1:LWIqQpqfRG3fNc5XsnIhz/wQ2XXGyugQwls7BgUmUfY= +github.com/ipfs/go-ipfs-pq v0.0.3 h1:YpoHVJB+jzK15mr/xsWC574tyDLkezVrDNeaalQBsTE= +github.com/ipfs/go-ipfs-pq v0.0.3/go.mod h1:btNw5hsHBpRcSSgZtiNm/SLj5gYIZ18AKtv3kERkRb4= github.com/ipfs/go-ipfs-provider v0.8.1 h1:qt670pYmcNH3BCjyXDgg07o2WsTRsOdMwYc25ukCdjQ= github.com/ipfs/go-ipfs-provider v0.8.1/go.mod h1:qCpwpoohIRVXvNzkygzsM3qdqP/sXlrogtA5I45tClc= github.com/ipfs/go-ipfs-redirects-file v0.1.1 h1:Io++k0Vf/wK+tfnhEh63Yte1oQK5VGT2hIEYpD0Rzx8= @@ -588,8 +590,8 @@ github.com/ipfs/go-ipld-legacy v0.1.1 h1:BvD8PEuqwBHLTKqlGFTHSwrwFOMkVESEvwIYwR2 github.com/ipfs/go-ipld-legacy v0.1.1/go.mod h1:8AyKFCjgRPsQFf15ZQgDB8Din4DML/fOmKZkkFkrIEg= github.com/ipfs/go-ipns v0.3.0 h1:ai791nTgVo+zTuq2bLvEGmWP1M0A6kGTXUsgv/Yq67A= github.com/ipfs/go-ipns v0.3.0/go.mod h1:3cLT2rbvgPZGkHJoPO1YMJeh6LtkxopCkKFcio/wE24= -github.com/ipfs/go-libipfs v0.5.0 h1:gtvzeoTdUHPUN4B5izzyBS3Cxtpvi+l7hd2mmjN+teM= -github.com/ipfs/go-libipfs v0.5.0/go.mod h1:iZ9QyhzNr3AkxRXrbQYb//rv7iLyvZJX0GNuc3lJDiQ= +github.com/ipfs/go-libipfs v0.6.0 h1:3FuckAJEm+zdHbHbf6lAyk0QUzc45LsFcGw102oBCZM= +github.com/ipfs/go-libipfs v0.6.0/go.mod h1:UjjDIuehp2GzlNP0HEr5I9GfFT7zWgst+YfpUEIThtw= github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= github.com/ipfs/go-log v1.0.2/go.mod h1:1MNjMxe0u6xvJZgeqbJ8vdo2TKaGwZ1a0Bpza+sr2Sk= github.com/ipfs/go-log v1.0.3/go.mod h1:OsLySYkwIbiSUR/yBTdv1qPtcE4FW3WPWk/ewz9Ru+A= @@ -623,8 +625,8 @@ github.com/ipfs/go-path v0.3.0 h1:tkjga3MtpXyM5v+3EbRvOHEoo+frwi4oumw5K+KYWyA= github.com/ipfs/go-path v0.3.0/go.mod h1:NOScsVgxfC/eIw4nz6OiGwK42PjaSJ4Y/ZFPn1Xe07I= github.com/ipfs/go-peertaskqueue v0.1.0/go.mod h1:Jmk3IyCcfl1W3jTW3YpghSwSEC6IJ3Vzz/jUmWw8Z0U= github.com/ipfs/go-peertaskqueue v0.7.0/go.mod h1:M/akTIE/z1jGNXMU7kFB4TeSEFvj68ow0Rrb04donIU= -github.com/ipfs/go-peertaskqueue v0.8.0 h1:JyNO144tfu9bx6Hpo119zvbEL9iQ760FHOiJYsUjqaU= -github.com/ipfs/go-peertaskqueue v0.8.0/go.mod h1:cz8hEnnARq4Du5TGqiWKgMr/BOSQ5XOgMOh1K5YYKKM= +github.com/ipfs/go-peertaskqueue v0.8.1 h1:YhxAs1+wxb5jk7RvS0LHdyiILpNmRIRnZVztekOF0pg= +github.com/ipfs/go-peertaskqueue v0.8.1/go.mod h1:Oxxd3eaK279FxeydSPPVGHzbwVeHjatZ2GA8XD+KbPU= github.com/ipfs/go-pinning-service-http-client v0.1.2 h1:jdr7KelhL9gNHTU8jbqPMwIexSZXgZzxNGkycCwmbXI= github.com/ipfs/go-pinning-service-http-client v0.1.2/go.mod h1:6wd5mjYhXJTiWU8b4RSWPpWdlzE5/csoXV0dWWMjun4= github.com/ipfs/go-unixfs v0.2.4/go.mod h1:SUdisfUjNoSDzzhGVxvCL9QO/nKdwXdr+gbMUdqcbYw= @@ -710,8 +712,8 @@ github.com/klauspost/compress v1.15.12 h1:YClS/PImqYbn+UILDnqxQCZ3RehC9N318SU3kE github.com/klauspost/compress v1.15.12/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.2.1 h1:U33DW0aiEj633gHYw3LoDNfkDiYnE5Q8M/TKJn2f2jI= -github.com/klauspost/cpuid/v2 v2.2.1/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= +github.com/klauspost/cpuid/v2 v2.2.3 h1:sxCkb+qR91z4vsqw4vGGZlDgPz3G7gjaLyK3V8y70BU= +github.com/klauspost/cpuid/v2 v2.2.3/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/koron/go-ssdp v0.0.0-20180514024734-4a0ed625a78b/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk= @@ -1167,8 +1169,9 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/polydawn/refmt v0.0.0-20190221155625-df39d6c2d992/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= github.com/polydawn/refmt v0.0.0-20190408063855-01bf1e26dd14/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= github.com/polydawn/refmt v0.0.0-20190807091052-3d65705ee9f1/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= -github.com/polydawn/refmt v0.0.0-20201211092308-30ac6d18308e h1:ZOcivgkkFRnjfoTcGsDq3UQYiBmekwLA+qg0OjyB/ls= github.com/polydawn/refmt v0.0.0-20201211092308-30ac6d18308e/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= +github.com/polydawn/refmt v0.89.0 h1:ADJTApkvkeBZsN0tBTx8QjpD9JkmxbKp0cxfr9qszm4= +github.com/polydawn/refmt v0.89.0/go.mod h1:/zvteZs/GwLtCgZ4BL6CBsk9IKIlexP43ObX9AxTqTw= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= @@ -1277,12 +1280,14 @@ github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrf github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.8.1/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= +github.com/smartystreets/assertions v1.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N3yZFZkDFs= +github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo= github.com/smartystreets/goconvey v0.0.0-20190222223459-a17d461953aa/go.mod h1:2RVY1rIf+2J2o/IM9+vPq9RzmHDSseB7FoXiSNIUsoU= github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/smartystreets/goconvey v1.7.2 h1:9RBaZCeXEQ3UselpuwUQHltGVXvdwm6cv1hgR6gDIPg= +github.com/smartystreets/goconvey v1.7.2/go.mod h1:Vw0tHAZW6lzCRk3xgdin6fKYcG+G3Pg9vgXWeJpQFMM= github.com/smola/gocompat v0.2.0/go.mod h1:1B0MlxbmoZNo3h8guHp8HztB3BSYR5itql9qtVc0ypY= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= @@ -1341,6 +1346,7 @@ github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLY 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 v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU= github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM= @@ -1350,14 +1356,15 @@ github.com/warpfork/go-testmark v0.9.0/go.mod h1:jhEf8FVxd+F17juRubpmut64NEG6I2r github.com/warpfork/go-testmark v0.10.0 h1:E86YlUMYfwIacEsQGlnTvjk1IgYkyTGjPhF0RnwTCmw= github.com/warpfork/go-wish v0.0.0-20180510122957-5ad1f5abf436/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= github.com/warpfork/go-wish v0.0.0-20190328234359-8b3e70f8e830/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= -github.com/warpfork/go-wish v0.0.0-20200122115046-b9ea61034e4a h1:G++j5e0OC488te356JvdhaM8YS6nMsjLAYF7JxCv07w= github.com/warpfork/go-wish v0.0.0-20200122115046-b9ea61034e4a/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= +github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0 h1:GDDkbFiaK8jsSDJfjId/PEGEShv6ugrt4kYsC5UIDaQ= +github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc h1:BCPnHtcboadS0DvysUuJXZ4lWVv5Bh5i7+tbIyi+ck4= github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc/go.mod h1:r45hJU7yEoA81k6MWNhpMj/kms0n14dkzkxYHoB96UM= github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11 h1:5HZfQkwe0mIfyDmc1Em5GqlNRzcdtlv4HTNmdpt7XH0= github.com/whyrusleeping/cbor-gen v0.0.0-20200123233031-1cdf64d27158/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI= -github.com/whyrusleeping/cbor-gen v0.0.0-20221220214510-0333c149dec0 h1:obKzQ1ey5AJg5NKjgtTo/CKwLImVP4ETLRcsmzFJ4Qw= -github.com/whyrusleeping/cbor-gen v0.0.0-20221220214510-0333c149dec0/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= +github.com/whyrusleeping/cbor-gen v0.0.0-20230126041949-52956bd4c9aa h1:EyA027ZAkuaCLoxVX4r1TZMPy1d31fM6hbfQ4OU4I5o= +github.com/whyrusleeping/cbor-gen v0.0.0-20230126041949-52956bd4c9aa/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f h1:jQa4QT2UP9WYv2nzyawpKMOCl+Z/jW7djv2/J50lj9E= github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f/go.mod h1:p9UJB6dDgdPgMJZs7UjUOdulKyRr9fqkS+6JKAInPy8= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 h1:EKhdznlJHPMoKr0XTrX+IlJs1LH3lyx2nfr1dOlZ79k= @@ -1487,8 +1494,8 @@ golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWP golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210506145944-38f3c27a63bf/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= golang.org/x/crypto v0.0.0-20210920023735-84f357641f63/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.4.0 h1:UVQgzMY87xqpKNgb+kDsll2Igd33HszWHFLmpaRMq/8= -golang.org/x/crypto v0.4.0/go.mod h1:3quD/ATkf6oY+rnes5c3ExXTbLc8mueNue5/DoinL80= +golang.org/x/crypto v0.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE= +golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1499,8 +1506,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20221205204356-47842c84f3db h1:D/cFflL63o2KSLJIwjlcIt8PR064j/xsmdEJL/YvY/o= -golang.org/x/exp v0.0.0-20221205204356-47842c84f3db/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= +golang.org/x/exp v0.0.0-20230129154200-a960b3787bd2 h1:5sPMf9HJXrvBWIamTw+rTST0bZ3Mho2n1p58M0+W99c= +golang.org/x/exp v0.0.0-20230129154200-a960b3787bd2/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1584,8 +1591,8 @@ golang.org/x/net v0.0.0-20210917221730-978cfadd31cf/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.4.0 h1:Q5QPcMlvfxFTAPV0+07Xz/MpK9NTXu2VDUuy0FeMfaU= -golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= +golang.org/x/net v0.5.0 h1:GyT4nK/YDHSqa1c4753ouYCDajOYKTja9Xb/OHtgvSw= +golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1711,8 +1718,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM= -golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.6.0 h1:3XmdazWV+ubf7QgHSTWeykHOci5oeekaGJBLkrkaw4k= +golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= From 714a968faadf297eae02e7f0a88a3d14463b0a35 Mon Sep 17 00:00:00 2001 From: ElPaisano <113373882+ElPaisano@users.noreply.github.com> Date: Mon, 20 Feb 2023 22:37:10 +0000 Subject: [PATCH 0474/1212] docs: bulk spelling edits (#9544) Co-authored-by: Jorropo Co-authored-by: Steve Loeppky Co-authored-by: Gus Eggert Co-authored-by: Marcin Rataj --- cmd/ipfs/dist/README.md | 4 +- docs/RELEASE_ISSUE_TEMPLATE.md | 6 +- docs/changelogs/v0.10.md | 2 +- docs/changelogs/v0.11.md | 4 +- docs/changelogs/v0.12.md | 2 +- docs/changelogs/v0.13.md | 14 +-- docs/changelogs/v0.15.md | 12 +-- docs/changelogs/v0.17.md | 2 +- docs/changelogs/v0.18.md | 4 +- docs/changelogs/v0.3.md | 14 +-- docs/changelogs/v0.4.md | 90 +++++++++---------- docs/changelogs/v0.5.md | 12 +-- docs/changelogs/v0.7.md | 8 +- docs/changelogs/v0.8.md | 4 +- docs/changelogs/v0.9.md | 12 +-- docs/config.md | 4 +- docs/delegated-routing.md | 3 +- docs/experimental-features.md | 2 +- docs/http-rpc-clients.md | 2 +- docs/libp2p-resource-management.md | 15 ++-- test/sharness/README.md | 2 +- .../README.md | 2 +- 22 files changed, 110 insertions(+), 110 deletions(-) diff --git a/cmd/ipfs/dist/README.md b/cmd/ipfs/dist/README.md index f541482ca..4517f655b 100644 --- a/cmd/ipfs/dist/README.md +++ b/cmd/ipfs/dist/README.md @@ -1,6 +1,6 @@ -# ipfs commandline tool +# ipfs command line tool -This is the [ipfs](http://ipfs.io) commandline tool. It contains a full ipfs node. +This is the [ipfs](http://ipfs.io) command line tool. It contains a full ipfs node. ## Install diff --git a/docs/RELEASE_ISSUE_TEMPLATE.md b/docs/RELEASE_ISSUE_TEMPLATE.md index 13b14c8a4..da3ec3e18 100644 --- a/docs/RELEASE_ISSUE_TEMPLATE.md +++ b/docs/RELEASE_ISSUE_TEMPLATE.md @@ -41,7 +41,7 @@ As usual, this release includes important fixes, some of which may be critical f Checklist: - [ ] **Stage 0 - Prerequisites** - - [ ] Open an issue against [bifrost-infra](https://github.com/protocol/bifrost-infra) ahead of the release ([example](https://github.com/protocol/bifrost-infra/issues/2109)). **Idealy, do this multiple days in advance of the RC** to give Bifrost the heads up that asks will be coming their way. + - [ ] Open an issue against [bifrost-infra](https://github.com/protocol/bifrost-infra) ahead of the release ([example](https://github.com/protocol/bifrost-infra/issues/2109)). **Ideally, do this multiple days in advance of the RC** to give Bifrost the heads up that asks will be coming their way. - [ ] Spell out all that we want updated - gateways, the bootstraper and the cluster/preload nodes - [ ] Mention @protocol/bifrost-team in the issue and let them know the expected date of the release - Issue link: @@ -74,7 +74,7 @@ Checklist: - [ ] If it's not a first RC, add new commits to the `release-vX.Y.Z` branch from `master` using `git cherry-pick -x ...` - Note: `release-*` branches are protected. You can do all needed updates on a separated branch (e.g. `wip-release-vX.Y.Z`) and when everything is settled push to `release-vX.Y.Z` - [ ] Bump the version in `version.go` in the `release-vX.Y.Z` branch to `vX.Y.Z-rcN`. - - [ ] If it's a first RC, create a draft PR targetting `release` branch if it doesn't exist yet ([example](https://github.com/ipfs/kubo/pull/9306)). + - [ ] If it's a first RC, create a draft PR targeting `release` branch if it doesn't exist yet ([example](https://github.com/ipfs/kubo/pull/9306)). - [ ] Wait for CI to run and complete PR checks. All checks should pass. - [ ] Create a signed tag for the release candidate. - [ ] This is a dangerous operation, as it is difficult to reverse due to Go modules and automated Docker image publishing. Remember to verify the commands you intend to run for items marked with ⚠️ with the release reviewer. @@ -144,7 +144,7 @@ Checklist: - [ ] Commit the changelog changes. - [ ] Push the `release-vX.Y.Z` branch to GitHub (`git push origin release-vX.Y.Z`) - [ ] Mark the PR created from `release-vX.Y.Z` as ready for review. - - [ ] Ensure the PR is targetting `release` branch. + - [ ] Ensure the PR is targeting `release` branch. - [ ] Ensure that CI is green. - [ ] Have release reviewer review the PR. - [ ] Merge the PR into `release` branch using the `Create a merge commit` (do **NOT** use `Squash and merge` nor `Rebase and merge` because we need to be able to sign the merge commit). diff --git a/docs/changelogs/v0.10.md b/docs/changelogs/v0.10.md index b4bbf1047..ea92201a9 100644 --- a/docs/changelogs/v0.10.md +++ b/docs/changelogs/v0.10.md @@ -278,7 +278,7 @@ See `ipfs swarm peering --help` for more details. ([ipld/go-ipld-prime#228](https://github.com/ipld/go-ipld-prime/pull/228)) - Fix ExploreRecursive stopAt condition, add tests, add error return to Explore (#229) ([ipld/go-ipld-prime#229](https://github.com/ipld/go-ipld-prime/pull/229)) - selector: add tests which are driven by language-agnostic spec fixtures. ([ipld/go-ipld-prime#231](https://github.com/ipld/go-ipld-prime/pull/231)) - - selector: Improve docs for implementors. (#227) ([ipld/go-ipld-prime#227](https://github.com/ipld/go-ipld-prime/pull/227)) + - selector: Improve docs for implementers. (#227) ([ipld/go-ipld-prime#227](https://github.com/ipld/go-ipld-prime/pull/227)) - Bindnode fixes of opportunity ([ipld/go-ipld-prime#226](https://github.com/ipld/go-ipld-prime/pull/226)) - node/bindnode: redesign the shape of unions in Go ([ipld/go-ipld-prime#223](https://github.com/ipld/go-ipld-prime/pull/223)) - summary of the v0.11.0 changelog should holler even more about how cool bindnode is. diff --git a/docs/changelogs/v0.11.md b/docs/changelogs/v0.11.md index 9a3d2b7c9..98133052a 100644 --- a/docs/changelogs/v0.11.md +++ b/docs/changelogs/v0.11.md @@ -260,7 +260,7 @@ This work was [contributed](https://github.com/ipfs/go-ipfs/pull/8569) by [Ceram - feat(queryexecutor): merge RunTraversal into QueryExecutor - feat(responsemanager): QueryExecutor to separate module - use TaskQueue, add tests - Merge branch 'release/v0.10.5' - - fix(responseassembler): dont hold block data reference in passed on subscribed block link (#268) ([ipfs/go-graphsync#268](https://github.com/ipfs/go-graphsync/pull/268)) + - fix(responseassembler): don't hold block data reference in passed on subscribed block link (#268) ([ipfs/go-graphsync#268](https://github.com/ipfs/go-graphsync/pull/268)) - sync: update CI config files (#266) ([ipfs/go-graphsync#266](https://github.com/ipfs/go-graphsync/pull/266)) - Check IPLD context cancellation error type instead of string comparison - Use `context.CancelFunc` instead of `func()` (#257) ([ipfs/go-graphsync#257](https://github.com/ipfs/go-graphsync/pull/257)) @@ -622,7 +622,7 @@ This work was [contributed](https://github.com/ipfs/go-ipfs/pull/8569) by [Ceram - github.com/libp2p/go-libp2p-pubsub (v0.5.4 -> v0.6.0): - feat: plumb through context changes (#459) ([libp2p/go-libp2p-pubsub#459](https://github.com/libp2p/go-libp2p-pubsub/pull/459)) - support MinTopicSize without a discovery mechanism - - clear peerPromises map when fullfilling a promise + - clear peerPromises map when fulfilling a promise - README: remove obsolete notice, fix example code for tracing. - remove peer filter check from subscriptions (#453) ([libp2p/go-libp2p-pubsub#453](https://github.com/libp2p/go-libp2p-pubsub/pull/453)) - Create peer filter option diff --git a/docs/changelogs/v0.12.md b/docs/changelogs/v0.12.md index 85639dd2b..def891271 100644 --- a/docs/changelogs/v0.12.md +++ b/docs/changelogs/v0.12.md @@ -166,7 +166,7 @@ For this migration, if your datastore has fast renames you may want to consider - Version 1.1.0 (#91) ([ipfs/go-ipfs-blockstore#91](https://github.com/ipfs/go-ipfs-blockstore/pull/91)) - feat: add context to interfaces (#90) ([ipfs/go-ipfs-blockstore#90](https://github.com/ipfs/go-ipfs-blockstore/pull/90)) - sync: update CI config files (#88) ([ipfs/go-ipfs-blockstore#88](https://github.com/ipfs/go-ipfs-blockstore/pull/88)) - - add constructor that doesnt mess with datastore keys ([ipfs/go-ipfs-blockstore#83](https://github.com/ipfs/go-ipfs-blockstore/pull/83)) + - add constructor that doesn't mess with datastore keys ([ipfs/go-ipfs-blockstore#83](https://github.com/ipfs/go-ipfs-blockstore/pull/83)) - Use bloom filter in GetSize - fix staticcheck ([ipfs/go-ipfs-blockstore#73](https://github.com/ipfs/go-ipfs-blockstore/pull/73)) - add BenchmarkARCCacheConcurrentOps ([ipfs/go-ipfs-blockstore#70](https://github.com/ipfs/go-ipfs-blockstore/pull/70)) diff --git a/docs/changelogs/v0.13.md b/docs/changelogs/v0.13.md index d0635beb8..9bf4ee88a 100644 --- a/docs/changelogs/v0.13.md +++ b/docs/changelogs/v0.13.md @@ -29,7 +29,7 @@ View the linked [security advisory](https://github.com/ipfs/go-ipfs/security/adv - Remove support for `ForEach` enumeration from car-index-sorted - Use a fix code as the multihash code for `CarIndexSorted` - Fix testutil assertion logic and update index generation tests - - fix: tighter constraint of singleWidthIndex width, add index recommentation docs + - fix: tighter constraint of singleWidthIndex width, add index recommendation docs - fix: explicitly disable serialization of insertionindex - feat: MaxAllowed{Header,Section}Size option - feat: MaxAllowedSectionSize default to 32M @@ -66,7 +66,7 @@ View the linked [security advisory](https://github.com/ipfs/go-ipfs/security/adv - Traversal-based car creation (#269) ([ipld/go-car#269](https://github.com/ipld/go-car/pull/269)) - Seek to start before index generation in `ReadOnly` blockstore - support extraction of unixfs content stored in car files (#263) ([ipld/go-car#263](https://github.com/ipld/go-car/pull/263)) - - Add a barebones readme to the car CLI (#262) ([ipld/go-car#262](https://github.com/ipld/go-car/pull/262)) + - Add a bare bones readme to the car CLI (#262) ([ipld/go-car#262](https://github.com/ipld/go-car/pull/262)) - sync: update CI config files (#261) ([ipld/go-car#261](https://github.com/ipld/go-car/pull/261)) - fix!: use -version=n instead of -v1 for index command - feat: fix get-dag and add version=1 option @@ -223,7 +223,7 @@ Future releases will [add support for dag-json and dag-cbor responses](https://g There are two ways for requesting CID specific response format: 1. HTTP header: `Accept: application/vnd.ipld.{format}` - Examples: [application/vnd.ipld.car](https://www.iana.org/assignments/media-types/application/vnd.ipld.car), [application/vnd.ipld.raw](https://www.iana.org/assignments/media-types/application/vnd.ipld.raw) -2. URL paramerer: `?format=` +2. URL parameter: `?format=` - Useful for creating "Download CAR" links. *Usage examples:* @@ -629,7 +629,7 @@ The more fully featured yamux stream multiplexer is now prioritized over mplex f - fix: cannot call SetPrimaryCore after using a Tee logger ([ipfs/go-log#121](https://github.com/ipfs/go-log/pull/121)) - Document environment variables ([ipfs/go-log#120](https://github.com/ipfs/go-log/pull/120)) - sync: update CI config files (#119) ([ipfs/go-log#119](https://github.com/ipfs/go-log/pull/119)) - - Add WithStacktrace untility ([ipfs/go-log#118](https://github.com/ipfs/go-log/pull/118)) + - Add WithStacktrace utility ([ipfs/go-log#118](https://github.com/ipfs/go-log/pull/118)) - In addition to StdOut/Err check the outfile for TTYness ([ipfs/go-log#117](https://github.com/ipfs/go-log/pull/117)) - github.com/ipfs/go-merkledag (v0.5.1 -> v0.6.0): - v0.6.0 @@ -659,7 +659,7 @@ The more fully featured yamux stream multiplexer is now prioritized over mplex f - add AsLargeBytes support to unixfs files (#24) ([ipfs/go-unixfsnode#24](https://github.com/ipfs/go-unixfsnode/pull/24)) - fix: add extra test to span the shard/no-shard boundary - fix: more Tsize fixes, fix HAMT and make it match go-unixfs output - - fix: encode Tsize correctly everywhere (using wraped LinkSystem) + - fix: encode Tsize correctly everywhere (using wrapped LinkSystem) - docs(version): tag 1.2.0 - Update deps for ADL selectors ([ipfs/go-unixfsnode#20](https://github.com/ipfs/go-unixfsnode/pull/20)) - add license (#17) ([ipfs/go-unixfsnode#17](https://github.com/ipfs/go-unixfsnode/pull/17)) @@ -951,7 +951,7 @@ The more fully featured yamux stream multiplexer is now prioritized over mplex f - disable the incoming streams limit (#49) ([libp2p/go-libp2p-yamux#49](https://github.com/libp2p/go-libp2p-yamux/pull/49)) - Release v0.8.1 ([libp2p/go-libp2p-yamux#48](https://github.com/libp2p/go-libp2p-yamux/pull/48)) - release v0.8.0 (#47) ([libp2p/go-libp2p-yamux#47](https://github.com/libp2p/go-libp2p-yamux/pull/47)) - - pass the PeerScope to yamux (satifiying its MemoryManger interface) (#46) ([libp2p/go-libp2p-yamux#46](https://github.com/libp2p/go-libp2p-yamux/pull/46)) + - pass the PeerScope to yamux ( satisfying its MemoryManger interface) (#46) ([libp2p/go-libp2p-yamux#46](https://github.com/libp2p/go-libp2p-yamux/pull/46)) - release v0.7.0 (#43) ([libp2p/go-libp2p-yamux#43](https://github.com/libp2p/go-libp2p-yamux/pull/43)) - sync: update CI config files (#42) ([libp2p/go-libp2p-yamux#42](https://github.com/libp2p/go-libp2p-yamux/pull/42)) - reduce the number of max incoming stream to 256 ([libp2p/go-libp2p-yamux#41](https://github.com/libp2p/go-libp2p-yamux/pull/41)) @@ -973,7 +973,7 @@ The more fully featured yamux stream multiplexer is now prioritized over mplex f - multiplex: add (*Multiplex).CloseChan ([libp2p/go-mplex#89](https://github.com/libp2p/go-mplex/pull/89)) - add a Go Reference badge to the README ([libp2p/go-mplex#88](https://github.com/libp2p/go-mplex/pull/88)) - sync: update CI config files ([libp2p/go-mplex#85](https://github.com/libp2p/go-mplex/pull/85)) - - Fixup tests & vet ([libp2p/go-mplex#84](https://github.com/libp2p/go-mplex/pull/84)) + - Fix up tests & vet ([libp2p/go-mplex#84](https://github.com/libp2p/go-mplex/pull/84)) - Bump lodash from 4.17.19 to 4.17.21 in /interop/js ([libp2p/go-mplex#83](https://github.com/libp2p/go-mplex/pull/83)) - github.com/libp2p/go-msgio (v0.1.0 -> v0.2.0): - release v0.2.0 (#34) ([libp2p/go-msgio#34](https://github.com/libp2p/go-msgio/pull/34)) diff --git a/docs/changelogs/v0.15.md b/docs/changelogs/v0.15.md index 93033b26c..cc51aba1a 100644 --- a/docs/changelogs/v0.15.md +++ b/docs/changelogs/v0.15.md @@ -75,7 +75,7 @@ http://127.0.0.1:8080 - docs(add): skip binary name in helptext - docs(cli): clarify CID determinism in add command - docs(cli): clarify CAR format in dag export|import - - test(gw): cors preflight with custom hearder + - test(gw): cors preflight with custom header - feat: make corehttp a reusable component ([ipfs/kubo#9070](https://github.com/ipfs/kubo/pull/9070)) - feat: go-libp2p v0.21 (rcmgr auto scaling) ([ipfs/kubo#9074](https://github.com/ipfs/kubo/pull/9074)) - ([ipfs/kubo#9024](https://github.com/ipfs/kubo/pull/9024)) @@ -90,7 +90,7 @@ http://127.0.0.1:8080 - feat: add $IPFS_PATH/gateway file - docs: replace `docs.ipfs.io` with `docs.ipfs.tech` (#9158) ([ipfs/kubo#9158](https://github.com/ipfs/kubo/pull/9158)) - chore: fix markdown link syntax typo for AutoNAT.ServiceMode - - chore: bump go-blockservice to only do put onces + - chore: bump go-blockservice to only do put once - docs: update Arch Linux installation instructions - chore: update kubo-as-a-library example - docs(readme): add maintainer info (#9141) ([ipfs/kubo#9141](https://github.com/ipfs/kubo/pull/9141)) @@ -212,9 +212,9 @@ http://127.0.0.1:8080 - Add package docs ([libp2p/go-libp2p-resource-manager#75](https://github.com/libp2p/go-libp2p-resource-manager/pull/75)) - chore: Release v0.5.2 ([libp2p/go-libp2p-resource-manager#74](https://github.com/libp2p/go-libp2p-resource-manager/pull/74)) - Record which direction the resource was blocked ([libp2p/go-libp2p-resource-manager#72](https://github.com/libp2p/go-libp2p-resource-manager/pull/72)) - - Simplify mem graphs in stock grafana dashboard ([libp2p/go-libp2p-resource-manager#73](https://github.com/libp2p/go-libp2p-resource-manager/pull/73)) - - feat: Handle multiple instances in stock grafana dashboard ([libp2p/go-libp2p-resource-manager#70](https://github.com/libp2p/go-libp2p-resource-manager/pull/70)) - - Use templated version of grafana dashboard json ([libp2p/go-libp2p-resource-manager#69](https://github.com/libp2p/go-libp2p-resource-manager/pull/69)) + - Simplify mem graphs in stock Grafana dashboard ([libp2p/go-libp2p-resource-manager#73](https://github.com/libp2p/go-libp2p-resource-manager/pull/73)) + - feat: Handle multiple instances in stock Grafana dashboard ([libp2p/go-libp2p-resource-manager#70](https://github.com/libp2p/go-libp2p-resource-manager/pull/70)) + - Use templated version of Grafana dashboard json ([libp2p/go-libp2p-resource-manager#69](https://github.com/libp2p/go-libp2p-resource-manager/pull/69)) - Release v0.5.1 ([libp2p/go-libp2p-resource-manager#66](https://github.com/libp2p/go-libp2p-resource-manager/pull/66)) - Implement `json.Marshaler` interface for LimitConfig ([libp2p/go-libp2p-resource-manager#67](https://github.com/libp2p/go-libp2p-resource-manager/pull/67)) - Don't wait for a chan that will never close ([libp2p/go-libp2p-resource-manager#65](https://github.com/libp2p/go-libp2p-resource-manager/pull/65)) @@ -249,7 +249,7 @@ http://127.0.0.1:8080 - remove Travis package (#57) ([libp2p/go-libp2p-testing#57](https://github.com/libp2p/go-libp2p-testing/pull/57)) - github.com/lucas-clemente/quic-go (v0.27.1 -> v0.28.0): - update for Go 1.19beta1 (#3460) ([lucas-clemente/quic-go#3460](https://github.com/lucas-clemente/quic-go/pull/3460)) - - dedupe Alt-Svc header values (#3461) ([lucas-clemente/quic-go#3461](https://github.com/lucas-clemente/quic-go/pull/3461)) + - Deduplicate Alt-Svc header values (#3461) ([lucas-clemente/quic-go#3461](https://github.com/lucas-clemente/quic-go/pull/3461)) - only set DF for sockets that can handle it (#3448) ([lucas-clemente/quic-go#3448](https://github.com/lucas-clemente/quic-go/pull/3448)) - fix flaky HTTP/3 request body test (#3447) ([lucas-clemente/quic-go#3447](https://github.com/lucas-clemente/quic-go/pull/3447)) - make the keep alive interval configurable (#3444) ([lucas-clemente/quic-go#3444](https://github.com/lucas-clemente/quic-go/pull/3444)) diff --git a/docs/changelogs/v0.17.md b/docs/changelogs/v0.17.md index 867ddf3ae..3c06cfc02 100644 --- a/docs/changelogs/v0.17.md +++ b/docs/changelogs/v0.17.md @@ -40,7 +40,7 @@ and [Swarm.ResourceMgr.MaxFileDescriptors](https://github.com/ipfs/go-ipfs/blob/ See [Swarm.ResourceMgr](https://github.com/ipfs/go-ipfs/blob/master/docs/config.md#swarmresourcemgr) for 1. what limits are set by default, 2. example override configuration, -3. how to access prometheus metrics and view grafana dashboards of resource usage, and +3. how to access Prometheus metrics and view Grafana dashboards of resource usage, and 4. how to set explicit "allow lists" to protect against eclipse attacks. #### Implicit connection manager limits diff --git a/docs/changelogs/v0.18.md b/docs/changelogs/v0.18.md index 3ea6ffef0..5b3b15439 100644 --- a/docs/changelogs/v0.18.md +++ b/docs/changelogs/v0.18.md @@ -134,7 +134,7 @@ Learn more in the [`Routing` docs](https://github.com/ipfs/kubo/blob/master/docs Default `Reprovider.Interval` changed from 12h to 22h to match new defaults for the Provider Record Expiration (48h) in [go-libp2p-kad-dht v0.20.0](https://github.com/libp2p/go-libp2p-kad-dht/releases/tag/v0.20.0). The rationale for increasing this can be found in -[RFM 17: Provider Record Livenes Report](https://github.com/protocol/network-measurements/blob/master/results/rfm17-provider-record-liveness.md), +[RFM 17: Provider Record Liveness Report](https://github.com/protocol/network-measurements/blob/master/results/rfm17-provider-record-liveness.md), [kubo#9326](https://github.com/ipfs/kubo/pull/9326), and the upstream DHT specifications at [libp2p/specs#451](https://github.com/libp2p/specs/pull/451). @@ -285,7 +285,7 @@ go-libp2p do supports listening with both QUIC versions on one single listener. WebTransport has only supported QUICv1. `/webtransport` now needs to be prefixed by a `/quic-v1` component instead of a `/quic` component. -Support for QUIC Draft-29 will be removed at some point in 2023 ([tracking issue](https://github.com/ipfs/kubo/issues/9496)). As a result, new deployements should use `/quic-v1` instead of `/quic`. +Support for QUIC Draft-29 will be removed at some point in 2023 ([tracking issue](https://github.com/ipfs/kubo/issues/9496)). As a result, new deployments should use `/quic-v1` instead of `/quic`. ##### QUICv1 and WebTransport config migration To support QUICv1 and WebTransport by default a new config migration (`v13`) is run which automatically adds entries in addresses-related fields: diff --git a/docs/changelogs/v0.3.md b/docs/changelogs/v0.3.md index 5d37a1b52..61c2f431e 100644 --- a/docs/changelogs/v0.3.md +++ b/docs/changelogs/v0.3.md @@ -46,7 +46,7 @@ test coverage. ## v0.3.10 - 2015-12-07 This patch update introduces the 'ipfs update' command which will be used for -future ipfs updates along with a few other bugfixes and documentation +future ipfs updates along with a few other bug fixes and documentation improvements. @@ -156,7 +156,7 @@ NOTICE: Version 0.3.8 also requires golang version 1.5.1 or higher. * use go1.5's built in trailers, no more failures (@whyrusleeping) * fix random bitswap hangs (@whyrusleeping) * rate limit fd usage (@whyrusleeping) - * fix panic in bitswap ratelimiting (@whyrusleeping) + * fix panic in bitswap rate limiting (@whyrusleeping) * Tool Changes * --empty-repo option for init (@prusnak) @@ -264,7 +264,7 @@ fixes (yet again) windows builds. * remove deadcode @lgierth @whyrusleeping * reduced number of logging libs to 2 (soon to be 1) @rht * dial address filtering @whyrusleeping - * prometheus metrics @lgierth + * Prometheus metrics @lgierth * new index page for gateway @krl @cryptix * move ping to separate protocol @whyrusleeping * add events to bitswap for a dashboard @whyrusleeping @@ -340,9 +340,9 @@ This patch improves overall stability and performance This patch update fixes various issues, in particular: - windows support (0.3.0 had broken it) -- commandline parses spaces correctly. +- command line parses spaces correctly. -* much improved commandline parsing by @AtnNn +* much improved command line parsing by @AtnNn * improved dockerfile by @luzifer * add cmd cleanup by @wking * fix flatfs windows support by @tv42 and @gatesvp @@ -354,7 +354,7 @@ This patch update fixes various issues, in particular: ## v0.3.2 - 2015-04-22 -This patch update implements multicast dns as well as fxing a few test issues. +This patch update implements multicast dns as well as fixing a few test issues. * implement mdns peer discovery @whyrusleeping * fix mounting issues in sharness tests @chriscool @@ -404,6 +404,6 @@ What to expect: * other * bash completion is now available - * ipfs stats bw -- bandwidth meetering + * ipfs stats bw -- bandwidth metering And many more things. diff --git a/docs/changelogs/v0.4.md b/docs/changelogs/v0.4.md index 7096d2327..5abf5df67 100644 --- a/docs/changelogs/v0.4.md +++ b/docs/changelogs/v0.4.md @@ -306,7 +306,7 @@ handshake). ### Commands -This release brings no new commands but does introduce a few changes, bugfixes, +This release brings no new commands but does introduce a few changes, bug fixes, and enhancements. This section is hardly complete but it lists the most noticeable changes. @@ -1122,7 +1122,7 @@ earlier on start. - add function to marshal raw nodes to json ([ipfs/go-merkledag#36](https://github.com/ipfs/go-merkledag/pull/36)) - fix some performance regressions when reading protobuf nodes ([ipfs/go-merkledag#34](https://github.com/ipfs/go-merkledag/pull/34)) - github.com/ipfs/go-metrics-interface: - - update the counter interface to match prometheus ([ipfs/go-metrics-interface#2](https://github.com/ipfs/go-metrics-interface/pull/2)) + - update the counter interface to match Prometheus ([ipfs/go-metrics-interface#2](https://github.com/ipfs/go-metrics-interface/pull/2)) - github.com/ipfs/go-mfs: - Return node from FlushPath ([ipfs/go-mfs#72](https://github.com/ipfs/go-mfs/pull/72)) - Wire up context to FlushPath ([ipfs/go-mfs#70](https://github.com/ipfs/go-mfs/pull/70)) @@ -1349,7 +1349,7 @@ Second up, `ipfs ls` now has a new `--stream` flag. In IPFS, very large directories (e.g., Wikipedia) are split up into multiple chunks (shards) as there are too many entries to fit in a single block. Unfortunately, `ipfs ls` buffers the _entire_ file list in memory and then sorts it. This means that -`ipfs ls /ipfs/QmXoypizjW3WknFiJnKLwHCnL72vedxjQkDDP1mXWo6uco/wiki` (wikipedia) +`ipfs ls /ipfs/QmXoypizjW3WknFiJnKLwHCnL72vedxjQkDDP1mXWo6uco/wiki` (Wikipedia) will take a _very_ long time to return anything (it'll also use quite a bit of memory). @@ -1541,7 +1541,7 @@ The next steps are: - [CORS] Bubble go-ipfs-cmds 2.0.10 - Updates CORS library ([ipfs/go-ipfs#5919](https://github.com/ipfs/go-ipfs/pull/5919)) - reduce verbosity of daemon start ([ipfs/go-ipfs#5904](https://github.com/ipfs/go-ipfs/pull/5904)) - feat: update to Web UI v2.3.2 ([ipfs/go-ipfs#5899](https://github.com/ipfs/go-ipfs/pull/5899)) - - CoreAPI: Don't panic when testing incomplete implementions ([ipfs/go-ipfs#5900](https://github.com/ipfs/go-ipfs/pull/5900)) + - CoreAPI: Don't panic when testing incomplete implementations ([ipfs/go-ipfs#5900](https://github.com/ipfs/go-ipfs/pull/5900)) - gateway: fix CORs headers ([ipfs/go-ipfs#5893](https://github.com/ipfs/go-ipfs/pull/5893)) - Local Gateway option ([ipfs/go-ipfs#5649](https://github.com/ipfs/go-ipfs/pull/5649)) - Show hash on gateway ([ipfs/go-ipfs#5830](https://github.com/ipfs/go-ipfs/pull/5830)) @@ -1590,7 +1590,7 @@ The next steps are: - cmds/bitswap: sort wantlist ([ipfs/go-ipfs#5759](https://github.com/ipfs/go-ipfs/pull/5759)) - cmds/update: use new cmds lib ([ipfs/go-ipfs#5730](https://github.com/ipfs/go-ipfs/pull/5730)) - cmds/file: use new cmds lib ([ipfs/go-ipfs#5756](https://github.com/ipfs/go-ipfs/pull/5756)) - - cmds: remove reduntant func ([ipfs/go-ipfs#5750](https://github.com/ipfs/go-ipfs/pull/5750)) + - cmds: remove redundant func ([ipfs/go-ipfs#5750](https://github.com/ipfs/go-ipfs/pull/5750)) - commands/refs: use new cmds ([ipfs/go-ipfs#5679](https://github.com/ipfs/go-ipfs/pull/5679)) - commands/pin: use new cmds lib ([ipfs/go-ipfs#5674](https://github.com/ipfs/go-ipfs/pull/5674)) - commands/boostrap: use new cmds ([ipfs/go-ipfs#5678](https://github.com/ipfs/go-ipfs/pull/5678)) @@ -1656,7 +1656,7 @@ The next steps are: - add codecs for Dash blocks, tx ([ipfs/go-cid#78](https://github.com/ipfs/go-cid/pull/78)) - github.com/ipfs/go-cidutil: - Fix Travis CI to run all tests. ([ipfs/go-cidutil#11](https://github.com/ipfs/go-cidutil/pull/11)) - - Changes needed for `--cid-base` option in go-ipfs (simplified vesion) ([ipfs/go-cidutil#10](https://github.com/ipfs/go-cidutil/pull/10)) + - Changes needed for `--cid-base` option in go-ipfs (simplified version) ([ipfs/go-cidutil#10](https://github.com/ipfs/go-cidutil/pull/10)) - add a utility method for sorting CID slices ([ipfs/go-cidutil#5](https://github.com/ipfs/go-cidutil/pull/5)) - github.com/libp2p/go-conn-security: - fix link to usage example in README ([libp2p/go-conn-security#4](https://github.com/libp2p/go-conn-security/pull/4)) @@ -1844,7 +1844,7 @@ The next steps are: - fix a fetch deadlock on error ([ipfs/go-merkledag#21](https://github.com/ipfs/go-merkledag/pull/21)) - Wait for all go routines to finish before function returns ([ipfs/go-merkledag#19](https://github.com/ipfs/go-merkledag/pull/19)) - github.com/ipfs/go-metrics-prometheus: - - use prometheus instead of gxed ([ipfs/go-metrics-prometheus#3](https://github.com/ipfs/go-metrics-prometheus/pull/3)) + - use Prometheus instead of gxed ([ipfs/go-metrics-prometheus#3](https://github.com/ipfs/go-metrics-prometheus/pull/3)) - github.com/ipfs/go-mfs: - fix(mv): dst filename error ([ipfs/go-mfs#62](https://github.com/ipfs/go-mfs/pull/62)) - fix over-wait in WaitPub ([ipfs/go-mfs#53](https://github.com/ipfs/go-mfs/pull/53)) @@ -2096,7 +2096,7 @@ You can track progress in https://github.com/ipfs/go-ipfs/issues/4498 We introduced new path type which introduces distinction between IPLD and IPFS (unixfs) paths. From now on paths prefixed with `/ipld/` will always use IPLD link traversal and `/ipfs/` will use unixfs path resolver, which -takes things like shardnig into account. +takes things like sharding into account. Note that this is only initial support and there likely are some bugs in how the paths are handled internally, so consider this feature @@ -2203,7 +2203,7 @@ Fixes (i.e., users take note): - refactor(command): modify int to int64 ([ipfs/go-ipfs#5612](https://github.com/ipfs/go-ipfs/pull/5612)) - fix(core): ipns config RecordLifetime panic ([ipfs/go-ipfs#5648](https://github.com/ipfs/go-ipfs/pull/5648)) - simplify dag put and correctly take pin lock ([ipfs/go-ipfs#5667](https://github.com/ipfs/go-ipfs/pull/5667)) - - fix prometheus concurrent map write bug ([ipfs/go-ipfs#5706](https://github.com/ipfs/go-ipfs/pull/5706)) + - fix Prometheus concurrent map write bug ([ipfs/go-ipfs#5706](https://github.com/ipfs/go-ipfs/pull/5706)) Regressions Fixes (fixes for bugs introduced since the last release): - namesys: properly attach path in name.Resolve ([ipfs/go-ipfs#5660](https://github.com/ipfs/go-ipfs/pull/5660)) @@ -2291,7 +2291,7 @@ Internal: - fix: maketarball.sh for OSX ([ipfs/go-ipfs#5575](https://github.com/ipfs/go-ipfs/pull/5575)) - test the correct return value when checking directory size ([ipfs/go-ipfs#5580](https://github.com/ipfs/go-ipfs/pull/5580)) - coreapi unixfs: remove Cat ([ipfs/go-ipfs#5574](https://github.com/ipfs/go-ipfs/pull/5574)) - - Explicitally use BufferedDAG after removing Batch from importers ([ipfs/go-ipfs#5626](https://github.com/ipfs/go-ipfs/pull/5626)) + - Explicitly use BufferedDAG after removing Batch from importers ([ipfs/go-ipfs#5626](https://github.com/ipfs/go-ipfs/pull/5626)) Cleanup: - Fix some weird code in core/coreunix/add.go ([ipfs/go-ipfs#5354](https://github.com/ipfs/go-ipfs/pull/5354)) @@ -2337,7 +2337,7 @@ github.com/ipfs/go-datastore github.com/ipfs/go-cid - Add tests for Set type ([ipfs/go-cid#63](https://github.com/ipfs/go-cid/pull/63)) - Create new Builder interface for creating CIDs. ([ipfs/go-cid#53](https://github.com/ipfs/go-cid/pull/53)) - - cid-fmt Enhancments ([ipfs/go-cid#61](https://github.com/ipfs/go-cid/pull/61)) + - cid-fmt enhancements ([ipfs/go-cid#61](https://github.com/ipfs/go-cid/pull/61)) - add String benchmark ([ipfs/go-cid#44](https://github.com/ipfs/go-cid/pull/44)) - add a streaming CID set ([ipfs/go-cid#67](https://github.com/ipfs/go-cid/pull/67)) - Extract non-core functionality from go-cid into go-cidutil ([ipfs/go-cid#69](https://github.com/ipfs/go-cid/pull/69)) @@ -2362,7 +2362,7 @@ github.com/ipfs/go-metrics-prometheus - use an existing metric when it has already been registered ([ipfs/go-metrics-prometheus#1](https://github.com/ipfs/go-metrics-prometheus/pull/1)) github.com/ipfs/go-metrics-interface - - update the counter interface to match prometheus ([ipfs/go-metrics-interface#2](https://github.com/ipfs/go-metrics-interface/pull/2)) + - update the counter interface to match Prometheus ([ipfs/go-metrics-interface#2](https://github.com/ipfs/go-metrics-interface/pull/2)) github.com/ipfs/go-ipld-format - add copy dagservice function ([ipfs/go-ipld-format#41](https://github.com/ipfs/go-ipld-format/pull/41)) @@ -2624,18 +2624,18 @@ add it yourself, but doing so was not easy). With this, ipfs can ingest and operate over Git repositories and commit graphs directly. For more information on this, see [the go-ipld-git repo](https://github.com/ipfs/go-ipld-git). -Finally, we've included many smaller bugfixes, refactorings, improved +Finally, we've included many smaller bug fixes, refactorings, improved documentation, and a good bit more. For the full details, see the changelog below. ## v0.4.16-rc3 2018-07-09 -- Bugfixes +- Bug fixes - Fix dht commands when ipns over pubsub is enabled ([ipfs/go-ipfs#5200](https://github.com/ipfs/go-ipfs/pull/5200)) - Fix content routing when ipns over pubsub is enabled ([ipfs/go-ipfs#5200](https://github.com/ipfs/go-ipfs/pull/5200)) - Correctly handle multi-hop dnslink resolution ([ipfs/go-ipfs#5202](https://github.com/ipfs/go-ipfs/pull/5202)) ## v0.4.16-rc2 2018-07-05 -- Bugfixes +- Bug fixes - Fix usage of file name vs path name in adder ([ipfs/go-ipfs#5167](https://github.com/ipfs/go-ipfs/pull/5167)) - Fix `ipfs update` working with migrations ([ipfs/go-ipfs#5194](https://github.com/ipfs/go-ipfs/pull/5194)) - Documentation @@ -2656,7 +2656,7 @@ below. - Add package overview comments to coreapi ([ipfs/go-ipfs#5108](https://github.com/ipfs/go-ipfs/pull/5108)) - Add README to docs folder ([ipfs/go-ipfs#5095](https://github.com/ipfs/go-ipfs/pull/5095)) - Add system requirements to README ([ipfs/go-ipfs#5137](https://github.com/ipfs/go-ipfs/pull/5137)) -- Bugfixes +- Bug fixes - Fix goroutine leak in pin verify ([ipfs/go-ipfs#5011](https://github.com/ipfs/go-ipfs/pull/5011)) - Fix commit string in version ([ipfs/go-ipfs#4982](https://github.com/ipfs/go-ipfs/pull/4982)) - Fix `key rename` command output error ([ipfs/go-ipfs#4962](https://github.com/ipfs/go-ipfs/pull/4962)) @@ -2688,7 +2688,7 @@ below. - Disable the MacOS tests in jenkins ([ipfs/go-ipfs#5119](https://github.com/ipfs/go-ipfs/pull/5119)) - Make republisher test robust against timing issues ([ipfs/go-ipfs#5125](https://github.com/ipfs/go-ipfs/pull/5125)) - Archive sharness trash dirs in jenkins ([ipfs/go-ipfs#5071](https://github.com/ipfs/go-ipfs/pull/5071)) - - Fixup DHT sharness tests ([ipfs/go-ipfs#5114](https://github.com/ipfs/go-ipfs/pull/5114)) + - Fix up DHT sharness tests ([ipfs/go-ipfs#5114](https://github.com/ipfs/go-ipfs/pull/5114)) - Dependencies - Update go-ipld-git to fix mergetag resolving ([ipfs/go-ipfs#4988](https://github.com/ipfs/go-ipfs/pull/4988)) - Fix duplicate /x/sys imports ([ipfs/go-ipfs#5068](https://github.com/ipfs/go-ipfs/pull/5068)) @@ -2757,7 +2757,7 @@ access. - Add docs for --profile=lowpower ([ipfs/go-ipfs#4970](https://github.com/ipfs/go-ipfs/pull/4970)) - Improve Windows build documentation ([ipfs/go-ipfs#4691](https://github.com/ipfs/go-ipfs/pull/4691)) -- Bugfixes +- Bug fixes - Check CIDs in base case when diffing nodes ([ipfs/go-ipfs#4767](https://github.com/ipfs/go-ipfs/pull/4767)) - Support for CIDv1 with custom mhtype in `ipfs block put` ([ipfs/go-ipfs#4563](https://github.com/ipfs/go-ipfs/pull/4563)) - Clean path in DagArchive ([ipfs/go-ipfs#4743](https://github.com/ipfs/go-ipfs/pull/4743)) @@ -2806,7 +2806,7 @@ access. ## v0.4.14 2018-03-22 -Ipfs 0.4.14 is a big release with a large number of improvements and bugfixes. +Ipfs 0.4.14 is a big release with a large number of improvements and bug fixes. It is also the first release of 2018, and our first release in over three months. The release took longer than expected due to our refactoring and extracting of our commands library. This refactor had two stages. The first @@ -2920,7 +2920,7 @@ remove them before updating. - Add godocs for path module ([ipfs/go-ipfs#4689](https://github.com/ipfs/go-ipfs/pull/4689)) - Add godocs for pin module ([ipfs/go-ipfs#4696](https://github.com/ipfs/go-ipfs/pull/4696)) - Update link to filestore experimental status ([ipfs/go-ipfs#4557](https://github.com/ipfs/go-ipfs/pull/4557)) -- Bugfixes +- Bug fixes - Remove trailing slash in ipfs get paths, fixes #3729 ([ipfs/go-ipfs#4365](https://github.com/ipfs/go-ipfs/pull/4365)) - fix deadlock in bitswap sessions ([ipfs/go-ipfs#4407](https://github.com/ipfs/go-ipfs/pull/4407)) - Fix two race conditions (and possibly go routine leaks) in commands ([ipfs/go-ipfs#4406](https://github.com/ipfs/go-ipfs/pull/4406)) @@ -2973,7 +2973,7 @@ remove them before updating. Ipfs 0.4.13 is a patch release that fixes two high priority issues that were discovered in the 0.4.12 release. -Bugfixes: +Bug fixes: - Fix periodic bitswap deadlock ([ipfs/go-ipfs#4386](https://github.com/ipfs/go-ipfs/pull/4386)) - Fix badgerds crash on startup ([ipfs/go-ipfs#4384](https://github.com/ipfs/go-ipfs/pull/4384)) @@ -3037,7 +3037,7 @@ filed pull requests, and contributed in any other way to this release! - Add more info about `ipfs add` chunker option ([ipfs/go-ipfs#4306](https://github.com/ipfs/go-ipfs/pull/4306)) - Remove cruft in readme and mention discourse forum ([ipfs/go-ipfs#4345](https://github.com/ipfs/go-ipfs/pull/4345)) - Add note about updating before reporting issues ([ipfs/go-ipfs#4361](https://github.com/ipfs/go-ipfs/pull/4361)) -- Bugfixes +- Bug fixes - Fix FreeBSD build issues ([ipfs/go-ipfs#4275](https://github.com/ipfs/go-ipfs/pull/4275)) - Don't crash when Datastore.StorageMax is not defined ([ipfs/go-ipfs#4246](https://github.com/ipfs/go-ipfs/pull/4246)) - Do not call 'Connect' on NewStream in bitswap ([ipfs/go-ipfs#4317](https://github.com/ipfs/go-ipfs/pull/4317)) @@ -3176,7 +3176,7 @@ you. - Update release docs ([ipfs/go-ipfs#4165](https://github.com/ipfs/go-ipfs/pull/4165)) - Add documentation for datastore configs ([ipfs/go-ipfs#4223](https://github.com/ipfs/go-ipfs/pull/4223)) - General update and clean-up of docs ([ipfs/go-ipfs#4222](https://github.com/ipfs/go-ipfs/pull/4222)) -- Bugfixes +- Bug fixes - Fix shutdown check in t0023 ([ipfs/go-ipfs#3969](https://github.com/ipfs/go-ipfs/pull/3969)) - Fix pinning of unixfs sharded directories ([ipfs/go-ipfs#3975](https://github.com/ipfs/go-ipfs/pull/3975)) - Show escaped url in gateway 404 message ([ipfs/go-ipfs#4005](https://github.com/ipfs/go-ipfs/pull/4005)) @@ -3197,7 +3197,7 @@ you. ### v0.4.10 - 2017-06-27 Ipfs 0.4.10 is a patch release that contains several exciting new features, -bugfixes and general improvements. Including new commands, easier corruption +bug fixes and general improvements. Including new commands, easier corruption recovery, and a generally cleaner codebase. The `ipfs pin` command has two new subcommands, `verify` and `update`. `ipfs @@ -3258,7 +3258,7 @@ other requested improvements. See below for the full list of changes. - Change 'neccessary' to 'necessary' ([ipfs/go-ipfs#3941](https://github.com/ipfs/go-ipfs/pull/3941)) - README.md: add Nix to the linux package managers ([ipfs/go-ipfs#3939](https://github.com/ipfs/go-ipfs/pull/3939)) - More verbose errors in filestore ([ipfs/go-ipfs#3964](https://github.com/ipfs/go-ipfs/pull/3964)) -- Bugfixes +- Bug fixes - Fix typo in message when file size check fails ([ipfs/go-ipfs#3895](https://github.com/ipfs/go-ipfs/pull/3895)) - Clean up bitswap ledgers when disconnecting ([ipfs/go-ipfs#3437](https://github.com/ipfs/go-ipfs/pull/3437)) - Make odds of 'process added after close' panic less likely ([ipfs/go-ipfs#3940](https://github.com/ipfs/go-ipfs/pull/3940)) @@ -3270,7 +3270,7 @@ other requested improvements. See below for the full list of changes. ### v0.4.9 - 2017-04-30 -Ipfs 0.4.9 is a maintenance release that contains several useful bugfixes and +Ipfs 0.4.9 is a maintenance release that contains several useful bug fixes and improvements. Notably, `ipfs add` has gained the ability to select which CID version will be output. The common ipfs hash that looks like this: `QmRjNgF2mRLDT8AzCPsQbw1EYF2hDTFgfUmJokJPhCApYP` is a multihash. Multihashes @@ -3307,8 +3307,8 @@ Aside from the CID flag, there were many other changes as noted below: - Change issue template to use Severity instead of Priority ([ipfs/go-ipfs#3834](https://github.com/ipfs/go-ipfs/pull/3834)) - Fix link to commit hook script in contribute.md ([ipfs/go-ipfs#3863](https://github.com/ipfs/go-ipfs/pull/3863)) - Fix install_unsupported for openbsd, add docs ([ipfs/go-ipfs#3880](https://github.com/ipfs/go-ipfs/pull/3880)) -- Bugfixes - - Fix wanlist typo in prometheus metric name ([ipfs/go-ipfs#3841](https://github.com/ipfs/go-ipfs/pull/3841)) +- Bug fixes + - Fix wantlist typo in Prometheus metric name ([ipfs/go-ipfs#3841](https://github.com/ipfs/go-ipfs/pull/3841)) - Fix `make install` not using ldflags for git hash ([ipfs/go-ipfs#3838](https://github.com/ipfs/go-ipfs/pull/3838)) - Fix `make install` not installing dependencies ([ipfs/go-ipfs#3848](https://github.com/ipfs/go-ipfs/pull/3848)) - Fix erroneous Cache-Control: immutable on dir listings ([ipfs/go-ipfs#3870](https://github.com/ipfs/go-ipfs/pull/3870)) @@ -3323,11 +3323,11 @@ Aside from the CID flag, there were many other changes as noted below: ### v0.4.8 - 2017-03-29 -Ipfs 0.4.8 brings with it several improvements, bugfixes, documentation +Ipfs 0.4.8 brings with it several improvements, bug fixes, documentation improvements, and the long awaited directory sharding code. Currently, when too many items are added into a unixfs directory, the object -gets too large and you may experience issues. To pervent this problem, and +gets too large and you may experience issues. To prevent this problem, and generally make working really large directories more efficient, we have implemented a HAMT structure for unixfs. To enable this feature, run: ``` @@ -3357,7 +3357,7 @@ look at all the other cool things added in 0.4.8 below. - Improve 'name' and 'key' helptexts ([ipfs/go-ipfs#3806](https://github.com/ipfs/go-ipfs/pull/3806)) - Update link to paper in dev.md ([ipfs/go-ipfs#3812](https://github.com/ipfs/go-ipfs/pull/3812)) - Add test to enforce helptext on commands ([ipfs/go-ipfs#2648](https://github.com/ipfs/go-ipfs/pull/2648)) -- Bugfixes +- Bug fixes - Remove bloom filter check on Put call in blockstore ([ipfs/go-ipfs#3782](https://github.com/ipfs/go-ipfs/pull/3782)) - Re-add the GOPATH checking functionality ([ipfs/go-ipfs#3787](https://github.com/ipfs/go-ipfs/pull/3787)) - Use fsrepo.IsInitialized to test for initialization ([ipfs/go-ipfs#3805](https://github.com/ipfs/go-ipfs/pull/3805)) @@ -3397,7 +3397,7 @@ stream multiplexing protocol was available previously via the `--enable-mplex-experiment` daemon flag, but has now graduated to being 'less experimental' and no longer requires the flag to use it. -Aside from those, we have a good number of bugfixes, perf improvements and new +Aside from those, we have a good number of bug fixes, perf improvements and new tests. Heres a list of highlights: - Features @@ -3416,7 +3416,7 @@ tests. Heres a list of highlights: - Documentation - Add Arch Linux install instructions to readme ([ipfs/go-ipfs#3742](https://github.com/ipfs/go-ipfs/pull/3742)) - Improve release checklist document ([ipfs/go-ipfs#3717](https://github.com/ipfs/go-ipfs/pull/3717)) -- Bugfixes +- Bug fixes - Fix drive root parsing on windows ([ipfs/go-ipfs#3328](https://github.com/ipfs/go-ipfs/pull/3328)) - Fix panic in ipfs get when passing no parameters to API ([ipfs/go-ipfs#3768](https://github.com/ipfs/go-ipfs/pull/3768)) - Fix breakage of `ipfs pin add` api output ([ipfs/go-ipfs#3760](https://github.com/ipfs/go-ipfs/pull/3760)) @@ -3437,7 +3437,7 @@ tests. Heres a list of highlights: ### v0.4.6 - 2017-02-21 -Ipfs 0.4.6 contains several bugfixes related to migrations and also contains a +Ipfs 0.4.6 contains several bug fixes related to migrations and also contains a few other improvements to other parts of the codebase. Notably: - The default config will now contain some ipv6 addresses for bootstrap nodes. @@ -3454,7 +3454,7 @@ few other improvements to other parts of the codebase. Notably: - Documentation - Add the snap installation instructions ([ipfs/go-ipfs#3663](https://github.com/ipfs/go-ipfs/pull/3663)) - Add closed PRs, Issues throughput ([ipfs/go-ipfs#3602](https://github.com/ipfs/go-ipfs/pull/3602)) -- Bugfixes +- Bug fixes - Fix auto-migration on docker nodes ([ipfs/go-ipfs#3698](https://github.com/ipfs/go-ipfs/pull/3698)) - Update flatfs to v1.1.2, fixing directory fd issue ([ipfs/go-ipfs#3711](https://github.com/ipfs/go-ipfs/pull/3711)) - General Changes and Refactorings @@ -3529,7 +3529,7 @@ few other improvements to other parts of the codebase. Notably: - Fix issue where wantlist fullness wasn't included in messages ([ipfs/go-ipfs#3461](https://github.com/ipfs/go-ipfs/pull/3461)) - Only pass keys down newBlocks chan in bitswap ([ipfs/go-ipfs#3271](https://github.com/ipfs/go-ipfs/pull/3271)) -- Bugfixes +- Bug fixes - gateway: fix --writable flag ([ipfs/go-ipfs#3206](https://github.com/ipfs/go-ipfs/pull/3206)) - Fix relative seek in unixfs not expanding file properly ([ipfs/go-ipfs#3095](https://github.com/ipfs/go-ipfs/pull/3095)) - Update multicodec service names for ipfs services ([ipfs/go-ipfs#3132](https://github.com/ipfs/go-ipfs/pull/3132)) @@ -3676,7 +3676,7 @@ expected, but none was given: [ipfs/go-ipfs#3050](https://github.com/ipfs/go-ipf ## v0.4.3-rc2 - 2016-08-04 -This release includes bugfixes and fixes for regressions that were introduced +This release includes bug fixes and fixes for regressions that were introduced between 0.4.2 and 0.4.3-rc1. - Regressions @@ -3716,7 +3716,7 @@ This is the first Release Candidate. Unless there are vulnerabilities or regress - Content Providers are now stored on disk to gain savings on process memory. (@whyrusleeping, [ipfs/go-ipfs#2804](https://github.com/ipfs/go-ipfs/pull/2804), [ipfs/go-ipfs#2860](https://github.com/ipfs/go-ipfs/pull/2860)) - Migrations of the fs-repo (usually stored at `~/.ipfs`) now run automatically. If there's a TTY available, you'll get prompted when running `ipfs daemon`, and in addition you can use the `--migrate=true` or `--migrate=false` options to avoid the prompt. (@whyrusleeping, @lgierth, [ipfs/go-ipfs#2939](https://github.com/ipfs/go-ipfs/pull/2939)) - The internal naming of blocks in the blockstore has changed, which requires a migration of the fs-repo, from version 3 to 4. (@whyrusleeping, [ipfs/go-ipfs#2903](https://github.com/ipfs/go-ipfs/pull/2903)) - - We now automatically raise the file descriptor limit to 1024 if neccessary. (@whyrusleeping, [ipfs/go-ipfs#2884](https://github.com/ipfs/go-ipfs/pull/2884), [ipfs/go-ipfs#2891](https://github.com/ipfs/go-ipfs/pull/2891)) + - We now automatically raise the file descriptor limit to 1024 if necessary. (@whyrusleeping, [ipfs/go-ipfs#2884](https://github.com/ipfs/go-ipfs/pull/2884), [ipfs/go-ipfs#2891](https://github.com/ipfs/go-ipfs/pull/2891)) - After a long struggle with deadlocks and hanging connections, we've decided to disable the uTP transport by default for now. (@whyrusleeping, [ipfs/go-ipfs#2840](https://github.com/ipfs/go-ipfs/pull/2840), [ipfs/go-libp2p-transport@88244000](https://github.com/ipfs/go-libp2p-transport/commit/88244000f0ce8851ffcfbac746ebc0794b71d2a4)) - There is now documentation for the configuration options in `docs/config.md`. (@whyrusleeping, [ipfs/go-ipfs#2974](https://github.com/ipfs/go-ipfs/pull/2974)) - All commands now sanely handle the combination of stdin and optional flags in certain edge cases. (@lgierth, [ipfs/go-ipfs#2952](https://github.com/ipfs/go-ipfs/pull/2952)) @@ -3727,7 +3727,7 @@ This is the first Release Candidate. Unless there are vulnerabilities or regress - Add `Datastore.HashOnRead` option for verifying block hashes on read access. (@Kubuxu, [ipfs/go-ipfs#2904](https://github.com/ipfs/go-ipfs/pull/2904)) - Add `Datastore.BloomFilterSize` option for tuning the blockstore's new lookup bloom filter. (@Kubuxu, [ipfs/go-ipfs#2973](https://github.com/ipfs/go-ipfs/pull/2973)) -- Bugfixes +- Bug fixes - Fix publishing of local IPNS entries, and more. (@whyrusleeping, [ipfs/go-ipfs#2943](https://github.com/ipfs/go-ipfs/pull/2943)) - Fix progress bars in `ipfs add` and `ipfs get`. (@whyrusleeping, [ipfs/go-ipfs#2893](https://github.com/ipfs/go-ipfs/pull/2893), [ipfs/go-ipfs#2948](https://github.com/ipfs/go-ipfs/pull/2948)) @@ -3781,7 +3781,7 @@ This is the first Release Candidate. Unless there are vulnerabilities or regress - Consolidate `--verbose` description across commands. (@Kubuxu, [ipfs/go-ipfs#2746](https://github.com/ipfs/go-ipfs/pull/2746)) - Allow setting position of default values in command option descriptions. (@Kubuxu, [ipfs/go-ipfs#2744](https://github.com/ipfs/go-ipfs/pull/2744)) - Set explicit default values for boolean command options. (@RichardLitt, [ipfs/go-ipfs#2657](https://github.com/ipfs/go-ipfs/pull/2657)) - - Autogenerate command synopsises. (@Kubuxu, [ipfs/go-ipfs#2785](https://github.com/ipfs/go-ipfs/pull/2785)) + - Autogenerate command synopses. (@Kubuxu, [ipfs/go-ipfs#2785](https://github.com/ipfs/go-ipfs/pull/2785)) - Fix and improve lots of documentation. (@RichardLitt, [ipfs/go-ipfs#2741](https://github.com/ipfs/go-ipfs/pull/2741), [ipfs/go-ipfs#2781](https://github.com/ipfs/go-ipfs/pull/2781)) - Improve command descriptions to fit a width of 78 characters. (@RichardLitt, [ipfs/go-ipfs#2779](https://github.com/ipfs/go-ipfs/pull/2779), [ipfs/go-ipfs#2780](https://github.com/ipfs/go-ipfs/pull/2780), [ipfs/go-ipfs#2782](https://github.com/ipfs/go-ipfs/pull/2782)) - Fix filename conflict in the debugging guide. (@Kubuxu, [ipfs/go-ipfs#2752](https://github.com/ipfs/go-ipfs/pull/2752)) @@ -3843,7 +3843,7 @@ There are also a few other nice improvements. * Removals * Remove -f option from `ipfs init` command. (@whyrusleeping) -* Bugfixes +* Bug fixes * Fix `ipfs object patch` argument handling and validation. (@jbenet) * Fix `ipfs config edit` command by running it client-side. (@Kubuxu) * Set default value for `ipfs refs` arguments. (@richardlitt) @@ -3859,7 +3859,7 @@ There are also a few other nice improvements. * Use gx for iptb. (@chriscool) * Update gx and gx-go. (@chriscool) * Make blocks.Block an interface. (@kevina) - * Silence check for Docker existance. (@chriscool) + * Silence check for Docker existence. (@chriscool) * Add dist_get script for fetching tools from dist.ipfs.tech. (@whyrusleeping) * Add proper defaults to all `ipfs` commands. (@richardlitt) * Remove dead `count` option from `ipfs pin ls`. (@richardlitt) @@ -3892,12 +3892,12 @@ hang bugfix that was shipped in the 0.4.0 release. * Fix package manifest fields (@lgierth) * remove incfusever dead-code (@whyrusleeping) * remove a ton of unused godeps (@whyrusleeping) - * metrics: add prometheus back (@lgierth) + * metrics: add Prometheus back (@lgierth) * clean up dead code and config fields (@whyrusleeping) * Add log events when blocks are added/removed from the blockstore (@michealmure) * repo: don't create logs directory, not used any longer (@lgierth) -* Bugfixes +* Bug fixes * fixed ipfs name resolve --local multihash error (@pfista) * ipfs patch commands won't return null links field anymore (@whyrusleeping) * Make non recursive resolve print the result (@Kubuxu) @@ -3927,7 +3927,7 @@ hang bugfix that was shipped in the 0.4.0 release. ## v0.4.0 - 2016-04-05 -This is a major release with plenty of new features and bugfixes. +This is a major release with plenty of new features and bug fixes. It also includes breaking changes which make it incompatible with v0.3.x on the networking layer. diff --git a/docs/changelogs/v0.5.md b/docs/changelogs/v0.5.md index 0fa488845..dd154a6b4 100644 --- a/docs/changelogs/v0.5.md +++ b/docs/changelogs/v0.5.md @@ -564,7 +564,7 @@ As usual, this release contains several Windows specific fixes and improvements: - fix: update the dht to fix yggdrasil ([ipfs/go-ipfs#7186](https://github.com/ipfs/go-ipfs/pull/7186)) - Choose architecture when download tini into docker container ([ipfs/go-ipfs#7187](https://github.com/ipfs/go-ipfs/pull/7187)) - Fix typos and cleanup ([ipfs/go-ipfs#7181](https://github.com/ipfs/go-ipfs/pull/7181)) - - Fixtypos ([ipfs/go-ipfs#7180](https://github.com/ipfs/go-ipfs/pull/7180)) + - Fix typos ([ipfs/go-ipfs#7180](https://github.com/ipfs/go-ipfs/pull/7180)) - feat: webui 2.7.5 ([ipfs/go-ipfs#7176](https://github.com/ipfs/go-ipfs/pull/7176)) - integration test for the dual dht ([ipfs/go-ipfs#7151](https://github.com/ipfs/go-ipfs/pull/7151)) - fix: subdomain redirect for dir CIDs ([ipfs/go-ipfs#7165](https://github.com/ipfs/go-ipfs/pull/7165)) @@ -640,7 +640,7 @@ As usual, this release contains several Windows specific fixes and improvements: - test(sharness): fix typo ([ipfs/go-ipfs#6835](https://github.com/ipfs/go-ipfs/pull/6835)) - test: E2E tests against ipfs-webui HEAD ([ipfs/go-ipfs#6825](https://github.com/ipfs/go-ipfs/pull/6825)) - mkreleaslog: improve edge-cases ([ipfs/go-ipfs#6833](https://github.com/ipfs/go-ipfs/pull/6833)) - - fix: dont fail to collect profiles if no ipfs bin ([ipfs/go-ipfs#6829](https://github.com/ipfs/go-ipfs/pull/6829)) + - fix: don't fail to collect profiles if no ipfs bin ([ipfs/go-ipfs#6829](https://github.com/ipfs/go-ipfs/pull/6829)) - update dockerfile and use openssl ([ipfs/go-ipfs#6828](https://github.com/ipfs/go-ipfs/pull/6828)) - docs: define Gateway.PathPrefixes ([ipfs/go-ipfs#6826](https://github.com/ipfs/go-ipfs/pull/6826)) - fix(badgerds): turn off sync writes by default ([ipfs/go-ipfs#6819](https://github.com/ipfs/go-ipfs/pull/6819)) @@ -661,7 +661,7 @@ As usual, this release contains several Windows specific fixes and improvements: - extract the pinner to go-ipfs-pinner and dagutils into go-merkledag ([ipfs/go-ipfs#6771](https://github.com/ipfs/go-ipfs/pull/6771)) - fix #2203: omit the charset attribute when Content-Type is text/html ([ipfs/go-ipfs#6743](https://github.com/ipfs/go-ipfs/pull/6743)) - Pin ls traverses all indirect pins ([ipfs/go-ipfs#6705](https://github.com/ipfs/go-ipfs/pull/6705)) - - fix: ignore nonexistant when force rm ([ipfs/go-ipfs#6773](https://github.com/ipfs/go-ipfs/pull/6773)) + - fix: ignore nonexistent when force rm ([ipfs/go-ipfs#6773](https://github.com/ipfs/go-ipfs/pull/6773)) - introduce IpfsNode Plugin ([ipfs/go-ipfs#6719](https://github.com/ipfs/go-ipfs/pull/6719)) - improve documentation and fix dht put bug ([ipfs/go-ipfs#6750](https://github.com/ipfs/go-ipfs/pull/6750)) - Adding alias for `ipfs repo stat`. ([ipfs/go-ipfs#6769](https://github.com/ipfs/go-ipfs/pull/6769)) @@ -673,7 +673,7 @@ As usual, this release contains several Windows specific fixes and improvements: - Add high-level go-ipfs architecture diagram ([ipfs/go-ipfs#6727](https://github.com/ipfs/go-ipfs/pull/6727)) - docs: remove extra ) on the example README ([ipfs/go-ipfs#6733](https://github.com/ipfs/go-ipfs/pull/6733)) - update maintainer label ([ipfs/go-ipfs#6735](https://github.com/ipfs/go-ipfs/pull/6735)) - - ipfs namespace is now being provided to prometheus ([ipfs/go-ipfs#6643](https://github.com/ipfs/go-ipfs/pull/6643)) + - ipfs namespace is now being provided to Prometheus ([ipfs/go-ipfs#6643](https://github.com/ipfs/go-ipfs/pull/6643)) - feat: web ui 2.5.8 ([ipfs/go-ipfs#6718](https://github.com/ipfs/go-ipfs/pull/6718)) - docs: add connmgr to config.md toc ([ipfs/go-ipfs#6712](https://github.com/ipfs/go-ipfs/pull/6712)) - feat: web ui 2.5.7 ([ipfs/go-ipfs#6707](https://github.com/ipfs/go-ipfs/pull/6707)) @@ -815,7 +815,7 @@ As usual, this release contains several Windows specific fixes and improvements: - Feat: Track Session Peer Latency More Accurately ([ipfs/go-bitswap#149](https://github.com/ipfs/go-bitswap/pull/149)) - ci(circleci): add benchmark comparisons ([ipfs/go-bitswap#147](https://github.com/ipfs/go-bitswap/pull/147)) - aggressively free memory ([ipfs/go-bitswap#143](https://github.com/ipfs/go-bitswap/pull/143)) - - Enchanced logging for bitswap ([ipfs/go-bitswap#137](https://github.com/ipfs/go-bitswap/pull/137)) + - Enhanced logging for bitswap ([ipfs/go-bitswap#137](https://github.com/ipfs/go-bitswap/pull/137)) - fix: rand.Intn(0) panics ([ipfs/go-bitswap#144](https://github.com/ipfs/go-bitswap/pull/144)) - fix some naming nits and broadcast on search ([ipfs/go-bitswap#139](https://github.com/ipfs/go-bitswap/pull/139)) - feat(sessions): add rebroadcasting, search backoff ([ipfs/go-bitswap#133](https://github.com/ipfs/go-bitswap/pull/133)) @@ -1075,7 +1075,7 @@ As usual, this release contains several Windows specific fixes and improvements: - fix: optimize isRelay ([libp2p/go-libp2p-kad-dht#585](https://github.com/libp2p/go-libp2p-kad-dht/pull/585)) - feat: expose WANActive ([libp2p/go-libp2p-kad-dht#580](https://github.com/libp2p/go-libp2p-kad-dht/pull/580)) - fix: improve error handling in dual dht ([libp2p/go-libp2p-kad-dht#582](https://github.com/libp2p/go-libp2p-kad-dht/pull/582)) - - fix: dedup addresses ([libp2p/go-libp2p-kad-dht#581](https://github.com/libp2p/go-libp2p-kad-dht/pull/581)) + - fix: deduplicate addresses ([libp2p/go-libp2p-kad-dht#581](https://github.com/libp2p/go-libp2p-kad-dht/pull/581)) - Fix bug in periodic peer pinging ([libp2p/go-libp2p-kad-dht#579](https://github.com/libp2p/go-libp2p-kad-dht/pull/579)) - Dual DHT scaffold ([libp2p/go-libp2p-kad-dht#570](https://github.com/libp2p/go-libp2p-kad-dht/pull/570)) - fix: linting fixes ([libp2p/go-libp2p-kad-dht#578](https://github.com/libp2p/go-libp2p-kad-dht/pull/578)) diff --git a/docs/changelogs/v0.7.md b/docs/changelogs/v0.7.md index f962a6800..0160916ba 100644 --- a/docs/changelogs/v0.7.md +++ b/docs/changelogs/v0.7.md @@ -76,7 +76,7 @@ The scripts in https://github.com/ipfs/go-ipfs-example-plugin have been updated - fix: ipfs pin ls - ignore pins that have errors ([ipfs/go-ipfs#7612](https://github.com/ipfs/go-ipfs/pull/7612)) - docs(config): fix Peering header ([ipfs/go-ipfs#7623](https://github.com/ipfs/go-ipfs/pull/7623)) - sharness: use dnsaddr example in ipfs p2p command tests ([ipfs/go-ipfs#7620](https://github.com/ipfs/go-ipfs/pull/7620)) - - fix(key): dont allow backup key to be named 'self' ([ipfs/go-ipfs#7615](https://github.com/ipfs/go-ipfs/pull/7615)) + - fix(key): don't allow backup key to be named 'self' ([ipfs/go-ipfs#7615](https://github.com/ipfs/go-ipfs/pull/7615)) - [BOUNTY] Directory page UI improvements ([ipfs/go-ipfs#7536](https://github.com/ipfs/go-ipfs/pull/7536)) - fix: make assets deterministic ([ipfs/go-ipfs#7609](https://github.com/ipfs/go-ipfs/pull/7609)) - use ed25519 keys by default ([ipfs/go-ipfs#7579](https://github.com/ipfs/go-ipfs/pull/7579)) @@ -157,7 +157,7 @@ The scripts in https://github.com/ipfs/go-ipfs-example-plugin have been updated - github.com/ipfs/go-graphsync (v0.0.5 -> v0.1.1): - docs(CHANGELOG): update for v0.1.1 - docs(CHANGELOG): update for v0.1.0 release ([ipfs/go-graphsync#84](https://github.com/ipfs/go-graphsync/pull/84)) - - Dedup by key extension (#83) ([ipfs/go-graphsync#83](https://github.com/ipfs/go-graphsync/pull/83)) + - Deduplicate by key extension (#83) ([ipfs/go-graphsync#83](https://github.com/ipfs/go-graphsync/pull/83)) - Release infrastructure (#81) ([ipfs/go-graphsync#81](https://github.com/ipfs/go-graphsync/pull/81)) - feat(persistenceoptions): add unregister ability (#80) ([ipfs/go-graphsync#80](https://github.com/ipfs/go-graphsync/pull/80)) - fix(message): regen protobuf code (#79) ([ipfs/go-graphsync#79](https://github.com/ipfs/go-graphsync/pull/79)) @@ -212,7 +212,7 @@ The scripts in https://github.com/ipfs/go-ipfs-example-plugin have been updated - Merge branch 'assembler-upgrade-to-codecs' - Path clarifications ([ipld/go-ipld-prime#47](https://github.com/ipld/go-ipld-prime/pull/47)) - Merge branch 'research-admissions' - - Add a typed link node to allow traversal with code gen'd builders across links ([ipld/go-ipld-prime#41](https://github.com/ipld/go-ipld-prime/pull/41)) + - Add a typed link node to allow traversal with code generated builders across links ([ipld/go-ipld-prime#41](https://github.com/ipld/go-ipld-prime/pull/41)) - Merge branch 'research-admissions' - Library updates. - Feat/add code gen disclaimer ([ipld/go-ipld-prime#39](https://github.com/ipld/go-ipld-prime/pull/39)) @@ -276,7 +276,7 @@ The scripts in https://github.com/ipfs/go-ipfs-example-plugin have been updated - github.com/libp2p/go-libp2p-pubsub (v0.3.1 -> v0.3.5): - regenerate protobufs (#381) ([libp2p/go-libp2p-pubsub#381](https://github.com/libp2p/go-libp2p-pubsub/pull/381)) - track validation time - - fullfill promise as soon as a message begins validation + - fulfill promise as soon as a message begins validation - don't apply penalty in self origin rejections - add behaviour penalty threshold - Add String() method to Topic. diff --git a/docs/changelogs/v0.8.md b/docs/changelogs/v0.8.md index fc5e61f51..7f4e1d759 100644 --- a/docs/changelogs/v0.8.md +++ b/docs/changelogs/v0.8.md @@ -128,7 +128,7 @@ Go 1.15 (the latest version of Go) [no longer supports](https://github.com/golan - Response Assembler Refactor (#138) ([ipfs/go-graphsync#138](https://github.com/ipfs/go-graphsync/pull/138)) - Add error listener on receiver (#136) ([ipfs/go-graphsync#136](https://github.com/ipfs/go-graphsync/pull/136)) - Run testplan on in CI (#137) ([ipfs/go-graphsync#137](https://github.com/ipfs/go-graphsync/pull/137)) - - fix(responsemanager): fix network error propogation (#133) ([ipfs/go-graphsync#133](https://github.com/ipfs/go-graphsync/pull/133)) + - fix(responsemanager): fix network error propagation (#133) ([ipfs/go-graphsync#133](https://github.com/ipfs/go-graphsync/pull/133)) - testground test for graphsync (#132) ([ipfs/go-graphsync#132](https://github.com/ipfs/go-graphsync/pull/132)) - docs(CHANGELOG): update for v0.5.2 ([ipfs/go-graphsync#130](https://github.com/ipfs/go-graphsync/pull/130)) - RegisterNetworkErrorListener should fire when there's an error connecting to the peer (#127) ([ipfs/go-graphsync#127](https://github.com/ipfs/go-graphsync/pull/127)) @@ -285,7 +285,7 @@ Go 1.15 (the latest version of Go) [no longer supports](https://github.com/golan - add support for priority topic delivery weights - tweak duplicate/reject weights - decay global counters after 2 min - - decouple global coutner decay from source counter decay + - decouple global counter decay from source counter decay - add warning for failure to parse IP out of remote multiaddr - more docs - configure the peer gater using a parameter object, docs and stuff diff --git a/docs/changelogs/v0.9.md b/docs/changelogs/v0.9.md index e210c7c24..7289adde7 100644 --- a/docs/changelogs/v0.9.md +++ b/docs/changelogs/v0.9.md @@ -209,7 +209,7 @@ SECIO was deprecated and turned off by default given the prevalence of TLS and N - fix(gw): remove hardcoded hostnames ([ipfs/go-ipfs#8069](https://github.com/ipfs/go-ipfs/pull/8069)) - Fix transposed words in docs/config.md ([ipfs/go-ipfs#8051](https://github.com/ipfs/go-ipfs/pull/8051)) - fix: update root help ([ipfs/go-ipfs#8052](https://github.com/ipfs/go-ipfs/pull/8052)) - - chore: dont docker tag rc as latest ([ipfs/go-ipfs#8055](https://github.com/ipfs/go-ipfs/pull/8055)) + - chore: don't docker tag rc as latest ([ipfs/go-ipfs#8055](https://github.com/ipfs/go-ipfs/pull/8055)) - Add info to "pin rm" help about how to tell if pin is indirect ([ipfs/go-ipfs#8044](https://github.com/ipfs/go-ipfs/pull/8044)) - build(deps): bump contrib.go.opencensus.io/exporter/prometheus from 0.2.0 to 0.3.0 ([ipfs/go-ipfs#8020](https://github.com/ipfs/go-ipfs/pull/8020)) - fix(gw): remove use of Clear-Site-Data in subdomain router ([ipfs/go-ipfs#7890](https://github.com/ipfs/go-ipfs/pull/7890)) @@ -223,7 +223,7 @@ SECIO was deprecated and turned off by default given the prevalence of TLS and N - fix: return an error if repo verify is canceled ([ipfs/go-ipfs#7973](https://github.com/ipfs/go-ipfs/pull/7973)) - doc: document security fix policy ([ipfs/go-ipfs#7991](https://github.com/ipfs/go-ipfs/pull/7991)) - feat(gw): /ipfs/ipfs/{cid} → /ipfs/{cid} ([ipfs/go-ipfs#7930](https://github.com/ipfs/go-ipfs/pull/7930)) - - Fix: innacuracies in MFS command documentation. ([ipfs/go-ipfs#8001](https://github.com/ipfs/go-ipfs/pull/8001)) + - Fix: inaccuracies in MFS command documentation. ([ipfs/go-ipfs#8001](https://github.com/ipfs/go-ipfs/pull/8001)) - Feat: Re-import InitializeKeyspace code from go-namesys ([ipfs/go-ipfs#7984](https://github.com/ipfs/go-ipfs/pull/7984)) - revert registration of metrics against unexposed prom registry ([ipfs/go-ipfs#7986](https://github.com/ipfs/go-ipfs/pull/7986)) - Extract the namesys and the keystore submodules ([ipfs/go-ipfs#7925](https://github.com/ipfs/go-ipfs/pull/7925)) @@ -266,7 +266,7 @@ SECIO was deprecated and turned off by default given the prevalence of TLS and N - docs(architecture): update architecture docs (#154) ([ipfs/go-graphsync#154](https://github.com/ipfs/go-graphsync/pull/154)) - release v0.7.0 ([ipfs/go-graphsync#152](https://github.com/ipfs/go-graphsync/pull/152)) - chore: update deps (#151) ([ipfs/go-graphsync#151](https://github.com/ipfs/go-graphsync/pull/151)) - - Automatically record heap profiles in testplans (#147) ([ipfs/go-graphsync#147](https://github.com/ipfs/go-graphsync/pull/147)) + - Automatically record heap profiles in test plans (#147) ([ipfs/go-graphsync#147](https://github.com/ipfs/go-graphsync/pull/147)) - feat(deps): update go-ipld-prime v0.7.0 (#145) ([ipfs/go-graphsync#145](https://github.com/ipfs/go-graphsync/pull/145)) - Release/v0.6.0 ([ipfs/go-graphsync#144](https://github.com/ipfs/go-graphsync/pull/144)) - github.com/ipfs/go-ipfs-blockstore (v0.1.4 -> v0.1.6): @@ -360,7 +360,7 @@ SECIO was deprecated and turned off by default given the prevalence of TLS and N - node/gendemo: use the new code generator - Merge pull request #96 , originally known as ipld/cidlink-only-usable-as-ptr - Codec revamp ([ipld/go-ipld-prime#112](https://github.com/ipld/go-ipld-prime/pull/112)) - - Allow overriden types (#116) ([ipld/go-ipld-prime#116](https://github.com/ipld/go-ipld-prime/pull/116)) + - Allow overridden types (#116) ([ipld/go-ipld-prime#116](https://github.com/ipld/go-ipld-prime/pull/116)) - add import to ipld in ipldsch_types.go ([ipld/go-ipld-prime#115](https://github.com/ipld/go-ipld-prime/pull/115)) - Codegen output rearrange ([ipld/go-ipld-prime#105](https://github.com/ipld/go-ipld-prime/pull/105)) - Validate struct builder sufficiency ([ipld/go-ipld-prime#111](https://github.com/ipld/go-ipld-prime/pull/111)) @@ -540,7 +540,7 @@ SECIO was deprecated and turned off by default given the prevalence of TLS and N - improve string representation of timeout errors ([lucas-clemente/quic-go#3118](https://github.com/lucas-clemente/quic-go/pull/3118)) - fix flaky timeout test ([lucas-clemente/quic-go#3105](https://github.com/lucas-clemente/quic-go/pull/3105)) - fix calculation of the time for the next keep alive - - add a 0-RTT test with different connecton ID lengths ([lucas-clemente/quic-go#3098](https://github.com/lucas-clemente/quic-go/pull/3098)) + - add a 0-RTT test with different connection ID lengths ([lucas-clemente/quic-go#3098](https://github.com/lucas-clemente/quic-go/pull/3098)) - only run Ginkgo focus detection in staged files in pre-commit hook ([lucas-clemente/quic-go#3099](https://github.com/lucas-clemente/quic-go/pull/3099)) - allow 0-RTT when flow control windows are increased ([lucas-clemente/quic-go#3096](https://github.com/lucas-clemente/quic-go/pull/3096)) - improve the 0-RTT rejection integration test ([lucas-clemente/quic-go#3097](https://github.com/lucas-clemente/quic-go/pull/3097)) @@ -705,7 +705,7 @@ SECIO was deprecated and turned off by default given the prevalence of TLS and N - Implement simultaneous open extension ([multiformats/go-multistream#42](https://github.com/multiformats/go-multistream/pull/42)) - reduce the number of streams in the stress tests, fix error handling ([multiformats/go-multistream#54](https://github.com/multiformats/go-multistream/pull/54)) - github.com/whyrusleeping/cbor-gen (v0.0.0-20200710004633-5379fc63235d -> v0.0.0-20210219115102-f37d292932f2): - - feat: allow unmarshaling of struct with more fields than marshaled struct ([whyrusleeping/cbor-gen#50](https://github.com/whyrusleeping/cbor-gen/pull/50)) + - feat: allow unmarshalling of struct with more fields than marshaled struct ([whyrusleeping/cbor-gen#50](https://github.com/whyrusleeping/cbor-gen/pull/50)) - chore: add a license file ([whyrusleeping/cbor-gen#49](https://github.com/whyrusleeping/cbor-gen/pull/49)) - fix: enforce maxlen in ReadByteArray() ([whyrusleeping/cbor-gen#43](https://github.com/whyrusleeping/cbor-gen/pull/43)) - use unix nanoseconds for encoding Cbortime ([whyrusleeping/cbor-gen#41](https://github.com/whyrusleeping/cbor-gen/pull/41)) diff --git a/docs/config.md b/docs/config.md index e1188b23a..3bc558e88 100644 --- a/docs/config.md +++ b/docs/config.md @@ -914,7 +914,7 @@ based on the metrics `ipfs_bitswap_active_tasks`, `ipfs_bitswap_pending_tasks`, `ipfs_bitswap_pending_block_tasks` and `ipfs_bitswap_active_block_tasks` reported by bitswap. -These metrics can be accessed as the prometheus endpoint at `{Addresses.API}/debug/metrics/prometheus` (default: `http://127.0.0.1:5001/debug/metrics/prometheus`) +These metrics can be accessed as the Prometheus endpoint at `{Addresses.API}/debug/metrics/prometheus` (default: `http://127.0.0.1:5001/debug/metrics/prometheus`) The value of `ipfs_bitswap_active_tasks` is capped by `EngineTaskWorkerCount`. @@ -938,7 +938,7 @@ while `ipfs_bitswap_active_block_tasks` is at its maximum, there is indication t available block tasks is creating a bottleneck (either due to high-latency block operations, or due to high number of block operations per bitswap peer task). In such cases, try increasing the `EngineBlockstoreWorkerCount`. -If this adjustment still does not increase the throuput of the node, there might +If this adjustment still does not increase the throughput of the node, there might be hardware limitations like I/O or CPU. #### `Internal.Bitswap.TaskWorkerCount` diff --git a/docs/delegated-routing.md b/docs/delegated-routing.md index 9e2b9c48b..ff58aa8f9 100644 --- a/docs/delegated-routing.md +++ b/docs/delegated-routing.md @@ -393,8 +393,7 @@ As test fixtures we can add different use cases here and see how the configurati } } ``` - -Yaml representation for clarity: +YAML representation for clarity: ```yaml --- diff --git a/docs/experimental-features.md b/docs/experimental-features.md index cd85cb200..41e72f1df 100644 --- a/docs/experimental-features.md +++ b/docs/experimental-features.md @@ -390,7 +390,7 @@ We also support the use of protocol names of the form /x/$NAME/http where $NAME ## FUSE FUSE makes it possible to mount `/ipfs` and `/ipns` namespaces in your OS, -allowing argitrary apps access to IPFS using a subset of filesystem abstractions. +allowing arbitrary apps access to IPFS using a subset of filesystem abstractions. It is considered EXPERIMENTAL due to limited (and buggy) support on some platforms. diff --git a/docs/http-rpc-clients.md b/docs/http-rpc-clients.md index c011b98f7..b77c90a56 100644 --- a/docs/http-rpc-clients.md +++ b/docs/http-rpc-clients.md @@ -1,6 +1,6 @@ # HTTP/RPC Clients -Kubo provides official HTTP RPC (`/api/v0`) clients for selected lanaguages: +Kubo provides official HTTP RPC (`/api/v0`) clients for selected languages: - [js-kubo-rpc-client](https://github.com/ipfs/js-kubo-rpc-client) - Official JS client for talking to Kubo RPC over HTTP - [go-ipfs-api](https://github.com/ipfs/go-ipfs-api) - The go interface to ipfs's HTTP RPC - Follow https://github.com/ipfs/kubo/issues/9124 for coming changes. diff --git a/docs/libp2p-resource-management.md b/docs/libp2p-resource-management.md index f8a7e58d5..255ee6699 100644 --- a/docs/libp2p-resource-management.md +++ b/docs/libp2p-resource-management.md @@ -70,7 +70,7 @@ The reason these scopes are chosen is because: We are reliant on the system scope for protection here in the malicious case. The reason for having a peer scope is to protect against unintentional DoS attacks (e.g., bug in a peer which is causing it to "misbehave"). - In the unintional case, we want to make sure a "misbehaving" node doesn't consume more resources than necessary. + In the unintentional case, we want to make sure a "misbehaving" node doesn't consume more resources than necessary. Within these scopes, limits are just set on [memory](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#memory), @@ -120,13 +120,13 @@ As an example: > Protected from exceeding resource limits 2 times: "system: cannot reserve inbound connection: resource limit exceeded" -This means that there were 2 recent occurences where the libp2p resource manager prevented an inbound connection at the "system" [scope](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#resource-scopes). +This means that there were 2 recent occurrences where the libp2p resource manager prevented an inbound connection at the "system" [scope](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#resource-scopes). Specificaly the ``Swarm.ResourceMgr.Limits.System.ConnsInbound`` [active limit](#how-does-one-see-the-active-limits) was hit. This can be analyzed by viewing the limit with `ipfs swarm limit system` and comparing the usage with `ipfs swarm stats system`. `ConnsInbound` is likely close or at the limit value. -The simiplest way to identify all resources across all scopes that are close to exceeding their limit is with a command like `ipfs swarm stats --min-used-limit-perc=90 all`. +The simplest way to identify all resources across all scopes that are close to exceeding their limit is with a command like `ipfs swarm stats --min-used-limit-perc=90 all`. Sources: * [kubo resource manager logging](https://github.com/ipfs/kubo/blob/master/core/node/libp2p/rcmgr_logging.go) @@ -135,7 +135,7 @@ Sources: ### What are the "Application error 0x0 (remote) ... cannot reserve ..." messages? These are messages coming from a *remote* go-libp2p peer (likely another Kubo node) with the resource manager enabled on why it failed to establish a connection. -This can be confusing, but these `Application error 0x0 (remote) ... cannot reserve ...` messages can occur even if your local node has the resoure manager disabled. +This can be confusing, but these `Application error 0x0 (remote) ... cannot reserve ...` messages can occur even if your local node has the resource manager disabled. You can distinguish resource manager messages originating from your local node if they're from the `resourcemanager` / `libp2p/rcmgr_logging.go` logger or you see the string that is unique to Kubo (and not in go-libp2p): "Protected from exceeding resource limits". @@ -166,9 +166,10 @@ This can be observed with an empty [`Swarm.ResourceMgr.Limits`](https://github.c and then [seeing the active limits](#how-does-one-see-the-active-limits). ### How does one monitor libp2p resource usage? -For [monitoring libp2p resource usage](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#monitoring), -various `*rcmgr_*` metrics can be accessed as the prometheus endpoint at `{Addresses.API}/debug/metrics/prometheus` (default: `http://127.0.0.1:5001/debug/metrics/prometheus`). -There are also [pre-built Grafana dashboards](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager/obs/grafana-dashboards) that can be added to a Grafana instance. + +For [monitoring libp2p resource usage](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#monitoring), +various `*rcmgr_*` metrics can be accessed as the Prometheus endpoint at `{Addresses.API}/debug/metrics/prometheus` (default: `http://127.0.0.1:5001/debug/metrics/prometheus`). +There are also [pre-built Grafana dashboards](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager/obs/grafana-dashboards) that can be added to a Grafana instance. A textual view of current resource usage and a list of services, protocols, and peers can be obtained via `ipfs swarm stats --help` diff --git a/test/sharness/README.md b/test/sharness/README.md index 9358fcf9c..6ab8539da 100644 --- a/test/sharness/README.md +++ b/test/sharness/README.md @@ -46,7 +46,7 @@ $ ./t0010-basic-commands.sh -v -i When running sharness tests from main Makefile or when `test_sharness_deps` target is run dependencies for sharness -will be downloaded from its github repo and installed in a "lib/sharness" +will be downloaded from its GitHub repo and installed in a "lib/sharness" directory. Please do not change anything in the "lib/sharness" directory. diff --git a/test/sharness/t0054-dag-car-import-export-data/README.md b/test/sharness/t0054-dag-car-import-export-data/README.md index 2b6b5c00f..033f837a0 100644 --- a/test/sharness/t0054-dag-car-import-export-data/README.md +++ b/test/sharness/t0054-dag-car-import-export-data/README.md @@ -20,7 +20,7 @@ - versions identical to the above, but with a single "empty-block" root each ( in order to work around go-car not following the current "roots can be empty" spec ) - combined_naked_roots_genesis_and_128.car - - only the roots of `lotus_devnet_genesis.car` and `lotus_testnet_export_128.car`, to to be used in combination with the root-less parts to validate "transactional" pinning + - only the roots of `lotus_devnet_genesis.car` and `lotus_testnet_export_128.car`,to be used in combination with the root-less parts to validate "transactional" pinning - lotus_testnet_export_128_v2.car - lotus_devnet_genesis_v2.car From 4db6ae177215c15656183390514f004131254c71 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Wed, 22 Feb 2023 03:22:03 +0100 Subject: [PATCH 0475/1212] fix(gateway): return HTTP 500 on ErrResolveFailed (#9589) --- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- test/cli/gateway_test.go | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index ff040fdba..7c421a937 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.18 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/go-libipfs v0.6.0 + github.com/ipfs/go-libipfs v0.6.1-0.20230222011044-7b201415a176 github.com/ipfs/interface-go-ipfs-core v0.11.0 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.25.2-0.20230214091718-aef956be688d diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 0c1c2abf5..d83b0c507 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -568,8 +568,8 @@ github.com/ipfs/go-ipld-legacy v0.1.1 h1:BvD8PEuqwBHLTKqlGFTHSwrwFOMkVESEvwIYwR2 github.com/ipfs/go-ipld-legacy v0.1.1/go.mod h1:8AyKFCjgRPsQFf15ZQgDB8Din4DML/fOmKZkkFkrIEg= github.com/ipfs/go-ipns v0.3.0 h1:ai791nTgVo+zTuq2bLvEGmWP1M0A6kGTXUsgv/Yq67A= github.com/ipfs/go-ipns v0.3.0/go.mod h1:3cLT2rbvgPZGkHJoPO1YMJeh6LtkxopCkKFcio/wE24= -github.com/ipfs/go-libipfs v0.6.0 h1:3FuckAJEm+zdHbHbf6lAyk0QUzc45LsFcGw102oBCZM= -github.com/ipfs/go-libipfs v0.6.0/go.mod h1:UjjDIuehp2GzlNP0HEr5I9GfFT7zWgst+YfpUEIThtw= +github.com/ipfs/go-libipfs v0.6.1-0.20230222011044-7b201415a176 h1:QJvWxLRKucrAo7W2vLz5FA2iLKwW6WkHWn8AL8kXAUU= +github.com/ipfs/go-libipfs v0.6.1-0.20230222011044-7b201415a176/go.mod h1:UjjDIuehp2GzlNP0HEr5I9GfFT7zWgst+YfpUEIThtw= github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= github.com/ipfs/go-log v1.0.2/go.mod h1:1MNjMxe0u6xvJZgeqbJ8vdo2TKaGwZ1a0Bpza+sr2Sk= github.com/ipfs/go-log v1.0.3/go.mod h1:OsLySYkwIbiSUR/yBTdv1qPtcE4FW3WPWk/ewz9Ru+A= diff --git a/go.mod b/go.mod index aa5e1b379..a9634a22b 100644 --- a/go.mod +++ b/go.mod @@ -45,7 +45,7 @@ require ( github.com/ipfs/go-ipld-git v0.1.1 github.com/ipfs/go-ipld-legacy v0.1.1 github.com/ipfs/go-ipns v0.3.0 - github.com/ipfs/go-libipfs v0.6.0 + github.com/ipfs/go-libipfs v0.6.1-0.20230222011044-7b201415a176 github.com/ipfs/go-log v1.0.5 github.com/ipfs/go-log/v2 v2.5.1 github.com/ipfs/go-merkledag v0.9.0 diff --git a/go.sum b/go.sum index 818458b78..5a89b69af 100644 --- a/go.sum +++ b/go.sum @@ -590,8 +590,8 @@ github.com/ipfs/go-ipld-legacy v0.1.1 h1:BvD8PEuqwBHLTKqlGFTHSwrwFOMkVESEvwIYwR2 github.com/ipfs/go-ipld-legacy v0.1.1/go.mod h1:8AyKFCjgRPsQFf15ZQgDB8Din4DML/fOmKZkkFkrIEg= github.com/ipfs/go-ipns v0.3.0 h1:ai791nTgVo+zTuq2bLvEGmWP1M0A6kGTXUsgv/Yq67A= github.com/ipfs/go-ipns v0.3.0/go.mod h1:3cLT2rbvgPZGkHJoPO1YMJeh6LtkxopCkKFcio/wE24= -github.com/ipfs/go-libipfs v0.6.0 h1:3FuckAJEm+zdHbHbf6lAyk0QUzc45LsFcGw102oBCZM= -github.com/ipfs/go-libipfs v0.6.0/go.mod h1:UjjDIuehp2GzlNP0HEr5I9GfFT7zWgst+YfpUEIThtw= +github.com/ipfs/go-libipfs v0.6.1-0.20230222011044-7b201415a176 h1:QJvWxLRKucrAo7W2vLz5FA2iLKwW6WkHWn8AL8kXAUU= +github.com/ipfs/go-libipfs v0.6.1-0.20230222011044-7b201415a176/go.mod h1:UjjDIuehp2GzlNP0HEr5I9GfFT7zWgst+YfpUEIThtw= github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= github.com/ipfs/go-log v1.0.2/go.mod h1:1MNjMxe0u6xvJZgeqbJ8vdo2TKaGwZ1a0Bpza+sr2Sk= github.com/ipfs/go-log v1.0.3/go.mod h1:OsLySYkwIbiSUR/yBTdv1qPtcE4FW3WPWk/ewz9Ru+A= diff --git a/test/cli/gateway_test.go b/test/cli/gateway_test.go index 6e8ef516a..7139bef1b 100644 --- a/test/cli/gateway_test.go +++ b/test/cli/gateway_test.go @@ -469,7 +469,7 @@ func TestGateway(t *testing.T) { t.Run("not present IPNS key from node 1", func(t *testing.T) { t.Parallel() - assert.Equal(t, 400, node1.GatewayClient().Get("/ipns/"+node2.PeerID().String()).StatusCode) + assert.Equal(t, 500, node1.GatewayClient().Get("/ipns/"+node2.PeerID().String()).StatusCode) }) }) From 86da181f7f5ac430cdcf7a9aae194083cf82085d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Mur=C3=A9?= Date: Wed, 22 Feb 2023 16:56:59 +0100 Subject: [PATCH 0476/1212] feat(pinning): connect some missing go context (#9557) Co-authored-by: Henrique Dias --- core/coreapi/block.go | 4 +++- core/coreapi/dag.go | 11 ++++++++--- core/coreapi/object.go | 8 ++++++-- core/coreunix/add.go | 7 ++++++- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- 8 files changed, 29 insertions(+), 13 deletions(-) diff --git a/core/coreapi/block.go b/core/coreapi/block.go index 4f086ae86..450f06f3b 100644 --- a/core/coreapi/block.go +++ b/core/coreapi/block.go @@ -60,7 +60,9 @@ func (api *BlockAPI) Put(ctx context.Context, src io.Reader, opts ...caopts.Bloc } if settings.Pin { - api.pinning.PinWithMode(b.Cid(), pin.Recursive) + if err = api.pinning.PinWithMode(ctx, b.Cid(), pin.Recursive); err != nil { + return nil, err + } if err := api.pinning.Flush(ctx); err != nil { return nil, err } diff --git a/core/coreapi/dag.go b/core/coreapi/dag.go index 0f38fc4d5..b352a2d3f 100644 --- a/core/coreapi/dag.go +++ b/core/coreapi/dag.go @@ -7,9 +7,10 @@ import ( pin "github.com/ipfs/go-ipfs-pinner" ipld "github.com/ipfs/go-ipld-format" dag "github.com/ipfs/go-merkledag" - "github.com/ipfs/kubo/tracing" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" + + "github.com/ipfs/kubo/tracing" ) type dagAPI struct { @@ -29,7 +30,9 @@ func (adder *pinningAdder) Add(ctx context.Context, nd ipld.Node) error { return err } - adder.pinning.PinWithMode(nd.Cid(), pin.Recursive) + if err := adder.pinning.PinWithMode(ctx, nd.Cid(), pin.Recursive); err != nil { + return err + } return adder.pinning.Flush(ctx) } @@ -48,7 +51,9 @@ func (adder *pinningAdder) AddMany(ctx context.Context, nds []ipld.Node) error { for _, nd := range nds { c := nd.Cid() if cids.Visit(c) { - adder.pinning.PinWithMode(c, pin.Recursive) + if err := adder.pinning.PinWithMode(ctx, c, pin.Recursive); err != nil { + return err + } } } diff --git a/core/coreapi/object.go b/core/coreapi/object.go index 28dd0df08..4b509c782 100644 --- a/core/coreapi/object.go +++ b/core/coreapi/object.go @@ -19,9 +19,10 @@ import ( coreiface "github.com/ipfs/interface-go-ipfs-core" caopts "github.com/ipfs/interface-go-ipfs-core/options" ipath "github.com/ipfs/interface-go-ipfs-core/path" - "github.com/ipfs/kubo/tracing" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" + + "github.com/ipfs/kubo/tracing" ) const inputLimit = 2 << 20 @@ -132,7 +133,10 @@ func (api *ObjectAPI) Put(ctx context.Context, src io.Reader, opts ...caopts.Obj } if options.Pin { - api.pinning.PinWithMode(dagnode.Cid(), pin.Recursive) + if err := api.pinning.PinWithMode(ctx, dagnode.Cid(), pin.Recursive); err != nil { + return nil, err + } + err = api.pinning.Flush(ctx) if err != nil { return nil, err diff --git a/core/coreunix/add.go b/core/coreunix/add.go index f895baf73..d2c4c3dff 100644 --- a/core/coreunix/add.go +++ b/core/coreunix/add.go @@ -24,6 +24,7 @@ import ( "github.com/ipfs/go-unixfs/importer/trickle" coreiface "github.com/ipfs/interface-go-ipfs-core" "github.com/ipfs/interface-go-ipfs-core/path" + "github.com/ipfs/kubo/tracing" ) @@ -185,7 +186,11 @@ func (adder *Adder) PinRoot(ctx context.Context, root ipld.Node) error { adder.tempRoot = rnk } - adder.pinning.PinWithMode(rnk, pin.Recursive) + err = adder.pinning.PinWithMode(ctx, rnk, pin.Recursive) + if err != nil { + return err + } + return adder.pinning.Flush(ctx) } diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 7c421a937..8e29e2333 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -84,7 +84,7 @@ require ( github.com/ipfs/go-ipfs-exchange-interface v0.2.0 // indirect github.com/ipfs/go-ipfs-exchange-offline v0.3.0 // indirect github.com/ipfs/go-ipfs-keystore v0.1.0 // indirect - github.com/ipfs/go-ipfs-pinner v0.2.1 // indirect + github.com/ipfs/go-ipfs-pinner v0.3.0 // indirect github.com/ipfs/go-ipfs-posinfo v0.0.1 // indirect github.com/ipfs/go-ipfs-pq v0.0.3 // indirect github.com/ipfs/go-ipfs-provider v0.8.1 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index d83b0c507..ff42c13b6 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -533,8 +533,8 @@ github.com/ipfs/go-ipfs-exchange-offline v0.3.0/go.mod h1:MOdJ9DChbb5u37M1IcbrRB github.com/ipfs/go-ipfs-files v0.0.3/go.mod h1:INEFm0LL2LWXBhNJ2PMIIb2w45hpXgPjNoE7yA8Y1d4= github.com/ipfs/go-ipfs-keystore v0.1.0 h1:gfuQUO/cyGZgZIHE6OrJas4OnwuxXCqJG7tI0lrB5Qc= github.com/ipfs/go-ipfs-keystore v0.1.0/go.mod h1:LvLw7Qhnb0RlMOfCzK6OmyWxICip6lQ06CCmdbee75U= -github.com/ipfs/go-ipfs-pinner v0.2.1 h1:kw9hiqh2p8TatILYZ3WAfQQABby7SQARdrdA+5Z5QfY= -github.com/ipfs/go-ipfs-pinner v0.2.1/go.mod h1:l1AtLL5bovb7opnG77sh4Y10waINz3Y1ni6CvTzx7oo= +github.com/ipfs/go-ipfs-pinner v0.3.0 h1:jwe5ViX3BON3KgOAYrrhav2+1ONB0QzFAWQd7HUlbuM= +github.com/ipfs/go-ipfs-pinner v0.3.0/go.mod h1:oX0I0nC6zlNIh0LslSrUnjfNKPq8ufoFtqV1/wcJvyo= github.com/ipfs/go-ipfs-posinfo v0.0.1 h1:Esoxj+1JgSjX0+ylc0hUmJCOv6V2vFoZiETLR6OtpRs= github.com/ipfs/go-ipfs-posinfo v0.0.1/go.mod h1:SwyeVP+jCwiDu0C313l/8jg6ZxM0qqtlt2a0vILTc1A= github.com/ipfs/go-ipfs-pq v0.0.1/go.mod h1:LWIqQpqfRG3fNc5XsnIhz/wQ2XXGyugQwls7BgUmUfY= diff --git a/go.mod b/go.mod index a9634a22b..c42d9bd07 100644 --- a/go.mod +++ b/go.mod @@ -36,7 +36,7 @@ require ( github.com/ipfs/go-ipfs-exchange-interface v0.2.0 github.com/ipfs/go-ipfs-exchange-offline v0.3.0 github.com/ipfs/go-ipfs-keystore v0.1.0 - github.com/ipfs/go-ipfs-pinner v0.2.1 + github.com/ipfs/go-ipfs-pinner v0.3.0 github.com/ipfs/go-ipfs-posinfo v0.0.1 github.com/ipfs/go-ipfs-provider v0.8.1 github.com/ipfs/go-ipfs-routing v0.3.0 diff --git a/go.sum b/go.sum index 5a89b69af..5b8cf6d46 100644 --- a/go.sum +++ b/go.sum @@ -553,8 +553,8 @@ github.com/ipfs/go-ipfs-exchange-offline v0.3.0/go.mod h1:MOdJ9DChbb5u37M1IcbrRB github.com/ipfs/go-ipfs-files v0.0.3/go.mod h1:INEFm0LL2LWXBhNJ2PMIIb2w45hpXgPjNoE7yA8Y1d4= github.com/ipfs/go-ipfs-keystore v0.1.0 h1:gfuQUO/cyGZgZIHE6OrJas4OnwuxXCqJG7tI0lrB5Qc= github.com/ipfs/go-ipfs-keystore v0.1.0/go.mod h1:LvLw7Qhnb0RlMOfCzK6OmyWxICip6lQ06CCmdbee75U= -github.com/ipfs/go-ipfs-pinner v0.2.1 h1:kw9hiqh2p8TatILYZ3WAfQQABby7SQARdrdA+5Z5QfY= -github.com/ipfs/go-ipfs-pinner v0.2.1/go.mod h1:l1AtLL5bovb7opnG77sh4Y10waINz3Y1ni6CvTzx7oo= +github.com/ipfs/go-ipfs-pinner v0.3.0 h1:jwe5ViX3BON3KgOAYrrhav2+1ONB0QzFAWQd7HUlbuM= +github.com/ipfs/go-ipfs-pinner v0.3.0/go.mod h1:oX0I0nC6zlNIh0LslSrUnjfNKPq8ufoFtqV1/wcJvyo= github.com/ipfs/go-ipfs-posinfo v0.0.1 h1:Esoxj+1JgSjX0+ylc0hUmJCOv6V2vFoZiETLR6OtpRs= github.com/ipfs/go-ipfs-posinfo v0.0.1/go.mod h1:SwyeVP+jCwiDu0C313l/8jg6ZxM0qqtlt2a0vILTc1A= github.com/ipfs/go-ipfs-pq v0.0.1/go.mod h1:LWIqQpqfRG3fNc5XsnIhz/wQ2XXGyugQwls7BgUmUfY= From f73cd19220b4ef909defb13dc503f19302386967 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Thu, 23 Feb 2023 09:17:01 +0100 Subject: [PATCH 0477/1212] chore: bump go-unixfs to v0.4.3 (#9643) Co-authored-by: Henrique Dias --- docs/examples/kubo-as-a-library/go.mod | 6 +++--- docs/examples/kubo-as-a-library/go.sum | 11 ++++++----- go.mod | 6 +++--- go.sum | 11 ++++++----- 4 files changed, 18 insertions(+), 16 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 8e29e2333..a7d8946c9 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -62,7 +62,7 @@ require ( github.com/hashicorp/golang-lru/v2 v2.0.1 // indirect github.com/huin/goupnp v1.0.3 // indirect github.com/ipfs/bbloom v0.0.4 // indirect - github.com/ipfs/go-bitfield v1.0.0 // indirect + github.com/ipfs/go-bitfield v1.1.0 // indirect github.com/ipfs/go-block-format v0.1.1 // indirect github.com/ipfs/go-blockservice v0.5.0 // indirect github.com/ipfs/go-cid v0.3.2 // indirect @@ -103,8 +103,8 @@ require ( github.com/ipfs/go-namesys v0.7.0 // indirect github.com/ipfs/go-path v0.3.0 // indirect github.com/ipfs/go-peertaskqueue v0.8.1 // indirect - github.com/ipfs/go-unixfs v0.4.2 // indirect - github.com/ipfs/go-unixfsnode v1.5.1 // indirect + github.com/ipfs/go-unixfs v0.4.3 // indirect + github.com/ipfs/go-unixfsnode v1.5.2 // indirect github.com/ipfs/go-verifcid v0.0.2 // indirect github.com/ipld/edelweiss v0.2.0 // indirect github.com/ipld/go-codec-dagpb v1.5.0 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index ff42c13b6..db99a6855 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -434,8 +434,9 @@ github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod github.com/ipfs/bbloom v0.0.1/go.mod h1:oqo8CVWsJFMOZqTglBG4wydCE4IQA/G2/SEofB0rjUI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/go-bitfield v1.0.0 h1:y/XHm2GEmD9wKngheWNNCNL0pzrWXZwCdQGv1ikXknQ= github.com/ipfs/go-bitfield v1.0.0/go.mod h1:N/UiujQy+K+ceU1EF5EkVd1TNqevLrCQMIcAEPrdtus= +github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= +github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.1.0/go.mod h1:FFJEf18E9izuCqUtHxbWEvq+reg7o4CW5wSAE1wsxj0= github.com/ipfs/go-bitswap v0.1.2/go.mod h1:qxSWS4NXGs7jQ6zQvoPY3+NmOfHHG47mhkiLzBpJQIs= github.com/ipfs/go-bitswap v0.5.1/go.mod h1:P+ckC87ri1xFLvk74NlXdP0Kj9RmWAh4+H78sC6Qopo= @@ -605,11 +606,11 @@ github.com/ipfs/go-peertaskqueue v0.8.1 h1:YhxAs1+wxb5jk7RvS0LHdyiILpNmRIRnZVzte github.com/ipfs/go-peertaskqueue v0.8.1/go.mod h1:Oxxd3eaK279FxeydSPPVGHzbwVeHjatZ2GA8XD+KbPU= github.com/ipfs/go-unixfs v0.2.4/go.mod h1:SUdisfUjNoSDzzhGVxvCL9QO/nKdwXdr+gbMUdqcbYw= github.com/ipfs/go-unixfs v0.3.1/go.mod h1:h4qfQYzghiIc8ZNFKiLMFWOTzrWIAtzYQ59W/pCFf1o= -github.com/ipfs/go-unixfs v0.4.2 h1:hdQlsHHK5tek9gC9mjGVua8xyTqC+eopGseCRcbCZNg= -github.com/ipfs/go-unixfs v0.4.2/go.mod h1:L+x6JRlFE0PfyMqeoLYVOKLhn5IeZHvNT7ZI51Y9Qyc= +github.com/ipfs/go-unixfs v0.4.3 h1:EdDc1sNZNFDUlo4UrVAvvAofVI5EwTnKu8Nv8mgXkWQ= +github.com/ipfs/go-unixfs v0.4.3/go.mod h1:TSG7G1UuT+l4pNj91raXAPkX0BhJi3jST1FDTfQ5QyM= github.com/ipfs/go-unixfsnode v1.1.2/go.mod h1:5dcE2x03pyjHk4JjamXmunTMzz+VUtqvPwZjIEkfV6s= -github.com/ipfs/go-unixfsnode v1.5.1 h1:JcR3t5C2nM1V7PMzhJ/Qmo19NkoFIKweDSZyDx+CjkI= -github.com/ipfs/go-unixfsnode v1.5.1/go.mod h1:ed79DaG9IEuZITJVQn4U6MZDftv6I3ygUBLPfhEbHvk= +github.com/ipfs/go-unixfsnode v1.5.2 h1:CvsiTt58W2uR5dD8bqQv+aAY0c1qolmXmSyNbPHYiew= +github.com/ipfs/go-unixfsnode v1.5.2/go.mod h1:NlOebRwYx8lMCNMdhAhEspYPBD3obp7TE0LvBqHY+ks= github.com/ipfs/go-verifcid v0.0.1/go.mod h1:5Hrva5KBeIog4A+UpqlaIU+DEstipcJYQQZc0g37pY0= github.com/ipfs/go-verifcid v0.0.2 h1:XPnUv0XmdH+ZIhLGKg6U2vaPaRDXb9urMyNVCE7uvTs= github.com/ipfs/go-verifcid v0.0.2/go.mod h1:40cD9x1y4OWnFXbLNJYRe7MpNvWlMn3LZAG5Wb4xnPU= diff --git a/go.mod b/go.mod index c42d9bd07..1f91c5c92 100644 --- a/go.mod +++ b/go.mod @@ -55,8 +55,8 @@ require ( github.com/ipfs/go-namesys v0.7.0 github.com/ipfs/go-path v0.3.0 github.com/ipfs/go-pinning-service-http-client v0.1.2 - github.com/ipfs/go-unixfs v0.4.2 - github.com/ipfs/go-unixfsnode v1.5.1 + github.com/ipfs/go-unixfs v0.4.3 + github.com/ipfs/go-unixfsnode v1.5.2 github.com/ipfs/go-verifcid v0.0.2 github.com/ipfs/interface-go-ipfs-core v0.11.0 github.com/ipld/go-car v0.5.0 @@ -156,7 +156,7 @@ require ( github.com/hashicorp/golang-lru/v2 v2.0.1 // indirect github.com/huin/goupnp v1.0.3 // indirect github.com/ipfs/bbloom v0.0.4 // indirect - github.com/ipfs/go-bitfield v1.0.0 // indirect + github.com/ipfs/go-bitfield v1.1.0 // indirect github.com/ipfs/go-block-format v0.1.1 // indirect github.com/ipfs/go-ipfs-delay v0.0.1 // indirect github.com/ipfs/go-ipfs-ds-help v1.1.0 // indirect diff --git a/go.sum b/go.sum index 5b8cf6d46..6b82d03be 100644 --- a/go.sum +++ b/go.sum @@ -452,8 +452,9 @@ github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod github.com/ipfs/bbloom v0.0.1/go.mod h1:oqo8CVWsJFMOZqTglBG4wydCE4IQA/G2/SEofB0rjUI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/go-bitfield v1.0.0 h1:y/XHm2GEmD9wKngheWNNCNL0pzrWXZwCdQGv1ikXknQ= github.com/ipfs/go-bitfield v1.0.0/go.mod h1:N/UiujQy+K+ceU1EF5EkVd1TNqevLrCQMIcAEPrdtus= +github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= +github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.1.0/go.mod h1:FFJEf18E9izuCqUtHxbWEvq+reg7o4CW5wSAE1wsxj0= github.com/ipfs/go-bitswap v0.1.2/go.mod h1:qxSWS4NXGs7jQ6zQvoPY3+NmOfHHG47mhkiLzBpJQIs= github.com/ipfs/go-bitswap v0.5.1/go.mod h1:P+ckC87ri1xFLvk74NlXdP0Kj9RmWAh4+H78sC6Qopo= @@ -631,11 +632,11 @@ github.com/ipfs/go-pinning-service-http-client v0.1.2 h1:jdr7KelhL9gNHTU8jbqPMwI github.com/ipfs/go-pinning-service-http-client v0.1.2/go.mod h1:6wd5mjYhXJTiWU8b4RSWPpWdlzE5/csoXV0dWWMjun4= github.com/ipfs/go-unixfs v0.2.4/go.mod h1:SUdisfUjNoSDzzhGVxvCL9QO/nKdwXdr+gbMUdqcbYw= github.com/ipfs/go-unixfs v0.3.1/go.mod h1:h4qfQYzghiIc8ZNFKiLMFWOTzrWIAtzYQ59W/pCFf1o= -github.com/ipfs/go-unixfs v0.4.2 h1:hdQlsHHK5tek9gC9mjGVua8xyTqC+eopGseCRcbCZNg= -github.com/ipfs/go-unixfs v0.4.2/go.mod h1:L+x6JRlFE0PfyMqeoLYVOKLhn5IeZHvNT7ZI51Y9Qyc= +github.com/ipfs/go-unixfs v0.4.3 h1:EdDc1sNZNFDUlo4UrVAvvAofVI5EwTnKu8Nv8mgXkWQ= +github.com/ipfs/go-unixfs v0.4.3/go.mod h1:TSG7G1UuT+l4pNj91raXAPkX0BhJi3jST1FDTfQ5QyM= github.com/ipfs/go-unixfsnode v1.1.2/go.mod h1:5dcE2x03pyjHk4JjamXmunTMzz+VUtqvPwZjIEkfV6s= -github.com/ipfs/go-unixfsnode v1.5.1 h1:JcR3t5C2nM1V7PMzhJ/Qmo19NkoFIKweDSZyDx+CjkI= -github.com/ipfs/go-unixfsnode v1.5.1/go.mod h1:ed79DaG9IEuZITJVQn4U6MZDftv6I3ygUBLPfhEbHvk= +github.com/ipfs/go-unixfsnode v1.5.2 h1:CvsiTt58W2uR5dD8bqQv+aAY0c1qolmXmSyNbPHYiew= +github.com/ipfs/go-unixfsnode v1.5.2/go.mod h1:NlOebRwYx8lMCNMdhAhEspYPBD3obp7TE0LvBqHY+ks= github.com/ipfs/go-verifcid v0.0.1/go.mod h1:5Hrva5KBeIog4A+UpqlaIU+DEstipcJYQQZc0g37pY0= github.com/ipfs/go-verifcid v0.0.2 h1:XPnUv0XmdH+ZIhLGKg6U2vaPaRDXb9urMyNVCE7uvTs= github.com/ipfs/go-verifcid v0.0.2/go.mod h1:40cD9x1y4OWnFXbLNJYRe7MpNvWlMn3LZAG5Wb4xnPU= From a3366c522a578db610d8633c5a15ebddb6e96e39 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Fri, 24 Feb 2023 01:34:10 -0800 Subject: [PATCH 0478/1212] chore: update go-libp2p to v0.26 (#9656) Co-authored-by: Henrique Dias --- .circleci/main.yml | 15 ++-- .github/workflows/build.yml | 5 +- core/node/libp2p/relay.go | 5 +- docs/examples/kubo-as-a-library/go.mod | 9 +- docs/examples/kubo-as-a-library/go.sum | 18 ++-- go.mod | 9 +- go.sum | 18 ++-- .../t0116-prometheus-data/prometheus_metrics | 83 +++++++++++++++++++ 8 files changed, 119 insertions(+), 43 deletions(-) diff --git a/.circleci/main.yml b/.circleci/main.yml index 6406c6655..b61102692 100644 --- a/.circleci/main.yml +++ b/.circleci/main.yml @@ -234,15 +234,16 @@ jobs: at: /tmp/circleci-workspace - restore_cache: keys: - - v1-interop-{{ .Branch }}-{{ .Revision }} - - v1-interop-{{ .Branch }}- - - v1-interop- + - v2-interop-{{ .Branch }}-{{ .Revision }} + - v2-interop-{{ .Branch }}- + - v2-interop- - run: name: Installing dependencies command: | npm init -y - npm install ipfs@^0.61.0 - npm install ipfs-interop@^8.0.10 + npm install ipfs@^0.66.0 + npm install kubo-rpc-client@^3.0.1 + npm install ipfs-interop@^10.0.1 npm install mocha-circleci-reporter@0.0.3 working_directory: ~/ipfs/kubo/interop - run: @@ -259,7 +260,7 @@ jobs: - store_test_results: path: /tmp/test-results - save_cache: - key: v1-interop-{{ .Branch }}-{{ .Revision }} + key: v2-interop-{{ .Branch }}-{{ .Revision }} paths: - ~/ipfs/kubo/interop/node_modules go-ipfs-api: @@ -292,7 +293,7 @@ jobs: command: go test -count=1 -v ./... working_directory: ~/ipfs/kubo/go-ipfs-api - save_cache: - key: v1-go-api-{{ checksum "~/ipfs/kubo/go-ipfs-api/go.sum" }} + key: v2-go-api-{{ checksum "~/ipfs/kubo/go-ipfs-api/go.sum" }} paths: - ~/go/pkg/mod - ~/.cache/go-build/ diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d0b4194b7..5e350cad7 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -70,8 +70,9 @@ jobs: - run: mkdir interop - run: | npm init -y - npm install ipfs@^0.61.0 - npm install ipfs-interop@^8.0.10 + npm install ipfs@^0.66.0 + npm install kubo-rpc-client@^3.0.1 + npm install ipfs-interop@^10.0.1 working-directory: interop - run: npx ipfs-interop -- -t node $(sed -e 's#[^ ]*#-f test/&.js#g' <<< '${{ matrix.suites }}') env: diff --git a/core/node/libp2p/relay.go b/core/node/libp2p/relay.go index fc362cc53..925fe7bd3 100644 --- a/core/node/libp2p/relay.go +++ b/core/node/libp2p/relay.go @@ -63,10 +63,7 @@ func MaybeAutoRelay(staticRelays []string, cfgPeering config.Peering, enabled bo } static = append(static, *addr) } - opts.Opts = append(opts.Opts, libp2p.EnableAutoRelayWithStaticRelays( - static, - autorelay.WithCircuitV1Support(), - )) + opts.Opts = append(opts.Opts, libp2p.EnableAutoRelayWithStaticRelays(static)) } return }) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index a7d8946c9..23e7df547 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -10,7 +10,7 @@ require ( github.com/ipfs/go-libipfs v0.6.1-0.20230222011044-7b201415a176 github.com/ipfs/interface-go-ipfs-core v0.11.0 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 - github.com/libp2p/go-libp2p v0.25.2-0.20230214091718-aef956be688d + github.com/libp2p/go-libp2p v0.26.0 github.com/multiformats/go-multiaddr v0.8.0 ) @@ -164,10 +164,9 @@ require ( github.com/prometheus/common v0.37.0 // indirect github.com/prometheus/procfs v0.8.0 // indirect github.com/quic-go/qpack v0.4.0 // indirect - github.com/quic-go/qtls-go1-18 v0.2.0 // indirect - github.com/quic-go/qtls-go1-19 v0.2.0 // indirect - github.com/quic-go/qtls-go1-20 v0.1.0 // indirect - github.com/quic-go/quic-go v0.32.0 // indirect + github.com/quic-go/qtls-go1-19 v0.2.1 // indirect + github.com/quic-go/qtls-go1-20 v0.1.1 // indirect + github.com/quic-go/quic-go v0.33.0 // indirect github.com/quic-go/webtransport-go v0.5.1 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/samber/lo v1.36.0 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index db99a6855..6d133eb46 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -730,8 +730,8 @@ github.com/libp2p/go-libp2p v0.7.0/go.mod h1:hZJf8txWeCduQRDC/WSqBGMxaTHCOYHt2xS github.com/libp2p/go-libp2p v0.7.4/go.mod h1:oXsBlTLF1q7pxr+9w6lqzS1ILpyHsaBPniVO7zIHGMw= github.com/libp2p/go-libp2p v0.8.1/go.mod h1:QRNH9pwdbEBpx5DTJYg+qxcVaDMAz3Ee/qDKwXujH5o= github.com/libp2p/go-libp2p v0.14.3/go.mod h1:d12V4PdKbpL0T1/gsUNN8DfgMuRPDX8bS2QxCZlwRH0= -github.com/libp2p/go-libp2p v0.25.2-0.20230214091718-aef956be688d h1:OeFN5DlT447jgmKB9LnzUkpykEw8FMuy7wWTL0rAK30= -github.com/libp2p/go-libp2p v0.25.2-0.20230214091718-aef956be688d/go.mod h1:xnK9/1d9+jeQCVvi/f1g12KqtVi/jP/SijtKV1hML3g= +github.com/libp2p/go-libp2p v0.26.0 h1:0FE0bP9/G9YADjruqoFvf1snBBFvrdh1MmTuEeUkl2E= +github.com/libp2p/go-libp2p v0.26.0/go.mod h1:R8N+XhwPDPLNb4TKboKJKnDeg9vPw8+zlC6g793dTGw= github.com/libp2p/go-libp2p-asn-util v0.2.0 h1:rg3+Os8jbnO5DxkC7K/Utdi+DkY3q/d1/1q+8WeNAsw= github.com/libp2p/go-libp2p-asn-util v0.2.0/go.mod h1:WoaWxbHKBymSN41hWSq/lGKJEca7TNm58+gGJi2WsLI= github.com/libp2p/go-libp2p-autonat v0.1.0/go.mod h1:1tLf2yXxiE/oKGtDwPYWTSYG3PtvYlJmg7NeVtPRqH8= @@ -1171,14 +1171,12 @@ github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5 github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= -github.com/quic-go/qtls-go1-18 v0.2.0 h1:5ViXqBZ90wpUcZS0ge79rf029yx0dYB0McyPJwqqj7U= -github.com/quic-go/qtls-go1-18 v0.2.0/go.mod h1:moGulGHK7o6O8lSPSZNoOwcLvJKJ85vVNc7oJFD65bc= -github.com/quic-go/qtls-go1-19 v0.2.0 h1:Cvn2WdhyViFUHoOqK52i51k4nDX8EwIh5VJiVM4nttk= -github.com/quic-go/qtls-go1-19 v0.2.0/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI= -github.com/quic-go/qtls-go1-20 v0.1.0 h1:d1PK3ErFy9t7zxKsG3NXBJXZjp/kMLoIb3y/kV54oAI= -github.com/quic-go/qtls-go1-20 v0.1.0/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= -github.com/quic-go/quic-go v0.32.0 h1:lY02md31s1JgPiiyfqJijpu/UX/Iun304FI3yUqX7tA= -github.com/quic-go/quic-go v0.32.0/go.mod h1:/fCsKANhQIeD5l76c2JFU+07gVE3KaA0FP+0zMWwfwo= +github.com/quic-go/qtls-go1-19 v0.2.1 h1:aJcKNMkH5ASEJB9FXNeZCyTEIHU1J7MmHyz1Q1TSG1A= +github.com/quic-go/qtls-go1-19 v0.2.1/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI= +github.com/quic-go/qtls-go1-20 v0.1.1 h1:KbChDlg82d3IHqaj2bn6GfKRj84Per2VGf5XV3wSwQk= +github.com/quic-go/qtls-go1-20 v0.1.1/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= +github.com/quic-go/quic-go v0.33.0 h1:ItNoTDN/Fm/zBlq769lLJc8ECe9gYaW40veHCCco7y0= +github.com/quic-go/quic-go v0.33.0/go.mod h1:YMuhaAV9/jIu0XclDXwZPAsP/2Kgr5yMYhe9oxhhOFA= github.com/quic-go/webtransport-go v0.5.1 h1:1eVb7WDWCRoaeTtFHpFBJ6WDN1bSrPrRoW6tZgSw0Ow= github.com/quic-go/webtransport-go v0.5.1/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= github.com/rabbitmq/amqp091-go v1.1.0/go.mod h1:ogQDLSOACsLPsIq0NpbtiifNZi2YOz0VTJ0kHRghqbM= diff --git a/go.mod b/go.mod index 1f91c5c92..3cf782f57 100644 --- a/go.mod +++ b/go.mod @@ -67,7 +67,7 @@ require ( 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.25.1 + github.com/libp2p/go-libp2p v0.26.0 github.com/libp2p/go-libp2p-http v0.4.0 github.com/libp2p/go-libp2p-kad-dht v0.21.0 github.com/libp2p/go-libp2p-kbucket v0.5.0 @@ -207,10 +207,9 @@ require ( github.com/prometheus/procfs v0.8.0 // indirect github.com/prometheus/statsd_exporter v0.21.0 // indirect github.com/quic-go/qpack v0.4.0 // indirect - github.com/quic-go/qtls-go1-18 v0.2.0 // indirect - github.com/quic-go/qtls-go1-19 v0.2.0 // indirect - github.com/quic-go/qtls-go1-20 v0.1.0 // indirect - github.com/quic-go/quic-go v0.32.0 // indirect + github.com/quic-go/qtls-go1-19 v0.2.1 // indirect + github.com/quic-go/qtls-go1-20 v0.1.1 // indirect + github.com/quic-go/quic-go v0.33.0 // indirect github.com/quic-go/webtransport-go v0.5.1 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/rs/cors v1.7.0 // indirect diff --git a/go.sum b/go.sum index 6b82d03be..61390fc2b 100644 --- a/go.sum +++ b/go.sum @@ -760,8 +760,8 @@ github.com/libp2p/go-libp2p v0.7.0/go.mod h1:hZJf8txWeCduQRDC/WSqBGMxaTHCOYHt2xS github.com/libp2p/go-libp2p v0.7.4/go.mod h1:oXsBlTLF1q7pxr+9w6lqzS1ILpyHsaBPniVO7zIHGMw= github.com/libp2p/go-libp2p v0.8.1/go.mod h1:QRNH9pwdbEBpx5DTJYg+qxcVaDMAz3Ee/qDKwXujH5o= github.com/libp2p/go-libp2p v0.14.3/go.mod h1:d12V4PdKbpL0T1/gsUNN8DfgMuRPDX8bS2QxCZlwRH0= -github.com/libp2p/go-libp2p v0.25.1 h1:YK+YDCHpYyTvitKWVxa5PfElgIpOONU01X5UcLEwJGA= -github.com/libp2p/go-libp2p v0.25.1/go.mod h1:xnK9/1d9+jeQCVvi/f1g12KqtVi/jP/SijtKV1hML3g= +github.com/libp2p/go-libp2p v0.26.0 h1:0FE0bP9/G9YADjruqoFvf1snBBFvrdh1MmTuEeUkl2E= +github.com/libp2p/go-libp2p v0.26.0/go.mod h1:R8N+XhwPDPLNb4TKboKJKnDeg9vPw8+zlC6g793dTGw= github.com/libp2p/go-libp2p-asn-util v0.2.0 h1:rg3+Os8jbnO5DxkC7K/Utdi+DkY3q/d1/1q+8WeNAsw= github.com/libp2p/go-libp2p-asn-util v0.2.0/go.mod h1:WoaWxbHKBymSN41hWSq/lGKJEca7TNm58+gGJi2WsLI= github.com/libp2p/go-libp2p-autonat v0.1.0/go.mod h1:1tLf2yXxiE/oKGtDwPYWTSYG3PtvYlJmg7NeVtPRqH8= @@ -1221,14 +1221,12 @@ github.com/prometheus/statsd_exporter v0.21.0 h1:hA05Q5RFeIjgwKIYEdFd59xu5Wwaznf github.com/prometheus/statsd_exporter v0.21.0/go.mod h1:rbT83sZq2V+p73lHhPZfMc3MLCHmSHelCh9hSGYNLTQ= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= -github.com/quic-go/qtls-go1-18 v0.2.0 h1:5ViXqBZ90wpUcZS0ge79rf029yx0dYB0McyPJwqqj7U= -github.com/quic-go/qtls-go1-18 v0.2.0/go.mod h1:moGulGHK7o6O8lSPSZNoOwcLvJKJ85vVNc7oJFD65bc= -github.com/quic-go/qtls-go1-19 v0.2.0 h1:Cvn2WdhyViFUHoOqK52i51k4nDX8EwIh5VJiVM4nttk= -github.com/quic-go/qtls-go1-19 v0.2.0/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI= -github.com/quic-go/qtls-go1-20 v0.1.0 h1:d1PK3ErFy9t7zxKsG3NXBJXZjp/kMLoIb3y/kV54oAI= -github.com/quic-go/qtls-go1-20 v0.1.0/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= -github.com/quic-go/quic-go v0.32.0 h1:lY02md31s1JgPiiyfqJijpu/UX/Iun304FI3yUqX7tA= -github.com/quic-go/quic-go v0.32.0/go.mod h1:/fCsKANhQIeD5l76c2JFU+07gVE3KaA0FP+0zMWwfwo= +github.com/quic-go/qtls-go1-19 v0.2.1 h1:aJcKNMkH5ASEJB9FXNeZCyTEIHU1J7MmHyz1Q1TSG1A= +github.com/quic-go/qtls-go1-19 v0.2.1/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI= +github.com/quic-go/qtls-go1-20 v0.1.1 h1:KbChDlg82d3IHqaj2bn6GfKRj84Per2VGf5XV3wSwQk= +github.com/quic-go/qtls-go1-20 v0.1.1/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= +github.com/quic-go/quic-go v0.33.0 h1:ItNoTDN/Fm/zBlq769lLJc8ECe9gYaW40veHCCco7y0= +github.com/quic-go/quic-go v0.33.0/go.mod h1:YMuhaAV9/jIu0XclDXwZPAsP/2Kgr5yMYhe9oxhhOFA= github.com/quic-go/webtransport-go v0.5.1 h1:1eVb7WDWCRoaeTtFHpFBJ6WDN1bSrPrRoW6tZgSw0Ow= github.com/quic-go/webtransport-go v0.5.1/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= github.com/rabbitmq/amqp091-go v1.1.0/go.mod h1:ogQDLSOACsLPsIq0NpbtiifNZi2YOz0VTJ0kHRghqbM= diff --git a/test/sharness/t0116-prometheus-data/prometheus_metrics b/test/sharness/t0116-prometheus-data/prometheus_metrics index fc6e96e8d..192e526c1 100644 --- a/test/sharness/t0116-prometheus-data/prometheus_metrics +++ b/test/sharness/t0116-prometheus-data/prometheus_metrics @@ -576,6 +576,9 @@ leveldb_datastore_sync_latency_seconds_bucket leveldb_datastore_sync_latency_seconds_count leveldb_datastore_sync_latency_seconds_sum leveldb_datastore_sync_total +libp2p_autonat_next_probe_timestamp +libp2p_autonat_reachability_status +libp2p_autonat_reachability_status_confidence libp2p_eventbus_events_emitted_total libp2p_eventbus_events_emitted_total libp2p_eventbus_subscriber_event_queued @@ -593,8 +596,88 @@ libp2p_eventbus_subscribers_total libp2p_eventbus_subscribers_total libp2p_eventbus_subscribers_total libp2p_eventbus_subscribers_total +libp2p_identify_addrs_count +libp2p_identify_addrs_received_bucket +libp2p_identify_addrs_received_bucket +libp2p_identify_addrs_received_bucket +libp2p_identify_addrs_received_bucket +libp2p_identify_addrs_received_bucket +libp2p_identify_addrs_received_bucket +libp2p_identify_addrs_received_bucket +libp2p_identify_addrs_received_bucket +libp2p_identify_addrs_received_bucket +libp2p_identify_addrs_received_bucket +libp2p_identify_addrs_received_bucket +libp2p_identify_addrs_received_bucket +libp2p_identify_addrs_received_bucket +libp2p_identify_addrs_received_bucket +libp2p_identify_addrs_received_bucket +libp2p_identify_addrs_received_bucket +libp2p_identify_addrs_received_bucket +libp2p_identify_addrs_received_bucket +libp2p_identify_addrs_received_bucket +libp2p_identify_addrs_received_bucket +libp2p_identify_addrs_received_bucket +libp2p_identify_addrs_received_bucket +libp2p_identify_addrs_received_bucket +libp2p_identify_addrs_received_bucket +libp2p_identify_addrs_received_bucket +libp2p_identify_addrs_received_bucket +libp2p_identify_addrs_received_bucket +libp2p_identify_addrs_received_bucket +libp2p_identify_addrs_received_bucket +libp2p_identify_addrs_received_bucket +libp2p_identify_addrs_received_bucket +libp2p_identify_addrs_received_bucket +libp2p_identify_addrs_received_bucket +libp2p_identify_addrs_received_bucket +libp2p_identify_addrs_received_bucket +libp2p_identify_addrs_received_bucket +libp2p_identify_addrs_received_bucket +libp2p_identify_addrs_received_count +libp2p_identify_addrs_received_sum libp2p_identify_identify_pushes_triggered_total libp2p_identify_identify_pushes_triggered_total +libp2p_identify_protocols_count +libp2p_identify_protocols_received_bucket +libp2p_identify_protocols_received_bucket +libp2p_identify_protocols_received_bucket +libp2p_identify_protocols_received_bucket +libp2p_identify_protocols_received_bucket +libp2p_identify_protocols_received_bucket +libp2p_identify_protocols_received_bucket +libp2p_identify_protocols_received_bucket +libp2p_identify_protocols_received_bucket +libp2p_identify_protocols_received_bucket +libp2p_identify_protocols_received_bucket +libp2p_identify_protocols_received_bucket +libp2p_identify_protocols_received_bucket +libp2p_identify_protocols_received_bucket +libp2p_identify_protocols_received_bucket +libp2p_identify_protocols_received_bucket +libp2p_identify_protocols_received_bucket +libp2p_identify_protocols_received_bucket +libp2p_identify_protocols_received_bucket +libp2p_identify_protocols_received_bucket +libp2p_identify_protocols_received_bucket +libp2p_identify_protocols_received_bucket +libp2p_identify_protocols_received_bucket +libp2p_identify_protocols_received_bucket +libp2p_identify_protocols_received_bucket +libp2p_identify_protocols_received_bucket +libp2p_identify_protocols_received_bucket +libp2p_identify_protocols_received_bucket +libp2p_identify_protocols_received_bucket +libp2p_identify_protocols_received_bucket +libp2p_identify_protocols_received_bucket +libp2p_identify_protocols_received_bucket +libp2p_identify_protocols_received_bucket +libp2p_identify_protocols_received_bucket +libp2p_identify_protocols_received_bucket +libp2p_identify_protocols_received_bucket +libp2p_identify_protocols_received_bucket +libp2p_identify_protocols_received_count +libp2p_identify_protocols_received_sum process_cpu_seconds_total process_max_fds process_open_fds From 4283b9d98f8438fc8751ccc840d8fc24eeae6f13 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Fri, 24 Feb 2023 11:49:31 +0100 Subject: [PATCH 0479/1212] chore: bump go-libp2p-kad-dht to v0.21.1 (#9663) --- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 23e7df547..d0a229424 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -120,7 +120,7 @@ require ( github.com/libp2p/go-doh-resolver v0.4.0 // indirect github.com/libp2p/go-flow-metrics v0.1.0 // indirect github.com/libp2p/go-libp2p-asn-util v0.2.0 // indirect - github.com/libp2p/go-libp2p-kad-dht v0.21.0 // indirect + github.com/libp2p/go-libp2p-kad-dht v0.21.1 // indirect github.com/libp2p/go-libp2p-kbucket v0.5.0 // indirect github.com/libp2p/go-libp2p-pubsub v0.9.0 // indirect github.com/libp2p/go-libp2p-pubsub-router v0.6.0 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 6d133eb46..6a5ee2396 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -774,8 +774,8 @@ github.com/libp2p/go-libp2p-discovery v0.1.0/go.mod h1:4F/x+aldVHjHDHuX85x1zWoFT github.com/libp2p/go-libp2p-discovery v0.2.0/go.mod h1:s4VGaxYMbw4+4+tsoQTqh7wfxg97AEdo4GYBt6BadWg= github.com/libp2p/go-libp2p-discovery v0.3.0/go.mod h1:o03drFnz9BVAZdzC/QUQ+NeQOu38Fu7LJGEOK2gQltw= github.com/libp2p/go-libp2p-discovery v0.5.0/go.mod h1:+srtPIU9gDaBNu//UHvcdliKBIcr4SfDcm0/PfPJLug= -github.com/libp2p/go-libp2p-kad-dht v0.21.0 h1:J0Yd22VA+sk0CJRGMgtfHvLVIkZDyJ3AJGiljywIw5U= -github.com/libp2p/go-libp2p-kad-dht v0.21.0/go.mod h1:Bhm9diAFmc6qcWAr084bHNL159srVZRKADdp96Qqd1I= +github.com/libp2p/go-libp2p-kad-dht v0.21.1 h1:xpfp8/t9+X2ip1l8Umap1/UGNnJ3RHJgKGAEsnRAlTo= +github.com/libp2p/go-libp2p-kad-dht v0.21.1/go.mod h1:Oy8wvbdjpB70eS5AaFaI68tOtrdo3KylTvXDjikxqFo= github.com/libp2p/go-libp2p-kbucket v0.3.1/go.mod h1:oyjT5O7tS9CQurok++ERgc46YLwEpuGoFq9ubvoUOio= github.com/libp2p/go-libp2p-kbucket v0.5.0 h1:g/7tVm8ACHDxH29BGrpsQlnNeu+6OF1A9bno/4/U1oA= github.com/libp2p/go-libp2p-kbucket v0.5.0/go.mod h1:zGzGCpQd78b5BNTDGHNDLaTt9aDK/A02xeZp9QeFC4U= diff --git a/go.mod b/go.mod index 3cf782f57..00c464b9d 100644 --- a/go.mod +++ b/go.mod @@ -69,7 +69,7 @@ require ( github.com/libp2p/go-doh-resolver v0.4.0 github.com/libp2p/go-libp2p v0.26.0 github.com/libp2p/go-libp2p-http v0.4.0 - github.com/libp2p/go-libp2p-kad-dht v0.21.0 + github.com/libp2p/go-libp2p-kad-dht v0.21.1 github.com/libp2p/go-libp2p-kbucket v0.5.0 github.com/libp2p/go-libp2p-pubsub v0.9.0 github.com/libp2p/go-libp2p-pubsub-router v0.6.0 diff --git a/go.sum b/go.sum index 61390fc2b..d650d704c 100644 --- a/go.sum +++ b/go.sum @@ -808,8 +808,8 @@ github.com/libp2p/go-libp2p-gostream v0.5.0 h1:niNGTUrFoUDP/8jxMgu97zngMO+UGYBpV github.com/libp2p/go-libp2p-gostream v0.5.0/go.mod h1:rXrb0CqfcRRxa7m3RSKORQiKiWgk3IPeXWda66ZXKsA= github.com/libp2p/go-libp2p-http v0.4.0 h1:V+f9Rhe/8GkColmXoyJyA0NVsN9F3TCLZgW2hwjoX5w= github.com/libp2p/go-libp2p-http v0.4.0/go.mod h1:92tmLGrlBliQFDlZRpBXT3BJM7rGFONy0vsNrG/bMPg= -github.com/libp2p/go-libp2p-kad-dht v0.21.0 h1:J0Yd22VA+sk0CJRGMgtfHvLVIkZDyJ3AJGiljywIw5U= -github.com/libp2p/go-libp2p-kad-dht v0.21.0/go.mod h1:Bhm9diAFmc6qcWAr084bHNL159srVZRKADdp96Qqd1I= +github.com/libp2p/go-libp2p-kad-dht v0.21.1 h1:xpfp8/t9+X2ip1l8Umap1/UGNnJ3RHJgKGAEsnRAlTo= +github.com/libp2p/go-libp2p-kad-dht v0.21.1/go.mod h1:Oy8wvbdjpB70eS5AaFaI68tOtrdo3KylTvXDjikxqFo= github.com/libp2p/go-libp2p-kbucket v0.3.1/go.mod h1:oyjT5O7tS9CQurok++ERgc46YLwEpuGoFq9ubvoUOio= github.com/libp2p/go-libp2p-kbucket v0.5.0 h1:g/7tVm8ACHDxH29BGrpsQlnNeu+6OF1A9bno/4/U1oA= github.com/libp2p/go-libp2p-kbucket v0.5.0/go.mod h1:zGzGCpQd78b5BNTDGHNDLaTt9aDK/A02xeZp9QeFC4U= From 0055f5b9bddcbb8a004125496e628019bddc5db5 Mon Sep 17 00:00:00 2001 From: Piotr Galar Date: Mon, 27 Feb 2023 10:08:51 +0100 Subject: [PATCH 0480/1212] Update docs/RELEASE_ISSUE_TEMPLATE.md --- docs/RELEASE_ISSUE_TEMPLATE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/RELEASE_ISSUE_TEMPLATE.md b/docs/RELEASE_ISSUE_TEMPLATE.md index c38b8eae9..9d4d22eb6 100644 --- a/docs/RELEASE_ISSUE_TEMPLATE.md +++ b/docs/RELEASE_ISSUE_TEMPLATE.md @@ -194,7 +194,7 @@ This section covers tasks to be done during each release. - [ ] check out [ipfs/ipfs-desktop](https://github.com/ipfs/ipfs-desktop) - [ ] run `npm install` - [ ] create a PR which updates `package.json` and `package-lock.json` - - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) merge the PR + - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) add @SgtPooki and @whizzzkid as reviewers
- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Update Kubo docs
using `kuboreleaser release --version vX.Y.Z(-RCN) update-ipfs-docs` or ... - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) run the [update-on-new-ipfs-tag.yml](https://github.com/ipfs/ipfs-docs/actions/workflows/update-on-new-ipfs-tag.yml) workflow From 5d60453326b955745be7539b4cec25c86a2e4921 Mon Sep 17 00:00:00 2001 From: Piotr Galar Date: Mon, 27 Feb 2023 10:49:21 +0100 Subject: [PATCH 0481/1212] ci: ensure new interop suites are executed --- .github/workflows/build.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5e350cad7..6a373b84c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -42,9 +42,10 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - suites: - - 'exchange-files' - - 'files pin circuit ipns cid-version-agnostic ipns-pubsub pubsub' + includes: + - patterns: 'exchange-files' + - patterns: 'exchange-files' + options: '-v' fail-fast: false defaults: run: @@ -74,7 +75,7 @@ jobs: npm install kubo-rpc-client@^3.0.1 npm install ipfs-interop@^10.0.1 working-directory: interop - - run: npx ipfs-interop -- -t node $(sed -e 's#[^ ]*#-f test/&.js#g' <<< '${{ matrix.suites }}') + - run: npx ipfs-interop -- -t node $(ls test/*.js | grep ${{ matrix.options }} '${{ matrix.patterns }}' | sed -e 's/^/-f /' | tr '\n' ' ') env: LIBP2P_TCP_REUSEPORT: false LIBP2P_ALLOW_WEAK_RSA_KEYS: 1 From 7cd7c67fb362ef0e807ccafc3620b6b2281586ad Mon Sep 17 00:00:00 2001 From: Piotr Galar Date: Mon, 27 Feb 2023 11:10:28 +0100 Subject: [PATCH 0482/1212] ci: fix test extraction in interop workflow --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6a373b84c..c7c17a43e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -42,7 +42,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - includes: + include: - patterns: 'exchange-files' - patterns: 'exchange-files' options: '-v' @@ -75,7 +75,7 @@ jobs: npm install kubo-rpc-client@^3.0.1 npm install ipfs-interop@^10.0.1 working-directory: interop - - run: npx ipfs-interop -- -t node $(ls test/*.js | grep ${{ matrix.options }} '${{ matrix.patterns }}' | sed -e 's/^/-f /' | tr '\n' ' ') + - run: npx ipfs-interop -- -t node $(ls node_modules/ipfs-interop/test/*.js | grep ${{ matrix.options }} '${{ matrix.patterns }}' | sed -e 's;node_modules/ipfs-interop/;-f ;' | tr '\n' ' ') env: LIBP2P_TCP_REUSEPORT: false LIBP2P_ALLOW_WEAK_RSA_KEYS: 1 From 0d7c892cecd81eed22ce141608df698ba6902b78 Mon Sep 17 00:00:00 2001 From: Laurent Senta Date: Wed, 15 Feb 2023 15:31:54 +0100 Subject: [PATCH 0483/1212] test: use car fixtures in sharness t0117 --- test/sharness/t0117-gateway-block.sh | 11 +++++----- test/sharness/t0117-gateway-block/README.md | 20 ++++++++++++++++++ .../sharness/t0117-gateway-block/fixtures.car | Bin 0 -> 309 bytes 3 files changed, 26 insertions(+), 5 deletions(-) create mode 100644 test/sharness/t0117-gateway-block/README.md create mode 100644 test/sharness/t0117-gateway-block/fixtures.car diff --git a/test/sharness/t0117-gateway-block.sh b/test/sharness/t0117-gateway-block.sh index 5f1d080a3..d5e40bb83 100755 --- a/test/sharness/t0117-gateway-block.sh +++ b/test/sharness/t0117-gateway-block.sh @@ -7,12 +7,13 @@ test_description="Test HTTP Gateway Raw Block (application/vnd.ipld.raw) Support test_init_ipfs test_launch_ipfs_daemon_without_network -test_expect_success "Create text fixtures" ' - mkdir -p dir && - echo "hello application/vnd.ipld.raw" > dir/ascii.txt && - ROOT_DIR_CID=$(ipfs add -Qrw --cid-version 1 dir) && - FILE_CID=$(ipfs resolve -r /ipfs/$ROOT_DIR_CID/dir/ascii.txt | cut -d "/" -f3) +# Import test case +# See the static fixtures in ./t0117-gateway-block/ +test_expect_success "Add the dir test directory" ' + ipfs dag import ../t0117-gateway-block/fixtures.car ' +ROOT_DIR_CID=bafybeie72edlprgtlwwctzljf6gkn2wnlrddqjbkxo3jomh4n7omwblxly # ./ +FILE_CID=bafkreihhpc5y2pqvl5rbe5uuyhqjouybfs3rvlmisccgzue2kkt5zq6upq # ./dir/ascii.txt # GET unixfs dir root block and compare it with `ipfs block get` output diff --git a/test/sharness/t0117-gateway-block/README.md b/test/sharness/t0117-gateway-block/README.md new file mode 100644 index 000000000..8ca237345 --- /dev/null +++ b/test/sharness/t0117-gateway-block/README.md @@ -0,0 +1,20 @@ +# Dataset description/sources + +- fixtures.car + - raw CARv1 + +generated with: + +```sh +mkdir -p dir && +echo "hello application/vnd.ipld.raw" > dir/ascii.txt && +ROOT_DIR_CID=$(ipfs add -Qrw --cid-version 1 dir) && +FILE_CID=$(ipfs resolve -r /ipfs/$ROOT_DIR_CID/dir/ascii.txt | cut -d "/" -f3) && +ipfs dag export $ROOT_DIR_CID > fixtures.car + +echo ROOT_DIR_CID=${ROOT_DIR_CID} # ./ +echo FILE_CID=${FILE_CID} # ./dir/ascii.txt + +# ROOT_DIR_CID=bafybeie72edlprgtlwwctzljf6gkn2wnlrddqjbkxo3jomh4n7omwblxly # ./ +# FILE_CID=bafkreihhpc5y2pqvl5rbe5uuyhqjouybfs3rvlmisccgzue2kkt5zq6upq # ./dir/ascii.txt +``` diff --git a/test/sharness/t0117-gateway-block/fixtures.car b/test/sharness/t0117-gateway-block/fixtures.car new file mode 100644 index 0000000000000000000000000000000000000000..77da1b5542e281eb1c80a4a8763c85bd7424b60b GIT binary patch literal 309 zcmcColveYNahp`Ifpb-g~vLz*Snd z?RAF`b4q5BLWzWsh6*V>uh`vdCmNq5R5s<{gXzJHI@_hzc1&o=xiBke z`JKa8YJ@lwi<2`m^-3yAB;-M+I}@WTBQ+-{Um>xeASW|9u>|N@{j$6iz087~6uqLv GaxMV9-hqPv literal 0 HcmV?d00001 From 64ccdbd6f26bcd0c24a27d209b662b1fbe80648c Mon Sep 17 00:00:00 2001 From: Laurent Senta Date: Wed, 15 Feb 2023 15:43:03 +0100 Subject: [PATCH 0484/1212] test: use car fixtures in sharness t0113 --- test/sharness/t0113-gateway-symlink.sh | 20 +++++++----------- test/sharness/t0113-gateway-symlink/README.md | 16 ++++++++++++++ .../t0113-gateway-symlink/testfiles.car | Bin 0 -> 282 bytes 3 files changed, 24 insertions(+), 12 deletions(-) create mode 100644 test/sharness/t0113-gateway-symlink/README.md create mode 100644 test/sharness/t0113-gateway-symlink/testfiles.car diff --git a/test/sharness/t0113-gateway-symlink.sh b/test/sharness/t0113-gateway-symlink.sh index 9fa7ffa6e..ea85b8150 100755 --- a/test/sharness/t0113-gateway-symlink.sh +++ b/test/sharness/t0113-gateway-symlink.sh @@ -9,26 +9,22 @@ test_description="Test symlink support on the HTTP gateway" test_init_ipfs test_launch_ipfs_daemon - -test_expect_success "Create a test directory with symlinks" ' - mkdir testfiles && - echo "content" > testfiles/foo && - ln -s foo testfiles/bar && - test_cmp testfiles/foo testfiles/bar -' - -test_expect_success "Add the test directory" ' - HASH=$(ipfs add -Qr testfiles) +# Import test case +# See the static fixtures in ./t0113-gateway-symlink/ +test_expect_success "Add the test directory with symlinks" ' + ipfs dag import ../t0113-gateway-symlink/testfiles.car ' +ROOT_DIR_CID=QmWvY6FaqFMS89YAQ9NAPjVP4WZKA1qbHbicc9HeSKQTgt # ./testfiles/ test_expect_success "Test the directory listing" ' - curl "$GWAY_ADDR/ipfs/$HASH/" > list_response && + curl "$GWAY_ADDR/ipfs/$ROOT_DIR_CID/" > list_response && test_should_contain ">foo<" list_response && test_should_contain ">bar<" list_response ' +# TODO: it's unclear to me if that `echo -n "foo" > expected` should be a fixture somehow. test_expect_success "Test the symlink" ' - curl "$GWAY_ADDR/ipfs/$HASH/bar" > bar_actual && + curl "$GWAY_ADDR/ipfs/$ROOT_DIR_CID/bar" > bar_actual && echo -n "foo" > bar_expected && test_cmp bar_expected bar_actual ' diff --git a/test/sharness/t0113-gateway-symlink/README.md b/test/sharness/t0113-gateway-symlink/README.md new file mode 100644 index 000000000..350405e32 --- /dev/null +++ b/test/sharness/t0113-gateway-symlink/README.md @@ -0,0 +1,16 @@ +# Dataset description/sources + +- testfiles.car + - raw CARv1 + +generated with: + +```sh +mkdir testfiles && +echo "content" > testfiles/foo && +ln -s foo testfiles/bar && +ROOT_DIR_CID=$(ipfs add -Qr testfiles) && +ipfs dag export $ROOT_DIR_CID > testfiles.car + +# ROOT_DIR_CID=QmWvY6FaqFMS89YAQ9NAPjVP4WZKA1qbHbicc9HeSKQTgt +``` diff --git a/test/sharness/t0113-gateway-symlink/testfiles.car b/test/sharness/t0113-gateway-symlink/testfiles.car new file mode 100644 index 0000000000000000000000000000000000000000..88e5825f3029ceb158138812c946825544704d26 GIT binary patch literal 282 zcmcCmlvG!RGgWg$JoF~Sh0{cmy(cz`^^ncIdY^b8_T#q9k%X>mgtKR@Vd1l;Qez>Zf=ID z2|~NuBOwJsCUfy|FbQ!a=jWBA=9O?sZ~y=yG;7fS literal 0 HcmV?d00001 From 771d62c8f4877b12ed0074a5186f5cc2a33be888 Mon Sep 17 00:00:00 2001 From: Laurent Senta Date: Wed, 15 Feb 2023 16:00:05 +0100 Subject: [PATCH 0485/1212] test: use car fixtures in sharness t0114 --- test/sharness/t0114-gateway-subdomains.sh | 32 ++++------- .../t0114-gateway-subdomains/README.md | 52 ++++++++++++++++++ .../t0114-gateway-subdomains/fixtures.car | Bin 0 -> 1518 bytes 3 files changed, 63 insertions(+), 21 deletions(-) create mode 100644 test/sharness/t0114-gateway-subdomains/README.md create mode 100644 test/sharness/t0114-gateway-subdomains/fixtures.car diff --git a/test/sharness/t0114-gateway-subdomains.sh b/test/sharness/t0114-gateway-subdomains.sh index a7e5a59c9..04f762ad6 100755 --- a/test/sharness/t0114-gateway-subdomains.sh +++ b/test/sharness/t0114-gateway-subdomains.sh @@ -91,27 +91,19 @@ test_expect_success "ipfs init" ' test_launch_ipfs_daemon_without_network +# Import test case +# See the static fixtures in ./t0114-gateway-subdomains/ +test_expect_success "Add the test fixtures" ' + ipfs dag import ../t0114-gateway-subdomains/fixtures.car +' +CID_VAL="hello" +CIDv1=bafkreicysg23kiwv34eg2d7qweipxwosdo2py4ldv42nbauguluen5v6am +CIDv0=QmZULkCELmmk5XNfCgTnCyFgAVxBRBXyDHGGMVoLFLiXEN # CIDv0to1 is necessary because raw-leaves are enabled by default during # "ipfs add" with CIDv1 and disabled with CIDv0 -test_expect_success "Add test text file" ' - CID_VAL="hello" - CIDv1=$(echo $CID_VAL | ipfs add --cid-version 1 -Q) - CIDv0=$(echo $CID_VAL | ipfs add --cid-version 0 -Q) - CIDv0to1=$(echo "$CIDv0" | ipfs cid base32) - echo CIDv0to1=${CIDv0to1} -' - -# Directory tree crafted to test for edge cases like "/ipfs/ipfs/ipns/bar" -test_expect_success "Add the test directory" ' - mkdir -p testdirlisting/ipfs/ipns && - echo "hello" > testdirlisting/hello && - echo "text-file-content" > testdirlisting/ipfs/ipns/bar && - mkdir -p testdirlisting/api && - mkdir -p testdirlisting/ipfs && - echo "I am a txt file" > testdirlisting/api/file.txt && - echo "I am a txt file" > testdirlisting/ipfs/file.txt && - DIR_CID=$(ipfs add -Qr --cid-version 1 testdirlisting) -' +CIDv0to1=bafybeiffndsajwhk3lwjewwdxqntmjm4b5wxaaanokonsggenkbw6slwk4 +CIDv1_TOO_LONG=bafkrgqhhyivzstcz3hhswshfjgy6ertgmnqeleynhwt4dlfsthi4hn7zgh4uvlsb5xncykzapi3ocd4lzogukir6ksdy6wzrnz6ohnv4aglcs +DIR_CID=bafybeiht6dtwk3les7vqm6ibpvz6qpohidvlshsfyr7l5mpysdw2vmbbhe # ./testdirlisting test_expect_success "Publish test text file to IPNS using RSA keys" ' RSA_KEY=$(ipfs key gen --ipns-base=b58mh --type=rsa --size=2048 test_key_rsa | head -n1 | tr -d "\n") @@ -600,8 +592,6 @@ test_expect_success \ IPNS_KEY="test_key_ed25519" IPNS_ED25519_B58MH=$(ipfs key list -l --ipns-base b58mh | grep $IPNS_KEY | cut -d" " -f1 | tr -d "\n") IPNS_ED25519_B36CID=$(ipfs key list -l --ipns-base base36 | grep $IPNS_KEY | cut -d" " -f1 | tr -d "\n") -# sha512 will be over 63char limit, even when represented in Base36 -CIDv1_TOO_LONG=$(echo $CID_VAL | ipfs add --cid-version 1 --hash sha2-512 -Q) # local: *.localhost test_localhost_gateway_response_should_contain \ diff --git a/test/sharness/t0114-gateway-subdomains/README.md b/test/sharness/t0114-gateway-subdomains/README.md new file mode 100644 index 000000000..8f0075ccd --- /dev/null +++ b/test/sharness/t0114-gateway-subdomains/README.md @@ -0,0 +1,52 @@ +# Dataset description/sources + +- fixtures.car + - raw CARv1 + +generated with: + +```sh +# CIDv0to1 is necessary because raw-leaves are enabled by default during +# "ipfs add" with CIDv1 and disabled with CIDv0 +CID_VAL="hello" +CIDv1=$(echo $CID_VAL | ipfs add --cid-version 1 -Q) +CIDv0=$(echo $CID_VAL | ipfs add --cid-version 0 -Q) +CIDv0to1=$(echo "$CIDv0" | ipfs cid base32) +# sha512 will be over 63char limit, even when represented in Base36 +CIDv1_TOO_LONG=$(echo $CID_VAL | ipfs add --cid-version 1 --hash sha2-512 -Q) + +echo CIDv1=${CIDv1} +echo CIDv0=${CIDv0} +echo CIDv0to1=${CIDv0to1} +echo CIDv1_TOO_LONG=${CIDv1_TOO_LONG} + +# Directory tree crafted to test for edge cases like "/ipfs/ipfs/ipns/bar" +mkdir -p testdirlisting/ipfs/ipns && +echo "hello" > testdirlisting/hello && +echo "text-file-content" > testdirlisting/ipfs/ipns/bar && +mkdir -p testdirlisting/api && +mkdir -p testdirlisting/ipfs && +echo "I am a txt file" > testdirlisting/api/file.txt && +echo "I am a txt file" > testdirlisting/ipfs/file.txt && +DIR_CID=$(ipfs add -Qr --cid-version 1 testdirlisting) + +echo DIR_CID=${DIR_CID} + +ipfs files mkdir /t0114/ +ipfs files cp /ipfs/${CIDv1} /t0114/ +ipfs files cp /ipfs/${CIDv0} /t0114/ +ipfs files cp /ipfs/${CIDv0to1} /t0114/ +ipfs files cp /ipfs/${DIR_CID} /t0114/ +ipfs files cp /ipfs/${CIDv1_TOO_LONG} /t0114/ + +ROOT=`ipfs files stat /t0114/ --hash` + +ipfs dag export ${ROOT} > ./fixtures.car + +# CID_VAL="hello" +# CIDv1=bafkreicysg23kiwv34eg2d7qweipxwosdo2py4ldv42nbauguluen5v6am +# CIDv0=QmZULkCELmmk5XNfCgTnCyFgAVxBRBXyDHGGMVoLFLiXEN +# CIDv0to1=bafybeiffndsajwhk3lwjewwdxqntmjm4b5wxaaanokonsggenkbw6slwk4 +# CIDv1_TOO_LONG=bafkrgqhhyivzstcz3hhswshfjgy6ertgmnqeleynhwt4dlfsthi4hn7zgh4uvlsb5xncykzapi3ocd4lzogukir6ksdy6wzrnz6ohnv4aglcs +# DIR_CID=bafybeiht6dtwk3les7vqm6ibpvz6qpohidvlshsfyr7l5mpysdw2vmbbhe # ./testdirlisting +``` diff --git a/test/sharness/t0114-gateway-subdomains/fixtures.car b/test/sharness/t0114-gateway-subdomains/fixtures.car new file mode 100644 index 0000000000000000000000000000000000000000..bc7b913dfa27573c76673744a7d15df6a885e891 GIT binary patch literal 1518 zcmb`GeQXnD9LKqJF0;ypXM$%)qznuxqXXLO6<<(B>E0+~lC3KP)VtnuFTJ<6&-Jc% zAZ8emC~AekvSdRu6%$2pDmVyKbW4oUh*Ouak!YMEFO$(kV@4F?-TIe*wK4wxe1E_1 z_w)Tds|P?zQB>G{VOezX9MmN~(GT9Z{qdnmvbArh-#syZWbfg+Tan$T4@h55eY@f; ztAP~c6&blvUi>i{an_)&H@Tn7FI=1Wb${3JnFYlCebrK8&fHYrI5rZ0MrqbM(YnW^ zu8yz}42300@JCyjAlohnjRv+pl3BNTUDR0L)Y!N&qJ$g5d^FUGRiVJS1nEFs(N|8K zs2TgAQmW1m&iixxn*|^Km5d$7zuvuP;7Y?EIS2X>MKVGP@G%3jUZ240nhyu8mkuO# zz$Y@g0%^sYFmRF9aIZ{}X*MmUf$Y}^Qo<_GA;h^J>9~9C_)FH>jS%Uy6m6hZq5P>0cx{A{x167X4IXPgm9G=!hNcl5z z%n(d6!TXdLjfVQ>ldKqnmUWv@q6GFfA%g-u!^kuw<2on! zL_H34oz5g>Rf_#$dF}$EKoWDMP0zHBACLO-}0A%ME6Wp7|2ub%9_vC zUORPPXk=Gza3*{G?e`WvFk6JZhEoYz)vX->2DGF^@Ki!GiDW|Ic-o4|LB>c0M8A|U zAgy~fiJ~}wz2-oNnG5tU7n~W9Hr?-NQS^b33-9l?*R}IyIwW^X%ccU0^X$ zvx}5mq{|YyY_)UWEX<-I{(~j7t^mm0H@&Is{G{{mu_pNH>0R@m?J@7lwGC|;xu>Q5 zokxEewE@Wx3)vAmZ9YW>cC%L0g@>Q_W*sNTZUpY|gtsF3{I*8<`0M+oyE~6==;=-O cqYjEpVW>TqDCNBhGOEXh;)yA;3S`y!570JmG5`Po literal 0 HcmV?d00001 From 8641d16a2b3acec0d5ff84ae9bbcbaa14ad6f436 Mon Sep 17 00:00:00 2001 From: Laurent Senta Date: Thu, 16 Feb 2023 10:23:37 +0100 Subject: [PATCH 0486/1212] test: use car fixtures in sharness t0115 --- test/sharness/t0115-gateway-dir-listing.sh | 18 ++++------ .../t0115-gateway-dir-listing/README.md | 31 ++++++++++++++++++ .../t0115-gateway-dir-listing/fixtures.car | Bin 0 -> 1053 bytes 3 files changed, 37 insertions(+), 12 deletions(-) create mode 100644 test/sharness/t0115-gateway-dir-listing/README.md create mode 100644 test/sharness/t0115-gateway-dir-listing/fixtures.car diff --git a/test/sharness/t0115-gateway-dir-listing.sh b/test/sharness/t0115-gateway-dir-listing.sh index 708e0c4cf..cf95bf4b0 100755 --- a/test/sharness/t0115-gateway-dir-listing.sh +++ b/test/sharness/t0115-gateway-dir-listing.sh @@ -18,20 +18,14 @@ test_expect_success "ipfs init" ' test_launch_ipfs_daemon_without_network +# Import test case +# See the static fixtures in ./t0115-gateway-dir-listing/ test_expect_success "Add the test directory" ' - mkdir -p rootDir/ipfs && - mkdir -p rootDir/ipns && - mkdir -p rootDir/api && - mkdir -p rootDir/ą/ę && - echo "I am a txt file on path with utf8" > rootDir/ą/ę/file-źł.txt && - echo "I am a txt file in confusing /api dir" > rootDir/api/file.txt && - echo "I am a txt file in confusing /ipfs dir" > rootDir/ipfs/file.txt && - echo "I am a txt file in confusing /ipns dir" > rootDir/ipns/file.txt && - DIR_CID=$(ipfs add -Qr --cid-version 1 rootDir) && - FILE_CID=$(ipfs files stat --enc=json /ipfs/$DIR_CID/ą/ę/file-źł.txt | jq -r .Hash) && - FILE_SIZE=$(ipfs files stat --enc=json /ipfs/$DIR_CID/ą/ę/file-źł.txt | jq -r .Size) - echo "$FILE_CID / $FILE_SIZE" + ipfs dag import ../t0115-gateway-dir-listing/fixtures.car ' +DIR_CID=bafybeig6ka5mlwkl4subqhaiatalkcleo4jgnr3hqwvpmsqfca27cijp3i # ./rootDir/ +FILE_CID=bafkreialihlqnf5uwo4byh4n3cmwlntwqzxxs2fg5vanqdi3d7tb2l5xkm # ./rootDir/ą/ę/file-źł.txt +FILE_SIZE=34 ## ============================================================================ ## Test dir listing on path gateway (eg. 127.0.0.1:8080/ipfs/) diff --git a/test/sharness/t0115-gateway-dir-listing/README.md b/test/sharness/t0115-gateway-dir-listing/README.md new file mode 100644 index 000000000..8b6e33275 --- /dev/null +++ b/test/sharness/t0115-gateway-dir-listing/README.md @@ -0,0 +1,31 @@ +# Dataset description/sources + +- fixtures.car + - raw CARv1 + +generated with: + +```sh +mkdir -p rootDir/ipfs && +mkdir -p rootDir/ipns && +mkdir -p rootDir/api && +mkdir -p rootDir/ą/ę && +echo "I am a txt file on path with utf8" > rootDir/ą/ę/file-źł.txt && +echo "I am a txt file in confusing /api dir" > rootDir/api/file.txt && +echo "I am a txt file in confusing /ipfs dir" > rootDir/ipfs/file.txt && +echo "I am a txt file in confusing /ipns dir" > rootDir/ipns/file.txt && +DIR_CID=$(ipfs add -Qr --cid-version 1 rootDir) && +FILE_CID=$(ipfs files stat --enc=json /ipfs/$DIR_CID/ą/ę/file-źł.txt | jq -r .Hash) && +FILE_SIZE=$(ipfs files stat --enc=json /ipfs/$DIR_CID/ą/ę/file-źł.txt | jq -r .Size) +echo "$FILE_CID / $FILE_SIZE" + +echo DIR_CID=${DIR_CID} +echo FILE_CID=${FILE_CID} +echo FILE_SIZE=${FILE_SIZE} + +ipfs dag export ${DIR_CID} > ./fixtures.car + +# DIR_CID=bafybeig6ka5mlwkl4subqhaiatalkcleo4jgnr3hqwvpmsqfca27cijp3i # ./rootDir/ +# FILE_CID=bafkreialihlqnf5uwo4byh4n3cmwlntwqzxxs2fg5vanqdi3d7tb2l5xkm # ./rootDir/ą/ę/file-źł.txt +# FILE_SIZE=34 +``` diff --git a/test/sharness/t0115-gateway-dir-listing/fixtures.car b/test/sharness/t0115-gateway-dir-listing/fixtures.car new file mode 100644 index 0000000000000000000000000000000000000000..71a5603822741f25320438bd70823589120e313c GIT binary patch literal 1053 zcmcColvR$Z!{1TqeSN@tUjjg{Tlgc7mrAdS5w!gPn*17KH6I(#F3Vnld4xzQ6ixRGTe(8O`Zyg zxeAF2KuroD-3pm`3d#9-X{E)PdFcxJz;IJY$t>amyOUtJLEZWM>i;({85gv-W(d_V zKa@*2eN@-d)vWbj%$Z-NzS6vINbXbzxziiuPC}aSyAu>)2!|4kFsMU?&s>>u#q@K) zg=4JD+Ddu%u4<)wm#M_8IM$cG*3(nQFic@T$&fnuIuO3{I&*k2EHJEuD( zXEu8GPP(?~NTtQ!*2R(r|4!eUF1UKJ@frzWikc}A4+_gfkg)`nn?n*5x8rrT>037M zkdg1bF*9{rSzCT(#hs2>E#m S1&JjY3gwwVqO>H Date: Mon, 20 Feb 2023 15:57:38 +0100 Subject: [PATCH 0487/1212] test: fix prometheus test folder path --- .../prometheus_metrics | 0 .../prometheus_metrics_added_by_enabling_rcmgr | 0 test/sharness/t0119-prometheus.sh | 6 +++--- 3 files changed, 3 insertions(+), 3 deletions(-) rename test/sharness/{t0116-prometheus-data => t0119-prometheus-data}/prometheus_metrics (100%) rename test/sharness/{t0116-prometheus-data => t0119-prometheus-data}/prometheus_metrics_added_by_enabling_rcmgr (100%) diff --git a/test/sharness/t0116-prometheus-data/prometheus_metrics b/test/sharness/t0119-prometheus-data/prometheus_metrics similarity index 100% rename from test/sharness/t0116-prometheus-data/prometheus_metrics rename to test/sharness/t0119-prometheus-data/prometheus_metrics diff --git a/test/sharness/t0116-prometheus-data/prometheus_metrics_added_by_enabling_rcmgr b/test/sharness/t0119-prometheus-data/prometheus_metrics_added_by_enabling_rcmgr similarity index 100% rename from test/sharness/t0116-prometheus-data/prometheus_metrics_added_by_enabling_rcmgr rename to test/sharness/t0119-prometheus-data/prometheus_metrics_added_by_enabling_rcmgr diff --git a/test/sharness/t0119-prometheus.sh b/test/sharness/t0119-prometheus.sh index e96b8b96f..3387f4feb 100755 --- a/test/sharness/t0119-prometheus.sh +++ b/test/sharness/t0119-prometheus.sh @@ -27,7 +27,7 @@ test_expect_success "filter metrics" ' ' test_expect_success "make sure metrics haven't changed" ' - diff -u ../t0116-prometheus-data/prometheus_metrics filtered_metrics + diff -u ../t0119-prometheus-data/prometheus_metrics filtered_metrics ' # Check what was added by enabling ResourceMgr.Enabled @@ -50,11 +50,11 @@ test_kill_ipfs_daemon test_expect_success "filter metrics and find ones added by enabling ResourceMgr" ' sed -ne "s/^\([a-z0-9_]\+\).*/\1/p" raw_metrics | LC_ALL=C sort > filtered_metrics && - grep -v -x -f ../t0116-prometheus-data/prometheus_metrics filtered_metrics > rcmgr_metrics + grep -v -x -f ../t0119-prometheus-data/prometheus_metrics filtered_metrics > rcmgr_metrics ' test_expect_success "make sure initial metrics added by setting ResourceMgr.Enabled haven't changed" ' - diff -u ../t0116-prometheus-data/prometheus_metrics_added_by_enabling_rcmgr rcmgr_metrics + diff -u ../t0119-prometheus-data/prometheus_metrics_added_by_enabling_rcmgr rcmgr_metrics ' test_done From 284bb8c819fbd8d50e757f733957980c183855b0 Mon Sep 17 00:00:00 2001 From: Laurent Senta Date: Mon, 20 Feb 2023 16:04:16 +0100 Subject: [PATCH 0488/1212] test: use car fixtures in sharness t0116 --- test/sharness/t0116-gateway-cache.sh | 15 +++++---- test/sharness/t0116-gateway-cache/README.md | 30 ++++++++++++++++++ .../sharness/t0116-gateway-cache/fixtures.car | Bin 0 -> 468 bytes 3 files changed, 38 insertions(+), 7 deletions(-) create mode 100644 test/sharness/t0116-gateway-cache/README.md create mode 100644 test/sharness/t0116-gateway-cache/fixtures.car diff --git a/test/sharness/t0116-gateway-cache.sh b/test/sharness/t0116-gateway-cache.sh index 0af4ec0eb..508fc73c2 100755 --- a/test/sharness/t0116-gateway-cache.sh +++ b/test/sharness/t0116-gateway-cache.sh @@ -25,15 +25,16 @@ test_launch_ipfs_daemon_without_network # Caching of things like raw blocks, CARs, dag-json and dag-cbor # is tested in their respective suites. +# Import test case +# See the static fixtures in ./t0116-gateway-cache/ test_expect_success "Add the test directory" ' - mkdir -p root2/root3/root4 && - echo "hello" > root2/root3/root4/index.html && - ROOT1_CID=$(ipfs add -Qrw --cid-version 1 root2) - ROOT2_CID=$(ipfs resolve -r /ipfs/$ROOT1_CID/root2 | cut -d "/" -f3) - ROOT3_CID=$(ipfs resolve -r /ipfs/$ROOT1_CID/root2/root3 | cut -d "/" -f3) - ROOT4_CID=$(ipfs resolve -r /ipfs/$ROOT1_CID/root2/root3/root4 | cut -d "/" -f3) - FILE_CID=$(ipfs resolve -r /ipfs/$ROOT1_CID/root2/root3/root4/index.html | cut -d "/" -f3) + ipfs dag import ../t0116-gateway-cache/fixtures.car ' +ROOT1_CID=bafybeib3ffl2teiqdncv3mkz4r23b5ctrwkzrrhctdbne6iboayxuxk5ui # ./ +ROOT2_CID=bafybeih2w7hjocxjg6g2ku25hvmd53zj7og4txpby3vsusfefw5rrg5sii # ./root2 +ROOT3_CID=bafybeiawdvhmjcz65x5egzx4iukxc72hg4woks6v6fvgyupiyt3oczk5ja # ./root2/root3 +ROOT4_CID=bafybeifq2rzpqnqrsdupncmkmhs3ckxxjhuvdcbvydkgvch3ms24k5lo7q # ./root2/root3/root4 +FILE_CID=bafkreicysg23kiwv34eg2d7qweipxwosdo2py4ldv42nbauguluen5v6am # ./root2/root3/root4/index.html test_expect_success "Prepare IPNS unixfs content path for testing" ' TEST_IPNS_ID=$(ipfs key gen --ipns-base=base36 --type=ed25519 cache_test_key | head -n1 | tr -d "\n") diff --git a/test/sharness/t0116-gateway-cache/README.md b/test/sharness/t0116-gateway-cache/README.md new file mode 100644 index 000000000..91c438941 --- /dev/null +++ b/test/sharness/t0116-gateway-cache/README.md @@ -0,0 +1,30 @@ +# Dataset description/sources + +- fixtures.car + - raw CARv1 + +generated with: + +```sh +mkdir -p root2/root3/root4 && +echo "hello" > root2/root3/root4/index.html && +ROOT1_CID=$(ipfs add -Qrw --cid-version 1 root2) +ROOT2_CID=$(ipfs resolve -r /ipfs/$ROOT1_CID/root2 | cut -d "/" -f3) +ROOT3_CID=$(ipfs resolve -r /ipfs/$ROOT1_CID/root2/root3 | cut -d "/" -f3) +ROOT4_CID=$(ipfs resolve -r /ipfs/$ROOT1_CID/root2/root3/root4 | cut -d "/" -f3) +FILE_CID=$(ipfs resolve -r /ipfs/$ROOT1_CID/root2/root3/root4/index.html | cut -d "/" -f3) + +echo ROOT1_CID=${ROOT1_CID} +echo ROOT2_CID=${ROOT2_CID} +echo ROOT3_CID=${ROOT3_CID} +echo ROOT4_CID=${ROOT4_CID} +echo FILE_CID=${FILE_CID} + +ipfs dag export ${ROOT1_CID} > ./fixtures.car + +# ROOT1_CID=bafybeib3ffl2teiqdncv3mkz4r23b5ctrwkzrrhctdbne6iboayxuxk5ui # ./ +# ROOT2_CID=bafybeih2w7hjocxjg6g2ku25hvmd53zj7og4txpby3vsusfefw5rrg5sii # ./root2 +# ROOT3_CID=bafybeiawdvhmjcz65x5egzx4iukxc72hg4woks6v6fvgyupiyt3oczk5ja # ./root2/root3 +# ROOT4_CID=bafybeifq2rzpqnqrsdupncmkmhs3ckxxjhuvdcbvydkgvch3ms24k5lo7q # ./root2/root3/root4 +# FILE_CID=bafkreicysg23kiwv34eg2d7qweipxwosdo2py4ldv42nbauguluen5v6am # ./root2/root3/root4/index.html +``` diff --git a/test/sharness/t0116-gateway-cache/fixtures.car b/test/sharness/t0116-gateway-cache/fixtures.car new file mode 100644 index 0000000000000000000000000000000000000000..43e570e1d6acb0a03531b47feb540318f5027204 GIT binary patch literal 468 zcmcColvx?P5~W2SVzij7-;r*+x4)dz{ z2?vnLaUeGn)L{a2bEuF)#Kf&zm9F0B$mRdAQQ-H@OVV5Z6eh1XxzN Date: Mon, 20 Feb 2023 16:13:17 +0100 Subject: [PATCH 0489/1212] test: use car fixtures in sharness t0118 --- test/sharness/t0118-gateway-car.sh | 17 ++++++++-------- test/sharness/t0118-gateway-car/README.md | 19 ++++++++++++++++++ .../t0118-gateway-car/deterministic.car | Bin 0 -> 127 bytes .../t0118-gateway-car/subdir/ascii.txt | 1 + test/sharness/t0118-gateway-car/test-dag.car | Bin 0 -> 312 bytes 5 files changed, 28 insertions(+), 9 deletions(-) create mode 100644 test/sharness/t0118-gateway-car/deterministic.car create mode 100644 test/sharness/t0118-gateway-car/subdir/ascii.txt create mode 100644 test/sharness/t0118-gateway-car/test-dag.car diff --git a/test/sharness/t0118-gateway-car.sh b/test/sharness/t0118-gateway-car.sh index 62b2725d0..7b7d998ee 100755 --- a/test/sharness/t0118-gateway-car.sh +++ b/test/sharness/t0118-gateway-car.sh @@ -11,15 +11,14 @@ test_launch_ipfs_daemon_without_network # but if we have a small file that fits into a single block, and export its CID # we will get a CAR that is a deterministic array of bytes. - test_expect_success "Create a deterministic CAR for testing" ' - mkdir -p subdir && - echo "hello application/vnd.ipld.car" > subdir/ascii.txt && - ROOT_DIR_CID=$(ipfs add -Qrw --cid-version 1 subdir) && - FILE_CID=$(ipfs resolve -r /ipfs/$ROOT_DIR_CID/subdir/ascii.txt | cut -d "/" -f3) && - ipfs dag export $ROOT_DIR_CID > test-dag.car && - ipfs dag export $FILE_CID > deterministic.car && - purge_blockstore - ' +# Import test case +# See the static fixtures in ./t0118-gateway-car/ +test_expect_success "Add the dir test directory" ' + cp ../t0118-gateway-car/test-dag.car ./test-dag.car && + cp ../t0118-gateway-car/deterministic.car ./deterministic.car +' +ROOT_DIR_CID=bafybeiefu3d7oytdumk5v7gn6s7whpornueaw7m7u46v2o6omsqcrhhkzi # ./ +FILE_CID=bafkreifkam6ns4aoolg3wedr4uzrs3kvq66p4pecirz6y2vlrngla62mxm # /subdir/ascii.txt # GET a reference DAG with dag-cbor+dag-pb+raw blocks as CAR diff --git a/test/sharness/t0118-gateway-car/README.md b/test/sharness/t0118-gateway-car/README.md index 2efccc185..f19494833 100644 --- a/test/sharness/t0118-gateway-car/README.md +++ b/test/sharness/t0118-gateway-car/README.md @@ -8,3 +8,22 @@ - description of the contents and layout of the raw CAR, encoded in DAG-JSON - Source: https://ipld.io/specs/transport/car/fixture/carv1-basic/carv1-basic.json +- test-dag.car + deterministic.car + - raw CARv1 + +generated with: + +```shell +mkdir -p subdir && +echo "hello application/vnd.ipld.car" > subdir/ascii.txt && +ROOT_DIR_CID=$(ipfs add -Qrw --cid-version 1 subdir) && +FILE_CID=$(ipfs resolve -r /ipfs/$ROOT_DIR_CID/subdir/ascii.txt | cut -d "/" -f3) && +ipfs dag export $ROOT_DIR_CID > test-dag.car && +ipfs dag export $FILE_CID > deterministic.car && + +echo ROOT_DIR_CID=${ROOT_DIR_CID} # ./ +echo FILE_CID=${FILE_CID} # /\subdir/ascii.txt + +# ROOT_DIR_CID=bafybeiefu3d7oytdumk5v7gn6s7whpornueaw7m7u46v2o6omsqcrhhkzi # ./ +# FILE_CID=bafkreifkam6ns4aoolg3wedr4uzrs3kvq66p4pecirz6y2vlrngla62mxm # /subdir/ascii.txt +``` diff --git a/test/sharness/t0118-gateway-car/deterministic.car b/test/sharness/t0118-gateway-car/deterministic.car new file mode 100644 index 0000000000000000000000000000000000000000..3967f909dce9b45cc3109ef1bccb0febfaf3c964 GIT binary patch literal 127 zcmcColvurnv%3WfpBhW%hPLndXVc_T{3dI4x6g)Z xpWW$YsYS(^`FV`a#Hh|l&B@7ENGvGG$xKcx0cz7P%S+MAEXYaGOHM4}0stv?G@1Ya literal 0 HcmV?d00001 diff --git a/test/sharness/t0118-gateway-car/subdir/ascii.txt b/test/sharness/t0118-gateway-car/subdir/ascii.txt new file mode 100644 index 000000000..a2f1a843b --- /dev/null +++ b/test/sharness/t0118-gateway-car/subdir/ascii.txt @@ -0,0 +1 @@ +hello application/vnd.ipld.car diff --git a/test/sharness/t0118-gateway-car/test-dag.car b/test/sharness/t0118-gateway-car/test-dag.car new file mode 100644 index 0000000000000000000000000000000000000000..e80fa4b0756cb7c9f5ebc44242424506fb7283cb GIT binary patch literal 312 zcmcColv^5u?@7svMQ{B%`(=Of-ix^$+_m$U+s0a-OIe^X z=hdn7vecsD%=|pYC}LC#8E~n9)Saw+P!{lU+i#stX^z~mrGeJ6Qa_#6abJ&?`ByJ= zomD}It++HPC9_B(f{TfRF_tJT#z3P(g%nmX+uSVRD>}Pdpzx`&WNv8to_{t?F2!%M zR(JbssP@?{#FH}E7+o2uIXU?Xi3J5YnaPPIK>zBO<)!Fl7UZPp JB_|ef0RZo3fVKbt literal 0 HcmV?d00001 From a57ca965c1c6923efb7b11134dc6fc92d10960fa Mon Sep 17 00:00:00 2001 From: Laurent Senta Date: Mon, 20 Feb 2023 16:17:50 +0100 Subject: [PATCH 0490/1212] test: use car fixtures in sharness t0122 --- test/sharness/t0122-gateway-tar.sh | 22 ++++------- test/sharness/t0122-gateway-tar/README.md | 37 ++++++++++++++++++ test/sharness/t0122-gateway-tar/fixtures.car | Bin 0 -> 1053 bytes .../inside-root.car | Bin .../outside-root.car | Bin 5 files changed, 45 insertions(+), 14 deletions(-) create mode 100644 test/sharness/t0122-gateway-tar/README.md create mode 100644 test/sharness/t0122-gateway-tar/fixtures.car rename test/sharness/{t0122-gateway-tar-data => t0122-gateway-tar}/inside-root.car (100%) rename test/sharness/{t0122-gateway-tar-data => t0122-gateway-tar}/outside-root.car (100%) diff --git a/test/sharness/t0122-gateway-tar.sh b/test/sharness/t0122-gateway-tar.sh index 34dc1ba12..20cc1bf4c 100755 --- a/test/sharness/t0122-gateway-tar.sh +++ b/test/sharness/t0122-gateway-tar.sh @@ -10,20 +10,14 @@ test_launch_ipfs_daemon_without_network OUTSIDE_ROOT_CID="bafybeicaj7kvxpcv4neaqzwhrqqmdstu4dhrwfpknrgebq6nzcecfucvyu" INSIDE_ROOT_CID="bafybeibfevfxlvxp5vxobr5oapczpf7resxnleb7tkqmdorc4gl5cdva3y" +# Import test case +# See the static fixtures in ./t0122-gateway-tar/ test_expect_success "Add the test directory" ' - mkdir -p rootDir/ipfs && - mkdir -p rootDir/ipns && - mkdir -p rootDir/api && - mkdir -p rootDir/ą/ę && - echo "I am a txt file on path with utf8" > rootDir/ą/ę/file-źł.txt && - echo "I am a txt file in confusing /api dir" > rootDir/api/file.txt && - echo "I am a txt file in confusing /ipfs dir" > rootDir/ipfs/file.txt && - echo "I am a txt file in confusing /ipns dir" > rootDir/ipns/file.txt && - DIR_CID=$(ipfs add -Qr --cid-version 1 rootDir) && - FILE_CID=$(ipfs files stat --enc=json /ipfs/$DIR_CID/ą/ę/file-źł.txt | jq -r .Hash) && - FILE_SIZE=$(ipfs files stat --enc=json /ipfs/$DIR_CID/ą/ę/file-źł.txt | jq -r .Size) - echo "$FILE_CID / $FILE_SIZE" + ipfs dag import ../t0122-gateway-tar/fixtures.car ' +DIR_CID=bafybeig6ka5mlwkl4subqhaiatalkcleo4jgnr3hqwvpmsqfca27cijp3i # ./rootDir +FILE_CID=bafkreialihlqnf5uwo4byh4n3cmwlntwqzxxs2fg5vanqdi3d7tb2l5xkm # ./rootDir/ą/ę/file-źł.txt +FILE_SIZE=34 test_expect_success "GET TAR with format=tar and extract" ' curl "http://127.0.0.1:$GWAY_PORT/ipfs/$FILE_CID?format=tar" | tar -x @@ -69,9 +63,9 @@ test_expect_success "GET TAR with explicit ?filename= succeeds with modified Con " test_expect_success "Add CARs with relative paths to test with" ' - ipfs dag import ../t0122-gateway-tar-data/outside-root.car > import_output && + ipfs dag import ../t0122-gateway-tar/outside-root.car > import_output && test_should_contain $OUTSIDE_ROOT_CID import_output && - ipfs dag import ../t0122-gateway-tar-data/inside-root.car > import_output && + ipfs dag import ../t0122-gateway-tar/inside-root.car > import_output && test_should_contain $INSIDE_ROOT_CID import_output ' diff --git a/test/sharness/t0122-gateway-tar/README.md b/test/sharness/t0122-gateway-tar/README.md new file mode 100644 index 000000000..8b9311277 --- /dev/null +++ b/test/sharness/t0122-gateway-tar/README.md @@ -0,0 +1,37 @@ +# Dataset description/sources + +- inside-root.car + +- outside-root.car + +- fixtures.car + - raw CARv1 + +generated with: + +```sh +# ipfs version 0.18.1 + +mkdir -p rootDir/ipfs && +mkdir -p rootDir/ipns && +mkdir -p rootDir/api && +mkdir -p rootDir/ą/ę && +echo "I am a txt file on path with utf8" > rootDir/ą/ę/file-źł.txt && +echo "I am a txt file in confusing /api dir" > rootDir/api/file.txt && +echo "I am a txt file in confusing /ipfs dir" > rootDir/ipfs/file.txt && +echo "I am a txt file in confusing /ipns dir" > rootDir/ipns/file.txt && +DIR_CID=$(ipfs add -Qr --cid-version 1 rootDir) && +FILE_CID=$(ipfs files stat --enc=json /ipfs/$DIR_CID/ą/ę/file-źł.txt | jq -r .Hash) && +FILE_SIZE=$(ipfs files stat --enc=json /ipfs/$DIR_CID/ą/ę/file-źł.txt | jq -r .Size) +echo "$FILE_CID / $FILE_SIZE" + +echo DIR_CID=${DIR_CID} # ./rootDir +echo FILE_CID=${FILE_CID} # ./rootDir/ą/ę/file-źł.txt +echo FILE_SIZE=${FILE_SIZE} + +ipfs dag export ${DIR_CID} > ./fixtures.car + +# DIR_CID=bafybeig6ka5mlwkl4subqhaiatalkcleo4jgnr3hqwvpmsqfca27cijp3i # ./rootDir +# FILE_CID=bafkreialihlqnf5uwo4byh4n3cmwlntwqzxxs2fg5vanqdi3d7tb2l5xkm # ./rootDir/ą/ę/file-źł.txt +# FILE_SIZE=34 +``` diff --git a/test/sharness/t0122-gateway-tar/fixtures.car b/test/sharness/t0122-gateway-tar/fixtures.car new file mode 100644 index 0000000000000000000000000000000000000000..71a5603822741f25320438bd70823589120e313c GIT binary patch literal 1053 zcmcColvR$Z!{1TqeSN@tUjjg{Tlgc7mrAdS5w!gPn*17KH6I(#F3Vnld4xzQ6ixRGTe(8O`Zyg zxeAF2KuroD-3pm`3d#9-X{E)PdFcxJz;IJY$t>amyOUtJLEZWM>i;({85gv-W(d_V zKa@*2eN@-d)vWbj%$Z-NzS6vINbXbzxziiuPC}aSyAu>)2!|4kFsMU?&s>>u#q@K) zg=4JD+Ddu%u4<)wm#M_8IM$cG*3(nQFic@T$&fnuIuO3{I&*k2EHJEuD( zXEu8GPP(?~NTtQ!*2R(r|4!eUF1UKJ@frzWikc}A4+_gfkg)`nn?n*5x8rrT>037M zkdg1bF*9{rSzCT(#hs2>E#m S1&JjY3gwwVqO>H Date: Mon, 20 Feb 2023 16:24:57 +0100 Subject: [PATCH 0491/1212] test: use car fixtures in sharness t0123 --- test/sharness/t0123-gateway-json-cbor.sh | 21 +++------ .../t0123-gateway-json-cbor/README.md | 43 ++++++++++++++++++ .../t0123-gateway-json-cbor/fixtures.car | Bin 0 -> 1179 bytes 3 files changed, 50 insertions(+), 14 deletions(-) create mode 100644 test/sharness/t0123-gateway-json-cbor/README.md create mode 100644 test/sharness/t0123-gateway-json-cbor/fixtures.car diff --git a/test/sharness/t0123-gateway-json-cbor.sh b/test/sharness/t0123-gateway-json-cbor.sh index 704d075f9..b22c056de 100755 --- a/test/sharness/t0123-gateway-json-cbor.sh +++ b/test/sharness/t0123-gateway-json-cbor.sh @@ -7,22 +7,15 @@ test_description="Test HTTP Gateway DAG-JSON (application/vnd.ipld.dag-json) and test_init_ipfs test_launch_ipfs_daemon_without_network +# Import test case +# See the static fixtures in ./t0123-gateway-json-cbor/ test_expect_success "Add the test directory" ' - mkdir -p rootDir/ipfs && - mkdir -p rootDir/ipns && - mkdir -p rootDir/api && - mkdir -p rootDir/ą/ę && - echo "{ \"test\": \"i am a plain json file\" }" > rootDir/ą/ę/t.json && - echo "I am a txt file on path with utf8" > rootDir/ą/ę/file-źł.txt && - echo "I am a txt file in confusing /api dir" > rootDir/api/file.txt && - echo "I am a txt file in confusing /ipfs dir" > rootDir/ipfs/file.txt && - echo "I am a txt file in confusing /ipns dir" > rootDir/ipns/file.txt && - DIR_CID=$(ipfs add -Qr --cid-version 1 rootDir) && - FILE_JSON_CID=$(ipfs files stat --enc=json /ipfs/$DIR_CID/ą/ę/t.json | jq -r .Hash) && - FILE_CID=$(ipfs files stat --enc=json /ipfs/$DIR_CID/ą/ę/file-źł.txt | jq -r .Hash) && - FILE_SIZE=$(ipfs files stat --enc=json /ipfs/$DIR_CID/ą/ę/file-źł.txt | jq -r .Size) - echo "$FILE_CID / $FILE_SIZE" + ipfs dag import ../t0123-gateway-json-cbor/fixtures.car ' +DIR_CID=bafybeiafyvqlazbbbtjnn6how5d6h6l6rxbqc4qgpbmteaiskjrffmyy4a # ./rootDir +FILE_JSON_CID=bafkreibrppizs3g7axs2jdlnjua6vgpmltv7k72l7v7sa6mmht6mne3qqe # ./rootDir/ą/ę/t.json +FILE_CID=bafkreialihlqnf5uwo4byh4n3cmwlntwqzxxs2fg5vanqdi3d7tb2l5xkm # ./rootDir/ą/ę/file-źł.txt +FILE_SIZE=34 ## Quick regression check for JSON stored on UnixFS: ## it has nothing to do with DAG-JSON and JSON codecs, diff --git a/test/sharness/t0123-gateway-json-cbor/README.md b/test/sharness/t0123-gateway-json-cbor/README.md new file mode 100644 index 000000000..0d9f0e1e1 --- /dev/null +++ b/test/sharness/t0123-gateway-json-cbor/README.md @@ -0,0 +1,43 @@ +# Dataset description/sources + +- dag-cbor-traversal.car + +- dag-json-traversal.car + +- dag-pb.car + +- dag-pb.json + +- fixtures.car + - raw CARv1 + +generated with: + +```sh +mkdir -p rootDir/ipfs && +mkdir -p rootDir/ipns && +mkdir -p rootDir/api && +mkdir -p rootDir/ą/ę && +echo "{ \"test\": \"i am a plain json file\" }" > rootDir/ą/ę/t.json && +echo "I am a txt file on path with utf8" > rootDir/ą/ę/file-źł.txt && +echo "I am a txt file in confusing /api dir" > rootDir/api/file.txt && +echo "I am a txt file in confusing /ipfs dir" > rootDir/ipfs/file.txt && +echo "I am a txt file in confusing /ipns dir" > rootDir/ipns/file.txt && +DIR_CID=$(ipfs add -Qr --cid-version 1 rootDir) && +FILE_JSON_CID=$(ipfs files stat --enc=json /ipfs/$DIR_CID/ą/ę/t.json | jq -r .Hash) && +FILE_CID=$(ipfs files stat --enc=json /ipfs/$DIR_CID/ą/ę/file-źł.txt | jq -r .Hash) && +FILE_SIZE=$(ipfs files stat --enc=json /ipfs/$DIR_CID/ą/ę/file-źł.txt | jq -r .Size) +echo "$FILE_CID / $FILE_SIZE" + +echo DIR_CID=${DIR_CID} # ./rootDir +echo FILE_JSON_CID=${FILE_JSON_CID} # ./rootDir/ą/ę/t.json +echo FILE_CID=${FILE_CID} # ./rootDir/ą/ę/file-źł.txt +echo FILE_SIZE=${FILE_SIZE} + +ipfs dag export ${DIR_CID} > fixtures.car + +# DIR_CID=bafybeiafyvqlazbbbtjnn6how5d6h6l6rxbqc4qgpbmteaiskjrffmyy4a # ./rootDir +# FILE_JSON_CID=bafkreibrppizs3g7axs2jdlnjua6vgpmltv7k72l7v7sa6mmht6mne3qqe # ./rootDir/ą/ę/t.json +# FILE_CID=bafkreialihlqnf5uwo4byh4n3cmwlntwqzxxs2fg5vanqdi3d7tb2l5xkm # ./rootDir/ą/ę/file-źł.txt +# FILE_SIZE=34 +``` diff --git a/test/sharness/t0123-gateway-json-cbor/fixtures.car b/test/sharness/t0123-gateway-json-cbor/fixtures.car new file mode 100644 index 0000000000000000000000000000000000000000..8663730f2fed608271d33fd2e205c68d544e89b7 GIT binary patch literal 1179 zcmcColvR$Z!{1Tq}`!({@E*_B@ucod~pEh~Fe6+Vnh$AgCCsnVcqC`RsWVjbGnmiQ} za}^R5fSMFQx)n0>6q57v(n^an^U@Xcf#If*l3BzBb|=AbgSzwi)&Fl^GA?Lu%@C?# zekhl4`lzm@t6A&6m@~gjeWiKbkld*ba;G=QorE;ucPA*q5Dq06VNiz(pSd#Sis|Qo z3&&WQwUzSjUDZnWE>nqFajY+Wv%U0UCaex6q=}G2^B@il2gN+Wlmbmr3p)>Tspfra zzuq^&%Z+8;aog1@_L@tNFW#`M%_oCfEfAQZW=d=Wr>M!`oI_B9IV4GOJ6>m-zGd?c z8TsBDGgG&fwdGf4EPLy4gI8MqnXLZyU?E;mqR>6M>u3`=T`36}Kr|XwU!0k9pY`dI z-dtbCS2N$ly#8A6{kLABvd8AnvB?FELTn{^S;hHz5~`pWb_2yQA-m86EKFpafyI_VZ5QMu0#h}}HQ*$!q)^KR00zs~cmMzZ literal 0 HcmV?d00001 From 3ed8f394e00fb3a7dc18af567b04512db51e6dbb Mon Sep 17 00:00:00 2001 From: Laurent Senta Date: Mon, 20 Feb 2023 16:45:28 +0100 Subject: [PATCH 0492/1212] test: use car fixtures in sharness t0400 --- test/sharness/t0400-api-no-gateway.sh | 9 +++++++-- test/sharness/t0400-api-no-gateway/README.md | 15 +++++++++++++++ test/sharness/t0400-api-no-gateway/fixtures.car | Bin 0 -> 108 bytes 3 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 test/sharness/t0400-api-no-gateway/README.md create mode 100644 test/sharness/t0400-api-no-gateway/fixtures.car diff --git a/test/sharness/t0400-api-no-gateway.sh b/test/sharness/t0400-api-no-gateway.sh index 137f99a95..d0daeece3 100755 --- a/test/sharness/t0400-api-no-gateway.sh +++ b/test/sharness/t0400-api-no-gateway.sh @@ -10,6 +10,13 @@ test_description="Test API security" test_init_ipfs +# Import test case +# See the static fixtures in ./t0400-api-no-gateway/ +test_expect_success "Add the test directory" ' + ipfs dag import ../t0400-api-no-gateway/fixtures.car +' +HASH=QmNYERzV2LfD2kkfahtfv44ocHzEFK1sLBaE7zdcYT2GAZ # a file containing the string "testing" + # by default, we don't let you load arbitrary ipfs objects through the api, # because this would open up the api to scripting vulnerabilities. # only the webui objects are allowed. @@ -17,14 +24,12 @@ test_init_ipfs test_launch_ipfs_daemon test_expect_success "Gateway on API unavailable" ' - HASH=$(echo "testing" | ipfs add -q) test_curl_resp_http_code "http://127.0.0.1:$API_PORT/ipfs/$HASH" "HTTP/1.1 404 Not Found" ' test_kill_ipfs_daemon test_launch_ipfs_daemon --unrestricted-api test_expect_success "Gateway on --unrestricted-api API available" ' - HASH=$(echo "testing" | ipfs add -q) test_curl_resp_http_code "http://127.0.0.1:$API_PORT/ipfs/$HASH" "HTTP/1.1 200 OK" ' test_kill_ipfs_daemon diff --git a/test/sharness/t0400-api-no-gateway/README.md b/test/sharness/t0400-api-no-gateway/README.md new file mode 100644 index 000000000..83d184d4a --- /dev/null +++ b/test/sharness/t0400-api-no-gateway/README.md @@ -0,0 +1,15 @@ +# Dataset description/sources + +- fixtures.car + - raw CARv1 + +generated with: + +```sh +HASH=$(echo "testing" | ipfs add -q) +ipfs dag export $HASH > fixtures.car + +echo HASH=${HASH} # a file containing the string "testing" + +# HASH=QmNYERzV2LfD2kkfahtfv44ocHzEFK1sLBaE7zdcYT2GAZ # a file containing the string "testing" +``` diff --git a/test/sharness/t0400-api-no-gateway/fixtures.car b/test/sharness/t0400-api-no-gateway/fixtures.car new file mode 100644 index 0000000000000000000000000000000000000000..1e090db6dc1e7d3a07c8523de752e61dc744bd1f GIT binary patch literal 108 zcmcCmlv Date: Thu, 23 Feb 2023 11:42:51 +0100 Subject: [PATCH 0493/1212] fix: add versions --- test/sharness/t0113-gateway-symlink/README.md | 1 + test/sharness/t0114-gateway-subdomains/README.md | 2 ++ test/sharness/t0115-gateway-dir-listing/README.md | 1 + test/sharness/t0116-gateway-cache/README.md | 1 + test/sharness/t0117-gateway-block/README.md | 1 + test/sharness/t0118-gateway-car/README.md | 3 ++- test/sharness/t0123-gateway-json-cbor/README.md | 1 + test/sharness/t0400-api-no-gateway/README.md | 1 + 8 files changed, 10 insertions(+), 1 deletion(-) diff --git a/test/sharness/t0113-gateway-symlink/README.md b/test/sharness/t0113-gateway-symlink/README.md index 350405e32..31a257bdd 100644 --- a/test/sharness/t0113-gateway-symlink/README.md +++ b/test/sharness/t0113-gateway-symlink/README.md @@ -6,6 +6,7 @@ generated with: ```sh +# using ipfs version 0.18.1 mkdir testfiles && echo "content" > testfiles/foo && ln -s foo testfiles/bar && diff --git a/test/sharness/t0114-gateway-subdomains/README.md b/test/sharness/t0114-gateway-subdomains/README.md index 8f0075ccd..611bd0ed5 100644 --- a/test/sharness/t0114-gateway-subdomains/README.md +++ b/test/sharness/t0114-gateway-subdomains/README.md @@ -6,6 +6,8 @@ generated with: ```sh +# using ipfs version 0.18.1 + # CIDv0to1 is necessary because raw-leaves are enabled by default during # "ipfs add" with CIDv1 and disabled with CIDv0 CID_VAL="hello" diff --git a/test/sharness/t0115-gateway-dir-listing/README.md b/test/sharness/t0115-gateway-dir-listing/README.md index 8b6e33275..937438bcd 100644 --- a/test/sharness/t0115-gateway-dir-listing/README.md +++ b/test/sharness/t0115-gateway-dir-listing/README.md @@ -6,6 +6,7 @@ generated with: ```sh +# using ipfs version 0.18.1 mkdir -p rootDir/ipfs && mkdir -p rootDir/ipns && mkdir -p rootDir/api && diff --git a/test/sharness/t0116-gateway-cache/README.md b/test/sharness/t0116-gateway-cache/README.md index 91c438941..8b44fe640 100644 --- a/test/sharness/t0116-gateway-cache/README.md +++ b/test/sharness/t0116-gateway-cache/README.md @@ -6,6 +6,7 @@ generated with: ```sh +# using ipfs version 0.18.1 mkdir -p root2/root3/root4 && echo "hello" > root2/root3/root4/index.html && ROOT1_CID=$(ipfs add -Qrw --cid-version 1 root2) diff --git a/test/sharness/t0117-gateway-block/README.md b/test/sharness/t0117-gateway-block/README.md index 8ca237345..4ce37ae08 100644 --- a/test/sharness/t0117-gateway-block/README.md +++ b/test/sharness/t0117-gateway-block/README.md @@ -6,6 +6,7 @@ generated with: ```sh +# using ipfs version 0.18.1 mkdir -p dir && echo "hello application/vnd.ipld.raw" > dir/ascii.txt && ROOT_DIR_CID=$(ipfs add -Qrw --cid-version 1 dir) && diff --git a/test/sharness/t0118-gateway-car/README.md b/test/sharness/t0118-gateway-car/README.md index f19494833..7b81e543b 100644 --- a/test/sharness/t0118-gateway-car/README.md +++ b/test/sharness/t0118-gateway-car/README.md @@ -13,7 +13,8 @@ generated with: -```shell +```sh +# using ipfs version 0.18.1 mkdir -p subdir && echo "hello application/vnd.ipld.car" > subdir/ascii.txt && ROOT_DIR_CID=$(ipfs add -Qrw --cid-version 1 subdir) && diff --git a/test/sharness/t0123-gateway-json-cbor/README.md b/test/sharness/t0123-gateway-json-cbor/README.md index 0d9f0e1e1..4e83f42a1 100644 --- a/test/sharness/t0123-gateway-json-cbor/README.md +++ b/test/sharness/t0123-gateway-json-cbor/README.md @@ -14,6 +14,7 @@ generated with: ```sh +# using ipfs version 0.18.1 mkdir -p rootDir/ipfs && mkdir -p rootDir/ipns && mkdir -p rootDir/api && diff --git a/test/sharness/t0400-api-no-gateway/README.md b/test/sharness/t0400-api-no-gateway/README.md index 83d184d4a..32222d41b 100644 --- a/test/sharness/t0400-api-no-gateway/README.md +++ b/test/sharness/t0400-api-no-gateway/README.md @@ -6,6 +6,7 @@ generated with: ```sh +# using ipfs version 0.18.1 HASH=$(echo "testing" | ipfs add -q) ipfs dag export $HASH > fixtures.car From 92a068a82b74e453c4afea37ec4b0f3155b0d248 Mon Sep 17 00:00:00 2001 From: Laurent Senta Date: Mon, 27 Feb 2023 11:21:02 +0100 Subject: [PATCH 0494/1212] fix: remove leftover fixtures & notes --- test/sharness/t0113-gateway-symlink.sh | 1 - test/sharness/t0118-gateway-car/subdir/ascii.txt | 1 - 2 files changed, 2 deletions(-) delete mode 100644 test/sharness/t0118-gateway-car/subdir/ascii.txt diff --git a/test/sharness/t0113-gateway-symlink.sh b/test/sharness/t0113-gateway-symlink.sh index ea85b8150..29e5b960d 100755 --- a/test/sharness/t0113-gateway-symlink.sh +++ b/test/sharness/t0113-gateway-symlink.sh @@ -22,7 +22,6 @@ test_expect_success "Test the directory listing" ' test_should_contain ">bar<" list_response ' -# TODO: it's unclear to me if that `echo -n "foo" > expected` should be a fixture somehow. test_expect_success "Test the symlink" ' curl "$GWAY_ADDR/ipfs/$ROOT_DIR_CID/bar" > bar_actual && echo -n "foo" > bar_expected && diff --git a/test/sharness/t0118-gateway-car/subdir/ascii.txt b/test/sharness/t0118-gateway-car/subdir/ascii.txt deleted file mode 100644 index a2f1a843b..000000000 --- a/test/sharness/t0118-gateway-car/subdir/ascii.txt +++ /dev/null @@ -1 +0,0 @@ -hello application/vnd.ipld.car From baa9d609ec808b7c77ac98da62244444c2827fc7 Mon Sep 17 00:00:00 2001 From: Piotr Galar Date: Mon, 27 Feb 2023 13:18:11 +0100 Subject: [PATCH 0495/1212] ci: get rid of interop matrix --- .github/workflows/build.yml | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c7c17a43e..5e607b5ed 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -40,13 +40,6 @@ jobs: ipfs-interop: needs: [prepare] runs-on: ubuntu-latest - strategy: - matrix: - include: - - patterns: 'exchange-files' - - patterns: 'exchange-files' - options: '-v' - fail-fast: false defaults: run: shell: bash @@ -75,7 +68,7 @@ jobs: npm install kubo-rpc-client@^3.0.1 npm install ipfs-interop@^10.0.1 working-directory: interop - - run: npx ipfs-interop -- -t node $(ls node_modules/ipfs-interop/test/*.js | grep ${{ matrix.options }} '${{ matrix.patterns }}' | sed -e 's;node_modules/ipfs-interop/;-f ;' | tr '\n' ' ') + - run: npx ipfs-interop -- -t node env: LIBP2P_TCP_REUSEPORT: false LIBP2P_ALLOW_WEAK_RSA_KEYS: 1 From e3b17a4fe6fa584ca97bdee21bb1b5ab36a1a27b Mon Sep 17 00:00:00 2001 From: Gabe <7622243+decentralgabe@users.noreply.github.com> Date: Mon, 27 Feb 2023 06:43:20 -0800 Subject: [PATCH 0496/1212] docs: be clear about swarm.addrfilters (#9661) --- docs/config.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/config.md b/docs/config.md index 3bc558e88..76a49ba03 100644 --- a/docs/config.md +++ b/docs/config.md @@ -1542,9 +1542,9 @@ another node, even if this other node is on a different network. This may trigger netscan alerts on some hosting providers or cause strain in some setups. The `server` configuration profile fills up this list with sensible defaults, -preventing dials to all non-routable IP addresses (e.g., `192.168.0.0/16`) but -you should always check settings against your own network and/or hosting -provider. +preventing dials to all non-routable IP addresses (e.g., `/ip4/192.168.0.0/ipcidr/16`, +which is the multiaddress representation of `192.168.0.0/16`) but you should always +check settings against your own network and/or hosting provider. Default: `[]` From 1794649bf2d4f8f1607a67f25632053a4d873617 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Tue, 28 Feb 2023 02:21:50 +0100 Subject: [PATCH 0497/1212] feat(gateway): error handling improvements (500, 502, 504) (#9660) * fix(gateway): return 500 for all /ip[nf]s/id failures * fix: replace deprecated structs * chore: bump go-libipfs to version from main --- core/commands/bitswap.go | 6 +++--- docs/examples/kubo-as-a-library/go.mod | 4 ++-- docs/examples/kubo-as-a-library/go.sum | 8 ++++---- go.mod | 4 ++-- go.sum | 8 ++++---- test/cli/gateway_test.go | 10 +++++----- 6 files changed, 20 insertions(+), 20 deletions(-) diff --git a/core/commands/bitswap.go b/core/commands/bitswap.go index a7e8965b1..51c2f916d 100644 --- a/core/commands/bitswap.go +++ b/core/commands/bitswap.go @@ -11,7 +11,7 @@ import ( cidutil "github.com/ipfs/go-cidutil" cmds "github.com/ipfs/go-ipfs-cmds" bitswap "github.com/ipfs/go-libipfs/bitswap" - decision "github.com/ipfs/go-libipfs/bitswap/decision" + "github.com/ipfs/go-libipfs/bitswap/server" peer "github.com/libp2p/go-libp2p/core/peer" ) @@ -179,7 +179,7 @@ prints the ledger associated with a given peer. Arguments: []cmds.Argument{ cmds.StringArg("peer", true, false, "The PeerID (B58) of the ledger to inspect."), }, - Type: decision.Receipt{}, + Type: server.Receipt{}, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { nd, err := cmdenv.GetNode(env) if err != nil { @@ -203,7 +203,7 @@ prints the ledger associated with a given peer. return cmds.EmitOnce(res, bs.LedgerForPeer(partner)) }, Encoders: cmds.EncoderMap{ - cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *decision.Receipt) error { + cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *server.Receipt) error { fmt.Fprintf(w, "Ledger for %s\n"+ "Debt ratio:\t%f\n"+ "Exchanges:\t%d\n"+ diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index d0a229424..ed2e7a1db 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.18 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/go-libipfs v0.6.1-0.20230222011044-7b201415a176 + github.com/ipfs/go-libipfs v0.6.1-0.20230228004237-36918f45f260 github.com/ipfs/interface-go-ipfs-core v0.11.0 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.26.0 @@ -101,7 +101,7 @@ require ( github.com/ipfs/go-metrics-interface v0.0.1 // indirect github.com/ipfs/go-mfs v0.2.1 // indirect github.com/ipfs/go-namesys v0.7.0 // indirect - github.com/ipfs/go-path v0.3.0 // indirect + github.com/ipfs/go-path v0.3.1 // indirect github.com/ipfs/go-peertaskqueue v0.8.1 // indirect github.com/ipfs/go-unixfs v0.4.3 // indirect github.com/ipfs/go-unixfsnode v1.5.2 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 6a5ee2396..17793a3ff 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -569,8 +569,8 @@ github.com/ipfs/go-ipld-legacy v0.1.1 h1:BvD8PEuqwBHLTKqlGFTHSwrwFOMkVESEvwIYwR2 github.com/ipfs/go-ipld-legacy v0.1.1/go.mod h1:8AyKFCjgRPsQFf15ZQgDB8Din4DML/fOmKZkkFkrIEg= github.com/ipfs/go-ipns v0.3.0 h1:ai791nTgVo+zTuq2bLvEGmWP1M0A6kGTXUsgv/Yq67A= github.com/ipfs/go-ipns v0.3.0/go.mod h1:3cLT2rbvgPZGkHJoPO1YMJeh6LtkxopCkKFcio/wE24= -github.com/ipfs/go-libipfs v0.6.1-0.20230222011044-7b201415a176 h1:QJvWxLRKucrAo7W2vLz5FA2iLKwW6WkHWn8AL8kXAUU= -github.com/ipfs/go-libipfs v0.6.1-0.20230222011044-7b201415a176/go.mod h1:UjjDIuehp2GzlNP0HEr5I9GfFT7zWgst+YfpUEIThtw= +github.com/ipfs/go-libipfs v0.6.1-0.20230228004237-36918f45f260 h1:QRLcCoITO9ZQo2pvjmrfngqKhUKjPopBva3MVH62LT8= +github.com/ipfs/go-libipfs v0.6.1-0.20230228004237-36918f45f260/go.mod h1:3OoEQs95UkqFEf65SbRDpiMwuzI+C/jTsYQaHfBbJXI= github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= github.com/ipfs/go-log v1.0.2/go.mod h1:1MNjMxe0u6xvJZgeqbJ8vdo2TKaGwZ1a0Bpza+sr2Sk= github.com/ipfs/go-log v1.0.3/go.mod h1:OsLySYkwIbiSUR/yBTdv1qPtcE4FW3WPWk/ewz9Ru+A= @@ -598,8 +598,8 @@ github.com/ipfs/go-mfs v0.2.1/go.mod h1:Woj80iuw4ajDnIP6+seRaoHpPsc9hmL0pk/nDNDW github.com/ipfs/go-namesys v0.7.0 h1:xqosk71GIVRkFDtF2UNRcXn4LdNeo7tzuy8feHD6NbU= github.com/ipfs/go-namesys v0.7.0/go.mod h1:KYSZBVZG3VJC34EfqqJPG7T48aWgxseoMPAPA5gLyyQ= github.com/ipfs/go-path v0.2.1/go.mod h1:NOScsVgxfC/eIw4nz6OiGwK42PjaSJ4Y/ZFPn1Xe07I= -github.com/ipfs/go-path v0.3.0 h1:tkjga3MtpXyM5v+3EbRvOHEoo+frwi4oumw5K+KYWyA= -github.com/ipfs/go-path v0.3.0/go.mod h1:NOScsVgxfC/eIw4nz6OiGwK42PjaSJ4Y/ZFPn1Xe07I= +github.com/ipfs/go-path v0.3.1 h1:wkeaCWE/NTuuPGlEkLTsED5UkzfKYZpxaFFPgk8ZVLE= +github.com/ipfs/go-path v0.3.1/go.mod h1:eNLsxJEEMxn/CDzUJ6wuNl+6No6tEUhOZcPKsZsYX0E= github.com/ipfs/go-peertaskqueue v0.1.0/go.mod h1:Jmk3IyCcfl1W3jTW3YpghSwSEC6IJ3Vzz/jUmWw8Z0U= github.com/ipfs/go-peertaskqueue v0.7.0/go.mod h1:M/akTIE/z1jGNXMU7kFB4TeSEFvj68ow0Rrb04donIU= github.com/ipfs/go-peertaskqueue v0.8.1 h1:YhxAs1+wxb5jk7RvS0LHdyiILpNmRIRnZVztekOF0pg= diff --git a/go.mod b/go.mod index 00c464b9d..aae886177 100644 --- a/go.mod +++ b/go.mod @@ -45,7 +45,7 @@ require ( github.com/ipfs/go-ipld-git v0.1.1 github.com/ipfs/go-ipld-legacy v0.1.1 github.com/ipfs/go-ipns v0.3.0 - github.com/ipfs/go-libipfs v0.6.1-0.20230222011044-7b201415a176 + github.com/ipfs/go-libipfs v0.6.1-0.20230228004237-36918f45f260 github.com/ipfs/go-log v1.0.5 github.com/ipfs/go-log/v2 v2.5.1 github.com/ipfs/go-merkledag v0.9.0 @@ -53,7 +53,7 @@ require ( github.com/ipfs/go-metrics-prometheus v0.0.2 github.com/ipfs/go-mfs v0.2.1 github.com/ipfs/go-namesys v0.7.0 - github.com/ipfs/go-path v0.3.0 + github.com/ipfs/go-path v0.3.1 github.com/ipfs/go-pinning-service-http-client v0.1.2 github.com/ipfs/go-unixfs v0.4.3 github.com/ipfs/go-unixfsnode v1.5.2 diff --git a/go.sum b/go.sum index d650d704c..93c9b97a4 100644 --- a/go.sum +++ b/go.sum @@ -591,8 +591,8 @@ github.com/ipfs/go-ipld-legacy v0.1.1 h1:BvD8PEuqwBHLTKqlGFTHSwrwFOMkVESEvwIYwR2 github.com/ipfs/go-ipld-legacy v0.1.1/go.mod h1:8AyKFCjgRPsQFf15ZQgDB8Din4DML/fOmKZkkFkrIEg= github.com/ipfs/go-ipns v0.3.0 h1:ai791nTgVo+zTuq2bLvEGmWP1M0A6kGTXUsgv/Yq67A= github.com/ipfs/go-ipns v0.3.0/go.mod h1:3cLT2rbvgPZGkHJoPO1YMJeh6LtkxopCkKFcio/wE24= -github.com/ipfs/go-libipfs v0.6.1-0.20230222011044-7b201415a176 h1:QJvWxLRKucrAo7W2vLz5FA2iLKwW6WkHWn8AL8kXAUU= -github.com/ipfs/go-libipfs v0.6.1-0.20230222011044-7b201415a176/go.mod h1:UjjDIuehp2GzlNP0HEr5I9GfFT7zWgst+YfpUEIThtw= +github.com/ipfs/go-libipfs v0.6.1-0.20230228004237-36918f45f260 h1:QRLcCoITO9ZQo2pvjmrfngqKhUKjPopBva3MVH62LT8= +github.com/ipfs/go-libipfs v0.6.1-0.20230228004237-36918f45f260/go.mod h1:3OoEQs95UkqFEf65SbRDpiMwuzI+C/jTsYQaHfBbJXI= github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= github.com/ipfs/go-log v1.0.2/go.mod h1:1MNjMxe0u6xvJZgeqbJ8vdo2TKaGwZ1a0Bpza+sr2Sk= github.com/ipfs/go-log v1.0.3/go.mod h1:OsLySYkwIbiSUR/yBTdv1qPtcE4FW3WPWk/ewz9Ru+A= @@ -622,8 +622,8 @@ github.com/ipfs/go-mfs v0.2.1/go.mod h1:Woj80iuw4ajDnIP6+seRaoHpPsc9hmL0pk/nDNDW github.com/ipfs/go-namesys v0.7.0 h1:xqosk71GIVRkFDtF2UNRcXn4LdNeo7tzuy8feHD6NbU= github.com/ipfs/go-namesys v0.7.0/go.mod h1:KYSZBVZG3VJC34EfqqJPG7T48aWgxseoMPAPA5gLyyQ= github.com/ipfs/go-path v0.2.1/go.mod h1:NOScsVgxfC/eIw4nz6OiGwK42PjaSJ4Y/ZFPn1Xe07I= -github.com/ipfs/go-path v0.3.0 h1:tkjga3MtpXyM5v+3EbRvOHEoo+frwi4oumw5K+KYWyA= -github.com/ipfs/go-path v0.3.0/go.mod h1:NOScsVgxfC/eIw4nz6OiGwK42PjaSJ4Y/ZFPn1Xe07I= +github.com/ipfs/go-path v0.3.1 h1:wkeaCWE/NTuuPGlEkLTsED5UkzfKYZpxaFFPgk8ZVLE= +github.com/ipfs/go-path v0.3.1/go.mod h1:eNLsxJEEMxn/CDzUJ6wuNl+6No6tEUhOZcPKsZsYX0E= github.com/ipfs/go-peertaskqueue v0.1.0/go.mod h1:Jmk3IyCcfl1W3jTW3YpghSwSEC6IJ3Vzz/jUmWw8Z0U= github.com/ipfs/go-peertaskqueue v0.7.0/go.mod h1:M/akTIE/z1jGNXMU7kFB4TeSEFvj68ow0Rrb04donIU= github.com/ipfs/go-peertaskqueue v0.8.1 h1:YhxAs1+wxb5jk7RvS0LHdyiILpNmRIRnZVztekOF0pg= diff --git a/test/cli/gateway_test.go b/test/cli/gateway_test.go index 7139bef1b..a585925a7 100644 --- a/test/cli/gateway_test.go +++ b/test/cli/gateway_test.go @@ -126,10 +126,10 @@ func TestGateway(t *testing.T) { assert.Equal(t, 404, resp.StatusCode) }) - t.Run("GET IPFS invalid CID returns 400 (Bad Request)", func(t *testing.T) { + t.Run("GET IPFS invalid CID returns 500 (Internal Server Error)", func(t *testing.T) { t.Parallel() resp := client.Get("/ipfs/QmInvalid/pleaseDontAddMe") - assert.Equal(t, 400, resp.StatusCode) + assert.Equal(t, 500, resp.StatusCode) }) t.Run("GET IPFS inlined zero-length data object returns ok code (200)", func(t *testing.T) { @@ -166,10 +166,10 @@ func TestGateway(t *testing.T) { t.Parallel() node.IPFS("name", "publish", "--allow-offline", cid) - t.Run("GET invalid IPNS root returns 400 (Bad Request)", func(t *testing.T) { + t.Run("GET invalid IPNS root returns 500 (Internal Server Error)", func(t *testing.T) { t.Parallel() resp := client.Get("/ipns/QmInvalid/pleaseDontAddMe") - assert.Equal(t, 400, resp.StatusCode) + assert.Equal(t, 500, resp.StatusCode) }) t.Run("GET IPNS path succeeds", func(t *testing.T) { @@ -198,7 +198,7 @@ func TestGateway(t *testing.T) { t.Run("GET invalid IPFS path errors", func(t *testing.T) { t.Parallel() - assert.Equal(t, 400, client.Get("/ipfs/12345").StatusCode) + assert.Equal(t, 500, client.Get("/ipfs/12345").StatusCode) }) t.Run("GET invalid path errors", func(t *testing.T) { From 56b9962103ce5a56f15752374cd14541bc3297e9 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Tue, 28 Feb 2023 10:25:25 +1300 Subject: [PATCH 0498/1212] chore: update go-libp2p to v0.26.1 --- docs/examples/kubo-as-a-library/go.mod | 6 +++--- docs/examples/kubo-as-a-library/go.sum | 12 ++++++------ go.mod | 6 +++--- go.sum | 12 ++++++------ 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index ed2e7a1db..77dc84038 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -10,7 +10,7 @@ require ( github.com/ipfs/go-libipfs v0.6.1-0.20230228004237-36918f45f260 github.com/ipfs/interface-go-ipfs-core v0.11.0 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 - github.com/libp2p/go-libp2p v0.26.0 + github.com/libp2p/go-libp2p v0.26.1 github.com/multiformats/go-multiaddr v0.8.0 ) @@ -119,7 +119,7 @@ require ( github.com/libp2p/go-cidranger v1.1.0 // indirect github.com/libp2p/go-doh-resolver v0.4.0 // indirect github.com/libp2p/go-flow-metrics v0.1.0 // indirect - github.com/libp2p/go-libp2p-asn-util v0.2.0 // indirect + github.com/libp2p/go-libp2p-asn-util v0.3.0 // indirect github.com/libp2p/go-libp2p-kad-dht v0.21.1 // indirect github.com/libp2p/go-libp2p-kbucket v0.5.0 // indirect github.com/libp2p/go-libp2p-pubsub v0.9.0 // indirect @@ -167,7 +167,7 @@ require ( github.com/quic-go/qtls-go1-19 v0.2.1 // indirect github.com/quic-go/qtls-go1-20 v0.1.1 // indirect github.com/quic-go/quic-go v0.33.0 // indirect - github.com/quic-go/webtransport-go v0.5.1 // indirect + github.com/quic-go/webtransport-go v0.5.2 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/samber/lo v1.36.0 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 17793a3ff..6e365b6a7 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -730,10 +730,10 @@ github.com/libp2p/go-libp2p v0.7.0/go.mod h1:hZJf8txWeCduQRDC/WSqBGMxaTHCOYHt2xS github.com/libp2p/go-libp2p v0.7.4/go.mod h1:oXsBlTLF1q7pxr+9w6lqzS1ILpyHsaBPniVO7zIHGMw= github.com/libp2p/go-libp2p v0.8.1/go.mod h1:QRNH9pwdbEBpx5DTJYg+qxcVaDMAz3Ee/qDKwXujH5o= github.com/libp2p/go-libp2p v0.14.3/go.mod h1:d12V4PdKbpL0T1/gsUNN8DfgMuRPDX8bS2QxCZlwRH0= -github.com/libp2p/go-libp2p v0.26.0 h1:0FE0bP9/G9YADjruqoFvf1snBBFvrdh1MmTuEeUkl2E= -github.com/libp2p/go-libp2p v0.26.0/go.mod h1:R8N+XhwPDPLNb4TKboKJKnDeg9vPw8+zlC6g793dTGw= -github.com/libp2p/go-libp2p-asn-util v0.2.0 h1:rg3+Os8jbnO5DxkC7K/Utdi+DkY3q/d1/1q+8WeNAsw= -github.com/libp2p/go-libp2p-asn-util v0.2.0/go.mod h1:WoaWxbHKBymSN41hWSq/lGKJEca7TNm58+gGJi2WsLI= +github.com/libp2p/go-libp2p v0.26.1 h1:I9bHj5KteIB1tsBWLT25TTttx5xSjun3ph/q/8Xax/k= +github.com/libp2p/go-libp2p v0.26.1/go.mod h1:HKQUKIQ5NhzabNMWq9Wczcs5Ksdx4LQ/ISAq4MRqBHQ= +github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= +github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-autonat v0.1.0/go.mod h1:1tLf2yXxiE/oKGtDwPYWTSYG3PtvYlJmg7NeVtPRqH8= github.com/libp2p/go-libp2p-autonat v0.1.1/go.mod h1:OXqkeGOY2xJVWKAGV2inNF5aKN/djNA3fdpCWloIudE= github.com/libp2p/go-libp2p-autonat v0.2.0/go.mod h1:DX+9teU4pEEoZUqR1PiMlqliONQdNbfzE1C718tcViI= @@ -1177,8 +1177,8 @@ github.com/quic-go/qtls-go1-20 v0.1.1 h1:KbChDlg82d3IHqaj2bn6GfKRj84Per2VGf5XV3w github.com/quic-go/qtls-go1-20 v0.1.1/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= github.com/quic-go/quic-go v0.33.0 h1:ItNoTDN/Fm/zBlq769lLJc8ECe9gYaW40veHCCco7y0= github.com/quic-go/quic-go v0.33.0/go.mod h1:YMuhaAV9/jIu0XclDXwZPAsP/2Kgr5yMYhe9oxhhOFA= -github.com/quic-go/webtransport-go v0.5.1 h1:1eVb7WDWCRoaeTtFHpFBJ6WDN1bSrPrRoW6tZgSw0Ow= -github.com/quic-go/webtransport-go v0.5.1/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= +github.com/quic-go/webtransport-go v0.5.2 h1:GA6Bl6oZY+g/flt00Pnu0XtivSD8vukOu3lYhJjnGEk= +github.com/quic-go/webtransport-go v0.5.2/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= github.com/rabbitmq/amqp091-go v1.1.0/go.mod h1:ogQDLSOACsLPsIq0NpbtiifNZi2YOz0VTJ0kHRghqbM= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU= diff --git a/go.mod b/go.mod index aae886177..762a3add5 100644 --- a/go.mod +++ b/go.mod @@ -67,7 +67,7 @@ require ( 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.26.0 + github.com/libp2p/go-libp2p v0.26.1 github.com/libp2p/go-libp2p-http v0.4.0 github.com/libp2p/go-libp2p-kad-dht v0.21.1 github.com/libp2p/go-libp2p-kbucket v0.5.0 @@ -172,7 +172,7 @@ require ( github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/libp2p/go-cidranger v1.1.0 // indirect github.com/libp2p/go-flow-metrics v0.1.0 // indirect - github.com/libp2p/go-libp2p-asn-util v0.2.0 // indirect + github.com/libp2p/go-libp2p-asn-util v0.3.0 // indirect github.com/libp2p/go-libp2p-gostream v0.5.0 // indirect github.com/libp2p/go-libp2p-xor v0.1.0 // indirect github.com/libp2p/go-mplex v0.7.0 // indirect @@ -210,7 +210,7 @@ require ( github.com/quic-go/qtls-go1-19 v0.2.1 // indirect github.com/quic-go/qtls-go1-20 v0.1.1 // indirect github.com/quic-go/quic-go v0.33.0 // indirect - github.com/quic-go/webtransport-go v0.5.1 // indirect + github.com/quic-go/webtransport-go v0.5.2 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/rs/cors v1.7.0 // indirect github.com/samber/lo v1.36.0 // indirect diff --git a/go.sum b/go.sum index 93c9b97a4..13c15ccc8 100644 --- a/go.sum +++ b/go.sum @@ -760,10 +760,10 @@ github.com/libp2p/go-libp2p v0.7.0/go.mod h1:hZJf8txWeCduQRDC/WSqBGMxaTHCOYHt2xS github.com/libp2p/go-libp2p v0.7.4/go.mod h1:oXsBlTLF1q7pxr+9w6lqzS1ILpyHsaBPniVO7zIHGMw= github.com/libp2p/go-libp2p v0.8.1/go.mod h1:QRNH9pwdbEBpx5DTJYg+qxcVaDMAz3Ee/qDKwXujH5o= github.com/libp2p/go-libp2p v0.14.3/go.mod h1:d12V4PdKbpL0T1/gsUNN8DfgMuRPDX8bS2QxCZlwRH0= -github.com/libp2p/go-libp2p v0.26.0 h1:0FE0bP9/G9YADjruqoFvf1snBBFvrdh1MmTuEeUkl2E= -github.com/libp2p/go-libp2p v0.26.0/go.mod h1:R8N+XhwPDPLNb4TKboKJKnDeg9vPw8+zlC6g793dTGw= -github.com/libp2p/go-libp2p-asn-util v0.2.0 h1:rg3+Os8jbnO5DxkC7K/Utdi+DkY3q/d1/1q+8WeNAsw= -github.com/libp2p/go-libp2p-asn-util v0.2.0/go.mod h1:WoaWxbHKBymSN41hWSq/lGKJEca7TNm58+gGJi2WsLI= +github.com/libp2p/go-libp2p v0.26.1 h1:I9bHj5KteIB1tsBWLT25TTttx5xSjun3ph/q/8Xax/k= +github.com/libp2p/go-libp2p v0.26.1/go.mod h1:HKQUKIQ5NhzabNMWq9Wczcs5Ksdx4LQ/ISAq4MRqBHQ= +github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= +github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-autonat v0.1.0/go.mod h1:1tLf2yXxiE/oKGtDwPYWTSYG3PtvYlJmg7NeVtPRqH8= github.com/libp2p/go-libp2p-autonat v0.1.1/go.mod h1:OXqkeGOY2xJVWKAGV2inNF5aKN/djNA3fdpCWloIudE= github.com/libp2p/go-libp2p-autonat v0.2.0/go.mod h1:DX+9teU4pEEoZUqR1PiMlqliONQdNbfzE1C718tcViI= @@ -1227,8 +1227,8 @@ github.com/quic-go/qtls-go1-20 v0.1.1 h1:KbChDlg82d3IHqaj2bn6GfKRj84Per2VGf5XV3w github.com/quic-go/qtls-go1-20 v0.1.1/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= github.com/quic-go/quic-go v0.33.0 h1:ItNoTDN/Fm/zBlq769lLJc8ECe9gYaW40veHCCco7y0= github.com/quic-go/quic-go v0.33.0/go.mod h1:YMuhaAV9/jIu0XclDXwZPAsP/2Kgr5yMYhe9oxhhOFA= -github.com/quic-go/webtransport-go v0.5.1 h1:1eVb7WDWCRoaeTtFHpFBJ6WDN1bSrPrRoW6tZgSw0Ow= -github.com/quic-go/webtransport-go v0.5.1/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= +github.com/quic-go/webtransport-go v0.5.2 h1:GA6Bl6oZY+g/flt00Pnu0XtivSD8vukOu3lYhJjnGEk= +github.com/quic-go/webtransport-go v0.5.2/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= github.com/rabbitmq/amqp091-go v1.1.0/go.mod h1:ogQDLSOACsLPsIq0NpbtiifNZi2YOz0VTJ0kHRghqbM= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU= From 145795b14815cc2a0b6f1599ca734966b3bcebf6 Mon Sep 17 00:00:00 2001 From: Gus Eggert Date: Mon, 27 Feb 2023 17:42:15 -0500 Subject: [PATCH 0499/1212] test: port rcmgr sharness tests to Go --- test/cli/harness/node.go | 13 + test/cli/harness/run.go | 4 + test/cli/rcmgr_test.go | 377 +++++++++++++++++++++++++++++ test/sharness/t0139-swarm-rcmgr.sh | 284 ---------------------- 4 files changed, 394 insertions(+), 284 deletions(-) create mode 100644 test/cli/rcmgr_test.go delete mode 100755 test/sharness/t0139-swarm-rcmgr.sh diff --git a/test/cli/harness/node.go b/test/cli/harness/node.go index 26a66ddd9..e486771ca 100644 --- a/test/cli/harness/node.go +++ b/test/cli/harness/node.go @@ -1,6 +1,7 @@ package harness import ( + "bytes" "encoding/json" "errors" "fmt" @@ -62,6 +63,18 @@ func BuildNode(ipfsBin, baseDir string, id int) *Node { } } +func (n *Node) WriteBytes(filename string, b []byte) { + f, err := os.Create(filepath.Join(n.Dir, filename)) + if err != nil { + panic(err) + } + defer f.Close() + _, err = io.Copy(f, bytes.NewReader(b)) + if err != nil { + panic(err) + } +} + func (n *Node) ReadConfig() *config.Config { cfg, err := serial.Load(filepath.Join(n.Dir, "config")) if err != nil { diff --git a/test/cli/harness/run.go b/test/cli/harness/run.go index 1a6b32fc2..9cbb871bc 100644 --- a/test/cli/harness/run.go +++ b/test/cli/harness/run.go @@ -38,6 +38,10 @@ type RunResult struct { Cmd *exec.Cmd } +func (r *RunResult) ExitCode() int { + return r.Cmd.ProcessState.ExitCode() +} + func environToMap(environ []string) map[string]string { m := map[string]string{} for _, e := range environ { diff --git a/test/cli/rcmgr_test.go b/test/cli/rcmgr_test.go new file mode 100644 index 000000000..23e123655 --- /dev/null +++ b/test/cli/rcmgr_test.go @@ -0,0 +1,377 @@ +package cli + +import ( + "encoding/json" + "testing" + + "github.com/ipfs/kubo/config" + "github.com/ipfs/kubo/core/node/libp2p" + "github.com/ipfs/kubo/test/cli/harness" + rcmgr "github.com/libp2p/go-libp2p/p2p/host/resource-manager" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestRcmgr(t *testing.T) { + t.Parallel() + + t.Run("Resource manager disabled", func(t *testing.T) { + t.Parallel() + node := harness.NewT(t).NewNode().Init() + node.UpdateConfig(func(cfg *config.Config) { + cfg.Swarm.ResourceMgr.Enabled = config.False + }) + + node.StartDaemon() + + t.Run("swarm limit should fail", func(t *testing.T) { + res := node.RunIPFS("swarm", "limit", "system") + assert.Equal(t, 1, res.ExitCode()) + assert.Contains(t, res.Stderr.Lines()[0], "missing ResourceMgr") + }) + t.Run("swarm stats should fail", func(t *testing.T) { + res := node.RunIPFS("swarm", "stats", "all") + assert.Equal(t, 1, res.ExitCode()) + assert.Contains(t, res.Stderr.Lines()[0], "missing ResourceMgr") + }) + }) + + t.Run("Node in offline mode", func(t *testing.T) { + t.Parallel() + node := harness.NewT(t).NewNode().Init() + node.UpdateConfig(func(cfg *config.Config) { + cfg.Swarm.ResourceMgr.Enabled = config.False + }) + node.StartDaemon() + + t.Run("swarm limit should fail", func(t *testing.T) { + res := node.RunIPFS("swarm", "limit", "system") + assert.Equal(t, 1, res.ExitCode()) + assert.Contains(t, res.Stderr.Lines()[0], "missing ResourceMgr") + }) + t.Run("swarm stats should fail", func(t *testing.T) { + res := node.RunIPFS("swarm", "stats", "all") + assert.Equal(t, 1, res.ExitCode()) + assert.Contains(t, res.Stderr.Lines()[0], "missing ResourceMgr") + }) + }) + + t.Run("Very high connmgr highwater", func(t *testing.T) { + node := harness.NewT(t).NewNode().Init() + node.UpdateConfig(func(cfg *config.Config) { + cfg.Swarm.ConnMgr.HighWater = config.NewOptionalInteger(1000) + }) + node.StartDaemon() + + res := node.RunIPFS("swarm", "limit", "system", "--enc=json") + require.Equal(t, 0, res.ExitCode()) + limits := unmarshalLimits(t, res.Stdout.Bytes()) + + assert.GreaterOrEqual(t, limits.ConnsInbound, 2000) + assert.GreaterOrEqual(t, limits.StreamsInbound, 2000) + }) + + t.Run("default configuration", func(t *testing.T) { + t.Parallel() + node := harness.NewT(t).NewNode().Init() + node.UpdateConfig(func(cfg *config.Config) { + cfg.Swarm.ConnMgr.HighWater = config.NewOptionalInteger(1000) + }) + node.StartDaemon() + + t.Run("conns and streams are above 800 for default connmgr settings", func(t *testing.T) { + res := node.RunIPFS("swarm", "limit", "system", "--enc=json") + require.Equal(t, 0, res.ExitCode()) + limits := unmarshalLimits(t, res.Stdout.Bytes()) + + assert.GreaterOrEqual(t, limits.ConnsInbound, 800) + assert.GreaterOrEqual(t, limits.StreamsInbound, 800) + }) + + t.Run("limits|stats should succeed", func(t *testing.T) { + res := node.RunIPFS("swarm", "limit", "all") + assert.Equal(t, 0, res.ExitCode()) + + limits := map[string]rcmgr.ResourceLimits{} + err := json.Unmarshal(res.Stdout.Bytes(), &limits) + require.NoError(t, err) + + assert.Greater(t, limits["System"].Memory, int64(0)) + assert.Greater(t, limits["System"].FD, 0) + assert.Greater(t, limits["System"].Conns, 0) + assert.Greater(t, limits["System"].ConnsInbound, 0) + assert.Greater(t, limits["System"].ConnsOutbound, 0) + assert.Greater(t, limits["System"].Streams, 0) + assert.Greater(t, limits["System"].StreamsInbound, 0) + assert.Greater(t, limits["System"].StreamsOutbound, 0) + assert.Greater(t, limits["Transient"].Memory, int64(0)) + }) + + t.Run("resetting limits should produce the same default limits", func(t *testing.T) { + resetRes := node.RunIPFS("swarm", "limit", "system", "--reset", "--enc=json") + require.Equal(t, 0, resetRes.ExitCode()) + limitRes := node.RunIPFS("swarm", "limit", "system", "--enc=json") + require.Equal(t, 0, limitRes.ExitCode()) + + assert.Equal(t, resetRes.Stdout.Bytes(), limitRes.Stdout.Bytes()) + }) + + t.Run("swarm stats system with filter should fail", func(t *testing.T) { + res := node.RunIPFS("swarm", "stats", "system", "--min-used-limit-perc=99") + assert.Equal(t, 1, res.ExitCode()) + assert.Contains(t, res.Stderr.Lines()[0], `Error: "min-used-limit-perc" can only be used when scope is "all"`) + }) + + t.Run("swarm limit reset on map values should work", func(t *testing.T) { + resetRes := node.RunIPFS("swarm", "limit", "peer:12D3KooWL7i1T9VSPeF8AgQApbyM51GNKZsYPvNvL347aMDmvNzG", "--reset", "--enc=json") + require.Equal(t, 0, resetRes.ExitCode()) + limitRes := node.RunIPFS("swarm", "limit", "peer:12D3KooWL7i1T9VSPeF8AgQApbyM51GNKZsYPvNvL347aMDmvNzG", "--enc=json") + require.Equal(t, 0, limitRes.ExitCode()) + + assert.Equal(t, resetRes.Stdout.Bytes(), limitRes.Stdout.Bytes()) + }) + + t.Run("scope is required using reset flags", func(t *testing.T) { + res := node.RunIPFS("swarm", "limit", "--reset") + assert.Equal(t, 1, res.ExitCode()) + assert.Contains(t, res.Stderr.Lines()[0], `Error: argument "scope" is required`) + }) + + t.Run("swarm stats works", func(t *testing.T) { + res := node.RunIPFS("swarm", "stats", "all", "--enc=json") + require.Equal(t, 0, res.ExitCode()) + + stats := libp2p.NetStatOut{} + err := json.Unmarshal(res.Stdout.Bytes(), &stats) + require.NoError(t, err) + + // every scope has the same fields, so we only inspect system + assert.Equal(t, rcmgr.LimitVal64(0), stats.System.Memory) + assert.Equal(t, rcmgr.LimitVal(0), stats.System.FD) + assert.Equal(t, rcmgr.LimitVal(0), stats.System.Conns) + assert.Equal(t, rcmgr.LimitVal(0), stats.System.ConnsInbound) + assert.Equal(t, rcmgr.LimitVal(0), stats.System.ConnsOutbound) + assert.Equal(t, rcmgr.LimitVal(0), stats.System.Streams) + assert.Equal(t, rcmgr.LimitVal(0), stats.System.StreamsInbound) + assert.Equal(t, rcmgr.LimitVal(0), stats.System.StreamsOutbound) + assert.Equal(t, rcmgr.LimitVal64(0), stats.Transient.Memory) + }) + }) + + t.Run("set system conns limit while daemon is not running", func(t *testing.T) { + node := harness.NewT(t).NewNode().Init() + res := node.RunIPFS("config", "--json", "Swarm.ResourceMgr.Limits.System.Conns", "99999") + require.Equal(t, 0, res.ExitCode()) + + t.Run("set an invalid limit which should result in a failure", func(t *testing.T) { + res := node.RunIPFS("config", "--json", "Swarm.ResourceMgr.Limits.System.Conns", "asdf") + assert.Equal(t, 1, res.ExitCode()) + assert.Contains(t, res.Stderr.String(), "failed to unmarshal") + }) + + node.StartDaemon() + + t.Run("new system conns limit is applied", func(t *testing.T) { + res := node.RunIPFS("swarm", "limit", "system", "--enc=json") + limits := unmarshalLimits(t, res.Stdout.Bytes()) + assert.Equal(t, limits.Conns, rcmgr.LimitVal(99999)) + }) + }) + + t.Run("set the system memory limit while the daemon is running", func(t *testing.T) { + node := harness.NewT(t).NewNode().Init().StartDaemon() + updateLimitsWithFile(t, node, "system", func(limits *rcmgr.ResourceLimits) { + limits.Memory = 99998 + }) + + assert.Equal(t, rcmgr.LimitVal64(99998), node.ReadConfig().Swarm.ResourceMgr.Limits.System.Memory) + + res := node.RunIPFS("swarm", "limit", "system", "--enc=json") + limits := unmarshalLimits(t, res.Stdout.Bytes()) + assert.Equal(t, rcmgr.LimitVal64(99998), limits.Memory) + }) + + t.Run("smoke test transient scope", func(t *testing.T) { + node := harness.NewT(t).NewNode().Init().StartDaemon() + updateLimitsWithFile(t, node, "transient", func(limits *rcmgr.ResourceLimits) { + limits.Memory = 88888 + }) + + res := node.RunIPFS("swarm", "limit", "transient", "--enc=json") + limits := unmarshalLimits(t, res.Stdout.Bytes()) + assert.Equal(t, rcmgr.LimitVal64(88888), limits.Memory) + }) + + t.Run("smoke test service scope", func(t *testing.T) { + node := harness.NewT(t).NewNode().Init().StartDaemon() + updateLimitsWithFile(t, node, "svc:foo", func(limits *rcmgr.ResourceLimits) { + limits.Memory = 77777 + }) + + res := node.RunIPFS("swarm", "limit", "svc:foo", "--enc=json") + limits := unmarshalLimits(t, res.Stdout.Bytes()) + assert.Equal(t, rcmgr.LimitVal64(77777), limits.Memory) + }) + + t.Run("smoke test protocol scope", func(t *testing.T) { + node := harness.NewT(t).NewNode().Init().StartDaemon() + updateLimitsWithFile(t, node, "proto:foo", func(limits *rcmgr.ResourceLimits) { + limits.Memory = 66666 + }) + + res := node.RunIPFS("swarm", "limit", "proto:foo", "--enc=json") + limits := unmarshalLimits(t, res.Stdout.Bytes()) + assert.Equal(t, rcmgr.LimitVal64(66666), limits.Memory) + }) + + t.Run("smoke test peer scope", func(t *testing.T) { + validPeerID := "QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN" + node := harness.NewT(t).NewNode().Init().StartDaemon() + updateLimitsWithFile(t, node, "peer:"+validPeerID, func(limits *rcmgr.ResourceLimits) { + limits.Memory = 66666 + }) + + res := node.RunIPFS("swarm", "limit", "peer:"+validPeerID, "--enc=json") + limits := unmarshalLimits(t, res.Stdout.Bytes()) + assert.Equal(t, rcmgr.LimitVal64(66666), limits.Memory) + + t.Parallel() + + t.Run("getting limit for invalid peer ID fails", func(t *testing.T) { + res := node.RunIPFS("swarm", "limit", "peer:foo") + assert.Equal(t, 1, res.ExitCode()) + assert.Contains(t, res.Stderr.String(), "invalid peer ID") + }) + + t.Run("setting limit for invalid peer ID fails", func(t *testing.T) { + filename := "invalid-peer-id.json" + node.WriteBytes(filename, []byte(`{"Memory":"99"}`)) + res := node.RunIPFS("swarm", "limit", "peer:foo", filename) + assert.Equal(t, 1, res.ExitCode()) + assert.Contains(t, res.Stderr.String(), "invalid peer ID") + }) + }) + + t.Run("", func(t *testing.T) { + nodes := harness.NewT(t).NewNodes(3).Init() + node0, node1, node2 := nodes[0], nodes[1], nodes[2] + // peerID0, peerID1, peerID2 := node0.PeerID(), node1.PeerID(), node2.PeerID() + peerID1, peerID2 := node1.PeerID().String(), node2.PeerID().String() + + node0.UpdateConfig(func(cfg *config.Config) { + cfg.Swarm.ResourceMgr.Enabled = config.True + cfg.Swarm.ResourceMgr.Allowlist = []string{"/ip4/0.0.0.0/ipcidr/0/p2p/" + peerID2} + }) + + nodes.StartDaemons() + + // change system limits on node 0 + updateLimitsWithFile(t, node0, "system", func(limits *rcmgr.ResourceLimits) { + limits.Conns = rcmgr.BlockAllLimit + limits.ConnsInbound = rcmgr.BlockAllLimit + limits.ConnsOutbound = rcmgr.BlockAllLimit + }) + + t.Parallel() + t.Run("node 0 should fail to connect to node 1", func(t *testing.T) { + res := node0.Runner.Run(harness.RunRequest{ + Path: node0.IPFSBin, + Args: []string{"swarm", "connect", node1.SwarmAddrs()[0].String()}, + }) + assert.Equal(t, 1, res.ExitCode()) + assert.Contains(t, res.Stderr.String(), "failed to find any peer in table") + }) + + t.Run("node 0 should connect to node 2 since it is allowlisted", func(t *testing.T) { + res := node0.Runner.Run(harness.RunRequest{ + Path: node0.IPFSBin, + Args: []string{"swarm", "connect", node2.SwarmAddrs()[0].String()}, + }) + assert.Equal(t, 0, res.ExitCode()) + }) + + t.Run("node 0 should fail to ping node 1", func(t *testing.T) { + res := node0.RunIPFS("ping", "-n2", peerID1) + assert.Equal(t, 1, res.ExitCode()) + assert.Contains(t, res.Stderr.String(), "Error: ping failed") + }) + + t.Run("node 0 should be able to ping node 2", func(t *testing.T) { + res := node0.RunIPFS("ping", "-n2", peerID2) + assert.Equal(t, 0, res.ExitCode()) + }) + }) + + t.Run("daemon should refuse to start if connmgr.highwater < resources inbound", func(t *testing.T) { + t.Parallel() + t.Run("system conns", func(t *testing.T) { + node := harness.NewT(t).NewNode().Init() + node.UpdateConfig(func(cfg *config.Config) { + cfg.Swarm.ResourceMgr.Limits = &rcmgr.PartialLimitConfig{} + cfg.Swarm.ResourceMgr.Limits.System.Conns = 128 + cfg.Swarm.ConnMgr.HighWater = config.NewOptionalInteger(128) + cfg.Swarm.ConnMgr.LowWater = config.NewOptionalInteger(64) + }) + + res := node.RunIPFS("daemon") + assert.Equal(t, 1, res.ExitCode()) + }) + t.Run("system conns inbound", func(t *testing.T) { + node := harness.NewT(t).NewNode().Init() + node.UpdateConfig(func(cfg *config.Config) { + cfg.Swarm.ResourceMgr.Limits = &rcmgr.PartialLimitConfig{} + cfg.Swarm.ResourceMgr.Limits.System.ConnsInbound = 128 + cfg.Swarm.ConnMgr.HighWater = config.NewOptionalInteger(128) + cfg.Swarm.ConnMgr.LowWater = config.NewOptionalInteger(64) + }) + + res := node.RunIPFS("daemon") + assert.Equal(t, 1, res.ExitCode()) + }) + t.Run("system streams", func(t *testing.T) { + node := harness.NewT(t).NewNode().Init() + node.UpdateConfig(func(cfg *config.Config) { + cfg.Swarm.ResourceMgr.Limits = &rcmgr.PartialLimitConfig{} + cfg.Swarm.ResourceMgr.Limits.System.Streams = 128 + cfg.Swarm.ConnMgr.HighWater = config.NewOptionalInteger(128) + cfg.Swarm.ConnMgr.LowWater = config.NewOptionalInteger(64) + }) + + res := node.RunIPFS("daemon") + assert.Equal(t, 1, res.ExitCode()) + }) + t.Run("system streams inbound", func(t *testing.T) { + node := harness.NewT(t).NewNode().Init() + node.UpdateConfig(func(cfg *config.Config) { + cfg.Swarm.ResourceMgr.Limits = &rcmgr.PartialLimitConfig{} + cfg.Swarm.ResourceMgr.Limits.System.StreamsInbound = 128 + cfg.Swarm.ConnMgr.HighWater = config.NewOptionalInteger(128) + cfg.Swarm.ConnMgr.LowWater = config.NewOptionalInteger(64) + }) + + res := node.RunIPFS("daemon") + assert.Equal(t, 1, res.ExitCode()) + }) + }) +} + +func updateLimitsWithFile(t *testing.T, node *harness.Node, limit string, f func(*rcmgr.ResourceLimits)) { + filename := limit + ".json" + res := node.RunIPFS("swarm", "limit", limit) + limits := unmarshalLimits(t, res.Stdout.Bytes()) + + f(limits) + + limitsOut, err := json.Marshal(limits) + require.NoError(t, err) + node.WriteBytes(filename, limitsOut) + res = node.RunIPFS("swarm", "limit", limit, filename) + assert.Equal(t, 0, res.ExitCode()) +} + +func unmarshalLimits(t *testing.T, b []byte) *rcmgr.ResourceLimits { + limits := &rcmgr.ResourceLimits{} + err := json.Unmarshal(b, limits) + require.NoError(t, err) + return limits +} diff --git a/test/sharness/t0139-swarm-rcmgr.sh b/test/sharness/t0139-swarm-rcmgr.sh deleted file mode 100755 index d450c0908..000000000 --- a/test/sharness/t0139-swarm-rcmgr.sh +++ /dev/null @@ -1,284 +0,0 @@ -#!/usr/bin/env bash -# -test_description="Test ipfs swarm ResourceMgr config and commands" - -. lib/test-lib.sh - -test_init_ipfs - -test_expect_success 'Disable resource manager' ' - ipfs config --bool Swarm.ResourceMgr.Enabled false -' - -# test correct behavior when resource manager is disabled -test_launch_ipfs_daemon - -test_expect_success 'Swarm limit should fail since RM is disabled' ' - test_expect_code 1 ipfs swarm limit system 2> actual && - test_should_contain "missing ResourceMgr" actual -' - -test_expect_success 'Swarm stats should fail since RM is disabled' ' - test_expect_code 1 ipfs swarm stats all 2> actual && - test_should_contain "missing ResourceMgr" actual -' - -test_kill_ipfs_daemon - -test_expect_success 'Enable resource manager' ' - ipfs config --bool Swarm.ResourceMgr.Enabled true -' - -# 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 -' - -# test sanity scaling -test_expect_success 'set very high connmgr highwater' ' - ipfs config --json Swarm.ConnMgr.HighWater 1000 -' - -test_launch_ipfs_daemon - -test_expect_success 'conns and streams are above 2000' ' - ipfs swarm limit system --enc=json | tee json && - [ "$(jq -r .ConnsInbound < json)" -ge 2000 ] && - [ "$(jq -r .StreamsInbound < json)" -ge 2000 ] -' - -test_kill_ipfs_daemon - -test_expect_success 'set previous connmgr highwater' ' - ipfs config --json Swarm.ConnMgr.HighWater 96 -' - -test_launch_ipfs_daemon - -test_expect_success 'conns and streams are above 800' ' - ipfs swarm limit system --enc=json | tee json && - [ "$(jq -r .ConnsInbound < json)" -ge 800 ] && - [ "$(jq -r .StreamsInbound < json)" -ge 800 ] -' - -# swarm limit|stats should succeed in online mode by default -# because Resource Manager is opt-out - -# 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 -' -test_expect_success 'ResourceMgr enabled: swarm limit reset' ' - ipfs swarm limit system --reset --enc=json 2> reset && - ipfs swarm limit system --enc=json 2> actual && - test_cmp reset actual -' - -test_expect_success 'Swarm stats system with filter should fail' ' - test_expect_code 1 ipfs swarm stats system --min-used-limit-perc=99 2> actual && - test_should_contain "Error: \"min-used-limit-perc\" can only be used when scope is \"all\"" actual -' - -test_expect_success 'ResourceMgr enabled: swarm limit reset on map values' ' - ipfs swarm limit peer:12D3KooWL7i1T9VSPeF8AgQApbyM51GNKZsYPvNvL347aMDmvNzG --reset --enc=json 2> reset && - ipfs swarm limit peer:12D3KooWL7i1T9VSPeF8AgQApbyM51GNKZsYPvNvL347aMDmvNzG --enc=json 2> actual && - test_cmp reset actual -' - -test_expect_success 'ResourceMgr enabled: scope is required using reset flag' ' - test_expect_code 1 ipfs swarm limit --reset 2> actual && - test_should_contain "Error: argument \"scope\" is required" actual -' - -test_expect_success 'connected: swarm stats all working properly' ' - test_expect_code 0 ipfs swarm stats all -' - -# 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.FD < json && - jq -e .System.Conns < json && - jq -e .System.ConnsInbound < json && - jq -e .System.ConnsOutbound < json && - jq -e .System.Streams < json && - jq -e .System.StreamsInbound < json && - jq -e .System.StreamsOutbound < json && - jq -e .Transient.Memory < json -' - -# shut down the daemon, set a limit in the config, and verify that it's applied -test_kill_ipfs_daemon - -test_expect_success "Set system conns limit while daemon is not running" " - ipfs config --json Swarm.ResourceMgr.Limits.System.Conns 99999 -" - -test_expect_success "Set an invalid limit, which should result in a failure" " - test_expect_code 1 ipfs config --json Swarm.ResourceMgr.Limits.System.Conns 'asdf' 2> actual && - test_should_contain 'failed to unmarshal' actual -" - -test_launch_ipfs_daemon - -test_expect_success 'Ensure the new system conns limit is applied' ' - ipfs swarm limit system --enc=json | tee json && - jq -e ".Conns == 99999" < json -' - -test_expect_success 'Set system memory limit while the daemon is running' ' - ipfs swarm limit system | jq ".Memory = 99998" > system.json && - ipfs swarm limit system system.json -' - -test_expect_success 'The new system limits were written to the config' ' - jq -e ".Swarm.ResourceMgr.Limits.System.Memory == \"99998\"" < "$IPFS_PATH/config" -' - -test_expect_success 'The new system limits are in the swarm limit output' ' - ipfs swarm limit system --enc=json | jq -e ".Memory == \"99998\"" -' - -# now test all the other scopes -test_expect_success 'Set limit on transient scope' ' - ipfs swarm limit transient | jq ".Memory = 88888" > transient.json && - ipfs swarm limit transient transient.json && - jq -e ".Swarm.ResourceMgr.Limits.Transient.Memory == \"88888\"" < "$IPFS_PATH/config" && - ipfs swarm limit transient --enc=json | tee limits && - jq -e ".Memory == \"88888\"" < limits -' - -test_expect_success 'Set limit on service scope' ' - ipfs swarm limit svc:foo | jq ".Memory = 77777" > service-foo.json && - ipfs swarm limit svc:foo service-foo.json --enc=json && - jq -e ".Swarm.ResourceMgr.Limits.Service.foo.Memory == \"77777\"" < "$IPFS_PATH/config" && - ipfs swarm limit svc:foo --enc=json | tee limits && - jq -e ".Memory == \"77777\"" < limits -' - -test_expect_success 'Set limit on protocol scope' ' - ipfs swarm limit proto:foo | jq ".Memory = 66666" > proto-foo.json && - ipfs swarm limit proto:foo proto-foo.json --enc=json && - jq -e ".Swarm.ResourceMgr.Limits.Protocol.foo.Memory == \"66666\"" < "$IPFS_PATH/config" && - ipfs swarm limit proto:foo --enc=json | tee limits && - jq -e ".Memory == \"66666\"" < limits -' - -# any valid peer id -PEER_ID=QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN - -test_expect_success 'Set limit on peer scope' ' - ipfs swarm limit peer:$PEER_ID | jq ".Memory = 66666" > peer-$PEER_ID.json && - ipfs swarm limit peer:$PEER_ID peer-$PEER_ID.json --enc=json && - jq -e ".Swarm.ResourceMgr.Limits.Peer.${PEER_ID}.Memory == \"66666\"" < "$IPFS_PATH/config" && - ipfs swarm limit peer:$PEER_ID --enc=json | tee limits && - jq -e ".Memory == \"66666\"" < limits -' - -test_expect_success 'Get limit for peer scope with an invalid peer ID' ' - test_expect_code 1 ipfs swarm limit peer:foo 2> actual && - test_should_contain "invalid peer ID" actual -' - -test_expect_success 'Set limit for peer scope with an invalid peer ID' ' - echo "{\"Memory\": 99}" > invalid-peer-id.json && - test_expect_code 1 ipfs swarm limit peer:foo invalid-peer-id.json 2> actual && - test_should_contain "invalid peer ID" actual -' - -test_kill_ipfs_daemon - -## Test allowlist - -test_expect_success 'init iptb' ' - iptb testbed create -type localipfs -count 3 -init -' - -test_expect_success 'peer ids' ' - PEERID_0=$(iptb attr get 0 id) && - PEERID_1=$(iptb attr get 1 id) && - PEERID_2=$(iptb attr get 2 id) -' - -#enable resource manager -test_expect_success 'enable RCMGR' ' - ipfsi 0 config --bool Swarm.ResourceMgr.Enabled true && - ipfsi 0 config --json Swarm.ResourceMgr.Allowlist "[\"/ip4/0.0.0.0/ipcidr/0/p2p/$PEERID_2\"]" -' - -test_expect_success 'start nodes' ' - iptb start -wait [0-2] -' - -test_expect_success "change system limits on node 0" ' - ipfsi 0 swarm limit system | jq ". + {Conns: 0,ConnsInbound: 0, ConnsOutbound: 0}" > system.json && - ipfsi 0 swarm limit system system.json -' - -test_expect_success "node 0 fails to connect to 1" ' - test_expect_code 1 iptb connect 0 1 -' - -test_expect_success "node 0 connects to 2 because it's allowlisted" ' - iptb connect 0 2 -' - -test_expect_success "node 0 fails to ping 1" ' - test_expect_code 1 ipfsi 0 ping -n2 -- "$PEERID_1" 2> actual && - test_should_contain "Error: ping failed" actual -' - -test_expect_success "node 1 can ping 2" ' - ipfsi 0 ping -n2 -- "$PEERID_2" -' - -test_expect_success 'stop iptb' ' - iptb stop 0 && - iptb stop 1 && - iptb stop 2 -' - -## Test daemon refuse to start if connmgr.highwater < ressources inbound - -test_expect_success "node refuse to start if Swarm.ResourceMgr.Limits.System.Conns <= Swarm.ConnMgr.HighWater" ' - ipfs config --json Swarm.ResourceMgr.Limits.System.Conns 128 && - ipfs config --json Swarm.ConnMgr.HighWater 128 && - ipfs config --json Swarm.ConnMgr.LowWater 64 && - test_expect_code 1 ipfs daemon && - ipfs config --json Swarm.ResourceMgr.Limits.System.Conns 256 -' - -test_expect_success "node refuse to start if Swarm.ResourceMgr.Limits.System.ConnsInbound <= Swarm.ConnMgr.HighWater" ' - ipfs config --json Swarm.ResourceMgr.Limits.System.ConnsInbound 128 && - test_expect_code 1 ipfs daemon && - ipfs config --json Swarm.ResourceMgr.Limits.System.ConnsInbound 256 -' - -test_expect_success "node refuse to start if Swarm.ResourceMgr.Limits.System.Streams <= Swarm.ConnMgr.HighWater" ' - ipfs config --json Swarm.ResourceMgr.Limits.System.Streams 128 && - test_expect_code 1 ipfs daemon && - ipfs config --json Swarm.ResourceMgr.Limits.System.Streams 256 -' - -test_expect_success "node refuse to start if Swarm.ResourceMgr.Limits.System.StreamsInbound <= Swarm.ConnMgr.HighWater" ' - ipfs config --json Swarm.ResourceMgr.Limits.System.StreamsInbound 128 && - test_expect_code 1 ipfs daemon && - ipfs config --json Swarm.ResourceMgr.Limits.System.StreamsInbound 256 -' - -test_done From 68f4dd4427c46a2a08ccde73d5221c12387a541e Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Thu, 2 Mar 2023 13:14:54 +1300 Subject: [PATCH 0500/1212] chore: update go-libp2p to v0.26.2 --- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 4 ++-- go.sum | 8 ++++---- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 77dc84038..c3e8e16d1 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -10,7 +10,7 @@ require ( github.com/ipfs/go-libipfs v0.6.1-0.20230228004237-36918f45f260 github.com/ipfs/interface-go-ipfs-core v0.11.0 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 - github.com/libp2p/go-libp2p v0.26.1 + github.com/libp2p/go-libp2p v0.26.2 github.com/multiformats/go-multiaddr v0.8.0 ) diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 6e365b6a7..a5b30e5d7 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -730,8 +730,8 @@ github.com/libp2p/go-libp2p v0.7.0/go.mod h1:hZJf8txWeCduQRDC/WSqBGMxaTHCOYHt2xS github.com/libp2p/go-libp2p v0.7.4/go.mod h1:oXsBlTLF1q7pxr+9w6lqzS1ILpyHsaBPniVO7zIHGMw= github.com/libp2p/go-libp2p v0.8.1/go.mod h1:QRNH9pwdbEBpx5DTJYg+qxcVaDMAz3Ee/qDKwXujH5o= github.com/libp2p/go-libp2p v0.14.3/go.mod h1:d12V4PdKbpL0T1/gsUNN8DfgMuRPDX8bS2QxCZlwRH0= -github.com/libp2p/go-libp2p v0.26.1 h1:I9bHj5KteIB1tsBWLT25TTttx5xSjun3ph/q/8Xax/k= -github.com/libp2p/go-libp2p v0.26.1/go.mod h1:HKQUKIQ5NhzabNMWq9Wczcs5Ksdx4LQ/ISAq4MRqBHQ= +github.com/libp2p/go-libp2p v0.26.2 h1:eHEoW/696FP7/6DxOvcrKfTD6Bi0DExxiMSZUJxswA0= +github.com/libp2p/go-libp2p v0.26.2/go.mod h1:x75BN32YbwuY0Awm2Uix4d4KOz+/4piInkp4Wr3yOo8= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-autonat v0.1.0/go.mod h1:1tLf2yXxiE/oKGtDwPYWTSYG3PtvYlJmg7NeVtPRqH8= diff --git a/go.mod b/go.mod index 762a3add5..ec0e3e8a5 100644 --- a/go.mod +++ b/go.mod @@ -67,7 +67,7 @@ require ( 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.26.1 + github.com/libp2p/go-libp2p v0.26.2 github.com/libp2p/go-libp2p-http v0.4.0 github.com/libp2p/go-libp2p-kad-dht v0.21.1 github.com/libp2p/go-libp2p-kbucket v0.5.0 @@ -172,7 +172,7 @@ require ( github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/libp2p/go-cidranger v1.1.0 // indirect github.com/libp2p/go-flow-metrics v0.1.0 // indirect - github.com/libp2p/go-libp2p-asn-util v0.3.0 // indirect + github.com/libp2p/go-libp2p-asn-util v0.2.0 // indirect github.com/libp2p/go-libp2p-gostream v0.5.0 // indirect github.com/libp2p/go-libp2p-xor v0.1.0 // indirect github.com/libp2p/go-mplex v0.7.0 // indirect diff --git a/go.sum b/go.sum index 13c15ccc8..9f666f405 100644 --- a/go.sum +++ b/go.sum @@ -760,10 +760,10 @@ github.com/libp2p/go-libp2p v0.7.0/go.mod h1:hZJf8txWeCduQRDC/WSqBGMxaTHCOYHt2xS github.com/libp2p/go-libp2p v0.7.4/go.mod h1:oXsBlTLF1q7pxr+9w6lqzS1ILpyHsaBPniVO7zIHGMw= github.com/libp2p/go-libp2p v0.8.1/go.mod h1:QRNH9pwdbEBpx5DTJYg+qxcVaDMAz3Ee/qDKwXujH5o= github.com/libp2p/go-libp2p v0.14.3/go.mod h1:d12V4PdKbpL0T1/gsUNN8DfgMuRPDX8bS2QxCZlwRH0= -github.com/libp2p/go-libp2p v0.26.1 h1:I9bHj5KteIB1tsBWLT25TTttx5xSjun3ph/q/8Xax/k= -github.com/libp2p/go-libp2p v0.26.1/go.mod h1:HKQUKIQ5NhzabNMWq9Wczcs5Ksdx4LQ/ISAq4MRqBHQ= -github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= -github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= +github.com/libp2p/go-libp2p v0.26.2 h1:eHEoW/696FP7/6DxOvcrKfTD6Bi0DExxiMSZUJxswA0= +github.com/libp2p/go-libp2p v0.26.2/go.mod h1:x75BN32YbwuY0Awm2Uix4d4KOz+/4piInkp4Wr3yOo8= +github.com/libp2p/go-libp2p-asn-util v0.2.0 h1:rg3+Os8jbnO5DxkC7K/Utdi+DkY3q/d1/1q+8WeNAsw= +github.com/libp2p/go-libp2p-asn-util v0.2.0/go.mod h1:WoaWxbHKBymSN41hWSq/lGKJEca7TNm58+gGJi2WsLI= github.com/libp2p/go-libp2p-autonat v0.1.0/go.mod h1:1tLf2yXxiE/oKGtDwPYWTSYG3PtvYlJmg7NeVtPRqH8= github.com/libp2p/go-libp2p-autonat v0.1.1/go.mod h1:OXqkeGOY2xJVWKAGV2inNF5aKN/djNA3fdpCWloIudE= github.com/libp2p/go-libp2p-autonat v0.2.0/go.mod h1:DX+9teU4pEEoZUqR1PiMlqliONQdNbfzE1C718tcViI= From 74cfddc39e29671cc57fb2db6b8539fc3b1860c5 Mon Sep 17 00:00:00 2001 From: galargh Date: Thu, 2 Mar 2023 10:34:38 +0100 Subject: [PATCH 0501/1212] ci: remove disabled testground workflow --- .github/workflows/testground-on-push.yml | 38 ------------------------ 1 file changed, 38 deletions(-) delete mode 100644 .github/workflows/testground-on-push.yml diff --git a/.github/workflows/testground-on-push.yml b/.github/workflows/testground-on-push.yml deleted file mode 100644 index 7b55dbdee..000000000 --- a/.github/workflows/testground-on-push.yml +++ /dev/null @@ -1,38 +0,0 @@ ---- -name: Testground PR Checker - -on: - workflow_dispatch: - push: - - -jobs: - testground: - if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' - runs-on: ubuntu-latest - name: ${{ matrix.composition_file }} - strategy: - matrix: - include: - - backend_addr: ci.testground.ipfs.team - backend_proto: https - plan_directory: testplans/bitswap - composition_file: testplans/bitswap/_compositions/small-k8s.toml - - backend_addr: ci.testground.ipfs.team - backend_proto: https - plan_directory: testplans/bitswap - composition_file: testplans/bitswap/_compositions/medium-k8s.toml - - backend_addr: ci.testground.ipfs.team - backend_proto: https - plan_directory: testplans/bitswap - composition_file: testplans/bitswap/_compositions/large-k8s.toml - steps: - - uses: actions/checkout@v2 - - name: testground run - uses: testground/testground-github-action@v1 - timeout-minutes: 5 - with: - backend_addr: ${{ matrix.backend_addr }} - backend_proto: ${{ matrix.backend_proto }} - plan_directory: ${{ matrix.plan_directory }} - composition_file: ${{ matrix.composition_file }} From e1f38d7567df725d37024e7f294ec00d584c84ef Mon Sep 17 00:00:00 2001 From: Piotr Galar Date: Thu, 2 Mar 2023 10:51:57 +0100 Subject: [PATCH 0502/1212] ci: set sensible timeouts on all gha jobs (#9683) --- .github/workflows/build.yml | 5 +++++ .github/workflows/codeql-analysis.yml | 1 + .github/workflows/docker-build.yml | 1 + .github/workflows/docker-image.yml | 1 + .github/workflows/gobuild.yml | 1 + .github/workflows/golang-analysis.yml | 1 + .github/workflows/golint.yml | 1 + .github/workflows/gotest.yml | 1 + .github/workflows/runner.yml | 1 + .github/workflows/sharness.yml | 1 + .github/workflows/sync-release-assets.yml | 1 + 11 files changed, 15 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5e350cad7..4e91b244b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -14,6 +14,7 @@ jobs: prepare: if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' runs-on: ubuntu-latest + timeout-minutes: 5 env: TEST_NO_DOCKER: 1 TEST_NO_FUSE: 1 @@ -40,6 +41,7 @@ jobs: ipfs-interop: needs: [prepare] runs-on: ubuntu-latest + timeout-minutes: 20 strategy: matrix: suites: @@ -83,6 +85,7 @@ jobs: go-ipfs-api: needs: [prepare] runs-on: ubuntu-latest + timeout-minutes: 5 env: TEST_NO_DOCKER: 1 TEST_NO_FUSE: 1 @@ -122,6 +125,7 @@ jobs: go-ipfs-http-client: needs: [prepare] runs-on: ubuntu-latest + timeout-minutes: 5 env: TEST_NO_DOCKER: 1 TEST_NO_FUSE: 1 @@ -154,6 +158,7 @@ jobs: ipfs-webui: needs: [prepare] runs-on: ubuntu-latest + timeout-minutes: 20 env: NO_SANDBOX: true LIBP2P_TCP_REUSEPORT: false diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index e12af6b4e..c5c355fac 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -16,6 +16,7 @@ jobs: if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' name: Analyze runs-on: ubuntu-latest + timeout-minutes: 20 strategy: fail-fast: false diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml index 86c50bec7..23e29bf39 100644 --- a/.github/workflows/docker-build.yml +++ b/.github/workflows/docker-build.yml @@ -11,6 +11,7 @@ jobs: docker-build: if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' runs-on: ubuntu-latest + timeout-minutes: 10 env: IMAGE_NAME: ipfs/kubo WIP_IMAGE_TAG: wip diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index a7416e388..f798bb202 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -14,6 +14,7 @@ jobs: if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' name: Push Docker image to Docker Hub runs-on: ubuntu-latest + timeout-minutes: 90 env: IMAGE_NAME: ipfs/kubo LEGACY_IMAGE_NAME: ipfs/go-ipfs diff --git a/.github/workflows/gobuild.yml b/.github/workflows/gobuild.yml index 120e94693..532d34590 100644 --- a/.github/workflows/gobuild.yml +++ b/.github/workflows/gobuild.yml @@ -14,6 +14,7 @@ jobs: gobuild: needs: [runner] runs-on: ${{ fromJSON(needs.runner.outputs.config).labels }} + timeout-minutes: 20 env: TEST_NO_DOCKER: 1 TEST_VERBOSE: 1 diff --git a/.github/workflows/golang-analysis.yml b/.github/workflows/golang-analysis.yml index 958ece668..1bc669003 100644 --- a/.github/workflows/golang-analysis.yml +++ b/.github/workflows/golang-analysis.yml @@ -11,6 +11,7 @@ jobs: unit: if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' runs-on: ubuntu-latest + timeout-minutes: 10 name: All steps: - uses: actions/checkout@v2 diff --git a/.github/workflows/golint.yml b/.github/workflows/golint.yml index 9623ae4b6..a6593582d 100644 --- a/.github/workflows/golint.yml +++ b/.github/workflows/golint.yml @@ -11,6 +11,7 @@ jobs: golint: if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' runs-on: ubuntu-latest + timeout-minutes: 10 env: TEST_NO_DOCKER: 1 TEST_NO_FUSE: 1 diff --git a/.github/workflows/gotest.yml b/.github/workflows/gotest.yml index 2c50fd3e5..8eb41a34d 100644 --- a/.github/workflows/gotest.yml +++ b/.github/workflows/gotest.yml @@ -11,6 +11,7 @@ jobs: gotest: if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' runs-on: ubuntu-latest + timeout-minutes: 20 env: TEST_NO_DOCKER: 1 TEST_NO_FUSE: 1 diff --git a/.github/workflows/runner.yml b/.github/workflows/runner.yml index afb4d740d..c8aef2256 100644 --- a/.github/workflows/runner.yml +++ b/.github/workflows/runner.yml @@ -10,6 +10,7 @@ on: jobs: choose: runs-on: ubuntu-latest + timeout-minutes: 1 outputs: config: ${{ steps.config.outputs.result }} steps: diff --git a/.github/workflows/sharness.yml b/.github/workflows/sharness.yml index 6241e3fe6..44df1e8a0 100644 --- a/.github/workflows/sharness.yml +++ b/.github/workflows/sharness.yml @@ -14,6 +14,7 @@ jobs: sharness: needs: [runner] runs-on: ${{ fromJSON(needs.runner.outputs.config).labels }} + timeout-minutes: 20 defaults: run: shell: bash diff --git a/.github/workflows/sync-release-assets.yml b/.github/workflows/sync-release-assets.yml index da3ca9582..f2527d47c 100644 --- a/.github/workflows/sync-release-assets.yml +++ b/.github/workflows/sync-release-assets.yml @@ -13,6 +13,7 @@ jobs: sync-github-and-dist-ipfs-tech: if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' runs-on: "ubuntu-latest" + timeout-minutes: 5 steps: - uses: ipfs/download-ipfs-distribution-action@v1 - uses: ipfs/start-ipfs-daemon-action@v1 From fe8f72e70739b7a55330a2a609fe3fd2a0bfc1ae Mon Sep 17 00:00:00 2001 From: galargh Date: Tue, 28 Feb 2023 13:00:23 +0100 Subject: [PATCH 0503/1212] ci: replace junit html generation with gh action --- .github/workflows/sharness.yml | 18 +++++++-- test/sharness/Rules.mk | 15 ------- test/sharness/lib/download-saxon.sh | 39 ------------------- test/sharness/lib/test-generate-junit-html.sh | 20 ---------- 4 files changed, 15 insertions(+), 77 deletions(-) delete mode 100755 test/sharness/lib/download-saxon.sh delete mode 100755 test/sharness/lib/test-generate-junit-html.sh diff --git a/.github/workflows/sharness.yml b/.github/workflows/sharness.yml index 44df1e8a0..8809f2a53 100644 --- a/.github/workflows/sharness.yml +++ b/.github/workflows/sharness.yml @@ -56,9 +56,7 @@ jobs: make -O -j "$PARALLEL" \ test_sharness \ coverage/sharness_tests.coverprofile \ - test/sharness/test-results/sharness.xml \ - test/sharness/test-results/sharness.html \ - test/sharness/test-results/sharness-html + test/sharness/test-results/sharness.xml working-directory: kubo env: TEST_NO_DOCKER: 0 @@ -88,6 +86,13 @@ jobs: echo "# Summary" >> $GITHUB_STEP_SUMMARY echo >> $GITHUB_STEP_SUMMARY cat kubo/test/sharness/test-results/summary.txt >> $GITHUB_STEP_SUMMARY + - name: Generate one-page HTML report + uses: pl-strflt/junit-xml-to-html@v1 + if: failure() || success() + with: + mode: no-frames + input: kubo/test/sharness/test-results/sharness.xml + output: kubo/test/sharness/test-results/sharness.html - name: Upload one-page HTML report to S3 id: one-page uses: pl-strflt/tf-aws-gh-runner/.github/actions/upload-artifact@main @@ -101,6 +106,13 @@ jobs: with: name: sharness.html path: kubo/test/sharness/test-results/sharness.html + - name: Generate full HTML report + uses: pl-strflt/junit-xml-to-html@v1 + if: failure() || success() + with: + mode: frames + input: kubo/test/sharness/test-results/sharness.xml + output: kubo/test/sharness/test-results/sharness-html - name: Upload full HTML report to S3 id: full uses: pl-strflt/tf-aws-gh-runner/.github/actions/upload-artifact@main diff --git a/test/sharness/Rules.mk b/test/sharness/Rules.mk index 20b2634db..f95aee15e 100644 --- a/test/sharness/Rules.mk +++ b/test/sharness/Rules.mk @@ -47,21 +47,6 @@ $(d)/test-results/sharness.xml: $(T_$(d)) @(cd $(@D)/.. && ./lib/test-aggregate-junit-reports.sh) .PHONY: $(d)/test-results/sharness.xml -$(d)/download-saxon: - @echo "*** $@ ***" - @(cd $(@D) && ./lib/download-saxon.sh) -.PHONY: $(d)/download-saxon - -$(d)/test-results/sharness-html: $(d)/test-results/sharness.xml $(d)/download-saxon - @echo "*** $@ ***" - @(cd $(@D)/.. && ./lib/test-generate-junit-html.sh frames) -.PHONY: $(d)/test-results/sharness-html - -$(d)/test-results/sharness.html: $(d)/test-results/sharness.xml $(d)/download-saxon - @echo "*** $@ ***" - @(cd $(@D)/.. && ./lib/test-generate-junit-html.sh no-frames) -.PHONY: $(d)/test-results/sharness.html - $(d)/clean-test-results: rm -rf $(@D)/test-results .PHONY: $(d)/clean-test-results diff --git a/test/sharness/lib/download-saxon.sh b/test/sharness/lib/download-saxon.sh deleted file mode 100755 index cc645238f..000000000 --- a/test/sharness/lib/download-saxon.sh +++ /dev/null @@ -1,39 +0,0 @@ -#!/bin/bash - -dependencies=( - "url=https://raw.githubusercontent.com/pl-strflt/Saxon-HE/3e039cdbccf4efb9643736f34c839a3bae3402ae/11/Java/SaxonHE11-4J.zip;md5=8a4783d307c32c898f8995b8f337fd6b" - "url=https://raw.githubusercontent.com/pl-strflt/ant/c781f7d79b92cc55530245d9554682a47f46851e/src/etc/junit-frames-saxon.xsl;md5=6eb013566903a91e4959413f6ff144d0" - "url=https://raw.githubusercontent.com/pl-strflt/ant/c781f7d79b92cc55530245d9554682a47f46851e/src/etc/junit-noframes-saxon.xsl;md5=8d54882d5f9d32a7743ec675cc2e30ac" -) - -dependenciesdir="lib/dependencies" -mkdir -p "$dependenciesdir" - -get_md5() { - md5sum "$1" | cut -d ' ' -f 1 -} - -for dependency in "${dependencies[@]}"; do - url="$(echo "$dependency" | cut -d ';' -f 1 | cut -d '=' -f 2)" - md5="$(echo "$dependency" | cut -d ';' -f 2 | cut -d '=' -f 2)" - filename="$(basename "$url")" - if test -f "$dependenciesdir/$filename" && test "$(get_md5 "$dependenciesdir/$filename")" = "$md5"; then - echo "Using cached $filename" - else - echo "Downloading $filename" - curl -L --max-redirs 5 --retry 5 --no-progress-meter --output "$dependenciesdir/$filename" "$url" - actual_md5="$(get_md5 "$dependenciesdir/$filename")" - if test "$actual_md5" != "$md5"; then - echo "Downloaded $filename has wrong md5sum ('$actual_md5' != '$md5')" - exit 1 - fi - dirname=${filename%.*} - extension=${filename#$dirname.} - if test "$extension" = "zip"; then - echo "Removing old $dependenciesdir/$dirname" - rm -rf "$dependenciesdir/$dirname" - echo "Unzipping $dependenciesdir/$filename" - unzip "$dependenciesdir/$filename" -d "$dependenciesdir/$dirname" - fi - fi -done diff --git a/test/sharness/lib/test-generate-junit-html.sh b/test/sharness/lib/test-generate-junit-html.sh deleted file mode 100755 index 2790a7b9d..000000000 --- a/test/sharness/lib/test-generate-junit-html.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/bash - -case "$1" in - "frames") - java -jar lib/dependencies/SaxonHE11-4J/saxon-he-11.4.jar \ - -s:test-results/sharness.xml \ - -xsl:lib/dependencies/junit-frames-saxon.xsl \ - output.dir=$(pwd)/test-results/sharness-html - ;; - "no-frames") - java -jar lib/dependencies/SaxonHE11-4J/saxon-he-11.4.jar \ - -s:test-results/sharness.xml \ - -xsl:lib/dependencies/junit-noframes-saxon.xsl \ - -o:test-results/sharness.html - ;; - *) - echo "Usage: $0 [frames|no-frames]" - exit 1 - ;; -esac From f84ad6d627fcd6d70f173229db22084837526ccf Mon Sep 17 00:00:00 2001 From: Steve Loeppky Date: Wed, 1 Mar 2023 15:12:38 -0800 Subject: [PATCH 0504/1212] Doc updates/additions --- docs/changelogs/v0.19.md | 13 ++- docs/config.md | 62 +------------ docs/libp2p-resource-management.md | 135 ++++++++++++----------------- 3 files changed, 70 insertions(+), 140 deletions(-) diff --git a/docs/changelogs/v0.19.md b/docs/changelogs/v0.19.md index e1c28482d..7663308a6 100644 --- a/docs/changelogs/v0.19.md +++ b/docs/changelogs/v0.19.md @@ -1,11 +1,12 @@ + # Kubo changelog v0.19 -- [v0.19.0](#v0190) - + ## v0.19.0 - [Overview](#overview) - [🔦 Highlights](#-highlights) + - [Improving the libp2p resource management integration](#improving-the-libp2p-resource-management-integration) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -13,6 +14,14 @@ ### 🔦 Highlights +#### Improving the libp2p resource management integration +There are further followups up on libp2p resource manager improvements in Kubo [0.18.0](https://github.com/ipfs/kubo/blob/master/docs/changelogs/v0.18.md#improving-libp2p-resource-management-integration-1) +and [0.18.1](https://github.com/ipfs/kubo/blob/master/docs/changelogs/v0.18.md#improving-libp2p-resource-management-integration): +1. `ipfs swarm limits` and `ipfs swarm stats` have been replaced by `ipfs swarm resources` to provide a single/combined view for limits and their current usage in a more intuitive ordering. +1. Removal of `Swarm.ResourceMgr.Limits` config. Instead [the power user can specify limits in a .json file that are fed directly to go-libp2p](https://github.com/ipfs/kubo/blob/master/docs/libp2p-resource-management.md#user-supplied-override-limits). This allows the power user to take advantage of the [new resource manager types introduced in go-libp2p 0.25](https://github.com/libp2p/go-libp2p/blob/master/CHANGELOG.md#new-resource-manager-types-) including "use default", "unlimited", "block all". + - Note: we don't expect most users to need these capablities, but they are there if so. +1. [Doc updates](https://github.com/ipfs/kubo/blob/master/docs/libp2p-resource-management.md). + ### 📝 Changelog ### 👨‍👩‍👧‍👦 Contributors diff --git a/docs/config.md b/docs/config.md index 76a49ba03..30a4e7601 100644 --- a/docs/config.md +++ b/docs/config.md @@ -146,7 +146,6 @@ config file at runtime. - [`Swarm.ResourceMgr.Enabled`](#swarmresourcemgrenabled) - [`Swarm.ResourceMgr.MaxMemory`](#swarmresourcemgrmaxmemory) - [`Swarm.ResourceMgr.MaxFileDescriptors`](#swarmresourcemgrmaxfiledescriptors) - - [`Swarm.ResourceMgr.Limits`](#swarmresourcemgrlimits) - [`Swarm.ResourceMgr.Allowlist`](#swarmresourcemgrallowlist) - [`Swarm.Transports`](#swarmtransports) - [`Swarm.Transports.Network`](#swarmtransportsnetwork) @@ -1846,6 +1845,8 @@ This value is also used to scale the limit on various resources at various scope when the default limits (discussed in [libp2p resource management](./libp2p-resource-management.md)) are used. For example, increasing this value will increase the default limit for incoming connections. +It is possible to inspect the runtime limits via `ipfs swarm resources --help`. + Default: `[TOTAL_SYSTEM_MEMORY]/2` Type: `optionalBytes` @@ -1859,65 +1860,6 @@ This param is ignored on Windows. Default `[TOTAL_SYSTEM_FILE_DESCRIPTORS]/2` Type: `optionalInteger` -#### `Swarm.ResourceMgr.Limits` - -Map of resource limits [per scope](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#resource-scopes). - -The map supports fields from the [`LimitConfig` struct](https://github.com/libp2p/go-libp2p/blob/master/p2p/host/resource-manager/limit_defaults.go#L111). - -[`BaseLimit`s](https://github.com/libp2p/go-libp2p/blob/master/p2p/host/resource-manager/limit.go#L89) can be set for any scope, and within the `BaseLimit`, all limit s are optional. - -The `Swarm.ResourceMgr.Limits` override the default limits described above. -Any override `BaseLimits` or limit s from `Swarm.ResourceMgr.Limits` -that aren't specified will use the [computed default limits](./libp2p-resource-management.md#computed-default-limits). - -Until [ipfs/kubo#9564](https://github.com/ipfs/kubo/issues/9564) is addressed, there isn't a way to set an override limit of zero. -0 is currently ignored. 0 currently means use to use the [computed default limits](./libp2p-resource-management.md#computed-default-limits). - -Example #1: setting limits for a specific scope -```json -{ - "Swarm": { - "ResourceMgr": { - "Limits": { - "System": { - "Memory": 1073741824, - "FD": 512, - "Conns": 1024, - "ConnsInbound": 256, - "ConnsOutbound": 1024, - "Streams": 16384, - "StreamsInbound": 4096, - "StreamsOutbound": 16384 - } - } - } - } -} -``` - -Example #2: setting a specific limit -```json -{ - "Swarm": { - "ResourceMgr": { - "Limits": { - "Transient": { - "ConnsOutbound": 256, - } - } - } - } -} -``` - -It is also possible to inspect and adjust some runtime limits via `ipfs swarm stats --help` and `ipfs swarm limit --help`. -Changes made via `ipfs swarm limit` are persisted in `Swarm.ResourceMgr.Limits`. - -Default: `{}` (use the [computed defaults](./libp2p-resource-management.md#computed-default-limits)) - -Type: `object[string->object]` - #### `Swarm.ResourceMgr.Allowlist` A list of multiaddrs that can bypass normal system limits (but are still limited by the allowlist scope). diff --git a/docs/libp2p-resource-management.md b/docs/libp2p-resource-management.md index 255ee6699..b7dbf4bae 100644 --- a/docs/libp2p-resource-management.md +++ b/docs/libp2p-resource-management.md @@ -1,3 +1,4 @@ + # libp2p Network Resource Manager (`Swarm.ResourceMgr`) ## Purpose @@ -12,32 +13,27 @@ Good places to start are: 3. Understand [how to inspect and change limits](#user-supplied-override-limits) ## Table of Contents - - [Purpose](#purpose) - [🙋 Help! The resource manager is protecting my node but I want to understand more](#-help--the-resource-manager-is-protecting-my-node-but-i-want-to-understand-more) - [Table of Contents](#table-of-contents) - [Levels of Configuration](#levels-of-configuration) - - [Approach](#approach) - - [Computed Default Limits](#computed-default-limits) - - [User Supplied Override Limits](#user-supplied-override-limits) - - [Infinite limits](#infinite-limits) + - [Approach](#approach) + - [Computed Default Limits](#computed-default-limits) + - [User Supplied Override Limits](#user-supplied-override-limits) - [FAQ](#faq) - - [What do these "Protected from exceeding resource limits" log messages mean?](#what-do-these-protected-from-exceeding-resource-limits-log-messages-mean) - - [What are the "Application error 0x0 remote ... cannot reserve ..." messages?](#what-are-the-application-error-0x0-remote--cannot-reserve--messages) - - [How does the resource manager ResourceMgr relate to the connection manager ConnMgr?](#how-does-the-resource-manager-resourcemgr-relate-to-the-connection-manager-connmgr) - - [How does one see the Active Limits?](#how-does-one-see-the-active-limits) - - [How does one see the Computed Default Limits?](#how-does-one-see-the-computed-default-limits) - - [How does one monitor libp2p resource usage?](#how-does-one-monitor-libp2p-resource-usage) + - [What do these "Protected from exceeding resource limits" log messages mean?](#what-do-these-protected-from-exceeding-resource-limits-log-messages-mean) + - [How does one see the Active Limits?](#how-does-one-see-the-active-limits) + - [How does one see the Computed Default Limits?](#how-does-one-see-the-computed-default-limits) + - [How does one monitor libp2p resource usage?](#how-does-one-monitor-libp2p-resource-usage) + - [How does the resource manager (ResourceMgr) relate to the connection manager (ConnMgr)?](#how-does-the-resource-manager-resourcemgr-relate-to-the-connection-manager-connmgr) + - [What are the "Application error 0x0 (remote) ... cannot reserve ..." messages?](#what-are-the-application-error-0x0-remote--cannot-reserve--messages) - [History](#history) - - ## Levels of Configuration See also the [`Swarm.ResourceMgr` config docs](./config.md#swarmresourcemgr). - ### Approach libp2p's resource manager provides tremendous flexibility but also adds complexity. There are these levels of limit configuration for resource management protection: @@ -45,12 +41,11 @@ libp2p's resource manager provides tremendous flexibility but also adds complexi based on the amount of memory and file descriptors their system has. This should protect the node from many attacks. -1. "Slightly more advanced user" - They can tweak the default limits discussed below. - Where the defaults aren't good enough, a good set of higher-level "knobs" are exposed to satisfy most use cases +2. "Slightly more advanced user" - Where the defaults aren't good enough, a good set of higher-level "knobs" are exposed to satisfy most use cases without requiring users to wade into all the intricacies of libp2p's resource manager. The "knobs"/inputs are `Swarm.ResourceMgr.MaxMemory` and `Swarm.ResourceMgr.MaxFileDescriptors` as described below. -1. "Power user" - They specify overrides to computed default limits via `ipfs swarm limit` and `Swarm.ResourceMgr.Limits`; +3. "Power user" - They [specify override limits](#user-supplied-override-limits) and own their own destiny without Kubo getting in the way. ### Computed Default Limits With the `Swarm.ResourceMgr.MaxMemory` and `Swarm.ResourceMgr.MaxFileDescriptors` inputs defined, @@ -58,7 +53,7 @@ With the `Swarm.ResourceMgr.MaxMemory` and `Swarm.ResourceMgr.MaxFileDescriptors [system](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#the-system-scope), [transient](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#the-transient-scope), and [peer](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#peer-scopes) scopes. -Other scopes are ignored (by being set to "[~infinity](#infinite-limits])". +Other scopes are ignored (by being set to "unlimited"). The reason these scopes are chosen is because: - `system` - This gives us the coarse-grained control we want so we can reason about the system as a whole. @@ -72,13 +67,14 @@ The reason these scopes are chosen is because: (e.g., bug in a peer which is causing it to "misbehave"). In the unintentional case, we want to make sure a "misbehaving" node doesn't consume more resources than necessary. -Within these scopes, limits are just set on -[memory](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#memory), -[file descriptors (FD)](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#file-descriptors), and [*inbound* connections](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#connections). +Within these scopes, limits are set on: +1. [memory](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#memory) +2. [file descriptors (FD)](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#file-descriptors) +3. [*inbound* connections](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#connections). Limits are set based on the `Swarm.ResourceMgr.MaxMemory` and `Swarm.ResourceMgr.MaxFileDescriptors` inputs above. There are also some special cases where minimum values are enforced. -For example, Kubo maintainers have found in practice that it's a footgun to have too low of a value for `Swarm.ResourceMgr.Limits.System.ConnsInbound` and a default minimum is used. (See [core/node/libp2p/rcmgr_defaults.go](https://github.com/ipfs/kubo/blob/master/core/node/libp2p/rcmgr_defaults.go) for specifics.) +For example, Kubo maintainers have found in practice that it's a footgun to have too low of a value for `System.ConnsInbound` and a default minimum is used. (See [core/node/libp2p/rcmgr_defaults.go](https://github.com/ipfs/kubo/blob/master/core/node/libp2p/rcmgr_defaults.go) for specifics.) We trust this node to behave properly and thus don't limit *outbound* connection/stream limits. We apply any limits that libp2p has for its protocols/services @@ -87,29 +83,10 @@ since we assume libp2p knows best here. Source: [core/node/libp2p/rcmgr_defaults.go](https://github.com/ipfs/kubo/blob/master/core/node/libp2p/rcmgr_defaults.go) ### User Supplied Override Limits -Once Kubo has the [Computed Default Limits](#computed-default-limits), it then applies any user-supplied [`Swarm.ResourceMgr.Limits`](https://github.com/ipfs/kubo/blob/master/docs/config.md#swarmresourcemgrlimits) on top. -These become the [active limits](#how-does-one-see-the-active-limits). - -While `Swarm.ResourceMgr.Limits` can be edited directly, it is also possible to use `ipfs swarm limit` command to inspect and tweak specific limits at runtime. - -To see all resources that are close to hitting their respective limit: - -```console -$ ipfs swarm stats --min-used-limit-perc=90 all -``` - -To modify limits for specific scope (e.g. `system`): - -```console -$ ipfs swarm limit system > change.json -$ vi change.json -$ ipfs swarm limit system change.json -``` - -Learn more: `ipfs swarm limit --help` - -### Infinite limits -There isn't a way via config to specify infinite limits (see [go-libp2p#1935](https://github.com/libp2p/go-libp2p/issues/1935)). For example, "-1" is not infinity. To work around this, Kubo uses a magic number of "1000000000" to denote infinity since it's effectively infinite. +A user who wants fine control over the limits used by the go-libp2p resoure manager can specify overrides to the [computed default limits](#computed-default-limits). +This is done by defining limits in ``$IPFS_PATH/libp2p-resource-limit-overrides.json``. +These values trump anything else and are parsed directly by go-libp2p. +(See the [go-libp2p Resource Manager README](https://github.com/libp2p/go-libp2p/blob/master/p2p/host/resource-manager/README.md) for formatting.) ## FAQ @@ -121,49 +98,23 @@ As an example: > Protected from exceeding resource limits 2 times: "system: cannot reserve inbound connection: resource limit exceeded" This means that there were 2 recent occurrences where the libp2p resource manager prevented an inbound connection at the "system" [scope](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#resource-scopes). -Specificaly the ``Swarm.ResourceMgr.Limits.System.ConnsInbound`` [active limit](#how-does-one-see-the-active-limits) was hit. +Specificaly the ``System.ConnsInbound`` limit was hit. -This can be analyzed by viewing the limit with `ipfs swarm limit system` and comparing the usage with `ipfs swarm stats system`. -`ConnsInbound` is likely close or at the limit value. +This can be analyzed by viewing the limit and current usage with `ipfs swarm resources`. +`System.ConnsInbound` is likely close or at the limit value. -The simplest way to identify all resources across all scopes that are close to exceeding their limit is with a command like `ipfs swarm stats --min-used-limit-perc=90 all`. +The simplest way to identify all resources across all scopes that are close to exceeding their limit (>90% usage) is with a command like `ipfs swarm resources | egrep "9.\..%"` Sources: * [kubo resource manager logging](https://github.com/ipfs/kubo/blob/master/core/node/libp2p/rcmgr_logging.go) * [libp2p resource manager messages](https://github.com/libp2p/go-libp2p/blob/master/p2p/host/resource-manager/scope.go) -### What are the "Application error 0x0 (remote) ... cannot reserve ..." messages? -These are messages coming from a *remote* go-libp2p peer (likely another Kubo node) with the resource manager enabled on why it failed to establish a connection. - -This can be confusing, but these `Application error 0x0 (remote) ... cannot reserve ...` messages can occur even if your local node has the resource manager disabled. - -You can distinguish resource manager messages originating from your local node if they're from the `resourcemanager` / `libp2p/rcmgr_logging.go` logger -or you see the string that is unique to Kubo (and not in go-libp2p): "Protected from exceeding resource limits". - -There is a go-libp2p issue ([#1928](https://github.com/libp2p/go-libp2p/issues/1928)) to make it even clearer that this is an error message originating from a remote peer. - -### How does the resource manager (ResourceMgr) relate to the connection manager (ConnMgr)? -As discussed [here](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#connmanager-vs-resource-manager) -these are separate systems in go-libp2p. -Kubo performs sanity checks to ensure that some of the hard limits of the ResourceMgr are sufficiently greater than the soft limits of the ConnMgr. - -The soft limit of `Swarm.ConnMgr.HighWater` needs to be less than the hard limit `Swarm.ResourceMgr.Limits.System.ConnsInbound` for the configuration to make sense. -This ensures the ConnMgr cleans up connections based on connection priorities before the hard limits of the ResourceMgr are applied. -If `Swarm.ConnMgr.HighWater` is greater than `Swarm.ResourceMgr.Limits.System.ConnsInbound`, -existing low priority idle connections can prevent new high priority connections from being established. -The ResourceMgr doesn't know that the new connection is high priority and simply blocks it because of the limit its enforcing. - -To ensure the ConnMgr and ResourceMgr are congruent, the ResourceMgr [computed default limts](#computed-default-limits) are adjusted such that: -1. `Swarm.ResourceMgr.Limits.System.ConnsInbound` >= `max(Swarm.ConnMgr.HighWater * 2, DefaultResourceMgrMinInboundConns)` AND -2. `Swarm.ResourceMgr.Limits.System.StreamsInbound` is greater than any new/adjusted `Swarm.ResourceMgr.Limits.System.ConnsInbound` value so that there's enough streams per connection. - ### How does one see the Active Limits? A dump of what limits are actually being used by the resource manager ([Computed Default Limits](#computed-default-limits) + [User Supplied Override Limits](#user-supplied-override-limits)) -can be obtained by `ipfs swarm limit all`. +can be obtained by `ipfs swarm resources`. ### How does one see the Computed Default Limits? -This can be observed with an empty [`Swarm.ResourceMgr.Limits`](https://github.com/ipfs/kubo/blob/master/docs/config.md#swarmresourcemgrlimits) -and then [seeing the active limits](#how-does-one-see-the-active-limits). +This can be observed [seeing the active limits](#how-does-one-see-the-active-limits) assuming one hasn't detoured into "power user" mode with [User Supplied Override Limits](#user-supplied-override-limits). ### How does one monitor libp2p resource usage? @@ -174,5 +125,33 @@ There are also [pre-built Grafana dashboards](https://github.com/libp2p/go-libp2 A textual view of current resource usage and a list of services, protocols, and peers can be obtained via `ipfs swarm stats --help` +### How does the resource manager (ResourceMgr) relate to the connection manager (ConnMgr)? +As discussed [here](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#connmanager-vs-resource-manager) +these are separate systems in go-libp2p. +Kubo performs sanity checks to ensure that some of the hard limits of the ResourceMgr are sufficiently greater than the soft limits of the ConnMgr. + +The soft limit of `Swarm.ConnMgr.HighWater` needs to be less than the resource manager hard limit `System.ConnsInbound` for the configuration to make sense. +This ensures the ConnMgr cleans up connections based on connection priorities before the hard limits of the ResourceMgr are applied. +If `Swarm.ConnMgr.HighWater` is greater than resource manager's `System.ConnsInbound`, +existing low priority idle connections can prevent new high priority connections from being established. +The ResourceMgr doesn't know that the new connection is high priority and simply blocks it because of the limit its enforcing. + +To ensure the ConnMgr and ResourceMgr are congruent, the ResourceMgr [computed default limts](#computed-default-limits) are adjusted such that: +1. `System.ConnsInbound` >= `max(Swarm.ConnMgr.HighWater * 2, DefaultResourceMgrMinInboundConns)` AND +2. `System.StreamsInbound` is greater than any new/adjusted `Swarm.ResourceMgr.Limits.System.ConnsInbound` value so that there's enough streams per connection. + +Source: [core/node/libp2p/rcmgr_defaults.go](https://github.com/ipfs/kubo/blob/master/core/node/libp2p/rcmgr_defaults.go) + +### What are the "Application error 0x0 (remote) ... cannot reserve ..." messages? +These are messages coming from old (pre go-libp2p 0.26) *remote* go-libp2p peers (likely another older Kubo node) with the resource manager enabled on why it failed to establish a connection. + +This can be confusing, but these `Application error 0x0 (remote) ... cannot reserve ...` messages can occur even if your local node has the resource manager disabled. + +You can distinguish resource manager messages originating from your local node if they're from the `resourcemanager` / `libp2p/rcmgr_logging.go` logger +or you see the string that is unique to Kubo (and not in go-libp2p): "Protected from exceeding resource limits". + +See more info in this go-libp2p issue ([#1928](https://github.com/libp2p/go-libp2p/issues/1928)). go-libp2p 0.26 / Kubo 0.19 onwards this confusing error message was removed. + + ## History -Kubo first [exposed this functionality in Kubo 0.13](./changelogs/v0.13.md#-libp2p-network-resource-manager-swarmresourcemgr), but it was disabled by default. It was then enabled by default in [Kubo 0.17](./changelogs/v0.17.md#libp2p-resource-management-enabled-by-default). Until that point, Kubo was vulnerable to unbound resource usage which could bring down nodes. Introducing limits like this by default after the fact is tricky, which is why there have been changes and improvements afterwards. +Kubo first [exposed this functionality in Kubo 0.13](./changelogs/v0.13.md#-libp2p-network-resource-manager-swarmresourcemgr), but it was disabled by default. It was then enabled by default in [Kubo 0.17](./changelogs/v0.17.md#libp2p-resource-management-enabled-by-default). Until that point, Kubo was vulnerable to unbound resource usage which could bring down nodes. Introducing limits like this by default after the fact is tricky, which is why there have been changes and improvements afterwards. The general trend since 0.17 with (0.18)[./changeloges/v0.18.md#improving-libp2p-resource-management-integration] and 0.19 has been to simplify and provide less options (and footguns!) for users and better documentation. From 23379d8d601e1beb8db929ca9ca154e0ddf3a5e4 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Thu, 2 Mar 2023 09:29:12 +0100 Subject: [PATCH 0505/1212] chore: update go-unixfs v0.4.4 Include missing error handling. --- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index c3e8e16d1..9bddae4de 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -103,7 +103,7 @@ require ( github.com/ipfs/go-namesys v0.7.0 // indirect github.com/ipfs/go-path v0.3.1 // indirect github.com/ipfs/go-peertaskqueue v0.8.1 // indirect - github.com/ipfs/go-unixfs v0.4.3 // indirect + github.com/ipfs/go-unixfs v0.4.4 // indirect github.com/ipfs/go-unixfsnode v1.5.2 // indirect github.com/ipfs/go-verifcid v0.0.2 // indirect github.com/ipld/edelweiss v0.2.0 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index a5b30e5d7..c56c5776c 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -606,8 +606,8 @@ github.com/ipfs/go-peertaskqueue v0.8.1 h1:YhxAs1+wxb5jk7RvS0LHdyiILpNmRIRnZVzte github.com/ipfs/go-peertaskqueue v0.8.1/go.mod h1:Oxxd3eaK279FxeydSPPVGHzbwVeHjatZ2GA8XD+KbPU= github.com/ipfs/go-unixfs v0.2.4/go.mod h1:SUdisfUjNoSDzzhGVxvCL9QO/nKdwXdr+gbMUdqcbYw= github.com/ipfs/go-unixfs v0.3.1/go.mod h1:h4qfQYzghiIc8ZNFKiLMFWOTzrWIAtzYQ59W/pCFf1o= -github.com/ipfs/go-unixfs v0.4.3 h1:EdDc1sNZNFDUlo4UrVAvvAofVI5EwTnKu8Nv8mgXkWQ= -github.com/ipfs/go-unixfs v0.4.3/go.mod h1:TSG7G1UuT+l4pNj91raXAPkX0BhJi3jST1FDTfQ5QyM= +github.com/ipfs/go-unixfs v0.4.4 h1:D/dLBOJgny5ZLIur2vIXVQVW0EyDHdOMBDEhgHrt6rY= +github.com/ipfs/go-unixfs v0.4.4/go.mod h1:TSG7G1UuT+l4pNj91raXAPkX0BhJi3jST1FDTfQ5QyM= github.com/ipfs/go-unixfsnode v1.1.2/go.mod h1:5dcE2x03pyjHk4JjamXmunTMzz+VUtqvPwZjIEkfV6s= github.com/ipfs/go-unixfsnode v1.5.2 h1:CvsiTt58W2uR5dD8bqQv+aAY0c1qolmXmSyNbPHYiew= github.com/ipfs/go-unixfsnode v1.5.2/go.mod h1:NlOebRwYx8lMCNMdhAhEspYPBD3obp7TE0LvBqHY+ks= diff --git a/go.mod b/go.mod index ec0e3e8a5..b53ff3b0e 100644 --- a/go.mod +++ b/go.mod @@ -55,7 +55,7 @@ require ( github.com/ipfs/go-namesys v0.7.0 github.com/ipfs/go-path v0.3.1 github.com/ipfs/go-pinning-service-http-client v0.1.2 - github.com/ipfs/go-unixfs v0.4.3 + github.com/ipfs/go-unixfs v0.4.4 github.com/ipfs/go-unixfsnode v1.5.2 github.com/ipfs/go-verifcid v0.0.2 github.com/ipfs/interface-go-ipfs-core v0.11.0 diff --git a/go.sum b/go.sum index 9f666f405..90a843a3b 100644 --- a/go.sum +++ b/go.sum @@ -632,8 +632,8 @@ github.com/ipfs/go-pinning-service-http-client v0.1.2 h1:jdr7KelhL9gNHTU8jbqPMwI github.com/ipfs/go-pinning-service-http-client v0.1.2/go.mod h1:6wd5mjYhXJTiWU8b4RSWPpWdlzE5/csoXV0dWWMjun4= github.com/ipfs/go-unixfs v0.2.4/go.mod h1:SUdisfUjNoSDzzhGVxvCL9QO/nKdwXdr+gbMUdqcbYw= github.com/ipfs/go-unixfs v0.3.1/go.mod h1:h4qfQYzghiIc8ZNFKiLMFWOTzrWIAtzYQ59W/pCFf1o= -github.com/ipfs/go-unixfs v0.4.3 h1:EdDc1sNZNFDUlo4UrVAvvAofVI5EwTnKu8Nv8mgXkWQ= -github.com/ipfs/go-unixfs v0.4.3/go.mod h1:TSG7G1UuT+l4pNj91raXAPkX0BhJi3jST1FDTfQ5QyM= +github.com/ipfs/go-unixfs v0.4.4 h1:D/dLBOJgny5ZLIur2vIXVQVW0EyDHdOMBDEhgHrt6rY= +github.com/ipfs/go-unixfs v0.4.4/go.mod h1:TSG7G1UuT+l4pNj91raXAPkX0BhJi3jST1FDTfQ5QyM= github.com/ipfs/go-unixfsnode v1.1.2/go.mod h1:5dcE2x03pyjHk4JjamXmunTMzz+VUtqvPwZjIEkfV6s= github.com/ipfs/go-unixfsnode v1.5.2 h1:CvsiTt58W2uR5dD8bqQv+aAY0c1qolmXmSyNbPHYiew= github.com/ipfs/go-unixfsnode v1.5.2/go.mod h1:NlOebRwYx8lMCNMdhAhEspYPBD3obp7TE0LvBqHY+ks= From fea25f7ab10463f3dd0e4dc1a01d8d729d0281f0 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Thu, 2 Mar 2023 09:29:40 +0100 Subject: [PATCH 0506/1212] chore: update golang.org/x/net to v0.7.0 Include fix for https://pkg.go.dev/vuln/GO-2023-1571 (this impact us in the DOH handler). --- docs/examples/kubo-as-a-library/go.mod | 6 +++--- docs/examples/kubo-as-a-library/go.sum | 12 ++++++------ go.mod | 8 ++++---- go.sum | 16 ++++++++-------- 4 files changed, 21 insertions(+), 21 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 9bddae4de..056aea334 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -198,10 +198,10 @@ require ( golang.org/x/crypto v0.5.0 // indirect golang.org/x/exp v0.0.0-20230129154200-a960b3787bd2 // indirect golang.org/x/mod v0.7.0 // indirect - golang.org/x/net v0.5.0 // indirect + golang.org/x/net v0.7.0 // indirect golang.org/x/sync v0.1.0 // indirect - golang.org/x/sys v0.4.0 // indirect - golang.org/x/text v0.6.0 // indirect + golang.org/x/sys v0.5.0 // indirect + golang.org/x/text v0.7.0 // indirect golang.org/x/tools v0.3.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index c56c5776c..8a07bfbe8 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -1526,8 +1526,8 @@ golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20210917221730-978cfadd31cf/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.5.0 h1:GyT4nK/YDHSqa1c4753ouYCDajOYKTja9Xb/OHtgvSw= -golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= +golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1635,8 +1635,8 @@ golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18= -golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -1648,8 +1648,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.6.0 h1:3XmdazWV+ubf7QgHSTWeykHOci5oeekaGJBLkrkaw4k= -golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= diff --git a/go.mod b/go.mod index b53ff3b0e..2892d3740 100644 --- a/go.mod +++ b/go.mod @@ -109,7 +109,7 @@ require ( golang.org/x/exp v0.0.0-20230129154200-a960b3787bd2 golang.org/x/mod v0.7.0 golang.org/x/sync v0.1.0 - golang.org/x/sys v0.4.0 + golang.org/x/sys v0.5.0 ) require ( @@ -228,10 +228,10 @@ require ( go.uber.org/atomic v1.10.0 // indirect go.uber.org/multierr v1.9.0 // indirect go4.org v0.0.0-20200411211856-f5505b9728dd // indirect - golang.org/x/net v0.5.0 // indirect + golang.org/x/net v0.7.0 // indirect golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b // indirect - golang.org/x/term v0.4.0 // indirect - golang.org/x/text v0.6.0 // indirect + golang.org/x/term v0.5.0 // indirect + golang.org/x/text v0.7.0 // indirect golang.org/x/tools v0.3.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/appengine v1.6.6 // indirect diff --git a/go.sum b/go.sum index 90a843a3b..6f7800a2e 100644 --- a/go.sum +++ b/go.sum @@ -1590,8 +1590,8 @@ golang.org/x/net v0.0.0-20210917221730-978cfadd31cf/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.5.0 h1:GyT4nK/YDHSqa1c4753ouYCDajOYKTja9Xb/OHtgvSw= -golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= +golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1702,13 +1702,13 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18= -golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.4.0 h1:O7UWfv5+A2qiuulQk30kVinPoMtoIPeVaKLEgLpVkvg= -golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= +golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1717,8 +1717,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.6.0 h1:3XmdazWV+ubf7QgHSTWeykHOci5oeekaGJBLkrkaw4k= -golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= From 7aed2163d3e2deb4a23c462df3a1d561fcd9595a Mon Sep 17 00:00:00 2001 From: Piotr Galar Date: Mon, 6 Mar 2023 12:30:04 +0100 Subject: [PATCH 0507/1212] fix: t0116-gateway-cache.sh --- test/sharness/t0116-gateway-cache.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/sharness/t0116-gateway-cache.sh b/test/sharness/t0116-gateway-cache.sh index 508fc73c2..0cb1a94eb 100755 --- a/test/sharness/t0116-gateway-cache.sh +++ b/test/sharness/t0116-gateway-cache.sh @@ -204,7 +204,7 @@ test_expect_success "Prepare IPNS unixfs content path for testing" ' grep -E "< Etag: \"DirIndex-.+_CID-${ROOT3_CID}\"" curl_ipfs_dir_listing_output ' test_expect_success "GET /ipns/ dir response has special Etag for generated dir listing" ' - test_should_contain "< Etag: \"DirIndex" curl_ipfs_dir_listing_output && + test_should_contain "< Etag: \"DirIndex" curl_ipns_dir_listing_output && grep -E "< Etag: \"DirIndex-.+_CID-${ROOT3_CID}\"" curl_ipns_dir_listing_output ' From 7986196414f37f79d35cd4183af8d56a53b9ec48 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Wed, 1 Mar 2023 15:29:45 +0100 Subject: [PATCH 0508/1212] feat: Reduce RM code footprint Co-Authored-By: Antonio Navarro Perez --- .circleci/main.yml | 2 +- .github/workflows/build.yml | 1 + config/swarm.go | 6 +- config/types.go | 26 + core/commands/commands_test.go | 3 +- core/commands/swarm.go | 191 ++---- core/node/groups.go | 33 +- core/node/libp2p/rcmgr.go | 896 ++++++++++++----------------- core/node/libp2p/rcmgr_defaults.go | 174 ++---- core/node/libp2p/rcmgr_test.go | 12 - core/node/storage.go | 3 +- go.mod | 2 +- repo/fsrepo/fsrepo.go | 42 +- repo/mock.go | 5 + repo/repo.go | 5 + test/cli/basic_commands_test.go | 1 + test/cli/harness/node.go | 33 ++ test/cli/rcmgr_test.go | 278 +++------ test/sharness/t0060-daemon.sh | 5 +- 19 files changed, 703 insertions(+), 1015 deletions(-) delete mode 100644 core/node/libp2p/rcmgr_test.go diff --git a/.circleci/main.yml b/.circleci/main.yml index b61102692..b6be1d914 100644 --- a/.circleci/main.yml +++ b/.circleci/main.yml @@ -309,7 +309,7 @@ jobs: - run: name: Cloning command: | - git clone https://github.com/ipfs/go-ipfs-http-client.git + git clone https://github.com/ipfs/go-ipfs-http-client.git -b bump-for-rcmgr-last-push git -C go-ipfs-http-client log -1 - restore_cache: keys: diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b6bc3c595..2994d7d1a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -143,6 +143,7 @@ jobs: with: repository: ipfs/go-ipfs-http-client path: go-ipfs-http-client + ref: bump-for-rcmgr-last-push - uses: protocol/cache-go-action@v1 with: name: ${{ github.job }} diff --git a/config/swarm.go b/config/swarm.go index abff91422..d7e40e27c 100644 --- a/config/swarm.go +++ b/config/swarm.go @@ -1,7 +1,5 @@ package config -import rcmgr "github.com/libp2p/go-libp2p/p2p/host/resource-manager" - type SwarmConfig struct { // AddrFilters specifies a set libp2p addresses that we should never // dial or receive connections from. @@ -141,8 +139,8 @@ type ConnMgr struct { // type ResourceMgr struct { // Enables the Network Resource Manager feature, default to on. - Enabled Flag `json:",omitempty"` - Limits *rcmgr.PartialLimitConfig `json:",omitempty"` + Enabled Flag `json:",omitempty"` + Limits swarmLimits `json:",omitempty"` MaxMemory *OptionalString `json:",omitempty"` MaxFileDescriptors *OptionalInteger `json:",omitempty"` diff --git a/config/types.go b/config/types.go index f753827ab..3a0d4f4b3 100644 --- a/config/types.go +++ b/config/types.go @@ -1,8 +1,10 @@ package config import ( + "bytes" "encoding/json" "fmt" + "io" "strings" "time" ) @@ -412,3 +414,27 @@ func (p OptionalString) String() string { var _ json.Unmarshaler = (*OptionalInteger)(nil) var _ json.Marshaler = (*OptionalInteger)(nil) + +type swarmLimits struct{} + +var _ json.Unmarshaler = swarmLimits{} + +func (swarmLimits) UnmarshalJSON(b []byte) error { + d := json.NewDecoder(bytes.NewReader(b)) + for { + switch tok, err := d.Token(); err { + case io.EOF: + return nil + case nil: + switch tok { + case json.Delim('{'), json.Delim('}'): + // accept empty objects + continue + } + //nolint + return fmt.Errorf("The Swarm.ResourceMgr.Limits configuration has been removed in Kubo 0.19 and should be empty or not present. To set custom libp2p limits, read https://github.com/ipfs/kubo/blob/master/docs/libp2p-resource-management.md#user-supplied-override-limits") + default: + return err + } + } +} diff --git a/core/commands/commands_test.go b/core/commands/commands_test.go index 8f94e5d64..bf1b76450 100644 --- a/core/commands/commands_test.go +++ b/core/commands/commands_test.go @@ -248,13 +248,12 @@ 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", + "/swarm/resources", "/tar", "/tar/add", "/tar/cat", diff --git a/core/commands/swarm.go b/core/commands/swarm.go index a4bb705f9..7d5ae96af 100644 --- a/core/commands/swarm.go +++ b/core/commands/swarm.go @@ -1,7 +1,6 @@ package commands import ( - "bytes" "context" "encoding/json" "errors" @@ -9,10 +8,11 @@ import ( "io" "path" "sort" + "strconv" "sync" + "text/tabwriter" "time" - "github.com/ipfs/go-libipfs/files" "github.com/ipfs/kubo/commands" "github.com/ipfs/kubo/config" "github.com/ipfs/kubo/core/commands/cmdenv" @@ -57,8 +57,8 @@ ipfs peers in the internet. "filters": swarmFiltersCmd, "peers": swarmPeersCmd, "peering": swarmPeeringCmd, - "stats": swarmStatsCmd, // libp2p Network Resource Manager - "limit": swarmLimitCmd, // libp2p Network Resource Manager + "resources": swarmResourcesCmd, // libp2p Network Resource Manager + }, } @@ -323,30 +323,15 @@ var swarmPeersCmd = &cmds.Command{ Type: connInfos{}, } -var swarmStatsCmd = &cmds.Command{ +var swarmResourcesCmd = &cmds.Command{ Status: cmds.Experimental, 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 output of this command is JSON. - -To see all resources that are close to hitting their respective limit, one can do something like: - ipfs swarm stats --min-used-limit-perc=90 all + Tagline: "Get a summary of all resources accounted for by the libp2p Resource Manager.", + LongDescription: ` +Get a summary of all resources accounted for by the libp2p Resource Manager. +This includes the limits and the usage against those limits. +This can output a human readable table and JSON encoding. `}, - Arguments: []cmds.Argument{ - cmds.StringArg("scope", true, false, "scope of the stat report"), - }, - Options: []cmds.Option{ - cmds.IntOption(swarmUsedResourcesPercentageName, "Only display resources that are using above the specified percentage of their respective limit"), - }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { node, err := cmdenv.GetNode(env) if err != nil { @@ -357,128 +342,68 @@ To see all resources that are close to hitting their respective limit, one can d return libp2p.ErrNoResourceMgr } - if len(req.Arguments) != 1 { - return fmt.Errorf("must specify exactly one scope") - } - - percentage, _ := req.Options[swarmUsedResourcesPercentageName].(int) - scope := req.Arguments[0] - - if percentage != 0 && scope != "all" { - return fmt.Errorf("%q can only be used when scope is %q", swarmUsedResourcesPercentageName, "all") - } - - result, err := libp2p.NetStat(node.ResourceManager, scope, percentage) + cfg, err := node.Repo.Config() 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) - }, - Encoders: cmds.EncoderMap{ - cmds.Text: HumanJSONEncoder, - }, -} - -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. -The scope can be one of the following: -- all -- all limits actually being applied. -- 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 persisted in the Swarm.ResourceMgr.Limits field of the $IPFS_PATH/config file. -`}, - Arguments: []cmds.Argument{ - cmds.StringArg("scope", true, false, "scope of the limit"), - cmds.FileArg("limit.json", false, false, "limits to be set").EnableStdin(), - }, - Options: []cmds.Option{ - cmds.BoolOption(swarmResetLimitsOptionName, "reset limit to default"), - }, - Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - node, err := cmdenv.GetNode(env) + userResourceOverrides, err := node.Repo.UserResourceOverrides() if err != nil { return err } - if node.ResourceManager == nil { + // FIXME: we shouldn't recompute limits, either save them or load them from libp2p (https://github.com/libp2p/go-libp2p/issues/2166) + limitConfig, _, err := libp2p.LimitConfig(cfg.Swarm, userResourceOverrides) + if err != nil { + return err + } + + rapi, ok := node.ResourceManager.(rcmgr.ResourceManagerState) + if !ok { // NullResourceManager return libp2p.ErrNoResourceMgr } - scope := req.Arguments[0] - - // set scope limit to new values (when limit.json is passed as a second arg) - if req.Files != nil { - var newLimit rcmgr.ResourceLimits - it := req.Files.Entries() - if it.Next() { - file := files.FileFromEntry(it) - if file == nil { - return errors.New("expected a JSON file") - } - - r := io.LimitReader(file, 32*1024*1024) // 32MiB - - if err := json.NewDecoder(r).Decode(&newLimit); err != nil { - return fmt.Errorf("decoding JSON as ResourceMgrScopeConfig: %w", err) - } - return libp2p.NetSetLimit(node.ResourceManager, node.Repo, scope, newLimit) - } - if err := it.Err(); err != nil { - return fmt.Errorf("error opening limit JSON file: %w", err) - } - } - - var result interface{} - switch _, reset := req.Options[swarmResetLimitsOptionName]; { - case reset: - result, err = libp2p.NetResetLimit(node.ResourceManager, node.Repo, scope) - case scope == "all": - result, err = libp2p.NetLimitAll(node.ResourceManager) - default: - // get scope limit - result, err = libp2p.NetLimit(node.ResourceManager, scope) - } - if err != nil { - return err - } - - if base, ok := result.(rcmgr.BaseLimit); ok { - result = base.ToResourceLimits() - } - - b := new(bytes.Buffer) - enc := json.NewEncoder(b) - err = enc.Encode(result) - if err != nil { - return err - } - return cmds.EmitOnce(res, b) + return cmds.EmitOnce(res, libp2p.MergeLimitsAndStatsIntoLimitsConfigAndUsage(limitConfig, rapi.Stat())) }, Encoders: cmds.EncoderMap{ - cmds.Text: HumanJSONEncoder, + cmds.JSON: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, limitsAndUsage libp2p.LimitsConfigAndUsage) error { + return json.NewEncoder(w).Encode(limitsAndUsage) + }), + cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, limitsAndUsage libp2p.LimitsConfigAndUsage) error { + tw := tabwriter.NewWriter(w, 20, 8, 0, '\t', 0) + defer tw.Flush() + + fmt.Fprintf(tw, "%s\t%s\t%s\t%s\t%s\t\n", "Scope", "Limit Name", "Limit Value", "Limit Usage Amount", "Limit Usage Percent") + for _, ri := range libp2p.LimitConfigsToInfo(limitsAndUsage) { + var limit, percentage string + switch ri.LimitValue { + case rcmgr.Unlimited64: + limit = "unlimited" + percentage = "n/a" + case rcmgr.BlockAllLimit64: + limit = "blockAll" + percentage = "n/a" + default: + limit = strconv.FormatInt(int64(ri.LimitValue), 10) + if ri.CurrentUsage == 0 { + percentage = "0%" + } else { + percentage = strconv.FormatFloat(float64(ri.CurrentUsage)/float64(ri.LimitValue)*100, 'f', 1, 64) + "%" + } + } + fmt.Fprintf(tw, "%s\t%s\t%s\t%d\t%s\t\n", + ri.ScopeName, + ri.LimitName, + limit, + ri.CurrentUsage, + percentage, + ) + } + + return nil + }), }, + Type: libp2p.LimitsConfigAndUsage{}, } type streamInfo struct { diff --git a/core/node/groups.go b/core/node/groups.go index e640feff1..866204ce3 100644 --- a/core/node/groups.go +++ b/core/node/groups.go @@ -6,21 +6,19 @@ import ( "fmt" "time" + "github.com/dustin/go-humanize" blockstore "github.com/ipfs/go-ipfs-blockstore" + offline "github.com/ipfs/go-ipfs-exchange-offline" util "github.com/ipfs/go-ipfs-util" "github.com/ipfs/go-log" + uio "github.com/ipfs/go-unixfs/io" "github.com/ipfs/kubo/config" + "github.com/ipfs/kubo/core/node/libp2p" + "github.com/ipfs/kubo/p2p" pubsub "github.com/libp2p/go-libp2p-pubsub" "github.com/libp2p/go-libp2p-pubsub/timecache" "github.com/libp2p/go-libp2p/core/peer" - - "github.com/ipfs/kubo/core/node/libp2p" - "github.com/ipfs/kubo/p2p" - - offline "github.com/ipfs/go-ipfs-exchange-offline" - uio "github.com/ipfs/go-unixfs/io" - - "github.com/dustin/go-humanize" + rcmgr "github.com/libp2p/go-libp2p/p2p/host/resource-manager" "go.uber.org/fx" ) @@ -37,7 +35,7 @@ var BaseLibP2P = fx.Options( fx.Invoke(libp2p.PNetChecker), ) -func LibP2P(bcfg *BuildCfg, cfg *config.Config) fx.Option { +func LibP2P(bcfg *BuildCfg, cfg *config.Config, userResourceOverrides rcmgr.PartialLimitConfig) fx.Option { var connmgr fx.Option // set connmgr based on Swarm.ConnMgr.Type @@ -150,7 +148,7 @@ func LibP2P(bcfg *BuildCfg, cfg *config.Config) fx.Option { fx.Provide(libp2p.UserAgent()), // Services (resource management) - fx.Provide(libp2p.ResourceManager(cfg.Swarm)), + fx.Provide(libp2p.ResourceManager(cfg.Swarm, userResourceOverrides)), 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)), @@ -249,7 +247,7 @@ var IPNS = fx.Options( ) // Online groups online-only units -func Online(bcfg *BuildCfg, cfg *config.Config) fx.Option { +func Online(bcfg *BuildCfg, cfg *config.Config, userResourceOverrides rcmgr.PartialLimitConfig) fx.Option { // Namesys params @@ -303,7 +301,7 @@ func Online(bcfg *BuildCfg, cfg *config.Config) fx.Option { fx.Provide(p2p.New), - LibP2P(bcfg, cfg), + LibP2P(bcfg, cfg, userResourceOverrides), OnlineProviders( cfg.Experimental.StrategicProviding, cfg.Experimental.AcceleratedDHTClient, @@ -340,9 +338,9 @@ var Core = fx.Options( fx.Provide(Files), ) -func Networked(bcfg *BuildCfg, cfg *config.Config) fx.Option { +func Networked(bcfg *BuildCfg, cfg *config.Config, userResourceOverrides rcmgr.PartialLimitConfig) fx.Option { if bcfg.Online { - return Online(bcfg, cfg) + return Online(bcfg, cfg, userResourceOverrides) } return Offline(cfg) } @@ -358,6 +356,11 @@ func IPFS(ctx context.Context, bcfg *BuildCfg) fx.Option { return bcfgOpts // error } + userResourceOverrides, err := bcfg.Repo.UserResourceOverrides() + if err != nil { + return fx.Error(err) + } + // Auto-sharding settings shardSizeString := cfg.Internal.UnixFSShardingSizeThreshold.WithDefault("256kiB") shardSizeInt, err := humanize.ParseBytes(shardSizeString) @@ -381,7 +384,7 @@ func IPFS(ctx context.Context, bcfg *BuildCfg) fx.Option { Storage(bcfg, cfg), Identity(cfg), IPNS, - Networked(bcfg, cfg), + Networked(bcfg, cfg, userResourceOverrides), Core, ) diff --git a/core/node/libp2p/rcmgr.go b/core/node/libp2p/rcmgr.go index 0d7ac761c..54bff2852 100644 --- a/core/node/libp2p/rcmgr.go +++ b/core/node/libp2p/rcmgr.go @@ -2,10 +2,10 @@ package libp2p import ( "context" + "encoding/json" "fmt" "os" "path/filepath" - "strings" "github.com/benbjohnson/clock" logging "github.com/ipfs/go-log/v2" @@ -17,21 +17,17 @@ import ( rcmgrObs "github.com/libp2p/go-libp2p/p2p/host/resource-manager/obs" "github.com/multiformats/go-multiaddr" "go.uber.org/fx" - "golang.org/x/exp/constraints" "github.com/ipfs/kubo/config" "github.com/ipfs/kubo/core/node/helpers" "github.com/ipfs/kubo/repo" ) -// FIXME(@Jorropo): for go-libp2p v0.26.0 use .MustConcrete and .MustBaseLimit instead of .Build(rcmgr.BaseLimit{}). - -const NetLimitDefaultFilename = "limit.json" const NetLimitTraceFilename = "rcmgr.json.gz" var ErrNoResourceMgr = fmt.Errorf("missing ResourceMgr: make sure the daemon is running with Swarm.ResourceMgr.Enabled") -func ResourceManager(cfg config.SwarmConfig) interface{} { +func ResourceManager(cfg config.SwarmConfig, userResourceOverrides rcmgr.PartialLimitConfig) interface{} { return func(mctx helpers.MetricsCtx, lc fx.Lifecycle, repo repo.Repo) (network.ResourceManager, Libp2pOpts, error) { var manager network.ResourceManager var opts Libp2pOpts @@ -54,32 +50,25 @@ func ResourceManager(cfg config.SwarmConfig) interface{} { return nil, opts, fmt.Errorf("opening IPFS_PATH: %w", err) } - var limitConfig rcmgr.ConcreteLimitConfig - defaultComputedLimitConfig, err := createDefaultLimitConfig(cfg) + limitConfig, msg, err := LimitConfig(cfg, userResourceOverrides) if err != nil { + return nil, opts, fmt.Errorf("creating final Resource Manager config: %w", err) + } + + if !isPartialConfigEmpty(userResourceOverrides) { + fmt.Print(` +libp2p-resource-limit-overrides.json has been loaded, "default" fields will be +filled in with autocomputed defaults. +`) + } + + // We want to see this message on startup, that's why we are using fmt instead of log. + fmt.Print(msg) + + if err := ensureConnMgrMakeSenseVsResourceMgr(limitConfig, cfg); err != nil { return nil, opts, err } - // The logic for defaults and overriding with specified SwarmConfig.ResourceMgr.Limits - // is documented in docs/config.md. - // Any changes here should be reflected there. - if cfg.ResourceMgr.Limits != nil { - userSuppliedOverrideLimitConfig := *cfg.ResourceMgr.Limits - // This effectively overrides the computed default LimitConfig with any non-zero values from cfg.ResourceMgr.Limits. - // Because of how how Apply works, any 0 value for a user supplied override - // will be overriden with a computed default value. - // There currently isn't a way for a user to supply a 0-value override. - limitConfig = userSuppliedOverrideLimitConfig.Build(defaultComputedLimitConfig) - } else { - limitConfig = defaultComputedLimitConfig - } - - if err := ensureConnMgrMakeSenseVsResourceMgr(limitConfig, cfg.ConnMgr); err != nil { - return nil, opts, err - } - - limiter := rcmgr.NewFixedLimiter(limitConfig) - str, err := rcmgrObs.NewStatsTraceReporter() if err != nil { return nil, opts, err @@ -106,6 +95,8 @@ func ResourceManager(cfg config.SwarmConfig) interface{} { ropts = append(ropts, rcmgr.WithTrace(traceFilePath)) } + limiter := rcmgr.NewFixedLimiter(limitConfig) + manager, err = rcmgr.NewResourceManager(limiter, ropts...) if err != nil { return nil, opts, fmt.Errorf("creating libp2p resource manager: %w", err) @@ -133,540 +124,363 @@ func ResourceManager(cfg config.SwarmConfig) interface{} { } } -type notOmitEmptyResourceLimit struct { - Streams rcmgr.LimitVal - StreamsInbound rcmgr.LimitVal - StreamsOutbound rcmgr.LimitVal - Conns rcmgr.LimitVal - ConnsInbound rcmgr.LimitVal - ConnsOutbound rcmgr.LimitVal - FD rcmgr.LimitVal - Memory rcmgr.LimitVal64 -} - -func resourceLimitsToNotOmitEmpty(r rcmgr.ResourceLimits) notOmitEmptyResourceLimit { - return notOmitEmptyResourceLimit{ - Streams: r.Streams, - StreamsInbound: r.StreamsInbound, - StreamsOutbound: r.StreamsOutbound, - Conns: r.Conns, - ConnsInbound: r.ConnsInbound, - ConnsOutbound: r.ConnsOutbound, - FD: r.FD, - Memory: r.Memory, - } -} - -type NetStatOut struct { - System *notOmitEmptyResourceLimit `json:",omitempty"` - Transient *notOmitEmptyResourceLimit `json:",omitempty"` - Services map[string]notOmitEmptyResourceLimit `json:",omitempty"` - Protocols map[string]notOmitEmptyResourceLimit `json:",omitempty"` - Peers map[string]notOmitEmptyResourceLimit `json:",omitempty"` -} - -func NetStat(mgr network.ResourceManager, scope string, percentage int) (NetStatOut, error) { - var err error - var result NetStatOut - switch { - case scope == "all": - rapi, ok := mgr.(rcmgr.ResourceManagerState) - if !ok { // NullResourceManager - return result, ErrNoResourceMgr - } - - limits, err := NetLimitAll(mgr) - if err != nil { - return result, err - } - - stat := rapi.Stat() - if s := scopeToLimit(stat.System); compareLimits(s, *limits.System, percentage) { - result.System = &s - } - if s := scopeToLimit(stat.Transient); compareLimits(s, *limits.Transient, percentage) { - result.Transient = &s - } - if len(stat.Services) > 0 { - result.Services = make(map[string]notOmitEmptyResourceLimit, len(stat.Services)) - for srv, s := range stat.Services { - ls := limits.Services[srv] - if stat := scopeToLimit(s); compareLimits(stat, ls, percentage) { - result.Services[srv] = stat - } - } - } - if len(stat.Protocols) > 0 { - result.Protocols = make(map[string]notOmitEmptyResourceLimit, len(stat.Protocols)) - for proto, s := range stat.Protocols { - ls := limits.Protocols[string(proto)] - if stat := scopeToLimit(s); compareLimits(stat, ls, percentage) { - result.Protocols[string(proto)] = stat - } - } - } - if len(stat.Peers) > 0 { - result.Peers = make(map[string]notOmitEmptyResourceLimit, len(stat.Peers)) - for p, s := range stat.Peers { - ls := limits.Peers[p.Pretty()] - if stat := scopeToLimit(s); compareLimits(stat, ls, percentage) { - result.Peers[p.Pretty()] = stat - } - } - } - - return result, nil - - case scope == config.ResourceMgrSystemScope: - err = mgr.ViewSystem(func(s network.ResourceScope) error { - stat := scopeToLimit(s.Stat()) - result.System = &stat - return nil - }) - return result, err - - case scope == config.ResourceMgrTransientScope: - err = mgr.ViewTransient(func(s network.ResourceScope) error { - stat := scopeToLimit(s.Stat()) - result.Transient = &stat - return nil - }) - return result, err - - case strings.HasPrefix(scope, config.ResourceMgrServiceScopePrefix): - svc := strings.TrimPrefix(scope, config.ResourceMgrServiceScopePrefix) - err = mgr.ViewService(svc, func(s network.ServiceScope) error { - result.Services = map[string]notOmitEmptyResourceLimit{ - svc: scopeToLimit(s.Stat()), - } - return nil - }) - return result, err - - case strings.HasPrefix(scope, config.ResourceMgrProtocolScopePrefix): - proto := strings.TrimPrefix(scope, config.ResourceMgrProtocolScopePrefix) - err = mgr.ViewProtocol(protocol.ID(proto), func(s network.ProtocolScope) error { - result.Protocols = map[string]notOmitEmptyResourceLimit{ - proto: scopeToLimit(s.Stat()), - } - return nil - }) - return result, err - - case strings.HasPrefix(scope, config.ResourceMgrPeerScopePrefix): - 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) - } - err = mgr.ViewPeer(pid, func(s network.PeerScope) error { - result.Peers = map[string]notOmitEmptyResourceLimit{ - p: scopeToLimit(s.Stat()), - } - return nil - }) - return result, err - - default: - return result, fmt.Errorf("invalid scope %q", scope) - } -} - -var scopes = []string{ - config.ResourceMgrSystemScope, - config.ResourceMgrTransientScope, - config.ResourceMgrServiceScopePrefix, - config.ResourceMgrProtocolScopePrefix, - config.ResourceMgrPeerScopePrefix, -} - -func scopeToLimit(s network.ScopeStat) notOmitEmptyResourceLimit { - return notOmitEmptyResourceLimit{ - Streams: rcmgr.LimitVal(s.NumStreamsInbound + s.NumStreamsOutbound), - StreamsInbound: rcmgr.LimitVal(s.NumStreamsInbound), - StreamsOutbound: rcmgr.LimitVal(s.NumStreamsOutbound), - Conns: rcmgr.LimitVal(s.NumConnsInbound + s.NumConnsOutbound), - ConnsInbound: rcmgr.LimitVal(s.NumConnsInbound), - ConnsOutbound: rcmgr.LimitVal(s.NumConnsOutbound), - FD: rcmgr.LimitVal(s.NumFD), - Memory: rcmgr.LimitVal64(s.Memory), - } -} - -// compareLimits compares stat and limit. -// If any of the stats value are equals or above the specified percentage, -// it returns true. -func compareLimits(stat, limit notOmitEmptyResourceLimit, percentage int) bool { - if abovePercentage(int(stat.Memory), int(limit.Memory), percentage) { - return true - } - if abovePercentage(stat.ConnsInbound, limit.ConnsInbound, percentage) { - return true - } - if abovePercentage(stat.ConnsOutbound, limit.ConnsOutbound, percentage) { - return true - } - if abovePercentage(stat.Conns, limit.Conns, percentage) { - return true - } - if abovePercentage(stat.FD, limit.FD, percentage) { - return true - } - if abovePercentage(stat.StreamsInbound, limit.StreamsInbound, percentage) { - return true - } - if abovePercentage(stat.StreamsOutbound, limit.StreamsOutbound, percentage) { - return true - } - if abovePercentage(stat.Streams, limit.Streams, percentage) { - return true - } - - return false -} - -func abovePercentage[T constraints.Integer | constraints.Float](v1, v2 T, percentage int) bool { - if percentage == 0 { - return true - } - - if v2 == 0 { +func isPartialConfigEmpty(cfg rcmgr.PartialLimitConfig) bool { + var emptyResourceConfig rcmgr.ResourceLimits + if cfg.System != emptyResourceConfig || + cfg.Transient != emptyResourceConfig || + cfg.AllowlistedSystem != emptyResourceConfig || + cfg.AllowlistedTransient != emptyResourceConfig || + cfg.ServiceDefault != emptyResourceConfig || + cfg.ServicePeerDefault != emptyResourceConfig || + cfg.ProtocolDefault != emptyResourceConfig || + cfg.ProtocolPeerDefault != emptyResourceConfig || + cfg.PeerDefault != emptyResourceConfig || + cfg.Conn != emptyResourceConfig || + cfg.Stream != emptyResourceConfig { return false } - - return int((float64(v1)/float64(v2))*100) >= percentage -} - -func NetLimitAll(mgr network.ResourceManager) (*NetStatOut, error) { - var result = &NetStatOut{} - lister, ok := mgr.(rcmgr.ResourceManagerState) - if !ok { // NullResourceManager - return result, ErrNoResourceMgr - } - - for _, s := range scopes { - switch s { - case config.ResourceMgrSystemScope: - s, err := NetLimit(mgr, config.ResourceMgrSystemScope) - if err != nil { - return nil, err - } - result.System = &s - case config.ResourceMgrTransientScope: - s, err := NetLimit(mgr, config.ResourceMgrSystemScope) - if err != nil { - return nil, err - } - result.Transient = &s - case config.ResourceMgrServiceScopePrefix: - result.Services = make(map[string]notOmitEmptyResourceLimit) - for _, serv := range lister.ListServices() { - s, err := NetLimit(mgr, config.ResourceMgrServiceScopePrefix+serv) - if err != nil { - return nil, err - } - result.Services[serv] = s - } - case config.ResourceMgrProtocolScopePrefix: - result.Protocols = make(map[string]notOmitEmptyResourceLimit) - for _, prot := range lister.ListProtocols() { - ps := string(prot) - s, err := NetLimit(mgr, config.ResourceMgrProtocolScopePrefix+ps) - if err != nil { - return nil, err - } - result.Protocols[ps] = s - } - case config.ResourceMgrPeerScopePrefix: - result.Peers = make(map[string]notOmitEmptyResourceLimit) - for _, peer := range lister.ListPeers() { - ps := peer.Pretty() - s, err := NetLimit(mgr, config.ResourceMgrPeerScopePrefix+ps) - if err != nil { - return nil, err - } - result.Peers[ps] = s - } + for _, v := range cfg.Service { + if v != emptyResourceConfig { + return false } } - - return result, nil + for _, v := range cfg.ServicePeer { + if v != emptyResourceConfig { + return false + } + } + for _, v := range cfg.Protocol { + if v != emptyResourceConfig { + return false + } + } + for _, v := range cfg.ProtocolPeer { + if v != emptyResourceConfig { + return false + } + } + for _, v := range cfg.Peer { + if v != emptyResourceConfig { + return false + } + } + return true } -func NetLimit(mgr network.ResourceManager, scope string) (notOmitEmptyResourceLimit, error) { - var result rcmgr.ResourceLimits - getLimit := func(s network.ResourceScope) error { - limiter, ok := s.(rcmgr.ResourceScopeLimiter) - if !ok { // NullResourceManager - return ErrNoResourceMgr +// LimitConfig returns the union of the Computed Default Limits and the User Supplied Override Limits. +func LimitConfig(cfg config.SwarmConfig, userResourceOverrides rcmgr.PartialLimitConfig) (limitConfig rcmgr.ConcreteLimitConfig, logMessageForStartup string, err error) { + limitConfig, msg, err := createDefaultLimitConfig(cfg) + if err != nil { + return rcmgr.ConcreteLimitConfig{}, msg, err + } + + // The logic for defaults and overriding with specified userResourceOverrides + // is documented in docs/libp2p-resource-management.md. + // Any changes here should be reflected there. + + // This effectively overrides the computed default LimitConfig with any non-"useDefault" values from the userResourceOverrides file. + // Because of how how Build works, any rcmgr.Default value in userResourceOverrides + // will be overriden with a computed default value. + limitConfig = userResourceOverrides.Build(limitConfig) + + return limitConfig, msg, nil +} + +type ResourceLimitsAndUsage struct { + // This is duplicated from rcmgr.ResourceResourceLimits but adding *Usage fields. + Memory rcmgr.LimitVal64 + MemoryUsage int64 + FD rcmgr.LimitVal + FDUsage int + Conns rcmgr.LimitVal + ConnsUsage int + ConnsInbound rcmgr.LimitVal + ConnsInboundUsage int + ConnsOutbound rcmgr.LimitVal + ConnsOutboundUsage int + Streams rcmgr.LimitVal + StreamsUsage int + StreamsInbound rcmgr.LimitVal + StreamsInboundUsage int + StreamsOutbound rcmgr.LimitVal + StreamsOutboundUsage int +} + +func (u ResourceLimitsAndUsage) ToResourceLimits() rcmgr.ResourceLimits { + return rcmgr.ResourceLimits{ + Memory: u.Memory, + FD: u.FD, + Conns: u.Conns, + ConnsInbound: u.ConnsInbound, + ConnsOutbound: u.ConnsOutbound, + Streams: u.Streams, + StreamsInbound: u.StreamsInbound, + StreamsOutbound: u.StreamsOutbound, + } +} + +type LimitsConfigAndUsage struct { + // This is duplicated from rcmgr.ResourceManagerStat but using ResourceLimitsAndUsage + // instead of network.ScopeStat. + System ResourceLimitsAndUsage `json:",omitempty"` + Transient ResourceLimitsAndUsage `json:",omitempty"` + Services map[string]ResourceLimitsAndUsage `json:",omitempty"` + Protocols map[protocol.ID]ResourceLimitsAndUsage `json:",omitempty"` + Peers map[peer.ID]ResourceLimitsAndUsage `json:",omitempty"` +} + +func (u LimitsConfigAndUsage) MarshalJSON() ([]byte, error) { + // we want to marshal the encoded peer id + encodedPeerMap := make(map[string]ResourceLimitsAndUsage, len(u.Peers)) + for p, v := range u.Peers { + encodedPeerMap[p.String()] = v + } + + type Alias LimitsConfigAndUsage + return json.Marshal(&struct { + *Alias + Peers map[string]ResourceLimitsAndUsage `json:",omitempty"` + }{ + Alias: (*Alias)(&u), + Peers: encodedPeerMap, + }) +} + +func (u LimitsConfigAndUsage) ToPartialLimitConfig() (result rcmgr.PartialLimitConfig) { + result.System = u.System.ToResourceLimits() + result.Transient = u.Transient.ToResourceLimits() + + result.Service = make(map[string]rcmgr.ResourceLimits, len(u.Services)) + for s, l := range u.Services { + result.Service[s] = l.ToResourceLimits() + } + result.Protocol = make(map[protocol.ID]rcmgr.ResourceLimits, len(u.Protocols)) + for p, l := range u.Protocols { + result.Protocol[p] = l.ToResourceLimits() + } + result.Peer = make(map[peer.ID]rcmgr.ResourceLimits, len(u.Peers)) + for p, l := range u.Peers { + result.Peer[p] = l.ToResourceLimits() + } + + return +} + +func MergeLimitsAndStatsIntoLimitsConfigAndUsage(l rcmgr.ConcreteLimitConfig, stats rcmgr.ResourceManagerStat) LimitsConfigAndUsage { + limits := l.ToPartialLimitConfig() + + return LimitsConfigAndUsage{ + System: mergeResourceLimitsAndScopeStatToResourceLimitsAndUsage(limits.System, stats.System), + Transient: mergeResourceLimitsAndScopeStatToResourceLimitsAndUsage(limits.Transient, stats.Transient), + Services: mergeLimitsAndStatsMapIntoLimitsConfigAndUsageMap(limits.Service, stats.Services), + Protocols: mergeLimitsAndStatsMapIntoLimitsConfigAndUsageMap(limits.Protocol, stats.Protocols), + Peers: mergeLimitsAndStatsMapIntoLimitsConfigAndUsageMap(limits.Peer, stats.Peers), + } +} + +func mergeLimitsAndStatsMapIntoLimitsConfigAndUsageMap[K comparable](limits map[K]rcmgr.ResourceLimits, stats map[K]network.ScopeStat) map[K]ResourceLimitsAndUsage { + r := make(map[K]ResourceLimitsAndUsage, maxInt(len(limits), len(stats))) + for p, s := range stats { + var l rcmgr.ResourceLimits + if limits != nil { + if rl, ok := limits[p]; ok { + l = rl + } + } + r[p] = mergeResourceLimitsAndScopeStatToResourceLimitsAndUsage(l, s) + } + for p, s := range limits { + if _, ok := stats[p]; ok { + continue // we already processed this element in the loop above } - switch limit := limiter.Limit(); l := limit.(type) { - case *rcmgr.BaseLimit: - result = l.ToResourceLimits() - case rcmgr.BaseLimit: - result = l.ToResourceLimits() - default: - return fmt.Errorf("unknown limit type %T", limit) + r[p] = mergeResourceLimitsAndScopeStatToResourceLimitsAndUsage(s, network.ScopeStat{}) + } + return r +} + +func maxInt(x, y int) int { + if x > y { + return x + } + return y +} + +func mergeResourceLimitsAndScopeStatToResourceLimitsAndUsage(rl rcmgr.ResourceLimits, ss network.ScopeStat) ResourceLimitsAndUsage { + return ResourceLimitsAndUsage{ + Memory: rl.Memory, + MemoryUsage: ss.Memory, + FD: rl.FD, + FDUsage: ss.NumFD, + Conns: rl.Conns, + ConnsUsage: ss.NumConnsOutbound + ss.NumConnsInbound, + ConnsOutbound: rl.ConnsOutbound, + ConnsOutboundUsage: ss.NumConnsOutbound, + ConnsInbound: rl.ConnsInbound, + ConnsInboundUsage: ss.NumConnsInbound, + Streams: rl.Streams, + StreamsUsage: ss.NumStreamsOutbound + ss.NumConnsInbound, + StreamsOutbound: rl.StreamsOutbound, + StreamsOutboundUsage: ss.NumConnsOutbound, + StreamsInbound: rl.StreamsInbound, + StreamsInboundUsage: ss.NumConnsInbound, + } +} + +type ResourceInfos []ResourceInfo + +type ResourceInfo struct { + ScopeName string + LimitName string + LimitValue rcmgr.LimitVal64 + CurrentUsage int64 +} + +// LimitConfigsToInfo gets limits and stats and generates a list of scopes and limits to be printed. +func LimitConfigsToInfo(stats LimitsConfigAndUsage) ResourceInfos { + result := ResourceInfos{} + + result = append(result, resourceLimitsAndUsageToResourceInfo(config.ResourceMgrSystemScope, stats.System)...) + result = append(result, resourceLimitsAndUsageToResourceInfo(config.ResourceMgrTransientScope, stats.Transient)...) + + for i, s := range stats.Services { + result = append(result, resourceLimitsAndUsageToResourceInfo( + config.ResourceMgrServiceScopePrefix+i, + s, + )...) + } + + for i, p := range stats.Protocols { + result = append(result, resourceLimitsAndUsageToResourceInfo( + config.ResourceMgrProtocolScopePrefix+string(i), + p, + )...) + } + + for i, p := range stats.Peers { + result = append(result, resourceLimitsAndUsageToResourceInfo( + config.ResourceMgrPeerScopePrefix+i.Pretty(), + p, + )...) + } + + return result +} + +const ( + limitNameMemory = "Memory" + limitNameFD = "FD" + limitNameConns = "Conns" + limitNameConnsInbound = "ConnsInbound" + limitNameConnsOutbound = "ConnsOutbound" + limitNameStreams = "Streams" + limitNameStreamsInbound = "StreamsInbound" + limitNameStreamsOutbound = "StreamsOutbound" +) + +var limits = []string{ + limitNameMemory, + limitNameFD, + limitNameConns, + limitNameConnsInbound, + limitNameConnsOutbound, + limitNameStreams, + limitNameStreamsInbound, + limitNameStreamsOutbound, +} + +func resourceLimitsAndUsageToResourceInfo(scopeName string, stats ResourceLimitsAndUsage) ResourceInfos { + result := ResourceInfos{} + for _, l := range limits { + ri := ResourceInfo{ + ScopeName: scopeName, + } + switch l { + case limitNameMemory: + ri.LimitName = limitNameMemory + ri.LimitValue = stats.Memory + ri.CurrentUsage = stats.MemoryUsage + case limitNameFD: + ri.LimitName = limitNameFD + ri.LimitValue = rcmgr.LimitVal64(stats.FD) + ri.CurrentUsage = int64(stats.FDUsage) + case limitNameConns: + ri.LimitName = limitNameConns + ri.LimitValue = rcmgr.LimitVal64(stats.Conns) + ri.CurrentUsage = int64(stats.ConnsUsage) + case limitNameConnsInbound: + ri.LimitName = limitNameConnsInbound + ri.LimitValue = rcmgr.LimitVal64(stats.ConnsInbound) + ri.CurrentUsage = int64(stats.ConnsInboundUsage) + case limitNameConnsOutbound: + ri.LimitName = limitNameConnsOutbound + ri.LimitValue = rcmgr.LimitVal64(stats.ConnsOutbound) + ri.CurrentUsage = int64(stats.ConnsOutboundUsage) + case limitNameStreams: + ri.LimitName = limitNameStreams + ri.LimitValue = rcmgr.LimitVal64(stats.Streams) + ri.CurrentUsage = int64(stats.StreamsUsage) + case limitNameStreamsInbound: + ri.LimitName = limitNameStreamsInbound + ri.LimitValue = rcmgr.LimitVal64(stats.StreamsInbound) + ri.CurrentUsage = int64(stats.StreamsInboundUsage) + case limitNameStreamsOutbound: + ri.LimitName = limitNameStreamsOutbound + ri.LimitValue = rcmgr.LimitVal64(stats.StreamsOutbound) + ri.CurrentUsage = int64(stats.StreamsOutboundUsage) } + if ri.LimitValue == rcmgr.Unlimited64 || ri.LimitValue == rcmgr.DefaultLimit64 { + // ignore unlimited and unset limits to remove noise from output. + continue + } + + result = append(result, ri) + } + + return result +} + +func ensureConnMgrMakeSenseVsResourceMgr(concreteLimits rcmgr.ConcreteLimitConfig, cfg config.SwarmConfig) error { + if cfg.ConnMgr.Type.WithDefault(config.DefaultConnMgrType) == "none" || len(cfg.ResourceMgr.Allowlist) != 0 { + // no connmgr OR + // If an allowlist is set, a user may be enacting some form of DoS defense. + // We don't want want to modify the System.ConnsInbound in that case for example + // as it may make sense for it to be (and stay) as "blockAll" + // so that only connections within the allowlist of multiaddrs get established. return nil } - var err error - switch { - case scope == config.ResourceMgrSystemScope: - err = mgr.ViewSystem(func(s network.ResourceScope) error { return getLimit(s) }) - case scope == config.ResourceMgrTransientScope: - err = mgr.ViewTransient(func(s network.ResourceScope) error { return getLimit(s) }) - case strings.HasPrefix(scope, config.ResourceMgrServiceScopePrefix): - svc := strings.TrimPrefix(scope, config.ResourceMgrServiceScopePrefix) - err = mgr.ViewService(svc, func(s network.ServiceScope) error { return getLimit(s) }) - case strings.HasPrefix(scope, config.ResourceMgrProtocolScopePrefix): - proto := strings.TrimPrefix(scope, config.ResourceMgrProtocolScopePrefix) - err = mgr.ViewProtocol(protocol.ID(proto), func(s network.ProtocolScope) error { return getLimit(s) }) - case strings.HasPrefix(scope, config.ResourceMgrPeerScopePrefix): - p := strings.TrimPrefix(scope, config.ResourceMgrPeerScopePrefix) - var pid peer.ID - pid, err = peer.Decode(p) - if err != nil { - return notOmitEmptyResourceLimit{}, fmt.Errorf("invalid peer ID: %q: %w", p, err) - } - err = mgr.ViewPeer(pid, func(s network.PeerScope) error { return getLimit(s) }) - default: - err = fmt.Errorf("invalid scope %q", scope) - } - return resourceLimitsToNotOmitEmpty(result), err -} + rcm := concreteLimits.ToPartialLimitConfig() -// NetSetLimit sets new ResourceManager limits for the given scope. The limits take effect immediately, and are also persisted to the repo config. -func NetSetLimit(mgr network.ResourceManager, repo repo.Repo, scope string, limit rcmgr.ResourceLimits) error { - setLimit := func(s network.ResourceScope) error { - limiter, ok := s.(rcmgr.ResourceScopeLimiter) - if !ok { // NullResourceManager - return ErrNoResourceMgr - } - - l := rcmgr.InfiniteLimits.ToPartialLimitConfig().System - limiter.SetLimit(limit.Build(l.Build(rcmgr.BaseLimit{}))) - return nil - } - - cfg, err := repo.Config() - if err != nil { - return fmt.Errorf("reading config to set limit: %w", err) - } - - if cfg.Swarm.ResourceMgr.Limits == nil { - cfg.Swarm.ResourceMgr.Limits = &rcmgr.PartialLimitConfig{} - } - configLimits := cfg.Swarm.ResourceMgr.Limits - - var setConfigFunc func() - switch { - case scope == config.ResourceMgrSystemScope: - err = mgr.ViewSystem(func(s network.ResourceScope) error { return setLimit(s) }) - setConfigFunc = func() { configLimits.System = limit } - case scope == config.ResourceMgrTransientScope: - err = mgr.ViewTransient(func(s network.ResourceScope) error { return setLimit(s) }) - setConfigFunc = func() { configLimits.Transient = limit } - case strings.HasPrefix(scope, config.ResourceMgrServiceScopePrefix): - svc := strings.TrimPrefix(scope, config.ResourceMgrServiceScopePrefix) - err = mgr.ViewService(svc, func(s network.ServiceScope) error { return setLimit(s) }) - setConfigFunc = func() { - if configLimits.Service == nil { - configLimits.Service = map[string]rcmgr.ResourceLimits{} - } - configLimits.Service[svc] = limit - } - case strings.HasPrefix(scope, config.ResourceMgrProtocolScopePrefix): - proto := strings.TrimPrefix(scope, config.ResourceMgrProtocolScopePrefix) - err = mgr.ViewProtocol(protocol.ID(proto), func(s network.ProtocolScope) error { return setLimit(s) }) - setConfigFunc = func() { - if configLimits.Protocol == nil { - configLimits.Protocol = map[protocol.ID]rcmgr.ResourceLimits{} - } - configLimits.Protocol[protocol.ID(proto)] = limit - } - case strings.HasPrefix(scope, config.ResourceMgrPeerScopePrefix): - p := strings.TrimPrefix(scope, config.ResourceMgrPeerScopePrefix) - var pid peer.ID - 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) }) - setConfigFunc = func() { - if configLimits.Peer == nil { - configLimits.Peer = map[peer.ID]rcmgr.ResourceLimits{} - } - configLimits.Peer[pid] = limit - } - default: - return fmt.Errorf("invalid scope %q", scope) - } - - if err != nil { - return fmt.Errorf("setting new limits on resource manager: %w", err) - } - - if cfg.Swarm.ResourceMgr.Limits == nil { - cfg.Swarm.ResourceMgr.Limits = &rcmgr.PartialLimitConfig{} - } - setConfigFunc() - - if err := repo.SetConfig(cfg); err != nil { - return fmt.Errorf("writing new limits to repo config: %w", err) - } - - return nil -} - -// NetResetLimit resets ResourceManager limits to defaults. The limits take effect immediately, and are also persisted to the repo config. -func NetResetLimit(mgr network.ResourceManager, repo repo.Repo, scope string) (rcmgr.BaseLimit, error) { - var result rcmgr.BaseLimit - - setLimit := func(s network.ResourceScope, l rcmgr.Limit) error { - limiter, ok := s.(rcmgr.ResourceScopeLimiter) - if !ok { - return ErrNoResourceMgr - } - - limiter.SetLimit(l) - return nil - } - - cfg, err := repo.Config() - if err != nil { - return rcmgr.BaseLimit{}, fmt.Errorf("reading config to reset limit: %w", err) - } - - defaultsOrig, err := createDefaultLimitConfig(cfg.Swarm) - if err != nil { - return rcmgr.BaseLimit{}, fmt.Errorf("creating default limit config: %w", err) - } - defaults := defaultsOrig.ToPartialLimitConfig() - - // INVESTIGATE(@Jorropo): Why do we save scaled configs in the repo ? - - if cfg.Swarm.ResourceMgr.Limits == nil { - cfg.Swarm.ResourceMgr.Limits = &rcmgr.PartialLimitConfig{} - } - configLimits := cfg.Swarm.ResourceMgr.Limits - - var setConfigFunc func() rcmgr.BaseLimit - switch { - case scope == config.ResourceMgrSystemScope: - err = mgr.ViewSystem(func(s network.ResourceScope) error { return setLimit(s, defaults.System.Build(rcmgr.BaseLimit{})) }) - setConfigFunc = func() rcmgr.BaseLimit { - configLimits.System = defaults.System - return defaults.System.Build(rcmgr.BaseLimit{}) - } - case scope == config.ResourceMgrTransientScope: - err = mgr.ViewTransient(func(s network.ResourceScope) error { return setLimit(s, defaults.Transient.Build(rcmgr.BaseLimit{})) }) - setConfigFunc = func() rcmgr.BaseLimit { - configLimits.Transient = defaults.Transient - return defaults.Transient.Build(rcmgr.BaseLimit{}) - } - case strings.HasPrefix(scope, config.ResourceMgrServiceScopePrefix): - svc := strings.TrimPrefix(scope, config.ResourceMgrServiceScopePrefix) - - err = mgr.ViewService(svc, func(s network.ServiceScope) error { - return setLimit(s, defaults.ServiceDefault.Build(rcmgr.BaseLimit{})) - }) - setConfigFunc = func() rcmgr.BaseLimit { - if configLimits.Service == nil { - configLimits.Service = map[string]rcmgr.ResourceLimits{} - } - configLimits.Service[svc] = defaults.ServiceDefault - return defaults.ServiceDefault.Build(rcmgr.BaseLimit{}) - } - case strings.HasPrefix(scope, config.ResourceMgrProtocolScopePrefix): - proto := strings.TrimPrefix(scope, config.ResourceMgrProtocolScopePrefix) - - err = mgr.ViewProtocol(protocol.ID(proto), func(s network.ProtocolScope) error { - return setLimit(s, defaults.ProtocolDefault.Build(rcmgr.BaseLimit{})) - }) - setConfigFunc = func() rcmgr.BaseLimit { - if configLimits.Protocol == nil { - configLimits.Protocol = map[protocol.ID]rcmgr.ResourceLimits{} - } - configLimits.Protocol[protocol.ID(proto)] = defaults.ProtocolDefault - - return defaults.ProtocolDefault.Build(rcmgr.BaseLimit{}) - } - case strings.HasPrefix(scope, config.ResourceMgrPeerScopePrefix): - p := strings.TrimPrefix(scope, config.ResourceMgrPeerScopePrefix) - - var pid peer.ID - 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 setLimit(s, defaults.PeerDefault.Build(rcmgr.BaseLimit{})) }) - setConfigFunc = func() rcmgr.BaseLimit { - if configLimits.Peer == nil { - configLimits.Peer = map[peer.ID]rcmgr.ResourceLimits{} - } - configLimits.Peer[pid] = defaults.PeerDefault - - return defaults.PeerDefault.Build(rcmgr.BaseLimit{}) - } - default: - return result, fmt.Errorf("invalid scope %q", scope) - } - - if err != nil { - return result, fmt.Errorf("resetting new limits on resource manager: %w", err) - } - - result = setConfigFunc() - - if err := repo.SetConfig(cfg); err != nil { - return result, fmt.Errorf("writing new limits to repo config: %w", err) - } - - return result, nil -} - -func ensureConnMgrMakeSenseVsResourceMgr(orig rcmgr.ConcreteLimitConfig, cmgr config.ConnMgr) error { - if cmgr.Type.WithDefault(config.DefaultConnMgrType) == "none" { - return nil // none connmgr, no checks to do - } - - rcm := orig.ToPartialLimitConfig() - - highWater := cmgr.HighWater.WithDefault(config.DefaultConnMgrHighWater) - if rcm.System.ConnsInbound <= rcm.System.Conns { - if int64(rcm.System.ConnsInbound) <= highWater { - // nolint - return fmt.Errorf(` -Unable to initialize libp2p due to conflicting limit configuration: -ResourceMgr.Limits.System.ConnsInbound (%d) must be bigger than ConnMgr.HighWater (%d) -`, rcm.System.ConnsInbound, highWater) - } - } else if int64(rcm.System.Conns) <= highWater { + highWater := cfg.ConnMgr.HighWater.WithDefault(config.DefaultConnMgrHighWater) + if rcm.System.Conns != rcmgr.Unlimited && int64(rcm.System.Conns) <= highWater { // nolint return fmt.Errorf(` -Unable to initialize libp2p due to conflicting limit configuration: -ResourceMgr.Limits.System.Conns (%d) must be bigger than ConnMgr.HighWater (%d) +Unable to initialize libp2p due to conflicting resource manager limit configuration. +resource manager System.Conns (%d) must be bigger than ConnMgr.HighWater (%d) `, rcm.System.Conns, highWater) } - if rcm.System.StreamsInbound <= rcm.System.Streams { - if int64(rcm.System.StreamsInbound) <= highWater { - // nolint - return fmt.Errorf(` -Unable to initialize libp2p due to conflicting limit configuration: -ResourceMgr.Limits.System.StreamsInbound (%d) must be bigger than ConnMgr.HighWater (%d) -`, rcm.System.StreamsInbound, highWater) - } - } else if int64(rcm.System.Streams) <= highWater { + if rcm.System.ConnsInbound != rcmgr.Unlimited && int64(rcm.System.ConnsInbound) <= highWater { // nolint return fmt.Errorf(` -Unable to initialize libp2p due to conflicting limit configuration: -ResourceMgr.Limits.System.Streams (%d) must be bigger than ConnMgr.HighWater (%d) +Unable to initialize libp2p due to conflicting resource manager limit configuration. +resource manager System.ConnsInbound (%d) must be bigger than ConnMgr.HighWater (%d) +`, rcm.System.ConnsInbound, highWater) + } + if rcm.System.Streams != rcmgr.Unlimited && int64(rcm.System.Streams) <= highWater { + // nolint + return fmt.Errorf(` +Unable to initialize libp2p due to conflicting resource manager limit configuration. +resource manager System.Streams (%d) must be bigger than ConnMgr.HighWater (%d) `, rcm.System.Streams, highWater) + } + if rcm.System.StreamsInbound != rcmgr.Unlimited && int64(rcm.System.StreamsInbound) <= highWater { + // nolint + return fmt.Errorf(` +Unable to initialize libp2p due to conflicting resource manager limit configuration. +resource manager System.StreamsInbound (%d) must be bigger than ConnMgr.HighWater (%d) +`, rcm.System.StreamsInbound, highWater) } return nil } diff --git a/core/node/libp2p/rcmgr_defaults.go b/core/node/libp2p/rcmgr_defaults.go index 05dda7745..5faaf7979 100644 --- a/core/node/libp2p/rcmgr_defaults.go +++ b/core/node/libp2p/rcmgr_defaults.go @@ -4,70 +4,31 @@ import ( "fmt" "github.com/dustin/go-humanize" + "github.com/ipfs/kubo/config" + "github.com/ipfs/kubo/core/node/libp2p/fd" "github.com/libp2p/go-libp2p" rcmgr "github.com/libp2p/go-libp2p/p2p/host/resource-manager" "github.com/pbnjay/memory" - - "github.com/ipfs/kubo/config" - "github.com/ipfs/kubo/core/node/libp2p/fd" ) -// We are doing some magic when parsing config files (we are using a map[string]interface{} to compare config files). -// When you don't have a type the JSON Parse function cast numbers to float64 by default, -// losing precision when writing the final number. So if we use math.MaxInt as our infinite number, -// after writing the config file we will have 9223372036854776000 instead of 9223372036854775807, -// making the parsing process fail. Setting 1e9 (1000000000) as "no limit" value. It also avoids to overflow on 32 bit architectures. -const bigEnough = 1e9 - -var infiniteBaseLimit = rcmgr.BaseLimit{ - Streams: bigEnough, - StreamsInbound: bigEnough, - StreamsOutbound: bigEnough, - Conns: bigEnough, - ConnsInbound: bigEnough, - ConnsOutbound: bigEnough, - FD: bigEnough, - Memory: bigEnough, -} - -var noLimitIncrease = rcmgr.BaseLimitIncrease{ - ConnsInbound: 0, - ConnsOutbound: 0, - Conns: 0, - StreamsInbound: 0, - StreamsOutbound: 0, - Streams: 0, - Memory: 0, - FDFraction: 0, -} +var infiniteResourceLimits = rcmgr.InfiniteLimits.ToPartialLimitConfig().System // This file defines implicit limit defaults used when Swarm.ResourceMgr.Enabled // createDefaultLimitConfig creates LimitConfig to pass to libp2p's resource manager. // The defaults follow the documentation in docs/libp2p-resource-management.md. // Any changes in the logic here should be reflected there. -func createDefaultLimitConfig(cfg config.SwarmConfig) (rcmgr.ConcreteLimitConfig, error) { +func createDefaultLimitConfig(cfg config.SwarmConfig) (limitConfig rcmgr.ConcreteLimitConfig, logMessageForStartup string, err error) { maxMemoryDefaultString := humanize.Bytes(uint64(memory.TotalMemory()) / 2) maxMemoryString := cfg.ResourceMgr.MaxMemory.WithDefault(maxMemoryDefaultString) maxMemory, err := humanize.ParseBytes(maxMemoryString) if err != nil { - return rcmgr.ConcreteLimitConfig{}, err + return rcmgr.ConcreteLimitConfig{}, "", err } maxMemoryMB := maxMemory / (1024 * 1024) maxFD := int(cfg.ResourceMgr.MaxFileDescriptors.WithDefault(int64(fd.GetNumFDs()) / 2)) - // We want to see this message on startup, that's why we are using fmt instead of log. - fmt.Printf(` -Computing default go-libp2p Resource Manager limits based on: - - 'Swarm.ResourceMgr.MaxMemory': %q - - 'Swarm.ResourceMgr.MaxFileDescriptors': %d - -Applying any user-supplied overrides on top. -Run 'ipfs swarm limit all' to see the resulting limits. - -`, maxMemoryString, maxFD) - // At least as of 2023-01-25, it's possible to open a connection that // doesn't ask for any memory usage with the libp2p Resource Manager/Accountant // (see https://github.com/libp2p/go-libp2p/issues/2010#issuecomment-1404280736). @@ -79,109 +40,86 @@ Run 'ipfs swarm limit all' to see the resulting limits. // (see https://github.com/libp2p/go-libp2p/blob/master/p2p/host/resource-manager/limit_defaults.go#L357 ). systemConnsInbound := int(1 * maxMemoryMB) - scalingLimitConfig := rcmgr.ScalingLimitConfig{ - SystemBaseLimit: rcmgr.BaseLimit{ - Memory: int64(maxMemory), - FD: maxFD, + partialLimits := rcmgr.PartialLimitConfig{ + System: rcmgr.ResourceLimits{ + Memory: rcmgr.LimitVal64(maxMemory), + FD: rcmgr.LimitVal(maxFD), - // By default, we just limit connections on the inbound side. - Conns: bigEnough, - ConnsInbound: systemConnsInbound, - ConnsOutbound: bigEnough, + Conns: rcmgr.Unlimited, + ConnsInbound: rcmgr.LimitVal(systemConnsInbound), + ConnsOutbound: rcmgr.Unlimited, - Streams: bigEnough, - StreamsInbound: bigEnough, - StreamsOutbound: bigEnough, + Streams: rcmgr.Unlimited, + StreamsOutbound: rcmgr.Unlimited, + StreamsInbound: rcmgr.Unlimited, }, - SystemLimitIncrease: noLimitIncrease, - // Transient connections won't cause any memory to accounted for by the resource manager. + // Transient connections won't cause any memory to be accounted for by the resource manager/accountant. // Only established connections do. // As a result, we can't rely on System.Memory to protect us from a bunch of transient connection being opened. // We limit the same values as the System scope, but only allow the Transient scope to take 25% of what is allowed for the System scope. - TransientBaseLimit: rcmgr.BaseLimit{ - Memory: int64(maxMemory / 4), - FD: maxFD / 4, + Transient: rcmgr.ResourceLimits{ + Memory: rcmgr.LimitVal64(maxMemory / 4), + FD: rcmgr.LimitVal(maxFD / 4), - Conns: bigEnough, - ConnsInbound: systemConnsInbound / 4, - ConnsOutbound: bigEnough, + Conns: rcmgr.Unlimited, + ConnsInbound: rcmgr.LimitVal(systemConnsInbound / 4), + ConnsOutbound: rcmgr.Unlimited, - Streams: bigEnough, - StreamsInbound: bigEnough, - StreamsOutbound: bigEnough, + Streams: rcmgr.Unlimited, + StreamsInbound: rcmgr.Unlimited, + StreamsOutbound: rcmgr.Unlimited, }, - TransientLimitIncrease: noLimitIncrease, - // Lets get out of the way of the allow list functionality. // If someone specified "Swarm.ResourceMgr.Allowlist" we should let it go through. - AllowlistedSystemBaseLimit: infiniteBaseLimit, - AllowlistedSystemLimitIncrease: noLimitIncrease, + AllowlistedSystem: infiniteResourceLimits, - AllowlistedTransientBaseLimit: infiniteBaseLimit, - AllowlistedTransientLimitIncrease: noLimitIncrease, + AllowlistedTransient: infiniteResourceLimits, // Keep it simple by not having Service, ServicePeer, Protocol, ProtocolPeer, Conn, or Stream limits. - ServiceBaseLimit: infiniteBaseLimit, - ServiceLimitIncrease: noLimitIncrease, + ServiceDefault: infiniteResourceLimits, - ServicePeerBaseLimit: infiniteBaseLimit, - ServicePeerLimitIncrease: noLimitIncrease, + ServicePeerDefault: infiniteResourceLimits, - ProtocolBaseLimit: infiniteBaseLimit, - ProtocolLimitIncrease: noLimitIncrease, + ProtocolDefault: infiniteResourceLimits, - ProtocolPeerBaseLimit: infiniteBaseLimit, - ProtocolPeerLimitIncrease: noLimitIncrease, + ProtocolPeerDefault: infiniteResourceLimits, - ConnBaseLimit: infiniteBaseLimit, - ConnLimitIncrease: noLimitIncrease, + Conn: infiniteResourceLimits, - StreamBaseLimit: infiniteBaseLimit, - StreamLimitIncrease: noLimitIncrease, + Stream: infiniteResourceLimits, // Limit the resources consumed by a peer. // This doesn't protect us against intentional DoS attacks since an attacker can easily spin up multiple peers. // We specify this limit against unintentional DoS attacks (e.g., a peer has a bug and is sending too much traffic intentionally). // In that case we want to keep that peer's resource consumption contained. // To keep this simple, we only constrain inbound connections and streams. - PeerBaseLimit: rcmgr.BaseLimit{ - Memory: bigEnough, - FD: bigEnough, - Conns: bigEnough, - ConnsInbound: rcmgr.DefaultLimits.PeerBaseLimit.ConnsInbound, - ConnsOutbound: bigEnough, - Streams: bigEnough, - StreamsInbound: rcmgr.DefaultLimits.PeerBaseLimit.StreamsInbound, - StreamsOutbound: bigEnough, - }, - // Most limits don't see an increase because they're already infinite/bigEnough. - // The values that should scale based on the amount of memory allocated to libp2p need to increase accordingly. - PeerLimitIncrease: rcmgr.BaseLimitIncrease{ - Memory: 0, - FDFraction: 0, - Conns: 0, - ConnsInbound: rcmgr.DefaultLimits.PeerLimitIncrease.ConnsInbound, - ConnsOutbound: 0, - Streams: 0, - StreamsInbound: rcmgr.DefaultLimits.PeerLimitIncrease.StreamsInbound, - StreamsOutbound: 0, + PeerDefault: rcmgr.ResourceLimits{ + Memory: rcmgr.Unlimited64, + FD: rcmgr.Unlimited, + Conns: rcmgr.Unlimited, + ConnsInbound: rcmgr.DefaultLimit, + ConnsOutbound: rcmgr.Unlimited, + Streams: rcmgr.Unlimited, + StreamsInbound: rcmgr.DefaultLimit, + StreamsOutbound: rcmgr.Unlimited, }, } - // Whatever limits libp2p has specifically tuned for its protocols/services we'll apply. + scalingLimitConfig := rcmgr.DefaultLimits libp2p.SetDefaultServiceLimits(&scalingLimitConfig) - orig := scalingLimitConfig.Scale(int64(maxMemory), maxFD) - defaultLimitConfig := orig.ToPartialLimitConfig() + // Anything set above in partialLimits that had a value of rcmgr.DefaultLimit will be overridden. + // Anything in scalingLimitConfig that wasn't defined in partialLimits above will be added (e.g., libp2p's default service limits). + partialLimits = partialLimits.Build(scalingLimitConfig.Scale(int64(maxMemory), maxFD)).ToPartialLimitConfig() // Simple checks to overide autoscaling ensuring limits make sense versus the connmgr values. // There are ways to break this, but this should catch most problems already. // We might improve this in the future. // See: https://github.com/ipfs/kubo/issues/9545 - if cfg.ConnMgr.Type.WithDefault(config.DefaultConnMgrType) != "none" { - maxInboundConns := int64(defaultLimitConfig.System.ConnsInbound) + if partialLimits.System.ConnsInbound != rcmgr.Unlimited && cfg.ConnMgr.Type.WithDefault(config.DefaultConnMgrType) != "none" { + maxInboundConns := int64(partialLimits.System.ConnsInbound) if connmgrHighWaterTimesTwo := cfg.ConnMgr.HighWater.WithDefault(config.DefaultConnMgrHighWater) * 2; maxInboundConns < connmgrHighWaterTimesTwo { maxInboundConns = connmgrHighWaterTimesTwo } @@ -191,9 +129,19 @@ Run 'ipfs swarm limit all' to see the resulting limits. } // Scale System.StreamsInbound as well, but use the existing ratio of StreamsInbound to ConnsInbound - defaultLimitConfig.System.StreamsInbound = rcmgr.LimitVal(maxInboundConns * int64(defaultLimitConfig.System.StreamsInbound) / int64(defaultLimitConfig.System.ConnsInbound)) - defaultLimitConfig.System.ConnsInbound = rcmgr.LimitVal(maxInboundConns) + partialLimits.System.StreamsInbound = rcmgr.LimitVal(maxInboundConns * int64(partialLimits.System.StreamsInbound) / int64(partialLimits.System.ConnsInbound)) + partialLimits.System.ConnsInbound = rcmgr.LimitVal(maxInboundConns) } - return defaultLimitConfig.Build(orig), nil + msg := fmt.Sprintf(` +Computed default go-libp2p Resource Manager limits based on: + - 'Swarm.ResourceMgr.MaxMemory': %q + - 'Swarm.ResourceMgr.MaxFileDescriptors': %d + +Theses can be inspected with 'ipfs swarm resources'. + +`, maxMemoryString, maxFD) + + // We already have a complete value thus pass in an empty ConcreteLimitConfig. + return partialLimits.Build(rcmgr.ConcreteLimitConfig{}), msg, nil } diff --git a/core/node/libp2p/rcmgr_test.go b/core/node/libp2p/rcmgr_test.go deleted file mode 100644 index e273ff756..000000000 --- a/core/node/libp2p/rcmgr_test.go +++ /dev/null @@ -1,12 +0,0 @@ -package libp2p - -import ( - "testing" - - "github.com/stretchr/testify/require" -) - -func TestPercentage(t *testing.T) { - require.True(t, abovePercentage(10, 100, 10)) - require.True(t, abovePercentage(100, 100, 99)) -} diff --git a/core/node/storage.go b/core/node/storage.go index 2e831fae2..d10921058 100644 --- a/core/node/storage.go +++ b/core/node/storage.go @@ -14,7 +14,8 @@ import ( // RepoConfig loads configuration from the repo func RepoConfig(repo repo.Repo) (*config.Config, error) { - return repo.Config() + cfg, err := repo.Config() + return cfg, err } // Datastore provides the datastore diff --git a/go.mod b/go.mod index 2892d3740..34603ebd2 100644 --- a/go.mod +++ b/go.mod @@ -106,7 +106,6 @@ require ( go.uber.org/fx v1.18.2 go.uber.org/zap v1.24.0 golang.org/x/crypto v0.5.0 - golang.org/x/exp v0.0.0-20230129154200-a960b3787bd2 golang.org/x/mod v0.7.0 golang.org/x/sync v0.1.0 golang.org/x/sys v0.5.0 @@ -228,6 +227,7 @@ require ( go.uber.org/atomic v1.10.0 // indirect go.uber.org/multierr v1.9.0 // indirect go4.org v0.0.0-20200411211856-f5505b9728dd // indirect + golang.org/x/exp v0.0.0-20230129154200-a960b3787bd2 // indirect golang.org/x/net v0.7.0 // indirect golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b // indirect golang.org/x/term v0.5.0 // indirect diff --git a/repo/fsrepo/fsrepo.go b/repo/fsrepo/fsrepo.go index 99104b083..6a7da9a06 100644 --- a/repo/fsrepo/fsrepo.go +++ b/repo/fsrepo/fsrepo.go @@ -16,6 +16,7 @@ import ( repo "github.com/ipfs/kubo/repo" "github.com/ipfs/kubo/repo/common" dir "github.com/ipfs/kubo/thirdparty/dir" + rcmgr "github.com/libp2p/go-libp2p/p2p/host/resource-manager" ds "github.com/ipfs/go-datastore" measure "github.com/ipfs/go-ds-measure" @@ -102,11 +103,12 @@ type FSRepo struct { configFilePath string // lockfile is the file system lock to prevent others from opening // the same fsrepo path concurrently - lockfile io.Closer - config *config.Config - ds repo.Datastore - keystore keystore.Keystore - filemgr *filestore.FileManager + lockfile io.Closer + config *config.Config + userResourceOverrides rcmgr.PartialLimitConfig + ds repo.Datastore + keystore keystore.Keystore + filemgr *filestore.FileManager } var _ repo.Repo = (*FSRepo)(nil) @@ -180,6 +182,10 @@ func open(repoPath string, userConfigFilePath string) (repo.Repo, error) { return nil, err } + if err := r.openUserResourceOverrides(); err != nil { + return nil, err + } + if err := r.openDatastore(); err != nil { return nil, err } @@ -437,6 +443,17 @@ func (r *FSRepo) openConfig() error { return nil } +// openUserResourceOverrides will remove all overrides if the file is not present. +// It will error if the decoding fails. +func (r *FSRepo) openUserResourceOverrides() error { + // This filepath is documented in docs/libp2p-resource-management.md and be kept in sync. + err := serialize.ReadConfigFile(filepath.Join(r.path, "libp2p-resource-limit-overrides.json"), &r.userResourceOverrides) + if err == serialize.ErrNotInitialized { + err = nil + } + return err +} + func (r *FSRepo) openKeystore() error { ksp := filepath.Join(r.path, "keystore") ks, err := keystore.NewFSKeystore(ksp) @@ -554,6 +571,21 @@ func (r *FSRepo) Config() (*config.Config, error) { return r.config, nil } +func (r *FSRepo) UserResourceOverrides() (rcmgr.PartialLimitConfig, error) { + // It is not necessary to hold the package lock since the repo is in an + // opened state. The package lock is _not_ meant to ensure that the repo is + // thread-safe. The package lock is only meant to guard against removal and + // coordinate the lockfile. However, we provide thread-safety to keep + // things simple. + packageLock.Lock() + defer packageLock.Unlock() + + if r.closed { + return rcmgr.PartialLimitConfig{}, errors.New("cannot access config, repo not open") + } + return r.userResourceOverrides, nil +} + func (r *FSRepo) FileManager() *filestore.FileManager { return r.filemgr } diff --git a/repo/mock.go b/repo/mock.go index a50d448ed..6f128d263 100644 --- a/repo/mock.go +++ b/repo/mock.go @@ -7,6 +7,7 @@ import ( filestore "github.com/ipfs/go-filestore" keystore "github.com/ipfs/go-ipfs-keystore" + rcmgr "github.com/libp2p/go-libp2p/p2p/host/resource-manager" config "github.com/ipfs/kubo/config" ma "github.com/multiformats/go-multiaddr" @@ -26,6 +27,10 @@ func (m *Mock) Config() (*config.Config, error) { return &m.C, nil // FIXME threadsafety } +func (m *Mock) UserResourceOverrides() (rcmgr.PartialLimitConfig, error) { + return rcmgr.PartialLimitConfig{}, nil +} + func (m *Mock) SetConfig(updated *config.Config) error { m.C = *updated // FIXME threadsafety return nil diff --git a/repo/repo.go b/repo/repo.go index bec02049d..6767dda72 100644 --- a/repo/repo.go +++ b/repo/repo.go @@ -8,6 +8,7 @@ import ( filestore "github.com/ipfs/go-filestore" keystore "github.com/ipfs/go-ipfs-keystore" + rcmgr "github.com/libp2p/go-libp2p/p2p/host/resource-manager" ds "github.com/ipfs/go-datastore" config "github.com/ipfs/kubo/config" @@ -24,6 +25,10 @@ type Repo interface { // to the returned config are not automatically persisted. Config() (*config.Config, error) + // UserResourceOverrides returns optional user resource overrides for the + // libp2p resource manager. + UserResourceOverrides() (rcmgr.PartialLimitConfig, error) + // BackupConfig creates a backup of the current configuration file using // the given prefix for naming. BackupConfig(prefix string) (string, error) diff --git a/test/cli/basic_commands_test.go b/test/cli/basic_commands_test.go index 30c1f1f9a..220ef2854 100644 --- a/test/cli/basic_commands_test.go +++ b/test/cli/basic_commands_test.go @@ -88,6 +88,7 @@ func TestAllSubcommandsAcceptHelp(t *testing.T) { t.Parallel() node := harness.NewT(t).NewNode() for _, cmd := range node.IPFSCommands() { + cmd := cmd t.Run(fmt.Sprintf("command %q accepts help", cmd), func(t *testing.T) { t.Parallel() splitCmd := strings.Split(cmd, " ")[1:] diff --git a/test/cli/harness/node.go b/test/cli/harness/node.go index e486771ca..0d0295307 100644 --- a/test/cli/harness/node.go +++ b/test/cli/harness/node.go @@ -20,6 +20,7 @@ import ( "github.com/ipfs/kubo/config" serial "github.com/ipfs/kubo/config/serialize" "github.com/libp2p/go-libp2p/core/peer" + rcmgr "github.com/libp2p/go-libp2p/p2p/host/resource-manager" "github.com/multiformats/go-multiaddr" manet "github.com/multiformats/go-multiaddr/net" ) @@ -96,6 +97,38 @@ func (n *Node) UpdateConfig(f func(cfg *config.Config)) { n.WriteConfig(cfg) } +func (n *Node) ReadUserResourceOverrides() *rcmgr.PartialLimitConfig { + var r rcmgr.PartialLimitConfig + err := serial.ReadConfigFile(filepath.Join(n.Dir, "libp2p-resource-limit-overrides.json"), &r) + switch err { + case nil, serial.ErrNotInitialized: + return &r + default: + panic(err) + } +} + +func (n *Node) WriteUserSuppliedResourceOverrides(c *rcmgr.PartialLimitConfig) { + err := serial.WriteConfigFile(filepath.Join(n.Dir, "libp2p-resource-limit-overrides.json"), c) + if err != nil { + panic(err) + } +} + +func (n *Node) UpdateUserSuppliedResourceManagerOverrides(f func(overrides *rcmgr.PartialLimitConfig)) { + overrides := n.ReadUserResourceOverrides() + f(overrides) + n.WriteUserSuppliedResourceOverrides(overrides) +} + +func (n *Node) UpdateConfigAndUserSuppliedResourceManagerOverrides(f func(cfg *config.Config, overrides *rcmgr.PartialLimitConfig)) { + overrides := n.ReadUserResourceOverrides() + cfg := n.ReadConfig() + f(cfg, overrides) + n.WriteConfig(cfg) + n.WriteUserSuppliedResourceOverrides(overrides) +} + func (n *Node) IPFS(args ...string) RunResult { res := n.RunIPFS(args...) n.Runner.AssertNoError(res) diff --git a/test/cli/rcmgr_test.go b/test/cli/rcmgr_test.go index 23e123655..fb644e1a7 100644 --- a/test/cli/rcmgr_test.go +++ b/test/cli/rcmgr_test.go @@ -7,6 +7,8 @@ import ( "github.com/ipfs/kubo/config" "github.com/ipfs/kubo/core/node/libp2p" "github.com/ipfs/kubo/test/cli/harness" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/protocol" rcmgr "github.com/libp2p/go-libp2p/p2p/host/resource-manager" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -24,19 +26,14 @@ func TestRcmgr(t *testing.T) { node.StartDaemon() - t.Run("swarm limit should fail", func(t *testing.T) { - res := node.RunIPFS("swarm", "limit", "system") + t.Run("swarm resources should fail", func(t *testing.T) { + res := node.RunIPFS("swarm", "resources") assert.Equal(t, 1, res.ExitCode()) - assert.Contains(t, res.Stderr.Lines()[0], "missing ResourceMgr") - }) - t.Run("swarm stats should fail", func(t *testing.T) { - res := node.RunIPFS("swarm", "stats", "all") - assert.Equal(t, 1, res.ExitCode()) - assert.Contains(t, res.Stderr.Lines()[0], "missing ResourceMgr") + assert.Contains(t, res.Stderr.String(), "missing ResourceMgr") }) }) - t.Run("Node in offline mode", func(t *testing.T) { + t.Run("Node with resource manager disabled", func(t *testing.T) { t.Parallel() node := harness.NewT(t).NewNode().Init() node.UpdateConfig(func(cfg *config.Config) { @@ -44,15 +41,10 @@ func TestRcmgr(t *testing.T) { }) node.StartDaemon() - t.Run("swarm limit should fail", func(t *testing.T) { - res := node.RunIPFS("swarm", "limit", "system") + t.Run("swarm resources should fail", func(t *testing.T) { + res := node.RunIPFS("swarm", "resources") assert.Equal(t, 1, res.ExitCode()) - assert.Contains(t, res.Stderr.Lines()[0], "missing ResourceMgr") - }) - t.Run("swarm stats should fail", func(t *testing.T) { - res := node.RunIPFS("swarm", "stats", "all") - assert.Equal(t, 1, res.ExitCode()) - assert.Contains(t, res.Stderr.Lines()[0], "missing ResourceMgr") + assert.Contains(t, res.Stderr.String(), "missing ResourceMgr") }) }) @@ -63,12 +55,14 @@ func TestRcmgr(t *testing.T) { }) node.StartDaemon() - res := node.RunIPFS("swarm", "limit", "system", "--enc=json") + res := node.RunIPFS("swarm", "resources", "--enc=json") require.Equal(t, 0, res.ExitCode()) limits := unmarshalLimits(t, res.Stdout.Bytes()) - assert.GreaterOrEqual(t, limits.ConnsInbound, 2000) - assert.GreaterOrEqual(t, limits.StreamsInbound, 2000) + rl := limits.System.ToResourceLimits() + s := rl.Build(rcmgr.BaseLimit{}) + assert.GreaterOrEqual(t, s.ConnsInbound, 2000) + assert.GreaterOrEqual(t, s.StreamsInbound, 2000) }) t.Run("default configuration", func(t *testing.T) { @@ -80,176 +74,102 @@ func TestRcmgr(t *testing.T) { node.StartDaemon() t.Run("conns and streams are above 800 for default connmgr settings", func(t *testing.T) { - res := node.RunIPFS("swarm", "limit", "system", "--enc=json") + res := node.RunIPFS("swarm", "resources", "--enc=json") require.Equal(t, 0, res.ExitCode()) limits := unmarshalLimits(t, res.Stdout.Bytes()) - assert.GreaterOrEqual(t, limits.ConnsInbound, 800) - assert.GreaterOrEqual(t, limits.StreamsInbound, 800) + if limits.System.ConnsInbound != rcmgr.Unlimited { + assert.GreaterOrEqual(t, limits.System.ConnsInbound, 800) + } + if limits.System.StreamsInbound != rcmgr.Unlimited { + assert.GreaterOrEqual(t, limits.System.StreamsInbound, 800) + } }) - t.Run("limits|stats should succeed", func(t *testing.T) { - res := node.RunIPFS("swarm", "limit", "all") + t.Run("limits should succeed", func(t *testing.T) { + res := node.RunIPFS("swarm", "resources", "--enc=json") assert.Equal(t, 0, res.ExitCode()) - limits := map[string]rcmgr.ResourceLimits{} + limits := rcmgr.PartialLimitConfig{} err := json.Unmarshal(res.Stdout.Bytes(), &limits) require.NoError(t, err) - assert.Greater(t, limits["System"].Memory, int64(0)) - assert.Greater(t, limits["System"].FD, 0) - assert.Greater(t, limits["System"].Conns, 0) - assert.Greater(t, limits["System"].ConnsInbound, 0) - assert.Greater(t, limits["System"].ConnsOutbound, 0) - assert.Greater(t, limits["System"].Streams, 0) - assert.Greater(t, limits["System"].StreamsInbound, 0) - assert.Greater(t, limits["System"].StreamsOutbound, 0) - assert.Greater(t, limits["Transient"].Memory, int64(0)) - }) - - t.Run("resetting limits should produce the same default limits", func(t *testing.T) { - resetRes := node.RunIPFS("swarm", "limit", "system", "--reset", "--enc=json") - require.Equal(t, 0, resetRes.ExitCode()) - limitRes := node.RunIPFS("swarm", "limit", "system", "--enc=json") - require.Equal(t, 0, limitRes.ExitCode()) - - assert.Equal(t, resetRes.Stdout.Bytes(), limitRes.Stdout.Bytes()) - }) - - t.Run("swarm stats system with filter should fail", func(t *testing.T) { - res := node.RunIPFS("swarm", "stats", "system", "--min-used-limit-perc=99") - assert.Equal(t, 1, res.ExitCode()) - assert.Contains(t, res.Stderr.Lines()[0], `Error: "min-used-limit-perc" can only be used when scope is "all"`) - }) - - t.Run("swarm limit reset on map values should work", func(t *testing.T) { - resetRes := node.RunIPFS("swarm", "limit", "peer:12D3KooWL7i1T9VSPeF8AgQApbyM51GNKZsYPvNvL347aMDmvNzG", "--reset", "--enc=json") - require.Equal(t, 0, resetRes.ExitCode()) - limitRes := node.RunIPFS("swarm", "limit", "peer:12D3KooWL7i1T9VSPeF8AgQApbyM51GNKZsYPvNvL347aMDmvNzG", "--enc=json") - require.Equal(t, 0, limitRes.ExitCode()) - - assert.Equal(t, resetRes.Stdout.Bytes(), limitRes.Stdout.Bytes()) - }) - - t.Run("scope is required using reset flags", func(t *testing.T) { - res := node.RunIPFS("swarm", "limit", "--reset") - assert.Equal(t, 1, res.ExitCode()) - assert.Contains(t, res.Stderr.Lines()[0], `Error: argument "scope" is required`) + assert.NotEqual(t, limits.Transient.Memory, rcmgr.BlockAllLimit64) + assert.NotEqual(t, limits.System.Memory, rcmgr.BlockAllLimit64) + assert.NotEqual(t, limits.System.FD, rcmgr.BlockAllLimit) + assert.NotEqual(t, limits.System.Conns, rcmgr.BlockAllLimit) + assert.NotEqual(t, limits.System.ConnsInbound, rcmgr.BlockAllLimit) + assert.NotEqual(t, limits.System.ConnsOutbound, rcmgr.BlockAllLimit) + assert.NotEqual(t, limits.System.Streams, rcmgr.BlockAllLimit) + assert.NotEqual(t, limits.System.StreamsInbound, rcmgr.BlockAllLimit) + assert.NotEqual(t, limits.System.StreamsOutbound, rcmgr.BlockAllLimit) }) t.Run("swarm stats works", func(t *testing.T) { - res := node.RunIPFS("swarm", "stats", "all", "--enc=json") + res := node.RunIPFS("swarm", "resources", "--enc=json") require.Equal(t, 0, res.ExitCode()) - stats := libp2p.NetStatOut{} - err := json.Unmarshal(res.Stdout.Bytes(), &stats) - require.NoError(t, err) + limits := unmarshalLimits(t, res.Stdout.Bytes()) // every scope has the same fields, so we only inspect system - assert.Equal(t, rcmgr.LimitVal64(0), stats.System.Memory) - assert.Equal(t, rcmgr.LimitVal(0), stats.System.FD) - assert.Equal(t, rcmgr.LimitVal(0), stats.System.Conns) - assert.Equal(t, rcmgr.LimitVal(0), stats.System.ConnsInbound) - assert.Equal(t, rcmgr.LimitVal(0), stats.System.ConnsOutbound) - assert.Equal(t, rcmgr.LimitVal(0), stats.System.Streams) - assert.Equal(t, rcmgr.LimitVal(0), stats.System.StreamsInbound) - assert.Equal(t, rcmgr.LimitVal(0), stats.System.StreamsOutbound) - assert.Equal(t, rcmgr.LimitVal64(0), stats.Transient.Memory) + assert.Zero(t, limits.System.MemoryUsage) + assert.Zero(t, limits.System.FDUsage) + assert.Zero(t, limits.System.ConnsInboundUsage) + assert.Zero(t, limits.System.ConnsOutboundUsage) + assert.Zero(t, limits.System.StreamsInboundUsage) + assert.Zero(t, limits.System.StreamsOutboundUsage) + assert.Zero(t, limits.Transient.MemoryUsage) }) }) - t.Run("set system conns limit while daemon is not running", func(t *testing.T) { - node := harness.NewT(t).NewNode().Init() - res := node.RunIPFS("config", "--json", "Swarm.ResourceMgr.Limits.System.Conns", "99999") - require.Equal(t, 0, res.ExitCode()) - - t.Run("set an invalid limit which should result in a failure", func(t *testing.T) { - res := node.RunIPFS("config", "--json", "Swarm.ResourceMgr.Limits.System.Conns", "asdf") - assert.Equal(t, 1, res.ExitCode()) - assert.Contains(t, res.Stderr.String(), "failed to unmarshal") - }) - - node.StartDaemon() - - t.Run("new system conns limit is applied", func(t *testing.T) { - res := node.RunIPFS("swarm", "limit", "system", "--enc=json") - limits := unmarshalLimits(t, res.Stdout.Bytes()) - assert.Equal(t, limits.Conns, rcmgr.LimitVal(99999)) - }) - }) - - t.Run("set the system memory limit while the daemon is running", func(t *testing.T) { - node := harness.NewT(t).NewNode().Init().StartDaemon() - updateLimitsWithFile(t, node, "system", func(limits *rcmgr.ResourceLimits) { - limits.Memory = 99998 - }) - - assert.Equal(t, rcmgr.LimitVal64(99998), node.ReadConfig().Swarm.ResourceMgr.Limits.System.Memory) - - res := node.RunIPFS("swarm", "limit", "system", "--enc=json") - limits := unmarshalLimits(t, res.Stdout.Bytes()) - assert.Equal(t, rcmgr.LimitVal64(99998), limits.Memory) - }) - t.Run("smoke test transient scope", func(t *testing.T) { - node := harness.NewT(t).NewNode().Init().StartDaemon() - updateLimitsWithFile(t, node, "transient", func(limits *rcmgr.ResourceLimits) { - limits.Memory = 88888 + node := harness.NewT(t).NewNode().Init() + node.UpdateUserSuppliedResourceManagerOverrides(func(overrides *rcmgr.PartialLimitConfig) { + overrides.Transient.Memory = 88888 }) + node.StartDaemon() - res := node.RunIPFS("swarm", "limit", "transient", "--enc=json") + res := node.RunIPFS("swarm", "resources", "--enc=json") limits := unmarshalLimits(t, res.Stdout.Bytes()) - assert.Equal(t, rcmgr.LimitVal64(88888), limits.Memory) + assert.Equal(t, rcmgr.LimitVal64(88888), limits.Transient.Memory) }) t.Run("smoke test service scope", func(t *testing.T) { - node := harness.NewT(t).NewNode().Init().StartDaemon() - updateLimitsWithFile(t, node, "svc:foo", func(limits *rcmgr.ResourceLimits) { - limits.Memory = 77777 + node := harness.NewT(t).NewNode().Init() + node.UpdateUserSuppliedResourceManagerOverrides(func(overrides *rcmgr.PartialLimitConfig) { + overrides.Service = map[string]rcmgr.ResourceLimits{"foo": {Memory: 77777}} }) + node.StartDaemon() - res := node.RunIPFS("swarm", "limit", "svc:foo", "--enc=json") + res := node.RunIPFS("swarm", "resources", "--enc=json") limits := unmarshalLimits(t, res.Stdout.Bytes()) - assert.Equal(t, rcmgr.LimitVal64(77777), limits.Memory) + assert.Equal(t, rcmgr.LimitVal64(77777), limits.Services["foo"].Memory) }) t.Run("smoke test protocol scope", func(t *testing.T) { - node := harness.NewT(t).NewNode().Init().StartDaemon() - updateLimitsWithFile(t, node, "proto:foo", func(limits *rcmgr.ResourceLimits) { - limits.Memory = 66666 + node := harness.NewT(t).NewNode().Init() + node.UpdateUserSuppliedResourceManagerOverrides(func(overrides *rcmgr.PartialLimitConfig) { + overrides.Protocol = map[protocol.ID]rcmgr.ResourceLimits{"foo": {Memory: 66666}} }) + node.StartDaemon() - res := node.RunIPFS("swarm", "limit", "proto:foo", "--enc=json") + res := node.RunIPFS("swarm", "resources", "--enc=json") limits := unmarshalLimits(t, res.Stdout.Bytes()) - assert.Equal(t, rcmgr.LimitVal64(66666), limits.Memory) + assert.Equal(t, rcmgr.LimitVal64(66666), limits.Protocols["foo"].Memory) }) t.Run("smoke test peer scope", func(t *testing.T) { - validPeerID := "QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN" - node := harness.NewT(t).NewNode().Init().StartDaemon() - updateLimitsWithFile(t, node, "peer:"+validPeerID, func(limits *rcmgr.ResourceLimits) { - limits.Memory = 66666 + validPeerID, err := peer.Decode("QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN") + assert.NoError(t, err) + node := harness.NewT(t).NewNode().Init() + node.UpdateUserSuppliedResourceManagerOverrides(func(overrides *rcmgr.PartialLimitConfig) { + overrides.Peer = map[peer.ID]rcmgr.ResourceLimits{validPeerID: {Memory: 55555}} }) + node.StartDaemon() - res := node.RunIPFS("swarm", "limit", "peer:"+validPeerID, "--enc=json") + res := node.RunIPFS("swarm", "resources", "--enc=json") limits := unmarshalLimits(t, res.Stdout.Bytes()) - assert.Equal(t, rcmgr.LimitVal64(66666), limits.Memory) - - t.Parallel() - - t.Run("getting limit for invalid peer ID fails", func(t *testing.T) { - res := node.RunIPFS("swarm", "limit", "peer:foo") - assert.Equal(t, 1, res.ExitCode()) - assert.Contains(t, res.Stderr.String(), "invalid peer ID") - }) - - t.Run("setting limit for invalid peer ID fails", func(t *testing.T) { - filename := "invalid-peer-id.json" - node.WriteBytes(filename, []byte(`{"Memory":"99"}`)) - res := node.RunIPFS("swarm", "limit", "peer:foo", filename) - assert.Equal(t, 1, res.ExitCode()) - assert.Contains(t, res.Stderr.String(), "invalid peer ID") - }) + assert.Equal(t, rcmgr.LimitVal64(55555), limits.Peers[validPeerID].Memory) }) t.Run("", func(t *testing.T) { @@ -258,20 +178,20 @@ func TestRcmgr(t *testing.T) { // peerID0, peerID1, peerID2 := node0.PeerID(), node1.PeerID(), node2.PeerID() peerID1, peerID2 := node1.PeerID().String(), node2.PeerID().String() - node0.UpdateConfig(func(cfg *config.Config) { + node0.UpdateConfigAndUserSuppliedResourceManagerOverrides(func(cfg *config.Config, overrides *rcmgr.PartialLimitConfig) { + *overrides = rcmgr.PartialLimitConfig{ + System: rcmgr.ResourceLimits{ + Conns: rcmgr.BlockAllLimit, + ConnsInbound: rcmgr.BlockAllLimit, + ConnsOutbound: rcmgr.BlockAllLimit, + }, + } cfg.Swarm.ResourceMgr.Enabled = config.True cfg.Swarm.ResourceMgr.Allowlist = []string{"/ip4/0.0.0.0/ipcidr/0/p2p/" + peerID2} }) nodes.StartDaemons() - // change system limits on node 0 - updateLimitsWithFile(t, node0, "system", func(limits *rcmgr.ResourceLimits) { - limits.Conns = rcmgr.BlockAllLimit - limits.ConnsInbound = rcmgr.BlockAllLimit - limits.ConnsOutbound = rcmgr.BlockAllLimit - }) - t.Parallel() t.Run("node 0 should fail to connect to node 1", func(t *testing.T) { res := node0.Runner.Run(harness.RunRequest{ @@ -306,9 +226,10 @@ func TestRcmgr(t *testing.T) { t.Parallel() t.Run("system conns", func(t *testing.T) { node := harness.NewT(t).NewNode().Init() - node.UpdateConfig(func(cfg *config.Config) { - cfg.Swarm.ResourceMgr.Limits = &rcmgr.PartialLimitConfig{} - cfg.Swarm.ResourceMgr.Limits.System.Conns = 128 + node.UpdateConfigAndUserSuppliedResourceManagerOverrides(func(cfg *config.Config, overrides *rcmgr.PartialLimitConfig) { + *overrides = rcmgr.PartialLimitConfig{ + System: rcmgr.ResourceLimits{Conns: 128}, + } cfg.Swarm.ConnMgr.HighWater = config.NewOptionalInteger(128) cfg.Swarm.ConnMgr.LowWater = config.NewOptionalInteger(64) }) @@ -318,9 +239,10 @@ func TestRcmgr(t *testing.T) { }) t.Run("system conns inbound", func(t *testing.T) { node := harness.NewT(t).NewNode().Init() - node.UpdateConfig(func(cfg *config.Config) { - cfg.Swarm.ResourceMgr.Limits = &rcmgr.PartialLimitConfig{} - cfg.Swarm.ResourceMgr.Limits.System.ConnsInbound = 128 + node.UpdateConfigAndUserSuppliedResourceManagerOverrides(func(cfg *config.Config, overrides *rcmgr.PartialLimitConfig) { + *overrides = rcmgr.PartialLimitConfig{ + System: rcmgr.ResourceLimits{ConnsInbound: 128}, + } cfg.Swarm.ConnMgr.HighWater = config.NewOptionalInteger(128) cfg.Swarm.ConnMgr.LowWater = config.NewOptionalInteger(64) }) @@ -330,9 +252,10 @@ func TestRcmgr(t *testing.T) { }) t.Run("system streams", func(t *testing.T) { node := harness.NewT(t).NewNode().Init() - node.UpdateConfig(func(cfg *config.Config) { - cfg.Swarm.ResourceMgr.Limits = &rcmgr.PartialLimitConfig{} - cfg.Swarm.ResourceMgr.Limits.System.Streams = 128 + node.UpdateConfigAndUserSuppliedResourceManagerOverrides(func(cfg *config.Config, overrides *rcmgr.PartialLimitConfig) { + *overrides = rcmgr.PartialLimitConfig{ + System: rcmgr.ResourceLimits{Streams: 128}, + } cfg.Swarm.ConnMgr.HighWater = config.NewOptionalInteger(128) cfg.Swarm.ConnMgr.LowWater = config.NewOptionalInteger(64) }) @@ -342,9 +265,10 @@ func TestRcmgr(t *testing.T) { }) t.Run("system streams inbound", func(t *testing.T) { node := harness.NewT(t).NewNode().Init() - node.UpdateConfig(func(cfg *config.Config) { - cfg.Swarm.ResourceMgr.Limits = &rcmgr.PartialLimitConfig{} - cfg.Swarm.ResourceMgr.Limits.System.StreamsInbound = 128 + node.UpdateConfigAndUserSuppliedResourceManagerOverrides(func(cfg *config.Config, overrides *rcmgr.PartialLimitConfig) { + *overrides = rcmgr.PartialLimitConfig{ + System: rcmgr.ResourceLimits{StreamsInbound: 128}, + } cfg.Swarm.ConnMgr.HighWater = config.NewOptionalInteger(128) cfg.Swarm.ConnMgr.LowWater = config.NewOptionalInteger(64) }) @@ -355,22 +279,8 @@ func TestRcmgr(t *testing.T) { }) } -func updateLimitsWithFile(t *testing.T, node *harness.Node, limit string, f func(*rcmgr.ResourceLimits)) { - filename := limit + ".json" - res := node.RunIPFS("swarm", "limit", limit) - limits := unmarshalLimits(t, res.Stdout.Bytes()) - - f(limits) - - limitsOut, err := json.Marshal(limits) - require.NoError(t, err) - node.WriteBytes(filename, limitsOut) - res = node.RunIPFS("swarm", "limit", limit, filename) - assert.Equal(t, 0, res.ExitCode()) -} - -func unmarshalLimits(t *testing.T, b []byte) *rcmgr.ResourceLimits { - limits := &rcmgr.ResourceLimits{} +func unmarshalLimits(t *testing.T, b []byte) *libp2p.LimitsConfigAndUsage { + limits := &libp2p.LimitsConfigAndUsage{} err := json.Unmarshal(b, limits) require.NoError(t, err) return limits diff --git a/test/sharness/t0060-daemon.sh b/test/sharness/t0060-daemon.sh index ca40fd0d1..b237e143f 100755 --- a/test/sharness/t0060-daemon.sh +++ b/test/sharness/t0060-daemon.sh @@ -81,12 +81,11 @@ test_expect_success "ipfs daemon output looks good" ' echo "Initializing daemon..." >expected_daemon && ipfs version --all >> expected_daemon && echo "" >>expected_daemon && - echo "Computing default go-libp2p Resource Manager limits based on:" >>expected_daemon && + echo "Computed default go-libp2p Resource Manager limits based on:" >>expected_daemon && echo " - '"'"'Swarm.ResourceMgr.MaxMemory'"'"': \"4GB\"" >>expected_daemon && echo " - '"'"'Swarm.ResourceMgr.MaxFileDescriptors'"'"': 1024" >>expected_daemon && echo "" >>expected_daemon && - echo "Applying any user-supplied overrides on top." >>expected_daemon && - echo "Run '"'"'ipfs swarm limit all'"'"' to see the resulting limits." >>expected_daemon && + echo "Theses can be inspected with '"'"'ipfs swarm resources'"'"'." >>expected_daemon && echo "" >>expected_daemon && sed "s/^/Swarm listening on /" listen_addrs >>expected_daemon && sed "s/^/Swarm announcing /" local_addrs >>expected_daemon && From 0f1181d23218fe2d8263eb1eab9c415ff5ea57c0 Mon Sep 17 00:00:00 2001 From: galargh Date: Mon, 6 Mar 2023 12:30:18 +0000 Subject: [PATCH 0509/1212] chore: update version --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index 1f0577fa3..71912f891 100644 --- a/version.go +++ b/version.go @@ -11,7 +11,7 @@ import ( var CurrentCommit string // CurrentVersionNumber is the current application's version literal -const CurrentVersionNumber = "0.19.0-dev" +const CurrentVersionNumber = "0.19.0-rc1" const ApiVersion = "/kubo/" + CurrentVersionNumber + "/" //nolint From 5e8fb41151ca66f1eb127417e61974936a588eec Mon Sep 17 00:00:00 2001 From: galargh Date: Mon, 6 Mar 2023 12:30:37 +0000 Subject: [PATCH 0510/1212] chore: update version --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index 1f0577fa3..992f4a988 100644 --- a/version.go +++ b/version.go @@ -11,7 +11,7 @@ import ( var CurrentCommit string // CurrentVersionNumber is the current application's version literal -const CurrentVersionNumber = "0.19.0-dev" +const CurrentVersionNumber = "0.20.0-dev" const ApiVersion = "/kubo/" + CurrentVersionNumber + "/" //nolint From 698166bf2ad349f11bb2df6b95e41c3df22863a8 Mon Sep 17 00:00:00 2001 From: omahs <73983677+omahs@users.noreply.github.com> Date: Mon, 6 Mar 2023 15:42:54 +0100 Subject: [PATCH 0511/1212] docs: fix typos --- docs/RELEASE_ISSUE_TEMPLATE.md | 10 +++++----- docs/config.md | 6 +++--- docs/delegated-routing.md | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/RELEASE_ISSUE_TEMPLATE.md b/docs/RELEASE_ISSUE_TEMPLATE.md index da3ec3e18..cb5c966a8 100644 --- a/docs/RELEASE_ISSUE_TEMPLATE.md +++ b/docs/RELEASE_ISSUE_TEMPLATE.md @@ -93,7 +93,7 @@ Checklist: - PR will be merged automatically once the diff is approved - `master` build will publish the artifacts to https://dist.ipfs.io in around 30 minutes - [ ] Ensure that the artifacts are available at https://dist.ipfs.io - - [ ] Publish the RC to [the NPM package](https://www.npmjs.com/package/go-ipfs?activeTab=versions) by running https://github.com/ipfs/npm-go-ipfs/actions/workflows/main.yml (it happens automatically but it is safe to speed up the process and kick of a run manually) + - [ ] Publish the RC to [the NPM package](https://www.npmjs.com/package/go-ipfs?activeTab=versions) by running https://github.com/ipfs/npm-go-ipfs/actions/workflows/main.yml (it happens automatically but it is safe to speed up the process and kick off a run manually) - [ ] Cut a pre-release on [GitHub](https://github.com/ipfs/kubo/releases) ([instructions](https://docs.github.com/en/repositories/releasing-projects-on-github/managing-releases-in-a-repository#creating-a-release), [example](https://github.com/ipfs/kubo/releases/tag/v0.17.0-rc1)) - Use `vX.Y.Z-rcN` as the tag. - Link to the release issue in the description. @@ -120,7 +120,7 @@ Checklist: - [ ] [Optional] Reply under a message about the issue in the #bifrost channel on FIL Slack once the RC is out. Send the message to the channel. - [ ] Check [metrics](https://protocollabs.grafana.net/d/8zlhkKTZk/gateway-slis-precomputed?orgId=1) every day. - Compare the metrics trends week over week. - - If there is an unexpected variation in the trend, message the #bifrost channel on FIL Slack and ask for help investigation the cause. + - If there is an unexpected variation in the trend, message the #bifrost channel on FIL Slack and ask for help investigating the cause. - [ ] IPFS Application Testing. - [ ] [IPFS Desktop](https://github.com/ipfs-shipyard/ipfs-desktop) - [ ] Upgrade to the RC in [ipfs-desktop](https://github.com/ipfs-shipyard/ipfs-desktop) @@ -133,13 +133,13 @@ Checklist: - [ ] Start a fresh chromium or chrome instance using `chromium --user-data-dir=$(mktemp -d)` (macos `/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --user-data-dir=$(mktemp -d)`) - [ ] Start a fresh firefox instance using `firefox --profile $(mktemp -d)` (macos `/Applications/Firefox.app/Contents/MacOS/firefox --profile $(mktemp -d)`) - [ ] Install IPFS Companion from [vendor-specific store](https://github.com/ipfs/ipfs-companion/#readme). - - [ ] Check that the comunication between Kubo daemon and IPFS companion is working properly checking if the number of connected peers changes. + - [ ] Check that the communication between Kubo daemon and IPFS companion is working properly checking if the number of connected peers changes. - [ ] **Stage 5 - Release** - _ONLY FOR FINAL RELEASE_ - [ ] Prepare the `release` branch. - [ ] Bump the version in `version.go` in the `release-vX.Y.Z` branch to `X.Y.Z`. - [ ] Update the [docs/changelogs/vX.Y.md](docs/changelogs) with the new commits and contributors. - [ ] Run `./bin/mkreleaselog` twice to generate the changelog and copy the output. - - The first run of the script might be poluted with `git clone` output. + - The first run of the script might be polluted with `git clone` output. - [ ] Paste the output into the `### Changelog` section of the changelog file inside the `
` block. - [ ] Commit the changelog changes. - [ ] Push the `release-vX.Y.Z` branch to GitHub (`git push origin release-vX.Y.Z`) @@ -169,7 +169,7 @@ Checklist: - PR will be merged automatically once the diff is approved - `master` build will publish the artifacts to https://dist.ipfs.io in around 30 minutes - [ ] Ensure that the artifacts are available at https://dist.ipfs.io - - [ ] Publish the release to [the NPM package](https://www.npmjs.com/package/go-ipfs?activeTab=versions) by running https://github.com/ipfs/npm-go-ipfs/actions/workflows/main.yml (it happens automatically but it is safe to speed up the process and kick of a run manually) + - [ ] Publish the release to [the NPM package](https://www.npmjs.com/package/go-ipfs?activeTab=versions) by running https://github.com/ipfs/npm-go-ipfs/actions/workflows/main.yml (it happens automatically but it is safe to speed up the process and kick off a run manually) - [ ] Cut the release on [GitHub](https://github.com/ipfs/kubo/releases) ([instructions](https://docs.github.com/en/repositories/releasing-projects-on-github/managing-releases-in-a-repository#creating-a-release), [example](https://github.com/ipfs/kubo/releases/tag/v0.17.0)) - Use `vX.Y.Z` as the tag. - Copy the relevant [changelog](https://github.com/ipfs/kubo/blob/release/docs/changelogs/) into the release description. diff --git a/docs/config.md b/docs/config.md index 30a4e7601..adf956ce0 100644 --- a/docs/config.md +++ b/docs/config.md @@ -454,7 +454,7 @@ Type: `string` (one of `"enabled"` or `"disabled"`) ### `AutoNAT.Throttle` -When set, this option configure's the AutoNAT services throttling behavior. By +When set, this option configures the AutoNAT services throttling behavior. By default, Kubo will rate-limit the number of NAT checks performed for other nodes to 30 per minute, and 3 per peer. @@ -616,7 +616,7 @@ Type: `bool` #### `Discovery.MDNS.Interval` -**REMOVED:** this is not configurable any more +**REMOVED:** this is not configurable anymore in the [new mDNS implementation](https://github.com/libp2p/zeroconf#readme). ## `Experimental` @@ -966,7 +966,7 @@ Type: `optionalInteger` (thread count, `null` means default which is 8) #### `Internal.Bitswap.MaxOutstandingBytesPerPeer` Maximum number of bytes (across all tasks) pending to be processed and sent to any individual peer. -This number controls fairness and can very from 250Kb (very fair) to 10Mb (less fair, with more work +This number controls fairness and can vary from 250Kb (very fair) to 10Mb (less fair, with more work dedicated to peers who ask for more). Values below 250Kb could cause thrashing. Values above 10Mb open the potential for aggressively-wanting peers to consume all resources and deteriorate the quality provided to less aggressively-wanting peers. diff --git a/docs/delegated-routing.md b/docs/delegated-routing.md index ff58aa8f9..32f7a7552 100644 --- a/docs/delegated-routing.md +++ b/docs/delegated-routing.md @@ -13,7 +13,7 @@ Now we need a better way to add different routers using different protocols like ## Motivation -The actual routing implementation is not enough. Some users needs to have more options when configuring the routing system. The new implementations should be able to: +The actual routing implementation is not enough. Some users need to have more options when configuring the routing system. The new implementations should be able to: - [x] Be user-friendly and easy enough to configure, but also versatile - [x] Configurable Router execution order From 6d7ad617477ea52d611bbd2eb8c044f0fc22451c Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Mon, 14 Nov 2022 14:17:04 +0000 Subject: [PATCH 0512/1212] fix: typo in documentation for install path By default, `go install` will install go $GOBIN and not $GOPATH/bin. In most cases there is no functional difference -- `go install` falls back to $GOPATH/bin when $GOBIN is empty. --- Rules.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Rules.mk b/Rules.mk index f7e962549..3d3d9c139 100644 --- a/Rules.mk +++ b/Rules.mk @@ -118,7 +118,7 @@ help: @echo ' all - print this help message' @echo ' build - Build binary at ./cmd/ipfs/ipfs' @echo ' nofuse - Build binary with no fuse support' - @echo ' install - Build binary and install into $$GOPATH/bin' + @echo ' install - Build binary and install into $$GOBIN' # @echo ' dist_install - TODO: c.f. ./cmd/ipfs/dist/README.md' @echo '' @echo 'CLEANING TARGETS:' From 0ee879ec69ccb95de7c57f5da48a05adc4d70f75 Mon Sep 17 00:00:00 2001 From: Piotr Galar Date: Mon, 6 Mar 2023 19:45:23 +0100 Subject: [PATCH 0513/1212] docs: sort early testers list alphabetically --- docs/EARLY_TESTERS.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/EARLY_TESTERS.md b/docs/EARLY_TESTERS.md index fb2fedc2a..b9bb1fa45 100644 --- a/docs/EARLY_TESTERS.md +++ b/docs/EARLY_TESTERS.md @@ -22,15 +22,15 @@ We will ask early testers to participate at two points in the process: ## Who has signed up? -- [ ] pacman.store (@RubenKelevra) +- [ ] Charity Engine (@rytiss, @tristanolive) +- [ ] Fission (@bmann) - [ ] Infura (@MichaelMure) -- [ ] Textile (@sanderpick) +- [ ] OrbitDB (@aphelionz) +- [ ] pacman.store (@RubenKelevra) - [ ] Pinata (@obo20) - [ ] RTrade (@postables) - [ ] Siderus (@koalalorenzo) -- [ ] Charity Engine (@rytiss, @tristanolive) -- [ ] Fission (@bmann) -- [ ] OrbitDB (@aphelionz) +- [ ] Textile (@sanderpick) ## How to sign up? From 4400db6ce425bd6db5268c3350a923315da96eb0 Mon Sep 17 00:00:00 2001 From: Piotr Galar Date: Mon, 6 Mar 2023 19:48:39 +0100 Subject: [PATCH 0514/1212] docs: add bifrost to early testers --- docs/EARLY_TESTERS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/EARLY_TESTERS.md b/docs/EARLY_TESTERS.md index b9bb1fa45..d0dd4a867 100644 --- a/docs/EARLY_TESTERS.md +++ b/docs/EARLY_TESTERS.md @@ -28,6 +28,7 @@ We will ask early testers to participate at two points in the process: - [ ] OrbitDB (@aphelionz) - [ ] pacman.store (@RubenKelevra) - [ ] Pinata (@obo20) +- [ ] PL EngRes bifrost (@gmasgras) - [ ] RTrade (@postables) - [ ] Siderus (@koalalorenzo) - [ ] Textile (@sanderpick) From a52625f1812145c439d92eb5890cb295d8121ace Mon Sep 17 00:00:00 2001 From: galargh Date: Mon, 6 Mar 2023 20:25:49 +0100 Subject: [PATCH 0515/1212] chore: update release issue template to use lowercase for rc --- docs/RELEASE_ISSUE_TEMPLATE.md | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/docs/RELEASE_ISSUE_TEMPLATE.md b/docs/RELEASE_ISSUE_TEMPLATE.md index 9d4d22eb6..8525d6473 100644 --- a/docs/RELEASE_ISSUE_TEMPLATE.md +++ b/docs/RELEASE_ISSUE_TEMPLATE.md @@ -79,7 +79,7 @@ This section covers tasks to be done ahead of the release. - [example](https://github.com/ipfs/distributions/pull/756) - [ ] ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) [ipfs/ipfs-docs](https://github.com/ipfs/ipfs-docs) - [example](https://github.com/ipfs/ipfs-docs/pull/1298) -- [ ] Notify the bifrost team about the upcoming release (_only if it is not the day of the release yet_)
using `kuboreleaser release --version vX.Y.Z(-RCN) notify-bifrost --date YYYY-MM-DD` or ... +- [ ] Notify the bifrost team about the upcoming release (_only if it is not the day of the release yet_)
using `kuboreleaser release --version vX.Y.Z(-rcN) notify-bifrost --date YYYY-MM-DD` or ... - [ ] open an issue against [bifrost-infra](https://github.com/protocol/bifrost-infra) - [example](https://github.com/protocol/bifrost-infra/issues/2221)
@@ -93,7 +93,7 @@ This section covers tasks to be done ahead of the release. This section covers tasks to be done during each release. -- [ ] Prepare the release branch and update version numbers accordingly
using `kuboreleaser release --version vX.Y.Z(-RCN) prepare-branch` or ... +- [ ] Prepare the release branch and update version numbers accordingly
using `kuboreleaser release --version vX.Y.Z(-rcN) prepare-branch` or ... - [ ] create a new branch `release-vX.Y.Z` - use `master` as base if `Z == 0` - use `release` as base if `Z > 0` @@ -112,7 +112,7 @@ This section covers tasks to be done during each release. - do **NOT** use `Squash and merge` nor `Rebase and merge` because we need to be able to sign the merge commit - do **NOT** delete the `release-vX.Y` branch
-- [ ] Create the release tag
using `kuboreleaser release --version vX.Y.Z(-RCN) tag` or ... +- [ ] Create the release tag
using `kuboreleaser release --version vX.Y.Z(-rcN) tag` or ... - This is a dangerous operation! Go and Docker publishing are difficult to reverse! Have the release reviewer verify all the commands marked with ⚠️! - [ ] ⚠️ ![](https://img.shields.io/badge/only-RC-blue?style=flat-square) tag the HEAD commit using `git tag -s vX.Y.Z(-RCN) -m 'Prerelease X.Y.Z(-RCN)'` - [ ] ⚠️ ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) tag the HEAD commit of the `release` branch using `git tag -s vX.Y.Z(-RCN) -m 'Release X.Y.Z(-RCN)'` @@ -120,10 +120,10 @@ This section covers tasks to be done during each release. - [ ] ⚠️ push the tag to GitHub using `git push origin vX.Y.Z(-RCN)` - do **NOT** use `git push --tags` because it pushes all your local tags
-- [ ] Publish the release to [DockerHub](https://hub.docker.com/r/ipfs/kubo/)
using `kuboreleaser --skip-check-before --skip-run release --version vX.Y.Z(-RCN) publish-to-dockerhub` or ... +- [ ] Publish the release to [DockerHub](https://hub.docker.com/r/ipfs/kubo/)
using `kuboreleaser --skip-check-before --skip-run release --version vX.Y.Z(-rcN) publish-to-dockerhub` or ... - [ ] Wait for [Publish docker image](https://github.com/ipfs/kubo/actions/workflows/docker-image.yml) workflow run initiated by the tag push to finish - [ ] verify the image is available on [Docker Hub](https://hub.docker.com/r/ipfs/kubo/tags) -- [ ] Publish the release to [ipfs.tech](https://dist.ipfs.tech)
using `kuboreleaser release --version vX.Y.Z(-RCN) publish-to-distributions` or ... +- [ ] Publish the release to [ipfs.tech](https://dist.ipfs.tech)
using `kuboreleaser release --version vX.Y.Z(-rcN) publish-to-distributions` or ... - [ ] check out [ipfs/distributions](https://github.com/ipfs/distributions) - [ ] run `./dist.sh add-version kubo vX.Y.Z(-RCN)` to add the new version to the `versions` file - [usage](https://github.com/ipfs/distributions#usage) @@ -132,12 +132,12 @@ This section covers tasks to be done during each release. - [ ] wait for the [CI](https://github.com/ipfs/distributions/actions/workflows/main.yml) workflow run initiated by the merge to master to finish - [ ] verify the release is available on [dist.ipfs.io](https://dist.ipfs.io/#kubo)
-- [ ] Publish the release to [NPM](https://www.npmjs.com/package/go-ipfs?activeTab=versions)
using `kuboreleaser release --version vX.Y.Z(-RCN) publish-to-npm` or ... +- [ ] Publish the release to [NPM](https://www.npmjs.com/package/go-ipfs?activeTab=versions)
using `kuboreleaser release --version vX.Y.Z(-rcN) publish-to-npm` or ... - [ ] run the [Release to npm](https://github.com/ipfs/npm-go-ipfs/actions/workflows/main.yml) workflow - [ ] check [Release to npm](https://github.com/ipfs/npm-go-ipfs/actions/workflows/main.yml) workflow run logs to verify it discovered the new release - [ ] verify the release is available on [NPM](https://www.npmjs.com/package/go-ipfs?activeTab=versions)
-- [ ] Publish the release to [GitHub](https://github.com/ipfs/kubo/releases)
using `kuboreleaser release --version vX.Y.Z(-RCN) publish-to-github` or ... +- [ ] Publish the release to [GitHub](https://github.com/ipfs/kubo/releases)
using `kuboreleaser release --version vX.Y.Z(-rcN) publish-to-github` or ... - [ ] create a new release on [GitHub](https://docs.github.com/en/repositories/releasing-projects-on-github/managing-releases-in-a-repository#creating-a-release) - [RC example](https://github.com/ipfs/kubo/releases/tag/v0.17.0-rc1) - [FINAL example](https://github.com/ipfs/kubo/releases/tag/v0.17.0) @@ -151,10 +151,10 @@ This section covers tasks to be done during each release. - [ ] wait for the [sync-release-assets](https://github.com/ipfs/kubo/actions/workflows/sync-release-assets.yml) workflow run to finish - [ ] verify the release assets are present in the [GitHub release](https://github.com/ipfs/kubo/releases/tag/vX.Y.Z(-RCN))
-- [ ] Notify the bifrost team about the release
using `kuboreleaser release --version vX.Y.Z(-RCN) notify-bifrost --date YYYY-MM-DD` or ... +- [ ] Notify the bifrost team about the release
using `kuboreleaser release --version vX.Y.Z(-rcN) notify-bifrost --date YYYY-MM-DD` or ... - [ ] create an issue comment on the issue in the [bifrost-infra](https://github/com/protocol/bifrost-infra)
-- [ ] Promote the release
using `kuboreleaser release --version vX.Y.Z(-RCN) promote` or ... +- [ ] Promote the release
using `kuboreleaser release --version vX.Y.Z(-rcN) promote` or ... - [ ] create an [IPFS Discourse](https://discuss.ipfs.tech) topic - [prerelease example](https://discuss.ipfs.tech/t/kubo-v0-16-0-rc1-release-candidate-is-out/15248) - [release example](https://discuss.ipfs.tech/t/kubo-v0-16-0-release-is-out/15249) @@ -179,28 +179,28 @@ This section covers tasks to be done during each release. - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) post the link to the [GitHub Release](https://github.com/ipfs/kubo/releases/tag/vX.Y.Z(-RCN)) to [Reddit](https://reddit.com/r/ipfs) - [example](https://www.reddit.com/r/ipfs/comments/9x0q0k/kubo_v0160_release_is_out/)
-- [ ] Test the new version with `ipfs-companion`
using `kuboreleaser release --version vX.Y.Z(-RCN) test-ipfs-companion` or ... +- [ ] Test the new version with `ipfs-companion`
using `kuboreleaser release --version vX.Y.Z(-rcN) test-ipfs-companion` or ... - [ ] run the [e2e](https://github.com/ipfs/ipfs-companion/actions/workflows/e2e.yml) - use `vX.Y.Z(-RCN)` as the Kubo image version - [ ] wait for the [e2e](https://github.com/ipfs/ipfs-companion/actions/workflows/e2e.yml) workflow run to finish
-- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Update Kubo in [interop](https://github.com/ipfs/interop)
using `kuboreleaser release --version vX.Y.Z(-RCN) update-interop` or ... +- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Update Kubo in [interop](https://github.com/ipfs/interop)
using `kuboreleaser release --version vX.Y.Z(-rcN) update-interop` or ... - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) check out [ipfs/interop](https://github.com/ipfs/interop) - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) run `npm install` - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) create a PR which updates `package.json` and `package-lock.json` - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) merge the PR
-- [ ] Update Kubo in [ipfs-desktop](https://github.com/ipfs/ipfs-desktop)
using `kuboreleaser release --version vX.Y.Z(-RCN) update-ipfs-desktop` or ... +- [ ] Update Kubo in [ipfs-desktop](https://github.com/ipfs/ipfs-desktop)
using `kuboreleaser release --version vX.Y.Z(-rcN) update-ipfs-desktop` or ... - [ ] check out [ipfs/ipfs-desktop](https://github.com/ipfs/ipfs-desktop) - [ ] run `npm install` - [ ] create a PR which updates `package.json` and `package-lock.json` - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) add @SgtPooki and @whizzzkid as reviewers
-- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Update Kubo docs
using `kuboreleaser release --version vX.Y.Z(-RCN) update-ipfs-docs` or ... +- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Update Kubo docs
using `kuboreleaser release --version vX.Y.Z(-rcN) update-ipfs-docs` or ... - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) run the [update-on-new-ipfs-tag.yml](https://github.com/ipfs/ipfs-docs/actions/workflows/update-on-new-ipfs-tag.yml) workflow - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) merge the PR created by the [update-on-new-ipfs-tag.yml](https://github.com/ipfs/ipfs-docs/actions/workflows/update-on-new-ipfs-tag.yml) workflow run
-- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Create a blog entry on [ipfs.tech](https://blog.ipfs.tech)
using `kuboreleaser release --version vX.Y.Z(-RCN) update-ipfs-blog --date YYYY-MM-DD` or ... +- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Create a blog entry on [ipfs.tech](https://blog.ipfs.tech)
using `kuboreleaser release --version vX.Y.Z(-rcN) update-ipfs-blog --date YYYY-MM-DD` or ... - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) create a PR which adds a release note for the new Kubo version - [example](https://github.com/ipfs/ipfs-blog/pull/529) - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) merge the PR @@ -209,11 +209,11 @@ This section covers tasks to be done during each release. - [ ] ![](https://img.shields.io/badge/only-RC-blue?style=flat-square) Keep checking the [metrics](https://protocollabs.grafana.net/d/8zlhkKTZk/gateway-slis-precomputed?orgId=1) until the release issue is closed - [release notes](https://www.notion.so/pl-strflt/Kubo-Gateway-Release-Notes-6e0efff28ee540be9ccb8f2b85104c42) - post in the [#bifrost](https://filecoinproject.slack.com/archives/C018EJ8LWH1) channel in FIL Slack if there is a problem -- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Merge the [release](https://github.com/ipfs/kubo/tree/release) branch back into [master](https://github.com/ipfs/kubo/tree/master), ignoring the changes to [version.go](version.go) (keep the `-dev`) version,
using `kuboreleaser release --version vX.Y.Z(-RCN) merge-branch` or ... +- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Merge the [release](https://github.com/ipfs/kubo/tree/release) branch back into [master](https://github.com/ipfs/kubo/tree/master), ignoring the changes to [version.go](version.go) (keep the `-dev`) version,
using `kuboreleaser release --version vX.Y.Z(-rcN) merge-branch` or ... - [ ] create a new branch `merge-release-vX.Y.Z` from `release` - [ ] create and merge a PR from `merge-release-vX.Y.Z` to `master`
-- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) Prepare for the next release
using `kuboreleaser release --version vX.Y.Z(-RCN) prepare-next` or ... +- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) Prepare for the next release
using `kuboreleaser release --version vX.Y.Z(-rcN) prepare-next` or ... - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) Create the next [changelog](https://github.com/ipfs/kubo/blob/master/docs/changelogs/vX.(Y+1).md) - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) Link to the new changelog in the [CHANGELOG.md](CHANGELOG.md) file - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) Create the next release issue From 9b7a31d28847e317b4d8baa5ed3c7a5f55666f7b Mon Sep 17 00:00:00 2001 From: galargh Date: Mon, 6 Mar 2023 20:27:25 +0100 Subject: [PATCH 0516/1212] refactor: remove unnecessary tasks in RELEASE_ISSUE_TEMPLATE.md --- docs/RELEASE_ISSUE_TEMPLATE.md | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/docs/RELEASE_ISSUE_TEMPLATE.md b/docs/RELEASE_ISSUE_TEMPLATE.md index 8525d6473..b4306536c 100644 --- a/docs/RELEASE_ISSUE_TEMPLATE.md +++ b/docs/RELEASE_ISSUE_TEMPLATE.md @@ -13,7 +13,6 @@ * Expected RC date: week of YYYY-MM-DD * 🚢 Expected final release date: YYYY-MM-DD * Accompanying PR for improving the release process: (example: https://github.com/ipfs/kubo/pull/9391) -* Accompanying Issue for updating the infra: (example: https://github.com/protocol/bifrost-infra/issues/2221) See the [Kubo release process](https://pl-strflt.notion.site/Kubo-Release-Process-5a5d066264704009a28a79cff93062c4) for more info. @@ -29,8 +28,6 @@ As usual, this release includes important fixes, some of which may be critical f ### Required -- [ ] Do we need to make any changes to the [infrastructure configuration](https://github.com/protocol/bifrost-infra/tree/master/ansible/inventories/bifrost/group_vars)? - ### Nice to have ## 🔦 Highlights @@ -60,8 +57,6 @@ This section covers tasks to be done ahead of the release. - [ ] [GPG signature](https://docs.github.com/en/authentication/managing-commit-signature-verification) configured in local git and in GitHub - [ ] [admin access to IPFS Discourse](https://discuss.ipfs.tech/g/admins) - ask the previous release owner (or @2color) for an invite - - [ ] [access to #bifrost](https://filecoinproject.slack.com/archives/C03MMMF606T) channel in FIL Slack - - ask the previous release owner for an invite - [ ] ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) [access to #shared-pl-marketing-requests](https://filecoinproject.slack.com/archives/C018EJ8LWH1) channel in FIL Slack - ask the previous release owner for an invite - [ ] [access to IPFS network metrics](https://github.com/protocol/pldw/blob/624f47cf4ec14ad2cec6adf601a9f7b203ef770d/docs/sources/ipfs.md#ipfs-network-metrics) dashboards in Grafana @@ -79,11 +74,6 @@ This section covers tasks to be done ahead of the release. - [example](https://github.com/ipfs/distributions/pull/756) - [ ] ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) [ipfs/ipfs-docs](https://github.com/ipfs/ipfs-docs) - [example](https://github.com/ipfs/ipfs-docs/pull/1298) -- [ ] Notify the bifrost team about the upcoming release (_only if it is not the day of the release yet_)
using `kuboreleaser release --version vX.Y.Z(-rcN) notify-bifrost --date YYYY-MM-DD` or ... - - [ ] open an issue against [bifrost-infra](https://github.com/protocol/bifrost-infra) - - [example](https://github.com/protocol/bifrost-infra/issues/2221) -
-- [ ] Link the [bifrost-infra](https://github.com/protocol/bifrost-infra) issue in the [Meta](#meta) section - [ ] Verify there is nothing [left for release](-what-s-left-for-release) - [ ] Create a release process improvement PR - [ ] update the [release issue template](docs/RELEASE_ISSUE_TEMPLATE.md) as you go @@ -151,9 +141,6 @@ This section covers tasks to be done during each release. - [ ] wait for the [sync-release-assets](https://github.com/ipfs/kubo/actions/workflows/sync-release-assets.yml) workflow run to finish - [ ] verify the release assets are present in the [GitHub release](https://github.com/ipfs/kubo/releases/tag/vX.Y.Z(-RCN))
-- [ ] Notify the bifrost team about the release
using `kuboreleaser release --version vX.Y.Z(-rcN) notify-bifrost --date YYYY-MM-DD` or ... - - [ ] create an issue comment on the issue in the [bifrost-infra](https://github/com/protocol/bifrost-infra) -
- [ ] Promote the release
using `kuboreleaser release --version vX.Y.Z(-rcN) promote` or ... - [ ] create an [IPFS Discourse](https://discuss.ipfs.tech) topic - [prerelease example](https://discuss.ipfs.tech/t/kubo-v0-16-0-rc1-release-candidate-is-out/15248) @@ -206,9 +193,6 @@ This section covers tasks to be done during each release. - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) merge the PR - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) verify the blog entry was published
-- [ ] ![](https://img.shields.io/badge/only-RC-blue?style=flat-square) Keep checking the [metrics](https://protocollabs.grafana.net/d/8zlhkKTZk/gateway-slis-precomputed?orgId=1) until the release issue is closed - - [release notes](https://www.notion.so/pl-strflt/Kubo-Gateway-Release-Notes-6e0efff28ee540be9ccb8f2b85104c42) - - post in the [#bifrost](https://filecoinproject.slack.com/archives/C018EJ8LWH1) channel in FIL Slack if there is a problem - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Merge the [release](https://github.com/ipfs/kubo/tree/release) branch back into [master](https://github.com/ipfs/kubo/tree/master), ignoring the changes to [version.go](version.go) (keep the `-dev`) version,
using `kuboreleaser release --version vX.Y.Z(-rcN) merge-branch` or ... - [ ] create a new branch `merge-release-vX.Y.Z` from `release` - [ ] create and merge a PR from `merge-release-vX.Y.Z` to `master` From 30fdc9c1e856e55a1cecf78f23598605d3c6ac1b Mon Sep 17 00:00:00 2001 From: galargh Date: Mon, 6 Mar 2023 20:27:57 +0100 Subject: [PATCH 0517/1212] feat: restrict updating kubo in ipfs-desktop to final releases only --- docs/RELEASE_ISSUE_TEMPLATE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/RELEASE_ISSUE_TEMPLATE.md b/docs/RELEASE_ISSUE_TEMPLATE.md index b4306536c..3ece6d414 100644 --- a/docs/RELEASE_ISSUE_TEMPLATE.md +++ b/docs/RELEASE_ISSUE_TEMPLATE.md @@ -177,7 +177,7 @@ This section covers tasks to be done during each release. - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) create a PR which updates `package.json` and `package-lock.json` - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) merge the PR
-- [ ] Update Kubo in [ipfs-desktop](https://github.com/ipfs/ipfs-desktop)
using `kuboreleaser release --version vX.Y.Z(-rcN) update-ipfs-desktop` or ... +- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Update Kubo in [ipfs-desktop](https://github.com/ipfs/ipfs-desktop)
using `kuboreleaser release --version vX.Y.Z(-rcN) update-ipfs-desktop` or ... - [ ] check out [ipfs/ipfs-desktop](https://github.com/ipfs/ipfs-desktop) - [ ] run `npm install` - [ ] create a PR which updates `package.json` and `package-lock.json` From 0f65594d9e8e8803eb306d40a46c4b19221ffd9e Mon Sep 17 00:00:00 2001 From: Alex Date: Tue, 7 Mar 2023 23:01:49 +0000 Subject: [PATCH 0518/1212] Apply suggestions from code review Co-authored-by: Piotr Galar --- .github/workflows/codeql-analysis.yml | 4 +--- .github/workflows/sync-release-assets.yml | 5 ++--- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index c5bbc1c2c..7cd6c4003 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -13,12 +13,10 @@ on: permissions: contents: read # to fetch code (actions/checkout) + security-events: write # (github/codeql-action/autobuild) jobs: analyze: - permissions: - contents: read # to fetch code (actions/checkout) - security-events: write # (github/codeql-action/autobuild) if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' name: Analyze diff --git a/.github/workflows/sync-release-assets.yml b/.github/workflows/sync-release-assets.yml index 0a7f2e626..1e9b51a3a 100644 --- a/.github/workflows/sync-release-assets.yml +++ b/.github/workflows/sync-release-assets.yml @@ -9,11 +9,10 @@ concurrency: group: release-assets-dist-sync cancel-in-progress: true -permissions: {} +permissions: + contents: write # to upload release asset jobs: sync-github-and-dist-ipfs-tech: - permissions: - contents: write # to upload release asset if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' runs-on: "ubuntu-latest" From b21e819923c7f0852791534fcf140cbc29185845 Mon Sep 17 00:00:00 2001 From: Piotr Galar Date: Wed, 8 Mar 2023 08:00:44 +0100 Subject: [PATCH 0519/1212] Apply suggestions from code review --- .github/workflows/codeql-analysis.yml | 1 - .github/workflows/sync-release-assets.yml | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 7cd6c4003..e732a1148 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -17,7 +17,6 @@ permissions: jobs: analyze: - if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' name: Analyze runs-on: ubuntu-latest diff --git a/.github/workflows/sync-release-assets.yml b/.github/workflows/sync-release-assets.yml index 1e9b51a3a..0c295d804 100644 --- a/.github/workflows/sync-release-assets.yml +++ b/.github/workflows/sync-release-assets.yml @@ -11,9 +11,9 @@ concurrency: permissions: contents: write # to upload release asset + jobs: sync-github-and-dist-ipfs-tech: - if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' runs-on: "ubuntu-latest" timeout-minutes: 5 From 40d7f2feccd7b59e476717e8f7730f521f70ebba Mon Sep 17 00:00:00 2001 From: Jorropo Date: Tue, 7 Mar 2023 19:28:52 +0100 Subject: [PATCH 0520/1212] chore: bump go-libipfs v0.6.1 This does nothing, just move from an untagged commit to a tagged commit but contain the same things. --- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 056aea334..1c19dd3eb 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.18 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/go-libipfs v0.6.1-0.20230228004237-36918f45f260 + github.com/ipfs/go-libipfs v0.6.1 github.com/ipfs/interface-go-ipfs-core v0.11.0 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.26.2 diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 8a07bfbe8..c927b58d9 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -569,8 +569,8 @@ github.com/ipfs/go-ipld-legacy v0.1.1 h1:BvD8PEuqwBHLTKqlGFTHSwrwFOMkVESEvwIYwR2 github.com/ipfs/go-ipld-legacy v0.1.1/go.mod h1:8AyKFCjgRPsQFf15ZQgDB8Din4DML/fOmKZkkFkrIEg= github.com/ipfs/go-ipns v0.3.0 h1:ai791nTgVo+zTuq2bLvEGmWP1M0A6kGTXUsgv/Yq67A= github.com/ipfs/go-ipns v0.3.0/go.mod h1:3cLT2rbvgPZGkHJoPO1YMJeh6LtkxopCkKFcio/wE24= -github.com/ipfs/go-libipfs v0.6.1-0.20230228004237-36918f45f260 h1:QRLcCoITO9ZQo2pvjmrfngqKhUKjPopBva3MVH62LT8= -github.com/ipfs/go-libipfs v0.6.1-0.20230228004237-36918f45f260/go.mod h1:3OoEQs95UkqFEf65SbRDpiMwuzI+C/jTsYQaHfBbJXI= +github.com/ipfs/go-libipfs v0.6.1 h1:OSO9cm1H3r4OXfP0MP1Q5UhTnhd2fByGl6CVYyz/Rhk= +github.com/ipfs/go-libipfs v0.6.1/go.mod h1:FmhKgxMOQA572TK5DA3MZ5GL44ZqsMHIrkgK4gLn4A8= github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= github.com/ipfs/go-log v1.0.2/go.mod h1:1MNjMxe0u6xvJZgeqbJ8vdo2TKaGwZ1a0Bpza+sr2Sk= github.com/ipfs/go-log v1.0.3/go.mod h1:OsLySYkwIbiSUR/yBTdv1qPtcE4FW3WPWk/ewz9Ru+A= diff --git a/go.mod b/go.mod index 34603ebd2..673dd3793 100644 --- a/go.mod +++ b/go.mod @@ -45,7 +45,7 @@ require ( github.com/ipfs/go-ipld-git v0.1.1 github.com/ipfs/go-ipld-legacy v0.1.1 github.com/ipfs/go-ipns v0.3.0 - github.com/ipfs/go-libipfs v0.6.1-0.20230228004237-36918f45f260 + github.com/ipfs/go-libipfs v0.6.1 github.com/ipfs/go-log v1.0.5 github.com/ipfs/go-log/v2 v2.5.1 github.com/ipfs/go-merkledag v0.9.0 diff --git a/go.sum b/go.sum index 6f7800a2e..16329d6ad 100644 --- a/go.sum +++ b/go.sum @@ -591,8 +591,8 @@ github.com/ipfs/go-ipld-legacy v0.1.1 h1:BvD8PEuqwBHLTKqlGFTHSwrwFOMkVESEvwIYwR2 github.com/ipfs/go-ipld-legacy v0.1.1/go.mod h1:8AyKFCjgRPsQFf15ZQgDB8Din4DML/fOmKZkkFkrIEg= github.com/ipfs/go-ipns v0.3.0 h1:ai791nTgVo+zTuq2bLvEGmWP1M0A6kGTXUsgv/Yq67A= github.com/ipfs/go-ipns v0.3.0/go.mod h1:3cLT2rbvgPZGkHJoPO1YMJeh6LtkxopCkKFcio/wE24= -github.com/ipfs/go-libipfs v0.6.1-0.20230228004237-36918f45f260 h1:QRLcCoITO9ZQo2pvjmrfngqKhUKjPopBva3MVH62LT8= -github.com/ipfs/go-libipfs v0.6.1-0.20230228004237-36918f45f260/go.mod h1:3OoEQs95UkqFEf65SbRDpiMwuzI+C/jTsYQaHfBbJXI= +github.com/ipfs/go-libipfs v0.6.1 h1:OSO9cm1H3r4OXfP0MP1Q5UhTnhd2fByGl6CVYyz/Rhk= +github.com/ipfs/go-libipfs v0.6.1/go.mod h1:FmhKgxMOQA572TK5DA3MZ5GL44ZqsMHIrkgK4gLn4A8= github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= github.com/ipfs/go-log v1.0.2/go.mod h1:1MNjMxe0u6xvJZgeqbJ8vdo2TKaGwZ1a0Bpza+sr2Sk= github.com/ipfs/go-log v1.0.3/go.mod h1:OsLySYkwIbiSUR/yBTdv1qPtcE4FW3WPWk/ewz9Ru+A= From f509e24984d0649d5079d6ad8c74c93a23cd09f2 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Wed, 8 Mar 2023 17:59:42 +0100 Subject: [PATCH 0521/1212] docs: add PubSub to changelog --- docs/changelogs/v0.19.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/changelogs/v0.19.md b/docs/changelogs/v0.19.md index 7663308a6..7a6274ee3 100644 --- a/docs/changelogs/v0.19.md +++ b/docs/changelogs/v0.19.md @@ -7,6 +7,7 @@ - [Overview](#overview) - [🔦 Highlights](#-highlights) - [Improving the libp2p resource management integration](#improving-the-libp2p-resource-management-integration) + - [Pubsub message caching improvements](#pubsub-message-caching-improvements) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -22,6 +23,10 @@ and [0.18.1](https://github.com/ipfs/kubo/blob/master/docs/changelogs/v0.18.md#i - Note: we don't expect most users to need these capablities, but they are there if so. 1. [Doc updates](https://github.com/ipfs/kubo/blob/master/docs/libp2p-resource-management.md). +#### PubSub message caching improvements + +The PubSub message cache will now [prune messages after TTL is exhausted](https://github.com/ipfs/kubo/blob/master/docs/config.md#pubsubseenmessagesttl), [either based on the last time a message was seen or the first time it was seen](https://github.com/ipfs/kubo/blob/master/docs/config.md#pubsubseenmessagesstrategy). + ### 📝 Changelog ### 👨‍👩‍👧‍👦 Contributors From fb663c6bb474a998bc4c0f56ef7c48dbe6c289e9 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Thu, 9 Mar 2023 00:24:46 +0100 Subject: [PATCH 0522/1212] docs: add IPIP-351 to 0.19 changelog --- docs/changelogs/v0.19.md | 45 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/docs/changelogs/v0.19.md b/docs/changelogs/v0.19.md index 7a6274ee3..3ce12e8d2 100644 --- a/docs/changelogs/v0.19.md +++ b/docs/changelogs/v0.19.md @@ -7,7 +7,10 @@ - [Overview](#overview) - [🔦 Highlights](#-highlights) - [Improving the libp2p resource management integration](#improving-the-libp2p-resource-management-integration) - - [Pubsub message caching improvements](#pubsub-message-caching-improvements) + - [PubSub message caching improvements](#pubsub-message-caching-improvements) + - [Gateways](#gateways) + - [Signed IPNS Record response format](#signed-ipns-record-response-format) + - [Example fetch and inspect IPNS record](#example-fetch-and-inspect-ipns-record) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -27,6 +30,46 @@ and [0.18.1](https://github.com/ipfs/kubo/blob/master/docs/changelogs/v0.18.md#i The PubSub message cache will now [prune messages after TTL is exhausted](https://github.com/ipfs/kubo/blob/master/docs/config.md#pubsubseenmessagesttl), [either based on the last time a message was seen or the first time it was seen](https://github.com/ipfs/kubo/blob/master/docs/config.md#pubsubseenmessagesstrategy). +#### Gateways + +##### Signed IPNS Record response format + +This release implements [IPIP-351](https://github.com/ipfs/specs/pull/351) and +adds Gateway support for returning signed (verifiable) `ipns-record` (0x0300) +when `/ipns/{libp2p-key}` is requested with either +`Accept: application/vnd.ipfs.ipns-record` HTTP header +or `?format=ipns-record` URL query parameter. + + +The Gateway in Kubo already supported [trustless, verifiable retrieval](https://docs.ipfs.tech/reference/http/gateway/#trustless-verifiable-retrieval) of immutable `/ipfs/` namespace. +With `?format=ipns-record`, light HTTP clients are now able to get the same level of verifiability for IPNS websites. + +Tooling is limited at the moment, but we are working on [go-libipfs](https://github.com/ipfs/go-libipfs/) examples that illustrate the verifiable HTTP client pattern. + +##### Example: fetch IPNS record over HTTP and inspect it with `ipfs name inspect --verify` + +```console +$ FILE_CID=$(echo "Hello IPFS" | ipfs add --cid-version 1 -q) +$ IPNS_KEY=$(ipfs key gen test) +$ ipfs name publish /ipfs/$FILE_CID --key=test --ttl=30m +Published to k51q..dvf1: /ipfs/bafk..z244 +$ curl "http://127.0.0.1:8080/ipns/$IPNS_KEY?format=ipns-record" > signed.ipns-record +$ ipfs name inspect --verify $IPNS_KEY < signed.ipns-record +Value: "/ipfs/bafk..." +Validity Type: "EOL" +Validity: 2023-03-09T23:13:34.032977468Z +Sequence: 0 +TTL: 1800000000000 +PublicKey: "" +Signature V1: "m..." +Signature V2: "m..." +Data: {...} + +Validation results: + Valid: true + PublicKey: 12D3... +``` + ### 📝 Changelog ### 👨‍👩‍👧‍👦 Contributors From ad5a0fea0e4627e66902c5ae5690892b67bf8d23 Mon Sep 17 00:00:00 2001 From: Gus Eggert Date: Wed, 8 Mar 2023 15:48:56 -0500 Subject: [PATCH 0523/1212] test: port legacy DHT tests to Go --- test/cli/dht_legacy_test.go | 137 ++++++++++++++++++++++++++++++ test/cli/harness/harness.go | 2 +- test/cli/harness/node.go | 44 +++++++--- test/cli/harness/nodes.go | 16 ++++ test/cli/harness/run.go | 8 +- test/sharness/t0170-legacy-dht.sh | 121 -------------------------- 6 files changed, 192 insertions(+), 136 deletions(-) create mode 100644 test/cli/dht_legacy_test.go delete mode 100755 test/sharness/t0170-legacy-dht.sh diff --git a/test/cli/dht_legacy_test.go b/test/cli/dht_legacy_test.go new file mode 100644 index 000000000..437b62ae4 --- /dev/null +++ b/test/cli/dht_legacy_test.go @@ -0,0 +1,137 @@ +package cli + +import ( + "sort" + "sync" + "testing" + + "github.com/ipfs/kubo/test/cli/harness" + "github.com/ipfs/kubo/test/cli/testutils" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestLegacyDHT(t *testing.T) { + nodes := harness.NewT(t).NewNodes(5).Init() + nodes.ForEachPar(func(node *harness.Node) { + node.IPFS("config", "Routing.Type", "dht") + }) + nodes.StartDaemons().Connect() + + t.Run("ipfs dht findpeer", func(t *testing.T) { + t.Parallel() + res := nodes[1].RunIPFS("dht", "findpeer", nodes[0].PeerID().String()) + assert.Equal(t, 0, res.ExitCode()) + + swarmAddr := nodes[0].SwarmAddrsWithoutPeerIDs()[0] + require.Equal(t, swarmAddr.String(), res.Stdout.Trimmed()) + }) + + t.Run("ipfs dht get ", func(t *testing.T) { + t.Parallel() + hash := nodes[2].IPFSAddStr("hello world") + nodes[2].IPFS("name", "publish", "/ipfs/"+hash) + + res := nodes[1].IPFS("dht", "get", "/ipns/"+nodes[2].PeerID().String()) + assert.Contains(t, res.Stdout.String(), "/ipfs/"+hash) + + t.Run("put round trips (#3124)", func(t *testing.T) { + t.Parallel() + nodes[0].WriteBytes("get_result", res.Stdout.Bytes()) + res := nodes[0].IPFS("dht", "put", "/ipns/"+nodes[2].PeerID().String(), "get_result") + assert.Greater(t, len(res.Stdout.Lines()), 0, "should put to at least one node") + }) + + t.Run("put with bad keys fails (issue #5113, #4611)", func(t *testing.T) { + t.Parallel() + keys := []string{"foo", "/pk/foo", "/ipns/foo"} + for _, key := range keys { + key := key + t.Run(key, func(t *testing.T) { + t.Parallel() + res := nodes[0].RunIPFS("dht", "put", key) + assert.Equal(t, 1, res.ExitCode()) + assert.Contains(t, res.Stderr.String(), "invalid") + assert.Empty(t, res.Stdout.String()) + }) + } + }) + + t.Run("get with bad keys (issue #4611)", func(t *testing.T) { + for _, key := range []string{"foo", "/pk/foo"} { + key := key + t.Run(key, func(t *testing.T) { + t.Parallel() + res := nodes[0].RunIPFS("dht", "get", key) + assert.Equal(t, 1, res.ExitCode()) + assert.Contains(t, res.Stderr.String(), "invalid") + assert.Empty(t, res.Stdout.String()) + }) + } + }) + }) + + t.Run("ipfs dht findprovs", func(t *testing.T) { + t.Parallel() + hash := nodes[3].IPFSAddStr("some stuff") + res := nodes[4].IPFS("dht", "findprovs", hash) + assert.Equal(t, nodes[3].PeerID().String(), res.Stdout.Trimmed()) + }) + + t.Run("ipfs dht query ", func(t *testing.T) { + t.Parallel() + t.Run("normal DHT configuration", func(t *testing.T) { + t.Parallel() + hash := nodes[0].IPFSAddStr("some other stuff") + peerCounts := map[string]int{} + peerCountsMut := sync.Mutex{} + harness.Nodes(nodes).ForEachPar(func(node *harness.Node) { + res := node.IPFS("dht", "query", hash) + closestPeer := res.Stdout.Lines()[0] + // check that it's a valid peer ID + _, err := peer.Decode(closestPeer) + require.NoError(t, err) + + peerCountsMut.Lock() + peerCounts[closestPeer]++ + peerCountsMut.Unlock() + }) + // 4 nodes should see the same peer ID + // 1 node (the closest) should see a different one + var counts []int + for _, count := range peerCounts { + counts = append(counts, count) + } + sort.IntSlice(counts).Sort() + assert.Equal(t, []int{1, 4}, counts) + }) + + }) + + t.Run("dht commands fail when offline", func(t *testing.T) { + t.Parallel() + node := harness.NewT(t).NewNode().Init() + + // these cannot be run in parallel due to repo locking (seems like a bug) + + t.Run("dht findprovs", func(t *testing.T) { + res := node.RunIPFS("dht", "findprovs", testutils.CIDEmptyDir) + assert.Equal(t, 1, res.ExitCode()) + assert.Contains(t, res.Stderr.String(), "this command must be run in online mode") + }) + + t.Run("dht findpeer", func(t *testing.T) { + res := node.RunIPFS("dht", "findpeer", testutils.CIDEmptyDir) + assert.Equal(t, 1, res.ExitCode()) + assert.Contains(t, res.Stderr.String(), "this command must be run in online mode") + }) + + t.Run("dht put", func(t *testing.T) { + node.WriteBytes("foo", []byte("foo")) + res := node.RunIPFS("dht", "put", "/ipns/"+node.PeerID().String(), "foo") + assert.Equal(t, 1, res.ExitCode()) + assert.Contains(t, res.Stderr.String(), "this action must be run in online mode") + }) + }) +} diff --git a/test/cli/harness/harness.go b/test/cli/harness/harness.go index de962e1c1..a35fead35 100644 --- a/test/cli/harness/harness.go +++ b/test/cli/harness/harness.go @@ -171,7 +171,7 @@ func (h *Harness) Mkdirs(paths ...string) { } } -func (h *Harness) Sh(expr string) RunResult { +func (h *Harness) Sh(expr string) *RunResult { return h.Runner.Run(RunRequest{ Path: "bash", Args: []string{"-c", expr}, diff --git a/test/cli/harness/node.go b/test/cli/harness/node.go index 0d0295307..181fca99b 100644 --- a/test/cli/harness/node.go +++ b/test/cli/harness/node.go @@ -129,23 +129,23 @@ func (n *Node) UpdateConfigAndUserSuppliedResourceManagerOverrides(f func(cfg *c n.WriteUserSuppliedResourceOverrides(overrides) } -func (n *Node) IPFS(args ...string) RunResult { +func (n *Node) IPFS(args ...string) *RunResult { res := n.RunIPFS(args...) n.Runner.AssertNoError(res) return res } -func (n *Node) PipeStrToIPFS(s string, args ...string) RunResult { +func (n *Node) PipeStrToIPFS(s string, args ...string) *RunResult { return n.PipeToIPFS(strings.NewReader(s), args...) } -func (n *Node) PipeToIPFS(reader io.Reader, args ...string) RunResult { +func (n *Node) PipeToIPFS(reader io.Reader, args ...string) *RunResult { res := n.RunPipeToIPFS(reader, args...) n.Runner.AssertNoError(res) return res } -func (n *Node) RunPipeToIPFS(reader io.Reader, args ...string) RunResult { +func (n *Node) RunPipeToIPFS(reader io.Reader, args ...string) *RunResult { return n.Runner.Run(RunRequest{ Path: n.IPFSBin, Args: args, @@ -153,7 +153,7 @@ func (n *Node) RunPipeToIPFS(reader io.Reader, args ...string) RunResult { }) } -func (n *Node) RunIPFS(args ...string) RunResult { +func (n *Node) RunIPFS(args ...string) *RunResult { return n.Runner.Run(RunRequest{ Path: n.IPFSBin, Args: args, @@ -216,7 +216,7 @@ func (n *Node) StartDaemon(ipfsArgs ...string) *Node { RunFunc: (*exec.Cmd).Start, }) - n.Daemon = &res + n.Daemon = res log.Debugf("node %d started, checking API", n.ID) n.WaitOnAPI() @@ -399,8 +399,6 @@ func (n *Node) SwarmAddrs() []multiaddr.Multiaddr { Path: n.IPFSBin, Args: []string{"swarm", "addrs", "local"}, }) - ipfsProtocol := multiaddr.ProtocolWithCode(multiaddr.P_IPFS).Name - peerID := n.PeerID() out := strings.TrimSpace(res.Stdout.String()) outLines := strings.Split(out, "\n") var addrs []multiaddr.Multiaddr @@ -409,9 +407,18 @@ func (n *Node) SwarmAddrs() []multiaddr.Multiaddr { if err != nil { panic(err) } + addrs = append(addrs, ma) + } + return addrs +} +func (n *Node) SwarmAddrsWithPeerIDs() []multiaddr.Multiaddr { + ipfsProtocol := multiaddr.ProtocolWithCode(multiaddr.P_IPFS).Name + peerID := n.PeerID() + var addrs []multiaddr.Multiaddr + for _, ma := range n.SwarmAddrs() { // add the peer ID to the multiaddr if it doesn't have it - _, err = ma.ValueForProtocol(multiaddr.P_IPFS) + _, err := ma.ValueForProtocol(multiaddr.P_IPFS) if errors.Is(err, multiaddr.ErrProtocolNotFound) { comp, err := multiaddr.NewComponent(ipfsProtocol, peerID.String()) if err != nil { @@ -424,10 +431,27 @@ func (n *Node) SwarmAddrs() []multiaddr.Multiaddr { return addrs } +func (n *Node) SwarmAddrsWithoutPeerIDs() []multiaddr.Multiaddr { + var addrs []multiaddr.Multiaddr + for _, ma := range n.SwarmAddrs() { + var components []multiaddr.Multiaddr + multiaddr.ForEach(ma, func(c multiaddr.Component) bool { + if c.Protocol().Code == multiaddr.P_IPFS { + return true + } + components = append(components, &c) + return true + }) + ma = multiaddr.Join(components...) + addrs = append(addrs, ma) + } + return addrs +} + func (n *Node) Connect(other *Node) *Node { n.Runner.MustRun(RunRequest{ Path: n.IPFSBin, - Args: []string{"swarm", "connect", other.SwarmAddrs()[0].String()}, + Args: []string{"swarm", "connect", other.SwarmAddrsWithPeerIDs()[0].String()}, }) return n } diff --git a/test/cli/harness/nodes.go b/test/cli/harness/nodes.go index dbc7de16b..872d77679 100644 --- a/test/cli/harness/nodes.go +++ b/test/cli/harness/nodes.go @@ -4,6 +4,7 @@ import ( "sync" "github.com/multiformats/go-multiaddr" + "golang.org/x/sync/errgroup" ) // Nodes is a collection of Kubo nodes along with operations on groups of nodes. @@ -16,6 +17,21 @@ func (n Nodes) Init(args ...string) Nodes { return n } +func (n Nodes) ForEachPar(f func(*Node)) { + group := &errgroup.Group{} + for _, node := range n { + node := node + group.Go(func() error { + f(node) + return nil + }) + } + err := group.Wait() + if err != nil { + panic(err) + } +} + func (n Nodes) Connect() Nodes { wg := sync.WaitGroup{} for i, node := range n { diff --git a/test/cli/harness/run.go b/test/cli/harness/run.go index 9cbb871bc..c2a3662be 100644 --- a/test/cli/harness/run.go +++ b/test/cli/harness/run.go @@ -51,7 +51,7 @@ func environToMap(environ []string) map[string]string { return m } -func (r *Runner) Run(req RunRequest) RunResult { +func (r *Runner) Run(req RunRequest) *RunResult { cmd := exec.Command(req.Path, req.Args...) stdout := &Buffer{} stderr := &Buffer{} @@ -86,17 +86,17 @@ func (r *Runner) Run(req RunRequest) RunResult { result.ExitErr = exitErr } - return result + return &result } // MustRun runs the command and fails the test if the command fails. -func (r *Runner) MustRun(req RunRequest) RunResult { +func (r *Runner) MustRun(req RunRequest) *RunResult { result := r.Run(req) r.AssertNoError(result) return result } -func (r *Runner) AssertNoError(result RunResult) { +func (r *Runner) AssertNoError(result *RunResult) { if result.ExitErr != nil { log.Panicf("'%s' returned error, code: %d, err: %s\nstdout:%s\nstderr:%s\n", result.Cmd.Args, result.ExitErr.ExitCode(), result.ExitErr.Error(), result.Stdout.String(), result.Stderr.String()) diff --git a/test/sharness/t0170-legacy-dht.sh b/test/sharness/t0170-legacy-dht.sh deleted file mode 100755 index fc11b9044..000000000 --- a/test/sharness/t0170-legacy-dht.sh +++ /dev/null @@ -1,121 +0,0 @@ -#!/usr/bin/env bash - -# Legacy / deprecated, see: t0170-routing-dht.sh -test_description="Test dht command" - -. lib/test-lib.sh - -test_dht() { - NUM_NODES=5 - - test_expect_success 'init iptb' ' - rm -rf .iptb/ && - iptb testbed create -type localipfs -count $NUM_NODES -init - ' - - test_expect_success 'DHT-only routing' ' - iptb run -- ipfs config Routing.Type dht - ' - - startup_cluster $NUM_NODES $@ - - test_expect_success 'peer ids' ' - PEERID_0=$(iptb attr get 0 id) && - PEERID_2=$(iptb attr get 2 id) - ' - - # ipfs dht findpeer - test_expect_success 'findpeer' ' - ipfsi 1 dht findpeer $PEERID_0 | sort >actual && - ipfsi 0 id -f "" | cut -d / -f 1-5 | sort >expected && - test_cmp actual expected - ' - - # ipfs dht get - test_expect_success 'get with good keys works' ' - HASH="$(echo "hello world" | ipfsi 2 add -q)" && - ipfsi 2 name publish "/ipfs/$HASH" && - ipfsi 1 dht get "/ipns/$PEERID_2" >get_result - ' - - test_expect_success 'get with good keys contains the right value' ' - cat get_result | grep -aq "/ipfs/$HASH" - ' - - test_expect_success 'put round trips (#3124)' ' - ipfsi 0 dht put "/ipns/$PEERID_2" get_result | sort >putted && - [ -s putted ] || - test_fsh cat putted - ' - - test_expect_success 'put with bad keys fails (issue #5113)' ' - ipfsi 0 dht put "foo" <<putted - ipfsi 0 dht put "/pk/foo" <<>putted - ipfsi 0 dht put "/ipns/foo" <<>putted - [ ! -s putted ] || - test_fsh cat putted - ' - - test_expect_success 'put with bad keys returns error (issue #4611)' ' - test_must_fail ipfsi 0 dht put "foo" << afile && - HASH=$(ipfsi 3 add -q afile) - ' - - # ipfs dht findprovs - test_expect_success 'findprovs' ' - ipfsi 4 dht findprovs $HASH > provs && - iptb attr get 3 id > expected && - test_cmp provs expected - ' - - - # ipfs dht query - # - # We test all nodes. 4 nodes should see the same peer ID, one node (the - # closest) should see a different one. - - for i in $(test_seq 0 4); do - test_expect_success "query from $i" ' - ipfsi "$i" dht query "$HASH" | head -1 >closest-$i - ' - done - - test_expect_success "collecting results" ' - cat closest-* | sort | uniq -c | sed -e "s/ *\([0-9]\+\) .*/\1/g" | sort -g > actual && - echo 1 > expected && - echo 4 >> expected - ' - - test_expect_success "checking results" ' - test_cmp actual expected - ' - - test_expect_success 'stop iptb' ' - iptb stop - ' - - test_expect_success "dht commands fail when offline" ' - test_must_fail ipfsi 0 dht findprovs "$HASH" 2>err_findprovs && - test_must_fail ipfsi 0 dht findpeer "$HASH" 2>err_findpeer && - test_must_fail ipfsi 0 dht put "/ipns/$PEERID_2" "get_result" 2>err_put && - test_should_contain "this command must be run in online mode" err_findprovs && - test_should_contain "this command must be run in online mode" err_findpeer && - test_should_contain "this action must be run in online mode" err_put - ' -} - -test_dht -test_dht --enable-pubsub-experiment --enable-namesys-pubsub - -test_done From fdbe363eb167a3a6e4800cd277dc7e8414bca86a Mon Sep 17 00:00:00 2001 From: Gus Eggert Date: Wed, 8 Mar 2023 16:25:45 -0500 Subject: [PATCH 0524/1212] test: parallelize more of rcmgr Go tests --- test/cli/harness/node.go | 8 ---- test/cli/rcmgr_test.go | 86 ++++++++++++++++++++++++---------------- 2 files changed, 52 insertions(+), 42 deletions(-) diff --git a/test/cli/harness/node.go b/test/cli/harness/node.go index 181fca99b..cc251e11b 100644 --- a/test/cli/harness/node.go +++ b/test/cli/harness/node.go @@ -121,14 +121,6 @@ func (n *Node) UpdateUserSuppliedResourceManagerOverrides(f func(overrides *rcmg n.WriteUserSuppliedResourceOverrides(overrides) } -func (n *Node) UpdateConfigAndUserSuppliedResourceManagerOverrides(f func(cfg *config.Config, overrides *rcmgr.PartialLimitConfig)) { - overrides := n.ReadUserResourceOverrides() - cfg := n.ReadConfig() - f(cfg, overrides) - n.WriteConfig(cfg) - n.WriteUserSuppliedResourceOverrides(overrides) -} - func (n *Node) IPFS(args ...string) *RunResult { res := n.RunIPFS(args...) n.Runner.AssertNoError(res) diff --git a/test/cli/rcmgr_test.go b/test/cli/rcmgr_test.go index fb644e1a7..51b2b0452 100644 --- a/test/cli/rcmgr_test.go +++ b/test/cli/rcmgr_test.go @@ -49,6 +49,7 @@ func TestRcmgr(t *testing.T) { }) t.Run("Very high connmgr highwater", func(t *testing.T) { + t.Parallel() node := harness.NewT(t).NewNode().Init() node.UpdateConfig(func(cfg *config.Config) { cfg.Swarm.ConnMgr.HighWater = config.NewOptionalInteger(1000) @@ -74,6 +75,7 @@ func TestRcmgr(t *testing.T) { node.StartDaemon() t.Run("conns and streams are above 800 for default connmgr settings", func(t *testing.T) { + t.Parallel() res := node.RunIPFS("swarm", "resources", "--enc=json") require.Equal(t, 0, res.ExitCode()) limits := unmarshalLimits(t, res.Stdout.Bytes()) @@ -87,6 +89,7 @@ func TestRcmgr(t *testing.T) { }) t.Run("limits should succeed", func(t *testing.T) { + t.Parallel() res := node.RunIPFS("swarm", "resources", "--enc=json") assert.Equal(t, 0, res.ExitCode()) @@ -106,6 +109,7 @@ func TestRcmgr(t *testing.T) { }) t.Run("swarm stats works", func(t *testing.T) { + t.Parallel() res := node.RunIPFS("swarm", "resources", "--enc=json") require.Equal(t, 0, res.ExitCode()) @@ -123,6 +127,7 @@ func TestRcmgr(t *testing.T) { }) t.Run("smoke test transient scope", func(t *testing.T) { + t.Parallel() node := harness.NewT(t).NewNode().Init() node.UpdateUserSuppliedResourceManagerOverrides(func(overrides *rcmgr.PartialLimitConfig) { overrides.Transient.Memory = 88888 @@ -135,6 +140,7 @@ func TestRcmgr(t *testing.T) { }) t.Run("smoke test service scope", func(t *testing.T) { + t.Parallel() node := harness.NewT(t).NewNode().Init() node.UpdateUserSuppliedResourceManagerOverrides(func(overrides *rcmgr.PartialLimitConfig) { overrides.Service = map[string]rcmgr.ResourceLimits{"foo": {Memory: 77777}} @@ -147,6 +153,7 @@ func TestRcmgr(t *testing.T) { }) t.Run("smoke test protocol scope", func(t *testing.T) { + t.Parallel() node := harness.NewT(t).NewNode().Init() node.UpdateUserSuppliedResourceManagerOverrides(func(overrides *rcmgr.PartialLimitConfig) { overrides.Protocol = map[protocol.ID]rcmgr.ResourceLimits{"foo": {Memory: 66666}} @@ -159,6 +166,7 @@ func TestRcmgr(t *testing.T) { }) t.Run("smoke test peer scope", func(t *testing.T) { + t.Parallel() validPeerID, err := peer.Decode("QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN") assert.NoError(t, err) node := harness.NewT(t).NewNode().Init() @@ -172,13 +180,17 @@ func TestRcmgr(t *testing.T) { assert.Equal(t, rcmgr.LimitVal64(55555), limits.Peers[validPeerID].Memory) }) - t.Run("", func(t *testing.T) { + t.Run("blocking and allowlists", func(t *testing.T) { + t.Parallel() nodes := harness.NewT(t).NewNodes(3).Init() node0, node1, node2 := nodes[0], nodes[1], nodes[2] - // peerID0, peerID1, peerID2 := node0.PeerID(), node1.PeerID(), node2.PeerID() peerID1, peerID2 := node1.PeerID().String(), node2.PeerID().String() - node0.UpdateConfigAndUserSuppliedResourceManagerOverrides(func(cfg *config.Config, overrides *rcmgr.PartialLimitConfig) { + node0.UpdateConfig(func(cfg *config.Config) { + cfg.Swarm.ResourceMgr.Enabled = config.True + cfg.Swarm.ResourceMgr.Allowlist = []string{"/ip4/0.0.0.0/ipcidr/0/p2p/" + peerID2} + }) + node0.UpdateUserSuppliedResourceManagerOverrides(func(overrides *rcmgr.PartialLimitConfig) { *overrides = rcmgr.PartialLimitConfig{ System: rcmgr.ResourceLimits{ Conns: rcmgr.BlockAllLimit, @@ -186,91 +198,97 @@ func TestRcmgr(t *testing.T) { ConnsOutbound: rcmgr.BlockAllLimit, }, } - cfg.Swarm.ResourceMgr.Enabled = config.True - cfg.Swarm.ResourceMgr.Allowlist = []string{"/ip4/0.0.0.0/ipcidr/0/p2p/" + peerID2} }) nodes.StartDaemons() - t.Parallel() - t.Run("node 0 should fail to connect to node 1", func(t *testing.T) { + t.Run("node 0 should fail to connect to and ping node 1", func(t *testing.T) { + t.Parallel() res := node0.Runner.Run(harness.RunRequest{ Path: node0.IPFSBin, - Args: []string{"swarm", "connect", node1.SwarmAddrs()[0].String()}, + Args: []string{"swarm", "connect", node1.SwarmAddrsWithPeerIDs()[0].String()}, }) assert.Equal(t, 1, res.ExitCode()) assert.Contains(t, res.Stderr.String(), "failed to find any peer in table") - }) - t.Run("node 0 should connect to node 2 since it is allowlisted", func(t *testing.T) { - res := node0.Runner.Run(harness.RunRequest{ - Path: node0.IPFSBin, - Args: []string{"swarm", "connect", node2.SwarmAddrs()[0].String()}, - }) - assert.Equal(t, 0, res.ExitCode()) - }) - - t.Run("node 0 should fail to ping node 1", func(t *testing.T) { - res := node0.RunIPFS("ping", "-n2", peerID1) + res = node0.RunIPFS("ping", "-n2", peerID1) assert.Equal(t, 1, res.ExitCode()) assert.Contains(t, res.Stderr.String(), "Error: ping failed") }) - t.Run("node 0 should be able to ping node 2", func(t *testing.T) { - res := node0.RunIPFS("ping", "-n2", peerID2) + t.Run("node 0 should connect to and ping node 2 since it is allowlisted", func(t *testing.T) { + t.Parallel() + res := node0.Runner.Run(harness.RunRequest{ + Path: node0.IPFSBin, + Args: []string{"swarm", "connect", node2.SwarmAddrsWithPeerIDs()[0].String()}, + }) + assert.Equal(t, 0, res.ExitCode()) + + res = node0.RunIPFS("ping", "-n2", peerID2) assert.Equal(t, 0, res.ExitCode()) }) }) t.Run("daemon should refuse to start if connmgr.highwater < resources inbound", func(t *testing.T) { - t.Parallel() t.Run("system conns", func(t *testing.T) { + t.Parallel() node := harness.NewT(t).NewNode().Init() - node.UpdateConfigAndUserSuppliedResourceManagerOverrides(func(cfg *config.Config, overrides *rcmgr.PartialLimitConfig) { + node.UpdateConfig(func(cfg *config.Config) { + cfg.Swarm.ConnMgr.HighWater = config.NewOptionalInteger(128) + cfg.Swarm.ConnMgr.LowWater = config.NewOptionalInteger(64) + }) + node.UpdateUserSuppliedResourceManagerOverrides(func(overrides *rcmgr.PartialLimitConfig) { *overrides = rcmgr.PartialLimitConfig{ System: rcmgr.ResourceLimits{Conns: 128}, } - cfg.Swarm.ConnMgr.HighWater = config.NewOptionalInteger(128) - cfg.Swarm.ConnMgr.LowWater = config.NewOptionalInteger(64) }) res := node.RunIPFS("daemon") assert.Equal(t, 1, res.ExitCode()) }) t.Run("system conns inbound", func(t *testing.T) { + t.Parallel() node := harness.NewT(t).NewNode().Init() - node.UpdateConfigAndUserSuppliedResourceManagerOverrides(func(cfg *config.Config, overrides *rcmgr.PartialLimitConfig) { + node.UpdateConfig(func(cfg *config.Config) { + cfg.Swarm.ConnMgr.HighWater = config.NewOptionalInteger(128) + cfg.Swarm.ConnMgr.LowWater = config.NewOptionalInteger(64) + }) + node.UpdateUserSuppliedResourceManagerOverrides(func(overrides *rcmgr.PartialLimitConfig) { *overrides = rcmgr.PartialLimitConfig{ System: rcmgr.ResourceLimits{ConnsInbound: 128}, } - cfg.Swarm.ConnMgr.HighWater = config.NewOptionalInteger(128) - cfg.Swarm.ConnMgr.LowWater = config.NewOptionalInteger(64) }) res := node.RunIPFS("daemon") assert.Equal(t, 1, res.ExitCode()) }) t.Run("system streams", func(t *testing.T) { + t.Parallel() node := harness.NewT(t).NewNode().Init() - node.UpdateConfigAndUserSuppliedResourceManagerOverrides(func(cfg *config.Config, overrides *rcmgr.PartialLimitConfig) { + node.UpdateConfig(func(cfg *config.Config) { + cfg.Swarm.ConnMgr.HighWater = config.NewOptionalInteger(128) + cfg.Swarm.ConnMgr.LowWater = config.NewOptionalInteger(64) + }) + node.UpdateUserSuppliedResourceManagerOverrides(func(overrides *rcmgr.PartialLimitConfig) { *overrides = rcmgr.PartialLimitConfig{ System: rcmgr.ResourceLimits{Streams: 128}, } - cfg.Swarm.ConnMgr.HighWater = config.NewOptionalInteger(128) - cfg.Swarm.ConnMgr.LowWater = config.NewOptionalInteger(64) }) res := node.RunIPFS("daemon") assert.Equal(t, 1, res.ExitCode()) }) t.Run("system streams inbound", func(t *testing.T) { + t.Parallel() node := harness.NewT(t).NewNode().Init() - node.UpdateConfigAndUserSuppliedResourceManagerOverrides(func(cfg *config.Config, overrides *rcmgr.PartialLimitConfig) { + node.UpdateConfig(func(cfg *config.Config) { + cfg.Swarm.ConnMgr.HighWater = config.NewOptionalInteger(128) + cfg.Swarm.ConnMgr.LowWater = config.NewOptionalInteger(64) + }) + node.UpdateUserSuppliedResourceManagerOverrides(func(overrides *rcmgr.PartialLimitConfig) { *overrides = rcmgr.PartialLimitConfig{ System: rcmgr.ResourceLimits{StreamsInbound: 128}, } - cfg.Swarm.ConnMgr.HighWater = config.NewOptionalInteger(128) - cfg.Swarm.ConnMgr.LowWater = config.NewOptionalInteger(64) }) res := node.RunIPFS("daemon") From 0d94bac30c2060de3ffaab00954df20be3723e4b Mon Sep 17 00:00:00 2001 From: Gus Eggert Date: Wed, 8 Mar 2023 16:26:47 -0500 Subject: [PATCH 0525/1212] feat: add "autoclient" routing type This routing type is the same as "auto" but it creates the DHT in "client" mode and hence does not start a DHT server. --- cmd/ipfs/daemon.go | 61 ++++++++++++++----------- config/routing.go | 2 +- core/node/libp2p/routingopt.go | 5 +- docs/changelogs/v0.19.md | 6 +++ docs/config.md | 6 ++- test/cli/delegated_routing_http_test.go | 2 +- test/cli/dht_autoclient_test.go | 39 ++++++++++++++++ 7 files changed, 88 insertions(+), 33 deletions(-) create mode 100644 test/cli/dht_autoclient_test.go diff --git a/cmd/ipfs/daemon.go b/cmd/ipfs/daemon.go index 21495c498..880d26b0e 100644 --- a/cmd/ipfs/daemon.go +++ b/cmd/ipfs/daemon.go @@ -45,32 +45,33 @@ import ( ) const ( - adjustFDLimitKwd = "manage-fdlimit" - enableGCKwd = "enable-gc" - initOptionKwd = "init" - initConfigOptionKwd = "init-config" - initProfileOptionKwd = "init-profile" - ipfsMountKwd = "mount-ipfs" - ipnsMountKwd = "mount-ipns" - migrateKwd = "migrate" - mountKwd = "mount" - offlineKwd = "offline" // global option - routingOptionKwd = "routing" - routingOptionSupernodeKwd = "supernode" - routingOptionDHTClientKwd = "dhtclient" - routingOptionDHTKwd = "dht" - routingOptionDHTServerKwd = "dhtserver" - routingOptionNoneKwd = "none" - routingOptionCustomKwd = "custom" - routingOptionDefaultKwd = "default" - routingOptionAutoKwd = "auto" - unencryptTransportKwd = "disable-transport-encryption" - unrestrictedAPIAccessKwd = "unrestricted-api" - writableKwd = "writable" - enablePubSubKwd = "enable-pubsub-experiment" - enableIPNSPubSubKwd = "enable-namesys-pubsub" - enableMultiplexKwd = "enable-mplex-experiment" - agentVersionSuffix = "agent-version-suffix" + adjustFDLimitKwd = "manage-fdlimit" + enableGCKwd = "enable-gc" + initOptionKwd = "init" + initConfigOptionKwd = "init-config" + initProfileOptionKwd = "init-profile" + ipfsMountKwd = "mount-ipfs" + ipnsMountKwd = "mount-ipns" + migrateKwd = "migrate" + mountKwd = "mount" + offlineKwd = "offline" // global option + routingOptionKwd = "routing" + routingOptionSupernodeKwd = "supernode" + routingOptionDHTClientKwd = "dhtclient" + routingOptionDHTKwd = "dht" + routingOptionDHTServerKwd = "dhtserver" + routingOptionNoneKwd = "none" + routingOptionCustomKwd = "custom" + routingOptionDefaultKwd = "default" + routingOptionAutoKwd = "auto" + routingOptionAutoClientKwd = "autoclient" + unencryptTransportKwd = "disable-transport-encryption" + unrestrictedAPIAccessKwd = "unrestricted-api" + writableKwd = "writable" + enablePubSubKwd = "enable-pubsub-experiment" + enableIPNSPubSubKwd = "enable-namesys-pubsub" + enableMultiplexKwd = "enable-mplex-experiment" + agentVersionSuffix = "agent-version-suffix" // apiAddrKwd = "address-api" // swarmAddrKwd = "address-swarm" ) @@ -416,6 +417,14 @@ func daemonFunc(req *cmds.Request, re cmds.ResponseEmitter, env cmds.Environment cfg.Identity.PeerID, cfg.Addresses.Swarm, cfg.Identity.PrivKey, + libp2p.DHTOption, + ) + case routingOptionAutoClientKwd: + ncfg.Routing = libp2p.ConstructDefaultRouting( + cfg.Identity.PeerID, + cfg.Addresses.Swarm, + cfg.Identity.PrivKey, + libp2p.DHTClientOption, ) case routingOptionDHTClientKwd: ncfg.Routing = libp2p.DHTClientOption diff --git a/config/routing.go b/config/routing.go index f19414ff3..1210bb3ce 100644 --- a/config/routing.go +++ b/config/routing.go @@ -10,7 +10,7 @@ import ( type Routing struct { // Type sets default daemon routing mode. // - // Can be one of "auto", "dht", "dhtclient", "dhtserver", "none", or "custom". + // Can be one of "auto", "autoclient", "dht", "dhtclient", "dhtserver", "none", or "custom". // When unset or set to "auto", DHT and implicit routers are used. // When "custom" is set, user-provided Routing.Routers is used. Type *OptionalString `json:",omitempty"` diff --git a/core/node/libp2p/routingopt.go b/core/node/libp2p/routingopt.go index bfb45971c..d54f37acc 100644 --- a/core/node/libp2p/routingopt.go +++ b/core/node/libp2p/routingopt.go @@ -40,7 +40,7 @@ func init() { } // ConstructDefaultRouting returns routers used when Routing.Type is unset or set to "auto" -func ConstructDefaultRouting(peerID string, addrs []string, privKey string) func( +func ConstructDefaultRouting(peerID string, addrs []string, privKey string, routingOpt RoutingOption) func( ctx context.Context, host host.Host, dstore datastore.Batching, @@ -58,8 +58,7 @@ func ConstructDefaultRouting(peerID string, addrs []string, privKey string) func // Different trade-offs can be made by setting Routing.Type = "custom" with own Routing.Routers var routers []*routinghelpers.ParallelRouter - // Run the default DHT routing (same as Routing.Type = "dht") - dhtRouting, err := DHTOption(ctx, host, dstore, validator, bootstrapPeers...) + dhtRouting, err := routingOpt(ctx, host, dstore, validator, bootstrapPeers...) if err != nil { return nil, err } diff --git a/docs/changelogs/v0.19.md b/docs/changelogs/v0.19.md index 7663308a6..fede7a454 100644 --- a/docs/changelogs/v0.19.md +++ b/docs/changelogs/v0.19.md @@ -7,6 +7,7 @@ - [Overview](#overview) - [🔦 Highlights](#-highlights) - [Improving the libp2p resource management integration](#improving-the-libp2p-resource-management-integration) + - [Addition of "autoclient" router type](#addition-of-autoclient-router-type) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -22,6 +23,11 @@ and [0.18.1](https://github.com/ipfs/kubo/blob/master/docs/changelogs/v0.18.md#i - Note: we don't expect most users to need these capablities, but they are there if so. 1. [Doc updates](https://github.com/ipfs/kubo/blob/master/docs/libp2p-resource-management.md). +#### Addition of "autoclient" router type +A new routing type "autoclient" has been added. This mode is similar to "auto", in that it is a hybrid of content routers (including Kademlia and HTTP routers), but it does not run a DHT server. This is similar to the difference between "dhtclient" and "dht" router types. + +See the [Routing.Type documentation](https://github.com/ipfs/kubo/blob/master/docs/config.md#routingtype) for more information. + ### 📝 Changelog ### 👨‍👩‍👧‍👦 Contributors diff --git a/docs/config.md b/docs/config.md index adf956ce0..686661918 100644 --- a/docs/config.md +++ b/docs/config.md @@ -1349,11 +1349,13 @@ Contains options for content, peer, and IPNS routing mechanisms. ### `Routing.Type` -There are multiple routing options: "auto", "none", "dht" and "custom". +There are multiple routing options: "auto", "autoclient", "none", "dht", "dhtclient", and "custom". * **DEFAULT:** If unset, or set to "auto", your node will use the IPFS DHT and parallel HTTP routers listed below for additional speed. +* If set to "autoclient", your node will behave as in "auto" but without running a DHT server. + * If set to "none", your node will use _no_ routing system. You'll have to explicitly connect to peers that have the content you're looking for. @@ -1379,7 +1381,7 @@ To force a specific DHT-only mode, client or server, set `Routing.Type` to `dhtclient` or `dhtserver` respectively. Please do not set this to `dhtserver` unless you're sure your node is reachable from the public network. -When `Routing.Type` is set to `auto` your node will accelerate some types of routing +When `Routing.Type` is set to `auto` or `autoclient` your node will accelerate some types of routing by leveraging HTTP endpoints compatible with [IPIP-337](https://github.com/ipfs/specs/pull/337) in addition to the IPFS DHT. By default, an instance of [IPNI](https://github.com/ipni/specs/blob/main/IPNI.md#readme) diff --git a/test/cli/delegated_routing_http_test.go b/test/cli/delegated_routing_http_test.go index 0b39a9b12..446ea5150 100644 --- a/test/cli/delegated_routing_http_test.go +++ b/test/cli/delegated_routing_http_test.go @@ -94,7 +94,7 @@ func TestHTTPDelegatedRouting(t *testing.T) { })) t.Cleanup(server.Close) - node.IPFS("config", "Routing.Type", "--json", `"custom"`) + node.IPFS("config", "Routing.Type", "custom") node.IPFS("config", "Routing.Routers.TestDelegatedRouter", "--json", ToJSONStr(JSONObj{ "Type": "http", "Parameters": JSONObj{ diff --git a/test/cli/dht_autoclient_test.go b/test/cli/dht_autoclient_test.go new file mode 100644 index 000000000..749e34b34 --- /dev/null +++ b/test/cli/dht_autoclient_test.go @@ -0,0 +1,39 @@ +package cli + +import ( + "bytes" + "testing" + + "github.com/ipfs/kubo/test/cli/harness" + "github.com/ipfs/kubo/test/cli/testutils" + "github.com/stretchr/testify/assert" +) + +func TestDHTAutoclient(t *testing.T) { + t.Parallel() + nodes := harness.NewT(t).NewNodes(10).Init() + harness.Nodes(nodes[8:]).ForEachPar(func(node *harness.Node) { + node.IPFS("config", "Routing.Type", "autoclient") + }) + nodes.StartDaemons().Connect() + + t.Run("file added on node in client mode is retrievable from node in client mode", func(t *testing.T) { + t.Parallel() + randomBytes := testutils.RandomBytes(1000) + hash := nodes[8].IPFSAdd(bytes.NewReader(randomBytes)) + + res := nodes[9].IPFS("cat", hash) + assert.Equal(t, randomBytes, []byte(res.Stdout.Trimmed())) + }) + + t.Run("file added on node in server mode is retrievable from all nodes", func(t *testing.T) { + t.Parallel() + randomBytes := testutils.RandomBytes(1000) + hash := nodes[0].IPFSAdd(bytes.NewReader(randomBytes)) + + for i := 0; i < 10; i++ { + res := nodes[i].IPFS("cat", hash) + assert.Equal(t, randomBytes, []byte(res.Stdout.Trimmed())) + } + }) +} From a4052c645bce995cd88c93fc4fa1dbcf12c3f84c Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Fri, 10 Mar 2023 15:30:18 +0100 Subject: [PATCH 0526/1212] chore: fix toc in changelog for 0.18 --- docs/changelogs/v0.18.md | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/docs/changelogs/v0.18.md b/docs/changelogs/v0.18.md index 5b3b15439..f2a22d84e 100644 --- a/docs/changelogs/v0.18.md +++ b/docs/changelogs/v0.18.md @@ -88,22 +88,22 @@ Below is an outline of all that is in this release, so you get a sense of all th - - [Overview](#overview) - - [🔦 Highlights](#-highlights) - - [Content routing](#content-routing) - - [Default InterPlanetary Network Indexer](#default-interplanetary-network-indexer) - - [Increase provider record republish interval and expiration](#increase-provider-record-republish-interval-and-expiration) - - [Gateways](#gateways) - - [(DAG-)JSON and (DAG-)CBOR response formats](#dag-json-and-dag-cbor-response-formats) - - [🐎 Fast directory listings with DAG sizes](#-fast-directory-listings-with-dag-sizes) - - [QUIC and WebTransport](#quic-and-webtransport) - - [WebTransport enabled by default](#webtransport-enabled-by-default) - - [QUIC and WebTransport share a single port](#quic-and-webtransport-share-a-single-port) - - [Differentiating QUIC versions](#differentiating-quic-versions) - - [QUICv1 and WebTransport config migration](#quicv1-and-webtransport-config-migration) - - [Improving libp2p resource management integration](#improving-libp2p-resource-management-integration) - - [📝 Changelog](#-changelog) - - [👨‍👩‍👧‍👦 Contributors](#-contributors) +- [Overview](#overview) +- [🔦 Highlights](#-highlights) + - [Content routing](#content-routing) + - [Default InterPlanetary Network Indexer](#default-interplanetary-network-indexer) + - [Increase provider record republish interval and expiration](#increase-provider-record-republish-interval-and-expiration) + - [Gateways](#gateways) + - [(DAG-)JSON and (DAG-)CBOR response formats](#dag-json-and-dag-cbor-response-formats) + - [🐎 Fast directory listings with DAG sizes](#-fast-directory-listings-with-dag-sizes) + - [QUIC and WebTransport](#quic-and-webtransport) + - [WebTransport enabled by default](#webtransport-enabled-by-default) + - [QUIC and WebTransport share a single port](#quic-and-webtransport-share-a-single-port) + - [Differentiating QUIC versions](#differentiating-quic-versions) + - [QUICv1 and WebTransport config migration](#quicv1-and-webtransport-config-migration) + - [Improving libp2p resource management integration](#improving-libp2p-resource-management-integration) +- [📝 Changelog](#-changelog) +- [👨‍👩‍👧‍👦 Contributors](#-contributors) From fc81639af441cb78b28ca78c6886ba0dd8c5db04 Mon Sep 17 00:00:00 2001 From: Laurent Senta Date: Thu, 9 Mar 2023 15:21:50 +0100 Subject: [PATCH 0527/1212] test: name --verify forgets the verified key --- test/sharness/t0100-name.sh | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/test/sharness/t0100-name.sh b/test/sharness/t0100-name.sh index 44c2afb2d..34f33ea4d 100755 --- a/test/sharness/t0100-name.sh +++ b/test/sharness/t0100-name.sh @@ -314,4 +314,32 @@ test_name_with_key 'rsa' test_name_with_key 'ed25519_b58' test_name_with_key 'ed25519_b36' + +# `ipfs name inspect --verify` using the wrong RSA key should not succeed + +test_init_ipfs +test_launch_ipfs_daemon + +test_expect_success "prepare RSA keys" ' + export KEY_1=`ipfs key gen --type=rsa --size=4096 key1` && + export KEY_2=`ipfs key gen --type=rsa --size=4096 key2` && + export PEERID_1=`ipfs key list --ipns-base=base36 -l | grep key1 | cut -d " " -f1` && + export PEERID_2=`ipfs key list --ipns-base=base36 -l | grep key2 | cut -d " " -f1` +' + +test_expect_success "ipfs name publish --allow-offline --key= ' succeeds" ' + ipfs name publish --allow-offline --key=${KEY_1} "/ipfs/$( echo "helloworld" | ipfs add --inline -q )" && + ipfs routing get "/ipns/$PEERID_1" > ipns_record +' + +test_expect_success "ipfs name inspect --verify' has '.Validation.Validity' set to 'true' with correct Peer ID" ' + ipfs name inspect --verify $PEERID_1 --enc json < ipns_record | jq -e ".Validation.Valid == true" +' + +test_expect_success "ipfs name inspect --verify' has '.Validation.Validity' set to 'false' when we verify the wrong Peer ID" ' + ipfs name inspect --verify $PEERID_2 --enc json < ipns_record | jq -e ".Validation.Valid == false" +' + +test_kill_ipfs_daemon + test_done From 877d091d7530e6ffea33c55c956077e06bc89557 Mon Sep 17 00:00:00 2001 From: Laurent Senta Date: Thu, 9 Mar 2023 15:23:52 +0100 Subject: [PATCH 0528/1212] fix: --verify forgets the verified key --- core/commands/name/name.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/core/commands/name/name.go b/core/commands/name/name.go index 7999aee3d..0e4fa6cb5 100644 --- a/core/commands/name/name.go +++ b/core/commands/name/name.go @@ -222,6 +222,20 @@ Passing --verify will verify signature against provided public key. // Peer ID. if len(entry.PubKey) > 0 { pub, err = ic.UnmarshalPublicKey(entry.PubKey) + if err != nil { + return err + } + + // Verify the public key matches the name we are verifying. + entryID, err := peer.IDFromPublicKey(pub) + + if err != nil { + return err + } + + if id != entryID { + return fmt.Errorf("record public key does not match the verified name") + } } } if err != nil { From 7f7a5ab1b9c3229b3ab52429a7581a9ed196f44e Mon Sep 17 00:00:00 2001 From: Eng Zer Jun Date: Wed, 10 Aug 2022 22:04:19 +0800 Subject: [PATCH 0529/1212] test: use `T.TempDir` to create temporary test directory This commit replaces `os.MkdirTemp` with `t.TempDir` in tests. The directory created by `t.TempDir` is automatically removed when the test and all its subtests complete. Prior to this commit, temporary directory created using `os.MkdirTemp` needs to be removed manually by calling `os.RemoveAll`, which is omitted in some tests. The error handling boilerplate e.g. defer func() { if err := os.RemoveAll(dir); err != nil { t.Fatal(err) } } is also tedious, but `t.TempDir` handles this for us nicely. Reference: https://pkg.go.dev/testing#T.TempDir Signed-off-by: Eng Zer Jun --- fuse/node/mount_test.go | 10 +++------- repo/fsrepo/config_test.go | 25 ++++--------------------- repo/fsrepo/fsrepo_test.go | 21 ++++++--------------- test/bench/bench_cli_ipfs_add/main.go | 7 +------ test/bench/offline_add/main.go | 6 +----- 5 files changed, 15 insertions(+), 54 deletions(-) diff --git a/fuse/node/mount_test.go b/fuse/node/mount_test.go index 12313ae3e..1691cfa5b 100644 --- a/fuse/node/mount_test.go +++ b/fuse/node/mount_test.go @@ -4,6 +4,7 @@ package node import ( + "context" "os" "strings" "testing" @@ -11,8 +12,6 @@ import ( "bazil.org/fuse" - "context" - core "github.com/ipfs/kubo/core" ipns "github.com/ipfs/kubo/fuse/ipns" mount "github.com/ipfs/kubo/fuse/mount" @@ -52,11 +51,8 @@ func TestExternalUnmount(t *testing.T) { t.Fatal(err) } - // get the test dir paths (/tmp/fusetestXXXX) - dir, err := os.MkdirTemp("", "fusetest") - if err != nil { - t.Fatal(err) - } + // get the test dir paths (/tmp/TestExternalUnmount) + dir := t.TempDir() ipfsDir := dir + "/ipfs" ipnsDir := dir + "/ipns" diff --git a/repo/fsrepo/config_test.go b/repo/fsrepo/config_test.go index 03af75a96..060d0222a 100644 --- a/repo/fsrepo/config_test.go +++ b/repo/fsrepo/config_test.go @@ -2,7 +2,6 @@ package fsrepo_test import ( "encoding/json" - "os" "reflect" "testing" @@ -88,11 +87,7 @@ func TestDefaultDatastoreConfig(t *testing.T) { t.Fatal(err) } - dir, err := os.MkdirTemp("", "ipfs-datastore-config-test") - if err != nil { - t.Fatal(err) - } - defer os.RemoveAll(dir) // clean up + dir := t.TempDir() config := new(config.Datastore) err = json.Unmarshal(defaultConfig, config) @@ -126,11 +121,7 @@ func TestLevelDbConfig(t *testing.T) { if err != nil { t.Fatal(err) } - dir, err := os.MkdirTemp("", "ipfs-datastore-config-test") - if err != nil { - t.Fatal(err) - } - defer os.RemoveAll(dir) // clean up + dir := t.TempDir() spec := make(map[string]interface{}) err = json.Unmarshal(leveldbConfig, &spec) @@ -164,11 +155,7 @@ func TestFlatfsConfig(t *testing.T) { if err != nil { t.Fatal(err) } - dir, err := os.MkdirTemp("", "ipfs-datastore-config-test") - if err != nil { - t.Fatal(err) - } - defer os.RemoveAll(dir) // clean up + dir := t.TempDir() spec := make(map[string]interface{}) err = json.Unmarshal(flatfsConfig, &spec) @@ -202,11 +189,7 @@ func TestMeasureConfig(t *testing.T) { if err != nil { t.Fatal(err) } - dir, err := os.MkdirTemp("", "ipfs-datastore-config-test") - if err != nil { - t.Fatal(err) - } - defer os.RemoveAll(dir) // clean up + dir := t.TempDir() spec := make(map[string]interface{}) err = json.Unmarshal(measureConfig, &spec) diff --git a/repo/fsrepo/fsrepo_test.go b/repo/fsrepo/fsrepo_test.go index 7c7551d20..6b30b107a 100644 --- a/repo/fsrepo/fsrepo_test.go +++ b/repo/fsrepo/fsrepo_test.go @@ -13,18 +13,9 @@ import ( config "github.com/ipfs/kubo/config" ) -// swap arg order -func testRepoPath(p string, t *testing.T) string { - name, err := os.MkdirTemp("", p) - if err != nil { - t.Fatal(err) - } - return name -} - func TestInitIdempotence(t *testing.T) { t.Parallel() - path := testRepoPath("", t) + path := t.TempDir() for i := 0; i < 10; i++ { assert.Nil(Init(path, &config.Config{Datastore: config.DefaultDatastoreConfig()}), t, "multiple calls to init should succeed") } @@ -37,8 +28,8 @@ func Remove(repoPath string) error { func TestCanManageReposIndependently(t *testing.T) { t.Parallel() - pathA := testRepoPath("a", t) - pathB := testRepoPath("b", t) + pathA := t.TempDir() + pathB := t.TempDir() t.Log("initialize two repos") assert.Nil(Init(pathA, &config.Config{Datastore: config.DefaultDatastoreConfig()}), t, "a", "should initialize successfully") @@ -65,7 +56,7 @@ func TestCanManageReposIndependently(t *testing.T) { func TestDatastoreGetNotAllowedAfterClose(t *testing.T) { t.Parallel() - path := testRepoPath("test", t) + path := t.TempDir() assert.True(!IsInitialized(path), t, "should NOT be initialized") assert.Nil(Init(path, &config.Config{Datastore: config.DefaultDatastoreConfig()}), t, "should initialize successfully") @@ -83,7 +74,7 @@ func TestDatastoreGetNotAllowedAfterClose(t *testing.T) { func TestDatastorePersistsFromRepoToRepo(t *testing.T) { t.Parallel() - path := testRepoPath("test", t) + path := t.TempDir() assert.Nil(Init(path, &config.Config{Datastore: config.DefaultDatastoreConfig()}), t) r1, err := Open(path) @@ -104,7 +95,7 @@ func TestDatastorePersistsFromRepoToRepo(t *testing.T) { func TestOpenMoreThanOnceInSameProcess(t *testing.T) { t.Parallel() - path := testRepoPath("", t) + path := t.TempDir() assert.Nil(Init(path, &config.Config{Datastore: config.DefaultDatastoreConfig()}), t) r1, err := Open(path) diff --git a/test/bench/bench_cli_ipfs_add/main.go b/test/bench/bench_cli_ipfs_add/main.go index a089410ef..e7fe90e04 100644 --- a/test/bench/bench_cli_ipfs_add/main.go +++ b/test/bench/bench_cli_ipfs_add/main.go @@ -45,12 +45,7 @@ func benchmarkAdd(amount int64) (*testing.BenchmarkResult, error) { b.SetBytes(amount) for i := 0; i < b.N; i++ { b.StopTimer() - tmpDir, err := os.MkdirTemp("", "") - if err != nil { - benchmarkError = err - b.Fatal(err) - } - defer os.RemoveAll(tmpDir) + tmpDir := b.TempDir() env := append( []string{fmt.Sprintf("%s=%s", config.EnvDir, path.Join(tmpDir, config.DefaultPathName))}, // first in order to override diff --git a/test/bench/offline_add/main.go b/test/bench/offline_add/main.go index a15ebcffd..338a5f6ac 100644 --- a/test/bench/offline_add/main.go +++ b/test/bench/offline_add/main.go @@ -37,11 +37,7 @@ func benchmarkAdd(amount int64) (*testing.BenchmarkResult, error) { b.SetBytes(amount) for i := 0; i < b.N; i++ { b.StopTimer() - tmpDir, err := os.MkdirTemp("", "") - if err != nil { - b.Fatal(err) - } - defer os.RemoveAll(tmpDir) + tmpDir := b.TempDir() env := append(os.Environ(), fmt.Sprintf("%s=%s", config.EnvDir, path.Join(tmpDir, config.DefaultPathName))) setupCmd := func(cmd *exec.Cmd) { From 676e557daf45f3b3244931f4568ce0582396db0c Mon Sep 17 00:00:00 2001 From: Gus Eggert Date: Fri, 16 Dec 2022 06:55:03 -0500 Subject: [PATCH 0530/1212] test: port peering test from sharness to Go This is the slowest test in the sharness test suite, because it has very long sleeps. It usually takes 2+ minutes to run. This new impl runs all peering tests in about 20 seconds, since it polls for conditions instead of sleeping, and runs the tests in parallel. This also has an additional test case for a peer that was never online and then connects. --- test/cli/harness/harness.go | 21 +++++ test/cli/harness/log.go | 155 +++++++++++++++++++++++++++++++++ test/cli/harness/node.go | 25 +++++- test/cli/harness/nodes.go | 20 +---- test/cli/peering_test.go | 141 ++++++++++++++++++++++++++++++ test/cli/testutils/strings.go | 14 +++ test/sharness/t0171-peering.sh | 127 --------------------------- 7 files changed, 358 insertions(+), 145 deletions(-) create mode 100644 test/cli/harness/log.go create mode 100644 test/cli/peering_test.go delete mode 100755 test/sharness/t0171-peering.sh diff --git a/test/cli/harness/harness.go b/test/cli/harness/harness.go index a35fead35..e68116b5e 100644 --- a/test/cli/harness/harness.go +++ b/test/cli/harness/harness.go @@ -11,6 +11,8 @@ import ( logging "github.com/ipfs/go-log/v2" . "github.com/ipfs/kubo/test/cli/testutils" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/multiformats/go-multiaddr" ) // Harness tracks state for a test, such as temp dirs and IFPS nodes, and cleans them up after the test. @@ -188,3 +190,22 @@ func (h *Harness) Cleanup() { log.Panicf("removing temp dir %s: %s", h.Dir, err) } } + +// ExtractPeerID extracts a peer ID from the given multiaddr, and fatals if it does not contain a peer ID. +func (h *Harness) ExtractPeerID(m multiaddr.Multiaddr) peer.ID { + var peerIDStr string + multiaddr.ForEach(m, func(c multiaddr.Component) bool { + if c.Protocol().Code == multiaddr.P_P2P { + peerIDStr = c.Value() + } + return true + }) + if peerIDStr == "" { + panic(multiaddr.ErrProtocolNotFound) + } + peerID, err := peer.Decode(peerIDStr) + if err != nil { + panic(err) + } + return peerID +} diff --git a/test/cli/harness/log.go b/test/cli/harness/log.go new file mode 100644 index 000000000..d76bb2747 --- /dev/null +++ b/test/cli/harness/log.go @@ -0,0 +1,155 @@ +package harness + +import ( + "fmt" + "path/filepath" + "runtime" + "sort" + "strings" + "sync" + "testing" + "time" +) + +type event struct { + timestamp time.Time + msg string +} + +type events []*event + +func (e events) Len() int { return len(e) } +func (e events) Less(i, j int) bool { return e[i].timestamp.Before(e[j].timestamp) } +func (e events) Swap(i, j int) { e[i], e[j] = e[j], e[i] } + +// TestLogger is a logger for tests. +// It buffers output and only writes the output if the test fails or output is explicitly turned on. +// The purpose of this logger is to allow Go test to run with the verbose flag without printing logs. +// The verbose flag is useful since it streams test progress, but also printing logs makes the output too verbose. +// +// You can also add prefixes that are prepended to each log message, for extra logging context. +// +// This is implemented as a hierarchy of loggers, with children flushing log entries back to parents. +// This works because t.Cleanup() processes entries in LIFO order, so children always flush first. +// +// Obviously this logger should never be used in production systems. +type TestLogger struct { + parent *TestLogger + children []*TestLogger + prefixes []string + prefixesIface []any + t *testing.T + buf events + m sync.Mutex + logsEnabled bool +} + +func NewTestLogger(t *testing.T) *TestLogger { + l := &TestLogger{t: t, buf: make(events, 0)} + t.Cleanup(l.flush) + return l +} + +func (t *TestLogger) buildPrefix(timestamp time.Time) string { + d := timestamp.Format("2006-01-02T15:04:05.999999") + _, file, lineno, _ := runtime.Caller(2) + file = filepath.Base(file) + caller := fmt.Sprintf("%s:%d", file, lineno) + + if len(t.prefixes) == 0 { + return fmt.Sprintf("%s\t%s\t", d, caller) + } + + prefixes := strings.Join(t.prefixes, ":") + return fmt.Sprintf("%s\t%s\t%s: ", d, caller, prefixes) +} + +func (t *TestLogger) Log(args ...any) { + timestamp := time.Now() + e := t.buildPrefix(timestamp) + fmt.Sprint(args...) + t.add(&event{timestamp: timestamp, msg: e}) +} + +func (t *TestLogger) Logf(format string, args ...any) { + timestamp := time.Now() + e := t.buildPrefix(timestamp) + fmt.Sprintf(format, args...) + t.add(&event{timestamp: timestamp, msg: e}) +} + +func (t *TestLogger) Fatal(args ...any) { + timestamp := time.Now() + e := t.buildPrefix(timestamp) + fmt.Sprint(append([]any{"fatal: "}, args...)...) + t.add(&event{timestamp: timestamp, msg: e}) + t.t.FailNow() +} + +func (t *TestLogger) Fatalf(format string, args ...any) { + timestamp := time.Now() + e := t.buildPrefix(timestamp) + fmt.Sprintf(fmt.Sprintf("fatal: %s", format), args...) + t.add(&event{timestamp: timestamp, msg: e}) + t.t.FailNow() +} + +func (t *TestLogger) add(e *event) { + t.m.Lock() + defer t.m.Unlock() + t.buf = append(t.buf, e) +} + +func (t *TestLogger) AddPrefix(prefix string) *TestLogger { + l := &TestLogger{ + prefixes: append(t.prefixes, prefix), + prefixesIface: append(t.prefixesIface, prefix), + t: t.t, + parent: t, + logsEnabled: t.logsEnabled, + } + t.m.Lock() + defer t.m.Unlock() + + t.children = append(t.children, l) + t.t.Cleanup(l.flush) + + return l +} + +func (t *TestLogger) EnableLogs() { + t.m.Lock() + defer t.m.Unlock() + t.logsEnabled = true + if t.parent != nil { + if t.parent.logsEnabled { + t.parent.EnableLogs() + } + } + fmt.Printf("enabling %d children\n", len(t.children)) + for _, c := range t.children { + if !c.logsEnabled { + c.EnableLogs() + } + } +} + +func (t *TestLogger) flush() { + if t.t.Failed() || t.logsEnabled { + t.m.Lock() + defer t.m.Unlock() + // if this is a child, send the events to the parent + // the root parent will print all the events in sorted order + if t.parent != nil { + for _, e := range t.buf { + t.parent.add(e) + } + } else { + // we're the root, sort all the events and then print them + sort.Sort(t.buf) + fmt.Println() + fmt.Printf("Logs for test %q:\n\n", t.t.Name()) + for _, e := range t.buf { + fmt.Println(e.msg) + } + fmt.Println() + } + t.buf = nil + } +} diff --git a/test/cli/harness/node.go b/test/cli/harness/node.go index cc251e11b..f740ab1b1 100644 --- a/test/cli/harness/node.go +++ b/test/cli/harness/node.go @@ -453,9 +453,8 @@ func (n *Node) Peers() []multiaddr.Multiaddr { Path: n.IPFSBin, Args: []string{"swarm", "peers"}, }) - lines := strings.Split(strings.TrimSpace(res.Stdout.String()), "\n") var addrs []multiaddr.Multiaddr - for _, line := range lines { + for _, line := range res.Stdout.Lines() { ma, err := multiaddr.NewMultiaddr(line) if err != nil { panic(err) @@ -465,6 +464,28 @@ func (n *Node) Peers() []multiaddr.Multiaddr { return addrs } +func (n *Node) PeerWith(other *Node) { + n.UpdateConfig(func(cfg *config.Config) { + var addrs []multiaddr.Multiaddr + for _, addrStr := range other.ReadConfig().Addresses.Swarm { + ma, err := multiaddr.NewMultiaddr(addrStr) + if err != nil { + panic(err) + } + addrs = append(addrs, ma) + } + + cfg.Peering.Peers = append(cfg.Peering.Peers, peer.AddrInfo{ + ID: other.PeerID(), + Addrs: addrs, + }) + }) +} + +func (n *Node) Disconnect(other *Node) { + n.IPFS("swarm", "disconnect", "/p2p/"+other.PeerID().String()) +} + // GatewayURL waits for the gateway file and then returns its contents or times out. func (n *Node) GatewayURL() string { timer := time.NewTimer(1 * time.Second) diff --git a/test/cli/harness/nodes.go b/test/cli/harness/nodes.go index 872d77679..78662afbb 100644 --- a/test/cli/harness/nodes.go +++ b/test/cli/harness/nodes.go @@ -3,6 +3,7 @@ package harness import ( "sync" + . "github.com/ipfs/kubo/test/cli/testutils" "github.com/multiformats/go-multiaddr" "golang.org/x/sync/errgroup" ) @@ -11,9 +12,7 @@ import ( type Nodes []*Node func (n Nodes) Init(args ...string) Nodes { - for _, node := range n { - node.Init() - } + ForEachPar(n, func(node *Node) { node.Init(args...) }) return n } @@ -59,22 +58,11 @@ func (n Nodes) Connect() Nodes { } func (n Nodes) StartDaemons() Nodes { - wg := sync.WaitGroup{} - for _, node := range n { - wg.Add(1) - node := node - go func() { - defer wg.Done() - node.StartDaemon() - }() - } - wg.Wait() + ForEachPar(n, func(node *Node) { node.StartDaemon() }) return n } func (n Nodes) StopDaemons() Nodes { - for _, node := range n { - node.StopDaemon() - } + ForEachPar(n, func(node *Node) { node.StopDaemon() }) return n } diff --git a/test/cli/peering_test.go b/test/cli/peering_test.go new file mode 100644 index 000000000..f3e797fae --- /dev/null +++ b/test/cli/peering_test.go @@ -0,0 +1,141 @@ +package cli + +import ( + "fmt" + "math/rand" + "testing" + "time" + + "github.com/ipfs/kubo/config" + "github.com/ipfs/kubo/test/cli/harness" + . "github.com/ipfs/kubo/test/cli/testutils" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/stretchr/testify/assert" +) + +func TestPeering(t *testing.T) { + t.Parallel() + + type peering struct { + from int + to int + } + + newRandPort := func() int { + n := rand.Int() + return 3000 + (n % 1000) + } + + containsPeerID := func(p peer.ID, peers []peer.ID) bool { + for _, peerID := range peers { + if p == peerID { + return true + } + } + return false + } + + assertPeered := func(h *harness.Harness, from *harness.Node, to *harness.Node) { + assert.Eventuallyf(t, func() bool { + fromPeers := from.Peers() + if len(fromPeers) == 0 { + return false + } + var fromPeerIDs []peer.ID + for _, p := range fromPeers { + fromPeerIDs = append(fromPeerIDs, h.ExtractPeerID(p)) + } + return containsPeerID(to.PeerID(), fromPeerIDs) + }, 20*time.Second, 10*time.Millisecond, "%d -> %d not peered", from.ID, to.ID) + } + + assertNotPeered := func(h *harness.Harness, from *harness.Node, to *harness.Node) { + assert.Eventuallyf(t, func() bool { + fromPeers := from.Peers() + if len(fromPeers) == 0 { + return false + } + var fromPeerIDs []peer.ID + for _, p := range fromPeers { + fromPeerIDs = append(fromPeerIDs, h.ExtractPeerID(p)) + } + return !containsPeerID(to.PeerID(), fromPeerIDs) + }, 20*time.Second, 10*time.Millisecond, "%d -> %d peered", from.ID, to.ID) + } + + assertPeerings := func(h *harness.Harness, nodes []*harness.Node, peerings []peering) { + ForEachPar(peerings, func(peering peering) { + assertPeered(h, nodes[peering.from], nodes[peering.to]) + }) + } + + createNodes := func(t *testing.T, n int, peerings []peering) (*harness.Harness, harness.Nodes) { + h := harness.NewT(t) + nodes := h.NewNodes(n).Init() + nodes.ForEachPar(func(node *harness.Node) { + node.UpdateConfig(func(cfg *config.Config) { + cfg.Routing.Type = config.NewOptionalString("none") + cfg.Addresses.Swarm = []string{fmt.Sprintf("/ip4/127.0.0.1/tcp/%d", newRandPort())} + }) + + }) + + for _, peering := range peerings { + nodes[peering.from].PeerWith(nodes[peering.to]) + } + + return h, nodes + } + + t.Run("bidirectional peering should work (simultaneous connect)", func(t *testing.T) { + t.Parallel() + peerings := []peering{{from: 0, to: 1}, {from: 1, to: 0}, {from: 1, to: 2}} + h, nodes := createNodes(t, 3, peerings) + + nodes.StartDaemons() + assertPeerings(h, nodes, peerings) + + nodes[0].Disconnect(nodes[1]) + assertPeerings(h, nodes, peerings) + }) + + t.Run("1 should reconnect to 2 when 2 disconnects from 1", func(t *testing.T) { + t.Parallel() + peerings := []peering{{from: 0, to: 1}, {from: 1, to: 0}, {from: 1, to: 2}} + h, nodes := createNodes(t, 3, peerings) + + nodes.StartDaemons() + assertPeerings(h, nodes, peerings) + + nodes[2].Disconnect(nodes[1]) + assertPeerings(h, nodes, peerings) + }) + + t.Run("1 will peer with 2 when it comes online", func(t *testing.T) { + t.Parallel() + peerings := []peering{{from: 0, to: 1}, {from: 1, to: 0}, {from: 1, to: 2}} + h, nodes := createNodes(t, 3, peerings) + + nodes[0].StartDaemon() + nodes[1].StartDaemon() + assertPeerings(h, nodes, []peering{{from: 0, to: 1}, {from: 1, to: 0}}) + + nodes[2].StartDaemon() + assertPeerings(h, nodes, peerings) + }) + + t.Run("1 will re-peer with 2 when it disconnects and then comes back online", func(t *testing.T) { + t.Parallel() + peerings := []peering{{from: 0, to: 1}, {from: 1, to: 0}, {from: 1, to: 2}} + h, nodes := createNodes(t, 3, peerings) + + nodes.StartDaemons() + assertPeerings(h, nodes, peerings) + + nodes[2].StopDaemon() + assertNotPeered(h, nodes[1], nodes[2]) + + nodes[2].StartDaemon() + assertPeerings(h, nodes, peerings) + }) +} diff --git a/test/cli/testutils/strings.go b/test/cli/testutils/strings.go index 1fb151248..110051e67 100644 --- a/test/cli/testutils/strings.go +++ b/test/cli/testutils/strings.go @@ -7,6 +7,7 @@ import ( "net/netip" "net/url" "strings" + "sync" "github.com/multiformats/go-multiaddr" manet "github.com/multiformats/go-multiaddr/net" @@ -75,3 +76,16 @@ func URLStrToMultiaddr(u string) multiaddr.Multiaddr { } return ma } + +// ForEachPar invokes f in a new goroutine for each element of s and waits for all to complete. +func ForEachPar[T any](s []T, f func(T)) { + wg := sync.WaitGroup{} + wg.Add(len(s)) + for _, x := range s { + go func(x T) { + defer wg.Done() + f(x) + }(x) + } + wg.Wait() +} diff --git a/test/sharness/t0171-peering.sh b/test/sharness/t0171-peering.sh deleted file mode 100755 index 207b27980..000000000 --- a/test/sharness/t0171-peering.sh +++ /dev/null @@ -1,127 +0,0 @@ -#!/usr/bin/env bash - -test_description="Test peering service" - -. lib/test-lib.sh - -NUM_NODES=3 - -test_expect_success 'init iptb' ' - rm -rf .iptb/ && - iptb testbed create -type localipfs -count $NUM_NODES -init -' - -test_expect_success 'disabling routing' ' - iptb run -- ipfs config Routing.Type none -' - -for i in $(seq 0 2); do - ADDR="$(printf '["/ip4/127.0.0.1/tcp/%s"]' "$(( 3000 + ( RANDOM % 1000 ) ))")" - test_expect_success "configuring node $i to listen on $ADDR" ' - ipfsi "$i" config --json Addresses.Swarm "$ADDR" - ' -done - -peer_id() { - ipfsi "$1" config Identity.PeerID -} - -peer_addrs() { - ipfsi "$1" config Addresses.Swarm -} - -peer() { - PEER1="$1" && - PEER2="$2" && - PEER_LIST="$(ipfsi "$PEER1" config Peering.Peers || true)" && - { [[ "$PEER_LIST" == "null" ]] || PEER_LIST_INNER="${PEER_LIST:1:-1}"; } && - ADDR_INFO="$(printf '[%s{"ID": "%s", "Addrs": %s}]' \ - "${PEER_LIST_INNER:+${PEER_LIST_INNER},}" \ - "$(peer_id "$PEER2")" \ - "$(peer_addrs "$PEER2")")" && - ipfsi "$PEER1" config --json Peering.Peers "${ADDR_INFO}" -} - -# Peer: -# - 0 <-> 1 -# - 1 -> 2 -test_expect_success 'configure peering' ' - peer 0 1 && - peer 1 0 && - peer 1 2 -' - -list_peers() { - ipfsi "$1" swarm peers | sed 's|.*/p2p/\([^/]*\)$|\1|' | sort -u -} - -check_peers() { - sleep 20 # give it some time to settle. - test_expect_success 'verifying peering for peer 0' ' - list_peers 0 > peers_0_actual && - peer_id 1 > peers_0_expected && - test_cmp peers_0_expected peers_0_actual - ' - - test_expect_success 'verifying peering for peer 1' ' - list_peers 1 > peers_1_actual && - { peer_id 0 && peer_id 2 ; } | sort -u > peers_1_expected && - test_cmp peers_1_expected peers_1_actual - ' - - test_expect_success 'verifying peering for peer 2' ' - list_peers 2 > peers_2_actual && - peer_id 1 > peers_2_expected && - test_cmp peers_2_expected peers_2_actual - ' -} - -test_expect_success 'startup cluster' ' - iptb start -wait && - iptb run -- ipfs log level peering debug -' - -check_peers - -disconnect() { - ipfsi "$1" swarm disconnect "/p2p/$(peer_id "$2")" -} - -# Bidirectional peering shouldn't cause problems (e.g., simultaneous connect -# issues). -test_expect_success 'disconnecting 0->1' ' - disconnect 0 1 -' - -check_peers - -# 1 should reconnect to 2 when 2 disconnects from 1. -test_expect_success 'disconnecting 2->1' ' - disconnect 2 1 -' - -check_peers - -# 2 isn't peering. This test ensures that 1 will re-peer with 2 when it comes -# back online. -test_expect_success 'stopping 2' ' - iptb stop 2 -' - -# Wait to disconnect -sleep 30 - -test_expect_success 'starting 2' ' - iptb start 2 -' - -# Wait for backoff -sleep 30 - -check_peers - -test_expect_success "stop testbed" ' - iptb stop -' - -test_done From 92743b1bf5cb7185495b62c7e7d1b53845ae01c0 Mon Sep 17 00:00:00 2001 From: galargh Date: Sat, 11 Mar 2023 11:00:59 +0100 Subject: [PATCH 0531/1212] feat: publish html report and test summary from gotest --- .github/workflows/gotest.yml | 54 ++++++++++++++++++++++++++++++------ 1 file changed, 45 insertions(+), 9 deletions(-) diff --git a/.github/workflows/gotest.yml b/.github/workflows/gotest.yml index 8eb41a34d..e594b55ee 100644 --- a/.github/workflows/gotest.yml +++ b/.github/workflows/gotest.yml @@ -23,22 +23,28 @@ jobs: run: shell: bash steps: - - uses: actions/setup-go@v3 + - name: Set up Go + uses: actions/setup-go@v3 with: go-version: 1.19.1 - - uses: actions/checkout@v3 - - uses: protocol/cache-go-action@v1 + - name: Check out Kubo + uses: actions/checkout@v3 + - name: Restore Go cache + uses: protocol/cache-go-action@v1 with: name: ${{ github.job }} - - run: | + - name: 👉️ If this step failed, go to «Summary» (top left) → inspect the «Failures/Errors» table + run: | make -j 1 test/unit/gotest.junit.xml && [[ ! $(jq -s -c 'map(select(.Action == "fail")) | .[]' test/unit/gotest.json) ]] - - uses: codecov/codecov-action@81cd2dc8148241f03f5839d295e000b8f761e378 # v3.1.0 - if: always() + - name: Upload coverage to Codecov + uses: codecov/codecov-action@81cd2dc8148241f03f5839d295e000b8f761e378 # v3.1.0 + if: failure() || success() with: name: unittests files: coverage/unit_tests.coverprofile - - run: | + - name: Test kubo-as-a-library example + run: | # we want to first test with the kubo version in the go.mod file go test -v ./... @@ -59,8 +65,38 @@ jobs: mv go.mod.bak go.mod mv go.sum.bak go.sum working-directory: docs/examples/kubo-as-a-library - - uses: actions/upload-artifact@v3 + - name: Create a proper JUnit XML report + uses: pl-strflt/gotest-json-to-junit-xml@v1 + with: + input: test/unit/gotest.json + output: test/unit/gotest.junit.xml + if: failure() || success() + - name: Archive the JUnit XML report + uses: actions/upload-artifact@v3 with: name: unit path: test/unit/gotest.junit.xml - if: always() + if: failure() || success() + - name: Create a HTML report + uses: pl-strflt/junit-xml-to-html@v1 + with: + mode: no-frames + input: test/unit/gotest.junit.xml + output: test/unit/gotest.html + if: failure() || success() + - name: Archive the HTML report + uses: actions/upload-artifact@v3 + with: + name: html + path: test/unit/gotest.html + if: failure() || success() + - name: Create a Markdown report + uses: pl-strflt/junit-xml-to-html@v1 + with: + mode: summary + input: test/unit/gotest.junit.xml + output: test/unit/gotest.md + if: failure() || success() + - name: Set the summary + run: cat test/unit/gotest.md >> $GITHUB_STEP_SUMMARY + if: failure() || success() From d23702bbf8513094ca445bea52742d952e80a8dc Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Tue, 14 Mar 2023 13:51:59 +0100 Subject: [PATCH 0532/1212] chore: add hamt directory sharding test --- test/sharness/t0115-gateway-dir-listing.sh | 24 ++++++++++++++++-- .../t0115-gateway-dir-listing/README.md | 23 ++++++++++++++++- .../t0115-gateway-dir-listing/hamt-refs.car | Bin 0 -> 782149 bytes 3 files changed, 44 insertions(+), 3 deletions(-) create mode 100644 test/sharness/t0115-gateway-dir-listing/hamt-refs.car diff --git a/test/sharness/t0115-gateway-dir-listing.sh b/test/sharness/t0115-gateway-dir-listing.sh index cf95bf4b0..4681e63ee 100755 --- a/test/sharness/t0115-gateway-dir-listing.sh +++ b/test/sharness/t0115-gateway-dir-listing.sh @@ -13,14 +13,34 @@ test_description="Test directory listing (dir-index-html) on the HTTP gateway" test_expect_success "ipfs init" ' export IPFS_PATH="$(pwd)/.ipfs" && - ipfs init --profile=test > /dev/null + ipfs init --empty-repo --profile=test > /dev/null ' test_launch_ipfs_daemon_without_network +# HAMT-sharded directory test. We must execute this test first as we want to +# start from an empty repository and count the exact number of refs we want. +HAMT_CID=bafybeiggvykl7skb2ndlmacg2k5modvudocffxjesexlod2pfvg5yhwrqm +HAMT_REFS_CID=bafybeicv4utmj46mgbpamvw2k6zg4qjs5yvspfnlxz2y6iuey5smjfcn4a +HAMT_REFS_COUNT=963 + +test_expect_success "hamt: import fixture with necessary refs" ' + ipfs dag import ../t0115-gateway-dir-listing/hamt-refs.car && + ipfs refs local | wc -l | tr -d " " > refs_count_actual && + echo $HAMT_REFS_COUNT > refs_count_expected && + test_cmp refs_count_expected refs_count_actual +' + +test_expect_success "hamt: fetch directory from gateway in offline mode" ' + curl --max-time 1 -sD - http://127.0.0.1:$GWAY_PORT/ipfs/$HAMT_CID/ > hamt_list_response && + ipfs refs local | wc -l | tr -d " " > refs_count_actual && + echo $HAMT_REFS_COUNT > refs_count_expected && + test_cmp refs_count_expected refs_count_actual +' + # Import test case # See the static fixtures in ./t0115-gateway-dir-listing/ -test_expect_success "Add the test directory" ' +test_expect_success "add remaining test fixtures" ' ipfs dag import ../t0115-gateway-dir-listing/fixtures.car ' DIR_CID=bafybeig6ka5mlwkl4subqhaiatalkcleo4jgnr3hqwvpmsqfca27cijp3i # ./rootDir/ diff --git a/test/sharness/t0115-gateway-dir-listing/README.md b/test/sharness/t0115-gateway-dir-listing/README.md index 937438bcd..7da44078b 100644 --- a/test/sharness/t0115-gateway-dir-listing/README.md +++ b/test/sharness/t0115-gateway-dir-listing/README.md @@ -2,8 +2,12 @@ - fixtures.car - raw CARv1 +- hamt-refs.car + - raw CARv1 containing all the necessary blocks to present a directory listing + for `bafybeiggvykl7skb2ndlmacg2k5modvudocffxjesexlod2pfvg5yhwrqm`, which is + a directory containing over 10k items. -generated with: +fixutres.car generated with: ```sh # using ipfs version 0.18.1 @@ -30,3 +34,20 @@ ipfs dag export ${DIR_CID} > ./fixtures.car # FILE_CID=bafkreialihlqnf5uwo4byh4n3cmwlntwqzxxs2fg5vanqdi3d7tb2l5xkm # ./rootDir/ą/ę/file-źł.txt # FILE_SIZE=34 ``` + +hamt-refs.car generated with: + +```sh +# using ipfs version 0.18.1 +export IPFS_PATH=$(mktemp -d) +ipfs init --empty-repo +ipfs daemon & +curl http://127.0.0.1:8080/ipfs/bafybeiggvykl7skb2ndlmacg2k5modvudocffxjesexlod2pfvg5yhwrqm/ +killall ipfs +ipfs refs local >> refs +ipfs files mkdir --cid-version 1 /Test +cat refs | xargs -I {} ipfs files cp /ipfs/{} /Test/{} +ipfs files stat /Test +# Grab CID: bafybeicv4utmj46mgbpamvw2k6zg4qjs5yvspfnlxz2y6iuey5smjfcn4a +ipfs dag export bafybeicv4utmj46mgbpamvw2k6zg4qjs5yvspfnlxz2y6iuey5smjfcn4a > ./refs.car +``` diff --git a/test/sharness/t0115-gateway-dir-listing/hamt-refs.car b/test/sharness/t0115-gateway-dir-listing/hamt-refs.car new file mode 100644 index 0000000000000000000000000000000000000000..58069310cc4eccb612a4b272050f4064e2652232 GIT binary patch literal 782149 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

QQ>M{}WU z4cNes%{3!pV+T8o2;p3OJ$GVFiupBP(*(EL$KrFMv?s@e;_u;!R}G{ z#~dXpcRZfQiTu9kJ&XsM@wok|8zS|-44K4pgEA4VZAMfzpy zaSCAx-d?FsYJX_PbR*Rm=lAs|c-2u3t=>G;vj9HL`NDbSJKYzS=BCfh`l`Ic*a7zq zx$&azP}V5V6hu+wu#`{kqP zp-PVU+REFqA*UiRy}P{1@1_q-EFCh;?>Eh!H@|%xXYEtARe9dQxu$F|D%fzWvxGoR z{a&0fq(bn?iU}b*k3gpGz|Q5fvv^})l&~^H6|HcF^WHe0)0QZB!VIj>vM`7=6bq4$fdpj9)yz1cK0X5km2@!mwI zP~6hyPK)5EweIZI(+V3}N}-B%zVdyh>NmAmPWI%_lvRi+%R+7<3Ss;{ilOQjU1p~^ zj`RJ;wM0Dvd1bR(pJuvS@cAO8#JRrk@mEU#90f-&A{bvm3MvvlxbyYI^U%gzY_Ews zj-0J+{LhyIZpmjb-*t(wVC-JJp1tqs1uFoBM?3q`5e+AO zR4xI59rk~%!;J0bf|aK8;EO2Yk}M+4H|f>N4^m9axwz^wd?|)93O5vH4Zq$vTn$u^6dk}&d?nriEGBjL5T)nC+)Go(` z^y%Xmo{@ZsYFNpexe-WC`SR0+(M5mScg7vyx>cZ=M>4lB|gtFB$CevvMAXMh0t+e|2NY zm-BuB#iKVS-%GcE4yM#0h-+pFrFh}|Nn50yTFKRNESDXH3FJI%^Ddr^SQSrCo|8@V zN{WuT4u}#I3{uDFa)g*AEvH9Zw2uo|R~y?skdGjF#~X37Tt?k)oI`=m3F8t!AUr;Z z7ojx8&KEQQ!uvGG>dA3$uMc|a1Oz9?F7+P!5ajzXMBO;u!uM<;_+lW@>Ch+i7AA%u zikH#DhCaoCqs^0T{KX&BjJ97#)@FAR}8evqKP&AJXrrM9&`<|WR(fRa*)D^nDQg>XguN_ekbaiD3|V;sZsiR zQBs_;F5|xAuYM9N4(qh~k!(Q53{-x>B!h!%*hHeBuwDsgw9F61k!RESOLK*4&+%H@ zQ+xglrAREC-HR3A!%zh}IY_reJ%ca9==HjT2#PP;^U0reQYrdyo8d*x5|e&{dg&7L zd;Fz)4yzCx7Kf@M#14FgL{EWT`eR2-wtnV?9CtkP#+k3kajzy8mzUH*wnGu``90|j zc;=8{br>9u@

tZQyW{;e4mnl&!%1pMf!EHIuY#cxIZhEB9Y|SlsvoP68R2mw|){ z+abvpxrUJKgbyA6>USU2_TMQL>9Pp*#bA%h{6!k@cCFy;v$+%q4ub<7CFl!|MnlRk zjrv}FvBDkV5ERJnBE0td7^?g_*VHr52VR zQ1wzS^F|mm;<5SXzrii-#SAU3&;&X;Aps=7^7SYaCu8`%(-@I}Led(mpm_9+(9bD+ zLAJ+abC=w`MznH6>wr!{j1Ph5J&*{FNKMi6obr>{A_FD#!efGSqZ`_yYMt{szNOa{ zNuqzM-WLT}Cdx^7#PEi>{&Ax|9=y1TpG-x42ikaTbuw%`xy=MSRB+A~XuJAXQK>%sl}W`2cqI3eJ6*y+#>J6p(@ayq%0$aJ;1BP5hFz zd)Otf8y0ks>!2VHL3Y&n4}LD%BusNHQP zeGYJ|An-E^F1i(?wOymNY6JUao@dUT(l7>F{xSwRKAAEq_Z&5lh?DuB4~J)N z|J=Jow&|Ze#+b%GKSvdo_fw{P6ri-NLHCzbQy{^3pi}mp@`bv)mf0|6+1C(~%oyzT zpchMw7*xd|rvzn1L7*ONqzXw$26>ZQt!z6yPM7pMfhktCNX3Vx%2kH}OEu{|m++rR z$Gc!RDZE$S6c+DJy$4?3FE}$VgEXNg}c-3E5IncJ_+wRrZdo$liO0 zGJc2G)63`cy}sY;=a2W5uJ`G_pZ7TT8 zd#Ibokv!Y_2SxY{<>;iC+A3`=Lc=V$deeq5X-IU9dEHmuRWX!u}kTESm$wR@o z>wQWnQm5y}@P2ba9!UYHxOA|;q0rX|xp=y<%S?WT40$DM|0r({|EVn!p{O@!P@WlE zdGJ2j*nYq7k_>f2BHf_^;&6-qQ`%-J-u~;{p)vF$JQ#1}sGP*T?2S$O zVYSuB`1p@ODz0{y+iu(3uRDJG{GF-9`wQoPf*kOq5vFcFuy>I4c!tLsK&!zuA6rTK zQ8H4>bqv&h2qJDl{?{~i9#9@dsAD?OM0%e)7)s~9s+N4;`F!I}5g(&Oj%?5u zj!s>D(WIs0dzWSawh2LBA=HBv1Ni~SLlDeyUR*w;*4Cu;oWY51iK8@1-GbK~Mh;J^Z>EHsNj zoe!ulyMOKA{xn^G=s`eO$mP$PIvf*;^Y~UwWD@V(c_SUF9>ZWM0~`poK!X{S*xN=l zS`WTZuX9?HmRCbyjQ8SI*Xl9rL|V;f8&Nc>Ww`V*HsDU$FF%J^OCOO&Mlc*n+|1iq zd$I{TgJYVj?{`G}r+iIVo`l$jgl7=UasG1#xWNyFfl$loc2p>!=K}ln*}_Ec5`EI& zpLy) zGK*~_bI)qe9dC4WxBzmJU>~5~gU?8Paac~>CD$4tJ$yeqaO+)Go3pUYrSNSpEVn;C zB{ja-ADiGBKq~zqRk9=GlS(sVJ2H}x9jB<>Q( z0mww)o7+*nF~ex{tm==gLTSyjd|ZU$H)fx{UtWo2G-ac0blav11%Ia$q+K9P*VcaY zK1Bb;SZjK*Quk;~V%YAyimFeYgQbiX&Sv2`ELM?#S{;y+1sV@(U520#0&)!qLYJva zi)uCuliE(>N4b>J+*_X==>F~>R=kj}>bx*@P*1Ua3!PvXB}hLa^W-k`$tlq;+;ANQ zgTjf})zQ(Z^@*iYTI{3(z$Z|s9eG}+z0mI?fxE5@@v2}mFGGZLLazIw^Lx*Pug2O7 z%@`v%JB$M0UXzvuZXU`XuvCkFk7EhHgbT-J-1(A7NZ!etd*uFW%znzVjjuF+^>ja>|hlz$P?5>>ygKWsp&=9WxOAS1|o zSRd;pTD!_bdHi90v0TtF|IX0C5v%ReqZ(h+o1}lbs0X2u?WzU92B?mOXrT^RM&y<^ z&n#lEmz%sw3464BF`zfiUSvZtmBqU{!}|Ce<$!dcQ9%wWbo4ry=EfiNv2<=_Vrg%? zpevHAbSE;acesc;jC=j+r_54DpBE!MbqXLS0?Egy*RE>?EoXVX-reki@OW9H7XRyC zzr_*^xzB0ET(_Ll$Uo_E-Lw$optdujRr-;7TyX7fhR^aW-d6weS7bp*%(g}0>VhYq zoQ()^#%`Ev)poNg$Vq~e6SWQgNGcXwgWKX;cv-$Lj^W#^jpk4Gw{08N+*m7kAy79? z(e0e~CI;l7t0uCZe-qHx;Gx-&$&IKBJ1V}?Zr#Tn+2|;^^eAj`#dz#PF6n$OgzE#l zCn|y(&kx~N!g#+rF65m(D<#;5CC@|s{jXZ3@a(zpyWtu^GuJEj*yb#6|y^ zOQQ5K-sSImWgawtx$&X@U}Isy43^dCna+v@Z57e|aJetPm@3&De_JnzarnuD5I-^Y z{pU=I?~wbtd8FUCD@Fe(i83+#Nw|7mMEJfG^RPan`Ydft4x@L#D+dNzPSMFe&=l#J=%;sC94twnp<(D+P@z5BUfRG1?La+_p=p!X|wwUzh zSWlD%w%UDlA9snqyl+8jO}5rHCyytVx*OB(Z!zzo>n$7V(6hme&j4EeKYrZc?+<2Q zh+6Q^y;DugD-~sr?j{vIJSIo41J3=KTB64LCp=EQ*F}}lhXv5 z!uA^5=#7%Fu#Bd%JU(W;xrWHT8wc7~qaKEiMRfL_a;%NmY?kF|UAw8%gL`H{b*?yi z;cQhy`Rgy8qOQG+A;*^is{g_L^G_!xJPVVjllb4Jj{N1p)c+lncISvqipEv$yV8Gc zev5>)UQ+Cp(~0wC$;1@mzb~suJ$iF^Rz5{<#TPJ~B6qc(leC*N*>e_+fMThDD204Ovcq@Uq2K7lj95PuOqDkiXl9 zbfSm#McyOCWmu{>Ew`o{ZP)#|0=Tn7i7f29zA0}TiahIYiTFX(5&AF*5u_Mfq_GICBX-0YnSIfcs=1kg@WkO#4i{v9Qw`&7s& zrlveUV<$hD`Wx3h6zabqvWa=&;QD zoKM?fyJ&0uQ)69r$NK4`J!44v;RpH@5_|0)L__(1L+|d{+l;Z{h4L|)Nj)Z&(@6Hw zeBc;+_ZUSOPufH9V1py+Fn_iJahbq+d~A7Wn96;zCu+c}6w5C*u;08uO17?7{$l=KWc%yI8;|o%&fi=E z&zd0h)+h=Z!#KxTr|9gk1iNYzZu*Cd9(!>^ymg{M_D`GX4YuCqm1$sw0m&15sRxJc z4>b7Me3hVUBOZk@*6JEm1ZXxfR*nHN)_aU9&p=Ull6186- zm&CGrBU-Z=E1M{6CcMIE>d}@T+jtqSjX-Njx(fL^*uX;jE+iCo$vW!1Y(Qzz85&9S z*xcIm&+j6y#NDmYj5l|!F)(vul4M?!JOjD?q)HTo%+4e|Y;2P?Ir4Eshcm?6wmRwq zL!L+zmD)JFF-1`P8p-6I2`RLV5`tbc2Va+PRMo}qr98%2`jcX~G4w>7$$4gY%xpPH z@55EpTQ62=JDOdD(V(svLb?fTL_ZO2KUn-Yd~Lor#84+U=n<>RpYBV~pt9h5cK=y1 zR;WG9QW)Y{2$%8=WKSS~^|Z9__NMV`;X$U7;_8P#HEj82FjRa3oFdo;URsbVpV_B; zLi4|aY371~k8CzI^`LuNp2csECxTM!EtZvpk4XxNwOpHRbDb~tEQL-S)J>0WKm#7j zO#*q{G;aMVv#}k`QQ|KpbpNCm)VXeIoZR_**}mTz6gdw>yiqUv?;f-|-QC+dLA2nq z!-W6xDOvFQ??FEttTj*Wk&-DrHqV@pUIsbvKOhyBe?qT7WPXvKb{}7S`c9cL{#MC) zOnrcD(k1B|RQOwRP3P{rEan0r6A__KTtPcXGVivTGuqu|R3{SX`@KSBozHKvbf#uB z_+4E5z4jCH1N%T4!oaBceTySGd?g;LeEx0yxXrFx_M3{UiltTJN51ain+9Jg8C5c| z=R@eg%m%kU%1!X10F?^@XE71?`s*OlciI;|noPW<_q+QEPyaU2gDrmu$FI@R#kj>p}V+p;BsIX$(}JfZL(O5Ms^@A2BeO^+y;U zUdGu-22tqdv+_zahxs`VD;0gi@_ct|4Vj|kLu!@Bg(8b#4QxJQl^Dt6;o_}jk8 zkst4p<&TZH+zkq3y=9dHa{Q12ggTC~BWT_K*s+zAkzXhGd{p~tV)rLOX^nHYqb~V- z3%|j7m&`#9^MwA<(2eWh7zZHCR2c8r%Sy7hsmJGP)8F@Jm=NF7`d4|+Vl4fmf=jOD zw`cu|`*RT1%GYNFDvNmoJd|{=o0N;_9|L;at(Ow9j;Ie*{0_ ze&1%4+#*5~f_*rH8{c-}=@T!(e+}<)De5y`Jx^2Up4+(dd_5?{t}zRAkc^PeB03#<)uLO~2^>d|R*UEA}i1~j;2 zoLPj*QwsTNo-G*6tZ9W0S4J`>=Vzvvob3U(%Ry%R!E&rX8aSd_m956tA}x*OR`t&m zIZ(OIZS!Acn8Po#s3FNV!@PY0@_d0X$A=J02TD#H&^BNh<$DB^ZUlP`^SQ7S`_hQF z>DRMhIp(f6V*5{zUklMDBqx#uqZgX;9Sk`C4n1J(<;?zPMgINKe+aOaQKo5kbW z>V10~{GXE4;k9Unw8GmT8xoB5x;M`XG&fdIam;i3d1Kt8NpKob75Yp?6bv=5c&Sr= zqe*ciw`oTWs*jDl)})vAxU&^mr>#Yq!*C-1ij!fV*QPEO0B7){An5PQQN3es0!$rt zI%><4T>QdgZ+quQ^@yv^J+`K#+32FWY{)7Maz^k{ZfxouR}9jp{57{PCk;e#)ID>5aR}7qa4G^Np=J~f2D3Xg<_QlhR!MMu zvXTK~6dU6Osy5fg0dC~%{)f?L^mjNgll_KU!`0*;JL=3y&GIVQ4y!99@!~rNCjbtp zlkvx5Hk$JhxpOqQ_u`kMPlcp-rJp70xvYEFxhb+aZtgsvBBQi+G>X7JVO> zqED$9Bx;o@zf!t=)wvP(qco9&P0%X4Bq$~@!H}?M*E~ARzBcFO7id5o!f?8d90O1H zMQ-N_uMUk4y6D?R_@ABXuzJs$89j7+_oWds_XE%L)Q*k>a6N~U8b#2t` zW3D>vJ(g5Z?E<>QqMqxe*Ju#P!uEmvbarr}G|TfT)RJv z0vM6w1%}(f!Ox#OPDllanb-|u|K~qU6O=W@Nt-cQ%n;E!z(x8&T>F(~07)+$#hPE` zmeeEbDpQ<@!)w}0n5RAEHqmiGm^R0nOU&kU7|8KJK;nXovD_%jl&-~=-;A+*^DPiOIMoebhz+HuZ&o5qX-0PCD z{Pj-aO`^cVoBVJctIbLwIQUk+Urd7ut3`f~OVuhn8Qq+|_NU+9+<|fgb;k|~7@pB6 zRRp@cfvr`jkk(Z&QmQM?v@F}TpE+Ax@Ba5_YvIo)K@MmN2qJ_Cz~OjFQ~@7S zuSAspQg>ypu!_rhN>6tt6+c%}>p7o&&VUaP0HE63Vb|mIZ1i~g*bIr+2w0vqbJ7*< z@mo?8G@AvN>B)_yFtcz*O5O!CfJa6c$XEwADDBmWLxfjBvoLv8=w0ev7pePpGsR0E zu$~(yzR}d}?h%_w|6P*;o_Ja6^(u6-y=SRpXV_#+sYOm$$+KvKn#t#lpFW+}9W$7c zemyLe{1i^0C_o_8INzY~G4dw*(PJ%2eux=DEJC+nsR2LSFn^cdTT*lU%<}Xw zIT6rLd3cb03pz@6;a54^vw5vJT2X`(FHbF(tlP&UmPXNBss7&=k}e!7cv6Aq%#T2e z>^3w6#cBF^d)vN77tcL|)h;xN?)gG}(YL}!@|O6tYV;>e@<9&FQp9z<_yfIf-`&K8 zYEs3*l}&q!JCq)cNnxG(U@XeBHR5SsF~7?MrFWntiy%U{$%sUs|Hs0FQ^!Xay=4li z8?T#2`^WtFl|b^#-jZ0iY2wP@cWRIWh7Xb)6%LW8{S5#;&~yFl5}6vewo0_XwGQ>n zQ;k#v3a2<1gi5|*m#lttJ_Cj#ygSIbEOkS_xJna6(>GsGGvtz=-1PHyV0LG(3H-NQ z$&*92=3dE}3B)Jp^TdN-!>lc|+}f!&i#s874~#A}mYH0$(_gmV{QBFsr@)}rh?OoH zXAtD11fdSu!9D!|HSG7#7tB-YeA@dAZSOG&ItKgqWMmB|a3g;A;IVgo8!Je*l3Q$p z(n8>aL?PwSV6^wbU}~$>A%C}W_7(M6!Pmu8>X@C$SImCZ;spsjUQ^vE2Ot7%%8K{?G$)~%GPlh#2?aS>m=1>OU8z6ijpEuf^*-mcKXnT%l zVxrB-u>2d2#%9}Jj&^41zGu$ogM`6;hBOG&HR$_}+I5(wPzncW@srRFfj?*2$_oE3 z?%kEVT$sTSxL3X$=G9V=08jXS77=PS^AXw;Xy@0%X(4`Zq)$dT*1iySp}ow2@zX-@ zd6zWfcDvpAbG%g`CkYj9P+BY(>F5A*Sl8Cd`Z4Yrsz;bk;0ftua;y)Wf_87K%=EUz zZ+${w*F}H`jA->2`RMCvWN@PI3FFV5PJd1gU-3^aloy0^YkPkya`kcv+;V?k0d}+u zb$k)psgoVQ8=)@#Q%8P+bKK|UD?9b4%BIR#=~cs@`7 z&$W0(f0O7eg=_-dM&z*M?ss?e9l+-q{w^sim!Euvb@2;UcxWfiaZ*-3uJbq^W7xaphyOaAAa^sljpjNHDCFQrR z7G0bh=i{epX7^rW22Ib+7?Nv|C~aT3@+cm*P8xc5APTJ51FgV{*(gYFhr|^&`@1@K%uEfZU}b^3-{^Z{X4sEObJ;_9z$5q zl`uBL=YyNU)`aYE1cJu7qsL?LQaQG`TTshbFNBk#bjo0*-6AL+hj!`0N9`v z$QUuPF_MU&{vw%Mn#2VO8Z6*@OJTT61o>dx<~+dc#Rn!47s2zN^Ln2?5^eiSN2{Kd^VIQCW_m3O;*MrF?q9!k2{_3)rr1?nXIWD)D$8j%P%426-uYE2o>$)6! zvLN~Jc^n&AKfWhoS1+4D^I(=2N3xkE_sq)cxfAmDxSr1JMuLKcwsXQr22m_hnhO+j zbNXI+(rk~^3x+thKQg1`){#+BUD{+lG|d5Y3wdRXASVePJ(MB}A0#C_0R{&?Hd43Z zV4^^pfq#hWwFOm1q?Z|=II-#Jl_Gl@PwQX-+iGX2dXe|ErE6Y?6J_5MQBZbq!Kd+* z(e=jh8e+7iPFd(>$2$23&(bQJ3X+F~fgz7*u;L@8k!*_hRddOg*g-mxxaQwfWrHY1 zyMGghlDDf6C!OIp06Z%S$?Qnj;`i6%g!C{`%KdpVqSqDmhl5EMp(Y)6-7nr$C~sBs zWUbCgi|-3!Kg3&etJE%tK6yO%ihJ{L($;~(LEcw>#lE#_z{Qe{bW*8*${?S3u8RB^ zF>y=Ejeh_Jq#-bmdcK-_(9a&%D-07tsUit_N%r?vhEp0gc~~~KGOv~Xh_Om9ot6f+ zuM9uXBT;BzEr^tm6()W9zbw%It`KrC_lSdzFkFobe{3GBd~nlNxWhH=zft`y)9YoZ z9pQL+i)x;`-@u{jZ<7#H`zl@(_w1r+R=NLOkU_ z&CQIV)qu&{^DPD`|E!O_mA8s1aDL`;aZv0oT@n9unwME*vRwt(DN;fLNGLL@4Xt(z zG~3Kr6|Q&XHsM}MbEG1A`tP9+hwnpO&VLK4cNJemfgBX4MdT9a(Kz&FjKulni~1_3 zXHBr(ck856D*GrdCKk{7PIe{}Cs={S3}GoAgi6v?gI32}Q;#ygZ=cx;EPNDF2CD6Yfm=VJS!uLk@o4AGF%3a{A?p^u|SF-=? z+bhs97xe=Fi$KfK+ROMw*xkfaCXe>XmjOFH2cG*WxZ2E_DEiio(wI58k!L?>-1vwEQnxl^1&lU9dNj=BH z9Uk`cB)zhA_1E>RFL!I*3F$Q~!^7Avo7_vk3a(c^NwDKk`@V$`tKl9ykd0;*;Ino| zb`)1Nm+GH;d+Uy;LkoN2Nc1e9&uI?1;Q*E2U@N0hy|H51{HI&=0+qPGR(v#5Z%vn-D!Kyp2eiUM zi2JigT!sgB#yh7jZ&PB_H0Z`qXjG-;Ep2A6_lFE-gp?R)kb(UnC=L6LazgDwC<2Mh z6#l53ZJX)Lpu72a{*D(1$t~VGT<6pHOt1Bm6bXA{?G9?EOjn~LN4u9aLe^-;iz24K zd(Nw?b?dm*m!wAN zl1;aR5oGV>%IVO$kGyF%!Nk*Q}Jr&w7 zKZbfRJ_n&arsfvsk8f^sah6>kA;i(vqS$hv-^e#R5q6;lvu-7>8a$s+z!Opr5A=}l zkp)o2Anwg%m-sfSgSFY+#Omg5pu(uFdg|BgO7$K$(Puzy5*CD7oCvHaKXF)>_htC8 zjZi60XWhfF?T^E9%q&t!bp%0Z3~6>L$bKNc$EAg5z3)M7xHUGqY_ z!%LPF0j!9B{&yR$mEG`F8u->~$KzQ5qe+V%mT_u1B5t@U&3G|&+3gV752|yd^U>G{ z#LUJMS5oj(XL(>-+%o|?0BV6D#I5zCM7a`TqOGSzXIEw~x%tZ2O^@409W!XrA^jF8 z8_rv7ybAtjAfH0w;lZl-A+`VD)-;trB}yyI6w$@5UkiMvb>I4C(RuH_Ef%>Qmsw3p z+Xo;Ad}9O@7D1p&7zKHi3O>yqXIW676TYWNc}dr(=tNK<39=zE#yxXmYkd=%eDF>_E>c~>=!vcGv!lOK6 zfk(cIE{}zo|JX%%^4uZku~7>#e0M3Ex2i8_f*vabc;b@KdjL^hBS+aTY5Hg6+J3%S zY7}?UWYn$y`#0@XjO0ZNOlcL8z4eMZfMSx8;JZR8lYk+#1;OkhID7Sx|74H-gMzce zZa?=zJdO!jDb&CIGSPLHYUl617ZRLMsCoJv@$TO`@jk!mhGl;`>+bZ6JT3059-#`- zDlEKQOSQc7(VswBN=ZRd4ie9qMTbLMBahXWSTy0zH!AuSueVV-)6EIgHGEb0b6kG- zf>ZX$emdr1#fS_fcn!PvZMnTnjGC@OBqEno=hslnPMB{(ynRc*&V+5F9Yb{_zyjb} zBi8WG3{>0+bn|(~&SOo&#?Rl%&2`S3tZ%;|7xJ?c&hPsZnA*p|6o&ex-z*Dga%@QJj;s#1&kwqBdRinIYyeRqC~7Zj^m91aBlV?D!MuNL6Ri z(aX zcKIR0r@dZ&;Kh&=6olR?2lLz;LtBjggIC4ppG!WIa$T&SS7dptvC&d((kJY4G5ymP zx24i1$nD!yD5bKth=gGsthIO^muG^tHFT-M%kg0y~7RN&j zmrf0%u0)fyf7Eb6ph(1F0JyRnt?iwpF0b&GJe8;xywDS0GD=eQRC0Dt@#SFLyPT{o z86~0vK6h{@THAA7=1WsovPwA?(D`JEB+W?X+meKF2*PbZ5#Xpm=o$XV zhQj>hUf(iUjnwstSL67c;O)}!K1w;MbZpWll)&%3cyWU5zB$6jk9ZZEp<**~P%rnq zebRl!M#af|kdjx$DZOd9P`V@Cvi_%y(-WqE^8?^66{60KLz9I{HonVamKTGQUpm`aEF!#$oc;0Tj@D=Yha+rqv?YLm#%x`*e~sc6MbX0 zcVdVHYmILL=m0_^@>!AaI3u4mQ~I#hj^u|aN38m7$FG5`F;pvthWGNk6SKc?&8pD? z2oR8?j?dyfJQg^QdGizFOE!`w-zO^h#=a+ujVIBw#Yr$fwHivq7Y0u8{f|O;$A6A0 zlZlW0_2mdAbWCjNNHxveYxQy#OYL{mT#s}-S$QchTyP(xz_mp^C!djYGf*r(X9%aK zdFNhEFUBMf#GUD0=2fJ3lepnqbt_+OcF*MQKInkcgnFD?k&>{m&0<`nMZc zPfu-l9dth*Pf=>HIMDF#VPaA@Wxen*FTT*t-EL7F~|W?9pPC-BS9?Kznm$BV*?JMX6t4- z*IBbQt;2d;R%zL}e!W$GUpbh42N&ev{X)FJF-XH)kZY>eea+K2^t>{5qAdH|iyIPZkHO+M8_!h6!#EqU#^OT)L56bl&O6-9T zFILU zNzh{f_0HxW>Fd^a1~(sWxaZhOg*QF8vXFS^`kaLJr6MNIj=nl)!~4L|6Xg{KMR~BE z8!_m2MfZ=tN&m{5JXPV$;}Yr)Ttpk0B&WB#zgwnyOnAHNKs^@dVtCktq#ZHx;9S!W z)9|y8TKpU8UM_ZfrY7wYHtY4&JH7J9$s(P-G&|rR0)ObR{>xYa`uj$uJvOTGKEJ$y zo9NEsx+(ohQq25i5woS(tJ5JvrQoC|l!Wj;a<2b|qhaS5)sx}8_8ZuK=Xe9!O~ok; z-x_iMETWi`tGhOICbV=H@CQJ51Q5g_75-qJw)a{|)%WD^9^j7|;Z1rbj0Y^7%Xr_# z6lwZtDfS}|1aH760)_pGd5?07@1&3(%A6u^FDe5+Nb$P|`i{(u7gf6(cq@h}< z5bFNrAEk*B+%#+I(s*fHrs&oSBmSNc0J5N454Z-38IXNh5go5!)S*ZI5>%y-+f46kq zH~&ITnz;$zj%1=VKOLJrq##v&jJESb6PZG+zB#N?4+8%~k*<}@*j=PVA5uG4^=mx<) zSt-H8iiTk$XlH_l@$-BpOWRQ2hI=Q@tD7tCh!OIHjPCAmyV#|>)RgJ~?t!kxNTR~a zx9H%r;&x{UU$uN=TSL&JOiP<>%qK*F0EHe49I}+0XR*kBU{_&a{MhFyFrxVM69;K>+~qTkAMUEA_j%OXP>?95-u$ZI zf2&36Z&;!%cL?R+v%~jr$tvp&CI_<+`*xUx&*|m$6w4Z#EDYOmOO@vrl`q@^7y|9( zL=mgSyAQoi$=qx&9+a}%I+7F5==cjy@390#D$!i~;Q2M7XvWPO^ad}a_aPLJrW&-~ zxF$hsp2$}s(iI}!BCgZlCLs0GIo2oWg=aBKPw)gKtP{`&p=H6r`58i-Jg}b+@Zy{( zpJDOTdKwKn*H=A{lQM0HAF{-=Pqqpg%yRkxa?m&ed7sKt(C3Gw2=}AD729Si->d3D zGnPj!lpd$DvF%$)^m>*!KkPzGfe-WzV&paeDFD%@JHtB>CcB@l%KX$ATF%Np8!{Ik zY%vMSyXvWZhKjfxoG$Qr5C=b)XD^b63wpo*dZk#*&p=&4pKF}YyaX^B%e-w2(g*tY zcmpnecbS0igLVdd2%{zpsqhKkXLsr{fB%ydDUujAQ{$vCpId@E*X&bVF1<*(KXvn2 zA#lebDUBDAD>^cB$F#nad9}|r>njjv?>&0dqBp%_!%j-sDE9JaVq~l0SCE5_tB8Ip zuSM^}V4-h>NfI}~-;2%pzcD9dCjOoE+;O~LGvY?7>Lv@7CHI{*0*G_(#RMAP>jkG4 z2&4*Z`4{p{+7)VFWct#>p2JLg_j2{3Z23+d@IS#U;79DhG^BwFtjkAXQ#|)}!9;!L z79*0_V+kL&Xiucn1o<0hw|(w(?j{0!v0rEv^*+Tkq2K#5gWZL-fv*KTDXsNs^YV z(o}!wF@yIP8Y3O1-FiWQ4cYfA0?%x^8RNR*u?np@@0+E(4i&K0icQZa{Mf#3kTa_W za)8$m`)m^8d5GML>m`;s6i!6))z+pyckYBm`zb=v&&uq~q->r4ba6;-Uy8a!5AQ9a6uqZ)r7DbK~ z&cf-RH*qeGVT;~-tZ_;hr+ebz-|mn%VsU`egy8{2NDQG}==XEn#n4W&?74Q47Q^F4 zBDnl}`482R#+%t&#=L*tRM6K7{K?e6>Wp_% zRyBu>_Nm1`trKA&T)L-7CJdXPc@UAFS z;zjVTes-Jwfzvp6eXpK!C8*zSsz>FSQ_xqnOTAvX6YAU)D zsz)tmSu%Cpzp(m*j+c3CKKa+w4F_hn>{-{@j?61X3QAo(ToG%?}xZ znQqZ6U9oK14so-E^9W^+M3LCvPb9w*_RXQuKJ%@^l;p=rtj?b)`GqWj(o?TF=TlbK zt$39<=nOy(9$dtHt3VRxK#q9y3$B!(nfryJ(kw*}r=RNl|Jui0RNG6;eEWXg;hFLBXCGQ?z-juv+Z%xsQp-qFQixUQNke!U!IfF%L zxu%QO;+QWX zo?MWZkiEtNb-ewFeLS)6a633Je+SU#(`s&Um_(5m+kPrPPG0rPKNdmPRKJl&Y$HFj ze_HQ7*4W1d``IZ6a!X4{rCcmb=&FN_YbL>n?ahcGf$c7J8-wQoZwXa(aBD(^Y)EZ9m`6b%THohH4KKO|W2ek2w-2=!$ykQG7j-#j zq?hx&w^R0&O5+tcN8ryv+!SAqoXb;FpDJ`7tgu{`yJf!oK(Nm19SwG|rCbUA!u=C7 zt{pGny9Gewpzc@iA2JlaK|*qe$LiBW-EaUjj* zc^Bnp{Hh+cr4ntgO0PAutlacVtq-<-n5ek`$DCIZ%n;Q4LsHRds`#VV?wDl!1AE={ zTuQ79ZT?>G^)I}Z`bG4&Axx6k7{=p;<{L;_aC-{c%&Hn*kficK9g#X>fD!K|>jYvz7$z3dCE46ERK7^Y2`AYs>RFYrJRWe>vRxG$`tG z4eXLC&$qo61kNC^)lt^cBr;9-yqK^u)+_G5bUo+C;=OOTRk%-U<^QO?xxU=;>&G~z zId}p1Ae{tZ)$bkMV&xQqpl=>im@Z>Pxic;sUv2MJa|sGty?tRI6!%2oHd_6eL97YknsEr|Nh zJT}8@oIP!?kKHtS?Y%}ZfO)|35b8ZpwrNmI2?0&m84`|lCrjF?HD8%eO}ln4oVg!s zST~(zIIk#I^ZV6H;K)JuzAUE0|Nl7&9{*Cl5mv&exM$n78Xh)FhCVX~#?oO+KK(TZ zHfR_sB1%0_j>=7g^;5tlZg@Io{53=4vXNgXue0t&M;--9cY_nm&BZ$GsSw$PZhr#E z`h7zPPaxOjbc~?uN3@VgT@Wu$)Jr_R(`2s$PI5;6>rE)@yws8la?-$nK|NwcYiMo4 ztS3s#ehV|)ka|lY6<1m5-A#(&*{~7J7u>NOM*PG;%!1li{D_g!3Q-(n9SANvxb@Cm zRp}44Xd3FpvKja68?mo!(PNwvS{&(>Pk=TAg49X5Xh!y*KHOOMJbZnxrOG%H{A2Q` z&&J1@_iQ-&v;=&4prWG-U``acnyB;S4<+M}ai()3nw*rf?Gh{78YSfWJ}GfKoqJ;I zo1OlPkZfc99OQpX^HYa>Lyz+wOHO5=<09vY&j$Lz%EstA$Io+PzU-?x!tz5)2F1_%{w+JiTXPa;yU>QV_?D^8q zXt}+4?8}#wbG&rouM3cn`iVK^_?_#s=gd)eb3UT7lGj0d>XxsW4%;v2<{P$<~&n z<}-ujs*}R)fc1|8h2y^U%z-l?2eoLC24928Xy-@rLZq40`yiedvI)!78RJ)Z?uO`N zFnYYRC|78B?ot5iSVmG9DDem9Jq&T~z<3N2Q6ejB_w}>>o|eVo7@w?b_O>*SGj+i| zGvb);CIf0!28wwhdMEU#n1|bTQpZyH;NO)`7z~~kgFloXEOL)M*ur^*K4w2*}aZ3N6T zBCXKj{Oc<^CG1)^dL-!j5cNN-6X{II6y>Bg`{!qmGgJSCwrU^5iSi&u_F)5L7%w(l z`ZKGM?=ie_f%Rf%@3R>^jd_nOhgCezy}c392Dn3?#;{w+BjL=3}Dxx&m+v> zDR!-RbdQIeQ(K_B#hLK3!r}(GoSHSr$w6^6)Op@ZJwbQ@oI{L(Sne3IRT$@?l>#FV zBNjDOSzwgJU~`uj&RN|c z1C}3$=!q=OUtdBt+DSCJn9z0bL!RgLx@nrKhXbeHmPf0&=vu;ohc=jq_3if^eE>x} ziS7z1Zf*Hm8htz!jw!365grlS)A*F_c;31=ULQmSWTb#Hk5Yg$$;VN|J$%SE`@en; zu+tpT0d~qwU>44Iz{gSz8fAx&ceioL{Nn**VbZ5!lkEI zwvY4OdLYVn{M8D$njud{7zs_(AEmfbDc`QqCgf%nu@QXpl%bM-N$sA& zrotYCCU_tX9dR{p&7of>#jr~kuX65Dv(bL<+L0!=}a&8Ftxf*ixM~pA9whnsnx<~)(CQP@CcwlP*4_{ z>FmjPiRRKn6UHwe#x9&O&YrRAWm(qsvhgj=tLqk@7#)H-7W}~cIJo5LvFPEhmuB;K z`t)zsH&n2m$kQ6EN8nJC8t>{{s$_X=G@wj2igYphRvD6~aY`U~|Vx{n!r z4pg6Fv*ZV8Cm?i)wK5R0GMo|>M==kn@&xt8Pmf|=3|JWq7kqwW!12@M;$4DCgYwly zfOc@e5eQnofL;!pSjmv6JKW5oKjkC*r=!@vzVd3gT|0J}LNu2{wnyhOU@d?Y2qauT zDpt_Ea8|mg|1r<%+?jN}x$~NVv-%qEe#zY(4|ruxMg zKWangx0%aClQ#4yV=nAWjmO=VExne%W^rQIQvhr6f&qkbxc>Z!HvFny*n4*|*JtMA zKA*-{CCxN{^F@g_jJAc;iDaEaF6<#-CVuezpl;7Qq~0a0%aB+w@wwjCuf>IUYvtxI z-K8U);|$O3xk@y=>hZnylnvwnGaW+ZdGu+ZoEn-G_?}) zi>9h*^8E_vSZEA-=;$9tTG+sNk*beKEdPe>7&NRYh)K#__Q~0x;FEM1ns_}KU}u5> zmX44du+>oC*M#Jm!oF)3F{YgR&JY*pc%LS;%I7kZ9u+aE` z3x;m&$O8&l3G!1UH(kGCmeRpf<_qjHe>;T`r+rZKih4yzy$LjA1C{+q_A-tFH z`{(YJsZd}(t!1#5SR#!c#XiAYFrYMj-TUgXdtiV={20N?egS9)9Hn%wDTYDjFcdRv zzE9cXqIBuu?p(f{W*MWF8Ku~#$3RTsq23xm^AY5kUFkoR1SZGY4S$YXnBSliSY_s| zj^+@z8@t+N`wtw+;NSp@{os6M9N7TF7?>6&H}zsRv855hEiRAPAtsAH{OI1gR?dP z=l^CsAAZKcf^VW0ymscSnAu&f7A55<-OuC7?w*-!n3V}%I?G1rC^zrFI-I(ezJ?9sGv;a`5G;s4uT${CsPe zPJnmbdfM>;Uk0st7Iw$YNA;4QZ`Oyh%_tlmwM+4W%u10A)utwVIHjb$zxTee&%b|s zJ~iMe$ydf^YVdXPLlHVe^(TKrqatM%hqF1Mx&k;&+)f;R>QCGKv+;4v*Lsp8zu5a) z=9ul9%Y26wu{V2>6z~0c9y*o|CX1@y#5?=<0d?1p{^B7yui&-i4avusIF#xNHg*!j zSx#!vksof;ta`Sx>__6JoDVOXM27`5D5#UDKYvOQv1Tl@XB7%a-G6=s00$kMvCr?( z?-U;6`LGM8MzdnAEX~i9JZ$0{r(}-p=MW>LePVpacpiu{((v3MdF-DDkjn4>TfQ{R zpAoqpeh2(|UW#ARr%Ss2xw!}85?|I3yFfx@U8cX-#&db+(X{#F-otfvnQPk8mJr9! zX?k>>**7z-jz*APdODA`WApRXP0eNCuE8mR9K(aD&y1qiIdqO!qTeiRO&lZ(xo||E%%WZ0p!v(=yOt-| zP;=$FluU>4NAPv>iU{%}Pf3jzTGeU`BwJLsr#aC3=w{;WpJ{sN2LVOC6Vu zj*T$WJm)I8OmzF#Sn_Sd0RnydK8I3IHsM8_1(uk2hOyf)FL0(JoTVgR^br?Y+Zf!km4rDarL)E672DCc@zxMiK_#X8&^gK3n(ZJDW?Fl?6%MAG##h zKG_6Cu0pSIDq*6b9chr05drqY!G3umUNRW(MzXxt#C577l@mO7=7b#PlTO4%reEtF zmLXxCUlB4_hWo@T3bh*!UN<1J01*Yg;WW*>=ds&JDYwT8wmoB#&ZwYGS^DnXweoYLGzDh{~6K$$?U#1zzA zLFO4}&VIw+Z)QWSC~W6*7O&7J>!&sBNuROT&YK*k`nd#8IB>^!kbMXoCOL$%|KE}b zSVFwiUy;&7u#P?DT|V0}Ee<=QRsji_7aAV^BC$0Iv9Nz|BL-t;Y7_JlO< z!idao}Osdd`Bi4}cK0qPJ+(D3iY#G|EL3P3Wbjz(r<;o$0 z)K%q`x3wBC=_g!T%D7>_=RU9N1osmdV^AypV8838QS*fFBM*EvBS_sXkn;(iuQ_+j2!}M8+)y$1OGPRM*N^^w z9AalO^VN@^!w#N!V7jATs^x6-JbUD-S`tYY2lUvO^>!4uW*^PReIS3aa!2VC{S{Z% z)06-WV46s*ZzKdI2lrrnEB41GO?5%a_Sn>@?dbby9plQd!RSv3YfbmsqOsv+6b0@w z5^E`%MY~~tH+1L|Y18iv4r)!yXwcmmeR5y=T%~eAdg$6Mr~NEWZw6>**Ha_~M%1JwZW^2EiX>m}$7_??_6 zbn{gCs@sbxuBpB(!sQ8$#3SXit}&_lxn5I5A2XJ9N`&aeGR5>x zd4j~vK=%T`n!;e`qK13rj=rqf-fR)y#Xj#jtYx(+Y?}z54As3DT0y{AXsmfkj#C~k zj|}v9MU+Y}knXp#qBLtCcsOOBFO22b- z?~)7;f!4~pfH=#pctgSj=`6@W`UGOXht8noDiv=ec*hoH%$i=ichAILs%Mn@?n4v9 z_5Aa{^c8Fj8$oWr{S68PMf@Q_`2z7@V_-aXQ>`E)Q^049mcYOu$M{Z$?E$XA3mEl` z7-R=Pvg3eI&l}b=lvYL5%67c(Y+u>`BkaB7v3}dQab%MfB4n?M?9sH9QY2)HB!!TK z3R&5dy+^XQh-|X=rig4s+1Z|h>*I3Y_wRXLzyA34?T_>IIj{3P&f|C=>wVCaR9yLR zdon_JLp@3QuD=Rt{oxNF)YG7=ebb)v+Nbs`Nt5I~VxGS8uSIFE%C#>t-{vBPiUK|; zfJQ1)=L*qQ(`mD2T(T!+u;0CifvUmtAq_78mp8fQE=&wZ!oG zyx=~;kHa^%NjzV3m#7g1mYa#x6N4wq4|oZY^f~CiLUNd5+LKlFac4pTn@%q_J#NB2 zr$az`y<3@9D(Y0WUuJvPeq8J@pp*O+troL*cN%{>@T>&XrVP5BzDZSReJnx#mvz(e zM!^lu%lH`kXcGwIP(SZmC;B|885ahK*E)k~?^J(CoVF&r^PM8!;`Uw>OIm>YhZXyM zlnNCS$g$M5qYLu`Y1%pGwnLRrG zXyvNnI45}fqihRj#Ce-gkvr^^e|zgGKCDu2U1%=bcMk!Bqv8p}u4px-I{RSariT)H zCq~m1nrBNl>+(Yk^|L1fS4uAA44F_-!`Mu))hKcA&O$#ECz|ZOQ~~Oz^U2nMdD63= z#H1TbCx%FkYsY*huHF3w?!TZY)YqWa`9psaqHccC`~LA;TtD$}FfLE0;CURE=kVGS z+@0X41W|#j9SgG1KOjgG;Erx0)NuJ6FtTG-Kf%k!_>Nn7N9Ou{rb_=sHJMw~1*>*vH!*^MR3NP#ME$TZ@d?;nkNcJciOM|+B&@eRrA3Op#f7Cj- zHi;O2>r8VV`DquYp^F1H9JB64%A0t+zue3G&7?0?+=X@fbeE{}7+6DJHy3MLc(o)2 zk-OGOG1;8(Zgs^!xBuo^1^x10%S%q{WrKBK;}Oi$4r&`wZ{2nCw_J9WG|Du;(~a5s zEXGtDxCPMV(@<<7 zzWS={B9Os|9!BBjKcSD)>(BJdN}bF%qpvXs-V%3gnK&p(G`?88f#uw217(!&;d3&; zmV&qp?PzS!DQVL>n*37zxZ1!;-JIg6nIhfo)i*M$Lze@Jck~n|_MtBSA+>KsCK^IY zOslc8Mq)cq$(5Jf_(5}?@BVWFiLREW?Ff8#E2|#>1tI?WUSwqKfmPP_*WdTl^Dc65wR*d>S1QNBENZA_Ji0XoOIo2 z%Pai2mt155OuIkU=*1QWCrqjXLhS+(Un>I*IwfNIU}lTCorCKV!w%{mJdD&1Syg* z+56zR#MYwaqDu1blPd#>HQzNKM`?e09=I}(6Zl=3!7#mm-5hIRd_S`bn?ri}w~#S2 zfKf@KZ6+BwI6eP;ne>}c`~D~_k|kttyeG_0{YUsRzd`e?8V-JV{K-qd?Hl&u!x9 z4?Xk;s0xV&_aKxb@SJU?Ei?G*96bC_Mb{frkB%@r?;jD|vP->)s~uv&k?sajWJzcU zLa8h7qtFD4jUDLic-8heO4>`0}M=zm+~*zD|=2Z6R{|)Y+)-Wv!!sUwfx}?jvT$ z?$cNk+QX+R%C1!L7n^x>B*$#B3eUI`Xu&#Zu%W2)|GkWi2cpEn#*o0e_6Gio!6bpv zfx*I*BSE8&j}ebS#!if(d4Q@=>>~W}-=D7+wK;XgCd|-LcGY|_efIHr;lxAZ&em<* z>l|obF-~=D`$5MUiF-`lFJ5StHpPE%4ExU8$b8@6uUD=9!%47PKxBawPQ7VI3+y|F z*)(6Bwjjrr`7px8z9Ar`m)=U}5L z2SHB(Q^`+cqGFW`zeidgw>vD_@Se(yXBUtYk{-|b%9(<~*&yixRj+dk_;cOs$%xf< zgGR{|{;^?u6v;T}xOseD^MjxT1U(@?fMgqY(HnJoTWqwvUR2I*ym@BtdV`!*>rL^Q zikbeWpXa9NLvi)M@WGf51Xa22kq}ZqE}KB&zapL}zI}o41a1l`>VUvC&vdm-JC=4` z4DGt7&K?`gdK><|O8*W`5zYOZHCu9-N;j`@#FDdS*c%V2CJS-m__&_NtuMHx?FBjt z!ZgU;?rfm(A0>CO;8_-@#LCi_*c9nKiP(ZOq?jxO7aSURABAi5^?~fdU@IhS_`ww! z)ai6^p!@&XPh|YhpM!I5IldqE7HD6d&&+Fcqx4?hBdMuf+EJJBI&mFu&^E^0H+{78 z;-O}cU7ig3{i*9~_V!1!2ZhY{sGm}N$*3Icv%_&J$@wP}z8~}yJEV;nj7LlKwrk<^ z*w6b`my|I6zBX@s7KOo(n~BFx6g*$euX_hF21ssJqxC!MtX_4o?(Tj>Zdi7d_u2TS#7aVsul_3l-@ ze42MB9o9(#OCU;&8h20+9gc5&)bG_S-O|*3r-jccb~V~lwDfg#hcER1_NA=TE!4!2fp5AJ^}qMko`+sDyxy4e1|BMw0n(E?U10T_X(k)J5pTxwUo3 z4YbLw6nwIn>cH+J?Qv6FnB)W=<{Un>l*AS`9&meJ}QRK;~_U{zs#r~ zNgXkoOTfXIW(sLH8?A}^qPkCIkUH`gE#hZ zCFHMBF}U!0^gbV^Gs_M6KG1V4a;qPW9LP7&7b>Gmi|pv_x449#^A_$;LMPN z`b`jAPwLJ}=_D>1v)WC5LsI|wxM;lI!px|#7le|{PMTyuX_u%Rjqg9Sp%e)(_fV%) z;nq98Gh^G>{5h{FtND+};QI5^oI{Pm9hV`7wl5~A{S5`6ai~D?4KFg?Wg{M9cP=;P zw@*7r{R;J`b?y1SY~VhAxYf2F6FY1t_J&{#0+;>1HUF_U3dBF&sYm-)$U^3Z?A ze`B`@Bj~5*kI#a5NrBc!Vrg!B=;!l*w3h_ehONtHk6W&Ru_ow6X+$Hfczejz`ifxI zztew8b9}7%lbRo8f#Fl-Kjmd@%OdQ&+g_7XGi)Sp?jFs;0{Q` zOh_aIx;l)mM0&ETxa7;_^)^!R6(g^xXROv!LOR@;`BRG5J5L{PcL%YQhALtNr-XK( z#W{0~!jO;s-Y0##WJZ@htTT4aCRpk^Q$k4Knq|b19IIL&xL&(iaKi$A|d|X zE6*+^<2CWfFdo5@wtJ948U#wEe9a%03gOD4_`dZ(fCK#cLx76?I3Y^VT0vf6K(>lra2d# z$_g_(tdj)kN2#y$Ni?0sF{#+-`~~v+*COSYntqC|&OD@8!jUbsbdXM;c`_#k77y?Z z;vH2ZMGEk_ERiKLEh6=M=3n$x7M-tDQ?1B8wDNZhPP(Xs-(=4W?t`2-%m75aww_2- zi~zJyOa}|eXWW{!%}6c19qy^l){|5!;~jj;&)QgcBF!La4rJJn4M!EvK;a-NXe5P& z%O!z!_)Eu#u|~4?;Iaq8@tq8R8Vw6xP-D6)H|x)nKE#*VMaZ8Tqqnr zPD)4(sNwj3F-#xq7B#C;(5_Hnz=y^gD_gtty(#hX9dgYiQnQBd;TvrZa~;^2hp!}w z-WoHsHjl$Jwnu|DSzH%WH|f+cJ9gGk0`BL%6VD;9E+`8HW2mqGI%-a|{@@h5NB8w! zH^KI)k?%`*Hdi86&y(JIia}|0*`Uy{ejkNG(-=zHgFYa~{eQs=2k=4S;J*k+D?}al z%bD|6W!Np=KfI8CTKQW&n^mS{wQDHud)xKEhSbW0L-4Tp<0~&mjNZ5lDHztQ zC?8)Go=|{#J)nm?j74wxAj2A&kc}dLVg2X6QAujS7*6k}#_|^Ro{`E8r3TM4ms?ZYGRO2F{J?^VPLx6T*rGYgB zC9lzAXtma2=3xcZ56+n@YS%9@P*k_3WLOJ!>9E~P#>U+d*JuFs1Vj0dgYR%Tjv7z? z|1E(yyov*vLGh6bR%86EXxzD}u@P~;xx`QX$cmMxE1Ot`tGB#)1-v>ogbvReQpi)4ovb}HUNv^kQ$ElVj6zXq3e?OQf{z|R9wqhLH z&_zL$rsDeSIVumZlrlhEg8IQJdE|tQuyblAWV44Sjr!-owoxpHLjO8(>LN?RnZsA| z_v{vph_rlj0$S@WBU86%+fv7G9B%t=5KGE+ssJN`I%=#}77G*p#j92+_GyyXW3yeZ z`p3Xw;uC;|P?VuADMVRZ&_p%lT$w^^qjGOqGuM(?`{Hm%`x8z*Ce?GoX!$%V*uxB7 zf!uye?}0{%A16bx96BM}{*S*anXSVrdMiuSm4bN`8J$r(bD2nY2L8sIQZ->=))lN(^BF@bdT&yWyHdj`H%Pklh}f zF3NWjX7E&{h^{HVHJH~EhP%8iqt(-Ub3Q%#WO?A4;HQd-!;Sv^MDe8K&iS(!a80=8 z&XPyG77tm;QvO+!d2S^p`B(_RAUInwFZYnd$<*p;k} zZiSO}4W+8kL(a3gV-tvoV94iE|kFe?AAKTar-M#+Y-C`-WIGfCubZJ6_q znNAK&5Hg$0L}RWKsBdzA3w}p^uzR@Uz>u@gP6p&X5wjDyqvBBR&FH^wH2gmHeh<&x z2JymY>+lw(g$})XZ-mnr%&dKXbc&KRgWT5`Dx>yqcU>Q_TFl~~J64Vr<}sdQmy-{& zAr2%8sHcz@NQ#n;Lw)z3>g3?aR}XZyu#j%K_rFV#lZCFoV!k$hV$=(B#th6h%%c%0 z*)FTKKRj}Z-#TVrFW=l5))qh0Shyv0x8T`3&n#P6Nt|e!r_s&(kyEI=JM2)KMkDce z3dd(TOE%h{J!sl1^^sY=VK`|0FzRldaE-O}2N5?q*z|t=73v*!A59y}cQoc;Yzvwd zGV1=$-2KpIlc9s|H%H{90dlq5Uh8Z*a8)ue&D2fUe_ zyKD3~hKz|6 z)tls51Um2o38_b5`}>ppQ194h4cY$xThf>gw~s2_6V@Y^YsppWa~sOR=QEFeH@0?4 zwllnErH`(=j^fwIl0R=Pn2BCd%@P3nttj`ybP}*QQVyep(@xQ@F4Do zY;P@P=L93(PNV=aPO5rW=Xlyh4(i%va#suPlU*Mp(i z+fmIb9mmyT+vkljtY7q_+Wynk=g(XqSP$NZAfg=t`;Vh$Xhl>FeXT!8ZlG41zQgy=Lf`^@IPj=T=GWVvn9vbmsj0N+_&hkbO+{8-}J|AA8S@|{2%4O+sv~gOiNTQSl|3O)pb2qwT*Uvuj znTP36I&1sXjhdS4MLY4F66EquKekoX7Ip>lY9N#X^?3+d%|4oxL-!+Hc-g^LSm{@t zW*%YV@oQf!<*g+|q#{;2p1TpN?7{8BJOc!5ee*=`4}Vu-MMiB^@ZkyiTh^VgH}Cwt z(RzZhabW5L=N+*>Wzdx+BtkR4$#*DaWnV3sLlaH1KQ!AdEb3qp((M$!)ma#(AV1Od z;+Kw89%y3$0dd6V^o9%|5*vTouzsD}HgzcU`@9P^QOAQzQMyrP@5=wA`wvptiCIQ~ zLKG4>9A&=(ExX7%;!CjO~aA=j)N z-FRCuenHPH2Ft4UEa#wk7hS3B(2fP~=Vbdc<|mRN1tkl0QwP$~7J}B>_N5BUNv`V0 zg77bR%X?ch4-ScvJka^~Az@C#TGuK9A}^v)9*^j4KcExc{~Q=M%%q-NYnzB4FZ-n; zC+loAstgl#r@8T^Z<0Q|TgIUJaDToY%z-)hTw)OVR0u}CPrhQ{*@{%8<6CI2DU0|{ zAJpJnGwl z^^-6f2&fcMpNk7XBl(R00o~9NAJHztT8`$_HvttmobspNp6f4A%J5`cde3nXe-S`D zm-un?y5bj3kBY3VIap|#IDTi1JN=DaHvcvD#337lR@|`B5m$-y2j2@b+MN9{uHna?+(4q!Cr+EEjxW&5 z!C>QeeV+LBXMaeeOF`Bi38a**qtAtDJ;=z?bgM(Nk7JAN&n=42nb|q zt-shWN&+@ZB(LzU0v$I~RW`J4mERr58ZZ#$P;C;5DfuIH{}MjMm3zV|TBaGnkYEz0 z@yKU7l**G%%;j|Pu8bBtbVRk7_L`>|i(g^B{AB#YwTV7DLnv^+hzWXY52Pe26)jya zBA+`s3f^fhCJD*)qo&CfYu0~BD}CCEK&FQ^f5SEgwkHdk9JOvR9DQw4nDZ^695Ier z-sfBIR)ud6A9q|Vd;9$Cxc%(2wqKF5U_OCF3MsAIjYZ?rt@($FVj9;^Cc9p6D!KEgNQ@M9tUT|H#Bv|33<9@y|=#p(*j-*aAyUD4S%u7rNZl5ZA!tk&tq zWsl>Y{YgFiKv@|mX+`7`;i-dH{^_|u^&elmMvEce{)j}KH?#3sq<3qGSyLF6rz(@5 z0)&;5g>*Q|G$#!sp#(@rkx5|6VKQCEcak8(V8U{GL}%Ng5(lOh)lVVP z^kk(eFO2_7*!onx@YZdMzdG&GJTJ|yT|5Mo2$k#(wJG-!0fnDBeMm$su93gpz?Fg& z`P5g8)ww}jW7?OhC7}2k5{HLGUqMI3kDTWttiG)(ohg{aMFG-w)kK+m=hWtp#Db!!IY>lf@r7Rti=?y36=SQ!)w0!jyR=XXA_rx+x^kXsWTk*E~0jFtv8;OnPm3<+66-| z3WfQIbW8*LD{@)OvNyMgA_70n@Y~7nvJ7xCja3-ma!iZ(`^niSF~%Jqq)`sI&`?S% zES&@uMmXB@f4SxG0}hTG6?zh_vRZs=GG*mw%Y4yTdA9?G&~W-<~v z+`=?-?#ewO98t})3mvkYc0J#xOk-lnCYQ*#=dNW&*eip8%0XNawS|@-v^61qIU42G zekDX>jh_q0FiO(iyMBz|tr5QfW_?o$>E;s1i!{tQMp+@}07PE)5!li8;UE9==imqI z9+ZcPZQp7$#UM0oy>sl1KaCuj=GrT+pf$5T*C(kD72EqW4}U;a=%u?gCwz6;oW89~ zKaKJfG`q98U8R;3dFPco{-ZJz09i2i6gm3@gzykvm{nrheW!|E9i&WE^jna6r%Fu$wTR&sjGinvNeU(`FLKAB{r1NV7t>#$A|>@Uh~azcu8 zK_;`N&SrQjx$0kK)FL7)`Tgdqne_0}>y_^(8|;bS+kAWrC=JFGAVuR_DQLT0A;L&5 zs1OMHke1zA=$1w7eS{;KLfKo1_di?-x+T1wMtO)t`_kPp)E;_;^`)OSQ2TcJJ4Bx#tbNFD z`mF^GDwWj zL{s0{okrGe_4-}wn_ga5JmyD&e-bAi;Z;cJA0M*^aL5k>mQcsplZaL+yc{FWXCG~kXJAg?EOB4KEgk^ev|;Alv9a4K{CgrUZLa@@4%%h zc#>W1Ceujsllc4YQ#e(}VI2&CLfqSseAGVS`ZiC>Y#4uG_be;>Birj<7j1rLCFM9z z{5=;^?>rs*GXS?=)Tuo&6Uyvd^0`Q+3E`5wEqBzfB*P_ikr9W*Z((8zym?~BB4M5MJ|o|OSg#!w zY*0Q;;FM#dS1eT2k9}%{PZ+<-`l0`#>m~VN*OXFyPfdWaz@CNBxo7@GpG%`5hw$$U zmx|B))v~6xJk{IQ7(P01>*lm<%{`!_zUm}b?%S3Me_h&ocr2QOEzUL^a?!S`vhvxAy- zeY0WcFQa~1_lwGCX;=rulSoyki#r;iQ0I%gl@3%VCsulRn`T`6DdKm_Eh0PVl3cIR zqh5jgkgA@_swCL#zOJT(9##9~o4XJ1W%v(=zWFVn z?|oJL+uZl=uM)Sq@_rh~6is|;ikWwM+4}U(8Nn$E0%Nc@pmjmdAKYIyGK>P`lm4BS zsflr31M}N8wwCL?l$D_ge7-NqIs>mM%%!;Q*9S@hy&(d?c8;iNN+`M?WcNP5PNmdx zvVqN6R3j7jeO(GIuRj(oqq`@q6RZ=4gF(s5+atWqa{p}iGRavZe@V=w36=JUxzn|b ziq14vBYwr1<`Zl1`y^#xY&2@!+>t+l&BBXE-}2g)f137;-2700OyI35_tuQX?H6}K z#2AjBhIO)HhlOB%-Dv$XcRli=IlFv{MEvIY@u0?&xFR?7JfFs;WNNaXUua+5Ps|Dd z0|`oAD#y_Jg;e?Fle-<=1Z`wub*z6+*eB6H9(M>^F*|87(w#$UGuDovE$jrBHU|UQ5v8P4IhwA72#F6A?LRc^NJkFe9th za`1?m`x`UvCO7g!a*>azH{$-2;F1$kG9WK9lER1l!po`Xd-pN?A&Ig1a;Tw0Ny_YJ zof#b?HFiih)>-X7iK&{;6rd-777=DK9o&0mDO%1>PGWfr8kaF|i4%Q{EHwGDR6NZ5 z_*E*G2&N=?njyI-;1g()NA4l&$Un=zOc4XIH>sRrjwoSOLyLjTnx8Xb9sOsCbd52c zw!gzVXc|HEOX(3mG+`sNgb%f^W5EaB##Nau|D~d9M&V*@;u}{8Ia6_xpbSP%7&6_c zd&p}=-(P2>c6wFPDcDNM%3Sf%-G@*!+=sU$c6Cf zpJBmQVj+|8hURA|D8r^U|&<+n}4BsMoz^uO6x6zf#fQxUFb|L5W$MT@Ym;r5C{lGY2(t-z#(sK(4 z&p5ox;DiLN8$l&rax>G`p`+aqJZb_M$kXHclFgy-b12}?z|f=@=kZQ!X3bl&HYQ!t<))*bL$BpIG75CAhFhBv}xt9@Gcd~nv*gQ zzM^Z!;;s6+BEf>ga*@+)i7eq-Z487^VXlW5QkoO_4lTmiRe`q+XW6eYyM#0vr7)=8 zag^EaP zWkAd)t*y%$)vV#zOUKDGO3HS*iWSyL!Q?K~OWQaiGzd#qen~;ewAo=RdCpYN=ogz{ z#t)~Fu=UI^{MJic@;?A^fB``yZu~o1b4lInzg$>0+I`dUXD;3VFZM0Ha8s(+xf=$1 zI>vF*$06SVb-fUfJH&EqqR&k>}EZdwlDoGhdZnj7J`zjgWtCeWKReHFTok56a8A! zxTo#wRDZaY2-UtoA~`hHmWX=8F%!X~UWw`)nShv_#?EknL7{ z9$#^jv{quu3H$^xm{X1zI{zag@9oYZj=-Pc@3WkLcmI}|P^*xAXZXnd!->YOJ0U#0 zX;48gx!){`Qm_RB=xZ;-$sPIlu}U(x^S+7bmBNk>mscf}m7I<{ynZZPRc-@-N>UPf zH&L&)6nV9v*xH0-bsmehSFnbNKb2hEB|b8tFBxC*~-nv(-}<*UdG$K#Sd5oxK*B-~+9 z)Hv-~t5gH`9oWjjZ%R zG0ISE|3u46NS0w@*sX7;?(=^Sc)vRqu|(!s_ckf;1Q+YAH!}W#5ZINHf~HZF9~*N- z3~R&W_?4c>dH&x&PLf2@iUuXaADBa&RfXrBKf5-c!-l{ojAI3Cd+;2hlF{-)&ZOlM zyg}<2)_BR%8HZgvZ|YX;T+MBV)UwMA*B=ZT0KfsJKg9oynnVXa9fWtQuVv|6qB@RI zV)20wt3^|wD~Xntm<@UmvyPKLfiahj0ds0uPTf1*CCKYwp6vbX)Vx%4ky`%9&D zaA`y?V|<>`ay+NIQzCpvO6ah#^yg7O-^wN8x~#3QVf;G<^^Y;?om}pIZ1GZ^HJNx^ z7vmCUcmsfxq#%&G9sI6|4b(Zp_w?S71m`gYw{wtuqPluExRPSYLYct4H1UrGF7}SW zs_lM25jeq6=MixPOii_4j*Hio;68|d#9a|ZbW%dPK7-zE#3%XMy;{;Aq*VY=fXxcY zii{&>0lrtA!A!2tn4B%{nDX03>Uhqn*YB^3Pu>5=tCIBYr=gTLtP_N?7SujFAW?Zh zP*2E)L5PJRLC6yX*>NW(GCu5Td?ri}2v0igN1Xm6FeYYI<#HiYy_I)T?oMObw3P00l4NM=Wy}^0D;zu9oe&6S%=AE9xFqaI2xQh%l z$svh>>>9KjcsW;f#o2dvcr{<^ioi)$_@puDeUG;7xb9NsZB20(C@GQy21dlJy{SZi z*?vy{Ft2}rYyRgy2R{In=oYgr@)?XO#;U)GBjM~Kl2LG?)K;eUi@O*Hc>^^=&CH=a z_z_w_F5=z$mr|oTSFY*R%kT8Z3_8TMdYqS7PV}byOaX-gI2I{s97jqv!JZp*jW&qS z{B8NW_o(dN>(NWQ1UfDNY~O*ZkiT-Ur+F zK*jZ(l69yVRi19>54pxGj4V=*Bn`wRRxz$JG>pq}UqIKRXPisUd_Dd-tJ8X3=z3)S?Gn{;Vaz<`(6AlARzu^+f1WSTkFD%hKhJt=Ds}@aS20Y?4+}a-pe<4u zaTF(D&=_K_{dms}aa5csExV;^8*+zK>!~|d1Fj9b(q#5A^W`c9i_7O#dJWg(}twPqD<>l@Vj@lv+yN4+)K;(6xPd%d0b~njBZ>=SJ z&tdTi$L*=Ru?jY=CX~@v`LX)u+_7YnPJ&(m>jIsX2kU~428#ge)Pl>mZyXzggb6xn z>%3)A&!-A(=#bD#HJzp0={>$%AQzq7`9$#UrxW7hIOF+kP7oS zpdQ|T4CXq~+zTX3)tz~2T178t z!~9uf_I#=stdoU)bkutvJ?eOG`o>bx z@8e0~!%SyALZ}aRlp~X#BFnG(Nm9Uwf^cEBnv6`H)9QM(r-^>Yi_$zQ2tZ28Kxr)s zzt$cF%+~7HUAP&HlIU;E=V!6CT5{7256SM#D{oXb5x1ssgZ_jL0T^X?AfNw!qdP5m zS)JLw=r$(p9PiRTWkB(A>QBARXr2Sz%Ua5*h&Uxe3L+^H$XFtb`juU1zvWx4Hm`!| zhV+eu`6W%k$H^CE)u)?N6vKLaS#(-eXZ7HNK-`BI%=97jMXWHNeF?=0igS7+u0_KUD6O#MDyEe6D4(*--CS?4hK|>IDD-q##JEK+ZR`B0PJ~z4~Wc zn-F0arp~3oxwN#udwx>de8E9uYvs;1%kBHXOGp5TkOu~!A5yY+X__p>IR+-~V2go^ zdjav@)#D*gwq@@M^xg|FN$r7kB0$-Q0&FculUZ2RHKI5Sam?fC{o9g@9uV^OteXm( zhLWc&5KpVKm4JeQC=3jrIk>-fpV9uRNc~miJ7m@Ul^;4L*cmh#WlW{UY=fLPyX;i6 zMoG8Mz&fBkK@@0r7|`lQg6Y=S4BR$aEqR8E%X7V2*Wmc{`)nTz01WJWNWGrfKzNM)fkB zYGjkZ0?dhdjcF+GBV(m1)bc@-ePzYKiaIUM z$e{ZAOX00V;z~8kl|!VU7W89Kx%TV)7va!hfnEDs}Ws|+qW1n zwi_h~vq+CBXaN4uR1rlC|KBUWhI8q6uzv*C(=ptv_|q^WxA&S0YJ0`zq}+iM3?i3fpIr1=XB`L8ZCA%&5v-iT}a9|Mky>4Hw5eESY{h zDYEoS>vXpXcqzdrx#%0Il&sn>~VNyqeMXIq|}Y|8xdr#j+|Buda-_*RUA# zu3A>sIa@bk6J5?AaBBF#S|G}MAPKGXE&fI{u_}F&2_|6)Wwq>&+AUczpLc!pd}KNNz75IZ_-j&MC1 zbEkH~`r#KA_NN>Z$H!<4_Xcjn7H#plsp|ZDWR-7dsx$`Z7X}R=ti>OGksZFy@rCj4 zxKX#poGuzui7>kBT-9wk9hH;m`W%A#RU~9@D6oXZXhwt3wV&*_HmdF!z4tL^jA)MT z$Jvtql=a{w&1fGf8&>{F^=}X?1ZXFKMAQ0W(MHh2h+|5uDmvNL;uvd_ivPrv9)(Iq z8ymCSo7FE*N5#QQ5{9%9(&p%viC!n=sGcJ&9!E0~Oq|@tF=ViQ^utp%-$QT` zUINM{WmKYiOhD?3?a#Cp7_JGLXJVb5v64p;}yBT{u0xJ!I^{5-*T zd=iaB3YS%=>(!`DtN&c-xZ3{d>uqjvD~q|eyz2*p6#9>XKUhjl{IC(&YGB1G3W89od7@`><@`yPtT!M!%X8Vj_|i)q^~YK?(}9A`t7o`;N3u7 z|CfH157&k22B-!}S!lyVsk8E+GqMPM5*S^5-35wBpn6ak zVUBD*I!85eq-s!r1yd{!i}U~Hp<~!hIQdUV28ts~ zW_u*OSS!zCvI?)9eLpoC`=t7&^|<~#R1wMnN%ev9T5UzY?u#nVe%V;pp6PMF+syO) zQ^8qP6WlMRO6=t_Yn>`DbpHZ`1hOEcl6eFv&Vbh)a|Y7?oKa{w4JUUdo7tU46!t* zA{0RoKzAkj`phYZcnpQ=zv1D#x4F{T-uwIO4P8bEujyjug#>yn2PIf11&=dOc-pG2eu{iAhoDD#qi=H^-0_%9!>TJ4gV#( zGf}jG%6P*L{xgk_XO(W4RwV1b)nEyRn1P5Zhw^2@D^MwA8faX?{CHXMMNKjN{bc{2p^nB>PFt5HmS^=Qqr{-*OI3 zVQsO?dDpRg%X6nQG7N|nR8oZNGX$DRA_f_LlDU)8Wq^$VT4JOmV!R5i<2c5+ynHPp zBa;<1&3~J?kV`ydF)eqy^+B@#5rfG|y@#+4B3+10%Lf`oB!V>f?N7=t744plw@R9Z z5zWPfV)vzSLKN#}z{zme%hl{pr+VzIm^_)8 zKjW&R2o5t0a7>qhT0Eb(*SdeN9FiNIt7Uah(p9u*-4vDY96%SBP~y35tGaE&n7 z04Zgf8bB+pdNHl=47#T7_$-0$V+KEqp|L`lCxriTv!Ls;`;SO@7(MESHL6a(BIR|VcNq85purIQ7(OI|9G8nObg$vf4q#~9 z+U(je;SQg!`uM8i_OtoZ7CY*V6I1!B&ztrc!1$5J`5S>2@VWfFc52SfY23{IzH?n6 zeTDvuDRpUXAN7JQSSIj=>A^(pvoa%a?Ylo(N;Sz7Itasl5@J)-W^yF;Z+3KS4Ti*6a(z-*Y(GO|PX+bf(+g2{|6q zAk(KtK>+OyNSrHR8STcT&qbPwbiIFWKT(-pIyFZ512bacMsvYc4c}^|h6i^SDX>H& zX<7r(GiO+Kq#u&4uk<MFQ(Fjfx+1{^%1R*2st z?h@CR>qf4xVsjIGhHDayJnZ9F#f7f<#J*u4H1E5k`_vf-5cp}_+t9>j*H%A;;hnL6 zvm!`?(?0jKy*-AYNy=|fMQN4x#2YaNh!X=zQ6Zmh;XR4QX;dVH zANI8sfk^`$j1Wm=rl77F#6#qqhi4vzp!*fpdYdApug|5exI7G2?I{@l(R|f-%@n&I z-T+!q)c4|%crE-sJf82B9-4O}H-sNu$&UIwS3aNVfB*TF9tFM_8|~>OV^|0IK*SU# z98Kpi{o>Hd>#C8pdUv{nSvYhE-12rn^mi7;Ab-VAQ{9HnUxnf+;%3=;m=^TJ%S^pa{wtY!#;SpC zmmWuc{w`IOG{hriAn=WdeacU?7E$9p8!zBiH=gb;SDHpNeYSp{yU{0ENt5W!hzTS2 zF^HeZz|TVNd-cc*rrkVkF`!&3mK}8|!sq<3oI#%BiA>U}SZ$r(`lPj7e_)-sm>A;8 zwH-0Gc}MNdzV0TKIF?Opc|)E-EVYp0pP;l%P0$-PfxAhkARj9u1tVZl5OM}|6B5TP zd(MCLdPR1}lAruqR&OYkMq5tO?sKYZYhr41z66%}U^}7k4=GrR=|+1fW4N_Elu|zT zFPX^KR9|v>|BQ0V;Mxb;eE+kzMepCdE(PnPg%1gFKK?;#$+u_E%h|9zmD!NqBg?LP z-t^4PGs70|Wsz&a1>76ul3K71IQfx0_39CE;j^|i!(M^cPF$KVV~+{WTw;E|iz7Ns zv!@>{Tovq=1bJ~eF(}+b!cqt$9mwS(G0wD>=KYf$)V=~kg3Dw-u~K=6T144OFzRJ% z=zm|?55GWM80GMVhM~h*qBkc!;u`21Y*Lf5!~ATOohQ1QME2~ei9g9DuafWWhkK;q zA)wZMk3xGyV@u>2U(Z*+(ybu0X;&ojlykHv*-(R%-Vk$}MGRHG!7F!!VWixX!^G)-S_toW1lg%hc0_D`e z!$bp#Ym%owR7Ow*$Uxg5Kh3XAG@Jaj;2%Dr7&{!n%S93f9PMM`z7Hx|jg?dCwKgBn zQuJcLcK|aZ3Du>eiMjr&uf!^74Vnv1$xwaqX?Gj+J!Ut?&2&tjjj@#F&;5~Ur@O&iLd2v zpndA&7=_fW<2J;9pU+|CG}e3-@}<+E-0@NEBVl_84^H>b zyMFGCjaI~im{*{K2}?kZrok2MvFqn+*_n(kM5P*JZi(RgMQpxiCZo;VOT(kd7|@9Iu4&t5@z(`=(?8@FFx|Mq92%*-6$c9={&l5yJX6^RUr;BHQY+y{ zQERJK7fQeEjR~uZ8ef;vPseDMXjNx7x>2RwkR&m{KL+Lpc(z~?&%riFj?(QL)^C)~ zTg9tHd`Mq(k6owt^j4+Lk-euxlo5?tFkS>O0O;WkN0z;XQGW<{mb~TLJ*y~f6Fd5Q zDI&RN#_FupWQ8v_Yiqu*OnD}(RTI7Z@ z3aFA7M55OINZ$c`Z`Vwy!qVE9HJNB3kC$BNj#BaLF6Yh-N@D6sgYT;5mHPn~_#o;$ z-yDJbHiKn*+tu1o%fi4PsqBy=fGl3O@V*?4 z5sAxcJSu0XL@#R$GaD;?uWFlyW>(3=S!qF#Z9=Y(YDn8h@@_n)X!Om^PQ&_y_c-G( z82?zb{<>!@|E1C#JX;Z2At=T?5SRQdH2Q;?MDNdDTHeEVu5UJ}`5H{cDA4~cIhsNS zt0`8+(hLG2qEaxt0rj{Oe9+d5?$hZczl^${Z@n?t;=f@BzKSsy$)Szb+CIk3G<|x3(bv(^3sGm{@f>LN+uf?o&2bT4QJI3ycfs+Ls z`G>_Ut<`9+XQWS=$7E08VgU0f+m!N~L8i1zC$~&*zVH?o8X))>ArEb(GBm*{=--u~ zCUec&*vj$W;Ptx}X~xpnrHxg}R>`gJw5*;hM_pfq?*L&Ik_4;zhbFn+Fwf&3&S*lcTwwFmkNccv(Q1Iaz&%Ck zh%*rb3aaOfbGlj(o#sNL!oxwXULLP6Y&eBd(*B&$P5!uPqfNJ99TdzWKqMyRII4n6 z0SLe_8^B?+*Z5-a!SC7A3U~?y^m{iC#*-@o7or z*8`l59Yz);6dgW#miz;vhx>o#`I&>$_38a5(*BKYN*{wT0wP>*%16x?^>s+?KWh0g*1129c2N?i2+Hl`cU-0ck-5k&rG4Ns&}S1f;vWrAu16K|u0f z@IJhp^L^iS{akw=+50+cKkHe~teJae?wO%|KITr`AGM0>8YlCFyUzF5>(q~<+Hp_C zS?WwG+O+_1^))8fChjC{ef5tZ2npCj9FPN?1Y)I- z%59uurTaD$_V#vq_)P`9`;N6ZGv05d1Ai^iR##DcwgVa-#C|~Y5t!JG!ms?V%2W&6 z=>tT)^gc)Lj%z3%5-kiBTqB7;qxMgR-Dl4R785k)g~at}2(EI!e96`ert27qb+{e8 zScsU-tlJ{$09J&D%Pnf5%3VW zWdMAJ;mo0a`1?Ivcv6&B_u*E=-TU|7n}{=|9V%Qan9G-+r@iNQvwPSYSXwYY0-AB^ z-T}jzV4vQo(UOJ?x?7cq*2nkonbe2%{BKSRjLctSjMxdc7Hb0WAFj&+mDxe~^ZJCy>z_4V3tRr3K&{ieGrF!H-2uWq2-l|7SJ3$*m!AMJEL1 zH3fy&fA_M-e+AKZJE)(p1C^E#|D@FmCN4lcH4=~2hR%`$be&e24PWt_9{W=+iq04L z3%6)>9hi~mfps8s3t0$1sN*>}mP6}VL$_7rArCZLnQ$fp43gtlx2;w^%kn+S@v~iV zn7}$oP!S5dMH?UBnwuV{CDo+v`r0ejNL+nxJ__8_7of`swnX3WLNQk~pPAy_Zl?(vkEI+LbMD}gC6P47JJdCN2yhxht)uE8YV5nP@NEXy_1_gG**VY z7SH_tsPP4;R4R)Q#0b=8?hd?H3N~kmiU#X|N`=BY)rIiehvQ;7rB<6H99*SPrWmCC zM)i7JcX+P+dwWNh@a8C|F0c;3TnLZPeuuBK`@rK_BkC~7qkRL4DiqNf!Sopfw|A}sfQQq(~ulGO$yAqg<|YsSN$n|F}bVC{=4RhzSK)PFuUsfmvq_7lHi?Cto)|W%#Hi+z&c*w zK*5Z`a5nsws>(b`?(1qRMv8Dnoh2lG6JPX&oG6NI&dpknm{{|~0jvWbbAL1b^QFWf5 zpu%^S{Heak)gX^><*pT!5u*WwOj966pxpo%?h3nZ>sKSHiiNZAk-n*O{GRH_i(pLj zJu@E;ydRZfQGK`kt#a$Q~ znKqGa5B(r4@I!85gI&aM{#^v}&+a7xZ~&?jz%;!J zb+~s5wHJd?WvBq&``?xcZQEtt<63z{24WPxca z1iDW146#%~0ekzkvr-vqQ-G+s9FeaHjg9TaZB_TD;zjZOp7g`^;!2>pm( z{&M-}#nxdBRJFsXBnilu#_EJ^&|iKqPa~K&WnjwK6yYF`w(60)EqJ+gwd3Wu`remR z?lIVJLn=gUCY7T+s8Qw_jg(6_PF?C3F3$au%oqtZY6NECpe;_?(GOFV(m=5ncO#g&zi{174i_$}l!M71;Z2H>%66{@0%u`!2gk(f)r~Tjxg( z{E>12qtCNMI34TWd!33EdsigXSu$?<{)quPT%V=Ue0R8~R3efgT358Zch!V&CJnxUe(-KejCny}`xa zf5Z0P?vm~isKY0-RWV6WyEs?REJT|y(`;BeS8HFbvuBFrP})M$ zFs9o7%;!*Qfj^KthLIK@jq@@6!#tNz{IWNl##v5^A;|R`$4Eg*O|Kro>tgp&y=a3F}9^n3TsUCSeZ(Qsn(pP7* za<47ZdV6d0Vw>QIGs1V92Jbrde;2>iPjcoRH{QJAGp-bI>o>2FyqcES6h4}i4CKh} z=ED^jN`QFgeZ(%m(ce)YS9i|p{Y8H1oc7VzZ7x;YDZaA`1_~2^C@8*F=noAe07>)n zUH;!c7kmGPcYbs_dr@*?x^99#c9<3HA!!Ur7%KNabT1>2KX4+`wCT{gypfH`4Avi1 zLc6C*cLK?@m*b*-``PXKOX8`;#&%8+CEf(=FitM0=4fjPu0<_oeR;|`K9&B#FT<$* zlU{ps99yskZGMG%k2{}r!X4zkz<{dD<`7Fz69lj=Cbn6MC;3yy59rwyq>H(Xl}58> zg7-GvlT9Y+_*LX8&s`!=3kS0<-W70=13!k5P0Ks{+`mFe}N`mX)xhX7LHpWk{YwW_~@0mFbBkgOq$ z`?mrPuEG$t$3w&)-}=yW;2udPbnWa;YwqJdt@>Z1FJvBk?bQY@0~oddGrEg~@Z%(k z+R=VMSosrw-e8xcrr~v`=h)DX`hv!(vjRlhbm7GF7$Qi4!LVvmGaQs5=&HnrF_hU? zFgHnX2+d%im)Ji-C2Rh2SV8ch93|!mkjf;93KQU|W<@On-tR5)zDT(0W(oNt6T(`m z?=vUSl+v1%m_455o_j(v;22@b;Kx23OmrtKS6K2+_6gb9MYo_-DbTCN_|E;+_Q%TT z*yXy-PIT^KaDwx=IL4%_(i@DxQ#2C#ccCt6Ro>l+tQ1bwkJ`iz(OM@nBDT{|*nme0 z05Rwif3dFhst1KEz8Fo5t0j|rX_t<(kTnU-n}0}SCe6xU9QNHUr|6=e zVvElLX~8+5LKRO^)dF{(P41hpqcJT?Ap$bM(ww}YNcv)**-%9`5N9{S>A7gunUSX0 zsOJhenNmvE@5Rm!+udX_wIB^`l#0B-{FgpPr4O8w$+!8IWpxiP=@|}#+D$`BKKe-< zbvND+`=fM3k{}zAEkK%+1q19Z9yfH=QpeH{DY?C`gFj1$!qw|1I_oeym#9L;og7X! z8m7Sj z`j;Q@UZ7SrhZXSSB#V$*Fn(RZLXeFtiFLO`zQCQx_jQ7QGD6)D(&tD^j@KWo2)ydZ#3x9tW#laPd)-KTb8gwjyh!eA4;J2V( zi9UPk*ShMfmqa;^(@S~S_emQ@*sCQqP9r#Ez7B%Z1dVa{AT!|(qzp=++?Q3<5gZuS zt{~Uk!CVT`=MZ=taYtu6R-Jz!KJZ=t6Yw}mP(gEXDks0;mXW2$I2&#LjK?@@=iu?M zpC#iLtc?YfjQ8z!LSLUBF8YGUfkrhDbHhP_z(e66+DL`xh2Flzlk@#YZ?ccaUBgk$Y&@*<8sY80=Bs5i3g(L0 z6~McY0I@1a=hc9`IP_X?UKo0?+|Hd-$Bo~%c)UxR_;9{xspTvB0?uJTYUsCyWc&476o?2vFp^uj;3 zzLy=lcfnm7TULyiaqNXCQN6(z#4S>lzaXrX>N=Xt$?owVJTSGR@c*3l~ZfuTx-F-xIO4g(_^1I};c=yDrR!!-NbOF;4 zcy=%g^AU82hM+0yhaIF1rBOv&C!WyoWYwe=-zRsOa4Hj(pRvifZ?S{<4FH-#lGJ9dwh93!ni?-_6`ykbtTrNnVF0f{gA2%A`Uf;B^tk;f zVx6VBCZnxV8=jZjy0>|(rsqQ`Eto&*IN%?;Fv;TI0LdTd<9c6B%-v|*Vcq6Lk;OIk z^{*R`s$!QSV=eIb>C!>#bX~^*ryhU?36S%H$$G^n_{Y6XW@#7t(?6oSPKYs2HAfurx6t=yNbt7)7 zwWqUiFtyim1M4KXK-;&AyA@S`Irjh=%xNGb1As~ei71&6!Hp0(R{;t09J+vZg$S_z z>KzxYM0Ch3+Q`O|IoaqvbjIH(jG~#!8Rr$@ZCa`BC7ZL(!iL;~bH;kTuz@UKz@ey& zQ!z;_@zmQp#3Z#7?RFq(#U1{5_Y2D@>U?UW%wvZpR)`<7J2tC-@~u9X{; zez$_?=+MnVVBoty88|Qw2~fNQ3l&%R!<9pETkhhM+-|3h=3AW9v@GT2?4k=Z1k&AW z&qyM-*z-ZRElw~J7YYw}m&0#gWn{~YN81*L368g7uZwH0w*HK(;MdJUBvg%=Bju`} zU>&Hif^J{_89c;{V9R{{$;|Kq!#F{YO{ve&cqz4E|I@QR{O7?t0<56c=EgZ49rk_B z0Cx$}MK1$iHsNle#u@P+GN-vlQh(?h!+XSQy=3Q3hU;t&3=R?(7g2EsoCB5@L)J7{ zCp>$-f0-t|m%Whau_E!)l8IMevyn*$O+7;au94>EhoUlVP>ny(=#NaVg&b$$tyKS{ zUGrWy5KDO?{{<~z?YZI`ar`FI1CXr&g-)P*)rA~v`oiT->e1NH5bFG+xMa2HJ6cw< z9jSw+jgrcNhW8q8sS_w?f_0!W8Ug_2Dew%+w?=|CDKtX_?$$?t6wXwzoOCpw9m%FV zz25g}E`O1R5C9tiqOxolQ+LXXL5JZ4@ z$u(CqQ!QLcM_u{gVF4w&$e%kJ*nU=FdkGLOlCVmqe@@jOp0=TUe*ysAI}FdBoAhGcTgr9hHaTORaTjTUsk0L+-0` zt7O-^hHU`nK|vmzq(iGOoSTr4s=)uVCf_@Izqt#@`FB?dgJl zKYG~DlF&(zhK-g*fdcuQ~+HF(04ochvdl=BYl1)Oo^K@Rr_R60*p z>RHT4H?Gl5I#*`70WpyPDG~??wa&wj|E9mUd=j0M_B{8oUtw=!>b;W+Q$bfE6%l?m z%<^Bl5?~!44+q3(^1l)jEUpK+Xfste32qJ|U3;0579oeo>VL{UFJ;Z9k`~GWf?E;* z=s^{GQCAJa4Qu@t*ir6S&0(%izK_^VH~d~yug_kvrROq{M^fwn0OI-NKd3WJ{V*J{ z5pb*fFmy+$Et>Ijybtm`d1~-9wK{_{e77b3kdJn%46Ks@!B?1C@I8TB&9pOOR)QPy z6n1xV<2$^N!i*>RG`~xl&5}GF%z9*K`3qQ0@HB{K?>P;>uGd$cUmhv*XxCA*k2y1| zeoJaM-(VZmBG!Kr5Je_>T6G@$0yQeIYn}u#lz{qj%6-j5?7#nR3^OnFjLiUiDGm z->@ru0Ol5$O~?uig~In~84&a#;QHM`608$V{WnZVBFAXYiL-lU4m58hWk~%51a28X z4S<5|F`xt)f_x=r?i}Bk-AehN4-d}TzWw`^M0;Af&HRn$21*F3_C3(zOGfsxlS=Yc z%@xNNses-In)%Wh^b^ZrBSr)rR!KVUw8^pa`+X~7EEl*2;!Q38_d41j$-hIt6-v| zUaIXLZ|jDjAhpRHI#>rfm_f!dsSFcV=t+y@CQT#`z=Jq$P&xvL!y+MLBB4?tAfO@n zo^uT^q8_lqKb^-5K04Ypx?Q@CEr*4rLid|@En<1HS04r%-%LfYpuCLO7^pf(+!d20 zpO4JMK6J+nd1PaQLcDnGQ)sM=)4}TWS9~-;l!qzr)T?5ReCvdd|NOVUVQCE|o;;zC zwi9|C^?D)uPqy{5jk*S8U7+-3z(gMywERMSBL#wx$nFNxD8~}ASWyQ z${^$s4gM_0322nO`M7g&>9NcoPhIKW@MFh7)gNzspZr%tqd@&UiQynAi^Yhyt$Pu4&ETMEz-2mJ$t5^SPQI+u(;*657 zJ$2k%3(h!oEK6JIiOHld{h^mL1OiO_pcyDkCZ?_;07Z35UlvOr@GU(QuB)CoA8te5C%8cO3u6j%uhWJ7{W z+l8VU8VLXp11VeRT!J7k4QR4r1{p(F#L~|N~vW(zdLXJB{-CyhPGdaqC5ge7B`nR#3MfKpZ!S_bJ*;eVsbC%ku5%A~H0gt_4se1H6y>w9K^z=s3;W9cV^9WlMzw`lP(c)&!C%MgxF8vI~riZmn* zyZ22B9gTm!^QGTAxZ&aC+MK`;<|0S*Mdp_(c%U@sjthIB|1q3zW+`ryPV;OkT($aa zZ;UNw@sYWr&@wf5i)uwTinM3hc@`XGQK6|(t5tC1AtxpLD*wcBeZx^_ePBnB8FP-k z)7G28(VX)D{hp&Jh^zBT3$R1!*RNM0DyfKjRL`cL|4b9>-)5Q@oc2+U;NoS%{;fS( zyn$Wv#^hWXaPV-zAjAL^odzEedy2l{2e;_Zjl#( zAoRm=$=*xNf~#uG8XAQ@c8{ zd(~9NtWh+LG&L1LE^%{Q2_&Vk52h^ zD;24}BtB;0(l5th4yF%chw%v* zq67OxL=3Lg2-TrAOIeWFR%%95j|u#XUBPoE?qVISnfi(gASDT2K(e{GN4Z<@bGh5^ z^0MH&(km>b8XwQ0FFlsh*9c!NeWX)bDnc#uz6tzZ(36A*D$VK*g0Jh)-gk~9WA0SD zU;J>rL)>!Q4R!b!gVM9}sB!-m($;UVPJru@+|xACi%hz>4CK|M4Jq=J0v{4$#sx5jg54_N3iaC>Sz zcOzw%0GU-v7PORsy`DETRSevQAI$$^UcLBJC;a&2u&Ez?14lYE@LPDBK_y?Hu_f2p zO#sZe1q2`_*H_Tv9rAl05Pwu7yYa6<`J-!x0a6X}L&{O_oaAip2l%umYf%UxpcY1& z=yMu8=ydd5@Z~;xSkYgz^z3~0KOK?-UrJxL1x#c-;1cl6=6nYjd7MP?&7_xNe8{s( z)AbEu=fg^Ri$DARC-O(5cPNys!h1-3m{pfQF#@Clig6+HlMChyKme|hS|Bwum4d2I z!g(%3o5H=?$(e%JidToLj6a5H;>fX^(9)34|q0=`VSHq+Mj zS<7X3X+@t#Un_shpA&DDSmIVWL-Xvb{2~_GQY6y+4?*~uyXQUIFMBb2LaiUc=TM#% zxmkcmy~39GIFe-WhJnBX#FjnHG|o~ap(ce%suiHrBtg?}7{Zx|hUz&llFLvvCj=5; zg9>$RT|HIlWRgMx$6A`6|GHf$;|y>aLF+h(Qk3M4{ojKMK`iP&el89fmIc>MGd;7hb3=^d*XTZWh{M$> zrQ3NgN&2x%*-pR2J>&Bww$YdSFv&=4ycRqu+M{aE`thYt`J2jRFAgr}xV9R;N#JdP z+{Ps}qi+>%;@Gp&`bINuZr)0NHV{RCOYC&at@pdgm-|y(DI%B2dwXzMKtvdF%D;cb zfeoYhFF+>#A3KM^GFTQ|w;(WgUnMqQJGSmPMBvNvSszPNU7c6t^6#=bqil?=%dIjfgqel5E4Y*4$Bz}FM}I)W zZv0lsIMM$1ClaHxbe-bC+>aR}%2J>;k0c;#K#p^F-endXzFR8zZ{U}UBZoM};K`zt`1@wGgFSg5DL}v=KXL_3`MsDS zdU+MW_W%3mV&^dDL(i~n)XOn|9P$3#+9D3NA>q3W4NnsS;;5`y)(I9;+smuzaX=ps zu`GNtmuYRRq}whaD1hqu@Gb*n9n==-s&D=1XbGbuO>r|LSPuJZKCmlwnrs7pTaA=q>3V9LDMF{@Ts;#G*Kl8o0QzI;L&Bm~LDD>wUof zeiBHF6lg#V^-Ku{69_Mk{l6|KeCwAEDy-MHKE_Avuv;NV8;arFhM794xBd}-wPQ}4 zIr~ao$1x(@bGd`t$yrbHRuahXT6Q#3+7;}Kq*wK6ZJjCUWev-gme`m9m=EF{5SlGp zg2Til0t`_D2a)LbhjLX%KZQu9z4x@9uI^$gPj8TP<~M^HML^5}Q@t)=#$E_6Iteg9 zc;e7*;cswp);Sj4)IhI#D6l*a=KDfzM)Aha1?0lPbnwgW*2N#;$m;Vb4c74!wH{NEzF*PD4g87GU(}jcKc7kld-46! zFh&IHKvy#;)I8P;57i%jsv^&=zfQ^~b&+6LA~yx7YLp;K z7>4&`z;Bi+y|&Swp`|-+s{LM^72%$+BOOcq`s8uBIE6Wf<+&#du0Bjfr(Vr8d?AzF zkQ%H``c)~ZK_O(Ar}l$|UJ}o`;Og2AN@EW2>_Aha^RavvA`k)E$U6(F zfb6Ag-Pqdgo82qE$NgdToP2)7hrQ_i}Sf zvcm^uaKOG_m@V~UzFc2AJdyR9$!z`EcF5w5@@~4t^v8baNs==mf3rPLu0GN zCMrO2-z-0DnSrw-Ceh_3;`*a;T;qUq<_IX~yZCCo3-HIC;5kza#sng%3HZNA%EV~o za#gU{md0R;HzRAFQVsz$RvusuAwR7@8@3KWr)$5erR0UG-ffd^l6Buh&8w4J3|M3_ zGv_~BzPHDCkbDjR&dUxjo;PuoC3ZM^r*XUP1I3O!U5_<-6A6p_k<~Z%7)DI7>qJ}w z^?2w0B$ycp`wZjZ@aN43e4~{TydN~@iV0jc z*!yKdIGSAb!DNx>pxR48l{Pydqv3XH;#R%WQX`0e@#WX~<7(7EYq{Mw|H+5kWSbnk&`1%kfAqh>gN_7UD{ zm#|fzzDeDsH(>g#Hg_18mf^UKx{APlY60khU}WIs=*-%yX5Cy*{-}Qy9I;>iQ+C8c z$0OQ4Ll~ydlF=L!@MfWhM;|111SCKYW7zv0F2cq0j~5302BBR6p*|YAONz2@&YjlH z;;okgZ^h~N9CgP*c^Bwu%MbaXakFso{A`a--B+%qw@rh3ZPrzs@C&8O18VC-RqMhd z1+lpaPy!;b&INo2t@Mly?1r?%0Rp$9Zw@$%Dt0f;-;z=In*ZP__Ihs93)X?wm{4D% zJg8_Mdp%z^ zO4QU{4ZR@>Z~ayyqb;dBLo@i=l=9yDN%x)}VU5iAPyHp2DVG2o0}RDW^IQX6Kkyki zHfz0o?$gYbSOU;sf{H(NJ_voNB! zfv9z^lB!7juL%_i<5_8|m2jOBN2t{GNw5x-Gw9U!1RdTHV8dpCM7uoY>`7nM%Hq;9OoF}G}J2p*!yDO(|IjeM6_IhU^Z>zH6 zsVTRVSETF-z5M2(+Nivh6ueOHj4J555mW^ zH4ddRt{3MbmMPG^Yw*i;tLP#HIRXiOU;tp&_iqU-UJ4G{4Os>)>6rC%VS`ei-dSA9 z-H&Zv&yW0cn6~X=t$7Bj@G&I7J-M9X`o$d&=Aocm0-*o;^J3qy`Ss#=w7Z6yGR+yM z7sBKOk#OJ5;mz^<@L=in9JL5ZpbWf3Lwwvsv+lC5i?*~WpHkdxtgG&&+ruqtYYYy2 znU?F^#CeYML3siUDo-}U^}-3+s*!PWfx-25JkHNUH&dGRQlf~cn?t+`+pt1T(E-{3 z)!qD%3!bon4Vzyt4z>%&^sr{@;*V6rUfgof&xqL$qxkNf6HxWa>3)OQUF+`(=Ja#l zOfDr0Cyxp-cXqi0ql2~zmCxLjiyI}2lrzLD(Kh8FVm(hCxB-BY2GNvaLg0$_&Gc&% zlLU-WF8doi{b`{c$41s?c7*ljdX}CV{7-`&!3~fFiE!AB%WB7lHCuQ4pFs0}pL6O3 zOcoC(Iklw`6;-R^dBS5EPrTRkwB{gty1a3PGU4??obToK|NfZ7FNtM*pf1&nG%gUg zcVDAY1~<=v!N7>tduL452Ane}7Kcg@+pfxaC-*px-Xbcqh{g^S^WY*(sHlDCN4#e# zfqI9_HKWFe9>5sDEQM&?_4`=p*Z|n0P$9TMjuXu56K^)LnbH4~M2FaHox%MtyYKx% zkuC<=3F}8TR~inUiA!nF_;HP7KPv$li%kaYiTs)mT`9t_zq;&@po@{t-y-)NV9jI& zE=LUJhr_Ms&9*yOV)bL8rF0(SpV}B&gAUB6@3st9N>plAi$;ZEgO4K%_y#a3>OaGU zd3|7y7eAMOLjQR2$Au`vVqX&Sb}@fz9(Qk3D>%AFy!)FFGHm6ueeY}?@3`|if?w?A z=J{Kr3&?*nVu=Z`wXhqvCzNLoBu994E{LvEwbI_sCIgTNP<|lOzf}O=JTDJ6g8@1d zfAFJ0ZERG=e8x?k(6FJxjVRh?WU2h(ii?;CKNM=MAHqey1&$aCMD4DAE_S<2cuv5U z2v2X|RSHNbx)Wj%*hZ56fDgMF&u!mri(!e_-{;5tC+_d=v8O0{iNTNLjh20LCY>cUbz5bzoFqg;J?q6Jg%9AqgB;(WaB4etgA*MIla;N ze9Y%&(;<0NNb?q0$IS^EW?rnT?S$V0#PaI8DlSVT@n9nV_a+o?N9f-t#DyVf{@_M_ zlP7Az1_TgPWkG`EdDUACm#a-nZ-0NZ-s|m;=UG{@pHZIHF*SVO!e)x6(HxD!00IbL z5ya5Qgu2WF#r8)dSBY3x;LVJj$Gn?k-G=yP@Vk~ul0oLSuZq$^zO7&#Ajms4 zba_7A#wK;j?0ZQ5a%5VHEbEiM^_Q)d0dP^c&eNW-d*0~}KbM)RYU|QAzt!B+wj)U{R>dg z0kK`Z;SuxyZ+*=9Z1?a0coUhY4;n4j4yprYN)nyqOZ{$H$C4RpIc(=?xF9b2v0yKP z=bQsK*mLrZ;0WclYy1|!4EGV|`xxUfN8t%RZiats`JU3|A=9sRe9-|Di(3*T;$Q)z zoHE$?gYW(I_l9S9g2fJzseP}7qv$(Y#esrhW1HWEH;qK%MC||<0SMP60kbF*?pC7; zXLa4l*L-nYx!35gQ6%vtA+6Rt8oTtpk;~tzj7O-T+nNATM?9QP`aFzgKz%H(_|WJp zDs_wG$~KZ-*yynrjik()k(=_^%td#$+GaR=cb)rj$RW<2x(~Km-)!9?5hiyEV>xAQ z{*(HA5}kK9&STS(z~6_RLnbuM1-uWL-hn>P5cZ)LqX9ogq+;CXdeXKTz()V>rSqmCcnZ{ad(Sy>5etK_VT}nOD1Vx z9Tz7bUCOVeKIo9_%x8R(9bFZl9JwKy}EDgRPTZ?@yT458U^T_}t+WBSA#|&Mpo4!h5f6p_F7x6B_E;o9Y*Az%?w$JpH8Z9>GfTFfz&$4`8HjJR{Q zv({E{A{`sW0rI;7k^=0I!QHzWewM@T5zS$AH`o8&NXWW~b~_dOwBZ@OOfOS`4{zTD zQ3n8WfY=WOFc&|;pI6O6+a*w1pDG+*#2?u=w6@#YAcrc)_ad}T!hxs#d_1TG_zqBy z$?{hCI#c{qf^3FYVafA_opq^NhUhoaDIQY(kkVRJR;)O-vjFP=lM1o}lN)gP|2yHB z;_tv4Y9^-Spo!}niRE>z?V4rfqvplER=RC(K);rdBnp^@_nO#b-a586?*BH@&k4F3 z1sre(g$6s|1{p=(&`HKUB=iK&kp}7!rsvvy;oqBvF%3beELQ%WwC`e7ja^(2?u}C% zx>p}e&2chgv-E<2Lk9YyLY~eXkS{2#$ts%yT z%^;QaAiIgI*ve{DT)&^w7%?Rk>^y$7!v@?x5PgB6{a>J%8oK28&on-nq+`62%F}+= zxxO{^_fK=EOXBhA9ovsY?Bh-#2nLeYVCw0`B?ym%zg_9~YqvMM8$NfK4u606Dhumb zJ?6%U#|lz;iM@5pEs<(KQkT9Yf2=_j`{0gWJI%GVXjs~n4*P31@r=5$waD8Ug?Dgh zDL6zeC2$3VEYD#Xq{BL|Y^hgw%GkR^#gjR?9tv&BFV{keW9&b-qTtEhp|eVPlMU#0 zpi|!Eq_o0nxK44`t_oGvXD>u0B9{)7n@vfMqJ0wXMa6NjF)F%)bT8%D2m1M^xQcGqoQFkvx=*V3?o6hR_jx_-4@s5tTpm>;h#534wZ*)?1gYe zDbaolV!Cin*&)urR=}lmO3RLr1l$iKF2+PO-cTXHfo{yh=}s+%_Y_x<}VdqM{5AIYSyJTwHJKv zg{+KJHgqGx>+uRv-hBem11@PW0Tqfmbi(hx_7l1ALow`E%FMJX!y)6+RerCJn^S&o zh}=$gcJ7b{$QZ=7E?Z;G<>8=H0AzggKY=musbN1CyM~eVBvIlrM7lf1+*!YFyjesS z_@=-}jYB_hq=|y{OfW$ZjzmU?8;oVSObZ^JD3#K%Wt4d^FETvUjK}-ZF=*J1D7p{u z{CWRG*s*`#gEN9$OYr{QmGt!!nyOUEFUK-=C?+mf)3rt@eE!UX*9zkmSSJmpP{Q7J zwGZmjf9DF#!%|K#&qRMj z546)zL?@}b=@~@tYHpZ{ViBfJEX|xa4DAGoDyhq!Nhc||=)^#lasTUt zfnZ;V@fgOrqbC^?!;>r854gc=-!c=@Z9ioG){(!VZp^3~K6o^^0-N6ezOXIriLsL- ze+PeCh##VIYIdAk1Ya1|ei%}Ev%?SW&x*id1D)C-?eQ66MuGpnZYE)$TAD^H`W%UF%)xpT9x~__njP8B7f%TRx=nj z^pN;BsdBlwNZLCtmV(O;=9ELE;JgsHBnD2K^(8ROk_Encw=Z5Fq(E*whw;_BPV_8V z%kr({a4Z1upy~`_aGgR-GqBGWdn_~&n}<#%KYc$fzEjq)6^Y89YwMD-5ZbQOIn)MJ46m;DY^PoxIyHJ8xX%BuKSNPxH6+< z+9os~Av;zQu^7HlIL-2Cy6`QBY2IDTeQb$J#HRBEjVy>v!uENZ1b3i>ZT8+OO}*b+ zA?EM)+Elxy#6~3i&HcB;I5$dVlCIL~MXl{jJsfBm_f>yX^3dzwK?2n8>gh`>v<7Jlc_*s7C9o1aYM zH^}<9a@wPE#E5N$-O4F@D&Q0wVYMAVoe46vfWZdyXFeUkac#hD%lPZ<&PPuL!AQkVsJA5Hpku)3YfI>%9!H({%Z{_ik!f=%pS zilAy_{<*CJZ4zLgH}*3eTIILJ@b+8}7QxmZ5{&VX!rLVN<5#YC$imc?9?RELtO+VY zK)YQSA{&{3Z4*517W0E4q{pTo{{Fb%8M17A5{WA$mBTR>hN3FA)e&guea_GTQ&M1$ z^MUxBU>)Z&p^FL`hp@sV61ynR!p4{l-#D823$>8~zZg>0DDZkxz)glKs%JnU);Zt= zQlETK72F@P@bi;kQ&<+C|374`5`SmRQX=u7x0v@&0sx$rk`aKS4PWZuLhs~OIb#-1 zPW|m)byt;W4%ctLzK#ToU(cVOq&WsC3jxZJG#~>)H07l!cy!| z?xsUCO!3gD5X9wxPIp5_z@-rfv1n;D1ot}d3)T5w7s`G7Vj_W*-U;W6dIz=aGSwGW zKa|=CUh11!x|u%Y>q{;B#?gCnY4$&MGQ2BVr>mh}U!^27K^)Aa-gj^NLTw@Lg-%h8 zf(Vo?5LHl7bfKirz)V`m5hzNdaCW*gj$(-ypsA4eM7TTME0I^$StOQ`h zK)L`*`wle1*BuvOjB`~UJ7mrtoQ_H1S>tP(QvWrKM}A~e`onXWYZt5oUL2GjO9W#^ zAb*8fCVWB6M9Q3;_ZN9L(GZMq#J>>)?6Hbh3@f;^zXT`@dI*=A}xt&VzWMJP~GtT6*B?3g)xzoXj_0&&?ba zX4^mA70eC5#91j{tPHuI?$u^B57vRM0g#_ll?nf>VJ<-KKT5`J@VbgbEfx@E z*L>MxGttSC*3|K zTzJnvjvc_7|t#T)7Xvy%XMO&a4KPml-F*R_K7yI)9HO&yH91Fab`4yS}0}C$> zQ5tOnW#0qbPm=c6KlQCi`npv}9fNf;=gq1v)}27SN}yz%GPm-M`T7=>r!W|Yg`3or z?=5LRPR=qPmwj%K_iG1mEx6Ca|FF;P;{jKODaH|dMEcjWng}WN^*?s}36r`19Zh1t zuGymRIUS|0GC8!HwRp>p2PuDc%IC{g+h7%N_^Llh^}hZ<3Gp6=qG&ZQh+Rnm zmO3mp7kouhpWP%5u-jETA-ebaI>~qS-NYw#Ca1>LJ)3v#XiAuS-#RB1@Ulb2#5Emo zoAl5E5B(@x`Onn)zD{fge{O`M$yuZB!^p-Lndpsr0@&xVBv3;EdtU8TOb^E-THCj3 zi^yf=F3x6q#ynO#>6*PsLsN8$fq3%Sst&M8pjH&p4kuRwf*qVU@$Ob=jN%XpEbVk% zW6x9@eB5s!r9)V&v7I<63FJ!x^pAv!SsI4m`%JPuTBw@AdNS%-C87SiEF5L{#p<9z zi$_}Ly=Jvl766SUIe=KgzI*E#d|d?RsQ5p+EsRK8)MBxqcQ;PZ=JUGDt3>6L^12s} z*Bik)KzxH*+2ntNe|K|@ftduW2j!SF(?({G(i8}~yQy-qHKlKbS1FG^^$q~*qG$nMWi{>FZi2U#t?iy_XjBE065y z6pqMe?brYhVI#m!=Oyz02`>{xiRTMGP~uOr9rdV?T1C=3sqcIG4_^rHOD)-+mVS!_ zcn)Z}3kAu#a^U+59@y?JY)HXb(;}}LlGDwx|CWS6pP+FDlqUl37G~r=bi>uq$Yg;d9;MS4 z`AP|Lvv=cY$be3`6!tm@QPQH5bNaZ54q7t_dd82Ks@3bQcGR|+ zLs%k8rd;<`hk<4V<{r{m;hAs=xk*oTw$vMkLlji%96s+i$;cCuDmNRQ>`GxR+!*~! z2xvM$ZHHKTU(c{$QyImfJyTun{bJ9V7mmI3sH9(FDM7c6U>|em(@8b;n1)pow)0$*6+uH8Qvv*&Czx7nKaH$y-Wa;laKBm$mqxaH*G(&7KjuUz{(%t>~h6hhy0J z226gXHXOo|bV8FH{)I2$r?#G;L%8)a3h`f&wf}L}Fv*s=&2jh6#@gUy zta@JO){BnSv-uA}nq=V&Z;V4rMk|Uh<)djW=>fvi+dF5$xn5#Vb=2>r{&;%$>aZfk zQS_E7Q*hGx{sH`iS^9lY0Sp1HHf7hxJcH)%$d09mg}WO$V?>7KeXH4T6ydA-Jn0ea z1#XD!CHpLC1*%|hgONV2HVpsmLP}sf5SjK{&pp0|zCU=WT7ubCG2jPMec(cg}-MGxOA-0TE9=K>8NVLOkn zf!|5=@~HyWoUFytRDrTDZ+lH5@V7ecA92|FaNgTPhW6hwE)6sTGr-MHk<}t6g?vZmbCn{L>v-K*gm0$%G=`wxuYlpRC+* zWbnpAS`D}yfSz>OkI4UO$M`gKe>Hy-ragP*Ruo{cHlJ@uL4=~Di*c8jWMDA4JPf!h zU`!9R zPV3e5wN{Iay(c2`^Y*!K!wGV{7e;%h34R_CVg{s2bD~f50z)Kx`=lSrs;e9-v`y0; z-E36n**&E!wK-%O}g3z^EJCZy3oLOB2d z1Ex;{AYubJm#0TlKX+ws4{WmJt6QKb_i2nwVhdOgpLxx$BFb9+0L)bGa|R!bNqM{s zznChtr*&2bL{%a^p0sZc2+$djNQ?Gs2zFi{TgXd`{H6ozK#lF)TCm4uQH=57 z9F1kXyJ=irXcnfp8fqNUif`oP^zmE26v)beZpI)td~u#VSC!2&{X3c_9EYE|i%Qo8 zvmMa(WwgU{GfQ%x$t9M&wJ=0Ew--Eokm{?uVv5ei;WgiN67f57mfgS3G9oVji_QN1 zgU5J@`$*}UJqH_LofII-!9Za=RA>y&CFBsJPIGY1=Itw{?{@ZiBoSeX!V4C}xL(_n zFQN)G#=$z!VG3euhh4=hDgJ~GOp>>EuQDbTk{qdyr$_ruOQZik!rnWa>;L;7w<;?u z6|&0+*)!Rrgi0zqMP-&EA!R3fkI3F5TS8XKNcPN3_ROB4-|>7tJiR~f_jUcg{n5*- z%efx+aqj2b&R!mncjfpL9N^#r{y>n>h@dO|jM0Y@4_4fo&N^^9WE^F+6d{z1t=?j+ zZJCxoeyQ5%3eHgo+JIXg!d$3xN$$lY^keU-_q%?y`Sm(7w}p?Jue|-PQe7si-G}Xq zSMHm)_xZtCIbo{49L)Ra@tn!}DH&SGAKI^buJH}lEvjeVcZOe460-2zoS(4r1tSc` zry&kL_e{+C)9tN^FH%w`Ae(D@A8hwoDt({Ah$WEms@G~or6i>3=HK=T)<>N8d% zA8^@1LQ4z1RUFzD?is4G&v1<7G(>6K^w}+3x(akK&=oO;gCN5fanW4-#5Ll&5cTrQ z>9<&TA9P7tr*anqUk6v74VcDf!oJiEbYRjV(YtSl#?4w+l|x!o_-)}2R(>o?mkTBE z8A4{~>)M60On7izz{tQ6Q>6O0gD#AK^#xxw;&tDSIg@rPNb1O)?8v)Ui^9JC%$?S6 z;~ENc}uZ)`f$o_0r3rSU$CpSa8H!-TPc?^3{ znh?hPdvv_!Wec+*H%W>~0wvC;;j8`hYrl0a2UOIAmjx!6I;Nj03k~{|Z!lL=jx6NG@@G*_pY5L!X?R$HhVT zOmn{88IT+=v~fm1GuIph$ze0?;|4qz7@p>I0t?$o8lO=V3!8+I>=@QLMlAHuG;}fQ z<)6OR&V-L#KLx+&@9d*JQE<|T1BYEAS~(&S}gE~V8`(|`e3 zya)3HT$eEdq`X?)gF8ngv@4og5OxgKFXA03m>?l! zf=C|K|6peX8==-cfdc=Rg+8*CUaCHA-Fe@~jz3_dr1Uy}r|b~5mFB|<0!8hFgCiGV ze^Xv}{#C8r#N6|(>&wvNF_5Z9v6DXAxNdfOJ(CI$imWIvQiD<7i($3C$fwe$Lh(#9 zQuW4e7e+-fczOP-GL*Hs)5RRgb%_roA7DRGqzmgXqRBynY|B4lC+wta!W}=_;pQfB zrGG^QwD5EP|_Jpa0S^3GGNFA)UF$=;hR?h<+5${}Vo}+VDp`-21j~CmEI|})e^e|IPj`bnd_Sb7e&HHH3KA=+U);7(*WJ+ z`*P-%_Urp6I!uacO()5lv0hY*Fpjl5klJh1D{a2&h(j#_u9?_fj^*Y1%~e`&)r)-B z88wf(sxjSY(q?~6+`f9sVb~KCqawt6(Tbo83JekNjB=6j7pm>n`nk7qF2eIRmALQD zE@tK54vM&Qt!>*T;o^RB5R|Z>^ngz|l0m?@f5@mmPRM@`|ARVqbQS28j_W#XFkt_J;(h^*fARTtdEo; zPncewisJVHR)MY)h}0fSz<9DuKE=872d&n$K2|nu3DZe{nGEZ_JWnx~FUB9<+Mi!e*J2HO7^htJo;drtA7_UD3_F(i>NRx z#z>aiE|@f2;h00)a*m4eV9J*k1v~aGu16p<_J`@BePKz5Rj1du9n*YB`GoX+qy-%W z@GZwf#!tFzpZ1~pBO)pw~?6of?(d(ov0^Sx}-PX#dAf}`nDxAtI;i)Z*T`dYGV zNY8laJ(q`0(FX2QuNDN%S z$;RddI>=Q(T*&j_%12OzIuRb*%EQKO!!ec+-W875gMB9m@?tqZy3W-QP2|sKLj(rA zFlaDR(uoljQdbG+Tt53+owoQiecaThgqA5m@CN(CAT!s~RWsg0`uhVQ_EP*yFUcLz3jsO^03aUg(8Fv}oE`qSsosY% zzwbQxbT*=2O*!F+sg87SXJc}_c(gm#4A8*{YB98tvg?5n54r5or9M-5mgmkgGpT#| z^mhocyWVflT^v&mtL+zy1CJhrQ=o+-id~Wqv!dlbin~xp-H|jIlEj`5;a$V}#G2W# z!0ne&F=`*>{GJKu6d-LIjS_0(Fz>>hd4r|;Uxv!re+<8c%7$hquj{hCHGUCPzgb{0 z>g@!sQ$ffg=0iNZxtMicPf21SFZx}klk%5x%~bDKvBKJdv#L~TaH~}yZMXG)+=1~xKQrgGFN?9W_3ovfLBto2T-;jtA$hzanP9yTw zC#Jpc-}SMG`om{o#q|XInFc-XDC=Y392j+UT3=70`)Z@FL8YgCtJBIC^b;s5iczY#9&kTK0E;r5HQ6JL1( z_8Wa4bgf-S+IGS+-EOp`G0Up`bkKOyrs12gBQ~;XCe_2M&#ZSufs<8b8&m+;ZU`## zM2-dMLWj76Z@(JAo@P%y`?w#MYNp(ywIb#p`KrhXWpia5Hqf|=Fe?cyUD78oQi710 zh3i5BdGi}qs!58-7=nB?x>Q_;HVYh!((WjeUl6B-_VWTrIbszugay9$LQL>p6VJVy zbad-)`A>`!N>24BqzbiunyEjdkS+ErVjtY^4@*Klhtb2XO(qKx;aLx6mp6#MJQfv9 zpcs674(C08cgBD@neO|?U2qL@P-Kf#n*|<%?MLq9OS_Hq*f0Bo(n~7DVv?|IB`t8G zKAJ5w+#wcz4aNj?>^^9pTGoJJYt5DVq-Knd-9))b^|r}@X(PkEjnog3@&>&l~p$P5%~A$*p2IOm|x z(~02b=kPlxM6SqP?J;Z(x|Y82;gi16G2^ZEm0`IputInR4^m8rq5cuE%09Wt{KPUb ze3K%bpXc%7Z8vVr^$YTUoi2AjA<~#z4!REc7JO8RUoo?7?>wJU@tA8*t~EdFpvK$V zdiP)H>rEkpBig)zPm@AY_u%&hsmca15h_D1K4nqIT=Ug&;W_m{cG5Pj;S;hijoT3N@J?VmVY!2Tmv#cjyfa`}X?ARKndA7((s*%b42uR;SHfC1q#3_! zX|f15{ir(0InV9mf%S+w`PIlZ;gpj^K?i!t6>svZ@G_%=XrR5IhAO`wlheY{`4ZvK z%TzeYS+_l0z{Y?Fg=W-ms~E;9Z?Sk~#6dj2cxpQ&)GWu zDVCRmP%--c+rY+P0mw~z;HN)?Qt%T3R!|rP9b~xj_0-eo*%Hpxq`eDLH~3#YT`Uq% zb$g3L?lD}k`GOJMS_590?I)s&>WP_0+JxS&#T;);)}O}fZ(bSr+`eS({ghdpdEY(~ zLVD`HLF(B+_HfHl1X$$^9C@o7&6LMHz4i01uu@FwV2QfBz8#)SGFY^V0Duu;5Zr~F zJz@_1pQWSz=RfTvG${OkHsL}{>y5n@{_VFJ+pOoZrpF%>G3%%btdxuKF4nSCU_0#W zLa;+XR`j5EUGfJ^kU?GjN_E=V+nV?(o%)TQZhlM6gMyKDGtJn~n*%iK)_y|98TbRy zXFs=vxVkZCe*nl)2fl_%)l_;xo=K`}+a~{5)SuJ*dWKhw+eOkgXRJ3}WeVqny9N#r z_>jULX>{k}{a)T|qCao8!}cz8Pru7i#7($ODg+^oj$RgdjgCUX(c8ZNa?WM4L}xD8<L{A%bGQ{@X;r=W zJHtu!2%Q_BXrQ0wqyu{dIam5Vx2F2 zkYcP9V9HRAE$p)*Gfq5z$L(xL#Ta?kF4SB>O$B(LQRn~TFh9UH+Ns6S!#MkgJ8PZp zwI|q<>f53gcI#i%tGy$02{Ir=Aq;~$5$QI6=pr{wy>TYruqZfik>0&Or_aAY%+1lJnv)zQM(5|Nq=hZMZ)5%r!}i3yNi|x7Ce_V zzRZFl4-iWbITxpG%>LZ7j^Ox4UDIfyw(Vi<6t&aJZ)kKFyJacK;&-*m=mnf7m;ey1 zK;$?cY^&u2UR!+F51Ix0~A?zPER=4T7J^76r?bJD`I10F3b6l;kR~w z0I_mq24vC6$V2N-w8fl)@F%=iaf!BLqx!)S4_Ftj(Zo5;r$zCt6WN;KfkrAe; z{m?Y#`U;tg9sDOfqkQ5^dJM4|35jf0*~!RlddoHztE1lCxdSLfem}Ju^|_V95~@-s zrMRz0>shMX<7~3W)QsE|{8%&_W!+E?*A2JMX>uQ(B~)m9Dn@HY)wRJ(ZL6<>50O zG#S=9pP!{OnOW}Z8(?d+txyLhG?jZ+aKQ*%5{e=55T{S=XE0Z@`xm*0F zi|y*S%Q%X#w1vtw!T5njX9q@8*rAPGE&P?xOs-$bhuvC=WJvWs6;;U9o-j`46?2(; zyDt;K1 z$%k|pS}MYT_1-bb&z-NIRQ{#bEy6YL)KPeB&~@+hpQ%V|qQSpg*u)@>VVVpg1)9EK z=!(vM47MNGiFgz$ZW2Yh#vqh2t)CydtfU~3^u;dx+)tpB0pWoYc zbyd2*;`?S|dQ%0QORt*p9^bDlBCA+u4h8og$Q%(Qz|+-;;Ukw~D?XVnf1HZy^DdtR z%l!N}qN!-=MQl{^qkTGVyH^4oxZn_N_yt-MAy~HKk!}(N(}}IFyrGME0jUMFxfz4s zPyLbo_licY{vN&&WJd~7)sJ8TCt1gQ)9=q%+B_^DP|OUu-br*nO8BkaV|!-~U)s|9 zos9eN0=liEwYAR*(ScSw*%l>Y)xA3Vfi7C$>D|0^dZydESd9_sGow?>{n6vKKnG1& zkmtC%jL~YAMk#yjt2H_NH`VH13dy$n62$qu6*JUpJ@)jPTD)*KXea2DfoR_nKlC|* zRP_BtE25%%#XzUqkvG|*GDGe`1hrJQa7k^(op!#9a%rHQmP98KVjLA~SU!vGJiI8g&_Sv0-u<0`+F z=Xah=<#bWX2>G}N6xifi_;+UQcN!K$>SN|IFk*vPigKHDJo(wVi{Gh~Web@GmeP&% zs(PzZ4P5#HsyZkyOhHDfnvlQla@<7HgKW{d4~xKrxTXlvg>MoYyw$fZTN^4i#i*Z1d4 z`WUtQ3}`<13V)Aye>6~gm&sySk|aBOb_~iTW;9aDPq`m1w(6c>2*y|~ct3XKKh5l;hf$;)e7-*Ur7Nc=LLT4&|!gTE0I-pdVH zOFh3--ML+ULK1W?3^GAp%>)v52VGV*6a1Qq^BddC;PhFN?i8Pwca_}ko=}xM?umW( zkpu`iXrK%^+UR|CCSb5#qq(J|ORzkyz>9IwB)3I^f+MBDt)X)BOxt}Fs?^wmpgW;M zBGQ1W<1gmAFIp|1SuSX=IY%Y=bcxhUcSb(WoF^uPoa{V$LShNc`52vBHxwyze>rt6JJn~# zcx}DWz{A3tWUq!3N0lU1R?aaW=s-3j$62t1*`9s#_dFU}>ADGl>?I$;vI+aad$lWg z?&HaCEVi)zH9PLd4*-jxw^t3G6vY3Tc;W#Ex2!^N{S?ZPw-Ne=38O1r?F(0er z-|bLp zNYZG6fDoON@&c@qX-8!0`0TZ9ETTeFb1qSmq%peL2LKd-aWaTZsXauJ<1gGVlySuc z(&+_L%>?QuUMNU8T0(jacS}b!Kfuic97S?44+=?|C@;Y5&sY9Cw#kPn$#c!x4dLqq z3Z0VI2K&v7Hs3BEPZjra{0MZ40ta0N=0Y&h<{q;v{qAjiG5y)JV-8a445h?6Esr|l*I z*y{=~Zw37dzK3Agq(RD8p(9~^=@aG23%HK*6Q5hPzGKbG%9$BZewNZX4j4oM252Bf zXzvc|Pf7%LHmN^k7yjTk<2bT*hn0%#$SR9?2NCfvrSGq*_*;Mu+;m8lQu<-gK9iWk z$Lj&5mtU4p$VcN?Lrs?^SSRUNr$ZJi zGjC*Ff=Lzd|N($Z! zjGnDN;}v0c7a!=L;u%T8Dueq*p23y26`U8Jf|452%>sfRF1#BR;={i$v3!nvN$yo> zZKEwzWJlrz6vNLS1BrCh-Tt!SlE+v_2R~kaM|?rY zt>zgv+zxbO6h$N8#%?n7$PLDQ@QO-PM*Z-A|3Y~$YEj+`W!eW9Rg4m>JOvy1L#9bo zdwEvg=gL_O(&aY>5TC=bK7g@HvF8eO!sRKIe}`W5@N=HsoZ+YuU46PrYg4mu)KvsB zAVA*nA_=rXHJCRbc5U*QeNy7%V)J5EGNU>!4G*EVW1&+I!jmy;XkG@{!0?@9eRilI)=%_$vevI6 zMP)&l$7rN7+nq#TA6x?q_s|3n#jeJ>1;x## z*k1dcD_6>GZ@ry3E+F!ibJ0H@fC{w2MwYqp7W23~ziyJPcJ)lZDq)QD=JU@u&uN#w zaPvX!%`mSUex%Y#E9R;oQp!wQSHt-1BO&*7qur(O4YMc;zzM~ zId`ULUzI@h4qA1!R-w-m_=S}{#XIKMzn6=z$)%PVc;*b9Id7)pG!^Ov`u%(8SfvPb zFgqLx!AuvgrM!YPo<8YWk3nWXLpT ze-*_X4({rzfjVcsbVP&=es2W7X_CsAn2%nG^2e8sI0kh442nLNngXO-2TlSO7BAUT zCy?IKSd6H@_mfwgusm_doM3VlN{*v5+?AP6I}r)qp^c@pC;9fSex+ba-;d&?WB$co ze|)H8bXpJIB_lQUydM2730B_d`^u>S<@S;J`bnx2Blclo9jZfU8+mJ5u5WF!S<7%eRZgPiy&^FifD4Q4&7fk{Ey${-68{JkfipkAdC zT#{RcRT4>QmSk@2AovWR15lwM!159@BMcRsVEo^8AN&hy{ZpvPRm#s@j2nDIsYP-a z9aWz%Rd)WZ!L_{-so(aLK=V~@=GuXL8(@fB!j~yrTwK2-dipqxLvql(7QJQ17go}@ zmi$C#L3~4!>A`!9AH(qZ@FQF{lefP#3%R+O?%KYiA@n{TZxYq}M%qku>r0t9h;QgC zj@frNM!w|*e>TX%qfX4B%e?E{U`Uhe5>)svnw0nW;|qn6I^V$rfVLqAA*u<)eun$L zXrReGacR@~7M;(jEAQ83yYhb+n@jmvbGd!d_;w-tKG4ZQ$9FWJH0)vAEGc4H@?Cys z-YhOfB=YBa;`T?#)x>$S;T;hK{@PyMzycXT%1xAPK9 z{q)<`TDi3@HY0b8Y#r3KJmk-!-){-*3xR@!uQxgrt&K_PTu-u4`@aU`1tI*2VJ=pcF*Bko05 z?{CdncBFcmzjOJ2OnwCxhmfMMFro%mU~2XL_kc|%uaw;meE0kkNyH_sJnWl2f}*-? zOFI^CkJJS*Ev(W(%m~7mkotf^BR`SG&p=nTH9*02am{`84X;Af#XW_Wan3BF6A4M5 z@6x821-C(FmM}kDADX>p3NdPsPl|c;U!ygFXGczMXRoG7Wwqr(f3dzWF1!85DYz+h}qwmL8_&@D*K{ToyWPr@(t%Z-_*@dOHDB_aeN59RIR}Vbl_J&QVJHJ z{ROf=&)Y1*gFK(y*_la6BJLQv>Brv7@qGE+mbL4YMC^`B5Wo>=#D#d*TD&phhI!UQ z9iPU+XX(=iC!^HLyB*32sdyf#EL?N5B)LKD@4!n2{piu#OUS~!as%S!a~vVjO#J)gQ49!F!xkiu=ZBXTZ#zYot|HQrHG^xKO#Ub1IPWtM zw+2X3K@z$ERoy(*ftRc7!6&T#)f1Y-)+b-@ef%LlEu~5%9#{QZm43rDSoCKQ{5~`V z>A*xHwH|MBjTON9k;f|?$eVL4^p}v)8weY?-_euIe!gEN;`6-&B!GALNM5sV_!!Jl}gJe;NcEwa=&kNA?5$yuT;-7jC7=Zm1gSAdWd>T4fYkes*UW`l>G<+UGw{_cXSR30j+kVo-xj|iQdfyyX8zy<$> zcu$uY(L&Pge=lge ze@Nw}vU%hm9D@56Y5Fw9f4a@W9x;tbK8GMSAEb#Oczy^Ok^_o?a`dcWgUY=Ejc~K1 zt1ry7Nbd=dW1BU9KULy3TX^9V#0mKJd&8qe(uxxq;c@WQ;5oyxQKyXVTz3se*W&qJ z@J8QpyWHkir(@df-j{nAoIZ9_#rmwQ9P{!4i11)N_JGkf)7AYWk>5y+i@n6%Vg@c+ zm4GZq_Kxh);ctTA{bRQo|=(OORn-_kf4e`=U0u|36=!WRi% zMMaOc_?MxpIs|wQ#t*ExkpG{~bx!~1h*7KdBiwKKb&WN+pHcct|LiSRd1^0uX*@{< zqQRzt9FHT0uZ#w&whnmX@@t9*w2yISEHgb=94cj{iv{9Yt%^LfU-16CK7z9YCL}lx zL=as)SdZ~~8r5HDZ_hlLF72mgmq;}7dEH|owmQSRlfiiSEH>ZJCm0nYKsD2f?vMxD z>|uV8Nk=O=s=RuePe-KVu@fN=?&n0D7{@V3+QmoykKjAdW^KZfxg69S)=pXoo_B6ovRL{~l^0qQxF?A{s zza1o=Bf!dV{)y>VBHh5KO0R?#@c8gUZ(xLX>kmzngf<%E_ajxwEqV+!5;J^m4J7n+ zb$K?^ZPz{MGuTW)>O&G1paPV>HA)4lluM;3GI%*FX5Gslh_hV8z#`7Zh z)h5C&N=Y?}$+Fo-f`60m-Mzn!zFERn78_d~9Pz(^P6m28AzsWF`(p(sa&ui(jSa#nC=8R1t=v%OZzV9`HDQ*KuSW6GZgf1JH@9O@Riz^ zu}BPvsVk#q|7^SpRJl4?3s?tg^AU_2ewYzpZ^CLBCdfB`NA!D1=MZ5;&ykqm+vy)A zhF7R*jpjbV{-8nIL0^zB$S@V)_xZ*r*~($;Jg=XON{Gw8&KN544!NIr{};FLjRJNK zXJ??3fzB@I=a-9UGvJdUqPumJN)d+Z52W#gPY9gfl+@6DH7HxJN&b!J`g@-JJP@c1 zL_ktSFJ^ztaqlQ!4ufBeNFQI@7TZ!+6ZGA*4c{|-AQdTJQ3ql_Zd|R(N$avu^?}6p4#suE{-$Rg2hKTJ zxhv>#Ed?~{dRSVljGrxuRTZ#Q&|iBvGz;1qVs6MitRLpblzn{mOzE;SVLZ|t)MIx*xhiH4Y=EWF&uni+9BhqpsPB4)9RyliH-F{O6#*gppzAalSZ9a1fXUFqz}@@ zFZ$fw_KaGl?Nx00>mDy#dknw+8j&&&yMDj7pCXLHg1kdCEGm!2ux*#0foI{7O7*{0 zk>0h@iy>>bBzXEbWBv~Q2}+$F*#gfP=)(hWpS^*`F>ovj3*AADC4=LlmXYeS_@2F{ zN)|+~qRi7dA9(tEh>U*U*T66p9lgx{Pnc_cRxqD}&!7D~uPnj1P@aaOErId4_Af>( zBBfZD$|?665W^y1Vxj2<_b_5{{^!Lv9bP(bbFHaY3_T@SS8xAYcx~vUTQ=wu6sAS_ zkOGHaj;g<%?m+n}-;%?bRLB~mDWtKTV4@XGe2i@-_#;U_;1|(CBi;K6$Uo)hLt;*@ zhm)1{-n^+;94WhO$^6-u_wMB@I=>a-t{*p7e`&Hei@$mqu(NGbP`4KBiJ@DKy|~ux94+2{ zp_s9${s7{b}6ktxH!+bS0nSugf(_bk<4p8GTzmzWxo zHZ}5QV~*h2*(jh>fHXI>)@|>^z}A~dy$&P43-5Zyq|i>24yE>lC@FV+EF8m%;|P%u zm)1nVUFda>`d&TKQ68k!w``5ezEr-aEUB0ieN66K%x#=Ap?ICBo$+q%)_6w=Gy)YC z1JeL)YkinQuM^lyO^|Aaj2>V5b!~L_CJs3p%MIQy{&~u)&%1kWZg+10z!R2(iRkEa z={lV0TSnTg^vhiStp*DXyA09G?9}_u8x*>q(CWv~8NbELF4Sss`xkLtFVupcH zrSo$>_t%)%E`=%4E<5o!B*=x;H>e*AIm(?_Car|h76%hr`ahxX57tTW179=#lK-%P z&a+ont!@x2bw|)PjLd)69K263YxNq;01=3~A@|;fj6j2P@lkVS>`CPksm|*1(=WP) z%h)O*X1A6icFx2EyF;Y$AJBo(goNtT(lF2N3`-kniT+z6%Hq!#Ov+d~u(~DA+MITj zTfiY+_|?k30w(-^*EjV3z9F6z_+EjfC$C3o#O0G0NROzk<6pa3b!z2ZS#7+}CGC^* zIyd-%4hp}Jn0w)&G%|mWG<-STPQ~vsS40;9XaSfl|}61X7anT=4)Ey)FE$ zc)Wz; z7m?$4LzFeJ7f0CYZH<|xmr)l6yOIR3g0eZSO-!y>9NXG!%+d=JE7&*XA&D7%-F~AO zsXi&HnO)KmhGV7iOHoTB*J0pz;=ES(4_?b^QQd_TQ+i-!3Wz{`GU~aOBkT-pA}d1j zax0ms>yLZVD(hlVIbK0%T!~eVLlq@XkiaAkhzA8;m{)+7&K*XawUJmP1qC8o=6=sZ0ctxM`vo;Ey@ z>6p(!^Fjj)Tfdo9S<^xunsdQ(MN8WiT0xmyYiMI0^lN-)Y-$LNTVC99yZ&n5?u9v% zXbkhC9SN_oLUecqU3Gpfd`tSH1h<%6 zNuX|F1FNrl{LU3op`kPqZ6Rl>jPn-`z=)ccoP3U)#F>Yu?qORJKHb~+2^orVk zvpaCKAkQ&!85w~LYyF=;0H{zP3hgbqzU*J7kCpb8LV8}2L9iu>nJ(R&{GFZdFmLno zUtL$x2MB!Z|5HM2@57h6)a7{A92Ln#)kXv3SGOBIz0~VgOuzTW?0X);MT%CBt%rP^ zj&tqv1IC}+{3y*%&?cXq}hW{V81#>Df{)JRWH))-l6Lk+?39Se|R>DtF3y6@k zIt4tl-*_K=XBBy5=vD>jQi)~X!_R&hEr<8 zYjkVFrBVkAKXEbEJ&CALyjZk&WB%m>&0?`O3FklGj;ryXwz^NY^LStPK%oNqwI&}H z&NS*gH)0m%L2|_Y=6EHN;){T9!H=1A=B)) zRr~KhsB`Z)v2QrsxcG22$mq2Xu^n@roM`1$IW2c=k@c)Zzw7^g=Ud@DJ$S1m`i$31 zYg1n22R$Mx7_O)!`~H`U?`Zbpo}F`^61sB2`wkAMcR>p`zgdhb``dJb=;W+%ZXtnh z?a11%ODt@8`nVzTCdXMipjip8Je9{f?ZGjXtj%+XP7$7OtqQBs9%CP7t8jdP z&EP+L`KJWk1H21DXzq`GRAEUml(oT4p;XVuayY*?SRcuAZ}EJlE}`QhZugsK1I9x)QY=t)Y82-Qsc& zpzeNkHkz$tCol-!p30EGt*_9g@eb2MchaWqV@H)QaiS^Dx->@Do(0gKgcNC6st-wM zSqJOOq$v7mK_Dm(X^<$c`P_k4wIJHE_~iW~pN@QY>Az6q z9zJHf!R11(s>+sS6a81TVUY$zvY-NFv7((;UNS1Ph|tnn;d9Vw07(|~ zI&^=nQQ2}{y+ZW+%KCWHs$lW=MZtF;WvMTf8Xw7_I%@S0f&xPOBU{nOxeQ#g?s;x^ARgkLj}f^I zd-S71yN+S?Q!j6;3JMytTwnX}Bi{50${u7Lz4rJ&im`{vdqCpfCn~f9Z$Q6iNAJ zPP>}&Y|t$~`q_}Bd#&>Ij!n+(@dxn&Uv^?g9bW<+%#uQ+(d41~%#gN4*XrxjWkw%; zsq*)hp(#_?P7m0$NOq&l%e6PD;XK7;AwdWIYDY>j>pXhdo=R2;$4T+XctF&N3yhnI zxztgwmBQS2`ELj-twC^23_{sRGllNM9P7m6(+n+<6JN{(us|%(kmMH=fB-7S3 z>7Rbke7^^4d~*usGJ@JYpG95I(KyMC?cVur!C>X}-N*QgR09V8|+x>h1}K z4dOPn%8qeqZ@9sT^(RhYLF?%U?YFmC`?Rr}IOW%$A4c~#jwFd<{fZ!26>EaiFs@+%0ll<%1PvXjCPYN*N zo%$<8mc#Egc+HsCXCEbi7(;83#Bhw*?9pwabh(oK;|Nc=;P)8yZ=4IO$H*op8&(I{ zGt!;)*d;9iqrKk?{#1P<^s zgs{bs_w&~mb8oHmxV*j!yn2HTl=j``0@ZRU7sE|R+r}KbivMI6DW3$o{kGz0lfeT) zLGXU6!%}4}1%D6+^bJ>ZvJ-fb-;TU=fnACC1YU9)_uFwhK%meiAIS*HK;93~(TCjg zPVbYHYET-Bzc}&f_flz$e`lSefWPqIomrd(W}pM?f>=`XhooY5N34FFARXW z0>p@ruGVdl7_FE2^k#&{u^V6S;643;|9R%7q_NXie@#6Plan1K@9)}yAq>hA99JlD zl=K#(^<3uTD+rl7@?E?JqHZT9oKXld&>~%PXZOo1%_za|1oniP38F}bMM4nb4JN~J zreuaSr`_Vo~%KuFsH> zU{HtX=N~bQVZSDk3h}~`Q7K<{bI-*V3O~k>%lC$!-zTUqEUWMBFpmd1A;|wli_@Gv zjQYKIU&QJ!LsY2ZmUg=A4ZLf9J=moma$VU@+QT%L0=9mzJ)n~V;&)s6i8*JtCs$up zzGgUuk-A@hosYQ)V`GA248VKpJJIUs_K zI;zfSt{ZPlUNZI6nLm&)1(|c`W9fo?N2EZB-g7cV;`sOURsVkN^+$t&7xGn`Z7%H& zzn0EuK4OAD513GZs&WY}r2riq$qpch&i}%4OSWN?=x*PUf|oefDUtIfcQYEkG8rU+ z_ZSLC4uUM%hi;{_AK7$hKmS?pV+c3yJKz8QM20S9Y25Lkd8j_R%8Ydcv^6ipg3#-W zLsBr{HH!CLC~Q}jBavWBxVQAhfAIsg$Gwoyf2X=#yvO;isqO$B6kZ`VP|~4$mUi1& z&9m_Ct#TqY;w27M`uEwmJzDW4nb)_-Jn-oP;S~!*YzE1TZ9fdoXsdW^s9SaEe7N+1 z5t}Ml`hM%oQ>vp~q2F}FkKuGsH3J<4t&mcX^v@VA_|e|AsLnyl_%9i`9nMW5Q&C@) zU;N)cBxbp3u2jD#gdhbB{DinD>e}|IG0#|gEZu3S*P*a**($M$ty9FucyhbZ)jH#k zn$QtS(Y9-V4xm^XF_qk)3KY3FCkn+NWmkhw*9WXTOR9>6-WCdWBr}yO-@kQJ?Drq8 zchGNBo~mL19qfg3#Ffta^YZjJ_FH>2uiPWzzLI_8mmoK*G0n}_q`x&50JerGWU(XK z{mUvws^Pn+&8}WnZKl?_@bUDEhix~Ga?p`09*g@Z*f8>_cS;S_O#$f-_|F}qB+hSL z9@IB(3jAq0F5j|XE^&w2COzZgp91EZ&5GH|?sE8?umH3TKpjV6IOerY{q8K)eR71F zP#~W2d&+e80v+kv{U4e|8QzTZ2G1TrEDpLy@gg0){A4))7-ym9BQu-Gt95e;7I8pE`A#9TR19SXK&9`a1WvT|~u#fH>^?&|*YvgHq zUEbAYl6NL58ngo-MMc3cgFKtzRSaEuxIuV!&n=Zs=Fu&eb{rdg%ZrbeB<7bs#}hr@ z;l2q{2YL&|kan#!nuY8=gVHA-F!mReXg0zI-`cz^V`=X2N8MzNuc@=Z+g!><{VFs zM$g~6qo=C#S#4dn_Tr*wy037;Z-x|R<(C(14B6U&4n_kYT@Jq=HnQu=U%sS9%ChJ$ z*e((Ls`1XCqPXFa$Nv7yx?{8t8m2%=i^=dG%&KTz#7I}O1!)RCZi+zH$_zZcVaer5 z_3A&Bbi}%sruD90z5N;7OEM5_Lp&|LNInbP+f|QzHvU`TPRX-c-;SJ+x<=nVR8l3V zpPKvOwTpUNxIWN92n%^OLz|fVyISW-y6CxH;T_AKjF7rI2^x)4?;|!0;<}z@9vciA z`UT!&Fip|Yr1x;R-?Ciixp482w8)}nJFf^E&g8aB-BGQ*I|>`}@oWmNV9~-DQwS!a z*mCl)ctn-${dMY2to)K3?AJ86o2xb7S~e{xC5`Rkh9@~VaPNnR1>hdg82-Zw#w{lh3*VWSrvib@jX z&=C(0eSUw32*75R5CzPVsztWrruti=8EAJ4UG=FjRTr~Yl?KSO!L#;=Vd&X1~E7m}tF!A?X1*{jG< zaQNP-k)DazNsA`8aW8dTLK&rO+0;4n;iK)(o@gd)oY03_4n?RMc-BSl3RLymSV+p^JHy z@37x@OA20g`SaYac=Ju_vu6g+upT@-^XX-N2Hy1tqhMn3!rMYj`BG=hLAMh65Ks4* z)9O*lGfHm@Ee6D}i3?yysHM$QpDIrL3l{__+fb#0Vu*wg4Cc9>eZGu`b;wYU!Zb`P zdaT#Pn$YCf=Yhvci3IDv=cF`%P9ER^8oPWtj8SfLvHw){To2F>{8g7{@jY*ijgC3M z^6Kj4TaoFL+<2;hc?5vl(U5xxdbuJ>u-71L@aiZ;SxoQ8i4{AMm+WZgTgqvcSpdD<8ufvvxgy=5FRpdRj_{u0`It+1Shh4kpMX zLO+krLkmRDe#iQxCZBbSm{J<=JFYJLRyAomKfF^_p90LV!nSb$^FW0g;z#UX#PE;J zJ0%1D;#!8X^{8pwy60Yd=`SKS>r7*7b53O5{TC$wbaJpU^l@}wzAW4Cg#(0m&@4kVAP->Rn%|He5gI$qV%$Ei-PE5ZHu)uxgR?o-JfS1&@-9x zQB}|tj+OvuB@acR=u`i2Xt?L<2}XR2jZDb5+kVVub@vnD+Md2r^k)OJyRQUolx`*i z)B!1jbU^sxh2ciMsS|oq0pcdj@&*jYH6HWVg=}8!bG1JG+U()!hu#bjQHF$YXefi? zs!-?#hTQU9GEJ_M>D2RE$C=6VIY@VG&+71!}xnEg)8R`U2mZ4223gsU1eIz2nIY^56RRSQ+8>6{!3Z=?{LN;_PqB+kI)ck8Aw5 zyvJkjW!3#~yOCvDYP!H2RR5|AvYkbFsj5FPAN>BMU!jc4!>cT_f;Z}@y80c%`ix## z>jqcS-t1!oYmOQ2Fui?-hS11;k#Cny+UXR1@90pEPq+ z&ShU0Lx&;sYijevU?>kpH=^$zNmJ7-d17B?sEe}v#7Z#X;5A_+<}Py{@f@8 z(|DI+&MPry4~rU)HI~E}pFzJmwP%LLK(%aYaPx!0R@e0`-+!pt-sPc~DSGjbShpgV zj?>eyzRjRsSlP~5UUQ?Aatr@3n-e&sr3!g~Q0#utlr*CabDxvFA~WN@c0-KOKlU~m zeFit%X_JSpC72DfUG5ZHXEOt(2-B#MZi)p}81X17qx+J6oekXfh zY@X+Rzu))y$G!AkYu0t{GiHvNIcA1h+68U6P23*$*JEH5fpURZ)jL^;{n)^3vsM?J z7a26)5p_@K+^T-zS>&`x)E>v08X*|w`UA*;A&n5G`3#lF0gSOS*%4^u{mb%;#5Gdf zTVq`e_lUQ}9-(HYtG-3bE)h5nbb!HD5ElJ%87TD74!&2DFq?v0L!m2v+>lIoT3|Vm zz$4+$@-zAxvjX6~Nl0>E1gO@#5UnDJ^+V(tGGbe|U!p&2+4moia80tn${EeCt9{cz zpYwYiSW`iMDDyixkN9~~KOg%&-3uXQ>hRO?d~2lmlpJ;VgU4bNdw~Q?Oc&Jzu!=ka zV5lkVc?@61Yeh<#S6T`FU^47fRjya2zK=oI@DJa-CU~zyhLLHlrUA%-O9B;|x`XgH z6tB>&IuObYVE1+vn7FbwFZSZgq4f=PofN>K8Q`g{HV`m9sAfq86E2ALYMM6Q6 zLBat4kVK(Iq9!DC134dbYS4ZMX58SDd{uT`Oo}=JQ>3n_|6|{L(>}vAfqcK2B0Re1 ziAlGgAi~(ZG&o_6KF0fD9iIQWo&EVo<=cyG8dA8Xe`MpTA9t-6I>AQV!j zqOEcEUQ*1bRmr|;Y$nWlXZCwR{YUm+z#0HvFGQ&M9)fr-vJ`Q$mR9W!nBCK;cPM{f z%_7D26B8*5p$i*8^1Z#21k|krKp}7pSyoDbc>^$}&xd~h$3Q69a^Xo!l|4Bck28xb zk4&q%q%M_sp}(y20aaT%!jq)dcGLvK7xATO8ooOUBZ=I7^HlYIXFtP~=M+YaCzJ8& z=~KyFXAgh_4RjB1p<(yq%pZO~z-x;TpF<)UDkN8L7zPgByB z&H-9pT#^$s)`7__&Hq=@5-eHteBGCSU<-$nzEvm>e#=fdYQ0*)c_W{((bRFp+sQ$L zyipTPkQoV$kmq9IVIFBbayP2E$}4CCmSyxq+lQRW2YjxwF0>eZl(42C1Pd2CAMF8K zK*8mF_vJaJeXWGLkJWMKZIY`{#8w^|f|JdsySTIh-+_y(SYMRej zPlY+zI=LgVQA_r!*=uRdjMQtPO8A=>t9IT_tscm0+ffe1QP|_uFdfpqZC1a0!+F4i z!-6W=8u&LHAmj;Ae1mHdm!yV;m^S!}N5HC~(8mF-&^DXZ*3?$bq`J&Bt`H`a1(3ny z0Lc`{Bp!T6C?DZ9bpdmuA1jNe*KkjB4!ph0&C7&^9yRV$WVa3NhR*;wPyhsx*-kEl zmyEa23WufnwkBmzN0|At7MLZLjD5%zjO0@rkQQ?1!J7xF0`!)H-HD7{gd06PEiU~N zX|ALBCl%QfKbo`Wla4crKTjA3{xrsWd|(3r8iYJSZ$_BhsvDwSt5`bC1A}9qf{bnl zE!~WtoQ(jT*5S3W`dcd9K!!8FGZ2ge-Jamlk2yfLfK+m1wFtIongrufYT2%kyRMGq zD`ugU!}1dEAidr%9<{fD7}ylZ56edE3gZfcAFq<83wLSX;4Dke;n>SOAJyG>(_~5m znjrC!LZAsjFapAv8T|;D|6n-uJs!)>t^yhI#KGF#l=}6rr)SUBv=8N_`ZtKLftpip zeo!3-*PylE5y6%UCkkJi^?Yp>rdF5z+af7Zp7m4c_ zKs|+G-9k$2c_ItfKQ4u>w|3~q+unE~-*oJ2kfAK{t_<_z_&MVpL~fy?X0JfRH7mT9 zyyO3!IAbTnnnnXz0{A9YQm!Mahr4Cy(#~jFkmS<2Z?B6s(E{|96B>a<=le&yb zRpD?^yJs3!9lJ(L*$s>Qo87Yu!azbIAh}<-dUEp)3pbHJ1;+!QCZqTe9l){#)sbitYZ=@jDW;OkRHtS%HdEj4pj>M z`-`^z*biuUFrM-P7(=b|fT}f6XpS^_Gm^!C>{s*Spq{V!#gt8j2igyfEyFluB{Gm1 z;p65833}K$ltURpa1M1NoCX+4VgudfJhXXFP5O^I47y%_Rl~P6l?p8)CbR%@JfPh^ z{GJVix)><)({d114Mr?;i$5V5{><7YF4BT@w^NRI-K)Iyq}!7LxM_f&$pOU>*yOa@R|AiJ6p}qXQ4#eddN}}!B{?{uNO&6P9}0;jCD64T zb7yYXc8z>xq^j=G*Uodj?lzS?3%k>*G3;&4Ffj_eE|72KgmxwAl6cG+^P_2eNaV|$<;~MI|EB^!JQc0S zng>N*{q-L7MtLg<QhR8P1_`v18 zptT=DAxm(2Dea&0rnJ;XvAtNoqr9|Zb?)MR;Jx?&`T2r~~+YS6Nc01L^yTgp)^`BaI)@=D9xe zZ(S4@-+%wilT(x%&@zD2%mcXxv1bTfZ96G5%kl84`$?7CLRo0T2h!h5N`E=oNXqz% zre#%F0U;aE2tZf~_8Kx<5Zco#RX9!+^WLEi!M0g)OjmG0WO=G$lI|32a`3%C8=LsX{vV@#xmLKx-Bl$1EX1dUlM+ zoM4Cb#57TxCdGW-dSd$gQDa!w(=P>Y83ogS`zo94#iM{|8KAX8u|WScgti@ENDQ>z z!T*Kz#$3PRdE1sj*YBIR)x6>>%*&krkhOslb4eb44k-WGRDlRJ`#KUW8C^kkjLZ=; zkDiLmOV@89YbfMmkg(cw(5&hd15L1aNh4Pg;ee;IoiF!!#viSQ2U(M{F^1a=?+|2C zj8IL=lPz?9Z3h_)NpPzmzCq-rl4amVSMLt~8Aq?otH-=&x}dUWbvo>B8ak>Jqxp^^ z4DbyApZ%gN#d8?3?-DH>Bip_AQz*F!oN%;$l*avBa<)0}A>WfLQhg=G^#?c-z!X3s zDbMrvbMxsWq6LWLNM@Dz6`%lNkOtYuDYg9o!^=~4|b)Mbp%vMNZogzxk zei-IUYkpc6){Lm+uz!Gxi9_zC;BO3;6f9~DSJU*ALg(=>Os!}0MCV{c3=mh~W;eVE z;qagtkfuJ$IriDwu8pu9S#cKLmOB|mXF&GOpgvyUJOTg}jQ#|HA=m{^12dywgM9u2 z-#Lp6pY+S!HLN6AKcf926* z35f)GC5|nRERSqd-uDHJw02J>6dAfdp#p0NVu28Kwc>JW!p;G`$pWSjg+*n`HmjJN ziS!TaH53v zCw&0|Hw8c6PktuWdM7bOd)s|@rXhIFrXl3T#p0P6ayxGvsJ;x?__@WS z>Z`L?s(IHP{m}t75|;v60lsPbp$P44U|`5LNkgScOob&DBrUgJ6u9!LSjPU>ZmJj!3cPR>0kFr);& z^xX*f(t!fSGn2$~I_&XKd7__KwX7(tlq}s65}ccr&}(-u)WWkIJV+3hfl`>Ao4Ehc zPmKEiw)#?7BNWxZ9TdKivicQzLZe&zF_oKW=*Wpbk~#>dhoc~0vn}cUhOuJ zlN7w@Gk*XERzlIt=NJiuv2}5Sv-v8#`Jro+c}d16%&r-ZF zp45*4Ind=7+V)S;h~v^}Vf*ZDrgRj5lYdomz+0V1hv_9x%)ft&HY#M~(fW))4!mY) z5bs_FqMr;3g@K;coJ4hCgh9Ge9MTW%{iev(%rZ|r#i}$nIWxd7E3S$Pm#;Kl@4JYg%h27M?qND#%8N1?b?Q zG#-uy`=$~4^mXR?=j#g-boa;Ax($sK@MUYOckJ@N)81&cA@1I^eRg!Pn^$DIUh)-!JcQ>r4sb*8=^=@ z5fVPxlakexCvJ0nCY(%M>-k9t^($&aiFD;TApnpy;RjdiftcO$yy{4eNj^D<1N$&~ zap>;NKbZk9;~qAlkz4w#F3z$R5n=&y3m91p-Lk|S|_-fB)-@uR8|5X<_Jx)rytrpC~(*nRW|6RVxSc(e4ShQh~I}& zKz3k-8turV?(%?r_Xvsghnr>uepXH3vj`;8WftHDNP=;P5D{mr1tIsf;mrd=(x(Gy ztvR!-$K+RM8Yrf<3Z-0#m=~zu$*@ENE5-#1R^SJ?Qi!-{t@P^VGNK3l^|eL*3~zH8 z?hCyykyH$<_=bloHx|ZB0OY_B9Vk{X-UU}=U|-BKKA0M$B|J(cA=!Ss{NS^mCUSk4 z8~ST3q@8@)tr9~355c>G_OmS&Y9dNajdotD0RDqQ1S*`}>d*{SjYN@<#HrDdl->Rl zZK(}Ly*q2ESzt1*4NMQe=i={&)!(&SWVX0%*foL`lzwLVPr+*br|2mZ=G z#^S@nnDE74!bAAdVMuEShE>$uw$57DJ}b-|eKnP3cG`LJ*6^0PpvlX3-Kn2Z9x?1( z?73E3I(xU@ij1ER^WgKFA6{@WkcX66`|&-iAu)X19Qy<8IR|jf;CDL+4EKftBK$0i z`2U(u2>JdbHB&v#RDb`aJH@5T+9FJ^!5y0=pA}#L(0dK4SV)D&0D`w9PZ^K*^v~_X{H;UX@ zwR7a;JQT_X0Xr}c4vNW-L&_Jt2^G#CGdxZGce{G7iw32Sc`lD1eNH55-Qdx1+|aN? z1B45ZmcMvQ8Tp9ge9Pbe-R?^WYnRKvs1x7cRM_2Y<5N@`H*UxB=k;0u!qf2wg#Ox3PhDBkxlX z+OojQ21mRX9OnPDU(4t&bNQA3_Rix!k1KM6uCTD{+EI-FJ-0(LR)z&Px+(A|xQCZF zej6m|PX*l;Pu+1Yi=tL0LLzb`M!;jyCGFr?V8Gm&Utg$G2SHZW`sI z4QiUTi=}C{hu>b20U3G@(u`O*COidEt=N2CIeEd%1=Lb=9v*ufI#E@C?#;83z45_7Fk^wg?0U z1tA_r5%jyjdG|-5Foud)6zcob$%`uT^4QlLvopSy(JWwTLYmIMaSc3Q;O9Xhn;|gk z0s38EUocbDtjHH7ad6(eT~vs(H}koJeiAvyzJB6bp7YmFu#EdGm?H*ZZuy+U2s!T< z3vY3yYTWpx?~eLzH{3%z33XVL zLrV1Fqx#YTjz1^!hI+;r2z{Ni{2*e@HXutvkwji|7Tgjlf%%kTY?sL;<6hjOdxA|o z`h!nirEKg=`!s;|X@Ic~k0i#$Bd!(Az$uaDE?cbD2U?dlmlLsT%AMb-u@{Ji?H*V2 zSepYE26QaFh#0h9w%eW}a>|i+d{Q%l;@Y6{SNg#0j>>(99WJ$m?bDO9#a|*o4ul{t z_#!C?brKtLl3kteul1Lf;x{47u6S6ZaQOYnnUE#CigFe{9pL&1ih+haaMeHa7rst# zY?*<))`1?aW_k-djk|+o3G#6dn3WS~kW5rE-^rpRpI0`3i4@Q^Ndnsmg{ukp+yg#! z2$oBoHZ3h+Ic&FeP0IIQ;W>F`U&rfUtfK>RNBp3L7VP%VrXY6HUK@j{X91%*;>xon zE&rywZ~2r}Z`a`JUoEFQB$e4D0%GD^kY^n539(8&-0d(NM-mr_+`s$jnBAH;g6=JZ z3o+WEkA8CzZdrH*00hWyLxW!Yf)L6iU2JWick~pWJ4l80Yqj=5o_NQ*aQdT3T(~VoI?>r91%?o*6k(b;;dH?>p)h!=`uCL+ z<2w4=ow2a?^|5G`(T8H$5AK{`Ot=BpibE2RvEa8odK7UVp3@OaPWdYI1rq0bTd=z) z{tD2{ir0HF9-fekdpJEG@3j!TdxazV^=WP9w9wUibUkm0@FZ)HU|NkexGC zprVesW&HnYAO?EmAwU=uu!9GV)D>txdvo-Z+7G`d5^uh`^n*ow@6#EDZ{r@SEUj(q z+{LPq30JOq5WX$oT5APSx?0()-X<~tPkv$IOOZ5d5{T}%ak zVP1`v+tKW-t;R};Bb*U*00w#j{-X;@ApCwl`RV`i2e$k`7?xE3;rXTZi+gB$69%5o zHJkwqt&;04pX!8;dapOOUfG?zSpJK)yTfiZj|6YXrA!?0-XGbu=(oCF&yxQd3*%>} zloWVgAgav;^Wn&%49N$%RLje=fc7XC+H(4_)%sFO{3F;<|DG+kt6v z(4lo*_TRTXA`k1Qw7yy*Kia?erBuQ}_2HRTH7!QTG)@)Y{ycDyxwyb|Q@EehdD++A zCO=Tx;dW=z(ku@~fT!ZS?~JXecfL*G7}A)cy*dFSR6sv`&@BtTUw?h!&ladFQ_@sR z>dfkrs0^}KC*Mn1=szin9W6MmrzmanyAa<43~@m4)7AxFOWH1Z2nF78EQ(LV?xl78*YRXFU!W}ZnC1KYr8T zeCquxS3I%eBj_)}%MS`NU|PJP91$l{J~>&Pn6Bd)o6ykw6?OH1-2o%RUlZN zt1!9FWrW==(6XjUu+2S=g5tn`3^PXaRqjm?d8r>xWH?J`2BOg5ys{n zstYH1yadhp za%jECa#&1M?%HybS)t;D2Q|9M+BWmc0|dnZxOedA#?&61$PONt41HOfHTCYIpSAFf z#JKK4(*D;b3`4|z=XTmSO5bM8DD zl#@|Y{9VN%&V`261t1ORQ3X-GlP;qvVHub~+vV(A!HQ*QSj@9)RKtqsc9o6J=1FVy zgC8FPqbLaS?@%%}HWINf2i=ZG0t%Ejo$$qNWu5(MuyH*3<{q}+JAE3G{ALUd#Loa{ z5)`_?&LQKnUPXzkvE>9!W9$#T50&X%`O=+#8&=!I`fjs=FEbp39gBe+m?RHHt35*y z=SL$Qopx8p=i6=7SR(HE7(TiX$;!Lv%{u{x{lCznZ5n~12dWmDezBd1C=BQ{R-@d$ zF{;6m@mm*t*_Yh)390d=u-R}o{-^SAfa)7c2r6o?i5k_B2MSN29^Xud)syg&8 z=Lc0u$L6XZ2~>zie!L?+kkNDpAPOi6C`>zAjL4;zx?=3?+`^v?KY8-!hwEzyrUYlktepl_r$Y#C`W@xawotgwc%U*B!jyPhvz&b$cg@ z5%=^2AW{h_egP<`{<8y-i&fzAQ87vqJ1dl_;ru{O>q48*?1l1_lKA`cH)G$7TwQ<# z;s#|T@Yh#!$-!#f8~q`U{pZcWtt-(qf%p$~9Rg79a&8`+HsRlRx6-`@aMhhVDlku>DIDgrxT|J1`3}q60dkUns|JrdJ5&$<`p&lsp| zoi_*tY$>j}pM;t$Z&XxXv$^M2`vBM|Fu@bzA@z15o&#I2*_DHrFImiSp4iZ1mx|bR za(L*F)=gx4O(&vJuY$0vG$&}*4*y;(2=+k^7Q4>(VfiM3!UsBbuR3vcJUmaI|7@p7 zQWSo|pcSG^*Gq^Z%|{xvj>t9BW-5eOM8wg?e3s<+mTqCMyMF3|Pd(PDEMvvW^yvu; z_>LHe!@$4u;U`pqfF_QDL>(;(>NJr>eLocF1ih;u*DJIh@jlSq&Yp+ZTGjgMwcp+OuuMzdrOISwyi>jXIftCT zcwGP-3}`P4S;LbuY?ft!Rw~PzdJ;SeuQU-w;cG`Qf5^?YF|aNI=>y<7qdJ%=l&1vPe9ej z|M&x2emM+aKUR5R-SzNv4rSyyKjY&Lp18^l@n`qY2_I?8!G)rT3ubfSh?OtS>lTDJlWpWYpxQC2@H?Xy{P`WsoawM z?RKx;c@%7*7(d`9!_~*hC8eN=U2#H0Z2!rZBB$qk_1eE$yL6)8mT+B96iXpal)u^l zv?C{|)Q4N|?rKDnCAa^v*|2}Y)(!9K{QsPL4q=?M)hkb|&MX3-t%{DyqfT%-3M#qL zS%%^XD1A04@s0xD=K%W#(FI2?i%v0(*+warB6NE{xp!U-n~C}w|D0Wb_*EGHeaXJZ zf|vk3NK1gRIB=`gUI=lj|95Mp|N0s5?pE-b;ZG{Mu-2598cO0*TbP`c@)(=fZ2UgY z9Czx8*}1jQB03f2gd!*a7E!!uh?8jYcvmRq z-kul`?<7D-{p~f|M54x(uL)uKE!F@|NdSf#{K7Rw;UYNJ|KUBrmb(V?6*PWDFrk;G z@rF>vxco3=8`jCM?dKl!!YCrn5dPQE&32*I*_s6PCSS^*#A!KZkmjP43Wgs}XZbI) zHd}Js^>t2)0F8!tNFyuZBw?^jhf#mjmvi17HmMGac$0-gly*1SUGa+_zgE@Sxxdi? zmI+4ef+i%eeI5WzIw;@a@OKKLqU}ag>DM&l$b+(AO|S> z5HYbn6s`$?0z?&zGx!!BWk);4n?6yW$vGtV{;hiFW7&c_5+ZFoGJyIx#Ls)rz`oZE zQL2EPx+_uTXlK$j0`bQ;4A%}Lc}QrK7!0P$U-|CYG2H6~=mylxb3)fB%@g5U7*CMM zYK&;)9GfK8JyYAY3smTIKs z>~m*6$>r}il|#!>(VDN-YwVCMI`^G`;|jljJIM&S(j8vhVOsAS8~C15d0cgJI2vwW zxmZy`-~Re|T3(QWc^>}-`AoRJ@LNZ~hB2!Z*1X1f2h%{U&+6Ld)0H`ZcI{lTEhHMU zH7W5Aa*-z$Jzp9(#$OawRF%91*YiBJ19yr4 z6(C3e4}y@fvg8==*ZnyqpbEVIJGCj2aH=sy=SWN;nLV5?6J&)2NJHlkaaj!?qYSyh zFj-}{ub%1!z`0) z?ivxjTA?fIkP!|b0SHKev=7{i+5Lua(q7a`9#2WN>3LfTjwH5F60NV%CbGFf6{*mphuK+EM+*y-(lJ`e*~3VyjZFUPzq zaF(8KYpnK(canbg2rHSoL(@6@@E|>`#5?X6y4hQh91@fO1LEO_U3}SgxySEKQPF0q zpx29_VBR?#-pS8=ZSujvM7~S$&gh)&;L(9LHG+^UnSJT{VDEdEee<88?eCMlMg6*^ zt@6%lSh>wS4L<&7!>(KwpLLOZXN7I|mUDL{vwZ8+Zpx){!uKHI^z?mS3+#GuAQOzdPgD5(MA{NVY*P z=n2G<2Fh>3#(`#vzwH3eZo?s!`d_i_z|6tN=DeHczK#S*5(zC#m|!1q{vQYKuI zh}51_X<_}9e)E-DN#p)!KYpTQ?cwJ$1=Sz{Edhvz(53bT1C$|U8`^un%kYiqY`&3? z!Tm==#@gy7xN8TbyT)x=G@JJ%uLI~R4ooOqsnmno1_RC0|>xntrtbWT$Ro7;k6n{IC=bC^*r#P~yPm#&Hd zumN~JP=IO+B4&a8_&C1f^{@Pn+NWE|w&G-rF34^9pQwK8qc0lqkfu|h0Z=9l!p4x2 z&7VQ+e@F0!3E$GRt+lb>L-rloiX`FF*1u}pmh8r~Uo71}0LG3qNCrYmFQy0bMKDE? zB+-#(kkOH(kO;6vk*Go0m^&QQqacZ4D8sBR+!xVcYobea=Nj4#3tcW!D|oQAqfA_9 zW6@{jb1i}%pGN!w9C$qJ=iw>1hvZPdXJSW}Y|YNr+JDp+RAa4eu~CVR444lf>2v|- zV=t%96g)9wtLsfK%$wM3UfuU>;NGX=zh+BLJmM3Fa&`C%a05VBIu2+m%jp@^0`t-r zxrD<1g>1a=&ubzyWSOL{Qw%aau`IZXirIByBw)q0gmx?iP(u=`mxnBpwX!uM2Zmvwqh*^K`q* zTxhplR6tHg6J-#toDJlFHi6j6-!F4fXClUZjHn{ZX93GbLdNXb@43zH{F|#6d4-iI=;HCEtH?g2^)Hkc**^h8uRr3^rG6 ztBB^}mGSPZu3qabZN}N9i!y<;s`8bq zRmH2Xm;3V^TlP9Ld||*m7ws< zTTwg=$bm#Q#Dw@ei-0mKeI;n##1=_Ed}I{sKc6&AzTqEkjhNC#z4x*%i&B{ZK$-Jq zmvCr!a@k&5^tR#A&y#88Yy6K>W$87CucbRpv&$Onb<}l?(Pd?Q19D=#U=k!uizMeE zA`)~SGN|@NL_~J#1&Zc@GZhA`{92U6L8^ zhr5ghbrwphgGYWI=z{;AlOKoxr?j$ix(rhu`*liFH*r_1*{9i!EMpJTbJOB+?PkOY ze1IGn0s(mrHJ1^cN-1{A$%At8;>sJm<+VnP?-iXZidhTk=`%_=;{q6BfSd%Va)7_f z#%{!UJ>os~qj@PAHT2{JPr;y3R%l^Nk5M9Jv`oEiUz*z%Kp)UhfQuh4m$HYD!+mw1 zRnwoPdUMwyd3En;DfVhUx9`6n8A1!l-OdumV9*(u5_-{(I;R+MUY>VmKsAzKmx@S; zW%F{YuL?jfLCyN2FhUJjQCTGxXi0=X*-bgiS6C|~mu<(CC2|)S1932C5`wzDC5SYJaDBsBmqYJ# z`j?9Pu70N+tAwu-B!_GdX=Q{y%C0kk^ardR z<>%`0KJx>Li8Xx;o55}1qKHd@nm{-jtP4h9Rsqix|FM{0*1oBN8@%goJv9pq87@1$?sZ%hpbs*US z_2b#iMt}+ht=cpDRnc8GhD`nmdkkj9o_W=&a6kH9ZoGHz(#q+9oER9e20y-1C}IPS z?*U!Q)dwHTY8N#3Y~SI3Z94ge`(P~$xgj}8wyH&A6$F^2z|d4^8p2=bngO|JV&ZEY zI$_~yW8UZ$@qc6k?(fN%Kc-ioV31k7OL+!tvXmsC$-&iK$8UsswUQ zkp68lQ5@#jBw-xxO_5fPqN-YsP5?&0ErU1@sh~p%ludH$+b$`;FHck8oN}cB%a*l3 zsv$h2l6>yPAbp~Xt581(aDbX(_-pu-0AUzpbZQhdd@&?3YGneXHVP2sa05|PG=L0{ z(U^U&{O5>qjh4AaK?hpPQ(qo(WG#X<7G+b;f^Oo!f3K3Hrio3AUBCe8Vq}%0va9V` z)63adcZVp3s@L%~{yYu->UvLi{@~RVFh^qC7oL1Z72?`%SK-o%5xup)D{t1^v0nd& zUG%j3=cayR&z`;V$WM8|B$AW{We{-B&MgvR2ZH7PAO9cn7q-M%Dn) zSiHN^q>BukfjWHXPCHRlrd38?E;f-YJf#nP%`o$3TF0~r-X2{~X>RPK&|*?&cqnL(_F=ee3yMSWc)Rosmb4jIlm{Lae^l< z4chI(H@|fd_rGeKq4i(HX<)Dso{!diL$kl_8#o!jFq#LvMhF2Q&qUz}j)iRL7=H zeadllrW1(Q^&vS!SV+Jth$;rxn90nQ!#=QfuUz?)!;{^y2YtQztE zV9PIpMS(S+a|cOP6Z6=9yz?tlrMdQJnNudgul4V=J|6t1Dk3=-%a07-vwbtAW7RH3 zjsDF+XJ7NoJ6lpYr}nyrp1z%x;pRCY13@GBGRl(>5qQ)Y)|7&_P*TG|jOBP!^h#Ay z$7~XFT>8cc?AYls>p#HINP$ zXFXd~>Bl*|vyp?M-Dn<@k1!XpZZ{mSnjtsV^Ra$?nH2>D3eW{Pn0Nu1!RcyF~*p#{T8@_$yAvqF|1K)$# z=_!}#IBNm7F@`Zu>Ns9`U+1sYD9sGYvo}*VYFCx3f=1gzgn*nRCx{`zuJpuZQX8{7 z0i!~%H(Sm**3QKH5upy&gNRcFx7Ts94)aBDsX1-ihK9sGtVD8xW$lJiJ|TwD`_cd{#z&K=3)b+~YXxQ&M( z4Um)I;fCavKqE59Yza5SL{M4%WXKLEQYH)Z&wfqEhwhJ7lIwbP43%H45k)J;c~{VuOHHGO=={rMy(4G4_#h=KEi`@#V+i2bC% zCT}axQ@XEv%Y7*R#Tr_g)O{*Rt1=7UP?86YM}i3;AO{$(kZS1wgi{EWZZ7y5yy)JZ z)wSg48Dm?e)UYYNEs7<9^X{`vyKKz^CxCthNDuPhEp~vpx}9A7I26&REWJZ~2!0 zRksnAD`LN{ys6ZFdwVBV?%X8J}K@I|Ww&o{btiv;PjWcJ2-l>SGm$5hTT(V1)j zC30|qv6`^`bQ?iz18*1+z{{WL;B3UKb(8FfBdl@! zYBq~~bl<&{l*g!#{DLb63DG4krWY44A(U1^S0kr zHN`)wWkM`q@IZSC`0ZLNLEK6ugHO?C8CUX-RrQZHpG^t<9YZe{CwYvgW+utnh?{l| zfGfZ+h9Yra$KkIBeDKgs-C$tul}iQcO7SP6wHJ!yds%qg17&^-IB|ZR4>-<2v!DQU zOX@)jCg^p~E?K$ty}D~B856O9zMaNM*+FVwWQ||mjp~Fi@z7EdRCY^~`UE3t`@Sp- zIH!6IRB|fmQoVA;P+WA2lyTdjt8$@TD(0zq_811TK}Hw0{Us%c@A%#1ej4PK-m_v; z7;be7@AGc~M)xBD-t-rK*rxvN!p*RVWXL2UCL`4rp1&a*_phqNU^c?yP0gm;x}`&7 zw9_8r{cr>vV@E)rv?Pgp}thdTt>n3;E+(m%>ttE~e$aZoe@ ze=Yd|2m}7{-CnaPhc*@XZz3A4&AAPVC2H{C%wE zL1A}wIp>?BD>Q4*E^Hkc)$XCzP{M%z@UEa+W)jLtCw{6$xLAbv5T#-zd#NI@bzr(8 zRA}}WL`2SQB+xB_3;_yq0}*K)$n?1En;+*T>6!E`O>*ou2)NW!)+~r5#MO4AOGIGT5FIA&#;0! zD=Aok5hSwyH_kt$@T*+;u?H9DZRB;a2re-V=P|FT4uH%+uYV{Qx>1AJ^Y>puH^$0- z9V?$UD*TyP+V}Wp=)3o9O!eon_qx2<_d?JVjprhacG`=LNe|E@`Tu{08_q>p$2;E; ztta%<*n>@e%2*HibXive@>_^il_y@^c0c`bm%2UH>tf?9w^G)WN+kJT5i=za?aM~9 zmA-sX8vweJB^u@Qn!QN`O9yk}pu|J$W!q6(3%U>bcN*^QAu`R558|M_P|Dh!D_`IjTfF}wD7k&2l017a(O%&N{}5XIiIggE z062L8CV}grPZ5Y~t?Ut!?U%|@;b+R{{j2pR{zz094%t5|; zeiTBTSVb;BD>rc= zXK^dte@1z4f!!t=J+J&3HP5hBPM6qX{ah+idoDV3!N_w6;T(Bj{W zj~U&ki0_;3Ikk@LvnP_wUIB8TGe1=0+Tn>P&9n}i|4yW9F!M?+TC|6QxgFz>>Qq({ zHK}>?>G$e)s@Q~BU~(cT)Pis5VFTiW++o|Fu9K)Mz{04F$KMbLwwM#vi zr$-tVqW-+(RQ-+PPqM-|+QBEXsPpQm+$xFEfp`@lh{7iY&H-ZSfqt`);X?ZyS~Df! z9-N29t{2|sUmAYd!I-v z?Q3)AZ)tM(Y)gC2bT8-$em;W_c3%os;Ku+|hh2Ni?;h^%RP9Qn@9|zEBt4sv*D?V<%IVy(9&v|$L;kFQRp7^zJa-&*& z*WTd&4nmg#q}h{*+GbBy`(u83yPIT6*6Egw@j)m|)Qckoyj#Rx{1KdlIG3Io1OY2oAzhARiYzy99LW2eSlgD~3L|mW4hy zDfJan&n4vw$no!?Fvi=}Jvj$cU>D)Hqz6zyA>ZovVW0KQ;-v4_M?DzzQrG-sLs_5w zBid50QKrQXmtO>&MbI((qQ6TIv0)3yvG>`$20E0=O;3X~I(Ih8o#MA?1rK-Xw+SQv4jO5jcd$)+#^~r{1yiW10t*AE&G6$3Y(k*L!q;R=_W zx>nYWu%29P#8EpUatCtft`A&G_je<LZx6o zq0C|9JOb<&3?(|FRz_C`Tc+JgbbIkG%L3zRQLp}&5z>8J8my)`Ajb=QUHJX_g zXsFSs>29LoBcq@qBZ(rTAl1pGw(2;Xs5i+f$KQw`QRHaqB$3zCRe_Ou`TyHm`QdpVaejAhd z%pTEaCG_=J*e7j&{?|HjNRt7XN63fy1qO-wi#)4gxG815g}~l|uHu|Di!Ix`Ju@U-9LrT^Bb^v&+i2?q(ibSEUN{3)xGyD6*4>WD zw2ZAh1OF=0Yv#_JbZkz}_n+G3feQ?#+C%W~&*ek_fe&~bKR!^r2~WP=k^9P|xP7N8 z9O)OP?=6W+P~vXf0`46LXcz!LmZ@!gI0A#R*#9RW23tG4Jp4V*HSVo4eU#KW5syCE z7LMDdRO5yY)YY@5TspfBw@)wDjzfrfKXc1PamVh3_U320hhjgqu4lgw@&7Kgy~*hZ zW;tW>fM)-YO4tAt4#>c*Aiw&yc;@pBbNAkLI$O*ldqcOd!{hxai@0!#K;Re?Vu^u* zpo_~toeb4eU8dlXkPzDrTlQbrmcLKT+{19NA#c~COZh!TX?tR}e7(DZ=-reLoe>UE zebmLWSrVl%C7;&N7f+g27PpRvHoXmx?xnFQ6*un*{G^H}2Ix)abHw2qz8SQ3fHcxR z>Cz8}%A5AD*?hI+X*u=SEmI}+JstUUyACG|-7K1cK>>wW@cXe8gLpvye)D>79W^0+ zaP&Xr@#eJHI?nophSbY{Y%JE#XgCeuOMU`b%zg~hn-AvjG=9slGZwz!dA*O9w6 zUAxf_e}QAP2C3?x>JZ?UaR9aa#3lgvg5ek!9gwp}a4^Zi!yx=0>jhj7*phePOa6b2E`*$;w7&@vLabcRHPd)D zj5ATysL}3Hqs{WEPEXIS`{KL+X;na40Nv7HTCxKwSO7-#t%zoajw?S_%c}b;#p$38 z!)SueV--UYJp&YxY|+o4ZbSmK*@2v~fg^-bRW}f=sCCojnVX9KVeAvP^MR8~_D`OR zZHhk?cY{W+1$b4U4hO(5t>se%-&+-YG)<8!pve1-79))eBm5rP!z7MuG4V6fbYOyir?t(-yo7 z`b(CHo+lMwc1|$l8?N-CFK6gg8|92(xX{15!RhI(CGVhojQq^C zWfj9@gAG@my)V4!+$4Z_Iou?Cx@_R;qh?l_2`FdHzBIzo7EUeuYz$ksE+*ZbzuMV%hpwu`ch!HObJa(KwRDdf3{4Lmn6 zK@TE*1VBAYz^&b;%q2s2#@zrk+V+61K=BQnSd3=D<1iS6~ z(2OY{XD!01Isa7d3zMoGCB1*w_`A+;|TH5_J0y z(v7A5eY_`qg0fc|d7mQaxl7UG_}{FKe+p1S?-!k4G!TG=fA14S6$F^)FfWIzicQu} z1JmVjoYgO#IK#;TJr1*CTE?LIPJ0kgpgiJ$_6nDqtw1P})5ZCZY*E9KVOWiE`~^|r zt(F~!*^`8QH9GIr3E#JZ@H~$sh`z#)@53dgllxFE-a6x|)GKhsJ*rC8e0A-8mbX&q zCLOB4uhY{Npn!NmsX0_@IB?0s7q@+JXV1Thb0tcYdALd1YkWAiIEvajqzs*RxYTb6 zcn+X_EB6KEuMcs}-jA_*GWtj*vqh2Sd>NA9Q9XF#-uU3Yr6pU;vIuGtFh3NDLOZrfdyBy9QmPv@R6cn$D z#f8{g*_8{z@v^u5SG5!pXxM+n)UORyns%{%2ILz)Zqm{Pcz7S2cQ(g0$N!J8?~doX z@BX(*wi0Q`Dk*zL*(+pMsAMFORVpJH*|LS~tZd5OlD*27>^-tak?}oz-ahX8`~5v0 zzw0m8eP8GCetll!jOTftbH;Tv`$(}en$){bK4&b#==mg~grn+vsj;eSxDd1=3^7L< z{kFqCB9WKno(;+J=88`eL!gq-_Gi6%{y*y%W`|?1H)ol9O#c23-;tm$cSe85yfJa( z+{SLmy2^$*MoHyM&lB4h@35FUdX{B`V2ky7fT09CjRdf(t!Rt)@x1U<Yy_=(!(pF}~!P&WZA?89`QXBO&yz`ZhN%yayl%r`Vy>o#65V6p1l zFZ!)j^+KQUj|mb9Qm>OB2c!ywhyCFnI%IoX_s{L!AA)hq+o25?D* zy3@6Y#HsFqfr4n64;6Y%9rYx7-&)!p78V%%89RUE%nkdAinv~kNa7ba{KkD$zOZ!K zf*j1DM$|$+v?fIy0j+f%mB&)N1n&~Yxr5ng`v%9}tE}JN92t;#&zHA!svH7lX~^Ro zJU3^gqW~OR-0A1dCvF+058XLoO!Z^ptiRoRF_}qc^1JNr+uoIYkh+CAth|V0T2O!d z@N*Z(I)~0_>k{!qZNz=!t9iAAKilAc?GNdnJEH0SZ7k;dfh-JgIr!YvH*`dER#Bnp z1z(r8oI!Ryu?M?VW{Jnc$_Il~#X^tq{PD{G2NILu;X!cGVHih@{5lg!XX}#2~yD7{@`=7sc1Ohb7&6LubXaW|I|0w&*5NN zH|Fv;|Era&YBl<1T2o?W3MQ8W05Viu`8NZtEFJ28Y|tCqXH}-1&?U8!h{4Cxs&pVu zDKIFwySjPvDJ)ZBe~=#vMi@ip)52x(bnYltOYYq&zpQ&>I>6=vTOOn1Dd8F`j4Nvu z+q5_xAO~Hmks^pcN6f^k--PtP6-UonR$RXJr;qZgny`pMU}_%sP4QdD^NSe7q0g%r zb#4H9$P8IRRN!!_jAWd(2PM_Tp*C!{BnU;(CoN+OQ{}1&_>Ec&*zV-zojA7Ckd%mqzQD$40<~ff19?6yjjD< zOQro1+I>t%NNDweH#1AohN9Eub;phpklVi{C>@z~)Wb%iZYF%q&2nYnq^7rk9--l# z*GsRY%nQZ0)UK@rt*mB)oFpeFC+bq}AeF1IjcfF3cJA?#R%djzP968bNj0Mw*pe{( zK-25)+4Sz`ALv~qDFy9^QQM!eh<ZGlOX6d! ztTLa}KFAME!%@0!=PjC;Hy_KUYVWX1`emajEu+ruRQQn0w(C`YUwm#tJ{i1~PVk0- zwu@A}M!iJ?&aPg&OmyV|uea2u!?LO~wFU)zL@1|YRJ=d91&9*=%iJ$Xf>imzt^89# zf+|Tm2EL6xhSUX73^FV%41Y{fF=~QK{+IR%J9y9lHuk{fSv#olc`aaWEt{UZ=-k9B z##%sYLwcQZ`Cg?ChivVyu{6mCFAiNEwpRbbDiXQ2ALTmL`p;P2HGKQj=AWx6GwHc- z?|w}$lmUS2!i(6xsZsQPHK!Na#a!f6;p)A!!_*V>%Q}1%^DDOLw7fS}sh`6nq+~h7 zp|d_J-d{ne1#mul^m(|V%)A-a+POq0%mlKud;%gn!%q<0mHA~LAg7!MauU1(2ybHx zTo(i$+GFy5$U7Hq#O}g5Mk0dO)p0rgxo*`TeEA7h($0_*KM0%>|2au*CZNG0})r6y6+zv)%$oy6+=VgZ2UXH=?w!3BDHvi z=$4pahbVo`qL`Sd`ZwUSz<5<82z$SSRx>w3W~)a@zJ=h>nwL(eyZ+8$rl4(5+w7@f&fFI z-iKoZn&@{)_Tll5{p=VaGz@iKlwtAxq`pcE4i_(}v|HlwU$N{5aunDW)NwZ-rDRq0 zE=XnjJw5(-Fyy>$vcdqBm#@`>>J)~KJ?*N67~lT3bDdE7sT zHz!A75r2W#%i$-W zq$@-e45IM}ML;C_;nw;7vMvb(CmBk zwG4`msI3|cV&KbG`FD!^sna4YRrF(*$HY2KSWL|)7!v^#hf!t-$*tiC<7D~sA@c)= z3)#ZS&UWlqZ}37{tV)S5)8GxC95K8@`w)JgQAYEC__8#Gscl>U-`-^DYPaUTXZdJ$F||%%iI`L8hcJu=`Tb^J;^JIU&|5y+UyO zrNQX8@Kh^`QnL!x5jUV31T1ivAzi?7Y@(_IWfpxqVCra zC@}h1hYN|YGQg_y(g-83l;ezi_eMU!kD<*aG)V}j;APWmf6^I<450l1 z(nP2Y)FSc&wkk$^ru8#|bv`aIi$0L~vUY(T*Oe*%whdP7*0a0+c=k6MUL@)VL`5Q{ z`~L;t9Ks`LQ0HLzsM7t{;zBE&rB~&B-@N1_ci+M@$we?7d{3BNjxr*(i6n(}QuhfpTrJzw$>+bjuQDWLoMdWBkW0bE)ye4fHup9M_2xpPDY~{G4*8&}FT| z=l9t(fAWQxw|sacqUK=!VBjRu!DIcX4rRh^ADMwPdShMQQdkpnm1q}a6jWE2chK#j}>dhoNUaCyzK61$OJ)&)nP!g6^T}M z$%evvl;a+9cE+z3++>7-*@Rh=Nisc%p;7%r*utX;JSU*qBj`rt4|F~>Ww1e$tQMPQ zwsBTr;W+Ot0$D@z=g!~dvjTL_C-SKpgXbhhUGVkH!I8jas$AL%J9*VFBD8Ux$7GtL z=TW}u5ayMB6Ip_4nfS~z&%tv7jw2Ee{(-bM;t`tkiCPF<;4b5^F|Loqy8k;>HT4aK zxDjb7hf>aW(|W+6xx{z{5v9{~R1#D1cPO^Dd1XPr{P+sndolh5+X?o`;Gc2|t2*9& z7KBSHf^?owy&L`UiEdByHq>wTKa+G#z#=G|feMcu4#i zjDUQg9PQ4&&%Yma|06x)HSDTj)oZ6ng(nl4Hgbf^jKu<7a>e1w!5kIjt#`JdjbYYe z`flFI<&(<^t$lcfce1oApPoHoom+@)FYV&!NI(Uh*d?hmE6yLrxt9E_JiK1b+iU#i zvZ$FO`;xiudr1h5&wJAo(9!=r`4e0w^pu{jk!YQ0PR~feNm9W)p|wtPN7uaC{d{HN zn`nGJ3r?l)3nwpL0M`e?9t2umNBHCLv+x<>E>`n?ZI_Of(!!kT(7sGb%oO-hMvR=+ z%)IxtDX^)42nYe|!F3!xDo(F>K0!w_bZ+{b@af6F3s`V%(0=-%IXdp+B9t!^fvSB-9JhOM1so%g9K5h zw$zUPd6%1vm~ClrEE#tX&gHpD3~Kl`waWXU>O?!x&QncHKTXF|(g zl`k`&Ey5%UZ!R=1=#=-D;tpt9hx`{mq`#3oZy_??2VQ|@`bt&P`&k0)P2<>>C=#=H zmAJ7%lS{jM@0J-FYsG(o9F+4SaY{Ebeg%#pThQcE`XWEph44p2J{~15+4VB^%KVKu zxVvX`S#ayX!G#2n4`zT1Dz@Jz6Q%n{jtUNQ zXhsM;df6dBq_sh-5HEkILI)TQVzK6-|V2 zUUlAnm~ZF7W4c=XXVB^Pg6G4C`f3-IeV0q{(B@n zb>Bq;b_K#Y{W*`m&$QX9yw2Z;6wZ^Sn z*^Kba7MSd6q-`1;E?p3bBOcM196AspN&`H{6ewJ)$qW4dZv-)oZ)V zS=NOWJ-UqDyr4_Kla;g)O%t69q(><2Lcvn~$!H@$9K<0++~eVbGtb~5=W+ges2PKF zW>BQ2|5CLODNY{Lu}VqvaUgO_2vZxb|Bv>~et(m%cj{m4cx{kveEY#JdvWEk04jt`Gv&^dw=NQa5xk5h>QGq9n{`Z?&aj)|(6 z3OOj8wl|v*G$7M=;vW;^O#WE|0K+-{QgR&Sireh`zFpeSa@6t?SM z|Mo7o`RGYp{`+kh|G+wP0BIlf1HM3^C2|jZ|1cZtQm1=G{CpWXOfwcKccs@^6!%u0 zH_ij!4_R30`*;X9G_O1O;qQEojAS7bg=<|u*gpcm}M>)GFoRl?A{*@_k!n@j|*m(TBahkp&$zPD; z7dV{a9QY26ztnMRW@YJq51kW<>uAtDqmk%UV=NlRQAkq8C{}=>wgc8rf_e~{VhrEm zExTt&n5<^KB?!<7y5Uf&f8+lq*bAs`3n9gI1LhC9OCSZqYw2jOs?G!Z(<|*UndvFnky68E{4Te&F5{w1 z(K%-loO`-t;ULEg8-hA-&n9#T`ExO+_Lr^bSo5$x_sjL`UZN@I_^I)xyedj|GTzmV zB!S%i%sYiANtr1IT^uw45aKn}2dB+H+3#5ufqg2*tJ!*!Xz1?At=^A|TI=O;2?uuiu;={y4fMWn zL*%M0oInG}yCjAAdQs*SOX_@ydi$C%@@ zus$s|HJR~L9|bu`Xd=kSR0Z*&nIP|{dn`1d^9%cZy{f3MU8?;;xYl3U`Yrj?#mEr5 zJY^UL&QD#PhpwLwI~`zIJZ>F-p_Xi>vi70b&GOj_o}X+kMjNt|$vNRK!L09(W<}YF zY@~fHs0Smrcd=}w8da_&o4D8Ixk|9w6>Zd3I~>f%nkOT){{V6(!L{#p9;m%wp!Oi@ zQduR5Cp53Q_$rR;`kR%>|{&cOn_Mg+sSO3Dk2?PoWNl;%XbvbgRR(@gL5&6Sl z=ys{tgi7jb!G?GxYu2~CXpOUcY*tUnsqP*Pf|HpmJk%iKn^qPQI9~q6YtsdWH`; z;1);$5QZ=i_JHh+n0E`@mQ*Izx*9WlfkhviKmUeB}(f6v> zoauQii%@Lu^x1Dt4mS9=*hxeD?^U#s@RJ#N@UQ~XAk6_i(@^JDfFM2aythl9RF<$s z#Kj3(u*shc$uc0N_n7;N@At}2tU(ToZ zxKAfUv=%Vz)(NRUrWKHL?)wEGhcY8BK8LODaK&-4G3a1$I7T3bGA8tbVWcLY$G|0X z#=w9vd?=s-)#}bZEXO(IsoIXeu$Ipw)z)WOFR>RKUc9>T^5@Ei z{eES5Ptv(<^w$cW76reLg|Wr?ETVZM63(Cxp|1zR&hI+<;ju!$eJ68pmUuj9j;Ywu z-(gIcW;^RCyfxX;Oi(scO27ZZArFD_*E0IheWw2lSozQXi2MJ?0a}6L(%DxukROkeU#A|U-;lHo9Ko0L-9Q)EFj?q=Cr(?o{@41z*$v?CUYEL+3 z=U$$BezzL3wZP^@sq?6CGD12a{hX5hU#my{^2R59nChNwdx4=X;ws17s0Q0EAi#$pr{TX4 ze-dFTp;zyS{tNZT!4E)n5qje-DEMB8JI5TA;>@ zgQ6Qt&7fOWp5q<$jG)j@CmFS?Eouy=9c9WUncZ;=`UMvsw7?<%vOgBBc*yP;+OMQE zmG_&yJo`Cv1wYuAlDAx<&8$VI(6d;F@+~MHDQ+&L4OKSOQ!~NFpAkJ;Fx}CgsJ{*t zKTfnyihWbpQfy;dFIhBlYLj|l@T0aqrHJ!ik6OI(detQ(Ze~@gbN6pah=ZftILvhu-}M)n{%MipWV}Cr07z`P{kl z#wyxNPv?2pgKUm-u0QQ5Ku!vplA+{291Xg;n~M3&bD*1uBD~ro{&}s}c9+6~iR5q3 z`M6|da7{(Q$$@DuP<(Oly-uXd39R$?-Po37t^JPnyia(DrdW!a9`+)NS!AKIVs33q7pcp(A8t#>cRIY z%*&?O#5iN^tHQ2Ua%M)Qbe!T7VBdX=S#H$)NZEo$hE1MAESbAz~0UdL`6dY!cD)Kg2*+F>rc#`eO` zOUz>gv$gR!y%ip8pH>!-A%y+pg&Dp`klzAnJH*NHb9wW4n=en{g8{L42bnklWnI~) zeDmmcnRJ2USu)4t_S0yG<>qsVXk&>HS9YJD?iJThNBu|c>**5~YG*HzG~U)@{P_>( zn18N1_*4Qg>lStF-OyzNaRwTu#PPNURc60m8N^8}xOL9GKBHuFc{sju%I;3t8yQw` za-jSY(aAs4(Qj)L)9hUTZHgNH5W}=m?U%$#7bD1Kt~5WbYs+D{tbS`4#GYx)Su2yPX~bO zEg=AdYfwJK&rhgrgxjorQGiG!O=>0Yb&_|LKBhSN#j*3XjoJTh4;KwDlZ|!OofzlEqQ6R?yJ}OE(EPq3V2=M!Qrrt?(`%T95S>TOC zDm76)U+ywA&z6-t8@Nk^*(q8Ca*_hz{2gc`_ZTz!d;T*#GdJXo=92XOu){W?AsKkC*aq@oanF&frxD9gB z{D%ncN*%%*cO;7?$H2zK6vxCmhL}qn92_zXQD!U*Q6QBcSeZhKeJkVOzEWNzFn27e zh7Di-yRJ<~9o`g2jGjUAltjR8oN4~ywe_9!x5QB|!y9;5m}DebdVBQ3q9=o~m!-`m z*YL98+wdHr(tra=YY+cHU0c}aI9|RJ#PMI-u=Ul7Gg*}8{!L1&q|<~d5RO^r_4&SF zpg0Cl4T6|%9~JkXPSWaW_Lb4RmlgNCR9kf8n?!qGP)q=wFJ0=!N^cjq6wqxJM!p{$ z&q@gT+L}bYXX&fM`Wrt#!zuK1KIhHE()g^d=o zkf4waviwthQOV%hX07BX#zPW!F-u%Y=L?y}G|xZ|rj#L(^tWEL(zm?eJte7;{{6cR zQ;Ba|EJ=h?WR<+kX=D6$l8;SHGkstTVdN&lVA%;pKa&^O-_$oA^=LaSGzkx=DAIi( z=pdG0%FT9+@MrnlLpAcbe*)xvd_KL3!$ zTem_2eoBBG^ngO1$rRG63XXv~pUAP0t-i9QfOzv#Dy_*1?v04AeWQa}#jiv}4Ye@9 zsKIMS?q3nq=^?zpndJ zF4w-_BAHP4{fV7;t+cuSyBI0moHj|6N6!67q#LCd2sbOQnJcAR{Hrk9{?8xM%JQE zA^j*#70v#Gx%%Z>@6X>H^)k#-bP`mFf-wo)4O;Okx0wQR*1#Wz`78*av3f+IC?20% za5T=*&mt&wT`m5t=NN@1-8bDYg09El(}$R{XP}0^nN!--*ob}8)yvelgPuWcy&)k}S<))}%&b&5&JlCvORoqh>Ku=l3%c?f1L?sq?+!S)4}`>SnHd&-GN*qS*EAScZO1ipjc_v0Vh+Pq`` z#5`|*Wqpr&xGYP(I*E8dOyVN<%`2kxMe5xHngCFUNedp%XZ1&b8`zg24WS}wN~x*{ zPdXZ{&d=Xy)Hhms-i$vZq$Eu}6`(b@?*qX}psweaqkLNG1q%Pbcjdg^VR`bNc#%0P zPJEy5^4Vrz`F_E7U2+_7I&m(6LoHtjS_uI}xb3FdMI@Ol0u8U_oKxwmV|{nJbE+)O1e5*sNk9*IRDhb< zgFZKgzAFoxw$p5+R5Ssyw14TX=(l(s_`2-u{61joE0IA6Aua_*2=(l?Q-}|GoWS?A z={ll+Oz>D)Nqm>zD3&=E14;C!lrMYB}GHI(I$| z{YsXb=fA8jP`>hi{Nj_FNR)j%f7u5oWpJG!ibq(n`N-fBFyW#niJI#6Y`+V!&zQ3f zDfT{d4lP!e^|3dKdaL{}ECODuq!e5dl1=9FPmJRtNpQXv9HUiv%ox94uiAGaBZupGkv9fXExwvxi_$P zIk*rKYgGvPbN!FJXzs6b{(Szom-s%@IUT?79OrPi_H$-$f)Ne2`Zhe+}0u@8(MLMD>0OOgie;>=(v zt=)TGt^WFSly{3%=%Hz9`)L2;ouyW_8Q02llhR<$4p$1YG>!C3MU}Smn^h&CG@v#1 z;kcCF2-ptCYEBWlLd=y|l}Rv0$K8MhUm#!oVegD~q5iz5{6G zX0;=dPmh->_3sn29cKk~r(ebizb0j`dE1}nS??zH8~Q-Ep~Fd)1HtIa?*83$?XTtK zQI2r~K3a>WAI`&!`JxM49hsL{>tBb&RDv8N6A=$DdJuJuV4XLU^*W-?y_FHCu0MO+ zWK=#1BQbYGc6{)Hk9^guK^j0&0XhL+?cln5{6nu(X zvWrZ#j$dyN?{2nMfSfodOe;H(3p}E$GTLE=1X*69cJVjvopV;?vm0GJO`R|-G7#04 z;U=RF*N+#p2HL{ zpsS*Ea39PWMLdgBN&4=eq1!nC_(+}!%MjWpmt}n1JD#mTeFDI0^Jg%0!UY_o<5zY^q zzDngJl&7sGOz4zX4K4+Y*bVdoyY5yew~^KuXUEy+TbFc1I;5+vIvb z!{mw&z;J?ak_#DwI1k`AvXA0bfo;>manY`ee8u+#WEK;0e?D}i?2`^T2#$ngP(Qo=|Yni`&Lg|6C;di-S!HUus@4)6l3Ic&uy3)|v6#K)DCtaABUD3iF zUO(0oA69?prndFu*c{LH??>5y(mLKx>$TXYlC=PJ5PRGf&ZN*GM_a-~9dlW7ZFhcqiCiE0b)l zOz1dr-#oRCj|d*ZXDRji>w1V zph6&?vTq^!nOCu-R?lC09Fi`3>g?^t=WYN1Auh#x*fwwi7+{F2+`}v>y>sQ}XAI6{ z5t5=uJo$g(W^HVYwhVS1`H3~mAc+Jx30%>G{aiYVAXcSQt|;m(?&x|;v$98ztbLki zuqS`*mQ2Evmn&C?Hjeo1HgD}@xnuprc8QqY~=jny)>oYm?=M2+JvvMkn zE{G0tJjE^5@v!o-U>RuM0W%GQc@Z#w5UG=eb8h@B*wy`Bz3%PXrz6)|eqM}Rbe;BT zkL-L+m9LAH90gtoG+VraMVhBs@KD;jWWf+F4NLV9%p*^yq7OI=OO0s!wYLlOtBI z(wXPK>C?d6iB12fRrb7!bpHWENQVr13i3y}ZQ$&!Vtmsc!8qTbX)3g6F3IMvpND(z zqHxNyljoSFmx+IWgogqBeGrmIxC=R|l`Wt!;8pzZe-7M>p@Ty4|1TE^x$he~9K84~ z?kBgbjCu>W7fxyTo+M3PQQQ*`vfnHn!2md(gA=AIqRePrF50cqA(;{^_t|2pJ7p+% zDmapnYG!H6220K>@*NI^wb*M2ML8h*j35a`9%wIhEB1^}&OH*MJX3?~YeF9Kf5;g; zgQD_UWLO?v$W8JGxSCrWT5h52sIvztAvxqc2v7`O9F+gGc<=)shOP+)~U%m0(f_&<-pKFSL<6&|s@a?4}dP z@cro2cv<@`C;|8(CG71emB2{nkJquNXQ|Rx^}qilf>x@r!^>fXm{^D zwVq-ay6~{`eoEA`k@2v^XLI5Afc(NBE5MizKEHD`yZZi2z7Ex&FRLZ9i>YxS?$RYrG?WUKII2mU^n6=$+@*&*4kkcL(HNt?mb z!^IMv#%Af0QRN}UpwEaj9{0yUiLlQ}-m~8juPzuTenzIwl~QZFcY-;KbT`7lBW{CgN=dpLYN>}Y7K`&!cC zE%Qv(*0n*pN`2v{6C5lK?i0;t83_FY2c(>MK@JFr2xBWUAFa%kc8UCgZQ6eDTbR#$ zE84xp*jVygKDqk&(5J~zqC8_pkON->@%FmfPV(d;Tfi!(v3JxXg%@wg+%# zDD6S;;>kGlbEM(w;F<~|Xl8*xiOS)T?vS+n8p)l)`RG|MsjOoL+90=2$wr;`=cA_E zi#&s`*{&^z_j&F`n+AR0qwn+m_}q=_?UgHfBHYuxPe2Z;s1R>21%O`!R0w+$X`;VU z-f&_|_O;Ck-qZ&=iOrCTqbj%87CFJ>fCoV&@8PW1+@p5)`7tI^-R#tVTh7fzt+T|6 zYyIdtK4~&jt6mhOL248Y?Q3Cb7&ijZEF*9@9K*AZ-J_8&O5?*?F6&Ws+?^*VJH7rP zZ{Wje%rVK3BvlBu_@GH8Lc}i)L?442Q$%R46v>=+h_O3iPi%luN?o~h}`LK5820+D19+YH0*2d8i7(@_Pd(2H+FmqUJduLxF_g-j!ajfpT;U}4R0 znQYWH&}7?{xo&kmjH5bQ$@hDRp}{L0GN2s6Y|X>cqVX>DLK7LH4PMA*rI=NRzq~9i zNTuFvqs6yM&8%n6ZDd*&2vIpqwG%`@m991PhQ@JsJLGY0FVv5QU7zqMAnTlHa;SVO z<$QVYxlXGsCfqY9WIAjLznF{Gzzg|Ku^eCUt9a}UH|g@89KSj6*>3&eLXF^FL7~}5 zCqzFG^a>)#b}$l!f>Y@$EJtqkUCHOdlZ$6-&)862wUS_Oxuo*@gY6YBAO33ieF9ME zjv&9zKIj9)X=^aiPe>hKoN*G(T5V30;dC2&hhy|b1AmcOGQ4pYjqE1!RD{0|{-PS4pYA^=KI@1#TRZ}C(C-*wyw>lcqpeR^6S$`{{66U?ro>Cd=F0aMG~bFe zCp(4yyBK#Lo3^K9Fx;^g=OyH^Ac+N4zz62{Js`43_voEn!PdP;o65(=esPm}Ph{V? zW7W_!MA+~f#=NXKbFP)7YqfSRoGux~T`bS?7>mYmF zwTXS%uaYDVJR^t+5&mg^En1F-=9wEG;q=xpuPEFDs8?ZHFgKblVEa)ePX- ziiyL1qMniK4tiHO&i`G=%>NV`l9od2Myzz(&%lMYOFX%I%jt=>E8PotwqnwdEJZmN zseq6o&c#iJm&^5_gLQm~}_DI%;}{jvpIPmn^)o)5UJhs46| z$he`QniU}zO^5aejb0oifv3)Qbe}$*kUC#&YRL^aIyZGhD;h^X9nca}!YlkXZCs9# zo=igp&l(qBW@Ip#>Di9OjN^42_>LGbRZw_%6YK|~{iFpp8+ORIrcLyHoziqgg;X&H zeeO=za8zD2W$3zB(h58?$wPWtUk>_bF{-1279(=m#8!mODftFVo!y=03Zukz>unG>H|c+l2Fi&1SmCbXxn`6Uz_}ki=vXgAyzuK zho{VCTp2At=k3-f#%aurizR}sgaPM}Xgm1cmo>C)zV`Y!&P(z}>AkCo{hy@Cz0VO@ z{8IGsdbgc!<^5&q8W5BK?}zHd13A|tp!Oo$MxK{7R>_n6e|VpaJ4E8%=9n#*-f3lO zsQA04X9xKOpshl>`atee07_@VTip?73tqscw-W#K(M#q7DLadYtk{YAgcb>r(~qC% zUj&3o3ThgW;gvB+_5|b-CF>Qx`3`bq&E71KTxR`+vn)`WYtUNTsOUC-eRHfGm_@UeL z!8T`mqFswGAG@-wcCMc?eHYN}La#t?O1mCA8@T;+(o+EA#C_#WV3q)oj`Cy%OUMYB zA+R`$RL1_Nd%piSiu7^ds81Zh1T! z%l>G3%XUtKeV;D=s}t^isUfz!F&fkbVdZy-D48EfS0>z*E(E#;w39_$t$#>~H5~Pf zDsE^q_fosiOpU{RtT$^74keb9SUq8OqStjU6wnkvG$jSt8S1FJk?zPKC+u0#%l_4s zF-AR%F!!&KhAu0c2szoexgYnXOhVaBz|92mgaC5220PK_Bha@)xZb;LtU3C%_p;{1 z#`)t9wZrQpK8rS=P{bqp0fbE$nZ$=E=D*O>0a29k6~8dkc`I&yJ72*$OK1yD6^HM{$7k$loOYyi*|J#cpEUvw0}&Dy(JM6pt8555bGC?^AIsV!6oWI{E;g8HOsY``xyJ~I#7{O zcOdPk(aVMNn~$;{Uwqo0LLTt@6sbJ309_dK1nvXkf!V*I;-%Ig2mUMq4*mxE3i7+^ zespVgUp;5@%=Eh1&4qgrZWYWsBg#2!PpO7Vt-T~&Aq?TA4qc-={O_;IRJaS>5PLEj z$$ZuEqeZ-HYen3wgIrQkdACp;RUr%!=H{a=twV#B4n_7>96>#@%O{3y`_4SC60|S- zgG(|s*?!_N#__DT0kAGeC?o62KcdHY#6F3qzh5>Zt|j1ZYT#xVKvXs)@a39Pa@6BI z5&sqwaI=9DiGarQNQx1zYgmbf(DirShQY^q`Jaj}|9<52{Dse=kq6BUvu#7Qfe#R6 z^Ke6lpo2G59fVd@s?HVD9A`$D1*FINB420L#^1Pcd%UD(M>i~hQRt-_9>~GW7=&)* z`U!oX`mlDlqZO_eQTktv?Pn8ue6iV>d)QRXhc#30G>&7<_kDK~Sf(fo72}4MBcT#; z=Q*E}-db-&F*!*v|Kk3*K$@}WE`wVqLqq=aHi)lC+SP#~%c0+$NGrph|d?rSw;5$lV^Y~_wJ7Pa*)+`yL8 z9@r0e6D^A)=6{(J<74e(lrZ)drNWzi(T>ayXPV zcNAX*^g(Zi4wp&R4N0j%>e7@nX?F>nzpb~-;-t^KJieFwTp|W6F#6eaz^D`i1KkN) z3v=T4Bj&w1XFj`NwaUCQkj!(uEL7r{5H_YzH8EHWuuq5ms~pkZ`TdkQY6sr!=T#n^ zzILz26YJ9QOHatloZkqE)b23$0Y42+?{FU0N)h^+wg07xeyfR<|AV4wwt8A##LD~) zjOQ}Ou)BBO&Vl9$E67O#VFjhDOJIZ#vd#xOPECFM+I~`|_jIRkwKnMt>pIIOcNdVe zPrf~c|LYXUNpl{yuqnw#a?-Jm02PBZ!f=M36k?7Cz%h{d=p3yv92x0EQ3aGP2R%FW zv2-3edW%f>>XY=DY-ul+1X|!zlIjHxOzXC|H-)1M4L&sKh+a4;#S@EEF6EP8;U6@Pu4+yLV-8ZJwFKP(+2NS>i6wx!qb}EqD~}PaR$HiKUpDf;f0~M4wQZ<%f8~FQejIh|=gI1?5`cEwIZ%cK;qp?Y?b}iwXu@;w zz7ob!as+Q^JGa={$3LVG9}+R5cR|N&EVKztz@(oLd1}Z$H9qlYSOHeQR~Kz8Aw! z^44Y&`8n!p?-b^yziW#uD=nah1*rFy(YV-;R=1IXm|~|#aRk2o&UtZrRbe?>SU6!_ zZFdG=bbJJ=2XF?tkQ_x%6ncF@Wta_H6LqDoWD9%WXD4nOSUtna_nS55^a+(VRoyt%EpISN88v?;eK$D5;HRjDuE1h@m5 zS)#T-*A=a%TA!x#IIL9T;I;Uwj81Q6$C|urQGd)A-TO#|_t?X~zysrhC>!xKt7p-2 zk6l++FVdF0=pI{o6hq2Iy7c(3zMWg=Lr%WOk>9p&085sCA6-GI{mnvju1cJBXYN(E z@a-@*^B<3wu)1eGW5pwb7M6rYV((!6IGsR&#m`6WmWb}2(R&Yj!=@TTP4Pxd(s(|oK2CLJK1qY~mm>DgA+Q!18{m2_|Df(V#J1xT4dr$09LaLv8p!>xK(|$~wz0^xi z*RVkj;9CT}`{9FjBTPyJ@88BurTp2L8j|#?Vqnt%n|g|InDtd>0M%@VBjm;epx_-z zMHIWE_iP4_-Zy*DjKpxHP!WW-E8bex}BnofvU3KSqQ0LT}BEZ;hJ=Meq1W9a+HxE zrN4_AW|_%i5|OL32)82mh$AuOhF|=-g6fGi`xd^M(K7yB zb)s)>n$O;LhC8geo87kovjjbPk%DsP0`%{*X{T(D8!1zGD51(vmVD-;eVAHMZs_%( zH>37v*k3n*SrUUh2eQte`RL!L^Jgb=;wC2buAE-=INsQu=Po6zj2Q{dLq!bC7%!~} z_RS#Rp(r=CE)*SKU!i#68p5?{7lGew_*Fb-tyl3(SX1k;)(Q_MABjE(0Tf(HP-m>5 z3ohNtu7$cv4=8+Cr(}C@Y@=75^+Qmvm}8D|t&bc1C-2_vf;0L7i&p_SXB7mwqz6)Q|b$p1{0f0mN;rg%l+6OzmCVve=(;e^|7} zzSR~e$tE>pmvTWASHXB(k!ShhdJ4ql(D@XlwZ@KUo^&M%dEKi|4ec-T5rvg?evf^* z=o69p^WLltTbxC5A!t_^^agIofz~QVrd)uQ9Pgbs2%B4z^T>U3g_5Q1x7{Pnq?ypF zp3WiB5><_A5s;IH27IV(9D{j52)wZtL9Vb`EYj9sd&JP+{H!S`~q(8rzC`z||ERTAfeP%Hn=pT;0zeS(`9>Q93F#Z69W80JF&3S9zu z5s=UaDbIp+a!5&>kqxhp9SzFiaapWQQd1aie|=m}_TC8-#vE3hPY@^rmWj082stVn z&-}Wrw9(S3XZY)#gaWPduhh%>WjYHuVrf{PZSpS{gEuHC3FWdVuP#0Xy-ua*W=5gP zW2uk)$=V#gzP3Qm)BL2@>t)1#U=ANd9eYC@TF#QcF)>0g!1U2);ZWUE z48PVii0TH+Zf488`e2nF<^YT>NYV2mYH!#L9Wi3+x0IYJmrB~F`aI&}V9*&1`^N9$7Bd~CZ{1@P`g1<@ zFm>jvzoA;3>4$xmhC!65`@ZOT)Sw-f`G5Yw+W%h;BIRzB3&kwMQ1V7)G@ll8txcJN zSZYfC8b!3yPj}gs^+lalk;C}~@80=N)oAJUb()0i)vL?LeeP%z5~+RfzI)?(=rhXU zR*K{M{n??N#KHFab)#Q_a-SH{^N31D=9)WU=ZS5<;~Lv;*U8KXFJ?1~;HiZH1kEAE z3&VB}=@PSY?KtYp#zS2X3d?>6*LEtB@0eMoKW;=iq~ZYp4&x zHs4>W46-+_6Oa5#d$ube2@b&K9Y0Vc#GDW9u>;Z?%N~~K z*HWZz-@9^b?&Hn-l;GSzsEug#AJAl=iHBXT#KYUFBxjbDA_Ejza_+}q`Hq=^m%|}=SXk)mir$yKNA-DcBi9S`bj{fq z6DsT@dI+7Z|FYa23y9EZS2+WfX8ij>^uh7{@Ef0ES3Cy z5b!7%nk0u#T~$f~*bYERZsavPE~AaI4f*EPsd6_GM$a?&9G9H?)&;xuo>cofZkdW^ z{d(R0W8cZ)=S7Tp-4T76Wsm>kT9Vx9{Wt zoQYC@Yd_KJlvVb!4}R%Me)-qGAV(RuPZw)aVm*H*2D>gRHYP1(_=21u7zNaGXp2C1 z;C8LWG;!5qjW(}{kYg%IrFmgi7NPs}sVTmx2xW=Vtv}ElLgJ9dn*p#M67!L%e#u?3 zQJq#+3VxlwlvE#9HZY*~C9QY*I?3nf+J;>4IcPtMKvn6%XkRmuH>VZD#L-PFifdH& zCUx|e{~_$X!?_IGxN)=0GD}8AvMYO)>{ZApp&~o0A(D~IWRDb*5oMOl%#cl1vSrKO zWYh2T{ocNw=l8tt@%kf29i7L0-Pe6x=lMC;=d?cmWQRX^$%<&KUz>d$PPH_QMMI9K z$6+7ipOBD1Qz)7)~Fa1;uWxUb~P&JIc?IDM9>>HAv_DSX8y>*0r z8N~W`?HI{}&9q%QOZJG-w zna+v)SO}b4{JsznozhO585G?kZv@Q8eXU^S8oSg+ci%4}cF~!9Z?p zM>s}Zi#b@Y<4F|e&nqaVwm`GTL)@JFIN-13zH`gk0pH0Sc+h${)j=7u_+z zv=~-phI1F~2demtJQs?JUz^ZcyngSMWqkQ3IUC4H?++|MUBAyr9Ubh;5vE()f&nZQ zlQzdM<_X!mrY=10!BVve>q~x_@!^>Hd61J8Ij9;6LtJb?12~F)cG~5eiLFvg?>+Iq zE|E93IbEr&&3$PtfaP1z9tPk8rZ^zlI`Xhrq=j}*zceN<#gq-dwI*3bR72kI*tznu z2)_m19o6<`@G<0N_zrx9zd`8l0P7@E6PI_PG#y}UiSQMZB2H&i^JwJWXmW9Lqq3ci z;IacbSs3e#whryUF^1eD&B}BJ|4(Ly^>iexF~`6Ba+R|2R;6-v|e&q-#lhTYNpvEG@BByY}=f`Ho!h<1O zSn(79)3DA!oQMg9YtUq$#$l`-H~XUVw@f}BVX2duS;o;1>)r8Ym64w_aZ~RbIoRh; zvWp(#i%Eph0j;9%ep@x1*Lx9CKet42!e_DMot%U|SYenchlJ!Ckq|1pfR|D`>5$BJ z($}=njW3^svR>CP{moDKdvcs)Wl1qT2lg4rJ`X1J4aNRn$vzM0KT%81MAdW|X9^{Z z(~vZB_`Xjt9JyzET_%c1G2aNMiO#c~;faUz!P3os8*0(vUWhW>T>SLi=(_Z`p{oQ5 z`4mj4RjyiGjGW&92nY%CA@oGaUYM|)Wi%6y$LQ;cFIY2+W)`g9B#hhDTU@Dlt%GeW zKg=CHy6>Lv&uv9rxndZjMGL7HawY^y9{fgwNOWPB3DZo!EPmA(w#Hco?2e;1oZegW z@0P3zm$`)sN{6ZGAFR09+06E_#pimWqQRW5Ip^Qi8gzAy4B{Vtd9F_TF4P@?Lk)3D z1Y!m6U@imwp4^#cK5ls*9#{Uide5bA@+E0xMg8!@dCcL!VLmSkr$t)ypx8XF4+$jV zVWGe-vhM%=h1&91(*3}X$*a>_Lbz==hAXijhNgx0OW(Y;E@-kOLl`i)A+n|waPR`d z4oX75(i%+h9H^cxDw%b?qnB|r3?-FP?EI@rv>x*kz$`ChtYn$4>03f z6vl&$ks!@hGV{TPn3@(`oBQ6=_3!mq!KaHR!tL!6)TgQgC+X@c_=I?N^XH@S6siFQK{eUIq{_Dt3P66&d#4)-b5&8$aL%(*QVRX zJD=J2F%)M`CEoG*bq5q21agHD`#bmtv(Q&M%ser{1v}#w1n(OA8*%I;8ug!*w!KN7 zn93ShNxlVg(0G8`8Mi@A{9NnKJm{VaacNqehhYzAI13)v&9PR9DwO07?f?iRizH zO3cYjRu`g`4Iags(YvI<*(oDA@(pzVG4;W~rqU#x15*Z#WC{80QA z$qk?Fpc9wbQtBp{1#%XCDB0Qqx`%p2BwzfY8}l7f43_D}?8)7J2ix1uja6dB@RKqm zsyf9S`{lcSJ>A$H6$68kE7XUNo50Aiu|1DANwrzHsN^mYQx?|IN_;WwDus~VYCYA& z&(c0GkduW1DD*l#4!ua+!Jo#8gE%3NJlP%zK6iW7XynS$$?mXK}x6nd(?8GT2)u%>E0tH_#^m03WqZKO}|> z-~Ce6W!KXWhuXf6PGRFmZFjwyA2(rf4w>Vec+ucXdIe&UFtA+UU~XLB9q|E;PR%FGcjzJumne8qYyWiFNt!a=HAMQt67jbTs(CqXQHGaO zJX0VCCw-TU0~i$DD1k~dYgwggj%p{fF6<*2XForp;s z*p^5o`g+YudK);bx#^JVB*cEW>BF4yNVQ29XIF%c4$zYJY zR&llR9^fCSxunWGQ*x)|<#X?Lv^k3!q)siC2zARBl@8Yq`Rw{Ugj#xD=%__#Okxkc z8ZMII7i$ybo@1O#YwPa!p3eG}q>epI^Za>SqMNXtQ~~5*%p>B}j3UGUU^la{viygX z?6sAew@gw8-<|w-%sI2AQhTcFy$NfCHWoyt!OjTsqxZ`ViP*y~Pgk5vJ72iH#vJ|o zf_+K%{k`I4X^*%yI|IdJvyWOm*T8HD0FyCVuJkLWpuxe}Rm-6Uf0?72jl}!c7mu~& zB|VvDZ^4%K--;4v4fnu23DYc0V47Sal}em>jpomDdT^LeQciX}sj01Y)V^vJ^RS~^ zlLns|o+ATYA855-IfpsrA%7zcW3Y>DDy4VpnK_e8{RzmTr{A~HI@6Nf<@Hoe7=Y$qr)oiy1IT-+RXk6iyjgga)DipE& zaU=XFzS3sPztj)>-akp+`#)QvJAUWrf+!^f*93sp1;Ga~KQS33JHryUvV`P}qd_(= zv$rKRCFZO@tLJvhDQ=5%+v9RV*QJ0wjkiC>%)ii!Dh?A+zI}t;Wi;NuKu|#|EZ;R% zn}M5`;;F}{n?}>*Kll-O=R~XluZo2-|;~L@kRXIW)Mt1vX0Lz7xErrbF z!m)j82B9kS#VGlPd9SV~a`E>w+Dy*B3%%N?U}1mdLq|GUjCu3r4+<%Tv>8=kmG+rr z(O$1RlBtIMf3hfi~p>7K=#!gmvbHbErumx|Pz z!+A8k#@}aJ^e%z_hdr4-mM!YpZP8OPH(C4wI4x>f?$%_yM z*6Yl45Ets7qf_msy-bYH+VQo8JRIL%i#A0OteGr7RH~yc{x8rM2plP;3j7y+qEFW= z(tO)y{8ECD<8TKnQ6RT<50uV^vTOfp(jQA#{!uzR+^3U12B*zoso2WcuXi z6OCs^&j-_SvL84+tVvc%eK`S{KT(>O@tE`f$FlBpMRxD?9`4UI`XA-;`&x~wDWAz2 zYH+*0uah@E4N#vCc+}DF6?N#=VU2j-p17;BB{iw)OQL_i{d;~BS+7Kw-hxWvxo&(I zu0kX#4M7L=IgT8{)av01mWRHM$v#R+WSqwFbmxs-SJ9bwX2mBA97iY1vD)_QT=xs3 z(ZMFSV$An$1Lh76RlT;{=LQYf=c#ZcgQB8;@kHZYm-qet%<9t!$U%E9!bmtBhe16N zc6XTla^lWbq_KVNim1Mju8)dP_N67raSO9S6QF1wNc9@Y;TjK^OQ`eCeoB5mV@ge`RuA($wkey+w<$mB6*%Q zANw>v)GKt31{RbDsXo=6+Yb^69bB`a@0eq?+wRlQ#d&miIH7v?=XH%-Y3a#8udUhp z^9#p^lj_#nKu%_#X$8H1HJD@7U*~cxv+%e3%}(QCy8>0^8woGIky}nS5_Tv%E&)?2)Tb3=>eJLT|I$C4 zJHdE{?A)|o)5WD+Z#`*`L}RkMYgd%WdFk@tIkE!0$Tf=v!fZtCT;=BE?72G_G@_P7 zoM0YLYfxKWQ#3+;on++ikLO1SAjk>?>IYz|^Kh)i!|d#JtRbr(;v^Tt`=z*IGmOX; zm!4w#gd_5d9RaTNimZVDDh&I$DI3uJ#*}gX^~?w8&R#wL=kzVjoQ6*fKGF%iq7eDv zt@(au?aPT@Z?Oht;I_*{$PayO(>@>_hEh`h8)`sOZmH;1|G%nWkgsL&?+y7AV|`Vb zfjRM>>y!A!$JSklCT&7^-qKJ%+*Yjsf;Ocu~5;o!j=bl`3@u zbAy(PcRNgqca5J#Ce}yR@4JFfEQ&Us(JjZ&Ly^hQMYOPX6z&W_#YIeyl^n}9a>&q$ zipX`m`qODazp92T<5`8+^O1nNjOV*i8w>~k%SnfNY}{*tTm28DKWM(d6Oq35JvLA8 zXW{I^6i?u$Jk-$&K{yX}&nCCf&MxSwtrH(@BE%9dUn==-Bjjfutf#suay%{W*tfdU zAp2tT;{eZqvj7Rkb|cN}AZPOZV)ae^AxqVMp~{bB$^n;SuNeD9O%!NbR5mThYsG*Z zGzcQ$l;0qS?v zPB_Sj-4$Z+y+ILES*X^N-5z;lWk>E-dxy$gdd$hvS8D>fWiY9LPll$Z5mUHik|ZGT znlQ@mH%S(L*^kQVzZ6|^tTu*%Nf~RZ7kECLfd$G!B`w-6y&J@wIJeNh8fkj>Sccde zW2228F#1Gmof^((Vapxd(+y^L91XY=Dwhz2zYH6RR77;y&gZC|ASaMrAbtJ0+P1i{ zfHYPA>O|7{W|_(SklZN>LMU%TxMl`FWAxl?mgv2c6C$jCI!vXiYKp^OdRQbLJ5P3l zWUT7d?Z)l>94nAU@S#si0Fu*%{V&ov%AvtRzc$&`J$1Gri?YC3;8$(OxnRjO0lG2I zGy5q|IZ-~u=?wpgflGJqe<;@Y=>Ju7D&oYl*RMzZ1*(+t&!;D3TE7aZOzatg9C)2b z8_YH|iXhuRnJD&XhUc0%Nf%BeL6fos0oU(%$DRkOP2aLbyh@ebC~yP?Y2LiX*ozs> z&D#4l8jmSUgty;I3Dnwm5K_$IY0MYH{rcH6RI$wtsCu(H$6Yj6a*l=qlw% zp9o>VdwIQc<(b8cwfq#L#MQB?zWYY3ijZu9)_fQjhdReANa_*fn5ks3#JLB**i1xO z;13bu+jucW=rPKOUY4XG5hec#c18rag%CIq=!U+ju#f+e9!UIIj-?KG|z*U#xMzwZ& zkdpx_8MGoyFT!XP#}jw_K3hoD$xLsw^;F&LJ(t%l#AM9Q^(e~wEL&U6ACQxSoF4i( zcY~XOXt4VF;~ow=YVFd;tZv|q5%=x{in&L~8;5@>_2}r9cZW!`w15yqvrzl#JB8t{ zc{MKE6s}78#7!iRZrbgEfFN510f$UtZ+z>Bw}YFv3g~ME0VIR(fl%4PcK)EaaOPKF zx@>B0ylocNr={x&tFCdtx1;g&__2)DeO@kE2x%bQpX(EtW9h4O)=m;{EO5fix99V8 z=R4sp`O|3^C_{%Wx1JZ~x?KU703Gm%*IWogJO%L}jU0Zovd+peB+@yiRlWw#587XvU%oHAc z&ea6gKY3n0K7<0-x@)k3%g`qYTv>0{5Vl=gzGdW-)VOsX9=At zB1lYeBnSiRUa$J*dOygC^BP^hYiZV5bvm?=+sOBWvc*kA(SMEIbD~IuLs~or5{f&O^VK+jpz? zsBe-_)cn(r92@wXIF|m+VaXj-W|M#QQp`$Hf7d_}3cGo9)Oo|8=aU5$6P$ByHPG+$JIe)|^&);M*>-jLI5aE)PvACef!^TfnnhoP}= z-9nvQo!@OGS2!aUqRtf7{s3>b2tYOPI73-DY85F+-2|L|vW%oJR4ep~pZ*Yvk7?ECYDha? z_roGS#a+Qf>L?-}jk-F_ipbmaetNnu7YcmTLOUK~P7i-Mt zcSRKS6jrQRByMj0T76!_C%nE+gF)j z>(G#)qlS#=6s(p^3cb>Uq!}8jB%ylq&0Yqi%D2e%J-Pe5`J3+%Vz&u%HDY}sH@{-1 zOW)$|D<5p{33`QN3NBZt?wh3_Ul_)iL5159Gt6IK@LD1V$#1OL$To!Zt`_HO4~f)63YGX z?IeDeu^C6N_Cmp93FqTaP75&PaDbdNw3?zX(?=vE1kZa#q9Ndv#OuxHbGEG?+jwAY zcg1hOS1M~Vg;w3s)4c%r1E8X=!>>UvtL!V?dHskd@ zafxTHId^Vl0~Qd2B4+gQS%l0AVw->X*IzuBmaG#oZahGcbr1WmgggB+x9K=+dWV!d z{md>9N)n+NSwj~i!+SlExN66DWBzAekFrPTt&jPq=xa*pcaIP_#f>+;*EH4y3?K~z zcj*21%)ls@*65makzbWTfl8EogmdG&N6yt(#fS~BR2nh72o|~lA;bMdEm8$n`Umq~ zrV}IHeO?RGxZTPgB*8MPM@`Fa7X-hp7plCHRZo?6cOOOb1BE+kKiao2wktbpICq>J zC#$OY+NAQzNfCuInv-RQl261nRbHE2--HA&)cgC!jHp17@;PXtCh4$gE@xlgiX zTz~7gjEW|~o2L&Z>T~-Rye@;B4BvsT6a_X9F($pHQi3IEi#H0&pMAf{-DIh9eYXAL z@S^@O`|X~xv$n}_?V+m@DWc7To^nKPwSwfO&~iYBbybBA=@*GRq`DNP*Cdpa6)FvO z6$I>oBob8C0fvT2s|RxP+NE?8C(XMEKT|h8r8>VpS$s3J;G_-P)F@q$iQxz&Vjx>| zFq_Z)usmyR>q6PaO5`bhS0DU0;S0uhLf4fN2i*y;-45T2UP?>>IXQj-gm8QTLOcjW zwY!h6>3ZHz$ks8PZP0_4S$!h+V#USZTvve~PL5_Z4&xfnW7P|r$J=B)nHYZMbZL%L zo!KVT^F~xmPQ@dy@YB@LQU?Al6xyIZ_Y_dqBHQ@u;h6YI0rypDn!9^N0}&MM+P04_ z=ubV%dA6f=p(PDk4MfBsCyqWQ?u!_kL7uaIwOh!})5ygxid0?GKuVKnc-DXXSFq`m zgnyzpl>x%RY-faXq_Gq8JZ3I4YI>=eyISO>j`SJ@PxB(f6fWD}@>yL|S;%P32mv{u zJ4AY)f6rr{w{(Tfa#B-mHs%QbQ3i&F7z5_YZSK0p_UpKbzr+Gvpod2kdX12E{zCF7 zpcdW*;n$92*y=FO-M=02YP*05-)2zfPHvd7^sl}>i*)?%b9Ja;&mbo#c+h?8ci19Xx%8GcM=mXtdgm6Y z10DO-Z*{sjJj;UraPGe0!;{p2NEyt^hJr5Ccc?>(kzt(+XU5})Dq3vk*iGuB#^1%6 zs?o6ImY+2%_m(v6wT^(upN2YoHecQM0En zHb#Wy6SneH zp*;A`ftelRB5W5e!-MZj)QlPR^)Q^4Ex7vS?4SVm*U0=e2pP&kpb;?}rH50|v;XbT z$_8cRhUA#0a&5`6%X(gR&bDLZG*>I_&?oD+1v#ijMI!ZX$bEzTD@o+z(P@xtQ)|H1 zezr$$*h_VWcd6#i!?0UJ414cygBg|u5?!Per2H4=JO2%$ThckN-q8a&IiOBPyD+)X>5J^218xMp+IQJ}`jYc1G?c^Z#T(P^Z*gOC zM%$N8?rLRXQ{c!6(Y)Qp?1x0OhX1qiaM1^uYC)Z^#)s4wIhO|NgGX!c&f(gjG56E?G|8~hQ?d)Mvp*j%40>ACdSYFm*)w3_tkb-#R?)>$luvNL(2|6- zjP0BICx+?C*}c0b#$2>SBHuQz^kld&+v;(~GMyJr3>}Be1q=k>L+ZrVVK~;l-hzG1 z6#IDIdrp{=*m-P-R9EJ*NIxsd>&W!=)cNN2;w##7Ah%zxhjv*@nlNT@JzAO7zeM{u z#~A)lnq+Q_8X=>?h=M?^VdzW#`Inh*Kn{oskvh$sFpL>Cw<5aLy{aU|=cbj|z^qgn zCZl}ZA;LezGqDsqe`^-dDdc}ekP4W%JoI;i_mfFUvb3H0xBFT~>E?a6dTgV*sEr@T zuFcR^U@;yol^X*&d8p1suhR?31i||`mOJ72?*;9R{ z{<>=+?n=bX{z@-`hRn=tO4? z;Wt`*uy9^-(T0mB8IQf?BFeY>`(%bztUU3u&-|i8{c?ZUwIcI5{6gKIQ~g~Q=J zur1xj=P^rhHC$3EJnXE}WB~P14u*xGSGC4~F2Ncj=CKAbS8%L-3r#-$A`($2yt(-= zv@|NnK#XX`+E|B`v{#_Gw)l!apgn03=;=be?5;l&YlTI-p%;r6KT-+j=fr#+auy34f4z$akQ~bj+F8mtFj@IIi3mzSMfj|5;d4XY<#1 z3#C#w5nD4;XCSKNrAcXHL_61*pzgum{P%Cv<3~}S*IerA)NIp>&$3v_l*;^0zuzn^ zs_6B%@SVgBoY%5W**^HZ7p-omDAEmJ+h$9M$tD>T?Tz>SG06Hjc`}dVH{~0Ko8Uh| z^EeXIckjReo>4aCJ8KRSLS<)cRHPTp-4*@VA9???ddt?ze6h~m84T?{1q*T^`wk7o zMK^|HrRn1#_vBX|Oz1VzA3-G3_-~n))$|FNF(4jm;^d7sR zUJ@NaFt=UyZgKtD>-h7zG|$YnTQjFDt)4jE`u(QJN@DF=Dc(WC;G(I9m^nR3S*eMF zZa{JA>nq;nZc4_dl@~K~($m?4eV`|RR~Vt>sF}tnIcH&|6T07L`wE&b{2t31Bbgy1 zT(;Kyrl|i0$85S=3&>7k$_kY6piV<`$8jQdIKroy{`;H!|2`RN^=L{C^W5f)k#@ZH z&E2_8O~X!pjU}5Gv&1gj7Dqf%RNc&eQYw z{H)}<=RZ8q(ZF|e!0noS7zblxcQ+#<|6X=wfM%sQS&Hc(l(qgsINzQ z_e)1G=Zk=xXS~c{B=$`&$*JF$?E?2C^vqAPXJtr6kjHJ8jQN5bR6-zr<)_H3TlUv3zAxzashg*ueD%!11R*Gg^iL6gHvEnKY{!T0b<3?VMgT(ydv9 zq%R7$+#@)jb$LZ)2>dkAi3cg?d8Ca7)+fOgZIImmxVa)sJu$5Du3ilL8}^ISrnn^C zej0Ye*Cap=dSa1MnfO>t+@WJ5YF%;TzL6mtIgS9Q47R#!qUht}Tq{3lYux^cC{TkO zG|M3cP??b!!}a99vi+9y%8+seI|Ta ziDyWKDrd@&#Pm3QeB#}oB#B1g;6c+3c*>|l8iVlGf_}};Y3;{aaJ7 zlCpm)WbOXJsyOpczuN8}$idx2DDaAa+zNTG+nN(Tw{Ml-X};r7x0P3TQL%Q_`mIpL z?3Dmh>JM1fjF5Zar3u-^d}rz^`Dv+n{(kfNU@VH0N3W`0AtJlGb+eiKo?ktam;l&q z7_f4{$s*`54;!qMUztq*$VcI-H(q`|9_jD5OvI&FFlXte!B#KT?+J1+gcsrDXx_m9z;;3BbmK=ImK|yDVv zd!mzaE~DF;`W6i!C(9>@a1D3_VD5FNox67l)9Ik_b$yB~+a@j^*=0kmAPd6yYJb9& zG`D?+9)LJfnzI6f$`FS>|LT&KZ{222eG%7JRW&(*7Bb1JN!S9b&c|)W7$#dIKu#Lw z{h`nCE=*-bzW2yIyx#l$J3MVtzppdnx6wQr@vYDM6M^5Ko}6ZaC7?oqBPva^Fo^ly z4E(Ixmn%28a6NuwH+j})IA2QH8@|f_-2X=9?m}Zl9XRB2q6b_9AyJt4%MIrs>?;Cl z0`zyQ;&q2^@}5sRyNJg`)2yJcb>*1S^DvMDDmlbfL?A(SILGOF)ZcKJt;&VpCUNxr zr8Tg_HR1C}tv!RQwLdgO8BwfZTEALNnR?!Idk1BHp|R=qNj zj}k`K>Y#xIY{Ee!%FJQk+18F;@WcsAM;~(>ne8a;wy7h6%M=|aH=O3rIv#Tw-T*ma zh;X3S*?m|z?KOiX@lBOzkfmu!79jifqv9Tu0({pqCB1H{Leq+*Oncol$zn zLG?oMt6pr>QcPd;eKKRq-|;gb2b1Oyx%>vq^ZfrR`QE$Rb659ehgw@QeqE&)?zQ4c zazCABom{=l$|-PQp}7%B;)El8gYdi?Uz%2SHHU@Cx@HH*V>fr-y5Dp>o`6L?+@z)6 z&L0KIA6b}=f!Mcfq!tLy3-28E_nvK;pO?gCvI;vZN0LfqN^gSX+E4PVgu+y-c`hOZzMfRXN1pWMzOW2CY_hKVsq{3#O|ltk-&6 z^Kl6WD!uxrPq+nyIDL9Q%sFkd$eZLM27Wy+&9_{P+2Q>*JI~wC^1Q`0kC943y|o}g zV~ zmsykQXjl_RK@OA`5?72_$9(S8=KE>od*KU4`J=Qs0P@uZ-d+#HT?so@a zklXK(M_;?x!+8$860-zi@ASUT4%{XfV}1Ls^YM{wd`p|!EZdt=3M;bv&x1J-h<`rj zj=2U7)E*{|*RUA_xr{{hZ_C|(d+cOIz2wV?^}r0Xu--{hkb^!oBpRo3Q z8?Lp=D90zR3D~|?C~xGK^l&U#3RLPFUR95()`;Q?+u;7<{QXAFcQC}>CR*<7Ye*G z6YVkPs1`Y{qtHnf@a$1NFS`g?6sZ#}fH?x{K?S-E1 zRXQw-@-PDJ*HJGopUH=)ubdpL9(~GvN0CXm%>N6JG5>->%InAWk@CIHt(zV>9Gkl~ z-5XYcpGkZd^v{nf>W)4elMFNel4EkP_>4j)M-r9$T%}@ zXW?iap#tQ}D<*V6J`A21QU!CneMqS>=(h1G`6+wly0ZzTYcKzqc!V{D(p%EUWxjZY zGzTH3an2uOvU0wWZebJT?)C-=&EKSDs&u^@Vw3s92e0l+j~T_~sw{wpf}okvp8X_p zci@FoHrP)pbef>6E za#CT;2DllJ%S>M@Z^7b1e^5aor zL*ni(>x5z==ejIhjS47w1n`fUjHTb0U{LH{# zljYcee6t|%pCGzxydATj!mT&GMn5o>YMCrF#avG4h^p|v66r?(u-rP6&*;dyXdt4gDBLC|kQdnD78X zr_3JeunhCuk=r7o!J0Y3s6xGr{Zv+dY*B99yPdLw?cILrX1_ca1>IIYV{)}uKF^5g z;jHnEvW$DtoHZ;ey?HKm@?I8uMAGS8`=_r0K~5e*erUN6r1~4y=`bLEtu#ru(c$$d z4Y9eNK0kHMX^NO^nsH8w8-{mYK^*~*sX-SM>UkM`7*`@OLs#qQpfWjGQu&Y0d#{3< z!dn`gjeTnMEq`5Qr1ZN6IUgaKuwQfswj-(Mr}+_bK3f6-S6>pL1nO&r0p}OALb|PO zar~+h9324a0c{)7;}iG;V{?*P-l)jEZPaByM;vR7BOB+o@aAmyEzT4N;^Zh_eggrJ zgVs+3f=%aObUL+=wz%vGB^(o<(Kqh86c3{+`Nbd~nV@tdbNr7?+ z)rLmE>jz!RrK+FDBg{SwI*Gp<2rO9UI1O_0e9#<(+DE^`E(We3JT3p>t`|$(BIRYu zF~K-2h9YZ2X>}@%wh9-%7Cr+x1+jzSwEc&pxGr~+?)=Sa_gyn>D;D5ywG968zUWbc zAi5LC*t;tDT>xC zg5(B{XZ9g2ANV3DxsRKedsjFoPgfl7ou@B5n>)l&Tz}R~*8W!3Dwlr%>ssrXOJf`h<`Mzysam+3h?9WJdk%&8BrP zA0OlpxVj>eoA;UE-Mi-mf@#nUC=1P|NF1sQsAv%%=F;91ft|JD$!j~CV$aK}n6A(7 z>b%g+<0W~qS^e!bQyA1&i_j!wqT4$_(awe!nf}NulwsMrK~_TXu#o)QgL$@eXX?r^ zp-XFzC{*D&FdH55vBnOkCSU&brj>>-&_X%&^!-%|L#C)_LyzxX@u+;fAZzQ3Gk+P3 zKXf@FiZ&N%K7;4|<{gr_=WBnivw7AgQR~4I=i*1?*Vf~xYpi5S!%xKlv6wsz8bp#S ztB2sm_#|Vs=W#k0N8%FamT5Us?FD80&-(T_XU|>N7=PdmA5I>o?jSLPws7FGaI$ueQ{N@1f6ZxyP`>fVvbh|wR*EX&s{wbuk%jfIrl zg|tNfKC*u|_x?!)&iuhSzfZuZ{VTlstaUldp8h|}B|vVnXuIz7dk~>iSqy!}DsA9zr== z%GH?1DVBxHGA!DWGxFrEv5AJ{s9Cx3!w;Z0ptu&2x2W?vhU8A*^W1f)k4_V!_N~1` z)$0^#*d4nZM3HvZz4Fb7)LV_v%loMZ@K6vJW#jPv*B6tOue@*LAq|sFwNXD!%bdn- zz->yRK5}ZYmGYv~-hK&*AfP(b^Xd`eDtKPOeaSazNi1>JM(Hn8WN%~-o*rFJPd{q3 zhCA5(sN4~bIlnxlw9#SHZ?PD=bm4h6tpUTo>7U&`LF_eGT z%?3FjMncL--!x(LcYA>v!Dox33YQwDo+^j(Hy#n%&|?@kxF+JqaPG-RKM%0;(EWi_ zSj8cX((oNT^*TlcrpM-693pSHO;#-6XWs2NP5hcJO;b@h{#HKJhY0|AFA^H-{)2g5 zz4qu4ofTs9fIFG7X0e2KR`iYrJz8ZJk^g}^d9jrr^soS|6KM;`kHDN4KjDYQlU&Cv z=fAjYWEA+Zkm)zFp0@JK$O(SiTa|o`0PH+Wm_oX{qG!lZ`UciX-M>Vsrrpp+bV(>r++>NX3e7YZLAA92Iw zZuX{)49=2#yWVfOcj{*rPz1>wOzY_P#OVFErUREdTcjDR+*G3iOQ`Jb2L-h)D}*mh z&FL(epLDqa_y9HrDG!~^z=UX?Dh?{$x`g{+{yy6*8@`Z5Ij<#I{P^2HK3+#^$lE>O zTnmGpK}xZ_4?`Jt-6N6E3{E7+hht)=hW>K9cCa%vpPp1qP1t$>G(fmmi z{AUl&j3}`1BjvW)2#*^avu^V`vyxMsS+-ha$4#Y}R$s_PYjzpmGr2(PHTiUF3d&dk zCWs+wY43142*JtMHAj1oT2AXmIz8){RrLL=`OneQa3p&`pqoncdli^_pfg0^Yit&# zxvaUtR0LgCDzQnC#;6>6U2)t8v zlBOmx$ql_auVW*=z*(){=d7Uiac5w&HVVu=FHGb^fA;mmV*Fkk_30S%3)oKtb^QFsh@gJ z|M*4pQ@IYG#CdC=!bW$D=kkW&B>4768P`wCO3&>(iARlc6fSe0p< zg6MMJNA_Pmw$txt%0C>PtDLJjnF!!S2nrm~sB)$eef!{fQ?Iah)IS_ay7EZewQobR zWFqO)2ke`38^1{(QU`uN^9|%cCm~*LNEl{czNv_;YIqW`zZHl5zcvXTnIXH&y zTgjiH^AA5f*a6=jSThj@hT<&DZ5K8@GGj`#D{(|=Goj!T+lT6*A?mxS9NddZCLyvj zrci$?rvNR@=zVzwbIcH>`#6^opSMlcr3XLgRD+&ZUR}=UL%U0{T}C2f4(dy!F%SuX zT5II>4(EvNZWdKm?2VUkiu5K7@fjB+oV?bu-WmF6{FiBE(Zy_V9_4{S2Qdx@W02vt z@70yy3;zi0ji?KVeUo^XCp(;8+ThsQ)=6!9ig}}WSf+xgD9m_8eZKj(NPz=3mJF5` z77mk}D48iX<<$*#`1*k;wJ?69tojKQLtVf}OM*ceXEZKQC zKkLQ(8C>lA6z<@MCS`_&NbIg_F-08z=RS)!bl#}Kov}I$d+S=HZqt`@#&SG2p#lY5 z*aPOLUZ86@HIQ3+ zoQMUItf!a`A}#+}@4WwSsFjzZSN>T2bBh+Yn9&C^wg86Lw{G1(QS9}${?8JF*&GiW zAEvt}ZB8XtE^sf&gGPU2L46?BO!Eiv^om0jcF7&T&O57O`!@#^Cffeg9oEwIyi}wj z&)lF4rB4gEE9fCoV&4{@ao&pD#*^Ch1Vt^RBou&k9qID+NJiS>4rU%;ik=VN1pWIz z*I(F@c&k$~X^16E{3nioka5XOti)-vC6-=~z%2hw^yoUc8Arz5Blu=3xEyJ|H}O0( zG;!f}S$uYO-CO_5l>}>{6Sc5@m_dicRg$vMHv{BoHif^$M5#7SeBqwHgIC_kHJ4!G zFtG6bL{)SrrSJeJn1X$FNEggwA5#8cR zc74O*^{bCuRrul5V|RKoXDc6!LLYTan7r7> z!jFRC*;gcJjptKWM8&C=F4Q*-& zu8n;~M#Kas=Oj8G|34XS)Vhn%>uyj!eqlm0T*NYli1SbNy=xAlGc5)aF%IQ_{KL%? zRt`>X`iVRCvsRntBWZE*PfYtU@oF8Uihxq@Af~(9iEdwnn?kEu zwn!-}JF_x1HRe;^<1ePe!yS{=QK3FiSHGS7{wdJJivpuE>c&Q{A;CuUvax_I>wkYx zYyXT|yXBv_?}Ay!#O5jrcB;BuPG553DKS;P#6qV*OLa3E_`(n^l}~NE5l6j!g*TbG zhx#&Gqs^52*6wqzGw;4^_IBr%&r=Wz!1xxla*KDz(2Cv1>ZWW;UFu&jyQMy>bf48g zOpVWYUeToWpJ~MDT=q$TGSJV4*7-5Nkt+X#r86NbM=cj!z+pLWaE*W}Fej+vDC<(G zn4XJg9wnu(g?T?i-tSZo^Xms&-SK#BbUS&gqqO!xAT?;%Gw(Q*cA4O{C!Epmp2gH#|O~9B+ z<*eEc&HEep-+y1=^y1cWZjrR5ct=3@oBereeF$lX^}eGh05Lbz^1mat1TMC!;)C__ zRQXqWmvNHU91@sw7jEBq*?6XxwU#Z{rY+S9QLF#$AQqfTp4T)*-;^H&Y67pWt8~0RQ}5j6?L2*1X)Uka|edaCJ=hEi0>&ngvrk*~-0owf7&H8q73JEeh^0=h?QG>+c6l z`3`yjRt|^1{>i-2FsWU&vi<3s*$vq=nwtyh8=Jf>1ZO8!ZY_EDSA!g!2E?%`IxOb& zUM`nU6$`Y|`#hx};n?!@h-pD5uual*4_aA+H}=KCBjW zL!XiMt98%UlP{ybYOyz7IS;k85LP&7`3UX8AQt*Md;_|-%9K%$(prz}=CYL!UoRov zlvJra-Z6gCFA4l$QC?v|1PXY4#aQ5`BQ7dmQ@xJNJ6yddO)pee{_;DGkuKC*DO7`B>wMin;0|R*1+8br&Y4RFxOw_?j#1}4@(jOz=gau z)TE$}=MSW%1+LBSISp&BA3BTuk{r9eyZmi02i@MjmpnbHeZg@2*1`xm$N^;(l2c4M ztj%|}%=wtdn!i}llp7qz=uD@(Q+cdL`sb||Mr7p0LGpBFhbvv0 zQj+9ns@1Qizs6x9J@R6wM36888~X4vu-J3in)O9NX2l9R02#^lh%Tp!#R4Mr2!i@*Nd%kFUBd3*a#x?RDxuWhYA!84t$ zkKivrh7j#$bktx9BV=BU4F-K_%8k+OYtU;R5NJr`P^IRNn-&lQ+r`4XKlz)N=0gwD zfhxVh>6Y0?g+nOzpsIINOMOi0n!s(s+M7=wOE2u6+EJQ?L@)i=uEiL416t~q_q5kLXN$RUxB+WhKK^d*3gojt8TT26-3*l^;5)GrFZ1w9gp zGbd;7tc>#o<$n8j3P71Ws4%2ItM$-}T@E|*RiV&j{Z1$LbJ8+<5&P*%moblEi8pt) zc%I!$gCaX9Xg&yf1S7oG@I366?W~E&8w9(wq6|d1rH*gugyvWAYkv$so9ynMv$+W% zidP7RE27rv4vlXpP6TWz3TTTY1O)C5lfd6&NntVJU=g@M<(&ssBm!d7PzK$qLxLl( z>&$20GNbQpR=4Q}3xAZpDe?Wl?&BrRa$6GvqPUu08p~b!BYnC#vsYzHYb9sC&vjLY zM3>X!Pk(xNWfAC7AYwy6Z2V#HY%eJ8f^^Rf!v{7aJ2?*VSJPJW+QxLKTs22@%Ac(l zf@Ou?>H}7S&BEhEQ~;ugQSb?ECsFng&2(wCIQSe-G_gaq0@C|vB@3+599yVE~Zwsy)TW9!w>n_0u#Q{wX$UM=VucTsIVS8fL zBUECNCpp;3NBk`fkD-7i$$B?N*9=rLq`r`@v$75hM4h3J;ZF9y?_~G%vs#!pkL1#f z7OUQP$hANB@OKMzJ#j%!4rWN90n_(A1Teu__^%(-7NdO{tMg|@+YHW{br*JNUe0`A zvSMbWV(NHa)XiB`_1*7j%sl%Od|k4q88&}8kyAvyi*4*&oT2=~|M-|=8$;sFC+Fzk z+6nIy6r)X6x*tY&k%uPJIStMkKf5>KQ8j)-HQ0gg!ua%!1rcouddA!t2zDq4L!TU4 zSH8X0$S}y$MzabQA{pcy;RuXdet*Dli+_z6f{yA&tZj9Yl0(#{MwHUw1M&1$;AKdu^U6VADSF%E4owaADyM_#yHD#5PM_y4EQnCKAUri8F3-S8( zfc)QnDjrf;2O-JB6r?)i<9ovwwOB8~c#oUc>3x&q-5kG$yUe*d{d5}S_#vi@ zHl+b?FgNgoFOdSpdN9@0l|QOYFL249 zx1Cx@i)pAO;WCv?nu*~UYltnrO|u=w5Y(lu+_KUO!6`mDi14D{FY6=5w(W|JxPC2T zVov>Q=XgU#*Xl{bBwuY{;0n9YrH}_lUKj%r2C%ZDm1|oL1_?<`{)~LQbNkzIF)iBH z-BY$3`S)H1MiA#c;uH)$fps53ef!1fh}=*lMvmgnmeZz=Ot~LP%GXif#IqVEM<405 zXpoFVN3n0ejs{>U0OMzo&}rlcjL~WM>Fv$%C*?VR`9%L4B7IwB_0T3_iiDriQoO|~ z*2~cS2a){)#WVtg?~n}A>FxR;!M?Yl@w}Nh8G!>FSx==yEAAAYOvFvjq+Tp00y)S8 zA)lc?6LU*fH0`O_|J`H`ANZ$MWpR3h^XdH3yFjBMXZPa_?63bpU`-HuM3Fj|xD?F$ z30ylL=xCHyklZqXH4x&kBPJU1>QRr!Vdps@uo( z_KB|L3!@h-$Ymy6r!Sal!aAW<8i>G9#&Pj*&|&dbyWaGcRnFUN7r`muZx~QbWZP3} zlry(2@rdfpv!=ii5}}!_$4smV^lh9^>KA7O79R^=8g zjM7~q-AD*3NJ)rvsDuKdQi`Am(j_4x-Q6M5(jlp|(kY$Nh=fQ=Biy;xde>r~^L_VT zekglCj^`b7%rQp?$Z*4Er9xFw!T(UoHdK~J_=<>v-4(yuN@tDQ3zAriVxIRN^1r3g zyds6In*-p09}E>O*ZxJ_o3@I0f3?Z`;#tNEJkgRz|2Y1hUgi!?D{VXzUQ?)x5rL}_ z(AE#9M>fc)K?z_y7Sm$JM5pH;Kfb7m&A<{IjIA!lLwKN$NREUKIihxv6^d``Od1NB*R<1L#-j>Pjk^rj zh!0X8vk!|i#-4frI62TWj^N|t9+dpKVY<*kYPkN#n(<T+Qd@riw@r=%UkBfP|w)SOBI8Vre@dPkDx22@ksU*I0$+H7E zP;3s(SM;4gosXbrT9ZP0Rfa#;dDb2cf4wjEUGW!IuEPgxf^&iIjmF?Hd}PLT>3mYy zoYVZ^lc~!hq7+^kALukTUB=2|{7D~V^@ZFfU)#F_GUj08Gnh{dr{{bXG4h@I2r?RT z=)U0Qv2`Ez*1!KyK@aOKC9w&!_r~em5Y-*fm8u{^Q(2E1o^XM4aqshOIekspqU=7B zw|SzelCPBofd|^f(N%+ir~J3IX&HP)19n5mA6~6g>>3$ir2MU{1uN#S(9~$@siwBkk9a) zw_0`i(|v|7^nX+~UAr*-%NN)S9-b9+&kr{Cth=4TqHCas8S#Ampjv+5`#i9l_PdSc zZd)jorZcuDqJkC6MMCx_!%QLhZ09-sr#T=lfIklTb~Aot1T?^RAazIkALcC_UqtZI zoX2)F{V8vvtLL}+>(B4&5Yul=3$1#dI3+y3)wWBli^R7*aN6VpyX&~#rav}6nRD<{ z!Vhy}Gj|H4PQ^;>pH2J1)SobDB7k2{!XK11L1k0ZVKRRFo77FYf$zTD(yj08A)yM_xb;WqmS@3 z&GWJU-Kk4UegC(1hvfnHG+{Gw!(8js?WgxDoEXRUW00ix_5Fj3LH)X9(PqzSiF4;T zva_mQ`yqqI!=vhxyWCs*FisH!BO~FQ5(F&`2LdPZeWuvpV!)aVL-6%4)9beq4=wB5 z4Mb~x#Nw!C5*oomY2ZmfhEiAy3BuEqhR{Z#{2$)7klYsjI8JFdI7*i;E~AiRNkq;+ z@&$7|k=3?B-F_Q2&!&gMeQpqkWzcGQeAN8<*B*?%-g(E*jLLQ2n>sghqW=I(8SK}B zc7L9NJ{O4KmuXkM_%tlZu7D3z5_2fj2Az#*`r5@N^d$ z0X1M2l5;MB;SNU^QE_dN!P6ymsrstg<4_LFCJh6+#}{wYTJ)md)OxO@>%E?VB=GEN zg3VDcvxY!Hfvw?WjIAD*xa8EQgW3b^nBR?$h%UiI04TXeNU)mon#Ave1fn(^Toq?q z!iD{KysoBeS9eNjXY0OI3+U$dUjyw?@}Tqva$Fh;NeMUrx(xqAaJU1E|MLS!9dl{N;e6)4?mwQcng9Vl`1Z~cUXVE`Tg28NeC0*XV zAY)3|`l`hIBU&c&qA`)QX`z6Jsx%RknKpQqieM=i!Y^q2jItllFIR*(Npv%BD7>8N zsre>uejqVlJ?61Z(3>}bZp8;`6~O8|P(1*D&SB9|>dYO9Eb8y`{{u(91TGRS)lb_7 zGr_2<$L5b)!mKyGvQepGv4$23LZa?5@q-P4A;0bVj$?l-=3Dl&eEu_NJN};ly5$k?w?XbRH#A5!(TZLud2#d%=ZyVjH4@=J9~(w{ z?4(|%w*QeKbCjXjv;7dNN?B5|v$?`aUZVFib`~%;=y8G$TCz=wVC?_fYXk!m{v%PW9*CX>ZS)ZclrY=YD-RO{6rjv{o=&d6Hd>(ei00xpNDNz$U)nc{NV576AzYYVn{PQZT4_fa{%eHTfSJLs3pR@`&eX_0^d=LrC1^ zdf%uySt_p&xtfvW`&zVvE>*@KqHTFcNaQ1k>Aum4h&pYF{iHS*;dZ~$Vv;50=ivS$ zGd^Oj^w(`zxZ(y_0SZTc_B^+trda1M>8<3bjeWW#{%mTN>7@=gKVL!?>#P11Lyb2e zJOz@vAjb!Xi;jb$$uOn)-*_w>VT1*1y|YiGn6Ij!AsilIugvcHMf$lPTRg*C%nM@Z z&cO#|NQC`Y!wVD@7GFNvHVHjjPj+0ib))zqGp)HpG4@ivY*QEJAi$=J!9QFIB}V{P zgkJl$JYm#Zwy*HW(27%!Q`8ePW~E*(Rq(YGI9YAfcwF63E$A^+2ELiFPLFE6T z^WnH7l)UvxQu@qH%eJ_;w%fqd&OknrNNVQ65jwieyg$trHiAgppD^aHHhnl49U{=Z zcz0_jIwmnwGtJ34Eyv_!Jofl?Bg}Uf=7TshbRNYiKb_F9i#v0?mlo7WIs(`J#^8K) zclh&`A=q;K$g9i%41Z9R2P51N9Jaj*DS4Lv;O_pP-;uw<4}dVit+9LZIIgy}SmKIq zggEaX&qnE8jghB#QkNULxAs0%9)1AeWsOXq`c#;+ns8qZr)o%({m$2MFz+W=dZkpp zRb~AO%=rc8AQ-g)Cw}@oD!8)Fl`P(rjHNDoViQT7$ast%rpl^OT$8_;HgzYMKyVtE z;9&L^w9Fv0gc#vm{tt5hkNj1JB))5guQ(P zFW=clqR&z4^gwQ`b!R21q{Ek?^qo(M%$BBz_B%>k#x|bQvQU^|3Jh9=C@;xEg_<`r zzTL<%rf@vSZyy>{%)ArJQT}!6<1oiGjZWJt>zCJn{tBR94D!|{p(QNRNJ69j{-19b zet=9;SoMZ=2G&&nuNu4={O>kGSe)|=?@MK?NFz5qey7knNx3~hGEf%zY8rn4^Ui2p z{RdNqsC~`fZFVWO=BBvLz5zQA2teHZVvNdgXnEs7~GLw3Q?ysZx?VRtYZ#eBTJq%{{(RR`w+)nl<(9nAndr zFp*DK6dE`X4>sgLj>B)v1x?m&yddKspQO*WQsa(dG2WPtsTQdxc(0;d(19%o+u03y z#cR+KH$Xmbo~|Fo6d8GC-V_2+x1QG0>9`*H%ADT1SN?MTW4WypfCC{h$TJLtiar1w z#~NG93xXld`3j=(Rms&W0>A%yM!q5HPoEr~lvgn%0dSzr2dbKj0;vEPo&fI8-&5Z< z?X7()QrR0{79UZ~-fA`RE4WH`dGEPJ0O61xfKvde4us7bJcsf`lYfe|IT2pU7~Ema z@87B~rcm*JO(GWcT2FGPO{JA<4e*~J=$b7}M&gq?CqhG%M9c zKUI38f873z!7X~|X(sLly4GZ90)HX~2Y_dq-^;`+8en5G|6W~AgHkf}-Dq!^=eYhI z-=Jd>p&UL?4F)DggIR^}XIcs60KmD3NH8p!`N&!H!uI~Q;JkOlkS+RbQ1#5+#n4l% z_wYN2LBrO^LfsO9&}{jcQ7ZJa4?+sg~wwO_fG1ABn@k`V(VKHzkznMDonuAx*06Es}T%CENE zO5>EU{Lp}zT0=%Q+#tek%A)yPa10y*^&>1f5K_?zpCfi0h&4K?Zl)qp!73u)A% zT-4W?u0?uYtT5NQx>+2Md=wBftf8OD!fu!EQ!wm6FFLCO@|!}S{~V!}ra+Mh^vbm` zCm5<&2-&b(E!1;F8DE{K%564pmZRlzc1qmDN(WjHwBv&<0`OZ1oI@#*PER$N-j2|z zA#XypA6k3&*s6YIkRM;p zEL+YgdO0-ulLADRK`{%Ik*Pl4n?`wGoUgz__vr$@bD3O#;wUO9Mc-LN}q zJP29M*hSOUrqBwLblO+nzlC!SjitjkyqJ= z?FZzQ?!&&@*enA+H`iRf(64<#Ujj-T2nWdHbqD+PAn7&P5Ow-(FvTfzO)o;K@3iva z^B~L&T20#^{-YZGkyJ2WQjwo#)f-gLA3g=>>G%UIN(zMJdrCnE8oGZY=44g|5 z>?wrs3k4P)+;JfzKx4r|V+ka}KqJFvWk>VQ!NR+ZP~BuWKy&}cO0qd~CfPdN4#{GR zyf1!IV%RRSzstHhn<~*=Y~}xJtryAQXz0%=d%pRPx--??Pslc$yF2xL!TdwX#b-l# zEoq)QK#d700P%|mL-HA2PW1UzrfcfeP zAh4Vm(ql}Tgsi0ho5zU2A7*#J(a$1-X)PQ5NcOe%pZPK(Pi{WA>3qW*Kk~%pgO`y> zY0E6lC(&m}^cBm+o3}2Ti+mn9(_oMuXN)NO`!NOm;SI<11Sy4{z;xj7f{TW>vS-90 ztR$dy$m6CLe_ek-j82uBKjSEuabl5kpy=}PE>*R+f0?rm$i#s0PT&XruDzkXe*msx z{dq-{N&Fgfzd`pI(U#fFg%~26cP;hQXf}@XRrMgl!LJCqb`bA+^L+lrCfRk}zn?g` zEO!>XV(yzTP`>bZ|3sJTp9YC;z{BvRWMG_tp>I$orU=ZZfXH0Hb}78WR3LI!$oGMU z^oupMGueBdXs%cVK`D+r=(X}Ne+~E$i0=*7qvV~&EsxjOT2ddQA8S5&y4d=il<%KB z8*%s-iyk39T;=BgPf!Df++^1|h0+3#2E(_Pb31<~Ie+Kdx4atR8|!wF+UXNk@a~0# zdQx6soq&Q=WD9KfxqMZvqdlZo=Fy3W{dgrgrKTbA%ML}B)MfGn!4%>}yaHYTcS8t- zrr`8USw!KvxYYMykIyNt*m0yxn72Fb}JXe>3j zhgY_SWrR4gY+*s|(>C#bCPnx8TK{ypb*WZO2SiC40J?y6d&s@s?!efC=;_|}!$7$- z#kGko2iJ>ZKU|V~Q+|^-GUF^~=jRLD<3|7vYz~0*z{dg9xUJ{hIo+!5L=VNU+0R|% z028w=9;Kf~NX3h4%GiB7?grMlkf_KF=$(&2^F;xk9kf?5&V(nzRQ?e=bt`>QFus=k zctfr`+>MFtlQB_KFMv}7Rxm>EG?b&B*WI>wRX>ZUb^JHxddDW_66EImws&V(v)3bZ zh^$X}F9NGg0BlY{@aG3u;<7A&`Scv z`*Tt1vBKlpu8@Ik7=Or*efQh%4Vyg%`oB0xNut@vQdjFwGyynyP~nBR_Ds-{3)Ppi zTcNYRs@wfl`#R2FgR&X3bvK~_?Y#`XP%~M{ePa;{P~oc}1hwex#G<6SM$p&RIl9o& zI~C5Y&;JnIZLkimdCXUvVX<{-vFWD1G_a-kKp`9Acv)c47If=!OSILr7cdp>9W+Q0 z>;(j%&jdcE+W3<4#;4J@i-4X;^L{t$J+#%oN6lruWa%l-bbq`UI$+)KgH8|x zT?)=n*B2)?a}al+A;2BmMX?n9qB)HE&lfxCNSMA))NO(@n}gj7-o&d+ zvig)C*z3D>e}YV&ESS^*h4c z@Gj;fO|sgL8D_09K>K_TLa;A9H)VzQb1AKL0V8X>_J=Eh0 z4tVqAO?$L|MxPdI?N2#LQ#G(s{kNBH70{`X6uTDFSl^C`%~qbP7%719+N`yq{F1XR)~I@$XI0Kyu(5 zkIP>fJ&EnDUlY0#%yPi&Q-rm&BhELq0|kSmvCz`d!aHygM42%rh1|EDvui z0W_koXwnEf0nrF!6F1AHdE)r)b#VScd!BI$!$02gsY!K43A!^$fmFN#kQ`lZ;#KB8XQLP9I+RxH2WFNV7_f%U7 z-jp<>W_rYX=Mu;5`$bv-0!vh~pbUj~jNZiN`9Q1Y08}S~JvtjYQwk zzDs_yTxGfHG0AlcSUDh)1<8|z0~C94{1v`4j8@aICgG7%@%v%J)_)01c7*j3FX z9KJcAp#_u)f&C3|^iR*NQx1WwTOY&LIXr8hd-*UtiMX>s<(i7kSmp60>Vkb>A@I%k zM1U)Z&|0NisPFkXV%fdbn0RhsbR>a(cKV|j{oSV(3?JF>3MYnt+L~4X4%W$zkeAyY zC~NG`v(ny{=^&QJ4#|g`|Im1z{S_3wU1UBLHQ^KA*pY(=;A92Fph+ZP)ftj5OFBZO zQV(k>8zgwg1X#&P3SZC$;@%EM=X}w~r=dah8IPTu_YpLj(rWs~@#5)(5P0uF^ zx?ADj3-U)fpSe^*mU}%pewB^nR7o|@b7!0+>y27IW-duOPi}JxBW&M zHV!Oj*>!X;_iL^lS>K)2`vATJYJDMfl@dTkE{ISEs$=;!XWv(>apd08Zug9^W!j1d zxJU#CMh!}LjjL}~k>d(M@t*Wh6!AqaNOtP*$kCA46g>0oOPo{;Ll-~6*`B>qsm!rz zliLG6CL;tUz`}_bQH!z^eT5{VwQ*>?RaK&K_BbNEZ+7h_?Mk9G36c8xN{#0U0ytSP z4F+-9>szSr?YsQczh_;5!!hnl;o^PjtRgB~R6~AY=8ilOv7qOd2S7rBR3pS(ojs@; z$FrpAHgQD>Tu;BRbm8tlRB<@SAN}~lQHF7O{M%=L_GVD?DMmBig3_r@G&icBiv@jUyw|ecdVb;VzI2KAOazm4BR`5{HefB& z>yixzfCFVbP%T*o*dYy>mK*U0)&@Mc6y#FUQfwXz8$WtUchBa@sgWzu^;yiJibHaI zP?`WaOgracI)%y?Pq%*y4TNV$uvw~K37fFG9HPyw#2V~%GwuFmSik^m3qm?*lO3pQ zGjdC}T5-BUSr;cUQOR`qyNlWQnc8N3UEtiR1|wEMAb^97O@=IIaBa}rjx`?Kbg3dO zAjuQ2`i+&C?M2RK%ciw&P3?Lt;Sff@1x!5nKZ7^9FLZp^|Et)x@4Vb!PE753=ai|rJu?_d^_wizxB^&`+lHESfAX`Gdm^ui)+}n#<6S;B|4aJx%pMGYw<#Qy8+j@U=vpIZm*>maM*W)(oW)4tiB?lIbL)=_&9u<$uQQ%BvTe=eFpfg&%z?)>n z$6M8!v69*6y2E2-U=RY}faMFtAOD_DnXm&pZ@K~lG|9{QYw8rQfI$kD&_Plt z@O(__{Yn<}2nCV-Sz+NMJG;J-dxo|ZiRlQ_p|Lk+gtwz^2Mr+PovlFzvf67Q1(tauFcQ)%xF#Yn}Y3W4r zv_@nv`2>zn(d8Gn3)<(nE+I*d+_ zm?K3p#fV4l(N%*+dKpkQ0Y9w!Ayh+#$_M@**h7Ik#9j}(iPF;KAAQuzECkz4PwNn^mmzz4eWyzms##zPe=WG`$um3fK;4gl+6yPfS1$ScM$m`oHK6M;Xx+ zW~XQ3s&%k#bH6{?W`=Hr=;Hx5Wyxcfk$L>EIJB{}a3snlu>(3aibPgvv^}Ix(Z-`l z9QZ4>ZG__V&2gF!i^E_eM!=+aC`A(i&4dO=^+!{#I$Be_MH%If7JqLpOjUbJLAVTp7F>=pe$NM0 zsS=bvr!#6%|AclrO1au_q2XB)uwE6xAbo@&tdB$C+%Pze?bdj|w?mJWj(!(!-G7z( zc13@?y43VSg;Gp37dWddNVp)lJ1CA6!QII68g~@U;bcbatg$z!b#F+|F2W79@Gm`< z(vbLLUZ_?+CV%_*=GE7j+z8hmaOpw`W(AjXh~km}@0wntk!9oEGP}luhnbsCboXtY z6XSss2-{kVkO=iq2QPqIC%oKxW$85hgOF~21fS%aKXKY#I2`v)*Nj+ZTU2QPnZdp~ zFoy=t-Ho+mi2dLwww8vYiV)cL?tewSuSE+ta@F15-)Zg*cZ|tmZ^ZiE?i){g!r?iA zEM+9%3i(YRJQw}5@Qo?yLnVPh;@wj!%-mv$Kh_;7FM!{U$1el%^WXDlSS9Styn?&? zPVI)k7Mtl_cUmgXXlHt`&tSJ(BGdK?kQ@rIvVDZ@u)jry*vHC(qUrzo1t!ShxFbr! zUyrokvM4*b5b{R-XD$WKrrqBa?z-#@o)3e>+$VX?@kq`{dVM`>FX!fq+;^8cebTt_ zpWeK;mWUS6_o_W^U0rXH9H>a}93iJN1qwLqAndKJf}7)T6Qnrz?AChvin^jJNx|7q!oCw@TdZ?&EXjT z=|jDN?;PE+S@-NKUhw3#%|twXFk+1zj&3F5uy(5+Z`@lHRA}&nX$epP%FKCp;gZh) zrLfpB7Dmct-GM}>`DSznM$#?$rob2fs@}dPn+I+_=z)ahEPVKbvbj?1*(f)aQvIfG z(Y$KrvSheZ&SM&8bF0gTj<@s%??*~lSOFy75q#m9MvQbJG#LL3V?OE+5~UMMl*llU zY2!-E)YSdTM*jPy7d32?>DGnLAr8EmPYLcVsPxW9FlI=U zKRIHJB#CSV|6YNnf0q&IIuKDX-_;b4T^dO5i@Q+izh0+yXc$qQH|EnsSmC5%m;q+w z@CiU{-gn*{HN|5_>T{bUThr$C`Z^v^`5-|GXu%j zobDc+tG7P=<TO)Ve%Ew#;4ke0uv`R%LBIo!XU2KK%I8aGPk&Pp&W}E99kJgQ zn?Ot86?BUq-}R>A6KuDQ0x2ulP!ni;M?pF&SmiMGqoxHzasW#iJN7V}*UCrh5wke$ zjvoskwWvAp4ZI?i)Aq4shyes0!JUV z>k>hinphN`j}N@B(+6AZexLdF@>#3`6H_t8gvXX?+i2F7et5rZ4BRk6ZhQ%ca!=s? zd~Z`PPgy+LNPZ%*kflzB>-~z1cycR?%a1QlE8KrP0|*G_=JMRHBz zNrm$8kH?ocaXwnMI}r7H7sM@KFpcMfpd@S@3Ub`b%sR?~1O_I>9Rsg0|A)?8ueZK0 zXx*qzpLlQ&+xcUFW!(>*y8uo>2pMy4%0R(Ax4Xh495v1qJnm#%t(?zIS}4EjM_RV$ z7D$tUen}711%i$Nu!9AD?~&E0d&pJoy23kD5cX4@dRwaOW{D!z>r)v{;;4F$J7m)~ zOCaS478oOai-Z(JjtuZ8u1&U0g(7*4v`qJFk6S-Cn0X^diZ9P{>{~w1_~eOJ1)FDx z3`hiljR{Z&5NmRh{M(u=gIa!qEP+_RYwbY}7S8(K{Nr~oucnO?ssb>OiGXajzo^@5 z2z`+0_C4~E3nNxM0U;4D+cdp6wPh%)wFONNEzvg2u9o8mL0|akvd_75FOM;U@p<#t z-{t+fxX&L|+|$$vEt!dJsd*T>PChU37G{s%0OM}qa1B$a?+M-ulCQO-TPNMO_R!YF z>l4m={=NOxMUH1ZivCq)f_pFr9PD95;2C!wf*n|7H>kON;FJF2!T4#Iq}|@3C9Zn5 z0812>;fE2E6Kya~1r&rJm@^!jtqYipttfPMY_-lkmOt*{Lnrh@zesH!c`xIvyj}th zt$2N9@Hx;p14Y+9B%qiqWzmr}2Fq9Ob*V`5g9S<%X&m|;vztmg*Ybz{ZoEJTWe%X2 z6{$m_!000=Oyi?7rgZE0hbRLxwuOhjl5qsu0%q4__NA@Rsh=+;weY|`4q2MvRa8gg z(o_EzxE>+C6*~sMdBuOdr09~5bglPUIyRlSAfdzG1av&`@}b9?`VmD&Ppr|#RFR>O z8&xAA-Qha>)$h`^o*rm!t9a*l-5>c0^5=@Opv)5Cjr`7qsy%_-g^tI#(c zz;whw3+F=fK$CePjfPHvFc0$K#_sEg)U`IP(oZb;dZ~p+a;}X_zeLhTDT&t#gzzOc z#KMqLgVf~TJD*#xj2LdoUVO%nRm>NEv7GEWt{Q7X_;= z3d*0mvsgb=lw(Z$u)h}eQ6I9AL|_6D0BlC6kEiJmiW@ZCrjM5rr@zH#M+;q%_vhCi z6{S71u5TR?zG}fb&e#o}GN{~y@*AOh#0YmEW^nxCbm-rQWfr=3r>uYM+gB=O;{$jJVP>NQ5XYkL@+f>kZgZyWke)*tIqjT`+L z7KSAmY-o?SllCrmFh*D()na7=;1SSV z0R=bW+aMl+Va$S{^8fYE|CqlHXC@5#TCQdNLcJ%mGQH6$Z!U3j23-4jw*AgO;gKl~ zlI)50^G91W2gKh@I-jLF8{K`?WzR2RSN9{f5HCBn#4VE*jKr}#tW2X!>TCBGx&nAhUJzt0p%8K?)X<4=E?~s}KYspW{yLDe zV{+$TU7n$Te3(6$AbeFsx1;v8%{7w2yEombm${I*7vf*^wTx8S&S7p$cN$Y`c(Y}0 zy0ohE)9AD9x8G;~(tuGY3n~E+IC!2<{@A({FlWqnLGI53`TIWuV$8842!+EQNAdpg zd7$cgueJrS8b2r}N65Ll4aodOc^L@Q@enT((Vgsw%N|Cj&hsa|iF8oxDs^3QhD19v z%^v=H-Jf^;RR#_Y-EO@zJcuJx=fgT6b^PrekO4S8K zyDu!m`5&y|6h^q7|Gz7Tp@?%I-(`Jvyc((pPYy#VMh6s0!t9T3%ylb0@}s@)tPL5w zZn{k?CkSO`M*%oc^#sY-LolfyvL$?rH*`!^%?ax3%R_pvYb)|$_fB_?UTbnaHIv0h3Rg-A-+QB**Z>ZQ6(|A_1j=8aFvkH*@kAJ&E$6X(U(RH)y+9(mz5KA>OTjAakIamyweBiE{akyK`mW>KDgXzB zEfmYiFGSfC2gg=e?86-aM;SxML9M(R@?{S~{4PfLB|NrA7cWud2XHVv5hmT~`7Zc) zb?Lp&m^e)*?J1kCtyC^)39lFxZn}@e7hofItExat5 zEj0*o52pF_H6;J@3@<$|fCJ0gA#J?7hkyh3P+9s)wUu@(@=nNm;PYkyHB0s7cI2zOfAU8EDWx=ESs<22C6Q8Q8_-Qh@K3EpFJHxj6ijOX9TH^)$>}@ zhiu;$om3kw{$6@mfK&D@SP4^&)W?9aU3}QyM^}eb4@g8gU`irXRiGb=F1y8AmABPg zb~_I+1*0;J_6hc-+K#U~a}hNjm9LCCI>OX5a2*imi(f<0g?v@7;0n%gm>kn9dnw%; z-l0@iWEQL6=_rMy^bD2av%ySx*iKhCT`JErygXVTuAM%x&zl&>zGRSW==892Ux>-! zb{r+0pL7@=8E_rsfTsyncl{YcJ@>M%J;(Y#bC=1C<;hyrJvncV1yeZb4dG8%mnpH) ze5(dQBRDE<<27m%clOpCKe=9%yx+X%{!9iWd0?Xoq1yGe1r(l^ zY#hJ%MoUjkjP5VHwvoKnx_~KrMw6QaQuLvi1(hGjDj=IW7m}IMzb_W z7f~1qofkCT()d)hoNH2{&8OOOD9Q@pSGB75YkA=+L`x$lw83tM; zOr^usBEnF0bb0r{u@!rptA&%uXRz3FZ+lBe_PdWz@6hCJ2@V5P;QQQZ}*OGidSLPaEf3OBV=P`XFvx)S{=w>GD5MR{|P?;WI8qeI1&oU44|mT z6Il-lkmtB)nBk~zJI?W*Qg|18{WDTAM2fu;;uRWOw$Io9VSlV}^^#9C-;1*~j z-S^S7f5A6TKvi-XRj3Da`fqx|GxVvL%ljm9AM(w-BZ4v=R_zHIr^OfUSQ!heI~n+|Wab7q_Ap7O6?GqNK6M);L&j*->Lb#@nbYOK|*HFmQ? z3aL2d3<^JVh&V_!bBisV?W%n00EtNar@xMyPv2=j?XT>I*&zZTxdeZKQ-df@6Y+na z?udEm`Dk<`0k6#U!0wi{t(~vW9B)ggIV6bZp8}^1Y=nT4a0$MsgMJw6`Lc(``%|xC z$=r1MXS2tfi_Lc8terCVi zL@VnvXY4lU3Fd^gR$J(02jSqC6l%wh2IE}XW9Q)2e@b z)rPsEuuVa5xS(@6)*y}je&$VVoI0LBc){nU995b#`R4x>f zD1=HtfIbz3DM*!8i8Da?b(BhmwUNkCL$UT% zVf0PB=BDgi))&|Oevb<*;HyaEGgV>59RfQ7H1t6M$S7!b2*6WPo?j4MXNcMN(w3cT zldIn48{BB8#+R}61E?AF>n1@lrVt2bKmpdZAk?$OHOf`}dhyC4P0vNQI$Ev7m(urW zUXc2T@+j}V$xtq326|l#!ZYaJr~=?XT^ud~7=bbTw!>_hn$|H`Q4-a1x9ugOTL=Y&Yy#Zw? z&d%M-WaXPypG9JS&5gF)ZDw!_-X^-V?6QiJXv@lOvts$b2}Y; z2OtP#wzn%$(qMO=XiHY3)l)mzGGVE4mq;rhsJ!Lzj}g=QB;U_iussSga^P49{;&Rm z;48o%dnWz9%~?l$2Y=R7r@E$gSHAde=NnL_|by) z=s9lQ)HRNvneX2+-TE`m#v83MObB*W*xtUMl6?=<3s{;8-Pa_TJ_tFOVJ8f1+&+uS z*lCI@V=Zw@GYnLk5p}6f1FN4*nAl0MLFiBp3=4&SZfF{@4GN&y#49Pv%Xi%|{K1Rs zGzQ{Y)AxU0wa%Y-^+JcK#!Vd79}I@5L4nauC~^qEzTZ&tlo)9(#*xml{GCv2Yn>nX zeMm>hWq!n&cp};xyi$1u5a2{`aZfKwdYKb6OY083@QUj3Z%;2|5NCKAxAwb#!uOvk zO$BC+r71kyCk(*_oENYO;?gwB5b}ITea3~g@=U_Hp_uK9moo$BQ;ox=t@rnUm!JS# zO31qLglccWty|q(?~#4`@1Ehu4h^1#+s+Ca)z@1buQ20ZefT}5l7SGwfl^;+A^b=a zN(${&M(w=3SSLQ|Rhe2Zfm!@QKrD9sP5J8QSjVS1a{7Q<6kw}>5zb*56!-;ndCZGm z=yvn1j;wh~pu_AAMcJ0^Xf$J<-UlU3{eKg=HbBY4vSbLj;bPRSwc-eud)$07YhcAWn4tUV_b(X+F#rd$Cs4X}d;k@G7kwe7r%1DIFvK?UDI;gCY%`g{ ztmunblzC9>=8rlFS^x*CH6Udk(*_NizI*AJ8Zd^W(fH6XtjR8cNf7RMXe`qB?x0BE z5o8o0iZGlt2YdYcSg9Oyao?AUQp_3`oot@vtvId~m+ZyAkc>ixV_siVyw_#;Vm3po zbe7~~-ZPKo5mE1g;39eY>*H51--GlB$e$u-q<;8_;0JI&Nt|u$-gUR=MiSgVy~*)v zSvV$8Q{VieBXP@r{l-(zRM_hR&JpB78P9{ne5v7Sx2bqsy&VTM-n^w!d#=tBV|JQ*Ohwf-)0G^jk~5{*;ijQPxm|{ z_IJj#K$6{XIyu5KLPHIc!h5f

UA01mk_x-eoMFT--vj$_n6ofj$uAlGq>Tjbi($ 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 z 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ν>PP1s0_e2*fv>qoFG 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

QQ>M{}WU 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

UA01mk_x-eoMFT--vj$_n6ofj$uAlGq>Tjbi($ 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 z zMWs~fZ+bDeOl_vm`>afN$F51}bo1WIS5t^KMwRab59pFRkTxAS?{SauCTRu5Gv-@c zk+d8cTf?U2ERO5WjyWF;>9P#&i-R1r=^*9zltXmPxfMKlm4CGl2YxpV(Dj3VfVS527UyT$cb@lMMXzHVNH8&}Shzsxne7hAZw@qUYZ zQoo$@CM2?<;Q;uI_AT?mA&N@cEpywVm$=R%YtXkgsHj85l!fAn-j*WU1ELE=On5se z?^fiXeWuR?qojg+=aO7<{;uGZ{F345d3e7mgsoXgXVt55|N`OK^d#QbMnD^?)yY}&gFm}RiOlZP`Q~C_GM>B^T%E&ZyMAQ`rW+)vQz)*0~m=+9*z25W{77_NCRHB~*Y?n}?8jjrTuyLeHaV9$8o zZy@U#LGedaP6^s>(AR9^u;-e&VVv?35%vmp6t93nson_xvCb=$-anFZBD}+;wl9Q$ z983>KxHapLX?1Wtsf#yKXX~h=mY?@znZ;ckbq&%k$$~K{mL10!q_zK8fp-fdei3hT zF9o9>CP$A}^mS?X+DwzmlCBph{7$8IsK33@!>LX_#8v$k5a04Z-GJowf+olhJSE4F z#MyfNypOCIHxjcp6`oc9o)k;!K1x2DDNHOqFA+qIqaeVL0J&{MInO&jml9^bl=W-v z?@#W%0W8hoR~J2`V=|6YES=)zD&(OiR)9(#TFd@DjGg|H72!_)`^GNXc>h!H$i=Qw z154JcN#~yiGxML3oxum&qbMXGj+A>d$1$;a*RtZ>3qPK6pFf+?^YH4*PIEDqn-OJj z7^OWm$>qIEkg5UK;Gjrf--g)^?Tql_X_JAtKbNAGdfbBZnNM+zpCC)a9U!d5cRiaA zsqOs~6ndTQhg6P94fKKfYg0S8nNx2GUBYjDn*FPzu@pf&c5JDe*td!ho?_d);g%QNvqudNJKu{3nCgxW^mG7`9bJOr)3A211->Jp4YF zE=@T*{lQU$T!k`Fav@z{KRq$AGW{2gcrCnJm(KjqI%}KYosC;_nLJ{q;Rt_TJ98Ub;gQBYLyYCFN`ylMJrj8HSgf{{SZ-wdqYSZCy|_KZ_njUz?ma4pwvc&lq55&e z^@fwbC$H19X&U6rL<-Hitm}3Mg=-!x#MjBNAnz!ly_}9xWv9bC&Noc-OK+NMt+GBW zS0uZP;(^*$kT~c{@2$tE8P~cvN5|R=b#E`q%${LtNSH4^d#Cu>yL%CS!DaHg5+-mF zl*B|3H4{-s_8)~VjH~uv2LbLczG1)670p#57*4=JC1KP=WnYjkf2Pi1YLhb!YKI01 z0do5B2a8|HTp_YH(4nn5&ADN@*Ka>VDRcW+cs_r0x6raI_4j%3prHJLz{1-Al7`xS zP$CKmyCcu@L(+t@mR(M|lvpvpqR3^LcBd(3ZYN)60Dc)DT!hYSbTqizfjPA=ii>1v zZ`E9voNu(JA+Z4j?l%K(|_-6i%*FsQ<+! zrfT&|wd(3Up+WgbyGUkZtcSR5=kD`>oH(!!p_QvwFJ_ZZW9gZP@S0^vz0l(R_p1EeJH|3aRjON7nzU++Y%j2I2agDGG}tm?HKv1r@a-$!b$OrKcDBi;NUDY zT0(*fK>Y``?=U2>2y!nssAEnaTQm=9)YLQeDCiLXL!5N%3l4ujS;I&`KoZoARgG&XxFOOIs(=u%~SZ`x`^pJA##iY+V(AOt|SLh4}OgikFw zLeScQtS=vUV}#KrF(rP?$(Lb(z+6=^`gfe&vw0CS4Q(9i=B-py8l@jvOwh0cjn@0C z`?Nj^l9lznl;$R+Y_WcCPfZALw|$}VP0YITU-4cm`pMnmYl}S+9|jVR)^-fR%>ph+5dcZ>H=o4KNCrKn)*wU@7RC%AGyaW^r;r{o2&tbM+a%#$nKulxI4DX&7 z`zM|6<9W6`vMvG@cZKuL z5R6QY|FR+vzo<*M`qRsP@HJ^V2Rm&(ImFm26^nRxhG$x!{%TkqDHp1G1nlTh-eZv2wi8a$@t zc4wMG?n#pT2+B)d*D6>{(moMUp?c zbAp__m>^P6`w0&lLHp<{X+O#SEzMEM@3pNO|1m!({R!#gT+OpbE`>3Q^Q>N>CRGvy zv=72n`RA}9X6wx|%{`_GGS|KWyoQmLf79L%-bUVym=J{_ba(t-q= z@B@1-A9?W&QcqWpg^Hb1x#=Ji_jM5*A z?2H>sZie{|SOhp&3|N&^II?*AmTY3b))jpRk7||Lf1sn_y@lHoJvF`jQ~H;vro|R& zbzcmGTv<7=WWOd^P8(UzYccf&es&qhuT}fpExq!2b4rC$#q?9qYc{Y*kXlB5cy{lh zrpLMYOcZE@Y90Cc&PGl5eV6GXv^9U-_hwu@SNNhsJSrC;h@>YYfO`P(Qu8&mJ4?yd zyh3A~GnHSk3;F0Z-z!iv(6b5n(%yYx#|#Vvpt#WXul}&7-?Ur)_h+qBO4+Mig#qoc zb!GJZG*{TwPoL@`PIOaET?PYzvPWp|Z}gCGyxBm9b$hejC(todrm{R-+&l6|`Zn%}>tpWg|8;RFgFCV3ys zuxi8DTT9tds+JC%X>03uk14)niAS*iJ$5EB`r%#QcbfNYMCnk5Li`~1jXum0zpY}K z9sfBbr!B}9$XWdbKQP5Og17{`dHC)VLfRAm31pzq(O11T6RUaGL#{)Qsu+;z$y;-&>(j~P(4 zNAXJ0^mzw>R)xV{Ah>TW77tVW?b*oe0_v>E^Pif%?#UX!T2|0bY~L`60y>8 zA=VH9uqOhhi(JF#4|AIM>$W7WXYH&@6%%Z>o<@m_PZt_6v8=U(mhfPeLSi=65Ve1IVt#*hDbn7x`ozDZMR?QX!y;cORkh<=!AE`N{_zh@ML}A-ASVy=4AAG71S{vU_(p{MkYS&Nadla*ncP-60cV2j%k?y(`N7Wo` z0aglV+z}vCDpHvPxkly~L4wH(J^i{hYnP0jem|u%rMHRZD_~I-(GuopmBiCX zN&)Jc#79$C2JZ`9`-SHbJ)bnYC#y$$%|s>vthYR*8j)x(^*zQ4=PSrMpSovbpdQn- zRbOm3B4c=@=8Iwg+sT5RaC1GJQILaFBl7#+9s<0!R8rh%o*EBd!u6Qww)D_6`uX;C z7X7i(l(5rk84g8cASWkyFnD48E#|%qW}ki?!xV0;bNZMcmy2c=bMas4YGEPU81ZoD z?>0%=Ag2s7718%BVh*z}5vfn_3j+Xm_0OsJ_lWq92 zmrWEKB689No{GZ=1|kga$U zFJ-<`mYz_p8P9wALwBS!o8r{JpIrk$^W-8hGt6FHn!(~;2wQG`!Iqg_SttC@l ze`ou&g5!b84nV~jy-xqb7MSvHGDB8hmj&0_HrdbpY<+UuHtb}uiNUFOuVBg7><*yk zmHC0k9<2wv^D*x>)a2p(F`OqxLW#Logmp@OMV)WgeomDpn8-8Ufs5~R9u>92G;_3` zC_rXg!hT*eW(*liV4&QgBkoBO-L#N@(mLV9=;`ng_nN9t(KoPT%1ROdF+%I5d?ebJ z$0h+rFFaXq5^OwdN-R7QK)HJP6JQhJ0l^m*j_kgh@o&GB^tm6W_Ob3ri1nHq?dwy4 z?VAP;d|zo7J*O=NBfKs6G!GQkg35)66pnCleC?8a{3G=`@fX^D^Sts{x3>|LBJh5r z4{in!ts)o6?Kj47bTZ-8M?MI=QZp|}62~`ReT~D@B|~MQZ}Pc>Sr3KlS=0rD&Qr7l z`6~x=K;Or&PSZSS)b8+je&s?#z0^ngd~Gp#LglT~zwkG#SmA(_1;h`=h`r6DLibAT zS9ahh{;z+O=nF3HaU?SVpN5Ca(v5)!yec=Z~i@5jhhg0O_`~CC2CB@yj z$#J~!v^+OKZ-Gw?{`Bj|ocL|KS;E?x;P8MKix}D;P;EvG!&b}HvvPN7FO|=qA`bR! z_|>+m+#zSbMt*cVbGtHc1P9~*0*dfU_#HwTd`mdb{1V!laSmxta{3wJXy5vEN?#~2 zw7%dDovcHU5I8&vz)gqV=YUSkK1bhpI>|nLg7D#a-nQaf6yt6QM!Q2#PslIWl3pcn z5G4l(1iYcv{A$o~!(C+hIUm&Svq%{5O%y>`kT4bS%6e2M#`B z_@*H;M*Tk6_htM~Ezjeg-kjEvZxOW!;d5T^yAjcR@heY>MCCaH3%C!$C@2~_5wdx> zFNrK1DR?G3wmn$tq{=T&Dw(~s{D(gpBh`|8JEg_$Lp2z70brU%%T0t~*4g=ScPBEY zDc_NoJY?RnM8NE(*WJ-O6mzvkY&&dBjR|0AA*YQLg_aUA>pb((M?Z+`K zJMB((fPT<)#LK0fc&4Mz*g;XlZt^3nGl4l6g?mY6m&EV_gE5x`fdbxS&CuGPB2n|) z58ZnqEWSoxFZ=>S3upnP=+!!gF%04V`uOp6V;-H8zvZX8tJ376wM#s4G9vR4!Tu%`gYi##xnAtWzhGnjoO?5=Y8cAso@ zyj-l_>USW+>(=#}rAj*Qbv(&xA-X$YC>0dJ!9^RcR2Z6y+!Hf*!Z2@j2gjn;klmo~ z7sNxlcvRbiR3_6%71_SrQ*H%=z%K#gDfboMU!)};?$;pk<6!*d=IEDw3FM3SOt_?j z^YvN>g}3jf`B7n$^w@zMVCs-GdgmL=J76>juJPyAO?Pqh;dvp%)Th?zeZ*EusdaVC zZ54OIAqC{1sDOmyf8jnO870L&dEdlOG_5zzck+C{Hms``T{~-ePQ|cGn^=8{!eU~- zN3}VeaX-L?ef$s*aQ`IX>znK`opx```t+n*NIAs4U6sX!p>S zw;a2w&5F0}$~>a`3hy5T+BDNwAJH=GCYTJrZy=RAvvJ|-!@lb}J!#2?S0c69hJ}Do zLmt+FSn48#$r^q@O4zcqA-BtDGqGIJ-Lrlq9`AMLi`SVG!$_1XUdn!t0MA?khDo5; zpPopCCcrr;xucj@_N@qpbhr(K=#Nq+op7hi(M_)I^mzOy@<0pyG!2MQCN_HRSn1m+f*Fl*h` zX#L>*puwZEl1f2O`<7hBRGt6vICJvW^LlkqJWvK+SfoQY9mf9ccijG8>0y90>0te6 zV$3p@sYoZ!wS^qVNFv>xT#dogzg1&~u%D9oDOF-Qd=WlazwMKM+>Gt~!E@rJvzkZK zYTPT1pS2$_VW7kPn zNdN9PxdtKR2L2?S=@K8(T?Ccf-eHO-t?~x-_sm)n2+iyPnESSiF#hUaYT|mGq{eX;HRHF zB%FW~>Oh}mO=0wfGXEp95BLSTMU=@r?bC5y*;Pz`s#&QRJ#X9>(`$PQ=`;vzp?z`x zq$k|T_j9N4dtA-1mYH4k>m}bm>8g%wG;HDju5vWu^3t|{f)cA1el#_qh%(wZL~LU! zmu0P)Dh5ump=y&wiUtE>ezwFvLdElLK7MZa$-VuN{vI&a2^_Sf4SmAs_|t+S7x?md zn*Nc>p8m{YJ+{m3bz7}KZqL){OqoWaM-A8_SR-;_d^sElB{Q%pek`HyA_ZaIQC zO(*k4an~96q3Hq;<`AUpZ%GkC5C(EoLC%9t{VxdQm`zK?7ftgitt03 zB&a>0WAAT;s`A3!;|;h zufCQ9*R%CFurFm7^5e5-G}_a9N*!#QtyK2M%2U4rCRB$mZREU|yUTH^falYQxrFX7 zqNuIhEr??TAl^k^iqXRa-y&UL&epJ|p&QIq0 zV!A$?trm@Zl9=S~Td~}0Ob)#6``b_HUdm7!eU(sHzFi2+1QOr}rM0i?CXrEUD4j+1 zM3TMKrU(Cb&~SyH57Wrw+aY&ztbd=L_%L!UjQA!T25NpLT5hx#a~NLXPp;Bz*GvYE z7TSKUvBll_7Ea6m!lqd=MdXc9jFA?EO#o6uIusfXiRvk}#kjdU4Q*fFOs=DEzYNSs zE5z+&rjbUc9BYUc>#0Ew`X~^GBnrXUz&h2Rb59-NC5h5wFZh+F?ya{NRCZlsZ&gd> zAGsbw=n;6ELNMG1!G3KXcBc5;wq2#(Qhs~?$W!TMQlgE*AifWe35plFIY>pwg`b1Y z5>keI4Ep$*Coyl@xcyOaX(@ZV>l9`FqRBDkGFL5A?)!79WKB)hKU`_SREh8dwjOOe z{E&PF=vFPs8NKI}Y<%=%JvY6aMrt-07uJVqHQx|YNVz|e;stCKT+xG3coT=ZZY_uK z;@v-NzPTF< zMpEt5pO%wott-~FW+DFy!>o~fT3HBMi@-T(op)oLsd;xRL+$>ORYY*_YrSxi0?m=o z%vapUi`L&MfI|iiZAfG1KpJL0=ZNnlQ5Vq}7aVaL8E-g&`_LeYqW!pq7Qd~U)q_u4 zP_UMe1C$i{IedraUL;J&SJ5EHkJFKn`?II@_FRsk)9?pTZdX41Mb3#bL!-N|AWRcv z=&41AX|TQ-y#|?0LQ&JV!nrpx#WFs$Om;^Exib5Q*oao!`}05;DTe}&qt82L1GB!f zU+^}2DL5y3>l=N)vt6NYrD57E{ZSqvtILV6Z?^0Ja`3wlP*p<_raD`q>TJh4zd$A- zOrUH<>zcMQT6^xrHnY`3kLJ%bBlJ1@VPu8}hS6$l3iEoJ$l+_tcCe37m;0SYv(0_BqR5G zxZ+w%*&wHg8h*F`z5^;T=R7!*W5&bv^!}Y(ftCJnQVKVvmWf`A1Kt7!3=TLX}lsPV}H@y=xE? zj%(8X2_s~4vl%XsYdKlcZKW8erXsni;^sjTZT-EbcLC&-P%N1H>x}(_QG2ew`M^A<`GH`s^bD^xuI{E`zR@7`Y`sGCSwC7OI3t` zL$ne%E}et9ee*$`a|Gb{#T2)_!4X3vVVPtMoRNIoIo`Y$I@vqn~xEAEt2(8-JCIRYCJ>#+uZC=*zFREiFnW zW6uLW$%(&pBmBf+0dkN&LokII(Aa}mN7Id2TGqD~Li*qT6~vS2eg) zl;T}{GzR2giYnr2dF~x>_flhpQem-T*I@}>#*>A(9}AlmxC*cmsR4P9jTO4@7NEI% z%gl?h`d4W5M;wnn+bwL8oRYahDw$aQ?8@;q&oJ?x(1V5OuMKt>Ip=utY#zUS@$u*P zh18vYImAR`D#)(Bi**brMAf0hz#HDbcWcN!hkG|IXCdRzKGlCB#_?hh(WF0}qS$~= zZAvw9Lyp9WtTi0agD`L$v46j(DAC-#tf)2rx4->Gf85VSm$}AY=TqpEc=Cosc~^$$ zT3z9Hh9I*PuVtJdc^ZXcmHkD-$9;TAz1bP3I`~IV=nC{MHLmdsowhv6CoyHY7|`#N z48{py#s>uPRfk2soqGA|Y3<+m#f9ddIi{+Ts_Q(?rhNQMARA$@ zXbz?zVT5p+>L7K2TK9fXy}x2~{-P|B`CmX;-q7FkNwI(GZWgRP{P=T^fUo$@tYO(3 zKKjUm6%!ZxP~6f!`}lTTL|XHW(5cCKrYg&V;Zi;^#V@{=*De4Y3(7Y_==-0SjB%1> z>6XqL60JQXp6e6PrWNZ-8$FTUB7f6!{_;-yWghk|+H>6${s3WahK1{E5Q{js#4 zI6q4<=W}-2n#25tqSAo z(!xZChRkH*%OLS*tDj@!8*7gLdcC=Ge(h}|XgR>lAs~g|_9G-5u&XTl5rizP_ka7_ zztd>S<_d0_V8w;N(a?+7;Ub}&**!-Dj*?2q$(-lPJcq+a!+L-OdBnzvm8`6PiGbl5 zmu=aYUiQ?+E2AXQvY7395O$5PjD zHg_5mey?3|_tSvEU)M(PpcG*cJQ97Ee4|45MY$a=TK4cC_y1{s>23Sy&kB$37~*wl zY_-ocB592S(WMN@%Fd)#o#6&&w*Ni8g$dpGj%f@2Zq+z7XZrP|%%)2)75N#O?rV}l zmbYYfD7Hu8tf5T={Hy)7w|~bx$7iOmCT{d+s_VFf2D!KrQvL2u>-qj{&(NF1={d(a zpnxKQA>9Wf0Ni1WHKOjnJjSIKc-Hnc+)(+FDABr_qQMQ5b-l*mw(qg46W_8l;7$V4 z4(V_0L(CHFmHoYo0XC9pRJUwr`o_Oq$BDVmr10|A(>EjpGZ&2IIlrKy6M$o))kc3V z##=hU<3`z&<+%NLipJcqIlroZ>XbsY>DiP}SFyCUaSjyW8xS=jdz{dUS!YFjec1V+ zgaR(g08+_~t(d-q%I#q-A%k}bCk+*JKW~HA4_*%f3i5~I1p*54nJ65Wj3g$C9(9jg z_6^SwyZe!wqPl69A>w34^W}o?kVgaPI{L}&jbWC_RyK-dd)6!RMd*r8+r4)Sx6i&M zx$&9k*&|V!jMYc~Ae0Asa%dgcKZbWOuoT%&t3drwVY}kvk215kJO6fGKkKkLoIT1f z_F+}?EBgf-2%=EB6baf!4{LHi@x(QQFQyuZ7{x1^x~!b@t0N`vRc(Cid?HZ$REd5& zO8=ueg!aFeei-as&dfG?(J9=g6S^GC$RYIlBmY8HU5KmQkM(^x9Q zg`;~NA5rP17)#*Am8dbmtSY-6RImVT_UP-pk%!sGQS}qHI5pEH-{f1fKSmR)Ng61w zUG$!JFgW(}4ZYwb=pQ*bR3F*?_iB^Ta&RqmueIWr1`8CaDvoCu_s}~0`4ghJa&gi4 zv(v3)3c5TaTWUfA}Ec@w?1|1*RU1AsjA7rh&2-y zMK@!h@;3oduQx!qKG%+3%`F~H#y~3Xs*Uy^yyGc)1TR)fZVy#K}+G6 zL)QEYHADJ4yE?7v1L96XX;0?2HPnuX<4#KlrxJK(cI#4rei9Tt7_qtwjMb=12|w<% zS5EQ8%9!L2op&?j>T=FSza}94|Sc<=>UhKQ1?e98i`ZIsSlo%+E7_D{8w%Cw|$AR_>w6 z#l`B4*;CrprbIzI>B(s-YcxMlZOI3!X!a218k9_J8hgitCHqe4=Z_!k&3;8!xYTf6 z8ERQyNdELs;V;+@=oUc$1s+iULz;Xn-%xQhk$Gj1u#}&xzoa4@EjimZtr9jbncwP7 zHyc!oqHu*kYX8?w9+uS}Y4trhX7~FP+f?*WSjuHqDdN+SWQpOO-sazDs?Go;8oD>c zfW>oP?qdWdUijF4Awle1@1CY0sr$Q>Q96mT3TC!i+<5w3V=Rd*c;EJJNTop3e z4K}myo#gQA?i(W=|FDM7{7%OH=@i^1`AsZ2aoRmt#kpq~{3W>2h-I9e!1(cuvL>G^ z73;p)Yd;$r{EVNuc-OAnnuF}dMen5*{N1*zAg2hJVe|{iOUE2~?seC?mVsRbpi&U{XbIOZXVlrEHEx#pago}cK z%EJG!a8RBPD|)E$tNjktiYUjyvIiDcefFjdQiN&Vub1ZLC$ zJpzvzTq9(GQx#~B6BhV2*YVN9C7z4Nr#SP9iNz~Us*zqx?Y7?BdYmfzW{D2)8Upet zE|&cZ*L&F3lqgx&W*UV*72@?MGw#E(=EzT^FFB;Jd$(gDY#qyg~)1CUC!I%n^rzW zdCmFDP4EX4pg$RHFl)Eabu~DI;oz6`FLs2_H1Sm!rntGOvtNjNSI=tAU*^HjNyPTb z8a@Xg2=pqG5Uc=*U3+x%wxb=&tB#(Qi8z+w_vpEtshFf+|K(rtV9j-`e z`8_1B5P#r2QTEAZj?D_ivB$Oj9NFd4Q^N!a=L}D`oLG!eJ@yEq6M$esE9m~2Z%$%f zZ~BF&JUKiIfuyJZWjQVe1`>tj1~-1EEc2ZY-Anf$E(bYiqDH{Xlm9S&i&apX-0O2P zOh^1Yu3E7;+!aoaQyV(xDrGDe_sBydd=UH=n1*mbPXiVSF%d<$+T+*Mt6#HcdV9X1 zm2>O7oArTpLzKSho!(fxgAsrfQB5+4Tzm)S_jzm?%r}{=%rxbde|7AC#T=P#VYoUn zdglDN=by5^9aO7^JUEc(W0;P{eD6YTo&y!P+h5C@nMSV#LQaxgB0u&u{%M>O{h56nFseMx@xe14g{wL$StG0bm2*$63RV;YBAc)ZACggU|Ym)HB^L(nSAIXO8&N;T`qF{+{#+7MAfsD zh?EzBKtUky9?*Ue56j zAJ(@tOVDzdnyw3-iQ$g=`k_3--v@jcVd&J{ zzn&d0G24RQOnrsDYN739#0CE^+D#->V`Da}CwcW4b4S{iWHP~m!EjpeB=_YS52KX( zeDk9fUQCG_0XH5Bzo0D4Uz=5GQ~oQdSl@fWCW1AW%`j6H($2VQGXy zX3nz`>$EB@*0o^T{X`cv2`ka*{pcEy1_y{EUCpXt~VdvVfWcaKu3;^Oh$SIz1$jdl`RUf*t~h7?fD#7v7~*g(uLDi;z2;(z+U+Vu zo3X5Sbqejw+^6pS^b|?BQ%L4(^M?0dB77Ox;*flR-zG-EhK|%a@u;k_5Zv|`j9cm@ zGe}mP+~y2s!E4@Dq9C-f1m7K+agnM-s6SeB!45I!45inPWTxJ9yit)5z>rt6D;z5j z%3{m5!#c}RS-cHL1=UfchCP){iB9W*bNC-W^?%@d_J4QEegf)CdS7Hl!ui=+Pxr=0 zBOJ-JlRcL2Zpy049e-OHb2M1-z#x@AdKvxUq-1Tqf}G~DwQgNy1IqD)(1*>^w`x+v z3{&O73xsjhNH#z7khe~IQ}JiB>*>kR_Y2aqCqx8wxL!Dpi)AsHYTV)6<@a&}r$=5) z0s(QBmy?qmfdmu*YQ?hXJQ+Gko!Es>5-Nk+@xkhLdU=gogn{WNvsV++mJj|4)PJ$m zH9x?rz07lCq|T=ljJuuD%=|6oQRqe9p6%Au`-BCaizqn#a7&}lxnd5J$3kthRxd_00Sym(d@EID+Qi<3XTs|-)Kkw zi9#ZWA(j$X1HTE8R+6BB-w=u@q4OeJ0Pw z^N6xgfjzCy+nMyU)Wpg#wh*oK2i=iZj7tCizy9{`#?t^@d zGRlqErp+_Bw;_q%YV^nF6H5ngLUBF8B7fAJ(|t+B$Vh@mY9c5^(wx3YqNbv8LR<6bQ~Z* zpbqJ50c%iNbcaI{|C%s8@nd%TrL=2B)@%a|w(>oAclx}d61s9hP8s+h&=HBd2gaJ0 zq>wnUkv5jn6kNh58@Y~O=pajG=2uO%%+Xz^bz7Jn9DV=>BhFFm;dn@i-q4UuUsc9F z$)ae{%Ay>zE2BbgKMS~vbFKMw-V&Ce0t_KBBrib@&l#-9C$f@4W<~xM20PRmLA1uMp<>8B6sW{dj3)ftAdrT z<0e#eVL0Rg3Ebquk%JawkEN74)mY((un$kwdb!`9cbW8R4kC;iW;!KP;kTnExj!=y zZIg#aF~-LbPlQu9j$FmK?^-G2V@Kz(ik~F3W*=zX8D8xuh!)<0%%L3g&7tLfBK3PX zy+)C$42|JyPZf2>pG-UI#WC8N(~UAkGmP!^vf#BoN6E=UDha(SAL1}+h4J9zrxVB3$z2{no$kSG!p$T!$nwP~{(x<>wb*ex7yXv#Zv(b!fk;DHlHGkgN@PsQCPg z{R6ctX{!akG)Wa8CjwLJ(61};5Y-)!)8<-EkZUiia%Um+y3#uJg$V)uMvD_unMKB| zw#!gg1dfM;sB-L(0%^4K55da^<@1GA|2~KmH&fh`(^%@&98?d{89!EDv9}0vau6M& zqtV7}%sNFyW{&8+BfDFEC9eGJiu89klr zL3?;hDfNxbA`I&>#rFmY-+TO2Yg@l%mu@k`qP(`g>rIrte>sPpdu| zH1zm*gQ*k4cgOpbjA>`3&pU{h1xy0|B<$2~t;)cemzop?LJ`(*WHmxz@&_taz@0Yrwyn9Iu}rUCfE4!Rfb_1j36u0#Fw*%(xVyReg2#JE zM991QJ!vQP?`V>g9=~}N)mBG90iafi^Z4eTe;zJU{IsaU_qKQPJs*7jt(EL<*>B zlW3b#+l5{y?5Ax_Xu^?%`H;C!6^p+Iqx5bc>wgeZ_t!SVMxCxVet{l^j)3$9`Z=_B zV}768>{~ve^2-^<&&|TIJ!`KmdEI^e^Wj5dFJ8_c$3u8lKu$tH5J^;fFJc(88ZL@) zX5oz0JjuJQm}t9Upy{l#MfCTnA#G9W*vR;F@%+DD(nqgiHJ$Gpbt3b! ze_q0c8i}k3oP@|e7DQpr%{}7+c_jY);)O@P4@jx?lfxq;Z7p0b4qI&9HLG@}9RfL+ zHGvcgY7S8}_j*!n6u&jdZRxfVm}biq96$AE=###7_SVzSnl~Rxl%WcaA_obGG=I!_ zCwh|2cCo2d(b`ukfBWU^-;M1NH~pMlznNw9q(NY8Cdi419q`YVzQXJa8Nt@gb%W=k z6XC1_tpD!jkh@-2;FN!N+A@&BK@l$v{Bb2YNCctPW+)(Z5#Nb3^~m)AzYC1iwRCn_ zFO%N2l?1f!^=uNq2)@NE=(GS-ol4Msh}Q0tlNfCzHTAb~YM4bj^mW?^MGU=taxw>> zmetCeGQ6~eKct$s!5xR$orw0!dyDv7lvs-V9FzpuSgcrB%5EAkSD6Hlj^7^-iwX}5 z2ge)jGtTaVG!t8L73VbVtQM4SWhY&YObLI?@bw70(aHC7*)b(4a_FQd-192&x&=Q5 zhn9ZR`-b1;!uL8D6gs5%k_StLl9pwYzO#W3gql-;HirR;m`n&($55(FgtZ7CJ{@72Ar6Wno?IyaIbq?0$f+*|b07BDUIu-VCRw;veR2@bIrf-Z+-eNx zNy?8uI|uv%u0FH?Il#^#EDft)&>IHpyh*j96D8T=GJnj|Fe9a=>8-E%!Eta*~M6uC_`?W;^VY;X>qPZ=fgVz z*fl>=@N4VD=r_-kfy)l`*41lFZE`f%6L~J+1a_FR(rXeVo$e2A#s?S#R0)L<%Anl= z4C+psv9oeE+0=0Bf+`E)ngU6r>4nd?XU0l+uO?k?vkZW-2m*2poqsS~PUlvR(Cdf1 z`m8#r{i)UZJLgpowVXoJ+vWpbs*6pAr04gOx#CFk-Os~Oz7`iRj``*|JD>VdDL9jS zMO>C6G%XFcK%t%}NY|_5+9&YQfMyxVxD>y_+*gv{g}mw0>FT!6<$4DavPHRYC!Vle zyj?`?MkakmDo+!poWj6MbjipKC}I(paCcNq#)U*mvz4ws=v*G%y;gcZ<;8%(lwj_O zQ&iV_WZ`ql@HzB7FFYi$>$n<)*K?(|BJF|lU*h~Z8Y(4fFRA3~srHk`+)auMFbwB5?&_j-X-Ss0I7hq-a)-};c$K! z59!>8pch*$7lt3#-Fqo1WGGVDKW?-ZpJN@-!p7Y-3UYv`Ktdpo5zO;%d7HO=zx%nt z53!}I=2Rq`kF{&mGwjUOEwj0-q^q`y!K;9lF+{Eb%IpYQ>?dJ*#o8U|`zE20W1bPm ztmxC}w@P=_#=JwUyD#)>PQg4cIfm?TG&e0=#|4%2)fDwMiOa@0h$ zj&O8Rxw=EXf@j}*IWX_Z?U?;9f5wZKYIJtSx~2Z+mFsISD{^cmVF3b9x{LwF0En z7gmOmx{t@S3ExOM({jF>^gpdm8^$xg3q7jfQ{JzH$ zKi<2ExmOoO?v^{(M7T@%((jbnoL|LBD+o^!`6>u_8~5v_(&k=hG7xFF8Z~qsE2i< z1xsC;yXMqe;$@2YEK2tTdWMZG6Wj_gdae1KZ z5k;GqyhFFZ(u(b_b5NFK-R-|SVk(Bp%lFx&^)@cY*HTQ) zWGm}M_w5D2>xnyj-(z`VtHQ1C_)&h+k{Te`;xR(GACON)rvTmo=@(+gmQqsxhR?8+ ze7WS?A{m@aMsS9ACS^{o=nlom-3Nv9F zP|cpzuolQ|Ir{G(0bR;_xdE6;t0=_qrIYF4zsGgvN}gb-(5F-3&gHS)c=u+rvt0t) zC7PL_Ol$mSgbw`o!VC)^G0){)G620c-J7B0MLzQ)N257`tzM18a`zeMfIY zQVr(!XbkTJC-wxH3fsAQR#AtQd#V>3_Wx!$+r}jkpR=4^1>jF$$zQ`TM%m}T@*b>l zu^OQYH~y0Rb-QSYUHn=weL;zS_JjPpsy6T)WzmC%jLJQXmtsnjzD>yLIjPF5PI-Cn zdh~9WLUn~x*SWC1FuZZx#5hzo4h0O{f6lr6m@Hln>%DgV@iY1}QQPm*#$#~3HbUP; znTE53>UmutxF-!TL}gKcGNHZFlw6El7nAwlWjlFUuHDQGdxB6 z*}tT{SHo#J{6@;vxihiP-+XYQ_Ob|wy7F;Tv%f3WLo50q`=>rLw=VT*&BFbmVY|WJ zsSnGVJE<0BWq)~mHvXPr;kpFs8EE(r5bF0Nssl8Jl$A-RVlmw-iK`J!PrujJD|dF% zOhs(irb_rmaQ(7v1vG{N`Y_`Hj-Xo-54u;792Iy>2Y>tPPTya5^4iBqioE{2&f@N> zbe=^xH-AjZ73oy8=(J;7vNimXIas#`&WG^$Uj*c9!jeAbZ@2bTS_L)v{XbSHhHAP! zt)VprD-Bu=Y4OblB2R={YVJjH@y%|JqOIS;wNhT^N36G*P0wkac8S;&6J)KkzeG(c zjB33_3Kd^QkDwub`)h}7N6?7q)MfIDa*Z|l;`x>PUaL+FHLknj_B(DVw)v$!&McG6 zCfEmSJ+~(JhLks)h3lNt_Z;hEu}x%>>&q5_pK~nFNk%v@Lc{|Ui3hm#3@?m|GKdZ9 z$MJ~NRq=8)96Kh`pPs4Ss=kXp70=AzGLX@*!xia8NG_ts+~)F zy-CGhY^~^n>$UAPX%fv1w!rZO!!XcM+E_5gO$f)niR(xuF~%Ncc{Nac+o6R)FNa`M z(JkKWOjl4gAG{+4Q2q#KNOC0=`fB_yOGelo_g9{Wz8ary_!@;`3rW<|^9p#UD^)1S zY_q=FB~Lk_SlhqLfx#rYJa)Nsyhm%*r0iVPZ4;gx7M6aPS@M4f`^u;)*DYL9Nl9VR zpma%xN~fTN5;h77l8TC;ARr~uE#2MHDWQTOsZ!FQv?w7VAa}z0Se$dlz2o}Bz4sV< zj_+M>%=yfE=EO-cyQaaoc1M_@2Hi?X`S*GP25@wBso2!K;HqH8#fhq4~(U9Jv%=Bwd9Ma_(SQNr$EL{Hbz>5Q*&`UEy~PYvng88cYOP-6Iu)ggRVbYbC{SpR9vH2D z#t%U_Rxt0GNg(Ez-C49RiBT^C3uG ze8#{b!fo2=PDXF6 z-IaB2X0G!`sEtM< zLhN?zh29IdZ=c9A?&PfH03Ks#3k5u}uP5C)FmMUGb?|G)WA=INYH`+iPHAeUvd$CS zk(qYxpWb*}$#M+^IcPjXYTCD_F-1U$RU2Yi+N~6>sM)ok5+)-Ds;8;1oqHbPjBVaO zFA)pgv4{#V1fzdnMFnP^A|`iTUJwmw;E3Tmjvxn# zH-zG#W*q~2yhq8M6}iY3&$lP}{<^y0Qxs=6 zYI-@UG!)12qT6R~KDKQR&(<`)mlb$B9S7u~zy;aQ^&L!gCw4+($f>UxCCsJ&da%D` z5q=+!i2J#L%Vy6UqNS6xo(k0*&>?_Ey9*f@6{hIwpC1;?TFIL%^YAal;ONnp60uVm zd`~9p?uGvz8dHPMNyA`E^mb z7irCk{EDg4Y;D~w*O>miL-#@sJNb*}qh_gLGRAm%fpUb~xsq@HI7AZy$`uCdjlRyC5PL>Y-MIA|K76ey z_M1tq&$gCRo-pAM=u2B&AgOGn#S?hE%L*|_C1J#Ah+n`w^YX1F(W+ei=rF&pWM-PL z2;x~eG6trCN0P_m{er3;pgs@+WATgNmayC(Lpfc&-AdhRHuj zXV+F4=D4e{MZ}H}5zLyXx{d7UDqF3495;OS_6YT{=JQ1}XZoSg3uw6y2!hgzF>>t5 zS2R}oTSNF2Dhxij)G}%=8=hZuV~x<)ey8rrb6*_fVDt~tjXmj$xhCg+-fF!Q948$R zF=Nw69!xAM_1Q+o?g(-EhT1?~#`-qMDN4b#hJCG)b?Ed7UKJRvuigb}ZS!KMBHiap zR|iQ)J_OT+2j@np(|+gxIcPUW@;hVA=D1;D`KKu#4xm}svcY5{Z47&9)n4nEsm z`0~#YYx=8oFYZTG&%d=D4EmWrPRZnqbpu+5v=*Ws@*5})o{{hT#U{f5X$^t4un^TL z&i5nZEc|&MOz+$!e%ZTe4&T_TsyLV^*o_P)fMZZ%e@wC}v%`>7u#kWIA>Z@q2b>yF zEn`EQIonj!fvk}EQGu?1L_7SLz#Kyl`=_8{(W1Y3Inr*Vt|~>J?(sxF%{s%i5$s)j zo|71e4}phJ8o6dshjoE|leZOUq^$m(Sc?xNeDsY!2j}!F(P4%OVMn6gw7i`BJ&+GU zc{HTR{7Z^X@xyVr5@4}K9wWzc#UsaoAvUZy=k~Jx4LW!@NMUH^J|ar-40&>Kc8V-D zLnS|xoHv`baj~iLQIbRZjkb%eMp$DUdJM1(do1|j4HW1-`}2e&sis=kJd z)R35iLQnLmRu&-LFqoPIG!8;{sHcQv>$2D$%jCW2KyY=1&innfwXQby9Va6EDABX^ zuGbH~C=n`ST{?neOq_D&W0IE@V~?wm8cED}S~fv#Nu~GeHo$JsbBzAt2vSP{2P=2- z2tSjhm8o5(EDN@=UR>0J>gk>*>95$WXXT=BgJt0d?&UtvW~LPx`3M^WH6bg;Kby&k zW3sg~bWUD$ORQl#dIpE2u3ol`lwBru4?cl&j(#V@$jBM^p4t6DmsjU}(@8gWr>qPp zyvy{ahMumiP*&l*!f#3F!v^>SCBKOJZ)(Np@gA$G$mc(CR&G(bXMPrT*Lz}UDplqi zyu&~)VQwv{2r*h=RcO>in~i?toxt~QyswUTdi9)4EBBYuC7HtV>x|T6VtAdep1T(i zyCxk6{V1X!c2ID;1HBxGxe;`YxokbYxSh8uc7EhXxC!wkCc=2WpeCh{lK~Nd345_c z;FCgE5p5u#3%2D9z0n23zXdUySxxVl@wS%f%Q*WiM3&nk7M&ZtIL(M5wg^Muks`Nk zsO?8;8+T-POlOLd&xVv+hIp+mES|rmXFkTV95Je1Rmwm#0c;4OK(~+7!KNepaPYlx zi_3rY-7*c$KCi}a*x-#>_>DV}&^yaV)a2UUU24DrIVEt~(c3Z+kNIBzPbkh$Zt4dP(%!HUB)0V$_?nP)YG2d3doFlx(p8iA7Ik_# zO32fUa|R{$fO#r7)LLiI63_+IoFO6TzcCmz^N=0y>**leJ1@;%iI0|XTP``+p6hEU zz{;j75n+v`Is;Z8IzW*9>_6nOO7={Q(%LN2_T<)gYQ2Jg^x-MV!3R=1%H$a-U4o@d z_8^>qX6~AK52*cIt>2To&uy2fc5+o`IZ-C`?`4 zHyd>&7&Ifc-i_ZBQys+?wOYLUbm=bfHUGk(_Ga6dtS!2ZtVvDiIT1t6M`MB}e2d9E zfr)GVr1=+2k2syY|D!WUy!keZ;wmd@n&VCc6#cys5HF)OWAf{V?$;?b>V)*nsayp^^eI4egr6B6xZVglZ3jLmgR%;%w(58=Y;c z$FR9CmfyFe6$0=ntpxqe=--ozcq?!})crOYkW%T+!(Jx$%?>5p^FBCVe&uooB38D{kzG@9ohRwPh&pjcLYWAr?}N_B6O z8-ArFzCV}Ta;IEI_LlzjK51wvQ-YiW!oT-x8sm)l^xX7&(@iL&9$u_OSkE*T6aCZi zuG$TsJhIaoD)-kRfmGky=ofb)ljTVJ4Z0tucf zXg-SiQ-85@`NVm9=dkC05(4}0zg*_tU8LA0T+!Yys|LoR`}hwM6w`F(QrdNbii#~rcmG8NOH_m4g0&7XTg(e z5M6-arU>G_b>w2sEs4SClW({=!}e8MuNGR>45Pb`TG^*mR}}?1eB4lPK`*NUeHT(z z^`{Z(Y{AApiHAkPj>1xu$EVQIVTF(g&R*z@9{#S!I>EXh9w|WsnD~EKbas!^e06CC5lVus*kpGtiugd?$0wPlY}*%;{<@R;7X) z%+6GWX_ot9(=b1f1xo*D0BOOW|1ALgj}Tf){*_BdN6%4^r`Lb#y%!qT9@g3FX!5f8 zro|Uc7Aha@gX_`6Q%5OBQ~AiC%XpNvQRb@TRlMthbuHi7UR?gX_~1eeSbOlj5cD1s zhq)ecmEPL z4DQ-r{=r`mS=(PZx~(^*ZV)?HyiVgCOC1jtewvj@Q@Mj;1kJ`#Rq^Ywsjemm`>lM9 zhcK+R=u7+Ur+$1{E(WpX^Q@owtN++A`O5G)-oXU}sUis+@B154Mpm*u80b=Qu2V%u)QC4MM&mUD@X;`yxXRHvO2gVXfx9*-!uQaKkC0xZm8f zkZxRTC|k#_qI=gIE4&BIAYz2P{kX$PR9w1SZbf)8%yi#JRh*BT(nOLB7QOJSjZ4g3 zND905#}jO=B9Qu`bw)mthXozAnO^>Z$~L7Qr4oYs16wezGv%?@o9zhHqMd9{m+eL- zyb%~&CXU{!ylUi){P$t~_kZotBkce1D)bL$6vA)9dHgrE|JyfQQS2RTE7!q`j&ZnO zABbCWO=?LToLR}!kD+Ei0?F{VcipE|@f;;%{i~XXa)r*^wrenQE>8mxB?_T@w6QB{ z$DCQl&BmQ6DQP1k2ct3rtcJ?xuhoV&&$-;S?of+renOVGr(`7$+T{l7$+1?uC~jkK7opKV|Jn%4jp|UIjgU(GYkQT0aNW?jzxNAz?XdawE}|^fM^0-5C6c*4 zIOj@d))Z^wEHm_Tnv~I9*xV`SPdKrbR2f_FhC+!C>N%tl@hq@GF$TuSG9= zb_dhd;MF(EGjHbVrZhhxCM}mTT}Xbb>QtwUp0lTuN}s)OA0#JXW)B*#*N>C_KNS?~ z{yFULcN^7SlW%ImMqATJ)LV*dX+EvBOZ_5jsOYsx{LrAz6UAL#jyd}ahySmS6MH7D zXM3&pB00mLaaDtBXuri>HJ=SO4xfK{H(z}R$89gojJ_}xZWxQ!8e7`L-g6(zYQxy; zl*6g?w|}A^e973xdGom!myGZWK4=F;NDiQ1`A?+y48Et`R;E!TsP@Ku95*FCl9lTQ z1#QOc%zc@SndljZqr{NK71^sHLnFd|7JTWJXBVzK}~WGc*!ao zy&ewda7lPF{u{{3-PWOkfubB?meOZ#hB-UNB-E^|%86@g!8-%94j{eZ_0WR!>_ z+t7|d2D?^{J7Uuxy~eEEf9ZJUylu7`5KHwI54vzgvN&Hj^()9hc{g$aGSV+ZzV{(N7pMaSx@S2y`-j_8|T^-fC*9uMie1l13qY@mgB|K1k7#yG&{R^hwN4d9c9Sta{&!xb3MizOi;VXY}z0%uB1S0#~! zag!yE>Ep-8S~x~k{y|6m0l@&yg}Imea;`{kE}Yv9#c@iUMUCF*ig?CgdM<+b=nOH9 zhH0%P)1aXjMC#8$u|QBBLGtZ~zwcV}Ox3qw?4KoB9ySVRUwBdBEQ;yZWweN2p^~n; z<^YBa#^N1x6aJaR+%MrYfhV}T7N&Q~7gQHGUwHQNw{zRYmpu2tXZ-5o_Z>V$D1nwj ztijM>6~mNfa%8tx8sn!){Jf9-f^_wYO=+ea88v~UZ@x$h;xK^z0AP)DJ${Tu?+YkE zgXUU7XJ+LaPdw{UV{P~2c^hwu2y(^cu1&WGC>5?X@97;$QDi?;5poESTM;C#czi)M zNat~U1}Vv-vbA^%9A~0P1#9(iQQTX;ivXx#asko@m3>$RROV-4)~mB_J!~OkYD}6& z;nAFx#If8_wL3xc{YcX=1o|X_Y!mS~ieX?8qG$@QuD1yu!#)+^=*mDmC{KmuT}XUg zz_jsGPEd+o`O%aB_shCChGs z_r?J+|L&X&IR3F%eBpeH;1w<_`}O1J*gvs90y&kv2-5zu%Z$UQ2meH->rXE!UDKu3 zsnUEEHbph|uu$^x%$4-!BJ4Zw7ofU90UFDZTI5wIu0b43j`fh%DNb#jizhU=cTZ4g zIBaX&5X)obre|^s_(hvl4sv@A75aN`V9X{WXUdmwGTgG@5u4}pMT(J_lRt{?M?QKc z&`Px1T9@@NYkAL%N*@p*G#<7BT#{8MR_K?&lKq%*KbkSnuM%tNS=bWpIDU}z>+u)t zP#mQQMO;Wct}h?+`xLl*l}xna3ucDKxPy6v3Z1eR%(PjqZ!D==m|dQ#5dt~L6(eBL z7X~LG>m=PM7plsaET=L0#Ao#LUE_O$R11Q*kkr%=P0>UY~dTd0@2S;3Nkl+@dr6^V4X$pOYk;EF7=ogD(h}fJ*hso z_U$Q;cULQ1UdPpts!cH04D9?P-wO}`b2O5#*sa8vt(~0T;nv6BmuC_VrFcE*7(^Y_ zp)(Acd-~btA%1stN+}dMNuvsSF*TFx8YV@x6;Fa1=}K9`@07UGE@s(Ym}m34N&2oP z`ZnX<`hZaa*~fq(%(?M}UD`fs`e$S$+M-(JyVE&uQq!f6Fa2n~XvLPF{8;1&*i#Hj z-O=Wt1?joldq0scodqfrNUckc2ePihczcrbhMpXI&TnDeuc)%g#dgC*-xzaA*BH24<=xZ`{6{ z78_`DS)KQUmF&-yfDO`|tHaHjve9Zymmb@J-wm~Ch*t5c##rU0lxxk>(?(ipR;QG7 zL`Q^!IbGGH3N|%l{g4WJn*``j zRT7-F{e7MD#-NDX0}6fLPMpCjZk4uJPGk0WF}BCz5DDK+{D;&1`tNZlP7&UpptCO* zoEIj)lK#dujt>kS$9W^=o&gTZGg%j>$%fVG5?!3XNBdjg|g8os`>kaWi7j8LV0 z@L9V}q{wWU+Fn4?s>{lV=1Z<0mZ*q47!%U7_p@3dr}%JCe*e=cvu zM{)Lgy~)Y!2+3>bPyv-7w^xyk-WT7)cv*yt_{+^%ovvuNpsUF;9&B7mR5uNb$!=7g zqRx}(npg)EvDZ0*Rxdq=X;g;9SL~f*qSwzld?o$&C*h3!pk=EZskw8ILZYFyZauWB zz(6qQPT$|pzC5&Af_26kI5GZkcTILkzk-8$+h8!qH>29jrGu@un$2#h_$>v(3t}*M z6)iU%i7DQ~Wy+osx$Nt;@%h@n$3E$?4&&Ce-69{#aXePv3pqC4rX+?bcQCI24Lb*y zF?#S9M;M`e7~6fSAyHL*`6qXzq-&3PTVq`m9rMUMa`G<(1)#)Q1c9rbk(h(HeKPN! z8sr+u$oe}hO?YleghcyF%5u?FR$Vb1SG?H?a6%ZW9nlJ-2j$&Lw2FxnAZS=;U{!(O-_^B#l#k_rQR~Mp>1cZ4LAleAWX()g2Zs7Cvv=t^`g_ONrsZmh`IY?(9wOPSU7~&Wy z>AJ##Xm+93@qN`V@9}k-JNLSrdqw`>N6}v%yo=14z)Y)v%Kd~Xx}7HUd3(`i$%^Z% z{uE8pspbaX_9)RK^!<(f%yysV3f90r>@j(w-RejnWI@hNHf2Db#3nmRmFC#76e}u| zcNSW`EbnLLTqfu?BF>)L>!|_oj{L5ga*UjsiG#b$Als+ajOEw#e?7upU(7sq4nM_S zESc<1`@>;hkdubd4(RWdLeVnnErD;!F?v~oHewtVa-H!a-8_@?&AVUvj%9iG&>2aAqTlyt_8(mP z;X}paliBfd#Tv5t(K7Kgo3Q)dwf>Jme1;MN_bRHeJoNn-KV*aW*3H># zU7u9;W^&NszR{l&LS-);O0LsBuRdj!@#9qVfq{Slk;v$bfY0dtfODQC&%AOYK&><5 z{=J_9!^1qj^K=gDK6kNY3q%GKms+5FM->=j5YD=A=+)TUe~@!xKh~ALYCXc{ZOC+O zGk4_7!pVhXriRy9zUgR$5@p!FqE^k9^OAdWm((*0ma(*9!8dukbu zq0CGIW!Kt%Z7g>ukZkpKB(;_lV>6n{QAB7Rpqhut)_I>>8mU~Wbn57o1OK)CpjM$_ zVzbrdh`z(yM_LPX>3f5a_rDnwh*|42sk5H+8B$C9W8pvKe0$i>3PHR-s<;t2zrk2C~iT#07&1UzIuO+m0e`$NYj4? zlwnKv{-C#be{<0{Aw8^3qTu$*Pv)O_U8X@fvc{=NpEyo&UN*||br{Kap*gq-Nt3_M z&Ty=9aFpv+&t3UM$M5ohoJ&6Wk9hRs(s<6zY`_`{Kp29UoFt6xC(GGjOZrZBAwN|* z5}&nK_qfq=u>op9`nQR_*4VebT&K7q(2JwxJ{KSR@0+m4k-NXx$o(?X^a{m7K8;8G zFITfk=mhB%+jVaZ^fry*1Sm8Z`wZC1yzL>?{)>6IBZ7+Ll?!5hrr=&#^_hr^yEqZtHDNf4u)wKe%{?mXtIv(C{B70iufzTPMCyg_Z{Bv%ke!dN=y)1_7hMtc<})FNUh*KV z$=Hq(0Dj`a|K5~yoHZjbI3{rkQqV}740 z{i?Cek*b-&(i|H01Ckf9P?YB+zVf?SR-%C~l-gBPcUefhbb0=B( zch7ZwRNDK@U9#?({MGRLP*4Q+6@6XWks&sq1;{(pdhFUHM+byl7HJmN%+LGt%nR56 zPe0N8TgiEvYIsY)(tyB*051$op-kIc_4faS|EIaNTzb_H_wOxf57J2=Kzc8S0D!kA_#p&!(l6L z=G#HvFndbFmXT1qXoGWV3BMe&wxy!i*!4T!EaGf80n7w0Q{-B29L|f=lhkww#iGho zJ8G3qmqnSE0yuy~y9n^t?pw)IQch-#|NV%? zbp1i~hlXry#D<8phb52`}Zx9rU#=9W2p;d9?wH{o|u_7*!LTeF3>r-Dj2+TRsm0@ z?*$}Bq(OxuQ8Kp*OzmDKueK^~0P^9BCz# zUkJtx9u7+Wt>V0*-CZ(zQaIiHbRuz-34ffX{`*(En%0B0U*S8-!UyT<`6^8CZ)fxR zT!>Ospi`B%zgz}GNf;;1B2ONPFsWza&A(b#Z$XwA%1h9@t!DS2>-l&mZ)l2oBSx`3Mr(S;X#etPf>o@V%Q7@TqsyhH- z_J-~uPIA#W<`VO+D_@k(&8Ph1xoG%1~;9IJ;>; zbc@7Ro^A14hlP)p>0SEEc8mB;-EV!9VJ7j`@46dY-Q{BTTo7A=9YqkeXp@O zNiwgI;#qCY7yV2bek)p+uV-zH(Sw|X2uz7Vziq@vhVRLDj{kaKIvF0Cq&7Tgt2hv8 zXmIjOTsd}T;`?2BmqJ^Rg9s3Uma-3Pf{p~!C(K=%QZp~GR`=$T%Bg&{e0fmu-}USd z@s?fn3|4y(TKHi4+*StWme^5eq@M`PnZrrY@d#KXznty)fFb{GLBDgINmmT9of=U2 zKp{1HTl}XGmM2y>Wi~8U9e^#^Vo)`K4Ox8bO!#Y=oE+~6Hkun0-Gh|=fvQ!Bz!*!c z<-(8iySk)LuV1+ZBVzQ9ehL3xJi|_Xa2w9qwai+!oTj<{*Oy~lal?FT(NQjkXxb8+ zR+iq4eHtt-ZG4JFi&GGg$_hcMsmSnyMYq?cnmS%QPaVnm)i~=f--?eI`Rp@$u zc@>+{x!K%3I_nni@-9Vs4^`|rRcM9d-h%Ohd#b5jABCHrdO9QSzN2UuMqpE!yjJ4U zvdp^?@1uYV{H`L(sD%lP7kq`OO~UTJ9FeOxCj)B~%d^=w(@*VM-!jIDwcc1qU|#_% z4b_TBn57DuArLQ&gS&kR-}AB}mGI8XPcL7IiFrKc6N{k#srW=Bu5?sI6y%`)9igE9 z3fy{#T;tbX=6g%xCIvjk51;2u)M-1$^AJ$Uq`xiTv>jDBUkq~6q6g9RhzX3`bH5`? z*Sz>%zVTcTX*@G4+ZJ4(VkJy7FsVo;M0Pfh3Bp!T&5gW~>BGteji=+mS!=p~>o0y= zdM0SnB>74=Ar~*?-*TVoJHyrokkt@_4rL@dlU{(i(}|H=(O%xX-n#tK_Hwioj*n*P zvi?39lA`5f(Hhu^cmi^YqA&?-Uv|02l3nSLRqn%?MGo=7Zx zS(e%Y+$>Nx&;_$E7wm~q9M^lW3P-;b|9gA~=jl>c?Aj>KiGiU%QY$}W{>d08(5Fy31ierDpKBk( zgyNSRr1AJ9?#&5uEi>TSObMQ5UYu1c!7q$3{zk#;-U}@z5_^~cz07cgsSqwRg}?O$ zDaP;j+=6ptuGkLB=~F!!q;@KgnmYAqxYN;x8!!kUGX&G+L}1=df8-nHnv+}qL@1Nz zwY)a}dcW)KKIPmJv@-Mf^D82~IG7xuDutYRWhlmaN-Q;N;z_vpzP-?Fc(l^}xU(x$ z+>LwdkN!RI8SN~jg$RKZkl`bQiXK~-{-saq>%@QFN=PubT+zNabc>boMnX3BfJf0 zP>=@VYNVob?2y~&aS}s#se*f#(FsOskF5!D+VGlryJ424-3B)as-uHqAP1D!h~N4R zG#7#(`6}|+RW1DcoIhQg*16lA&}TZ#|5ROx+xUdBVBWXbk07T26SmO^xwQ`?mvDjW zOb)pN4NtzpX*0H)GA+vr&eTJRv-9V zUtS(fR3#xMCr#`@>!9J8Z1x}*8~~`hIrx1oNJA3riw})k=1ASjtX24971!(ep)n_3 zxo^{yHFn<0OaJ|zZ3e&vgtn2y($@_PxX6gSlFWl5Al$x!d+eN8bjhQYB~hNhzp_tV zA`7OPW+AT*;0Gc+`?oW$10&ZQsKTESn{P9BwoY+Uo9v$~c9MNV#)~@53)LqWd8uB4 z98fnQYy?Y(m9CTY#tk+feUsSa@Yzed6~it^x=yNVQaq{`RDllCD@o+wMVb&>0AD zraFJ0dpv`1%$bS*Ep5RWyfc?Nb(7mV6e=Eu;minCL`k#c6P!NK{inI;(;hmy6Lx+d z38%rwO;!)<7`Qfp@9-_5HOruk3_|)4c>qARf3Q6W+ZCvf)0f4rFnN|*;#qsVzD&_> zc~oAMLFyFFPo;O*(iSAOJs=0nc1UN`8dC5Aa+PPQM#ew;>aN5mThXoDQTHJJ*4=)( z)s9NfT)xbJ8Q`A~lVxY`2OJsU;O1CLiaV~jnL28YZznMa$o-G$?h-_OQjZ{ zSo`#J%#gFjc>xa_H9S?Mu5Y!V1)l>3J|ym)29vq=rgy?~Rx7%FMyGZ8<>QxOKQG4J z9(;AD;3ZyIh;+}}f2~W2SB_E=h#r*Je@(=AB#bSJeXZBsN%t$BhSVHhqV||w0BHat&dRERajKbZY=+fc# z`})FHAp5$1Lkf{;d$6{)=PPfhbmH#6vrc}X_k4|Jewmyv{#i!0_l9_X`s@cvu+|VN zLT*;$4rc4`iOiCkyeTZQYRT#Q!c=EGX=I%5;V2sa08 zk2yo$@GJVW)e+WA3Ic|ZD8n3-)Htc!gk{5dh0>}jFK9u6xhcp?{P_c8m^dbH{UvQ& zO8-bT?5F5VwG|!8^Jh+?RjwpB`0M$^dw^BpdPpL6H!lgJfv@sTGd(2W7;tr#`Q}+1 zA1Id8ttm8XL!Nno>sJ@2{b!I<7K75J{cYLk!MuFnk;0D)EWA!6SX-9sT=eVY zTvh_p5B~q2CHfx+d%eexgSHgEkxCrc&idM^Yg2IohGAsOlBNA;l@)_%bLKMY{G}FZ z)<1X;yMmlFq+rkwb)y2)`7Qr)m&ee3G4Pz0YoNw;9IZOOXZJMJMV&v-ZO~o5L8e7X zEGfL#`HlYI9xoE&w~AOPl#okG)&HI!ZL{cfUV0)(pO?fTqAI2|S@@nSQxIBfMNz%~ zm=E^9r0#r7qw&R{i#n%K$y+8%8_~+YRa^_-fxYcF>I2AU*!y6_)^>2 zm5gIZ1SQ92tS=U9)@xj=zW&-<5ag7hOdI_@D0DpdSy_3<3W|SoIXh)Zt9dCu4s*Y? zo%HQ@Ql^4?iX)eFXgVd1lql-O0tSqu9z5*L);R5af4=or8u4`Z3wptr-t~8vlbx9< zyH#E*?4{_SgBqRl+^)uyVwgQ#_Uv@-{`R!nMS*`_``SF6h2@i{*M=ghEM?ZT-{L_K zLC{F`q^J60SN#vHqv7gK8d+c z!A6UJj^>YwIKCXq-x`0Vap&?A&8t(h3m$Vr8%C)PP*Dkv-a(3V1IZ%5qt1EyBqrWL zTEk1iqeFc3ja%5y5 zVfV?@YM^-bMfZsBjZ+ZnR8RqhfPOFD2%kO3xs}{1QEdttUrBqm8gEx7{!!ZmqP3 zJRm5GelCrN%-4{DR5aC|z#i9LF>tXSjl9>?-jZyN*hPz0Vz^nIKK zI<`F(4(lY1aYMbFQlz}(!!;V8H=Iy$?zqwdEJ;{V^ zb@IY=!^|jO-bd8#<7B!CJ^hj42YYx05Hs3}y*X?XxO{2l0i8YPhjW&czDZ(7A7nJJ z#ieVlbLTy!bkwXQlG)36KvM@=t^;8ufdi_`@~C=riHWw$eLG-nx+tCS&5g`A8F@D1 z%${~c$5|o$B&-abpXldR2nCJE^^@gKk0FwB3v0$HTVDARI&5%3DLUG%3ExmghwfJ(i`*CHx>~b)8t_hd?^$W!c|ad*0t_WV z*6C)+@7TfZ+7#rK_92<1qw=26jJEpR5A2u!LKfsSYPa@$ai}Cf@5^okMhyhu_6_y% zym;~6?TD#L{)F0@qU&Tj=L;P+v#4CB42jf14hW@?{R~3}Z^JrqiR%B5H@(LRv2_u_ zQ8Ue<>D5;}og$JbyF<0H>K(HJascFzkW$NU%sQz*XLJ@kXuW^`ii@KelPCTU3yp~L zYpvztaSE5Tbtw)e;7t2 zIA(oxV?Yk_IY@Z3KLi5+jm;M(=k=@``$Y8}*&piren}Ke7S@@S^n7__;&J&J8F>FN z6#>1S!@tl&SKxCdUO3;3Ru@*^yoq}4cjQbM2j7oZb~HmN+u9i=`0LE(Af_U55KM)M zKFBGY-LSDJZqtd}!1EKSdE+a#J?Y{9@d6)N=t;ka1e;2C0Te(S>!5z`Kk|Qp4PMX0 z5|?^{o}7DqHH^hjKjwMr3%wGJ$j1A-yaqI2JcUIMrf7@-jSTX=Y&_dr6tOr?CZoDr zQHqg156ACV&pErh3aClAT%O3Y2RRttiFomaofsn}>u1c}Ycnc&{X!p$*ZqpjtyPgB zJyDmG#`X$2zSrJaAO|!g$T|zFFt_u3rt^ysQhCn{u8!%7MuGyNH>AFc@umiqHN^j8 zM&-flgQ`nmq>;_b9V2(Ej`-PKfz7QaE?XA!Ugz_#3AMz&5jK2uGKW$$Ey!XIRP3em z(fPk*q%0eb;d=hdULn0yW6{2j8D%TV))I@Ow3GQy<*CN38%biBw7}Ry`yoH(Xg9_E;mqb+@BPj`_r4ZBG{Sx!5#@0!QIF##X7D~%PznQ6w z_48?aOcf3!GUD+((F~OZp9{z@fP`~j>8}-FuppmwP*5Q!=rJCH5>X=Z%ZKjdJ~64hAkR?6^6)F@Mhf zI1i=}G6M)C=@>`9Ie4p=@_FM3WZETWBQklFs_(U};D0Bq9*)ZGzZz0mL#_((JxJ$> zBfqaA2P4OHkJC3iZM2hRrt8IpW&+iQx*9B%(Po>r5s#n8wis{iIq%TjiZ}*f(5_A~*`J}I zJ+drtmE+@;z~!gBv2>wqoo>D|iKF^zrywz-tc?2j2hAM=KkK6HLz4;`(e2J!m#v&u z?M9DDF7fE!_F}&(qzXya1owRXy_#dR&7J>(Q9)kB*LBi!QwV-n#2-1r@@ke@@Lj%c zLn3dUSKt(`K_xZFL7O%b16e)nc~Q;iqLrIf3ypP&rX~?btx3O+H4BcDxei$siiDo+ z+aRY3M4ISJ{Gklv6jsq_k_;ao3odwKyQ6%Hz&x|xxlpC>w6p4}^Rl5LV=*NGaF(EV zqkac9EZT3_ka46L4wx&*j)b*J`2|B%gOZBl?#iuj5Dt>y3s(1cM zF8>0I5Rd^t!{(1jr95mh{iheje{N7;?z*fItsg=sBp4~kGF|XCaOT^;eA@{j2e8x9 zaCOkjpZtWmt4{9*Zu%Tg9M8q751q zmV*~B_C7-N8}!1L^)lG#OTUnx7atDgqTi{@;=gNnF1>yaPbh=gL~n8jQt=M!?9K16 zJzth|Em-jJ@C7H~4{y2V-Y8Jk){8cENWcHgH3M?sZ6dMu6zFV4G^o3PN1)SOb*1wV zcIr>17_0z+>I`+QV@gSeEb|KVi3@-WV88-m|5_u^njXHV_j`F{wDfvD{%n(PuzjeW zUFp?U-rFYpm#!IRnY@YzI17yj!oujcv6+r}8xK$hgwJU7lOj`PJqnAl!%E&caBHqQ7l{n|piYbW@y9#x0Sgd|}mT?kRD`$opG5UvwS# zya8XrY%Q?^ZvQsSn=+HvoLy-5%2UG1pgJe=Y$#&s_xY>Cox-%Z{)?BaGPfYKAcpez zC$PUA@U!YauN3pnubI_+th;6X-n;-yKK%(@l)#A3vpeHLZ5=?`3(hxa_-wzl99sZM>lOO%+0jX)AwyHgFT~i)%K#IEr~(ilpjBbOFU&Tk+|qa$ z`UX4Tm4sBNjn9CLBWnA5QG)8{v&X)_dDuV?6~SUKL;%^wHe{AFtg~UH)ktsgs@^fx zCX{dUqIb`8%^xLygD>%%kNrX)#RlFc`1+zq2mL@JMx_l?pC?oseK)13bQJOHejp#SG z&Y60O?e6S$drBN}VboSQIui!hI5F`_#5Bi(RqXoNq^TAET(h{m2B} zvIAU!uo~ihZ1`bl(~6n~!Y+TS9g%Ba-MW0i?Bs2(d!BQJArXdQjL&ovEdZv%(Aa~0 zEc%WKwp3;RsiYY6SInn6%4B@;`E5Qex%?f9(-d|6pPIp7mw}8NskbZ#RJC{9u>CRxyAYxZ z>D(^Sw(!+{O>s^&HChoX1M9JCU_lx)qaVnrN(muh`8Fi81>3@Xe7reb!^t!u$<$x~ zw>9}G`36Z#D0Ri>Q8|>BLAeRob8vAHyb^HO4kpgblAshM*I)md>D+^Q$I7Tl|^5s`y=FjZ@Um}3CWo;h2CTGHnTike9Jo!o$9BD9SywIfwWCQkUAd(lY**`!ca*IBV|;crBM7Rdndo z?K|-Y6(uhZiEu1NI<&X1JPWi+%zJsF zHvKMgdideSwW|Zt*1|kDU#Ocu2^lHdLp)H^v#&M#BQV?PWUpbL*=MKfc5hnVvD?pW zK;Kp3sp>^{%8p^f7rCF};B$Kj5}j3fjnFN@=LBY1+&32%W;zyIpQ3kgch)Qzi;Y>(nCjKSwrBt#J(F=z^7 z6eM+>ncnI1DhiGq_bz{qYZr>sd_hQvaOKkjX#owNJb4IiKx_kP=B_(b?)_Iy8`W$A zy~r|se&q|B-_n!M`FDyqpZoKPv0oy)S&SeDCP4&!tA8HmPKFIaYF~5_eIylXw54q8 z`5~`PY9<=pd_HDi!It}{7T|aQXa_7*;SefCybP?zWTA`Y)yK_l=_~(^xG=wHV?D}! zUQkYYeO#e&7wAb+NmVnkwf-H&ht# zHuG-@cVibf-eoxyefg8XCR{Ek>q}~R1ii)= zy#_X0`>?Dwb}$2Cdt>>~&w9Ea^E@r&=B3_Vwb6H7EzVI8lw02Xy4?Pq)JG>?gWR%o zyc=Tfk_zC=qpf$&A{h}KESwxovEYhX^ZtU-?9Q1t>|XL+G3&9r6n&om=H(RP;>lB4 z22X#ko$AHw=NrvG0MA!@MC51h{mLwSXZj_3yB9SC;!Jc=8SHGI#C4kio8=G2}N(T z{C`j=U>1F_(bedUe$F27mnV5?_i?>yw=!=~e+|v_e1|`WNK)sWAi86x4srmVyKkPX zPJY~Qbdq}*`Z}Iw_N?i0Bq_w)-)G)A9K(C#rJPS|HA^gi!7EdQ53`?p`)3|Vg6rGwbsr&b&!0V?H0<$Haqo+uN0a*1+?4{taodpPJ+j z2nfWVG+C^^?QXA&>YQ8zNDsrvkSfq+WKI+q8>2V&%e>Fr$)chN$L5tyLU3L@8e>6? zq}t7AuXfk1u7Mn!72$KX+*0lSZ8}%Te+gA@_YSze@m^NrjaU}=II5`V zY{rBCU++9yw3kq4nM0pRvEqj#GoSbr{{-$bdcXUFd+x-OxJgPJF)`G?R{8^NW!A*M z;g(a(eWI1nIGXguqxm3_&@IaRpO5NEH;i+SLFf_cOofnj{fNS7E9-RyK@_v-n&P$Z z7A;n6=k$~_<#lN&-H4qY{8j%NNDgu^b{zpBb8#5C$*Wy|SIcQWoqE-8@Q5kq(wr0h zvxhYPj74^jy@DG}A>k?^2GrkZFu#CUceodynMzLuPxWi&m~ zIF8IMkKpU=Wh8;I2gx9{WA23x-qp8GOj*jembfK*r!M%F36#x_=CaV}j{RZ!Ggc+H zKk4Ib47xlRzB7?lRPcxMj{0pyor~WSteH;w&X)CrtH!172IW^D*+>8_3^9MCmd70# z!3%OcY)UGuvRm4{k;OeM3^w?A-TECK+Y+=YI~(U1S)UMt9E58S&XC1aj21oa{>1hz zwvVEwSeDpB$!=?^a|(yliHh=+hN0^+|SO$YG3Gb7J~TX+9%tFw{I zmj^y$W*#l>o(UYwF36sD8~7W$2mX~|?m61b4ew&Ux5#oyu?t%&jk*o1vdCK~{$`XPuqQH5B73=3f;dj{i|86#TfQDZYbgP5=G70zIx%yvy55uS4&4w(L0@(gzi4 zyWyDM7k0V!_XWSTYmt+ZohbLZKamDb7xEPp^M|msYUY5afhmkO^8}{hYv@ljXHBUwPa=J#|@{d_Mg$PT~qLRNIJ%{c%J; zX(rvvr-J4|5&9QHnE0GQn(08aeIj+$tKW0c8Q!70?lnOwN4$SBklr}XcailvJV##g zV7_|YVJ4LIt(|l~C+Bnbgo1n5e)qi-Ws~#iXBMjRd}AqaL;U7`W>Qfc>L^hAF>pBO zDsW6)tL98?E<=;8pq%Bk0^BMbNz2HE&gb(#IVWnGAa(%*(S#AFbUY2SAGdy8(LMQT zo94G9J6(OAT445a%MgE*r{uhm>{;iy?@)1|0PF=w8EH6Djt}2057)7kMthxl^zN@K zskB+M)Tb+-6t6byEqqdlevCZ<`br7t29d6a@4#h)ghwxm$u7P(kkj%?y7=v!h%3RA z=A$%kuM;N(SlxDUkKcI*Xd1|!k*Mk`j9Tq}-$wL)VfO2;@>RrX{E-s33rcO_WPxBBPPzFyAiNrM{ zbLn7PEE>tB&XxAfn|yH!d}MQrKjjQ;5YMpMuM~P1X zcsO~4Y`?RNkcEbU0-qHNOCBFepD6_0v9Rpq+*CbK=%E?~ebTJ`@U&axwlpb@CTM$5fHI9cI&9LWVo#_)=cJem9;WSL)G_r%otU5D`# zQ#;Rv$4yk*BVg@e${Ny2J_yltB=l6P%h$+$`&(tautkF|PgU+{V0OJzZUVPr zP?D3#@%F3Jth!l0^shLDvWzYz#nXu*&6409 z9Z49?uu^?J77y_`O6u-7VvyTsJVT>|ZKU}Kp4TzYzD}f_=WdnuWAssZPs>(c`bVdf zGx%Y8IezK^NqK-0fd2_egy$V5gH&;}UGEi!(HT5ocX64=e*cajc6vNOW#Sjv+2b>L zOuYN(LI?(epsiFd=6gA)bH*_>dBQSf>$(0Zp`l#oSppVqc0{CDnLc)5i)<-Vgh-Lo(d+VNe1vD?z9b{k*DA znCGzx$+|o`=D@qkys&=h=^WOd*8Fq5BD%MmTfdt;xzDs8(v$}ZIrP4aBOJ(ZZz3HH z-T&5!61;ohR^o(}m}z4{%45W=h4uF~Zs9);mRvv!5NSf%kURs>)&tg=`NDze;>Jrq zrVm=Ic~X@R@;ZK}SXhXjc-@T6H$z@(3v$rZ}%c(zb7(G{?_#()NwB9+V>qjpJ4sCG{KL~Qu_K9Z@z;MsQ?8KNJUKg zD(3qs)%hf^YI;PtauTHzc|W~J^SrikxBK1Sz2w(~e-id4K@MWXNO|M@SB%`(&!m@I zZysqoQQZ=~$iNk~Ku*zmT~e&}=d436xmn;5kb}}@wWtzL_gV%8j&nVzz?TM%M|`f}u)twWs`q8GN8-V0S;n_~E7!ceDzAK*XS zWn_`}B?QZm+@dTkz&i)Bl|uBNVllljG!6AxUrD#<<}W32=6o35Fev_J^Y+L5hG@lS zUn@30Yd{MCGLXWK&|J*=tS{2lM8|kGD{irR?y$F>dYWf_t=2n)MLB0TL?mw<(4jI^ zZ6f+%0=UPK_096~;zrJTBu9~I<=8U~FwGm`3NldsQq43oCdPji;R2KhD)dEvSr1T& z+PiX6r&;~_+Ip3|A9elby`Rwfb$L_E+sDqeFs4UvL4TFv0d;j#0vVbCa-Ufrix>-! z5=Rc2tgw~v@bFnE-3alp!Fp>!x7B~zZBOy)E2)I?vw9*z)V2*L;zUgUi-F ze=7g=`QY6Av&X&E(dU7cXVcZy{{GUJboG;j4+rmbJ^%Y7EaI7&K6sBRFv$RohSv{6 z#W_9ys7Xxqeo5ZCY91EM;^=*Rl`c`<(1ra5p>2kMsndSYP~spI9-fahi2W}e?r5{^ zhWZ1w{!BFP_} zbqrt=DeUw95BfDwt3?Nh(s#$I^2KBF2^+$LFU_1}roo*V{=Mv<>Se{IORGP{ez4nH zLN=9ODz!iKby}K)R&<|Y8#}Gm`C^`4TG)4r=8DRnua}(x&xoqQyE%>-~!;XCaEI|wg zEm!gZ;~74g(I8f|rRexEdrpqB*u=u!y=2s)P9bNzY}GV4{9GttBtVXs+DA-&Kuxl) zBhe?kPqJvyYZTwe;*pEhgl|0$V?#f+3Hf*y*g&YX6hdl-y&^CeDLU*ohhjHLU&Few zNLG%9yH0{s_S}2heBOTD_>e4V4v4@g(Qgi6Fb{Fe?IPv#g#t|tcRhMNk{-A*R!tWd zQ&jd*64M71g?YepV3sjbthOD1iO}uxr?()m-Sh-|G7=gxOr% zyk!|qs}MA>qiuUhCgyHUzRd9WGuh-gjHhbY>1MCPν>PP1s0_e2*fv>qoFG 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 From 1f5763f7877a59e933fa729afdfbf26d253b0fe0 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Wed, 15 Mar 2023 03:23:41 +0100 Subject: [PATCH 0534/1212] chore: deprecate the pubsub api Fixes #9717 --- README.md | 3 +-- cmd/ipfs/daemon.go | 2 +- core/commands/pubsub.go | 20 ++++++++++---------- docs/changelogs/v0.19.md | 7 +++++++ docs/config.md | 12 +++++++++++- docs/experimental-features.md | 31 ------------------------------- 6 files changed, 30 insertions(+), 45 deletions(-) diff --git a/README.md b/README.md index e734fef66..94e5e42af 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ Kubo was the first IPFS implementation and is the most widely used one today. Im Featureset - Runs an IPFS-Node as a network service - [Command Line Interface](https://docs.ipfs.tech/reference/kubo/cli/) to IPFS-Nodes -- Local [Web2-to-Web3 HTTP Gateway functionality](https://github.com/ipfs/specs/tree/main/http-gateways#readme) +- Local [Web2-to-Web3 HTTP Gateway functionality](https://github.com/ipfs/specs/tree/main/http-gateways#readme) - HTTP RPC API (`/api/v0`) to access and control the daemon - IPFS's internal Webgui can be used to manage the Kubo nodes @@ -381,7 +381,6 @@ Some places to get you started on the codebase: - libp2p - libp2p: https://github.com/libp2p/go-libp2p - DHT: https://github.com/libp2p/go-libp2p-kad-dht - - PubSub: https://github.com/libp2p/go-libp2p-pubsub - [IPFS : The `Add` command demystified](https://github.com/ipfs/kubo/tree/master/docs/add-code-flow.md) ### Map of Implemented Subsystems diff --git a/cmd/ipfs/daemon.go b/cmd/ipfs/daemon.go index 880d26b0e..52addcc07 100644 --- a/cmd/ipfs/daemon.go +++ b/cmd/ipfs/daemon.go @@ -171,7 +171,7 @@ Headers. cmds.BoolOption(enableGCKwd, "Enable automatic periodic repo garbage collection"), cmds.BoolOption(adjustFDLimitKwd, "Check and raise file descriptor limits if needed").WithDefault(true), cmds.BoolOption(migrateKwd, "If true, assume yes at the migrate prompt. If false, assume no."), - cmds.BoolOption(enablePubSubKwd, "Enable experimental pubsub feature. Overrides Pubsub.Enabled config."), + cmds.BoolOption(enablePubSubKwd, "DEPRECATED"), cmds.BoolOption(enableIPNSPubSubKwd, "Enable IPNS over pubsub. Implicitly enables pubsub, overrides Ipns.UsePubsub config."), cmds.BoolOption(enableMultiplexKwd, "DEPRECATED"), cmds.StringOption(agentVersionSuffix, "Optional suffix to the AgentVersion presented by `ipfs id` and also advertised through BitSwap."), diff --git a/core/commands/pubsub.go b/core/commands/pubsub.go index ef8afcb44..ee795e078 100644 --- a/core/commands/pubsub.go +++ b/core/commands/pubsub.go @@ -16,14 +16,14 @@ import ( ) var PubsubCmd = &cmds.Command{ - Status: cmds.Experimental, + Status: cmds.Deprecated, Helptext: cmds.HelpText{ Tagline: "An experimental publish-subscribe system on ipfs.", ShortDescription: ` ipfs pubsub allows you to publish messages to a given topic, and also to subscribe to new messages on a given topic. -EXPERIMENTAL FEATURE +DEPRECATED FEATURE (see https://github.com/ipfs/kubo/issues/9717) It is not intended in its current state to be used in a production environment. To use, the daemon must be run with @@ -46,13 +46,13 @@ type pubsubMessage struct { } var PubsubSubCmd = &cmds.Command{ - Status: cmds.Experimental, + Status: cmds.Deprecated, Helptext: cmds.HelpText{ Tagline: "Subscribe to messages on a given topic.", ShortDescription: ` ipfs pubsub sub subscribes to messages on a given topic. -EXPERIMENTAL FEATURE +DEPRECATED FEATURE (see https://github.com/ipfs/kubo/issues/9717) It is not intended in its current state to be used in a production environment. To use, the daemon must be run with @@ -145,14 +145,14 @@ TOPIC AND DATA ENCODING } var PubsubPubCmd = &cmds.Command{ - Status: cmds.Experimental, + Status: cmds.Deprecated, Helptext: cmds.HelpText{ Tagline: "Publish data to a given pubsub topic.", ShortDescription: ` ipfs pubsub pub publishes a message to a specified topic. It reads binary data from stdin or a file. -EXPERIMENTAL FEATURE +DEPRECATED FEATURE (see https://github.com/ipfs/kubo/issues/9717) It is not intended in its current state to be used in a production environment. To use, the daemon must be run with @@ -201,13 +201,13 @@ HTTP RPC ENCODING } var PubsubLsCmd = &cmds.Command{ - Status: cmds.Experimental, + Status: cmds.Deprecated, Helptext: cmds.HelpText{ Tagline: "List subscribed topics by name.", ShortDescription: ` ipfs pubsub ls lists out the names of topics you are currently subscribed to. -EXPERIMENTAL FEATURE +DEPRECATED FEATURE (see https://github.com/ipfs/kubo/issues/9717) It is not intended in its current state to be used in a production environment. To use, the daemon must be run with @@ -273,7 +273,7 @@ func safeTextListEncoder(req *cmds.Request, w io.Writer, list *stringList) error } var PubsubPeersCmd = &cmds.Command{ - Status: cmds.Experimental, + Status: cmds.Deprecated, Helptext: cmds.HelpText{ Tagline: "List peers we are currently pubsubbing with.", ShortDescription: ` @@ -281,7 +281,7 @@ ipfs pubsub peers with no arguments lists out the pubsub peers you are currently connected to. If given a topic, it will list connected peers who are subscribed to the named topic. -EXPERIMENTAL FEATURE +DEPRECATED FEATURE (see https://github.com/ipfs/kubo/issues/9717) It is not intended in its current state to be used in a production environment. To use, the daemon must be run with diff --git a/docs/changelogs/v0.19.md b/docs/changelogs/v0.19.md index fede7a454..12331cae7 100644 --- a/docs/changelogs/v0.19.md +++ b/docs/changelogs/v0.19.md @@ -8,6 +8,7 @@ - [🔦 Highlights](#-highlights) - [Improving the libp2p resource management integration](#improving-the-libp2p-resource-management-integration) - [Addition of "autoclient" router type](#addition-of-autoclient-router-type) + - [Deprecation of the `ipfs pubsub` commands and matching HTTP endpoints](#deprecation-of-the-ipfs-pubsub-commands-and-matching-http-endpoints) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -28,6 +29,12 @@ A new routing type "autoclient" has been added. This mode is similar to "auto", See the [Routing.Type documentation](https://github.com/ipfs/kubo/blob/master/docs/config.md#routingtype) for more information. +#### Deprecation of the `ipfs pubsub` commands and matching HTTP endpoints + +We are deprecating `ipfs pubsub` and all `/api/v0/pubsub/` RPC endpoints and will remove them in the next release. + +For more information and rational see [#9717](https://github.com/ipfs/kubo/issues/9717). + ### 📝 Changelog ### 👨‍👩‍👧‍👦 Contributors diff --git a/docs/config.md b/docs/config.md index 686661918..2e9fff512 100644 --- a/docs/config.md +++ b/docs/config.md @@ -1165,13 +1165,15 @@ Type: `duration` ## `Pubsub` +**DEPRECATED**: See [#9717](https://github.com/ipfs/kubo/issues/9717) + Pubsub configures the `ipfs pubsub` subsystem. To use, it must be enabled by passing the `--enable-pubsub-experiment` flag to the daemon or via the `Pubsub.Enabled` flag below. ### `Pubsub.Enabled` -**EXPERIMENTAL:** read about current limitations at [experimental-features.md#ipfs-pubsub](./experimental-features.md#ipfs-pubsub). +**DEPRECATED**: See [#9717](https://github.com/ipfs/kubo/issues/9717) Enables the pubsub system. @@ -1181,6 +1183,8 @@ Type: `flag` ### `Pubsub.Router` +**DEPRECATED**: See [#9717](https://github.com/ipfs/kubo/issues/9717) + Sets the default router used by pubsub to route messages to peers. This can be one of: * `"floodsub"` - floodsub is a basic router that simply _floods_ messages to all @@ -1196,6 +1200,8 @@ Type: `string` (one of `"floodsub"`, `"gossipsub"`, or `""` (apply default)) ### `Pubsub.DisableSigning` +**DEPRECATED**: See [#9717](https://github.com/ipfs/kubo/issues/9717) + Disables message signing and signature verification. Enable this option if you're operating in a completely trusted network. @@ -1209,6 +1215,8 @@ Type: `bool` ### `Pubsub.SeenMessagesTTL` +**DEPRECATED**: See [#9717](https://github.com/ipfs/kubo/issues/9717) + Controls the time window within which duplicate messages, identified by Message ID, will be identified and won't be emitted again. @@ -1228,6 +1236,8 @@ Type: `optionalDuration` ### `Pubsub.SeenMessagesStrategy` +**DEPRECATED**: See [#9717](https://github.com/ipfs/kubo/issues/9717) + Determines how the time-to-live (TTL) countdown for deduplicating Pubsub messages is calculated. diff --git a/docs/experimental-features.md b/docs/experimental-features.md index 41e72f1df..296f6ca1e 100644 --- a/docs/experimental-features.md +++ b/docs/experimental-features.md @@ -12,7 +12,6 @@ When you add a new experimental feature to kubo or change an experimental feature, you MUST please make a PR updating this document, and link the PR in the above issue. -- [ipfs pubsub](#ipfs-pubsub) - [Raw leaves for unixfs files](#raw-leaves-for-unixfs-files) - [ipfs filestore](#ipfs-filestore) - [ipfs urlstore](#ipfs-urlstore) @@ -31,36 +30,6 @@ the above issue. --- -## ipfs pubsub - -### State - -Candidate, disabled by default but will be enabled by default in 0.6.0. - -### In Version - -0.4.5 (`--enable-pubsub-experiment`) -0.11.0 (`Pubsub.Enabled` flag in config) - -### How to enable - -Run your daemon with the `--enable-pubsub-experiment` flag -or modify your ipfs config and restart the daemon: -``` -ipfs config --json Pubsub.Enabled true -``` - -Then use the `ipfs pubsub` commands. - -NOTE: `--enable-pubsub-experiment` CLI flag overrides `Pubsub.Enabled` config. - -Configuration documentation can be found in [kubo/docs/config.md](./config.md#pubsub) - -### Road to being a real feature - -- [ ] Needs to not impact peers who don't use pubsub: - https://github.com/libp2p/go-libp2p-pubsub/issues/332 - ## Raw Leaves for unixfs files Allows files to be added with no formatting in the leaf nodes of the graph. From 684d9dc79fce8d899ea1c5b97a7400526fc1d28f Mon Sep 17 00:00:00 2001 From: Gus Eggert Date: Wed, 15 Mar 2023 14:57:23 -0400 Subject: [PATCH 0535/1212] test: fix flaky rcmgr test --- test/cli/rcmgr_test.go | 6 +++++- test/cli/testutils/asserts.go | 15 +++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 test/cli/testutils/asserts.go diff --git a/test/cli/rcmgr_test.go b/test/cli/rcmgr_test.go index 51b2b0452..9d76a7dd8 100644 --- a/test/cli/rcmgr_test.go +++ b/test/cli/rcmgr_test.go @@ -7,6 +7,7 @@ import ( "github.com/ipfs/kubo/config" "github.com/ipfs/kubo/core/node/libp2p" "github.com/ipfs/kubo/test/cli/harness" + "github.com/ipfs/kubo/test/cli/testutils" "github.com/libp2p/go-libp2p/core/peer" "github.com/libp2p/go-libp2p/core/protocol" rcmgr "github.com/libp2p/go-libp2p/p2p/host/resource-manager" @@ -209,7 +210,10 @@ func TestRcmgr(t *testing.T) { Args: []string{"swarm", "connect", node1.SwarmAddrsWithPeerIDs()[0].String()}, }) assert.Equal(t, 1, res.ExitCode()) - assert.Contains(t, res.Stderr.String(), "failed to find any peer in table") + testutils.AssertStringContainsOneOf(t, res.Stderr.String(), + "failed to find any peer in table", + "resource limit exceeded", + ) res = node0.RunIPFS("ping", "-n2", peerID1) assert.Equal(t, 1, res.ExitCode()) diff --git a/test/cli/testutils/asserts.go b/test/cli/testutils/asserts.go new file mode 100644 index 000000000..cf840c20e --- /dev/null +++ b/test/cli/testutils/asserts.go @@ -0,0 +1,15 @@ +package testutils + +import ( + "strings" + "testing" +) + +func AssertStringContainsOneOf(t *testing.T, str string, ss ...string) { + for _, s := range ss { + if strings.Contains(str, s) { + return + } + } + t.Errorf("%q does not contain one of %v", str, ss) +} From e870dcdc0ec59a8514a0949ce2a8e08eda46667d Mon Sep 17 00:00:00 2001 From: Jorropo Date: Wed, 15 Mar 2023 04:40:16 +0100 Subject: [PATCH 0536/1212] fix: preserve Unlimited StreamsInbound in connmgr reconciliation Fixes #9695 --- core/node/libp2p/rcmgr.go | 4 ++++ core/node/libp2p/rcmgr_defaults.go | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/core/node/libp2p/rcmgr.go b/core/node/libp2p/rcmgr.go index 54bff2852..3e1624531 100644 --- a/core/node/libp2p/rcmgr.go +++ b/core/node/libp2p/rcmgr.go @@ -459,6 +459,7 @@ func ensureConnMgrMakeSenseVsResourceMgr(concreteLimits rcmgr.ConcreteLimitConfi return fmt.Errorf(` Unable to initialize libp2p due to conflicting resource manager limit configuration. resource manager System.Conns (%d) must be bigger than ConnMgr.HighWater (%d) +See: https://github.com/ipfs/kubo/blob/master/docs/libp2p-resource-management.md#how-does-the-resource-manager-resourcemgr-relate-to-the-connection-manager-connmgr `, rcm.System.Conns, highWater) } if rcm.System.ConnsInbound != rcmgr.Unlimited && int64(rcm.System.ConnsInbound) <= highWater { @@ -466,6 +467,7 @@ resource manager System.Conns (%d) must be bigger than ConnMgr.HighWater (%d) return fmt.Errorf(` Unable to initialize libp2p due to conflicting resource manager limit configuration. resource manager System.ConnsInbound (%d) must be bigger than ConnMgr.HighWater (%d) +See: https://github.com/ipfs/kubo/blob/master/docs/libp2p-resource-management.md#how-does-the-resource-manager-resourcemgr-relate-to-the-connection-manager-connmgr `, rcm.System.ConnsInbound, highWater) } if rcm.System.Streams != rcmgr.Unlimited && int64(rcm.System.Streams) <= highWater { @@ -473,6 +475,7 @@ resource manager System.ConnsInbound (%d) must be bigger than ConnMgr.HighWater return fmt.Errorf(` Unable to initialize libp2p due to conflicting resource manager limit configuration. resource manager System.Streams (%d) must be bigger than ConnMgr.HighWater (%d) +See: https://github.com/ipfs/kubo/blob/master/docs/libp2p-resource-management.md#how-does-the-resource-manager-resourcemgr-relate-to-the-connection-manager-connmgr `, rcm.System.Streams, highWater) } if rcm.System.StreamsInbound != rcmgr.Unlimited && int64(rcm.System.StreamsInbound) <= highWater { @@ -480,6 +483,7 @@ resource manager System.Streams (%d) must be bigger than ConnMgr.HighWater (%d) return fmt.Errorf(` Unable to initialize libp2p due to conflicting resource manager limit configuration. resource manager System.StreamsInbound (%d) must be bigger than ConnMgr.HighWater (%d) +See: https://github.com/ipfs/kubo/blob/master/docs/libp2p-resource-management.md#how-does-the-resource-manager-resourcemgr-relate-to-the-connection-manager-connmgr `, rcm.System.StreamsInbound, highWater) } return nil diff --git a/core/node/libp2p/rcmgr_defaults.go b/core/node/libp2p/rcmgr_defaults.go index 5faaf7979..4f02c6b4a 100644 --- a/core/node/libp2p/rcmgr_defaults.go +++ b/core/node/libp2p/rcmgr_defaults.go @@ -129,7 +129,9 @@ func createDefaultLimitConfig(cfg config.SwarmConfig) (limitConfig rcmgr.Concret } // Scale System.StreamsInbound as well, but use the existing ratio of StreamsInbound to ConnsInbound - partialLimits.System.StreamsInbound = rcmgr.LimitVal(maxInboundConns * int64(partialLimits.System.StreamsInbound) / int64(partialLimits.System.ConnsInbound)) + if partialLimits.System.StreamsInbound != rcmgr.Unlimited { + partialLimits.System.StreamsInbound = rcmgr.LimitVal(maxInboundConns * int64(partialLimits.System.StreamsInbound) / int64(partialLimits.System.ConnsInbound)) + } partialLimits.System.ConnsInbound = rcmgr.LimitVal(maxInboundConns) } From 8b05cf05b05f6362756027e266294032b431411a Mon Sep 17 00:00:00 2001 From: Jorropo Date: Wed, 15 Mar 2023 17:36:08 +0100 Subject: [PATCH 0537/1212] test: add test for presarvation of unlimited configs for inbound systems --- test/cli/rcmgr_test.go | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/test/cli/rcmgr_test.go b/test/cli/rcmgr_test.go index 9d76a7dd8..3dbceb5d7 100644 --- a/test/cli/rcmgr_test.go +++ b/test/cli/rcmgr_test.go @@ -127,6 +127,22 @@ func TestRcmgr(t *testing.T) { }) }) + t.Run("smoke test unlimited System inbounds", func(t *testing.T) { + t.Parallel() + node := harness.NewT(t).NewNode().Init() + node.UpdateUserSuppliedResourceManagerOverrides(func(overrides *rcmgr.PartialLimitConfig) { + overrides.System.StreamsInbound = rcmgr.Unlimited + overrides.System.ConnsInbound = rcmgr.Unlimited + }) + node.StartDaemon() + + res := node.RunIPFS("swarm", "resources", "--enc=json") + limits := unmarshalLimits(t, res.Stdout.Bytes()) + + assert.Equal(t, rcmgr.Unlimited, limits.System.ConnsInbound) + assert.Equal(t, rcmgr.Unlimited, limits.System.StreamsInbound) + }) + t.Run("smoke test transient scope", func(t *testing.T) { t.Parallel() node := harness.NewT(t).NewNode().Init() From a3b417779ca59f6329ae0d713b901537033a0c0a Mon Sep 17 00:00:00 2001 From: Jorropo Date: Wed, 15 Mar 2023 17:40:12 +0100 Subject: [PATCH 0538/1212] fix: future proof with > rcmgr.DefaultLimit for new enum rcmgr values --- core/node/libp2p/rcmgr.go | 8 ++++---- core/node/libp2p/rcmgr_defaults.go | 4 ++-- test/cli/rcmgr_test.go | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/core/node/libp2p/rcmgr.go b/core/node/libp2p/rcmgr.go index 3e1624531..c61f8dcfe 100644 --- a/core/node/libp2p/rcmgr.go +++ b/core/node/libp2p/rcmgr.go @@ -454,7 +454,7 @@ func ensureConnMgrMakeSenseVsResourceMgr(concreteLimits rcmgr.ConcreteLimitConfi rcm := concreteLimits.ToPartialLimitConfig() highWater := cfg.ConnMgr.HighWater.WithDefault(config.DefaultConnMgrHighWater) - if rcm.System.Conns != rcmgr.Unlimited && int64(rcm.System.Conns) <= highWater { + if (rcm.System.Conns > rcmgr.DefaultLimit || rcm.System.Conns == rcmgr.BlockAllLimit) && int64(rcm.System.Conns) <= highWater { // nolint return fmt.Errorf(` Unable to initialize libp2p due to conflicting resource manager limit configuration. @@ -462,7 +462,7 @@ resource manager System.Conns (%d) must be bigger than ConnMgr.HighWater (%d) See: https://github.com/ipfs/kubo/blob/master/docs/libp2p-resource-management.md#how-does-the-resource-manager-resourcemgr-relate-to-the-connection-manager-connmgr `, rcm.System.Conns, highWater) } - if rcm.System.ConnsInbound != rcmgr.Unlimited && int64(rcm.System.ConnsInbound) <= highWater { + if (rcm.System.ConnsInbound > rcmgr.DefaultLimit || rcm.System.ConnsInbound == rcmgr.BlockAllLimit) && int64(rcm.System.ConnsInbound) <= highWater { // nolint return fmt.Errorf(` Unable to initialize libp2p due to conflicting resource manager limit configuration. @@ -470,7 +470,7 @@ resource manager System.ConnsInbound (%d) must be bigger than ConnMgr.HighWater See: https://github.com/ipfs/kubo/blob/master/docs/libp2p-resource-management.md#how-does-the-resource-manager-resourcemgr-relate-to-the-connection-manager-connmgr `, rcm.System.ConnsInbound, highWater) } - if rcm.System.Streams != rcmgr.Unlimited && int64(rcm.System.Streams) <= highWater { + if rcm.System.Streams > rcmgr.DefaultLimit || rcm.System.Streams == rcmgr.BlockAllLimit && int64(rcm.System.Streams) <= highWater { // nolint return fmt.Errorf(` Unable to initialize libp2p due to conflicting resource manager limit configuration. @@ -478,7 +478,7 @@ resource manager System.Streams (%d) must be bigger than ConnMgr.HighWater (%d) See: https://github.com/ipfs/kubo/blob/master/docs/libp2p-resource-management.md#how-does-the-resource-manager-resourcemgr-relate-to-the-connection-manager-connmgr `, rcm.System.Streams, highWater) } - if rcm.System.StreamsInbound != rcmgr.Unlimited && int64(rcm.System.StreamsInbound) <= highWater { + if (rcm.System.StreamsInbound > rcmgr.DefaultLimit || rcm.System.StreamsInbound == rcmgr.BlockAllLimit) && int64(rcm.System.StreamsInbound) <= highWater { // nolint return fmt.Errorf(` Unable to initialize libp2p due to conflicting resource manager limit configuration. diff --git a/core/node/libp2p/rcmgr_defaults.go b/core/node/libp2p/rcmgr_defaults.go index 4f02c6b4a..7a0e5a282 100644 --- a/core/node/libp2p/rcmgr_defaults.go +++ b/core/node/libp2p/rcmgr_defaults.go @@ -118,7 +118,7 @@ func createDefaultLimitConfig(cfg config.SwarmConfig) (limitConfig rcmgr.Concret // There are ways to break this, but this should catch most problems already. // We might improve this in the future. // See: https://github.com/ipfs/kubo/issues/9545 - if partialLimits.System.ConnsInbound != rcmgr.Unlimited && cfg.ConnMgr.Type.WithDefault(config.DefaultConnMgrType) != "none" { + if partialLimits.System.ConnsInbound > rcmgr.DefaultLimit && cfg.ConnMgr.Type.WithDefault(config.DefaultConnMgrType) != "none" { maxInboundConns := int64(partialLimits.System.ConnsInbound) if connmgrHighWaterTimesTwo := cfg.ConnMgr.HighWater.WithDefault(config.DefaultConnMgrHighWater) * 2; maxInboundConns < connmgrHighWaterTimesTwo { maxInboundConns = connmgrHighWaterTimesTwo @@ -129,7 +129,7 @@ func createDefaultLimitConfig(cfg config.SwarmConfig) (limitConfig rcmgr.Concret } // Scale System.StreamsInbound as well, but use the existing ratio of StreamsInbound to ConnsInbound - if partialLimits.System.StreamsInbound != rcmgr.Unlimited { + if partialLimits.System.StreamsInbound > rcmgr.DefaultLimit { partialLimits.System.StreamsInbound = rcmgr.LimitVal(maxInboundConns * int64(partialLimits.System.StreamsInbound) / int64(partialLimits.System.ConnsInbound)) } partialLimits.System.ConnsInbound = rcmgr.LimitVal(maxInboundConns) diff --git a/test/cli/rcmgr_test.go b/test/cli/rcmgr_test.go index 3dbceb5d7..50ea26979 100644 --- a/test/cli/rcmgr_test.go +++ b/test/cli/rcmgr_test.go @@ -81,10 +81,10 @@ func TestRcmgr(t *testing.T) { require.Equal(t, 0, res.ExitCode()) limits := unmarshalLimits(t, res.Stdout.Bytes()) - if limits.System.ConnsInbound != rcmgr.Unlimited { + if limits.System.ConnsInbound > rcmgr.DefaultLimit { assert.GreaterOrEqual(t, limits.System.ConnsInbound, 800) } - if limits.System.StreamsInbound != rcmgr.Unlimited { + if limits.System.StreamsInbound > rcmgr.DefaultLimit { assert.GreaterOrEqual(t, limits.System.StreamsInbound, 800) } }) From 51eabd46dac6f004cc0301273a2ca6140ecbf7e5 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Thu, 16 Mar 2023 17:21:35 +0100 Subject: [PATCH 0539/1212] chore: bump go-libipfs@v0.6.2 --- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 1c19dd3eb..d96fa795d 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.18 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/go-libipfs v0.6.1 + github.com/ipfs/go-libipfs v0.6.2 github.com/ipfs/interface-go-ipfs-core v0.11.0 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.26.2 diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index c927b58d9..3a08f464a 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -569,8 +569,8 @@ github.com/ipfs/go-ipld-legacy v0.1.1 h1:BvD8PEuqwBHLTKqlGFTHSwrwFOMkVESEvwIYwR2 github.com/ipfs/go-ipld-legacy v0.1.1/go.mod h1:8AyKFCjgRPsQFf15ZQgDB8Din4DML/fOmKZkkFkrIEg= github.com/ipfs/go-ipns v0.3.0 h1:ai791nTgVo+zTuq2bLvEGmWP1M0A6kGTXUsgv/Yq67A= github.com/ipfs/go-ipns v0.3.0/go.mod h1:3cLT2rbvgPZGkHJoPO1YMJeh6LtkxopCkKFcio/wE24= -github.com/ipfs/go-libipfs v0.6.1 h1:OSO9cm1H3r4OXfP0MP1Q5UhTnhd2fByGl6CVYyz/Rhk= -github.com/ipfs/go-libipfs v0.6.1/go.mod h1:FmhKgxMOQA572TK5DA3MZ5GL44ZqsMHIrkgK4gLn4A8= +github.com/ipfs/go-libipfs v0.6.2 h1:QUf3kS3RrCjgtE0QW2d18PFFfOLeEt24Ft892ipLzRI= +github.com/ipfs/go-libipfs v0.6.2/go.mod h1:FmhKgxMOQA572TK5DA3MZ5GL44ZqsMHIrkgK4gLn4A8= github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= github.com/ipfs/go-log v1.0.2/go.mod h1:1MNjMxe0u6xvJZgeqbJ8vdo2TKaGwZ1a0Bpza+sr2Sk= github.com/ipfs/go-log v1.0.3/go.mod h1:OsLySYkwIbiSUR/yBTdv1qPtcE4FW3WPWk/ewz9Ru+A= diff --git a/go.mod b/go.mod index 673dd3793..4fce33b56 100644 --- a/go.mod +++ b/go.mod @@ -45,7 +45,7 @@ require ( github.com/ipfs/go-ipld-git v0.1.1 github.com/ipfs/go-ipld-legacy v0.1.1 github.com/ipfs/go-ipns v0.3.0 - github.com/ipfs/go-libipfs v0.6.1 + github.com/ipfs/go-libipfs v0.6.2 github.com/ipfs/go-log v1.0.5 github.com/ipfs/go-log/v2 v2.5.1 github.com/ipfs/go-merkledag v0.9.0 diff --git a/go.sum b/go.sum index 16329d6ad..100875344 100644 --- a/go.sum +++ b/go.sum @@ -591,8 +591,8 @@ github.com/ipfs/go-ipld-legacy v0.1.1 h1:BvD8PEuqwBHLTKqlGFTHSwrwFOMkVESEvwIYwR2 github.com/ipfs/go-ipld-legacy v0.1.1/go.mod h1:8AyKFCjgRPsQFf15ZQgDB8Din4DML/fOmKZkkFkrIEg= github.com/ipfs/go-ipns v0.3.0 h1:ai791nTgVo+zTuq2bLvEGmWP1M0A6kGTXUsgv/Yq67A= github.com/ipfs/go-ipns v0.3.0/go.mod h1:3cLT2rbvgPZGkHJoPO1YMJeh6LtkxopCkKFcio/wE24= -github.com/ipfs/go-libipfs v0.6.1 h1:OSO9cm1H3r4OXfP0MP1Q5UhTnhd2fByGl6CVYyz/Rhk= -github.com/ipfs/go-libipfs v0.6.1/go.mod h1:FmhKgxMOQA572TK5DA3MZ5GL44ZqsMHIrkgK4gLn4A8= +github.com/ipfs/go-libipfs v0.6.2 h1:QUf3kS3RrCjgtE0QW2d18PFFfOLeEt24Ft892ipLzRI= +github.com/ipfs/go-libipfs v0.6.2/go.mod h1:FmhKgxMOQA572TK5DA3MZ5GL44ZqsMHIrkgK4gLn4A8= github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= github.com/ipfs/go-log v1.0.2/go.mod h1:1MNjMxe0u6xvJZgeqbJ8vdo2TKaGwZ1a0Bpza+sr2Sk= github.com/ipfs/go-log v1.0.3/go.mod h1:OsLySYkwIbiSUR/yBTdv1qPtcE4FW3WPWk/ewz9Ru+A= From 23b5abfb7abcf5775640e72df327fc25f06482ac Mon Sep 17 00:00:00 2001 From: Gus Eggert Date: Thu, 16 Mar 2023 08:41:50 -0400 Subject: [PATCH 0540/1212] feat: add heap allocs to 'ipfs diag profile' --- core/commands/profile.go | 4 +++- profile/profile.go | 10 ++++++++++ profile/profile_test.go | 6 ++++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/core/commands/profile.go b/core/commands/profile.go index 3875cfdcb..d25711dac 100644 --- a/core/commands/profile.go +++ b/core/commands/profile.go @@ -49,7 +49,8 @@ The output file includes: - A list of running goroutines. - A CPU profile. -- A heap profile. +- A heap inuse profile. +- A heap allocation profile. - A mutex profile. - A block profile. - Your copy of go-ipfs. @@ -79,6 +80,7 @@ However, it could reveal: profile.CollectorGoroutinesPprof, profile.CollectorVersion, profile.CollectorHeap, + profile.CollectorAllocs, profile.CollectorBin, profile.CollectorCPU, profile.CollectorMutex, diff --git a/profile/profile.go b/profile/profile.go index d15d51251..b9ad86d2f 100644 --- a/profile/profile.go +++ b/profile/profile.go @@ -22,6 +22,7 @@ const ( CollectorGoroutinesPprof = "goroutines-pprof" CollectorVersion = "version" CollectorHeap = "heap" + CollectorAllocs = "allocs" CollectorBin = "bin" CollectorCPU = "cpu" CollectorMutex = "mutex" @@ -71,6 +72,11 @@ var collectors = map[string]collector{ collectFunc: heapProfile, enabledFunc: func(opts Options) bool { return true }, }, + CollectorAllocs: { + outputFile: "allocs.pprof", + collectFunc: allocsProfile, + enabledFunc: func(opts Options) bool { return true }, + }, CollectorBin: { outputFile: "ipfs", isExecutable: true, @@ -197,6 +203,10 @@ func heapProfile(ctx context.Context, _ Options, w io.Writer) error { return pprof.Lookup("heap").WriteTo(w, 0) } +func allocsProfile(ctx context.Context, _ Options, w io.Writer) error { + return pprof.Lookup("allocs").WriteTo(w, 0) +} + func versionInfo(ctx context.Context, _ Options, w io.Writer) error { return json.NewEncoder(w).Encode(version.GetVersionInfo()) } diff --git a/profile/profile_test.go b/profile/profile_test.go index 8da00d018..a2fe0b51d 100644 --- a/profile/profile_test.go +++ b/profile/profile_test.go @@ -17,6 +17,7 @@ func TestProfiler(t *testing.T) { CollectorGoroutinesPprof, CollectorVersion, CollectorHeap, + CollectorAllocs, CollectorBin, CollectorCPU, CollectorMutex, @@ -43,6 +44,7 @@ func TestProfiler(t *testing.T) { "goroutines.pprof", "version.json", "heap.pprof", + "allocs.pprof", "ipfs", "cpu.pprof", "mutex.pprof", @@ -63,6 +65,7 @@ func TestProfiler(t *testing.T) { "goroutines.pprof", "version.json", "heap.pprof", + "allocs.pprof", "ipfs.exe", "cpu.pprof", "mutex.pprof", @@ -81,6 +84,7 @@ func TestProfiler(t *testing.T) { "goroutines.pprof", "version.json", "heap.pprof", + "allocs.pprof", "ipfs", }, }, @@ -96,6 +100,7 @@ func TestProfiler(t *testing.T) { "goroutines.pprof", "version.json", "heap.pprof", + "allocs.pprof", "ipfs", "cpu.pprof", "block.pprof", @@ -114,6 +119,7 @@ func TestProfiler(t *testing.T) { "goroutines.pprof", "version.json", "heap.pprof", + "allocs.pprof", "ipfs", "cpu.pprof", "mutex.pprof", From 63b2a0e069e4e37b0c1c36a73a3d62b452b2c7a5 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Fri, 17 Mar 2023 15:14:10 +0100 Subject: [PATCH 0541/1212] fix: apply API.HTTPHeaders to /webui redirect --- core/corehttp/redirect.go | 15 +++++++++++++-- test/cli/gateway_test.go | 17 +++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/core/corehttp/redirect.go b/core/corehttp/redirect.go index bcd536d23..4b98963e2 100644 --- a/core/corehttp/redirect.go +++ b/core/corehttp/redirect.go @@ -8,8 +8,14 @@ import ( ) func RedirectOption(path string, redirect string) ServeOption { - handler := &redirectHandler{redirect} return func(n *core.IpfsNode, _ net.Listener, mux *http.ServeMux) (*http.ServeMux, error) { + cfg, err := n.Repo.Config() + if err != nil { + return nil, err + } + + handler := &redirectHandler{redirect, cfg.API.HTTPHeaders} + if len(path) > 0 { mux.Handle("/"+path+"/", handler) } else { @@ -20,9 +26,14 @@ func RedirectOption(path string, redirect string) ServeOption { } type redirectHandler struct { - path string + path string + headers map[string][]string } func (i *redirectHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + for k, v := range i.headers { + w.Header()[k] = v + } + http.Redirect(w, r, i.path, http.StatusFound) } diff --git a/test/cli/gateway_test.go b/test/cli/gateway_test.go index a585925a7..d2a90b04a 100644 --- a/test/cli/gateway_test.go +++ b/test/cli/gateway_test.go @@ -219,6 +219,23 @@ func TestGateway(t *testing.T) { assert.Contains(t, []int{302, 301}, resp.StatusCode) }) + t.Run("GET /webui/ returns user-specified headers", func(t *testing.T) { + t.Parallel() + + header := "Access-Control-Allow-Origin" + values := []string{"http://localhost:3000", "https://webui.ipfs.io"} + + node := harness.NewT(t).NewNode().Init() + node.UpdateConfig(func(cfg *config.Config) { + cfg.API.HTTPHeaders = map[string][]string{header: values} + }) + node.StartDaemon() + + resp := node.APIClient().DisableRedirects().Get("/webui/") + assert.Equal(t, resp.Headers.Values(header), values) + assert.Contains(t, []int{302, 301}, resp.StatusCode) + }) + t.Run("GET /logs returns logs", func(t *testing.T) { t.Parallel() apiClient := node.APIClient() From ed671e84891232c99165c4759b046ce303a30b49 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Fri, 17 Mar 2023 15:29:39 +0100 Subject: [PATCH 0542/1212] fix: canonicalize user defined headers --- core/corehttp/gateway_writable.go | 2 +- core/corehttp/redirect.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/corehttp/gateway_writable.go b/core/corehttp/gateway_writable.go index 89a2973ac..34cd8438e 100644 --- a/core/corehttp/gateway_writable.go +++ b/core/corehttp/gateway_writable.go @@ -30,7 +30,7 @@ type writableGatewayHandler struct { func (i *writableGatewayHandler) addUserHeaders(w http.ResponseWriter) { for k, v := range i.config.Headers { - w.Header()[k] = v + w.Header()[http.CanonicalHeaderKey(k)] = v } } diff --git a/core/corehttp/redirect.go b/core/corehttp/redirect.go index 4b98963e2..106355d24 100644 --- a/core/corehttp/redirect.go +++ b/core/corehttp/redirect.go @@ -32,7 +32,7 @@ type redirectHandler struct { func (i *redirectHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { for k, v := range i.headers { - w.Header()[k] = v + w.Header()[http.CanonicalHeaderKey(k)] = v } http.Redirect(w, r, i.path, http.StatusFound) From 715019440f6d122e1d949615359c6a79548cf5e4 Mon Sep 17 00:00:00 2001 From: Piotr Galar Date: Mon, 20 Mar 2023 09:47:59 +0100 Subject: [PATCH 0543/1212] chore: update go-libp2p to v0.26.3 (#9737) --- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index d96fa795d..5453ae1d5 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -10,7 +10,7 @@ require ( github.com/ipfs/go-libipfs v0.6.2 github.com/ipfs/interface-go-ipfs-core v0.11.0 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 - github.com/libp2p/go-libp2p v0.26.2 + github.com/libp2p/go-libp2p v0.26.3 github.com/multiformats/go-multiaddr v0.8.0 ) diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 3a08f464a..6f7e7f253 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -730,8 +730,8 @@ github.com/libp2p/go-libp2p v0.7.0/go.mod h1:hZJf8txWeCduQRDC/WSqBGMxaTHCOYHt2xS github.com/libp2p/go-libp2p v0.7.4/go.mod h1:oXsBlTLF1q7pxr+9w6lqzS1ILpyHsaBPniVO7zIHGMw= github.com/libp2p/go-libp2p v0.8.1/go.mod h1:QRNH9pwdbEBpx5DTJYg+qxcVaDMAz3Ee/qDKwXujH5o= github.com/libp2p/go-libp2p v0.14.3/go.mod h1:d12V4PdKbpL0T1/gsUNN8DfgMuRPDX8bS2QxCZlwRH0= -github.com/libp2p/go-libp2p v0.26.2 h1:eHEoW/696FP7/6DxOvcrKfTD6Bi0DExxiMSZUJxswA0= -github.com/libp2p/go-libp2p v0.26.2/go.mod h1:x75BN32YbwuY0Awm2Uix4d4KOz+/4piInkp4Wr3yOo8= +github.com/libp2p/go-libp2p v0.26.3 h1:6g/psubqwdaBqNNoidbRKSTBEYgaOuKBhHl8Q5tO+PM= +github.com/libp2p/go-libp2p v0.26.3/go.mod h1:x75BN32YbwuY0Awm2Uix4d4KOz+/4piInkp4Wr3yOo8= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-autonat v0.1.0/go.mod h1:1tLf2yXxiE/oKGtDwPYWTSYG3PtvYlJmg7NeVtPRqH8= diff --git a/go.mod b/go.mod index 4fce33b56..f7237b46a 100644 --- a/go.mod +++ b/go.mod @@ -67,7 +67,7 @@ require ( 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.26.2 + github.com/libp2p/go-libp2p v0.26.3 github.com/libp2p/go-libp2p-http v0.4.0 github.com/libp2p/go-libp2p-kad-dht v0.21.1 github.com/libp2p/go-libp2p-kbucket v0.5.0 diff --git a/go.sum b/go.sum index 100875344..27e101e1c 100644 --- a/go.sum +++ b/go.sum @@ -760,8 +760,8 @@ github.com/libp2p/go-libp2p v0.7.0/go.mod h1:hZJf8txWeCduQRDC/WSqBGMxaTHCOYHt2xS github.com/libp2p/go-libp2p v0.7.4/go.mod h1:oXsBlTLF1q7pxr+9w6lqzS1ILpyHsaBPniVO7zIHGMw= github.com/libp2p/go-libp2p v0.8.1/go.mod h1:QRNH9pwdbEBpx5DTJYg+qxcVaDMAz3Ee/qDKwXujH5o= github.com/libp2p/go-libp2p v0.14.3/go.mod h1:d12V4PdKbpL0T1/gsUNN8DfgMuRPDX8bS2QxCZlwRH0= -github.com/libp2p/go-libp2p v0.26.2 h1:eHEoW/696FP7/6DxOvcrKfTD6Bi0DExxiMSZUJxswA0= -github.com/libp2p/go-libp2p v0.26.2/go.mod h1:x75BN32YbwuY0Awm2Uix4d4KOz+/4piInkp4Wr3yOo8= +github.com/libp2p/go-libp2p v0.26.3 h1:6g/psubqwdaBqNNoidbRKSTBEYgaOuKBhHl8Q5tO+PM= +github.com/libp2p/go-libp2p v0.26.3/go.mod h1:x75BN32YbwuY0Awm2Uix4d4KOz+/4piInkp4Wr3yOo8= github.com/libp2p/go-libp2p-asn-util v0.2.0 h1:rg3+Os8jbnO5DxkC7K/Utdi+DkY3q/d1/1q+8WeNAsw= github.com/libp2p/go-libp2p-asn-util v0.2.0/go.mod h1:WoaWxbHKBymSN41hWSq/lGKJEca7TNm58+gGJi2WsLI= github.com/libp2p/go-libp2p-autonat v0.1.0/go.mod h1:1tLf2yXxiE/oKGtDwPYWTSYG3PtvYlJmg7NeVtPRqH8= From adcee3e515b231632249d397cb2e866e06d6ddc4 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Mon, 14 Nov 2022 14:17:04 +0000 Subject: [PATCH 0544/1212] fix: typo in documentation for install path By default, `go install` will install go $GOBIN and not $GOPATH/bin. In most cases there is no functional difference -- `go install` falls back to $GOPATH/bin when $GOBIN is empty. --- Rules.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Rules.mk b/Rules.mk index f7e962549..3d3d9c139 100644 --- a/Rules.mk +++ b/Rules.mk @@ -118,7 +118,7 @@ help: @echo ' all - print this help message' @echo ' build - Build binary at ./cmd/ipfs/ipfs' @echo ' nofuse - Build binary with no fuse support' - @echo ' install - Build binary and install into $$GOPATH/bin' + @echo ' install - Build binary and install into $$GOBIN' # @echo ' dist_install - TODO: c.f. ./cmd/ipfs/dist/README.md' @echo '' @echo 'CLEANING TARGETS:' From c30ab94c53eed391a841f8a1e6f83e22c8fcc655 Mon Sep 17 00:00:00 2001 From: Piotr Galar Date: Mon, 6 Mar 2023 20:03:19 +0100 Subject: [PATCH 0545/1212] Merge pull request #9689 from ipfs/no-testground ci: remove disabled testground workflow --- .github/workflows/testground-on-push.yml | 38 ------------------------ 1 file changed, 38 deletions(-) delete mode 100644 .github/workflows/testground-on-push.yml diff --git a/.github/workflows/testground-on-push.yml b/.github/workflows/testground-on-push.yml deleted file mode 100644 index 7b55dbdee..000000000 --- a/.github/workflows/testground-on-push.yml +++ /dev/null @@ -1,38 +0,0 @@ ---- -name: Testground PR Checker - -on: - workflow_dispatch: - push: - - -jobs: - testground: - if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' - runs-on: ubuntu-latest - name: ${{ matrix.composition_file }} - strategy: - matrix: - include: - - backend_addr: ci.testground.ipfs.team - backend_proto: https - plan_directory: testplans/bitswap - composition_file: testplans/bitswap/_compositions/small-k8s.toml - - backend_addr: ci.testground.ipfs.team - backend_proto: https - plan_directory: testplans/bitswap - composition_file: testplans/bitswap/_compositions/medium-k8s.toml - - backend_addr: ci.testground.ipfs.team - backend_proto: https - plan_directory: testplans/bitswap - composition_file: testplans/bitswap/_compositions/large-k8s.toml - steps: - - uses: actions/checkout@v2 - - name: testground run - uses: testground/testground-github-action@v1 - timeout-minutes: 5 - with: - backend_addr: ${{ matrix.backend_addr }} - backend_proto: ${{ matrix.backend_proto }} - plan_directory: ${{ matrix.plan_directory }} - composition_file: ${{ matrix.composition_file }} From ff019366f5c7335656e33c5dc985dd68bd21db61 Mon Sep 17 00:00:00 2001 From: Piotr Galar Date: Mon, 6 Mar 2023 20:19:34 +0100 Subject: [PATCH 0546/1212] Merge pull request #9699 from ipfs/early-testers docs: add bifrost to early testers --- docs/EARLY_TESTERS.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/docs/EARLY_TESTERS.md b/docs/EARLY_TESTERS.md index fb2fedc2a..d0dd4a867 100644 --- a/docs/EARLY_TESTERS.md +++ b/docs/EARLY_TESTERS.md @@ -22,15 +22,16 @@ We will ask early testers to participate at two points in the process: ## Who has signed up? -- [ ] pacman.store (@RubenKelevra) -- [ ] Infura (@MichaelMure) -- [ ] Textile (@sanderpick) -- [ ] Pinata (@obo20) -- [ ] RTrade (@postables) -- [ ] Siderus (@koalalorenzo) - [ ] Charity Engine (@rytiss, @tristanolive) - [ ] Fission (@bmann) +- [ ] Infura (@MichaelMure) - [ ] OrbitDB (@aphelionz) +- [ ] pacman.store (@RubenKelevra) +- [ ] Pinata (@obo20) +- [ ] PL EngRes bifrost (@gmasgras) +- [ ] RTrade (@postables) +- [ ] Siderus (@koalalorenzo) +- [ ] Textile (@sanderpick) ## How to sign up? From 8fe7d779c1b977bebc20e549a8c5227f436673d6 Mon Sep 17 00:00:00 2001 From: Piotr Galar Date: Wed, 8 Mar 2023 10:19:28 +0100 Subject: [PATCH 0547/1212] Merge pull request #9696 from ipfs/galargh-patch-2 fix: t0116-gateway-cache.sh --- test/sharness/t0116-gateway-cache.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/sharness/t0116-gateway-cache.sh b/test/sharness/t0116-gateway-cache.sh index 508fc73c2..0cb1a94eb 100755 --- a/test/sharness/t0116-gateway-cache.sh +++ b/test/sharness/t0116-gateway-cache.sh @@ -204,7 +204,7 @@ test_expect_success "Prepare IPNS unixfs content path for testing" ' grep -E "< Etag: \"DirIndex-.+_CID-${ROOT3_CID}\"" curl_ipfs_dir_listing_output ' test_expect_success "GET /ipns/ dir response has special Etag for generated dir listing" ' - test_should_contain "< Etag: \"DirIndex" curl_ipfs_dir_listing_output && + test_should_contain "< Etag: \"DirIndex" curl_ipns_dir_listing_output && grep -E "< Etag: \"DirIndex-.+_CID-${ROOT3_CID}\"" curl_ipns_dir_listing_output ' From d339059a7fb44467b8d3bb92359236cf76538c91 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Tue, 7 Mar 2023 19:28:52 +0100 Subject: [PATCH 0548/1212] chore: bump go-libipfs v0.6.1 This does nothing, just move from an untagged commit to a tagged commit but contain the same things. --- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 056aea334..1c19dd3eb 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.18 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/go-libipfs v0.6.1-0.20230228004237-36918f45f260 + github.com/ipfs/go-libipfs v0.6.1 github.com/ipfs/interface-go-ipfs-core v0.11.0 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.26.2 diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 8a07bfbe8..c927b58d9 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -569,8 +569,8 @@ github.com/ipfs/go-ipld-legacy v0.1.1 h1:BvD8PEuqwBHLTKqlGFTHSwrwFOMkVESEvwIYwR2 github.com/ipfs/go-ipld-legacy v0.1.1/go.mod h1:8AyKFCjgRPsQFf15ZQgDB8Din4DML/fOmKZkkFkrIEg= github.com/ipfs/go-ipns v0.3.0 h1:ai791nTgVo+zTuq2bLvEGmWP1M0A6kGTXUsgv/Yq67A= github.com/ipfs/go-ipns v0.3.0/go.mod h1:3cLT2rbvgPZGkHJoPO1YMJeh6LtkxopCkKFcio/wE24= -github.com/ipfs/go-libipfs v0.6.1-0.20230228004237-36918f45f260 h1:QRLcCoITO9ZQo2pvjmrfngqKhUKjPopBva3MVH62LT8= -github.com/ipfs/go-libipfs v0.6.1-0.20230228004237-36918f45f260/go.mod h1:3OoEQs95UkqFEf65SbRDpiMwuzI+C/jTsYQaHfBbJXI= +github.com/ipfs/go-libipfs v0.6.1 h1:OSO9cm1H3r4OXfP0MP1Q5UhTnhd2fByGl6CVYyz/Rhk= +github.com/ipfs/go-libipfs v0.6.1/go.mod h1:FmhKgxMOQA572TK5DA3MZ5GL44ZqsMHIrkgK4gLn4A8= github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= github.com/ipfs/go-log v1.0.2/go.mod h1:1MNjMxe0u6xvJZgeqbJ8vdo2TKaGwZ1a0Bpza+sr2Sk= github.com/ipfs/go-log v1.0.3/go.mod h1:OsLySYkwIbiSUR/yBTdv1qPtcE4FW3WPWk/ewz9Ru+A= diff --git a/go.mod b/go.mod index 34603ebd2..673dd3793 100644 --- a/go.mod +++ b/go.mod @@ -45,7 +45,7 @@ require ( github.com/ipfs/go-ipld-git v0.1.1 github.com/ipfs/go-ipld-legacy v0.1.1 github.com/ipfs/go-ipns v0.3.0 - github.com/ipfs/go-libipfs v0.6.1-0.20230228004237-36918f45f260 + github.com/ipfs/go-libipfs v0.6.1 github.com/ipfs/go-log v1.0.5 github.com/ipfs/go-log/v2 v2.5.1 github.com/ipfs/go-merkledag v0.9.0 diff --git a/go.sum b/go.sum index 6f7800a2e..16329d6ad 100644 --- a/go.sum +++ b/go.sum @@ -591,8 +591,8 @@ github.com/ipfs/go-ipld-legacy v0.1.1 h1:BvD8PEuqwBHLTKqlGFTHSwrwFOMkVESEvwIYwR2 github.com/ipfs/go-ipld-legacy v0.1.1/go.mod h1:8AyKFCjgRPsQFf15ZQgDB8Din4DML/fOmKZkkFkrIEg= github.com/ipfs/go-ipns v0.3.0 h1:ai791nTgVo+zTuq2bLvEGmWP1M0A6kGTXUsgv/Yq67A= github.com/ipfs/go-ipns v0.3.0/go.mod h1:3cLT2rbvgPZGkHJoPO1YMJeh6LtkxopCkKFcio/wE24= -github.com/ipfs/go-libipfs v0.6.1-0.20230228004237-36918f45f260 h1:QRLcCoITO9ZQo2pvjmrfngqKhUKjPopBva3MVH62LT8= -github.com/ipfs/go-libipfs v0.6.1-0.20230228004237-36918f45f260/go.mod h1:3OoEQs95UkqFEf65SbRDpiMwuzI+C/jTsYQaHfBbJXI= +github.com/ipfs/go-libipfs v0.6.1 h1:OSO9cm1H3r4OXfP0MP1Q5UhTnhd2fByGl6CVYyz/Rhk= +github.com/ipfs/go-libipfs v0.6.1/go.mod h1:FmhKgxMOQA572TK5DA3MZ5GL44ZqsMHIrkgK4gLn4A8= github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= github.com/ipfs/go-log v1.0.2/go.mod h1:1MNjMxe0u6xvJZgeqbJ8vdo2TKaGwZ1a0Bpza+sr2Sk= github.com/ipfs/go-log v1.0.3/go.mod h1:OsLySYkwIbiSUR/yBTdv1qPtcE4FW3WPWk/ewz9Ru+A= From bfa425fc67b5a6125412cd2453d6fa7f83a4bc96 Mon Sep 17 00:00:00 2001 From: Gus Eggert Date: Wed, 8 Mar 2023 15:48:56 -0500 Subject: [PATCH 0549/1212] test: port legacy DHT tests to Go --- test/cli/dht_legacy_test.go | 137 ++++++++++++++++++++++++++++++ test/cli/harness/harness.go | 2 +- test/cli/harness/node.go | 44 +++++++--- test/cli/harness/nodes.go | 16 ++++ test/cli/harness/run.go | 8 +- test/sharness/t0170-legacy-dht.sh | 121 -------------------------- 6 files changed, 192 insertions(+), 136 deletions(-) create mode 100644 test/cli/dht_legacy_test.go delete mode 100755 test/sharness/t0170-legacy-dht.sh diff --git a/test/cli/dht_legacy_test.go b/test/cli/dht_legacy_test.go new file mode 100644 index 000000000..437b62ae4 --- /dev/null +++ b/test/cli/dht_legacy_test.go @@ -0,0 +1,137 @@ +package cli + +import ( + "sort" + "sync" + "testing" + + "github.com/ipfs/kubo/test/cli/harness" + "github.com/ipfs/kubo/test/cli/testutils" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestLegacyDHT(t *testing.T) { + nodes := harness.NewT(t).NewNodes(5).Init() + nodes.ForEachPar(func(node *harness.Node) { + node.IPFS("config", "Routing.Type", "dht") + }) + nodes.StartDaemons().Connect() + + t.Run("ipfs dht findpeer", func(t *testing.T) { + t.Parallel() + res := nodes[1].RunIPFS("dht", "findpeer", nodes[0].PeerID().String()) + assert.Equal(t, 0, res.ExitCode()) + + swarmAddr := nodes[0].SwarmAddrsWithoutPeerIDs()[0] + require.Equal(t, swarmAddr.String(), res.Stdout.Trimmed()) + }) + + t.Run("ipfs dht get ", func(t *testing.T) { + t.Parallel() + hash := nodes[2].IPFSAddStr("hello world") + nodes[2].IPFS("name", "publish", "/ipfs/"+hash) + + res := nodes[1].IPFS("dht", "get", "/ipns/"+nodes[2].PeerID().String()) + assert.Contains(t, res.Stdout.String(), "/ipfs/"+hash) + + t.Run("put round trips (#3124)", func(t *testing.T) { + t.Parallel() + nodes[0].WriteBytes("get_result", res.Stdout.Bytes()) + res := nodes[0].IPFS("dht", "put", "/ipns/"+nodes[2].PeerID().String(), "get_result") + assert.Greater(t, len(res.Stdout.Lines()), 0, "should put to at least one node") + }) + + t.Run("put with bad keys fails (issue #5113, #4611)", func(t *testing.T) { + t.Parallel() + keys := []string{"foo", "/pk/foo", "/ipns/foo"} + for _, key := range keys { + key := key + t.Run(key, func(t *testing.T) { + t.Parallel() + res := nodes[0].RunIPFS("dht", "put", key) + assert.Equal(t, 1, res.ExitCode()) + assert.Contains(t, res.Stderr.String(), "invalid") + assert.Empty(t, res.Stdout.String()) + }) + } + }) + + t.Run("get with bad keys (issue #4611)", func(t *testing.T) { + for _, key := range []string{"foo", "/pk/foo"} { + key := key + t.Run(key, func(t *testing.T) { + t.Parallel() + res := nodes[0].RunIPFS("dht", "get", key) + assert.Equal(t, 1, res.ExitCode()) + assert.Contains(t, res.Stderr.String(), "invalid") + assert.Empty(t, res.Stdout.String()) + }) + } + }) + }) + + t.Run("ipfs dht findprovs", func(t *testing.T) { + t.Parallel() + hash := nodes[3].IPFSAddStr("some stuff") + res := nodes[4].IPFS("dht", "findprovs", hash) + assert.Equal(t, nodes[3].PeerID().String(), res.Stdout.Trimmed()) + }) + + t.Run("ipfs dht query ", func(t *testing.T) { + t.Parallel() + t.Run("normal DHT configuration", func(t *testing.T) { + t.Parallel() + hash := nodes[0].IPFSAddStr("some other stuff") + peerCounts := map[string]int{} + peerCountsMut := sync.Mutex{} + harness.Nodes(nodes).ForEachPar(func(node *harness.Node) { + res := node.IPFS("dht", "query", hash) + closestPeer := res.Stdout.Lines()[0] + // check that it's a valid peer ID + _, err := peer.Decode(closestPeer) + require.NoError(t, err) + + peerCountsMut.Lock() + peerCounts[closestPeer]++ + peerCountsMut.Unlock() + }) + // 4 nodes should see the same peer ID + // 1 node (the closest) should see a different one + var counts []int + for _, count := range peerCounts { + counts = append(counts, count) + } + sort.IntSlice(counts).Sort() + assert.Equal(t, []int{1, 4}, counts) + }) + + }) + + t.Run("dht commands fail when offline", func(t *testing.T) { + t.Parallel() + node := harness.NewT(t).NewNode().Init() + + // these cannot be run in parallel due to repo locking (seems like a bug) + + t.Run("dht findprovs", func(t *testing.T) { + res := node.RunIPFS("dht", "findprovs", testutils.CIDEmptyDir) + assert.Equal(t, 1, res.ExitCode()) + assert.Contains(t, res.Stderr.String(), "this command must be run in online mode") + }) + + t.Run("dht findpeer", func(t *testing.T) { + res := node.RunIPFS("dht", "findpeer", testutils.CIDEmptyDir) + assert.Equal(t, 1, res.ExitCode()) + assert.Contains(t, res.Stderr.String(), "this command must be run in online mode") + }) + + t.Run("dht put", func(t *testing.T) { + node.WriteBytes("foo", []byte("foo")) + res := node.RunIPFS("dht", "put", "/ipns/"+node.PeerID().String(), "foo") + assert.Equal(t, 1, res.ExitCode()) + assert.Contains(t, res.Stderr.String(), "this action must be run in online mode") + }) + }) +} diff --git a/test/cli/harness/harness.go b/test/cli/harness/harness.go index de962e1c1..a35fead35 100644 --- a/test/cli/harness/harness.go +++ b/test/cli/harness/harness.go @@ -171,7 +171,7 @@ func (h *Harness) Mkdirs(paths ...string) { } } -func (h *Harness) Sh(expr string) RunResult { +func (h *Harness) Sh(expr string) *RunResult { return h.Runner.Run(RunRequest{ Path: "bash", Args: []string{"-c", expr}, diff --git a/test/cli/harness/node.go b/test/cli/harness/node.go index 0d0295307..181fca99b 100644 --- a/test/cli/harness/node.go +++ b/test/cli/harness/node.go @@ -129,23 +129,23 @@ func (n *Node) UpdateConfigAndUserSuppliedResourceManagerOverrides(f func(cfg *c n.WriteUserSuppliedResourceOverrides(overrides) } -func (n *Node) IPFS(args ...string) RunResult { +func (n *Node) IPFS(args ...string) *RunResult { res := n.RunIPFS(args...) n.Runner.AssertNoError(res) return res } -func (n *Node) PipeStrToIPFS(s string, args ...string) RunResult { +func (n *Node) PipeStrToIPFS(s string, args ...string) *RunResult { return n.PipeToIPFS(strings.NewReader(s), args...) } -func (n *Node) PipeToIPFS(reader io.Reader, args ...string) RunResult { +func (n *Node) PipeToIPFS(reader io.Reader, args ...string) *RunResult { res := n.RunPipeToIPFS(reader, args...) n.Runner.AssertNoError(res) return res } -func (n *Node) RunPipeToIPFS(reader io.Reader, args ...string) RunResult { +func (n *Node) RunPipeToIPFS(reader io.Reader, args ...string) *RunResult { return n.Runner.Run(RunRequest{ Path: n.IPFSBin, Args: args, @@ -153,7 +153,7 @@ func (n *Node) RunPipeToIPFS(reader io.Reader, args ...string) RunResult { }) } -func (n *Node) RunIPFS(args ...string) RunResult { +func (n *Node) RunIPFS(args ...string) *RunResult { return n.Runner.Run(RunRequest{ Path: n.IPFSBin, Args: args, @@ -216,7 +216,7 @@ func (n *Node) StartDaemon(ipfsArgs ...string) *Node { RunFunc: (*exec.Cmd).Start, }) - n.Daemon = &res + n.Daemon = res log.Debugf("node %d started, checking API", n.ID) n.WaitOnAPI() @@ -399,8 +399,6 @@ func (n *Node) SwarmAddrs() []multiaddr.Multiaddr { Path: n.IPFSBin, Args: []string{"swarm", "addrs", "local"}, }) - ipfsProtocol := multiaddr.ProtocolWithCode(multiaddr.P_IPFS).Name - peerID := n.PeerID() out := strings.TrimSpace(res.Stdout.String()) outLines := strings.Split(out, "\n") var addrs []multiaddr.Multiaddr @@ -409,9 +407,18 @@ func (n *Node) SwarmAddrs() []multiaddr.Multiaddr { if err != nil { panic(err) } + addrs = append(addrs, ma) + } + return addrs +} +func (n *Node) SwarmAddrsWithPeerIDs() []multiaddr.Multiaddr { + ipfsProtocol := multiaddr.ProtocolWithCode(multiaddr.P_IPFS).Name + peerID := n.PeerID() + var addrs []multiaddr.Multiaddr + for _, ma := range n.SwarmAddrs() { // add the peer ID to the multiaddr if it doesn't have it - _, err = ma.ValueForProtocol(multiaddr.P_IPFS) + _, err := ma.ValueForProtocol(multiaddr.P_IPFS) if errors.Is(err, multiaddr.ErrProtocolNotFound) { comp, err := multiaddr.NewComponent(ipfsProtocol, peerID.String()) if err != nil { @@ -424,10 +431,27 @@ func (n *Node) SwarmAddrs() []multiaddr.Multiaddr { return addrs } +func (n *Node) SwarmAddrsWithoutPeerIDs() []multiaddr.Multiaddr { + var addrs []multiaddr.Multiaddr + for _, ma := range n.SwarmAddrs() { + var components []multiaddr.Multiaddr + multiaddr.ForEach(ma, func(c multiaddr.Component) bool { + if c.Protocol().Code == multiaddr.P_IPFS { + return true + } + components = append(components, &c) + return true + }) + ma = multiaddr.Join(components...) + addrs = append(addrs, ma) + } + return addrs +} + func (n *Node) Connect(other *Node) *Node { n.Runner.MustRun(RunRequest{ Path: n.IPFSBin, - Args: []string{"swarm", "connect", other.SwarmAddrs()[0].String()}, + Args: []string{"swarm", "connect", other.SwarmAddrsWithPeerIDs()[0].String()}, }) return n } diff --git a/test/cli/harness/nodes.go b/test/cli/harness/nodes.go index dbc7de16b..872d77679 100644 --- a/test/cli/harness/nodes.go +++ b/test/cli/harness/nodes.go @@ -4,6 +4,7 @@ import ( "sync" "github.com/multiformats/go-multiaddr" + "golang.org/x/sync/errgroup" ) // Nodes is a collection of Kubo nodes along with operations on groups of nodes. @@ -16,6 +17,21 @@ func (n Nodes) Init(args ...string) Nodes { return n } +func (n Nodes) ForEachPar(f func(*Node)) { + group := &errgroup.Group{} + for _, node := range n { + node := node + group.Go(func() error { + f(node) + return nil + }) + } + err := group.Wait() + if err != nil { + panic(err) + } +} + func (n Nodes) Connect() Nodes { wg := sync.WaitGroup{} for i, node := range n { diff --git a/test/cli/harness/run.go b/test/cli/harness/run.go index 9cbb871bc..c2a3662be 100644 --- a/test/cli/harness/run.go +++ b/test/cli/harness/run.go @@ -51,7 +51,7 @@ func environToMap(environ []string) map[string]string { return m } -func (r *Runner) Run(req RunRequest) RunResult { +func (r *Runner) Run(req RunRequest) *RunResult { cmd := exec.Command(req.Path, req.Args...) stdout := &Buffer{} stderr := &Buffer{} @@ -86,17 +86,17 @@ func (r *Runner) Run(req RunRequest) RunResult { result.ExitErr = exitErr } - return result + return &result } // MustRun runs the command and fails the test if the command fails. -func (r *Runner) MustRun(req RunRequest) RunResult { +func (r *Runner) MustRun(req RunRequest) *RunResult { result := r.Run(req) r.AssertNoError(result) return result } -func (r *Runner) AssertNoError(result RunResult) { +func (r *Runner) AssertNoError(result *RunResult) { if result.ExitErr != nil { log.Panicf("'%s' returned error, code: %d, err: %s\nstdout:%s\nstderr:%s\n", result.Cmd.Args, result.ExitErr.ExitCode(), result.ExitErr.Error(), result.Stdout.String(), result.Stderr.String()) diff --git a/test/sharness/t0170-legacy-dht.sh b/test/sharness/t0170-legacy-dht.sh deleted file mode 100755 index fc11b9044..000000000 --- a/test/sharness/t0170-legacy-dht.sh +++ /dev/null @@ -1,121 +0,0 @@ -#!/usr/bin/env bash - -# Legacy / deprecated, see: t0170-routing-dht.sh -test_description="Test dht command" - -. lib/test-lib.sh - -test_dht() { - NUM_NODES=5 - - test_expect_success 'init iptb' ' - rm -rf .iptb/ && - iptb testbed create -type localipfs -count $NUM_NODES -init - ' - - test_expect_success 'DHT-only routing' ' - iptb run -- ipfs config Routing.Type dht - ' - - startup_cluster $NUM_NODES $@ - - test_expect_success 'peer ids' ' - PEERID_0=$(iptb attr get 0 id) && - PEERID_2=$(iptb attr get 2 id) - ' - - # ipfs dht findpeer - test_expect_success 'findpeer' ' - ipfsi 1 dht findpeer $PEERID_0 | sort >actual && - ipfsi 0 id -f "" | cut -d / -f 1-5 | sort >expected && - test_cmp actual expected - ' - - # ipfs dht get - test_expect_success 'get with good keys works' ' - HASH="$(echo "hello world" | ipfsi 2 add -q)" && - ipfsi 2 name publish "/ipfs/$HASH" && - ipfsi 1 dht get "/ipns/$PEERID_2" >get_result - ' - - test_expect_success 'get with good keys contains the right value' ' - cat get_result | grep -aq "/ipfs/$HASH" - ' - - test_expect_success 'put round trips (#3124)' ' - ipfsi 0 dht put "/ipns/$PEERID_2" get_result | sort >putted && - [ -s putted ] || - test_fsh cat putted - ' - - test_expect_success 'put with bad keys fails (issue #5113)' ' - ipfsi 0 dht put "foo" <<putted - ipfsi 0 dht put "/pk/foo" <<>putted - ipfsi 0 dht put "/ipns/foo" <<>putted - [ ! -s putted ] || - test_fsh cat putted - ' - - test_expect_success 'put with bad keys returns error (issue #4611)' ' - test_must_fail ipfsi 0 dht put "foo" << afile && - HASH=$(ipfsi 3 add -q afile) - ' - - # ipfs dht findprovs - test_expect_success 'findprovs' ' - ipfsi 4 dht findprovs $HASH > provs && - iptb attr get 3 id > expected && - test_cmp provs expected - ' - - - # ipfs dht query - # - # We test all nodes. 4 nodes should see the same peer ID, one node (the - # closest) should see a different one. - - for i in $(test_seq 0 4); do - test_expect_success "query from $i" ' - ipfsi "$i" dht query "$HASH" | head -1 >closest-$i - ' - done - - test_expect_success "collecting results" ' - cat closest-* | sort | uniq -c | sed -e "s/ *\([0-9]\+\) .*/\1/g" | sort -g > actual && - echo 1 > expected && - echo 4 >> expected - ' - - test_expect_success "checking results" ' - test_cmp actual expected - ' - - test_expect_success 'stop iptb' ' - iptb stop - ' - - test_expect_success "dht commands fail when offline" ' - test_must_fail ipfsi 0 dht findprovs "$HASH" 2>err_findprovs && - test_must_fail ipfsi 0 dht findpeer "$HASH" 2>err_findpeer && - test_must_fail ipfsi 0 dht put "/ipns/$PEERID_2" "get_result" 2>err_put && - test_should_contain "this command must be run in online mode" err_findprovs && - test_should_contain "this command must be run in online mode" err_findpeer && - test_should_contain "this action must be run in online mode" err_put - ' -} - -test_dht -test_dht --enable-pubsub-experiment --enable-namesys-pubsub - -test_done From 840eaa75990c3efb67e4404c9f0e7d25f091c152 Mon Sep 17 00:00:00 2001 From: Gus Eggert Date: Wed, 8 Mar 2023 16:25:45 -0500 Subject: [PATCH 0550/1212] test: parallelize more of rcmgr Go tests --- test/cli/harness/node.go | 8 ---- test/cli/rcmgr_test.go | 86 ++++++++++++++++++++++++---------------- 2 files changed, 52 insertions(+), 42 deletions(-) diff --git a/test/cli/harness/node.go b/test/cli/harness/node.go index 181fca99b..cc251e11b 100644 --- a/test/cli/harness/node.go +++ b/test/cli/harness/node.go @@ -121,14 +121,6 @@ func (n *Node) UpdateUserSuppliedResourceManagerOverrides(f func(overrides *rcmg n.WriteUserSuppliedResourceOverrides(overrides) } -func (n *Node) UpdateConfigAndUserSuppliedResourceManagerOverrides(f func(cfg *config.Config, overrides *rcmgr.PartialLimitConfig)) { - overrides := n.ReadUserResourceOverrides() - cfg := n.ReadConfig() - f(cfg, overrides) - n.WriteConfig(cfg) - n.WriteUserSuppliedResourceOverrides(overrides) -} - func (n *Node) IPFS(args ...string) *RunResult { res := n.RunIPFS(args...) n.Runner.AssertNoError(res) diff --git a/test/cli/rcmgr_test.go b/test/cli/rcmgr_test.go index fb644e1a7..51b2b0452 100644 --- a/test/cli/rcmgr_test.go +++ b/test/cli/rcmgr_test.go @@ -49,6 +49,7 @@ func TestRcmgr(t *testing.T) { }) t.Run("Very high connmgr highwater", func(t *testing.T) { + t.Parallel() node := harness.NewT(t).NewNode().Init() node.UpdateConfig(func(cfg *config.Config) { cfg.Swarm.ConnMgr.HighWater = config.NewOptionalInteger(1000) @@ -74,6 +75,7 @@ func TestRcmgr(t *testing.T) { node.StartDaemon() t.Run("conns and streams are above 800 for default connmgr settings", func(t *testing.T) { + t.Parallel() res := node.RunIPFS("swarm", "resources", "--enc=json") require.Equal(t, 0, res.ExitCode()) limits := unmarshalLimits(t, res.Stdout.Bytes()) @@ -87,6 +89,7 @@ func TestRcmgr(t *testing.T) { }) t.Run("limits should succeed", func(t *testing.T) { + t.Parallel() res := node.RunIPFS("swarm", "resources", "--enc=json") assert.Equal(t, 0, res.ExitCode()) @@ -106,6 +109,7 @@ func TestRcmgr(t *testing.T) { }) t.Run("swarm stats works", func(t *testing.T) { + t.Parallel() res := node.RunIPFS("swarm", "resources", "--enc=json") require.Equal(t, 0, res.ExitCode()) @@ -123,6 +127,7 @@ func TestRcmgr(t *testing.T) { }) t.Run("smoke test transient scope", func(t *testing.T) { + t.Parallel() node := harness.NewT(t).NewNode().Init() node.UpdateUserSuppliedResourceManagerOverrides(func(overrides *rcmgr.PartialLimitConfig) { overrides.Transient.Memory = 88888 @@ -135,6 +140,7 @@ func TestRcmgr(t *testing.T) { }) t.Run("smoke test service scope", func(t *testing.T) { + t.Parallel() node := harness.NewT(t).NewNode().Init() node.UpdateUserSuppliedResourceManagerOverrides(func(overrides *rcmgr.PartialLimitConfig) { overrides.Service = map[string]rcmgr.ResourceLimits{"foo": {Memory: 77777}} @@ -147,6 +153,7 @@ func TestRcmgr(t *testing.T) { }) t.Run("smoke test protocol scope", func(t *testing.T) { + t.Parallel() node := harness.NewT(t).NewNode().Init() node.UpdateUserSuppliedResourceManagerOverrides(func(overrides *rcmgr.PartialLimitConfig) { overrides.Protocol = map[protocol.ID]rcmgr.ResourceLimits{"foo": {Memory: 66666}} @@ -159,6 +166,7 @@ func TestRcmgr(t *testing.T) { }) t.Run("smoke test peer scope", func(t *testing.T) { + t.Parallel() validPeerID, err := peer.Decode("QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN") assert.NoError(t, err) node := harness.NewT(t).NewNode().Init() @@ -172,13 +180,17 @@ func TestRcmgr(t *testing.T) { assert.Equal(t, rcmgr.LimitVal64(55555), limits.Peers[validPeerID].Memory) }) - t.Run("", func(t *testing.T) { + t.Run("blocking and allowlists", func(t *testing.T) { + t.Parallel() nodes := harness.NewT(t).NewNodes(3).Init() node0, node1, node2 := nodes[0], nodes[1], nodes[2] - // peerID0, peerID1, peerID2 := node0.PeerID(), node1.PeerID(), node2.PeerID() peerID1, peerID2 := node1.PeerID().String(), node2.PeerID().String() - node0.UpdateConfigAndUserSuppliedResourceManagerOverrides(func(cfg *config.Config, overrides *rcmgr.PartialLimitConfig) { + node0.UpdateConfig(func(cfg *config.Config) { + cfg.Swarm.ResourceMgr.Enabled = config.True + cfg.Swarm.ResourceMgr.Allowlist = []string{"/ip4/0.0.0.0/ipcidr/0/p2p/" + peerID2} + }) + node0.UpdateUserSuppliedResourceManagerOverrides(func(overrides *rcmgr.PartialLimitConfig) { *overrides = rcmgr.PartialLimitConfig{ System: rcmgr.ResourceLimits{ Conns: rcmgr.BlockAllLimit, @@ -186,91 +198,97 @@ func TestRcmgr(t *testing.T) { ConnsOutbound: rcmgr.BlockAllLimit, }, } - cfg.Swarm.ResourceMgr.Enabled = config.True - cfg.Swarm.ResourceMgr.Allowlist = []string{"/ip4/0.0.0.0/ipcidr/0/p2p/" + peerID2} }) nodes.StartDaemons() - t.Parallel() - t.Run("node 0 should fail to connect to node 1", func(t *testing.T) { + t.Run("node 0 should fail to connect to and ping node 1", func(t *testing.T) { + t.Parallel() res := node0.Runner.Run(harness.RunRequest{ Path: node0.IPFSBin, - Args: []string{"swarm", "connect", node1.SwarmAddrs()[0].String()}, + Args: []string{"swarm", "connect", node1.SwarmAddrsWithPeerIDs()[0].String()}, }) assert.Equal(t, 1, res.ExitCode()) assert.Contains(t, res.Stderr.String(), "failed to find any peer in table") - }) - t.Run("node 0 should connect to node 2 since it is allowlisted", func(t *testing.T) { - res := node0.Runner.Run(harness.RunRequest{ - Path: node0.IPFSBin, - Args: []string{"swarm", "connect", node2.SwarmAddrs()[0].String()}, - }) - assert.Equal(t, 0, res.ExitCode()) - }) - - t.Run("node 0 should fail to ping node 1", func(t *testing.T) { - res := node0.RunIPFS("ping", "-n2", peerID1) + res = node0.RunIPFS("ping", "-n2", peerID1) assert.Equal(t, 1, res.ExitCode()) assert.Contains(t, res.Stderr.String(), "Error: ping failed") }) - t.Run("node 0 should be able to ping node 2", func(t *testing.T) { - res := node0.RunIPFS("ping", "-n2", peerID2) + t.Run("node 0 should connect to and ping node 2 since it is allowlisted", func(t *testing.T) { + t.Parallel() + res := node0.Runner.Run(harness.RunRequest{ + Path: node0.IPFSBin, + Args: []string{"swarm", "connect", node2.SwarmAddrsWithPeerIDs()[0].String()}, + }) + assert.Equal(t, 0, res.ExitCode()) + + res = node0.RunIPFS("ping", "-n2", peerID2) assert.Equal(t, 0, res.ExitCode()) }) }) t.Run("daemon should refuse to start if connmgr.highwater < resources inbound", func(t *testing.T) { - t.Parallel() t.Run("system conns", func(t *testing.T) { + t.Parallel() node := harness.NewT(t).NewNode().Init() - node.UpdateConfigAndUserSuppliedResourceManagerOverrides(func(cfg *config.Config, overrides *rcmgr.PartialLimitConfig) { + node.UpdateConfig(func(cfg *config.Config) { + cfg.Swarm.ConnMgr.HighWater = config.NewOptionalInteger(128) + cfg.Swarm.ConnMgr.LowWater = config.NewOptionalInteger(64) + }) + node.UpdateUserSuppliedResourceManagerOverrides(func(overrides *rcmgr.PartialLimitConfig) { *overrides = rcmgr.PartialLimitConfig{ System: rcmgr.ResourceLimits{Conns: 128}, } - cfg.Swarm.ConnMgr.HighWater = config.NewOptionalInteger(128) - cfg.Swarm.ConnMgr.LowWater = config.NewOptionalInteger(64) }) res := node.RunIPFS("daemon") assert.Equal(t, 1, res.ExitCode()) }) t.Run("system conns inbound", func(t *testing.T) { + t.Parallel() node := harness.NewT(t).NewNode().Init() - node.UpdateConfigAndUserSuppliedResourceManagerOverrides(func(cfg *config.Config, overrides *rcmgr.PartialLimitConfig) { + node.UpdateConfig(func(cfg *config.Config) { + cfg.Swarm.ConnMgr.HighWater = config.NewOptionalInteger(128) + cfg.Swarm.ConnMgr.LowWater = config.NewOptionalInteger(64) + }) + node.UpdateUserSuppliedResourceManagerOverrides(func(overrides *rcmgr.PartialLimitConfig) { *overrides = rcmgr.PartialLimitConfig{ System: rcmgr.ResourceLimits{ConnsInbound: 128}, } - cfg.Swarm.ConnMgr.HighWater = config.NewOptionalInteger(128) - cfg.Swarm.ConnMgr.LowWater = config.NewOptionalInteger(64) }) res := node.RunIPFS("daemon") assert.Equal(t, 1, res.ExitCode()) }) t.Run("system streams", func(t *testing.T) { + t.Parallel() node := harness.NewT(t).NewNode().Init() - node.UpdateConfigAndUserSuppliedResourceManagerOverrides(func(cfg *config.Config, overrides *rcmgr.PartialLimitConfig) { + node.UpdateConfig(func(cfg *config.Config) { + cfg.Swarm.ConnMgr.HighWater = config.NewOptionalInteger(128) + cfg.Swarm.ConnMgr.LowWater = config.NewOptionalInteger(64) + }) + node.UpdateUserSuppliedResourceManagerOverrides(func(overrides *rcmgr.PartialLimitConfig) { *overrides = rcmgr.PartialLimitConfig{ System: rcmgr.ResourceLimits{Streams: 128}, } - cfg.Swarm.ConnMgr.HighWater = config.NewOptionalInteger(128) - cfg.Swarm.ConnMgr.LowWater = config.NewOptionalInteger(64) }) res := node.RunIPFS("daemon") assert.Equal(t, 1, res.ExitCode()) }) t.Run("system streams inbound", func(t *testing.T) { + t.Parallel() node := harness.NewT(t).NewNode().Init() - node.UpdateConfigAndUserSuppliedResourceManagerOverrides(func(cfg *config.Config, overrides *rcmgr.PartialLimitConfig) { + node.UpdateConfig(func(cfg *config.Config) { + cfg.Swarm.ConnMgr.HighWater = config.NewOptionalInteger(128) + cfg.Swarm.ConnMgr.LowWater = config.NewOptionalInteger(64) + }) + node.UpdateUserSuppliedResourceManagerOverrides(func(overrides *rcmgr.PartialLimitConfig) { *overrides = rcmgr.PartialLimitConfig{ System: rcmgr.ResourceLimits{StreamsInbound: 128}, } - cfg.Swarm.ConnMgr.HighWater = config.NewOptionalInteger(128) - cfg.Swarm.ConnMgr.LowWater = config.NewOptionalInteger(64) }) res := node.RunIPFS("daemon") From 2510f063643086f83a5ac3f70a2f56d1d373bf21 Mon Sep 17 00:00:00 2001 From: Gus Eggert Date: Wed, 8 Mar 2023 16:26:47 -0500 Subject: [PATCH 0551/1212] feat: add "autoclient" routing type This routing type is the same as "auto" but it creates the DHT in "client" mode and hence does not start a DHT server. --- cmd/ipfs/daemon.go | 61 ++++++++++++++----------- config/routing.go | 2 +- core/node/libp2p/routingopt.go | 5 +- docs/changelogs/v0.19.md | 6 +++ docs/config.md | 6 ++- test/cli/delegated_routing_http_test.go | 2 +- test/cli/dht_autoclient_test.go | 39 ++++++++++++++++ 7 files changed, 88 insertions(+), 33 deletions(-) create mode 100644 test/cli/dht_autoclient_test.go diff --git a/cmd/ipfs/daemon.go b/cmd/ipfs/daemon.go index 21495c498..880d26b0e 100644 --- a/cmd/ipfs/daemon.go +++ b/cmd/ipfs/daemon.go @@ -45,32 +45,33 @@ import ( ) const ( - adjustFDLimitKwd = "manage-fdlimit" - enableGCKwd = "enable-gc" - initOptionKwd = "init" - initConfigOptionKwd = "init-config" - initProfileOptionKwd = "init-profile" - ipfsMountKwd = "mount-ipfs" - ipnsMountKwd = "mount-ipns" - migrateKwd = "migrate" - mountKwd = "mount" - offlineKwd = "offline" // global option - routingOptionKwd = "routing" - routingOptionSupernodeKwd = "supernode" - routingOptionDHTClientKwd = "dhtclient" - routingOptionDHTKwd = "dht" - routingOptionDHTServerKwd = "dhtserver" - routingOptionNoneKwd = "none" - routingOptionCustomKwd = "custom" - routingOptionDefaultKwd = "default" - routingOptionAutoKwd = "auto" - unencryptTransportKwd = "disable-transport-encryption" - unrestrictedAPIAccessKwd = "unrestricted-api" - writableKwd = "writable" - enablePubSubKwd = "enable-pubsub-experiment" - enableIPNSPubSubKwd = "enable-namesys-pubsub" - enableMultiplexKwd = "enable-mplex-experiment" - agentVersionSuffix = "agent-version-suffix" + adjustFDLimitKwd = "manage-fdlimit" + enableGCKwd = "enable-gc" + initOptionKwd = "init" + initConfigOptionKwd = "init-config" + initProfileOptionKwd = "init-profile" + ipfsMountKwd = "mount-ipfs" + ipnsMountKwd = "mount-ipns" + migrateKwd = "migrate" + mountKwd = "mount" + offlineKwd = "offline" // global option + routingOptionKwd = "routing" + routingOptionSupernodeKwd = "supernode" + routingOptionDHTClientKwd = "dhtclient" + routingOptionDHTKwd = "dht" + routingOptionDHTServerKwd = "dhtserver" + routingOptionNoneKwd = "none" + routingOptionCustomKwd = "custom" + routingOptionDefaultKwd = "default" + routingOptionAutoKwd = "auto" + routingOptionAutoClientKwd = "autoclient" + unencryptTransportKwd = "disable-transport-encryption" + unrestrictedAPIAccessKwd = "unrestricted-api" + writableKwd = "writable" + enablePubSubKwd = "enable-pubsub-experiment" + enableIPNSPubSubKwd = "enable-namesys-pubsub" + enableMultiplexKwd = "enable-mplex-experiment" + agentVersionSuffix = "agent-version-suffix" // apiAddrKwd = "address-api" // swarmAddrKwd = "address-swarm" ) @@ -416,6 +417,14 @@ func daemonFunc(req *cmds.Request, re cmds.ResponseEmitter, env cmds.Environment cfg.Identity.PeerID, cfg.Addresses.Swarm, cfg.Identity.PrivKey, + libp2p.DHTOption, + ) + case routingOptionAutoClientKwd: + ncfg.Routing = libp2p.ConstructDefaultRouting( + cfg.Identity.PeerID, + cfg.Addresses.Swarm, + cfg.Identity.PrivKey, + libp2p.DHTClientOption, ) case routingOptionDHTClientKwd: ncfg.Routing = libp2p.DHTClientOption diff --git a/config/routing.go b/config/routing.go index f19414ff3..1210bb3ce 100644 --- a/config/routing.go +++ b/config/routing.go @@ -10,7 +10,7 @@ import ( type Routing struct { // Type sets default daemon routing mode. // - // Can be one of "auto", "dht", "dhtclient", "dhtserver", "none", or "custom". + // Can be one of "auto", "autoclient", "dht", "dhtclient", "dhtserver", "none", or "custom". // When unset or set to "auto", DHT and implicit routers are used. // When "custom" is set, user-provided Routing.Routers is used. Type *OptionalString `json:",omitempty"` diff --git a/core/node/libp2p/routingopt.go b/core/node/libp2p/routingopt.go index bfb45971c..d54f37acc 100644 --- a/core/node/libp2p/routingopt.go +++ b/core/node/libp2p/routingopt.go @@ -40,7 +40,7 @@ func init() { } // ConstructDefaultRouting returns routers used when Routing.Type is unset or set to "auto" -func ConstructDefaultRouting(peerID string, addrs []string, privKey string) func( +func ConstructDefaultRouting(peerID string, addrs []string, privKey string, routingOpt RoutingOption) func( ctx context.Context, host host.Host, dstore datastore.Batching, @@ -58,8 +58,7 @@ func ConstructDefaultRouting(peerID string, addrs []string, privKey string) func // Different trade-offs can be made by setting Routing.Type = "custom" with own Routing.Routers var routers []*routinghelpers.ParallelRouter - // Run the default DHT routing (same as Routing.Type = "dht") - dhtRouting, err := DHTOption(ctx, host, dstore, validator, bootstrapPeers...) + dhtRouting, err := routingOpt(ctx, host, dstore, validator, bootstrapPeers...) if err != nil { return nil, err } diff --git a/docs/changelogs/v0.19.md b/docs/changelogs/v0.19.md index 7663308a6..fede7a454 100644 --- a/docs/changelogs/v0.19.md +++ b/docs/changelogs/v0.19.md @@ -7,6 +7,7 @@ - [Overview](#overview) - [🔦 Highlights](#-highlights) - [Improving the libp2p resource management integration](#improving-the-libp2p-resource-management-integration) + - [Addition of "autoclient" router type](#addition-of-autoclient-router-type) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -22,6 +23,11 @@ and [0.18.1](https://github.com/ipfs/kubo/blob/master/docs/changelogs/v0.18.md#i - Note: we don't expect most users to need these capablities, but they are there if so. 1. [Doc updates](https://github.com/ipfs/kubo/blob/master/docs/libp2p-resource-management.md). +#### Addition of "autoclient" router type +A new routing type "autoclient" has been added. This mode is similar to "auto", in that it is a hybrid of content routers (including Kademlia and HTTP routers), but it does not run a DHT server. This is similar to the difference between "dhtclient" and "dht" router types. + +See the [Routing.Type documentation](https://github.com/ipfs/kubo/blob/master/docs/config.md#routingtype) for more information. + ### 📝 Changelog ### 👨‍👩‍👧‍👦 Contributors diff --git a/docs/config.md b/docs/config.md index 30a4e7601..de47e5445 100644 --- a/docs/config.md +++ b/docs/config.md @@ -1349,11 +1349,13 @@ Contains options for content, peer, and IPNS routing mechanisms. ### `Routing.Type` -There are multiple routing options: "auto", "none", "dht" and "custom". +There are multiple routing options: "auto", "autoclient", "none", "dht", "dhtclient", and "custom". * **DEFAULT:** If unset, or set to "auto", your node will use the IPFS DHT and parallel HTTP routers listed below for additional speed. +* If set to "autoclient", your node will behave as in "auto" but without running a DHT server. + * If set to "none", your node will use _no_ routing system. You'll have to explicitly connect to peers that have the content you're looking for. @@ -1379,7 +1381,7 @@ To force a specific DHT-only mode, client or server, set `Routing.Type` to `dhtclient` or `dhtserver` respectively. Please do not set this to `dhtserver` unless you're sure your node is reachable from the public network. -When `Routing.Type` is set to `auto` your node will accelerate some types of routing +When `Routing.Type` is set to `auto` or `autoclient` your node will accelerate some types of routing by leveraging HTTP endpoints compatible with [IPIP-337](https://github.com/ipfs/specs/pull/337) in addition to the IPFS DHT. By default, an instance of [IPNI](https://github.com/ipni/specs/blob/main/IPNI.md#readme) diff --git a/test/cli/delegated_routing_http_test.go b/test/cli/delegated_routing_http_test.go index 0b39a9b12..446ea5150 100644 --- a/test/cli/delegated_routing_http_test.go +++ b/test/cli/delegated_routing_http_test.go @@ -94,7 +94,7 @@ func TestHTTPDelegatedRouting(t *testing.T) { })) t.Cleanup(server.Close) - node.IPFS("config", "Routing.Type", "--json", `"custom"`) + node.IPFS("config", "Routing.Type", "custom") node.IPFS("config", "Routing.Routers.TestDelegatedRouter", "--json", ToJSONStr(JSONObj{ "Type": "http", "Parameters": JSONObj{ diff --git a/test/cli/dht_autoclient_test.go b/test/cli/dht_autoclient_test.go new file mode 100644 index 000000000..749e34b34 --- /dev/null +++ b/test/cli/dht_autoclient_test.go @@ -0,0 +1,39 @@ +package cli + +import ( + "bytes" + "testing" + + "github.com/ipfs/kubo/test/cli/harness" + "github.com/ipfs/kubo/test/cli/testutils" + "github.com/stretchr/testify/assert" +) + +func TestDHTAutoclient(t *testing.T) { + t.Parallel() + nodes := harness.NewT(t).NewNodes(10).Init() + harness.Nodes(nodes[8:]).ForEachPar(func(node *harness.Node) { + node.IPFS("config", "Routing.Type", "autoclient") + }) + nodes.StartDaemons().Connect() + + t.Run("file added on node in client mode is retrievable from node in client mode", func(t *testing.T) { + t.Parallel() + randomBytes := testutils.RandomBytes(1000) + hash := nodes[8].IPFSAdd(bytes.NewReader(randomBytes)) + + res := nodes[9].IPFS("cat", hash) + assert.Equal(t, randomBytes, []byte(res.Stdout.Trimmed())) + }) + + t.Run("file added on node in server mode is retrievable from all nodes", func(t *testing.T) { + t.Parallel() + randomBytes := testutils.RandomBytes(1000) + hash := nodes[0].IPFSAdd(bytes.NewReader(randomBytes)) + + for i := 0; i < 10; i++ { + res := nodes[i].IPFS("cat", hash) + assert.Equal(t, randomBytes, []byte(res.Stdout.Trimmed())) + } + }) +} From 6bab5ce37ca9a525a9ce16c21a1251947529e0e1 Mon Sep 17 00:00:00 2001 From: Laurent Senta Date: Thu, 9 Mar 2023 15:21:50 +0100 Subject: [PATCH 0552/1212] test: name --verify forgets the verified key --- test/sharness/t0100-name.sh | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/test/sharness/t0100-name.sh b/test/sharness/t0100-name.sh index 44c2afb2d..34f33ea4d 100755 --- a/test/sharness/t0100-name.sh +++ b/test/sharness/t0100-name.sh @@ -314,4 +314,32 @@ test_name_with_key 'rsa' test_name_with_key 'ed25519_b58' test_name_with_key 'ed25519_b36' + +# `ipfs name inspect --verify` using the wrong RSA key should not succeed + +test_init_ipfs +test_launch_ipfs_daemon + +test_expect_success "prepare RSA keys" ' + export KEY_1=`ipfs key gen --type=rsa --size=4096 key1` && + export KEY_2=`ipfs key gen --type=rsa --size=4096 key2` && + export PEERID_1=`ipfs key list --ipns-base=base36 -l | grep key1 | cut -d " " -f1` && + export PEERID_2=`ipfs key list --ipns-base=base36 -l | grep key2 | cut -d " " -f1` +' + +test_expect_success "ipfs name publish --allow-offline --key= ' succeeds" ' + ipfs name publish --allow-offline --key=${KEY_1} "/ipfs/$( echo "helloworld" | ipfs add --inline -q )" && + ipfs routing get "/ipns/$PEERID_1" > ipns_record +' + +test_expect_success "ipfs name inspect --verify' has '.Validation.Validity' set to 'true' with correct Peer ID" ' + ipfs name inspect --verify $PEERID_1 --enc json < ipns_record | jq -e ".Validation.Valid == true" +' + +test_expect_success "ipfs name inspect --verify' has '.Validation.Validity' set to 'false' when we verify the wrong Peer ID" ' + ipfs name inspect --verify $PEERID_2 --enc json < ipns_record | jq -e ".Validation.Valid == false" +' + +test_kill_ipfs_daemon + test_done From d001ed74513eab7aee0fbef5f3c5ea0d94ca43e9 Mon Sep 17 00:00:00 2001 From: Laurent Senta Date: Thu, 9 Mar 2023 15:23:52 +0100 Subject: [PATCH 0553/1212] fix: --verify forgets the verified key --- core/commands/name/name.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/core/commands/name/name.go b/core/commands/name/name.go index 7999aee3d..0e4fa6cb5 100644 --- a/core/commands/name/name.go +++ b/core/commands/name/name.go @@ -222,6 +222,20 @@ Passing --verify will verify signature against provided public key. // Peer ID. if len(entry.PubKey) > 0 { pub, err = ic.UnmarshalPublicKey(entry.PubKey) + if err != nil { + return err + } + + // Verify the public key matches the name we are verifying. + entryID, err := peer.IDFromPublicKey(pub) + + if err != nil { + return err + } + + if id != entryID { + return fmt.Errorf("record public key does not match the verified name") + } } } if err != nil { From 5f766619cf5c8856edc06139d4338753c444577c Mon Sep 17 00:00:00 2001 From: Eng Zer Jun Date: Wed, 10 Aug 2022 22:04:19 +0800 Subject: [PATCH 0554/1212] test: use `T.TempDir` to create temporary test directory This commit replaces `os.MkdirTemp` with `t.TempDir` in tests. The directory created by `t.TempDir` is automatically removed when the test and all its subtests complete. Prior to this commit, temporary directory created using `os.MkdirTemp` needs to be removed manually by calling `os.RemoveAll`, which is omitted in some tests. The error handling boilerplate e.g. defer func() { if err := os.RemoveAll(dir); err != nil { t.Fatal(err) } } is also tedious, but `t.TempDir` handles this for us nicely. Reference: https://pkg.go.dev/testing#T.TempDir Signed-off-by: Eng Zer Jun --- fuse/node/mount_test.go | 10 +++------- repo/fsrepo/config_test.go | 25 ++++--------------------- repo/fsrepo/fsrepo_test.go | 21 ++++++--------------- test/bench/bench_cli_ipfs_add/main.go | 7 +------ test/bench/offline_add/main.go | 6 +----- 5 files changed, 15 insertions(+), 54 deletions(-) diff --git a/fuse/node/mount_test.go b/fuse/node/mount_test.go index 12313ae3e..1691cfa5b 100644 --- a/fuse/node/mount_test.go +++ b/fuse/node/mount_test.go @@ -4,6 +4,7 @@ package node import ( + "context" "os" "strings" "testing" @@ -11,8 +12,6 @@ import ( "bazil.org/fuse" - "context" - core "github.com/ipfs/kubo/core" ipns "github.com/ipfs/kubo/fuse/ipns" mount "github.com/ipfs/kubo/fuse/mount" @@ -52,11 +51,8 @@ func TestExternalUnmount(t *testing.T) { t.Fatal(err) } - // get the test dir paths (/tmp/fusetestXXXX) - dir, err := os.MkdirTemp("", "fusetest") - if err != nil { - t.Fatal(err) - } + // get the test dir paths (/tmp/TestExternalUnmount) + dir := t.TempDir() ipfsDir := dir + "/ipfs" ipnsDir := dir + "/ipns" diff --git a/repo/fsrepo/config_test.go b/repo/fsrepo/config_test.go index 03af75a96..060d0222a 100644 --- a/repo/fsrepo/config_test.go +++ b/repo/fsrepo/config_test.go @@ -2,7 +2,6 @@ package fsrepo_test import ( "encoding/json" - "os" "reflect" "testing" @@ -88,11 +87,7 @@ func TestDefaultDatastoreConfig(t *testing.T) { t.Fatal(err) } - dir, err := os.MkdirTemp("", "ipfs-datastore-config-test") - if err != nil { - t.Fatal(err) - } - defer os.RemoveAll(dir) // clean up + dir := t.TempDir() config := new(config.Datastore) err = json.Unmarshal(defaultConfig, config) @@ -126,11 +121,7 @@ func TestLevelDbConfig(t *testing.T) { if err != nil { t.Fatal(err) } - dir, err := os.MkdirTemp("", "ipfs-datastore-config-test") - if err != nil { - t.Fatal(err) - } - defer os.RemoveAll(dir) // clean up + dir := t.TempDir() spec := make(map[string]interface{}) err = json.Unmarshal(leveldbConfig, &spec) @@ -164,11 +155,7 @@ func TestFlatfsConfig(t *testing.T) { if err != nil { t.Fatal(err) } - dir, err := os.MkdirTemp("", "ipfs-datastore-config-test") - if err != nil { - t.Fatal(err) - } - defer os.RemoveAll(dir) // clean up + dir := t.TempDir() spec := make(map[string]interface{}) err = json.Unmarshal(flatfsConfig, &spec) @@ -202,11 +189,7 @@ func TestMeasureConfig(t *testing.T) { if err != nil { t.Fatal(err) } - dir, err := os.MkdirTemp("", "ipfs-datastore-config-test") - if err != nil { - t.Fatal(err) - } - defer os.RemoveAll(dir) // clean up + dir := t.TempDir() spec := make(map[string]interface{}) err = json.Unmarshal(measureConfig, &spec) diff --git a/repo/fsrepo/fsrepo_test.go b/repo/fsrepo/fsrepo_test.go index 7c7551d20..6b30b107a 100644 --- a/repo/fsrepo/fsrepo_test.go +++ b/repo/fsrepo/fsrepo_test.go @@ -13,18 +13,9 @@ import ( config "github.com/ipfs/kubo/config" ) -// swap arg order -func testRepoPath(p string, t *testing.T) string { - name, err := os.MkdirTemp("", p) - if err != nil { - t.Fatal(err) - } - return name -} - func TestInitIdempotence(t *testing.T) { t.Parallel() - path := testRepoPath("", t) + path := t.TempDir() for i := 0; i < 10; i++ { assert.Nil(Init(path, &config.Config{Datastore: config.DefaultDatastoreConfig()}), t, "multiple calls to init should succeed") } @@ -37,8 +28,8 @@ func Remove(repoPath string) error { func TestCanManageReposIndependently(t *testing.T) { t.Parallel() - pathA := testRepoPath("a", t) - pathB := testRepoPath("b", t) + pathA := t.TempDir() + pathB := t.TempDir() t.Log("initialize two repos") assert.Nil(Init(pathA, &config.Config{Datastore: config.DefaultDatastoreConfig()}), t, "a", "should initialize successfully") @@ -65,7 +56,7 @@ func TestCanManageReposIndependently(t *testing.T) { func TestDatastoreGetNotAllowedAfterClose(t *testing.T) { t.Parallel() - path := testRepoPath("test", t) + path := t.TempDir() assert.True(!IsInitialized(path), t, "should NOT be initialized") assert.Nil(Init(path, &config.Config{Datastore: config.DefaultDatastoreConfig()}), t, "should initialize successfully") @@ -83,7 +74,7 @@ func TestDatastoreGetNotAllowedAfterClose(t *testing.T) { func TestDatastorePersistsFromRepoToRepo(t *testing.T) { t.Parallel() - path := testRepoPath("test", t) + path := t.TempDir() assert.Nil(Init(path, &config.Config{Datastore: config.DefaultDatastoreConfig()}), t) r1, err := Open(path) @@ -104,7 +95,7 @@ func TestDatastorePersistsFromRepoToRepo(t *testing.T) { func TestOpenMoreThanOnceInSameProcess(t *testing.T) { t.Parallel() - path := testRepoPath("", t) + path := t.TempDir() assert.Nil(Init(path, &config.Config{Datastore: config.DefaultDatastoreConfig()}), t) r1, err := Open(path) diff --git a/test/bench/bench_cli_ipfs_add/main.go b/test/bench/bench_cli_ipfs_add/main.go index a089410ef..e7fe90e04 100644 --- a/test/bench/bench_cli_ipfs_add/main.go +++ b/test/bench/bench_cli_ipfs_add/main.go @@ -45,12 +45,7 @@ func benchmarkAdd(amount int64) (*testing.BenchmarkResult, error) { b.SetBytes(amount) for i := 0; i < b.N; i++ { b.StopTimer() - tmpDir, err := os.MkdirTemp("", "") - if err != nil { - benchmarkError = err - b.Fatal(err) - } - defer os.RemoveAll(tmpDir) + tmpDir := b.TempDir() env := append( []string{fmt.Sprintf("%s=%s", config.EnvDir, path.Join(tmpDir, config.DefaultPathName))}, // first in order to override diff --git a/test/bench/offline_add/main.go b/test/bench/offline_add/main.go index a15ebcffd..338a5f6ac 100644 --- a/test/bench/offline_add/main.go +++ b/test/bench/offline_add/main.go @@ -37,11 +37,7 @@ func benchmarkAdd(amount int64) (*testing.BenchmarkResult, error) { b.SetBytes(amount) for i := 0; i < b.N; i++ { b.StopTimer() - tmpDir, err := os.MkdirTemp("", "") - if err != nil { - b.Fatal(err) - } - defer os.RemoveAll(tmpDir) + tmpDir := b.TempDir() env := append(os.Environ(), fmt.Sprintf("%s=%s", config.EnvDir, path.Join(tmpDir, config.DefaultPathName))) setupCmd := func(cmd *exec.Cmd) { From b4211be7d6147193882efb6e4da1aecabe71a563 Mon Sep 17 00:00:00 2001 From: Gus Eggert Date: Fri, 16 Dec 2022 06:55:03 -0500 Subject: [PATCH 0555/1212] test: port peering test from sharness to Go This is the slowest test in the sharness test suite, because it has very long sleeps. It usually takes 2+ minutes to run. This new impl runs all peering tests in about 20 seconds, since it polls for conditions instead of sleeping, and runs the tests in parallel. This also has an additional test case for a peer that was never online and then connects. --- test/cli/harness/harness.go | 21 +++++ test/cli/harness/log.go | 155 +++++++++++++++++++++++++++++++++ test/cli/harness/node.go | 25 +++++- test/cli/harness/nodes.go | 20 +---- test/cli/peering_test.go | 141 ++++++++++++++++++++++++++++++ test/cli/testutils/strings.go | 14 +++ test/sharness/t0171-peering.sh | 127 --------------------------- 7 files changed, 358 insertions(+), 145 deletions(-) create mode 100644 test/cli/harness/log.go create mode 100644 test/cli/peering_test.go delete mode 100755 test/sharness/t0171-peering.sh diff --git a/test/cli/harness/harness.go b/test/cli/harness/harness.go index a35fead35..e68116b5e 100644 --- a/test/cli/harness/harness.go +++ b/test/cli/harness/harness.go @@ -11,6 +11,8 @@ import ( logging "github.com/ipfs/go-log/v2" . "github.com/ipfs/kubo/test/cli/testutils" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/multiformats/go-multiaddr" ) // Harness tracks state for a test, such as temp dirs and IFPS nodes, and cleans them up after the test. @@ -188,3 +190,22 @@ func (h *Harness) Cleanup() { log.Panicf("removing temp dir %s: %s", h.Dir, err) } } + +// ExtractPeerID extracts a peer ID from the given multiaddr, and fatals if it does not contain a peer ID. +func (h *Harness) ExtractPeerID(m multiaddr.Multiaddr) peer.ID { + var peerIDStr string + multiaddr.ForEach(m, func(c multiaddr.Component) bool { + if c.Protocol().Code == multiaddr.P_P2P { + peerIDStr = c.Value() + } + return true + }) + if peerIDStr == "" { + panic(multiaddr.ErrProtocolNotFound) + } + peerID, err := peer.Decode(peerIDStr) + if err != nil { + panic(err) + } + return peerID +} diff --git a/test/cli/harness/log.go b/test/cli/harness/log.go new file mode 100644 index 000000000..d76bb2747 --- /dev/null +++ b/test/cli/harness/log.go @@ -0,0 +1,155 @@ +package harness + +import ( + "fmt" + "path/filepath" + "runtime" + "sort" + "strings" + "sync" + "testing" + "time" +) + +type event struct { + timestamp time.Time + msg string +} + +type events []*event + +func (e events) Len() int { return len(e) } +func (e events) Less(i, j int) bool { return e[i].timestamp.Before(e[j].timestamp) } +func (e events) Swap(i, j int) { e[i], e[j] = e[j], e[i] } + +// TestLogger is a logger for tests. +// It buffers output and only writes the output if the test fails or output is explicitly turned on. +// The purpose of this logger is to allow Go test to run with the verbose flag without printing logs. +// The verbose flag is useful since it streams test progress, but also printing logs makes the output too verbose. +// +// You can also add prefixes that are prepended to each log message, for extra logging context. +// +// This is implemented as a hierarchy of loggers, with children flushing log entries back to parents. +// This works because t.Cleanup() processes entries in LIFO order, so children always flush first. +// +// Obviously this logger should never be used in production systems. +type TestLogger struct { + parent *TestLogger + children []*TestLogger + prefixes []string + prefixesIface []any + t *testing.T + buf events + m sync.Mutex + logsEnabled bool +} + +func NewTestLogger(t *testing.T) *TestLogger { + l := &TestLogger{t: t, buf: make(events, 0)} + t.Cleanup(l.flush) + return l +} + +func (t *TestLogger) buildPrefix(timestamp time.Time) string { + d := timestamp.Format("2006-01-02T15:04:05.999999") + _, file, lineno, _ := runtime.Caller(2) + file = filepath.Base(file) + caller := fmt.Sprintf("%s:%d", file, lineno) + + if len(t.prefixes) == 0 { + return fmt.Sprintf("%s\t%s\t", d, caller) + } + + prefixes := strings.Join(t.prefixes, ":") + return fmt.Sprintf("%s\t%s\t%s: ", d, caller, prefixes) +} + +func (t *TestLogger) Log(args ...any) { + timestamp := time.Now() + e := t.buildPrefix(timestamp) + fmt.Sprint(args...) + t.add(&event{timestamp: timestamp, msg: e}) +} + +func (t *TestLogger) Logf(format string, args ...any) { + timestamp := time.Now() + e := t.buildPrefix(timestamp) + fmt.Sprintf(format, args...) + t.add(&event{timestamp: timestamp, msg: e}) +} + +func (t *TestLogger) Fatal(args ...any) { + timestamp := time.Now() + e := t.buildPrefix(timestamp) + fmt.Sprint(append([]any{"fatal: "}, args...)...) + t.add(&event{timestamp: timestamp, msg: e}) + t.t.FailNow() +} + +func (t *TestLogger) Fatalf(format string, args ...any) { + timestamp := time.Now() + e := t.buildPrefix(timestamp) + fmt.Sprintf(fmt.Sprintf("fatal: %s", format), args...) + t.add(&event{timestamp: timestamp, msg: e}) + t.t.FailNow() +} + +func (t *TestLogger) add(e *event) { + t.m.Lock() + defer t.m.Unlock() + t.buf = append(t.buf, e) +} + +func (t *TestLogger) AddPrefix(prefix string) *TestLogger { + l := &TestLogger{ + prefixes: append(t.prefixes, prefix), + prefixesIface: append(t.prefixesIface, prefix), + t: t.t, + parent: t, + logsEnabled: t.logsEnabled, + } + t.m.Lock() + defer t.m.Unlock() + + t.children = append(t.children, l) + t.t.Cleanup(l.flush) + + return l +} + +func (t *TestLogger) EnableLogs() { + t.m.Lock() + defer t.m.Unlock() + t.logsEnabled = true + if t.parent != nil { + if t.parent.logsEnabled { + t.parent.EnableLogs() + } + } + fmt.Printf("enabling %d children\n", len(t.children)) + for _, c := range t.children { + if !c.logsEnabled { + c.EnableLogs() + } + } +} + +func (t *TestLogger) flush() { + if t.t.Failed() || t.logsEnabled { + t.m.Lock() + defer t.m.Unlock() + // if this is a child, send the events to the parent + // the root parent will print all the events in sorted order + if t.parent != nil { + for _, e := range t.buf { + t.parent.add(e) + } + } else { + // we're the root, sort all the events and then print them + sort.Sort(t.buf) + fmt.Println() + fmt.Printf("Logs for test %q:\n\n", t.t.Name()) + for _, e := range t.buf { + fmt.Println(e.msg) + } + fmt.Println() + } + t.buf = nil + } +} diff --git a/test/cli/harness/node.go b/test/cli/harness/node.go index cc251e11b..f740ab1b1 100644 --- a/test/cli/harness/node.go +++ b/test/cli/harness/node.go @@ -453,9 +453,8 @@ func (n *Node) Peers() []multiaddr.Multiaddr { Path: n.IPFSBin, Args: []string{"swarm", "peers"}, }) - lines := strings.Split(strings.TrimSpace(res.Stdout.String()), "\n") var addrs []multiaddr.Multiaddr - for _, line := range lines { + for _, line := range res.Stdout.Lines() { ma, err := multiaddr.NewMultiaddr(line) if err != nil { panic(err) @@ -465,6 +464,28 @@ func (n *Node) Peers() []multiaddr.Multiaddr { return addrs } +func (n *Node) PeerWith(other *Node) { + n.UpdateConfig(func(cfg *config.Config) { + var addrs []multiaddr.Multiaddr + for _, addrStr := range other.ReadConfig().Addresses.Swarm { + ma, err := multiaddr.NewMultiaddr(addrStr) + if err != nil { + panic(err) + } + addrs = append(addrs, ma) + } + + cfg.Peering.Peers = append(cfg.Peering.Peers, peer.AddrInfo{ + ID: other.PeerID(), + Addrs: addrs, + }) + }) +} + +func (n *Node) Disconnect(other *Node) { + n.IPFS("swarm", "disconnect", "/p2p/"+other.PeerID().String()) +} + // GatewayURL waits for the gateway file and then returns its contents or times out. func (n *Node) GatewayURL() string { timer := time.NewTimer(1 * time.Second) diff --git a/test/cli/harness/nodes.go b/test/cli/harness/nodes.go index 872d77679..78662afbb 100644 --- a/test/cli/harness/nodes.go +++ b/test/cli/harness/nodes.go @@ -3,6 +3,7 @@ package harness import ( "sync" + . "github.com/ipfs/kubo/test/cli/testutils" "github.com/multiformats/go-multiaddr" "golang.org/x/sync/errgroup" ) @@ -11,9 +12,7 @@ import ( type Nodes []*Node func (n Nodes) Init(args ...string) Nodes { - for _, node := range n { - node.Init() - } + ForEachPar(n, func(node *Node) { node.Init(args...) }) return n } @@ -59,22 +58,11 @@ func (n Nodes) Connect() Nodes { } func (n Nodes) StartDaemons() Nodes { - wg := sync.WaitGroup{} - for _, node := range n { - wg.Add(1) - node := node - go func() { - defer wg.Done() - node.StartDaemon() - }() - } - wg.Wait() + ForEachPar(n, func(node *Node) { node.StartDaemon() }) return n } func (n Nodes) StopDaemons() Nodes { - for _, node := range n { - node.StopDaemon() - } + ForEachPar(n, func(node *Node) { node.StopDaemon() }) return n } diff --git a/test/cli/peering_test.go b/test/cli/peering_test.go new file mode 100644 index 000000000..f3e797fae --- /dev/null +++ b/test/cli/peering_test.go @@ -0,0 +1,141 @@ +package cli + +import ( + "fmt" + "math/rand" + "testing" + "time" + + "github.com/ipfs/kubo/config" + "github.com/ipfs/kubo/test/cli/harness" + . "github.com/ipfs/kubo/test/cli/testutils" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/stretchr/testify/assert" +) + +func TestPeering(t *testing.T) { + t.Parallel() + + type peering struct { + from int + to int + } + + newRandPort := func() int { + n := rand.Int() + return 3000 + (n % 1000) + } + + containsPeerID := func(p peer.ID, peers []peer.ID) bool { + for _, peerID := range peers { + if p == peerID { + return true + } + } + return false + } + + assertPeered := func(h *harness.Harness, from *harness.Node, to *harness.Node) { + assert.Eventuallyf(t, func() bool { + fromPeers := from.Peers() + if len(fromPeers) == 0 { + return false + } + var fromPeerIDs []peer.ID + for _, p := range fromPeers { + fromPeerIDs = append(fromPeerIDs, h.ExtractPeerID(p)) + } + return containsPeerID(to.PeerID(), fromPeerIDs) + }, 20*time.Second, 10*time.Millisecond, "%d -> %d not peered", from.ID, to.ID) + } + + assertNotPeered := func(h *harness.Harness, from *harness.Node, to *harness.Node) { + assert.Eventuallyf(t, func() bool { + fromPeers := from.Peers() + if len(fromPeers) == 0 { + return false + } + var fromPeerIDs []peer.ID + for _, p := range fromPeers { + fromPeerIDs = append(fromPeerIDs, h.ExtractPeerID(p)) + } + return !containsPeerID(to.PeerID(), fromPeerIDs) + }, 20*time.Second, 10*time.Millisecond, "%d -> %d peered", from.ID, to.ID) + } + + assertPeerings := func(h *harness.Harness, nodes []*harness.Node, peerings []peering) { + ForEachPar(peerings, func(peering peering) { + assertPeered(h, nodes[peering.from], nodes[peering.to]) + }) + } + + createNodes := func(t *testing.T, n int, peerings []peering) (*harness.Harness, harness.Nodes) { + h := harness.NewT(t) + nodes := h.NewNodes(n).Init() + nodes.ForEachPar(func(node *harness.Node) { + node.UpdateConfig(func(cfg *config.Config) { + cfg.Routing.Type = config.NewOptionalString("none") + cfg.Addresses.Swarm = []string{fmt.Sprintf("/ip4/127.0.0.1/tcp/%d", newRandPort())} + }) + + }) + + for _, peering := range peerings { + nodes[peering.from].PeerWith(nodes[peering.to]) + } + + return h, nodes + } + + t.Run("bidirectional peering should work (simultaneous connect)", func(t *testing.T) { + t.Parallel() + peerings := []peering{{from: 0, to: 1}, {from: 1, to: 0}, {from: 1, to: 2}} + h, nodes := createNodes(t, 3, peerings) + + nodes.StartDaemons() + assertPeerings(h, nodes, peerings) + + nodes[0].Disconnect(nodes[1]) + assertPeerings(h, nodes, peerings) + }) + + t.Run("1 should reconnect to 2 when 2 disconnects from 1", func(t *testing.T) { + t.Parallel() + peerings := []peering{{from: 0, to: 1}, {from: 1, to: 0}, {from: 1, to: 2}} + h, nodes := createNodes(t, 3, peerings) + + nodes.StartDaemons() + assertPeerings(h, nodes, peerings) + + nodes[2].Disconnect(nodes[1]) + assertPeerings(h, nodes, peerings) + }) + + t.Run("1 will peer with 2 when it comes online", func(t *testing.T) { + t.Parallel() + peerings := []peering{{from: 0, to: 1}, {from: 1, to: 0}, {from: 1, to: 2}} + h, nodes := createNodes(t, 3, peerings) + + nodes[0].StartDaemon() + nodes[1].StartDaemon() + assertPeerings(h, nodes, []peering{{from: 0, to: 1}, {from: 1, to: 0}}) + + nodes[2].StartDaemon() + assertPeerings(h, nodes, peerings) + }) + + t.Run("1 will re-peer with 2 when it disconnects and then comes back online", func(t *testing.T) { + t.Parallel() + peerings := []peering{{from: 0, to: 1}, {from: 1, to: 0}, {from: 1, to: 2}} + h, nodes := createNodes(t, 3, peerings) + + nodes.StartDaemons() + assertPeerings(h, nodes, peerings) + + nodes[2].StopDaemon() + assertNotPeered(h, nodes[1], nodes[2]) + + nodes[2].StartDaemon() + assertPeerings(h, nodes, peerings) + }) +} diff --git a/test/cli/testutils/strings.go b/test/cli/testutils/strings.go index 1fb151248..110051e67 100644 --- a/test/cli/testutils/strings.go +++ b/test/cli/testutils/strings.go @@ -7,6 +7,7 @@ import ( "net/netip" "net/url" "strings" + "sync" "github.com/multiformats/go-multiaddr" manet "github.com/multiformats/go-multiaddr/net" @@ -75,3 +76,16 @@ func URLStrToMultiaddr(u string) multiaddr.Multiaddr { } return ma } + +// ForEachPar invokes f in a new goroutine for each element of s and waits for all to complete. +func ForEachPar[T any](s []T, f func(T)) { + wg := sync.WaitGroup{} + wg.Add(len(s)) + for _, x := range s { + go func(x T) { + defer wg.Done() + f(x) + }(x) + } + wg.Wait() +} diff --git a/test/sharness/t0171-peering.sh b/test/sharness/t0171-peering.sh deleted file mode 100755 index 207b27980..000000000 --- a/test/sharness/t0171-peering.sh +++ /dev/null @@ -1,127 +0,0 @@ -#!/usr/bin/env bash - -test_description="Test peering service" - -. lib/test-lib.sh - -NUM_NODES=3 - -test_expect_success 'init iptb' ' - rm -rf .iptb/ && - iptb testbed create -type localipfs -count $NUM_NODES -init -' - -test_expect_success 'disabling routing' ' - iptb run -- ipfs config Routing.Type none -' - -for i in $(seq 0 2); do - ADDR="$(printf '["/ip4/127.0.0.1/tcp/%s"]' "$(( 3000 + ( RANDOM % 1000 ) ))")" - test_expect_success "configuring node $i to listen on $ADDR" ' - ipfsi "$i" config --json Addresses.Swarm "$ADDR" - ' -done - -peer_id() { - ipfsi "$1" config Identity.PeerID -} - -peer_addrs() { - ipfsi "$1" config Addresses.Swarm -} - -peer() { - PEER1="$1" && - PEER2="$2" && - PEER_LIST="$(ipfsi "$PEER1" config Peering.Peers || true)" && - { [[ "$PEER_LIST" == "null" ]] || PEER_LIST_INNER="${PEER_LIST:1:-1}"; } && - ADDR_INFO="$(printf '[%s{"ID": "%s", "Addrs": %s}]' \ - "${PEER_LIST_INNER:+${PEER_LIST_INNER},}" \ - "$(peer_id "$PEER2")" \ - "$(peer_addrs "$PEER2")")" && - ipfsi "$PEER1" config --json Peering.Peers "${ADDR_INFO}" -} - -# Peer: -# - 0 <-> 1 -# - 1 -> 2 -test_expect_success 'configure peering' ' - peer 0 1 && - peer 1 0 && - peer 1 2 -' - -list_peers() { - ipfsi "$1" swarm peers | sed 's|.*/p2p/\([^/]*\)$|\1|' | sort -u -} - -check_peers() { - sleep 20 # give it some time to settle. - test_expect_success 'verifying peering for peer 0' ' - list_peers 0 > peers_0_actual && - peer_id 1 > peers_0_expected && - test_cmp peers_0_expected peers_0_actual - ' - - test_expect_success 'verifying peering for peer 1' ' - list_peers 1 > peers_1_actual && - { peer_id 0 && peer_id 2 ; } | sort -u > peers_1_expected && - test_cmp peers_1_expected peers_1_actual - ' - - test_expect_success 'verifying peering for peer 2' ' - list_peers 2 > peers_2_actual && - peer_id 1 > peers_2_expected && - test_cmp peers_2_expected peers_2_actual - ' -} - -test_expect_success 'startup cluster' ' - iptb start -wait && - iptb run -- ipfs log level peering debug -' - -check_peers - -disconnect() { - ipfsi "$1" swarm disconnect "/p2p/$(peer_id "$2")" -} - -# Bidirectional peering shouldn't cause problems (e.g., simultaneous connect -# issues). -test_expect_success 'disconnecting 0->1' ' - disconnect 0 1 -' - -check_peers - -# 1 should reconnect to 2 when 2 disconnects from 1. -test_expect_success 'disconnecting 2->1' ' - disconnect 2 1 -' - -check_peers - -# 2 isn't peering. This test ensures that 1 will re-peer with 2 when it comes -# back online. -test_expect_success 'stopping 2' ' - iptb stop 2 -' - -# Wait to disconnect -sleep 30 - -test_expect_success 'starting 2' ' - iptb start 2 -' - -# Wait for backoff -sleep 30 - -check_peers - -test_expect_success "stop testbed" ' - iptb stop -' - -test_done From cc5e1325b4646e0eb651a63ad04ac86086d2589b Mon Sep 17 00:00:00 2001 From: Jorropo Date: Wed, 15 Mar 2023 03:23:41 +0100 Subject: [PATCH 0556/1212] chore: deprecate the pubsub api Fixes #9717 --- README.md | 3 +-- cmd/ipfs/daemon.go | 2 +- core/commands/pubsub.go | 20 ++++++++++---------- docs/changelogs/v0.19.md | 7 +++++++ docs/config.md | 12 +++++++++++- docs/experimental-features.md | 31 ------------------------------- 6 files changed, 30 insertions(+), 45 deletions(-) diff --git a/README.md b/README.md index e734fef66..94e5e42af 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ Kubo was the first IPFS implementation and is the most widely used one today. Im Featureset - Runs an IPFS-Node as a network service - [Command Line Interface](https://docs.ipfs.tech/reference/kubo/cli/) to IPFS-Nodes -- Local [Web2-to-Web3 HTTP Gateway functionality](https://github.com/ipfs/specs/tree/main/http-gateways#readme) +- Local [Web2-to-Web3 HTTP Gateway functionality](https://github.com/ipfs/specs/tree/main/http-gateways#readme) - HTTP RPC API (`/api/v0`) to access and control the daemon - IPFS's internal Webgui can be used to manage the Kubo nodes @@ -381,7 +381,6 @@ Some places to get you started on the codebase: - libp2p - libp2p: https://github.com/libp2p/go-libp2p - DHT: https://github.com/libp2p/go-libp2p-kad-dht - - PubSub: https://github.com/libp2p/go-libp2p-pubsub - [IPFS : The `Add` command demystified](https://github.com/ipfs/kubo/tree/master/docs/add-code-flow.md) ### Map of Implemented Subsystems diff --git a/cmd/ipfs/daemon.go b/cmd/ipfs/daemon.go index 880d26b0e..52addcc07 100644 --- a/cmd/ipfs/daemon.go +++ b/cmd/ipfs/daemon.go @@ -171,7 +171,7 @@ Headers. cmds.BoolOption(enableGCKwd, "Enable automatic periodic repo garbage collection"), cmds.BoolOption(adjustFDLimitKwd, "Check and raise file descriptor limits if needed").WithDefault(true), cmds.BoolOption(migrateKwd, "If true, assume yes at the migrate prompt. If false, assume no."), - cmds.BoolOption(enablePubSubKwd, "Enable experimental pubsub feature. Overrides Pubsub.Enabled config."), + cmds.BoolOption(enablePubSubKwd, "DEPRECATED"), cmds.BoolOption(enableIPNSPubSubKwd, "Enable IPNS over pubsub. Implicitly enables pubsub, overrides Ipns.UsePubsub config."), cmds.BoolOption(enableMultiplexKwd, "DEPRECATED"), cmds.StringOption(agentVersionSuffix, "Optional suffix to the AgentVersion presented by `ipfs id` and also advertised through BitSwap."), diff --git a/core/commands/pubsub.go b/core/commands/pubsub.go index ef8afcb44..ee795e078 100644 --- a/core/commands/pubsub.go +++ b/core/commands/pubsub.go @@ -16,14 +16,14 @@ import ( ) var PubsubCmd = &cmds.Command{ - Status: cmds.Experimental, + Status: cmds.Deprecated, Helptext: cmds.HelpText{ Tagline: "An experimental publish-subscribe system on ipfs.", ShortDescription: ` ipfs pubsub allows you to publish messages to a given topic, and also to subscribe to new messages on a given topic. -EXPERIMENTAL FEATURE +DEPRECATED FEATURE (see https://github.com/ipfs/kubo/issues/9717) It is not intended in its current state to be used in a production environment. To use, the daemon must be run with @@ -46,13 +46,13 @@ type pubsubMessage struct { } var PubsubSubCmd = &cmds.Command{ - Status: cmds.Experimental, + Status: cmds.Deprecated, Helptext: cmds.HelpText{ Tagline: "Subscribe to messages on a given topic.", ShortDescription: ` ipfs pubsub sub subscribes to messages on a given topic. -EXPERIMENTAL FEATURE +DEPRECATED FEATURE (see https://github.com/ipfs/kubo/issues/9717) It is not intended in its current state to be used in a production environment. To use, the daemon must be run with @@ -145,14 +145,14 @@ TOPIC AND DATA ENCODING } var PubsubPubCmd = &cmds.Command{ - Status: cmds.Experimental, + Status: cmds.Deprecated, Helptext: cmds.HelpText{ Tagline: "Publish data to a given pubsub topic.", ShortDescription: ` ipfs pubsub pub publishes a message to a specified topic. It reads binary data from stdin or a file. -EXPERIMENTAL FEATURE +DEPRECATED FEATURE (see https://github.com/ipfs/kubo/issues/9717) It is not intended in its current state to be used in a production environment. To use, the daemon must be run with @@ -201,13 +201,13 @@ HTTP RPC ENCODING } var PubsubLsCmd = &cmds.Command{ - Status: cmds.Experimental, + Status: cmds.Deprecated, Helptext: cmds.HelpText{ Tagline: "List subscribed topics by name.", ShortDescription: ` ipfs pubsub ls lists out the names of topics you are currently subscribed to. -EXPERIMENTAL FEATURE +DEPRECATED FEATURE (see https://github.com/ipfs/kubo/issues/9717) It is not intended in its current state to be used in a production environment. To use, the daemon must be run with @@ -273,7 +273,7 @@ func safeTextListEncoder(req *cmds.Request, w io.Writer, list *stringList) error } var PubsubPeersCmd = &cmds.Command{ - Status: cmds.Experimental, + Status: cmds.Deprecated, Helptext: cmds.HelpText{ Tagline: "List peers we are currently pubsubbing with.", ShortDescription: ` @@ -281,7 +281,7 @@ ipfs pubsub peers with no arguments lists out the pubsub peers you are currently connected to. If given a topic, it will list connected peers who are subscribed to the named topic. -EXPERIMENTAL FEATURE +DEPRECATED FEATURE (see https://github.com/ipfs/kubo/issues/9717) It is not intended in its current state to be used in a production environment. To use, the daemon must be run with diff --git a/docs/changelogs/v0.19.md b/docs/changelogs/v0.19.md index fede7a454..12331cae7 100644 --- a/docs/changelogs/v0.19.md +++ b/docs/changelogs/v0.19.md @@ -8,6 +8,7 @@ - [🔦 Highlights](#-highlights) - [Improving the libp2p resource management integration](#improving-the-libp2p-resource-management-integration) - [Addition of "autoclient" router type](#addition-of-autoclient-router-type) + - [Deprecation of the `ipfs pubsub` commands and matching HTTP endpoints](#deprecation-of-the-ipfs-pubsub-commands-and-matching-http-endpoints) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -28,6 +29,12 @@ A new routing type "autoclient" has been added. This mode is similar to "auto", See the [Routing.Type documentation](https://github.com/ipfs/kubo/blob/master/docs/config.md#routingtype) for more information. +#### Deprecation of the `ipfs pubsub` commands and matching HTTP endpoints + +We are deprecating `ipfs pubsub` and all `/api/v0/pubsub/` RPC endpoints and will remove them in the next release. + +For more information and rational see [#9717](https://github.com/ipfs/kubo/issues/9717). + ### 📝 Changelog ### 👨‍👩‍👧‍👦 Contributors diff --git a/docs/config.md b/docs/config.md index de47e5445..28331c2ae 100644 --- a/docs/config.md +++ b/docs/config.md @@ -1165,13 +1165,15 @@ Type: `duration` ## `Pubsub` +**DEPRECATED**: See [#9717](https://github.com/ipfs/kubo/issues/9717) + Pubsub configures the `ipfs pubsub` subsystem. To use, it must be enabled by passing the `--enable-pubsub-experiment` flag to the daemon or via the `Pubsub.Enabled` flag below. ### `Pubsub.Enabled` -**EXPERIMENTAL:** read about current limitations at [experimental-features.md#ipfs-pubsub](./experimental-features.md#ipfs-pubsub). +**DEPRECATED**: See [#9717](https://github.com/ipfs/kubo/issues/9717) Enables the pubsub system. @@ -1181,6 +1183,8 @@ Type: `flag` ### `Pubsub.Router` +**DEPRECATED**: See [#9717](https://github.com/ipfs/kubo/issues/9717) + Sets the default router used by pubsub to route messages to peers. This can be one of: * `"floodsub"` - floodsub is a basic router that simply _floods_ messages to all @@ -1196,6 +1200,8 @@ Type: `string` (one of `"floodsub"`, `"gossipsub"`, or `""` (apply default)) ### `Pubsub.DisableSigning` +**DEPRECATED**: See [#9717](https://github.com/ipfs/kubo/issues/9717) + Disables message signing and signature verification. Enable this option if you're operating in a completely trusted network. @@ -1209,6 +1215,8 @@ Type: `bool` ### `Pubsub.SeenMessagesTTL` +**DEPRECATED**: See [#9717](https://github.com/ipfs/kubo/issues/9717) + Controls the time window within which duplicate messages, identified by Message ID, will be identified and won't be emitted again. @@ -1228,6 +1236,8 @@ Type: `optionalDuration` ### `Pubsub.SeenMessagesStrategy` +**DEPRECATED**: See [#9717](https://github.com/ipfs/kubo/issues/9717) + Determines how the time-to-live (TTL) countdown for deduplicating Pubsub messages is calculated. diff --git a/docs/experimental-features.md b/docs/experimental-features.md index 41e72f1df..296f6ca1e 100644 --- a/docs/experimental-features.md +++ b/docs/experimental-features.md @@ -12,7 +12,6 @@ When you add a new experimental feature to kubo or change an experimental feature, you MUST please make a PR updating this document, and link the PR in the above issue. -- [ipfs pubsub](#ipfs-pubsub) - [Raw leaves for unixfs files](#raw-leaves-for-unixfs-files) - [ipfs filestore](#ipfs-filestore) - [ipfs urlstore](#ipfs-urlstore) @@ -31,36 +30,6 @@ the above issue. --- -## ipfs pubsub - -### State - -Candidate, disabled by default but will be enabled by default in 0.6.0. - -### In Version - -0.4.5 (`--enable-pubsub-experiment`) -0.11.0 (`Pubsub.Enabled` flag in config) - -### How to enable - -Run your daemon with the `--enable-pubsub-experiment` flag -or modify your ipfs config and restart the daemon: -``` -ipfs config --json Pubsub.Enabled true -``` - -Then use the `ipfs pubsub` commands. - -NOTE: `--enable-pubsub-experiment` CLI flag overrides `Pubsub.Enabled` config. - -Configuration documentation can be found in [kubo/docs/config.md](./config.md#pubsub) - -### Road to being a real feature - -- [ ] Needs to not impact peers who don't use pubsub: - https://github.com/libp2p/go-libp2p-pubsub/issues/332 - ## Raw Leaves for unixfs files Allows files to be added with no formatting in the leaf nodes of the graph. From c78c9886ad1c647f33846908b4bf01ecc769cb12 Mon Sep 17 00:00:00 2001 From: Gus Eggert Date: Wed, 15 Mar 2023 14:57:23 -0400 Subject: [PATCH 0557/1212] test: fix flaky rcmgr test --- test/cli/rcmgr_test.go | 6 +++++- test/cli/testutils/asserts.go | 15 +++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 test/cli/testutils/asserts.go diff --git a/test/cli/rcmgr_test.go b/test/cli/rcmgr_test.go index 51b2b0452..9d76a7dd8 100644 --- a/test/cli/rcmgr_test.go +++ b/test/cli/rcmgr_test.go @@ -7,6 +7,7 @@ import ( "github.com/ipfs/kubo/config" "github.com/ipfs/kubo/core/node/libp2p" "github.com/ipfs/kubo/test/cli/harness" + "github.com/ipfs/kubo/test/cli/testutils" "github.com/libp2p/go-libp2p/core/peer" "github.com/libp2p/go-libp2p/core/protocol" rcmgr "github.com/libp2p/go-libp2p/p2p/host/resource-manager" @@ -209,7 +210,10 @@ func TestRcmgr(t *testing.T) { Args: []string{"swarm", "connect", node1.SwarmAddrsWithPeerIDs()[0].String()}, }) assert.Equal(t, 1, res.ExitCode()) - assert.Contains(t, res.Stderr.String(), "failed to find any peer in table") + testutils.AssertStringContainsOneOf(t, res.Stderr.String(), + "failed to find any peer in table", + "resource limit exceeded", + ) res = node0.RunIPFS("ping", "-n2", peerID1) assert.Equal(t, 1, res.ExitCode()) diff --git a/test/cli/testutils/asserts.go b/test/cli/testutils/asserts.go new file mode 100644 index 000000000..cf840c20e --- /dev/null +++ b/test/cli/testutils/asserts.go @@ -0,0 +1,15 @@ +package testutils + +import ( + "strings" + "testing" +) + +func AssertStringContainsOneOf(t *testing.T, str string, ss ...string) { + for _, s := range ss { + if strings.Contains(str, s) { + return + } + } + t.Errorf("%q does not contain one of %v", str, ss) +} From 6ff764f9fb1bfbff2625f46c732d3515b0443c70 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Wed, 15 Mar 2023 04:40:16 +0100 Subject: [PATCH 0558/1212] fix: preserve Unlimited StreamsInbound in connmgr reconciliation Fixes #9695 --- core/node/libp2p/rcmgr.go | 4 ++++ core/node/libp2p/rcmgr_defaults.go | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/core/node/libp2p/rcmgr.go b/core/node/libp2p/rcmgr.go index 54bff2852..3e1624531 100644 --- a/core/node/libp2p/rcmgr.go +++ b/core/node/libp2p/rcmgr.go @@ -459,6 +459,7 @@ func ensureConnMgrMakeSenseVsResourceMgr(concreteLimits rcmgr.ConcreteLimitConfi return fmt.Errorf(` Unable to initialize libp2p due to conflicting resource manager limit configuration. resource manager System.Conns (%d) must be bigger than ConnMgr.HighWater (%d) +See: https://github.com/ipfs/kubo/blob/master/docs/libp2p-resource-management.md#how-does-the-resource-manager-resourcemgr-relate-to-the-connection-manager-connmgr `, rcm.System.Conns, highWater) } if rcm.System.ConnsInbound != rcmgr.Unlimited && int64(rcm.System.ConnsInbound) <= highWater { @@ -466,6 +467,7 @@ resource manager System.Conns (%d) must be bigger than ConnMgr.HighWater (%d) return fmt.Errorf(` Unable to initialize libp2p due to conflicting resource manager limit configuration. resource manager System.ConnsInbound (%d) must be bigger than ConnMgr.HighWater (%d) +See: https://github.com/ipfs/kubo/blob/master/docs/libp2p-resource-management.md#how-does-the-resource-manager-resourcemgr-relate-to-the-connection-manager-connmgr `, rcm.System.ConnsInbound, highWater) } if rcm.System.Streams != rcmgr.Unlimited && int64(rcm.System.Streams) <= highWater { @@ -473,6 +475,7 @@ resource manager System.ConnsInbound (%d) must be bigger than ConnMgr.HighWater return fmt.Errorf(` Unable to initialize libp2p due to conflicting resource manager limit configuration. resource manager System.Streams (%d) must be bigger than ConnMgr.HighWater (%d) +See: https://github.com/ipfs/kubo/blob/master/docs/libp2p-resource-management.md#how-does-the-resource-manager-resourcemgr-relate-to-the-connection-manager-connmgr `, rcm.System.Streams, highWater) } if rcm.System.StreamsInbound != rcmgr.Unlimited && int64(rcm.System.StreamsInbound) <= highWater { @@ -480,6 +483,7 @@ resource manager System.Streams (%d) must be bigger than ConnMgr.HighWater (%d) return fmt.Errorf(` Unable to initialize libp2p due to conflicting resource manager limit configuration. resource manager System.StreamsInbound (%d) must be bigger than ConnMgr.HighWater (%d) +See: https://github.com/ipfs/kubo/blob/master/docs/libp2p-resource-management.md#how-does-the-resource-manager-resourcemgr-relate-to-the-connection-manager-connmgr `, rcm.System.StreamsInbound, highWater) } return nil diff --git a/core/node/libp2p/rcmgr_defaults.go b/core/node/libp2p/rcmgr_defaults.go index 5faaf7979..4f02c6b4a 100644 --- a/core/node/libp2p/rcmgr_defaults.go +++ b/core/node/libp2p/rcmgr_defaults.go @@ -129,7 +129,9 @@ func createDefaultLimitConfig(cfg config.SwarmConfig) (limitConfig rcmgr.Concret } // Scale System.StreamsInbound as well, but use the existing ratio of StreamsInbound to ConnsInbound - partialLimits.System.StreamsInbound = rcmgr.LimitVal(maxInboundConns * int64(partialLimits.System.StreamsInbound) / int64(partialLimits.System.ConnsInbound)) + if partialLimits.System.StreamsInbound != rcmgr.Unlimited { + partialLimits.System.StreamsInbound = rcmgr.LimitVal(maxInboundConns * int64(partialLimits.System.StreamsInbound) / int64(partialLimits.System.ConnsInbound)) + } partialLimits.System.ConnsInbound = rcmgr.LimitVal(maxInboundConns) } From 383065397deafc7031aaa9ddad69c450400c3e2b Mon Sep 17 00:00:00 2001 From: Jorropo Date: Wed, 15 Mar 2023 17:36:08 +0100 Subject: [PATCH 0559/1212] test: add test for presarvation of unlimited configs for inbound systems --- test/cli/rcmgr_test.go | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/test/cli/rcmgr_test.go b/test/cli/rcmgr_test.go index 9d76a7dd8..3dbceb5d7 100644 --- a/test/cli/rcmgr_test.go +++ b/test/cli/rcmgr_test.go @@ -127,6 +127,22 @@ func TestRcmgr(t *testing.T) { }) }) + t.Run("smoke test unlimited System inbounds", func(t *testing.T) { + t.Parallel() + node := harness.NewT(t).NewNode().Init() + node.UpdateUserSuppliedResourceManagerOverrides(func(overrides *rcmgr.PartialLimitConfig) { + overrides.System.StreamsInbound = rcmgr.Unlimited + overrides.System.ConnsInbound = rcmgr.Unlimited + }) + node.StartDaemon() + + res := node.RunIPFS("swarm", "resources", "--enc=json") + limits := unmarshalLimits(t, res.Stdout.Bytes()) + + assert.Equal(t, rcmgr.Unlimited, limits.System.ConnsInbound) + assert.Equal(t, rcmgr.Unlimited, limits.System.StreamsInbound) + }) + t.Run("smoke test transient scope", func(t *testing.T) { t.Parallel() node := harness.NewT(t).NewNode().Init() From af79d841dcd1429980d20a5427949f1afea8b11f Mon Sep 17 00:00:00 2001 From: Jorropo Date: Wed, 15 Mar 2023 17:40:12 +0100 Subject: [PATCH 0560/1212] fix: future proof with > rcmgr.DefaultLimit for new enum rcmgr values --- core/node/libp2p/rcmgr.go | 8 ++++---- core/node/libp2p/rcmgr_defaults.go | 4 ++-- test/cli/rcmgr_test.go | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/core/node/libp2p/rcmgr.go b/core/node/libp2p/rcmgr.go index 3e1624531..c61f8dcfe 100644 --- a/core/node/libp2p/rcmgr.go +++ b/core/node/libp2p/rcmgr.go @@ -454,7 +454,7 @@ func ensureConnMgrMakeSenseVsResourceMgr(concreteLimits rcmgr.ConcreteLimitConfi rcm := concreteLimits.ToPartialLimitConfig() highWater := cfg.ConnMgr.HighWater.WithDefault(config.DefaultConnMgrHighWater) - if rcm.System.Conns != rcmgr.Unlimited && int64(rcm.System.Conns) <= highWater { + if (rcm.System.Conns > rcmgr.DefaultLimit || rcm.System.Conns == rcmgr.BlockAllLimit) && int64(rcm.System.Conns) <= highWater { // nolint return fmt.Errorf(` Unable to initialize libp2p due to conflicting resource manager limit configuration. @@ -462,7 +462,7 @@ resource manager System.Conns (%d) must be bigger than ConnMgr.HighWater (%d) See: https://github.com/ipfs/kubo/blob/master/docs/libp2p-resource-management.md#how-does-the-resource-manager-resourcemgr-relate-to-the-connection-manager-connmgr `, rcm.System.Conns, highWater) } - if rcm.System.ConnsInbound != rcmgr.Unlimited && int64(rcm.System.ConnsInbound) <= highWater { + if (rcm.System.ConnsInbound > rcmgr.DefaultLimit || rcm.System.ConnsInbound == rcmgr.BlockAllLimit) && int64(rcm.System.ConnsInbound) <= highWater { // nolint return fmt.Errorf(` Unable to initialize libp2p due to conflicting resource manager limit configuration. @@ -470,7 +470,7 @@ resource manager System.ConnsInbound (%d) must be bigger than ConnMgr.HighWater See: https://github.com/ipfs/kubo/blob/master/docs/libp2p-resource-management.md#how-does-the-resource-manager-resourcemgr-relate-to-the-connection-manager-connmgr `, rcm.System.ConnsInbound, highWater) } - if rcm.System.Streams != rcmgr.Unlimited && int64(rcm.System.Streams) <= highWater { + if rcm.System.Streams > rcmgr.DefaultLimit || rcm.System.Streams == rcmgr.BlockAllLimit && int64(rcm.System.Streams) <= highWater { // nolint return fmt.Errorf(` Unable to initialize libp2p due to conflicting resource manager limit configuration. @@ -478,7 +478,7 @@ resource manager System.Streams (%d) must be bigger than ConnMgr.HighWater (%d) See: https://github.com/ipfs/kubo/blob/master/docs/libp2p-resource-management.md#how-does-the-resource-manager-resourcemgr-relate-to-the-connection-manager-connmgr `, rcm.System.Streams, highWater) } - if rcm.System.StreamsInbound != rcmgr.Unlimited && int64(rcm.System.StreamsInbound) <= highWater { + if (rcm.System.StreamsInbound > rcmgr.DefaultLimit || rcm.System.StreamsInbound == rcmgr.BlockAllLimit) && int64(rcm.System.StreamsInbound) <= highWater { // nolint return fmt.Errorf(` Unable to initialize libp2p due to conflicting resource manager limit configuration. diff --git a/core/node/libp2p/rcmgr_defaults.go b/core/node/libp2p/rcmgr_defaults.go index 4f02c6b4a..7a0e5a282 100644 --- a/core/node/libp2p/rcmgr_defaults.go +++ b/core/node/libp2p/rcmgr_defaults.go @@ -118,7 +118,7 @@ func createDefaultLimitConfig(cfg config.SwarmConfig) (limitConfig rcmgr.Concret // There are ways to break this, but this should catch most problems already. // We might improve this in the future. // See: https://github.com/ipfs/kubo/issues/9545 - if partialLimits.System.ConnsInbound != rcmgr.Unlimited && cfg.ConnMgr.Type.WithDefault(config.DefaultConnMgrType) != "none" { + if partialLimits.System.ConnsInbound > rcmgr.DefaultLimit && cfg.ConnMgr.Type.WithDefault(config.DefaultConnMgrType) != "none" { maxInboundConns := int64(partialLimits.System.ConnsInbound) if connmgrHighWaterTimesTwo := cfg.ConnMgr.HighWater.WithDefault(config.DefaultConnMgrHighWater) * 2; maxInboundConns < connmgrHighWaterTimesTwo { maxInboundConns = connmgrHighWaterTimesTwo @@ -129,7 +129,7 @@ func createDefaultLimitConfig(cfg config.SwarmConfig) (limitConfig rcmgr.Concret } // Scale System.StreamsInbound as well, but use the existing ratio of StreamsInbound to ConnsInbound - if partialLimits.System.StreamsInbound != rcmgr.Unlimited { + if partialLimits.System.StreamsInbound > rcmgr.DefaultLimit { partialLimits.System.StreamsInbound = rcmgr.LimitVal(maxInboundConns * int64(partialLimits.System.StreamsInbound) / int64(partialLimits.System.ConnsInbound)) } partialLimits.System.ConnsInbound = rcmgr.LimitVal(maxInboundConns) diff --git a/test/cli/rcmgr_test.go b/test/cli/rcmgr_test.go index 3dbceb5d7..50ea26979 100644 --- a/test/cli/rcmgr_test.go +++ b/test/cli/rcmgr_test.go @@ -81,10 +81,10 @@ func TestRcmgr(t *testing.T) { require.Equal(t, 0, res.ExitCode()) limits := unmarshalLimits(t, res.Stdout.Bytes()) - if limits.System.ConnsInbound != rcmgr.Unlimited { + if limits.System.ConnsInbound > rcmgr.DefaultLimit { assert.GreaterOrEqual(t, limits.System.ConnsInbound, 800) } - if limits.System.StreamsInbound != rcmgr.Unlimited { + if limits.System.StreamsInbound > rcmgr.DefaultLimit { assert.GreaterOrEqual(t, limits.System.StreamsInbound, 800) } }) From 3c35a0cdea9a9029fe4740f9f609fa99d5965d92 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Thu, 16 Mar 2023 17:21:35 +0100 Subject: [PATCH 0561/1212] chore: bump go-libipfs@v0.6.2 --- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 1c19dd3eb..d96fa795d 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.18 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/go-libipfs v0.6.1 + github.com/ipfs/go-libipfs v0.6.2 github.com/ipfs/interface-go-ipfs-core v0.11.0 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.26.2 diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index c927b58d9..3a08f464a 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -569,8 +569,8 @@ github.com/ipfs/go-ipld-legacy v0.1.1 h1:BvD8PEuqwBHLTKqlGFTHSwrwFOMkVESEvwIYwR2 github.com/ipfs/go-ipld-legacy v0.1.1/go.mod h1:8AyKFCjgRPsQFf15ZQgDB8Din4DML/fOmKZkkFkrIEg= github.com/ipfs/go-ipns v0.3.0 h1:ai791nTgVo+zTuq2bLvEGmWP1M0A6kGTXUsgv/Yq67A= github.com/ipfs/go-ipns v0.3.0/go.mod h1:3cLT2rbvgPZGkHJoPO1YMJeh6LtkxopCkKFcio/wE24= -github.com/ipfs/go-libipfs v0.6.1 h1:OSO9cm1H3r4OXfP0MP1Q5UhTnhd2fByGl6CVYyz/Rhk= -github.com/ipfs/go-libipfs v0.6.1/go.mod h1:FmhKgxMOQA572TK5DA3MZ5GL44ZqsMHIrkgK4gLn4A8= +github.com/ipfs/go-libipfs v0.6.2 h1:QUf3kS3RrCjgtE0QW2d18PFFfOLeEt24Ft892ipLzRI= +github.com/ipfs/go-libipfs v0.6.2/go.mod h1:FmhKgxMOQA572TK5DA3MZ5GL44ZqsMHIrkgK4gLn4A8= github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= github.com/ipfs/go-log v1.0.2/go.mod h1:1MNjMxe0u6xvJZgeqbJ8vdo2TKaGwZ1a0Bpza+sr2Sk= github.com/ipfs/go-log v1.0.3/go.mod h1:OsLySYkwIbiSUR/yBTdv1qPtcE4FW3WPWk/ewz9Ru+A= diff --git a/go.mod b/go.mod index 673dd3793..4fce33b56 100644 --- a/go.mod +++ b/go.mod @@ -45,7 +45,7 @@ require ( github.com/ipfs/go-ipld-git v0.1.1 github.com/ipfs/go-ipld-legacy v0.1.1 github.com/ipfs/go-ipns v0.3.0 - github.com/ipfs/go-libipfs v0.6.1 + github.com/ipfs/go-libipfs v0.6.2 github.com/ipfs/go-log v1.0.5 github.com/ipfs/go-log/v2 v2.5.1 github.com/ipfs/go-merkledag v0.9.0 diff --git a/go.sum b/go.sum index 16329d6ad..100875344 100644 --- a/go.sum +++ b/go.sum @@ -591,8 +591,8 @@ github.com/ipfs/go-ipld-legacy v0.1.1 h1:BvD8PEuqwBHLTKqlGFTHSwrwFOMkVESEvwIYwR2 github.com/ipfs/go-ipld-legacy v0.1.1/go.mod h1:8AyKFCjgRPsQFf15ZQgDB8Din4DML/fOmKZkkFkrIEg= github.com/ipfs/go-ipns v0.3.0 h1:ai791nTgVo+zTuq2bLvEGmWP1M0A6kGTXUsgv/Yq67A= github.com/ipfs/go-ipns v0.3.0/go.mod h1:3cLT2rbvgPZGkHJoPO1YMJeh6LtkxopCkKFcio/wE24= -github.com/ipfs/go-libipfs v0.6.1 h1:OSO9cm1H3r4OXfP0MP1Q5UhTnhd2fByGl6CVYyz/Rhk= -github.com/ipfs/go-libipfs v0.6.1/go.mod h1:FmhKgxMOQA572TK5DA3MZ5GL44ZqsMHIrkgK4gLn4A8= +github.com/ipfs/go-libipfs v0.6.2 h1:QUf3kS3RrCjgtE0QW2d18PFFfOLeEt24Ft892ipLzRI= +github.com/ipfs/go-libipfs v0.6.2/go.mod h1:FmhKgxMOQA572TK5DA3MZ5GL44ZqsMHIrkgK4gLn4A8= github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= github.com/ipfs/go-log v1.0.2/go.mod h1:1MNjMxe0u6xvJZgeqbJ8vdo2TKaGwZ1a0Bpza+sr2Sk= github.com/ipfs/go-log v1.0.3/go.mod h1:OsLySYkwIbiSUR/yBTdv1qPtcE4FW3WPWk/ewz9Ru+A= From 010e22b508153672a777d180e6cdc16f59090b21 Mon Sep 17 00:00:00 2001 From: Gus Eggert Date: Thu, 16 Mar 2023 08:41:50 -0400 Subject: [PATCH 0562/1212] feat: add heap allocs to 'ipfs diag profile' --- core/commands/profile.go | 4 +++- profile/profile.go | 10 ++++++++++ profile/profile_test.go | 6 ++++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/core/commands/profile.go b/core/commands/profile.go index 3875cfdcb..d25711dac 100644 --- a/core/commands/profile.go +++ b/core/commands/profile.go @@ -49,7 +49,8 @@ The output file includes: - A list of running goroutines. - A CPU profile. -- A heap profile. +- A heap inuse profile. +- A heap allocation profile. - A mutex profile. - A block profile. - Your copy of go-ipfs. @@ -79,6 +80,7 @@ However, it could reveal: profile.CollectorGoroutinesPprof, profile.CollectorVersion, profile.CollectorHeap, + profile.CollectorAllocs, profile.CollectorBin, profile.CollectorCPU, profile.CollectorMutex, diff --git a/profile/profile.go b/profile/profile.go index d15d51251..b9ad86d2f 100644 --- a/profile/profile.go +++ b/profile/profile.go @@ -22,6 +22,7 @@ const ( CollectorGoroutinesPprof = "goroutines-pprof" CollectorVersion = "version" CollectorHeap = "heap" + CollectorAllocs = "allocs" CollectorBin = "bin" CollectorCPU = "cpu" CollectorMutex = "mutex" @@ -71,6 +72,11 @@ var collectors = map[string]collector{ collectFunc: heapProfile, enabledFunc: func(opts Options) bool { return true }, }, + CollectorAllocs: { + outputFile: "allocs.pprof", + collectFunc: allocsProfile, + enabledFunc: func(opts Options) bool { return true }, + }, CollectorBin: { outputFile: "ipfs", isExecutable: true, @@ -197,6 +203,10 @@ func heapProfile(ctx context.Context, _ Options, w io.Writer) error { return pprof.Lookup("heap").WriteTo(w, 0) } +func allocsProfile(ctx context.Context, _ Options, w io.Writer) error { + return pprof.Lookup("allocs").WriteTo(w, 0) +} + func versionInfo(ctx context.Context, _ Options, w io.Writer) error { return json.NewEncoder(w).Encode(version.GetVersionInfo()) } diff --git a/profile/profile_test.go b/profile/profile_test.go index 8da00d018..a2fe0b51d 100644 --- a/profile/profile_test.go +++ b/profile/profile_test.go @@ -17,6 +17,7 @@ func TestProfiler(t *testing.T) { CollectorGoroutinesPprof, CollectorVersion, CollectorHeap, + CollectorAllocs, CollectorBin, CollectorCPU, CollectorMutex, @@ -43,6 +44,7 @@ func TestProfiler(t *testing.T) { "goroutines.pprof", "version.json", "heap.pprof", + "allocs.pprof", "ipfs", "cpu.pprof", "mutex.pprof", @@ -63,6 +65,7 @@ func TestProfiler(t *testing.T) { "goroutines.pprof", "version.json", "heap.pprof", + "allocs.pprof", "ipfs.exe", "cpu.pprof", "mutex.pprof", @@ -81,6 +84,7 @@ func TestProfiler(t *testing.T) { "goroutines.pprof", "version.json", "heap.pprof", + "allocs.pprof", "ipfs", }, }, @@ -96,6 +100,7 @@ func TestProfiler(t *testing.T) { "goroutines.pprof", "version.json", "heap.pprof", + "allocs.pprof", "ipfs", "cpu.pprof", "block.pprof", @@ -114,6 +119,7 @@ func TestProfiler(t *testing.T) { "goroutines.pprof", "version.json", "heap.pprof", + "allocs.pprof", "ipfs", "cpu.pprof", "mutex.pprof", From 6cdc3c8a144f95d422563930f81c5d7a30a4523a Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Fri, 17 Mar 2023 15:14:10 +0100 Subject: [PATCH 0563/1212] fix: apply API.HTTPHeaders to /webui redirect --- core/corehttp/redirect.go | 15 +++++++++++++-- test/cli/gateway_test.go | 17 +++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/core/corehttp/redirect.go b/core/corehttp/redirect.go index bcd536d23..4b98963e2 100644 --- a/core/corehttp/redirect.go +++ b/core/corehttp/redirect.go @@ -8,8 +8,14 @@ import ( ) func RedirectOption(path string, redirect string) ServeOption { - handler := &redirectHandler{redirect} return func(n *core.IpfsNode, _ net.Listener, mux *http.ServeMux) (*http.ServeMux, error) { + cfg, err := n.Repo.Config() + if err != nil { + return nil, err + } + + handler := &redirectHandler{redirect, cfg.API.HTTPHeaders} + if len(path) > 0 { mux.Handle("/"+path+"/", handler) } else { @@ -20,9 +26,14 @@ func RedirectOption(path string, redirect string) ServeOption { } type redirectHandler struct { - path string + path string + headers map[string][]string } func (i *redirectHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + for k, v := range i.headers { + w.Header()[k] = v + } + http.Redirect(w, r, i.path, http.StatusFound) } diff --git a/test/cli/gateway_test.go b/test/cli/gateway_test.go index a585925a7..d2a90b04a 100644 --- a/test/cli/gateway_test.go +++ b/test/cli/gateway_test.go @@ -219,6 +219,23 @@ func TestGateway(t *testing.T) { assert.Contains(t, []int{302, 301}, resp.StatusCode) }) + t.Run("GET /webui/ returns user-specified headers", func(t *testing.T) { + t.Parallel() + + header := "Access-Control-Allow-Origin" + values := []string{"http://localhost:3000", "https://webui.ipfs.io"} + + node := harness.NewT(t).NewNode().Init() + node.UpdateConfig(func(cfg *config.Config) { + cfg.API.HTTPHeaders = map[string][]string{header: values} + }) + node.StartDaemon() + + resp := node.APIClient().DisableRedirects().Get("/webui/") + assert.Equal(t, resp.Headers.Values(header), values) + assert.Contains(t, []int{302, 301}, resp.StatusCode) + }) + t.Run("GET /logs returns logs", func(t *testing.T) { t.Parallel() apiClient := node.APIClient() From a22db797b9794d71147459395b32dad6b1e19125 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Fri, 17 Mar 2023 15:29:39 +0100 Subject: [PATCH 0564/1212] fix: canonicalize user defined headers --- core/corehttp/gateway_writable.go | 2 +- core/corehttp/redirect.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/corehttp/gateway_writable.go b/core/corehttp/gateway_writable.go index 89a2973ac..34cd8438e 100644 --- a/core/corehttp/gateway_writable.go +++ b/core/corehttp/gateway_writable.go @@ -30,7 +30,7 @@ type writableGatewayHandler struct { func (i *writableGatewayHandler) addUserHeaders(w http.ResponseWriter) { for k, v := range i.config.Headers { - w.Header()[k] = v + w.Header()[http.CanonicalHeaderKey(k)] = v } } diff --git a/core/corehttp/redirect.go b/core/corehttp/redirect.go index 4b98963e2..106355d24 100644 --- a/core/corehttp/redirect.go +++ b/core/corehttp/redirect.go @@ -32,7 +32,7 @@ type redirectHandler struct { func (i *redirectHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { for k, v := range i.headers { - w.Header()[k] = v + w.Header()[http.CanonicalHeaderKey(k)] = v } http.Redirect(w, r, i.path, http.StatusFound) From 7ea6e321fe0ccffdd76f39c203435ab0254f4205 Mon Sep 17 00:00:00 2001 From: Piotr Galar Date: Mon, 20 Mar 2023 09:47:59 +0100 Subject: [PATCH 0565/1212] chore: update go-libp2p to v0.26.3 (#9737) --- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index d96fa795d..5453ae1d5 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -10,7 +10,7 @@ require ( github.com/ipfs/go-libipfs v0.6.2 github.com/ipfs/interface-go-ipfs-core v0.11.0 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 - github.com/libp2p/go-libp2p v0.26.2 + github.com/libp2p/go-libp2p v0.26.3 github.com/multiformats/go-multiaddr v0.8.0 ) diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 3a08f464a..6f7e7f253 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -730,8 +730,8 @@ github.com/libp2p/go-libp2p v0.7.0/go.mod h1:hZJf8txWeCduQRDC/WSqBGMxaTHCOYHt2xS github.com/libp2p/go-libp2p v0.7.4/go.mod h1:oXsBlTLF1q7pxr+9w6lqzS1ILpyHsaBPniVO7zIHGMw= github.com/libp2p/go-libp2p v0.8.1/go.mod h1:QRNH9pwdbEBpx5DTJYg+qxcVaDMAz3Ee/qDKwXujH5o= github.com/libp2p/go-libp2p v0.14.3/go.mod h1:d12V4PdKbpL0T1/gsUNN8DfgMuRPDX8bS2QxCZlwRH0= -github.com/libp2p/go-libp2p v0.26.2 h1:eHEoW/696FP7/6DxOvcrKfTD6Bi0DExxiMSZUJxswA0= -github.com/libp2p/go-libp2p v0.26.2/go.mod h1:x75BN32YbwuY0Awm2Uix4d4KOz+/4piInkp4Wr3yOo8= +github.com/libp2p/go-libp2p v0.26.3 h1:6g/psubqwdaBqNNoidbRKSTBEYgaOuKBhHl8Q5tO+PM= +github.com/libp2p/go-libp2p v0.26.3/go.mod h1:x75BN32YbwuY0Awm2Uix4d4KOz+/4piInkp4Wr3yOo8= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-autonat v0.1.0/go.mod h1:1tLf2yXxiE/oKGtDwPYWTSYG3PtvYlJmg7NeVtPRqH8= diff --git a/go.mod b/go.mod index 4fce33b56..f7237b46a 100644 --- a/go.mod +++ b/go.mod @@ -67,7 +67,7 @@ require ( 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.26.2 + github.com/libp2p/go-libp2p v0.26.3 github.com/libp2p/go-libp2p-http v0.4.0 github.com/libp2p/go-libp2p-kad-dht v0.21.1 github.com/libp2p/go-libp2p-kbucket v0.5.0 diff --git a/go.sum b/go.sum index 100875344..27e101e1c 100644 --- a/go.sum +++ b/go.sum @@ -760,8 +760,8 @@ github.com/libp2p/go-libp2p v0.7.0/go.mod h1:hZJf8txWeCduQRDC/WSqBGMxaTHCOYHt2xS github.com/libp2p/go-libp2p v0.7.4/go.mod h1:oXsBlTLF1q7pxr+9w6lqzS1ILpyHsaBPniVO7zIHGMw= github.com/libp2p/go-libp2p v0.8.1/go.mod h1:QRNH9pwdbEBpx5DTJYg+qxcVaDMAz3Ee/qDKwXujH5o= github.com/libp2p/go-libp2p v0.14.3/go.mod h1:d12V4PdKbpL0T1/gsUNN8DfgMuRPDX8bS2QxCZlwRH0= -github.com/libp2p/go-libp2p v0.26.2 h1:eHEoW/696FP7/6DxOvcrKfTD6Bi0DExxiMSZUJxswA0= -github.com/libp2p/go-libp2p v0.26.2/go.mod h1:x75BN32YbwuY0Awm2Uix4d4KOz+/4piInkp4Wr3yOo8= +github.com/libp2p/go-libp2p v0.26.3 h1:6g/psubqwdaBqNNoidbRKSTBEYgaOuKBhHl8Q5tO+PM= +github.com/libp2p/go-libp2p v0.26.3/go.mod h1:x75BN32YbwuY0Awm2Uix4d4KOz+/4piInkp4Wr3yOo8= github.com/libp2p/go-libp2p-asn-util v0.2.0 h1:rg3+Os8jbnO5DxkC7K/Utdi+DkY3q/d1/1q+8WeNAsw= github.com/libp2p/go-libp2p-asn-util v0.2.0/go.mod h1:WoaWxbHKBymSN41hWSq/lGKJEca7TNm58+gGJi2WsLI= github.com/libp2p/go-libp2p-autonat v0.1.0/go.mod h1:1tLf2yXxiE/oKGtDwPYWTSYG3PtvYlJmg7NeVtPRqH8= From 754264fc08e86ecf777cbaeeee5580b120f84c6c Mon Sep 17 00:00:00 2001 From: Piotr Galar Date: Mon, 20 Mar 2023 11:45:02 +0100 Subject: [PATCH 0566/1212] Merge pull request #9707 from ipfs/changelog-0.19 docs: 0.19 changelog --- docs/changelogs/v0.19.md | 48 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/docs/changelogs/v0.19.md b/docs/changelogs/v0.19.md index 12331cae7..67dc57af1 100644 --- a/docs/changelogs/v0.19.md +++ b/docs/changelogs/v0.19.md @@ -7,6 +7,10 @@ - [Overview](#overview) - [🔦 Highlights](#-highlights) - [Improving the libp2p resource management integration](#improving-the-libp2p-resource-management-integration) + - [PubSub message caching improvements](#pubsub-message-caching-improvements) + - [Gateways](#gateways) + - [Signed IPNS Record response format](#signed-ipns-record-response-format) + - [Example fetch and inspect IPNS record](#example-fetch-and-inspect-ipns-record) - [Addition of "autoclient" router type](#addition-of-autoclient-router-type) - [Deprecation of the `ipfs pubsub` commands and matching HTTP endpoints](#deprecation-of-the-ipfs-pubsub-commands-and-matching-http-endpoints) - [📝 Changelog](#-changelog) @@ -24,6 +28,50 @@ and [0.18.1](https://github.com/ipfs/kubo/blob/master/docs/changelogs/v0.18.md#i - Note: we don't expect most users to need these capablities, but they are there if so. 1. [Doc updates](https://github.com/ipfs/kubo/blob/master/docs/libp2p-resource-management.md). +#### PubSub message caching improvements + +The PubSub message cache will now [prune messages after TTL is exhausted](https://github.com/ipfs/kubo/blob/master/docs/config.md#pubsubseenmessagesttl), [either based on the last time a message was seen or the first time it was seen](https://github.com/ipfs/kubo/blob/master/docs/config.md#pubsubseenmessagesstrategy). + +#### Gateways + +##### Signed IPNS Record response format + +This release implements [IPIP-351](https://github.com/ipfs/specs/pull/351) and +adds Gateway support for returning signed (verifiable) `ipns-record` (0x0300) +when `/ipns/{libp2p-key}` is requested with either +`Accept: application/vnd.ipfs.ipns-record` HTTP header +or `?format=ipns-record` URL query parameter. + + +The Gateway in Kubo already supported [trustless, verifiable retrieval](https://docs.ipfs.tech/reference/http/gateway/#trustless-verifiable-retrieval) of immutable `/ipfs/` namespace. +With `?format=ipns-record`, light HTTP clients are now able to get the same level of verifiability for IPNS websites. + +Tooling is limited at the moment, but we are working on [go-libipfs](https://github.com/ipfs/go-libipfs/) examples that illustrate the verifiable HTTP client pattern. + +##### Example: fetch IPNS record over HTTP and inspect it with `ipfs name inspect --verify` + +```console +$ FILE_CID=$(echo "Hello IPFS" | ipfs add --cid-version 1 -q) +$ IPNS_KEY=$(ipfs key gen test) +$ ipfs name publish /ipfs/$FILE_CID --key=test --ttl=30m +Published to k51q..dvf1: /ipfs/bafk..z244 +$ curl "http://127.0.0.1:8080/ipns/$IPNS_KEY?format=ipns-record" > signed.ipns-record +$ ipfs name inspect --verify $IPNS_KEY < signed.ipns-record +Value: "/ipfs/bafk..." +Validity Type: "EOL" +Validity: 2023-03-09T23:13:34.032977468Z +Sequence: 0 +TTL: 1800000000000 +PublicKey: "" +Signature V1: "m..." +Signature V2: "m..." +Data: {...} + +Validation results: + Valid: true + PublicKey: 12D3... +``` + #### Addition of "autoclient" router type A new routing type "autoclient" has been added. This mode is similar to "auto", in that it is a hybrid of content routers (including Kademlia and HTTP routers), but it does not run a DHT server. This is similar to the difference between "dhtclient" and "dht" router types. From 822106134af70eb56101e123aaf85e0b59b5f3be Mon Sep 17 00:00:00 2001 From: galargh Date: Mon, 20 Mar 2023 11:15:40 +0000 Subject: [PATCH 0567/1212] chore: update version --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index 71912f891..18bbf9a2d 100644 --- a/version.go +++ b/version.go @@ -11,7 +11,7 @@ import ( var CurrentCommit string // CurrentVersionNumber is the current application's version literal -const CurrentVersionNumber = "0.19.0-rc1" +const CurrentVersionNumber = "0.19.0" const ApiVersion = "/kubo/" + CurrentVersionNumber + "/" //nolint From c9fc10dafcf8487245f83f1e57cd2e02f88dbb51 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Mon, 20 Mar 2023 12:23:16 +0100 Subject: [PATCH 0568/1212] fix: remove outdated changelog part --- docs/changelogs/v0.19.md | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/docs/changelogs/v0.19.md b/docs/changelogs/v0.19.md index 67dc57af1..5ecb2d0f1 100644 --- a/docs/changelogs/v0.19.md +++ b/docs/changelogs/v0.19.md @@ -7,7 +7,6 @@ - [Overview](#overview) - [🔦 Highlights](#-highlights) - [Improving the libp2p resource management integration](#improving-the-libp2p-resource-management-integration) - - [PubSub message caching improvements](#pubsub-message-caching-improvements) - [Gateways](#gateways) - [Signed IPNS Record response format](#signed-ipns-record-response-format) - [Example fetch and inspect IPNS record](#example-fetch-and-inspect-ipns-record) @@ -21,16 +20,13 @@ ### 🔦 Highlights #### Improving the libp2p resource management integration + There are further followups up on libp2p resource manager improvements in Kubo [0.18.0](https://github.com/ipfs/kubo/blob/master/docs/changelogs/v0.18.md#improving-libp2p-resource-management-integration-1) and [0.18.1](https://github.com/ipfs/kubo/blob/master/docs/changelogs/v0.18.md#improving-libp2p-resource-management-integration): 1. `ipfs swarm limits` and `ipfs swarm stats` have been replaced by `ipfs swarm resources` to provide a single/combined view for limits and their current usage in a more intuitive ordering. 1. Removal of `Swarm.ResourceMgr.Limits` config. Instead [the power user can specify limits in a .json file that are fed directly to go-libp2p](https://github.com/ipfs/kubo/blob/master/docs/libp2p-resource-management.md#user-supplied-override-limits). This allows the power user to take advantage of the [new resource manager types introduced in go-libp2p 0.25](https://github.com/libp2p/go-libp2p/blob/master/CHANGELOG.md#new-resource-manager-types-) including "use default", "unlimited", "block all". - Note: we don't expect most users to need these capablities, but they are there if so. -1. [Doc updates](https://github.com/ipfs/kubo/blob/master/docs/libp2p-resource-management.md). - -#### PubSub message caching improvements - -The PubSub message cache will now [prune messages after TTL is exhausted](https://github.com/ipfs/kubo/blob/master/docs/config.md#pubsubseenmessagesttl), [either based on the last time a message was seen or the first time it was seen](https://github.com/ipfs/kubo/blob/master/docs/config.md#pubsubseenmessagesstrategy). +1. [Doc updates](https://github.com/ipfs/kubo/blob/master/docs/libp2p-resource-management.md). #### Gateways From 13865920d835ea104be4d803eb2453de0fa42f11 Mon Sep 17 00:00:00 2001 From: galargh Date: Mon, 20 Mar 2023 12:33:11 +0100 Subject: [PATCH 0569/1212] docs: update changelog --- docs/changelogs/v0.19.md | 467 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 465 insertions(+), 2 deletions(-) diff --git a/docs/changelogs/v0.19.md b/docs/changelogs/v0.19.md index 67dc57af1..4663d1323 100644 --- a/docs/changelogs/v0.19.md +++ b/docs/changelogs/v0.19.md @@ -23,10 +23,10 @@ #### Improving the libp2p resource management integration There are further followups up on libp2p resource manager improvements in Kubo [0.18.0](https://github.com/ipfs/kubo/blob/master/docs/changelogs/v0.18.md#improving-libp2p-resource-management-integration-1) and [0.18.1](https://github.com/ipfs/kubo/blob/master/docs/changelogs/v0.18.md#improving-libp2p-resource-management-integration): -1. `ipfs swarm limits` and `ipfs swarm stats` have been replaced by `ipfs swarm resources` to provide a single/combined view for limits and their current usage in a more intuitive ordering. +1. `ipfs swarm limits` and `ipfs swarm stats` have been replaced by `ipfs swarm resources` to provide a single/combined view for limits and their current usage in a more intuitive ordering. 1. Removal of `Swarm.ResourceMgr.Limits` config. Instead [the power user can specify limits in a .json file that are fed directly to go-libp2p](https://github.com/ipfs/kubo/blob/master/docs/libp2p-resource-management.md#user-supplied-override-limits). This allows the power user to take advantage of the [new resource manager types introduced in go-libp2p 0.25](https://github.com/libp2p/go-libp2p/blob/master/CHANGELOG.md#new-resource-manager-types-) including "use default", "unlimited", "block all". - Note: we don't expect most users to need these capablities, but they are there if so. -1. [Doc updates](https://github.com/ipfs/kubo/blob/master/docs/libp2p-resource-management.md). +1. [Doc updates](https://github.com/ipfs/kubo/blob/master/docs/libp2p-resource-management.md). #### PubSub message caching improvements @@ -85,4 +85,467 @@ For more information and rational see [#9717](https://github.com/ipfs/kubo/issue ### 📝 Changelog +

Full Changelog + +- github.com/ipfs/kubo: + - chore: update version + - docs: 0.19 changelog ([ipfs/kubo#9707](https://github.com/ipfs/kubo/pull/9707)) + - fix: canonicalize user defined headers + - fix: apply API.HTTPHeaders to /webui redirect + - feat: add heap allocs to 'ipfs diag profile' + - fix: future proof with > rcmgr.DefaultLimit for new enum rcmgr values + - test: add test for presarvation of unlimited configs for inbound systems + - fix: preserve Unlimited StreamsInbound in connmgr reconciliation + - test: fix flaky rcmgr test + - chore: deprecate the pubsub api + - test: port peering test from sharness to Go + - test: use `T.TempDir` to create temporary test directory + - fix: --verify forgets the verified key + - test: name --verify forgets the verified key + - feat: add "autoclient" routing type + - test: parallelize more of rcmgr Go tests + - test: port legacy DHT tests to Go + - fix: t0116-gateway-cache.sh ([ipfs/kubo#9696](https://github.com/ipfs/kubo/pull/9696)) + - docs: add bifrost to early testers ([ipfs/kubo#9699](https://github.com/ipfs/kubo/pull/9699)) + - fix: typo in documentation for install path + - chore: update version + - feat: Reduce RM code footprint + - Doc updates/additions + - ci: replace junit html generation with gh action + - test: port rcmgr sharness tests to Go + - test(gateway): use deterministic CAR fixtures ([ipfs/kubo#9657](https://github.com/ipfs/kubo/pull/9657)) + - feat(gateway): error handling improvements (500, 502, 504) (#9660) ([ipfs/kubo#9660](https://github.com/ipfs/kubo/pull/9660)) + - docs: be clear about swarm.addrfilters (#9661) ([ipfs/kubo#9661](https://github.com/ipfs/kubo/pull/9661)) + - chore: update go-libp2p to v0.26 (#9656) ([ipfs/kubo#9656](https://github.com/ipfs/kubo/pull/9656)) + - feat(pinning): connect some missing go context (#9557) ([ipfs/kubo#9557](https://github.com/ipfs/kubo/pull/9557)) + - fix(gateway): return HTTP 500 on ErrResolveFailed (#9589) ([ipfs/kubo#9589](https://github.com/ipfs/kubo/pull/9589)) + - docs: bulk spelling edits (#9544) ([ipfs/kubo#9544](https://github.com/ipfs/kubo/pull/9544)) + - docs: "remote" errors from resource manager (#9653) ([ipfs/kubo#9653](https://github.com/ipfs/kubo/pull/9653)) + - test: remove gateway tests migrated to go-libipfs + - fix: update rcmgr for go-libp2p v0.25 + - chore: update go-libp2p to v0.25.1 + - docs(0.18.1): guide users to clean up limits (#9644) ([ipfs/kubo#9644](https://github.com/ipfs/kubo/pull/9644)) + - feat: add NewOptionalInteger function + - fix: dereference int64 pointer in OptionalInteger.String() (#9640) ([ipfs/kubo#9640](https://github.com/ipfs/kubo/pull/9640)) + - fix: restore wire format for /api/v0/routing/get|put (#9639) ([ipfs/kubo#9639](https://github.com/ipfs/kubo/pull/9639)) + - refactor(gw): move Host (DNSLink and subdomain) handling to go-libipfs (#9624) ([ipfs/kubo#9624](https://github.com/ipfs/kubo/pull/9624)) + - refactor: new go-libipfs/gateway API, deprecate Gateway.Writable (#9616) ([ipfs/kubo#9616](https://github.com/ipfs/kubo/pull/9616)) + - Create Changelog: v0.19 ([ipfs/kubo#9617](https://github.com/ipfs/kubo/pull/9617)) + - refactor: use gateway from go-libipfs (#9588) ([ipfs/kubo#9588](https://github.com/ipfs/kubo/pull/9588)) + - Merge Release: v0.18.1 ([ipfs/kubo#9613](https://github.com/ipfs/kubo/pull/9613)) + - Add overview section + - Adjust inbound connection limits depending on memory. + - feat: ipfs-webui 2.22.0 + - chore: bump go-libipfs remove go-bitswap + - docs: DefaultResourceMgrMinInboundConns + - feat(gateway): IPNS record response format (IPIP-351) (#9399) ([ipfs/kubo#9399](https://github.com/ipfs/kubo/pull/9399)) + - fix(ipns): honour --ttl flag in 'ipfs name publish' (#9471) ([ipfs/kubo#9471](https://github.com/ipfs/kubo/pull/9471)) + - feat: Pubsub.SeenMessagesStrategy (#9543) ([ipfs/kubo#9543](https://github.com/ipfs/kubo/pull/9543)) + - chore: bump go-libipfs to replace go-block-format + - Merge Kubo: v0.18 ([ipfs/kubo#9581](https://github.com/ipfs/kubo/pull/9581)) + - fix: clarity: no user supplied rcmgr limits of 0 (#9563) ([ipfs/kubo#9563](https://github.com/ipfs/kubo/pull/9563)) + - fix(gateway): undesired conversions to dag-json and friends (#9566) ([ipfs/kubo#9566](https://github.com/ipfs/kubo/pull/9566)) + - fix: ensure connmgr is smaller then autoscalled ressource limits + - fix: typo in ensureConnMgrMakeSenseVsResourcesMgr + - docs: clarify browser descriptions for webtransport + - fix: update saxon download path + - fix: refuse to start if connmgr is smaller than ressource limits and not using none connmgr + - fix: User-Agent sent to HTTP routers + - test: port gateway sharness tests to Go tests + - fix: do not download saxon in parallel + - docs: improve docs/README (#9539) ([ipfs/kubo#9539](https://github.com/ipfs/kubo/pull/9539)) + - test: port CircleCI to GH Actions and improve sharness reporting (#9355) ([ipfs/kubo#9355](https://github.com/ipfs/kubo/pull/9355)) + - chore: migrate from go-ipfs-files to go-libipfs/files (#9535) ([ipfs/kubo#9535](https://github.com/ipfs/kubo/pull/9535)) + - fix: stats dht command when Routing.Type=auto (#9538) ([ipfs/kubo#9538](https://github.com/ipfs/kubo/pull/9538)) + - fix: hint people to changing from RSA peer ids + - fix(gateway): JSON when Accept is a list + - fix(test): retry flaky t0125-twonode.sh + - docs: fix Router config Godoc (#9528) ([ipfs/kubo#9528](https://github.com/ipfs/kubo/pull/9528)) + - fix(ci): flaky sharness test + - docs(config): ProviderSearchDelay (#9526) ([ipfs/kubo#9526](https://github.com/ipfs/kubo/pull/9526)) + - docs: clarify debug environment variables + - fix: disable provide over HTTP with Routing.Type=auto (#9511) ([ipfs/kubo#9511](https://github.com/ipfs/kubo/pull/9511)) + - fix(test): stabilize flaky provider tests + - feat: port pins CLI test + - Removing QRI from early tester ([ipfs/kubo#9503](https://github.com/ipfs/kubo/pull/9503)) + - Update Version (dev): v0.18 ([ipfs/kubo#9500](https://github.com/ipfs/kubo/pull/9500)) +- github.com/ipfs/go-bitfield (v1.0.0 -> v1.1.0): + - Merge pull request from GHSA-2h6c-j3gf-xp9r + - sync: update CI config files (#3) ([ipfs/go-bitfield#3](https://github.com/ipfs/go-bitfield/pull/3)) +- github.com/ipfs/go-block-format (v0.0.3 -> v0.1.1): + - chore: release v0.1.1 + - docs: fix wrong copy paste in docs + - chore: release v0.1.0 + - refactor: deprecate and add stub types to go-libipfs/blocks + - sync: update CI config files (#34) ([ipfs/go-block-format#34](https://github.com/ipfs/go-block-format/pull/34)) + - remove Makefile ([ipfs/go-block-format#31](https://github.com/ipfs/go-block-format/pull/31)) +- github.com/ipfs/go-ipfs-files (v0.0.8 -> v0.3.0): + - ([ipfs/go-ipfs-files#59](https://github.com/ipfs/go-ipfs-files/pull/59)) + - docs: add moved noticed [ci skip] + - Release v0.2.0 + - fix: error when TAR has files outside of root (#56) ([ipfs/go-ipfs-files#56](https://github.com/ipfs/go-ipfs-files/pull/56)) + - sync: update CI config files ([ipfs/go-ipfs-files#55](https://github.com/ipfs/go-ipfs-files/pull/55)) + - chore(Directory): add DirIterator API restriction: iterate only once + - Release v0.1.1 + - fix: add dragonfly build option for filewriter flags + - fix: add freebsd build option for filewriter flags + - Release v0.1.0 + - docs: fix community CONTRIBUTING.md link (#45) ([ipfs/go-ipfs-files#45](https://github.com/ipfs/go-ipfs-files/pull/45)) + - chore(filewriter): cleanup writes (#43) ([ipfs/go-ipfs-files#43](https://github.com/ipfs/go-ipfs-files/pull/43)) + - sync: update CI config files (#44) ([ipfs/go-ipfs-files#44](https://github.com/ipfs/go-ipfs-files/pull/44)) + - sync: update CI config files ([ipfs/go-ipfs-files#40](https://github.com/ipfs/go-ipfs-files/pull/40)) + - fix: manually parse the content disposition to preserve directories ([ipfs/go-ipfs-files#42](https://github.com/ipfs/go-ipfs-files/pull/42)) + - fix: round timestamps down by truncating them to seconds ([ipfs/go-ipfs-files#41](https://github.com/ipfs/go-ipfs-files/pull/41)) + - sync: update CI config files ([ipfs/go-ipfs-files#34](https://github.com/ipfs/go-ipfs-files/pull/34)) + - Fix test failure on Windows caused by nil `sys` in mock `FileInfo` ([ipfs/go-ipfs-files#39](https://github.com/ipfs/go-ipfs-files/pull/39)) + - fix staticcheck ([ipfs/go-ipfs-files#35](https://github.com/ipfs/go-ipfs-files/pull/35)) + - fix linters ([ipfs/go-ipfs-files#33](https://github.com/ipfs/go-ipfs-files/pull/33)) +- github.com/ipfs/go-ipfs-pinner (v0.2.1 -> v0.3.0): + - chore: release v0.3.0 (#27) ([ipfs/go-ipfs-pinner#27](https://github.com/ipfs/go-ipfs-pinner/pull/27)) + - feat!: add and connect missing context, remove RemovePinWithMode (#23) ([ipfs/go-ipfs-pinner#23](https://github.com/ipfs/go-ipfs-pinner/pull/23)) + - sync: update CI config files ([ipfs/go-ipfs-pinner#16](https://github.com/ipfs/go-ipfs-pinner/pull/16)) +- github.com/ipfs/go-ipfs-pq (v0.0.2 -> v0.0.3): + - chore: release v0.0.3 + - fix: enable early GC + - sync: update CI config files (#10) ([ipfs/go-ipfs-pq#10](https://github.com/ipfs/go-ipfs-pq/pull/10)) + - sync: update CI config files ([ipfs/go-ipfs-pq#8](https://github.com/ipfs/go-ipfs-pq/pull/8)) + - remove Makefile ([ipfs/go-ipfs-pq#7](https://github.com/ipfs/go-ipfs-pq/pull/7)) +- github.com/ipfs/go-libipfs (v0.2.0 -> v0.6.2): + - chore: release 0.6.2 (#211) ([ipfs/go-libipfs#211](https://github.com/ipfs/go-libipfs/pull/211)) + - fix(gateway): 500 on panic, recover on WithHostname + - refactor: use assert in remaining gateway tests + - chore: release 0.6.1 + - feat: support HTTP 429 with Retry-After (#194) ([ipfs/go-libipfs#194](https://github.com/ipfs/go-libipfs/pull/194)) + - docs: fix typo in README.md + - fix(gateway): return 500 for all /ip[nf]s/id failures + - chore: make gocritic happier + - feat(gateway): improved error handling, support for 502 and 504 ([ipfs/go-libipfs#182](https://github.com/ipfs/go-libipfs/pull/182)) + - feat: add content path in request context (#184) ([ipfs/go-libipfs#184](https://github.com/ipfs/go-libipfs/pull/184)) + - sync: update CI config files ([ipfs/go-libipfs#159](https://github.com/ipfs/go-libipfs/pull/159)) + - fix(gateway): return HTTP 500 on namesys.ErrResolveFailed (#150) ([ipfs/go-libipfs#150](https://github.com/ipfs/go-libipfs/pull/150)) + - docs(examples): add UnixFS file download over Bitswap (#143) ([ipfs/go-libipfs#143](https://github.com/ipfs/go-libipfs/pull/143)) + - bitswap/server/internal/decision: fix: remove unused private type + - chore: release v0.6.0 + - bitswap/server/internal/decision: add more non flaky tests + - bitswap/server/internal/decision: add filtering on CIDs - Ignore cids that are too big. - Kill connection for peers that are using inline CIDs. + - bitswap/server/internal/decision: rewrite ledger inversion + - docs(readme): various updates for clarity (#171) ([ipfs/go-libipfs#171](https://github.com/ipfs/go-libipfs/pull/171)) + - feat: metric for implicit index.html in dirs + - fix(gateway): ensure ipfs_http_gw_get_duration_seconds gets updated + - test(gateway): migrate Go tests from Kubo ([ipfs/go-libipfs#156](https://github.com/ipfs/go-libipfs/pull/156)) + - docs: fix link (#165) ([ipfs/go-libipfs#165](https://github.com/ipfs/go-libipfs/pull/165)) + - fix: GetIPNSRecord example gateway implementation (#158) ([ipfs/go-libipfs#158](https://github.com/ipfs/go-libipfs/pull/158)) + - chore: release v0.5.0 + - chore: update go-libp2p to v0.25.1 + - fix(gateway): display correct error with 500 (#160) ([ipfs/go-libipfs#160](https://github.com/ipfs/go-libipfs/pull/160)) + - fix: gateway car example dnslink + - feat(gateway): add TAR, IPNS Record, DAG-* histograms and spans (#155) ([ipfs/go-libipfs#155](https://github.com/ipfs/go-libipfs/pull/155)) + - feat(gateway): migrate subdomain and dnslink code (#153) ([ipfs/go-libipfs#153](https://github.com/ipfs/go-libipfs/pull/153)) + - docs: add example of gateway that proxies to ?format=raw (#151) ([ipfs/go-libipfs#151](https://github.com/ipfs/go-libipfs/pull/151)) + - docs: add example of gateway backed by CAR file (#147) ([ipfs/go-libipfs#147](https://github.com/ipfs/go-libipfs/pull/147)) + - undefined ([ipfs/go-libipfs#145](https://github.com/ipfs/go-libipfs/pull/145)) + - Extract Gateway Code From Kubo + ([ipfs/go-libipfs#65](https://github.com/ipfs/go-libipfs/pull/65)) + - Migrate go-bitswap ([ipfs/go-libipfs#63](https://github.com/ipfs/go-libipfs/pull/63)) + - Use `PUT` as method to insert provider records + - Migrate `go-block-format` ([ipfs/go-libipfs#58](https://github.com/ipfs/go-libipfs/pull/58)) + - chore: add codecov PR comment + - chore: add a logo and some basics in the README (#37) ([ipfs/go-libipfs#37](https://github.com/ipfs/go-libipfs/pull/37)) +- github.com/ipfs/go-namesys (v0.6.0 -> v0.7.0): + - chore: release 0.7.0 (#36) ([ipfs/go-namesys#36](https://github.com/ipfs/go-namesys/pull/36)) + - feat: use PublishOptions for publishing IPNS records (#35) ([ipfs/go-namesys#35](https://github.com/ipfs/go-namesys/pull/35)) +- github.com/ipfs/go-path (v0.3.0 -> v0.3.1): + - chore: release v0.3.1 (#67) ([ipfs/go-path#67](https://github.com/ipfs/go-path/pull/67)) + - feat: expose ErrInvalidPath and implement .Is function (#66) ([ipfs/go-path#66](https://github.com/ipfs/go-path/pull/66)) + - sync: update CI config files (#60) ([ipfs/go-path#60](https://github.com/ipfs/go-path/pull/60)) + - feat: add basic tracing ([ipfs/go-path#59](https://github.com/ipfs/go-path/pull/59)) +- github.com/ipfs/go-peertaskqueue (v0.8.0 -> v0.8.1): + - chore: release v0.8.1 + - feat: add PushTasksTruncated which only push a limited amount of tasks + - feat: add (*PeerTaskQueue).Clear which fully removes a peer + - sync: update CI config files (#26) ([ipfs/go-peertaskqueue#26](https://github.com/ipfs/go-peertaskqueue/pull/26)) +- github.com/ipfs/go-unixfs (v0.4.2 -> v0.4.4): + - chore: release v0.4.4 + - fix: correctly handle return errors + - fix: correctly handle errors in balancedbuilder's Layout + - test: fix tests after hamt issues fixes + - Merge pull request from GHSA-q264-w97q-q778 +- github.com/ipfs/go-unixfsnode (v1.5.1 -> v1.5.2): + - Merge pull request from GHSA-4gj3-6r43-3wfc +- github.com/ipfs/interface-go-ipfs-core (v0.8.2 -> v0.11.0): + - chore: release v0.11.0 + - test: basic routing interface test + - chore: release v0.10.0 (#102) ([ipfs/interface-go-ipfs-core#102](https://github.com/ipfs/interface-go-ipfs-core/pull/102)) + - feat: add RoutingAPI to CoreAPI + - chore: release 0.9.0 (#101) ([ipfs/interface-go-ipfs-core#101](https://github.com/ipfs/interface-go-ipfs-core/pull/101)) + - feat: add namesys publish options (#94) ([ipfs/interface-go-ipfs-core#94](https://github.com/ipfs/interface-go-ipfs-core/pull/94)) +- github.com/ipld/go-car (v0.4.0 -> v0.5.0): + - chore: bump version to 0.5.0 + - fix: remove use of ioutil + - run gofmt -s + - bump go.mod to Go 1.18 and run go fix + - bump go.mod to Go 1.18 and run go fix + - OpenReadWriteFile: add test + - blockstore: allow to pass a file to write in (#323) ([ipld/go-car#323](https://github.com/ipld/go-car/pull/323)) + - feat: add `car inspect` command to cmd pkg (#320) ([ipld/go-car#320](https://github.com/ipld/go-car/pull/320)) + - Separate `index.ReadFrom` tests + - Only read index codec during inspection + - Upgrade to the latest `go-car/v2` + - Empty identity CID should be indexed when options are set +- github.com/libp2p/go-libp2p (v0.24.2 -> v0.26.3): + - Release v0.26.3 (#2197) ([libp2p/go-libp2p#2197](https://github.com/libp2p/go-libp2p/pull/2197)) + - retract v0.26.1, release v0.26.2 (#2153) ([libp2p/go-libp2p#2153](https://github.com/libp2p/go-libp2p/pull/2153)) + - rcmgr: fix JSON marshalling of ResourceManagerStat peer map (#2156) ([libp2p/go-libp2p#2156](https://github.com/libp2p/go-libp2p/pull/2156)) + - release v0.26.1 ([libp2p/go-libp2p#2146](https://github.com/libp2p/go-libp2p/pull/2146)) + - release v0.26.0 (#2133) ([libp2p/go-libp2p#2133](https://github.com/libp2p/go-libp2p/pull/2133)) + - identify: add more detailed metrics (#2126) ([libp2p/go-libp2p#2126](https://github.com/libp2p/go-libp2p/pull/2126)) + - autorelay: refactor relay finder and start autorelay after identify (#2120) ([libp2p/go-libp2p#2120](https://github.com/libp2p/go-libp2p/pull/2120)) + - don't use the time value from the time.Ticker channel (#2127) ([libp2p/go-libp2p#2127](https://github.com/libp2p/go-libp2p/pull/2127)) + - Wrap conn with metrics (#2131) ([libp2p/go-libp2p#2131](https://github.com/libp2p/go-libp2p/pull/2131)) + - chore: update changelog for 0.26.0 (#2132) ([libp2p/go-libp2p#2132](https://github.com/libp2p/go-libp2p/pull/2132)) + - circuitv2: Update proto files to proto3 (#2121) ([libp2p/go-libp2p#2121](https://github.com/libp2p/go-libp2p/pull/2121)) + - swarm: remove parallel tests from swarm tests (#2130) ([libp2p/go-libp2p#2130](https://github.com/libp2p/go-libp2p/pull/2130)) + - circuitv2: add a relay option to disable limits (#2125) ([libp2p/go-libp2p#2125](https://github.com/libp2p/go-libp2p/pull/2125)) + - quic: fix stalled virtual listener (#2122) ([libp2p/go-libp2p#2122](https://github.com/libp2p/go-libp2p/pull/2122)) + - swarm: add early muxer selection to swarm metrics (#2119) ([libp2p/go-libp2p#2119](https://github.com/libp2p/go-libp2p/pull/2119)) + - metrics: add options to disable metrics and to set Prometheus registerer (#2116) ([libp2p/go-libp2p#2116](https://github.com/libp2p/go-libp2p/pull/2116)) + - swarm: add ip_version to metrics (#2114) ([libp2p/go-libp2p#2114](https://github.com/libp2p/go-libp2p/pull/2114)) + - Revert mistaken "Bump timeout" + - Bump timeout + - remove all circuit v1 related code (#2107) ([libp2p/go-libp2p#2107](https://github.com/libp2p/go-libp2p/pull/2107)) + - quic: don't send detailed error messages when closing connections (#2112) ([libp2p/go-libp2p#2112](https://github.com/libp2p/go-libp2p/pull/2112)) + - metrics: add no alloc metrics for eventbus, swarm, identify (#2108) ([libp2p/go-libp2p#2108](https://github.com/libp2p/go-libp2p/pull/2108)) + - chore: fix typo in Changelog (#2111) ([libp2p/go-libp2p#2111](https://github.com/libp2p/go-libp2p/pull/2111)) + - chore: update changelog (#2109) ([libp2p/go-libp2p#2109](https://github.com/libp2p/go-libp2p/pull/2109)) + - chore: unify dashboard location (#2110) ([libp2p/go-libp2p#2110](https://github.com/libp2p/go-libp2p/pull/2110)) + - autonat: add metrics (#2086) ([libp2p/go-libp2p#2086](https://github.com/libp2p/go-libp2p/pull/2086)) + - relaymanager: do not start new relay if one already exists (#2093) ([libp2p/go-libp2p#2093](https://github.com/libp2p/go-libp2p/pull/2093)) + - autonat: don't emit reachability changed events on address change (#2092) ([libp2p/go-libp2p#2092](https://github.com/libp2p/go-libp2p/pull/2092)) + - chore: modify changelog entries (#2101) ([libp2p/go-libp2p#2101](https://github.com/libp2p/go-libp2p/pull/2101)) + - Introduce a changelog (#2084) ([libp2p/go-libp2p#2084](https://github.com/libp2p/go-libp2p/pull/2084)) + - use atomic.Int32 and atomic.Int64 (#2096) ([libp2p/go-libp2p#2096](https://github.com/libp2p/go-libp2p/pull/2096)) + - change atomic.Value to atomic.Pointer (#2088) ([libp2p/go-libp2p#2088](https://github.com/libp2p/go-libp2p/pull/2088)) + - use atomic.Bool instead of int32 operations (#2089) ([libp2p/go-libp2p#2089](https://github.com/libp2p/go-libp2p/pull/2089)) + - sync: update CI config files (#2073) ([libp2p/go-libp2p#2073](https://github.com/libp2p/go-libp2p/pull/2073)) + - chore: update examples to v0.25.1 (#2080) ([libp2p/go-libp2p#2080](https://github.com/libp2p/go-libp2p/pull/2080)) + - v0.25.1 (#2082) ([libp2p/go-libp2p#2082](https://github.com/libp2p/go-libp2p/pull/2082)) + - Start host in mocknet (#2078) ([libp2p/go-libp2p#2078](https://github.com/libp2p/go-libp2p/pull/2078)) + - Release v0.25.0 (#2077) ([libp2p/go-libp2p#2077](https://github.com/libp2p/go-libp2p/pull/2077)) + - identify: add some basic metrics (#2069) ([libp2p/go-libp2p#2069](https://github.com/libp2p/go-libp2p/pull/2069)) + - p2p/test/quic: use contexts with a timeout for Connect calls (#2070) ([libp2p/go-libp2p#2070](https://github.com/libp2p/go-libp2p/pull/2070)) + - feat!: rcmgr: Change LimitConfig to use LimitVal type (#2000) ([libp2p/go-libp2p#2000](https://github.com/libp2p/go-libp2p/pull/2000)) + - identify: refactor sending of Identify pushes (#1984) ([libp2p/go-libp2p#1984](https://github.com/libp2p/go-libp2p/pull/1984)) + - Update interop to match spec (#2049) ([libp2p/go-libp2p#2049](https://github.com/libp2p/go-libp2p/pull/2049)) + - chore: git-ignore various flavors of qlog files (#2064) ([libp2p/go-libp2p#2064](https://github.com/libp2p/go-libp2p/pull/2064)) + - rcmgr: add libp2p prefix to all metrics (#2063) ([libp2p/go-libp2p#2063](https://github.com/libp2p/go-libp2p/pull/2063)) + - websocket: Replace gorilla websocket transport with nhooyr websocket transport (#1982) ([libp2p/go-libp2p#1982](https://github.com/libp2p/go-libp2p/pull/1982)) + - rcmgr: Use prometheus SDK for rcmgr metrics (#2044) ([libp2p/go-libp2p#2044](https://github.com/libp2p/go-libp2p/pull/2044)) + - autorelay: Split libp2p.EnableAutoRelay into 2 functions (#2022) ([libp2p/go-libp2p#2022](https://github.com/libp2p/go-libp2p/pull/2022)) + - set names for eventbus event subscriptions (#2057) ([libp2p/go-libp2p#2057](https://github.com/libp2p/go-libp2p/pull/2057)) + - Test cleanup (#2053) ([libp2p/go-libp2p#2053](https://github.com/libp2p/go-libp2p/pull/2053)) + - metrics: use a single slice pool for all metrics tracer (#2054) ([libp2p/go-libp2p#2054](https://github.com/libp2p/go-libp2p/pull/2054)) + - eventbus: add metrics (#2038) ([libp2p/go-libp2p#2038](https://github.com/libp2p/go-libp2p/pull/2038)) + - quic: disable sending of Version Negotiation packets (#2015) ([libp2p/go-libp2p#2015](https://github.com/libp2p/go-libp2p/pull/2015)) + - p2p/test: fix flaky notification test (#2051) ([libp2p/go-libp2p#2051](https://github.com/libp2p/go-libp2p/pull/2051)) + - quic, tcp: only register Prometheus counters when metrics are enabled ([libp2p/go-libp2p#1971](https://github.com/libp2p/go-libp2p/pull/1971)) + - p2p/test: add test for EvtLocalAddressesUpdated event (#2016) ([libp2p/go-libp2p#2016](https://github.com/libp2p/go-libp2p/pull/2016)) + - quic / webtransport: extend test to test dialing draft-29 and v1 (#1957) ([libp2p/go-libp2p#1957](https://github.com/libp2p/go-libp2p/pull/1957)) + - holepunch: fix flaky by not remove holepunch protocol handler (#1948) ([libp2p/go-libp2p#1948](https://github.com/libp2p/go-libp2p/pull/1948)) + - use quic-go and webtransport-go from quic-go organization (#2040) ([libp2p/go-libp2p#2040](https://github.com/libp2p/go-libp2p/pull/2040)) + - Migrate to test-plan composite action (#2039) ([libp2p/go-libp2p#2039](https://github.com/libp2p/go-libp2p/pull/2039)) + - chore: remove license files from the eventbus package (#2042) ([libp2p/go-libp2p#2042](https://github.com/libp2p/go-libp2p/pull/2042)) + - rcmgr: *: Always close connscope (#2037) ([libp2p/go-libp2p#2037](https://github.com/libp2p/go-libp2p/pull/2037)) + - chore: remove textual roadmap in favor for Starmap (#2036) ([libp2p/go-libp2p#2036](https://github.com/libp2p/go-libp2p/pull/2036)) + - swarm metrics: fix datasource for dashboard (#2024) ([libp2p/go-libp2p#2024](https://github.com/libp2p/go-libp2p/pull/2024)) + - consistently use protocol.ID instead of strings (#2004) ([libp2p/go-libp2p#2004](https://github.com/libp2p/go-libp2p/pull/2004)) + - swarm: add a basic metrics tracer (#1973) ([libp2p/go-libp2p#1973](https://github.com/libp2p/go-libp2p/pull/1973)) + - Expose muxer ids (#2012) ([libp2p/go-libp2p#2012](https://github.com/libp2p/go-libp2p/pull/2012)) + - Clean addresses with peer id before adding to addrbook (#2007) ([libp2p/go-libp2p#2007](https://github.com/libp2p/go-libp2p/pull/2007)) + - feat: ci test-plans: Parse test timeout parameter for interop test (#2014) ([libp2p/go-libp2p#2014](https://github.com/libp2p/go-libp2p/pull/2014)) + - Export resource manager errors (#2008) ([libp2p/go-libp2p#2008](https://github.com/libp2p/go-libp2p/pull/2008)) + - peerstore: make it possible to use an empty peer ID (#2006) ([libp2p/go-libp2p#2006](https://github.com/libp2p/go-libp2p/pull/2006)) + - Add ci flakiness score to readme (#2002) ([libp2p/go-libp2p#2002](https://github.com/libp2p/go-libp2p/pull/2002)) + - rcmgr: fix: Ignore zero values when marshalling Limits. (#1998) ([libp2p/go-libp2p#1998](https://github.com/libp2p/go-libp2p/pull/1998)) + - CI: Fast multidimensional Interop tests (#1991) ([libp2p/go-libp2p#1991](https://github.com/libp2p/go-libp2p/pull/1991)) + - feat: add some users to the readme (#1981) ([libp2p/go-libp2p#1981](https://github.com/libp2p/go-libp2p/pull/1981)) + - ci: run go generate as part of the go-check workflow (#1986) ([libp2p/go-libp2p#1986](https://github.com/libp2p/go-libp2p/pull/1986)) + - switch to Google's Protobuf library, make protobufs compile with go generate ([libp2p/go-libp2p#1979](https://github.com/libp2p/go-libp2p/pull/1979)) + - circuitv2: correctly set the transport in the ConnectionState (#1972) ([libp2p/go-libp2p#1972](https://github.com/libp2p/go-libp2p/pull/1972)) + - roadmap: remove optimizations of the TCP-based handshake (#1959) ([libp2p/go-libp2p#1959](https://github.com/libp2p/go-libp2p/pull/1959)) + - identify: remove support for Identify Delta ([libp2p/go-libp2p#1975](https://github.com/libp2p/go-libp2p/pull/1975)) + - core: remove introspection package (#1978) ([libp2p/go-libp2p#1978](https://github.com/libp2p/go-libp2p/pull/1978)) + - identify: remove old code targeting Go 1.17 (#1964) ([libp2p/go-libp2p#1964](https://github.com/libp2p/go-libp2p/pull/1964)) + - add WebTransport to the list of default transports (#1915) ([libp2p/go-libp2p#1915](https://github.com/libp2p/go-libp2p/pull/1915)) + - core/crypto: drop all OpenSSL code paths (#1953) ([libp2p/go-libp2p#1953](https://github.com/libp2p/go-libp2p/pull/1953)) + - chore: use generic LRU cache (#1980) ([libp2p/go-libp2p#1980](https://github.com/libp2p/go-libp2p/pull/1980)) +- github.com/libp2p/go-libp2p-kad-dht (v0.20.0 -> v0.21.1): + - chore: bump to v0.21.1 (#821) ([libp2p/go-libp2p-kad-dht#821](https://github.com/libp2p/go-libp2p-kad-dht/pull/821)) + - feat: send FIND_NODE request to peers on routing table refresh (#810) ([libp2p/go-libp2p-kad-dht#810](https://github.com/libp2p/go-libp2p-kad-dht/pull/810)) + - chore: release v0.21. + - chore: Update to go libp2p v0.25 ([libp2p/go-libp2p-kad-dht#815](https://github.com/libp2p/go-libp2p-kad-dht/pull/815)) +- github.com/libp2p/go-libp2p-pubsub (v0.8.3 -> v0.9.0): + - chore: update to go-libp2p v0.25 (#517) ([libp2p/go-libp2p-pubsub#517](https://github.com/libp2p/go-libp2p-pubsub/pull/517)) +- github.com/libp2p/go-libp2p-routing-helpers (v0.6.0 -> v0.6.1): + - chore: release v0.6.1 + - fix: cancel parallel routers +- github.com/libp2p/go-msgio (v0.2.0 -> v0.3.0): + - release v0.3.0 (#39) ([libp2p/go-msgio#39](https://github.com/libp2p/go-msgio/pull/39)) + - switch from deprecated gogo to google.golang.org/protobuf ([libp2p/go-msgio#38](https://github.com/libp2p/go-msgio/pull/38)) + - sync: update CI config files (#36) ([libp2p/go-msgio#36](https://github.com/libp2p/go-msgio/pull/36)) +- github.com/lucas-clemente/quic-go (v0.31.1 -> v0.29.1): + - http3: fix double close of chan when using DontCloseRequestStream +- github.com/multiformats/go-multistream (v0.3.3 -> v0.4.1): + - release v0.4.1 ([multiformats/go-multistream#101](https://github.com/multiformats/go-multistream/pull/101)) + - Fix errors Is checking ([multiformats/go-multistream#100](https://github.com/multiformats/go-multistream/pull/100)) + - release v0.4.0 (#93) ([multiformats/go-multistream#93](https://github.com/multiformats/go-multistream/pull/93)) + - switch to Go's native fuzzing (#96) ([multiformats/go-multistream#96](https://github.com/multiformats/go-multistream/pull/96)) + - Add not supported protocols to returned errors (#97) ([multiformats/go-multistream#97](https://github.com/multiformats/go-multistream/pull/97)) + - Make MultistreamMuxer and Client APIs generic (#95) ([multiformats/go-multistream#95](https://github.com/multiformats/go-multistream/pull/95)) + - remove MultistreamMuxer.NegotiateLazy (#92) ([multiformats/go-multistream#92](https://github.com/multiformats/go-multistream/pull/92)) + - sync: update CI config files (#91) ([multiformats/go-multistream#91](https://github.com/multiformats/go-multistream/pull/91)) +- github.com/warpfork/go-wish (v0.0.0-20200122115046-b9ea61034e4a -> v0.0.0-20220906213052-39a1cc7a02d0): + - Update readme with deprecation info +- github.com/whyrusleeping/cbor-gen (v0.0.0-20221220214510-0333c149dec0 -> v0.0.0-20230126041949-52956bd4c9aa): + - add setter to allow reuse of cborreader struct + - fix typo + - allow fields to be ignored ([whyrusleeping/cbor-gen#79](https://github.com/whyrusleeping/cbor-gen/pull/79)) + +
+ ### 👨‍👩‍👧‍👦 Contributors + +| Contributor | Commits | Lines ± | Files Changed | +|-------------|---------|---------|---------------| +| Dirk McCormick | 128 | +16757/-7211 | 387 | +| Henrique Dias | 69 | +7599/-10016 | 316 | +| hannahhoward | 88 | +8503/-4397 | 271 | +| Jeromy Johnson | 244 | +6544/-4034 | 774 | +| Marten Seemann | 64 | +4870/-5628 | 266 | +| Steven Allen | 296 | +4769/-3517 | 972 | +| Brian Tiger Chow | 250 | +5520/-2579 | 435 | +| Jorropo | 64 | +4237/-3548 | 302 | +| Sukun | 18 | +4327/-1093 | 132 | +| Marco Munizaga | 35 | +2809/-1294 | 94 | +| Gus Eggert | 20 | +2523/-1476 | 99 | +| Adin Schmahmann | 15 | +683/-2625 | 69 | +| Marcin Rataj | 73 | +2348/-882 | 133 | +| whyrusleeping | 12 | +1683/-1338 | 23 | +| Jeromy | 99 | +1754/-1181 | 453 | +| Juan Batiz-Benet | 69 | +1182/-678 | 149 | +| Lars Gierth | 31 | +827/-358 | 92 | +| Paul Wolneykien | 2 | +670/-338 | 9 | +| Laurent Senta | 16 | +806/-134 | 53 | +| Henry | 19 | +438/-372 | 36 | +| Michael Muré | 8 | +400/-387 | 19 | +| Łukasz Magiera | 56 | +413/-354 | 117 | +| Jakub Sztandera | 40 | +413/-251 | 100 | +| Justin Johnson | 2 | +479/-165 | 5 | +| Piotr Galar | 7 | +227/-378 | 24 | +| Kevin Atkinson | 11 | +252/-232 | 49 | +| web3-bot | 17 | +236/-240 | 59 | +| Petar Maymounkov | 2 | +348/-84 | 11 | +| Hector Sanjuan | 38 | +206/-223 | 85 | +| Antonio Navarro Perez | 9 | +259/-95 | 17 | +| keks | 22 | +233/-118 | 24 | +| Ho-Sheng Hsiao | 3 | +170/-170 | 30 | +| Lucas Molas | 6 | +266/-54 | 16 | +| Mildred Ki'Lya | 4 | +280/-35 | 7 | +| Steve Loeppky | 5 | +147/-156 | 9 | +| rht | 14 | +97/-188 | 20 | +| Prithvi Shahi | 6 | +89/-193 | 11 | +| Ian Davis | 6 | +198/-75 | 11 | +| taylor | 1 | +180/-89 | 8 | +| ᴍᴀᴛᴛ ʙᴇʟʟ | 14 | +158/-104 | 18 | +| Chris Boddy | 6 | +190/-45 | 8 | +| Rod Vagg | 3 | +203/-28 | 15 | +| Masih H. Derkani | 8 | +165/-61 | 16 | +| Kevin Wallace | 4 | +194/-27 | 7 | +| Mohsin Zaidi | 1 | +179/-41 | 5 | +| ElPaisano | 1 | +110/-110 | 22 | +| Simon Zhu | 6 | +177/-32 | 8 | +| galargh | 9 | +80/-120 | 14 | +| Tomasz Zdybał | 1 | +180/-1 | 4 | +| dgrisham | 3 | +176/-2 | 4 | +| Michael Avila | 3 | +116/-59 | 8 | +| Raúl Kripalani | 2 | +85/-77 | 34 | +| Dr Ian Preston | 11 | +101/-48 | 11 | +| JP Hastings-Spital | 1 | +145/-0 | 2 | +| George Antoniadis | 6 | +59/-58 | 43 | +| Kevin Neaton | 2 | +97/-16 | 4 | +| Adrian Lanzafame | 6 | +81/-25 | 7 | +| Dennis Trautwein | 3 | +89/-9 | 5 | +| mathew-cf | 2 | +82/-9 | 5 | +| tg | 1 | +41/-33 | 1 | +| Eng Zer Jun | 1 | +15/-54 | 5 | +| zramsay | 4 | +15/-53 | 12 | +| muXxer | 1 | +28/-33 | 4 | +| Thomas Eizinger | 1 | +24/-37 | 4 | +| Remco Bloemen | 2 | +28/-18 | 3 | +| Manuel Alonso | 1 | +36/-9 | 1 | +| vyzo | 4 | +26/-12 | 13 | +| Djalil Dreamski | 3 | +27/-9 | 3 | +| Thomas Gardner | 2 | +32/-3 | 4 | +| Jan Winkelmann | 2 | +23/-12 | 8 | +| Artem Andreenko | 1 | +16/-19 | 1 | +| James Stanley | 1 | +34/-0 | 1 | +| Brendan McMillion | 1 | +10/-17 | 3 | +| Jack Loughran | 1 | +22/-0 | 3 | +| Peter Wu | 2 | +12/-9 | 2 | +| Gowtham G | 4 | +14/-7 | 4 | +| Tor Arne Vestbø | 3 | +19/-1 | 3 | +| Cory Schwartz | 1 | +8/-12 | 5 | +| Peter Rabbitson | 1 | +15/-4 | 1 | +| David Dias | 1 | +9/-9 | 1 | +| Will Scott | 1 | +13/-4 | 2 | +| Eric Myhre | 1 | +15/-2 | 1 | +| Stephen Whitmore | 1 | +8/-8 | 1 | +| Rafael Ramalho | 5 | +11/-5 | 5 | +| Christian Couder | 1 | +14/-2 | 1 | +| W. Trevor King | 2 | +9/-6 | 3 | +| Steven Vandevelde | 1 | +11/-3 | 1 | +| Knut Ahlers | 3 | +9/-5 | 3 | +| Bob Potter | 1 | +3/-10 | 1 | +| Russell Dempsey | 4 | +8/-4 | 4 | +| Diogo Silva | 4 | +8/-4 | 4 | +| Dave Justice | 1 | +8/-4 | 1 | +| Andy Leap | 2 | +2/-10 | 2 | +| divingpetrel | 1 | +7/-4 | 2 | +| Iaroslav Gridin | 1 | +9/-2 | 1 | +| Dominic Della Valle | 3 | +5/-5 | 3 | +| Vijayee Kulkaa | 1 | +3/-6 | 1 | +| Friedel Ziegelmayer | 3 | +6/-3 | 3 | +| Stephen Solka | 1 | +1/-7 | 1 | +| Richard Littauer | 3 | +4/-4 | 3 | +| Franky W | 2 | +4/-4 | 2 | +| Dimitris Apostolou | 2 | +4/-4 | 3 | +| Adrian Ulrich | 1 | +8/-0 | 1 | +| Masashi Salvador Mitsuzawa | 1 | +5/-1 | 1 | +| Gabe | 1 | +3/-3 | 1 | +| zuuluuz | 1 | +4/-1 | 1 | +| myml | 1 | +5/-0 | 1 | +| swedneck | 1 | +3/-1 | 1 | +| Wayback Archiver | 1 | +2/-2 | 1 | +| Vladimir Ivanov | 1 | +2/-2 | 1 | +| Péter Szilágyi | 1 | +2/-2 | 1 | +| Karthik Bala | 1 | +2/-2 | 1 | +| Etienne Laurin | 1 | +1/-3 | 1 | +| Shotaro Yamada | 1 | +2/-1 | 1 | +| Robert Carlsen | 1 | +2/-1 | 1 | +| Oli Evans | 1 | +2/-1 | 1 | +| Dan McQuillan | 1 | +2/-1 | 1 | +| susarlanikhilesh | 1 | +1/-1 | 1 | +| mateon1 | 1 | +1/-1 | 1 | +| kpcyrd | 1 | +1/-1 | 1 | +| bbenshoof | 1 | +1/-1 | 1 | +| ZenGround0 | 1 | +1/-1 | 1 | +| Will Hawkins | 1 | +1/-1 | 1 | +| Tommi Virtanen | 1 | +1/-1 | 1 | +| Seungbae Yu | 1 | +1/-1 | 1 | +| Riishab Joshi | 1 | +1/-1 | 1 | +| Kubo Mage | 1 | +1/-1 | 1 | +| Ivan | 1 | +1/-1 | 1 | +| Guillaume Renault | 1 | +1/-1 | 1 | +| Anjor Kanekar | 1 | +1/-1 | 1 | +| Andrew Chin | 1 | +1/-1 | 1 | +| Abdul Rauf | 1 | +1/-1 | 1 | +| makeworld | 1 | +1/-0 | 1 | From b975593920455c32793d4d233e49ee6762fbaf3b Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Mon, 20 Mar 2023 14:14:38 +0100 Subject: [PATCH 0570/1212] feat(gateway): invalid CID returns 400 Bad Request (#9726) --- docs/examples/kubo-as-a-library/go.mod | 4 ++-- docs/examples/kubo-as-a-library/go.sum | 8 ++++---- go.mod | 4 ++-- go.sum | 8 ++++---- test/cli/gateway_test.go | 8 ++++---- test/sharness/t0090-get.sh | 2 +- 6 files changed, 17 insertions(+), 17 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 5453ae1d5..cb8e9bc9a 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.18 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/go-libipfs v0.6.2 + github.com/ipfs/go-libipfs v0.7.0 github.com/ipfs/interface-go-ipfs-core v0.11.0 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.26.3 @@ -65,7 +65,7 @@ require ( github.com/ipfs/go-bitfield v1.1.0 // indirect github.com/ipfs/go-block-format v0.1.1 // indirect github.com/ipfs/go-blockservice v0.5.0 // indirect - github.com/ipfs/go-cid v0.3.2 // indirect + github.com/ipfs/go-cid v0.4.0 // indirect github.com/ipfs/go-cidutil v0.1.0 // indirect github.com/ipfs/go-datastore v0.6.0 // indirect github.com/ipfs/go-delegated-routing v0.7.0 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 6f7e7f253..bfdbf90fe 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -460,8 +460,8 @@ github.com/ipfs/go-cid v0.0.5/go.mod h1:plgt+Y5MnOey4vO4UlUazGqdbEXuFYitED67Fexh github.com/ipfs/go-cid v0.0.6/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I= github.com/ipfs/go-cid v0.0.7/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I= github.com/ipfs/go-cid v0.1.0/go.mod h1:rH5/Xv83Rfy8Rw6xG+id3DYAMUVmem1MowoKwdXmN2o= -github.com/ipfs/go-cid v0.3.2 h1:OGgOd+JCFM+y1DjWPmVH+2/4POtpDzwcr7VgnB7mZXc= -github.com/ipfs/go-cid v0.3.2/go.mod h1:gQ8pKqT/sUxGY+tIwy1RPpAojYu7jAyCp5Tz1svoupw= +github.com/ipfs/go-cid v0.4.0 h1:a4pdZq0sx6ZSxbCizebnKiMCx/xI/aBBFlB73IgH4rA= +github.com/ipfs/go-cid v0.4.0/go.mod h1:uQHwDeX4c6CtyrFwdqyhpNcxVewur1M7l7fNU7LKwZk= github.com/ipfs/go-cidutil v0.1.0 h1:RW5hO7Vcf16dplUU60Hs0AKDkQAVPVplr7lk97CFL+Q= github.com/ipfs/go-cidutil v0.1.0/go.mod h1:e7OEVBMIv9JaOxt9zaGEmAoSlXW9jdFZ5lP/0PwcfpA= github.com/ipfs/go-datastore v0.0.1/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= @@ -569,8 +569,8 @@ github.com/ipfs/go-ipld-legacy v0.1.1 h1:BvD8PEuqwBHLTKqlGFTHSwrwFOMkVESEvwIYwR2 github.com/ipfs/go-ipld-legacy v0.1.1/go.mod h1:8AyKFCjgRPsQFf15ZQgDB8Din4DML/fOmKZkkFkrIEg= github.com/ipfs/go-ipns v0.3.0 h1:ai791nTgVo+zTuq2bLvEGmWP1M0A6kGTXUsgv/Yq67A= github.com/ipfs/go-ipns v0.3.0/go.mod h1:3cLT2rbvgPZGkHJoPO1YMJeh6LtkxopCkKFcio/wE24= -github.com/ipfs/go-libipfs v0.6.2 h1:QUf3kS3RrCjgtE0QW2d18PFFfOLeEt24Ft892ipLzRI= -github.com/ipfs/go-libipfs v0.6.2/go.mod h1:FmhKgxMOQA572TK5DA3MZ5GL44ZqsMHIrkgK4gLn4A8= +github.com/ipfs/go-libipfs v0.7.0 h1:Mi54WJTODaOL2/ZSm5loi3SwI3jI2OuFWUrQIkJ5cpM= +github.com/ipfs/go-libipfs v0.7.0/go.mod h1:KsIf/03CqhICzyRGyGo68tooiBE2iFbI/rXW7FhAYr0= github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= github.com/ipfs/go-log v1.0.2/go.mod h1:1MNjMxe0u6xvJZgeqbJ8vdo2TKaGwZ1a0Bpza+sr2Sk= github.com/ipfs/go-log v1.0.3/go.mod h1:OsLySYkwIbiSUR/yBTdv1qPtcE4FW3WPWk/ewz9Ru+A= diff --git a/go.mod b/go.mod index f7237b46a..4a8bf632c 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,7 @@ require ( github.com/google/uuid v1.3.0 github.com/hashicorp/go-multierror v1.1.1 github.com/ipfs/go-blockservice v0.5.0 - github.com/ipfs/go-cid v0.3.2 + github.com/ipfs/go-cid v0.4.0 github.com/ipfs/go-cidutil v0.1.0 github.com/ipfs/go-datastore v0.6.0 github.com/ipfs/go-delegated-routing v0.7.0 @@ -45,7 +45,7 @@ require ( github.com/ipfs/go-ipld-git v0.1.1 github.com/ipfs/go-ipld-legacy v0.1.1 github.com/ipfs/go-ipns v0.3.0 - github.com/ipfs/go-libipfs v0.6.2 + github.com/ipfs/go-libipfs v0.7.0 github.com/ipfs/go-log v1.0.5 github.com/ipfs/go-log/v2 v2.5.1 github.com/ipfs/go-merkledag v0.9.0 diff --git a/go.sum b/go.sum index 27e101e1c..c259bc1a1 100644 --- a/go.sum +++ b/go.sum @@ -478,8 +478,8 @@ github.com/ipfs/go-cid v0.0.5/go.mod h1:plgt+Y5MnOey4vO4UlUazGqdbEXuFYitED67Fexh github.com/ipfs/go-cid v0.0.6/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I= github.com/ipfs/go-cid v0.0.7/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I= github.com/ipfs/go-cid v0.1.0/go.mod h1:rH5/Xv83Rfy8Rw6xG+id3DYAMUVmem1MowoKwdXmN2o= -github.com/ipfs/go-cid v0.3.2 h1:OGgOd+JCFM+y1DjWPmVH+2/4POtpDzwcr7VgnB7mZXc= -github.com/ipfs/go-cid v0.3.2/go.mod h1:gQ8pKqT/sUxGY+tIwy1RPpAojYu7jAyCp5Tz1svoupw= +github.com/ipfs/go-cid v0.4.0 h1:a4pdZq0sx6ZSxbCizebnKiMCx/xI/aBBFlB73IgH4rA= +github.com/ipfs/go-cid v0.4.0/go.mod h1:uQHwDeX4c6CtyrFwdqyhpNcxVewur1M7l7fNU7LKwZk= github.com/ipfs/go-cidutil v0.1.0 h1:RW5hO7Vcf16dplUU60Hs0AKDkQAVPVplr7lk97CFL+Q= github.com/ipfs/go-cidutil v0.1.0/go.mod h1:e7OEVBMIv9JaOxt9zaGEmAoSlXW9jdFZ5lP/0PwcfpA= github.com/ipfs/go-datastore v0.0.1/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= @@ -591,8 +591,8 @@ github.com/ipfs/go-ipld-legacy v0.1.1 h1:BvD8PEuqwBHLTKqlGFTHSwrwFOMkVESEvwIYwR2 github.com/ipfs/go-ipld-legacy v0.1.1/go.mod h1:8AyKFCjgRPsQFf15ZQgDB8Din4DML/fOmKZkkFkrIEg= github.com/ipfs/go-ipns v0.3.0 h1:ai791nTgVo+zTuq2bLvEGmWP1M0A6kGTXUsgv/Yq67A= github.com/ipfs/go-ipns v0.3.0/go.mod h1:3cLT2rbvgPZGkHJoPO1YMJeh6LtkxopCkKFcio/wE24= -github.com/ipfs/go-libipfs v0.6.2 h1:QUf3kS3RrCjgtE0QW2d18PFFfOLeEt24Ft892ipLzRI= -github.com/ipfs/go-libipfs v0.6.2/go.mod h1:FmhKgxMOQA572TK5DA3MZ5GL44ZqsMHIrkgK4gLn4A8= +github.com/ipfs/go-libipfs v0.7.0 h1:Mi54WJTODaOL2/ZSm5loi3SwI3jI2OuFWUrQIkJ5cpM= +github.com/ipfs/go-libipfs v0.7.0/go.mod h1:KsIf/03CqhICzyRGyGo68tooiBE2iFbI/rXW7FhAYr0= github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= github.com/ipfs/go-log v1.0.2/go.mod h1:1MNjMxe0u6xvJZgeqbJ8vdo2TKaGwZ1a0Bpza+sr2Sk= github.com/ipfs/go-log v1.0.3/go.mod h1:OsLySYkwIbiSUR/yBTdv1qPtcE4FW3WPWk/ewz9Ru+A= diff --git a/test/cli/gateway_test.go b/test/cli/gateway_test.go index d2a90b04a..4c40729c7 100644 --- a/test/cli/gateway_test.go +++ b/test/cli/gateway_test.go @@ -126,10 +126,10 @@ func TestGateway(t *testing.T) { assert.Equal(t, 404, resp.StatusCode) }) - t.Run("GET IPFS invalid CID returns 500 (Internal Server Error)", func(t *testing.T) { + t.Run("GET IPFS invalid CID returns 400 (Bad Request)", func(t *testing.T) { t.Parallel() resp := client.Get("/ipfs/QmInvalid/pleaseDontAddMe") - assert.Equal(t, 500, resp.StatusCode) + assert.Equal(t, 400, resp.StatusCode) }) t.Run("GET IPFS inlined zero-length data object returns ok code (200)", func(t *testing.T) { @@ -198,7 +198,7 @@ func TestGateway(t *testing.T) { t.Run("GET invalid IPFS path errors", func(t *testing.T) { t.Parallel() - assert.Equal(t, 500, client.Get("/ipfs/12345").StatusCode) + assert.Equal(t, 400, client.Get("/ipfs/12345").StatusCode) }) t.Run("GET invalid path errors", func(t *testing.T) { @@ -406,7 +406,7 @@ func TestGateway(t *testing.T) { gatewayAddr := URLStrToMultiaddr(node.GatewayURL()) res := node.RunIPFS("--api", gatewayAddr.String(), "refs", "local") assert.Equal(t, - `Error: invalid path "local": selected encoding not supported`, + `Error: invalid path "local": invalid cid: selected encoding not supported`, res.Stderr.Trimmed(), ) }) diff --git a/test/sharness/t0090-get.sh b/test/sharness/t0090-get.sh index 5e16c7d01..2f3838db4 100755 --- a/test/sharness/t0090-get.sh +++ b/test/sharness/t0090-get.sh @@ -129,7 +129,7 @@ test_get_cmd() { ' test_expect_success "ipfs get ../.. should fail" ' - echo "Error: invalid path \"../..\": selected encoding not supported" >expected && + echo "Error: invalid path \"../..\": invalid cid: selected encoding not supported" >expected && test_must_fail ipfs get ../.. 2>actual && test_cmp expected actual ' From 1f36e3dbe6f9ca6335182150626e4c15fcb8aa8b Mon Sep 17 00:00:00 2001 From: galargh Date: Mon, 20 Mar 2023 16:35:00 +0000 Subject: [PATCH 0571/1212] chore: create next changelog --- CHANGELOG.md | 1 + docs/changelogs/v0.20.md | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 docs/changelogs/v0.20.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 16e72bcb1..2659f2608 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ # Kubo Changelogs +- [v0.20](docs/changelogs/v0.20.md) - [v0.19](docs/changelogs/v0.19.md) - [v0.18](docs/changelogs/v0.18.md) - [v0.17](docs/changelogs/v0.17.md) diff --git a/docs/changelogs/v0.20.md b/docs/changelogs/v0.20.md new file mode 100644 index 000000000..c1c3e9639 --- /dev/null +++ b/docs/changelogs/v0.20.md @@ -0,0 +1,18 @@ +# Kubo changelog v0.20 + +- [v0.20.0](#v0200) + +## v0.20.0 + +- [Overview](#overview) +- [🔦 Highlights](#-highlights) +- [📝 Changelog](#-changelog) +- [👨‍👩‍👧‍👦 Contributors](#-contributors) + +### Overview + +### 🔦 Highlights + +### 📝 Changelog + +### 👨‍👩‍👧‍👦 Contributors From e0b08ed7832d8275477ebf7e493824e87fca73ce Mon Sep 17 00:00:00 2001 From: Gus Eggert Date: Mon, 20 Mar 2023 17:27:45 -0400 Subject: [PATCH 0572/1212] docs: use fx.Decorate instead of fx.Replace in examples (#9725) In practice there are cases when fx.Replace doesn't work as expected, so this updates the documentation to recommend using fx.Decorate instead which is a bit easier to use. --- docs/plugins.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/docs/plugins.md b/docs/plugins.md index 1feca834c..86cfe1c51 100644 --- a/docs/plugins.md +++ b/docs/plugins.md @@ -51,14 +51,15 @@ plugin type is likely the best interim solution. ### fx (experimental) Fx plugins let you customize the [fx](https://pkg.go.dev/go.uber.org/fx) dependency graph and configuration, -by customizing the`fx.Option`s that are passed to `fx` when the IPFS node is initialized. +by customizing the`fx.Option`s that are passed to `fx` when the Kubo node is initialized. -For example, you can inject custom implementations of interfaces such as [exchange.Interface](https://github.com/ipfs/go-ipfs-exchange-interface) -or [pin.Pinner](https://github.com/ipfs/go-ipfs-pinner) by adding an option like `fx.Replace(fx.Annotate(customExchange, fx.As(new(exchange.Interface))))`. +For example, you can override an interface such as [exchange.Interface](https://github.com/ipfs/go-ipfs-exchange-interface) +or [pin.Pinner](https://github.com/ipfs/go-ipfs-pinner) with a custom implementation by appending an option like +`fx.Decorate(func() exchange.Interface { return customExchange })`. Fx supports some advanced customization. Simple interface replacements like above are unlikely to break in the future, but the more invasive your changes, the more likely they are to break between releases. Kubo cannot guarantee backwards -compatibility for invasive `fx` customizations. +compatibility for `fx` customizations. Fx options are applied across every execution of the `ipfs` binary, including: @@ -68,7 +69,7 @@ Fx options are applied across every execution of the `ipfs` binary, including: - etc. So if you plug in a blockservice that disallows non-allowlisted CIDs, then this may break migrations -that fetch migration code over IPFS. +that fetch migration code over the IPFS network. ### Internal From 7b9819e5263203eb437dfa4889363ad67f96721e Mon Sep 17 00:00:00 2001 From: galargh Date: Thu, 2 Mar 2023 09:07:56 +0100 Subject: [PATCH 0573/1212] ci: remove circleci config --- .circleci/config.yml | 37 ---- .circleci/main.yml | 404 ------------------------------------------- 2 files changed, 441 deletions(-) delete mode 100644 .circleci/config.yml delete mode 100644 .circleci/main.yml diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index 3da57d246..000000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,37 +0,0 @@ -version: 2.1 -setup: true -orbs: - continuation: circleci/continuation@0.2.0 -jobs: - generate-params: - executor: continuation/default - steps: - - checkout - - run: - name: Generate params - # for builds on the ipfs/kubo repo, use 2xlarge for faster builds - # but since this is not available for many contributors, we otherwise use medium - command: | - echo $CIRCLE_REPOSITORY_URL - if [ "$CIRCLE_REPOSITORY_URL" = 'git@github.com:ipfs/kubo.git' ]; then - resource_class=2xlarge - make_jobs=10 - else - resource_class=medium - make_jobs=3 - fi - cat \<<- EOF > params.json - { - "resource_class": "$resource_class", - "make_jobs": "$make_jobs" - } - EOF - cat params.json - - continuation/continue: - parameters: params.json - configuration_path: .circleci/main.yml -workflows: - version: 2 - setup-workflow: - jobs: - - generate-params diff --git a/.circleci/main.yml b/.circleci/main.yml deleted file mode 100644 index b6be1d914..000000000 --- a/.circleci/main.yml +++ /dev/null @@ -1,404 +0,0 @@ -version: 2.1 - -parameters: - resource_class: - type: string - default: medium - make_jobs: - type: string - default: 3 - -aliases: - make_out_dirs: &make_out_dirs - run: mkdir -p /tmp/circleci-artifacts /tmp/circleci-workspace /tmp/circleci-test-results/{unit,sharness} - restore_gomod: &restore_gomod - restore_cache: - keys: - - v5-dep-{{ .Branch }}-{{ checksum "~/ipfs/kubo/go.sum" }}-{{ .Environment.CIRCLE_JOB }} - - v5-dep-{{ .Branch }}-{{ checksum "~/ipfs/kubo/go.sum" }}- - - v5-dep-{{ .Branch }}- - - v5-dep-master- - store_gomod: &store_gomod - save_cache: - key: v5-dep-{{ .Branch }}-{{ checksum "~/ipfs/kubo/go.sum" }}-{{ .Environment.CIRCLE_JOB }} - paths: - - ~/go/pkg/mod - - ~/.cache/go-build/ - -default_environment: &default_environment - SERVICE: circle-ci - TRAVIS: 1 - CIRCLE: 1 - CIRCLE_TEST_REPORTS: /tmp/circleci-test-results - CIRCLE_ARTIFACTS: /tmp/circleci-artifacts - GIT_PAGER: cat - -executors: - golang: - docker: - - image: cimg/go:1.19.1 - working_directory: ~/ipfs/kubo - environment: - <<: *default_environment - TEST_NO_DOCKER: 1 - TEST_NO_FUSE: 1 - TEST_VERBOSE: 1 - node: - docker: - - image: circleci/node:14 - working_directory: ~/ipfs/kubo - environment: - <<: *default_environment - node-browsers: - docker: - - image: circleci/node:16.12.0-browsers - working_directory: ~/ipfs/kubo - environment: - <<: *default_environment - NO_SANDBOX: true - LIBP2P_TCP_REUSEPORT: false - LIBP2P_ALLOW_WEAK_RSA_KEYS: 1 - E2E_IPFSD_TYPE: go - dockerizer: - docker: - - image: cimg/go:1.19.1 - environment: - IMAGE_NAME: ipfs/kubo - WIP_IMAGE_TAG: wip - -jobs: - gobuild: - executor: golang - resource_class: 2xlarge+ - steps: - - checkout - - *make_out_dirs - - *restore_gomod - - run: - command: make cmd/ipfs-try-build - environment: - TEST_NO_FUSE: 0 - - run: - command: make cmd/ipfs-try-build - environment: - TEST_NO_FUSE: 1 - - *store_gomod - golint: - executor: golang - steps: - - checkout - - *make_out_dirs - - *restore_gomod - - run: | - make -O test_go_lint - - *store_gomod - gotest: - executor: golang - steps: - - checkout - - *make_out_dirs - - *restore_gomod - - - run: | - make -j 1 test/unit/gotest.junit.xml \ - && [[ ! $(jq -s -c 'map(select(.Action == "fail")) | .[]' test/unit/gotest.json) ]] - - run: - when: always - command: bash <(curl -s https://codecov.io/bash) -cF unittests -X search -f coverage/unit_tests.coverprofile - - run: - command: | - # we want to first test with the kubo version in the go.mod file - go test -v ./... - - # we also want to test the examples against the current version of kubo - # however, that version might be in a fork so we need to replace the dependency - - # backup the go.mod and go.sum files to restore them after we run the tests - cp go.mod go.mod.bak - cp go.sum go.sum.bak - - # make sure the examples run against the current version of kubo - go mod edit -replace github.com/ipfs/kubo=./../../.. - go mod tidy - - go test -v ./... - - # restore the go.mod and go.sum files to their original state - mv go.mod.bak go.mod - mv go.sum.bak go.sum - working_directory: ~/ipfs/kubo/docs/examples/kubo-as-a-library - - - run: - when: always - command: mv "test/unit/gotest.junit.xml" /tmp/circleci-test-results/unit - - - *store_gomod - - - store_test_results: - path: /tmp/circleci-test-results - # Save artifacts - - store_artifacts: - path: /tmp/circleci-artifacts - - store_artifacts: - path: /tmp/circleci-test-results - sharness: - machine: - image: ubuntu-2204:2022.10.1 - resource_class: << pipeline.parameters.resource_class >> - working_directory: ~/ipfs/kubo - environment: - <<: *default_environment - TEST_NO_DOCKER: 0 - TEST_NO_PLUGIN: 1 - TEST_NO_FUSE: 1 - TEST_VERBOSE: 1 - TEST_JUNIT: 1 - TEST_EXPENSIVE: 1 - steps: - - run: sudo apt update - - run: | - mkdir ~/localgo && cd ~/localgo - wget https://golang.org/dl/go1.19.1.linux-amd64.tar.gz - tar xfz go1.19.1.linux-amd64.tar.gz - echo "export PATH=$(pwd)/go/bin:\$PATH" >> ~/.bashrc - - run: go version - - run: sudo apt install socat net-tools fish libxml2-utils - - checkout - - - run: - mkdir rb-pinning-service-api && - cd rb-pinning-service-api && - git init && - git remote add origin https://github.com/ipfs-shipyard/rb-pinning-service-api.git && - git fetch --depth 1 origin 773c3adbb421c551d2d89288abac3e01e1f7c3a8 && - git checkout FETCH_HEAD - - run: - cd rb-pinning-service-api && - (for i in {1..3}; do docker-compose pull && break || sleep 5; done) && - docker-compose up -d - - - *make_out_dirs - - *restore_gomod - - - run: - name: Setup Environment Variables - # we need the docker host IP; all ports exported by child containers can be accessed there. - command: echo "export TEST_DOCKER_HOST=$(ip -4 addr show docker0 | grep -Po 'inet \K[\d.]+')" >> $BASH_ENV - - run: - echo TEST_DOCKER_HOST=$TEST_DOCKER_HOST && - make -O -j << pipeline.parameters.make_jobs >> test_sharness coverage/sharness_tests.coverprofile test/sharness/test-results/sharness.xml CONTINUE_ON_S_FAILURE=1 TEST_DOCKER_HOST=$TEST_DOCKER_HOST - - run: - when: always - command: bash <(curl -s https://codecov.io/bash) -cF sharness -X search -f coverage/sharness_tests.coverprofile - - - run: mv "test/sharness/test-results/sharness.xml" /tmp/circleci-test-results/sharness - # make sure we fail if there are test failures - - run: find test/sharness/test-results -name 't*-*.sh.*.counts' | test/sharness/lib/sharness/aggregate-results.sh | grep 'failed\s*0' - - - *store_gomod - - - store_test_results: - path: /tmp/circleci-test-results - # Save artifacts - - store_artifacts: - path: /tmp/circleci-artifacts - - store_artifacts: - path: /tmp/circleci-test-results - build: - executor: golang - steps: - - checkout - - *make_out_dirs - - *restore_gomod - - run: - name: Building - command: make build - - run: - name: Storing - command: | - mkdir -p /tmp/circleci-workspace/bin - cp cmd/ipfs/ipfs /tmp/circleci-workspace/bin - - persist_to_workspace: - root: /tmp/circleci-workspace - paths: - - bin/ipfs - - *store_gomod - interop: - docker: - - image: cimg/go:1.19.1-node - parallelism: 4 - resource_class: 2xlarge+ - steps: - - *make_out_dirs - - attach_workspace: - at: /tmp/circleci-workspace - - restore_cache: - keys: - - v2-interop-{{ .Branch }}-{{ .Revision }} - - v2-interop-{{ .Branch }}- - - v2-interop- - - run: - name: Installing dependencies - command: | - npm init -y - npm install ipfs@^0.66.0 - npm install kubo-rpc-client@^3.0.1 - npm install ipfs-interop@^10.0.1 - npm install mocha-circleci-reporter@0.0.3 - working_directory: ~/ipfs/kubo/interop - - run: - name: Running tests - command: | - mkdir -p /tmp/test-results/interop/ - export MOCHA_FILE="$(mktemp /tmp/test-results/interop/unit.XXXXXX.xml)" - npx ipfs-interop -- -t node -f $(sed -n -e "s|^import '\(.*\)'$|test/\1|p" node_modules/ipfs-interop/test/node.js | circleci tests split --split-by=timings) -- --reporter mocha-circleci-reporter - working_directory: ~/ipfs/kubo/interop - environment: - LIBP2P_TCP_REUSEPORT: false - LIBP2P_ALLOW_WEAK_RSA_KEYS: 1 - IPFS_GO_EXEC: /tmp/circleci-workspace/bin/ipfs - - store_test_results: - path: /tmp/test-results - - save_cache: - key: v2-interop-{{ .Branch }}-{{ .Revision }} - paths: - - ~/ipfs/kubo/interop/node_modules - go-ipfs-api: - executor: golang - steps: - - *make_out_dirs - - attach_workspace: - at: /tmp/circleci-workspace - - run: - name: Cloning - command: | - git clone https://github.com/ipfs/go-ipfs-api.git - git -C go-ipfs-api log -1 - - run: - name: Starting the daemon - command: /tmp/circleci-workspace/bin/ipfs daemon --init --enable-namesys-pubsub - background: true - - run: - name: Waiting for the daemon - no_output_timeout: 30s - command: | - while ! /tmp/circleci-workspace/bin/ipfs id --api=/ip4/127.0.0.1/tcp/5001 2>/dev/null; do - sleep 1 - done - - restore_cache: - keys: - - v1-go-api-{{ checksum "~/ipfs/kubo/go-ipfs-api/go.sum" }} - - v1-go-api- - - run: - command: go test -count=1 -v ./... - working_directory: ~/ipfs/kubo/go-ipfs-api - - save_cache: - key: v2-go-api-{{ checksum "~/ipfs/kubo/go-ipfs-api/go.sum" }} - paths: - - ~/go/pkg/mod - - ~/.cache/go-build/ - - run: - name: Stopping the daemon - command: /tmp/circleci-workspace/bin/ipfs shutdown - go-ipfs-http-client: - executor: golang - steps: - - *make_out_dirs - - attach_workspace: - at: /tmp/circleci-workspace - - run: - name: Cloning - command: | - git clone https://github.com/ipfs/go-ipfs-http-client.git -b bump-for-rcmgr-last-push - git -C go-ipfs-http-client log -1 - - restore_cache: - keys: - - v1-http-client-{{ checksum "~/ipfs/kubo/go-ipfs-http-client/go.sum" }} - - v1-http-client- - - run: - name: go test -count=1 -v ./... - command: | - export PATH=/tmp/circleci-workspace/bin:$PATH - go test -count=1 -v ./... - working_directory: ~/ipfs/kubo/go-ipfs-http-client - - save_cache: - key: v1-http-client-{{ checksum "~/ipfs/kubo/go-ipfs-http-client/go.sum" }} - paths: - - ~/go/pkg/mod - - ~/.cache/go-build/ - ipfs-webui: - executor: node-browsers - resource_class: 2xlarge+ - steps: - - *make_out_dirs - - attach_workspace: - at: /tmp/circleci-workspace - - run: - name: Cloning - command: | - git clone https://github.com/ipfs/ipfs-webui.git - git -C ipfs-webui log -1 - - restore_cache: - keys: - - v1-ipfs-webui-{{ checksum "~/ipfs/kubo/ipfs-webui/package-lock.json" }} - - v1-ipfs-webui- - - run: - name: Installing dependencies - command: | - npm ci --prefer-offline --no-audit --progress=false --cache ~/ipfs/kubo/.cache/npm - npx playwright install - working_directory: ~/ipfs/kubo/ipfs-webui - - run: - name: Run ipfs-webui@main build and smoke-test to confirm the upstream repo is not broken - command: | - npm test - working_directory: ~/ipfs/kubo/ipfs-webui - - run: - name: Test ipfs-webui@main E2E against the locally built Kubo binary - command: npm run test:e2e - working_directory: ~/ipfs/kubo/ipfs-webui - environment: - IPFS_GO_EXEC: /tmp/circleci-workspace/bin/ipfs - - save_cache: - key: v1-ipfs-webui-{{ checksum "~/ipfs/kubo/ipfs-webui/package-lock.json" }} - paths: - - ~/.cache/ms-playwright - - ~/ipfs/kubo/.cache/npm - # We only run build as a test here. DockerHub images are built and published - # by GitHub Action now: https://github.com/ipfs/kubo/pull/8467 - docker-build: - executor: dockerizer - steps: - - checkout - - setup_remote_docker: - version: "19.03.13" - - run: - name: Build Docker image - command: | - docker build -t $IMAGE_NAME:$WIP_IMAGE_TAG . - -workflows: - version: 2 - - # Runs for all branches, but not on tags - # see: https://circleci.com/docs/2.0/workflows/#executing-workflows-for-a-git-tag - test: - jobs: - - gobuild - - golint - - gotest - - sharness - - build - - interop: - requires: - - build - - go-ipfs-api: - requires: - - build - - go-ipfs-http-client: - requires: - - build - - ipfs-webui: - requires: - - build - - docker-build From ceed43ea0e4b402f8873f4bfe47ee8a191e99a5f Mon Sep 17 00:00:00 2001 From: galargh Date: Thu, 2 Mar 2023 09:11:48 +0100 Subject: [PATCH 0574/1212] chore: clean up after circleci removal --- README.md | 5 ++--- bin/get-docker-tags.sh | 5 +---- bin/mkreleaselog | 1 - bin/push-docker-tags.sh | 12 ++++-------- codecov.yml | 3 +-- 5 files changed, 8 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 94e5e42af..07f8a87c5 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,6 @@ [![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square&cacheSeconds=3600)](https://protocol.ai) [![GoDoc](https://img.shields.io/badge/godoc-reference-5272B4.svg?style=flat-square&cacheSeconds=3600)](https://godoc.org/github.com/ipfs/kubo) -[![CircleCI](https://img.shields.io/circleci/build/github/ipfs/kubo?style=flat-square&cacheSeconds=3600)](https://circleci.com/gh/ipfs/kubo) ## What is Kubo? @@ -33,7 +32,7 @@ Before opening an issue, consider using one of the following locations to ensure - Exploration of new ideas in [ipfs/notes issues](https://github.com/ipfs/notes/issues). - Ask questions and meet the rest of the community at the [IPFS Forum](https://discuss.ipfs.tech). - Or [chat with us](https://docs.ipfs.tech/community/chat/). - + [![YouTube Channel Subscribers](https://img.shields.io/youtube/channel/subscribers/UCdjsUXJ3QawK4O5L1kqqsew?label=Subscribe%20IPFS&style=social&cacheSeconds=3600)](https://www.youtube.com/channel/UCdjsUXJ3QawK4O5L1kqqsew) [![Follow @IPFS on Twitter](https://img.shields.io/twitter/follow/IPFS?style=social&cacheSeconds=3600)](https://twitter.com/IPFS) ## Next milestones @@ -68,7 +67,7 @@ Before opening an issue, consider using one of the following locations to ensure - [Unofficial MacOS packages](#unofficial-macos-packages) - [MacPorts](#macports) - [Nix](#nix-macos) - - [Homebrew](#homebrew) + - [Homebrew](#homebrew) - [Build from Source](#build-from-source) - [Install Go](#install-go) - [Download and Compile IPFS](#download-and-compile-ipfs) diff --git a/bin/get-docker-tags.sh b/bin/get-docker-tags.sh index e50ec69fa..e54da6482 100755 --- a/bin/get-docker-tags.sh +++ b/bin/get-docker-tags.sh @@ -6,16 +6,13 @@ # ./get-docker-tags.sh [git tag name] # # Example: -# +# # # get tag for the master branch # ./get-docker-tags.sh $(date -u +%F) testingsha master # # # get tag for a release tag # ./get-docker-tags.sh $(date -u +%F) testingsha release v0.5.0 # -# # Serving suggestion in circle ci - https://circleci.com/docs/2.0/env-vars/#built-in-environment-variables -# ./get-docker-tags.sh $(date -u +%F) "$CIRCLE_SHA1" "$CIRCLE_BRANCH" "$CIRCLE_TAG" -# set -euo pipefail if [[ $# -lt 1 ]] ; then diff --git a/bin/mkreleaselog b/bin/mkreleaselog index 1b31854a7..bd8d418b0 100755 --- a/bin/mkreleaselog +++ b/bin/mkreleaselog @@ -41,7 +41,6 @@ IGNORE_FILES=( "go.mod" "go.sum" ".github" - ".circleci" "*.pb.go" "cbor_gen.go" "ipldsch_*.go" diff --git a/bin/push-docker-tags.sh b/bin/push-docker-tags.sh index 00d314c07..af809b989 100755 --- a/bin/push-docker-tags.sh +++ b/bin/push-docker-tags.sh @@ -2,11 +2,10 @@ # push-docker-tags.sh # -# Run from ci to tag images based on the current branch or tag name. +# Run from ci to tag images based on the current branch or tag name. # A bit like dockerhub autobuild config, but somewhere we can version control it. -# -# The `docker-build` job in .circleci/config.yml builds the current commit -# in docker and tags it as ipfs/go-ipfs:wip +# +# The `docker-build` job builds the current commit in docker and tags it as ipfs/go-ipfs:wip # # Then the `docker-publish` job runs this script to decide what tag, if any, # to publish to dockerhub. @@ -17,16 +16,13 @@ # Example: # # dry run. pass a 5th arg to have it print what it would do rather than do it. # ./push-docker-tags.sh $(date -u +%F) testingsha master "" dryrun -# +# # # push tag for the master branch # ./push-docker-tags.sh $(date -u +%F) testingsha master # # # push tag for a release tag # ./push-docker-tags.sh $(date -u +%F) testingsha release v0.5.0 # -# # Serving suggestion in circle ci - https://circleci.com/docs/2.0/env-vars/#built-in-environment-variables -# ./push-docker-tags.sh $(date -u +%F) "$CIRCLE_SHA1" "$CIRCLE_BRANCH" "$CIRCLE_TAG" -# set -euo pipefail if [[ $# -lt 1 ]] ; then diff --git a/codecov.yml b/codecov.yml index f6d4fc05b..8405abb90 100644 --- a/codecov.yml +++ b/codecov.yml @@ -1,10 +1,9 @@ codecov: ci: - - "ci/circle-ci" - "!travis-ci.org" - "!ci.ipfs.team:8111" - "!ci.ipfs.team" - - "!github.com" + - "github.com" notify: require_ci_to_pass: no after_n_builds: 2 From be3bde6df9036aaf34ef25333943cc53dace5b25 Mon Sep 17 00:00:00 2001 From: galargh Date: Thu, 2 Mar 2023 09:13:27 +0100 Subject: [PATCH 0575/1212] ci: remove experimental tags from GHA workflows --- .github/workflows/build.yml | 2 +- .github/workflows/docker-build.yml | 2 +- .github/workflows/gobuild.yml | 2 +- .github/workflows/golint.yml | 2 +- .github/workflows/gotest.yml | 2 +- .github/workflows/runner.yml | 2 +- .github/workflows/sharness.yml | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2994d7d1a..dfa876823 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,4 +1,4 @@ -name: 'ci/gh-experiment: interop' +name: 'ci/gh: interop' on: workflow_dispatch: diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml index 23e29bf39..0dfedd74a 100644 --- a/.github/workflows/docker-build.yml +++ b/.github/workflows/docker-build.yml @@ -1,4 +1,4 @@ -name: 'ci/gh-experiment: docker-build' +name: 'ci/gh: docker-build' on: workflow_dispatch: diff --git a/.github/workflows/gobuild.yml b/.github/workflows/gobuild.yml index 532d34590..658da533d 100644 --- a/.github/workflows/gobuild.yml +++ b/.github/workflows/gobuild.yml @@ -1,4 +1,4 @@ -name: 'ci/gh-experiment: go build' +name: 'ci/gh: go build' on: workflow_dispatch: diff --git a/.github/workflows/golint.yml b/.github/workflows/golint.yml index a6593582d..2a6ebf3f5 100644 --- a/.github/workflows/golint.yml +++ b/.github/workflows/golint.yml @@ -1,4 +1,4 @@ -name: 'ci/gh-experiment: go lint' +name: 'ci/gh: go lint' on: workflow_dispatch: diff --git a/.github/workflows/gotest.yml b/.github/workflows/gotest.yml index e594b55ee..d9d9c5bc5 100644 --- a/.github/workflows/gotest.yml +++ b/.github/workflows/gotest.yml @@ -1,4 +1,4 @@ -name: 'ci/gh-experiment: go test' +name: 'ci/gh: go test' on: workflow_dispatch: diff --git a/.github/workflows/runner.yml b/.github/workflows/runner.yml index c8aef2256..73182ace4 100644 --- a/.github/workflows/runner.yml +++ b/.github/workflows/runner.yml @@ -1,4 +1,4 @@ -name: 'ci/gh-experiment: choose runner' +name: 'ci/gh: choose runner' on: workflow_call: diff --git a/.github/workflows/sharness.yml b/.github/workflows/sharness.yml index 8809f2a53..8def7933e 100644 --- a/.github/workflows/sharness.yml +++ b/.github/workflows/sharness.yml @@ -1,4 +1,4 @@ -name: 'ci/gh-experiment: sharness' +name: 'ci/gh: sharness' on: workflow_dispatch: From 337ddb122787fc5a7f152e072206ddea0776efd7 Mon Sep 17 00:00:00 2001 From: galargh Date: Thu, 2 Mar 2023 09:15:57 +0100 Subject: [PATCH 0576/1212] ci: remove ci/gh prefix from GHA workflows --- .github/workflows/build.yml | 2 +- .github/workflows/docker-build.yml | 2 +- .github/workflows/gobuild.yml | 2 +- .github/workflows/golint.yml | 2 +- .github/workflows/gotest.yml | 2 +- .github/workflows/runner.yml | 2 +- .github/workflows/sharness.yml | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index dfa876823..db1e6880a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,4 +1,4 @@ -name: 'ci/gh: interop' +name: 'interop' on: workflow_dispatch: diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml index 0dfedd74a..e0cbe75b7 100644 --- a/.github/workflows/docker-build.yml +++ b/.github/workflows/docker-build.yml @@ -1,4 +1,4 @@ -name: 'ci/gh: docker-build' +name: 'docker-build' on: workflow_dispatch: diff --git a/.github/workflows/gobuild.yml b/.github/workflows/gobuild.yml index 658da533d..3d1387ccb 100644 --- a/.github/workflows/gobuild.yml +++ b/.github/workflows/gobuild.yml @@ -1,4 +1,4 @@ -name: 'ci/gh: go build' +name: 'go build' on: workflow_dispatch: diff --git a/.github/workflows/golint.yml b/.github/workflows/golint.yml index 2a6ebf3f5..9a7ad81f9 100644 --- a/.github/workflows/golint.yml +++ b/.github/workflows/golint.yml @@ -1,4 +1,4 @@ -name: 'ci/gh: go lint' +name: 'go lint' on: workflow_dispatch: diff --git a/.github/workflows/gotest.yml b/.github/workflows/gotest.yml index d9d9c5bc5..e7ece897a 100644 --- a/.github/workflows/gotest.yml +++ b/.github/workflows/gotest.yml @@ -1,4 +1,4 @@ -name: 'ci/gh: go test' +name: 'go test' on: workflow_dispatch: diff --git a/.github/workflows/runner.yml b/.github/workflows/runner.yml index 73182ace4..7b609737a 100644 --- a/.github/workflows/runner.yml +++ b/.github/workflows/runner.yml @@ -1,4 +1,4 @@ -name: 'ci/gh: choose runner' +name: 'choose runner' on: workflow_call: diff --git a/.github/workflows/sharness.yml b/.github/workflows/sharness.yml index 8def7933e..b564d2177 100644 --- a/.github/workflows/sharness.yml +++ b/.github/workflows/sharness.yml @@ -1,4 +1,4 @@ -name: 'ci/gh: sharness' +name: 'sharness' on: workflow_dispatch: From 2d65120fd5352af9c057acc5eb79023838276409 Mon Sep 17 00:00:00 2001 From: galargh Date: Thu, 2 Mar 2023 09:54:48 +0100 Subject: [PATCH 0577/1212] ci: standarise gha names --- .github/workflows/build.yml | 4 ++-- .github/workflows/codeql-analysis.yml | 3 +-- .github/workflows/docker-build.yml | 4 ++-- .github/workflows/docker-image.yml | 4 ++-- .github/workflows/gobuild.yml | 4 ++-- .github/workflows/golang-analysis.yml | 4 ++-- .github/workflows/golint.yml | 4 ++-- .github/workflows/gotest.yml | 4 ++-- .github/workflows/runner.yml | 2 +- .github/workflows/sharness.yml | 4 ++-- .github/workflows/sync-release-assets.yml | 4 ++-- 11 files changed, 20 insertions(+), 21 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index db1e6880a..4a61e18b0 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,4 +1,4 @@ -name: 'interop' +name: Interop on: workflow_dispatch: @@ -38,7 +38,7 @@ jobs: with: name: kubo path: cmd/ipfs/ipfs - ipfs-interop: + interop: needs: [prepare] runs-on: ubuntu-latest timeout-minutes: 20 diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index e732a1148..d4b16857f 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -16,9 +16,8 @@ permissions: security-events: write # (github/codeql-action/autobuild) jobs: - analyze: + go: if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' - name: Analyze runs-on: ubuntu-latest timeout-minutes: 20 diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml index e0cbe75b7..2d76cc8eb 100644 --- a/.github/workflows/docker-build.yml +++ b/.github/workflows/docker-build.yml @@ -1,4 +1,4 @@ -name: 'docker-build' +name: Docker Build on: workflow_dispatch: @@ -8,7 +8,7 @@ on: - 'master' jobs: - docker-build: + head: if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' runs-on: ubuntu-latest timeout-minutes: 10 diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index e612fba0c..47c375440 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -1,4 +1,4 @@ -name: Publish Docker image +name: Docker Push on: workflow_dispatch: @@ -13,7 +13,7 @@ permissions: contents: read # to fetch code (actions/checkout) jobs: - push_to_registry: + docker-hub: if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' name: Push Docker image to Docker Hub runs-on: ubuntu-latest diff --git a/.github/workflows/gobuild.yml b/.github/workflows/gobuild.yml index 3d1387ccb..9fe883392 100644 --- a/.github/workflows/gobuild.yml +++ b/.github/workflows/gobuild.yml @@ -1,4 +1,4 @@ -name: 'go build' +name: Go Build on: workflow_dispatch: @@ -11,7 +11,7 @@ jobs: runner: if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' uses: ipfs/kubo/.github/workflows/runner.yml@master - gobuild: + build: needs: [runner] runs-on: ${{ fromJSON(needs.runner.outputs.config).labels }} timeout-minutes: 20 diff --git a/.github/workflows/golang-analysis.yml b/.github/workflows/golang-analysis.yml index 982ab085f..b0eced941 100644 --- a/.github/workflows/golang-analysis.yml +++ b/.github/workflows/golang-analysis.yml @@ -1,4 +1,4 @@ -name: Go Checks +name: Go Check on: workflow_dispatch: @@ -11,7 +11,7 @@ permissions: contents: read # to fetch code (actions/checkout) jobs: - unit: + check: if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' runs-on: ubuntu-latest timeout-minutes: 10 diff --git a/.github/workflows/golint.yml b/.github/workflows/golint.yml index 9a7ad81f9..524beb018 100644 --- a/.github/workflows/golint.yml +++ b/.github/workflows/golint.yml @@ -1,4 +1,4 @@ -name: 'go lint' +name: Go Lint on: workflow_dispatch: @@ -8,7 +8,7 @@ on: - 'master' jobs: - golint: + lint: if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' runs-on: ubuntu-latest timeout-minutes: 10 diff --git a/.github/workflows/gotest.yml b/.github/workflows/gotest.yml index e7ece897a..76c090c2f 100644 --- a/.github/workflows/gotest.yml +++ b/.github/workflows/gotest.yml @@ -1,4 +1,4 @@ -name: 'go test' +name: Go Test on: workflow_dispatch: @@ -8,7 +8,7 @@ on: - 'master' jobs: - gotest: + test: if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' runs-on: ubuntu-latest timeout-minutes: 20 diff --git a/.github/workflows/runner.yml b/.github/workflows/runner.yml index 7b609737a..74a8b41d7 100644 --- a/.github/workflows/runner.yml +++ b/.github/workflows/runner.yml @@ -1,4 +1,4 @@ -name: 'choose runner' +name: Runner on: workflow_call: diff --git a/.github/workflows/sharness.yml b/.github/workflows/sharness.yml index b564d2177..8e29386ff 100644 --- a/.github/workflows/sharness.yml +++ b/.github/workflows/sharness.yml @@ -1,4 +1,4 @@ -name: 'sharness' +name: Sharness on: workflow_dispatch: @@ -11,7 +11,7 @@ jobs: runner: if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' uses: ipfs/kubo/.github/workflows/runner.yml@master - sharness: + test: needs: [runner] runs-on: ${{ fromJSON(needs.runner.outputs.config).labels }} timeout-minutes: 20 diff --git a/.github/workflows/sync-release-assets.yml b/.github/workflows/sync-release-assets.yml index 0c295d804..23bf90748 100644 --- a/.github/workflows/sync-release-assets.yml +++ b/.github/workflows/sync-release-assets.yml @@ -1,4 +1,4 @@ -name: Sync github release assets with dist.ipfs.tech +name: Sync GitHub Release Assets on: workflow_dispatch: @@ -13,7 +13,7 @@ permissions: contents: write # to upload release asset jobs: - sync-github-and-dist-ipfs-tech: + dist-ipfs-tech: if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' runs-on: "ubuntu-latest" timeout-minutes: 5 From a8f2c12f71703a6fd840d82c65588a3fc9dde89e Mon Sep 17 00:00:00 2001 From: galargh Date: Thu, 2 Mar 2023 09:56:07 +0100 Subject: [PATCH 0578/1212] ci: rename gha workflow files to match workflow names --- .github/workflows/{codeql-analysis.yml => codeql.yml} | 0 .github/workflows/{docker-image.yml => docker-push.yml} | 0 .github/workflows/{gobuild.yml => go-build.yml} | 0 .github/workflows/{golang-analysis.yml => go-check.yml} | 0 .github/workflows/{golint.yml => go-lint.yml} | 0 .github/workflows/{gotest.yml => go-test.yml} | 0 .github/workflows/{build.yml => interop.yml} | 0 .../{sync-release-assets.yml => sync-github-release-assets.yml} | 0 8 files changed, 0 insertions(+), 0 deletions(-) rename .github/workflows/{codeql-analysis.yml => codeql.yml} (100%) rename .github/workflows/{docker-image.yml => docker-push.yml} (100%) rename .github/workflows/{gobuild.yml => go-build.yml} (100%) rename .github/workflows/{golang-analysis.yml => go-check.yml} (100%) rename .github/workflows/{golint.yml => go-lint.yml} (100%) rename .github/workflows/{gotest.yml => go-test.yml} (100%) rename .github/workflows/{build.yml => interop.yml} (100%) rename .github/workflows/{sync-release-assets.yml => sync-github-release-assets.yml} (100%) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql.yml similarity index 100% rename from .github/workflows/codeql-analysis.yml rename to .github/workflows/codeql.yml diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-push.yml similarity index 100% rename from .github/workflows/docker-image.yml rename to .github/workflows/docker-push.yml diff --git a/.github/workflows/gobuild.yml b/.github/workflows/go-build.yml similarity index 100% rename from .github/workflows/gobuild.yml rename to .github/workflows/go-build.yml diff --git a/.github/workflows/golang-analysis.yml b/.github/workflows/go-check.yml similarity index 100% rename from .github/workflows/golang-analysis.yml rename to .github/workflows/go-check.yml diff --git a/.github/workflows/golint.yml b/.github/workflows/go-lint.yml similarity index 100% rename from .github/workflows/golint.yml rename to .github/workflows/go-lint.yml diff --git a/.github/workflows/gotest.yml b/.github/workflows/go-test.yml similarity index 100% rename from .github/workflows/gotest.yml rename to .github/workflows/go-test.yml diff --git a/.github/workflows/build.yml b/.github/workflows/interop.yml similarity index 100% rename from .github/workflows/build.yml rename to .github/workflows/interop.yml diff --git a/.github/workflows/sync-release-assets.yml b/.github/workflows/sync-github-release-assets.yml similarity index 100% rename from .github/workflows/sync-release-assets.yml rename to .github/workflows/sync-github-release-assets.yml From 64d3c153cbe2c439513d7a972530cf6606fb87b8 Mon Sep 17 00:00:00 2001 From: galargh Date: Thu, 2 Mar 2023 10:14:30 +0100 Subject: [PATCH 0579/1212] Revert "ci: rename gha workflow files to match workflow names" This reverts commit d164129258f456fb70dc709b59d743a8aed57cc2. --- .github/workflows/{interop.yml => build.yml} | 0 .github/workflows/{codeql.yml => codeql-analysis.yml} | 0 .github/workflows/{docker-push.yml => docker-image.yml} | 0 .github/workflows/{go-build.yml => gobuild.yml} | 0 .github/workflows/{go-check.yml => golang-analysis.yml} | 0 .github/workflows/{go-lint.yml => golint.yml} | 0 .github/workflows/{go-test.yml => gotest.yml} | 0 .../{sync-github-release-assets.yml => sync-release-assets.yml} | 0 8 files changed, 0 insertions(+), 0 deletions(-) rename .github/workflows/{interop.yml => build.yml} (100%) rename .github/workflows/{codeql.yml => codeql-analysis.yml} (100%) rename .github/workflows/{docker-push.yml => docker-image.yml} (100%) rename .github/workflows/{go-build.yml => gobuild.yml} (100%) rename .github/workflows/{go-check.yml => golang-analysis.yml} (100%) rename .github/workflows/{go-lint.yml => golint.yml} (100%) rename .github/workflows/{go-test.yml => gotest.yml} (100%) rename .github/workflows/{sync-github-release-assets.yml => sync-release-assets.yml} (100%) diff --git a/.github/workflows/interop.yml b/.github/workflows/build.yml similarity index 100% rename from .github/workflows/interop.yml rename to .github/workflows/build.yml diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql-analysis.yml similarity index 100% rename from .github/workflows/codeql.yml rename to .github/workflows/codeql-analysis.yml diff --git a/.github/workflows/docker-push.yml b/.github/workflows/docker-image.yml similarity index 100% rename from .github/workflows/docker-push.yml rename to .github/workflows/docker-image.yml diff --git a/.github/workflows/go-build.yml b/.github/workflows/gobuild.yml similarity index 100% rename from .github/workflows/go-build.yml rename to .github/workflows/gobuild.yml diff --git a/.github/workflows/go-check.yml b/.github/workflows/golang-analysis.yml similarity index 100% rename from .github/workflows/go-check.yml rename to .github/workflows/golang-analysis.yml diff --git a/.github/workflows/go-lint.yml b/.github/workflows/golint.yml similarity index 100% rename from .github/workflows/go-lint.yml rename to .github/workflows/golint.yml diff --git a/.github/workflows/go-test.yml b/.github/workflows/gotest.yml similarity index 100% rename from .github/workflows/go-test.yml rename to .github/workflows/gotest.yml diff --git a/.github/workflows/sync-github-release-assets.yml b/.github/workflows/sync-release-assets.yml similarity index 100% rename from .github/workflows/sync-github-release-assets.yml rename to .github/workflows/sync-release-assets.yml From d45d8ecdad5600b72afc5da8591504b49a94c3aa Mon Sep 17 00:00:00 2001 From: galargh Date: Thu, 2 Mar 2023 10:27:25 +0100 Subject: [PATCH 0580/1212] ci: simplify codeql worfklow --- .github/workflows/codeql-analysis.yml | 10 +--------- .github/workflows/golang-analysis.yml | 1 - 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index d4b16857f..800741b2e 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -21,14 +21,6 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 20 - strategy: - fail-fast: false - matrix: - language: [ 'go' ] - # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] - # Learn more: - # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed - steps: - name: Checkout repository uses: actions/checkout@v2 @@ -37,7 +29,7 @@ jobs: - name: Initialize CodeQL uses: github/codeql-action/init@v2 with: - languages: ${{ matrix.language }} + languages: go - name: Autobuild uses: github/codeql-action/autobuild@v2 diff --git a/.github/workflows/golang-analysis.yml b/.github/workflows/golang-analysis.yml index b0eced941..5db740ee9 100644 --- a/.github/workflows/golang-analysis.yml +++ b/.github/workflows/golang-analysis.yml @@ -15,7 +15,6 @@ jobs: if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' runs-on: ubuntu-latest timeout-minutes: 10 - name: All steps: - uses: actions/checkout@v2 with: From fb80af5180ec9e1d9700b7dafb1a79ec9fef2c66 Mon Sep 17 00:00:00 2001 From: galargh Date: Tue, 21 Mar 2023 15:26:07 +0100 Subject: [PATCH 0581/1212] fix: ensure unique job names across all GHA workflows --- .github/workflows/build.yml | 10 +++++----- .github/workflows/codeql-analysis.yml | 2 +- .github/workflows/docker-build.yml | 2 +- .github/workflows/gobuild.yml | 8 ++++---- .github/workflows/golang-analysis.yml | 2 +- .github/workflows/golint.yml | 2 +- .github/workflows/gotest.yml | 2 +- .github/workflows/sharness.yml | 20 ++++++++++---------- 8 files changed, 24 insertions(+), 24 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4a61e18b0..15f467f74 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -11,7 +11,7 @@ env: GO_VERSION: 1.19.1 jobs: - prepare: + interop-prep: if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' runs-on: ubuntu-latest timeout-minutes: 5 @@ -39,7 +39,7 @@ jobs: name: kubo path: cmd/ipfs/ipfs interop: - needs: [prepare] + needs: [interop-prep] runs-on: ubuntu-latest timeout-minutes: 20 defaults: @@ -77,7 +77,7 @@ jobs: IPFS_GO_EXEC: ${{ github.workspace }}/cmd/ipfs/ipfs working-directory: interop go-ipfs-api: - needs: [prepare] + needs: [interop-prep] runs-on: ubuntu-latest timeout-minutes: 5 env: @@ -117,7 +117,7 @@ jobs: - run: cmd/ipfs/ipfs shutdown if: always() go-ipfs-http-client: - needs: [prepare] + needs: [interop-prep] runs-on: ubuntu-latest timeout-minutes: 5 env: @@ -151,7 +151,7 @@ jobs: - run: go test -count=1 -v ./... working-directory: go-ipfs-http-client ipfs-webui: - needs: [prepare] + needs: [interop-prep] runs-on: ubuntu-latest timeout-minutes: 20 env: diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 800741b2e..e2fa78bef 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -16,7 +16,7 @@ permissions: security-events: write # (github/codeql-action/autobuild) jobs: - go: + codeql: if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' runs-on: ubuntu-latest timeout-minutes: 20 diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml index 2d76cc8eb..ea6c9d9b3 100644 --- a/.github/workflows/docker-build.yml +++ b/.github/workflows/docker-build.yml @@ -8,7 +8,7 @@ on: - 'master' jobs: - head: + docker-build: if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' runs-on: ubuntu-latest timeout-minutes: 10 diff --git a/.github/workflows/gobuild.yml b/.github/workflows/gobuild.yml index 9fe883392..f80fb8205 100644 --- a/.github/workflows/gobuild.yml +++ b/.github/workflows/gobuild.yml @@ -8,12 +8,12 @@ on: - 'master' jobs: - runner: + go-build-runner: if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' uses: ipfs/kubo/.github/workflows/runner.yml@master - build: - needs: [runner] - runs-on: ${{ fromJSON(needs.runner.outputs.config).labels }} + go-build: + needs: [go-build-runner] + runs-on: ${{ fromJSON(needs.go-build-runner.outputs.config).labels }} timeout-minutes: 20 env: TEST_NO_DOCKER: 1 diff --git a/.github/workflows/golang-analysis.yml b/.github/workflows/golang-analysis.yml index 5db740ee9..d3fead57c 100644 --- a/.github/workflows/golang-analysis.yml +++ b/.github/workflows/golang-analysis.yml @@ -11,7 +11,7 @@ permissions: contents: read # to fetch code (actions/checkout) jobs: - check: + go-check: if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' runs-on: ubuntu-latest timeout-minutes: 10 diff --git a/.github/workflows/golint.yml b/.github/workflows/golint.yml index 524beb018..621a2807a 100644 --- a/.github/workflows/golint.yml +++ b/.github/workflows/golint.yml @@ -8,7 +8,7 @@ on: - 'master' jobs: - lint: + go-lint: if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' runs-on: ubuntu-latest timeout-minutes: 10 diff --git a/.github/workflows/gotest.yml b/.github/workflows/gotest.yml index 76c090c2f..3867271ca 100644 --- a/.github/workflows/gotest.yml +++ b/.github/workflows/gotest.yml @@ -8,7 +8,7 @@ on: - 'master' jobs: - test: + go-test: if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' runs-on: ubuntu-latest timeout-minutes: 20 diff --git a/.github/workflows/sharness.yml b/.github/workflows/sharness.yml index 8e29386ff..7b392bcd9 100644 --- a/.github/workflows/sharness.yml +++ b/.github/workflows/sharness.yml @@ -8,12 +8,12 @@ on: - 'master' jobs: - runner: + sharness-runner: if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' uses: ipfs/kubo/.github/workflows/runner.yml@master - test: - needs: [runner] - runs-on: ${{ fromJSON(needs.runner.outputs.config).labels }} + sharness-test: + needs: [sharness-runner] + runs-on: ${{ fromJSON(needs.sharness-runner.outputs.config).labels }} timeout-minutes: 20 defaults: run: @@ -67,7 +67,7 @@ jobs: TEST_EXPENSIVE: 1 IPFS_CHECK_RCMGR_DEFAULTS: 1 CONTINUE_ON_S_FAILURE: 1 - PARALLEL: ${{ fromJSON(needs.runner.outputs.config).parallel }} + PARALLEL: ${{ fromJSON(needs.sharness-runner.outputs.config).parallel }} - name: Upload coverage report uses: codecov/codecov-action@81cd2dc8148241f03f5839d295e000b8f761e378 # v3.1.0 if: failure() || success() @@ -96,12 +96,12 @@ jobs: - name: Upload one-page HTML report to S3 id: one-page uses: pl-strflt/tf-aws-gh-runner/.github/actions/upload-artifact@main - if: fromJSON(needs.runner.outputs.config).aws && (failure() || success()) + if: fromJSON(needs.sharness-runner.outputs.config).aws && (failure() || success()) with: source: kubo/test/sharness/test-results/sharness.html destination: sharness.html - name: Upload one-page HTML report - if: (! fromJSON(needs.runner.outputs.config).aws) && (failure() || success()) + if: (! fromJSON(needs.sharness-runner.outputs.config).aws) && (failure() || success()) uses: actions/upload-artifact@v3 with: name: sharness.html @@ -116,18 +116,18 @@ jobs: - name: Upload full HTML report to S3 id: full uses: pl-strflt/tf-aws-gh-runner/.github/actions/upload-artifact@main - if: fromJSON(needs.runner.outputs.config).aws && (failure() || success()) + if: fromJSON(needs.sharness-runner.outputs.config).aws && (failure() || success()) with: source: kubo/test/sharness/test-results/sharness-html destination: sharness-html/ - name: Upload full HTML report - if: (! fromJSON(needs.runner.outputs.config).aws) && (failure() || success()) + if: (! fromJSON(needs.sharness-runner.outputs.config).aws) && (failure() || success()) uses: actions/upload-artifact@v3 with: name: sharness-html path: kubo/test/sharness/test-results/sharness-html - name: Add S3 links to the summary - if: fromJSON(needs.runner.outputs.config).aws && (failure() || success()) + if: fromJSON(needs.sharness-runner.outputs.config).aws && (failure() || success()) run: echo "$MD" >> $GITHUB_STEP_SUMMARY env: MD: | From 1457b4fd4abff0bdcdccbacc26934cb7fa8e8a43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Mur=C3=A9?= Date: Wed, 22 Mar 2023 03:06:40 +0100 Subject: [PATCH 0582/1212] feat: improve dag/import (#9721) - don't bypass the CoreApi - don't use a goroutine and return channel for `importWorker`, when what's happening is really just a synchronous call - only `PinLock()` when we are going to pin - use `cid.Set` instead of an explicit map - fail the request early if any pinning fail, no need to try to pin more if the request failed already --- core/commands/dag/dag.go | 7 -- core/commands/dag/import.go | 182 ++++++++++++------------------------ 2 files changed, 59 insertions(+), 130 deletions(-) diff --git a/core/commands/dag/dag.go b/core/commands/dag/dag.go index df7762c00..e58ddc82d 100644 --- a/core/commands/dag/dag.go +++ b/core/commands/dag/dag.go @@ -168,13 +168,6 @@ var DagResolveCmd = &cmds.Command{ Type: ResolveOutput{}, } -type importResult struct { - blockCount uint64 - blockBytesCount uint64 - roots map[cid.Cid]struct{} - err error -} - // DagImportCmd is a command for importing a car to ipfs var DagImportCmd = &cmds.Command{ Helptext: cmds.HelpText{ diff --git a/core/commands/dag/import.go b/core/commands/dag/import.go index c9f0ebbde..ef39e38f4 100644 --- a/core/commands/dag/import.go +++ b/core/commands/dag/import.go @@ -2,24 +2,22 @@ package dagcmd import ( "errors" - "fmt" "io" cid "github.com/ipfs/go-cid" + cmds "github.com/ipfs/go-ipfs-cmds" ipld "github.com/ipfs/go-ipld-format" ipldlegacy "github.com/ipfs/go-ipld-legacy" "github.com/ipfs/go-libipfs/files" - iface "github.com/ipfs/interface-go-ipfs-core" "github.com/ipfs/interface-go-ipfs-core/options" + "github.com/ipfs/interface-go-ipfs-core/path" + gocarv2 "github.com/ipld/go-car/v2" + "github.com/ipfs/kubo/core/commands/cmdenv" "github.com/ipfs/kubo/core/commands/cmdutils" - - cmds "github.com/ipfs/go-ipfs-cmds" - gocarv2 "github.com/ipld/go-car/v2" ) func dagImport(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - node, err := cmdenv.GetNode(env) if err != nil { return err @@ -38,127 +36,42 @@ func dagImport(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment return err } + doPinRoots, _ := req.Options[pinRootsOptionName].(bool) + // grab a pinlock ( which doubles as a GC lock ) so that regardless of the // size of the streamed-in cars nothing will disappear on us before we had // a chance to roots that may show up at the very end // This is especially important for use cases like dagger: // ipfs dag import $( ... | ipfs-dagger --stdout=carfifos ) // - unlocker := node.Blockstore.PinLock(req.Context) - defer unlocker.Unlock(req.Context) - - doPinRoots, _ := req.Options[pinRootsOptionName].(bool) - - retCh := make(chan importResult, 1) - go importWorker(req, res, api, retCh) - - done := <-retCh - if done.err != nil { - return done.err - } - - // It is not guaranteed that a root in a header is actually present in the same ( or any ) - // .car file. This is the case in version 1, and ideally in further versions too - // Accumulate any root CID seen in a header, and supplement its actual node if/when encountered - // We will attempt a pin *only* at the end in case all car files were well formed - // - // The boolean value indicates whether we have encountered the root within the car file's - roots := done.roots - - // opportunistic pinning: try whatever sticks if doPinRoots { - - var failedPins int - for c := range roots { - - // We need to re-retrieve a block, convert it to ipld, and feed it - // to the Pinning interface, sigh... - // - // If we didn't have the problem of inability to take multiple pinlocks, - // we could use the api directly like so (though internally it does the same): - // - // // not ideal, but the pinning api takes only paths :( - // rp := path.NewResolvedPath( - // ipfspath.FromCid(c), - // c, - // c, - // "", - // ) - // - // if err := api.Pin().Add(req.Context, rp, options.Pin.Recursive(true)); err != nil { - - ret := RootMeta{Cid: c} - - if block, err := node.Blockstore.Get(req.Context, c); err != nil { - ret.PinErrorMsg = err.Error() - } else if nd, err := ipldlegacy.DecodeNode(req.Context, block); err != nil { - ret.PinErrorMsg = err.Error() - } else if err := node.Pinning.Pin(req.Context, nd, true); err != nil { - ret.PinErrorMsg = err.Error() - } else if err := node.Pinning.Flush(req.Context); err != nil { - ret.PinErrorMsg = err.Error() - } - - if ret.PinErrorMsg != "" { - failedPins++ - } - - if err := res.Emit(&CarImportOutput{Root: &ret}); err != nil { - return err - } - } - - if failedPins > 0 { - return fmt.Errorf( - "unable to pin all roots: %d out of %d failed", - failedPins, - len(roots), - ) - } + unlocker := node.Blockstore.PinLock(req.Context) + defer unlocker.Unlock(req.Context) } - stats, _ := req.Options[statsOptionName].(bool) - if stats { - err = res.Emit(&CarImportOutput{ - Stats: &CarImportStats{ - BlockCount: done.blockCount, - BlockBytesCount: done.blockBytesCount, - }, - }) - if err != nil { - return err - } - } - - return nil -} - -func importWorker(req *cmds.Request, re cmds.ResponseEmitter, api iface.CoreAPI, ret chan importResult) { - // this is *not* a transaction // it is simply a way to relieve pressure on the blockstore // similar to pinner.Pin/pinner.Flush batch := ipld.NewBatch(req.Context, api.Dag()) - roots := make(map[cid.Cid]struct{}) + roots := cid.NewSet() var blockCount, blockBytesCount uint64 it := req.Files.Entries() for it.Next() { - file := files.FileFromEntry(it) if file == nil { - ret <- importResult{err: errors.New("expected a file handle")} - return + return errors.New("expected a file handle") } - // wrap a defer-closer-scope - // - // every single file in it() is already open before we start - // just close here sooner rather than later for neatness - // and to surface potential errors writing on closed fifos - // this won't/can't help with not running out of handles - err := func() error { + // import blocks + err = func() error { + // wrap a defer-closer-scope + // + // every single file in it() is already open before we start + // just close here sooner rather than later for neatness + // and to surface potential errors writing on closed fifos + // this won't/can't help with not running out of handles defer file.Close() car, err := gocarv2.NewBlockReader(file) @@ -167,7 +80,7 @@ func importWorker(req *cmds.Request, re cmds.ResponseEmitter, api iface.CoreAPI, } for _, c := range car.Roots { - roots[c] = struct{}{} + roots.Add(c) } for { @@ -193,28 +106,51 @@ func importWorker(req *cmds.Request, re cmds.ResponseEmitter, api iface.CoreAPI, blockCount++ blockBytesCount += uint64(len(block.RawData())) } - return nil }() - - if err != nil { - ret <- importResult{err: err} - return - } - } - - if err := it.Err(); err != nil { - ret <- importResult{err: err} - return } if err := batch.Commit(); err != nil { - ret <- importResult{err: err} - return + return err } - ret <- importResult{ - blockCount: blockCount, - blockBytesCount: blockBytesCount, - roots: roots} + // It is not guaranteed that a root in a header is actually present in the same ( or any ) + // .car file. This is the case in version 1, and ideally in further versions too. + // Accumulate any root CID seen in a header, and supplement its actual node if/when encountered + // We will attempt a pin *only* at the end in case all car files were well-formed. + + // opportunistic pinning: try whatever sticks + if doPinRoots { + err = roots.ForEach(func(c cid.Cid) error { + ret := RootMeta{Cid: c} + + // This will trigger a full read of the DAG in the pinner, to make sure we have all blocks. + // Ideally we would have a lighter merkledag.Walk() instead of the underlying merkledag.FetchDag, + // then pinner.PinWithMode(). + err = api.Pin().Add(req.Context, path.IpldPath(c), options.Pin.Recursive(true)) + if err != nil { + return err + } + + return res.Emit(&CarImportOutput{Root: &ret}) + }) + if err != nil { + return err + } + } + + stats, _ := req.Options[statsOptionName].(bool) + if stats { + err = res.Emit(&CarImportOutput{ + Stats: &CarImportStats{ + BlockCount: blockCount, + BlockBytesCount: blockBytesCount, + }, + }) + if err != nil { + return err + } + } + + return nil } From bb020ea1ef8765f873e06ae4fd7f58c075b04edc Mon Sep 17 00:00:00 2001 From: Jorropo Date: Sat, 25 Mar 2023 11:19:01 +0100 Subject: [PATCH 0583/1212] fix: deadlock while racing `ipfs dag import` and `ipfs repo gc` This fixes a deadlock introduced in 1457b4fd4abff0bdcdccbacc26934cb7fa8e8a43. We can't use the coreapi here because it will try to take the PinLock (RLock) again, so revert this small part of 1457b4fd4abff0bdcdccbacc26934cb7fa8e8a43. This used cause a deadlock when concurrently running `ipfs dag import` concurrently with the GC. The bug is that `ipfs dag import` takes an RLock with the PinLock. *the cars are imported, leaving a wide window of time* Then GC Takes a Lock on that same RWMutex while taking the GC Lock (it blocks because it waits for the RLock to be released). Then the car imports are finished and `ipfs dag import` tries to aqcuire the PinLock (doing an RLock) again in `Api().Pin`. However at this point the RWMutex is starved, the runtime put a fence in front of RLocks if a Lock has been waiting for too lock (else you could have an endless stream of RLock / RUnlock forever delaying a Lock to ever go through). The issue is that `ipfs dag import`'s original RLock which is blocking everyone will be released once it returns, which only happens when `Api().Pin` completes. So we have a deadlock (ABA kind ?), because `ipfs dag import` waits on the GC Lock, which waits on `ipfs dag import`. Calling the Pinner directly does not acquire the PinLock again, and thus does not have this issue. --- core/commands/dag/import.go | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/core/commands/dag/import.go b/core/commands/dag/import.go index ef39e38f4..c07a8cdf9 100644 --- a/core/commands/dag/import.go +++ b/core/commands/dag/import.go @@ -10,7 +10,6 @@ import ( ipldlegacy "github.com/ipfs/go-ipld-legacy" "github.com/ipfs/go-libipfs/files" "github.com/ipfs/interface-go-ipfs-core/options" - "github.com/ipfs/interface-go-ipfs-core/path" gocarv2 "github.com/ipld/go-car/v2" "github.com/ipfs/kubo/core/commands/cmdenv" @@ -108,6 +107,9 @@ func dagImport(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment } return nil }() + if err != nil { + return err + } } if err := batch.Commit(); err != nil { @@ -125,11 +127,16 @@ func dagImport(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment ret := RootMeta{Cid: c} // This will trigger a full read of the DAG in the pinner, to make sure we have all blocks. - // Ideally we would have a lighter merkledag.Walk() instead of the underlying merkledag.FetchDag, - // then pinner.PinWithMode(). - err = api.Pin().Add(req.Context, path.IpldPath(c), options.Pin.Recursive(true)) - if err != nil { - return err + // Ideally we would do colloring of the pinning state while importing the blocks + // and ensure the gray bucket is empty at the end (or use the network to download missing blocks). + if block, err := node.Blockstore.Get(req.Context, c); err != nil { + ret.PinErrorMsg = err.Error() + } else if nd, err := ipldlegacy.DecodeNode(req.Context, block); err != nil { + ret.PinErrorMsg = err.Error() + } else if err := node.Pinning.Pin(req.Context, nd, true); err != nil { + ret.PinErrorMsg = err.Error() + } else if err := node.Pinning.Flush(req.Context); err != nil { + ret.PinErrorMsg = err.Error() } return res.Emit(&CarImportOutput{Root: &ret}) From 88d431c8129aeef2ea5076336412cb54161342ce Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Mon, 27 Mar 2023 15:19:55 +0200 Subject: [PATCH 0584/1212] feat: remove writable gateway (#9743) Co-authored-by: Marcin Rataj --- cmd/ipfs/daemon.go | 19 +- cmd/ipfswatch/main.go | 2 +- config/gateway.go | 3 +- core/corehttp/corehttp.go | 2 +- core/corehttp/gateway.go | 29 +-- core/corehttp/gateway_test.go | 2 +- core/corehttp/gateway_writable.go | 265 ----------------------- docs/config.md | 9 +- test/cli/gateway_test.go | 2 +- test/sharness/lib/test-lib.sh | 9 +- test/sharness/t0060-daemon.sh | 4 +- test/sharness/t0111-gateway-writeable.sh | 136 ------------ 12 files changed, 18 insertions(+), 464 deletions(-) delete mode 100644 core/corehttp/gateway_writable.go delete mode 100755 test/sharness/t0111-gateway-writeable.sh diff --git a/cmd/ipfs/daemon.go b/cmd/ipfs/daemon.go index 52addcc07..85ca79246 100644 --- a/cmd/ipfs/daemon.go +++ b/cmd/ipfs/daemon.go @@ -163,7 +163,7 @@ Headers. cmds.StringOption(initProfileOptionKwd, "Configuration profiles to apply for --init. See ipfs init --help for more"), cmds.StringOption(routingOptionKwd, "Overrides the routing option").WithDefault(routingOptionDefaultKwd), cmds.BoolOption(mountKwd, "Mounts IPFS to the filesystem using FUSE (experimental)"), - cmds.BoolOption(writableKwd, "Enable legacy Gateway.Writable (deprecated)"), + cmds.BoolOption(writableKwd, "Enable legacy Gateway.Writable (REMOVED)"), cmds.StringOption(ipfsMountKwd, "Path to the mountpoint for IPFS (if using --mount). Defaults to config setting."), cmds.StringOption(ipnsMountKwd, "Path to the mountpoint for IPNS (if using --mount). Defaults to config setting."), cmds.BoolOption(unrestrictedAPIAccessKwd, "Allow API access to unlisted hashes"), @@ -679,7 +679,7 @@ func serveHTTPApi(req *cmds.Request, cctx *oldcmds.Context) (<-chan error, error for _, listener := range listeners { // we might have listened to /tcp/0 - let's see what we are listing on - fmt.Printf("API server listening on %s\n", listener.Multiaddr()) + fmt.Printf("RPC API server listening on %s\n", listener.Multiaddr()) // Browsers require TCP. switch listener.Addr().Network() { case "tcp", "tcp4", "tcp6": @@ -692,9 +692,9 @@ func serveHTTPApi(req *cmds.Request, cctx *oldcmds.Context) (<-chan error, error // only the webui objects are allowed. // if you know what you're doing, go ahead and pass --unrestricted-api. unrestricted, _ := req.Options[unrestrictedAPIAccessKwd].(bool) - gatewayOpt := corehttp.GatewayOption(false, corehttp.WebUIPaths...) + gatewayOpt := corehttp.GatewayOption(corehttp.WebUIPaths...) if unrestricted { - gatewayOpt = corehttp.GatewayOption(true, "/ipfs", "/ipns") + gatewayOpt = corehttp.GatewayOption("/ipfs", "/ipns") } var opts = []corehttp.ServeOption{ @@ -804,7 +804,7 @@ func serveHTTPGateway(req *cmds.Request, cctx *oldcmds.Context) (<-chan error, e } if writable { - log.Error("serveHTTPGateway: legacy Gateway.Writable is DEPRECATED and will be removed or changed in future versions. If you are still using this, provide feedback in https://github.com/ipfs/specs/issues/375") + log.Fatalf("Support for Gateway.Writable and --writable has been REMOVED. Please remove it from your config file or CLI. Modern replacement tracked in https://github.com/ipfs/specs/issues/375") } listeners, err := sockets.TakeListeners("io.ipfs.gateway") @@ -837,13 +837,8 @@ func serveHTTPGateway(req *cmds.Request, cctx *oldcmds.Context) (<-chan error, e } // we might have listened to /tcp/0 - let's see what we are listing on - gwType := "readonly" - if writable { - gwType = "writable" - } - for _, listener := range listeners { - fmt.Printf("Gateway (%s) server listening on %s\n", gwType, listener.Multiaddr()) + fmt.Printf("Gateway server listening on %s\n", listener.Multiaddr()) } cmdctx := *cctx @@ -852,7 +847,7 @@ func serveHTTPGateway(req *cmds.Request, cctx *oldcmds.Context) (<-chan error, e var opts = []corehttp.ServeOption{ corehttp.MetricsCollectionOption("gateway"), corehttp.HostnameOption(), - corehttp.GatewayOption(writable, "/ipfs", "/ipns"), + corehttp.GatewayOption("/ipfs", "/ipns"), corehttp.VersionOption(), corehttp.CheckVersionOption(), corehttp.CommandsROOption(cmdctx), diff --git a/cmd/ipfswatch/main.go b/cmd/ipfswatch/main.go index 06215687c..2c333fc23 100644 --- a/cmd/ipfswatch/main.go +++ b/cmd/ipfswatch/main.go @@ -94,7 +94,7 @@ func run(ipfsPath, watchPath string) error { if *http { addr := "/ip4/127.0.0.1/tcp/5001" var opts = []corehttp.ServeOption{ - corehttp.GatewayOption(true, "/ipfs", "/ipns"), + corehttp.GatewayOption("/ipfs", "/ipns"), corehttp.WebUIOption, corehttp.CommandsOption(cmdCtx(node, ipfsPath)), } diff --git a/config/gateway.go b/config/gateway.go index de43dd39e..8ae312b59 100644 --- a/config/gateway.go +++ b/config/gateway.go @@ -38,8 +38,7 @@ type Gateway struct { // should be redirected. RootRedirect string - // DEPRECATED: Enables legacy PUT/POST request handling. - // Modern replacement tracked in https://github.com/ipfs/specs/issues/375 + // REMOVED: modern replacement tracked in https://github.com/ipfs/specs/issues/375 Writable Flag `json:",omitempty"` // PathPrefixes was removed: https://github.com/ipfs/go-ipfs/issues/7702 diff --git a/core/corehttp/corehttp.go b/core/corehttp/corehttp.go index fe9f1b1db..b1a317f3c 100644 --- a/core/corehttp/corehttp.go +++ b/core/corehttp/corehttp.go @@ -75,7 +75,7 @@ func ListenAndServe(n *core.IpfsNode, listeningMultiAddr string, options ...Serv // we might have listened to /tcp/0 - let's see what we are listing on addr = list.Multiaddr() - fmt.Printf("API server listening on %s\n", addr) + fmt.Printf("RPC API server listening on %s\n", addr) return Serve(n, manet.NetListener(list), options...) } diff --git a/core/corehttp/gateway.go b/core/corehttp/gateway.go index c20ab6e4a..f77e941d9 100644 --- a/core/corehttp/gateway.go +++ b/core/corehttp/gateway.go @@ -24,18 +24,13 @@ import ( "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" ) -func GatewayOption(writable bool, paths ...string) ServeOption { +func GatewayOption(paths ...string) ServeOption { return func(n *core.IpfsNode, _ net.Listener, mux *http.ServeMux) (*http.ServeMux, error) { cfg, err := n.Repo.Config() if err != nil { return nil, err } - api, err := coreapi.NewCoreAPI(n, options.Api.FetchBlocks(!cfg.Gateway.NoFetch)) - if err != nil { - return nil, err - } - headers := make(map[string][]string, len(cfg.Gateway.HTTPHeaders)) for h, v := range cfg.Gateway.HTTPHeaders { headers[http.CanonicalHeaderKey(h)] = v @@ -58,28 +53,6 @@ func GatewayOption(writable bool, paths ...string) ServeOption { // By default, our HTTP handler is the gateway handler. handler := gw.ServeHTTP - // If we have the writable gateway enabled, we have to replace our - // http handler by a handler that takes care of the different methods. - if writable { - writableGw := &writableGatewayHandler{ - config: &gwConfig, - api: api, - } - - handler = func(w http.ResponseWriter, r *http.Request) { - switch r.Method { - case http.MethodPost: - writableGw.postHandler(w, r) - case http.MethodDelete: - writableGw.deleteHandler(w, r) - case http.MethodPut: - writableGw.putHandler(w, r) - default: - gw.ServeHTTP(w, r) - } - } - } - for _, p := range paths { mux.HandleFunc(p+"/", handler) } diff --git a/core/corehttp/gateway_test.go b/core/corehttp/gateway_test.go index d4e357740..03b04350d 100644 --- a/core/corehttp/gateway_test.go +++ b/core/corehttp/gateway_test.go @@ -124,7 +124,7 @@ func newTestServerAndNode(t *testing.T, ns mockNamesys) (*httptest.Server, iface dh.Handler, err = makeHandler(n, ts.Listener, HostnameOption(), - GatewayOption(false, "/ipfs", "/ipns"), + GatewayOption("/ipfs", "/ipns"), VersionOption(), ) if err != nil { diff --git a/core/corehttp/gateway_writable.go b/core/corehttp/gateway_writable.go deleted file mode 100644 index 34cd8438e..000000000 --- a/core/corehttp/gateway_writable.go +++ /dev/null @@ -1,265 +0,0 @@ -package corehttp - -import ( - "context" - "fmt" - "net/http" - "os" - gopath "path" - - cid "github.com/ipfs/go-cid" - ipld "github.com/ipfs/go-ipld-format" - "github.com/ipfs/go-libipfs/files" - "github.com/ipfs/go-libipfs/gateway" - dag "github.com/ipfs/go-merkledag" - "github.com/ipfs/go-mfs" - path "github.com/ipfs/go-path" - "github.com/ipfs/go-path/resolver" - iface "github.com/ipfs/interface-go-ipfs-core" - routing "github.com/libp2p/go-libp2p/core/routing" -) - -const ( - ipfsPathPrefix = "/ipfs/" -) - -type writableGatewayHandler struct { - api iface.CoreAPI - config *gateway.Config -} - -func (i *writableGatewayHandler) addUserHeaders(w http.ResponseWriter) { - for k, v := range i.config.Headers { - w.Header()[http.CanonicalHeaderKey(k)] = v - } -} - -func (i *writableGatewayHandler) postHandler(w http.ResponseWriter, r *http.Request) { - p, err := i.api.Unixfs().Add(r.Context(), files.NewReaderFile(r.Body)) - if err != nil { - internalWebError(w, err) - return - } - - i.addUserHeaders(w) // ok, _now_ write user's headers. - w.Header().Set("IPFS-Hash", p.Cid().String()) - log.Debugw("CID created, http redirect", "from", r.URL, "to", p, "status", http.StatusCreated) - http.Redirect(w, r, p.String(), http.StatusCreated) -} - -func (i *writableGatewayHandler) putHandler(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() - ds := i.api.Dag() - - // Parse the path - rootCid, newPath, err := parseIpfsPath(r.URL.Path) - if err != nil { - webError(w, "WritableGateway: failed to parse the path", err, http.StatusBadRequest) - return - } - if newPath == "" || newPath == "/" { - http.Error(w, "WritableGateway: empty path", http.StatusBadRequest) - return - } - newDirectory, newFileName := gopath.Split(newPath) - - // Resolve the old root. - - rnode, err := ds.Get(ctx, rootCid) - if err != nil { - webError(w, "WritableGateway: Could not create DAG from request", err, http.StatusInternalServerError) - return - } - - pbnd, ok := rnode.(*dag.ProtoNode) - if !ok { - webError(w, "Cannot read non protobuf nodes through gateway", dag.ErrNotProtobuf, http.StatusBadRequest) - return - } - - // Create the new file. - newFilePath, err := i.api.Unixfs().Add(ctx, files.NewReaderFile(r.Body)) - if err != nil { - webError(w, "WritableGateway: could not create DAG from request", err, http.StatusInternalServerError) - return - } - - newFile, err := ds.Get(ctx, newFilePath.Cid()) - if err != nil { - webError(w, "WritableGateway: failed to resolve new file", err, http.StatusInternalServerError) - return - } - - // Patch the new file into the old root. - - root, err := mfs.NewRoot(ctx, ds, pbnd, nil) - if err != nil { - webError(w, "WritableGateway: failed to create MFS root", err, http.StatusBadRequest) - return - } - - if newDirectory != "" { - err := mfs.Mkdir(root, newDirectory, mfs.MkdirOpts{Mkparents: true, Flush: false}) - if err != nil { - webError(w, "WritableGateway: failed to create MFS directory", err, http.StatusInternalServerError) - return - } - } - dirNode, err := mfs.Lookup(root, newDirectory) - if err != nil { - webError(w, "WritableGateway: failed to lookup directory", err, http.StatusInternalServerError) - return - } - dir, ok := dirNode.(*mfs.Directory) - if !ok { - http.Error(w, "WritableGateway: target directory is not a directory", http.StatusBadRequest) - return - } - err = dir.Unlink(newFileName) - switch err { - case os.ErrNotExist, nil: - default: - webError(w, "WritableGateway: failed to replace existing file", err, http.StatusBadRequest) - return - } - err = dir.AddChild(newFileName, newFile) - if err != nil { - webError(w, "WritableGateway: failed to link file into directory", err, http.StatusInternalServerError) - return - } - nnode, err := root.GetDirectory().GetNode() - if err != nil { - webError(w, "WritableGateway: failed to finalize", err, http.StatusInternalServerError) - return - } - newcid := nnode.Cid() - - i.addUserHeaders(w) // ok, _now_ write user's headers. - w.Header().Set("IPFS-Hash", newcid.String()) - - redirectURL := gopath.Join(ipfsPathPrefix, newcid.String(), newPath) - log.Debugw("CID replaced, redirect", "from", r.URL, "to", redirectURL, "status", http.StatusCreated) - http.Redirect(w, r, redirectURL, http.StatusCreated) -} - -func (i *writableGatewayHandler) deleteHandler(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() - - // parse the path - - rootCid, newPath, err := parseIpfsPath(r.URL.Path) - if err != nil { - webError(w, "WritableGateway: failed to parse the path", err, http.StatusBadRequest) - return - } - if newPath == "" || newPath == "/" { - http.Error(w, "WritableGateway: empty path", http.StatusBadRequest) - return - } - directory, filename := gopath.Split(newPath) - - // lookup the root - - rootNodeIPLD, err := i.api.Dag().Get(ctx, rootCid) - if err != nil { - webError(w, "WritableGateway: failed to resolve root CID", err, http.StatusInternalServerError) - return - } - rootNode, ok := rootNodeIPLD.(*dag.ProtoNode) - if !ok { - http.Error(w, "WritableGateway: empty path", http.StatusInternalServerError) - return - } - - // construct the mfs root - - root, err := mfs.NewRoot(ctx, i.api.Dag(), rootNode, nil) - if err != nil { - webError(w, "WritableGateway: failed to construct the MFS root", err, http.StatusBadRequest) - return - } - - // lookup the parent directory - - parentNode, err := mfs.Lookup(root, directory) - if err != nil { - webError(w, "WritableGateway: failed to look up parent", err, http.StatusInternalServerError) - return - } - - parent, ok := parentNode.(*mfs.Directory) - if !ok { - http.Error(w, "WritableGateway: parent is not a directory", http.StatusInternalServerError) - return - } - - // delete the file - - switch parent.Unlink(filename) { - case nil, os.ErrNotExist: - default: - webError(w, "WritableGateway: failed to remove file", err, http.StatusInternalServerError) - return - } - - nnode, err := root.GetDirectory().GetNode() - if err != nil { - webError(w, "WritableGateway: failed to finalize", err, http.StatusInternalServerError) - return - } - ncid := nnode.Cid() - - i.addUserHeaders(w) // ok, _now_ write user's headers. - w.Header().Set("IPFS-Hash", ncid.String()) - - redirectURL := gopath.Join(ipfsPathPrefix+ncid.String(), directory) - // note: StatusCreated is technically correct here as we created a new resource. - log.Debugw("CID deleted, redirect", "from", r.RequestURI, "to", redirectURL, "status", http.StatusCreated) - http.Redirect(w, r, redirectURL, http.StatusCreated) -} - -func parseIpfsPath(p string) (cid.Cid, string, error) { - rootPath, err := path.ParsePath(p) - if err != nil { - return cid.Cid{}, "", err - } - - // Check the path. - rsegs := rootPath.Segments() - if rsegs[0] != "ipfs" { - return cid.Cid{}, "", fmt.Errorf("WritableGateway: only ipfs paths supported") - } - - rootCid, err := cid.Decode(rsegs[1]) - if err != nil { - return cid.Cid{}, "", err - } - - return rootCid, path.Join(rsegs[2:]), nil -} - -func webError(w http.ResponseWriter, message string, err error, defaultCode int) { - if _, ok := err.(resolver.ErrNoLink); ok { - webErrorWithCode(w, message, err, http.StatusNotFound) - } else if err == routing.ErrNotFound { - webErrorWithCode(w, message, err, http.StatusNotFound) - } else if ipld.IsNotFound(err) { - webErrorWithCode(w, message, err, http.StatusNotFound) - } else if err == context.DeadlineExceeded { - webErrorWithCode(w, message, err, http.StatusRequestTimeout) - } else { - webErrorWithCode(w, message, err, defaultCode) - } -} - -func webErrorWithCode(w http.ResponseWriter, message string, err error, code int) { - http.Error(w, fmt.Sprintf("%s: %s", message, err), code) - if code >= 500 { - log.Warnf("server error: %s: %s", message, err) - } -} - -// return a 500 error and log -func internalWebError(w http.ResponseWriter, err error) { - webErrorWithCode(w, "internalWebError", err, http.StatusInternalServerError) -} diff --git a/docs/config.md b/docs/config.md index 2e9fff512..bb2d8b702 100644 --- a/docs/config.md +++ b/docs/config.md @@ -681,14 +681,9 @@ Type: `string` (url) ### `Gateway.Writable` -**DEPRECATED**: Enables legacy PUT/POST request handling. +**REMOVED**: this option no longer available as of [Kubo 0.20](https://github.com/ipfs/kubo/blob/master/docs/changelogs/v0.20.md). -This API is not standardized, and should not be used for new projects. -We are working on a modern replacement. IPIP can be tracked in [ipfs/specs#375](https://github.com/ipfs/specs/issues/375). - -Default: `false` - -Type: `bool` +We are working on developing a modern replacement. To support our efforts, please leave a comment describing your use case in [ipfs/specs#375](https://github.com/ipfs/specs/issues/375). ### `Gateway.PathPrefixes` diff --git a/test/cli/gateway_test.go b/test/cli/gateway_test.go index 4c40729c7..1d6ac45b9 100644 --- a/test/cli/gateway_test.go +++ b/test/cli/gateway_test.go @@ -436,7 +436,7 @@ func TestGateway(t *testing.T) { t.Run("verify gateway file", func(t *testing.T) { t.Parallel() - r := regexp.MustCompile(`Gateway \(readonly\) server listening on (?P.+)\s`) + r := regexp.MustCompile(`Gateway server listening on (?P.+)\s`) matches := r.FindStringSubmatch(node.Daemon.Stdout.String()) ma, err := multiaddr.NewMultiaddr(matches[1]) require.NoError(t, err) diff --git a/test/sharness/lib/test-lib.sh b/test/sharness/lib/test-lib.sh index 3aecaec99..1f1491f9e 100644 --- a/test/sharness/lib/test-lib.sh +++ b/test/sharness/lib/test-lib.sh @@ -214,13 +214,6 @@ test_init_ipfs() { } -test_config_ipfs_gateway_writable() { - test_expect_success "prepare config -- gateway writable" ' - test_config_set --bool Gateway.Writable true || - test_fsh cat "\"$IPFS_PATH/config\"" - ' -} - test_wait_for_file() { loops=$1 delay=$2 @@ -247,7 +240,7 @@ test_set_address_vars() { API_ADDR=$(convert_tcp_maddr $API_MADDR) && API_PORT=$(port_from_maddr $API_MADDR) && - GWAY_MADDR=$(sed -n "s/^Gateway (.*) server listening on //p" "$daemon_output") && + GWAY_MADDR=$(sed -n "s/^Gateway server listening on //p" "$daemon_output") && GWAY_ADDR=$(convert_tcp_maddr $GWAY_MADDR) && GWAY_PORT=$(port_from_maddr $GWAY_MADDR) ' diff --git a/test/sharness/t0060-daemon.sh b/test/sharness/t0060-daemon.sh index b237e143f..f43708b1d 100755 --- a/test/sharness/t0060-daemon.sh +++ b/test/sharness/t0060-daemon.sh @@ -89,9 +89,9 @@ test_expect_success "ipfs daemon output looks good" ' echo "" >>expected_daemon && sed "s/^/Swarm listening on /" listen_addrs >>expected_daemon && sed "s/^/Swarm announcing /" local_addrs >>expected_daemon && - echo "API server listening on '$API_MADDR'" >>expected_daemon && + echo "RPC API server listening on '$API_MADDR'" >>expected_daemon && echo "WebUI: http://'$API_ADDR'/webui" >>expected_daemon && - echo "Gateway (readonly) server listening on '$GWAY_MADDR'" >>expected_daemon && + echo "Gateway server listening on '$GWAY_MADDR'" >>expected_daemon && echo "Daemon is ready" >>expected_daemon && test_cmp expected_daemon actual_daemon ' diff --git a/test/sharness/t0111-gateway-writeable.sh b/test/sharness/t0111-gateway-writeable.sh deleted file mode 100755 index 115114c89..000000000 --- a/test/sharness/t0111-gateway-writeable.sh +++ /dev/null @@ -1,136 +0,0 @@ -#!/usr/bin/env bash -# -# Copyright (c) 2014 Christian Couder -# MIT Licensed; see the LICENSE file in this repository. -# - -test_description="Test HTTP Gateway (Writable)" - -. lib/test-lib.sh - -test_init_ipfs - -test_launch_ipfs_daemon --writable -test_expect_success "ipfs daemon --writable overrides config" ' - curl -v -X POST http://$GWAY_ADDR/ipfs/ 2> outfile && - grep "HTTP/1.1 201 Created" outfile && - grep "Location: /ipfs/QmbFMke1KXqnYyBBWxB74N4c5SBnJMVAiMNRcGu6x1AwQH" outfile -' -test_kill_ipfs_daemon - -test_config_ipfs_gateway_writable -test_launch_ipfs_daemon --writable=false -test_expect_success "ipfs daemon --writable=false overrides Writable=true config" ' - curl -v -X POST http://$GWAY_ADDR/ipfs/ 2> outfile && - grep "HTTP/1.1 405 Method Not Allowed" outfile -' -test_kill_ipfs_daemon -test_launch_ipfs_daemon - -port=$GWAY_PORT - -test_expect_success "ipfs daemon up" ' - pollEndpoint -host $GWAY_MADDR -v -tout=1s -tries=60 2>poll_apierr > poll_apiout || - test_fsh cat poll_apierr || test_fsh cat poll_apiout -' - -test_expect_success "deprecation notice is printed when Gateway.Writable=true" ' - test_should_contain "legacy Gateway.Writable is DEPRECATED and will be removed or changed in future versions. If you are still using this, provide feedback in https://github.com/ipfs/specs/issues/375" daemon_err -' - -test_expect_success "HTTP gateway gives access to sample file" ' - curl -s -o welcome "http://$GWAY_ADDR/ipfs/$HASH_WELCOME_DOCS/readme" && - grep "Hello and Welcome to IPFS!" welcome -' - -test_expect_success "HTTP POST file gives Hash" ' - echo "$RANDOM" >infile && - URL="http://127.0.0.1:$port/ipfs/" && - curl -svX POST --data-binary @infile "$URL" 2>curl_post.out && - grep "HTTP/1.1 201 Created" curl_post.out && - LOCATION=$(grep Location curl_post.out) && - HASH=$(echo $LOCATION | cut -d":" -f2- |tr -d " \n\r") -' - -test_expect_success "We can HTTP GET file just created" ' - URL="http://127.0.0.1:${port}${HASH}" && - curl -so outfile "$URL" && - test_cmp infile outfile -' - -test_expect_success "We got the correct hash" ' - ADD_HASH="/ipfs/$(ipfs add -q infile)" && - test "x$ADD_HASH" = "x$HASH" || test_fsh echo "$ADD_HASH != $HASH" -' - -test_expect_success "HTTP GET empty directory" ' - URL="http://127.0.0.1:$port/ipfs/$HASH_EMPTY_DIR/" && - echo "GET $URL" && - curl -so outfile "$URL" 2>curl_getEmpty.out && - cat outfile | tr -s "\n" " " | grep "Index of /ipfs/$HASH_EMPTY_DIR" -' - -test_expect_success "HTTP PUT file to construct a hierarchy" ' - echo "$RANDOM" >infile && - URL="http://127.0.0.1:$port/ipfs/$HASH_EMPTY_DIR/test.txt" && - echo "PUT $URL" && - curl -svX PUT --data-binary @infile "$URL" 2>curl_put.out && - grep "HTTP/1.1 201 Created" curl_put.out && - LOCATION=$(grep Location curl_put.out) && - HASH=$(expr "$LOCATION" : "< Location: /ipfs/\(.*\)/test.txt") -' - -test_expect_success "We can HTTP GET file just created" ' - URL="http://127.0.0.1:$port/ipfs/$HASH/test.txt" && - echo "GET $URL" && - curl -so outfile "$URL" && - test_cmp infile outfile -' - -test_expect_success "HTTP PUT file to append to existing hierarchy" ' - echo "$RANDOM" >infile2 && - URL="http://127.0.0.1:$port/ipfs/$HASH/test/test.txt" && - echo "PUT $URL" && - curl -svX PUT --data-binary @infile2 "$URL" 2>curl_putAgain.out && - grep "HTTP/1.1 201 Created" curl_putAgain.out && - LOCATION=$(grep Location curl_putAgain.out) && - HASH=$(expr "$LOCATION" : "< Location: /ipfs/\(.*\)/test/test.txt") -' - - -test_expect_success "We can HTTP GET file just updated" ' - URL="http://127.0.0.1:$port/ipfs/$HASH/test/test.txt" && - echo "GET $URL" && - curl -svo outfile2 "$URL" 2>curl_getAgain.out && - test_cmp infile2 outfile2 -' - -test_expect_success "HTTP PUT to replace a directory" ' - echo "$RANDOM" >infile3 && - URL="http://127.0.0.1:$port/ipfs/$HASH/test" && - echo "PUT $URL" && - curl -svX PUT --data-binary @infile3 "$URL" 2>curl_putOverDirectory.out && - grep "HTTP/1.1 201 Created" curl_putOverDirectory.out && - LOCATION=$(grep Location curl_putOverDirectory.out) && - HASH=$(expr "$LOCATION" : "< Location: /ipfs/\(.*\)/test") -' - -test_expect_success "We can HTTP GET file just put over a directory" ' - URL="http://127.0.0.1:$port/ipfs/$HASH/test" && - echo "GET $URL" && - curl -svo outfile3 "$URL" 2>curl_getOverDirectory.out && - test_cmp infile3 outfile3 -' - -test_expect_success "HTTP PUT to /ipns fails" ' - PEERID=`ipfs id --format=""` && - URL="http://127.0.0.1:$port/ipns/$PEERID/test.txt" && - echo "PUT $URL" && - curl -svX PUT --data-binary @infile1 "$URL" 2>curl_putIpns.out && - grep "HTTP/1.1 400 Bad Request" curl_putIpns.out -' - - -test_kill_ipfs_daemon - -test_done From 60ba0b1821127cbc58ed27a53d5968219b01b095 Mon Sep 17 00:00:00 2001 From: Gus Eggert Date: Thu, 16 Mar 2023 10:29:45 -0400 Subject: [PATCH 0585/1212] test: increase max wait time for peering assertion The peering test is flaky and fails waiting for peers to be connected to each other, I don't know if this will fix it, but worth trying. --- test/cli/peering_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/cli/peering_test.go b/test/cli/peering_test.go index f3e797fae..ade52ec3c 100644 --- a/test/cli/peering_test.go +++ b/test/cli/peering_test.go @@ -46,7 +46,7 @@ func TestPeering(t *testing.T) { fromPeerIDs = append(fromPeerIDs, h.ExtractPeerID(p)) } return containsPeerID(to.PeerID(), fromPeerIDs) - }, 20*time.Second, 10*time.Millisecond, "%d -> %d not peered", from.ID, to.ID) + }, time.Minute, 10*time.Millisecond, "%d -> %d not peered", from.ID, to.ID) } assertNotPeered := func(h *harness.Harness, from *harness.Node, to *harness.Node) { From 4c49967d9cb8c41f63740e763949e964cd260eca Mon Sep 17 00:00:00 2001 From: Gus Eggert Date: Mon, 27 Mar 2023 14:58:12 -0400 Subject: [PATCH 0586/1212] feat: add client-side metrics for routing-v1 client --- routing/delegated.go | 5 +++++ test/cli/delegated_routing_http_test.go | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/routing/delegated.go b/routing/delegated.go index 1e8d7efa0..a32c5c091 100644 --- a/routing/delegated.go +++ b/routing/delegated.go @@ -221,6 +221,11 @@ func httpRoutingFromConfig(conf config.Router, extraHTTP *ExtraHTTPParams) (rout contentrouter.WithMaxProvideConcurrency(params.MaxProvideConcurrency), ) + err = view.Register(drclient.OpenCensusViews...) + if err != nil { + return nil, fmt.Errorf("registering HTTP delegated routing views: %w", err) + } + return &httpRoutingWrapper{ ContentRouting: cr, ProvideManyRouter: cr, diff --git a/test/cli/delegated_routing_http_test.go b/test/cli/delegated_routing_http_test.go index 446ea5150..8cf3368fa 100644 --- a/test/cli/delegated_routing_http_test.go +++ b/test/cli/delegated_routing_http_test.go @@ -118,4 +118,9 @@ func TestHTTPDelegatedRouting(t *testing.T) { assert.Equal(t, prov, res.Stdout.Trimmed()) }) + t.Run("HTTP client should emit OpenCensus metrics", func(t *testing.T) { + resp := node.APIClient().Get("/debug/metrics/prometheus") + assert.Contains(t, resp.Body, "routing_http_client_length_count") + }) + } From 405b1d2dcd976b9917f3b82036ce5266352bdca9 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Mon, 27 Mar 2023 11:24:40 +0200 Subject: [PATCH 0587/1212] chore: update go-libp2p to v0.26.4 --- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index cb8e9bc9a..65d5d86da 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -10,7 +10,7 @@ require ( github.com/ipfs/go-libipfs v0.7.0 github.com/ipfs/interface-go-ipfs-core v0.11.0 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 - github.com/libp2p/go-libp2p v0.26.3 + github.com/libp2p/go-libp2p v0.26.4 github.com/multiformats/go-multiaddr v0.8.0 ) diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index bfdbf90fe..fed70264a 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -730,8 +730,8 @@ github.com/libp2p/go-libp2p v0.7.0/go.mod h1:hZJf8txWeCduQRDC/WSqBGMxaTHCOYHt2xS github.com/libp2p/go-libp2p v0.7.4/go.mod h1:oXsBlTLF1q7pxr+9w6lqzS1ILpyHsaBPniVO7zIHGMw= github.com/libp2p/go-libp2p v0.8.1/go.mod h1:QRNH9pwdbEBpx5DTJYg+qxcVaDMAz3Ee/qDKwXujH5o= github.com/libp2p/go-libp2p v0.14.3/go.mod h1:d12V4PdKbpL0T1/gsUNN8DfgMuRPDX8bS2QxCZlwRH0= -github.com/libp2p/go-libp2p v0.26.3 h1:6g/psubqwdaBqNNoidbRKSTBEYgaOuKBhHl8Q5tO+PM= -github.com/libp2p/go-libp2p v0.26.3/go.mod h1:x75BN32YbwuY0Awm2Uix4d4KOz+/4piInkp4Wr3yOo8= +github.com/libp2p/go-libp2p v0.26.4 h1:VA9ChjN0n1BwwfU/dqx4Zj9ezXtIxGk8FyJPwFONqxs= +github.com/libp2p/go-libp2p v0.26.4/go.mod h1:x75BN32YbwuY0Awm2Uix4d4KOz+/4piInkp4Wr3yOo8= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-autonat v0.1.0/go.mod h1:1tLf2yXxiE/oKGtDwPYWTSYG3PtvYlJmg7NeVtPRqH8= diff --git a/go.mod b/go.mod index 4a8bf632c..47111ef0c 100644 --- a/go.mod +++ b/go.mod @@ -67,7 +67,7 @@ require ( 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.26.3 + github.com/libp2p/go-libp2p v0.26.4 github.com/libp2p/go-libp2p-http v0.4.0 github.com/libp2p/go-libp2p-kad-dht v0.21.1 github.com/libp2p/go-libp2p-kbucket v0.5.0 diff --git a/go.sum b/go.sum index c259bc1a1..dceb1ca79 100644 --- a/go.sum +++ b/go.sum @@ -760,8 +760,8 @@ github.com/libp2p/go-libp2p v0.7.0/go.mod h1:hZJf8txWeCduQRDC/WSqBGMxaTHCOYHt2xS github.com/libp2p/go-libp2p v0.7.4/go.mod h1:oXsBlTLF1q7pxr+9w6lqzS1ILpyHsaBPniVO7zIHGMw= github.com/libp2p/go-libp2p v0.8.1/go.mod h1:QRNH9pwdbEBpx5DTJYg+qxcVaDMAz3Ee/qDKwXujH5o= github.com/libp2p/go-libp2p v0.14.3/go.mod h1:d12V4PdKbpL0T1/gsUNN8DfgMuRPDX8bS2QxCZlwRH0= -github.com/libp2p/go-libp2p v0.26.3 h1:6g/psubqwdaBqNNoidbRKSTBEYgaOuKBhHl8Q5tO+PM= -github.com/libp2p/go-libp2p v0.26.3/go.mod h1:x75BN32YbwuY0Awm2Uix4d4KOz+/4piInkp4Wr3yOo8= +github.com/libp2p/go-libp2p v0.26.4 h1:VA9ChjN0n1BwwfU/dqx4Zj9ezXtIxGk8FyJPwFONqxs= +github.com/libp2p/go-libp2p v0.26.4/go.mod h1:x75BN32YbwuY0Awm2Uix4d4KOz+/4piInkp4Wr3yOo8= github.com/libp2p/go-libp2p-asn-util v0.2.0 h1:rg3+Os8jbnO5DxkC7K/Utdi+DkY3q/d1/1q+8WeNAsw= github.com/libp2p/go-libp2p-asn-util v0.2.0/go.mod h1:WoaWxbHKBymSN41hWSq/lGKJEca7TNm58+gGJi2WsLI= github.com/libp2p/go-libp2p-autonat v0.1.0/go.mod h1:1tLf2yXxiE/oKGtDwPYWTSYG3PtvYlJmg7NeVtPRqH8= From 5c21cf0ce95d7c2710d5bb5dd58e2871c0fbc7bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Pedro?= <92101826+PedrobyJoao@users.noreply.github.com> Date: Tue, 28 Mar 2023 07:38:24 -0300 Subject: [PATCH 0588/1212] docs: adding example of connection and pinning to README (#173) Co-authored-by: JPexplorer This commit was moved from ipfs/go-ipfs-http-client@b0de2b028e6ef03d4dba3ed105641ad299d4f7be --- client/httpapi/README.md | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/client/httpapi/README.md b/client/httpapi/README.md index d3e14ac3f..da25f24fe 100644 --- a/client/httpapi/README.md +++ b/client/httpapi/README.md @@ -17,6 +17,41 @@ greatest features, please use _this_ package. https://godoc.org/github.com/ipfs/go-ipfs-http-api +### Example + +Pin file on your local IPFS node based on its CID: + +```go +package main + +import ( + "context" + "fmt" + + ipfsClient "github.com/ipfs/go-ipfs-http-client" + path "github.com/ipfs/interface-go-ipfs-core/path" +) + +func main() { + // "Connect" to local node + node, err := ipfsClient.NewLocalApi() + if err != nil { + fmt.Printf(err) + return + } + // Pin a given file by its CID + ctx := context.Background() + cid := "bafkreidtuosuw37f5xmn65b3ksdiikajy7pwjjslzj2lxxz2vc4wdy3zku" + p := path.New(cid) + err = node.Pin().Add(ctx, p) + if err != nil { + fmt.Printf(err) + return + } + return +} +``` + ## Contribute Feel free to join in. All welcome. Open an [issue](https://github.com/ipfs/go-ipfs-http-api/issues)! From 2bd6d22617a248c6f246432c2472e743024b152c Mon Sep 17 00:00:00 2001 From: Jorropo Date: Tue, 28 Mar 2023 15:25:01 +0200 Subject: [PATCH 0589/1212] chore: bump sharness-deps for go 1.20 --- test/dependencies/go.mod | 101 +++++----- test/dependencies/go.sum | 411 +++++++++++++-------------------------- 2 files changed, 183 insertions(+), 329 deletions(-) diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 1a0eea226..5c2857114 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -8,21 +8,21 @@ require ( github.com/ipfs/go-blockservice v0.3.0 github.com/ipfs/go-cid v0.3.2 github.com/ipfs/go-cidutil v0.1.0 - github.com/ipfs/go-datastore v0.5.1 - github.com/ipfs/go-graphsync v0.13.2 + github.com/ipfs/go-datastore v0.6.0 + github.com/ipfs/go-graphsync v0.14.3 github.com/ipfs/go-ipfs-blockstore v1.2.0 github.com/ipfs/go-ipfs-exchange-offline v0.2.0 github.com/ipfs/go-log v1.0.5 github.com/ipfs/go-merkledag v0.8.1 - github.com/ipfs/go-unixfs v0.3.1 + github.com/ipfs/go-unixfs v0.4.3 github.com/ipfs/hang-fds v0.1.0 github.com/ipfs/iptb v1.4.0 github.com/ipfs/iptb-plugins v0.3.0 - github.com/ipld/go-ipld-prime v0.19.0 + github.com/ipld/go-ipld-prime v0.20.0 github.com/jbenet/go-random v0.0.0-20190219211222-123a90aedc0c github.com/jbenet/go-random-files v0.0.0-20190219210431-31b3f20ebded - github.com/libp2p/go-libp2p v0.22.0 - github.com/multiformats/go-multiaddr v0.6.0 + github.com/libp2p/go-libp2p v0.26.4 + github.com/multiformats/go-multiaddr v0.8.0 github.com/multiformats/go-multihash v0.2.1 gotest.tools/gotestsum v0.4.2 ) @@ -36,7 +36,6 @@ require ( github.com/GaijinEntertainment/go-exhaustruct/v2 v2.3.0 // indirect github.com/Masterminds/semver v1.5.0 // indirect github.com/OpenPeeDeeP/depguard v1.1.0 // indirect - github.com/Stebalien/go-bitfield v0.0.1 // indirect github.com/alecthomas/units v0.0.0-20210927113745-59d0afb8317a // indirect github.com/alexkohler/prealloc v1.0.0 // indirect github.com/alingse/asasalint v0.0.11 // indirect @@ -50,12 +49,11 @@ require ( github.com/breml/bidichk v0.2.3 // indirect github.com/breml/errchkjson v0.3.0 // indirect github.com/butuzov/ireturn v0.1.1 // indirect - github.com/cespare/xxhash/v2 v2.1.2 // indirect + github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/charithe/durationcheck v0.0.9 // indirect github.com/chavacava/garif v0.0.0-20220630083739-93517212f375 // indirect - github.com/cheekybits/genny v1.0.0 // indirect github.com/containerd/cgroups v1.0.4 // indirect - github.com/coreos/go-systemd/v22 v22.3.2 // indirect + github.com/coreos/go-systemd/v22 v22.5.0 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/curioswitch/go-reassign v0.1.2 // indirect github.com/daixiang0/gci v0.6.3 // indirect @@ -63,7 +61,7 @@ require ( github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect github.com/denis-tingaikin/go-header v0.4.3 // indirect - github.com/docker/go-units v0.4.0 // indirect + github.com/docker/go-units v0.5.0 // indirect github.com/dustin/go-humanize v1.0.0 // indirect github.com/elastic/gosigar v0.14.2 // indirect github.com/esimonov/ifshort v1.0.4 // indirect @@ -90,6 +88,7 @@ require ( github.com/godbus/dbus/v5 v5.1.0 // indirect github.com/gofrs/flock v0.8.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/mock v1.6.0 // indirect github.com/golang/protobuf v1.5.2 // indirect github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2 // indirect github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a // indirect @@ -102,6 +101,7 @@ require ( github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4 // indirect github.com/google/go-cmp v0.5.9 // indirect github.com/google/gopacket v1.1.19 // indirect + github.com/google/pprof v0.0.0-20221203041831-ce31453925ec // indirect github.com/google/uuid v1.3.0 // indirect github.com/gordonklaus/ineffassign v0.0.0-20210914165742-4cc7213b9bc8 // indirect github.com/gorilla/websocket v1.5.0 // indirect @@ -120,7 +120,7 @@ require ( github.com/huin/goupnp v1.0.3 // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/ipfs/bbloom v0.0.4 // indirect - github.com/ipfs/go-bitfield v1.0.0 // indirect + github.com/ipfs/go-bitfield v1.1.0 // indirect github.com/ipfs/go-block-format v0.0.3 // indirect github.com/ipfs/go-ipfs-config v0.19.0 // indirect github.com/ipfs/go-ipfs-ds-help v1.1.0 // indirect @@ -132,11 +132,11 @@ require ( github.com/ipfs/go-ipld-legacy v0.1.0 // indirect github.com/ipfs/go-log/v2 v2.5.1 // indirect github.com/ipfs/go-metrics-interface v0.0.1 // indirect - github.com/ipfs/go-peertaskqueue v0.7.1 // indirect - github.com/ipfs/go-unixfsnode v1.4.0 // indirect + github.com/ipfs/go-peertaskqueue v0.8.0 // indirect + github.com/ipfs/go-unixfsnode v1.5.2 // indirect github.com/ipfs/go-verifcid v0.0.1 // indirect github.com/ipfs/interface-go-ipfs-core v0.7.0 // indirect - github.com/ipld/go-codec-dagpb v1.4.0 // indirect + github.com/ipld/go-codec-dagpb v1.5.0 // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect github.com/jbenet/goprocess v0.1.4 // indirect @@ -147,8 +147,8 @@ require ( github.com/julz/importas v0.1.0 // indirect github.com/kisielk/errcheck v1.6.2 // indirect github.com/kisielk/gotool v1.0.0 // indirect - github.com/klauspost/compress v1.15.1 // indirect - github.com/klauspost/cpuid/v2 v2.1.0 // indirect + github.com/klauspost/compress v1.15.12 // indirect + github.com/klauspost/cpuid/v2 v2.2.1 // indirect github.com/koron/go-ssdp v0.0.3 // indirect github.com/kulti/thelper v0.6.3 // indirect github.com/kunwardeep/paralleltest v1.0.6 // indirect @@ -161,28 +161,20 @@ require ( github.com/libp2p/go-flow-metrics v0.1.0 // indirect github.com/libp2p/go-libp2p-asn-util v0.2.0 // indirect github.com/libp2p/go-libp2p-core v0.20.1 // indirect - github.com/libp2p/go-libp2p-record v0.1.3 // indirect - github.com/libp2p/go-msgio v0.2.0 // indirect + github.com/libp2p/go-msgio v0.3.0 // indirect github.com/libp2p/go-nat v0.1.0 // indirect - github.com/libp2p/go-netroute v0.2.0 // indirect - github.com/libp2p/go-openssl v0.1.0 // indirect + github.com/libp2p/go-netroute v0.2.1 // indirect github.com/libp2p/go-reuseport v0.2.0 // indirect - github.com/libp2p/go-yamux/v3 v3.1.2 // indirect - github.com/lucas-clemente/quic-go v0.28.1 // indirect + github.com/libp2p/go-yamux/v4 v4.0.0 // indirect github.com/lufeee/execinquery v1.2.1 // indirect github.com/magiconair/properties v1.8.6 // indirect github.com/maratori/testpackage v1.1.0 // indirect - github.com/marten-seemann/qtls-go1-16 v0.1.5 // indirect - github.com/marten-seemann/qtls-go1-17 v0.1.2 // indirect - github.com/marten-seemann/qtls-go1-18 v0.1.2 // indirect - github.com/marten-seemann/qtls-go1-19 v0.1.0 // indirect github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect github.com/matoous/godox v0.0.0-20210227103229-6504466cf951 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.16 // indirect - github.com/mattn/go-pointer v0.0.1 // indirect github.com/mattn/go-runewidth v0.0.9 // indirect - github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/mbilski/exhaustivestruct v1.2.0 // indirect github.com/mgechev/revive v1.2.3 // indirect github.com/miekg/dns v1.1.50 // indirect @@ -193,21 +185,20 @@ require ( github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/moricho/tparallel v0.2.1 // indirect github.com/mr-tron/base58 v1.2.0 // indirect - github.com/multiformats/go-base32 v0.0.4 // indirect - github.com/multiformats/go-base36 v0.1.0 // indirect + github.com/multiformats/go-base32 v0.1.0 // indirect + github.com/multiformats/go-base36 v0.2.0 // indirect github.com/multiformats/go-multiaddr-dns v0.3.1 // indirect github.com/multiformats/go-multiaddr-fmt v0.1.0 // indirect github.com/multiformats/go-multibase v0.1.1 // indirect - github.com/multiformats/go-multicodec v0.6.0 // indirect - github.com/multiformats/go-multistream v0.3.3 // indirect - github.com/multiformats/go-varint v0.0.6 // indirect + github.com/multiformats/go-multicodec v0.8.0 // indirect + github.com/multiformats/go-multistream v0.4.1 // indirect + github.com/multiformats/go-varint v0.0.7 // indirect github.com/nakabonne/nestif v0.3.1 // indirect github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354 // indirect github.com/nishanths/exhaustive v0.8.1 // indirect github.com/nishanths/predeclared v0.2.2 // indirect - github.com/nxadm/tail v1.4.8 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect - github.com/onsi/ginkgo v1.16.5 // indirect + github.com/onsi/ginkgo/v2 v2.5.1 // indirect github.com/opencontainers/runtime-spec v1.0.2 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect @@ -218,14 +209,19 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect github.com/polydawn/refmt v0.0.0-20201211092308-30ac6d18308e // indirect github.com/polyfloyd/go-errorlint v1.0.2 // indirect - github.com/prometheus/client_golang v1.12.1 // indirect - github.com/prometheus/client_model v0.2.0 // indirect + github.com/prometheus/client_golang v1.14.0 // indirect + github.com/prometheus/client_model v0.3.0 // indirect github.com/prometheus/common v0.37.0 // indirect github.com/prometheus/procfs v0.8.0 // indirect github.com/quasilyte/go-ruleguard v0.3.17 // indirect github.com/quasilyte/gogrep v0.0.0-20220120141003-628d8b3623b5 // indirect github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95 // indirect github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 // indirect + github.com/quic-go/qpack v0.4.0 // indirect + github.com/quic-go/qtls-go1-19 v0.2.1 // indirect + github.com/quic-go/qtls-go1-20 v0.1.1 // indirect + github.com/quic-go/quic-go v0.33.0 // indirect + github.com/quic-go/webtransport-go v0.5.2 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/ryancurrah/gomodguard v1.2.4 // indirect @@ -241,7 +237,6 @@ require ( github.com/sivchari/tenv v1.7.0 // indirect github.com/sonatard/noctx v0.0.1 // indirect github.com/sourcegraph/go-diff v0.6.1 // indirect - github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/spf13/afero v1.8.2 // indirect github.com/spf13/cast v1.5.0 // indirect @@ -251,8 +246,8 @@ require ( github.com/spf13/viper v1.12.0 // indirect github.com/ssgreg/nlreturn/v2 v2.2.1 // indirect github.com/stbenjam/no-sprintf-host-port v0.1.1 // indirect - github.com/stretchr/objx v0.4.0 // indirect - github.com/stretchr/testify v1.8.0 // indirect + github.com/stretchr/objx v0.5.0 // indirect + github.com/stretchr/testify v1.8.1 // indirect github.com/subosito/gotenv v1.4.0 // indirect github.com/sylvia7788/contextcheck v1.0.6 // indirect github.com/tdakkota/asciicheck v0.1.1 // indirect @@ -272,22 +267,23 @@ require ( go.opentelemetry.io/otel v1.2.0 // indirect go.opentelemetry.io/otel/trace v1.2.0 // indirect go.uber.org/atomic v1.10.0 // indirect + go.uber.org/dig v1.15.0 // indirect + go.uber.org/fx v1.18.2 // indirect go.uber.org/multierr v1.8.0 // indirect - go.uber.org/zap v1.22.0 // indirect - golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa // indirect - golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect + go.uber.org/zap v1.24.0 // indirect + golang.org/x/crypto v0.4.0 // indirect + golang.org/x/exp v0.0.0-20221205204356-47842c84f3db // indirect golang.org/x/exp/typeparams v0.0.0-20220613132600-b0d781184e0d // indirect - golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect - golang.org/x/net v0.0.0-20220812174116-3211cb980234 // indirect - golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 // indirect - golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab // indirect - golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect - golang.org/x/text v0.3.7 // indirect - golang.org/x/tools v0.1.12 // indirect + golang.org/x/mod v0.7.0 // indirect + golang.org/x/net v0.4.0 // indirect + golang.org/x/sync v0.1.0 // indirect + golang.org/x/sys v0.3.0 // indirect + golang.org/x/term v0.3.0 // indirect + golang.org/x/text v0.5.0 // indirect + golang.org/x/tools v0.3.0 // indirect golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df // indirect google.golang.org/protobuf v1.28.1 // indirect gopkg.in/ini.v1 v1.66.6 // indirect - gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect honnef.co/go/tools v0.3.3 // indirect @@ -296,4 +292,5 @@ require ( mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed // indirect mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b // indirect mvdan.cc/unparam v0.0.0-20220706161116-678bad134442 // indirect + nhooyr.io/websocket v1.8.7 // indirect ) diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 47bd100f4..57e25d3fa 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -41,14 +41,12 @@ cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9 cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -dmitri.shuralyov.com/gpu/mtl v0.0.0-20201218220906-28db891af037/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU= dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4= dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU= git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg= github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= -github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/Antonboom/errname v0.1.7 h1:mBBDKvEYwPl4WFFNwec1CZO096G6vzK9vvDQzAwkako= github.com/Antonboom/errname v0.1.7/go.mod h1:g0ONh16msHIPgJSGsecu1G/dcF2hlYR/0SddnIAGavU= github.com/Antonboom/nilnil v0.1.1 h1:PHhrh5ANKFWRBh7TdYmyyq2gyT2lotnvFvvFbylF81Q= @@ -72,7 +70,6 @@ github.com/OpenPeeDeeP/depguard v1.1.0 h1:pjK9nLPS1FwQYGGpPxoMYpe7qACHOhAWQMQzV7 github.com/OpenPeeDeeP/depguard v1.1.0/go.mod h1:JtAMzWkmFEzDPyAd+W0NHl1lvpQKTvT9jnRVsohBKpc= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= -github.com/Stebalien/go-bitfield v0.0.1 h1:X3kbSSPUaJK60wV2hjOPZwmpljr6VGCqdq4cBLhbQBo= github.com/Stebalien/go-bitfield v0.0.1/go.mod h1:GNjFpasyUVkHMsfEOk8EFLJ9syQ6SI+XWrX9Wf2XH0s= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= @@ -89,7 +86,6 @@ github.com/alexkohler/prealloc v1.0.0/go.mod h1:VetnK3dIgFBBKmg0YnD9F9x6Icjd+9cv github.com/alingse/asasalint v0.0.11 h1:SFwnQXJ49Kx/1GghOFz1XGqHYKp21Kq1nHad/0WQRnw= github.com/alingse/asasalint v0.0.11/go.mod h1:nCaoMhw7a9kSJObvQyVzNTPBDbNpdocqrSP7t/cW5+I= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= -github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= @@ -129,12 +125,10 @@ github.com/btcsuite/btcd v0.0.0-20190605094302-a0d1e3e36d50/go.mod h1:3J08xEfcug github.com/btcsuite/btcd v0.0.0-20190824003749-130ea5bddde3/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= github.com/btcsuite/btcd v0.21.0-beta/go.mod h1:ZSWyehm27aAuS9bvkATT+Xte3hjHZ+MRgMY/8NJ7K94= -github.com/btcsuite/btcd v0.22.0-beta/go.mod h1:9n5ntfhhHQBIhUvlhDvD3Qg6fRUj4jkN0VB8L8svzOA= github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= github.com/btcsuite/btcutil v1.0.2/go.mod h1:j9HUFwoQRsZL3V4n+qG+CUnEGHOarIxfC3Le2Yhbcts= -github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce/go.mod h1:0DVlHczLPewLcPGEIeUEzfOJhqGPQ0mJJRDBtD307+o= github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= github.com/btcsuite/goleveldb v1.0.0/go.mod h1:QiK9vBlgftBg6rWQIj6wFzbPfRjiykIEhBH4obrXJ/I= @@ -150,32 +144,26 @@ github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QH github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/charithe/durationcheck v0.0.9 h1:mPP4ucLrf/rKZiIG/a9IPXHGlh8p4CzgpyTy6EEutYk= github.com/charithe/durationcheck v0.0.9/go.mod h1:SSbRIBVfMjCi/kEB6K65XEA83D6prSM8ap1UCpNKtgg= github.com/chavacava/garif v0.0.0-20220630083739-93517212f375 h1:E7LT642ysztPWE0dfz43cWOvMiF42DyTRC+eZIaO4yI= github.com/chavacava/garif v0.0.0-20220630083739-93517212f375/go.mod h1:4m1Rv7xfuwWPNKXlThldNuJvutYM6J95wNuuVmn55To= -github.com/cheekybits/genny v1.0.0 h1:uGGa4nei+j20rOSeDeP5Of12XVm7TGUd4dJA9RDitfE= github.com/cheekybits/genny v1.0.0/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ= 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/cilium/ebpf v0.4.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= 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= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= -github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/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/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE= -github.com/containerd/cgroups v1.0.3/go.mod h1:/ofk34relqNjSGyqPrmEULrO4Sc8LJhvJmWbUCUKqj8= github.com/containerd/cgroups v1.0.4 h1:jN/mbWBEaz+T1pi5OFtnkQ+8qnmEbAr1Oo1FRm5B0dA= github.com/containerd/cgroups v1.0.4/go.mod h1:nLNQtsF7Sl2HxNebu77i1R0oDlhiTG+kO4JTrUzo6IA= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= @@ -185,10 +173,9 @@ github.com/coreos/go-semver v0.2.1-0.20180108230905-e214231b295a/go.mod h1:nnelY github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= 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/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= +github.com/coreos/go-systemd/v22 v22.5.0/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= @@ -223,13 +210,13 @@ github.com/dgraph-io/badger v1.5.5-0.20190226225317-8115aed38f8f/go.mod h1:VZxzA github.com/dgraph-io/badger v1.6.0-rc1/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= github.com/dgraph-io/badger v1.6.1/go.mod h1:FRmFw3uxvcpa8zG3Rxs0th+hCLIuaQg8HlNV5bjgnuU= -github.com/dgraph-io/badger v1.6.2/go.mod h1:JW2yswe3V058sS0kZ2h/AXeDSqFjxnZcRrVH//y2UQE= github.com/dgraph-io/ristretto v0.0.2/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-farm v0.0.0-20190104051053-3adb47b1fb0f/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= 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/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= +github.com/docker/go-units v0.5.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= @@ -246,7 +233,6 @@ github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.m github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/esimonov/ifshort v1.0.4 h1:6SID4yGWfRae/M7hkVDVVyppy8q/v9OuxNdmjLQStBA= github.com/esimonov/ifshort v1.0.4/go.mod h1:Pe8zjlRrJ80+q2CxHLfEOfTwxCZ4O+MuhcHcfgNWTk0= @@ -270,18 +256,18 @@ github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiD github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= -github.com/frankban/quicktest v1.14.0/go.mod h1:NeW+ay9A/U67EYXNFA1nPE8e/tnQv/09mUdL/ijj8og= -github.com/frankban/quicktest v1.14.2/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps= -github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= -github.com/frankban/quicktest v1.14.3/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps= +github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI= github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= github.com/fzipp/gocyclo v0.6.0 h1:lsblElZG7d3ALtGMx9fmxeTKZaLLpU8mET09yN4BBLo= github.com/fzipp/gocyclo v0.6.0/go.mod h1:rXPyn8fnlpa0R2csP/31uerbiVBugk5whMdlyaLkLoA= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= +github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14= +github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= github.com/go-critic/go-critic v0.6.4 h1:tucuG1pvOyYgpBIrVxw0R6gwO42lNa92Aq3VaDoIs+E= @@ -299,7 +285,14 @@ github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9 github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= -github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= +github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= +github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= +github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= +github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= +github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= +github.com/go-playground/validator/v10 v10.2.0 h1:KgJ0snyC2R9VXYN2rneOtQcw5aHQB1Vv0sFl1UcHBOY= +github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I= @@ -327,6 +320,12 @@ github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b h1:khEcpUM4yFcxg4 github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= +github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0= +github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= +github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8= +github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= +github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo= +github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= @@ -410,7 +409,6 @@ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ 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= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= @@ -433,6 +431,8 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20221203041831-ce31453925ec h1:fR20TYVVwhK4O7r7y+McjRYyaTH6/vjwJOajE+XhlzM= +github.com/google/pprof v0.0.0-20221203041831-ce31453925ec/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -479,12 +479,10 @@ github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/gxed/go-shellwords v1.0.3 h1:2TP32H4TAklZUdz84oj95BJhVnIrRasyx2j1cqH5K38= github.com/gxed/go-shellwords v1.0.3/go.mod h1:N7paucT91ByIjmVJHhvoarjoQnmsi3Jd3vH7VqgtMxQ= github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= -github.com/hannahhoward/cbor-gen-for v0.0.0-20200817222906-ea96cece81f1/go.mod h1:jvfsLIxk0fY/2BKSQ1xf2406AKA5dwMmKKv0ADcOfN8= github.com/hannahhoward/go-pubsub v0.0.0-20200423002714-8d62886cc36e h1:3YKHER4nmd7b5qy5t0GWDTwSn4OyRgfAXSmo6VnryBY= github.com/hannahhoward/go-pubsub v0.0.0-20200423002714-8d62886cc36e/go.mod h1:I8h3MITA53gN9OnWGCgaMa0JWVRdXthWw4M3CPM54OY= github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= @@ -534,12 +532,11 @@ github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod github.com/ipfs/bbloom v0.0.1/go.mod h1:oqo8CVWsJFMOZqTglBG4wydCE4IQA/G2/SEofB0rjUI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/go-bitfield v1.0.0 h1:y/XHm2GEmD9wKngheWNNCNL0pzrWXZwCdQGv1ikXknQ= -github.com/ipfs/go-bitfield v1.0.0/go.mod h1:N/UiujQy+K+ceU1EF5EkVd1TNqevLrCQMIcAEPrdtus= +github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= +github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.0.9/go.mod h1:kAPf5qgn2W2DrgAcscZ3HrM9qh4pH+X8Fkk3UPrwvis= github.com/ipfs/go-bitswap v0.1.0/go.mod h1:FFJEf18E9izuCqUtHxbWEvq+reg7o4CW5wSAE1wsxj0= github.com/ipfs/go-bitswap v0.1.2/go.mod h1:qxSWS4NXGs7jQ6zQvoPY3+NmOfHHG47mhkiLzBpJQIs= -github.com/ipfs/go-bitswap v0.5.1/go.mod h1:P+ckC87ri1xFLvk74NlXdP0Kj9RmWAh4+H78sC6Qopo= github.com/ipfs/go-bitswap v0.6.0 h1:f2rc6GZtoSFhEIzQmddgGiel9xntj02Dg0ZNf2hSC+w= github.com/ipfs/go-bitswap v0.6.0/go.mod h1:Hj3ZXdOC5wBJvENtdqsixmzzRukqd8EHLxZLZc3mzRA= github.com/ipfs/go-block-format v0.0.1/go.mod h1:DK/YYcsSUIVAFNwo/KZCdIIbpN0ROH/baNLgayt4pFc= @@ -548,7 +545,6 @@ github.com/ipfs/go-block-format v0.0.3 h1:r8t66QstRp/pd/or4dpnbVfXT5Gt7lOqRvC+/d github.com/ipfs/go-block-format v0.0.3/go.mod h1:4LmD4ZUw0mhO+JSKdpWwrzATiEfM7WWgQ8H5l6P8MVk= github.com/ipfs/go-blockservice v0.0.7/go.mod h1:EOfb9k/Y878ZTRY/CH0x5+ATtaipfbRhbvNSdgc/7So= github.com/ipfs/go-blockservice v0.1.0/go.mod h1:hzmMScl1kXHg3M2BjTymbVPjv627N7sYcvYaKbop39M= -github.com/ipfs/go-blockservice v0.2.1/go.mod h1:k6SiwmgyYgs4M/qt+ww6amPeUH9EISLRBnvUurKJhi8= github.com/ipfs/go-blockservice v0.3.0 h1:cDgcZ+0P0Ih3sl8+qjFr2sVaMdysg/YZpLj5WJ8kiiw= github.com/ipfs/go-blockservice v0.3.0/go.mod h1:P5ppi8IHDC7O+pA0AlGTF09jruB2h+oP3wVVaZl8sfk= github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= @@ -558,8 +554,6 @@ github.com/ipfs/go-cid v0.0.4/go.mod h1:4LLaPOQwmk5z9LBgQnpkivrx8BJjUyGwTXCd5Xfj github.com/ipfs/go-cid v0.0.5/go.mod h1:plgt+Y5MnOey4vO4UlUazGqdbEXuFYitED67FexhXog= github.com/ipfs/go-cid v0.0.6/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I= github.com/ipfs/go-cid v0.0.7/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I= -github.com/ipfs/go-cid v0.1.0/go.mod h1:rH5/Xv83Rfy8Rw6xG+id3DYAMUVmem1MowoKwdXmN2o= -github.com/ipfs/go-cid v0.2.0/go.mod h1:P+HXFDF4CVhaVayiEb4wkAy7zBHxBwsJyt0Y5U6MLro= github.com/ipfs/go-cid v0.3.2 h1:OGgOd+JCFM+y1DjWPmVH+2/4POtpDzwcr7VgnB7mZXc= github.com/ipfs/go-cid v0.3.2/go.mod h1:gQ8pKqT/sUxGY+tIwy1RPpAojYu7jAyCp5Tz1svoupw= github.com/ipfs/go-cidutil v0.1.0 h1:RW5hO7Vcf16dplUU60Hs0AKDkQAVPVplr7lk97CFL+Q= @@ -574,32 +568,27 @@ github.com/ipfs/go-datastore v0.4.1/go.mod h1:SX/xMIKoCszPqp+z9JhPYCmoOoXTvaa13X github.com/ipfs/go-datastore v0.4.4/go.mod h1:SX/xMIKoCszPqp+z9JhPYCmoOoXTvaa13XEbGtsFUhA= github.com/ipfs/go-datastore v0.4.5/go.mod h1:eXTcaaiN6uOlVCLS9GjJUJtlvJfM3xk23w3fyfrmmJs= github.com/ipfs/go-datastore v0.5.0/go.mod h1:9zhEApYMTl17C8YDp7JmU7sQZi2/wqiYh73hakZ90Bk= -github.com/ipfs/go-datastore v0.5.1 h1:WkRhLuISI+XPD0uk3OskB0fYFSyqK8Ob5ZYew9Qa1nQ= -github.com/ipfs/go-datastore v0.5.1/go.mod h1:9zhEApYMTl17C8YDp7JmU7sQZi2/wqiYh73hakZ90Bk= +github.com/ipfs/go-datastore v0.6.0 h1:JKyz+Gvz1QEZw0LsX1IBn+JFCJQH4SJVFtM4uWU0Myk= +github.com/ipfs/go-datastore v0.6.0/go.mod h1:rt5M3nNbSO/8q1t4LNkLyUwRs8HupMeN/8O4Vn9YAT8= github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk= github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps= github.com/ipfs/go-ds-badger v0.0.2/go.mod h1:Y3QpeSFWQf6MopLTiZD+VT6IC1yZqaGmjvRcKeSGij8= github.com/ipfs/go-ds-badger v0.0.5/go.mod h1:g5AuuCGmr7efyzQhLL8MzwqcauPojGPUaHzfGTzuE3s= github.com/ipfs/go-ds-badger v0.2.1/go.mod h1:Tx7l3aTph3FMFrRS838dcSJh+jjA7cX9DrGVwx/NOwE= github.com/ipfs/go-ds-badger v0.2.3/go.mod h1:pEYw0rgg3FIrywKKnL+Snr+w/LjJZVMTBRn4FS6UHUk= -github.com/ipfs/go-ds-badger v0.3.0/go.mod h1:1ke6mXNqeV8K3y5Ak2bAA0osoTfmxUdupVCGm4QUIek= github.com/ipfs/go-ds-leveldb v0.0.1/go.mod h1:feO8V3kubwsEF22n0YRQCffeb79OOYIykR4L04tMOYc= github.com/ipfs/go-ds-leveldb v0.4.1/go.mod h1:jpbku/YqBSsBc1qgME8BkWS4AxzF2cEu1Ii2r79Hh9s= github.com/ipfs/go-ds-leveldb v0.4.2/go.mod h1:jpbku/YqBSsBc1qgME8BkWS4AxzF2cEu1Ii2r79Hh9s= -github.com/ipfs/go-ds-leveldb v0.5.0/go.mod h1:d3XG9RUDzQ6V4SHi8+Xgj9j1XuEk1z82lquxrVbml/Q= -github.com/ipfs/go-graphsync v0.13.2 h1:+7IjTrdg3+3iwtPXSkLoxvhaByS3+3b9NStMAowFqkw= -github.com/ipfs/go-graphsync v0.13.2/go.mod h1:TO1Y65spARny/t37hkid5xCpQJ6vR7A7VFTEUb0Z6eA= +github.com/ipfs/go-graphsync v0.14.3 h1:IXH9S7AraMQ0J6Fzcl8rqSPqLn+es33bD8OW2KNyU/o= +github.com/ipfs/go-graphsync v0.14.3/go.mod h1:yT0AfjFgicOoWdAlUJ96tQ5AkuGI4r1taIQX/aHbBQo= github.com/ipfs/go-ipfs-blockstore v0.0.1/go.mod h1:d3WClOmRQKFnJ0Jz/jj/zmksX0ma1gROTlovZKBmN08= github.com/ipfs/go-ipfs-blockstore v0.1.0/go.mod h1:5aD0AvHPi7mZc6Ci1WCAhiBQu2IsfTduLl+422H6Rqw= -github.com/ipfs/go-ipfs-blockstore v0.2.1/go.mod h1:jGesd8EtCM3/zPgx+qr0/feTXGUeRai6adgwC+Q+JvE= -github.com/ipfs/go-ipfs-blockstore v1.1.2/go.mod h1:w51tNR9y5+QXB0wkNcHt4O2aSZjTdqaEWaQdSxEyUOY= github.com/ipfs/go-ipfs-blockstore v1.2.0 h1:n3WTeJ4LdICWs/0VSfjHrlqpPpl6MZ+ySd3j8qz0ykw= github.com/ipfs/go-ipfs-blockstore v1.2.0/go.mod h1:eh8eTFLiINYNSNawfZOC7HOxNTxpB1PFuA5E1m/7exE= github.com/ipfs/go-ipfs-blocksutil v0.0.1 h1:Eh/H4pc1hsvhzsQoMEP3Bke/aW5P5rVM1IWFJMcGIPQ= github.com/ipfs/go-ipfs-blocksutil v0.0.1/go.mod h1:Yq4M86uIOmxmGPUHv/uI7uKqZNtLb449gwKqXjIsnRk= github.com/ipfs/go-ipfs-chunker v0.0.1/go.mod h1:tWewYK0we3+rMbOh7pPFGDyypCtvGcBFymgY4rSDLAw= github.com/ipfs/go-ipfs-chunker v0.0.5 h1:ojCf7HV/m+uS2vhUGWcogIIxiO5ubl5O57Q7NapWLY8= -github.com/ipfs/go-ipfs-chunker v0.0.5/go.mod h1:jhgdF8vxRHycr00k13FM8Y0E+6BoalYeobXmUyTreP8= github.com/ipfs/go-ipfs-config v0.5.3/go.mod h1:nSLCFtlaL+2rbl3F+9D4gQZQbT1LjRKx7TJg/IHz6oM= github.com/ipfs/go-ipfs-config v0.19.0 h1:OuKIL+BkOZgJ+hb4Wg/9ynCtE/BaZBWcGy8hgdMepAo= github.com/ipfs/go-ipfs-config v0.19.0/go.mod h1:wz2lKzOjgJeYJa6zx8W9VT7mz+iSd0laBMqS/9wmX6A= @@ -614,11 +603,9 @@ github.com/ipfs/go-ipfs-exchange-interface v0.0.1/go.mod h1:c8MwfHjtQjPoDyiy9cFq github.com/ipfs/go-ipfs-exchange-interface v0.1.0 h1:TiMekCrOGQuWYtZO3mf4YJXDIdNgnKWZ9IE3fGlnWfo= github.com/ipfs/go-ipfs-exchange-interface v0.1.0/go.mod h1:ych7WPlyHqFvCi/uQI48zLZuAWVP5iTQPXEfVaw5WEI= github.com/ipfs/go-ipfs-exchange-offline v0.0.1/go.mod h1:WhHSFCVYX36H/anEKQboAzpUws3x7UeEGkzQc3iNkM0= -github.com/ipfs/go-ipfs-exchange-offline v0.1.1/go.mod h1:vTiBRIbzSwDD0OWm+i3xeT0mO7jG2cbJYatp3HPk5XY= github.com/ipfs/go-ipfs-exchange-offline v0.2.0 h1:2PF4o4A7W656rC0RxuhUace997FTcDTcIQ6NoEtyjAI= github.com/ipfs/go-ipfs-exchange-offline v0.2.0/go.mod h1:HjwBeW0dvZvfOMwDP0TSKXIHf2s+ksdP4E3MLDRtLKY= github.com/ipfs/go-ipfs-files v0.0.3/go.mod h1:INEFm0LL2LWXBhNJ2PMIIb2w45hpXgPjNoE7yA8Y1d4= -github.com/ipfs/go-ipfs-files v0.0.8 h1:8o0oFJkJ8UkO/ABl8T6ac6tKF3+NIpj67aAB6ZpusRg= github.com/ipfs/go-ipfs-files v0.0.8/go.mod h1:wiN/jSG8FKyk7N0WyctKSvq3ljIa2NNTiZB55kpTdOs= github.com/ipfs/go-ipfs-posinfo v0.0.1 h1:Esoxj+1JgSjX0+ylc0hUmJCOv6V2vFoZiETLR6OtpRs= github.com/ipfs/go-ipfs-posinfo v0.0.1/go.mod h1:SwyeVP+jCwiDu0C313l/8jg6ZxM0qqtlt2a0vILTc1A= @@ -627,8 +614,8 @@ github.com/ipfs/go-ipfs-pq v0.0.2 h1:e1vOOW6MuOwG2lqxcLA+wEn93i/9laCY8sXAw76jFOY github.com/ipfs/go-ipfs-pq v0.0.2/go.mod h1:LWIqQpqfRG3fNc5XsnIhz/wQ2XXGyugQwls7BgUmUfY= github.com/ipfs/go-ipfs-routing v0.0.1/go.mod h1:k76lf20iKFxQTjcJokbPM9iBXVXVZhcOwc360N4nuKs= github.com/ipfs/go-ipfs-routing v0.1.0/go.mod h1:hYoUkJLyAUKhF58tysKpids8RNDPO42BVMgK5dNsoqY= -github.com/ipfs/go-ipfs-routing v0.2.1 h1:E+whHWhJkdN9YeoHZNj5itzc+OR292AJ2uE9FFiW0BY= github.com/ipfs/go-ipfs-routing v0.2.1/go.mod h1:xiNNiwgjmLqPS1cimvAw6EyB9rkVDbiocA4yY+wRNLM= +github.com/ipfs/go-ipfs-routing v0.3.0 h1:9W/W3N+g+y4ZDeffSgqhgo7BsBSJwPMcyssET9OWevc= github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyBCNzQxlJBc= github.com/ipfs/go-ipfs-util v0.0.2 h1:59Sswnk1MFaiq+VcaknX7aYEyGyGDAA73ilhEK2POp8= github.com/ipfs/go-ipfs-util v0.0.2/go.mod h1:CbPtkWJzjLdEcezDns2XYaehFVNXG9zrdrtMecczcsQ= @@ -645,6 +632,7 @@ github.com/ipfs/go-ipld-format v0.4.0 h1:yqJSaJftjmjc9jEOFYlpkwOLVKv68OD27jFLlSg github.com/ipfs/go-ipld-format v0.4.0/go.mod h1:co/SdBE8h99968X0hViiw1MNlh6fvxxnHpvVLnH7jSM= github.com/ipfs/go-ipld-legacy v0.1.0 h1:wxkkc4k8cnvIGIjPO0waJCe7SHEyFgl+yQdafdjGrpA= github.com/ipfs/go-ipld-legacy v0.1.0/go.mod h1:86f5P/srAmh9GcIcWQR9lfFLZPrIyyXQeVlOWeeWEuI= +github.com/ipfs/go-libipfs v0.1.0 h1:I6CrHHp4cIiqsWJPVU3QBH4BZrRWSljS2aAbA3Eg9AY= github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= github.com/ipfs/go-log v1.0.2/go.mod h1:1MNjMxe0u6xvJZgeqbJ8vdo2TKaGwZ1a0Bpza+sr2Sk= github.com/ipfs/go-log v1.0.3/go.mod h1:OsLySYkwIbiSUR/yBTdv1qPtcE4FW3WPWk/ewz9Ru+A= @@ -657,13 +645,11 @@ github.com/ipfs/go-log/v2 v2.0.5/go.mod h1:eZs4Xt4ZUJQFM3DlanGhy7TkwwawCZcSByscw 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/go.mod h1:QqGoj30OTpnKaG/LKTGTxoP2mmQtjVMEnK72gynbe/g= -github.com/ipfs/go-log/v2 v2.5.0/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOLU9U5UI= github.com/ipfs/go-log/v2 v2.5.1 h1:1XdUzF7048prq4aBjDQQ4SL5RxftpRGdXhNRwKSAlcY= github.com/ipfs/go-log/v2 v2.5.1/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= -github.com/ipfs/go-merkledag v0.5.1/go.mod h1:cLMZXx8J08idkp5+id62iVftUQV+HlYJ3PIhDfZsjA4= github.com/ipfs/go-merkledag v0.8.1 h1:N3yrqSre/ffvdwtHL4MXy0n7XH+VzN8DlzDrJySPa94= github.com/ipfs/go-merkledag v0.8.1/go.mod h1:uYUlWE34GhbcTjGuUDEcdPzsEtOdnOupL64NgSRjmWI= github.com/ipfs/go-metrics-interface v0.0.1 h1:j+cpbjYvu4R8zbleSs36gvB7jR+wsL2fGD6n0jO4kdg= @@ -672,14 +658,14 @@ github.com/ipfs/go-path v0.0.7/go.mod h1:6KTKmeRnBXgqrTvzFrPV3CamxcgvXX/4z79tfAd github.com/ipfs/go-peertaskqueue v0.0.4/go.mod h1:03H8fhyeMfKNFWqzYEVyMbcPUeYrqP1MX6Kd+aN+rMQ= github.com/ipfs/go-peertaskqueue v0.1.0/go.mod h1:Jmk3IyCcfl1W3jTW3YpghSwSEC6IJ3Vzz/jUmWw8Z0U= github.com/ipfs/go-peertaskqueue v0.7.0/go.mod h1:M/akTIE/z1jGNXMU7kFB4TeSEFvj68ow0Rrb04donIU= -github.com/ipfs/go-peertaskqueue v0.7.1 h1:7PLjon3RZwRQMgOTvYccZ+mjzkmds/7YzSWKFlBAypE= -github.com/ipfs/go-peertaskqueue v0.7.1/go.mod h1:M/akTIE/z1jGNXMU7kFB4TeSEFvj68ow0Rrb04donIU= +github.com/ipfs/go-peertaskqueue v0.8.0 h1:JyNO144tfu9bx6Hpo119zvbEL9iQ760FHOiJYsUjqaU= +github.com/ipfs/go-peertaskqueue v0.8.0/go.mod h1:cz8hEnnARq4Du5TGqiWKgMr/BOSQ5XOgMOh1K5YYKKM= github.com/ipfs/go-todocounter v0.0.1/go.mod h1:l5aErvQc8qKE2r7NDMjmq5UNAvuZy0rC8BHOplkWvZ4= github.com/ipfs/go-unixfs v0.2.4/go.mod h1:SUdisfUjNoSDzzhGVxvCL9QO/nKdwXdr+gbMUdqcbYw= -github.com/ipfs/go-unixfs v0.3.1 h1:LrfED0OGfG98ZEegO4/xiprx2O+yS+krCMQSp7zLVv8= -github.com/ipfs/go-unixfs v0.3.1/go.mod h1:h4qfQYzghiIc8ZNFKiLMFWOTzrWIAtzYQ59W/pCFf1o= -github.com/ipfs/go-unixfsnode v1.4.0 h1:9BUxHBXrbNi8mWHc6j+5C580WJqtVw9uoeEKn4tMhwA= -github.com/ipfs/go-unixfsnode v1.4.0/go.mod h1:qc7YFFZ8tABc58p62HnIYbUMwj9chhUuFWmxSokfePo= +github.com/ipfs/go-unixfs v0.4.3 h1:EdDc1sNZNFDUlo4UrVAvvAofVI5EwTnKu8Nv8mgXkWQ= +github.com/ipfs/go-unixfs v0.4.3/go.mod h1:TSG7G1UuT+l4pNj91raXAPkX0BhJi3jST1FDTfQ5QyM= +github.com/ipfs/go-unixfsnode v1.5.2 h1:CvsiTt58W2uR5dD8bqQv+aAY0c1qolmXmSyNbPHYiew= +github.com/ipfs/go-unixfsnode v1.5.2/go.mod h1:NlOebRwYx8lMCNMdhAhEspYPBD3obp7TE0LvBqHY+ks= github.com/ipfs/go-verifcid v0.0.1 h1:m2HI7zIuR5TFyQ1b79Da5N9dnnCP1vcu2QqawmWlK2E= github.com/ipfs/go-verifcid v0.0.1/go.mod h1:5Hrva5KBeIog4A+UpqlaIU+DEstipcJYQQZc0g37pY0= github.com/ipfs/hang-fds v0.1.0 h1:deBiFlWHsVGzJ0ZMaqscEqRM1r2O1rFZ59UiQXb1Xko= @@ -692,19 +678,11 @@ github.com/ipfs/iptb v1.4.0/go.mod h1:1rzHpCYtNp87/+hTxG5TfCVn/yMY3dKnLn8tBiMfdm github.com/ipfs/iptb-plugins v0.3.0 h1:C1rpq1o5lUZtaAOkLIox5akh6ba4uk/3RwWc6ttVxw0= github.com/ipfs/iptb-plugins v0.3.0/go.mod h1:5QtOvckeIw4bY86gSH4fgh3p3gCSMn3FmIKr4gaBncA= github.com/ipld/go-car/v2 v2.1.1 h1:saaKz4nC0AdfCGHLYKeXLGn8ivoPC54fyS55uyOLKwA= -github.com/ipld/go-car/v2 v2.1.1/go.mod h1:+2Yvf0Z3wzkv7NeI69i8tuZ+ft7jyjPYIWZzeVNeFcI= -github.com/ipld/go-codec-dagpb v1.3.0/go.mod h1:ga4JTU3abYApDC3pZ00BC2RSvC3qfBb9MSJkMLSwnhA= -github.com/ipld/go-codec-dagpb v1.3.1/go.mod h1:ErNNglIi5KMur/MfFE/svtgQthzVvf+43MrzLbpcIZY= -github.com/ipld/go-codec-dagpb v1.4.0 h1:VqADPIFng8G4vz5EQytmmcx/2gEgOHfBuw/kIuCgDAY= -github.com/ipld/go-codec-dagpb v1.4.0/go.mod h1:ErNNglIi5KMur/MfFE/svtgQthzVvf+43MrzLbpcIZY= +github.com/ipld/go-codec-dagpb v1.5.0 h1:RspDRdsJpLfgCI0ONhTAnbHdySGD4t+LHSPK4X1+R0k= +github.com/ipld/go-codec-dagpb v1.5.0/go.mod h1:0yRIutEFD8o1DGVqw4RSHh+BUTlJA9XWldxaaWR/o4g= 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.14.0/go.mod h1:9ASQLwUFLptCov6lIYc70GRB4V7UTyLD0IJtrDJe6ZM= -github.com/ipld/go-ipld-prime v0.16.0/go.mod h1:axSCuOCBPqrH+gvXr2w9uAOulJqBPhHPT2PjoiiU1qA= -github.com/ipld/go-ipld-prime v0.17.0/go.mod h1:aYcKm5TIvGfY8P3QBKz/2gKcLxzJ1zDaD+o0bOowhgs= -github.com/ipld/go-ipld-prime v0.19.0 h1:5axC7rJmPc17Emw6TelxGwnzALk0PdupZ2oj2roDj04= -github.com/ipld/go-ipld-prime v0.19.0/go.mod h1:Q9j3BaVXwaA3o5JUDNvptDDr/x8+F7FG6XJ8WI3ILg4= -github.com/ipld/go-ipld-prime/storage/bsadapter v0.0.0-20211210234204-ce2a1c70cd73/go.mod h1:2PJ0JgxyB08t0b2WKrcuqI3di0V+5n6RS/LTUJhkoxY= +github.com/ipld/go-ipld-prime v0.20.0 h1:Ud3VwE9ClxpO2LkCYP7vWPc0Fo+dYdYzgxUJZ3uRG4g= +github.com/ipld/go-ipld-prime v0.20.0/go.mod h1:PzqZ/ZR981eKbgdr3y2DJYeD/8bgMawdGVlJDE8kK+M= 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= @@ -741,8 +719,10 @@ github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlT github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= @@ -762,21 +742,17 @@ github.com/kisielk/errcheck v1.6.2/go.mod h1:nXw/i/MfnvRHqXa7XXmQMUB0oNFGuBrNI8d github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= 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/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/compress v1.15.1 h1:y9FcTHGyrebwfP0ZZqFiaxTaiDnUrGkJkI+f583BL1A= -github.com/klauspost/compress v1.15.1/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.15.12 h1:YClS/PImqYbn+UILDnqxQCZ3RehC9N318SU3kElDUEM= +github.com/klauspost/compress v1.15.12/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= 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/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c= -github.com/klauspost/cpuid/v2 v2.1.0 h1:eyi1Ad2aNJMW95zcSbmGg7Cg6cq3ADwLpMAP96d8rF0= -github.com/klauspost/cpuid/v2 v2.1.0/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= +github.com/klauspost/cpuid/v2 v2.2.1 h1:U33DW0aiEj633gHYw3LoDNfkDiYnE5Q8M/TKJn2f2jI= +github.com/klauspost/cpuid/v2 v2.2.1/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/koron/go-ssdp v0.0.0-20180514024734-4a0ed625a78b/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk= github.com/koron/go-ssdp v0.0.0-20191105050749-2e1c40ed0b5d/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk= -github.com/koron/go-ssdp v0.0.2/go.mod h1:XoLfkAiA2KeZsYh4DbHxD7h3nR2AZNqVQOa+LJuqPYs= github.com/koron/go-ssdp v0.0.3 h1:JivLMY45N76b4p/vsWGOKewBQu6uf39y8l+AQ7sDKx8= github.com/koron/go-ssdp v0.0.3/go.mod h1:b2MxI6yh02pKrsyNoQUsk4+YNikaGhe4894J+Q5lDvA= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= @@ -784,8 +760,7 @@ github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFB github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= -github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= @@ -801,12 +776,13 @@ github.com/ldez/gomoddirectives v0.2.3 h1:y7MBaisZVDYmKvt9/l1mjNCiSA1BVn34U0ObUc github.com/ldez/gomoddirectives v0.2.3/go.mod h1:cpgBogWITnCfRq2qGoDkKMEVSaarhdBr6g8G04uz6d0= github.com/ldez/tagliatelle v0.3.1 h1:3BqVVlReVUZwafJUwQ+oxbx2BEX2vUG4Yu/NOfMiKiM= github.com/ldez/tagliatelle v0.3.1/go.mod h1:8s6WJQwEYHbKZDsp/LjArytKOG8qaMrKQQ3mFukHs88= +github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= +github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/leonklingele/grouper v1.1.0 h1:tC2y/ygPbMFSBOs3DcyaEMKnnwH7eYKzohOtRrf0SAg= github.com/leonklingele/grouper v1.1.0/go.mod h1:uk3I3uDfi9B6PeUjsCKi6ndcf63Uy7snXgR4yDYQVDY= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= 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/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/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM= github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= @@ -818,7 +794,6 @@ github.com/libp2p/go-conn-security-multistream v0.0.2/go.mod h1:nc9vud7inQ+d6SO0 github.com/libp2p/go-conn-security-multistream v0.1.0/go.mod h1:aw6eD7LOsHEX7+2hJkDxw1MteijaVcI+/eP2/x3J1xc= github.com/libp2p/go-conn-security-multistream v0.2.0/go.mod h1:hZN4MjlNetKD3Rq5Jb/P5ohUnFLNzEAR4DLSzpn2QLU= github.com/libp2p/go-conn-security-multistream v0.2.1/go.mod h1:cR1d8gA0Hr59Fj6NhaTpFhJZrjSYuNmhpT2r25zYR70= -github.com/libp2p/go-conn-security-multistream v0.3.0/go.mod h1:EEP47t4fw/bTelVmEzIDqSe69hO/ip52xBEhZMLWAHM= github.com/libp2p/go-eventbus v0.0.2/go.mod h1:Hr/yGlwxA/stuLnpMiu82lpNKpvRy3EaJxPu40XYOwk= github.com/libp2p/go-eventbus v0.1.0/go.mod h1:vROgu5cs5T7cv7POWlWxBaVLxfSegC5UGQf8A2eEmx4= github.com/libp2p/go-eventbus v0.2.1/go.mod h1:jc2S4SoEVPP48H9Wpzm5aiGwUCBMfGhVhhBjyhhCJs8= @@ -836,10 +811,8 @@ github.com/libp2p/go-libp2p v0.7.0/go.mod h1:hZJf8txWeCduQRDC/WSqBGMxaTHCOYHt2xS github.com/libp2p/go-libp2p v0.7.4/go.mod h1:oXsBlTLF1q7pxr+9w6lqzS1ILpyHsaBPniVO7zIHGMw= github.com/libp2p/go-libp2p v0.8.1/go.mod h1:QRNH9pwdbEBpx5DTJYg+qxcVaDMAz3Ee/qDKwXujH5o= github.com/libp2p/go-libp2p v0.14.3/go.mod h1:d12V4PdKbpL0T1/gsUNN8DfgMuRPDX8bS2QxCZlwRH0= -github.com/libp2p/go-libp2p v0.19.4/go.mod h1:MIt8y481VDhUe4ErWi1a4bvt/CjjFfOq6kZTothWIXY= -github.com/libp2p/go-libp2p v0.22.0 h1:2Tce0kHOp5zASFKJbNzRElvh0iZwdtG5uZheNW8chIw= -github.com/libp2p/go-libp2p v0.22.0/go.mod h1:UDolmweypBSjQb2f7xutPnwZ/fxioLbMBxSjRksxxU4= -github.com/libp2p/go-libp2p-asn-util v0.1.0/go.mod h1:wu+AnM9Ii2KgO5jMmS1rz9dvzTdj8BXqsPR9HR0XB7I= +github.com/libp2p/go-libp2p v0.26.4 h1:VA9ChjN0n1BwwfU/dqx4Zj9ezXtIxGk8FyJPwFONqxs= +github.com/libp2p/go-libp2p v0.26.4/go.mod h1:x75BN32YbwuY0Awm2Uix4d4KOz+/4piInkp4Wr3yOo8= github.com/libp2p/go-libp2p-asn-util v0.2.0 h1:rg3+Os8jbnO5DxkC7K/Utdi+DkY3q/d1/1q+8WeNAsw= github.com/libp2p/go-libp2p-asn-util v0.2.0/go.mod h1:WoaWxbHKBymSN41hWSq/lGKJEca7TNm58+gGJi2WsLI= github.com/libp2p/go-libp2p-autonat v0.0.6/go.mod h1:uZneLdOkZHro35xIhpbtTzLlgYturpu4J5+0cZK3MqE= @@ -855,7 +828,6 @@ github.com/libp2p/go-libp2p-blankhost v0.1.1/go.mod h1:pf2fvdLJPsC1FsVrNP3DUUvMz github.com/libp2p/go-libp2p-blankhost v0.1.3/go.mod h1:KML1//wiKR8vuuJO0y3LUd1uLv+tlkGTAr3jC0S5cLg= github.com/libp2p/go-libp2p-blankhost v0.1.4/go.mod h1:oJF0saYsAXQCSfDq254GMNmLNz6ZTHTOvtF4ZydUvwU= github.com/libp2p/go-libp2p-blankhost v0.2.0/go.mod h1:eduNKXGTioTuQAUcZ5epXi9vMl+t4d8ugUBRQ4SqaNQ= -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.1/go.mod h1:Ahq4cY3V9VJcHcn1SBXjr78AbFkZeIRmfunbA7pmFh8= @@ -863,7 +835,6 @@ github.com/libp2p/go-libp2p-circuit v0.1.3/go.mod h1:Xqh2TjSy8DD5iV2cCOMzdynd6h8 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/go.mod h1:t/ktoFIUzM6uLQ+o1G6NuBl2ANhBKN9Bc8jRIk31MoA= -github.com/libp2p/go-libp2p-circuit v0.6.0/go.mod h1:kB8hY+zCpMeScyvFrKrGicRdid6vNXbunKE4rXATZ0M= github.com/libp2p/go-libp2p-connmgr v0.1.1/go.mod h1:wZxh8veAmU5qdrfJ0ZBLcU8oJe9L82ciVP/fl1VHjXk= 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= @@ -880,7 +851,6 @@ github.com/libp2p/go-libp2p-core v0.4.0/go.mod h1:49XGI+kc38oGVwqSBhDEwytaAxgZas github.com/libp2p/go-libp2p-core v0.5.0/go.mod h1:49XGI+kc38oGVwqSBhDEwytaAxgZasHhFfQKibzTls0= github.com/libp2p/go-libp2p-core v0.5.1/go.mod h1:uN7L2D4EvPCvzSH5SrhR72UWbnSGpt5/a35Sm4upn4Y= github.com/libp2p/go-libp2p-core v0.5.2/go.mod h1:uN7L2D4EvPCvzSH5SrhR72UWbnSGpt5/a35Sm4upn4Y= -github.com/libp2p/go-libp2p-core v0.5.3/go.mod h1:uN7L2D4EvPCvzSH5SrhR72UWbnSGpt5/a35Sm4upn4Y= github.com/libp2p/go-libp2p-core v0.5.4/go.mod h1:uN7L2D4EvPCvzSH5SrhR72UWbnSGpt5/a35Sm4upn4Y= github.com/libp2p/go-libp2p-core v0.5.5/go.mod h1:vj3awlOr9+GMZJFH9s4mpt9RHHgGqeHCopzbYKZdRjM= github.com/libp2p/go-libp2p-core v0.5.6/go.mod h1:txwbVEhHEXikXn9gfC7/UDDw7rkxuX0bJvM49Ykaswo= @@ -892,12 +862,6 @@ github.com/libp2p/go-libp2p-core v0.8.0/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJB github.com/libp2p/go-libp2p-core v0.8.1/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= github.com/libp2p/go-libp2p-core v0.8.2/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= github.com/libp2p/go-libp2p-core v0.8.5/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= -github.com/libp2p/go-libp2p-core v0.8.6/go.mod h1:dgHr0l0hIKfWpGpqAMbpo19pen9wJfdCGv51mTmdpmM= -github.com/libp2p/go-libp2p-core v0.10.0/go.mod h1:ECdxehoYosLYHgDDFa2N4yE8Y7aQRAMf0sX9mf2sbGg= -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.14.0/go.mod h1:tLasfcVdTXnixsLB0QYaT1syJOhsbrhG7q6pGrHtBg8= -github.com/libp2p/go-libp2p-core v0.15.1/go.mod h1:agSaboYM4hzB1cWekgVReqV5M4g5M+2eNNejV+1EEhs= github.com/libp2p/go-libp2p-core v0.20.1 h1:fQz4BJyIFmSZAiTbKV8qoYhEH5Dtv/cVhZbG3Ib/+Cw= github.com/libp2p/go-libp2p-core v0.20.1/go.mod h1:6zR8H7CvQWgYLsbG4on6oLNSGcyKaYFSEYyDt51+bIY= github.com/libp2p/go-libp2p-crypto v0.0.1/go.mod h1:yJkNyDmO341d5wwXxDUGO0LykUVT72ImHNUqh5D/dBE= @@ -928,18 +892,15 @@ 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.4.0/go.mod h1:yCyWJE2sc6TBTnFpjvLuEJgTSw/u+MamvzILKdX7asw= 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-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= -github.com/libp2p/go-libp2p-nat v0.1.0/go.mod h1:DQzAG+QbDYjN1/C3B6vXucLtz3u9rEonLVPtZVzQqks= github.com/libp2p/go-libp2p-net v0.0.1/go.mod h1:Yt3zgmlsHOgUWSXmt5V/Jpz9upuJBE8EgNU9DrCcR8c= github.com/libp2p/go-libp2p-net v0.0.2/go.mod h1:Yt3zgmlsHOgUWSXmt5V/Jpz9upuJBE8EgNU9DrCcR8c= github.com/libp2p/go-libp2p-netutil v0.0.1/go.mod h1:GdusFvujWZI9Vt0X5BKqwWWmZFxecf9Gt03cKxm2f/Q= github.com/libp2p/go-libp2p-netutil v0.1.0 h1:zscYDNVEcGxyUpMd0JReUZTrpMfia8PmLKcKF72EAMQ= github.com/libp2p/go-libp2p-netutil v0.1.0/go.mod h1:3Qv/aDqtMLTUyQeundkKsA+YCThNdbQD54k3TqjpbFU= github.com/libp2p/go-libp2p-noise v0.2.0/go.mod h1:IEbYhBBzGyvdLBoxxULL/SGbJARhUeqlO8lVSREYu2Q= -github.com/libp2p/go-libp2p-noise v0.4.0/go.mod h1:BzzY5pyzCYSyJbQy9oD8z5oP2idsafjt4/X42h9DjZU= github.com/libp2p/go-libp2p-peer v0.0.1/go.mod h1:nXQvOBbwVqoP+T5Y5nCjeH4sP9IX/J0AMzcDUVruVoo= github.com/libp2p/go-libp2p-peer v0.1.1/go.mod h1:jkF12jGB4Gk/IOo+yomm+7oLWxF278F7UnrYUQ1Q8es= github.com/libp2p/go-libp2p-peer v0.2.0/go.mod h1:RCffaCvUyW2CJmG2gAWVqwePwW7JMgxjsHm7+J5kjWY= @@ -952,23 +913,16 @@ github.com/libp2p/go-libp2p-peerstore v0.2.1/go.mod h1:NQxhNjWxf1d4w6PihR8btWIRj github.com/libp2p/go-libp2p-peerstore v0.2.2/go.mod h1:NQxhNjWxf1d4w6PihR8btWIRjwRLBr4TYKfNgrUkOPA= 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.4.0/go.mod h1:rDJUFyzEWPpXpEwywkcTYYzDHlwza8riYMaUzaN6hX0= -github.com/libp2p/go-libp2p-peerstore v0.6.0/go.mod h1:DGEmKdXrcYpK9Jha3sS7MhqYdInxJy84bIPtSu65bKc= 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= github.com/libp2p/go-libp2p-protocol v0.1.0/go.mod h1:KQPHpAabB57XQxGrXCNvbL6UEXfQqUgC/1adR2Xtflk= github.com/libp2p/go-libp2p-pubsub v0.1.1/go.mod h1:ZwlKzRSe1eGvSIdU5bD7+8RZN/Uzw0t1Bp9R1znpR/Q= github.com/libp2p/go-libp2p-quic-transport v0.1.1/go.mod h1:wqG/jzhF3Pu2NrhJEvE+IE0NTHNXslOPn9JQzyCAxzU= github.com/libp2p/go-libp2p-quic-transport v0.10.0/go.mod h1:RfJbZ8IqXIhxBRm5hqUEJqjiiY8xmEuq3HUDS993MkA= -github.com/libp2p/go-libp2p-quic-transport v0.13.0/go.mod h1:39/ZWJ1TW/jx1iFkKzzUg00W6tDJh73FC0xYudjr7Hc= -github.com/libp2p/go-libp2p-quic-transport v0.16.0/go.mod h1:1BXjVMzr+w7EkPfiHkKnwsWjPjtfaNT0q8RS3tGDvEQ= -github.com/libp2p/go-libp2p-quic-transport v0.17.0/go.mod h1:x4pw61P3/GRCcSLypcQJE/Q2+E9f4X+5aRcZLXf20LM= 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.1/go.mod h1:VRgKajOyMVgP/F0L5g3kH7SVskp17vFi2xheb5uMJtg= -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.2.1/go.mod h1:K+eCkiapf+ey/LADO4TaMpMTP9/Qde/uLlrnRqV4PLQ= +github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= github.com/libp2p/go-libp2p-routing v0.0.1/go.mod h1:N51q3yTr4Zdr7V8Jt2JIktVU+3xBBylx1MZeVA6t1Ys= github.com/libp2p/go-libp2p-routing v0.1.0/go.mod h1:zfLhI1RI8RLEzmEaaPwzonRvXeeSHddONWkcTcB54nE= github.com/libp2p/go-libp2p-secio v0.0.3/go.mod h1:hS7HQ00MgLhRO/Wyu1bTX6ctJKhVpm+j2/S2A5UqYb0= @@ -984,9 +938,6 @@ github.com/libp2p/go-libp2p-swarm v0.2.3/go.mod h1:P2VO/EpxRyDxtChXz/VPVXyTnszHv github.com/libp2p/go-libp2p-swarm v0.2.8/go.mod h1:JQKMGSth4SMqonruY0a8yjlPVIkb0mdNSwckW7OYziM= github.com/libp2p/go-libp2p-swarm v0.3.0/go.mod h1:hdv95GWCTmzkgeJpP+GK/9D9puJegb7H57B5hWQR5Kk= github.com/libp2p/go-libp2p-swarm v0.5.0/go.mod h1:sU9i6BoHE0Ve5SKz3y9WfKrh8dUat6JknzUehFx8xW4= -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/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= @@ -996,14 +947,8 @@ github.com/libp2p/go-libp2p-testing v0.1.1/go.mod h1:xaZWMJrPUM5GlDBxCeGUi7kI4eq github.com/libp2p/go-libp2p-testing v0.1.2-0.20200422005655-8775583591d8/go.mod h1:Qy8sAncLKpwXtS2dSnDOP8ktexIAHKu+J+pnZOFZLTc= 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.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.9.0/go.mod h1:Td7kbdkWqYTJYQGTwzlgXwaqldraIanyjuRiAbK/XQU= -github.com/libp2p/go-libp2p-testing v0.9.2/go.mod h1:Td7kbdkWqYTJYQGTwzlgXwaqldraIanyjuRiAbK/XQU= -github.com/libp2p/go-libp2p-testing v0.11.0 h1:+R7FRl/U3Y00neyBSM2qgDzqz3HkWH24U9nMlascHL4= +github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA= 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.4.1/go.mod h1:EKCixHEysLNDlLUoKxv+3f/Lp90O2EXNjTr0UQDnrIw= github.com/libp2p/go-libp2p-transport v0.0.1/go.mod h1:UzbUs9X+PHOSw7S3ZmeOxfnwaQY5vGDzZmKPod3N3tk= github.com/libp2p/go-libp2p-transport v0.0.5/go.mod h1:StoY3sx6IqsP6XKoabsPnHCwqKXWUMWU7Rfcsubee/A= github.com/libp2p/go-libp2p-transport-upgrader v0.0.4/go.mod h1:RGq+tupk+oj7PzL2kn/m1w6YXxcIAYJYeI90h6BGgUc= @@ -1011,9 +956,6 @@ github.com/libp2p/go-libp2p-transport-upgrader v0.1.1/go.mod h1:IEtA6or8JUbsV07q github.com/libp2p/go-libp2p-transport-upgrader v0.2.0/go.mod h1:mQcrHj4asu6ArfSoMuyojOdjx73Q47cYD7s5+gZOlns= github.com/libp2p/go-libp2p-transport-upgrader v0.3.0/go.mod h1:i+SKzbRnvXdVbU3D1dwydnTmKRPXiAR/fyvi1dXuL4o= github.com/libp2p/go-libp2p-transport-upgrader v0.4.2/go.mod h1:NR8ne1VwfreD5VIWIU62Agt/J18ekORFU/j1i2y8zvk= -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/go.mod h1:GIR2aTRp1J5yjVlkUoFqMkdobfob6RnAwYg/RZPhrzg= github.com/libp2p/go-libp2p-yamux v0.1.2/go.mod h1:xUoV/RmYkg6BW/qGxA9XJyg+HzXFYkeXbnhjmnYzKp8= github.com/libp2p/go-libp2p-yamux v0.1.3/go.mod h1:VGSQVrqkh6y4nm0189qqxMtvyBft44MOYYPpYKXiVt4= github.com/libp2p/go-libp2p-yamux v0.2.0/go.mod h1:Db2gU+XfLpm6E4rG5uGCFX6uXA8MEXOxFcRoXUODaK8= @@ -1025,9 +967,6 @@ github.com/libp2p/go-libp2p-yamux v0.2.8/go.mod h1:/t6tDqeuZf0INZMTgd0WxIRbtK2Ez github.com/libp2p/go-libp2p-yamux v0.4.0/go.mod h1:+DWDjtFMzoAwYLVkNZftoucn7PelNoy5nm3tZ3/Zw30= github.com/libp2p/go-libp2p-yamux v0.5.0/go.mod h1:AyR8k5EzyM2QN9Bbdg6X1SkVVuqLwTGf0L4DFq9g6po= github.com/libp2p/go-libp2p-yamux v0.5.4/go.mod h1:tfrXbyaTqqSU654GTvK3ocnSZL3BuHoeTSqhcel1wsE= -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.9.1/go.mod h1:wRc6wvyxQINFcKe7daL4BeQ02Iyp+wxyC8WCNfngBrA= 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= @@ -1039,13 +978,12 @@ github.com/libp2p/go-mplex v0.1.1/go.mod h1:Xgz2RDCi3co0LeZfgjm4OgUF15+sVR8SRcu3 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/go.mod h1:0Oy/A9PQlwBytDRp4wSkFnzHYDKcpLot35JQ6msjvYQ= -github.com/libp2p/go-mplex v0.4.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= github.com/libp2p/go-msgio v0.0.6/go.mod h1:4ecVB6d9f4BDSL5fqvPiC4A3KivjWn+Venn/1ALLMWA= -github.com/libp2p/go-msgio v0.2.0 h1:W6shmB+FeynDrUVl2dgFQvzfBZcXiyqY4VmpQLu9FqU= -github.com/libp2p/go-msgio v0.2.0/go.mod h1:dBVM1gW3Jk9XqHkU4eKdGvVHdLa51hoGfll6jMJMSlY= +github.com/libp2p/go-msgio v0.3.0 h1:mf3Z8B1xcFN314sWX+2vOTShIE0Mmn2TXn3YCUQGNj0= +github.com/libp2p/go-msgio v0.3.0/go.mod h1:nyRM819GmVaF9LX3l03RMh10QdOroF++NBbxAb0mmDM= github.com/libp2p/go-nat v0.0.3/go.mod h1:88nUEt0k0JD45Bk93NIwDqjlhiOwOoV36GchpcVc1yI= github.com/libp2p/go-nat v0.0.4/go.mod h1:Nmw50VAvKuk38jUBcmNh6p9lUJLoODbJRvYAa/+KSDo= github.com/libp2p/go-nat v0.0.5/go.mod h1:B7NxsVNPZmRLvMOwiEO1scOSyjA56zxYAGv1yQgRkEU= @@ -1055,24 +993,20 @@ github.com/libp2p/go-netroute v0.1.2/go.mod h1:jZLDV+1PE8y5XxBySEBgbuVAXbhtuHSdm 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/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-netroute v0.2.1 h1:V8kVrpD8GK0Riv15/7VN6RbUQ3URNZVosw7H2v9tksU= +github.com/libp2p/go-netroute v0.2.1/go.mod h1:hraioZr0fhBjG0ZRXJJ6Zj2IVEVNx6tDTFQfSmcq7mQ= 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= github.com/libp2p/go-openssl v0.0.5/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= github.com/libp2p/go-openssl v0.0.7/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= -github.com/libp2p/go-openssl v0.1.0 h1:LBkKEcUv6vtZIQLVTegAil8jbNpJErQ9AnT+bWV+Ooo= -github.com/libp2p/go-openssl v0.1.0/go.mod h1:OiOxwPpL3n4xlenjx2h7AwSGaFSC/KZvf6gNdOBQMtc= github.com/libp2p/go-reuseport v0.0.1/go.mod h1:jn6RmB1ufnQwl0Q1f+YxAj8isJgDCQzaaxIFYDhcYEA= github.com/libp2p/go-reuseport v0.0.2/go.mod h1:SPD+5RwGC7rcnzngoYC86GjPzjSywuQyMVAheVBD9nQ= -github.com/libp2p/go-reuseport v0.1.0/go.mod h1:bQVn9hmfcTaoo0c9v5pBhOarsU1eNOBZdaAd2hzXRKU= github.com/libp2p/go-reuseport v0.2.0 h1:18PRvIMlpY6ZK85nIAicSBuXXvrYoSw3dsBAR7zc560= github.com/libp2p/go-reuseport v0.2.0/go.mod h1:bvVho6eLMm6Bz5hmU0LYN3ixd3nPPvtIlaURZZgOY4k= github.com/libp2p/go-reuseport-transport v0.0.2/go.mod h1:YkbSDrvjUVDL6b8XqriyA20obEtsW9BLkuOUyQAOCbs= github.com/libp2p/go-reuseport-transport v0.0.3/go.mod h1:Spv+MPft1exxARzP2Sruj2Wb5JSyHNncjf1Oi2dEbzM= github.com/libp2p/go-reuseport-transport v0.0.4/go.mod h1:trPa7r/7TJK/d+0hdBLOCGvpQQVOU74OXbNCIMkufGw= -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/go.mod h1:syPvOmNs24S3dFVGJA1/mrqdeijPxLV2Le3BRLKd68k= @@ -1081,15 +1015,11 @@ github.com/libp2p/go-stream-muxer v0.1.0/go.mod h1:8JAVsjeRBCWwPoZeH0W1imLOcriqX 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/go.mod h1:yDh8abSIzmZtqtOt64gFJUXEryejzNb0lisTt+fAMJA= -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= github.com/libp2p/go-tcp-transport v0.2.0/go.mod h1:vX2U0CnWimU4h0SGSEsg++AzvBcroCGYw28kh94oLe0= github.com/libp2p/go-tcp-transport v0.2.3/go.mod h1:9dvr03yqrPyYGIEN6Dy5UvdJZjyPFvl1S/igQ5QD1SU= -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/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= @@ -1098,7 +1028,6 @@ github.com/libp2p/go-ws-transport v0.1.2/go.mod h1:dsh2Ld8F+XNmzpkaAijmg5Is+e9l6 github.com/libp2p/go-ws-transport v0.2.0/go.mod h1:9BHJz/4Q5A9ludYWKoGCFC5gUElzlHoKzu0yY9p/klM= github.com/libp2p/go-ws-transport v0.3.0/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.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= @@ -1109,22 +1038,12 @@ github.com/libp2p/go-yamux v1.3.7/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/h github.com/libp2p/go-yamux v1.4.0/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/hkmpooHE= github.com/libp2p/go-yamux v1.4.1/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/hkmpooHE= github.com/libp2p/go-yamux/v2 v2.2.0/go.mod h1:3So6P6TV6r75R9jiBpiIKgU/66lOarCZjqROGxzPpPQ= -github.com/libp2p/go-yamux/v3 v3.0.1/go.mod h1:s2LsDhHbh+RfCsQoICSYt58U2f8ijtPANFD8BmE74Bo= -github.com/libp2p/go-yamux/v3 v3.0.2/go.mod h1:s2LsDhHbh+RfCsQoICSYt58U2f8ijtPANFD8BmE74Bo= -github.com/libp2p/go-yamux/v3 v3.1.1/go.mod h1:jeLEQgLXqE2YqX1ilAClIfCMDY+0uXQUKmmb/qp0gT4= -github.com/libp2p/go-yamux/v3 v3.1.2 h1:lNEy28MBk1HavUAlzKgShp+F6mn/ea1nDYWftZhFW9Q= -github.com/libp2p/go-yamux/v3 v3.1.2/go.mod h1:jeLEQgLXqE2YqX1ilAClIfCMDY+0uXQUKmmb/qp0gT4= -github.com/libp2p/zeroconf/v2 v2.1.1/go.mod h1:fuJqLnUwZTshS3U/bMRJ3+ow/v9oid1n0DmyYyNO1Xs= +github.com/libp2p/go-yamux/v4 v4.0.0 h1:+Y80dV2Yx/kv7Y7JKu0LECyVdMXm1VUoko+VQ9rBfZQ= +github.com/libp2p/go-yamux/v4 v4.0.0/go.mod h1:NWjl8ZTLOGlozrXSOZ/HlfG++39iKNnM5wwmtQP1YB4= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= github.com/lucas-clemente/quic-go v0.11.2/go.mod h1:PpMmPfPKO9nKJ/psF49ESTAGQSdfXxlg1otPbEB2nOw= github.com/lucas-clemente/quic-go v0.19.3/go.mod h1:ADXpNbTQjq1hIzCpB+y/k5iz4n4z4IwqoLb94Kh5Hu8= -github.com/lucas-clemente/quic-go v0.23.0/go.mod h1:paZuzjXCE5mj6sikVLMvqXk8lJV2AsqtJ6bDhjEfxx0= -github.com/lucas-clemente/quic-go v0.25.0/go.mod h1:YtzP8bxRVCBlO77yRanE264+fY/T2U9ZlW1AaHOsMOg= -github.com/lucas-clemente/quic-go v0.27.0/go.mod h1:AzgQoPda7N+3IqMMMkywBKggIFo2KT6pfnlrQ2QieeI= -github.com/lucas-clemente/quic-go v0.27.1/go.mod h1:AzgQoPda7N+3IqMMMkywBKggIFo2KT6pfnlrQ2QieeI= -github.com/lucas-clemente/quic-go v0.28.1 h1:Uo0lvVxWg5la9gflIF9lwa39ONq85Xq2D91YNEIslzU= -github.com/lucas-clemente/quic-go v0.28.1/go.mod h1:oGz5DKK41cJt5+773+BSO9BXDsREY4HLf7+0odGAPO0= github.com/lufeee/execinquery v1.2.1 h1:hf0Ems4SHcUGBxpGN7Jz78z1ppVkP/837ZlETPCEtOM= github.com/lufeee/execinquery v1.2.1/go.mod h1:EC7DrEKView09ocscGHC+apXMIaorh4xqSxS/dy8SbM= github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= @@ -1140,21 +1059,6 @@ github.com/marten-seemann/qpack v0.2.1/go.mod h1:F7Gl5L1jIgN1D11ucXefiuJS9UMVP2o github.com/marten-seemann/qtls v0.2.3/go.mod h1:xzjG7avBwGGbdZ8dTGxlBnLArsVKLvwmjgmPuiQEcYk= github.com/marten-seemann/qtls v0.10.0/go.mod h1:UvMd1oaYDACI99/oZUYLzMCkBXQVT0aGm99sJhbT8hs= github.com/marten-seemann/qtls-go1-15 v0.1.1/go.mod h1:GyFwywLKkRt+6mfU99csTEY1joMZz5vmB1WNZH3P81I= -github.com/marten-seemann/qtls-go1-15 v0.1.4/go.mod h1:GyFwywLKkRt+6mfU99csTEY1joMZz5vmB1WNZH3P81I= -github.com/marten-seemann/qtls-go1-16 v0.1.4/go.mod h1:gNpI2Ol+lRS3WwSOtIUUtRwZEQMXjYK+dQSBFbethAk= -github.com/marten-seemann/qtls-go1-16 v0.1.5 h1:o9JrYPPco/Nukd/HpOHMHZoBDXQqoNtUCmny98/1uqQ= -github.com/marten-seemann/qtls-go1-16 v0.1.5/go.mod h1:gNpI2Ol+lRS3WwSOtIUUtRwZEQMXjYK+dQSBFbethAk= -github.com/marten-seemann/qtls-go1-17 v0.1.0/go.mod h1:fz4HIxByo+LlWcreM4CZOYNuz3taBQ8rN2X6FqvaWo8= -github.com/marten-seemann/qtls-go1-17 v0.1.1/go.mod h1:C2ekUKcDdz9SDWxec1N/MvcXBpaX9l3Nx67XaR84L5s= -github.com/marten-seemann/qtls-go1-17 v0.1.2 h1:JADBlm0LYiVbuSySCHeY863dNkcpMmDR7s0bLKJeYlQ= -github.com/marten-seemann/qtls-go1-17 v0.1.2/go.mod h1:C2ekUKcDdz9SDWxec1N/MvcXBpaX9l3Nx67XaR84L5s= -github.com/marten-seemann/qtls-go1-18 v0.1.0-beta.1/go.mod h1:PUhIQk19LoFt2174H4+an8TYvWOGjb/hHwphBeaDHwI= -github.com/marten-seemann/qtls-go1-18 v0.1.1/go.mod h1:mJttiymBAByA49mhlNZZGrH5u1uXYZJ+RW28Py7f4m4= -github.com/marten-seemann/qtls-go1-18 v0.1.2 h1:JH6jmzbduz0ITVQ7ShevK10Av5+jBEKAHMntXmIV7kM= -github.com/marten-seemann/qtls-go1-18 v0.1.2/go.mod h1:mJttiymBAByA49mhlNZZGrH5u1uXYZJ+RW28Py7f4m4= -github.com/marten-seemann/qtls-go1-19 v0.1.0-beta.1/go.mod h1:5HTDWtVudo/WFsHKRNuOhWlbdjrfs5JHrYb0wIJqGpI= -github.com/marten-seemann/qtls-go1-19 v0.1.0 h1:rLFKD/9mp/uq1SYGYuVZhm83wkmU95pK5df3GufyYYU= -github.com/marten-seemann/qtls-go1-19 v0.1.0/go.mod h1:5HTDWtVudo/WFsHKRNuOhWlbdjrfs5JHrYb0wIJqGpI= 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/matoous/godox v0.0.0-20210227103229-6504466cf951 h1:pWxk9e//NbPwfxat7RXkts09K+dEBJWakUWwICVqYbA= @@ -1176,14 +1080,13 @@ github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Ky github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-pointer v0.0.1 h1:n+XhsuGeVO6MEAp7xyEukFINEa+Quek5psIR/ylA6o0= -github.com/mattn/go-pointer v0.0.1/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= -github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= +github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/mbilski/exhaustivestruct v1.2.0 h1:wCBmUnSYufAHO6J4AVWY6ff+oxWxsVFrwgOdMUQePUo= github.com/mbilski/exhaustivestruct v1.2.0/go.mod h1:OeTBVxQWoEmB2J2JCHmXWPJ0aksxSUOUy+nvtVEfzXc= github.com/mgechev/revive v1.2.3 h1:NzIEEa9+WimQ6q2Ov7OcNeySS/IOcwtkQ8RAh0R5UJ4= @@ -1194,8 +1097,6 @@ github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3N github.com/miekg/dns v1.1.12/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.28/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= -github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= -github.com/miekg/dns v1.1.48/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA= github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c h1:bzE/A84HN25pxAuk9Eej1Kz9OUelF97nAc82bDquQI8= @@ -1224,9 +1125,11 @@ github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/moricho/tparallel v0.2.1 h1:95FytivzT6rYzdJLdtfn6m1bfFJylOJK41+lgv/EHf4= github.com/moricho/tparallel v0.2.1/go.mod h1:fXEIZxG2vdfl0ZF8b42f5a78EhjjD5mX8qUplsoSU4k= @@ -1237,10 +1140,11 @@ github.com/mr-tron/base58 v1.1.3/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjW github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= -github.com/multiformats/go-base32 v0.0.4 h1:+qMh4a2f37b4xTNs6mqitDinryCI+tfO2dRVMN9mjSE= -github.com/multiformats/go-base32 v0.0.4/go.mod h1:jNLFzjPZtp3aIARHbJRZIaPuspdH0J6q39uUM5pnABM= -github.com/multiformats/go-base36 v0.1.0 h1:JR6TyF7JjGd3m6FbLU2cOxhC0Li8z8dLNGQ89tUg4F4= +github.com/multiformats/go-base32 v0.1.0 h1:pVx9xoSPqEIQG8o+UbAe7DNi51oej1NtK+aGkbLYxPE= +github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYgtWibDcT0rExnbI= github.com/multiformats/go-base36 v0.1.0/go.mod h1:kFGE83c6s80PklsHO9sRn2NCoffoRdUUOENyW/Vv6sM= +github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0= +github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4= github.com/multiformats/go-multiaddr v0.0.1/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= github.com/multiformats/go-multiaddr v0.0.2/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= github.com/multiformats/go-multiaddr v0.0.4/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= @@ -1252,11 +1156,8 @@ github.com/multiformats/go-multiaddr v0.2.2/go.mod h1:NtfXiOtHvghW9KojvtySjH5y0u github.com/multiformats/go-multiaddr v0.3.0/go.mod h1:dF9kph9wfJ+3VLAaeBqo9Of8x4fJxp6ggJGteB8HQTI= 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/go.mod h1:3afI9HfVW8csiF8UZqtpYRiDyew8pRX7qLIGHu9FLuM= -github.com/multiformats/go-multiaddr v0.5.0/go.mod h1:3KAxNkUqLTJ20AAwN4XVX4kZar+bR+gh4zgbfr3SNug= -github.com/multiformats/go-multiaddr v0.6.0 h1:qMnoOPj2s8xxPU5kZ57Cqdr0hHhARz7mFsPMIiYNqzg= -github.com/multiformats/go-multiaddr v0.6.0/go.mod h1:F4IpaKZuPP360tOMn2Tpyu0At8w23aRyVqeK0DbFeGM= +github.com/multiformats/go-multiaddr v0.8.0 h1:aqjksEcqK+iD/Foe1RRFsGZh8+XFiGo7FgUCZlpv3LU= +github.com/multiformats/go-multiaddr v0.8.0/go.mod h1:Fs50eBDWvZu+l3/9S6xAE7ZYj6yhxlvaVZjakWN7xRs= 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.0.3/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= @@ -1279,13 +1180,8 @@ github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/g github.com/multiformats/go-multibase v0.0.3/go.mod h1:5+1R4eQrT3PkYZ24C3W2Ue2tPwIdYQD509ZjSb5y9Oc= github.com/multiformats/go-multibase v0.1.1 h1:3ASCDsuLX8+j4kx58qnJ4YFq/JWTJpCyDW27ztsVTOI= github.com/multiformats/go-multibase v0.1.1/go.mod h1:ZEjHE+IsUrgp5mhlEAYjMtZwK1k4haNkcaPg9aoe1a8= -github.com/multiformats/go-multicodec v0.3.0/go.mod h1:qGGaQmioCDh+TeFOnxrbU0DaIPw8yFgAZgFG0V7p1qQ= -github.com/multiformats/go-multicodec v0.3.1-0.20210902112759-1539a079fd61/go.mod h1:1Hj/eHRaVWSXiSNNfcEPcwZleTmdNP81xlxDLnWU9GQ= -github.com/multiformats/go-multicodec v0.3.1-0.20211210143421-a526f306ed2c/go.mod h1:1Hj/eHRaVWSXiSNNfcEPcwZleTmdNP81xlxDLnWU9GQ= -github.com/multiformats/go-multicodec v0.4.1/go.mod h1:1Hj/eHRaVWSXiSNNfcEPcwZleTmdNP81xlxDLnWU9GQ= -github.com/multiformats/go-multicodec v0.5.0/go.mod h1:DiY2HFaEp5EhEXb/iYzVAunmyX/aSFMxq2KMKfWEues= -github.com/multiformats/go-multicodec v0.6.0 h1:KhH2kSuCARyuJraYMFxrNO3DqIaYhOdS039kbhgVwpE= -github.com/multiformats/go-multicodec v0.6.0/go.mod h1:GUC8upxSBE4oG+q3kWZRw/+6yC1BqO550bjhWsJbZlw= +github.com/multiformats/go-multicodec v0.8.0 h1:evBmgkbSQux+Ds2IgfhkO38Dl2GDtRW8/Rp6YiSHX/Q= +github.com/multiformats/go-multicodec v0.8.0/go.mod h1:GUC8upxSBE4oG+q3kWZRw/+6yC1BqO550bjhWsJbZlw= github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= github.com/multiformats/go-multihash v0.0.5/go.mod h1:lt/HCbqlQwlPBz7lv0sQCdtfcMtlJvakRUn/0Ual8po= github.com/multiformats/go-multihash v0.0.8/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= @@ -1293,7 +1189,6 @@ github.com/multiformats/go-multihash v0.0.10/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpK github.com/multiformats/go-multihash v0.0.13/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= github.com/multiformats/go-multihash v0.0.14/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= github.com/multiformats/go-multihash v0.0.15/go.mod h1:D6aZrWNLFTV/ynMpKsNtB40mJzmCl4jb1alC0OvHiHg= -github.com/multiformats/go-multihash v0.1.0/go.mod h1:RJlXsxt6vHGaia+S8We0ErjhojtKzPP2AH4+kYM7k84= github.com/multiformats/go-multihash v0.2.1 h1:aem8ZT0VA2nCHHk7bPJ1BjUbHNciqZC/d16Vve9l108= github.com/multiformats/go-multihash v0.2.1/go.mod h1:WxoMcYG85AZVQUyRyo9s4wULvW5qrI9vb2Lt6evduFc= github.com/multiformats/go-multistream v0.0.1/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg= @@ -1302,14 +1197,14 @@ github.com/multiformats/go-multistream v0.1.0/go.mod h1:fJTiDfXJVmItycydCnNx4+wS github.com/multiformats/go-multistream v0.1.1/go.mod h1:KmHZ40hzVxiaiwlj3MEbYgK9JFk2/9UktWZAF54Du38= github.com/multiformats/go-multistream v0.2.1/go.mod h1:5GZPQZbkWOLOn3J2y4Y99vVW7vOfsAflxARk3x14o6k= github.com/multiformats/go-multistream v0.2.2/go.mod h1:UIcnm7Zuo8HKG+HkWgfQsGL+/MIEhyTqbODbIUwSXKs= -github.com/multiformats/go-multistream v0.3.0/go.mod h1:ODRoqamLUsETKS9BNcII4gcRsJBU5VAwRIv7O39cEXg= -github.com/multiformats/go-multistream v0.3.3 h1:d5PZpjwRgVlbwfdTDjife7XszfZd8KYWfROYFlGcR8o= -github.com/multiformats/go-multistream v0.3.3/go.mod h1:ODRoqamLUsETKS9BNcII4gcRsJBU5VAwRIv7O39cEXg= +github.com/multiformats/go-multistream v0.4.1 h1:rFy0Iiyn3YT0asivDUIR05leAdwZq3de4741sbiSdfo= +github.com/multiformats/go-multistream v0.4.1/go.mod h1:Mz5eykRVAjJWckE2U78c6xqdtyNUEhKSM0Lwar2p77Q= github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/multiformats/go-varint v0.0.2/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= -github.com/multiformats/go-varint v0.0.6 h1:gk85QWKxh3TazbLxED/NlDVv8+q+ReFJk7Y2W/KhfNY= github.com/multiformats/go-varint v0.0.6/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= +github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8= +github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/nakabonne/nestif v0.3.1 h1:wm28nZjhQY5HyYPx+weN3Q65k6ilSBxDb8v5S81B81U= @@ -1331,8 +1226,6 @@ github.com/nishanths/exhaustive v0.8.1/go.mod h1:qj+zJJUgJ76tR92+25+03oYUhzF4R7/ github.com/nishanths/predeclared v0.2.2 h1:V2EPdZPliZymNAn79T8RkNApBjMmVKh5XRpLm/w98Vk= github.com/nishanths/predeclared v0.2.2/go.mod h1:RROzoN6TnGQupbC+lqggsOlcgysk3LMK/HI84Mp280c= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= -github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= -github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= @@ -1344,19 +1237,15 @@ github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= -github.com/onsi/ginkgo v1.16.2/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E= -github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= -github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= -github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.1.4 h1:GNapqRSid3zijZ9H77KrgVG4/8KqiyRsxcSxe+7ApXY= +github.com/onsi/ginkgo/v2 v2.5.1 h1:auzK7OI497k6x4OvWq+TKAcpcSAlod0doAH72oIN0Jw= +github.com/onsi/ginkgo/v2 v2.5.1/go.mod h1:63DOGlLAH8+REH8jUGdL3YpCpu7JODesutUjdENfUAc= github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.13.0/go.mod h1:lRk9szgn8TxENtWd0Tp4c3wjlRfMTMH27I+3Je41yGY= -github.com/onsi/gomega v1.20.0 h1:8W0cWlwFkflGPLltQvLRB7ZVD5HuP6ng320w2IS245Q= +github.com/onsi/gomega v1.24.0 h1:+0glovB9Jd6z3VR+ScSwQqXVTIfJcGA9UBM8yzQxhqg= 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= @@ -1389,7 +1278,6 @@ github.com/pelletier/go-toml/v2 v2.0.2 h1:+jQXlF3scKIcSEKkdHzXhCTDLPFi5r1wnK6yPS github.com/pelletier/go-toml/v2 v2.0.2/go.mod h1:MovirKjgVRESsAvNZlAjtFwV867yGuwRkXbG66OzopI= github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 h1:1/WtZae0yGtPq+TI6+Tv1WTxkukpXeMlviSxvL7SRgk= -github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9/go.mod h1:x3N5drFsm2uilKKuuYo6LdyD8vZAW55sH/9w+pbo1sw= github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d h1:CdDQnGF8Nq9ocOS/xlSptM1N3BbrA6/kmaep5ggwaIA= github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d/go.mod h1:3OzsM7FXDQlpCiw2j81fOmAwQLnZnLGXVKUzeKQXIAw= github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= @@ -1417,29 +1305,28 @@ github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5Fsn github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.9.0/go.mod h1:FqZLKOZnGdFAhOK4nqGHa7D66IdsO+O441Eve7ptJDU= github.com/prometheus/client_golang v1.10.0/go.mod h1:WJM3cc3yu7XKBKa/I8WeZm+V3eltZnBwfENSU7mdogU= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -github.com/prometheus/client_golang v1.12.1 h1:ZiaPsmm9uiBeaSMRznKsCDNtPCS0T3JVDGF+06gjBzk= github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= +github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw= +github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= +github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= -github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= github.com/prometheus/common v0.18.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= -github.com/prometheus/common v0.33.0/go.mod h1:gB3sOl7P0TvJabZpLY5uQMpUqRCPPCyRLCZYc7JZTNE= github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE= github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= @@ -1449,7 +1336,6 @@ github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsT github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo= @@ -1467,18 +1353,22 @@ github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95 h1:L8QM9bvf github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95/go.mod h1:rlzQ04UMyJXu/aOvhd8qT+hvDrFpiwqp8MRXDY9szc0= github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 h1:M8mH9eK4OUR4lu7Gd+PU1fV2/qnDNfzT635KRSObncs= github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567/go.mod h1:DWNGW8A4Y+GyBgPuaQJuWiy0XYftx4Xm/y5Jqk9I6VQ= -github.com/raulk/clock v1.1.0/go.mod h1:3MpVxdZ/ODBQDxbN+kzshf5OSZwPjtMDx6BBXBmOeY0= -github.com/raulk/go-watchdog v1.2.0/go.mod h1:lzSbAl5sh4rtI8tYHU01BWIDzgzqaQLj6RcA1i4mlqI= +github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= +github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= +github.com/quic-go/qtls-go1-19 v0.2.1 h1:aJcKNMkH5ASEJB9FXNeZCyTEIHU1J7MmHyz1Q1TSG1A= +github.com/quic-go/qtls-go1-19 v0.2.1/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI= +github.com/quic-go/qtls-go1-20 v0.1.1 h1:KbChDlg82d3IHqaj2bn6GfKRj84Per2VGf5XV3wSwQk= +github.com/quic-go/qtls-go1-20 v0.1.1/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= +github.com/quic-go/quic-go v0.33.0 h1:ItNoTDN/Fm/zBlq769lLJc8ECe9gYaW40veHCCco7y0= +github.com/quic-go/quic-go v0.33.0/go.mod h1:YMuhaAV9/jIu0XclDXwZPAsP/2Kgr5yMYhe9oxhhOFA= +github.com/quic-go/webtransport-go v0.5.2 h1:GA6Bl6oZY+g/flt00Pnu0XtivSD8vukOu3lYhJjnGEk= +github.com/quic-go/webtransport-go v0.5.2/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU= 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= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= -github.com/rogpeppe/go-internal v1.8.1 h1:geMPLpDpQOgVyCg5z5GoRwLHepNdb71NXb67XFkP+Eg= -github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= -github.com/rs/zerolog v1.21.0/go.mod h1:ZPhntP/xmq1nnND05hhpAh2QMhSsA4UN3MGZ6O2J3hM= +github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= @@ -1529,7 +1419,6 @@ github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPx 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/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/sivchari/containedctx v1.0.2 h1:0hLQKpgC53OVF1VT7CeoFHk9YKstur1XOgfYIc1yrHI= @@ -1555,7 +1444,6 @@ github.com/sourcegraph/go-diff v0.6.1 h1:hmA1LzxW0n1c3Q4YbrFgg4P99GSnebYa3x8gr0H github.com/sourcegraph/go-diff v0.6.1/go.mod h1:iBszgVvyxdc8SFZ7gm69go2KDdt3ag071iBaWPF6cjs= github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA= github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a/go.mod h1:7AyxJNCJ7SBZ1MfVQCWD6Uqo2oubI2Eq2y2eqf+A5r0= -github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU= github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= @@ -1590,8 +1478,9 @@ github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3 github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.1.4/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= @@ -1601,8 +1490,9 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= -github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/subosito/gotenv v1.4.0 h1:yAzM1+SmVcz5R4tXGsNMu1jUl2aOJXoiWUCEwwnGrvs= github.com/subosito/gotenv v1.4.0/go.mod h1:mZd6rFysKEcUhUHXJk0C/08wAgyDBFuwEYL7vWWGaGo= github.com/sylvia7788/contextcheck v1.0.6 h1:o2EZgVPyMKE/Mtoqym61DInKEjwEbsmyoxg3VrmjNO4= @@ -1626,7 +1516,11 @@ github.com/tomarrell/wrapcheck/v2 v2.6.2 h1:3dI6YNcrJTQ/CJQ6M/DUkc0gnqYSIk6o0rCh github.com/tomarrell/wrapcheck/v2 v2.6.2/go.mod h1:ao7l5p0aOlUNJKI0qVwB4Yjlqutd0IvAB9Rdwyilxvg= github.com/tommy-muehle/go-mnd/v2 v2.5.0 h1:iAj0a8e6+dXSL7Liq0aXPox36FiN1dBbjA6lt9fl65s= github.com/tommy-muehle/go-mnd/v2 v2.5.0/go.mod h1:WsUAkMJMYww6l/ufffCD3m+P7LEvr8TnZn9lwVDlgzw= +github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= +github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= +github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/ultraware/funlen v0.0.3 h1:5ylVWm8wsNwH5aWo9438pwvsK0QiqVuUrt9bn7S/iLA= github.com/ultraware/funlen v0.0.3/go.mod h1:Dp4UiAus7Wdb9KUZsYWZEWiRzGuM2kXM1lPbfaF6xhA= github.com/ultraware/whitespace v0.0.5 h1:hh+/cpIcopyMYbZNVov9iSxvJU3OYQg78Sfaqzi/CzI= @@ -1635,23 +1529,18 @@ github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijb github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.2 h1:gsqYFH8bb9ekPA12kRo0hfjngWQjkJPlN9R0N78BoUo= 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/uudashr/gocognit v1.0.6 h1:2Cgi6MweCsdB6kpcVQp7EW4U23iBFQWfTXiWlyp842Y= github.com/uudashr/gocognit v1.0.6/go.mod h1:nAIUuVBnYU7pcninia3BHOvQkpQCeO76Uscky5BOwcY= github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU= github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM= -github.com/warpfork/go-testmark v0.3.0/go.mod h1:jhEf8FVxd+F17juRubpmut64NEG6I2rgkUhlcqqXwE0= -github.com/warpfork/go-testmark v0.10.0 h1:E86YlUMYfwIacEsQGlnTvjk1IgYkyTGjPhF0RnwTCmw= -github.com/warpfork/go-testmark v0.10.0/go.mod h1:jhEf8FVxd+F17juRubpmut64NEG6I2rgkUhlcqqXwE0= +github.com/warpfork/go-testmark v0.11.0 h1:J6LnV8KpceDvo7spaNU4+DauH2n1x+6RaO2rJrmpQ9U= github.com/warpfork/go-wish v0.0.0-20180510122957-5ad1f5abf436/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= github.com/warpfork/go-wish v0.0.0-20190328234359-8b3e70f8e830/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= github.com/warpfork/go-wish v0.0.0-20200122115046-b9ea61034e4a h1:G++j5e0OC488te356JvdhaM8YS6nMsjLAYF7JxCv07w= github.com/warpfork/go-wish v0.0.0-20200122115046-b9ea61034e4a/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc/go.mod h1:r45hJU7yEoA81k6MWNhpMj/kms0n14dkzkxYHoB96UM= github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11 h1:5HZfQkwe0mIfyDmc1Em5GqlNRzcdtlv4HTNmdpt7XH0= -github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11/go.mod h1:Wlo/SzPmxVp6vXpGt/zaXhHH0fn4IxgqZc82aKg6bpQ= github.com/whyrusleeping/cbor-gen v0.0.0-20200123233031-1cdf64d27158/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI= -github.com/whyrusleeping/cbor-gen v0.0.0-20200710004633-5379fc63235d/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= github.com/whyrusleeping/cbor-gen v0.0.0-20210219115102-f37d292932f2 h1:bsUlNhdmbtlfdLVXAVfuvKQ01RnWAM09TVrJkI7NZs4= github.com/whyrusleeping/cbor-gen v0.0.0-20210219115102-f37d292932f2/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f h1:jQa4QT2UP9WYv2nzyawpKMOCl+Z/jW7djv2/J50lj9E= @@ -1695,37 +1584,29 @@ go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= -go.opentelemetry.io/otel v0.20.0/go.mod h1:Y3ugLH2oa81t5QO+Lty+zXf8zC9L26ax4Nzoxm/dooo= go.opentelemetry.io/otel v1.2.0 h1:YOQDvxO1FayUcT9MIhJhgMyNO1WqoduiyvQHzGN0kUQ= go.opentelemetry.io/otel v1.2.0/go.mod h1:aT17Fk0Z1Nor9e0uisf98LrntPGMnk4frBO9+dkf69I= -go.opentelemetry.io/otel/metric v0.20.0/go.mod h1:598I5tYlH1vzBjn+BTuhzTCSb/9debfNp6R3s7Pr1eU= -go.opentelemetry.io/otel/oteltest v0.20.0/go.mod h1:L7bgKf9ZB7qCwT9Up7i9/pn0PWIa9FqQ2IQ8LoxiGnw= -go.opentelemetry.io/otel/sdk v0.20.0/go.mod h1:g/IcepuwNsoiX5Byy2nNV0ySUF1em498m7hBWC279Yc= go.opentelemetry.io/otel/sdk v1.2.0 h1:wKN260u4DesJYhyjxDa7LRFkuhH7ncEVKU37LWcyNIo= -go.opentelemetry.io/otel/sdk v1.2.0/go.mod h1:jNN8QtpvbsKhgaC6V5lHiejMoKD+V8uadoSafgHPx1U= -go.opentelemetry.io/otel/trace v0.20.0/go.mod h1:6GjCW8zgDjwGHGa6GkyeB8+/5vjT16gUEi0Nf1iBdgw= go.opentelemetry.io/otel/trace v1.2.0 h1:Ys3iqbqZhcf28hHzrm5WAquMkDHNZTUkw7KHbuNjej0= go.opentelemetry.io/otel/trace v1.2.0/go.mod h1:N5FLswTubnxKxOJHM7XZC074qpeEdLy3CgAVsdMucK0= -go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= +go.uber.org/dig v1.15.0 h1:vq3YWr8zRj1eFGC7Gvf907hE0eRjPTZ1d3xHadD6liE= +go.uber.org/dig v1.15.0/go.mod h1:pKHs0wMynzL6brANhB2hLMro+zalv1osARTviTcqHLM= +go.uber.org/fx v1.18.2 h1:bUNI6oShr+OVFQeU8cDNbnN7VFsu+SsjHzUF51V/GAU= +go.uber.org/fx v1.18.2/go.mod h1:g0V1KMQ66zIRk8bLu3Ea5Jt2w/cHlOIp4wdRsgh0JaY= 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/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA= -go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= -go.uber.org/multierr v1.7.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8= go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= @@ -1735,9 +1616,8 @@ go.uber.org/zap v1.14.1/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= 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.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= -go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= -go.uber.org/zap v1.22.0 h1:Zcye5DUgBloQ9BaT4qc9BnjOFog5TvBSAGkJ3Nf70c0= -go.uber.org/zap v1.22.0/go.mod h1:H4siCOZOrAolnUPJEkfaSjDqyP+BDS0DdDWzwcgt3+U= +go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= +go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -1769,18 +1649,13 @@ golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20210506145944-38f3c27a63bf/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= -golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= -golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa h1:zuSxTR4o9y82ebqCUJYNGJbGPo6sKVl54f/TVDObg1c= -golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.4.0 h1:UVQgzMY87xqpKNgb+kDsll2Igd33HszWHFLmpaRMq/8= +golang.org/x/crypto v0.4.0/go.mod h1:3quD/ATkf6oY+rnes5c3ExXTbLc8mueNue5/DoinL80= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= @@ -1788,9 +1663,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20210615023648-acb5c1269671/go.mod h1:DVyR6MI7P4kEQgvZJSj1fQGrWIi2RzIrfYWycwheUAc= -golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e h1:+WEEuIdZHnUeJJmEUjyYC2gfUMj69yZXw17EnHg/otA= -golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA= +golang.org/x/exp v0.0.0-20221205204356-47842c84f3db h1:D/cFflL63o2KSLJIwjlcIt8PR064j/xsmdEJL/YvY/o= +golang.org/x/exp v0.0.0-20221205204356-47842c84f3db/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= golang.org/x/exp/typeparams v0.0.0-20220428152302-39d4317da171/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/exp/typeparams v0.0.0-20220613132600-b0d781184e0d h1:+W8Qf4iJtMGKkyAygcKohjxTk4JPsL9DpzApJ22m5Ic= golang.org/x/exp/typeparams v0.0.0-20220613132600-b0d781184e0d/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= @@ -1810,12 +1684,10 @@ golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPI golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= -golang.org/x/mobile v0.0.0-20201217150744-e6ae53a27f4f/go.mod h1:skQtrUTUwhdJvXM/2KKJzY8pDgNr9I/FOMqDVRPBUS4= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.1.1-0.20191209134235-331c550502dd/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= @@ -1823,8 +1695,9 @@ golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA= +golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1869,7 +1742,6 @@ golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200904194848-62affa334b73/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= @@ -1880,18 +1752,14 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210423184538-5f58ad60dda6/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220418201149-a630d4f3e7a2/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.0.0-20220812174116-3211cb980234 h1:RDqmgfe7SvlMWoqC3xwQ2blLO3fcWcxMa3eBLRdRW7E= -golang.org/x/net v0.0.0-20220812174116-3211cb980234/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.4.0 h1:Q5QPcMlvfxFTAPV0+07Xz/MpK9NTXu2VDUuy0FeMfaU= +golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1917,8 +1785,9 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 h1:uVc8UZUe6tr40fFVnUP5Oj+veunVezqYl9z7DYw9xzw= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= +golang.org/x/sync v0.1.0/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= @@ -1960,7 +1829,6 @@ golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191206220618-eeba5f6aabab/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1987,9 +1855,7 @@ golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201214210602-f9fddec55a1e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -2002,8 +1868,6 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210426080607-c94f62235c83/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210511113859-b0526f3d8744/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -2017,12 +1881,14 @@ golang.org/x/sys v0.0.0-20220702020025-31831981b65f/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab h1:2QkjZIsXupsJbJIdSjjUOgWK3aEtzyuh2mPt3l/CkeU= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ= +golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.3.0 h1:qoo4akIqOcDME5bhc/NgxUdovd6BSS2uMsVjB56q1xI= +golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -2030,8 +1896,9 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM= +golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -2077,7 +1944,6 @@ golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapK golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200117012304-6edc0a871e69/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200117220505-0cba7a3a9ee9/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= @@ -2115,7 +1981,6 @@ golang.org/x/tools v0.0.0-20201023174141-c8cfbd0f21e6/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201230224404-63754364767c/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= @@ -2130,13 +1995,13 @@ golang.org/x/tools v0.1.9-0.20211228192929-ee1ca4ffc4da/go.mod h1:nABZi5QlRsZVlz golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/tools v0.1.11/go.mod h1:SgwaegtQh8clINPpECJMqnxLv9I09HLqnW3RMqW0CA4= -golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.3.0 h1:SrNbZl6ECOS1qFzgTdQfWXZM9XBkiA6tkFrH9YSTPHM= +golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df h1:5Pf6pFKu98ODmgnpvkJ3kFUOQGGLIzLIkbzUHp47618= golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= @@ -2199,7 +2064,6 @@ google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfG google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= @@ -2234,12 +2098,9 @@ google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3Iji google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -2252,8 +2113,6 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= @@ -2275,13 +2134,11 @@ gopkg.in/ini.v1 v1.66.6/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/src-d/go-cli.v0 v0.0.0-20181105080154-d492247bbc0d/go.mod h1:z+K8VcOYVYcSwSjGebuDL6176A1XskgbtNl64NSg+n8= gopkg.in/src-d/go-log.v1 v1.0.1/go.mod h1:GN34hKP0g305ysm2/hctJ0Y8nWP3zxXXJ8GFabTyABE= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -2305,10 +2162,8 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= honnef.co/go/tools v0.3.3 h1:oDx7VAwstgpYpb3wv0oxiZlxY+foCpRAwY7Vk6XpAgA= honnef.co/go/tools v0.3.3/go.mod h1:jzwdWgg7Jdq75wlfblQxO4neNaFFSvgc1tD5Wv8U0Yw= -lukechampine.com/blake3 v1.1.6/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= lukechampine.com/blake3 v1.1.7 h1:GgRMhmdsuK8+ii6UZFDL8Nb+VyMwadAgcJyfYHxG6n0= lukechampine.com/blake3 v1.1.7/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= mvdan.cc/gofumpt v0.3.1 h1:avhhrOmv0IuvQVK7fvwV91oFSGAk5/6Po8GXTzICeu8= @@ -2319,6 +2174,8 @@ mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b h1:DxJ5nJdkhDlLok9K6qO+5290kphD mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4= mvdan.cc/unparam v0.0.0-20220706161116-678bad134442 h1:seuXWbRB1qPrS3NQnHmFKLJLtskWyueeIzmLXghMGgk= mvdan.cc/unparam v0.0.0-20220706161116-678bad134442/go.mod h1:F/Cxw/6mVrNKqrR2YjFf5CaW0Bw4RL8RfbEf4GRggJk= +nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g= +nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= From 1e3b6c98579cf549f4042e4fa76ec9d155f82bf3 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Tue, 28 Mar 2023 21:52:36 +0200 Subject: [PATCH 0590/1212] feat: add tracing to the commands client --- cmd/ipfs/main.go | 59 +++++++++++++------ core/corehttp/commands.go | 12 ++-- core/corehttp/gateway.go | 2 + ...230-channel-streaming-http-content-type.sh | 2 + tracing/tracing.go | 9 ++- 5 files changed, 60 insertions(+), 24 deletions(-) diff --git a/cmd/ipfs/main.go b/cmd/ipfs/main.go index 8b9822c99..c3b3f3eaa 100644 --- a/cmd/ipfs/main.go +++ b/cmd/ipfs/main.go @@ -10,8 +10,15 @@ import ( "net/http" "os" "runtime/pprof" + "strings" "time" + "github.com/google/uuid" + cmds "github.com/ipfs/go-ipfs-cmds" + "github.com/ipfs/go-ipfs-cmds/cli" + cmdhttp "github.com/ipfs/go-ipfs-cmds/http" + u "github.com/ipfs/go-ipfs-util" + logging "github.com/ipfs/go-log" "github.com/ipfs/kubo/cmd/ipfs/util" oldcmds "github.com/ipfs/kubo/commands" "github.com/ipfs/kubo/core" @@ -21,22 +28,19 @@ import ( "github.com/ipfs/kubo/repo" "github.com/ipfs/kubo/repo/fsrepo" "github.com/ipfs/kubo/tracing" - - cmds "github.com/ipfs/go-ipfs-cmds" - "github.com/ipfs/go-ipfs-cmds/cli" - cmdhttp "github.com/ipfs/go-ipfs-cmds/http" - u "github.com/ipfs/go-ipfs-util" - logging "github.com/ipfs/go-log" ma "github.com/multiformats/go-multiaddr" madns "github.com/multiformats/go-multiaddr-dns" manet "github.com/multiformats/go-multiaddr/net" - - "github.com/google/uuid" + "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/codes" + "go.opentelemetry.io/otel/trace" ) // log is the command logger var log = logging.Logger("cmd/ipfs") +var tracer trace.Tracer // declared as a var for testing purposes var dnsResolver = madns.DefaultResolver @@ -91,7 +95,6 @@ func newUUID(key string) logging.Metadata { func mainRet() (exitCode int) { rand.Seed(time.Now().UnixNano()) ctx := logging.ContextWithLoggable(context.Background(), newUUID("session")) - var err error tp, err := tracing.NewTracerProvider(ctx) if err != nil { @@ -103,6 +106,7 @@ func mainRet() (exitCode int) { } }() otel.SetTracerProvider(tp) + tracer = tp.Tracer("Kubo-cli") stopFunc, err := profileIfEnabled() if err != nil { @@ -219,7 +223,7 @@ func apiAddrOption(req *cmds.Request) (ma.Multiaddr, error) { } func makeExecutor(req *cmds.Request, env interface{}) (cmds.Executor, error) { - exe := cmds.NewExecutor(req.Root) + exe := tracingWrappedExecutor{cmds.NewExecutor(req.Root)} cctx := env.(*oldcmds.Context) // Check if the command is disabled. @@ -294,23 +298,44 @@ func makeExecutor(req *cmds.Request, env interface{}) (cmds.Executor, error) { opts = append(opts, cmdhttp.ClientWithFallback(exe)) } + var tpt http.RoundTripper switch network { case "tcp", "tcp4", "tcp6": + tpt = http.DefaultTransport case "unix": path := host host = "unix" - opts = append(opts, cmdhttp.ClientWithHTTPClient(&http.Client{ - Transport: &http.Transport{ - DialContext: func(_ context.Context, _, _ string) (net.Conn, error) { - return net.Dial("unix", path) - }, + tpt = &http.Transport{ + DialContext: func(_ context.Context, _, _ string) (net.Conn, error) { + return net.Dial("unix", path) }, - })) + } default: return nil, fmt.Errorf("unsupported API address: %s", apiAddr) } + opts = append(opts, cmdhttp.ClientWithHTTPClient(&http.Client{ + Transport: otelhttp.NewTransport(tpt, + otelhttp.WithPropagators(tracing.Propagator()), + ), + })) - return cmdhttp.NewClient(host, opts...), nil + return tracingWrappedExecutor{cmdhttp.NewClient(host, opts...)}, nil +} + +type tracingWrappedExecutor struct { + exec cmds.Executor +} + +func (twe tracingWrappedExecutor) Execute(req *cmds.Request, re cmds.ResponseEmitter, env cmds.Environment) error { + ctx, span := tracer.Start(req.Context, "cmds."+strings.Join(req.Path, "."), trace.WithAttributes(attribute.StringSlice("Arguments", req.Arguments))) + defer span.End() + req.Context = ctx + + err := twe.exec.Execute(req, re, env) + if err != nil { + span.SetStatus(codes.Error, err.Error()) + } + return err } func getRepoPath(req *cmds.Request) (string, error) { diff --git a/core/corehttp/commands.go b/core/corehttp/commands.go index c0ebf5506..5d8399393 100644 --- a/core/corehttp/commands.go +++ b/core/corehttp/commands.go @@ -9,15 +9,16 @@ import ( "strconv" "strings" - version "github.com/ipfs/kubo" - oldcmds "github.com/ipfs/kubo/commands" - "github.com/ipfs/kubo/core" - corecommands "github.com/ipfs/kubo/core/commands" - cmds "github.com/ipfs/go-ipfs-cmds" cmdsHttp "github.com/ipfs/go-ipfs-cmds/http" path "github.com/ipfs/go-path" + version "github.com/ipfs/kubo" + oldcmds "github.com/ipfs/kubo/commands" config "github.com/ipfs/kubo/config" + "github.com/ipfs/kubo/core" + corecommands "github.com/ipfs/kubo/core/commands" + "github.com/ipfs/kubo/tracing" + "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" ) var ( @@ -146,6 +147,7 @@ func commandsOption(cctx oldcmds.Context, command *cmds.Command, allowGet bool) patchCORSVars(cfg, l.Addr()) cmdHandler := cmdsHttp.NewHandler(&cctx, command, cfg) + cmdHandler = otelhttp.NewHandler(cmdHandler, "corehttp.cmdsHandler", otelhttp.WithPropagators(tracing.Propagator())) mux.Handle(APIPath+"/", cmdHandler) return mux, nil } diff --git a/core/corehttp/gateway.go b/core/corehttp/gateway.go index f77e941d9..b68aa7bda 100644 --- a/core/corehttp/gateway.go +++ b/core/corehttp/gateway.go @@ -48,6 +48,8 @@ func GatewayOption(paths ...string) ServeOption { } gw := gateway.NewHandler(gwConfig, gwAPI) + // TODO: Add otelhttp.WithPropagators(tracing.Propagator()) option to + // propagate traces through the gateway once we test this feature. gw = otelhttp.NewHandler(gw, "Gateway.Request") // By default, our HTTP handler is the gateway handler. diff --git a/test/sharness/t0230-channel-streaming-http-content-type.sh b/test/sharness/t0230-channel-streaming-http-content-type.sh index be23d8151..055b342d1 100755 --- a/test/sharness/t0230-channel-streaming-http-content-type.sh +++ b/test/sharness/t0230-channel-streaming-http-content-type.sh @@ -23,6 +23,7 @@ test_ls_cmd() { printf "HTTP/1.1 200 OK\r\n" >expected_output && printf "Access-Control-Allow-Headers: X-Stream-Output, X-Chunked-Output, X-Content-Length\r\n" >>expected_output && printf "Access-Control-Expose-Headers: X-Stream-Output, X-Chunked-Output, X-Content-Length\r\n" >>expected_output && + printf "Connection: close\r\n" >>expected_output && printf "Content-Type: text/plain\r\n" >>expected_output && printf "Server: kubo/%s\r\n" $(ipfs version -n) >>expected_output && printf "Trailer: X-Stream-Error\r\n" >>expected_output && @@ -46,6 +47,7 @@ test_ls_cmd() { printf "HTTP/1.1 200 OK\r\n" >expected_output && printf "Access-Control-Allow-Headers: X-Stream-Output, X-Chunked-Output, X-Content-Length\r\n" >>expected_output && printf "Access-Control-Expose-Headers: X-Stream-Output, X-Chunked-Output, X-Content-Length\r\n" >>expected_output && + printf "Connection: close\r\n" >>expected_output && printf "Content-Type: application/json\r\n" >>expected_output && printf "Server: kubo/%s\r\n" $(ipfs version -n) >>expected_output && printf "Trailer: X-Stream-Error\r\n" >>expected_output && diff --git a/tracing/tracing.go b/tracing/tracing.go index 6cc666a83..1da3fbd53 100644 --- a/tracing/tracing.go +++ b/tracing/tracing.go @@ -13,6 +13,7 @@ import ( "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc" "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp" "go.opentelemetry.io/otel/exporters/zipkin" + "go.opentelemetry.io/otel/propagation" "go.opentelemetry.io/otel/sdk/resource" "go.opentelemetry.io/otel/sdk/trace" semconv "go.opentelemetry.io/otel/semconv/v1.4.0" @@ -130,7 +131,7 @@ func NewTracerProvider(ctx context.Context) (shutdownTracerProvider, error) { r, err := resource.Merge( resource.Default(), resource.NewSchemaless( - semconv.ServiceNameKey.String("go-ipfs"), + semconv.ServiceNameKey.String("Kubo"), semconv.ServiceVersionKey.String(version.CurrentVersionNumber), ), ) @@ -144,5 +145,9 @@ func NewTracerProvider(ctx context.Context) (shutdownTracerProvider, error) { // Span starts a new span using the standard IPFS tracing conventions. func Span(ctx context.Context, componentName string, spanName string, opts ...traceapi.SpanStartOption) (context.Context, traceapi.Span) { - return otel.Tracer("go-ipfs").Start(ctx, fmt.Sprintf("%s.%s", componentName, spanName), opts...) + return otel.Tracer("Kubo").Start(ctx, fmt.Sprintf("%s.%s", componentName, spanName), opts...) +} + +func Propagator() propagation.TextMapPropagator { + return propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{}) } From 3ab1086f710264c822e448e8813950eb8e91c24f Mon Sep 17 00:00:00 2001 From: Jorropo Date: Thu, 23 Mar 2023 09:15:36 +0100 Subject: [PATCH 0591/1212] chore: migrate go-libipfs to boxo Resolves #9677, #9676, #9675, #9736 --- assets/assets.go | 6 +- blocks/blockstoreutil/remove.go | 4 +- cmd/ipfs/add_migrations.go | 8 +- cmd/ipfs/daemon.go | 2 +- cmd/ipfs/init.go | 8 +- cmd/ipfs/main.go | 2 +- cmd/ipfs/pinmfs.go | 2 +- cmd/ipfs/pinmfs_test.go | 2 +- cmd/ipfswatch/main.go | 2 +- commands/context.go | 4 +- config/init.go | 2 +- config/init_test.go | 2 +- core/commands/add.go | 8 +- core/commands/bitswap.go | 4 +- core/commands/block.go | 6 +- core/commands/cat.go | 6 +- core/commands/cid.go | 2 +- core/commands/cmdenv/env.go | 4 +- core/commands/cmdenv/file.go | 2 +- core/commands/cmdutils/utils.go | 2 +- core/commands/dag/dag.go | 2 +- core/commands/dag/export.go | 6 +- core/commands/dag/get.go | 2 +- core/commands/dag/import.go | 6 +- core/commands/dag/put.go | 4 +- core/commands/dag/resolve.go | 2 +- core/commands/dag/stat.go | 6 +- core/commands/dht_test.go | 4 +- core/commands/dns.go | 4 +- core/commands/files.go | 14 +- core/commands/filestore.go | 2 +- core/commands/get.go | 6 +- core/commands/keystore.go | 4 +- core/commands/ls.go | 10 +- core/commands/name/ipns.go | 8 +- core/commands/name/name.go | 4 +- core/commands/name/publish.go | 6 +- core/commands/object/diff.go | 4 +- core/commands/object/object.go | 6 +- core/commands/object/patch.go | 4 +- core/commands/pin/pin.go | 14 +- core/commands/pin/remotepin.go | 4 +- core/commands/pubsub.go | 2 +- core/commands/refs.go | 6 +- core/commands/repo.go | 2 +- core/commands/resolve.go | 10 +- core/commands/routing.go | 4 +- core/commands/stat_provide.go | 2 +- core/commands/tar.go | 4 +- core/commands/unixfs/ls.go | 6 +- core/commands/urlstore.go | 6 +- core/core.go | 20 +- core/core_test.go | 2 +- core/coreapi/block.go | 10 +- core/coreapi/coreapi.go | 24 +- core/coreapi/dag.go | 4 +- core/coreapi/dht.go | 14 +- core/coreapi/key.go | 8 +- core/coreapi/name.go | 14 +- core/coreapi/object.go | 14 +- core/coreapi/path.go | 12 +- core/coreapi/pin.go | 14 +- core/coreapi/pubsub.go | 4 +- core/coreapi/routing.go | 4 +- core/coreapi/swarm.go | 2 +- core/coreapi/test/api_test.go | 8 +- core/coreapi/test/path_test.go | 10 +- core/coreapi/unixfs.go | 26 +- core/corehttp/commands.go | 2 +- core/corehttp/gateway.go | 16 +- core/corehttp/gateway_test.go | 8 +- core/corerepo/gc.go | 2 +- core/coreunix/add.go | 26 +- core/coreunix/add_test.go | 14 +- core/coreunix/metadata.go | 4 +- core/coreunix/metadata_test.go | 18 +- core/node/bitswap.go | 8 +- core/node/core.go | 22 +- core/node/graphsync.go | 2 +- core/node/groups.go | 8 +- core/node/ipns.go | 8 +- core/node/libp2p/routing.go | 2 +- core/node/provider.go | 12 +- core/node/storage.go | 4 +- docs/examples/kubo-as-a-library/go.mod | 73 +- docs/examples/kubo-as-a-library/go.sum | 693 ++--------------- docs/examples/kubo-as-a-library/main.go | 6 +- fuse/ipns/common.go | 6 +- fuse/ipns/ipns_test.go | 2 +- fuse/ipns/ipns_unix.go | 12 +- fuse/readonly/ipfs_test.go | 14 +- fuse/readonly/readonly_unix.go | 10 +- gc/gc.go | 12 +- go.mod | 90 +-- go.sum | 705 ++---------------- plugin/daemon.go | 2 +- repo/fsrepo/fsrepo.go | 6 +- .../migrations/ipfsfetcher/ipfsfetcher.go | 8 +- repo/mock.go | 4 +- repo/repo.go | 4 +- routing/delegated.go | 4 +- tar/format.go | 12 +- test/integration/addcat_test.go | 2 +- test/integration/bench_cat_test.go | 2 +- test/integration/bitswap_wo_routing_test.go | 2 +- test/integration/three_legged_cat_test.go | 2 +- thirdparty/verifbs/verifbs.go | 6 +- 107 files changed, 553 insertions(+), 1712 deletions(-) diff --git a/assets/assets.go b/assets/assets.go index 00792d511..945e8e10a 100644 --- a/assets/assets.go +++ b/assets/assets.go @@ -8,10 +8,10 @@ import ( "github.com/ipfs/kubo/core" "github.com/ipfs/kubo/core/coreapi" + options "github.com/ipfs/boxo/coreiface/options" + "github.com/ipfs/boxo/coreiface/path" + "github.com/ipfs/boxo/files" cid "github.com/ipfs/go-cid" - "github.com/ipfs/go-libipfs/files" - options "github.com/ipfs/interface-go-ipfs-core/options" - "github.com/ipfs/interface-go-ipfs-core/path" ) //go:embed init-doc diff --git a/blocks/blockstoreutil/remove.go b/blocks/blockstoreutil/remove.go index 4440c2a65..d4219d7b1 100644 --- a/blocks/blockstoreutil/remove.go +++ b/blocks/blockstoreutil/remove.go @@ -6,9 +6,9 @@ import ( "errors" "fmt" + bs "github.com/ipfs/boxo/blockstore" + pin "github.com/ipfs/boxo/pinning/pinner" cid "github.com/ipfs/go-cid" - bs "github.com/ipfs/go-ipfs-blockstore" - pin "github.com/ipfs/go-ipfs-pinner" format "github.com/ipfs/go-ipld-format" ) diff --git a/cmd/ipfs/add_migrations.go b/cmd/ipfs/add_migrations.go index 50ea9ad1c..e0a5d7101 100644 --- a/cmd/ipfs/add_migrations.go +++ b/cmd/ipfs/add_migrations.go @@ -8,10 +8,10 @@ import ( "os" "path/filepath" - "github.com/ipfs/go-libipfs/files" - coreiface "github.com/ipfs/interface-go-ipfs-core" - "github.com/ipfs/interface-go-ipfs-core/options" - ipath "github.com/ipfs/interface-go-ipfs-core/path" + coreiface "github.com/ipfs/boxo/coreiface" + "github.com/ipfs/boxo/coreiface/options" + ipath "github.com/ipfs/boxo/coreiface/path" + "github.com/ipfs/boxo/files" "github.com/ipfs/kubo/core" "github.com/ipfs/kubo/core/coreapi" "github.com/ipfs/kubo/repo/fsrepo/migrations" diff --git a/cmd/ipfs/daemon.go b/cmd/ipfs/daemon.go index 85ca79246..ffcb30a34 100644 --- a/cmd/ipfs/daemon.go +++ b/cmd/ipfs/daemon.go @@ -34,9 +34,9 @@ import ( pnet "github.com/libp2p/go-libp2p/core/pnet" sockets "github.com/libp2p/go-socket-activation" + options "github.com/ipfs/boxo/coreiface/options" cmds "github.com/ipfs/go-ipfs-cmds" mprome "github.com/ipfs/go-metrics-prometheus" - options "github.com/ipfs/interface-go-ipfs-core/options" goprocess "github.com/jbenet/goprocess" ma "github.com/multiformats/go-multiaddr" manet "github.com/multiformats/go-multiaddr/net" diff --git a/cmd/ipfs/init.go b/cmd/ipfs/init.go index 4232cc262..3856f2ff4 100644 --- a/cmd/ipfs/init.go +++ b/cmd/ipfs/init.go @@ -10,17 +10,17 @@ import ( "path/filepath" "strings" - path "github.com/ipfs/go-path" - unixfs "github.com/ipfs/go-unixfs" + unixfs "github.com/ipfs/boxo/ipld/unixfs" + path "github.com/ipfs/boxo/path" assets "github.com/ipfs/kubo/assets" oldcmds "github.com/ipfs/kubo/commands" core "github.com/ipfs/kubo/core" "github.com/ipfs/kubo/core/commands" fsrepo "github.com/ipfs/kubo/repo/fsrepo" + options "github.com/ipfs/boxo/coreiface/options" + "github.com/ipfs/boxo/files" cmds "github.com/ipfs/go-ipfs-cmds" - "github.com/ipfs/go-libipfs/files" - options "github.com/ipfs/interface-go-ipfs-core/options" config "github.com/ipfs/kubo/config" ) diff --git a/cmd/ipfs/main.go b/cmd/ipfs/main.go index c3b3f3eaa..2d9673ece 100644 --- a/cmd/ipfs/main.go +++ b/cmd/ipfs/main.go @@ -14,10 +14,10 @@ import ( "time" "github.com/google/uuid" + u "github.com/ipfs/boxo/util" cmds "github.com/ipfs/go-ipfs-cmds" "github.com/ipfs/go-ipfs-cmds/cli" cmdhttp "github.com/ipfs/go-ipfs-cmds/http" - u "github.com/ipfs/go-ipfs-util" logging "github.com/ipfs/go-log" "github.com/ipfs/kubo/cmd/ipfs/util" oldcmds "github.com/ipfs/kubo/commands" diff --git a/cmd/ipfs/pinmfs.go b/cmd/ipfs/pinmfs.go index 57f353f1d..f36b0a8c5 100644 --- a/cmd/ipfs/pinmfs.go +++ b/cmd/ipfs/pinmfs.go @@ -8,10 +8,10 @@ import ( "github.com/libp2p/go-libp2p/core/host" peer "github.com/libp2p/go-libp2p/core/peer" + pinclient "github.com/ipfs/boxo/pinning/remote/client" cid "github.com/ipfs/go-cid" ipld "github.com/ipfs/go-ipld-format" logging "github.com/ipfs/go-log" - pinclient "github.com/ipfs/go-pinning-service-http-client" config "github.com/ipfs/kubo/config" "github.com/ipfs/kubo/core" diff --git a/cmd/ipfs/pinmfs_test.go b/cmd/ipfs/pinmfs_test.go index 78c7a863b..7f1ac8696 100644 --- a/cmd/ipfs/pinmfs_test.go +++ b/cmd/ipfs/pinmfs_test.go @@ -7,8 +7,8 @@ import ( "testing" "time" + merkledag "github.com/ipfs/boxo/ipld/merkledag" ipld "github.com/ipfs/go-ipld-format" - merkledag "github.com/ipfs/go-merkledag" config "github.com/ipfs/kubo/config" "github.com/libp2p/go-libp2p/core/host" peer "github.com/libp2p/go-libp2p/core/peer" diff --git a/cmd/ipfswatch/main.go b/cmd/ipfswatch/main.go index 2c333fc23..9f2558e25 100644 --- a/cmd/ipfswatch/main.go +++ b/cmd/ipfswatch/main.go @@ -19,7 +19,7 @@ import ( fsrepo "github.com/ipfs/kubo/repo/fsrepo" fsnotify "github.com/fsnotify/fsnotify" - "github.com/ipfs/go-libipfs/files" + "github.com/ipfs/boxo/files" process "github.com/jbenet/goprocess" homedir "github.com/mitchellh/go-homedir" ) diff --git a/commands/context.go b/commands/context.go index 64e6ec55d..fa1022819 100644 --- a/commands/context.go +++ b/commands/context.go @@ -10,10 +10,10 @@ import ( coreapi "github.com/ipfs/kubo/core/coreapi" loader "github.com/ipfs/kubo/plugin/loader" + coreiface "github.com/ipfs/boxo/coreiface" + options "github.com/ipfs/boxo/coreiface/options" cmds "github.com/ipfs/go-ipfs-cmds" logging "github.com/ipfs/go-log" - coreiface "github.com/ipfs/interface-go-ipfs-core" - options "github.com/ipfs/interface-go-ipfs-core/options" config "github.com/ipfs/kubo/config" ) diff --git a/config/init.go b/config/init.go index 288f8a1d5..646d1e6e0 100644 --- a/config/init.go +++ b/config/init.go @@ -7,7 +7,7 @@ import ( "io" "time" - "github.com/ipfs/interface-go-ipfs-core/options" + "github.com/ipfs/boxo/coreiface/options" "github.com/libp2p/go-libp2p/core/crypto" "github.com/libp2p/go-libp2p/core/peer" ) diff --git a/config/init_test.go b/config/init_test.go index b48b360c3..762ad3976 100644 --- a/config/init_test.go +++ b/config/init_test.go @@ -4,7 +4,7 @@ import ( "bytes" "testing" - "github.com/ipfs/interface-go-ipfs-core/options" + "github.com/ipfs/boxo/coreiface/options" crypto_pb "github.com/libp2p/go-libp2p/core/crypto/pb" ) diff --git a/core/commands/add.go b/core/commands/add.go index 7afe10f1e..fa78d7074 100644 --- a/core/commands/add.go +++ b/core/commands/add.go @@ -11,12 +11,12 @@ import ( "github.com/ipfs/kubo/core/commands/cmdenv" "github.com/cheggaaa/pb" + coreiface "github.com/ipfs/boxo/coreiface" + "github.com/ipfs/boxo/coreiface/options" + "github.com/ipfs/boxo/files" + mfs "github.com/ipfs/boxo/mfs" cmds "github.com/ipfs/go-ipfs-cmds" ipld "github.com/ipfs/go-ipld-format" - "github.com/ipfs/go-libipfs/files" - mfs "github.com/ipfs/go-mfs" - coreiface "github.com/ipfs/interface-go-ipfs-core" - "github.com/ipfs/interface-go-ipfs-core/options" mh "github.com/multiformats/go-multihash" ) diff --git a/core/commands/bitswap.go b/core/commands/bitswap.go index 51c2f916d..6502876d1 100644 --- a/core/commands/bitswap.go +++ b/core/commands/bitswap.go @@ -8,10 +8,10 @@ import ( e "github.com/ipfs/kubo/core/commands/e" humanize "github.com/dustin/go-humanize" + bitswap "github.com/ipfs/boxo/bitswap" + "github.com/ipfs/boxo/bitswap/server" cidutil "github.com/ipfs/go-cidutil" cmds "github.com/ipfs/go-ipfs-cmds" - bitswap "github.com/ipfs/go-libipfs/bitswap" - "github.com/ipfs/go-libipfs/bitswap/server" peer "github.com/libp2p/go-libp2p/core/peer" ) diff --git a/core/commands/block.go b/core/commands/block.go index c8001b49c..45b8f2a72 100644 --- a/core/commands/block.go +++ b/core/commands/block.go @@ -6,14 +6,14 @@ import ( "io" "os" - "github.com/ipfs/go-libipfs/files" + "github.com/ipfs/boxo/files" cmdenv "github.com/ipfs/kubo/core/commands/cmdenv" "github.com/ipfs/kubo/core/commands/cmdutils" + options "github.com/ipfs/boxo/coreiface/options" + path "github.com/ipfs/boxo/coreiface/path" cmds "github.com/ipfs/go-ipfs-cmds" - options "github.com/ipfs/interface-go-ipfs-core/options" - path "github.com/ipfs/interface-go-ipfs-core/path" mh "github.com/multiformats/go-multihash" ) diff --git a/core/commands/cat.go b/core/commands/cat.go index c80bacf02..92b045235 100644 --- a/core/commands/cat.go +++ b/core/commands/cat.go @@ -9,10 +9,10 @@ import ( "github.com/ipfs/kubo/core/commands/cmdenv" "github.com/cheggaaa/pb" + iface "github.com/ipfs/boxo/coreiface" + "github.com/ipfs/boxo/coreiface/path" + "github.com/ipfs/boxo/files" cmds "github.com/ipfs/go-ipfs-cmds" - "github.com/ipfs/go-libipfs/files" - iface "github.com/ipfs/interface-go-ipfs-core" - "github.com/ipfs/interface-go-ipfs-core/path" ) const ( diff --git a/core/commands/cid.go b/core/commands/cid.go index a6406a3e0..7590b35b4 100644 --- a/core/commands/cid.go +++ b/core/commands/cid.go @@ -7,10 +7,10 @@ import ( "strings" "unicode" + verifcid "github.com/ipfs/boxo/verifcid" cid "github.com/ipfs/go-cid" cidutil "github.com/ipfs/go-cidutil" cmds "github.com/ipfs/go-ipfs-cmds" - verifcid "github.com/ipfs/go-verifcid" ipldmulticodec "github.com/ipld/go-ipld-prime/multicodec" mbase "github.com/multiformats/go-multibase" mc "github.com/multiformats/go-multicodec" diff --git a/core/commands/cmdenv/env.go b/core/commands/cmdenv/env.go index 2c5845890..69ad2dc74 100644 --- a/core/commands/cmdenv/env.go +++ b/core/commands/cmdenv/env.go @@ -8,10 +8,10 @@ import ( "github.com/ipfs/kubo/commands" "github.com/ipfs/kubo/core" + coreiface "github.com/ipfs/boxo/coreiface" + options "github.com/ipfs/boxo/coreiface/options" cmds "github.com/ipfs/go-ipfs-cmds" logging "github.com/ipfs/go-log" - coreiface "github.com/ipfs/interface-go-ipfs-core" - options "github.com/ipfs/interface-go-ipfs-core/options" ) var log = logging.Logger("core/commands/cmdenv") diff --git a/core/commands/cmdenv/file.go b/core/commands/cmdenv/file.go index 43c12abc4..8167ba54d 100644 --- a/core/commands/cmdenv/file.go +++ b/core/commands/cmdenv/file.go @@ -3,7 +3,7 @@ package cmdenv import ( "fmt" - "github.com/ipfs/go-libipfs/files" + "github.com/ipfs/boxo/files" ) // GetFileArg returns the next file from the directory or an error diff --git a/core/commands/cmdutils/utils.go b/core/commands/cmdutils/utils.go index f4b6b40f4..9b498933b 100644 --- a/core/commands/cmdutils/utils.go +++ b/core/commands/cmdutils/utils.go @@ -5,8 +5,8 @@ import ( cmds "github.com/ipfs/go-ipfs-cmds" + coreiface "github.com/ipfs/boxo/coreiface" "github.com/ipfs/go-cid" - coreiface "github.com/ipfs/interface-go-ipfs-core" ) const ( diff --git a/core/commands/dag/dag.go b/core/commands/dag/dag.go index e58ddc82d..75588b8ed 100644 --- a/core/commands/dag/dag.go +++ b/core/commands/dag/dag.go @@ -7,10 +7,10 @@ import ( "github.com/ipfs/kubo/core/commands/cmdenv" "github.com/ipfs/kubo/core/commands/cmdutils" + ipfspath "github.com/ipfs/boxo/path" cid "github.com/ipfs/go-cid" cidenc "github.com/ipfs/go-cidutil/cidenc" cmds "github.com/ipfs/go-ipfs-cmds" - ipfspath "github.com/ipfs/go-path" //gipfree "github.com/ipld/go-ipld-prime/impl/free" //gipselector "github.com/ipld/go-ipld-prime/traversal/selector" //gipselectorbuilder "github.com/ipld/go-ipld-prime/traversal/selector/builder" diff --git a/core/commands/dag/export.go b/core/commands/dag/export.go index b78523ce5..9a8e11af1 100644 --- a/core/commands/dag/export.go +++ b/core/commands/dag/export.go @@ -9,14 +9,14 @@ import ( "time" "github.com/cheggaaa/pb" + iface "github.com/ipfs/boxo/coreiface" + blocks "github.com/ipfs/go-block-format" cid "github.com/ipfs/go-cid" ipld "github.com/ipfs/go-ipld-format" - blocks "github.com/ipfs/go-libipfs/blocks" - iface "github.com/ipfs/interface-go-ipfs-core" "github.com/ipfs/kubo/core/commands/cmdenv" + gocar "github.com/ipfs/boxo/ipld/car" cmds "github.com/ipfs/go-ipfs-cmds" - gocar "github.com/ipld/go-car" selectorparse "github.com/ipld/go-ipld-prime/traversal/selector/parse" ) diff --git a/core/commands/dag/get.go b/core/commands/dag/get.go index 79ad98a49..1252293a8 100644 --- a/core/commands/dag/get.go +++ b/core/commands/dag/get.go @@ -4,8 +4,8 @@ import ( "fmt" "io" + "github.com/ipfs/boxo/coreiface/path" ipldlegacy "github.com/ipfs/go-ipld-legacy" - "github.com/ipfs/interface-go-ipfs-core/path" "github.com/ipfs/kubo/core/commands/cmdenv" "github.com/ipld/go-ipld-prime" diff --git a/core/commands/dag/import.go b/core/commands/dag/import.go index c07a8cdf9..2f2ed9e58 100644 --- a/core/commands/dag/import.go +++ b/core/commands/dag/import.go @@ -4,13 +4,13 @@ import ( "errors" "io" + "github.com/ipfs/boxo/coreiface/options" + "github.com/ipfs/boxo/files" + gocarv2 "github.com/ipfs/boxo/ipld/car/v2" cid "github.com/ipfs/go-cid" cmds "github.com/ipfs/go-ipfs-cmds" ipld "github.com/ipfs/go-ipld-format" ipldlegacy "github.com/ipfs/go-ipld-legacy" - "github.com/ipfs/go-libipfs/files" - "github.com/ipfs/interface-go-ipfs-core/options" - gocarv2 "github.com/ipld/go-car/v2" "github.com/ipfs/kubo/core/commands/cmdenv" "github.com/ipfs/kubo/core/commands/cmdutils" diff --git a/core/commands/dag/put.go b/core/commands/dag/put.go index 351b9cacd..c9c0b455b 100644 --- a/core/commands/dag/put.go +++ b/core/commands/dag/put.go @@ -4,17 +4,17 @@ import ( "bytes" "fmt" + blocks "github.com/ipfs/go-block-format" "github.com/ipfs/go-cid" ipldlegacy "github.com/ipfs/go-ipld-legacy" - blocks "github.com/ipfs/go-libipfs/blocks" "github.com/ipfs/kubo/core/commands/cmdenv" "github.com/ipfs/kubo/core/commands/cmdutils" "github.com/ipld/go-ipld-prime/multicodec" basicnode "github.com/ipld/go-ipld-prime/node/basic" + "github.com/ipfs/boxo/files" cmds "github.com/ipfs/go-ipfs-cmds" ipld "github.com/ipfs/go-ipld-format" - "github.com/ipfs/go-libipfs/files" mc "github.com/multiformats/go-multicodec" // Expected minimal set of available format/ienc codecs. diff --git a/core/commands/dag/resolve.go b/core/commands/dag/resolve.go index 9b5ae2ccd..0f252be9d 100644 --- a/core/commands/dag/resolve.go +++ b/core/commands/dag/resolve.go @@ -1,7 +1,7 @@ package dagcmd import ( - "github.com/ipfs/interface-go-ipfs-core/path" + "github.com/ipfs/boxo/coreiface/path" "github.com/ipfs/kubo/core/commands/cmdenv" cmds "github.com/ipfs/go-ipfs-cmds" diff --git a/core/commands/dag/stat.go b/core/commands/dag/stat.go index fa573f57d..b4617a5b5 100644 --- a/core/commands/dag/stat.go +++ b/core/commands/dag/stat.go @@ -5,13 +5,13 @@ import ( "io" "os" - "github.com/ipfs/go-merkledag/traverse" - "github.com/ipfs/interface-go-ipfs-core/path" + "github.com/ipfs/boxo/coreiface/path" + "github.com/ipfs/boxo/ipld/merkledag/traverse" "github.com/ipfs/kubo/core/commands/cmdenv" "github.com/ipfs/kubo/core/commands/e" + mdag "github.com/ipfs/boxo/ipld/merkledag" cmds "github.com/ipfs/go-ipfs-cmds" - mdag "github.com/ipfs/go-merkledag" ) func dagStat(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { diff --git a/core/commands/dht_test.go b/core/commands/dht_test.go index 5c027a2f4..961d906ab 100644 --- a/core/commands/dht_test.go +++ b/core/commands/dht_test.go @@ -3,9 +3,9 @@ package commands import ( "testing" - "github.com/ipfs/go-namesys" + "github.com/ipfs/boxo/namesys" - ipns "github.com/ipfs/go-ipns" + ipns "github.com/ipfs/boxo/ipns" "github.com/libp2p/go-libp2p/core/test" ) diff --git a/core/commands/dns.go b/core/commands/dns.go index 81854e1c1..fda0cb6c3 100644 --- a/core/commands/dns.go +++ b/core/commands/dns.go @@ -4,8 +4,8 @@ import ( "fmt" "io" - namesys "github.com/ipfs/go-namesys" - nsopts "github.com/ipfs/interface-go-ipfs-core/options/namesys" + nsopts "github.com/ipfs/boxo/coreiface/options/namesys" + namesys "github.com/ipfs/boxo/namesys" cmdenv "github.com/ipfs/kubo/core/commands/cmdenv" ncmd "github.com/ipfs/kubo/core/commands/name" diff --git a/core/commands/files.go b/core/commands/files.go index bba14a1e1..9c0c6e5a9 100644 --- a/core/commands/files.go +++ b/core/commands/files.go @@ -14,18 +14,18 @@ import ( "github.com/ipfs/kubo/core" "github.com/ipfs/kubo/core/commands/cmdenv" - bservice "github.com/ipfs/go-blockservice" + bservice "github.com/ipfs/boxo/blockservice" + iface "github.com/ipfs/boxo/coreiface" + path "github.com/ipfs/boxo/coreiface/path" + offline "github.com/ipfs/boxo/exchange/offline" + dag "github.com/ipfs/boxo/ipld/merkledag" + ft "github.com/ipfs/boxo/ipld/unixfs" + mfs "github.com/ipfs/boxo/mfs" cid "github.com/ipfs/go-cid" cidenc "github.com/ipfs/go-cidutil/cidenc" cmds "github.com/ipfs/go-ipfs-cmds" - offline "github.com/ipfs/go-ipfs-exchange-offline" ipld "github.com/ipfs/go-ipld-format" logging "github.com/ipfs/go-log" - dag "github.com/ipfs/go-merkledag" - mfs "github.com/ipfs/go-mfs" - ft "github.com/ipfs/go-unixfs" - iface "github.com/ipfs/interface-go-ipfs-core" - path "github.com/ipfs/interface-go-ipfs-core/path" mh "github.com/multiformats/go-multihash" ) diff --git a/core/commands/filestore.go b/core/commands/filestore.go index 7a271526b..0c9dbee0a 100644 --- a/core/commands/filestore.go +++ b/core/commands/filestore.go @@ -6,7 +6,7 @@ import ( "io" "os" - filestore "github.com/ipfs/go-filestore" + filestore "github.com/ipfs/boxo/filestore" cmds "github.com/ipfs/go-ipfs-cmds" core "github.com/ipfs/kubo/core" cmdenv "github.com/ipfs/kubo/core/commands/cmdenv" diff --git a/core/commands/get.go b/core/commands/get.go index e5648b28f..35cd45c9d 100644 --- a/core/commands/get.go +++ b/core/commands/get.go @@ -15,10 +15,10 @@ import ( "github.com/ipfs/kubo/core/commands/e" "github.com/cheggaaa/pb" + "github.com/ipfs/boxo/coreiface/path" + "github.com/ipfs/boxo/files" + "github.com/ipfs/boxo/tar" cmds "github.com/ipfs/go-ipfs-cmds" - "github.com/ipfs/go-libipfs/files" - "github.com/ipfs/go-libipfs/tar" - "github.com/ipfs/interface-go-ipfs-core/path" ) var ErrInvalidCompressionLevel = errors.New("compression level must be between 1 and 9") diff --git a/core/commands/keystore.go b/core/commands/keystore.go index f530d5eda..ed0d5d4e9 100644 --- a/core/commands/keystore.go +++ b/core/commands/keystore.go @@ -12,9 +12,9 @@ import ( "strings" "text/tabwriter" + options "github.com/ipfs/boxo/coreiface/options" + keystore "github.com/ipfs/boxo/keystore" cmds "github.com/ipfs/go-ipfs-cmds" - keystore "github.com/ipfs/go-ipfs-keystore" - options "github.com/ipfs/interface-go-ipfs-core/options" oldcmds "github.com/ipfs/kubo/commands" config "github.com/ipfs/kubo/config" cmdenv "github.com/ipfs/kubo/core/commands/cmdenv" diff --git a/core/commands/ls.go b/core/commands/ls.go index a8d01a594..10d378562 100644 --- a/core/commands/ls.go +++ b/core/commands/ls.go @@ -9,12 +9,12 @@ import ( cmdenv "github.com/ipfs/kubo/core/commands/cmdenv" + iface "github.com/ipfs/boxo/coreiface" + options "github.com/ipfs/boxo/coreiface/options" + path "github.com/ipfs/boxo/coreiface/path" + unixfs "github.com/ipfs/boxo/ipld/unixfs" + unixfs_pb "github.com/ipfs/boxo/ipld/unixfs/pb" cmds "github.com/ipfs/go-ipfs-cmds" - unixfs "github.com/ipfs/go-unixfs" - unixfs_pb "github.com/ipfs/go-unixfs/pb" - iface "github.com/ipfs/interface-go-ipfs-core" - options "github.com/ipfs/interface-go-ipfs-core/options" - path "github.com/ipfs/interface-go-ipfs-core/path" ) // LsLink contains printable data for a single ipld link in ls output diff --git a/core/commands/name/ipns.go b/core/commands/name/ipns.go index 3c6935331..8c2b755d5 100644 --- a/core/commands/name/ipns.go +++ b/core/commands/name/ipns.go @@ -7,14 +7,14 @@ import ( "strings" "time" - namesys "github.com/ipfs/go-namesys" + namesys "github.com/ipfs/boxo/namesys" cmdenv "github.com/ipfs/kubo/core/commands/cmdenv" + options "github.com/ipfs/boxo/coreiface/options" + nsopts "github.com/ipfs/boxo/coreiface/options/namesys" + path "github.com/ipfs/boxo/path" cmds "github.com/ipfs/go-ipfs-cmds" logging "github.com/ipfs/go-log" - path "github.com/ipfs/go-path" - options "github.com/ipfs/interface-go-ipfs-core/options" - nsopts "github.com/ipfs/interface-go-ipfs-core/options/namesys" ) var log = logging.Logger("core/commands/ipns") diff --git a/core/commands/name/name.go b/core/commands/name/name.go index 0e4fa6cb5..75512e8f3 100644 --- a/core/commands/name/name.go +++ b/core/commands/name/name.go @@ -10,9 +10,9 @@ import ( "time" "github.com/gogo/protobuf/proto" + "github.com/ipfs/boxo/ipns" + ipns_pb "github.com/ipfs/boxo/ipns/pb" cmds "github.com/ipfs/go-ipfs-cmds" - "github.com/ipfs/go-ipns" - ipns_pb "github.com/ipfs/go-ipns/pb" cmdenv "github.com/ipfs/kubo/core/commands/cmdenv" "github.com/ipld/go-ipld-prime" "github.com/ipld/go-ipld-prime/codec/dagcbor" diff --git a/core/commands/name/publish.go b/core/commands/name/publish.go index 3619a23d5..b104aaeb5 100644 --- a/core/commands/name/publish.go +++ b/core/commands/name/publish.go @@ -8,10 +8,10 @@ import ( cmdenv "github.com/ipfs/kubo/core/commands/cmdenv" + iface "github.com/ipfs/boxo/coreiface" + options "github.com/ipfs/boxo/coreiface/options" + path "github.com/ipfs/boxo/coreiface/path" cmds "github.com/ipfs/go-ipfs-cmds" - iface "github.com/ipfs/interface-go-ipfs-core" - options "github.com/ipfs/interface-go-ipfs-core/options" - path "github.com/ipfs/interface-go-ipfs-core/path" ke "github.com/ipfs/kubo/core/commands/keyencode" peer "github.com/libp2p/go-libp2p/core/peer" ) diff --git a/core/commands/object/diff.go b/core/commands/object/diff.go index 8d3caafc5..fca026ac1 100644 --- a/core/commands/object/diff.go +++ b/core/commands/object/diff.go @@ -4,9 +4,9 @@ import ( "fmt" "io" + path "github.com/ipfs/boxo/coreiface/path" + "github.com/ipfs/boxo/ipld/merkledag/dagutils" cmds "github.com/ipfs/go-ipfs-cmds" - "github.com/ipfs/go-merkledag/dagutils" - path "github.com/ipfs/interface-go-ipfs-core/path" cmdenv "github.com/ipfs/kubo/core/commands/cmdenv" ) diff --git a/core/commands/object/object.go b/core/commands/object/object.go index 44864d046..febcf3470 100644 --- a/core/commands/object/object.go +++ b/core/commands/object/object.go @@ -11,11 +11,11 @@ import ( "github.com/ipfs/kubo/core/commands/cmdenv" humanize "github.com/dustin/go-humanize" + "github.com/ipfs/boxo/coreiface/options" + path "github.com/ipfs/boxo/coreiface/path" + dag "github.com/ipfs/boxo/ipld/merkledag" "github.com/ipfs/go-cid" ipld "github.com/ipfs/go-ipld-format" - dag "github.com/ipfs/go-merkledag" - "github.com/ipfs/interface-go-ipfs-core/options" - path "github.com/ipfs/interface-go-ipfs-core/path" ) type Node struct { diff --git a/core/commands/object/patch.go b/core/commands/object/patch.go index 6368562bc..8ec5b3516 100644 --- a/core/commands/object/patch.go +++ b/core/commands/object/patch.go @@ -8,8 +8,8 @@ import ( "github.com/ipfs/kubo/core/commands/cmdenv" "github.com/ipfs/kubo/core/commands/cmdutils" - "github.com/ipfs/interface-go-ipfs-core/options" - "github.com/ipfs/interface-go-ipfs-core/path" + "github.com/ipfs/boxo/coreiface/options" + "github.com/ipfs/boxo/coreiface/path" ) var ObjectPatchCmd = &cmds.Command{ diff --git a/core/commands/pin/pin.go b/core/commands/pin/pin.go index 89e56f687..6650fb93d 100644 --- a/core/commands/pin/pin.go +++ b/core/commands/pin/pin.go @@ -8,16 +8,16 @@ import ( "os" "time" - bserv "github.com/ipfs/go-blockservice" + bserv "github.com/ipfs/boxo/blockservice" + coreiface "github.com/ipfs/boxo/coreiface" + options "github.com/ipfs/boxo/coreiface/options" + "github.com/ipfs/boxo/coreiface/path" + offline "github.com/ipfs/boxo/exchange/offline" + dag "github.com/ipfs/boxo/ipld/merkledag" + verifcid "github.com/ipfs/boxo/verifcid" cid "github.com/ipfs/go-cid" cidenc "github.com/ipfs/go-cidutil/cidenc" cmds "github.com/ipfs/go-ipfs-cmds" - offline "github.com/ipfs/go-ipfs-exchange-offline" - dag "github.com/ipfs/go-merkledag" - verifcid "github.com/ipfs/go-verifcid" - coreiface "github.com/ipfs/interface-go-ipfs-core" - options "github.com/ipfs/interface-go-ipfs-core/options" - "github.com/ipfs/interface-go-ipfs-core/path" core "github.com/ipfs/kubo/core" cmdenv "github.com/ipfs/kubo/core/commands/cmdenv" diff --git a/core/commands/pin/remotepin.go b/core/commands/pin/remotepin.go index 95b17a315..bbec1a73d 100644 --- a/core/commands/pin/remotepin.go +++ b/core/commands/pin/remotepin.go @@ -15,11 +15,11 @@ import ( "golang.org/x/sync/errgroup" + path "github.com/ipfs/boxo/coreiface/path" + pinclient "github.com/ipfs/boxo/pinning/remote/client" cid "github.com/ipfs/go-cid" cmds "github.com/ipfs/go-ipfs-cmds" logging "github.com/ipfs/go-log" - pinclient "github.com/ipfs/go-pinning-service-http-client" - path "github.com/ipfs/interface-go-ipfs-core/path" config "github.com/ipfs/kubo/config" "github.com/ipfs/kubo/core/commands/cmdenv" fsrepo "github.com/ipfs/kubo/repo/fsrepo" diff --git a/core/commands/pubsub.go b/core/commands/pubsub.go index ee795e078..aadc681d9 100644 --- a/core/commands/pubsub.go +++ b/core/commands/pubsub.go @@ -11,8 +11,8 @@ import ( mbase "github.com/multiformats/go-multibase" "github.com/pkg/errors" + options "github.com/ipfs/boxo/coreiface/options" cmds "github.com/ipfs/go-ipfs-cmds" - options "github.com/ipfs/interface-go-ipfs-core/options" ) var PubsubCmd = &cmds.Command{ diff --git a/core/commands/refs.go b/core/commands/refs.go index 81c13cbda..de5206a65 100644 --- a/core/commands/refs.go +++ b/core/commands/refs.go @@ -9,13 +9,13 @@ import ( cmdenv "github.com/ipfs/kubo/core/commands/cmdenv" + iface "github.com/ipfs/boxo/coreiface" + path "github.com/ipfs/boxo/coreiface/path" + merkledag "github.com/ipfs/boxo/ipld/merkledag" cid "github.com/ipfs/go-cid" cidenc "github.com/ipfs/go-cidutil/cidenc" cmds "github.com/ipfs/go-ipfs-cmds" ipld "github.com/ipfs/go-ipld-format" - merkledag "github.com/ipfs/go-merkledag" - iface "github.com/ipfs/interface-go-ipfs-core" - path "github.com/ipfs/interface-go-ipfs-core/path" ) var refsEncoderMap = cmds.EncoderMap{ diff --git a/core/commands/repo.go b/core/commands/repo.go index 5c4c7b947..1f4df327a 100644 --- a/core/commands/repo.go +++ b/core/commands/repo.go @@ -19,8 +19,8 @@ import ( "github.com/ipfs/kubo/repo/fsrepo/migrations/ipfsfetcher" humanize "github.com/dustin/go-humanize" + bstore "github.com/ipfs/boxo/blockstore" cid "github.com/ipfs/go-cid" - bstore "github.com/ipfs/go-ipfs-blockstore" cmds "github.com/ipfs/go-ipfs-cmds" ) diff --git a/core/commands/resolve.go b/core/commands/resolve.go index 3bdd6924e..38de57b21 100644 --- a/core/commands/resolve.go +++ b/core/commands/resolve.go @@ -7,16 +7,16 @@ import ( "strings" "time" - ns "github.com/ipfs/go-namesys" + ns "github.com/ipfs/boxo/namesys" cmdenv "github.com/ipfs/kubo/core/commands/cmdenv" ncmd "github.com/ipfs/kubo/core/commands/name" + options "github.com/ipfs/boxo/coreiface/options" + nsopts "github.com/ipfs/boxo/coreiface/options/namesys" + path "github.com/ipfs/boxo/coreiface/path" + ipfspath "github.com/ipfs/boxo/path" cidenc "github.com/ipfs/go-cidutil/cidenc" cmds "github.com/ipfs/go-ipfs-cmds" - ipfspath "github.com/ipfs/go-path" - options "github.com/ipfs/interface-go-ipfs-core/options" - nsopts "github.com/ipfs/interface-go-ipfs-core/options/namesys" - path "github.com/ipfs/interface-go-ipfs-core/path" ) const ( diff --git a/core/commands/routing.go b/core/commands/routing.go index 460abb97a..2d578fcb6 100644 --- a/core/commands/routing.go +++ b/core/commands/routing.go @@ -10,11 +10,11 @@ import ( cmdenv "github.com/ipfs/kubo/core/commands/cmdenv" + dag "github.com/ipfs/boxo/ipld/merkledag" + path "github.com/ipfs/boxo/path" cid "github.com/ipfs/go-cid" cmds "github.com/ipfs/go-ipfs-cmds" ipld "github.com/ipfs/go-ipld-format" - dag "github.com/ipfs/go-merkledag" - path "github.com/ipfs/go-path" peer "github.com/libp2p/go-libp2p/core/peer" routing "github.com/libp2p/go-libp2p/core/routing" ) diff --git a/core/commands/stat_provide.go b/core/commands/stat_provide.go index e192944d6..f93f73cb4 100644 --- a/core/commands/stat_provide.go +++ b/core/commands/stat_provide.go @@ -10,7 +10,7 @@ import ( cmds "github.com/ipfs/go-ipfs-cmds" "github.com/ipfs/kubo/core/commands/cmdenv" - "github.com/ipfs/go-ipfs-provider/batched" + "github.com/ipfs/boxo/provider/batched" ) var statProvideCmd = &cmds.Command{ diff --git a/core/commands/tar.go b/core/commands/tar.go index eaec9ab68..50bd67943 100644 --- a/core/commands/tar.go +++ b/core/commands/tar.go @@ -8,8 +8,8 @@ import ( "github.com/ipfs/kubo/core/commands/cmdenv" tar "github.com/ipfs/kubo/tar" - dag "github.com/ipfs/go-merkledag" - path "github.com/ipfs/interface-go-ipfs-core/path" + path "github.com/ipfs/boxo/coreiface/path" + dag "github.com/ipfs/boxo/ipld/merkledag" ) var TarCmd = &cmds.Command{ diff --git a/core/commands/unixfs/ls.go b/core/commands/unixfs/ls.go index dc4221eb6..120b76034 100644 --- a/core/commands/unixfs/ls.go +++ b/core/commands/unixfs/ls.go @@ -8,10 +8,10 @@ import ( cmdenv "github.com/ipfs/kubo/core/commands/cmdenv" + path "github.com/ipfs/boxo/coreiface/path" + merkledag "github.com/ipfs/boxo/ipld/merkledag" + unixfs "github.com/ipfs/boxo/ipld/unixfs" cmds "github.com/ipfs/go-ipfs-cmds" - merkledag "github.com/ipfs/go-merkledag" - unixfs "github.com/ipfs/go-unixfs" - path "github.com/ipfs/interface-go-ipfs-core/path" ) type LsLink struct { diff --git a/core/commands/urlstore.go b/core/commands/urlstore.go index b17dc713a..4eec85ede 100644 --- a/core/commands/urlstore.go +++ b/core/commands/urlstore.go @@ -5,12 +5,12 @@ import ( "io" "net/url" - filestore "github.com/ipfs/go-filestore" + filestore "github.com/ipfs/boxo/filestore" cmdenv "github.com/ipfs/kubo/core/commands/cmdenv" + "github.com/ipfs/boxo/coreiface/options" + "github.com/ipfs/boxo/files" cmds "github.com/ipfs/go-ipfs-cmds" - "github.com/ipfs/go-libipfs/files" - "github.com/ipfs/interface-go-ipfs-core/options" ) var urlStoreCmd = &cmds.Command{ diff --git a/core/core.go b/core/core.go index 9e515b816..8aeeaaef6 100644 --- a/core/core.go +++ b/core/core.go @@ -13,18 +13,18 @@ import ( "context" "io" - "github.com/ipfs/go-filestore" - pin "github.com/ipfs/go-ipfs-pinner" + "github.com/ipfs/boxo/filestore" + pin "github.com/ipfs/boxo/pinning/pinner" - bserv "github.com/ipfs/go-blockservice" - "github.com/ipfs/go-fetcher" + bserv "github.com/ipfs/boxo/blockservice" + bstore "github.com/ipfs/boxo/blockstore" + exchange "github.com/ipfs/boxo/exchange" + "github.com/ipfs/boxo/fetcher" + mfs "github.com/ipfs/boxo/mfs" + provider "github.com/ipfs/boxo/provider" "github.com/ipfs/go-graphsync" - bstore "github.com/ipfs/go-ipfs-blockstore" - exchange "github.com/ipfs/go-ipfs-exchange-interface" - provider "github.com/ipfs/go-ipfs-provider" ipld "github.com/ipfs/go-ipld-format" logging "github.com/ipfs/go-log" - mfs "github.com/ipfs/go-mfs" goprocess "github.com/jbenet/goprocess" ddht "github.com/libp2p/go-libp2p-kad-dht/dual" pubsub "github.com/libp2p/go-libp2p-pubsub" @@ -43,8 +43,8 @@ import ( ma "github.com/multiformats/go-multiaddr" madns "github.com/multiformats/go-multiaddr-dns" - "github.com/ipfs/go-namesys" - ipnsrp "github.com/ipfs/go-namesys/republisher" + "github.com/ipfs/boxo/namesys" + ipnsrp "github.com/ipfs/boxo/namesys/republisher" "github.com/ipfs/kubo/core/bootstrap" "github.com/ipfs/kubo/core/node" "github.com/ipfs/kubo/core/node/libp2p" diff --git a/core/core_test.go b/core/core_test.go index 1d0703de0..5e8c1336c 100644 --- a/core/core_test.go +++ b/core/core_test.go @@ -11,9 +11,9 @@ import ( context "context" + "github.com/ipfs/boxo/ipns" "github.com/ipfs/go-cid" "github.com/ipfs/go-delegated-routing/client" - "github.com/ipfs/go-ipns" "github.com/ipfs/kubo/core/node/libp2p" "github.com/ipfs/kubo/repo" "github.com/libp2p/go-libp2p/core/crypto" diff --git a/core/coreapi/block.go b/core/coreapi/block.go index 450f06f3b..55810de7e 100644 --- a/core/coreapi/block.go +++ b/core/coreapi/block.go @@ -6,12 +6,12 @@ import ( "errors" "io" + coreiface "github.com/ipfs/boxo/coreiface" + caopts "github.com/ipfs/boxo/coreiface/options" + path "github.com/ipfs/boxo/coreiface/path" + pin "github.com/ipfs/boxo/pinning/pinner" + blocks "github.com/ipfs/go-block-format" cid "github.com/ipfs/go-cid" - pin "github.com/ipfs/go-ipfs-pinner" - blocks "github.com/ipfs/go-libipfs/blocks" - coreiface "github.com/ipfs/interface-go-ipfs-core" - caopts "github.com/ipfs/interface-go-ipfs-core/options" - path "github.com/ipfs/interface-go-ipfs-core/path" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" diff --git a/core/coreapi/coreapi.go b/core/coreapi/coreapi.go index 85bd60c12..c58c67f6b 100644 --- a/core/coreapi/coreapi.go +++ b/core/coreapi/coreapi.go @@ -18,18 +18,18 @@ import ( "errors" "fmt" - bserv "github.com/ipfs/go-blockservice" - "github.com/ipfs/go-fetcher" - blockstore "github.com/ipfs/go-ipfs-blockstore" - exchange "github.com/ipfs/go-ipfs-exchange-interface" - offlinexch "github.com/ipfs/go-ipfs-exchange-offline" - pin "github.com/ipfs/go-ipfs-pinner" - provider "github.com/ipfs/go-ipfs-provider" - offlineroute "github.com/ipfs/go-ipfs-routing/offline" + bserv "github.com/ipfs/boxo/blockservice" + blockstore "github.com/ipfs/boxo/blockstore" + coreiface "github.com/ipfs/boxo/coreiface" + "github.com/ipfs/boxo/coreiface/options" + exchange "github.com/ipfs/boxo/exchange" + offlinexch "github.com/ipfs/boxo/exchange/offline" + "github.com/ipfs/boxo/fetcher" + dag "github.com/ipfs/boxo/ipld/merkledag" + pin "github.com/ipfs/boxo/pinning/pinner" + provider "github.com/ipfs/boxo/provider" + offlineroute "github.com/ipfs/boxo/routing/offline" ipld "github.com/ipfs/go-ipld-format" - dag "github.com/ipfs/go-merkledag" - coreiface "github.com/ipfs/interface-go-ipfs-core" - "github.com/ipfs/interface-go-ipfs-core/options" pubsub "github.com/libp2p/go-libp2p-pubsub" record "github.com/libp2p/go-libp2p-record" ci "github.com/libp2p/go-libp2p/core/crypto" @@ -39,7 +39,7 @@ import ( routing "github.com/libp2p/go-libp2p/core/routing" madns "github.com/multiformats/go-multiaddr-dns" - "github.com/ipfs/go-namesys" + "github.com/ipfs/boxo/namesys" "github.com/ipfs/kubo/core" "github.com/ipfs/kubo/core/node" "github.com/ipfs/kubo/repo" diff --git a/core/coreapi/dag.go b/core/coreapi/dag.go index b352a2d3f..c4d0dc9d2 100644 --- a/core/coreapi/dag.go +++ b/core/coreapi/dag.go @@ -3,10 +3,10 @@ package coreapi import ( "context" + dag "github.com/ipfs/boxo/ipld/merkledag" + pin "github.com/ipfs/boxo/pinning/pinner" cid "github.com/ipfs/go-cid" - pin "github.com/ipfs/go-ipfs-pinner" ipld "github.com/ipfs/go-ipld-format" - dag "github.com/ipfs/go-merkledag" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" diff --git a/core/coreapi/dht.go b/core/coreapi/dht.go index 3691a16c6..4feb8a76c 100644 --- a/core/coreapi/dht.go +++ b/core/coreapi/dht.go @@ -4,15 +4,15 @@ import ( "context" "fmt" - blockservice "github.com/ipfs/go-blockservice" + blockservice "github.com/ipfs/boxo/blockservice" + blockstore "github.com/ipfs/boxo/blockstore" + coreiface "github.com/ipfs/boxo/coreiface" + caopts "github.com/ipfs/boxo/coreiface/options" + path "github.com/ipfs/boxo/coreiface/path" + offline "github.com/ipfs/boxo/exchange/offline" + dag "github.com/ipfs/boxo/ipld/merkledag" cid "github.com/ipfs/go-cid" cidutil "github.com/ipfs/go-cidutil" - blockstore "github.com/ipfs/go-ipfs-blockstore" - offline "github.com/ipfs/go-ipfs-exchange-offline" - dag "github.com/ipfs/go-merkledag" - coreiface "github.com/ipfs/interface-go-ipfs-core" - caopts "github.com/ipfs/interface-go-ipfs-core/options" - path "github.com/ipfs/interface-go-ipfs-core/path" "github.com/ipfs/kubo/tracing" peer "github.com/libp2p/go-libp2p/core/peer" routing "github.com/libp2p/go-libp2p/core/routing" diff --git a/core/coreapi/key.go b/core/coreapi/key.go index 903659bb9..925748a37 100644 --- a/core/coreapi/key.go +++ b/core/coreapi/key.go @@ -7,10 +7,10 @@ import ( "fmt" "sort" - ipfspath "github.com/ipfs/go-path" - coreiface "github.com/ipfs/interface-go-ipfs-core" - caopts "github.com/ipfs/interface-go-ipfs-core/options" - path "github.com/ipfs/interface-go-ipfs-core/path" + coreiface "github.com/ipfs/boxo/coreiface" + caopts "github.com/ipfs/boxo/coreiface/options" + path "github.com/ipfs/boxo/coreiface/path" + ipfspath "github.com/ipfs/boxo/path" "github.com/ipfs/kubo/tracing" crypto "github.com/libp2p/go-libp2p/core/crypto" peer "github.com/libp2p/go-libp2p/core/peer" diff --git a/core/coreapi/name.go b/core/coreapi/name.go index 87af34af4..f07cfcd0c 100644 --- a/core/coreapi/name.go +++ b/core/coreapi/name.go @@ -6,17 +6,17 @@ import ( "strings" "time" - keystore "github.com/ipfs/go-ipfs-keystore" - "github.com/ipfs/go-namesys" + keystore "github.com/ipfs/boxo/keystore" + "github.com/ipfs/boxo/namesys" "github.com/ipfs/kubo/tracing" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" - ipath "github.com/ipfs/go-path" - coreiface "github.com/ipfs/interface-go-ipfs-core" - caopts "github.com/ipfs/interface-go-ipfs-core/options" - nsopts "github.com/ipfs/interface-go-ipfs-core/options/namesys" - path "github.com/ipfs/interface-go-ipfs-core/path" + coreiface "github.com/ipfs/boxo/coreiface" + caopts "github.com/ipfs/boxo/coreiface/options" + nsopts "github.com/ipfs/boxo/coreiface/options/namesys" + path "github.com/ipfs/boxo/coreiface/path" + ipath "github.com/ipfs/boxo/path" ci "github.com/libp2p/go-libp2p/core/crypto" peer "github.com/libp2p/go-libp2p/core/peer" ) diff --git a/core/coreapi/object.go b/core/coreapi/object.go index 4b509c782..1b1caea65 100644 --- a/core/coreapi/object.go +++ b/core/coreapi/object.go @@ -10,15 +10,15 @@ import ( "fmt" "io" + coreiface "github.com/ipfs/boxo/coreiface" + caopts "github.com/ipfs/boxo/coreiface/options" + ipath "github.com/ipfs/boxo/coreiface/path" + dag "github.com/ipfs/boxo/ipld/merkledag" + "github.com/ipfs/boxo/ipld/merkledag/dagutils" + ft "github.com/ipfs/boxo/ipld/unixfs" + pin "github.com/ipfs/boxo/pinning/pinner" cid "github.com/ipfs/go-cid" - pin "github.com/ipfs/go-ipfs-pinner" ipld "github.com/ipfs/go-ipld-format" - dag "github.com/ipfs/go-merkledag" - "github.com/ipfs/go-merkledag/dagutils" - ft "github.com/ipfs/go-unixfs" - coreiface "github.com/ipfs/interface-go-ipfs-core" - caopts "github.com/ipfs/interface-go-ipfs-core/options" - ipath "github.com/ipfs/interface-go-ipfs-core/path" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" diff --git a/core/coreapi/path.go b/core/coreapi/path.go index c890ade6e..099f192a1 100644 --- a/core/coreapi/path.go +++ b/core/coreapi/path.go @@ -5,19 +5,19 @@ import ( "fmt" gopath "path" - "github.com/ipfs/go-namesys/resolve" + "github.com/ipfs/boxo/namesys/resolve" "github.com/ipfs/kubo/tracing" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" + coreiface "github.com/ipfs/boxo/coreiface" + path "github.com/ipfs/boxo/coreiface/path" + "github.com/ipfs/boxo/fetcher" + ipfspath "github.com/ipfs/boxo/path" + ipfspathresolver "github.com/ipfs/boxo/path/resolver" "github.com/ipfs/go-cid" - "github.com/ipfs/go-fetcher" ipld "github.com/ipfs/go-ipld-format" - ipfspath "github.com/ipfs/go-path" - ipfspathresolver "github.com/ipfs/go-path/resolver" - coreiface "github.com/ipfs/interface-go-ipfs-core" - path "github.com/ipfs/interface-go-ipfs-core/path" ) // ResolveNode resolves the path `p` using Unixfs resolver, gets and returns the diff --git a/core/coreapi/pin.go b/core/coreapi/pin.go index 41327c8c3..4aea8dfd3 100644 --- a/core/coreapi/pin.go +++ b/core/coreapi/pin.go @@ -4,14 +4,14 @@ import ( "context" "fmt" - bserv "github.com/ipfs/go-blockservice" + bserv "github.com/ipfs/boxo/blockservice" + coreiface "github.com/ipfs/boxo/coreiface" + caopts "github.com/ipfs/boxo/coreiface/options" + "github.com/ipfs/boxo/coreiface/path" + offline "github.com/ipfs/boxo/exchange/offline" + "github.com/ipfs/boxo/ipld/merkledag" + pin "github.com/ipfs/boxo/pinning/pinner" "github.com/ipfs/go-cid" - offline "github.com/ipfs/go-ipfs-exchange-offline" - pin "github.com/ipfs/go-ipfs-pinner" - "github.com/ipfs/go-merkledag" - coreiface "github.com/ipfs/interface-go-ipfs-core" - caopts "github.com/ipfs/interface-go-ipfs-core/options" - "github.com/ipfs/interface-go-ipfs-core/path" "github.com/ipfs/kubo/tracing" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" diff --git a/core/coreapi/pubsub.go b/core/coreapi/pubsub.go index af29afecc..9e180c149 100644 --- a/core/coreapi/pubsub.go +++ b/core/coreapi/pubsub.go @@ -4,8 +4,8 @@ import ( "context" "errors" - coreiface "github.com/ipfs/interface-go-ipfs-core" - caopts "github.com/ipfs/interface-go-ipfs-core/options" + coreiface "github.com/ipfs/boxo/coreiface" + caopts "github.com/ipfs/boxo/coreiface/options" "github.com/ipfs/kubo/tracing" pubsub "github.com/libp2p/go-libp2p-pubsub" peer "github.com/libp2p/go-libp2p/core/peer" diff --git a/core/coreapi/routing.go b/core/coreapi/routing.go index 78f21c429..76d969316 100644 --- a/core/coreapi/routing.go +++ b/core/coreapi/routing.go @@ -4,8 +4,8 @@ import ( "context" "errors" - "github.com/ipfs/go-path" - coreiface "github.com/ipfs/interface-go-ipfs-core" + coreiface "github.com/ipfs/boxo/coreiface" + "github.com/ipfs/boxo/path" peer "github.com/libp2p/go-libp2p/core/peer" ) diff --git a/core/coreapi/swarm.go b/core/coreapi/swarm.go index 2faa912d9..778a46e72 100644 --- a/core/coreapi/swarm.go +++ b/core/coreapi/swarm.go @@ -5,7 +5,7 @@ import ( "sort" "time" - coreiface "github.com/ipfs/interface-go-ipfs-core" + coreiface "github.com/ipfs/boxo/coreiface" "github.com/ipfs/kubo/tracing" inet "github.com/libp2p/go-libp2p/core/network" "github.com/libp2p/go-libp2p/core/peer" diff --git a/core/coreapi/test/api_test.go b/core/coreapi/test/api_test.go index 012aa8f8e..dafadcc1f 100644 --- a/core/coreapi/test/api_test.go +++ b/core/coreapi/test/api_test.go @@ -8,8 +8,8 @@ import ( "path/filepath" "testing" - "github.com/ipfs/go-filestore" - keystore "github.com/ipfs/go-ipfs-keystore" + "github.com/ipfs/boxo/filestore" + keystore "github.com/ipfs/boxo/keystore" "github.com/ipfs/kubo/core" "github.com/ipfs/kubo/core/bootstrap" "github.com/ipfs/kubo/core/coreapi" @@ -17,10 +17,10 @@ import ( "github.com/ipfs/kubo/core/node/libp2p" "github.com/ipfs/kubo/repo" + coreiface "github.com/ipfs/boxo/coreiface" + "github.com/ipfs/boxo/coreiface/tests" "github.com/ipfs/go-datastore" syncds "github.com/ipfs/go-datastore/sync" - coreiface "github.com/ipfs/interface-go-ipfs-core" - "github.com/ipfs/interface-go-ipfs-core/tests" "github.com/ipfs/kubo/config" "github.com/libp2p/go-libp2p/core/crypto" "github.com/libp2p/go-libp2p/core/peer" diff --git a/core/coreapi/test/path_test.go b/core/coreapi/test/path_test.go index acba1c47f..9f67f3c71 100644 --- a/core/coreapi/test/path_test.go +++ b/core/coreapi/test/path_test.go @@ -6,11 +6,11 @@ import ( "testing" "time" - "github.com/ipfs/go-libipfs/files" - "github.com/ipfs/go-merkledag" - uio "github.com/ipfs/go-unixfs/io" - "github.com/ipfs/interface-go-ipfs-core/options" - "github.com/ipfs/interface-go-ipfs-core/path" + "github.com/ipfs/boxo/coreiface/options" + "github.com/ipfs/boxo/coreiface/path" + "github.com/ipfs/boxo/files" + "github.com/ipfs/boxo/ipld/merkledag" + uio "github.com/ipfs/boxo/ipld/unixfs/io" "github.com/ipld/go-ipld-prime" ) diff --git a/core/coreapi/unixfs.go b/core/coreapi/unixfs.go index 7ab7d34d6..dd6db41fb 100644 --- a/core/coreapi/unixfs.go +++ b/core/coreapi/unixfs.go @@ -12,22 +12,22 @@ import ( "github.com/ipfs/kubo/core/coreunix" - blockservice "github.com/ipfs/go-blockservice" + blockservice "github.com/ipfs/boxo/blockservice" + bstore "github.com/ipfs/boxo/blockstore" + coreiface "github.com/ipfs/boxo/coreiface" + options "github.com/ipfs/boxo/coreiface/options" + path "github.com/ipfs/boxo/coreiface/path" + "github.com/ipfs/boxo/files" + filestore "github.com/ipfs/boxo/filestore" + merkledag "github.com/ipfs/boxo/ipld/merkledag" + dagtest "github.com/ipfs/boxo/ipld/merkledag/test" + ft "github.com/ipfs/boxo/ipld/unixfs" + unixfile "github.com/ipfs/boxo/ipld/unixfs/file" + uio "github.com/ipfs/boxo/ipld/unixfs/io" + mfs "github.com/ipfs/boxo/mfs" cid "github.com/ipfs/go-cid" cidutil "github.com/ipfs/go-cidutil" - filestore "github.com/ipfs/go-filestore" - bstore "github.com/ipfs/go-ipfs-blockstore" ipld "github.com/ipfs/go-ipld-format" - "github.com/ipfs/go-libipfs/files" - merkledag "github.com/ipfs/go-merkledag" - dagtest "github.com/ipfs/go-merkledag/test" - mfs "github.com/ipfs/go-mfs" - ft "github.com/ipfs/go-unixfs" - unixfile "github.com/ipfs/go-unixfs/file" - uio "github.com/ipfs/go-unixfs/io" - coreiface "github.com/ipfs/interface-go-ipfs-core" - options "github.com/ipfs/interface-go-ipfs-core/options" - path "github.com/ipfs/interface-go-ipfs-core/path" ) type UnixfsAPI CoreAPI diff --git a/core/corehttp/commands.go b/core/corehttp/commands.go index 5d8399393..6a33a2b29 100644 --- a/core/corehttp/commands.go +++ b/core/corehttp/commands.go @@ -9,9 +9,9 @@ import ( "strconv" "strings" + path "github.com/ipfs/boxo/path" cmds "github.com/ipfs/go-ipfs-cmds" cmdsHttp "github.com/ipfs/go-ipfs-cmds/http" - path "github.com/ipfs/go-path" version "github.com/ipfs/kubo" oldcmds "github.com/ipfs/kubo/commands" config "github.com/ipfs/kubo/config" diff --git a/core/corehttp/gateway.go b/core/corehttp/gateway.go index b68aa7bda..fdc91ae4c 100644 --- a/core/corehttp/gateway.go +++ b/core/corehttp/gateway.go @@ -7,15 +7,15 @@ import ( "net" "net/http" + iface "github.com/ipfs/boxo/coreiface" + options "github.com/ipfs/boxo/coreiface/options" + nsopts "github.com/ipfs/boxo/coreiface/options/namesys" + "github.com/ipfs/boxo/coreiface/path" + "github.com/ipfs/boxo/files" + "github.com/ipfs/boxo/gateway" + "github.com/ipfs/boxo/namesys" + "github.com/ipfs/go-block-format" cid "github.com/ipfs/go-cid" - "github.com/ipfs/go-libipfs/blocks" - "github.com/ipfs/go-libipfs/files" - "github.com/ipfs/go-libipfs/gateway" - "github.com/ipfs/go-namesys" - iface "github.com/ipfs/interface-go-ipfs-core" - options "github.com/ipfs/interface-go-ipfs-core/options" - nsopts "github.com/ipfs/interface-go-ipfs-core/options/namesys" - "github.com/ipfs/interface-go-ipfs-core/path" version "github.com/ipfs/kubo" config "github.com/ipfs/kubo/config" core "github.com/ipfs/kubo/core" diff --git a/core/corehttp/gateway_test.go b/core/corehttp/gateway_test.go index 03b04350d..522d92f13 100644 --- a/core/corehttp/gateway_test.go +++ b/core/corehttp/gateway_test.go @@ -9,17 +9,17 @@ import ( "strings" "testing" - namesys "github.com/ipfs/go-namesys" + namesys "github.com/ipfs/boxo/namesys" version "github.com/ipfs/kubo" core "github.com/ipfs/kubo/core" "github.com/ipfs/kubo/core/coreapi" repo "github.com/ipfs/kubo/repo" + iface "github.com/ipfs/boxo/coreiface" + nsopts "github.com/ipfs/boxo/coreiface/options/namesys" + path "github.com/ipfs/boxo/path" datastore "github.com/ipfs/go-datastore" syncds "github.com/ipfs/go-datastore/sync" - path "github.com/ipfs/go-path" - iface "github.com/ipfs/interface-go-ipfs-core" - nsopts "github.com/ipfs/interface-go-ipfs-core/options/namesys" config "github.com/ipfs/kubo/config" ci "github.com/libp2p/go-libp2p/core/crypto" id "github.com/libp2p/go-libp2p/p2p/protocol/identify" diff --git a/core/corerepo/gc.go b/core/corerepo/gc.go index de3d16980..cf89587d6 100644 --- a/core/corerepo/gc.go +++ b/core/corerepo/gc.go @@ -11,9 +11,9 @@ import ( "github.com/ipfs/kubo/repo" "github.com/dustin/go-humanize" + "github.com/ipfs/boxo/mfs" "github.com/ipfs/go-cid" logging "github.com/ipfs/go-log" - "github.com/ipfs/go-mfs" ) var log = logging.Logger("corerepo") diff --git a/core/coreunix/add.go b/core/coreunix/add.go index d2c4c3dff..31a867b03 100644 --- a/core/coreunix/add.go +++ b/core/coreunix/add.go @@ -8,22 +8,22 @@ import ( gopath "path" "strconv" + bstore "github.com/ipfs/boxo/blockstore" + chunker "github.com/ipfs/boxo/chunker" + coreiface "github.com/ipfs/boxo/coreiface" + "github.com/ipfs/boxo/coreiface/path" + "github.com/ipfs/boxo/files" + posinfo "github.com/ipfs/boxo/filestore/posinfo" + dag "github.com/ipfs/boxo/ipld/merkledag" + "github.com/ipfs/boxo/ipld/unixfs" + "github.com/ipfs/boxo/ipld/unixfs/importer/balanced" + ihelper "github.com/ipfs/boxo/ipld/unixfs/importer/helpers" + "github.com/ipfs/boxo/ipld/unixfs/importer/trickle" + "github.com/ipfs/boxo/mfs" + pin "github.com/ipfs/boxo/pinning/pinner" "github.com/ipfs/go-cid" - bstore "github.com/ipfs/go-ipfs-blockstore" - chunker "github.com/ipfs/go-ipfs-chunker" - pin "github.com/ipfs/go-ipfs-pinner" - posinfo "github.com/ipfs/go-ipfs-posinfo" ipld "github.com/ipfs/go-ipld-format" - "github.com/ipfs/go-libipfs/files" logging "github.com/ipfs/go-log" - dag "github.com/ipfs/go-merkledag" - "github.com/ipfs/go-mfs" - "github.com/ipfs/go-unixfs" - "github.com/ipfs/go-unixfs/importer/balanced" - ihelper "github.com/ipfs/go-unixfs/importer/helpers" - "github.com/ipfs/go-unixfs/importer/trickle" - coreiface "github.com/ipfs/interface-go-ipfs-core" - "github.com/ipfs/interface-go-ipfs-core/path" "github.com/ipfs/kubo/tracing" ) diff --git a/core/coreunix/add_test.go b/core/coreunix/add_test.go index e64d41001..4560d9964 100644 --- a/core/coreunix/add_test.go +++ b/core/coreunix/add_test.go @@ -14,16 +14,16 @@ import ( "github.com/ipfs/kubo/gc" "github.com/ipfs/kubo/repo" - "github.com/ipfs/go-blockservice" + "github.com/ipfs/boxo/blockservice" + blockstore "github.com/ipfs/boxo/blockstore" + coreiface "github.com/ipfs/boxo/coreiface" + "github.com/ipfs/boxo/files" + pi "github.com/ipfs/boxo/filestore/posinfo" + dag "github.com/ipfs/boxo/ipld/merkledag" + blocks "github.com/ipfs/go-block-format" "github.com/ipfs/go-cid" "github.com/ipfs/go-datastore" syncds "github.com/ipfs/go-datastore/sync" - blockstore "github.com/ipfs/go-ipfs-blockstore" - pi "github.com/ipfs/go-ipfs-posinfo" - blocks "github.com/ipfs/go-libipfs/blocks" - "github.com/ipfs/go-libipfs/files" - dag "github.com/ipfs/go-merkledag" - coreiface "github.com/ipfs/interface-go-ipfs-core" config "github.com/ipfs/kubo/config" ) diff --git a/core/coreunix/metadata.go b/core/coreunix/metadata.go index 5454b213f..bed171efc 100644 --- a/core/coreunix/metadata.go +++ b/core/coreunix/metadata.go @@ -1,9 +1,9 @@ package coreunix import ( + dag "github.com/ipfs/boxo/ipld/merkledag" + ft "github.com/ipfs/boxo/ipld/unixfs" cid "github.com/ipfs/go-cid" - dag "github.com/ipfs/go-merkledag" - ft "github.com/ipfs/go-unixfs" core "github.com/ipfs/kubo/core" ) diff --git a/core/coreunix/metadata_test.go b/core/coreunix/metadata_test.go index f745ec5ff..b40f010db 100644 --- a/core/coreunix/metadata_test.go +++ b/core/coreunix/metadata_test.go @@ -6,20 +6,20 @@ import ( "io" "testing" - bserv "github.com/ipfs/go-blockservice" - merkledag "github.com/ipfs/go-merkledag" - ft "github.com/ipfs/go-unixfs" - importer "github.com/ipfs/go-unixfs/importer" - uio "github.com/ipfs/go-unixfs/io" + bserv "github.com/ipfs/boxo/blockservice" + merkledag "github.com/ipfs/boxo/ipld/merkledag" + ft "github.com/ipfs/boxo/ipld/unixfs" + importer "github.com/ipfs/boxo/ipld/unixfs/importer" + uio "github.com/ipfs/boxo/ipld/unixfs/io" core "github.com/ipfs/kubo/core" + bstore "github.com/ipfs/boxo/blockstore" + chunker "github.com/ipfs/boxo/chunker" + offline "github.com/ipfs/boxo/exchange/offline" + u "github.com/ipfs/boxo/util" cid "github.com/ipfs/go-cid" ds "github.com/ipfs/go-datastore" dssync "github.com/ipfs/go-datastore/sync" - bstore "github.com/ipfs/go-ipfs-blockstore" - chunker "github.com/ipfs/go-ipfs-chunker" - offline "github.com/ipfs/go-ipfs-exchange-offline" - u "github.com/ipfs/go-ipfs-util" ipld "github.com/ipfs/go-ipld-format" ) diff --git a/core/node/bitswap.go b/core/node/bitswap.go index f78703039..1c4c1df21 100644 --- a/core/node/bitswap.go +++ b/core/node/bitswap.go @@ -4,10 +4,10 @@ import ( "context" "time" - blockstore "github.com/ipfs/go-ipfs-blockstore" - exchange "github.com/ipfs/go-ipfs-exchange-interface" - "github.com/ipfs/go-libipfs/bitswap" - "github.com/ipfs/go-libipfs/bitswap/network" + "github.com/ipfs/boxo/bitswap" + "github.com/ipfs/boxo/bitswap/network" + blockstore "github.com/ipfs/boxo/blockstore" + exchange "github.com/ipfs/boxo/exchange" "github.com/ipfs/kubo/config" irouting "github.com/ipfs/kubo/routing" "github.com/libp2p/go-libp2p/core/host" diff --git a/core/node/core.go b/core/node/core.go index 8aed8b05e..76f44b521 100644 --- a/core/node/core.go +++ b/core/node/core.go @@ -4,20 +4,20 @@ import ( "context" "fmt" - "github.com/ipfs/go-blockservice" + "github.com/ipfs/boxo/blockservice" + blockstore "github.com/ipfs/boxo/blockstore" + exchange "github.com/ipfs/boxo/exchange" + "github.com/ipfs/boxo/fetcher" + bsfetcher "github.com/ipfs/boxo/fetcher/impl/blockservice" + "github.com/ipfs/boxo/filestore" + "github.com/ipfs/boxo/ipld/merkledag" + "github.com/ipfs/boxo/ipld/unixfs" + "github.com/ipfs/boxo/mfs" + pin "github.com/ipfs/boxo/pinning/pinner" + "github.com/ipfs/boxo/pinning/pinner/dspinner" "github.com/ipfs/go-cid" "github.com/ipfs/go-datastore" - "github.com/ipfs/go-fetcher" - bsfetcher "github.com/ipfs/go-fetcher/impl/blockservice" - "github.com/ipfs/go-filestore" - blockstore "github.com/ipfs/go-ipfs-blockstore" - exchange "github.com/ipfs/go-ipfs-exchange-interface" - pin "github.com/ipfs/go-ipfs-pinner" - "github.com/ipfs/go-ipfs-pinner/dspinner" format "github.com/ipfs/go-ipld-format" - "github.com/ipfs/go-merkledag" - "github.com/ipfs/go-mfs" - "github.com/ipfs/go-unixfs" "github.com/ipfs/go-unixfsnode" dagpb "github.com/ipld/go-codec-dagpb" "github.com/ipld/go-ipld-prime" diff --git a/core/node/graphsync.go b/core/node/graphsync.go index 548888d66..4425d66ff 100644 --- a/core/node/graphsync.go +++ b/core/node/graphsync.go @@ -1,11 +1,11 @@ package node import ( + blockstore "github.com/ipfs/boxo/blockstore" "github.com/ipfs/go-graphsync" gsimpl "github.com/ipfs/go-graphsync/impl" "github.com/ipfs/go-graphsync/network" "github.com/ipfs/go-graphsync/storeutil" - blockstore "github.com/ipfs/go-ipfs-blockstore" libp2p "github.com/libp2p/go-libp2p/core" "go.uber.org/fx" diff --git a/core/node/groups.go b/core/node/groups.go index 866204ce3..a18a6aa5f 100644 --- a/core/node/groups.go +++ b/core/node/groups.go @@ -7,11 +7,11 @@ import ( "time" "github.com/dustin/go-humanize" - blockstore "github.com/ipfs/go-ipfs-blockstore" - offline "github.com/ipfs/go-ipfs-exchange-offline" - util "github.com/ipfs/go-ipfs-util" + blockstore "github.com/ipfs/boxo/blockstore" + offline "github.com/ipfs/boxo/exchange/offline" + uio "github.com/ipfs/boxo/ipld/unixfs/io" + util "github.com/ipfs/boxo/util" "github.com/ipfs/go-log" - uio "github.com/ipfs/go-unixfs/io" "github.com/ipfs/kubo/config" "github.com/ipfs/kubo/core/node/libp2p" "github.com/ipfs/kubo/p2p" diff --git a/core/node/ipns.go b/core/node/ipns.go index 0500c7be4..b1b5ee6e0 100644 --- a/core/node/ipns.go +++ b/core/node/ipns.go @@ -4,15 +4,15 @@ import ( "fmt" "time" - util "github.com/ipfs/go-ipfs-util" - "github.com/ipfs/go-ipns" + "github.com/ipfs/boxo/ipns" + util "github.com/ipfs/boxo/util" record "github.com/libp2p/go-libp2p-record" "github.com/libp2p/go-libp2p/core/crypto" "github.com/libp2p/go-libp2p/core/peerstore" madns "github.com/multiformats/go-multiaddr-dns" - "github.com/ipfs/go-namesys" - "github.com/ipfs/go-namesys/republisher" + "github.com/ipfs/boxo/namesys" + "github.com/ipfs/boxo/namesys/republisher" "github.com/ipfs/kubo/repo" irouting "github.com/ipfs/kubo/routing" ) diff --git a/core/node/libp2p/routing.go b/core/node/libp2p/routing.go index f16fec5a1..8de3ed10a 100644 --- a/core/node/libp2p/routing.go +++ b/core/node/libp2p/routing.go @@ -8,8 +8,8 @@ import ( "time" "github.com/cenkalti/backoff/v4" + offroute "github.com/ipfs/boxo/routing/offline" ds "github.com/ipfs/go-datastore" - offroute "github.com/ipfs/go-ipfs-routing/offline" dht "github.com/libp2p/go-libp2p-kad-dht" ddht "github.com/libp2p/go-libp2p-kad-dht/dual" "github.com/libp2p/go-libp2p-kad-dht/fullrt" diff --git a/core/node/provider.go b/core/node/provider.go index 9110b41b2..58e74bdb3 100644 --- a/core/node/provider.go +++ b/core/node/provider.go @@ -5,12 +5,12 @@ import ( "fmt" "time" - "github.com/ipfs/go-fetcher" - pin "github.com/ipfs/go-ipfs-pinner" - provider "github.com/ipfs/go-ipfs-provider" - "github.com/ipfs/go-ipfs-provider/batched" - q "github.com/ipfs/go-ipfs-provider/queue" - "github.com/ipfs/go-ipfs-provider/simple" + "github.com/ipfs/boxo/fetcher" + pin "github.com/ipfs/boxo/pinning/pinner" + provider "github.com/ipfs/boxo/provider" + "github.com/ipfs/boxo/provider/batched" + q "github.com/ipfs/boxo/provider/queue" + "github.com/ipfs/boxo/provider/simple" "go.uber.org/fx" "github.com/ipfs/kubo/core/node/helpers" diff --git a/core/node/storage.go b/core/node/storage.go index d10921058..782ff58f0 100644 --- a/core/node/storage.go +++ b/core/node/storage.go @@ -1,12 +1,12 @@ package node import ( + blockstore "github.com/ipfs/boxo/blockstore" "github.com/ipfs/go-datastore" - blockstore "github.com/ipfs/go-ipfs-blockstore" config "github.com/ipfs/kubo/config" "go.uber.org/fx" - "github.com/ipfs/go-filestore" + "github.com/ipfs/boxo/filestore" "github.com/ipfs/kubo/core/node/helpers" "github.com/ipfs/kubo/repo" "github.com/ipfs/kubo/thirdparty/verifbs" diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 65d5d86da..bcbdf6d4b 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,8 +7,7 @@ go 1.18 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/go-libipfs v0.7.0 - github.com/ipfs/interface-go-ipfs-core v0.11.0 + github.com/ipfs/boxo v0.8.0-rc2 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.26.4 github.com/multiformats/go-multiaddr v0.8.0 @@ -23,7 +22,7 @@ require ( github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver/v4 v4.0.0 // indirect github.com/cenkalti/backoff v2.2.1+incompatible // indirect - github.com/cenkalti/backoff/v4 v4.1.3 // indirect + github.com/cenkalti/backoff/v4 v4.2.0 // indirect github.com/ceramicnetwork/go-dag-jose v0.1.0 // indirect github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect @@ -63,52 +62,34 @@ require ( github.com/huin/goupnp v1.0.3 // indirect github.com/ipfs/bbloom v0.0.4 // indirect github.com/ipfs/go-bitfield v1.1.0 // indirect - github.com/ipfs/go-block-format v0.1.1 // indirect - github.com/ipfs/go-blockservice v0.5.0 // indirect + github.com/ipfs/go-block-format v0.1.2 // indirect github.com/ipfs/go-cid v0.4.0 // indirect github.com/ipfs/go-cidutil v0.1.0 // indirect github.com/ipfs/go-datastore v0.6.0 // indirect - github.com/ipfs/go-delegated-routing v0.7.0 // indirect + github.com/ipfs/go-delegated-routing v0.8.0 // indirect github.com/ipfs/go-ds-badger v0.3.0 // indirect github.com/ipfs/go-ds-flatfs v0.5.1 // indirect github.com/ipfs/go-ds-leveldb v0.5.0 // indirect github.com/ipfs/go-ds-measure v0.2.0 // indirect - github.com/ipfs/go-fetcher v1.6.1 // indirect - github.com/ipfs/go-filestore v1.2.0 // indirect github.com/ipfs/go-fs-lock v0.0.7 // indirect github.com/ipfs/go-graphsync v0.14.1 // indirect - github.com/ipfs/go-ipfs-blockstore v1.2.0 // indirect - github.com/ipfs/go-ipfs-chunker v0.0.5 // indirect + github.com/ipfs/go-ipfs-blockstore v1.3.0 // indirect github.com/ipfs/go-ipfs-delay v0.0.1 // indirect github.com/ipfs/go-ipfs-ds-help v1.1.0 // indirect - github.com/ipfs/go-ipfs-exchange-interface v0.2.0 // indirect - github.com/ipfs/go-ipfs-exchange-offline v0.3.0 // indirect - github.com/ipfs/go-ipfs-keystore v0.1.0 // indirect - github.com/ipfs/go-ipfs-pinner v0.3.0 // indirect - github.com/ipfs/go-ipfs-posinfo v0.0.1 // indirect github.com/ipfs/go-ipfs-pq v0.0.3 // indirect - github.com/ipfs/go-ipfs-provider v0.8.1 // indirect - github.com/ipfs/go-ipfs-routing v0.3.0 // indirect github.com/ipfs/go-ipfs-util v0.0.2 // indirect github.com/ipfs/go-ipld-cbor v0.0.6 // indirect github.com/ipfs/go-ipld-format v0.4.0 // indirect github.com/ipfs/go-ipld-git v0.1.1 // indirect github.com/ipfs/go-ipld-legacy v0.1.1 // indirect - github.com/ipfs/go-ipns v0.3.0 // indirect github.com/ipfs/go-log v1.0.5 // indirect github.com/ipfs/go-log/v2 v2.5.1 // indirect - github.com/ipfs/go-merkledag v0.9.0 // indirect github.com/ipfs/go-metrics-interface v0.0.1 // indirect - github.com/ipfs/go-mfs v0.2.1 // indirect - github.com/ipfs/go-namesys v0.7.0 // indirect - github.com/ipfs/go-path v0.3.1 // indirect github.com/ipfs/go-peertaskqueue v0.8.1 // indirect - github.com/ipfs/go-unixfs v0.4.4 // indirect - github.com/ipfs/go-unixfsnode v1.5.2 // indirect - github.com/ipfs/go-verifcid v0.0.2 // indirect + github.com/ipfs/go-unixfsnode v1.6.0 // indirect github.com/ipld/edelweiss v0.2.0 // indirect - github.com/ipld/go-codec-dagpb v1.5.0 // indirect - github.com/ipld/go-ipld-prime v0.19.0 // indirect + github.com/ipld/go-codec-dagpb v1.6.0 // indirect + github.com/ipld/go-ipld-prime v0.20.0 // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect github.com/jbenet/goprocess v0.1.4 // indirect @@ -120,7 +101,7 @@ require ( github.com/libp2p/go-doh-resolver v0.4.0 // indirect github.com/libp2p/go-flow-metrics v0.1.0 // indirect github.com/libp2p/go-libp2p-asn-util v0.3.0 // indirect - github.com/libp2p/go-libp2p-kad-dht v0.21.1 // indirect + github.com/libp2p/go-libp2p-kad-dht v0.22.0 // indirect github.com/libp2p/go-libp2p-kbucket v0.5.0 // indirect github.com/libp2p/go-libp2p-pubsub v0.9.0 // indirect github.com/libp2p/go-libp2p-pubsub-router v0.6.0 // indirect @@ -148,14 +129,14 @@ require ( github.com/multiformats/go-multiaddr-dns v0.3.1 // indirect github.com/multiformats/go-multiaddr-fmt v0.1.0 // indirect github.com/multiformats/go-multibase v0.1.1 // indirect - github.com/multiformats/go-multicodec v0.7.0 // indirect + github.com/multiformats/go-multicodec v0.8.1 // indirect github.com/multiformats/go-multihash v0.2.1 // indirect github.com/multiformats/go-multistream v0.4.1 // indirect github.com/multiformats/go-varint v0.0.7 // indirect github.com/onsi/ginkgo/v2 v2.5.1 // indirect github.com/opencontainers/runtime-spec v1.0.2 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect - github.com/openzipkin/zipkin-go v0.4.0 // indirect + github.com/openzipkin/zipkin-go v0.4.1 // indirect github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/polydawn/refmt v0.89.0 // indirect @@ -178,34 +159,34 @@ require ( github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 // indirect go.opencensus.io v0.24.0 // indirect - go.opentelemetry.io/otel v1.7.0 // indirect - go.opentelemetry.io/otel/exporters/jaeger v1.7.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.7.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.7.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.7.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.7.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.7.0 // indirect - go.opentelemetry.io/otel/exporters/zipkin v1.7.0 // indirect - go.opentelemetry.io/otel/sdk v1.7.0 // indirect - go.opentelemetry.io/otel/trace v1.7.0 // indirect - go.opentelemetry.io/proto/otlp v0.16.0 // indirect + go.opentelemetry.io/otel v1.14.0 // indirect + go.opentelemetry.io/otel/exporters/jaeger v1.14.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.14.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.14.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.14.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.14.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.14.0 // indirect + go.opentelemetry.io/otel/exporters/zipkin v1.14.0 // indirect + go.opentelemetry.io/otel/sdk v1.14.0 // indirect + go.opentelemetry.io/otel/trace v1.14.0 // indirect + go.opentelemetry.io/proto/otlp v0.19.0 // indirect go.uber.org/atomic v1.10.0 // indirect go.uber.org/dig v1.15.0 // indirect go.uber.org/fx v1.18.2 // indirect go.uber.org/multierr v1.9.0 // indirect go.uber.org/zap v1.24.0 // indirect go4.org v0.0.0-20200411211856-f5505b9728dd // indirect - golang.org/x/crypto v0.5.0 // indirect - golang.org/x/exp v0.0.0-20230129154200-a960b3787bd2 // indirect + golang.org/x/crypto v0.6.0 // indirect + golang.org/x/exp v0.0.0-20230213192124-5e25df0256eb // indirect golang.org/x/mod v0.7.0 // indirect golang.org/x/net v0.7.0 // indirect golang.org/x/sync v0.1.0 // indirect - golang.org/x/sys v0.5.0 // indirect + golang.org/x/sys v0.6.0 // indirect golang.org/x/text v0.7.0 // indirect golang.org/x/tools v0.3.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect - google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1 // indirect - google.golang.org/grpc v1.46.0 // indirect + google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect + google.golang.org/grpc v1.53.0 // indirect google.golang.org/protobuf v1.28.1 // indirect gopkg.in/square/go-jose.v2 v2.5.1 // indirect lukechampine.com/blake3 v1.1.7 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index fed70264a..235e25c83 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -40,24 +40,14 @@ dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBr dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4= dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU= git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg= -github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 h1:cTp8I5+VIoKjsnZuH8vjyaysT/ses3EvZeaV/1UkF2M= github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= -github.com/Kubuxu/go-os-helper v0.0.1/go.mod h1:N8B+I7vPCT80IcP58r50u4+gEEcsZETFUpAzWW2ep1Y= github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= -github.com/Shopify/sarama v1.30.0/go.mod h1:zujlQQx1kzHsh4jfV1USnptCQrHAEZ2Hk8fTKCulPVs= -github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= -github.com/Shopify/toxiproxy/v2 v2.1.6-0.20210914104332-15ea381dcdae/go.mod h1:/cvHQkZ1fst0EmZnA5dFtiQdWCNCFYzb+uE2vqVgvx0= -github.com/Stebalien/go-bitfield v0.0.1/go.mod h1:GNjFpasyUVkHMsfEOk8EFLJ9syQ6SI+XWrX9Wf2XH0s= -github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= -github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= @@ -69,16 +59,7 @@ github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5 h1:iW0a5 github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5/go.mod h1:Y2QMoi1vgtOIfc+6DhrMOGkLoGzqSV2rKp4Sm+opsyA= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= -github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= -github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= -github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= -github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= -github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= @@ -86,33 +67,23 @@ github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24 github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= -github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= -github.com/btcsuite/btcd v0.0.0-20190523000118-16327141da8c/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= -github.com/btcsuite/btcd v0.0.0-20190605094302-a0d1e3e36d50/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= github.com/btcsuite/btcd v0.0.0-20190824003749-130ea5bddde3/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= -github.com/btcsuite/btcd v0.21.0-beta/go.mod h1:ZSWyehm27aAuS9bvkATT+Xte3hjHZ+MRgMY/8NJ7K94= github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= -github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= -github.com/btcsuite/btcutil v1.0.2/go.mod h1:j9HUFwoQRsZL3V4n+qG+CUnEGHOarIxfC3Le2Yhbcts= github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= -github.com/btcsuite/goleveldb v1.0.0/go.mod h1:QiK9vBlgftBg6rWQIj6wFzbPfRjiykIEhBH4obrXJ/I= github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= -github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= -github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= -github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4= -github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= +github.com/cenkalti/backoff/v4 v4.2.0 h1:HN5dHm3WBOgndBH6E8V0q2jIYIR3s9yglV8k/+MN3u4= +github.com/cenkalti/backoff/v4 v4.2.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/ceramicnetwork/go-dag-jose v0.1.0 h1:yJ/HVlfKpnD3LdYP03AHyTvbm3BpPiz2oZiOeReJRdU= github.com/ceramicnetwork/go-dag-jose v0.1.0/go.mod h1:qYA1nYt0X8u4XoMAVoOV3upUVKtrxy/I670Dg5F0wjI= @@ -122,12 +93,10 @@ github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cheekybits/genny v1.0.0/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ= 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= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= @@ -135,10 +104,7 @@ github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XP github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/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/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE= github.com/containerd/cgroups v1.0.4 h1:jN/mbWBEaz+T1pi5OFtnkQ+8qnmEbAr1Oo1FRm5B0dA= github.com/containerd/cgroups v1.0.4/go.mod h1:nLNQtsF7Sl2HxNebu77i1R0oDlhiTG+kO4JTrUzo6IA= @@ -146,18 +112,15 @@ github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc 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= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= github.com/coreos/go-systemd/v22 v22.5.0/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= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cskr/pubsub v1.0.2 h1:vlOzMhl6PFn60gRlTQQsIfVwaPB/B/8MziK8FhEPt/0= github.com/cskr/pubsub v1.0.2/go.mod h1:/8MzYXk/NJAz782G8RPkFzXTZVu63VotefPnR9TIRis= @@ -165,64 +128,45 @@ github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davidlazar/go-crypto v0.0.0-20170701192655-dcfb0a7ac018/go.mod h1:rQYf4tfk5sSwFsnDg3qYaBxSjsD9S8+59vW0dKUgme4= github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c h1:pFUpOrbxDR6AkioZ1ySsx5yxlDQZ8stG2b88gTPxgJU= github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c/go.mod h1:6UhI8N9EjYm1c2odKpFpAYeR8dsBeM7PtzQhRgxRr9U= github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 h1:HbphB4TFFXpv7MNrT52FGrrgVXF1owhMVTHFZIlnvd4= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0/go.mod h1:DZGJHZMqrU4JJqFAWUS2UO1+lbSKsdiOoYi9Zzey7Fc= -github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= -github.com/dgraph-io/badger v1.5.5-0.20190226225317-8115aed38f8f/go.mod h1:VZxzAIRPHRVNRKRo6AXrX9BJegn6il06VMTZVJYCIjQ= -github.com/dgraph-io/badger v1.6.0-rc1/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= -github.com/dgraph-io/badger v1.6.1/go.mod h1:FRmFw3uxvcpa8zG3Rxs0th+hCLIuaQg8HlNV5bjgnuU= github.com/dgraph-io/badger v1.6.2 h1:mNw0qs90GVgGGWylh0umH5iag1j6n/PeJtNvL6KY/x8= github.com/dgraph-io/badger v1.6.2/go.mod h1:JW2yswe3V058sS0kZ2h/AXeDSqFjxnZcRrVH//y2UQE= github.com/dgraph-io/ristretto v0.0.2 h1:a5WaUrDa0qm0YrAAS1tUykT5El3kt62KNZZeMxQn3po= github.com/dgraph-io/ristretto v0.0.2/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= -github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= -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/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.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= -github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= -github.com/eapache/go-resiliency v1.2.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= -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/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= github.com/elastic/gosigar v0.14.2 h1:Dg80n8cr90OZ7x+bAax/QjoW/XqTI11RmA79ZwIm9/4= github.com/elastic/gosigar v0.14.2/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= -github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= -github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5 h1:BBso6MBKW8ncyZLv37o+KNyy0HrrHgfnOaGQC2qvN+A= github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5/go.mod h1:JpoxHjuQauoxiFMl1ie8Xc/7TfLuMZ5eOCONd1sUBHg= -github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/flynn/noise v1.0.0 h1:DlTHqmzmvcEiKj+4RYo/imoswx/4r6iBlCMfVtrMXpQ= github.com/flynn/noise v1.0.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag= -github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk= github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= -github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= -github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/frankban/quicktest v1.14.0/go.mod h1:NeW+ay9A/U67EYXNFA1nPE8e/tnQv/09mUdL/ijj8og= -github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= +github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= @@ -239,7 +183,6 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= @@ -258,7 +201,6 @@ github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD87 github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= github.com/go-playground/validator/v10 v10.2.0 h1:KgJ0snyC2R9VXYN2rneOtQcw5aHQB1Vv0sFl1UcHBOY= github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= -github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= 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= @@ -273,9 +215,7 @@ github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5x github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= github.com/godbus/dbus/v5 v5.1.0/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= -github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= @@ -284,9 +224,7 @@ github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ= github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= -github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= @@ -301,7 +239,6 @@ github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71 github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= @@ -335,7 +272,6 @@ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ 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= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= @@ -355,10 +291,8 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20221203041831-ce31453925ec h1:fR20TYVVwhK4O7r7y+McjRYyaTH6/vjwJOajE+XhlzM= github.com/google/pprof v0.0.0-20221203041831-ce31453925ec/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= @@ -367,24 +301,12 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c h1:7lF+Vz0LqiRidnzC1Oq86fpX1q/iEv2KJdrCtttYjT4= -github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= -github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= -github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= -github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= -github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= -github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 h1:BZHcxBETFHIdVyhyEfOvn/RdU/QGdLI4y34qQGjGWO0= github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= @@ -392,25 +314,11 @@ github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfm github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= github.com/hannahhoward/go-pubsub v0.0.0-20200423002714-8d62886cc36e h1:3YKHER4nmd7b5qy5t0GWDTwSn4OyRgfAXSmo6VnryBY= github.com/hannahhoward/go-pubsub v0.0.0-20200423002714-8d62886cc36e/go.mod h1:I8h3MITA53gN9OnWGCgaMa0JWVRdXthWw4M3CPM54OY= -github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= -github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= -github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= -github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= -github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= -github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= -github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= @@ -418,40 +326,24 @@ github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uG github.com/hashicorp/golang-lru/v2 v2.0.1 h1:5pv5N1lT1fjLg2VQ5KWc7kmucp2x/kvFOnxuVTqZ6x4= github.com/hashicorp/golang-lru/v2 v2.0.1/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= -github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= -github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= -github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= github.com/huin/goupnp v1.0.3 h1:N8No57ls+MnjlB+JPiCVSOyy/ot7MJTqlo7rn+NYSqQ= github.com/huin/goupnp v1.0.3/go.mod h1:ZxNlw5WqJj6wSsRK5+YfflQGXYfccj5VgQsMNixHM7Y= github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= -github.com/ipfs/bbloom v0.0.1/go.mod h1:oqo8CVWsJFMOZqTglBG4wydCE4IQA/G2/SEofB0rjUI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/go-bitfield v1.0.0/go.mod h1:N/UiujQy+K+ceU1EF5EkVd1TNqevLrCQMIcAEPrdtus= +github.com/ipfs/boxo v0.8.0-rc2 h1:JnSlLKlIURiVsTfPs1BLv3NNCygjV1b07wGva3w4sLY= +github.com/ipfs/boxo v0.8.0-rc2/go.mod h1:EgDiNox/+W/+ySwEotRrHlvdmrhbSAB4p22ELg+ZsCc= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= -github.com/ipfs/go-bitswap v0.1.0/go.mod h1:FFJEf18E9izuCqUtHxbWEvq+reg7o4CW5wSAE1wsxj0= -github.com/ipfs/go-bitswap v0.1.2/go.mod h1:qxSWS4NXGs7jQ6zQvoPY3+NmOfHHG47mhkiLzBpJQIs= -github.com/ipfs/go-bitswap v0.5.1/go.mod h1:P+ckC87ri1xFLvk74NlXdP0Kj9RmWAh4+H78sC6Qopo= -github.com/ipfs/go-bitswap v0.6.0/go.mod h1:Hj3ZXdOC5wBJvENtdqsixmzzRukqd8EHLxZLZc3mzRA= -github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= -github.com/ipfs/go-block-format v0.0.1/go.mod h1:DK/YYcsSUIVAFNwo/KZCdIIbpN0ROH/baNLgayt4pFc= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= github.com/ipfs/go-block-format v0.0.3/go.mod h1:4LmD4ZUw0mhO+JSKdpWwrzATiEfM7WWgQ8H5l6P8MVk= -github.com/ipfs/go-block-format v0.1.1 h1:129vSO3zwbsYADcyQWcOYiuCpAqt462SFfqFHdFJhhI= -github.com/ipfs/go-block-format v0.1.1/go.mod h1:+McEIT+g52p+zz5xGAABGSOKrzmrdX97bc0USBdWPUs= -github.com/ipfs/go-blockservice v0.1.0/go.mod h1:hzmMScl1kXHg3M2BjTymbVPjv627N7sYcvYaKbop39M= -github.com/ipfs/go-blockservice v0.2.1/go.mod h1:k6SiwmgyYgs4M/qt+ww6amPeUH9EISLRBnvUurKJhi8= -github.com/ipfs/go-blockservice v0.3.0/go.mod h1:P5ppi8IHDC7O+pA0AlGTF09jruB2h+oP3wVVaZl8sfk= +github.com/ipfs/go-block-format v0.1.2 h1:GAjkfhVx1f4YTODS6Esrj1wt2HhrtwTnhEr+DyPUaJo= +github.com/ipfs/go-block-format v0.1.2/go.mod h1:mACVcrxarQKstUU3Yf/RdwbC4DzPV6++rO2a3d+a/KE= github.com/ipfs/go-blockservice v0.5.0 h1:B2mwhhhVQl2ntW2EIpaWPwSCxSuqr5fFA93Ms4bYLEY= -github.com/ipfs/go-blockservice v0.5.0/go.mod h1:W6brZ5k20AehbmERplmERn8o2Ni3ZZubvAxaIUeaT6w= github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.2/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.3/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= @@ -459,206 +351,108 @@ github.com/ipfs/go-cid v0.0.4/go.mod h1:4LLaPOQwmk5z9LBgQnpkivrx8BJjUyGwTXCd5Xfj github.com/ipfs/go-cid v0.0.5/go.mod h1:plgt+Y5MnOey4vO4UlUazGqdbEXuFYitED67FexhXog= github.com/ipfs/go-cid v0.0.6/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I= github.com/ipfs/go-cid v0.0.7/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I= -github.com/ipfs/go-cid v0.1.0/go.mod h1:rH5/Xv83Rfy8Rw6xG+id3DYAMUVmem1MowoKwdXmN2o= github.com/ipfs/go-cid v0.4.0 h1:a4pdZq0sx6ZSxbCizebnKiMCx/xI/aBBFlB73IgH4rA= github.com/ipfs/go-cid v0.4.0/go.mod h1:uQHwDeX4c6CtyrFwdqyhpNcxVewur1M7l7fNU7LKwZk= github.com/ipfs/go-cidutil v0.1.0 h1:RW5hO7Vcf16dplUU60Hs0AKDkQAVPVplr7lk97CFL+Q= github.com/ipfs/go-cidutil v0.1.0/go.mod h1:e7OEVBMIv9JaOxt9zaGEmAoSlXW9jdFZ5lP/0PwcfpA= -github.com/ipfs/go-datastore v0.0.1/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= -github.com/ipfs/go-datastore v0.0.5/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= github.com/ipfs/go-datastore v0.1.0/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= github.com/ipfs/go-datastore v0.1.1/go.mod h1:w38XXW9kVFNp57Zj5knbKWM2T+KOZCGDRVNdgPHtbHw= -github.com/ipfs/go-datastore v0.3.1/go.mod h1:w38XXW9kVFNp57Zj5knbKWM2T+KOZCGDRVNdgPHtbHw= -github.com/ipfs/go-datastore v0.4.0/go.mod h1:SX/xMIKoCszPqp+z9JhPYCmoOoXTvaa13XEbGtsFUhA= -github.com/ipfs/go-datastore v0.4.1/go.mod h1:SX/xMIKoCszPqp+z9JhPYCmoOoXTvaa13XEbGtsFUhA= -github.com/ipfs/go-datastore v0.4.4/go.mod h1:SX/xMIKoCszPqp+z9JhPYCmoOoXTvaa13XEbGtsFUhA= -github.com/ipfs/go-datastore v0.4.5/go.mod h1:eXTcaaiN6uOlVCLS9GjJUJtlvJfM3xk23w3fyfrmmJs= github.com/ipfs/go-datastore v0.5.0/go.mod h1:9zhEApYMTl17C8YDp7JmU7sQZi2/wqiYh73hakZ90Bk= github.com/ipfs/go-datastore v0.6.0 h1:JKyz+Gvz1QEZw0LsX1IBn+JFCJQH4SJVFtM4uWU0Myk= github.com/ipfs/go-datastore v0.6.0/go.mod h1:rt5M3nNbSO/8q1t4LNkLyUwRs8HupMeN/8O4Vn9YAT8= -github.com/ipfs/go-delegated-routing v0.7.0 h1:43FyMnKA+8XnyX68Fwg6aoGkqrf8NS5aG7p644s26PU= -github.com/ipfs/go-delegated-routing v0.7.0/go.mod h1:u4zxjUWIe7APUW5ds9CfD0tJX3vM9JhIeNqA8kE4vHE= +github.com/ipfs/go-delegated-routing v0.8.0 h1:faiRi4k8YioTxU2x7+pnrLQjR7jIQhGWN2JvCwcQ/aU= +github.com/ipfs/go-delegated-routing v0.8.0/go.mod h1:18Dds6ZoNTsff9S/7R49Nh2t2YNXIIKR/RLQmBZdjjY= github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk= github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps= -github.com/ipfs/go-ds-badger v0.0.2/go.mod h1:Y3QpeSFWQf6MopLTiZD+VT6IC1yZqaGmjvRcKeSGij8= -github.com/ipfs/go-ds-badger v0.0.5/go.mod h1:g5AuuCGmr7efyzQhLL8MzwqcauPojGPUaHzfGTzuE3s= github.com/ipfs/go-ds-badger v0.0.7/go.mod h1:qt0/fWzZDoPW6jpQeqUjR5kBfhDNB65jd9YlmAvpQBk= -github.com/ipfs/go-ds-badger v0.2.1/go.mod h1:Tx7l3aTph3FMFrRS838dcSJh+jjA7cX9DrGVwx/NOwE= -github.com/ipfs/go-ds-badger v0.2.3/go.mod h1:pEYw0rgg3FIrywKKnL+Snr+w/LjJZVMTBRn4FS6UHUk= 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-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= -github.com/ipfs/go-ds-leveldb v0.4.2/go.mod h1:jpbku/YqBSsBc1qgME8BkWS4AxzF2cEu1Ii2r79Hh9s= github.com/ipfs/go-ds-leveldb v0.5.0 h1:s++MEBbD3ZKc9/8/njrn4flZLnCuY9I79v94gBUNumo= github.com/ipfs/go-ds-leveldb v0.5.0/go.mod h1:d3XG9RUDzQ6V4SHi8+Xgj9j1XuEk1z82lquxrVbml/Q= github.com/ipfs/go-ds-measure v0.2.0 h1:sG4goQe0KDTccHMyT45CY1XyUbxe5VwTKpg2LjApYyQ= github.com/ipfs/go-ds-measure v0.2.0/go.mod h1:SEUD/rE2PwRa4IQEC5FuNAmjJCyYObZr9UvVh8V3JxE= -github.com/ipfs/go-fetcher v1.6.1 h1:UFuRVYX5AIllTiRhi5uK/iZkfhSpBCGX7L70nSZEmK8= -github.com/ipfs/go-fetcher v1.6.1/go.mod h1:27d/xMV8bodjVs9pugh/RCjjK2OZ68UgAMspMdingNo= -github.com/ipfs/go-filestore v1.2.0 h1:O2wg7wdibwxkEDcl7xkuQsPvJFRBVgVSsOJ/GP6z3yU= -github.com/ipfs/go-filestore v1.2.0/go.mod h1:HLJrCxRXquTeEEpde4lTLMaE/MYJZD7WHLkp9z6+FF8= github.com/ipfs/go-fs-lock v0.0.7 h1:6BR3dajORFrFTkb5EpCUFIAypsoxpGpDSVUdFwzgL9U= github.com/ipfs/go-fs-lock v0.0.7/go.mod h1:Js8ka+FNYmgQRLrRXzU3CB/+Csr1BwrRilEcvYrHhhc= github.com/ipfs/go-graphsync v0.14.1 h1:tvFpBY9LcehIB7zi5SZIa+7aoxBOrGbdekhOXdnlT70= github.com/ipfs/go-graphsync v0.14.1/go.mod h1:S6O/c5iXOXqDgrQgiZSgOTRUSiVvpKEhrzqFHKnLVcs= -github.com/ipfs/go-ipfs-blockstore v0.0.1/go.mod h1:d3WClOmRQKFnJ0Jz/jj/zmksX0ma1gROTlovZKBmN08= -github.com/ipfs/go-ipfs-blockstore v0.1.0/go.mod h1:5aD0AvHPi7mZc6Ci1WCAhiBQu2IsfTduLl+422H6Rqw= -github.com/ipfs/go-ipfs-blockstore v0.2.1/go.mod h1:jGesd8EtCM3/zPgx+qr0/feTXGUeRai6adgwC+Q+JvE= -github.com/ipfs/go-ipfs-blockstore v1.2.0 h1:n3WTeJ4LdICWs/0VSfjHrlqpPpl6MZ+ySd3j8qz0ykw= -github.com/ipfs/go-ipfs-blockstore v1.2.0/go.mod h1:eh8eTFLiINYNSNawfZOC7HOxNTxpB1PFuA5E1m/7exE= +github.com/ipfs/go-ipfs-blockstore v1.3.0 h1:m2EXaWgwTzAfsmt5UdJ7Is6l4gJcaM/A12XwJyvYvMM= +github.com/ipfs/go-ipfs-blockstore v1.3.0/go.mod h1:KgtZyc9fq+P2xJUiCAzbRdhhqJHvsw8u2Dlqy2MyRTE= github.com/ipfs/go-ipfs-blocksutil v0.0.1 h1:Eh/H4pc1hsvhzsQoMEP3Bke/aW5P5rVM1IWFJMcGIPQ= -github.com/ipfs/go-ipfs-blocksutil v0.0.1/go.mod h1:Yq4M86uIOmxmGPUHv/uI7uKqZNtLb449gwKqXjIsnRk= -github.com/ipfs/go-ipfs-chunker v0.0.1/go.mod h1:tWewYK0we3+rMbOh7pPFGDyypCtvGcBFymgY4rSDLAw= github.com/ipfs/go-ipfs-chunker v0.0.5 h1:ojCf7HV/m+uS2vhUGWcogIIxiO5ubl5O57Q7NapWLY8= -github.com/ipfs/go-ipfs-chunker v0.0.5/go.mod h1:jhgdF8vxRHycr00k13FM8Y0E+6BoalYeobXmUyTreP8= github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= github.com/ipfs/go-ipfs-delay v0.0.1 h1:r/UXYyRcddO6thwOnhiznIAiSvxMECGgtv35Xs1IeRQ= github.com/ipfs/go-ipfs-delay v0.0.1/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= -github.com/ipfs/go-ipfs-ds-help v0.0.1/go.mod h1:gtP9xRaZXqIQRh1HRpp595KbBEdgqWFxefeVKOV8sxo= -github.com/ipfs/go-ipfs-ds-help v0.1.1/go.mod h1:SbBafGJuGsPI/QL3j9Fc5YPLeAu+SzOkI0gFwAg+mOs= github.com/ipfs/go-ipfs-ds-help v1.1.0 h1:yLE2w9RAsl31LtfMt91tRZcrx+e61O5mDxFRR994w4Q= github.com/ipfs/go-ipfs-ds-help v1.1.0/go.mod h1:YR5+6EaebOhfcqVCyqemItCLthrpVNot+rsOU/5IatU= -github.com/ipfs/go-ipfs-exchange-interface v0.0.1/go.mod h1:c8MwfHjtQjPoDyiy9cFquVtVHkO9b9Ob3FG91qJnWCM= -github.com/ipfs/go-ipfs-exchange-interface v0.1.0/go.mod h1:ych7WPlyHqFvCi/uQI48zLZuAWVP5iTQPXEfVaw5WEI= github.com/ipfs/go-ipfs-exchange-interface v0.2.0 h1:8lMSJmKogZYNo2jjhUs0izT+dck05pqUw4mWNW9Pw6Y= -github.com/ipfs/go-ipfs-exchange-interface v0.2.0/go.mod h1:z6+RhJuDQbqKguVyslSOuVDhqF9JtTrO3eptSAiW2/Y= -github.com/ipfs/go-ipfs-exchange-offline v0.0.1/go.mod h1:WhHSFCVYX36H/anEKQboAzpUws3x7UeEGkzQc3iNkM0= -github.com/ipfs/go-ipfs-exchange-offline v0.1.1/go.mod h1:vTiBRIbzSwDD0OWm+i3xeT0mO7jG2cbJYatp3HPk5XY= -github.com/ipfs/go-ipfs-exchange-offline v0.2.0/go.mod h1:HjwBeW0dvZvfOMwDP0TSKXIHf2s+ksdP4E3MLDRtLKY= github.com/ipfs/go-ipfs-exchange-offline v0.3.0 h1:c/Dg8GDPzixGd0MC8Jh6mjOwU57uYokgWRFidfvEkuA= -github.com/ipfs/go-ipfs-exchange-offline v0.3.0/go.mod h1:MOdJ9DChbb5u37M1IcbrRB02e++Z7521fMxqCNRrz9s= -github.com/ipfs/go-ipfs-files v0.0.3/go.mod h1:INEFm0LL2LWXBhNJ2PMIIb2w45hpXgPjNoE7yA8Y1d4= -github.com/ipfs/go-ipfs-keystore v0.1.0 h1:gfuQUO/cyGZgZIHE6OrJas4OnwuxXCqJG7tI0lrB5Qc= -github.com/ipfs/go-ipfs-keystore v0.1.0/go.mod h1:LvLw7Qhnb0RlMOfCzK6OmyWxICip6lQ06CCmdbee75U= -github.com/ipfs/go-ipfs-pinner v0.3.0 h1:jwe5ViX3BON3KgOAYrrhav2+1ONB0QzFAWQd7HUlbuM= -github.com/ipfs/go-ipfs-pinner v0.3.0/go.mod h1:oX0I0nC6zlNIh0LslSrUnjfNKPq8ufoFtqV1/wcJvyo= +github.com/ipfs/go-ipfs-files v0.3.0 h1:fallckyc5PYjuMEitPNrjRfpwl7YFt69heCOUhsbGxQ= github.com/ipfs/go-ipfs-posinfo v0.0.1 h1:Esoxj+1JgSjX0+ylc0hUmJCOv6V2vFoZiETLR6OtpRs= -github.com/ipfs/go-ipfs-posinfo v0.0.1/go.mod h1:SwyeVP+jCwiDu0C313l/8jg6ZxM0qqtlt2a0vILTc1A= -github.com/ipfs/go-ipfs-pq v0.0.1/go.mod h1:LWIqQpqfRG3fNc5XsnIhz/wQ2XXGyugQwls7BgUmUfY= -github.com/ipfs/go-ipfs-pq v0.0.2/go.mod h1:LWIqQpqfRG3fNc5XsnIhz/wQ2XXGyugQwls7BgUmUfY= github.com/ipfs/go-ipfs-pq v0.0.3 h1:YpoHVJB+jzK15mr/xsWC574tyDLkezVrDNeaalQBsTE= github.com/ipfs/go-ipfs-pq v0.0.3/go.mod h1:btNw5hsHBpRcSSgZtiNm/SLj5gYIZ18AKtv3kERkRb4= -github.com/ipfs/go-ipfs-provider v0.8.1 h1:qt670pYmcNH3BCjyXDgg07o2WsTRsOdMwYc25ukCdjQ= -github.com/ipfs/go-ipfs-provider v0.8.1/go.mod h1:qCpwpoohIRVXvNzkygzsM3qdqP/sXlrogtA5I45tClc= -github.com/ipfs/go-ipfs-routing v0.1.0/go.mod h1:hYoUkJLyAUKhF58tysKpids8RNDPO42BVMgK5dNsoqY= -github.com/ipfs/go-ipfs-routing v0.2.1/go.mod h1:xiNNiwgjmLqPS1cimvAw6EyB9rkVDbiocA4yY+wRNLM= -github.com/ipfs/go-ipfs-routing v0.3.0 h1:9W/W3N+g+y4ZDeffSgqhgo7BsBSJwPMcyssET9OWevc= -github.com/ipfs/go-ipfs-routing v0.3.0/go.mod h1:dKqtTFIql7e1zYsEuWLyuOU+E0WJWW8JjbTPLParDWo= github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyBCNzQxlJBc= github.com/ipfs/go-ipfs-util v0.0.2 h1:59Sswnk1MFaiq+VcaknX7aYEyGyGDAA73ilhEK2POp8= github.com/ipfs/go-ipfs-util v0.0.2/go.mod h1:CbPtkWJzjLdEcezDns2XYaehFVNXG9zrdrtMecczcsQ= -github.com/ipfs/go-ipld-cbor v0.0.2/go.mod h1:wTBtrQZA3SoFKMVkp6cn6HMRteIB1VsmHA0AQFOn7Nc= -github.com/ipfs/go-ipld-cbor v0.0.3/go.mod h1:wTBtrQZA3SoFKMVkp6cn6HMRteIB1VsmHA0AQFOn7Nc= -github.com/ipfs/go-ipld-cbor v0.0.5/go.mod h1:BkCduEx3XBCO6t2Sfo5BaHzuok7hbhdMm9Oh8B2Ftq4= github.com/ipfs/go-ipld-cbor v0.0.6 h1:pYuWHyvSpIsOOLw4Jy7NbBkCyzLDcl64Bf/LZW7eBQ0= github.com/ipfs/go-ipld-cbor v0.0.6/go.mod h1:ssdxxaLJPXH7OjF5V4NSjBbcfh+evoR4ukuru0oPXMA= github.com/ipfs/go-ipld-format v0.0.1/go.mod h1:kyJtbkDALmFHv3QR6et67i35QzO3S0dCDnkOJhcZkms= -github.com/ipfs/go-ipld-format v0.0.2/go.mod h1:4B6+FM2u9OJ9zCV+kSbgFAZlOrv1Hqbf0INGQgiKf9k= github.com/ipfs/go-ipld-format v0.2.0/go.mod h1:3l3C1uKoadTPbeNfrDi+xMInYKlx2Cvg1BuydPSdzQs= -github.com/ipfs/go-ipld-format v0.3.0/go.mod h1:co/SdBE8h99968X0hViiw1MNlh6fvxxnHpvVLnH7jSM= github.com/ipfs/go-ipld-format v0.4.0 h1:yqJSaJftjmjc9jEOFYlpkwOLVKv68OD27jFLlSghBlQ= github.com/ipfs/go-ipld-format v0.4.0/go.mod h1:co/SdBE8h99968X0hViiw1MNlh6fvxxnHpvVLnH7jSM= github.com/ipfs/go-ipld-git v0.1.1 h1:TWGnZjS0htmEmlMFEkA3ogrNCqWjIxwr16x1OsdhG+Y= github.com/ipfs/go-ipld-git v0.1.1/go.mod h1:+VyMqF5lMcJh4rwEppV0e6g4nCCHXThLYYDpKUkJubI= -github.com/ipfs/go-ipld-legacy v0.1.0/go.mod h1:86f5P/srAmh9GcIcWQR9lfFLZPrIyyXQeVlOWeeWEuI= github.com/ipfs/go-ipld-legacy v0.1.1 h1:BvD8PEuqwBHLTKqlGFTHSwrwFOMkVESEvwIYwR2cdcc= github.com/ipfs/go-ipld-legacy v0.1.1/go.mod h1:8AyKFCjgRPsQFf15ZQgDB8Din4DML/fOmKZkkFkrIEg= -github.com/ipfs/go-ipns v0.3.0 h1:ai791nTgVo+zTuq2bLvEGmWP1M0A6kGTXUsgv/Yq67A= -github.com/ipfs/go-ipns v0.3.0/go.mod h1:3cLT2rbvgPZGkHJoPO1YMJeh6LtkxopCkKFcio/wE24= github.com/ipfs/go-libipfs v0.7.0 h1:Mi54WJTODaOL2/ZSm5loi3SwI3jI2OuFWUrQIkJ5cpM= -github.com/ipfs/go-libipfs v0.7.0/go.mod h1:KsIf/03CqhICzyRGyGo68tooiBE2iFbI/rXW7FhAYr0= github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= -github.com/ipfs/go-log v1.0.2/go.mod h1:1MNjMxe0u6xvJZgeqbJ8vdo2TKaGwZ1a0Bpza+sr2Sk= github.com/ipfs/go-log v1.0.3/go.mod h1:OsLySYkwIbiSUR/yBTdv1qPtcE4FW3WPWk/ewz9Ru+A= -github.com/ipfs/go-log v1.0.4/go.mod h1:oDCg2FkjogeFOhqqb+N39l2RpTNPL6F/StPkB3kPgcs= github.com/ipfs/go-log v1.0.5 h1:2dOuUCB1Z7uoczMWgAyDck5JLb72zHzrMnGnCNNbvY8= github.com/ipfs/go-log v1.0.5/go.mod h1:j0b8ZoR+7+R99LD9jZ6+AJsrzkPbSXbZfGakb5JPtIo= -github.com/ipfs/go-log/v2 v2.0.2/go.mod h1:O7P1lJt27vWHhOwQmcFEvlmo49ry2VY2+JfBWFaa9+0= github.com/ipfs/go-log/v2 v2.0.3/go.mod h1:O7P1lJt27vWHhOwQmcFEvlmo49ry2VY2+JfBWFaa9+0= 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/go.mod h1:QqGoj30OTpnKaG/LKTGTxoP2mmQtjVMEnK72gynbe/g= github.com/ipfs/go-log/v2 v2.5.1 h1:1XdUzF7048prq4aBjDQQ4SL5RxftpRGdXhNRwKSAlcY= github.com/ipfs/go-log/v2 v2.5.1/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOLU9U5UI= -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= -github.com/ipfs/go-merkledag v0.5.1/go.mod h1:cLMZXx8J08idkp5+id62iVftUQV+HlYJ3PIhDfZsjA4= -github.com/ipfs/go-merkledag v0.6.0/go.mod h1:9HSEwRd5sV+lbykiYP+2NC/3o6MZbKNaa4hfNcH5iH0= -github.com/ipfs/go-merkledag v0.9.0 h1:DFC8qZ96Dz1hMT7dtIpcY524eFFDiEWAF8hNJHWW2pk= -github.com/ipfs/go-merkledag v0.9.0/go.mod h1:bPHqkHt5OZ0p1n3iqPeDiw2jIBkjAytRjS3WSBwjq90= +github.com/ipfs/go-merkledag v0.10.0 h1:IUQhj/kzTZfam4e+LnaEpoiZ9vZF6ldimVlby+6OXL4= github.com/ipfs/go-metrics-interface v0.0.1 h1:j+cpbjYvu4R8zbleSs36gvB7jR+wsL2fGD6n0jO4kdg= github.com/ipfs/go-metrics-interface v0.0.1/go.mod h1:6s6euYU4zowdslK0GKHmqaIZ3j/b/tL7HTWtJ4VPgWY= -github.com/ipfs/go-mfs v0.2.1 h1:5jz8+ukAg/z6jTkollzxGzhkl3yxm022Za9f2nL5ab8= -github.com/ipfs/go-mfs v0.2.1/go.mod h1:Woj80iuw4ajDnIP6+seRaoHpPsc9hmL0pk/nDNDWP88= -github.com/ipfs/go-namesys v0.7.0 h1:xqosk71GIVRkFDtF2UNRcXn4LdNeo7tzuy8feHD6NbU= -github.com/ipfs/go-namesys v0.7.0/go.mod h1:KYSZBVZG3VJC34EfqqJPG7T48aWgxseoMPAPA5gLyyQ= -github.com/ipfs/go-path v0.2.1/go.mod h1:NOScsVgxfC/eIw4nz6OiGwK42PjaSJ4Y/ZFPn1Xe07I= -github.com/ipfs/go-path v0.3.1 h1:wkeaCWE/NTuuPGlEkLTsED5UkzfKYZpxaFFPgk8ZVLE= -github.com/ipfs/go-path v0.3.1/go.mod h1:eNLsxJEEMxn/CDzUJ6wuNl+6No6tEUhOZcPKsZsYX0E= -github.com/ipfs/go-peertaskqueue v0.1.0/go.mod h1:Jmk3IyCcfl1W3jTW3YpghSwSEC6IJ3Vzz/jUmWw8Z0U= -github.com/ipfs/go-peertaskqueue v0.7.0/go.mod h1:M/akTIE/z1jGNXMU7kFB4TeSEFvj68ow0Rrb04donIU= github.com/ipfs/go-peertaskqueue v0.8.1 h1:YhxAs1+wxb5jk7RvS0LHdyiILpNmRIRnZVztekOF0pg= github.com/ipfs/go-peertaskqueue v0.8.1/go.mod h1:Oxxd3eaK279FxeydSPPVGHzbwVeHjatZ2GA8XD+KbPU= -github.com/ipfs/go-unixfs v0.2.4/go.mod h1:SUdisfUjNoSDzzhGVxvCL9QO/nKdwXdr+gbMUdqcbYw= -github.com/ipfs/go-unixfs v0.3.1/go.mod h1:h4qfQYzghiIc8ZNFKiLMFWOTzrWIAtzYQ59W/pCFf1o= -github.com/ipfs/go-unixfs v0.4.4 h1:D/dLBOJgny5ZLIur2vIXVQVW0EyDHdOMBDEhgHrt6rY= -github.com/ipfs/go-unixfs v0.4.4/go.mod h1:TSG7G1UuT+l4pNj91raXAPkX0BhJi3jST1FDTfQ5QyM= -github.com/ipfs/go-unixfsnode v1.1.2/go.mod h1:5dcE2x03pyjHk4JjamXmunTMzz+VUtqvPwZjIEkfV6s= -github.com/ipfs/go-unixfsnode v1.5.2 h1:CvsiTt58W2uR5dD8bqQv+aAY0c1qolmXmSyNbPHYiew= -github.com/ipfs/go-unixfsnode v1.5.2/go.mod h1:NlOebRwYx8lMCNMdhAhEspYPBD3obp7TE0LvBqHY+ks= -github.com/ipfs/go-verifcid v0.0.1/go.mod h1:5Hrva5KBeIog4A+UpqlaIU+DEstipcJYQQZc0g37pY0= +github.com/ipfs/go-unixfs v0.4.5 h1:wj8JhxvV1G6CD7swACwSKYa+NgtdWC1RUit+gFnymDU= +github.com/ipfs/go-unixfsnode v1.6.0 h1:JOSA02yaLylRNi2rlB4ldPr5VcZhcnaIVj5zNLcOjDo= +github.com/ipfs/go-unixfsnode v1.6.0/go.mod h1:PVfoyZkX1B34qzT3vJO4nsLUpRCyhnMuHBznRcXirlk= github.com/ipfs/go-verifcid v0.0.2 h1:XPnUv0XmdH+ZIhLGKg6U2vaPaRDXb9urMyNVCE7uvTs= -github.com/ipfs/go-verifcid v0.0.2/go.mod h1:40cD9x1y4OWnFXbLNJYRe7MpNvWlMn3LZAG5Wb4xnPU= -github.com/ipfs/interface-go-ipfs-core v0.11.0 h1:n1tplrwsz7oZXkpkZM5a3MDBxksMfSQ103ej4e+l7NA= -github.com/ipfs/interface-go-ipfs-core v0.11.0/go.mod h1:xmnoccUXY7N/Q8AIx0vFqgW926/FAZ8+do/1NTEHKsU= github.com/ipld/edelweiss v0.2.0 h1:KfAZBP8eeJtrLxLhi7r3N0cBCo7JmwSRhOJp3WSpNjk= github.com/ipld/edelweiss v0.2.0/go.mod h1:FJAzJRCep4iI8FOFlRriN9n0b7OuX3T/S9++NpBDmA4= -github.com/ipld/go-car v0.5.0 h1:kcCEa3CvYMs0iE5BzD5sV7O2EwMiCIp3uF8tA6APQT8= -github.com/ipld/go-car/v2 v2.5.1 h1:U2ux9JS23upEgrJScW8VQuxmE94560kYxj9CQUpcfmk= -github.com/ipld/go-codec-dagpb v1.3.0/go.mod h1:ga4JTU3abYApDC3pZ00BC2RSvC3qfBb9MSJkMLSwnhA= -github.com/ipld/go-codec-dagpb v1.5.0 h1:RspDRdsJpLfgCI0ONhTAnbHdySGD4t+LHSPK4X1+R0k= -github.com/ipld/go-codec-dagpb v1.5.0/go.mod h1:0yRIutEFD8o1DGVqw4RSHh+BUTlJA9XWldxaaWR/o4g= +github.com/ipld/go-car/v2 v2.9.1-0.20230325062757-fff0e4397a3d h1:22g+x1tgWSXK34i25qjs+afr7basaneEkHaglBshd2g= +github.com/ipld/go-codec-dagpb v1.6.0 h1:9nYazfyu9B1p3NAgfVdpRco3Fs2nFC72DqVsMj6rOcc= +github.com/ipld/go-codec-dagpb v1.6.0/go.mod h1:ANzFhfP2uMJxRBr8CE+WQWs5UsNa0pYtmKZ+agnUw9s= 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.14.1/go.mod h1:QcE4Y9n/ZZr8Ijg5bGPT0GqYWgZ1704nH0RDcQtgTP0= -github.com/ipld/go-ipld-prime v0.19.0 h1:5axC7rJmPc17Emw6TelxGwnzALk0PdupZ2oj2roDj04= -github.com/ipld/go-ipld-prime v0.19.0/go.mod h1:Q9j3BaVXwaA3o5JUDNvptDDr/x8+F7FG6XJ8WI3ILg4= -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/ipld/go-ipld-prime v0.20.0 h1:Ud3VwE9ClxpO2LkCYP7vWPc0Fo+dYdYzgxUJZ3uRG4g= +github.com/ipld/go-ipld-prime v0.20.0/go.mod h1:PzqZ/ZR981eKbgdr3y2DJYeD/8bgMawdGVlJDE8kK+M= github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= -github.com/jbenet/go-cienv v0.0.0-20150120210510-1bb1476777ec/go.mod h1:rGaEvXB4uRSZMmzKNLoXvTu1sfx+1kv/DojUlPrSZGs= github.com/jbenet/go-cienv v0.1.0 h1:Vc/s0QbQtoxX8MwwSLWWh+xNNZvM3Lw7NsTcHrvvhMc= github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA= github.com/jbenet/go-random v0.0.0-20190219211222-123a90aedc0c h1:uUx61FiAa1GI6ZmVd2wf2vULeQZIKG66eybjNXKYCz4= -github.com/jbenet/go-temp-err-catcher v0.0.0-20150120210811-aac704a3f4f2/go.mod h1:8GXXJV31xl8whumTzdZsTt3RnUIiPqzkyf7mxToRCMs= github.com/jbenet/go-temp-err-catcher v0.1.0 h1:zpb3ZH6wIE8Shj2sKS+khgRvf7T7RABoLk/+KKHggpk= github.com/jbenet/go-temp-err-catcher v0.1.0/go.mod h1:0kJRvmDZXNMIiJirNPEYfhpPwbGVtZVWC34vc5WLsDk= github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY= github.com/jbenet/goprocess v0.1.3/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= github.com/jbenet/goprocess v0.1.4 h1:DRGOFReOMqqDNXwW70QkacFW0YN9QnwLV0Vqk+3oU0o= github.com/jbenet/goprocess v0.1.4/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= -github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs= -github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM= -github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o= -github.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxyjn/mY9zx4tFonSg= -github.com/jcmturner/gokrb5/v8 v8.4.2/go.mod h1:sb+Xq/fTY5yktf/VxLsE3wlfPqQjp0aWNYyvBVK62bc= -github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc= github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= -github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= @@ -678,7 +472,6 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI 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.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/compress v1.15.12 h1:YClS/PImqYbn+UILDnqxQCZ3RehC9N318SU3kElDUEM= github.com/klauspost/compress v1.15.12/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= @@ -687,7 +480,6 @@ github.com/klauspost/cpuid/v2 v2.2.3 h1:sxCkb+qR91z4vsqw4vGGZlDgPz3G7gjaLyK3V8y7 github.com/klauspost/cpuid/v2 v2.2.3/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/koron/go-ssdp v0.0.0-20180514024734-4a0ed625a78b/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk= github.com/koron/go-ssdp v0.0.0-20191105050749-2e1c40ed0b5d/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk= github.com/koron/go-ssdp v0.0.3 h1:JivLMY45N76b4p/vsWGOKewBQu6uf39y8l+AQ7sDKx8= github.com/koron/go-ssdp v0.0.3/go.mod h1:b2MxI6yh02pKrsyNoQUsk4+YNikaGhe4894J+Q5lDvA= @@ -695,8 +487,8 @@ github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFB github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= @@ -704,250 +496,80 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= -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-buffer-pool v0.0.1/go.mod h1:xtyIz9PMobb13WaxR6Zo1Pd1zXJKYg0a8KiIvDp3TzQ= github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM= github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38yPW7c= github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic= -github.com/libp2p/go-conn-security-multistream v0.1.0/go.mod h1:aw6eD7LOsHEX7+2hJkDxw1MteijaVcI+/eP2/x3J1xc= -github.com/libp2p/go-conn-security-multistream v0.2.0/go.mod h1:hZN4MjlNetKD3Rq5Jb/P5ohUnFLNzEAR4DLSzpn2QLU= -github.com/libp2p/go-conn-security-multistream v0.2.1/go.mod h1:cR1d8gA0Hr59Fj6NhaTpFhJZrjSYuNmhpT2r25zYR70= github.com/libp2p/go-doh-resolver v0.4.0 h1:gUBa1f1XsPwtpE1du0O+nnZCUqtG7oYi7Bb+0S7FQqw= github.com/libp2p/go-doh-resolver v0.4.0/go.mod h1:v1/jwsFusgsWIGX/c6vCRrnJ60x7bhTiq/fs2qt0cAg= -github.com/libp2p/go-eventbus v0.1.0/go.mod h1:vROgu5cs5T7cv7POWlWxBaVLxfSegC5UGQf8A2eEmx4= -github.com/libp2p/go-eventbus v0.2.1/go.mod h1:jc2S4SoEVPP48H9Wpzm5aiGwUCBMfGhVhhBjyhhCJs8= github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8= github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.1.0/go.mod h1:6D/2OBauqLUoqcADOJpn9WbKqvaM07tDw68qHM0BxUM= -github.com/libp2p/go-libp2p v0.1.1/go.mod h1:I00BRo1UuUSdpuc8Q2mN7yDF/oTUTRAX6JWpTiK9Rp8= -github.com/libp2p/go-libp2p v0.6.1/go.mod h1:CTFnWXogryAHjXAKEbOf1OWY+VeAP3lDMZkfEI5sT54= -github.com/libp2p/go-libp2p v0.7.0/go.mod h1:hZJf8txWeCduQRDC/WSqBGMxaTHCOYHt2xSU1ivxn0k= -github.com/libp2p/go-libp2p v0.7.4/go.mod h1:oXsBlTLF1q7pxr+9w6lqzS1ILpyHsaBPniVO7zIHGMw= -github.com/libp2p/go-libp2p v0.8.1/go.mod h1:QRNH9pwdbEBpx5DTJYg+qxcVaDMAz3Ee/qDKwXujH5o= -github.com/libp2p/go-libp2p v0.14.3/go.mod h1:d12V4PdKbpL0T1/gsUNN8DfgMuRPDX8bS2QxCZlwRH0= github.com/libp2p/go-libp2p v0.26.4 h1:VA9ChjN0n1BwwfU/dqx4Zj9ezXtIxGk8FyJPwFONqxs= github.com/libp2p/go-libp2p v0.26.4/go.mod h1:x75BN32YbwuY0Awm2Uix4d4KOz+/4piInkp4Wr3yOo8= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= -github.com/libp2p/go-libp2p-autonat v0.1.0/go.mod h1:1tLf2yXxiE/oKGtDwPYWTSYG3PtvYlJmg7NeVtPRqH8= -github.com/libp2p/go-libp2p-autonat v0.1.1/go.mod h1:OXqkeGOY2xJVWKAGV2inNF5aKN/djNA3fdpCWloIudE= -github.com/libp2p/go-libp2p-autonat v0.2.0/go.mod h1:DX+9teU4pEEoZUqR1PiMlqliONQdNbfzE1C718tcViI= -github.com/libp2p/go-libp2p-autonat v0.2.1/go.mod h1:MWtAhV5Ko1l6QBsHQNSuM6b1sRkXrpk0/LqCr+vCVxI= -github.com/libp2p/go-libp2p-autonat v0.2.2/go.mod h1:HsM62HkqZmHR2k1xgX34WuWDzk/nBwNHoeyyT4IWV6A= -github.com/libp2p/go-libp2p-autonat v0.4.2/go.mod h1:YxaJlpr81FhdOv3W3BTconZPfhaYivRdf53g+S2wobk= -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/go.mod h1:eduNKXGTioTuQAUcZ5epXi9vMl+t4d8ugUBRQ4SqaNQ= -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/go.mod h1:t/ktoFIUzM6uLQ+o1G6NuBl2ANhBKN9Bc8jRIk31MoA= -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= -github.com/libp2p/go-libp2p-core v0.0.4/go.mod h1:jyuCQP356gzfCFtRKyvAbNkyeuxb7OlyhWZ3nls5d2I= -github.com/libp2p/go-libp2p-core v0.2.0/go.mod h1:X0eyB0Gy93v0DZtSYbEM7RnMChm9Uv3j7yRXjO77xSI= -github.com/libp2p/go-libp2p-core v0.2.2/go.mod h1:8fcwTbsG2B+lTgRJ1ICZtiM5GWCWZVoVrLaDRvIRng0= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= github.com/libp2p/go-libp2p-core v0.3.0/go.mod h1:ACp3DmS3/N64c2jDzcV429ukDpicbL6+TrrxANBjPGw= -github.com/libp2p/go-libp2p-core v0.3.1/go.mod h1:thvWy0hvaSBhnVBaW37BvzgVV68OUhgJJLAa6almrII= -github.com/libp2p/go-libp2p-core v0.4.0/go.mod h1:49XGI+kc38oGVwqSBhDEwytaAxgZasHhFfQKibzTls0= -github.com/libp2p/go-libp2p-core v0.5.0/go.mod h1:49XGI+kc38oGVwqSBhDEwytaAxgZasHhFfQKibzTls0= -github.com/libp2p/go-libp2p-core v0.5.1/go.mod h1:uN7L2D4EvPCvzSH5SrhR72UWbnSGpt5/a35Sm4upn4Y= -github.com/libp2p/go-libp2p-core v0.5.4/go.mod h1:uN7L2D4EvPCvzSH5SrhR72UWbnSGpt5/a35Sm4upn4Y= -github.com/libp2p/go-libp2p-core v0.5.5/go.mod h1:vj3awlOr9+GMZJFH9s4mpt9RHHgGqeHCopzbYKZdRjM= -github.com/libp2p/go-libp2p-core v0.5.6/go.mod h1:txwbVEhHEXikXn9gfC7/UDDw7rkxuX0bJvM49Ykaswo= -github.com/libp2p/go-libp2p-core v0.5.7/go.mod h1:txwbVEhHEXikXn9gfC7/UDDw7rkxuX0bJvM49Ykaswo= -github.com/libp2p/go-libp2p-core v0.6.0/go.mod h1:txwbVEhHEXikXn9gfC7/UDDw7rkxuX0bJvM49Ykaswo= -github.com/libp2p/go-libp2p-core v0.7.0/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= -github.com/libp2p/go-libp2p-core v0.8.0/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= -github.com/libp2p/go-libp2p-core v0.8.1/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= -github.com/libp2p/go-libp2p-core v0.8.2/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= -github.com/libp2p/go-libp2p-core v0.8.5/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= -github.com/libp2p/go-libp2p-crypto v0.1.0/go.mod h1:sPUokVISZiy+nNuTTH/TY+leRSxnFj/2GLjtOTW90hI= -github.com/libp2p/go-libp2p-discovery v0.1.0/go.mod h1:4F/x+aldVHjHDHuX85x1zWoFTGElt8HnoDzwkFZm29g= -github.com/libp2p/go-libp2p-discovery v0.2.0/go.mod h1:s4VGaxYMbw4+4+tsoQTqh7wfxg97AEdo4GYBt6BadWg= -github.com/libp2p/go-libp2p-discovery v0.3.0/go.mod h1:o03drFnz9BVAZdzC/QUQ+NeQOu38Fu7LJGEOK2gQltw= -github.com/libp2p/go-libp2p-discovery v0.5.0/go.mod h1:+srtPIU9gDaBNu//UHvcdliKBIcr4SfDcm0/PfPJLug= -github.com/libp2p/go-libp2p-kad-dht v0.21.1 h1:xpfp8/t9+X2ip1l8Umap1/UGNnJ3RHJgKGAEsnRAlTo= -github.com/libp2p/go-libp2p-kad-dht v0.21.1/go.mod h1:Oy8wvbdjpB70eS5AaFaI68tOtrdo3KylTvXDjikxqFo= +github.com/libp2p/go-libp2p-kad-dht v0.22.0 h1:cW2nGgG0hztDM42tOPyC5cVflD7EzLaHM0/Kjol6Wio= +github.com/libp2p/go-libp2p-kad-dht v0.22.0/go.mod h1:hareSo3Z/GJ7nUWPMj7XhD/56a7+rRltYCWwCuy3FQk= github.com/libp2p/go-libp2p-kbucket v0.3.1/go.mod h1:oyjT5O7tS9CQurok++ERgc46YLwEpuGoFq9ubvoUOio= github.com/libp2p/go-libp2p-kbucket v0.5.0 h1:g/7tVm8ACHDxH29BGrpsQlnNeu+6OF1A9bno/4/U1oA= github.com/libp2p/go-libp2p-kbucket v0.5.0/go.mod h1:zGzGCpQd78b5BNTDGHNDLaTt9aDK/A02xeZp9QeFC4U= -github.com/libp2p/go-libp2p-loggables v0.1.0/go.mod h1:EyumB2Y6PrYjr55Q3/tiJ/o3xoDasoRYM7nOzEpoa90= -github.com/libp2p/go-libp2p-mplex v0.2.0/go.mod h1:Ejl9IyjvXJ0T9iqUTE1jpYATQ9NM3g+OtR+EMMODbKo= -github.com/libp2p/go-libp2p-mplex v0.2.1/go.mod h1:SC99Rxs8Vuzrf/6WhmH41kNn13TiYdAWNYHrwImKLnE= -github.com/libp2p/go-libp2p-mplex v0.2.2/go.mod h1:74S9eum0tVQdAfFiKxAyKzNdSuLqw5oadDq7+L/FELo= -github.com/libp2p/go-libp2p-mplex v0.2.3/go.mod h1:CK3p2+9qH9x+7ER/gWWDYJ3QW5ZxWDkm+dVvjfuG3ek= -github.com/libp2p/go-libp2p-mplex v0.4.0/go.mod h1:yCyWJE2sc6TBTnFpjvLuEJgTSw/u+MamvzILKdX7asw= -github.com/libp2p/go-libp2p-mplex v0.4.1/go.mod h1:cmy+3GfqfM1PceHTLL7zQzAAYaryDu6iPSC+CIb094g= -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= -github.com/libp2p/go-libp2p-netutil v0.1.0/go.mod h1:3Qv/aDqtMLTUyQeundkKsA+YCThNdbQD54k3TqjpbFU= -github.com/libp2p/go-libp2p-noise v0.2.0/go.mod h1:IEbYhBBzGyvdLBoxxULL/SGbJARhUeqlO8lVSREYu2Q= -github.com/libp2p/go-libp2p-peer v0.2.0/go.mod h1:RCffaCvUyW2CJmG2gAWVqwePwW7JMgxjsHm7+J5kjWY= -github.com/libp2p/go-libp2p-peerstore v0.1.0/go.mod h1:2CeHkQsr8svp4fZ+Oi9ykN1HBb6u0MOvdJ7YIsmcwtY= -github.com/libp2p/go-libp2p-peerstore v0.1.3/go.mod h1:BJ9sHlm59/80oSkpWgr1MyY1ciXAXV397W6h1GH/uKI= github.com/libp2p/go-libp2p-peerstore v0.1.4/go.mod h1:+4BDbDiiKf4PzpANZDAT+knVdLxvqh7hXOujessqdzs= -github.com/libp2p/go-libp2p-peerstore v0.2.0/go.mod h1:N2l3eVIeAitSg3Pi2ipSrJYnqhVnMNQZo9nkSCuAbnQ= -github.com/libp2p/go-libp2p-peerstore v0.2.1/go.mod h1:NQxhNjWxf1d4w6PihR8btWIRjwRLBr4TYKfNgrUkOPA= -github.com/libp2p/go-libp2p-peerstore v0.2.2/go.mod h1:NQxhNjWxf1d4w6PihR8btWIRjwRLBr4TYKfNgrUkOPA= -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-pnet v0.2.0/go.mod h1:Qqvq6JH/oMZGwqs3N1Fqhv8NVhrdYcO0BW4wssv21LA= github.com/libp2p/go-libp2p-pubsub v0.9.0 h1:mcLb4WzwhUG4OKb0rp1/bYMd/DYhvMyzJheQH3LMd1s= github.com/libp2p/go-libp2p-pubsub v0.9.0/go.mod h1:OEsj0Cc/BpkqikXRTrVspWU/Hx7bMZwHP+6vNMd+c7I= github.com/libp2p/go-libp2p-pubsub-router v0.6.0 h1:D30iKdlqDt5ZmLEYhHELCMRj8b4sFAqrUcshIUvVP/s= github.com/libp2p/go-libp2p-pubsub-router v0.6.0/go.mod h1:FY/q0/RBTKsLA7l4vqC2cbRbOvyDotg8PJQ7j8FDudE= -github.com/libp2p/go-libp2p-quic-transport v0.10.0/go.mod h1:RfJbZ8IqXIhxBRm5hqUEJqjiiY8xmEuq3HUDS993MkA= -github.com/libp2p/go-libp2p-record v0.1.0/go.mod h1:ujNc8iuE5dlKWVy6wuL6dd58t0n7xI4hAIl8pE6wu5Q= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= github.com/libp2p/go-libp2p-record v0.2.0/go.mod h1:I+3zMkvvg5m2OcSdoL0KPljyJyvNDFGKX7QdlpYUcwk= github.com/libp2p/go-libp2p-routing-helpers v0.6.1 h1:tI3rHOf/FDQsxC2pHBaOZiqPJ0MZYyzGAf4V45xla4U= github.com/libp2p/go-libp2p-routing-helpers v0.6.1/go.mod h1:R289GUxUMzRXIbWGSuUUTPrlVJZ3Y/pPz495+qgXJX8= -github.com/libp2p/go-libp2p-secio v0.1.0/go.mod h1:tMJo2w7h3+wN4pgU2LSYeiKPrfqBgkOsdiKK77hE7c8= -github.com/libp2p/go-libp2p-secio v0.2.0/go.mod h1:2JdZepB8J5V9mBp79BmwsaPQhRPNN2NrnB2lKQcdy6g= -github.com/libp2p/go-libp2p-secio v0.2.1/go.mod h1:cWtZpILJqkqrSkiYcDBh5lA3wbT2Q+hz3rJQq3iftD8= -github.com/libp2p/go-libp2p-secio v0.2.2/go.mod h1:wP3bS+m5AUnFA+OFO7Er03uO1mncHG0uVwGrwvjYlNY= -github.com/libp2p/go-libp2p-swarm v0.1.0/go.mod h1:wQVsCdjsuZoc730CgOvh5ox6K8evllckjebkdiY5ta4= -github.com/libp2p/go-libp2p-swarm v0.2.2/go.mod h1:fvmtQ0T1nErXym1/aa1uJEyN7JzaTNyBcHImCxRpPKU= -github.com/libp2p/go-libp2p-swarm v0.2.3/go.mod h1:P2VO/EpxRyDxtChXz/VPVXyTnszHvokHKRhfkEgFKNM= -github.com/libp2p/go-libp2p-swarm v0.2.8/go.mod h1:JQKMGSth4SMqonruY0a8yjlPVIkb0mdNSwckW7OYziM= -github.com/libp2p/go-libp2p-swarm v0.3.0/go.mod h1:hdv95GWCTmzkgeJpP+GK/9D9puJegb7H57B5hWQR5Kk= -github.com/libp2p/go-libp2p-swarm v0.5.0/go.mod h1:sU9i6BoHE0Ve5SKz3y9WfKrh8dUat6JknzUehFx8xW4= -github.com/libp2p/go-libp2p-testing v0.0.2/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= -github.com/libp2p/go-libp2p-testing v0.0.3/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= -github.com/libp2p/go-libp2p-testing v0.0.4/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= -github.com/libp2p/go-libp2p-testing v0.1.0/go.mod h1:xaZWMJrPUM5GlDBxCeGUi7kI4eqnjVyavGroI2nxEM0= -github.com/libp2p/go-libp2p-testing v0.1.1/go.mod h1:xaZWMJrPUM5GlDBxCeGUi7kI4eqnjVyavGroI2nxEM0= -github.com/libp2p/go-libp2p-testing v0.1.2-0.20200422005655-8775583591d8/go.mod h1:Qy8sAncLKpwXtS2dSnDOP8ktexIAHKu+J+pnZOFZLTc= -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.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA= -github.com/libp2p/go-libp2p-tls v0.1.3/go.mod h1:wZfuewxOndz5RTnCAxFliGjvYSDA40sKitV4c50uI1M= -github.com/libp2p/go-libp2p-transport-upgrader v0.1.1/go.mod h1:IEtA6or8JUbsV07qPW4r01GnTenLW4oi3lOPbUMGJJA= -github.com/libp2p/go-libp2p-transport-upgrader v0.2.0/go.mod h1:mQcrHj4asu6ArfSoMuyojOdjx73Q47cYD7s5+gZOlns= -github.com/libp2p/go-libp2p-transport-upgrader v0.3.0/go.mod h1:i+SKzbRnvXdVbU3D1dwydnTmKRPXiAR/fyvi1dXuL4o= -github.com/libp2p/go-libp2p-transport-upgrader v0.4.2/go.mod h1:NR8ne1VwfreD5VIWIU62Agt/J18ekORFU/j1i2y8zvk= github.com/libp2p/go-libp2p-xor v0.1.0 h1:hhQwT4uGrBcuAkUGXADuPltalOdpf9aag9kaYNT2tLA= github.com/libp2p/go-libp2p-xor v0.1.0/go.mod h1:LSTM5yRnjGZbWNTA/hRwq2gGFrvRIbQJscoIL/u6InY= -github.com/libp2p/go-libp2p-yamux v0.2.0/go.mod h1:Db2gU+XfLpm6E4rG5uGCFX6uXA8MEXOxFcRoXUODaK8= -github.com/libp2p/go-libp2p-yamux v0.2.1/go.mod h1:1FBXiHDk1VyRM1C0aez2bCfHQ4vMZKkAQzZbkSQt5fI= -github.com/libp2p/go-libp2p-yamux v0.2.2/go.mod h1:lIohaR0pT6mOt0AZ0L2dFze9hds9Req3OfS+B+dv4qw= -github.com/libp2p/go-libp2p-yamux v0.2.5/go.mod h1:Zpgj6arbyQrmZ3wxSZxfBmbdnWtbZ48OpsfmQVTErwA= -github.com/libp2p/go-libp2p-yamux v0.2.7/go.mod h1:X28ENrBMU/nm4I3Nx4sZ4dgjZ6VhLEn0XhIoZ5viCwU= -github.com/libp2p/go-libp2p-yamux v0.2.8/go.mod h1:/t6tDqeuZf0INZMTgd0WxIRbtK2EzI2h7HbFm9eAKI4= -github.com/libp2p/go-libp2p-yamux v0.4.0/go.mod h1:+DWDjtFMzoAwYLVkNZftoucn7PelNoy5nm3tZ3/Zw30= -github.com/libp2p/go-libp2p-yamux v0.5.0/go.mod h1:AyR8k5EzyM2QN9Bbdg6X1SkVVuqLwTGf0L4DFq9g6po= -github.com/libp2p/go-libp2p-yamux v0.5.4/go.mod h1:tfrXbyaTqqSU654GTvK3ocnSZL3BuHoeTSqhcel1wsE= -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/go.mod h1:VzZhTXkMucEGGEOSKddrwGiOv0tUhgnKqNEmIAz/bPU= -github.com/libp2p/go-mplex v0.0.3/go.mod h1:pK5yMLmOoBR1pNCqDlA2GQrdAVTMkqFalaTWe7l4Yd0= -github.com/libp2p/go-mplex v0.1.0/go.mod h1:SXgmdki2kwCUlCCbfGLEgHjC4pFqhTp0ZoV6aiKgxDU= -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/go.mod h1:0Oy/A9PQlwBytDRp4wSkFnzHYDKcpLot35JQ6msjvYQ= github.com/libp2p/go-mplex v0.7.0 h1:BDhFZdlk5tbr0oyFq/xv/NPGfjbnrsDam1EvutpBDbY= github.com/libp2p/go-mplex v0.7.0/go.mod h1:rW8ThnRcYWft/Jb2jeORBmPd6xuG3dGxWN/W168L9EU= -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= -github.com/libp2p/go-msgio v0.0.6/go.mod h1:4ecVB6d9f4BDSL5fqvPiC4A3KivjWn+Venn/1ALLMWA= github.com/libp2p/go-msgio v0.3.0 h1:mf3Z8B1xcFN314sWX+2vOTShIE0Mmn2TXn3YCUQGNj0= github.com/libp2p/go-msgio v0.3.0/go.mod h1:nyRM819GmVaF9LX3l03RMh10QdOroF++NBbxAb0mmDM= -github.com/libp2p/go-nat v0.0.3/go.mod h1:88nUEt0k0JD45Bk93NIwDqjlhiOwOoV36GchpcVc1yI= -github.com/libp2p/go-nat v0.0.4/go.mod h1:Nmw50VAvKuk38jUBcmNh6p9lUJLoODbJRvYAa/+KSDo= -github.com/libp2p/go-nat v0.0.5/go.mod h1:B7NxsVNPZmRLvMOwiEO1scOSyjA56zxYAGv1yQgRkEU= github.com/libp2p/go-nat v0.1.0 h1:MfVsH6DLcpa04Xr+p8hmVRG4juse0s3J8HyNWYHffXg= github.com/libp2p/go-nat v0.1.0/go.mod h1:X7teVkwRHNInVNWQiO/tAiAVRwSr5zoRz4YSTC3uRBM= 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/go.mod h1:AqhkMh0VuWmfgtxKPp3Oc1LdU5QSWS7wl0QLhSZqXxQ= github.com/libp2p/go-netroute v0.2.1 h1:V8kVrpD8GK0Riv15/7VN6RbUQ3URNZVosw7H2v9tksU= github.com/libp2p/go-netroute v0.2.1/go.mod h1:hraioZr0fhBjG0ZRXJJ6Zj2IVEVNx6tDTFQfSmcq7mQ= -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= -github.com/libp2p/go-openssl v0.0.5/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= -github.com/libp2p/go-openssl v0.0.7/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= -github.com/libp2p/go-reuseport v0.0.1/go.mod h1:jn6RmB1ufnQwl0Q1f+YxAj8isJgDCQzaaxIFYDhcYEA= -github.com/libp2p/go-reuseport v0.0.2/go.mod h1:SPD+5RwGC7rcnzngoYC86GjPzjSywuQyMVAheVBD9nQ= github.com/libp2p/go-reuseport v0.2.0 h1:18PRvIMlpY6ZK85nIAicSBuXXvrYoSw3dsBAR7zc560= github.com/libp2p/go-reuseport v0.2.0/go.mod h1:bvVho6eLMm6Bz5hmU0LYN3ixd3nPPvtIlaURZZgOY4k= -github.com/libp2p/go-reuseport-transport v0.0.2/go.mod h1:YkbSDrvjUVDL6b8XqriyA20obEtsW9BLkuOUyQAOCbs= -github.com/libp2p/go-reuseport-transport v0.0.3/go.mod h1:Spv+MPft1exxARzP2Sruj2Wb5JSyHNncjf1Oi2dEbzM= -github.com/libp2p/go-reuseport-transport v0.0.4/go.mod h1:trPa7r/7TJK/d+0hdBLOCGvpQQVOU74OXbNCIMkufGw= 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/go.mod h1:syPvOmNs24S3dFVGJA1/mrqdeijPxLV2Le3BRLKd68k= -github.com/libp2p/go-stream-muxer v0.0.1/go.mod h1:bAo8x7YkSpadMTbtTaxGVHWUQsR/l5MEaHbKaliuT14= -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/go.mod h1:yDh8abSIzmZtqtOt64gFJUXEryejzNb0lisTt+fAMJA= -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= -github.com/libp2p/go-tcp-transport v0.2.0/go.mod h1:vX2U0CnWimU4h0SGSEsg++AzvBcroCGYw28kh94oLe0= -github.com/libp2p/go-tcp-transport v0.2.3/go.mod h1:9dvr03yqrPyYGIEN6Dy5UvdJZjyPFvl1S/igQ5QD1SU= -github.com/libp2p/go-testutil v0.1.0/go.mod h1:81b2n5HypcVyrCg/MJx4Wgfp/VHojytjVe/gLzZ2Ehc= -github.com/libp2p/go-ws-transport v0.1.0/go.mod h1:rjw1MG1LU9YDC6gzmwObkPd/Sqwhw7yT74kj3raBFuo= -github.com/libp2p/go-ws-transport v0.2.0/go.mod h1:9BHJz/4Q5A9ludYWKoGCFC5gUElzlHoKzu0yY9p/klM= -github.com/libp2p/go-ws-transport v0.3.0/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-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= -github.com/libp2p/go-yamux v1.3.0/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= -github.com/libp2p/go-yamux v1.3.3/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= -github.com/libp2p/go-yamux v1.3.5/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= -github.com/libp2p/go-yamux v1.3.7/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/hkmpooHE= -github.com/libp2p/go-yamux v1.4.0/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/hkmpooHE= -github.com/libp2p/go-yamux v1.4.1/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/hkmpooHE= -github.com/libp2p/go-yamux/v2 v2.2.0/go.mod h1:3So6P6TV6r75R9jiBpiIKgU/66lOarCZjqROGxzPpPQ= github.com/libp2p/go-yamux/v4 v4.0.0 h1:+Y80dV2Yx/kv7Y7JKu0LECyVdMXm1VUoko+VQ9rBfZQ= github.com/libp2p/go-yamux/v4 v4.0.0/go.mod h1:NWjl8ZTLOGlozrXSOZ/HlfG++39iKNnM5wwmtQP1YB4= github.com/libp2p/zeroconf/v2 v2.2.0 h1:Cup06Jv6u81HLhIj1KasuNM/RHHrJ8T7wOTS4+Tv53Q= github.com/libp2p/zeroconf/v2 v2.2.0/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= -github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= -github.com/lucas-clemente/quic-go v0.19.3/go.mod h1:ADXpNbTQjq1hIzCpB+y/k5iz4n4z4IwqoLb94Kh5Hu8= 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= github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/marten-seemann/qpack v0.2.1/go.mod h1:F7Gl5L1jIgN1D11ucXefiuJS9UMVP2opoCp2jDKb7wc= -github.com/marten-seemann/qtls v0.10.0/go.mod h1:UvMd1oaYDACI99/oZUYLzMCkBXQVT0aGm99sJhbT8hs= -github.com/marten-seemann/qtls-go1-15 v0.1.1/go.mod h1:GyFwywLKkRt+6mfU99csTEY1joMZz5vmB1WNZH3P81I= 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= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= -github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= 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.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= -github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/miekg/dns v1.1.12/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/miekg/dns v1.1.28/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA= @@ -960,20 +582,12 @@ github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc h1:PTfri+PuQmWDqERdn github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc/go.mod h1:cGKTAVKx4SxOuR/czcZ/E2RSJ3sfHs8FpHhQ5CWMf9s= github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= -github.com/minio/sha256-simd v0.0.0-20190328051042-05b4dd3047e5/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= -github.com/minio/sha256-simd v0.1.0/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g= github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM= -github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= -github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= -github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= -github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= -github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= @@ -983,7 +597,6 @@ github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3Rllmb github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= -github.com/mr-tron/base58 v1.1.1/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mr-tron/base58 v1.1.3/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= @@ -994,45 +607,25 @@ github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYg github.com/multiformats/go-base36 v0.1.0/go.mod h1:kFGE83c6s80PklsHO9sRn2NCoffoRdUUOENyW/Vv6sM= github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0= github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4= -github.com/multiformats/go-multiaddr v0.0.1/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= -github.com/multiformats/go-multiaddr v0.0.2/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= -github.com/multiformats/go-multiaddr v0.0.4/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= github.com/multiformats/go-multiaddr v0.1.0/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo= github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4= -github.com/multiformats/go-multiaddr v0.2.1/go.mod h1:s/Apk6IyxfvMjDafnhJgJ3/46z7tZ04iMk5wP4QMGGE= -github.com/multiformats/go-multiaddr v0.2.2/go.mod h1:NtfXiOtHvghW9KojvtySjH5y0u0xW5UouOmQQrn6a3Y= -github.com/multiformats/go-multiaddr v0.3.0/go.mod h1:dF9kph9wfJ+3VLAaeBqo9Of8x4fJxp6ggJGteB8HQTI= -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.8.0 h1:aqjksEcqK+iD/Foe1RRFsGZh8+XFiGo7FgUCZlpv3LU= github.com/multiformats/go-multiaddr v0.8.0/go.mod h1:Fs50eBDWvZu+l3/9S6xAE7ZYj6yhxlvaVZjakWN7xRs= -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= github.com/multiformats/go-multiaddr-dns v0.3.0/go.mod h1:mNzQ4eTGDg0ll1N9jKPOUogZPoJ30W8a7zk66FQPpdQ= github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A= github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk= -github.com/multiformats/go-multiaddr-fmt v0.0.1/go.mod h1:aBYjqL4T/7j4Qx+R73XSv/8JsgnRFlf0w2KGLCmXl3Q= github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E= github.com/multiformats/go-multiaddr-fmt v0.1.0/go.mod h1:hGtDIW4PU4BqJ50gW2quDuPVjyWNZxToGUh/HwTZYJo= -github.com/multiformats/go-multiaddr-net v0.0.1/go.mod h1:nw6HSxNmCIQH27XPGBuX+d1tnvM7ihcFwHMSstNAVUU= -github.com/multiformats/go-multiaddr-net v0.1.0/go.mod h1:5JNbcfBOP4dnhoZOv10JJVkJO0pCCEf8mTnipAo2UZQ= github.com/multiformats/go-multiaddr-net v0.1.1/go.mod h1:5JNbcfBOP4dnhoZOv10JJVkJO0pCCEf8mTnipAo2UZQ= -github.com/multiformats/go-multiaddr-net v0.1.2/go.mod h1:QsWt3XK/3hwvNxZJp92iMQKME1qHfpYmyIjFVsSOY6Y= -github.com/multiformats/go-multiaddr-net v0.1.3/go.mod h1:ilNnaM9HbmVFqsb/qcNysjCu4PVONlrBZpHIrw/qQuA= -github.com/multiformats/go-multiaddr-net v0.1.4/go.mod h1:ilNnaM9HbmVFqsb/qcNysjCu4PVONlrBZpHIrw/qQuA= -github.com/multiformats/go-multiaddr-net v0.1.5/go.mod h1:ilNnaM9HbmVFqsb/qcNysjCu4PVONlrBZpHIrw/qQuA= -github.com/multiformats/go-multiaddr-net v0.2.0/go.mod h1:gGdH3UXny6U3cKKYCvpXI5rnK7YaOIEOPVDI9tsJbEA= github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= github.com/multiformats/go-multibase v0.0.3/go.mod h1:5+1R4eQrT3PkYZ24C3W2Ue2tPwIdYQD509ZjSb5y9Oc= github.com/multiformats/go-multibase v0.1.1 h1:3ASCDsuLX8+j4kx58qnJ4YFq/JWTJpCyDW27ztsVTOI= github.com/multiformats/go-multibase v0.1.1/go.mod h1:ZEjHE+IsUrgp5mhlEAYjMtZwK1k4haNkcaPg9aoe1a8= github.com/multiformats/go-multicodec v0.3.0/go.mod h1:qGGaQmioCDh+TeFOnxrbU0DaIPw8yFgAZgFG0V7p1qQ= -github.com/multiformats/go-multicodec v0.7.0 h1:rTUjGOwjlhGHbEMbPoSUJowG1spZTVsITRANCjKTUAQ= -github.com/multiformats/go-multicodec v0.7.0/go.mod h1:GUC8upxSBE4oG+q3kWZRw/+6yC1BqO550bjhWsJbZlw= +github.com/multiformats/go-multicodec v0.8.1 h1:ycepHwavHafh3grIbR1jIXnKCsFm0fqsfEOsJ8NtKE8= +github.com/multiformats/go-multicodec v0.8.1/go.mod h1:L3QTQvMIaVBkXOXXtVmYE+LI16i14xuaojr/H7Ai54k= github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= -github.com/multiformats/go-multihash v0.0.5/go.mod h1:lt/HCbqlQwlPBz7lv0sQCdtfcMtlJvakRUn/0Ual8po= github.com/multiformats/go-multihash v0.0.8/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= github.com/multiformats/go-multihash v0.0.10/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= github.com/multiformats/go-multihash v0.0.13/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= @@ -1041,129 +634,78 @@ github.com/multiformats/go-multihash v0.0.15/go.mod h1:D6aZrWNLFTV/ynMpKsNtB40mJ github.com/multiformats/go-multihash v0.1.0/go.mod h1:RJlXsxt6vHGaia+S8We0ErjhojtKzPP2AH4+kYM7k84= github.com/multiformats/go-multihash v0.2.1 h1:aem8ZT0VA2nCHHk7bPJ1BjUbHNciqZC/d16Vve9l108= github.com/multiformats/go-multihash v0.2.1/go.mod h1:WxoMcYG85AZVQUyRyo9s4wULvW5qrI9vb2Lt6evduFc= -github.com/multiformats/go-multistream v0.1.0/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg= -github.com/multiformats/go-multistream v0.1.1/go.mod h1:KmHZ40hzVxiaiwlj3MEbYgK9JFk2/9UktWZAF54Du38= -github.com/multiformats/go-multistream v0.2.1/go.mod h1:5GZPQZbkWOLOn3J2y4Y99vVW7vOfsAflxARk3x14o6k= -github.com/multiformats/go-multistream v0.2.2/go.mod h1:UIcnm7Zuo8HKG+HkWgfQsGL+/MIEhyTqbODbIUwSXKs= github.com/multiformats/go-multistream v0.4.1 h1:rFy0Iiyn3YT0asivDUIR05leAdwZq3de4741sbiSdfo= github.com/multiformats/go-multistream v0.4.1/go.mod h1:Mz5eykRVAjJWckE2U78c6xqdtyNUEhKSM0Lwar2p77Q= github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= -github.com/multiformats/go-varint v0.0.2/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/multiformats/go-varint v0.0.6/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8= github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= -github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= -github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= -github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= -github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= -github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= -github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= -github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= -github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= -github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= -github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= -github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= -github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/ginkgo/v2 v2.5.1 h1:auzK7OI497k6x4OvWq+TKAcpcSAlod0doAH72oIN0Jw= github.com/onsi/ginkgo/v2 v2.5.1/go.mod h1:63DOGlLAH8+REH8jUGdL3YpCpu7JODesutUjdENfUAc= -github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.16.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.24.0 h1:+0glovB9Jd6z3VR+ScSwQqXVTIfJcGA9UBM8yzQxhqg= -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= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= -github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= -github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= -github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= -github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= -github.com/openzipkin/zipkin-go v0.4.0 h1:CtfRrOVZtbDj8rt1WXjklw0kqqJQwICrCKmlfUuBUUw= -github.com/openzipkin/zipkin-go v0.4.0/go.mod h1:4c3sLeE8xjNqehmF5RpAFLPLJxXscc0R4l6Zg0P1tTQ= -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/openzipkin/zipkin-go v0.4.1 h1:kNd/ST2yLLWhaWrkgchya40TJabe8Hioj9udfPcEO5A= +github.com/openzipkin/zipkin-go v0.4.1/go.mod h1:qY0VqDSN1pOBN94dBc6w2GJlWLiovAyg7Qt6/I9HecM= 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= github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 h1:1/WtZae0yGtPq+TI6+Tv1WTxkukpXeMlviSxvL7SRgk= -github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= -github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= -github.com/pierrec/lz4 v2.6.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/polydawn/refmt v0.0.0-20190221155625-df39d6c2d992/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= -github.com/polydawn/refmt v0.0.0-20190408063855-01bf1e26dd14/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= github.com/polydawn/refmt v0.0.0-20190807091052-3d65705ee9f1/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= github.com/polydawn/refmt v0.0.0-20201211092308-30ac6d18308e/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= github.com/polydawn/refmt v0.89.0 h1:ADJTApkvkeBZsN0tBTx8QjpD9JkmxbKp0cxfr9qszm4= github.com/polydawn/refmt v0.89.0/go.mod h1:/zvteZs/GwLtCgZ4BL6CBsk9IKIlexP43ObX9AxTqTw= -github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.10.0/go.mod h1:WJM3cc3yu7XKBKa/I8WeZm+V3eltZnBwfENSU7mdogU= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw= github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= -github.com/prometheus/common v0.18.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE= github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= @@ -1179,24 +721,17 @@ github.com/quic-go/quic-go v0.33.0 h1:ItNoTDN/Fm/zBlq769lLJc8ECe9gYaW40veHCCco7y github.com/quic-go/quic-go v0.33.0/go.mod h1:YMuhaAV9/jIu0XclDXwZPAsP/2Kgr5yMYhe9oxhhOFA= github.com/quic-go/webtransport-go v0.5.2 h1:GA6Bl6oZY+g/flt00Pnu0XtivSD8vukOu3lYhJjnGEk= github.com/quic-go/webtransport-go v0.5.2/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= -github.com/rabbitmq/amqp091-go v1.1.0/go.mod h1:ogQDLSOACsLPsIq0NpbtiifNZi2YOz0VTJ0kHRghqbM= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU= -github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= -github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/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= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd/go.mod h1:hPqNNc0+uJM6H+SuU8sEs5K5IQeKccPqeSjfgcKGgPk= -github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/samber/lo v1.36.0 h1:4LaOxH1mHnbDGhTVE0i1z8v/lWaQW8AIfOD3HU4mSaw= github.com/samber/lo v1.36.0/go.mod h1:HLeWcJRRyLKp3+/XBJvOrerCQn9mhdKMHyd7IRlgeQ8= -github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= -github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY= github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM= @@ -1225,38 +760,27 @@ github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPx 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/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/assertions v1.0.0/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= github.com/smartystreets/assertions v1.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N3yZFZkDFs= github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo= github.com/smartystreets/goconvey v0.0.0-20190222223459-a17d461953aa/go.mod h1:2RVY1rIf+2J2o/IM9+vPq9RzmHDSseB7FoXiSNIUsoU= -github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/smartystreets/goconvey v1.7.2 h1:9RBaZCeXEQ3UselpuwUQHltGVXvdwm6cv1hgR6gDIPg= github.com/smartystreets/goconvey v1.7.2/go.mod h1:Vw0tHAZW6lzCRk3xgdin6fKYcG+G3Pg9vgXWeJpQFMM= github.com/smola/gocompat v0.2.0/go.mod h1:1B0MlxbmoZNo3h8guHp8HztB3BSYR5itql9qtVc0ypY= -github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= -github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE= github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA= -github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a/go.mod h1:7AyxJNCJ7SBZ1MfVQCWD6Uqo2oubI2Eq2y2eqf+A5r0= github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/src-d/envconfig v1.0.0/go.mod h1:Q9YQZ7BKITldTBnoxsE5gOeB5y66RyPXeue/R4aaNBc= -github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= -github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= -github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= @@ -1266,18 +790,16 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= github.com/thoas/go-funk v0.9.1 h1:O549iLZqPpTUQ10ykd26sZhzD+rmR5pWhuElrhbC20M= -github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c h1:u6SKchux2yDvFQnDHS3lPnIRmfVJ5Sxy3ao2SIdysLQ= github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM= github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= @@ -1285,19 +807,15 @@ github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVM github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= -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 v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU= github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM= github.com/wangjia184/sortedset v0.0.0-20160527075905-f5d03557ba30/go.mod h1:YkocrP2K2tcw938x9gCOmT5G5eCD6jsTz0SZuyAqwIE= github.com/warpfork/go-testmark v0.3.0/go.mod h1:jhEf8FVxd+F17juRubpmut64NEG6I2rgkUhlcqqXwE0= github.com/warpfork/go-testmark v0.9.0/go.mod h1:jhEf8FVxd+F17juRubpmut64NEG6I2rgkUhlcqqXwE0= -github.com/warpfork/go-testmark v0.10.0 h1:E86YlUMYfwIacEsQGlnTvjk1IgYkyTGjPhF0RnwTCmw= +github.com/warpfork/go-testmark v0.11.0 h1:J6LnV8KpceDvo7spaNU4+DauH2n1x+6RaO2rJrmpQ9U= github.com/warpfork/go-wish v0.0.0-20180510122957-5ad1f5abf436/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= -github.com/warpfork/go-wish v0.0.0-20190328234359-8b3e70f8e830/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= github.com/warpfork/go-wish v0.0.0-20200122115046-b9ea61034e4a/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0 h1:GDDkbFiaK8jsSDJfjId/PEGEShv6ugrt4kYsC5UIDaQ= github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= @@ -1312,64 +830,48 @@ github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f/go.mod h1:p9 github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 h1:EKhdznlJHPMoKr0XTrX+IlJs1LH3lyx2nfr1dOlZ79k= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc= github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= -github.com/whyrusleeping/go-logging v0.0.1/go.mod h1:lDPYj54zutzG1XYfHAhcc7oNXEburHQBn+Iqd4yS4vE= -github.com/whyrusleeping/go-notifier v0.0.0-20170827234753-097c5d47330f/go.mod h1:cZNvX9cFybI01GriPRMXDtczuvUhgbcYr9iCGaNlRv8= -github.com/whyrusleeping/mafmt v1.2.8/go.mod h1:faQJFPbLSxzD9xpA02ttW/tS9vZykNvXwGvqIpk20FA= -github.com/whyrusleeping/mdns v0.0.0-20180901202407-ef14215e6b30/go.mod h1:j4l84WPFclQPj320J9gp0XwNKBb3U0zt5CBqjPp22G4= -github.com/whyrusleeping/mdns v0.0.0-20190826153040-b9b60ed33aa9/go.mod h1:j4l84WPFclQPj320J9gp0XwNKBb3U0zt5CBqjPp22G4= github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 h1:E9S12nwJwEOXe2d6gT6qxdvqMnNq+VnSsKPgm2ZZNds= github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7/go.mod h1:X2c0RVCI1eSUFI8eLcY3c0423ykwiUdxLJtkDvruhjI= github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE= -github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= -github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= -github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= -github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA= -go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= -go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.1/go.mod h1:Ap50jQcDJrx6rB6VgeeFPtuPIf3wMRvRfrfYDO6+BmA= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/otel v1.7.0 h1:Z2lA3Tdch0iDcrhJXDIlC94XE+bxok1F9B+4Lz/lGsM= -go.opentelemetry.io/otel v1.7.0/go.mod h1:5BdUoMIz5WEs0vt0CUEMtSSaTSHBBVwrhnz7+nrD5xk= -go.opentelemetry.io/otel/exporters/jaeger v1.7.0 h1:wXgjiRldljksZkZrldGVe6XrG9u3kYDyQmkZwmm5dI0= -go.opentelemetry.io/otel/exporters/jaeger v1.7.0/go.mod h1:PwQAOqBgqbLQRKlj466DuD2qyMjbtcPpfPfj+AqbSBs= -go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.7.0 h1:7Yxsak1q4XrJ5y7XBnNwqWx9amMZvoidCctv62XOQ6Y= -go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.7.0/go.mod h1:M1hVZHNxcbkAlcvrOMlpQ4YOO3Awf+4N2dxkZL3xm04= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.7.0 h1:cMDtmgJ5FpRvqx9x2Aq+Mm0O6K/zcUkH73SFz20TuBw= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.7.0/go.mod h1:ceUgdyfNv4h4gLxHR0WNfDiiVmZFodZhZSbOLhpxqXE= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.7.0 h1:MFAyzUPrTwLOwCi+cltN0ZVyy4phU41lwH+lyMyQTS4= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.7.0/go.mod h1:E+/KKhwOSw8yoPxSSuUHG6vKppkvhN+S1Jc7Nib3k3o= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.7.0 h1:pLP0MH4MAqeTEV0g/4flxw9O8Is48uAIauAnjznbW50= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.7.0/go.mod h1:aFXT9Ng2seM9eizF+LfKiyPBGy8xIZKwhusC1gIu3hA= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.7.0 h1:8hPcgCg0rUJiKE6VWahRvjgLUrNl7rW2hffUEPKXVEM= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.7.0/go.mod h1:K4GDXPY6TjUiwbOh+DkKaEdCF8y+lvMoM6SeAPyfCCM= -go.opentelemetry.io/otel/exporters/zipkin v1.7.0 h1:X0FZj+kaIdLi29UiyrEGDhRTYsEXj9GdEW5Y39UQFEE= -go.opentelemetry.io/otel/exporters/zipkin v1.7.0/go.mod h1:9YBXeOMFLQGwNEjsxMRiWPGoJX83usGMhbCmxUbNe5I= -go.opentelemetry.io/otel/sdk v1.7.0 h1:4OmStpcKVOfvDOgCt7UriAPtKolwIhxpnSNI/yK+1B0= -go.opentelemetry.io/otel/sdk v1.7.0/go.mod h1:uTEOTwaqIVuTGiJN7ii13Ibp75wJmYUDe374q6cZwUU= -go.opentelemetry.io/otel/trace v1.7.0 h1:O37Iogk1lEkMRXewVtZ1BBTVn5JEp8GrJvP92bJqC6o= -go.opentelemetry.io/otel/trace v1.7.0/go.mod h1:fzLSB9nqR2eXzxPXb2JW9IKE+ScyXA48yyE4TNvoHqU= +go.opentelemetry.io/otel v1.14.0 h1:/79Huy8wbf5DnIPhemGB+zEPVwnN6fuQybr/SRXa6hM= +go.opentelemetry.io/otel v1.14.0/go.mod h1:o4buv+dJzx8rohcUeRmWUZhqupFvzWis188WlggnNeU= +go.opentelemetry.io/otel/exporters/jaeger v1.14.0 h1:CjbUNd4iN2hHmWekmOqZ+zSCU+dzZppG8XsV+A3oc8Q= +go.opentelemetry.io/otel/exporters/jaeger v1.14.0/go.mod h1:4Ay9kk5vELRrbg5z4cpP9EtmQRFap2Wb0woPG4lujZA= +go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.14.0 h1:/fXHZHGvro6MVqV34fJzDhi7sHGpX3Ej/Qjmfn003ho= +go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.14.0/go.mod h1:UFG7EBMRdXyFstOwH028U0sVf+AvukSGhF0g8+dmNG8= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.14.0 h1:TKf2uAs2ueguzLaxOCBXNpHxfO/aC7PAdDsSH0IbeRQ= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.14.0/go.mod h1:HrbCVv40OOLTABmOn1ZWty6CHXkU8DK/Urc43tHug70= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.14.0 h1:ap+y8RXX3Mu9apKVtOkM6WSFESLM8K3wNQyOU8sWHcc= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.14.0/go.mod h1:5w41DY6S9gZrbjuq6Y+753e96WfPha5IcsOSZTtullM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.14.0 h1:3jAYbRHQAqzLjd9I4tzxwJ8Pk/N6AqBcF6m1ZHrxG94= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.14.0/go.mod h1:+N7zNjIJv4K+DeX67XXET0P+eIciESgaFDBqh+ZJFS4= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.14.0 h1:sEL90JjOO/4yhquXl5zTAkLLsZ5+MycAgX99SDsxGc8= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.14.0/go.mod h1:oCslUcizYdpKYyS9e8srZEqM6BB8fq41VJBjLAE6z1w= +go.opentelemetry.io/otel/exporters/zipkin v1.14.0 h1:reEVE1upBF9tcujgvSqLJS0SrI7JQPaTKP4s4rymnSs= +go.opentelemetry.io/otel/exporters/zipkin v1.14.0/go.mod h1:RcjvOAcvhzcufQP8aHmzRw1gE9g/VEZufDdo2w+s4sk= +go.opentelemetry.io/otel/sdk v1.14.0 h1:PDCppFRDq8A1jL9v6KMI6dYesaq+DFcDZvjsoGvxGzY= +go.opentelemetry.io/otel/sdk v1.14.0/go.mod h1:bwIC5TjrNG6QDCHNWvW4HLHtUQ4I+VQDsnjhvyZCALM= +go.opentelemetry.io/otel/trace v1.14.0 h1:wp2Mmvj41tDsyAJXiWDWpfNsOiIyd38fy85pyKcFq/M= +go.opentelemetry.io/otel/trace v1.14.0/go.mod h1:8avnQLK+CG77yNLUae4ea2JDQ6iT+gozhnZjy/rw9G8= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= -go.opentelemetry.io/proto/otlp v0.16.0 h1:WHzDWdXUvbc5bG2ObdrGfaNpQz7ft7QN9HHmJlbiB1E= -go.opentelemetry.io/proto/otlp v0.16.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= -go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.opentelemetry.io/proto/otlp v0.19.0 h1:IVN6GR+mhC4s5yfcTbmzHYODqvWAp3ZedA2SJPI1Nnw= +go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= @@ -1378,21 +880,16 @@ go.uber.org/dig v1.15.0 h1:vq3YWr8zRj1eFGC7Gvf907hE0eRjPTZ1d3xHadD6liE= go.uber.org/dig v1.15.0/go.mod h1:pKHs0wMynzL6brANhB2hLMro+zalv1osARTviTcqHLM= go.uber.org/fx v1.18.2 h1:bUNI6oShr+OVFQeU8cDNbnN7VFsu+SsjHzUF51V/GAU= go.uber.org/fx v1.18.2/go.mod h1:g0V1KMQ66zIRk8bLu3Ea5Jt2w/cHlOIp4wdRsgh0JaY= -go.uber.org/goleak v1.0.0/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.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA= -go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= +go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= -go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.14.1/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= -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.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= @@ -1403,35 +900,21 @@ go4.org v0.0.0-20200411211856-f5505b9728dd/go.mod h1:CIiUVy99QCPfoE13bO4EZaz5GZM golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190618222545-ea8f1a30c443/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200602180216-279210d13fed/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20210506145944-38f3c27a63bf/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= -golang.org/x/crypto v0.0.0-20210920023735-84f357641f63/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE= -golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= +golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc= +golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1442,8 +925,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20230129154200-a960b3787bd2 h1:5sPMf9HJXrvBWIamTw+rTST0bZ3Mho2n1p58M0+W99c= -golang.org/x/exp v0.0.0-20230129154200-a960b3787bd2/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= +golang.org/x/exp v0.0.0-20230213192124-5e25df0256eb h1:PaBZQdo+iSDyHT053FjUCgZQ/9uqVwPOcl7KSWhKn6w= +golang.org/x/exp v0.0.0-20230213192124-5e25df0256eb/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1468,19 +951,14 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA= golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -1488,15 +966,11 @@ golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190611141213-3f473d35a33a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -1517,13 +991,10 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210423184538-5f58ad60dda6/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210917221730-978cfadd31cf/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= @@ -1553,21 +1024,16 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= golang.org/x/sync v0.1.0/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= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190302025703-b6889370fb10/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190405154228-4b34438f7a67/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1575,23 +1041,17 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190524122548-abf6ff778158/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190526052359-791d8a0f4d09/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190610200419-93c9922d18ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191210023423-ac6580df4449/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1616,16 +1076,11 @@ golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210317225723-c4fcb01b228e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210426080607-c94f62235c83/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1635,8 +1090,8 @@ golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -1677,16 +1132,13 @@ golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= @@ -1706,7 +1158,6 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= @@ -1722,7 +1173,6 @@ golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNq google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y= -google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= @@ -1756,7 +1206,6 @@ google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRn google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= @@ -1782,37 +1231,31 @@ google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7Fc google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1 h1:b9mVrqYfq3P4bCdaLg1qtBnPzUYgglsIdjZkL/fQVOE= google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f h1:BWUVssLB0HVOSY78gIdvk1dTVYtT1y8SBWtPYuTJ/6w= +google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= -google.golang.org/grpc v1.28.1/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= -google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k= google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc v1.46.0 h1:oCjezcn6g6A75TGoKYBPgKmVBLexhYLM6MebdrPApP8= -google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.53.0 h1:LAv2ds7cmFV/XTS3XG1NneeENYrXGmorPxsBbptIjNc= +google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -1826,7 +1269,6 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= @@ -1835,20 +1277,15 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/square/go-jose.v2 v2.5.1 h1:7odma5RETjNHWJnR32wx8t+Io4djHE1PqxCFx3iiZ2w= gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/src-d/go-cli.v0 v0.0.0-20181105080154-d492247bbc0d/go.mod h1:z+K8VcOYVYcSwSjGebuDL6176A1XskgbtNl64NSg+n8= gopkg.in/src-d/go-log.v1 v1.0.1/go.mod h1:GN34hKP0g305ysm2/hctJ0Y8nWP3zxXXJ8GFabTyABE= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= -gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -1881,7 +1318,5 @@ pgregory.net/rapid v0.4.7/go.mod h1:UYpPVyjFHzYBGHIxLFoupi8vwk6rXNzRY9OMvVxFIOU= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= -sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck= sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0= diff --git a/docs/examples/kubo-as-a-library/main.go b/docs/examples/kubo-as-a-library/main.go index 8bd9f8f9c..ce19a5a64 100644 --- a/docs/examples/kubo-as-a-library/main.go +++ b/docs/examples/kubo-as-a-library/main.go @@ -11,9 +11,9 @@ import ( "strings" "sync" - "github.com/ipfs/go-libipfs/files" - icore "github.com/ipfs/interface-go-ipfs-core" - icorepath "github.com/ipfs/interface-go-ipfs-core/path" + icore "github.com/ipfs/boxo/coreiface" + icorepath "github.com/ipfs/boxo/coreiface/path" + "github.com/ipfs/boxo/files" ma "github.com/multiformats/go-multiaddr" "github.com/ipfs/kubo/config" diff --git a/fuse/ipns/common.go b/fuse/ipns/common.go index 45b46dc20..db231fe45 100644 --- a/fuse/ipns/common.go +++ b/fuse/ipns/common.go @@ -3,9 +3,9 @@ package ipns import ( "context" - nsys "github.com/ipfs/go-namesys" - path "github.com/ipfs/go-path" - ft "github.com/ipfs/go-unixfs" + ft "github.com/ipfs/boxo/ipld/unixfs" + nsys "github.com/ipfs/boxo/namesys" + path "github.com/ipfs/boxo/path" "github.com/ipfs/kubo/core" ci "github.com/libp2p/go-libp2p/core/crypto" ) diff --git a/fuse/ipns/ipns_test.go b/fuse/ipns/ipns_test.go index 51ac9518c..05a4e467e 100644 --- a/fuse/ipns/ipns_test.go +++ b/fuse/ipns/ipns_test.go @@ -19,8 +19,8 @@ import ( coreapi "github.com/ipfs/kubo/core/coreapi" fstest "bazil.org/fuse/fs/fstestutil" + u "github.com/ipfs/boxo/util" racedet "github.com/ipfs/go-detect-race" - u "github.com/ipfs/go-ipfs-util" ci "github.com/libp2p/go-libp2p-testing/ci" ) diff --git a/fuse/ipns/ipns_unix.go b/fuse/ipns/ipns_unix.go index c19898919..9db0d61f9 100644 --- a/fuse/ipns/ipns_unix.go +++ b/fuse/ipns/ipns_unix.go @@ -13,17 +13,17 @@ import ( "os" "strings" - dag "github.com/ipfs/go-merkledag" - ft "github.com/ipfs/go-unixfs" - path "github.com/ipfs/interface-go-ipfs-core/path" + path "github.com/ipfs/boxo/coreiface/path" + dag "github.com/ipfs/boxo/ipld/merkledag" + ft "github.com/ipfs/boxo/ipld/unixfs" fuse "bazil.org/fuse" fs "bazil.org/fuse/fs" + iface "github.com/ipfs/boxo/coreiface" + options "github.com/ipfs/boxo/coreiface/options" + mfs "github.com/ipfs/boxo/mfs" cid "github.com/ipfs/go-cid" logging "github.com/ipfs/go-log" - mfs "github.com/ipfs/go-mfs" - iface "github.com/ipfs/interface-go-ipfs-core" - options "github.com/ipfs/interface-go-ipfs-core/options" ) func init() { diff --git a/fuse/readonly/ipfs_test.go b/fuse/readonly/ipfs_test.go index 04fc07f73..ffe86509d 100644 --- a/fuse/readonly/ipfs_test.go +++ b/fuse/readonly/ipfs_test.go @@ -23,14 +23,14 @@ import ( coremock "github.com/ipfs/kubo/core/mock" fstest "bazil.org/fuse/fs/fstestutil" - chunker "github.com/ipfs/go-ipfs-chunker" - u "github.com/ipfs/go-ipfs-util" + chunker "github.com/ipfs/boxo/chunker" + ipath "github.com/ipfs/boxo/coreiface/path" + "github.com/ipfs/boxo/files" + dag "github.com/ipfs/boxo/ipld/merkledag" + importer "github.com/ipfs/boxo/ipld/unixfs/importer" + uio "github.com/ipfs/boxo/ipld/unixfs/io" + u "github.com/ipfs/boxo/util" ipld "github.com/ipfs/go-ipld-format" - "github.com/ipfs/go-libipfs/files" - dag "github.com/ipfs/go-merkledag" - importer "github.com/ipfs/go-unixfs/importer" - uio "github.com/ipfs/go-unixfs/io" - ipath "github.com/ipfs/interface-go-ipfs-core/path" ci "github.com/libp2p/go-libp2p-testing/ci" ) diff --git a/fuse/readonly/readonly_unix.go b/fuse/readonly/readonly_unix.go index 39ca972e5..ae90caead 100644 --- a/fuse/readonly/readonly_unix.go +++ b/fuse/readonly/readonly_unix.go @@ -13,14 +13,14 @@ import ( fuse "bazil.org/fuse" fs "bazil.org/fuse/fs" + mdag "github.com/ipfs/boxo/ipld/merkledag" + ft "github.com/ipfs/boxo/ipld/unixfs" + uio "github.com/ipfs/boxo/ipld/unixfs/io" + path "github.com/ipfs/boxo/path" + "github.com/ipfs/boxo/path/resolver" "github.com/ipfs/go-cid" ipld "github.com/ipfs/go-ipld-format" logging "github.com/ipfs/go-log" - mdag "github.com/ipfs/go-merkledag" - path "github.com/ipfs/go-path" - "github.com/ipfs/go-path/resolver" - ft "github.com/ipfs/go-unixfs" - uio "github.com/ipfs/go-unixfs/io" core "github.com/ipfs/kubo/core" ipldprime "github.com/ipld/go-ipld-prime" cidlink "github.com/ipld/go-ipld-prime/linking/cid" diff --git a/gc/gc.go b/gc/gc.go index 851b42d3b..7e81ef557 100644 --- a/gc/gc.go +++ b/gc/gc.go @@ -7,16 +7,16 @@ import ( "fmt" "strings" - bserv "github.com/ipfs/go-blockservice" + bserv "github.com/ipfs/boxo/blockservice" + bstore "github.com/ipfs/boxo/blockstore" + offline "github.com/ipfs/boxo/exchange/offline" + dag "github.com/ipfs/boxo/ipld/merkledag" + pin "github.com/ipfs/boxo/pinning/pinner" + "github.com/ipfs/boxo/verifcid" cid "github.com/ipfs/go-cid" dstore "github.com/ipfs/go-datastore" - bstore "github.com/ipfs/go-ipfs-blockstore" - offline "github.com/ipfs/go-ipfs-exchange-offline" - pin "github.com/ipfs/go-ipfs-pinner" ipld "github.com/ipfs/go-ipld-format" logging "github.com/ipfs/go-log" - dag "github.com/ipfs/go-merkledag" - "github.com/ipfs/go-verifcid" ) var log = logging.Logger("gc") diff --git a/go.mod b/go.mod index 47111ef0c..3d8585be0 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ require ( contrib.go.opencensus.io/exporter/prometheus v0.4.0 github.com/benbjohnson/clock v1.3.0 github.com/blang/semver/v4 v4.0.0 - github.com/cenkalti/backoff/v4 v4.1.3 + github.com/cenkalti/backoff/v4 v4.2.0 github.com/ceramicnetwork/go-dag-jose v0.1.0 github.com/cheggaaa/pb v1.0.29 github.com/coreos/go-systemd/v22 v22.5.0 @@ -16,60 +16,37 @@ require ( github.com/gogo/protobuf v1.3.2 github.com/google/uuid v1.3.0 github.com/hashicorp/go-multierror v1.1.1 - github.com/ipfs/go-blockservice v0.5.0 + github.com/ipfs/boxo v0.8.0-rc2 + github.com/ipfs/go-block-format v0.1.2 github.com/ipfs/go-cid v0.4.0 github.com/ipfs/go-cidutil v0.1.0 github.com/ipfs/go-datastore v0.6.0 - github.com/ipfs/go-delegated-routing v0.7.0 + github.com/ipfs/go-delegated-routing v0.8.0 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-leveldb v0.5.0 github.com/ipfs/go-ds-measure v0.2.0 - github.com/ipfs/go-fetcher v1.6.1 - github.com/ipfs/go-filestore v1.2.0 github.com/ipfs/go-fs-lock v0.0.7 - github.com/ipfs/go-graphsync v0.14.1 - github.com/ipfs/go-ipfs-blockstore v1.2.0 - github.com/ipfs/go-ipfs-chunker v0.0.5 - github.com/ipfs/go-ipfs-cmds v0.8.2 - github.com/ipfs/go-ipfs-exchange-interface v0.2.0 - github.com/ipfs/go-ipfs-exchange-offline v0.3.0 - github.com/ipfs/go-ipfs-keystore v0.1.0 - github.com/ipfs/go-ipfs-pinner v0.3.0 - github.com/ipfs/go-ipfs-posinfo v0.0.1 - github.com/ipfs/go-ipfs-provider v0.8.1 - github.com/ipfs/go-ipfs-routing v0.3.0 - github.com/ipfs/go-ipfs-util v0.0.2 + github.com/ipfs/go-graphsync v0.14.0 + github.com/ipfs/go-ipfs-cmds v0.9.0 github.com/ipfs/go-ipld-format v0.4.0 github.com/ipfs/go-ipld-git v0.1.1 github.com/ipfs/go-ipld-legacy v0.1.1 - github.com/ipfs/go-ipns v0.3.0 - github.com/ipfs/go-libipfs v0.7.0 github.com/ipfs/go-log v1.0.5 github.com/ipfs/go-log/v2 v2.5.1 - github.com/ipfs/go-merkledag v0.9.0 github.com/ipfs/go-metrics-interface v0.0.1 github.com/ipfs/go-metrics-prometheus v0.0.2 - github.com/ipfs/go-mfs v0.2.1 - github.com/ipfs/go-namesys v0.7.0 - github.com/ipfs/go-path v0.3.1 - github.com/ipfs/go-pinning-service-http-client v0.1.2 - github.com/ipfs/go-unixfs v0.4.4 - github.com/ipfs/go-unixfsnode v1.5.2 - github.com/ipfs/go-verifcid v0.0.2 - github.com/ipfs/interface-go-ipfs-core v0.11.0 - github.com/ipld/go-car v0.5.0 - github.com/ipld/go-car/v2 v2.5.1 - github.com/ipld/go-codec-dagpb v1.5.0 - github.com/ipld/go-ipld-prime v0.19.0 + github.com/ipfs/go-unixfsnode v1.6.0 + github.com/ipld/go-codec-dagpb v1.6.0 + github.com/ipld/go-ipld-prime v0.20.0 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.26.4 github.com/libp2p/go-libp2p-http v0.4.0 - github.com/libp2p/go-libp2p-kad-dht v0.21.1 + github.com/libp2p/go-libp2p-kad-dht v0.22.0 github.com/libp2p/go-libp2p-kbucket v0.5.0 github.com/libp2p/go-libp2p-pubsub v0.9.0 github.com/libp2p/go-libp2p-pubsub-router v0.6.0 @@ -82,33 +59,36 @@ require ( github.com/multiformats/go-multiaddr v0.8.0 github.com/multiformats/go-multiaddr-dns v0.3.1 github.com/multiformats/go-multibase v0.1.1 - github.com/multiformats/go-multicodec v0.7.0 + github.com/multiformats/go-multicodec v0.8.1 github.com/multiformats/go-multihash v0.2.1 github.com/opentracing/opentracing-go v1.2.0 github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.14.0 - github.com/stretchr/testify v1.8.1 + github.com/stretchr/testify v1.8.2 github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 github.com/whyrusleeping/go-sysinfo v0.0.0-20190219211824-4a357d4b90b1 github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 go.opencensus.io v0.24.0 go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.32.0 - go.opentelemetry.io/otel v1.7.0 - go.opentelemetry.io/otel/exporters/jaeger v1.7.0 - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.7.0 - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.7.0 - go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.7.0 - go.opentelemetry.io/otel/exporters/zipkin v1.7.0 - go.opentelemetry.io/otel/sdk v1.7.0 - go.opentelemetry.io/otel/trace v1.7.0 + go.opentelemetry.io/otel v1.14.0 + go.opentelemetry.io/otel/exporters/jaeger v1.14.0 + go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.14.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.14.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.14.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.14.0 + go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.14.0 + go.opentelemetry.io/otel/exporters/zipkin v1.14.0 + go.opentelemetry.io/otel/sdk v1.14.0 + go.opentelemetry.io/otel/trace v1.14.0 + go.opentelemetry.io/proto/otlp v0.19.0 // indirect go.uber.org/dig v1.15.0 go.uber.org/fx v1.18.2 go.uber.org/zap v1.24.0 - golang.org/x/crypto v0.5.0 + golang.org/x/crypto v0.6.0 golang.org/x/mod v0.7.0 golang.org/x/sync v0.1.0 - golang.org/x/sys v0.5.0 + golang.org/x/sys v0.6.0 ) require ( @@ -156,12 +136,15 @@ require ( github.com/huin/goupnp v1.0.3 // indirect github.com/ipfs/bbloom v0.0.4 // indirect github.com/ipfs/go-bitfield v1.1.0 // indirect - github.com/ipfs/go-block-format v0.1.1 // indirect + github.com/ipfs/go-ipfs-blockstore v1.3.0 // indirect github.com/ipfs/go-ipfs-delay v0.0.1 // indirect github.com/ipfs/go-ipfs-ds-help v1.1.0 // indirect + github.com/ipfs/go-ipfs-files v0.3.0 // indirect github.com/ipfs/go-ipfs-pq v0.0.3 // indirect github.com/ipfs/go-ipfs-redirects-file v0.1.1 // indirect + github.com/ipfs/go-ipfs-util v0.0.2 // indirect github.com/ipfs/go-ipld-cbor v0.0.6 // indirect + github.com/ipfs/go-libipfs v0.7.0 // indirect github.com/ipfs/go-peertaskqueue v0.8.1 // indirect github.com/ipld/edelweiss v0.2.0 // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect @@ -198,7 +181,7 @@ require ( github.com/multiformats/go-varint v0.0.7 // indirect github.com/onsi/ginkgo/v2 v2.5.1 // indirect github.com/opencontainers/runtime-spec v1.0.2 // indirect - github.com/openzipkin/zipkin-go v0.4.0 // indirect + github.com/openzipkin/zipkin-go v0.4.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/polydawn/refmt v0.89.0 // indirect github.com/prometheus/client_model v0.3.0 // indirect @@ -220,23 +203,20 @@ require ( github.com/whyrusleeping/cbor-gen v0.0.0-20230126041949-52956bd4c9aa // indirect github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f // indirect github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect - go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.7.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.7.0 // indirect go.opentelemetry.io/otel/metric v0.30.0 // indirect - go.opentelemetry.io/proto/otlp v0.16.0 // indirect go.uber.org/atomic v1.10.0 // indirect go.uber.org/multierr v1.9.0 // indirect go4.org v0.0.0-20200411211856-f5505b9728dd // indirect - golang.org/x/exp v0.0.0-20230129154200-a960b3787bd2 // indirect + golang.org/x/exp v0.0.0-20230213192124-5e25df0256eb // indirect golang.org/x/net v0.7.0 // indirect - golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b // indirect + golang.org/x/oauth2 v0.4.0 // indirect golang.org/x/term v0.5.0 // indirect golang.org/x/text v0.7.0 // indirect golang.org/x/tools v0.3.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect - google.golang.org/appengine v1.6.6 // indirect - google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1 // indirect - google.golang.org/grpc v1.46.0 // indirect + google.golang.org/appengine v1.6.7 // indirect + google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect + google.golang.org/grpc v1.53.0 // indirect google.golang.org/protobuf v1.28.1 // indirect gopkg.in/square/go-jose.v2 v2.5.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/go.sum b/go.sum index dceb1ca79..fc8dd18e8 100644 --- a/go.sum +++ b/go.sum @@ -42,25 +42,16 @@ dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBr dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4= dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU= git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg= -github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 h1:cTp8I5+VIoKjsnZuH8vjyaysT/ses3EvZeaV/1UkF2M= github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/Kubuxu/go-os-helper v0.0.1 h1:EJiD2VUQyh5A9hWJLmc6iWg6yIcJ7jpBcwC8GMGXfDk= github.com/Kubuxu/go-os-helper v0.0.1/go.mod h1:N8B+I7vPCT80IcP58r50u4+gEEcsZETFUpAzWW2ep1Y= github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= -github.com/Shopify/sarama v1.30.0/go.mod h1:zujlQQx1kzHsh4jfV1USnptCQrHAEZ2Hk8fTKCulPVs= -github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= -github.com/Shopify/toxiproxy/v2 v2.1.6-0.20210914104332-15ea381dcdae/go.mod h1:/cvHQkZ1fst0EmZnA5dFtiQdWCNCFYzb+uE2vqVgvx0= -github.com/Stebalien/go-bitfield v0.0.1/go.mod h1:GNjFpasyUVkHMsfEOk8EFLJ9syQ6SI+XWrX9Wf2XH0s= -github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= -github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= @@ -72,16 +63,7 @@ github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5 h1:iW0a5 github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5/go.mod h1:Y2QMoi1vgtOIfc+6DhrMOGkLoGzqSV2rKp4Sm+opsyA= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= -github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= -github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= -github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= -github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= -github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= @@ -89,33 +71,23 @@ github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24 github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= -github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= -github.com/btcsuite/btcd v0.0.0-20190523000118-16327141da8c/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= -github.com/btcsuite/btcd v0.0.0-20190605094302-a0d1e3e36d50/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= github.com/btcsuite/btcd v0.0.0-20190824003749-130ea5bddde3/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= -github.com/btcsuite/btcd v0.21.0-beta/go.mod h1:ZSWyehm27aAuS9bvkATT+Xte3hjHZ+MRgMY/8NJ7K94= github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= -github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= -github.com/btcsuite/btcutil v1.0.2/go.mod h1:j9HUFwoQRsZL3V4n+qG+CUnEGHOarIxfC3Le2Yhbcts= github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= -github.com/btcsuite/goleveldb v1.0.0/go.mod h1:QiK9vBlgftBg6rWQIj6wFzbPfRjiykIEhBH4obrXJ/I= github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= -github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= -github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= -github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4= -github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= +github.com/cenkalti/backoff/v4 v4.2.0 h1:HN5dHm3WBOgndBH6E8V0q2jIYIR3s9yglV8k/+MN3u4= +github.com/cenkalti/backoff/v4 v4.2.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/ceramicnetwork/go-dag-jose v0.1.0 h1:yJ/HVlfKpnD3LdYP03AHyTvbm3BpPiz2oZiOeReJRdU= github.com/ceramicnetwork/go-dag-jose v0.1.0/go.mod h1:qYA1nYt0X8u4XoMAVoOV3upUVKtrxy/I670Dg5F0wjI= @@ -125,14 +97,12 @@ github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cheekybits/genny v1.0.0/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ= github.com/cheggaaa/pb v1.0.29 h1:FckUN5ngEk2LpvuG0fw1GEFx6LtyY2pWI/Z2QgCnEYo= github.com/cheggaaa/pb v1.0.29/go.mod h1:W40334L7FMC5JKWldsTWbdGjLo0RxUKK73K+TuPxX30= 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= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= @@ -140,10 +110,7 @@ github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XP github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/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/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE= github.com/containerd/cgroups v1.0.4 h1:jN/mbWBEaz+T1pi5OFtnkQ+8qnmEbAr1Oo1FRm5B0dA= github.com/containerd/cgroups v1.0.4/go.mod h1:nLNQtsF7Sl2HxNebu77i1R0oDlhiTG+kO4JTrUzo6IA= @@ -151,19 +118,16 @@ github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc 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= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= 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.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= github.com/coreos/go-systemd/v22 v22.5.0/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= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cskr/pubsub v1.0.2 h1:vlOzMhl6PFn60gRlTQQsIfVwaPB/B/8MziK8FhEPt/0= github.com/cskr/pubsub v1.0.2/go.mod h1:/8MzYXk/NJAz782G8RPkFzXTZVu63VotefPnR9TIRis= @@ -171,36 +135,23 @@ github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davidlazar/go-crypto v0.0.0-20170701192655-dcfb0a7ac018/go.mod h1:rQYf4tfk5sSwFsnDg3qYaBxSjsD9S8+59vW0dKUgme4= github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c h1:pFUpOrbxDR6AkioZ1ySsx5yxlDQZ8stG2b88gTPxgJU= github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c/go.mod h1:6UhI8N9EjYm1c2odKpFpAYeR8dsBeM7PtzQhRgxRr9U= github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 h1:HbphB4TFFXpv7MNrT52FGrrgVXF1owhMVTHFZIlnvd4= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0/go.mod h1:DZGJHZMqrU4JJqFAWUS2UO1+lbSKsdiOoYi9Zzey7Fc= -github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= -github.com/dgraph-io/badger v1.5.5-0.20190226225317-8115aed38f8f/go.mod h1:VZxzAIRPHRVNRKRo6AXrX9BJegn6il06VMTZVJYCIjQ= -github.com/dgraph-io/badger v1.6.0-rc1/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= -github.com/dgraph-io/badger v1.6.1/go.mod h1:FRmFw3uxvcpa8zG3Rxs0th+hCLIuaQg8HlNV5bjgnuU= github.com/dgraph-io/badger v1.6.2 h1:mNw0qs90GVgGGWylh0umH5iag1j6n/PeJtNvL6KY/x8= github.com/dgraph-io/badger v1.6.2/go.mod h1:JW2yswe3V058sS0kZ2h/AXeDSqFjxnZcRrVH//y2UQE= github.com/dgraph-io/ristretto v0.0.2 h1:a5WaUrDa0qm0YrAAS1tUykT5El3kt62KNZZeMxQn3po= github.com/dgraph-io/ristretto v0.0.2/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= -github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= -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/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.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= -github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= -github.com/eapache/go-resiliency v1.2.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= -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/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= github.com/elastic/gosigar v0.14.2 h1:Dg80n8cr90OZ7x+bAax/QjoW/XqTI11RmA79ZwIm9/4= github.com/elastic/gosigar v0.14.2/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= @@ -208,18 +159,15 @@ github.com/elgris/jsondiff v0.0.0-20160530203242-765b5c24c302 h1:QV0ZrfBLpFc2KDk github.com/elgris/jsondiff v0.0.0-20160530203242-765b5c24c302/go.mod h1:qBlWZqWeVx9BjvqBsnC/8RUlAYpIFmPvgROcw0n1scE= github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= -github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= -github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5 h1:BBso6MBKW8ncyZLv37o+KNyy0HrrHgfnOaGQC2qvN+A= github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5/go.mod h1:JpoxHjuQauoxiFMl1ie8Xc/7TfLuMZ5eOCONd1sUBHg= -github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= github.com/felixge/httpsnoop v1.0.2 h1:+nS9g82KMXccJ/wp0zyRW9ZBHFETmMGtkk+2CTTrW4o= @@ -227,14 +175,11 @@ github.com/felixge/httpsnoop v1.0.2/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSw github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/flynn/noise v1.0.0 h1:DlTHqmzmvcEiKj+4RYo/imoswx/4r6iBlCMfVtrMXpQ= github.com/flynn/noise v1.0.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag= -github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk= github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= -github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= -github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/frankban/quicktest v1.14.0/go.mod h1:NeW+ay9A/U67EYXNFA1nPE8e/tnQv/09mUdL/ijj8og= -github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= +github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= @@ -254,7 +199,6 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= github.com/go-kit/log v0.2.0 h1:7i2K3eKTos3Vc0enKCfnVcgHh2olr/MyfboYq7cAcFw= github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= @@ -275,7 +219,6 @@ github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD87 github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= github.com/go-playground/validator/v10 v10.2.0 h1:KgJ0snyC2R9VXYN2rneOtQcw5aHQB1Vv0sFl1UcHBOY= github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= -github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= 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= @@ -290,9 +233,7 @@ github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5x github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= github.com/godbus/dbus/v5 v5.1.0/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= -github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= @@ -301,9 +242,7 @@ github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ= github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= -github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= @@ -319,7 +258,6 @@ github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71 github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= @@ -373,10 +311,8 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20221203041831-ce31453925ec h1:fR20TYVVwhK4O7r7y+McjRYyaTH6/vjwJOajE+XhlzM= github.com/google/pprof v0.0.0-20221203041831-ce31453925ec/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= @@ -385,24 +321,12 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c h1:7lF+Vz0LqiRidnzC1Oq86fpX1q/iEv2KJdrCtttYjT4= -github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= -github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= -github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= -github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= -github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= -github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 h1:BZHcxBETFHIdVyhyEfOvn/RdU/QGdLI4y34qQGjGWO0= github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= @@ -410,25 +334,11 @@ github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfm github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= github.com/hannahhoward/go-pubsub v0.0.0-20200423002714-8d62886cc36e h1:3YKHER4nmd7b5qy5t0GWDTwSn4OyRgfAXSmo6VnryBY= github.com/hannahhoward/go-pubsub v0.0.0-20200423002714-8d62886cc36e/go.mod h1:I8h3MITA53gN9OnWGCgaMa0JWVRdXthWw4M3CPM54OY= -github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= -github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= -github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= -github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= -github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= -github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= -github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= @@ -436,40 +346,24 @@ github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uG github.com/hashicorp/golang-lru/v2 v2.0.1 h1:5pv5N1lT1fjLg2VQ5KWc7kmucp2x/kvFOnxuVTqZ6x4= github.com/hashicorp/golang-lru/v2 v2.0.1/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= -github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= -github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= -github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= github.com/huin/goupnp v1.0.3 h1:N8No57ls+MnjlB+JPiCVSOyy/ot7MJTqlo7rn+NYSqQ= github.com/huin/goupnp v1.0.3/go.mod h1:ZxNlw5WqJj6wSsRK5+YfflQGXYfccj5VgQsMNixHM7Y= github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= -github.com/ipfs/bbloom v0.0.1/go.mod h1:oqo8CVWsJFMOZqTglBG4wydCE4IQA/G2/SEofB0rjUI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/go-bitfield v1.0.0/go.mod h1:N/UiujQy+K+ceU1EF5EkVd1TNqevLrCQMIcAEPrdtus= +github.com/ipfs/boxo v0.8.0-rc2 h1:JnSlLKlIURiVsTfPs1BLv3NNCygjV1b07wGva3w4sLY= +github.com/ipfs/boxo v0.8.0-rc2/go.mod h1:EgDiNox/+W/+ySwEotRrHlvdmrhbSAB4p22ELg+ZsCc= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= -github.com/ipfs/go-bitswap v0.1.0/go.mod h1:FFJEf18E9izuCqUtHxbWEvq+reg7o4CW5wSAE1wsxj0= -github.com/ipfs/go-bitswap v0.1.2/go.mod h1:qxSWS4NXGs7jQ6zQvoPY3+NmOfHHG47mhkiLzBpJQIs= -github.com/ipfs/go-bitswap v0.5.1/go.mod h1:P+ckC87ri1xFLvk74NlXdP0Kj9RmWAh4+H78sC6Qopo= -github.com/ipfs/go-bitswap v0.6.0/go.mod h1:Hj3ZXdOC5wBJvENtdqsixmzzRukqd8EHLxZLZc3mzRA= -github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= -github.com/ipfs/go-block-format v0.0.1/go.mod h1:DK/YYcsSUIVAFNwo/KZCdIIbpN0ROH/baNLgayt4pFc= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= github.com/ipfs/go-block-format v0.0.3/go.mod h1:4LmD4ZUw0mhO+JSKdpWwrzATiEfM7WWgQ8H5l6P8MVk= -github.com/ipfs/go-block-format v0.1.1 h1:129vSO3zwbsYADcyQWcOYiuCpAqt462SFfqFHdFJhhI= -github.com/ipfs/go-block-format v0.1.1/go.mod h1:+McEIT+g52p+zz5xGAABGSOKrzmrdX97bc0USBdWPUs= -github.com/ipfs/go-blockservice v0.1.0/go.mod h1:hzmMScl1kXHg3M2BjTymbVPjv627N7sYcvYaKbop39M= -github.com/ipfs/go-blockservice v0.2.1/go.mod h1:k6SiwmgyYgs4M/qt+ww6amPeUH9EISLRBnvUurKJhi8= -github.com/ipfs/go-blockservice v0.3.0/go.mod h1:P5ppi8IHDC7O+pA0AlGTF09jruB2h+oP3wVVaZl8sfk= +github.com/ipfs/go-block-format v0.1.2 h1:GAjkfhVx1f4YTODS6Esrj1wt2HhrtwTnhEr+DyPUaJo= +github.com/ipfs/go-block-format v0.1.2/go.mod h1:mACVcrxarQKstUU3Yf/RdwbC4DzPV6++rO2a3d+a/KE= github.com/ipfs/go-blockservice v0.5.0 h1:B2mwhhhVQl2ntW2EIpaWPwSCxSuqr5fFA93Ms4bYLEY= -github.com/ipfs/go-blockservice v0.5.0/go.mod h1:W6brZ5k20AehbmERplmERn8o2Ni3ZZubvAxaIUeaT6w= github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.2/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.3/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= @@ -477,218 +371,119 @@ github.com/ipfs/go-cid v0.0.4/go.mod h1:4LLaPOQwmk5z9LBgQnpkivrx8BJjUyGwTXCd5Xfj github.com/ipfs/go-cid v0.0.5/go.mod h1:plgt+Y5MnOey4vO4UlUazGqdbEXuFYitED67FexhXog= github.com/ipfs/go-cid v0.0.6/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I= github.com/ipfs/go-cid v0.0.7/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I= -github.com/ipfs/go-cid v0.1.0/go.mod h1:rH5/Xv83Rfy8Rw6xG+id3DYAMUVmem1MowoKwdXmN2o= github.com/ipfs/go-cid v0.4.0 h1:a4pdZq0sx6ZSxbCizebnKiMCx/xI/aBBFlB73IgH4rA= github.com/ipfs/go-cid v0.4.0/go.mod h1:uQHwDeX4c6CtyrFwdqyhpNcxVewur1M7l7fNU7LKwZk= github.com/ipfs/go-cidutil v0.1.0 h1:RW5hO7Vcf16dplUU60Hs0AKDkQAVPVplr7lk97CFL+Q= github.com/ipfs/go-cidutil v0.1.0/go.mod h1:e7OEVBMIv9JaOxt9zaGEmAoSlXW9jdFZ5lP/0PwcfpA= -github.com/ipfs/go-datastore v0.0.1/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= -github.com/ipfs/go-datastore v0.0.5/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= github.com/ipfs/go-datastore v0.1.0/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= github.com/ipfs/go-datastore v0.1.1/go.mod h1:w38XXW9kVFNp57Zj5knbKWM2T+KOZCGDRVNdgPHtbHw= -github.com/ipfs/go-datastore v0.3.1/go.mod h1:w38XXW9kVFNp57Zj5knbKWM2T+KOZCGDRVNdgPHtbHw= -github.com/ipfs/go-datastore v0.4.0/go.mod h1:SX/xMIKoCszPqp+z9JhPYCmoOoXTvaa13XEbGtsFUhA= -github.com/ipfs/go-datastore v0.4.1/go.mod h1:SX/xMIKoCszPqp+z9JhPYCmoOoXTvaa13XEbGtsFUhA= -github.com/ipfs/go-datastore v0.4.4/go.mod h1:SX/xMIKoCszPqp+z9JhPYCmoOoXTvaa13XEbGtsFUhA= -github.com/ipfs/go-datastore v0.4.5/go.mod h1:eXTcaaiN6uOlVCLS9GjJUJtlvJfM3xk23w3fyfrmmJs= github.com/ipfs/go-datastore v0.5.0/go.mod h1:9zhEApYMTl17C8YDp7JmU7sQZi2/wqiYh73hakZ90Bk= github.com/ipfs/go-datastore v0.6.0 h1:JKyz+Gvz1QEZw0LsX1IBn+JFCJQH4SJVFtM4uWU0Myk= github.com/ipfs/go-datastore v0.6.0/go.mod h1:rt5M3nNbSO/8q1t4LNkLyUwRs8HupMeN/8O4Vn9YAT8= -github.com/ipfs/go-delegated-routing v0.7.0 h1:43FyMnKA+8XnyX68Fwg6aoGkqrf8NS5aG7p644s26PU= -github.com/ipfs/go-delegated-routing v0.7.0/go.mod h1:u4zxjUWIe7APUW5ds9CfD0tJX3vM9JhIeNqA8kE4vHE= +github.com/ipfs/go-delegated-routing v0.8.0 h1:faiRi4k8YioTxU2x7+pnrLQjR7jIQhGWN2JvCwcQ/aU= +github.com/ipfs/go-delegated-routing v0.8.0/go.mod h1:18Dds6ZoNTsff9S/7R49Nh2t2YNXIIKR/RLQmBZdjjY= github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk= github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps= -github.com/ipfs/go-ds-badger v0.0.2/go.mod h1:Y3QpeSFWQf6MopLTiZD+VT6IC1yZqaGmjvRcKeSGij8= -github.com/ipfs/go-ds-badger v0.0.5/go.mod h1:g5AuuCGmr7efyzQhLL8MzwqcauPojGPUaHzfGTzuE3s= github.com/ipfs/go-ds-badger v0.0.7/go.mod h1:qt0/fWzZDoPW6jpQeqUjR5kBfhDNB65jd9YlmAvpQBk= -github.com/ipfs/go-ds-badger v0.2.1/go.mod h1:Tx7l3aTph3FMFrRS838dcSJh+jjA7cX9DrGVwx/NOwE= -github.com/ipfs/go-ds-badger v0.2.3/go.mod h1:pEYw0rgg3FIrywKKnL+Snr+w/LjJZVMTBRn4FS6UHUk= 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-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= -github.com/ipfs/go-ds-leveldb v0.4.2/go.mod h1:jpbku/YqBSsBc1qgME8BkWS4AxzF2cEu1Ii2r79Hh9s= github.com/ipfs/go-ds-leveldb v0.5.0 h1:s++MEBbD3ZKc9/8/njrn4flZLnCuY9I79v94gBUNumo= github.com/ipfs/go-ds-leveldb v0.5.0/go.mod h1:d3XG9RUDzQ6V4SHi8+Xgj9j1XuEk1z82lquxrVbml/Q= github.com/ipfs/go-ds-measure v0.2.0 h1:sG4goQe0KDTccHMyT45CY1XyUbxe5VwTKpg2LjApYyQ= github.com/ipfs/go-ds-measure v0.2.0/go.mod h1:SEUD/rE2PwRa4IQEC5FuNAmjJCyYObZr9UvVh8V3JxE= -github.com/ipfs/go-fetcher v1.6.1 h1:UFuRVYX5AIllTiRhi5uK/iZkfhSpBCGX7L70nSZEmK8= -github.com/ipfs/go-fetcher v1.6.1/go.mod h1:27d/xMV8bodjVs9pugh/RCjjK2OZ68UgAMspMdingNo= -github.com/ipfs/go-filestore v1.2.0 h1:O2wg7wdibwxkEDcl7xkuQsPvJFRBVgVSsOJ/GP6z3yU= -github.com/ipfs/go-filestore v1.2.0/go.mod h1:HLJrCxRXquTeEEpde4lTLMaE/MYJZD7WHLkp9z6+FF8= github.com/ipfs/go-fs-lock v0.0.7 h1:6BR3dajORFrFTkb5EpCUFIAypsoxpGpDSVUdFwzgL9U= github.com/ipfs/go-fs-lock v0.0.7/go.mod h1:Js8ka+FNYmgQRLrRXzU3CB/+Csr1BwrRilEcvYrHhhc= -github.com/ipfs/go-graphsync v0.14.1 h1:tvFpBY9LcehIB7zi5SZIa+7aoxBOrGbdekhOXdnlT70= -github.com/ipfs/go-graphsync v0.14.1/go.mod h1:S6O/c5iXOXqDgrQgiZSgOTRUSiVvpKEhrzqFHKnLVcs= -github.com/ipfs/go-ipfs-blockstore v0.0.1/go.mod h1:d3WClOmRQKFnJ0Jz/jj/zmksX0ma1gROTlovZKBmN08= -github.com/ipfs/go-ipfs-blockstore v0.1.0/go.mod h1:5aD0AvHPi7mZc6Ci1WCAhiBQu2IsfTduLl+422H6Rqw= -github.com/ipfs/go-ipfs-blockstore v0.2.1/go.mod h1:jGesd8EtCM3/zPgx+qr0/feTXGUeRai6adgwC+Q+JvE= -github.com/ipfs/go-ipfs-blockstore v1.2.0 h1:n3WTeJ4LdICWs/0VSfjHrlqpPpl6MZ+ySd3j8qz0ykw= -github.com/ipfs/go-ipfs-blockstore v1.2.0/go.mod h1:eh8eTFLiINYNSNawfZOC7HOxNTxpB1PFuA5E1m/7exE= +github.com/ipfs/go-graphsync v0.14.0 h1:f5KYkc8GpwwE1BrjBOWxIkRivXIw7fVqGZlnILpvbSc= +github.com/ipfs/go-graphsync v0.14.0/go.mod h1:1LDVVnNHjit8ddJOtw3Jq9epP792xWFXXL3dJWIBIkM= +github.com/ipfs/go-ipfs-blockstore v1.3.0 h1:m2EXaWgwTzAfsmt5UdJ7Is6l4gJcaM/A12XwJyvYvMM= +github.com/ipfs/go-ipfs-blockstore v1.3.0/go.mod h1:KgtZyc9fq+P2xJUiCAzbRdhhqJHvsw8u2Dlqy2MyRTE= github.com/ipfs/go-ipfs-blocksutil v0.0.1 h1:Eh/H4pc1hsvhzsQoMEP3Bke/aW5P5rVM1IWFJMcGIPQ= -github.com/ipfs/go-ipfs-blocksutil v0.0.1/go.mod h1:Yq4M86uIOmxmGPUHv/uI7uKqZNtLb449gwKqXjIsnRk= -github.com/ipfs/go-ipfs-chunker v0.0.1/go.mod h1:tWewYK0we3+rMbOh7pPFGDyypCtvGcBFymgY4rSDLAw= github.com/ipfs/go-ipfs-chunker v0.0.5 h1:ojCf7HV/m+uS2vhUGWcogIIxiO5ubl5O57Q7NapWLY8= -github.com/ipfs/go-ipfs-chunker v0.0.5/go.mod h1:jhgdF8vxRHycr00k13FM8Y0E+6BoalYeobXmUyTreP8= -github.com/ipfs/go-ipfs-cmds v0.8.2 h1:WmehvYWkxch8dTw0bdF51R8lqbyl+3H8e6pIACzT/ds= -github.com/ipfs/go-ipfs-cmds v0.8.2/go.mod h1:/b17Davff0E0Wh/hhXsN1Pgxxbkm26k3PV+G4EDiC/s= +github.com/ipfs/go-ipfs-cmds v0.9.0 h1:K0VcXg1l1k6aY6sHnoxYcyimyJQbcV1ueXuWgThmK9Q= +github.com/ipfs/go-ipfs-cmds v0.9.0/go.mod h1:SBFHK8WNwC416QWH9Vz1Ql42SSMAOqKpaHUMBu3jpLo= github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= github.com/ipfs/go-ipfs-delay v0.0.1 h1:r/UXYyRcddO6thwOnhiznIAiSvxMECGgtv35Xs1IeRQ= github.com/ipfs/go-ipfs-delay v0.0.1/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= -github.com/ipfs/go-ipfs-ds-help v0.0.1/go.mod h1:gtP9xRaZXqIQRh1HRpp595KbBEdgqWFxefeVKOV8sxo= -github.com/ipfs/go-ipfs-ds-help v0.1.1/go.mod h1:SbBafGJuGsPI/QL3j9Fc5YPLeAu+SzOkI0gFwAg+mOs= github.com/ipfs/go-ipfs-ds-help v1.1.0 h1:yLE2w9RAsl31LtfMt91tRZcrx+e61O5mDxFRR994w4Q= github.com/ipfs/go-ipfs-ds-help v1.1.0/go.mod h1:YR5+6EaebOhfcqVCyqemItCLthrpVNot+rsOU/5IatU= -github.com/ipfs/go-ipfs-exchange-interface v0.0.1/go.mod h1:c8MwfHjtQjPoDyiy9cFquVtVHkO9b9Ob3FG91qJnWCM= -github.com/ipfs/go-ipfs-exchange-interface v0.1.0/go.mod h1:ych7WPlyHqFvCi/uQI48zLZuAWVP5iTQPXEfVaw5WEI= github.com/ipfs/go-ipfs-exchange-interface v0.2.0 h1:8lMSJmKogZYNo2jjhUs0izT+dck05pqUw4mWNW9Pw6Y= -github.com/ipfs/go-ipfs-exchange-interface v0.2.0/go.mod h1:z6+RhJuDQbqKguVyslSOuVDhqF9JtTrO3eptSAiW2/Y= -github.com/ipfs/go-ipfs-exchange-offline v0.0.1/go.mod h1:WhHSFCVYX36H/anEKQboAzpUws3x7UeEGkzQc3iNkM0= -github.com/ipfs/go-ipfs-exchange-offline v0.1.1/go.mod h1:vTiBRIbzSwDD0OWm+i3xeT0mO7jG2cbJYatp3HPk5XY= -github.com/ipfs/go-ipfs-exchange-offline v0.2.0/go.mod h1:HjwBeW0dvZvfOMwDP0TSKXIHf2s+ksdP4E3MLDRtLKY= github.com/ipfs/go-ipfs-exchange-offline v0.3.0 h1:c/Dg8GDPzixGd0MC8Jh6mjOwU57uYokgWRFidfvEkuA= -github.com/ipfs/go-ipfs-exchange-offline v0.3.0/go.mod h1:MOdJ9DChbb5u37M1IcbrRB02e++Z7521fMxqCNRrz9s= -github.com/ipfs/go-ipfs-files v0.0.3/go.mod h1:INEFm0LL2LWXBhNJ2PMIIb2w45hpXgPjNoE7yA8Y1d4= -github.com/ipfs/go-ipfs-keystore v0.1.0 h1:gfuQUO/cyGZgZIHE6OrJas4OnwuxXCqJG7tI0lrB5Qc= -github.com/ipfs/go-ipfs-keystore v0.1.0/go.mod h1:LvLw7Qhnb0RlMOfCzK6OmyWxICip6lQ06CCmdbee75U= -github.com/ipfs/go-ipfs-pinner v0.3.0 h1:jwe5ViX3BON3KgOAYrrhav2+1ONB0QzFAWQd7HUlbuM= -github.com/ipfs/go-ipfs-pinner v0.3.0/go.mod h1:oX0I0nC6zlNIh0LslSrUnjfNKPq8ufoFtqV1/wcJvyo= +github.com/ipfs/go-ipfs-files v0.3.0 h1:fallckyc5PYjuMEitPNrjRfpwl7YFt69heCOUhsbGxQ= +github.com/ipfs/go-ipfs-files v0.3.0/go.mod h1:xAUtYMwB+iu/dtf6+muHNSFQCJG2dSiStR2P6sn9tIM= github.com/ipfs/go-ipfs-posinfo v0.0.1 h1:Esoxj+1JgSjX0+ylc0hUmJCOv6V2vFoZiETLR6OtpRs= -github.com/ipfs/go-ipfs-posinfo v0.0.1/go.mod h1:SwyeVP+jCwiDu0C313l/8jg6ZxM0qqtlt2a0vILTc1A= -github.com/ipfs/go-ipfs-pq v0.0.1/go.mod h1:LWIqQpqfRG3fNc5XsnIhz/wQ2XXGyugQwls7BgUmUfY= -github.com/ipfs/go-ipfs-pq v0.0.2/go.mod h1:LWIqQpqfRG3fNc5XsnIhz/wQ2XXGyugQwls7BgUmUfY= github.com/ipfs/go-ipfs-pq v0.0.3 h1:YpoHVJB+jzK15mr/xsWC574tyDLkezVrDNeaalQBsTE= github.com/ipfs/go-ipfs-pq v0.0.3/go.mod h1:btNw5hsHBpRcSSgZtiNm/SLj5gYIZ18AKtv3kERkRb4= -github.com/ipfs/go-ipfs-provider v0.8.1 h1:qt670pYmcNH3BCjyXDgg07o2WsTRsOdMwYc25ukCdjQ= -github.com/ipfs/go-ipfs-provider v0.8.1/go.mod h1:qCpwpoohIRVXvNzkygzsM3qdqP/sXlrogtA5I45tClc= github.com/ipfs/go-ipfs-redirects-file v0.1.1 h1:Io++k0Vf/wK+tfnhEh63Yte1oQK5VGT2hIEYpD0Rzx8= github.com/ipfs/go-ipfs-redirects-file v0.1.1/go.mod h1:tAwRjCV0RjLTjH8DR/AU7VYvfQECg+lpUy2Mdzv7gyk= -github.com/ipfs/go-ipfs-routing v0.1.0/go.mod h1:hYoUkJLyAUKhF58tysKpids8RNDPO42BVMgK5dNsoqY= -github.com/ipfs/go-ipfs-routing v0.2.1/go.mod h1:xiNNiwgjmLqPS1cimvAw6EyB9rkVDbiocA4yY+wRNLM= -github.com/ipfs/go-ipfs-routing v0.3.0 h1:9W/W3N+g+y4ZDeffSgqhgo7BsBSJwPMcyssET9OWevc= -github.com/ipfs/go-ipfs-routing v0.3.0/go.mod h1:dKqtTFIql7e1zYsEuWLyuOU+E0WJWW8JjbTPLParDWo= github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyBCNzQxlJBc= github.com/ipfs/go-ipfs-util v0.0.2 h1:59Sswnk1MFaiq+VcaknX7aYEyGyGDAA73ilhEK2POp8= github.com/ipfs/go-ipfs-util v0.0.2/go.mod h1:CbPtkWJzjLdEcezDns2XYaehFVNXG9zrdrtMecczcsQ= -github.com/ipfs/go-ipld-cbor v0.0.2/go.mod h1:wTBtrQZA3SoFKMVkp6cn6HMRteIB1VsmHA0AQFOn7Nc= -github.com/ipfs/go-ipld-cbor v0.0.3/go.mod h1:wTBtrQZA3SoFKMVkp6cn6HMRteIB1VsmHA0AQFOn7Nc= -github.com/ipfs/go-ipld-cbor v0.0.5/go.mod h1:BkCduEx3XBCO6t2Sfo5BaHzuok7hbhdMm9Oh8B2Ftq4= github.com/ipfs/go-ipld-cbor v0.0.6 h1:pYuWHyvSpIsOOLw4Jy7NbBkCyzLDcl64Bf/LZW7eBQ0= github.com/ipfs/go-ipld-cbor v0.0.6/go.mod h1:ssdxxaLJPXH7OjF5V4NSjBbcfh+evoR4ukuru0oPXMA= github.com/ipfs/go-ipld-format v0.0.1/go.mod h1:kyJtbkDALmFHv3QR6et67i35QzO3S0dCDnkOJhcZkms= -github.com/ipfs/go-ipld-format v0.0.2/go.mod h1:4B6+FM2u9OJ9zCV+kSbgFAZlOrv1Hqbf0INGQgiKf9k= github.com/ipfs/go-ipld-format v0.2.0/go.mod h1:3l3C1uKoadTPbeNfrDi+xMInYKlx2Cvg1BuydPSdzQs= -github.com/ipfs/go-ipld-format v0.3.0/go.mod h1:co/SdBE8h99968X0hViiw1MNlh6fvxxnHpvVLnH7jSM= github.com/ipfs/go-ipld-format v0.4.0 h1:yqJSaJftjmjc9jEOFYlpkwOLVKv68OD27jFLlSghBlQ= github.com/ipfs/go-ipld-format v0.4.0/go.mod h1:co/SdBE8h99968X0hViiw1MNlh6fvxxnHpvVLnH7jSM= github.com/ipfs/go-ipld-git v0.1.1 h1:TWGnZjS0htmEmlMFEkA3ogrNCqWjIxwr16x1OsdhG+Y= github.com/ipfs/go-ipld-git v0.1.1/go.mod h1:+VyMqF5lMcJh4rwEppV0e6g4nCCHXThLYYDpKUkJubI= -github.com/ipfs/go-ipld-legacy v0.1.0/go.mod h1:86f5P/srAmh9GcIcWQR9lfFLZPrIyyXQeVlOWeeWEuI= github.com/ipfs/go-ipld-legacy v0.1.1 h1:BvD8PEuqwBHLTKqlGFTHSwrwFOMkVESEvwIYwR2cdcc= github.com/ipfs/go-ipld-legacy v0.1.1/go.mod h1:8AyKFCjgRPsQFf15ZQgDB8Din4DML/fOmKZkkFkrIEg= -github.com/ipfs/go-ipns v0.3.0 h1:ai791nTgVo+zTuq2bLvEGmWP1M0A6kGTXUsgv/Yq67A= -github.com/ipfs/go-ipns v0.3.0/go.mod h1:3cLT2rbvgPZGkHJoPO1YMJeh6LtkxopCkKFcio/wE24= github.com/ipfs/go-libipfs v0.7.0 h1:Mi54WJTODaOL2/ZSm5loi3SwI3jI2OuFWUrQIkJ5cpM= github.com/ipfs/go-libipfs v0.7.0/go.mod h1:KsIf/03CqhICzyRGyGo68tooiBE2iFbI/rXW7FhAYr0= github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= -github.com/ipfs/go-log v1.0.2/go.mod h1:1MNjMxe0u6xvJZgeqbJ8vdo2TKaGwZ1a0Bpza+sr2Sk= github.com/ipfs/go-log v1.0.3/go.mod h1:OsLySYkwIbiSUR/yBTdv1qPtcE4FW3WPWk/ewz9Ru+A= -github.com/ipfs/go-log v1.0.4/go.mod h1:oDCg2FkjogeFOhqqb+N39l2RpTNPL6F/StPkB3kPgcs= github.com/ipfs/go-log v1.0.5 h1:2dOuUCB1Z7uoczMWgAyDck5JLb72zHzrMnGnCNNbvY8= github.com/ipfs/go-log v1.0.5/go.mod h1:j0b8ZoR+7+R99LD9jZ6+AJsrzkPbSXbZfGakb5JPtIo= -github.com/ipfs/go-log/v2 v2.0.2/go.mod h1:O7P1lJt27vWHhOwQmcFEvlmo49ry2VY2+JfBWFaa9+0= github.com/ipfs/go-log/v2 v2.0.3/go.mod h1:O7P1lJt27vWHhOwQmcFEvlmo49ry2VY2+JfBWFaa9+0= 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/go.mod h1:QqGoj30OTpnKaG/LKTGTxoP2mmQtjVMEnK72gynbe/g= github.com/ipfs/go-log/v2 v2.5.1 h1:1XdUzF7048prq4aBjDQQ4SL5RxftpRGdXhNRwKSAlcY= github.com/ipfs/go-log/v2 v2.5.1/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOLU9U5UI= -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= -github.com/ipfs/go-merkledag v0.5.1/go.mod h1:cLMZXx8J08idkp5+id62iVftUQV+HlYJ3PIhDfZsjA4= -github.com/ipfs/go-merkledag v0.6.0/go.mod h1:9HSEwRd5sV+lbykiYP+2NC/3o6MZbKNaa4hfNcH5iH0= -github.com/ipfs/go-merkledag v0.9.0 h1:DFC8qZ96Dz1hMT7dtIpcY524eFFDiEWAF8hNJHWW2pk= -github.com/ipfs/go-merkledag v0.9.0/go.mod h1:bPHqkHt5OZ0p1n3iqPeDiw2jIBkjAytRjS3WSBwjq90= +github.com/ipfs/go-merkledag v0.10.0 h1:IUQhj/kzTZfam4e+LnaEpoiZ9vZF6ldimVlby+6OXL4= github.com/ipfs/go-metrics-interface v0.0.1 h1:j+cpbjYvu4R8zbleSs36gvB7jR+wsL2fGD6n0jO4kdg= github.com/ipfs/go-metrics-interface v0.0.1/go.mod h1:6s6euYU4zowdslK0GKHmqaIZ3j/b/tL7HTWtJ4VPgWY= github.com/ipfs/go-metrics-prometheus v0.0.2 h1:9i2iljLg12S78OhC6UAiXi176xvQGiZaGVF1CUVdE+s= github.com/ipfs/go-metrics-prometheus v0.0.2/go.mod h1:ELLU99AQQNi+zX6GCGm2lAgnzdSH3u5UVlCdqSXnEks= -github.com/ipfs/go-mfs v0.2.1 h1:5jz8+ukAg/z6jTkollzxGzhkl3yxm022Za9f2nL5ab8= -github.com/ipfs/go-mfs v0.2.1/go.mod h1:Woj80iuw4ajDnIP6+seRaoHpPsc9hmL0pk/nDNDWP88= -github.com/ipfs/go-namesys v0.7.0 h1:xqosk71GIVRkFDtF2UNRcXn4LdNeo7tzuy8feHD6NbU= -github.com/ipfs/go-namesys v0.7.0/go.mod h1:KYSZBVZG3VJC34EfqqJPG7T48aWgxseoMPAPA5gLyyQ= -github.com/ipfs/go-path v0.2.1/go.mod h1:NOScsVgxfC/eIw4nz6OiGwK42PjaSJ4Y/ZFPn1Xe07I= -github.com/ipfs/go-path v0.3.1 h1:wkeaCWE/NTuuPGlEkLTsED5UkzfKYZpxaFFPgk8ZVLE= -github.com/ipfs/go-path v0.3.1/go.mod h1:eNLsxJEEMxn/CDzUJ6wuNl+6No6tEUhOZcPKsZsYX0E= -github.com/ipfs/go-peertaskqueue v0.1.0/go.mod h1:Jmk3IyCcfl1W3jTW3YpghSwSEC6IJ3Vzz/jUmWw8Z0U= -github.com/ipfs/go-peertaskqueue v0.7.0/go.mod h1:M/akTIE/z1jGNXMU7kFB4TeSEFvj68ow0Rrb04donIU= github.com/ipfs/go-peertaskqueue v0.8.1 h1:YhxAs1+wxb5jk7RvS0LHdyiILpNmRIRnZVztekOF0pg= github.com/ipfs/go-peertaskqueue v0.8.1/go.mod h1:Oxxd3eaK279FxeydSPPVGHzbwVeHjatZ2GA8XD+KbPU= -github.com/ipfs/go-pinning-service-http-client v0.1.2 h1:jdr7KelhL9gNHTU8jbqPMwIexSZXgZzxNGkycCwmbXI= -github.com/ipfs/go-pinning-service-http-client v0.1.2/go.mod h1:6wd5mjYhXJTiWU8b4RSWPpWdlzE5/csoXV0dWWMjun4= -github.com/ipfs/go-unixfs v0.2.4/go.mod h1:SUdisfUjNoSDzzhGVxvCL9QO/nKdwXdr+gbMUdqcbYw= -github.com/ipfs/go-unixfs v0.3.1/go.mod h1:h4qfQYzghiIc8ZNFKiLMFWOTzrWIAtzYQ59W/pCFf1o= -github.com/ipfs/go-unixfs v0.4.4 h1:D/dLBOJgny5ZLIur2vIXVQVW0EyDHdOMBDEhgHrt6rY= -github.com/ipfs/go-unixfs v0.4.4/go.mod h1:TSG7G1UuT+l4pNj91raXAPkX0BhJi3jST1FDTfQ5QyM= -github.com/ipfs/go-unixfsnode v1.1.2/go.mod h1:5dcE2x03pyjHk4JjamXmunTMzz+VUtqvPwZjIEkfV6s= -github.com/ipfs/go-unixfsnode v1.5.2 h1:CvsiTt58W2uR5dD8bqQv+aAY0c1qolmXmSyNbPHYiew= -github.com/ipfs/go-unixfsnode v1.5.2/go.mod h1:NlOebRwYx8lMCNMdhAhEspYPBD3obp7TE0LvBqHY+ks= -github.com/ipfs/go-verifcid v0.0.1/go.mod h1:5Hrva5KBeIog4A+UpqlaIU+DEstipcJYQQZc0g37pY0= +github.com/ipfs/go-unixfs v0.4.5 h1:wj8JhxvV1G6CD7swACwSKYa+NgtdWC1RUit+gFnymDU= +github.com/ipfs/go-unixfsnode v1.6.0 h1:JOSA02yaLylRNi2rlB4ldPr5VcZhcnaIVj5zNLcOjDo= +github.com/ipfs/go-unixfsnode v1.6.0/go.mod h1:PVfoyZkX1B34qzT3vJO4nsLUpRCyhnMuHBznRcXirlk= github.com/ipfs/go-verifcid v0.0.2 h1:XPnUv0XmdH+ZIhLGKg6U2vaPaRDXb9urMyNVCE7uvTs= -github.com/ipfs/go-verifcid v0.0.2/go.mod h1:40cD9x1y4OWnFXbLNJYRe7MpNvWlMn3LZAG5Wb4xnPU= -github.com/ipfs/interface-go-ipfs-core v0.11.0 h1:n1tplrwsz7oZXkpkZM5a3MDBxksMfSQ103ej4e+l7NA= -github.com/ipfs/interface-go-ipfs-core v0.11.0/go.mod h1:xmnoccUXY7N/Q8AIx0vFqgW926/FAZ8+do/1NTEHKsU= github.com/ipld/edelweiss v0.2.0 h1:KfAZBP8eeJtrLxLhi7r3N0cBCo7JmwSRhOJp3WSpNjk= github.com/ipld/edelweiss v0.2.0/go.mod h1:FJAzJRCep4iI8FOFlRriN9n0b7OuX3T/S9++NpBDmA4= github.com/ipld/go-car v0.5.0 h1:kcCEa3CvYMs0iE5BzD5sV7O2EwMiCIp3uF8tA6APQT8= -github.com/ipld/go-car v0.5.0/go.mod h1:ppiN5GWpjOZU9PgpAZ9HbZd9ZgSpwPMr48fGRJOWmvE= -github.com/ipld/go-car/v2 v2.5.1 h1:U2ux9JS23upEgrJScW8VQuxmE94560kYxj9CQUpcfmk= -github.com/ipld/go-car/v2 v2.5.1/go.mod h1:jKjGOqoCj5zn6KjnabD6JbnCsMntqU2hLiU6baZVO3E= -github.com/ipld/go-codec-dagpb v1.3.0/go.mod h1:ga4JTU3abYApDC3pZ00BC2RSvC3qfBb9MSJkMLSwnhA= -github.com/ipld/go-codec-dagpb v1.5.0 h1:RspDRdsJpLfgCI0ONhTAnbHdySGD4t+LHSPK4X1+R0k= -github.com/ipld/go-codec-dagpb v1.5.0/go.mod h1:0yRIutEFD8o1DGVqw4RSHh+BUTlJA9XWldxaaWR/o4g= +github.com/ipld/go-car/v2 v2.9.1-0.20230325062757-fff0e4397a3d h1:22g+x1tgWSXK34i25qjs+afr7basaneEkHaglBshd2g= +github.com/ipld/go-codec-dagpb v1.6.0 h1:9nYazfyu9B1p3NAgfVdpRco3Fs2nFC72DqVsMj6rOcc= +github.com/ipld/go-codec-dagpb v1.6.0/go.mod h1:ANzFhfP2uMJxRBr8CE+WQWs5UsNa0pYtmKZ+agnUw9s= 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.14.1/go.mod h1:QcE4Y9n/ZZr8Ijg5bGPT0GqYWgZ1704nH0RDcQtgTP0= -github.com/ipld/go-ipld-prime v0.19.0 h1:5axC7rJmPc17Emw6TelxGwnzALk0PdupZ2oj2roDj04= -github.com/ipld/go-ipld-prime v0.19.0/go.mod h1:Q9j3BaVXwaA3o5JUDNvptDDr/x8+F7FG6XJ8WI3ILg4= -github.com/ipld/go-ipld-prime/storage/bsadapter v0.0.0-20211210234204-ce2a1c70cd73 h1:TsyATB2ZRRQGTwafJdgEUQkmjOExRV0DNokcihZxbnQ= -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/ipld/go-ipld-prime v0.20.0 h1:Ud3VwE9ClxpO2LkCYP7vWPc0Fo+dYdYzgxUJZ3uRG4g= +github.com/ipld/go-ipld-prime v0.20.0/go.mod h1:PzqZ/ZR981eKbgdr3y2DJYeD/8bgMawdGVlJDE8kK+M= +github.com/ipld/go-ipld-prime/storage/bsadapter v0.0.0-20230102063945-1a409dc236dd h1:gMlw/MhNr2Wtp5RwGdsW23cs+yCuj9k2ON7i9MiJlRo= github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= -github.com/jbenet/go-cienv v0.0.0-20150120210510-1bb1476777ec/go.mod h1:rGaEvXB4uRSZMmzKNLoXvTu1sfx+1kv/DojUlPrSZGs= github.com/jbenet/go-cienv v0.1.0 h1:Vc/s0QbQtoxX8MwwSLWWh+xNNZvM3Lw7NsTcHrvvhMc= github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA= github.com/jbenet/go-random v0.0.0-20190219211222-123a90aedc0c h1:uUx61FiAa1GI6ZmVd2wf2vULeQZIKG66eybjNXKYCz4= github.com/jbenet/go-random v0.0.0-20190219211222-123a90aedc0c/go.mod h1:sdx1xVM9UuLw1tXnhJWN3piypTUO3vCIHYmG15KE/dU= -github.com/jbenet/go-temp-err-catcher v0.0.0-20150120210811-aac704a3f4f2/go.mod h1:8GXXJV31xl8whumTzdZsTt3RnUIiPqzkyf7mxToRCMs= github.com/jbenet/go-temp-err-catcher v0.1.0 h1:zpb3ZH6wIE8Shj2sKS+khgRvf7T7RABoLk/+KKHggpk= github.com/jbenet/go-temp-err-catcher v0.1.0/go.mod h1:0kJRvmDZXNMIiJirNPEYfhpPwbGVtZVWC34vc5WLsDk= github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY= github.com/jbenet/goprocess v0.1.3/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= github.com/jbenet/goprocess v0.1.4 h1:DRGOFReOMqqDNXwW70QkacFW0YN9QnwLV0Vqk+3oU0o= github.com/jbenet/goprocess v0.1.4/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= -github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs= -github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM= -github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o= -github.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxyjn/mY9zx4tFonSg= -github.com/jcmturner/gokrb5/v8 v8.4.2/go.mod h1:sb+Xq/fTY5yktf/VxLsE3wlfPqQjp0aWNYyvBVK62bc= -github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc= github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= -github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= @@ -708,7 +503,6 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI 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.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/compress v1.15.12 h1:YClS/PImqYbn+UILDnqxQCZ3RehC9N318SU3kElDUEM= github.com/klauspost/compress v1.15.12/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= @@ -717,7 +511,6 @@ github.com/klauspost/cpuid/v2 v2.2.3 h1:sxCkb+qR91z4vsqw4vGGZlDgPz3G7gjaLyK3V8y7 github.com/klauspost/cpuid/v2 v2.2.3/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/koron/go-ssdp v0.0.0-20180514024734-4a0ed625a78b/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk= github.com/koron/go-ssdp v0.0.0-20191105050749-2e1c40ed0b5d/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk= github.com/koron/go-ssdp v0.0.3 h1:JivLMY45N76b4p/vsWGOKewBQu6uf39y8l+AQ7sDKx8= github.com/koron/go-ssdp v0.0.3/go.mod h1:b2MxI6yh02pKrsyNoQUsk4+YNikaGhe4894J+Q5lDvA= @@ -725,8 +518,8 @@ github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFB github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= @@ -734,242 +527,77 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= -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-buffer-pool v0.0.1/go.mod h1:xtyIz9PMobb13WaxR6Zo1Pd1zXJKYg0a8KiIvDp3TzQ= github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM= github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38yPW7c= github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic= -github.com/libp2p/go-conn-security-multistream v0.1.0/go.mod h1:aw6eD7LOsHEX7+2hJkDxw1MteijaVcI+/eP2/x3J1xc= -github.com/libp2p/go-conn-security-multistream v0.2.0/go.mod h1:hZN4MjlNetKD3Rq5Jb/P5ohUnFLNzEAR4DLSzpn2QLU= -github.com/libp2p/go-conn-security-multistream v0.2.1/go.mod h1:cR1d8gA0Hr59Fj6NhaTpFhJZrjSYuNmhpT2r25zYR70= github.com/libp2p/go-doh-resolver v0.4.0 h1:gUBa1f1XsPwtpE1du0O+nnZCUqtG7oYi7Bb+0S7FQqw= github.com/libp2p/go-doh-resolver v0.4.0/go.mod h1:v1/jwsFusgsWIGX/c6vCRrnJ60x7bhTiq/fs2qt0cAg= -github.com/libp2p/go-eventbus v0.1.0/go.mod h1:vROgu5cs5T7cv7POWlWxBaVLxfSegC5UGQf8A2eEmx4= -github.com/libp2p/go-eventbus v0.2.1/go.mod h1:jc2S4SoEVPP48H9Wpzm5aiGwUCBMfGhVhhBjyhhCJs8= github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8= github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.1.0/go.mod h1:6D/2OBauqLUoqcADOJpn9WbKqvaM07tDw68qHM0BxUM= -github.com/libp2p/go-libp2p v0.1.1/go.mod h1:I00BRo1UuUSdpuc8Q2mN7yDF/oTUTRAX6JWpTiK9Rp8= -github.com/libp2p/go-libp2p v0.6.1/go.mod h1:CTFnWXogryAHjXAKEbOf1OWY+VeAP3lDMZkfEI5sT54= -github.com/libp2p/go-libp2p v0.7.0/go.mod h1:hZJf8txWeCduQRDC/WSqBGMxaTHCOYHt2xSU1ivxn0k= -github.com/libp2p/go-libp2p v0.7.4/go.mod h1:oXsBlTLF1q7pxr+9w6lqzS1ILpyHsaBPniVO7zIHGMw= -github.com/libp2p/go-libp2p v0.8.1/go.mod h1:QRNH9pwdbEBpx5DTJYg+qxcVaDMAz3Ee/qDKwXujH5o= -github.com/libp2p/go-libp2p v0.14.3/go.mod h1:d12V4PdKbpL0T1/gsUNN8DfgMuRPDX8bS2QxCZlwRH0= github.com/libp2p/go-libp2p v0.26.4 h1:VA9ChjN0n1BwwfU/dqx4Zj9ezXtIxGk8FyJPwFONqxs= github.com/libp2p/go-libp2p v0.26.4/go.mod h1:x75BN32YbwuY0Awm2Uix4d4KOz+/4piInkp4Wr3yOo8= github.com/libp2p/go-libp2p-asn-util v0.2.0 h1:rg3+Os8jbnO5DxkC7K/Utdi+DkY3q/d1/1q+8WeNAsw= github.com/libp2p/go-libp2p-asn-util v0.2.0/go.mod h1:WoaWxbHKBymSN41hWSq/lGKJEca7TNm58+gGJi2WsLI= -github.com/libp2p/go-libp2p-autonat v0.1.0/go.mod h1:1tLf2yXxiE/oKGtDwPYWTSYG3PtvYlJmg7NeVtPRqH8= -github.com/libp2p/go-libp2p-autonat v0.1.1/go.mod h1:OXqkeGOY2xJVWKAGV2inNF5aKN/djNA3fdpCWloIudE= -github.com/libp2p/go-libp2p-autonat v0.2.0/go.mod h1:DX+9teU4pEEoZUqR1PiMlqliONQdNbfzE1C718tcViI= -github.com/libp2p/go-libp2p-autonat v0.2.1/go.mod h1:MWtAhV5Ko1l6QBsHQNSuM6b1sRkXrpk0/LqCr+vCVxI= -github.com/libp2p/go-libp2p-autonat v0.2.2/go.mod h1:HsM62HkqZmHR2k1xgX34WuWDzk/nBwNHoeyyT4IWV6A= -github.com/libp2p/go-libp2p-autonat v0.4.2/go.mod h1:YxaJlpr81FhdOv3W3BTconZPfhaYivRdf53g+S2wobk= -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/go.mod h1:eduNKXGTioTuQAUcZ5epXi9vMl+t4d8ugUBRQ4SqaNQ= -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/go.mod h1:t/ktoFIUzM6uLQ+o1G6NuBl2ANhBKN9Bc8jRIk31MoA= -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= -github.com/libp2p/go-libp2p-core v0.0.4/go.mod h1:jyuCQP356gzfCFtRKyvAbNkyeuxb7OlyhWZ3nls5d2I= -github.com/libp2p/go-libp2p-core v0.2.0/go.mod h1:X0eyB0Gy93v0DZtSYbEM7RnMChm9Uv3j7yRXjO77xSI= -github.com/libp2p/go-libp2p-core v0.2.2/go.mod h1:8fcwTbsG2B+lTgRJ1ICZtiM5GWCWZVoVrLaDRvIRng0= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= github.com/libp2p/go-libp2p-core v0.3.0/go.mod h1:ACp3DmS3/N64c2jDzcV429ukDpicbL6+TrrxANBjPGw= -github.com/libp2p/go-libp2p-core v0.3.1/go.mod h1:thvWy0hvaSBhnVBaW37BvzgVV68OUhgJJLAa6almrII= -github.com/libp2p/go-libp2p-core v0.4.0/go.mod h1:49XGI+kc38oGVwqSBhDEwytaAxgZasHhFfQKibzTls0= -github.com/libp2p/go-libp2p-core v0.5.0/go.mod h1:49XGI+kc38oGVwqSBhDEwytaAxgZasHhFfQKibzTls0= -github.com/libp2p/go-libp2p-core v0.5.1/go.mod h1:uN7L2D4EvPCvzSH5SrhR72UWbnSGpt5/a35Sm4upn4Y= -github.com/libp2p/go-libp2p-core v0.5.4/go.mod h1:uN7L2D4EvPCvzSH5SrhR72UWbnSGpt5/a35Sm4upn4Y= -github.com/libp2p/go-libp2p-core v0.5.5/go.mod h1:vj3awlOr9+GMZJFH9s4mpt9RHHgGqeHCopzbYKZdRjM= -github.com/libp2p/go-libp2p-core v0.5.6/go.mod h1:txwbVEhHEXikXn9gfC7/UDDw7rkxuX0bJvM49Ykaswo= -github.com/libp2p/go-libp2p-core v0.5.7/go.mod h1:txwbVEhHEXikXn9gfC7/UDDw7rkxuX0bJvM49Ykaswo= -github.com/libp2p/go-libp2p-core v0.6.0/go.mod h1:txwbVEhHEXikXn9gfC7/UDDw7rkxuX0bJvM49Ykaswo= -github.com/libp2p/go-libp2p-core v0.7.0/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= -github.com/libp2p/go-libp2p-core v0.8.0/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= -github.com/libp2p/go-libp2p-core v0.8.1/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= -github.com/libp2p/go-libp2p-core v0.8.2/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= -github.com/libp2p/go-libp2p-core v0.8.5/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= -github.com/libp2p/go-libp2p-crypto v0.1.0/go.mod h1:sPUokVISZiy+nNuTTH/TY+leRSxnFj/2GLjtOTW90hI= -github.com/libp2p/go-libp2p-discovery v0.1.0/go.mod h1:4F/x+aldVHjHDHuX85x1zWoFTGElt8HnoDzwkFZm29g= -github.com/libp2p/go-libp2p-discovery v0.2.0/go.mod h1:s4VGaxYMbw4+4+tsoQTqh7wfxg97AEdo4GYBt6BadWg= -github.com/libp2p/go-libp2p-discovery v0.3.0/go.mod h1:o03drFnz9BVAZdzC/QUQ+NeQOu38Fu7LJGEOK2gQltw= -github.com/libp2p/go-libp2p-discovery v0.5.0/go.mod h1:+srtPIU9gDaBNu//UHvcdliKBIcr4SfDcm0/PfPJLug= github.com/libp2p/go-libp2p-gostream v0.5.0 h1:niNGTUrFoUDP/8jxMgu97zngMO+UGYBpVpbCKwIJBls= github.com/libp2p/go-libp2p-gostream v0.5.0/go.mod h1:rXrb0CqfcRRxa7m3RSKORQiKiWgk3IPeXWda66ZXKsA= github.com/libp2p/go-libp2p-http v0.4.0 h1:V+f9Rhe/8GkColmXoyJyA0NVsN9F3TCLZgW2hwjoX5w= github.com/libp2p/go-libp2p-http v0.4.0/go.mod h1:92tmLGrlBliQFDlZRpBXT3BJM7rGFONy0vsNrG/bMPg= -github.com/libp2p/go-libp2p-kad-dht v0.21.1 h1:xpfp8/t9+X2ip1l8Umap1/UGNnJ3RHJgKGAEsnRAlTo= -github.com/libp2p/go-libp2p-kad-dht v0.21.1/go.mod h1:Oy8wvbdjpB70eS5AaFaI68tOtrdo3KylTvXDjikxqFo= +github.com/libp2p/go-libp2p-kad-dht v0.22.0 h1:cW2nGgG0hztDM42tOPyC5cVflD7EzLaHM0/Kjol6Wio= +github.com/libp2p/go-libp2p-kad-dht v0.22.0/go.mod h1:hareSo3Z/GJ7nUWPMj7XhD/56a7+rRltYCWwCuy3FQk= github.com/libp2p/go-libp2p-kbucket v0.3.1/go.mod h1:oyjT5O7tS9CQurok++ERgc46YLwEpuGoFq9ubvoUOio= github.com/libp2p/go-libp2p-kbucket v0.5.0 h1:g/7tVm8ACHDxH29BGrpsQlnNeu+6OF1A9bno/4/U1oA= github.com/libp2p/go-libp2p-kbucket v0.5.0/go.mod h1:zGzGCpQd78b5BNTDGHNDLaTt9aDK/A02xeZp9QeFC4U= -github.com/libp2p/go-libp2p-loggables v0.1.0/go.mod h1:EyumB2Y6PrYjr55Q3/tiJ/o3xoDasoRYM7nOzEpoa90= -github.com/libp2p/go-libp2p-mplex v0.2.0/go.mod h1:Ejl9IyjvXJ0T9iqUTE1jpYATQ9NM3g+OtR+EMMODbKo= -github.com/libp2p/go-libp2p-mplex v0.2.1/go.mod h1:SC99Rxs8Vuzrf/6WhmH41kNn13TiYdAWNYHrwImKLnE= -github.com/libp2p/go-libp2p-mplex v0.2.2/go.mod h1:74S9eum0tVQdAfFiKxAyKzNdSuLqw5oadDq7+L/FELo= -github.com/libp2p/go-libp2p-mplex v0.2.3/go.mod h1:CK3p2+9qH9x+7ER/gWWDYJ3QW5ZxWDkm+dVvjfuG3ek= -github.com/libp2p/go-libp2p-mplex v0.4.0/go.mod h1:yCyWJE2sc6TBTnFpjvLuEJgTSw/u+MamvzILKdX7asw= -github.com/libp2p/go-libp2p-mplex v0.4.1/go.mod h1:cmy+3GfqfM1PceHTLL7zQzAAYaryDu6iPSC+CIb094g= -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= -github.com/libp2p/go-libp2p-netutil v0.1.0/go.mod h1:3Qv/aDqtMLTUyQeundkKsA+YCThNdbQD54k3TqjpbFU= -github.com/libp2p/go-libp2p-noise v0.2.0/go.mod h1:IEbYhBBzGyvdLBoxxULL/SGbJARhUeqlO8lVSREYu2Q= -github.com/libp2p/go-libp2p-peer v0.2.0/go.mod h1:RCffaCvUyW2CJmG2gAWVqwePwW7JMgxjsHm7+J5kjWY= -github.com/libp2p/go-libp2p-peerstore v0.1.0/go.mod h1:2CeHkQsr8svp4fZ+Oi9ykN1HBb6u0MOvdJ7YIsmcwtY= -github.com/libp2p/go-libp2p-peerstore v0.1.3/go.mod h1:BJ9sHlm59/80oSkpWgr1MyY1ciXAXV397W6h1GH/uKI= github.com/libp2p/go-libp2p-peerstore v0.1.4/go.mod h1:+4BDbDiiKf4PzpANZDAT+knVdLxvqh7hXOujessqdzs= -github.com/libp2p/go-libp2p-peerstore v0.2.0/go.mod h1:N2l3eVIeAitSg3Pi2ipSrJYnqhVnMNQZo9nkSCuAbnQ= -github.com/libp2p/go-libp2p-peerstore v0.2.1/go.mod h1:NQxhNjWxf1d4w6PihR8btWIRjwRLBr4TYKfNgrUkOPA= -github.com/libp2p/go-libp2p-peerstore v0.2.2/go.mod h1:NQxhNjWxf1d4w6PihR8btWIRjwRLBr4TYKfNgrUkOPA= -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-pnet v0.2.0/go.mod h1:Qqvq6JH/oMZGwqs3N1Fqhv8NVhrdYcO0BW4wssv21LA= github.com/libp2p/go-libp2p-pubsub v0.9.0 h1:mcLb4WzwhUG4OKb0rp1/bYMd/DYhvMyzJheQH3LMd1s= github.com/libp2p/go-libp2p-pubsub v0.9.0/go.mod h1:OEsj0Cc/BpkqikXRTrVspWU/Hx7bMZwHP+6vNMd+c7I= github.com/libp2p/go-libp2p-pubsub-router v0.6.0 h1:D30iKdlqDt5ZmLEYhHELCMRj8b4sFAqrUcshIUvVP/s= github.com/libp2p/go-libp2p-pubsub-router v0.6.0/go.mod h1:FY/q0/RBTKsLA7l4vqC2cbRbOvyDotg8PJQ7j8FDudE= -github.com/libp2p/go-libp2p-quic-transport v0.10.0/go.mod h1:RfJbZ8IqXIhxBRm5hqUEJqjiiY8xmEuq3HUDS993MkA= -github.com/libp2p/go-libp2p-record v0.1.0/go.mod h1:ujNc8iuE5dlKWVy6wuL6dd58t0n7xI4hAIl8pE6wu5Q= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= github.com/libp2p/go-libp2p-record v0.2.0/go.mod h1:I+3zMkvvg5m2OcSdoL0KPljyJyvNDFGKX7QdlpYUcwk= github.com/libp2p/go-libp2p-routing-helpers v0.6.1 h1:tI3rHOf/FDQsxC2pHBaOZiqPJ0MZYyzGAf4V45xla4U= github.com/libp2p/go-libp2p-routing-helpers v0.6.1/go.mod h1:R289GUxUMzRXIbWGSuUUTPrlVJZ3Y/pPz495+qgXJX8= -github.com/libp2p/go-libp2p-secio v0.1.0/go.mod h1:tMJo2w7h3+wN4pgU2LSYeiKPrfqBgkOsdiKK77hE7c8= -github.com/libp2p/go-libp2p-secio v0.2.0/go.mod h1:2JdZepB8J5V9mBp79BmwsaPQhRPNN2NrnB2lKQcdy6g= -github.com/libp2p/go-libp2p-secio v0.2.1/go.mod h1:cWtZpILJqkqrSkiYcDBh5lA3wbT2Q+hz3rJQq3iftD8= -github.com/libp2p/go-libp2p-secio v0.2.2/go.mod h1:wP3bS+m5AUnFA+OFO7Er03uO1mncHG0uVwGrwvjYlNY= -github.com/libp2p/go-libp2p-swarm v0.1.0/go.mod h1:wQVsCdjsuZoc730CgOvh5ox6K8evllckjebkdiY5ta4= -github.com/libp2p/go-libp2p-swarm v0.2.2/go.mod h1:fvmtQ0T1nErXym1/aa1uJEyN7JzaTNyBcHImCxRpPKU= -github.com/libp2p/go-libp2p-swarm v0.2.3/go.mod h1:P2VO/EpxRyDxtChXz/VPVXyTnszHvokHKRhfkEgFKNM= -github.com/libp2p/go-libp2p-swarm v0.2.8/go.mod h1:JQKMGSth4SMqonruY0a8yjlPVIkb0mdNSwckW7OYziM= -github.com/libp2p/go-libp2p-swarm v0.3.0/go.mod h1:hdv95GWCTmzkgeJpP+GK/9D9puJegb7H57B5hWQR5Kk= -github.com/libp2p/go-libp2p-swarm v0.5.0/go.mod h1:sU9i6BoHE0Ve5SKz3y9WfKrh8dUat6JknzUehFx8xW4= -github.com/libp2p/go-libp2p-testing v0.0.2/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= -github.com/libp2p/go-libp2p-testing v0.0.3/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= -github.com/libp2p/go-libp2p-testing v0.0.4/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= -github.com/libp2p/go-libp2p-testing v0.1.0/go.mod h1:xaZWMJrPUM5GlDBxCeGUi7kI4eqnjVyavGroI2nxEM0= -github.com/libp2p/go-libp2p-testing v0.1.1/go.mod h1:xaZWMJrPUM5GlDBxCeGUi7kI4eqnjVyavGroI2nxEM0= -github.com/libp2p/go-libp2p-testing v0.1.2-0.20200422005655-8775583591d8/go.mod h1:Qy8sAncLKpwXtS2dSnDOP8ktexIAHKu+J+pnZOFZLTc= -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.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA= github.com/libp2p/go-libp2p-testing v0.12.0/go.mod h1:KcGDRXyN7sQCllucn1cOOS+Dmm7ujhfEyXQL5lvkcPg= -github.com/libp2p/go-libp2p-tls v0.1.3/go.mod h1:wZfuewxOndz5RTnCAxFliGjvYSDA40sKitV4c50uI1M= -github.com/libp2p/go-libp2p-transport-upgrader v0.1.1/go.mod h1:IEtA6or8JUbsV07qPW4r01GnTenLW4oi3lOPbUMGJJA= -github.com/libp2p/go-libp2p-transport-upgrader v0.2.0/go.mod h1:mQcrHj4asu6ArfSoMuyojOdjx73Q47cYD7s5+gZOlns= -github.com/libp2p/go-libp2p-transport-upgrader v0.3.0/go.mod h1:i+SKzbRnvXdVbU3D1dwydnTmKRPXiAR/fyvi1dXuL4o= -github.com/libp2p/go-libp2p-transport-upgrader v0.4.2/go.mod h1:NR8ne1VwfreD5VIWIU62Agt/J18ekORFU/j1i2y8zvk= github.com/libp2p/go-libp2p-xor v0.1.0 h1:hhQwT4uGrBcuAkUGXADuPltalOdpf9aag9kaYNT2tLA= github.com/libp2p/go-libp2p-xor v0.1.0/go.mod h1:LSTM5yRnjGZbWNTA/hRwq2gGFrvRIbQJscoIL/u6InY= -github.com/libp2p/go-libp2p-yamux v0.2.0/go.mod h1:Db2gU+XfLpm6E4rG5uGCFX6uXA8MEXOxFcRoXUODaK8= -github.com/libp2p/go-libp2p-yamux v0.2.1/go.mod h1:1FBXiHDk1VyRM1C0aez2bCfHQ4vMZKkAQzZbkSQt5fI= -github.com/libp2p/go-libp2p-yamux v0.2.2/go.mod h1:lIohaR0pT6mOt0AZ0L2dFze9hds9Req3OfS+B+dv4qw= -github.com/libp2p/go-libp2p-yamux v0.2.5/go.mod h1:Zpgj6arbyQrmZ3wxSZxfBmbdnWtbZ48OpsfmQVTErwA= -github.com/libp2p/go-libp2p-yamux v0.2.7/go.mod h1:X28ENrBMU/nm4I3Nx4sZ4dgjZ6VhLEn0XhIoZ5viCwU= -github.com/libp2p/go-libp2p-yamux v0.2.8/go.mod h1:/t6tDqeuZf0INZMTgd0WxIRbtK2EzI2h7HbFm9eAKI4= -github.com/libp2p/go-libp2p-yamux v0.4.0/go.mod h1:+DWDjtFMzoAwYLVkNZftoucn7PelNoy5nm3tZ3/Zw30= -github.com/libp2p/go-libp2p-yamux v0.5.0/go.mod h1:AyR8k5EzyM2QN9Bbdg6X1SkVVuqLwTGf0L4DFq9g6po= -github.com/libp2p/go-libp2p-yamux v0.5.4/go.mod h1:tfrXbyaTqqSU654GTvK3ocnSZL3BuHoeTSqhcel1wsE= -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/go.mod h1:VzZhTXkMucEGGEOSKddrwGiOv0tUhgnKqNEmIAz/bPU= -github.com/libp2p/go-mplex v0.0.3/go.mod h1:pK5yMLmOoBR1pNCqDlA2GQrdAVTMkqFalaTWe7l4Yd0= -github.com/libp2p/go-mplex v0.1.0/go.mod h1:SXgmdki2kwCUlCCbfGLEgHjC4pFqhTp0ZoV6aiKgxDU= -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/go.mod h1:0Oy/A9PQlwBytDRp4wSkFnzHYDKcpLot35JQ6msjvYQ= github.com/libp2p/go-mplex v0.7.0 h1:BDhFZdlk5tbr0oyFq/xv/NPGfjbnrsDam1EvutpBDbY= github.com/libp2p/go-mplex v0.7.0/go.mod h1:rW8ThnRcYWft/Jb2jeORBmPd6xuG3dGxWN/W168L9EU= -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= -github.com/libp2p/go-msgio v0.0.6/go.mod h1:4ecVB6d9f4BDSL5fqvPiC4A3KivjWn+Venn/1ALLMWA= github.com/libp2p/go-msgio v0.3.0 h1:mf3Z8B1xcFN314sWX+2vOTShIE0Mmn2TXn3YCUQGNj0= github.com/libp2p/go-msgio v0.3.0/go.mod h1:nyRM819GmVaF9LX3l03RMh10QdOroF++NBbxAb0mmDM= -github.com/libp2p/go-nat v0.0.3/go.mod h1:88nUEt0k0JD45Bk93NIwDqjlhiOwOoV36GchpcVc1yI= -github.com/libp2p/go-nat v0.0.4/go.mod h1:Nmw50VAvKuk38jUBcmNh6p9lUJLoODbJRvYAa/+KSDo= -github.com/libp2p/go-nat v0.0.5/go.mod h1:B7NxsVNPZmRLvMOwiEO1scOSyjA56zxYAGv1yQgRkEU= github.com/libp2p/go-nat v0.1.0 h1:MfVsH6DLcpa04Xr+p8hmVRG4juse0s3J8HyNWYHffXg= github.com/libp2p/go-nat v0.1.0/go.mod h1:X7teVkwRHNInVNWQiO/tAiAVRwSr5zoRz4YSTC3uRBM= 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/go.mod h1:AqhkMh0VuWmfgtxKPp3Oc1LdU5QSWS7wl0QLhSZqXxQ= github.com/libp2p/go-netroute v0.2.1 h1:V8kVrpD8GK0Riv15/7VN6RbUQ3URNZVosw7H2v9tksU= github.com/libp2p/go-netroute v0.2.1/go.mod h1:hraioZr0fhBjG0ZRXJJ6Zj2IVEVNx6tDTFQfSmcq7mQ= -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= -github.com/libp2p/go-openssl v0.0.5/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= -github.com/libp2p/go-openssl v0.0.7/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= -github.com/libp2p/go-reuseport v0.0.1/go.mod h1:jn6RmB1ufnQwl0Q1f+YxAj8isJgDCQzaaxIFYDhcYEA= -github.com/libp2p/go-reuseport v0.0.2/go.mod h1:SPD+5RwGC7rcnzngoYC86GjPzjSywuQyMVAheVBD9nQ= github.com/libp2p/go-reuseport v0.2.0 h1:18PRvIMlpY6ZK85nIAicSBuXXvrYoSw3dsBAR7zc560= github.com/libp2p/go-reuseport v0.2.0/go.mod h1:bvVho6eLMm6Bz5hmU0LYN3ixd3nPPvtIlaURZZgOY4k= -github.com/libp2p/go-reuseport-transport v0.0.2/go.mod h1:YkbSDrvjUVDL6b8XqriyA20obEtsW9BLkuOUyQAOCbs= -github.com/libp2p/go-reuseport-transport v0.0.3/go.mod h1:Spv+MPft1exxARzP2Sruj2Wb5JSyHNncjf1Oi2dEbzM= -github.com/libp2p/go-reuseport-transport v0.0.4/go.mod h1:trPa7r/7TJK/d+0hdBLOCGvpQQVOU74OXbNCIMkufGw= 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/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= -github.com/libp2p/go-stream-muxer v0.0.1/go.mod h1:bAo8x7YkSpadMTbtTaxGVHWUQsR/l5MEaHbKaliuT14= -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/go.mod h1:yDh8abSIzmZtqtOt64gFJUXEryejzNb0lisTt+fAMJA= -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= -github.com/libp2p/go-tcp-transport v0.2.0/go.mod h1:vX2U0CnWimU4h0SGSEsg++AzvBcroCGYw28kh94oLe0= -github.com/libp2p/go-tcp-transport v0.2.3/go.mod h1:9dvr03yqrPyYGIEN6Dy5UvdJZjyPFvl1S/igQ5QD1SU= -github.com/libp2p/go-testutil v0.1.0/go.mod h1:81b2n5HypcVyrCg/MJx4Wgfp/VHojytjVe/gLzZ2Ehc= -github.com/libp2p/go-ws-transport v0.1.0/go.mod h1:rjw1MG1LU9YDC6gzmwObkPd/Sqwhw7yT74kj3raBFuo= -github.com/libp2p/go-ws-transport v0.2.0/go.mod h1:9BHJz/4Q5A9ludYWKoGCFC5gUElzlHoKzu0yY9p/klM= -github.com/libp2p/go-ws-transport v0.3.0/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-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= -github.com/libp2p/go-yamux v1.3.0/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= -github.com/libp2p/go-yamux v1.3.3/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= -github.com/libp2p/go-yamux v1.3.5/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= -github.com/libp2p/go-yamux v1.3.7/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/hkmpooHE= -github.com/libp2p/go-yamux v1.4.0/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/hkmpooHE= -github.com/libp2p/go-yamux v1.4.1/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/hkmpooHE= -github.com/libp2p/go-yamux/v2 v2.2.0/go.mod h1:3So6P6TV6r75R9jiBpiIKgU/66lOarCZjqROGxzPpPQ= github.com/libp2p/go-yamux/v4 v4.0.0 h1:+Y80dV2Yx/kv7Y7JKu0LECyVdMXm1VUoko+VQ9rBfZQ= github.com/libp2p/go-yamux/v4 v4.0.0/go.mod h1:NWjl8ZTLOGlozrXSOZ/HlfG++39iKNnM5wwmtQP1YB4= github.com/libp2p/zeroconf/v2 v2.2.0 h1:Cup06Jv6u81HLhIj1KasuNM/RHHrJ8T7wOTS4+Tv53Q= github.com/libp2p/zeroconf/v2 v2.2.0/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= -github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= -github.com/lucas-clemente/quic-go v0.19.3/go.mod h1:ADXpNbTQjq1hIzCpB+y/k5iz4n4z4IwqoLb94Kh5Hu8= 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= github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/marten-seemann/qpack v0.2.1/go.mod h1:F7Gl5L1jIgN1D11ucXefiuJS9UMVP2opoCp2jDKb7wc= -github.com/marten-seemann/qtls v0.10.0/go.mod h1:UvMd1oaYDACI99/oZUYLzMCkBXQVT0aGm99sJhbT8hs= -github.com/marten-seemann/qtls-go1-15 v0.1.1/go.mod h1:GyFwywLKkRt+6mfU99csTEY1joMZz5vmB1WNZH3P81I= 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= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= -github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= 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= @@ -979,7 +607,6 @@ github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Ky github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -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= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= @@ -988,9 +615,6 @@ github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfr github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4= github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= -github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/miekg/dns v1.1.12/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/miekg/dns v1.1.28/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA= @@ -1003,20 +627,12 @@ github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc h1:PTfri+PuQmWDqERdn github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc/go.mod h1:cGKTAVKx4SxOuR/czcZ/E2RSJ3sfHs8FpHhQ5CWMf9s= github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= -github.com/minio/sha256-simd v0.0.0-20190328051042-05b4dd3047e5/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= -github.com/minio/sha256-simd v0.1.0/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g= github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM= -github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= -github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= -github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= -github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= -github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= @@ -1026,7 +642,6 @@ github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3Rllmb github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= -github.com/mr-tron/base58 v1.1.1/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mr-tron/base58 v1.1.3/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= @@ -1037,46 +652,26 @@ github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYg github.com/multiformats/go-base36 v0.1.0/go.mod h1:kFGE83c6s80PklsHO9sRn2NCoffoRdUUOENyW/Vv6sM= github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0= github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4= -github.com/multiformats/go-multiaddr v0.0.1/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= -github.com/multiformats/go-multiaddr v0.0.2/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= -github.com/multiformats/go-multiaddr v0.0.4/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= github.com/multiformats/go-multiaddr v0.1.0/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo= github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4= -github.com/multiformats/go-multiaddr v0.2.1/go.mod h1:s/Apk6IyxfvMjDafnhJgJ3/46z7tZ04iMk5wP4QMGGE= -github.com/multiformats/go-multiaddr v0.2.2/go.mod h1:NtfXiOtHvghW9KojvtySjH5y0u0xW5UouOmQQrn6a3Y= -github.com/multiformats/go-multiaddr v0.3.0/go.mod h1:dF9kph9wfJ+3VLAaeBqo9Of8x4fJxp6ggJGteB8HQTI= -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.8.0 h1:aqjksEcqK+iD/Foe1RRFsGZh8+XFiGo7FgUCZlpv3LU= github.com/multiformats/go-multiaddr v0.8.0/go.mod h1:Fs50eBDWvZu+l3/9S6xAE7ZYj6yhxlvaVZjakWN7xRs= -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= github.com/multiformats/go-multiaddr-dns v0.3.0/go.mod h1:mNzQ4eTGDg0ll1N9jKPOUogZPoJ30W8a7zk66FQPpdQ= github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A= github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk= -github.com/multiformats/go-multiaddr-fmt v0.0.1/go.mod h1:aBYjqL4T/7j4Qx+R73XSv/8JsgnRFlf0w2KGLCmXl3Q= github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E= github.com/multiformats/go-multiaddr-fmt v0.1.0/go.mod h1:hGtDIW4PU4BqJ50gW2quDuPVjyWNZxToGUh/HwTZYJo= -github.com/multiformats/go-multiaddr-net v0.0.1/go.mod h1:nw6HSxNmCIQH27XPGBuX+d1tnvM7ihcFwHMSstNAVUU= -github.com/multiformats/go-multiaddr-net v0.1.0/go.mod h1:5JNbcfBOP4dnhoZOv10JJVkJO0pCCEf8mTnipAo2UZQ= github.com/multiformats/go-multiaddr-net v0.1.1/go.mod h1:5JNbcfBOP4dnhoZOv10JJVkJO0pCCEf8mTnipAo2UZQ= -github.com/multiformats/go-multiaddr-net v0.1.2/go.mod h1:QsWt3XK/3hwvNxZJp92iMQKME1qHfpYmyIjFVsSOY6Y= -github.com/multiformats/go-multiaddr-net v0.1.3/go.mod h1:ilNnaM9HbmVFqsb/qcNysjCu4PVONlrBZpHIrw/qQuA= -github.com/multiformats/go-multiaddr-net v0.1.4/go.mod h1:ilNnaM9HbmVFqsb/qcNysjCu4PVONlrBZpHIrw/qQuA= -github.com/multiformats/go-multiaddr-net v0.1.5/go.mod h1:ilNnaM9HbmVFqsb/qcNysjCu4PVONlrBZpHIrw/qQuA= -github.com/multiformats/go-multiaddr-net v0.2.0/go.mod h1:gGdH3UXny6U3cKKYCvpXI5rnK7YaOIEOPVDI9tsJbEA= github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= github.com/multiformats/go-multibase v0.0.3/go.mod h1:5+1R4eQrT3PkYZ24C3W2Ue2tPwIdYQD509ZjSb5y9Oc= github.com/multiformats/go-multibase v0.1.1 h1:3ASCDsuLX8+j4kx58qnJ4YFq/JWTJpCyDW27ztsVTOI= github.com/multiformats/go-multibase v0.1.1/go.mod h1:ZEjHE+IsUrgp5mhlEAYjMtZwK1k4haNkcaPg9aoe1a8= github.com/multiformats/go-multicodec v0.3.0/go.mod h1:qGGaQmioCDh+TeFOnxrbU0DaIPw8yFgAZgFG0V7p1qQ= -github.com/multiformats/go-multicodec v0.7.0 h1:rTUjGOwjlhGHbEMbPoSUJowG1spZTVsITRANCjKTUAQ= -github.com/multiformats/go-multicodec v0.7.0/go.mod h1:GUC8upxSBE4oG+q3kWZRw/+6yC1BqO550bjhWsJbZlw= +github.com/multiformats/go-multicodec v0.8.1 h1:ycepHwavHafh3grIbR1jIXnKCsFm0fqsfEOsJ8NtKE8= +github.com/multiformats/go-multicodec v0.8.1/go.mod h1:L3QTQvMIaVBkXOXXtVmYE+LI16i14xuaojr/H7Ai54k= github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= -github.com/multiformats/go-multihash v0.0.5/go.mod h1:lt/HCbqlQwlPBz7lv0sQCdtfcMtlJvakRUn/0Ual8po= github.com/multiformats/go-multihash v0.0.8/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= github.com/multiformats/go-multihash v0.0.10/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= github.com/multiformats/go-multihash v0.0.13/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= @@ -1085,122 +680,73 @@ github.com/multiformats/go-multihash v0.0.15/go.mod h1:D6aZrWNLFTV/ynMpKsNtB40mJ github.com/multiformats/go-multihash v0.1.0/go.mod h1:RJlXsxt6vHGaia+S8We0ErjhojtKzPP2AH4+kYM7k84= github.com/multiformats/go-multihash v0.2.1 h1:aem8ZT0VA2nCHHk7bPJ1BjUbHNciqZC/d16Vve9l108= github.com/multiformats/go-multihash v0.2.1/go.mod h1:WxoMcYG85AZVQUyRyo9s4wULvW5qrI9vb2Lt6evduFc= -github.com/multiformats/go-multistream v0.1.0/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg= -github.com/multiformats/go-multistream v0.1.1/go.mod h1:KmHZ40hzVxiaiwlj3MEbYgK9JFk2/9UktWZAF54Du38= -github.com/multiformats/go-multistream v0.2.1/go.mod h1:5GZPQZbkWOLOn3J2y4Y99vVW7vOfsAflxARk3x14o6k= -github.com/multiformats/go-multistream v0.2.2/go.mod h1:UIcnm7Zuo8HKG+HkWgfQsGL+/MIEhyTqbODbIUwSXKs= github.com/multiformats/go-multistream v0.4.1 h1:rFy0Iiyn3YT0asivDUIR05leAdwZq3de4741sbiSdfo= github.com/multiformats/go-multistream v0.4.1/go.mod h1:Mz5eykRVAjJWckE2U78c6xqdtyNUEhKSM0Lwar2p77Q= github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= -github.com/multiformats/go-varint v0.0.2/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/multiformats/go-varint v0.0.6/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8= github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= -github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= -github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= -github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= -github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= -github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= -github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= -github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= -github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= -github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= -github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= -github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= -github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/ginkgo/v2 v2.5.1 h1:auzK7OI497k6x4OvWq+TKAcpcSAlod0doAH72oIN0Jw= github.com/onsi/ginkgo/v2 v2.5.1/go.mod h1:63DOGlLAH8+REH8jUGdL3YpCpu7JODesutUjdENfUAc= -github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.16.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.24.0 h1:+0glovB9Jd6z3VR+ScSwQqXVTIfJcGA9UBM8yzQxhqg= -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= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= -github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= -github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= -github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= -github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= -github.com/openzipkin/zipkin-go v0.4.0 h1:CtfRrOVZtbDj8rt1WXjklw0kqqJQwICrCKmlfUuBUUw= -github.com/openzipkin/zipkin-go v0.4.0/go.mod h1:4c3sLeE8xjNqehmF5RpAFLPLJxXscc0R4l6Zg0P1tTQ= -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/openzipkin/zipkin-go v0.4.1 h1:kNd/ST2yLLWhaWrkgchya40TJabe8Hioj9udfPcEO5A= +github.com/openzipkin/zipkin-go v0.4.1/go.mod h1:qY0VqDSN1pOBN94dBc6w2GJlWLiovAyg7Qt6/I9HecM= 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= github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 h1:1/WtZae0yGtPq+TI6+Tv1WTxkukpXeMlviSxvL7SRgk= -github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= -github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= -github.com/pierrec/lz4 v2.6.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/polydawn/refmt v0.0.0-20190221155625-df39d6c2d992/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= -github.com/polydawn/refmt v0.0.0-20190408063855-01bf1e26dd14/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= github.com/polydawn/refmt v0.0.0-20190807091052-3d65705ee9f1/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= github.com/polydawn/refmt v0.0.0-20201211092308-30ac6d18308e/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= github.com/polydawn/refmt v0.89.0 h1:ADJTApkvkeBZsN0tBTx8QjpD9JkmxbKp0cxfr9qszm4= github.com/polydawn/refmt v0.89.0/go.mod h1:/zvteZs/GwLtCgZ4BL6CBsk9IKIlexP43ObX9AxTqTw= -github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM= -github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.10.0/go.mod h1:WJM3cc3yu7XKBKa/I8WeZm+V3eltZnBwfENSU7mdogU= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw= github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= -github.com/prometheus/common v0.18.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/common v0.28.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= @@ -1209,9 +755,7 @@ github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJ github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= @@ -1229,26 +773,19 @@ github.com/quic-go/quic-go v0.33.0 h1:ItNoTDN/Fm/zBlq769lLJc8ECe9gYaW40veHCCco7y github.com/quic-go/quic-go v0.33.0/go.mod h1:YMuhaAV9/jIu0XclDXwZPAsP/2Kgr5yMYhe9oxhhOFA= github.com/quic-go/webtransport-go v0.5.2 h1:GA6Bl6oZY+g/flt00Pnu0XtivSD8vukOu3lYhJjnGEk= github.com/quic-go/webtransport-go v0.5.2/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= -github.com/rabbitmq/amqp091-go v1.1.0/go.mod h1:ogQDLSOACsLPsIq0NpbtiifNZi2YOz0VTJ0kHRghqbM= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU= -github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= -github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/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= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd/go.mod h1:hPqNNc0+uJM6H+SuU8sEs5K5IQeKccPqeSjfgcKGgPk= -github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/samber/lo v1.36.0 h1:4LaOxH1mHnbDGhTVE0i1z8v/lWaQW8AIfOD3HU4mSaw= github.com/samber/lo v1.36.0/go.mod h1:HLeWcJRRyLKp3+/XBJvOrerCQn9mhdKMHyd7IRlgeQ8= -github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= -github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY= github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM= @@ -1277,38 +814,27 @@ github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPx 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/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/assertions v1.0.0/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= github.com/smartystreets/assertions v1.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N3yZFZkDFs= github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo= github.com/smartystreets/goconvey v0.0.0-20190222223459-a17d461953aa/go.mod h1:2RVY1rIf+2J2o/IM9+vPq9RzmHDSseB7FoXiSNIUsoU= -github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/smartystreets/goconvey v1.7.2 h1:9RBaZCeXEQ3UselpuwUQHltGVXvdwm6cv1hgR6gDIPg= github.com/smartystreets/goconvey v1.7.2/go.mod h1:Vw0tHAZW6lzCRk3xgdin6fKYcG+G3Pg9vgXWeJpQFMM= github.com/smola/gocompat v0.2.0/go.mod h1:1B0MlxbmoZNo3h8guHp8HztB3BSYR5itql9qtVc0ypY= -github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= -github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE= github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA= -github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a/go.mod h1:7AyxJNCJ7SBZ1MfVQCWD6Uqo2oubI2Eq2y2eqf+A5r0= github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/src-d/envconfig v1.0.0/go.mod h1:Q9YQZ7BKITldTBnoxsE5gOeB5y66RyPXeue/R4aaNBc= -github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= -github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= -github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= @@ -1322,8 +848,9 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= @@ -1332,7 +859,6 @@ github.com/texttheater/golang-levenshtein v0.0.0-20180516184445-d188e65d659e h1: github.com/texttheater/golang-levenshtein v0.0.0-20180516184445-d188e65d659e/go.mod h1:XDKHRm5ThF8YJjx001LtgelzsoaEcvnA7lVWz9EeX3g= github.com/thoas/go-funk v0.9.1 h1:O549iLZqPpTUQ10ykd26sZhzD+rmR5pWhuElrhbC20M= github.com/tj/assert v0.0.3 h1:Df/BlaZ20mq6kuai7f5z2TvPFiwC3xaWJSDQNiIS3Rk= -github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c h1:u6SKchux2yDvFQnDHS3lPnIRmfVJ5Sxy3ao2SIdysLQ= github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM= github.com/ucarion/urlpath v0.0.0-20200424170820-7ccc79b76bbb h1:Ywfo8sUltxogBpFuMOFRrrSifO788kAFxmvVw31PtQQ= @@ -1342,19 +868,15 @@ github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVM github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= -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 v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU= github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM= github.com/wangjia184/sortedset v0.0.0-20160527075905-f5d03557ba30/go.mod h1:YkocrP2K2tcw938x9gCOmT5G5eCD6jsTz0SZuyAqwIE= github.com/warpfork/go-testmark v0.3.0/go.mod h1:jhEf8FVxd+F17juRubpmut64NEG6I2rgkUhlcqqXwE0= github.com/warpfork/go-testmark v0.9.0/go.mod h1:jhEf8FVxd+F17juRubpmut64NEG6I2rgkUhlcqqXwE0= -github.com/warpfork/go-testmark v0.10.0 h1:E86YlUMYfwIacEsQGlnTvjk1IgYkyTGjPhF0RnwTCmw= +github.com/warpfork/go-testmark v0.11.0 h1:J6LnV8KpceDvo7spaNU4+DauH2n1x+6RaO2rJrmpQ9U= github.com/warpfork/go-wish v0.0.0-20180510122957-5ad1f5abf436/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= -github.com/warpfork/go-wish v0.0.0-20190328234359-8b3e70f8e830/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= github.com/warpfork/go-wish v0.0.0-20200122115046-b9ea61034e4a/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0 h1:GDDkbFiaK8jsSDJfjId/PEGEShv6ugrt4kYsC5UIDaQ= github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= @@ -1369,31 +891,18 @@ github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f/go.mod h1:p9 github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 h1:EKhdznlJHPMoKr0XTrX+IlJs1LH3lyx2nfr1dOlZ79k= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc= github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= -github.com/whyrusleeping/go-logging v0.0.1/go.mod h1:lDPYj54zutzG1XYfHAhcc7oNXEburHQBn+Iqd4yS4vE= -github.com/whyrusleeping/go-notifier v0.0.0-20170827234753-097c5d47330f/go.mod h1:cZNvX9cFybI01GriPRMXDtczuvUhgbcYr9iCGaNlRv8= github.com/whyrusleeping/go-sysinfo v0.0.0-20190219211824-4a357d4b90b1 h1:ctS9Anw/KozviCCtK6VWMz5kPL9nbQzbQY4yfqlIV4M= github.com/whyrusleeping/go-sysinfo v0.0.0-20190219211824-4a357d4b90b1/go.mod h1:tKH72zYNt/exx6/5IQO6L9LoQ0rEjd5SbbWaDTs9Zso= -github.com/whyrusleeping/mafmt v1.2.8/go.mod h1:faQJFPbLSxzD9xpA02ttW/tS9vZykNvXwGvqIpk20FA= -github.com/whyrusleeping/mdns v0.0.0-20180901202407-ef14215e6b30/go.mod h1:j4l84WPFclQPj320J9gp0XwNKBb3U0zt5CBqjPp22G4= -github.com/whyrusleeping/mdns v0.0.0-20190826153040-b9b60ed33aa9/go.mod h1:j4l84WPFclQPj320J9gp0XwNKBb3U0zt5CBqjPp22G4= github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 h1:E9S12nwJwEOXe2d6gT6qxdvqMnNq+VnSsKPgm2ZZNds= github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7/go.mod h1:X2c0RVCI1eSUFI8eLcY3c0423ykwiUdxLJtkDvruhjI= github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE= -github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= -github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= -github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= -github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA= -go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= -go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.1/go.mod h1:Ap50jQcDJrx6rB6VgeeFPtuPIf3wMRvRfrfYDO6+BmA= @@ -1405,34 +914,34 @@ go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.32.0 h1:mac9BKRqwaX6zxHPDe3pvmWpwuuIM0vuXv2juCnQevE= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.32.0/go.mod h1:5eCOqeGphOyz6TsY3ZDNjE33SM/TFAK3RGuCL2naTgY= -go.opentelemetry.io/otel v1.7.0 h1:Z2lA3Tdch0iDcrhJXDIlC94XE+bxok1F9B+4Lz/lGsM= go.opentelemetry.io/otel v1.7.0/go.mod h1:5BdUoMIz5WEs0vt0CUEMtSSaTSHBBVwrhnz7+nrD5xk= -go.opentelemetry.io/otel/exporters/jaeger v1.7.0 h1:wXgjiRldljksZkZrldGVe6XrG9u3kYDyQmkZwmm5dI0= -go.opentelemetry.io/otel/exporters/jaeger v1.7.0/go.mod h1:PwQAOqBgqbLQRKlj466DuD2qyMjbtcPpfPfj+AqbSBs= -go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.7.0 h1:7Yxsak1q4XrJ5y7XBnNwqWx9amMZvoidCctv62XOQ6Y= -go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.7.0/go.mod h1:M1hVZHNxcbkAlcvrOMlpQ4YOO3Awf+4N2dxkZL3xm04= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.7.0 h1:cMDtmgJ5FpRvqx9x2Aq+Mm0O6K/zcUkH73SFz20TuBw= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.7.0/go.mod h1:ceUgdyfNv4h4gLxHR0WNfDiiVmZFodZhZSbOLhpxqXE= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.7.0 h1:MFAyzUPrTwLOwCi+cltN0ZVyy4phU41lwH+lyMyQTS4= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.7.0/go.mod h1:E+/KKhwOSw8yoPxSSuUHG6vKppkvhN+S1Jc7Nib3k3o= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.7.0 h1:pLP0MH4MAqeTEV0g/4flxw9O8Is48uAIauAnjznbW50= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.7.0/go.mod h1:aFXT9Ng2seM9eizF+LfKiyPBGy8xIZKwhusC1gIu3hA= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.7.0 h1:8hPcgCg0rUJiKE6VWahRvjgLUrNl7rW2hffUEPKXVEM= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.7.0/go.mod h1:K4GDXPY6TjUiwbOh+DkKaEdCF8y+lvMoM6SeAPyfCCM= -go.opentelemetry.io/otel/exporters/zipkin v1.7.0 h1:X0FZj+kaIdLi29UiyrEGDhRTYsEXj9GdEW5Y39UQFEE= -go.opentelemetry.io/otel/exporters/zipkin v1.7.0/go.mod h1:9YBXeOMFLQGwNEjsxMRiWPGoJX83usGMhbCmxUbNe5I= +go.opentelemetry.io/otel v1.14.0 h1:/79Huy8wbf5DnIPhemGB+zEPVwnN6fuQybr/SRXa6hM= +go.opentelemetry.io/otel v1.14.0/go.mod h1:o4buv+dJzx8rohcUeRmWUZhqupFvzWis188WlggnNeU= +go.opentelemetry.io/otel/exporters/jaeger v1.14.0 h1:CjbUNd4iN2hHmWekmOqZ+zSCU+dzZppG8XsV+A3oc8Q= +go.opentelemetry.io/otel/exporters/jaeger v1.14.0/go.mod h1:4Ay9kk5vELRrbg5z4cpP9EtmQRFap2Wb0woPG4lujZA= +go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.14.0 h1:/fXHZHGvro6MVqV34fJzDhi7sHGpX3Ej/Qjmfn003ho= +go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.14.0/go.mod h1:UFG7EBMRdXyFstOwH028U0sVf+AvukSGhF0g8+dmNG8= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.14.0 h1:TKf2uAs2ueguzLaxOCBXNpHxfO/aC7PAdDsSH0IbeRQ= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.14.0/go.mod h1:HrbCVv40OOLTABmOn1ZWty6CHXkU8DK/Urc43tHug70= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.14.0 h1:ap+y8RXX3Mu9apKVtOkM6WSFESLM8K3wNQyOU8sWHcc= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.14.0/go.mod h1:5w41DY6S9gZrbjuq6Y+753e96WfPha5IcsOSZTtullM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.14.0 h1:3jAYbRHQAqzLjd9I4tzxwJ8Pk/N6AqBcF6m1ZHrxG94= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.14.0/go.mod h1:+N7zNjIJv4K+DeX67XXET0P+eIciESgaFDBqh+ZJFS4= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.14.0 h1:sEL90JjOO/4yhquXl5zTAkLLsZ5+MycAgX99SDsxGc8= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.14.0/go.mod h1:oCslUcizYdpKYyS9e8srZEqM6BB8fq41VJBjLAE6z1w= +go.opentelemetry.io/otel/exporters/zipkin v1.14.0 h1:reEVE1upBF9tcujgvSqLJS0SrI7JQPaTKP4s4rymnSs= +go.opentelemetry.io/otel/exporters/zipkin v1.14.0/go.mod h1:RcjvOAcvhzcufQP8aHmzRw1gE9g/VEZufDdo2w+s4sk= go.opentelemetry.io/otel/metric v0.30.0 h1:Hs8eQZ8aQgs0U49diZoaS6Uaxw3+bBE3lcMUKBFIk3c= go.opentelemetry.io/otel/metric v0.30.0/go.mod h1:/ShZ7+TS4dHzDFmfi1kSXMhMVubNoP0oIaBp70J6UXU= -go.opentelemetry.io/otel/sdk v1.7.0 h1:4OmStpcKVOfvDOgCt7UriAPtKolwIhxpnSNI/yK+1B0= -go.opentelemetry.io/otel/sdk v1.7.0/go.mod h1:uTEOTwaqIVuTGiJN7ii13Ibp75wJmYUDe374q6cZwUU= -go.opentelemetry.io/otel/trace v1.7.0 h1:O37Iogk1lEkMRXewVtZ1BBTVn5JEp8GrJvP92bJqC6o= +go.opentelemetry.io/otel/sdk v1.14.0 h1:PDCppFRDq8A1jL9v6KMI6dYesaq+DFcDZvjsoGvxGzY= +go.opentelemetry.io/otel/sdk v1.14.0/go.mod h1:bwIC5TjrNG6QDCHNWvW4HLHtUQ4I+VQDsnjhvyZCALM= go.opentelemetry.io/otel/trace v1.7.0/go.mod h1:fzLSB9nqR2eXzxPXb2JW9IKE+ScyXA48yyE4TNvoHqU= +go.opentelemetry.io/otel/trace v1.14.0 h1:wp2Mmvj41tDsyAJXiWDWpfNsOiIyd38fy85pyKcFq/M= +go.opentelemetry.io/otel/trace v1.14.0/go.mod h1:8avnQLK+CG77yNLUae4ea2JDQ6iT+gozhnZjy/rw9G8= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= -go.opentelemetry.io/proto/otlp v0.16.0 h1:WHzDWdXUvbc5bG2ObdrGfaNpQz7ft7QN9HHmJlbiB1E= -go.opentelemetry.io/proto/otlp v0.16.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= -go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.opentelemetry.io/proto/otlp v0.19.0 h1:IVN6GR+mhC4s5yfcTbmzHYODqvWAp3ZedA2SJPI1Nnw= +go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= @@ -1441,21 +950,16 @@ go.uber.org/dig v1.15.0 h1:vq3YWr8zRj1eFGC7Gvf907hE0eRjPTZ1d3xHadD6liE= go.uber.org/dig v1.15.0/go.mod h1:pKHs0wMynzL6brANhB2hLMro+zalv1osARTviTcqHLM= go.uber.org/fx v1.18.2 h1:bUNI6oShr+OVFQeU8cDNbnN7VFsu+SsjHzUF51V/GAU= go.uber.org/fx v1.18.2/go.mod h1:g0V1KMQ66zIRk8bLu3Ea5Jt2w/cHlOIp4wdRsgh0JaY= -go.uber.org/goleak v1.0.0/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.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA= -go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= +go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= -go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.14.1/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= -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.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= @@ -1466,35 +970,21 @@ go4.org v0.0.0-20200411211856-f5505b9728dd/go.mod h1:CIiUVy99QCPfoE13bO4EZaz5GZM golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190618222545-ea8f1a30c443/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200602180216-279210d13fed/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20210506145944-38f3c27a63bf/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= -golang.org/x/crypto v0.0.0-20210920023735-84f357641f63/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE= -golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= +golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc= +golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1505,8 +995,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20230129154200-a960b3787bd2 h1:5sPMf9HJXrvBWIamTw+rTST0bZ3Mho2n1p58M0+W99c= -golang.org/x/exp v0.0.0-20230129154200-a960b3787bd2/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= +golang.org/x/exp v0.0.0-20230213192124-5e25df0256eb h1:PaBZQdo+iSDyHT053FjUCgZQ/9uqVwPOcl7KSWhKn6w= +golang.org/x/exp v0.0.0-20230213192124-5e25df0256eb/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1531,19 +1021,15 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA= golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -1551,15 +1037,11 @@ golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190611141213-3f473d35a33a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -1580,13 +1062,10 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210423184538-5f58ad60dda6/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210917221730-978cfadd31cf/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= @@ -1601,8 +1080,9 @@ golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4Iltr golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b h1:clP8eMhB30EHdc0bd2Twtq6kgU7yl5ub2cQLSdrv1Dg= golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.4.0 h1:NF0gk8LVPg1Ml7SSbGyySuoxdsXitj7TvgvuRxIMc/M= +golang.org/x/oauth2 v0.4.0/go.mod h1:RznEsdpjGAINPTOF0UH/t+xJ75L18YO3Ho6Pyn+uRec= golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1618,21 +1098,16 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= golang.org/x/sync v0.1.0/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= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190302025703-b6889370fb10/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190405154228-4b34438f7a67/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1640,23 +1115,17 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190524122548-abf6ff778158/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190526052359-791d8a0f4d09/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190610200419-93c9922d18ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191210023423-ac6580df4449/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1681,16 +1150,11 @@ golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210317225723-c4fcb01b228e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210426080607-c94f62235c83/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1702,8 +1166,8 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -1746,16 +1210,13 @@ golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= @@ -1775,7 +1236,6 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= @@ -1791,7 +1251,6 @@ golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNq google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y= -google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= @@ -1815,8 +1274,9 @@ google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7 google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= @@ -1826,7 +1286,6 @@ google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRn google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= @@ -1852,37 +1311,31 @@ google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7Fc google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1 h1:b9mVrqYfq3P4bCdaLg1qtBnPzUYgglsIdjZkL/fQVOE= google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f h1:BWUVssLB0HVOSY78gIdvk1dTVYtT1y8SBWtPYuTJ/6w= +google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= -google.golang.org/grpc v1.28.1/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= -google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k= google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc v1.46.0 h1:oCjezcn6g6A75TGoKYBPgKmVBLexhYLM6MebdrPApP8= -google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.53.0 h1:LAv2ds7cmFV/XTS3XG1NneeENYrXGmorPxsBbptIjNc= +google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -1896,7 +1349,6 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= @@ -1905,20 +1357,15 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/square/go-jose.v2 v2.5.1 h1:7odma5RETjNHWJnR32wx8t+Io4djHE1PqxCFx3iiZ2w= gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/src-d/go-cli.v0 v0.0.0-20181105080154-d492247bbc0d/go.mod h1:z+K8VcOYVYcSwSjGebuDL6176A1XskgbtNl64NSg+n8= gopkg.in/src-d/go-log.v1 v1.0.1/go.mod h1:GN34hKP0g305ysm2/hctJ0Y8nWP3zxXXJ8GFabTyABE= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= -gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -1951,7 +1398,5 @@ pgregory.net/rapid v0.4.7/go.mod h1:UYpPVyjFHzYBGHIxLFoupi8vwk6rXNzRY9OMvVxFIOU= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= -sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck= sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0= diff --git a/plugin/daemon.go b/plugin/daemon.go index 04b18b33b..6ea58a921 100644 --- a/plugin/daemon.go +++ b/plugin/daemon.go @@ -1,7 +1,7 @@ package plugin import ( - coreiface "github.com/ipfs/interface-go-ipfs-core" + coreiface "github.com/ipfs/boxo/coreiface" ) // PluginDaemon is an interface for daemon plugins. These plugins will be run on diff --git a/repo/fsrepo/fsrepo.go b/repo/fsrepo/fsrepo.go index 6a7da9a06..cb8de08c1 100644 --- a/repo/fsrepo/fsrepo.go +++ b/repo/fsrepo/fsrepo.go @@ -11,17 +11,17 @@ import ( "strings" "sync" - filestore "github.com/ipfs/go-filestore" - keystore "github.com/ipfs/go-ipfs-keystore" + filestore "github.com/ipfs/boxo/filestore" + keystore "github.com/ipfs/boxo/keystore" repo "github.com/ipfs/kubo/repo" "github.com/ipfs/kubo/repo/common" dir "github.com/ipfs/kubo/thirdparty/dir" rcmgr "github.com/libp2p/go-libp2p/p2p/host/resource-manager" + util "github.com/ipfs/boxo/util" ds "github.com/ipfs/go-datastore" measure "github.com/ipfs/go-ds-measure" lockfile "github.com/ipfs/go-fs-lock" - util "github.com/ipfs/go-ipfs-util" logging "github.com/ipfs/go-log" config "github.com/ipfs/kubo/config" serialize "github.com/ipfs/kubo/config/serialize" diff --git a/repo/fsrepo/migrations/ipfsfetcher/ipfsfetcher.go b/repo/fsrepo/migrations/ipfsfetcher/ipfsfetcher.go index 52cd354d3..977b31656 100644 --- a/repo/fsrepo/migrations/ipfsfetcher/ipfsfetcher.go +++ b/repo/fsrepo/migrations/ipfsfetcher/ipfsfetcher.go @@ -11,10 +11,10 @@ import ( "strings" "sync" - "github.com/ipfs/go-libipfs/files" - iface "github.com/ipfs/interface-go-ipfs-core" - "github.com/ipfs/interface-go-ipfs-core/options" - ipath "github.com/ipfs/interface-go-ipfs-core/path" + iface "github.com/ipfs/boxo/coreiface" + "github.com/ipfs/boxo/coreiface/options" + ipath "github.com/ipfs/boxo/coreiface/path" + "github.com/ipfs/boxo/files" "github.com/ipfs/kubo/config" "github.com/ipfs/kubo/core" "github.com/ipfs/kubo/core/coreapi" diff --git a/repo/mock.go b/repo/mock.go index 6f128d263..ae4d98d3b 100644 --- a/repo/mock.go +++ b/repo/mock.go @@ -5,8 +5,8 @@ import ( "errors" "net" - filestore "github.com/ipfs/go-filestore" - keystore "github.com/ipfs/go-ipfs-keystore" + filestore "github.com/ipfs/boxo/filestore" + keystore "github.com/ipfs/boxo/keystore" rcmgr "github.com/libp2p/go-libp2p/p2p/host/resource-manager" config "github.com/ipfs/kubo/config" diff --git a/repo/repo.go b/repo/repo.go index 6767dda72..05e938825 100644 --- a/repo/repo.go +++ b/repo/repo.go @@ -6,8 +6,8 @@ import ( "io" "net" - filestore "github.com/ipfs/go-filestore" - keystore "github.com/ipfs/go-ipfs-keystore" + filestore "github.com/ipfs/boxo/filestore" + keystore "github.com/ipfs/boxo/keystore" rcmgr "github.com/libp2p/go-libp2p/p2p/host/resource-manager" ds "github.com/ipfs/go-datastore" diff --git a/routing/delegated.go b/routing/delegated.go index a32c5c091..90a9c0807 100644 --- a/routing/delegated.go +++ b/routing/delegated.go @@ -7,11 +7,11 @@ import ( "fmt" "net/http" + drclient "github.com/ipfs/boxo/routing/http/client" + "github.com/ipfs/boxo/routing/http/contentrouter" "github.com/ipfs/go-datastore" drc "github.com/ipfs/go-delegated-routing/client" drp "github.com/ipfs/go-delegated-routing/gen/proto" - drclient "github.com/ipfs/go-libipfs/routing/http/client" - "github.com/ipfs/go-libipfs/routing/http/contentrouter" logging "github.com/ipfs/go-log" version "github.com/ipfs/kubo" "github.com/ipfs/kubo/config" diff --git a/tar/format.go b/tar/format.go index 2bbf7298f..f3a2d3fb5 100644 --- a/tar/format.go +++ b/tar/format.go @@ -8,13 +8,13 @@ import ( "io" "strings" - dag "github.com/ipfs/go-merkledag" - "github.com/ipfs/go-merkledag/dagutils" - path "github.com/ipfs/go-path" - importer "github.com/ipfs/go-unixfs/importer" - uio "github.com/ipfs/go-unixfs/io" + dag "github.com/ipfs/boxo/ipld/merkledag" + "github.com/ipfs/boxo/ipld/merkledag/dagutils" + importer "github.com/ipfs/boxo/ipld/unixfs/importer" + uio "github.com/ipfs/boxo/ipld/unixfs/io" + path "github.com/ipfs/boxo/path" - chunker "github.com/ipfs/go-ipfs-chunker" + chunker "github.com/ipfs/boxo/chunker" ipld "github.com/ipfs/go-ipld-format" logging "github.com/ipfs/go-log" ) diff --git a/test/integration/addcat_test.go b/test/integration/addcat_test.go index 6f306d2bf..2974f51fb 100644 --- a/test/integration/addcat_test.go +++ b/test/integration/addcat_test.go @@ -11,7 +11,7 @@ import ( "testing" "time" - "github.com/ipfs/go-libipfs/files" + "github.com/ipfs/boxo/files" logging "github.com/ipfs/go-log" "github.com/ipfs/kubo/core" "github.com/ipfs/kubo/core/bootstrap" diff --git a/test/integration/bench_cat_test.go b/test/integration/bench_cat_test.go index 12c4d8dea..e95ff87df 100644 --- a/test/integration/bench_cat_test.go +++ b/test/integration/bench_cat_test.go @@ -8,7 +8,7 @@ import ( "math" "testing" - "github.com/ipfs/go-libipfs/files" + "github.com/ipfs/boxo/files" "github.com/ipfs/kubo/core" "github.com/ipfs/kubo/core/bootstrap" "github.com/ipfs/kubo/core/coreapi" diff --git a/test/integration/bitswap_wo_routing_test.go b/test/integration/bitswap_wo_routing_test.go index 6a6fca4b7..fa4e8d513 100644 --- a/test/integration/bitswap_wo_routing_test.go +++ b/test/integration/bitswap_wo_routing_test.go @@ -5,8 +5,8 @@ import ( "context" "testing" + blocks "github.com/ipfs/go-block-format" "github.com/ipfs/go-cid" - blocks "github.com/ipfs/go-libipfs/blocks" "github.com/ipfs/kubo/core" coremock "github.com/ipfs/kubo/core/mock" "github.com/ipfs/kubo/core/node/libp2p" diff --git a/test/integration/three_legged_cat_test.go b/test/integration/three_legged_cat_test.go index c788bfb5e..e8a838e1f 100644 --- a/test/integration/three_legged_cat_test.go +++ b/test/integration/three_legged_cat_test.go @@ -14,7 +14,7 @@ import ( mock "github.com/ipfs/kubo/core/mock" "github.com/ipfs/kubo/thirdparty/unit" - "github.com/ipfs/go-libipfs/files" + "github.com/ipfs/boxo/files" testutil "github.com/libp2p/go-libp2p-testing/net" "github.com/libp2p/go-libp2p/core/peer" mocknet "github.com/libp2p/go-libp2p/p2p/net/mock" diff --git a/thirdparty/verifbs/verifbs.go b/thirdparty/verifbs/verifbs.go index ca2f5d839..929e8cde9 100644 --- a/thirdparty/verifbs/verifbs.go +++ b/thirdparty/verifbs/verifbs.go @@ -3,10 +3,10 @@ package verifbs import ( "context" + bstore "github.com/ipfs/boxo/blockstore" + "github.com/ipfs/boxo/verifcid" + blocks "github.com/ipfs/go-block-format" cid "github.com/ipfs/go-cid" - bstore "github.com/ipfs/go-ipfs-blockstore" - blocks "github.com/ipfs/go-libipfs/blocks" - "github.com/ipfs/go-verifcid" ) type VerifBSGC struct { From 6ebbd9d39bdd14fdd229322c7803543d01269422 Mon Sep 17 00:00:00 2001 From: Gus Eggert Date: Wed, 29 Mar 2023 11:56:11 -0400 Subject: [PATCH 0592/1212] test: skip flaky pubsub test (#9770) This test flakes very often and we plan on removing this feature entirely, so disabling this test since its failures are pretty disruptive. --- test/integration/pubsub_msg_seen_cache_test.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/test/integration/pubsub_msg_seen_cache_test.go b/test/integration/pubsub_msg_seen_cache_test.go index 749508089..4194881a5 100644 --- a/test/integration/pubsub_msg_seen_cache_test.go +++ b/test/integration/pubsub_msg_seen_cache_test.go @@ -20,16 +20,17 @@ import ( "github.com/ipfs/go-datastore" syncds "github.com/ipfs/go-datastore/sync" - "github.com/libp2p/go-libp2p-pubsub" - "github.com/libp2p/go-libp2p-pubsub/pb" + pubsub "github.com/libp2p/go-libp2p-pubsub" + pubsub_pb "github.com/libp2p/go-libp2p-pubsub/pb" "github.com/libp2p/go-libp2p-pubsub/timecache" "github.com/libp2p/go-libp2p/core/peer" mock "github.com/ipfs/kubo/core/mock" - "github.com/libp2p/go-libp2p/p2p/net/mock" + mocknet "github.com/libp2p/go-libp2p/p2p/net/mock" ) func TestMessageSeenCacheTTL(t *testing.T) { + t.Skip("skipping PubSub seen cache TTL test due to flakiness") if err := RunMessageSeenCacheTTLTest(t, "10s"); err != nil { t.Fatal(err) } From f4d361dd4e88fd799b83ecb2a8e0977f92f44524 Mon Sep 17 00:00:00 2001 From: Gus Eggert Date: Wed, 29 Mar 2023 11:56:25 -0400 Subject: [PATCH 0593/1212] test: fix autoclient flakiness (#9769) The test trims all whitespace bytes from the output of 'ipfs cat' but if the random bytes end in a whitespace char then it trims that too, resulting in random test failure. Instead this updates the test harness to only trim a single trailing newline char, so that it doesn't end up chomping legitimate output. --- test/cli/dht_autoclient_test.go | 1 + test/cli/harness/buffer.go | 12 ++++++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/test/cli/dht_autoclient_test.go b/test/cli/dht_autoclient_test.go index 749e34b34..39aa5b258 100644 --- a/test/cli/dht_autoclient_test.go +++ b/test/cli/dht_autoclient_test.go @@ -20,6 +20,7 @@ func TestDHTAutoclient(t *testing.T) { t.Run("file added on node in client mode is retrievable from node in client mode", func(t *testing.T) { t.Parallel() randomBytes := testutils.RandomBytes(1000) + randomBytes = append(randomBytes, '\r') hash := nodes[8].IPFSAdd(bytes.NewReader(randomBytes)) res := nodes[9].IPFS("cat", hash) diff --git a/test/cli/harness/buffer.go b/test/cli/harness/buffer.go index b40e160b0..ba1cddf02 100644 --- a/test/cli/harness/buffer.go +++ b/test/cli/harness/buffer.go @@ -25,11 +25,19 @@ func (b *Buffer) String() string { return b.b.String() } -// Trimmed returns the bytes as a string, with leading and trailing whitespace removed. +// Trimmed returns the bytes as a string, but with the trailing newline removed. +// This only removes a single trailing newline, not all whitespace. func (b *Buffer) Trimmed() string { b.m.Lock() defer b.m.Unlock() - return strings.TrimSpace(b.b.String()) + s := b.b.String() + if len(s) == 0 { + return s + } + if s[len(s)-1] == '\n' { + return s[:len(s)-1] + } + return s } func (b *Buffer) Bytes() []byte { From 9fb09dd398c21b36a33a743433a550ecf6442c54 Mon Sep 17 00:00:00 2001 From: Gus Eggert Date: Wed, 29 Mar 2023 19:28:55 -0400 Subject: [PATCH 0594/1212] test: port routing DHT tests to Go (#9709) --- test/cli/dht_legacy_test.go | 1 + test/cli/harness/nodes.go | 4 +- test/cli/routing_dht_test.go | 123 +++++++++++++++++++++++++++ test/sharness/t0170-routing-dht.sh | 128 ----------------------------- 4 files changed, 126 insertions(+), 130 deletions(-) create mode 100644 test/cli/routing_dht_test.go delete mode 100755 test/sharness/t0170-routing-dht.sh diff --git a/test/cli/dht_legacy_test.go b/test/cli/dht_legacy_test.go index 437b62ae4..5a84b8963 100644 --- a/test/cli/dht_legacy_test.go +++ b/test/cli/dht_legacy_test.go @@ -13,6 +13,7 @@ import ( ) func TestLegacyDHT(t *testing.T) { + t.Parallel() nodes := harness.NewT(t).NewNodes(5).Init() nodes.ForEachPar(func(node *harness.Node) { node.IPFS("config", "Routing.Type", "dht") diff --git a/test/cli/harness/nodes.go b/test/cli/harness/nodes.go index 78662afbb..113289e3c 100644 --- a/test/cli/harness/nodes.go +++ b/test/cli/harness/nodes.go @@ -57,8 +57,8 @@ func (n Nodes) Connect() Nodes { return n } -func (n Nodes) StartDaemons() Nodes { - ForEachPar(n, func(node *Node) { node.StartDaemon() }) +func (n Nodes) StartDaemons(args ...string) Nodes { + ForEachPar(n, func(node *Node) { node.StartDaemon(args...) }) return n } diff --git a/test/cli/routing_dht_test.go b/test/cli/routing_dht_test.go new file mode 100644 index 000000000..7dc0ddfcb --- /dev/null +++ b/test/cli/routing_dht_test.go @@ -0,0 +1,123 @@ +package cli + +import ( + "fmt" + "testing" + + "github.com/ipfs/kubo/test/cli/harness" + "github.com/ipfs/kubo/test/cli/testutils" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func testRoutingDHT(t *testing.T, enablePubsub bool) { + t.Run(fmt.Sprintf("enablePubSub=%v", enablePubsub), func(t *testing.T) { + t.Parallel() + nodes := harness.NewT(t).NewNodes(5).Init() + nodes.ForEachPar(func(node *harness.Node) { + node.IPFS("config", "Routing.Type", "dht") + }) + + var daemonArgs []string + if enablePubsub { + daemonArgs = []string{ + "--enable-pubsub-experiment", + "--enable-namesys-pubsub", + } + } + + nodes.StartDaemons(daemonArgs...).Connect() + + t.Run("ipfs routing findpeer", func(t *testing.T) { + t.Parallel() + res := nodes[1].RunIPFS("routing", "findpeer", nodes[0].PeerID().String()) + assert.Equal(t, 0, res.ExitCode()) + + swarmAddr := nodes[0].SwarmAddrsWithoutPeerIDs()[0] + require.Equal(t, swarmAddr.String(), res.Stdout.Trimmed()) + }) + + t.Run("ipfs routing get ", func(t *testing.T) { + t.Parallel() + hash := nodes[2].IPFSAddStr("hello world") + nodes[2].IPFS("name", "publish", "/ipfs/"+hash) + + res := nodes[1].IPFS("routing", "get", "/ipns/"+nodes[2].PeerID().String()) + assert.Contains(t, res.Stdout.String(), "/ipfs/"+hash) + + t.Run("put round trips (#3124)", func(t *testing.T) { + t.Parallel() + nodes[0].WriteBytes("get_result", res.Stdout.Bytes()) + res := nodes[0].IPFS("routing", "put", "/ipns/"+nodes[2].PeerID().String(), "get_result") + assert.Greater(t, len(res.Stdout.Lines()), 0, "should put to at least one node") + }) + + t.Run("put with bad keys fails (issue #5113, #4611)", func(t *testing.T) { + t.Parallel() + keys := []string{"foo", "/pk/foo", "/ipns/foo"} + for _, key := range keys { + key := key + t.Run(key, func(t *testing.T) { + t.Parallel() + res := nodes[0].RunIPFS("routing", "put", key) + assert.Equal(t, 1, res.ExitCode()) + assert.Contains(t, res.Stderr.String(), "invalid") + assert.Empty(t, res.Stdout.String()) + }) + } + }) + + t.Run("get with bad keys (issue #4611)", func(t *testing.T) { + for _, key := range []string{"foo", "/pk/foo"} { + key := key + t.Run(key, func(t *testing.T) { + t.Parallel() + res := nodes[0].RunIPFS("routing", "get", key) + assert.Equal(t, 1, res.ExitCode()) + assert.Contains(t, res.Stderr.String(), "invalid") + assert.Empty(t, res.Stdout.String()) + }) + } + }) + }) + + t.Run("ipfs routing findprovs", func(t *testing.T) { + t.Parallel() + hash := nodes[3].IPFSAddStr("some stuff") + res := nodes[4].IPFS("routing", "findprovs", hash) + assert.Equal(t, nodes[3].PeerID().String(), res.Stdout.Trimmed()) + }) + + t.Run("routing commands fail when offline", func(t *testing.T) { + t.Parallel() + node := harness.NewT(t).NewNode().Init() + + // these cannot be run in parallel due to repo locking + // this seems like a bug, we should be able to run these without locking the repo + + t.Run("routing findprovs", func(t *testing.T) { + res := node.RunIPFS("routing", "findprovs", testutils.CIDEmptyDir) + assert.Equal(t, 1, res.ExitCode()) + assert.Contains(t, res.Stderr.String(), "this command must be run in online mode") + }) + + t.Run("routing findpeer", func(t *testing.T) { + res := node.RunIPFS("routing", "findpeer", testutils.CIDEmptyDir) + assert.Equal(t, 1, res.ExitCode()) + assert.Contains(t, res.Stderr.String(), "this command must be run in online mode") + }) + + t.Run("routing put", func(t *testing.T) { + node.WriteBytes("foo", []byte("foo")) + res := node.RunIPFS("routing", "put", "/ipns/"+node.PeerID().String(), "foo") + assert.Equal(t, 1, res.ExitCode()) + assert.Contains(t, res.Stderr.String(), "this action must be run in online mode") + }) + }) + }) +} + +func TestRoutingDHT(t *testing.T) { + testRoutingDHT(t, false) + testRoutingDHT(t, true) +} diff --git a/test/sharness/t0170-routing-dht.sh b/test/sharness/t0170-routing-dht.sh deleted file mode 100755 index e6e9940f2..000000000 --- a/test/sharness/t0170-routing-dht.sh +++ /dev/null @@ -1,128 +0,0 @@ -#!/usr/bin/env bash - -# This file does the same tests as t0170-dht.sh but uses 'routing' commands instead -# (only exception is query, which lives only under dht) -test_description="Test routing command for DHT queries" - -. lib/test-lib.sh - -test_dht() { - NUM_NODES=5 - - test_expect_success 'init iptb' ' - rm -rf .iptb/ && - iptb testbed create -type localipfs -count $NUM_NODES -init - ' - - test_expect_success 'DHT-only routing' ' - iptb run -- ipfs config Routing.Type dht - ' - - startup_cluster $NUM_NODES $@ - - test_expect_success 'peer ids' ' - PEERID_0=$(iptb attr get 0 id) && - PEERID_2=$(iptb attr get 2 id) - ' - - # ipfs routing findpeer - test_expect_success 'findpeer' ' - ipfsi 1 routing findpeer $PEERID_0 | sort >actual && - ipfsi 0 id -f "" | cut -d / -f 1-5 | sort >expected && - test_cmp actual expected - ' - - # ipfs routing get - test_expect_success 'get with good keys works' ' - HASH="$(echo "hello world" | ipfsi 2 add -q)" && - ipfsi 2 name publish "/ipfs/$HASH" && - ipfsi 1 routing get "/ipns/$PEERID_2" >get_result - ' - - test_expect_success 'get with good keys contains the right value' ' - cat get_result | grep -aq "/ipfs/$HASH" - ' - - test_expect_success 'put round trips (#3124)' ' - ipfsi 0 routing put "/ipns/$PEERID_2" get_result | sort >putted && - [ -s putted ] || - test_fsh cat putted - ' - - test_expect_success 'put with bad keys fails (issue #5113)' ' - ipfsi 0 routing put "foo" <<putted - ipfsi 0 routing put "/pk/foo" <<>putted - ipfsi 0 routing put "/ipns/foo" <<>putted - [ ! -s putted ] || - test_fsh cat putted - ' - - test_expect_success 'put with bad keys returns error (issue #4611)' ' - test_must_fail ipfsi 0 routing put "foo" << afile && - HASH=$(ipfsi 3 add -q afile) - ' - - # ipfs routing findprovs - test_expect_success 'findprovs' ' - ipfsi 4 routing findprovs $HASH > provs && - iptb attr get 3 id > expected && - test_cmp provs expected - ' - - # ipfs routing get --enc=json has correct properties - test_expect_success 'routing get --enc=json has correct properties' ' - HASH="$(echo "hello world" | ipfsi 2 add -q)" && - ipfsi 2 name publish "/ipfs/$HASH" && - ipfsi 1 routing get --enc=json "/ipns/$PEERID_2" | jq -e "has(\"Extra\") and has(\"Type\")" - ' - - # ipfs dht query - # - # We test all nodes. 4 nodes should see the same peer ID, one node (the - # closest) should see a different one. - - for i in $(test_seq 0 4); do - test_expect_success "dht query from $i" ' - ipfsi "$i" dht query "$HASH" | head -1 >closest-$i - ' - done - - test_expect_success "collecting results" ' - cat closest-* | sort | uniq -c | sed -e "s/ *\([0-9]\+\) .*/\1/g" | sort -g > actual && - echo 1 > expected && - echo 4 >> expected - ' - - test_expect_success "checking results" ' - test_cmp actual expected - ' - - test_expect_success 'stop iptb' ' - iptb stop - ' - - test_expect_success "dht commands fail when offline" ' - test_must_fail ipfsi 0 routing findprovs "$HASH" 2>err_findprovs && - test_must_fail ipfsi 0 routing findpeer "$HASH" 2>err_findpeer && - test_must_fail ipfsi 0 routing put "/ipns/$PEERID_2" "get_result" 2>err_put && - test_should_contain "this command must be run in online mode" err_findprovs && - test_should_contain "this command must be run in online mode" err_findpeer && - test_should_contain "this action must be run in online mode" err_put - ' -} - -test_dht -test_dht --enable-pubsub-experiment --enable-namesys-pubsub - -test_done From e89cce63fd1428c40031edb30b407cbb468abb08 Mon Sep 17 00:00:00 2001 From: Arthur Gavazza <32915690+arthurgavazza@users.noreply.github.com> Date: Thu, 30 Mar 2023 01:34:57 -0300 Subject: [PATCH 0595/1212] feat: add identify option to swarm peers command Fixes #9578 --- core/commands/swarm.go | 71 ++++++++++++++++++++++++--- test/cli/harness/peering.go | 37 ++++++++++++++ test/cli/peering_test.go | 55 +++++---------------- test/cli/swarm_test.go | 97 +++++++++++++++++++++++++++++++++++++ 4 files changed, 210 insertions(+), 50 deletions(-) create mode 100644 test/cli/harness/peering.go create mode 100644 test/cli/swarm_test.go diff --git a/core/commands/swarm.go b/core/commands/swarm.go index 7d5ae96af..c9259bef0 100644 --- a/core/commands/swarm.go +++ b/core/commands/swarm.go @@ -2,6 +2,7 @@ package commands import ( "context" + "encoding/base64" "encoding/json" "errors" "fmt" @@ -21,8 +22,10 @@ import ( "github.com/ipfs/kubo/repo/fsrepo" cmds "github.com/ipfs/go-ipfs-cmds" + ic "github.com/libp2p/go-libp2p/core/crypto" inet "github.com/libp2p/go-libp2p/core/network" "github.com/libp2p/go-libp2p/core/peer" + pstore "github.com/libp2p/go-libp2p/core/peerstore" rcmgr "github.com/libp2p/go-libp2p/p2p/host/resource-manager" ma "github.com/multiformats/go-multiaddr" madns "github.com/multiformats/go-multiaddr-dns" @@ -69,6 +72,7 @@ const ( swarmDirectionOptionName = "direction" swarmResetLimitsOptionName = "reset" swarmUsedResourcesPercentageName = "min-used-limit-perc" + swarmIdentifyOptionName = "identify" ) type peeringResult struct { @@ -236,17 +240,18 @@ var swarmPeersCmd = &cmds.Command{ cmds.BoolOption(swarmStreamsOptionName, "Also list information about open streams for each peer"), cmds.BoolOption(swarmLatencyOptionName, "Also list information about latency to each peer"), cmds.BoolOption(swarmDirectionOptionName, "Also list information about the direction of connection"), + cmds.BoolOption(swarmIdentifyOptionName, "Also list information about peers identify"), }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { api, err := cmdenv.GetApi(env, req) if err != nil { return err } - verbose, _ := req.Options[swarmVerboseOptionName].(bool) latency, _ := req.Options[swarmLatencyOptionName].(bool) streams, _ := req.Options[swarmStreamsOptionName].(bool) direction, _ := req.Options[swarmDirectionOptionName].(bool) + identify, _ := req.Options[swarmIdentifyOptionName].(bool) conns, err := api.Swarm().Peers(req.Context) if err != nil { @@ -287,6 +292,15 @@ var swarmPeersCmd = &cmds.Command{ ci.Streams = append(ci.Streams, streamInfo{Protocol: string(s)}) } } + + if verbose || identify { + n, err := cmdenv.GetNode(env) + if err != nil { + return err + } + identifyResult, _ := ci.identifyPeer(n.Peerstore, c.ID()) + ci.Identify = identifyResult + } sort.Sort(&ci) out.Peers = append(out.Peers, ci) } @@ -411,12 +425,13 @@ type streamInfo struct { } type connInfo struct { - Addr string - Peer string - Latency string - Muxer string - Direction inet.Direction - Streams []streamInfo + Addr string `json:",omitempty"` + Peer string `json:",omitempty"` + Latency string `json:",omitempty"` + Muxer string `json:",omitempty"` + Direction inet.Direction `json:",omitempty"` + Streams []streamInfo `json:",omitempty"` + Identify IdOutput `json:",omitempty"` } func (ci *connInfo) Less(i, j int) bool { @@ -447,6 +462,48 @@ func (ci connInfos) Swap(i, j int) { ci.Peers[i], ci.Peers[j] = ci.Peers[j], ci.Peers[i] } +func (ci *connInfo) identifyPeer(ps pstore.Peerstore, p peer.ID) (IdOutput, error) { + var info IdOutput + info.ID = p.String() + + if pk := ps.PubKey(p); pk != nil { + pkb, err := ic.MarshalPublicKey(pk) + if err != nil { + return IdOutput{}, err + } + info.PublicKey = base64.StdEncoding.EncodeToString(pkb) + } + + addrInfo := ps.PeerInfo(p) + addrs, err := peer.AddrInfoToP2pAddrs(&addrInfo) + if err != nil { + return IdOutput{}, err + } + + for _, a := range addrs { + info.Addresses = append(info.Addresses, a.String()) + } + sort.Strings(info.Addresses) + + if protocols, err := ps.GetProtocols(p); err == nil { + info.Protocols = append(info.Protocols, protocols...) + sort.Slice(info.Protocols, func(i, j int) bool { return info.Protocols[i] < info.Protocols[j] }) + } + + if v, err := ps.Get(p, "ProtocolVersion"); err == nil { + if vs, ok := v.(string); ok { + info.ProtocolVersion = vs + } + } + if v, err := ps.Get(p, "AgentVersion"); err == nil { + if vs, ok := v.(string); ok { + info.AgentVersion = vs + } + } + + return info, nil +} + // directionString transfers to string func directionString(d inet.Direction) string { switch d { diff --git a/test/cli/harness/peering.go b/test/cli/harness/peering.go new file mode 100644 index 000000000..3fcd8bb6b --- /dev/null +++ b/test/cli/harness/peering.go @@ -0,0 +1,37 @@ +package harness + +import ( + "fmt" + "math/rand" + "testing" + + "github.com/ipfs/kubo/config" +) + +type Peering struct { + From int + To int +} + +func newRandPort() int { + n := rand.Int() + return 3000 + (n % 1000) +} + +func CreatePeerNodes(t *testing.T, n int, peerings []Peering) (*Harness, Nodes) { + h := NewT(t) + nodes := h.NewNodes(n).Init() + nodes.ForEachPar(func(node *Node) { + node.UpdateConfig(func(cfg *config.Config) { + cfg.Routing.Type = config.NewOptionalString("none") + cfg.Addresses.Swarm = []string{fmt.Sprintf("/ip4/127.0.0.1/tcp/%d", newRandPort())} + }) + + }) + + for _, peering := range peerings { + nodes[peering.From].PeerWith(nodes[peering.To]) + } + + return h, nodes +} diff --git a/test/cli/peering_test.go b/test/cli/peering_test.go index ade52ec3c..9c6ab975d 100644 --- a/test/cli/peering_test.go +++ b/test/cli/peering_test.go @@ -1,12 +1,9 @@ package cli import ( - "fmt" - "math/rand" "testing" "time" - "github.com/ipfs/kubo/config" "github.com/ipfs/kubo/test/cli/harness" . "github.com/ipfs/kubo/test/cli/testutils" "github.com/libp2p/go-libp2p/core/peer" @@ -16,16 +13,6 @@ import ( func TestPeering(t *testing.T) { t.Parallel() - type peering struct { - from int - to int - } - - newRandPort := func() int { - n := rand.Int() - return 3000 + (n % 1000) - } - containsPeerID := func(p peer.ID, peers []peer.ID) bool { for _, peerID := range peers { if p == peerID { @@ -63,34 +50,16 @@ func TestPeering(t *testing.T) { }, 20*time.Second, 10*time.Millisecond, "%d -> %d peered", from.ID, to.ID) } - assertPeerings := func(h *harness.Harness, nodes []*harness.Node, peerings []peering) { - ForEachPar(peerings, func(peering peering) { - assertPeered(h, nodes[peering.from], nodes[peering.to]) + assertPeerings := func(h *harness.Harness, nodes []*harness.Node, peerings []harness.Peering) { + ForEachPar(peerings, func(peering harness.Peering) { + assertPeered(h, nodes[peering.From], nodes[peering.To]) }) } - createNodes := func(t *testing.T, n int, peerings []peering) (*harness.Harness, harness.Nodes) { - h := harness.NewT(t) - nodes := h.NewNodes(n).Init() - nodes.ForEachPar(func(node *harness.Node) { - node.UpdateConfig(func(cfg *config.Config) { - cfg.Routing.Type = config.NewOptionalString("none") - cfg.Addresses.Swarm = []string{fmt.Sprintf("/ip4/127.0.0.1/tcp/%d", newRandPort())} - }) - - }) - - for _, peering := range peerings { - nodes[peering.from].PeerWith(nodes[peering.to]) - } - - return h, nodes - } - t.Run("bidirectional peering should work (simultaneous connect)", func(t *testing.T) { t.Parallel() - peerings := []peering{{from: 0, to: 1}, {from: 1, to: 0}, {from: 1, to: 2}} - h, nodes := createNodes(t, 3, peerings) + peerings := []harness.Peering{{From: 0, To: 1}, {From: 1, To: 0}, {From: 1, To: 2}} + h, nodes := harness.CreatePeerNodes(t, 3, peerings) nodes.StartDaemons() assertPeerings(h, nodes, peerings) @@ -101,8 +70,8 @@ func TestPeering(t *testing.T) { t.Run("1 should reconnect to 2 when 2 disconnects from 1", func(t *testing.T) { t.Parallel() - peerings := []peering{{from: 0, to: 1}, {from: 1, to: 0}, {from: 1, to: 2}} - h, nodes := createNodes(t, 3, peerings) + peerings := []harness.Peering{{From: 0, To: 1}, {From: 1, To: 0}, {From: 1, To: 2}} + h, nodes := harness.CreatePeerNodes(t, 3, peerings) nodes.StartDaemons() assertPeerings(h, nodes, peerings) @@ -113,12 +82,12 @@ func TestPeering(t *testing.T) { t.Run("1 will peer with 2 when it comes online", func(t *testing.T) { t.Parallel() - peerings := []peering{{from: 0, to: 1}, {from: 1, to: 0}, {from: 1, to: 2}} - h, nodes := createNodes(t, 3, peerings) + peerings := []harness.Peering{{From: 0, To: 1}, {From: 1, To: 0}, {From: 1, To: 2}} + h, nodes := harness.CreatePeerNodes(t, 3, peerings) nodes[0].StartDaemon() nodes[1].StartDaemon() - assertPeerings(h, nodes, []peering{{from: 0, to: 1}, {from: 1, to: 0}}) + assertPeerings(h, nodes, []harness.Peering{{From: 0, To: 1}, {From: 1, To: 0}}) nodes[2].StartDaemon() assertPeerings(h, nodes, peerings) @@ -126,8 +95,8 @@ func TestPeering(t *testing.T) { t.Run("1 will re-peer with 2 when it disconnects and then comes back online", func(t *testing.T) { t.Parallel() - peerings := []peering{{from: 0, to: 1}, {from: 1, to: 0}, {from: 1, to: 2}} - h, nodes := createNodes(t, 3, peerings) + peerings := []harness.Peering{{From: 0, To: 1}, {From: 1, To: 0}, {From: 1, To: 2}} + h, nodes := harness.CreatePeerNodes(t, 3, peerings) nodes.StartDaemons() assertPeerings(h, nodes, peerings) diff --git a/test/cli/swarm_test.go b/test/cli/swarm_test.go new file mode 100644 index 000000000..d32208106 --- /dev/null +++ b/test/cli/swarm_test.go @@ -0,0 +1,97 @@ +package cli + +import ( + "encoding/json" + "fmt" + "testing" + + "github.com/ipfs/kubo/test/cli/harness" + + "github.com/stretchr/testify/assert" +) + +// TODO: Migrate the rest of the sharness swarm test. +func TestSwarm(t *testing.T) { + type identifyType struct { + ID string + PublicKey string + Addresses []string + AgentVersion string + ProtocolVersion string + Protocols []string + } + type peer struct { + Identify identifyType + } + type expectedOutputType struct { + Peers []peer + } + + t.Parallel() + + t.Run("ipfs swarm peers returns empty peers when a node is not connected to any peers", func(t *testing.T) { + t.Parallel() + node := harness.NewT(t).NewNode().Init().StartDaemon() + res := node.RunIPFS("swarm", "peers", "--enc=json", "--identify") + var output expectedOutputType + err := json.Unmarshal(res.Stdout.Bytes(), &output) + assert.Nil(t, err) + assert.Equal(t, 0, len(output.Peers)) + + }) + t.Run("ipfs swarm peers with flag identify outputs expected identify information about connected peers", func(t *testing.T) { + t.Parallel() + node := harness.NewT(t).NewNode().Init().StartDaemon() + otherNode := harness.NewT(t).NewNode().Init().StartDaemon() + node.Connect(otherNode) + + res := node.RunIPFS("swarm", "peers", "--enc=json", "--identify") + var output expectedOutputType + err := json.Unmarshal(res.Stdout.Bytes(), &output) + assert.Nil(t, err) + actualID := output.Peers[0].Identify.ID + actualPublicKey := output.Peers[0].Identify.PublicKey + actualAgentVersion := output.Peers[0].Identify.AgentVersion + actualAdresses := output.Peers[0].Identify.Addresses + actualProtocolVersion := output.Peers[0].Identify.ProtocolVersion + actualProtocols := output.Peers[0].Identify.Protocols + + expectedID := otherNode.PeerID().String() + expectedAddresses := []string{fmt.Sprintf("%s/p2p/%s", otherNode.SwarmAddrs()[0], actualID)} + + assert.Equal(t, actualID, expectedID) + assert.NotNil(t, actualPublicKey) + assert.NotNil(t, actualAgentVersion) + assert.NotNil(t, actualProtocolVersion) + assert.Len(t, actualAdresses, 1) + assert.Equal(t, expectedAddresses[0], actualAdresses[0]) + assert.Greater(t, len(actualProtocols), 0) + + }) + + t.Run("ipfs swarm peers with flag identify outputs Identify field with data that matches calling ipfs id on a peer", func(t *testing.T) { + t.Parallel() + node := harness.NewT(t).NewNode().Init().StartDaemon() + otherNode := harness.NewT(t).NewNode().Init().StartDaemon() + node.Connect(otherNode) + + otherNodeIDResponse := otherNode.RunIPFS("id", "--enc=json") + var otherNodeIDOutput identifyType + err := json.Unmarshal(otherNodeIDResponse.Stdout.Bytes(), &otherNodeIDOutput) + assert.Nil(t, err) + res := node.RunIPFS("swarm", "peers", "--enc=json", "--identify") + + var output expectedOutputType + err = json.Unmarshal(res.Stdout.Bytes(), &output) + assert.Nil(t, err) + outputIdentify := output.Peers[0].Identify + + assert.Equal(t, outputIdentify.ID, otherNodeIDOutput.ID) + assert.Equal(t, outputIdentify.PublicKey, otherNodeIDOutput.PublicKey) + assert.Equal(t, outputIdentify.AgentVersion, otherNodeIDOutput.AgentVersion) + assert.Equal(t, outputIdentify.ProtocolVersion, otherNodeIDOutput.ProtocolVersion) + assert.ElementsMatch(t, outputIdentify.Addresses, otherNodeIDOutput.Addresses) + assert.ElementsMatch(t, outputIdentify.Protocols, otherNodeIDOutput.Protocols) + + }) +} From a24cfb89a509aa3a8dd95be363f2cbb2d4c8e692 Mon Sep 17 00:00:00 2001 From: Gus Eggert Date: Thu, 30 Mar 2023 07:46:35 -0400 Subject: [PATCH 0596/1212] test: port remote pinning tests to Go (#9720) This also means that rb-pinning-service-api is no longer required for running remote pinning tests. This alone saves at least 3 minutes in test runtime in CI because we don't need to checkout the repo, build the Docker image, run it, etc. Instead this implements a simple pinning service in Go that the test runs in-process, with a callback that can be used to control the async behavior of the pinning service (e.g. simulate work happening asynchronously like transitioning from "queued" -> "pinning" -> "pinned"). This also adds an environment variable to Kubo to control the MFS remote pin polling interval, so that we don't have to wait 30 seconds in the test for MFS changes to be repinned. This is purely for tests so I don't think we should document this. This entire test suite runs in around 2.5 sec on my laptop, compared to the existing 3+ minutes in CI. --- .github/workflows/sharness.yml | 14 - cmd/ipfs/pinmfs.go | 15 +- go.mod | 5 + go.sum | 10 + test/cli/harness/node.go | 17 + test/cli/must.go | 8 + test/cli/pinning_remote_test.go | 446 +++++++++++++++++++ test/cli/testutils/pinningservice/pinning.go | 401 +++++++++++++++++ test/sharness/t0700-remotepin.sh | 332 -------------- 9 files changed, 901 insertions(+), 347 deletions(-) create mode 100644 test/cli/must.go create mode 100644 test/cli/pinning_remote_test.go create mode 100644 test/cli/testutils/pinningservice/pinning.go delete mode 100755 test/sharness/t0700-remotepin.sh diff --git a/.github/workflows/sharness.yml b/.github/workflows/sharness.yml index 7b392bcd9..90c622c3b 100644 --- a/.github/workflows/sharness.yml +++ b/.github/workflows/sharness.yml @@ -29,24 +29,10 @@ jobs: path: kubo - name: Install missing tools run: sudo apt install -y socat net-tools fish libxml2-utils - - name: Checkout IPFS Pinning Service API - uses: actions/checkout@v3 - with: - repository: ipfs-shipyard/rb-pinning-service-api - ref: 773c3adbb421c551d2d89288abac3e01e1f7c3a8 - path: rb-pinning-service-api - # TODO: check if docker compose (not docker-compose) is available on default gh runners - - name: Start IPFS Pinning Service API - run: | - (for i in {1..3}; do docker compose pull && break || sleep 5; done) && - docker compose up -d - working-directory: rb-pinning-service-api - name: Restore Go Cache uses: protocol/cache-go-action@v1 with: name: ${{ github.job }} - - name: Find IPFS Pinning Service API address - run: echo "TEST_DOCKER_HOST=$(ip -4 addr show docker0 | grep -Po 'inet \K[\d.]+')" >> $GITHUB_ENV - uses: actions/cache@v3 with: path: test/sharness/lib/dependencies diff --git a/cmd/ipfs/pinmfs.go b/cmd/ipfs/pinmfs.go index f36b0a8c5..c2c0cb8b7 100644 --- a/cmd/ipfs/pinmfs.go +++ b/cmd/ipfs/pinmfs.go @@ -3,6 +3,7 @@ package main import ( "context" "fmt" + "os" "time" "github.com/libp2p/go-libp2p/core/host" @@ -31,7 +32,19 @@ func (x lastPin) IsValid() bool { return x != lastPin{} } -const daemonConfigPollInterval = time.Minute / 2 +var daemonConfigPollInterval = time.Minute / 2 + +func init() { + // this environment variable is solely for testing, use at your own risk + if pollDurStr := os.Getenv("MFS_PIN_POLL_INTERVAL"); pollDurStr != "" { + d, err := time.ParseDuration(pollDurStr) + if err != nil { + mfslog.Error("error parsing MFS_PIN_POLL_INTERVAL, using default:", err) + } + daemonConfigPollInterval = d + } +} + const defaultRepinInterval = 5 * time.Minute type pinMFSContext interface { diff --git a/go.mod b/go.mod index 3d8585be0..3648783d5 100644 --- a/go.mod +++ b/go.mod @@ -43,6 +43,7 @@ require ( 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/julienschmidt/httprouter v1.3.0 github.com/libp2p/go-doh-resolver v0.4.0 github.com/libp2p/go-libp2p v0.26.4 github.com/libp2p/go-libp2p-http v0.4.0 @@ -67,6 +68,8 @@ require ( github.com/prometheus/client_golang v1.14.0 github.com/stretchr/testify v1.8.2 github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 + github.com/tidwall/gjson v1.14.4 + github.com/tidwall/sjson v1.2.5 github.com/whyrusleeping/go-sysinfo v0.0.0-20190219211824-4a357d4b90b1 github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 go.opencensus.io v0.24.0 @@ -198,6 +201,8 @@ require ( github.com/samber/lo v1.36.0 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/texttheater/golang-levenshtein v0.0.0-20180516184445-d188e65d659e // indirect + github.com/tidwall/match v1.1.1 // indirect + github.com/tidwall/pretty v1.2.0 // indirect github.com/ucarion/urlpath v0.0.0-20200424170820-7ccc79b76bbb // indirect github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc // indirect github.com/whyrusleeping/cbor-gen v0.0.0-20230126041949-52956bd4c9aa // indirect diff --git a/go.sum b/go.sum index fc8dd18e8..95daffbf7 100644 --- a/go.sum +++ b/go.sum @@ -495,6 +495,7 @@ github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVY github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/kami-zh/go-capturer v0.0.0-20171211120116-e492ea43421d/go.mod h1:P2viExyCEfeWGU259JnaQ34Inuec4R38JCyBx2edgD0= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= @@ -858,6 +859,15 @@ github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cb github.com/texttheater/golang-levenshtein v0.0.0-20180516184445-d188e65d659e h1:T5PdfK/M1xyrHwynxMIVMWLS7f/qHwfslZphxtGnw7s= github.com/texttheater/golang-levenshtein v0.0.0-20180516184445-d188e65d659e/go.mod h1:XDKHRm5ThF8YJjx001LtgelzsoaEcvnA7lVWz9EeX3g= github.com/thoas/go-funk v0.9.1 h1:O549iLZqPpTUQ10ykd26sZhzD+rmR5pWhuElrhbC20M= +github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/gjson v1.14.4 h1:uo0p8EbA09J7RQaflQ1aBRffTR7xedD2bcIVSYxLnkM= +github.com/tidwall/gjson v1.14.4/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= +github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= +github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= +github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= +github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/tj/assert v0.0.3 h1:Df/BlaZ20mq6kuai7f5z2TvPFiwC3xaWJSDQNiIS3Rk= github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c h1:u6SKchux2yDvFQnDHS3lPnIRmfVJ5Sxy3ao2SIdysLQ= github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM= diff --git a/test/cli/harness/node.go b/test/cli/harness/node.go index f740ab1b1..4d9ed965c 100644 --- a/test/cli/harness/node.go +++ b/test/cli/harness/node.go @@ -76,6 +76,23 @@ func (n *Node) WriteBytes(filename string, b []byte) { } } +// ReadFile reads the specific file. If it is relative, it is relative the node's root dir. +func (n *Node) ReadFile(filename string) string { + f := filename + if !filepath.IsAbs(filename) { + f = filepath.Join(n.Dir, filename) + } + b, err := os.ReadFile(f) + if err != nil { + panic(err) + } + return string(b) +} + +func (n *Node) ConfigFile() string { + return filepath.Join(n.Dir, "config") +} + func (n *Node) ReadConfig() *config.Config { cfg, err := serial.Load(filepath.Join(n.Dir, "config")) if err != nil { diff --git a/test/cli/must.go b/test/cli/must.go new file mode 100644 index 000000000..e12598466 --- /dev/null +++ b/test/cli/must.go @@ -0,0 +1,8 @@ +package cli + +func MustVal[V any](val V, err error) V { + if err != nil { + panic(err) + } + return val +} diff --git a/test/cli/pinning_remote_test.go b/test/cli/pinning_remote_test.go new file mode 100644 index 000000000..fede942ba --- /dev/null +++ b/test/cli/pinning_remote_test.go @@ -0,0 +1,446 @@ +package cli + +import ( + "errors" + "fmt" + "net" + "net/http" + "testing" + "time" + + "github.com/google/uuid" + "github.com/ipfs/kubo/test/cli/harness" + "github.com/ipfs/kubo/test/cli/testutils" + "github.com/ipfs/kubo/test/cli/testutils/pinningservice" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/tidwall/gjson" + "github.com/tidwall/sjson" +) + +func runPinningService(t *testing.T, authToken string) (*pinningservice.PinningService, string) { + svc := pinningservice.New() + router := pinningservice.NewRouter(authToken, svc) + server := &http.Server{Handler: router} + listener, err := net.Listen("tcp", "127.0.0.1:0") + require.NoError(t, err) + go func() { + err := server.Serve(listener) + if err != nil && !errors.Is(err, net.ErrClosed) && !errors.Is(err, http.ErrServerClosed) { + t.Logf("Serve error: %s", err) + } + }() + t.Cleanup(func() { listener.Close() }) + + return svc, fmt.Sprintf("http://%s/api/v1", listener.Addr().String()) +} + +func TestRemotePinning(t *testing.T) { + t.Parallel() + authToken := "testauthtoken" + + t.Run("MFS pinning", func(t *testing.T) { + t.Parallel() + node := harness.NewT(t).NewNode().Init() + node.Runner.Env["MFS_PIN_POLL_INTERVAL"] = "10ms" + + _, svcURL := runPinningService(t, authToken) + node.IPFS("pin", "remote", "service", "add", "svc", svcURL, authToken) + node.IPFS("config", "--json", "Pinning.RemoteServices.svc.Policies.MFS.RepinInterval", `"1s"`) + node.IPFS("config", "--json", "Pinning.RemoteServices.svc.Policies.MFS.PinName", `"test_pin"`) + node.IPFS("config", "--json", "Pinning.RemoteServices.svc.Policies.MFS.Enable", "true") + + node.StartDaemon() + + node.IPFS("files", "cp", "/ipfs/bafkqaaa", "/mfs-pinning-test-"+uuid.NewString()) + node.IPFS("files", "flush") + res := node.IPFS("files", "stat", "/", "--enc=json") + hash := gjson.Get(res.Stdout.String(), "Hash").Str + + assert.Eventually(t, + func() bool { + res = node.IPFS("pin", "remote", "ls", + "--service=svc", + "--name=test_pin", + "--status=queued,pinning,pinned,failed", + "--enc=json", + ) + pinnedHash := gjson.Get(res.Stdout.String(), "Cid").Str + return hash == pinnedHash + }, + 10*time.Second, + 10*time.Millisecond, + ) + + t.Run("MFS root is repinned on CID change", func(t *testing.T) { + node.IPFS("files", "cp", "/ipfs/bafkqaaa", "/mfs-pinning-repin-test-"+uuid.NewString()) + node.IPFS("files", "flush") + res = node.IPFS("files", "stat", "/", "--enc=json") + hash := gjson.Get(res.Stdout.String(), "Hash").Str + assert.Eventually(t, + func() bool { + res := node.IPFS("pin", "remote", "ls", + "--service=svc", + "--name=test_pin", + "--status=queued,pinning,pinned,failed", + "--enc=json", + ) + pinnedHash := gjson.Get(res.Stdout.String(), "Cid").Str + return hash == pinnedHash + }, + 10*time.Second, + 10*time.Millisecond, + ) + }) + }) + + // Pinning.RemoteServices includes API.Key, so we give it the same treatment + // as Identity,PrivKey to prevent exposing it on the network + t.Run("access token security", func(t *testing.T) { + t.Parallel() + node := harness.NewT(t).NewNode().Init() + node.IPFS("pin", "remote", "service", "add", "1", "http://example1.com", "testkey") + res := node.RunIPFS("config", "Pinning") + assert.Equal(t, 1, res.ExitCode()) + assert.Contains(t, res.Stderr.String(), "cannot show or change pinning services credentials") + assert.NotContains(t, res.Stdout.String(), "testkey") + + res = node.RunIPFS("config", "Pinning.RemoteServices.1.API.Key") + assert.Equal(t, 1, res.ExitCode()) + assert.Contains(t, res.Stderr.String(), "cannot show or change pinning services credentials") + assert.NotContains(t, res.Stdout.String(), "testkey") + + configShow := node.RunIPFS("config", "show").Stdout.String() + assert.NotContains(t, configShow, "testkey") + + t.Run("re-injecting config with 'ipfs config replace' preserves the API keys", func(t *testing.T) { + node.WriteBytes("config-show", []byte(configShow)) + node.IPFS("config", "replace", "config-show") + assert.Contains(t, node.ReadFile(node.ConfigFile()), "testkey") + }) + + t.Run("injecting config with 'ipfs config replace' with API keys returns an error", func(t *testing.T) { + // remove Identity.PrivKey to ensure error is triggered by Pinning.RemoteServices + configJSON := MustVal(sjson.Delete(configShow, "Identity.PrivKey")) + configJSON = MustVal(sjson.Set(configJSON, "Pinning.RemoteServices.1.API.Key", "testkey")) + node.WriteBytes("new-config", []byte(configJSON)) + res := node.RunIPFS("config", "replace", "new-config") + assert.Equal(t, 1, res.ExitCode()) + assert.Contains(t, res.Stderr.String(), "cannot change remote pinning services api info with `config replace`") + }) + }) + + t.Run("pin remote service ls --stat", func(t *testing.T) { + t.Parallel() + node := harness.NewT(t).NewNode().Init().StartDaemon() + _, svcURL := runPinningService(t, authToken) + + node.IPFS("pin", "remote", "service", "add", "svc", svcURL, authToken) + node.IPFS("pin", "remote", "service", "add", "invalid-svc", svcURL+"/invalidpath", authToken) + + res := node.IPFS("pin", "remote", "service", "ls", "--stat") + assert.Contains(t, res.Stdout.String(), " 0/0/0/0") + + stats := node.IPFS("pin", "remote", "service", "ls", "--stat", "--enc=json").Stdout.String() + assert.Equal(t, "valid", gjson.Get(stats, `RemoteServices.#(Service == "svc").Stat.Status`).Str) + assert.Equal(t, "invalid", gjson.Get(stats, `RemoteServices.#(Service == "invalid-svc").Stat.Status`).Str) + + // no --stat returns no stat obj + t.Run("no --stat returns no stat obj", func(t *testing.T) { + res := node.IPFS("pin", "remote", "service", "ls", "--enc=json") + assert.False(t, gjson.Get(res.Stdout.String(), `RemoteServices.#(Service == "svc").Stat`).Exists()) + }) + }) + + t.Run("adding service with invalid URL fails", func(t *testing.T) { + t.Parallel() + node := harness.NewT(t).NewNode().Init().StartDaemon() + + res := node.RunIPFS("pin", "remote", "service", "add", "svc", "invalid-service.example.com", "key") + assert.Equal(t, 1, res.ExitCode()) + assert.Contains(t, res.Stderr.String(), "service endpoint must be a valid HTTP URL") + + res = node.RunIPFS("pin", "remote", "service", "add", "svc", "xyz://invalid-service.example.com", "key") + assert.Equal(t, 1, res.ExitCode()) + assert.Contains(t, res.Stderr.String(), "service endpoint must be a valid HTTP URL") + }) + + t.Run("unauthorized pinning service calls fail", func(t *testing.T) { + t.Parallel() + node := harness.NewT(t).NewNode().Init().StartDaemon() + _, svcURL := runPinningService(t, authToken) + + node.IPFS("pin", "remote", "service", "add", "svc", svcURL, "othertoken") + + res := node.RunIPFS("pin", "remote", "ls", "--service=svc") + assert.Equal(t, 1, res.ExitCode()) + assert.Contains(t, res.Stderr.String(), "access denied") + }) + + t.Run("pinning service calls fail when there is a wrong path", func(t *testing.T) { + t.Parallel() + node := harness.NewT(t).NewNode().Init().StartDaemon() + _, svcURL := runPinningService(t, authToken) + node.IPFS("pin", "remote", "service", "add", "svc", svcURL+"/invalid-path", authToken) + + res := node.RunIPFS("pin", "remote", "ls", "--service=svc") + assert.Equal(t, 1, res.ExitCode()) + assert.Contains(t, res.Stderr.String(), "404") + }) + + t.Run("pinning service calls fail when DNS resolution fails", func(t *testing.T) { + t.Parallel() + node := harness.NewT(t).NewNode().Init().StartDaemon() + node.IPFS("pin", "remote", "service", "add", "svc", "https://invalid-service.example.com", authToken) + + res := node.RunIPFS("pin", "remote", "ls", "--service=svc") + assert.Equal(t, 1, res.ExitCode()) + assert.Contains(t, res.Stderr.String(), "no such host") + }) + + t.Run("pin remote service rm", func(t *testing.T) { + t.Parallel() + node := harness.NewT(t).NewNode().Init().StartDaemon() + node.IPFS("pin", "remote", "service", "add", "svc", "https://example.com", authToken) + node.IPFS("pin", "remote", "service", "rm", "svc") + res := node.IPFS("pin", "remote", "service", "ls") + assert.NotContains(t, res.Stdout.String(), "svc") + }) + + t.Run("remote pinning", func(t *testing.T) { + t.Parallel() + + verifyStatus := func(node *harness.Node, name, hash, status string) { + resJSON := node.IPFS("pin", "remote", "ls", + "--service=svc", + "--enc=json", + "--name="+name, + "--status="+status, + ).Stdout.String() + + assert.Equal(t, status, gjson.Get(resJSON, "Status").Str) + assert.Equal(t, hash, gjson.Get(resJSON, "Cid").Str) + assert.Equal(t, name, gjson.Get(resJSON, "Name").Str) + } + + t.Run("'ipfs pin remote add --background=true'", func(t *testing.T) { + node := harness.NewT(t).NewNode().Init().StartDaemon() + svc, svcURL := runPinningService(t, authToken) + node.IPFS("pin", "remote", "service", "add", "svc", svcURL, authToken) + + // retain a ptr to the pin that's in the DB so we can directly mutate its status + // to simulate async work + pinCh := make(chan *pinningservice.PinStatus, 1) + svc.PinAdded = func(req *pinningservice.AddPinRequest, pin *pinningservice.PinStatus) { + pinCh <- pin + } + + hash := node.IPFSAddStr("foo") + node.IPFS("pin", "remote", "add", + "--background=true", + "--service=svc", + "--name=pin1", + hash, + ) + + pin := <-pinCh + + transitionStatus := func(status string) { + pin.M.Lock() + pin.Status = status + pin.M.Unlock() + } + + verifyStatus(node, "pin1", hash, "queued") + + transitionStatus("pinning") + verifyStatus(node, "pin1", hash, "pinning") + + transitionStatus("pinned") + verifyStatus(node, "pin1", hash, "pinned") + + transitionStatus("failed") + verifyStatus(node, "pin1", hash, "failed") + }) + + t.Run("'ipfs pin remote add --background=false'", func(t *testing.T) { + t.Parallel() + node := harness.NewT(t).NewNode().Init().StartDaemon() + svc, svcURL := runPinningService(t, authToken) + node.IPFS("pin", "remote", "service", "add", "svc", svcURL, authToken) + + svc.PinAdded = func(req *pinningservice.AddPinRequest, pin *pinningservice.PinStatus) { + pin.M.Lock() + defer pin.M.Unlock() + pin.Status = "pinned" + } + hash := node.IPFSAddStr("foo") + node.IPFS("pin", "remote", "add", + "--background=false", + "--service=svc", + "--name=pin2", + hash, + ) + verifyStatus(node, "pin2", hash, "pinned") + }) + + t.Run("'ipfs pin remote ls' with multiple statuses", func(t *testing.T) { + t.Parallel() + node := harness.NewT(t).NewNode().Init().StartDaemon() + svc, svcURL := runPinningService(t, authToken) + node.IPFS("pin", "remote", "service", "add", "svc", svcURL, authToken) + + hash := node.IPFSAddStr("foo") + desiredStatuses := map[string]string{ + "pin-queued": "queued", + "pin-pinning": "pinning", + "pin-pinned": "pinned", + "pin-failed": "failed", + } + var pins []*pinningservice.PinStatus + svc.PinAdded = func(req *pinningservice.AddPinRequest, pin *pinningservice.PinStatus) { + pin.M.Lock() + defer pin.M.Unlock() + pins = append(pins, pin) + // this must be "pinned" for the 'pin remote add' command to return + // after 'pin remote add', we change the status to its real status + pin.Status = "pinned" + } + + for pinName := range desiredStatuses { + node.IPFS("pin", "remote", "add", + "--service=svc", + "--name="+pinName, + hash, + ) + } + for _, pin := range pins { + pin.M.Lock() + pin.Status = desiredStatuses[pin.Pin.Name] + pin.M.Unlock() + } + + res := node.IPFS("pin", "remote", "ls", + "--service=svc", + "--status=queued,pinning,pinned,failed", + "--enc=json", + ) + actualStatuses := map[string]string{} + for _, line := range res.Stdout.Lines() { + name := gjson.Get(line, "Name").Str + status := gjson.Get(line, "Status").Str + // drop statuses of other pins we didn't add + if _, ok := desiredStatuses[name]; ok { + actualStatuses[name] = status + } + } + assert.Equal(t, desiredStatuses, actualStatuses) + }) + + t.Run("'ipfs pin remote ls' by CID", func(t *testing.T) { + t.Parallel() + node := harness.NewT(t).NewNode().Init().StartDaemon() + svc, svcURL := runPinningService(t, authToken) + node.IPFS("pin", "remote", "service", "add", "svc", svcURL, authToken) + + transitionedCh := make(chan struct{}, 1) + svc.PinAdded = func(req *pinningservice.AddPinRequest, pin *pinningservice.PinStatus) { + pin.M.Lock() + defer pin.M.Unlock() + pin.Status = "pinned" + transitionedCh <- struct{}{} + } + hash := node.IPFSAddStr(string(testutils.RandomBytes(1000))) + node.IPFS("pin", "remote", "add", "--background=false", "--service=svc", hash) + <-transitionedCh + res := node.IPFS("pin", "remote", "ls", "--service=svc", "--cid="+hash, "--enc=json").Stdout.String() + assert.Contains(t, res, hash) + }) + + t.Run("'ipfs pin remote rm --name' without --force when multiple pins match", func(t *testing.T) { + t.Parallel() + node := harness.NewT(t).NewNode().Init().StartDaemon() + svc, svcURL := runPinningService(t, authToken) + node.IPFS("pin", "remote", "service", "add", "svc", svcURL, authToken) + + svc.PinAdded = func(req *pinningservice.AddPinRequest, pin *pinningservice.PinStatus) { + pin.M.Lock() + defer pin.M.Unlock() + pin.Status = "pinned" + } + hash := node.IPFSAddStr(string(testutils.RandomBytes(1000))) + node.IPFS("pin", "remote", "add", "--service=svc", "--name=force-test-name", hash) + node.IPFS("pin", "remote", "add", "--service=svc", "--name=force-test-name", hash) + + t.Run("fails", func(t *testing.T) { + res := node.RunIPFS("pin", "remote", "rm", "--service=svc", "--name=force-test-name") + assert.Equal(t, 1, res.ExitCode()) + assert.Contains(t, res.Stderr.String(), "Error: multiple remote pins are matching this query, add --force to confirm the bulk removal") + }) + + t.Run("matching pins are not removed", func(t *testing.T) { + lines := node.IPFS("pin", "remote", "ls", "--service=svc", "--name=force-test-name").Stdout.Lines() + assert.Contains(t, lines[0], "force-test-name") + assert.Contains(t, lines[1], "force-test-name") + }) + }) + + t.Run("'ipfs pin remote rm --name --force' remove multiple pins", func(t *testing.T) { + t.Parallel() + node := harness.NewT(t).NewNode().Init().StartDaemon() + svc, svcURL := runPinningService(t, authToken) + node.IPFS("pin", "remote", "service", "add", "svc", svcURL, authToken) + + svc.PinAdded = func(req *pinningservice.AddPinRequest, pin *pinningservice.PinStatus) { + pin.M.Lock() + defer pin.M.Unlock() + pin.Status = "pinned" + } + hash := node.IPFSAddStr(string(testutils.RandomBytes(1000))) + node.IPFS("pin", "remote", "add", "--service=svc", "--name=force-test-name", hash) + node.IPFS("pin", "remote", "add", "--service=svc", "--name=force-test-name", hash) + + node.IPFS("pin", "remote", "rm", "--service=svc", "--name=force-test-name", "--force") + out := node.IPFS("pin", "remote", "ls", "--service=svc", "--name=force-test-name").Stdout.Trimmed() + assert.Empty(t, out) + }) + + t.Run("'ipfs pin remote rm --force' removes all pins", func(t *testing.T) { + t.Parallel() + node := harness.NewT(t).NewNode().Init().StartDaemon() + svc, svcURL := runPinningService(t, authToken) + node.IPFS("pin", "remote", "service", "add", "svc", svcURL, authToken) + + svc.PinAdded = func(req *pinningservice.AddPinRequest, pin *pinningservice.PinStatus) { + pin.M.Lock() + defer pin.M.Unlock() + pin.Status = "pinned" + } + for i := 0; i < 4; i++ { + hash := node.IPFSAddStr(string(testutils.RandomBytes(1000))) + name := fmt.Sprintf("--name=%d", i) + node.IPFS("pin", "remote", "add", "--service=svc", "--name="+name, hash) + } + + lines := node.IPFS("pin", "remote", "ls", "--service=svc").Stdout.Lines() + assert.Len(t, lines, 4) + + node.IPFS("pin", "remote", "rm", "--service=svc", "--force") + + lines = node.IPFS("pin", "remote", "ls", "--service=svc").Stdout.Lines() + assert.Len(t, lines, 0) + }) + }) + + t.Run("'ipfs pin remote add' shows a warning message when offline", func(t *testing.T) { + t.Parallel() + node := harness.NewT(t).NewNode().Init() + _, svcURL := runPinningService(t, authToken) + node.IPFS("pin", "remote", "service", "add", "svc", svcURL, authToken) + + hash := node.IPFSAddStr(string(testutils.RandomBytes(1000))) + res := node.IPFS("pin", "remote", "add", "--service=svc", "--background", hash) + warningMsg := "WARNING: the local node is offline and remote pinning may fail if there is no other provider for this CID" + assert.Contains(t, res.Stdout.String(), warningMsg) + }) +} diff --git a/test/cli/testutils/pinningservice/pinning.go b/test/cli/testutils/pinningservice/pinning.go new file mode 100644 index 000000000..6bfd4ed4e --- /dev/null +++ b/test/cli/testutils/pinningservice/pinning.go @@ -0,0 +1,401 @@ +package pinningservice + +import ( + "encoding/json" + "fmt" + "net/http" + "reflect" + "strconv" + "strings" + "sync" + "time" + + "github.com/google/uuid" + "github.com/julienschmidt/httprouter" +) + +func NewRouter(authToken string, svc *PinningService) http.Handler { + router := httprouter.New() + router.GET("/api/v1/pins", svc.listPins) + router.POST("/api/v1/pins", svc.addPin) + router.GET("/api/v1/pins/:requestID", svc.getPin) + router.POST("/api/v1/pins/:requestID", svc.replacePin) + router.DELETE("/api/v1/pins/:requestID", svc.removePin) + + handler := authHandler(authToken, router) + + return handler +} + +func authHandler(authToken string, delegate http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + authz := r.Header.Get("Authorization") + if !strings.HasPrefix(authz, "Bearer ") { + errResp(w, "invalid authorization token, must start with 'Bearer '", "", http.StatusBadRequest) + return + } + + token := strings.TrimPrefix(authz, "Bearer ") + if token != authToken { + errResp(w, "access denied", "", http.StatusUnauthorized) + return + } + + delegate.ServeHTTP(w, r) + }) +} + +func New() *PinningService { + return &PinningService{ + PinAdded: func(*AddPinRequest, *PinStatus) {}, + } +} + +// PinningService is a basic pinning service that implements the Remote Pinning API, for testing Kubo's integration with remote pinning services. +// Pins are not persisted, they are just kept in-memory, and this provides callbacks for controlling the behavior of the pinning service. +type PinningService struct { + m sync.Mutex + // PinAdded is a callback that is invoked after a new pin is added via the API. + PinAdded func(*AddPinRequest, *PinStatus) + pins []*PinStatus +} + +type Pin struct { + CID string `json:"cid"` + Name string `json:"name"` + Origins []string `json:"origins"` + Meta map[string]interface{} `json:"meta"` +} + +type PinStatus struct { + M sync.Mutex + RequestID string + Status string + Created time.Time + Pin Pin + Delegates []string + Info map[string]interface{} +} + +func (p *PinStatus) MarshalJSON() ([]byte, error) { + type pinStatusJSON struct { + RequestID string `json:"requestid"` + Status string `json:"status"` + Created time.Time `json:"created"` + Pin Pin `json:"pin"` + Delegates []string `json:"delegates"` + Info map[string]interface{} `json:"info"` + } + // lock the pin before marshaling it to protect against data races while marshaling + p.M.Lock() + pinJSON := pinStatusJSON{ + RequestID: p.RequestID, + Status: p.Status, + Created: p.Created, + Pin: p.Pin, + Delegates: p.Delegates, + Info: p.Info, + } + p.M.Unlock() + return json.Marshal(pinJSON) +} + +func (p *PinStatus) Clone() PinStatus { + return PinStatus{ + RequestID: p.RequestID, + Status: p.Status, + Created: p.Created, + Pin: p.Pin, + Delegates: p.Delegates, + Info: p.Info, + } +} + +const ( + matchExact = "exact" + matchIExact = "iexact" + matchPartial = "partial" + matchIPartial = "ipartial" + + statusQueued = "queued" + statusPinning = "pinning" + statusPinned = "pinned" + statusFailed = "failed" + + timeLayout = "2006-01-02T15:04:05.999Z" +) + +func errResp(w http.ResponseWriter, reason, details string, statusCode int) { + type errorObj struct { + Reason string `json:"reason"` + Details string `json:"details"` + } + type errorResp struct { + Error errorObj `json:"error"` + } + resp := errorResp{ + Error: errorObj{ + Reason: reason, + Details: details, + }, + } + writeJSON(w, resp, statusCode) +} + +func writeJSON(w http.ResponseWriter, val any, statusCode int) { + b, err := json.Marshal(val) + if err != nil { + w.Header().Set("Content-Type", "text/plain") + errResp(w, fmt.Sprintf("marshaling response: %s", err), "", http.StatusInternalServerError) + return + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(statusCode) + _, _ = w.Write(b) +} + +type AddPinRequest struct { + CID string `json:"cid"` + Name string `json:"name"` + Origins []string `json:"origins"` + Meta map[string]interface{} `json:"meta"` +} + +func (p *PinningService) addPin(writer http.ResponseWriter, req *http.Request, params httprouter.Params) { + var addReq AddPinRequest + err := json.NewDecoder(req.Body).Decode(&addReq) + if err != nil { + errResp(writer, fmt.Sprintf("unmarshaling req: %s", err), "", http.StatusBadRequest) + return + } + + pin := &PinStatus{ + RequestID: uuid.NewString(), + Status: statusQueued, + Created: time.Now(), + Pin: Pin(addReq), + } + + p.m.Lock() + p.pins = append(p.pins, pin) + p.m.Unlock() + + writeJSON(writer, &pin, http.StatusAccepted) + p.PinAdded(&addReq, pin) +} + +type ListPinsResponse struct { + Count int `json:"count"` + Results []*PinStatus `json:"results"` +} + +func (p *PinningService) listPins(writer http.ResponseWriter, req *http.Request, params httprouter.Params) { + q := req.URL.Query() + + cidStr := q.Get("cid") + name := q.Get("name") + match := q.Get("match") + status := q.Get("status") + beforeStr := q.Get("before") + afterStr := q.Get("after") + limitStr := q.Get("limit") + metaStr := q.Get("meta") + + if limitStr == "" { + limitStr = "10" + } + limit, err := strconv.Atoi(limitStr) + if err != nil { + errResp(writer, fmt.Sprintf("parsing limit: %s", err), "", http.StatusBadRequest) + return + } + + var cids []string + if cidStr != "" { + cids = strings.Split(cidStr, ",") + } + + var statuses []string + if status != "" { + statuses = strings.Split(status, ",") + } + + p.m.Lock() + defer p.m.Unlock() + var pins []*PinStatus + for _, pinStatus := range p.pins { + // clone it so we can immediately release the lock + pinStatus.M.Lock() + clonedPS := pinStatus.Clone() + pinStatus.M.Unlock() + + // cid + var matchesCID bool + if len(cids) == 0 { + matchesCID = true + } else { + for _, cid := range cids { + if cid == clonedPS.Pin.CID { + matchesCID = true + } + } + } + if !matchesCID { + continue + } + + // name + if match == "" { + match = matchExact + } + if name != "" { + switch match { + case matchExact: + if name != clonedPS.Pin.Name { + continue + } + case matchIExact: + if !strings.EqualFold(name, clonedPS.Pin.Name) { + continue + } + case matchPartial: + if !strings.Contains(clonedPS.Pin.Name, name) { + continue + } + case matchIPartial: + if !strings.Contains(strings.ToLower(clonedPS.Pin.Name), strings.ToLower(name)) { + continue + } + default: + errResp(writer, fmt.Sprintf("unknown match %q", match), "", http.StatusBadRequest) + return + } + } + + // status + var matchesStatus bool + if len(statuses) == 0 { + statuses = []string{statusPinned} + } + for _, status := range statuses { + if status == clonedPS.Status { + matchesStatus = true + } + } + if !matchesStatus { + continue + } + + // before + if beforeStr != "" { + before, err := time.Parse(timeLayout, beforeStr) + if err != nil { + errResp(writer, fmt.Sprintf("parsing before: %s", err), "", http.StatusBadRequest) + return + } + if !clonedPS.Created.Before(before) { + continue + } + } + + // after + if afterStr != "" { + after, err := time.Parse(timeLayout, afterStr) + if err != nil { + errResp(writer, fmt.Sprintf("parsing before: %s", err), "", http.StatusBadRequest) + return + } + if !clonedPS.Created.After(after) { + continue + } + } + + // meta + if metaStr != "" { + meta := map[string]interface{}{} + err := json.Unmarshal([]byte(metaStr), &meta) + if err != nil { + errResp(writer, fmt.Sprintf("parsing meta: %s", err), "", http.StatusBadRequest) + return + } + var matchesMeta bool + for k, v := range meta { + pinV, contains := clonedPS.Pin.Meta[k] + if !contains || !reflect.DeepEqual(pinV, v) { + matchesMeta = false + break + } + } + if !matchesMeta { + continue + } + } + + // add the original pin status, not the cloned one + pins = append(pins, pinStatus) + + if len(pins) == limit { + break + } + } + + out := ListPinsResponse{ + Count: len(pins), + Results: pins, + } + writeJSON(writer, out, http.StatusOK) +} + +func (p *PinningService) getPin(writer http.ResponseWriter, req *http.Request, params httprouter.Params) { + requestID := params.ByName("requestID") + p.m.Lock() + defer p.m.Unlock() + for _, pin := range p.pins { + if pin.RequestID == requestID { + writeJSON(writer, pin, http.StatusOK) + return + } + } + errResp(writer, "", "", http.StatusNotFound) +} + +func (p *PinningService) replacePin(writer http.ResponseWriter, req *http.Request, params httprouter.Params) { + requestID := params.ByName("requestID") + + var replaceReq Pin + err := json.NewDecoder(req.Body).Decode(&replaceReq) + if err != nil { + errResp(writer, fmt.Sprintf("decoding request: %s", err), "", http.StatusBadRequest) + return + } + + p.m.Lock() + defer p.m.Unlock() + for _, pin := range p.pins { + if pin.RequestID == requestID { + pin.M.Lock() + pin.Pin = replaceReq + pin.M.Unlock() + writer.WriteHeader(http.StatusAccepted) + return + } + } + errResp(writer, "", "", http.StatusNotFound) +} + +func (p *PinningService) removePin(writer http.ResponseWriter, req *http.Request, params httprouter.Params) { + requestID := params.ByName("requestID") + + p.m.Lock() + defer p.m.Unlock() + + for i, pin := range p.pins { + if pin.RequestID == requestID { + p.pins = append(p.pins[0:i], p.pins[i+1:]...) + writer.WriteHeader(http.StatusAccepted) + return + } + } + + errResp(writer, "", "", http.StatusNotFound) +} diff --git a/test/sharness/t0700-remotepin.sh b/test/sharness/t0700-remotepin.sh deleted file mode 100755 index 2566c06d8..000000000 --- a/test/sharness/t0700-remotepin.sh +++ /dev/null @@ -1,332 +0,0 @@ -#!/usr/bin/env bash - -test_description="Test ipfs remote pinning operations" - -. lib/test-lib.sh - -if [ -z ${TEST_DOCKER_HOST+x} ]; then - # TODO: set up instead of skipping? - skip_all='Skipping pinning service integration tests: missing TEST_DOCKER_HOST, remote pinning service not available' - test_done -fi - -# daemon running in online mode to ensure Pin.origins/PinStatus.delegates work -test_init_ipfs -test_launch_ipfs_daemon - -# create user on pinning service -TEST_PIN_SVC="http://${TEST_DOCKER_HOST}:5000/api/v1" -TEST_PIN_SVC_KEY=$(curl -s -X POST "$TEST_PIN_SVC/users" -d email="go-ipfs-sharness@ipfs.example.com" | jq --raw-output .access_token) - -# pin remote service add|ls|rm - -# confirm empty service list response has proper json struct -# https://github.com/ipfs/go-ipfs/pull/7829 -test_expect_success "test 'ipfs pin remote service ls' JSON on empty list" ' - ipfs pin remote service ls --stat --enc=json | tee empty_ls_out && - echo "{\"RemoteServices\":[]}" > exp_ls_out && - test_cmp exp_ls_out empty_ls_out -' - -# add valid and invalid services -test_expect_success "creating test user on remote pinning service" ' - echo CI host IP address ${TEST_PIN_SVC} && - ipfs pin remote service add test_pin_svc ${TEST_PIN_SVC} ${TEST_PIN_SVC_KEY} && - ipfs pin remote service add test_invalid_key_svc ${TEST_PIN_SVC} fake_api_key && - ipfs pin remote service add test_invalid_url_path_svc ${TEST_PIN_SVC}/invalid-path fake_api_key && - ipfs pin remote service add test_invalid_url_dns_svc https://invalid-service.example.com fake_api_key && - ipfs pin remote service add test_pin_mfs_svc ${TEST_PIN_SVC} ${TEST_PIN_SVC_KEY} -' - -# add a service with a invalid endpoint -test_expect_success "adding remote service with invalid endpoint" ' - test_expect_code 1 ipfs pin remote service add test_endpoint_no_protocol invalid-service.example.com fake_api_key && - test_expect_code 1 ipfs pin remote service add test_endpoint_bad_protocol xyz://invalid-service.example.com fake_api_key -' - -test_expect_success "test 'ipfs pin remote service ls'" ' - ipfs pin remote service ls | tee ls_out && - grep -q test_pin_svc ls_out && - grep -q test_invalid_key_svc ls_out && - grep -q test_invalid_url_path_svc ls_out && - grep -q test_invalid_url_dns_svc ls_out -' - -test_expect_success "test enabling mfs pinning" ' - ipfs config --json Pinning.RemoteServices.test_pin_mfs_svc.Policies.MFS.RepinInterval \"10s\" && - ipfs config --json Pinning.RemoteServices.test_pin_mfs_svc.Policies.MFS.PinName \"mfs_test_pin\" && - ipfs config --json Pinning.RemoteServices.test_pin_mfs_svc.Policies.MFS.Enable true && - ipfs config --json Pinning.RemoteServices.test_pin_mfs_svc.Policies.MFS.RepinInterval > repin_interval && - ipfs config --json Pinning.RemoteServices.test_pin_mfs_svc.Policies.MFS.PinName > pin_name && - ipfs config --json Pinning.RemoteServices.test_pin_mfs_svc.Policies.MFS.Enable > enable && - echo 10s > expected_repin_interval && - echo mfs_test_pin > expected_pin_name && - echo true > expected_enable && - test_cmp repin_interval expected_repin_interval && - test_cmp pin_name expected_pin_name && - test_cmp enable expected_enable -' - -# expect PIN to be created -test_expect_success "verify MFS root is being pinned" ' - ipfs files cp /ipfs/bafkqaaa /mfs-pinning-test-$(date +%s.%N) && - ipfs files flush && - sleep 31 && - ipfs files stat / --enc=json | jq -r .Hash > mfs_cid && - ipfs pin remote ls --service=test_pin_mfs_svc --name=mfs_test_pin --status=queued,pinning,pinned,failed --enc=json | tee ls_out | jq -r .Cid > pin_cid && - cat mfs_cid ls_out && - test_cmp mfs_cid pin_cid -' - -# expect existing PIN to be replaced -test_expect_success "verify MFS root is being repinned on CID change" ' - ipfs files cp /ipfs/bafkqaaa /mfs-pinning-repin-test-$(date +%s.%N) && - ipfs files flush && - sleep 31 && - ipfs files stat / --enc=json | jq -r .Hash > mfs_cid && - ipfs pin remote ls --service=test_pin_mfs_svc --name=mfs_test_pin --status=queued,pinning,pinned,failed --enc=json | tee ls_out | jq -r .Cid > pin_cid && - cat mfs_cid ls_out && - test_cmp mfs_cid pin_cid -' - -# SECURITY of access tokens in API.Key fields: -# Pinning.RemoteServices includes API.Key, and we give it the same treatment -# as Identity.PrivKey to prevent exposing it on the network - -test_expect_success "'ipfs config Pinning' fails" ' - test_expect_code 1 ipfs config Pinning 2>&1 > config_out -' -test_expect_success "output does not include API.Key" ' - test_expect_code 1 grep -q Key config_out -' - -test_expect_success "'ipfs config Pinning.RemoteServices.test_pin_svc.API.Key' fails" ' - test_expect_code 1 ipfs config Pinning.RemoteServices.test_pin_svc.API.Key 2> config_out -' - -test_expect_success "output includes meaningful error" ' - echo "Error: cannot show or change pinning services credentials" > config_exp && - test_cmp config_exp config_out -' - -test_expect_success "'ipfs config Pinning.RemoteServices.test_pin_svc' fails" ' - test_expect_code 1 ipfs config Pinning.RemoteServices.test_pin_svc 2> config_out -' -test_expect_success "output includes meaningful error" ' - test_cmp config_exp config_out -' - -test_expect_success "'ipfs config show' does not include Pinning.RemoteServices[*].API.Key" ' - ipfs config show | tee show_config | jq -r .Pinning.RemoteServices > remote_services && - test_expect_code 1 grep \"Key\" remote_services && - test_expect_code 1 grep fake_api_key show_config && - test_expect_code 1 grep "$TEST_PIN_SVC_KEY" show_config -' - -test_expect_success "'ipfs config replace' injects Pinning.RemoteServices[*].API.Key back" ' - test_expect_code 1 grep fake_api_key show_config && - test_expect_code 1 grep "$TEST_PIN_SVC_KEY" show_config && - ipfs config replace show_config && - test_expect_code 0 grep fake_api_key "$IPFS_PATH/config" && - test_expect_code 0 grep "$TEST_PIN_SVC_KEY" "$IPFS_PATH/config" -' - -# note: we remove Identity.PrivKey to ensure error is triggered by Pinning.RemoteServices -test_expect_success "'ipfs config replace' with Pinning.RemoteServices[*].API.Key errors out" ' - jq -M "del(.Identity.PrivKey)" "$IPFS_PATH/config" | jq ".Pinning += { RemoteServices: {\"myservice\": {\"API\": {\"Endpoint\": \"https://example.com/psa\", \"Key\": \"mysecret\"}}}}" > new_config && - test_expect_code 1 ipfs config replace - < new_config 2> replace_out -' -test_expect_success "output includes meaningful error" " - echo \"Error: cannot add or remove remote pinning services with 'config replace'\" > replace_expected && - test_cmp replace_out replace_expected -" - -# /SECURITY - -test_expect_success "pin remote service ls --stat' returns numbers for a valid service" ' - ipfs pin remote service ls --stat | grep -E "^test_pin_svc.+[0-9]+/[0-9]+/[0-9]+/[0-9]+$" -' - -test_expect_success "pin remote service ls --enc=json --stat' returns valid status" " - ipfs pin remote service ls --stat --enc=json | jq --raw-output '.RemoteServices[] | select(.Service == \"test_pin_svc\") | .Stat.Status' | tee stat_out && - echo valid > stat_expected && - test_cmp stat_out stat_expected -" - -test_expect_success "pin remote service ls --stat' returns invalid status for invalid service" ' - ipfs pin remote service ls --stat | grep -E "^test_invalid_url_path_svc.+invalid$" -' - -test_expect_success "pin remote service ls --enc=json --stat' returns invalid status" " - ipfs pin remote service ls --stat --enc=json | jq --raw-output '.RemoteServices[] | select(.Service == \"test_invalid_url_path_svc\") | .Stat.Status' | tee stat_out && - echo invalid > stat_expected && - test_cmp stat_out stat_expected -" - -test_expect_success "pin remote service ls --enc=json' (without --stat) returns no Stat object" " - ipfs pin remote service ls --enc=json | jq --raw-output '.RemoteServices[] | select(.Service == \"test_invalid_url_path_svc\") | .Stat' | tee stat_out && - echo null > stat_expected && - test_cmp stat_out stat_expected -" - -test_expect_success "check connection to the test pinning service" ' - ipfs pin remote ls --service=test_pin_svc --enc=json -' - -test_expect_success "unauthorized pinning service calls fail" ' - test_expect_code 1 ipfs pin remote ls --service=test_invalid_key_svc -' - -test_expect_success "misconfigured pinning service calls fail (wrong path)" ' - test_expect_code 1 ipfs pin remote ls --service=test_invalid_url_path_svc -' - -test_expect_success "misconfigured pinning service calls fail (dns error)" ' - test_expect_code 1 ipfs pin remote ls --service=test_invalid_url_dns_svc -' - -# pin remote service rm - -test_expect_success "remove pinning service" ' - ipfs pin remote service rm test_invalid_key_svc && - ipfs pin remote service rm test_invalid_url_path_svc && - ipfs pin remote service rm test_invalid_url_dns_svc -' - -test_expect_success "verify pinning service removal works" ' - ipfs pin remote service ls | tee ls_out && - test_expect_code 1 grep test_invalid_key_svc ls_out && - test_expect_code 1 grep test_invalid_url_path_svc ls_out && - test_expect_code 1 grep test_invalid_url_dns_svc ls_out -' - -# pin remote add - -# we leverage the fact that inlined CID can be pinned instantly on the remote service -# (https://github.com/ipfs-shipyard/rb-pinning-service-api/issues/8) -# below test ensures that assumption is correct (before we proceed to actual tests) -test_expect_success "verify that default add (implicit --background=false) works with data inlined in CID" ' - ipfs pin remote add --service=test_pin_svc --name=inlined_null bafkqaaa && - ipfs pin remote ls --service=test_pin_svc --enc=json --name=inlined_null --status=pinned | jq --raw-output .Status | tee ls_out && - grep -q "pinned" ls_out -' - -test_remote_pins() { - BASE=$1 - if [ -n "$BASE" ]; then - BASE_ARGS="--cid-base=$BASE" - fi - - # note: HAS_MISSING is not inlined nor imported to IPFS on purpose, to reliably test 'queued' state - test_expect_success "create some hashes using base $BASE" ' - export HASH_A=$(echo -n "A @ $(date +%s.%N)" | ipfs add $BASE_ARGS -q --inline --inline-limit 1000 --pin=false) && - export HASH_B=$(echo -n "B @ $(date +%s.%N)" | ipfs add $BASE_ARGS -q --inline --inline-limit 1000 --pin=false) && - export HASH_C=$(echo -n "C @ $(date +%s.%N)" | ipfs add $BASE_ARGS -q --inline --inline-limit 1000 --pin=false) && - export HASH_MISSING=$(echo "MISSING FROM IPFS @ $(date +%s.%N)" | ipfs add $BASE_ARGS -q --only-hash) && - echo "A: $HASH_A" && - echo "B: $HASH_B" && - echo "C: $HASH_C" && - echo "M: $HASH_MISSING" - ' - - test_expect_success "'ipfs pin remote add --background=true'" ' - ipfs pin remote add --background=true --service=test_pin_svc --enc=json $BASE_ARGS --name=name_a $HASH_A - ' - - test_expect_success "verify background add worked (instantly pinned variant)" ' - ipfs pin remote ls --service=test_pin_svc --enc=json --name=name_a | tee ls_out && - test_expect_code 0 grep -q name_a ls_out && - test_expect_code 0 grep -q $HASH_A ls_out - ' - - test_expect_success "'ipfs pin remote add --background=true' with CID that is not available" ' - test_expect_code 0 ipfs pin remote add --background=true --service=test_pin_svc --enc=json $BASE_ARGS --name=name_m $HASH_MISSING - ' - - test_expect_success "verify background add worked (queued variant)" ' - ipfs pin remote ls --service=test_pin_svc --enc=json --name=name_m --status=queued,pinning | tee ls_out && - test_expect_code 0 grep -q name_m ls_out && - test_expect_code 0 grep -q $HASH_MISSING ls_out - ' - - test_expect_success "'ipfs pin remote add --background=false'" ' - test_expect_code 0 ipfs pin remote add --background=false --service=test_pin_svc --enc=json $BASE_ARGS --name=name_b $HASH_B - ' - - test_expect_success "verify foreground add worked" ' - ipfs pin remote ls --service=test_pin_svc --enc=json $ID_B | tee ls_out && - test_expect_code 0 grep -q name_b ls_out && - test_expect_code 0 grep -q pinned ls_out && - test_expect_code 0 grep -q $HASH_B ls_out - ' - - test_expect_success "'ipfs pin remote ls' for existing pins by multiple statuses" ' - ipfs pin remote ls --service=test_pin_svc --enc=json --status=queued,pinning,pinned,failed | tee ls_out && - test_expect_code 0 grep -q $HASH_A ls_out && - test_expect_code 0 grep -q $HASH_B ls_out && - test_expect_code 0 grep -q $HASH_MISSING ls_out - ' - - test_expect_success "'ipfs pin remote ls' for existing pins by CID" ' - ipfs pin remote ls --service=test_pin_svc --enc=json --cid=$HASH_B | tee ls_out && - test_expect_code 0 grep -q $HASH_B ls_out - ' - - test_expect_success "'ipfs pin remote ls' for existing pins by name" ' - ipfs pin remote ls --service=test_pin_svc --enc=json --name=name_a | tee ls_out && - test_expect_code 0 grep -q $HASH_A ls_out - ' - - test_expect_success "'ipfs pin remote ls' for ongoing pins by status" ' - ipfs pin remote ls --service=test_pin_svc --status=queued,pinning | tee ls_out && - test_expect_code 0 grep -q $HASH_MISSING ls_out - ' - - # --force is required only when more than a single match is found, - # so we add second pin with the same name (but different CID) to simulate that scenario - test_expect_success "'ipfs pin remote rm --name' fails without --force when matching multiple pins" ' - test_expect_code 0 ipfs pin remote add --service=test_pin_svc --enc=json $BASE_ARGS --name=name_b $HASH_C && - test_expect_code 1 ipfs pin remote rm --service=test_pin_svc --name=name_b 2> rm_out && - echo "Error: multiple remote pins are matching this query, add --force to confirm the bulk removal" > rm_expected && - test_cmp rm_out rm_expected - ' - - test_expect_success "'ipfs pin remote rm --name' without --force did not remove matching pins" ' - ipfs pin remote ls --service=test_pin_svc --enc=json --name=name_b | jq --raw-output .Cid | tee ls_out && - test_expect_code 0 grep -q $HASH_B ls_out && - test_expect_code 0 grep -q $HASH_C ls_out - ' - - test_expect_success "'ipfs pin remote rm --name' with --force removes all matching pins" ' - test_expect_code 0 ipfs pin remote rm --service=test_pin_svc --name=name_b --force && - ipfs pin remote ls --service=test_pin_svc --enc=json --name=name_b | jq --raw-output .Cid | tee ls_out && - test_expect_code 1 grep -q $HASH_B ls_out && - test_expect_code 1 grep -q $HASH_C ls_out - ' - - test_expect_success "'ipfs pin remote rm --force' removes all pinned items" ' - ipfs pin remote ls --service=test_pin_svc --enc=json --status=queued,pinning,pinned,failed | jq --raw-output .Cid | tee ls_out && - test_expect_code 0 grep -q $HASH_A ls_out && - test_expect_code 0 grep -q $HASH_MISSING ls_out && - ipfs pin remote rm --service=test_pin_svc --status=queued,pinning,pinned,failed --force && - ipfs pin remote ls --service=test_pin_svc --enc=json --status=queued,pinning,pinned,failed | jq --raw-output .Cid | tee ls_out && - test_expect_code 1 grep -q $HASH_A ls_out && - test_expect_code 1 grep -q $HASH_MISSING ls_out - ' - -} - -test_remote_pins "" - -test_kill_ipfs_daemon - -WARNINGMESSAGE="WARNING: the local node is offline and remote pinning may fail if there is no other provider for this CID" - -test_expect_success "'ipfs pin remote add' shows the warning message while offline" ' - test_expect_code 0 ipfs pin remote add --service=test_pin_svc --background $BASE_ARGS --name=name_a $HASH_A > actual && - test_expect_code 0 grep -q "$WARNINGMESSAGE" actual -' - -test_done - -# vim: ts=2 sw=2 sts=2 et: From ebdca5cf0221f0408ef5f504448f0c6e89fb9cf8 Mon Sep 17 00:00:00 2001 From: Gus Eggert Date: Thu, 30 Mar 2023 07:58:12 -0400 Subject: [PATCH 0597/1212] test: cancel workflows on same branch when new commit is added (#9771) This is pretty common when working through PRs and ends up causing tons of in-flight GitHub Actions workflows running because they aren't currently canceled when a new commit is added. This will cancel previous runs if a new commit is added on a branch (which is the behavior we had on CircleCI). --- .github/workflows/build.yml | 4 ++++ .github/workflows/codeql-analysis.yml | 4 ++++ .github/workflows/docker-build.yml | 4 ++++ .github/workflows/gobuild.yml | 4 ++++ .github/workflows/golang-analysis.yml | 4 ++++ .github/workflows/golint.yml | 4 ++++ .github/workflows/gotest.yml | 4 ++++ .github/workflows/sharness.yml | 4 ++++ 8 files changed, 32 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 15f467f74..9bc617fec 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -10,6 +10,10 @@ on: env: GO_VERSION: 1.19.1 +concurrency: + group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.event_name == 'push' && github.sha || github.ref }} + cancel-in-progress: true + jobs: interop-prep: if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index e2fa78bef..805b183a7 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -15,6 +15,10 @@ permissions: contents: read # to fetch code (actions/checkout) security-events: write # (github/codeql-action/autobuild) +concurrency: + group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.event_name == 'push' && github.sha || github.ref }} + cancel-in-progress: true + jobs: codeql: if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml index ea6c9d9b3..13334faa6 100644 --- a/.github/workflows/docker-build.yml +++ b/.github/workflows/docker-build.yml @@ -7,6 +7,10 @@ on: branches: - 'master' +concurrency: + group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.event_name == 'push' && github.sha || github.ref }} + cancel-in-progress: true + jobs: docker-build: if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' diff --git a/.github/workflows/gobuild.yml b/.github/workflows/gobuild.yml index f80fb8205..26dc66777 100644 --- a/.github/workflows/gobuild.yml +++ b/.github/workflows/gobuild.yml @@ -7,6 +7,10 @@ on: branches: - 'master' +concurrency: + group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.event_name == 'push' && github.sha || github.ref }} + cancel-in-progress: true + jobs: go-build-runner: if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' diff --git a/.github/workflows/golang-analysis.yml b/.github/workflows/golang-analysis.yml index d3fead57c..123e22403 100644 --- a/.github/workflows/golang-analysis.yml +++ b/.github/workflows/golang-analysis.yml @@ -10,6 +10,10 @@ on: permissions: contents: read # to fetch code (actions/checkout) +concurrency: + group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.event_name == 'push' && github.sha || github.ref }} + cancel-in-progress: true + jobs: go-check: if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' diff --git a/.github/workflows/golint.yml b/.github/workflows/golint.yml index 621a2807a..ae3683ff4 100644 --- a/.github/workflows/golint.yml +++ b/.github/workflows/golint.yml @@ -7,6 +7,10 @@ on: branches: - 'master' +concurrency: + group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.event_name == 'push' && github.sha || github.ref }} + cancel-in-progress: true + jobs: go-lint: if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' diff --git a/.github/workflows/gotest.yml b/.github/workflows/gotest.yml index 3867271ca..2c349d940 100644 --- a/.github/workflows/gotest.yml +++ b/.github/workflows/gotest.yml @@ -7,6 +7,10 @@ on: branches: - 'master' +concurrency: + group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.event_name == 'push' && github.sha || github.ref }} + cancel-in-progress: true + jobs: go-test: if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' diff --git a/.github/workflows/sharness.yml b/.github/workflows/sharness.yml index 90c622c3b..04779d15f 100644 --- a/.github/workflows/sharness.yml +++ b/.github/workflows/sharness.yml @@ -7,6 +7,10 @@ on: branches: - 'master' +concurrency: + group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.event_name == 'push' && github.sha || github.ref }} + cancel-in-progress: true + jobs: sharness-runner: if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' From 353dd49be239be651650c3ef3dfef83deebac58c Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Thu, 30 Mar 2023 09:20:37 -0400 Subject: [PATCH 0598/1212] refactor: switch gateway code to new API from go-libipfs (#9681) Co-authored-by: Marcin Rataj Co-authored-by: Henrique Dias --- core/corehttp/gateway.go | 155 +++++++++++------- core/node/dns.go | 72 +------- docs/examples/kubo-as-a-library/go.mod | 5 +- docs/examples/kubo-as-a-library/go.sum | 13 +- go.mod | 4 +- go.sum | 4 +- test/cli/fixtures/README.md | 72 ++++++++ .../cli/fixtures/TestGatewayHAMTDirectory.car | Bin 0 -> 1388518 bytes test/cli/fixtures/TestGatewayMultiRange.car | Bin 0 -> 3693246 bytes test/cli/gateway_range_test.go | 75 +++++++++ test/cli/harness/ipfs.go | 19 +++ test/sharness/t0117-gateway-block.sh | 15 ++ 12 files changed, 299 insertions(+), 135 deletions(-) create mode 100644 test/cli/fixtures/README.md create mode 100644 test/cli/fixtures/TestGatewayHAMTDirectory.car create mode 100644 test/cli/fixtures/TestGatewayMultiRange.car create mode 100644 test/cli/gateway_range_test.go diff --git a/core/corehttp/gateway.go b/core/corehttp/gateway.go index fdc91ae4c..75dba80c7 100644 --- a/core/corehttp/gateway.go +++ b/core/corehttp/gateway.go @@ -2,24 +2,26 @@ package corehttp import ( "context" + "errors" "fmt" "io" "net" "net/http" + "github.com/ipfs/boxo/blockservice" iface "github.com/ipfs/boxo/coreiface" - options "github.com/ipfs/boxo/coreiface/options" - nsopts "github.com/ipfs/boxo/coreiface/options/namesys" "github.com/ipfs/boxo/coreiface/path" + "github.com/ipfs/boxo/exchange/offline" "github.com/ipfs/boxo/files" "github.com/ipfs/boxo/gateway" "github.com/ipfs/boxo/namesys" - "github.com/ipfs/go-block-format" + offlineroute "github.com/ipfs/boxo/routing/offline" cid "github.com/ipfs/go-cid" version "github.com/ipfs/kubo" config "github.com/ipfs/kubo/config" core "github.com/ipfs/kubo/core" - coreapi "github.com/ipfs/kubo/core/coreapi" + "github.com/ipfs/kubo/core/node" + "github.com/libp2p/go-libp2p/core/routing" id "github.com/libp2p/go-libp2p/p2p/protocol/identify" "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" ) @@ -42,7 +44,7 @@ func GatewayOption(paths ...string) ServeOption { Headers: headers, } - gwAPI, err := newGatewayAPI(n) + gwAPI, err := newGatewayBackend(n) if err != nil { return nil, err } @@ -70,7 +72,7 @@ func HostnameOption() ServeOption { return nil, err } - gwAPI, err := newGatewayAPI(n) + gwAPI, err := newGatewayBackend(n) if err != nil { return nil, err } @@ -93,83 +95,120 @@ func VersionOption() ServeOption { } } -type gatewayAPI struct { - ns namesys.NameSystem - api iface.CoreAPI - offlineAPI iface.CoreAPI -} - -func newGatewayAPI(n *core.IpfsNode) (*gatewayAPI, error) { +func newGatewayBackend(n *core.IpfsNode) (gateway.IPFSBackend, error) { cfg, err := n.Repo.Config() if err != nil { return nil, err } - api, err := coreapi.NewCoreAPI(n, options.Api.FetchBlocks(!cfg.Gateway.NoFetch)) + bserv := n.Blocks + var vsRouting routing.ValueStore = n.Routing + nsys := n.Namesys + if cfg.Gateway.NoFetch { + bserv = blockservice.New(bserv.Blockstore(), offline.Exchange(bserv.Blockstore())) + + cs := cfg.Ipns.ResolveCacheSize + if cs == 0 { + cs = node.DefaultIpnsCacheSize + } + if cs < 0 { + return nil, fmt.Errorf("cannot specify negative resolve cache size") + } + + vsRouting = offlineroute.NewOfflineRouter(n.Repo.Datastore(), n.RecordValidator) + nsys, err = namesys.NewNameSystem(vsRouting, + namesys.WithDatastore(n.Repo.Datastore()), + namesys.WithDNSResolver(n.DNSResolver), + namesys.WithCache(cs)) + if err != nil { + return nil, fmt.Errorf("error constructing namesys: %w", err) + } + } + + gw, err := gateway.NewBlocksGateway(bserv, gateway.WithValueStore(vsRouting), gateway.WithNameSystem(nsys)) if err != nil { return nil, err } - offlineAPI, err := api.WithOptions(options.Api.Offline(true)) - if err != nil { - return nil, err + return &offlineGatewayErrWrapper{gwimpl: gw}, nil +} + +type offlineGatewayErrWrapper struct { + gwimpl gateway.IPFSBackend +} + +func offlineErrWrap(err error) error { + if errors.Is(err, iface.ErrOffline) { + return fmt.Errorf("%s : %w", err.Error(), gateway.ErrServiceUnavailable) } - - return &gatewayAPI{ - ns: n.Namesys, - api: api, - offlineAPI: offlineAPI, - }, nil + return err } -func (gw *gatewayAPI) GetUnixFsNode(ctx context.Context, pth path.Resolved) (files.Node, error) { - return gw.api.Unixfs().Get(ctx, pth) +func (o *offlineGatewayErrWrapper) Get(ctx context.Context, path gateway.ImmutablePath) (gateway.ContentPathMetadata, *gateway.GetResponse, error) { + md, n, err := o.gwimpl.Get(ctx, path) + err = offlineErrWrap(err) + return md, n, err } -func (gw *gatewayAPI) LsUnixFsDir(ctx context.Context, pth path.Resolved) (<-chan iface.DirEntry, error) { - // Optimization: use Unixfs.Ls without resolving children, but using the - // cumulative DAG size as the file size. This allows for a fast listing - // while keeping a good enough Size field. - return gw.api.Unixfs().Ls(ctx, pth, - options.Unixfs.ResolveChildren(false), - options.Unixfs.UseCumulativeSize(true), - ) +func (o *offlineGatewayErrWrapper) GetRange(ctx context.Context, path gateway.ImmutablePath, ranges ...gateway.GetRange) (gateway.ContentPathMetadata, files.File, error) { + md, n, err := o.gwimpl.GetRange(ctx, path, ranges...) + err = offlineErrWrap(err) + return md, n, err } -func (gw *gatewayAPI) GetBlock(ctx context.Context, cid cid.Cid) (blocks.Block, error) { - r, err := gw.api.Block().Get(ctx, path.IpfsPath(cid)) - if err != nil { - return nil, err - } - - data, err := io.ReadAll(r) - if err != nil { - return nil, err - } - - return blocks.NewBlockWithCid(data, cid) +func (o *offlineGatewayErrWrapper) GetAll(ctx context.Context, path gateway.ImmutablePath) (gateway.ContentPathMetadata, files.Node, error) { + md, n, err := o.gwimpl.GetAll(ctx, path) + err = offlineErrWrap(err) + return md, n, err } -func (gw *gatewayAPI) GetIPNSRecord(ctx context.Context, c cid.Cid) ([]byte, error) { - return gw.api.Routing().Get(ctx, "/ipns/"+c.String()) +func (o *offlineGatewayErrWrapper) GetBlock(ctx context.Context, path gateway.ImmutablePath) (gateway.ContentPathMetadata, files.File, error) { + md, n, err := o.gwimpl.GetBlock(ctx, path) + err = offlineErrWrap(err) + return md, n, err } -func (gw *gatewayAPI) GetDNSLinkRecord(ctx context.Context, hostname string) (path.Path, error) { - p, err := gw.ns.Resolve(ctx, "/ipns/"+hostname, nsopts.Depth(1)) - if err == namesys.ErrResolveRecursion { - err = nil - } - return path.New(p.String()), err +func (o *offlineGatewayErrWrapper) Head(ctx context.Context, path gateway.ImmutablePath) (gateway.ContentPathMetadata, files.Node, error) { + md, n, err := o.gwimpl.Head(ctx, path) + err = offlineErrWrap(err) + return md, n, err } -func (gw *gatewayAPI) IsCached(ctx context.Context, pth path.Path) bool { - _, err := gw.offlineAPI.Block().Stat(ctx, pth) - return err == nil +func (o *offlineGatewayErrWrapper) ResolvePath(ctx context.Context, path gateway.ImmutablePath) (gateway.ContentPathMetadata, error) { + md, err := o.gwimpl.ResolvePath(ctx, path) + err = offlineErrWrap(err) + return md, err } -func (gw *gatewayAPI) ResolvePath(ctx context.Context, pth path.Path) (path.Resolved, error) { - return gw.api.ResolvePath(ctx, pth) +func (o *offlineGatewayErrWrapper) GetCAR(ctx context.Context, path gateway.ImmutablePath) (gateway.ContentPathMetadata, io.ReadCloser, <-chan error, error) { + md, data, errCh, err := o.gwimpl.GetCAR(ctx, path) + err = offlineErrWrap(err) + return md, data, errCh, err } +func (o *offlineGatewayErrWrapper) IsCached(ctx context.Context, path path.Path) bool { + return o.gwimpl.IsCached(ctx, path) +} + +func (o *offlineGatewayErrWrapper) GetIPNSRecord(ctx context.Context, c cid.Cid) ([]byte, error) { + rec, err := o.gwimpl.GetIPNSRecord(ctx, c) + err = offlineErrWrap(err) + return rec, err +} + +func (o *offlineGatewayErrWrapper) ResolveMutable(ctx context.Context, path path.Path) (gateway.ImmutablePath, error) { + imPath, err := o.gwimpl.ResolveMutable(ctx, path) + err = offlineErrWrap(err) + return imPath, err +} + +func (o *offlineGatewayErrWrapper) GetDNSLinkRecord(ctx context.Context, s string) (path.Path, error) { + p, err := o.gwimpl.GetDNSLinkRecord(ctx, s) + err = offlineErrWrap(err) + return p, err +} + +var _ gateway.IPFSBackend = (*offlineGatewayErrWrapper)(nil) + var defaultPaths = []string{"/ipfs/", "/ipns/", "/api/", "/p2p/"} var subdomainGatewaySpec = &gateway.Specification{ diff --git a/core/node/dns.go b/core/node/dns.go index d66cccc54..d338e0e8b 100644 --- a/core/node/dns.go +++ b/core/node/dns.go @@ -1,88 +1,20 @@ package node import ( - "fmt" "math" - "strings" "time" + "github.com/ipfs/boxo/gateway" config "github.com/ipfs/kubo/config" doh "github.com/libp2p/go-doh-resolver" madns "github.com/multiformats/go-multiaddr-dns" - - "github.com/miekg/dns" ) -var defaultResolvers = map[string]string{ - "eth.": "https://resolver.cloudflare-eth.com/dns-query", - "crypto.": "https://resolver.cloudflare-eth.com/dns-query", -} - -func newResolver(url string, opts ...doh.Option) (madns.BasicResolver, error) { - if !strings.HasPrefix(url, "https://") { - return nil, fmt.Errorf("invalid resolver url: %s", url) - } - - return doh.NewResolver(url, opts...) -} - func DNSResolver(cfg *config.Config) (*madns.Resolver, error) { - var opts []madns.Option - var err error - var dohOpts []doh.Option if !cfg.DNS.MaxCacheTTL.IsDefault() { dohOpts = append(dohOpts, doh.WithMaxCacheTTL(cfg.DNS.MaxCacheTTL.WithDefault(time.Duration(math.MaxUint32)*time.Second))) } - domains := make(map[string]struct{}) // to track overridden default resolvers - rslvrs := make(map[string]madns.BasicResolver) // to reuse resolvers for the same URL - - for domain, url := range cfg.DNS.Resolvers { - if domain != "." && !dns.IsFqdn(domain) { - return nil, fmt.Errorf("invalid domain %s; must be FQDN", domain) - } - - domains[domain] = struct{}{} - if url == "" { - // allow overriding of implicit defaults with the default resolver - continue - } - - rslv, ok := rslvrs[url] - if !ok { - rslv, err = newResolver(url, dohOpts...) - if err != nil { - return nil, fmt.Errorf("bad resolver for %s: %w", domain, err) - } - rslvrs[url] = rslv - } - - if domain != "." { - opts = append(opts, madns.WithDomainResolver(domain, rslv)) - } else { - opts = append(opts, madns.WithDefaultResolver(rslv)) - } - } - - // fill in defaults if not overridden by the user - for domain, url := range defaultResolvers { - _, ok := domains[domain] - if ok { - continue - } - - rslv, ok := rslvrs[url] - if !ok { - rslv, err = newResolver(url) - if err != nil { - return nil, fmt.Errorf("bad resolver for %s: %w", domain, err) - } - rslvrs[url] = rslv - } - - opts = append(opts, madns.WithDomainResolver(domain, rslv)) - } - - return madns.NewResolver(opts...) + return gateway.NewDNSResolver(cfg.DNS.Resolvers, dohOpts...) } diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index bcbdf6d4b..06dbb08c1 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.18 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.8.0-rc2 + github.com/ipfs/boxo v0.8.0-rc3 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.26.4 github.com/multiformats/go-multiaddr v0.8.0 @@ -41,6 +41,7 @@ require ( github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5 // indirect github.com/flynn/noise v1.0.0 // indirect github.com/francoispqt/gojay v1.2.13 // indirect + github.com/gabriel-vasile/mimetype v1.4.1 // indirect github.com/go-logr/logr v1.2.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect @@ -77,6 +78,7 @@ require ( github.com/ipfs/go-ipfs-delay v0.0.1 // indirect github.com/ipfs/go-ipfs-ds-help v1.1.0 // indirect github.com/ipfs/go-ipfs-pq v0.0.3 // indirect + github.com/ipfs/go-ipfs-redirects-file v0.1.1 // indirect github.com/ipfs/go-ipfs-util v0.0.2 // indirect github.com/ipfs/go-ipld-cbor v0.0.6 // indirect github.com/ipfs/go-ipld-format v0.4.0 // indirect @@ -153,6 +155,7 @@ require ( github.com/samber/lo v1.36.0 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect + github.com/ucarion/urlpath v0.0.0-20200424170820-7ccc79b76bbb // indirect github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc // indirect github.com/whyrusleeping/cbor-gen v0.0.0-20230126041949-52956bd4c9aa // indirect github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 235e25c83..8da997a7c 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -170,6 +170,8 @@ github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0X github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= +github.com/gabriel-vasile/mimetype v1.4.1 h1:TRWk7se+TOjCYgRth7+1/OYLNiRNIotknkFtf/dnN7Q= +github.com/gabriel-vasile/mimetype v1.4.1/go.mod h1:05Vi0w3Y9c/lNvJOdmIwvrrAhX3rYhfQQCaf9VJcv7M= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= @@ -335,8 +337,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.8.0-rc2 h1:JnSlLKlIURiVsTfPs1BLv3NNCygjV1b07wGva3w4sLY= -github.com/ipfs/boxo v0.8.0-rc2/go.mod h1:EgDiNox/+W/+ySwEotRrHlvdmrhbSAB4p22ELg+ZsCc= +github.com/ipfs/boxo v0.8.0-rc3 h1:rttpGdhLE0zeTec8f2/e5YDgCYzEQf7dI4eRglu2ktc= +github.com/ipfs/boxo v0.8.0-rc3/go.mod h1:RIsi4CnTyQ7AUsNn5gXljJYZlQrHBMnJp94p73liFiA= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= @@ -393,6 +395,8 @@ github.com/ipfs/go-ipfs-files v0.3.0 h1:fallckyc5PYjuMEitPNrjRfpwl7YFt69heCOUhsb github.com/ipfs/go-ipfs-posinfo v0.0.1 h1:Esoxj+1JgSjX0+ylc0hUmJCOv6V2vFoZiETLR6OtpRs= github.com/ipfs/go-ipfs-pq v0.0.3 h1:YpoHVJB+jzK15mr/xsWC574tyDLkezVrDNeaalQBsTE= github.com/ipfs/go-ipfs-pq v0.0.3/go.mod h1:btNw5hsHBpRcSSgZtiNm/SLj5gYIZ18AKtv3kERkRb4= +github.com/ipfs/go-ipfs-redirects-file v0.1.1 h1:Io++k0Vf/wK+tfnhEh63Yte1oQK5VGT2hIEYpD0Rzx8= +github.com/ipfs/go-ipfs-redirects-file v0.1.1/go.mod h1:tAwRjCV0RjLTjH8DR/AU7VYvfQECg+lpUy2Mdzv7gyk= github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyBCNzQxlJBc= github.com/ipfs/go-ipfs-util v0.0.2 h1:59Sswnk1MFaiq+VcaknX7aYEyGyGDAA73ilhEK2POp8= github.com/ipfs/go-ipfs-util v0.0.2/go.mod h1:CbPtkWJzjLdEcezDns2XYaehFVNXG9zrdrtMecczcsQ= @@ -800,8 +804,11 @@ github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70 github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= github.com/thoas/go-funk v0.9.1 h1:O549iLZqPpTUQ10ykd26sZhzD+rmR5pWhuElrhbC20M= +github.com/tj/assert v0.0.3 h1:Df/BlaZ20mq6kuai7f5z2TvPFiwC3xaWJSDQNiIS3Rk= github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c h1:u6SKchux2yDvFQnDHS3lPnIRmfVJ5Sxy3ao2SIdysLQ= github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM= +github.com/ucarion/urlpath v0.0.0-20200424170820-7ccc79b76bbb h1:Ywfo8sUltxogBpFuMOFRrrSifO788kAFxmvVw31PtQQ= +github.com/ucarion/urlpath v0.0.0-20200424170820-7ccc79b76bbb/go.mod h1:ikPs9bRWicNw3S7XpJ8sK/smGwU9WcSVU3dy9qahYBM= github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= @@ -997,6 +1004,7 @@ golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1088,6 +1096,7 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= diff --git a/go.mod b/go.mod index 3648783d5..c3785381c 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/gogo/protobuf v1.3.2 github.com/google/uuid v1.3.0 github.com/hashicorp/go-multierror v1.1.1 - github.com/ipfs/boxo v0.8.0-rc2 + github.com/ipfs/boxo v0.8.0-rc3 github.com/ipfs/go-block-format v0.1.2 github.com/ipfs/go-cid v0.4.0 github.com/ipfs/go-cidutil v0.1.0 @@ -55,7 +55,6 @@ require ( github.com/libp2p/go-libp2p-routing-helpers v0.6.1 github.com/libp2p/go-libp2p-testing v0.12.0 github.com/libp2p/go-socket-activation v0.1.0 - github.com/miekg/dns v1.1.50 github.com/mitchellh/go-homedir v1.1.0 github.com/multiformats/go-multiaddr v0.8.0 github.com/multiformats/go-multiaddr-dns v0.3.1 @@ -173,6 +172,7 @@ require ( github.com/mattn/go-runewidth v0.0.4 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect + github.com/miekg/dns v1.1.50 // indirect github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect github.com/minio/sha256-simd v1.0.0 // indirect diff --git a/go.sum b/go.sum index 95daffbf7..5822ea898 100644 --- a/go.sum +++ b/go.sum @@ -355,8 +355,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.8.0-rc2 h1:JnSlLKlIURiVsTfPs1BLv3NNCygjV1b07wGva3w4sLY= -github.com/ipfs/boxo v0.8.0-rc2/go.mod h1:EgDiNox/+W/+ySwEotRrHlvdmrhbSAB4p22ELg+ZsCc= +github.com/ipfs/boxo v0.8.0-rc3 h1:rttpGdhLE0zeTec8f2/e5YDgCYzEQf7dI4eRglu2ktc= +github.com/ipfs/boxo v0.8.0-rc3/go.mod h1:RIsi4CnTyQ7AUsNn5gXljJYZlQrHBMnJp94p73liFiA= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= diff --git a/test/cli/fixtures/README.md b/test/cli/fixtures/README.md new file mode 100644 index 000000000..dab926be4 --- /dev/null +++ b/test/cli/fixtures/README.md @@ -0,0 +1,72 @@ +# Dataset Description / Sources + +TestGatewayHAMTDirectory.car generated with: + +```bash +ipfs version +# ipfs version 0.19.0 + +export HAMT_DIR=bafybeiggvykl7skb2ndlmacg2k5modvudocffxjesexlod2pfvg5yhwrqm +export IPFS_PATH=$(mktemp -d) + +# Init and start daemon, ensure we have an empty repository. +ipfs init --empty-repo +ipfs daemon &> /dev/null & +export IPFS_PID=$! + +# Retrieve the directory listing, forcing the daemon to download all required DAGs. Kill daemon. +curl -o dir.html http://127.0.0.1:8080/ipfs/$HAMT_DIR/ +kill $IPFS_PID + +# Get the list with all the downloaded refs and sanity check. +ipfs refs local > required_refs +cat required_refs | wc -l +# 962 + +# Get the list of all the files CIDs inside the directory and sanity check. +cat dir.html| pup '#content tbody .ipfs-hash attr{href}' | sed 's/\/ipfs\///g;s/\?filename=.*//g' > files_refs +cat files_refs | wc -l +# 10100 + +# Make and export our fixture. +ipfs files mkdir --cid-version 1 /fixtures +cat required_refs | xargs -I {} ipfs files cp /ipfs/{} /fixtures/{} +cat files_refs | ipfs files write --create /fixtures/files_refs +export FIXTURE_CID=$(ipfs files stat --hash /fixtures/) +echo $FIXTURE_CID +# bafybeig3yoibxe56aolixqa4zk55gp5sug3qgaztkakpndzk2b2ynobd4i +ipfs dag export $FIXTURE_CID > TestGatewayHAMTDirectory.car +``` + +TestGatewayMultiRange.car generated with: + + +```sh +ipfs version +# ipfs version 0.19.0 + +export FILE_CID=bafybeiae5abzv6j3ucqbzlpnx3pcqbr2otbnpot7d2k5pckmpymin4guau +export IPFS_PATH=$(mktemp -d) + +# Init and start daemon, ensure we have an empty repository. +ipfs init --empty-repo +ipfs daemon &> /dev/null & +export IPFS_PID=$! + +# Get a specific byte range from the file. +curl http://127.0.0.1:8080/ipfs/$FILE_CID -i -H "Range: bytes=1276-1279, 29839070-29839080" +kill $IPFS_PID + +# Get the list with all the downloaded refs and sanity check. +ipfs refs local > required_refs +cat required_refs | wc -l +# 19 + +# Make and export our fixture. +ipfs files mkdir --cid-version 1 /fixtures +cat required_refs | xargs -I {} ipfs files cp /ipfs/{} /fixtures/{} +export FIXTURE_CID=$(ipfs files stat --hash /fixtures/) +echo $FIXTURE_CID +# bafybeicgsg3lwyn3yl75lw7sn4zhyj5dxtb7wfxwscpq6yzippetmr2w3y +ipfs dag export $FIXTURE_CID > TestGatewayMultiRange.car +``` diff --git a/test/cli/fixtures/TestGatewayHAMTDirectory.car b/test/cli/fixtures/TestGatewayHAMTDirectory.car new file mode 100644 index 0000000000000000000000000000000000000000..2cb03c6c8792d0f2e5db2923d818f8c35c51620e GIT binary patch literal 1388518 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ÏVf@0MFccG4xeKBGr{ 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
    lW!=;9T>zK8{nfSXs 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π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%0D(N8>>ke(P*^9^No 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 YtmdG)$E4D`TeF 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

    oqsdtFO)_2Q!cUS1a+NTwJGYcE#$bchct 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∨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

    2^n`%nMHViJ-UKME_ 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

    (#$47l0EW5LLIcxN%81KjM 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�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 cm?@Cm#$sA;;mT3*{(|fSg)dgv|1Ks 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�i+ey$u8p?m)JleTtGCdaU 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 literal 0 HcmV?d00001 diff --git a/test/cli/fixtures/TestGatewayMultiRange.car b/test/cli/fixtures/TestGatewayMultiRange.car new file mode 100644 index 0000000000000000000000000000000000000000..993d86e33dbfe6cc8710a8a1d2bf5cdc8259c185 GIT binary patch literal 3693246 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

    w0rU4-sYwlCQ<o<8MJI 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%0D5L-= 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%0DuU(dX>AOz*=Bt)2yyms_ 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 z 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 z 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

    92KgRttx%&e92O! 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 z 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
    #R+*CE%;Rt0 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�gHqn&Z`nFF|}KBQQQ3nFXxllY1~ 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

    ?^LLd-!GRD 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�S6G;;q82*|>GG*aZ5OE`e=_Rz&c~PGdn50o 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 expected_file_block_single_range && + curl -sX GET -H "Accept: application/vnd.ipld.raw" -H "Range: bytes=6-16" "http://127.0.0.1:$GWAY_PORT/ipfs/$FILE_CID" -o curl_ipfs_file_block_single_range && + test_cmp expected_file_block_single_range curl_ipfs_file_block_single_range + ' + + test_expect_success "GET for application/vnd.ipld.raw with multiple range request includes correct bytes" ' + curl -sX GET -H "Accept: application/vnd.ipld.raw" -H "Range: bytes=6-16,0-4" "http://127.0.0.1:$GWAY_PORT/ipfs/$FILE_CID" -o curl_ipfs_file_block_multiple_range && + test_should_contain "Content-Range: bytes 6-16/31" curl_ipfs_file_block_multiple_range && + test_should_contain "Content-Type: application/vnd.ipld.raw" curl_ipfs_file_block_multiple_range && + test_should_contain "application" curl_ipfs_file_block_multiple_range && + test_should_contain "Content-Range: bytes 0-4/31" curl_ipfs_file_block_multiple_range && + test_should_contain "hello" curl_ipfs_file_block_multiple_range + ' + # Make sure expected HTTP headers are returned with the block bytes test_expect_success "GET response for application/vnd.ipld.raw has expected Content-Type" ' From a09c8df24d2eaac3ce99c4e6184f47bb218193cf Mon Sep 17 00:00:00 2001 From: Gus Eggert Date: Thu, 30 Mar 2023 16:08:43 -0400 Subject: [PATCH 0599/1212] fix: remove timeout on default DHT operations (#9783) * fix: remove timeout on default DHT operations This removes the timeout by default for DHT operations. In particular this causes issues with ProvideMany requests which can take an indeterminate amount of time, but really these should just respect context timeouts by default. Users can still specify timeouts here if they want, but by default they will be set to "0" which means "no timeout". This is unlikely to break existing users of custom routing, because there was previously no utility in configuring a router with timeout=0 because that would cause the router to immediately fail, so it is unlikely (and incorrect) if anybody was using timeout=0. * fix: remove 5m timeout on ProvideManyRouter For context see https://github.com/ipfs/kubo/pull/9783/commits/5fda291b6665abe7aaf6a3f17687474dc85d8db4 --------- Co-authored-by: Marcin Rataj --- core/node/libp2p/routing.go | 1 - core/node/libp2p/routingopt.go | 1 - docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- 6 files changed, 6 insertions(+), 8 deletions(-) diff --git a/core/node/libp2p/routing.go b/core/node/libp2p/routing.go index 8de3ed10a..f96f772e1 100644 --- a/core/node/libp2p/routing.go +++ b/core/node/libp2p/routing.go @@ -186,7 +186,6 @@ func Routing(in p2pOnlineRoutingIn) irouting.ProvideManyRouter { var cRouters []*routinghelpers.ParallelRouter for _, v := range routers { cRouters = append(cRouters, &routinghelpers.ParallelRouter{ - Timeout: 5 * time.Minute, IgnoreError: true, Router: v.Routing, }) diff --git a/core/node/libp2p/routingopt.go b/core/node/libp2p/routingopt.go index d54f37acc..8a69e181b 100644 --- a/core/node/libp2p/routingopt.go +++ b/core/node/libp2p/routingopt.go @@ -65,7 +65,6 @@ func ConstructDefaultRouting(peerID string, addrs []string, privKey string, rout routers = append(routers, &routinghelpers.ParallelRouter{ Router: dhtRouting, IgnoreError: false, - Timeout: 5 * time.Minute, // https://github.com/ipfs/kubo/pull/9475#discussion_r1042501333 ExecuteAfter: 0, }) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 06dbb08c1..84f2b812a 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -108,7 +108,7 @@ require ( github.com/libp2p/go-libp2p-pubsub v0.9.0 // indirect github.com/libp2p/go-libp2p-pubsub-router v0.6.0 // indirect github.com/libp2p/go-libp2p-record v0.2.0 // indirect - github.com/libp2p/go-libp2p-routing-helpers v0.6.1 // indirect + github.com/libp2p/go-libp2p-routing-helpers v0.6.2 // indirect github.com/libp2p/go-libp2p-xor v0.1.0 // indirect github.com/libp2p/go-mplex v0.7.0 // indirect github.com/libp2p/go-msgio v0.3.0 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 8da997a7c..a92be7d75 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -530,8 +530,8 @@ github.com/libp2p/go-libp2p-pubsub-router v0.6.0 h1:D30iKdlqDt5ZmLEYhHELCMRj8b4s github.com/libp2p/go-libp2p-pubsub-router v0.6.0/go.mod h1:FY/q0/RBTKsLA7l4vqC2cbRbOvyDotg8PJQ7j8FDudE= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= github.com/libp2p/go-libp2p-record v0.2.0/go.mod h1:I+3zMkvvg5m2OcSdoL0KPljyJyvNDFGKX7QdlpYUcwk= -github.com/libp2p/go-libp2p-routing-helpers v0.6.1 h1:tI3rHOf/FDQsxC2pHBaOZiqPJ0MZYyzGAf4V45xla4U= -github.com/libp2p/go-libp2p-routing-helpers v0.6.1/go.mod h1:R289GUxUMzRXIbWGSuUUTPrlVJZ3Y/pPz495+qgXJX8= +github.com/libp2p/go-libp2p-routing-helpers v0.6.2 h1:u6SWfX+3LoqqTAFxWVl79RkcIDE3Zsay5d+JohlEBaE= +github.com/libp2p/go-libp2p-routing-helpers v0.6.2/go.mod h1:R289GUxUMzRXIbWGSuUUTPrlVJZ3Y/pPz495+qgXJX8= github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA= github.com/libp2p/go-libp2p-xor v0.1.0 h1:hhQwT4uGrBcuAkUGXADuPltalOdpf9aag9kaYNT2tLA= github.com/libp2p/go-libp2p-xor v0.1.0/go.mod h1:LSTM5yRnjGZbWNTA/hRwq2gGFrvRIbQJscoIL/u6InY= diff --git a/go.mod b/go.mod index c3785381c..11b41d5cc 100644 --- a/go.mod +++ b/go.mod @@ -52,7 +52,7 @@ require ( github.com/libp2p/go-libp2p-pubsub v0.9.0 github.com/libp2p/go-libp2p-pubsub-router v0.6.0 github.com/libp2p/go-libp2p-record v0.2.0 - github.com/libp2p/go-libp2p-routing-helpers v0.6.1 + github.com/libp2p/go-libp2p-routing-helpers v0.6.2 github.com/libp2p/go-libp2p-testing v0.12.0 github.com/libp2p/go-socket-activation v0.1.0 github.com/mitchellh/go-homedir v1.1.0 diff --git a/go.sum b/go.sum index 5822ea898..925a7278f 100644 --- a/go.sum +++ b/go.sum @@ -562,8 +562,8 @@ github.com/libp2p/go-libp2p-pubsub-router v0.6.0 h1:D30iKdlqDt5ZmLEYhHELCMRj8b4s github.com/libp2p/go-libp2p-pubsub-router v0.6.0/go.mod h1:FY/q0/RBTKsLA7l4vqC2cbRbOvyDotg8PJQ7j8FDudE= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= github.com/libp2p/go-libp2p-record v0.2.0/go.mod h1:I+3zMkvvg5m2OcSdoL0KPljyJyvNDFGKX7QdlpYUcwk= -github.com/libp2p/go-libp2p-routing-helpers v0.6.1 h1:tI3rHOf/FDQsxC2pHBaOZiqPJ0MZYyzGAf4V45xla4U= -github.com/libp2p/go-libp2p-routing-helpers v0.6.1/go.mod h1:R289GUxUMzRXIbWGSuUUTPrlVJZ3Y/pPz495+qgXJX8= +github.com/libp2p/go-libp2p-routing-helpers v0.6.2 h1:u6SWfX+3LoqqTAFxWVl79RkcIDE3Zsay5d+JohlEBaE= +github.com/libp2p/go-libp2p-routing-helpers v0.6.2/go.mod h1:R289GUxUMzRXIbWGSuUUTPrlVJZ3Y/pPz495+qgXJX8= github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA= github.com/libp2p/go-libp2p-testing v0.12.0/go.mod h1:KcGDRXyN7sQCllucn1cOOS+Dmm7ujhfEyXQL5lvkcPg= github.com/libp2p/go-libp2p-xor v0.1.0 h1:hhQwT4uGrBcuAkUGXADuPltalOdpf9aag9kaYNT2tLA= From 95dd93b24370168f9538cb9c5b65b39e463c752c Mon Sep 17 00:00:00 2001 From: galargh Date: Thu, 30 Mar 2023 19:28:46 +0200 Subject: [PATCH 0600/1212] ci: ignore js-js interop test cases --- .github/workflows/build.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9bc617fec..ddb3382c6 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -74,7 +74,8 @@ jobs: npm install kubo-rpc-client@^3.0.1 npm install ipfs-interop@^10.0.1 working-directory: interop - - run: npx ipfs-interop -- -t node + # Run the interop tests while ignoring the js-js interop test cases + - run: npx ipfs-interop -- -t node --grep '^(?!.*(js\d? -> js\d?|js-js-js))' env: LIBP2P_TCP_REUSEPORT: false LIBP2P_ALLOW_WEAK_RSA_KEYS: 1 From c81d2da87103a731260e3d62c2bf060ad0ded870 Mon Sep 17 00:00:00 2001 From: Piotr Galar Date: Fri, 31 Mar 2023 12:07:23 +0200 Subject: [PATCH 0601/1212] ci: add gateway-conformance tests for kubo-gateway (#9780) --- .github/workflows/gateway-conformance.yml | 86 +++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 .github/workflows/gateway-conformance.yml diff --git a/.github/workflows/gateway-conformance.yml b/.github/workflows/gateway-conformance.yml new file mode 100644 index 000000000..588aec346 --- /dev/null +++ b/.github/workflows/gateway-conformance.yml @@ -0,0 +1,86 @@ +name: Gateway Conformance + +on: + push: + branches: + - master + pull_request: + +concurrency: + group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.event_name == 'push' && github.sha || github.ref }} + cancel-in-progress: true + +defaults: + run: + shell: bash + +jobs: + gateway-conformance: + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + # 1. Download the gateway-conformance fixtures + - name: Download gateway-conformance fixtures + uses: ipfs/gateway-conformance/.github/actions/extract-fixtures@v0.0 + with: + output: fixtures + + # 2. Build the kubo-gateway + - name: Setup Go + uses: actions/setup-go@v3 + with: + go-version: 1.19.x + - name: Checkout kubo-gateway + uses: actions/checkout@v3 + with: + path: kubo-gateway + - name: Build kubo-gateway + run: make build + working-directory: kubo-gateway + + # 3. Start the kubo-gateway + - name: Start kubo-gateway + env: + GATEWAY_PUBLIC_GATEWAYS: | + { + "example.com": { + "UseSubdomains": true, + "Paths": ["/ipfs", "/ipns"] + }, + "localhost": { + "UseSubdomains": true, + "InlineDNSLink": true, + "Paths": ["/ipfs", "/ipns"] + } + } + run: | + ./ipfs init + ./ipfs config --json Gateway.PublicGateways "$GATEWAY_PUBLIC_GATEWAYS" + ./ipfs daemon --offline & + working-directory: kubo-gateway/cmd/ipfs + + # 4. Populate the Kubo gateway with the gateway-conformance fixtures + - name: Import fixtures + run: find ./fixtures -name '*.car' -exec kubo-gateway/cmd/ipfs/ipfs dag import --pin-roots=false {} \; + + # 5. Run the gateway-conformance tests + - name: Run gateway-conformance tests + uses: ipfs/gateway-conformance/.github/actions/test@v0.0 + with: + gateway-url: http://127.0.0.1:8080 + json: output.json + xml: output.xml + html: output.html + markdown: output.md + args: -skip 'TestGatewayCar/GET_response_for_application/vnd.ipld.car/Header_Content-Length' + + # 6. Upload the results + - name: Upload MD summary + if: failure() || success() + run: cat output.md >> $GITHUB_STEP_SUMMARY + - name: Upload HTML report + if: failure() || success() + uses: actions/upload-artifact@v3 + with: + name: gateway-conformance.html + path: output.html From 55587d8e419078858ba16e4ed4e1b2ab6069398e Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Fri, 31 Mar 2023 15:06:23 +0200 Subject: [PATCH 0602/1212] feat!: make --empty-repo default (#9758) Context: https://github.com/ipfs/kubo/pull/9758#pullrequestreview-1366898875 --- cmd/ipfs/init.go | 3 ++- test/cli/init_test.go | 18 +++++++++--------- test/sharness/lib/test-lib.sh | 4 ++-- test/sharness/t0025-datastores.sh | 4 ++-- test/sharness/t0054-dag-car-import-export.sh | 2 +- test/sharness/t0080-repo.sh | 2 +- test/sharness/t0100-name.sh | 10 +++++----- .../t0600-issues-and-regressions-online.sh | 2 +- 8 files changed, 23 insertions(+), 22 deletions(-) diff --git a/cmd/ipfs/init.go b/cmd/ipfs/init.go index 3856f2ff4..28845faa5 100644 --- a/cmd/ipfs/init.go +++ b/cmd/ipfs/init.go @@ -28,6 +28,7 @@ const ( algorithmDefault = options.Ed25519Key algorithmOptionName = "algorithm" bitsOptionName = "bits" + emptyRepoDefault = true emptyRepoOptionName = "empty-repo" profileOptionName = "profile" ) @@ -61,7 +62,7 @@ environment variable: Options: []cmds.Option{ cmds.StringOption(algorithmOptionName, "a", "Cryptographic algorithm to use for key generation.").WithDefault(algorithmDefault), cmds.IntOption(bitsOptionName, "b", "Number of bits to use in the generated RSA private key."), - cmds.BoolOption(emptyRepoOptionName, "e", "Don't add and pin help files to the local storage."), + cmds.BoolOption(emptyRepoOptionName, "e", "Don't add and pin help files to the local storage.").WithDefault(emptyRepoDefault), cmds.StringOption(profileOptionName, "p", "Apply profile settings to config. Multiple profiles can be separated by ','"), // TODO need to decide whether to expose the override as a file or a diff --git a/test/cli/init_test.go b/test/cli/init_test.go index 359856e6b..a45ef05d5 100644 --- a/test/cli/init_test.go +++ b/test/cli/init_test.go @@ -33,9 +33,7 @@ func testInitAlgo(t *testing.T, initFlags []string, expOutputName string, expPee lines := []string{ fmt.Sprintf("generating %s keypair...done", expOutputName), fmt.Sprintf("peer identity: %s", node.PeerID().String()), - fmt.Sprintf("initializing IPFS node at %s", node.Dir), - "to get started, enter:", - fmt.Sprintf("\n\tipfs cat /ipfs/%s/readme\n\n", CIDWelcomeDocs), + fmt.Sprintf("initializing IPFS node at %s\n", node.Dir), } expectedInitOutput := strings.Join(lines, "\n") assert.Equal(t, expectedInitOutput, initRes.Stdout.String()) @@ -54,26 +52,28 @@ func testInitAlgo(t *testing.T, initFlags []string, expOutputName string, expPee res := node.IPFS("config", "Mounts.IPFS") assert.Equal(t, "/ipfs", res.Stdout.Trimmed()) - node.IPFS("cat", fmt.Sprintf("/ipfs/%s/readme", CIDWelcomeDocs)) + catRes := node.RunIPFS("cat", fmt.Sprintf("/ipfs/%s/readme", CIDWelcomeDocs)) + assert.NotEqual(t, 0, catRes.ExitErr.ExitCode(), "welcome readme doesn't exist") }) - t.Run("init empty repo", func(t *testing.T) { + t.Run("init without empty repo", func(t *testing.T) { t.Parallel() node := harness.NewT(t).NewNode() - initRes := node.IPFS(StrCat("init", "--empty-repo", initFlags)...) + initRes := node.IPFS(StrCat("init", "--empty-repo=false", initFlags)...) validatePeerID(t, node.PeerID(), expPeerIDPubKeyErr, expPeerIDPubKeyType) lines := []string{ fmt.Sprintf("generating %s keypair...done", expOutputName), fmt.Sprintf("peer identity: %s", node.PeerID().String()), - fmt.Sprintf("initializing IPFS node at %s\n", node.Dir), + fmt.Sprintf("initializing IPFS node at %s", node.Dir), + "to get started, enter:", + fmt.Sprintf("\n\tipfs cat /ipfs/%s/readme\n\n", CIDWelcomeDocs), } expectedEmptyInitOutput := strings.Join(lines, "\n") assert.Equal(t, expectedEmptyInitOutput, initRes.Stdout.String()) - catRes := node.RunIPFS("cat", fmt.Sprintf("/ipfs/%s/readme", CIDWelcomeDocs)) - assert.NotEqual(t, 0, catRes.ExitErr.ExitCode(), "welcome readme doesn't exist") + node.IPFS("cat", fmt.Sprintf("/ipfs/%s/readme", CIDWelcomeDocs)) idRes := node.IPFS("id", "-f", "") version := node.IPFS("version", "-n").Stdout.Trimmed() diff --git a/test/sharness/lib/test-lib.sh b/test/sharness/lib/test-lib.sh index 1f1491f9e..f135cdd79 100644 --- a/test/sharness/lib/test-lib.sh +++ b/test/sharness/lib/test-lib.sh @@ -194,7 +194,7 @@ test_config_set() { } test_init_ipfs() { - + args=("$@") # we set the Addresses.API config variable. # the cli client knows to use it, so only need to set. @@ -202,7 +202,7 @@ test_init_ipfs() { test_expect_success "ipfs init succeeds" ' export IPFS_PATH="$(pwd)/.ipfs" && - ipfs init --profile=test > /dev/null + ipfs init "${args[@]}" --profile=test > /dev/null ' test_expect_success "prepare config -- mounting" ' diff --git a/test/sharness/t0025-datastores.sh b/test/sharness/t0025-datastores.sh index ec99accb5..f0ddd4e2e 100755 --- a/test/sharness/t0025-datastores.sh +++ b/test/sharness/t0025-datastores.sh @@ -4,9 +4,9 @@ test_description="Test non-standard datastores" . lib/test-lib.sh -test_expect_success "'ipfs init --profile=badgerds' succeeds" ' +test_expect_success "'ipfs init --empty-repo=false --profile=badgerds' succeeds" ' BITS="2048" && - ipfs init --profile=badgerds + ipfs init --empty-repo=false --profile=badgerds ' test_expect_success "'ipfs pin ls' works" ' diff --git a/test/sharness/t0054-dag-car-import-export.sh b/test/sharness/t0054-dag-car-import-export.sh index f378e9128..fe6f11476 100755 --- a/test/sharness/t0054-dag-car-import-export.sh +++ b/test/sharness/t0054-dag-car-import-export.sh @@ -171,7 +171,7 @@ test_expect_success "shut down nodes" ' # We want to just init the repo, without using a daemon for stuff below -test_init_ipfs +test_init_ipfs --empty-repo=false test_expect_success "basic offline export of 'getting started' dag works" ' diff --git a/test/sharness/t0080-repo.sh b/test/sharness/t0080-repo.sh index 7bd84b276..3f33a5f44 100755 --- a/test/sharness/t0080-repo.sh +++ b/test/sharness/t0080-repo.sh @@ -8,7 +8,7 @@ test_description="Test ipfs repo operations" . lib/test-lib.sh -test_init_ipfs +test_init_ipfs --empty-repo=false test_launch_ipfs_daemon_without_network test_expect_success "'ipfs repo gc' succeeds" ' diff --git a/test/sharness/t0100-name.sh b/test/sharness/t0100-name.sh index 34f33ea4d..f49df3417 100755 --- a/test/sharness/t0100-name.sh +++ b/test/sharness/t0100-name.sh @@ -15,13 +15,13 @@ test_name_with_self() { export IPFS_PATH="$(pwd)/.ipfs" && case $SELF_ALG in default) - ipfs init --profile=test > /dev/null + ipfs init --empty-repo=false --profile=test > /dev/null ;; rsa) - ipfs init --profile=test -a=rsa > /dev/null + ipfs init --empty-repo=false --profile=test -a=rsa > /dev/null ;; ed25519) - ipfs init --profile=test -a=ed25519 > /dev/null + ipfs init --empty-repo=false --profile=test -a=ed25519 > /dev/null ;; esac && export PEERID=`ipfs key list --ipns-base=base36 -l | grep self | cut -d " " -f1` && @@ -273,7 +273,7 @@ test_name_with_key() { test_expect_success "ipfs init (key variant $GEN_ALG)" ' export IPFS_PATH="$(pwd)/.ipfs" && - ipfs init --profile=test > /dev/null + ipfs init --empty-repo=false --profile=test > /dev/null ' test_expect_success "'prepare keys" ' @@ -317,7 +317,7 @@ test_name_with_key 'ed25519_b36' # `ipfs name inspect --verify` using the wrong RSA key should not succeed -test_init_ipfs +test_init_ipfs --empty-repo=false test_launch_ipfs_daemon test_expect_success "prepare RSA keys" ' diff --git a/test/sharness/t0600-issues-and-regressions-online.sh b/test/sharness/t0600-issues-and-regressions-online.sh index 3468f23d6..56384c0d0 100755 --- a/test/sharness/t0600-issues-and-regressions-online.sh +++ b/test/sharness/t0600-issues-and-regressions-online.sh @@ -4,7 +4,7 @@ test_description="Tests for various fixed issues and regressions." . lib/test-lib.sh -test_init_ipfs +test_init_ipfs --empty-repo=false test_launch_ipfs_daemon From d1713ca28e939fcc611e093b5bfcb1e3a54c5b14 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Mon, 3 Apr 2023 10:17:07 +0200 Subject: [PATCH 0603/1212] feat(gw): new metrics and HTTP range support (#9786) Co-authored-by: Henrique Dias --- core/corehttp/gateway.go | 10 ++-------- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- 5 files changed, 8 insertions(+), 14 deletions(-) diff --git a/core/corehttp/gateway.go b/core/corehttp/gateway.go index 75dba80c7..aed860368 100644 --- a/core/corehttp/gateway.go +++ b/core/corehttp/gateway.go @@ -143,14 +143,8 @@ func offlineErrWrap(err error) error { return err } -func (o *offlineGatewayErrWrapper) Get(ctx context.Context, path gateway.ImmutablePath) (gateway.ContentPathMetadata, *gateway.GetResponse, error) { - md, n, err := o.gwimpl.Get(ctx, path) - err = offlineErrWrap(err) - return md, n, err -} - -func (o *offlineGatewayErrWrapper) GetRange(ctx context.Context, path gateway.ImmutablePath, ranges ...gateway.GetRange) (gateway.ContentPathMetadata, files.File, error) { - md, n, err := o.gwimpl.GetRange(ctx, path, ranges...) +func (o *offlineGatewayErrWrapper) Get(ctx context.Context, path gateway.ImmutablePath, ranges ...gateway.ByteRange) (gateway.ContentPathMetadata, *gateway.GetResponse, error) { + md, n, err := o.gwimpl.Get(ctx, path, ranges...) err = offlineErrWrap(err) return md, n, err } diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 84f2b812a..7528602ae 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.18 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.8.0-rc3 + github.com/ipfs/boxo v0.8.0-rc4 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.26.4 github.com/multiformats/go-multiaddr v0.8.0 diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index a92be7d75..d42cf6441 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -337,8 +337,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.8.0-rc3 h1:rttpGdhLE0zeTec8f2/e5YDgCYzEQf7dI4eRglu2ktc= -github.com/ipfs/boxo v0.8.0-rc3/go.mod h1:RIsi4CnTyQ7AUsNn5gXljJYZlQrHBMnJp94p73liFiA= +github.com/ipfs/boxo v0.8.0-rc4 h1:TT9uY/cw6yjmeKjfJPKaGZIYSJmV6B9Bd/O5Rem6MfA= +github.com/ipfs/boxo v0.8.0-rc4/go.mod h1:RIsi4CnTyQ7AUsNn5gXljJYZlQrHBMnJp94p73liFiA= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= diff --git a/go.mod b/go.mod index 11b41d5cc..6a6b70ce2 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/gogo/protobuf v1.3.2 github.com/google/uuid v1.3.0 github.com/hashicorp/go-multierror v1.1.1 - github.com/ipfs/boxo v0.8.0-rc3 + github.com/ipfs/boxo v0.8.0-rc4 github.com/ipfs/go-block-format v0.1.2 github.com/ipfs/go-cid v0.4.0 github.com/ipfs/go-cidutil v0.1.0 diff --git a/go.sum b/go.sum index 925a7278f..9aaa5edb4 100644 --- a/go.sum +++ b/go.sum @@ -355,8 +355,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.8.0-rc3 h1:rttpGdhLE0zeTec8f2/e5YDgCYzEQf7dI4eRglu2ktc= -github.com/ipfs/boxo v0.8.0-rc3/go.mod h1:RIsi4CnTyQ7AUsNn5gXljJYZlQrHBMnJp94p73liFiA= +github.com/ipfs/boxo v0.8.0-rc4 h1:TT9uY/cw6yjmeKjfJPKaGZIYSJmV6B9Bd/O5Rem6MfA= +github.com/ipfs/boxo v0.8.0-rc4/go.mod h1:RIsi4CnTyQ7AUsNn5gXljJYZlQrHBMnJp94p73liFiA= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= From 68ee5e61a87a96b1ce5d47cc0434a22cb8ee1e04 Mon Sep 17 00:00:00 2001 From: Gus Eggert Date: Mon, 3 Apr 2023 11:21:53 -0400 Subject: [PATCH 0604/1212] feat: add changelog entry for router timeouts for v0.19.1 (#9784) * feat: add changelog entry for router timeouts for v0.19.1 * Apply suggestions from code review Co-authored-by: Steve Loeppky --------- Co-authored-by: Steve Loeppky --- docs/changelogs/v0.19.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/docs/changelogs/v0.19.md b/docs/changelogs/v0.19.md index 140b5482a..722f00677 100644 --- a/docs/changelogs/v0.19.md +++ b/docs/changelogs/v0.19.md @@ -1,6 +1,17 @@ # Kubo changelog v0.19 +## v0.19.1 + +### 🔦 Highlights + +#### DHT Timeouts +In v0.16.0, Kubo added the ability to configure custom content routers and DHTs with the `custom` router type, and as part of this added a default 5 minute timeout to all DHT operations. In some cases with large repos ([example](https://github.com/ipfs/kubo/issues/9722)), this can cause provide and reprovide operations to fail because the timeout is reached. This release removes these timeouts on DHT operations. If users desire these timeouts, they can be added back using [the `custom` router type](https://github.com/ipfs/kubo/blob/master/docs/config.md#routingrouters-parameters). + +### 📝 Changelog + +### 👨‍👩‍👧‍👦 Contributors + ## v0.19.0 From 249ef363d236b598ce334c4bc2cfe084c13474ca Mon Sep 17 00:00:00 2001 From: galargh Date: Tue, 4 Apr 2023 08:17:18 +0000 Subject: [PATCH 0605/1212] chore: update version --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index 18bbf9a2d..1fd474ea7 100644 --- a/version.go +++ b/version.go @@ -11,7 +11,7 @@ import ( var CurrentCommit string // CurrentVersionNumber is the current application's version literal -const CurrentVersionNumber = "0.19.0" +const CurrentVersionNumber = "0.19.1-rc1" const ApiVersion = "/kubo/" + CurrentVersionNumber + "/" //nolint From 0fad74c61997ffd22008c5721f860c81a7e5aa6e Mon Sep 17 00:00:00 2001 From: Jorropo Date: Mon, 27 Mar 2023 11:24:40 +0200 Subject: [PATCH 0606/1212] chore: update go-libp2p to v0.26.4 --- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 5453ae1d5..9ddfde672 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -10,7 +10,7 @@ require ( github.com/ipfs/go-libipfs v0.6.2 github.com/ipfs/interface-go-ipfs-core v0.11.0 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 - github.com/libp2p/go-libp2p v0.26.3 + github.com/libp2p/go-libp2p v0.26.4 github.com/multiformats/go-multiaddr v0.8.0 ) diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 6f7e7f253..5ecd0f47f 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -730,8 +730,8 @@ github.com/libp2p/go-libp2p v0.7.0/go.mod h1:hZJf8txWeCduQRDC/WSqBGMxaTHCOYHt2xS github.com/libp2p/go-libp2p v0.7.4/go.mod h1:oXsBlTLF1q7pxr+9w6lqzS1ILpyHsaBPniVO7zIHGMw= github.com/libp2p/go-libp2p v0.8.1/go.mod h1:QRNH9pwdbEBpx5DTJYg+qxcVaDMAz3Ee/qDKwXujH5o= github.com/libp2p/go-libp2p v0.14.3/go.mod h1:d12V4PdKbpL0T1/gsUNN8DfgMuRPDX8bS2QxCZlwRH0= -github.com/libp2p/go-libp2p v0.26.3 h1:6g/psubqwdaBqNNoidbRKSTBEYgaOuKBhHl8Q5tO+PM= -github.com/libp2p/go-libp2p v0.26.3/go.mod h1:x75BN32YbwuY0Awm2Uix4d4KOz+/4piInkp4Wr3yOo8= +github.com/libp2p/go-libp2p v0.26.4 h1:VA9ChjN0n1BwwfU/dqx4Zj9ezXtIxGk8FyJPwFONqxs= +github.com/libp2p/go-libp2p v0.26.4/go.mod h1:x75BN32YbwuY0Awm2Uix4d4KOz+/4piInkp4Wr3yOo8= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-autonat v0.1.0/go.mod h1:1tLf2yXxiE/oKGtDwPYWTSYG3PtvYlJmg7NeVtPRqH8= diff --git a/go.mod b/go.mod index f7237b46a..d3c664c49 100644 --- a/go.mod +++ b/go.mod @@ -67,7 +67,7 @@ require ( 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.26.3 + github.com/libp2p/go-libp2p v0.26.4 github.com/libp2p/go-libp2p-http v0.4.0 github.com/libp2p/go-libp2p-kad-dht v0.21.1 github.com/libp2p/go-libp2p-kbucket v0.5.0 diff --git a/go.sum b/go.sum index 27e101e1c..c35e3ad0a 100644 --- a/go.sum +++ b/go.sum @@ -760,8 +760,8 @@ github.com/libp2p/go-libp2p v0.7.0/go.mod h1:hZJf8txWeCduQRDC/WSqBGMxaTHCOYHt2xS github.com/libp2p/go-libp2p v0.7.4/go.mod h1:oXsBlTLF1q7pxr+9w6lqzS1ILpyHsaBPniVO7zIHGMw= github.com/libp2p/go-libp2p v0.8.1/go.mod h1:QRNH9pwdbEBpx5DTJYg+qxcVaDMAz3Ee/qDKwXujH5o= github.com/libp2p/go-libp2p v0.14.3/go.mod h1:d12V4PdKbpL0T1/gsUNN8DfgMuRPDX8bS2QxCZlwRH0= -github.com/libp2p/go-libp2p v0.26.3 h1:6g/psubqwdaBqNNoidbRKSTBEYgaOuKBhHl8Q5tO+PM= -github.com/libp2p/go-libp2p v0.26.3/go.mod h1:x75BN32YbwuY0Awm2Uix4d4KOz+/4piInkp4Wr3yOo8= +github.com/libp2p/go-libp2p v0.26.4 h1:VA9ChjN0n1BwwfU/dqx4Zj9ezXtIxGk8FyJPwFONqxs= +github.com/libp2p/go-libp2p v0.26.4/go.mod h1:x75BN32YbwuY0Awm2Uix4d4KOz+/4piInkp4Wr3yOo8= github.com/libp2p/go-libp2p-asn-util v0.2.0 h1:rg3+Os8jbnO5DxkC7K/Utdi+DkY3q/d1/1q+8WeNAsw= github.com/libp2p/go-libp2p-asn-util v0.2.0/go.mod h1:WoaWxbHKBymSN41hWSq/lGKJEca7TNm58+gGJi2WsLI= github.com/libp2p/go-libp2p-autonat v0.1.0/go.mod h1:1tLf2yXxiE/oKGtDwPYWTSYG3PtvYlJmg7NeVtPRqH8= From e80dadd1a4dd543b2e15af4f22f5b4045724a098 Mon Sep 17 00:00:00 2001 From: Gus Eggert Date: Thu, 30 Mar 2023 16:08:43 -0400 Subject: [PATCH 0607/1212] fix: remove timeout on default DHT operations (#9783) * fix: remove timeout on default DHT operations This removes the timeout by default for DHT operations. In particular this causes issues with ProvideMany requests which can take an indeterminate amount of time, but really these should just respect context timeouts by default. Users can still specify timeouts here if they want, but by default they will be set to "0" which means "no timeout". This is unlikely to break existing users of custom routing, because there was previously no utility in configuring a router with timeout=0 because that would cause the router to immediately fail, so it is unlikely (and incorrect) if anybody was using timeout=0. * fix: remove 5m timeout on ProvideManyRouter For context see https://github.com/ipfs/kubo/pull/9783/commits/5fda291b6665abe7aaf6a3f17687474dc85d8db4 --------- Co-authored-by: Marcin Rataj --- core/node/libp2p/routing.go | 1 - core/node/libp2p/routingopt.go | 1 - docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- 6 files changed, 6 insertions(+), 8 deletions(-) diff --git a/core/node/libp2p/routing.go b/core/node/libp2p/routing.go index f16fec5a1..8014d4142 100644 --- a/core/node/libp2p/routing.go +++ b/core/node/libp2p/routing.go @@ -186,7 +186,6 @@ func Routing(in p2pOnlineRoutingIn) irouting.ProvideManyRouter { var cRouters []*routinghelpers.ParallelRouter for _, v := range routers { cRouters = append(cRouters, &routinghelpers.ParallelRouter{ - Timeout: 5 * time.Minute, IgnoreError: true, Router: v.Routing, }) diff --git a/core/node/libp2p/routingopt.go b/core/node/libp2p/routingopt.go index d54f37acc..8a69e181b 100644 --- a/core/node/libp2p/routingopt.go +++ b/core/node/libp2p/routingopt.go @@ -65,7 +65,6 @@ func ConstructDefaultRouting(peerID string, addrs []string, privKey string, rout routers = append(routers, &routinghelpers.ParallelRouter{ Router: dhtRouting, IgnoreError: false, - Timeout: 5 * time.Minute, // https://github.com/ipfs/kubo/pull/9475#discussion_r1042501333 ExecuteAfter: 0, }) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 9ddfde672..8710c28f6 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -125,7 +125,7 @@ require ( github.com/libp2p/go-libp2p-pubsub v0.9.0 // indirect github.com/libp2p/go-libp2p-pubsub-router v0.6.0 // indirect github.com/libp2p/go-libp2p-record v0.2.0 // indirect - github.com/libp2p/go-libp2p-routing-helpers v0.6.1 // indirect + github.com/libp2p/go-libp2p-routing-helpers v0.6.2 // indirect github.com/libp2p/go-libp2p-xor v0.1.0 // indirect github.com/libp2p/go-mplex v0.7.0 // indirect github.com/libp2p/go-msgio v0.3.0 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 5ecd0f47f..13bb2158b 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -809,8 +809,8 @@ github.com/libp2p/go-libp2p-quic-transport v0.10.0/go.mod h1:RfJbZ8IqXIhxBRm5hqU github.com/libp2p/go-libp2p-record v0.1.0/go.mod h1:ujNc8iuE5dlKWVy6wuL6dd58t0n7xI4hAIl8pE6wu5Q= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= github.com/libp2p/go-libp2p-record v0.2.0/go.mod h1:I+3zMkvvg5m2OcSdoL0KPljyJyvNDFGKX7QdlpYUcwk= -github.com/libp2p/go-libp2p-routing-helpers v0.6.1 h1:tI3rHOf/FDQsxC2pHBaOZiqPJ0MZYyzGAf4V45xla4U= -github.com/libp2p/go-libp2p-routing-helpers v0.6.1/go.mod h1:R289GUxUMzRXIbWGSuUUTPrlVJZ3Y/pPz495+qgXJX8= +github.com/libp2p/go-libp2p-routing-helpers v0.6.2 h1:u6SWfX+3LoqqTAFxWVl79RkcIDE3Zsay5d+JohlEBaE= +github.com/libp2p/go-libp2p-routing-helpers v0.6.2/go.mod h1:R289GUxUMzRXIbWGSuUUTPrlVJZ3Y/pPz495+qgXJX8= github.com/libp2p/go-libp2p-secio v0.1.0/go.mod h1:tMJo2w7h3+wN4pgU2LSYeiKPrfqBgkOsdiKK77hE7c8= github.com/libp2p/go-libp2p-secio v0.2.0/go.mod h1:2JdZepB8J5V9mBp79BmwsaPQhRPNN2NrnB2lKQcdy6g= github.com/libp2p/go-libp2p-secio v0.2.1/go.mod h1:cWtZpILJqkqrSkiYcDBh5lA3wbT2Q+hz3rJQq3iftD8= diff --git a/go.mod b/go.mod index d3c664c49..3b3107d37 100644 --- a/go.mod +++ b/go.mod @@ -74,7 +74,7 @@ require ( github.com/libp2p/go-libp2p-pubsub v0.9.0 github.com/libp2p/go-libp2p-pubsub-router v0.6.0 github.com/libp2p/go-libp2p-record v0.2.0 - github.com/libp2p/go-libp2p-routing-helpers v0.6.1 + github.com/libp2p/go-libp2p-routing-helpers v0.6.2 github.com/libp2p/go-libp2p-testing v0.12.0 github.com/libp2p/go-socket-activation v0.1.0 github.com/miekg/dns v1.1.50 diff --git a/go.sum b/go.sum index c35e3ad0a..fd1016903 100644 --- a/go.sum +++ b/go.sum @@ -843,8 +843,8 @@ github.com/libp2p/go-libp2p-quic-transport v0.10.0/go.mod h1:RfJbZ8IqXIhxBRm5hqU github.com/libp2p/go-libp2p-record v0.1.0/go.mod h1:ujNc8iuE5dlKWVy6wuL6dd58t0n7xI4hAIl8pE6wu5Q= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= github.com/libp2p/go-libp2p-record v0.2.0/go.mod h1:I+3zMkvvg5m2OcSdoL0KPljyJyvNDFGKX7QdlpYUcwk= -github.com/libp2p/go-libp2p-routing-helpers v0.6.1 h1:tI3rHOf/FDQsxC2pHBaOZiqPJ0MZYyzGAf4V45xla4U= -github.com/libp2p/go-libp2p-routing-helpers v0.6.1/go.mod h1:R289GUxUMzRXIbWGSuUUTPrlVJZ3Y/pPz495+qgXJX8= +github.com/libp2p/go-libp2p-routing-helpers v0.6.2 h1:u6SWfX+3LoqqTAFxWVl79RkcIDE3Zsay5d+JohlEBaE= +github.com/libp2p/go-libp2p-routing-helpers v0.6.2/go.mod h1:R289GUxUMzRXIbWGSuUUTPrlVJZ3Y/pPz495+qgXJX8= github.com/libp2p/go-libp2p-secio v0.1.0/go.mod h1:tMJo2w7h3+wN4pgU2LSYeiKPrfqBgkOsdiKK77hE7c8= github.com/libp2p/go-libp2p-secio v0.2.0/go.mod h1:2JdZepB8J5V9mBp79BmwsaPQhRPNN2NrnB2lKQcdy6g= github.com/libp2p/go-libp2p-secio v0.2.1/go.mod h1:cWtZpILJqkqrSkiYcDBh5lA3wbT2Q+hz3rJQq3iftD8= From 486c583293d162c99d51b0626530fddcd2ddb446 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Tue, 4 Apr 2023 18:57:54 +0200 Subject: [PATCH 0608/1212] chore: bump go-blockservice to v0.5.1 --- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 8710c28f6..62e00384f 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -64,7 +64,7 @@ require ( github.com/ipfs/bbloom v0.0.4 // indirect github.com/ipfs/go-bitfield v1.1.0 // indirect github.com/ipfs/go-block-format v0.1.1 // indirect - github.com/ipfs/go-blockservice v0.5.0 // indirect + github.com/ipfs/go-blockservice v0.5.1 // indirect github.com/ipfs/go-cid v0.3.2 // indirect github.com/ipfs/go-cidutil v0.1.0 // indirect github.com/ipfs/go-datastore v0.6.0 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 13bb2158b..a127e4d06 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -450,8 +450,8 @@ github.com/ipfs/go-block-format v0.1.1/go.mod h1:+McEIT+g52p+zz5xGAABGSOKrzmrdX9 github.com/ipfs/go-blockservice v0.1.0/go.mod h1:hzmMScl1kXHg3M2BjTymbVPjv627N7sYcvYaKbop39M= github.com/ipfs/go-blockservice v0.2.1/go.mod h1:k6SiwmgyYgs4M/qt+ww6amPeUH9EISLRBnvUurKJhi8= github.com/ipfs/go-blockservice v0.3.0/go.mod h1:P5ppi8IHDC7O+pA0AlGTF09jruB2h+oP3wVVaZl8sfk= -github.com/ipfs/go-blockservice v0.5.0 h1:B2mwhhhVQl2ntW2EIpaWPwSCxSuqr5fFA93Ms4bYLEY= -github.com/ipfs/go-blockservice v0.5.0/go.mod h1:W6brZ5k20AehbmERplmERn8o2Ni3ZZubvAxaIUeaT6w= +github.com/ipfs/go-blockservice v0.5.1 h1:9pAtkyKAz/skdHTh0kH8VulzWp+qmSDD0aI17TYP/s0= +github.com/ipfs/go-blockservice v0.5.1/go.mod h1:VpMblFEqG67A/H2sHKAemeH9vlURVavlysbdUI632yk= github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.2/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.3/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= diff --git a/go.mod b/go.mod index 3b3107d37..abc28bd88 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/gogo/protobuf v1.3.2 github.com/google/uuid v1.3.0 github.com/hashicorp/go-multierror v1.1.1 - github.com/ipfs/go-blockservice v0.5.0 + github.com/ipfs/go-blockservice v0.5.1 github.com/ipfs/go-cid v0.3.2 github.com/ipfs/go-cidutil v0.1.0 github.com/ipfs/go-datastore v0.6.0 diff --git a/go.sum b/go.sum index fd1016903..5d39d5f7d 100644 --- a/go.sum +++ b/go.sum @@ -468,8 +468,8 @@ github.com/ipfs/go-block-format v0.1.1/go.mod h1:+McEIT+g52p+zz5xGAABGSOKrzmrdX9 github.com/ipfs/go-blockservice v0.1.0/go.mod h1:hzmMScl1kXHg3M2BjTymbVPjv627N7sYcvYaKbop39M= github.com/ipfs/go-blockservice v0.2.1/go.mod h1:k6SiwmgyYgs4M/qt+ww6amPeUH9EISLRBnvUurKJhi8= github.com/ipfs/go-blockservice v0.3.0/go.mod h1:P5ppi8IHDC7O+pA0AlGTF09jruB2h+oP3wVVaZl8sfk= -github.com/ipfs/go-blockservice v0.5.0 h1:B2mwhhhVQl2ntW2EIpaWPwSCxSuqr5fFA93Ms4bYLEY= -github.com/ipfs/go-blockservice v0.5.0/go.mod h1:W6brZ5k20AehbmERplmERn8o2Ni3ZZubvAxaIUeaT6w= +github.com/ipfs/go-blockservice v0.5.1 h1:9pAtkyKAz/skdHTh0kH8VulzWp+qmSDD0aI17TYP/s0= +github.com/ipfs/go-blockservice v0.5.1/go.mod h1:VpMblFEqG67A/H2sHKAemeH9vlURVavlysbdUI632yk= github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.2/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.3/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= From 027c5b1a09f79ce029286a8a8f0fe63d3a6aec32 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Tue, 4 Apr 2023 19:11:32 +0100 Subject: [PATCH 0609/1212] feat: allow injecting custom path resolvers (#9750) In order to make it possible to easily-overwrite the path Resolvers (i.e. via plugins), this creates resolvers as part of the Node rather than creating them ad-hoc. --- core/core.go | 27 +++++++++++++++------------ core/coreapi/coreapi.go | 25 +++++++++++++++---------- core/coreapi/path.go | 8 +++----- core/node/core.go | 30 +++++++++++++++++++++++++++--- core/node/groups.go | 1 + fuse/readonly/readonly_unix.go | 3 +-- 6 files changed, 62 insertions(+), 32 deletions(-) diff --git a/core/core.go b/core/core.go index 8aeeaaef6..448386444 100644 --- a/core/core.go +++ b/core/core.go @@ -21,6 +21,7 @@ import ( exchange "github.com/ipfs/boxo/exchange" "github.com/ipfs/boxo/fetcher" mfs "github.com/ipfs/boxo/mfs" + pathresolver "github.com/ipfs/boxo/path/resolver" provider "github.com/ipfs/boxo/provider" "github.com/ipfs/go-graphsync" ipld "github.com/ipfs/go-ipld-format" @@ -87,18 +88,20 @@ 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 irouting.ProvideManyRouter `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"` + 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 irouting.ProvideManyRouter `optional:"true"` // the routing system. recommend ipfs-dht + DNSResolver *madns.Resolver // the DNS resolver + IPLDPathResolver pathresolver.Resolver `name:"ipldPathResolver"` // The IPLD path resolver + UnixFSPathResolver pathresolver.Resolver `name:"unixFSPathResolver"` // The UnixFS path 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/coreapi/coreapi.go b/core/coreapi/coreapi.go index c58c67f6b..6c97800a3 100644 --- a/core/coreapi/coreapi.go +++ b/core/coreapi/coreapi.go @@ -26,6 +26,7 @@ import ( offlinexch "github.com/ipfs/boxo/exchange/offline" "github.com/ipfs/boxo/fetcher" dag "github.com/ipfs/boxo/ipld/merkledag" + pathresolver "github.com/ipfs/boxo/path/resolver" pin "github.com/ipfs/boxo/pinning/pinner" provider "github.com/ipfs/boxo/provider" offlineroute "github.com/ipfs/boxo/routing/offline" @@ -65,9 +66,11 @@ type CoreAPI struct { recordValidator record.Validator exchange exchange.Interface - namesys namesys.NameSystem - routing routing.Routing - dnsResolver *madns.Resolver + namesys namesys.NameSystem + routing routing.Routing + dnsResolver *madns.Resolver + ipldPathResolver pathresolver.Resolver + unixFSPathResolver pathresolver.Resolver provider provider.System @@ -179,13 +182,15 @@ func (api *CoreAPI) WithOptions(opts ...options.ApiOption) (coreiface.CoreAPI, e ipldFetcherFactory: n.IPLDFetcherFactory, unixFSFetcherFactory: n.UnixFSFetcherFactory, - peerstore: n.Peerstore, - peerHost: n.PeerHost, - namesys: n.Namesys, - recordValidator: n.RecordValidator, - exchange: n.Exchange, - routing: n.Routing, - dnsResolver: n.DNSResolver, + peerstore: n.Peerstore, + peerHost: n.PeerHost, + namesys: n.Namesys, + recordValidator: n.RecordValidator, + exchange: n.Exchange, + routing: n.Routing, + dnsResolver: n.DNSResolver, + ipldPathResolver: n.IPLDPathResolver, + unixFSPathResolver: n.UnixFSPathResolver, provider: n.Provider, diff --git a/core/coreapi/path.go b/core/coreapi/path.go index 099f192a1..db07c6428 100644 --- a/core/coreapi/path.go +++ b/core/coreapi/path.go @@ -13,7 +13,6 @@ import ( coreiface "github.com/ipfs/boxo/coreiface" path "github.com/ipfs/boxo/coreiface/path" - "github.com/ipfs/boxo/fetcher" ipfspath "github.com/ipfs/boxo/path" ipfspathresolver "github.com/ipfs/boxo/path/resolver" "github.com/ipfs/go-cid" @@ -63,13 +62,12 @@ func (api *CoreAPI) ResolvePath(ctx context.Context, p path.Path) (path.Resolved return nil, fmt.Errorf("unsupported path namespace: %s", p.Namespace()) } - var dataFetcher fetcher.Factory + var resolver ipfspathresolver.Resolver if ipath.Segments()[0] == "ipld" { - dataFetcher = api.ipldFetcherFactory + resolver = api.ipldPathResolver } else { - dataFetcher = api.unixFSFetcherFactory + resolver = api.unixFSPathResolver } - resolver := ipfspathresolver.NewBasicResolver(dataFetcher) node, rest, err := resolver.ResolveToLastNode(ctx, ipath) if err != nil { diff --git a/core/node/core.go b/core/node/core.go index 76f44b521..d2d2c63d7 100644 --- a/core/node/core.go +++ b/core/node/core.go @@ -13,6 +13,7 @@ import ( "github.com/ipfs/boxo/ipld/merkledag" "github.com/ipfs/boxo/ipld/unixfs" "github.com/ipfs/boxo/mfs" + pathresolver "github.com/ipfs/boxo/path/resolver" pin "github.com/ipfs/boxo/pinning/pinner" "github.com/ipfs/boxo/pinning/pinner/dspinner" "github.com/ipfs/go-cid" @@ -83,14 +84,22 @@ func (s *syncDagService) Session(ctx context.Context) format.NodeGetter { return merkledag.NewSession(ctx, s.DAGService) } -type fetchersOut struct { +// FetchersOut allows injection of fetchers. +type FetchersOut struct { fx.Out IPLDFetcher fetcher.Factory `name:"ipldFetcher"` UnixfsFetcher fetcher.Factory `name:"unixfsFetcher"` } +// FetchersIn allows using fetchers for other dependencies. +type FetchersIn struct { + fx.In + IPLDFetcher fetcher.Factory `name:"ipldFetcher"` + UnixfsFetcher fetcher.Factory `name:"unixfsFetcher"` +} + // FetcherConfig returns a fetcher config that can build new fetcher instances -func FetcherConfig(bs blockservice.BlockService) fetchersOut { +func FetcherConfig(bs blockservice.BlockService) FetchersOut { ipldFetcher := bsfetcher.NewFetcherConfig(bs) ipldFetcher.PrototypeChooser = dagpb.AddSupportToChooser(func(lnk ipld.Link, lnkCtx ipld.LinkContext) (ipld.NodePrototype, error) { if tlnkNd, ok := lnkCtx.LinkNode.(schema.TypedLinkNode); ok { @@ -100,7 +109,22 @@ func FetcherConfig(bs blockservice.BlockService) fetchersOut { }) unixFSFetcher := ipldFetcher.WithReifier(unixfsnode.Reify) - return fetchersOut{IPLDFetcher: ipldFetcher, UnixfsFetcher: unixFSFetcher} + return FetchersOut{IPLDFetcher: ipldFetcher, UnixfsFetcher: unixFSFetcher} +} + +// PathResolversOut allows injection of path resolvers +type PathResolversOut struct { + fx.Out + IPLDPathResolver pathresolver.Resolver `name:"ipldPathResolver"` + UnixFSPathResolver pathresolver.Resolver `name:"unixFSPathResolver"` +} + +// PathResolverConfig creates path resolvers with the given fetchers. +func PathResolverConfig(fetchers FetchersIn) PathResolversOut { + return PathResolversOut{ + IPLDPathResolver: pathresolver.NewBasicResolver(fetchers.IPLDFetcher), + UnixFSPathResolver: pathresolver.NewBasicResolver(fetchers.UnixfsFetcher), + } } // Dag creates new DAGService diff --git a/core/node/groups.go b/core/node/groups.go index a18a6aa5f..0b1660265 100644 --- a/core/node/groups.go +++ b/core/node/groups.go @@ -334,6 +334,7 @@ var Core = fx.Options( fx.Provide(BlockService), fx.Provide(Dag), fx.Provide(FetcherConfig), + fx.Provide(PathResolverConfig), fx.Provide(Pinning), fx.Provide(Files), ) diff --git a/fuse/readonly/readonly_unix.go b/fuse/readonly/readonly_unix.go index ae90caead..d925ec8c2 100644 --- a/fuse/readonly/readonly_unix.go +++ b/fuse/readonly/readonly_unix.go @@ -17,7 +17,6 @@ import ( ft "github.com/ipfs/boxo/ipld/unixfs" uio "github.com/ipfs/boxo/ipld/unixfs/io" path "github.com/ipfs/boxo/path" - "github.com/ipfs/boxo/path/resolver" "github.com/ipfs/go-cid" ipld "github.com/ipfs/go-ipld-format" logging "github.com/ipfs/go-log" @@ -69,7 +68,7 @@ func (s *Root) Lookup(ctx context.Context, name string) (fs.Node, error) { return nil, fuse.ENOENT } - nd, ndLnk, err := resolver.NewBasicResolver(s.Ipfs.UnixFSFetcherFactory).ResolvePath(ctx, p) + nd, ndLnk, err := s.Ipfs.UnixFSPathResolver.ResolvePath(ctx, p) if err != nil { // todo: make this error more versatile. return nil, fuse.ENOENT From f5bcaaecc1d6e299bbf60fb50b9b082e425348e5 Mon Sep 17 00:00:00 2001 From: Gus Eggert Date: Wed, 5 Apr 2023 06:59:49 -0400 Subject: [PATCH 0610/1212] test: use self hosted runner for go tests (#9792) --- .github/workflows/gotest.yml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/workflows/gotest.yml b/.github/workflows/gotest.yml index 2c349d940..ab35ec3a7 100644 --- a/.github/workflows/gotest.yml +++ b/.github/workflows/gotest.yml @@ -12,9 +12,12 @@ concurrency: cancel-in-progress: true jobs: - go-test: + go-test-runner: if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' - runs-on: ubuntu-latest + uses: ipfs/kubo/.github/workflows/runner.yml@master + go-test: + needs: [go-test-runner] + runs-on: ${{ fromJSON(needs.go-test-runner.outputs.config).labels }} timeout-minutes: 20 env: TEST_NO_DOCKER: 1 @@ -39,7 +42,7 @@ jobs: name: ${{ github.job }} - name: 👉️ If this step failed, go to «Summary» (top left) → inspect the «Failures/Errors» table run: | - make -j 1 test/unit/gotest.junit.xml && + make -j 2 test/unit/gotest.junit.xml && [[ ! $(jq -s -c 'map(select(.Action == "fail")) | .[]' test/unit/gotest.json) ]] - name: Upload coverage to Codecov uses: codecov/codecov-action@81cd2dc8148241f03f5839d295e000b8f761e378 # v3.1.0 From fd830b3c1a1aeda55504f28fe6a268e92cc30225 Mon Sep 17 00:00:00 2001 From: Gus Eggert Date: Wed, 5 Apr 2023 07:10:32 -0400 Subject: [PATCH 0611/1212] test: fix flaky content routing over HTTP test (#9772) --- test/cli/content_routing_http_test.go | 104 ++++++++++++++++++ .../t0172-content-routing-over-http.sh | 61 ---------- 2 files changed, 104 insertions(+), 61 deletions(-) create mode 100644 test/cli/content_routing_http_test.go delete mode 100755 test/sharness/t0172-content-routing-over-http.sh diff --git a/test/cli/content_routing_http_test.go b/test/cli/content_routing_http_test.go new file mode 100644 index 000000000..a8b825619 --- /dev/null +++ b/test/cli/content_routing_http_test.go @@ -0,0 +1,104 @@ +package cli + +import ( + "context" + "net/http" + "net/http/httptest" + "os/exec" + "sync" + "testing" + "time" + + "github.com/ipfs/boxo/routing/http/server" + "github.com/ipfs/boxo/routing/http/types" + "github.com/ipfs/go-cid" + "github.com/ipfs/kubo/test/cli/harness" + "github.com/ipfs/kubo/test/cli/testutils" + "github.com/stretchr/testify/assert" +) + +type fakeHTTPContentRouter struct { + m sync.Mutex + findProvidersCalls int + provideCalls int +} + +func (r *fakeHTTPContentRouter) FindProviders(ctx context.Context, key cid.Cid) ([]types.ProviderResponse, error) { + r.m.Lock() + defer r.m.Unlock() + r.findProvidersCalls++ + return []types.ProviderResponse{}, nil +} + +func (r *fakeHTTPContentRouter) ProvideBitswap(ctx context.Context, req *server.BitswapWriteProvideRequest) (time.Duration, error) { + r.m.Lock() + defer r.m.Unlock() + r.provideCalls++ + return 0, nil +} +func (r *fakeHTTPContentRouter) Provide(ctx context.Context, req *server.WriteProvideRequest) (types.ProviderResponse, error) { + r.m.Lock() + defer r.m.Unlock() + r.provideCalls++ + return nil, nil +} + +func (r *fakeHTTPContentRouter) numFindProvidersCalls() int { + r.m.Lock() + defer r.m.Unlock() + return r.findProvidersCalls +} + +// userAgentRecorder records the user agent of every HTTP request +type userAgentRecorder struct { + delegate http.Handler + userAgents []string +} + +func (r *userAgentRecorder) ServeHTTP(w http.ResponseWriter, req *http.Request) { + r.userAgents = append(r.userAgents, req.UserAgent()) + r.delegate.ServeHTTP(w, req) +} + +func TestContentRoutingHTTP(t *testing.T) { + cr := &fakeHTTPContentRouter{} + + // run the content routing HTTP server + userAgentRecorder := &userAgentRecorder{delegate: server.Handler(cr)} + server := httptest.NewServer(userAgentRecorder) + t.Cleanup(func() { server.Close() }) + + // setup the node + node := harness.NewT(t).NewNode().Init() + node.Runner.Env["IPFS_HTTP_ROUTERS"] = server.URL + node.StartDaemon() + + // compute a random CID + randStr := string(testutils.RandomBytes(100)) + res := node.PipeStrToIPFS(randStr, "add", "-qn") + wantCIDStr := res.Stdout.Trimmed() + + t.Run("fetching an uncached block results in an HTTP lookup", func(t *testing.T) { + statRes := node.Runner.Run(harness.RunRequest{ + Path: node.IPFSBin, + Args: []string{"block", "stat", wantCIDStr}, + RunFunc: (*exec.Cmd).Start, + }) + defer func() { + if err := statRes.Cmd.Process.Kill(); err != nil { + t.Logf("error killing 'block stat' cmd: %s", err) + } + }() + + // verify the content router was called + assert.Eventually(t, func() bool { + return cr.numFindProvidersCalls() > 0 + }, time.Minute, 10*time.Millisecond) + + assert.NotEmpty(t, userAgentRecorder.userAgents) + version := node.IPFS("id", "-f", "").Stdout.Trimmed() + for _, userAgent := range userAgentRecorder.userAgents { + assert.Equal(t, version, userAgent) + } + }) +} diff --git a/test/sharness/t0172-content-routing-over-http.sh b/test/sharness/t0172-content-routing-over-http.sh deleted file mode 100755 index 2dac04e7d..000000000 --- a/test/sharness/t0172-content-routing-over-http.sh +++ /dev/null @@ -1,61 +0,0 @@ -#!/usr/bin/env bash - -test_description="Test content routing over HTTP" - -. lib/test-lib.sh - - -if ! test_have_prereq SOCAT; then - skip_all="skipping '$test_description': socat is not available" - test_done -fi - -test_init_ipfs - -# Run listener on a free port to log HTTP requests sent by Kubo in Routing.Type=auto mode -export ROUTER_PORT=$(comm -23 <(seq 49152 65535 | sort) <(ss -Htan | awk '{print $4}' | cut -d':' -f2) | head -n 1) -export IPFS_HTTP_ROUTERS="http://127.0.0.1:$ROUTER_PORT" - -test_launch_ipfs_daemon - -test_expect_success "start HTTP router proxy" ' - touch http_requests - socat -u TCP-LISTEN:$ROUTER_PORT,reuseaddr,fork,bind=127.0.0.1,retry=10 CREATE:http_requests & - NCPID=$! -' - -## HTTP GETs - -test_expect_success 'create unique CID without adding it to the local datastore' ' - WANT_CID=$(date +"%FT%T.%N%z" | ipfs add -qn) -' - -test_expect_success 'expect HTTP lookup when CID is not in the local datastore' ' - ipfs block stat "$WANT_CID" & - test_wait_output_n_lines http_requests 4 && - test_should_contain "GET /routing/v1/providers/$WANT_CID" http_requests -' - -test_expect_success 'expect HTTP request User-Agent to match Kubo version' ' - test_should_contain "User-Agent: $(ipfs id -f "")" http_requests -' - -## HTTP PUTs - -test_expect_success 'add new CID to the local datastore' ' - ADD_CID=$(date +"%FT%T.%N%z" | ipfs add -q) -' - -# cid.contact supports GET-only: https://github.com/ipfs/kubo/issues/9504 -# which means no announcements over HTTP should be made. -test_expect_success 'expect no HTTP requests to be sent with locally added CID' ' - test_should_not_contain "$ADD_CID" http_requests -' - -test_expect_success "stop nc" ' - kill "$NCPID" && wait "$NCPID" || true - rm -f http_requests || true -' - -test_kill_ipfs_daemon -test_done From 1b3e4438fc40adb4bd51df21ccb005c2b5a0f7a8 Mon Sep 17 00:00:00 2001 From: Gus Eggert Date: Wed, 5 Apr 2023 07:44:14 -0400 Subject: [PATCH 0612/1212] chore: upgrade OpenTelemetry dependencies (#9736) --- .github/workflows/build.yml | 12 +-- .github/workflows/gobuild.yml | 6 +- .github/workflows/golint.yml | 4 +- .github/workflows/gotest.yml | 4 +- .github/workflows/sharness.yml | 6 +- Rules.mk | 2 +- coverage/Rules.mk | 2 +- go.mod | 12 +-- go.sum | 15 ++-- test/cli/harness/node.go | 30 +++++-- test/cli/harness/run.go | 12 +++ test/cli/testutils/requires.go | 6 +- test/cli/tracing_test.go | 89 +++++++++++++++++++ test/sharness/Rules.mk | 2 +- test/sharness/lib/test-lib.sh | 12 +-- ...230-channel-streaming-http-content-type.sh | 2 - test/sharness/t0310-tracing.sh | 57 ------------ 17 files changed, 164 insertions(+), 109 deletions(-) create mode 100644 test/cli/tracing_test.go delete mode 100755 test/sharness/t0310-tracing.sh diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ddb3382c6..50889613b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -20,8 +20,8 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 5 env: - TEST_NO_DOCKER: 1 - TEST_NO_FUSE: 1 + TEST_DOCKER: 0 + TEST_FUSE: 0 TEST_VERBOSE: 1 TRAVIS: 1 GIT_PAGER: cat @@ -86,8 +86,8 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 5 env: - TEST_NO_DOCKER: 1 - TEST_NO_FUSE: 1 + TEST_DOCKER: 0 + TEST_FUSE: 0 TEST_VERBOSE: 1 TRAVIS: 1 GIT_PAGER: cat @@ -126,8 +126,8 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 5 env: - TEST_NO_DOCKER: 1 - TEST_NO_FUSE: 1 + TEST_DOCKER: 0 + TEST_FUSE: 0 TEST_VERBOSE: 1 TRAVIS: 1 GIT_PAGER: cat diff --git a/.github/workflows/gobuild.yml b/.github/workflows/gobuild.yml index 26dc66777..f1e3a60b7 100644 --- a/.github/workflows/gobuild.yml +++ b/.github/workflows/gobuild.yml @@ -20,7 +20,7 @@ jobs: runs-on: ${{ fromJSON(needs.go-build-runner.outputs.config).labels }} timeout-minutes: 20 env: - TEST_NO_DOCKER: 1 + TEST_DOCKER: 0 TEST_VERBOSE: 1 TRAVIS: 1 GIT_PAGER: cat @@ -38,7 +38,7 @@ jobs: name: ${{ github.job }} - run: make cmd/ipfs-try-build env: - TEST_NO_FUSE: 0 + TEST_FUSE: 1 - run: make cmd/ipfs-try-build env: - TEST_NO_FUSE: 1 + TEST_FUSE: 0 diff --git a/.github/workflows/golint.yml b/.github/workflows/golint.yml index ae3683ff4..216573a46 100644 --- a/.github/workflows/golint.yml +++ b/.github/workflows/golint.yml @@ -17,8 +17,8 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 10 env: - TEST_NO_DOCKER: 1 - TEST_NO_FUSE: 1 + TEST_DOCKER: 0 + TEST_FUSE: 0 TEST_VERBOSE: 1 TRAVIS: 1 GIT_PAGER: cat diff --git a/.github/workflows/gotest.yml b/.github/workflows/gotest.yml index ab35ec3a7..81c39fd5e 100644 --- a/.github/workflows/gotest.yml +++ b/.github/workflows/gotest.yml @@ -20,8 +20,8 @@ jobs: runs-on: ${{ fromJSON(needs.go-test-runner.outputs.config).labels }} timeout-minutes: 20 env: - TEST_NO_DOCKER: 1 - TEST_NO_FUSE: 1 + TEST_DOCKER: 0 + TEST_FUSE: 0 TEST_VERBOSE: 1 TRAVIS: 1 GIT_PAGER: cat diff --git a/.github/workflows/sharness.yml b/.github/workflows/sharness.yml index 04779d15f..012a6a982 100644 --- a/.github/workflows/sharness.yml +++ b/.github/workflows/sharness.yml @@ -49,9 +49,9 @@ jobs: test/sharness/test-results/sharness.xml working-directory: kubo env: - TEST_NO_DOCKER: 0 - TEST_NO_PLUGIN: 1 - TEST_NO_FUSE: 1 + TEST_DOCKER: 1 + TEST_PLUGIN: 0 + TEST_FUSE: 0 TEST_VERBOSE: 1 TEST_JUNIT: 1 TEST_EXPENSIVE: 1 diff --git a/Rules.mk b/Rules.mk index 3d3d9c139..cec34cef7 100644 --- a/Rules.mk +++ b/Rules.mk @@ -19,7 +19,7 @@ include mk/golang.mk # extra properties # # -------------------- # -ifeq ($(TEST_NO_FUSE),1) +ifeq ($(TEST_FUSE),0) GOTAGS += nofuse endif export LIBP2P_TCP_REUSEPORT=false diff --git a/coverage/Rules.mk b/coverage/Rules.mk index 7770ed69b..48fce2856 100644 --- a/coverage/Rules.mk +++ b/coverage/Rules.mk @@ -45,7 +45,7 @@ endif export IPFS_COVER_DIR:= $(realpath $(d))/sharnesscover/ -$(d)/sharness_tests.coverprofile: export TEST_NO_PLUGIN=1 +$(d)/sharness_tests.coverprofile: export TEST_PLUGIN=0 $(d)/sharness_tests.coverprofile: $(d)/ipfs cmd/ipfs/ipfs-test-cover $(d)/coverage_deps test_sharness (cd $(@D)/sharnesscover && find . -type f | gocovmerge -list -) > $@ diff --git a/go.mod b/go.mod index 6a6b70ce2..1b7893475 100644 --- a/go.mod +++ b/go.mod @@ -72,18 +72,15 @@ 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.24.0 - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.32.0 + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.40.0 go.opentelemetry.io/otel v1.14.0 go.opentelemetry.io/otel/exporters/jaeger v1.14.0 - go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.14.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.14.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.14.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.14.0 go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.14.0 go.opentelemetry.io/otel/exporters/zipkin v1.14.0 go.opentelemetry.io/otel/sdk v1.14.0 go.opentelemetry.io/otel/trace v1.14.0 - go.opentelemetry.io/proto/otlp v0.19.0 // indirect go.uber.org/dig v1.15.0 go.uber.org/fx v1.18.2 go.uber.org/zap v1.24.0 @@ -113,7 +110,7 @@ require ( github.com/docker/go-units v0.5.0 // indirect github.com/elastic/gosigar v0.14.2 // indirect github.com/emirpasic/gods v1.18.1 // indirect - github.com/felixge/httpsnoop v1.0.2 // indirect + github.com/felixge/httpsnoop v1.0.3 // indirect github.com/flynn/noise v1.0.0 // indirect github.com/francoispqt/gojay v1.2.13 // indirect github.com/gabriel-vasile/mimetype v1.4.1 // indirect @@ -208,7 +205,10 @@ require ( github.com/whyrusleeping/cbor-gen v0.0.0-20230126041949-52956bd4c9aa // indirect github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f // indirect github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect - go.opentelemetry.io/otel/metric v0.30.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.14.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.14.0 // indirect + go.opentelemetry.io/otel/metric v0.37.0 // indirect + go.opentelemetry.io/proto/otlp v0.19.0 // indirect go.uber.org/atomic v1.10.0 // indirect go.uber.org/multierr v1.9.0 // indirect go4.org v0.0.0-20200411211856-f5505b9728dd // indirect diff --git a/go.sum b/go.sum index 9aaa5edb4..858e36850 100644 --- a/go.sum +++ b/go.sum @@ -170,8 +170,8 @@ github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5 h1:BBso6MBKW github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5/go.mod h1:JpoxHjuQauoxiFMl1ie8Xc/7TfLuMZ5eOCONd1sUBHg= github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= -github.com/felixge/httpsnoop v1.0.2 h1:+nS9g82KMXccJ/wp0zyRW9ZBHFETmMGtkk+2CTTrW4o= -github.com/felixge/httpsnoop v1.0.2/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk= +github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/flynn/noise v1.0.0 h1:DlTHqmzmvcEiKj+4RYo/imoswx/4r6iBlCMfVtrMXpQ= github.com/flynn/noise v1.0.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag= @@ -291,7 +291,6 @@ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ 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= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= @@ -922,9 +921,8 @@ go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.32.0 h1:mac9BKRqwaX6zxHPDe3pvmWpwuuIM0vuXv2juCnQevE= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.32.0/go.mod h1:5eCOqeGphOyz6TsY3ZDNjE33SM/TFAK3RGuCL2naTgY= -go.opentelemetry.io/otel v1.7.0/go.mod h1:5BdUoMIz5WEs0vt0CUEMtSSaTSHBBVwrhnz7+nrD5xk= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.40.0 h1:lE9EJyw3/JhrjWH/hEy9FptnalDQgj7vpbgC2KCCCxE= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.40.0/go.mod h1:pcQ3MM3SWvrA71U4GDqv9UFDJ3HQsW7y5ZO3tDTlUdI= go.opentelemetry.io/otel v1.14.0 h1:/79Huy8wbf5DnIPhemGB+zEPVwnN6fuQybr/SRXa6hM= go.opentelemetry.io/otel v1.14.0/go.mod h1:o4buv+dJzx8rohcUeRmWUZhqupFvzWis188WlggnNeU= go.opentelemetry.io/otel/exporters/jaeger v1.14.0 h1:CjbUNd4iN2hHmWekmOqZ+zSCU+dzZppG8XsV+A3oc8Q= @@ -941,11 +939,10 @@ go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.14.0 h1:sEL90JjOO/4yhqu go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.14.0/go.mod h1:oCslUcizYdpKYyS9e8srZEqM6BB8fq41VJBjLAE6z1w= go.opentelemetry.io/otel/exporters/zipkin v1.14.0 h1:reEVE1upBF9tcujgvSqLJS0SrI7JQPaTKP4s4rymnSs= go.opentelemetry.io/otel/exporters/zipkin v1.14.0/go.mod h1:RcjvOAcvhzcufQP8aHmzRw1gE9g/VEZufDdo2w+s4sk= -go.opentelemetry.io/otel/metric v0.30.0 h1:Hs8eQZ8aQgs0U49diZoaS6Uaxw3+bBE3lcMUKBFIk3c= -go.opentelemetry.io/otel/metric v0.30.0/go.mod h1:/ShZ7+TS4dHzDFmfi1kSXMhMVubNoP0oIaBp70J6UXU= +go.opentelemetry.io/otel/metric v0.37.0 h1:pHDQuLQOZwYD+Km0eb657A25NaRzy0a+eLyKfDXedEs= +go.opentelemetry.io/otel/metric v0.37.0/go.mod h1:DmdaHfGt54iV6UKxsV9slj2bBRJcKC1B1uvDLIioc1s= go.opentelemetry.io/otel/sdk v1.14.0 h1:PDCppFRDq8A1jL9v6KMI6dYesaq+DFcDZvjsoGvxGzY= go.opentelemetry.io/otel/sdk v1.14.0/go.mod h1:bwIC5TjrNG6QDCHNWvW4HLHtUQ4I+VQDsnjhvyZCALM= -go.opentelemetry.io/otel/trace v1.7.0/go.mod h1:fzLSB9nqR2eXzxPXb2JW9IKE+ScyXA48yyE4TNvoHqU= go.opentelemetry.io/otel/trace v1.14.0 h1:wp2Mmvj41tDsyAJXiWDWpfNsOiIyd38fy85pyKcFq/M= go.opentelemetry.io/otel/trace v1.14.0/go.mod h1:8avnQLK+CG77yNLUae4ea2JDQ6iT+gozhnZjy/rw9G8= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= diff --git a/test/cli/harness/node.go b/test/cli/harness/node.go index 4d9ed965c..625a01fb6 100644 --- a/test/cli/harness/node.go +++ b/test/cli/harness/node.go @@ -211,19 +211,29 @@ func (n *Node) Init(ipfsArgs ...string) *Node { return n } -func (n *Node) StartDaemon(ipfsArgs ...string) *Node { +// StartDaemonWithReq runs a Kubo daemon with the given request. +// This overwrites the request Path with the Kubo bin path. +// +// For example, if you want to run the daemon and see stderr and stdout to debug: +// +// node.StartDaemonWithReq(harness.RunRequest{ +// CmdOpts: []harness.CmdOpt{ +// harness.RunWithStderr(os.Stdout), +// harness.RunWithStdout(os.Stdout), +// }, +// }) +func (n *Node) StartDaemonWithReq(req RunRequest) *Node { alive := n.IsAlive() if alive { log.Panicf("node %d is already running", n.ID) } + newReq := req + newReq.Path = n.IPFSBin + newReq.Args = append([]string{"daemon"}, req.Args...) + newReq.RunFunc = (*exec.Cmd).Start - daemonArgs := append([]string{"daemon"}, ipfsArgs...) log.Debugf("starting node %d", n.ID) - res := n.Runner.MustRun(RunRequest{ - Path: n.IPFSBin, - Args: daemonArgs, - RunFunc: (*exec.Cmd).Start, - }) + res := n.Runner.MustRun(newReq) n.Daemon = res @@ -232,6 +242,12 @@ func (n *Node) StartDaemon(ipfsArgs ...string) *Node { return n } +func (n *Node) StartDaemon(ipfsArgs ...string) *Node { + return n.StartDaemonWithReq(RunRequest{ + Args: ipfsArgs, + }) +} + func (n *Node) signalAndWait(watch <-chan struct{}, signal os.Signal, t time.Duration) bool { err := n.Daemon.Cmd.Process.Signal(signal) if err != nil { diff --git a/test/cli/harness/run.go b/test/cli/harness/run.go index c2a3662be..75c07bcc2 100644 --- a/test/cli/harness/run.go +++ b/test/cli/harness/run.go @@ -142,3 +142,15 @@ func RunWithStdin(reader io.Reader) CmdOpt { func RunWithStdinStr(s string) CmdOpt { return RunWithStdin(strings.NewReader(s)) } + +func RunWithStdout(writer io.Writer) CmdOpt { + return func(cmd *exec.Cmd) { + cmd.Stdout = io.MultiWriter(writer, cmd.Stdout) + } +} + +func RunWithStderr(writer io.Writer) CmdOpt { + return func(cmd *exec.Cmd) { + cmd.Stderr = io.MultiWriter(writer, cmd.Stdout) + } +} diff --git a/test/cli/testutils/requires.go b/test/cli/testutils/requires.go index d4b88cd6d..1462b7fee 100644 --- a/test/cli/testutils/requires.go +++ b/test/cli/testutils/requires.go @@ -7,13 +7,13 @@ import ( ) func RequiresDocker(t *testing.T) { - if os.Getenv("TEST_NO_DOCKER") == "1" { + if os.Getenv("TEST_DOCKER") != "1" { t.SkipNow() } } func RequiresFUSE(t *testing.T) { - if os.Getenv("TEST_NO_FUSE") == "1" { + if os.Getenv("TEST_FUSE") != "1" { t.SkipNow() } } @@ -25,7 +25,7 @@ func RequiresExpensive(t *testing.T) { } func RequiresPlugins(t *testing.T) { - if os.Getenv("TEST_NO_PLUGIN") == "1" { + if os.Getenv("TEST_PLUGIN") != "1" { t.SkipNow() } } diff --git a/test/cli/tracing_test.go b/test/cli/tracing_test.go new file mode 100644 index 000000000..ef717716e --- /dev/null +++ b/test/cli/tracing_test.go @@ -0,0 +1,89 @@ +package cli + +import ( + "fmt" + "os" + "os/exec" + "path/filepath" + "strings" + "testing" + "time" + + "github.com/ipfs/kubo/test/cli/harness" + "github.com/ipfs/kubo/test/cli/testutils" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +var otelCollectorConfigYAML = ` +receivers: + otlp: + protocols: + grpc: + +processors: + batch: + +exporters: + file: + path: /traces/traces.json + +service: + pipelines: + traces: + receivers: [otlp] + processors: [batch] + exporters: [file] +` + +func TestTracing(t *testing.T) { + testutils.RequiresDocker(t) + t.Parallel() + node := harness.NewT(t).NewNode().Init() + + node.WriteBytes("collector-config.yaml", []byte(otelCollectorConfigYAML)) + + // touch traces.json and give it 777 perms in case Docker runs as a different user + node.WriteBytes("traces.json", nil) + err := os.Chmod(filepath.Join(node.Dir, "traces.json"), 0777) + require.NoError(t, err) + + dockerBin, err := exec.LookPath("docker") + require.NoError(t, err) + node.Runner.MustRun(harness.RunRequest{ + Path: dockerBin, + Args: []string{ + "run", + "--rm", + "--detach", + "--volume", fmt.Sprintf("%s:/config.yaml", filepath.Join(node.Dir, "collector-config.yaml")), + "--volume", fmt.Sprintf("%s:/traces", node.Dir), + "--net", "host", + "--name", "ipfs-test-otel-collector", + "otel/opentelemetry-collector-contrib:0.52.0", + "--config", "/config.yaml", + }, + }) + + t.Cleanup(func() { + node.Runner.MustRun(harness.RunRequest{ + Path: dockerBin, + Args: []string{"stop", "ipfs-test-otel-collector"}, + }) + }) + + node.Runner.Env["OTEL_TRACES_EXPORTER"] = "otlp" + node.Runner.Env["OTEL_EXPORTER_OTLP_PROTOCOL"] = "grpc" + node.Runner.Env["OTEL_EXPORTER_OTLP_ENDPOINT"] = "http://localhost:4317" + node.StartDaemon() + + assert.Eventually(t, + func() bool { + b, err := os.ReadFile(filepath.Join(node.Dir, "traces.json")) + require.NoError(t, err) + return strings.Contains(string(b), "go-ipfs") + }, + 5*time.Minute, + 10*time.Millisecond, + ) +} diff --git a/test/sharness/Rules.mk b/test/sharness/Rules.mk index f95aee15e..0dcd8d2e4 100644 --- a/test/sharness/Rules.mk +++ b/test/sharness/Rules.mk @@ -21,7 +21,7 @@ $(PLUGINS_$(d)): $(ORGIN_PLUGINS_$(d)) @mkdir -p $(@D) cp -f plugin/plugins/$(@F) $@ -ifneq ($(TEST_NO_PLUGIN),1) +ifneq ($(TEST_PLUGIN),0) DEPS_$(d) += $(PLUGINS_$(d)) endif endif diff --git a/test/sharness/lib/test-lib.sh b/test/sharness/lib/test-lib.sh index f135cdd79..bd8f7de9b 100644 --- a/test/sharness/lib/test-lib.sh +++ b/test/sharness/lib/test-lib.sh @@ -94,10 +94,10 @@ export TERM=dumb TEST_OS="$(uname -s | tr '[a-z]' '[A-Z]')" # grab + output options -test "$TEST_NO_FUSE" != 1 && test_set_prereq FUSE +test "$TEST_FUSE" = 1 && test_set_prereq FUSE test "$TEST_EXPENSIVE" = 1 && test_set_prereq EXPENSIVE -test "$TEST_NO_DOCKER" != 1 && type docker >/dev/null 2>&1 && groups | egrep "\bdocker\b" && test_set_prereq DOCKER -test "$TEST_NO_PLUGIN" != 1 && test "$TEST_OS" = "LINUX" && test_set_prereq PLUGIN +test "$TEST_DOCKER" = 1 && type docker >/dev/null 2>&1 && groups | egrep "\bdocker\b" && test_set_prereq DOCKER +test "$TEST_PLUGIN" = 1 && test "$TEST_OS" = "LINUX" && test_set_prereq PLUGIN # this may not be available, skip a few dependent tests type socat >/dev/null 2>&1 && test_set_prereq SOCAT @@ -110,9 +110,9 @@ expr "$TEST_OS" : "CYGWIN_NT" >/dev/null || test_set_prereq STD_ERR_MSG if test "$TEST_VERBOSE" = 1; then echo '# TEST_VERBOSE='"$TEST_VERBOSE" echo '# TEST_IMMEDIATE='"$TEST_IMMEDIATE" - echo '# TEST_NO_FUSE='"$TEST_NO_FUSE" - echo '# TEST_NO_DOCKER='"$TEST_NO_DOCKER" - echo '# TEST_NO_PLUGIN='"$TEST_NO_PLUGIN" + echo '# TEST_FUSE='"$TEST_FUSE" + echo '# TEST_DOCKER='"$TEST_DOCKER" + echo '# TEST_PLUGIN='"$TEST_PLUGIN" echo '# TEST_EXPENSIVE='"$TEST_EXPENSIVE" echo '# TEST_OS='"$TEST_OS" echo '# TEST_JUNIT='"$TEST_JUNIT" diff --git a/test/sharness/t0230-channel-streaming-http-content-type.sh b/test/sharness/t0230-channel-streaming-http-content-type.sh index 055b342d1..be23d8151 100755 --- a/test/sharness/t0230-channel-streaming-http-content-type.sh +++ b/test/sharness/t0230-channel-streaming-http-content-type.sh @@ -23,7 +23,6 @@ test_ls_cmd() { printf "HTTP/1.1 200 OK\r\n" >expected_output && printf "Access-Control-Allow-Headers: X-Stream-Output, X-Chunked-Output, X-Content-Length\r\n" >>expected_output && printf "Access-Control-Expose-Headers: X-Stream-Output, X-Chunked-Output, X-Content-Length\r\n" >>expected_output && - printf "Connection: close\r\n" >>expected_output && printf "Content-Type: text/plain\r\n" >>expected_output && printf "Server: kubo/%s\r\n" $(ipfs version -n) >>expected_output && printf "Trailer: X-Stream-Error\r\n" >>expected_output && @@ -47,7 +46,6 @@ test_ls_cmd() { printf "HTTP/1.1 200 OK\r\n" >expected_output && printf "Access-Control-Allow-Headers: X-Stream-Output, X-Chunked-Output, X-Content-Length\r\n" >>expected_output && printf "Access-Control-Expose-Headers: X-Stream-Output, X-Chunked-Output, X-Content-Length\r\n" >>expected_output && - printf "Connection: close\r\n" >>expected_output && printf "Content-Type: application/json\r\n" >>expected_output && printf "Server: kubo/%s\r\n" $(ipfs version -n) >>expected_output && printf "Trailer: X-Stream-Error\r\n" >>expected_output && diff --git a/test/sharness/t0310-tracing.sh b/test/sharness/t0310-tracing.sh deleted file mode 100755 index 96d07ae8d..000000000 --- a/test/sharness/t0310-tracing.sh +++ /dev/null @@ -1,57 +0,0 @@ -#!/usr/bin/env bash -# -# Copyright (c) 2022 Protocol Labs -# MIT/Apache-2.0 Licensed; see the LICENSE file in this repository. -# - -test_description="Test tracing" - -. lib/test-lib.sh - -test_init_ipfs - -export OTEL_TRACES_EXPORTER=otlp -export OTEL_EXPORTER_OTLP_PROTOCOL=grpc -export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317 - -cat < collector-config.yaml -receivers: - otlp: - protocols: - grpc: - -processors: - batch: - -exporters: - file: - path: /traces/traces.json - -service: - pipelines: - traces: - receivers: [otlp] - processors: [batch] - exporters: [file] -EOF - -# touch traces.json and give it 777 perms, in case docker runs as a different user -rm -rf traces.json && touch traces.json && chmod 777 traces.json - -test_expect_success "run opentelemetry collector" ' - docker run --rm -d -v "$PWD/collector-config.yaml":/config.yaml -v "$PWD":/traces --net=host --name=ipfs-test-otel-collector otel/opentelemetry-collector-contrib:0.52.0 --config /config.yaml -' - -test_launch_ipfs_daemon - -test_expect_success "check that a swarm span eventually appears in exported traces" ' - until cat traces.json | grep CoreAPI.SwarmAPI >/dev/null; do sleep 0.1; done -' - -test_expect_success "kill docker container" ' - docker kill ipfs-test-otel-collector -' - -test_kill_ipfs_daemon - -test_done From 0ec22f4adde242c0299c3763af4cd823adf18527 Mon Sep 17 00:00:00 2001 From: Piotr Galar Date: Wed, 5 Apr 2023 14:02:20 +0200 Subject: [PATCH 0613/1212] chore: update deps after v0.19.0 release (#9744) Co-authored-by: Henrique Dias --- docs/examples/kubo-as-a-library/go.mod | 40 ++++----- docs/examples/kubo-as-a-library/go.sum | 84 ++++++++++-------- go.mod | 52 ++++++------ go.sum | 113 +++++++++++++++---------- 4 files changed, 159 insertions(+), 130 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 7528602ae..d70ff4553 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -10,13 +10,13 @@ require ( github.com/ipfs/boxo v0.8.0-rc4 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.26.4 - github.com/multiformats/go-multiaddr v0.8.0 + github.com/multiformats/go-multiaddr v0.9.0 ) require ( bazil.org/fuse v0.0.0-20200117225306-7b5117fecadc // indirect github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 // indirect - github.com/alecthomas/units v0.0.0-20210927113745-59d0afb8317a // indirect + github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5 // indirect github.com/benbjohnson/clock v1.3.0 // indirect github.com/beorn7/perks v1.0.1 // indirect @@ -35,9 +35,8 @@ require ( github.com/dgraph-io/badger v1.6.2 // indirect github.com/dgraph-io/ristretto v0.0.2 // indirect github.com/docker/go-units v0.5.0 // indirect - github.com/dustin/go-humanize v1.0.0 // indirect + github.com/dustin/go-humanize v1.0.1 // indirect github.com/elastic/gosigar v0.14.2 // indirect - github.com/emirpasic/gods v1.18.1 // indirect github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5 // indirect github.com/flynn/noise v1.0.0 // indirect github.com/francoispqt/gojay v1.2.13 // indirect @@ -64,7 +63,7 @@ require ( github.com/ipfs/bbloom v0.0.4 // indirect github.com/ipfs/go-bitfield v1.1.0 // indirect github.com/ipfs/go-block-format v0.1.2 // indirect - github.com/ipfs/go-cid v0.4.0 // indirect + github.com/ipfs/go-cid v0.4.1 // indirect github.com/ipfs/go-cidutil v0.1.0 // indirect github.com/ipfs/go-datastore v0.6.0 // indirect github.com/ipfs/go-delegated-routing v0.8.0 // indirect @@ -73,10 +72,11 @@ require ( github.com/ipfs/go-ds-leveldb v0.5.0 // indirect github.com/ipfs/go-ds-measure v0.2.0 // indirect github.com/ipfs/go-fs-lock v0.0.7 // indirect - github.com/ipfs/go-graphsync v0.14.1 // indirect + github.com/ipfs/go-graphsync v0.14.4 // indirect github.com/ipfs/go-ipfs-blockstore v1.3.0 // indirect github.com/ipfs/go-ipfs-delay v0.0.1 // indirect github.com/ipfs/go-ipfs-ds-help v1.1.0 // indirect + github.com/ipfs/go-ipfs-files v0.3.0 // indirect github.com/ipfs/go-ipfs-pq v0.0.3 // indirect github.com/ipfs/go-ipfs-redirects-file v0.1.1 // indirect github.com/ipfs/go-ipfs-util v0.0.2 // indirect @@ -96,7 +96,7 @@ require ( github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect github.com/jbenet/goprocess v0.1.4 // indirect github.com/klauspost/compress v1.15.12 // indirect - github.com/klauspost/cpuid/v2 v2.2.3 // indirect + github.com/klauspost/cpuid/v2 v2.2.4 // indirect github.com/koron/go-ssdp v0.0.3 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/libp2p/go-cidranger v1.1.0 // indirect @@ -105,7 +105,7 @@ require ( github.com/libp2p/go-libp2p-asn-util v0.3.0 // indirect github.com/libp2p/go-libp2p-kad-dht v0.22.0 // indirect github.com/libp2p/go-libp2p-kbucket v0.5.0 // indirect - github.com/libp2p/go-libp2p-pubsub v0.9.0 // indirect + github.com/libp2p/go-libp2p-pubsub v0.9.3 // indirect github.com/libp2p/go-libp2p-pubsub-router v0.6.0 // indirect github.com/libp2p/go-libp2p-record v0.2.0 // indirect github.com/libp2p/go-libp2p-routing-helpers v0.6.2 // indirect @@ -130,7 +130,7 @@ require ( github.com/multiformats/go-base36 v0.2.0 // indirect github.com/multiformats/go-multiaddr-dns v0.3.1 // indirect github.com/multiformats/go-multiaddr-fmt v0.1.0 // indirect - github.com/multiformats/go-multibase v0.1.1 // indirect + github.com/multiformats/go-multibase v0.2.0 // indirect github.com/multiformats/go-multicodec v0.8.1 // indirect github.com/multiformats/go-multihash v0.2.1 // indirect github.com/multiformats/go-multistream v0.4.1 // indirect @@ -174,23 +174,23 @@ require ( go.opentelemetry.io/otel/trace v1.14.0 // indirect go.opentelemetry.io/proto/otlp v0.19.0 // indirect go.uber.org/atomic v1.10.0 // indirect - go.uber.org/dig v1.15.0 // indirect - go.uber.org/fx v1.18.2 // indirect - go.uber.org/multierr v1.9.0 // indirect + go.uber.org/dig v1.16.1 // indirect + go.uber.org/fx v1.19.2 // indirect + go.uber.org/multierr v1.10.0 // indirect go.uber.org/zap v1.24.0 // indirect - go4.org v0.0.0-20200411211856-f5505b9728dd // indirect - golang.org/x/crypto v0.6.0 // indirect + go4.org v0.0.0-20230225012048-214862532bf5 // indirect + golang.org/x/crypto v0.7.0 // indirect golang.org/x/exp v0.0.0-20230213192124-5e25df0256eb // indirect - golang.org/x/mod v0.7.0 // indirect - golang.org/x/net v0.7.0 // indirect + golang.org/x/mod v0.10.0 // indirect + golang.org/x/net v0.8.0 // indirect golang.org/x/sync v0.1.0 // indirect - golang.org/x/sys v0.6.0 // indirect - golang.org/x/text v0.7.0 // indirect - golang.org/x/tools v0.3.0 // indirect + golang.org/x/sys v0.7.0 // indirect + golang.org/x/text v0.8.0 // indirect + golang.org/x/tools v0.6.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect google.golang.org/grpc v1.53.0 // indirect - google.golang.org/protobuf v1.28.1 // indirect + google.golang.org/protobuf v1.30.0 // indirect gopkg.in/square/go-jose.v2 v2.5.1 // indirect lukechampine.com/blake3 v1.1.7 // indirect nhooyr.io/websocket v1.8.7 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index d42cf6441..92576a4ce 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -53,8 +53,8 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= -github.com/alecthomas/units v0.0.0-20210927113745-59d0afb8317a h1:E/8AP5dFtMhl5KPJz66Kt9G0n+7Sn41Fy1wv9/jHOrc= -github.com/alecthomas/units v0.0.0-20210927113745-59d0afb8317a/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= +github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 h1:s6gZFSlWYmbqAuRjVTiNNhvNRfY2Wxp9nhfyel4rklc= +github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5 h1:iW0a5ljuFxkLGPNem5Ui+KBjFJzKg4Fv2fnxe4dvzpM= github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5/go.mod h1:Y2QMoi1vgtOIfc+6DhrMOGkLoGzqSV2rKp4Sm+opsyA= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= @@ -143,13 +143,12 @@ github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUn github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= +github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/elastic/gosigar v0.12.0/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= github.com/elastic/gosigar v0.14.2 h1:Dg80n8cr90OZ7x+bAax/QjoW/XqTI11RmA79ZwIm9/4= github.com/elastic/gosigar v0.14.2/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= -github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= -github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -353,8 +352,8 @@ github.com/ipfs/go-cid v0.0.4/go.mod h1:4LLaPOQwmk5z9LBgQnpkivrx8BJjUyGwTXCd5Xfj github.com/ipfs/go-cid v0.0.5/go.mod h1:plgt+Y5MnOey4vO4UlUazGqdbEXuFYitED67FexhXog= github.com/ipfs/go-cid v0.0.6/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I= github.com/ipfs/go-cid v0.0.7/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I= -github.com/ipfs/go-cid v0.4.0 h1:a4pdZq0sx6ZSxbCizebnKiMCx/xI/aBBFlB73IgH4rA= -github.com/ipfs/go-cid v0.4.0/go.mod h1:uQHwDeX4c6CtyrFwdqyhpNcxVewur1M7l7fNU7LKwZk= +github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= +github.com/ipfs/go-cid v0.4.1/go.mod h1:uQHwDeX4c6CtyrFwdqyhpNcxVewur1M7l7fNU7LKwZk= github.com/ipfs/go-cidutil v0.1.0 h1:RW5hO7Vcf16dplUU60Hs0AKDkQAVPVplr7lk97CFL+Q= github.com/ipfs/go-cidutil v0.1.0/go.mod h1:e7OEVBMIv9JaOxt9zaGEmAoSlXW9jdFZ5lP/0PwcfpA= github.com/ipfs/go-datastore v0.1.0/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= @@ -378,8 +377,8 @@ github.com/ipfs/go-ds-measure v0.2.0 h1:sG4goQe0KDTccHMyT45CY1XyUbxe5VwTKpg2LjAp github.com/ipfs/go-ds-measure v0.2.0/go.mod h1:SEUD/rE2PwRa4IQEC5FuNAmjJCyYObZr9UvVh8V3JxE= github.com/ipfs/go-fs-lock v0.0.7 h1:6BR3dajORFrFTkb5EpCUFIAypsoxpGpDSVUdFwzgL9U= github.com/ipfs/go-fs-lock v0.0.7/go.mod h1:Js8ka+FNYmgQRLrRXzU3CB/+Csr1BwrRilEcvYrHhhc= -github.com/ipfs/go-graphsync v0.14.1 h1:tvFpBY9LcehIB7zi5SZIa+7aoxBOrGbdekhOXdnlT70= -github.com/ipfs/go-graphsync v0.14.1/go.mod h1:S6O/c5iXOXqDgrQgiZSgOTRUSiVvpKEhrzqFHKnLVcs= +github.com/ipfs/go-graphsync v0.14.4 h1:ysazATpwsIjYtYEZH5CdD/HRaonCJd4pASUtnzESewk= +github.com/ipfs/go-graphsync v0.14.4/go.mod h1:yT0AfjFgicOoWdAlUJ96tQ5AkuGI4r1taIQX/aHbBQo= github.com/ipfs/go-ipfs-blockstore v1.3.0 h1:m2EXaWgwTzAfsmt5UdJ7Is6l4gJcaM/A12XwJyvYvMM= github.com/ipfs/go-ipfs-blockstore v1.3.0/go.mod h1:KgtZyc9fq+P2xJUiCAzbRdhhqJHvsw8u2Dlqy2MyRTE= github.com/ipfs/go-ipfs-blocksutil v0.0.1 h1:Eh/H4pc1hsvhzsQoMEP3Bke/aW5P5rVM1IWFJMcGIPQ= @@ -392,6 +391,7 @@ github.com/ipfs/go-ipfs-ds-help v1.1.0/go.mod h1:YR5+6EaebOhfcqVCyqemItCLthrpVNo github.com/ipfs/go-ipfs-exchange-interface v0.2.0 h1:8lMSJmKogZYNo2jjhUs0izT+dck05pqUw4mWNW9Pw6Y= github.com/ipfs/go-ipfs-exchange-offline v0.3.0 h1:c/Dg8GDPzixGd0MC8Jh6mjOwU57uYokgWRFidfvEkuA= github.com/ipfs/go-ipfs-files v0.3.0 h1:fallckyc5PYjuMEitPNrjRfpwl7YFt69heCOUhsbGxQ= +github.com/ipfs/go-ipfs-files v0.3.0/go.mod h1:xAUtYMwB+iu/dtf6+muHNSFQCJG2dSiStR2P6sn9tIM= github.com/ipfs/go-ipfs-posinfo v0.0.1 h1:Esoxj+1JgSjX0+ylc0hUmJCOv6V2vFoZiETLR6OtpRs= github.com/ipfs/go-ipfs-pq v0.0.3 h1:YpoHVJB+jzK15mr/xsWC574tyDLkezVrDNeaalQBsTE= github.com/ipfs/go-ipfs-pq v0.0.3/go.mod h1:btNw5hsHBpRcSSgZtiNm/SLj5gYIZ18AKtv3kERkRb4= @@ -480,8 +480,8 @@ github.com/klauspost/compress v1.15.12 h1:YClS/PImqYbn+UILDnqxQCZ3RehC9N318SU3kE github.com/klauspost/compress v1.15.12/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.2.3 h1:sxCkb+qR91z4vsqw4vGGZlDgPz3G7gjaLyK3V8y70BU= -github.com/klauspost/cpuid/v2 v2.2.3/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= +github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk= +github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/koron/go-ssdp v0.0.0-20191105050749-2e1c40ed0b5d/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk= @@ -524,8 +524,8 @@ github.com/libp2p/go-libp2p-kbucket v0.3.1/go.mod h1:oyjT5O7tS9CQurok++ERgc46YLw github.com/libp2p/go-libp2p-kbucket v0.5.0 h1:g/7tVm8ACHDxH29BGrpsQlnNeu+6OF1A9bno/4/U1oA= github.com/libp2p/go-libp2p-kbucket v0.5.0/go.mod h1:zGzGCpQd78b5BNTDGHNDLaTt9aDK/A02xeZp9QeFC4U= github.com/libp2p/go-libp2p-peerstore v0.1.4/go.mod h1:+4BDbDiiKf4PzpANZDAT+knVdLxvqh7hXOujessqdzs= -github.com/libp2p/go-libp2p-pubsub v0.9.0 h1:mcLb4WzwhUG4OKb0rp1/bYMd/DYhvMyzJheQH3LMd1s= -github.com/libp2p/go-libp2p-pubsub v0.9.0/go.mod h1:OEsj0Cc/BpkqikXRTrVspWU/Hx7bMZwHP+6vNMd+c7I= +github.com/libp2p/go-libp2p-pubsub v0.9.3 h1:ihcz9oIBMaCK9kcx+yHWm3mLAFBMAUsM4ux42aikDxo= +github.com/libp2p/go-libp2p-pubsub v0.9.3/go.mod h1:RYA7aM9jIic5VV47WXu4GkcRxRhrdElWf8xtyli+Dzc= github.com/libp2p/go-libp2p-pubsub-router v0.6.0 h1:D30iKdlqDt5ZmLEYhHELCMRj8b4sFAqrUcshIUvVP/s= github.com/libp2p/go-libp2p-pubsub-router v0.6.0/go.mod h1:FY/q0/RBTKsLA7l4vqC2cbRbOvyDotg8PJQ7j8FDudE= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= @@ -614,8 +614,8 @@ github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a github.com/multiformats/go-multiaddr v0.1.0/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo= github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4= -github.com/multiformats/go-multiaddr v0.8.0 h1:aqjksEcqK+iD/Foe1RRFsGZh8+XFiGo7FgUCZlpv3LU= -github.com/multiformats/go-multiaddr v0.8.0/go.mod h1:Fs50eBDWvZu+l3/9S6xAE7ZYj6yhxlvaVZjakWN7xRs= +github.com/multiformats/go-multiaddr v0.9.0 h1:3h4V1LHIk5w4hJHekMKWALPXErDfz/sggzwC/NcqbDQ= +github.com/multiformats/go-multiaddr v0.9.0/go.mod h1:mI67Lb1EeTOYb8GQfL/7wpIZwc46ElrvzhYnoJOmTT0= github.com/multiformats/go-multiaddr-dns v0.3.0/go.mod h1:mNzQ4eTGDg0ll1N9jKPOUogZPoJ30W8a7zk66FQPpdQ= github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A= github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk= @@ -624,8 +624,8 @@ github.com/multiformats/go-multiaddr-fmt v0.1.0/go.mod h1:hGtDIW4PU4BqJ50gW2quDu github.com/multiformats/go-multiaddr-net v0.1.1/go.mod h1:5JNbcfBOP4dnhoZOv10JJVkJO0pCCEf8mTnipAo2UZQ= github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= github.com/multiformats/go-multibase v0.0.3/go.mod h1:5+1R4eQrT3PkYZ24C3W2Ue2tPwIdYQD509ZjSb5y9Oc= -github.com/multiformats/go-multibase v0.1.1 h1:3ASCDsuLX8+j4kx58qnJ4YFq/JWTJpCyDW27ztsVTOI= -github.com/multiformats/go-multibase v0.1.1/go.mod h1:ZEjHE+IsUrgp5mhlEAYjMtZwK1k4haNkcaPg9aoe1a8= +github.com/multiformats/go-multibase v0.2.0 h1:isdYCVLvksgWlMW9OZRYJEa9pZETFivncJHmHnnd87g= +github.com/multiformats/go-multibase v0.2.0/go.mod h1:bFBZX4lKCA/2lyOFSAoKH5SS6oPyjtnzK/XTFDPkNuk= github.com/multiformats/go-multicodec v0.3.0/go.mod h1:qGGaQmioCDh+TeFOnxrbU0DaIPw8yFgAZgFG0V7p1qQ= github.com/multiformats/go-multicodec v0.8.1 h1:ycepHwavHafh3grIbR1jIXnKCsFm0fqsfEOsJ8NtKE8= github.com/multiformats/go-multicodec v0.8.1/go.mod h1:L3QTQvMIaVBkXOXXtVmYE+LI16i14xuaojr/H7Ai54k= @@ -846,6 +846,7 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= @@ -883,17 +884,17 @@ go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/dig v1.15.0 h1:vq3YWr8zRj1eFGC7Gvf907hE0eRjPTZ1d3xHadD6liE= -go.uber.org/dig v1.15.0/go.mod h1:pKHs0wMynzL6brANhB2hLMro+zalv1osARTviTcqHLM= -go.uber.org/fx v1.18.2 h1:bUNI6oShr+OVFQeU8cDNbnN7VFsu+SsjHzUF51V/GAU= -go.uber.org/fx v1.18.2/go.mod h1:g0V1KMQ66zIRk8bLu3Ea5Jt2w/cHlOIp4wdRsgh0JaY= +go.uber.org/dig v1.16.1 h1:+alNIBsl0qfY0j6epRubp/9obgtrObRAc5aD+6jbWY8= +go.uber.org/dig v1.16.1/go.mod h1:557JTAUZT5bUK0SvCwikmLPPtdQhfvLYtO5tJgQSbnk= +go.uber.org/fx v1.19.2 h1:SyFgYQFr1Wl0AYstE8vyYIzP4bFz2URrScjwC4cwUvY= +go.uber.org/fx v1.19.2/go.mod h1:43G1VcqSzbIv77y00p1DRAsyZS8WdzuYdhZXmEUkMyQ= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= -go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= -go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ= +go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ= +go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.14.1/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= @@ -902,8 +903,9 @@ go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= -go4.org v0.0.0-20200411211856-f5505b9728dd h1:BNJlw5kRTzdmyfh5U8F93HA2OwkP7ZGwA51eJ/0wKOU= go4.org v0.0.0-20200411211856-f5505b9728dd/go.mod h1:CIiUVy99QCPfoE13bO4EZaz5GZMZXMSBGhxRdsvzbkg= +go4.org v0.0.0-20230225012048-214862532bf5 h1:nifaUDeh+rPaBCMPMQHZmvJf+QdpLFnuQPwx+LxVmtc= +go4.org v0.0.0-20230225012048-214862532bf5/go.mod h1:F57wTi5Lrj6WLyswp5EYV1ncrEbFGHD4hhz6S1ZYeaU= golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -920,8 +922,9 @@ golang.org/x/crypto v0.0.0-20200602180216-279210d13fed/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc= -golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A= +golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -956,8 +959,9 @@ golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA= -golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk= +golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1005,8 +1009,10 @@ golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1029,6 +1035,7 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1098,12 +1105,15 @@ golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= +golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1112,8 +1122,9 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1171,8 +1182,9 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.3.0 h1:SrNbZl6ECOS1qFzgTdQfWXZM9XBkiA6tkFrH9YSTPHM= -golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1278,8 +1290,8 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= -google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= +google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/go.mod b/go.mod index 1b7893475..04c92fcd4 100644 --- a/go.mod +++ b/go.mod @@ -2,14 +2,14 @@ module github.com/ipfs/kubo require ( bazil.org/fuse v0.0.0-20200117225306-7b5117fecadc - contrib.go.opencensus.io/exporter/prometheus v0.4.0 + contrib.go.opencensus.io/exporter/prometheus v0.4.2 github.com/benbjohnson/clock v1.3.0 github.com/blang/semver/v4 v4.0.0 github.com/cenkalti/backoff/v4 v4.2.0 github.com/ceramicnetwork/go-dag-jose v0.1.0 github.com/cheggaaa/pb v1.0.29 github.com/coreos/go-systemd/v22 v22.5.0 - github.com/dustin/go-humanize v1.0.0 + github.com/dustin/go-humanize v1.0.1 github.com/elgris/jsondiff v0.0.0-20160530203242-765b5c24c302 github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5 github.com/fsnotify/fsnotify v1.6.0 @@ -18,7 +18,7 @@ require ( github.com/hashicorp/go-multierror v1.1.1 github.com/ipfs/boxo v0.8.0-rc4 github.com/ipfs/go-block-format v0.1.2 - github.com/ipfs/go-cid v0.4.0 + github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 github.com/ipfs/go-datastore v0.6.0 github.com/ipfs/go-delegated-routing v0.8.0 @@ -28,7 +28,7 @@ require ( github.com/ipfs/go-ds-leveldb v0.5.0 github.com/ipfs/go-ds-measure v0.2.0 github.com/ipfs/go-fs-lock v0.0.7 - github.com/ipfs/go-graphsync v0.14.0 + github.com/ipfs/go-graphsync v0.14.4 github.com/ipfs/go-ipfs-cmds v0.9.0 github.com/ipfs/go-ipld-format v0.4.0 github.com/ipfs/go-ipld-git v0.1.1 @@ -46,19 +46,19 @@ require ( github.com/julienschmidt/httprouter v1.3.0 github.com/libp2p/go-doh-resolver v0.4.0 github.com/libp2p/go-libp2p v0.26.4 - github.com/libp2p/go-libp2p-http v0.4.0 + github.com/libp2p/go-libp2p-http v0.5.0 github.com/libp2p/go-libp2p-kad-dht v0.22.0 github.com/libp2p/go-libp2p-kbucket v0.5.0 - github.com/libp2p/go-libp2p-pubsub v0.9.0 + github.com/libp2p/go-libp2p-pubsub v0.9.3 github.com/libp2p/go-libp2p-pubsub-router v0.6.0 github.com/libp2p/go-libp2p-record v0.2.0 github.com/libp2p/go-libp2p-routing-helpers v0.6.2 github.com/libp2p/go-libp2p-testing v0.12.0 github.com/libp2p/go-socket-activation v0.1.0 github.com/mitchellh/go-homedir v1.1.0 - github.com/multiformats/go-multiaddr v0.8.0 + github.com/multiformats/go-multiaddr v0.9.0 github.com/multiformats/go-multiaddr-dns v0.3.1 - github.com/multiformats/go-multibase v0.1.1 + github.com/multiformats/go-multibase v0.2.0 github.com/multiformats/go-multicodec v0.8.1 github.com/multiformats/go-multihash v0.2.1 github.com/opentracing/opentracing-go v1.2.0 @@ -81,19 +81,19 @@ require ( go.opentelemetry.io/otel/exporters/zipkin v1.14.0 go.opentelemetry.io/otel/sdk v1.14.0 go.opentelemetry.io/otel/trace v1.14.0 - go.uber.org/dig v1.15.0 - go.uber.org/fx v1.18.2 + go.uber.org/dig v1.16.1 + go.uber.org/fx v1.19.2 go.uber.org/zap v1.24.0 - golang.org/x/crypto v0.6.0 - golang.org/x/mod v0.7.0 + golang.org/x/crypto v0.7.0 + golang.org/x/mod v0.10.0 golang.org/x/sync v0.1.0 - golang.org/x/sys v0.6.0 + golang.org/x/sys v0.7.0 ) require ( github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 // indirect github.com/Kubuxu/go-os-helper v0.0.1 // indirect - github.com/alecthomas/units v0.0.0-20210927113745-59d0afb8317a // indirect + github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cenkalti/backoff v2.2.1+incompatible // indirect @@ -109,12 +109,11 @@ require ( github.com/dgraph-io/ristretto v0.0.2 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/elastic/gosigar v0.14.2 // indirect - github.com/emirpasic/gods v1.18.1 // indirect github.com/felixge/httpsnoop v1.0.3 // indirect github.com/flynn/noise v1.0.0 // indirect github.com/francoispqt/gojay v1.2.13 // indirect github.com/gabriel-vasile/mimetype v1.4.1 // indirect - github.com/go-kit/log v0.2.0 // indirect + github.com/go-kit/log v0.2.1 // indirect github.com/go-logfmt/logfmt v0.5.1 // indirect github.com/go-logr/logr v1.2.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect @@ -138,7 +137,6 @@ require ( github.com/ipfs/go-ipfs-blockstore v1.3.0 // indirect github.com/ipfs/go-ipfs-delay v0.0.1 // indirect github.com/ipfs/go-ipfs-ds-help v1.1.0 // indirect - github.com/ipfs/go-ipfs-files v0.3.0 // indirect github.com/ipfs/go-ipfs-pq v0.0.3 // indirect github.com/ipfs/go-ipfs-redirects-file v0.1.1 // indirect github.com/ipfs/go-ipfs-util v0.0.2 // indirect @@ -148,13 +146,13 @@ require ( github.com/ipld/edelweiss v0.2.0 // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/klauspost/compress v1.15.12 // indirect - github.com/klauspost/cpuid/v2 v2.2.3 // indirect + github.com/klauspost/cpuid/v2 v2.2.4 // indirect github.com/koron/go-ssdp v0.0.3 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/libp2p/go-cidranger v1.1.0 // indirect github.com/libp2p/go-flow-metrics v0.1.0 // indirect github.com/libp2p/go-libp2p-asn-util v0.2.0 // indirect - github.com/libp2p/go-libp2p-gostream v0.5.0 // indirect + github.com/libp2p/go-libp2p-gostream v0.6.0 // indirect github.com/libp2p/go-libp2p-xor v0.1.0 // indirect github.com/libp2p/go-mplex v0.7.0 // indirect github.com/libp2p/go-msgio v0.3.0 // indirect @@ -187,7 +185,7 @@ require ( github.com/prometheus/client_model v0.3.0 // indirect github.com/prometheus/common v0.37.0 // indirect github.com/prometheus/procfs v0.8.0 // indirect - github.com/prometheus/statsd_exporter v0.21.0 // indirect + github.com/prometheus/statsd_exporter v0.22.7 // indirect github.com/quic-go/qpack v0.4.0 // indirect github.com/quic-go/qtls-go1-19 v0.2.1 // indirect github.com/quic-go/qtls-go1-20 v0.1.1 // indirect @@ -210,19 +208,19 @@ require ( go.opentelemetry.io/otel/metric v0.37.0 // indirect go.opentelemetry.io/proto/otlp v0.19.0 // indirect go.uber.org/atomic v1.10.0 // indirect - go.uber.org/multierr v1.9.0 // indirect - go4.org v0.0.0-20200411211856-f5505b9728dd // indirect + go.uber.org/multierr v1.10.0 // indirect + go4.org v0.0.0-20230225012048-214862532bf5 // indirect golang.org/x/exp v0.0.0-20230213192124-5e25df0256eb // indirect - golang.org/x/net v0.7.0 // indirect + golang.org/x/net v0.8.0 // indirect golang.org/x/oauth2 v0.4.0 // indirect - golang.org/x/term v0.5.0 // indirect - golang.org/x/text v0.7.0 // indirect - golang.org/x/tools v0.3.0 // indirect + golang.org/x/term v0.6.0 // indirect + golang.org/x/text v0.8.0 // indirect + golang.org/x/tools v0.6.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect google.golang.org/grpc v1.53.0 // indirect - google.golang.org/protobuf v1.28.1 // indirect + google.golang.org/protobuf v1.30.0 // indirect gopkg.in/square/go-jose.v2 v2.5.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 858e36850..63fed62b8 100644 --- a/go.sum +++ b/go.sum @@ -34,8 +34,8 @@ cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0Zeo cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -contrib.go.opencensus.io/exporter/prometheus v0.4.0 h1:0QfIkj9z/iVZgK31D9H9ohjjIDApI2GOPScCKwxedbs= -contrib.go.opencensus.io/exporter/prometheus v0.4.0/go.mod h1:o7cosnyfuPVK0tB8q0QmaQNhGnptITnPQB+z1+qeFB0= +contrib.go.opencensus.io/exporter/prometheus v0.4.2 h1:sqfsYl5GIY/L570iT+l93ehxaWJs2/OwXtiWwew3oAg= +contrib.go.opencensus.io/exporter/prometheus v0.4.2/go.mod h1:dvEHbiKmgvbr5pjaF9fpw1KeYcjrnC1J8B+JKjsZyRQ= dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU= @@ -57,8 +57,8 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= -github.com/alecthomas/units v0.0.0-20210927113745-59d0afb8317a h1:E/8AP5dFtMhl5KPJz66Kt9G0n+7Sn41Fy1wv9/jHOrc= -github.com/alecthomas/units v0.0.0-20210927113745-59d0afb8317a/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= +github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 h1:s6gZFSlWYmbqAuRjVTiNNhvNRfY2Wxp9nhfyel4rklc= +github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5 h1:iW0a5ljuFxkLGPNem5Ui+KBjFJzKg4Fv2fnxe4dvzpM= github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5/go.mod h1:Y2QMoi1vgtOIfc+6DhrMOGkLoGzqSV2rKp4Sm+opsyA= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= @@ -150,15 +150,14 @@ github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUn github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= +github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/elastic/gosigar v0.12.0/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= github.com/elastic/gosigar v0.14.2 h1:Dg80n8cr90OZ7x+bAax/QjoW/XqTI11RmA79ZwIm9/4= github.com/elastic/gosigar v0.14.2/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/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= -github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -200,8 +199,9 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2 github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= -github.com/go-kit/log v0.2.0 h1:7i2K3eKTos3Vc0enKCfnVcgHh2olr/MyfboYq7cAcFw= github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= +github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU= +github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= @@ -291,6 +291,7 @@ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ 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= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= @@ -370,8 +371,8 @@ github.com/ipfs/go-cid v0.0.4/go.mod h1:4LLaPOQwmk5z9LBgQnpkivrx8BJjUyGwTXCd5Xfj github.com/ipfs/go-cid v0.0.5/go.mod h1:plgt+Y5MnOey4vO4UlUazGqdbEXuFYitED67FexhXog= github.com/ipfs/go-cid v0.0.6/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I= github.com/ipfs/go-cid v0.0.7/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I= -github.com/ipfs/go-cid v0.4.0 h1:a4pdZq0sx6ZSxbCizebnKiMCx/xI/aBBFlB73IgH4rA= -github.com/ipfs/go-cid v0.4.0/go.mod h1:uQHwDeX4c6CtyrFwdqyhpNcxVewur1M7l7fNU7LKwZk= +github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= +github.com/ipfs/go-cid v0.4.1/go.mod h1:uQHwDeX4c6CtyrFwdqyhpNcxVewur1M7l7fNU7LKwZk= github.com/ipfs/go-cidutil v0.1.0 h1:RW5hO7Vcf16dplUU60Hs0AKDkQAVPVplr7lk97CFL+Q= github.com/ipfs/go-cidutil v0.1.0/go.mod h1:e7OEVBMIv9JaOxt9zaGEmAoSlXW9jdFZ5lP/0PwcfpA= github.com/ipfs/go-datastore v0.1.0/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= @@ -395,8 +396,8 @@ github.com/ipfs/go-ds-measure v0.2.0 h1:sG4goQe0KDTccHMyT45CY1XyUbxe5VwTKpg2LjAp github.com/ipfs/go-ds-measure v0.2.0/go.mod h1:SEUD/rE2PwRa4IQEC5FuNAmjJCyYObZr9UvVh8V3JxE= github.com/ipfs/go-fs-lock v0.0.7 h1:6BR3dajORFrFTkb5EpCUFIAypsoxpGpDSVUdFwzgL9U= github.com/ipfs/go-fs-lock v0.0.7/go.mod h1:Js8ka+FNYmgQRLrRXzU3CB/+Csr1BwrRilEcvYrHhhc= -github.com/ipfs/go-graphsync v0.14.0 h1:f5KYkc8GpwwE1BrjBOWxIkRivXIw7fVqGZlnILpvbSc= -github.com/ipfs/go-graphsync v0.14.0/go.mod h1:1LDVVnNHjit8ddJOtw3Jq9epP792xWFXXL3dJWIBIkM= +github.com/ipfs/go-graphsync v0.14.4 h1:ysazATpwsIjYtYEZH5CdD/HRaonCJd4pASUtnzESewk= +github.com/ipfs/go-graphsync v0.14.4/go.mod h1:yT0AfjFgicOoWdAlUJ96tQ5AkuGI4r1taIQX/aHbBQo= github.com/ipfs/go-ipfs-blockstore v1.3.0 h1:m2EXaWgwTzAfsmt5UdJ7Is6l4gJcaM/A12XwJyvYvMM= github.com/ipfs/go-ipfs-blockstore v1.3.0/go.mod h1:KgtZyc9fq+P2xJUiCAzbRdhhqJHvsw8u2Dlqy2MyRTE= github.com/ipfs/go-ipfs-blocksutil v0.0.1 h1:Eh/H4pc1hsvhzsQoMEP3Bke/aW5P5rVM1IWFJMcGIPQ= @@ -411,7 +412,6 @@ github.com/ipfs/go-ipfs-ds-help v1.1.0/go.mod h1:YR5+6EaebOhfcqVCyqemItCLthrpVNo github.com/ipfs/go-ipfs-exchange-interface v0.2.0 h1:8lMSJmKogZYNo2jjhUs0izT+dck05pqUw4mWNW9Pw6Y= github.com/ipfs/go-ipfs-exchange-offline v0.3.0 h1:c/Dg8GDPzixGd0MC8Jh6mjOwU57uYokgWRFidfvEkuA= github.com/ipfs/go-ipfs-files v0.3.0 h1:fallckyc5PYjuMEitPNrjRfpwl7YFt69heCOUhsbGxQ= -github.com/ipfs/go-ipfs-files v0.3.0/go.mod h1:xAUtYMwB+iu/dtf6+muHNSFQCJG2dSiStR2P6sn9tIM= github.com/ipfs/go-ipfs-posinfo v0.0.1 h1:Esoxj+1JgSjX0+ylc0hUmJCOv6V2vFoZiETLR6OtpRs= github.com/ipfs/go-ipfs-pq v0.0.3 h1:YpoHVJB+jzK15mr/xsWC574tyDLkezVrDNeaalQBsTE= github.com/ipfs/go-ipfs-pq v0.0.3/go.mod h1:btNw5hsHBpRcSSgZtiNm/SLj5gYIZ18AKtv3kERkRb4= @@ -507,8 +507,8 @@ github.com/klauspost/compress v1.15.12 h1:YClS/PImqYbn+UILDnqxQCZ3RehC9N318SU3kE github.com/klauspost/compress v1.15.12/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.2.3 h1:sxCkb+qR91z4vsqw4vGGZlDgPz3G7gjaLyK3V8y70BU= -github.com/klauspost/cpuid/v2 v2.2.3/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= +github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk= +github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/koron/go-ssdp v0.0.0-20191105050749-2e1c40ed0b5d/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk= @@ -545,18 +545,18 @@ github.com/libp2p/go-libp2p-asn-util v0.2.0 h1:rg3+Os8jbnO5DxkC7K/Utdi+DkY3q/d1/ github.com/libp2p/go-libp2p-asn-util v0.2.0/go.mod h1:WoaWxbHKBymSN41hWSq/lGKJEca7TNm58+gGJi2WsLI= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= github.com/libp2p/go-libp2p-core v0.3.0/go.mod h1:ACp3DmS3/N64c2jDzcV429ukDpicbL6+TrrxANBjPGw= -github.com/libp2p/go-libp2p-gostream v0.5.0 h1:niNGTUrFoUDP/8jxMgu97zngMO+UGYBpVpbCKwIJBls= -github.com/libp2p/go-libp2p-gostream v0.5.0/go.mod h1:rXrb0CqfcRRxa7m3RSKORQiKiWgk3IPeXWda66ZXKsA= -github.com/libp2p/go-libp2p-http v0.4.0 h1:V+f9Rhe/8GkColmXoyJyA0NVsN9F3TCLZgW2hwjoX5w= -github.com/libp2p/go-libp2p-http v0.4.0/go.mod h1:92tmLGrlBliQFDlZRpBXT3BJM7rGFONy0vsNrG/bMPg= +github.com/libp2p/go-libp2p-gostream v0.6.0 h1:QfAiWeQRce6pqnYfmIVWJFXNdDyfiR/qkCnjyaZUPYU= +github.com/libp2p/go-libp2p-gostream v0.6.0/go.mod h1:Nywu0gYZwfj7Jc91PQvbGU8dIpqbQQkjWgDuOrFaRdA= +github.com/libp2p/go-libp2p-http v0.5.0 h1:+x0AbLaUuLBArHubbbNRTsgWz0RjNTy6DJLOxQ3/QBc= +github.com/libp2p/go-libp2p-http v0.5.0/go.mod h1:glh87nZ35XCQyFsdzZps6+F4HYI6DctVFY5u1fehwSg= github.com/libp2p/go-libp2p-kad-dht v0.22.0 h1:cW2nGgG0hztDM42tOPyC5cVflD7EzLaHM0/Kjol6Wio= github.com/libp2p/go-libp2p-kad-dht v0.22.0/go.mod h1:hareSo3Z/GJ7nUWPMj7XhD/56a7+rRltYCWwCuy3FQk= github.com/libp2p/go-libp2p-kbucket v0.3.1/go.mod h1:oyjT5O7tS9CQurok++ERgc46YLwEpuGoFq9ubvoUOio= github.com/libp2p/go-libp2p-kbucket v0.5.0 h1:g/7tVm8ACHDxH29BGrpsQlnNeu+6OF1A9bno/4/U1oA= github.com/libp2p/go-libp2p-kbucket v0.5.0/go.mod h1:zGzGCpQd78b5BNTDGHNDLaTt9aDK/A02xeZp9QeFC4U= github.com/libp2p/go-libp2p-peerstore v0.1.4/go.mod h1:+4BDbDiiKf4PzpANZDAT+knVdLxvqh7hXOujessqdzs= -github.com/libp2p/go-libp2p-pubsub v0.9.0 h1:mcLb4WzwhUG4OKb0rp1/bYMd/DYhvMyzJheQH3LMd1s= -github.com/libp2p/go-libp2p-pubsub v0.9.0/go.mod h1:OEsj0Cc/BpkqikXRTrVspWU/Hx7bMZwHP+6vNMd+c7I= +github.com/libp2p/go-libp2p-pubsub v0.9.3 h1:ihcz9oIBMaCK9kcx+yHWm3mLAFBMAUsM4ux42aikDxo= +github.com/libp2p/go-libp2p-pubsub v0.9.3/go.mod h1:RYA7aM9jIic5VV47WXu4GkcRxRhrdElWf8xtyli+Dzc= github.com/libp2p/go-libp2p-pubsub-router v0.6.0 h1:D30iKdlqDt5ZmLEYhHELCMRj8b4sFAqrUcshIUvVP/s= github.com/libp2p/go-libp2p-pubsub-router v0.6.0/go.mod h1:FY/q0/RBTKsLA7l4vqC2cbRbOvyDotg8PJQ7j8FDudE= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= @@ -656,8 +656,8 @@ github.com/multiformats/go-multiaddr v0.1.0/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lg github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo= github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4= github.com/multiformats/go-multiaddr v0.4.0/go.mod h1:YcpyLH8ZPudLxQlemYBPhSm0/oCXAT8Z4mzFpyoPyRc= -github.com/multiformats/go-multiaddr v0.8.0 h1:aqjksEcqK+iD/Foe1RRFsGZh8+XFiGo7FgUCZlpv3LU= -github.com/multiformats/go-multiaddr v0.8.0/go.mod h1:Fs50eBDWvZu+l3/9S6xAE7ZYj6yhxlvaVZjakWN7xRs= +github.com/multiformats/go-multiaddr v0.9.0 h1:3h4V1LHIk5w4hJHekMKWALPXErDfz/sggzwC/NcqbDQ= +github.com/multiformats/go-multiaddr v0.9.0/go.mod h1:mI67Lb1EeTOYb8GQfL/7wpIZwc46ElrvzhYnoJOmTT0= github.com/multiformats/go-multiaddr-dns v0.3.0/go.mod h1:mNzQ4eTGDg0ll1N9jKPOUogZPoJ30W8a7zk66FQPpdQ= github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A= github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk= @@ -666,8 +666,8 @@ github.com/multiformats/go-multiaddr-fmt v0.1.0/go.mod h1:hGtDIW4PU4BqJ50gW2quDu github.com/multiformats/go-multiaddr-net v0.1.1/go.mod h1:5JNbcfBOP4dnhoZOv10JJVkJO0pCCEf8mTnipAo2UZQ= github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= github.com/multiformats/go-multibase v0.0.3/go.mod h1:5+1R4eQrT3PkYZ24C3W2Ue2tPwIdYQD509ZjSb5y9Oc= -github.com/multiformats/go-multibase v0.1.1 h1:3ASCDsuLX8+j4kx58qnJ4YFq/JWTJpCyDW27ztsVTOI= -github.com/multiformats/go-multibase v0.1.1/go.mod h1:ZEjHE+IsUrgp5mhlEAYjMtZwK1k4haNkcaPg9aoe1a8= +github.com/multiformats/go-multibase v0.2.0 h1:isdYCVLvksgWlMW9OZRYJEa9pZETFivncJHmHnnd87g= +github.com/multiformats/go-multibase v0.2.0/go.mod h1:bFBZX4lKCA/2lyOFSAoKH5SS6oPyjtnzK/XTFDPkNuk= github.com/multiformats/go-multicodec v0.3.0/go.mod h1:qGGaQmioCDh+TeFOnxrbU0DaIPw8yFgAZgFG0V7p1qQ= github.com/multiformats/go-multicodec v0.8.1 h1:ycepHwavHafh3grIbR1jIXnKCsFm0fqsfEOsJ8NtKE8= github.com/multiformats/go-multicodec v0.8.1/go.mod h1:L3QTQvMIaVBkXOXXtVmYE+LI16i14xuaojr/H7Ai54k= @@ -735,6 +735,8 @@ github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5Fsn github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= +github.com/prometheus/client_golang v1.12.2/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= +github.com/prometheus/client_golang v1.13.0/go.mod h1:vTeo+zgvILHsnnj/39Ou/1fPN5nJFOEMgftOUOmlvYQ= github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw= github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= @@ -748,8 +750,8 @@ github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7q github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= -github.com/prometheus/common v0.28.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= +github.com/prometheus/common v0.35.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE= github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= @@ -761,8 +763,8 @@ github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1 github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo= github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= -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/prometheus/statsd_exporter v0.22.7 h1:7Pji/i2GuhK6Lu7DHrtTkFmNBCudCPT1pX2CziuyQR0= +github.com/prometheus/statsd_exporter v0.22.7/go.mod h1:N/TevpjkIh9ccs6nuzY3jQn9dFqnUakOjnEuMPJJJnI= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= github.com/quic-go/qtls-go1-19 v0.2.1 h1:aJcKNMkH5ASEJB9FXNeZCyTEIHU1J7MmHyz1Q1TSG1A= @@ -851,6 +853,7 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stvp/go-udp-testing v0.0.0-20201019212854-469649b16807/go.mod h1:7jxmlfBCDBXRzr0eAQJ48XC1hBu1np4CS5+cHEYfwpc= github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= @@ -911,6 +914,7 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= @@ -953,17 +957,17 @@ go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/dig v1.15.0 h1:vq3YWr8zRj1eFGC7Gvf907hE0eRjPTZ1d3xHadD6liE= -go.uber.org/dig v1.15.0/go.mod h1:pKHs0wMynzL6brANhB2hLMro+zalv1osARTviTcqHLM= -go.uber.org/fx v1.18.2 h1:bUNI6oShr+OVFQeU8cDNbnN7VFsu+SsjHzUF51V/GAU= -go.uber.org/fx v1.18.2/go.mod h1:g0V1KMQ66zIRk8bLu3Ea5Jt2w/cHlOIp4wdRsgh0JaY= +go.uber.org/dig v1.16.1 h1:+alNIBsl0qfY0j6epRubp/9obgtrObRAc5aD+6jbWY8= +go.uber.org/dig v1.16.1/go.mod h1:557JTAUZT5bUK0SvCwikmLPPtdQhfvLYtO5tJgQSbnk= +go.uber.org/fx v1.19.2 h1:SyFgYQFr1Wl0AYstE8vyYIzP4bFz2URrScjwC4cwUvY= +go.uber.org/fx v1.19.2/go.mod h1:43G1VcqSzbIv77y00p1DRAsyZS8WdzuYdhZXmEUkMyQ= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= -go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= -go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ= +go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ= +go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.14.1/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= @@ -972,8 +976,9 @@ go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= -go4.org v0.0.0-20200411211856-f5505b9728dd h1:BNJlw5kRTzdmyfh5U8F93HA2OwkP7ZGwA51eJ/0wKOU= go4.org v0.0.0-20200411211856-f5505b9728dd/go.mod h1:CIiUVy99QCPfoE13bO4EZaz5GZMZXMSBGhxRdsvzbkg= +go4.org v0.0.0-20230225012048-214862532bf5 h1:nifaUDeh+rPaBCMPMQHZmvJf+QdpLFnuQPwx+LxVmtc= +go4.org v0.0.0-20230225012048-214862532bf5/go.mod h1:F57wTi5Lrj6WLyswp5EYV1ncrEbFGHD4hhz6S1ZYeaU= golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -990,8 +995,9 @@ golang.org/x/crypto v0.0.0-20200602180216-279210d13fed/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc= -golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A= +golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1026,8 +1032,9 @@ golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA= -golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk= +golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1076,8 +1083,10 @@ golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1102,6 +1111,8 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1171,15 +1182,19 @@ golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220708085239-5a0f0661e09d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= +golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1188,8 +1203,9 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1247,8 +1263,9 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.3.0 h1:SrNbZl6ECOS1qFzgTdQfWXZM9XBkiA6tkFrH9YSTPHM= -golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1356,8 +1373,10 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= +google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= From 096c783e4b8934a4da7118bebe2dac304c2e1bbe Mon Sep 17 00:00:00 2001 From: galargh Date: Wed, 5 Apr 2023 15:28:47 +0000 Subject: [PATCH 0614/1212] chore: update version --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index 1fd474ea7..52c34a408 100644 --- a/version.go +++ b/version.go @@ -11,7 +11,7 @@ import ( var CurrentCommit string // CurrentVersionNumber is the current application's version literal -const CurrentVersionNumber = "0.19.1-rc1" +const CurrentVersionNumber = "0.19.1" const ApiVersion = "/kubo/" + CurrentVersionNumber + "/" //nolint From b34c7a367ed8c672a0dd7d5136c52ca6c098cd82 Mon Sep 17 00:00:00 2001 From: galargh Date: Wed, 5 Apr 2023 15:52:04 +0000 Subject: [PATCH 0615/1212] chore: update changelog for v0.19 --- docs/changelogs/v0.19.md | 43 +++++++++++++++++++++++++++++++++++----- 1 file changed, 38 insertions(+), 5 deletions(-) diff --git a/docs/changelogs/v0.19.md b/docs/changelogs/v0.19.md index 4663d1323..1abc2e518 100644 --- a/docs/changelogs/v0.19.md +++ b/docs/changelogs/v0.19.md @@ -1,13 +1,49 @@ # Kubo changelog v0.19 +## v0.19.1 + +### 🔦 Highlights + +#### DHT Timeouts +In v0.16.0, Kubo added the ability to configure custom content routers and DHTs with the `custom` router type, and as part of this added a default 5 minute timeout to all DHT operations. In some cases with large repos ([example](https://github.com/ipfs/kubo/issues/9722)), this can cause provide and reprovide operations to fail because the timeout is reached. This release removes these timeouts on DHT operations. If users desire these timeouts, they can be added back using [the `custom` router type](https://github.com/ipfs/kubo/blob/master/docs/config.md#routingrouters-parameters). + +### Changelog + +

    Full Changelog + +- github.com/ipfs/kubo: + - chore: update version + - fix: remove timeout on default DHT operations (#9783) ([ipfs/kubo#9783](https://github.com/ipfs/kubo/pull/9783)) + - chore: update version +- github.com/ipfs/go-blockservice (v0.5.0 -> v0.5.1): + - chore: release v0.5.1 + - fix: remove busyloop in getBlocks by removing batching +- github.com/libp2p/go-libp2p (v0.26.3 -> v0.26.4): + - release v0.26.4 + - autorelay: fix busy loop bug and flaky tests in relay finder (#2208) ([libp2p/go-libp2p#2208](https://github.com/libp2p/go-libp2p/pull/2208)) +- github.com/libp2p/go-libp2p-routing-helpers (v0.6.1 -> v0.6.2): + - Release v0.6.2 (#73) ([libp2p/go-libp2p-routing-helpers#73](https://github.com/libp2p/go-libp2p-routing-helpers/pull/73)) + - feat: zero timeout on composed routers should disable timeout (#72) ([libp2p/go-libp2p-routing-helpers#72](https://github.com/libp2p/go-libp2p-routing-helpers/pull/72)) + +
    + +### Contributors + +| Contributor | Commits | Lines ± | Files Changed | +|-------------|---------|---------|---------------| +| Marco Munizaga | 1 | +347/-46 | 5 | +| Gus Eggert | 3 | +119/-93 | 8 | +| Jorropo | 2 | +20/-32 | 2 | +| galargh | 2 | +2/-2 | 2 | +| Marten Seemann | 1 | +2/-2 | 1 | + ## v0.19.0 - [Overview](#overview) - [🔦 Highlights](#-highlights) - [Improving the libp2p resource management integration](#improving-the-libp2p-resource-management-integration) - - [PubSub message caching improvements](#pubsub-message-caching-improvements) - [Gateways](#gateways) - [Signed IPNS Record response format](#signed-ipns-record-response-format) - [Example fetch and inspect IPNS record](#example-fetch-and-inspect-ipns-record) @@ -21,6 +57,7 @@ ### 🔦 Highlights #### Improving the libp2p resource management integration + There are further followups up on libp2p resource manager improvements in Kubo [0.18.0](https://github.com/ipfs/kubo/blob/master/docs/changelogs/v0.18.md#improving-libp2p-resource-management-integration-1) and [0.18.1](https://github.com/ipfs/kubo/blob/master/docs/changelogs/v0.18.md#improving-libp2p-resource-management-integration): 1. `ipfs swarm limits` and `ipfs swarm stats` have been replaced by `ipfs swarm resources` to provide a single/combined view for limits and their current usage in a more intuitive ordering. @@ -28,10 +65,6 @@ and [0.18.1](https://github.com/ipfs/kubo/blob/master/docs/changelogs/v0.18.md#i - Note: we don't expect most users to need these capablities, but they are there if so. 1. [Doc updates](https://github.com/ipfs/kubo/blob/master/docs/libp2p-resource-management.md). -#### PubSub message caching improvements - -The PubSub message cache will now [prune messages after TTL is exhausted](https://github.com/ipfs/kubo/blob/master/docs/config.md#pubsubseenmessagesttl), [either based on the last time a message was seen or the first time it was seen](https://github.com/ipfs/kubo/blob/master/docs/config.md#pubsubseenmessagesstrategy). - #### Gateways ##### Signed IPNS Record response format From 7cff6b9359115e7669d1deafd2329c2f53878a90 Mon Sep 17 00:00:00 2001 From: Gus Eggert Date: Wed, 5 Apr 2023 12:48:39 -0400 Subject: [PATCH 0616/1212] chore: upgrade boxo to v0.8.0 (#9793) --- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index d70ff4553..3f809f00b 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.18 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.8.0-rc4 + github.com/ipfs/boxo v0.8.0 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.26.4 github.com/multiformats/go-multiaddr v0.9.0 diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 92576a4ce..4a9480ed3 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -336,8 +336,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.8.0-rc4 h1:TT9uY/cw6yjmeKjfJPKaGZIYSJmV6B9Bd/O5Rem6MfA= -github.com/ipfs/boxo v0.8.0-rc4/go.mod h1:RIsi4CnTyQ7AUsNn5gXljJYZlQrHBMnJp94p73liFiA= +github.com/ipfs/boxo v0.8.0 h1:UdjAJmHzQHo/j3g3b1bAcAXCj/GM6iTwvSlBDvPBNBs= +github.com/ipfs/boxo v0.8.0/go.mod h1:RIsi4CnTyQ7AUsNn5gXljJYZlQrHBMnJp94p73liFiA= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= diff --git a/go.mod b/go.mod index 04c92fcd4..37933e71f 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/gogo/protobuf v1.3.2 github.com/google/uuid v1.3.0 github.com/hashicorp/go-multierror v1.1.1 - github.com/ipfs/boxo v0.8.0-rc4 + github.com/ipfs/boxo v0.8.0 github.com/ipfs/go-block-format v0.1.2 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 diff --git a/go.sum b/go.sum index 63fed62b8..ab6cea44e 100644 --- a/go.sum +++ b/go.sum @@ -355,8 +355,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.8.0-rc4 h1:TT9uY/cw6yjmeKjfJPKaGZIYSJmV6B9Bd/O5Rem6MfA= -github.com/ipfs/boxo v0.8.0-rc4/go.mod h1:RIsi4CnTyQ7AUsNn5gXljJYZlQrHBMnJp94p73liFiA= +github.com/ipfs/boxo v0.8.0 h1:UdjAJmHzQHo/j3g3b1bAcAXCj/GM6iTwvSlBDvPBNBs= +github.com/ipfs/boxo v0.8.0/go.mod h1:RIsi4CnTyQ7AUsNn5gXljJYZlQrHBMnJp94p73liFiA= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= From f18a69ecedd71cc2c694f2ce3b9f3ba2d5a79642 Mon Sep 17 00:00:00 2001 From: Piotr Galar Date: Wed, 5 Apr 2023 22:42:09 +0200 Subject: [PATCH 0617/1212] Merge Release: v0.19.1 (#9794) * chore: update version * chore: update go-libp2p to v0.26.4 * fix: remove timeout on default DHT operations (#9783) * fix: remove timeout on default DHT operations This removes the timeout by default for DHT operations. In particular this causes issues with ProvideMany requests which can take an indeterminate amount of time, but really these should just respect context timeouts by default. Users can still specify timeouts here if they want, but by default they will be set to "0" which means "no timeout". This is unlikely to break existing users of custom routing, because there was previously no utility in configuring a router with timeout=0 because that would cause the router to immediately fail, so it is unlikely (and incorrect) if anybody was using timeout=0. * fix: remove 5m timeout on ProvideManyRouter For context see https://github.com/ipfs/kubo/pull/9783/commits/5fda291b6665abe7aaf6a3f17687474dc85d8db4 --------- Co-authored-by: Marcin Rataj * chore: bump go-blockservice to v0.5.1 * chore: update version * chore: update changelog for v0.19 --------- Co-authored-by: Jorropo Co-authored-by: Gus Eggert Co-authored-by: Marcin Rataj --- docs/changelogs/v0.19.md | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/docs/changelogs/v0.19.md b/docs/changelogs/v0.19.md index 722f00677..1abc2e518 100644 --- a/docs/changelogs/v0.19.md +++ b/docs/changelogs/v0.19.md @@ -8,9 +8,35 @@ #### DHT Timeouts In v0.16.0, Kubo added the ability to configure custom content routers and DHTs with the `custom` router type, and as part of this added a default 5 minute timeout to all DHT operations. In some cases with large repos ([example](https://github.com/ipfs/kubo/issues/9722)), this can cause provide and reprovide operations to fail because the timeout is reached. This release removes these timeouts on DHT operations. If users desire these timeouts, they can be added back using [the `custom` router type](https://github.com/ipfs/kubo/blob/master/docs/config.md#routingrouters-parameters). -### 📝 Changelog +### Changelog -### 👨‍👩‍👧‍👦 Contributors +
    Full Changelog + +- github.com/ipfs/kubo: + - chore: update version + - fix: remove timeout on default DHT operations (#9783) ([ipfs/kubo#9783](https://github.com/ipfs/kubo/pull/9783)) + - chore: update version +- github.com/ipfs/go-blockservice (v0.5.0 -> v0.5.1): + - chore: release v0.5.1 + - fix: remove busyloop in getBlocks by removing batching +- github.com/libp2p/go-libp2p (v0.26.3 -> v0.26.4): + - release v0.26.4 + - autorelay: fix busy loop bug and flaky tests in relay finder (#2208) ([libp2p/go-libp2p#2208](https://github.com/libp2p/go-libp2p/pull/2208)) +- github.com/libp2p/go-libp2p-routing-helpers (v0.6.1 -> v0.6.2): + - Release v0.6.2 (#73) ([libp2p/go-libp2p-routing-helpers#73](https://github.com/libp2p/go-libp2p-routing-helpers/pull/73)) + - feat: zero timeout on composed routers should disable timeout (#72) ([libp2p/go-libp2p-routing-helpers#72](https://github.com/libp2p/go-libp2p-routing-helpers/pull/72)) + +
    + +### Contributors + +| Contributor | Commits | Lines ± | Files Changed | +|-------------|---------|---------|---------------| +| Marco Munizaga | 1 | +347/-46 | 5 | +| Gus Eggert | 3 | +119/-93 | 8 | +| Jorropo | 2 | +20/-32 | 2 | +| galargh | 2 | +2/-2 | 2 | +| Marten Seemann | 1 | +2/-2 | 1 | ## v0.19.0 From 1958510b3e7b796b17cee27fa3424d7310905eae Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Thu, 6 Apr 2023 11:30:20 +0200 Subject: [PATCH 0618/1212] docs: fix jaeger command (#9797) --- docs/environment-variables.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/environment-variables.md b/docs/environment-variables.md index ba1cce166..b877aa183 100644 --- a/docs/environment-variables.md +++ b/docs/environment-variables.md @@ -219,7 +219,7 @@ $ docker run --rm -it --name jaeger \ -p 5778:5778 \ -p 16686:16686 \ -p 14268:14268 \ - -p 14268:14269 \ + -p 14269:14269 \ -p 14250:14250 \ -p 9411:9411 \ jaegertracing/all-in-one From c6a59c9cc1e712b4ac4c6e5ce15c3eb663d73ed3 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Thu, 6 Apr 2023 16:36:15 +0200 Subject: [PATCH 0619/1212] feat(tracing): use OTEL_PROPAGATORS as per OTel spec (#9801) --- cmd/ipfs/main.go | 6 +++--- core/corehttp/commands.go | 3 +-- core/corehttp/gateway.go | 4 +--- docs/environment-variables.md | 4 ++++ go.mod | 5 +++++ go.sum | 10 ++++++++++ tracing/tracing.go | 5 ----- 7 files changed, 24 insertions(+), 13 deletions(-) diff --git a/cmd/ipfs/main.go b/cmd/ipfs/main.go index 2d9673ece..c1e529932 100644 --- a/cmd/ipfs/main.go +++ b/cmd/ipfs/main.go @@ -32,6 +32,7 @@ import ( madns "github.com/multiformats/go-multiaddr-dns" manet "github.com/multiformats/go-multiaddr/net" "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" + "go.opentelemetry.io/contrib/propagators/autoprop" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/codes" @@ -106,6 +107,7 @@ func mainRet() (exitCode int) { } }() otel.SetTracerProvider(tp) + otel.SetTextMapPropagator(autoprop.NewTextMapPropagator()) tracer = tp.Tracer("Kubo-cli") stopFunc, err := profileIfEnabled() @@ -314,9 +316,7 @@ func makeExecutor(req *cmds.Request, env interface{}) (cmds.Executor, error) { return nil, fmt.Errorf("unsupported API address: %s", apiAddr) } opts = append(opts, cmdhttp.ClientWithHTTPClient(&http.Client{ - Transport: otelhttp.NewTransport(tpt, - otelhttp.WithPropagators(tracing.Propagator()), - ), + Transport: otelhttp.NewTransport(tpt), })) return tracingWrappedExecutor{cmdhttp.NewClient(host, opts...)}, nil diff --git a/core/corehttp/commands.go b/core/corehttp/commands.go index 6a33a2b29..e7ac14289 100644 --- a/core/corehttp/commands.go +++ b/core/corehttp/commands.go @@ -17,7 +17,6 @@ import ( config "github.com/ipfs/kubo/config" "github.com/ipfs/kubo/core" corecommands "github.com/ipfs/kubo/core/commands" - "github.com/ipfs/kubo/tracing" "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" ) @@ -147,7 +146,7 @@ func commandsOption(cctx oldcmds.Context, command *cmds.Command, allowGet bool) patchCORSVars(cfg, l.Addr()) cmdHandler := cmdsHttp.NewHandler(&cctx, command, cfg) - cmdHandler = otelhttp.NewHandler(cmdHandler, "corehttp.cmdsHandler", otelhttp.WithPropagators(tracing.Propagator())) + cmdHandler = otelhttp.NewHandler(cmdHandler, "corehttp.cmdsHandler") mux.Handle(APIPath+"/", cmdHandler) return mux, nil } diff --git a/core/corehttp/gateway.go b/core/corehttp/gateway.go index aed860368..a9c42f185 100644 --- a/core/corehttp/gateway.go +++ b/core/corehttp/gateway.go @@ -50,9 +50,7 @@ func GatewayOption(paths ...string) ServeOption { } gw := gateway.NewHandler(gwConfig, gwAPI) - // TODO: Add otelhttp.WithPropagators(tracing.Propagator()) option to - // propagate traces through the gateway once we test this feature. - gw = otelhttp.NewHandler(gw, "Gateway.Request") + gw = otelhttp.NewHandler(gw, "Gateway") // By default, our HTTP handler is the gateway handler. handler := gw.ServeHTTP diff --git a/docs/environment-variables.md b/docs/environment-variables.md index b877aa183..b3d03d1bd 100644 --- a/docs/environment-variables.md +++ b/docs/environment-variables.md @@ -231,3 +231,7 @@ $ OTEL_TRACES_EXPORTER=jaeger ipfs daemon ``` Finally, the [Jaeger UI](https://github.com/jaegertracing/jaeger-ui#readme) is available at http://localhost:16686 + +## `OTEL_PROPAGATORS` + +See https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/sdk-environment-variables.md#general-sdk-configuration diff --git a/go.mod b/go.mod index 37933e71f..0c1456a07 100644 --- a/go.mod +++ b/go.mod @@ -73,6 +73,7 @@ require ( github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 go.opencensus.io v0.24.0 go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.40.0 + go.opentelemetry.io/contrib/propagators/autoprop v0.40.0 go.opentelemetry.io/otel v1.14.0 go.opentelemetry.io/otel/exporters/jaeger v1.14.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.14.0 @@ -203,6 +204,10 @@ require ( github.com/whyrusleeping/cbor-gen v0.0.0-20230126041949-52956bd4c9aa // indirect github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f // indirect github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect + go.opentelemetry.io/contrib/propagators/aws v1.15.0 // indirect + go.opentelemetry.io/contrib/propagators/b3 v1.15.0 // indirect + go.opentelemetry.io/contrib/propagators/jaeger v1.15.0 // indirect + go.opentelemetry.io/contrib/propagators/ot v1.15.0 // indirect go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.14.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.14.0 // indirect go.opentelemetry.io/otel/metric v0.37.0 // indirect diff --git a/go.sum b/go.sum index ab6cea44e..6ac7bbbec 100644 --- a/go.sum +++ b/go.sum @@ -927,6 +927,16 @@ go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.40.0 h1:lE9EJyw3/JhrjWH/hEy9FptnalDQgj7vpbgC2KCCCxE= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.40.0/go.mod h1:pcQ3MM3SWvrA71U4GDqv9UFDJ3HQsW7y5ZO3tDTlUdI= +go.opentelemetry.io/contrib/propagators/autoprop v0.40.0 h1:Lj33jj7eIrBfIShiK8NU91u2BglKnUS1UUxVemuQJtw= +go.opentelemetry.io/contrib/propagators/autoprop v0.40.0/go.mod h1:6QO816FeZ+6zahs6hYqbUCCsnNBm7o+t4iwVySpzcdI= +go.opentelemetry.io/contrib/propagators/aws v1.15.0 h1:FLe+bRTMAhEALItDQt1U2S/rdq8/rGGJTJpOpCDvMu0= +go.opentelemetry.io/contrib/propagators/aws v1.15.0/go.mod h1:Z/nqdjqKjErrS3gYoEMZt8//dt8VZbqalD0V+7vh7lM= +go.opentelemetry.io/contrib/propagators/b3 v1.15.0 h1:bMaonPyFcAvZ4EVzkUNkfnUHP5Zi63CIDlA3dRsEg8Q= +go.opentelemetry.io/contrib/propagators/b3 v1.15.0/go.mod h1:VjU0g2v6HSQ+NwfifambSLAeBgevjIcqmceaKWEzl0c= +go.opentelemetry.io/contrib/propagators/jaeger v1.15.0 h1:xdJjwy5t/8I+TZehMMQ+r2h50HREihH2oMUhimQ+jug= +go.opentelemetry.io/contrib/propagators/jaeger v1.15.0/go.mod h1:tU0nwW4QTvKceNUP60/PQm0FI8zDSwey7gIFt3RR/yw= +go.opentelemetry.io/contrib/propagators/ot v1.15.0 h1:iBNejawWy7wWZ5msuZDNcMjBy14Wc0v3gCAXukGHN/Q= +go.opentelemetry.io/contrib/propagators/ot v1.15.0/go.mod h1:0P7QQ+MHt6SXR1ATaMpewSiWlp8NbKErNLKcaU4EEKI= go.opentelemetry.io/otel v1.14.0 h1:/79Huy8wbf5DnIPhemGB+zEPVwnN6fuQybr/SRXa6hM= go.opentelemetry.io/otel v1.14.0/go.mod h1:o4buv+dJzx8rohcUeRmWUZhqupFvzWis188WlggnNeU= go.opentelemetry.io/otel/exporters/jaeger v1.14.0 h1:CjbUNd4iN2hHmWekmOqZ+zSCU+dzZppG8XsV+A3oc8Q= diff --git a/tracing/tracing.go b/tracing/tracing.go index 1da3fbd53..b22930a6f 100644 --- a/tracing/tracing.go +++ b/tracing/tracing.go @@ -13,7 +13,6 @@ import ( "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc" "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp" "go.opentelemetry.io/otel/exporters/zipkin" - "go.opentelemetry.io/otel/propagation" "go.opentelemetry.io/otel/sdk/resource" "go.opentelemetry.io/otel/sdk/trace" semconv "go.opentelemetry.io/otel/semconv/v1.4.0" @@ -147,7 +146,3 @@ func NewTracerProvider(ctx context.Context) (shutdownTracerProvider, error) { func Span(ctx context.Context, componentName string, spanName string, opts ...traceapi.SpanStartOption) (context.Context, traceapi.Span) { return otel.Tracer("Kubo").Start(ctx, fmt.Sprintf("%s.%s", componentName, spanName), opts...) } - -func Propagator() propagation.TextMapPropagator { - return propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{}) -} From 6f08cdedc0c79424d487407a591a88697060b2ea Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Thu, 6 Apr 2023 20:53:52 +0200 Subject: [PATCH 0620/1212] fix(ci): speed up docker build (#9800) trying two things: - speed up arm build by allowing cross-comp from go instead of slow QEMU - take a stab at caching buildx layers, without infinite growth This fix was laready applied in https://github.com/ipfs/bifrost-gateway/commit/14cfa48bed514fb8b865d41df3cecb5f827e54ab and reduced build time from 20m to 3m. --- .github/workflows/docker-image.yml | 17 +++++++++++++++++ Dockerfile | 11 ++++++++--- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index 47c375440..520e37833 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -31,6 +31,14 @@ jobs: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v1 + - name: Cache Docker layers + uses: actions/cache@v3 + with: + path: /tmp/.buildx-cache + key: ${{ runner.os }}-buildx-${{ github.sha }} + restore-keys: | + ${{ runner.os }}-buildx- + - name: Get tags id: tags run: | @@ -53,3 +61,12 @@ jobs: push: true file: ./Dockerfile tags: "${{ steps.tags.outputs.value }}" + cache-from: type=local,src=/tmp/.buildx-cache + cache-to: type=local,dest=/tmp/.buildx-cache-new + + # https://github.com/docker/build-push-action/issues/252 + # https://github.com/moby/buildkit/issues/1896 + - name: Move cache to limit growth + run: | + rm -rf /tmp/.buildx-cache + mv /tmp/.buildx-cache-new /tmp/.buildx-cache diff --git a/Dockerfile b/Dockerfile index 57e650710..a252bc997 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,11 @@ -FROM golang:1.19.1-buster +FROM --platform=${BUILDPLATFORM:-linux/amd64} golang:1.19.1-buster LABEL maintainer="Steven Allen " +ARG TARGETPLATFORM +ARG BUILDPLATFORM +ARG TARGETOS +ARG TARGETARCH + # Install deps RUN apt-get update && apt-get install -y \ libssl-dev \ @@ -24,7 +29,7 @@ ARG IPFS_PLUGINS # Also: fix getting HEAD commit hash via git rev-parse. RUN cd $SRC_DIR \ && mkdir -p .git/objects \ - && GOFLAGS=-buildvcs=false make build GOTAGS=openssl IPFS_PLUGINS=$IPFS_PLUGINS + && GOOS=$TARGETOS GOARCH=$TARGETARCH GOFLAGS=-buildvcs=false make build GOTAGS=openssl IPFS_PLUGINS=$IPFS_PLUGINS # Get su-exec, a very minimal tool for dropping privileges, # and tini, a very minimal init daemon for containers @@ -46,7 +51,7 @@ RUN set -eux; \ && chmod +x tini # Now comes the actual target image, which aims to be as small as possible. -FROM busybox:1.31.1-glibc +FROM --platform=${BUILDPLATFORM:-linux/amd64} busybox:1.31.1-glibc LABEL maintainer="Steven Allen " # Get the ipfs binary, entrypoint script, and TLS CAs from the build container. From 0e55ca9377515ef2a78816ee78db33a0fa66bf3b Mon Sep 17 00:00:00 2001 From: Gus Eggert Date: Fri, 24 Mar 2023 21:09:35 -0400 Subject: [PATCH 0621/1212] feat: add experimental optimistic provide This adds the ability to enable "optimistic provide" to the default DHT client, which enables faster provides and reprovides. For more information about optimistic provide, see: https://protocollabs.notion.site/Optimistic-Provide-2c79745820fa45649d48de038516b814 Note that this feature only works when using non-custom router types. This does not include the ability to enable optimistic provide on custom routers for now, to minimize the footprint of this experimental feature. We intend on continuing to test this and improve the UX, which may or may not involve adding configuration for it to custom routers. We also plan on refactoring/redesigning custom routers more broadly so I don't want this to add more effort for maintainers and confusion for users. --- config/experiments.go | 18 +++-- core/node/libp2p/host.go | 21 +++-- core/node/libp2p/routingopt.go | 108 +++++++++---------------- docs/examples/kubo-as-a-library/go.mod | 3 +- docs/examples/kubo-as-a-library/go.sum | 6 +- go.mod | 3 +- go.sum | 6 +- test/cli/dht_opt_prov_test.go | 30 +++++++ test/cli/harness/node.go | 4 +- test/cli/testutils/random.go | 4 + 10 files changed, 111 insertions(+), 92 deletions(-) create mode 100644 test/cli/dht_opt_prov_test.go diff --git a/config/experiments.go b/config/experiments.go index 7ad87c853..072dcd0dd 100644 --- a/config/experiments.go +++ b/config/experiments.go @@ -1,12 +1,14 @@ package config type Experiments struct { - FilestoreEnabled bool - UrlstoreEnabled bool - ShardingEnabled bool `json:",omitempty"` // deprecated by autosharding: https://github.com/ipfs/kubo/pull/8527 - GraphsyncEnabled bool - Libp2pStreamMounting bool - P2pHttpProxy bool //nolint - StrategicProviding bool - AcceleratedDHTClient bool + FilestoreEnabled bool + UrlstoreEnabled bool + ShardingEnabled bool `json:",omitempty"` // deprecated by autosharding: https://github.com/ipfs/kubo/pull/8527 + GraphsyncEnabled bool + Libp2pStreamMounting bool + P2pHttpProxy bool //nolint + StrategicProviding bool + AcceleratedDHTClient bool + OptimisticProvide bool + OptimisticProvideJobsPoolSize int } diff --git a/core/node/libp2p/host.go b/core/node/libp2p/host.go index 15d815812..afbd2080c 100644 --- a/core/node/libp2p/host.go +++ b/core/node/libp2p/host.go @@ -53,13 +53,18 @@ func Host(mctx helpers.MetricsCtx, lc fx.Lifecycle, params P2PHostIn) (out P2PHo return out, err } + routingOptArgs := RoutingOptionArgs{ + Ctx: ctx, + Datastore: params.Repo.Datastore(), + Validator: params.Validator, + BootstrapPeers: bootstrappers, + OptimisticProvide: cfg.Experimental.OptimisticProvide, + OptimisticProvideJobsPoolSize: cfg.Experimental.OptimisticProvideJobsPoolSize, + } opts = append(opts, libp2p.Routing(func(h host.Host) (routing.PeerRouting, error) { - r, err := params.RoutingOption( - ctx, h, - params.Repo.Datastore(), - params.Validator, - bootstrappers..., - ) + args := routingOptArgs + args.Host = h + r, err := params.RoutingOption(args) out.Routing = r return r, err })) @@ -69,10 +74,12 @@ func Host(mctx helpers.MetricsCtx, lc fx.Lifecycle, params P2PHostIn) (out P2PHo return P2PHostOut{}, err } + routingOptArgs.Host = out.Host + // this code is necessary just for tests: mock network constructions // ignore the libp2p constructor options that actually construct the routing! if out.Routing == nil { - r, err := params.RoutingOption(ctx, out.Host, params.Repo.Datastore(), params.Validator, bootstrappers...) + r, err := params.RoutingOption(routingOptArgs) if err != nil { return P2PHostOut{}, err } diff --git a/core/node/libp2p/routingopt.go b/core/node/libp2p/routingopt.go index 8a69e181b..1d47ae273 100644 --- a/core/node/libp2p/routingopt.go +++ b/core/node/libp2p/routingopt.go @@ -18,13 +18,17 @@ import ( routing "github.com/libp2p/go-libp2p/core/routing" ) -type RoutingOption func( - context.Context, - host.Host, - datastore.Batching, - record.Validator, - ...peer.AddrInfo, -) (routing.Routing, error) +type RoutingOptionArgs struct { + Ctx context.Context + Host host.Host + Datastore datastore.Batching + Validator record.Validator + BootstrapPeers []peer.AddrInfo + OptimisticProvide bool + OptimisticProvideJobsPoolSize int +} + +type RoutingOption func(args RoutingOptionArgs) (routing.Routing, error) // Default HTTP routers used in parallel to DHT when Routing.Type = "auto" var defaultHTTPRouters = []string{ @@ -40,25 +44,13 @@ func init() { } // ConstructDefaultRouting returns routers used when Routing.Type is unset or set to "auto" -func ConstructDefaultRouting(peerID string, addrs []string, privKey string, routingOpt RoutingOption) func( - ctx context.Context, - host host.Host, - dstore datastore.Batching, - validator record.Validator, - bootstrapPeers ...peer.AddrInfo, -) (routing.Routing, error) { - return func( - ctx context.Context, - host host.Host, - dstore datastore.Batching, - validator record.Validator, - bootstrapPeers ...peer.AddrInfo, - ) (routing.Routing, error) { +func ConstructDefaultRouting(peerID string, addrs []string, privKey string, routingOpt RoutingOption) RoutingOption { + return func(args RoutingOptionArgs) (routing.Routing, error) { // Defined routers will be queried in parallel (optimizing for response speed) // Different trade-offs can be made by setting Routing.Type = "custom" with own Routing.Routers var routers []*routinghelpers.ParallelRouter - dhtRouting, err := routingOpt(ctx, host, dstore, validator, bootstrapPeers...) + dhtRouting, err := routingOpt(args) if err != nil { return nil, err } @@ -97,54 +89,38 @@ func ConstructDefaultRouting(peerID string, addrs []string, privKey string, rout } // constructDHTRouting is used when Routing.Type = "dht" -func constructDHTRouting(mode dht.ModeOpt) func( - ctx context.Context, - host host.Host, - dstore datastore.Batching, - validator record.Validator, - bootstrapPeers ...peer.AddrInfo, -) (routing.Routing, error) { - return func( - ctx context.Context, - host host.Host, - dstore datastore.Batching, - validator record.Validator, - bootstrapPeers ...peer.AddrInfo, - ) (routing.Routing, error) { +func constructDHTRouting(mode dht.ModeOpt) RoutingOption { + return func(args RoutingOptionArgs) (routing.Routing, error) { + dhtOpts := []dht.Option{ + dht.Concurrency(10), + dht.Mode(mode), + dht.Datastore(args.Datastore), + dht.Validator(args.Validator), + } + if args.OptimisticProvide { + dhtOpts = append(dhtOpts, dht.EnableOptimisticProvide()) + } + if args.OptimisticProvideJobsPoolSize != 0 { + dhtOpts = append(dhtOpts, dht.OptimisticProvideJobsPoolSize(args.OptimisticProvideJobsPoolSize)) + } return dual.New( - ctx, host, - dual.DHTOption( - dht.Concurrency(10), - dht.Mode(mode), - dht.Datastore(dstore), - dht.Validator(validator)), - dual.WanDHTOption(dht.BootstrapPeers(bootstrapPeers...)), + args.Ctx, args.Host, + dual.DHTOption(dhtOpts...), + dual.WanDHTOption(dht.BootstrapPeers(args.BootstrapPeers...)), ) } } // ConstructDelegatedRouting is used when Routing.Type = "custom" -func ConstructDelegatedRouting(routers config.Routers, methods config.Methods, peerID string, addrs []string, privKey string) func( - ctx context.Context, - host host.Host, - dstore datastore.Batching, - validator record.Validator, - bootstrapPeers ...peer.AddrInfo, -) (routing.Routing, error) { - return func( - ctx context.Context, - host host.Host, - dstore datastore.Batching, - validator record.Validator, - bootstrapPeers ...peer.AddrInfo, - ) (routing.Routing, error) { +func ConstructDelegatedRouting(routers config.Routers, methods config.Methods, peerID string, addrs []string, privKey string) RoutingOption { + return func(args RoutingOptionArgs) (routing.Routing, error) { return irouting.Parse(routers, methods, &irouting.ExtraDHTParams{ - BootstrapPeers: bootstrapPeers, - Host: host, - Validator: validator, - Datastore: dstore, - Context: ctx, + BootstrapPeers: args.BootstrapPeers, + Host: args.Host, + Validator: args.Validator, + Datastore: args.Datastore, + Context: args.Ctx, }, &irouting.ExtraHTTPParams{ PeerID: peerID, @@ -154,13 +130,7 @@ func ConstructDelegatedRouting(routers config.Routers, methods config.Methods, p } } -func constructNilRouting( - ctx context.Context, - host host.Host, - dstore datastore.Batching, - validator record.Validator, - bootstrapPeers ...peer.AddrInfo, -) (routing.Routing, error) { +func constructNilRouting(_ RoutingOptionArgs) (routing.Routing, error) { return routinghelpers.Null{}, nil } diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 3f809f00b..3fa9b7c90 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -103,7 +103,7 @@ require ( github.com/libp2p/go-doh-resolver v0.4.0 // indirect github.com/libp2p/go-flow-metrics v0.1.0 // indirect github.com/libp2p/go-libp2p-asn-util v0.3.0 // indirect - github.com/libp2p/go-libp2p-kad-dht v0.22.0 // indirect + github.com/libp2p/go-libp2p-kad-dht v0.23.0 // indirect github.com/libp2p/go-libp2p-kbucket v0.5.0 // indirect github.com/libp2p/go-libp2p-pubsub v0.9.3 // indirect github.com/libp2p/go-libp2p-pubsub-router v0.6.0 // indirect @@ -188,6 +188,7 @@ require ( golang.org/x/text v0.8.0 // indirect golang.org/x/tools v0.6.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect + gonum.org/v1/gonum v0.11.0 // indirect google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect google.golang.org/grpc v1.53.0 // indirect google.golang.org/protobuf v1.30.0 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 4a9480ed3..1403cb302 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -518,8 +518,8 @@ github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLE github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= github.com/libp2p/go-libp2p-core v0.3.0/go.mod h1:ACp3DmS3/N64c2jDzcV429ukDpicbL6+TrrxANBjPGw= -github.com/libp2p/go-libp2p-kad-dht v0.22.0 h1:cW2nGgG0hztDM42tOPyC5cVflD7EzLaHM0/Kjol6Wio= -github.com/libp2p/go-libp2p-kad-dht v0.22.0/go.mod h1:hareSo3Z/GJ7nUWPMj7XhD/56a7+rRltYCWwCuy3FQk= +github.com/libp2p/go-libp2p-kad-dht v0.23.0 h1:sxE6LxLopp79eLeV695n7+c77V/Vn4AMF28AdM/XFqM= +github.com/libp2p/go-libp2p-kad-dht v0.23.0/go.mod h1:oO5N308VT2msnQI6qi5M61wzPmJYg7Tr9e16m5n7uDU= github.com/libp2p/go-libp2p-kbucket v0.3.1/go.mod h1:oyjT5O7tS9CQurok++ERgc46YLwEpuGoFq9ubvoUOio= github.com/libp2p/go-libp2p-kbucket v0.5.0 h1:g/7tVm8ACHDxH29BGrpsQlnNeu+6OF1A9bno/4/U1oA= github.com/libp2p/go-libp2p-kbucket v0.5.0/go.mod h1:zGzGCpQd78b5BNTDGHNDLaTt9aDK/A02xeZp9QeFC4U= @@ -1191,6 +1191,8 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +gonum.org/v1/gonum v0.11.0 h1:f1IJhK4Km5tBJmaiJXtk/PkL4cdVX6J+tGiM187uT5E= +gonum.org/v1/gonum v0.11.0/go.mod h1:fSG4YDCxxUZQJ7rKsQrj0gMOg00Il0Z96/qMA4bVQhA= google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y= diff --git a/go.mod b/go.mod index 0c1456a07..38f5a5a21 100644 --- a/go.mod +++ b/go.mod @@ -47,7 +47,7 @@ require ( github.com/libp2p/go-doh-resolver v0.4.0 github.com/libp2p/go-libp2p v0.26.4 github.com/libp2p/go-libp2p-http v0.5.0 - github.com/libp2p/go-libp2p-kad-dht v0.22.0 + github.com/libp2p/go-libp2p-kad-dht v0.23.0 github.com/libp2p/go-libp2p-kbucket v0.5.0 github.com/libp2p/go-libp2p-pubsub v0.9.3 github.com/libp2p/go-libp2p-pubsub-router v0.6.0 @@ -222,6 +222,7 @@ require ( golang.org/x/text v0.8.0 // indirect golang.org/x/tools v0.6.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect + gonum.org/v1/gonum v0.11.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect google.golang.org/grpc v1.53.0 // indirect diff --git a/go.sum b/go.sum index 6ac7bbbec..bd48a883c 100644 --- a/go.sum +++ b/go.sum @@ -549,8 +549,8 @@ github.com/libp2p/go-libp2p-gostream v0.6.0 h1:QfAiWeQRce6pqnYfmIVWJFXNdDyfiR/qk github.com/libp2p/go-libp2p-gostream v0.6.0/go.mod h1:Nywu0gYZwfj7Jc91PQvbGU8dIpqbQQkjWgDuOrFaRdA= github.com/libp2p/go-libp2p-http v0.5.0 h1:+x0AbLaUuLBArHubbbNRTsgWz0RjNTy6DJLOxQ3/QBc= github.com/libp2p/go-libp2p-http v0.5.0/go.mod h1:glh87nZ35XCQyFsdzZps6+F4HYI6DctVFY5u1fehwSg= -github.com/libp2p/go-libp2p-kad-dht v0.22.0 h1:cW2nGgG0hztDM42tOPyC5cVflD7EzLaHM0/Kjol6Wio= -github.com/libp2p/go-libp2p-kad-dht v0.22.0/go.mod h1:hareSo3Z/GJ7nUWPMj7XhD/56a7+rRltYCWwCuy3FQk= +github.com/libp2p/go-libp2p-kad-dht v0.23.0 h1:sxE6LxLopp79eLeV695n7+c77V/Vn4AMF28AdM/XFqM= +github.com/libp2p/go-libp2p-kad-dht v0.23.0/go.mod h1:oO5N308VT2msnQI6qi5M61wzPmJYg7Tr9e16m5n7uDU= github.com/libp2p/go-libp2p-kbucket v0.3.1/go.mod h1:oyjT5O7tS9CQurok++ERgc46YLwEpuGoFq9ubvoUOio= github.com/libp2p/go-libp2p-kbucket v0.5.0 h1:g/7tVm8ACHDxH29BGrpsQlnNeu+6OF1A9bno/4/U1oA= github.com/libp2p/go-libp2p-kbucket v0.5.0/go.mod h1:zGzGCpQd78b5BNTDGHNDLaTt9aDK/A02xeZp9QeFC4U= @@ -1282,6 +1282,8 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +gonum.org/v1/gonum v0.11.0 h1:f1IJhK4Km5tBJmaiJXtk/PkL4cdVX6J+tGiM187uT5E= +gonum.org/v1/gonum v0.11.0/go.mod h1:fSG4YDCxxUZQJ7rKsQrj0gMOg00Il0Z96/qMA4bVQhA= google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y= diff --git a/test/cli/dht_opt_prov_test.go b/test/cli/dht_opt_prov_test.go new file mode 100644 index 000000000..5481315af --- /dev/null +++ b/test/cli/dht_opt_prov_test.go @@ -0,0 +1,30 @@ +package cli + +import ( + "testing" + + "github.com/ipfs/kubo/config" + "github.com/ipfs/kubo/test/cli/harness" + "github.com/ipfs/kubo/test/cli/testutils" + "github.com/stretchr/testify/assert" +) + +func TestDHTOptimisticProvide(t *testing.T) { + t.Parallel() + + t.Run("optimistic provide smoke test", func(t *testing.T) { + nodes := harness.NewT(t).NewNodes(2).Init() + + nodes[0].UpdateConfig(func(cfg *config.Config) { + cfg.Experimental.OptimisticProvide = true + }) + + nodes.StartDaemons().Connect() + + hash := nodes[0].IPFSAddStr(testutils.RandomStr(100)) + nodes[0].IPFS("dht", "provide", hash) + + res := nodes[1].IPFS("routing", "findprovs", "--num-providers=1", hash) + assert.Equal(t, nodes[0].PeerID().String(), res.Stdout.Trimmed()) + }) +} diff --git a/test/cli/harness/node.go b/test/cli/harness/node.go index 625a01fb6..0516c2b45 100644 --- a/test/cli/harness/node.go +++ b/test/cli/harness/node.go @@ -218,8 +218,8 @@ func (n *Node) Init(ipfsArgs ...string) *Node { // // node.StartDaemonWithReq(harness.RunRequest{ // CmdOpts: []harness.CmdOpt{ -// harness.RunWithStderr(os.Stdout), -// harness.RunWithStdout(os.Stdout), +// harness.RunWithStderr(os.Stdout), +// harness.RunWithStdout(os.Stdout), // }, // }) func (n *Node) StartDaemonWithReq(req RunRequest) *Node { diff --git a/test/cli/testutils/random.go b/test/cli/testutils/random.go index 00bb9de49..6fa6528c3 100644 --- a/test/cli/testutils/random.go +++ b/test/cli/testutils/random.go @@ -10,3 +10,7 @@ func RandomBytes(n int) []byte { } return bytes } + +func RandomStr(n int) string { + return string(RandomBytes(n)) +} From cb2e109e4d5882f4fc5e5e5a981460c961525b20 Mon Sep 17 00:00:00 2001 From: Dennis Trautwein Date: Thu, 6 Apr 2023 16:28:20 +0200 Subject: [PATCH 0622/1212] docs: add optimistic provide feature description --- docs/experimental-features.md | 74 +++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/docs/experimental-features.md b/docs/experimental-features.md index 296f6ca1e..83a5fdf7b 100644 --- a/docs/experimental-features.md +++ b/docs/experimental-features.md @@ -27,6 +27,7 @@ the above issue. - [Graphsync](#graphsync) - [Noise](#noise) - [Accelerated DHT Client](#accelerated-dht-client) +- [Optimistic Provide](#optimistic-provide) --- @@ -597,3 +598,76 @@ ipfs config --json Experimental.AcceleratedDHTClient true - [ ] Needs more people to use and report on how well it works - [ ] Should be usable for queries (even if slower/less efficient) shortly after startup - [ ] Should be usable with non-WAN DHTs + +## Optimistic Provide + +### In Version + +0.20.0 + +### State + +Experimental, disabled by default. + +When the DHT client tries to store a provider in the DHT, it typically searches for the 20 peers that are closest to the +target key. However, this process can be time-consuming, as the search terminates only after no closer peers are found +among the three currently (during the query) known closest ones. In cases where these closest peers are slow to respond +(which often happens if they are located at the edge of the DHT network), the query gets blocked by the slowest peer. + +To address this issue, the `OptimisticProvide` feature can be enabled. This feature allows the client to estimate the +network size and determine how close a peer _likely_ needs to be to the target key to be within the 20 closest peers. +While searching for the closest peers in the DHT, the client will _optimistically_ store the provider record with peers +and abort the query completely when the set of currently known 20 closest peers are also _likely_ the actual 20 closest +ones. This heuristic approach can significantly speed up the process, resulting in a speed improvement of 2x to >10x. + +When it is enabled: + +- DHT provide operations should complete much faster than with it disabled +- This can be tested with commands such as `ipfs routing provide` + +**Tradeoffs** + +There are now the classic client, the accelerated DHT client, and optimistic provide that improve the provider process. +There are different trade-offs with all of them. The accelerated DHT client is still faster to provide large amounts +of provider records at the cost of high resource requirements. Optimistic provide doesn't have the high resource +requirements but might not choose optimal peers and is not as fast as the accelerated client, but still much faster +than the classic client. + +**Caveats:** + +1. Providing optimistically requires a current network size estimation. This estimation is calculated through routing + table refresh queries and is only available after the daemon has been running for some time. If there is no network + size estimation available the client will transparently fall back to the classic approach. +2. The chosen peers to store the provider records might not be the actual closest ones. Measurements showed that this + is not a problem. +3. The optimistic provide process returns already after 15 out of the 20 provider records were stored with peers. The + reasoning here is that one out of the remaining 5 peers are very likely to time out and delay the whole process. To + limit the number of in-flight async requests there is the second `OptimisticProvideJobsPoolSize` setting. Currently, + this is set to 60. This means that at most 60 parallel background requests are allowed to be in-flight. If this + limit is exceeded optimistic provide will block until all 20 provider records are written. This is still 2x faster + than the classic approach but not as fast as returning early which yields >10x speed-ups. +4. Since the in-flight background requests are likely to time out, they are not consuming many resources and the job + pool size could probably be much higher. + +For more information, see: + +- Project doc: https://protocollabs.notion.site/Optimistic-Provide-2c79745820fa45649d48de038516b814 +- go-libp2p-kad-dht: https://github.com/libp2p/go-libp2p-kad-dht/pull/783 + +### Configuring +To enable: + +``` +ipfs config --json Experimental.OptimisticProvide true +``` + +If you want to change the `OptimisticProvideJobsPoolSize` setting from its default of 60: + +``` +ipfs config --json Experimental.OptimisticProvideJobsPoolSize 120 +``` + +### Road to being a real feature + +- [ ] Needs more people to use and report on how well it works +- [ ] Should prove at least equivalent availability of provider records as the classic approach From 3c363eb6584204640defaf34b8f6f519618a92fd Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Thu, 6 Apr 2023 16:18:07 +0800 Subject: [PATCH 0623/1212] update go-libp2p to v0.27.0 --- docs/examples/kubo-as-a-library/go.mod | 38 ++--- docs/examples/kubo-as-a-library/go.sum | 147 +++++------------- go.mod | 42 ++--- go.sum | 87 ++++++----- .../t0119-prometheus-data/prometheus_metrics | 27 ++++ 5 files changed, 152 insertions(+), 189 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 3fa9b7c90..1c2af1154 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -9,7 +9,7 @@ replace github.com/ipfs/kubo => ./../../.. require ( github.com/ipfs/boxo v0.8.0 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 - github.com/libp2p/go-libp2p v0.26.4 + github.com/libp2p/go-libp2p v0.27.0 github.com/multiformats/go-multiaddr v0.9.0 ) @@ -26,7 +26,7 @@ require ( github.com/ceramicnetwork/go-dag-jose v0.1.0 // indirect github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect - github.com/containerd/cgroups v1.0.4 // indirect + github.com/containerd/cgroups v1.1.0 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect github.com/crackcomm/go-gitignore v0.0.0-20170627025303-887ab5e44cc3 // indirect github.com/cskr/pubsub v1.0.2 // indirect @@ -43,14 +43,14 @@ require ( github.com/gabriel-vasile/mimetype v1.4.1 // indirect github.com/go-logr/logr v1.2.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect + github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/godbus/dbus/v5 v5.1.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/mock v1.6.0 // indirect - github.com/golang/protobuf v1.5.2 // indirect + github.com/golang/protobuf v1.5.3 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/gopacket v1.1.19 // indirect - github.com/google/pprof v0.0.0-20221203041831-ce31453925ec // indirect + github.com/google/pprof v0.0.0-20230405160723-4a4c7d95572b // indirect github.com/google/uuid v1.3.0 // indirect github.com/gorilla/mux v1.8.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 // indirect @@ -58,8 +58,8 @@ require ( github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/golang-lru v0.5.4 // indirect - github.com/hashicorp/golang-lru/v2 v2.0.1 // indirect - github.com/huin/goupnp v1.0.3 // indirect + github.com/hashicorp/golang-lru/v2 v2.0.2 // indirect + github.com/huin/goupnp v1.1.0 // indirect github.com/ipfs/bbloom v0.0.4 // indirect github.com/ipfs/go-bitfield v1.1.0 // indirect github.com/ipfs/go-block-format v0.1.2 // indirect @@ -95,9 +95,9 @@ require ( github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect github.com/jbenet/goprocess v0.1.4 // indirect - github.com/klauspost/compress v1.15.12 // indirect + github.com/klauspost/compress v1.16.4 // indirect github.com/klauspost/cpuid/v2 v2.2.4 // indirect - github.com/koron/go-ssdp v0.0.3 // indirect + github.com/koron/go-ssdp v0.0.4 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/libp2p/go-cidranger v1.1.0 // indirect github.com/libp2p/go-doh-resolver v0.4.0 // indirect @@ -118,9 +118,9 @@ require ( github.com/libp2p/go-yamux/v4 v4.0.0 // indirect github.com/libp2p/zeroconf/v2 v2.2.0 // indirect github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect - github.com/mattn/go-isatty v0.0.17 // indirect + github.com/mattn/go-isatty v0.0.18 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect - github.com/miekg/dns v1.1.50 // indirect + github.com/miekg/dns v1.1.53 // indirect github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect github.com/minio/sha256-simd v1.0.0 // indirect @@ -135,7 +135,7 @@ require ( github.com/multiformats/go-multihash v0.2.1 // indirect github.com/multiformats/go-multistream v0.4.1 // indirect github.com/multiformats/go-varint v0.0.7 // indirect - github.com/onsi/ginkgo/v2 v2.5.1 // indirect + github.com/onsi/ginkgo/v2 v2.9.2 // indirect github.com/opencontainers/runtime-spec v1.0.2 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/openzipkin/zipkin-go v0.4.1 // indirect @@ -144,11 +144,11 @@ require ( github.com/polydawn/refmt v0.89.0 // indirect github.com/prometheus/client_golang v1.14.0 // indirect github.com/prometheus/client_model v0.3.0 // indirect - github.com/prometheus/common v0.37.0 // indirect - github.com/prometheus/procfs v0.8.0 // indirect + github.com/prometheus/common v0.42.0 // indirect + github.com/prometheus/procfs v0.9.0 // indirect github.com/quic-go/qpack v0.4.0 // indirect - github.com/quic-go/qtls-go1-19 v0.2.1 // indirect - github.com/quic-go/qtls-go1-20 v0.1.1 // indirect + github.com/quic-go/qtls-go1-19 v0.3.2 // indirect + github.com/quic-go/qtls-go1-20 v0.2.2 // indirect github.com/quic-go/quic-go v0.33.0 // indirect github.com/quic-go/webtransport-go v0.5.2 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect @@ -176,17 +176,17 @@ require ( go.uber.org/atomic v1.10.0 // indirect go.uber.org/dig v1.16.1 // indirect go.uber.org/fx v1.19.2 // indirect - go.uber.org/multierr v1.10.0 // indirect + go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.24.0 // indirect go4.org v0.0.0-20230225012048-214862532bf5 // indirect golang.org/x/crypto v0.7.0 // indirect - golang.org/x/exp v0.0.0-20230213192124-5e25df0256eb // indirect + golang.org/x/exp v0.0.0-20230321023759-10a507213a29 // indirect golang.org/x/mod v0.10.0 // indirect golang.org/x/net v0.8.0 // indirect golang.org/x/sync v0.1.0 // indirect golang.org/x/sys v0.7.0 // indirect golang.org/x/text v0.8.0 // indirect - golang.org/x/tools v0.6.0 // indirect + golang.org/x/tools v0.7.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect gonum.org/v1/gonum v0.11.0 // indirect google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 1403cb302..802f84be6 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -48,11 +48,6 @@ github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 h1:s6gZFSlWYmbqAuRjVTiNNhvNRfY2Wxp9nhfyel4rklc= github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5 h1:iW0a5ljuFxkLGPNem5Ui+KBjFJzKg4Fv2fnxe4dvzpM= @@ -64,7 +59,6 @@ github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZx github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= -github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= @@ -90,7 +84,6 @@ github.com/ceramicnetwork/go-dag-jose v0.1.0/go.mod h1:qYA1nYt0X8u4XoMAVoOV3upUV github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= @@ -106,8 +99,8 @@ github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWH github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/containerd/cgroups v0.0.0-20201119153540-4cbc285b3327/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE= -github.com/containerd/cgroups v1.0.4 h1:jN/mbWBEaz+T1pi5OFtnkQ+8qnmEbAr1Oo1FRm5B0dA= -github.com/containerd/cgroups v1.0.4/go.mod h1:nLNQtsF7Sl2HxNebu77i1R0oDlhiTG+kO4JTrUzo6IA= +github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM= +github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw= 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= @@ -182,14 +175,6 @@ github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= -github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= -github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= -github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= @@ -202,9 +187,8 @@ github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD87 github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= github.com/go-playground/validator/v10 v10.2.0 h1:KgJ0snyC2R9VXYN2rneOtQcw5aHQB1Vv0sFl1UcHBOY= github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -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/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= @@ -254,8 +238,9 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= @@ -289,8 +274,8 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20221203041831-ce31453925ec h1:fR20TYVVwhK4O7r7y+McjRYyaTH6/vjwJOajE+XhlzM= -github.com/google/pprof v0.0.0-20221203041831-ce31453925ec/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo= +github.com/google/pprof v0.0.0-20230405160723-4a4c7d95572b h1:Qcx5LM0fSiks9uCyFZwDBUasd3lxd1RM0GYpL+Li5o4= +github.com/google/pprof v0.0.0-20230405160723-4a4c7d95572b/go.mod h1:79YE0hCXdHag9sBkw2o+N/YnZtTkXi0UT9Nnixa5eYk= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -324,13 +309,13 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= -github.com/hashicorp/golang-lru/v2 v2.0.1 h1:5pv5N1lT1fjLg2VQ5KWc7kmucp2x/kvFOnxuVTqZ6x4= -github.com/hashicorp/golang-lru/v2 v2.0.1/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= +github.com/hashicorp/golang-lru/v2 v2.0.2 h1:Dwmkdr5Nc/oBiXgJS3CDHNhJtIHkuZ3DZF5twqnfBdU= +github.com/hashicorp/golang-lru/v2 v2.0.2/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= -github.com/huin/goupnp v1.0.3 h1:N8No57ls+MnjlB+JPiCVSOyy/ot7MJTqlo7rn+NYSqQ= -github.com/huin/goupnp v1.0.3/go.mod h1:ZxNlw5WqJj6wSsRK5+YfflQGXYfccj5VgQsMNixHM7Y= +github.com/huin/goupnp v1.1.0 h1:gEe0Dp/lZmPZiDFzJJaOfUpOvv2MKUkoBX8lDrn9vKU= +github.com/huin/goupnp v1.1.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= @@ -454,21 +439,15 @@ github.com/jbenet/goprocess v0.1.4/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZl github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= -github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/kami-zh/go-capturer v0.0.0-20171211120116-e492ea43421d/go.mod h1:P2viExyCEfeWGU259JnaQ34Inuec4R38JCyBx2edgD0= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= @@ -476,18 +455,16 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI 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.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/klauspost/compress v1.15.12 h1:YClS/PImqYbn+UILDnqxQCZ3RehC9N318SU3kElDUEM= -github.com/klauspost/compress v1.15.12/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= +github.com/klauspost/compress v1.16.4 h1:91KN02FnsOYhuunwU4ssRe8lc2JosWmizWa91B5v1PU= +github.com/klauspost/compress v1.16.4/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk= github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/koron/go-ssdp v0.0.0-20191105050749-2e1c40ed0b5d/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk= -github.com/koron/go-ssdp v0.0.3 h1:JivLMY45N76b4p/vsWGOKewBQu6uf39y8l+AQ7sDKx8= -github.com/koron/go-ssdp v0.0.3/go.mod h1:b2MxI6yh02pKrsyNoQUsk4+YNikaGhe4894J+Q5lDvA= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/koron/go-ssdp v0.0.4 h1:1IDwrghSKYM7yLf7XCzbByg2sJ/JcNOZRXS2jczTwz0= +github.com/koron/go-ssdp v0.0.4/go.mod h1:oDXq+E5IL5q0U8uSBcoAXzTzInwy5lEgC91HoKtbmZk= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= @@ -512,8 +489,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.26.4 h1:VA9ChjN0n1BwwfU/dqx4Zj9ezXtIxGk8FyJPwFONqxs= -github.com/libp2p/go-libp2p v0.26.4/go.mod h1:x75BN32YbwuY0Awm2Uix4d4KOz+/4piInkp4Wr3yOo8= +github.com/libp2p/go-libp2p v0.27.0 h1:QbhrTuB0ln9j9op6yAOR0o+cx/qa9NyNZ5ov0Tql8ZU= +github.com/libp2p/go-libp2p v0.27.0/go.mod h1:FAvvfQa/YOShUYdiSS03IR9OXzkcJXwcNA2FUCh9ImE= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= @@ -567,8 +544,8 @@ github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hd github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= -github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp98= +github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= @@ -576,8 +553,8 @@ github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyex github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= -github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA= -github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= +github.com/miekg/dns v1.1.53 h1:ZBkuHr5dxHtB1caEOlZTLPo7D3L3TWckgUUs/RHfDxw= +github.com/miekg/dns v1.1.53/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c h1:bzE/A84HN25pxAuk9Eej1Kz9OUelF97nAc82bDquQI8= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c/go.mod h1:0SQS9kMwD2VsyFEB++InYyBJroV/FRmBgcydeSUcJms= github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= @@ -599,7 +576,6 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= -github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mr-tron/base58 v1.1.3/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= @@ -645,8 +621,6 @@ github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXS github.com/multiformats/go-varint v0.0.6/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8= github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU= -github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= @@ -656,12 +630,12 @@ github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= -github.com/onsi/ginkgo/v2 v2.5.1 h1:auzK7OI497k6x4OvWq+TKAcpcSAlod0doAH72oIN0Jw= -github.com/onsi/ginkgo/v2 v2.5.1/go.mod h1:63DOGlLAH8+REH8jUGdL3YpCpu7JODesutUjdENfUAc= +github.com/onsi/ginkgo/v2 v2.9.2 h1:BA2GMJOtfGAfagzYtrAlufIP0lq6QERkFmHLMLPwFSU= +github.com/onsi/ginkgo/v2 v2.9.2/go.mod h1:WHcJJG2dIlcCqVfBAwUCrJxSPFb6v4azBwgxeMeDuts= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.24.0 h1:+0glovB9Jd6z3VR+ScSwQqXVTIfJcGA9UBM8yzQxhqg= +github.com/onsi/gomega v1.27.4 h1:Z2AnStgsdSayCMDiCU42qIz+HLqEPcgiOCXjAU/w+8E= github.com/opencontainers/runtime-spec v1.0.2 h1:UfAcuLBJB9Coz72x1hgl8O5RVzTdNiaglX6v2DM6FI0= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= @@ -675,7 +649,6 @@ github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2D github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 h1:1/WtZae0yGtPq+TI6+Tv1WTxkukpXeMlviSxvL7SRgk= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -687,40 +660,24 @@ github.com/polydawn/refmt v0.0.0-20201211092308-30ac6d18308e/go.mod h1:uIp+gprXx github.com/polydawn/refmt v0.89.0 h1:ADJTApkvkeBZsN0tBTx8QjpD9JkmxbKp0cxfr9qszm4= github.com/polydawn/refmt v0.89.0/go.mod h1:/zvteZs/GwLtCgZ4BL6CBsk9IKIlexP43ObX9AxTqTw= github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw= github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= -github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= -github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= -github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE= -github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= +github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM= +github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo= -github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= +github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= +github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= -github.com/quic-go/qtls-go1-19 v0.2.1 h1:aJcKNMkH5ASEJB9FXNeZCyTEIHU1J7MmHyz1Q1TSG1A= -github.com/quic-go/qtls-go1-19 v0.2.1/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI= -github.com/quic-go/qtls-go1-20 v0.1.1 h1:KbChDlg82d3IHqaj2bn6GfKRj84Per2VGf5XV3wSwQk= -github.com/quic-go/qtls-go1-20 v0.1.1/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= +github.com/quic-go/qtls-go1-19 v0.3.2 h1:tFxjCFcTQzK+oMxG6Zcvp4Dq8dx4yD3dDiIiyc86Z5U= +github.com/quic-go/qtls-go1-19 v0.3.2/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI= +github.com/quic-go/qtls-go1-20 v0.2.2 h1:WLOPx6OY/hxtTxKV1Zrq20FtXtDEkeY00CGQm8GEa3E= +github.com/quic-go/qtls-go1-20 v0.2.2/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= github.com/quic-go/quic-go v0.33.0 h1:ItNoTDN/Fm/zBlq769lLJc8ECe9gYaW40veHCCco7y0= github.com/quic-go/quic-go v0.33.0/go.mod h1:YMuhaAV9/jIu0XclDXwZPAsP/2Kgr5yMYhe9oxhhOFA= github.com/quic-go/webtransport-go v0.5.2 h1:GA6Bl6oZY+g/flt00Pnu0XtivSD8vukOu3lYhJjnGEk= @@ -761,8 +718,6 @@ github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeV github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYEDaXHZDBsXlPCDqdhQuJkuw4NOtaxYe3xii4= github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw= 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.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N3yZFZkDFs= @@ -794,6 +749,7 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= @@ -893,8 +849,8 @@ go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= -go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ= -go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.14.1/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= @@ -935,8 +891,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20230213192124-5e25df0256eb h1:PaBZQdo+iSDyHT053FjUCgZQ/9uqVwPOcl7KSWhKn6w= -golang.org/x/exp v0.0.0-20230213192124-5e25df0256eb/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= +golang.org/x/exp v0.0.0-20230321023759-10a507213a29 h1:ooxPy7fPvB4kwsA2h+iBNHkAbp/4JxTSwCmvdjEYmug= +golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -968,7 +924,6 @@ golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -978,7 +933,6 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -1004,10 +958,6 @@ golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210423184538-5f58ad60dda6/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= @@ -1020,9 +970,7 @@ golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4Iltr golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1033,7 +981,6 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= @@ -1043,7 +990,6 @@ golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1053,7 +999,6 @@ golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190405154228-4b34438f7a67/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1068,7 +1013,6 @@ golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191210023423-ac6580df4449/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 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= @@ -1085,29 +1029,23 @@ golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210426080607-c94f62235c83/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= @@ -1181,10 +1119,9 @@ golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4= +golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1294,7 +1231,6 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -1313,7 +1249,6 @@ gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= diff --git a/go.mod b/go.mod index 38f5a5a21..58d943ac5 100644 --- a/go.mod +++ b/go.mod @@ -45,7 +45,7 @@ require ( github.com/jbenet/goprocess v0.1.4 github.com/julienschmidt/httprouter v1.3.0 github.com/libp2p/go-doh-resolver v0.4.0 - github.com/libp2p/go-libp2p v0.26.4 + github.com/libp2p/go-libp2p v0.27.0 github.com/libp2p/go-libp2p-http v0.5.0 github.com/libp2p/go-libp2p-kad-dht v0.23.0 github.com/libp2p/go-libp2p-kbucket v0.5.0 @@ -100,7 +100,7 @@ require ( github.com/cenkalti/backoff v2.2.1+incompatible // indirect github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect - github.com/containerd/cgroups v1.0.4 // indirect + github.com/containerd/cgroups v1.1.0 // indirect github.com/crackcomm/go-gitignore v0.0.0-20170627025303-887ab5e44cc3 // indirect github.com/cskr/pubsub v1.0.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect @@ -118,21 +118,21 @@ require ( github.com/go-logfmt/logfmt v0.5.1 // indirect github.com/go-logr/logr v1.2.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect + github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/godbus/dbus/v5 v5.1.0 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/mock v1.6.0 // indirect - github.com/golang/protobuf v1.5.2 // indirect + github.com/golang/protobuf v1.5.3 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/gopacket v1.1.19 // indirect - github.com/google/pprof v0.0.0-20221203041831-ce31453925ec // indirect + github.com/google/pprof v0.0.0-20230405160723-4a4c7d95572b // indirect github.com/gorilla/mux v1.8.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 // indirect github.com/hannahhoward/go-pubsub v0.0.0-20200423002714-8d62886cc36e // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/golang-lru v0.5.4 // indirect - github.com/hashicorp/golang-lru/v2 v2.0.1 // indirect - github.com/huin/goupnp v1.0.3 // indirect + github.com/hashicorp/golang-lru/v2 v2.0.2 // indirect + github.com/huin/goupnp v1.1.0 // indirect github.com/ipfs/bbloom v0.0.4 // indirect github.com/ipfs/go-bitfield v1.1.0 // indirect github.com/ipfs/go-ipfs-blockstore v1.3.0 // indirect @@ -146,13 +146,13 @@ require ( github.com/ipfs/go-peertaskqueue v0.8.1 // indirect github.com/ipld/edelweiss v0.2.0 // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect - github.com/klauspost/compress v1.15.12 // indirect + github.com/klauspost/compress v1.16.4 // indirect github.com/klauspost/cpuid/v2 v2.2.4 // indirect - github.com/koron/go-ssdp v0.0.3 // indirect + github.com/koron/go-ssdp v0.0.4 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/libp2p/go-cidranger v1.1.0 // indirect github.com/libp2p/go-flow-metrics v0.1.0 // indirect - github.com/libp2p/go-libp2p-asn-util v0.2.0 // indirect + github.com/libp2p/go-libp2p-asn-util v0.3.0 // indirect github.com/libp2p/go-libp2p-gostream v0.6.0 // indirect github.com/libp2p/go-libp2p-xor v0.1.0 // indirect github.com/libp2p/go-mplex v0.7.0 // indirect @@ -164,11 +164,11 @@ require ( github.com/libp2p/zeroconf/v2 v2.2.0 // indirect github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect github.com/mattn/go-colorable v0.1.4 // indirect - github.com/mattn/go-isatty v0.0.17 // indirect + github.com/mattn/go-isatty v0.0.18 // indirect github.com/mattn/go-runewidth v0.0.4 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect - github.com/miekg/dns v1.1.50 // indirect + github.com/miekg/dns v1.1.53 // indirect github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect github.com/minio/sha256-simd v1.0.0 // indirect @@ -178,18 +178,18 @@ require ( github.com/multiformats/go-multiaddr-fmt v0.1.0 // indirect github.com/multiformats/go-multistream v0.4.1 // indirect github.com/multiformats/go-varint v0.0.7 // indirect - github.com/onsi/ginkgo/v2 v2.5.1 // indirect + github.com/onsi/ginkgo/v2 v2.9.2 // indirect github.com/opencontainers/runtime-spec v1.0.2 // indirect github.com/openzipkin/zipkin-go v0.4.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/polydawn/refmt v0.89.0 // indirect github.com/prometheus/client_model v0.3.0 // indirect - github.com/prometheus/common v0.37.0 // indirect - github.com/prometheus/procfs v0.8.0 // indirect + github.com/prometheus/common v0.42.0 // indirect + github.com/prometheus/procfs v0.9.0 // indirect github.com/prometheus/statsd_exporter v0.22.7 // indirect github.com/quic-go/qpack v0.4.0 // indirect - github.com/quic-go/qtls-go1-19 v0.2.1 // indirect - github.com/quic-go/qtls-go1-20 v0.1.1 // indirect + github.com/quic-go/qtls-go1-19 v0.3.2 // indirect + github.com/quic-go/qtls-go1-20 v0.2.2 // indirect github.com/quic-go/quic-go v0.33.0 // indirect github.com/quic-go/webtransport-go v0.5.2 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect @@ -213,14 +213,14 @@ require ( go.opentelemetry.io/otel/metric v0.37.0 // indirect go.opentelemetry.io/proto/otlp v0.19.0 // indirect go.uber.org/atomic v1.10.0 // indirect - go.uber.org/multierr v1.10.0 // indirect + go.uber.org/multierr v1.11.0 // indirect go4.org v0.0.0-20230225012048-214862532bf5 // indirect - golang.org/x/exp v0.0.0-20230213192124-5e25df0256eb // indirect + golang.org/x/exp v0.0.0-20230321023759-10a507213a29 // indirect golang.org/x/net v0.8.0 // indirect - golang.org/x/oauth2 v0.4.0 // indirect + golang.org/x/oauth2 v0.5.0 // indirect golang.org/x/term v0.6.0 // indirect golang.org/x/text v0.8.0 // indirect - golang.org/x/tools v0.6.0 // indirect + golang.org/x/tools v0.7.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect gonum.org/v1/gonum v0.11.0 // indirect google.golang.org/appengine v1.6.7 // indirect diff --git a/go.sum b/go.sum index bd48a883c..c623a9d4d 100644 --- a/go.sum +++ b/go.sum @@ -112,8 +112,8 @@ github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWH github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/containerd/cgroups v0.0.0-20201119153540-4cbc285b3327/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE= -github.com/containerd/cgroups v1.0.4 h1:jN/mbWBEaz+T1pi5OFtnkQ+8qnmEbAr1Oo1FRm5B0dA= -github.com/containerd/cgroups v1.0.4/go.mod h1:nLNQtsF7Sl2HxNebu77i1R0oDlhiTG+kO4JTrUzo6IA= +github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM= +github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw= 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= @@ -220,8 +220,8 @@ github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+ github.com/go-playground/validator/v10 v10.2.0 h1:KgJ0snyC2R9VXYN2rneOtQcw5aHQB1Vv0sFl1UcHBOY= github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -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/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= @@ -272,8 +272,9 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= @@ -308,8 +309,8 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20221203041831-ce31453925ec h1:fR20TYVVwhK4O7r7y+McjRYyaTH6/vjwJOajE+XhlzM= -github.com/google/pprof v0.0.0-20221203041831-ce31453925ec/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo= +github.com/google/pprof v0.0.0-20230405160723-4a4c7d95572b h1:Qcx5LM0fSiks9uCyFZwDBUasd3lxd1RM0GYpL+Li5o4= +github.com/google/pprof v0.0.0-20230405160723-4a4c7d95572b/go.mod h1:79YE0hCXdHag9sBkw2o+N/YnZtTkXi0UT9Nnixa5eYk= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -343,13 +344,13 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= -github.com/hashicorp/golang-lru/v2 v2.0.1 h1:5pv5N1lT1fjLg2VQ5KWc7kmucp2x/kvFOnxuVTqZ6x4= -github.com/hashicorp/golang-lru/v2 v2.0.1/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= +github.com/hashicorp/golang-lru/v2 v2.0.2 h1:Dwmkdr5Nc/oBiXgJS3CDHNhJtIHkuZ3DZF5twqnfBdU= +github.com/hashicorp/golang-lru/v2 v2.0.2/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= -github.com/huin/goupnp v1.0.3 h1:N8No57ls+MnjlB+JPiCVSOyy/ot7MJTqlo7rn+NYSqQ= -github.com/huin/goupnp v1.0.3/go.mod h1:ZxNlw5WqJj6wSsRK5+YfflQGXYfccj5VgQsMNixHM7Y= +github.com/huin/goupnp v1.1.0 h1:gEe0Dp/lZmPZiDFzJJaOfUpOvv2MKUkoBX8lDrn9vKU= +github.com/huin/goupnp v1.1.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= @@ -503,8 +504,8 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI 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.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/klauspost/compress v1.15.12 h1:YClS/PImqYbn+UILDnqxQCZ3RehC9N318SU3kElDUEM= -github.com/klauspost/compress v1.15.12/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= +github.com/klauspost/compress v1.16.4 h1:91KN02FnsOYhuunwU4ssRe8lc2JosWmizWa91B5v1PU= +github.com/klauspost/compress v1.16.4/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk= @@ -512,8 +513,8 @@ github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8t github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/koron/go-ssdp v0.0.0-20191105050749-2e1c40ed0b5d/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk= -github.com/koron/go-ssdp v0.0.3 h1:JivLMY45N76b4p/vsWGOKewBQu6uf39y8l+AQ7sDKx8= -github.com/koron/go-ssdp v0.0.3/go.mod h1:b2MxI6yh02pKrsyNoQUsk4+YNikaGhe4894J+Q5lDvA= +github.com/koron/go-ssdp v0.0.4 h1:1IDwrghSKYM7yLf7XCzbByg2sJ/JcNOZRXS2jczTwz0= +github.com/koron/go-ssdp v0.0.4/go.mod h1:oDXq+E5IL5q0U8uSBcoAXzTzInwy5lEgC91HoKtbmZk= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= @@ -539,10 +540,10 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.26.4 h1:VA9ChjN0n1BwwfU/dqx4Zj9ezXtIxGk8FyJPwFONqxs= -github.com/libp2p/go-libp2p v0.26.4/go.mod h1:x75BN32YbwuY0Awm2Uix4d4KOz+/4piInkp4Wr3yOo8= -github.com/libp2p/go-libp2p-asn-util v0.2.0 h1:rg3+Os8jbnO5DxkC7K/Utdi+DkY3q/d1/1q+8WeNAsw= -github.com/libp2p/go-libp2p-asn-util v0.2.0/go.mod h1:WoaWxbHKBymSN41hWSq/lGKJEca7TNm58+gGJi2WsLI= +github.com/libp2p/go-libp2p v0.27.0 h1:QbhrTuB0ln9j9op6yAOR0o+cx/qa9NyNZ5ov0Tql8ZU= +github.com/libp2p/go-libp2p v0.27.0/go.mod h1:FAvvfQa/YOShUYdiSS03IR9OXzkcJXwcNA2FUCh9ImE= +github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= +github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= github.com/libp2p/go-libp2p-core v0.3.0/go.mod h1:ACp3DmS3/N64c2jDzcV429ukDpicbL6+TrrxANBjPGw= github.com/libp2p/go-libp2p-gostream v0.6.0 h1:QfAiWeQRce6pqnYfmIVWJFXNdDyfiR/qkCnjyaZUPYU= @@ -605,8 +606,8 @@ github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOA github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= -github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp98= +github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= 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= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= @@ -617,8 +618,8 @@ github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyex github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= -github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA= -github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= +github.com/miekg/dns v1.1.53 h1:ZBkuHr5dxHtB1caEOlZTLPo7D3L3TWckgUUs/RHfDxw= +github.com/miekg/dns v1.1.53/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c h1:bzE/A84HN25pxAuk9Eej1Kz9OUelF97nAc82bDquQI8= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c/go.mod h1:0SQS9kMwD2VsyFEB++InYyBJroV/FRmBgcydeSUcJms= github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= @@ -698,12 +699,12 @@ github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= -github.com/onsi/ginkgo/v2 v2.5.1 h1:auzK7OI497k6x4OvWq+TKAcpcSAlod0doAH72oIN0Jw= -github.com/onsi/ginkgo/v2 v2.5.1/go.mod h1:63DOGlLAH8+REH8jUGdL3YpCpu7JODesutUjdENfUAc= +github.com/onsi/ginkgo/v2 v2.9.2 h1:BA2GMJOtfGAfagzYtrAlufIP0lq6QERkFmHLMLPwFSU= +github.com/onsi/ginkgo/v2 v2.9.2/go.mod h1:WHcJJG2dIlcCqVfBAwUCrJxSPFb6v4azBwgxeMeDuts= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.24.0 h1:+0glovB9Jd6z3VR+ScSwQqXVTIfJcGA9UBM8yzQxhqg= +github.com/onsi/gomega v1.27.4 h1:Z2AnStgsdSayCMDiCU42qIz+HLqEPcgiOCXjAU/w+8E= github.com/opencontainers/runtime-spec v1.0.2 h1:UfAcuLBJB9Coz72x1hgl8O5RVzTdNiaglX6v2DM6FI0= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= @@ -752,8 +753,9 @@ github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB8 github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/common v0.35.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= -github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE= github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= +github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM= +github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= @@ -761,16 +763,17 @@ github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsT github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo= github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= +github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= +github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= github.com/prometheus/statsd_exporter v0.22.7 h1:7Pji/i2GuhK6Lu7DHrtTkFmNBCudCPT1pX2CziuyQR0= github.com/prometheus/statsd_exporter v0.22.7/go.mod h1:N/TevpjkIh9ccs6nuzY3jQn9dFqnUakOjnEuMPJJJnI= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= -github.com/quic-go/qtls-go1-19 v0.2.1 h1:aJcKNMkH5ASEJB9FXNeZCyTEIHU1J7MmHyz1Q1TSG1A= -github.com/quic-go/qtls-go1-19 v0.2.1/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI= -github.com/quic-go/qtls-go1-20 v0.1.1 h1:KbChDlg82d3IHqaj2bn6GfKRj84Per2VGf5XV3wSwQk= -github.com/quic-go/qtls-go1-20 v0.1.1/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= +github.com/quic-go/qtls-go1-19 v0.3.2 h1:tFxjCFcTQzK+oMxG6Zcvp4Dq8dx4yD3dDiIiyc86Z5U= +github.com/quic-go/qtls-go1-19 v0.3.2/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI= +github.com/quic-go/qtls-go1-20 v0.2.2 h1:WLOPx6OY/hxtTxKV1Zrq20FtXtDEkeY00CGQm8GEa3E= +github.com/quic-go/qtls-go1-20 v0.2.2/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= github.com/quic-go/quic-go v0.33.0 h1:ItNoTDN/Fm/zBlq769lLJc8ECe9gYaW40veHCCco7y0= github.com/quic-go/quic-go v0.33.0/go.mod h1:YMuhaAV9/jIu0XclDXwZPAsP/2Kgr5yMYhe9oxhhOFA= github.com/quic-go/webtransport-go v0.5.2 h1:GA6Bl6oZY+g/flt00Pnu0XtivSD8vukOu3lYhJjnGEk= @@ -976,8 +979,8 @@ go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= -go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ= -go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.14.1/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= @@ -1018,8 +1021,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20230213192124-5e25df0256eb h1:PaBZQdo+iSDyHT053FjUCgZQ/9uqVwPOcl7KSWhKn6w= -golang.org/x/exp v0.0.0-20230213192124-5e25df0256eb/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= +golang.org/x/exp v0.0.0-20230321023759-10a507213a29 h1:ooxPy7fPvB4kwsA2h+iBNHkAbp/4JxTSwCmvdjEYmug= +golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1089,7 +1092,6 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210423184538-5f58ad60dda6/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= @@ -1107,8 +1109,8 @@ golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4Iltr golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.4.0 h1:NF0gk8LVPg1Ml7SSbGyySuoxdsXitj7TvgvuRxIMc/M= -golang.org/x/oauth2 v0.4.0/go.mod h1:RznEsdpjGAINPTOF0UH/t+xJ75L18YO3Ho6Pyn+uRec= +golang.org/x/oauth2 v0.5.0 h1:HuArIo48skDwlrvM3sEdHXElYslAMsf3KwRkkW4MC4s= +golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I= golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1194,9 +1196,9 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220708085239-5a0f0661e09d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= @@ -1272,10 +1274,9 @@ golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4= +golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/test/sharness/t0119-prometheus-data/prometheus_metrics b/test/sharness/t0119-prometheus-data/prometheus_metrics index 192e526c1..5db8a7665 100644 --- a/test/sharness/t0119-prometheus-data/prometheus_metrics +++ b/test/sharness/t0119-prometheus-data/prometheus_metrics @@ -579,6 +579,17 @@ leveldb_datastore_sync_total libp2p_autonat_next_probe_timestamp libp2p_autonat_reachability_status libp2p_autonat_reachability_status_confidence +libp2p_autorelay_candidate_loop_state +libp2p_autorelay_candidates_circuit_v2_support_total +libp2p_autorelay_candidates_circuit_v2_support_total +libp2p_autorelay_desired_reservations +libp2p_autorelay_relay_addresses_count +libp2p_autorelay_relay_addresses_updated_total +libp2p_autorelay_reservation_requests_outcome_total +libp2p_autorelay_reservation_requests_outcome_total +libp2p_autorelay_reservations_closed_total +libp2p_autorelay_reservations_opened_total +libp2p_autorelay_status libp2p_eventbus_events_emitted_total libp2p_eventbus_events_emitted_total libp2p_eventbus_subscriber_event_queued @@ -678,6 +689,22 @@ libp2p_identify_protocols_received_bucket libp2p_identify_protocols_received_bucket libp2p_identify_protocols_received_count libp2p_identify_protocols_received_sum +libp2p_relaysvc_connection_duration_seconds_bucket +libp2p_relaysvc_connection_duration_seconds_bucket +libp2p_relaysvc_connection_duration_seconds_bucket +libp2p_relaysvc_connection_duration_seconds_bucket +libp2p_relaysvc_connection_duration_seconds_bucket +libp2p_relaysvc_connection_duration_seconds_bucket +libp2p_relaysvc_connection_duration_seconds_bucket +libp2p_relaysvc_connection_duration_seconds_bucket +libp2p_relaysvc_connection_duration_seconds_bucket +libp2p_relaysvc_connection_duration_seconds_bucket +libp2p_relaysvc_connection_duration_seconds_bucket +libp2p_relaysvc_connection_duration_seconds_bucket +libp2p_relaysvc_connection_duration_seconds_count +libp2p_relaysvc_connection_duration_seconds_sum +libp2p_relaysvc_data_transferred_bytes_total +libp2p_relaysvc_status process_cpu_seconds_total process_max_fds process_open_fds From 16d8d972b669ce6658c30719396e38905852a9fb Mon Sep 17 00:00:00 2001 From: galargh Date: Fri, 7 Apr 2023 07:12:08 +0000 Subject: [PATCH 0624/1212] chore: update version --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index 992f4a988..850332654 100644 --- a/version.go +++ b/version.go @@ -11,7 +11,7 @@ import ( var CurrentCommit string // CurrentVersionNumber is the current application's version literal -const CurrentVersionNumber = "0.20.0-dev" +const CurrentVersionNumber = "0.20.0-rc1" const ApiVersion = "/kubo/" + CurrentVersionNumber + "/" //nolint From c58aadb887a5ca88256ac8f3a8fbf60b0263c978 Mon Sep 17 00:00:00 2001 From: Piotr Galar Date: Fri, 7 Apr 2023 09:28:40 +0200 Subject: [PATCH 0625/1212] chore: update version (#9805) --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index 992f4a988..bf6419ec6 100644 --- a/version.go +++ b/version.go @@ -11,7 +11,7 @@ import ( var CurrentCommit string // CurrentVersionNumber is the current application's version literal -const CurrentVersionNumber = "0.20.0-dev" +const CurrentVersionNumber = "0.21.0-dev" const ApiVersion = "/kubo/" + CurrentVersionNumber + "/" //nolint From a97bf4271d54898ca7f2447d2308fad1ebb8968b Mon Sep 17 00:00:00 2001 From: Gus Eggert Date: Mon, 10 Apr 2023 06:59:40 -0400 Subject: [PATCH 0626/1212] chore: set kubo-maintainers as default code owners (#9808) --- .github/CODEOWNERS | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 5151ad178..7d17855e0 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -2,6 +2,9 @@ # request that modifies code that they own. Code owners are not automatically # requested to review draft pull requests. +# Default +* @ipfs/kubo-maintainers + # HTTP Gateway core/corehttp/ @lidel test/sharness/*gateway*.sh @lidel From 03a98280e3e642774776cd3d0435ab53e5dfa867 Mon Sep 17 00:00:00 2001 From: Gus Eggert Date: Fri, 7 Apr 2023 08:57:21 -0400 Subject: [PATCH 0627/1212] test: port twonode test to Go, remove multinode test The multinode test is effectively the same as the twonode test. There are some problems with it too: it *looks* like it's testing the Websocket transport with the "listentype,ws" IPTB attribute, but that attribute doesn't actually exist in ipfs/iptb-plugins, so it does nothing, so that test actually just runs the same test twice (Yamux disabled). Furthermore, this is just the same test as in the mplex twonode test. So this just removes the useless multinode test entirely. Also, this removes the part of the twonode test that checks the amount of data transferred over Bitswap. This is an implementation detail of Bitswap, it's not appropriate to test this in an end-to-end test as it depends on algorithmic details of how Bitswap works, and has nothing to do with transports. This is probably more appropriate as a perf or benchmark test of Bitswap. This also moves equivalent functionality from jbenet/go-random-files into the testutils package. This just copies the code and modifies it slightly for better ergonomics. --- test/cli/testutils/random_files.go | 116 +++++++++++++++++++ test/cli/transports_test.go | 127 ++++++++++++++++++++ test/sharness/t0125-twonode.sh | 178 ----------------------------- test/sharness/t0130-multinode.sh | 115 ------------------- 4 files changed, 243 insertions(+), 293 deletions(-) create mode 100644 test/cli/testutils/random_files.go create mode 100644 test/cli/transports_test.go delete mode 100755 test/sharness/t0125-twonode.sh delete mode 100755 test/sharness/t0130-multinode.sh diff --git a/test/cli/testutils/random_files.go b/test/cli/testutils/random_files.go new file mode 100644 index 000000000..0e550a125 --- /dev/null +++ b/test/cli/testutils/random_files.go @@ -0,0 +1,116 @@ +package testutils + +import ( + "fmt" + "io" + "math/rand" + "os" + "path" + "time" +) + +var AlphabetEasy = []rune("abcdefghijklmnopqrstuvwxyz01234567890-_") +var AlphabetHard = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890!@#$%^&*()-_+= ;.,<>'\"[]{}() ") + +type RandFiles struct { + Rand *rand.Rand + FileSize int // the size per file. + FilenameSize int + Alphabet []rune // for filenames + + FanoutDepth int // how deep the hierarchy goes + FanoutFiles int // how many files per dir + FanoutDirs int // how many dirs per dir + + RandomSize bool // randomize file sizes + RandomFanout bool // randomize fanout numbers +} + +func NewRandFiles() *RandFiles { + return &RandFiles{ + Rand: rand.New(rand.NewSource(time.Now().UnixNano())), + FileSize: 4096, + FilenameSize: 16, + Alphabet: AlphabetEasy, + FanoutDepth: 2, + FanoutDirs: 5, + FanoutFiles: 10, + RandomSize: true, + } +} + +func (r *RandFiles) WriteRandomFiles(root string, depth int) error { + numfiles := r.FanoutFiles + if r.RandomFanout { + numfiles = rand.Intn(r.FanoutFiles) + 1 + } + + for i := 0; i < numfiles; i++ { + if err := r.WriteRandomFile(root); err != nil { + return err + } + } + + if depth+1 <= r.FanoutDepth { + numdirs := r.FanoutDirs + if r.RandomFanout { + numdirs = r.Rand.Intn(numdirs) + 1 + } + + for i := 0; i < numdirs; i++ { + if err := r.WriteRandomDir(root, depth+1); err != nil { + return err + } + } + } + + return nil +} + +func (r *RandFiles) RandomFilename(length int) string { + b := make([]rune, length) + for i := range b { + b[i] = r.Alphabet[r.Rand.Intn(len(r.Alphabet))] + } + return string(b) +} + +func (r *RandFiles) WriteRandomFile(root string) error { + filesize := int64(r.FileSize) + if r.RandomSize { + filesize = r.Rand.Int63n(filesize) + 1 + } + + n := rand.Intn(r.FilenameSize-4) + 4 + name := r.RandomFilename(n) + filepath := path.Join(root, name) + f, err := os.Create(filepath) + if err != nil { + return fmt.Errorf("creating random file: %w", err) + } + + if _, err := io.CopyN(f, r.Rand, filesize); err != nil { + return fmt.Errorf("copying random file: %w", err) + } + + return f.Close() +} + +func (r *RandFiles) WriteRandomDir(root string, depth int) error { + if depth > r.FanoutDepth { + return nil + } + + n := rand.Intn(r.FilenameSize-4) + 4 + name := r.RandomFilename(n) + root = path.Join(root, name) + if err := os.MkdirAll(root, 0755); err != nil { + return fmt.Errorf("creating random dir: %w", err) + } + + err := r.WriteRandomFiles(root, depth) + if err != nil { + return fmt.Errorf("writing random files in random dir: %w", err) + } + return nil +} diff --git a/test/cli/transports_test.go b/test/cli/transports_test.go new file mode 100644 index 000000000..78f21fd05 --- /dev/null +++ b/test/cli/transports_test.go @@ -0,0 +1,127 @@ +package cli + +import ( + "os" + "path/filepath" + "testing" + + "github.com/ipfs/kubo/config" + "github.com/ipfs/kubo/test/cli/harness" + "github.com/ipfs/kubo/test/cli/testutils" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestTransports(t *testing.T) { + disableRouting := func(nodes harness.Nodes) { + nodes.ForEachPar(func(n *harness.Node) { + n.UpdateConfig(func(cfg *config.Config) { + cfg.Routing.Type = config.NewOptionalString("none") + cfg.Bootstrap = nil + }) + }) + } + checkSingleFile := func(nodes harness.Nodes) { + s := testutils.RandomStr(100) + hash := nodes[0].IPFSAddStr(s) + nodes.ForEachPar(func(n *harness.Node) { + val := n.IPFS("cat", hash).Stdout.String() + assert.Equal(t, s, val) + }) + } + checkRandomDir := func(nodes harness.Nodes) { + randDir := filepath.Join(nodes[0].Dir, "foobar") + require.NoError(t, os.Mkdir(randDir, 0777)) + rf := testutils.NewRandFiles() + rf.FanoutDirs = 3 + rf.FanoutFiles = 6 + require.NoError(t, rf.WriteRandomFiles(randDir, 4)) + + hash := nodes[1].IPFS("add", "-r", "-Q", randDir).Stdout.Trimmed() + nodes.ForEachPar(func(n *harness.Node) { + res := n.RunIPFS("refs", "-r", hash) + assert.Equal(t, 0, res.ExitCode()) + }) + } + + runTests := func(nodes harness.Nodes) { + checkSingleFile(nodes) + checkRandomDir(nodes) + } + + tcpNodes := func(t *testing.T) harness.Nodes { + nodes := harness.NewT(t).NewNodes(2).Init() + nodes.ForEachPar(func(n *harness.Node) { + n.UpdateConfig(func(cfg *config.Config) { + cfg.Addresses.Swarm = []string{"/ip4/127.0.0.1/tcp/0"} + cfg.Swarm.Transports.Network.QUIC = config.False + cfg.Swarm.Transports.Network.Relay = config.False + cfg.Swarm.Transports.Network.WebTransport = config.False + cfg.Swarm.Transports.Network.Websocket = config.False + }) + }) + disableRouting(nodes) + return nodes + } + + t.Run("tcp", func(t *testing.T) { + t.Parallel() + nodes := tcpNodes(t).StartDaemons().Connect() + runTests(nodes) + }) + + t.Run("tcp with mplex", func(t *testing.T) { + t.Parallel() + nodes := tcpNodes(t) + nodes.ForEachPar(func(n *harness.Node) { + n.UpdateConfig(func(cfg *config.Config) { + cfg.Swarm.Transports.Multiplexers.Yamux = config.Disabled + }) + }) + nodes.StartDaemons().Connect() + runTests(nodes) + }) + + t.Run("tcp with NOISE", func(t *testing.T) { + t.Parallel() + nodes := tcpNodes(t) + nodes.ForEachPar(func(n *harness.Node) { + n.UpdateConfig(func(cfg *config.Config) { + cfg.Swarm.Transports.Security.TLS = config.Disabled + }) + }) + nodes.StartDaemons().Connect() + runTests(nodes) + }) + + t.Run("QUIC", func(t *testing.T) { + t.Parallel() + nodes := harness.NewT(t).NewNodes(5).Init() + nodes.ForEachPar(func(n *harness.Node) { + n.UpdateConfig(func(cfg *config.Config) { + cfg.Addresses.Swarm = []string{"/ip4/127.0.0.1/udp/0/quic-v1"} + cfg.Swarm.Transports.Network.QUIC = config.True + cfg.Swarm.Transports.Network.TCP = config.False + }) + }) + disableRouting(nodes) + nodes.StartDaemons().Connect() + runTests(nodes) + }) + + t.Run("QUIC", func(t *testing.T) { + t.Parallel() + nodes := harness.NewT(t).NewNodes(5).Init() + nodes.ForEachPar(func(n *harness.Node) { + n.UpdateConfig(func(cfg *config.Config) { + cfg.Addresses.Swarm = []string{"/ip4/127.0.0.1/udp/0/quic-v1/webtransport"} + cfg.Swarm.Transports.Network.QUIC = config.True + cfg.Swarm.Transports.Network.WebTransport = config.True + }) + }) + disableRouting(nodes) + nodes.StartDaemons().Connect() + runTests(nodes) + }) + +} diff --git a/test/sharness/t0125-twonode.sh b/test/sharness/t0125-twonode.sh deleted file mode 100755 index 8ea1c9e5d..000000000 --- a/test/sharness/t0125-twonode.sh +++ /dev/null @@ -1,178 +0,0 @@ -#!/usr/bin/env bash -# -# Copyright (c) 2017 Jeromy Johnson -# MIT Licensed; see the LICENSE file in this repository. -# - -test_description="Test two ipfs nodes transferring a file" - -. lib/test-lib.sh - -check_file_fetch() { - node=$1 - fhash=$2 - fname=$3 - - test_expect_success "can fetch file" ' - ipfsi $node cat $fhash > fetch_out - ' - - test_expect_success "file looks good" ' - test_cmp $fname fetch_out - ' -} - -check_dir_fetch() { - node=$1 - ref=$2 - - test_expect_success "node can fetch all refs for dir" ' - ipfsi $node refs -r $ref > /dev/null - ' -} - -run_single_file_test() { - test_expect_success "add a file on node1" ' - random 1000000 > filea && - FILEA_HASH=$(ipfsi 1 add -q filea) - ' - - check_file_fetch 0 $FILEA_HASH filea -} - -run_random_dir_test() { - test_expect_success "create a bunch of random files" ' - random-files -depth=3 -dirs=4 -files=5 -seed=5 foobar > /dev/null - ' - - test_expect_success "add those on node 0" ' - DIR_HASH=$(ipfsi 0 add -r -Q foobar) - ' - - check_dir_fetch 1 $DIR_HASH -} - -flaky_advanced_test() { - startup_cluster 2 "$@" - - test_expect_success "clean repo before test" ' - ipfsi 0 repo gc > /dev/null && - ipfsi 1 repo gc > /dev/null - ' - - run_single_file_test - - run_random_dir_test - - test_expect_success "gather bitswap stats" ' - ipfsi 0 bitswap stat -v > stat0 && - ipfsi 1 bitswap stat -v > stat1 - ' - - test_expect_success "shut down nodes" ' - iptb stop && iptb_wait_stop - ' - - # NOTE: data transferred stats checks are flaky - # trying to debug them by printing out the stats hides the flakiness - # my theory is that the extra time cat calls take to print out the stats - # allow for proper cleanup to happen - go-sleep 1s -} - -run_advanced_test() { - # TODO: investigate why flaky_advanced_test is flaky - # Context: https://github.com/ipfs/kubo/pull/9486 - # sometimes, bitswap status returns unexpected block transfers - # and everyone has been re-running circleci until is passes for at least a year. - # this re-runs test until it passes or a timeout hits - - BLOCKS_0=126 - BLOCKS_1=5 - DATA_0=228113 - DATA_1=1000256 - for i in $(test_seq 1 600); do - flaky_advanced_test - (grep -q "$DATA_0" stat0 && grep -q "$DATA_1" stat1) && break - go-sleep 100ms - done - - test_expect_success "node0 data transferred looks correct" ' - test_should_contain "blocks sent: $BLOCKS_0" stat0 && - test_should_contain "blocks received: $BLOCKS_1" stat0 && - test_should_contain "data sent: $DATA_0" stat0 && - test_should_contain "data received: $DATA_1" stat0 - ' - - test_expect_success "node1 data transferred looks correct" ' - test_should_contain "blocks received: $BLOCKS_0" stat1 && - test_should_contain "blocks sent: $BLOCKS_1" stat1 && - test_should_contain "data received: $DATA_0" stat1 && - test_should_contain "data sent: $DATA_1" stat1 - ' - -} - -test_expect_success "set up tcp testbed" ' - iptb testbed create -type localipfs -count 2 -force -init -' - -test_expect_success "disable routing, use direct peering" ' - iptb run -- ipfs config Routing.Type none && - iptb run -- ipfs config --json Bootstrap "[]" -' - -# Test TCP transport -echo "Testing TCP" -addrs='"[\"/ip4/127.0.0.1/tcp/0\"]"' -test_expect_success "use TCP only" ' - iptb run -- ipfs config --json Addresses.Swarm '"${addrs}"' && - iptb run -- ipfs config --json Swarm.Transports.Network.QUIC false && - iptb run -- ipfs config --json Swarm.Transports.Network.Relay false && - iptb run -- ipfs config --json Swarm.Transports.Network.WebTransport false && - iptb run -- ipfs config --json Swarm.Transports.Network.Websocket false -' -run_advanced_test - -# test multiplex muxer -echo "Running TCP tests with mplex" -test_expect_success "disable yamux" ' - iptb run -- ipfs config --json Swarm.Transports.Multiplexers.Yamux false -' -run_advanced_test - -test_expect_success "re-enable yamux" ' - iptb run -- ipfs config --json Swarm.Transports.Multiplexers.Yamux null -' -# test Noise -echo "Running TCP tests with NOISE" -test_expect_success "use noise only" ' - iptb run -- ipfs config --json Swarm.Transports.Security.TLS false -' -run_advanced_test - -test_expect_success "re-enable TLS" ' - iptb run -- ipfs config --json Swarm.Transports.Security.TLS null -' - -# test QUIC -echo "Running advanced tests over QUIC" -addrs='"[\"/ip4/127.0.0.1/udp/0/quic-v1\"]"' -test_expect_success "use QUIC only" ' - iptb run -- ipfs config --json Addresses.Swarm '"${addrs}"' && - iptb run -- ipfs config --json Swarm.Transports.Network.QUIC true && - iptb run -- ipfs config --json Swarm.Transports.Network.TCP false -' -run_advanced_test - -# test WebTransport -echo "Running advanced tests over WebTransport" -addrs='"[\"/ip4/127.0.0.1/udp/0/quic-v1/webtransport\"]"' -test_expect_success "use WebTransport only" ' - iptb run -- ipfs config --json Addresses.Swarm '"${addrs}"' && - iptb run -- ipfs config --json Swarm.Transports.Network.QUIC true && - iptb run -- ipfs config --json Swarm.Transports.Network.WebTransport true -' -run_advanced_test - -test_done diff --git a/test/sharness/t0130-multinode.sh b/test/sharness/t0130-multinode.sh deleted file mode 100755 index 04746850b..000000000 --- a/test/sharness/t0130-multinode.sh +++ /dev/null @@ -1,115 +0,0 @@ -#!/usr/bin/env bash -# -# Copyright (c) 2015 Jeromy Johnson -# MIT Licensed; see the LICENSE file in this repository. -# - -test_description="Test multiple ipfs nodes" - -. lib/test-lib.sh - -check_file_fetch() { - node=$1 - fhash=$2 - fname=$3 - - test_expect_success "can fetch file" ' - ipfsi $node cat $fhash > fetch_out - ' - - test_expect_success "file looks good" ' - test_cmp $fname fetch_out - ' -} - -check_dir_fetch() { - node=$1 - ref=$2 - - test_expect_success "node can fetch all refs for dir" ' - ipfsi $node refs -r $ref > /dev/null - ' -} - -run_single_file_test() { - test_expect_success "add a file on node1" ' - random 1000000 > filea && - FILEA_HASH=$(ipfsi 1 add -q filea) - ' - - check_file_fetch 4 $FILEA_HASH filea - check_file_fetch 3 $FILEA_HASH filea - check_file_fetch 2 $FILEA_HASH filea - check_file_fetch 1 $FILEA_HASH filea - check_file_fetch 0 $FILEA_HASH filea -} - -run_random_dir_test() { - test_expect_success "create a bunch of random files" ' - random-files -depth=4 -dirs=3 -files=6 foobar > /dev/null - ' - - test_expect_success "add those on node 2" ' - DIR_HASH=$(ipfsi 2 add -r -Q foobar) - ' - - check_dir_fetch 0 $DIR_HASH - check_dir_fetch 1 $DIR_HASH - check_dir_fetch 2 $DIR_HASH - check_dir_fetch 3 $DIR_HASH - check_dir_fetch 4 $DIR_HASH -} - - -run_basic_test() { - startup_cluster 5 - - run_single_file_test - - test_expect_success "shut down nodes" ' - iptb stop && iptb_wait_stop - ' -} - -run_advanced_test() { - startup_cluster 5 "$@" - - run_single_file_test - - run_random_dir_test - - test_expect_success "shut down nodes" ' - iptb stop && iptb_wait_stop || - test_fsh tail -n +1 .iptb/testbeds/default/*/daemon.std* - ' -} - -test_expect_success "set up /tcp testbed" ' - iptb testbed create -type localipfs -count 5 -force -init -' - -# test default configuration -run_advanced_test - -# test multiplex muxer -test_expect_success "disable yamux" ' - iptb run -- ipfs config --json Swarm.Transports.Multiplexers.Yamux false -' -run_advanced_test - -test_expect_success "set up /ws testbed" ' - iptb testbed create -type localipfs -count 5 -attr listentype,ws -force -init -' - -# test default configuration -run_advanced_test - -# test multiplex muxer -test_expect_success "disable yamux" ' - iptb run -- ipfs config --json Swarm.Transports.Multiplexers.Yamux false -' - -run_advanced_test - - -test_done From f7cab554f9a8d1fc2b16742c10ea75f8f05e4190 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Wed, 12 Apr 2023 01:51:02 +0200 Subject: [PATCH 0628/1212] feat: boxo tracing and traceparent support (#9811) https://www.w3.org/TR/trace-context/ https://github.com/ipfs/bifrost-gateway/issues/68 --- docs/environment-variables.md | 71 +-------------------- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 +- go.mod | 12 ++-- go.sum | 4 +- tracing/file_exporter.go | 45 ------------- tracing/tracing.go | 88 +------------------------- 7 files changed, 14 insertions(+), 212 deletions(-) delete mode 100644 tracing/file_exporter.go diff --git a/docs/environment-variables.md b/docs/environment-variables.md index b3d03d1bd..4113be09b 100644 --- a/docs/environment-variables.md +++ b/docs/environment-variables.md @@ -164,74 +164,5 @@ and outputs it to `rcmgr.json.gz` Default: disabled (not set) # Tracing -For advanced configuration (e.g. ratio-based sampling), see also: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/sdk-environment-variables.md -## `OTEL_TRACES_EXPORTER` -Specifies the exporters to use as a comma-separated string. Each exporter has a set of additional environment variables used to configure it. The following values are supported: - -- `otlp` -- `jaeger` -- `zipkin` -- `file` -- appends traces to a JSON file on the filesystem - -Setting this enables OpenTelemetry tracing. - -**NOTE** Tracing support is experimental: releases may contain tracing-related breaking changes. - -Default: "" (no exporters) - -## `OTLP Exporter` -Unless specified in this section, the OTLP exporter uses the environment variables documented here: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md - -### `OTEL_EXPORTER_OTLP_PROTOCOL` -Specifies the OTLP protocol to use, which is one of: - -- `grpc` -- `http/protobuf` - -Default: "grpc" - -## `Jaeger Exporter` - -See: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/sdk-environment-variables.md#jaeger-exporter - -## `Zipkin Exporter` -See: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/sdk-environment-variables.md#zipkin-exporter - -## `File Exporter` -### `OTEL_EXPORTER_FILE_PATH` -Specifies the filesystem path for the JSON file. - -Default: "$PWD/traces.json" - -### How to use Jaeger UI - -One can use the `jaegertracing/all-in-one` Docker image to run a full Jaeger -stack and configure Kubo to publish traces to it (here, in an ephemeral -container): - -```console -$ docker run --rm -it --name jaeger \ - -e COLLECTOR_ZIPKIN_HOST_PORT=:9411 \ - -p 5775:5775/udp \ - -p 6831:6831/udp \ - -p 6832:6832/udp \ - -p 5778:5778 \ - -p 16686:16686 \ - -p 14268:14268 \ - -p 14269:14269 \ - -p 14250:14250 \ - -p 9411:9411 \ - jaegertracing/all-in-one -``` - -Then, in other terminal, start Kubo with Jaeger tracing enabled: -``` -$ OTEL_TRACES_EXPORTER=jaeger ipfs daemon -``` - -Finally, the [Jaeger UI](https://github.com/jaegertracing/jaeger-ui#readme) is available at http://localhost:16686 - -## `OTEL_PROPAGATORS` - -See https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/sdk-environment-variables.md#general-sdk-configuration +For tracing configuration, please check: https://github.com/ipfs/boxo/blob/main/docs/tracing.md diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 1c2af1154..345f97f3f 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.18 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.8.0 + github.com/ipfs/boxo v0.8.1-0.20230411232920-5d6c73c8e35e github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.27.0 github.com/multiformats/go-multiaddr v0.9.0 diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 802f84be6..755f9aceb 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -321,8 +321,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.8.0 h1:UdjAJmHzQHo/j3g3b1bAcAXCj/GM6iTwvSlBDvPBNBs= -github.com/ipfs/boxo v0.8.0/go.mod h1:RIsi4CnTyQ7AUsNn5gXljJYZlQrHBMnJp94p73liFiA= +github.com/ipfs/boxo v0.8.1-0.20230411232920-5d6c73c8e35e h1:8wmBhjwJk2drWZjNwoN7uc+IkG+N93laIhjY69rjMqw= +github.com/ipfs/boxo v0.8.1-0.20230411232920-5d6c73c8e35e/go.mod h1:xJ2hVb4La5WyD7GvKYE0lq2g1rmQZoCD2K4WNrV6aZI= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= diff --git a/go.mod b/go.mod index 58d943ac5..115bd5749 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/gogo/protobuf v1.3.2 github.com/google/uuid v1.3.0 github.com/hashicorp/go-multierror v1.1.1 - github.com/ipfs/boxo v0.8.0 + github.com/ipfs/boxo v0.8.1-0.20230411232920-5d6c73c8e35e github.com/ipfs/go-block-format v0.1.2 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 @@ -75,11 +75,6 @@ require ( go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.40.0 go.opentelemetry.io/contrib/propagators/autoprop v0.40.0 go.opentelemetry.io/otel v1.14.0 - go.opentelemetry.io/otel/exporters/jaeger v1.14.0 - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.14.0 - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.14.0 - go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.14.0 - go.opentelemetry.io/otel/exporters/zipkin v1.14.0 go.opentelemetry.io/otel/sdk v1.14.0 go.opentelemetry.io/otel/trace v1.14.0 go.uber.org/dig v1.16.1 @@ -208,8 +203,13 @@ require ( go.opentelemetry.io/contrib/propagators/b3 v1.15.0 // indirect go.opentelemetry.io/contrib/propagators/jaeger v1.15.0 // indirect go.opentelemetry.io/contrib/propagators/ot v1.15.0 // indirect + go.opentelemetry.io/otel/exporters/jaeger v1.14.0 // indirect go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.14.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.14.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.14.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.14.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.14.0 // indirect + go.opentelemetry.io/otel/exporters/zipkin v1.14.0 // indirect go.opentelemetry.io/otel/metric v0.37.0 // indirect go.opentelemetry.io/proto/otlp v0.19.0 // indirect go.uber.org/atomic v1.10.0 // indirect diff --git a/go.sum b/go.sum index c623a9d4d..90cd6eb79 100644 --- a/go.sum +++ b/go.sum @@ -356,8 +356,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.8.0 h1:UdjAJmHzQHo/j3g3b1bAcAXCj/GM6iTwvSlBDvPBNBs= -github.com/ipfs/boxo v0.8.0/go.mod h1:RIsi4CnTyQ7AUsNn5gXljJYZlQrHBMnJp94p73liFiA= +github.com/ipfs/boxo v0.8.1-0.20230411232920-5d6c73c8e35e h1:8wmBhjwJk2drWZjNwoN7uc+IkG+N93laIhjY69rjMqw= +github.com/ipfs/boxo v0.8.1-0.20230411232920-5d6c73c8e35e/go.mod h1:xJ2hVb4La5WyD7GvKYE0lq2g1rmQZoCD2K4WNrV6aZI= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= diff --git a/tracing/file_exporter.go b/tracing/file_exporter.go deleted file mode 100644 index 32ca20ee2..000000000 --- a/tracing/file_exporter.go +++ /dev/null @@ -1,45 +0,0 @@ -package tracing - -import ( - "context" - "fmt" - "os" - - "go.opentelemetry.io/otel/exporters/stdout/stdouttrace" - "go.opentelemetry.io/otel/sdk/trace" -) - -// fileExporter wraps a file-writing exporter and closes the file when the exporter is shutdown. -type fileExporter struct { - file *os.File - writerExporter *stdouttrace.Exporter -} - -func newFileExporter(file string) (*fileExporter, error) { - f, err := os.OpenFile(file, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666) - if err != nil { - return nil, fmt.Errorf("opening '%s' for OpenTelemetry file exporter: %w", file, err) - } - stdoutExporter, err := stdouttrace.New(stdouttrace.WithWriter(f)) - if err != nil { - return nil, err - } - return &fileExporter{ - writerExporter: stdoutExporter, - file: f, - }, nil -} - -func (e *fileExporter) ExportSpans(ctx context.Context, spans []trace.ReadOnlySpan) error { - return e.writerExporter.ExportSpans(ctx, spans) -} - -func (e *fileExporter) Shutdown(ctx context.Context) error { - if err := e.writerExporter.Shutdown(ctx); err != nil { - return err - } - if err := e.file.Close(); err != nil { - return fmt.Errorf("closing trace file: %w", err) - } - return nil -} diff --git a/tracing/tracing.go b/tracing/tracing.go index b22930a6f..8fd898d7b 100644 --- a/tracing/tracing.go +++ b/tracing/tracing.go @@ -3,16 +3,10 @@ package tracing import ( "context" "fmt" - "os" - "path" - "strings" + "github.com/ipfs/boxo/tracing" version "github.com/ipfs/kubo" "go.opentelemetry.io/otel" - "go.opentelemetry.io/otel/exporters/jaeger" - "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc" - "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp" - "go.opentelemetry.io/otel/exporters/zipkin" "go.opentelemetry.io/otel/sdk/resource" "go.opentelemetry.io/otel/sdk/trace" semconv "go.opentelemetry.io/otel/semconv/v1.4.0" @@ -33,87 +27,9 @@ type noopShutdownTracerProvider struct{ traceapi.TracerProvider } func (n *noopShutdownTracerProvider) Shutdown(ctx context.Context) error { return nil } -func buildExporters(ctx context.Context) ([]trace.SpanExporter, error) { - // These env vars are standardized but not yet supported by opentelemetry-go. - // Once supported, we can remove most of this code. - // - // Specs: - // https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/sdk-environment-variables.md#exporter-selection - // https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md - var exporters []trace.SpanExporter - for _, exporterStr := range strings.Split(os.Getenv("OTEL_TRACES_EXPORTER"), ",") { - switch exporterStr { - case "otlp": - protocol := "http/protobuf" - if v := os.Getenv("OTEL_EXPORTER_OTLP_PROTOCOL"); v != "" { - protocol = v - } - if v := os.Getenv("OTEL_EXPORTER_OTLP_TRACES_PROTOCOL"); v != "" { - protocol = v - } - - switch protocol { - case "http/protobuf": - exporter, err := otlptracehttp.New(ctx) - if err != nil { - return nil, fmt.Errorf("building OTLP HTTP exporter: %w", err) - } - exporters = append(exporters, exporter) - case "grpc": - exporter, err := otlptracegrpc.New(ctx) - if err != nil { - return nil, fmt.Errorf("building OTLP gRPC exporter: %w", err) - } - exporters = append(exporters, exporter) - default: - return nil, fmt.Errorf("unknown or unsupported OTLP exporter '%s'", exporterStr) - } - case "jaeger": - exporter, err := jaeger.New(jaeger.WithCollectorEndpoint()) - if err != nil { - return nil, fmt.Errorf("building Jaeger exporter: %w", err) - } - exporters = append(exporters, exporter) - case "zipkin": - exporter, err := zipkin.New("") - if err != nil { - return nil, fmt.Errorf("building Zipkin exporter: %w", err) - } - exporters = append(exporters, exporter) - case "file": - // This is not part of the spec, but provided for convenience - // so that you don't have to setup a collector, - // and because we don't support the stdout exporter. - filePath := os.Getenv("OTEL_EXPORTER_FILE_PATH") - if filePath == "" { - cwd, err := os.Getwd() - if err != nil { - return nil, fmt.Errorf("finding working directory for the OpenTelemetry file exporter: %w", err) - } - filePath = path.Join(cwd, "traces.json") - } - exporter, err := newFileExporter(filePath) - if err != nil { - return nil, err - } - exporters = append(exporters, exporter) - case "none": - continue - case "": - continue - case "stdout": - // stdout is already used for certain kinds of logging, so we don't support this - fallthrough - default: - return nil, fmt.Errorf("unknown or unsupported exporter '%s'", exporterStr) - } - } - return exporters, nil -} - // NewTracerProvider creates and configures a TracerProvider. func NewTracerProvider(ctx context.Context) (shutdownTracerProvider, error) { - exporters, err := buildExporters(ctx) + exporters, err := tracing.NewSpanExporters(ctx) if err != nil { return nil, err } From 3a15a0fc550b1307cf54ef6ea5606fbe1bf72410 Mon Sep 17 00:00:00 2001 From: Gus Eggert Date: Wed, 12 Apr 2023 03:03:11 -0400 Subject: [PATCH 0629/1212] test: fix Docker tests in GH Actions (#9812) GH Actions recently changed their Docker build implementation and it has a different output than previously, causing the tests that parse its output to fail. This switches the test to not parse Docker build output. The parsing was used to extract the image ID while still showing logs. A better way to show logs and still know the image ID is to tag it, which is what this now does. This also renames the Docker tests so that they run earlier. This takes better advantage of the fact that the sharness tests are run in parallel. Since the Docker test are quite long, and are at the end of the list, the test runner is not running other tests in parallel while the Docker tests are running. --- test/ipfs-test-lib.sh | 12 ++++++------ ...300-docker-image.sh => t0002-docker-image.sh} | 16 +++++----------- ...docker-migrate.sh => t0003-docker-migrate.sh} | 9 ++++----- 3 files changed, 15 insertions(+), 22 deletions(-) rename test/sharness/{t0300-docker-image.sh => t0002-docker-image.sh} (87%) rename test/sharness/{t0301-docker-migrate.sh => t0003-docker-migrate.sh} (92%) diff --git a/test/ipfs-test-lib.sh b/test/ipfs-test-lib.sh index eabf17020..a3bc32bbb 100644 --- a/test/ipfs-test-lib.sh +++ b/test/ipfs-test-lib.sh @@ -50,19 +50,19 @@ test_path_cmp() { # Docker -# This takes a Dockerfile, and a build context directory +# This takes a Dockerfile, a tag name, and a build context directory docker_build() { - docker build --rm -f "$1" "$2" | ansi_strip + docker build --rm --tag "$1" --file "$2" "$3" | ansi_strip } # This takes an image as argument and writes a docker ID on stdout docker_run() { - docker run -d "$1" + docker run --detach "$1" } # This takes a docker ID and a command as arguments docker_exec() { - docker exec -t "$1" /bin/sh -c "$2" + docker exec --tty "$1" /bin/sh -c "$2" } # This takes a docker ID as argument @@ -72,12 +72,12 @@ docker_stop() { # This takes a docker ID as argument docker_rm() { - docker rm -f -v "$1" > /dev/null + docker rm --force --volumes "$1" > /dev/null } # This takes a docker image name as argument docker_rmi() { - docker rmi -f "$1" > /dev/null + docker rmi --force "$1" > /dev/null } # Test whether all the expected lines are included in a file. The file diff --git a/test/sharness/t0300-docker-image.sh b/test/sharness/t0002-docker-image.sh similarity index 87% rename from test/sharness/t0300-docker-image.sh rename to test/sharness/t0002-docker-image.sh index 3c390a453..11ccf01b7 100755 --- a/test/sharness/t0300-docker-image.sh +++ b/test/sharness/t0002-docker-image.sh @@ -27,18 +27,12 @@ TEST_TRASH_DIR=$(pwd) TEST_SCRIPTS_DIR=$(dirname "$TEST_TRASH_DIR") TEST_TESTS_DIR=$(dirname "$TEST_SCRIPTS_DIR") APP_ROOT_DIR=$(dirname "$TEST_TESTS_DIR") +IMAGE_TAG=kubo_test test_expect_success "docker image build succeeds" ' - docker_build "$TEST_TESTS_DIR/../Dockerfile" "$APP_ROOT_DIR" | tee build-actual || + docker_build "$IMAGE_TAG" "$TEST_TESTS_DIR/../Dockerfile" "$APP_ROOT_DIR" || test_fsh echo "TEST_TESTS_DIR: $TEST_TESTS_DIR" || - test_fsh echo "APP_ROOT_DIR : $APP_ROOT_DIR" || - test_fsh cat build-actual -' - -test_expect_success "docker image build output looks good" ' - SUCCESS_LINE=$(egrep "^Successfully built" build-actual) && - IMAGE_ID=$(expr "$SUCCESS_LINE" : "^Successfully built \(.*\)") || - test_fsh cat build-actual + test_fsh echo "APP_ROOT_DIR : $APP_ROOT_DIR" ' test_expect_success "write init scripts" ' @@ -52,7 +46,7 @@ test_expect_success "docker image runs" ' -p 127.0.0.1:5001:5001 -p 127.0.0.1:8080:8080 \ -v "$PWD/001.sh":/container-init.d/001.sh \ -v "$PWD/002.sh":/container-init.d/002.sh \ - "$IMAGE_ID") + "$IMAGE_TAG") ' test_expect_success "docker container gateway is up" ' @@ -100,5 +94,5 @@ test_expect_success "stop docker container" ' ' docker_rm "$DOC_ID" -docker_rmi "$IMAGE_ID" +docker_rmi "$IMAGE_TAG" test_done diff --git a/test/sharness/t0301-docker-migrate.sh b/test/sharness/t0003-docker-migrate.sh similarity index 92% rename from test/sharness/t0301-docker-migrate.sh rename to test/sharness/t0003-docker-migrate.sh index 3f7d32f21..ac3c7aee2 100755 --- a/test/sharness/t0301-docker-migrate.sh +++ b/test/sharness/t0003-docker-migrate.sh @@ -24,10 +24,10 @@ TEST_TRASH_DIR=$(pwd) TEST_SCRIPTS_DIR=$(dirname "$TEST_TRASH_DIR") TEST_TESTS_DIR=$(dirname "$TEST_SCRIPTS_DIR") APP_ROOT_DIR=$(dirname "$TEST_TESTS_DIR") +IMAGE_TAG=kubo_migrate test_expect_success "docker image build succeeds" ' - docker_build "$TEST_TESTS_DIR/../Dockerfile" "$APP_ROOT_DIR" >actual && - IMAGE_ID=$(tail -n1 actual | cut -d " " -f 3) + docker_build "$IMAGE_TAG" "$TEST_TESTS_DIR/../Dockerfile" "$APP_ROOT_DIR" ' test_init_ipfs @@ -53,7 +53,7 @@ test_expect_success "startup fake dists server" ' ' test_expect_success "docker image runs" ' - DOC_ID=$(docker run -d -v "$IPFS_PATH":/data/ipfs --net=host "$IMAGE_ID") + DOC_ID=$(docker run -d -v "$IPFS_PATH":/data/ipfs --net=host "$IMAGE_TAG") ' test_expect_success "docker container tries to pull migrations from netcat" ' @@ -78,6 +78,5 @@ test_expect_success "correct version was requested" ' ' docker_rm "$DOC_ID" -docker_rmi "$IMAGE_ID" +docker_rmi "$IMAGE_TAG" test_done - From 0d38c369fda56d19e7d8c023ca1d4595c5bd52dc Mon Sep 17 00:00:00 2001 From: Steve Loeppky Date: Thu, 13 Apr 2023 06:59:08 -0700 Subject: [PATCH 0630/1212] docs: preparing 0.20 changelog for release (#9799) Co-authored-by: Gus Eggert Co-authored-by: Marcin Rataj Co-authored-by: Henrique Dias --- docs/changelogs/v0.20.md | 98 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) diff --git a/docs/changelogs/v0.20.md b/docs/changelogs/v0.20.md index c1c3e9639..9809d4703 100644 --- a/docs/changelogs/v0.20.md +++ b/docs/changelogs/v0.20.md @@ -6,6 +6,13 @@ - [Overview](#overview) - [🔦 Highlights](#-highlights) + - [Boxo under the covers](#boxo-under-the-covers) + - [HTTP Gateway](#http-gateway) + - [Switch to `boxo/gateway` library](#switch-to-boxogateway-library) + - [Improved testing](#improved-testing) + - [Trace Context support](#trace-context-support) + - [Removed legacy features](#removed-legacy-features) + - [`--empty-repo` is now the default](#--empty-repo-is-now-the-default) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -13,6 +20,97 @@ ### 🔦 Highlights +#### Boxo under the covers +We have consolidated many IPFS repos into [Boxo](https://github.com/ipfs/boxo), and this release switches Kubo over to use Boxo instead of those repos, resulting in the removal of 27 dependencies from Kubo: + +- github.com/ipfs/go-bitswap +- github.com/ipfs/go-ipfs-files +- github.com/ipfs/tar-utils +- gihtub.com/ipfs/go-block-format +- github.com/ipfs/interface-go-ipfs-core +- github.com/ipfs/go-unixfs +- github.com/ipfs/go-pinning-service-http-client +- github.com/ipfs/go-path +- github.com/ipfs/go-namesys +- github.com/ipfs/go-mfs +- github.com/ipfs/go-ipfs-provider +- github.com/ipfs/go-ipfs-pinner +- github.com/ipfs/go-ipfs-keystore +- github.com/ipfs/go-filestore +- github.com/ipfs/go-ipns +- github.com/ipfs/go-blockservice +- github.com/ipfs/go-ipfs-chunker +- github.com/ipfs/go-fetcher +- github.com/ipfs/go-ipfs-blockstore +- github.com/ipfs/go-ipfs-posinfo +- github.com/ipfs/go-ipfs-util +- github.com/ipfs/go-ipfs-ds-help +- github.com/ipfs/go-verifcid +- github.com/ipfs/go-ipfs-exchange-offline +- github.com/ipfs/go-ipfs-routing +- github.com/ipfs/go-ipfs-exchange-interface +- github.com/ipfs/go-libipfs + +Note: if you consume these in your own code, we recommend migrating to Boxo. To ease this process, there's a [tool which will help migrate your code to Boxo](https://github.com/ipfs/boxo#migrating-to-box). + +You can learn more about the [Boxo 0.8 release](https://github.com/ipfs/boxo/releases/tag/v0.8.0) that Kubo now depends and the general effort to get Boxo to be a stable foundation [here](https://github.com/ipfs/boxo/issues/196). + +#### HTTP Gateway + +##### Switch to `boxo/gateway` library + +Gateway code was extracted and refactored into a standalone library that now +lives in [boxo/gateway](https://github.com/ipfs/boxo/tree/main/gateway). This +enabled us to clean up some legacy code and remove dependency on Kubo +internals. + +The GO API is still being refined, but now operates on higher level abstraction +defined by `gateway.IPFSBackend` interface. It is now possible to embed +gateway functionality without the rest of Kubo. + +See the [car](https://github.com/ipfs/boxo/tree/main/examples/gateway/car) +and [proxy](https://github.com/ipfs/boxo/tree/main/examples/gateway/proxy) +examples, or more advanced +[bifrost-gateway](https://github.com/ipfs/bifrost-gateway). + +##### Improved testing + +We are also in the progress of moving away from gateway testing being based on +Kubo sharness tests, and are working on +[ipfs/gateway-conformance](https://github.com/ipfs/gateway-conformance) test +suite that is vendor agnostic and can be run against arbitrary HTTP endpoint to +test specific subset of [HTTP Gateways specifications](https://specs.ipfs.tech/http-gateways/). + +##### Trace Context support + +We've introduced initial support for `traceparent` header from [W3C's Trace +Context spec](https://w3c.github.io/trace-context/). + +If `traceparent` header is +present in the gateway request, one can use its `trace-id` part to inspect +trace spans via selected exporter such as Jaeger UI +([docs](https://github.com/ipfs/boxo/blob/main/docs/tracing.md#using-jaeger-ui), +[demo](https://user-images.githubusercontent.com/157609/231312374-bafc2035-1fc6-4d6b-901b-9e4af039807c.png)). + +To learn more, see [tracing docs](https://github.com/ipfs/boxo/blob/main/docs/tracing.md). + +##### Removed legacy features + +- Some Kubo-specific prometheus metrics are no longer available. + - An up-to-date list of gateway metrics can be found in [boxo/gateway/metrics.go](https://github.com/ipfs/boxo/blob/main/gateway/metrics.go). +- The legacy opt-in `Gateway.Writable` is no longer available as of Kubo 0.20. + - We are working on developing a modern replacement. + To support our efforts, please leave a comment describing your use case in + [ipfs/specs#375](https://github.com/ipfs/specs/issues/375). + +#### `--empty-repo` is now the default + +When creating a repository with `ipfs init`, `--empty-repo=true` is now the default. This means +that your repository will be empty by default instead of containing the introduction files. +You can read more about the rationale behind this decision on the [tracking issue](https://github.com/ipfs/kubo/issues/9757). + ### 📝 Changelog ### 👨‍👩‍👧‍👦 Contributors + + From 78895a11848a9ddab05231b7cbde99b406f1a01c Mon Sep 17 00:00:00 2001 From: Marco Munizaga Date: Fri, 14 Apr 2023 02:09:51 -0700 Subject: [PATCH 0631/1212] deps: bump go-libp2p to v0.27.1 (#9816) Co-authored-by: Jorropo --- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 345f97f3f..e61559247 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -9,7 +9,7 @@ replace github.com/ipfs/kubo => ./../../.. require ( github.com/ipfs/boxo v0.8.1-0.20230411232920-5d6c73c8e35e github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 - github.com/libp2p/go-libp2p v0.27.0 + github.com/libp2p/go-libp2p v0.27.1 github.com/multiformats/go-multiaddr v0.9.0 ) diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 755f9aceb..643c6ace0 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -489,8 +489,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.27.0 h1:QbhrTuB0ln9j9op6yAOR0o+cx/qa9NyNZ5ov0Tql8ZU= -github.com/libp2p/go-libp2p v0.27.0/go.mod h1:FAvvfQa/YOShUYdiSS03IR9OXzkcJXwcNA2FUCh9ImE= +github.com/libp2p/go-libp2p v0.27.1 h1:k1u6RHsX3hqKnslDjsSgLNURxJ3O1atIZCY4gpMbbus= +github.com/libp2p/go-libp2p v0.27.1/go.mod h1:FAvvfQa/YOShUYdiSS03IR9OXzkcJXwcNA2FUCh9ImE= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= diff --git a/go.mod b/go.mod index 115bd5749..a7737edef 100644 --- a/go.mod +++ b/go.mod @@ -45,7 +45,7 @@ require ( github.com/jbenet/goprocess v0.1.4 github.com/julienschmidt/httprouter v1.3.0 github.com/libp2p/go-doh-resolver v0.4.0 - github.com/libp2p/go-libp2p v0.27.0 + github.com/libp2p/go-libp2p v0.27.1 github.com/libp2p/go-libp2p-http v0.5.0 github.com/libp2p/go-libp2p-kad-dht v0.23.0 github.com/libp2p/go-libp2p-kbucket v0.5.0 diff --git a/go.sum b/go.sum index 90cd6eb79..e060b4e25 100644 --- a/go.sum +++ b/go.sum @@ -540,8 +540,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.27.0 h1:QbhrTuB0ln9j9op6yAOR0o+cx/qa9NyNZ5ov0Tql8ZU= -github.com/libp2p/go-libp2p v0.27.0/go.mod h1:FAvvfQa/YOShUYdiSS03IR9OXzkcJXwcNA2FUCh9ImE= +github.com/libp2p/go-libp2p v0.27.1 h1:k1u6RHsX3hqKnslDjsSgLNURxJ3O1atIZCY4gpMbbus= +github.com/libp2p/go-libp2p v0.27.1/go.mod h1:FAvvfQa/YOShUYdiSS03IR9OXzkcJXwcNA2FUCh9ImE= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= From 8bebfc00b7192de63b79082bd2666d8d1bf76126 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Sun, 16 Apr 2023 12:31:09 +0200 Subject: [PATCH 0632/1212] chore: migrate from go-libipfs to boxo This commit was moved from ipfs/go-ipfs-http-client@ae996cbe5a91708d245100267c45094ab52c42ad --- client/httpapi/api.go | 4 ++-- client/httpapi/api_test.go | 7 +++---- client/httpapi/apifile.go | 6 +++--- client/httpapi/block.go | 6 +++--- client/httpapi/dag.go | 6 +++--- client/httpapi/dht.go | 4 ++-- client/httpapi/key.go | 6 +++--- client/httpapi/name.go | 8 ++++---- client/httpapi/object.go | 10 +++++----- client/httpapi/path.go | 4 ++-- client/httpapi/pin.go | 6 +++--- client/httpapi/pubsub.go | 4 ++-- client/httpapi/requestbuilder.go | 2 +- client/httpapi/response.go | 2 +- client/httpapi/swarm.go | 2 +- client/httpapi/unixfs.go | 12 ++++++------ 16 files changed, 44 insertions(+), 45 deletions(-) diff --git a/client/httpapi/api.go b/client/httpapi/api.go index 10df94603..b7cfb2b52 100644 --- a/client/httpapi/api.go +++ b/client/httpapi/api.go @@ -8,8 +8,8 @@ import ( "path/filepath" "strings" - iface "github.com/ipfs/interface-go-ipfs-core" - caopts "github.com/ipfs/interface-go-ipfs-core/options" + iface "github.com/ipfs/boxo/coreiface" + caopts "github.com/ipfs/boxo/coreiface/options" "github.com/mitchellh/go-homedir" ma "github.com/multiformats/go-multiaddr" manet "github.com/multiformats/go-multiaddr/net" diff --git a/client/httpapi/api_test.go b/client/httpapi/api_test.go index 5960ea2c0..2832d722d 100644 --- a/client/httpapi/api_test.go +++ b/client/httpapi/api_test.go @@ -12,10 +12,9 @@ import ( "testing" "time" - iface "github.com/ipfs/interface-go-ipfs-core" - "github.com/ipfs/interface-go-ipfs-core/path" - - "github.com/ipfs/interface-go-ipfs-core/tests" + iface "github.com/ipfs/boxo/coreiface" + "github.com/ipfs/boxo/coreiface/path" + "github.com/ipfs/boxo/coreiface/tests" local "github.com/ipfs/iptb-plugins/local" "github.com/ipfs/iptb/testbed" testbedi "github.com/ipfs/iptb/testbed/interfaces" diff --git a/client/httpapi/apifile.go b/client/httpapi/apifile.go index 80fd13cd4..25fd7c3b3 100644 --- a/client/httpapi/apifile.go +++ b/client/httpapi/apifile.go @@ -6,10 +6,10 @@ import ( "fmt" "io" + "github.com/ipfs/boxo/coreiface/path" + "github.com/ipfs/boxo/files" + unixfs "github.com/ipfs/boxo/ipld/unixfs" "github.com/ipfs/go-cid" - "github.com/ipfs/go-libipfs/files" - unixfs "github.com/ipfs/go-unixfs" - "github.com/ipfs/interface-go-ipfs-core/path" ) const forwardSeekLimit = 1 << 14 //16k diff --git a/client/httpapi/block.go b/client/httpapi/block.go index 7b4cf0eda..2a794c26f 100644 --- a/client/httpapi/block.go +++ b/client/httpapi/block.go @@ -6,10 +6,10 @@ import ( "fmt" "io" + iface "github.com/ipfs/boxo/coreiface" + caopts "github.com/ipfs/boxo/coreiface/options" + "github.com/ipfs/boxo/coreiface/path" "github.com/ipfs/go-cid" - iface "github.com/ipfs/interface-go-ipfs-core" - caopts "github.com/ipfs/interface-go-ipfs-core/options" - "github.com/ipfs/interface-go-ipfs-core/path" mc "github.com/multiformats/go-multicodec" mh "github.com/multiformats/go-multihash" ) diff --git a/client/httpapi/dag.go b/client/httpapi/dag.go index 2fbfea1ff..795e1d78d 100644 --- a/client/httpapi/dag.go +++ b/client/httpapi/dag.go @@ -6,11 +6,11 @@ import ( "fmt" "io" + "github.com/ipfs/boxo/coreiface/options" + "github.com/ipfs/boxo/coreiface/path" + "github.com/ipfs/go-block-format" "github.com/ipfs/go-cid" format "github.com/ipfs/go-ipld-format" - "github.com/ipfs/go-libipfs/blocks" - "github.com/ipfs/interface-go-ipfs-core/options" - "github.com/ipfs/interface-go-ipfs-core/path" multicodec "github.com/multiformats/go-multicodec" ) diff --git a/client/httpapi/dht.go b/client/httpapi/dht.go index ebecfcaeb..a2910fef6 100644 --- a/client/httpapi/dht.go +++ b/client/httpapi/dht.go @@ -4,8 +4,8 @@ import ( "context" "encoding/json" - caopts "github.com/ipfs/interface-go-ipfs-core/options" - "github.com/ipfs/interface-go-ipfs-core/path" + caopts "github.com/ipfs/boxo/coreiface/options" + "github.com/ipfs/boxo/coreiface/path" "github.com/libp2p/go-libp2p/core/peer" "github.com/libp2p/go-libp2p/core/routing" ) diff --git a/client/httpapi/key.go b/client/httpapi/key.go index b785bbf45..434e98fe5 100644 --- a/client/httpapi/key.go +++ b/client/httpapi/key.go @@ -4,9 +4,9 @@ import ( "context" "errors" - iface "github.com/ipfs/interface-go-ipfs-core" - caopts "github.com/ipfs/interface-go-ipfs-core/options" - "github.com/ipfs/interface-go-ipfs-core/path" + iface "github.com/ipfs/boxo/coreiface" + caopts "github.com/ipfs/boxo/coreiface/options" + "github.com/ipfs/boxo/coreiface/path" "github.com/libp2p/go-libp2p/core/peer" ) diff --git a/client/httpapi/name.go b/client/httpapi/name.go index b6a783603..f82f69f3a 100644 --- a/client/httpapi/name.go +++ b/client/httpapi/name.go @@ -6,10 +6,10 @@ import ( "fmt" "io" - iface "github.com/ipfs/interface-go-ipfs-core" - caopts "github.com/ipfs/interface-go-ipfs-core/options" - nsopts "github.com/ipfs/interface-go-ipfs-core/options/namesys" - "github.com/ipfs/interface-go-ipfs-core/path" + iface "github.com/ipfs/boxo/coreiface" + caopts "github.com/ipfs/boxo/coreiface/options" + nsopts "github.com/ipfs/boxo/coreiface/options/namesys" + "github.com/ipfs/boxo/coreiface/path" ) type NameAPI HttpApi diff --git a/client/httpapi/object.go b/client/httpapi/object.go index 894369223..4e3b9ef6b 100644 --- a/client/httpapi/object.go +++ b/client/httpapi/object.go @@ -6,13 +6,13 @@ import ( "fmt" "io" + iface "github.com/ipfs/boxo/coreiface" + caopts "github.com/ipfs/boxo/coreiface/options" + "github.com/ipfs/boxo/coreiface/path" + "github.com/ipfs/boxo/ipld/merkledag" + ft "github.com/ipfs/boxo/ipld/unixfs" "github.com/ipfs/go-cid" ipld "github.com/ipfs/go-ipld-format" - "github.com/ipfs/go-merkledag" - ft "github.com/ipfs/go-unixfs" - iface "github.com/ipfs/interface-go-ipfs-core" - caopts "github.com/ipfs/interface-go-ipfs-core/options" - "github.com/ipfs/interface-go-ipfs-core/path" ) type ObjectAPI HttpApi diff --git a/client/httpapi/path.go b/client/httpapi/path.go index 619dd0e0d..d69d425ab 100644 --- a/client/httpapi/path.go +++ b/client/httpapi/path.go @@ -3,10 +3,10 @@ package httpapi import ( "context" + "github.com/ipfs/boxo/coreiface/path" + ipfspath "github.com/ipfs/boxo/path" cid "github.com/ipfs/go-cid" ipld "github.com/ipfs/go-ipld-format" - ipfspath "github.com/ipfs/go-path" - "github.com/ipfs/interface-go-ipfs-core/path" ) func (api *HttpApi) ResolvePath(ctx context.Context, p path.Path) (path.Resolved, error) { diff --git a/client/httpapi/pin.go b/client/httpapi/pin.go index 13de2d389..30a3d7b7a 100644 --- a/client/httpapi/pin.go +++ b/client/httpapi/pin.go @@ -5,10 +5,10 @@ import ( "encoding/json" "strings" + iface "github.com/ipfs/boxo/coreiface" + caopts "github.com/ipfs/boxo/coreiface/options" + "github.com/ipfs/boxo/coreiface/path" "github.com/ipfs/go-cid" - iface "github.com/ipfs/interface-go-ipfs-core" - caopts "github.com/ipfs/interface-go-ipfs-core/options" - "github.com/ipfs/interface-go-ipfs-core/path" "github.com/pkg/errors" ) diff --git a/client/httpapi/pubsub.go b/client/httpapi/pubsub.go index ec45d1a51..28f1ef8e6 100644 --- a/client/httpapi/pubsub.go +++ b/client/httpapi/pubsub.go @@ -6,8 +6,8 @@ import ( "encoding/json" "io" - iface "github.com/ipfs/interface-go-ipfs-core" - caopts "github.com/ipfs/interface-go-ipfs-core/options" + iface "github.com/ipfs/boxo/coreiface" + caopts "github.com/ipfs/boxo/coreiface/options" "github.com/libp2p/go-libp2p/core/peer" mbase "github.com/multiformats/go-multibase" ) diff --git a/client/httpapi/requestbuilder.go b/client/httpapi/requestbuilder.go index bc6f4c8a9..476aed786 100644 --- a/client/httpapi/requestbuilder.go +++ b/client/httpapi/requestbuilder.go @@ -8,7 +8,7 @@ import ( "strconv" "strings" - "github.com/ipfs/go-libipfs/files" + "github.com/ipfs/boxo/files" ) type RequestBuilder interface { diff --git a/client/httpapi/response.go b/client/httpapi/response.go index 99932ca0d..189b43671 100644 --- a/client/httpapi/response.go +++ b/client/httpapi/response.go @@ -10,9 +10,9 @@ import ( "net/url" "os" + "github.com/ipfs/boxo/files" cmds "github.com/ipfs/go-ipfs-cmds" cmdhttp "github.com/ipfs/go-ipfs-cmds/http" - "github.com/ipfs/go-libipfs/files" ) type Error = cmds.Error diff --git a/client/httpapi/swarm.go b/client/httpapi/swarm.go index c5dfbe564..9b073078d 100644 --- a/client/httpapi/swarm.go +++ b/client/httpapi/swarm.go @@ -4,7 +4,7 @@ import ( "context" "time" - iface "github.com/ipfs/interface-go-ipfs-core" + iface "github.com/ipfs/boxo/coreiface" "github.com/libp2p/go-libp2p/core/network" "github.com/libp2p/go-libp2p/core/peer" "github.com/libp2p/go-libp2p/core/protocol" diff --git a/client/httpapi/unixfs.go b/client/httpapi/unixfs.go index 38f23d5b9..b9c34c59f 100644 --- a/client/httpapi/unixfs.go +++ b/client/httpapi/unixfs.go @@ -7,13 +7,13 @@ import ( "fmt" "io" + iface "github.com/ipfs/boxo/coreiface" + caopts "github.com/ipfs/boxo/coreiface/options" + "github.com/ipfs/boxo/coreiface/path" + "github.com/ipfs/boxo/files" + unixfs "github.com/ipfs/boxo/ipld/unixfs" + unixfs_pb "github.com/ipfs/boxo/ipld/unixfs/pb" "github.com/ipfs/go-cid" - "github.com/ipfs/go-libipfs/files" - unixfs "github.com/ipfs/go-unixfs" - unixfs_pb "github.com/ipfs/go-unixfs/pb" - iface "github.com/ipfs/interface-go-ipfs-core" - caopts "github.com/ipfs/interface-go-ipfs-core/options" - "github.com/ipfs/interface-go-ipfs-core/path" mh "github.com/multiformats/go-multihash" ) From f812f82574964322ee6a79ba76e4f2be25bb8edc Mon Sep 17 00:00:00 2001 From: Piotr Galar Date: Mon, 24 Apr 2023 09:44:27 +0200 Subject: [PATCH 0633/1212] ci: update apt before installing deps (#9831) --- .github/workflows/build.yml | 1 - .github/workflows/sharness.yml | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 50889613b..1f16d9bf3 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -148,7 +148,6 @@ jobs: with: repository: ipfs/go-ipfs-http-client path: go-ipfs-http-client - ref: bump-for-rcmgr-last-push - uses: protocol/cache-go-action@v1 with: name: ${{ github.job }} diff --git a/.github/workflows/sharness.yml b/.github/workflows/sharness.yml index 012a6a982..2d9dfb41d 100644 --- a/.github/workflows/sharness.yml +++ b/.github/workflows/sharness.yml @@ -32,7 +32,7 @@ jobs: with: path: kubo - name: Install missing tools - run: sudo apt install -y socat net-tools fish libxml2-utils + run: sudo apt update && sudo apt install -y socat net-tools fish libxml2-utils - name: Restore Go Cache uses: protocol/cache-go-action@v1 with: From 366546aae23bf4f673377b1e2a915bc71a177dfd Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Tue, 25 Apr 2023 09:55:40 +0200 Subject: [PATCH 0634/1212] docs: add `ipfs pubsub` deprecation reminder to changelog (#9827) --- docs/changelogs/v0.20.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/changelogs/v0.20.md b/docs/changelogs/v0.20.md index 9809d4703..590ef5453 100644 --- a/docs/changelogs/v0.20.md +++ b/docs/changelogs/v0.20.md @@ -13,6 +13,7 @@ - [Trace Context support](#trace-context-support) - [Removed legacy features](#removed-legacy-features) - [`--empty-repo` is now the default](#--empty-repo-is-now-the-default) + - [Reminder: `ipfs pubsub` commands and matching HTTP endpoints are deprecated and will be removed](#reminder-ipfs-pubsub-commands-and-matching-http-endpoints-are-deprecated-and-will-be-removed) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -109,6 +110,10 @@ When creating a repository with `ipfs init`, `--empty-repo=true` is now the defa that your repository will be empty by default instead of containing the introduction files. You can read more about the rationale behind this decision on the [tracking issue](https://github.com/ipfs/kubo/issues/9757). +#### Reminder: `ipfs pubsub` commands and matching HTTP endpoints are deprecated and will be removed + +`ipfs pubsub` commands and all `/api/v0/pubsub/` RPC endpoints and will be removed in the next release. For more information and rational see [#9717](https://github.com/ipfs/kubo/issues/9717). + ### 📝 Changelog ### 👨‍👩‍👧‍👦 Contributors From e4908a01633582e205b26ab36769830fe8490c10 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Tue, 25 Apr 2023 10:47:28 +0200 Subject: [PATCH 0635/1212] chore: bump to boxo 0.8.1 (#9836) --- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index e61559247..6eb1bcb5e 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.18 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.8.1-0.20230411232920-5d6c73c8e35e + github.com/ipfs/boxo v0.8.1 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.27.1 github.com/multiformats/go-multiaddr v0.9.0 diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 643c6ace0..2302548a9 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -321,8 +321,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.8.1-0.20230411232920-5d6c73c8e35e h1:8wmBhjwJk2drWZjNwoN7uc+IkG+N93laIhjY69rjMqw= -github.com/ipfs/boxo v0.8.1-0.20230411232920-5d6c73c8e35e/go.mod h1:xJ2hVb4La5WyD7GvKYE0lq2g1rmQZoCD2K4WNrV6aZI= +github.com/ipfs/boxo v0.8.1 h1:3DkKBCK+3rdEB5t77WDShUXXhktYwH99mkAsgajsKrU= +github.com/ipfs/boxo v0.8.1/go.mod h1:xJ2hVb4La5WyD7GvKYE0lq2g1rmQZoCD2K4WNrV6aZI= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= diff --git a/go.mod b/go.mod index a7737edef..b83143f9b 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/gogo/protobuf v1.3.2 github.com/google/uuid v1.3.0 github.com/hashicorp/go-multierror v1.1.1 - github.com/ipfs/boxo v0.8.1-0.20230411232920-5d6c73c8e35e + github.com/ipfs/boxo v0.8.1 github.com/ipfs/go-block-format v0.1.2 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 diff --git a/go.sum b/go.sum index e060b4e25..b00e5aed6 100644 --- a/go.sum +++ b/go.sum @@ -356,8 +356,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.8.1-0.20230411232920-5d6c73c8e35e h1:8wmBhjwJk2drWZjNwoN7uc+IkG+N93laIhjY69rjMqw= -github.com/ipfs/boxo v0.8.1-0.20230411232920-5d6c73c8e35e/go.mod h1:xJ2hVb4La5WyD7GvKYE0lq2g1rmQZoCD2K4WNrV6aZI= +github.com/ipfs/boxo v0.8.1 h1:3DkKBCK+3rdEB5t77WDShUXXhktYwH99mkAsgajsKrU= +github.com/ipfs/boxo v0.8.1/go.mod h1:xJ2hVb4La5WyD7GvKYE0lq2g1rmQZoCD2K4WNrV6aZI= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= From acb622fb1162bb53f43e9c82b636aa9cb02d5fec Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Tue, 25 Apr 2023 11:44:53 +0000 Subject: [PATCH 0636/1212] chore: update version --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index 850332654..7c1681bf0 100644 --- a/version.go +++ b/version.go @@ -11,7 +11,7 @@ import ( var CurrentCommit string // CurrentVersionNumber is the current application's version literal -const CurrentVersionNumber = "0.20.0-rc1" +const CurrentVersionNumber = "0.20.0-rc2" const ApiVersion = "/kubo/" + CurrentVersionNumber + "/" //nolint From e4fa9cb7ac7f8cc71144d21be476d5f9830578ef Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Wed, 12 Apr 2023 01:51:02 +0200 Subject: [PATCH 0637/1212] feat: boxo tracing and traceparent support (#9811) https://www.w3.org/TR/trace-context/ https://github.com/ipfs/bifrost-gateway/issues/68 --- docs/environment-variables.md | 71 +-------------------- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 +- go.mod | 12 ++-- go.sum | 4 +- tracing/file_exporter.go | 45 ------------- tracing/tracing.go | 88 +------------------------- 7 files changed, 14 insertions(+), 212 deletions(-) delete mode 100644 tracing/file_exporter.go diff --git a/docs/environment-variables.md b/docs/environment-variables.md index b3d03d1bd..4113be09b 100644 --- a/docs/environment-variables.md +++ b/docs/environment-variables.md @@ -164,74 +164,5 @@ and outputs it to `rcmgr.json.gz` Default: disabled (not set) # Tracing -For advanced configuration (e.g. ratio-based sampling), see also: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/sdk-environment-variables.md -## `OTEL_TRACES_EXPORTER` -Specifies the exporters to use as a comma-separated string. Each exporter has a set of additional environment variables used to configure it. The following values are supported: - -- `otlp` -- `jaeger` -- `zipkin` -- `file` -- appends traces to a JSON file on the filesystem - -Setting this enables OpenTelemetry tracing. - -**NOTE** Tracing support is experimental: releases may contain tracing-related breaking changes. - -Default: "" (no exporters) - -## `OTLP Exporter` -Unless specified in this section, the OTLP exporter uses the environment variables documented here: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md - -### `OTEL_EXPORTER_OTLP_PROTOCOL` -Specifies the OTLP protocol to use, which is one of: - -- `grpc` -- `http/protobuf` - -Default: "grpc" - -## `Jaeger Exporter` - -See: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/sdk-environment-variables.md#jaeger-exporter - -## `Zipkin Exporter` -See: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/sdk-environment-variables.md#zipkin-exporter - -## `File Exporter` -### `OTEL_EXPORTER_FILE_PATH` -Specifies the filesystem path for the JSON file. - -Default: "$PWD/traces.json" - -### How to use Jaeger UI - -One can use the `jaegertracing/all-in-one` Docker image to run a full Jaeger -stack and configure Kubo to publish traces to it (here, in an ephemeral -container): - -```console -$ docker run --rm -it --name jaeger \ - -e COLLECTOR_ZIPKIN_HOST_PORT=:9411 \ - -p 5775:5775/udp \ - -p 6831:6831/udp \ - -p 6832:6832/udp \ - -p 5778:5778 \ - -p 16686:16686 \ - -p 14268:14268 \ - -p 14269:14269 \ - -p 14250:14250 \ - -p 9411:9411 \ - jaegertracing/all-in-one -``` - -Then, in other terminal, start Kubo with Jaeger tracing enabled: -``` -$ OTEL_TRACES_EXPORTER=jaeger ipfs daemon -``` - -Finally, the [Jaeger UI](https://github.com/jaegertracing/jaeger-ui#readme) is available at http://localhost:16686 - -## `OTEL_PROPAGATORS` - -See https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/sdk-environment-variables.md#general-sdk-configuration +For tracing configuration, please check: https://github.com/ipfs/boxo/blob/main/docs/tracing.md diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 1c2af1154..345f97f3f 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.18 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.8.0 + github.com/ipfs/boxo v0.8.1-0.20230411232920-5d6c73c8e35e github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.27.0 github.com/multiformats/go-multiaddr v0.9.0 diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 802f84be6..755f9aceb 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -321,8 +321,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.8.0 h1:UdjAJmHzQHo/j3g3b1bAcAXCj/GM6iTwvSlBDvPBNBs= -github.com/ipfs/boxo v0.8.0/go.mod h1:RIsi4CnTyQ7AUsNn5gXljJYZlQrHBMnJp94p73liFiA= +github.com/ipfs/boxo v0.8.1-0.20230411232920-5d6c73c8e35e h1:8wmBhjwJk2drWZjNwoN7uc+IkG+N93laIhjY69rjMqw= +github.com/ipfs/boxo v0.8.1-0.20230411232920-5d6c73c8e35e/go.mod h1:xJ2hVb4La5WyD7GvKYE0lq2g1rmQZoCD2K4WNrV6aZI= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= diff --git a/go.mod b/go.mod index 58d943ac5..115bd5749 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/gogo/protobuf v1.3.2 github.com/google/uuid v1.3.0 github.com/hashicorp/go-multierror v1.1.1 - github.com/ipfs/boxo v0.8.0 + github.com/ipfs/boxo v0.8.1-0.20230411232920-5d6c73c8e35e github.com/ipfs/go-block-format v0.1.2 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 @@ -75,11 +75,6 @@ require ( go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.40.0 go.opentelemetry.io/contrib/propagators/autoprop v0.40.0 go.opentelemetry.io/otel v1.14.0 - go.opentelemetry.io/otel/exporters/jaeger v1.14.0 - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.14.0 - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.14.0 - go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.14.0 - go.opentelemetry.io/otel/exporters/zipkin v1.14.0 go.opentelemetry.io/otel/sdk v1.14.0 go.opentelemetry.io/otel/trace v1.14.0 go.uber.org/dig v1.16.1 @@ -208,8 +203,13 @@ require ( go.opentelemetry.io/contrib/propagators/b3 v1.15.0 // indirect go.opentelemetry.io/contrib/propagators/jaeger v1.15.0 // indirect go.opentelemetry.io/contrib/propagators/ot v1.15.0 // indirect + go.opentelemetry.io/otel/exporters/jaeger v1.14.0 // indirect go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.14.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.14.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.14.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.14.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.14.0 // indirect + go.opentelemetry.io/otel/exporters/zipkin v1.14.0 // indirect go.opentelemetry.io/otel/metric v0.37.0 // indirect go.opentelemetry.io/proto/otlp v0.19.0 // indirect go.uber.org/atomic v1.10.0 // indirect diff --git a/go.sum b/go.sum index c623a9d4d..90cd6eb79 100644 --- a/go.sum +++ b/go.sum @@ -356,8 +356,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.8.0 h1:UdjAJmHzQHo/j3g3b1bAcAXCj/GM6iTwvSlBDvPBNBs= -github.com/ipfs/boxo v0.8.0/go.mod h1:RIsi4CnTyQ7AUsNn5gXljJYZlQrHBMnJp94p73liFiA= +github.com/ipfs/boxo v0.8.1-0.20230411232920-5d6c73c8e35e h1:8wmBhjwJk2drWZjNwoN7uc+IkG+N93laIhjY69rjMqw= +github.com/ipfs/boxo v0.8.1-0.20230411232920-5d6c73c8e35e/go.mod h1:xJ2hVb4La5WyD7GvKYE0lq2g1rmQZoCD2K4WNrV6aZI= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= diff --git a/tracing/file_exporter.go b/tracing/file_exporter.go deleted file mode 100644 index 32ca20ee2..000000000 --- a/tracing/file_exporter.go +++ /dev/null @@ -1,45 +0,0 @@ -package tracing - -import ( - "context" - "fmt" - "os" - - "go.opentelemetry.io/otel/exporters/stdout/stdouttrace" - "go.opentelemetry.io/otel/sdk/trace" -) - -// fileExporter wraps a file-writing exporter and closes the file when the exporter is shutdown. -type fileExporter struct { - file *os.File - writerExporter *stdouttrace.Exporter -} - -func newFileExporter(file string) (*fileExporter, error) { - f, err := os.OpenFile(file, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666) - if err != nil { - return nil, fmt.Errorf("opening '%s' for OpenTelemetry file exporter: %w", file, err) - } - stdoutExporter, err := stdouttrace.New(stdouttrace.WithWriter(f)) - if err != nil { - return nil, err - } - return &fileExporter{ - writerExporter: stdoutExporter, - file: f, - }, nil -} - -func (e *fileExporter) ExportSpans(ctx context.Context, spans []trace.ReadOnlySpan) error { - return e.writerExporter.ExportSpans(ctx, spans) -} - -func (e *fileExporter) Shutdown(ctx context.Context) error { - if err := e.writerExporter.Shutdown(ctx); err != nil { - return err - } - if err := e.file.Close(); err != nil { - return fmt.Errorf("closing trace file: %w", err) - } - return nil -} diff --git a/tracing/tracing.go b/tracing/tracing.go index b22930a6f..8fd898d7b 100644 --- a/tracing/tracing.go +++ b/tracing/tracing.go @@ -3,16 +3,10 @@ package tracing import ( "context" "fmt" - "os" - "path" - "strings" + "github.com/ipfs/boxo/tracing" version "github.com/ipfs/kubo" "go.opentelemetry.io/otel" - "go.opentelemetry.io/otel/exporters/jaeger" - "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc" - "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp" - "go.opentelemetry.io/otel/exporters/zipkin" "go.opentelemetry.io/otel/sdk/resource" "go.opentelemetry.io/otel/sdk/trace" semconv "go.opentelemetry.io/otel/semconv/v1.4.0" @@ -33,87 +27,9 @@ type noopShutdownTracerProvider struct{ traceapi.TracerProvider } func (n *noopShutdownTracerProvider) Shutdown(ctx context.Context) error { return nil } -func buildExporters(ctx context.Context) ([]trace.SpanExporter, error) { - // These env vars are standardized but not yet supported by opentelemetry-go. - // Once supported, we can remove most of this code. - // - // Specs: - // https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/sdk-environment-variables.md#exporter-selection - // https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md - var exporters []trace.SpanExporter - for _, exporterStr := range strings.Split(os.Getenv("OTEL_TRACES_EXPORTER"), ",") { - switch exporterStr { - case "otlp": - protocol := "http/protobuf" - if v := os.Getenv("OTEL_EXPORTER_OTLP_PROTOCOL"); v != "" { - protocol = v - } - if v := os.Getenv("OTEL_EXPORTER_OTLP_TRACES_PROTOCOL"); v != "" { - protocol = v - } - - switch protocol { - case "http/protobuf": - exporter, err := otlptracehttp.New(ctx) - if err != nil { - return nil, fmt.Errorf("building OTLP HTTP exporter: %w", err) - } - exporters = append(exporters, exporter) - case "grpc": - exporter, err := otlptracegrpc.New(ctx) - if err != nil { - return nil, fmt.Errorf("building OTLP gRPC exporter: %w", err) - } - exporters = append(exporters, exporter) - default: - return nil, fmt.Errorf("unknown or unsupported OTLP exporter '%s'", exporterStr) - } - case "jaeger": - exporter, err := jaeger.New(jaeger.WithCollectorEndpoint()) - if err != nil { - return nil, fmt.Errorf("building Jaeger exporter: %w", err) - } - exporters = append(exporters, exporter) - case "zipkin": - exporter, err := zipkin.New("") - if err != nil { - return nil, fmt.Errorf("building Zipkin exporter: %w", err) - } - exporters = append(exporters, exporter) - case "file": - // This is not part of the spec, but provided for convenience - // so that you don't have to setup a collector, - // and because we don't support the stdout exporter. - filePath := os.Getenv("OTEL_EXPORTER_FILE_PATH") - if filePath == "" { - cwd, err := os.Getwd() - if err != nil { - return nil, fmt.Errorf("finding working directory for the OpenTelemetry file exporter: %w", err) - } - filePath = path.Join(cwd, "traces.json") - } - exporter, err := newFileExporter(filePath) - if err != nil { - return nil, err - } - exporters = append(exporters, exporter) - case "none": - continue - case "": - continue - case "stdout": - // stdout is already used for certain kinds of logging, so we don't support this - fallthrough - default: - return nil, fmt.Errorf("unknown or unsupported exporter '%s'", exporterStr) - } - } - return exporters, nil -} - // NewTracerProvider creates and configures a TracerProvider. func NewTracerProvider(ctx context.Context) (shutdownTracerProvider, error) { - exporters, err := buildExporters(ctx) + exporters, err := tracing.NewSpanExporters(ctx) if err != nil { return nil, err } From b706d644875108786ab44d76833a902daab3b5e2 Mon Sep 17 00:00:00 2001 From: Steve Loeppky Date: Thu, 13 Apr 2023 06:59:08 -0700 Subject: [PATCH 0638/1212] docs: preparing 0.20 changelog for release (#9799) Co-authored-by: Gus Eggert Co-authored-by: Marcin Rataj Co-authored-by: Henrique Dias --- docs/changelogs/v0.20.md | 98 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) diff --git a/docs/changelogs/v0.20.md b/docs/changelogs/v0.20.md index c1c3e9639..9809d4703 100644 --- a/docs/changelogs/v0.20.md +++ b/docs/changelogs/v0.20.md @@ -6,6 +6,13 @@ - [Overview](#overview) - [🔦 Highlights](#-highlights) + - [Boxo under the covers](#boxo-under-the-covers) + - [HTTP Gateway](#http-gateway) + - [Switch to `boxo/gateway` library](#switch-to-boxogateway-library) + - [Improved testing](#improved-testing) + - [Trace Context support](#trace-context-support) + - [Removed legacy features](#removed-legacy-features) + - [`--empty-repo` is now the default](#--empty-repo-is-now-the-default) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -13,6 +20,97 @@ ### 🔦 Highlights +#### Boxo under the covers +We have consolidated many IPFS repos into [Boxo](https://github.com/ipfs/boxo), and this release switches Kubo over to use Boxo instead of those repos, resulting in the removal of 27 dependencies from Kubo: + +- github.com/ipfs/go-bitswap +- github.com/ipfs/go-ipfs-files +- github.com/ipfs/tar-utils +- gihtub.com/ipfs/go-block-format +- github.com/ipfs/interface-go-ipfs-core +- github.com/ipfs/go-unixfs +- github.com/ipfs/go-pinning-service-http-client +- github.com/ipfs/go-path +- github.com/ipfs/go-namesys +- github.com/ipfs/go-mfs +- github.com/ipfs/go-ipfs-provider +- github.com/ipfs/go-ipfs-pinner +- github.com/ipfs/go-ipfs-keystore +- github.com/ipfs/go-filestore +- github.com/ipfs/go-ipns +- github.com/ipfs/go-blockservice +- github.com/ipfs/go-ipfs-chunker +- github.com/ipfs/go-fetcher +- github.com/ipfs/go-ipfs-blockstore +- github.com/ipfs/go-ipfs-posinfo +- github.com/ipfs/go-ipfs-util +- github.com/ipfs/go-ipfs-ds-help +- github.com/ipfs/go-verifcid +- github.com/ipfs/go-ipfs-exchange-offline +- github.com/ipfs/go-ipfs-routing +- github.com/ipfs/go-ipfs-exchange-interface +- github.com/ipfs/go-libipfs + +Note: if you consume these in your own code, we recommend migrating to Boxo. To ease this process, there's a [tool which will help migrate your code to Boxo](https://github.com/ipfs/boxo#migrating-to-box). + +You can learn more about the [Boxo 0.8 release](https://github.com/ipfs/boxo/releases/tag/v0.8.0) that Kubo now depends and the general effort to get Boxo to be a stable foundation [here](https://github.com/ipfs/boxo/issues/196). + +#### HTTP Gateway + +##### Switch to `boxo/gateway` library + +Gateway code was extracted and refactored into a standalone library that now +lives in [boxo/gateway](https://github.com/ipfs/boxo/tree/main/gateway). This +enabled us to clean up some legacy code and remove dependency on Kubo +internals. + +The GO API is still being refined, but now operates on higher level abstraction +defined by `gateway.IPFSBackend` interface. It is now possible to embed +gateway functionality without the rest of Kubo. + +See the [car](https://github.com/ipfs/boxo/tree/main/examples/gateway/car) +and [proxy](https://github.com/ipfs/boxo/tree/main/examples/gateway/proxy) +examples, or more advanced +[bifrost-gateway](https://github.com/ipfs/bifrost-gateway). + +##### Improved testing + +We are also in the progress of moving away from gateway testing being based on +Kubo sharness tests, and are working on +[ipfs/gateway-conformance](https://github.com/ipfs/gateway-conformance) test +suite that is vendor agnostic and can be run against arbitrary HTTP endpoint to +test specific subset of [HTTP Gateways specifications](https://specs.ipfs.tech/http-gateways/). + +##### Trace Context support + +We've introduced initial support for `traceparent` header from [W3C's Trace +Context spec](https://w3c.github.io/trace-context/). + +If `traceparent` header is +present in the gateway request, one can use its `trace-id` part to inspect +trace spans via selected exporter such as Jaeger UI +([docs](https://github.com/ipfs/boxo/blob/main/docs/tracing.md#using-jaeger-ui), +[demo](https://user-images.githubusercontent.com/157609/231312374-bafc2035-1fc6-4d6b-901b-9e4af039807c.png)). + +To learn more, see [tracing docs](https://github.com/ipfs/boxo/blob/main/docs/tracing.md). + +##### Removed legacy features + +- Some Kubo-specific prometheus metrics are no longer available. + - An up-to-date list of gateway metrics can be found in [boxo/gateway/metrics.go](https://github.com/ipfs/boxo/blob/main/gateway/metrics.go). +- The legacy opt-in `Gateway.Writable` is no longer available as of Kubo 0.20. + - We are working on developing a modern replacement. + To support our efforts, please leave a comment describing your use case in + [ipfs/specs#375](https://github.com/ipfs/specs/issues/375). + +#### `--empty-repo` is now the default + +When creating a repository with `ipfs init`, `--empty-repo=true` is now the default. This means +that your repository will be empty by default instead of containing the introduction files. +You can read more about the rationale behind this decision on the [tracking issue](https://github.com/ipfs/kubo/issues/9757). + ### 📝 Changelog ### 👨‍👩‍👧‍👦 Contributors + + From 4f438e6d4efb06f8b956b9d32736cdf0d4f70e0c Mon Sep 17 00:00:00 2001 From: Marco Munizaga Date: Fri, 14 Apr 2023 02:09:51 -0700 Subject: [PATCH 0639/1212] deps: bump go-libp2p to v0.27.1 (#9816) Co-authored-by: Jorropo --- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 345f97f3f..e61559247 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -9,7 +9,7 @@ replace github.com/ipfs/kubo => ./../../.. require ( github.com/ipfs/boxo v0.8.1-0.20230411232920-5d6c73c8e35e github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 - github.com/libp2p/go-libp2p v0.27.0 + github.com/libp2p/go-libp2p v0.27.1 github.com/multiformats/go-multiaddr v0.9.0 ) diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 755f9aceb..643c6ace0 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -489,8 +489,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.27.0 h1:QbhrTuB0ln9j9op6yAOR0o+cx/qa9NyNZ5ov0Tql8ZU= -github.com/libp2p/go-libp2p v0.27.0/go.mod h1:FAvvfQa/YOShUYdiSS03IR9OXzkcJXwcNA2FUCh9ImE= +github.com/libp2p/go-libp2p v0.27.1 h1:k1u6RHsX3hqKnslDjsSgLNURxJ3O1atIZCY4gpMbbus= +github.com/libp2p/go-libp2p v0.27.1/go.mod h1:FAvvfQa/YOShUYdiSS03IR9OXzkcJXwcNA2FUCh9ImE= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= diff --git a/go.mod b/go.mod index 115bd5749..a7737edef 100644 --- a/go.mod +++ b/go.mod @@ -45,7 +45,7 @@ require ( github.com/jbenet/goprocess v0.1.4 github.com/julienschmidt/httprouter v1.3.0 github.com/libp2p/go-doh-resolver v0.4.0 - github.com/libp2p/go-libp2p v0.27.0 + github.com/libp2p/go-libp2p v0.27.1 github.com/libp2p/go-libp2p-http v0.5.0 github.com/libp2p/go-libp2p-kad-dht v0.23.0 github.com/libp2p/go-libp2p-kbucket v0.5.0 diff --git a/go.sum b/go.sum index 90cd6eb79..e060b4e25 100644 --- a/go.sum +++ b/go.sum @@ -540,8 +540,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.27.0 h1:QbhrTuB0ln9j9op6yAOR0o+cx/qa9NyNZ5ov0Tql8ZU= -github.com/libp2p/go-libp2p v0.27.0/go.mod h1:FAvvfQa/YOShUYdiSS03IR9OXzkcJXwcNA2FUCh9ImE= +github.com/libp2p/go-libp2p v0.27.1 h1:k1u6RHsX3hqKnslDjsSgLNURxJ3O1atIZCY4gpMbbus= +github.com/libp2p/go-libp2p v0.27.1/go.mod h1:FAvvfQa/YOShUYdiSS03IR9OXzkcJXwcNA2FUCh9ImE= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= From 656867b81c7ecdc47e835714d5073937ecfb6fd6 Mon Sep 17 00:00:00 2001 From: Piotr Galar Date: Mon, 24 Apr 2023 09:44:27 +0200 Subject: [PATCH 0640/1212] ci: update apt before installing deps (#9831) --- .github/workflows/build.yml | 1 - .github/workflows/sharness.yml | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 50889613b..1f16d9bf3 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -148,7 +148,6 @@ jobs: with: repository: ipfs/go-ipfs-http-client path: go-ipfs-http-client - ref: bump-for-rcmgr-last-push - uses: protocol/cache-go-action@v1 with: name: ${{ github.job }} diff --git a/.github/workflows/sharness.yml b/.github/workflows/sharness.yml index 012a6a982..2d9dfb41d 100644 --- a/.github/workflows/sharness.yml +++ b/.github/workflows/sharness.yml @@ -32,7 +32,7 @@ jobs: with: path: kubo - name: Install missing tools - run: sudo apt install -y socat net-tools fish libxml2-utils + run: sudo apt update && sudo apt install -y socat net-tools fish libxml2-utils - name: Restore Go Cache uses: protocol/cache-go-action@v1 with: From 7ea0b0703816473460614d1705b9c8cc9f12e052 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Tue, 25 Apr 2023 09:55:40 +0200 Subject: [PATCH 0641/1212] docs: add `ipfs pubsub` deprecation reminder to changelog (#9827) --- docs/changelogs/v0.20.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/changelogs/v0.20.md b/docs/changelogs/v0.20.md index 9809d4703..590ef5453 100644 --- a/docs/changelogs/v0.20.md +++ b/docs/changelogs/v0.20.md @@ -13,6 +13,7 @@ - [Trace Context support](#trace-context-support) - [Removed legacy features](#removed-legacy-features) - [`--empty-repo` is now the default](#--empty-repo-is-now-the-default) + - [Reminder: `ipfs pubsub` commands and matching HTTP endpoints are deprecated and will be removed](#reminder-ipfs-pubsub-commands-and-matching-http-endpoints-are-deprecated-and-will-be-removed) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -109,6 +110,10 @@ When creating a repository with `ipfs init`, `--empty-repo=true` is now the defa that your repository will be empty by default instead of containing the introduction files. You can read more about the rationale behind this decision on the [tracking issue](https://github.com/ipfs/kubo/issues/9757). +#### Reminder: `ipfs pubsub` commands and matching HTTP endpoints are deprecated and will be removed + +`ipfs pubsub` commands and all `/api/v0/pubsub/` RPC endpoints and will be removed in the next release. For more information and rational see [#9717](https://github.com/ipfs/kubo/issues/9717). + ### 📝 Changelog ### 👨‍👩‍👧‍👦 Contributors From 8418b083d8fa0db0f8a2ad0fb99a45eed9f38406 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Tue, 25 Apr 2023 10:47:28 +0200 Subject: [PATCH 0642/1212] chore: bump to boxo 0.8.1 (#9836) --- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index e61559247..6eb1bcb5e 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.18 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.8.1-0.20230411232920-5d6c73c8e35e + github.com/ipfs/boxo v0.8.1 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.27.1 github.com/multiformats/go-multiaddr v0.9.0 diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 643c6ace0..2302548a9 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -321,8 +321,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.8.1-0.20230411232920-5d6c73c8e35e h1:8wmBhjwJk2drWZjNwoN7uc+IkG+N93laIhjY69rjMqw= -github.com/ipfs/boxo v0.8.1-0.20230411232920-5d6c73c8e35e/go.mod h1:xJ2hVb4La5WyD7GvKYE0lq2g1rmQZoCD2K4WNrV6aZI= +github.com/ipfs/boxo v0.8.1 h1:3DkKBCK+3rdEB5t77WDShUXXhktYwH99mkAsgajsKrU= +github.com/ipfs/boxo v0.8.1/go.mod h1:xJ2hVb4La5WyD7GvKYE0lq2g1rmQZoCD2K4WNrV6aZI= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= diff --git a/go.mod b/go.mod index a7737edef..b83143f9b 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/gogo/protobuf v1.3.2 github.com/google/uuid v1.3.0 github.com/hashicorp/go-multierror v1.1.1 - github.com/ipfs/boxo v0.8.1-0.20230411232920-5d6c73c8e35e + github.com/ipfs/boxo v0.8.1 github.com/ipfs/go-block-format v0.1.2 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 diff --git a/go.sum b/go.sum index e060b4e25..b00e5aed6 100644 --- a/go.sum +++ b/go.sum @@ -356,8 +356,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.8.1-0.20230411232920-5d6c73c8e35e h1:8wmBhjwJk2drWZjNwoN7uc+IkG+N93laIhjY69rjMqw= -github.com/ipfs/boxo v0.8.1-0.20230411232920-5d6c73c8e35e/go.mod h1:xJ2hVb4La5WyD7GvKYE0lq2g1rmQZoCD2K4WNrV6aZI= +github.com/ipfs/boxo v0.8.1 h1:3DkKBCK+3rdEB5t77WDShUXXhktYwH99mkAsgajsKrU= +github.com/ipfs/boxo v0.8.1/go.mod h1:xJ2hVb4La5WyD7GvKYE0lq2g1rmQZoCD2K4WNrV6aZI= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= From 4ca36c41b63f2ad62ebc0e5d7d207c9ad4816d94 Mon Sep 17 00:00:00 2001 From: Gus Eggert Date: Mon, 1 May 2023 15:29:34 -0400 Subject: [PATCH 0643/1212] fix: use default HTTP routers when FullRT DHT client is used (#9841) --- cmd/ipfs/daemon.go | 14 ++------- core/node/groups.go | 2 +- core/node/libp2p/routing.go | 47 ++++++++++++++++++----------- core/node/libp2p/routingopt.go | 55 ++++++++++++++++++++-------------- 4 files changed, 65 insertions(+), 53 deletions(-) diff --git a/cmd/ipfs/daemon.go b/cmd/ipfs/daemon.go index ffcb30a34..1e03a8264 100644 --- a/cmd/ipfs/daemon.go +++ b/cmd/ipfs/daemon.go @@ -413,19 +413,9 @@ func daemonFunc(req *cmds.Request, re cmds.ResponseEmitter, env cmds.Environment case routingOptionSupernodeKwd: return errors.New("supernode routing was never fully implemented and has been removed") case routingOptionDefaultKwd, routingOptionAutoKwd: - ncfg.Routing = libp2p.ConstructDefaultRouting( - cfg.Identity.PeerID, - cfg.Addresses.Swarm, - cfg.Identity.PrivKey, - libp2p.DHTOption, - ) + ncfg.Routing = libp2p.ConstructDefaultRouting(cfg, libp2p.DHTOption) case routingOptionAutoClientKwd: - ncfg.Routing = libp2p.ConstructDefaultRouting( - cfg.Identity.PeerID, - cfg.Addresses.Swarm, - cfg.Identity.PrivKey, - libp2p.DHTClientOption, - ) + ncfg.Routing = libp2p.ConstructDefaultRouting(cfg, libp2p.DHTClientOption) case routingOptionDHTClientKwd: ncfg.Routing = libp2p.DHTClientOption case routingOptionDHTKwd: diff --git a/core/node/groups.go b/core/node/groups.go index 0b1660265..ae8ce8539 100644 --- a/core/node/groups.go +++ b/core/node/groups.go @@ -165,7 +165,7 @@ func LibP2P(bcfg *BuildCfg, cfg *config.Config, userResourceOverrides rcmgr.Part fx.Provide(libp2p.Routing), fx.Provide(libp2p.ContentRouting), - fx.Provide(libp2p.BaseRouting(cfg.Experimental.AcceleratedDHTClient)), + fx.Provide(libp2p.BaseRouting(cfg)), maybeProvide(libp2p.PubsubRouter, bcfg.getOpt("ipnsps")), maybeProvide(libp2p.BandwidthCounter, !cfg.Swarm.DisableBandwidthMetrics), diff --git a/core/node/libp2p/routing.go b/core/node/libp2p/routing.go index f96f772e1..2e356e447 100644 --- a/core/node/libp2p/routing.go +++ b/core/node/libp2p/routing.go @@ -63,35 +63,34 @@ type processInitialRoutingOut struct { type AddrInfoChan chan peer.AddrInfo -func BaseRouting(experimentalDHTClient bool) interface{} { +func BaseRouting(cfg *config.Config) interface{} { return func(lc fx.Lifecycle, in processInitialRoutingIn) (out processInitialRoutingOut, err error) { - var dr *ddht.DHT + var dualDHT *ddht.DHT if dht, ok := in.Router.(*ddht.DHT); ok { - dr = dht + dualDHT = dht lc.Append(fx.Hook{ OnStop: func(ctx context.Context) error { - return dr.Close() + return dualDHT.Close() }, }) } - if pr, ok := in.Router.(routinghelpers.ComposableRouter); ok { - for _, r := range pr.Routers() { + if cr, ok := in.Router.(routinghelpers.ComposableRouter); ok { + for _, r := range cr.Routers() { if dht, ok := r.(*ddht.DHT); ok { - dr = dht + dualDHT = dht lc.Append(fx.Hook{ OnStop: func(ctx context.Context) error { - return dr.Close() + return dualDHT.Close() }, }) - break } } } - if dr != nil && experimentalDHTClient { + if dualDHT != nil && cfg.Experimental.AcceleratedDHTClient { cfg, err := in.Repo.Config() if err != nil { return out, err @@ -101,7 +100,7 @@ func BaseRouting(experimentalDHTClient bool) interface{} { return out, err } - expClient, err := fullrt.NewFullRT(in.Host, + fullRTClient, err := fullrt.NewFullRT(in.Host, dht.DefaultPrefix, fullrt.DHTOption( dht.Validator(in.Validator), @@ -116,18 +115,30 @@ func BaseRouting(experimentalDHTClient bool) interface{} { lc.Append(fx.Hook{ OnStop: func(ctx context.Context) error { - return expClient.Close() + return fullRTClient.Close() }, }) + // we want to also use the default HTTP routers, so wrap the FullRT client + // in a parallel router that calls them in parallel + httpRouters, err := constructDefaultHTTPRouters(cfg) + if err != nil { + return out, err + } + routers := []*routinghelpers.ParallelRouter{ + {Router: fullRTClient}, + } + routers = append(routers, httpRouters...) + router := routinghelpers.NewComposableParallel(routers) + return processInitialRoutingOut{ Router: Router{ - Routing: expClient, Priority: 1000, + Routing: router, }, - DHT: dr, - DHTClient: expClient, - ContentRouter: expClient, + DHT: dualDHT, + DHTClient: fullRTClient, + ContentRouter: fullRTClient, }, nil } @@ -136,8 +147,8 @@ func BaseRouting(experimentalDHTClient bool) interface{} { Priority: 1000, Routing: in.Router, }, - DHT: dr, - DHTClient: dr, + DHT: dualDHT, + DHTClient: dualDHT, ContentRouter: in.Router, }, nil } diff --git a/core/node/libp2p/routingopt.go b/core/node/libp2p/routingopt.go index 1d47ae273..b363f25b7 100644 --- a/core/node/libp2p/routingopt.go +++ b/core/node/libp2p/routingopt.go @@ -43,8 +43,35 @@ func init() { } } +func constructDefaultHTTPRouters(cfg *config.Config) ([]*routinghelpers.ParallelRouter, error) { + var routers []*routinghelpers.ParallelRouter + // Append HTTP routers for additional speed + for _, endpoint := range defaultHTTPRouters { + httpRouter, err := irouting.ConstructHTTPRouter(endpoint, cfg.Identity.PeerID, cfg.Addresses.Swarm, cfg.Identity.PrivKey) + if err != nil { + return nil, err + } + + r := &irouting.Composer{ + GetValueRouter: routinghelpers.Null{}, + PutValueRouter: routinghelpers.Null{}, + ProvideRouter: routinghelpers.Null{}, // modify this when indexers supports provide + FindPeersRouter: routinghelpers.Null{}, + FindProvidersRouter: httpRouter, + } + + routers = append(routers, &routinghelpers.ParallelRouter{ + Router: r, + IgnoreError: true, // https://github.com/ipfs/kubo/pull/9475#discussion_r1042507387 + Timeout: 15 * time.Second, // 5x server value from https://github.com/ipfs/kubo/pull/9475#discussion_r1042428529 + ExecuteAfter: 0, + }) + } + return routers, nil +} + // ConstructDefaultRouting returns routers used when Routing.Type is unset or set to "auto" -func ConstructDefaultRouting(peerID string, addrs []string, privKey string, routingOpt RoutingOption) RoutingOption { +func ConstructDefaultRouting(cfg *config.Config, routingOpt RoutingOption) RoutingOption { return func(args RoutingOptionArgs) (routing.Routing, error) { // Defined routers will be queried in parallel (optimizing for response speed) // Different trade-offs can be made by setting Routing.Type = "custom" with own Routing.Routers @@ -60,29 +87,13 @@ func ConstructDefaultRouting(peerID string, addrs []string, privKey string, rout ExecuteAfter: 0, }) - // Append HTTP routers for additional speed - for _, endpoint := range defaultHTTPRouters { - httpRouter, err := irouting.ConstructHTTPRouter(endpoint, peerID, addrs, privKey) - if err != nil { - return nil, err - } - - r := &irouting.Composer{ - GetValueRouter: routinghelpers.Null{}, - PutValueRouter: routinghelpers.Null{}, - ProvideRouter: routinghelpers.Null{}, // modify this when indexers supports provide - FindPeersRouter: routinghelpers.Null{}, - FindProvidersRouter: httpRouter, - } - - routers = append(routers, &routinghelpers.ParallelRouter{ - Router: r, - IgnoreError: true, // https://github.com/ipfs/kubo/pull/9475#discussion_r1042507387 - Timeout: 15 * time.Second, // 5x server value from https://github.com/ipfs/kubo/pull/9475#discussion_r1042428529 - ExecuteAfter: 0, - }) + httpRouters, err := constructDefaultHTTPRouters(cfg) + if err != nil { + return nil, err } + routers = append(routers, httpRouters...) + routing := routinghelpers.NewComposableParallel(routers) return routing, nil } From 53821c202f14df2116459ba8729d61248342e15a Mon Sep 17 00:00:00 2001 From: Russell Dempsey <1173416+SgtPooki@users.noreply.github.com> Date: Tue, 2 May 2023 04:16:52 -0700 Subject: [PATCH 0644/1212] feat: webui@3.0.0 (#9835) --- core/corehttp/webui.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/corehttp/webui.go b/core/corehttp/webui.go index f7b27c939..9b7cf776d 100644 --- a/core/corehttp/webui.go +++ b/core/corehttp/webui.go @@ -1,11 +1,12 @@ package corehttp // TODO: move to IPNS -const WebUIPath = "/ipfs/bafybeifeqt7mvxaniphyu2i3qhovjaf3sayooxbh5enfdqtiehxjv2ldte" // v2.22.0 +const WebUIPath = "/ipfs/bafybeic4gops3d3lyrisqku37uio33nvt6fqxvkxihrwlqsuvf76yln4fm" // v3.0.0 // WebUIPaths is a list of all past webUI paths. var WebUIPaths = []string{ WebUIPath, + "/ipfs/bafybeifeqt7mvxaniphyu2i3qhovjaf3sayooxbh5enfdqtiehxjv2ldte", "/ipfs/bafybeiequgo72mrvuml56j4gk7crewig5bavumrrzhkqbim6b3s2yqi7ty", "/ipfs/bafybeibjbq3tmmy7wuihhhwvbladjsd3gx3kfjepxzkq6wylik6wc3whzy", "/ipfs/bafybeiavrvt53fks6u32n5p2morgblcmck4bh4ymf4rrwu7ah5zsykmqqa", From 97169169edd8837695ce167f2a8be4f2a1111648 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Wed, 3 May 2023 06:27:11 +0000 Subject: [PATCH 0645/1212] chore: update version --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index 52c34a408..4a515f82c 100644 --- a/version.go +++ b/version.go @@ -11,7 +11,7 @@ import ( var CurrentCommit string // CurrentVersionNumber is the current application's version literal -const CurrentVersionNumber = "0.19.1" +const CurrentVersionNumber = "0.19.2" const ApiVersion = "/kubo/" + CurrentVersionNumber + "/" //nolint From ecf20f540b25905dc0a5b1505f72238de704bba2 Mon Sep 17 00:00:00 2001 From: Gus Eggert Date: Mon, 1 May 2023 15:29:34 -0400 Subject: [PATCH 0646/1212] fix: use default HTTP routers when FullRT DHT client is used (#9841) --- cmd/ipfs/daemon.go | 14 ++------- core/node/groups.go | 2 +- core/node/libp2p/routing.go | 47 ++++++++++++++++++----------- core/node/libp2p/routingopt.go | 55 ++++++++++++++++++++-------------- 4 files changed, 65 insertions(+), 53 deletions(-) diff --git a/cmd/ipfs/daemon.go b/cmd/ipfs/daemon.go index 52addcc07..2964716a3 100644 --- a/cmd/ipfs/daemon.go +++ b/cmd/ipfs/daemon.go @@ -413,19 +413,9 @@ func daemonFunc(req *cmds.Request, re cmds.ResponseEmitter, env cmds.Environment case routingOptionSupernodeKwd: return errors.New("supernode routing was never fully implemented and has been removed") case routingOptionDefaultKwd, routingOptionAutoKwd: - ncfg.Routing = libp2p.ConstructDefaultRouting( - cfg.Identity.PeerID, - cfg.Addresses.Swarm, - cfg.Identity.PrivKey, - libp2p.DHTOption, - ) + ncfg.Routing = libp2p.ConstructDefaultRouting(cfg, libp2p.DHTOption) case routingOptionAutoClientKwd: - ncfg.Routing = libp2p.ConstructDefaultRouting( - cfg.Identity.PeerID, - cfg.Addresses.Swarm, - cfg.Identity.PrivKey, - libp2p.DHTClientOption, - ) + ncfg.Routing = libp2p.ConstructDefaultRouting(cfg, libp2p.DHTClientOption) case routingOptionDHTClientKwd: ncfg.Routing = libp2p.DHTClientOption case routingOptionDHTKwd: diff --git a/core/node/groups.go b/core/node/groups.go index 866204ce3..086d71d14 100644 --- a/core/node/groups.go +++ b/core/node/groups.go @@ -165,7 +165,7 @@ func LibP2P(bcfg *BuildCfg, cfg *config.Config, userResourceOverrides rcmgr.Part fx.Provide(libp2p.Routing), fx.Provide(libp2p.ContentRouting), - fx.Provide(libp2p.BaseRouting(cfg.Experimental.AcceleratedDHTClient)), + fx.Provide(libp2p.BaseRouting(cfg)), maybeProvide(libp2p.PubsubRouter, bcfg.getOpt("ipnsps")), maybeProvide(libp2p.BandwidthCounter, !cfg.Swarm.DisableBandwidthMetrics), diff --git a/core/node/libp2p/routing.go b/core/node/libp2p/routing.go index 8014d4142..0fc138cad 100644 --- a/core/node/libp2p/routing.go +++ b/core/node/libp2p/routing.go @@ -63,35 +63,34 @@ type processInitialRoutingOut struct { type AddrInfoChan chan peer.AddrInfo -func BaseRouting(experimentalDHTClient bool) interface{} { +func BaseRouting(cfg *config.Config) interface{} { return func(lc fx.Lifecycle, in processInitialRoutingIn) (out processInitialRoutingOut, err error) { - var dr *ddht.DHT + var dualDHT *ddht.DHT if dht, ok := in.Router.(*ddht.DHT); ok { - dr = dht + dualDHT = dht lc.Append(fx.Hook{ OnStop: func(ctx context.Context) error { - return dr.Close() + return dualDHT.Close() }, }) } - if pr, ok := in.Router.(routinghelpers.ComposableRouter); ok { - for _, r := range pr.Routers() { + if cr, ok := in.Router.(routinghelpers.ComposableRouter); ok { + for _, r := range cr.Routers() { if dht, ok := r.(*ddht.DHT); ok { - dr = dht + dualDHT = dht lc.Append(fx.Hook{ OnStop: func(ctx context.Context) error { - return dr.Close() + return dualDHT.Close() }, }) - break } } } - if dr != nil && experimentalDHTClient { + if dualDHT != nil && cfg.Experimental.AcceleratedDHTClient { cfg, err := in.Repo.Config() if err != nil { return out, err @@ -101,7 +100,7 @@ func BaseRouting(experimentalDHTClient bool) interface{} { return out, err } - expClient, err := fullrt.NewFullRT(in.Host, + fullRTClient, err := fullrt.NewFullRT(in.Host, dht.DefaultPrefix, fullrt.DHTOption( dht.Validator(in.Validator), @@ -116,18 +115,30 @@ func BaseRouting(experimentalDHTClient bool) interface{} { lc.Append(fx.Hook{ OnStop: func(ctx context.Context) error { - return expClient.Close() + return fullRTClient.Close() }, }) + // we want to also use the default HTTP routers, so wrap the FullRT client + // in a parallel router that calls them in parallel + httpRouters, err := constructDefaultHTTPRouters(cfg) + if err != nil { + return out, err + } + routers := []*routinghelpers.ParallelRouter{ + {Router: fullRTClient}, + } + routers = append(routers, httpRouters...) + router := routinghelpers.NewComposableParallel(routers) + return processInitialRoutingOut{ Router: Router{ - Routing: expClient, Priority: 1000, + Routing: router, }, - DHT: dr, - DHTClient: expClient, - ContentRouter: expClient, + DHT: dualDHT, + DHTClient: fullRTClient, + ContentRouter: fullRTClient, }, nil } @@ -136,8 +147,8 @@ func BaseRouting(experimentalDHTClient bool) interface{} { Priority: 1000, Routing: in.Router, }, - DHT: dr, - DHTClient: dr, + DHT: dualDHT, + DHTClient: dualDHT, ContentRouter: in.Router, }, nil } diff --git a/core/node/libp2p/routingopt.go b/core/node/libp2p/routingopt.go index 8a69e181b..62d3320f8 100644 --- a/core/node/libp2p/routingopt.go +++ b/core/node/libp2p/routingopt.go @@ -39,8 +39,35 @@ func init() { } } +func constructDefaultHTTPRouters(cfg *config.Config) ([]*routinghelpers.ParallelRouter, error) { + var routers []*routinghelpers.ParallelRouter + // Append HTTP routers for additional speed + for _, endpoint := range defaultHTTPRouters { + httpRouter, err := irouting.ConstructHTTPRouter(endpoint, cfg.Identity.PeerID, cfg.Addresses.Swarm, cfg.Identity.PrivKey) + if err != nil { + return nil, err + } + + r := &irouting.Composer{ + GetValueRouter: routinghelpers.Null{}, + PutValueRouter: routinghelpers.Null{}, + ProvideRouter: routinghelpers.Null{}, // modify this when indexers supports provide + FindPeersRouter: routinghelpers.Null{}, + FindProvidersRouter: httpRouter, + } + + routers = append(routers, &routinghelpers.ParallelRouter{ + Router: r, + IgnoreError: true, // https://github.com/ipfs/kubo/pull/9475#discussion_r1042507387 + Timeout: 15 * time.Second, // 5x server value from https://github.com/ipfs/kubo/pull/9475#discussion_r1042428529 + ExecuteAfter: 0, + }) + } + return routers, nil +} + // ConstructDefaultRouting returns routers used when Routing.Type is unset or set to "auto" -func ConstructDefaultRouting(peerID string, addrs []string, privKey string, routingOpt RoutingOption) func( +func ConstructDefaultRouting(cfg *config.Config, routingOpt RoutingOption) func( ctx context.Context, host host.Host, dstore datastore.Batching, @@ -68,29 +95,13 @@ func ConstructDefaultRouting(peerID string, addrs []string, privKey string, rout ExecuteAfter: 0, }) - // Append HTTP routers for additional speed - for _, endpoint := range defaultHTTPRouters { - httpRouter, err := irouting.ConstructHTTPRouter(endpoint, peerID, addrs, privKey) - if err != nil { - return nil, err - } - - r := &irouting.Composer{ - GetValueRouter: routinghelpers.Null{}, - PutValueRouter: routinghelpers.Null{}, - ProvideRouter: routinghelpers.Null{}, // modify this when indexers supports provide - FindPeersRouter: routinghelpers.Null{}, - FindProvidersRouter: httpRouter, - } - - routers = append(routers, &routinghelpers.ParallelRouter{ - Router: r, - IgnoreError: true, // https://github.com/ipfs/kubo/pull/9475#discussion_r1042507387 - Timeout: 15 * time.Second, // 5x server value from https://github.com/ipfs/kubo/pull/9475#discussion_r1042428529 - ExecuteAfter: 0, - }) + httpRouters, err := constructDefaultHTTPRouters(cfg) + if err != nil { + return nil, err } + routers = append(routers, httpRouters...) + routing := routinghelpers.NewComposableParallel(routers) return routing, nil } From 347ad061f4aa60e4b336a0efd1796cf8bb2a2543 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Wed, 3 May 2023 09:00:41 +0200 Subject: [PATCH 0647/1212] docs: add changelog for v0.19.2 --- docs/changelogs/v0.19.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/docs/changelogs/v0.19.md b/docs/changelogs/v0.19.md index 1abc2e518..f7e190a7e 100644 --- a/docs/changelogs/v0.19.md +++ b/docs/changelogs/v0.19.md @@ -1,6 +1,33 @@ # Kubo changelog v0.19 +## v0.19.2 + +### Highlights + +#### FullRT DHT HTTP Routers + +The default HTTP routers are now used when the FullRT DHT client is used. This fixes +the issue where cid.contact is not being queried by default when the accelerated +DHT client was enabled. Read more in ([ipfs/kubo#9841](https://github.com/ipfs/kubo/pull/9841)). + +### Changelog + +
    Full Changelog + +- github.com/ipfs/kubo: + - fix: use default HTTP routers when FullRT DHT client is used (#9841) ([ipfs/kubo#9841](https://github.com/ipfs/kubo/pull/9841)) + - chore: update version + +
    + +### Contributors + +| Contributor | Commits | Lines ± | Files Changed | +|-------------|---------|---------|---------------| +| Gus Eggert | 1 | +65/-53 | 4 | +| Henrique Dias | 1 | +1/-1 | 1 | + ## v0.19.1 ### 🔦 Highlights From 1b154e24568ab4970740bc49e9364c748dc05738 Mon Sep 17 00:00:00 2001 From: Laurent Senta Date: Wed, 3 May 2023 12:59:07 +0200 Subject: [PATCH 0648/1212] feat(routing): allow-offline with routing put (#278) This commit was moved from ipfs/boxo@8059f183d86648f69ad562546b4797bc148c0984 --- core/coreiface/options/routing.go | 35 +++++++++++++++++++++++++ core/coreiface/routing.go | 4 ++- core/coreiface/tests/api.go | 37 +++++++++++++++++--------- core/coreiface/tests/dht.go | 6 ++--- core/coreiface/tests/name.go | 6 ++--- core/coreiface/tests/pubsub.go | 2 +- core/coreiface/tests/routing.go | 43 ++++++++++++++++++++++++++++--- 7 files changed, 109 insertions(+), 24 deletions(-) create mode 100644 core/coreiface/options/routing.go diff --git a/core/coreiface/options/routing.go b/core/coreiface/options/routing.go new file mode 100644 index 000000000..d66d44a0d --- /dev/null +++ b/core/coreiface/options/routing.go @@ -0,0 +1,35 @@ +package options + +type RoutingPutSettings struct { + AllowOffline bool +} + +type RoutingPutOption func(*RoutingPutSettings) error + +func RoutingPutOptions(opts ...RoutingPutOption) (*RoutingPutSettings, error) { + options := &RoutingPutSettings{ + AllowOffline: false, + } + + for _, opt := range opts { + err := opt(options) + if err != nil { + return nil, err + } + } + + return options, nil +} + +type putOpts struct{} + +var Put putOpts + +// AllowOffline is an option for Routing.Put which specifies whether to allow +// publishing when the node is offline. Default value is false +func (putOpts) AllowOffline(allow bool) RoutingPutOption { + return func(settings *RoutingPutSettings) error { + settings.AllowOffline = allow + return nil + } +} diff --git a/core/coreiface/routing.go b/core/coreiface/routing.go index a28ceb9e7..5099c3de0 100644 --- a/core/coreiface/routing.go +++ b/core/coreiface/routing.go @@ -2,6 +2,8 @@ package iface import ( "context" + + "github.com/ipfs/boxo/coreiface/options" ) // RoutingAPI specifies the interface to the routing layer. @@ -10,5 +12,5 @@ type RoutingAPI interface { Get(context.Context, string) ([]byte, error) // Put sets a value for a given key - Put(ctx context.Context, key string, value []byte) error + Put(ctx context.Context, key string, value []byte, opts ...options.RoutingPutOption) error } diff --git a/core/coreiface/tests/api.go b/core/coreiface/tests/api.go index 497ef9d27..f30990512 100644 --- a/core/coreiface/tests/api.go +++ b/core/coreiface/tests/api.go @@ -11,21 +11,12 @@ import ( var errAPINotImplemented = errors.New("api not implemented") -func (tp *TestSuite) makeAPI(ctx context.Context) (coreiface.CoreAPI, error) { - api, err := tp.MakeAPISwarm(ctx, false, 1) - if err != nil { - return nil, err - } - - return api[0], nil -} - type Provider interface { // Make creates n nodes. fullIdentity set to false can be ignored - MakeAPISwarm(ctx context.Context, fullIdentity bool, n int) ([]coreiface.CoreAPI, error) + MakeAPISwarm(ctx context.Context, fullIdentity bool, online bool, n int) ([]coreiface.CoreAPI, error) } -func (tp *TestSuite) MakeAPISwarm(ctx context.Context, fullIdentity bool, n int) ([]coreiface.CoreAPI, error) { +func (tp *TestSuite) makeAPISwarm(ctx context.Context, fullIdentity bool, online bool, n int) ([]coreiface.CoreAPI, error) { if tp.apis != nil { tp.apis <- 1 go func() { @@ -34,7 +25,29 @@ func (tp *TestSuite) MakeAPISwarm(ctx context.Context, fullIdentity bool, n int) }() } - return tp.Provider.MakeAPISwarm(ctx, fullIdentity, n) + return tp.Provider.MakeAPISwarm(ctx, fullIdentity, online, n) +} + +func (tp *TestSuite) makeAPI(ctx context.Context) (coreiface.CoreAPI, error) { + api, err := tp.makeAPISwarm(ctx, false, false, 1) + if err != nil { + return nil, err + } + + return api[0], nil +} + +func (tp *TestSuite) makeAPIWithIdentityAndOffline(ctx context.Context) (coreiface.CoreAPI, error) { + api, err := tp.makeAPISwarm(ctx, true, false, 1) + if err != nil { + return nil, err + } + + return api[0], nil +} + +func (tp *TestSuite) MakeAPISwarm(ctx context.Context, n int) ([]coreiface.CoreAPI, error) { + return tp.makeAPISwarm(ctx, true, true, n) } type TestSuite struct { diff --git a/core/coreiface/tests/dht.go b/core/coreiface/tests/dht.go index fb3f6d1a0..61f9fd687 100644 --- a/core/coreiface/tests/dht.go +++ b/core/coreiface/tests/dht.go @@ -26,7 +26,7 @@ func (tp *TestSuite) TestDht(t *testing.T) { func (tp *TestSuite) TestDhtFindPeer(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - apis, err := tp.MakeAPISwarm(ctx, true, 5) + apis, err := tp.MakeAPISwarm(ctx, 5) if err != nil { t.Fatal(err) } @@ -81,7 +81,7 @@ func (tp *TestSuite) TestDhtFindPeer(t *testing.T) { func (tp *TestSuite) TestDhtFindProviders(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - apis, err := tp.MakeAPISwarm(ctx, true, 5) + apis, err := tp.MakeAPISwarm(ctx, 5) if err != nil { t.Fatal(err) } @@ -113,7 +113,7 @@ func (tp *TestSuite) TestDhtFindProviders(t *testing.T) { func (tp *TestSuite) TestDhtProvide(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - apis, err := tp.MakeAPISwarm(ctx, true, 5) + apis, err := tp.MakeAPISwarm(ctx, 5) if err != nil { t.Fatal(err) } diff --git a/core/coreiface/tests/name.go b/core/coreiface/tests/name.go index a67876cba..a669e0c02 100644 --- a/core/coreiface/tests/name.go +++ b/core/coreiface/tests/name.go @@ -43,7 +43,7 @@ func (tp *TestSuite) TestPublishResolve(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() init := func() (coreiface.CoreAPI, path.Path) { - apis, err := tp.MakeAPISwarm(ctx, true, 5) + apis, err := tp.MakeAPISwarm(ctx, 5) if err != nil { t.Fatal(err) return nil, nil @@ -191,7 +191,7 @@ func (tp *TestSuite) TestPublishResolve(t *testing.T) { func (tp *TestSuite) TestBasicPublishResolveKey(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - apis, err := tp.MakeAPISwarm(ctx, true, 5) + apis, err := tp.MakeAPISwarm(ctx, 5) if err != nil { t.Fatal(err) } @@ -235,7 +235,7 @@ func (tp *TestSuite) TestBasicPublishResolveTimeout(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - apis, err := tp.MakeAPISwarm(ctx, true, 5) + apis, err := tp.MakeAPISwarm(ctx, 5) if err != nil { t.Fatal(err) } diff --git a/core/coreiface/tests/pubsub.go b/core/coreiface/tests/pubsub.go index 446e0771a..24a8ac309 100644 --- a/core/coreiface/tests/pubsub.go +++ b/core/coreiface/tests/pubsub.go @@ -24,7 +24,7 @@ func (tp *TestSuite) TestBasicPubSub(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - apis, err := tp.MakeAPISwarm(ctx, true, 2) + apis, err := tp.MakeAPISwarm(ctx, 2) if err != nil { t.Fatal(err) } diff --git a/core/coreiface/tests/routing.go b/core/coreiface/tests/routing.go index e1d8d1060..bf314cafe 100644 --- a/core/coreiface/tests/routing.go +++ b/core/coreiface/tests/routing.go @@ -7,6 +7,7 @@ import ( "github.com/gogo/protobuf/proto" iface "github.com/ipfs/boxo/coreiface" + "github.com/ipfs/boxo/coreiface/options" ipns_pb "github.com/ipfs/boxo/ipns/pb" ) @@ -20,15 +21,16 @@ func (tp *TestSuite) TestRouting(t *testing.T) { t.Run("TestRoutingGet", tp.TestRoutingGet) t.Run("TestRoutingPut", tp.TestRoutingPut) + t.Run("TestRoutingPutOffline", tp.TestRoutingPutOffline) } -func (tp *TestSuite) testRoutingPublishKey(t *testing.T, ctx context.Context, api iface.CoreAPI) iface.IpnsEntry { +func (tp *TestSuite) testRoutingPublishKey(t *testing.T, ctx context.Context, api iface.CoreAPI, opts ...options.NamePublishOption) iface.IpnsEntry { p, err := addTestObject(ctx, api) if err != nil { t.Fatal(err) } - entry, err := api.Name().Publish(ctx, p) + entry, err := api.Name().Publish(ctx, p, opts...) if err != nil { t.Fatal(err) } @@ -41,7 +43,7 @@ func (tp *TestSuite) TestRoutingGet(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - apis, err := tp.MakeAPISwarm(ctx, true, 2) + apis, err := tp.MakeAPISwarm(ctx, 2) if err != nil { t.Fatal(err) } @@ -70,7 +72,7 @@ func (tp *TestSuite) TestRoutingGet(t *testing.T) { func (tp *TestSuite) TestRoutingPut(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - apis, err := tp.MakeAPISwarm(ctx, true, 2) + apis, err := tp.MakeAPISwarm(ctx, 2) if err != nil { t.Fatal(err) } @@ -90,3 +92,36 @@ func (tp *TestSuite) TestRoutingPut(t *testing.T) { t.Fatal(err) } } + +func (tp *TestSuite) TestRoutingPutOffline(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + // init a swarm & publish an IPNS entry to get a valid payload + apis, err := tp.MakeAPISwarm(ctx, 2) + if err != nil { + t.Fatal(err) + } + + ipnsEntry := tp.testRoutingPublishKey(t, ctx, apis[0], options.Name.AllowOffline(true)) + data, err := apis[0].Routing().Get(ctx, "/ipns/"+ipnsEntry.Name()) + if err != nil { + t.Fatal(err) + } + + // init our offline node and try to put the payload + api, err := tp.makeAPIWithIdentityAndOffline(ctx) + if err != nil { + t.Fatal(err) + } + + err = api.Routing().Put(ctx, "/ipns/"+ipnsEntry.Name(), data) + if err == nil { + t.Fatal("this operation should fail because we are offline") + } + + err = api.Routing().Put(ctx, "/ipns/"+ipnsEntry.Name(), data, options.Put.AllowOffline(true)) + if err != nil { + t.Fatal(err) + } +} From a6f446a4bab78b3d8b814474f1532f7bebcdc9c1 Mon Sep 17 00:00:00 2001 From: Laurent Senta Date: Wed, 3 May 2023 15:01:13 +0200 Subject: [PATCH 0649/1212] test: deterministic ipns fixtures during sharness gateway tests (#9667) --- core/commands/routing.go | 34 ++++++--- core/coreapi/routing.go | 13 +++- core/coreapi/test/api_test.go | 22 +++--- core/coreapi/test/path_test.go | 2 +- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 +- go.mod | 2 +- go.sum | 4 +- test/sharness/t0114-gateway-subdomains.sh | 50 +++++--------- ...XSZpdHs7oHbXub2G5WC8Tx4NQhyd2d.ipns-record | Bin 0 -> 394 bytes ...8itnGufN7MEtPRCNHkKpNuA4onsRa3.ipns-record | Bin 0 -> 1082 bytes .../t0114-gateway-subdomains/README.md | 65 ++++++++++++++++-- test/sharness/t0116-gateway-cache.sh | 18 ++--- test/sharness/t0116-gateway-cache/README.md | 20 ++++-- ...p32iwm9pdt9nq3y5rpn3ln9j12zfhe.ipns-record | Bin 0 -> 394 bytes test/sharness/t0123-gateway-json-cbor.sh | 22 +++--- .../t0123-gateway-json-cbor/README.md | 24 ++++++- ...xckoqzwqeqwudfr74kfd11zcyk3b7l.ipns-record | Bin 0 -> 394 bytes ...e2z4pwgp15pgv3ho1azvidttzh8yy2.ipns-record | Bin 0 -> 398 bytes test/sharness/t0124-gateway-ipns-record.sh | 16 +++-- .../t0124-gateway-ipns-record/README.md | 27 ++++++++ .../t0124-gateway-ipns-record/fixtures.car | Bin 0 -> 107 bytes ...i88nsady6qgd1dhjcyfsaqmpp143ab.ipns-record | Bin 0 -> 392 bytes 23 files changed, 224 insertions(+), 101 deletions(-) create mode 100644 test/sharness/t0114-gateway-subdomains/12D3KooWLQzUv2FHWGVPXTXSZpdHs7oHbXub2G5WC8Tx4NQhyd2d.ipns-record create mode 100644 test/sharness/t0114-gateway-subdomains/QmVujd5Vb7moysJj8itnGufN7MEtPRCNHkKpNuA4onsRa3.ipns-record create mode 100644 test/sharness/t0116-gateway-cache/k51qzi5uqu5dlxdsdu5fpuu7h69wu4ohp32iwm9pdt9nq3y5rpn3ln9j12zfhe.ipns-record create mode 100644 test/sharness/t0123-gateway-json-cbor/k51qzi5uqu5dghjous0agrwavl8vzl64xckoqzwqeqwudfr74kfd11zcyk3b7l.ipns-record create mode 100644 test/sharness/t0123-gateway-json-cbor/k51qzi5uqu5dhjghbwdvbo6mi40htrq6e2z4pwgp15pgv3ho1azvidttzh8yy2.ipns-record create mode 100644 test/sharness/t0124-gateway-ipns-record/README.md create mode 100644 test/sharness/t0124-gateway-ipns-record/fixtures.car create mode 100644 test/sharness/t0124-gateway-ipns-record/k51qzi5uqu5dh71qgwangrt6r0nd4094i88nsady6qgd1dhjcyfsaqmpp143ab.ipns-record diff --git a/core/commands/routing.go b/core/commands/routing.go index 2d578fcb6..76672c6f2 100644 --- a/core/commands/routing.go +++ b/core/commands/routing.go @@ -10,6 +10,8 @@ import ( cmdenv "github.com/ipfs/kubo/core/commands/cmdenv" + iface "github.com/ipfs/boxo/coreiface" + "github.com/ipfs/boxo/coreiface/options" dag "github.com/ipfs/boxo/ipld/merkledag" path "github.com/ipfs/boxo/path" cid "github.com/ipfs/go-cid" @@ -19,6 +21,16 @@ import ( routing "github.com/libp2p/go-libp2p/core/routing" ) +var ( + errAllowOffline = errors.New("can't put while offline: pass `--allow-offline` to override") +) + +const ( + dhtVerboseOptionName = "verbose" + numProvidersOptionName = "num-providers" + allowOfflineOptionName = "allow-offline" +) + var RoutingCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "Issue routing commands.", @@ -34,14 +46,6 @@ var RoutingCmd = &cmds.Command{ }, } -const ( - dhtVerboseOptionName = "verbose" -) - -const ( - numProvidersOptionName = "num-providers" -) - var findProvidersRoutingCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "Find peers that can provide a specific value, given a key.", @@ -420,6 +424,9 @@ identified by QmFoo. cmds.StringArg("key", true, false, "The key to store the value at."), cmds.FileArg("value-file", true, false, "A path to a file containing the value to store.").EnableStdin(), }, + Options: []cmds.Option{ + cmds.BoolOption(allowOfflineOptionName, "When offline, save the IPNS record to the the local datastore without broadcasting to the network instead of simply failing."), + }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { api, err := cmdenv.GetApi(env, req) if err != nil { @@ -437,13 +444,22 @@ identified by QmFoo. return err } - err = api.Routing().Put(req.Context, req.Arguments[0], data) + allowOffline, _ := req.Options[allowOfflineOptionName].(bool) + + opts := []options.RoutingPutOption{ + options.Put.AllowOffline(allowOffline), + } + + err = api.Routing().Put(req.Context, req.Arguments[0], data, opts...) if err != nil { return err } id, err := api.Key().Self(req.Context) if err != nil { + if err == iface.ErrOffline { + err = errAllowOffline + } return err } diff --git a/core/coreapi/routing.go b/core/coreapi/routing.go index 76d969316..95b50aa63 100644 --- a/core/coreapi/routing.go +++ b/core/coreapi/routing.go @@ -5,6 +5,7 @@ import ( "errors" coreiface "github.com/ipfs/boxo/coreiface" + caopts "github.com/ipfs/boxo/coreiface/options" "github.com/ipfs/boxo/path" peer "github.com/libp2p/go-libp2p/core/peer" ) @@ -24,9 +25,15 @@ func (r *RoutingAPI) Get(ctx context.Context, key string) ([]byte, error) { return r.routing.GetValue(ctx, dhtKey) } -func (r *RoutingAPI) Put(ctx context.Context, key string, value []byte) error { - if !r.nd.IsOnline { - return coreiface.ErrOffline +func (r *RoutingAPI) Put(ctx context.Context, key string, value []byte, opts ...caopts.RoutingPutOption) error { + options, err := caopts.RoutingPutOptions(opts...) + if err != nil { + return err + } + + err = r.checkOnline(options.AllowOffline) + if err != nil { + return err } dhtKey, err := normalizeKey(key) diff --git a/core/coreapi/test/api_test.go b/core/coreapi/test/api_test.go index dafadcc1f..64d873896 100644 --- a/core/coreapi/test/api_test.go +++ b/core/coreapi/test/api_test.go @@ -31,7 +31,7 @@ const testPeerID = "QmTFauExutTsy4XP6JbMFcw2Wa9645HJt2bTqL6qYDCKfe" type NodeProvider struct{} -func (NodeProvider) MakeAPISwarm(ctx context.Context, fullIdentity bool, n int) ([]coreiface.CoreAPI, error) { +func (NodeProvider) MakeAPISwarm(ctx context.Context, fullIdentity bool, online bool, n int) ([]coreiface.CoreAPI, error) { mn := mocknet.New() nodes := make([]*core.IpfsNode, n) @@ -82,7 +82,7 @@ func (NodeProvider) MakeAPISwarm(ctx context.Context, fullIdentity bool, n int) Routing: libp2p.DHTServerOption, Repo: r, Host: mock.MockHostOption(mn), - Online: fullIdentity, + Online: online, ExtraOpts: map[string]bool{ "pubsub": true, }, @@ -102,15 +102,17 @@ func (NodeProvider) MakeAPISwarm(ctx context.Context, fullIdentity bool, n int) return nil, err } - bsinf := bootstrap.BootstrapConfigWithPeers( - []peer.AddrInfo{ - nodes[0].Peerstore.PeerInfo(nodes[0].Identity), - }, - ) + if online { + bsinf := bootstrap.BootstrapConfigWithPeers( + []peer.AddrInfo{ + nodes[0].Peerstore.PeerInfo(nodes[0].Identity), + }, + ) - for _, n := range nodes[1:] { - if err := n.Bootstrap(bsinf); err != nil { - return nil, err + for _, n := range nodes[1:] { + if err := n.Bootstrap(bsinf); err != nil { + return nil, err + } } } diff --git a/core/coreapi/test/path_test.go b/core/coreapi/test/path_test.go index 9f67f3c71..c89ce48c9 100644 --- a/core/coreapi/test/path_test.go +++ b/core/coreapi/test/path_test.go @@ -19,7 +19,7 @@ func TestPathUnixFSHAMTPartial(t *testing.T) { defer cancel() // Create a node - apis, err := NodeProvider{}.MakeAPISwarm(ctx, true, 1) + apis, err := NodeProvider{}.MakeAPISwarm(ctx, true, true, 1) if err != nil { t.Fatal(err) } diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 6eb1bcb5e..fd3ad8909 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.18 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.8.1 + github.com/ipfs/boxo v0.8.2-0.20230503105907-8059f183d866 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.27.1 github.com/multiformats/go-multiaddr v0.9.0 diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 2302548a9..15bf75e82 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -321,8 +321,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.8.1 h1:3DkKBCK+3rdEB5t77WDShUXXhktYwH99mkAsgajsKrU= -github.com/ipfs/boxo v0.8.1/go.mod h1:xJ2hVb4La5WyD7GvKYE0lq2g1rmQZoCD2K4WNrV6aZI= +github.com/ipfs/boxo v0.8.2-0.20230503105907-8059f183d866 h1:ThRTXD/EyoLb/jz+YW+ZlOLbjX9FyaxP0dEpgUp3cCE= +github.com/ipfs/boxo v0.8.2-0.20230503105907-8059f183d866/go.mod h1:bORAHrH6hUtDZjbzTEaLrSpTdyhHKDIpjDRT+A14B7w= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= diff --git a/go.mod b/go.mod index b83143f9b..159bbd3e4 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/gogo/protobuf v1.3.2 github.com/google/uuid v1.3.0 github.com/hashicorp/go-multierror v1.1.1 - github.com/ipfs/boxo v0.8.1 + github.com/ipfs/boxo v0.8.2-0.20230503105907-8059f183d866 github.com/ipfs/go-block-format v0.1.2 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 diff --git a/go.sum b/go.sum index b00e5aed6..16d312ef5 100644 --- a/go.sum +++ b/go.sum @@ -356,8 +356,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.8.1 h1:3DkKBCK+3rdEB5t77WDShUXXhktYwH99mkAsgajsKrU= -github.com/ipfs/boxo v0.8.1/go.mod h1:xJ2hVb4La5WyD7GvKYE0lq2g1rmQZoCD2K4WNrV6aZI= +github.com/ipfs/boxo v0.8.2-0.20230503105907-8059f183d866 h1:ThRTXD/EyoLb/jz+YW+ZlOLbjX9FyaxP0dEpgUp3cCE= +github.com/ipfs/boxo v0.8.2-0.20230503105907-8059f183d866/go.mod h1:bORAHrH6hUtDZjbzTEaLrSpTdyhHKDIpjDRT+A14B7w= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= diff --git a/test/sharness/t0114-gateway-subdomains.sh b/test/sharness/t0114-gateway-subdomains.sh index 04f762ad6..bf5070985 100755 --- a/test/sharness/t0114-gateway-subdomains.sh +++ b/test/sharness/t0114-gateway-subdomains.sh @@ -93,40 +93,29 @@ test_launch_ipfs_daemon_without_network # Import test case # See the static fixtures in ./t0114-gateway-subdomains/ -test_expect_success "Add the test fixtures" ' - ipfs dag import ../t0114-gateway-subdomains/fixtures.car -' -CID_VAL="hello" +CID_VAL=hello CIDv1=bafkreicysg23kiwv34eg2d7qweipxwosdo2py4ldv42nbauguluen5v6am CIDv0=QmZULkCELmmk5XNfCgTnCyFgAVxBRBXyDHGGMVoLFLiXEN -# CIDv0to1 is necessary because raw-leaves are enabled by default during -# "ipfs add" with CIDv1 and disabled with CIDv0 CIDv0to1=bafybeiffndsajwhk3lwjewwdxqntmjm4b5wxaaanokonsggenkbw6slwk4 CIDv1_TOO_LONG=bafkrgqhhyivzstcz3hhswshfjgy6ertgmnqeleynhwt4dlfsthi4hn7zgh4uvlsb5xncykzapi3ocd4lzogukir6ksdy6wzrnz6ohnv4aglcs -DIR_CID=bafybeiht6dtwk3les7vqm6ibpvz6qpohidvlshsfyr7l5mpysdw2vmbbhe # ./testdirlisting +DIR_CID=bafybeiht6dtwk3les7vqm6ibpvz6qpohidvlshsfyr7l5mpysdw2vmbbhe -test_expect_success "Publish test text file to IPNS using RSA keys" ' - RSA_KEY=$(ipfs key gen --ipns-base=b58mh --type=rsa --size=2048 test_key_rsa | head -n1 | tr -d "\n") - RSA_IPNS_IDv0=$(echo "$RSA_KEY" | ipfs cid format -v 0) - RSA_IPNS_IDv1=$(echo "$RSA_KEY" | ipfs cid format -v 1 --mc libp2p-key -b base36) - RSA_IPNS_IDv1_DAGPB=$(echo "$RSA_IPNS_IDv0" | ipfs cid format -v 1 -b base36) - test_check_peerid "${RSA_KEY}" && - ipfs name publish --key test_key_rsa --allow-offline -Q "/ipfs/$CIDv1" > name_publish_out && - ipfs name resolve "$RSA_KEY" > output && - printf "/ipfs/%s\n" "$CIDv1" > expected2 && - test_cmp expected2 output -' +RSA_KEY=QmVujd5Vb7moysJj8itnGufN7MEtPRCNHkKpNuA4onsRa3 +RSA_IPNS_IDv0=QmVujd5Vb7moysJj8itnGufN7MEtPRCNHkKpNuA4onsRa3 +RSA_IPNS_IDv1=k2k4r8m7xvggw5pxxk3abrkwyer625hg01hfyggrai7lk1m63fuihi7w +RSA_IPNS_IDv1_DAGPB=k2jmtxu61bnhrtj301lw7zizknztocdbeqhxgv76l2q9t36fn9jbzipo -test_expect_success "Publish test text file to IPNS using ED25519 keys" ' - ED25519_KEY=$(ipfs key gen --ipns-base=b58mh --type=ed25519 test_key_ed25519 | head -n1 | tr -d "\n") - ED25519_IPNS_IDv0=$ED25519_KEY - ED25519_IPNS_IDv1=$(ipfs key list -l --ipns-base=base36 | grep test_key_ed25519 | cut -d " " -f1 | tr -d "\n") - ED25519_IPNS_IDv1_DAGPB=$(echo "$ED25519_IPNS_IDv1" | ipfs cid format -v 1 -b base36 --mc dag-pb) - test_check_peerid "${ED25519_KEY}" && - ipfs name publish --key test_key_ed25519 --allow-offline -Q "/ipfs/$CIDv1" > name_publish_out && - ipfs name resolve "$ED25519_KEY" > output && - printf "/ipfs/%s\n" "$CIDv1" > expected2 && - test_cmp expected2 output +ED25519_KEY=12D3KooWLQzUv2FHWGVPXTXSZpdHs7oHbXub2G5WC8Tx4NQhyd2d +ED25519_IPNS_IDv0=12D3KooWLQzUv2FHWGVPXTXSZpdHs7oHbXub2G5WC8Tx4NQhyd2d +ED25519_IPNS_IDv1=k51qzi5uqu5dk3v4rmjber23h16xnr23bsggmqqil9z2gduiis5se8dht36dam +ED25519_IPNS_IDv1_DAGPB=k50rm9yjlt0jey4fqg6wafvqprktgbkpgkqdg27tpqje6iimzxewnhvtin9hhq +IPNS_ED25519_B58MH=12D3KooWLQzUv2FHWGVPXTXSZpdHs7oHbXub2G5WC8Tx4NQhyd2d +IPNS_ED25519_B36CID=k51qzi5uqu5dk3v4rmjber23h16xnr23bsggmqqil9z2gduiis5se8dht36dam + +test_expect_success "Add the test fixtures" ' + ipfs dag import ../t0114-gateway-subdomains/fixtures.car && + ipfs routing put --allow-offline /ipns/${RSA_KEY} ../t0114-gateway-subdomains/${RSA_KEY}.ipns-record && + ipfs routing put --allow-offline /ipns/${ED25519_KEY} ../t0114-gateway-subdomains/${ED25519_KEY}.ipns-record ' # ensure we start with empty Gateway.PublicGateways @@ -588,11 +577,6 @@ test_expect_success \ ## https://github.com/ipfs/go-ipfs/issues/7318 ## ============================================================================ -# ed25519 fits under 63 char limit when represented in base36 -IPNS_KEY="test_key_ed25519" -IPNS_ED25519_B58MH=$(ipfs key list -l --ipns-base b58mh | grep $IPNS_KEY | cut -d" " -f1 | tr -d "\n") -IPNS_ED25519_B36CID=$(ipfs key list -l --ipns-base base36 | grep $IPNS_KEY | cut -d" " -f1 | tr -d "\n") - # local: *.localhost test_localhost_gateway_response_should_contain \ "request for a ED25519 libp2p-key at localhost/ipns/{b58mh} returns Location HTTP header for DNS-safe subdomain redirect in browsers" \ diff --git a/test/sharness/t0114-gateway-subdomains/12D3KooWLQzUv2FHWGVPXTXSZpdHs7oHbXub2G5WC8Tx4NQhyd2d.ipns-record b/test/sharness/t0114-gateway-subdomains/12D3KooWLQzUv2FHWGVPXTXSZpdHs7oHbXub2G5WC8Tx4NQhyd2d.ipns-record new file mode 100644 index 0000000000000000000000000000000000000000..39b2f41a40866132588557e1be7beb97f50b79d4 GIT binary patch literal 394 zcmd;b)XywPE7ng+Ov^4x%}lN=PB${n&MYr8Hc3r4N--}iPt7c-D9<^J}Yul1#e?Les=qsP9*TpHppd@W%Xk@HwV4`bi6k=#> zWnyAwYN=;oU}$b+5v9Rk(9qDcxZ%Nrr`k>qKjaU!b6-4rYi;`fm-}a{vCo?xRu}4g z^l|FihwZAz%U!lw{rY|+(EGO7p=OmC>knNP>?`)U^*Whrs^fvF0qEJ$Sl0Mn+K ATmS$7 literal 0 HcmV?d00001 diff --git a/test/sharness/t0114-gateway-subdomains/QmVujd5Vb7moysJj8itnGufN7MEtPRCNHkKpNuA4onsRa3.ipns-record b/test/sharness/t0114-gateway-subdomains/QmVujd5Vb7moysJj8itnGufN7MEtPRCNHkKpNuA4onsRa3.ipns-record new file mode 100644 index 0000000000000000000000000000000000000000..b37d9b75b50ce3baa472e0c790c63cc4476c8631 GIT binary patch literal 1082 zcmd;b)XywPE7ng+Ov^4x%}lN=PB${n&MYr8Hc3r4N--}iPt7c-D92(*IMXR5Go)>GsSynodq(GRGFw`JL;^nAdmmZe7@< z?;9u0)~oe;B6n8l#B-O4jHLznwHFfawsGeD^WdI5dD6CW_D`?(IR6u4yS}n>0Xs|C zV|Deu10TJ;+15H9y#1%w)-Pu|{~C5NEh+2ohgE%4GcFi^=!o1|c=mvclzM~Aq?sH1 zV;9|>pJ(C4b;k1K_pY`7N=jcyC2D2fRy9#Bx;b;nX--YmkL>f5|4X=(dm6Aa@2=jn zPF^r?@jIi2gJJgHoU|F^9$YA16dbkmCI8(bi=coUk?re*CGPIOm;0ZgQ?hD>F0X=C zL#OarR>@Lloz*!)FR?K>|cBO@yVa}y&! z15licsfm%1;pVJGT^wtTb=KA$^<13Nv3!=^X2&xt9)0ASbyDGP?WdlXx7q)`d@Z+h z!6|`%_KMwXk1o8Mo?{-MVA*x}^cm9=t?8#{Bqsazy{TE_Y}T4V{h&^m3)r^)bGv-5U2WMvuSX z7vtkGPzgn;O5JiMe~&<38&ZhUC?flR8gS@+~<#_0!o~ z@AZ8}8?WuOn%~@gsOVv8C3nV1oCd(eK6PTncvj@)S}Wr`}S-X)$F5@;ne3PMT?z z=NIb*B<2n+zLRAc6lAY~eeG%iDJwNZBx`P>1GC& uWCn)RutZ?qi=aH?W(21e0yA-PDnka)$jp??lFA5t$v6k5Dx|U?l>q?Oq1V#@ literal 0 HcmV?d00001 diff --git a/test/sharness/t0114-gateway-subdomains/README.md b/test/sharness/t0114-gateway-subdomains/README.md index 611bd0ed5..005a7f0c5 100644 --- a/test/sharness/t0114-gateway-subdomains/README.md +++ b/test/sharness/t0114-gateway-subdomains/README.md @@ -3,10 +3,16 @@ - fixtures.car - raw CARv1 -generated with: +- QmUKd....ipns-record + - ipns record, encoded with protocol buffer + +- 12D3K....ipns-record + - ipns record, encoded with protocol buffer + +Generated with: ```sh -# using ipfs version 0.18.1 +# using ipfs version 0.21.0-dev (03a98280e3e642774776cd3d0435ab53e5dfa867) # CIDv0to1 is necessary because raw-leaves are enabled by default during # "ipfs add" with CIDv1 and disabled with CIDv0 @@ -17,6 +23,7 @@ CIDv0to1=$(echo "$CIDv0" | ipfs cid base32) # sha512 will be over 63char limit, even when represented in Base36 CIDv1_TOO_LONG=$(echo $CID_VAL | ipfs add --cid-version 1 --hash sha2-512 -Q) +echo CID_VAL=${CID_VAL} echo CIDv1=${CIDv1} echo CIDv0=${CIDv0} echo CIDv0to1=${CIDv0to1} @@ -32,7 +39,7 @@ echo "I am a txt file" > testdirlisting/api/file.txt && echo "I am a txt file" > testdirlisting/ipfs/file.txt && DIR_CID=$(ipfs add -Qr --cid-version 1 testdirlisting) -echo DIR_CID=${DIR_CID} +echo DIR_CID=${DIR_CID} # ./testdirlisting ipfs files mkdir /t0114/ ipfs files cp /ipfs/${CIDv1} /t0114/ @@ -45,10 +52,60 @@ ROOT=`ipfs files stat /t0114/ --hash` ipfs dag export ${ROOT} > ./fixtures.car -# CID_VAL="hello" +# Then the keys + +KEY_NAME=test_key_rsa_$RANDOM +RSA_KEY=$(ipfs key gen --ipns-base=b58mh --type=rsa --size=2048 ${KEY_NAME} | head -n1 | tr -d "\n") +RSA_IPNS_IDv0=$(echo "$RSA_KEY" | ipfs cid format -v 0) +RSA_IPNS_IDv1=$(echo "$RSA_KEY" | ipfs cid format -v 1 --mc libp2p-key -b base36) +RSA_IPNS_IDv1_DAGPB=$(echo "$RSA_IPNS_IDv0" | ipfs cid format -v 1 -b base36) + +# publish a record valid for a 100 years +ipfs name publish --key ${KEY_NAME} --allow-offline -Q --ttl=876600h --lifetime=876600h "/ipfs/$CIDv1" +ipfs routing get /ipns/${RSA_KEY} > ${RSA_KEY}.ipns-record + +echo RSA_KEY=${RSA_KEY} +echo RSA_IPNS_IDv0=${RSA_IPNS_IDv0} +echo RSA_IPNS_IDv1=${RSA_IPNS_IDv1} +echo RSA_IPNS_IDv1_DAGPB=${RSA_IPNS_IDv1_DAGPB} + +KEY_NAME=test_key_ed25519_$RANDOM +ED25519_KEY=$(ipfs key gen --ipns-base=b58mh --type=ed25519 ${KEY_NAME} | head -n1 | tr -d "\n") +ED25519_IPNS_IDv0=$ED25519_KEY +ED25519_IPNS_IDv1=$(ipfs key list -l --ipns-base=base36 | grep ${KEY_NAME} | cut -d " " -f1 | tr -d "\n") +ED25519_IPNS_IDv1_DAGPB=$(echo "$ED25519_IPNS_IDv1" | ipfs cid format -v 1 -b base36 --mc dag-pb) + +# ed25519 fits under 63 char limit when represented in base36 +IPNS_ED25519_B58MH=$(ipfs key list -l --ipns-base b58mh | grep $KEY_NAME | cut -d" " -f1 | tr -d "\n") +IPNS_ED25519_B36CID=$(ipfs key list -l --ipns-base base36 | grep $KEY_NAME | cut -d" " -f1 | tr -d "\n") + +# publish a record valid for a 100 years +ipfs name publish --key ${KEY_NAME} --allow-offline -Q --ttl=876600h --lifetime=876600h "/ipfs/$CIDv1" +ipfs routing get /ipns/${ED25519_KEY} > ${ED25519_KEY}.ipns-record + +echo ED25519_KEY=${ED25519_KEY} +echo ED25519_IPNS_IDv0=${ED25519_IPNS_IDv0} +echo ED25519_IPNS_IDv1=${ED25519_IPNS_IDv1} +echo ED25519_IPNS_IDv1_DAGPB=${ED25519_IPNS_IDv1_DAGPB} +echo IPNS_ED25519_B58MH=${IPNS_ED25519_B58MH} +echo IPNS_ED25519_B36CID=${IPNS_ED25519_B36CID} + +# CID_VAL=hello # CIDv1=bafkreicysg23kiwv34eg2d7qweipxwosdo2py4ldv42nbauguluen5v6am # CIDv0=QmZULkCELmmk5XNfCgTnCyFgAVxBRBXyDHGGMVoLFLiXEN # CIDv0to1=bafybeiffndsajwhk3lwjewwdxqntmjm4b5wxaaanokonsggenkbw6slwk4 # CIDv1_TOO_LONG=bafkrgqhhyivzstcz3hhswshfjgy6ertgmnqeleynhwt4dlfsthi4hn7zgh4uvlsb5xncykzapi3ocd4lzogukir6ksdy6wzrnz6ohnv4aglcs # DIR_CID=bafybeiht6dtwk3les7vqm6ibpvz6qpohidvlshsfyr7l5mpysdw2vmbbhe # ./testdirlisting + +# RSA_KEY=QmVujd5Vb7moysJj8itnGufN7MEtPRCNHkKpNuA4onsRa3 +# RSA_IPNS_IDv0=QmVujd5Vb7moysJj8itnGufN7MEtPRCNHkKpNuA4onsRa3 +# RSA_IPNS_IDv1=k2k4r8m7xvggw5pxxk3abrkwyer625hg01hfyggrai7lk1m63fuihi7w +# RSA_IPNS_IDv1_DAGPB=k2jmtxu61bnhrtj301lw7zizknztocdbeqhxgv76l2q9t36fn9jbzipo + +# ED25519_KEY=12D3KooWLQzUv2FHWGVPXTXSZpdHs7oHbXub2G5WC8Tx4NQhyd2d +# ED25519_IPNS_IDv0=12D3KooWLQzUv2FHWGVPXTXSZpdHs7oHbXub2G5WC8Tx4NQhyd2d +# ED25519_IPNS_IDv1=k51qzi5uqu5dk3v4rmjber23h16xnr23bsggmqqil9z2gduiis5se8dht36dam +# ED25519_IPNS_IDv1_DAGPB=k50rm9yjlt0jey4fqg6wafvqprktgbkpgkqdg27tpqje6iimzxewnhvtin9hhq +# IPNS_ED25519_B58MH=12D3KooWLQzUv2FHWGVPXTXSZpdHs7oHbXub2G5WC8Tx4NQhyd2d +# IPNS_ED25519_B36CID=k51qzi5uqu5dk3v4rmjber23h16xnr23bsggmqqil9z2gduiis5se8dht36dam ``` diff --git a/test/sharness/t0116-gateway-cache.sh b/test/sharness/t0116-gateway-cache.sh index 0cb1a94eb..b2e6b3af3 100755 --- a/test/sharness/t0116-gateway-cache.sh +++ b/test/sharness/t0116-gateway-cache.sh @@ -25,24 +25,18 @@ test_launch_ipfs_daemon_without_network # Caching of things like raw blocks, CARs, dag-json and dag-cbor # is tested in their respective suites. -# Import test case -# See the static fixtures in ./t0116-gateway-cache/ -test_expect_success "Add the test directory" ' - ipfs dag import ../t0116-gateway-cache/fixtures.car -' ROOT1_CID=bafybeib3ffl2teiqdncv3mkz4r23b5ctrwkzrrhctdbne6iboayxuxk5ui # ./ ROOT2_CID=bafybeih2w7hjocxjg6g2ku25hvmd53zj7og4txpby3vsusfefw5rrg5sii # ./root2 ROOT3_CID=bafybeiawdvhmjcz65x5egzx4iukxc72hg4woks6v6fvgyupiyt3oczk5ja # ./root2/root3 ROOT4_CID=bafybeifq2rzpqnqrsdupncmkmhs3ckxxjhuvdcbvydkgvch3ms24k5lo7q # ./root2/root3/root4 FILE_CID=bafkreicysg23kiwv34eg2d7qweipxwosdo2py4ldv42nbauguluen5v6am # ./root2/root3/root4/index.html +TEST_IPNS_ID=k51qzi5uqu5dlxdsdu5fpuu7h69wu4ohp32iwm9pdt9nq3y5rpn3ln9j12zfhe -test_expect_success "Prepare IPNS unixfs content path for testing" ' - TEST_IPNS_ID=$(ipfs key gen --ipns-base=base36 --type=ed25519 cache_test_key | head -n1 | tr -d "\n") - ipfs name publish --key cache_test_key --allow-offline -Q "/ipfs/$ROOT1_CID" > name_publish_out && - test_check_peerid "${TEST_IPNS_ID}" && - ipfs name resolve "${TEST_IPNS_ID}" > output && - printf "/ipfs/%s\n" "$ROOT1_CID" > expected && - test_cmp expected output +# Import test case +# See the static fixtures in ./t0116-gateway-cache/ +test_expect_success "Add the test directory" ' + ipfs dag import ../t0116-gateway-cache/fixtures.car + ipfs routing put --allow-offline /ipns/${TEST_IPNS_ID} ../t0116-gateway-cache/${TEST_IPNS_ID}.ipns-record ' # GET /ipfs/ diff --git a/test/sharness/t0116-gateway-cache/README.md b/test/sharness/t0116-gateway-cache/README.md index 8b44fe640..1be92f454 100644 --- a/test/sharness/t0116-gateway-cache/README.md +++ b/test/sharness/t0116-gateway-cache/README.md @@ -6,7 +6,8 @@ generated with: ```sh -# using ipfs version 0.18.1 +# using ipfs version 0.21.0-dev (03a98280e3e642774776cd3d0435ab53e5dfa867) + mkdir -p root2/root3/root4 && echo "hello" > root2/root3/root4/index.html && ROOT1_CID=$(ipfs add -Qrw --cid-version 1 root2) @@ -15,11 +16,17 @@ ROOT3_CID=$(ipfs resolve -r /ipfs/$ROOT1_CID/root2/root3 | cut -d "/" -f3) ROOT4_CID=$(ipfs resolve -r /ipfs/$ROOT1_CID/root2/root3/root4 | cut -d "/" -f3) FILE_CID=$(ipfs resolve -r /ipfs/$ROOT1_CID/root2/root3/root4/index.html | cut -d "/" -f3) -echo ROOT1_CID=${ROOT1_CID} -echo ROOT2_CID=${ROOT2_CID} -echo ROOT3_CID=${ROOT3_CID} -echo ROOT4_CID=${ROOT4_CID} -echo FILE_CID=${FILE_CID} +TEST_IPNS_ID=$(ipfs key gen --ipns-base=base36 --type=ed25519 cache_test_key | head -n1 | tr -d "\n") +# publish a record valid for a 100 years +ipfs name publish --key cache_test_key --allow-offline -Q --ttl=876600h --lifetime=876600h "/ipfs/$ROOT1_CID" +ipfs routing get /ipns/${TEST_IPNS_ID} > ${TEST_IPNS_ID}.ipns-record + +echo ROOT1_CID=${ROOT1_CID} # ./ +echo ROOT2_CID=${ROOT2_CID} # ./root2 +echo ROOT3_CID=${ROOT3_CID} # ./root2/root3 +echo ROOT4_CID=${ROOT4_CID} # ./root2/root3/root4 +echo FILE_CID=${FILE_CID} # ./root2/root3/root4/index.html +echo TEST_IPNS_ID=${TEST_IPNS_ID} ipfs dag export ${ROOT1_CID} > ./fixtures.car @@ -28,4 +35,5 @@ ipfs dag export ${ROOT1_CID} > ./fixtures.car # ROOT3_CID=bafybeiawdvhmjcz65x5egzx4iukxc72hg4woks6v6fvgyupiyt3oczk5ja # ./root2/root3 # ROOT4_CID=bafybeifq2rzpqnqrsdupncmkmhs3ckxxjhuvdcbvydkgvch3ms24k5lo7q # ./root2/root3/root4 # FILE_CID=bafkreicysg23kiwv34eg2d7qweipxwosdo2py4ldv42nbauguluen5v6am # ./root2/root3/root4/index.html +# TEST_IPNS_ID=k51qzi5uqu5dlxdsdu5fpuu7h69wu4ohp32iwm9pdt9nq3y5rpn3ln9j12zfhe ``` diff --git a/test/sharness/t0116-gateway-cache/k51qzi5uqu5dlxdsdu5fpuu7h69wu4ohp32iwm9pdt9nq3y5rpn3ln9j12zfhe.ipns-record b/test/sharness/t0116-gateway-cache/k51qzi5uqu5dlxdsdu5fpuu7h69wu4ohp32iwm9pdt9nq3y5rpn3ln9j12zfhe.ipns-record new file mode 100644 index 0000000000000000000000000000000000000000..9cd7491bf7e71ec8f11e908b51aa908702a4a353 GIT binary patch literal 394 zcmd;b)XywPE7ng+Osh;v%}g>*OUp4TNzE)w$xALX&dsheDKaunGEFWiD$lMeD#}PM zNlD5}HOoxOPpqsct;jYl%@lIj#Aa`PX!4XzpKmQY)6e$9U7<`kzNU$F%{D)#mwVMZ z{GZ-h%zgj3z3+a9thHt*l@~txHDQw3!_thyQ+_E$H*2s|5P0dSAWyk;;nVFJVQW=5IUpX*UA(aKG3;+eR BnWX># literal 0 HcmV?d00001 diff --git a/test/sharness/t0123-gateway-json-cbor.sh b/test/sharness/t0123-gateway-json-cbor.sh index b22c056de..745e984db 100755 --- a/test/sharness/t0123-gateway-json-cbor.sh +++ b/test/sharness/t0123-gateway-json-cbor.sh @@ -163,6 +163,14 @@ test_expect_success "Add CARs for path traversal and DAG-PB representation tests test_should_contain $DAG_PB_CID import_output ' +IPNS_ID_DAG_JSON=k51qzi5uqu5dhjghbwdvbo6mi40htrq6e2z4pwgp15pgv3ho1azvidttzh8yy2 +IPNS_ID_DAG_CBOR=k51qzi5uqu5dghjous0agrwavl8vzl64xckoqzwqeqwudfr74kfd11zcyk3b7l + +test_expect_success "Add ipns records for path traversal and DAG-PB representation tests" ' + ipfs routing put --allow-offline /ipns/${IPNS_ID_DAG_JSON} ../t0123-gateway-json-cbor/${IPNS_ID_DAG_JSON}.ipns-record && + ipfs routing put --allow-offline /ipns/${IPNS_ID_DAG_CBOR} ../t0123-gateway-json-cbor/${IPNS_ID_DAG_CBOR}.ipns-record +' + test_expect_success "GET DAG-JSON traversal returns 501 if there is path remainder" ' curl -sD - "http://127.0.0.1:$GWAY_PORT/ipfs/$DAG_JSON_TRAVERSAL_CID/foo?format=dag-json" > curl_output 2>&1 && test_should_contain "501 Not Implemented" curl_output && @@ -197,6 +205,7 @@ test_native_dag () { format=$2 disposition=$3 CID=$4 + IPNS_ID=$5 # GET without explicit format and Accept: text/html returns raw block @@ -313,15 +322,6 @@ test_native_dag () { # IPNS behavior (should be same as immutable /ipfs, but with different caching headers) # To keep tests small we only confirm payload is the same, and then only test delta around caching headers. - test_expect_success "Prepare IPNS with dag-$format" ' - IPNS_ID=$(ipfs key gen --ipns-base=base36 --type=ed25519 ${format}_test_key | head -n1 | tr -d "\n") && - ipfs name publish --key ${format}_test_key --allow-offline -Q "/ipfs/$CID" > name_publish_out && - test_check_peerid "${IPNS_ID}" && - ipfs name resolve "${IPNS_ID}" > output && - printf "/ipfs/%s\n" "$CID" > expected && - test_cmp expected output - ' - test_expect_success "GET $name from /ipns without explicit format returns the same payload as /ipfs" ' curl -sX GET "http://127.0.0.1:$GWAY_PORT/ipfs/$CID" -o ipfs_output && curl -sX GET "http://127.0.0.1:$GWAY_PORT/ipns/$IPNS_ID" -o ipns_output && @@ -369,8 +369,8 @@ test_native_dag () { } -test_native_dag "DAG-JSON" "json" "inline" "$DAG_JSON_TRAVERSAL_CID" -test_native_dag "DAG-CBOR" "cbor" "attachment" "$DAG_CBOR_TRAVERSAL_CID" +test_native_dag "DAG-JSON" "json" "inline" "$DAG_JSON_TRAVERSAL_CID" ${IPNS_ID_DAG_JSON} +test_native_dag "DAG-CBOR" "cbor" "attachment" "$DAG_CBOR_TRAVERSAL_CID" ${IPNS_ID_DAG_CBOR} test_kill_ipfs_daemon diff --git a/test/sharness/t0123-gateway-json-cbor/README.md b/test/sharness/t0123-gateway-json-cbor/README.md index 4e83f42a1..5a63b192a 100644 --- a/test/sharness/t0123-gateway-json-cbor/README.md +++ b/test/sharness/t0123-gateway-json-cbor/README.md @@ -14,7 +14,8 @@ generated with: ```sh -# using ipfs version 0.18.1 +# using ipfs version 0.21.0-dev (03a98280e3e642774776cd3d0435ab53e5dfa867) + mkdir -p rootDir/ipfs && mkdir -p rootDir/ipns && mkdir -p rootDir/api && @@ -37,8 +38,29 @@ echo FILE_SIZE=${FILE_SIZE} ipfs dag export ${DIR_CID} > fixtures.car +DAG_CBOR_TRAVERSAL_CID="bafyreibs4utpgbn7uqegmd2goqz4bkyflre2ek2iwv743fhvylwi4zeeim" +DAG_JSON_TRAVERSAL_CID="baguqeeram5ujjqrwheyaty3w5gdsmoz6vittchvhk723jjqxk7hakxkd47xq" +DAG_PB_CID="bafybeiegxwlgmoh2cny7qlolykdf7aq7g6dlommarldrbm7c4hbckhfcke" + +test_native_dag() { + NAME=$1 + CID=$2 + + IPNS_ID=$(ipfs key gen --ipns-base=base36 --type=ed25519 ${NAME}_test_key | head -n1 | tr -d "\n") + ipfs name publish --key ${NAME}_test_key --allow-offline --ttl=876600h --lifetime=876600h -Q "/ipfs/${CID}" > name_publish_out + + ipfs routing get /ipns/${IPNS_ID} > ${IPNS_ID}.ipns-record + + echo "IPNS_ID_${NAME}=${IPNS_ID}" +} + +test_native_dag "DAG_JSON" "$DAG_JSON_TRAVERSAL_CID" +test_native_dag "DAG_CBOR" "$DAG_CBOR_TRAVERSAL_CID" + # DIR_CID=bafybeiafyvqlazbbbtjnn6how5d6h6l6rxbqc4qgpbmteaiskjrffmyy4a # ./rootDir # FILE_JSON_CID=bafkreibrppizs3g7axs2jdlnjua6vgpmltv7k72l7v7sa6mmht6mne3qqe # ./rootDir/ą/ę/t.json # FILE_CID=bafkreialihlqnf5uwo4byh4n3cmwlntwqzxxs2fg5vanqdi3d7tb2l5xkm # ./rootDir/ą/ę/file-źł.txt # FILE_SIZE=34 +# IPNS_ID_DAG_JSON=k51qzi5uqu5dhjghbwdvbo6mi40htrq6e2z4pwgp15pgv3ho1azvidttzh8yy2 +# IPNS_ID_DAG_CBOR=k51qzi5uqu5dghjous0agrwavl8vzl64xckoqzwqeqwudfr74kfd11zcyk3b7l ``` diff --git a/test/sharness/t0123-gateway-json-cbor/k51qzi5uqu5dghjous0agrwavl8vzl64xckoqzwqeqwudfr74kfd11zcyk3b7l.ipns-record b/test/sharness/t0123-gateway-json-cbor/k51qzi5uqu5dghjous0agrwavl8vzl64xckoqzwqeqwudfr74kfd11zcyk3b7l.ipns-record new file mode 100644 index 0000000000000000000000000000000000000000..7186c709e3ceb29fbfda0fd38b4e43109f26ce55 GIT binary patch literal 394 zcmd;b)XywPE7ng+OsgzP%}gpbDJ>~TPs%edElf?%O)*N(FRU_2%C1byDM~d;%{Iy` zFEckWPRl5(%qh<_sY*@F%oTE|Wo^}bx%d5*Sx4q7wQu^*{jh&wK$gukjlQ6!w<^zC z3zgkZ3FJ7HbjEJnE2pg~YAb1T`}pU#Pwl?`TRqWK?I))MgOaq7p^>q!fr+l6afpG1 zm4T&|siB^QrJ=E@n00{M& AZ2$lO literal 0 HcmV?d00001 diff --git a/test/sharness/t0123-gateway-json-cbor/k51qzi5uqu5dhjghbwdvbo6mi40htrq6e2z4pwgp15pgv3ho1azvidttzh8yy2.ipns-record b/test/sharness/t0123-gateway-json-cbor/k51qzi5uqu5dhjghbwdvbo6mi40htrq6e2z4pwgp15pgv3ho1azvidttzh8yy2.ipns-record new file mode 100644 index 0000000000000000000000000000000000000000..28676f4d9a8824989d039a03376aeea9ae63d0d3 GIT binary patch literal 398 zcmd;b*3T?RE7ng+OfM}=O)W~yH7(7`Dl96`NUcmPsWdJ(O;0J#&95>m%Pc8L&M3>s zHa9W`DyYad&q&O!$WAdauP799P;T3(=A&^x$Y#D|lG@q>LT5|;wEh}r>YUo65W?xX z)~)KP*_E#3s?1Ys{Wt72pZosTYWup`{b6o#URK<3lJD3g7?h-q42_I+4NPq4G7B@V2@KoE$;q~X{`u_XeTsd(Ml(;WP%n0C_P+X~( z`|*~;{f_SyrzS~i|89=(;gu+H(2(HipQ0Kl{`~X07?TnkT`#}eZV&jprZX;04hiv* z);`_Lz>>_skQ$blQ<@q curl_output_filename && test_should_contain "Hello IPFS" curl_output_filename ' @@ -31,14 +37,14 @@ test_expect_success "GET KEY with format=ipns-record has expected HTTP headers" curl -sD - "http://127.0.0.1:$GWAY_PORT/ipns/$IPNS_KEY?format=ipns-record" > curl_output_filename 2>&1 && test_should_contain "Content-Disposition: attachment;" curl_output_filename && test_should_contain "Content-Type: application/vnd.ipfs.ipns-record" curl_output_filename && - test_should_contain "Cache-Control: public, max-age=1800" curl_output_filename + test_should_contain "Cache-Control: public, max-age=3155760000" curl_output_filename ' test_expect_success "GET KEY with 'Accept: application/vnd.ipfs.ipns-record' has expected HTTP headers" ' curl -H "Accept: application/vnd.ipfs.ipns-record" -sD - "http://127.0.0.1:$GWAY_PORT/ipns/$IPNS_KEY" > curl_output_filename 2>&1 && test_should_contain "Content-Disposition: attachment;" curl_output_filename && test_should_contain "Content-Type: application/vnd.ipfs.ipns-record" curl_output_filename && - test_should_contain "Cache-Control: public, max-age=1800" curl_output_filename + test_should_contain "Cache-Control: public, max-age=3155760000" curl_output_filename ' test_expect_success "GET KEY with expliciy ?filename= succeeds with modified Content-Disposition header" ' diff --git a/test/sharness/t0124-gateway-ipns-record/README.md b/test/sharness/t0124-gateway-ipns-record/README.md new file mode 100644 index 000000000..8ada577d4 --- /dev/null +++ b/test/sharness/t0124-gateway-ipns-record/README.md @@ -0,0 +1,27 @@ +# Dataset description/sources + +- fixtures.car + - raw CARv1 + +- k51....ipns-record + - ipns record, encoded with protocol buffer + +generated with: + +```sh +# using ipfs version 0.21.0-dev (03a98280e3e642774776cd3d0435ab53e5dfa867) +FILE_CID=$(echo "Hello IPFS" | ipfs add --cid-version 1 -q) +IPNS_KEY=$(ipfs key gen ipns-record) + +ipfs dag export ${FILE_CID} > fixtures.car + +# publish a record valid for a 100 years +ipfs name publish --key=ipns-record --quieter --ttl=876600h --lifetime=876600h /ipfs/${FILE_CID} +ipfs routing get /ipns/${IPNS_KEY} > ${IPNS_KEY}.ipns-record + +echo IPNS_KEY=${IPNS_KEY} +echo FILE_CID=${FILE_CID} # A file containing "Hello IPFS" + +# IPNS_KEY=k51qzi5uqu5dh71qgwangrt6r0nd4094i88nsady6qgd1dhjcyfsaqmpp143ab +# FILE_CID=bafkreidfdrlkeq4m4xnxuyx6iae76fdm4wgl5d4xzsb77ixhyqwumhz244 # A file containing Hello IPFS +``` diff --git a/test/sharness/t0124-gateway-ipns-record/fixtures.car b/test/sharness/t0124-gateway-ipns-record/fixtures.car new file mode 100644 index 0000000000000000000000000000000000000000..5c541e430ea6d1aed7c20545c40c9a56994ac546 GIT binary patch literal 107 zcmcColvSFJ04j^dIZkA-4vOEfq6H0ie39ZWWO|7T-n zhTD&u+CmfaOSEsE-5&R2o=I`u(JdVUdxTlHr4_DQ%+Dynpd@8vXk@HwV4`bi6k=#> zWo%|;YN2OjY;I&8rNLm((9pBE;lYEa+D;DZwog8P;JtWuR2%!>xl6YFEuU6)>E){C z#}a3ym{+MAwLQ!K{b1W$zOv&|S}J#Rzj~K(y{i5eAFDB8+QsA7xBcYvn!>m=IV8kK zTKjY}14}XkLuy!JPHAcc<>8PKoLX3#nwOl)kO4F@GbOX6G6Ijca$t%=DhpB>023mb A4*&oF literal 0 HcmV?d00001 From a197125b8f3f85cc5070678f19b4d5853f3ff4d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Mur=C3=A9?= Date: Thu, 4 May 2023 13:50:02 +0200 Subject: [PATCH 0650/1212] pin: follow async pinner changes See https://github.com/ipfs/boxo/pull/290 This PR follow the changes in the Pinner to make listing recursive and direct pins asynchronous, which in turns allow pin/ls to build and emit results without having to wait anything, or accumulate too much in memory. Note: there is a tradeoff for pin/ls?type=all: - keep the recursive pins in memory (which I chose) - ask the pinner twice for the recursive pins, and limit memory usage Also, follow the changes in the GC with similar benefit of not having to wait the full pin list. Add a test. Also, follow the changes in pin.Verify. --- core/commands/pin/pin.go | 14 ++--- core/coreapi/pin.go | 130 ++++++++++++++++++++++----------------- gc/gc.go | 71 ++++++++++++--------- gc/gc_test.go | 96 +++++++++++++++++++++++++++++ go.mod | 3 + go.sum | 4 +- 6 files changed, 223 insertions(+), 95 deletions(-) create mode 100644 gc/gc_test.go diff --git a/core/commands/pin/pin.go b/core/commands/pin/pin.go index 6650fb93d..94072864c 100644 --- a/core/commands/pin/pin.go +++ b/core/commands/pin/pin.go @@ -675,10 +675,6 @@ func pinVerify(ctx context.Context, n *core.IpfsNode, opts pinVerifyOpts, enc ci bs := n.Blocks.Blockstore() DAG := dag.NewDAGService(bserv.New(bs, offline.Exchange(bs))) getLinks := dag.GetLinksWithDAG(DAG) - recPins, err := n.Pinning.RecursiveKeys(ctx) - if err != nil { - return nil, err - } var checkPin func(root cid.Cid) PinStatus checkPin = func(root cid.Cid) PinStatus { @@ -722,11 +718,15 @@ func pinVerify(ctx context.Context, n *core.IpfsNode, opts pinVerifyOpts, enc ci out := make(chan interface{}) go func() { defer close(out) - for _, cid := range recPins { - pinStatus := checkPin(cid) + for p := range n.Pinning.RecursiveKeys(ctx) { + if p.Err != nil { + out <- p.Err + return + } + pinStatus := checkPin(p.C) if !pinStatus.Ok || opts.includeOk { select { - case out <- &PinVerifyRes{enc.Encode(cid), pinStatus}: + case out <- &PinVerifyRes{enc.Encode(p.C), pinStatus}: case <-ctx.Done(): return } diff --git a/core/coreapi/pin.go b/core/coreapi/pin.go index 4aea8dfd3..98be600b2 100644 --- a/core/coreapi/pin.go +++ b/core/coreapi/pin.go @@ -12,9 +12,10 @@ import ( "github.com/ipfs/boxo/ipld/merkledag" pin "github.com/ipfs/boxo/pinning/pinner" "github.com/ipfs/go-cid" - "github.com/ipfs/kubo/tracing" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" + + "github.com/ipfs/kubo/tracing" ) type PinAPI CoreAPI @@ -156,6 +157,7 @@ func (api *PinAPI) Update(ctx context.Context, from path.Path, to path.Path, opt } type pinStatus struct { + err error cid cid.Cid ok bool badNodes []coreiface.BadPinNode @@ -175,6 +177,10 @@ func (s *pinStatus) BadNodes() []coreiface.BadPinNode { return s.badNodes } +func (s *pinStatus) Err() error { + return s.err +} + func (n *badNode) Path() path.Resolved { return n.path } @@ -191,10 +197,6 @@ func (api *PinAPI) Verify(ctx context.Context) (<-chan coreiface.PinStatus, erro bs := api.blockstore DAG := merkledag.NewDAGService(bserv.New(bs, offline.Exchange(bs))) getLinks := merkledag.GetLinksWithDAG(DAG) - recPins, err := api.pinning.RecursiveKeys(ctx) - if err != nil { - return nil, err - } var checkPin func(root cid.Cid) *pinStatus checkPin = func(root cid.Cid) *pinStatus { @@ -229,8 +231,18 @@ func (api *PinAPI) Verify(ctx context.Context) (<-chan coreiface.PinStatus, erro out := make(chan coreiface.PinStatus) go func() { defer close(out) - for _, c := range recPins { - out <- checkPin(c) + for p := range api.pinning.RecursiveKeys(ctx) { + var res *pinStatus + if p.Err != nil { + res = &pinStatus{err: p.Err} + } else { + res = checkPin(p.C) + } + select { + case <-ctx.Done(): + return + case out <- res: + } } }() @@ -262,63 +274,57 @@ func (p *pinInfo) Err() error { func (api *PinAPI) pinLsAll(ctx context.Context, typeStr string) <-chan coreiface.Pin { out := make(chan coreiface.Pin, 1) - keys := cid.NewSet() + emittedSet := cid.NewSet() - AddToResultKeys := func(keyList []cid.Cid, typeStr string) error { - for _, c := range keyList { - if keys.Visit(c) { - select { - case out <- &pinInfo{ - pinType: typeStr, - path: path.IpldPath(c), - }: - case <-ctx.Done(): - return ctx.Err() - } + AddToResultKeys := func(c cid.Cid, typeStr string) error { + if emittedSet.Visit(c) { + select { + case out <- &pinInfo{ + pinType: typeStr, + path: path.IpldPath(c), + }: + case <-ctx.Done(): + return ctx.Err() } } return nil } - VisitKeys := func(keyList []cid.Cid) { - for _, c := range keyList { - keys.Visit(c) - } - } - go func() { defer close(out) - var dkeys, rkeys []cid.Cid + var rkeys []cid.Cid var err error if typeStr == "recursive" || typeStr == "all" { - rkeys, err = api.pinning.RecursiveKeys(ctx) - if err != nil { - out <- &pinInfo{err: err} - return - } - if err = AddToResultKeys(rkeys, "recursive"); err != nil { - out <- &pinInfo{err: err} - return + for streamedCid := range api.pinning.RecursiveKeys(ctx) { + if streamedCid.Err != nil { + out <- &pinInfo{err: streamedCid.Err} + return + } + if err = AddToResultKeys(streamedCid.C, "recursive"); err != nil { + out <- &pinInfo{err: err} + return + } } } if typeStr == "direct" || typeStr == "all" { - dkeys, err = api.pinning.DirectKeys(ctx) - if err != nil { - out <- &pinInfo{err: err} - return - } - if err = AddToResultKeys(dkeys, "direct"); err != nil { - out <- &pinInfo{err: err} - return + for streamedCid := range api.pinning.DirectKeys(ctx) { + if streamedCid.Err != nil { + out <- &pinInfo{err: streamedCid.Err} + return + } + if err = AddToResultKeys(streamedCid.C, "direct"); err != nil { + out <- &pinInfo{err: err} + return + } } } if typeStr == "all" { - set := cid.NewSet() + walkingSet := cid.NewSet() for _, k := range rkeys { err = merkledag.Walk( ctx, merkledag.GetLinksWithDAG(api.dag), k, - set.Visit, + walkingSet.Visit, merkledag.SkipRoot(), merkledag.Concurrent(), ) if err != nil { @@ -326,7 +332,10 @@ func (api *PinAPI) pinLsAll(ctx context.Context, typeStr string) <-chan coreifac return } } - if err = AddToResultKeys(set.Keys(), "indirect"); err != nil { + err = walkingSet.ForEach(func(c cid.Cid) error { + return AddToResultKeys(c, "indirect") + }) + if err != nil { out <- &pinInfo{err: err} return } @@ -335,25 +344,27 @@ func (api *PinAPI) pinLsAll(ctx context.Context, typeStr string) <-chan coreifac // We need to first visit the direct pins that have priority // without emitting them - dkeys, err = api.pinning.DirectKeys(ctx) - if err != nil { - out <- &pinInfo{err: err} - return + for streamedCid := range api.pinning.DirectKeys(ctx) { + if streamedCid.Err != nil { + out <- &pinInfo{err: streamedCid.Err} + return + } + emittedSet.Add(streamedCid.C) } - VisitKeys(dkeys) - rkeys, err = api.pinning.RecursiveKeys(ctx) - if err != nil { - out <- &pinInfo{err: err} - return + for streamedCid := range api.pinning.RecursiveKeys(ctx) { + if streamedCid.Err != nil { + out <- &pinInfo{err: streamedCid.Err} + return + } + emittedSet.Add(streamedCid.C) } - VisitKeys(rkeys) - set := cid.NewSet() + walkingSet := cid.NewSet() for _, k := range rkeys { err = merkledag.Walk( ctx, merkledag.GetLinksWithDAG(api.dag), k, - set.Visit, + walkingSet.Visit, merkledag.SkipRoot(), merkledag.Concurrent(), ) if err != nil { @@ -361,7 +372,10 @@ func (api *PinAPI) pinLsAll(ctx context.Context, typeStr string) <-chan coreifac return } } - if err = AddToResultKeys(set.Keys(), "indirect"); err != nil { + err = emittedSet.ForEach(func(c cid.Cid) error { + return AddToResultKeys(c, "indirect") + }) + if err != nil { out <- &pinInfo{err: err} return } diff --git a/gc/gc.go b/gc/gc.go index 7e81ef557..6df598741 100644 --- a/gc/gc.go +++ b/gc/gc.go @@ -154,7 +154,7 @@ func GC(ctx context.Context, bs bstore.GCBlockstore, dstor dstore.Datastore, pn // Descendants recursively finds all the descendants of the given roots and // adds them to the given cid.Set, using the provided dag.GetLinks function // to walk the tree. -func Descendants(ctx context.Context, getLinks dag.GetLinks, set *cid.Set, roots []cid.Cid) error { +func Descendants(ctx context.Context, getLinks dag.GetLinks, set *cid.Set, roots <-chan pin.StreamedCid) error { verifyGetLinks := func(ctx context.Context, c cid.Cid) ([]*ipld.Link, error) { err := verifcid.ValidateCid(c) if err != nil { @@ -167,7 +167,7 @@ func Descendants(ctx context.Context, getLinks dag.GetLinks, set *cid.Set, roots verboseCidError := func(err error) error { if strings.Contains(err.Error(), verifcid.ErrBelowMinimumHashLength.Error()) || strings.Contains(err.Error(), verifcid.ErrPossiblyInsecureHashFunction.Error()) { - err = fmt.Errorf("\"%s\"\nPlease run 'ipfs pin verify'"+ //nolint + err = fmt.Errorf("\"%s\"\nPlease run 'ipfs pin verify'"+ // nolint " to list insecure hashes. If you want to read them,"+ " please downgrade your go-ipfs to 0.4.13\n", err) log.Error(err) @@ -175,19 +175,29 @@ func Descendants(ctx context.Context, getLinks dag.GetLinks, set *cid.Set, roots return err } - for _, c := range roots { - // Walk recursively walks the dag and adds the keys to the given set - err := dag.Walk(ctx, verifyGetLinks, c, func(k cid.Cid) bool { - return set.Visit(toCidV1(k)) - }, dag.Concurrent()) + for { + select { + case <-ctx.Done(): + return ctx.Err() + case wrapper, ok := <-roots: + if !ok { + return nil + } + if wrapper.Err != nil { + return wrapper.Err + } - if err != nil { - err = verboseCidError(err) - return err + // Walk recursively walks the dag and adds the keys to the given set + err := dag.Walk(ctx, verifyGetLinks, wrapper.C, func(k cid.Cid) bool { + return set.Visit(toCidV1(k)) + }, dag.Concurrent()) + + if err != nil { + err = verboseCidError(err) + return err + } } } - - return nil } // toCidV1 converts any CIDv0s to CIDv1s. @@ -217,11 +227,8 @@ func ColoredSet(ctx context.Context, pn pin.Pinner, ng ipld.NodeGetter, bestEffo } return links, nil } - rkeys, err := pn.RecursiveKeys(ctx) - if err != nil { - return nil, err - } - err = Descendants(ctx, getLinks, gcs, rkeys) + rkeys := pn.RecursiveKeys(ctx) + err := Descendants(ctx, getLinks, gcs, rkeys) if err != nil { errors = true select { @@ -243,7 +250,18 @@ func ColoredSet(ctx context.Context, pn pin.Pinner, ng ipld.NodeGetter, bestEffo } return links, nil } - err = Descendants(ctx, bestEffortGetLinks, gcs, bestEffortRoots) + bestEffortRootsChan := make(chan pin.StreamedCid) + go func() { + defer close(bestEffortRootsChan) + for _, root := range bestEffortRoots { + select { + case <-ctx.Done(): + return + case bestEffortRootsChan <- pin.StreamedCid{C: root}: + } + } + }() + err = Descendants(ctx, bestEffortGetLinks, gcs, bestEffortRootsChan) if err != nil { errors = true select { @@ -253,18 +271,15 @@ func ColoredSet(ctx context.Context, pn pin.Pinner, ng ipld.NodeGetter, bestEffo } } - dkeys, err := pn.DirectKeys(ctx) - if err != nil { - return nil, err - } - for _, k := range dkeys { - gcs.Add(toCidV1(k)) + dkeys := pn.DirectKeys(ctx) + for k := range dkeys { + if k.Err != nil { + return nil, k.Err + } + gcs.Add(toCidV1(k.C)) } - ikeys, err := pn.InternalPins(ctx) - if err != nil { - return nil, err - } + ikeys := pn.InternalPins(ctx) err = Descendants(ctx, getLinks, gcs, ikeys) if err != nil { errors = true diff --git a/gc/gc_test.go b/gc/gc_test.go new file mode 100644 index 000000000..4fb6dbf09 --- /dev/null +++ b/gc/gc_test.go @@ -0,0 +1,96 @@ +package gc + +import ( + "context" + "testing" + + "github.com/ipfs/boxo/blockservice" + "github.com/ipfs/boxo/blockstore" + "github.com/ipfs/boxo/exchange/offline" + "github.com/ipfs/boxo/ipld/merkledag" + mdutils "github.com/ipfs/boxo/ipld/merkledag/test" + pin "github.com/ipfs/boxo/pinning/pinner" + "github.com/ipfs/boxo/pinning/pinner/dspinner" + "github.com/ipfs/go-cid" + "github.com/ipfs/go-datastore" + dssync "github.com/ipfs/go-datastore/sync" + "github.com/multiformats/go-multihash" + "github.com/stretchr/testify/require" +) + +func TestGC(t *testing.T) { + ctx := context.Background() + + ds := dssync.MutexWrap(datastore.NewMapDatastore()) + bs := blockstore.NewGCBlockstore(blockstore.NewBlockstore(ds), blockstore.NewGCLocker()) + bserv := blockservice.New(bs, offline.Exchange(bs)) + dserv := merkledag.NewDAGService(bserv) + pinner, err := dspinner.New(ctx, ds, dserv) + require.NoError(t, err) + + daggen := mdutils.NewDAGGenerator() + + var expectedKept []multihash.Multihash + var expectedDiscarded []multihash.Multihash + + // add some pins + for i := 0; i < 5; i++ { + // direct + root, _, err := daggen.MakeDagNode(dserv.Add, 0, 1) + require.NoError(t, err) + err = pinner.PinWithMode(ctx, root, pin.Direct) + require.NoError(t, err) + expectedKept = append(expectedKept, root.Hash()) + + // recursive + root, allCids, err := daggen.MakeDagNode(dserv.Add, 5, 2) + require.NoError(t, err) + err = pinner.PinWithMode(ctx, root, pin.Recursive) + require.NoError(t, err) + expectedKept = append(expectedKept, toMHs(allCids)...) + } + + err = pinner.Flush(ctx) + require.NoError(t, err) + + // add more dags to be GCed + for i := 0; i < 5; i++ { + _, allCids, err := daggen.MakeDagNode(dserv.Add, 5, 2) + require.NoError(t, err) + expectedDiscarded = append(expectedDiscarded, toMHs(allCids)...) + } + + // and some other as "best effort roots" + var bestEffortRoots []cid.Cid + for i := 0; i < 5; i++ { + root, allCids, err := daggen.MakeDagNode(dserv.Add, 5, 2) + require.NoError(t, err) + bestEffortRoots = append(bestEffortRoots, root) + expectedKept = append(expectedKept, toMHs(allCids)...) + } + + ch := GC(ctx, bs, ds, pinner, bestEffortRoots) + var discarded []multihash.Multihash + for res := range ch { + require.NoError(t, res.Error) + discarded = append(discarded, res.KeyRemoved.Hash()) + } + + allKeys, err := bs.AllKeysChan(ctx) + require.NoError(t, err) + var kept []multihash.Multihash + for key := range allKeys { + kept = append(kept, key.Hash()) + } + + require.ElementsMatch(t, expectedDiscarded, discarded) + require.ElementsMatch(t, expectedKept, kept) +} + +func toMHs(cids []cid.Cid) []multihash.Multihash { + res := make([]multihash.Multihash, len(cids)) + for i, c := range cids { + res[i] = c.Hash() + } + return res +} diff --git a/go.mod b/go.mod index 159bbd3e4..d2b1f834f 100644 --- a/go.mod +++ b/go.mod @@ -1,5 +1,8 @@ module github.com/ipfs/kubo +// https://github.com/ipfs/boxo/pull/290 +replace github.com/ipfs/boxo => github.com/MichaelMure/boxo v0.0.0-20230505145003-9207501a615f + require ( bazil.org/fuse v0.0.0-20200117225306-7b5117fecadc contrib.go.opencensus.io/exporter/prometheus v0.4.2 diff --git a/go.sum b/go.sum index 16d312ef5..eb9a48dc0 100644 --- a/go.sum +++ b/go.sum @@ -49,6 +49,8 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/Kubuxu/go-os-helper v0.0.1 h1:EJiD2VUQyh5A9hWJLmc6iWg6yIcJ7jpBcwC8GMGXfDk= github.com/Kubuxu/go-os-helper v0.0.1/go.mod h1:N8B+I7vPCT80IcP58r50u4+gEEcsZETFUpAzWW2ep1Y= +github.com/MichaelMure/boxo v0.0.0-20230505145003-9207501a615f h1:2UbpOJ6cIC43V/hIDxgvP0VLbJIk+cBofPAWmXBlSrg= +github.com/MichaelMure/boxo v0.0.0-20230505145003-9207501a615f/go.mod h1:bORAHrH6hUtDZjbzTEaLrSpTdyhHKDIpjDRT+A14B7w= github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= @@ -356,8 +358,6 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.8.2-0.20230503105907-8059f183d866 h1:ThRTXD/EyoLb/jz+YW+ZlOLbjX9FyaxP0dEpgUp3cCE= -github.com/ipfs/boxo v0.8.2-0.20230503105907-8059f183d866/go.mod h1:bORAHrH6hUtDZjbzTEaLrSpTdyhHKDIpjDRT+A14B7w= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= From 196b5c16c00faac96438368f0a0d9f9ef0d7169f Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Mon, 8 May 2023 14:20:51 +0200 Subject: [PATCH 0651/1212] docs(config): remove mentions of relay v1 (#9860) Context: https://github.com/ipfs/interop/pull/592 --- docs/config.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/config.md b/docs/config.md index bb2d8b702..91866a423 100644 --- a/docs/config.md +++ b/docs/config.md @@ -1622,8 +1622,8 @@ Type: `flag` #### `Swarm.RelayClient.StaticRelays` -Your node will use these statically configured relay servers (V1 or V2) -instead of discovering public relays V2 from the network. +Your node will use these statically configured relay servers +instead of discovering public relays ([Circuit Relay v2](https://github.com/libp2p/specs/blob/master/relay/circuit-v2.md)) from the network. Default: `[]` From c178c51835f89f7b8d9e46962fe5e5d3dd3b2a69 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Mon, 8 May 2023 16:11:03 +0200 Subject: [PATCH 0652/1212] fix: deadlock on retrieving WebTransport addresses (#9857) Co-authored-by: Marco Polo --- core/mock/mock.go | 11 +++++++- core/node/groups.go | 2 +- core/node/libp2p/addrs.go | 38 ++++---------------------- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 +-- go.mod | 2 +- go.sum | 4 +-- test/cli/harness/peering.go | 4 +-- test/cli/transports_test.go | 23 ++++++++++++++++ 9 files changed, 48 insertions(+), 42 deletions(-) diff --git a/core/mock/mock.go b/core/mock/mock.go index 7b718c43e..f9e0876f8 100644 --- a/core/mock/mock.go +++ b/core/mock/mock.go @@ -34,7 +34,16 @@ func NewMockNode() (*core.IpfsNode, error) { } func MockHostOption(mn mocknet.Mocknet) libp2p2.HostOption { - return func(id peer.ID, ps pstore.Peerstore, _ ...libp2p.Option) (host.Host, error) { + return func(id peer.ID, ps pstore.Peerstore, opts ...libp2p.Option) (host.Host, error) { + var cfg libp2p.Config + if err := cfg.Apply(opts...); err != nil { + return nil, err + } + + // The mocknet does not use the provided libp2p.Option. This options include + // the listening addresses we want our peer listening on. Therefore, we have + // to manually parse the configuration and add them here. + ps.AddAddrs(id, cfg.ListenAddrs, pstore.PermanentAddrTTL) return mn.AddPeerWithPeerstore(id, ps) } } diff --git a/core/node/groups.go b/core/node/groups.go index ae8ce8539..548678835 100644 --- a/core/node/groups.go +++ b/core/node/groups.go @@ -155,7 +155,7 @@ func LibP2P(bcfg *BuildCfg, cfg *config.Config, userResourceOverrides rcmgr.Part fx.Provide(libp2p.RelayTransport(enableRelayTransport)), fx.Provide(libp2p.RelayService(enableRelayService, cfg.Swarm.RelayService)), fx.Provide(libp2p.Transports(cfg.Swarm.Transports)), - fx.Invoke(libp2p.StartListening(cfg.Addresses.Swarm)), + fx.Provide(libp2p.ListenOn(cfg.Addresses.Swarm)), fx.Invoke(libp2p.SetupDiscovery(cfg.Discovery.MDNS.Enabled)), fx.Provide(libp2p.ForceReachability(cfg.Internal.Libp2pForceReachability)), fx.Provide(libp2p.HolePunching(cfg.Swarm.EnableHolePunching, enableRelayClient)), diff --git a/core/node/libp2p/addrs.go b/core/node/libp2p/addrs.go index 480b045f8..b287c20ff 100644 --- a/core/node/libp2p/addrs.go +++ b/core/node/libp2p/addrs.go @@ -4,7 +4,6 @@ import ( "fmt" "github.com/libp2p/go-libp2p" - "github.com/libp2p/go-libp2p/core/host" p2pbhost "github.com/libp2p/go-libp2p/p2p/host/basic" ma "github.com/multiformats/go-multiaddr" mamask "github.com/whyrusleeping/multiaddr-filter" @@ -99,37 +98,12 @@ func AddrsFactory(announce []string, appendAnnouce []string, noAnnounce []string } } -func listenAddresses(addresses []string) ([]ma.Multiaddr, error) { - listen := make([]ma.Multiaddr, len(addresses)) - for i, addr := range addresses { - maddr, err := ma.NewMultiaddr(addr) - if err != nil { - return nil, fmt.Errorf("failure to parse config.Addresses.Swarm: %s", addresses) +func ListenOn(addresses []string) interface{} { + return func() (opts Libp2pOpts) { + return Libp2pOpts{ + Opts: []libp2p.Option{ + libp2p.ListenAddrStrings(addresses...), + }, } - listen[i] = maddr - } - - return listen, nil -} - -func StartListening(addresses []string) func(host host.Host) error { - return func(host host.Host) error { - listenAddrs, err := listenAddresses(addresses) - if err != nil { - return err - } - - // Actually start listening: - if err := host.Network().Listen(listenAddrs...); err != nil { - return err - } - - // list out our addresses - addrs, err := host.Network().InterfaceListenAddresses() - if err != nil { - return err - } - log.Infof("Swarm listening at: %s", addrs) - return nil } } diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index fd3ad8909..3c35f0e84 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -9,7 +9,7 @@ replace github.com/ipfs/kubo => ./../../.. require ( github.com/ipfs/boxo v0.8.2-0.20230503105907-8059f183d866 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 - github.com/libp2p/go-libp2p v0.27.1 + github.com/libp2p/go-libp2p v0.27.2 github.com/multiformats/go-multiaddr v0.9.0 ) diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 15bf75e82..c3ccc9ae3 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -489,8 +489,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.27.1 h1:k1u6RHsX3hqKnslDjsSgLNURxJ3O1atIZCY4gpMbbus= -github.com/libp2p/go-libp2p v0.27.1/go.mod h1:FAvvfQa/YOShUYdiSS03IR9OXzkcJXwcNA2FUCh9ImE= +github.com/libp2p/go-libp2p v0.27.2 h1:I1fxqxdm/O0TFoAZKje8wSMu9tfLlLdzTQvgT3HA6v0= +github.com/libp2p/go-libp2p v0.27.2/go.mod h1:FAvvfQa/YOShUYdiSS03IR9OXzkcJXwcNA2FUCh9ImE= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= diff --git a/go.mod b/go.mod index 159bbd3e4..6cb0108d8 100644 --- a/go.mod +++ b/go.mod @@ -45,7 +45,7 @@ require ( github.com/jbenet/goprocess v0.1.4 github.com/julienschmidt/httprouter v1.3.0 github.com/libp2p/go-doh-resolver v0.4.0 - github.com/libp2p/go-libp2p v0.27.1 + github.com/libp2p/go-libp2p v0.27.2 github.com/libp2p/go-libp2p-http v0.5.0 github.com/libp2p/go-libp2p-kad-dht v0.23.0 github.com/libp2p/go-libp2p-kbucket v0.5.0 diff --git a/go.sum b/go.sum index 16d312ef5..e136c5c00 100644 --- a/go.sum +++ b/go.sum @@ -540,8 +540,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.27.1 h1:k1u6RHsX3hqKnslDjsSgLNURxJ3O1atIZCY4gpMbbus= -github.com/libp2p/go-libp2p v0.27.1/go.mod h1:FAvvfQa/YOShUYdiSS03IR9OXzkcJXwcNA2FUCh9ImE= +github.com/libp2p/go-libp2p v0.27.2 h1:I1fxqxdm/O0TFoAZKje8wSMu9tfLlLdzTQvgT3HA6v0= +github.com/libp2p/go-libp2p v0.27.2/go.mod h1:FAvvfQa/YOShUYdiSS03IR9OXzkcJXwcNA2FUCh9ImE= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= diff --git a/test/cli/harness/peering.go b/test/cli/harness/peering.go index 3fcd8bb6b..13c3430f0 100644 --- a/test/cli/harness/peering.go +++ b/test/cli/harness/peering.go @@ -13,7 +13,7 @@ type Peering struct { To int } -func newRandPort() int { +func NewRandPort() int { n := rand.Int() return 3000 + (n % 1000) } @@ -24,7 +24,7 @@ func CreatePeerNodes(t *testing.T, n int, peerings []Peering) (*Harness, Nodes) nodes.ForEachPar(func(node *Node) { node.UpdateConfig(func(cfg *config.Config) { cfg.Routing.Type = config.NewOptionalString("none") - cfg.Addresses.Swarm = []string{fmt.Sprintf("/ip4/127.0.0.1/tcp/%d", newRandPort())} + cfg.Addresses.Swarm = []string{fmt.Sprintf("/ip4/127.0.0.1/tcp/%d", NewRandPort())} }) }) diff --git a/test/cli/transports_test.go b/test/cli/transports_test.go index 78f21fd05..3a7b5ed93 100644 --- a/test/cli/transports_test.go +++ b/test/cli/transports_test.go @@ -1,6 +1,7 @@ package cli import ( + "fmt" "os" "path/filepath" "testing" @@ -124,4 +125,26 @@ func TestTransports(t *testing.T) { runTests(nodes) }) + t.Run("QUIC connects with non-dialable transports", func(t *testing.T) { + // This test targets specific Kubo internals which may change later. This checks + // if we can announce an address we do not listen on, and then are able to connect + // via a different address that is available. + t.Parallel() + nodes := harness.NewT(t).NewNodes(5).Init() + nodes.ForEachPar(func(n *harness.Node) { + n.UpdateConfig(func(cfg *config.Config) { + // We need a specific port to announce so we first generate a random port. + // We can't use 0 here to automatically assign an available port because + // that would only work with Swarm, but not for the announcing. + port := harness.NewRandPort() + quicAddr := fmt.Sprintf("/ip4/127.0.0.1/udp/%d/quic-v1", port) + cfg.Addresses.Swarm = []string{quicAddr} + cfg.Addresses.Announce = []string{quicAddr, quicAddr + "/webtransport"} + }) + }) + disableRouting(nodes) + nodes.StartDaemons().Connect() + runTests(nodes) + }) + } From c39b8052ea39132b230cbffe0b0942956a605b4d Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Tue, 9 May 2023 10:59:05 +0200 Subject: [PATCH 0653/1212] chore: update go-libp2p to v0.27.3 (#9862) --- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 3c35f0e84..6a54fcad3 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -9,7 +9,7 @@ replace github.com/ipfs/kubo => ./../../.. require ( github.com/ipfs/boxo v0.8.2-0.20230503105907-8059f183d866 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 - github.com/libp2p/go-libp2p v0.27.2 + github.com/libp2p/go-libp2p v0.27.3 github.com/multiformats/go-multiaddr v0.9.0 ) diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index c3ccc9ae3..1ac6f8afd 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -489,8 +489,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.27.2 h1:I1fxqxdm/O0TFoAZKje8wSMu9tfLlLdzTQvgT3HA6v0= -github.com/libp2p/go-libp2p v0.27.2/go.mod h1:FAvvfQa/YOShUYdiSS03IR9OXzkcJXwcNA2FUCh9ImE= +github.com/libp2p/go-libp2p v0.27.3 h1:tkV/zm3KCZ4R5er9Xcs2pt0YNB4JH0iBfGAtHJdLHRs= +github.com/libp2p/go-libp2p v0.27.3/go.mod h1:FAvvfQa/YOShUYdiSS03IR9OXzkcJXwcNA2FUCh9ImE= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= diff --git a/go.mod b/go.mod index 6cb0108d8..95f326b14 100644 --- a/go.mod +++ b/go.mod @@ -45,7 +45,7 @@ require ( github.com/jbenet/goprocess v0.1.4 github.com/julienschmidt/httprouter v1.3.0 github.com/libp2p/go-doh-resolver v0.4.0 - github.com/libp2p/go-libp2p v0.27.2 + github.com/libp2p/go-libp2p v0.27.3 github.com/libp2p/go-libp2p-http v0.5.0 github.com/libp2p/go-libp2p-kad-dht v0.23.0 github.com/libp2p/go-libp2p-kbucket v0.5.0 diff --git a/go.sum b/go.sum index e136c5c00..6eaf0919e 100644 --- a/go.sum +++ b/go.sum @@ -540,8 +540,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.27.2 h1:I1fxqxdm/O0TFoAZKje8wSMu9tfLlLdzTQvgT3HA6v0= -github.com/libp2p/go-libp2p v0.27.2/go.mod h1:FAvvfQa/YOShUYdiSS03IR9OXzkcJXwcNA2FUCh9ImE= +github.com/libp2p/go-libp2p v0.27.3 h1:tkV/zm3KCZ4R5er9Xcs2pt0YNB4JH0iBfGAtHJdLHRs= +github.com/libp2p/go-libp2p v0.27.3/go.mod h1:FAvvfQa/YOShUYdiSS03IR9OXzkcJXwcNA2FUCh9ImE= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= From 45b31600d841d69e5129a37c1f2f7e5599b508bf Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Tue, 9 May 2023 09:12:56 +0000 Subject: [PATCH 0654/1212] chore: update version --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index 7c1681bf0..86ac8dbf4 100644 --- a/version.go +++ b/version.go @@ -11,7 +11,7 @@ import ( var CurrentCommit string // CurrentVersionNumber is the current application's version literal -const CurrentVersionNumber = "0.20.0-rc2" +const CurrentVersionNumber = "0.20.0" const ApiVersion = "/kubo/" + CurrentVersionNumber + "/" //nolint From 9482d7529233ff8942601a875c705fac55376c06 Mon Sep 17 00:00:00 2001 From: Gus Eggert Date: Mon, 1 May 2023 15:29:34 -0400 Subject: [PATCH 0655/1212] fix: use default HTTP routers when FullRT DHT client is used (#9841) --- cmd/ipfs/daemon.go | 14 ++------- core/node/groups.go | 2 +- core/node/libp2p/routing.go | 47 ++++++++++++++++++----------- core/node/libp2p/routingopt.go | 55 ++++++++++++++++++++-------------- 4 files changed, 65 insertions(+), 53 deletions(-) diff --git a/cmd/ipfs/daemon.go b/cmd/ipfs/daemon.go index ffcb30a34..1e03a8264 100644 --- a/cmd/ipfs/daemon.go +++ b/cmd/ipfs/daemon.go @@ -413,19 +413,9 @@ func daemonFunc(req *cmds.Request, re cmds.ResponseEmitter, env cmds.Environment case routingOptionSupernodeKwd: return errors.New("supernode routing was never fully implemented and has been removed") case routingOptionDefaultKwd, routingOptionAutoKwd: - ncfg.Routing = libp2p.ConstructDefaultRouting( - cfg.Identity.PeerID, - cfg.Addresses.Swarm, - cfg.Identity.PrivKey, - libp2p.DHTOption, - ) + ncfg.Routing = libp2p.ConstructDefaultRouting(cfg, libp2p.DHTOption) case routingOptionAutoClientKwd: - ncfg.Routing = libp2p.ConstructDefaultRouting( - cfg.Identity.PeerID, - cfg.Addresses.Swarm, - cfg.Identity.PrivKey, - libp2p.DHTClientOption, - ) + ncfg.Routing = libp2p.ConstructDefaultRouting(cfg, libp2p.DHTClientOption) case routingOptionDHTClientKwd: ncfg.Routing = libp2p.DHTClientOption case routingOptionDHTKwd: diff --git a/core/node/groups.go b/core/node/groups.go index 0b1660265..ae8ce8539 100644 --- a/core/node/groups.go +++ b/core/node/groups.go @@ -165,7 +165,7 @@ func LibP2P(bcfg *BuildCfg, cfg *config.Config, userResourceOverrides rcmgr.Part fx.Provide(libp2p.Routing), fx.Provide(libp2p.ContentRouting), - fx.Provide(libp2p.BaseRouting(cfg.Experimental.AcceleratedDHTClient)), + fx.Provide(libp2p.BaseRouting(cfg)), maybeProvide(libp2p.PubsubRouter, bcfg.getOpt("ipnsps")), maybeProvide(libp2p.BandwidthCounter, !cfg.Swarm.DisableBandwidthMetrics), diff --git a/core/node/libp2p/routing.go b/core/node/libp2p/routing.go index f96f772e1..2e356e447 100644 --- a/core/node/libp2p/routing.go +++ b/core/node/libp2p/routing.go @@ -63,35 +63,34 @@ type processInitialRoutingOut struct { type AddrInfoChan chan peer.AddrInfo -func BaseRouting(experimentalDHTClient bool) interface{} { +func BaseRouting(cfg *config.Config) interface{} { return func(lc fx.Lifecycle, in processInitialRoutingIn) (out processInitialRoutingOut, err error) { - var dr *ddht.DHT + var dualDHT *ddht.DHT if dht, ok := in.Router.(*ddht.DHT); ok { - dr = dht + dualDHT = dht lc.Append(fx.Hook{ OnStop: func(ctx context.Context) error { - return dr.Close() + return dualDHT.Close() }, }) } - if pr, ok := in.Router.(routinghelpers.ComposableRouter); ok { - for _, r := range pr.Routers() { + if cr, ok := in.Router.(routinghelpers.ComposableRouter); ok { + for _, r := range cr.Routers() { if dht, ok := r.(*ddht.DHT); ok { - dr = dht + dualDHT = dht lc.Append(fx.Hook{ OnStop: func(ctx context.Context) error { - return dr.Close() + return dualDHT.Close() }, }) - break } } } - if dr != nil && experimentalDHTClient { + if dualDHT != nil && cfg.Experimental.AcceleratedDHTClient { cfg, err := in.Repo.Config() if err != nil { return out, err @@ -101,7 +100,7 @@ func BaseRouting(experimentalDHTClient bool) interface{} { return out, err } - expClient, err := fullrt.NewFullRT(in.Host, + fullRTClient, err := fullrt.NewFullRT(in.Host, dht.DefaultPrefix, fullrt.DHTOption( dht.Validator(in.Validator), @@ -116,18 +115,30 @@ func BaseRouting(experimentalDHTClient bool) interface{} { lc.Append(fx.Hook{ OnStop: func(ctx context.Context) error { - return expClient.Close() + return fullRTClient.Close() }, }) + // we want to also use the default HTTP routers, so wrap the FullRT client + // in a parallel router that calls them in parallel + httpRouters, err := constructDefaultHTTPRouters(cfg) + if err != nil { + return out, err + } + routers := []*routinghelpers.ParallelRouter{ + {Router: fullRTClient}, + } + routers = append(routers, httpRouters...) + router := routinghelpers.NewComposableParallel(routers) + return processInitialRoutingOut{ Router: Router{ - Routing: expClient, Priority: 1000, + Routing: router, }, - DHT: dr, - DHTClient: expClient, - ContentRouter: expClient, + DHT: dualDHT, + DHTClient: fullRTClient, + ContentRouter: fullRTClient, }, nil } @@ -136,8 +147,8 @@ func BaseRouting(experimentalDHTClient bool) interface{} { Priority: 1000, Routing: in.Router, }, - DHT: dr, - DHTClient: dr, + DHT: dualDHT, + DHTClient: dualDHT, ContentRouter: in.Router, }, nil } diff --git a/core/node/libp2p/routingopt.go b/core/node/libp2p/routingopt.go index 1d47ae273..b363f25b7 100644 --- a/core/node/libp2p/routingopt.go +++ b/core/node/libp2p/routingopt.go @@ -43,8 +43,35 @@ func init() { } } +func constructDefaultHTTPRouters(cfg *config.Config) ([]*routinghelpers.ParallelRouter, error) { + var routers []*routinghelpers.ParallelRouter + // Append HTTP routers for additional speed + for _, endpoint := range defaultHTTPRouters { + httpRouter, err := irouting.ConstructHTTPRouter(endpoint, cfg.Identity.PeerID, cfg.Addresses.Swarm, cfg.Identity.PrivKey) + if err != nil { + return nil, err + } + + r := &irouting.Composer{ + GetValueRouter: routinghelpers.Null{}, + PutValueRouter: routinghelpers.Null{}, + ProvideRouter: routinghelpers.Null{}, // modify this when indexers supports provide + FindPeersRouter: routinghelpers.Null{}, + FindProvidersRouter: httpRouter, + } + + routers = append(routers, &routinghelpers.ParallelRouter{ + Router: r, + IgnoreError: true, // https://github.com/ipfs/kubo/pull/9475#discussion_r1042507387 + Timeout: 15 * time.Second, // 5x server value from https://github.com/ipfs/kubo/pull/9475#discussion_r1042428529 + ExecuteAfter: 0, + }) + } + return routers, nil +} + // ConstructDefaultRouting returns routers used when Routing.Type is unset or set to "auto" -func ConstructDefaultRouting(peerID string, addrs []string, privKey string, routingOpt RoutingOption) RoutingOption { +func ConstructDefaultRouting(cfg *config.Config, routingOpt RoutingOption) RoutingOption { return func(args RoutingOptionArgs) (routing.Routing, error) { // Defined routers will be queried in parallel (optimizing for response speed) // Different trade-offs can be made by setting Routing.Type = "custom" with own Routing.Routers @@ -60,29 +87,13 @@ func ConstructDefaultRouting(peerID string, addrs []string, privKey string, rout ExecuteAfter: 0, }) - // Append HTTP routers for additional speed - for _, endpoint := range defaultHTTPRouters { - httpRouter, err := irouting.ConstructHTTPRouter(endpoint, peerID, addrs, privKey) - if err != nil { - return nil, err - } - - r := &irouting.Composer{ - GetValueRouter: routinghelpers.Null{}, - PutValueRouter: routinghelpers.Null{}, - ProvideRouter: routinghelpers.Null{}, // modify this when indexers supports provide - FindPeersRouter: routinghelpers.Null{}, - FindProvidersRouter: httpRouter, - } - - routers = append(routers, &routinghelpers.ParallelRouter{ - Router: r, - IgnoreError: true, // https://github.com/ipfs/kubo/pull/9475#discussion_r1042507387 - Timeout: 15 * time.Second, // 5x server value from https://github.com/ipfs/kubo/pull/9475#discussion_r1042428529 - ExecuteAfter: 0, - }) + httpRouters, err := constructDefaultHTTPRouters(cfg) + if err != nil { + return nil, err } + routers = append(routers, httpRouters...) + routing := routinghelpers.NewComposableParallel(routers) return routing, nil } From b4504be54c6f7265aa5473f5432b801b84c5dec4 Mon Sep 17 00:00:00 2001 From: Russell Dempsey <1173416+SgtPooki@users.noreply.github.com> Date: Tue, 2 May 2023 04:16:52 -0700 Subject: [PATCH 0656/1212] feat: webui@3.0.0 (#9835) --- core/corehttp/webui.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/corehttp/webui.go b/core/corehttp/webui.go index f7b27c939..9b7cf776d 100644 --- a/core/corehttp/webui.go +++ b/core/corehttp/webui.go @@ -1,11 +1,12 @@ package corehttp // TODO: move to IPNS -const WebUIPath = "/ipfs/bafybeifeqt7mvxaniphyu2i3qhovjaf3sayooxbh5enfdqtiehxjv2ldte" // v2.22.0 +const WebUIPath = "/ipfs/bafybeic4gops3d3lyrisqku37uio33nvt6fqxvkxihrwlqsuvf76yln4fm" // v3.0.0 // WebUIPaths is a list of all past webUI paths. var WebUIPaths = []string{ WebUIPath, + "/ipfs/bafybeifeqt7mvxaniphyu2i3qhovjaf3sayooxbh5enfdqtiehxjv2ldte", "/ipfs/bafybeiequgo72mrvuml56j4gk7crewig5bavumrrzhkqbim6b3s2yqi7ty", "/ipfs/bafybeibjbq3tmmy7wuihhhwvbladjsd3gx3kfjepxzkq6wylik6wc3whzy", "/ipfs/bafybeiavrvt53fks6u32n5p2morgblcmck4bh4ymf4rrwu7ah5zsykmqqa", From d2c578878faf63ec2633788c2424e5b24edfbbf4 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Wed, 3 May 2023 09:00:41 +0200 Subject: [PATCH 0657/1212] docs: add changelog for v0.19.2 --- docs/changelogs/v0.19.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/docs/changelogs/v0.19.md b/docs/changelogs/v0.19.md index 1abc2e518..f7e190a7e 100644 --- a/docs/changelogs/v0.19.md +++ b/docs/changelogs/v0.19.md @@ -1,6 +1,33 @@ # Kubo changelog v0.19 +## v0.19.2 + +### Highlights + +#### FullRT DHT HTTP Routers + +The default HTTP routers are now used when the FullRT DHT client is used. This fixes +the issue where cid.contact is not being queried by default when the accelerated +DHT client was enabled. Read more in ([ipfs/kubo#9841](https://github.com/ipfs/kubo/pull/9841)). + +### Changelog + +
    Full Changelog + +- github.com/ipfs/kubo: + - fix: use default HTTP routers when FullRT DHT client is used (#9841) ([ipfs/kubo#9841](https://github.com/ipfs/kubo/pull/9841)) + - chore: update version + +
    + +### Contributors + +| Contributor | Commits | Lines ± | Files Changed | +|-------------|---------|---------|---------------| +| Gus Eggert | 1 | +65/-53 | 4 | +| Henrique Dias | 1 | +1/-1 | 1 | + ## v0.19.1 ### 🔦 Highlights From d1b0083d604e0a4b46bcdc17f03b950744b9bc55 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Wed, 3 May 2023 09:08:04 +0200 Subject: [PATCH 0658/1212] Merge pull request #9847 from ipfs/release-v0.19.2 Release: v0.19.2 From 5f5c16e2cc7a42ca64f2ad31bd46591a5a345c79 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Wed, 3 May 2023 12:57:21 +0200 Subject: [PATCH 0659/1212] Merge branch 'master' into merge-release-v0.19.2 --- .github/CODEOWNERS | 3 + test/cli/testutils/random_files.go | 116 ++++++++++++ test/cli/transports_test.go | 127 +++++++++++++ test/ipfs-test-lib.sh | 12 +- ...-docker-image.sh => t0002-docker-image.sh} | 16 +- ...ker-migrate.sh => t0003-docker-migrate.sh} | 9 +- test/sharness/t0125-twonode.sh | 178 ------------------ test/sharness/t0130-multinode.sh | 115 ----------- 8 files changed, 261 insertions(+), 315 deletions(-) create mode 100644 test/cli/testutils/random_files.go create mode 100644 test/cli/transports_test.go rename test/sharness/{t0300-docker-image.sh => t0002-docker-image.sh} (87%) rename test/sharness/{t0301-docker-migrate.sh => t0003-docker-migrate.sh} (92%) delete mode 100755 test/sharness/t0125-twonode.sh delete mode 100755 test/sharness/t0130-multinode.sh diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 5151ad178..7d17855e0 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -2,6 +2,9 @@ # request that modifies code that they own. Code owners are not automatically # requested to review draft pull requests. +# Default +* @ipfs/kubo-maintainers + # HTTP Gateway core/corehttp/ @lidel test/sharness/*gateway*.sh @lidel diff --git a/test/cli/testutils/random_files.go b/test/cli/testutils/random_files.go new file mode 100644 index 000000000..0e550a125 --- /dev/null +++ b/test/cli/testutils/random_files.go @@ -0,0 +1,116 @@ +package testutils + +import ( + "fmt" + "io" + "math/rand" + "os" + "path" + "time" +) + +var AlphabetEasy = []rune("abcdefghijklmnopqrstuvwxyz01234567890-_") +var AlphabetHard = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890!@#$%^&*()-_+= ;.,<>'\"[]{}() ") + +type RandFiles struct { + Rand *rand.Rand + FileSize int // the size per file. + FilenameSize int + Alphabet []rune // for filenames + + FanoutDepth int // how deep the hierarchy goes + FanoutFiles int // how many files per dir + FanoutDirs int // how many dirs per dir + + RandomSize bool // randomize file sizes + RandomFanout bool // randomize fanout numbers +} + +func NewRandFiles() *RandFiles { + return &RandFiles{ + Rand: rand.New(rand.NewSource(time.Now().UnixNano())), + FileSize: 4096, + FilenameSize: 16, + Alphabet: AlphabetEasy, + FanoutDepth: 2, + FanoutDirs: 5, + FanoutFiles: 10, + RandomSize: true, + } +} + +func (r *RandFiles) WriteRandomFiles(root string, depth int) error { + numfiles := r.FanoutFiles + if r.RandomFanout { + numfiles = rand.Intn(r.FanoutFiles) + 1 + } + + for i := 0; i < numfiles; i++ { + if err := r.WriteRandomFile(root); err != nil { + return err + } + } + + if depth+1 <= r.FanoutDepth { + numdirs := r.FanoutDirs + if r.RandomFanout { + numdirs = r.Rand.Intn(numdirs) + 1 + } + + for i := 0; i < numdirs; i++ { + if err := r.WriteRandomDir(root, depth+1); err != nil { + return err + } + } + } + + return nil +} + +func (r *RandFiles) RandomFilename(length int) string { + b := make([]rune, length) + for i := range b { + b[i] = r.Alphabet[r.Rand.Intn(len(r.Alphabet))] + } + return string(b) +} + +func (r *RandFiles) WriteRandomFile(root string) error { + filesize := int64(r.FileSize) + if r.RandomSize { + filesize = r.Rand.Int63n(filesize) + 1 + } + + n := rand.Intn(r.FilenameSize-4) + 4 + name := r.RandomFilename(n) + filepath := path.Join(root, name) + f, err := os.Create(filepath) + if err != nil { + return fmt.Errorf("creating random file: %w", err) + } + + if _, err := io.CopyN(f, r.Rand, filesize); err != nil { + return fmt.Errorf("copying random file: %w", err) + } + + return f.Close() +} + +func (r *RandFiles) WriteRandomDir(root string, depth int) error { + if depth > r.FanoutDepth { + return nil + } + + n := rand.Intn(r.FilenameSize-4) + 4 + name := r.RandomFilename(n) + root = path.Join(root, name) + if err := os.MkdirAll(root, 0755); err != nil { + return fmt.Errorf("creating random dir: %w", err) + } + + err := r.WriteRandomFiles(root, depth) + if err != nil { + return fmt.Errorf("writing random files in random dir: %w", err) + } + return nil +} diff --git a/test/cli/transports_test.go b/test/cli/transports_test.go new file mode 100644 index 000000000..78f21fd05 --- /dev/null +++ b/test/cli/transports_test.go @@ -0,0 +1,127 @@ +package cli + +import ( + "os" + "path/filepath" + "testing" + + "github.com/ipfs/kubo/config" + "github.com/ipfs/kubo/test/cli/harness" + "github.com/ipfs/kubo/test/cli/testutils" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestTransports(t *testing.T) { + disableRouting := func(nodes harness.Nodes) { + nodes.ForEachPar(func(n *harness.Node) { + n.UpdateConfig(func(cfg *config.Config) { + cfg.Routing.Type = config.NewOptionalString("none") + cfg.Bootstrap = nil + }) + }) + } + checkSingleFile := func(nodes harness.Nodes) { + s := testutils.RandomStr(100) + hash := nodes[0].IPFSAddStr(s) + nodes.ForEachPar(func(n *harness.Node) { + val := n.IPFS("cat", hash).Stdout.String() + assert.Equal(t, s, val) + }) + } + checkRandomDir := func(nodes harness.Nodes) { + randDir := filepath.Join(nodes[0].Dir, "foobar") + require.NoError(t, os.Mkdir(randDir, 0777)) + rf := testutils.NewRandFiles() + rf.FanoutDirs = 3 + rf.FanoutFiles = 6 + require.NoError(t, rf.WriteRandomFiles(randDir, 4)) + + hash := nodes[1].IPFS("add", "-r", "-Q", randDir).Stdout.Trimmed() + nodes.ForEachPar(func(n *harness.Node) { + res := n.RunIPFS("refs", "-r", hash) + assert.Equal(t, 0, res.ExitCode()) + }) + } + + runTests := func(nodes harness.Nodes) { + checkSingleFile(nodes) + checkRandomDir(nodes) + } + + tcpNodes := func(t *testing.T) harness.Nodes { + nodes := harness.NewT(t).NewNodes(2).Init() + nodes.ForEachPar(func(n *harness.Node) { + n.UpdateConfig(func(cfg *config.Config) { + cfg.Addresses.Swarm = []string{"/ip4/127.0.0.1/tcp/0"} + cfg.Swarm.Transports.Network.QUIC = config.False + cfg.Swarm.Transports.Network.Relay = config.False + cfg.Swarm.Transports.Network.WebTransport = config.False + cfg.Swarm.Transports.Network.Websocket = config.False + }) + }) + disableRouting(nodes) + return nodes + } + + t.Run("tcp", func(t *testing.T) { + t.Parallel() + nodes := tcpNodes(t).StartDaemons().Connect() + runTests(nodes) + }) + + t.Run("tcp with mplex", func(t *testing.T) { + t.Parallel() + nodes := tcpNodes(t) + nodes.ForEachPar(func(n *harness.Node) { + n.UpdateConfig(func(cfg *config.Config) { + cfg.Swarm.Transports.Multiplexers.Yamux = config.Disabled + }) + }) + nodes.StartDaemons().Connect() + runTests(nodes) + }) + + t.Run("tcp with NOISE", func(t *testing.T) { + t.Parallel() + nodes := tcpNodes(t) + nodes.ForEachPar(func(n *harness.Node) { + n.UpdateConfig(func(cfg *config.Config) { + cfg.Swarm.Transports.Security.TLS = config.Disabled + }) + }) + nodes.StartDaemons().Connect() + runTests(nodes) + }) + + t.Run("QUIC", func(t *testing.T) { + t.Parallel() + nodes := harness.NewT(t).NewNodes(5).Init() + nodes.ForEachPar(func(n *harness.Node) { + n.UpdateConfig(func(cfg *config.Config) { + cfg.Addresses.Swarm = []string{"/ip4/127.0.0.1/udp/0/quic-v1"} + cfg.Swarm.Transports.Network.QUIC = config.True + cfg.Swarm.Transports.Network.TCP = config.False + }) + }) + disableRouting(nodes) + nodes.StartDaemons().Connect() + runTests(nodes) + }) + + t.Run("QUIC", func(t *testing.T) { + t.Parallel() + nodes := harness.NewT(t).NewNodes(5).Init() + nodes.ForEachPar(func(n *harness.Node) { + n.UpdateConfig(func(cfg *config.Config) { + cfg.Addresses.Swarm = []string{"/ip4/127.0.0.1/udp/0/quic-v1/webtransport"} + cfg.Swarm.Transports.Network.QUIC = config.True + cfg.Swarm.Transports.Network.WebTransport = config.True + }) + }) + disableRouting(nodes) + nodes.StartDaemons().Connect() + runTests(nodes) + }) + +} diff --git a/test/ipfs-test-lib.sh b/test/ipfs-test-lib.sh index eabf17020..a3bc32bbb 100644 --- a/test/ipfs-test-lib.sh +++ b/test/ipfs-test-lib.sh @@ -50,19 +50,19 @@ test_path_cmp() { # Docker -# This takes a Dockerfile, and a build context directory +# This takes a Dockerfile, a tag name, and a build context directory docker_build() { - docker build --rm -f "$1" "$2" | ansi_strip + docker build --rm --tag "$1" --file "$2" "$3" | ansi_strip } # This takes an image as argument and writes a docker ID on stdout docker_run() { - docker run -d "$1" + docker run --detach "$1" } # This takes a docker ID and a command as arguments docker_exec() { - docker exec -t "$1" /bin/sh -c "$2" + docker exec --tty "$1" /bin/sh -c "$2" } # This takes a docker ID as argument @@ -72,12 +72,12 @@ docker_stop() { # This takes a docker ID as argument docker_rm() { - docker rm -f -v "$1" > /dev/null + docker rm --force --volumes "$1" > /dev/null } # This takes a docker image name as argument docker_rmi() { - docker rmi -f "$1" > /dev/null + docker rmi --force "$1" > /dev/null } # Test whether all the expected lines are included in a file. The file diff --git a/test/sharness/t0300-docker-image.sh b/test/sharness/t0002-docker-image.sh similarity index 87% rename from test/sharness/t0300-docker-image.sh rename to test/sharness/t0002-docker-image.sh index 3c390a453..11ccf01b7 100755 --- a/test/sharness/t0300-docker-image.sh +++ b/test/sharness/t0002-docker-image.sh @@ -27,18 +27,12 @@ TEST_TRASH_DIR=$(pwd) TEST_SCRIPTS_DIR=$(dirname "$TEST_TRASH_DIR") TEST_TESTS_DIR=$(dirname "$TEST_SCRIPTS_DIR") APP_ROOT_DIR=$(dirname "$TEST_TESTS_DIR") +IMAGE_TAG=kubo_test test_expect_success "docker image build succeeds" ' - docker_build "$TEST_TESTS_DIR/../Dockerfile" "$APP_ROOT_DIR" | tee build-actual || + docker_build "$IMAGE_TAG" "$TEST_TESTS_DIR/../Dockerfile" "$APP_ROOT_DIR" || test_fsh echo "TEST_TESTS_DIR: $TEST_TESTS_DIR" || - test_fsh echo "APP_ROOT_DIR : $APP_ROOT_DIR" || - test_fsh cat build-actual -' - -test_expect_success "docker image build output looks good" ' - SUCCESS_LINE=$(egrep "^Successfully built" build-actual) && - IMAGE_ID=$(expr "$SUCCESS_LINE" : "^Successfully built \(.*\)") || - test_fsh cat build-actual + test_fsh echo "APP_ROOT_DIR : $APP_ROOT_DIR" ' test_expect_success "write init scripts" ' @@ -52,7 +46,7 @@ test_expect_success "docker image runs" ' -p 127.0.0.1:5001:5001 -p 127.0.0.1:8080:8080 \ -v "$PWD/001.sh":/container-init.d/001.sh \ -v "$PWD/002.sh":/container-init.d/002.sh \ - "$IMAGE_ID") + "$IMAGE_TAG") ' test_expect_success "docker container gateway is up" ' @@ -100,5 +94,5 @@ test_expect_success "stop docker container" ' ' docker_rm "$DOC_ID" -docker_rmi "$IMAGE_ID" +docker_rmi "$IMAGE_TAG" test_done diff --git a/test/sharness/t0301-docker-migrate.sh b/test/sharness/t0003-docker-migrate.sh similarity index 92% rename from test/sharness/t0301-docker-migrate.sh rename to test/sharness/t0003-docker-migrate.sh index 3f7d32f21..ac3c7aee2 100755 --- a/test/sharness/t0301-docker-migrate.sh +++ b/test/sharness/t0003-docker-migrate.sh @@ -24,10 +24,10 @@ TEST_TRASH_DIR=$(pwd) TEST_SCRIPTS_DIR=$(dirname "$TEST_TRASH_DIR") TEST_TESTS_DIR=$(dirname "$TEST_SCRIPTS_DIR") APP_ROOT_DIR=$(dirname "$TEST_TESTS_DIR") +IMAGE_TAG=kubo_migrate test_expect_success "docker image build succeeds" ' - docker_build "$TEST_TESTS_DIR/../Dockerfile" "$APP_ROOT_DIR" >actual && - IMAGE_ID=$(tail -n1 actual | cut -d " " -f 3) + docker_build "$IMAGE_TAG" "$TEST_TESTS_DIR/../Dockerfile" "$APP_ROOT_DIR" ' test_init_ipfs @@ -53,7 +53,7 @@ test_expect_success "startup fake dists server" ' ' test_expect_success "docker image runs" ' - DOC_ID=$(docker run -d -v "$IPFS_PATH":/data/ipfs --net=host "$IMAGE_ID") + DOC_ID=$(docker run -d -v "$IPFS_PATH":/data/ipfs --net=host "$IMAGE_TAG") ' test_expect_success "docker container tries to pull migrations from netcat" ' @@ -78,6 +78,5 @@ test_expect_success "correct version was requested" ' ' docker_rm "$DOC_ID" -docker_rmi "$IMAGE_ID" +docker_rmi "$IMAGE_TAG" test_done - diff --git a/test/sharness/t0125-twonode.sh b/test/sharness/t0125-twonode.sh deleted file mode 100755 index 8ea1c9e5d..000000000 --- a/test/sharness/t0125-twonode.sh +++ /dev/null @@ -1,178 +0,0 @@ -#!/usr/bin/env bash -# -# Copyright (c) 2017 Jeromy Johnson -# MIT Licensed; see the LICENSE file in this repository. -# - -test_description="Test two ipfs nodes transferring a file" - -. lib/test-lib.sh - -check_file_fetch() { - node=$1 - fhash=$2 - fname=$3 - - test_expect_success "can fetch file" ' - ipfsi $node cat $fhash > fetch_out - ' - - test_expect_success "file looks good" ' - test_cmp $fname fetch_out - ' -} - -check_dir_fetch() { - node=$1 - ref=$2 - - test_expect_success "node can fetch all refs for dir" ' - ipfsi $node refs -r $ref > /dev/null - ' -} - -run_single_file_test() { - test_expect_success "add a file on node1" ' - random 1000000 > filea && - FILEA_HASH=$(ipfsi 1 add -q filea) - ' - - check_file_fetch 0 $FILEA_HASH filea -} - -run_random_dir_test() { - test_expect_success "create a bunch of random files" ' - random-files -depth=3 -dirs=4 -files=5 -seed=5 foobar > /dev/null - ' - - test_expect_success "add those on node 0" ' - DIR_HASH=$(ipfsi 0 add -r -Q foobar) - ' - - check_dir_fetch 1 $DIR_HASH -} - -flaky_advanced_test() { - startup_cluster 2 "$@" - - test_expect_success "clean repo before test" ' - ipfsi 0 repo gc > /dev/null && - ipfsi 1 repo gc > /dev/null - ' - - run_single_file_test - - run_random_dir_test - - test_expect_success "gather bitswap stats" ' - ipfsi 0 bitswap stat -v > stat0 && - ipfsi 1 bitswap stat -v > stat1 - ' - - test_expect_success "shut down nodes" ' - iptb stop && iptb_wait_stop - ' - - # NOTE: data transferred stats checks are flaky - # trying to debug them by printing out the stats hides the flakiness - # my theory is that the extra time cat calls take to print out the stats - # allow for proper cleanup to happen - go-sleep 1s -} - -run_advanced_test() { - # TODO: investigate why flaky_advanced_test is flaky - # Context: https://github.com/ipfs/kubo/pull/9486 - # sometimes, bitswap status returns unexpected block transfers - # and everyone has been re-running circleci until is passes for at least a year. - # this re-runs test until it passes or a timeout hits - - BLOCKS_0=126 - BLOCKS_1=5 - DATA_0=228113 - DATA_1=1000256 - for i in $(test_seq 1 600); do - flaky_advanced_test - (grep -q "$DATA_0" stat0 && grep -q "$DATA_1" stat1) && break - go-sleep 100ms - done - - test_expect_success "node0 data transferred looks correct" ' - test_should_contain "blocks sent: $BLOCKS_0" stat0 && - test_should_contain "blocks received: $BLOCKS_1" stat0 && - test_should_contain "data sent: $DATA_0" stat0 && - test_should_contain "data received: $DATA_1" stat0 - ' - - test_expect_success "node1 data transferred looks correct" ' - test_should_contain "blocks received: $BLOCKS_0" stat1 && - test_should_contain "blocks sent: $BLOCKS_1" stat1 && - test_should_contain "data received: $DATA_0" stat1 && - test_should_contain "data sent: $DATA_1" stat1 - ' - -} - -test_expect_success "set up tcp testbed" ' - iptb testbed create -type localipfs -count 2 -force -init -' - -test_expect_success "disable routing, use direct peering" ' - iptb run -- ipfs config Routing.Type none && - iptb run -- ipfs config --json Bootstrap "[]" -' - -# Test TCP transport -echo "Testing TCP" -addrs='"[\"/ip4/127.0.0.1/tcp/0\"]"' -test_expect_success "use TCP only" ' - iptb run -- ipfs config --json Addresses.Swarm '"${addrs}"' && - iptb run -- ipfs config --json Swarm.Transports.Network.QUIC false && - iptb run -- ipfs config --json Swarm.Transports.Network.Relay false && - iptb run -- ipfs config --json Swarm.Transports.Network.WebTransport false && - iptb run -- ipfs config --json Swarm.Transports.Network.Websocket false -' -run_advanced_test - -# test multiplex muxer -echo "Running TCP tests with mplex" -test_expect_success "disable yamux" ' - iptb run -- ipfs config --json Swarm.Transports.Multiplexers.Yamux false -' -run_advanced_test - -test_expect_success "re-enable yamux" ' - iptb run -- ipfs config --json Swarm.Transports.Multiplexers.Yamux null -' -# test Noise -echo "Running TCP tests with NOISE" -test_expect_success "use noise only" ' - iptb run -- ipfs config --json Swarm.Transports.Security.TLS false -' -run_advanced_test - -test_expect_success "re-enable TLS" ' - iptb run -- ipfs config --json Swarm.Transports.Security.TLS null -' - -# test QUIC -echo "Running advanced tests over QUIC" -addrs='"[\"/ip4/127.0.0.1/udp/0/quic-v1\"]"' -test_expect_success "use QUIC only" ' - iptb run -- ipfs config --json Addresses.Swarm '"${addrs}"' && - iptb run -- ipfs config --json Swarm.Transports.Network.QUIC true && - iptb run -- ipfs config --json Swarm.Transports.Network.TCP false -' -run_advanced_test - -# test WebTransport -echo "Running advanced tests over WebTransport" -addrs='"[\"/ip4/127.0.0.1/udp/0/quic-v1/webtransport\"]"' -test_expect_success "use WebTransport only" ' - iptb run -- ipfs config --json Addresses.Swarm '"${addrs}"' && - iptb run -- ipfs config --json Swarm.Transports.Network.QUIC true && - iptb run -- ipfs config --json Swarm.Transports.Network.WebTransport true -' -run_advanced_test - -test_done diff --git a/test/sharness/t0130-multinode.sh b/test/sharness/t0130-multinode.sh deleted file mode 100755 index 04746850b..000000000 --- a/test/sharness/t0130-multinode.sh +++ /dev/null @@ -1,115 +0,0 @@ -#!/usr/bin/env bash -# -# Copyright (c) 2015 Jeromy Johnson -# MIT Licensed; see the LICENSE file in this repository. -# - -test_description="Test multiple ipfs nodes" - -. lib/test-lib.sh - -check_file_fetch() { - node=$1 - fhash=$2 - fname=$3 - - test_expect_success "can fetch file" ' - ipfsi $node cat $fhash > fetch_out - ' - - test_expect_success "file looks good" ' - test_cmp $fname fetch_out - ' -} - -check_dir_fetch() { - node=$1 - ref=$2 - - test_expect_success "node can fetch all refs for dir" ' - ipfsi $node refs -r $ref > /dev/null - ' -} - -run_single_file_test() { - test_expect_success "add a file on node1" ' - random 1000000 > filea && - FILEA_HASH=$(ipfsi 1 add -q filea) - ' - - check_file_fetch 4 $FILEA_HASH filea - check_file_fetch 3 $FILEA_HASH filea - check_file_fetch 2 $FILEA_HASH filea - check_file_fetch 1 $FILEA_HASH filea - check_file_fetch 0 $FILEA_HASH filea -} - -run_random_dir_test() { - test_expect_success "create a bunch of random files" ' - random-files -depth=4 -dirs=3 -files=6 foobar > /dev/null - ' - - test_expect_success "add those on node 2" ' - DIR_HASH=$(ipfsi 2 add -r -Q foobar) - ' - - check_dir_fetch 0 $DIR_HASH - check_dir_fetch 1 $DIR_HASH - check_dir_fetch 2 $DIR_HASH - check_dir_fetch 3 $DIR_HASH - check_dir_fetch 4 $DIR_HASH -} - - -run_basic_test() { - startup_cluster 5 - - run_single_file_test - - test_expect_success "shut down nodes" ' - iptb stop && iptb_wait_stop - ' -} - -run_advanced_test() { - startup_cluster 5 "$@" - - run_single_file_test - - run_random_dir_test - - test_expect_success "shut down nodes" ' - iptb stop && iptb_wait_stop || - test_fsh tail -n +1 .iptb/testbeds/default/*/daemon.std* - ' -} - -test_expect_success "set up /tcp testbed" ' - iptb testbed create -type localipfs -count 5 -force -init -' - -# test default configuration -run_advanced_test - -# test multiplex muxer -test_expect_success "disable yamux" ' - iptb run -- ipfs config --json Swarm.Transports.Multiplexers.Yamux false -' -run_advanced_test - -test_expect_success "set up /ws testbed" ' - iptb testbed create -type localipfs -count 5 -attr listentype,ws -force -init -' - -# test default configuration -run_advanced_test - -# test multiplex muxer -test_expect_success "disable yamux" ' - iptb run -- ipfs config --json Swarm.Transports.Multiplexers.Yamux false -' - -run_advanced_test - - -test_done From d1c94776bbed16c24b6ec435d1384a531878fda6 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Wed, 3 May 2023 14:15:14 +0200 Subject: [PATCH 0660/1212] Merge pull request #9848 from ipfs/merge-release-v0.19.2 Merge Release: v0.19.2 From 548d082db4b76f2170e34d2de34c7568b627b059 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Mon, 8 May 2023 14:20:51 +0200 Subject: [PATCH 0661/1212] docs(config): remove mentions of relay v1 (#9860) Context: https://github.com/ipfs/interop/pull/592 --- docs/config.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/config.md b/docs/config.md index bb2d8b702..91866a423 100644 --- a/docs/config.md +++ b/docs/config.md @@ -1622,8 +1622,8 @@ Type: `flag` #### `Swarm.RelayClient.StaticRelays` -Your node will use these statically configured relay servers (V1 or V2) -instead of discovering public relays V2 from the network. +Your node will use these statically configured relay servers +instead of discovering public relays ([Circuit Relay v2](https://github.com/libp2p/specs/blob/master/relay/circuit-v2.md)) from the network. Default: `[]` From 8684f05ef376f5971b8df6f67e9aaddccdba5bed Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Mon, 8 May 2023 16:11:03 +0200 Subject: [PATCH 0662/1212] fix: deadlock on retrieving WebTransport addresses (#9857) Co-authored-by: Marco Polo --- core/mock/mock.go | 11 +++++++- core/node/groups.go | 2 +- core/node/libp2p/addrs.go | 38 ++++---------------------- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 +-- go.mod | 2 +- go.sum | 4 +-- test/cli/harness/peering.go | 4 +-- test/cli/transports_test.go | 23 ++++++++++++++++ 9 files changed, 48 insertions(+), 42 deletions(-) diff --git a/core/mock/mock.go b/core/mock/mock.go index 7b718c43e..f9e0876f8 100644 --- a/core/mock/mock.go +++ b/core/mock/mock.go @@ -34,7 +34,16 @@ func NewMockNode() (*core.IpfsNode, error) { } func MockHostOption(mn mocknet.Mocknet) libp2p2.HostOption { - return func(id peer.ID, ps pstore.Peerstore, _ ...libp2p.Option) (host.Host, error) { + return func(id peer.ID, ps pstore.Peerstore, opts ...libp2p.Option) (host.Host, error) { + var cfg libp2p.Config + if err := cfg.Apply(opts...); err != nil { + return nil, err + } + + // The mocknet does not use the provided libp2p.Option. This options include + // the listening addresses we want our peer listening on. Therefore, we have + // to manually parse the configuration and add them here. + ps.AddAddrs(id, cfg.ListenAddrs, pstore.PermanentAddrTTL) return mn.AddPeerWithPeerstore(id, ps) } } diff --git a/core/node/groups.go b/core/node/groups.go index ae8ce8539..548678835 100644 --- a/core/node/groups.go +++ b/core/node/groups.go @@ -155,7 +155,7 @@ func LibP2P(bcfg *BuildCfg, cfg *config.Config, userResourceOverrides rcmgr.Part fx.Provide(libp2p.RelayTransport(enableRelayTransport)), fx.Provide(libp2p.RelayService(enableRelayService, cfg.Swarm.RelayService)), fx.Provide(libp2p.Transports(cfg.Swarm.Transports)), - fx.Invoke(libp2p.StartListening(cfg.Addresses.Swarm)), + fx.Provide(libp2p.ListenOn(cfg.Addresses.Swarm)), fx.Invoke(libp2p.SetupDiscovery(cfg.Discovery.MDNS.Enabled)), fx.Provide(libp2p.ForceReachability(cfg.Internal.Libp2pForceReachability)), fx.Provide(libp2p.HolePunching(cfg.Swarm.EnableHolePunching, enableRelayClient)), diff --git a/core/node/libp2p/addrs.go b/core/node/libp2p/addrs.go index 480b045f8..b287c20ff 100644 --- a/core/node/libp2p/addrs.go +++ b/core/node/libp2p/addrs.go @@ -4,7 +4,6 @@ import ( "fmt" "github.com/libp2p/go-libp2p" - "github.com/libp2p/go-libp2p/core/host" p2pbhost "github.com/libp2p/go-libp2p/p2p/host/basic" ma "github.com/multiformats/go-multiaddr" mamask "github.com/whyrusleeping/multiaddr-filter" @@ -99,37 +98,12 @@ func AddrsFactory(announce []string, appendAnnouce []string, noAnnounce []string } } -func listenAddresses(addresses []string) ([]ma.Multiaddr, error) { - listen := make([]ma.Multiaddr, len(addresses)) - for i, addr := range addresses { - maddr, err := ma.NewMultiaddr(addr) - if err != nil { - return nil, fmt.Errorf("failure to parse config.Addresses.Swarm: %s", addresses) +func ListenOn(addresses []string) interface{} { + return func() (opts Libp2pOpts) { + return Libp2pOpts{ + Opts: []libp2p.Option{ + libp2p.ListenAddrStrings(addresses...), + }, } - listen[i] = maddr - } - - return listen, nil -} - -func StartListening(addresses []string) func(host host.Host) error { - return func(host host.Host) error { - listenAddrs, err := listenAddresses(addresses) - if err != nil { - return err - } - - // Actually start listening: - if err := host.Network().Listen(listenAddrs...); err != nil { - return err - } - - // list out our addresses - addrs, err := host.Network().InterfaceListenAddresses() - if err != nil { - return err - } - log.Infof("Swarm listening at: %s", addrs) - return nil } } diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 6eb1bcb5e..ae1e3b796 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -9,7 +9,7 @@ replace github.com/ipfs/kubo => ./../../.. require ( github.com/ipfs/boxo v0.8.1 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 - github.com/libp2p/go-libp2p v0.27.1 + github.com/libp2p/go-libp2p v0.27.2 github.com/multiformats/go-multiaddr v0.9.0 ) diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 2302548a9..9fc6e5a29 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -489,8 +489,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.27.1 h1:k1u6RHsX3hqKnslDjsSgLNURxJ3O1atIZCY4gpMbbus= -github.com/libp2p/go-libp2p v0.27.1/go.mod h1:FAvvfQa/YOShUYdiSS03IR9OXzkcJXwcNA2FUCh9ImE= +github.com/libp2p/go-libp2p v0.27.2 h1:I1fxqxdm/O0TFoAZKje8wSMu9tfLlLdzTQvgT3HA6v0= +github.com/libp2p/go-libp2p v0.27.2/go.mod h1:FAvvfQa/YOShUYdiSS03IR9OXzkcJXwcNA2FUCh9ImE= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= diff --git a/go.mod b/go.mod index b83143f9b..d9310c7be 100644 --- a/go.mod +++ b/go.mod @@ -45,7 +45,7 @@ require ( github.com/jbenet/goprocess v0.1.4 github.com/julienschmidt/httprouter v1.3.0 github.com/libp2p/go-doh-resolver v0.4.0 - github.com/libp2p/go-libp2p v0.27.1 + github.com/libp2p/go-libp2p v0.27.2 github.com/libp2p/go-libp2p-http v0.5.0 github.com/libp2p/go-libp2p-kad-dht v0.23.0 github.com/libp2p/go-libp2p-kbucket v0.5.0 diff --git a/go.sum b/go.sum index b00e5aed6..8ca1f10b9 100644 --- a/go.sum +++ b/go.sum @@ -540,8 +540,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.27.1 h1:k1u6RHsX3hqKnslDjsSgLNURxJ3O1atIZCY4gpMbbus= -github.com/libp2p/go-libp2p v0.27.1/go.mod h1:FAvvfQa/YOShUYdiSS03IR9OXzkcJXwcNA2FUCh9ImE= +github.com/libp2p/go-libp2p v0.27.2 h1:I1fxqxdm/O0TFoAZKje8wSMu9tfLlLdzTQvgT3HA6v0= +github.com/libp2p/go-libp2p v0.27.2/go.mod h1:FAvvfQa/YOShUYdiSS03IR9OXzkcJXwcNA2FUCh9ImE= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= diff --git a/test/cli/harness/peering.go b/test/cli/harness/peering.go index 3fcd8bb6b..13c3430f0 100644 --- a/test/cli/harness/peering.go +++ b/test/cli/harness/peering.go @@ -13,7 +13,7 @@ type Peering struct { To int } -func newRandPort() int { +func NewRandPort() int { n := rand.Int() return 3000 + (n % 1000) } @@ -24,7 +24,7 @@ func CreatePeerNodes(t *testing.T, n int, peerings []Peering) (*Harness, Nodes) nodes.ForEachPar(func(node *Node) { node.UpdateConfig(func(cfg *config.Config) { cfg.Routing.Type = config.NewOptionalString("none") - cfg.Addresses.Swarm = []string{fmt.Sprintf("/ip4/127.0.0.1/tcp/%d", newRandPort())} + cfg.Addresses.Swarm = []string{fmt.Sprintf("/ip4/127.0.0.1/tcp/%d", NewRandPort())} }) }) diff --git a/test/cli/transports_test.go b/test/cli/transports_test.go index 78f21fd05..3a7b5ed93 100644 --- a/test/cli/transports_test.go +++ b/test/cli/transports_test.go @@ -1,6 +1,7 @@ package cli import ( + "fmt" "os" "path/filepath" "testing" @@ -124,4 +125,26 @@ func TestTransports(t *testing.T) { runTests(nodes) }) + t.Run("QUIC connects with non-dialable transports", func(t *testing.T) { + // This test targets specific Kubo internals which may change later. This checks + // if we can announce an address we do not listen on, and then are able to connect + // via a different address that is available. + t.Parallel() + nodes := harness.NewT(t).NewNodes(5).Init() + nodes.ForEachPar(func(n *harness.Node) { + n.UpdateConfig(func(cfg *config.Config) { + // We need a specific port to announce so we first generate a random port. + // We can't use 0 here to automatically assign an available port because + // that would only work with Swarm, but not for the announcing. + port := harness.NewRandPort() + quicAddr := fmt.Sprintf("/ip4/127.0.0.1/udp/%d/quic-v1", port) + cfg.Addresses.Swarm = []string{quicAddr} + cfg.Addresses.Announce = []string{quicAddr, quicAddr + "/webtransport"} + }) + }) + disableRouting(nodes) + nodes.StartDaemons().Connect() + runTests(nodes) + }) + } From 34653542f6c16a7aac1e77c47ba27ecbc152aebf Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Tue, 9 May 2023 10:59:05 +0200 Subject: [PATCH 0663/1212] chore: update go-libp2p to v0.27.3 (#9862) --- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index ae1e3b796..240bd2402 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -9,7 +9,7 @@ replace github.com/ipfs/kubo => ./../../.. require ( github.com/ipfs/boxo v0.8.1 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 - github.com/libp2p/go-libp2p v0.27.2 + github.com/libp2p/go-libp2p v0.27.3 github.com/multiformats/go-multiaddr v0.9.0 ) diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 9fc6e5a29..c1e617c73 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -489,8 +489,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.27.2 h1:I1fxqxdm/O0TFoAZKje8wSMu9tfLlLdzTQvgT3HA6v0= -github.com/libp2p/go-libp2p v0.27.2/go.mod h1:FAvvfQa/YOShUYdiSS03IR9OXzkcJXwcNA2FUCh9ImE= +github.com/libp2p/go-libp2p v0.27.3 h1:tkV/zm3KCZ4R5er9Xcs2pt0YNB4JH0iBfGAtHJdLHRs= +github.com/libp2p/go-libp2p v0.27.3/go.mod h1:FAvvfQa/YOShUYdiSS03IR9OXzkcJXwcNA2FUCh9ImE= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= diff --git a/go.mod b/go.mod index d9310c7be..be52c6d65 100644 --- a/go.mod +++ b/go.mod @@ -45,7 +45,7 @@ require ( github.com/jbenet/goprocess v0.1.4 github.com/julienschmidt/httprouter v1.3.0 github.com/libp2p/go-doh-resolver v0.4.0 - github.com/libp2p/go-libp2p v0.27.2 + github.com/libp2p/go-libp2p v0.27.3 github.com/libp2p/go-libp2p-http v0.5.0 github.com/libp2p/go-libp2p-kad-dht v0.23.0 github.com/libp2p/go-libp2p-kbucket v0.5.0 diff --git a/go.sum b/go.sum index 8ca1f10b9..cad142edc 100644 --- a/go.sum +++ b/go.sum @@ -540,8 +540,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.27.2 h1:I1fxqxdm/O0TFoAZKje8wSMu9tfLlLdzTQvgT3HA6v0= -github.com/libp2p/go-libp2p v0.27.2/go.mod h1:FAvvfQa/YOShUYdiSS03IR9OXzkcJXwcNA2FUCh9ImE= +github.com/libp2p/go-libp2p v0.27.3 h1:tkV/zm3KCZ4R5er9Xcs2pt0YNB4JH0iBfGAtHJdLHRs= +github.com/libp2p/go-libp2p v0.27.3/go.mod h1:FAvvfQa/YOShUYdiSS03IR9OXzkcJXwcNA2FUCh9ImE= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= From 3a6fa1e2290aea790d4810c755b3f9c05e69b686 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Tue, 9 May 2023 09:31:11 +0000 Subject: [PATCH 0664/1212] chore: update changelog for v0.20 --- docs/changelogs/v0.20.md | 472 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 472 insertions(+) diff --git a/docs/changelogs/v0.20.md b/docs/changelogs/v0.20.md index 590ef5453..3a6ce8f64 100644 --- a/docs/changelogs/v0.20.md +++ b/docs/changelogs/v0.20.md @@ -116,6 +116,478 @@ You can read more about the rationale behind this decision on the [tracking issu ### 📝 Changelog +
    Full Changelog + +- github.com/ipfs/kubo: + - fix: deadlock on retrieving WebTransport addresses (#9857) ([ipfs/kubo#9857](https://github.com/ipfs/kubo/pull/9857)) + - docs(config): remove mentions of relay v1 (#9860) ([ipfs/kubo#9860](https://github.com/ipfs/kubo/pull/9860)) + - Merge branch 'master' into merge-release-v0.19.2 + - docs: add changelog for v0.19.2 + - feat: webui@3.0.0 (#9835) ([ipfs/kubo#9835](https://github.com/ipfs/kubo/pull/9835)) + - fix: use default HTTP routers when FullRT DHT client is used (#9841) ([ipfs/kubo#9841](https://github.com/ipfs/kubo/pull/9841)) + - chore: update version + - docs: add `ipfs pubsub` deprecation reminder to changelog (#9827) ([ipfs/kubo#9827](https://github.com/ipfs/kubo/pull/9827)) + - docs: preparing 0.20 changelog for release (#9799) ([ipfs/kubo#9799](https://github.com/ipfs/kubo/pull/9799)) + - feat: boxo tracing and traceparent support (#9811) ([ipfs/kubo#9811](https://github.com/ipfs/kubo/pull/9811)) + - chore: update version + - chore: update version + - update go-libp2p to v0.27.0 + - docs: add optimistic provide feature description + - feat: add experimental optimistic provide + - fix(ci): speed up docker build (#9800) ([ipfs/kubo#9800](https://github.com/ipfs/kubo/pull/9800)) + - feat(tracing): use OTEL_PROPAGATORS as per OTel spec (#9801) ([ipfs/kubo#9801](https://github.com/ipfs/kubo/pull/9801)) + - docs: fix jaeger command (#9797) ([ipfs/kubo#9797](https://github.com/ipfs/kubo/pull/9797)) + - Merge Release: v0.19.1 (#9794) ([ipfs/kubo#9794](https://github.com/ipfs/kubo/pull/9794)) + - chore: upgrade OpenTelemetry dependencies (#9736) ([ipfs/kubo#9736](https://github.com/ipfs/kubo/pull/9736)) + - test: fix flaky content routing over HTTP test (#9772) ([ipfs/kubo#9772](https://github.com/ipfs/kubo/pull/9772)) + - feat: allow injecting custom path resolvers (#9750) ([ipfs/kubo#9750](https://github.com/ipfs/kubo/pull/9750)) + - feat: add changelog entry for router timeouts for v0.19.1 (#9784) ([ipfs/kubo#9784](https://github.com/ipfs/kubo/pull/9784)) + - feat(gw): new metrics and HTTP range support (#9786) ([ipfs/kubo#9786](https://github.com/ipfs/kubo/pull/9786)) + - feat!: make --empty-repo default (#9758) ([ipfs/kubo#9758](https://github.com/ipfs/kubo/pull/9758)) + - fix: remove timeout on default DHT operations (#9783) ([ipfs/kubo#9783](https://github.com/ipfs/kubo/pull/9783)) + - refactor: switch gateway code to new API from go-libipfs (#9681) ([ipfs/kubo#9681](https://github.com/ipfs/kubo/pull/9681)) + - test: port remote pinning tests to Go (#9720) ([ipfs/kubo#9720](https://github.com/ipfs/kubo/pull/9720)) + - feat: add identify option to swarm peers command + - test: port routing DHT tests to Go (#9709) ([ipfs/kubo#9709](https://github.com/ipfs/kubo/pull/9709)) + - test: fix autoclient flakiness (#9769) ([ipfs/kubo#9769](https://github.com/ipfs/kubo/pull/9769)) + - test: skip flaky pubsub test (#9770) ([ipfs/kubo#9770](https://github.com/ipfs/kubo/pull/9770)) + - chore: migrate go-libipfs to boxo + - feat: add tracing to the commands client + - feat: add client-side metrics for routing-v1 client + - test: increase max wait time for peering assertion + - feat: remove writable gateway (#9743) ([ipfs/kubo#9743](https://github.com/ipfs/kubo/pull/9743)) + - Process Improvement: v0.18.0 ([ipfs/kubo#9484](https://github.com/ipfs/kubo/pull/9484)) + - fix: deadlock while racing `ipfs dag import` and `ipfs repo gc` + - feat: improve dag/import (#9721) ([ipfs/kubo#9721](https://github.com/ipfs/kubo/pull/9721)) + - ci: remove circleci config ([ipfs/kubo#9687](https://github.com/ipfs/kubo/pull/9687)) + - docs: use fx.Decorate instead of fx.Replace in examples (#9725) ([ipfs/kubo#9725](https://github.com/ipfs/kubo/pull/9725)) + - Create Changelog: v0.20 ([ipfs/kubo#9742](https://github.com/ipfs/kubo/pull/9742)) + - Merge Release: v0.19.0 ([ipfs/kubo#9741](https://github.com/ipfs/kubo/pull/9741)) + - feat(gateway): invalid CID returns 400 Bad Request (#9726) ([ipfs/kubo#9726](https://github.com/ipfs/kubo/pull/9726)) + - fix: remove outdated changelog part ([ipfs/kubo#9739](https://github.com/ipfs/kubo/pull/9739)) + - docs: 0.19 changelog ([ipfs/kubo#9707](https://github.com/ipfs/kubo/pull/9707)) + - fix: canonicalize user defined headers + - fix: apply API.HTTPHeaders to /webui redirect + - feat: add heap allocs to 'ipfs diag profile' + - fix: future proof with > rcmgr.DefaultLimit for new enum rcmgr values + - test: add test for presarvation of unlimited configs for inbound systems + - fix: preserve Unlimited StreamsInbound in connmgr reconciliation + - test: fix flaky rcmgr test + - chore: deprecate the pubsub api + - Revert "chore: add hamt directory sharding test" + - chore: add hamt directory sharding test + - test: port peering test from sharness to Go + - test: use `T.TempDir` to create temporary test directory + - fix: --verify forgets the verified key + - test: name --verify forgets the verified key + - chore: fix toc in changelog for 0.18 + - feat: add "autoclient" routing type + - test: parallelize more of rcmgr Go tests + - test: port legacy DHT tests to Go + - fix: t0116-gateway-cache.sh ([ipfs/kubo#9696](https://github.com/ipfs/kubo/pull/9696)) + - docs: add bifrost to early testers ([ipfs/kubo#9699](https://github.com/ipfs/kubo/pull/9699)) + - fix: typo in documentation for install path + - docs: fix typos + - Update Version: v0.19 ([ipfs/kubo#9698](https://github.com/ipfs/kubo/pull/9698)) +- github.com/ipfs/go-block-format (v0.1.1 -> v0.1.2): + - chore: release v0.1.2 + - Revert deprecation and go-libipfs/blocks stub types + - docs: deprecation notice [ci skip] +- github.com/ipfs/go-cid (v0.3.2 -> v0.4.1): + - v0.4.1 + - Add unit test for unexpected eof + - Update cid.go + - CidFromReader should not wrap valid EOF return. + - chore: version 0.4.0 + - feat: wrap parsing errors into ErrInvalidCid + - fix: use crypto/rand.Read + - Fix README.md example error (#146) ([ipfs/go-cid#146](https://github.com/ipfs/go-cid/pull/146)) +- github.com/ipfs/go-delegated-routing (v0.7.0 -> v0.8.0): + - chore: release v0.8.0 + - chore: migrate from go-ipns to boxo + - docs: add deprecation notice [ci skip] +- github.com/ipfs/go-graphsync (v0.14.1 -> v0.14.4): + - Update version to cover latest fixes (#419) ([ipfs/go-graphsync#419](https://github.com/ipfs/go-graphsync/pull/419)) + - Bring changes from #412 + - Bring changes from #391 + - fix: calling message queue Shutdown twice causes panic (because close is called twice on done channel) (#414) ([ipfs/go-graphsync#414](https://github.com/ipfs/go-graphsync/pull/414)) + - docs(CHANGELOG): update for v0.14.3 + - fix: wire up proper linksystem to traverser (#411) ([ipfs/go-graphsync#411](https://github.com/ipfs/go-graphsync/pull/411)) + - sync: update CI config files (#378) ([ipfs/go-graphsync#378](https://github.com/ipfs/go-graphsync/pull/378)) + - chore: remove social links (#398) ([ipfs/go-graphsync#398](https://github.com/ipfs/go-graphsync/pull/398)) + - Removes `main` branch callout. + - release v0.14.2 +- github.com/ipfs/go-ipfs-blockstore (v1.2.0 -> v1.3.0): + - chore: release v1.3.0 + - feat: stub and deprecate NewBlockstoreNoPrefix + - Accept options for blockstore: start with WriteThrough and NoPrefix + - Allow using a NewWriteThrough() blockstore. + - sync: update CI config files (#105) ([ipfs/go-ipfs-blockstore#105](https://github.com/ipfs/go-ipfs-blockstore/pull/105)) + - feat: fast-path for PutMany, falling back to Put for single block call (#97) ([ipfs/go-ipfs-blockstore#97](https://github.com/ipfs/go-ipfs-blockstore/pull/97)) +- github.com/ipfs/go-ipfs-cmds (v0.8.2 -> v0.9.0): + - chore: release v0.9.0 + - chore: change go-libipfs to boxo +- github.com/ipfs/go-libipfs (v0.6.2 -> v0.7.0): + - chore: bump to 0.7.0 (#213) ([ipfs/go-libipfs#213](https://github.com/ipfs/go-libipfs/pull/213)) + - feat: return 400 on /ipfs/invalid-cid (#205) ([ipfs/go-libipfs#205](https://github.com/ipfs/go-libipfs/pull/205)) + - docs: add note in README that go-libipfs is not comprehensive (#163) ([ipfs/go-libipfs#163](https://github.com/ipfs/go-libipfs/pull/163)) +- github.com/ipfs/go-merkledag (v0.9.0 -> v0.10.0): + - chore: bump version to 0.10.0 + - fix: switch to crypto/rand.Read + - stop using the deprecated io/ioutil package +- github.com/ipfs/go-unixfs (v0.4.4 -> v0.4.5): + - chore: release v0.4.5 + - chore: remove go-libipfs dependency +- github.com/ipfs/go-unixfsnode (v1.5.2 -> v1.6.0): + - chore: bump v1.6.0 + - feat: add UnixFSPathSelectorBuilder ([ipfs/go-unixfsnode#45](https://github.com/ipfs/go-unixfsnode/pull/45)) + - fix: update state to allow iter continuance on NotFound errors + - chore!: make PBLinkItr private - not intended for public use + - fix: propagate iteration errors +- github.com/ipld/go-car/v2 (v2.5.1 -> v2.9.1-0.20230325062757-fff0e4397a3d): + - chore: unmigrate from go-libipfs + - Create CODEOWNERS + - blockstore: give a direct access to the index for read operations + - blockstore: only close the file on error in OpenReadWrite, not OpenReadWriteFile + - fix: handle (and test) WholeCID vs not; fast Has() path for storage + - ReadWrite: faster Has() by using the in-memory index instead of reading on disk + - fix: let `extract` skip missing unixfs shard links + - fix: error when no files extracted + - fix: make -f optional, read from stdin if omitted + - fix: update cmd/car/README with latest description + - chore: add test cases for extract modes + - feat: extract accepts '-' as an output path for stdout + - feat: extract specific path, accept stdin as streaming input + - fix: if we don't read the full block data, don't error on !EOF + - blockstore: try to close during Finalize(), even in case of previous error + - ReadWrite: add an alternative FinalizeReadOnly+Close flow + - feat: add WithTrustedCar() reader option (#381) ([ipld/go-car#381](https://github.com/ipld/go-car/pull/381)) + - blockstore: fast path for AllKeysChan using the index + - fix: switch to crypto/rand.Read + - stop using the deprecated io/ioutil package + - fix(doc): fix storage package doc formatting + - fix: return errors for unsupported operations + - chore: move insertionindex into store pkg + - chore: add experimental note + - fix: minor lint & windows fd test problems + - feat: docs for StorageCar interfaces + - feat: ReadableWritable; dedupe shared code + - feat: add Writable functionality to StorageCar + - feat: StorageCar as a Readable storage, separate from blockstore + - feat(blockstore): implement a streaming read only storage + - feat(cmd): add index create subcommand to create an external carv2 index ([ipld/go-car#350](https://github.com/ipld/go-car/pull/350)) + - chore: bump version to 0.6.0 + - fix: use goreleaser instead + - Allow using WalkOption in WriteCar function ([ipld/go-car#357](https://github.com/ipld/go-car/pull/357)) + - fix: update go-block-format to the version that includes the stubs + - feat: upgrade from go-block-format to go-libipfs/blocks + - cleanup readme a bit to make the cli more discoverable (#353) ([ipld/go-car#353](https://github.com/ipld/go-car/pull/353)) + - Update install instructions in README.md + - Add a debugging form for car files. (#341) ([ipld/go-car#341](https://github.com/ipld/go-car/pull/341)) + - ([ipld/go-car#340](https://github.com/ipld/go-car/pull/340)) +- github.com/ipld/go-codec-dagpb (v1.5.0 -> v1.6.0): + - Update version.json +- github.com/ipld/go-ipld-prime (v0.19.0 -> v0.20.0): + - Prepare v0.20.0 + - fix(datamodel): add tests to Copy, make it complain on nil + - feat(dagcbor): mode to allow parsing undelimited streamed objects + - Fix mispatched package declaration. + - Add several pieces of docs to schema/dmt. + - Additional access to schema/dmt package; schema concatenation feature ([ipld/go-ipld-prime#483](https://github.com/ipld/go-ipld-prime/pull/483)) + - Fix hash mismatch error on matching link pointer + - feat: support errors.Is for schema errors +- github.com/ipld/go-ipld-prime/storage/bsadapter (v0.0.0-20211210234204-ce2a1c70cd73 -> v0.0.0-20230102063945-1a409dc236dd): + - build(deps): bump github.com/ipfs/go-blockservice + - Fix mispatched package declaration. + - Add several pieces of docs to schema/dmt. + - Additional access to schema/dmt package; schema concatenation feature ([ipld/go-ipld-prime/storage/bsadapter#483](https://github.com/ipld/go-ipld-prime/storage/bsadapter/pull/483)) + - fix: go mod tidy + - build(deps): bump github.com/frankban/quicktest from 1.14.3 to 1.14.4 + - Fix hash mismatch error on matching link pointer + - build(deps): bump github.com/warpfork/go-testmark from 0.10.0 to 0.11.0 + - feat: support errors.Is for schema errors + - build(deps): bump github.com/multiformats/go-multicodec + - Prepare v0.19.0 + - fix: correct json codec links & bytes handling + - build(deps): bump github.com/google/go-cmp from 0.5.8 to 0.5.9 (#468) ([ipld/go-ipld-prime/storage/bsadapter#468](https://github.com/ipld/go-ipld-prime/storage/bsadapter/pull/468)) + - build(deps): bump github.com/ipfs/go-cid from 0.3.0 to 0.3.2 (#466) ([ipld/go-ipld-prime/storage/bsadapter#466](https://github.com/ipld/go-ipld-prime/storage/bsadapter/pull/466)) + - build(deps): bump github.com/ipfs/go-cid in /storage/bsrvadapter (#464) ([ipld/go-ipld-prime/storage/bsadapter#464](https://github.com/ipld/go-ipld-prime/storage/bsadapter/pull/464)) + - test(basicnode): increase test coverage for int and map types (#454) ([ipld/go-ipld-prime/storage/bsadapter#454](https://github.com/ipld/go-ipld-prime/storage/bsadapter/pull/454)) + - build(deps): bump github.com/ipfs/go-cid in /storage/bsrvadapter + - build(deps): bump github.com/ipfs/go-cid from 0.2.0 to 0.3.0 + - build(deps): bump github.com/multiformats/go-multicodec + - fix: remove reliance on ioutil + - fix: update sub-package modules + - build(deps): bump github.com/multiformats/go-multihash + - build(deps): bump github.com/ipfs/go-datastore in /storage/dsadapter + - update .github/workflows/go-check.yml + - update .github/workflows/go-test.yml + - run gofmt -s + - bump go.mod to Go 1.18 and run go fix + - bump go.mod to Go 1.18 and run go fix + - bump go.mod to Go 1.18 and run go fix + - bump go.mod to Go 1.18 and run go fix + - feat: add kinded union to gendemo + - fix: go mod 1.17 compat problems + - build(deps): bump github.com/ipfs/go-blockservice + - Prepare v0.18.0 + - fix(deps): update benchmarks go.sum + - build(deps): bump github.com/multiformats/go-multihash + - feat(bindnode): add a BindnodeRegistry utility (#437) ([ipld/go-ipld-prime/storage/bsadapter#437](https://github.com/ipld/go-ipld-prime/storage/bsadapter/pull/437)) + - feat(bindnode): support full uint64 range + - chore(bindnode): remove typed functions for options + - chore(bindnode): docs and minor tweaks + - feat(bindnode): make Any converters work for List and Map values + - fix(bindnode): shorten converter option names, minor perf improvements + - fix(bindnode): only custom convert AssignNull for Any converter + - feat(bindnode): pass Null on to nullable custom converters + - chore(bindnode): config helper refactor w/ short-circuit + - feat(bindnode): add AddCustomTypeAnyConverter() to handle `Any` fields + - feat(bindnode): add AddCustomTypeXConverter() options for most scalar kinds + - chore(bindnode): back out of reflection for converters + - feat(bindnode): switch to converter functions instead of type + - feat(bindnode): allow custom type conversions with options + - feat: add release checklist (#442) ([ipld/go-ipld-prime/storage/bsadapter#442](https://github.com/ipld/go-ipld-prime/storage/bsadapter/pull/442)) + - Prepare v0.17.0 + - feat: introduce UIntNode interface, used within DAG-CBOR codec + - add option to not parse beyond end of structure (#435) ([ipld/go-ipld-prime/storage/bsadapter#435](https://github.com/ipld/go-ipld-prime/storage/bsadapter/pull/435)) + - sync benchmarks go.sum + - build(deps): bump github.com/multiformats/go-multicodec + - patch: first draft. ([ipld/go-ipld-prime/storage/bsadapter#350](https://github.com/ipld/go-ipld-prime/storage/bsadapter/pull/350)) + - feat(bindnode): infer links and Any from Go types (#432) ([ipld/go-ipld-prime/storage/bsadapter#432](https://github.com/ipld/go-ipld-prime/storage/bsadapter/pull/432)) + - fix(codecs): error on cid.Undef links in dag{json,cbor} encoding (#433) ([ipld/go-ipld-prime/storage/bsadapter#433](https://github.com/ipld/go-ipld-prime/storage/bsadapter/pull/433)) + - chore(bindnode): add test for sub-node unwrapping + - fix(bindnode): more helpful error message for enum value footgun + - fix(bindnode): panic early if API has been passed ptr-to-ptr + - fix(deps): mod tidy for dependencies + - build(deps): bump github.com/warpfork/go-testmark from 0.3.0 to 0.10.0 + - build(deps): bump github.com/multiformats/go-multicodec + - build(deps): bump github.com/ipfs/go-cid from 0.0.4 to 0.2.0 + - build(deps): bump github.com/google/go-cmp from 0.5.7 to 0.5.8 + - build(deps): bump github.com/frankban/quicktest from 1.14.2 to 1.14.3 + - build(deps): bump github.com/ipfs/go-cid in /storage/bsrvadapter + - chore(deps): expand dependabot to sub-modules + - chore(deps): add dependabot config + - printer: fix printing of floats + - add version.json file (#411) ([ipld/go-ipld-prime/storage/bsadapter#411](https://github.com/ipld/go-ipld-prime/storage/bsadapter/pull/411)) + - ci: use GOFLAGS to control test tags + - ci: disable coverpkg using custom workflow insertion + - ci: add initial web3 unified-ci files + - fix: make 32-bit safe and stable & add to CI + - ci: add go-check.yml workflow from unified-ci + - ci: go mod tidy + - fix: staticcheck and govet fixes + - test: make tests work on Windows, add Windows to CI (#405) ([ipld/go-ipld-prime/storage/bsadapter#405](https://github.com/ipld/go-ipld-prime/storage/bsadapter/pull/405)) + - schema: enable inline types through dsl parser & compiler (#404) ([ipld/go-ipld-prime/storage/bsadapter#404](https://github.com/ipld/go-ipld-prime/storage/bsadapter/pull/404)) + - node/bindnode: allow nilable types for IPLD optional/nullable + - test(ci): enable macos in GitHub Actions + - test(gen-go): disable parallelism when testing on macos + - storage: update deps + - dsl support for stringjoin struct repr and stringprefix union repr ([ipld/go-ipld-prime/storage/bsadapter#397](https://github.com/ipld/go-ipld-prime/storage/bsadapter/pull/397)) + - codec/dagcbor: add DecodeOptions.ExperimentalDeterminism + - node/bindnode: add some more docs + - start testing on Go 1.18.x, drop Go 1.16.x + - readme: getting started pointers. + - readme: bindnode definitely needs a mention! + - Readme updates! + - datamodel: document that repr prototypes produce type nodes + - node/bindnode: minor fuzz improvements + - gengo: update readme. + - fix(dagcbor): don't accept trailing bytes + - schema/dmt: reject duplicate or missing union repr members + - node/bindnode: actually check schemadmt.Compile errors when fuzzing + - node/bindnode: avoid OOM when inferring from cyclic IPLD schemas + - schema/dmt: require enum reprs to refer valid members + - skip NaN/Inf errors for dag-json + - node/bindnode: refuse to decode empty union values + - schema/dmt: error in Compile if union reprs refer to unknown members + - node/bindnode: start fuzzing with schema/dmt and codec/dagcbor + - mark v0.16.0 + - node/bindnode: enforce pointer requirement for nullable maps + - Implement WalkTransforming traversal (#376) ([ipld/go-ipld-prime/storage/bsadapter#376](https://github.com/ipld/go-ipld-prime/storage/bsadapter/pull/376)) + - docs(datamodel): add comment to LargeBytesNode + - Add partial-match traversal of large bytes (#375) ([ipld/go-ipld-prime/storage/bsadapter#375](https://github.com/ipld/go-ipld-prime/storage/bsadapter/pull/375)) + - Implement option to start traversals at a path ([ipld/go-ipld-prime/storage/bsadapter#358](https://github.com/ipld/go-ipld-prime/storage/bsadapter/pull/358)) + - add top-level "go value with schema" example + - Support optional `LargeBytesNode` interface (#372) ([ipld/go-ipld-prime/storage/bsadapter#372](https://github.com/ipld/go-ipld-prime/storage/bsadapter/pull/372)) + - node/bindnode: support pointers to datamodel.Node to bind with Any + - fix(bindnode): tuple struct iterator should handle absent fields properly + - node/bindnode: make AssignNode work at the repr level + - node/bindnode: add support for unsigned integers + - node/bindnode: cover even more edge case panics + - node/bindnode: polish some more AsT panics + - schema/dmt: stop using a fake test to generate code ([ipld/go-ipld-prime/storage/bsadapter#356](https://github.com/ipld/go-ipld-prime/storage/bsadapter/pull/356)) + - schema: remove one review note; add another. + - fix: minor EncodedLength fixes, add tests to fully exercise + - feat: add dagcbor.EncodedLength(Node) to calculate length without encoding + - chore: rename Garbage() to Generate() + - fix: minor garbage nits + - fix: Garbage() takes rand parameter, tweak algorithms, improve docs + - feat: add Garbage() Node generator + - node/bindnode: introduce an assembler that always errors + - node/bindnode: polish panics on invalid AssignT calls + - datamodel: don't panic when stringifying an empty KindSet + - node/bindnode: start using ipld.LoadSchema APIs + - selectors: fix for edge case around recursion clauses with an immediate edge. ([ipld/go-ipld-prime/storage/bsadapter#334](https://github.com/ipld/go-ipld-prime/storage/bsadapter/pull/334)) + - node/bindnode: improve support for pointer types + - node/bindnode: subtract all absents in Length at the repr level + - fix(codecs): error when encoding maps whose lengths don't match entry count + - schema: avoid alloc and copy in Struct and Enum methods + - node/bindnode: allow mapping int-repr enums with Go integers + - schema,node/bindnode: add support for Any + - signaling ADLs in selectors (#301) ([ipld/go-ipld-prime/storage/bsadapter#301](https://github.com/ipld/go-ipld-prime/storage/bsadapter/pull/301)) + - node/bindnode: add support for enums + - schema/...: add support for enum int representations + - node/bindnode: allow binding cidlink.Link to links +- github.com/libp2p/go-libp2p (v0.26.4 -> v0.27.3): + - release v0.27.3 + - quic virtual listener: don't panic when quic-go's accept call errors (#2276) ([libp2p/go-libp2p#2276](https://github.com/libp2p/go-libp2p/pull/2276)) + - Release v0.27.2 (#2270) ([libp2p/go-libp2p#2270](https://github.com/libp2p/go-libp2p/pull/2270)) + - release v0.27.1 (#2252) ([libp2p/go-libp2p#2252](https://github.com/libp2p/go-libp2p/pull/2252)) + - Infer public webtransport addrs from quic-v1 addrs. (#2251) ([libp2p/go-libp2p#2251](https://github.com/libp2p/go-libp2p/pull/2251)) + - basichost: don't allocate when deduplicating multiaddrs (#2206) ([libp2p/go-libp2p#2206](https://github.com/libp2p/go-libp2p/pull/2206)) + - identify: fix normalization of interface listen addresses (#2250) ([libp2p/go-libp2p#2250](https://github.com/libp2p/go-libp2p/pull/2250)) + - autonat: fix flaky TestAutoNATDialRefused (#2245) ([libp2p/go-libp2p#2245](https://github.com/libp2p/go-libp2p/pull/2245)) + - basichost: remove stray print statement in test (#2249) ([libp2p/go-libp2p#2249](https://github.com/libp2p/go-libp2p/pull/2249)) + - swarm: fix multiaddr comparison in ListenClose (#2247) ([libp2p/go-libp2p#2247](https://github.com/libp2p/go-libp2p/pull/2247)) + - release v0.27.0 (#2242) ([libp2p/go-libp2p#2242](https://github.com/libp2p/go-libp2p/pull/2242)) + - add a security policy (#2238) ([libp2p/go-libp2p#2238](https://github.com/libp2p/go-libp2p/pull/2238)) + - chore: 0.27.0 changelog entries (#2241) ([libp2p/go-libp2p#2241](https://github.com/libp2p/go-libp2p/pull/2241)) + - correctly handle WebTransport addresses without certhashes (#2239) ([libp2p/go-libp2p#2239](https://github.com/libp2p/go-libp2p/pull/2239)) + - autorelay: add metrics (#2185) ([libp2p/go-libp2p#2185](https://github.com/libp2p/go-libp2p/pull/2185)) + - autonat: don't change status on dial request refused (#2225) ([libp2p/go-libp2p#2225](https://github.com/libp2p/go-libp2p/pull/2225)) + - autonat: fix closing of listeners in dialPolicy tests (#2226) ([libp2p/go-libp2p#2226](https://github.com/libp2p/go-libp2p/pull/2226)) + - discovery (backoff): fix typo in comment (#2214) ([libp2p/go-libp2p#2214](https://github.com/libp2p/go-libp2p/pull/2214)) + - relaysvc: flaky TestReachabilityChangeEvent (#2215) ([libp2p/go-libp2p#2215](https://github.com/libp2p/go-libp2p/pull/2215)) + - Add wss transport to interop tester impl (#2178) ([libp2p/go-libp2p#2178](https://github.com/libp2p/go-libp2p/pull/2178)) + - tests: add a stream read deadline transport test (#2210) ([libp2p/go-libp2p#2210](https://github.com/libp2p/go-libp2p/pull/2210)) + - autorelay: fix busy loop bug and flaky tests in relay finder (#2208) ([libp2p/go-libp2p#2208](https://github.com/libp2p/go-libp2p/pull/2208)) + - tests: test mplex and Yamux, Noise and TLS in transport tests (#2209) ([libp2p/go-libp2p#2209](https://github.com/libp2p/go-libp2p/pull/2209)) + - tests: add some basic transport integration tests (#2207) ([libp2p/go-libp2p#2207](https://github.com/libp2p/go-libp2p/pull/2207)) + - autorelay: remove unused semaphore (#2184) ([libp2p/go-libp2p#2184](https://github.com/libp2p/go-libp2p/pull/2184)) + - basichost: prevent duplicate dials (#2196) ([libp2p/go-libp2p#2196](https://github.com/libp2p/go-libp2p/pull/2196)) + - websocket: don't set a WSS multiaddr for accepted unencrypted conns (#2199) ([libp2p/go-libp2p#2199](https://github.com/libp2p/go-libp2p/pull/2199)) + - websocket: Don't limit message sizes in the websocket reader (#2193) ([libp2p/go-libp2p#2193](https://github.com/libp2p/go-libp2p/pull/2193)) + - identify: fix stale comment (#2179) ([libp2p/go-libp2p#2179](https://github.com/libp2p/go-libp2p/pull/2179)) + - relay service: add metrics (#2154) ([libp2p/go-libp2p#2154](https://github.com/libp2p/go-libp2p/pull/2154)) + - identify: Fix IdentifyWait when Connected events happen out of order (#2173) ([libp2p/go-libp2p#2173](https://github.com/libp2p/go-libp2p/pull/2173)) + - chore: fix ressource manager's README (#2168) ([libp2p/go-libp2p#2168](https://github.com/libp2p/go-libp2p/pull/2168)) + - relay: fix deadlock when closing (#2171) ([libp2p/go-libp2p#2171](https://github.com/libp2p/go-libp2p/pull/2171)) + - core: remove LocalPrivateKey method from network.Conn interface (#2144) ([libp2p/go-libp2p#2144](https://github.com/libp2p/go-libp2p/pull/2144)) + - routed host: return connection error instead of routing error (#2169) ([libp2p/go-libp2p#2169](https://github.com/libp2p/go-libp2p/pull/2169)) + - connmgr: reduce log level for closing connections (#2165) ([libp2p/go-libp2p#2165](https://github.com/libp2p/go-libp2p/pull/2165)) + - circuitv2: cleanup relay service properly (#2164) ([libp2p/go-libp2p#2164](https://github.com/libp2p/go-libp2p/pull/2164)) + - chore: add patch release to changelog (#2151) ([libp2p/go-libp2p#2151](https://github.com/libp2p/go-libp2p/pull/2151)) + - chore: remove superfluous testing section from README (#2150) ([libp2p/go-libp2p#2150](https://github.com/libp2p/go-libp2p/pull/2150)) + - autonat: don't use autonat for address discovery (#2148) ([libp2p/go-libp2p#2148](https://github.com/libp2p/go-libp2p/pull/2148)) + - swarm metrics: fix connection direction (#2147) ([libp2p/go-libp2p#2147](https://github.com/libp2p/go-libp2p/pull/2147)) + - connmgr: Use eventually equal helper in connmgr tests (#2128) ([libp2p/go-libp2p#2128](https://github.com/libp2p/go-libp2p/pull/2128)) + - swarm: emit PeerConnectedness event from swarm instead of from hosts (#1574) ([libp2p/go-libp2p#1574](https://github.com/libp2p/go-libp2p/pull/1574)) + - relay: initialize the ASN util when starting the service (#2143) ([libp2p/go-libp2p#2143](https://github.com/libp2p/go-libp2p/pull/2143)) + - Fix flaky TestMetricsNoAllocNoCover test (#2142) ([libp2p/go-libp2p#2142](https://github.com/libp2p/go-libp2p/pull/2142)) + - identify: Bump timeouts/sleep in tests (#2135) ([libp2p/go-libp2p#2135](https://github.com/libp2p/go-libp2p/pull/2135)) + - Add sleep to fix flaky test (#2129) ([libp2p/go-libp2p#2129](https://github.com/libp2p/go-libp2p/pull/2129)) + - basic_host: Fix flaky tests (#2136) ([libp2p/go-libp2p#2136](https://github.com/libp2p/go-libp2p/pull/2136)) + - swarm: Check context once more before dialing (#2139) ([libp2p/go-libp2p#2139](https://github.com/libp2p/go-libp2p/pull/2139)) +- github.com/libp2p/go-libp2p-asn-util (v0.2.0 -> v0.3.0): + - release v0.3.0 (#26) ([libp2p/go-libp2p-asn-util#26](https://github.com/libp2p/go-libp2p-asn-util/pull/26)) + - initialize the store lazily (#25) ([libp2p/go-libp2p-asn-util#25](https://github.com/libp2p/go-libp2p-asn-util/pull/25)) +- github.com/libp2p/go-libp2p-gostream (v0.5.0 -> v0.6.0): + - Update libp2p ([libp2p/go-libp2p-gostream#80](https://github.com/libp2p/go-libp2p-gostream/pull/80)) + - fix typo in README (#75) ([libp2p/go-libp2p-gostream#75](https://github.com/libp2p/go-libp2p-gostream/pull/75)) +- github.com/libp2p/go-libp2p-http (v0.4.0 -> v0.5.0): + - sync: update CI config files ([libp2p/go-libp2p-http#82](https://github.com/libp2p/go-libp2p-http/pull/82)) +- github.com/libp2p/go-libp2p-kad-dht (v0.21.1 -> v0.23.0): + - Release v0.23.0 + - Specified CODEOWNERS ([libp2p/go-libp2p-kad-dht#828](https://github.com/libp2p/go-libp2p-kad-dht/pull/828)) + - fix: optimistic provide ci checks in tests ([libp2p/go-libp2p-kad-dht#833](https://github.com/libp2p/go-libp2p-kad-dht/pull/833)) + - feat: add experimental optimistic provide (#783) ([libp2p/go-libp2p-kad-dht#783](https://github.com/libp2p/go-libp2p-kad-dht/pull/783)) + - feat: rework tracing a bit + - feat: add basic tracing + - chore: release v0.22.0 + - chore: migrate go-libipfs to boxo + - Fix multiple ProviderAddrTTL definitions #795 ([libp2p/go-libp2p-kad-dht#831](https://github.com/libp2p/go-libp2p-kad-dht/pull/831)) + - Increase provider Multiaddress TTL ([libp2p/go-libp2p-kad-dht#795](https://github.com/libp2p/go-libp2p-kad-dht/pull/795)) + - Make provider manager options configurable in `fullrt` ([libp2p/go-libp2p-kad-dht#829](https://github.com/libp2p/go-libp2p-kad-dht/pull/829)) + - Adjust PeerSet logic in the DHT lookup process ([libp2p/go-libp2p-kad-dht#802](https://github.com/libp2p/go-libp2p-kad-dht/pull/802)) + - added maintainers in the README ([libp2p/go-libp2p-kad-dht#826](https://github.com/libp2p/go-libp2p-kad-dht/pull/826)) + - Allow DHT crawler to be swappable + - Introduce options to parameterize config of the accelerated DHT client ([libp2p/go-libp2p-kad-dht#822](https://github.com/libp2p/go-libp2p-kad-dht/pull/822)) +- github.com/libp2p/go-libp2p-pubsub (v0.9.0 -> v0.9.3): + - Fix Memory Leak In New Timecache Implementations (#528) ([libp2p/go-libp2p-pubsub#528](https://github.com/libp2p/go-libp2p-pubsub/pull/528)) + - Default validator support (#525) ([libp2p/go-libp2p-pubsub#525](https://github.com/libp2p/go-libp2p-pubsub/pull/525)) + - Refactor timecache implementations (#523) ([libp2p/go-libp2p-pubsub#523](https://github.com/libp2p/go-libp2p-pubsub/pull/523)) + - fix(timecache): remove panic in first seen cache on Add (#522) ([libp2p/go-libp2p-pubsub#522](https://github.com/libp2p/go-libp2p-pubsub/pull/522)) + - chore: update go version and dependencies (#516) ([libp2p/go-libp2p-pubsub#516](https://github.com/libp2p/go-libp2p-pubsub/pull/516)) +- github.com/multiformats/go-multiaddr (v0.8.0 -> v0.9.0): + - Release v0.9.0 ([multiformats/go-multiaddr#196](https://github.com/multiformats/go-multiaddr/pull/196)) + - Update webrtc protocols after rename ([multiformats/go-multiaddr#195](https://github.com/multiformats/go-multiaddr/pull/195)) +- github.com/multiformats/go-multibase (v0.1.1 -> v0.2.0): + - chore: bump v0.2.0 + - fix: math/rand -> crypto/rand + - fuzz: add Decoder fuzzing +- github.com/multiformats/go-multicodec (v0.7.0 -> v0.8.1): + - Bump version to release `ipns-record` code + - chore: update submodules and go generate + - deps: upgrade stringer to compatible version + - v0.8.0 + - chore: update submodules and go generate +- github.com/warpfork/go-testmark (v0.10.0 -> v0.11.0): + - Quick changelog to note we have an API update. + - Index fix ([warpfork/go-testmark#13](https://github.com/warpfork/go-testmark/pull/13)) + - Link to python implementation in the readme! + +
    + ### 👨‍👩‍👧‍👦 Contributors +| Contributor | Commits | Lines ± | Files Changed | +|-------------|---------|---------|---------------| +| Rod Vagg | 40 | +4214/-1400 | 102 | +| Sukun | 12 | +3541/-267 | 34 | +| Gus Eggert | 22 | +2387/-1160 | 81 | +| galargh | 23 | +1331/-1734 | 34 | +| Henrique Dias | 23 | +681/-1167 | 79 | +| Marco Munizaga | 19 | +1500/-187 | 55 | +| Jorropo | 25 | +897/-597 | 180 | +| Dennis Trautwein | 4 | +990/-60 | 14 | +| Marten Seemann | 18 | +443/-450 | 53 | +| vyzo | 2 | +595/-152 | 11 | +| Michael Muré | 8 | +427/-182 | 18 | +| Will | 2 | +536/-15 | 5 | +| Adin Schmahmann | 3 | +327/-125 | 11 | +| hannahhoward | 2 | +344/-1 | 4 | +| Arthur Gavazza | 1 | +210/-50 | 4 | +| Hector Sanjuan | 6 | +181/-77 | 13 | +| Masih H. Derkani | 5 | +214/-42 | 12 | +| Calvin Behling | 4 | +158/-58 | 11 | +| Eric Myhre | 7 | +113/-27 | 15 | +| Marcin Rataj | 5 | +72/-30 | 5 | +| Steve Loeppky | 2 | +99/-0 | 2 | +| Piotr Galar | 9 | +60/-18 | 9 | +| gammazero | 4 | +69/-0 | 8 | +| Prithvi Shahi | 2 | +55/-14 | 2 | +| Eng Zer Jun | 1 | +15/-54 | 5 | +| Laurent Senta | 3 | +44/-2 | 3 | +| Ian Davis | 1 | +35/-0 | 1 | +| web3-bot | 4 | +19/-13 | 7 | +| guillaumemichel | 2 | +18/-14 | 3 | +| Guillaume Michel - guissou | 4 | +24/-8 | 4 | +| omahs | 1 | +9/-9 | 3 | +| cortze | 3 | +9/-9 | 3 | +| Nishant Das | 1 | +9/-5 | 3 | +| Hlib Kanunnikov | 2 | +11/-3 | 3 | +| Andrew Gillis | 3 | +6/-8 | 3 | +| Johnny | 1 | +0/-10 | 1 | +| Rafał Leszko | 1 | +4/-4 | 1 | +| Dirk McCormick | 1 | +4/-1 | 1 | +| Antonio Navarro Perez | 1 | +4/-1 | 1 | +| RichΛrd | 2 | +2/-2 | 2 | +| Russell Dempsey | 1 | +2/-1 | 1 | +| Winterhuman | 1 | +1/-1 | 1 | +| Will Hawkins | 1 | +1/-1 | 1 | +| Nikhilesh Susarla | 1 | +1/-1 | 1 | +| Kubo Mage | 1 | +1/-1 | 1 | +| Bryan White | 1 | +1/-1 | 1 | + From c9a8d9ff92c7a578209167e38c898fc1e849de67 Mon Sep 17 00:00:00 2001 From: Piotr Galar Date: Tue, 9 May 2023 12:53:56 +0200 Subject: [PATCH 0665/1212] ci: simplify self-hosted runner selection (#9813) * ci: simplify self-hosted runner selection * ci: put interop jobs on self-hosted runners --- .github/workflows/build.yml | 34 +++++++++++++++++++++++++--------- .github/workflows/gobuild.yml | 7 ++----- .github/workflows/gotest.yml | 12 ++++++------ .github/workflows/runner.yml | 34 ---------------------------------- .github/workflows/sharness.yml | 20 +++++++++----------- 5 files changed, 42 insertions(+), 65 deletions(-) delete mode 100644 .github/workflows/runner.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1f16d9bf3..e59532597 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -14,6 +14,10 @@ concurrency: group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.event_name == 'push' && github.sha || github.ref }} cancel-in-progress: true +defaults: + run: + shell: bash + jobs: interop-prep: if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' @@ -44,7 +48,7 @@ jobs: path: cmd/ipfs/ipfs interop: needs: [interop-prep] - runs-on: ubuntu-latest + runs-on: ${{ fromJSON(github.repository == 'ipfs/kubo' && '["self-hosted", "linux", "x64", "2xlarge"]' || '"ubuntu-latest"') }} timeout-minutes: 20 defaults: run: @@ -75,7 +79,7 @@ jobs: npm install ipfs-interop@^10.0.1 working-directory: interop # Run the interop tests while ignoring the js-js interop test cases - - run: npx ipfs-interop -- -t node --grep '^(?!.*(js\d? -> js\d?|js-js-js))' + - run: npx ipfs-interop -- -t node --grep '^(?!.*(js\d? -> js\d?|js-js-js))' --parallel env: LIBP2P_TCP_REUSEPORT: false LIBP2P_ALLOW_WEAK_RSA_KEYS: 1 @@ -156,7 +160,7 @@ jobs: working-directory: go-ipfs-http-client ipfs-webui: needs: [interop-prep] - runs-on: ubuntu-latest + runs-on: ${{ fromJSON(github.repository == 'ipfs/kubo' && '["self-hosted", "linux", "x64", "2xlarge"]' || '"ubuntu-latest"') }} timeout-minutes: 20 env: NO_SANDBOX: true @@ -191,14 +195,26 @@ jobs: key: ${{ runner.os }}-${{ github.job }}-${{ hashFiles('**/package-lock.json') }} restore-keys: | ${{ runner.os }}-${{ github.job }}- - - run: | - npm ci --prefer-offline --no-audit --progress=false - npx playwright install + - env: + NPM_CACHE_DIR: ${{ steps.npm-cache-dir.outputs.dir }} + run: | + npm ci --prefer-offline --no-audit --progress=false --cache "$NPM_CACHE_DIR" + npx playwright install --with-deps working-directory: ipfs-webui - - name: Run ipfs-webui@main build and smoke-test to confirm the upstream repo is not broken - run: npm test + - id: ref + run: echo "ref=$(git rev-parse --short HEAD)" | tee -a $GITHUB_OUTPUT working-directory: ipfs-webui - - name: Test ipfs-webui@main E2E against the locally built Kubo binary + - id: state + env: + GITHUB_REPOSITORY: ipfs/ipfs-webui + GITHUB_REF: ${{ steps.ref.outputs.ref }} + GITHUB_TOKEN: ${{ github.token }} + run: | + echo "state=$(curl -L -H "Authorization: Bearer $GITHUB_TOKEN" "https://api.github.com/repos/$GITHUB_REPOSITORY/commits/$GITHUB_REF/status" --jq '.state')" | tee -a $GITHUB_OUTPUT + - name: Build ipfs-webui@main (state=${{ steps.state.outputs.state }}) + run: npm run test:build + working-directory: ipfs-webui + - name: Test ipfs-webui@main (state=${{ steps.state.outputs.state }}) E2E against the locally built Kubo binary run: npm run test:e2e env: IPFS_GO_EXEC: ${{ github.workspace }}/cmd/ipfs/ipfs diff --git a/.github/workflows/gobuild.yml b/.github/workflows/gobuild.yml index f1e3a60b7..8591213c4 100644 --- a/.github/workflows/gobuild.yml +++ b/.github/workflows/gobuild.yml @@ -12,12 +12,9 @@ concurrency: cancel-in-progress: true jobs: - go-build-runner: - if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' - uses: ipfs/kubo/.github/workflows/runner.yml@master go-build: - needs: [go-build-runner] - runs-on: ${{ fromJSON(needs.go-build-runner.outputs.config).labels }} + if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' + runs-on: ${{ fromJSON(github.repository == 'ipfs/kubo' && '["self-hosted", "linux", "x64", "4xlarge"]' || '"ubuntu-latest"') }} timeout-minutes: 20 env: TEST_DOCKER: 0 diff --git a/.github/workflows/gotest.yml b/.github/workflows/gotest.yml index 81c39fd5e..b20dca2a3 100644 --- a/.github/workflows/gotest.yml +++ b/.github/workflows/gotest.yml @@ -12,12 +12,9 @@ concurrency: cancel-in-progress: true jobs: - go-test-runner: - if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' - uses: ipfs/kubo/.github/workflows/runner.yml@master go-test: - needs: [go-test-runner] - runs-on: ${{ fromJSON(needs.go-test-runner.outputs.config).labels }} + if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' + runs-on: ${{ fromJSON(github.repository == 'ipfs/kubo' && '["self-hosted", "linux", "x64", "2xlarge"]' || '"ubuntu-latest"') }} timeout-minutes: 20 env: TEST_DOCKER: 0 @@ -41,8 +38,11 @@ jobs: with: name: ${{ github.job }} - name: 👉️ If this step failed, go to «Summary» (top left) → inspect the «Failures/Errors» table + env: + # increasing parallelism beyond 2 doesn't speed up the tests much + PARALLEL: 2 run: | - make -j 2 test/unit/gotest.junit.xml && + make -j "$PARALLEL" test/unit/gotest.junit.xml && [[ ! $(jq -s -c 'map(select(.Action == "fail")) | .[]' test/unit/gotest.json) ]] - name: Upload coverage to Codecov uses: codecov/codecov-action@81cd2dc8148241f03f5839d295e000b8f761e378 # v3.1.0 diff --git a/.github/workflows/runner.yml b/.github/workflows/runner.yml deleted file mode 100644 index 74a8b41d7..000000000 --- a/.github/workflows/runner.yml +++ /dev/null @@ -1,34 +0,0 @@ -name: Runner - -on: - workflow_call: - outputs: - config: - description: "The runner's configuration" - value: ${{ jobs.choose.outputs.config }} - -jobs: - choose: - runs-on: ubuntu-latest - timeout-minutes: 1 - outputs: - config: ${{ steps.config.outputs.result }} - steps: - - uses: actions/github-script@v6 - id: config - with: - script: | - if (`${context.repo.owner}/${context.repo.repo}` === 'ipfs/kubo') { - return { - labels: ['self-hosted', 'linux', 'x64', 'kubo'], - parallel: 10, - aws: true - } - } else { - return { - labels: ['ubuntu-latest'], - parallel: 3, - aws: false - } - } - - run: echo ${{ steps.config.outputs.result }} diff --git a/.github/workflows/sharness.yml b/.github/workflows/sharness.yml index 2d9dfb41d..a4c2241be 100644 --- a/.github/workflows/sharness.yml +++ b/.github/workflows/sharness.yml @@ -12,12 +12,9 @@ concurrency: cancel-in-progress: true jobs: - sharness-runner: - if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' - uses: ipfs/kubo/.github/workflows/runner.yml@master sharness-test: - needs: [sharness-runner] - runs-on: ${{ fromJSON(needs.sharness-runner.outputs.config).labels }} + if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' + runs-on: ${{ fromJSON(github.repository == 'ipfs/kubo' && '["self-hosted", "linux", "x64", "4xlarge"]' || '"ubuntu-latest"') }} timeout-minutes: 20 defaults: run: @@ -57,7 +54,8 @@ jobs: TEST_EXPENSIVE: 1 IPFS_CHECK_RCMGR_DEFAULTS: 1 CONTINUE_ON_S_FAILURE: 1 - PARALLEL: ${{ fromJSON(needs.sharness-runner.outputs.config).parallel }} + # increasing parallelism beyond 10 doesn't speed up the tests much + PARALLEL: ${{ github.repository == 'ipfs/kubo' && 10 || 3 }} - name: Upload coverage report uses: codecov/codecov-action@81cd2dc8148241f03f5839d295e000b8f761e378 # v3.1.0 if: failure() || success() @@ -86,12 +84,12 @@ jobs: - name: Upload one-page HTML report to S3 id: one-page uses: pl-strflt/tf-aws-gh-runner/.github/actions/upload-artifact@main - if: fromJSON(needs.sharness-runner.outputs.config).aws && (failure() || success()) + if: github.repository == 'ipfs/kubo' && (failure() || success()) with: source: kubo/test/sharness/test-results/sharness.html destination: sharness.html - name: Upload one-page HTML report - if: (! fromJSON(needs.sharness-runner.outputs.config).aws) && (failure() || success()) + if: github.repository != 'ipfs/kubo' && (failure() || success()) uses: actions/upload-artifact@v3 with: name: sharness.html @@ -106,18 +104,18 @@ jobs: - name: Upload full HTML report to S3 id: full uses: pl-strflt/tf-aws-gh-runner/.github/actions/upload-artifact@main - if: fromJSON(needs.sharness-runner.outputs.config).aws && (failure() || success()) + if: github.repository == 'ipfs/kubo' && (failure() || success()) with: source: kubo/test/sharness/test-results/sharness-html destination: sharness-html/ - name: Upload full HTML report - if: (! fromJSON(needs.sharness-runner.outputs.config).aws) && (failure() || success()) + if: github.repository != 'ipfs/kubo' && (failure() || success()) uses: actions/upload-artifact@v3 with: name: sharness-html path: kubo/test/sharness/test-results/sharness-html - name: Add S3 links to the summary - if: fromJSON(needs.sharness-runner.outputs.config).aws && (failure() || success()) + if: github.repository == 'ipfs/kubo' && (failure() || success()) run: echo "$MD" >> $GITHUB_STEP_SUMMARY env: MD: | From 851248aedc954ae8b878e657c986af9bcb99dd85 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Tue, 9 May 2023 13:05:13 +0000 Subject: [PATCH 0666/1212] chore: create next changelog --- CHANGELOG.md | 1 + docs/changelogs/v0.21.md | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 docs/changelogs/v0.21.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 2659f2608..b99ff4f15 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ # Kubo Changelogs +- [v0.21](docs/changelogs/v0.21.md) - [v0.20](docs/changelogs/v0.20.md) - [v0.19](docs/changelogs/v0.19.md) - [v0.18](docs/changelogs/v0.18.md) diff --git a/docs/changelogs/v0.21.md b/docs/changelogs/v0.21.md new file mode 100644 index 000000000..57eb7002b --- /dev/null +++ b/docs/changelogs/v0.21.md @@ -0,0 +1,18 @@ +# Kubo changelog v0.21 + +- [v0.21.0](#v0210) + +## v0.21.0 + +- [Overview](#overview) +- [🔦 Highlights](#-highlights) +- [📝 Changelog](#-changelog) +- [👨‍👩‍👧‍👦 Contributors](#-contributors) + +### Overview + +### 🔦 Highlights + +### 📝 Changelog + +### 👨‍👩‍👧‍👦 Contributors From 7ec67fdc04d5c048de474b176fc94bb01b681aab Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 May 2023 12:44:57 +0000 Subject: [PATCH 0667/1212] chore(deps): bump golang.org/x/crypto from 0.7.0 to 0.9.0 Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.7.0 to 0.9.0. - [Commits](https://github.com/golang/crypto/compare/v0.7.0...v0.9.0) --- updated-dependencies: - dependency-name: golang.org/x/crypto dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- docs/examples/kubo-as-a-library/go.mod | 8 ++++---- docs/examples/kubo-as-a-library/go.sum | 16 ++++++++-------- go.mod | 10 +++++----- go.sum | 20 ++++++++++---------- 4 files changed, 27 insertions(+), 27 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 6a54fcad3..12f136456 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -179,13 +179,13 @@ require ( go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.24.0 // indirect go4.org v0.0.0-20230225012048-214862532bf5 // indirect - golang.org/x/crypto v0.7.0 // indirect + golang.org/x/crypto v0.9.0 // indirect golang.org/x/exp v0.0.0-20230321023759-10a507213a29 // indirect golang.org/x/mod v0.10.0 // indirect - golang.org/x/net v0.8.0 // indirect + golang.org/x/net v0.10.0 // indirect golang.org/x/sync v0.1.0 // indirect - golang.org/x/sys v0.7.0 // indirect - golang.org/x/text v0.8.0 // indirect + golang.org/x/sys v0.8.0 // indirect + golang.org/x/text v0.9.0 // indirect golang.org/x/tools v0.7.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect gonum.org/v1/gonum v0.11.0 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 1ac6f8afd..cfbcf4474 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -879,8 +879,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A= -golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= +golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g= +golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -961,8 +961,8 @@ golang.org/x/net v0.0.0-20210423184538-5f58ad60dda6/go.mod h1:OJAsFXCWl8Ukc7SiCT golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= -golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1046,8 +1046,8 @@ golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= -golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -1061,8 +1061,8 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= -golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= diff --git a/go.mod b/go.mod index 95f326b14..54889a77a 100644 --- a/go.mod +++ b/go.mod @@ -80,10 +80,10 @@ require ( go.uber.org/dig v1.16.1 go.uber.org/fx v1.19.2 go.uber.org/zap v1.24.0 - golang.org/x/crypto v0.7.0 + golang.org/x/crypto v0.9.0 golang.org/x/mod v0.10.0 golang.org/x/sync v0.1.0 - golang.org/x/sys v0.7.0 + golang.org/x/sys v0.8.0 ) require ( @@ -216,10 +216,10 @@ require ( go.uber.org/multierr v1.11.0 // indirect go4.org v0.0.0-20230225012048-214862532bf5 // indirect golang.org/x/exp v0.0.0-20230321023759-10a507213a29 // indirect - golang.org/x/net v0.8.0 // indirect + golang.org/x/net v0.10.0 // indirect golang.org/x/oauth2 v0.5.0 // indirect - golang.org/x/term v0.6.0 // indirect - golang.org/x/text v0.8.0 // indirect + golang.org/x/term v0.8.0 // indirect + golang.org/x/text v0.9.0 // indirect golang.org/x/tools v0.7.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect gonum.org/v1/gonum v0.11.0 // indirect diff --git a/go.sum b/go.sum index 6eaf0919e..25a1ce432 100644 --- a/go.sum +++ b/go.sum @@ -1009,8 +1009,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A= -golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= +golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g= +golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1097,8 +1097,8 @@ golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= -golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1199,14 +1199,14 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= -golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw= -golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1216,8 +1216,8 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= -golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= From eab0baad3b4c5678f21840ee1a1c7fadf9977b73 Mon Sep 17 00:00:00 2001 From: Gus Eggert Date: Wed, 10 May 2023 02:59:13 -0400 Subject: [PATCH 0668/1212] docs: add "Customizing Kubo" doc (#9854) Co-authored-by: Steve Loeppky Co-authored-by: Henrique Dias --- docs/customizing.md | 60 +++++++++++++++++++++++ docs/examples/kubo-as-a-library/README.md | 2 +- 2 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 docs/customizing.md diff --git a/docs/customizing.md b/docs/customizing.md new file mode 100644 index 000000000..4db3c3431 --- /dev/null +++ b/docs/customizing.md @@ -0,0 +1,60 @@ +# Customizing Kubo + +You may want to customize Kubo if you want to reuse most of Kubo's machinery. This document discusses some approaches you may consider for customizing Kubo, and their tradeoffs. + +Some common use cases for customizing Kubo include: + +- Using a custom datastore for storing blocks, pins, or other Kubo metadata +- Adding a custom data transfer protocol into Kubo +- Customizing Kubo internals, such as adding allowlist/blocklist functionality to Bitswap +- Adding new commands, interfaces, functionality, etc. to Kubo while reusing the libp2p swarm +- Building on top of Kubo's configuration and config migration functionality + +## Summary +This table summarizes the tradeoffs between the approaches below: + +| | [Boxo](#boxo-build-your-own-binary) | [Kubo Plugin](#kubo-plugins) | [Bespoke Extension Point](#bespoke-extension-points) | [Go Plugin](#go-plugins) | [Fork](#fork-kubo) | +|:-------------------:|:-----------------------------------:|:----------------------------:|:----------------------------------------------------:|:------------------------:|:------------------:| +| Supported? | ✅ | ✅ | ✅ | ❌ | ❌ | +| Future-proof? | ✅ | ❌ | ✅ | ❌ | ❌ | +| Fully customizable? | ✅ | ✅ | ❌ | ✅ | ✅ | +| Fast to implement? | ❌ | ✅ | ✅ | ✅ | ✅ | +| Dynamic at runtime? | ❌ | ❌ | ✅ | ✅ | ❌ | +| Add new commands? | ❌ | ✅ | ❌ | ✅ | ✅ | + +## Boxo: build your own binary +The best way to reuse Kubo functionality is to pick the functionality you need directly from [Boxo](https://github.com/ipfs/boxo) and compile your own binary. + +Boxo's raison d'etre is to be an IPFS component toolbox to support building custom-made implementations and applications. If your use case is not easy to implement with Boxo, you may want to consider adding whatever functionality is needed to Boxo instead of customizing Kubo, so that the community can benefit. If you are interested in this option, please reach out to Boxo maintainers, who will be happy to help you scope & plan the work. See [Boxo's FAQ](https://github.com/ipfs/boxo#help) for more info. + +## Kubo Plugins +Kubo plugins are a set of interfaces that may be implemented and injected into Kubo. Generally you should recompile the Kubo binary with your plugins added. A popular example of a Kubo plugin is [go-ds-s3](https://github.com/ipfs/go-ds-s3), which can be used to store blocks in Amazon S3. + +Some plugins, such as the `fx` plugin, allow deep customization of Kubo internals. As a result, Kubo maintainers can't guarantee backwards compatibility with these, so you may need to adapt to breaking changes when upgrading to new Kubo versions. + +For more information about the different types of Kubo plugins, see [plugins.md](./plugins.md). + +Kubo plugins can also be injected at runtime using Go plugins (see below), but these are hard to use and not well supported by Go, so we don't recommend them. + +## Bespoke Extension Points +Certain Kubo functionality may have their own extension points. For example: + +* Kubo supports the [Routing v1](https://github.com/ipfs/specs/blob/main/routing/ROUTING_V1_HTTP.md) API for delegating content routing to external processes +* Kubo supports the [Pinning Service API](https://github.com/ipfs/pinning-services-api-spec) for delegating pinning to external processes +* Kubo supports [DNSLink](https://dnslink.dev/) for delegating name->CID mappings to DNS + +(This list is not exhaustive.) + +These can generally be developed and deployed as sidecars (or full external services) without modifying the Kubo binary. + +## Go Plugins +Go provides [dynamic plugins](https://pkg.go.dev/plugin) which can be loaded at runtime into a Go binary. + +Kubo currently works with Go plugins. But using Go plugins requires that you compile the plugin using the exact same version of the Go toolchain with the same configuration (build flags, environment variables, etc.). As a result, you likely need to build Kubo and the plugins together at the same time, and at that point you may as well just compile the functionality directly into Kubo and avoid Go plugins. + +As a result, we don't recommend using Go plugins, and are likely to remove them in a future release of Kubo. + +## Fork Kubo +The "nuclear option" is to fork Kubo into your own repo, make your changes, and periodically sync your repo with the Kubo repo. This can be a good option if your changes are significant and you can commit to keeping your repo in sync with Kubo. + +Kubo maintainers can't make any backwards compatibility guarantees about Kubo internals, so by choosing this option you're accepting the risk that you may need to spend more time adapting to breaking changes. diff --git a/docs/examples/kubo-as-a-library/README.md b/docs/examples/kubo-as-a-library/README.md index c9a320985..bd41b5ee7 100644 --- a/docs/examples/kubo-as-a-library/README.md +++ b/docs/examples/kubo-as-a-library/README.md @@ -1,6 +1,6 @@ # Use Kubo (go-ipfs) as a library to spawn a node and add a file -> This tutorial is the sibling of the [js-ipfs IPFS 101 tutorial](https://github.com/ipfs-examples/js-ipfs-examples/tree/master/examples/ipfs-101#readme). +> Note: if you are trying to customize or extend Kubo, you should read the [Customizing Kubo](../../customizing.md) doc By the end of this tutorial, you will learn how to: From 0e7331c952b40d481efc717b0d749af2bd6bb92f Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Wed, 10 May 2023 10:14:48 +0200 Subject: [PATCH 0669/1212] feat: update boxo with routing streaming --- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- test/cli/content_routing_http_test.go | 5 +++-- test/cli/delegated_routing_http_test.go | 1 + 6 files changed, 10 insertions(+), 8 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 12f136456..6aa69fdac 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.18 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.8.2-0.20230503105907-8059f183d866 + github.com/ipfs/boxo v0.8.2-0.20230510071416-d7db1adc7e82 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.27.3 github.com/multiformats/go-multiaddr v0.9.0 diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index cfbcf4474..7c782c536 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -321,8 +321,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.8.2-0.20230503105907-8059f183d866 h1:ThRTXD/EyoLb/jz+YW+ZlOLbjX9FyaxP0dEpgUp3cCE= -github.com/ipfs/boxo v0.8.2-0.20230503105907-8059f183d866/go.mod h1:bORAHrH6hUtDZjbzTEaLrSpTdyhHKDIpjDRT+A14B7w= +github.com/ipfs/boxo v0.8.2-0.20230510071416-d7db1adc7e82 h1:WddjqbpZs6VHWQOpWoyj5N5DSy6o1oGsO41Wp9iQInE= +github.com/ipfs/boxo v0.8.2-0.20230510071416-d7db1adc7e82/go.mod h1:bORAHrH6hUtDZjbzTEaLrSpTdyhHKDIpjDRT+A14B7w= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= diff --git a/go.mod b/go.mod index 54889a77a..26415d8bb 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/gogo/protobuf v1.3.2 github.com/google/uuid v1.3.0 github.com/hashicorp/go-multierror v1.1.1 - github.com/ipfs/boxo v0.8.2-0.20230503105907-8059f183d866 + github.com/ipfs/boxo v0.8.2-0.20230510071416-d7db1adc7e82 github.com/ipfs/go-block-format v0.1.2 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 diff --git a/go.sum b/go.sum index 25a1ce432..d2d9980cb 100644 --- a/go.sum +++ b/go.sum @@ -356,8 +356,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.8.2-0.20230503105907-8059f183d866 h1:ThRTXD/EyoLb/jz+YW+ZlOLbjX9FyaxP0dEpgUp3cCE= -github.com/ipfs/boxo v0.8.2-0.20230503105907-8059f183d866/go.mod h1:bORAHrH6hUtDZjbzTEaLrSpTdyhHKDIpjDRT+A14B7w= +github.com/ipfs/boxo v0.8.2-0.20230510071416-d7db1adc7e82 h1:WddjqbpZs6VHWQOpWoyj5N5DSy6o1oGsO41Wp9iQInE= +github.com/ipfs/boxo v0.8.2-0.20230510071416-d7db1adc7e82/go.mod h1:bORAHrH6hUtDZjbzTEaLrSpTdyhHKDIpjDRT+A14B7w= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= diff --git a/test/cli/content_routing_http_test.go b/test/cli/content_routing_http_test.go index a8b825619..acdea7029 100644 --- a/test/cli/content_routing_http_test.go +++ b/test/cli/content_routing_http_test.go @@ -11,6 +11,7 @@ import ( "github.com/ipfs/boxo/routing/http/server" "github.com/ipfs/boxo/routing/http/types" + "github.com/ipfs/boxo/routing/http/types/iter" "github.com/ipfs/go-cid" "github.com/ipfs/kubo/test/cli/harness" "github.com/ipfs/kubo/test/cli/testutils" @@ -23,11 +24,11 @@ type fakeHTTPContentRouter struct { provideCalls int } -func (r *fakeHTTPContentRouter) FindProviders(ctx context.Context, key cid.Cid) ([]types.ProviderResponse, error) { +func (r *fakeHTTPContentRouter) FindProviders(ctx context.Context, key cid.Cid) (iter.ResultIter[types.ProviderResponse], error) { r.m.Lock() defer r.m.Unlock() r.findProvidersCalls++ - return []types.ProviderResponse{}, nil + return iter.FromSlice([]iter.Result[types.ProviderResponse]{}), nil } func (r *fakeHTTPContentRouter) ProvideBitswap(ctx context.Context, req *server.BitswapWriteProvideRequest) (time.Duration, error) { diff --git a/test/cli/delegated_routing_http_test.go b/test/cli/delegated_routing_http_test.go index 8cf3368fa..a94c0b608 100644 --- a/test/cli/delegated_routing_http_test.go +++ b/test/cli/delegated_routing_http_test.go @@ -17,6 +17,7 @@ func TestHTTPDelegatedRouting(t *testing.T) { fakeServer := func(resp string) *httptest.Server { return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") _, err := w.Write([]byte(resp)) if err != nil { panic(err) From 61f8c7301ac878367c80601796885880933d2dac Mon Sep 17 00:00:00 2001 From: Laurent Senta Date: Wed, 10 May 2023 13:49:31 +0200 Subject: [PATCH 0670/1212] refactor: use reusable IPNS ValidateWithPeerID (#9867) Co-authored-by: Henrique Dias --- core/commands/name/name.go | 29 +------------------------- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- 5 files changed, 7 insertions(+), 34 deletions(-) diff --git a/core/commands/name/name.go b/core/commands/name/name.go index 75512e8f3..94f05290c 100644 --- a/core/commands/name/name.go +++ b/core/commands/name/name.go @@ -17,7 +17,6 @@ import ( "github.com/ipld/go-ipld-prime" "github.com/ipld/go-ipld-prime/codec/dagcbor" "github.com/ipld/go-ipld-prime/codec/dagjson" - ic "github.com/libp2p/go-libp2p/core/crypto" "github.com/libp2p/go-libp2p/core/peer" mbase "github.com/multiformats/go-multibase" ) @@ -216,33 +215,7 @@ Passing --verify will verify signature against provided public key. PublicKey: id, } - pub, err := id.ExtractPublicKey() - if err != nil { - // Make sure it works with all those RSA that cannot be embedded into the - // Peer ID. - if len(entry.PubKey) > 0 { - pub, err = ic.UnmarshalPublicKey(entry.PubKey) - if err != nil { - return err - } - - // Verify the public key matches the name we are verifying. - entryID, err := peer.IDFromPublicKey(pub) - - if err != nil { - return err - } - - if id != entryID { - return fmt.Errorf("record public key does not match the verified name") - } - } - } - if err != nil { - return err - } - - err = ipns.Validate(pub, &entry) + err = ipns.ValidateWithPeerID(id, &entry) if err == nil { result.Validation.Valid = true } else { diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 6aa69fdac..52e3c0646 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.18 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.8.2-0.20230510071416-d7db1adc7e82 + github.com/ipfs/boxo v0.8.2-0.20230510114019-33e3f0cd052b github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.27.3 github.com/multiformats/go-multiaddr v0.9.0 diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 7c782c536..3111d683f 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -321,8 +321,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.8.2-0.20230510071416-d7db1adc7e82 h1:WddjqbpZs6VHWQOpWoyj5N5DSy6o1oGsO41Wp9iQInE= -github.com/ipfs/boxo v0.8.2-0.20230510071416-d7db1adc7e82/go.mod h1:bORAHrH6hUtDZjbzTEaLrSpTdyhHKDIpjDRT+A14B7w= +github.com/ipfs/boxo v0.8.2-0.20230510114019-33e3f0cd052b h1:6EVpfwbBgwhfZOA19i55jOGokKOy+OaQAm1dg4RbXmc= +github.com/ipfs/boxo v0.8.2-0.20230510114019-33e3f0cd052b/go.mod h1:Ej2r08Z4VIaFKqY08UXMNhwcLf6VekHhK8c+KqA1B9Y= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= diff --git a/go.mod b/go.mod index 26415d8bb..a756f0f32 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/gogo/protobuf v1.3.2 github.com/google/uuid v1.3.0 github.com/hashicorp/go-multierror v1.1.1 - github.com/ipfs/boxo v0.8.2-0.20230510071416-d7db1adc7e82 + github.com/ipfs/boxo v0.8.2-0.20230510114019-33e3f0cd052b github.com/ipfs/go-block-format v0.1.2 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 diff --git a/go.sum b/go.sum index d2d9980cb..af7ec2fc0 100644 --- a/go.sum +++ b/go.sum @@ -356,8 +356,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.8.2-0.20230510071416-d7db1adc7e82 h1:WddjqbpZs6VHWQOpWoyj5N5DSy6o1oGsO41Wp9iQInE= -github.com/ipfs/boxo v0.8.2-0.20230510071416-d7db1adc7e82/go.mod h1:bORAHrH6hUtDZjbzTEaLrSpTdyhHKDIpjDRT+A14B7w= +github.com/ipfs/boxo v0.8.2-0.20230510114019-33e3f0cd052b h1:6EVpfwbBgwhfZOA19i55jOGokKOy+OaQAm1dg4RbXmc= +github.com/ipfs/boxo v0.8.2-0.20230510114019-33e3f0cd052b/go.mod h1:Ej2r08Z4VIaFKqY08UXMNhwcLf6VekHhK8c+KqA1B9Y= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= From 4acadd49ebc445d86afb678477abad880fec36cf Mon Sep 17 00:00:00 2001 From: Gus Eggert Date: Sun, 14 May 2023 23:22:35 -0400 Subject: [PATCH 0671/1212] docs: add Thunderdome docs for releases (#9872) --- docs/RELEASE_ISSUE_TEMPLATE.md | 3 ++ docs/releases_thunderdome.md | 60 ++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 docs/releases_thunderdome.md diff --git a/docs/RELEASE_ISSUE_TEMPLATE.md b/docs/RELEASE_ISSUE_TEMPLATE.md index 3ece6d414..ed181126e 100644 --- a/docs/RELEASE_ISSUE_TEMPLATE.md +++ b/docs/RELEASE_ISSUE_TEMPLATE.md @@ -63,6 +63,7 @@ This section covers tasks to be done ahead of the release. - open an access request in the [pldw](https://github.com/protocol/pldw/issues/new/choose) - [example](https://github.com/protocol/pldw/issues/158) - [ ] [kuboreleaser](https://github.com/ipfs/kuboreleaser) checked out on your system (_only if you're using [kuboreleaser](https://github.com/ipfs/kuboreleaser)_) + - [ ] [Thunderdome](https://github.com/ipfs-shipyard/thunderdome) checked out on your system and configured (see the [Thunderdome release docs](./releases_thunderdome.md) for setup) - [ ] [docker](https://docs.docker.com/get-docker/) installed on your system (_only if you're using [kuboreleaser](https://github.com/ipfs/kuboreleaser)_) - [ ] [npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) installed on your system (_only if you're **NOT** using [kuboreleaser](https://github.com/ipfs/kuboreleaser)_) - [ ] [zsh](https://github.com/ohmyzsh/ohmyzsh/wiki/Installing-ZSH#install-and-set-up-zsh-as-default) installed on your system @@ -102,6 +103,8 @@ This section covers tasks to be done during each release. - do **NOT** use `Squash and merge` nor `Rebase and merge` because we need to be able to sign the merge commit - do **NOT** delete the `release-vX.Y` branch

    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%0D(T#~V>2>LbMdA9e} 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 literal 0 HcmV?d00001 From 5b9442cfed8b668c1f2c9f968c1a4c86c82af201 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Tue, 14 Mar 2023 13:53:17 +0100 Subject: [PATCH 0533/1212] Revert "chore: add hamt directory sharding test" This reverts commit d23702bbf8513094ca445bea52742d952e80a8dc. --- test/sharness/t0115-gateway-dir-listing.sh | 24 ++---------------- .../t0115-gateway-dir-listing/README.md | 23 +---------------- .../t0115-gateway-dir-listing/hamt-refs.car | Bin 782149 -> 0 bytes 3 files changed, 3 insertions(+), 44 deletions(-) delete mode 100644 test/sharness/t0115-gateway-dir-listing/hamt-refs.car diff --git a/test/sharness/t0115-gateway-dir-listing.sh b/test/sharness/t0115-gateway-dir-listing.sh index 4681e63ee..cf95bf4b0 100755 --- a/test/sharness/t0115-gateway-dir-listing.sh +++ b/test/sharness/t0115-gateway-dir-listing.sh @@ -13,34 +13,14 @@ test_description="Test directory listing (dir-index-html) on the HTTP gateway" test_expect_success "ipfs init" ' export IPFS_PATH="$(pwd)/.ipfs" && - ipfs init --empty-repo --profile=test > /dev/null + ipfs init --profile=test > /dev/null ' test_launch_ipfs_daemon_without_network -# HAMT-sharded directory test. We must execute this test first as we want to -# start from an empty repository and count the exact number of refs we want. -HAMT_CID=bafybeiggvykl7skb2ndlmacg2k5modvudocffxjesexlod2pfvg5yhwrqm -HAMT_REFS_CID=bafybeicv4utmj46mgbpamvw2k6zg4qjs5yvspfnlxz2y6iuey5smjfcn4a -HAMT_REFS_COUNT=963 - -test_expect_success "hamt: import fixture with necessary refs" ' - ipfs dag import ../t0115-gateway-dir-listing/hamt-refs.car && - ipfs refs local | wc -l | tr -d " " > refs_count_actual && - echo $HAMT_REFS_COUNT > refs_count_expected && - test_cmp refs_count_expected refs_count_actual -' - -test_expect_success "hamt: fetch directory from gateway in offline mode" ' - curl --max-time 1 -sD - http://127.0.0.1:$GWAY_PORT/ipfs/$HAMT_CID/ > hamt_list_response && - ipfs refs local | wc -l | tr -d " " > refs_count_actual && - echo $HAMT_REFS_COUNT > refs_count_expected && - test_cmp refs_count_expected refs_count_actual -' - # Import test case # See the static fixtures in ./t0115-gateway-dir-listing/ -test_expect_success "add remaining test fixtures" ' +test_expect_success "Add the test directory" ' ipfs dag import ../t0115-gateway-dir-listing/fixtures.car ' DIR_CID=bafybeig6ka5mlwkl4subqhaiatalkcleo4jgnr3hqwvpmsqfca27cijp3i # ./rootDir/ diff --git a/test/sharness/t0115-gateway-dir-listing/README.md b/test/sharness/t0115-gateway-dir-listing/README.md index 7da44078b..937438bcd 100644 --- a/test/sharness/t0115-gateway-dir-listing/README.md +++ b/test/sharness/t0115-gateway-dir-listing/README.md @@ -2,12 +2,8 @@ - fixtures.car - raw CARv1 -- hamt-refs.car - - raw CARv1 containing all the necessary blocks to present a directory listing - for `bafybeiggvykl7skb2ndlmacg2k5modvudocffxjesexlod2pfvg5yhwrqm`, which is - a directory containing over 10k items. -fixutres.car generated with: +generated with: ```sh # using ipfs version 0.18.1 @@ -34,20 +30,3 @@ ipfs dag export ${DIR_CID} > ./fixtures.car # FILE_CID=bafkreialihlqnf5uwo4byh4n3cmwlntwqzxxs2fg5vanqdi3d7tb2l5xkm # ./rootDir/ą/ę/file-źł.txt # FILE_SIZE=34 ``` - -hamt-refs.car generated with: - -```sh -# using ipfs version 0.18.1 -export IPFS_PATH=$(mktemp -d) -ipfs init --empty-repo -ipfs daemon & -curl http://127.0.0.1:8080/ipfs/bafybeiggvykl7skb2ndlmacg2k5modvudocffxjesexlod2pfvg5yhwrqm/ -killall ipfs -ipfs refs local >> refs -ipfs files mkdir --cid-version 1 /Test -cat refs | xargs -I {} ipfs files cp /ipfs/{} /Test/{} -ipfs files stat /Test -# Grab CID: bafybeicv4utmj46mgbpamvw2k6zg4qjs5yvspfnlxz2y6iuey5smjfcn4a -ipfs dag export bafybeicv4utmj46mgbpamvw2k6zg4qjs5yvspfnlxz2y6iuey5smjfcn4a > ./refs.car -``` diff --git a/test/sharness/t0115-gateway-dir-listing/hamt-refs.car b/test/sharness/t0115-gateway-dir-listing/hamt-refs.car deleted file mode 100644 index 58069310cc4eccb612a4b272050f4064e2652232..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 782149 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

+- [ ] Run Thunderdome testing, see the [Thunderdome release docs](./releases_thunderdome.md) for details + - [ ] create a PR and merge the experiment config into Thunderdome - [ ] Create the release tag
using `kuboreleaser release --version vX.Y.Z(-rcN) tag` or ... - This is a dangerous operation! Go and Docker publishing are difficult to reverse! Have the release reviewer verify all the commands marked with ⚠️! - [ ] ⚠️ ![](https://img.shields.io/badge/only-RC-blue?style=flat-square) tag the HEAD commit using `git tag -s vX.Y.Z(-RCN) -m 'Prerelease X.Y.Z(-RCN)'` diff --git a/docs/releases_thunderdome.md b/docs/releases_thunderdome.md new file mode 100644 index 000000000..11057e26a --- /dev/null +++ b/docs/releases_thunderdome.md @@ -0,0 +1,60 @@ +# Testing Kubo releases with Thunderdome +This document is for running Thunderdome tests by release engineers as part of releasing Kubo. + +We use Thunderdome to replay ipfs.io gateway traffic in a controlled environment against two different versions of Kubo, and we record metrics and compare them to look for logic or performance regressions before releasing a new Kubo version. + +For background information about how Thunderdome works, see: https://github.com/ipfs-shipyard/thunderdome + +## Prerequisites + +* Ensure you have access to the "IPFS Stewards" vault in 1Password, which contains the requisite AWS Console and API credentials +* Ensure you have Docker and the Docker CLI installed +* Checkout the Thunderdome repo locally (or `git pull` to ensure it's up-to-date) +* Install AWS CLI v2: https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html +* Configure the AWS CLI + * Configure the credentials as described in the [Thunderdome documentation](https://github.com/ipfs-shipyard/thunderdome/blob/main/cmd/thunderdome/README.md#credentials), using the credentials from 1Password +* Make sure the `thunderdome` binary is up-to-date: `go build ./cmd/thunderdome` + +## Add & run an experiment + +Create a new release configuration JSON in the `experiments/` directory, based on the most recent `kubo-release` configuration, and tweak as necessary. Generally we setup the targets to run a commit against the tag of the last release, such as: + +```json + "targets": [ + { + "name": "kubo190-4283b9", + "description": "kubo 0.19.0-rc1", + "build_from_git": { + "repo": "https://github.com/ipfs/kubo.git", + "commit":"4283b9d98f8438fc8751ccc840d8fc24eeae6f13" + } + }, + { + "name": "kubo181", + "description": "kubo 0.18.", + "build_from_git": { + "repo": "https://github.com/ipfs/kubo.git", + "tag":"v0.18.1" + } + } + ] +``` + +Run the experiment (where `$EXPERIMENT_CONFIG_JSON` is a path to the config JSON created above): + +```shell +AWS_PROFILE=thunderdome ./thunderdome deploy --verbose --duration 120 $EXPERIMENT_CONFIG_JSON +``` + +This will build the Docker images, upload them to ECR, and then launch the experiment in Thunderdome. Once the experiment starts, the CLI will exit and the experiment will continue to run for the duration. + +## Analyze Results + +Add a log entry in https://www.notion.so/pl-strflt/ce2d1bd56f3541028d960d3711465659 and link to it from the release issue, so that experiment results are publicly visible. + +The `deploy` command will output a link to the Grafana dashboard for the experiment. We don't currently have rigorous acceptance criteria, so you should look for anomalies or changes in the metrics and make sure they are tolerable and explainable. Unexplainable anomalies should be noted in the log with a screenshot, and then root caused. + + +## Open a PR to merge the experiment config into Thunderdome + +This is important for both posterity, and so that someone else can sanity-check the test parameters. From f683bf6cf2326987debb43d51ce3d63967dd230b Mon Sep 17 00:00:00 2001 From: Piotr Galar Date: Mon, 15 May 2023 14:29:21 +0200 Subject: [PATCH 0672/1212] feat: create pull request template (#9620) --- .github/PULL_REQUEST_TEMPLATE/pull_request_template.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .github/PULL_REQUEST_TEMPLATE/pull_request_template.md diff --git a/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md b/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md new file mode 100644 index 000000000..6d06659db --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md @@ -0,0 +1,4 @@ + From 8ca9b712cfb24edda34d2ffc9b4253889ddbf9dd Mon Sep 17 00:00:00 2001 From: Piotr Galar Date: Mon, 15 May 2023 14:53:03 +0200 Subject: [PATCH 0673/1212] fix: the location of the PR template (#9878) --- .github/{PULL_REQUEST_TEMPLATE => }/pull_request_template.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/{PULL_REQUEST_TEMPLATE => }/pull_request_template.md (100%) diff --git a/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md b/.github/pull_request_template.md similarity index 100% rename from .github/PULL_REQUEST_TEMPLATE/pull_request_template.md rename to .github/pull_request_template.md From a4f54574d021c01d97de2ea8a210ab09afe7df9d Mon Sep 17 00:00:00 2001 From: Piotr Galar Date: Mon, 15 May 2023 15:39:00 +0200 Subject: [PATCH 0674/1212] ci: skip build on PRs modifying MDs only (#9879) --- .github/workflows/build.yml | 2 ++ .github/workflows/codeql-analysis.yml | 2 ++ .github/workflows/docker-build.yml | 2 ++ .github/workflows/gateway-conformance.yml | 2 ++ .github/workflows/gobuild.yml | 2 ++ .github/workflows/golang-analysis.yml | 2 ++ .github/workflows/golint.yml | 2 ++ .github/workflows/gotest.yml | 2 ++ .github/workflows/sharness.yml | 2 ++ 9 files changed, 18 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e59532597..294729c1a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -3,6 +3,8 @@ name: Interop on: workflow_dispatch: pull_request: + paths-ignore: + - '**/*.md' push: branches: - 'master' diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 805b183a7..49a47476a 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -8,6 +8,8 @@ on: pull_request: # The branches below must be a subset of the branches above branches: [ master ] + paths-ignore: + - '**/*.md' schedule: - cron: '30 12 * * 2' diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml index 13334faa6..42d9c7c9c 100644 --- a/.github/workflows/docker-build.yml +++ b/.github/workflows/docker-build.yml @@ -3,6 +3,8 @@ name: Docker Build on: workflow_dispatch: pull_request: + paths-ignore: + - '**/*.md' push: branches: - 'master' diff --git a/.github/workflows/gateway-conformance.yml b/.github/workflows/gateway-conformance.yml index 588aec346..ece4ca463 100644 --- a/.github/workflows/gateway-conformance.yml +++ b/.github/workflows/gateway-conformance.yml @@ -5,6 +5,8 @@ on: branches: - master pull_request: + paths-ignore: + - '**/*.md' concurrency: group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.event_name == 'push' && github.sha || github.ref }} diff --git a/.github/workflows/gobuild.yml b/.github/workflows/gobuild.yml index 8591213c4..ea71d1b50 100644 --- a/.github/workflows/gobuild.yml +++ b/.github/workflows/gobuild.yml @@ -3,6 +3,8 @@ name: Go Build on: workflow_dispatch: pull_request: + paths-ignore: + - '**/*.md' push: branches: - 'master' diff --git a/.github/workflows/golang-analysis.yml b/.github/workflows/golang-analysis.yml index 123e22403..684223edd 100644 --- a/.github/workflows/golang-analysis.yml +++ b/.github/workflows/golang-analysis.yml @@ -3,6 +3,8 @@ name: Go Check on: workflow_dispatch: pull_request: + paths-ignore: + - '**/*.md' push: branches: - 'master' diff --git a/.github/workflows/golint.yml b/.github/workflows/golint.yml index 216573a46..0472e0f71 100644 --- a/.github/workflows/golint.yml +++ b/.github/workflows/golint.yml @@ -3,6 +3,8 @@ name: Go Lint on: workflow_dispatch: pull_request: + paths-ignore: + - '**/*.md' push: branches: - 'master' diff --git a/.github/workflows/gotest.yml b/.github/workflows/gotest.yml index b20dca2a3..a25cc3e4b 100644 --- a/.github/workflows/gotest.yml +++ b/.github/workflows/gotest.yml @@ -3,6 +3,8 @@ name: Go Test on: workflow_dispatch: pull_request: + paths-ignore: + - '**/*.md' push: branches: - 'master' diff --git a/.github/workflows/sharness.yml b/.github/workflows/sharness.yml index a4c2241be..505c4cd03 100644 --- a/.github/workflows/sharness.yml +++ b/.github/workflows/sharness.yml @@ -3,6 +3,8 @@ name: Sharness on: workflow_dispatch: pull_request: + paths-ignore: + - '**/*.md' push: branches: - 'master' From 7d8262307cb40c1f21fd79fe52cdfd36a7dcb5cd Mon Sep 17 00:00:00 2001 From: Ross Jones Date: Mon, 15 May 2023 17:18:51 +0100 Subject: [PATCH 0675/1212] fix: use https URI when multiaddress specifies tls (#177) Currently any clients created through `NewApiWithClient` will make a HTTP request to the api, even if the multiaddress specifies TLS or (the deprecated multiaddr option) https. This commit addresses this by having NewApiWithClient iterate the available protocols for the multiaddress, specifying the URL proto as https if it finds TLS or HTTPS is specified. The default continues to be http for those multiaddresses that do not specify these options. Should resolve #176 This commit was moved from ipfs/go-ipfs-http-client@7e1de1f7ccfa8cd1f616e94664886fe04d70806e --- client/httpapi/api.go | 16 +++++++++++++++- client/httpapi/api_test.go | 28 ++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/client/httpapi/api.go b/client/httpapi/api.go index b7cfb2b52..5584de85d 100644 --- a/client/httpapi/api.go +++ b/client/httpapi/api.go @@ -107,7 +107,21 @@ func NewApiWithClient(a ma.Multiaddr, c *http.Client) (*HttpApi, error) { } } - return NewURLApiWithClient(url, c) + proto := "http://" + + // By default, DialArgs is going to provide details suitable for connecting + // a socket to, but not really suitable for making an informed choice of http + // protocol. For multiaddresses specifying tls and/or https we want to make + // a https request instead of a http request. + protocols := a.Protocols() + for _, p := range protocols { + if p.Code == ma.P_HTTPS || p.Code == ma.P_TLS { + proto = "https://" + break + } + } + + return NewURLApiWithClient(proto+url, c) } func NewURLApiWithClient(url string, c *http.Client) (*HttpApi, error) { diff --git a/client/httpapi/api_test.go b/client/httpapi/api_test.go index 2832d722d..a6d684b0d 100644 --- a/client/httpapi/api_test.go +++ b/client/httpapi/api_test.go @@ -246,3 +246,31 @@ func Test_NewURLApiWithClient_With_Headers(t *testing.T) { t.Fatal(err) } } + +func Test_NewURLApiWithClient_HTTP_Variant(t *testing.T) { + testcases := []struct { + address string + expected string + }{ + {address: "/ip4/127.0.0.1/tcp/80", expected: "http://127.0.0.1:80"}, + {address: "/ip4/127.0.0.1/tcp/443/tls", expected: "https://127.0.0.1:443"}, + {address: "/ip4/127.0.0.1/tcp/443/https", expected: "https://127.0.0.1:443"}, + {address: "/ip4/127.0.0.1/tcp/443/tls/http", expected: "https://127.0.0.1:443"}, + } + + for _, tc := range testcases { + address, err := ma.NewMultiaddr(tc.address) + if err != nil { + t.Fatal(err) + } + + api, err := NewApiWithClient(address, &http.Client{}) + if err != nil { + t.Fatal(err) + } + + if api.url != tc.expected { + t.Errorf("Expected = %s; got %s", tc.expected, api.url) + } + } +} From 13c379604fd39250ca788bfbfc20c90595898aca Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Tue, 16 May 2023 13:09:39 +0200 Subject: [PATCH 0676/1212] fix(gateway): redirect /ipns/b58mh to /ipns/cidb36 (#9785) --- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- test/cli/gateway_test.go | 17 ++++++++++++----- 5 files changed, 18 insertions(+), 11 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 52e3c0646..9542831b5 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.18 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.8.2-0.20230510114019-33e3f0cd052b + github.com/ipfs/boxo v0.8.2-0.20230516102723-5e94b9d91816 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.27.3 github.com/multiformats/go-multiaddr v0.9.0 diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 3111d683f..4285b1b47 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -321,8 +321,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.8.2-0.20230510114019-33e3f0cd052b h1:6EVpfwbBgwhfZOA19i55jOGokKOy+OaQAm1dg4RbXmc= -github.com/ipfs/boxo v0.8.2-0.20230510114019-33e3f0cd052b/go.mod h1:Ej2r08Z4VIaFKqY08UXMNhwcLf6VekHhK8c+KqA1B9Y= +github.com/ipfs/boxo v0.8.2-0.20230516102723-5e94b9d91816 h1:5EacqVA/Houq8q7jpecu80sWMB0Gvz0rLgRiK2Mfat0= +github.com/ipfs/boxo v0.8.2-0.20230516102723-5e94b9d91816/go.mod h1:Ej2r08Z4VIaFKqY08UXMNhwcLf6VekHhK8c+KqA1B9Y= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= diff --git a/go.mod b/go.mod index a756f0f32..c61903c25 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/gogo/protobuf v1.3.2 github.com/google/uuid v1.3.0 github.com/hashicorp/go-multierror v1.1.1 - github.com/ipfs/boxo v0.8.2-0.20230510114019-33e3f0cd052b + github.com/ipfs/boxo v0.8.2-0.20230516102723-5e94b9d91816 github.com/ipfs/go-block-format v0.1.2 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 diff --git a/go.sum b/go.sum index af7ec2fc0..c22b20251 100644 --- a/go.sum +++ b/go.sum @@ -356,8 +356,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.8.2-0.20230510114019-33e3f0cd052b h1:6EVpfwbBgwhfZOA19i55jOGokKOy+OaQAm1dg4RbXmc= -github.com/ipfs/boxo v0.8.2-0.20230510114019-33e3f0cd052b/go.mod h1:Ej2r08Z4VIaFKqY08UXMNhwcLf6VekHhK8c+KqA1B9Y= +github.com/ipfs/boxo v0.8.2-0.20230516102723-5e94b9d91816 h1:5EacqVA/Houq8q7jpecu80sWMB0Gvz0rLgRiK2Mfat0= +github.com/ipfs/boxo v0.8.2-0.20230516102723-5e94b9d91816/go.mod h1:Ej2r08Z4VIaFKqY08UXMNhwcLf6VekHhK8c+KqA1B9Y= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= diff --git a/test/cli/gateway_test.go b/test/cli/gateway_test.go index 1d6ac45b9..67f7e136a 100644 --- a/test/cli/gateway_test.go +++ b/test/cli/gateway_test.go @@ -13,8 +13,10 @@ import ( "github.com/ipfs/kubo/config" "github.com/ipfs/kubo/test/cli/harness" . "github.com/ipfs/kubo/test/cli/testutils" + "github.com/libp2p/go-libp2p/core/peer" "github.com/multiformats/go-multiaddr" manet "github.com/multiformats/go-multiaddr/net" + "github.com/multiformats/go-multibase" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -25,10 +27,13 @@ func TestGateway(t *testing.T) { node := h.NewNode().Init().StartDaemon("--offline") cid := node.IPFSAddStr("Hello Worlds!") + peerID, err := peer.ToCid(node.PeerID()).StringOfBase(multibase.Base36) + assert.Nil(t, err) + client := node.GatewayClient() client.TemplateData = map[string]string{ "CID": cid, - "PeerID": node.PeerID().String(), + "PeerID": peerID, } t.Run("GET IPFS path succeeds", func(t *testing.T) { @@ -182,7 +187,7 @@ func TestGateway(t *testing.T) { t.Run("GET /ipfs/ipns/{peerid} returns redirect to the valid path", func(t *testing.T) { t.Parallel() resp := client.Get("/ipfs/ipns/{{.PeerID}}?query=to-remember") - peerID := node.PeerID().String() + assert.Contains(t, resp.Body, fmt.Sprintf(``, peerID), @@ -474,6 +479,9 @@ func TestGateway(t *testing.T) { cfg.Gateway.NoFetch = true }) + node2PeerID, err := peer.ToCid(node2.PeerID()).StringOfBase(multibase.Base36) + assert.Nil(t, err) + nodes.StartDaemons().Connect() t.Run("not present", func(t *testing.T) { @@ -486,7 +494,7 @@ func TestGateway(t *testing.T) { t.Run("not present IPNS key from node 1", func(t *testing.T) { t.Parallel() - assert.Equal(t, 500, node1.GatewayClient().Get("/ipns/"+node2.PeerID().String()).StatusCode) + assert.Equal(t, 500, node1.GatewayClient().Get("/ipns/"+node2PeerID).StatusCode) }) }) @@ -501,8 +509,7 @@ func TestGateway(t *testing.T) { t.Run("present IPNS key from node 1", func(t *testing.T) { t.Parallel() node2.IPFS("name", "publish", "/ipfs/"+cidBar) - assert.Equal(t, 200, node1.GatewayClient().Get("/ipns/"+node2.PeerID().String()).StatusCode) - + assert.Equal(t, 200, node1.GatewayClient().Get("/ipns/"+node2PeerID).StatusCode) }) }) }) From 65b8d530b0bb6f0608264b7e9e6d1aaa2378bd0a Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Tue, 16 May 2023 14:05:22 +0200 Subject: [PATCH 0677/1212] test: add streaming delegated routing test (#9874) --- test/cli/delegated_routing_http_test.go | 52 ++++++++++++++++++++----- 1 file changed, 42 insertions(+), 10 deletions(-) diff --git a/test/cli/delegated_routing_http_test.go b/test/cli/delegated_routing_http_test.go index a94c0b608..b1ebacd14 100644 --- a/test/cli/delegated_routing_http_test.go +++ b/test/cli/delegated_routing_http_test.go @@ -15,18 +15,20 @@ func TestHTTPDelegatedRouting(t *testing.T) { t.Parallel() node := harness.NewT(t).NewNode().Init().StartDaemon() - fakeServer := func(resp string) *httptest.Server { + fakeServer := func(contentType string, resp ...string) *httptest.Server { return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json") - _, err := w.Write([]byte(resp)) - if err != nil { - panic(err) + w.Header().Set("Content-Type", contentType) + for _, r := range resp { + _, err := w.Write([]byte(r)) + if err != nil { + panic(err) + } } })) } findProvsCID := "baeabep4vu3ceru7nerjjbk37sxb7wmftteve4hcosmyolsbsiubw2vr6pqzj6mw7kv6tbn6nqkkldnklbjgm5tzbi4hkpkled4xlcr7xz4bq" - prov := "12D3KooWARYacCc6eoCqvsS9RW9MA2vo51CV75deoiqssx3YgyYJ" + provs := []string{"12D3KooWAobjw92XDcnQ1rRmRJDA3zAQpdPYUpZKrJxH6yccSpje", "12D3KooWARYacCc6eoCqvsS9RW9MA2vo51CV75deoiqssx3YgyYJ"} t.Run("default routing config has no routers defined", func(t *testing.T) { assert.Nil(t, node.ReadConfig().Routing.Routers) @@ -85,11 +87,11 @@ func TestHTTPDelegatedRouting(t *testing.T) { }) t.Run("adding HTTP delegated routing endpoint to Routing.Routers config works", func(t *testing.T) { - server := fakeServer(ToJSONStr(JSONObj{ + server := fakeServer("application/json", ToJSONStr(JSONObj{ "Providers": []JSONObj{{ "Protocol": "transport-bitswap", "Schema": "bitswap", - "ID": prov, + "ID": provs[0], "Addrs": []string{"/ip4/0.0.0.0/tcp/4001", "/ip4/0.0.0.0/tcp/4002"}, }}, })) @@ -114,9 +116,39 @@ func TestHTTPDelegatedRouting(t *testing.T) { assert.Equal(t, res.Stdout.Trimmed(), server.URL) node.StartDaemon() - res = node.IPFS("routing", "findprovs", findProvsCID) - assert.Equal(t, prov, res.Stdout.Trimmed()) + assert.Equal(t, provs[0], res.Stdout.Trimmed()) + }) + + node.StopDaemon() + + t.Run("adding HTTP delegated routing endpoint to Routing.Routers config works (streaming)", func(t *testing.T) { + server := fakeServer("application/x-ndjson", ToJSONStr(JSONObj{ + "Protocol": "transport-bitswap", + "Schema": "bitswap", + "ID": provs[1], + "Addrs": []string{"/ip4/0.0.0.0/tcp/4001", "/ip4/0.0.0.0/tcp/4002"}, + }), ToJSONStr(JSONObj{ + "Protocol": "transport-bitswap", + "Schema": "bitswap", + "ID": provs[0], + "Addrs": []string{"/ip4/0.0.0.0/tcp/4001", "/ip4/0.0.0.0/tcp/4002"}, + })) + t.Cleanup(server.Close) + + node.IPFS("config", "Routing.Routers.TestDelegatedRouter", "--json", ToJSONStr(JSONObj{ + "Type": "http", + "Parameters": JSONObj{ + "Endpoint": server.URL, + }, + })) + + res := node.IPFS("config", "Routing.Routers.TestDelegatedRouter.Parameters.Endpoint") + assert.Equal(t, res.Stdout.Trimmed(), server.URL) + + node.StartDaemon() + res = node.IPFS("routing", "findprovs", findProvsCID) + assert.Equal(t, provs[1]+"\n"+provs[0], res.Stdout.Trimmed()) }) t.Run("HTTP client should emit OpenCensus metrics", func(t *testing.T) { From da28fbc65a2e0f1ce59f9923823326ae2bc4f713 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Tue, 16 May 2023 15:33:27 +0200 Subject: [PATCH 0678/1212] chore: use assert.NoError instead of assert.Nil for errors --- test/cli/gateway_range_test.go | 8 ++++---- test/cli/gateway_test.go | 4 ++-- test/cli/swarm_test.go | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/test/cli/gateway_range_test.go b/test/cli/gateway_range_test.go index 5db7cc00e..7440e6341 100644 --- a/test/cli/gateway_range_test.go +++ b/test/cli/gateway_range_test.go @@ -31,10 +31,10 @@ func TestGatewayHAMTDirectory(t *testing.T) { // Import fixtures r, err := os.Open("./fixtures/TestGatewayHAMTDirectory.car") - assert.Nil(t, err) + assert.NoError(t, err) defer r.Close() err = node.IPFSDagImport(r, fixtureCid) - assert.Nil(t, err) + assert.NoError(t, err) // Fetch HAMT directory succeeds with minimal refs resp := client.Get(fmt.Sprintf("/ipfs/%s/", hamtCid)) @@ -60,10 +60,10 @@ func TestGatewayMultiRange(t *testing.T) { // Import fixtures r, err := os.Open("./fixtures/TestGatewayMultiRange.car") - assert.Nil(t, err) + assert.NoError(t, err) defer r.Close() err = node.IPFSDagImport(r, fixtureCid) - assert.Nil(t, err) + assert.NoError(t, err) // Succeeds fetching a range of blocks we have resp := client.Get(fmt.Sprintf("/ipfs/%s", fileCid), func(r *http.Request) { diff --git a/test/cli/gateway_test.go b/test/cli/gateway_test.go index 67f7e136a..972544ae0 100644 --- a/test/cli/gateway_test.go +++ b/test/cli/gateway_test.go @@ -28,7 +28,7 @@ func TestGateway(t *testing.T) { cid := node.IPFSAddStr("Hello Worlds!") peerID, err := peer.ToCid(node.PeerID()).StringOfBase(multibase.Base36) - assert.Nil(t, err) + assert.NoError(t, err) client := node.GatewayClient() client.TemplateData = map[string]string{ @@ -480,7 +480,7 @@ func TestGateway(t *testing.T) { }) node2PeerID, err := peer.ToCid(node2.PeerID()).StringOfBase(multibase.Base36) - assert.Nil(t, err) + assert.NoError(t, err) nodes.StartDaemons().Connect() diff --git a/test/cli/swarm_test.go b/test/cli/swarm_test.go index d32208106..d1a4b5c6c 100644 --- a/test/cli/swarm_test.go +++ b/test/cli/swarm_test.go @@ -35,7 +35,7 @@ func TestSwarm(t *testing.T) { res := node.RunIPFS("swarm", "peers", "--enc=json", "--identify") var output expectedOutputType err := json.Unmarshal(res.Stdout.Bytes(), &output) - assert.Nil(t, err) + assert.NoError(t, err) assert.Equal(t, 0, len(output.Peers)) }) @@ -48,7 +48,7 @@ func TestSwarm(t *testing.T) { res := node.RunIPFS("swarm", "peers", "--enc=json", "--identify") var output expectedOutputType err := json.Unmarshal(res.Stdout.Bytes(), &output) - assert.Nil(t, err) + assert.NoError(t, err) actualID := output.Peers[0].Identify.ID actualPublicKey := output.Peers[0].Identify.PublicKey actualAgentVersion := output.Peers[0].Identify.AgentVersion @@ -78,12 +78,12 @@ func TestSwarm(t *testing.T) { otherNodeIDResponse := otherNode.RunIPFS("id", "--enc=json") var otherNodeIDOutput identifyType err := json.Unmarshal(otherNodeIDResponse.Stdout.Bytes(), &otherNodeIDOutput) - assert.Nil(t, err) + assert.NoError(t, err) res := node.RunIPFS("swarm", "peers", "--enc=json", "--identify") var output expectedOutputType err = json.Unmarshal(res.Stdout.Bytes(), &output) - assert.Nil(t, err) + assert.NoError(t, err) outputIdentify := output.Peers[0].Identify assert.Equal(t, outputIdentify.ID, otherNodeIDOutput.ID) From eda19c8abeb9996ad963d439bc2545feb29fec86 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Tue, 23 May 2023 10:42:14 +0200 Subject: [PATCH 0679/1212] chore: fix nix install options (#9887) See: https://github.com/NixOS/nixpkgs/commit/eefaaf41d67ea28c3f70150958f6a29533dce709 Fixes: #9752 --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 07f8a87c5..6b6154065 100644 --- a/README.md +++ b/README.md @@ -187,10 +187,10 @@ $ ipfs get /ipns/dist.ipfs.tech/kubo/$VERSION/kubo_$VERSION_windows-amd64.zip With the purely functional package manager [Nix](https://nixos.org/nix/) you can install kubo (go-ipfs) like this: ``` -$ nix-env -i ipfs +$ nix-env -i kubo ``` -You can also install the Package by using its attribute name, which is also `ipfs`. +You can also install the Package by using its attribute name, which is also `kubo`. #### Solus @@ -251,10 +251,10 @@ $ sudo port install ipfs In macOS you can use the purely functional package manager [Nix](https://nixos.org/nix/): ``` -$ nix-env -i ipfs +$ nix-env -i kubo ``` -You can also install the Package by using its attribute name, which is also `ipfs`. +You can also install the Package by using its attribute name, which is also `kubo`. #### Homebrew From 63561f3baf63524ce7d147f67c0c4b4e0ddc5bc9 Mon Sep 17 00:00:00 2001 From: Lucas Molas Date: Thu, 25 May 2023 09:39:49 -0300 Subject: [PATCH 0680/1212] feat(bootstrap): save connected peers as backup bootstrap peers (#8856) * feat(bootstrap): save connected peers as backup temporary bootstrap ones * fix: do not add duplicated oldSavedPeers, not using tags, reuse randomizeList * test: add regression test * chore: add changelog --------- Co-authored-by: Henrique Dias Co-authored-by: Marcin Rataj --- config/internal.go | 7 +- core/bootstrap/bootstrap.go | 233 +++++++++++++++++++++++------- core/bootstrap/bootstrap_test.go | 6 +- core/core.go | 61 +++++++- docs/changelogs/v0.21.md | 16 ++ test/cli/backup_bootstrap_test.go | 60 ++++++++ 6 files changed, 325 insertions(+), 58 deletions(-) create mode 100644 test/cli/backup_bootstrap_test.go diff --git a/config/internal.go b/config/internal.go index a860c02c9..40070b11b 100644 --- a/config/internal.go +++ b/config/internal.go @@ -2,9 +2,10 @@ package config type Internal struct { // All marked as omitempty since we are expecting to make changes to all subcomponents of Internal - Bitswap *InternalBitswap `json:",omitempty"` - UnixFSShardingSizeThreshold *OptionalString `json:",omitempty"` - Libp2pForceReachability *OptionalString `json:",omitempty"` + Bitswap *InternalBitswap `json:",omitempty"` + UnixFSShardingSizeThreshold *OptionalString `json:",omitempty"` + Libp2pForceReachability *OptionalString `json:",omitempty"` + BackupBootstrapInterval *OptionalDuration `json:",omitempty"` } type InternalBitswap struct { diff --git a/core/bootstrap/bootstrap.go b/core/bootstrap/bootstrap.go index daa0a44d3..b566e0e97 100644 --- a/core/bootstrap/bootstrap.go +++ b/core/bootstrap/bootstrap.go @@ -3,16 +3,16 @@ package bootstrap import ( "context" "errors" - "fmt" "io" "math/rand" "sync" + "sync/atomic" "time" logging "github.com/ipfs/go-log" "github.com/jbenet/goprocess" - "github.com/jbenet/goprocess/context" - "github.com/jbenet/goprocess/periodic" + goprocessctx "github.com/jbenet/goprocess/context" + periodicproc "github.com/jbenet/goprocess/periodic" "github.com/libp2p/go-libp2p/core/host" "github.com/libp2p/go-libp2p/core/network" "github.com/libp2p/go-libp2p/core/peer" @@ -50,13 +50,26 @@ type BootstrapConfig struct { // for the bootstrap process to use. This makes it possible for clients // to control the peers the process uses at any moment. BootstrapPeers func() []peer.AddrInfo + + // BackupBootstrapInterval governs the periodic interval at which the node will + // attempt to save connected nodes to use as temporary bootstrap peers. + BackupBootstrapInterval time.Duration + + // MaxBackupBootstrapSize controls the maximum number of peers we're saving + // as backup bootstrap peers. + MaxBackupBootstrapSize int + + SaveBackupBootstrapPeers func(context.Context, []peer.AddrInfo) + LoadBackupBootstrapPeers func(context.Context) []peer.AddrInfo } // DefaultBootstrapConfig specifies default sane parameters for bootstrapping. var DefaultBootstrapConfig = BootstrapConfig{ - MinPeerThreshold: 4, - Period: 30 * time.Second, - ConnectionTimeout: (30 * time.Second) / 3, // Perod / 3 + MinPeerThreshold: 4, + Period: 30 * time.Second, + ConnectionTimeout: (30 * time.Second) / 3, // Perod / 3 + BackupBootstrapInterval: 1 * time.Hour, + MaxBackupBootstrapSize: 20, } func BootstrapConfigWithPeers(pis []peer.AddrInfo) BootstrapConfig { @@ -90,6 +103,9 @@ func Bootstrap(id peer.ID, host host.Host, rt routing.Routing, cfg BootstrapConf log.Debugf("%s bootstrap error: %s", id, err) } + // Exit the first call (triggered independently by `proc.Go`, not `Tick`) + // only after being done with the *single* Routing.Bootstrap call. Following + // periodic calls (`Tick`) will not block on this. <-doneWithRound } @@ -108,9 +124,100 @@ func Bootstrap(id peer.ID, host host.Host, rt routing.Routing, cfg BootstrapConf doneWithRound <- struct{}{} close(doneWithRound) // it no longer blocks periodic + + startSavePeersAsTemporaryBootstrapProc(cfg, host, proc) + return proc, nil } +// Aside of the main bootstrap process we also run a secondary one that saves +// connected peers as a backup measure if we can't connect to the official +// bootstrap ones. These peers will serve as *temporary* bootstrap nodes. +func startSavePeersAsTemporaryBootstrapProc(cfg BootstrapConfig, host host.Host, bootstrapProc goprocess.Process) { + savePeersFn := func(worker goprocess.Process) { + ctx := goprocessctx.OnClosingContext(worker) + + if err := saveConnectedPeersAsTemporaryBootstrap(ctx, host, cfg); err != nil { + log.Debugf("saveConnectedPeersAsTemporaryBootstrap error: %s", err) + } + } + savePeersProc := periodicproc.Tick(cfg.BackupBootstrapInterval, savePeersFn) + + // When the main bootstrap process ends also terminate the 'save connected + // peers' ones. Coupling the two seems the easiest way to handle this backup + // process without additional complexity. + go func() { + <-bootstrapProc.Closing() + savePeersProc.Close() + }() + + // Run the first round now (after the first bootstrap process has finished) + // as the SavePeersPeriod can be much longer than bootstrap. + savePeersProc.Go(savePeersFn) +} + +func saveConnectedPeersAsTemporaryBootstrap(ctx context.Context, host host.Host, cfg BootstrapConfig) error { + // Randomize the list of connected peers, we don't prioritize anyone. + connectedPeers := randomizeList(host.Network().Peers()) + + bootstrapPeers := cfg.BootstrapPeers() + backupPeers := make([]peer.AddrInfo, 0, cfg.MaxBackupBootstrapSize) + + // Choose peers to save and filter out the ones that are already bootstrap nodes. + for _, p := range connectedPeers { + found := false + for _, bootstrapPeer := range bootstrapPeers { + if p == bootstrapPeer.ID { + found = true + break + } + } + if !found { + backupPeers = append(backupPeers, peer.AddrInfo{ + ID: p, + Addrs: host.Network().Peerstore().Addrs(p), + }) + } + + if len(backupPeers) >= cfg.MaxBackupBootstrapSize { + break + } + } + + // If we didn't reach the target number use previously stored connected peers. + if len(backupPeers) < cfg.MaxBackupBootstrapSize { + oldSavedPeers := cfg.LoadBackupBootstrapPeers(ctx) + log.Debugf("missing %d peers to reach backup bootstrap target of %d, trying from previous list of %d saved peers", + cfg.MaxBackupBootstrapSize-len(backupPeers), cfg.MaxBackupBootstrapSize, len(oldSavedPeers)) + + // Add some of the old saved peers. Ensure we don't duplicate them. + for _, p := range oldSavedPeers { + found := false + for _, sp := range backupPeers { + if p.ID == sp.ID { + found = true + break + } + } + + if !found { + backupPeers = append(backupPeers, p) + } + + if len(backupPeers) >= cfg.MaxBackupBootstrapSize { + break + } + } + } + + cfg.SaveBackupBootstrapPeers(ctx, backupPeers) + log.Debugf("saved %d peers (of %d target) as bootstrap backup in the config", len(backupPeers), cfg.MaxBackupBootstrapSize) + return nil +} + +// Connect to as many peers needed to reach the BootstrapConfig.MinPeerThreshold. +// Peers can be original bootstrap or temporary ones (drawn from a list of +// persisted previously connected peers). func bootstrapRound(ctx context.Context, host host.Host, cfg BootstrapConfig) error { ctx, cancel := context.WithTimeout(ctx, cfg.ConnectionTimeout) @@ -127,35 +234,58 @@ func bootstrapRound(ctx context.Context, host host.Host, cfg BootstrapConfig) er id, len(connected), cfg.MinPeerThreshold) return nil } - numToDial := cfg.MinPeerThreshold - len(connected) + numToDial := cfg.MinPeerThreshold - len(connected) // numToDial > 0 - // filter out bootstrap nodes we are already connected to - var notConnected []peer.AddrInfo - for _, p := range peers { - if host.Network().Connectedness(p.ID) != network.Connected { - notConnected = append(notConnected, p) + if len(peers) > 0 { + numToDial -= int(peersConnect(ctx, host, peers, numToDial, true)) + if numToDial <= 0 { + return nil } } - // if connected to all bootstrap peer candidates, exit - if len(notConnected) < 1 { - log.Debugf("%s no more bootstrap peers to create %d connections", id, numToDial) - return ErrNotEnoughBootstrapPeers + log.Debugf("not enough bootstrap peers to fill the remaining target of %d connections, trying backup list", numToDial) + + tempBootstrapPeers := cfg.LoadBackupBootstrapPeers(ctx) + if len(tempBootstrapPeers) > 0 { + numToDial -= int(peersConnect(ctx, host, tempBootstrapPeers, numToDial, false)) + if numToDial <= 0 { + return nil + } } - // connect to a random susbset of bootstrap candidates - randSubset := randomSubsetOfPeers(notConnected, numToDial) + log.Debugf("tried both original bootstrap peers and temporary ones but still missing target of %d connections", numToDial) - log.Debugf("%s bootstrapping to %d nodes: %s", id, numToDial, randSubset) - return bootstrapConnect(ctx, host, randSubset) + return ErrNotEnoughBootstrapPeers } -func bootstrapConnect(ctx context.Context, ph host.Host, peers []peer.AddrInfo) error { - if len(peers) < 1 { - return ErrNotEnoughBootstrapPeers - } +// Attempt to make `needed` connections from the `availablePeers` list. Mark +// peers as either `permanent` or temporary when adding them to the Peerstore. +// Return the number of connections completed. We eagerly over-connect in parallel, +// so we might connect to more than needed. +// (We spawn as many routines and attempt connections as the number of availablePeers, +// but this list comes from restricted sets of original or temporary bootstrap +// nodes which will keep it under a sane value.) +func peersConnect(ctx context.Context, ph host.Host, availablePeers []peer.AddrInfo, needed int, permanent bool) uint64 { + peers := randomizeList(availablePeers) + + // Monitor the number of connections and stop if we reach the target. + var connected uint64 + ctx, cancel := context.WithCancel(ctx) + defer cancel() + go func() { + for { + select { + case <-ctx.Done(): + return + case <-time.After(1 * time.Second): + if int(atomic.LoadUint64(&connected)) >= needed { + cancel() + return + } + } + } + }() - errs := make(chan error, len(peers)) var wg sync.WaitGroup for _, p := range peers { @@ -164,45 +294,46 @@ func bootstrapConnect(ctx context.Context, ph host.Host, peers []peer.AddrInfo) // fail/abort due to an expiring context. // Also, performed asynchronously for dial speed. + if int(atomic.LoadUint64(&connected)) >= needed { + cancel() + break + } + wg.Add(1) go func(p peer.AddrInfo) { defer wg.Done() - log.Debugf("%s bootstrapping to %s", ph.ID(), p.ID) - ph.Peerstore().AddAddrs(p.ID, p.Addrs, peerstore.PermanentAddrTTL) - if err := ph.Connect(ctx, p); err != nil { - log.Debugf("failed to bootstrap with %v: %s", p.ID, err) - errs <- err + // Skip addresses belonging to a peer we're already connected to. + // (Not a guarantee but a best-effort policy.) + if ph.Network().Connectedness(p.ID) == network.Connected { return } + log.Debugf("%s bootstrapping to %s", ph.ID(), p.ID) + + if err := ph.Connect(ctx, p); err != nil { + if ctx.Err() != context.Canceled { + log.Debugf("failed to bootstrap with %v: %s", p.ID, err) + } + return + } + if permanent { + // We're connecting to an original bootstrap peer, mark it as + // a permanent address (Connect will register it as TempAddrTTL). + ph.Peerstore().AddAddrs(p.ID, p.Addrs, peerstore.PermanentAddrTTL) + } + log.Infof("bootstrapped with %v", p.ID) + atomic.AddUint64(&connected, 1) }(p) } wg.Wait() - // our failure condition is when no connection attempt succeeded. - // So drain the errs channel, counting the results. - close(errs) - count := 0 - var err error - for err = range errs { - if err != nil { - count++ - } - } - if count == len(peers) { - return fmt.Errorf("failed to bootstrap. %s", err) - } - return nil + return connected } -func randomSubsetOfPeers(in []peer.AddrInfo, max int) []peer.AddrInfo { - if max > len(in) { - max = len(in) - } - - out := make([]peer.AddrInfo, max) - for i, val := range rand.Perm(len(in))[:max] { +func randomizeList[T any](in []T) []T { + out := make([]T, len(in)) + for i, val := range rand.Perm(len(in)) { out[i] = in[val] } return out diff --git a/core/bootstrap/bootstrap_test.go b/core/bootstrap/bootstrap_test.go index 98a4a7827..39490a474 100644 --- a/core/bootstrap/bootstrap_test.go +++ b/core/bootstrap/bootstrap_test.go @@ -7,9 +7,9 @@ import ( "github.com/libp2p/go-libp2p/core/test" ) -func TestSubsetWhenMaxIsGreaterThanLengthOfSlice(t *testing.T) { +func TestRandomizeAddressList(t *testing.T) { var ps []peer.AddrInfo - sizeofSlice := 100 + sizeofSlice := 10 for i := 0; i < sizeofSlice; i++ { pid, err := test.RandPeerID() if err != nil { @@ -18,7 +18,7 @@ func TestSubsetWhenMaxIsGreaterThanLengthOfSlice(t *testing.T) { ps = append(ps, peer.AddrInfo{ID: pid}) } - out := randomSubsetOfPeers(ps, 2*sizeofSlice) + out := randomizeList(ps) if len(out) != len(ps) { t.Fail() } diff --git a/core/core.go b/core/core.go index 448386444..5c0a7ef2c 100644 --- a/core/core.go +++ b/core/core.go @@ -11,10 +11,13 @@ package core import ( "context" + "encoding/json" "io" + "time" "github.com/ipfs/boxo/filestore" pin "github.com/ipfs/boxo/pinning/pinner" + "github.com/ipfs/go-datastore" bserv "github.com/ipfs/boxo/blockservice" bstore "github.com/ipfs/boxo/blockstore" @@ -46,6 +49,7 @@ import ( "github.com/ipfs/boxo/namesys" ipnsrp "github.com/ipfs/boxo/namesys/republisher" + "github.com/ipfs/kubo/config" "github.com/ipfs/kubo/core/bootstrap" "github.com/ipfs/kubo/core/node" "github.com/ipfs/kubo/core/node/libp2p" @@ -165,12 +169,40 @@ func (n *IpfsNode) Bootstrap(cfg bootstrap.BootstrapConfig) error { return ps } } + if cfg.SaveBackupBootstrapPeers == nil { + cfg.SaveBackupBootstrapPeers = func(ctx context.Context, peerList []peer.AddrInfo) { + err := n.saveTempBootstrapPeers(ctx, peerList) + if err != nil { + log.Warnf("saveTempBootstrapPeers failed: %s", err) + return + } + } + } + if cfg.LoadBackupBootstrapPeers == nil { + cfg.LoadBackupBootstrapPeers = func(ctx context.Context) []peer.AddrInfo { + peerList, err := n.loadTempBootstrapPeers(ctx) + if err != nil { + log.Warnf("loadTempBootstrapPeers failed: %s", err) + return nil + } + return peerList + } + } + + repoConf, err := n.Repo.Config() + if err != nil { + return err + } + if repoConf.Internal.BackupBootstrapInterval != nil { + cfg.BackupBootstrapInterval = repoConf.Internal.BackupBootstrapInterval.WithDefault(time.Hour) + } - var err error n.Bootstrapper, err = bootstrap.Bootstrap(n.Identity, n.PeerHost, n.Routing, cfg) return err } +var TempBootstrapPeersKey = datastore.NewKey("/local/temp_bootstrap_peers") + func (n *IpfsNode) loadBootstrapPeers() ([]peer.AddrInfo, error) { cfg, err := n.Repo.Config() if err != nil { @@ -180,6 +212,33 @@ func (n *IpfsNode) loadBootstrapPeers() ([]peer.AddrInfo, error) { return cfg.BootstrapPeers() } +func (n *IpfsNode) saveTempBootstrapPeers(ctx context.Context, peerList []peer.AddrInfo) error { + ds := n.Repo.Datastore() + bytes, err := json.Marshal(config.BootstrapPeerStrings(peerList)) + if err != nil { + return err + } + + if err := ds.Put(ctx, TempBootstrapPeersKey, bytes); err != nil { + return err + } + return ds.Sync(ctx, TempBootstrapPeersKey) +} + +func (n *IpfsNode) loadTempBootstrapPeers(ctx context.Context) ([]peer.AddrInfo, error) { + ds := n.Repo.Datastore() + bytes, err := ds.Get(ctx, TempBootstrapPeersKey) + if err != nil { + return nil, err + } + + var addrs []string + if err := json.Unmarshal(bytes, &addrs); err != nil { + return nil, err + } + return config.ParseBootstrapPeers(addrs) +} + type ConstructPeerHostOpts struct { AddrsFactory p2pbhost.AddrsFactory DisableNatPortMap bool diff --git a/docs/changelogs/v0.21.md b/docs/changelogs/v0.21.md index 57eb7002b..b4af6168b 100644 --- a/docs/changelogs/v0.21.md +++ b/docs/changelogs/v0.21.md @@ -6,6 +6,7 @@ - [Overview](#overview) - [🔦 Highlights](#-highlights) + - [Saving previously seen nodes for later bootstrapping](#saving-previously-seen-nodes-for-later-bootstrapping) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -13,6 +14,21 @@ ### 🔦 Highlights +#### Saving previously seen nodes for later bootstrapping + +Kubo now stores a subset of connected peers as backup bootstrap nodes ([kubo#8856](https://github.com/ipfs/kubo/pull/8856)). +These nodes are used in addition to the explicitly defined bootstrappers in the +[`Bootstrap`](https://github.com/ipfs/kubo/blob/master/docs/config.md#bootstrap) configuration. + +This enhancement improves the resiliency of the system, as it eliminates the +necessity of relying solely on the default bootstrappers operated by Protocol +Labs for joining the public IPFS swarm. Previously, this level of robustness +was only available in LAN contexts with [mDNS peer discovery](https://github.com/ipfs/kubo/blob/master/docs/config.md#discoverymdns) +enabled. + +With this update, the same level of robustness is applied to peers that lack +mDNS peers and solely rely on the public DHT. + ### 📝 Changelog ### 👨‍👩‍👧‍👦 Contributors diff --git a/test/cli/backup_bootstrap_test.go b/test/cli/backup_bootstrap_test.go new file mode 100644 index 000000000..017499f3d --- /dev/null +++ b/test/cli/backup_bootstrap_test.go @@ -0,0 +1,60 @@ +package cli + +import ( + "fmt" + "testing" + "time" + + "github.com/ipfs/kubo/config" + "github.com/ipfs/kubo/test/cli/harness" + "github.com/stretchr/testify/assert" +) + +func TestBackupBootstrapPeers(t *testing.T) { + nodes := harness.NewT(t).NewNodes(3).Init() + nodes.ForEachPar(func(n *harness.Node) { + n.UpdateConfig(func(cfg *config.Config) { + cfg.Bootstrap = []string{} + cfg.Addresses.Swarm = []string{fmt.Sprintf("/ip4/127.0.0.1/tcp/%d", harness.NewRandPort())} + cfg.Discovery.MDNS.Enabled = false + cfg.Internal.BackupBootstrapInterval = config.NewOptionalDuration(250 * time.Millisecond) + }) + }) + + // Start all nodes and ensure they all have no peers. + nodes.StartDaemons() + nodes.ForEachPar(func(n *harness.Node) { + assert.Len(t, n.Peers(), 0) + }) + + // Connect nodes 0 and 1, ensure they know each other. + nodes[0].Connect(nodes[1]) + assert.Len(t, nodes[0].Peers(), 1) + assert.Len(t, nodes[1].Peers(), 1) + assert.Len(t, nodes[2].Peers(), 0) + + // Wait a bit to ensure that 0 and 1 saved their temporary bootstrap backups. + time.Sleep(time.Millisecond * 500) + nodes.StopDaemons() + + // Start 1 and 2. 2 does not know anyone yet. + nodes[1].StartDaemon() + nodes[2].StartDaemon() + assert.Len(t, nodes[1].Peers(), 0) + assert.Len(t, nodes[2].Peers(), 0) + + // Connect 1 and 2, ensure they know each other. + nodes[1].Connect(nodes[2]) + assert.Len(t, nodes[1].Peers(), 1) + assert.Len(t, nodes[2].Peers(), 1) + + // Start 0, wait a bit. Should connect to 1, and then discover 2 via the + // backup bootstrap peers. + nodes[0].StartDaemon() + time.Sleep(time.Millisecond * 500) + + // Check if they're all connected. + assert.Len(t, nodes[0].Peers(), 2) + assert.Len(t, nodes[1].Peers(), 2) + assert.Len(t, nodes[2].Peers(), 2) +} From e3126eb3e03f9e7b3ae291ace0f9cf7f6affea41 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Thu, 25 May 2023 15:36:33 +0200 Subject: [PATCH 0681/1212] chore: upgrade boxo and fix test function signature (#9896) --- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- test/cli/content_routing_http_test.go | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 9542831b5..9de8c6579 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.18 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.8.2-0.20230516102723-5e94b9d91816 + github.com/ipfs/boxo v0.8.2-0.20230525115135-a8533c998f49 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.27.3 github.com/multiformats/go-multiaddr v0.9.0 diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 4285b1b47..11d274816 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -321,8 +321,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.8.2-0.20230516102723-5e94b9d91816 h1:5EacqVA/Houq8q7jpecu80sWMB0Gvz0rLgRiK2Mfat0= -github.com/ipfs/boxo v0.8.2-0.20230516102723-5e94b9d91816/go.mod h1:Ej2r08Z4VIaFKqY08UXMNhwcLf6VekHhK8c+KqA1B9Y= +github.com/ipfs/boxo v0.8.2-0.20230525115135-a8533c998f49 h1:hi2x0dCINl9fHIV6YM+IH+Bah45pRAFekjM5MMKWJO4= +github.com/ipfs/boxo v0.8.2-0.20230525115135-a8533c998f49/go.mod h1:Ej2r08Z4VIaFKqY08UXMNhwcLf6VekHhK8c+KqA1B9Y= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= diff --git a/go.mod b/go.mod index c61903c25..2799171dc 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/gogo/protobuf v1.3.2 github.com/google/uuid v1.3.0 github.com/hashicorp/go-multierror v1.1.1 - github.com/ipfs/boxo v0.8.2-0.20230516102723-5e94b9d91816 + github.com/ipfs/boxo v0.8.2-0.20230525115135-a8533c998f49 github.com/ipfs/go-block-format v0.1.2 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 diff --git a/go.sum b/go.sum index c22b20251..c9c874dc5 100644 --- a/go.sum +++ b/go.sum @@ -356,8 +356,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.8.2-0.20230516102723-5e94b9d91816 h1:5EacqVA/Houq8q7jpecu80sWMB0Gvz0rLgRiK2Mfat0= -github.com/ipfs/boxo v0.8.2-0.20230516102723-5e94b9d91816/go.mod h1:Ej2r08Z4VIaFKqY08UXMNhwcLf6VekHhK8c+KqA1B9Y= +github.com/ipfs/boxo v0.8.2-0.20230525115135-a8533c998f49 h1:hi2x0dCINl9fHIV6YM+IH+Bah45pRAFekjM5MMKWJO4= +github.com/ipfs/boxo v0.8.2-0.20230525115135-a8533c998f49/go.mod h1:Ej2r08Z4VIaFKqY08UXMNhwcLf6VekHhK8c+KqA1B9Y= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= diff --git a/test/cli/content_routing_http_test.go b/test/cli/content_routing_http_test.go index acdea7029..c1ea64d3f 100644 --- a/test/cli/content_routing_http_test.go +++ b/test/cli/content_routing_http_test.go @@ -24,7 +24,7 @@ type fakeHTTPContentRouter struct { provideCalls int } -func (r *fakeHTTPContentRouter) FindProviders(ctx context.Context, key cid.Cid) (iter.ResultIter[types.ProviderResponse], error) { +func (r *fakeHTTPContentRouter) FindProviders(ctx context.Context, key cid.Cid, limit int) (iter.ResultIter[types.ProviderResponse], error) { r.m.Lock() defer r.m.Unlock() r.findProvidersCalls++ From 38556b8d21292c5c10f0bd7b5d874ca447111c23 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Mon, 29 May 2023 16:17:11 +0200 Subject: [PATCH 0682/1212] docs: Reprovider config (#9900) This updates docs to match new values from https://github.com/ipfs/kubo/pull/9326 --- docs/config.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/docs/config.md b/docs/config.md index 91866a423..c571407e8 100644 --- a/docs/config.md +++ b/docs/config.md @@ -1326,15 +1326,19 @@ Type: `array[peering]` ### `Reprovider.Interval` Sets the time between rounds of reproviding local content to the routing -system. If unset, it defaults to 12 hours. If set to the value `"0"` it will -disable content reproviding. +system. + +- If unset, it uses the implicit safe default. +- If set to the value `"0"` it will disable content reproviding. Note: disabling content reproviding will result in other nodes on the network not being able to discover that you have the objects that you have. If you want to have this disabled and keep the network aware of what you have, you must manually announce your content periodically. -Type: `duration` +Default: `22h` (`DefaultReproviderInterval`) + +Type: `optionalDuration` (unset for the default) ### `Reprovider.Strategy` @@ -1346,7 +1350,7 @@ Tells reprovider what should be announced. Valid strategies are: Default: `"all"` -Type: `string` (or unset for the default, which is "all") +Type: `optionalString` (unset for the default) ## `Routing` From c10b804449cd6e8e354a693f3d0c4bc7bd93fbca Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Tue, 30 May 2023 00:59:34 +0200 Subject: [PATCH 0683/1212] feat: Gateway.DeserializedResponses config flag (#9789) Co-authored-by: Marcin Rataj --- config/gateway.go | 16 ++++- core/corehttp/gateway.go | 69 +++++++++++---------- core/corehttp/gateway_test.go | 40 +++++++++++++ docs/changelogs/v0.21.md | 27 +++++++++ docs/config.md | 30 ++++++++-- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 +- go.mod | 2 +- go.sum | 4 +- test/cli/gateway_test.go | 83 ++++++++++++++++++++++++++ 10 files changed, 235 insertions(+), 42 deletions(-) diff --git a/config/gateway.go b/config/gateway.go index 8ae312b59..816b1f48d 100644 --- a/config/gateway.go +++ b/config/gateway.go @@ -1,6 +1,9 @@ package config -const DefaultInlineDNSLink = false +const ( + DefaultInlineDNSLink = false + DefaultDeserializedResponses = true +) type GatewaySpec struct { // Paths is explicit list of path prefixes that should be handled by @@ -25,6 +28,11 @@ type GatewaySpec struct { // (FQDN) into a single DNS label in order to interop with wildcard TLS certs // and Origin per CID isolation provided by rules like https://publicsuffix.org InlineDNSLink Flag + + // DeserializedResponses configures this gateway to respond to deserialized + // responses. Disabling this option enables a Trustless Gateway, as per: + // https://specs.ipfs.tech/http-gateways/trustless-gateway/. + DeserializedResponses Flag } // Gateway contains options for the HTTP gateway server. @@ -56,6 +64,12 @@ type Gateway struct { // This flag can be overridden per FQDN in PublicGateways. NoDNSLink bool + // DeserializedResponses configures this gateway to respond to deserialized + // requests. Disabling this option enables a Trustless only gateway, as per: + // https://specs.ipfs.tech/http-gateways/trustless-gateway/. This can + // be overridden per FQDN in PublicGateways. + DeserializedResponses Flag + // PublicGateways configures behavior of known public gateways. // Each key is a fully qualified domain name (FQDN). PublicGateways map[string]*GatewaySpec diff --git a/core/corehttp/gateway.go b/core/corehttp/gateway.go index a9c42f185..0f86d4da7 100644 --- a/core/corehttp/gateway.go +++ b/core/corehttp/gateway.go @@ -28,22 +28,11 @@ import ( func GatewayOption(paths ...string) ServeOption { return func(n *core.IpfsNode, _ net.Listener, mux *http.ServeMux) (*http.ServeMux, error) { - cfg, err := n.Repo.Config() + gwConfig, err := getGatewayConfig(n) if err != nil { return nil, err } - headers := make(map[string][]string, len(cfg.Gateway.HTTPHeaders)) - for h, v := range cfg.Gateway.HTTPHeaders { - headers[http.CanonicalHeaderKey(h)] = v - } - - gateway.AddAccessControlHeaders(headers) - - gwConfig := gateway.Config{ - Headers: headers, - } - gwAPI, err := newGatewayBackend(n) if err != nil { return nil, err @@ -65,7 +54,7 @@ func GatewayOption(paths ...string) ServeOption { func HostnameOption() ServeOption { return func(n *core.IpfsNode, _ net.Listener, mux *http.ServeMux) (*http.ServeMux, error) { - cfg, err := n.Repo.Config() + gwConfig, err := getGatewayConfig(n) if err != nil { return nil, err } @@ -75,9 +64,8 @@ func HostnameOption() ServeOption { return nil, err } - publicGateways := convertPublicGateways(cfg.Gateway.PublicGateways) childMux := http.NewServeMux() - mux.HandleFunc("/", gateway.WithHostname(childMux, gwAPI, publicGateways, cfg.Gateway.NoDNSLink).ServeHTTP) + mux.HandleFunc("/", gateway.WithHostname(gwConfig, gwAPI, childMux).ServeHTTP) return childMux, nil } } @@ -212,30 +200,49 @@ var defaultKnownGateways = map[string]*gateway.Specification{ "localhost": subdomainGatewaySpec, } -func convertPublicGateways(publicGateways map[string]*config.GatewaySpec) map[string]*gateway.Specification { - gws := map[string]*gateway.Specification{} - - // First, implicit defaults such as subdomain gateway on localhost - for hostname, gw := range defaultKnownGateways { - gws[hostname] = gw +func getGatewayConfig(n *core.IpfsNode) (gateway.Config, error) { + cfg, err := n.Repo.Config() + if err != nil { + return gateway.Config{}, err } - // Then apply values from Gateway.PublicGateways, if present in the config - for hostname, gw := range publicGateways { + // Parse configuration headers and add the default Access Control Headers. + headers := make(map[string][]string, len(cfg.Gateway.HTTPHeaders)) + for h, v := range cfg.Gateway.HTTPHeaders { + headers[http.CanonicalHeaderKey(h)] = v + } + gateway.AddAccessControlHeaders(headers) + + // Initialize gateway configuration, with empty PublicGateways, handled after. + gwCfg := gateway.Config{ + Headers: headers, + DeserializedResponses: cfg.Gateway.DeserializedResponses.WithDefault(config.DefaultDeserializedResponses), + NoDNSLink: cfg.Gateway.NoDNSLink, + PublicGateways: map[string]*gateway.Specification{}, + } + + // Add default implicit known gateways, such as subdomain gateway on localhost. + for hostname, gw := range defaultKnownGateways { + gwCfg.PublicGateways[hostname] = gw + } + + // Apply values from cfg.Gateway.PublicGateways if they exist. + for hostname, gw := range cfg.Gateway.PublicGateways { if gw == nil { // Remove any implicit defaults, if present. This is useful when one - // wants to disable subdomain gateway on localhost etc. - delete(gws, hostname) + // wants to disable subdomain gateway on localhost, etc. + delete(gwCfg.PublicGateways, hostname) continue } - gws[hostname] = &gateway.Specification{ - Paths: gw.Paths, - NoDNSLink: gw.NoDNSLink, - UseSubdomains: gw.UseSubdomains, - InlineDNSLink: gw.InlineDNSLink.WithDefault(config.DefaultInlineDNSLink), + gwCfg.PublicGateways[hostname] = &gateway.Specification{ + Paths: gw.Paths, + NoDNSLink: gw.NoDNSLink, + UseSubdomains: gw.UseSubdomains, + InlineDNSLink: gw.InlineDNSLink.WithDefault(config.DefaultInlineDNSLink), + DeserializedResponses: gw.DeserializedResponses.WithDefault(gwCfg.DeserializedResponses), } } - return gws + return gwCfg, nil } diff --git a/core/corehttp/gateway_test.go b/core/corehttp/gateway_test.go index 522d92f13..cfc245137 100644 --- a/core/corehttp/gateway_test.go +++ b/core/corehttp/gateway_test.go @@ -14,6 +14,7 @@ import ( core "github.com/ipfs/kubo/core" "github.com/ipfs/kubo/core/coreapi" repo "github.com/ipfs/kubo/repo" + "github.com/stretchr/testify/assert" iface "github.com/ipfs/boxo/coreiface" nsopts "github.com/ipfs/boxo/coreiface/options/namesys" @@ -173,3 +174,42 @@ func TestVersion(t *testing.T) { t.Fatalf("response doesn't contain protocol version:\n%s", s) } } + +func TestDeserializedResponsesInheritance(t *testing.T) { + for _, testCase := range []struct { + globalSetting config.Flag + gatewaySetting config.Flag + expectedGatewaySetting bool + }{ + {config.True, config.Default, true}, + {config.False, config.Default, false}, + {config.False, config.True, true}, + {config.True, config.False, false}, + } { + c := config.Config{ + Identity: config.Identity{ + PeerID: "QmTFauExutTsy4XP6JbMFcw2Wa9645HJt2bTqL6qYDCKfe", // required by offline node + }, + Gateway: config.Gateway{ + DeserializedResponses: testCase.globalSetting, + PublicGateways: map[string]*config.GatewaySpec{ + "example.com": { + DeserializedResponses: testCase.gatewaySetting, + }, + }, + }, + } + r := &repo.Mock{ + C: c, + D: syncds.MutexWrap(datastore.NewMapDatastore()), + } + n, err := core.NewNode(context.Background(), &core.BuildCfg{Repo: r}) + assert.NoError(t, err) + + gwCfg, err := getGatewayConfig(n) + assert.NoError(t, err) + + assert.Contains(t, gwCfg.PublicGateways, "example.com") + assert.Equal(t, testCase.expectedGatewaySetting, gwCfg.PublicGateways["example.com"].DeserializedResponses) + } +} diff --git a/docs/changelogs/v0.21.md b/docs/changelogs/v0.21.md index b4af6168b..d4a69514f 100644 --- a/docs/changelogs/v0.21.md +++ b/docs/changelogs/v0.21.md @@ -7,6 +7,7 @@ - [Overview](#overview) - [🔦 Highlights](#-highlights) - [Saving previously seen nodes for later bootstrapping](#saving-previously-seen-nodes-for-later-bootstrapping) + - [`Gateway.DeserializedResponses` config flag](#gatewaydeserializedresponses-config-flag) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -29,6 +30,32 @@ enabled. With this update, the same level of robustness is applied to peers that lack mDNS peers and solely rely on the public DHT. + +#### `Gateway.DeserializedResponses` config flag + +This release introduces the +[`Gateway.DeserializedResponses`](https://github.com/ipfs/kubo/blob/master/docs/config.md#gatewaydeserializedresponses) +configuration flag. + +With this flag, one can explicitly configure whether the gateway responds to +deserialized requests or not. By default, this flag is enabled. + +Disabling deserialized responses allows the +gateway to operate +as a [Trustless Gateway](https://specs.ipfs.tech/http-gateways/trustless-gateway/) +limited to three [verifiable](https://docs.ipfs.tech/reference/http/gateway/#trustless-verifiable-retrieval) +response types: +[application/vnd.ipld.raw](https://www.iana.org/assignments/media-types/application/vnd.ipld.raw), +[application/vnd.ipld.car](https://www.iana.org/assignments/media-types/application/vnd.ipld.car), +and [application/vnd.ipfs.ipns-record](https://www.iana.org/assignments/media-types/application/vnd.ipfs.ipns-record). + +With deserialized responses disabled, the Kubo gateway can serve as a block +backend for other software (like +[bifrost-gateway](https://github.com/ipfs/bifrost-gateway#readme), +[IPFS in Chromium](https://github.com/little-bear-labs/ipfs-chromium/blob/main/README.md) +etc) without the usual risks associated with hosting deserialized data behind +third-party CIDs. + ### 📝 Changelog ### 👨‍👩‍👧‍👦 Contributors diff --git a/docs/config.md b/docs/config.md index c571407e8..bf2b7750c 100644 --- a/docs/config.md +++ b/docs/config.md @@ -50,6 +50,7 @@ config file at runtime. - [`Gateway`](#gateway) - [`Gateway.NoFetch`](#gatewaynofetch) - [`Gateway.NoDNSLink`](#gatewaynodnslink) + - [`Gateway.DeserializedResponses`](#gatewaydeserializedresponses) - [`Gateway.HTTPHeaders`](#gatewayhttpheaders) - [`Gateway.RootRedirect`](#gatewayrootredirect) - [`Gateway.FastDirIndexThreshold`](#gatewayfastdirindexthreshold) @@ -60,6 +61,7 @@ config file at runtime. - [`Gateway.PublicGateways: UseSubdomains`](#gatewaypublicgateways-usesubdomains) - [`Gateway.PublicGateways: NoDNSLink`](#gatewaypublicgateways-nodnslink) - [`Gateway.PublicGateways: InlineDNSLink`](#gatewaypublicgateways-inlinednslink) + - [`Gateway.PublicGateways: DeserializedResponses`](#gatewaypublicgateways-deserializedresponses) - [Implicit defaults of `Gateway.PublicGateways`](#implicit-defaults-of-gatewaypublicgateways) - [`Gateway` recipes](#gateway-recipes) - [`Identity`](#identity) @@ -236,7 +238,7 @@ documented in `ipfs config profile --help`. smaller than several gigabytes. If you run IPFS with `--enable-gc`, you plan on storing very little data in your IPFS node, and disk usage is more critical than performance, consider using `flatfs`. - - This datastore uses up to several gigabytes of memory. + - This datastore uses up to several gigabytes of memory. - Good for medium-size datastores, but may run into performance issues if your dataset is bigger than a terabyte. - The current implementation is based on old badger 1.x which is no longer supported by the upstream team. @@ -646,6 +648,16 @@ Default: `false` Type: `bool` +#### `Gateway.DeserializedResponses` + +An optional flag to explicitly configure whether this gateway responds to deserialized +requests, or not. By default, it is enabled. When disabling this option, the gateway +operates as a Trustless Gateway only: https://specs.ipfs.tech/http-gateways/trustless-gateway/. + +Default: `true` + +Type: `flag` + ### `Gateway.HTTPHeaders` Headers to set on gateway responses. @@ -790,6 +802,16 @@ Default: `false` Type: `flag` +#### `Gateway.PublicGateways: DeserializedResponses` + +An optional flag to explicitly configure whether this gateway responds to deserialized +requests, or not. By default, it is enabled. When disabling this option, the gateway +operates as a Trustless Gateway only: https://specs.ipfs.tech/http-gateways/trustless-gateway/. + +Default: same as global `Gateway.DeserializedResponses` + +Type: `flag` + #### Implicit defaults of `Gateway.PublicGateways` Default entries for `localhost` hostname and loopback IPs are always present. @@ -895,7 +917,7 @@ Type: `string` (base64 encoded) ## `Internal` -This section includes internal knobs for various subsystems to allow advanced users with big or private infrastructures to fine-tune some behaviors without the need to recompile Kubo. +This section includes internal knobs for various subsystems to allow advanced users with big or private infrastructures to fine-tune some behaviors without the need to recompile Kubo. **Be aware that making informed change here requires in-depth knowledge and most users should leave these untouched. All knobs listed here are subject to breaking changes between versions.** @@ -971,7 +993,7 @@ Type: `optionalInteger` (byte count, `null` means default which is 1MB) ### `Internal.Bitswap.ProviderSearchDelay` This parameter determines how long to wait before looking for providers outside of bitswap. -Other routing systems like the DHT are able to provide results in less than a second, so lowering +Other routing systems like the DHT are able to provide results in less than a second, so lowering this number will allow faster peers lookups in some cases. Type: `optionalDuration` (`null` means default which is 1s) @@ -1552,7 +1574,7 @@ another node, even if this other node is on a different network. This may trigger netscan alerts on some hosting providers or cause strain in some setups. The `server` configuration profile fills up this list with sensible defaults, -preventing dials to all non-routable IP addresses (e.g., `/ip4/192.168.0.0/ipcidr/16`, +preventing dials to all non-routable IP addresses (e.g., `/ip4/192.168.0.0/ipcidr/16`, which is the multiaddress representation of `192.168.0.0/16`) but you should always check settings against your own network and/or hosting provider. diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 9de8c6579..e21648bd4 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.18 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.8.2-0.20230525115135-a8533c998f49 + github.com/ipfs/boxo v0.8.2-0.20230529214945-86cdb2485dad github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.27.3 github.com/multiformats/go-multiaddr v0.9.0 diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 11d274816..d6dd84679 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -321,8 +321,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.8.2-0.20230525115135-a8533c998f49 h1:hi2x0dCINl9fHIV6YM+IH+Bah45pRAFekjM5MMKWJO4= -github.com/ipfs/boxo v0.8.2-0.20230525115135-a8533c998f49/go.mod h1:Ej2r08Z4VIaFKqY08UXMNhwcLf6VekHhK8c+KqA1B9Y= +github.com/ipfs/boxo v0.8.2-0.20230529214945-86cdb2485dad h1:2vkMvvVa5f9fWzts7OcJL6ZS0QaKCcEeOV6I+doPMo0= +github.com/ipfs/boxo v0.8.2-0.20230529214945-86cdb2485dad/go.mod h1:Ej2r08Z4VIaFKqY08UXMNhwcLf6VekHhK8c+KqA1B9Y= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= diff --git a/go.mod b/go.mod index 2799171dc..006c3ab58 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/gogo/protobuf v1.3.2 github.com/google/uuid v1.3.0 github.com/hashicorp/go-multierror v1.1.1 - github.com/ipfs/boxo v0.8.2-0.20230525115135-a8533c998f49 + github.com/ipfs/boxo v0.8.2-0.20230529214945-86cdb2485dad github.com/ipfs/go-block-format v0.1.2 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 diff --git a/go.sum b/go.sum index c9c874dc5..2717767c0 100644 --- a/go.sum +++ b/go.sum @@ -356,8 +356,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.8.2-0.20230525115135-a8533c998f49 h1:hi2x0dCINl9fHIV6YM+IH+Bah45pRAFekjM5MMKWJO4= -github.com/ipfs/boxo v0.8.2-0.20230525115135-a8533c998f49/go.mod h1:Ej2r08Z4VIaFKqY08UXMNhwcLf6VekHhK8c+KqA1B9Y= +github.com/ipfs/boxo v0.8.2-0.20230529214945-86cdb2485dad h1:2vkMvvVa5f9fWzts7OcJL6ZS0QaKCcEeOV6I+doPMo0= +github.com/ipfs/boxo v0.8.2-0.20230529214945-86cdb2485dad/go.mod h1:Ej2r08Z4VIaFKqY08UXMNhwcLf6VekHhK8c+KqA1B9Y= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= diff --git a/test/cli/gateway_test.go b/test/cli/gateway_test.go index 972544ae0..eb955b593 100644 --- a/test/cli/gateway_test.go +++ b/test/cli/gateway_test.go @@ -513,4 +513,87 @@ func TestGateway(t *testing.T) { }) }) }) + + t.Run("DeserializedResponses", func(t *testing.T) { + type testCase struct { + globalValue config.Flag + gatewayValue config.Flag + deserializedGlobalStatusCode int + deserializedGatewayStaticCode int + message string + } + + setHost := func(r *http.Request) { + r.Host = "example.com" + } + + withAccept := func(accept string) func(r *http.Request) { + return func(r *http.Request) { + r.Header.Set("Accept", accept) + } + } + + withHostAndAccept := func(accept string) func(r *http.Request) { + return func(r *http.Request) { + setHost(r) + withAccept(accept)(r) + } + } + + makeTest := func(test *testCase) func(t *testing.T) { + return func(t *testing.T) { + t.Parallel() + + node := harness.NewT(t).NewNode().Init() + node.UpdateConfig(func(cfg *config.Config) { + cfg.Gateway.DeserializedResponses = test.globalValue + cfg.Gateway.PublicGateways = map[string]*config.GatewaySpec{ + "example.com": { + Paths: []string{"/ipfs", "/ipns"}, + DeserializedResponses: test.gatewayValue, + }, + } + }) + node.StartDaemon() + + cidFoo := node.IPFSAddStr("foo") + client := node.GatewayClient() + + deserializedPath := "/ipfs/" + cidFoo + + blockPath := deserializedPath + "?format=raw" + carPath := deserializedPath + "?format=car" + + // Global Check (Gateway.DeserializedResponses) + assert.Equal(t, http.StatusOK, client.Get(blockPath).StatusCode) + assert.Equal(t, http.StatusOK, client.Get(deserializedPath, withAccept("application/vnd.ipld.raw")).StatusCode) + + assert.Equal(t, http.StatusOK, client.Get(carPath).StatusCode) + assert.Equal(t, http.StatusOK, client.Get(deserializedPath, withAccept("application/vnd.ipld.car")).StatusCode) + + assert.Equal(t, test.deserializedGlobalStatusCode, client.Get(deserializedPath).StatusCode) + assert.Equal(t, test.deserializedGlobalStatusCode, client.Get(deserializedPath, withAccept("application/json")).StatusCode) + + // Public Gateway (example.com) Check (Gateway.PublicGateways[example.com].DeserializedResponses) + assert.Equal(t, http.StatusOK, client.Get(blockPath, setHost).StatusCode) + assert.Equal(t, http.StatusOK, client.Get(deserializedPath, withHostAndAccept("application/vnd.ipld.raw")).StatusCode) + + assert.Equal(t, http.StatusOK, client.Get(carPath, setHost).StatusCode) + assert.Equal(t, http.StatusOK, client.Get(deserializedPath, withHostAndAccept("application/vnd.ipld.car")).StatusCode) + + assert.Equal(t, test.deserializedGatewayStaticCode, client.Get(deserializedPath, setHost).StatusCode) + assert.Equal(t, test.deserializedGatewayStaticCode, client.Get(deserializedPath, withHostAndAccept("application/json")).StatusCode) + + } + } + + for _, test := range []*testCase{ + {config.True, config.Default, http.StatusOK, http.StatusOK, "when Gateway.DeserializedResponses is globally enabled, leaving implicit default for Gateway.PublicGateways[example.com] should inherit the global setting (enabled)"}, + {config.False, config.Default, http.StatusNotAcceptable, http.StatusNotAcceptable, "when Gateway.DeserializedResponses is globally disabled, leaving implicit default on Gateway.PublicGateways[example.com] should inherit the global setting (disabled)"}, + {config.False, config.True, http.StatusNotAcceptable, http.StatusOK, "when Gateway.DeserializedResponses is globally disabled, explicitly enabling on Gateway.PublicGateways[example.com] should override global (enabled)"}, + {config.True, config.False, http.StatusOK, http.StatusNotAcceptable, "when Gateway.DeserializedResponses is globally enabled, explicitly disabling on Gateway.PublicGateways[example.com] should override global (disabled)"}, + } { + t.Run(test.message, makeTest(test)) + } + }) } From 18143e2bb38a00b778b4eefc7a31077cf556b480 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Tue, 30 May 2023 19:08:53 +0200 Subject: [PATCH 0684/1212] coreiface: add a testing.T argument to the provider This is usefull because it allows the Provider to use t.Cleanup for cleaning up the nodes. This commit was moved from ipfs/boxo@c23df3837fbe224259a60e8eed9d77e2656f2dce --- core/coreiface/tests/api.go | 20 ++++++++++---------- core/coreiface/tests/block.go | 22 +++++++++++----------- core/coreiface/tests/dag.go | 10 +++++----- core/coreiface/tests/dht.go | 6 +++--- core/coreiface/tests/key.go | 32 ++++++++++++++++---------------- core/coreiface/tests/name.go | 6 +++--- core/coreiface/tests/object.go | 24 ++++++++++++------------ core/coreiface/tests/path.go | 10 +++++----- core/coreiface/tests/pin.go | 16 ++++++++-------- core/coreiface/tests/pubsub.go | 2 +- core/coreiface/tests/routing.go | 8 ++++---- core/coreiface/tests/unixfs.go | 26 +++++++++++++------------- 12 files changed, 91 insertions(+), 91 deletions(-) diff --git a/core/coreiface/tests/api.go b/core/coreiface/tests/api.go index f30990512..a66e2abeb 100644 --- a/core/coreiface/tests/api.go +++ b/core/coreiface/tests/api.go @@ -13,10 +13,10 @@ var errAPINotImplemented = errors.New("api not implemented") type Provider interface { // Make creates n nodes. fullIdentity set to false can be ignored - MakeAPISwarm(ctx context.Context, fullIdentity bool, online bool, n int) ([]coreiface.CoreAPI, error) + MakeAPISwarm(t *testing.T, ctx context.Context, fullIdentity bool, online bool, n int) ([]coreiface.CoreAPI, error) } -func (tp *TestSuite) makeAPISwarm(ctx context.Context, fullIdentity bool, online bool, n int) ([]coreiface.CoreAPI, error) { +func (tp *TestSuite) makeAPISwarm(t *testing.T, ctx context.Context, fullIdentity bool, online bool, n int) ([]coreiface.CoreAPI, error) { if tp.apis != nil { tp.apis <- 1 go func() { @@ -25,11 +25,11 @@ func (tp *TestSuite) makeAPISwarm(ctx context.Context, fullIdentity bool, online }() } - return tp.Provider.MakeAPISwarm(ctx, fullIdentity, online, n) + return tp.Provider.MakeAPISwarm(t, ctx, fullIdentity, online, n) } -func (tp *TestSuite) makeAPI(ctx context.Context) (coreiface.CoreAPI, error) { - api, err := tp.makeAPISwarm(ctx, false, false, 1) +func (tp *TestSuite) makeAPI(t *testing.T, ctx context.Context) (coreiface.CoreAPI, error) { + api, err := tp.makeAPISwarm(t, ctx, false, false, 1) if err != nil { return nil, err } @@ -37,8 +37,8 @@ func (tp *TestSuite) makeAPI(ctx context.Context) (coreiface.CoreAPI, error) { return api[0], nil } -func (tp *TestSuite) makeAPIWithIdentityAndOffline(ctx context.Context) (coreiface.CoreAPI, error) { - api, err := tp.makeAPISwarm(ctx, true, false, 1) +func (tp *TestSuite) makeAPIWithIdentityAndOffline(t *testing.T, ctx context.Context) (coreiface.CoreAPI, error) { + api, err := tp.makeAPISwarm(t, ctx, true, false, 1) if err != nil { return nil, err } @@ -46,8 +46,8 @@ func (tp *TestSuite) makeAPIWithIdentityAndOffline(ctx context.Context) (coreifa return api[0], nil } -func (tp *TestSuite) MakeAPISwarm(ctx context.Context, n int) ([]coreiface.CoreAPI, error) { - return tp.makeAPISwarm(ctx, true, true, n) +func (tp *TestSuite) MakeAPISwarm(t *testing.T, ctx context.Context, n int) ([]coreiface.CoreAPI, error) { + return tp.makeAPISwarm(t, ctx, true, true, n) } type TestSuite struct { @@ -99,7 +99,7 @@ func TestApi(p Provider) func(t *testing.T) { func (tp *TestSuite) hasApi(t *testing.T, tf func(coreiface.CoreAPI) error) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) } diff --git a/core/coreiface/tests/block.go b/core/coreiface/tests/block.go index c884f3e82..5dcb16e4f 100644 --- a/core/coreiface/tests/block.go +++ b/core/coreiface/tests/block.go @@ -58,7 +58,7 @@ func (tp *TestSuite) TestBlock(t *testing.T) { func (tp *TestSuite) TestBlockPut(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) } @@ -78,7 +78,7 @@ func (tp *TestSuite) TestBlockPut(t *testing.T) { func (tp *TestSuite) TestBlockPutFormatDagCbor(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) } @@ -98,7 +98,7 @@ func (tp *TestSuite) TestBlockPutFormatDagCbor(t *testing.T) { func (tp *TestSuite) TestBlockPutFormatDagPb(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) } @@ -118,7 +118,7 @@ func (tp *TestSuite) TestBlockPutFormatDagPb(t *testing.T) { func (tp *TestSuite) TestBlockPutFormatV0(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) } @@ -136,7 +136,7 @@ func (tp *TestSuite) TestBlockPutFormatV0(t *testing.T) { func (tp *TestSuite) TestBlockPutCidCodecDagCbor(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) } @@ -154,7 +154,7 @@ func (tp *TestSuite) TestBlockPutCidCodecDagCbor(t *testing.T) { func (tp *TestSuite) TestBlockPutCidCodecDagPb(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) } @@ -172,7 +172,7 @@ func (tp *TestSuite) TestBlockPutCidCodecDagPb(t *testing.T) { func (tp *TestSuite) TestBlockPutHash(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) } @@ -195,7 +195,7 @@ func (tp *TestSuite) TestBlockPutHash(t *testing.T) { func (tp *TestSuite) TestBlockGet(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) } @@ -233,7 +233,7 @@ func (tp *TestSuite) TestBlockGet(t *testing.T) { func (tp *TestSuite) TestBlockRm(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) } @@ -287,7 +287,7 @@ func (tp *TestSuite) TestBlockRm(t *testing.T) { func (tp *TestSuite) TestBlockStat(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) } @@ -314,7 +314,7 @@ func (tp *TestSuite) TestBlockStat(t *testing.T) { func (tp *TestSuite) TestBlockPin(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) } diff --git a/core/coreiface/tests/dag.go b/core/coreiface/tests/dag.go index b4118e2cc..ba74031f9 100644 --- a/core/coreiface/tests/dag.go +++ b/core/coreiface/tests/dag.go @@ -44,7 +44,7 @@ var ( func (tp *TestSuite) TestPut(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) } @@ -67,7 +67,7 @@ func (tp *TestSuite) TestPut(t *testing.T) { func (tp *TestSuite) TestPutWithHash(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) } @@ -90,7 +90,7 @@ func (tp *TestSuite) TestPutWithHash(t *testing.T) { func (tp *TestSuite) TestDagPath(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) } @@ -135,7 +135,7 @@ func (tp *TestSuite) TestDagPath(t *testing.T) { func (tp *TestSuite) TestTree(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) } @@ -170,7 +170,7 @@ func (tp *TestSuite) TestTree(t *testing.T) { func (tp *TestSuite) TestBatch(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) } diff --git a/core/coreiface/tests/dht.go b/core/coreiface/tests/dht.go index 61f9fd687..3b3ac1d61 100644 --- a/core/coreiface/tests/dht.go +++ b/core/coreiface/tests/dht.go @@ -26,7 +26,7 @@ func (tp *TestSuite) TestDht(t *testing.T) { func (tp *TestSuite) TestDhtFindPeer(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - apis, err := tp.MakeAPISwarm(ctx, 5) + apis, err := tp.MakeAPISwarm(t, ctx, 5) if err != nil { t.Fatal(err) } @@ -81,7 +81,7 @@ func (tp *TestSuite) TestDhtFindPeer(t *testing.T) { func (tp *TestSuite) TestDhtFindProviders(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - apis, err := tp.MakeAPISwarm(ctx, 5) + apis, err := tp.MakeAPISwarm(t, ctx, 5) if err != nil { t.Fatal(err) } @@ -113,7 +113,7 @@ func (tp *TestSuite) TestDhtFindProviders(t *testing.T) { func (tp *TestSuite) TestDhtProvide(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - apis, err := tp.MakeAPISwarm(ctx, 5) + apis, err := tp.MakeAPISwarm(t, ctx, 5) if err != nil { t.Fatal(err) } diff --git a/core/coreiface/tests/key.go b/core/coreiface/tests/key.go index 3a38c07ae..0b755380e 100644 --- a/core/coreiface/tests/key.go +++ b/core/coreiface/tests/key.go @@ -40,7 +40,7 @@ func (tp *TestSuite) TestKey(t *testing.T) { func (tp *TestSuite) TestListSelf(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) return @@ -74,7 +74,7 @@ func (tp *TestSuite) TestListSelf(t *testing.T) { func (tp *TestSuite) TestRenameSelf(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) return @@ -102,7 +102,7 @@ func (tp *TestSuite) TestRenameSelf(t *testing.T) { func (tp *TestSuite) TestRemoveSelf(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) return @@ -121,7 +121,7 @@ func (tp *TestSuite) TestRemoveSelf(t *testing.T) { func (tp *TestSuite) TestGenerate(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) } @@ -165,7 +165,7 @@ func verifyIPNSPath(t *testing.T, p string) bool { func (tp *TestSuite) TestGenerateSize(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) } @@ -189,7 +189,7 @@ func (tp *TestSuite) TestGenerateType(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) } @@ -213,7 +213,7 @@ func (tp *TestSuite) TestGenerateType(t *testing.T) { func (tp *TestSuite) TestGenerateExisting(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) } @@ -246,7 +246,7 @@ func (tp *TestSuite) TestGenerateExisting(t *testing.T) { func (tp *TestSuite) TestList(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) } @@ -285,7 +285,7 @@ func (tp *TestSuite) TestList(t *testing.T) { func (tp *TestSuite) TestRename(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) } @@ -314,7 +314,7 @@ func (tp *TestSuite) TestRename(t *testing.T) { func (tp *TestSuite) TestRenameToSelf(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) } @@ -338,7 +338,7 @@ func (tp *TestSuite) TestRenameToSelf(t *testing.T) { func (tp *TestSuite) TestRenameToSelfForce(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) } @@ -362,7 +362,7 @@ func (tp *TestSuite) TestRenameToSelfForce(t *testing.T) { func (tp *TestSuite) TestRenameOverwriteNoForce(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) } @@ -392,7 +392,7 @@ func (tp *TestSuite) TestRenameOverwriteNoForce(t *testing.T) { func (tp *TestSuite) TestRenameOverwrite(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) } @@ -431,7 +431,7 @@ func (tp *TestSuite) TestRenameOverwrite(t *testing.T) { func (tp *TestSuite) TestRenameSameNameNoForce(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) } @@ -460,7 +460,7 @@ func (tp *TestSuite) TestRenameSameNameNoForce(t *testing.T) { func (tp *TestSuite) TestRenameSameName(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) } @@ -489,7 +489,7 @@ func (tp *TestSuite) TestRenameSameName(t *testing.T) { func (tp *TestSuite) TestRemove(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) } diff --git a/core/coreiface/tests/name.go b/core/coreiface/tests/name.go index a669e0c02..8fa733567 100644 --- a/core/coreiface/tests/name.go +++ b/core/coreiface/tests/name.go @@ -43,7 +43,7 @@ func (tp *TestSuite) TestPublishResolve(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() init := func() (coreiface.CoreAPI, path.Path) { - apis, err := tp.MakeAPISwarm(ctx, 5) + apis, err := tp.MakeAPISwarm(t, ctx, 5) if err != nil { t.Fatal(err) return nil, nil @@ -191,7 +191,7 @@ func (tp *TestSuite) TestPublishResolve(t *testing.T) { func (tp *TestSuite) TestBasicPublishResolveKey(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - apis, err := tp.MakeAPISwarm(ctx, 5) + apis, err := tp.MakeAPISwarm(t, ctx, 5) if err != nil { t.Fatal(err) } @@ -235,7 +235,7 @@ func (tp *TestSuite) TestBasicPublishResolveTimeout(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - apis, err := tp.MakeAPISwarm(ctx, 5) + apis, err := tp.MakeAPISwarm(t, ctx, 5) if err != nil { t.Fatal(err) } diff --git a/core/coreiface/tests/object.go b/core/coreiface/tests/object.go index 8e8f52b3d..77061b699 100644 --- a/core/coreiface/tests/object.go +++ b/core/coreiface/tests/object.go @@ -37,7 +37,7 @@ func (tp *TestSuite) TestObject(t *testing.T) { func (tp *TestSuite) TestNew(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) } @@ -64,7 +64,7 @@ func (tp *TestSuite) TestNew(t *testing.T) { func (tp *TestSuite) TestObjectPut(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) } @@ -105,7 +105,7 @@ func (tp *TestSuite) TestObjectPut(t *testing.T) { func (tp *TestSuite) TestObjectGet(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) } @@ -128,7 +128,7 @@ func (tp *TestSuite) TestObjectGet(t *testing.T) { func (tp *TestSuite) TestObjectData(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) } @@ -156,7 +156,7 @@ func (tp *TestSuite) TestObjectData(t *testing.T) { func (tp *TestSuite) TestObjectLinks(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) } @@ -192,7 +192,7 @@ func (tp *TestSuite) TestObjectLinks(t *testing.T) { func (tp *TestSuite) TestObjectStat(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) } @@ -240,7 +240,7 @@ func (tp *TestSuite) TestObjectStat(t *testing.T) { func (tp *TestSuite) TestObjectAddLink(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) } @@ -281,7 +281,7 @@ func (tp *TestSuite) TestObjectAddLink(t *testing.T) { func (tp *TestSuite) TestObjectAddLinkCreate(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) } @@ -330,7 +330,7 @@ func (tp *TestSuite) TestObjectAddLinkCreate(t *testing.T) { func (tp *TestSuite) TestObjectRmLink(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) } @@ -363,7 +363,7 @@ func (tp *TestSuite) TestObjectRmLink(t *testing.T) { func (tp *TestSuite) TestObjectAddData(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) } @@ -396,7 +396,7 @@ func (tp *TestSuite) TestObjectAddData(t *testing.T) { func (tp *TestSuite) TestObjectSetData(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) } @@ -429,7 +429,7 @@ func (tp *TestSuite) TestObjectSetData(t *testing.T) { func (tp *TestSuite) TestDiffTest(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) } diff --git a/core/coreiface/tests/path.go b/core/coreiface/tests/path.go index 321c79d6e..06f3aa1f8 100644 --- a/core/coreiface/tests/path.go +++ b/core/coreiface/tests/path.go @@ -25,7 +25,7 @@ func (tp *TestSuite) TestPath(t *testing.T) { func (tp *TestSuite) TestMutablePath(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) } @@ -58,7 +58,7 @@ func (tp *TestSuite) TestMutablePath(t *testing.T) { func (tp *TestSuite) TestPathRemainder(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) } @@ -89,7 +89,7 @@ func (tp *TestSuite) TestPathRemainder(t *testing.T) { func (tp *TestSuite) TestEmptyPathRemainder(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) } @@ -120,7 +120,7 @@ func (tp *TestSuite) TestEmptyPathRemainder(t *testing.T) { func (tp *TestSuite) TestInvalidPathRemainder(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) } @@ -147,7 +147,7 @@ func (tp *TestSuite) TestInvalidPathRemainder(t *testing.T) { func (tp *TestSuite) TestPathRoot(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) } diff --git a/core/coreiface/tests/pin.go b/core/coreiface/tests/pin.go index ac90d097e..bbf602994 100644 --- a/core/coreiface/tests/pin.go +++ b/core/coreiface/tests/pin.go @@ -34,7 +34,7 @@ func (tp *TestSuite) TestPin(t *testing.T) { func (tp *TestSuite) TestPinAdd(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) } @@ -53,7 +53,7 @@ func (tp *TestSuite) TestPinAdd(t *testing.T) { func (tp *TestSuite) TestPinSimple(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) } @@ -105,7 +105,7 @@ func (tp *TestSuite) TestPinSimple(t *testing.T) { func (tp *TestSuite) TestPinRecursive(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) } @@ -249,7 +249,7 @@ func (tp *TestSuite) TestPinRecursive(t *testing.T) { func (tp *TestSuite) TestPinLsIndirect(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) } @@ -282,7 +282,7 @@ func (tp *TestSuite) TestPinLsPrecedence(t *testing.T) { func (tp *TestSuite) TestPinLsPredenceRecursiveIndirect(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) } @@ -306,7 +306,7 @@ func (tp *TestSuite) TestPinLsPredenceRecursiveIndirect(t *testing.T) { func (tp *TestSuite) TestPinLsPrecedenceDirectIndirect(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) } @@ -330,7 +330,7 @@ func (tp *TestSuite) TestPinLsPrecedenceDirectIndirect(t *testing.T) { func (tp *TestSuite) TestPinLsPrecedenceRecursiveDirect(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) } @@ -366,7 +366,7 @@ func (tp *TestSuite) TestPinLsPrecedenceRecursiveDirect(t *testing.T) { func (tp *TestSuite) TestPinIsPinned(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) } diff --git a/core/coreiface/tests/pubsub.go b/core/coreiface/tests/pubsub.go index 24a8ac309..8cbc6a3eb 100644 --- a/core/coreiface/tests/pubsub.go +++ b/core/coreiface/tests/pubsub.go @@ -24,7 +24,7 @@ func (tp *TestSuite) TestBasicPubSub(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - apis, err := tp.MakeAPISwarm(ctx, 2) + apis, err := tp.MakeAPISwarm(t, ctx, 2) if err != nil { t.Fatal(err) } diff --git a/core/coreiface/tests/routing.go b/core/coreiface/tests/routing.go index bf314cafe..6fca1a003 100644 --- a/core/coreiface/tests/routing.go +++ b/core/coreiface/tests/routing.go @@ -43,7 +43,7 @@ func (tp *TestSuite) TestRoutingGet(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - apis, err := tp.MakeAPISwarm(ctx, 2) + apis, err := tp.MakeAPISwarm(t, ctx, 2) if err != nil { t.Fatal(err) } @@ -72,7 +72,7 @@ func (tp *TestSuite) TestRoutingGet(t *testing.T) { func (tp *TestSuite) TestRoutingPut(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - apis, err := tp.MakeAPISwarm(ctx, 2) + apis, err := tp.MakeAPISwarm(t, ctx, 2) if err != nil { t.Fatal(err) } @@ -98,7 +98,7 @@ func (tp *TestSuite) TestRoutingPutOffline(t *testing.T) { defer cancel() // init a swarm & publish an IPNS entry to get a valid payload - apis, err := tp.MakeAPISwarm(ctx, 2) + apis, err := tp.MakeAPISwarm(t, ctx, 2) if err != nil { t.Fatal(err) } @@ -110,7 +110,7 @@ func (tp *TestSuite) TestRoutingPutOffline(t *testing.T) { } // init our offline node and try to put the payload - api, err := tp.makeAPIWithIdentityAndOffline(ctx) + api, err := tp.makeAPIWithIdentityAndOffline(t, ctx) if err != nil { t.Fatal(err) } diff --git a/core/coreiface/tests/unixfs.go b/core/coreiface/tests/unixfs.go index cca42bb28..2842b47bc 100644 --- a/core/coreiface/tests/unixfs.go +++ b/core/coreiface/tests/unixfs.go @@ -99,7 +99,7 @@ func wrapped(names ...string) func(f files.Node) files.Node { func (tp *TestSuite) TestAdd(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) } @@ -533,7 +533,7 @@ func (tp *TestSuite) TestAdd(t *testing.T) { func (tp *TestSuite) TestAddPinned(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) } @@ -559,7 +559,7 @@ func (tp *TestSuite) TestAddPinned(t *testing.T) { func (tp *TestSuite) TestAddHashOnly(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) } @@ -585,7 +585,7 @@ func (tp *TestSuite) TestAddHashOnly(t *testing.T) { func (tp *TestSuite) TestGetEmptyFile(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) } @@ -615,7 +615,7 @@ func (tp *TestSuite) TestGetEmptyFile(t *testing.T) { func (tp *TestSuite) TestGetDir(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) } @@ -648,7 +648,7 @@ func (tp *TestSuite) TestGetDir(t *testing.T) { func (tp *TestSuite) TestGetNonUnixfs(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) } @@ -668,7 +668,7 @@ func (tp *TestSuite) TestGetNonUnixfs(t *testing.T) { func (tp *TestSuite) TestLs(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) } @@ -728,7 +728,7 @@ func (tp *TestSuite) TestLs(t *testing.T) { func (tp *TestSuite) TestEntriesExpired(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) } @@ -770,7 +770,7 @@ func (tp *TestSuite) TestEntriesExpired(t *testing.T) { func (tp *TestSuite) TestLsEmptyDir(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) } @@ -799,7 +799,7 @@ func (tp *TestSuite) TestLsEmptyDir(t *testing.T) { func (tp *TestSuite) TestLsNonUnixfs(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) } @@ -858,7 +858,7 @@ func (f *closeTestF) Close() error { func (tp *TestSuite) TestAddCloses(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) } @@ -896,7 +896,7 @@ func (tp *TestSuite) TestAddCloses(t *testing.T) { func (tp *TestSuite) TestGetSeek(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) } @@ -1002,7 +1002,7 @@ func (tp *TestSuite) TestGetSeek(t *testing.T) { func (tp *TestSuite) TestGetReadAt(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(ctx) + api, err := tp.makeAPI(t, ctx) if err != nil { t.Fatal(err) } From 12f343d837850b0cb198ccf2b40630bdbf1ec715 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Wed, 31 May 2023 14:29:59 +0200 Subject: [PATCH 0685/1212] client/rpc: rename package name to match rpc and edit migration story --- client/rpc/README.md | 6 +++--- client/rpc/api.go | 2 +- client/rpc/api_test.go | 2 +- client/rpc/apifile.go | 2 +- client/rpc/block.go | 2 +- client/rpc/dag.go | 2 +- client/rpc/dht.go | 2 +- client/rpc/errors.go | 2 +- client/rpc/errors_test.go | 2 +- client/rpc/key.go | 2 +- client/rpc/name.go | 2 +- client/rpc/object.go | 2 +- client/rpc/path.go | 2 +- client/rpc/pin.go | 2 +- client/rpc/pubsub.go | 2 +- client/rpc/request.go | 2 +- client/rpc/requestbuilder.go | 2 +- client/rpc/response.go | 2 +- client/rpc/routing.go | 2 +- client/rpc/swarm.go | 2 +- client/rpc/unixfs.go | 2 +- docs/changelogs/v0.21.md | 3 ++- docs/http-rpc-clients.md | 4 ++-- 23 files changed, 27 insertions(+), 26 deletions(-) diff --git a/client/rpc/README.md b/client/rpc/README.md index e6b534b90..a020aa9da 100644 --- a/client/rpc/README.md +++ b/client/rpc/README.md @@ -1,4 +1,4 @@ -# `httpapi` +# `coreiface.CoreAPI` over http `rpc` > IPFS CoreAPI implementation using HTTP API @@ -19,13 +19,13 @@ import ( "context" "fmt" - ipfsClient "github.com/ipfs/kubo/client/rpc" + "github.com/ipfs/kubo/client/rpc" path "github.com/ipfs/boxo/coreiface/path" ) func main() { // "Connect" to local node - node, err := ipfsClient.NewLocalApi() + node, err := rpc.NewLocalApi() if err != nil { fmt.Printf(err) return diff --git a/client/rpc/api.go b/client/rpc/api.go index 5584de85d..4df4dfde1 100644 --- a/client/rpc/api.go +++ b/client/rpc/api.go @@ -1,4 +1,4 @@ -package httpapi +package rpc import ( "errors" diff --git a/client/rpc/api_test.go b/client/rpc/api_test.go index 2fd8a65dc..51f8cf89d 100644 --- a/client/rpc/api_test.go +++ b/client/rpc/api_test.go @@ -1,4 +1,4 @@ -package httpapi +package rpc import ( "context" diff --git a/client/rpc/apifile.go b/client/rpc/apifile.go index 25fd7c3b3..24e93a834 100644 --- a/client/rpc/apifile.go +++ b/client/rpc/apifile.go @@ -1,4 +1,4 @@ -package httpapi +package rpc import ( "context" diff --git a/client/rpc/block.go b/client/rpc/block.go index 2a794c26f..a11e5e655 100644 --- a/client/rpc/block.go +++ b/client/rpc/block.go @@ -1,4 +1,4 @@ -package httpapi +package rpc import ( "bytes" diff --git a/client/rpc/dag.go b/client/rpc/dag.go index 795e1d78d..62b54697e 100644 --- a/client/rpc/dag.go +++ b/client/rpc/dag.go @@ -1,4 +1,4 @@ -package httpapi +package rpc import ( "bytes" diff --git a/client/rpc/dht.go b/client/rpc/dht.go index a2910fef6..1d3b24643 100644 --- a/client/rpc/dht.go +++ b/client/rpc/dht.go @@ -1,4 +1,4 @@ -package httpapi +package rpc import ( "context" diff --git a/client/rpc/errors.go b/client/rpc/errors.go index 59e4ad705..dc5946be3 100644 --- a/client/rpc/errors.go +++ b/client/rpc/errors.go @@ -1,4 +1,4 @@ -package httpapi +package rpc import ( "errors" diff --git a/client/rpc/errors_test.go b/client/rpc/errors_test.go index 0e6cfe0dc..c14738740 100644 --- a/client/rpc/errors_test.go +++ b/client/rpc/errors_test.go @@ -1,4 +1,4 @@ -package httpapi +package rpc import ( "errors" diff --git a/client/rpc/key.go b/client/rpc/key.go index 434e98fe5..487c14c3d 100644 --- a/client/rpc/key.go +++ b/client/rpc/key.go @@ -1,4 +1,4 @@ -package httpapi +package rpc import ( "context" diff --git a/client/rpc/name.go b/client/rpc/name.go index f82f69f3a..e6c726c58 100644 --- a/client/rpc/name.go +++ b/client/rpc/name.go @@ -1,4 +1,4 @@ -package httpapi +package rpc import ( "context" diff --git a/client/rpc/object.go b/client/rpc/object.go index 4e3b9ef6b..5860c7661 100644 --- a/client/rpc/object.go +++ b/client/rpc/object.go @@ -1,4 +1,4 @@ -package httpapi +package rpc import ( "bytes" diff --git a/client/rpc/path.go b/client/rpc/path.go index d69d425ab..6edf0e797 100644 --- a/client/rpc/path.go +++ b/client/rpc/path.go @@ -1,4 +1,4 @@ -package httpapi +package rpc import ( "context" diff --git a/client/rpc/pin.go b/client/rpc/pin.go index 30a3d7b7a..9ce92b4cf 100644 --- a/client/rpc/pin.go +++ b/client/rpc/pin.go @@ -1,4 +1,4 @@ -package httpapi +package rpc import ( "context" diff --git a/client/rpc/pubsub.go b/client/rpc/pubsub.go index 28f1ef8e6..a386c80a1 100644 --- a/client/rpc/pubsub.go +++ b/client/rpc/pubsub.go @@ -1,4 +1,4 @@ -package httpapi +package rpc import ( "bytes" diff --git a/client/rpc/request.go b/client/rpc/request.go index dd5293b7a..675717707 100644 --- a/client/rpc/request.go +++ b/client/rpc/request.go @@ -1,4 +1,4 @@ -package httpapi +package rpc import ( "context" diff --git a/client/rpc/requestbuilder.go b/client/rpc/requestbuilder.go index 476aed786..63206be40 100644 --- a/client/rpc/requestbuilder.go +++ b/client/rpc/requestbuilder.go @@ -1,4 +1,4 @@ -package httpapi +package rpc import ( "bytes" diff --git a/client/rpc/response.go b/client/rpc/response.go index 189b43671..bad274777 100644 --- a/client/rpc/response.go +++ b/client/rpc/response.go @@ -1,4 +1,4 @@ -package httpapi +package rpc import ( "encoding/json" diff --git a/client/rpc/routing.go b/client/rpc/routing.go index 550308329..a6c4f5c08 100644 --- a/client/rpc/routing.go +++ b/client/rpc/routing.go @@ -1,4 +1,4 @@ -package httpapi +package rpc import ( "bytes" diff --git a/client/rpc/swarm.go b/client/rpc/swarm.go index 9b073078d..49ece0d07 100644 --- a/client/rpc/swarm.go +++ b/client/rpc/swarm.go @@ -1,4 +1,4 @@ -package httpapi +package rpc import ( "context" diff --git a/client/rpc/unixfs.go b/client/rpc/unixfs.go index b9c34c59f..2099f190b 100644 --- a/client/rpc/unixfs.go +++ b/client/rpc/unixfs.go @@ -1,4 +1,4 @@ -package httpapi +package rpc import ( "context" diff --git a/docs/changelogs/v0.21.md b/docs/changelogs/v0.21.md index d88a48fa6..ce08e3dcc 100644 --- a/docs/changelogs/v0.21.md +++ b/docs/changelogs/v0.21.md @@ -66,7 +66,8 @@ updated the CoreAPI with new Kubo features but forgot to port thoses to the http-client, making it impossible to use them together with the same coreapi version. -**TODO(@Jorropo)**: add link to `boxo-migrate` once support for rewriting this import path has been added +For smooth transition `v0.7.0` of `go-ipfs-http-client` provides updated stubs +for Kubo `v0.21`. ### 📝 Changelog diff --git a/docs/http-rpc-clients.md b/docs/http-rpc-clients.md index 0a6ea369d..0b4baa1b0 100644 --- a/docs/http-rpc-clients.md +++ b/docs/http-rpc-clients.md @@ -4,11 +4,11 @@ Kubo provides official HTTP RPC (`/api/v0`) clients for selected languages: - [`js-kubo-rpc-client`](https://github.com/ipfs/js-kubo-rpc-client) - Official JS client for talking to Kubo RPC over HTTP - [`go-ipfs-api`](https://github.com/ipfs/go-ipfs-api) - The go interface to ipfs's HTTP RPC - Follow https://github.com/ipfs/kubo/issues/9124 for coming changes. -- [`httpapi`](./client/rpc) (previously `go-ipfs-http-client`)) - IPFS CoreAPI implementation using HTTP RPC +- [`httpapi`](./client/rpc) (previously `go-ipfs-http-client`) - [`coreiface.CoreAPI`](https://pkg.go.dev/github.com/ipfs/boxo/coreiface#CoreAPI) implementation using HTTP RPC ## Recommended clients | Language | Package Name | Github Repository | |:--------:|:-------------------:|--------------------------------------------| | JS | kubo-rpc-client | https://github.com/ipfs/js-kubo-rpc-client | -| Go | `httpapi` | [`./client/rpc`](./client/rpc) | +| Go | `rpc` | [`./client/rpc`](./client/rpc) | From 5a993cf20dc251adc196a230e0c1fd43d8f9c33d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 31 May 2023 08:18:48 +0000 Subject: [PATCH 0686/1212] chore(deps): bump go.uber.org/dig from 1.16.1 to 1.17.0 Bumps [go.uber.org/dig](https://github.com/uber-go/dig) from 1.16.1 to 1.17.0. - [Release notes](https://github.com/uber-go/dig/releases) - [Changelog](https://github.com/uber-go/dig/blob/master/CHANGELOG.md) - [Commits](https://github.com/uber-go/dig/compare/v1.16.1...v1.17.0) --- updated-dependencies: - dependency-name: go.uber.org/dig dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index e03472af8..00cb50575 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -174,7 +174,7 @@ require ( go.opentelemetry.io/otel/trace v1.14.0 // indirect go.opentelemetry.io/proto/otlp v0.19.0 // indirect go.uber.org/atomic v1.10.0 // indirect - go.uber.org/dig v1.16.1 // indirect + go.uber.org/dig v1.17.0 // indirect go.uber.org/fx v1.19.2 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.24.0 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 542d2e512..e19356484 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -840,8 +840,8 @@ go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/dig v1.16.1 h1:+alNIBsl0qfY0j6epRubp/9obgtrObRAc5aD+6jbWY8= -go.uber.org/dig v1.16.1/go.mod h1:557JTAUZT5bUK0SvCwikmLPPtdQhfvLYtO5tJgQSbnk= +go.uber.org/dig v1.17.0 h1:5Chju+tUvcC+N7N6EV08BJz41UZuO3BmHcN4A287ZLI= +go.uber.org/dig v1.17.0/go.mod h1:rTxpf7l5I0eBTlE6/9RL+lDybC7WFwY2QH55ZSjy1mU= go.uber.org/fx v1.19.2 h1:SyFgYQFr1Wl0AYstE8vyYIzP4bFz2URrScjwC4cwUvY= go.uber.org/fx v1.19.2/go.mod h1:43G1VcqSzbIv77y00p1DRAsyZS8WdzuYdhZXmEUkMyQ= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= diff --git a/go.mod b/go.mod index e34d6461f..87e7dfea1 100644 --- a/go.mod +++ b/go.mod @@ -77,7 +77,7 @@ require ( go.opentelemetry.io/otel v1.14.0 go.opentelemetry.io/otel/sdk v1.14.0 go.opentelemetry.io/otel/trace v1.14.0 - go.uber.org/dig v1.16.1 + go.uber.org/dig v1.17.0 go.uber.org/fx v1.19.2 go.uber.org/multierr v1.11.0 go.uber.org/zap v1.24.0 diff --git a/go.sum b/go.sum index 1c2f1079b..b8dcfb8ff 100644 --- a/go.sum +++ b/go.sum @@ -970,8 +970,8 @@ go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/dig v1.16.1 h1:+alNIBsl0qfY0j6epRubp/9obgtrObRAc5aD+6jbWY8= -go.uber.org/dig v1.16.1/go.mod h1:557JTAUZT5bUK0SvCwikmLPPtdQhfvLYtO5tJgQSbnk= +go.uber.org/dig v1.17.0 h1:5Chju+tUvcC+N7N6EV08BJz41UZuO3BmHcN4A287ZLI= +go.uber.org/dig v1.17.0/go.mod h1:rTxpf7l5I0eBTlE6/9RL+lDybC7WFwY2QH55ZSjy1mU= go.uber.org/fx v1.19.2 h1:SyFgYQFr1Wl0AYstE8vyYIzP4bFz2URrScjwC4cwUvY= go.uber.org/fx v1.19.2/go.mod h1:43G1VcqSzbIv77y00p1DRAsyZS8WdzuYdhZXmEUkMyQ= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= From 99fdaa1b4dc46e369a72989d2e1b3a6bfbf1a11c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Mur=C3=A9?= Date: Wed, 31 May 2023 17:49:21 +0200 Subject: [PATCH 0687/1212] plugin: fix non-deterministic loading order fix #9909 --- plugin/loader/loader.go | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/plugin/loader/loader.go b/plugin/loader/loader.go index 0742e6a49..f891bb570 100644 --- a/plugin/loader/loader.go +++ b/plugin/loader/loader.go @@ -87,7 +87,7 @@ func (ls loaderState) String() string { // 5. Call Close to close all plugins. type PluginLoader struct { state loaderState - plugins map[string]plugin.Plugin + plugins []plugin.Plugin started []plugin.Plugin config config.Plugins repo string @@ -95,7 +95,7 @@ type PluginLoader struct { // NewPluginLoader creates new plugin loader func NewPluginLoader(repo string) (*PluginLoader, error) { - loader := &PluginLoader{plugins: make(map[string]plugin.Plugin, len(preloadPlugins)), repo: repo} + loader := &PluginLoader{plugins: make([]plugin.Plugin, 0, len(preloadPlugins)), repo: repo} if repo != "" { cfg, err := cserialize.Load(filepath.Join(repo, config.DefaultConfigFile)) switch err { @@ -106,6 +106,7 @@ func NewPluginLoader(repo string) (*PluginLoader, error) { return nil, err } } + for _, v := range preloadPlugins { if err := loader.Load(v); err != nil { return nil, err @@ -140,18 +141,22 @@ func (loader *PluginLoader) Load(pl plugin.Plugin) error { } name := pl.Name() - if ppl, ok := loader.plugins[name]; ok { - // plugin is already loaded - return fmt.Errorf( - "plugin: %s, is duplicated in version: %s, "+ - "while trying to load dynamically: %s", - name, ppl.Version(), pl.Version()) + + for _, p := range loader.plugins { + if p.Name() == name { + // plugin is already loaded + return fmt.Errorf( + "plugin: %s, is duplicated in version: %s, "+ + "while trying to load dynamically: %s", + name, p.Version(), pl.Version()) + } } + if loader.config.Plugins[name].Disabled { log.Infof("not loading disabled plugin %s", name) return nil } - loader.plugins[name] = pl + loader.plugins = append(loader.plugins, pl) return nil } @@ -219,10 +224,10 @@ func (loader *PluginLoader) Initialize() error { if err := loader.transition(loaderLoading, loaderInitializing); err != nil { return err } - for name, p := range loader.plugins { + for _, p := range loader.plugins { err := p.Init(&plugin.Environment{ Repo: loader.repo, - Config: loader.config.Plugins[name].Config, + Config: loader.config.Plugins[p.Name()].Config, }) if err != nil { loader.state = loaderFailed From 67e1a173fcde1b7c4b09464184aea8ef86bedab2 Mon Sep 17 00:00:00 2001 From: imthe1 Date: Thu, 20 Apr 2023 20:54:43 +0530 Subject: [PATCH 0688/1212] feat: adds secp256k1 keypair type to key gen command, adds test cases --- core/commands/keystore.go | 6 +++--- core/coreapi/key.go | 8 ++++++++ test/sharness/lib/test-lib.sh | 16 ++++++++++++++++ test/sharness/t0027-rotate.sh | 7 +++++++ test/sharness/t0165-keystore.sh | 31 +++++++++++++++++++++++++++++++ 5 files changed, 65 insertions(+), 3 deletions(-) diff --git a/core/commands/keystore.go b/core/commands/keystore.go index ed0d5d4e9..cf3e75b7d 100644 --- a/core/commands/keystore.go +++ b/core/commands/keystore.go @@ -83,7 +83,7 @@ var keyGenCmd = &cmds.Command{ Tagline: "Create a new keypair", }, Options: []cmds.Option{ - cmds.StringOption(keyStoreTypeOptionName, "t", "type of the key to create: rsa, ed25519").WithDefault(keyStoreAlgorithmDefault), + cmds.StringOption(keyStoreTypeOptionName, "t", "type of the key to create: rsa, ed25519, secp256k1").WithDefault(keyStoreAlgorithmDefault), cmds.IntOption(keyStoreSizeOptionName, "s", "size of the key to generate"), ke.OptionIPNSBase, }, @@ -398,7 +398,7 @@ The PEM format allows for key generation outside of the IPFS node: allowAnyKeyType, _ := req.Options[keyAllowAnyTypeOptionName].(bool) if !allowAnyKeyType { switch t := sk.(type) { - case *crypto.RsaPrivateKey, *crypto.Ed25519PrivateKey: + case *crypto.RsaPrivateKey, *crypto.Ed25519PrivateKey, *crypto.Secp256k1PrivateKey: default: return fmt.Errorf("key type %T is not allowed to be imported, only RSA or Ed25519;"+ " use flag --%s if you are sure of what you're doing", @@ -604,7 +604,7 @@ environment variable: Arguments: []cmds.Argument{}, Options: []cmds.Option{ cmds.StringOption(oldKeyOptionName, "o", "Keystore name to use for backing up your existing identity"), - cmds.StringOption(keyStoreTypeOptionName, "t", "type of the key to create: rsa, ed25519").WithDefault(keyStoreAlgorithmDefault), + cmds.StringOption(keyStoreTypeOptionName, "t", "type of the key to create: rsa, ed25519, secp256k1").WithDefault(keyStoreAlgorithmDefault), cmds.IntOption(keyStoreSizeOptionName, "s", "size of the key to generate"), }, NoRemote: true, diff --git a/core/coreapi/key.go b/core/coreapi/key.go index 925748a37..743f2076e 100644 --- a/core/coreapi/key.go +++ b/core/coreapi/key.go @@ -82,6 +82,14 @@ func (api *KeyAPI) Generate(ctx context.Context, name string, opts ...caopts.Key return nil, err } + sk = priv + pk = pub + case "secp256k1": + priv, pub, err := crypto.GenerateSecp256k1Key(rand.Reader) + if err != nil { + return nil, err + } + sk = priv pk = pub default: diff --git a/test/sharness/lib/test-lib.sh b/test/sharness/lib/test-lib.sh index bd8f7de9b..35c4ae835 100644 --- a/test/sharness/lib/test-lib.sh +++ b/test/sharness/lib/test-lib.sh @@ -486,6 +486,14 @@ test_check_ed25519_b58mh_peerid() { } } +test_check_secp256k1_b58mh_peerid() { + peeridlen=$(echo "$1" | tr -dC "[:alnum:]" | wc -c | tr -d " ") && + test "$peeridlen" = "53" || { + echo "Bad SECP256K1 B58MH peerid '$1' with len '$peeridlen'" + return 1 + } +} + test_check_rsa2048_base36_peerid() { peeridlen=$(echo "$1" | tr -dC "[:alnum:]" | wc -c | tr -d " ") && test "$peeridlen" = "56" || { @@ -502,6 +510,14 @@ test_check_ed25519_base36_peerid() { } } +test_check_secp256k1_base36_peerid() { + peeridlen=$(echo "$1" | tr -dC "[:alnum:]" | wc -c | tr -d " ") && + test "$peeridlen" = "63" || { + echo "Bad SECP256K1 B36CID peerid '$1' with len '$peeridlen'" + return 1 + } +} + convert_tcp_maddr() { echo $1 | awk -F'/' '{ printf "%s:%s", $3, $5 }' } diff --git a/test/sharness/t0027-rotate.sh b/test/sharness/t0027-rotate.sh index b3e748e90..982b70a92 100755 --- a/test/sharness/t0027-rotate.sh +++ b/test/sharness/t0027-rotate.sh @@ -87,12 +87,19 @@ test_rotate() { } test_rotate 'rsa' '' test_rotate 'ed25519' '' +test_rotate 'secp256k1' '' test_rotate '' '' test_rotate 'rsa' 'rsa' test_rotate 'ed25519' 'rsa' +test_rotate 'secp256k1' 'rsa' test_rotate '' 'rsa' test_rotate 'rsa' 'ed25519' test_rotate 'ed25519' 'ed25519' +test_rotate 'secp256k1' 'ed25519' test_rotate '' 'ed25519' +test_rotate 'rsa' 'secp256k1' +test_rotate 'ed25519' 'secp256k1' +test_rotate 'secp256k1' 'secp256k1' +test_rotate '' 'secp256k1' test_done diff --git a/test/sharness/t0165-keystore.sh b/test/sharness/t0165-keystore.sh index 60089ecd7..2fc7c2e67 100755 --- a/test/sharness/t0165-keystore.sh +++ b/test/sharness/t0165-keystore.sh @@ -55,6 +55,29 @@ PEERID=$(ipfs key list --ipns-base=base36 -l | grep key_ed25519 | head -n 1 | cu test_check_ed25519_base36_peerid $PEERID && ipfs key rm key_ed25519 ' + +test_expect_success "create an SECP256k1 key and test B58MH/B36CID output formats" ' +PEERID=$(ipfs key gen --ipns-base=b58mh --type=secp256k1 key_secp256k1) && +test_check_secp256k1_b58mh_peerid $PEERID && +ipfs key rm key_secp256k1 && +PEERID=$(ipfs key gen --ipns-base=base36 --type=secp256k1 key_secp256k1) && +test_check_secp256k1_base36_peerid $PEERID +' + +test_expect_success "test SECP256k1 key sk export format" ' +ipfs key export key_secp256k1 && +test_check_ed25519_sk key_secp256k1.key && +rm key_secp256k1.key +' + +test_expect_success "test SECP256k1 key B58MH/B36CID multihash format" ' +PEERID=$(ipfs key list --ipns-base=b58mh -l | grep key_secp256k1 | head -n 1 | cut -d " " -f1) && +test_check_secp256k1_b58mh_peerid $PEERID && +PEERID=$(ipfs key list --ipns-base=base36 -l | grep key_secp256k1 | head -n 1 | cut -d " " -f1) && +test_check_secp256k1_base36_peerid $PEERID && +ipfs key rm key_secp256k1 +' + # end of format test @@ -72,6 +95,11 @@ ipfs key rm key_ed25519 test_key_import_export_all_formats ed25519_key + test_expect_success "create a new secp256k1 key" ' + k1hash=$(ipfs key gen generated_secp256k1_key --type=secp256k1) + echo $k1hash > secp256k1_key_id + ' + test_openssl_compatibility_all_types INVALID_KEY=../t0165-keystore-data/openssl_secp384r1.pem @@ -116,6 +144,7 @@ ipfs key rm key_ed25519 test_expect_success "all keys show up in list output" ' echo generated_ed25519_key > list_exp && echo generated_rsa_key >> list_exp && + echo generated_secp256k1_key >> list_exp && echo quxel >> list_exp && echo self >> list_exp ipfs key list > list_out && @@ -135,6 +164,7 @@ ipfs key rm key_ed25519 test_expect_success "key rm remove a key" ' ipfs key rm generated_rsa_key echo generated_ed25519_key > list_exp && + echo generated_secp256k1_key >> list_exp && echo quxel >> list_exp && echo self >> list_exp ipfs key list > list_out && @@ -149,6 +179,7 @@ ipfs key rm key_ed25519 test_expect_success "key rename rename a key" ' ipfs key rename generated_ed25519_key fooed echo fooed > list_exp && + echo generated_secp256k1_key >> list_exp && echo quxel >> list_exp && echo self >> list_exp ipfs key list > list_out && From dfd244816a7701c61dc2e0fe944cfc92395c5652 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Thu, 1 Jun 2023 01:43:11 +0200 Subject: [PATCH 0689/1212] feat(gateway): human error pages, dag-cbor/dag-json preview (#9904) Co-authored-by: Marcin Rataj --- docs/changelogs/v0.21.md | 19 +++++++++++++++++-- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- test/sharness/t0123-gateway-json-cbor.sh | 4 ++-- 6 files changed, 25 insertions(+), 10 deletions(-) diff --git a/docs/changelogs/v0.21.md b/docs/changelogs/v0.21.md index ce08e3dcc..dccdb505d 100644 --- a/docs/changelogs/v0.21.md +++ b/docs/changelogs/v0.21.md @@ -8,7 +8,8 @@ - [🔦 Highlights](#-highlights) - [Saving previously seen nodes for later bootstrapping](#saving-previously-seen-nodes-for-later-bootstrapping) - [`Gateway.DeserializedResponses` config flag](#gatewaydeserializedresponses-config-flag) - - [`client/rpc` migration of go-ipfs-http-client](#clientrpc-migration-of-go-ipfs-http-client) + - [`client/rpc` migration of `go-ipfs-http-client`](#clientrpc-migration-of-go-ipfs-http-client) + - [Gateway: DAG-CBOR/-JSON previews and improved error pages](#gateway-dag-cbor-json-previews-and-improved-error-pages) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -59,7 +60,7 @@ third-party CIDs. #### `client/rpc` migration of `go-ipfs-http-client` The [`go-ipfs-http-client`](https://github.com/ipfs/go-ipfs-http-client) RPC has -been migrated into [`client/rpc`](./client/rpc). +been migrated into [`kubo/client/rpc`](../../client/rpc). With this change the two will be kept in sync, in some previous releases we updated the CoreAPI with new Kubo features but forgot to port thoses to the @@ -69,6 +70,20 @@ version. For smooth transition `v0.7.0` of `go-ipfs-http-client` provides updated stubs for Kubo `v0.21`. +#### Gateway: DAG-CBOR/-JSON previews and improved error pages + +In this release, we improved the HTML templates of our HTTP gateway: + +1. You can now preview the contents of a DAG-CBOR and DAG-JSON document from your browser, as well as follow any IPLD Links ([CBOR Tag 42](https://github.com/ipld/cid-cbor/)) contained within them. +2. The HTML directory listings now contain [updated, higher-definition icons](https://user-images.githubusercontent.com/5447088/241224419-5385793a-d3bb-40aa-8cb0-0382b5bc56a0.png). +3. On gateway error, instead of a plain text error message, web browsers will now get a friendly HTML response with more details regarding the problem. + +HTML responses are returned when request's `Accept` header includes `text/html`. + +| DAG-CBOR Preview | Error Page | +| ---- | ---- | +| ![DAG-CBOR Preview](https://github.com/ipfs/boxo/assets/5447088/973f05d1-5731-4469-9da5-d1d776891899) | ![Error Page](https://github.com/ipfs/boxo/assets/5447088/14c453df-adbc-4634-b038-133121914550) | + ### 📝 Changelog ### 👨‍👩‍👧‍👦 Contributors diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 00cb50575..4ce4275ac 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.18 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.8.2-0.20230530175401-c23df3837fbe + github.com/ipfs/boxo v0.8.2-0.20230531151409-d1b8d1d6d076 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.27.3 github.com/multiformats/go-multiaddr v0.9.0 diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index e19356484..406780e47 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -321,8 +321,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.8.2-0.20230530175401-c23df3837fbe h1:H6ETX0d5BiNTd1XIK8VARmEn0hpYpYdKKKp3rUJBLjY= -github.com/ipfs/boxo v0.8.2-0.20230530175401-c23df3837fbe/go.mod h1:Ej2r08Z4VIaFKqY08UXMNhwcLf6VekHhK8c+KqA1B9Y= +github.com/ipfs/boxo v0.8.2-0.20230531151409-d1b8d1d6d076 h1:jkmzkt/eRxC+tAOgUYOoQh50Bvfnun/Dy3n72tRSkmo= +github.com/ipfs/boxo v0.8.2-0.20230531151409-d1b8d1d6d076/go.mod h1:Ej2r08Z4VIaFKqY08UXMNhwcLf6VekHhK8c+KqA1B9Y= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= diff --git a/go.mod b/go.mod index 87e7dfea1..5e980dc2b 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/gogo/protobuf v1.3.2 github.com/google/uuid v1.3.0 github.com/hashicorp/go-multierror v1.1.1 - github.com/ipfs/boxo v0.8.2-0.20230530175401-c23df3837fbe + github.com/ipfs/boxo v0.8.2-0.20230531151409-d1b8d1d6d076 github.com/ipfs/go-block-format v0.1.2 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 diff --git a/go.sum b/go.sum index b8dcfb8ff..5e3e2c99a 100644 --- a/go.sum +++ b/go.sum @@ -356,8 +356,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.8.2-0.20230530175401-c23df3837fbe h1:H6ETX0d5BiNTd1XIK8VARmEn0hpYpYdKKKp3rUJBLjY= -github.com/ipfs/boxo v0.8.2-0.20230530175401-c23df3837fbe/go.mod h1:Ej2r08Z4VIaFKqY08UXMNhwcLf6VekHhK8c+KqA1B9Y= +github.com/ipfs/boxo v0.8.2-0.20230531151409-d1b8d1d6d076 h1:jkmzkt/eRxC+tAOgUYOoQh50Bvfnun/Dy3n72tRSkmo= +github.com/ipfs/boxo v0.8.2-0.20230531151409-d1b8d1d6d076/go.mod h1:Ej2r08Z4VIaFKqY08UXMNhwcLf6VekHhK8c+KqA1B9Y= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= diff --git a/test/sharness/t0123-gateway-json-cbor.sh b/test/sharness/t0123-gateway-json-cbor.sh index 745e984db..b4b0446ff 100755 --- a/test/sharness/t0123-gateway-json-cbor.sh +++ b/test/sharness/t0123-gateway-json-cbor.sh @@ -349,7 +349,7 @@ test_native_dag () { # As this is generated, we don't return immutable Cache-Control, even on /ipfs (same as for dir-index-html) test_expect_success "GET $name on /ipfs with Accept: text/html returns HTML (dag-index-html)" ' - curl -sD - -H "Accept: text/html" "http://127.0.0.1:$GWAY_PORT/ipfs/$CID" > curl_output 2>&1 && + curl -sD - -H "Accept: text/html" "http://127.0.0.1:$GWAY_PORT/ipfs/$CID/" > curl_output 2>&1 && test_should_not_contain "Content-Disposition" curl_output && test_should_not_contain "Cache-Control" curl_output && test_should_contain "Etag: \"DagIndex-" curl_output && @@ -358,7 +358,7 @@ test_native_dag () { ' test_expect_success "GET $name on /ipns with Accept: text/html returns HTML (dag-index-html)" ' - curl -sD - -H "Accept: text/html" "http://127.0.0.1:$GWAY_PORT/ipns/$IPNS_ID" > curl_output 2>&1 && + curl -sD - -H "Accept: text/html" "http://127.0.0.1:$GWAY_PORT/ipns/$IPNS_ID/" > curl_output 2>&1 && test_should_not_contain "Content-Disposition" curl_output && test_should_not_contain "Cache-Control" curl_output && test_should_contain "Etag: \"DagIndex-" curl_output && From 6eef0b4eefd6813dd6169d5a78ae57b9aa1cd90b Mon Sep 17 00:00:00 2001 From: Nikhilesh Susarla Date: Thu, 1 Jun 2023 15:49:29 +0530 Subject: [PATCH 0690/1212] fix: 'ipfs routing findpeer' explicitly fails when searching for self (#9903) --- core/commands/root.go | 1 + core/commands/routing.go | 4 ++++ test/cli/routing_dht_test.go | 16 ++++++++++++++++ 3 files changed, 21 insertions(+) diff --git a/core/commands/root.go b/core/commands/root.go index cfa2708e6..76e110e2b 100644 --- a/core/commands/root.go +++ b/core/commands/root.go @@ -17,6 +17,7 @@ import ( var log = logging.Logger("core/commands") var ErrNotOnline = errors.New("this command must be run in online mode. Try running 'ipfs daemon' first") +var ErrSelfUnsupported = errors.New("finding your own node in the DHT is currently not supported") const ( RepoDirOption = "repo-dir" diff --git a/core/commands/routing.go b/core/commands/routing.go index 76672c6f2..44ca2e29f 100644 --- a/core/commands/routing.go +++ b/core/commands/routing.go @@ -301,6 +301,10 @@ var findPeerRoutingCmd = &cmds.Command{ return err } + if pid == nd.Identity { + return ErrSelfUnsupported + } + ctx, cancel := context.WithCancel(req.Context) ctx, events := routing.RegisterForQueryEvents(ctx) diff --git a/test/cli/routing_dht_test.go b/test/cli/routing_dht_test.go index 7dc0ddfcb..3a3adc51c 100644 --- a/test/cli/routing_dht_test.go +++ b/test/cli/routing_dht_test.go @@ -117,7 +117,23 @@ func testRoutingDHT(t *testing.T, enablePubsub bool) { }) } +func testSelfFindDHT(t *testing.T) { + t.Run("ipfs routing findpeer fails for self", func(t *testing.T) { + t.Parallel() + nodes := harness.NewT(t).NewNodes(1).Init() + nodes.ForEachPar(func(node *harness.Node) { + node.IPFS("config", "Routing.Type", "dht") + }) + + nodes.StartDaemons() + + res := nodes[0].RunIPFS("dht", "findpeer", nodes[0].PeerID().String()) + assert.Equal(t, 1, res.ExitCode()) + }) +} + func TestRoutingDHT(t *testing.T) { testRoutingDHT(t, false) testRoutingDHT(t, true) + testSelfFindDHT(t) } From eb265f7cd89443f8d9260749377aa2cd6b9d7547 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Fri, 2 Jun 2023 08:14:19 +0200 Subject: [PATCH 0691/1212] fix(gateway)!: no duplicate payload during subdomain redirects (#9913) Co-authored-by: Marcin Rataj --- docs/changelogs/v0.21.md | 22 ++++++++++++++++++++-- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- test/sharness/t0114-gateway-subdomains.sh | 10 ++++------ 6 files changed, 30 insertions(+), 14 deletions(-) diff --git a/docs/changelogs/v0.21.md b/docs/changelogs/v0.21.md index dccdb505d..fe369ef90 100644 --- a/docs/changelogs/v0.21.md +++ b/docs/changelogs/v0.21.md @@ -7,9 +7,10 @@ - [Overview](#overview) - [🔦 Highlights](#-highlights) - [Saving previously seen nodes for later bootstrapping](#saving-previously-seen-nodes-for-later-bootstrapping) - - [`Gateway.DeserializedResponses` config flag](#gatewaydeserializedresponses-config-flag) + - [Gateway: `DeserializedResponses` config flag](#gateway-deserializedresponses-config-flag) - [`client/rpc` migration of `go-ipfs-http-client`](#clientrpc-migration-of-go-ipfs-http-client) - [Gateway: DAG-CBOR/-JSON previews and improved error pages](#gateway-dag-cbor-json-previews-and-improved-error-pages) + - [Gateway: subdomain redirects are now `text/html`](#gateway-subdomain-redirects-are-now-texthtml) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -32,7 +33,7 @@ enabled. With this update, the same level of robustness is applied to peers that lack mDNS peers and solely rely on the public DHT. -#### `Gateway.DeserializedResponses` config flag +#### Gateway: `DeserializedResponses` config flag This release introduces the [`Gateway.DeserializedResponses`](https://github.com/ipfs/kubo/blob/master/docs/config.md#gatewaydeserializedresponses) @@ -84,6 +85,23 @@ HTML responses are returned when request's `Accept` header includes `text/html`. | ---- | ---- | | ![DAG-CBOR Preview](https://github.com/ipfs/boxo/assets/5447088/973f05d1-5731-4469-9da5-d1d776891899) | ![Error Page](https://github.com/ipfs/boxo/assets/5447088/14c453df-adbc-4634-b038-133121914550) | +#### Gateway: subdomain redirects are now `text/html` + +HTTP 301 redirects [from path to subdomain](https://specs.ipfs.tech/http-gateways/subdomain-gateway/#migrating-from-path-to-subdomain-gateway) +no longer include the target data in the body. +The data is returned only once, with the final HTTP 200 returned from the +target subdomain. + +The HTTP 301 body now includes human-readable `text/html` message +for clients that do not follow redirects by default: + +```console +$ curl "https://subdomain-gw.example.net/ipfs/${cid}/" +Moved Permanently. +``` + +Rationale can be found in [kubo#9913](https://github.com/ipfs/kubo/pull/9913). + ### 📝 Changelog ### 👨‍👩‍👧‍👦 Contributors diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 4ce4275ac..81caa1258 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.18 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.8.2-0.20230531151409-d1b8d1d6d076 + github.com/ipfs/boxo v0.8.2-0.20230602025754-4c5c98b94b21 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.27.3 github.com/multiformats/go-multiaddr v0.9.0 diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 406780e47..a51153459 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -321,8 +321,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.8.2-0.20230531151409-d1b8d1d6d076 h1:jkmzkt/eRxC+tAOgUYOoQh50Bvfnun/Dy3n72tRSkmo= -github.com/ipfs/boxo v0.8.2-0.20230531151409-d1b8d1d6d076/go.mod h1:Ej2r08Z4VIaFKqY08UXMNhwcLf6VekHhK8c+KqA1B9Y= +github.com/ipfs/boxo v0.8.2-0.20230602025754-4c5c98b94b21 h1:efxZK66VVeQ1cGczX7ufjd4DW6X2nb/PbAJ5k85YC98= +github.com/ipfs/boxo v0.8.2-0.20230602025754-4c5c98b94b21/go.mod h1:Ej2r08Z4VIaFKqY08UXMNhwcLf6VekHhK8c+KqA1B9Y= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= diff --git a/go.mod b/go.mod index 5e980dc2b..78765c0b6 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/gogo/protobuf v1.3.2 github.com/google/uuid v1.3.0 github.com/hashicorp/go-multierror v1.1.1 - github.com/ipfs/boxo v0.8.2-0.20230531151409-d1b8d1d6d076 + github.com/ipfs/boxo v0.8.2-0.20230602025754-4c5c98b94b21 github.com/ipfs/go-block-format v0.1.2 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 diff --git a/go.sum b/go.sum index 5e3e2c99a..9157775d7 100644 --- a/go.sum +++ b/go.sum @@ -356,8 +356,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.8.2-0.20230531151409-d1b8d1d6d076 h1:jkmzkt/eRxC+tAOgUYOoQh50Bvfnun/Dy3n72tRSkmo= -github.com/ipfs/boxo v0.8.2-0.20230531151409-d1b8d1d6d076/go.mod h1:Ej2r08Z4VIaFKqY08UXMNhwcLf6VekHhK8c+KqA1B9Y= +github.com/ipfs/boxo v0.8.2-0.20230602025754-4c5c98b94b21 h1:efxZK66VVeQ1cGczX7ufjd4DW6X2nb/PbAJ5k85YC98= +github.com/ipfs/boxo v0.8.2-0.20230602025754-4c5c98b94b21/go.mod h1:Ej2r08Z4VIaFKqY08UXMNhwcLf6VekHhK8c+KqA1B9Y= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= diff --git a/test/sharness/t0114-gateway-subdomains.sh b/test/sharness/t0114-gateway-subdomains.sh index bf5070985..1d19a6570 100755 --- a/test/sharness/t0114-gateway-subdomains.sh +++ b/test/sharness/t0114-gateway-subdomains.sh @@ -162,14 +162,12 @@ test_localhost_gateway_response_should_contain \ "http://localhost:$GWAY_PORT/ipfs/$DIR_CID/" \ "Location: http://$DIR_CID.ipfs.localhost:$GWAY_PORT/" -# We return body with HTTP 301 so existing cli scripts that use path-based -# gateway do not break (curl doesn't auto-redirect without passing -L; wget -# does not span across hostnames by default) -# Context: https://github.com/ipfs/go-ipfs/issues/6975 +# We return human-readable body with HTTP 301 so existing cli scripts that use path-based +# gateway are informed to enable following HTTP redirects test_localhost_gateway_response_should_contain \ - "request for localhost/ipfs/{CIDv1} includes valid payload in body for CLI tools like curl" \ + "request for localhost/ipfs/{CIDv1} includes human-readable link and redirect info in HTTP 301 body" \ "http://localhost:$GWAY_PORT/ipfs/$CIDv1" \ - "$CID_VAL" + ">Moved Permanently" test_localhost_gateway_response_should_contain \ "request for localhost/ipfs/{CIDv0} redirects to CIDv1 representation in subdomain" \ From 0134124cdd62b2437b3888e9bd240a5a59de9962 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Mur=C3=A9?= Date: Fri, 2 Jun 2023 16:49:03 +0200 Subject: [PATCH 0692/1212] pinner: change the interface to have async pin listing The rational is that if the pin list get big, a synchronous call to get the complete list can delay handling unnecessarily. For example, when listing indirect pins, you can start walking the DAGs immediately with the first recursive pin instead of waiting for the full list. This matters even more on low power device, of if the pin list is stored remotely. * coreiface: allow to return an error not linked to a specific Cid * merkledag/test: add a DAG generator Rationale is that generating a test DAG is quite difficult, and anything that helps writing better tests is helpful. This commit was moved from ipfs/boxo@e2fc7f2fd0237afad200d7b0eec8b7a60bdc6644 --- core/coreiface/pin.go | 3 +++ core/coreiface/tests/pin.go | 5 ++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/core/coreiface/pin.go b/core/coreiface/pin.go index ba5df5354..6b97c6ca5 100644 --- a/core/coreiface/pin.go +++ b/core/coreiface/pin.go @@ -27,6 +27,9 @@ type PinStatus interface { // BadNodes returns any bad (usually missing) nodes from the pin BadNodes() []BadPinNode + + // if not nil, an error happened. Everything else should be ignored. + Err() error } // BadPinNode is a node that has been marked as bad by Pin.Verify diff --git a/core/coreiface/tests/pin.go b/core/coreiface/tests/pin.go index bbf602994..4b0fea01d 100644 --- a/core/coreiface/tests/pin.go +++ b/core/coreiface/tests/pin.go @@ -198,6 +198,9 @@ func (tp *TestSuite) TestPinRecursive(t *testing.T) { } n := 0 for r := range res { + if err := r.Err(); err != nil { + t.Error(err) + } if !r.Ok() { t.Error("expected pin to be ok") } @@ -208,7 +211,7 @@ func (tp *TestSuite) TestPinRecursive(t *testing.T) { t.Errorf("unexpected verify result count: %d", n) } - //TODO: figure out a way to test verify without touching IpfsNode + // TODO: figure out a way to test verify without touching IpfsNode /* err = api.Block().Rm(ctx, p0, opt.Block.Force(true)) if err != nil { From a2c66abc52864bcd7bbb099f5959ec66557c73cd Mon Sep 17 00:00:00 2001 From: Jorropo Date: Fri, 2 Jun 2023 18:16:46 +0200 Subject: [PATCH 0693/1212] pinning: fix pin listings --- core/commands/pin/pin.go | 23 ++++++++++--------- core/coreapi/pin.go | 48 +++++++++++++++------------------------- 2 files changed, 31 insertions(+), 40 deletions(-) diff --git a/core/commands/pin/pin.go b/core/commands/pin/pin.go index 626c536db..8312c1fb4 100644 --- a/core/commands/pin/pin.go +++ b/core/commands/pin/pin.go @@ -342,14 +342,17 @@ Example: } // For backward compatibility, we accumulate the pins in the same output type as before. - emit := res.Emit + var emit func(PinLsOutputWrapper) error lgcList := map[string]PinLsType{} if !stream { - emit = func(v interface{}) error { - obj := v.(*PinLsOutputWrapper) - lgcList[obj.PinLsObject.Cid] = PinLsType{Type: obj.PinLsObject.Type} + emit = func(v PinLsOutputWrapper) error { + lgcList[v.PinLsObject.Cid] = PinLsType{Type: v.PinLsObject.Type} return nil } + } else { + emit = func(v PinLsOutputWrapper) error { + return res.Emit(v) + } } if len(req.Arguments) > 0 { @@ -371,7 +374,7 @@ Example: }, Type: &PinLsOutputWrapper{}, Encoders: cmds.EncoderMap{ - cmds.JSON: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *PinLsOutputWrapper) error { + cmds.JSON: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out PinLsOutputWrapper) error { stream, _ := req.Options[pinStreamOptionName].(bool) enc := json.NewEncoder(w) @@ -382,7 +385,7 @@ Example: return enc.Encode(out.PinLsList) }), - cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *PinLsOutputWrapper) error { + cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out PinLsOutputWrapper) error { quiet, _ := req.Options[pinQuietOptionName].(bool) stream, _ := req.Options[pinStreamOptionName].(bool) @@ -432,7 +435,7 @@ type PinLsObject struct { Type string `json:",omitempty"` } -func pinLsKeys(req *cmds.Request, typeStr string, api coreiface.CoreAPI, emit func(value interface{}) error) error { +func pinLsKeys(req *cmds.Request, typeStr string, api coreiface.CoreAPI, emit func(value PinLsOutputWrapper) error) error { enc, err := cmdenv.GetCidEncoder(req) if err != nil { return err @@ -470,7 +473,7 @@ func pinLsKeys(req *cmds.Request, typeStr string, api coreiface.CoreAPI, emit fu pinType = "indirect through " + pinType } - err = emit(&PinLsOutputWrapper{ + err = emit(PinLsOutputWrapper{ PinLsObject: PinLsObject{ Type: pinType, Cid: enc.Encode(rp.Cid()), @@ -484,7 +487,7 @@ func pinLsKeys(req *cmds.Request, typeStr string, api coreiface.CoreAPI, emit fu return nil } -func pinLsAll(req *cmds.Request, typeStr string, api coreiface.CoreAPI, emit func(value interface{}) error) error { +func pinLsAll(req *cmds.Request, typeStr string, api coreiface.CoreAPI, emit func(value PinLsOutputWrapper) error) error { enc, err := cmdenv.GetCidEncoder(req) if err != nil { return err @@ -511,7 +514,7 @@ func pinLsAll(req *cmds.Request, typeStr string, api coreiface.CoreAPI, emit fun if err := p.Err(); err != nil { return err } - err = emit(&PinLsOutputWrapper{ + err = emit(PinLsOutputWrapper{ PinLsObject: PinLsObject{ Type: p.Type(), Cid: enc.Encode(p.Path().Cid()), diff --git a/core/coreapi/pin.go b/core/coreapi/pin.go index 98be600b2..ec2cedb83 100644 --- a/core/coreapi/pin.go +++ b/core/coreapi/pin.go @@ -305,6 +305,7 @@ func (api *PinAPI) pinLsAll(ctx context.Context, typeStr string) <-chan coreifac out <- &pinInfo{err: err} return } + rkeys = append(rkeys, streamedCid.C) } } if typeStr == "direct" || typeStr == "all" { @@ -319,27 +320,6 @@ func (api *PinAPI) pinLsAll(ctx context.Context, typeStr string) <-chan coreifac } } } - if typeStr == "all" { - walkingSet := cid.NewSet() - for _, k := range rkeys { - err = merkledag.Walk( - ctx, merkledag.GetLinksWithDAG(api.dag), k, - walkingSet.Visit, - merkledag.SkipRoot(), merkledag.Concurrent(), - ) - if err != nil { - out <- &pinInfo{err: err} - return - } - } - err = walkingSet.ForEach(func(c cid.Cid) error { - return AddToResultKeys(c, "indirect") - }) - if err != nil { - out <- &pinInfo{err: err} - return - } - } if typeStr == "indirect" { // We need to first visit the direct pins that have priority // without emitting them @@ -358,13 +338,28 @@ func (api *PinAPI) pinLsAll(ctx context.Context, typeStr string) <-chan coreifac return } emittedSet.Add(streamedCid.C) + rkeys = append(rkeys, streamedCid.C) } - + } + if typeStr == "indirect" || typeStr == "all" { walkingSet := cid.NewSet() for _, k := range rkeys { err = merkledag.Walk( ctx, merkledag.GetLinksWithDAG(api.dag), k, - walkingSet.Visit, + func(c cid.Cid) bool { + if !walkingSet.Visit(c) { + return false + } + if emittedSet.Has(c) { + return true // skipped + } + err := AddToResultKeys(c, "indirect") + if err != nil { + out <- &pinInfo{err: err} + return false + } + return true + }, merkledag.SkipRoot(), merkledag.Concurrent(), ) if err != nil { @@ -372,13 +367,6 @@ func (api *PinAPI) pinLsAll(ctx context.Context, typeStr string) <-chan coreifac return } } - err = emittedSet.ForEach(func(c cid.Cid) error { - return AddToResultKeys(c, "indirect") - }) - if err != nil { - out <- &pinInfo{err: err} - return - } } }() From 8114573933fe4cc9f494155bf8254848c0d414e5 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Fri, 2 Jun 2023 19:22:30 +0200 Subject: [PATCH 0694/1212] core/commands/pin: fix incorrect pointer type in encoder --- core/commands/pin/pin.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/commands/pin/pin.go b/core/commands/pin/pin.go index 8312c1fb4..673afc971 100644 --- a/core/commands/pin/pin.go +++ b/core/commands/pin/pin.go @@ -365,14 +365,14 @@ Example: } if !stream { - return cmds.EmitOnce(res, &PinLsOutputWrapper{ + return cmds.EmitOnce(res, PinLsOutputWrapper{ PinLsList: PinLsList{Keys: lgcList}, }) } return nil }, - Type: &PinLsOutputWrapper{}, + Type: PinLsOutputWrapper{}, Encoders: cmds.EncoderMap{ cmds.JSON: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out PinLsOutputWrapper) error { stream, _ := req.Options[pinStreamOptionName].(bool) @@ -421,7 +421,7 @@ type PinLsOutputWrapper struct { // PinLsList is a set of pins with their type type PinLsList struct { - Keys map[string]PinLsType + Keys map[string]PinLsType `json:",omitempty"` } // PinLsType contains the type of a pin From f8f4b83c9c473ebd01e9624a39097a429f65c572 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Fri, 2 Jun 2023 19:22:58 +0200 Subject: [PATCH 0695/1212] client/rpc: use streaming pin listing This also fix a leaking goroutine bug on client/rpc.PinAPI.Ls, we would deadlock if context was canceled while writing the keys. --- client/rpc/pin.go | 54 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 43 insertions(+), 11 deletions(-) diff --git a/client/rpc/pin.go b/client/rpc/pin.go index ccfe465ae..dc85b9f30 100644 --- a/client/rpc/pin.go +++ b/client/rpc/pin.go @@ -29,15 +29,15 @@ type pin struct { err error } -func (p *pin) Err() error { +func (p pin) Err() error { return p.err } -func (p *pin) Path() path.Resolved { +func (p pin) Path() path.Resolved { return p.path } -func (p *pin) Type() string { +func (p pin) Type() string { return p.typ } @@ -51,29 +51,61 @@ func (api *PinAPI) Add(ctx context.Context, p path.Path, opts ...caopts.PinAddOp Option("recursive", options.Recursive).Exec(ctx, nil) } +type pinLsObject struct { + Cid string + Type string +} + func (api *PinAPI) Ls(ctx context.Context, opts ...caopts.PinLsOption) (<-chan iface.Pin, error) { options, err := caopts.PinLsOptions(opts...) if err != nil { return nil, err } - var out pinRefKeyList - err = api.core().Request("pin/ls"). - Option("type", options.Type).Exec(ctx, &out) + res, err := api.core().Request("pin/ls"). + Option("type", options.Type). + Option("stream", true). + Send(ctx) if err != nil { return nil, err } pins := make(chan iface.Pin) go func(ch chan<- iface.Pin) { + defer res.Output.Close() defer close(ch) - for hash, p := range out.Keys { - c, e := cid.Parse(hash) - if e != nil { - ch <- &pin{typ: p.Type, err: e} + + dec := json.NewDecoder(res.Output) + var out pinLsObject + for { + switch err := dec.Decode(&out); err { + case nil: + case io.EOF: + return + default: + select { + case ch <- pin{err: err}: + return + case <-ctx.Done(): + return + } + } + + c, err := cid.Parse(out.Cid) + if err != nil { + select { + case ch <- pin{err: err}: + return + case <-ctx.Done(): + return + } + } + + select { + case ch <- pin{typ: out.Type, path: path.IpldPath(c)}: + case <-ctx.Done(): return } - ch <- &pin{typ: p.Type, path: path.IpldPath(c), err: e} } }(pins) return pins, nil From 726eabead42086d151a1d4aed1f4d92ec796d6a5 Mon Sep 17 00:00:00 2001 From: Arthur Gavazza <32915690+arthurgavazza@users.noreply.github.com> Date: Tue, 6 Jun 2023 10:17:45 -0300 Subject: [PATCH 0696/1212] feat: add deduplication ratio to 'ipfs dag stat' (#9787) --- core/commands/dag/dag.go | 109 ++++++++++++++++- core/commands/dag/stat.go | 115 ++++++++++-------- test/cli/dag_test.go | 105 ++++++++++++++++ test/cli/fixtures/TestDagStat.car | Bin 0 -> 402 bytes .../fixtures/TestDagStatExpectedOutput.txt | 12 ++ test/cli/testutils/floats.go | 9 ++ test/sharness/t0053-dag.sh | 33 ----- 7 files changed, 296 insertions(+), 87 deletions(-) create mode 100644 test/cli/dag_test.go create mode 100644 test/cli/fixtures/TestDagStat.car create mode 100644 test/cli/fixtures/TestDagStatExpectedOutput.txt create mode 100644 test/cli/testutils/floats.go diff --git a/core/commands/dag/dag.go b/core/commands/dag/dag.go index 75588b8ed..7d21eb071 100644 --- a/core/commands/dag/dag.go +++ b/core/commands/dag/dag.go @@ -1,6 +1,8 @@ package dagcmd import ( + "encoding/csv" + "encoding/json" "fmt" "io" @@ -276,12 +278,81 @@ CAR file follows the CARv1 format: https://ipld.io/specs/transport/car/carv1/ // DagStat is a dag stat command response type DagStat struct { - Size uint64 - NumBlocks int64 + Cid cid.Cid `json:",omitempty"` + Size uint64 `json:",omitempty"` + NumBlocks int64 `json:",omitempty"` } func (s *DagStat) String() string { - return fmt.Sprintf("Size: %d, NumBlocks: %d", s.Size, s.NumBlocks) + return fmt.Sprintf("%s %d %d", s.Cid.String()[:20], s.Size, s.NumBlocks) +} + +func (s *DagStat) MarshalJSON() ([]byte, error) { + type Alias DagStat + /* + We can't rely on cid.Cid.MarshalJSON since it uses the {"/": "..."} + format. To make the output consistent and follow the Kubo API patterns + we use the Cid.String method + */ + return json.Marshal(struct { + Cid string `json:"Cid"` + *Alias + }{ + Cid: s.Cid.String(), + Alias: (*Alias)(s), + }) +} + +func (s *DagStat) UnmarshalJSON(data []byte) error { + /* + We can't rely on cid.Cid.UnmarshalJSON since it uses the {"/": "..."} + format. To make the output consistent and follow the Kubo API patterns + we use the Cid.Parse method + */ + type Alias DagStat + aux := struct { + Cid string `json:"Cid"` + *Alias + }{ + Alias: (*Alias)(s), + } + if err := json.Unmarshal(data, &aux); err != nil { + return err + } + Cid, err := cid.Parse(aux.Cid) + if err != nil { + return err + } + s.Cid = Cid + return nil +} + +type DagStatSummary struct { + redundantSize uint64 `json:"-"` + UniqueBlocks int `json:",omitempty"` + TotalSize uint64 `json:",omitempty"` + SharedSize uint64 `json:",omitempty"` + Ratio float32 `json:",omitempty"` + DagStatsArray []*DagStat `json:"DagStats,omitempty"` +} + +func (s *DagStatSummary) String() string { + return fmt.Sprintf("Total Size: %d\nUnique Blocks: %d\nShared Size: %d\nRatio: %f", s.TotalSize, s.UniqueBlocks, s.SharedSize, s.Ratio) +} + +func (s *DagStatSummary) incrementTotalSize(size uint64) { + s.TotalSize += size +} +func (s *DagStatSummary) incrementRedundantSize(size uint64) { + s.redundantSize += size +} +func (s *DagStatSummary) appendStats(stats *DagStat) { + s.DagStatsArray = append(s.DagStatsArray, stats) +} + +func (s *DagStatSummary) calculateSummary() { + s.Ratio = float32(s.redundantSize) / float32(s.TotalSize) + s.SharedSize = s.redundantSize - s.TotalSize } // DagStatCmd is a command for getting size information about an ipfs-stored dag @@ -296,24 +367,50 @@ Note: This command skips duplicate blocks in reporting both size and the number `, }, Arguments: []cmds.Argument{ - cmds.StringArg("root", true, false, "CID of a DAG root to get statistics for").EnableStdin(), + cmds.StringArg("root", true, true, "CID of a DAG root to get statistics for").EnableStdin(), }, Options: []cmds.Option{ cmds.BoolOption(progressOptionName, "p", "Return progressive data while reading through the DAG").WithDefault(true), }, Run: dagStat, - Type: DagStat{}, + Type: DagStatSummary{}, PostRun: cmds.PostRunMap{ cmds.CLI: finishCLIStat, }, Encoders: cmds.EncoderMap{ - cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, event *DagStat) error { + cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, event *DagStatSummary) error { + fmt.Fprintln(w) + csvWriter := csv.NewWriter(w) + csvWriter.Comma = '\t' + cidSpacing := len(event.DagStatsArray[0].Cid.String()) + header := []string{fmt.Sprintf("%-*s", cidSpacing, "CID"), fmt.Sprintf("%-15s", "Blocks"), "Size"} + if err := csvWriter.Write(header); err != nil { + return err + } + for _, dagStat := range event.DagStatsArray { + numBlocksStr := fmt.Sprint(dagStat.NumBlocks) + err := csvWriter.Write([]string{ + dagStat.Cid.String(), + fmt.Sprintf("%-15s", numBlocksStr), + fmt.Sprint(dagStat.Size), + }) + if err != nil { + return err + } + } + csvWriter.Flush() + fmt.Fprint(w, "\nSummary\n") _, err := fmt.Fprintf( w, "%v\n", event, ) + fmt.Fprint(w, "\n\n") return err }), + cmds.JSON: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, event *DagStatSummary) error { + return json.NewEncoder(w).Encode(event) + }, + ), }, } diff --git a/core/commands/dag/stat.go b/core/commands/dag/stat.go index b4617a5b5..a8897c79c 100644 --- a/core/commands/dag/stat.go +++ b/core/commands/dag/stat.go @@ -6,70 +6,82 @@ import ( "os" "github.com/ipfs/boxo/coreiface/path" + mdag "github.com/ipfs/boxo/ipld/merkledag" "github.com/ipfs/boxo/ipld/merkledag/traverse" + cid "github.com/ipfs/go-cid" + cmds "github.com/ipfs/go-ipfs-cmds" "github.com/ipfs/kubo/core/commands/cmdenv" "github.com/ipfs/kubo/core/commands/e" - - mdag "github.com/ipfs/boxo/ipld/merkledag" - cmds "github.com/ipfs/go-ipfs-cmds" ) +// TODO cache every cid traversal in a dp cache +// if the cid exists in the cache, don't traverse it, and use the cached result +// to compute the new state + func dagStat(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { progressive := req.Options[progressOptionName].(bool) - api, err := cmdenv.GetApi(env, req) if err != nil { return err } - - rp, err := api.ResolvePath(req.Context, path.New(req.Arguments[0])) - if err != nil { - return err - } - - if len(rp.Remainder()) > 0 { - return fmt.Errorf("cannot return size for anything other than a DAG with a root CID") - } - nodeGetter := mdag.NewSession(req.Context, api.Dag()) - obj, err := nodeGetter.Get(req.Context, rp.Cid()) - if err != nil { - return err - } - dagstats := &DagStat{} - err = traverse.Traverse(obj, traverse.Options{ - DAG: nodeGetter, - Order: traverse.DFSPre, - Func: func(current traverse.State) error { - dagstats.Size += uint64(len(current.Node.RawData())) - dagstats.NumBlocks++ - - if progressive { - if err := res.Emit(dagstats); err != nil { - return err - } - } - return nil - }, - ErrFunc: nil, - SkipDuplicates: true, - }) - if err != nil { - return fmt.Errorf("error traversing DAG: %w", err) - } - - if !progressive { - if err := res.Emit(dagstats); err != nil { + cidSet := cid.NewSet() + dagStatSummary := &DagStatSummary{DagStatsArray: []*DagStat{}} + for _, a := range req.Arguments { + rp, err := api.ResolvePath(req.Context, path.New(a)) + if err != nil { return err } + if len(rp.Remainder()) > 0 { + return fmt.Errorf("cannot return size for anything other than a DAG with a root CID") + } + + obj, err := nodeGetter.Get(req.Context, rp.Cid()) + if err != nil { + return err + } + dagstats := &DagStat{Cid: rp.Cid()} + dagStatSummary.appendStats(dagstats) + err = traverse.Traverse(obj, traverse.Options{ + DAG: nodeGetter, + Order: traverse.DFSPre, + Func: func(current traverse.State) error { + fmt.Println("previousDagStatSize:", dagstats.Size) + currentNodeSize := uint64(len(current.Node.RawData())) + dagstats.Size += currentNodeSize + dagstats.NumBlocks++ + if !cidSet.Has(current.Node.Cid()) { + dagStatSummary.incrementTotalSize(currentNodeSize) + } + dagStatSummary.incrementRedundantSize(currentNodeSize) + cidSet.Add(current.Node.Cid()) + if progressive { + if err := res.Emit(dagStatSummary); err != nil { + return err + } + } + return nil + }, + ErrFunc: nil, + SkipDuplicates: true, + }) + if err != nil { + return fmt.Errorf("error traversing DAG: %w", err) + } } + dagStatSummary.UniqueBlocks = cidSet.Len() + dagStatSummary.calculateSummary() + + if err := res.Emit(dagStatSummary); err != nil { + return err + } return nil } func finishCLIStat(res cmds.Response, re cmds.ResponseEmitter) error { - var dagStats *DagStat + var dagStats *DagStatSummary for { v, err := res.Next() if err != nil { @@ -78,13 +90,20 @@ func finishCLIStat(res cmds.Response, re cmds.ResponseEmitter) error { } return err } - - out, ok := v.(*DagStat) - if !ok { + switch out := v.(type) { + case *DagStatSummary: + dagStats = out + if dagStats.Ratio == 0 { + length := len(dagStats.DagStatsArray) + if length > 0 { + currentStat := dagStats.DagStatsArray[length-1] + fmt.Fprintf(os.Stderr, "CID: %s, Size: %d, NumBlocks: %d\n", currentStat.Cid, currentStat.Size, currentStat.NumBlocks) + } + } + default: return e.TypeErr(out, v) + } - dagStats = out - fmt.Fprintf(os.Stderr, "%v\r", out) } return re.Emit(dagStats) } diff --git a/test/cli/dag_test.go b/test/cli/dag_test.go new file mode 100644 index 000000000..edcacffae --- /dev/null +++ b/test/cli/dag_test.go @@ -0,0 +1,105 @@ +package cli + +import ( + "encoding/json" + "io" + "os" + "testing" + + "github.com/ipfs/kubo/test/cli/harness" + "github.com/ipfs/kubo/test/cli/testutils" + "github.com/stretchr/testify/assert" +) + +const ( + fixtureFile = "./fixtures/TestDagStat.car" + textOutputPath = "./fixtures/TestDagStatExpectedOutput.txt" + node1Cid = "bafyreibmdfd7c5db4kls4ty57zljfhqv36gi43l6txl44pi423wwmeskwy" + node2Cid = "bafyreie3njilzdi4ixumru4nzgecsnjtu7fzfcwhg7e6s4s5i7cnbslvn4" + fixtureCid = "bafyreifrm6uf5o4dsaacuszf35zhibyojlqclabzrms7iak67pf62jygaq" +) + +type DagStat struct { + Cid string `json:"Cid"` + Size int `json:"Size"` + NumBlocks int `json:"NumBlocks"` +} + +type Data struct { + UniqueBlocks int `json:"UniqueBlocks"` + TotalSize int `json:"TotalSize"` + SharedSize int `json:"SharedSize"` + Ratio float64 `json:"Ratio"` + DagStats []DagStat `json:"DagStats"` +} + +// The Fixture file represents a dag where 2 nodes of size = 46B each, have a common child of 7B +// when traversing the DAG from the root's children (node1 and node2) we count (46 + 7)x2 bytes (counting redundant bytes) = 106 +// since both nodes share a common child of 7 bytes we actually had to read (46)x2 + 7 = 99 bytes +// we should get a dedup ratio of 106/99 that results in approximatelly 1.0707071 + +func TestDag(t *testing.T) { + t.Parallel() + + t.Run("ipfs dag stat --enc=json", func(t *testing.T) { + t.Parallel() + node := harness.NewT(t).NewNode().Init().StartDaemon() + // Import fixture + r, err := os.Open(fixtureFile) + assert.Nil(t, err) + defer r.Close() + err = node.IPFSDagImport(r, fixtureCid) + assert.NoError(t, err) + stat := node.RunIPFS("dag", "stat", "--progress=false", "--enc=json", node1Cid, node2Cid) + var data Data + err = json.Unmarshal(stat.Stdout.Bytes(), &data) + assert.NoError(t, err) + + expectedUniqueBlocks := 3 + expectedSharedSize := 7 + expectedTotalSize := 99 + expectedRatio := float64(expectedSharedSize+expectedTotalSize) / float64(expectedTotalSize) + expectedDagStatsLength := 2 + // Validate UniqueBlocks + assert.Equal(t, expectedUniqueBlocks, data.UniqueBlocks) + assert.Equal(t, expectedSharedSize, data.SharedSize) + assert.Equal(t, expectedTotalSize, data.TotalSize) + assert.Equal(t, testutils.FloatTruncate(expectedRatio, 4), testutils.FloatTruncate(data.Ratio, 4)) + + // Validate DagStats + assert.Equal(t, expectedDagStatsLength, len(data.DagStats)) + node1Output := data.DagStats[0] + node2Output := data.DagStats[1] + + assert.Equal(t, node1Output.Cid, node1Cid) + assert.Equal(t, node2Output.Cid, node2Cid) + + expectedNode1Size := (expectedTotalSize + expectedSharedSize) / 2 + expectedNode2Size := (expectedTotalSize + expectedSharedSize) / 2 + assert.Equal(t, expectedNode1Size, node1Output.Size) + assert.Equal(t, expectedNode2Size, node2Output.Size) + + expectedNode1Blocks := 2 + expectedNode2Blocks := 2 + assert.Equal(t, expectedNode1Blocks, node1Output.NumBlocks) + assert.Equal(t, expectedNode2Blocks, node2Output.NumBlocks) + }) + + t.Run("ipfs dag stat", func(t *testing.T) { + t.Parallel() + node := harness.NewT(t).NewNode().Init().StartDaemon() + r, err := os.Open(fixtureFile) + assert.NoError(t, err) + defer r.Close() + f, err := os.Open(textOutputPath) + assert.NoError(t, err) + defer f.Close() + content, err := io.ReadAll(f) + assert.NoError(t, err) + err = node.IPFSDagImport(r, fixtureCid) + assert.NoError(t, err) + stat := node.RunIPFS("dag", "stat", "--progress=false", node1Cid, node2Cid) + assert.Equal(t, content, stat.Stdout.Bytes()) + }) + +} diff --git a/test/cli/fixtures/TestDagStat.car b/test/cli/fixtures/TestDagStat.car new file mode 100644 index 0000000000000000000000000000000000000000..d8af41b4da086eb89986648843199905ee0fcb79 GIT binary patch literal 402 zcmcColvX9eu(m2rJ>;&SiF4oy?z<) actual_stat_inner_ipld_obj && - echo "Size: 8, NumBlocks: 1" > exp_stat_inner_ipld_obj && - test_cmp exp_stat_inner_ipld_obj actual_stat_inner_ipld_obj && - ipfs dag stat $HASH > actual_stat_ipld_obj && - echo "Size: 54, NumBlocks: 2" > exp_stat_ipld_obj && - test_cmp exp_stat_ipld_obj actual_stat_ipld_obj - ' - test_expect_success "dag stat of simple UnixFS object" ' - BASIC_UNIXFS=$(echo "1234" | ipfs add --pin=false -q) && - ipfs dag stat $BASIC_UNIXFS > actual_stat_basic_unixfs && - echo "Size: 13, NumBlocks: 1" > exp_stat_basic_unixfs && - test_cmp exp_stat_basic_unixfs actual_stat_basic_unixfs - ' - - # The multiblock file is just 10000000 copies of the number 1 - # As most of its data is replicated it should have a small number of blocks - test_expect_success "dag stat of multiblock UnixFS object" ' - MULTIBLOCK_UNIXFS=$(printf "1%.0s" {1..10000000} | ipfs add --pin=false -q) && - ipfs dag stat $MULTIBLOCK_UNIXFS > actual_stat_multiblock_unixfs && - echo "Size: 302582, NumBlocks: 3" > exp_stat_multiblock_unixfs && - test_cmp exp_stat_multiblock_unixfs actual_stat_multiblock_unixfs - ' - - test_expect_success "dag stat of directory of UnixFS objects" ' - mkdir -p unixfsdir && - echo "1234" > unixfsdir/small.txt - printf "1%.0s" {1..10000000} > unixfsdir/many1s.txt && - DIRECTORY_UNIXFS=$(ipfs add -r --pin=false -Q unixfsdir) && - ipfs dag stat $DIRECTORY_UNIXFS > actual_stat_directory_unixfs && - echo "Size: 302705, NumBlocks: 5" > exp_stat_directory_unixfs && - test_cmp exp_stat_directory_unixfs actual_stat_directory_unixfs - ' } # should work offline From d86e227a5d115b9ad2347aa38dacd67d732386f9 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Tue, 6 Jun 2023 15:43:12 +0200 Subject: [PATCH 0697/1212] cmds/dag.stat: remove printf debug Oops lol. --- core/commands/dag/stat.go | 1 - 1 file changed, 1 deletion(-) diff --git a/core/commands/dag/stat.go b/core/commands/dag/stat.go index a8897c79c..23f4ab481 100644 --- a/core/commands/dag/stat.go +++ b/core/commands/dag/stat.go @@ -47,7 +47,6 @@ func dagStat(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) DAG: nodeGetter, Order: traverse.DFSPre, Func: func(current traverse.State) error { - fmt.Println("previousDagStatSize:", dagstats.Size) currentNodeSize := uint64(len(current.Node.RawData())) dagstats.Size += currentNodeSize dagstats.NumBlocks++ From 50daf64be41903b4c7175ffb2d883d94ecf9cd88 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Tue, 6 Jun 2023 15:49:31 +0200 Subject: [PATCH 0698/1212] changelog/v0.21: add dag stat additions --- docs/changelogs/v0.21.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/docs/changelogs/v0.21.md b/docs/changelogs/v0.21.md index fe369ef90..e000208a4 100644 --- a/docs/changelogs/v0.21.md +++ b/docs/changelogs/v0.21.md @@ -11,6 +11,7 @@ - [`client/rpc` migration of `go-ipfs-http-client`](#clientrpc-migration-of-go-ipfs-http-client) - [Gateway: DAG-CBOR/-JSON previews and improved error pages](#gateway-dag-cbor-json-previews-and-improved-error-pages) - [Gateway: subdomain redirects are now `text/html`](#gateway-subdomain-redirects-are-now-texthtml) + - [`ipfs dag stat` deduping statistics](#ipfs-dag-stat-deduping-statistics) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -102,6 +103,27 @@ $ curl "https://subdomain-gw.example.net/ipfs/${cid}/" Rationale can be found in [kubo#9913](https://github.com/ipfs/kubo/pull/9913). +#### `ipfs dag stat` deduping statistics + +`ipfs dat stat` now accept multiple CIDs and will dump advanced statistics +on the number of shared blocks and size of each CID. + +```console +$ ipfs dag stat --progress=false QmfXuRxzyVy5H2LssLgtXrKCrNvDY8UBvMp2aoW8LS8AYA QmfZDyu2UFfUhL4VdHaw7Hofivmn5D4DdQj38Lwo86RsnB + +CID Blocks Size +QmfXuRxzyVy5H2LssLgtXrKCrNvDY8UBvMp2aoW8LS8AYA 3 2151 +QmfZDyu2UFfUhL4VdHaw7Hofivmn5D4DdQj38Lwo86RsnB 4 3223 + +Summary +Total Size: 3326 +Unique Blocks: 5 +Shared Size: 2048 +Ratio: 1.615755 +``` + +`ipfs --enc=json dag stat`'s keys are a non breaking change, new keys have been added but old keys with previous sementics are still here. + ### 📝 Changelog ### 👨‍👩‍👧‍👦 Contributors From e5b33924a7730aa61c2cda0b8c63c3419a2511a0 Mon Sep 17 00:00:00 2001 From: Ivan Schasny <31857042+ischasny@users.noreply.github.com> Date: Wed, 7 Jun 2023 16:59:55 +0100 Subject: [PATCH 0699/1212] fix: correct list of addresses for delegated routing (#9920) --- cmd/ipfs/daemon.go | 2 +- core/core_test.go | 2 +- core/node/libp2p/routingopt.go | 34 ++++++++++++++++++++++++++--- core/node/libp2p/routingopt_test.go | 34 +++++++++++++++++++++++++++++ 4 files changed, 67 insertions(+), 5 deletions(-) create mode 100644 core/node/libp2p/routingopt_test.go diff --git a/cmd/ipfs/daemon.go b/cmd/ipfs/daemon.go index 1e03a8264..a61f1473b 100644 --- a/cmd/ipfs/daemon.go +++ b/cmd/ipfs/daemon.go @@ -429,7 +429,7 @@ func daemonFunc(req *cmds.Request, re cmds.ResponseEmitter, env cmds.Environment cfg.Routing.Routers, cfg.Routing.Methods, cfg.Identity.PeerID, - cfg.Addresses.Swarm, + cfg.Addresses, cfg.Identity.PrivKey, ) default: diff --git a/core/core_test.go b/core/core_test.go index 5e8c1336c..2d7e8927c 100644 --- a/core/core_test.go +++ b/core/core_test.go @@ -256,7 +256,7 @@ func GetNode(t *testing.T, reframeURLs ...string) *IpfsNode { cfg.Routing.Routers, cfg.Routing.Methods, cfg.Identity.PeerID, - cfg.Addresses.Swarm, + cfg.Addresses, cfg.Identity.PrivKey, ), }, diff --git a/core/node/libp2p/routingopt.go b/core/node/libp2p/routingopt.go index b363f25b7..da940837f 100644 --- a/core/node/libp2p/routingopt.go +++ b/core/node/libp2p/routingopt.go @@ -47,7 +47,7 @@ func constructDefaultHTTPRouters(cfg *config.Config) ([]*routinghelpers.Parallel var routers []*routinghelpers.ParallelRouter // Append HTTP routers for additional speed for _, endpoint := range defaultHTTPRouters { - httpRouter, err := irouting.ConstructHTTPRouter(endpoint, cfg.Identity.PeerID, cfg.Addresses.Swarm, cfg.Identity.PrivKey) + httpRouter, err := irouting.ConstructHTTPRouter(endpoint, cfg.Identity.PeerID, httpAddrsFromConfig(cfg.Addresses), cfg.Identity.PrivKey) if err != nil { return nil, err } @@ -123,7 +123,7 @@ func constructDHTRouting(mode dht.ModeOpt) RoutingOption { } // ConstructDelegatedRouting is used when Routing.Type = "custom" -func ConstructDelegatedRouting(routers config.Routers, methods config.Methods, peerID string, addrs []string, privKey string) RoutingOption { +func ConstructDelegatedRouting(routers config.Routers, methods config.Methods, peerID string, addrs config.Addresses, privKey string) RoutingOption { return func(args RoutingOptionArgs) (routing.Routing, error) { return irouting.Parse(routers, methods, &irouting.ExtraDHTParams{ @@ -135,7 +135,7 @@ func ConstructDelegatedRouting(routers config.Routers, methods config.Methods, p }, &irouting.ExtraHTTPParams{ PeerID: peerID, - Addrs: addrs, + Addrs: httpAddrsFromConfig(addrs), PrivKeyB64: privKey, }) } @@ -151,3 +151,31 @@ var ( DHTServerOption = constructDHTRouting(dht.ModeServer) NilRouterOption = constructNilRouting ) + +// httpAddrsFromConfig creates a list of addresses from the provided configuration to be used by HTTP delegated routers. +func httpAddrsFromConfig(cfgAddrs config.Addresses) []string { + // Swarm addrs are announced by default + addrs := cfgAddrs.Swarm + // if Announce addrs are specified - override Swarm + if len(cfgAddrs.Announce) > 0 { + addrs = cfgAddrs.Announce + } else if len(cfgAddrs.NoAnnounce) > 0 { + // if Announce adds are not specified - filter Swarm addrs with NoAnnounce list + maddrs := map[string]struct{}{} + for _, addr := range addrs { + maddrs[addr] = struct{}{} + } + for _, addr := range cfgAddrs.NoAnnounce { + delete(maddrs, addr) + } + addrs = make([]string, 0, len(maddrs)) + for k := range maddrs { + addrs = append(addrs, k) + } + } + // append AppendAnnounce addrs to the result list + if len(cfgAddrs.AppendAnnounce) > 0 { + addrs = append(addrs, cfgAddrs.AppendAnnounce...) + } + return addrs +} diff --git a/core/node/libp2p/routingopt_test.go b/core/node/libp2p/routingopt_test.go new file mode 100644 index 000000000..7a19b9d84 --- /dev/null +++ b/core/node/libp2p/routingopt_test.go @@ -0,0 +1,34 @@ +package libp2p + +import ( + "testing" + + config "github.com/ipfs/kubo/config" + "github.com/stretchr/testify/require" +) + +func TestHttpAddrsFromConfig(t *testing.T) { + require.Equal(t, []string{"/ip4/0.0.0.0/tcp/4001", "/ip4/0.0.0.0/udp/4001/quic"}, + httpAddrsFromConfig(config.Addresses{ + Swarm: []string{"/ip4/0.0.0.0/tcp/4001", "/ip4/0.0.0.0/udp/4001/quic"}, + }), "Swarm addrs should be taken by default") + + require.Equal(t, []string{"/ip4/192.168.0.1/tcp/4001"}, + httpAddrsFromConfig(config.Addresses{ + Swarm: []string{"/ip4/0.0.0.0/tcp/4001", "/ip4/0.0.0.0/udp/4001/quic"}, + Announce: []string{"/ip4/192.168.0.1/tcp/4001"}, + }), "Announce addrs should override Swarm if specified") + + require.Equal(t, []string{"/ip4/0.0.0.0/udp/4001/quic"}, + httpAddrsFromConfig(config.Addresses{ + Swarm: []string{"/ip4/0.0.0.0/tcp/4001", "/ip4/0.0.0.0/udp/4001/quic"}, + NoAnnounce: []string{"/ip4/0.0.0.0/tcp/4001"}, + }), "Swarm addrs should not contain NoAnnounce addrs") + + require.Equal(t, []string{"/ip4/192.168.0.1/tcp/4001", "/ip4/192.168.0.2/tcp/4001"}, + httpAddrsFromConfig(config.Addresses{ + Swarm: []string{"/ip4/0.0.0.0/tcp/4001", "/ip4/0.0.0.0/udp/4001/quic"}, + Announce: []string{"/ip4/192.168.0.1/tcp/4001"}, + AppendAnnounce: []string{"/ip4/192.168.0.2/tcp/4001"}, + }), "AppendAnnounce addrs should be included if specified") +} From 8390f8596f0bf41b452dafee792b2fc12ea25d4b Mon Sep 17 00:00:00 2001 From: Marco Munizaga Date: Wed, 7 Jun 2023 16:04:20 -0700 Subject: [PATCH 0700/1212] docs: update QUIC as the most widely used transport by Kubo nodes (#9921) * Update QUIC as the most widely used transport by Kubo nodes * Update docs --- docs/config.md | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/docs/config.md b/docs/config.md index bf2b7750c..eeff6ce58 100644 --- a/docs/config.md +++ b/docs/config.md @@ -1919,10 +1919,10 @@ Each field in this section is a `flag`. #### `Swarm.Transports.Network.TCP` -[TCP](https://en.wikipedia.org/wiki/Transmission_Control_Protocol) is the most -widely used transport by Kubo nodes. It doesn't directly support encryption -and/or multiplexing, so libp2p will layer a security & multiplexing transport -over it. +[TCP](https://en.wikipedia.org/wiki/Transmission_Control_Protocol) is a simple +and widely deployed transport, it should be compatible with most implementations +and network configurations. TCP doesn't directly support encryption and/or +multiplexing, so libp2p will layer a security & multiplexing transport over it. Default: Enabled @@ -1950,12 +1950,14 @@ Listen Addresses: #### `Swarm.Transports.Network.QUIC` -[QUIC](https://en.wikipedia.org/wiki/QUIC) is a UDP-based transport with -built-in encryption and multiplexing. The primary benefits over TCP are: +[QUIC](https://en.wikipedia.org/wiki/QUIC) is the most widely used transport by +Kubo nodes. It is a UDP-based transport with built-in encryption and +multiplexing. The primary benefits over TCP are: -1. It doesn't require a file descriptor per connection, easing the load on the OS. -2. It currently takes 2 round trips to establish a connection (our TCP transport - currently takes 6). +1. It takes 1 round trip to establish a connection (our TCP transport + currently takes 4). +2. No [Head-of-Line blocking](https://en.wikipedia.org/wiki/Head-of-line_blocking). +3. It doesn't require a file descriptor per connection, easing the load on the OS. Default: Enabled From 50feb752b92b5168985e5d7e0b3fe8dbf438efcd Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Fri, 2 Jun 2023 09:26:35 -0400 Subject: [PATCH 0701/1212] chore: update boxo to version with fewer globals --- docs/examples/kubo-as-a-library/go.mod | 6 +++--- docs/examples/kubo-as-a-library/go.sum | 16 ++++++---------- go.mod | 6 +++--- go.sum | 16 ++++++---------- 4 files changed, 18 insertions(+), 26 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 8a80a42c9..538e5ea8d 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.18 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.8.2-0.20230602144903-e2fc7f2fd023 + github.com/ipfs/boxo v0.8.2-0.20230608072023-5e3d0e035282 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.27.3 github.com/multiformats/go-multiaddr v0.9.0 @@ -81,9 +81,9 @@ require ( github.com/ipfs/go-ipfs-redirects-file v0.1.1 // indirect github.com/ipfs/go-ipfs-util v0.0.2 // indirect github.com/ipfs/go-ipld-cbor v0.0.6 // indirect - github.com/ipfs/go-ipld-format v0.4.0 // indirect + github.com/ipfs/go-ipld-format v0.5.0 // indirect github.com/ipfs/go-ipld-git v0.1.1 // indirect - github.com/ipfs/go-ipld-legacy v0.1.1 // indirect + github.com/ipfs/go-ipld-legacy v0.2.1 // indirect github.com/ipfs/go-log v1.0.5 // indirect github.com/ipfs/go-log/v2 v2.5.1 // indirect github.com/ipfs/go-metrics-interface v0.0.1 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 5c13ec7c5..dd3394438 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -321,8 +321,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.8.2-0.20230602144903-e2fc7f2fd023 h1:+9QiIziAuKW8AuGi26dFHw8SXTNB+MKooTp/sMlCmDY= -github.com/ipfs/boxo v0.8.2-0.20230602144903-e2fc7f2fd023/go.mod h1:Ej2r08Z4VIaFKqY08UXMNhwcLf6VekHhK8c+KqA1B9Y= +github.com/ipfs/boxo v0.8.2-0.20230608072023-5e3d0e035282 h1:86eDthzBwFRcIgXk/r0dEc3CgZzqmcqpgoU8GDKoYHQ= +github.com/ipfs/boxo v0.8.2-0.20230608072023-5e3d0e035282/go.mod h1:T7UvYGLnT4E9IjFbAnbisVfjUGQqMnbWCVT0kduwVck= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= @@ -331,7 +331,6 @@ github.com/ipfs/go-block-format v0.1.2 h1:GAjkfhVx1f4YTODS6Esrj1wt2HhrtwTnhEr+Dy github.com/ipfs/go-block-format v0.1.2/go.mod h1:mACVcrxarQKstUU3Yf/RdwbC4DzPV6++rO2a3d+a/KE= github.com/ipfs/go-blockservice v0.5.0 h1:B2mwhhhVQl2ntW2EIpaWPwSCxSuqr5fFA93Ms4bYLEY= github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= -github.com/ipfs/go-cid v0.0.2/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.3/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.4/go.mod h1:4LLaPOQwmk5z9LBgQnpkivrx8BJjUyGwTXCd5Xfj6+M= github.com/ipfs/go-cid v0.0.5/go.mod h1:plgt+Y5MnOey4vO4UlUazGqdbEXuFYitED67FexhXog= @@ -388,13 +387,12 @@ github.com/ipfs/go-ipfs-util v0.0.2/go.mod h1:CbPtkWJzjLdEcezDns2XYaehFVNXG9zrdr github.com/ipfs/go-ipld-cbor v0.0.6 h1:pYuWHyvSpIsOOLw4Jy7NbBkCyzLDcl64Bf/LZW7eBQ0= github.com/ipfs/go-ipld-cbor v0.0.6/go.mod h1:ssdxxaLJPXH7OjF5V4NSjBbcfh+evoR4ukuru0oPXMA= github.com/ipfs/go-ipld-format v0.0.1/go.mod h1:kyJtbkDALmFHv3QR6et67i35QzO3S0dCDnkOJhcZkms= -github.com/ipfs/go-ipld-format v0.2.0/go.mod h1:3l3C1uKoadTPbeNfrDi+xMInYKlx2Cvg1BuydPSdzQs= -github.com/ipfs/go-ipld-format v0.4.0 h1:yqJSaJftjmjc9jEOFYlpkwOLVKv68OD27jFLlSghBlQ= -github.com/ipfs/go-ipld-format v0.4.0/go.mod h1:co/SdBE8h99968X0hViiw1MNlh6fvxxnHpvVLnH7jSM= +github.com/ipfs/go-ipld-format v0.5.0 h1:WyEle9K96MSrvr47zZHKKcDxJ/vlpET6PSiQsAFO+Ds= +github.com/ipfs/go-ipld-format v0.5.0/go.mod h1:ImdZqJQaEouMjCvqCe0ORUS+uoBmf7Hf+EO/jh+nk3M= github.com/ipfs/go-ipld-git v0.1.1 h1:TWGnZjS0htmEmlMFEkA3ogrNCqWjIxwr16x1OsdhG+Y= github.com/ipfs/go-ipld-git v0.1.1/go.mod h1:+VyMqF5lMcJh4rwEppV0e6g4nCCHXThLYYDpKUkJubI= -github.com/ipfs/go-ipld-legacy v0.1.1 h1:BvD8PEuqwBHLTKqlGFTHSwrwFOMkVESEvwIYwR2cdcc= -github.com/ipfs/go-ipld-legacy v0.1.1/go.mod h1:8AyKFCjgRPsQFf15ZQgDB8Din4DML/fOmKZkkFkrIEg= +github.com/ipfs/go-ipld-legacy v0.2.1 h1:mDFtrBpmU7b//LzLSypVrXsD8QxkEWxu5qVxN99/+tk= +github.com/ipfs/go-ipld-legacy v0.2.1/go.mod h1:782MOUghNzMO2DER0FlBR94mllfdCJCkTtDtPM51otM= github.com/ipfs/go-libipfs v0.7.0 h1:Mi54WJTODaOL2/ZSm5loi3SwI3jI2OuFWUrQIkJ5cpM= github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= github.com/ipfs/go-log v1.0.3/go.mod h1:OsLySYkwIbiSUR/yBTdv1qPtcE4FW3WPWk/ewz9Ru+A= @@ -420,7 +418,6 @@ github.com/ipld/edelweiss v0.2.0/go.mod h1:FJAzJRCep4iI8FOFlRriN9n0b7OuX3T/S9++N github.com/ipld/go-car/v2 v2.9.1-0.20230325062757-fff0e4397a3d h1:22g+x1tgWSXK34i25qjs+afr7basaneEkHaglBshd2g= github.com/ipld/go-codec-dagpb v1.6.0 h1:9nYazfyu9B1p3NAgfVdpRco3Fs2nFC72DqVsMj6rOcc= github.com/ipld/go-codec-dagpb v1.6.0/go.mod h1:ANzFhfP2uMJxRBr8CE+WQWs5UsNa0pYtmKZ+agnUw9s= -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.14.1/go.mod h1:QcE4Y9n/ZZr8Ijg5bGPT0GqYWgZ1704nH0RDcQtgTP0= github.com/ipld/go-ipld-prime v0.20.0 h1:Ud3VwE9ClxpO2LkCYP7vWPc0Fo+dYdYzgxUJZ3uRG4g= @@ -655,7 +652,6 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/polydawn/refmt v0.0.0-20190221155625-df39d6c2d992/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= -github.com/polydawn/refmt v0.0.0-20190807091052-3d65705ee9f1/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= github.com/polydawn/refmt v0.0.0-20201211092308-30ac6d18308e/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= github.com/polydawn/refmt v0.89.0 h1:ADJTApkvkeBZsN0tBTx8QjpD9JkmxbKp0cxfr9qszm4= github.com/polydawn/refmt v0.89.0/go.mod h1:/zvteZs/GwLtCgZ4BL6CBsk9IKIlexP43ObX9AxTqTw= diff --git a/go.mod b/go.mod index 39443c36d..2363cee56 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/gogo/protobuf v1.3.2 github.com/google/uuid v1.3.0 github.com/hashicorp/go-multierror v1.1.1 - github.com/ipfs/boxo v0.8.2-0.20230602144903-e2fc7f2fd023 + github.com/ipfs/boxo v0.8.2-0.20230608072023-5e3d0e035282 github.com/ipfs/go-block-format v0.1.2 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 @@ -30,9 +30,9 @@ require ( github.com/ipfs/go-fs-lock v0.0.7 github.com/ipfs/go-graphsync v0.14.4 github.com/ipfs/go-ipfs-cmds v0.9.0 - github.com/ipfs/go-ipld-format v0.4.0 + github.com/ipfs/go-ipld-format v0.5.0 github.com/ipfs/go-ipld-git v0.1.1 - github.com/ipfs/go-ipld-legacy v0.1.1 + github.com/ipfs/go-ipld-legacy v0.2.1 github.com/ipfs/go-log v1.0.5 github.com/ipfs/go-log/v2 v2.5.1 github.com/ipfs/go-metrics-interface v0.0.1 diff --git a/go.sum b/go.sum index aec474d1c..25db08ebf 100644 --- a/go.sum +++ b/go.sum @@ -356,8 +356,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.8.2-0.20230602144903-e2fc7f2fd023 h1:+9QiIziAuKW8AuGi26dFHw8SXTNB+MKooTp/sMlCmDY= -github.com/ipfs/boxo v0.8.2-0.20230602144903-e2fc7f2fd023/go.mod h1:Ej2r08Z4VIaFKqY08UXMNhwcLf6VekHhK8c+KqA1B9Y= +github.com/ipfs/boxo v0.8.2-0.20230608072023-5e3d0e035282 h1:86eDthzBwFRcIgXk/r0dEc3CgZzqmcqpgoU8GDKoYHQ= +github.com/ipfs/boxo v0.8.2-0.20230608072023-5e3d0e035282/go.mod h1:T7UvYGLnT4E9IjFbAnbisVfjUGQqMnbWCVT0kduwVck= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= @@ -366,7 +366,6 @@ github.com/ipfs/go-block-format v0.1.2 h1:GAjkfhVx1f4YTODS6Esrj1wt2HhrtwTnhEr+Dy github.com/ipfs/go-block-format v0.1.2/go.mod h1:mACVcrxarQKstUU3Yf/RdwbC4DzPV6++rO2a3d+a/KE= github.com/ipfs/go-blockservice v0.5.0 h1:B2mwhhhVQl2ntW2EIpaWPwSCxSuqr5fFA93Ms4bYLEY= github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= -github.com/ipfs/go-cid v0.0.2/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.3/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.4/go.mod h1:4LLaPOQwmk5z9LBgQnpkivrx8BJjUyGwTXCd5Xfj6+M= github.com/ipfs/go-cid v0.0.5/go.mod h1:plgt+Y5MnOey4vO4UlUazGqdbEXuFYitED67FexhXog= @@ -424,13 +423,12 @@ github.com/ipfs/go-ipfs-util v0.0.2/go.mod h1:CbPtkWJzjLdEcezDns2XYaehFVNXG9zrdr github.com/ipfs/go-ipld-cbor v0.0.6 h1:pYuWHyvSpIsOOLw4Jy7NbBkCyzLDcl64Bf/LZW7eBQ0= github.com/ipfs/go-ipld-cbor v0.0.6/go.mod h1:ssdxxaLJPXH7OjF5V4NSjBbcfh+evoR4ukuru0oPXMA= github.com/ipfs/go-ipld-format v0.0.1/go.mod h1:kyJtbkDALmFHv3QR6et67i35QzO3S0dCDnkOJhcZkms= -github.com/ipfs/go-ipld-format v0.2.0/go.mod h1:3l3C1uKoadTPbeNfrDi+xMInYKlx2Cvg1BuydPSdzQs= -github.com/ipfs/go-ipld-format v0.4.0 h1:yqJSaJftjmjc9jEOFYlpkwOLVKv68OD27jFLlSghBlQ= -github.com/ipfs/go-ipld-format v0.4.0/go.mod h1:co/SdBE8h99968X0hViiw1MNlh6fvxxnHpvVLnH7jSM= +github.com/ipfs/go-ipld-format v0.5.0 h1:WyEle9K96MSrvr47zZHKKcDxJ/vlpET6PSiQsAFO+Ds= +github.com/ipfs/go-ipld-format v0.5.0/go.mod h1:ImdZqJQaEouMjCvqCe0ORUS+uoBmf7Hf+EO/jh+nk3M= github.com/ipfs/go-ipld-git v0.1.1 h1:TWGnZjS0htmEmlMFEkA3ogrNCqWjIxwr16x1OsdhG+Y= github.com/ipfs/go-ipld-git v0.1.1/go.mod h1:+VyMqF5lMcJh4rwEppV0e6g4nCCHXThLYYDpKUkJubI= -github.com/ipfs/go-ipld-legacy v0.1.1 h1:BvD8PEuqwBHLTKqlGFTHSwrwFOMkVESEvwIYwR2cdcc= -github.com/ipfs/go-ipld-legacy v0.1.1/go.mod h1:8AyKFCjgRPsQFf15ZQgDB8Din4DML/fOmKZkkFkrIEg= +github.com/ipfs/go-ipld-legacy v0.2.1 h1:mDFtrBpmU7b//LzLSypVrXsD8QxkEWxu5qVxN99/+tk= +github.com/ipfs/go-ipld-legacy v0.2.1/go.mod h1:782MOUghNzMO2DER0FlBR94mllfdCJCkTtDtPM51otM= github.com/ipfs/go-libipfs v0.7.0 h1:Mi54WJTODaOL2/ZSm5loi3SwI3jI2OuFWUrQIkJ5cpM= github.com/ipfs/go-libipfs v0.7.0/go.mod h1:KsIf/03CqhICzyRGyGo68tooiBE2iFbI/rXW7FhAYr0= github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= @@ -460,7 +458,6 @@ github.com/ipld/go-car v0.5.0 h1:kcCEa3CvYMs0iE5BzD5sV7O2EwMiCIp3uF8tA6APQT8= github.com/ipld/go-car/v2 v2.9.1-0.20230325062757-fff0e4397a3d h1:22g+x1tgWSXK34i25qjs+afr7basaneEkHaglBshd2g= github.com/ipld/go-codec-dagpb v1.6.0 h1:9nYazfyu9B1p3NAgfVdpRco3Fs2nFC72DqVsMj6rOcc= github.com/ipld/go-codec-dagpb v1.6.0/go.mod h1:ANzFhfP2uMJxRBr8CE+WQWs5UsNa0pYtmKZ+agnUw9s= -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.14.1/go.mod h1:QcE4Y9n/ZZr8Ijg5bGPT0GqYWgZ1704nH0RDcQtgTP0= github.com/ipld/go-ipld-prime v0.20.0 h1:Ud3VwE9ClxpO2LkCYP7vWPc0Fo+dYdYzgxUJZ3uRG4g= @@ -725,7 +722,6 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/polydawn/refmt v0.0.0-20190221155625-df39d6c2d992/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= -github.com/polydawn/refmt v0.0.0-20190807091052-3d65705ee9f1/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= github.com/polydawn/refmt v0.0.0-20201211092308-30ac6d18308e/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= github.com/polydawn/refmt v0.89.0 h1:ADJTApkvkeBZsN0tBTx8QjpD9JkmxbKp0cxfr9qszm4= github.com/polydawn/refmt v0.89.0/go.mod h1:/zvteZs/GwLtCgZ4BL6CBsk9IKIlexP43ObX9AxTqTw= From 4ebde42ec8fce624e510b1763e196805f4b9194b Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Wed, 31 May 2023 11:22:39 -0400 Subject: [PATCH 0702/1212] feat: switch dag import command to use default go-ipld-legacy block decoder --- core/commands/dag/import.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/core/commands/dag/import.go b/core/commands/dag/import.go index 2f2ed9e58..20f947bc2 100644 --- a/core/commands/dag/import.go +++ b/core/commands/dag/import.go @@ -27,6 +27,8 @@ func dagImport(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment return err } + blockDecoder := ipldlegacy.NewDecoder() + // on import ensure we do not reach out to the network for any reason // if a pin based on what is imported + what is in the blockstore // isn't possible: tough luck @@ -94,7 +96,7 @@ func dagImport(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment } // the double-decode is suboptimal, but we need it for batching - nd, err := ipldlegacy.DecodeNode(req.Context, block) + nd, err := blockDecoder.DecodeNode(req.Context, block) if err != nil { return err } @@ -131,7 +133,7 @@ func dagImport(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment // and ensure the gray bucket is empty at the end (or use the network to download missing blocks). if block, err := node.Blockstore.Get(req.Context, c); err != nil { ret.PinErrorMsg = err.Error() - } else if nd, err := ipldlegacy.DecodeNode(req.Context, block); err != nil { + } else if nd, err := blockDecoder.DecodeNode(req.Context, block); err != nil { ret.PinErrorMsg = err.Error() } else if err := node.Pinning.Pin(req.Context, nd, true); err != nil { ret.PinErrorMsg = err.Error() From de59ac1b44d6f3e8deaed0b2cbddb4d09a6bb11a Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Fri, 2 Jun 2023 10:35:31 -0400 Subject: [PATCH 0703/1212] feat(client/rpc): switch rpc client to use go-ipld-prime global decoders via go-ipld-legacy instead of go-ipld-format ones --- client/rpc/api.go | 15 +++++++++++++++ client/rpc/dag.go | 2 +- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/client/rpc/api.go b/client/rpc/api.go index 4df4dfde1..404f4b312 100644 --- a/client/rpc/api.go +++ b/client/rpc/api.go @@ -10,6 +10,12 @@ import ( iface "github.com/ipfs/boxo/coreiface" caopts "github.com/ipfs/boxo/coreiface/options" + "github.com/ipfs/boxo/ipld/merkledag" + "github.com/ipfs/go-cid" + legacy "github.com/ipfs/go-ipld-legacy" + dagpb "github.com/ipld/go-codec-dagpb" + _ "github.com/ipld/go-ipld-prime/codec/dagcbor" + "github.com/ipld/go-ipld-prime/node/basicnode" "github.com/mitchellh/go-homedir" ma "github.com/multiformats/go-multiaddr" manet "github.com/multiformats/go-multiaddr/net" @@ -35,6 +41,7 @@ type HttpApi struct { httpcli http.Client Headers http.Header applyGlobal func(*requestBuilder) + ipldDecoder *legacy.Decoder } // NewLocalApi tries to construct new HttpApi instance communicating with local @@ -125,11 +132,19 @@ func NewApiWithClient(a ma.Multiaddr, c *http.Client) (*HttpApi, error) { } func NewURLApiWithClient(url string, c *http.Client) (*HttpApi, error) { + decoder := legacy.NewDecoder() + // Add support for these codecs to match what is done in the merkledag library + // Note: to match prior behavior the go-ipld-prime CBOR decoder is manually included + // TODO: allow the codec registry used to be configured by the caller not through a global variable + decoder.RegisterCodec(cid.DagProtobuf, dagpb.Type.PBNode, merkledag.ProtoNodeConverter) + decoder.RegisterCodec(cid.Raw, basicnode.Prototype.Bytes, merkledag.RawNodeConverter) + api := &HttpApi{ url: url, httpcli: *c, Headers: make(map[string][]string), applyGlobal: func(*requestBuilder) {}, + ipldDecoder: decoder, } // We don't support redirects. diff --git a/client/rpc/dag.go b/client/rpc/dag.go index 62b54697e..69f83abfe 100644 --- a/client/rpc/dag.go +++ b/client/rpc/dag.go @@ -34,7 +34,7 @@ func (api *HttpDagServ) Get(ctx context.Context, c cid.Cid) (format.Node, error) return nil, err } - return format.DefaultBlockDecoder.Decode(blk) + return api.ipldDecoder.DecodeNode(ctx, blk) } func (api *HttpDagServ) GetMany(ctx context.Context, cids []cid.Cid) <-chan *format.NodeOption { From 23f01232c962a1a02810c40e2d8baf50f211af11 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Thu, 8 Jun 2023 07:07:53 +0200 Subject: [PATCH 0704/1212] ci: bump go version to 1.19.x across the whole board We were quite inconsistent about this previously, some files used 1.19.1 some 1.19.x, this makes it more consistent. --- .github/workflows/build.yml | 2 +- .github/workflows/docker-build.yml | 2 +- .github/workflows/gobuild.yml | 2 +- .github/workflows/golint.yml | 2 +- .github/workflows/gotest.yml | 2 +- .github/workflows/sharness.yml | 2 +- Dockerfile | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 33618d99c..d3dce10a0 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -10,7 +10,7 @@ on: - 'master' env: - GO_VERSION: 1.19.1 + GO_VERSION: 1.19.x concurrency: group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.event_name == 'push' && github.sha || github.ref }} diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml index 42d9c7c9c..6c9187364 100644 --- a/.github/workflows/docker-build.yml +++ b/.github/workflows/docker-build.yml @@ -27,6 +27,6 @@ jobs: steps: - uses: actions/setup-go@v3 with: - go-version: 1.19.1 + go-version: 1.19.x - uses: actions/checkout@v3 - run: docker build -t $IMAGE_NAME:$WIP_IMAGE_TAG . diff --git a/.github/workflows/gobuild.yml b/.github/workflows/gobuild.yml index ea71d1b50..b4a596afc 100644 --- a/.github/workflows/gobuild.yml +++ b/.github/workflows/gobuild.yml @@ -30,7 +30,7 @@ jobs: steps: - uses: actions/setup-go@v3 with: - go-version: 1.19.1 + go-version: 1.19.x - uses: actions/checkout@v3 - uses: protocol/cache-go-action@v1 with: diff --git a/.github/workflows/golint.yml b/.github/workflows/golint.yml index 0472e0f71..791f41e1b 100644 --- a/.github/workflows/golint.yml +++ b/.github/workflows/golint.yml @@ -31,7 +31,7 @@ jobs: steps: - uses: actions/setup-go@v3 with: - go-version: 1.19.1 + go-version: 1.19.x - uses: actions/checkout@v3 - uses: protocol/cache-go-action@v1 with: diff --git a/.github/workflows/gotest.yml b/.github/workflows/gotest.yml index a25cc3e4b..3f6db57ae 100644 --- a/.github/workflows/gotest.yml +++ b/.github/workflows/gotest.yml @@ -32,7 +32,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v3 with: - go-version: 1.19.1 + go-version: 1.19.x - name: Check out Kubo uses: actions/checkout@v3 - name: Restore Go cache diff --git a/.github/workflows/sharness.yml b/.github/workflows/sharness.yml index 505c4cd03..cc9ead442 100644 --- a/.github/workflows/sharness.yml +++ b/.github/workflows/sharness.yml @@ -25,7 +25,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v3 with: - go-version: 1.19.1 + go-version: 1.19.x - name: Checkout Kubo uses: actions/checkout@v3 with: diff --git a/Dockerfile b/Dockerfile index a252bc997..e70abcc1a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM --platform=${BUILDPLATFORM:-linux/amd64} golang:1.19.1-buster +FROM --platform=${BUILDPLATFORM:-linux/amd64} golang:1.19-buster LABEL maintainer="Steven Allen " ARG TARGETPLATFORM From 5de86ab047f9bfb5507133f17845b5c7bf6952c0 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Thu, 8 Jun 2023 09:51:26 +0200 Subject: [PATCH 0705/1212] chore: migrate test/dependencies to boxo --- test/dependencies/go.mod | 81 +-- test/dependencies/go.sum | 647 +++--------------- .../graphsync-get/graphsync-get.go | 10 +- 3 files changed, 139 insertions(+), 599 deletions(-) diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 5c2857114..4c805bba7 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -2,19 +2,17 @@ module github.com/ipfs/kubo/test/dependencies go 1.18 +replace github.com/ipfs/kubo => ../../ + require ( github.com/Kubuxu/gocovmerge v0.0.0-20161216165753-7ecaa51963cd github.com/golangci/golangci-lint v1.49.0 - github.com/ipfs/go-blockservice v0.3.0 - github.com/ipfs/go-cid v0.3.2 + github.com/ipfs/boxo v0.8.0 + github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 github.com/ipfs/go-datastore v0.6.0 - github.com/ipfs/go-graphsync v0.14.3 - github.com/ipfs/go-ipfs-blockstore v1.2.0 - github.com/ipfs/go-ipfs-exchange-offline v0.2.0 + github.com/ipfs/go-graphsync v0.14.4 github.com/ipfs/go-log v1.0.5 - github.com/ipfs/go-merkledag v0.8.1 - github.com/ipfs/go-unixfs v0.4.3 github.com/ipfs/hang-fds v0.1.0 github.com/ipfs/iptb v1.4.0 github.com/ipfs/iptb-plugins v0.3.0 @@ -48,6 +46,7 @@ require ( github.com/bombsimon/wsl/v3 v3.3.0 // indirect github.com/breml/bidichk v0.2.3 // indirect github.com/breml/errchkjson v0.3.0 // indirect + github.com/btcsuite/btcd v0.20.1-beta // indirect github.com/butuzov/ireturn v0.1.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/charithe/durationcheck v0.0.9 // indirect @@ -72,9 +71,11 @@ require ( github.com/firefart/nonamedreturns v1.0.4 // indirect github.com/flynn/noise v1.0.0 // indirect github.com/francoispqt/gojay v1.2.13 // indirect - github.com/fsnotify/fsnotify v1.5.4 // indirect + github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/fzipp/gocyclo v0.6.0 // indirect github.com/go-critic/go-critic v0.6.4 // indirect + github.com/go-logr/logr v1.2.3 // indirect + github.com/go-logr/stdr v1.2.2 // indirect github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect github.com/go-toolsmith/astcast v1.0.0 // indirect github.com/go-toolsmith/astcopy v1.0.1 // indirect @@ -111,7 +112,7 @@ require ( github.com/gostaticanalysis/nilerr v0.1.1 // indirect github.com/gxed/go-shellwords v1.0.3 // indirect github.com/hannahhoward/go-pubsub v0.0.0-20200423002714-8d62886cc36e // indirect - github.com/hashicorp/errwrap v1.0.0 // indirect + github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-version v1.6.0 // indirect github.com/hashicorp/golang-lru v0.5.4 // indirect @@ -121,22 +122,21 @@ require ( github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/ipfs/bbloom v0.0.4 // indirect github.com/ipfs/go-bitfield v1.1.0 // indirect - github.com/ipfs/go-block-format v0.0.3 // indirect - github.com/ipfs/go-ipfs-config v0.19.0 // indirect + github.com/ipfs/go-block-format v0.1.2 // indirect + github.com/ipfs/go-ipfs-blockstore v1.3.0 // indirect + github.com/ipfs/go-ipfs-config v0.5.3 // indirect github.com/ipfs/go-ipfs-ds-help v1.1.0 // indirect - github.com/ipfs/go-ipfs-exchange-interface v0.1.0 // indirect - github.com/ipfs/go-ipfs-pq v0.0.2 // indirect + github.com/ipfs/go-ipfs-files v0.2.0 // indirect + github.com/ipfs/go-ipfs-pq v0.0.3 // indirect github.com/ipfs/go-ipfs-util v0.0.2 // indirect - github.com/ipfs/go-ipld-cbor v0.0.5 // indirect + github.com/ipfs/go-ipld-cbor v0.0.6 // indirect github.com/ipfs/go-ipld-format v0.4.0 // indirect - github.com/ipfs/go-ipld-legacy v0.1.0 // indirect + github.com/ipfs/go-ipld-legacy v0.1.1 // indirect github.com/ipfs/go-log/v2 v2.5.1 // indirect github.com/ipfs/go-metrics-interface v0.0.1 // indirect - github.com/ipfs/go-peertaskqueue v0.8.0 // indirect - github.com/ipfs/go-unixfsnode v1.5.2 // indirect - github.com/ipfs/go-verifcid v0.0.1 // indirect - github.com/ipfs/interface-go-ipfs-core v0.7.0 // indirect - github.com/ipld/go-codec-dagpb v1.5.0 // indirect + github.com/ipfs/go-peertaskqueue v0.8.1 // indirect + github.com/ipfs/go-unixfsnode v1.6.0 // indirect + github.com/ipld/go-codec-dagpb v1.6.0 // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect github.com/jbenet/goprocess v0.1.4 // indirect @@ -148,7 +148,7 @@ require ( github.com/kisielk/errcheck v1.6.2 // indirect github.com/kisielk/gotool v1.0.0 // indirect github.com/klauspost/compress v1.15.12 // indirect - github.com/klauspost/cpuid/v2 v2.2.1 // indirect + github.com/klauspost/cpuid/v2 v2.2.3 // indirect github.com/koron/go-ssdp v0.0.3 // indirect github.com/kulti/thelper v0.6.3 // indirect github.com/kunwardeep/paralleltest v1.0.6 // indirect @@ -159,11 +159,12 @@ require ( github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/libp2p/go-cidranger v1.1.0 // indirect github.com/libp2p/go-flow-metrics v0.1.0 // indirect - github.com/libp2p/go-libp2p-asn-util v0.2.0 // indirect - github.com/libp2p/go-libp2p-core v0.20.1 // indirect + github.com/libp2p/go-libp2p-asn-util v0.3.0 // indirect + github.com/libp2p/go-libp2p-core v0.5.2 // indirect github.com/libp2p/go-msgio v0.3.0 // indirect github.com/libp2p/go-nat v0.1.0 // indirect github.com/libp2p/go-netroute v0.2.1 // indirect + github.com/libp2p/go-openssl v0.1.0 // indirect github.com/libp2p/go-reuseport v0.2.0 // indirect github.com/libp2p/go-yamux/v4 v4.0.0 // indirect github.com/lufeee/execinquery v1.2.1 // indirect @@ -172,7 +173,8 @@ require ( github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect github.com/matoous/godox v0.0.0-20210227103229-6504466cf951 // indirect github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.16 // indirect + github.com/mattn/go-isatty v0.0.18 // indirect + github.com/mattn/go-pointer v0.0.1 // indirect github.com/mattn/go-runewidth v0.0.9 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/mbilski/exhaustivestruct v1.2.0 // indirect @@ -190,7 +192,7 @@ require ( github.com/multiformats/go-multiaddr-dns v0.3.1 // indirect github.com/multiformats/go-multiaddr-fmt v0.1.0 // indirect github.com/multiformats/go-multibase v0.1.1 // indirect - github.com/multiformats/go-multicodec v0.8.0 // indirect + github.com/multiformats/go-multicodec v0.8.1 // indirect github.com/multiformats/go-multistream v0.4.1 // indirect github.com/multiformats/go-varint v0.0.7 // indirect github.com/nakabonne/nestif v0.3.1 // indirect @@ -207,7 +209,7 @@ require ( github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/polydawn/refmt v0.0.0-20201211092308-30ac6d18308e // indirect + github.com/polydawn/refmt v0.89.0 // indirect github.com/polyfloyd/go-errorlint v1.0.2 // indirect github.com/prometheus/client_golang v1.14.0 // indirect github.com/prometheus/client_model v0.3.0 // indirect @@ -237,6 +239,7 @@ require ( github.com/sivchari/tenv v1.7.0 // indirect github.com/sonatard/noctx v0.0.1 // indirect github.com/sourcegraph/go-diff v0.6.1 // indirect + github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/spf13/afero v1.8.2 // indirect github.com/spf13/cast v1.5.0 // indirect @@ -247,7 +250,7 @@ require ( github.com/ssgreg/nlreturn/v2 v2.2.1 // indirect github.com/stbenjam/no-sprintf-host-port v0.1.1 // indirect github.com/stretchr/objx v0.5.0 // indirect - github.com/stretchr/testify v1.8.1 // indirect + github.com/stretchr/testify v1.8.2 // indirect github.com/subosito/gotenv v1.4.0 // indirect github.com/sylvia7788/contextcheck v1.0.6 // indirect github.com/tdakkota/asciicheck v0.1.1 // indirect @@ -258,30 +261,30 @@ require ( github.com/tommy-muehle/go-mnd/v2 v2.5.0 // indirect github.com/ultraware/funlen v0.0.3 // indirect github.com/ultraware/whitespace v0.0.5 // indirect - github.com/urfave/cli v1.22.2 // indirect + github.com/urfave/cli v1.22.10 // indirect github.com/uudashr/gocognit v1.0.6 // indirect - github.com/whyrusleeping/cbor-gen v0.0.0-20210219115102-f37d292932f2 // indirect + github.com/whyrusleeping/cbor-gen v0.0.0-20230126041949-52956bd4c9aa // indirect github.com/yagipy/maintidx v1.0.0 // indirect github.com/yeya24/promlinter v0.2.0 // indirect gitlab.com/bosi/decorder v0.2.3 // indirect - go.opentelemetry.io/otel v1.2.0 // indirect - go.opentelemetry.io/otel/trace v1.2.0 // indirect + go.opentelemetry.io/otel v1.14.0 // indirect + go.opentelemetry.io/otel/trace v1.14.0 // indirect go.uber.org/atomic v1.10.0 // indirect go.uber.org/dig v1.15.0 // indirect go.uber.org/fx v1.18.2 // indirect - go.uber.org/multierr v1.8.0 // indirect + go.uber.org/multierr v1.9.0 // indirect go.uber.org/zap v1.24.0 // indirect - golang.org/x/crypto v0.4.0 // indirect - golang.org/x/exp v0.0.0-20221205204356-47842c84f3db // indirect + golang.org/x/crypto v0.6.0 // indirect + golang.org/x/exp v0.0.0-20230213192124-5e25df0256eb // indirect golang.org/x/exp/typeparams v0.0.0-20220613132600-b0d781184e0d // indirect golang.org/x/mod v0.7.0 // indirect - golang.org/x/net v0.4.0 // indirect + golang.org/x/net v0.7.0 // indirect golang.org/x/sync v0.1.0 // indirect - golang.org/x/sys v0.3.0 // indirect - golang.org/x/term v0.3.0 // indirect - golang.org/x/text v0.5.0 // indirect + golang.org/x/sys v0.6.0 // indirect + golang.org/x/term v0.5.0 // indirect + golang.org/x/text v0.7.0 // indirect golang.org/x/tools v0.3.0 // indirect - golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df // indirect + golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/protobuf v1.28.1 // indirect gopkg.in/ini.v1 v1.66.6 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 57e25d3fa..a353f474c 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -59,21 +59,14 @@ github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 h1:sHglBQTwgx+rW github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs= github.com/GaijinEntertainment/go-exhaustruct/v2 v2.3.0 h1:+r1rSv4gvYn0wmRjC8X7IAzX8QezqtFV9m0MUHFJgts= github.com/GaijinEntertainment/go-exhaustruct/v2 v2.3.0/go.mod h1:b3g59n2Y+T5xmcxJL+UEG2f8cQploZm1mR/v6BW0mU0= -github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/Kubuxu/go-os-helper v0.0.1/go.mod h1:N8B+I7vPCT80IcP58r50u4+gEEcsZETFUpAzWW2ep1Y= github.com/Kubuxu/gocovmerge v0.0.0-20161216165753-7ecaa51963cd h1:HNhzThEtZW714v8Eda8sWWRcu9WSzJC+oCyjRjvZgRA= github.com/Kubuxu/gocovmerge v0.0.0-20161216165753-7ecaa51963cd/go.mod h1:bqoB8kInrTeEtYAwaIXoSRqdwnjQmFhsfusnzyui6yY= github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= -github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/OpenPeeDeeP/depguard v1.1.0 h1:pjK9nLPS1FwQYGGpPxoMYpe7qACHOhAWQMQzV71i49o= github.com/OpenPeeDeeP/depguard v1.1.0/go.mod h1:JtAMzWkmFEzDPyAd+W0NHl1lvpQKTvT9jnRVsohBKpc= -github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= -github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= -github.com/Stebalien/go-bitfield v0.0.1/go.mod h1:GNjFpasyUVkHMsfEOk8EFLJ9syQ6SI+XWrX9Wf2XH0s= -github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= -github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= @@ -86,20 +79,11 @@ github.com/alexkohler/prealloc v1.0.0/go.mod h1:VetnK3dIgFBBKmg0YnD9F9x6Icjd+9cv github.com/alingse/asasalint v0.0.11 h1:SFwnQXJ49Kx/1GghOFz1XGqHYKp21Kq1nHad/0WQRnw= github.com/alingse/asasalint v0.0.11/go.mod h1:nCaoMhw7a9kSJObvQyVzNTPBDbNpdocqrSP7t/cW5+I= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= -github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= -github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= -github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= -github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= github.com/ashanbrown/forbidigo v1.3.0 h1:VkYIwb/xxdireGAdJNZoo24O4lmnEWkactplBlWTShc= github.com/ashanbrown/forbidigo v1.3.0/go.mod h1:vVW7PEdqEFqapJe95xHkTfB1+XvZXBFg8t0sG2FIxmI= github.com/ashanbrown/makezero v1.1.1 h1:iCQ87C0V0vSyO+M9E/FZYbu65auqH0lnsOkf5FcB28s= github.com/ashanbrown/makezero v1.1.1/go.mod h1:i1bJLCRSCHOcOa9Y6MyF2FTfMZMFdHvxKHxgO5Z1axI= -github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= -github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= @@ -107,7 +91,6 @@ github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24 github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bkielbasa/cyclop v1.2.0 h1:7Jmnh0yL2DjKfw28p86YTd/B4lRGcNuu12sKE35sM7A= github.com/bkielbasa/cyclop v1.2.0/go.mod h1:qOI0yy6A7dYC4Zgsa72Ppm9kONl0RoIlPbzot9mhmeI= github.com/blizzy78/varnamelen v0.8.0 h1:oqSblyuQvFsW1hbBHh1zfwrKe3kcSj0rnXkKzsQ089M= @@ -121,28 +104,21 @@ github.com/breml/errchkjson v0.3.0 h1:YdDqhfqMT+I1vIxPSas44P+9Z9HzJwCeAzjB8PxP1x github.com/breml/errchkjson v0.3.0/go.mod h1:9Cogkyv9gcT8HREpzi3TiqBxCqDzo8awa92zSDFcofU= github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= github.com/btcsuite/btcd v0.0.0-20190523000118-16327141da8c/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= -github.com/btcsuite/btcd v0.0.0-20190605094302-a0d1e3e36d50/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= github.com/btcsuite/btcd v0.0.0-20190824003749-130ea5bddde3/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= +github.com/btcsuite/btcd v0.20.1-beta h1:Ik4hyJqN8Jfyv3S4AGBOmyouMsYE3EdYODkMbQjwPGw= github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= -github.com/btcsuite/btcd v0.21.0-beta/go.mod h1:ZSWyehm27aAuS9bvkATT+Xte3hjHZ+MRgMY/8NJ7K94= github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= -github.com/btcsuite/btcutil v1.0.2/go.mod h1:j9HUFwoQRsZL3V4n+qG+CUnEGHOarIxfC3Le2Yhbcts= github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= -github.com/btcsuite/goleveldb v1.0.0/go.mod h1:QiK9vBlgftBg6rWQIj6wFzbPfRjiykIEhBH4obrXJ/I= github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= -github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= github.com/butuzov/ireturn v0.1.1 h1:QvrO2QF2+/Cx1WA/vETCIYBKtRjc30vesdoPUNo1EbY= github.com/butuzov/ireturn v0.1.1/go.mod h1:Wh6Zl3IMtTpaIKbmwzqi6olnM9ptYQxxVacMsOEFPoc= -github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= -github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= @@ -156,39 +132,30 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR 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= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -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/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE= github.com/containerd/cgroups v1.0.4 h1:jN/mbWBEaz+T1pi5OFtnkQ+8qnmEbAr1Oo1FRm5B0dA= github.com/containerd/cgroups v1.0.4/go.mod h1:nLNQtsF7Sl2HxNebu77i1R0oDlhiTG+kO4JTrUzo6IA= 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= -github.com/coreos/go-semver v0.2.1-0.20180108230905-e214231b295a/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= github.com/coreos/go-systemd/v22 v22.5.0/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/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= 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= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cristalhq/acmd v0.7.0/go.mod h1:LG5oa43pE/BbxtfMoImHCQN++0Su7dzipdgBjMCBVDQ= github.com/cskr/pubsub v1.0.2 h1:vlOzMhl6PFn60gRlTQQsIfVwaPB/B/8MziK8FhEPt/0= -github.com/cskr/pubsub v1.0.2/go.mod h1:/8MzYXk/NJAz782G8RPkFzXTZVu63VotefPnR9TIRis= github.com/curioswitch/go-reassign v0.1.2 h1:ekM07+z+VFT560Exz4mTv0/s1yU9gem6CJc/tlYpkmI= github.com/curioswitch/go-reassign v0.1.2/go.mod h1:bFJIHgtTM3hRm2sKXSPkbwNjSFyGURQXyn4IXD2qwfQ= github.com/daixiang0/gci v0.6.3 h1:wUAqXChk8HbwXn8AfxD9DYSCp9Bpz1L3e6Q4Roe+q9E= @@ -197,37 +164,25 @@ github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davidlazar/go-crypto v0.0.0-20170701192655-dcfb0a7ac018/go.mod h1:rQYf4tfk5sSwFsnDg3qYaBxSjsD9S8+59vW0dKUgme4= github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c h1:pFUpOrbxDR6AkioZ1ySsx5yxlDQZ8stG2b88gTPxgJU= github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c/go.mod h1:6UhI8N9EjYm1c2odKpFpAYeR8dsBeM7PtzQhRgxRr9U= github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 h1:HbphB4TFFXpv7MNrT52FGrrgVXF1owhMVTHFZIlnvd4= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0/go.mod h1:DZGJHZMqrU4JJqFAWUS2UO1+lbSKsdiOoYi9Zzey7Fc= -github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= github.com/denis-tingaikin/go-header v0.4.3 h1:tEaZKAlqql6SKCY++utLmkPLd6K8IBM20Ha7UVm+mtU= github.com/denis-tingaikin/go-header v0.4.3/go.mod h1:0wOCWuN71D5qIgE2nz9KrKmuYBAC2Mra5RassOIQ2/c= github.com/dgraph-io/badger v1.5.5-0.20190226225317-8115aed38f8f/go.mod h1:VZxzAIRPHRVNRKRo6AXrX9BJegn6il06VMTZVJYCIjQ= github.com/dgraph-io/badger v1.6.0-rc1/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= -github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= -github.com/dgraph-io/badger v1.6.1/go.mod h1:FRmFw3uxvcpa8zG3Rxs0th+hCLIuaQg8HlNV5bjgnuU= -github.com/dgraph-io/ristretto v0.0.2/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= -github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-farm v0.0.0-20190104051053-3adb47b1fb0f/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.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= -github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= -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/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= github.com/elastic/gosigar v0.14.2 h1:Dg80n8cr90OZ7x+bAax/QjoW/XqTI11RmA79ZwIm9/4= github.com/elastic/gosigar v0.14.2/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= -github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -241,7 +196,6 @@ github.com/ettle/strcase v0.1.1/go.mod h1:hzDLsPC7/lwKyBOywSHEP89nt2pDgdy+No1NBA github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5 h1:BBso6MBKW8ncyZLv37o+KNyy0HrrHgfnOaGQC2qvN+A= github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5/go.mod h1:JpoxHjuQauoxiFMl1ie8Xc/7TfLuMZ5eOCONd1sUBHg= github.com/fatih/color v1.6.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4= @@ -253,14 +207,11 @@ github.com/flynn/noise v1.0.0 h1:DlTHqmzmvcEiKj+4RYo/imoswx/4r6iBlCMfVtrMXpQ= github.com/flynn/noise v1.0.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag= github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk= github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= -github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= -github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI= -github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= +github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= +github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/fzipp/gocyclo v0.6.0 h1:lsblElZG7d3ALtGMx9fmxeTKZaLLpU8mET09yN4BBLo= github.com/fzipp/gocyclo v0.6.0/go.mod h1:rXPyn8fnlpa0R2csP/31uerbiVBugk5whMdlyaLkLoA= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= @@ -278,14 +229,17 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= @@ -318,6 +272,7 @@ github.com/go-toolsmith/typep v1.0.2 h1:8xdsa1+FSIH/RhEkgnD1j2CJOy5mNllW1Q9tRiYw github.com/go-toolsmith/typep v1.0.2/go.mod h1:JSQCQMUPdRlMZFswiq3TGpNp1GMktqkR2Ns5AIQkATU= github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b h1:khEcpUM4yFcxg4/FHQWkvVRmgijNXRfzkIDHh23ggEo= github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM= +github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0= @@ -332,18 +287,14 @@ github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= -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= -github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= @@ -405,7 +356,6 @@ github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ 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= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= @@ -434,10 +384,8 @@ github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20221203041831-ce31453925ec h1:fR20TYVVwhK4O7r7y+McjRYyaTH6/vjwJOajE+XhlzM= github.com/google/pprof v0.0.0-20221203041831-ce31453925ec/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= @@ -447,16 +395,10 @@ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5m github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c h1:7lF+Vz0LqiRidnzC1Oq86fpX1q/iEv2KJdrCtttYjT4= -github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gordonklaus/ineffassign v0.0.0-20210914165742-4cc7213b9bc8 h1:PVRE9d4AQKmbelZ7emNig1+NT27DUmKZn5qXxfio54U= github.com/gordonklaus/ineffassign v0.0.0-20210914165742-4cc7213b9bc8/go.mod h1:Qcp2HIAYhR7mNUVSIxZww3Guk4it82ghYcEXIAk+QT0= -github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= -github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE= @@ -475,36 +417,22 @@ github.com/gostaticanalysis/nilerr v0.1.1/go.mod h1:wZYb6YI5YAxxq0i1+VJbY0s2YONW github.com/gostaticanalysis/testutil v0.3.1-0.20210208050101-bfb5c8eec0e4/go.mod h1:D+FIZ+7OahH3ePw/izIEeH5I06eKs1IKI4Xr64/Am3M= github.com/gostaticanalysis/testutil v0.4.0 h1:nhdCmubdmDF6VEatUNjgUZBJKWRqugoISdUv3PPQgHY= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= -github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/gxed/go-shellwords v1.0.3 h1:2TP32H4TAklZUdz84oj95BJhVnIrRasyx2j1cqH5K38= github.com/gxed/go-shellwords v1.0.3/go.mod h1:N7paucT91ByIjmVJHhvoarjoQnmsi3Jd3vH7VqgtMxQ= github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= github.com/hannahhoward/go-pubsub v0.0.0-20200423002714-8d62886cc36e h1:3YKHER4nmd7b5qy5t0GWDTwSn4OyRgfAXSmo6VnryBY= github.com/hannahhoward/go-pubsub v0.0.0-20200423002714-8d62886cc36e/go.mod h1:I8h3MITA53gN9OnWGCgaMa0JWVRdXthWw4M3CPM54OY= -github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= -github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= -github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= +github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= -github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= -github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= -github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= -github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= @@ -512,14 +440,9 @@ github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+l github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= -github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= -github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= -github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= github.com/huin/goupnp v1.0.3 h1:N8No57ls+MnjlB+JPiCVSOyy/ot7MJTqlo7rn+NYSqQ= github.com/huin/goupnp v1.0.3/go.mod h1:ZxNlw5WqJj6wSsRK5+YfflQGXYfccj5VgQsMNixHM7Y= @@ -528,25 +451,17 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= -github.com/ipfs/bbloom v0.0.1/go.mod h1:oqo8CVWsJFMOZqTglBG4wydCE4IQA/G2/SEofB0rjUI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= +github.com/ipfs/boxo v0.8.0 h1:UdjAJmHzQHo/j3g3b1bAcAXCj/GM6iTwvSlBDvPBNBs= +github.com/ipfs/boxo v0.8.0/go.mod h1:RIsi4CnTyQ7AUsNn5gXljJYZlQrHBMnJp94p73liFiA= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= -github.com/ipfs/go-bitswap v0.0.9/go.mod h1:kAPf5qgn2W2DrgAcscZ3HrM9qh4pH+X8Fkk3UPrwvis= -github.com/ipfs/go-bitswap v0.1.0/go.mod h1:FFJEf18E9izuCqUtHxbWEvq+reg7o4CW5wSAE1wsxj0= -github.com/ipfs/go-bitswap v0.1.2/go.mod h1:qxSWS4NXGs7jQ6zQvoPY3+NmOfHHG47mhkiLzBpJQIs= -github.com/ipfs/go-bitswap v0.6.0 h1:f2rc6GZtoSFhEIzQmddgGiel9xntj02Dg0ZNf2hSC+w= -github.com/ipfs/go-bitswap v0.6.0/go.mod h1:Hj3ZXdOC5wBJvENtdqsixmzzRukqd8EHLxZLZc3mzRA= -github.com/ipfs/go-block-format v0.0.1/go.mod h1:DK/YYcsSUIVAFNwo/KZCdIIbpN0ROH/baNLgayt4pFc= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= -github.com/ipfs/go-block-format v0.0.3 h1:r8t66QstRp/pd/or4dpnbVfXT5Gt7lOqRvC+/dDTpMc= github.com/ipfs/go-block-format v0.0.3/go.mod h1:4LmD4ZUw0mhO+JSKdpWwrzATiEfM7WWgQ8H5l6P8MVk= -github.com/ipfs/go-blockservice v0.0.7/go.mod h1:EOfb9k/Y878ZTRY/CH0x5+ATtaipfbRhbvNSdgc/7So= -github.com/ipfs/go-blockservice v0.1.0/go.mod h1:hzmMScl1kXHg3M2BjTymbVPjv627N7sYcvYaKbop39M= -github.com/ipfs/go-blockservice v0.3.0 h1:cDgcZ+0P0Ih3sl8+qjFr2sVaMdysg/YZpLj5WJ8kiiw= -github.com/ipfs/go-blockservice v0.3.0/go.mod h1:P5ppi8IHDC7O+pA0AlGTF09jruB2h+oP3wVVaZl8sfk= +github.com/ipfs/go-block-format v0.1.2 h1:GAjkfhVx1f4YTODS6Esrj1wt2HhrtwTnhEr+DyPUaJo= +github.com/ipfs/go-block-format v0.1.2/go.mod h1:mACVcrxarQKstUU3Yf/RdwbC4DzPV6++rO2a3d+a/KE= +github.com/ipfs/go-blockservice v0.5.0 h1:B2mwhhhVQl2ntW2EIpaWPwSCxSuqr5fFA93Ms4bYLEY= github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.2/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.3/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= @@ -554,19 +469,12 @@ github.com/ipfs/go-cid v0.0.4/go.mod h1:4LLaPOQwmk5z9LBgQnpkivrx8BJjUyGwTXCd5Xfj github.com/ipfs/go-cid v0.0.5/go.mod h1:plgt+Y5MnOey4vO4UlUazGqdbEXuFYitED67FexhXog= github.com/ipfs/go-cid v0.0.6/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I= github.com/ipfs/go-cid v0.0.7/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I= -github.com/ipfs/go-cid v0.3.2 h1:OGgOd+JCFM+y1DjWPmVH+2/4POtpDzwcr7VgnB7mZXc= -github.com/ipfs/go-cid v0.3.2/go.mod h1:gQ8pKqT/sUxGY+tIwy1RPpAojYu7jAyCp5Tz1svoupw= +github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= +github.com/ipfs/go-cid v0.4.1/go.mod h1:uQHwDeX4c6CtyrFwdqyhpNcxVewur1M7l7fNU7LKwZk= github.com/ipfs/go-cidutil v0.1.0 h1:RW5hO7Vcf16dplUU60Hs0AKDkQAVPVplr7lk97CFL+Q= github.com/ipfs/go-cidutil v0.1.0/go.mod h1:e7OEVBMIv9JaOxt9zaGEmAoSlXW9jdFZ5lP/0PwcfpA= github.com/ipfs/go-datastore v0.0.1/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= -github.com/ipfs/go-datastore v0.0.5/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= github.com/ipfs/go-datastore v0.1.0/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= -github.com/ipfs/go-datastore v0.1.1/go.mod h1:w38XXW9kVFNp57Zj5knbKWM2T+KOZCGDRVNdgPHtbHw= -github.com/ipfs/go-datastore v0.3.1/go.mod h1:w38XXW9kVFNp57Zj5knbKWM2T+KOZCGDRVNdgPHtbHw= -github.com/ipfs/go-datastore v0.4.0/go.mod h1:SX/xMIKoCszPqp+z9JhPYCmoOoXTvaa13XEbGtsFUhA= -github.com/ipfs/go-datastore v0.4.1/go.mod h1:SX/xMIKoCszPqp+z9JhPYCmoOoXTvaa13XEbGtsFUhA= -github.com/ipfs/go-datastore v0.4.4/go.mod h1:SX/xMIKoCszPqp+z9JhPYCmoOoXTvaa13XEbGtsFUhA= -github.com/ipfs/go-datastore v0.4.5/go.mod h1:eXTcaaiN6uOlVCLS9GjJUJtlvJfM3xk23w3fyfrmmJs= github.com/ipfs/go-datastore v0.5.0/go.mod h1:9zhEApYMTl17C8YDp7JmU7sQZi2/wqiYh73hakZ90Bk= github.com/ipfs/go-datastore v0.6.0 h1:JKyz+Gvz1QEZw0LsX1IBn+JFCJQH4SJVFtM4uWU0Myk= github.com/ipfs/go-datastore v0.6.0/go.mod h1:rt5M3nNbSO/8q1t4LNkLyUwRs8HupMeN/8O4Vn9YAT8= @@ -574,112 +482,63 @@ github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps= github.com/ipfs/go-ds-badger v0.0.2/go.mod h1:Y3QpeSFWQf6MopLTiZD+VT6IC1yZqaGmjvRcKeSGij8= github.com/ipfs/go-ds-badger v0.0.5/go.mod h1:g5AuuCGmr7efyzQhLL8MzwqcauPojGPUaHzfGTzuE3s= -github.com/ipfs/go-ds-badger v0.2.1/go.mod h1:Tx7l3aTph3FMFrRS838dcSJh+jjA7cX9DrGVwx/NOwE= -github.com/ipfs/go-ds-badger v0.2.3/go.mod h1:pEYw0rgg3FIrywKKnL+Snr+w/LjJZVMTBRn4FS6UHUk= github.com/ipfs/go-ds-leveldb v0.0.1/go.mod h1:feO8V3kubwsEF22n0YRQCffeb79OOYIykR4L04tMOYc= -github.com/ipfs/go-ds-leveldb v0.4.1/go.mod h1:jpbku/YqBSsBc1qgME8BkWS4AxzF2cEu1Ii2r79Hh9s= -github.com/ipfs/go-ds-leveldb v0.4.2/go.mod h1:jpbku/YqBSsBc1qgME8BkWS4AxzF2cEu1Ii2r79Hh9s= -github.com/ipfs/go-graphsync v0.14.3 h1:IXH9S7AraMQ0J6Fzcl8rqSPqLn+es33bD8OW2KNyU/o= -github.com/ipfs/go-graphsync v0.14.3/go.mod h1:yT0AfjFgicOoWdAlUJ96tQ5AkuGI4r1taIQX/aHbBQo= -github.com/ipfs/go-ipfs-blockstore v0.0.1/go.mod h1:d3WClOmRQKFnJ0Jz/jj/zmksX0ma1gROTlovZKBmN08= -github.com/ipfs/go-ipfs-blockstore v0.1.0/go.mod h1:5aD0AvHPi7mZc6Ci1WCAhiBQu2IsfTduLl+422H6Rqw= -github.com/ipfs/go-ipfs-blockstore v1.2.0 h1:n3WTeJ4LdICWs/0VSfjHrlqpPpl6MZ+ySd3j8qz0ykw= -github.com/ipfs/go-ipfs-blockstore v1.2.0/go.mod h1:eh8eTFLiINYNSNawfZOC7HOxNTxpB1PFuA5E1m/7exE= +github.com/ipfs/go-graphsync v0.14.4 h1:ysazATpwsIjYtYEZH5CdD/HRaonCJd4pASUtnzESewk= +github.com/ipfs/go-graphsync v0.14.4/go.mod h1:yT0AfjFgicOoWdAlUJ96tQ5AkuGI4r1taIQX/aHbBQo= +github.com/ipfs/go-ipfs-blockstore v1.3.0 h1:m2EXaWgwTzAfsmt5UdJ7Is6l4gJcaM/A12XwJyvYvMM= +github.com/ipfs/go-ipfs-blockstore v1.3.0/go.mod h1:KgtZyc9fq+P2xJUiCAzbRdhhqJHvsw8u2Dlqy2MyRTE= github.com/ipfs/go-ipfs-blocksutil v0.0.1 h1:Eh/H4pc1hsvhzsQoMEP3Bke/aW5P5rVM1IWFJMcGIPQ= -github.com/ipfs/go-ipfs-blocksutil v0.0.1/go.mod h1:Yq4M86uIOmxmGPUHv/uI7uKqZNtLb449gwKqXjIsnRk= -github.com/ipfs/go-ipfs-chunker v0.0.1/go.mod h1:tWewYK0we3+rMbOh7pPFGDyypCtvGcBFymgY4rSDLAw= github.com/ipfs/go-ipfs-chunker v0.0.5 h1:ojCf7HV/m+uS2vhUGWcogIIxiO5ubl5O57Q7NapWLY8= +github.com/ipfs/go-ipfs-config v0.5.3 h1:3GpI/xR9FoJNTjU6YvCMRbYyEi0dBVY5UtlUTcNRlSA= github.com/ipfs/go-ipfs-config v0.5.3/go.mod h1:nSLCFtlaL+2rbl3F+9D4gQZQbT1LjRKx7TJg/IHz6oM= -github.com/ipfs/go-ipfs-config v0.19.0 h1:OuKIL+BkOZgJ+hb4Wg/9ynCtE/BaZBWcGy8hgdMepAo= -github.com/ipfs/go-ipfs-config v0.19.0/go.mod h1:wz2lKzOjgJeYJa6zx8W9VT7mz+iSd0laBMqS/9wmX6A= github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= github.com/ipfs/go-ipfs-delay v0.0.1 h1:r/UXYyRcddO6thwOnhiznIAiSvxMECGgtv35Xs1IeRQ= -github.com/ipfs/go-ipfs-delay v0.0.1/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= -github.com/ipfs/go-ipfs-ds-help v0.0.1/go.mod h1:gtP9xRaZXqIQRh1HRpp595KbBEdgqWFxefeVKOV8sxo= -github.com/ipfs/go-ipfs-ds-help v0.1.1/go.mod h1:SbBafGJuGsPI/QL3j9Fc5YPLeAu+SzOkI0gFwAg+mOs= github.com/ipfs/go-ipfs-ds-help v1.1.0 h1:yLE2w9RAsl31LtfMt91tRZcrx+e61O5mDxFRR994w4Q= github.com/ipfs/go-ipfs-ds-help v1.1.0/go.mod h1:YR5+6EaebOhfcqVCyqemItCLthrpVNot+rsOU/5IatU= -github.com/ipfs/go-ipfs-exchange-interface v0.0.1/go.mod h1:c8MwfHjtQjPoDyiy9cFquVtVHkO9b9Ob3FG91qJnWCM= -github.com/ipfs/go-ipfs-exchange-interface v0.1.0 h1:TiMekCrOGQuWYtZO3mf4YJXDIdNgnKWZ9IE3fGlnWfo= -github.com/ipfs/go-ipfs-exchange-interface v0.1.0/go.mod h1:ych7WPlyHqFvCi/uQI48zLZuAWVP5iTQPXEfVaw5WEI= -github.com/ipfs/go-ipfs-exchange-offline v0.0.1/go.mod h1:WhHSFCVYX36H/anEKQboAzpUws3x7UeEGkzQc3iNkM0= -github.com/ipfs/go-ipfs-exchange-offline v0.2.0 h1:2PF4o4A7W656rC0RxuhUace997FTcDTcIQ6NoEtyjAI= -github.com/ipfs/go-ipfs-exchange-offline v0.2.0/go.mod h1:HjwBeW0dvZvfOMwDP0TSKXIHf2s+ksdP4E3MLDRtLKY= -github.com/ipfs/go-ipfs-files v0.0.3/go.mod h1:INEFm0LL2LWXBhNJ2PMIIb2w45hpXgPjNoE7yA8Y1d4= -github.com/ipfs/go-ipfs-files v0.0.8/go.mod h1:wiN/jSG8FKyk7N0WyctKSvq3ljIa2NNTiZB55kpTdOs= +github.com/ipfs/go-ipfs-exchange-interface v0.2.0 h1:8lMSJmKogZYNo2jjhUs0izT+dck05pqUw4mWNW9Pw6Y= +github.com/ipfs/go-ipfs-exchange-offline v0.3.0 h1:c/Dg8GDPzixGd0MC8Jh6mjOwU57uYokgWRFidfvEkuA= +github.com/ipfs/go-ipfs-files v0.2.0 h1:z6MCYHQSZpDWpUSK59Kf0ajP1fi4gLCf6fIulVsp8A8= +github.com/ipfs/go-ipfs-files v0.2.0/go.mod h1:vT7uaQfIsprKktzbTPLnIsd+NGw9ZbYwSq0g3N74u0M= github.com/ipfs/go-ipfs-posinfo v0.0.1 h1:Esoxj+1JgSjX0+ylc0hUmJCOv6V2vFoZiETLR6OtpRs= -github.com/ipfs/go-ipfs-posinfo v0.0.1/go.mod h1:SwyeVP+jCwiDu0C313l/8jg6ZxM0qqtlt2a0vILTc1A= -github.com/ipfs/go-ipfs-pq v0.0.1/go.mod h1:LWIqQpqfRG3fNc5XsnIhz/wQ2XXGyugQwls7BgUmUfY= -github.com/ipfs/go-ipfs-pq v0.0.2 h1:e1vOOW6MuOwG2lqxcLA+wEn93i/9laCY8sXAw76jFOY= -github.com/ipfs/go-ipfs-pq v0.0.2/go.mod h1:LWIqQpqfRG3fNc5XsnIhz/wQ2XXGyugQwls7BgUmUfY= -github.com/ipfs/go-ipfs-routing v0.0.1/go.mod h1:k76lf20iKFxQTjcJokbPM9iBXVXVZhcOwc360N4nuKs= -github.com/ipfs/go-ipfs-routing v0.1.0/go.mod h1:hYoUkJLyAUKhF58tysKpids8RNDPO42BVMgK5dNsoqY= -github.com/ipfs/go-ipfs-routing v0.2.1/go.mod h1:xiNNiwgjmLqPS1cimvAw6EyB9rkVDbiocA4yY+wRNLM= -github.com/ipfs/go-ipfs-routing v0.3.0 h1:9W/W3N+g+y4ZDeffSgqhgo7BsBSJwPMcyssET9OWevc= +github.com/ipfs/go-ipfs-pq v0.0.3 h1:YpoHVJB+jzK15mr/xsWC574tyDLkezVrDNeaalQBsTE= +github.com/ipfs/go-ipfs-pq v0.0.3/go.mod h1:btNw5hsHBpRcSSgZtiNm/SLj5gYIZ18AKtv3kERkRb4= github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyBCNzQxlJBc= github.com/ipfs/go-ipfs-util v0.0.2 h1:59Sswnk1MFaiq+VcaknX7aYEyGyGDAA73ilhEK2POp8= github.com/ipfs/go-ipfs-util v0.0.2/go.mod h1:CbPtkWJzjLdEcezDns2XYaehFVNXG9zrdrtMecczcsQ= -github.com/ipfs/go-ipld-cbor v0.0.2/go.mod h1:wTBtrQZA3SoFKMVkp6cn6HMRteIB1VsmHA0AQFOn7Nc= -github.com/ipfs/go-ipld-cbor v0.0.3/go.mod h1:wTBtrQZA3SoFKMVkp6cn6HMRteIB1VsmHA0AQFOn7Nc= -github.com/ipfs/go-ipld-cbor v0.0.4/go.mod h1:BkCduEx3XBCO6t2Sfo5BaHzuok7hbhdMm9Oh8B2Ftq4= -github.com/ipfs/go-ipld-cbor v0.0.5 h1:ovz4CHKogtG2KB/h1zUp5U0c/IzZrL435rCh5+K/5G8= -github.com/ipfs/go-ipld-cbor v0.0.5/go.mod h1:BkCduEx3XBCO6t2Sfo5BaHzuok7hbhdMm9Oh8B2Ftq4= +github.com/ipfs/go-ipld-cbor v0.0.6 h1:pYuWHyvSpIsOOLw4Jy7NbBkCyzLDcl64Bf/LZW7eBQ0= +github.com/ipfs/go-ipld-cbor v0.0.6/go.mod h1:ssdxxaLJPXH7OjF5V4NSjBbcfh+evoR4ukuru0oPXMA= github.com/ipfs/go-ipld-format v0.0.1/go.mod h1:kyJtbkDALmFHv3QR6et67i35QzO3S0dCDnkOJhcZkms= -github.com/ipfs/go-ipld-format v0.0.2/go.mod h1:4B6+FM2u9OJ9zCV+kSbgFAZlOrv1Hqbf0INGQgiKf9k= github.com/ipfs/go-ipld-format v0.2.0/go.mod h1:3l3C1uKoadTPbeNfrDi+xMInYKlx2Cvg1BuydPSdzQs= -github.com/ipfs/go-ipld-format v0.3.0/go.mod h1:co/SdBE8h99968X0hViiw1MNlh6fvxxnHpvVLnH7jSM= github.com/ipfs/go-ipld-format v0.4.0 h1:yqJSaJftjmjc9jEOFYlpkwOLVKv68OD27jFLlSghBlQ= github.com/ipfs/go-ipld-format v0.4.0/go.mod h1:co/SdBE8h99968X0hViiw1MNlh6fvxxnHpvVLnH7jSM= -github.com/ipfs/go-ipld-legacy v0.1.0 h1:wxkkc4k8cnvIGIjPO0waJCe7SHEyFgl+yQdafdjGrpA= -github.com/ipfs/go-ipld-legacy v0.1.0/go.mod h1:86f5P/srAmh9GcIcWQR9lfFLZPrIyyXQeVlOWeeWEuI= -github.com/ipfs/go-libipfs v0.1.0 h1:I6CrHHp4cIiqsWJPVU3QBH4BZrRWSljS2aAbA3Eg9AY= +github.com/ipfs/go-ipld-legacy v0.1.1 h1:BvD8PEuqwBHLTKqlGFTHSwrwFOMkVESEvwIYwR2cdcc= +github.com/ipfs/go-ipld-legacy v0.1.1/go.mod h1:8AyKFCjgRPsQFf15ZQgDB8Din4DML/fOmKZkkFkrIEg= +github.com/ipfs/go-libipfs v0.6.0 h1:3FuckAJEm+zdHbHbf6lAyk0QUzc45LsFcGw102oBCZM= github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= -github.com/ipfs/go-log v1.0.2/go.mod h1:1MNjMxe0u6xvJZgeqbJ8vdo2TKaGwZ1a0Bpza+sr2Sk= -github.com/ipfs/go-log v1.0.3/go.mod h1:OsLySYkwIbiSUR/yBTdv1qPtcE4FW3WPWk/ewz9Ru+A= -github.com/ipfs/go-log v1.0.4/go.mod h1:oDCg2FkjogeFOhqqb+N39l2RpTNPL6F/StPkB3kPgcs= github.com/ipfs/go-log v1.0.5 h1:2dOuUCB1Z7uoczMWgAyDck5JLb72zHzrMnGnCNNbvY8= github.com/ipfs/go-log v1.0.5/go.mod h1:j0b8ZoR+7+R99LD9jZ6+AJsrzkPbSXbZfGakb5JPtIo= -github.com/ipfs/go-log/v2 v2.0.2/go.mod h1:O7P1lJt27vWHhOwQmcFEvlmo49ry2VY2+JfBWFaa9+0= -github.com/ipfs/go-log/v2 v2.0.3/go.mod h1:O7P1lJt27vWHhOwQmcFEvlmo49ry2VY2+JfBWFaa9+0= -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/go.mod h1:QqGoj30OTpnKaG/LKTGTxoP2mmQtjVMEnK72gynbe/g= github.com/ipfs/go-log/v2 v2.5.1 h1:1XdUzF7048prq4aBjDQQ4SL5RxftpRGdXhNRwKSAlcY= github.com/ipfs/go-log/v2 v2.5.1/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= -github.com/ipfs/go-merkledag v0.8.1 h1:N3yrqSre/ffvdwtHL4MXy0n7XH+VzN8DlzDrJySPa94= -github.com/ipfs/go-merkledag v0.8.1/go.mod h1:uYUlWE34GhbcTjGuUDEcdPzsEtOdnOupL64NgSRjmWI= +github.com/ipfs/go-merkledag v0.10.0 h1:IUQhj/kzTZfam4e+LnaEpoiZ9vZF6ldimVlby+6OXL4= github.com/ipfs/go-metrics-interface v0.0.1 h1:j+cpbjYvu4R8zbleSs36gvB7jR+wsL2fGD6n0jO4kdg= github.com/ipfs/go-metrics-interface v0.0.1/go.mod h1:6s6euYU4zowdslK0GKHmqaIZ3j/b/tL7HTWtJ4VPgWY= -github.com/ipfs/go-path v0.0.7/go.mod h1:6KTKmeRnBXgqrTvzFrPV3CamxcgvXX/4z79tfAd2Sno= -github.com/ipfs/go-peertaskqueue v0.0.4/go.mod h1:03H8fhyeMfKNFWqzYEVyMbcPUeYrqP1MX6Kd+aN+rMQ= -github.com/ipfs/go-peertaskqueue v0.1.0/go.mod h1:Jmk3IyCcfl1W3jTW3YpghSwSEC6IJ3Vzz/jUmWw8Z0U= -github.com/ipfs/go-peertaskqueue v0.7.0/go.mod h1:M/akTIE/z1jGNXMU7kFB4TeSEFvj68ow0Rrb04donIU= -github.com/ipfs/go-peertaskqueue v0.8.0 h1:JyNO144tfu9bx6Hpo119zvbEL9iQ760FHOiJYsUjqaU= -github.com/ipfs/go-peertaskqueue v0.8.0/go.mod h1:cz8hEnnARq4Du5TGqiWKgMr/BOSQ5XOgMOh1K5YYKKM= +github.com/ipfs/go-peertaskqueue v0.8.1 h1:YhxAs1+wxb5jk7RvS0LHdyiILpNmRIRnZVztekOF0pg= +github.com/ipfs/go-peertaskqueue v0.8.1/go.mod h1:Oxxd3eaK279FxeydSPPVGHzbwVeHjatZ2GA8XD+KbPU= github.com/ipfs/go-todocounter v0.0.1/go.mod h1:l5aErvQc8qKE2r7NDMjmq5UNAvuZy0rC8BHOplkWvZ4= -github.com/ipfs/go-unixfs v0.2.4/go.mod h1:SUdisfUjNoSDzzhGVxvCL9QO/nKdwXdr+gbMUdqcbYw= -github.com/ipfs/go-unixfs v0.4.3 h1:EdDc1sNZNFDUlo4UrVAvvAofVI5EwTnKu8Nv8mgXkWQ= -github.com/ipfs/go-unixfs v0.4.3/go.mod h1:TSG7G1UuT+l4pNj91raXAPkX0BhJi3jST1FDTfQ5QyM= -github.com/ipfs/go-unixfsnode v1.5.2 h1:CvsiTt58W2uR5dD8bqQv+aAY0c1qolmXmSyNbPHYiew= -github.com/ipfs/go-unixfsnode v1.5.2/go.mod h1:NlOebRwYx8lMCNMdhAhEspYPBD3obp7TE0LvBqHY+ks= -github.com/ipfs/go-verifcid v0.0.1 h1:m2HI7zIuR5TFyQ1b79Da5N9dnnCP1vcu2QqawmWlK2E= -github.com/ipfs/go-verifcid v0.0.1/go.mod h1:5Hrva5KBeIog4A+UpqlaIU+DEstipcJYQQZc0g37pY0= +github.com/ipfs/go-unixfs v0.4.5 h1:wj8JhxvV1G6CD7swACwSKYa+NgtdWC1RUit+gFnymDU= +github.com/ipfs/go-unixfsnode v1.6.0 h1:JOSA02yaLylRNi2rlB4ldPr5VcZhcnaIVj5zNLcOjDo= +github.com/ipfs/go-unixfsnode v1.6.0/go.mod h1:PVfoyZkX1B34qzT3vJO4nsLUpRCyhnMuHBznRcXirlk= +github.com/ipfs/go-verifcid v0.0.2 h1:XPnUv0XmdH+ZIhLGKg6U2vaPaRDXb9urMyNVCE7uvTs= github.com/ipfs/hang-fds v0.1.0 h1:deBiFlWHsVGzJ0ZMaqscEqRM1r2O1rFZ59UiQXb1Xko= github.com/ipfs/hang-fds v0.1.0/go.mod h1:29VLWOn3ftAgNNgXg/al7b11UzuQ+w7AwtCGcTaWkbM= -github.com/ipfs/interface-go-ipfs-core v0.4.0/go.mod h1:UJBcU6iNennuI05amq3FQ7g0JHUkibHFAfhfUIy927o= -github.com/ipfs/interface-go-ipfs-core v0.7.0 h1:7tb+2upz8oCcjIyjo1atdMk+P+u7wPmI+GksBlLE8js= -github.com/ipfs/interface-go-ipfs-core v0.7.0/go.mod h1:lF27E/nnSPbylPqKVXGZghal2hzifs3MmjyiEjnc9FY= github.com/ipfs/iptb v1.4.0 h1:YFYTrCkLMRwk/35IMyC6+yjoQSHTEcNcefBStLJzgvo= github.com/ipfs/iptb v1.4.0/go.mod h1:1rzHpCYtNp87/+hTxG5TfCVn/yMY3dKnLn8tBiMfdmg= github.com/ipfs/iptb-plugins v0.3.0 h1:C1rpq1o5lUZtaAOkLIox5akh6ba4uk/3RwWc6ttVxw0= github.com/ipfs/iptb-plugins v0.3.0/go.mod h1:5QtOvckeIw4bY86gSH4fgh3p3gCSMn3FmIKr4gaBncA= -github.com/ipld/go-car/v2 v2.1.1 h1:saaKz4nC0AdfCGHLYKeXLGn8ivoPC54fyS55uyOLKwA= -github.com/ipld/go-codec-dagpb v1.5.0 h1:RspDRdsJpLfgCI0ONhTAnbHdySGD4t+LHSPK4X1+R0k= -github.com/ipld/go-codec-dagpb v1.5.0/go.mod h1:0yRIutEFD8o1DGVqw4RSHh+BUTlJA9XWldxaaWR/o4g= +github.com/ipld/go-car/v2 v2.9.1-0.20230325062757-fff0e4397a3d h1:22g+x1tgWSXK34i25qjs+afr7basaneEkHaglBshd2g= +github.com/ipld/go-codec-dagpb v1.6.0 h1:9nYazfyu9B1p3NAgfVdpRco3Fs2nFC72DqVsMj6rOcc= +github.com/ipld/go-codec-dagpb v1.6.0/go.mod h1:ANzFhfP2uMJxRBr8CE+WQWs5UsNa0pYtmKZ+agnUw9s= github.com/ipld/go-ipld-prime v0.9.1-0.20210324083106-dc342a9917db/go.mod h1:KvBLMr4PX1gWptgkzRjVZCrLmSGcZCb/jioOQwCqZN8= github.com/ipld/go-ipld-prime v0.20.0 h1:Ud3VwE9ClxpO2LkCYP7vWPc0Fo+dYdYzgxUJZ3uRG4g= github.com/ipld/go-ipld-prime v0.20.0/go.mod h1:PzqZ/ZR981eKbgdr3y2DJYeD/8bgMawdGVlJDE8kK+M= @@ -709,7 +568,6 @@ github.com/jingyugao/rowserrcheck v1.1.1 h1:zibz55j/MJtLsjP1OF4bSdgXxwL1b+Vn7Tjz github.com/jingyugao/rowserrcheck v1.1.1/go.mod h1:4yvlZSDb3IyDTUZJUmpZfm2Hwok+Dtp+nu2qOq+er9c= github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af h1:KA9BjwUk7KlCh6S9EAGWBt1oExIUv9WyNCiRz5amv48= github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af/go.mod h1:HEWGJkRDzjJY2sqdDwxccsGicWEf9BQOZsq2tV+xzM0= -github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jonboulle/clockwork v0.2.0 h1:J2SLSdy7HgElq8ekSl2Mxh6vrRNFxqbXGenYH2I02Vs= @@ -718,7 +576,6 @@ github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= @@ -747,8 +604,8 @@ github.com/klauspost/compress v1.15.12 h1:YClS/PImqYbn+UILDnqxQCZ3RehC9N318SU3kE github.com/klauspost/compress v1.15.12/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.2.1 h1:U33DW0aiEj633gHYw3LoDNfkDiYnE5Q8M/TKJn2f2jI= -github.com/klauspost/cpuid/v2 v2.2.1/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= +github.com/klauspost/cpuid/v2 v2.2.3 h1:sxCkb+qR91z4vsqw4vGGZlDgPz3G7gjaLyK3V8y70BU= +github.com/klauspost/cpuid/v2 v2.2.3/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/koron/go-ssdp v0.0.0-20180514024734-4a0ed625a78b/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk= @@ -782,272 +639,112 @@ github.com/leonklingele/grouper v1.1.0 h1:tC2y/ygPbMFSBOs3DcyaEMKnnwH7eYKzohOtRr github.com/leonklingele/grouper v1.1.0/go.mod h1:uk3I3uDfi9B6PeUjsCKi6ndcf63Uy7snXgR4yDYQVDY= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= 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-buffer-pool v0.0.1/go.mod h1:xtyIz9PMobb13WaxR6Zo1Pd1zXJKYg0a8KiIvDp3TzQ= github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM= github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38yPW7c= github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic= -github.com/libp2p/go-conn-security v0.0.1/go.mod h1:bGmu51N0KU9IEjX7kl2PQjgZa40JQWnayTvNMgD/vyk= -github.com/libp2p/go-conn-security-multistream v0.0.2/go.mod h1:nc9vud7inQ+d6SO0I/6dSWrdMnHnzZNHeyUQqrAJulE= github.com/libp2p/go-conn-security-multistream v0.1.0/go.mod h1:aw6eD7LOsHEX7+2hJkDxw1MteijaVcI+/eP2/x3J1xc= -github.com/libp2p/go-conn-security-multistream v0.2.0/go.mod h1:hZN4MjlNetKD3Rq5Jb/P5ohUnFLNzEAR4DLSzpn2QLU= -github.com/libp2p/go-conn-security-multistream v0.2.1/go.mod h1:cR1d8gA0Hr59Fj6NhaTpFhJZrjSYuNmhpT2r25zYR70= github.com/libp2p/go-eventbus v0.0.2/go.mod h1:Hr/yGlwxA/stuLnpMiu82lpNKpvRy3EaJxPu40XYOwk= github.com/libp2p/go-eventbus v0.1.0/go.mod h1:vROgu5cs5T7cv7POWlWxBaVLxfSegC5UGQf8A2eEmx4= -github.com/libp2p/go-eventbus v0.2.1/go.mod h1:jc2S4SoEVPP48H9Wpzm5aiGwUCBMfGhVhhBjyhhCJs8= github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8= github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.0.30/go.mod h1:XWT8FGHlhptAv1+3V/+J5mEpzyui/5bvFsNuWYs611A= github.com/libp2p/go-libp2p v0.1.0/go.mod h1:6D/2OBauqLUoqcADOJpn9WbKqvaM07tDw68qHM0BxUM= -github.com/libp2p/go-libp2p v0.1.1/go.mod h1:I00BRo1UuUSdpuc8Q2mN7yDF/oTUTRAX6JWpTiK9Rp8= github.com/libp2p/go-libp2p v0.3.1/go.mod h1:e6bwxbdYH1HqWTz8faTChKGR0BjPc8p+6SyP8GTTR7Y= github.com/libp2p/go-libp2p v0.4.0/go.mod h1:9EsEIf9p2UDuwtPd0DwJsAl0qXVxgAnuDGRvHbfATfI= -github.com/libp2p/go-libp2p v0.6.1/go.mod h1:CTFnWXogryAHjXAKEbOf1OWY+VeAP3lDMZkfEI5sT54= -github.com/libp2p/go-libp2p v0.7.0/go.mod h1:hZJf8txWeCduQRDC/WSqBGMxaTHCOYHt2xSU1ivxn0k= -github.com/libp2p/go-libp2p v0.7.4/go.mod h1:oXsBlTLF1q7pxr+9w6lqzS1ILpyHsaBPniVO7zIHGMw= -github.com/libp2p/go-libp2p v0.8.1/go.mod h1:QRNH9pwdbEBpx5DTJYg+qxcVaDMAz3Ee/qDKwXujH5o= -github.com/libp2p/go-libp2p v0.14.3/go.mod h1:d12V4PdKbpL0T1/gsUNN8DfgMuRPDX8bS2QxCZlwRH0= github.com/libp2p/go-libp2p v0.26.4 h1:VA9ChjN0n1BwwfU/dqx4Zj9ezXtIxGk8FyJPwFONqxs= github.com/libp2p/go-libp2p v0.26.4/go.mod h1:x75BN32YbwuY0Awm2Uix4d4KOz+/4piInkp4Wr3yOo8= -github.com/libp2p/go-libp2p-asn-util v0.2.0 h1:rg3+Os8jbnO5DxkC7K/Utdi+DkY3q/d1/1q+8WeNAsw= -github.com/libp2p/go-libp2p-asn-util v0.2.0/go.mod h1:WoaWxbHKBymSN41hWSq/lGKJEca7TNm58+gGJi2WsLI= -github.com/libp2p/go-libp2p-autonat v0.0.6/go.mod h1:uZneLdOkZHro35xIhpbtTzLlgYturpu4J5+0cZK3MqE= +github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= +github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-autonat v0.1.0/go.mod h1:1tLf2yXxiE/oKGtDwPYWTSYG3PtvYlJmg7NeVtPRqH8= -github.com/libp2p/go-libp2p-autonat v0.1.1/go.mod h1:OXqkeGOY2xJVWKAGV2inNF5aKN/djNA3fdpCWloIudE= -github.com/libp2p/go-libp2p-autonat v0.2.0/go.mod h1:DX+9teU4pEEoZUqR1PiMlqliONQdNbfzE1C718tcViI= -github.com/libp2p/go-libp2p-autonat v0.2.1/go.mod h1:MWtAhV5Ko1l6QBsHQNSuM6b1sRkXrpk0/LqCr+vCVxI= -github.com/libp2p/go-libp2p-autonat v0.2.2/go.mod h1:HsM62HkqZmHR2k1xgX34WuWDzk/nBwNHoeyyT4IWV6A= -github.com/libp2p/go-libp2p-autonat v0.4.2/go.mod h1:YxaJlpr81FhdOv3W3BTconZPfhaYivRdf53g+S2wobk= github.com/libp2p/go-libp2p-autonat-svc v0.1.0/go.mod h1:fqi8Obl/z3R4PFVLm8xFtZ6PBL9MlV/xumymRFkKq5A= -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.3/go.mod h1:KML1//wiKR8vuuJO0y3LUd1uLv+tlkGTAr3jC0S5cLg= github.com/libp2p/go-libp2p-blankhost v0.1.4/go.mod h1:oJF0saYsAXQCSfDq254GMNmLNz6ZTHTOvtF4ZydUvwU= -github.com/libp2p/go-libp2p-blankhost v0.2.0/go.mod h1:eduNKXGTioTuQAUcZ5epXi9vMl+t4d8ugUBRQ4SqaNQ= -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.1/go.mod h1:Ahq4cY3V9VJcHcn1SBXjr78AbFkZeIRmfunbA7pmFh8= github.com/libp2p/go-libp2p-circuit v0.1.3/go.mod h1:Xqh2TjSy8DD5iV2cCOMzdynd6h8OTBGoV1AWbWor3qM= -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/go.mod h1:t/ktoFIUzM6uLQ+o1G6NuBl2ANhBKN9Bc8jRIk31MoA= github.com/libp2p/go-libp2p-connmgr v0.1.1/go.mod h1:wZxh8veAmU5qdrfJ0ZBLcU8oJe9L82ciVP/fl1VHjXk= 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= github.com/libp2p/go-libp2p-core v0.0.4/go.mod h1:jyuCQP356gzfCFtRKyvAbNkyeuxb7OlyhWZ3nls5d2I= github.com/libp2p/go-libp2p-core v0.0.6/go.mod h1:0d9xmaYAVY5qmbp/fcgxHT3ZJsLjYeYPMJAUKpaCHrE= github.com/libp2p/go-libp2p-core v0.2.0/go.mod h1:X0eyB0Gy93v0DZtSYbEM7RnMChm9Uv3j7yRXjO77xSI= github.com/libp2p/go-libp2p-core v0.2.2/go.mod h1:8fcwTbsG2B+lTgRJ1ICZtiM5GWCWZVoVrLaDRvIRng0= github.com/libp2p/go-libp2p-core v0.2.3/go.mod h1:GqhyQqyIAPsxFYXHMjfXgMv03lxsvM0mFzuYA9Ib42A= -github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= -github.com/libp2p/go-libp2p-core v0.3.0/go.mod h1:ACp3DmS3/N64c2jDzcV429ukDpicbL6+TrrxANBjPGw= -github.com/libp2p/go-libp2p-core v0.3.1/go.mod h1:thvWy0hvaSBhnVBaW37BvzgVV68OUhgJJLAa6almrII= -github.com/libp2p/go-libp2p-core v0.4.0/go.mod h1:49XGI+kc38oGVwqSBhDEwytaAxgZasHhFfQKibzTls0= github.com/libp2p/go-libp2p-core v0.5.0/go.mod h1:49XGI+kc38oGVwqSBhDEwytaAxgZasHhFfQKibzTls0= -github.com/libp2p/go-libp2p-core v0.5.1/go.mod h1:uN7L2D4EvPCvzSH5SrhR72UWbnSGpt5/a35Sm4upn4Y= +github.com/libp2p/go-libp2p-core v0.5.2 h1:hevsCcdLiazurKBoeNn64aPYTVOPdY4phaEGeLtHOAs= github.com/libp2p/go-libp2p-core v0.5.2/go.mod h1:uN7L2D4EvPCvzSH5SrhR72UWbnSGpt5/a35Sm4upn4Y= -github.com/libp2p/go-libp2p-core v0.5.4/go.mod h1:uN7L2D4EvPCvzSH5SrhR72UWbnSGpt5/a35Sm4upn4Y= -github.com/libp2p/go-libp2p-core v0.5.5/go.mod h1:vj3awlOr9+GMZJFH9s4mpt9RHHgGqeHCopzbYKZdRjM= -github.com/libp2p/go-libp2p-core v0.5.6/go.mod h1:txwbVEhHEXikXn9gfC7/UDDw7rkxuX0bJvM49Ykaswo= -github.com/libp2p/go-libp2p-core v0.5.7/go.mod h1:txwbVEhHEXikXn9gfC7/UDDw7rkxuX0bJvM49Ykaswo= -github.com/libp2p/go-libp2p-core v0.6.0/go.mod h1:txwbVEhHEXikXn9gfC7/UDDw7rkxuX0bJvM49Ykaswo= -github.com/libp2p/go-libp2p-core v0.6.1/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= -github.com/libp2p/go-libp2p-core v0.7.0/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= -github.com/libp2p/go-libp2p-core v0.8.0/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= -github.com/libp2p/go-libp2p-core v0.8.1/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= -github.com/libp2p/go-libp2p-core v0.8.2/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= -github.com/libp2p/go-libp2p-core v0.8.5/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= -github.com/libp2p/go-libp2p-core v0.20.1 h1:fQz4BJyIFmSZAiTbKV8qoYhEH5Dtv/cVhZbG3Ib/+Cw= -github.com/libp2p/go-libp2p-core v0.20.1/go.mod h1:6zR8H7CvQWgYLsbG4on6oLNSGcyKaYFSEYyDt51+bIY= -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= github.com/libp2p/go-libp2p-daemon v0.2.2/go.mod h1:kyrpsLB2JeNYR2rvXSVWyY0iZuRIMhqzWR3im9BV6NQ= -github.com/libp2p/go-libp2p-discovery v0.0.5/go.mod h1:YtF20GUxjgoKZ4zmXj8j3Nb2TUSBHFlOCetzYdbZL5I= github.com/libp2p/go-libp2p-discovery v0.1.0/go.mod h1:4F/x+aldVHjHDHuX85x1zWoFTGElt8HnoDzwkFZm29g= -github.com/libp2p/go-libp2p-discovery v0.2.0/go.mod h1:s4VGaxYMbw4+4+tsoQTqh7wfxg97AEdo4GYBt6BadWg= -github.com/libp2p/go-libp2p-discovery v0.3.0/go.mod h1:o03drFnz9BVAZdzC/QUQ+NeQOu38Fu7LJGEOK2gQltw= -github.com/libp2p/go-libp2p-discovery v0.5.0/go.mod h1:+srtPIU9gDaBNu//UHvcdliKBIcr4SfDcm0/PfPJLug= -github.com/libp2p/go-libp2p-host v0.0.1/go.mod h1:qWd+H1yuU0m5CwzAkvbSjqKairayEHdR5MMl7Cwa7Go= -github.com/libp2p/go-libp2p-host v0.0.3/go.mod h1:Y/qPyA6C8j2coYyos1dfRm0I8+nvd4TGrDGt4tA7JR8= -github.com/libp2p/go-libp2p-interface-connmgr v0.0.1/go.mod h1:GarlRLH0LdeWcLnYM/SaBykKFl9U5JFnbBGruAk/D5k= -github.com/libp2p/go-libp2p-interface-connmgr v0.0.4/go.mod h1:GarlRLH0LdeWcLnYM/SaBykKFl9U5JFnbBGruAk/D5k= -github.com/libp2p/go-libp2p-interface-connmgr v0.0.5/go.mod h1:GarlRLH0LdeWcLnYM/SaBykKFl9U5JFnbBGruAk/D5k= -github.com/libp2p/go-libp2p-interface-pnet v0.0.1/go.mod h1:el9jHpQAXK5dnTpKA4yfCNBZXvrzdOU75zz+C6ryp3k= github.com/libp2p/go-libp2p-kad-dht v0.2.1/go.mod h1:k7ONOlup7HKzQ68dE6lSnp07cdxdkmnRa+6B4Fh9/w0= github.com/libp2p/go-libp2p-kbucket v0.2.1/go.mod h1:/Rtu8tqbJ4WQ2KTCOMJhggMukOLNLNPY1EtEWWLxUvc= -github.com/libp2p/go-libp2p-loggables v0.0.1/go.mod h1:lDipDlBNYbpyqyPX/KcoO+eq0sJYEVR2JgOexcivchg= -github.com/libp2p/go-libp2p-loggables v0.1.0 h1:h3w8QFfCt2UJl/0/NW4K829HX/0S4KD31PQ7m8UXXO8= github.com/libp2p/go-libp2p-loggables v0.1.0/go.mod h1:EyumB2Y6PrYjr55Q3/tiJ/o3xoDasoRYM7nOzEpoa90= -github.com/libp2p/go-libp2p-metrics v0.0.1/go.mod h1:jQJ95SXXA/K1VZi13h52WZMa9ja78zjyy5rspMsC/08= -github.com/libp2p/go-libp2p-mplex v0.1.1/go.mod h1:KUQWpGkCzfV7UIpi8SKsAVxyBgz1c9R5EvxgnwLsb/I= github.com/libp2p/go-libp2p-mplex v0.2.0/go.mod h1:Ejl9IyjvXJ0T9iqUTE1jpYATQ9NM3g+OtR+EMMODbKo= github.com/libp2p/go-libp2p-mplex v0.2.1/go.mod h1:SC99Rxs8Vuzrf/6WhmH41kNn13TiYdAWNYHrwImKLnE= -github.com/libp2p/go-libp2p-mplex v0.2.2/go.mod h1:74S9eum0tVQdAfFiKxAyKzNdSuLqw5oadDq7+L/FELo= -github.com/libp2p/go-libp2p-mplex v0.2.3/go.mod h1:CK3p2+9qH9x+7ER/gWWDYJ3QW5ZxWDkm+dVvjfuG3ek= -github.com/libp2p/go-libp2p-mplex v0.4.0/go.mod h1:yCyWJE2sc6TBTnFpjvLuEJgTSw/u+MamvzILKdX7asw= -github.com/libp2p/go-libp2p-mplex v0.4.1/go.mod h1:cmy+3GfqfM1PceHTLL7zQzAAYaryDu6iPSC+CIb094g= 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= -github.com/libp2p/go-libp2p-net v0.0.1/go.mod h1:Yt3zgmlsHOgUWSXmt5V/Jpz9upuJBE8EgNU9DrCcR8c= -github.com/libp2p/go-libp2p-net v0.0.2/go.mod h1:Yt3zgmlsHOgUWSXmt5V/Jpz9upuJBE8EgNU9DrCcR8c= -github.com/libp2p/go-libp2p-netutil v0.0.1/go.mod h1:GdusFvujWZI9Vt0X5BKqwWWmZFxecf9Gt03cKxm2f/Q= -github.com/libp2p/go-libp2p-netutil v0.1.0 h1:zscYDNVEcGxyUpMd0JReUZTrpMfia8PmLKcKF72EAMQ= github.com/libp2p/go-libp2p-netutil v0.1.0/go.mod h1:3Qv/aDqtMLTUyQeundkKsA+YCThNdbQD54k3TqjpbFU= -github.com/libp2p/go-libp2p-noise v0.2.0/go.mod h1:IEbYhBBzGyvdLBoxxULL/SGbJARhUeqlO8lVSREYu2Q= -github.com/libp2p/go-libp2p-peer v0.0.1/go.mod h1:nXQvOBbwVqoP+T5Y5nCjeH4sP9IX/J0AMzcDUVruVoo= -github.com/libp2p/go-libp2p-peer v0.1.1/go.mod h1:jkF12jGB4Gk/IOo+yomm+7oLWxF278F7UnrYUQ1Q8es= github.com/libp2p/go-libp2p-peer v0.2.0/go.mod h1:RCffaCvUyW2CJmG2gAWVqwePwW7JMgxjsHm7+J5kjWY= -github.com/libp2p/go-libp2p-peerstore v0.0.1/go.mod h1:RabLyPVJLuNQ+GFyoEkfi8H4Ti6k/HtZJ7YKgtSq+20= -github.com/libp2p/go-libp2p-peerstore v0.0.6/go.mod h1:RabLyPVJLuNQ+GFyoEkfi8H4Ti6k/HtZJ7YKgtSq+20= github.com/libp2p/go-libp2p-peerstore v0.1.0/go.mod h1:2CeHkQsr8svp4fZ+Oi9ykN1HBb6u0MOvdJ7YIsmcwtY= github.com/libp2p/go-libp2p-peerstore v0.1.3/go.mod h1:BJ9sHlm59/80oSkpWgr1MyY1ciXAXV397W6h1GH/uKI= -github.com/libp2p/go-libp2p-peerstore v0.2.0/go.mod h1:N2l3eVIeAitSg3Pi2ipSrJYnqhVnMNQZo9nkSCuAbnQ= -github.com/libp2p/go-libp2p-peerstore v0.2.1/go.mod h1:NQxhNjWxf1d4w6PihR8btWIRjwRLBr4TYKfNgrUkOPA= -github.com/libp2p/go-libp2p-peerstore v0.2.2/go.mod h1:NQxhNjWxf1d4w6PihR8btWIRjwRLBr4TYKfNgrUkOPA= -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-pnet v0.2.0/go.mod h1:Qqvq6JH/oMZGwqs3N1Fqhv8NVhrdYcO0BW4wssv21LA= -github.com/libp2p/go-libp2p-protocol v0.0.1/go.mod h1:Af9n4PiruirSDjHycM1QuiMi/1VZNHYcK8cLgFJLZ4s= -github.com/libp2p/go-libp2p-protocol v0.1.0/go.mod h1:KQPHpAabB57XQxGrXCNvbL6UEXfQqUgC/1adR2Xtflk= github.com/libp2p/go-libp2p-pubsub v0.1.1/go.mod h1:ZwlKzRSe1eGvSIdU5bD7+8RZN/Uzw0t1Bp9R1znpR/Q= github.com/libp2p/go-libp2p-quic-transport v0.1.1/go.mod h1:wqG/jzhF3Pu2NrhJEvE+IE0NTHNXslOPn9JQzyCAxzU= -github.com/libp2p/go-libp2p-quic-transport v0.10.0/go.mod h1:RfJbZ8IqXIhxBRm5hqUEJqjiiY8xmEuq3HUDS993MkA= -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.1/go.mod h1:VRgKajOyMVgP/F0L5g3kH7SVskp17vFi2xheb5uMJtg= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= -github.com/libp2p/go-libp2p-routing v0.0.1/go.mod h1:N51q3yTr4Zdr7V8Jt2JIktVU+3xBBylx1MZeVA6t1Ys= github.com/libp2p/go-libp2p-routing v0.1.0/go.mod h1:zfLhI1RI8RLEzmEaaPwzonRvXeeSHddONWkcTcB54nE= -github.com/libp2p/go-libp2p-secio v0.0.3/go.mod h1:hS7HQ00MgLhRO/Wyu1bTX6ctJKhVpm+j2/S2A5UqYb0= github.com/libp2p/go-libp2p-secio v0.1.0/go.mod h1:tMJo2w7h3+wN4pgU2LSYeiKPrfqBgkOsdiKK77hE7c8= github.com/libp2p/go-libp2p-secio v0.2.0/go.mod h1:2JdZepB8J5V9mBp79BmwsaPQhRPNN2NrnB2lKQcdy6g= -github.com/libp2p/go-libp2p-secio v0.2.1/go.mod h1:cWtZpILJqkqrSkiYcDBh5lA3wbT2Q+hz3rJQq3iftD8= -github.com/libp2p/go-libp2p-secio v0.2.2/go.mod h1:wP3bS+m5AUnFA+OFO7Er03uO1mncHG0uVwGrwvjYlNY= -github.com/libp2p/go-libp2p-swarm v0.0.6/go.mod h1:s5GZvzg9xXe8sbeESuFpjt8CJPTCa8mhEusweJqyFy8= github.com/libp2p/go-libp2p-swarm v0.1.0/go.mod h1:wQVsCdjsuZoc730CgOvh5ox6K8evllckjebkdiY5ta4= github.com/libp2p/go-libp2p-swarm v0.2.1/go.mod h1:x07b4zkMFo2EvgPV2bMTlNmdQc8i+74Jjio7xGvsTgU= github.com/libp2p/go-libp2p-swarm v0.2.2/go.mod h1:fvmtQ0T1nErXym1/aa1uJEyN7JzaTNyBcHImCxRpPKU= -github.com/libp2p/go-libp2p-swarm v0.2.3/go.mod h1:P2VO/EpxRyDxtChXz/VPVXyTnszHvokHKRhfkEgFKNM= -github.com/libp2p/go-libp2p-swarm v0.2.8/go.mod h1:JQKMGSth4SMqonruY0a8yjlPVIkb0mdNSwckW7OYziM= -github.com/libp2p/go-libp2p-swarm v0.3.0/go.mod h1:hdv95GWCTmzkgeJpP+GK/9D9puJegb7H57B5hWQR5Kk= -github.com/libp2p/go-libp2p-swarm v0.5.0/go.mod h1:sU9i6BoHE0Ve5SKz3y9WfKrh8dUat6JknzUehFx8xW4= -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= github.com/libp2p/go-libp2p-testing v0.0.4/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= github.com/libp2p/go-libp2p-testing v0.1.0/go.mod h1:xaZWMJrPUM5GlDBxCeGUi7kI4eqnjVyavGroI2nxEM0= -github.com/libp2p/go-libp2p-testing v0.1.1/go.mod h1:xaZWMJrPUM5GlDBxCeGUi7kI4eqnjVyavGroI2nxEM0= -github.com/libp2p/go-libp2p-testing v0.1.2-0.20200422005655-8775583591d8/go.mod h1:Qy8sAncLKpwXtS2dSnDOP8ktexIAHKu+J+pnZOFZLTc= -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.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA= -github.com/libp2p/go-libp2p-tls v0.1.3/go.mod h1:wZfuewxOndz5RTnCAxFliGjvYSDA40sKitV4c50uI1M= -github.com/libp2p/go-libp2p-transport v0.0.1/go.mod h1:UzbUs9X+PHOSw7S3ZmeOxfnwaQY5vGDzZmKPod3N3tk= -github.com/libp2p/go-libp2p-transport v0.0.5/go.mod h1:StoY3sx6IqsP6XKoabsPnHCwqKXWUMWU7Rfcsubee/A= -github.com/libp2p/go-libp2p-transport-upgrader v0.0.4/go.mod h1:RGq+tupk+oj7PzL2kn/m1w6YXxcIAYJYeI90h6BGgUc= github.com/libp2p/go-libp2p-transport-upgrader v0.1.1/go.mod h1:IEtA6or8JUbsV07qPW4r01GnTenLW4oi3lOPbUMGJJA= -github.com/libp2p/go-libp2p-transport-upgrader v0.2.0/go.mod h1:mQcrHj4asu6ArfSoMuyojOdjx73Q47cYD7s5+gZOlns= -github.com/libp2p/go-libp2p-transport-upgrader v0.3.0/go.mod h1:i+SKzbRnvXdVbU3D1dwydnTmKRPXiAR/fyvi1dXuL4o= -github.com/libp2p/go-libp2p-transport-upgrader v0.4.2/go.mod h1:NR8ne1VwfreD5VIWIU62Agt/J18ekORFU/j1i2y8zvk= -github.com/libp2p/go-libp2p-yamux v0.1.2/go.mod h1:xUoV/RmYkg6BW/qGxA9XJyg+HzXFYkeXbnhjmnYzKp8= -github.com/libp2p/go-libp2p-yamux v0.1.3/go.mod h1:VGSQVrqkh6y4nm0189qqxMtvyBft44MOYYPpYKXiVt4= github.com/libp2p/go-libp2p-yamux v0.2.0/go.mod h1:Db2gU+XfLpm6E4rG5uGCFX6uXA8MEXOxFcRoXUODaK8= github.com/libp2p/go-libp2p-yamux v0.2.1/go.mod h1:1FBXiHDk1VyRM1C0aez2bCfHQ4vMZKkAQzZbkSQt5fI= -github.com/libp2p/go-libp2p-yamux v0.2.2/go.mod h1:lIohaR0pT6mOt0AZ0L2dFze9hds9Req3OfS+B+dv4qw= -github.com/libp2p/go-libp2p-yamux v0.2.5/go.mod h1:Zpgj6arbyQrmZ3wxSZxfBmbdnWtbZ48OpsfmQVTErwA= -github.com/libp2p/go-libp2p-yamux v0.2.7/go.mod h1:X28ENrBMU/nm4I3Nx4sZ4dgjZ6VhLEn0XhIoZ5viCwU= -github.com/libp2p/go-libp2p-yamux v0.2.8/go.mod h1:/t6tDqeuZf0INZMTgd0WxIRbtK2EzI2h7HbFm9eAKI4= -github.com/libp2p/go-libp2p-yamux v0.4.0/go.mod h1:+DWDjtFMzoAwYLVkNZftoucn7PelNoy5nm3tZ3/Zw30= -github.com/libp2p/go-libp2p-yamux v0.5.0/go.mod h1:AyR8k5EzyM2QN9Bbdg6X1SkVVuqLwTGf0L4DFq9g6po= -github.com/libp2p/go-libp2p-yamux v0.5.4/go.mod h1:tfrXbyaTqqSU654GTvK3ocnSZL3BuHoeTSqhcel1wsE= -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/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= github.com/libp2p/go-mplex v0.1.0/go.mod h1:SXgmdki2kwCUlCCbfGLEgHjC4pFqhTp0ZoV6aiKgxDU= -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/go.mod h1:0Oy/A9PQlwBytDRp4wSkFnzHYDKcpLot35JQ6msjvYQ= 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= -github.com/libp2p/go-msgio v0.0.6/go.mod h1:4ecVB6d9f4BDSL5fqvPiC4A3KivjWn+Venn/1ALLMWA= github.com/libp2p/go-msgio v0.3.0 h1:mf3Z8B1xcFN314sWX+2vOTShIE0Mmn2TXn3YCUQGNj0= github.com/libp2p/go-msgio v0.3.0/go.mod h1:nyRM819GmVaF9LX3l03RMh10QdOroF++NBbxAb0mmDM= github.com/libp2p/go-nat v0.0.3/go.mod h1:88nUEt0k0JD45Bk93NIwDqjlhiOwOoV36GchpcVc1yI= -github.com/libp2p/go-nat v0.0.4/go.mod h1:Nmw50VAvKuk38jUBcmNh6p9lUJLoODbJRvYAa/+KSDo= -github.com/libp2p/go-nat v0.0.5/go.mod h1:B7NxsVNPZmRLvMOwiEO1scOSyjA56zxYAGv1yQgRkEU= github.com/libp2p/go-nat v0.1.0 h1:MfVsH6DLcpa04Xr+p8hmVRG4juse0s3J8HyNWYHffXg= github.com/libp2p/go-nat v0.1.0/go.mod h1:X7teVkwRHNInVNWQiO/tAiAVRwSr5zoRz4YSTC3uRBM= 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/go.mod h1:AqhkMh0VuWmfgtxKPp3Oc1LdU5QSWS7wl0QLhSZqXxQ= github.com/libp2p/go-netroute v0.2.1 h1:V8kVrpD8GK0Riv15/7VN6RbUQ3URNZVosw7H2v9tksU= github.com/libp2p/go-netroute v0.2.1/go.mod h1:hraioZr0fhBjG0ZRXJJ6Zj2IVEVNx6tDTFQfSmcq7mQ= 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= -github.com/libp2p/go-openssl v0.0.5/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= -github.com/libp2p/go-openssl v0.0.7/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= +github.com/libp2p/go-openssl v0.1.0 h1:LBkKEcUv6vtZIQLVTegAil8jbNpJErQ9AnT+bWV+Ooo= +github.com/libp2p/go-openssl v0.1.0/go.mod h1:OiOxwPpL3n4xlenjx2h7AwSGaFSC/KZvf6gNdOBQMtc= github.com/libp2p/go-reuseport v0.0.1/go.mod h1:jn6RmB1ufnQwl0Q1f+YxAj8isJgDCQzaaxIFYDhcYEA= -github.com/libp2p/go-reuseport v0.0.2/go.mod h1:SPD+5RwGC7rcnzngoYC86GjPzjSywuQyMVAheVBD9nQ= github.com/libp2p/go-reuseport v0.2.0 h1:18PRvIMlpY6ZK85nIAicSBuXXvrYoSw3dsBAR7zc560= github.com/libp2p/go-reuseport v0.2.0/go.mod h1:bvVho6eLMm6Bz5hmU0LYN3ixd3nPPvtIlaURZZgOY4k= github.com/libp2p/go-reuseport-transport v0.0.2/go.mod h1:YkbSDrvjUVDL6b8XqriyA20obEtsW9BLkuOUyQAOCbs= -github.com/libp2p/go-reuseport-transport v0.0.3/go.mod h1:Spv+MPft1exxARzP2Sruj2Wb5JSyHNncjf1Oi2dEbzM= -github.com/libp2p/go-reuseport-transport v0.0.4/go.mod h1:trPa7r/7TJK/d+0hdBLOCGvpQQVOU74OXbNCIMkufGw= 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/go.mod h1:syPvOmNs24S3dFVGJA1/mrqdeijPxLV2Le3BRLKd68k= github.com/libp2p/go-stream-muxer v0.0.1/go.mod h1:bAo8x7YkSpadMTbtTaxGVHWUQsR/l5MEaHbKaliuT14= -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/go.mod h1:yDh8abSIzmZtqtOt64gFJUXEryejzNb0lisTt+fAMJA= -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= -github.com/libp2p/go-tcp-transport v0.2.0/go.mod h1:vX2U0CnWimU4h0SGSEsg++AzvBcroCGYw28kh94oLe0= -github.com/libp2p/go-tcp-transport v0.2.3/go.mod h1:9dvr03yqrPyYGIEN6Dy5UvdJZjyPFvl1S/igQ5QD1SU= -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= github.com/libp2p/go-ws-transport v0.1.0/go.mod h1:rjw1MG1LU9YDC6gzmwObkPd/Sqwhw7yT74kj3raBFuo= github.com/libp2p/go-ws-transport v0.1.2/go.mod h1:dsh2Ld8F+XNmzpkaAijmg5Is+e9l6/1tK/6VFOdN69Y= -github.com/libp2p/go-ws-transport v0.2.0/go.mod h1:9BHJz/4Q5A9ludYWKoGCFC5gUElzlHoKzu0yY9p/klM= -github.com/libp2p/go-ws-transport v0.3.0/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-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= -github.com/libp2p/go-yamux v1.3.0/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= -github.com/libp2p/go-yamux v1.3.3/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= -github.com/libp2p/go-yamux v1.3.5/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= -github.com/libp2p/go-yamux v1.3.7/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/hkmpooHE= -github.com/libp2p/go-yamux v1.4.0/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/hkmpooHE= -github.com/libp2p/go-yamux v1.4.1/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/hkmpooHE= -github.com/libp2p/go-yamux/v2 v2.2.0/go.mod h1:3So6P6TV6r75R9jiBpiIKgU/66lOarCZjqROGxzPpPQ= github.com/libp2p/go-yamux/v4 v4.0.0 h1:+Y80dV2Yx/kv7Y7JKu0LECyVdMXm1VUoko+VQ9rBfZQ= github.com/libp2p/go-yamux/v4 v4.0.0/go.mod h1:NWjl8ZTLOGlozrXSOZ/HlfG++39iKNnM5wwmtQP1YB4= -github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= -github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= github.com/lucas-clemente/quic-go v0.11.2/go.mod h1:PpMmPfPKO9nKJ/psF49ESTAGQSdfXxlg1otPbEB2nOw= -github.com/lucas-clemente/quic-go v0.19.3/go.mod h1:ADXpNbTQjq1hIzCpB+y/k5iz4n4z4IwqoLb94Kh5Hu8= github.com/lufeee/execinquery v1.2.1 h1:hf0Ems4SHcUGBxpGN7Jz78z1ppVkP/837ZlETPCEtOM= github.com/lufeee/execinquery v1.2.1/go.mod h1:EC7DrEKView09ocscGHC+apXMIaorh4xqSxS/dy8SbM= 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= github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo= github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= @@ -1055,10 +752,7 @@ github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/maratori/testpackage v1.1.0 h1:GJY4wlzQhuBusMF1oahQCBtUV/AQ/k69IZ68vxaac2Q= github.com/maratori/testpackage v1.1.0/go.mod h1:PeAhzU8qkCwdGEMTEupsHJNlQu2gZopMC6RjbhmHeDc= -github.com/marten-seemann/qpack v0.2.1/go.mod h1:F7Gl5L1jIgN1D11ucXefiuJS9UMVP2opoCp2jDKb7wc= github.com/marten-seemann/qtls v0.2.3/go.mod h1:xzjG7avBwGGbdZ8dTGxlBnLArsVKLvwmjgmPuiQEcYk= -github.com/marten-seemann/qtls v0.10.0/go.mod h1:UvMd1oaYDACI99/oZUYLzMCkBXQVT0aGm99sJhbT8hs= -github.com/marten-seemann/qtls-go1-15 v0.1.1/go.mod h1:GyFwywLKkRt+6mfU99csTEY1joMZz5vmB1WNZH3P81I= 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/matoous/godox v0.0.0-20210227103229-6504466cf951 h1:pWxk9e//NbPwfxat7RXkts09K+dEBJWakUWwICVqYbA= @@ -1067,20 +761,19 @@ github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE= github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= -github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= 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.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-isatty v0.0.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp98= +github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-pointer v0.0.1 h1:n+XhsuGeVO6MEAp7xyEukFINEa+Quek5psIR/ylA6o0= +github.com/mattn/go-pointer v0.0.1/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc= github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= @@ -1093,9 +786,7 @@ github.com/mgechev/revive v1.2.3 h1:NzIEEa9+WimQ6q2Ov7OcNeySS/IOcwtkQ8RAh0R5UJ4= github.com/mgechev/revive v1.2.3/go.mod h1:iAWlQishqCuj4yhV24FTnKSXGpbAA+0SckXB8GQMX/Q= github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= -github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.12/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/miekg/dns v1.1.28/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA= github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= @@ -1113,14 +804,8 @@ github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1 github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g= github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM= -github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= -github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= -github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= -github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= -github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= @@ -1152,17 +837,12 @@ github.com/multiformats/go-multiaddr v0.1.0/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lg github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo= github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4= github.com/multiformats/go-multiaddr v0.2.1/go.mod h1:s/Apk6IyxfvMjDafnhJgJ3/46z7tZ04iMk5wP4QMGGE= -github.com/multiformats/go-multiaddr v0.2.2/go.mod h1:NtfXiOtHvghW9KojvtySjH5y0u0xW5UouOmQQrn6a3Y= -github.com/multiformats/go-multiaddr v0.3.0/go.mod h1:dF9kph9wfJ+3VLAaeBqo9Of8x4fJxp6ggJGteB8HQTI= -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.8.0 h1:aqjksEcqK+iD/Foe1RRFsGZh8+XFiGo7FgUCZlpv3LU= github.com/multiformats/go-multiaddr v0.8.0/go.mod h1:Fs50eBDWvZu+l3/9S6xAE7ZYj6yhxlvaVZjakWN7xRs= 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.0.3/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= github.com/multiformats/go-multiaddr-dns v0.1.0/go.mod h1:01k2RAqtoXIuPa3DCavAE9/6jc6nM0H3EgZyfUhN2oY= -github.com/multiformats/go-multiaddr-dns v0.2.0/go.mod h1:TJ5pr5bBO7Y1B18djPuRsVkduhQH2YqYSbxWJzYGdK0= github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A= github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk= github.com/multiformats/go-multiaddr-fmt v0.0.1/go.mod h1:aBYjqL4T/7j4Qx+R73XSv/8JsgnRFlf0w2KGLCmXl3Q= @@ -1170,18 +850,12 @@ github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/e github.com/multiformats/go-multiaddr-fmt v0.1.0/go.mod h1:hGtDIW4PU4BqJ50gW2quDuPVjyWNZxToGUh/HwTZYJo= github.com/multiformats/go-multiaddr-net v0.0.1/go.mod h1:nw6HSxNmCIQH27XPGBuX+d1tnvM7ihcFwHMSstNAVUU= github.com/multiformats/go-multiaddr-net v0.1.0/go.mod h1:5JNbcfBOP4dnhoZOv10JJVkJO0pCCEf8mTnipAo2UZQ= -github.com/multiformats/go-multiaddr-net v0.1.1/go.mod h1:5JNbcfBOP4dnhoZOv10JJVkJO0pCCEf8mTnipAo2UZQ= -github.com/multiformats/go-multiaddr-net v0.1.2/go.mod h1:QsWt3XK/3hwvNxZJp92iMQKME1qHfpYmyIjFVsSOY6Y= -github.com/multiformats/go-multiaddr-net v0.1.3/go.mod h1:ilNnaM9HbmVFqsb/qcNysjCu4PVONlrBZpHIrw/qQuA= -github.com/multiformats/go-multiaddr-net v0.1.4/go.mod h1:ilNnaM9HbmVFqsb/qcNysjCu4PVONlrBZpHIrw/qQuA= -github.com/multiformats/go-multiaddr-net v0.1.5/go.mod h1:ilNnaM9HbmVFqsb/qcNysjCu4PVONlrBZpHIrw/qQuA= -github.com/multiformats/go-multiaddr-net v0.2.0/go.mod h1:gGdH3UXny6U3cKKYCvpXI5rnK7YaOIEOPVDI9tsJbEA= github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= github.com/multiformats/go-multibase v0.0.3/go.mod h1:5+1R4eQrT3PkYZ24C3W2Ue2tPwIdYQD509ZjSb5y9Oc= github.com/multiformats/go-multibase v0.1.1 h1:3ASCDsuLX8+j4kx58qnJ4YFq/JWTJpCyDW27ztsVTOI= github.com/multiformats/go-multibase v0.1.1/go.mod h1:ZEjHE+IsUrgp5mhlEAYjMtZwK1k4haNkcaPg9aoe1a8= -github.com/multiformats/go-multicodec v0.8.0 h1:evBmgkbSQux+Ds2IgfhkO38Dl2GDtRW8/Rp6YiSHX/Q= -github.com/multiformats/go-multicodec v0.8.0/go.mod h1:GUC8upxSBE4oG+q3kWZRw/+6yC1BqO550bjhWsJbZlw= +github.com/multiformats/go-multicodec v0.8.1 h1:ycepHwavHafh3grIbR1jIXnKCsFm0fqsfEOsJ8NtKE8= +github.com/multiformats/go-multicodec v0.8.1/go.mod h1:L3QTQvMIaVBkXOXXtVmYE+LI16i14xuaojr/H7Ai54k= github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= github.com/multiformats/go-multihash v0.0.5/go.mod h1:lt/HCbqlQwlPBz7lv0sQCdtfcMtlJvakRUn/0Ual8po= github.com/multiformats/go-multihash v0.0.8/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= @@ -1191,12 +865,7 @@ github.com/multiformats/go-multihash v0.0.14/go.mod h1:VdAWLKTwram9oKAatUcLxBNUj github.com/multiformats/go-multihash v0.0.15/go.mod h1:D6aZrWNLFTV/ynMpKsNtB40mJzmCl4jb1alC0OvHiHg= github.com/multiformats/go-multihash v0.2.1 h1:aem8ZT0VA2nCHHk7bPJ1BjUbHNciqZC/d16Vve9l108= github.com/multiformats/go-multihash v0.2.1/go.mod h1:WxoMcYG85AZVQUyRyo9s4wULvW5qrI9vb2Lt6evduFc= -github.com/multiformats/go-multistream v0.0.1/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg= -github.com/multiformats/go-multistream v0.0.4/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg= github.com/multiformats/go-multistream v0.1.0/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg= -github.com/multiformats/go-multistream v0.1.1/go.mod h1:KmHZ40hzVxiaiwlj3MEbYgK9JFk2/9UktWZAF54Du38= -github.com/multiformats/go-multistream v0.2.1/go.mod h1:5GZPQZbkWOLOn3J2y4Y99vVW7vOfsAflxARk3x14o6k= -github.com/multiformats/go-multistream v0.2.2/go.mod h1:UIcnm7Zuo8HKG+HkWgfQsGL+/MIEhyTqbODbIUwSXKs= github.com/multiformats/go-multistream v0.4.1 h1:rFy0Iiyn3YT0asivDUIR05leAdwZq3de4741sbiSdfo= github.com/multiformats/go-multistream v0.4.1/go.mod h1:Mz5eykRVAjJWckE2U78c6xqdtyNUEhKSM0Lwar2p77Q= github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= @@ -1209,13 +878,6 @@ github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRW github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/nakabonne/nestif v0.3.1 h1:wm28nZjhQY5HyYPx+weN3Q65k6ilSBxDb8v5S81B81U= github.com/nakabonne/nestif v0.3.1/go.mod h1:9EtoZochLn5iUprVDmDjqGKPofoUEBL8U4Ngq6aY7OE= -github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= -github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= -github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= -github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= -github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= -github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= -github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354 h1:4kuARK6Y6FxaNu/BnU2OAaLF86eTVhP2hjTB6iMvItA= github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354/go.mod h1:KSVJerMDfblTH7p5MZaTt+8zaT2iEk3AkVb9PQdZuE8= github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= @@ -1225,116 +887,78 @@ github.com/nishanths/exhaustive v0.8.1 h1:0QKNascWv9qIHY7zRoZSxeRr6kuk5aAT3YXLTi github.com/nishanths/exhaustive v0.8.1/go.mod h1:qj+zJJUgJ76tR92+25+03oYUhzF4R7/2Wk7fGTfCHmg= github.com/nishanths/predeclared v0.2.2 h1:V2EPdZPliZymNAn79T8RkNApBjMmVKh5XRpLm/w98Vk= github.com/nishanths/predeclared v0.2.2/go.mod h1:RROzoN6TnGQupbC+lqggsOlcgysk3LMK/HI84Mp280c= -github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= -github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= -github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= -github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg= -github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo/v2 v2.5.1 h1:auzK7OI497k6x4OvWq+TKAcpcSAlod0doAH72oIN0Jw= github.com/onsi/ginkgo/v2 v2.5.1/go.mod h1:63DOGlLAH8+REH8jUGdL3YpCpu7JODesutUjdENfUAc= -github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= -github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.24.0 h1:+0glovB9Jd6z3VR+ScSwQqXVTIfJcGA9UBM8yzQxhqg= -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= -github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= -github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= -github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= -github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= -github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= github.com/otiai10/copy v1.2.0 h1:HvG945u96iNadPoG2/Ja2+AUJeW5YuFQMixq9yirC+k= github.com/otiai10/copy v1.2.0/go.mod h1:rrF5dJ5F0t/EWSYODDu4j9/vEeYHMkc8jt0zJChqQWw= github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs= github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo= github.com/otiai10/mint v1.3.1/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc= -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/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pelletier/go-toml/v2 v2.0.2 h1:+jQXlF3scKIcSEKkdHzXhCTDLPFi5r1wnK6yPS+49Gw= github.com/pelletier/go-toml/v2 v2.0.2/go.mod h1:MovirKjgVRESsAvNZlAjtFwV867yGuwRkXbG66OzopI= -github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 h1:1/WtZae0yGtPq+TI6+Tv1WTxkukpXeMlviSxvL7SRgk= github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d h1:CdDQnGF8Nq9ocOS/xlSptM1N3BbrA6/kmaep5ggwaIA= github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d/go.mod h1:3OzsM7FXDQlpCiw2j81fOmAwQLnZnLGXVKUzeKQXIAw= -github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= -github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/polydawn/refmt v0.0.0-20190221155625-df39d6c2d992/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= -github.com/polydawn/refmt v0.0.0-20190408063855-01bf1e26dd14/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= github.com/polydawn/refmt v0.0.0-20190807091052-3d65705ee9f1/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= -github.com/polydawn/refmt v0.0.0-20201211092308-30ac6d18308e h1:ZOcivgkkFRnjfoTcGsDq3UQYiBmekwLA+qg0OjyB/ls= -github.com/polydawn/refmt v0.0.0-20201211092308-30ac6d18308e/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= +github.com/polydawn/refmt v0.89.0 h1:ADJTApkvkeBZsN0tBTx8QjpD9JkmxbKp0cxfr9qszm4= +github.com/polydawn/refmt v0.89.0/go.mod h1:/zvteZs/GwLtCgZ4BL6CBsk9IKIlexP43ObX9AxTqTw= github.com/polyfloyd/go-errorlint v1.0.2 h1:kp1yvHflYhTmw5m3MmBy8SCyQkKPjwDthVuMH0ug6Yk= github.com/polyfloyd/go-errorlint v1.0.2/go.mod h1:APVvOesVSAnne5SClsPxPdfvZTVDojXh1/G3qb5wjGI= -github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= -github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.10.0/go.mod h1:WJM3cc3yu7XKBKa/I8WeZm+V3eltZnBwfENSU7mdogU= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw= github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= -github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= -github.com/prometheus/common v0.18.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE= github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= -github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= @@ -1365,8 +989,6 @@ github.com/quic-go/webtransport-go v0.5.2 h1:GA6Bl6oZY+g/flt00Pnu0XtivSD8vukOu3l github.com/quic-go/webtransport-go v0.5.2/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU= -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/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= @@ -1377,15 +999,12 @@ github.com/ryancurrah/gomodguard v1.2.4 h1:CpMSDKan0LtNGGhPrvupAoLeObRFjND8/tU1r github.com/ryancurrah/gomodguard v1.2.4/go.mod h1:+Kem4VjWwvFpUJRJSwa16s1tBJe+vbv02+naTow2f6M= github.com/ryanrolds/sqlclosecheck v0.3.0 h1:AZx+Bixh8zdUBxUA1NxbxVAS78vTPq4rCb8OUZI9xFw= github.com/ryanrolds/sqlclosecheck v0.3.0/go.mod h1:1gREqxyTGR3lVtpngyFo3hZAgk0KCtEdgEkHwDbigdA= -github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= github.com/sanposhiho/wastedassign/v2 v2.0.6 h1:+6/hQIHKNJAUixEj6EmOngGIisyeI+T3335lYTyxRoA= github.com/sanposhiho/wastedassign/v2 v2.0.6/go.mod h1:KyZ0MWTwxxBmfwn33zh3k1dmsbF2ud9pAAGfoLfjhtI= github.com/sashamelentyev/interfacebloat v1.1.0 h1:xdRdJp0irL086OyW1H/RTZTr1h/tMEOsumirXcOJqAw= github.com/sashamelentyev/interfacebloat v1.1.0/go.mod h1:+Y9yU5YdTkrNvoX0xHc84dxiN1iBi9+G8zZIhPVoNjQ= github.com/sashamelentyev/usestdlibvars v1.13.0 h1:uObNudVEEHf6JbOJy5bgKJloA1bWjxR9fwgNFpPzKnI= github.com/sashamelentyev/usestdlibvars v1.13.0/go.mod h1:D2Wb7niIYmTB+gB8z7kh8tyP5ccof1dQ+SFk+WW5NtY= -github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/securego/gosec/v2 v2.13.1 h1:7mU32qn2dyC81MH9L2kefnQyRMUarfDER3iQyMHcjYM= github.com/securego/gosec/v2 v2.13.1/go.mod h1:EO1sImBMBWFjOTFzMWfTRrZW6M15gm60ljzrmy/wtHo= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= @@ -1428,24 +1047,22 @@ github.com/sivchari/nosnakecase v1.7.0/go.mod h1:CwDzrzPea40/GB6uynrNLiorAlgFRvR github.com/sivchari/tenv v1.7.0 h1:d4laZMBK6jpe5PWepxlV9S+LC0yXqvYHiq8E6ceoVVE= github.com/sivchari/tenv v1.7.0/go.mod h1:64yStXKSOxDfX47NlhVwND4dHwfZDdbp2Lyl018Icvg= 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= +github.com/smartystreets/assertions v1.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N3yZFZkDFs= +github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo= github.com/smartystreets/goconvey v0.0.0-20190222223459-a17d461953aa/go.mod h1:2RVY1rIf+2J2o/IM9+vPq9RzmHDSseB7FoXiSNIUsoU= -github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/smartystreets/goconvey v1.7.2 h1:9RBaZCeXEQ3UselpuwUQHltGVXvdwm6cv1hgR6gDIPg= +github.com/smartystreets/goconvey v1.7.2/go.mod h1:Vw0tHAZW6lzCRk3xgdin6fKYcG+G3Pg9vgXWeJpQFMM= github.com/smola/gocompat v0.2.0/go.mod h1:1B0MlxbmoZNo3h8guHp8HztB3BSYR5itql9qtVc0ypY= -github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/sonatard/noctx v0.0.1 h1:VC1Qhl6Oxx9vvWo3UDgrGXYCeKCe3Wbw7qAWL6FrmTY= github.com/sonatard/noctx v0.0.1/go.mod h1:9D2D/EoULe8Yy2joDHJj7bv3sZoq9AaSb8B4lqBjiZI= -github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE= github.com/sourcegraph/go-diff v0.6.1 h1:hmA1LzxW0n1c3Q4YbrFgg4P99GSnebYa3x8gr0HZqLQ= github.com/sourcegraph/go-diff v0.6.1/go.mod h1:iBszgVvyxdc8SFZ7gm69go2KDdt3ag071iBaWPF6cjs= github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA= github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a/go.mod h1:7AyxJNCJ7SBZ1MfVQCWD6Uqo2oubI2Eq2y2eqf+A5r0= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU= github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= -github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= @@ -1454,14 +1071,12 @@ github.com/spf13/afero v1.8.2/go.mod h1:CtAatgMJh6bJEIs48Ay/FOnkljP3WeGUG0MC1RfA github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= -github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/cobra v1.5.0 h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU= github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= -github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= @@ -1473,9 +1088,6 @@ github.com/ssgreg/nlreturn/v2 v2.2.1 h1:X4XDI7jstt3ySqGU86YGAURbxw3oTDPK9sPEi6YE github.com/ssgreg/nlreturn/v2 v2.2.1/go.mod h1:E/iiPB78hV7Szg2YfRgyIrk1AD6JVMTRkkxBiELzh2I= github.com/stbenjam/no-sprintf-host-port v0.1.1 h1:tYugd/yrm1O0dV+ThCbaKZh195Dfm07ysF0U6JQXczc= github.com/stbenjam/no-sprintf-host-port v0.1.1/go.mod h1:TLhvtIvONRzdmkFiio4O8LHsN9N74I+PhRquPsxpL0I= -github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= -github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= -github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= @@ -1486,13 +1098,12 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/subosito/gotenv v1.4.0 h1:yAzM1+SmVcz5R4tXGsNMu1jUl2aOJXoiWUCEwwnGrvs= github.com/subosito/gotenv v1.4.0/go.mod h1:mZd6rFysKEcUhUHXJk0C/08wAgyDBFuwEYL7vWWGaGo= github.com/sylvia7788/contextcheck v1.0.6 h1:o2EZgVPyMKE/Mtoqym61DInKEjwEbsmyoxg3VrmjNO4= @@ -1511,7 +1122,6 @@ github.com/timakin/bodyclose v0.0.0-20210704033933-f49887972144 h1:kl4KhGNsJIbDH github.com/timakin/bodyclose v0.0.0-20210704033933-f49887972144/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk= github.com/timonwong/logrlint v0.1.0 h1:phZCcypL/vtx6cGxObJgWZ5wexZF5SXFPLOM+ru0e/M= github.com/timonwong/logrlint v0.1.0/go.mod h1:Zleg4Gw+kRxNej+Ra7o+tEaW5k1qthTaYKU7rSD39LU= -github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tomarrell/wrapcheck/v2 v2.6.2 h1:3dI6YNcrJTQ/CJQ6M/DUkc0gnqYSIk6o0rChn9E/D0M= github.com/tomarrell/wrapcheck/v2 v2.6.2/go.mod h1:ao7l5p0aOlUNJKI0qVwB4Yjlqutd0IvAB9Rdwyilxvg= github.com/tommy-muehle/go-mnd/v2 v2.5.0 h1:iAj0a8e6+dXSL7Liq0aXPox36FiN1dBbjA6lt9fl65s= @@ -1526,29 +1136,27 @@ github.com/ultraware/funlen v0.0.3/go.mod h1:Dp4UiAus7Wdb9KUZsYWZEWiRzGuM2kXM1lP github.com/ultraware/whitespace v0.0.5 h1:hh+/cpIcopyMYbZNVov9iSxvJU3OYQg78Sfaqzi/CzI= github.com/ultraware/whitespace v0.0.5/go.mod h1:aVMh/gQve5Maj9hQ/hg+F75lr/X5A89uZnzAmWSineA= 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 h1:gsqYFH8bb9ekPA12kRo0hfjngWQjkJPlN9R0N78BoUo= github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/urfave/cli v1.22.10 h1:p8Fspmz3iTctJstry1PYS3HVdllxnEzTEsgIgtxTrCk= +github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/uudashr/gocognit v1.0.6 h1:2Cgi6MweCsdB6kpcVQp7EW4U23iBFQWfTXiWlyp842Y= github.com/uudashr/gocognit v1.0.6/go.mod h1:nAIUuVBnYU7pcninia3BHOvQkpQCeO76Uscky5BOwcY= github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU= github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM= github.com/warpfork/go-testmark v0.11.0 h1:J6LnV8KpceDvo7spaNU4+DauH2n1x+6RaO2rJrmpQ9U= github.com/warpfork/go-wish v0.0.0-20180510122957-5ad1f5abf436/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= -github.com/warpfork/go-wish v0.0.0-20190328234359-8b3e70f8e830/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= -github.com/warpfork/go-wish v0.0.0-20200122115046-b9ea61034e4a h1:G++j5e0OC488te356JvdhaM8YS6nMsjLAYF7JxCv07w= github.com/warpfork/go-wish v0.0.0-20200122115046-b9ea61034e4a/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= +github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0 h1:GDDkbFiaK8jsSDJfjId/PEGEShv6ugrt4kYsC5UIDaQ= +github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc/go.mod h1:r45hJU7yEoA81k6MWNhpMj/kms0n14dkzkxYHoB96UM= github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11 h1:5HZfQkwe0mIfyDmc1Em5GqlNRzcdtlv4HTNmdpt7XH0= github.com/whyrusleeping/cbor-gen v0.0.0-20200123233031-1cdf64d27158/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI= -github.com/whyrusleeping/cbor-gen v0.0.0-20210219115102-f37d292932f2 h1:bsUlNhdmbtlfdLVXAVfuvKQ01RnWAM09TVrJkI7NZs4= -github.com/whyrusleeping/cbor-gen v0.0.0-20210219115102-f37d292932f2/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= +github.com/whyrusleeping/cbor-gen v0.0.0-20230126041949-52956bd4c9aa h1:EyA027ZAkuaCLoxVX4r1TZMPy1d31fM6hbfQ4OU4I5o= +github.com/whyrusleeping/cbor-gen v0.0.0-20230126041949-52956bd4c9aa/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f h1:jQa4QT2UP9WYv2nzyawpKMOCl+Z/jW7djv2/J50lj9E= -github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f/go.mod h1:p9UJB6dDgdPgMJZs7UjUOdulKyRr9fqkS+6JKAInPy8= github.com/whyrusleeping/go-ctrlnet v0.0.0-20180313164037-f564fbbdaa95/go.mod h1:SJqKCCPXRfBFCwXjfNT/skfsceF7+MBFLI2OrvuRA7g= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc= github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= -github.com/whyrusleeping/go-logging v0.0.1/go.mod h1:lDPYj54zutzG1XYfHAhcc7oNXEburHQBn+Iqd4yS4vE= github.com/whyrusleeping/go-notifier v0.0.0-20170827234753-097c5d47330f/go.mod h1:cZNvX9cFybI01GriPRMXDtczuvUhgbcYr9iCGaNlRv8= github.com/whyrusleeping/mafmt v1.2.8/go.mod h1:faQJFPbLSxzD9xpA02ttW/tS9vZykNvXwGvqIpk20FA= github.com/whyrusleeping/mdns v0.0.0-20180901202407-ef14215e6b30/go.mod h1:j4l84WPFclQPj320J9gp0XwNKBb3U0zt5CBqjPp22G4= @@ -1556,7 +1164,6 @@ github.com/whyrusleeping/mdns v0.0.0-20190826153040-b9b60ed33aa9/go.mod h1:j4l84 github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7/go.mod h1:X2c0RVCI1eSUFI8eLcY3c0423ykwiUdxLJtkDvruhjI= github.com/whyrusleeping/timecache v0.0.0-20160911033111-cfcb2f1abfee/go.mod h1:m2aV4LZI4Aez7dP5PMyVKEHhUyEJ/RjmPEDOpDvudHg= github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE= -github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/yagipy/maintidx v1.0.0 h1:h5NvIsCz+nRDapQ0exNv4aJ0yXSI0420omVANTv3GJM= github.com/yagipy/maintidx v1.0.0/go.mod h1:0qNf/I/CCZXSMhsRsrEPDZ+DkekpKLXAJfsTACwgXLk= @@ -1571,11 +1178,7 @@ github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1 github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= gitlab.com/bosi/decorder v0.2.3 h1:gX4/RgK16ijY8V+BRQHAySfQAb354T7/xQpDB2n10P0= gitlab.com/bosi/decorder v0.2.3/go.mod h1:9K1RB5+VPNQYtXtTDAzd2OEftsZb1oV0IrJrzChSdGE= -go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA= -go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= -go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.1/go.mod h1:Ap50jQcDJrx6rB6VgeeFPtuPIf3wMRvRfrfYDO6+BmA= @@ -1583,15 +1186,11 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= -go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= -go.opentelemetry.io/otel v1.2.0 h1:YOQDvxO1FayUcT9MIhJhgMyNO1WqoduiyvQHzGN0kUQ= -go.opentelemetry.io/otel v1.2.0/go.mod h1:aT17Fk0Z1Nor9e0uisf98LrntPGMnk4frBO9+dkf69I= +go.opentelemetry.io/otel v1.14.0 h1:/79Huy8wbf5DnIPhemGB+zEPVwnN6fuQybr/SRXa6hM= +go.opentelemetry.io/otel v1.14.0/go.mod h1:o4buv+dJzx8rohcUeRmWUZhqupFvzWis188WlggnNeU= go.opentelemetry.io/otel/sdk v1.2.0 h1:wKN260u4DesJYhyjxDa7LRFkuhH7ncEVKU37LWcyNIo= -go.opentelemetry.io/otel/trace v1.2.0 h1:Ys3iqbqZhcf28hHzrm5WAquMkDHNZTUkw7KHbuNjej0= -go.opentelemetry.io/otel/trace v1.2.0/go.mod h1:N5FLswTubnxKxOJHM7XZC074qpeEdLy3CgAVsdMucK0= -go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.opentelemetry.io/otel/trace v1.14.0 h1:wp2Mmvj41tDsyAJXiWDWpfNsOiIyd38fy85pyKcFq/M= +go.opentelemetry.io/otel/trace v1.14.0/go.mod h1:8avnQLK+CG77yNLUae4ea2JDQ6iT+gozhnZjy/rw9G8= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= @@ -1600,20 +1199,13 @@ go.uber.org/dig v1.15.0 h1:vq3YWr8zRj1eFGC7Gvf907hE0eRjPTZ1d3xHadD6liE= go.uber.org/dig v1.15.0/go.mod h1:pKHs0wMynzL6brANhB2hLMro+zalv1osARTviTcqHLM= go.uber.org/fx v1.18.2 h1:bUNI6oShr+OVFQeU8cDNbnN7VFsu+SsjHzUF51V/GAU= go.uber.org/fx v1.18.2/go.mod h1:g0V1KMQ66zIRk8bLu3Ea5Jt2w/cHlOIp4wdRsgh0JaY= -go.uber.org/goleak v1.0.0/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.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA= -go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= -go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= -go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8= -go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= +go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= +go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= -go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= -go.uber.org/zap v1.14.1/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= -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.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= @@ -1622,7 +1214,6 @@ go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1 golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -1633,26 +1224,20 @@ golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190618222545-ea8f1a30c443/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200602180216-279210d13fed/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.4.0 h1:UVQgzMY87xqpKNgb+kDsll2Igd33HszWHFLmpaRMq/8= -golang.org/x/crypto v0.4.0/go.mod h1:3quD/ATkf6oY+rnes5c3ExXTbLc8mueNue5/DoinL80= +golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc= +golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1663,8 +1248,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20221205204356-47842c84f3db h1:D/cFflL63o2KSLJIwjlcIt8PR064j/xsmdEJL/YvY/o= -golang.org/x/exp v0.0.0-20221205204356-47842c84f3db/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= +golang.org/x/exp v0.0.0-20230213192124-5e25df0256eb h1:PaBZQdo+iSDyHT053FjUCgZQ/9uqVwPOcl7KSWhKn6w= +golang.org/x/exp v0.0.0-20230213192124-5e25df0256eb/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= golang.org/x/exp/typeparams v0.0.0-20220428152302-39d4317da171/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/exp/typeparams v0.0.0-20220613132600-b0d781184e0d h1:+W8Qf4iJtMGKkyAygcKohjxTk4JPsL9DpzApJ22m5Ic= golang.org/x/exp/typeparams v0.0.0-20220613132600-b0d781184e0d/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= @@ -1698,19 +1283,14 @@ golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2 golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA= golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -1718,15 +1298,11 @@ golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190611141213-3f473d35a33a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -1737,29 +1313,25 @@ golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20210423184538-5f58ad60dda6/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.4.0 h1:Q5QPcMlvfxFTAPV0+07Xz/MpK9NTXu2VDUuy0FeMfaU= -golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= +golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1789,21 +1361,16 @@ golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= golang.org/x/sync v0.1.0/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= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190302025703-b6889370fb10/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190405154228-4b34438f7a67/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1811,25 +1378,15 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190524122548-abf6ff778158/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190524152521-dbbf3f1254d4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190526052359-791d8a0f4d09/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190610200419-93c9922d18ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1845,7 +1402,6 @@ golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1861,12 +1417,9 @@ golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210317225723-c4fcb01b228e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210426080607-c94f62235c83/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1875,20 +1428,20 @@ golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211105183446-c75c47738b0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220702020025-31831981b65f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ= -golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.3.0 h1:qoo4akIqOcDME5bhc/NgxUdovd6BSS2uMsVjB56q1xI= -golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= +golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1897,8 +1450,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM= -golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1940,10 +1493,8 @@ golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200117220505-0cba7a3a9ee9/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= @@ -2002,12 +1553,11 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df h1:5Pf6pFKu98ODmgnpvkJ3kFUOQGGLIzLIkbzUHp47618= -golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y= -google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= @@ -2045,7 +1595,6 @@ google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRn google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= @@ -2081,19 +1630,14 @@ google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmE google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= -google.golang.org/grpc v1.28.1/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= @@ -2123,20 +1667,15 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.66.6 h1:LATuAqN/shcYAOkv3wl2L4rkaKqkcgTBQjOyYDvcPKI= gopkg.in/ini.v1 v1.66.6/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/src-d/go-cli.v0 v0.0.0-20181105080154-d492247bbc0d/go.mod h1:z+K8VcOYVYcSwSjGebuDL6176A1XskgbtNl64NSg+n8= gopkg.in/src-d/go-log.v1 v1.0.1/go.mod h1:GN34hKP0g305ysm2/hctJ0Y8nWP3zxXXJ8GFabTyABE= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= -gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -2179,7 +1718,5 @@ nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0 rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= -sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck= sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0= diff --git a/test/dependencies/graphsync-get/graphsync-get.go b/test/dependencies/graphsync-get/graphsync-get.go index 005d1e53c..9e59379ec 100644 --- a/test/dependencies/graphsync-get/graphsync-get.go +++ b/test/dependencies/graphsync-get/graphsync-get.go @@ -7,7 +7,11 @@ import ( "log" "os" - "github.com/ipfs/go-blockservice" + "github.com/ipfs/boxo/blockservice" + blockstore "github.com/ipfs/boxo/blockstore" + offline "github.com/ipfs/boxo/exchange/offline" + "github.com/ipfs/boxo/ipld/merkledag" + uio "github.com/ipfs/boxo/ipld/unixfs/io" "github.com/ipfs/go-cid" "github.com/ipfs/go-datastore" dssync "github.com/ipfs/go-datastore/sync" @@ -15,10 +19,6 @@ import ( gsimpl "github.com/ipfs/go-graphsync/impl" "github.com/ipfs/go-graphsync/network" "github.com/ipfs/go-graphsync/storeutil" - blockstore "github.com/ipfs/go-ipfs-blockstore" - offline "github.com/ipfs/go-ipfs-exchange-offline" - "github.com/ipfs/go-merkledag" - uio "github.com/ipfs/go-unixfs/io" "github.com/ipld/go-ipld-prime" cidlink "github.com/ipld/go-ipld-prime/linking/cid" basicnode "github.com/ipld/go-ipld-prime/node/basicnode" From e7294cbdfffc7160bd3f3b65c4b2b27a5f32470f Mon Sep 17 00:00:00 2001 From: Jorropo Date: Thu, 8 Jun 2023 03:07:19 +0200 Subject: [PATCH 0706/1212] feat: warn users who are falling behind reprovides Fixes: #9704 Fixes: #9702 Fixes: #9703 Fixes: #9419 --- cmd/ipfs/daemon.go | 3 + config/experiments.go | 2 +- config/routing.go | 2 + config/types.go | 24 ++ core/commands/stat_provide.go | 17 +- core/coreapi/coreapi.go | 2 +- core/node/groups.go | 9 +- core/node/libp2p/routing.go | 2 +- core/node/provider.go | 205 ++++++------ docs/changelogs/v0.21.md | 17 +- docs/config.md | 52 +++- docs/examples/kubo-as-a-library/go.mod | 5 +- docs/examples/kubo-as-a-library/go.sum | 10 +- docs/experimental-features.md | 57 +--- go.mod | 7 +- go.sum | 10 +- repo/fsrepo/fsrepo.go | 2 +- repo/fsrepo/migrations/fetcher.go | 2 +- routing/composer.go | 2 +- test/dependencies/go.mod | 81 +++-- test/dependencies/go.sum | 415 +++++-------------------- 21 files changed, 344 insertions(+), 582 deletions(-) diff --git a/cmd/ipfs/daemon.go b/cmd/ipfs/daemon.go index a61f1473b..5788bf3ce 100644 --- a/cmd/ipfs/daemon.go +++ b/cmd/ipfs/daemon.go @@ -425,6 +425,9 @@ func daemonFunc(req *cmds.Request, re cmds.ResponseEmitter, env cmds.Environment case routingOptionNoneKwd: ncfg.Routing = libp2p.NilRouterOption case routingOptionCustomKwd: + if cfg.Routing.AcceleratedDHTClient { + return fmt.Errorf("Routing.AcceleratedDHTClient option is set even tho Routing.Type is custom, using custom .AcceleratedDHTClient needs to be set on DHT routers individually") + } ncfg.Routing = libp2p.ConstructDelegatedRouting( cfg.Routing.Routers, cfg.Routing.Methods, diff --git a/config/experiments.go b/config/experiments.go index 072dcd0dd..f5ecf4be6 100644 --- a/config/experiments.go +++ b/config/experiments.go @@ -8,7 +8,7 @@ type Experiments struct { Libp2pStreamMounting bool P2pHttpProxy bool //nolint StrategicProviding bool - AcceleratedDHTClient bool + AcceleratedDHTClient experimentalAcceleratedDHTClient `json:",omitempty"` OptimisticProvide bool OptimisticProvideJobsPoolSize int } diff --git a/config/routing.go b/config/routing.go index 1210bb3ce..7f5e48aa2 100644 --- a/config/routing.go +++ b/config/routing.go @@ -15,6 +15,8 @@ type Routing struct { // When "custom" is set, user-provided Routing.Routers is used. Type *OptionalString `json:",omitempty"` + AcceleratedDHTClient bool + Routers Routers Methods Methods diff --git a/config/types.go b/config/types.go index 3a0d4f4b3..a781f023a 100644 --- a/config/types.go +++ b/config/types.go @@ -438,3 +438,27 @@ func (swarmLimits) UnmarshalJSON(b []byte) error { } } } + +type experimentalAcceleratedDHTClient struct{} + +var _ json.Unmarshaler = experimentalAcceleratedDHTClient{} + +func (experimentalAcceleratedDHTClient) UnmarshalJSON(b []byte) error { + d := json.NewDecoder(bytes.NewReader(b)) + for { + switch tok, err := d.Token(); err { + case io.EOF: + return nil + case nil: + switch tok { + case json.Delim('{'), json.Delim('}'): + // accept empty objects + continue + } + //nolint + return fmt.Errorf("The Experimental.AcceleratedDHTClient key has been moved to Routing.AcceleratedDHTClient in Kubo 0.21, please use this new key and remove the old one.") + default: + return err + } + } +} diff --git a/core/commands/stat_provide.go b/core/commands/stat_provide.go index f93f73cb4..6ee51e516 100644 --- a/core/commands/stat_provide.go +++ b/core/commands/stat_provide.go @@ -7,10 +7,10 @@ import ( "time" humanize "github.com/dustin/go-humanize" + "github.com/ipfs/boxo/provider" cmds "github.com/ipfs/go-ipfs-cmds" "github.com/ipfs/kubo/core/commands/cmdenv" - - "github.com/ipfs/boxo/provider/batched" + "golang.org/x/exp/constraints" ) var statProvideCmd = &cmds.Command{ @@ -34,12 +34,7 @@ This interface is not stable and may change from release to release. return ErrNotOnline } - sys, ok := nd.Provider.(*batched.BatchProvidingSystem) - if !ok { - return fmt.Errorf("can only return stats if Experimental.AcceleratedDHTClient is enabled") - } - - stats, err := sys.Stat(req.Context) + stats, err := nd.Provider.Stat() if err != nil { return err } @@ -51,7 +46,7 @@ This interface is not stable and may change from release to release. return nil }, Encoders: cmds.EncoderMap{ - cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, s *batched.BatchedProviderStats) error { + cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, s *provider.ReproviderStats) error { wtr := tabwriter.NewWriter(w, 1, 2, 1, ' ', 0) defer wtr.Flush() @@ -62,14 +57,14 @@ This interface is not stable and may change from release to release. return nil }), }, - Type: batched.BatchedProviderStats{}, + Type: provider.ReproviderStats{}, } func humanDuration(val time.Duration) string { return val.Truncate(time.Microsecond).String() } -func humanNumber(n int) string { +func humanNumber[T constraints.Float | constraints.Integer](n T) string { nf := float64(n) str := humanSI(nf, 0) fullStr := humanFull(nf, 0) diff --git a/core/coreapi/coreapi.go b/core/coreapi/coreapi.go index 6c97800a3..5a7e321a9 100644 --- a/core/coreapi/coreapi.go +++ b/core/coreapi/coreapi.go @@ -238,7 +238,7 @@ func (api *CoreAPI) WithOptions(opts ...options.ApiOption) (coreiface.CoreAPI, e return nil, fmt.Errorf("error constructing namesys: %w", err) } - subAPI.provider = provider.NewOfflineProvider() + subAPI.provider = provider.NewNoopProvider() subAPI.peerstore = nil subAPI.peerHost = nil diff --git a/core/node/groups.go b/core/node/groups.go index 548678835..a626a5cae 100644 --- a/core/node/groups.go +++ b/core/node/groups.go @@ -304,9 +304,9 @@ func Online(bcfg *BuildCfg, cfg *config.Config, userResourceOverrides rcmgr.Part LibP2P(bcfg, cfg, userResourceOverrides), OnlineProviders( cfg.Experimental.StrategicProviding, - cfg.Experimental.AcceleratedDHTClient, cfg.Reprovider.Strategy.WithDefault(config.DefaultReproviderStrategy), cfg.Reprovider.Interval.WithDefault(config.DefaultReproviderInterval), + cfg.Routing.AcceleratedDHTClient, ), ) } @@ -320,12 +320,7 @@ func Offline(cfg *config.Config) fx.Option { fx.Provide(libp2p.Routing), fx.Provide(libp2p.ContentRouting), fx.Provide(libp2p.OfflineRouting), - OfflineProviders( - cfg.Experimental.StrategicProviding, - cfg.Experimental.AcceleratedDHTClient, - cfg.Reprovider.Strategy.WithDefault(config.DefaultReproviderStrategy), - cfg.Reprovider.Interval.WithDefault(config.DefaultReproviderInterval), - ), + OfflineProviders(), ) } diff --git a/core/node/libp2p/routing.go b/core/node/libp2p/routing.go index 2e356e447..0b642ed8c 100644 --- a/core/node/libp2p/routing.go +++ b/core/node/libp2p/routing.go @@ -90,7 +90,7 @@ func BaseRouting(cfg *config.Config) interface{} { } } - if dualDHT != nil && cfg.Experimental.AcceleratedDHTClient { + if dualDHT != nil && cfg.Routing.AcceleratedDHTClient { cfg, err := in.Repo.Config() if err != nil { return out, err diff --git a/core/node/provider.go b/core/node/provider.go index 58e74bdb3..215e0adac 100644 --- a/core/node/provider.go +++ b/core/node/provider.go @@ -5,145 +5,158 @@ import ( "fmt" "time" + "github.com/ipfs/boxo/blockstore" "github.com/ipfs/boxo/fetcher" pin "github.com/ipfs/boxo/pinning/pinner" provider "github.com/ipfs/boxo/provider" - "github.com/ipfs/boxo/provider/batched" - q "github.com/ipfs/boxo/provider/queue" - "github.com/ipfs/boxo/provider/simple" - "go.uber.org/fx" - - "github.com/ipfs/kubo/core/node/helpers" "github.com/ipfs/kubo/repo" irouting "github.com/ipfs/kubo/routing" + "go.uber.org/fx" ) -// SIMPLE - -// ProviderQueue creates new datastore backed provider queue -func ProviderQueue(mctx helpers.MetricsCtx, lc fx.Lifecycle, repo repo.Repo) (*q.Queue, error) { - return q.NewQueue(helpers.LifecycleCtx(mctx, lc), "provider-v1", repo.Datastore()) -} - -// SimpleProvider creates new record provider -func SimpleProvider(mctx helpers.MetricsCtx, lc fx.Lifecycle, queue *q.Queue, rt irouting.ProvideManyRouter) provider.Provider { - return simple.NewProvider(helpers.LifecycleCtx(mctx, lc), queue, rt) -} - -// SimpleReprovider creates new reprovider -func SimpleReprovider(reproviderInterval time.Duration) interface{} { - return func(mctx helpers.MetricsCtx, lc fx.Lifecycle, rt irouting.ProvideManyRouter, keyProvider simple.KeyChanFunc) (provider.Reprovider, error) { - return simple.NewReprovider(helpers.LifecycleCtx(mctx, lc), reproviderInterval, rt, keyProvider), nil - } -} - -// SimpleProviderSys creates new provider system -func SimpleProviderSys(isOnline bool) interface{} { - return func(lc fx.Lifecycle, p provider.Provider, r provider.Reprovider) provider.System { - sys := provider.NewSystem(p, r) - - if isOnline { - lc.Append(fx.Hook{ - OnStart: func(ctx context.Context) error { - sys.Run() - return nil - }, - OnStop: func(ctx context.Context) error { - return sys.Close() - }, - }) +func ProviderSys(reprovideInterval time.Duration, acceleratedDHTClient bool) fx.Option { + const magicThroughputReportCount = 128 + return fx.Provide(func(lc fx.Lifecycle, cr irouting.ProvideManyRouter, keyProvider provider.KeyChanFunc, repo repo.Repo, bs blockstore.Blockstore) (provider.System, error) { + opts := []provider.Option{ + provider.Online(cr), + provider.ReproviderInterval(reprovideInterval), + provider.KeyProvider(keyProvider), } + if !acceleratedDHTClient { + // The estimation kinda suck if you are running with accelerated DHT client, + // given this message is just trying to push people to use the acceleratedDHTClient + // let's not report on through if it's in use + opts = append(opts, + provider.ThroughputReport(func(reprovide bool, complete bool, keysProvided uint, duration time.Duration) bool { + avgProvideSpeed := duration / time.Duration(keysProvided) + count := uint64(keysProvided) - return sys - } -} + if !reprovide || !complete { + // We don't know how many CIDs we have to provide, try to fetch it from the blockstore. + // But don't try for too long as this might be very expensive if you have a huge datastore. + ctx, cancel := context.WithTimeout(context.Background(), time.Minute*5) + defer cancel() -// BatchedProviderSys creates new provider system -func BatchedProviderSys(isOnline bool, reprovideInterval time.Duration) interface{} { - return func(lc fx.Lifecycle, cr irouting.ProvideManyRouter, q *q.Queue, keyProvider simple.KeyChanFunc, repo repo.Repo) (provider.System, error) { - sys, err := batched.New(cr, q, - batched.ReproviderInterval(reprovideInterval), - batched.Datastore(repo.Datastore()), - batched.KeyProvider(keyProvider)) + // FIXME: I want a running counter of blocks so size of blockstore can be an O(1) lookup. + ch, err := bs.AllKeysChan(ctx) + if err != nil { + logger.Errorf("fetching AllKeysChain in provider ThroughputReport: %v", err) + return false + } + count = 0 + countLoop: + for { + select { + case _, ok := <-ch: + if !ok { + break countLoop + } + count++ + case <-ctx.Done(): + // really big blockstore mode + + // how many blocks would be in a 10TiB blockstore with 128KiB blocks. + const probableBigBlockstore = (10 * 1024 * 1024 * 1024 * 1024) / (128 * 1024) + // How long per block that lasts us. + expectedProvideSpeed := reprovideInterval / probableBigBlockstore + if avgProvideSpeed > expectedProvideSpeed { + logger.Errorf(` +🔔🔔🔔 YOU MAY BE FALLING BEHIND DHT REPROVIDES! 🔔🔔🔔 + +⚠️ Your system might be struggling to keep up with DHT reprovides! +This means your content could partially or completely inaccessible on the network. +We observed that you recently provided %d keys at an average rate of %v per key. + +🕑 An attempt to estimate your blockstore size timed out after 5 minutes, +implying your blockstore might be exceedingly large. Assuming a considerable +size of 10TiB, it would take %v to provide the complete set. + +⏰ The total provide time needs to stay under your reprovide interval (%v) to prevent falling behind! + +💡 Consider enabling the Accelerated DHT to enhance your system performance. See: +https://github.com/ipfs/kubo/blob/master/docs/config.md#routingaccelerateddhtclient`, + keysProvided, avgProvideSpeed, avgProvideSpeed*probableBigBlockstore, reprovideInterval) + return false + } + } + } + } + + // How long per block that lasts us. + expectedProvideSpeed := reprovideInterval / time.Duration(count) + if avgProvideSpeed > expectedProvideSpeed { + // FIXME(@Jorropo): add link to the accelerated DHT client docs once this isn't experimental anymore. + logger.Errorf(` +🔔🔔🔔 YOU ARE FALLING BEHIND DHT REPROVIDES! 🔔🔔🔔 + +⚠️ Your system is struggling to keep up with DHT reprovides! +This means your content could partially or completely inaccessible on the network. +We observed that you recently provided %d keys at an average rate of %v per key. + +💾 Your total CID count is ~%d which would total at %v reprovide process. + +⏰ The total provide time needs to stay under your reprovide interval (%v) to prevent falling behind! + +💡 Consider enabling the Accelerated DHT to enhance your reprovide throughput. See: +https://github.com/ipfs/kubo/blob/master/docs/config.md#routingaccelerateddhtclient`, + keysProvided, avgProvideSpeed, count, avgProvideSpeed*time.Duration(count), reprovideInterval) + } + return false + }, magicThroughputReportCount)) + } + sys, err := provider.New(repo.Datastore(), opts...) if err != nil { return nil, err } - if isOnline { - lc.Append(fx.Hook{ - OnStart: func(ctx context.Context) error { - sys.Run() - return nil - }, - OnStop: func(ctx context.Context) error { - return sys.Close() - }, - }) - } + lc.Append(fx.Hook{ + OnStop: func(ctx context.Context) error { + return sys.Close() + }, + }) return sys, nil - } + }) } // ONLINE/OFFLINE // OnlineProviders groups units managing provider routing records online -func OnlineProviders(useStrategicProviding bool, useBatchedProviding bool, reprovideStrategy string, reprovideInterval time.Duration) fx.Option { +func OnlineProviders(useStrategicProviding bool, reprovideStrategy string, reprovideInterval time.Duration, acceleratedDHTClient bool) fx.Option { if useStrategicProviding { - return fx.Provide(provider.NewOfflineProvider) + return OfflineProviders() } - return fx.Options( - SimpleProviders(reprovideStrategy, reprovideInterval), - maybeProvide(SimpleProviderSys(true), !useBatchedProviding), - maybeProvide(BatchedProviderSys(true, reprovideInterval), useBatchedProviding), - ) -} - -// OfflineProviders groups units managing provider routing records offline -func OfflineProviders(useStrategicProviding bool, useBatchedProviding bool, reprovideStrategy string, reprovideInterval time.Duration) fx.Option { - if useStrategicProviding { - return fx.Provide(provider.NewOfflineProvider) - } - - return fx.Options( - SimpleProviders(reprovideStrategy, reprovideInterval), - maybeProvide(SimpleProviderSys(false), true), - //maybeProvide(BatchedProviderSys(false, reprovideInterval), useBatchedProviding), - ) -} - -// SimpleProviders creates the simple provider/reprovider dependencies -func SimpleProviders(reprovideStrategy string, reproviderInterval time.Duration) fx.Option { var keyProvider fx.Option switch reprovideStrategy { - case "all": - fallthrough - case "": - keyProvider = fx.Provide(simple.NewBlockstoreProvider) + case "all", "": + keyProvider = fx.Provide(provider.NewBlockstoreProvider) case "roots": keyProvider = fx.Provide(pinnedProviderStrategy(true)) case "pinned": keyProvider = fx.Provide(pinnedProviderStrategy(false)) default: - return fx.Error(fmt.Errorf("unknown reprovider strategy '%s'", reprovideStrategy)) + return fx.Error(fmt.Errorf("unknown reprovider strategy %q", reprovideStrategy)) } return fx.Options( - fx.Provide(ProviderQueue), - fx.Provide(SimpleProvider), keyProvider, - fx.Provide(SimpleReprovider(reproviderInterval)), + ProviderSys(reprovideInterval, acceleratedDHTClient), ) } +// OfflineProviders groups units managing provider routing records offline +func OfflineProviders() fx.Option { + return fx.Provide(provider.NewNoopProvider) +} + func pinnedProviderStrategy(onlyRoots bool) interface{} { type input struct { fx.In Pinner pin.Pinner IPLDFetcher fetcher.Factory `name:"ipldFetcher"` } - return func(in input) simple.KeyChanFunc { - return simple.NewPinnedProvider(onlyRoots, in.Pinner, in.IPLDFetcher) + return func(in input) provider.KeyChanFunc { + return provider.NewPinnedProvider(onlyRoots, in.Pinner, in.IPLDFetcher) } } diff --git a/docs/changelogs/v0.21.md b/docs/changelogs/v0.21.md index e000208a4..55350caee 100644 --- a/docs/changelogs/v0.21.md +++ b/docs/changelogs/v0.21.md @@ -12,6 +12,7 @@ - [Gateway: DAG-CBOR/-JSON previews and improved error pages](#gateway-dag-cbor-json-previews-and-improved-error-pages) - [Gateway: subdomain redirects are now `text/html`](#gateway-subdomain-redirects-are-now-texthtml) - [`ipfs dag stat` deduping statistics](#ipfs-dag-stat-deduping-statistics) + - [Accelerated DHT Client is no longer experimental](#--empty-repo-is-now-the-default) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -76,7 +77,7 @@ for Kubo `v0.21`. In this release, we improved the HTML templates of our HTTP gateway: -1. You can now preview the contents of a DAG-CBOR and DAG-JSON document from your browser, as well as follow any IPLD Links ([CBOR Tag 42](https://github.com/ipld/cid-cbor/)) contained within them. +1. You can now preview the contents of a DAG-CBOR and DAG-JSON document from your browser, as well as follow any IPLD Links ([CBOR Tag 42](https://github.com/ipld/cid-cbor/)) contained within them. 2. The HTML directory listings now contain [updated, higher-definition icons](https://user-images.githubusercontent.com/5447088/241224419-5385793a-d3bb-40aa-8cb0-0382b5bc56a0.png). 3. On gateway error, instead of a plain text error message, web browsers will now get a friendly HTML response with more details regarding the problem. @@ -124,6 +125,20 @@ Ratio: 1.615755 `ipfs --enc=json dag stat`'s keys are a non breaking change, new keys have been added but old keys with previous sementics are still here. +#### Accelerated DHT Client is no longer experimental + +The [accelerated DHT client](docs/config.md#routingaccelerateddhtclient) is now +the main recommended solution for users who are hosting lots of data. +By trading some upfront DHT caching and increased memory usage, +one gets provider throughput improvements up to 6 millions times bigger dataset. +See [the docs](docs/config.md#routingaccelerateddhtclient) for more info. + +The `Experimental.AcceleratedDHTClient` flag moved to `[Routing.AcceleratedDHTClient](docs/config.md#routingaccelerateddhtclient)`. +A config migration has been added to handle this automatically. + +A new tracker estimates the providing speed and warns users if they +should be using AcceleratedDHTClient because they are falling behind. + ### 📝 Changelog ### 👨‍👩‍👧‍👦 Contributors diff --git a/docs/config.md b/docs/config.md index eeff6ce58..7b304476e 100644 --- a/docs/config.md +++ b/docs/config.md @@ -110,6 +110,7 @@ config file at runtime. - [`Reprovider.Strategy`](#reproviderstrategy) - [`Routing`](#routing) - [`Routing.Type`](#routingtype) + - [`Routing.AcceleratedDHTClient`](#routingaccelerateddhtclient) - [`Routing.Routers`](#routingrouters) - [`Routing.Routers: Type`](#routingrouters-type) - [`Routing.Routers: Parameters`](#routingrouters-parameters) @@ -1348,7 +1349,7 @@ Type: `array[peering]` ### `Reprovider.Interval` Sets the time between rounds of reproviding local content to the routing -system. +system. - If unset, it uses the implicit safe default. - If set to the value `"0"` it will disable content reproviding. @@ -1423,6 +1424,53 @@ Default: `auto` (DHT + IPNI) Type: `optionalString` (`null`/missing means the default) + +### `Routing.AcceleratedDHTClient` + +This alternative DHT client with a Full-Routing-Table strategy will +do a complete scan of the DHT every hour and record all nodes found. +Then when a lookup is tried instead of having to go through multiple Kad hops it +is able to find the 20 final nodes by looking up the in-memory recorded network table. + +This means sustained higher memory to store the routing table +and extra CPU and network bandwidth for each network scan. +However the latency of individual read/write operations should be ~10x faster +and the provide throughput up to 6 million times faster on larger datasets! + +This is not compatible with `Routing.Type` `custom`. If you are using composable routers +you can configure this individualy on each router. + +When it is enabled: +- Client DHT operations (reads and writes) should complete much faster +- The provider will now use a keyspace sweeping mode allowing to keep alive + CID sets that are multiple orders of magnitude larger. + - The standard Bucket-Routing-Table DHT will still run for the DHT server (if + the DHT server is enabled). This means the classical routing table will + still be used to answer other nodes. + This is critical to maintain to not harm the network. +- The operations `ipfs stats dht` will default to showing information about the accelerated DHT client + +**Caveats:** +1. Running the accelerated client likely will result in more resource consumption (connections, RAM, CPU, bandwidth) + - Users that are limited in the number of parallel connections their machines/networks can perform will likely suffer + - The resource usage is not smooth as the client crawls the network in rounds and reproviding is similarly done in rounds + - Users who previously had a lot of content but were unable to advertise it on the network will see an increase in + egress bandwidth as their nodes start to advertise all of their CIDs into the network. If you have lots of data + entering your node that you don't want to advertise, then consider using [Reprovider Strategies](#reproviderstrategy) + to reduce the number of CIDs that you are reproviding. Similarly, if you are running a node that deals mostly with + short-lived temporary data (e.g. you use a separate node for ingesting data then for storing and serving it) then + you may benefit from using [Strategic Providing](experimental-features.md#strategic-providing) to prevent advertising + of data that you ultimately will not have. +2. Currently, the DHT is not usable for queries for the first 5-10 minutes of operation as the routing table is being +prepared. This means operations like searching the DHT for particular peers or content will not work initially. + - You can see if the DHT has been initially populated by running `ipfs stats dht` +3. Currently, the accelerated DHT client is not compatible with LAN-based DHTs and will not perform operations against +them + +Default: `false` + +Type: `bool` (missing means `false`) + ### `Routing.Routers` **EXPERIMENTAL: `Routing.Routers` configuration may change in future release** @@ -1465,7 +1513,7 @@ HTTP: DHT: - `"Mode"`: Mode used by the DHT. Possible values: "server", "client", "auto" - - `"AcceleratedDHTClient"`: Set to `true` if you want to use the experimentalDHT. + - `"AcceleratedDHTClient"`: Set to `true` if you want to use the acceleratedDHT. - `"PublicIPNetwork"`: Set to `true` to create a `WAN` DHT. Set to `false` to create a `LAN` DHT. Parallel: diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 538e5ea8d..8edf08a2f 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.18 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.8.2-0.20230608072023-5e3d0e035282 + github.com/ipfs/boxo v0.8.2-0.20230608080412-e44e658cb393 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.27.3 github.com/multiformats/go-multiaddr v0.9.0 @@ -21,7 +21,6 @@ require ( github.com/benbjohnson/clock v1.3.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver/v4 v4.0.0 // indirect - github.com/cenkalti/backoff v2.2.1+incompatible // indirect github.com/cenkalti/backoff/v4 v4.2.0 // indirect github.com/ceramicnetwork/go-dag-jose v0.1.0 // indirect github.com/cespare/xxhash v1.1.0 // indirect @@ -108,7 +107,7 @@ require ( github.com/libp2p/go-libp2p-pubsub v0.9.3 // indirect github.com/libp2p/go-libp2p-pubsub-router v0.6.0 // indirect github.com/libp2p/go-libp2p-record v0.2.0 // indirect - github.com/libp2p/go-libp2p-routing-helpers v0.6.2 // indirect + github.com/libp2p/go-libp2p-routing-helpers v0.7.0 // indirect github.com/libp2p/go-libp2p-xor v0.1.0 // indirect github.com/libp2p/go-mplex v0.7.0 // indirect github.com/libp2p/go-msgio v0.3.0 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index dd3394438..727546d53 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -74,8 +74,6 @@ github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= -github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= -github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/cenkalti/backoff/v4 v4.2.0 h1:HN5dHm3WBOgndBH6E8V0q2jIYIR3s9yglV8k/+MN3u4= github.com/cenkalti/backoff/v4 v4.2.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -321,8 +319,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.8.2-0.20230608072023-5e3d0e035282 h1:86eDthzBwFRcIgXk/r0dEc3CgZzqmcqpgoU8GDKoYHQ= -github.com/ipfs/boxo v0.8.2-0.20230608072023-5e3d0e035282/go.mod h1:T7UvYGLnT4E9IjFbAnbisVfjUGQqMnbWCVT0kduwVck= +github.com/ipfs/boxo v0.8.2-0.20230608080412-e44e658cb393 h1:o3l1Rq7NwXT//tOgd0k+JOYTQgvg+WhgKoLy8tJfLxk= +github.com/ipfs/boxo v0.8.2-0.20230608080412-e44e658cb393/go.mod h1:ic5+bhD5T+A9n0HMkXYHiTzpjjaAZaPeKRQ9dWethTs= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= @@ -504,8 +502,8 @@ github.com/libp2p/go-libp2p-pubsub-router v0.6.0 h1:D30iKdlqDt5ZmLEYhHELCMRj8b4s github.com/libp2p/go-libp2p-pubsub-router v0.6.0/go.mod h1:FY/q0/RBTKsLA7l4vqC2cbRbOvyDotg8PJQ7j8FDudE= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= github.com/libp2p/go-libp2p-record v0.2.0/go.mod h1:I+3zMkvvg5m2OcSdoL0KPljyJyvNDFGKX7QdlpYUcwk= -github.com/libp2p/go-libp2p-routing-helpers v0.6.2 h1:u6SWfX+3LoqqTAFxWVl79RkcIDE3Zsay5d+JohlEBaE= -github.com/libp2p/go-libp2p-routing-helpers v0.6.2/go.mod h1:R289GUxUMzRXIbWGSuUUTPrlVJZ3Y/pPz495+qgXJX8= +github.com/libp2p/go-libp2p-routing-helpers v0.7.0 h1:sirOYVD0wGWjkDwHZvinunIpaqPLBXkcnXApVHwZFGA= +github.com/libp2p/go-libp2p-routing-helpers v0.7.0/go.mod h1:R289GUxUMzRXIbWGSuUUTPrlVJZ3Y/pPz495+qgXJX8= github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA= github.com/libp2p/go-libp2p-xor v0.1.0 h1:hhQwT4uGrBcuAkUGXADuPltalOdpf9aag9kaYNT2tLA= github.com/libp2p/go-libp2p-xor v0.1.0/go.mod h1:LSTM5yRnjGZbWNTA/hRwq2gGFrvRIbQJscoIL/u6InY= diff --git a/docs/experimental-features.md b/docs/experimental-features.md index 83a5fdf7b..07f7f30f5 100644 --- a/docs/experimental-features.md +++ b/docs/experimental-features.md @@ -513,7 +513,7 @@ ipfs config --json Experimental.StrategicProviding true - [ ] provide roots - [ ] provide all - [ ] provide strategic - + ## GraphSync ### State @@ -546,59 +546,6 @@ Stable, enabled by default [Noise](https://github.com/libp2p/specs/tree/master/noise) libp2p transport based on the [Noise Protocol Framework](https://noiseprotocol.org/noise.html). While TLS remains the default transport in Kubo, Noise is easier to implement and is thus the "interop" transport between IPFS and libp2p implementations. -## Accelerated DHT Client - -### In Version - -0.9.0 - -### State - -Experimental, default-disabled. - -Utilizes an alternative DHT client that searches for and maintains more information about the network -in exchange for being more performant. - -When it is enabled: -- DHT operations should complete much faster than with it disabled -- A batching reprovider system will be enabled which takes advantage of some properties of the experimental client to - very efficiently put provider records into the network -- The standard DHT client (and server if enabled) are run alongside the alternative client -- The operations `ipfs stats dht` and `ipfs stats provide` will have different outputs - - `ipfs stats provide` only works when the accelerated DHT client is enabled and shows various statistics regarding - the provider/reprovider system - - `ipfs stats dht` will default to showing information about the new client - -**Caveats:** -1. Running the experimental client likely will result in more resource consumption (connections, RAM, CPU, bandwidth) - - Users that are limited in the number of parallel connections their machines/networks can perform will likely suffer - - Currently, the resource usage is not smooth as the client crawls the network in rounds and reproviding is similarly - done in rounds - - Users who previously had a lot of content but were unable to advertise it on the network will see an increase in - egress bandwidth as their nodes start to advertise all of their CIDs into the network. If you have lots of data - entering your node that you don't want to advertise consider using [Reprovider Strategies](config.md#reproviderstrategy) - to reduce the number of CIDs that you are reproviding. Similarly, if you are running a node that deals mostly with - short-lived temporary data (e.g. you use a separate node for ingesting data then for storing and serving it) then - you may benefit from using [Strategic Providing](#strategic-providing) to prevent advertising of data that you - ultimately will not have. -2. Currently, the DHT is not usable for queries for the first 5-10 minutes of operation as the routing table is being -prepared. This means operations like searching the DHT for particular peers or content will not work - - You can see if the DHT has been initially populated by running `ipfs stats dht` -3. Currently, the accelerated DHT client is not compatible with LAN-based DHTs and will not perform operations against -them - -### How to enable - -``` -ipfs config --json Experimental.AcceleratedDHTClient true -``` - -### Road to being a real feature - -- [ ] Needs more people to use and report on how well it works -- [ ] Should be usable for queries (even if slower/less efficient) shortly after startup -- [ ] Should be usable with non-WAN DHTs - ## Optimistic Provide ### In Version @@ -640,7 +587,7 @@ than the classic client. size estimation available the client will transparently fall back to the classic approach. 2. The chosen peers to store the provider records might not be the actual closest ones. Measurements showed that this is not a problem. -3. The optimistic provide process returns already after 15 out of the 20 provider records were stored with peers. The +3. The optimistic provide process returns already after 15 out of the 20 provider records were stored with peers. The reasoning here is that one out of the remaining 5 peers are very likely to time out and delay the whole process. To limit the number of in-flight async requests there is the second `OptimisticProvideJobsPoolSize` setting. Currently, this is set to 60. This means that at most 60 parallel background requests are allowed to be in-flight. If this diff --git a/go.mod b/go.mod index 2363cee56..4613c2ebf 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/gogo/protobuf v1.3.2 github.com/google/uuid v1.3.0 github.com/hashicorp/go-multierror v1.1.1 - github.com/ipfs/boxo v0.8.2-0.20230608072023-5e3d0e035282 + github.com/ipfs/boxo v0.8.2-0.20230608080412-e44e658cb393 github.com/ipfs/go-block-format v0.1.2 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 @@ -52,7 +52,7 @@ require ( github.com/libp2p/go-libp2p-pubsub v0.9.3 github.com/libp2p/go-libp2p-pubsub-router v0.6.0 github.com/libp2p/go-libp2p-record v0.2.0 - github.com/libp2p/go-libp2p-routing-helpers v0.6.2 + github.com/libp2p/go-libp2p-routing-helpers v0.7.0 github.com/libp2p/go-libp2p-testing v0.12.0 github.com/libp2p/go-socket-activation v0.1.0 github.com/mitchellh/go-homedir v1.1.0 @@ -82,6 +82,7 @@ require ( go.uber.org/multierr v1.11.0 go.uber.org/zap v1.24.0 golang.org/x/crypto v0.9.0 + golang.org/x/exp v0.0.0-20230321023759-10a507213a29 golang.org/x/mod v0.10.0 golang.org/x/sync v0.1.0 golang.org/x/sys v0.8.0 @@ -93,7 +94,6 @@ require ( github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/cenkalti/backoff v2.2.1+incompatible // indirect github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/containerd/cgroups v1.1.0 // indirect @@ -215,7 +215,6 @@ require ( go.opentelemetry.io/proto/otlp v0.19.0 // indirect go.uber.org/atomic v1.10.0 // indirect go4.org v0.0.0-20230225012048-214862532bf5 // indirect - golang.org/x/exp v0.0.0-20230321023759-10a507213a29 // indirect golang.org/x/net v0.10.0 // indirect golang.org/x/oauth2 v0.5.0 // indirect golang.org/x/term v0.8.0 // indirect diff --git a/go.sum b/go.sum index 25db08ebf..3c503b9c0 100644 --- a/go.sum +++ b/go.sum @@ -84,8 +84,6 @@ github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= -github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= -github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/cenkalti/backoff/v4 v4.2.0 h1:HN5dHm3WBOgndBH6E8V0q2jIYIR3s9yglV8k/+MN3u4= github.com/cenkalti/backoff/v4 v4.2.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -356,8 +354,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.8.2-0.20230608072023-5e3d0e035282 h1:86eDthzBwFRcIgXk/r0dEc3CgZzqmcqpgoU8GDKoYHQ= -github.com/ipfs/boxo v0.8.2-0.20230608072023-5e3d0e035282/go.mod h1:T7UvYGLnT4E9IjFbAnbisVfjUGQqMnbWCVT0kduwVck= +github.com/ipfs/boxo v0.8.2-0.20230608080412-e44e658cb393 h1:o3l1Rq7NwXT//tOgd0k+JOYTQgvg+WhgKoLy8tJfLxk= +github.com/ipfs/boxo v0.8.2-0.20230608080412-e44e658cb393/go.mod h1:ic5+bhD5T+A9n0HMkXYHiTzpjjaAZaPeKRQ9dWethTs= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= @@ -559,8 +557,8 @@ github.com/libp2p/go-libp2p-pubsub-router v0.6.0 h1:D30iKdlqDt5ZmLEYhHELCMRj8b4s github.com/libp2p/go-libp2p-pubsub-router v0.6.0/go.mod h1:FY/q0/RBTKsLA7l4vqC2cbRbOvyDotg8PJQ7j8FDudE= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= github.com/libp2p/go-libp2p-record v0.2.0/go.mod h1:I+3zMkvvg5m2OcSdoL0KPljyJyvNDFGKX7QdlpYUcwk= -github.com/libp2p/go-libp2p-routing-helpers v0.6.2 h1:u6SWfX+3LoqqTAFxWVl79RkcIDE3Zsay5d+JohlEBaE= -github.com/libp2p/go-libp2p-routing-helpers v0.6.2/go.mod h1:R289GUxUMzRXIbWGSuUUTPrlVJZ3Y/pPz495+qgXJX8= +github.com/libp2p/go-libp2p-routing-helpers v0.7.0 h1:sirOYVD0wGWjkDwHZvinunIpaqPLBXkcnXApVHwZFGA= +github.com/libp2p/go-libp2p-routing-helpers v0.7.0/go.mod h1:R289GUxUMzRXIbWGSuUUTPrlVJZ3Y/pPz495+qgXJX8= github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA= github.com/libp2p/go-libp2p-testing v0.12.0/go.mod h1:KcGDRXyN7sQCllucn1cOOS+Dmm7ujhfEyXQL5lvkcPg= github.com/libp2p/go-libp2p-xor v0.1.0 h1:hhQwT4uGrBcuAkUGXADuPltalOdpf9aag9kaYNT2tLA= diff --git a/repo/fsrepo/fsrepo.go b/repo/fsrepo/fsrepo.go index cb8de08c1..3c4a709c1 100644 --- a/repo/fsrepo/fsrepo.go +++ b/repo/fsrepo/fsrepo.go @@ -37,7 +37,7 @@ const LockFile = "repo.lock" var log = logging.Logger("fsrepo") // RepoVersion is the version number that we are currently expecting to see -var RepoVersion = 13 +var RepoVersion = 14 var migrationInstructions = `See https://github.com/ipfs/fs-repo-migrations/blob/master/run.md Sorry for the inconvenience. In the future, these will run automatically.` diff --git a/repo/fsrepo/migrations/fetcher.go b/repo/fsrepo/migrations/fetcher.go index c174b5e77..1dc4d0345 100644 --- a/repo/fsrepo/migrations/fetcher.go +++ b/repo/fsrepo/migrations/fetcher.go @@ -11,7 +11,7 @@ import ( const ( // Current distribution to fetch migrations from - CurrentIpfsDist = "/ipfs/Qmf4yftD4LuMo8JMNPqqw3BtUwYd2VkXMiAThuPE6usrbQ" // fs-repo-12-to-13 v1.0.0 + CurrentIpfsDist = "/ipfs/QmYerugGRCZWA8yQMKDsd9daEVXUR3C5nuw3VXuX1mggHa" // fs-repo-13-to-14 v1.0.0 // Latest distribution path. Default for fetchers. LatestIpfsDist = "/ipns/dist.ipfs.tech" diff --git a/routing/composer.go b/routing/composer.go index f54d954bd..24af9b356 100644 --- a/routing/composer.go +++ b/routing/composer.go @@ -51,7 +51,7 @@ func (c *Composer) ProvideMany(ctx context.Context, keys []multihash.Multihash) func (c *Composer) Ready() bool { log.Debug("composer: calling ready") - pmr, ok := c.ProvideRouter.(routinghelpers.ProvideManyRouter) + pmr, ok := c.ProvideRouter.(routinghelpers.ReadyAbleRouter) if !ok { return true } diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 4c805bba7..4807ae28c 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -7,7 +7,7 @@ replace github.com/ipfs/kubo => ../../ require ( github.com/Kubuxu/gocovmerge v0.0.0-20161216165753-7ecaa51963cd github.com/golangci/golangci-lint v1.49.0 - github.com/ipfs/boxo v0.8.0 + github.com/ipfs/boxo v0.8.2-0.20230608080412-e44e658cb393 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 github.com/ipfs/go-datastore v0.6.0 @@ -15,12 +15,12 @@ require ( github.com/ipfs/go-log v1.0.5 github.com/ipfs/hang-fds v0.1.0 github.com/ipfs/iptb v1.4.0 - github.com/ipfs/iptb-plugins v0.3.0 + github.com/ipfs/iptb-plugins v0.5.0 github.com/ipld/go-ipld-prime v0.20.0 github.com/jbenet/go-random v0.0.0-20190219211222-123a90aedc0c github.com/jbenet/go-random-files v0.0.0-20190219210431-31b3f20ebded - github.com/libp2p/go-libp2p v0.26.4 - github.com/multiformats/go-multiaddr v0.8.0 + github.com/libp2p/go-libp2p v0.27.3 + github.com/multiformats/go-multiaddr v0.9.0 github.com/multiformats/go-multihash v0.2.1 gotest.tools/gotestsum v0.4.2 ) @@ -34,7 +34,7 @@ require ( github.com/GaijinEntertainment/go-exhaustruct/v2 v2.3.0 // indirect github.com/Masterminds/semver v1.5.0 // indirect github.com/OpenPeeDeeP/depguard v1.1.0 // indirect - github.com/alecthomas/units v0.0.0-20210927113745-59d0afb8317a // indirect + github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect github.com/alexkohler/prealloc v1.0.0 // indirect github.com/alingse/asasalint v0.0.11 // indirect github.com/ashanbrown/forbidigo v1.3.0 // indirect @@ -46,12 +46,11 @@ require ( github.com/bombsimon/wsl/v3 v3.3.0 // indirect github.com/breml/bidichk v0.2.3 // indirect github.com/breml/errchkjson v0.3.0 // indirect - github.com/btcsuite/btcd v0.20.1-beta // indirect github.com/butuzov/ireturn v0.1.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/charithe/durationcheck v0.0.9 // indirect github.com/chavacava/garif v0.0.0-20220630083739-93517212f375 // indirect - github.com/containerd/cgroups v1.0.4 // indirect + github.com/containerd/cgroups v1.1.0 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/curioswitch/go-reassign v0.1.2 // indirect @@ -61,7 +60,7 @@ require ( github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect github.com/denis-tingaikin/go-header v0.4.3 // indirect github.com/docker/go-units v0.5.0 // indirect - github.com/dustin/go-humanize v1.0.0 // indirect + github.com/dustin/go-humanize v1.0.1 // indirect github.com/elastic/gosigar v0.14.2 // indirect github.com/esimonov/ifshort v1.0.4 // indirect github.com/ettle/strcase v0.1.1 // indirect @@ -76,7 +75,7 @@ require ( github.com/go-critic/go-critic v0.6.4 // indirect github.com/go-logr/logr v1.2.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect + github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/go-toolsmith/astcast v1.0.0 // indirect github.com/go-toolsmith/astcopy v1.0.1 // indirect github.com/go-toolsmith/astequal v1.0.2 // indirect @@ -90,7 +89,7 @@ require ( github.com/gofrs/flock v0.8.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/mock v1.6.0 // indirect - github.com/golang/protobuf v1.5.2 // indirect + github.com/golang/protobuf v1.5.3 // indirect github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2 // indirect github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a // indirect github.com/golangci/go-misc v0.0.0-20220329215616-d24fe342adfe // indirect @@ -102,10 +101,9 @@ require ( github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4 // indirect github.com/google/go-cmp v0.5.9 // indirect github.com/google/gopacket v1.1.19 // indirect - github.com/google/pprof v0.0.0-20221203041831-ce31453925ec // indirect + github.com/google/pprof v0.0.0-20230405160723-4a4c7d95572b // indirect github.com/google/uuid v1.3.0 // indirect github.com/gordonklaus/ineffassign v0.0.0-20210914165742-4cc7213b9bc8 // indirect - github.com/gorilla/websocket v1.5.0 // indirect github.com/gostaticanalysis/analysisutil v0.7.1 // indirect github.com/gostaticanalysis/comment v1.4.2 // indirect github.com/gostaticanalysis/forcetypeassert v0.1.0 // indirect @@ -118,24 +116,23 @@ require ( github.com/hashicorp/golang-lru v0.5.4 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/hexops/gotextdiff v1.0.3 // indirect - github.com/huin/goupnp v1.0.3 // indirect + github.com/huin/goupnp v1.1.0 // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/ipfs/bbloom v0.0.4 // indirect github.com/ipfs/go-bitfield v1.1.0 // indirect github.com/ipfs/go-block-format v0.1.2 // indirect github.com/ipfs/go-ipfs-blockstore v1.3.0 // indirect - github.com/ipfs/go-ipfs-config v0.5.3 // indirect github.com/ipfs/go-ipfs-ds-help v1.1.0 // indirect github.com/ipfs/go-ipfs-files v0.2.0 // indirect github.com/ipfs/go-ipfs-pq v0.0.3 // indirect github.com/ipfs/go-ipfs-util v0.0.2 // indirect - github.com/ipfs/go-ipld-cbor v0.0.6 // indirect - github.com/ipfs/go-ipld-format v0.4.0 // indirect - github.com/ipfs/go-ipld-legacy v0.1.1 // indirect + github.com/ipfs/go-ipld-format v0.5.0 // indirect + github.com/ipfs/go-ipld-legacy v0.2.1 // indirect github.com/ipfs/go-log/v2 v2.5.1 // indirect github.com/ipfs/go-metrics-interface v0.0.1 // indirect github.com/ipfs/go-peertaskqueue v0.8.1 // indirect github.com/ipfs/go-unixfsnode v1.6.0 // indirect + github.com/ipfs/kubo v0.16.0 // indirect github.com/ipld/go-codec-dagpb v1.6.0 // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect @@ -147,9 +144,9 @@ require ( github.com/julz/importas v0.1.0 // indirect github.com/kisielk/errcheck v1.6.2 // indirect github.com/kisielk/gotool v1.0.0 // indirect - github.com/klauspost/compress v1.15.12 // indirect - github.com/klauspost/cpuid/v2 v2.2.3 // indirect - github.com/koron/go-ssdp v0.0.3 // indirect + github.com/klauspost/compress v1.16.4 // indirect + github.com/klauspost/cpuid/v2 v2.2.4 // indirect + github.com/koron/go-ssdp v0.0.4 // indirect github.com/kulti/thelper v0.6.3 // indirect github.com/kunwardeep/paralleltest v1.0.6 // indirect github.com/kyoh86/exportloopref v0.1.8 // indirect @@ -160,11 +157,9 @@ require ( github.com/libp2p/go-cidranger v1.1.0 // indirect github.com/libp2p/go-flow-metrics v0.1.0 // indirect github.com/libp2p/go-libp2p-asn-util v0.3.0 // indirect - github.com/libp2p/go-libp2p-core v0.5.2 // indirect github.com/libp2p/go-msgio v0.3.0 // indirect github.com/libp2p/go-nat v0.1.0 // indirect github.com/libp2p/go-netroute v0.2.1 // indirect - github.com/libp2p/go-openssl v0.1.0 // indirect github.com/libp2p/go-reuseport v0.2.0 // indirect github.com/libp2p/go-yamux/v4 v4.0.0 // indirect github.com/lufeee/execinquery v1.2.1 // indirect @@ -174,12 +169,11 @@ require ( github.com/matoous/godox v0.0.0-20210227103229-6504466cf951 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.18 // indirect - github.com/mattn/go-pointer v0.0.1 // indirect github.com/mattn/go-runewidth v0.0.9 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/mbilski/exhaustivestruct v1.2.0 // indirect github.com/mgechev/revive v1.2.3 // indirect - github.com/miekg/dns v1.1.50 // indirect + github.com/miekg/dns v1.1.53 // indirect github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect github.com/minio/sha256-simd v1.0.0 // indirect @@ -191,7 +185,7 @@ require ( github.com/multiformats/go-base36 v0.2.0 // indirect github.com/multiformats/go-multiaddr-dns v0.3.1 // indirect github.com/multiformats/go-multiaddr-fmt v0.1.0 // indirect - github.com/multiformats/go-multibase v0.1.1 // indirect + github.com/multiformats/go-multibase v0.2.0 // indirect github.com/multiformats/go-multicodec v0.8.1 // indirect github.com/multiformats/go-multistream v0.4.1 // indirect github.com/multiformats/go-varint v0.0.7 // indirect @@ -200,7 +194,7 @@ require ( github.com/nishanths/exhaustive v0.8.1 // indirect github.com/nishanths/predeclared v0.2.2 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect - github.com/onsi/ginkgo/v2 v2.5.1 // indirect + github.com/onsi/ginkgo/v2 v2.9.2 // indirect github.com/opencontainers/runtime-spec v1.0.2 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect @@ -213,15 +207,15 @@ require ( github.com/polyfloyd/go-errorlint v1.0.2 // indirect github.com/prometheus/client_golang v1.14.0 // indirect github.com/prometheus/client_model v0.3.0 // indirect - github.com/prometheus/common v0.37.0 // indirect - github.com/prometheus/procfs v0.8.0 // indirect + github.com/prometheus/common v0.42.0 // indirect + github.com/prometheus/procfs v0.9.0 // indirect github.com/quasilyte/go-ruleguard v0.3.17 // indirect github.com/quasilyte/gogrep v0.0.0-20220120141003-628d8b3623b5 // indirect github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95 // indirect github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 // indirect github.com/quic-go/qpack v0.4.0 // indirect - github.com/quic-go/qtls-go1-19 v0.2.1 // indirect - github.com/quic-go/qtls-go1-20 v0.1.1 // indirect + github.com/quic-go/qtls-go1-19 v0.3.2 // indirect + github.com/quic-go/qtls-go1-20 v0.2.2 // indirect github.com/quic-go/quic-go v0.33.0 // indirect github.com/quic-go/webtransport-go v0.5.2 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect @@ -239,7 +233,6 @@ require ( github.com/sivchari/tenv v1.7.0 // indirect github.com/sonatard/noctx v0.0.1 // indirect github.com/sourcegraph/go-diff v0.6.1 // indirect - github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/spf13/afero v1.8.2 // indirect github.com/spf13/cast v1.5.0 // indirect @@ -263,29 +256,27 @@ require ( github.com/ultraware/whitespace v0.0.5 // indirect github.com/urfave/cli v1.22.10 // indirect github.com/uudashr/gocognit v1.0.6 // indirect - github.com/whyrusleeping/cbor-gen v0.0.0-20230126041949-52956bd4c9aa // indirect github.com/yagipy/maintidx v1.0.0 // indirect github.com/yeya24/promlinter v0.2.0 // indirect gitlab.com/bosi/decorder v0.2.3 // indirect go.opentelemetry.io/otel v1.14.0 // indirect go.opentelemetry.io/otel/trace v1.14.0 // indirect go.uber.org/atomic v1.10.0 // indirect - go.uber.org/dig v1.15.0 // indirect - go.uber.org/fx v1.18.2 // indirect - go.uber.org/multierr v1.9.0 // indirect + go.uber.org/dig v1.17.0 // indirect + go.uber.org/fx v1.19.2 // indirect + go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.24.0 // indirect - golang.org/x/crypto v0.6.0 // indirect - golang.org/x/exp v0.0.0-20230213192124-5e25df0256eb // indirect + golang.org/x/crypto v0.9.0 // indirect + golang.org/x/exp v0.0.0-20230321023759-10a507213a29 // indirect golang.org/x/exp/typeparams v0.0.0-20220613132600-b0d781184e0d // indirect - golang.org/x/mod v0.7.0 // indirect - golang.org/x/net v0.7.0 // indirect + golang.org/x/mod v0.10.0 // indirect + golang.org/x/net v0.10.0 // indirect golang.org/x/sync v0.1.0 // indirect - golang.org/x/sys v0.6.0 // indirect - golang.org/x/term v0.5.0 // indirect - golang.org/x/text v0.7.0 // indirect - golang.org/x/tools v0.3.0 // indirect - golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect - google.golang.org/protobuf v1.28.1 // indirect + golang.org/x/sys v0.8.0 // indirect + golang.org/x/term v0.8.0 // indirect + golang.org/x/text v0.9.0 // indirect + golang.org/x/tools v0.7.0 // indirect + google.golang.org/protobuf v1.30.0 // indirect gopkg.in/ini.v1 v1.66.6 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index a353f474c..66957ef56 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -45,8 +45,6 @@ dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBr dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4= dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU= git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg= -github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= -github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/Antonboom/errname v0.1.7 h1:mBBDKvEYwPl4WFFNwec1CZO096G6vzK9vvDQzAwkako= github.com/Antonboom/errname v0.1.7/go.mod h1:g0ONh16msHIPgJSGsecu1G/dcF2hlYR/0SddnIAGavU= github.com/Antonboom/nilnil v0.1.1 h1:PHhrh5ANKFWRBh7TdYmyyq2gyT2lotnvFvvFbylF81Q= @@ -59,27 +57,24 @@ github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 h1:sHglBQTwgx+rW github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs= github.com/GaijinEntertainment/go-exhaustruct/v2 v2.3.0 h1:+r1rSv4gvYn0wmRjC8X7IAzX8QezqtFV9m0MUHFJgts= github.com/GaijinEntertainment/go-exhaustruct/v2 v2.3.0/go.mod h1:b3g59n2Y+T5xmcxJL+UEG2f8cQploZm1mR/v6BW0mU0= -github.com/Kubuxu/go-os-helper v0.0.1/go.mod h1:N8B+I7vPCT80IcP58r50u4+gEEcsZETFUpAzWW2ep1Y= github.com/Kubuxu/gocovmerge v0.0.0-20161216165753-7ecaa51963cd h1:HNhzThEtZW714v8Eda8sWWRcu9WSzJC+oCyjRjvZgRA= github.com/Kubuxu/gocovmerge v0.0.0-20161216165753-7ecaa51963cd/go.mod h1:bqoB8kInrTeEtYAwaIXoSRqdwnjQmFhsfusnzyui6yY= github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= github.com/OpenPeeDeeP/depguard v1.1.0 h1:pjK9nLPS1FwQYGGpPxoMYpe7qACHOhAWQMQzV71i49o= github.com/OpenPeeDeeP/depguard v1.1.0/go.mod h1:JtAMzWkmFEzDPyAd+W0NHl1lvpQKTvT9jnRVsohBKpc= -github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= -github.com/alecthomas/units v0.0.0-20210927113745-59d0afb8317a h1:E/8AP5dFtMhl5KPJz66Kt9G0n+7Sn41Fy1wv9/jHOrc= -github.com/alecthomas/units v0.0.0-20210927113745-59d0afb8317a/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= +github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 h1:s6gZFSlWYmbqAuRjVTiNNhvNRfY2Wxp9nhfyel4rklc= +github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= github.com/alexkohler/prealloc v1.0.0 h1:Hbq0/3fJPQhNkN0dR95AVrr6R7tou91y0uHG5pOcUuw= github.com/alexkohler/prealloc v1.0.0/go.mod h1:VetnK3dIgFBBKmg0YnD9F9x6Icjd+9cvfHR56wJVlKE= github.com/alingse/asasalint v0.0.11 h1:SFwnQXJ49Kx/1GghOFz1XGqHYKp21Kq1nHad/0WQRnw= github.com/alingse/asasalint v0.0.11/go.mod h1:nCaoMhw7a9kSJObvQyVzNTPBDbNpdocqrSP7t/cW5+I= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= -github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/ashanbrown/forbidigo v1.3.0 h1:VkYIwb/xxdireGAdJNZoo24O4lmnEWkactplBlWTShc= github.com/ashanbrown/forbidigo v1.3.0/go.mod h1:vVW7PEdqEFqapJe95xHkTfB1+XvZXBFg8t0sG2FIxmI= github.com/ashanbrown/makezero v1.1.1 h1:iCQ87C0V0vSyO+M9E/FZYbu65auqH0lnsOkf5FcB28s= @@ -102,19 +97,6 @@ github.com/breml/bidichk v0.2.3 h1:qe6ggxpTfA8E75hdjWPZ581sY3a2lnl0IRxLQFelECI= github.com/breml/bidichk v0.2.3/go.mod h1:8u2C6DnAy0g2cEq+k/A2+tr9O1s+vHGxWn0LTc70T2A= github.com/breml/errchkjson v0.3.0 h1:YdDqhfqMT+I1vIxPSas44P+9Z9HzJwCeAzjB8PxP1xw= github.com/breml/errchkjson v0.3.0/go.mod h1:9Cogkyv9gcT8HREpzi3TiqBxCqDzo8awa92zSDFcofU= -github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= -github.com/btcsuite/btcd v0.0.0-20190523000118-16327141da8c/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= -github.com/btcsuite/btcd v0.0.0-20190824003749-130ea5bddde3/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= -github.com/btcsuite/btcd v0.20.1-beta h1:Ik4hyJqN8Jfyv3S4AGBOmyouMsYE3EdYODkMbQjwPGw= -github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= -github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= -github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= -github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= -github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= -github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= -github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= -github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= -github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= github.com/butuzov/ireturn v0.1.1 h1:QvrO2QF2+/Cx1WA/vETCIYBKtRjc30vesdoPUNo1EbY= github.com/butuzov/ireturn v0.1.1/go.mod h1:Wh6Zl3IMtTpaIKbmwzqi6olnM9ptYQxxVacMsOEFPoc= @@ -127,7 +109,6 @@ github.com/charithe/durationcheck v0.0.9 h1:mPP4ucLrf/rKZiIG/a9IPXHGlh8p4CzgpyTy github.com/charithe/durationcheck v0.0.9/go.mod h1:SSbRIBVfMjCi/kEB6K65XEA83D6prSM8ap1UCpNKtgg= github.com/chavacava/garif v0.0.0-20220630083739-93517212f375 h1:E7LT642ysztPWE0dfz43cWOvMiF42DyTRC+eZIaO4yI= github.com/chavacava/garif v0.0.0-20220630083739-93517212f375/go.mod h1:4m1Rv7xfuwWPNKXlThldNuJvutYM6J95wNuuVmn55To= -github.com/cheekybits/genny v1.0.0/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ= 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= @@ -137,17 +118,12 @@ github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGX github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/containerd/cgroups v0.0.0-20201119153540-4cbc285b3327/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE= -github.com/containerd/cgroups v1.0.4 h1:jN/mbWBEaz+T1pi5OFtnkQ+8qnmEbAr1Oo1FRm5B0dA= -github.com/containerd/cgroups v1.0.4/go.mod h1:nLNQtsF7Sl2HxNebu77i1R0oDlhiTG+kO4JTrUzo6IA= -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= -github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM= +github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw= github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -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/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= @@ -160,7 +136,6 @@ github.com/curioswitch/go-reassign v0.1.2 h1:ekM07+z+VFT560Exz4mTv0/s1yU9gem6CJc github.com/curioswitch/go-reassign v0.1.2/go.mod h1:bFJIHgtTM3hRm2sKXSPkbwNjSFyGURQXyn4IXD2qwfQ= github.com/daixiang0/gci v0.6.3 h1:wUAqXChk8HbwXn8AfxD9DYSCp9Bpz1L3e6Q4Roe+q9E= github.com/daixiang0/gci v0.6.3/go.mod h1:EpVfrztufwVgQRXjnX4zuNinEpLj5OmMjtu/+MB0V0c= -github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -171,15 +146,12 @@ github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 h1:HbphB4TFFXpv7MNrT52FGrrgVXF1 github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0/go.mod h1:DZGJHZMqrU4JJqFAWUS2UO1+lbSKsdiOoYi9Zzey7Fc= github.com/denis-tingaikin/go-header v0.4.3 h1:tEaZKAlqql6SKCY++utLmkPLd6K8IBM20Ha7UVm+mtU= github.com/denis-tingaikin/go-header v0.4.3/go.mod h1:0wOCWuN71D5qIgE2nz9KrKmuYBAC2Mra5RassOIQ2/c= -github.com/dgraph-io/badger v1.5.5-0.20190226225317-8115aed38f8f/go.mod h1:VZxzAIRPHRVNRKRo6AXrX9BJegn6il06VMTZVJYCIjQ= -github.com/dgraph-io/badger v1.6.0-rc1/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= -github.com/dgryski/go-farm v0.0.0-20190104051053-3adb47b1fb0f/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= -github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= +github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/elastic/gosigar v0.12.0/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= github.com/elastic/gosigar v0.14.2 h1:Dg80n8cr90OZ7x+bAax/QjoW/XqTI11RmA79ZwIm9/4= github.com/elastic/gosigar v0.14.2/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= @@ -207,7 +179,6 @@ github.com/flynn/noise v1.0.0 h1:DlTHqmzmvcEiKj+4RYo/imoswx/4r6iBlCMfVtrMXpQ= github.com/flynn/noise v1.0.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag= github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk= github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= -github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= @@ -220,7 +191,6 @@ github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14= github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= -github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= github.com/go-critic/go-critic v0.6.4 h1:tucuG1pvOyYgpBIrVxw0R6gwO42lNa92Aq3VaDoIs+E= github.com/go-critic/go-critic v0.6.4/go.mod h1:qL5SOlk7NtY6sJPoVCTKDIgzNOxHkkkOCVDyi9wJe1U= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= @@ -230,11 +200,9 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2 github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= -github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= -github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= @@ -249,8 +217,8 @@ github.com/go-playground/validator/v10 v10.2.0 h1:KgJ0snyC2R9VXYN2rneOtQcw5aHQB1 github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -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/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/go-toolsmith/astcast v1.0.0 h1:JojxlmI6STnFVG9yOImLeGREv8W2ocNUM+iOhR6jE7g= github.com/go-toolsmith/astcast v1.0.0/go.mod h1:mt2OdQTeAQcY4DQgPSArJjHCcOwlX+Wl/kwN+LbLGQ4= github.com/go-toolsmith/astcopy v1.0.0/go.mod h1:vrgyG+5Bxrnz4MZWPF+pI4R8h3qKRjjyvV/DSez4WVQ= @@ -288,8 +256,6 @@ github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5x github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= -github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= @@ -308,7 +274,6 @@ github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71 github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= @@ -323,9 +288,9 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2 h1:23T5iq8rbUYlhpt5DB4XJkc6BU31uODLD1o1gKvZmD0= github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2/go.mod h1:k9Qvh+8juN+UKMCS/3jFtGICgW8O96FVaZsaxdzDkR4= github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a h1:w8hkcTqaFpzKqonE9uMCefW1WDie15eSP/4MssdenaM= @@ -381,8 +346,8 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20221203041831-ce31453925ec h1:fR20TYVVwhK4O7r7y+McjRYyaTH6/vjwJOajE+XhlzM= -github.com/google/pprof v0.0.0-20221203041831-ce31453925ec/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo= +github.com/google/pprof v0.0.0-20230405160723-4a4c7d95572b h1:Qcx5LM0fSiks9uCyFZwDBUasd3lxd1RM0GYpL+Li5o4= +github.com/google/pprof v0.0.0-20230405160723-4a4c7d95572b/go.mod h1:79YE0hCXdHag9sBkw2o+N/YnZtTkXi0UT9Nnixa5eYk= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -397,10 +362,8 @@ github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORR github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c h1:7lF+Vz0LqiRidnzC1Oq86fpX1q/iEv2KJdrCtttYjT4= github.com/gordonklaus/ineffassign v0.0.0-20210914165742-4cc7213b9bc8 h1:PVRE9d4AQKmbelZ7emNig1+NT27DUmKZn5qXxfio54U= github.com/gordonklaus/ineffassign v0.0.0-20210914165742-4cc7213b9bc8/go.mod h1:Qcp2HIAYhR7mNUVSIxZww3Guk4it82ghYcEXIAk+QT0= -github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= -github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE= github.com/gostaticanalysis/analysisutil v0.0.3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE= github.com/gostaticanalysis/analysisutil v0.1.0/go.mod h1:dMhHRU9KTiDcuLGdy87/2gTR8WruwYZrKdRq9m1O6uw= @@ -420,14 +383,11 @@ github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:Fecb github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= github.com/gxed/go-shellwords v1.0.3 h1:2TP32H4TAklZUdz84oj95BJhVnIrRasyx2j1cqH5K38= github.com/gxed/go-shellwords v1.0.3/go.mod h1:N7paucT91ByIjmVJHhvoarjoQnmsi3Jd3vH7VqgtMxQ= -github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= -github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= github.com/hannahhoward/go-pubsub v0.0.0-20200423002714-8d62886cc36e h1:3YKHER4nmd7b5qy5t0GWDTwSn4OyRgfAXSmo6VnryBY= github.com/hannahhoward/go-pubsub v0.0.0-20200423002714-8d62886cc36e/go.mod h1:I8h3MITA53gN9OnWGCgaMa0JWVRdXthWw4M3CPM54OY= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= @@ -435,7 +395,6 @@ github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mO github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= @@ -444,8 +403,8 @@ github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUq github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= -github.com/huin/goupnp v1.0.3 h1:N8No57ls+MnjlB+JPiCVSOyy/ot7MJTqlo7rn+NYSqQ= -github.com/huin/goupnp v1.0.3/go.mod h1:ZxNlw5WqJj6wSsRK5+YfflQGXYfccj5VgQsMNixHM7Y= +github.com/huin/goupnp v1.1.0 h1:gEe0Dp/lZmPZiDFzJJaOfUpOvv2MKUkoBX8lDrn9vKU= +github.com/huin/goupnp v1.1.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= @@ -453,44 +412,29 @@ github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NH github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.8.0 h1:UdjAJmHzQHo/j3g3b1bAcAXCj/GM6iTwvSlBDvPBNBs= -github.com/ipfs/boxo v0.8.0/go.mod h1:RIsi4CnTyQ7AUsNn5gXljJYZlQrHBMnJp94p73liFiA= +github.com/ipfs/boxo v0.8.2-0.20230608080412-e44e658cb393 h1:o3l1Rq7NwXT//tOgd0k+JOYTQgvg+WhgKoLy8tJfLxk= +github.com/ipfs/boxo v0.8.2-0.20230608080412-e44e658cb393/go.mod h1:ic5+bhD5T+A9n0HMkXYHiTzpjjaAZaPeKRQ9dWethTs= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= -github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= -github.com/ipfs/go-block-format v0.0.3/go.mod h1:4LmD4ZUw0mhO+JSKdpWwrzATiEfM7WWgQ8H5l6P8MVk= github.com/ipfs/go-block-format v0.1.2 h1:GAjkfhVx1f4YTODS6Esrj1wt2HhrtwTnhEr+DyPUaJo= github.com/ipfs/go-block-format v0.1.2/go.mod h1:mACVcrxarQKstUU3Yf/RdwbC4DzPV6++rO2a3d+a/KE= github.com/ipfs/go-blockservice v0.5.0 h1:B2mwhhhVQl2ntW2EIpaWPwSCxSuqr5fFA93Ms4bYLEY= -github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= -github.com/ipfs/go-cid v0.0.2/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= -github.com/ipfs/go-cid v0.0.3/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= -github.com/ipfs/go-cid v0.0.4/go.mod h1:4LLaPOQwmk5z9LBgQnpkivrx8BJjUyGwTXCd5Xfj6+M= github.com/ipfs/go-cid v0.0.5/go.mod h1:plgt+Y5MnOey4vO4UlUazGqdbEXuFYitED67FexhXog= -github.com/ipfs/go-cid v0.0.6/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I= -github.com/ipfs/go-cid v0.0.7/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I= github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= github.com/ipfs/go-cid v0.4.1/go.mod h1:uQHwDeX4c6CtyrFwdqyhpNcxVewur1M7l7fNU7LKwZk= github.com/ipfs/go-cidutil v0.1.0 h1:RW5hO7Vcf16dplUU60Hs0AKDkQAVPVplr7lk97CFL+Q= github.com/ipfs/go-cidutil v0.1.0/go.mod h1:e7OEVBMIv9JaOxt9zaGEmAoSlXW9jdFZ5lP/0PwcfpA= -github.com/ipfs/go-datastore v0.0.1/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= -github.com/ipfs/go-datastore v0.1.0/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= github.com/ipfs/go-datastore v0.5.0/go.mod h1:9zhEApYMTl17C8YDp7JmU7sQZi2/wqiYh73hakZ90Bk= github.com/ipfs/go-datastore v0.6.0 h1:JKyz+Gvz1QEZw0LsX1IBn+JFCJQH4SJVFtM4uWU0Myk= github.com/ipfs/go-datastore v0.6.0/go.mod h1:rt5M3nNbSO/8q1t4LNkLyUwRs8HupMeN/8O4Vn9YAT8= github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk= github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps= -github.com/ipfs/go-ds-badger v0.0.2/go.mod h1:Y3QpeSFWQf6MopLTiZD+VT6IC1yZqaGmjvRcKeSGij8= -github.com/ipfs/go-ds-badger v0.0.5/go.mod h1:g5AuuCGmr7efyzQhLL8MzwqcauPojGPUaHzfGTzuE3s= -github.com/ipfs/go-ds-leveldb v0.0.1/go.mod h1:feO8V3kubwsEF22n0YRQCffeb79OOYIykR4L04tMOYc= github.com/ipfs/go-graphsync v0.14.4 h1:ysazATpwsIjYtYEZH5CdD/HRaonCJd4pASUtnzESewk= github.com/ipfs/go-graphsync v0.14.4/go.mod h1:yT0AfjFgicOoWdAlUJ96tQ5AkuGI4r1taIQX/aHbBQo= github.com/ipfs/go-ipfs-blockstore v1.3.0 h1:m2EXaWgwTzAfsmt5UdJ7Is6l4gJcaM/A12XwJyvYvMM= github.com/ipfs/go-ipfs-blockstore v1.3.0/go.mod h1:KgtZyc9fq+P2xJUiCAzbRdhhqJHvsw8u2Dlqy2MyRTE= github.com/ipfs/go-ipfs-blocksutil v0.0.1 h1:Eh/H4pc1hsvhzsQoMEP3Bke/aW5P5rVM1IWFJMcGIPQ= github.com/ipfs/go-ipfs-chunker v0.0.5 h1:ojCf7HV/m+uS2vhUGWcogIIxiO5ubl5O57Q7NapWLY8= -github.com/ipfs/go-ipfs-config v0.5.3 h1:3GpI/xR9FoJNTjU6YvCMRbYyEi0dBVY5UtlUTcNRlSA= -github.com/ipfs/go-ipfs-config v0.5.3/go.mod h1:nSLCFtlaL+2rbl3F+9D4gQZQbT1LjRKx7TJg/IHz6oM= github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= github.com/ipfs/go-ipfs-delay v0.0.1 h1:r/UXYyRcddO6thwOnhiznIAiSvxMECGgtv35Xs1IeRQ= github.com/ipfs/go-ipfs-ds-help v1.1.0 h1:yLE2w9RAsl31LtfMt91tRZcrx+e61O5mDxFRR994w4Q= @@ -502,19 +446,14 @@ github.com/ipfs/go-ipfs-files v0.2.0/go.mod h1:vT7uaQfIsprKktzbTPLnIsd+NGw9ZbYwS github.com/ipfs/go-ipfs-posinfo v0.0.1 h1:Esoxj+1JgSjX0+ylc0hUmJCOv6V2vFoZiETLR6OtpRs= github.com/ipfs/go-ipfs-pq v0.0.3 h1:YpoHVJB+jzK15mr/xsWC574tyDLkezVrDNeaalQBsTE= github.com/ipfs/go-ipfs-pq v0.0.3/go.mod h1:btNw5hsHBpRcSSgZtiNm/SLj5gYIZ18AKtv3kERkRb4= -github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyBCNzQxlJBc= github.com/ipfs/go-ipfs-util v0.0.2 h1:59Sswnk1MFaiq+VcaknX7aYEyGyGDAA73ilhEK2POp8= github.com/ipfs/go-ipfs-util v0.0.2/go.mod h1:CbPtkWJzjLdEcezDns2XYaehFVNXG9zrdrtMecczcsQ= github.com/ipfs/go-ipld-cbor v0.0.6 h1:pYuWHyvSpIsOOLw4Jy7NbBkCyzLDcl64Bf/LZW7eBQ0= -github.com/ipfs/go-ipld-cbor v0.0.6/go.mod h1:ssdxxaLJPXH7OjF5V4NSjBbcfh+evoR4ukuru0oPXMA= -github.com/ipfs/go-ipld-format v0.0.1/go.mod h1:kyJtbkDALmFHv3QR6et67i35QzO3S0dCDnkOJhcZkms= -github.com/ipfs/go-ipld-format v0.2.0/go.mod h1:3l3C1uKoadTPbeNfrDi+xMInYKlx2Cvg1BuydPSdzQs= -github.com/ipfs/go-ipld-format v0.4.0 h1:yqJSaJftjmjc9jEOFYlpkwOLVKv68OD27jFLlSghBlQ= -github.com/ipfs/go-ipld-format v0.4.0/go.mod h1:co/SdBE8h99968X0hViiw1MNlh6fvxxnHpvVLnH7jSM= -github.com/ipfs/go-ipld-legacy v0.1.1 h1:BvD8PEuqwBHLTKqlGFTHSwrwFOMkVESEvwIYwR2cdcc= -github.com/ipfs/go-ipld-legacy v0.1.1/go.mod h1:8AyKFCjgRPsQFf15ZQgDB8Din4DML/fOmKZkkFkrIEg= -github.com/ipfs/go-libipfs v0.6.0 h1:3FuckAJEm+zdHbHbf6lAyk0QUzc45LsFcGw102oBCZM= -github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= +github.com/ipfs/go-ipld-format v0.5.0 h1:WyEle9K96MSrvr47zZHKKcDxJ/vlpET6PSiQsAFO+Ds= +github.com/ipfs/go-ipld-format v0.5.0/go.mod h1:ImdZqJQaEouMjCvqCe0ORUS+uoBmf7Hf+EO/jh+nk3M= +github.com/ipfs/go-ipld-legacy v0.2.1 h1:mDFtrBpmU7b//LzLSypVrXsD8QxkEWxu5qVxN99/+tk= +github.com/ipfs/go-ipld-legacy v0.2.1/go.mod h1:782MOUghNzMO2DER0FlBR94mllfdCJCkTtDtPM51otM= +github.com/ipfs/go-libipfs v0.7.0 h1:Mi54WJTODaOL2/ZSm5loi3SwI3jI2OuFWUrQIkJ5cpM= github.com/ipfs/go-log v1.0.5 h1:2dOuUCB1Z7uoczMWgAyDck5JLb72zHzrMnGnCNNbvY8= github.com/ipfs/go-log v1.0.5/go.mod h1:j0b8ZoR+7+R99LD9jZ6+AJsrzkPbSXbZfGakb5JPtIo= github.com/ipfs/go-log/v2 v2.1.3/go.mod h1:/8d0SH3Su5Ooc31QlL1WysJhvyOTDCjcCZ9Axpmri6g= @@ -525,7 +464,6 @@ github.com/ipfs/go-metrics-interface v0.0.1 h1:j+cpbjYvu4R8zbleSs36gvB7jR+wsL2fG github.com/ipfs/go-metrics-interface v0.0.1/go.mod h1:6s6euYU4zowdslK0GKHmqaIZ3j/b/tL7HTWtJ4VPgWY= github.com/ipfs/go-peertaskqueue v0.8.1 h1:YhxAs1+wxb5jk7RvS0LHdyiILpNmRIRnZVztekOF0pg= github.com/ipfs/go-peertaskqueue v0.8.1/go.mod h1:Oxxd3eaK279FxeydSPPVGHzbwVeHjatZ2GA8XD+KbPU= -github.com/ipfs/go-todocounter v0.0.1/go.mod h1:l5aErvQc8qKE2r7NDMjmq5UNAvuZy0rC8BHOplkWvZ4= github.com/ipfs/go-unixfs v0.4.5 h1:wj8JhxvV1G6CD7swACwSKYa+NgtdWC1RUit+gFnymDU= github.com/ipfs/go-unixfsnode v1.6.0 h1:JOSA02yaLylRNi2rlB4ldPr5VcZhcnaIVj5zNLcOjDo= github.com/ipfs/go-unixfsnode v1.6.0/go.mod h1:PVfoyZkX1B34qzT3vJO4nsLUpRCyhnMuHBznRcXirlk= @@ -534,34 +472,25 @@ github.com/ipfs/hang-fds v0.1.0 h1:deBiFlWHsVGzJ0ZMaqscEqRM1r2O1rFZ59UiQXb1Xko= github.com/ipfs/hang-fds v0.1.0/go.mod h1:29VLWOn3ftAgNNgXg/al7b11UzuQ+w7AwtCGcTaWkbM= github.com/ipfs/iptb v1.4.0 h1:YFYTrCkLMRwk/35IMyC6+yjoQSHTEcNcefBStLJzgvo= github.com/ipfs/iptb v1.4.0/go.mod h1:1rzHpCYtNp87/+hTxG5TfCVn/yMY3dKnLn8tBiMfdmg= -github.com/ipfs/iptb-plugins v0.3.0 h1:C1rpq1o5lUZtaAOkLIox5akh6ba4uk/3RwWc6ttVxw0= -github.com/ipfs/iptb-plugins v0.3.0/go.mod h1:5QtOvckeIw4bY86gSH4fgh3p3gCSMn3FmIKr4gaBncA= +github.com/ipfs/iptb-plugins v0.5.0 h1:zEMLlWAb531mLpD36KFy/yc0egT6FkBEHQtdERexNao= +github.com/ipfs/iptb-plugins v0.5.0/go.mod h1:/6crDf3s58T70BhZ+m9SyyKpK7VvSDS2Ny4kafxXDp4= github.com/ipld/go-car/v2 v2.9.1-0.20230325062757-fff0e4397a3d h1:22g+x1tgWSXK34i25qjs+afr7basaneEkHaglBshd2g= github.com/ipld/go-codec-dagpb v1.6.0 h1:9nYazfyu9B1p3NAgfVdpRco3Fs2nFC72DqVsMj6rOcc= github.com/ipld/go-codec-dagpb v1.6.0/go.mod h1:ANzFhfP2uMJxRBr8CE+WQWs5UsNa0pYtmKZ+agnUw9s= -github.com/ipld/go-ipld-prime v0.9.1-0.20210324083106-dc342a9917db/go.mod h1:KvBLMr4PX1gWptgkzRjVZCrLmSGcZCb/jioOQwCqZN8= github.com/ipld/go-ipld-prime v0.20.0 h1:Ud3VwE9ClxpO2LkCYP7vWPc0Fo+dYdYzgxUJZ3uRG4g= github.com/ipld/go-ipld-prime v0.20.0/go.mod h1:PzqZ/ZR981eKbgdr3y2DJYeD/8bgMawdGVlJDE8kK+M= -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= github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= -github.com/jbenet/go-cienv v0.0.0-20150120210510-1bb1476777ec/go.mod h1:rGaEvXB4uRSZMmzKNLoXvTu1sfx+1kv/DojUlPrSZGs= github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA= github.com/jbenet/go-random v0.0.0-20190219211222-123a90aedc0c h1:uUx61FiAa1GI6ZmVd2wf2vULeQZIKG66eybjNXKYCz4= github.com/jbenet/go-random v0.0.0-20190219211222-123a90aedc0c/go.mod h1:sdx1xVM9UuLw1tXnhJWN3piypTUO3vCIHYmG15KE/dU= github.com/jbenet/go-random-files v0.0.0-20190219210431-31b3f20ebded h1:fHCa28iw+qaRWZK4IqrntHxXALD5kKr/ESrpOCRRdrg= github.com/jbenet/go-random-files v0.0.0-20190219210431-31b3f20ebded/go.mod h1:FKvZrl5nnaGnTAMewcq0i7wM5zHD75e0lwlnF8q46uo= -github.com/jbenet/go-temp-err-catcher v0.0.0-20150120210811-aac704a3f4f2/go.mod h1:8GXXJV31xl8whumTzdZsTt3RnUIiPqzkyf7mxToRCMs= github.com/jbenet/go-temp-err-catcher v0.1.0 h1:zpb3ZH6wIE8Shj2sKS+khgRvf7T7RABoLk/+KKHggpk= github.com/jbenet/go-temp-err-catcher v0.1.0/go.mod h1:0kJRvmDZXNMIiJirNPEYfhpPwbGVtZVWC34vc5WLsDk= -github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY= -github.com/jbenet/goprocess v0.1.3/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= github.com/jbenet/goprocess v0.1.4 h1:DRGOFReOMqqDNXwW70QkacFW0YN9QnwLV0Vqk+3oU0o= github.com/jbenet/goprocess v0.1.4/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU= -github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jgautheron/goconst v1.5.1 h1:HxVbL1MhydKs8R8n/HE5NPvzfaYmQJA3o879lE4+WcM= github.com/jgautheron/goconst v1.5.1/go.mod h1:aAosetZ5zaeC/2EfMeRswtxUFBpe2Hr7HzkgX4fanO4= github.com/jingyugao/rowserrcheck v1.1.1 h1:zibz55j/MJtLsjP1OF4bSdgXxwL1b+Vn7Tjzq7gFzUs= @@ -573,9 +502,7 @@ github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22 github.com/jonboulle/clockwork v0.2.0 h1:J2SLSdy7HgElq8ekSl2Mxh6vrRNFxqbXGenYH2I02Vs= github.com/jonboulle/clockwork v0.2.0/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= -github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= @@ -583,35 +510,30 @@ github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnr github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= -github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/julz/importas v0.1.0 h1:F78HnrsjY3cR7j0etXy5+TU1Zuy7Xt08X/1aJnH5xXY= github.com/julz/importas v0.1.0/go.mod h1:oSFU2R4XK/P7kNBrnL/FEQlDGN1/6WoxXEjSSXO0DV0= -github.com/kami-zh/go-capturer v0.0.0-20171211120116-e492ea43421d/go.mod h1:P2viExyCEfeWGU259JnaQ34Inuec4R38JCyBx2edgD0= -github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/errcheck v1.6.2 h1:uGQ9xI8/pgc9iOoCe7kWQgRE6SBTrCGmTSf0LrEtY7c= github.com/kisielk/errcheck v1.6.2/go.mod h1:nXw/i/MfnvRHqXa7XXmQMUB0oNFGuBrNI8d8NLy0LPw= github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= 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.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/klauspost/compress v1.15.12 h1:YClS/PImqYbn+UILDnqxQCZ3RehC9N318SU3kElDUEM= -github.com/klauspost/compress v1.15.12/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= +github.com/klauspost/compress v1.16.4 h1:91KN02FnsOYhuunwU4ssRe8lc2JosWmizWa91B5v1PU= +github.com/klauspost/compress v1.16.4/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.2.3 h1:sxCkb+qR91z4vsqw4vGGZlDgPz3G7gjaLyK3V8y70BU= -github.com/klauspost/cpuid/v2 v2.2.3/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= +github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk= +github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/koron/go-ssdp v0.0.0-20180514024734-4a0ed625a78b/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk= github.com/koron/go-ssdp v0.0.0-20191105050749-2e1c40ed0b5d/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk= -github.com/koron/go-ssdp v0.0.3 h1:JivLMY45N76b4p/vsWGOKewBQu6uf39y8l+AQ7sDKx8= -github.com/koron/go-ssdp v0.0.3/go.mod h1:b2MxI6yh02pKrsyNoQUsk4+YNikaGhe4894J+Q5lDvA= +github.com/koron/go-ssdp v0.0.4 h1:1IDwrghSKYM7yLf7XCzbByg2sJ/JcNOZRXS2jczTwz0= +github.com/koron/go-ssdp v0.0.4/go.mod h1:oDXq+E5IL5q0U8uSBcoAXzTzInwy5lEgC91HoKtbmZk= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= @@ -638,121 +560,38 @@ github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgx github.com/leonklingele/grouper v1.1.0 h1:tC2y/ygPbMFSBOs3DcyaEMKnnwH7eYKzohOtRrf0SAg= github.com/leonklingele/grouper v1.1.0/go.mod h1:uk3I3uDfi9B6PeUjsCKi6ndcf63Uy7snXgR4yDYQVDY= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/libp2p/go-addr-util v0.0.1/go.mod h1:4ac6O7n9rIAKB1dnd+s8IbbMXkt+oBpzX4/+RACcnlQ= -github.com/libp2p/go-buffer-pool v0.0.1/go.mod h1:xtyIz9PMobb13WaxR6Zo1Pd1zXJKYg0a8KiIvDp3TzQ= -github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM= github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38yPW7c= github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic= -github.com/libp2p/go-conn-security-multistream v0.1.0/go.mod h1:aw6eD7LOsHEX7+2hJkDxw1MteijaVcI+/eP2/x3J1xc= -github.com/libp2p/go-eventbus v0.0.2/go.mod h1:Hr/yGlwxA/stuLnpMiu82lpNKpvRy3EaJxPu40XYOwk= -github.com/libp2p/go-eventbus v0.1.0/go.mod h1:vROgu5cs5T7cv7POWlWxBaVLxfSegC5UGQf8A2eEmx4= -github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8= -github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.1.0/go.mod h1:6D/2OBauqLUoqcADOJpn9WbKqvaM07tDw68qHM0BxUM= -github.com/libp2p/go-libp2p v0.3.1/go.mod h1:e6bwxbdYH1HqWTz8faTChKGR0BjPc8p+6SyP8GTTR7Y= -github.com/libp2p/go-libp2p v0.4.0/go.mod h1:9EsEIf9p2UDuwtPd0DwJsAl0qXVxgAnuDGRvHbfATfI= -github.com/libp2p/go-libp2p v0.26.4 h1:VA9ChjN0n1BwwfU/dqx4Zj9ezXtIxGk8FyJPwFONqxs= -github.com/libp2p/go-libp2p v0.26.4/go.mod h1:x75BN32YbwuY0Awm2Uix4d4KOz+/4piInkp4Wr3yOo8= +github.com/libp2p/go-libp2p v0.27.3 h1:tkV/zm3KCZ4R5er9Xcs2pt0YNB4JH0iBfGAtHJdLHRs= +github.com/libp2p/go-libp2p v0.27.3/go.mod h1:FAvvfQa/YOShUYdiSS03IR9OXzkcJXwcNA2FUCh9ImE= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= -github.com/libp2p/go-libp2p-autonat v0.1.0/go.mod h1:1tLf2yXxiE/oKGtDwPYWTSYG3PtvYlJmg7NeVtPRqH8= -github.com/libp2p/go-libp2p-autonat-svc v0.1.0/go.mod h1:fqi8Obl/z3R4PFVLm8xFtZ6PBL9MlV/xumymRFkKq5A= -github.com/libp2p/go-libp2p-blankhost v0.1.1/go.mod h1:pf2fvdLJPsC1FsVrNP3DUUvMzUts2dsLLBEpo1vW1ro= -github.com/libp2p/go-libp2p-blankhost v0.1.3/go.mod h1:KML1//wiKR8vuuJO0y3LUd1uLv+tlkGTAr3jC0S5cLg= -github.com/libp2p/go-libp2p-blankhost v0.1.4/go.mod h1:oJF0saYsAXQCSfDq254GMNmLNz6ZTHTOvtF4ZydUvwU= -github.com/libp2p/go-libp2p-circuit v0.1.0/go.mod h1:Ahq4cY3V9VJcHcn1SBXjr78AbFkZeIRmfunbA7pmFh8= -github.com/libp2p/go-libp2p-circuit v0.1.1/go.mod h1:Ahq4cY3V9VJcHcn1SBXjr78AbFkZeIRmfunbA7pmFh8= -github.com/libp2p/go-libp2p-circuit v0.1.3/go.mod h1:Xqh2TjSy8DD5iV2cCOMzdynd6h8OTBGoV1AWbWor3qM= -github.com/libp2p/go-libp2p-connmgr v0.1.1/go.mod h1:wZxh8veAmU5qdrfJ0ZBLcU8oJe9L82ciVP/fl1VHjXk= -github.com/libp2p/go-libp2p-core v0.0.1/go.mod h1:g/VxnTZ/1ygHxH3dKok7Vno1VfpvGcGip57wjTU4fco= -github.com/libp2p/go-libp2p-core v0.0.4/go.mod h1:jyuCQP356gzfCFtRKyvAbNkyeuxb7OlyhWZ3nls5d2I= -github.com/libp2p/go-libp2p-core v0.0.6/go.mod h1:0d9xmaYAVY5qmbp/fcgxHT3ZJsLjYeYPMJAUKpaCHrE= -github.com/libp2p/go-libp2p-core v0.2.0/go.mod h1:X0eyB0Gy93v0DZtSYbEM7RnMChm9Uv3j7yRXjO77xSI= -github.com/libp2p/go-libp2p-core v0.2.2/go.mod h1:8fcwTbsG2B+lTgRJ1ICZtiM5GWCWZVoVrLaDRvIRng0= -github.com/libp2p/go-libp2p-core v0.2.3/go.mod h1:GqhyQqyIAPsxFYXHMjfXgMv03lxsvM0mFzuYA9Ib42A= -github.com/libp2p/go-libp2p-core v0.5.0/go.mod h1:49XGI+kc38oGVwqSBhDEwytaAxgZasHhFfQKibzTls0= -github.com/libp2p/go-libp2p-core v0.5.2 h1:hevsCcdLiazurKBoeNn64aPYTVOPdY4phaEGeLtHOAs= -github.com/libp2p/go-libp2p-core v0.5.2/go.mod h1:uN7L2D4EvPCvzSH5SrhR72UWbnSGpt5/a35Sm4upn4Y= -github.com/libp2p/go-libp2p-crypto v0.1.0/go.mod h1:sPUokVISZiy+nNuTTH/TY+leRSxnFj/2GLjtOTW90hI= -github.com/libp2p/go-libp2p-daemon v0.2.2/go.mod h1:kyrpsLB2JeNYR2rvXSVWyY0iZuRIMhqzWR3im9BV6NQ= -github.com/libp2p/go-libp2p-discovery v0.1.0/go.mod h1:4F/x+aldVHjHDHuX85x1zWoFTGElt8HnoDzwkFZm29g= -github.com/libp2p/go-libp2p-kad-dht v0.2.1/go.mod h1:k7ONOlup7HKzQ68dE6lSnp07cdxdkmnRa+6B4Fh9/w0= -github.com/libp2p/go-libp2p-kbucket v0.2.1/go.mod h1:/Rtu8tqbJ4WQ2KTCOMJhggMukOLNLNPY1EtEWWLxUvc= -github.com/libp2p/go-libp2p-loggables v0.1.0/go.mod h1:EyumB2Y6PrYjr55Q3/tiJ/o3xoDasoRYM7nOzEpoa90= -github.com/libp2p/go-libp2p-mplex v0.2.0/go.mod h1:Ejl9IyjvXJ0T9iqUTE1jpYATQ9NM3g+OtR+EMMODbKo= -github.com/libp2p/go-libp2p-mplex v0.2.1/go.mod h1:SC99Rxs8Vuzrf/6WhmH41kNn13TiYdAWNYHrwImKLnE= -github.com/libp2p/go-libp2p-nat v0.0.4/go.mod h1:N9Js/zVtAXqaeT99cXgTV9e75KpnWCvVOiGzlcHmBbY= -github.com/libp2p/go-libp2p-netutil v0.1.0/go.mod h1:3Qv/aDqtMLTUyQeundkKsA+YCThNdbQD54k3TqjpbFU= -github.com/libp2p/go-libp2p-peer v0.2.0/go.mod h1:RCffaCvUyW2CJmG2gAWVqwePwW7JMgxjsHm7+J5kjWY= -github.com/libp2p/go-libp2p-peerstore v0.1.0/go.mod h1:2CeHkQsr8svp4fZ+Oi9ykN1HBb6u0MOvdJ7YIsmcwtY= -github.com/libp2p/go-libp2p-peerstore v0.1.3/go.mod h1:BJ9sHlm59/80oSkpWgr1MyY1ciXAXV397W6h1GH/uKI= -github.com/libp2p/go-libp2p-pubsub v0.1.1/go.mod h1:ZwlKzRSe1eGvSIdU5bD7+8RZN/Uzw0t1Bp9R1znpR/Q= -github.com/libp2p/go-libp2p-quic-transport v0.1.1/go.mod h1:wqG/jzhF3Pu2NrhJEvE+IE0NTHNXslOPn9JQzyCAxzU= -github.com/libp2p/go-libp2p-record v0.1.1/go.mod h1:VRgKajOyMVgP/F0L5g3kH7SVskp17vFi2xheb5uMJtg= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= -github.com/libp2p/go-libp2p-routing v0.1.0/go.mod h1:zfLhI1RI8RLEzmEaaPwzonRvXeeSHddONWkcTcB54nE= -github.com/libp2p/go-libp2p-secio v0.1.0/go.mod h1:tMJo2w7h3+wN4pgU2LSYeiKPrfqBgkOsdiKK77hE7c8= -github.com/libp2p/go-libp2p-secio v0.2.0/go.mod h1:2JdZepB8J5V9mBp79BmwsaPQhRPNN2NrnB2lKQcdy6g= -github.com/libp2p/go-libp2p-swarm v0.1.0/go.mod h1:wQVsCdjsuZoc730CgOvh5ox6K8evllckjebkdiY5ta4= -github.com/libp2p/go-libp2p-swarm v0.2.1/go.mod h1:x07b4zkMFo2EvgPV2bMTlNmdQc8i+74Jjio7xGvsTgU= -github.com/libp2p/go-libp2p-swarm v0.2.2/go.mod h1:fvmtQ0T1nErXym1/aa1uJEyN7JzaTNyBcHImCxRpPKU= -github.com/libp2p/go-libp2p-testing v0.0.2/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= -github.com/libp2p/go-libp2p-testing v0.0.3/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= -github.com/libp2p/go-libp2p-testing v0.0.4/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= -github.com/libp2p/go-libp2p-testing v0.1.0/go.mod h1:xaZWMJrPUM5GlDBxCeGUi7kI4eqnjVyavGroI2nxEM0= github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA= -github.com/libp2p/go-libp2p-transport-upgrader v0.1.1/go.mod h1:IEtA6or8JUbsV07qPW4r01GnTenLW4oi3lOPbUMGJJA= -github.com/libp2p/go-libp2p-yamux v0.2.0/go.mod h1:Db2gU+XfLpm6E4rG5uGCFX6uXA8MEXOxFcRoXUODaK8= -github.com/libp2p/go-libp2p-yamux v0.2.1/go.mod h1:1FBXiHDk1VyRM1C0aez2bCfHQ4vMZKkAQzZbkSQt5fI= -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-mplex v0.0.3/go.mod h1:pK5yMLmOoBR1pNCqDlA2GQrdAVTMkqFalaTWe7l4Yd0= -github.com/libp2p/go-mplex v0.1.0/go.mod h1:SXgmdki2kwCUlCCbfGLEgHjC4pFqhTp0ZoV6aiKgxDU= -github.com/libp2p/go-msgio v0.0.2/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= -github.com/libp2p/go-msgio v0.0.4/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= github.com/libp2p/go-msgio v0.3.0 h1:mf3Z8B1xcFN314sWX+2vOTShIE0Mmn2TXn3YCUQGNj0= github.com/libp2p/go-msgio v0.3.0/go.mod h1:nyRM819GmVaF9LX3l03RMh10QdOroF++NBbxAb0mmDM= -github.com/libp2p/go-nat v0.0.3/go.mod h1:88nUEt0k0JD45Bk93NIwDqjlhiOwOoV36GchpcVc1yI= github.com/libp2p/go-nat v0.1.0 h1:MfVsH6DLcpa04Xr+p8hmVRG4juse0s3J8HyNWYHffXg= github.com/libp2p/go-nat v0.1.0/go.mod h1:X7teVkwRHNInVNWQiO/tAiAVRwSr5zoRz4YSTC3uRBM= github.com/libp2p/go-netroute v0.1.2/go.mod h1:jZLDV+1PE8y5XxBySEBgbuVAXbhtuHSdmLPL2n9MKbk= github.com/libp2p/go-netroute v0.2.1 h1:V8kVrpD8GK0Riv15/7VN6RbUQ3URNZVosw7H2v9tksU= github.com/libp2p/go-netroute v0.2.1/go.mod h1:hraioZr0fhBjG0ZRXJJ6Zj2IVEVNx6tDTFQfSmcq7mQ= -github.com/libp2p/go-openssl v0.0.2/go.mod h1:v8Zw2ijCSWBQi8Pq5GAixw6DbFfa9u6VIYDXnvOXkc0= -github.com/libp2p/go-openssl v0.0.4/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= -github.com/libp2p/go-openssl v0.1.0 h1:LBkKEcUv6vtZIQLVTegAil8jbNpJErQ9AnT+bWV+Ooo= -github.com/libp2p/go-openssl v0.1.0/go.mod h1:OiOxwPpL3n4xlenjx2h7AwSGaFSC/KZvf6gNdOBQMtc= -github.com/libp2p/go-reuseport v0.0.1/go.mod h1:jn6RmB1ufnQwl0Q1f+YxAj8isJgDCQzaaxIFYDhcYEA= github.com/libp2p/go-reuseport v0.2.0 h1:18PRvIMlpY6ZK85nIAicSBuXXvrYoSw3dsBAR7zc560= github.com/libp2p/go-reuseport v0.2.0/go.mod h1:bvVho6eLMm6Bz5hmU0LYN3ixd3nPPvtIlaURZZgOY4k= -github.com/libp2p/go-reuseport-transport v0.0.2/go.mod h1:YkbSDrvjUVDL6b8XqriyA20obEtsW9BLkuOUyQAOCbs= github.com/libp2p/go-sockaddr v0.0.2/go.mod h1:syPvOmNs24S3dFVGJA1/mrqdeijPxLV2Le3BRLKd68k= -github.com/libp2p/go-stream-muxer v0.0.1/go.mod h1:bAo8x7YkSpadMTbtTaxGVHWUQsR/l5MEaHbKaliuT14= -github.com/libp2p/go-stream-muxer-multistream v0.2.0/go.mod h1:j9eyPol/LLRqT+GPLSxvimPhNph4sfYfMoDPd7HkzIc= -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= -github.com/libp2p/go-ws-transport v0.1.0/go.mod h1:rjw1MG1LU9YDC6gzmwObkPd/Sqwhw7yT74kj3raBFuo= -github.com/libp2p/go-ws-transport v0.1.2/go.mod h1:dsh2Ld8F+XNmzpkaAijmg5Is+e9l6/1tK/6VFOdN69Y= -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= github.com/libp2p/go-yamux/v4 v4.0.0 h1:+Y80dV2Yx/kv7Y7JKu0LECyVdMXm1VUoko+VQ9rBfZQ= github.com/libp2p/go-yamux/v4 v4.0.0/go.mod h1:NWjl8ZTLOGlozrXSOZ/HlfG++39iKNnM5wwmtQP1YB4= -github.com/lucas-clemente/quic-go v0.11.2/go.mod h1:PpMmPfPKO9nKJ/psF49ESTAGQSdfXxlg1otPbEB2nOw= github.com/lufeee/execinquery v1.2.1 h1:hf0Ems4SHcUGBxpGN7Jz78z1ppVkP/837ZlETPCEtOM= github.com/lufeee/execinquery v1.2.1/go.mod h1:EC7DrEKView09ocscGHC+apXMIaorh4xqSxS/dy8SbM= github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= -github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo= github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= -github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/maratori/testpackage v1.1.0 h1:GJY4wlzQhuBusMF1oahQCBtUV/AQ/k69IZ68vxaac2Q= github.com/maratori/testpackage v1.1.0/go.mod h1:PeAhzU8qkCwdGEMTEupsHJNlQu2gZopMC6RjbhmHeDc= -github.com/marten-seemann/qtls v0.2.3/go.mod h1:xzjG7avBwGGbdZ8dTGxlBnLArsVKLvwmjgmPuiQEcYk= 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/matoous/godox v0.0.0-20210227103229-6504466cf951 h1:pWxk9e//NbPwfxat7RXkts09K+dEBJWakUWwICVqYbA= @@ -760,20 +599,15 @@ github.com/matoous/godox v0.0.0-20210227103229-6504466cf951/go.mod h1:1BELzlh859 github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE= github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp98= github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-pointer v0.0.1 h1:n+XhsuGeVO6MEAp7xyEukFINEa+Quek5psIR/ylA6o0= -github.com/mattn/go-pointer v0.0.1/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc= github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= @@ -784,12 +618,10 @@ github.com/mbilski/exhaustivestruct v1.2.0 h1:wCBmUnSYufAHO6J4AVWY6ff+oxWxsVFrwg github.com/mbilski/exhaustivestruct v1.2.0/go.mod h1:OeTBVxQWoEmB2J2JCHmXWPJ0aksxSUOUy+nvtVEfzXc= github.com/mgechev/revive v1.2.3 h1:NzIEEa9+WimQ6q2Ov7OcNeySS/IOcwtkQ8RAh0R5UJ4= github.com/mgechev/revive v1.2.3/go.mod h1:iAWlQishqCuj4yhV24FTnKSXGpbAA+0SckXB8GQMX/Q= -github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= -github.com/miekg/dns v1.1.12/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= -github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA= -github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= +github.com/miekg/dns v1.1.53 h1:ZBkuHr5dxHtB1caEOlZTLPo7D3L3TWckgUUs/RHfDxw= +github.com/miekg/dns v1.1.53/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c h1:bzE/A84HN25pxAuk9Eej1Kz9OUelF97nAc82bDquQI8= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c/go.mod h1:0SQS9kMwD2VsyFEB++InYyBJroV/FRmBgcydeSUcJms= github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= @@ -797,16 +629,11 @@ github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b/go.mod h1:lxPUiZwKo github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc h1:PTfri+PuQmWDqERdnNMiD9ZejrlswWrCpBEZgWOiTrc= github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc/go.mod h1:cGKTAVKx4SxOuR/czcZ/E2RSJ3sfHs8FpHhQ5CWMf9s= github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= -github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= -github.com/minio/sha256-simd v0.0.0-20190328051042-05b4dd3047e5/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= -github.com/minio/sha256-simd v0.1.0/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= -github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g= github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -819,7 +646,6 @@ github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjY github.com/moricho/tparallel v0.2.1 h1:95FytivzT6rYzdJLdtfn6m1bfFJylOJK41+lgv/EHf4= github.com/moricho/tparallel v0.2.1/go.mod h1:fXEIZxG2vdfl0ZF8b42f5a78EhjjD5mX8qUplsoSU4k= github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= -github.com/mr-tron/base58 v1.1.1/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mr-tron/base58 v1.1.3/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= @@ -827,51 +653,29 @@ github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjW github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= github.com/multiformats/go-base32 v0.1.0 h1:pVx9xoSPqEIQG8o+UbAe7DNi51oej1NtK+aGkbLYxPE= github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYgtWibDcT0rExnbI= -github.com/multiformats/go-base36 v0.1.0/go.mod h1:kFGE83c6s80PklsHO9sRn2NCoffoRdUUOENyW/Vv6sM= github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0= github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4= -github.com/multiformats/go-multiaddr v0.0.1/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= -github.com/multiformats/go-multiaddr v0.0.2/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= -github.com/multiformats/go-multiaddr v0.0.4/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= -github.com/multiformats/go-multiaddr v0.1.0/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo= github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4= -github.com/multiformats/go-multiaddr v0.2.1/go.mod h1:s/Apk6IyxfvMjDafnhJgJ3/46z7tZ04iMk5wP4QMGGE= -github.com/multiformats/go-multiaddr v0.8.0 h1:aqjksEcqK+iD/Foe1RRFsGZh8+XFiGo7FgUCZlpv3LU= -github.com/multiformats/go-multiaddr v0.8.0/go.mod h1:Fs50eBDWvZu+l3/9S6xAE7ZYj6yhxlvaVZjakWN7xRs= -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.0.3/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= -github.com/multiformats/go-multiaddr-dns v0.1.0/go.mod h1:01k2RAqtoXIuPa3DCavAE9/6jc6nM0H3EgZyfUhN2oY= +github.com/multiformats/go-multiaddr v0.9.0 h1:3h4V1LHIk5w4hJHekMKWALPXErDfz/sggzwC/NcqbDQ= +github.com/multiformats/go-multiaddr v0.9.0/go.mod h1:mI67Lb1EeTOYb8GQfL/7wpIZwc46ElrvzhYnoJOmTT0= github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A= github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk= -github.com/multiformats/go-multiaddr-fmt v0.0.1/go.mod h1:aBYjqL4T/7j4Qx+R73XSv/8JsgnRFlf0w2KGLCmXl3Q= github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E= github.com/multiformats/go-multiaddr-fmt v0.1.0/go.mod h1:hGtDIW4PU4BqJ50gW2quDuPVjyWNZxToGUh/HwTZYJo= -github.com/multiformats/go-multiaddr-net v0.0.1/go.mod h1:nw6HSxNmCIQH27XPGBuX+d1tnvM7ihcFwHMSstNAVUU= -github.com/multiformats/go-multiaddr-net v0.1.0/go.mod h1:5JNbcfBOP4dnhoZOv10JJVkJO0pCCEf8mTnipAo2UZQ= github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= -github.com/multiformats/go-multibase v0.0.3/go.mod h1:5+1R4eQrT3PkYZ24C3W2Ue2tPwIdYQD509ZjSb5y9Oc= -github.com/multiformats/go-multibase v0.1.1 h1:3ASCDsuLX8+j4kx58qnJ4YFq/JWTJpCyDW27ztsVTOI= -github.com/multiformats/go-multibase v0.1.1/go.mod h1:ZEjHE+IsUrgp5mhlEAYjMtZwK1k4haNkcaPg9aoe1a8= +github.com/multiformats/go-multibase v0.2.0 h1:isdYCVLvksgWlMW9OZRYJEa9pZETFivncJHmHnnd87g= +github.com/multiformats/go-multibase v0.2.0/go.mod h1:bFBZX4lKCA/2lyOFSAoKH5SS6oPyjtnzK/XTFDPkNuk= github.com/multiformats/go-multicodec v0.8.1 h1:ycepHwavHafh3grIbR1jIXnKCsFm0fqsfEOsJ8NtKE8= github.com/multiformats/go-multicodec v0.8.1/go.mod h1:L3QTQvMIaVBkXOXXtVmYE+LI16i14xuaojr/H7Ai54k= -github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= -github.com/multiformats/go-multihash v0.0.5/go.mod h1:lt/HCbqlQwlPBz7lv0sQCdtfcMtlJvakRUn/0Ual8po= github.com/multiformats/go-multihash v0.0.8/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= -github.com/multiformats/go-multihash v0.0.10/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= github.com/multiformats/go-multihash v0.0.13/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= -github.com/multiformats/go-multihash v0.0.14/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= -github.com/multiformats/go-multihash v0.0.15/go.mod h1:D6aZrWNLFTV/ynMpKsNtB40mJzmCl4jb1alC0OvHiHg= github.com/multiformats/go-multihash v0.2.1 h1:aem8ZT0VA2nCHHk7bPJ1BjUbHNciqZC/d16Vve9l108= github.com/multiformats/go-multihash v0.2.1/go.mod h1:WxoMcYG85AZVQUyRyo9s4wULvW5qrI9vb2Lt6evduFc= -github.com/multiformats/go-multistream v0.1.0/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg= github.com/multiformats/go-multistream v0.4.1 h1:rFy0Iiyn3YT0asivDUIR05leAdwZq3de4741sbiSdfo= github.com/multiformats/go-multistream v0.4.1/go.mod h1:Mz5eykRVAjJWckE2U78c6xqdtyNUEhKSM0Lwar2p77Q= github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= -github.com/multiformats/go-varint v0.0.2/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= -github.com/multiformats/go-varint v0.0.6/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8= github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= @@ -890,16 +694,13 @@ github.com/nishanths/predeclared v0.2.2/go.mod h1:RROzoN6TnGQupbC+lqggsOlcgysk3L github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo/v2 v2.5.1 h1:auzK7OI497k6x4OvWq+TKAcpcSAlod0doAH72oIN0Jw= -github.com/onsi/ginkgo/v2 v2.5.1/go.mod h1:63DOGlLAH8+REH8jUGdL3YpCpu7JODesutUjdENfUAc= +github.com/onsi/ginkgo/v2 v2.9.2 h1:BA2GMJOtfGAfagzYtrAlufIP0lq6QERkFmHLMLPwFSU= +github.com/onsi/ginkgo/v2 v2.9.2/go.mod h1:WHcJJG2dIlcCqVfBAwUCrJxSPFb6v4azBwgxeMeDuts= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.24.0 h1:+0glovB9Jd6z3VR+ScSwQqXVTIfJcGA9UBM8yzQxhqg= +github.com/onsi/gomega v1.27.4 h1:Z2AnStgsdSayCMDiCU42qIz+HLqEPcgiOCXjAU/w+8E= github.com/opencontainers/runtime-spec v1.0.2 h1:UfAcuLBJB9Coz72x1hgl8O5RVzTdNiaglX6v2DM6FI0= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= @@ -911,7 +712,6 @@ github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT9 github.com/otiai10/mint v1.3.1/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc= 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/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pelletier/go-toml/v2 v2.0.2 h1:+jQXlF3scKIcSEKkdHzXhCTDLPFi5r1wnK6yPS+49Gw= @@ -926,8 +726,6 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/polydawn/refmt v0.0.0-20190221155625-df39d6c2d992/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= -github.com/polydawn/refmt v0.0.0-20190807091052-3d65705ee9f1/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= github.com/polydawn/refmt v0.89.0 h1:ADJTApkvkeBZsN0tBTx8QjpD9JkmxbKp0cxfr9qszm4= github.com/polydawn/refmt v0.89.0/go.mod h1:/zvteZs/GwLtCgZ4BL6CBsk9IKIlexP43ObX9AxTqTw= github.com/polyfloyd/go-errorlint v1.0.2 h1:kp1yvHflYhTmw5m3MmBy8SCyQkKPjwDthVuMH0ug6Yk= @@ -935,7 +733,6 @@ github.com/polyfloyd/go-errorlint v1.0.2/go.mod h1:APVvOesVSAnne5SClsPxPdfvZTVDo github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= @@ -949,21 +746,19 @@ github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvq github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= -github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE= -github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= +github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM= +github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo= -github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= +github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= +github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= github.com/quasilyte/go-ruleguard v0.3.1-0.20210203134552-1b5a410e1cc8/go.mod h1:KsAh3x0e7Fkpgs+Q9pNLS5XpFSvYCEVl5gP9Pp1xp30= github.com/quasilyte/go-ruleguard v0.3.17 h1:cDdoaSbQg11LXPDQqiCK54QmQXsEQQCTIgdcpeULGSI= github.com/quasilyte/go-ruleguard v0.3.17/go.mod h1:sST5PvaR7yb/Az5ksX8oc88usJ4EGjmJv7cK7y3jyig= @@ -979,10 +774,10 @@ github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 h1:M8mH9eK4OUR4l github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567/go.mod h1:DWNGW8A4Y+GyBgPuaQJuWiy0XYftx4Xm/y5Jqk9I6VQ= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= -github.com/quic-go/qtls-go1-19 v0.2.1 h1:aJcKNMkH5ASEJB9FXNeZCyTEIHU1J7MmHyz1Q1TSG1A= -github.com/quic-go/qtls-go1-19 v0.2.1/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI= -github.com/quic-go/qtls-go1-20 v0.1.1 h1:KbChDlg82d3IHqaj2bn6GfKRj84Per2VGf5XV3wSwQk= -github.com/quic-go/qtls-go1-20 v0.1.1/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= +github.com/quic-go/qtls-go1-19 v0.3.2 h1:tFxjCFcTQzK+oMxG6Zcvp4Dq8dx4yD3dDiIiyc86Z5U= +github.com/quic-go/qtls-go1-19 v0.3.2/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI= +github.com/quic-go/qtls-go1-20 v0.2.2 h1:WLOPx6OY/hxtTxKV1Zrq20FtXtDEkeY00CGQm8GEa3E= +github.com/quic-go/qtls-go1-20 v0.2.2/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= github.com/quic-go/quic-go v0.33.0 h1:ItNoTDN/Fm/zBlq769lLJc8ECe9gYaW40veHCCco7y0= github.com/quic-go/quic-go v0.33.0/go.mod h1:YMuhaAV9/jIu0XclDXwZPAsP/2Kgr5yMYhe9oxhhOFA= github.com/quic-go/webtransport-go v0.5.2 h1:GA6Bl6oZY+g/flt00Pnu0XtivSD8vukOu3lYhJjnGEk= @@ -1046,44 +841,31 @@ github.com/sivchari/nosnakecase v1.7.0 h1:7QkpWIRMe8x25gckkFd2A5Pi6Ymo0qgr4JrhGt github.com/sivchari/nosnakecase v1.7.0/go.mod h1:CwDzrzPea40/GB6uynrNLiorAlgFRvRbFSgJx2Gs+QY= github.com/sivchari/tenv v1.7.0 h1:d4laZMBK6jpe5PWepxlV9S+LC0yXqvYHiq8E6ceoVVE= github.com/sivchari/tenv v1.7.0/go.mod h1:64yStXKSOxDfX47NlhVwND4dHwfZDdbp2Lyl018Icvg= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/assertions v1.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N3yZFZkDFs= github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo= -github.com/smartystreets/goconvey v0.0.0-20190222223459-a17d461953aa/go.mod h1:2RVY1rIf+2J2o/IM9+vPq9RzmHDSseB7FoXiSNIUsoU= -github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/smartystreets/goconvey v1.7.2 h1:9RBaZCeXEQ3UselpuwUQHltGVXvdwm6cv1hgR6gDIPg= github.com/smartystreets/goconvey v1.7.2/go.mod h1:Vw0tHAZW6lzCRk3xgdin6fKYcG+G3Pg9vgXWeJpQFMM= -github.com/smola/gocompat v0.2.0/go.mod h1:1B0MlxbmoZNo3h8guHp8HztB3BSYR5itql9qtVc0ypY= github.com/sonatard/noctx v0.0.1 h1:VC1Qhl6Oxx9vvWo3UDgrGXYCeKCe3Wbw7qAWL6FrmTY= github.com/sonatard/noctx v0.0.1/go.mod h1:9D2D/EoULe8Yy2joDHJj7bv3sZoq9AaSb8B4lqBjiZI= github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE= github.com/sourcegraph/go-diff v0.6.1 h1:hmA1LzxW0n1c3Q4YbrFgg4P99GSnebYa3x8gr0HZqLQ= github.com/sourcegraph/go-diff v0.6.1/go.mod h1:iBszgVvyxdc8SFZ7gm69go2KDdt3ag071iBaWPF6cjs= github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA= -github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a/go.mod h1:7AyxJNCJ7SBZ1MfVQCWD6Uqo2oubI2Eq2y2eqf+A5r0= -github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU= -github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.8.2 h1:xehSyVa0YnHWsJ49JFljMpg1HX19V6NDZ1fkm1Xznbo= github.com/spf13/afero v1.8.2/go.mod h1:CtAatgMJh6bJEIs48Ay/FOnkljP3WeGUG0MC1RfAqwo= -github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= -github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/cobra v1.5.0 h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU= github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM= -github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/spf13/viper v1.12.0 h1:CZ7eSOd3kZoaYDLbXnmzgQI5RlciuXBMA+18HwHRfZQ= github.com/spf13/viper v1.12.0/go.mod h1:b6COn30jlNxbm/V2IqWiNWkJ+vZNiMNksliPCiuKtSI= -github.com/src-d/envconfig v1.0.0/go.mod h1:Q9YQZ7BKITldTBnoxsE5gOeB5y66RyPXeue/R4aaNBc= github.com/ssgreg/nlreturn/v2 v2.2.1 h1:X4XDI7jstt3ySqGU86YGAURbxw3oTDPK9sPEi6YEwQ0= github.com/ssgreg/nlreturn/v2 v2.2.1/go.mod h1:E/iiPB78hV7Szg2YfRgyIrk1AD6JVMTRkkxBiELzh2I= github.com/stbenjam/no-sprintf-host-port v0.1.1 h1:tYugd/yrm1O0dV+ThCbaKZh195Dfm07ysF0U6JQXczc= @@ -1098,6 +880,7 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= @@ -1108,7 +891,6 @@ github.com/subosito/gotenv v1.4.0 h1:yAzM1+SmVcz5R4tXGsNMu1jUl2aOJXoiWUCEwwnGrvs github.com/subosito/gotenv v1.4.0/go.mod h1:mZd6rFysKEcUhUHXJk0C/08wAgyDBFuwEYL7vWWGaGo= github.com/sylvia7788/contextcheck v1.0.6 h1:o2EZgVPyMKE/Mtoqym61DInKEjwEbsmyoxg3VrmjNO4= github.com/sylvia7788/contextcheck v1.0.6/go.mod h1:9XDxwvxyuKD+8N+a7Gs7bfWLityh5t70g/GjdEt2N2M= -github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= github.com/tdakkota/asciicheck v0.1.1 h1:PKzG7JUTUmVspQTDqtkX9eSiLGossXTybutHwTXuO0A= github.com/tdakkota/asciicheck v0.1.1/go.mod h1:yHp0ai0Z9gUljN3o0xMhYJnH/IcvkdTBOX2fmJ93JEM= @@ -1128,7 +910,6 @@ github.com/tommy-muehle/go-mnd/v2 v2.5.0 h1:iAj0a8e6+dXSL7Liq0aXPox36FiN1dBbjA6l github.com/tommy-muehle/go-mnd/v2 v2.5.0/go.mod h1:WsUAkMJMYww6l/ufffCD3m+P7LEvr8TnZn9lwVDlgzw= github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= -github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/ultraware/funlen v0.0.3 h1:5ylVWm8wsNwH5aWo9438pwvsK0QiqVuUrt9bn7S/iLA= @@ -1144,27 +925,11 @@ github.com/uudashr/gocognit v1.0.6/go.mod h1:nAIUuVBnYU7pcninia3BHOvQkpQCeO76Usc github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU= github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM= github.com/warpfork/go-testmark v0.11.0 h1:J6LnV8KpceDvo7spaNU4+DauH2n1x+6RaO2rJrmpQ9U= -github.com/warpfork/go-wish v0.0.0-20180510122957-5ad1f5abf436/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= -github.com/warpfork/go-wish v0.0.0-20200122115046-b9ea61034e4a/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0 h1:GDDkbFiaK8jsSDJfjId/PEGEShv6ugrt4kYsC5UIDaQ= github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= -github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc/go.mod h1:r45hJU7yEoA81k6MWNhpMj/kms0n14dkzkxYHoB96UM= github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11 h1:5HZfQkwe0mIfyDmc1Em5GqlNRzcdtlv4HTNmdpt7XH0= -github.com/whyrusleeping/cbor-gen v0.0.0-20200123233031-1cdf64d27158/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI= github.com/whyrusleeping/cbor-gen v0.0.0-20230126041949-52956bd4c9aa h1:EyA027ZAkuaCLoxVX4r1TZMPy1d31fM6hbfQ4OU4I5o= -github.com/whyrusleeping/cbor-gen v0.0.0-20230126041949-52956bd4c9aa/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f h1:jQa4QT2UP9WYv2nzyawpKMOCl+Z/jW7djv2/J50lj9E= -github.com/whyrusleeping/go-ctrlnet v0.0.0-20180313164037-f564fbbdaa95/go.mod h1:SJqKCCPXRfBFCwXjfNT/skfsceF7+MBFLI2OrvuRA7g= -github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc= -github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= -github.com/whyrusleeping/go-notifier v0.0.0-20170827234753-097c5d47330f/go.mod h1:cZNvX9cFybI01GriPRMXDtczuvUhgbcYr9iCGaNlRv8= -github.com/whyrusleeping/mafmt v1.2.8/go.mod h1:faQJFPbLSxzD9xpA02ttW/tS9vZykNvXwGvqIpk20FA= -github.com/whyrusleeping/mdns v0.0.0-20180901202407-ef14215e6b30/go.mod h1:j4l84WPFclQPj320J9gp0XwNKBb3U0zt5CBqjPp22G4= -github.com/whyrusleeping/mdns v0.0.0-20190826153040-b9b60ed33aa9/go.mod h1:j4l84WPFclQPj320J9gp0XwNKBb3U0zt5CBqjPp22G4= -github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7/go.mod h1:X2c0RVCI1eSUFI8eLcY3c0423ykwiUdxLJtkDvruhjI= -github.com/whyrusleeping/timecache v0.0.0-20160911033111-cfcb2f1abfee/go.mod h1:m2aV4LZI4Aez7dP5PMyVKEHhUyEJ/RjmPEDOpDvudHg= -github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE= -github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/yagipy/maintidx v1.0.0 h1:h5NvIsCz+nRDapQ0exNv4aJ0yXSI0420omVANTv3GJM= github.com/yagipy/maintidx v1.0.0/go.mod h1:0qNf/I/CCZXSMhsRsrEPDZ+DkekpKLXAJfsTACwgXLk= github.com/yeya24/promlinter v0.2.0 h1:xFKDQ82orCU5jQujdaD8stOHiv8UN68BSdn2a8u8Y3o= @@ -1181,30 +946,29 @@ gitlab.com/bosi/decorder v0.2.3/go.mod h1:9K1RB5+VPNQYtXtTDAzd2OEftsZb1oV0IrJrzC go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= -go.opencensus.io v0.22.1/go.mod h1:Ap50jQcDJrx6rB6VgeeFPtuPIf3wMRvRfrfYDO6+BmA= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opentelemetry.io/otel v1.14.0 h1:/79Huy8wbf5DnIPhemGB+zEPVwnN6fuQybr/SRXa6hM= go.opentelemetry.io/otel v1.14.0/go.mod h1:o4buv+dJzx8rohcUeRmWUZhqupFvzWis188WlggnNeU= -go.opentelemetry.io/otel/sdk v1.2.0 h1:wKN260u4DesJYhyjxDa7LRFkuhH7ncEVKU37LWcyNIo= +go.opentelemetry.io/otel/sdk v1.14.0 h1:PDCppFRDq8A1jL9v6KMI6dYesaq+DFcDZvjsoGvxGzY= go.opentelemetry.io/otel/trace v1.14.0 h1:wp2Mmvj41tDsyAJXiWDWpfNsOiIyd38fy85pyKcFq/M= go.opentelemetry.io/otel/trace v1.14.0/go.mod h1:8avnQLK+CG77yNLUae4ea2JDQ6iT+gozhnZjy/rw9G8= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/dig v1.15.0 h1:vq3YWr8zRj1eFGC7Gvf907hE0eRjPTZ1d3xHadD6liE= -go.uber.org/dig v1.15.0/go.mod h1:pKHs0wMynzL6brANhB2hLMro+zalv1osARTviTcqHLM= -go.uber.org/fx v1.18.2 h1:bUNI6oShr+OVFQeU8cDNbnN7VFsu+SsjHzUF51V/GAU= -go.uber.org/fx v1.18.2/go.mod h1:g0V1KMQ66zIRk8bLu3Ea5Jt2w/cHlOIp4wdRsgh0JaY= +go.uber.org/dig v1.17.0 h1:5Chju+tUvcC+N7N6EV08BJz41UZuO3BmHcN4A287ZLI= +go.uber.org/dig v1.17.0/go.mod h1:rTxpf7l5I0eBTlE6/9RL+lDybC7WFwY2QH55ZSjy1mU= +go.uber.org/fx v1.19.2 h1:SyFgYQFr1Wl0AYstE8vyYIzP4bFz2URrScjwC4cwUvY= +go.uber.org/fx v1.19.2/go.mod h1:43G1VcqSzbIv77y00p1DRAsyZS8WdzuYdhZXmEUkMyQ= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= -go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= -go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= @@ -1212,32 +976,22 @@ go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw= -golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20190228161510-8dd112bcdc25/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190618222545-ea8f1a30c443/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200602180216-279210d13fed/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc= -golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= +golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g= +golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1248,8 +1002,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20230213192124-5e25df0256eb h1:PaBZQdo+iSDyHT053FjUCgZQ/9uqVwPOcl7KSWhKn6w= -golang.org/x/exp v0.0.0-20230213192124-5e25df0256eb/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= +golang.org/x/exp v0.0.0-20230321023759-10a507213a29 h1:ooxPy7fPvB4kwsA2h+iBNHkAbp/4JxTSwCmvdjEYmug= +golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= golang.org/x/exp/typeparams v0.0.0-20220428152302-39d4317da171/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/exp/typeparams v0.0.0-20220613132600-b0d781184e0d h1:+W8Qf4iJtMGKkyAygcKohjxTk4JPsL9DpzApJ22m5Ic= golang.org/x/exp/typeparams v0.0.0-20220613132600-b0d781184e0d/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= @@ -1281,8 +1035,8 @@ golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA= -golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk= +golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1292,7 +1046,6 @@ golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -1325,13 +1078,10 @@ golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= -golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1344,7 +1094,6 @@ golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1366,10 +1115,7 @@ golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1380,10 +1126,7 @@ golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1416,7 +1159,6 @@ golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1426,7 +1168,6 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211105183446-c75c47738b0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220702020025-31831981b65f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1435,13 +1176,13 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= +golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY= -golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1450,19 +1191,17 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181130052023-1c3d964395ce/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190307163923-6a08e3108db3/go.mod h1:25r3+/G6/xytQM8iWZKq3Hn0kr0rgFKPUNVEL/dr3z4= @@ -1541,20 +1280,18 @@ golang.org/x/tools v0.1.1-0.20210205202024-ef80cdb6ec6d/go.mod h1:9bzcO0MWcOuT0t golang.org/x/tools v0.1.1-0.20210302220138-2ac05c832e1a/go.mod h1:9bzcO0MWcOuT0tm1iBGzDVPshzfwoVvREIui8C+MHqU= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.9-0.20211228192929-ee1ca4ffc4da/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/tools v0.1.11/go.mod h1:SgwaegtQh8clINPpECJMqnxLv9I09HLqnW3RMqW0CA4= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.3.0 h1:SrNbZl6ECOS1qFzgTdQfWXZM9XBkiA6tkFrH9YSTPHM= -golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= +golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4= +golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= -golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y= @@ -1657,8 +1394,8 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= -google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= +google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -1673,8 +1410,6 @@ gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKW gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.66.6 h1:LATuAqN/shcYAOkv3wl2L4rkaKqkcgTBQjOyYDvcPKI= gopkg.in/ini.v1 v1.66.6/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/src-d/go-cli.v0 v0.0.0-20181105080154-d492247bbc0d/go.mod h1:z+K8VcOYVYcSwSjGebuDL6176A1XskgbtNl64NSg+n8= -gopkg.in/src-d/go-log.v1 v1.0.1/go.mod h1:GN34hKP0g305ysm2/hctJ0Y8nWP3zxXXJ8GFabTyABE= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= From 30f5e54e19a1497c6060b4ff8daabc013796ed76 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Thu, 8 Jun 2023 12:34:23 +0200 Subject: [PATCH 0707/1212] chore: update dependencies ahead of 0.21 release --- docs/examples/kubo-as-a-library/go.mod | 24 +++++------ docs/examples/kubo-as-a-library/go.sum | 51 +++++++++++----------- go.mod | 26 ++++++------ go.sum | 53 +++++++++++------------ test/dependencies/go.mod | 26 ++++++------ test/dependencies/go.sum | 58 +++++++++++++------------- 6 files changed, 119 insertions(+), 119 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 8edf08a2f..ce14f58c3 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,9 +7,9 @@ go 1.18 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.8.2-0.20230608080412-e44e658cb393 + github.com/ipfs/boxo v0.9.0 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 - github.com/libp2p/go-libp2p v0.27.3 + github.com/libp2p/go-libp2p v0.27.5 github.com/multiformats/go-multiaddr v0.9.0 ) @@ -30,7 +30,7 @@ require ( github.com/crackcomm/go-gitignore v0.0.0-20170627025303-887ab5e44cc3 // indirect github.com/cskr/pubsub v1.0.2 // indirect github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect - github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect github.com/dgraph-io/badger v1.6.2 // indirect github.com/dgraph-io/ristretto v0.0.2 // indirect github.com/docker/go-units v0.5.0 // indirect @@ -40,7 +40,7 @@ require ( github.com/flynn/noise v1.0.0 // indirect github.com/francoispqt/gojay v1.2.13 // indirect github.com/gabriel-vasile/mimetype v1.4.1 // indirect - github.com/go-logr/logr v1.2.3 // indirect + github.com/go-logr/logr v1.2.4 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/godbus/dbus/v5 v5.1.0 // indirect @@ -78,7 +78,7 @@ require ( github.com/ipfs/go-ipfs-files v0.3.0 // indirect github.com/ipfs/go-ipfs-pq v0.0.3 // indirect github.com/ipfs/go-ipfs-redirects-file v0.1.1 // indirect - github.com/ipfs/go-ipfs-util v0.0.2 // indirect + github.com/ipfs/go-ipfs-util v0.0.3 // indirect github.com/ipfs/go-ipld-cbor v0.0.6 // indirect github.com/ipfs/go-ipld-format v0.5.0 // indirect github.com/ipfs/go-ipld-git v0.1.1 // indirect @@ -95,7 +95,7 @@ require ( github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect github.com/jbenet/goprocess v0.1.4 // indirect github.com/klauspost/compress v1.16.4 // indirect - github.com/klauspost/cpuid/v2 v2.2.4 // indirect + github.com/klauspost/cpuid/v2 v2.2.5 // indirect github.com/koron/go-ssdp v0.0.4 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/libp2p/go-cidranger v1.1.0 // indirect @@ -117,12 +117,12 @@ require ( github.com/libp2p/go-yamux/v4 v4.0.0 // indirect github.com/libp2p/zeroconf/v2 v2.2.0 // indirect github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect - github.com/mattn/go-isatty v0.0.18 // indirect + github.com/mattn/go-isatty v0.0.19 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/miekg/dns v1.1.53 // indirect github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect - github.com/minio/sha256-simd v1.0.0 // indirect + github.com/minio/sha256-simd v1.0.1 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mr-tron/base58 v1.2.0 // indirect github.com/multiformats/go-base32 v0.1.0 // indirect @@ -130,8 +130,8 @@ require ( github.com/multiformats/go-multiaddr-dns v0.3.1 // indirect github.com/multiformats/go-multiaddr-fmt v0.1.0 // indirect github.com/multiformats/go-multibase v0.2.0 // indirect - github.com/multiformats/go-multicodec v0.8.1 // indirect - github.com/multiformats/go-multihash v0.2.1 // indirect + github.com/multiformats/go-multicodec v0.9.0 // indirect + github.com/multiformats/go-multihash v0.2.2 // indirect github.com/multiformats/go-multistream v0.4.1 // indirect github.com/multiformats/go-varint v0.0.7 // indirect github.com/onsi/ginkgo/v2 v2.9.2 // indirect @@ -172,7 +172,7 @@ require ( go.opentelemetry.io/otel/sdk v1.14.0 // indirect go.opentelemetry.io/otel/trace v1.14.0 // indirect go.opentelemetry.io/proto/otlp v0.19.0 // indirect - go.uber.org/atomic v1.10.0 // indirect + go.uber.org/atomic v1.11.0 // indirect go.uber.org/dig v1.17.0 // indirect go.uber.org/fx v1.19.2 // indirect go.uber.org/multierr v1.11.0 // indirect @@ -192,6 +192,6 @@ require ( google.golang.org/grpc v1.53.0 // indirect google.golang.org/protobuf v1.30.0 // indirect gopkg.in/square/go-jose.v2 v2.5.1 // indirect - lukechampine.com/blake3 v1.1.7 // indirect + lukechampine.com/blake3 v1.2.1 // indirect nhooyr.io/websocket v1.8.7 // indirect ) diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 727546d53..3756be266 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -121,9 +121,9 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c h1:pFUpOrbxDR6AkioZ1ySsx5yxlDQZ8stG2b88gTPxgJU= github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c/go.mod h1:6UhI8N9EjYm1c2odKpFpAYeR8dsBeM7PtzQhRgxRr9U= -github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 h1:HbphB4TFFXpv7MNrT52FGrrgVXF1owhMVTHFZIlnvd4= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0/go.mod h1:DZGJHZMqrU4JJqFAWUS2UO1+lbSKsdiOoYi9Zzey7Fc= +github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= github.com/dgraph-io/badger v1.6.2 h1:mNw0qs90GVgGGWylh0umH5iag1j6n/PeJtNvL6KY/x8= github.com/dgraph-io/badger v1.6.2/go.mod h1:JW2yswe3V058sS0kZ2h/AXeDSqFjxnZcRrVH//y2UQE= @@ -174,8 +174,8 @@ github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= -github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= +github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= @@ -319,8 +319,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.8.2-0.20230608080412-e44e658cb393 h1:o3l1Rq7NwXT//tOgd0k+JOYTQgvg+WhgKoLy8tJfLxk= -github.com/ipfs/boxo v0.8.2-0.20230608080412-e44e658cb393/go.mod h1:ic5+bhD5T+A9n0HMkXYHiTzpjjaAZaPeKRQ9dWethTs= +github.com/ipfs/boxo v0.9.0 h1:Gb3KGXOZ4J5eCZTsky33tx2oHztrfBo+2IFq6lxmoGM= +github.com/ipfs/boxo v0.9.0/go.mod h1:ic5+bhD5T+A9n0HMkXYHiTzpjjaAZaPeKRQ9dWethTs= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= @@ -380,8 +380,9 @@ github.com/ipfs/go-ipfs-pq v0.0.3/go.mod h1:btNw5hsHBpRcSSgZtiNm/SLj5gYIZ18AKtv3 github.com/ipfs/go-ipfs-redirects-file v0.1.1 h1:Io++k0Vf/wK+tfnhEh63Yte1oQK5VGT2hIEYpD0Rzx8= github.com/ipfs/go-ipfs-redirects-file v0.1.1/go.mod h1:tAwRjCV0RjLTjH8DR/AU7VYvfQECg+lpUy2Mdzv7gyk= github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyBCNzQxlJBc= -github.com/ipfs/go-ipfs-util v0.0.2 h1:59Sswnk1MFaiq+VcaknX7aYEyGyGDAA73ilhEK2POp8= github.com/ipfs/go-ipfs-util v0.0.2/go.mod h1:CbPtkWJzjLdEcezDns2XYaehFVNXG9zrdrtMecczcsQ= +github.com/ipfs/go-ipfs-util v0.0.3 h1:2RFdGez6bu2ZlZdI+rWfIdbQb1KudQp3VGwPtdNCmE0= +github.com/ipfs/go-ipfs-util v0.0.3/go.mod h1:LHzG1a0Ig4G+iZ26UUOMjHd+lfM84LZCrn17xAKWBvs= github.com/ipfs/go-ipld-cbor v0.0.6 h1:pYuWHyvSpIsOOLw4Jy7NbBkCyzLDcl64Bf/LZW7eBQ0= github.com/ipfs/go-ipld-cbor v0.0.6/go.mod h1:ssdxxaLJPXH7OjF5V4NSjBbcfh+evoR4ukuru0oPXMA= github.com/ipfs/go-ipld-format v0.0.1/go.mod h1:kyJtbkDALmFHv3QR6et67i35QzO3S0dCDnkOJhcZkms= @@ -454,8 +455,8 @@ github.com/klauspost/compress v1.16.4 h1:91KN02FnsOYhuunwU4ssRe8lc2JosWmizWa91B5 github.com/klauspost/compress v1.16.4/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk= -github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= +github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= +github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/koron/go-ssdp v0.0.0-20191105050749-2e1c40ed0b5d/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk= github.com/koron/go-ssdp v0.0.4 h1:1IDwrghSKYM7yLf7XCzbByg2sJ/JcNOZRXS2jczTwz0= @@ -484,8 +485,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.27.3 h1:tkV/zm3KCZ4R5er9Xcs2pt0YNB4JH0iBfGAtHJdLHRs= -github.com/libp2p/go-libp2p v0.27.3/go.mod h1:FAvvfQa/YOShUYdiSS03IR9OXzkcJXwcNA2FUCh9ImE= +github.com/libp2p/go-libp2p v0.27.5 h1:KwA7pXKXpz8hG6Cr1fMA7UkgleogcwQj0sxl5qquWRg= +github.com/libp2p/go-libp2p v0.27.5/go.mod h1:oMfQGTb9CHnrOuSM6yMmyK2lXz3qIhnkn2+oK3B1Y2g= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= @@ -539,8 +540,8 @@ github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hd github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-isatty v0.0.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp98= -github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= +github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= @@ -560,8 +561,9 @@ github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8Rv github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= -github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g= github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM= +github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM= +github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= @@ -598,8 +600,8 @@ github.com/multiformats/go-multibase v0.0.3/go.mod h1:5+1R4eQrT3PkYZ24C3W2Ue2tPw github.com/multiformats/go-multibase v0.2.0 h1:isdYCVLvksgWlMW9OZRYJEa9pZETFivncJHmHnnd87g= github.com/multiformats/go-multibase v0.2.0/go.mod h1:bFBZX4lKCA/2lyOFSAoKH5SS6oPyjtnzK/XTFDPkNuk= github.com/multiformats/go-multicodec v0.3.0/go.mod h1:qGGaQmioCDh+TeFOnxrbU0DaIPw8yFgAZgFG0V7p1qQ= -github.com/multiformats/go-multicodec v0.8.1 h1:ycepHwavHafh3grIbR1jIXnKCsFm0fqsfEOsJ8NtKE8= -github.com/multiformats/go-multicodec v0.8.1/go.mod h1:L3QTQvMIaVBkXOXXtVmYE+LI16i14xuaojr/H7Ai54k= +github.com/multiformats/go-multicodec v0.9.0 h1:pb/dlPnzee/Sxv/j4PmkDRxCOi3hXTz3IbPKOXWJkmg= +github.com/multiformats/go-multicodec v0.9.0/go.mod h1:L3QTQvMIaVBkXOXXtVmYE+LI16i14xuaojr/H7Ai54k= github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= github.com/multiformats/go-multihash v0.0.8/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= github.com/multiformats/go-multihash v0.0.10/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= @@ -607,8 +609,8 @@ github.com/multiformats/go-multihash v0.0.13/go.mod h1:VdAWLKTwram9oKAatUcLxBNUj github.com/multiformats/go-multihash v0.0.14/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= github.com/multiformats/go-multihash v0.0.15/go.mod h1:D6aZrWNLFTV/ynMpKsNtB40mJzmCl4jb1alC0OvHiHg= github.com/multiformats/go-multihash v0.1.0/go.mod h1:RJlXsxt6vHGaia+S8We0ErjhojtKzPP2AH4+kYM7k84= -github.com/multiformats/go-multihash v0.2.1 h1:aem8ZT0VA2nCHHk7bPJ1BjUbHNciqZC/d16Vve9l108= -github.com/multiformats/go-multihash v0.2.1/go.mod h1:WxoMcYG85AZVQUyRyo9s4wULvW5qrI9vb2Lt6evduFc= +github.com/multiformats/go-multihash v0.2.2 h1:Uu7LWs/PmWby1gkj1S1DXx3zyd3aVabA4FiMKn/2tAc= +github.com/multiformats/go-multihash v0.2.2/go.mod h1:dXgKXCXjBzdscBLk9JkjINiEsCKRVch90MdaGiKsvSM= github.com/multiformats/go-multistream v0.4.1 h1:rFy0Iiyn3YT0asivDUIR05leAdwZq3de4741sbiSdfo= github.com/multiformats/go-multistream v0.4.1/go.mod h1:Mz5eykRVAjJWckE2U78c6xqdtyNUEhKSM0Lwar2p77Q= github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= @@ -748,7 +750,7 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= +github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY= github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= @@ -832,8 +834,8 @@ go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= -go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= +go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= +go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/dig v1.17.0 h1:5Chju+tUvcC+N7N6EV08BJz41UZuO3BmHcN4A287ZLI= go.uber.org/dig v1.17.0/go.mod h1:rTxpf7l5I0eBTlE6/9RL+lDybC7WFwY2QH55ZSjy1mU= go.uber.org/fx v1.19.2 h1:SyFgYQFr1Wl0AYstE8vyYIzP4bFz2URrScjwC4cwUvY= @@ -1036,7 +1038,6 @@ golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1261,8 +1262,8 @@ honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= lukechampine.com/blake3 v1.1.6/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= -lukechampine.com/blake3 v1.1.7 h1:GgRMhmdsuK8+ii6UZFDL8Nb+VyMwadAgcJyfYHxG6n0= -lukechampine.com/blake3 v1.1.7/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= +lukechampine.com/blake3 v1.2.1 h1:YuqqRuaqsGV71BV/nm9xlI0MKUv4QC54jQnBChWbGnI= +lukechampine.com/blake3 v1.2.1/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g= nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= pgregory.net/rapid v0.4.7 h1:MTNRktPuv5FNqOO151TM9mDTa+XHcX6ypYeISDVD14g= diff --git a/go.mod b/go.mod index 4613c2ebf..2d8266005 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/gogo/protobuf v1.3.2 github.com/google/uuid v1.3.0 github.com/hashicorp/go-multierror v1.1.1 - github.com/ipfs/boxo v0.8.2-0.20230608080412-e44e658cb393 + github.com/ipfs/boxo v0.9.0 github.com/ipfs/go-block-format v0.1.2 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 @@ -45,7 +45,7 @@ require ( github.com/jbenet/goprocess v0.1.4 github.com/julienschmidt/httprouter v1.3.0 github.com/libp2p/go-doh-resolver v0.4.0 - github.com/libp2p/go-libp2p v0.27.3 + github.com/libp2p/go-libp2p v0.27.5 github.com/libp2p/go-libp2p-http v0.5.0 github.com/libp2p/go-libp2p-kad-dht v0.23.0 github.com/libp2p/go-libp2p-kbucket v0.5.0 @@ -59,13 +59,13 @@ require ( github.com/multiformats/go-multiaddr v0.9.0 github.com/multiformats/go-multiaddr-dns v0.3.1 github.com/multiformats/go-multibase v0.2.0 - github.com/multiformats/go-multicodec v0.8.1 - github.com/multiformats/go-multihash v0.2.1 + github.com/multiformats/go-multicodec v0.9.0 + github.com/multiformats/go-multihash v0.2.2 github.com/opentracing/opentracing-go v1.2.0 github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.14.0 - github.com/stretchr/testify v1.8.2 + github.com/stretchr/testify v1.8.3 github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 github.com/tidwall/gjson v1.14.4 github.com/tidwall/sjson v1.2.5 @@ -101,7 +101,7 @@ require ( github.com/cskr/pubsub v1.0.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect - github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect github.com/dgraph-io/badger v1.6.2 // indirect github.com/dgraph-io/ristretto v0.0.2 // indirect github.com/docker/go-units v0.5.0 // indirect @@ -112,7 +112,7 @@ require ( github.com/gabriel-vasile/mimetype v1.4.1 // indirect github.com/go-kit/log v0.2.1 // indirect github.com/go-logfmt/logfmt v0.5.1 // indirect - github.com/go-logr/logr v1.2.3 // indirect + github.com/go-logr/logr v1.2.4 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/godbus/dbus/v5 v5.1.0 // indirect @@ -136,14 +136,14 @@ require ( github.com/ipfs/go-ipfs-ds-help v1.1.0 // indirect github.com/ipfs/go-ipfs-pq v0.0.3 // indirect github.com/ipfs/go-ipfs-redirects-file v0.1.1 // indirect - github.com/ipfs/go-ipfs-util v0.0.2 // indirect + github.com/ipfs/go-ipfs-util v0.0.3 // indirect github.com/ipfs/go-ipld-cbor v0.0.6 // indirect github.com/ipfs/go-libipfs v0.7.0 // indirect github.com/ipfs/go-peertaskqueue v0.8.1 // indirect github.com/ipld/edelweiss v0.2.0 // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/klauspost/compress v1.16.4 // indirect - github.com/klauspost/cpuid/v2 v2.2.4 // indirect + github.com/klauspost/cpuid/v2 v2.2.5 // indirect github.com/koron/go-ssdp v0.0.4 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/libp2p/go-cidranger v1.1.0 // indirect @@ -160,14 +160,14 @@ require ( github.com/libp2p/zeroconf/v2 v2.2.0 // indirect github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect github.com/mattn/go-colorable v0.1.4 // indirect - github.com/mattn/go-isatty v0.0.18 // indirect + github.com/mattn/go-isatty v0.0.19 // indirect github.com/mattn/go-runewidth v0.0.4 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect github.com/miekg/dns v1.1.53 // indirect github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect - github.com/minio/sha256-simd v1.0.0 // indirect + github.com/minio/sha256-simd v1.0.1 // indirect github.com/mr-tron/base58 v1.2.0 // indirect github.com/multiformats/go-base32 v0.1.0 // indirect github.com/multiformats/go-base36 v0.2.0 // indirect @@ -213,7 +213,7 @@ require ( go.opentelemetry.io/otel/exporters/zipkin v1.14.0 // indirect go.opentelemetry.io/otel/metric v0.37.0 // indirect go.opentelemetry.io/proto/otlp v0.19.0 // indirect - go.uber.org/atomic v1.10.0 // indirect + go.uber.org/atomic v1.11.0 // indirect go4.org v0.0.0-20230225012048-214862532bf5 // indirect golang.org/x/net v0.10.0 // indirect golang.org/x/oauth2 v0.5.0 // indirect @@ -229,7 +229,7 @@ require ( gopkg.in/square/go-jose.v2 v2.5.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - lukechampine.com/blake3 v1.1.7 // indirect + lukechampine.com/blake3 v1.2.1 // indirect nhooyr.io/websocket v1.8.7 // indirect ) diff --git a/go.sum b/go.sum index 3c503b9c0..5ab048972 100644 --- a/go.sum +++ b/go.sum @@ -135,9 +135,9 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c h1:pFUpOrbxDR6AkioZ1ySsx5yxlDQZ8stG2b88gTPxgJU= github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c/go.mod h1:6UhI8N9EjYm1c2odKpFpAYeR8dsBeM7PtzQhRgxRr9U= -github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 h1:HbphB4TFFXpv7MNrT52FGrrgVXF1owhMVTHFZIlnvd4= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0/go.mod h1:DZGJHZMqrU4JJqFAWUS2UO1+lbSKsdiOoYi9Zzey7Fc= +github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= github.com/dgraph-io/badger v1.6.2 h1:mNw0qs90GVgGGWylh0umH5iag1j6n/PeJtNvL6KY/x8= github.com/dgraph-io/badger v1.6.2/go.mod h1:JW2yswe3V058sS0kZ2h/AXeDSqFjxnZcRrVH//y2UQE= @@ -206,8 +206,8 @@ github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA= github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= -github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= +github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= @@ -354,8 +354,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.8.2-0.20230608080412-e44e658cb393 h1:o3l1Rq7NwXT//tOgd0k+JOYTQgvg+WhgKoLy8tJfLxk= -github.com/ipfs/boxo v0.8.2-0.20230608080412-e44e658cb393/go.mod h1:ic5+bhD5T+A9n0HMkXYHiTzpjjaAZaPeKRQ9dWethTs= +github.com/ipfs/boxo v0.9.0 h1:Gb3KGXOZ4J5eCZTsky33tx2oHztrfBo+2IFq6lxmoGM= +github.com/ipfs/boxo v0.9.0/go.mod h1:ic5+bhD5T+A9n0HMkXYHiTzpjjaAZaPeKRQ9dWethTs= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= @@ -416,8 +416,9 @@ github.com/ipfs/go-ipfs-pq v0.0.3/go.mod h1:btNw5hsHBpRcSSgZtiNm/SLj5gYIZ18AKtv3 github.com/ipfs/go-ipfs-redirects-file v0.1.1 h1:Io++k0Vf/wK+tfnhEh63Yte1oQK5VGT2hIEYpD0Rzx8= github.com/ipfs/go-ipfs-redirects-file v0.1.1/go.mod h1:tAwRjCV0RjLTjH8DR/AU7VYvfQECg+lpUy2Mdzv7gyk= github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyBCNzQxlJBc= -github.com/ipfs/go-ipfs-util v0.0.2 h1:59Sswnk1MFaiq+VcaknX7aYEyGyGDAA73ilhEK2POp8= github.com/ipfs/go-ipfs-util v0.0.2/go.mod h1:CbPtkWJzjLdEcezDns2XYaehFVNXG9zrdrtMecczcsQ= +github.com/ipfs/go-ipfs-util v0.0.3 h1:2RFdGez6bu2ZlZdI+rWfIdbQb1KudQp3VGwPtdNCmE0= +github.com/ipfs/go-ipfs-util v0.0.3/go.mod h1:LHzG1a0Ig4G+iZ26UUOMjHd+lfM84LZCrn17xAKWBvs= github.com/ipfs/go-ipld-cbor v0.0.6 h1:pYuWHyvSpIsOOLw4Jy7NbBkCyzLDcl64Bf/LZW7eBQ0= github.com/ipfs/go-ipld-cbor v0.0.6/go.mod h1:ssdxxaLJPXH7OjF5V4NSjBbcfh+evoR4ukuru0oPXMA= github.com/ipfs/go-ipld-format v0.0.1/go.mod h1:kyJtbkDALmFHv3QR6et67i35QzO3S0dCDnkOJhcZkms= @@ -503,8 +504,8 @@ github.com/klauspost/compress v1.16.4 h1:91KN02FnsOYhuunwU4ssRe8lc2JosWmizWa91B5 github.com/klauspost/compress v1.16.4/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk= -github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= +github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= +github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/koron/go-ssdp v0.0.0-20191105050749-2e1c40ed0b5d/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk= @@ -535,8 +536,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.27.3 h1:tkV/zm3KCZ4R5er9Xcs2pt0YNB4JH0iBfGAtHJdLHRs= -github.com/libp2p/go-libp2p v0.27.3/go.mod h1:FAvvfQa/YOShUYdiSS03IR9OXzkcJXwcNA2FUCh9ImE= +github.com/libp2p/go-libp2p v0.27.5 h1:KwA7pXKXpz8hG6Cr1fMA7UkgleogcwQj0sxl5qquWRg= +github.com/libp2p/go-libp2p v0.27.5/go.mod h1:oMfQGTb9CHnrOuSM6yMmyK2lXz3qIhnkn2+oK3B1Y2g= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= @@ -601,8 +602,8 @@ github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOA github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-isatty v0.0.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp98= -github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= +github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= 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= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= @@ -625,8 +626,9 @@ github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8Rv github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= -github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g= github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM= +github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM= +github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= @@ -665,8 +667,8 @@ github.com/multiformats/go-multibase v0.0.3/go.mod h1:5+1R4eQrT3PkYZ24C3W2Ue2tPw github.com/multiformats/go-multibase v0.2.0 h1:isdYCVLvksgWlMW9OZRYJEa9pZETFivncJHmHnnd87g= github.com/multiformats/go-multibase v0.2.0/go.mod h1:bFBZX4lKCA/2lyOFSAoKH5SS6oPyjtnzK/XTFDPkNuk= github.com/multiformats/go-multicodec v0.3.0/go.mod h1:qGGaQmioCDh+TeFOnxrbU0DaIPw8yFgAZgFG0V7p1qQ= -github.com/multiformats/go-multicodec v0.8.1 h1:ycepHwavHafh3grIbR1jIXnKCsFm0fqsfEOsJ8NtKE8= -github.com/multiformats/go-multicodec v0.8.1/go.mod h1:L3QTQvMIaVBkXOXXtVmYE+LI16i14xuaojr/H7Ai54k= +github.com/multiformats/go-multicodec v0.9.0 h1:pb/dlPnzee/Sxv/j4PmkDRxCOi3hXTz3IbPKOXWJkmg= +github.com/multiformats/go-multicodec v0.9.0/go.mod h1:L3QTQvMIaVBkXOXXtVmYE+LI16i14xuaojr/H7Ai54k= github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= github.com/multiformats/go-multihash v0.0.8/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= github.com/multiformats/go-multihash v0.0.10/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= @@ -674,8 +676,8 @@ github.com/multiformats/go-multihash v0.0.13/go.mod h1:VdAWLKTwram9oKAatUcLxBNUj github.com/multiformats/go-multihash v0.0.14/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= github.com/multiformats/go-multihash v0.0.15/go.mod h1:D6aZrWNLFTV/ynMpKsNtB40mJzmCl4jb1alC0OvHiHg= github.com/multiformats/go-multihash v0.1.0/go.mod h1:RJlXsxt6vHGaia+S8We0ErjhojtKzPP2AH4+kYM7k84= -github.com/multiformats/go-multihash v0.2.1 h1:aem8ZT0VA2nCHHk7bPJ1BjUbHNciqZC/d16Vve9l108= -github.com/multiformats/go-multihash v0.2.1/go.mod h1:WxoMcYG85AZVQUyRyo9s4wULvW5qrI9vb2Lt6evduFc= +github.com/multiformats/go-multihash v0.2.2 h1:Uu7LWs/PmWby1gkj1S1DXx3zyd3aVabA4FiMKn/2tAc= +github.com/multiformats/go-multihash v0.2.2/go.mod h1:dXgKXCXjBzdscBLk9JkjINiEsCKRVch90MdaGiKsvSM= github.com/multiformats/go-multistream v0.4.1 h1:rFy0Iiyn3YT0asivDUIR05leAdwZq3de4741sbiSdfo= github.com/multiformats/go-multistream v0.4.1/go.mod h1:Mz5eykRVAjJWckE2U78c6xqdtyNUEhKSM0Lwar2p77Q= github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= @@ -848,8 +850,8 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= -github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY= +github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stvp/go-udp-testing v0.0.0-20201019212854-469649b16807/go.mod h1:7jxmlfBCDBXRzr0eAQJ48XC1hBu1np4CS5+cHEYfwpc= github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= @@ -962,8 +964,8 @@ go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= -go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= +go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= +go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/dig v1.17.0 h1:5Chju+tUvcC+N7N6EV08BJz41UZuO3BmHcN4A287ZLI= go.uber.org/dig v1.17.0/go.mod h1:rTxpf7l5I0eBTlE6/9RL+lDybC7WFwY2QH55ZSjy1mU= go.uber.org/fx v1.19.2 h1:SyFgYQFr1Wl0AYstE8vyYIzP4bFz2URrScjwC4cwUvY= @@ -1187,7 +1189,6 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220708085239-5a0f0661e09d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1422,8 +1423,8 @@ honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= lukechampine.com/blake3 v1.1.6/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= -lukechampine.com/blake3 v1.1.7 h1:GgRMhmdsuK8+ii6UZFDL8Nb+VyMwadAgcJyfYHxG6n0= -lukechampine.com/blake3 v1.1.7/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= +lukechampine.com/blake3 v1.2.1 h1:YuqqRuaqsGV71BV/nm9xlI0MKUv4QC54jQnBChWbGnI= +lukechampine.com/blake3 v1.2.1/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g= nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= pgregory.net/rapid v0.4.7 h1:MTNRktPuv5FNqOO151TM9mDTa+XHcX6ypYeISDVD14g= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 4807ae28c..e2ed3cada 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -7,7 +7,7 @@ replace github.com/ipfs/kubo => ../../ require ( github.com/Kubuxu/gocovmerge v0.0.0-20161216165753-7ecaa51963cd github.com/golangci/golangci-lint v1.49.0 - github.com/ipfs/boxo v0.8.2-0.20230608080412-e44e658cb393 + github.com/ipfs/boxo v0.9.0 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 github.com/ipfs/go-datastore v0.6.0 @@ -19,9 +19,9 @@ require ( github.com/ipld/go-ipld-prime v0.20.0 github.com/jbenet/go-random v0.0.0-20190219211222-123a90aedc0c github.com/jbenet/go-random-files v0.0.0-20190219210431-31b3f20ebded - github.com/libp2p/go-libp2p v0.27.3 + github.com/libp2p/go-libp2p v0.27.5 github.com/multiformats/go-multiaddr v0.9.0 - github.com/multiformats/go-multihash v0.2.1 + github.com/multiformats/go-multihash v0.2.2 gotest.tools/gotestsum v0.4.2 ) @@ -57,7 +57,7 @@ require ( github.com/daixiang0/gci v0.6.3 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect - github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect github.com/denis-tingaikin/go-header v0.4.3 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/dustin/go-humanize v1.0.1 // indirect @@ -73,7 +73,7 @@ require ( github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/fzipp/gocyclo v0.6.0 // indirect github.com/go-critic/go-critic v0.6.4 // indirect - github.com/go-logr/logr v1.2.3 // indirect + github.com/go-logr/logr v1.2.4 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/go-toolsmith/astcast v1.0.0 // indirect @@ -125,7 +125,7 @@ require ( github.com/ipfs/go-ipfs-ds-help v1.1.0 // indirect github.com/ipfs/go-ipfs-files v0.2.0 // indirect github.com/ipfs/go-ipfs-pq v0.0.3 // indirect - github.com/ipfs/go-ipfs-util v0.0.2 // indirect + github.com/ipfs/go-ipfs-util v0.0.3 // indirect github.com/ipfs/go-ipld-format v0.5.0 // indirect github.com/ipfs/go-ipld-legacy v0.2.1 // indirect github.com/ipfs/go-log/v2 v2.5.1 // indirect @@ -145,7 +145,7 @@ require ( github.com/kisielk/errcheck v1.6.2 // indirect github.com/kisielk/gotool v1.0.0 // indirect github.com/klauspost/compress v1.16.4 // indirect - github.com/klauspost/cpuid/v2 v2.2.4 // indirect + github.com/klauspost/cpuid/v2 v2.2.5 // indirect github.com/koron/go-ssdp v0.0.4 // indirect github.com/kulti/thelper v0.6.3 // indirect github.com/kunwardeep/paralleltest v1.0.6 // indirect @@ -168,7 +168,7 @@ require ( github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect github.com/matoous/godox v0.0.0-20210227103229-6504466cf951 // indirect github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.18 // indirect + github.com/mattn/go-isatty v0.0.19 // indirect github.com/mattn/go-runewidth v0.0.9 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/mbilski/exhaustivestruct v1.2.0 // indirect @@ -176,7 +176,7 @@ require ( github.com/miekg/dns v1.1.53 // indirect github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect - github.com/minio/sha256-simd v1.0.0 // indirect + github.com/minio/sha256-simd v1.0.1 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/moricho/tparallel v0.2.1 // indirect @@ -186,7 +186,7 @@ require ( github.com/multiformats/go-multiaddr-dns v0.3.1 // indirect github.com/multiformats/go-multiaddr-fmt v0.1.0 // indirect github.com/multiformats/go-multibase v0.2.0 // indirect - github.com/multiformats/go-multicodec v0.8.1 // indirect + github.com/multiformats/go-multicodec v0.9.0 // indirect github.com/multiformats/go-multistream v0.4.1 // indirect github.com/multiformats/go-varint v0.0.7 // indirect github.com/nakabonne/nestif v0.3.1 // indirect @@ -243,7 +243,7 @@ require ( github.com/ssgreg/nlreturn/v2 v2.2.1 // indirect github.com/stbenjam/no-sprintf-host-port v0.1.1 // indirect github.com/stretchr/objx v0.5.0 // indirect - github.com/stretchr/testify v1.8.2 // indirect + github.com/stretchr/testify v1.8.3 // indirect github.com/subosito/gotenv v1.4.0 // indirect github.com/sylvia7788/contextcheck v1.0.6 // indirect github.com/tdakkota/asciicheck v0.1.1 // indirect @@ -261,7 +261,7 @@ require ( gitlab.com/bosi/decorder v0.2.3 // indirect go.opentelemetry.io/otel v1.14.0 // indirect go.opentelemetry.io/otel/trace v1.14.0 // indirect - go.uber.org/atomic v1.10.0 // indirect + go.uber.org/atomic v1.11.0 // indirect go.uber.org/dig v1.17.0 // indirect go.uber.org/fx v1.19.2 // indirect go.uber.org/multierr v1.11.0 // indirect @@ -281,7 +281,7 @@ require ( gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect honnef.co/go/tools v0.3.3 // indirect - lukechampine.com/blake3 v1.1.7 // indirect + lukechampine.com/blake3 v1.2.1 // indirect mvdan.cc/gofumpt v0.3.1 // indirect mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed // indirect mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 66957ef56..907caf115 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -141,9 +141,9 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c h1:pFUpOrbxDR6AkioZ1ySsx5yxlDQZ8stG2b88gTPxgJU= github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c/go.mod h1:6UhI8N9EjYm1c2odKpFpAYeR8dsBeM7PtzQhRgxRr9U= -github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 h1:HbphB4TFFXpv7MNrT52FGrrgVXF1owhMVTHFZIlnvd4= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0/go.mod h1:DZGJHZMqrU4JJqFAWUS2UO1+lbSKsdiOoYi9Zzey7Fc= +github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= github.com/denis-tingaikin/go-header v0.4.3 h1:tEaZKAlqql6SKCY++utLmkPLd6K8IBM20Ha7UVm+mtU= github.com/denis-tingaikin/go-header v0.4.3/go.mod h1:0wOCWuN71D5qIgE2nz9KrKmuYBAC2Mra5RassOIQ2/c= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= @@ -204,8 +204,8 @@ github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9 github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= -github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= +github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= @@ -412,8 +412,8 @@ github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NH github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.8.2-0.20230608080412-e44e658cb393 h1:o3l1Rq7NwXT//tOgd0k+JOYTQgvg+WhgKoLy8tJfLxk= -github.com/ipfs/boxo v0.8.2-0.20230608080412-e44e658cb393/go.mod h1:ic5+bhD5T+A9n0HMkXYHiTzpjjaAZaPeKRQ9dWethTs= +github.com/ipfs/boxo v0.9.0 h1:Gb3KGXOZ4J5eCZTsky33tx2oHztrfBo+2IFq6lxmoGM= +github.com/ipfs/boxo v0.9.0/go.mod h1:ic5+bhD5T+A9n0HMkXYHiTzpjjaAZaPeKRQ9dWethTs= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.1.2 h1:GAjkfhVx1f4YTODS6Esrj1wt2HhrtwTnhEr+DyPUaJo= @@ -446,8 +446,8 @@ github.com/ipfs/go-ipfs-files v0.2.0/go.mod h1:vT7uaQfIsprKktzbTPLnIsd+NGw9ZbYwS github.com/ipfs/go-ipfs-posinfo v0.0.1 h1:Esoxj+1JgSjX0+ylc0hUmJCOv6V2vFoZiETLR6OtpRs= github.com/ipfs/go-ipfs-pq v0.0.3 h1:YpoHVJB+jzK15mr/xsWC574tyDLkezVrDNeaalQBsTE= github.com/ipfs/go-ipfs-pq v0.0.3/go.mod h1:btNw5hsHBpRcSSgZtiNm/SLj5gYIZ18AKtv3kERkRb4= -github.com/ipfs/go-ipfs-util v0.0.2 h1:59Sswnk1MFaiq+VcaknX7aYEyGyGDAA73ilhEK2POp8= -github.com/ipfs/go-ipfs-util v0.0.2/go.mod h1:CbPtkWJzjLdEcezDns2XYaehFVNXG9zrdrtMecczcsQ= +github.com/ipfs/go-ipfs-util v0.0.3 h1:2RFdGez6bu2ZlZdI+rWfIdbQb1KudQp3VGwPtdNCmE0= +github.com/ipfs/go-ipfs-util v0.0.3/go.mod h1:LHzG1a0Ig4G+iZ26UUOMjHd+lfM84LZCrn17xAKWBvs= github.com/ipfs/go-ipld-cbor v0.0.6 h1:pYuWHyvSpIsOOLw4Jy7NbBkCyzLDcl64Bf/LZW7eBQ0= github.com/ipfs/go-ipld-format v0.5.0 h1:WyEle9K96MSrvr47zZHKKcDxJ/vlpET6PSiQsAFO+Ds= github.com/ipfs/go-ipld-format v0.5.0/go.mod h1:ImdZqJQaEouMjCvqCe0ORUS+uoBmf7Hf+EO/jh+nk3M= @@ -525,10 +525,8 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.16.4 h1:91KN02FnsOYhuunwU4ssRe8lc2JosWmizWa91B5v1PU= github.com/klauspost/compress v1.16.4/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= -github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk= -github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= +github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= +github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/koron/go-ssdp v0.0.0-20191105050749-2e1c40ed0b5d/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk= @@ -566,8 +564,8 @@ github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38y github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.27.3 h1:tkV/zm3KCZ4R5er9Xcs2pt0YNB4JH0iBfGAtHJdLHRs= -github.com/libp2p/go-libp2p v0.27.3/go.mod h1:FAvvfQa/YOShUYdiSS03IR9OXzkcJXwcNA2FUCh9ImE= +github.com/libp2p/go-libp2p v0.27.5 h1:KwA7pXKXpz8hG6Cr1fMA7UkgleogcwQj0sxl5qquWRg= +github.com/libp2p/go-libp2p v0.27.5/go.mod h1:oMfQGTb9CHnrOuSM6yMmyK2lXz3qIhnkn2+oK3B1Y2g= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= @@ -606,8 +604,8 @@ github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNx github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp98= -github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= +github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= @@ -630,8 +628,8 @@ github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc h1:PTfri+PuQmWDqERdn github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc/go.mod h1:cGKTAVKx4SxOuR/czcZ/E2RSJ3sfHs8FpHhQ5CWMf9s= github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= -github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g= -github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM= +github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM= +github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= @@ -666,12 +664,12 @@ github.com/multiformats/go-multiaddr-fmt v0.1.0/go.mod h1:hGtDIW4PU4BqJ50gW2quDu github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= github.com/multiformats/go-multibase v0.2.0 h1:isdYCVLvksgWlMW9OZRYJEa9pZETFivncJHmHnnd87g= github.com/multiformats/go-multibase v0.2.0/go.mod h1:bFBZX4lKCA/2lyOFSAoKH5SS6oPyjtnzK/XTFDPkNuk= -github.com/multiformats/go-multicodec v0.8.1 h1:ycepHwavHafh3grIbR1jIXnKCsFm0fqsfEOsJ8NtKE8= -github.com/multiformats/go-multicodec v0.8.1/go.mod h1:L3QTQvMIaVBkXOXXtVmYE+LI16i14xuaojr/H7Ai54k= +github.com/multiformats/go-multicodec v0.9.0 h1:pb/dlPnzee/Sxv/j4PmkDRxCOi3hXTz3IbPKOXWJkmg= +github.com/multiformats/go-multicodec v0.9.0/go.mod h1:L3QTQvMIaVBkXOXXtVmYE+LI16i14xuaojr/H7Ai54k= github.com/multiformats/go-multihash v0.0.8/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= github.com/multiformats/go-multihash v0.0.13/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= -github.com/multiformats/go-multihash v0.2.1 h1:aem8ZT0VA2nCHHk7bPJ1BjUbHNciqZC/d16Vve9l108= -github.com/multiformats/go-multihash v0.2.1/go.mod h1:WxoMcYG85AZVQUyRyo9s4wULvW5qrI9vb2Lt6evduFc= +github.com/multiformats/go-multihash v0.2.2 h1:Uu7LWs/PmWby1gkj1S1DXx3zyd3aVabA4FiMKn/2tAc= +github.com/multiformats/go-multihash v0.2.2/go.mod h1:dXgKXCXjBzdscBLk9JkjINiEsCKRVch90MdaGiKsvSM= github.com/multiformats/go-multistream v0.4.1 h1:rFy0Iiyn3YT0asivDUIR05leAdwZq3de4741sbiSdfo= github.com/multiformats/go-multistream v0.4.1/go.mod h1:Mz5eykRVAjJWckE2U78c6xqdtyNUEhKSM0Lwar2p77Q= github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= @@ -885,8 +883,8 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= -github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY= +github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/subosito/gotenv v1.4.0 h1:yAzM1+SmVcz5R4tXGsNMu1jUl2aOJXoiWUCEwwnGrvs= github.com/subosito/gotenv v1.4.0/go.mod h1:mZd6rFysKEcUhUHXJk0C/08wAgyDBFuwEYL7vWWGaGo= github.com/sylvia7788/contextcheck v1.0.6 h1:o2EZgVPyMKE/Mtoqym61DInKEjwEbsmyoxg3VrmjNO4= @@ -957,8 +955,8 @@ go.opentelemetry.io/otel/trace v1.14.0 h1:wp2Mmvj41tDsyAJXiWDWpfNsOiIyd38fy85pyK go.opentelemetry.io/otel/trace v1.14.0/go.mod h1:8avnQLK+CG77yNLUae4ea2JDQ6iT+gozhnZjy/rw9G8= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= -go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= +go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= +go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/dig v1.17.0 h1:5Chju+tUvcC+N7N6EV08BJz41UZuO3BmHcN4A287ZLI= go.uber.org/dig v1.17.0/go.mod h1:rTxpf7l5I0eBTlE6/9RL+lDybC7WFwY2QH55ZSjy1mU= go.uber.org/fx v1.19.2 h1:SyFgYQFr1Wl0AYstE8vyYIzP4bFz2URrScjwC4cwUvY= @@ -1171,11 +1169,11 @@ golang.org/x/sys v0.0.0-20211105183446-c75c47738b0c/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220702020025-31831981b65f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1438,8 +1436,8 @@ honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9 honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.3.3 h1:oDx7VAwstgpYpb3wv0oxiZlxY+foCpRAwY7Vk6XpAgA= honnef.co/go/tools v0.3.3/go.mod h1:jzwdWgg7Jdq75wlfblQxO4neNaFFSvgc1tD5Wv8U0Yw= -lukechampine.com/blake3 v1.1.7 h1:GgRMhmdsuK8+ii6UZFDL8Nb+VyMwadAgcJyfYHxG6n0= -lukechampine.com/blake3 v1.1.7/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= +lukechampine.com/blake3 v1.2.1 h1:YuqqRuaqsGV71BV/nm9xlI0MKUv4QC54jQnBChWbGnI= +lukechampine.com/blake3 v1.2.1/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= mvdan.cc/gofumpt v0.3.1 h1:avhhrOmv0IuvQVK7fvwV91oFSGAk5/6Po8GXTzICeu8= mvdan.cc/gofumpt v0.3.1/go.mod h1:w3ymliuxvzVx8DAutBnVyDqYb1Niy/yCJt/lk821YCE= mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed h1:WX1yoOaKQfddO/mLzdV4wptyWgoH/6hwLs7QHTixo0I= From 2716cd987fcf9ee3c6c1ffd0d5cc68283c32e557 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Thu, 8 Jun 2023 17:32:18 +0200 Subject: [PATCH 0708/1212] feat(gateway): support for IPIP-402 CAR params (#9914) --- core/corehttp/gateway.go | 37 ++-- docs/changelogs/v0.21.md | 4 + docs/examples/kubo-as-a-library/go.mod | 6 +- docs/examples/kubo-as-a-library/go.sum | 11 +- go.mod | 6 +- go.sum | 10 +- test/dependencies/go.mod | 4 +- test/dependencies/go.sum | 8 +- test/sharness/t0118-gateway-car.sh | 136 --------------- test/sharness/t0118-gateway-car/README.md | 30 ---- .../t0118-gateway-car/carv1-basic.car | Bin 715 -> 0 bytes .../t0118-gateway-car/carv1-basic.json | 159 ------------------ .../t0118-gateway-car/deterministic.car | Bin 127 -> 0 bytes test/sharness/t0118-gateway-car/test-dag.car | Bin 312 -> 0 bytes 14 files changed, 48 insertions(+), 363 deletions(-) delete mode 100755 test/sharness/t0118-gateway-car.sh delete mode 100644 test/sharness/t0118-gateway-car/README.md delete mode 100644 test/sharness/t0118-gateway-car/carv1-basic.car delete mode 100644 test/sharness/t0118-gateway-car/carv1-basic.json delete mode 100644 test/sharness/t0118-gateway-car/deterministic.car delete mode 100644 test/sharness/t0118-gateway-car/test-dag.car diff --git a/core/corehttp/gateway.go b/core/corehttp/gateway.go index 0f86d4da7..25ec19e0f 100644 --- a/core/corehttp/gateway.go +++ b/core/corehttp/gateway.go @@ -28,24 +28,21 @@ import ( func GatewayOption(paths ...string) ServeOption { return func(n *core.IpfsNode, _ net.Listener, mux *http.ServeMux) (*http.ServeMux, error) { - gwConfig, err := getGatewayConfig(n) + config, err := getGatewayConfig(n) if err != nil { return nil, err } - gwAPI, err := newGatewayBackend(n) + backend, err := newGatewayBackend(n) if err != nil { return nil, err } - gw := gateway.NewHandler(gwConfig, gwAPI) - gw = otelhttp.NewHandler(gw, "Gateway") - - // By default, our HTTP handler is the gateway handler. - handler := gw.ServeHTTP + handler := gateway.NewHandler(config, backend) + handler = otelhttp.NewHandler(handler, "Gateway") for _, p := range paths { - mux.HandleFunc(p+"/", handler) + mux.HandleFunc(p+"/", handler.ServeHTTP) } return mux, nil @@ -54,18 +51,18 @@ func GatewayOption(paths ...string) ServeOption { func HostnameOption() ServeOption { return func(n *core.IpfsNode, _ net.Listener, mux *http.ServeMux) (*http.ServeMux, error) { - gwConfig, err := getGatewayConfig(n) + config, err := getGatewayConfig(n) if err != nil { return nil, err } - gwAPI, err := newGatewayBackend(n) + backend, err := newGatewayBackend(n) if err != nil { return nil, err } childMux := http.NewServeMux() - mux.HandleFunc("/", gateway.WithHostname(gwConfig, gwAPI, childMux).ServeHTTP) + mux.HandleFunc("/", gateway.NewHostnameHandler(config, backend, childMux).ServeHTTP) return childMux, nil } } @@ -111,11 +108,11 @@ func newGatewayBackend(n *core.IpfsNode) (gateway.IPFSBackend, error) { } } - gw, err := gateway.NewBlocksGateway(bserv, gateway.WithValueStore(vsRouting), gateway.WithNameSystem(nsys)) + backend, err := gateway.NewBlocksBackend(bserv, gateway.WithValueStore(vsRouting), gateway.WithNameSystem(nsys)) if err != nil { return nil, err } - return &offlineGatewayErrWrapper{gwimpl: gw}, nil + return &offlineGatewayErrWrapper{gwimpl: backend}, nil } type offlineGatewayErrWrapper struct { @@ -159,10 +156,10 @@ func (o *offlineGatewayErrWrapper) ResolvePath(ctx context.Context, path gateway return md, err } -func (o *offlineGatewayErrWrapper) GetCAR(ctx context.Context, path gateway.ImmutablePath) (gateway.ContentPathMetadata, io.ReadCloser, <-chan error, error) { - md, data, errCh, err := o.gwimpl.GetCAR(ctx, path) +func (o *offlineGatewayErrWrapper) GetCAR(ctx context.Context, path gateway.ImmutablePath, params gateway.CarParams) (gateway.ContentPathMetadata, io.ReadCloser, error) { + md, data, err := o.gwimpl.GetCAR(ctx, path, params) err = offlineErrWrap(err) - return md, data, errCh, err + return md, data, err } func (o *offlineGatewayErrWrapper) IsCached(ctx context.Context, path path.Path) bool { @@ -191,12 +188,12 @@ var _ gateway.IPFSBackend = (*offlineGatewayErrWrapper)(nil) var defaultPaths = []string{"/ipfs/", "/ipns/", "/api/", "/p2p/"} -var subdomainGatewaySpec = &gateway.Specification{ +var subdomainGatewaySpec = &gateway.PublicGateway{ Paths: defaultPaths, UseSubdomains: true, } -var defaultKnownGateways = map[string]*gateway.Specification{ +var defaultKnownGateways = map[string]*gateway.PublicGateway{ "localhost": subdomainGatewaySpec, } @@ -218,7 +215,7 @@ func getGatewayConfig(n *core.IpfsNode) (gateway.Config, error) { Headers: headers, DeserializedResponses: cfg.Gateway.DeserializedResponses.WithDefault(config.DefaultDeserializedResponses), NoDNSLink: cfg.Gateway.NoDNSLink, - PublicGateways: map[string]*gateway.Specification{}, + PublicGateways: map[string]*gateway.PublicGateway{}, } // Add default implicit known gateways, such as subdomain gateway on localhost. @@ -235,7 +232,7 @@ func getGatewayConfig(n *core.IpfsNode) (gateway.Config, error) { continue } - gwCfg.PublicGateways[hostname] = &gateway.Specification{ + gwCfg.PublicGateways[hostname] = &gateway.PublicGateway{ Paths: gw.Paths, NoDNSLink: gw.NoDNSLink, UseSubdomains: gw.UseSubdomains, diff --git a/docs/changelogs/v0.21.md b/docs/changelogs/v0.21.md index 55350caee..034201748 100644 --- a/docs/changelogs/v0.21.md +++ b/docs/changelogs/v0.21.md @@ -104,6 +104,10 @@ $ curl "https://subdomain-gw.example.net/ipfs/${cid}/" Rationale can be found in [kubo#9913](https://github.com/ipfs/kubo/pull/9913). +#### Gateway: support for CAR parameters of IPIP-402 + +The gateway now supports partial CAR export parameters as indicated in [IPIP-402](https://github.com/ipfs/specs/pull/402). + #### `ipfs dag stat` deduping statistics `ipfs dat stat` now accept multiple CIDs and will dump advanced statistics diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index ce14f58c3..97a6bedb5 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.18 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.9.0 + github.com/ipfs/boxo v0.9.1-0.20230608151829-475d57614469 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.27.5 github.com/multiformats/go-multiaddr v0.9.0 @@ -87,7 +87,7 @@ require ( github.com/ipfs/go-log/v2 v2.5.1 // indirect github.com/ipfs/go-metrics-interface v0.0.1 // indirect github.com/ipfs/go-peertaskqueue v0.8.1 // indirect - github.com/ipfs/go-unixfsnode v1.6.0 // indirect + github.com/ipfs/go-unixfsnode v1.7.1 // indirect github.com/ipld/edelweiss v0.2.0 // indirect github.com/ipld/go-codec-dagpb v1.6.0 // indirect github.com/ipld/go-ipld-prime v0.20.0 // indirect @@ -139,6 +139,7 @@ require ( github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/openzipkin/zipkin-go v0.4.1 // indirect github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect + github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/polydawn/refmt v0.89.0 // indirect github.com/prometheus/client_golang v1.14.0 // indirect @@ -156,6 +157,7 @@ require ( github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect github.com/ucarion/urlpath v0.0.0-20200424170820-7ccc79b76bbb // indirect github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc // indirect + github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11 // indirect github.com/whyrusleeping/cbor-gen v0.0.0-20230126041949-52956bd4c9aa // indirect github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f // indirect github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 3756be266..0a7693ed1 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -319,8 +319,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.9.0 h1:Gb3KGXOZ4J5eCZTsky33tx2oHztrfBo+2IFq6lxmoGM= -github.com/ipfs/boxo v0.9.0/go.mod h1:ic5+bhD5T+A9n0HMkXYHiTzpjjaAZaPeKRQ9dWethTs= +github.com/ipfs/boxo v0.9.1-0.20230608151829-475d57614469 h1:pZAeFwl7Ff6L2sWnqM5ekemKH7MOvSPFeyw7473LfAw= +github.com/ipfs/boxo v0.9.1-0.20230608151829-475d57614469/go.mod h1:Fg+BnfxZ0RPzR0nOodzdIq3A7KgoWAOWsEIImrIQdBM= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= @@ -409,8 +409,8 @@ github.com/ipfs/go-metrics-interface v0.0.1/go.mod h1:6s6euYU4zowdslK0GKHmqaIZ3j github.com/ipfs/go-peertaskqueue v0.8.1 h1:YhxAs1+wxb5jk7RvS0LHdyiILpNmRIRnZVztekOF0pg= github.com/ipfs/go-peertaskqueue v0.8.1/go.mod h1:Oxxd3eaK279FxeydSPPVGHzbwVeHjatZ2GA8XD+KbPU= github.com/ipfs/go-unixfs v0.4.5 h1:wj8JhxvV1G6CD7swACwSKYa+NgtdWC1RUit+gFnymDU= -github.com/ipfs/go-unixfsnode v1.6.0 h1:JOSA02yaLylRNi2rlB4ldPr5VcZhcnaIVj5zNLcOjDo= -github.com/ipfs/go-unixfsnode v1.6.0/go.mod h1:PVfoyZkX1B34qzT3vJO4nsLUpRCyhnMuHBznRcXirlk= +github.com/ipfs/go-unixfsnode v1.7.1 h1:RRxO2b6CSr5UQ/kxnGzaChTjp5LWTdf3Y4n8ANZgB/s= +github.com/ipfs/go-unixfsnode v1.7.1/go.mod h1:PVfoyZkX1B34qzT3vJO4nsLUpRCyhnMuHBznRcXirlk= github.com/ipfs/go-verifcid v0.0.2 h1:XPnUv0XmdH+ZIhLGKg6U2vaPaRDXb9urMyNVCE7uvTs= github.com/ipld/edelweiss v0.2.0 h1:KfAZBP8eeJtrLxLhi7r3N0cBCo7JmwSRhOJp3WSpNjk= github.com/ipld/edelweiss v0.2.0/go.mod h1:FJAzJRCep4iI8FOFlRriN9n0b7OuX3T/S9++NpBDmA4= @@ -421,6 +421,7 @@ github.com/ipld/go-ipld-prime v0.11.0/go.mod h1:+WIAkokurHmZ/KwzDOMUuoeJgaRQktHt github.com/ipld/go-ipld-prime v0.14.1/go.mod h1:QcE4Y9n/ZZr8Ijg5bGPT0GqYWgZ1704nH0RDcQtgTP0= github.com/ipld/go-ipld-prime v0.20.0 h1:Ud3VwE9ClxpO2LkCYP7vWPc0Fo+dYdYzgxUJZ3uRG4g= github.com/ipld/go-ipld-prime v0.20.0/go.mod h1:PzqZ/ZR981eKbgdr3y2DJYeD/8bgMawdGVlJDE8kK+M= +github.com/ipld/go-ipld-prime/storage/bsadapter v0.0.0-20230102063945-1a409dc236dd h1:gMlw/MhNr2Wtp5RwGdsW23cs+yCuj9k2ON7i9MiJlRo= github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/jbenet/go-cienv v0.1.0 h1:Vc/s0QbQtoxX8MwwSLWWh+xNNZvM3Lw7NsTcHrvvhMc= @@ -646,6 +647,7 @@ github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2D github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 h1:1/WtZae0yGtPq+TI6+Tv1WTxkukpXeMlviSxvL7SRgk= +github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9/go.mod h1:x3N5drFsm2uilKKuuYo6LdyD8vZAW55sH/9w+pbo1sw= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -781,6 +783,7 @@ github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0/go.mod h1:x6AKhvS github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc h1:BCPnHtcboadS0DvysUuJXZ4lWVv5Bh5i7+tbIyi+ck4= github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc/go.mod h1:r45hJU7yEoA81k6MWNhpMj/kms0n14dkzkxYHoB96UM= github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11 h1:5HZfQkwe0mIfyDmc1Em5GqlNRzcdtlv4HTNmdpt7XH0= +github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11/go.mod h1:Wlo/SzPmxVp6vXpGt/zaXhHH0fn4IxgqZc82aKg6bpQ= github.com/whyrusleeping/cbor-gen v0.0.0-20200123233031-1cdf64d27158/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI= github.com/whyrusleeping/cbor-gen v0.0.0-20230126041949-52956bd4c9aa h1:EyA027ZAkuaCLoxVX4r1TZMPy1d31fM6hbfQ4OU4I5o= github.com/whyrusleeping/cbor-gen v0.0.0-20230126041949-52956bd4c9aa/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= diff --git a/go.mod b/go.mod index 2d8266005..7e6386f1c 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/gogo/protobuf v1.3.2 github.com/google/uuid v1.3.0 github.com/hashicorp/go-multierror v1.1.1 - github.com/ipfs/boxo v0.9.0 + github.com/ipfs/boxo v0.9.1-0.20230608151829-475d57614469 github.com/ipfs/go-block-format v0.1.2 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 @@ -37,7 +37,7 @@ require ( github.com/ipfs/go-log/v2 v2.5.1 github.com/ipfs/go-metrics-interface v0.0.1 github.com/ipfs/go-metrics-prometheus v0.0.2 - github.com/ipfs/go-unixfsnode v1.6.0 + github.com/ipfs/go-unixfsnode v1.7.1 github.com/ipld/go-codec-dagpb v1.6.0 github.com/ipld/go-ipld-prime v0.20.0 github.com/jbenet/go-random v0.0.0-20190219211222-123a90aedc0c @@ -177,6 +177,7 @@ require ( github.com/onsi/ginkgo/v2 v2.9.2 // indirect github.com/opencontainers/runtime-spec v1.0.2 // indirect github.com/openzipkin/zipkin-go v0.4.1 // indirect + github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/polydawn/refmt v0.89.0 // indirect github.com/prometheus/client_model v0.3.0 // indirect @@ -197,6 +198,7 @@ require ( github.com/tidwall/pretty v1.2.0 // indirect github.com/ucarion/urlpath v0.0.0-20200424170820-7ccc79b76bbb // indirect github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc // indirect + github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11 // indirect github.com/whyrusleeping/cbor-gen v0.0.0-20230126041949-52956bd4c9aa // indirect github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f // indirect github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect diff --git a/go.sum b/go.sum index 5ab048972..d1ca4000a 100644 --- a/go.sum +++ b/go.sum @@ -354,8 +354,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.9.0 h1:Gb3KGXOZ4J5eCZTsky33tx2oHztrfBo+2IFq6lxmoGM= -github.com/ipfs/boxo v0.9.0/go.mod h1:ic5+bhD5T+A9n0HMkXYHiTzpjjaAZaPeKRQ9dWethTs= +github.com/ipfs/boxo v0.9.1-0.20230608151829-475d57614469 h1:pZAeFwl7Ff6L2sWnqM5ekemKH7MOvSPFeyw7473LfAw= +github.com/ipfs/boxo v0.9.1-0.20230608151829-475d57614469/go.mod h1:Fg+BnfxZ0RPzR0nOodzdIq3A7KgoWAOWsEIImrIQdBM= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= @@ -448,8 +448,8 @@ github.com/ipfs/go-metrics-prometheus v0.0.2/go.mod h1:ELLU99AQQNi+zX6GCGm2lAgnz github.com/ipfs/go-peertaskqueue v0.8.1 h1:YhxAs1+wxb5jk7RvS0LHdyiILpNmRIRnZVztekOF0pg= github.com/ipfs/go-peertaskqueue v0.8.1/go.mod h1:Oxxd3eaK279FxeydSPPVGHzbwVeHjatZ2GA8XD+KbPU= github.com/ipfs/go-unixfs v0.4.5 h1:wj8JhxvV1G6CD7swACwSKYa+NgtdWC1RUit+gFnymDU= -github.com/ipfs/go-unixfsnode v1.6.0 h1:JOSA02yaLylRNi2rlB4ldPr5VcZhcnaIVj5zNLcOjDo= -github.com/ipfs/go-unixfsnode v1.6.0/go.mod h1:PVfoyZkX1B34qzT3vJO4nsLUpRCyhnMuHBznRcXirlk= +github.com/ipfs/go-unixfsnode v1.7.1 h1:RRxO2b6CSr5UQ/kxnGzaChTjp5LWTdf3Y4n8ANZgB/s= +github.com/ipfs/go-unixfsnode v1.7.1/go.mod h1:PVfoyZkX1B34qzT3vJO4nsLUpRCyhnMuHBznRcXirlk= github.com/ipfs/go-verifcid v0.0.2 h1:XPnUv0XmdH+ZIhLGKg6U2vaPaRDXb9urMyNVCE7uvTs= github.com/ipld/edelweiss v0.2.0 h1:KfAZBP8eeJtrLxLhi7r3N0cBCo7JmwSRhOJp3WSpNjk= github.com/ipld/edelweiss v0.2.0/go.mod h1:FJAzJRCep4iI8FOFlRriN9n0b7OuX3T/S9++NpBDmA4= @@ -715,6 +715,7 @@ github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2D github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 h1:1/WtZae0yGtPq+TI6+Tv1WTxkukpXeMlviSxvL7SRgk= +github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9/go.mod h1:x3N5drFsm2uilKKuuYo6LdyD8vZAW55sH/9w+pbo1sw= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -894,6 +895,7 @@ github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0/go.mod h1:x6AKhvS github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc h1:BCPnHtcboadS0DvysUuJXZ4lWVv5Bh5i7+tbIyi+ck4= github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc/go.mod h1:r45hJU7yEoA81k6MWNhpMj/kms0n14dkzkxYHoB96UM= github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11 h1:5HZfQkwe0mIfyDmc1Em5GqlNRzcdtlv4HTNmdpt7XH0= +github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11/go.mod h1:Wlo/SzPmxVp6vXpGt/zaXhHH0fn4IxgqZc82aKg6bpQ= github.com/whyrusleeping/cbor-gen v0.0.0-20200123233031-1cdf64d27158/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI= github.com/whyrusleeping/cbor-gen v0.0.0-20230126041949-52956bd4c9aa h1:EyA027ZAkuaCLoxVX4r1TZMPy1d31fM6hbfQ4OU4I5o= github.com/whyrusleeping/cbor-gen v0.0.0-20230126041949-52956bd4c9aa/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index e2ed3cada..2c667ab89 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -7,7 +7,7 @@ replace github.com/ipfs/kubo => ../../ require ( github.com/Kubuxu/gocovmerge v0.0.0-20161216165753-7ecaa51963cd github.com/golangci/golangci-lint v1.49.0 - github.com/ipfs/boxo v0.9.0 + github.com/ipfs/boxo v0.9.1-0.20230608151829-475d57614469 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 github.com/ipfs/go-datastore v0.6.0 @@ -131,7 +131,7 @@ require ( github.com/ipfs/go-log/v2 v2.5.1 // indirect github.com/ipfs/go-metrics-interface v0.0.1 // indirect github.com/ipfs/go-peertaskqueue v0.8.1 // indirect - github.com/ipfs/go-unixfsnode v1.6.0 // indirect + github.com/ipfs/go-unixfsnode v1.7.1 // indirect github.com/ipfs/kubo v0.16.0 // indirect github.com/ipld/go-codec-dagpb v1.6.0 // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 907caf115..199b20938 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -412,8 +412,8 @@ github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NH github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.9.0 h1:Gb3KGXOZ4J5eCZTsky33tx2oHztrfBo+2IFq6lxmoGM= -github.com/ipfs/boxo v0.9.0/go.mod h1:ic5+bhD5T+A9n0HMkXYHiTzpjjaAZaPeKRQ9dWethTs= +github.com/ipfs/boxo v0.9.1-0.20230608151829-475d57614469 h1:pZAeFwl7Ff6L2sWnqM5ekemKH7MOvSPFeyw7473LfAw= +github.com/ipfs/boxo v0.9.1-0.20230608151829-475d57614469/go.mod h1:Fg+BnfxZ0RPzR0nOodzdIq3A7KgoWAOWsEIImrIQdBM= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.1.2 h1:GAjkfhVx1f4YTODS6Esrj1wt2HhrtwTnhEr+DyPUaJo= @@ -465,8 +465,8 @@ github.com/ipfs/go-metrics-interface v0.0.1/go.mod h1:6s6euYU4zowdslK0GKHmqaIZ3j github.com/ipfs/go-peertaskqueue v0.8.1 h1:YhxAs1+wxb5jk7RvS0LHdyiILpNmRIRnZVztekOF0pg= github.com/ipfs/go-peertaskqueue v0.8.1/go.mod h1:Oxxd3eaK279FxeydSPPVGHzbwVeHjatZ2GA8XD+KbPU= github.com/ipfs/go-unixfs v0.4.5 h1:wj8JhxvV1G6CD7swACwSKYa+NgtdWC1RUit+gFnymDU= -github.com/ipfs/go-unixfsnode v1.6.0 h1:JOSA02yaLylRNi2rlB4ldPr5VcZhcnaIVj5zNLcOjDo= -github.com/ipfs/go-unixfsnode v1.6.0/go.mod h1:PVfoyZkX1B34qzT3vJO4nsLUpRCyhnMuHBznRcXirlk= +github.com/ipfs/go-unixfsnode v1.7.1 h1:RRxO2b6CSr5UQ/kxnGzaChTjp5LWTdf3Y4n8ANZgB/s= +github.com/ipfs/go-unixfsnode v1.7.1/go.mod h1:PVfoyZkX1B34qzT3vJO4nsLUpRCyhnMuHBznRcXirlk= github.com/ipfs/go-verifcid v0.0.2 h1:XPnUv0XmdH+ZIhLGKg6U2vaPaRDXb9urMyNVCE7uvTs= github.com/ipfs/hang-fds v0.1.0 h1:deBiFlWHsVGzJ0ZMaqscEqRM1r2O1rFZ59UiQXb1Xko= github.com/ipfs/hang-fds v0.1.0/go.mod h1:29VLWOn3ftAgNNgXg/al7b11UzuQ+w7AwtCGcTaWkbM= diff --git a/test/sharness/t0118-gateway-car.sh b/test/sharness/t0118-gateway-car.sh deleted file mode 100755 index 7b7d998ee..000000000 --- a/test/sharness/t0118-gateway-car.sh +++ /dev/null @@ -1,136 +0,0 @@ -#!/usr/bin/env bash - -test_description="Test HTTP Gateway CAR (application/vnd.ipld.car) Support" - -. lib/test-lib.sh - -test_init_ipfs -test_launch_ipfs_daemon_without_network - -# CAR stream is not deterministic, as blocks can arrive in random order, -# but if we have a small file that fits into a single block, and export its CID -# we will get a CAR that is a deterministic array of bytes. - -# Import test case -# See the static fixtures in ./t0118-gateway-car/ -test_expect_success "Add the dir test directory" ' - cp ../t0118-gateway-car/test-dag.car ./test-dag.car && - cp ../t0118-gateway-car/deterministic.car ./deterministic.car -' -ROOT_DIR_CID=bafybeiefu3d7oytdumk5v7gn6s7whpornueaw7m7u46v2o6omsqcrhhkzi # ./ -FILE_CID=bafkreifkam6ns4aoolg3wedr4uzrs3kvq66p4pecirz6y2vlrngla62mxm # /subdir/ascii.txt - -# GET a reference DAG with dag-cbor+dag-pb+raw blocks as CAR - - # This test uses official CARv1 fixture from https://ipld.io/specs/transport/car/fixture/carv1-basic/ - test_expect_success "GET for application/vnd.ipld.car with dag-cbor root returns a CARv1 stream with full DAG" ' - ipfs dag import ../t0118-gateway-car/carv1-basic.car && - DAG_CBOR_CID=bafyreihyrpefhacm6kkp4ql6j6udakdit7g3dmkzfriqfykhjw6cad5lrm && - curl -sX GET -H "Accept: application/vnd.ipld.car" "http://127.0.0.1:$GWAY_PORT/ipfs/$DAG_CBOR_CID" -o gateway-dag-cbor.car && - purge_blockstore && - ipfs dag import gateway-dag-cbor.car && - ipfs dag stat --offline $DAG_CBOR_CID - ' - -# GET unixfs file as CAR -# (by using a single file we ensure deterministic result that can be compared byte-for-byte) - - test_expect_success "GET with format=car param returns a CARv1 stream" ' - ipfs dag import test-dag.car && - curl -sX GET "http://127.0.0.1:$GWAY_PORT/ipfs/$ROOT_DIR_CID/subdir/ascii.txt?format=car" -o gateway-param.car && - test_cmp deterministic.car gateway-param.car - ' - - test_expect_success "GET for application/vnd.ipld.car returns a CARv1 stream" ' - ipfs dag import test-dag.car && - curl -sX GET -H "Accept: application/vnd.ipld.car" "http://127.0.0.1:$GWAY_PORT/ipfs/$ROOT_DIR_CID/subdir/ascii.txt" -o gateway-header.car && - test_cmp deterministic.car gateway-header.car - ' - - # explicit version=1 - test_expect_success "GET for application/vnd.ipld.raw version=1 returns a CARv1 stream" ' - ipfs dag import test-dag.car && - curl -sX GET -H "Accept: application/vnd.ipld.car;version=1" "http://127.0.0.1:$GWAY_PORT/ipfs/$ROOT_DIR_CID/subdir/ascii.txt" -o gateway-header-v1.car && - test_cmp deterministic.car gateway-header-v1.car - ' - - # explicit version=1 with whitepace - test_expect_success "GET for application/vnd.ipld.raw version=1 returns a CARv1 stream (with whitespace)" ' - ipfs dag import test-dag.car && - curl -sX GET -H "Accept: application/vnd.ipld.car; version=1" "http://127.0.0.1:$GWAY_PORT/ipfs/$ROOT_DIR_CID/subdir/ascii.txt" -o gateway-header-v1.car && - test_cmp deterministic.car gateway-header-v1.car - ' - - # explicit version=2 - test_expect_success "GET for application/vnd.ipld.raw version=2 returns HTTP 400 Bad Request error" ' - curl -svX GET -H "Accept: application/vnd.ipld.car;version=2" "http://127.0.0.1:$GWAY_PORT/ipfs/$ROOT_DIR_CID/subdir/ascii.txt" > curl_output 2>&1 && - cat curl_output && - grep "400 Bad Request" curl_output && - grep "unsupported CAR version" curl_output - ' - -# GET unixfs directory as a CAR with DAG and some selector - - # TODO: this is basic test for "full" selector, we will add support for custom ones in https://github.com/ipfs/go-ipfs/issues/8769 - test_expect_success "GET for application/vnd.ipld.car with unixfs dir returns a CARv1 stream with full DAG" ' - ipfs dag import test-dag.car && - curl -sX GET -H "Accept: application/vnd.ipld.car" "http://127.0.0.1:$GWAY_PORT/ipfs/$ROOT_DIR_CID" -o gateway-dir.car && - purge_blockstore && - ipfs dag import gateway-dir.car && - ipfs dag stat --offline $ROOT_DIR_CID - ' - -# Make sure expected HTTP headers are returned with the CAR bytes - - test_expect_success "GET response for application/vnd.ipld.car has expected Content-Type" ' - ipfs dag import test-dag.car && - curl -svX GET -H "Accept: application/vnd.ipld.car" "http://127.0.0.1:$GWAY_PORT/ipfs/$ROOT_DIR_CID/subdir/ascii.txt" >/dev/null 2>curl_output && - cat curl_output && - grep "< Content-Type: application/vnd.ipld.car; version=1" curl_output - ' - - # CAR is streamed, gateway may not have the entire thing, unable to calculate total size - test_expect_success "GET response for application/vnd.ipld.car includes no Content-Length" ' - grep -qv "< Content-Length:" curl_output - ' - - test_expect_success "GET response for application/vnd.ipld.car includes Content-Disposition" ' - grep "< Content-Disposition: attachment\; filename=\"${FILE_CID}.car\"" curl_output - ' - - test_expect_success "GET response for application/vnd.ipld.car includes nosniff hint" ' - grep "< X-Content-Type-Options: nosniff" curl_output - ' - - # CAR is streamed, gateway may not have the entire thing, unable to support range-requests - # Partial downloads and resumes should be handled using - # IPLD selectors: https://github.com/ipfs/go-ipfs/issues/8769 - test_expect_success "GET response for application/vnd.ipld.car includes Accept-Ranges header" ' - grep "< Accept-Ranges: none" curl_output - ' - - test_expect_success "GET for application/vnd.ipld.car with query filename includes Content-Disposition with custom filename" ' - curl -svX GET -H "Accept: application/vnd.ipld.car" "http://127.0.0.1:$GWAY_PORT/ipfs/$ROOT_DIR_CID/subdir/ascii.txt?filename=foobar.car" >/dev/null 2>curl_output_filename && - cat curl_output_filename && - grep "< Content-Disposition: attachment\; filename=\"foobar.car\"" curl_output_filename - ' - -# Cache control HTTP headers - - test_expect_success "GET response for application/vnd.ipld.car includes a weak Etag" ' - grep "< Etag: W/\"${FILE_CID}.car\"" curl_output - ' - - # (basic checks, detailed behavior for some fields is tested in t0116-gateway-cache.sh) - test_expect_success "GET response for application/vnd.ipld.car includes X-Ipfs-Path and X-Ipfs-Roots" ' - grep "< X-Ipfs-Path" curl_output && - grep "< X-Ipfs-Roots" curl_output - ' - - test_expect_success "GET response for application/vnd.ipld.car includes same Cache-Control as a block or a file" ' - grep "< Cache-Control: public, max-age=29030400, immutable" curl_output - ' - -test_kill_ipfs_daemon - -test_done diff --git a/test/sharness/t0118-gateway-car/README.md b/test/sharness/t0118-gateway-car/README.md deleted file mode 100644 index 7b81e543b..000000000 --- a/test/sharness/t0118-gateway-car/README.md +++ /dev/null @@ -1,30 +0,0 @@ -# Dataset description/sources - -- carv1-basic.car - - raw CARv1 - - Source: https://ipld.io/specs/transport/car/fixture/carv1-basic/carv1-basic.car - -- carv1-basic.json - - description of the contents and layout of the raw CAR, encoded in DAG-JSON - - Source: https://ipld.io/specs/transport/car/fixture/carv1-basic/carv1-basic.json - -- test-dag.car + deterministic.car - - raw CARv1 - -generated with: - -```sh -# using ipfs version 0.18.1 -mkdir -p subdir && -echo "hello application/vnd.ipld.car" > subdir/ascii.txt && -ROOT_DIR_CID=$(ipfs add -Qrw --cid-version 1 subdir) && -FILE_CID=$(ipfs resolve -r /ipfs/$ROOT_DIR_CID/subdir/ascii.txt | cut -d "/" -f3) && -ipfs dag export $ROOT_DIR_CID > test-dag.car && -ipfs dag export $FILE_CID > deterministic.car && - -echo ROOT_DIR_CID=${ROOT_DIR_CID} # ./ -echo FILE_CID=${FILE_CID} # /\subdir/ascii.txt - -# ROOT_DIR_CID=bafybeiefu3d7oytdumk5v7gn6s7whpornueaw7m7u46v2o6omsqcrhhkzi # ./ -# FILE_CID=bafkreifkam6ns4aoolg3wedr4uzrs3kvq66p4pecirz6y2vlrngla62mxm # /subdir/ascii.txt -``` diff --git a/test/sharness/t0118-gateway-car/carv1-basic.car b/test/sharness/t0118-gateway-car/carv1-basic.car deleted file mode 100644 index 48c67a3d8dc77ccff652289efb2b41edd4867d44..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 715 zcmYdZlv@T^XBM16^mDnYKs~9PRn;i&guKF^#9|+JO5wK+*E)0UP@kKZfZ(W zPG&(fBVpA-dR!`up+XAVeqSs7*{8Kv>B?Kpzb6a>{@wA2tebRKs!GK|)@4yipb$$^ zYGRQDi;zB-l8{2>%BFiZGufxw`Wo51ljYy|w%_%~d!}|Co}CXSx$O<+5@IV(P0r6t zk(kP;L5%6iK+phmEkSd2A+Bva6D`izRIm8 zgfZBugp5uCfurnv%3WfpBhW%hPLndXVc_T{3dI4x6g)Z xpWW$YsYS(^`FV`a#Hh|l&B@7ENGvGG$xKcx0cz7P%S+MAEXYaGOHM4}0stv?G@1Ya diff --git a/test/sharness/t0118-gateway-car/test-dag.car b/test/sharness/t0118-gateway-car/test-dag.car deleted file mode 100644 index e80fa4b0756cb7c9f5ebc44242424506fb7283cb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 312 zcmcColv^5u?@7svMQ{B%`(=Of-ix^$+_m$U+s0a-OIe^X z=hdn7vecsD%=|pYC}LC#8E~n9)Saw+P!{lU+i#stX^z~mrGeJ6Qa_#6abJ&?`ByJ= zomD}It++HPC9_B(f{TfRF_tJT#z3P(g%nmX+uSVRD>}Pdpzx`&WNv8to_{t?F2!%M zR(JbssP@?{#FH}E7+o2uIXU?Xi3J5YnaPPIK>zBO<)!Fl7UZPp JB_|ef0RZo3fVKbt From 1859e89d86e36d6f8917aacc2d375738e8e4c400 Mon Sep 17 00:00:00 2001 From: Laurent Senta Date: Thu, 8 Jun 2023 19:18:04 +0200 Subject: [PATCH 0709/1212] feat: update gateway-conformance to v0.1 (#9925) --- .github/workflows/gateway-conformance.yml | 36 ++++++++++++++++++----- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/.github/workflows/gateway-conformance.yml b/.github/workflows/gateway-conformance.yml index ece4ca463..8825f9bce 100644 --- a/.github/workflows/gateway-conformance.yml +++ b/.github/workflows/gateway-conformance.yml @@ -23,7 +23,7 @@ jobs: steps: # 1. Download the gateway-conformance fixtures - name: Download gateway-conformance fixtures - uses: ipfs/gateway-conformance/.github/actions/extract-fixtures@v0.0 + uses: ipfs/gateway-conformance/.github/actions/extract-fixtures@v0.1 with: output: fixtures @@ -40,8 +40,8 @@ jobs: run: make build working-directory: kubo-gateway - # 3. Start the kubo-gateway - - name: Start kubo-gateway + # 3. Init the kubo-gateway + - name: Init kubo-gateway env: GATEWAY_PUBLIC_GATEWAYS: | { @@ -58,16 +58,36 @@ jobs: run: | ./ipfs init ./ipfs config --json Gateway.PublicGateways "$GATEWAY_PUBLIC_GATEWAYS" - ./ipfs daemon --offline & working-directory: kubo-gateway/cmd/ipfs # 4. Populate the Kubo gateway with the gateway-conformance fixtures - name: Import fixtures - run: find ./fixtures -name '*.car' -exec kubo-gateway/cmd/ipfs/ipfs dag import --pin-roots=false {} \; + run: | + # Import car files + find ./fixtures -name '*.car' -exec kubo-gateway/cmd/ipfs/ipfs dag import --pin-roots=false {} \; - # 5. Run the gateway-conformance tests + # Import ipns records + records=$(find ./fixtures -name '*.ipns-record') + for record in $records + do + key=$(basename -s .ipns-record "$record" | cut -d'_' -f1) + kubo-gateway/cmd/ipfs/ipfs routing put --allow-offline "/ipns/$key" "$record" + done + + # Import dnslink records + # the IPFS_NS_MAP env will be used by the daemon + export IPFS_NS_MAP=$(cat ./fixtures/dnslinks.json | jq -r 'to_entries | map("\(.key).example.com:\(.value)") | join(",")') + echo "IPFS_NS_MAP=${IPFS_NS_MAP}" >> $GITHUB_ENV + + # 5. Start the kubo-gateway + - name: Start kubo-gateway + run: | + ./ipfs daemon --offline & + working-directory: kubo-gateway/cmd/ipfs + + # 6. Run the gateway-conformance tests - name: Run gateway-conformance tests - uses: ipfs/gateway-conformance/.github/actions/test@v0.0 + uses: ipfs/gateway-conformance/.github/actions/test@v0.1 with: gateway-url: http://127.0.0.1:8080 json: output.json @@ -76,7 +96,7 @@ jobs: markdown: output.md args: -skip 'TestGatewayCar/GET_response_for_application/vnd.ipld.car/Header_Content-Length' - # 6. Upload the results + # 7. Upload the results - name: Upload MD summary if: failure() || success() run: cat output.md >> $GITHUB_STEP_SUMMARY From ad9e208ad6e757b00fcdaed0955ff5de8c913993 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Fri, 9 Jun 2023 12:29:07 +0200 Subject: [PATCH 0710/1212] chore: bump to boxo 0.10 (#9928) --- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- test/dependencies/go.mod | 2 +- test/dependencies/go.sum | 4 ++-- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 97a6bedb5..8066f3286 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.18 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.9.1-0.20230608151829-475d57614469 + github.com/ipfs/boxo v0.10.0 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.27.5 github.com/multiformats/go-multiaddr v0.9.0 diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 0a7693ed1..c3b246b39 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -319,8 +319,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.9.1-0.20230608151829-475d57614469 h1:pZAeFwl7Ff6L2sWnqM5ekemKH7MOvSPFeyw7473LfAw= -github.com/ipfs/boxo v0.9.1-0.20230608151829-475d57614469/go.mod h1:Fg+BnfxZ0RPzR0nOodzdIq3A7KgoWAOWsEIImrIQdBM= +github.com/ipfs/boxo v0.10.0 h1:tdDAxq8jrsbRkYoF+5Rcqyeb91hgWe2hp7iLu7ORZLY= +github.com/ipfs/boxo v0.10.0/go.mod h1:Fg+BnfxZ0RPzR0nOodzdIq3A7KgoWAOWsEIImrIQdBM= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= diff --git a/go.mod b/go.mod index 7e6386f1c..53f517571 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/gogo/protobuf v1.3.2 github.com/google/uuid v1.3.0 github.com/hashicorp/go-multierror v1.1.1 - github.com/ipfs/boxo v0.9.1-0.20230608151829-475d57614469 + github.com/ipfs/boxo v0.10.0 github.com/ipfs/go-block-format v0.1.2 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 diff --git a/go.sum b/go.sum index d1ca4000a..ea70323c8 100644 --- a/go.sum +++ b/go.sum @@ -354,8 +354,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.9.1-0.20230608151829-475d57614469 h1:pZAeFwl7Ff6L2sWnqM5ekemKH7MOvSPFeyw7473LfAw= -github.com/ipfs/boxo v0.9.1-0.20230608151829-475d57614469/go.mod h1:Fg+BnfxZ0RPzR0nOodzdIq3A7KgoWAOWsEIImrIQdBM= +github.com/ipfs/boxo v0.10.0 h1:tdDAxq8jrsbRkYoF+5Rcqyeb91hgWe2hp7iLu7ORZLY= +github.com/ipfs/boxo v0.10.0/go.mod h1:Fg+BnfxZ0RPzR0nOodzdIq3A7KgoWAOWsEIImrIQdBM= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 2c667ab89..579fd5a30 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -7,7 +7,7 @@ replace github.com/ipfs/kubo => ../../ require ( github.com/Kubuxu/gocovmerge v0.0.0-20161216165753-7ecaa51963cd github.com/golangci/golangci-lint v1.49.0 - github.com/ipfs/boxo v0.9.1-0.20230608151829-475d57614469 + github.com/ipfs/boxo v0.10.0 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 github.com/ipfs/go-datastore v0.6.0 diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 199b20938..bb8d2a267 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -412,8 +412,8 @@ github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NH github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.9.1-0.20230608151829-475d57614469 h1:pZAeFwl7Ff6L2sWnqM5ekemKH7MOvSPFeyw7473LfAw= -github.com/ipfs/boxo v0.9.1-0.20230608151829-475d57614469/go.mod h1:Fg+BnfxZ0RPzR0nOodzdIq3A7KgoWAOWsEIImrIQdBM= +github.com/ipfs/boxo v0.10.0 h1:tdDAxq8jrsbRkYoF+5Rcqyeb91hgWe2hp7iLu7ORZLY= +github.com/ipfs/boxo v0.10.0/go.mod h1:Fg+BnfxZ0RPzR0nOodzdIq3A7KgoWAOWsEIImrIQdBM= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.1.2 h1:GAjkfhVx1f4YTODS6Esrj1wt2HhrtwTnhEr+DyPUaJo= From 8138e00024922c89c08056b3ca69162a693dfddc Mon Sep 17 00:00:00 2001 From: Jorropo Date: Mon, 12 Jun 2023 15:10:49 +0200 Subject: [PATCH 0711/1212] chore: last dependency update for v0.21-rc1 --- docs/examples/kubo-as-a-library/go.mod | 29 ++++---- docs/examples/kubo-as-a-library/go.sum | 62 +++++++++-------- go.mod | 46 ++++++------- go.sum | 94 +++++++++++++------------- test/dependencies/go.mod | 11 +-- test/dependencies/go.sum | 24 ++++--- 6 files changed, 136 insertions(+), 130 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 8066f3286..cda83aeb4 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -21,7 +21,7 @@ require ( github.com/benbjohnson/clock v1.3.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver/v4 v4.0.0 // indirect - github.com/cenkalti/backoff/v4 v4.2.0 // indirect + github.com/cenkalti/backoff/v4 v4.2.1 // indirect github.com/ceramicnetwork/go-dag-jose v0.1.0 // indirect github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect @@ -102,8 +102,8 @@ require ( github.com/libp2p/go-doh-resolver v0.4.0 // indirect github.com/libp2p/go-flow-metrics v0.1.0 // indirect github.com/libp2p/go-libp2p-asn-util v0.3.0 // indirect - github.com/libp2p/go-libp2p-kad-dht v0.23.0 // indirect - github.com/libp2p/go-libp2p-kbucket v0.5.0 // indirect + github.com/libp2p/go-libp2p-kad-dht v0.24.0 // indirect + github.com/libp2p/go-libp2p-kbucket v0.6.1 // indirect github.com/libp2p/go-libp2p-pubsub v0.9.3 // indirect github.com/libp2p/go-libp2p-pubsub-router v0.6.0 // indirect github.com/libp2p/go-libp2p-record v0.2.0 // indirect @@ -131,7 +131,7 @@ require ( github.com/multiformats/go-multiaddr-fmt v0.1.0 // indirect github.com/multiformats/go-multibase v0.2.0 // indirect github.com/multiformats/go-multicodec v0.9.0 // indirect - github.com/multiformats/go-multihash v0.2.2 // indirect + github.com/multiformats/go-multihash v0.2.3 // indirect github.com/multiformats/go-multistream v0.4.1 // indirect github.com/multiformats/go-varint v0.0.7 // indirect github.com/onsi/ginkgo/v2 v2.9.2 // indirect @@ -163,20 +163,21 @@ require ( github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 // indirect go.opencensus.io v0.24.0 // indirect - go.opentelemetry.io/otel v1.14.0 // indirect + go.opentelemetry.io/otel v1.16.0 // indirect go.opentelemetry.io/otel/exporters/jaeger v1.14.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.14.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.14.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.16.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.16.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.14.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.14.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.16.0 // indirect go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.14.0 // indirect go.opentelemetry.io/otel/exporters/zipkin v1.14.0 // indirect - go.opentelemetry.io/otel/sdk v1.14.0 // indirect - go.opentelemetry.io/otel/trace v1.14.0 // indirect + go.opentelemetry.io/otel/metric v1.16.0 // indirect + go.opentelemetry.io/otel/sdk v1.16.0 // indirect + go.opentelemetry.io/otel/trace v1.16.0 // indirect go.opentelemetry.io/proto/otlp v0.19.0 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/dig v1.17.0 // indirect - go.uber.org/fx v1.19.2 // indirect + go.uber.org/fx v1.19.3 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.24.0 // indirect go4.org v0.0.0-20230225012048-214862532bf5 // indirect @@ -189,9 +190,9 @@ require ( golang.org/x/text v0.9.0 // indirect golang.org/x/tools v0.7.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect - gonum.org/v1/gonum v0.11.0 // indirect - google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect - google.golang.org/grpc v1.53.0 // indirect + gonum.org/v1/gonum v0.13.0 // indirect + google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect + google.golang.org/grpc v1.55.0 // indirect google.golang.org/protobuf v1.30.0 // indirect gopkg.in/square/go-jose.v2 v2.5.1 // indirect lukechampine.com/blake3 v1.2.1 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index c3b246b39..922906c35 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -74,8 +74,8 @@ github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= -github.com/cenkalti/backoff/v4 v4.2.0 h1:HN5dHm3WBOgndBH6E8V0q2jIYIR3s9yglV8k/+MN3u4= -github.com/cenkalti/backoff/v4 v4.2.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= +github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/ceramicnetwork/go-dag-jose v0.1.0 h1:yJ/HVlfKpnD3LdYP03AHyTvbm3BpPiz2oZiOeReJRdU= github.com/ceramicnetwork/go-dag-jose v0.1.0/go.mod h1:qYA1nYt0X8u4XoMAVoOV3upUVKtrxy/I670Dg5F0wjI= @@ -205,8 +205,8 @@ github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXP github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ= github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= +github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -492,11 +492,11 @@ github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLE github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= github.com/libp2p/go-libp2p-core v0.3.0/go.mod h1:ACp3DmS3/N64c2jDzcV429ukDpicbL6+TrrxANBjPGw= -github.com/libp2p/go-libp2p-kad-dht v0.23.0 h1:sxE6LxLopp79eLeV695n7+c77V/Vn4AMF28AdM/XFqM= -github.com/libp2p/go-libp2p-kad-dht v0.23.0/go.mod h1:oO5N308VT2msnQI6qi5M61wzPmJYg7Tr9e16m5n7uDU= +github.com/libp2p/go-libp2p-kad-dht v0.24.0 h1:nZnFDQEFU4N8GzclnR+IGxIgR7k4PPCDk/GK9A28onk= +github.com/libp2p/go-libp2p-kad-dht v0.24.0/go.mod h1:lfu5T01EH+r6uDZ/8G+ObhwgzVyd0b1nb54AdT8XGhc= github.com/libp2p/go-libp2p-kbucket v0.3.1/go.mod h1:oyjT5O7tS9CQurok++ERgc46YLwEpuGoFq9ubvoUOio= -github.com/libp2p/go-libp2p-kbucket v0.5.0 h1:g/7tVm8ACHDxH29BGrpsQlnNeu+6OF1A9bno/4/U1oA= -github.com/libp2p/go-libp2p-kbucket v0.5.0/go.mod h1:zGzGCpQd78b5BNTDGHNDLaTt9aDK/A02xeZp9QeFC4U= +github.com/libp2p/go-libp2p-kbucket v0.6.1 h1:Y/NIvALuY5/fJlOpaJor9Azg4eor15JskGs9Lb2EhH0= +github.com/libp2p/go-libp2p-kbucket v0.6.1/go.mod h1:dvWO707Oq/vhMVuUhyfLkw0QsOrJFETepbNfpVHSELI= github.com/libp2p/go-libp2p-peerstore v0.1.4/go.mod h1:+4BDbDiiKf4PzpANZDAT+knVdLxvqh7hXOujessqdzs= github.com/libp2p/go-libp2p-pubsub v0.9.3 h1:ihcz9oIBMaCK9kcx+yHWm3mLAFBMAUsM4ux42aikDxo= github.com/libp2p/go-libp2p-pubsub v0.9.3/go.mod h1:RYA7aM9jIic5VV47WXu4GkcRxRhrdElWf8xtyli+Dzc= @@ -610,8 +610,8 @@ github.com/multiformats/go-multihash v0.0.13/go.mod h1:VdAWLKTwram9oKAatUcLxBNUj github.com/multiformats/go-multihash v0.0.14/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= github.com/multiformats/go-multihash v0.0.15/go.mod h1:D6aZrWNLFTV/ynMpKsNtB40mJzmCl4jb1alC0OvHiHg= github.com/multiformats/go-multihash v0.1.0/go.mod h1:RJlXsxt6vHGaia+S8We0ErjhojtKzPP2AH4+kYM7k84= -github.com/multiformats/go-multihash v0.2.2 h1:Uu7LWs/PmWby1gkj1S1DXx3zyd3aVabA4FiMKn/2tAc= -github.com/multiformats/go-multihash v0.2.2/go.mod h1:dXgKXCXjBzdscBLk9JkjINiEsCKRVch90MdaGiKsvSM= +github.com/multiformats/go-multihash v0.2.3 h1:7Lyc8XfX/IY2jWb/gI7JP+o7JEq9hOa7BFvVU9RSh+U= +github.com/multiformats/go-multihash v0.2.3/go.mod h1:dXgKXCXjBzdscBLk9JkjINiEsCKRVch90MdaGiKsvSM= github.com/multiformats/go-multistream v0.4.1 h1:rFy0Iiyn3YT0asivDUIR05leAdwZq3de4741sbiSdfo= github.com/multiformats/go-multistream v0.4.1/go.mod h1:Mz5eykRVAjJWckE2U78c6xqdtyNUEhKSM0Lwar2p77Q= github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= @@ -752,7 +752,7 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= @@ -811,26 +811,28 @@ go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/otel v1.14.0 h1:/79Huy8wbf5DnIPhemGB+zEPVwnN6fuQybr/SRXa6hM= -go.opentelemetry.io/otel v1.14.0/go.mod h1:o4buv+dJzx8rohcUeRmWUZhqupFvzWis188WlggnNeU= +go.opentelemetry.io/otel v1.16.0 h1:Z7GVAX/UkAXPKsy94IU+i6thsQS4nb7LviLpnaNeW8s= +go.opentelemetry.io/otel v1.16.0/go.mod h1:vl0h9NUa1D5s1nv3A5vZOYWn8av4K8Ml6JDeHrT/bx4= go.opentelemetry.io/otel/exporters/jaeger v1.14.0 h1:CjbUNd4iN2hHmWekmOqZ+zSCU+dzZppG8XsV+A3oc8Q= go.opentelemetry.io/otel/exporters/jaeger v1.14.0/go.mod h1:4Ay9kk5vELRrbg5z4cpP9EtmQRFap2Wb0woPG4lujZA= -go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.14.0 h1:/fXHZHGvro6MVqV34fJzDhi7sHGpX3Ej/Qjmfn003ho= -go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.14.0/go.mod h1:UFG7EBMRdXyFstOwH028U0sVf+AvukSGhF0g8+dmNG8= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.14.0 h1:TKf2uAs2ueguzLaxOCBXNpHxfO/aC7PAdDsSH0IbeRQ= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.14.0/go.mod h1:HrbCVv40OOLTABmOn1ZWty6CHXkU8DK/Urc43tHug70= +go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.16.0 h1:t4ZwRPU+emrcvM2e9DHd0Fsf0JTPVcbfa/BhTDF03d0= +go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.16.0/go.mod h1:vLarbg68dH2Wa77g71zmKQqlQ8+8Rq3GRG31uc0WcWI= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.16.0 h1:cbsD4cUcviQGXdw8+bo5x2wazq10SKz8hEbtCRPcU78= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.16.0/go.mod h1:JgXSGah17croqhJfhByOLVY719k1emAXC8MVhCIJlRs= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.14.0 h1:ap+y8RXX3Mu9apKVtOkM6WSFESLM8K3wNQyOU8sWHcc= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.14.0/go.mod h1:5w41DY6S9gZrbjuq6Y+753e96WfPha5IcsOSZTtullM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.14.0 h1:3jAYbRHQAqzLjd9I4tzxwJ8Pk/N6AqBcF6m1ZHrxG94= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.14.0/go.mod h1:+N7zNjIJv4K+DeX67XXET0P+eIciESgaFDBqh+ZJFS4= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.16.0 h1:iqjq9LAB8aK++sKVcELezzn655JnBNdsDhghU4G/So8= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.16.0/go.mod h1:hGXzO5bhhSHZnKvrDaXB82Y9DRFour0Nz/KrBh7reWw= go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.14.0 h1:sEL90JjOO/4yhquXl5zTAkLLsZ5+MycAgX99SDsxGc8= go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.14.0/go.mod h1:oCslUcizYdpKYyS9e8srZEqM6BB8fq41VJBjLAE6z1w= go.opentelemetry.io/otel/exporters/zipkin v1.14.0 h1:reEVE1upBF9tcujgvSqLJS0SrI7JQPaTKP4s4rymnSs= go.opentelemetry.io/otel/exporters/zipkin v1.14.0/go.mod h1:RcjvOAcvhzcufQP8aHmzRw1gE9g/VEZufDdo2w+s4sk= -go.opentelemetry.io/otel/sdk v1.14.0 h1:PDCppFRDq8A1jL9v6KMI6dYesaq+DFcDZvjsoGvxGzY= -go.opentelemetry.io/otel/sdk v1.14.0/go.mod h1:bwIC5TjrNG6QDCHNWvW4HLHtUQ4I+VQDsnjhvyZCALM= -go.opentelemetry.io/otel/trace v1.14.0 h1:wp2Mmvj41tDsyAJXiWDWpfNsOiIyd38fy85pyKcFq/M= -go.opentelemetry.io/otel/trace v1.14.0/go.mod h1:8avnQLK+CG77yNLUae4ea2JDQ6iT+gozhnZjy/rw9G8= +go.opentelemetry.io/otel/metric v1.16.0 h1:RbrpwVG1Hfv85LgnZ7+txXioPDoh6EdbZHo26Q3hqOo= +go.opentelemetry.io/otel/metric v1.16.0/go.mod h1:QE47cpOmkwipPiefDwo2wDzwJrlfxxNYodqc4xnGCo4= +go.opentelemetry.io/otel/sdk v1.16.0 h1:Z1Ok1YsijYL0CSJpHt4cS3wDDh7p572grzNrBMiMWgE= +go.opentelemetry.io/otel/sdk v1.16.0/go.mod h1:tMsIuKXuuIWPBAOrH+eHtvhTL+SntFtXF9QD68aP6p4= +go.opentelemetry.io/otel/trace v1.16.0 h1:8JRpaObFoW0pxuVPapkgH8UhHQj+bJW8jJsCZEu5MQs= +go.opentelemetry.io/otel/trace v1.16.0/go.mod h1:Yt9vYq1SdNz3xdjZZK7wcXv1qv2pwLkqr2QVwea0ef0= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.opentelemetry.io/proto/otlp v0.19.0 h1:IVN6GR+mhC4s5yfcTbmzHYODqvWAp3ZedA2SJPI1Nnw= go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= @@ -841,8 +843,8 @@ go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/dig v1.17.0 h1:5Chju+tUvcC+N7N6EV08BJz41UZuO3BmHcN4A287ZLI= go.uber.org/dig v1.17.0/go.mod h1:rTxpf7l5I0eBTlE6/9RL+lDybC7WFwY2QH55ZSjy1mU= -go.uber.org/fx v1.19.2 h1:SyFgYQFr1Wl0AYstE8vyYIzP4bFz2URrScjwC4cwUvY= -go.uber.org/fx v1.19.2/go.mod h1:43G1VcqSzbIv77y00p1DRAsyZS8WdzuYdhZXmEUkMyQ= +go.uber.org/fx v1.19.3 h1:YqMRE4+2IepTYCMOvXqQpRa+QAVdiSTnsHU4XNWBceA= +go.uber.org/fx v1.19.3/go.mod h1:w2HrQg26ql9fLK7hlBiZ6JsRUKV+Lj/atT1KCjT8YhM= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= @@ -1126,8 +1128,8 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= -gonum.org/v1/gonum v0.11.0 h1:f1IJhK4Km5tBJmaiJXtk/PkL4cdVX6J+tGiM187uT5E= -gonum.org/v1/gonum v0.11.0/go.mod h1:fSG4YDCxxUZQJ7rKsQrj0gMOg00Il0Z96/qMA4bVQhA= +gonum.org/v1/gonum v0.13.0 h1:a0T3bh+7fhRyqeNbiC3qVHYmkiQgit3wnNan/2c0HMM= +gonum.org/v1/gonum v0.13.0/go.mod h1:/WPYRckkfWrhWefxyYTfrTtQR0KH4iyHNuzxqXAKyAU= google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y= @@ -1190,8 +1192,8 @@ google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f h1:BWUVssLB0HVOSY78gIdvk1dTVYtT1y8SBWtPYuTJ/6w= -google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 h1:DdoeryqhaXp1LtT/emMP1BRJPHHKFi5akj/nbx/zNTA= +google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= @@ -1212,8 +1214,8 @@ google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc v1.53.0 h1:LAv2ds7cmFV/XTS3XG1NneeENYrXGmorPxsBbptIjNc= -google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw= +google.golang.org/grpc v1.55.0 h1:3Oj82/tFSCeUrRTg/5E/7d/W5A1tj6Ky1ABAuZuv5ag= +google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/go.mod b/go.mod index 53f517571..bd0296e80 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ require ( contrib.go.opencensus.io/exporter/prometheus v0.4.2 github.com/benbjohnson/clock v1.3.0 github.com/blang/semver/v4 v4.0.0 - github.com/cenkalti/backoff/v4 v4.2.0 + github.com/cenkalti/backoff/v4 v4.2.1 github.com/ceramicnetwork/go-dag-jose v0.1.0 github.com/cheggaaa/pb v1.0.29 github.com/coreos/go-systemd/v22 v22.5.0 @@ -47,8 +47,8 @@ require ( github.com/libp2p/go-doh-resolver v0.4.0 github.com/libp2p/go-libp2p v0.27.5 github.com/libp2p/go-libp2p-http v0.5.0 - github.com/libp2p/go-libp2p-kad-dht v0.23.0 - github.com/libp2p/go-libp2p-kbucket v0.5.0 + github.com/libp2p/go-libp2p-kad-dht v0.24.0 + github.com/libp2p/go-libp2p-kbucket v0.6.1 github.com/libp2p/go-libp2p-pubsub v0.9.3 github.com/libp2p/go-libp2p-pubsub-router v0.6.0 github.com/libp2p/go-libp2p-record v0.2.0 @@ -60,25 +60,25 @@ require ( github.com/multiformats/go-multiaddr-dns v0.3.1 github.com/multiformats/go-multibase v0.2.0 github.com/multiformats/go-multicodec v0.9.0 - github.com/multiformats/go-multihash v0.2.2 + github.com/multiformats/go-multihash v0.2.3 github.com/opentracing/opentracing-go v1.2.0 github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.14.0 - github.com/stretchr/testify v1.8.3 + github.com/stretchr/testify v1.8.4 github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 github.com/tidwall/gjson v1.14.4 github.com/tidwall/sjson v1.2.5 github.com/whyrusleeping/go-sysinfo v0.0.0-20190219211824-4a357d4b90b1 github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 go.opencensus.io v0.24.0 - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.40.0 - go.opentelemetry.io/contrib/propagators/autoprop v0.40.0 - go.opentelemetry.io/otel v1.14.0 - go.opentelemetry.io/otel/sdk v1.14.0 - go.opentelemetry.io/otel/trace v1.14.0 + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.42.0 + go.opentelemetry.io/contrib/propagators/autoprop v0.42.0 + go.opentelemetry.io/otel v1.16.0 + go.opentelemetry.io/otel/sdk v1.16.0 + go.opentelemetry.io/otel/trace v1.16.0 go.uber.org/dig v1.17.0 - go.uber.org/fx v1.19.2 + go.uber.org/fx v1.19.3 go.uber.org/multierr v1.11.0 go.uber.org/zap v1.24.0 golang.org/x/crypto v0.9.0 @@ -202,31 +202,31 @@ require ( github.com/whyrusleeping/cbor-gen v0.0.0-20230126041949-52956bd4c9aa // indirect github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f // indirect github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect - go.opentelemetry.io/contrib/propagators/aws v1.15.0 // indirect - go.opentelemetry.io/contrib/propagators/b3 v1.15.0 // indirect - go.opentelemetry.io/contrib/propagators/jaeger v1.15.0 // indirect - go.opentelemetry.io/contrib/propagators/ot v1.15.0 // indirect + go.opentelemetry.io/contrib/propagators/aws v1.17.0 // indirect + go.opentelemetry.io/contrib/propagators/b3 v1.17.0 // indirect + go.opentelemetry.io/contrib/propagators/jaeger v1.17.0 // indirect + go.opentelemetry.io/contrib/propagators/ot v1.17.0 // indirect go.opentelemetry.io/otel/exporters/jaeger v1.14.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.14.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.14.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.16.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.16.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.14.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.14.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.16.0 // indirect go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.14.0 // indirect go.opentelemetry.io/otel/exporters/zipkin v1.14.0 // indirect - go.opentelemetry.io/otel/metric v0.37.0 // indirect + go.opentelemetry.io/otel/metric v1.16.0 // indirect go.opentelemetry.io/proto/otlp v0.19.0 // indirect go.uber.org/atomic v1.11.0 // indirect go4.org v0.0.0-20230225012048-214862532bf5 // indirect golang.org/x/net v0.10.0 // indirect - golang.org/x/oauth2 v0.5.0 // indirect + golang.org/x/oauth2 v0.6.0 // indirect golang.org/x/term v0.8.0 // indirect golang.org/x/text v0.9.0 // indirect golang.org/x/tools v0.7.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect - gonum.org/v1/gonum v0.11.0 // indirect + gonum.org/v1/gonum v0.13.0 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect - google.golang.org/grpc v1.53.0 // indirect + google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect + google.golang.org/grpc v1.55.0 // indirect google.golang.org/protobuf v1.30.0 // indirect gopkg.in/square/go-jose.v2 v2.5.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/go.sum b/go.sum index ea70323c8..fa503f351 100644 --- a/go.sum +++ b/go.sum @@ -84,8 +84,8 @@ github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= -github.com/cenkalti/backoff/v4 v4.2.0 h1:HN5dHm3WBOgndBH6E8V0q2jIYIR3s9yglV8k/+MN3u4= -github.com/cenkalti/backoff/v4 v4.2.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= +github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/ceramicnetwork/go-dag-jose v0.1.0 h1:yJ/HVlfKpnD3LdYP03AHyTvbm3BpPiz2oZiOeReJRdU= github.com/ceramicnetwork/go-dag-jose v0.1.0/go.mod h1:qYA1nYt0X8u4XoMAVoOV3upUVKtrxy/I670Dg5F0wjI= @@ -238,8 +238,8 @@ github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXP github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ= github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= +github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -546,11 +546,11 @@ github.com/libp2p/go-libp2p-gostream v0.6.0 h1:QfAiWeQRce6pqnYfmIVWJFXNdDyfiR/qk github.com/libp2p/go-libp2p-gostream v0.6.0/go.mod h1:Nywu0gYZwfj7Jc91PQvbGU8dIpqbQQkjWgDuOrFaRdA= github.com/libp2p/go-libp2p-http v0.5.0 h1:+x0AbLaUuLBArHubbbNRTsgWz0RjNTy6DJLOxQ3/QBc= github.com/libp2p/go-libp2p-http v0.5.0/go.mod h1:glh87nZ35XCQyFsdzZps6+F4HYI6DctVFY5u1fehwSg= -github.com/libp2p/go-libp2p-kad-dht v0.23.0 h1:sxE6LxLopp79eLeV695n7+c77V/Vn4AMF28AdM/XFqM= -github.com/libp2p/go-libp2p-kad-dht v0.23.0/go.mod h1:oO5N308VT2msnQI6qi5M61wzPmJYg7Tr9e16m5n7uDU= +github.com/libp2p/go-libp2p-kad-dht v0.24.0 h1:nZnFDQEFU4N8GzclnR+IGxIgR7k4PPCDk/GK9A28onk= +github.com/libp2p/go-libp2p-kad-dht v0.24.0/go.mod h1:lfu5T01EH+r6uDZ/8G+ObhwgzVyd0b1nb54AdT8XGhc= github.com/libp2p/go-libp2p-kbucket v0.3.1/go.mod h1:oyjT5O7tS9CQurok++ERgc46YLwEpuGoFq9ubvoUOio= -github.com/libp2p/go-libp2p-kbucket v0.5.0 h1:g/7tVm8ACHDxH29BGrpsQlnNeu+6OF1A9bno/4/U1oA= -github.com/libp2p/go-libp2p-kbucket v0.5.0/go.mod h1:zGzGCpQd78b5BNTDGHNDLaTt9aDK/A02xeZp9QeFC4U= +github.com/libp2p/go-libp2p-kbucket v0.6.1 h1:Y/NIvALuY5/fJlOpaJor9Azg4eor15JskGs9Lb2EhH0= +github.com/libp2p/go-libp2p-kbucket v0.6.1/go.mod h1:dvWO707Oq/vhMVuUhyfLkw0QsOrJFETepbNfpVHSELI= github.com/libp2p/go-libp2p-peerstore v0.1.4/go.mod h1:+4BDbDiiKf4PzpANZDAT+knVdLxvqh7hXOujessqdzs= github.com/libp2p/go-libp2p-pubsub v0.9.3 h1:ihcz9oIBMaCK9kcx+yHWm3mLAFBMAUsM4ux42aikDxo= github.com/libp2p/go-libp2p-pubsub v0.9.3/go.mod h1:RYA7aM9jIic5VV47WXu4GkcRxRhrdElWf8xtyli+Dzc= @@ -676,8 +676,8 @@ github.com/multiformats/go-multihash v0.0.13/go.mod h1:VdAWLKTwram9oKAatUcLxBNUj github.com/multiformats/go-multihash v0.0.14/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= github.com/multiformats/go-multihash v0.0.15/go.mod h1:D6aZrWNLFTV/ynMpKsNtB40mJzmCl4jb1alC0OvHiHg= github.com/multiformats/go-multihash v0.1.0/go.mod h1:RJlXsxt6vHGaia+S8We0ErjhojtKzPP2AH4+kYM7k84= -github.com/multiformats/go-multihash v0.2.2 h1:Uu7LWs/PmWby1gkj1S1DXx3zyd3aVabA4FiMKn/2tAc= -github.com/multiformats/go-multihash v0.2.2/go.mod h1:dXgKXCXjBzdscBLk9JkjINiEsCKRVch90MdaGiKsvSM= +github.com/multiformats/go-multihash v0.2.3 h1:7Lyc8XfX/IY2jWb/gI7JP+o7JEq9hOa7BFvVU9RSh+U= +github.com/multiformats/go-multihash v0.2.3/go.mod h1:dXgKXCXjBzdscBLk9JkjINiEsCKRVch90MdaGiKsvSM= github.com/multiformats/go-multistream v0.4.1 h1:rFy0Iiyn3YT0asivDUIR05leAdwZq3de4741sbiSdfo= github.com/multiformats/go-multistream v0.4.1/go.mod h1:Mz5eykRVAjJWckE2U78c6xqdtyNUEhKSM0Lwar2p77Q= github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= @@ -851,8 +851,8 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY= -github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stvp/go-udp-testing v0.0.0-20201019212854-469649b16807/go.mod h1:7jxmlfBCDBXRzr0eAQJ48XC1hBu1np4CS5+cHEYfwpc= github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= @@ -926,40 +926,40 @@ go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.40.0 h1:lE9EJyw3/JhrjWH/hEy9FptnalDQgj7vpbgC2KCCCxE= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.40.0/go.mod h1:pcQ3MM3SWvrA71U4GDqv9UFDJ3HQsW7y5ZO3tDTlUdI= -go.opentelemetry.io/contrib/propagators/autoprop v0.40.0 h1:Lj33jj7eIrBfIShiK8NU91u2BglKnUS1UUxVemuQJtw= -go.opentelemetry.io/contrib/propagators/autoprop v0.40.0/go.mod h1:6QO816FeZ+6zahs6hYqbUCCsnNBm7o+t4iwVySpzcdI= -go.opentelemetry.io/contrib/propagators/aws v1.15.0 h1:FLe+bRTMAhEALItDQt1U2S/rdq8/rGGJTJpOpCDvMu0= -go.opentelemetry.io/contrib/propagators/aws v1.15.0/go.mod h1:Z/nqdjqKjErrS3gYoEMZt8//dt8VZbqalD0V+7vh7lM= -go.opentelemetry.io/contrib/propagators/b3 v1.15.0 h1:bMaonPyFcAvZ4EVzkUNkfnUHP5Zi63CIDlA3dRsEg8Q= -go.opentelemetry.io/contrib/propagators/b3 v1.15.0/go.mod h1:VjU0g2v6HSQ+NwfifambSLAeBgevjIcqmceaKWEzl0c= -go.opentelemetry.io/contrib/propagators/jaeger v1.15.0 h1:xdJjwy5t/8I+TZehMMQ+r2h50HREihH2oMUhimQ+jug= -go.opentelemetry.io/contrib/propagators/jaeger v1.15.0/go.mod h1:tU0nwW4QTvKceNUP60/PQm0FI8zDSwey7gIFt3RR/yw= -go.opentelemetry.io/contrib/propagators/ot v1.15.0 h1:iBNejawWy7wWZ5msuZDNcMjBy14Wc0v3gCAXukGHN/Q= -go.opentelemetry.io/contrib/propagators/ot v1.15.0/go.mod h1:0P7QQ+MHt6SXR1ATaMpewSiWlp8NbKErNLKcaU4EEKI= -go.opentelemetry.io/otel v1.14.0 h1:/79Huy8wbf5DnIPhemGB+zEPVwnN6fuQybr/SRXa6hM= -go.opentelemetry.io/otel v1.14.0/go.mod h1:o4buv+dJzx8rohcUeRmWUZhqupFvzWis188WlggnNeU= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.42.0 h1:pginetY7+onl4qN1vl0xW/V/v6OBZ0vVdH+esuJgvmM= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.42.0/go.mod h1:XiYsayHc36K3EByOO6nbAXnAWbrUxdjUROCEeeROOH8= +go.opentelemetry.io/contrib/propagators/autoprop v0.42.0 h1:s2RzYOAqHVgG23q8fPWYChobUoZM6rJZ98EnylJr66w= +go.opentelemetry.io/contrib/propagators/autoprop v0.42.0/go.mod h1:Mv/tWNtZn+NbALDb2XcItP0OM3lWWZjAfSroINxfW+Y= +go.opentelemetry.io/contrib/propagators/aws v1.17.0 h1:IX8d7l2uRw61BlmZBOTQFaK+y22j6vytMVTs9wFrO+c= +go.opentelemetry.io/contrib/propagators/aws v1.17.0/go.mod h1:pAlCYRWff4uGqRXOVn3WP8pDZ5E0K56bEoG7a1VSL4k= +go.opentelemetry.io/contrib/propagators/b3 v1.17.0 h1:ImOVvHnku8jijXqkwCSyYKRDt2YrnGXD4BbhcpfbfJo= +go.opentelemetry.io/contrib/propagators/b3 v1.17.0/go.mod h1:IkfUfMpKWmynvvE0264trz0sf32NRTZL4nuAN9AbWRc= +go.opentelemetry.io/contrib/propagators/jaeger v1.17.0 h1:Zbpbmwav32Ea5jSotpmkWEl3a6Xvd4tw/3xxGO1i05Y= +go.opentelemetry.io/contrib/propagators/jaeger v1.17.0/go.mod h1:tcTUAlmO8nuInPDSBVfG+CP6Mzjy5+gNV4mPxMbL0IA= +go.opentelemetry.io/contrib/propagators/ot v1.17.0 h1:ufo2Vsz8l76eI47jFjuVyjyB3Ae2DmfiCV/o6Vc8ii0= +go.opentelemetry.io/contrib/propagators/ot v1.17.0/go.mod h1:SbKPj5XGp8K/sGm05XblaIABgMgw2jDczP8gGeuaVLk= +go.opentelemetry.io/otel v1.16.0 h1:Z7GVAX/UkAXPKsy94IU+i6thsQS4nb7LviLpnaNeW8s= +go.opentelemetry.io/otel v1.16.0/go.mod h1:vl0h9NUa1D5s1nv3A5vZOYWn8av4K8Ml6JDeHrT/bx4= go.opentelemetry.io/otel/exporters/jaeger v1.14.0 h1:CjbUNd4iN2hHmWekmOqZ+zSCU+dzZppG8XsV+A3oc8Q= go.opentelemetry.io/otel/exporters/jaeger v1.14.0/go.mod h1:4Ay9kk5vELRrbg5z4cpP9EtmQRFap2Wb0woPG4lujZA= -go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.14.0 h1:/fXHZHGvro6MVqV34fJzDhi7sHGpX3Ej/Qjmfn003ho= -go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.14.0/go.mod h1:UFG7EBMRdXyFstOwH028U0sVf+AvukSGhF0g8+dmNG8= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.14.0 h1:TKf2uAs2ueguzLaxOCBXNpHxfO/aC7PAdDsSH0IbeRQ= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.14.0/go.mod h1:HrbCVv40OOLTABmOn1ZWty6CHXkU8DK/Urc43tHug70= +go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.16.0 h1:t4ZwRPU+emrcvM2e9DHd0Fsf0JTPVcbfa/BhTDF03d0= +go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.16.0/go.mod h1:vLarbg68dH2Wa77g71zmKQqlQ8+8Rq3GRG31uc0WcWI= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.16.0 h1:cbsD4cUcviQGXdw8+bo5x2wazq10SKz8hEbtCRPcU78= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.16.0/go.mod h1:JgXSGah17croqhJfhByOLVY719k1emAXC8MVhCIJlRs= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.14.0 h1:ap+y8RXX3Mu9apKVtOkM6WSFESLM8K3wNQyOU8sWHcc= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.14.0/go.mod h1:5w41DY6S9gZrbjuq6Y+753e96WfPha5IcsOSZTtullM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.14.0 h1:3jAYbRHQAqzLjd9I4tzxwJ8Pk/N6AqBcF6m1ZHrxG94= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.14.0/go.mod h1:+N7zNjIJv4K+DeX67XXET0P+eIciESgaFDBqh+ZJFS4= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.16.0 h1:iqjq9LAB8aK++sKVcELezzn655JnBNdsDhghU4G/So8= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.16.0/go.mod h1:hGXzO5bhhSHZnKvrDaXB82Y9DRFour0Nz/KrBh7reWw= go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.14.0 h1:sEL90JjOO/4yhquXl5zTAkLLsZ5+MycAgX99SDsxGc8= go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.14.0/go.mod h1:oCslUcizYdpKYyS9e8srZEqM6BB8fq41VJBjLAE6z1w= go.opentelemetry.io/otel/exporters/zipkin v1.14.0 h1:reEVE1upBF9tcujgvSqLJS0SrI7JQPaTKP4s4rymnSs= go.opentelemetry.io/otel/exporters/zipkin v1.14.0/go.mod h1:RcjvOAcvhzcufQP8aHmzRw1gE9g/VEZufDdo2w+s4sk= -go.opentelemetry.io/otel/metric v0.37.0 h1:pHDQuLQOZwYD+Km0eb657A25NaRzy0a+eLyKfDXedEs= -go.opentelemetry.io/otel/metric v0.37.0/go.mod h1:DmdaHfGt54iV6UKxsV9slj2bBRJcKC1B1uvDLIioc1s= -go.opentelemetry.io/otel/sdk v1.14.0 h1:PDCppFRDq8A1jL9v6KMI6dYesaq+DFcDZvjsoGvxGzY= -go.opentelemetry.io/otel/sdk v1.14.0/go.mod h1:bwIC5TjrNG6QDCHNWvW4HLHtUQ4I+VQDsnjhvyZCALM= -go.opentelemetry.io/otel/trace v1.14.0 h1:wp2Mmvj41tDsyAJXiWDWpfNsOiIyd38fy85pyKcFq/M= -go.opentelemetry.io/otel/trace v1.14.0/go.mod h1:8avnQLK+CG77yNLUae4ea2JDQ6iT+gozhnZjy/rw9G8= +go.opentelemetry.io/otel/metric v1.16.0 h1:RbrpwVG1Hfv85LgnZ7+txXioPDoh6EdbZHo26Q3hqOo= +go.opentelemetry.io/otel/metric v1.16.0/go.mod h1:QE47cpOmkwipPiefDwo2wDzwJrlfxxNYodqc4xnGCo4= +go.opentelemetry.io/otel/sdk v1.16.0 h1:Z1Ok1YsijYL0CSJpHt4cS3wDDh7p572grzNrBMiMWgE= +go.opentelemetry.io/otel/sdk v1.16.0/go.mod h1:tMsIuKXuuIWPBAOrH+eHtvhTL+SntFtXF9QD68aP6p4= +go.opentelemetry.io/otel/trace v1.16.0 h1:8JRpaObFoW0pxuVPapkgH8UhHQj+bJW8jJsCZEu5MQs= +go.opentelemetry.io/otel/trace v1.16.0/go.mod h1:Yt9vYq1SdNz3xdjZZK7wcXv1qv2pwLkqr2QVwea0ef0= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.opentelemetry.io/proto/otlp v0.19.0 h1:IVN6GR+mhC4s5yfcTbmzHYODqvWAp3ZedA2SJPI1Nnw= go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= @@ -970,8 +970,8 @@ go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/dig v1.17.0 h1:5Chju+tUvcC+N7N6EV08BJz41UZuO3BmHcN4A287ZLI= go.uber.org/dig v1.17.0/go.mod h1:rTxpf7l5I0eBTlE6/9RL+lDybC7WFwY2QH55ZSjy1mU= -go.uber.org/fx v1.19.2 h1:SyFgYQFr1Wl0AYstE8vyYIzP4bFz2URrScjwC4cwUvY= -go.uber.org/fx v1.19.2/go.mod h1:43G1VcqSzbIv77y00p1DRAsyZS8WdzuYdhZXmEUkMyQ= +go.uber.org/fx v1.19.3 h1:YqMRE4+2IepTYCMOvXqQpRa+QAVdiSTnsHU4XNWBceA= +go.uber.org/fx v1.19.3/go.mod h1:w2HrQg26ql9fLK7hlBiZ6JsRUKV+Lj/atT1KCjT8YhM= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= @@ -1107,8 +1107,8 @@ golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4Iltr golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.5.0 h1:HuArIo48skDwlrvM3sEdHXElYslAMsf3KwRkkW4MC4s= -golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I= +golang.org/x/oauth2 v0.6.0 h1:Lh8GPgSKBfWSwFvtuWOfeI3aAAnbXTSutYxJiOJFgIw= +golang.org/x/oauth2 v0.6.0/go.mod h1:ycmewcwgD4Rpr3eZJLSB4Kyyljb3qDh40vJ8STE5HKw= golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1280,8 +1280,8 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= -gonum.org/v1/gonum v0.11.0 h1:f1IJhK4Km5tBJmaiJXtk/PkL4cdVX6J+tGiM187uT5E= -gonum.org/v1/gonum v0.11.0/go.mod h1:fSG4YDCxxUZQJ7rKsQrj0gMOg00Il0Z96/qMA4bVQhA= +gonum.org/v1/gonum v0.13.0 h1:a0T3bh+7fhRyqeNbiC3qVHYmkiQgit3wnNan/2c0HMM= +gonum.org/v1/gonum v0.13.0/go.mod h1:/WPYRckkfWrhWefxyYTfrTtQR0KH4iyHNuzxqXAKyAU= google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y= @@ -1346,8 +1346,8 @@ google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f h1:BWUVssLB0HVOSY78gIdvk1dTVYtT1y8SBWtPYuTJ/6w= -google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 h1:DdoeryqhaXp1LtT/emMP1BRJPHHKFi5akj/nbx/zNTA= +google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= @@ -1368,8 +1368,8 @@ google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc v1.53.0 h1:LAv2ds7cmFV/XTS3XG1NneeENYrXGmorPxsBbptIjNc= -google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw= +google.golang.org/grpc v1.55.0 h1:3Oj82/tFSCeUrRTg/5E/7d/W5A1tj6Ky1ABAuZuv5ag= +google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 579fd5a30..2564e2bdc 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -21,7 +21,7 @@ require ( github.com/jbenet/go-random-files v0.0.0-20190219210431-31b3f20ebded github.com/libp2p/go-libp2p v0.27.5 github.com/multiformats/go-multiaddr v0.9.0 - github.com/multiformats/go-multihash v0.2.2 + github.com/multiformats/go-multihash v0.2.3 gotest.tools/gotestsum v0.4.2 ) @@ -243,7 +243,7 @@ require ( github.com/ssgreg/nlreturn/v2 v2.2.1 // indirect github.com/stbenjam/no-sprintf-host-port v0.1.1 // indirect github.com/stretchr/objx v0.5.0 // indirect - github.com/stretchr/testify v1.8.3 // indirect + github.com/stretchr/testify v1.8.4 // indirect github.com/subosito/gotenv v1.4.0 // indirect github.com/sylvia7788/contextcheck v1.0.6 // indirect github.com/tdakkota/asciicheck v0.1.1 // indirect @@ -259,11 +259,12 @@ require ( github.com/yagipy/maintidx v1.0.0 // indirect github.com/yeya24/promlinter v0.2.0 // indirect gitlab.com/bosi/decorder v0.2.3 // indirect - go.opentelemetry.io/otel v1.14.0 // indirect - go.opentelemetry.io/otel/trace v1.14.0 // indirect + go.opentelemetry.io/otel v1.16.0 // indirect + go.opentelemetry.io/otel/metric v1.16.0 // indirect + go.opentelemetry.io/otel/trace v1.16.0 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/dig v1.17.0 // indirect - go.uber.org/fx v1.19.2 // indirect + go.uber.org/fx v1.19.3 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.24.0 // indirect golang.org/x/crypto v0.9.0 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index bb8d2a267..a8ed1279e 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -668,8 +668,8 @@ github.com/multiformats/go-multicodec v0.9.0 h1:pb/dlPnzee/Sxv/j4PmkDRxCOi3hXTz3 github.com/multiformats/go-multicodec v0.9.0/go.mod h1:L3QTQvMIaVBkXOXXtVmYE+LI16i14xuaojr/H7Ai54k= github.com/multiformats/go-multihash v0.0.8/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= github.com/multiformats/go-multihash v0.0.13/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= -github.com/multiformats/go-multihash v0.2.2 h1:Uu7LWs/PmWby1gkj1S1DXx3zyd3aVabA4FiMKn/2tAc= -github.com/multiformats/go-multihash v0.2.2/go.mod h1:dXgKXCXjBzdscBLk9JkjINiEsCKRVch90MdaGiKsvSM= +github.com/multiformats/go-multihash v0.2.3 h1:7Lyc8XfX/IY2jWb/gI7JP+o7JEq9hOa7BFvVU9RSh+U= +github.com/multiformats/go-multihash v0.2.3/go.mod h1:dXgKXCXjBzdscBLk9JkjINiEsCKRVch90MdaGiKsvSM= github.com/multiformats/go-multistream v0.4.1 h1:rFy0Iiyn3YT0asivDUIR05leAdwZq3de4741sbiSdfo= github.com/multiformats/go-multistream v0.4.1/go.mod h1:Mz5eykRVAjJWckE2U78c6xqdtyNUEhKSM0Lwar2p77Q= github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= @@ -883,8 +883,8 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY= -github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/subosito/gotenv v1.4.0 h1:yAzM1+SmVcz5R4tXGsNMu1jUl2aOJXoiWUCEwwnGrvs= github.com/subosito/gotenv v1.4.0/go.mod h1:mZd6rFysKEcUhUHXJk0C/08wAgyDBFuwEYL7vWWGaGo= github.com/sylvia7788/contextcheck v1.0.6 h1:o2EZgVPyMKE/Mtoqym61DInKEjwEbsmyoxg3VrmjNO4= @@ -948,19 +948,21 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= -go.opentelemetry.io/otel v1.14.0 h1:/79Huy8wbf5DnIPhemGB+zEPVwnN6fuQybr/SRXa6hM= -go.opentelemetry.io/otel v1.14.0/go.mod h1:o4buv+dJzx8rohcUeRmWUZhqupFvzWis188WlggnNeU= -go.opentelemetry.io/otel/sdk v1.14.0 h1:PDCppFRDq8A1jL9v6KMI6dYesaq+DFcDZvjsoGvxGzY= -go.opentelemetry.io/otel/trace v1.14.0 h1:wp2Mmvj41tDsyAJXiWDWpfNsOiIyd38fy85pyKcFq/M= -go.opentelemetry.io/otel/trace v1.14.0/go.mod h1:8avnQLK+CG77yNLUae4ea2JDQ6iT+gozhnZjy/rw9G8= +go.opentelemetry.io/otel v1.16.0 h1:Z7GVAX/UkAXPKsy94IU+i6thsQS4nb7LviLpnaNeW8s= +go.opentelemetry.io/otel v1.16.0/go.mod h1:vl0h9NUa1D5s1nv3A5vZOYWn8av4K8Ml6JDeHrT/bx4= +go.opentelemetry.io/otel/metric v1.16.0 h1:RbrpwVG1Hfv85LgnZ7+txXioPDoh6EdbZHo26Q3hqOo= +go.opentelemetry.io/otel/metric v1.16.0/go.mod h1:QE47cpOmkwipPiefDwo2wDzwJrlfxxNYodqc4xnGCo4= +go.opentelemetry.io/otel/sdk v1.16.0 h1:Z1Ok1YsijYL0CSJpHt4cS3wDDh7p572grzNrBMiMWgE= +go.opentelemetry.io/otel/trace v1.16.0 h1:8JRpaObFoW0pxuVPapkgH8UhHQj+bJW8jJsCZEu5MQs= +go.opentelemetry.io/otel/trace v1.16.0/go.mod h1:Yt9vYq1SdNz3xdjZZK7wcXv1qv2pwLkqr2QVwea0ef0= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/dig v1.17.0 h1:5Chju+tUvcC+N7N6EV08BJz41UZuO3BmHcN4A287ZLI= go.uber.org/dig v1.17.0/go.mod h1:rTxpf7l5I0eBTlE6/9RL+lDybC7WFwY2QH55ZSjy1mU= -go.uber.org/fx v1.19.2 h1:SyFgYQFr1Wl0AYstE8vyYIzP4bFz2URrScjwC4cwUvY= -go.uber.org/fx v1.19.2/go.mod h1:43G1VcqSzbIv77y00p1DRAsyZS8WdzuYdhZXmEUkMyQ= +go.uber.org/fx v1.19.3 h1:YqMRE4+2IepTYCMOvXqQpRa+QAVdiSTnsHU4XNWBceA= +go.uber.org/fx v1.19.3/go.mod h1:w2HrQg26ql9fLK7hlBiZ6JsRUKV+Lj/atT1KCjT8YhM= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= From e2128107f632a828c8234ce79079e79756d3ccb6 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Mon, 12 Jun 2023 15:35:17 +0200 Subject: [PATCH 0712/1212] Revert "feat: adds secp256k1 keypair type to key gen command, adds test cases" This reverts commit 67e1a173fcde1b7c4b09464184aea8ef86bedab2. --- core/commands/keystore.go | 6 +++--- core/coreapi/key.go | 8 -------- test/sharness/lib/test-lib.sh | 16 ---------------- test/sharness/t0027-rotate.sh | 7 ------- test/sharness/t0165-keystore.sh | 31 ------------------------------- 5 files changed, 3 insertions(+), 65 deletions(-) diff --git a/core/commands/keystore.go b/core/commands/keystore.go index cf3e75b7d..ed0d5d4e9 100644 --- a/core/commands/keystore.go +++ b/core/commands/keystore.go @@ -83,7 +83,7 @@ var keyGenCmd = &cmds.Command{ Tagline: "Create a new keypair", }, Options: []cmds.Option{ - cmds.StringOption(keyStoreTypeOptionName, "t", "type of the key to create: rsa, ed25519, secp256k1").WithDefault(keyStoreAlgorithmDefault), + cmds.StringOption(keyStoreTypeOptionName, "t", "type of the key to create: rsa, ed25519").WithDefault(keyStoreAlgorithmDefault), cmds.IntOption(keyStoreSizeOptionName, "s", "size of the key to generate"), ke.OptionIPNSBase, }, @@ -398,7 +398,7 @@ The PEM format allows for key generation outside of the IPFS node: allowAnyKeyType, _ := req.Options[keyAllowAnyTypeOptionName].(bool) if !allowAnyKeyType { switch t := sk.(type) { - case *crypto.RsaPrivateKey, *crypto.Ed25519PrivateKey, *crypto.Secp256k1PrivateKey: + case *crypto.RsaPrivateKey, *crypto.Ed25519PrivateKey: default: return fmt.Errorf("key type %T is not allowed to be imported, only RSA or Ed25519;"+ " use flag --%s if you are sure of what you're doing", @@ -604,7 +604,7 @@ environment variable: Arguments: []cmds.Argument{}, Options: []cmds.Option{ cmds.StringOption(oldKeyOptionName, "o", "Keystore name to use for backing up your existing identity"), - cmds.StringOption(keyStoreTypeOptionName, "t", "type of the key to create: rsa, ed25519, secp256k1").WithDefault(keyStoreAlgorithmDefault), + cmds.StringOption(keyStoreTypeOptionName, "t", "type of the key to create: rsa, ed25519").WithDefault(keyStoreAlgorithmDefault), cmds.IntOption(keyStoreSizeOptionName, "s", "size of the key to generate"), }, NoRemote: true, diff --git a/core/coreapi/key.go b/core/coreapi/key.go index 743f2076e..925748a37 100644 --- a/core/coreapi/key.go +++ b/core/coreapi/key.go @@ -82,14 +82,6 @@ func (api *KeyAPI) Generate(ctx context.Context, name string, opts ...caopts.Key return nil, err } - sk = priv - pk = pub - case "secp256k1": - priv, pub, err := crypto.GenerateSecp256k1Key(rand.Reader) - if err != nil { - return nil, err - } - sk = priv pk = pub default: diff --git a/test/sharness/lib/test-lib.sh b/test/sharness/lib/test-lib.sh index 35c4ae835..bd8f7de9b 100644 --- a/test/sharness/lib/test-lib.sh +++ b/test/sharness/lib/test-lib.sh @@ -486,14 +486,6 @@ test_check_ed25519_b58mh_peerid() { } } -test_check_secp256k1_b58mh_peerid() { - peeridlen=$(echo "$1" | tr -dC "[:alnum:]" | wc -c | tr -d " ") && - test "$peeridlen" = "53" || { - echo "Bad SECP256K1 B58MH peerid '$1' with len '$peeridlen'" - return 1 - } -} - test_check_rsa2048_base36_peerid() { peeridlen=$(echo "$1" | tr -dC "[:alnum:]" | wc -c | tr -d " ") && test "$peeridlen" = "56" || { @@ -510,14 +502,6 @@ test_check_ed25519_base36_peerid() { } } -test_check_secp256k1_base36_peerid() { - peeridlen=$(echo "$1" | tr -dC "[:alnum:]" | wc -c | tr -d " ") && - test "$peeridlen" = "63" || { - echo "Bad SECP256K1 B36CID peerid '$1' with len '$peeridlen'" - return 1 - } -} - convert_tcp_maddr() { echo $1 | awk -F'/' '{ printf "%s:%s", $3, $5 }' } diff --git a/test/sharness/t0027-rotate.sh b/test/sharness/t0027-rotate.sh index 982b70a92..b3e748e90 100755 --- a/test/sharness/t0027-rotate.sh +++ b/test/sharness/t0027-rotate.sh @@ -87,19 +87,12 @@ test_rotate() { } test_rotate 'rsa' '' test_rotate 'ed25519' '' -test_rotate 'secp256k1' '' test_rotate '' '' test_rotate 'rsa' 'rsa' test_rotate 'ed25519' 'rsa' -test_rotate 'secp256k1' 'rsa' test_rotate '' 'rsa' test_rotate 'rsa' 'ed25519' test_rotate 'ed25519' 'ed25519' -test_rotate 'secp256k1' 'ed25519' test_rotate '' 'ed25519' -test_rotate 'rsa' 'secp256k1' -test_rotate 'ed25519' 'secp256k1' -test_rotate 'secp256k1' 'secp256k1' -test_rotate '' 'secp256k1' test_done diff --git a/test/sharness/t0165-keystore.sh b/test/sharness/t0165-keystore.sh index 2fc7c2e67..60089ecd7 100755 --- a/test/sharness/t0165-keystore.sh +++ b/test/sharness/t0165-keystore.sh @@ -55,29 +55,6 @@ PEERID=$(ipfs key list --ipns-base=base36 -l | grep key_ed25519 | head -n 1 | cu test_check_ed25519_base36_peerid $PEERID && ipfs key rm key_ed25519 ' - -test_expect_success "create an SECP256k1 key and test B58MH/B36CID output formats" ' -PEERID=$(ipfs key gen --ipns-base=b58mh --type=secp256k1 key_secp256k1) && -test_check_secp256k1_b58mh_peerid $PEERID && -ipfs key rm key_secp256k1 && -PEERID=$(ipfs key gen --ipns-base=base36 --type=secp256k1 key_secp256k1) && -test_check_secp256k1_base36_peerid $PEERID -' - -test_expect_success "test SECP256k1 key sk export format" ' -ipfs key export key_secp256k1 && -test_check_ed25519_sk key_secp256k1.key && -rm key_secp256k1.key -' - -test_expect_success "test SECP256k1 key B58MH/B36CID multihash format" ' -PEERID=$(ipfs key list --ipns-base=b58mh -l | grep key_secp256k1 | head -n 1 | cut -d " " -f1) && -test_check_secp256k1_b58mh_peerid $PEERID && -PEERID=$(ipfs key list --ipns-base=base36 -l | grep key_secp256k1 | head -n 1 | cut -d " " -f1) && -test_check_secp256k1_base36_peerid $PEERID && -ipfs key rm key_secp256k1 -' - # end of format test @@ -95,11 +72,6 @@ ipfs key rm key_secp256k1 test_key_import_export_all_formats ed25519_key - test_expect_success "create a new secp256k1 key" ' - k1hash=$(ipfs key gen generated_secp256k1_key --type=secp256k1) - echo $k1hash > secp256k1_key_id - ' - test_openssl_compatibility_all_types INVALID_KEY=../t0165-keystore-data/openssl_secp384r1.pem @@ -144,7 +116,6 @@ ipfs key rm key_secp256k1 test_expect_success "all keys show up in list output" ' echo generated_ed25519_key > list_exp && echo generated_rsa_key >> list_exp && - echo generated_secp256k1_key >> list_exp && echo quxel >> list_exp && echo self >> list_exp ipfs key list > list_out && @@ -164,7 +135,6 @@ ipfs key rm key_secp256k1 test_expect_success "key rm remove a key" ' ipfs key rm generated_rsa_key echo generated_ed25519_key > list_exp && - echo generated_secp256k1_key >> list_exp && echo quxel >> list_exp && echo self >> list_exp ipfs key list > list_out && @@ -179,7 +149,6 @@ ipfs key rm key_secp256k1 test_expect_success "key rename rename a key" ' ipfs key rename generated_ed25519_key fooed echo fooed > list_exp && - echo generated_secp256k1_key >> list_exp && echo quxel >> list_exp && echo self >> list_exp ipfs key list > list_out && From b55cd72657e5edc44f58c54db8d58b7cd43221e2 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Thu, 8 Jun 2023 11:57:38 +0200 Subject: [PATCH 0713/1212] fix: print rcmgr to logger --- core/node/libp2p/rcmgr.go | 11 ++++++----- test/sharness/t0060-daemon.sh | 7 ------- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/core/node/libp2p/rcmgr.go b/core/node/libp2p/rcmgr.go index c61f8dcfe..bc723d7e3 100644 --- a/core/node/libp2p/rcmgr.go +++ b/core/node/libp2p/rcmgr.go @@ -23,6 +23,8 @@ import ( "github.com/ipfs/kubo/repo" ) +var rcmgrLogger = logging.Logger("rcmgr") + const NetLimitTraceFilename = "rcmgr.json.gz" var ErrNoResourceMgr = fmt.Errorf("missing ResourceMgr: make sure the daemon is running with Swarm.ResourceMgr.Enabled") @@ -56,14 +58,13 @@ func ResourceManager(cfg config.SwarmConfig, userResourceOverrides rcmgr.Partial } if !isPartialConfigEmpty(userResourceOverrides) { - fmt.Print(` + rcmgrLogger.Info(` libp2p-resource-limit-overrides.json has been loaded, "default" fields will be -filled in with autocomputed defaults. -`) +filled in with autocomputed defaults.`) } // We want to see this message on startup, that's why we are using fmt instead of log. - fmt.Print(msg) + rcmgrLogger.Info(msg) if err := ensureConnMgrMakeSenseVsResourceMgr(limitConfig, cfg); err != nil { return nil, opts, err @@ -109,7 +110,7 @@ filled in with autocomputed defaults. lrm.start(helpers.LifecycleCtx(mctx, lc)) manager = lrm } else { - fmt.Println("go-libp2p resource manager protection disabled") + rcmgrLogger.Info("go-libp2p resource manager protection disabled") manager = &network.NullResourceManager{} } diff --git a/test/sharness/t0060-daemon.sh b/test/sharness/t0060-daemon.sh index f43708b1d..29474c7ff 100755 --- a/test/sharness/t0060-daemon.sh +++ b/test/sharness/t0060-daemon.sh @@ -80,13 +80,6 @@ test_expect_success "ipfs daemon output looks good" ' STARTFILE="ipfs cat /ipfs/$HASH_WELCOME_DOCS/readme" && echo "Initializing daemon..." >expected_daemon && ipfs version --all >> expected_daemon && - echo "" >>expected_daemon && - echo "Computed default go-libp2p Resource Manager limits based on:" >>expected_daemon && - echo " - '"'"'Swarm.ResourceMgr.MaxMemory'"'"': \"4GB\"" >>expected_daemon && - echo " - '"'"'Swarm.ResourceMgr.MaxFileDescriptors'"'"': 1024" >>expected_daemon && - echo "" >>expected_daemon && - echo "Theses can be inspected with '"'"'ipfs swarm resources'"'"'." >>expected_daemon && - echo "" >>expected_daemon && sed "s/^/Swarm listening on /" listen_addrs >>expected_daemon && sed "s/^/Swarm announcing /" local_addrs >>expected_daemon && echo "RPC API server listening on '$API_MADDR'" >>expected_daemon && From 696b3a471b0ab93d931b4b7cb572e8b91056cc5a Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Mon, 12 Jun 2023 13:47:57 +0000 Subject: [PATCH 0714/1212] chore: update version --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index bf6419ec6..dce4e39ec 100644 --- a/version.go +++ b/version.go @@ -11,7 +11,7 @@ import ( var CurrentCommit string // CurrentVersionNumber is the current application's version literal -const CurrentVersionNumber = "0.21.0-dev" +const CurrentVersionNumber = "0.21.0-rc1" const ApiVersion = "/kubo/" + CurrentVersionNumber + "/" //nolint From cfe52e0924fdaae7ac678bd2e5a8d23867a5a74a Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Mon, 12 Jun 2023 14:34:31 +0000 Subject: [PATCH 0715/1212] chore: update version --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index bf6419ec6..8050b14d1 100644 --- a/version.go +++ b/version.go @@ -11,7 +11,7 @@ import ( var CurrentCommit string // CurrentVersionNumber is the current application's version literal -const CurrentVersionNumber = "0.21.0-dev" +const CurrentVersionNumber = "0.22.0-dev" const ApiVersion = "/kubo/" + CurrentVersionNumber + "/" //nolint From 18db5935ef81917fab01d8bd911d784d6f184910 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Tue, 13 Jun 2023 14:43:57 +0200 Subject: [PATCH 0716/1212] fix: more stable prometheus test (#9944) --- .../t0119-prometheus-data/prometheus_metrics | 379 ------------------ test/sharness/t0119-prometheus.sh | 4 +- 2 files changed, 2 insertions(+), 381 deletions(-) diff --git a/test/sharness/t0119-prometheus-data/prometheus_metrics b/test/sharness/t0119-prometheus-data/prometheus_metrics index 5db8a7665..22239ff19 100644 --- a/test/sharness/t0119-prometheus-data/prometheus_metrics +++ b/test/sharness/t0119-prometheus-data/prometheus_metrics @@ -1,169 +1,83 @@ flatfs_datastore_batchcommit_errors_total flatfs_datastore_batchcommit_latency_seconds_bucket -flatfs_datastore_batchcommit_latency_seconds_bucket -flatfs_datastore_batchcommit_latency_seconds_bucket -flatfs_datastore_batchcommit_latency_seconds_bucket -flatfs_datastore_batchcommit_latency_seconds_bucket -flatfs_datastore_batchcommit_latency_seconds_bucket flatfs_datastore_batchcommit_latency_seconds_count flatfs_datastore_batchcommit_latency_seconds_sum flatfs_datastore_batchcommit_total flatfs_datastore_batchdelete_errors_total flatfs_datastore_batchdelete_latency_seconds_bucket -flatfs_datastore_batchdelete_latency_seconds_bucket -flatfs_datastore_batchdelete_latency_seconds_bucket -flatfs_datastore_batchdelete_latency_seconds_bucket -flatfs_datastore_batchdelete_latency_seconds_bucket -flatfs_datastore_batchdelete_latency_seconds_bucket flatfs_datastore_batchdelete_latency_seconds_count flatfs_datastore_batchdelete_latency_seconds_sum flatfs_datastore_batchdelete_total flatfs_datastore_batchput_errors_total flatfs_datastore_batchput_latency_seconds_bucket -flatfs_datastore_batchput_latency_seconds_bucket -flatfs_datastore_batchput_latency_seconds_bucket -flatfs_datastore_batchput_latency_seconds_bucket -flatfs_datastore_batchput_latency_seconds_bucket -flatfs_datastore_batchput_latency_seconds_bucket flatfs_datastore_batchput_latency_seconds_count flatfs_datastore_batchput_latency_seconds_sum flatfs_datastore_batchput_size_bytes_bucket -flatfs_datastore_batchput_size_bytes_bucket -flatfs_datastore_batchput_size_bytes_bucket -flatfs_datastore_batchput_size_bytes_bucket -flatfs_datastore_batchput_size_bytes_bucket flatfs_datastore_batchput_size_bytes_count flatfs_datastore_batchput_size_bytes_sum flatfs_datastore_batchput_total flatfs_datastore_check_errors_total flatfs_datastore_check_latency_seconds_bucket -flatfs_datastore_check_latency_seconds_bucket -flatfs_datastore_check_latency_seconds_bucket -flatfs_datastore_check_latency_seconds_bucket -flatfs_datastore_check_latency_seconds_bucket -flatfs_datastore_check_latency_seconds_bucket flatfs_datastore_check_latency_seconds_count flatfs_datastore_check_latency_seconds_sum flatfs_datastore_check_total flatfs_datastore_delete_errors_total flatfs_datastore_delete_latency_seconds_bucket -flatfs_datastore_delete_latency_seconds_bucket -flatfs_datastore_delete_latency_seconds_bucket -flatfs_datastore_delete_latency_seconds_bucket -flatfs_datastore_delete_latency_seconds_bucket -flatfs_datastore_delete_latency_seconds_bucket flatfs_datastore_delete_latency_seconds_count flatfs_datastore_delete_latency_seconds_sum flatfs_datastore_delete_total flatfs_datastore_du_errors_total flatfs_datastore_du_latency_seconds_bucket -flatfs_datastore_du_latency_seconds_bucket -flatfs_datastore_du_latency_seconds_bucket -flatfs_datastore_du_latency_seconds_bucket -flatfs_datastore_du_latency_seconds_bucket -flatfs_datastore_du_latency_seconds_bucket flatfs_datastore_du_latency_seconds_count flatfs_datastore_du_latency_seconds_sum flatfs_datastore_du_total flatfs_datastore_gc_errors_total flatfs_datastore_gc_latency_seconds_bucket -flatfs_datastore_gc_latency_seconds_bucket -flatfs_datastore_gc_latency_seconds_bucket -flatfs_datastore_gc_latency_seconds_bucket -flatfs_datastore_gc_latency_seconds_bucket -flatfs_datastore_gc_latency_seconds_bucket flatfs_datastore_gc_latency_seconds_count flatfs_datastore_gc_latency_seconds_sum flatfs_datastore_gc_total flatfs_datastore_get_errors_total flatfs_datastore_get_latency_seconds_bucket -flatfs_datastore_get_latency_seconds_bucket -flatfs_datastore_get_latency_seconds_bucket -flatfs_datastore_get_latency_seconds_bucket -flatfs_datastore_get_latency_seconds_bucket -flatfs_datastore_get_latency_seconds_bucket flatfs_datastore_get_latency_seconds_count flatfs_datastore_get_latency_seconds_sum flatfs_datastore_get_size_bytes_bucket -flatfs_datastore_get_size_bytes_bucket -flatfs_datastore_get_size_bytes_bucket -flatfs_datastore_get_size_bytes_bucket -flatfs_datastore_get_size_bytes_bucket flatfs_datastore_get_size_bytes_count flatfs_datastore_get_size_bytes_sum flatfs_datastore_get_total flatfs_datastore_getsize_errors_total flatfs_datastore_getsize_latency_seconds_bucket -flatfs_datastore_getsize_latency_seconds_bucket -flatfs_datastore_getsize_latency_seconds_bucket -flatfs_datastore_getsize_latency_seconds_bucket -flatfs_datastore_getsize_latency_seconds_bucket -flatfs_datastore_getsize_latency_seconds_bucket flatfs_datastore_getsize_latency_seconds_count flatfs_datastore_getsize_latency_seconds_sum flatfs_datastore_getsize_total flatfs_datastore_has_errors_total flatfs_datastore_has_latency_seconds_bucket -flatfs_datastore_has_latency_seconds_bucket -flatfs_datastore_has_latency_seconds_bucket -flatfs_datastore_has_latency_seconds_bucket -flatfs_datastore_has_latency_seconds_bucket -flatfs_datastore_has_latency_seconds_bucket flatfs_datastore_has_latency_seconds_count flatfs_datastore_has_latency_seconds_sum flatfs_datastore_has_total flatfs_datastore_put_errors_total flatfs_datastore_put_latency_seconds_bucket -flatfs_datastore_put_latency_seconds_bucket -flatfs_datastore_put_latency_seconds_bucket -flatfs_datastore_put_latency_seconds_bucket -flatfs_datastore_put_latency_seconds_bucket -flatfs_datastore_put_latency_seconds_bucket flatfs_datastore_put_latency_seconds_count flatfs_datastore_put_latency_seconds_sum flatfs_datastore_put_size_bytes_bucket -flatfs_datastore_put_size_bytes_bucket -flatfs_datastore_put_size_bytes_bucket -flatfs_datastore_put_size_bytes_bucket -flatfs_datastore_put_size_bytes_bucket flatfs_datastore_put_size_bytes_count flatfs_datastore_put_size_bytes_sum flatfs_datastore_put_total flatfs_datastore_query_errors_total flatfs_datastore_query_latency_seconds_bucket -flatfs_datastore_query_latency_seconds_bucket -flatfs_datastore_query_latency_seconds_bucket -flatfs_datastore_query_latency_seconds_bucket -flatfs_datastore_query_latency_seconds_bucket -flatfs_datastore_query_latency_seconds_bucket flatfs_datastore_query_latency_seconds_count flatfs_datastore_query_latency_seconds_sum flatfs_datastore_query_total flatfs_datastore_scrub_errors_total flatfs_datastore_scrub_latency_seconds_bucket -flatfs_datastore_scrub_latency_seconds_bucket -flatfs_datastore_scrub_latency_seconds_bucket -flatfs_datastore_scrub_latency_seconds_bucket -flatfs_datastore_scrub_latency_seconds_bucket -flatfs_datastore_scrub_latency_seconds_bucket flatfs_datastore_scrub_latency_seconds_count flatfs_datastore_scrub_latency_seconds_sum flatfs_datastore_scrub_total flatfs_datastore_sync_errors_total flatfs_datastore_sync_latency_seconds_bucket -flatfs_datastore_sync_latency_seconds_bucket -flatfs_datastore_sync_latency_seconds_bucket -flatfs_datastore_sync_latency_seconds_bucket -flatfs_datastore_sync_latency_seconds_bucket -flatfs_datastore_sync_latency_seconds_bucket flatfs_datastore_sync_latency_seconds_count flatfs_datastore_sync_latency_seconds_sum flatfs_datastore_sync_total go_gc_duration_seconds -go_gc_duration_seconds -go_gc_duration_seconds -go_gc_duration_seconds -go_gc_duration_seconds go_gc_duration_seconds_count go_gc_duration_seconds_sum go_goroutines @@ -197,40 +111,15 @@ ipfs_bitswap_active_tasks ipfs_bitswap_pending_block_tasks ipfs_bitswap_pending_tasks ipfs_bitswap_recv_all_blocks_bytes_bucket -ipfs_bitswap_recv_all_blocks_bytes_bucket -ipfs_bitswap_recv_all_blocks_bytes_bucket -ipfs_bitswap_recv_all_blocks_bytes_bucket -ipfs_bitswap_recv_all_blocks_bytes_bucket -ipfs_bitswap_recv_all_blocks_bytes_bucket -ipfs_bitswap_recv_all_blocks_bytes_bucket ipfs_bitswap_recv_all_blocks_bytes_count ipfs_bitswap_recv_all_blocks_bytes_sum ipfs_bitswap_recv_dup_blocks_bytes_bucket -ipfs_bitswap_recv_dup_blocks_bytes_bucket -ipfs_bitswap_recv_dup_blocks_bytes_bucket -ipfs_bitswap_recv_dup_blocks_bytes_bucket -ipfs_bitswap_recv_dup_blocks_bytes_bucket -ipfs_bitswap_recv_dup_blocks_bytes_bucket -ipfs_bitswap_recv_dup_blocks_bytes_bucket ipfs_bitswap_recv_dup_blocks_bytes_count ipfs_bitswap_recv_dup_blocks_bytes_sum ipfs_bitswap_send_times_bucket -ipfs_bitswap_send_times_bucket -ipfs_bitswap_send_times_bucket -ipfs_bitswap_send_times_bucket -ipfs_bitswap_send_times_bucket -ipfs_bitswap_send_times_bucket -ipfs_bitswap_send_times_bucket -ipfs_bitswap_send_times_bucket ipfs_bitswap_send_times_count ipfs_bitswap_send_times_sum ipfs_bitswap_sent_all_blocks_bytes_bucket -ipfs_bitswap_sent_all_blocks_bytes_bucket -ipfs_bitswap_sent_all_blocks_bytes_bucket -ipfs_bitswap_sent_all_blocks_bytes_bucket -ipfs_bitswap_sent_all_blocks_bytes_bucket -ipfs_bitswap_sent_all_blocks_bytes_bucket -ipfs_bitswap_sent_all_blocks_bytes_bucket ipfs_bitswap_sent_all_blocks_bytes_count ipfs_bitswap_sent_all_blocks_bytes_sum ipfs_bitswap_want_blocks_total @@ -239,340 +128,170 @@ ipfs_bs_cache_arc_hits_total ipfs_bs_cache_arc_total ipfs_fsrepo_datastore_batchcommit_errors_total ipfs_fsrepo_datastore_batchcommit_latency_seconds_bucket -ipfs_fsrepo_datastore_batchcommit_latency_seconds_bucket -ipfs_fsrepo_datastore_batchcommit_latency_seconds_bucket -ipfs_fsrepo_datastore_batchcommit_latency_seconds_bucket -ipfs_fsrepo_datastore_batchcommit_latency_seconds_bucket -ipfs_fsrepo_datastore_batchcommit_latency_seconds_bucket ipfs_fsrepo_datastore_batchcommit_latency_seconds_count ipfs_fsrepo_datastore_batchcommit_latency_seconds_sum ipfs_fsrepo_datastore_batchcommit_total ipfs_fsrepo_datastore_batchdelete_errors_total ipfs_fsrepo_datastore_batchdelete_latency_seconds_bucket -ipfs_fsrepo_datastore_batchdelete_latency_seconds_bucket -ipfs_fsrepo_datastore_batchdelete_latency_seconds_bucket -ipfs_fsrepo_datastore_batchdelete_latency_seconds_bucket -ipfs_fsrepo_datastore_batchdelete_latency_seconds_bucket -ipfs_fsrepo_datastore_batchdelete_latency_seconds_bucket ipfs_fsrepo_datastore_batchdelete_latency_seconds_count ipfs_fsrepo_datastore_batchdelete_latency_seconds_sum ipfs_fsrepo_datastore_batchdelete_total ipfs_fsrepo_datastore_batchput_errors_total ipfs_fsrepo_datastore_batchput_latency_seconds_bucket -ipfs_fsrepo_datastore_batchput_latency_seconds_bucket -ipfs_fsrepo_datastore_batchput_latency_seconds_bucket -ipfs_fsrepo_datastore_batchput_latency_seconds_bucket -ipfs_fsrepo_datastore_batchput_latency_seconds_bucket -ipfs_fsrepo_datastore_batchput_latency_seconds_bucket ipfs_fsrepo_datastore_batchput_latency_seconds_count ipfs_fsrepo_datastore_batchput_latency_seconds_sum ipfs_fsrepo_datastore_batchput_size_bytes_bucket -ipfs_fsrepo_datastore_batchput_size_bytes_bucket -ipfs_fsrepo_datastore_batchput_size_bytes_bucket -ipfs_fsrepo_datastore_batchput_size_bytes_bucket -ipfs_fsrepo_datastore_batchput_size_bytes_bucket ipfs_fsrepo_datastore_batchput_size_bytes_count ipfs_fsrepo_datastore_batchput_size_bytes_sum ipfs_fsrepo_datastore_batchput_total ipfs_fsrepo_datastore_check_errors_total ipfs_fsrepo_datastore_check_latency_seconds_bucket -ipfs_fsrepo_datastore_check_latency_seconds_bucket -ipfs_fsrepo_datastore_check_latency_seconds_bucket -ipfs_fsrepo_datastore_check_latency_seconds_bucket -ipfs_fsrepo_datastore_check_latency_seconds_bucket -ipfs_fsrepo_datastore_check_latency_seconds_bucket ipfs_fsrepo_datastore_check_latency_seconds_count ipfs_fsrepo_datastore_check_latency_seconds_sum ipfs_fsrepo_datastore_check_total ipfs_fsrepo_datastore_delete_errors_total ipfs_fsrepo_datastore_delete_latency_seconds_bucket -ipfs_fsrepo_datastore_delete_latency_seconds_bucket -ipfs_fsrepo_datastore_delete_latency_seconds_bucket -ipfs_fsrepo_datastore_delete_latency_seconds_bucket -ipfs_fsrepo_datastore_delete_latency_seconds_bucket -ipfs_fsrepo_datastore_delete_latency_seconds_bucket ipfs_fsrepo_datastore_delete_latency_seconds_count ipfs_fsrepo_datastore_delete_latency_seconds_sum ipfs_fsrepo_datastore_delete_total ipfs_fsrepo_datastore_du_errors_total ipfs_fsrepo_datastore_du_latency_seconds_bucket -ipfs_fsrepo_datastore_du_latency_seconds_bucket -ipfs_fsrepo_datastore_du_latency_seconds_bucket -ipfs_fsrepo_datastore_du_latency_seconds_bucket -ipfs_fsrepo_datastore_du_latency_seconds_bucket -ipfs_fsrepo_datastore_du_latency_seconds_bucket ipfs_fsrepo_datastore_du_latency_seconds_count ipfs_fsrepo_datastore_du_latency_seconds_sum ipfs_fsrepo_datastore_du_total ipfs_fsrepo_datastore_gc_errors_total ipfs_fsrepo_datastore_gc_latency_seconds_bucket -ipfs_fsrepo_datastore_gc_latency_seconds_bucket -ipfs_fsrepo_datastore_gc_latency_seconds_bucket -ipfs_fsrepo_datastore_gc_latency_seconds_bucket -ipfs_fsrepo_datastore_gc_latency_seconds_bucket -ipfs_fsrepo_datastore_gc_latency_seconds_bucket ipfs_fsrepo_datastore_gc_latency_seconds_count ipfs_fsrepo_datastore_gc_latency_seconds_sum ipfs_fsrepo_datastore_gc_total ipfs_fsrepo_datastore_get_errors_total ipfs_fsrepo_datastore_get_latency_seconds_bucket -ipfs_fsrepo_datastore_get_latency_seconds_bucket -ipfs_fsrepo_datastore_get_latency_seconds_bucket -ipfs_fsrepo_datastore_get_latency_seconds_bucket -ipfs_fsrepo_datastore_get_latency_seconds_bucket -ipfs_fsrepo_datastore_get_latency_seconds_bucket ipfs_fsrepo_datastore_get_latency_seconds_count ipfs_fsrepo_datastore_get_latency_seconds_sum ipfs_fsrepo_datastore_get_size_bytes_bucket -ipfs_fsrepo_datastore_get_size_bytes_bucket -ipfs_fsrepo_datastore_get_size_bytes_bucket -ipfs_fsrepo_datastore_get_size_bytes_bucket -ipfs_fsrepo_datastore_get_size_bytes_bucket ipfs_fsrepo_datastore_get_size_bytes_count ipfs_fsrepo_datastore_get_size_bytes_sum ipfs_fsrepo_datastore_get_total ipfs_fsrepo_datastore_getsize_errors_total ipfs_fsrepo_datastore_getsize_latency_seconds_bucket -ipfs_fsrepo_datastore_getsize_latency_seconds_bucket -ipfs_fsrepo_datastore_getsize_latency_seconds_bucket -ipfs_fsrepo_datastore_getsize_latency_seconds_bucket -ipfs_fsrepo_datastore_getsize_latency_seconds_bucket -ipfs_fsrepo_datastore_getsize_latency_seconds_bucket ipfs_fsrepo_datastore_getsize_latency_seconds_count ipfs_fsrepo_datastore_getsize_latency_seconds_sum ipfs_fsrepo_datastore_getsize_total ipfs_fsrepo_datastore_has_errors_total ipfs_fsrepo_datastore_has_latency_seconds_bucket -ipfs_fsrepo_datastore_has_latency_seconds_bucket -ipfs_fsrepo_datastore_has_latency_seconds_bucket -ipfs_fsrepo_datastore_has_latency_seconds_bucket -ipfs_fsrepo_datastore_has_latency_seconds_bucket -ipfs_fsrepo_datastore_has_latency_seconds_bucket ipfs_fsrepo_datastore_has_latency_seconds_count ipfs_fsrepo_datastore_has_latency_seconds_sum ipfs_fsrepo_datastore_has_total ipfs_fsrepo_datastore_put_errors_total ipfs_fsrepo_datastore_put_latency_seconds_bucket -ipfs_fsrepo_datastore_put_latency_seconds_bucket -ipfs_fsrepo_datastore_put_latency_seconds_bucket -ipfs_fsrepo_datastore_put_latency_seconds_bucket -ipfs_fsrepo_datastore_put_latency_seconds_bucket -ipfs_fsrepo_datastore_put_latency_seconds_bucket ipfs_fsrepo_datastore_put_latency_seconds_count ipfs_fsrepo_datastore_put_latency_seconds_sum ipfs_fsrepo_datastore_put_size_bytes_bucket -ipfs_fsrepo_datastore_put_size_bytes_bucket -ipfs_fsrepo_datastore_put_size_bytes_bucket -ipfs_fsrepo_datastore_put_size_bytes_bucket -ipfs_fsrepo_datastore_put_size_bytes_bucket ipfs_fsrepo_datastore_put_size_bytes_count ipfs_fsrepo_datastore_put_size_bytes_sum ipfs_fsrepo_datastore_put_total ipfs_fsrepo_datastore_query_errors_total ipfs_fsrepo_datastore_query_latency_seconds_bucket -ipfs_fsrepo_datastore_query_latency_seconds_bucket -ipfs_fsrepo_datastore_query_latency_seconds_bucket -ipfs_fsrepo_datastore_query_latency_seconds_bucket -ipfs_fsrepo_datastore_query_latency_seconds_bucket -ipfs_fsrepo_datastore_query_latency_seconds_bucket ipfs_fsrepo_datastore_query_latency_seconds_count ipfs_fsrepo_datastore_query_latency_seconds_sum ipfs_fsrepo_datastore_query_total ipfs_fsrepo_datastore_scrub_errors_total ipfs_fsrepo_datastore_scrub_latency_seconds_bucket -ipfs_fsrepo_datastore_scrub_latency_seconds_bucket -ipfs_fsrepo_datastore_scrub_latency_seconds_bucket -ipfs_fsrepo_datastore_scrub_latency_seconds_bucket -ipfs_fsrepo_datastore_scrub_latency_seconds_bucket -ipfs_fsrepo_datastore_scrub_latency_seconds_bucket ipfs_fsrepo_datastore_scrub_latency_seconds_count ipfs_fsrepo_datastore_scrub_latency_seconds_sum ipfs_fsrepo_datastore_scrub_total ipfs_fsrepo_datastore_sync_errors_total ipfs_fsrepo_datastore_sync_latency_seconds_bucket -ipfs_fsrepo_datastore_sync_latency_seconds_bucket -ipfs_fsrepo_datastore_sync_latency_seconds_bucket -ipfs_fsrepo_datastore_sync_latency_seconds_bucket -ipfs_fsrepo_datastore_sync_latency_seconds_bucket -ipfs_fsrepo_datastore_sync_latency_seconds_bucket ipfs_fsrepo_datastore_sync_latency_seconds_count ipfs_fsrepo_datastore_sync_latency_seconds_sum ipfs_fsrepo_datastore_sync_total ipfs_http_request_duration_seconds -ipfs_http_request_duration_seconds -ipfs_http_request_duration_seconds ipfs_http_request_duration_seconds_count ipfs_http_request_duration_seconds_sum ipfs_http_request_size_bytes -ipfs_http_request_size_bytes -ipfs_http_request_size_bytes ipfs_http_request_size_bytes_count ipfs_http_request_size_bytes_sum ipfs_http_requests_total ipfs_http_response_size_bytes -ipfs_http_response_size_bytes -ipfs_http_response_size_bytes ipfs_http_response_size_bytes_count ipfs_http_response_size_bytes_sum ipfs_info leveldb_datastore_batchcommit_errors_total leveldb_datastore_batchcommit_latency_seconds_bucket -leveldb_datastore_batchcommit_latency_seconds_bucket -leveldb_datastore_batchcommit_latency_seconds_bucket -leveldb_datastore_batchcommit_latency_seconds_bucket -leveldb_datastore_batchcommit_latency_seconds_bucket -leveldb_datastore_batchcommit_latency_seconds_bucket leveldb_datastore_batchcommit_latency_seconds_count leveldb_datastore_batchcommit_latency_seconds_sum leveldb_datastore_batchcommit_total leveldb_datastore_batchdelete_errors_total leveldb_datastore_batchdelete_latency_seconds_bucket -leveldb_datastore_batchdelete_latency_seconds_bucket -leveldb_datastore_batchdelete_latency_seconds_bucket -leveldb_datastore_batchdelete_latency_seconds_bucket -leveldb_datastore_batchdelete_latency_seconds_bucket -leveldb_datastore_batchdelete_latency_seconds_bucket leveldb_datastore_batchdelete_latency_seconds_count leveldb_datastore_batchdelete_latency_seconds_sum leveldb_datastore_batchdelete_total leveldb_datastore_batchput_errors_total leveldb_datastore_batchput_latency_seconds_bucket -leveldb_datastore_batchput_latency_seconds_bucket -leveldb_datastore_batchput_latency_seconds_bucket -leveldb_datastore_batchput_latency_seconds_bucket -leveldb_datastore_batchput_latency_seconds_bucket -leveldb_datastore_batchput_latency_seconds_bucket leveldb_datastore_batchput_latency_seconds_count leveldb_datastore_batchput_latency_seconds_sum leveldb_datastore_batchput_size_bytes_bucket -leveldb_datastore_batchput_size_bytes_bucket -leveldb_datastore_batchput_size_bytes_bucket -leveldb_datastore_batchput_size_bytes_bucket -leveldb_datastore_batchput_size_bytes_bucket leveldb_datastore_batchput_size_bytes_count leveldb_datastore_batchput_size_bytes_sum leveldb_datastore_batchput_total leveldb_datastore_check_errors_total leveldb_datastore_check_latency_seconds_bucket -leveldb_datastore_check_latency_seconds_bucket -leveldb_datastore_check_latency_seconds_bucket -leveldb_datastore_check_latency_seconds_bucket -leveldb_datastore_check_latency_seconds_bucket -leveldb_datastore_check_latency_seconds_bucket leveldb_datastore_check_latency_seconds_count leveldb_datastore_check_latency_seconds_sum leveldb_datastore_check_total leveldb_datastore_delete_errors_total leveldb_datastore_delete_latency_seconds_bucket -leveldb_datastore_delete_latency_seconds_bucket -leveldb_datastore_delete_latency_seconds_bucket -leveldb_datastore_delete_latency_seconds_bucket -leveldb_datastore_delete_latency_seconds_bucket -leveldb_datastore_delete_latency_seconds_bucket leveldb_datastore_delete_latency_seconds_count leveldb_datastore_delete_latency_seconds_sum leveldb_datastore_delete_total leveldb_datastore_du_errors_total leveldb_datastore_du_latency_seconds_bucket -leveldb_datastore_du_latency_seconds_bucket -leveldb_datastore_du_latency_seconds_bucket -leveldb_datastore_du_latency_seconds_bucket -leveldb_datastore_du_latency_seconds_bucket -leveldb_datastore_du_latency_seconds_bucket leveldb_datastore_du_latency_seconds_count leveldb_datastore_du_latency_seconds_sum leveldb_datastore_du_total leveldb_datastore_gc_errors_total leveldb_datastore_gc_latency_seconds_bucket -leveldb_datastore_gc_latency_seconds_bucket -leveldb_datastore_gc_latency_seconds_bucket -leveldb_datastore_gc_latency_seconds_bucket -leveldb_datastore_gc_latency_seconds_bucket -leveldb_datastore_gc_latency_seconds_bucket leveldb_datastore_gc_latency_seconds_count leveldb_datastore_gc_latency_seconds_sum leveldb_datastore_gc_total leveldb_datastore_get_errors_total leveldb_datastore_get_latency_seconds_bucket -leveldb_datastore_get_latency_seconds_bucket -leveldb_datastore_get_latency_seconds_bucket -leveldb_datastore_get_latency_seconds_bucket -leveldb_datastore_get_latency_seconds_bucket -leveldb_datastore_get_latency_seconds_bucket leveldb_datastore_get_latency_seconds_count leveldb_datastore_get_latency_seconds_sum leveldb_datastore_get_size_bytes_bucket -leveldb_datastore_get_size_bytes_bucket -leveldb_datastore_get_size_bytes_bucket -leveldb_datastore_get_size_bytes_bucket -leveldb_datastore_get_size_bytes_bucket leveldb_datastore_get_size_bytes_count leveldb_datastore_get_size_bytes_sum leveldb_datastore_get_total leveldb_datastore_getsize_errors_total leveldb_datastore_getsize_latency_seconds_bucket -leveldb_datastore_getsize_latency_seconds_bucket -leveldb_datastore_getsize_latency_seconds_bucket -leveldb_datastore_getsize_latency_seconds_bucket -leveldb_datastore_getsize_latency_seconds_bucket -leveldb_datastore_getsize_latency_seconds_bucket leveldb_datastore_getsize_latency_seconds_count leveldb_datastore_getsize_latency_seconds_sum leveldb_datastore_getsize_total leveldb_datastore_has_errors_total leveldb_datastore_has_latency_seconds_bucket -leveldb_datastore_has_latency_seconds_bucket -leveldb_datastore_has_latency_seconds_bucket -leveldb_datastore_has_latency_seconds_bucket -leveldb_datastore_has_latency_seconds_bucket -leveldb_datastore_has_latency_seconds_bucket leveldb_datastore_has_latency_seconds_count leveldb_datastore_has_latency_seconds_sum leveldb_datastore_has_total leveldb_datastore_put_errors_total leveldb_datastore_put_latency_seconds_bucket -leveldb_datastore_put_latency_seconds_bucket -leveldb_datastore_put_latency_seconds_bucket -leveldb_datastore_put_latency_seconds_bucket -leveldb_datastore_put_latency_seconds_bucket -leveldb_datastore_put_latency_seconds_bucket leveldb_datastore_put_latency_seconds_count leveldb_datastore_put_latency_seconds_sum leveldb_datastore_put_size_bytes_bucket -leveldb_datastore_put_size_bytes_bucket -leveldb_datastore_put_size_bytes_bucket -leveldb_datastore_put_size_bytes_bucket -leveldb_datastore_put_size_bytes_bucket leveldb_datastore_put_size_bytes_count leveldb_datastore_put_size_bytes_sum leveldb_datastore_put_total leveldb_datastore_query_errors_total leveldb_datastore_query_latency_seconds_bucket -leveldb_datastore_query_latency_seconds_bucket -leveldb_datastore_query_latency_seconds_bucket -leveldb_datastore_query_latency_seconds_bucket -leveldb_datastore_query_latency_seconds_bucket -leveldb_datastore_query_latency_seconds_bucket leveldb_datastore_query_latency_seconds_count leveldb_datastore_query_latency_seconds_sum leveldb_datastore_query_total leveldb_datastore_scrub_errors_total leveldb_datastore_scrub_latency_seconds_bucket -leveldb_datastore_scrub_latency_seconds_bucket -leveldb_datastore_scrub_latency_seconds_bucket -leveldb_datastore_scrub_latency_seconds_bucket -leveldb_datastore_scrub_latency_seconds_bucket -leveldb_datastore_scrub_latency_seconds_bucket leveldb_datastore_scrub_latency_seconds_count leveldb_datastore_scrub_latency_seconds_sum leveldb_datastore_scrub_total leveldb_datastore_sync_errors_total leveldb_datastore_sync_latency_seconds_bucket -leveldb_datastore_sync_latency_seconds_bucket -leveldb_datastore_sync_latency_seconds_bucket -leveldb_datastore_sync_latency_seconds_bucket -leveldb_datastore_sync_latency_seconds_bucket -leveldb_datastore_sync_latency_seconds_bucket leveldb_datastore_sync_latency_seconds_count leveldb_datastore_sync_latency_seconds_sum leveldb_datastore_sync_total @@ -581,126 +300,28 @@ libp2p_autonat_reachability_status libp2p_autonat_reachability_status_confidence libp2p_autorelay_candidate_loop_state libp2p_autorelay_candidates_circuit_v2_support_total -libp2p_autorelay_candidates_circuit_v2_support_total libp2p_autorelay_desired_reservations libp2p_autorelay_relay_addresses_count libp2p_autorelay_relay_addresses_updated_total libp2p_autorelay_reservation_requests_outcome_total -libp2p_autorelay_reservation_requests_outcome_total libp2p_autorelay_reservations_closed_total libp2p_autorelay_reservations_opened_total libp2p_autorelay_status libp2p_eventbus_events_emitted_total -libp2p_eventbus_events_emitted_total -libp2p_eventbus_subscriber_event_queued -libp2p_eventbus_subscriber_event_queued libp2p_eventbus_subscriber_event_queued libp2p_eventbus_subscriber_queue_full -libp2p_eventbus_subscriber_queue_full -libp2p_eventbus_subscriber_queue_full libp2p_eventbus_subscriber_queue_length -libp2p_eventbus_subscriber_queue_length -libp2p_eventbus_subscriber_queue_length -libp2p_eventbus_subscribers_total -libp2p_eventbus_subscribers_total -libp2p_eventbus_subscribers_total -libp2p_eventbus_subscribers_total -libp2p_eventbus_subscribers_total libp2p_eventbus_subscribers_total libp2p_identify_addrs_count libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket libp2p_identify_addrs_received_count libp2p_identify_addrs_received_sum libp2p_identify_identify_pushes_triggered_total -libp2p_identify_identify_pushes_triggered_total libp2p_identify_protocols_count libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket libp2p_identify_protocols_received_count libp2p_identify_protocols_received_sum libp2p_relaysvc_connection_duration_seconds_bucket -libp2p_relaysvc_connection_duration_seconds_bucket -libp2p_relaysvc_connection_duration_seconds_bucket -libp2p_relaysvc_connection_duration_seconds_bucket -libp2p_relaysvc_connection_duration_seconds_bucket -libp2p_relaysvc_connection_duration_seconds_bucket -libp2p_relaysvc_connection_duration_seconds_bucket -libp2p_relaysvc_connection_duration_seconds_bucket -libp2p_relaysvc_connection_duration_seconds_bucket -libp2p_relaysvc_connection_duration_seconds_bucket -libp2p_relaysvc_connection_duration_seconds_bucket -libp2p_relaysvc_connection_duration_seconds_bucket libp2p_relaysvc_connection_duration_seconds_count libp2p_relaysvc_connection_duration_seconds_sum libp2p_relaysvc_data_transferred_bytes_total diff --git a/test/sharness/t0119-prometheus.sh b/test/sharness/t0119-prometheus.sh index 3387f4feb..0e00f088a 100755 --- a/test/sharness/t0119-prometheus.sh +++ b/test/sharness/t0119-prometheus.sh @@ -23,7 +23,7 @@ test_expect_success "collect metrics" ' test_kill_ipfs_daemon test_expect_success "filter metrics" ' - sed -ne "s/^\([a-z0-9_]\+\).*/\1/p" raw_metrics | LC_ALL=C sort > filtered_metrics + sed -ne "s/^\([a-z0-9_]\+\).*/\1/p" raw_metrics | LC_ALL=C sort | uniq > filtered_metrics ' test_expect_success "make sure metrics haven't changed" ' @@ -50,7 +50,7 @@ test_kill_ipfs_daemon test_expect_success "filter metrics and find ones added by enabling ResourceMgr" ' sed -ne "s/^\([a-z0-9_]\+\).*/\1/p" raw_metrics | LC_ALL=C sort > filtered_metrics && - grep -v -x -f ../t0119-prometheus-data/prometheus_metrics filtered_metrics > rcmgr_metrics + grep -v -x -f ../t0119-prometheus-data/prometheus_metrics filtered_metrics | LC_ALL=C sort | uniq > rcmgr_metrics ' test_expect_success "make sure initial metrics added by setting ResourceMgr.Enabled haven't changed" ' From f0397719ad4e403bcd6efd40f2309f380f5b8301 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Wed, 14 Jun 2023 00:37:03 +0200 Subject: [PATCH 0717/1212] =?UTF-8?q?chore(docs):=20typo=20http=E2=86=92ht?= =?UTF-8?q?tps?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/changelogs/v0.21.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/changelogs/v0.21.md b/docs/changelogs/v0.21.md index 034201748..1ac92adb7 100644 --- a/docs/changelogs/v0.21.md +++ b/docs/changelogs/v0.21.md @@ -99,7 +99,7 @@ for clients that do not follow redirects by default: ```console $ curl "https://subdomain-gw.example.net/ipfs/${cid}/" -Moved Permanently. +Moved Permanently. ``` Rationale can be found in [kubo#9913](https://github.com/ipfs/kubo/pull/9913). From c93e2675ba6c90ae0f8ab537b25914c5824e3c36 Mon Sep 17 00:00:00 2001 From: Russell Dempsey <1173416+SgtPooki@users.noreply.github.com> Date: Wed, 14 Jun 2023 01:12:41 -0700 Subject: [PATCH 0718/1212] feat: webui@4.0.1 (#9940) --- .github/workflows/build.yml | 2 +- core/corehttp/webui.go | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d3dce10a0..3caee6bac 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -145,7 +145,7 @@ jobs: steps: - uses: actions/setup-node@v3 with: - node-version: 16.12.0 + node-version: 18.14.0 - uses: actions/download-artifact@v3 with: name: kubo diff --git a/core/corehttp/webui.go b/core/corehttp/webui.go index 9b7cf776d..e5abd3922 100644 --- a/core/corehttp/webui.go +++ b/core/corehttp/webui.go @@ -1,11 +1,12 @@ package corehttp // TODO: move to IPNS -const WebUIPath = "/ipfs/bafybeic4gops3d3lyrisqku37uio33nvt6fqxvkxihrwlqsuvf76yln4fm" // v3.0.0 +const WebUIPath = "/ipfs/bafybeigs6d53gpgu34553mbi5bbkb26e4ikruoaaar75jpfdywpup2r3my" // v4.0.1 // WebUIPaths is a list of all past webUI paths. var WebUIPaths = []string{ WebUIPath, + "/ipfs/bafybeic4gops3d3lyrisqku37uio33nvt6fqxvkxihrwlqsuvf76yln4fm", "/ipfs/bafybeifeqt7mvxaniphyu2i3qhovjaf3sayooxbh5enfdqtiehxjv2ldte", "/ipfs/bafybeiequgo72mrvuml56j4gk7crewig5bavumrrzhkqbim6b3s2yqi7ty", "/ipfs/bafybeibjbq3tmmy7wuihhhwvbladjsd3gx3kfjepxzkq6wylik6wc3whzy", From ced4be8c130919af47fb24dc98d86b699b118c18 Mon Sep 17 00:00:00 2001 From: GitHub Date: Wed, 14 Jun 2023 11:14:35 +0000 Subject: [PATCH 0719/1212] chore: Update .github/workflows/stale.yml [skip ci] --- .github/workflows/stale.yml | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 6f6d895d1..668bd07d4 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -6,21 +6,4 @@ on: jobs: stale: - - runs-on: ubuntu-latest - permissions: - issues: write - pull-requests: write - - steps: - - uses: actions/stale@v3 - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - stale-issue-message: 'Oops, seems like we needed more information for this issue, please comment with more details or this issue will be closed in 7 days.' - close-issue-message: 'This issue was closed because it is missing author input.' - stale-issue-label: 'kind/stale' - any-of-labels: 'need/author-input' - exempt-issue-labels: 'need/triage,need/community-input,need/maintainer-input,need/maintainers-input,need/analysis,status/blocked,status/in-progress,status/ready,status/deferred,status/inactive' - days-before-issue-stale: 6 - days-before-issue-close: 7 - enable-statistics: true + uses: pl-strflt/.github/.github/workflows/reusable-stale-issue.yml@v0.3 From b8da86e0dd552ea42922363270e69a1026054275 Mon Sep 17 00:00:00 2001 From: "ipfs-mgmt-read-write[bot]" <104492829+ipfs-mgmt-read-write[bot]@users.noreply.github.com> Date: Wed, 14 Jun 2023 13:05:45 +0000 Subject: [PATCH 0720/1212] chore: label dependabot PRs --- .github/dependabot.yml | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 14f776456..6ff8dba1f 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,10 +1,14 @@ version: 2 updates: -- package-ecosystem: gomod - directory: "/" - schedule: - interval: daily - time: "11:00" - open-pull-requests-limit: 10 - labels: - - "topic/dependencies" + - package-ecosystem: gomod + directory: "/" + schedule: + interval: daily + time: "11:00" + open-pull-requests-limit: 10 + labels: + - "topic/dependencies" + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" From f5f6b664dbfe7d5c1f0d28754e7383a9a5b230bf Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Wed, 14 Jun 2023 20:55:31 +0200 Subject: [PATCH 0721/1212] fix(cmd): useful errors in dag import (#9945) * fix: useful errors during dag import Most of the time the error is either a bitflip in one of blocks, or a truncation of car stream. This allows user to understand what happened and at which place in the car stream, making debug more humane. * fix: correct message when root pin failed this also correctly exits CLI commands with code 1 (was silent false-positive 0 before) --- core/commands/dag/dag.go | 2 +- core/commands/dag/import.go | 25 +++++++++++++++++++++---- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/core/commands/dag/dag.go b/core/commands/dag/dag.go index 7d21eb071..41fde70e5 100644 --- a/core/commands/dag/dag.go +++ b/core/commands/dag/dag.go @@ -237,7 +237,7 @@ Specification of CAR formats: https://ipld.io/specs/transport/car/ } if event.Root.PinErrorMsg != "" { - event.Root.PinErrorMsg = fmt.Sprintf("FAILED: %s", event.Root.PinErrorMsg) + return fmt.Errorf("pinning root %q FAILED: %s", enc.Encode(event.Root.Cid), event.Root.PinErrorMsg) } else { event.Root.PinErrorMsg = "success" } diff --git a/core/commands/dag/import.go b/core/commands/dag/import.go index 20f947bc2..36f4176d5 100644 --- a/core/commands/dag/import.go +++ b/core/commands/dag/import.go @@ -2,11 +2,13 @@ package dagcmd import ( "errors" + "fmt" "io" "github.com/ipfs/boxo/coreiface/options" "github.com/ipfs/boxo/files" gocarv2 "github.com/ipfs/boxo/ipld/car/v2" + blocks "github.com/ipfs/go-block-format" cid "github.com/ipfs/go-cid" cmds "github.com/ipfs/go-ipfs-cmds" ipld "github.com/ipfs/go-ipld-format" @@ -58,6 +60,18 @@ func dagImport(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment roots := cid.NewSet() var blockCount, blockBytesCount uint64 + // remember last valid block and provide a meaningful error message + // when a truncated/mangled CAR is being imported + importError := func(previous blocks.Block, current blocks.Block, err error) error { + if current != nil { + return fmt.Errorf("import failed at block %q: %w", current.Cid(), err) + } + if previous != nil { + return fmt.Errorf("import failed after block %q: %w", previous.Cid(), err) + } + return fmt.Errorf("import failed: %w", err) + } + it := req.Files.Entries() for it.Next() { file := files.FileFromEntry(it) @@ -75,6 +89,8 @@ func dagImport(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment // this won't/can't help with not running out of handles defer file.Close() + var previous blocks.Block + car, err := gocarv2.NewBlockReader(file) if err != nil { return err @@ -87,25 +103,26 @@ func dagImport(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment for { block, err := car.Next() if err != nil && err != io.EOF { - return err + return importError(previous, block, err) } else if block == nil { break } if err := cmdutils.CheckBlockSize(req, uint64(len(block.RawData()))); err != nil { - return err + return importError(previous, block, err) } // the double-decode is suboptimal, but we need it for batching nd, err := blockDecoder.DecodeNode(req.Context, block) if err != nil { - return err + return importError(previous, block, err) } if err := batch.Add(req.Context, nd); err != nil { - return err + return importError(previous, block, err) } blockCount++ blockBytesCount += uint64(len(block.RawData())) + previous = block } return nil }() From b685355ca8ceaaf55619ee3b8cffa612a4106569 Mon Sep 17 00:00:00 2001 From: Rod Vagg Date: Thu, 15 Jun 2023 06:45:34 +1000 Subject: [PATCH 0722/1212] feat!: dag import - don't pin roots by default (#9926) * feat!: dag import - don't pin roots by default Fixes: https://github.com/ipfs/kubo/issues/9765 * test(ipip-402): dag import this adds basic regression test that guards behavior around partial cars with or without pinning * docs(ipip-402): ipip and dag import changelog --------- Co-authored-by: Marcin Rataj --- core/commands/dag/dag.go | 13 +++--- docs/changelogs/v0.21.md | 35 ++++++++++++++-- .../README.md | 4 ++ .../partial-dag-scope-entity.car | Bin 0 -> 1711 bytes test/sharness/t0054-dag-car-import-export.sh | 38 ++++++++++++++---- test/sharness/t0109-gateway-web-_redirects.sh | 2 +- test/sharness/t0113-gateway-symlink.sh | 2 +- test/sharness/t0114-gateway-subdomains.sh | 2 +- test/sharness/t0115-gateway-dir-listing.sh | 2 +- test/sharness/t0116-gateway-cache.sh | 2 +- test/sharness/t0117-gateway-block.sh | 2 +- test/sharness/t0122-gateway-tar.sh | 6 +-- test/sharness/t0123-gateway-json-cbor.sh | 8 ++-- test/sharness/t0124-gateway-ipns-record.sh | 2 +- test/sharness/t0400-api-no-gateway.sh | 2 +- testplans/bitswap/main.go | 6 +-- 16 files changed, 92 insertions(+), 34 deletions(-) create mode 100644 test/sharness/t0054-dag-car-import-export-data/partial-dag-scope-entity.car diff --git a/core/commands/dag/dag.go b/core/commands/dag/dag.go index 41fde70e5..505f9770d 100644 --- a/core/commands/dag/dag.go +++ b/core/commands/dag/dag.go @@ -176,13 +176,16 @@ var DagImportCmd = &cmds.Command{ Tagline: "Import the contents of .car files", ShortDescription: ` 'ipfs dag import' imports all blocks present in supplied .car -( Content Address aRchive ) files, recursively pinning any roots -specified in the CAR file headers, unless --pin-roots is set to false. +( Content Address aRchive ) files, optionally recursively pinning any +roots specified in the CAR file headers if --pin-roots is set. Note: This command will import all blocks in the CAR file, not just those - reachable from the specified roots. However, these other blocks will - not be pinned and may be garbage collected later. + reachable from the specified roots. However, when using --pin-roots, + these other blocks will not be pinned and may be garbage collected + later. When not using --pin-roots, all blocks imported may be garbage + collected if no other pin operation is performed on them, or a root + that references them. The pinning of the roots happens after all car files are processed, permitting import of DAGs spanning multiple files. @@ -200,7 +203,7 @@ Specification of CAR formats: https://ipld.io/specs/transport/car/ cmds.FileArg("path", true, true, "The path of a .car file.").EnableStdin(), }, Options: []cmds.Option{ - cmds.BoolOption(pinRootsOptionName, "Pin optional roots listed in the .car headers after importing.").WithDefault(true), + cmds.BoolOption(pinRootsOptionName, "Pin optional roots listed in the .car headers after importing."), cmds.BoolOption(silentOptionName, "No output."), cmds.BoolOption(statsOptionName, "Output stats."), cmdutils.AllowBigBlockOption, diff --git a/docs/changelogs/v0.21.md b/docs/changelogs/v0.21.md index 1ac92adb7..0f5ea1cf6 100644 --- a/docs/changelogs/v0.21.md +++ b/docs/changelogs/v0.21.md @@ -11,8 +11,10 @@ - [`client/rpc` migration of `go-ipfs-http-client`](#clientrpc-migration-of-go-ipfs-http-client) - [Gateway: DAG-CBOR/-JSON previews and improved error pages](#gateway-dag-cbor-json-previews-and-improved-error-pages) - [Gateway: subdomain redirects are now `text/html`](#gateway-subdomain-redirects-are-now-texthtml) + - [Gateway: support for partial CAR export parameters (IPIP-402)](#gateway-support-for-partial-car-export-parameters-ipip-402) + - [`ipfs dag import` no longer pins by default](#ipfs-dag-import-no-longer-pins-by-default) - [`ipfs dag stat` deduping statistics](#ipfs-dag-stat-deduping-statistics) - - [Accelerated DHT Client is no longer experimental](#--empty-repo-is-now-the-default) + - [Accelerated DHT Client is no longer experimental](#accelerated-dht-client-is-no-longer-experimental) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -104,9 +106,36 @@ $ curl "https://subdomain-gw.example.net/ipfs/${cid}/" Rationale can be found in [kubo#9913](https://github.com/ipfs/kubo/pull/9913). -#### Gateway: support for CAR parameters of IPIP-402 +#### Gateway: support for partial CAR export parameters (IPIP-402) -The gateway now supports partial CAR export parameters as indicated in [IPIP-402](https://github.com/ipfs/specs/pull/402). +The gateway now supports optional CAR export parameters +`dag-scope=block|entity|all` and `entity-bytes=from:to` as specified in +[IPIP-402](https://github.com/ipfs/specs/pull/402). + +Batch block retrieval minimizes round trips, catering to the requirements of +light HTTP clients for directory enumeration, range requests, and content path +resolution. + +#### `ipfs dag import` no longer pins by default + +With the gateway now capable of handling partial CAR exports +([IPIP-402](https://github.com/ipfs/specs/pull/402)) and incomplete DAG CARs +becoming more prevalent, there have been changes to the pinning mode when using +`ipfs dag import`. + +Recursive pinning of the entire DAG within an imported CAR is now optional. To +explicitly attempt pinning the DAG referenced by any roots present in the CAR, +you can opt in by using the `--pin-roots` option. + +Pinning incomplete DAG will produce an error: + +```console +$ curl 'http://127.0.0.1:8080/ipns/docs.ipfs.tech?format=car&dag-scope=entity' > ./partial-entity.car # Kubo 0.21.0 with IPIP-402 (only root block of unixfs dir) +$ ipfs dag import --stats --pin-roots=true ./partial-entity.car +Error pinning QmPDC11yLAbVw3dX5jMeEuSdk4BiVjSd9X87zaYRdVjzW3 FAILED: block was not found locally (offline): ipld: could not find QmPDvrDAz2aHeLjPVQ4uh1neyknUmDpf1GsBzAbpFhS8ro +Imported 1 blocks (1618 bytes) +[exit code 1] +``` #### `ipfs dag stat` deduping statistics diff --git a/test/sharness/t0054-dag-car-import-export-data/README.md b/test/sharness/t0054-dag-car-import-export-data/README.md index 033f837a0..786f9ade0 100644 --- a/test/sharness/t0054-dag-car-import-export-data/README.md +++ b/test/sharness/t0054-dag-car-import-export-data/README.md @@ -26,3 +26,7 @@ - lotus_devnet_genesis_v2.car - generated with `car index lotus_testnet_export_128.car > lotus_testnet_export_128_v2.car` - install `go-car` CLI from https://github.com/ipld/go-car + +- partial-dag-scope-entity.car + - unixfs directory entity exported from gateway via `?format=car&dag-scope=entity` ([IPIP-402](https://github.com/ipfs/specs/pull/402)) + - CAR roots includes directory CID, but only the root block is included in the CAR, making the DAG incomplete diff --git a/test/sharness/t0054-dag-car-import-export-data/partial-dag-scope-entity.car b/test/sharness/t0054-dag-car-import-export-data/partial-dag-scope-entity.car new file mode 100644 index 0000000000000000000000000000000000000000..b149a18df7ceb2921d2c53dd40b919e8ce25cdd1 GIT binary patch literal 1711 zcmai#dpJ~i7{?7(86*5m+eu8rw2PQQlT>vBb@4xeT-|z4Hd*APwpN}Zz zasuDhF?%&f53m_;rG~=4INA}rju?Y9X{4%*!|E}$tKg@X|Hj|&dO)0jC~;Jd(Z(46 z|1nrhw*&0>*#*V=+N6fI__`2bNd(g(+ub&OnzXT{u6@*0U>5_dU`(i#qe8AgqLj-J zuG@k+8uIWIm>6oBLKPYG9C-!%pBgZ~Qs(xej2i^JhG>Na%c_3-l$}!%nw;~WB6Hm5 zX~^@f$Pp&+)+tGqjIW*<+~Hpd*H?vBPB@;_uN6(z+4ACU=#=Ar~rosUBE&e zkQ)_i(*J7E_kBbDmh*NXu0$-riYzX;FF*Qtx=)U)1X#o=l-_KVYKOBZBXmEhLw-DgUO^q0iq!7sD0uKxH`tvuB$Vr zAet{J!WkF}<)jzKjVUi&pMMG*x6!hg0bcO6wFB!M zB#lq4t43krJ*V>4U>hE=5Wxw$SK_+O)3{MjebIno7x|TW2RN|~ExteeXTr1EerE5@ zlh2-q?zK%>W!|H0mi^1}=V{2~(x8hW3JfN*wKu0klqTxvha*!JK(WpuP>391biQOJw zX4zMI9BRnCARbJCUPKvs&uHr%V~SaK!6X#J30NwH>RJJC*IoaG9V2;@Q(o^|mz^bN zGgf*HIY!>9Og5>lvQewC@tQS&fntPGE>sB!GCrUZ9yPP7h?f3J*9A#$l8`oK_1Aj# z^U@DcW0TM!v7YS~w%Gufq6!hto$ET6l9(Azagn(vi)Pu(ys@+pO5A>V@};^ZcT=~p zmV4;&JPk4qV(q|G24koQ!3o|5ob2~bA9(6y_B|P#s4XZB>k7+yJo~2X^IkzD_Q&y~ zsZK?Cxe*1Oy8w{k1WIOro4c!qJl_H!;|IzXy^5L-5i?)MBWAvhsk<#(tY@wrim#b! za=v*W>x1uS8knR|$~Pba0&31Pru<*O;+@REzb3Y1;pTy3OY}}C_l>cl z``oSp`bHHhh$qcd5>UZ5BWfeXo`Gf-jsA$Esmx+i%p;c9lG>oW3=8owj`2j$bhZ{4 zD-jW*M92k$PSm?o8#!dKa{OnGSGJ>vC=@iqZ%_0lKhV%l9kwhD#yk2IazIzgj5qeAe;s{199=ZEcvpi_jcxAaa5H8R8<^lIfyiLR zx1efIqLy>F`FPp&+q1$}gg#7Jey1(1UD7||XgoTaneG|h7;$R?n5z*fnK=kIPK8Q^ P/dev/null; done & while [[ -e spin.gc ]]; do ipfsi "$node" repo gc &>/dev/null; done & - ipfsi "$node" dag import "$@" 2>&1 && ipfsi "$node" repo verify &>/dev/null + ipfsi "$node" dag import --pin-roots "$@" 2>&1 && ipfsi "$node" repo verify &>/dev/null result=$? rm -f spin.gc &>/dev/null @@ -117,7 +117,7 @@ EOE ' test_expect_success "import/pin naked roots only, relying on local blockstore having all the data" ' - ipfsi 1 dag import --stats --enc=json ../t0054-dag-car-import-export-data/combined_naked_roots_genesis_and_128.car \ + ipfsi 1 dag import --stats --enc=json --pin-roots ../t0054-dag-car-import-export-data/combined_naked_roots_genesis_and_128.car \ > naked_import_result_json_actual ' @@ -197,14 +197,14 @@ EOE head -3 multiroot_import_json_stats_expected > multiroot_import_json_expected test_expect_success "multiroot import works (--enc=json)" ' - ipfs dag import --enc=json ../t0054-dag-car-import-export-data/lotus_testnet_export_256_multiroot.car > multiroot_import_json_actual + ipfs dag import --enc=json --pin-roots ../t0054-dag-car-import-export-data/lotus_testnet_export_256_multiroot.car > multiroot_import_json_actual ' test_expect_success "multiroot import expected output" ' test_cmp_sorted multiroot_import_json_expected multiroot_import_json_actual ' test_expect_success "multiroot import works with --stats" ' - ipfs dag import --stats --enc=json ../t0054-dag-car-import-export-data/lotus_testnet_export_256_multiroot.car > multiroot_import_json_actual + ipfs dag import --stats --enc=json --pin-roots ../t0054-dag-car-import-export-data/lotus_testnet_export_256_multiroot.car > multiroot_import_json_actual ' test_expect_success "multiroot import expected output" ' test_cmp_sorted multiroot_import_json_stats_expected multiroot_import_json_actual @@ -215,18 +215,18 @@ cat >pin_import_expected << EOE {"Stats":{"BlockCount":1198,"BlockBytesCount":468513}} EOE test_expect_success "pin-less import works" ' - ipfs dag import --stats --enc=json --pin-roots=false \ + ipfs dag import --stats --enc=json \ ../t0054-dag-car-import-export-data/lotus_devnet_genesis.car \ ../t0054-dag-car-import-export-data/lotus_testnet_export_128.car \ > no-pin_import_actual ' -test_expect_success "expected no pins on --pin-roots=false" ' +test_expect_success "expected no pins on" ' test_cmp pin_import_expected no-pin_import_actual ' test_expect_success "naked root import works" ' - ipfs dag import --stats --enc=json ../t0054-dag-car-import-export-data/combined_naked_roots_genesis_and_128.car \ + ipfs dag import --stats --enc=json --pin-roots ../t0054-dag-car-import-export-data/combined_naked_roots_genesis_and_128.car \ > naked_root_import_json_actual ' test_expect_success "naked root import expected output" ' @@ -253,7 +253,7 @@ cat > version_2_import_expected << EOE EOE test_expect_success "version 2 import" ' - ipfs dag import --stats --enc=json \ + ipfs dag import --stats --enc=json --pin-roots \ ../t0054-dag-car-import-export-data/lotus_testnet_export_128_v2.car \ ../t0054-dag-car-import-export-data/lotus_devnet_genesis_v2.car \ > version_2_import_actual @@ -291,4 +291,26 @@ test_expect_success "'ipfs dag import' decode IPLD 'cbor' codec works" ' rm cbor.car ' +# IPIP-402 +cat > partial_nopin_import_expected << EOE +{"Stats":{"BlockCount":1,"BlockBytesCount":1618}} +EOE +test_expect_success "'ipfs dag import' without pinning works fine with incomplete DAG (unixfs dir exported as dag-scope=entity from IPIP-402)" ' + ipfs dag import --stats --enc=json --pin-roots=false ../t0054-dag-car-import-export-data/partial-dag-scope-entity.car >partial_nopin_import_out 2>&1 && + test_cmp partial_nopin_import_expected partial_nopin_import_out +' +test_expect_success "'ipfs dag import' with no params in CLI mode produces exit code 0 (unixfs dir exported as dag-scope=entity from IPIP-402)" ' + test_expect_code 0 ipfs dag import ../t0054-dag-car-import-export-data/partial-dag-scope-entity.car +' + +test_expect_success "'ipfs dag import' with pinning errors due to incomplete DAG (unixfs dir exported as dag-scope=entity from IPIP-402)" ' + ipfs dag import --stats --enc=json --pin-roots=true ../t0054-dag-car-import-export-data/partial-dag-scope-entity.car >partial_pin_import_out 2>&1 && + test_should_contain "\"PinErrorMsg\":\"block was not found locally" partial_pin_import_out +' + +test_expect_success "'ipfs dag import' pin error in default CLI mode produces exit code 1 (unixfs dir exported as dag-scope=entity from IPIP-402)" ' + test_expect_code 1 ipfs dag import --pin-roots ../t0054-dag-car-import-export-data/partial-dag-scope-entity.car >partial_pin_import_out 2>&1 && + test_should_contain "Error: pinning root \"QmPDC11yLAbVw3dX5jMeEuSdk4BiVjSd9X87zaYRdVjzW3\" FAILED: block was not found locally" partial_pin_import_out +' + test_done diff --git a/test/sharness/t0109-gateway-web-_redirects.sh b/test/sharness/t0109-gateway-web-_redirects.sh index 9ebfb911e..0bc2a23b6 100755 --- a/test/sharness/t0109-gateway-web-_redirects.sh +++ b/test/sharness/t0109-gateway-web-_redirects.sh @@ -14,7 +14,7 @@ test_launch_ipfs_daemon # Import test case # Run `ipfs cat /ipfs/$REDIRECTS_DIR_CID/_redirects` to see sample _redirects file test_expect_success "Add the _redirects file test directory" ' - ipfs dag import ../t0109-gateway-web-_redirects-data/redirects.car + ipfs dag import --pin-roots ../t0109-gateway-web-_redirects-data/redirects.car ' CAR_ROOT_CID=QmQyqMY5vUBSbSxyitJqthgwZunCQjDVtNd8ggVCxzuPQ4 diff --git a/test/sharness/t0113-gateway-symlink.sh b/test/sharness/t0113-gateway-symlink.sh index 29e5b960d..2cb4f3195 100755 --- a/test/sharness/t0113-gateway-symlink.sh +++ b/test/sharness/t0113-gateway-symlink.sh @@ -12,7 +12,7 @@ test_launch_ipfs_daemon # Import test case # See the static fixtures in ./t0113-gateway-symlink/ test_expect_success "Add the test directory with symlinks" ' - ipfs dag import ../t0113-gateway-symlink/testfiles.car + ipfs dag import --pin-roots ../t0113-gateway-symlink/testfiles.car ' ROOT_DIR_CID=QmWvY6FaqFMS89YAQ9NAPjVP4WZKA1qbHbicc9HeSKQTgt # ./testfiles/ diff --git a/test/sharness/t0114-gateway-subdomains.sh b/test/sharness/t0114-gateway-subdomains.sh index 1d19a6570..8be102c4f 100755 --- a/test/sharness/t0114-gateway-subdomains.sh +++ b/test/sharness/t0114-gateway-subdomains.sh @@ -113,7 +113,7 @@ IPNS_ED25519_B58MH=12D3KooWLQzUv2FHWGVPXTXSZpdHs7oHbXub2G5WC8Tx4NQhyd2d IPNS_ED25519_B36CID=k51qzi5uqu5dk3v4rmjber23h16xnr23bsggmqqil9z2gduiis5se8dht36dam test_expect_success "Add the test fixtures" ' - ipfs dag import ../t0114-gateway-subdomains/fixtures.car && + ipfs dag import --pin-roots ../t0114-gateway-subdomains/fixtures.car && ipfs routing put --allow-offline /ipns/${RSA_KEY} ../t0114-gateway-subdomains/${RSA_KEY}.ipns-record && ipfs routing put --allow-offline /ipns/${ED25519_KEY} ../t0114-gateway-subdomains/${ED25519_KEY}.ipns-record ' diff --git a/test/sharness/t0115-gateway-dir-listing.sh b/test/sharness/t0115-gateway-dir-listing.sh index cf95bf4b0..1ce0861b2 100755 --- a/test/sharness/t0115-gateway-dir-listing.sh +++ b/test/sharness/t0115-gateway-dir-listing.sh @@ -21,7 +21,7 @@ test_launch_ipfs_daemon_without_network # Import test case # See the static fixtures in ./t0115-gateway-dir-listing/ test_expect_success "Add the test directory" ' - ipfs dag import ../t0115-gateway-dir-listing/fixtures.car + ipfs dag import --pin-roots ../t0115-gateway-dir-listing/fixtures.car ' DIR_CID=bafybeig6ka5mlwkl4subqhaiatalkcleo4jgnr3hqwvpmsqfca27cijp3i # ./rootDir/ FILE_CID=bafkreialihlqnf5uwo4byh4n3cmwlntwqzxxs2fg5vanqdi3d7tb2l5xkm # ./rootDir/ą/ę/file-źł.txt diff --git a/test/sharness/t0116-gateway-cache.sh b/test/sharness/t0116-gateway-cache.sh index b2e6b3af3..2c0f2f833 100755 --- a/test/sharness/t0116-gateway-cache.sh +++ b/test/sharness/t0116-gateway-cache.sh @@ -35,7 +35,7 @@ TEST_IPNS_ID=k51qzi5uqu5dlxdsdu5fpuu7h69wu4ohp32iwm9pdt9nq3y5rpn3ln9j12zfhe # Import test case # See the static fixtures in ./t0116-gateway-cache/ test_expect_success "Add the test directory" ' - ipfs dag import ../t0116-gateway-cache/fixtures.car + ipfs dag import --pin-roots ../t0116-gateway-cache/fixtures.car ipfs routing put --allow-offline /ipns/${TEST_IPNS_ID} ../t0116-gateway-cache/${TEST_IPNS_ID}.ipns-record ' diff --git a/test/sharness/t0117-gateway-block.sh b/test/sharness/t0117-gateway-block.sh index b21425bc4..a4a661bd1 100755 --- a/test/sharness/t0117-gateway-block.sh +++ b/test/sharness/t0117-gateway-block.sh @@ -10,7 +10,7 @@ test_launch_ipfs_daemon_without_network # Import test case # See the static fixtures in ./t0117-gateway-block/ test_expect_success "Add the dir test directory" ' - ipfs dag import ../t0117-gateway-block/fixtures.car + ipfs dag import --pin-roots ../t0117-gateway-block/fixtures.car ' ROOT_DIR_CID=bafybeie72edlprgtlwwctzljf6gkn2wnlrddqjbkxo3jomh4n7omwblxly # ./ FILE_CID=bafkreihhpc5y2pqvl5rbe5uuyhqjouybfs3rvlmisccgzue2kkt5zq6upq # ./dir/ascii.txt diff --git a/test/sharness/t0122-gateway-tar.sh b/test/sharness/t0122-gateway-tar.sh index 20cc1bf4c..435623547 100755 --- a/test/sharness/t0122-gateway-tar.sh +++ b/test/sharness/t0122-gateway-tar.sh @@ -13,7 +13,7 @@ INSIDE_ROOT_CID="bafybeibfevfxlvxp5vxobr5oapczpf7resxnleb7tkqmdorc4gl5cdva3y" # Import test case # See the static fixtures in ./t0122-gateway-tar/ test_expect_success "Add the test directory" ' - ipfs dag import ../t0122-gateway-tar/fixtures.car + ipfs dag import --pin-roots ../t0122-gateway-tar/fixtures.car ' DIR_CID=bafybeig6ka5mlwkl4subqhaiatalkcleo4jgnr3hqwvpmsqfca27cijp3i # ./rootDir FILE_CID=bafkreialihlqnf5uwo4byh4n3cmwlntwqzxxs2fg5vanqdi3d7tb2l5xkm # ./rootDir/ą/ę/file-źł.txt @@ -63,9 +63,9 @@ test_expect_success "GET TAR with explicit ?filename= succeeds with modified Con " test_expect_success "Add CARs with relative paths to test with" ' - ipfs dag import ../t0122-gateway-tar/outside-root.car > import_output && + ipfs dag import --pin-roots ../t0122-gateway-tar/outside-root.car > import_output && test_should_contain $OUTSIDE_ROOT_CID import_output && - ipfs dag import ../t0122-gateway-tar/inside-root.car > import_output && + ipfs dag import --pin-roots ../t0122-gateway-tar/inside-root.car > import_output && test_should_contain $INSIDE_ROOT_CID import_output ' diff --git a/test/sharness/t0123-gateway-json-cbor.sh b/test/sharness/t0123-gateway-json-cbor.sh index b4b0446ff..323d23d58 100755 --- a/test/sharness/t0123-gateway-json-cbor.sh +++ b/test/sharness/t0123-gateway-json-cbor.sh @@ -10,7 +10,7 @@ test_launch_ipfs_daemon_without_network # Import test case # See the static fixtures in ./t0123-gateway-json-cbor/ test_expect_success "Add the test directory" ' - ipfs dag import ../t0123-gateway-json-cbor/fixtures.car + ipfs dag import --pin-roots ../t0123-gateway-json-cbor/fixtures.car ' DIR_CID=bafybeiafyvqlazbbbtjnn6how5d6h6l6rxbqc4qgpbmteaiskjrffmyy4a # ./rootDir FILE_JSON_CID=bafkreibrppizs3g7axs2jdlnjua6vgpmltv7k72l7v7sa6mmht6mne3qqe # ./rootDir/ą/ę/t.json @@ -155,11 +155,11 @@ DAG_JSON_TRAVERSAL_CID="baguqeeram5ujjqrwheyaty3w5gdsmoz6vittchvhk723jjqxk7hakxk DAG_PB_CID="bafybeiegxwlgmoh2cny7qlolykdf7aq7g6dlommarldrbm7c4hbckhfcke" test_expect_success "Add CARs for path traversal and DAG-PB representation tests" ' - ipfs dag import ../t0123-gateway-json-cbor/dag-cbor-traversal.car > import_output && + ipfs dag import --pin-roots ../t0123-gateway-json-cbor/dag-cbor-traversal.car > import_output && test_should_contain $DAG_CBOR_TRAVERSAL_CID import_output && - ipfs dag import ../t0123-gateway-json-cbor/dag-json-traversal.car > import_output && + ipfs dag import --pin-roots ../t0123-gateway-json-cbor/dag-json-traversal.car > import_output && test_should_contain $DAG_JSON_TRAVERSAL_CID import_output && - ipfs dag import ../t0123-gateway-json-cbor/dag-pb.car > import_output && + ipfs dag import --pin-roots ../t0123-gateway-json-cbor/dag-pb.car > import_output && test_should_contain $DAG_PB_CID import_output ' diff --git a/test/sharness/t0124-gateway-ipns-record.sh b/test/sharness/t0124-gateway-ipns-record.sh index 1d05b5698..605252c0f 100755 --- a/test/sharness/t0124-gateway-ipns-record.sh +++ b/test/sharness/t0124-gateway-ipns-record.sh @@ -12,7 +12,7 @@ test_launch_ipfs_daemon IPNS_KEY=k51qzi5uqu5dh71qgwangrt6r0nd4094i88nsady6qgd1dhjcyfsaqmpp143ab FILE_CID=bafkreidfdrlkeq4m4xnxuyx6iae76fdm4wgl5d4xzsb77ixhyqwumhz244 # A file containing Hello IPFS test_expect_success "Add the test directory & IPNS records" ' - ipfs dag import ../t0124-gateway-ipns-record/fixtures.car && + ipfs dag import --pin-roots ../t0124-gateway-ipns-record/fixtures.car && ipfs routing put /ipns/${IPNS_KEY} ../t0124-gateway-ipns-record/${IPNS_KEY}.ipns-record ' diff --git a/test/sharness/t0400-api-no-gateway.sh b/test/sharness/t0400-api-no-gateway.sh index d0daeece3..7518db427 100755 --- a/test/sharness/t0400-api-no-gateway.sh +++ b/test/sharness/t0400-api-no-gateway.sh @@ -13,7 +13,7 @@ test_init_ipfs # Import test case # See the static fixtures in ./t0400-api-no-gateway/ test_expect_success "Add the test directory" ' - ipfs dag import ../t0400-api-no-gateway/fixtures.car + ipfs dag import --pin-roots ../t0400-api-no-gateway/fixtures.car ' HASH=QmNYERzV2LfD2kkfahtfv44ocHzEFK1sLBaE7zdcYT2GAZ # a file containing the string "testing" diff --git a/testplans/bitswap/main.go b/testplans/bitswap/main.go index aa98d4f31..0af2ad95c 100644 --- a/testplans/bitswap/main.go +++ b/testplans/bitswap/main.go @@ -12,14 +12,14 @@ import ( "github.com/testground/sdk-go/runtime" "github.com/testground/sdk-go/sync" - bitswap "github.com/ipfs/go-libipfs/bitswap" - bsnet "github.com/ipfs/go-libipfs/bitswap/network" - block "github.com/ipfs/go-libipfs/blocks" "github.com/ipfs/go-cid" datastore "github.com/ipfs/go-datastore" blockstore "github.com/ipfs/go-ipfs-blockstore" exchange "github.com/ipfs/go-ipfs-exchange-interface" bstats "github.com/ipfs/go-ipfs-regression/bitswap" + bitswap "github.com/ipfs/go-libipfs/bitswap" + bsnet "github.com/ipfs/go-libipfs/bitswap/network" + block "github.com/ipfs/go-libipfs/blocks" "github.com/libp2p/go-libp2p" dht "github.com/libp2p/go-libp2p-kad-dht" "github.com/libp2p/go-libp2p/core/host" From 44c5ec05056275b61a750b4f1aeaef2a6a0b81af Mon Sep 17 00:00:00 2001 From: Jorropo Date: Thu, 15 Jun 2023 12:43:48 +0200 Subject: [PATCH 0723/1212] chore: update dht and libp2p for identify stream block Streams used to be blocked on ping IO because we didn't handled the DHT ping check asynchronously. Include fixes from libp2p/go-libp2p-kad-dht#851 Fixes #9957 --- docs/examples/kubo-as-a-library/go.mod | 34 ++++++------ docs/examples/kubo-as-a-library/go.sum | 69 ++++++++++++------------ go.mod | 36 ++++++------- go.sum | 73 +++++++++++++------------- test/dependencies/go.mod | 32 +++++------ test/dependencies/go.sum | 65 ++++++++++++----------- 6 files changed, 156 insertions(+), 153 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index cda83aeb4..bfbe48843 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -9,7 +9,7 @@ replace github.com/ipfs/kubo => ./../../.. require ( github.com/ipfs/boxo v0.10.0 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 - github.com/libp2p/go-libp2p v0.27.5 + github.com/libp2p/go-libp2p v0.27.6 github.com/multiformats/go-multiaddr v0.9.0 ) @@ -18,7 +18,7 @@ require ( github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 // indirect github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5 // indirect - github.com/benbjohnson/clock v1.3.0 // indirect + github.com/benbjohnson/clock v1.3.5 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver/v4 v4.0.0 // indirect github.com/cenkalti/backoff/v4 v4.2.1 // indirect @@ -49,7 +49,7 @@ require ( github.com/golang/protobuf v1.5.3 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/gopacket v1.1.19 // indirect - github.com/google/pprof v0.0.0-20230405160723-4a4c7d95572b // indirect + github.com/google/pprof v0.0.0-20230602150820-91b7bce49751 // indirect github.com/google/uuid v1.3.0 // indirect github.com/gorilla/mux v1.8.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 // indirect @@ -58,7 +58,7 @@ require ( github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/golang-lru v0.5.4 // indirect github.com/hashicorp/golang-lru/v2 v2.0.2 // indirect - github.com/huin/goupnp v1.1.0 // indirect + github.com/huin/goupnp v1.2.0 // indirect github.com/ipfs/bbloom v0.0.4 // indirect github.com/ipfs/go-bitfield v1.1.0 // indirect github.com/ipfs/go-block-format v0.1.2 // indirect @@ -94,7 +94,7 @@ require ( github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect github.com/jbenet/goprocess v0.1.4 // indirect - github.com/klauspost/compress v1.16.4 // indirect + github.com/klauspost/compress v1.16.5 // indirect github.com/klauspost/cpuid/v2 v2.2.5 // indirect github.com/koron/go-ssdp v0.0.4 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect @@ -102,8 +102,8 @@ require ( github.com/libp2p/go-doh-resolver v0.4.0 // indirect github.com/libp2p/go-flow-metrics v0.1.0 // indirect github.com/libp2p/go-libp2p-asn-util v0.3.0 // indirect - github.com/libp2p/go-libp2p-kad-dht v0.24.0 // indirect - github.com/libp2p/go-libp2p-kbucket v0.6.1 // indirect + github.com/libp2p/go-libp2p-kad-dht v0.24.1 // indirect + github.com/libp2p/go-libp2p-kbucket v0.6.3 // indirect github.com/libp2p/go-libp2p-pubsub v0.9.3 // indirect github.com/libp2p/go-libp2p-pubsub-router v0.6.0 // indirect github.com/libp2p/go-libp2p-record v0.2.0 // indirect @@ -113,13 +113,13 @@ require ( github.com/libp2p/go-msgio v0.3.0 // indirect github.com/libp2p/go-nat v0.1.0 // indirect github.com/libp2p/go-netroute v0.2.1 // indirect - github.com/libp2p/go-reuseport v0.2.0 // indirect + github.com/libp2p/go-reuseport v0.3.0 // indirect github.com/libp2p/go-yamux/v4 v4.0.0 // indirect github.com/libp2p/zeroconf/v2 v2.2.0 // indirect github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect github.com/mattn/go-isatty v0.0.19 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect - github.com/miekg/dns v1.1.53 // indirect + github.com/miekg/dns v1.1.54 // indirect github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect github.com/minio/sha256-simd v1.0.1 // indirect @@ -134,7 +134,7 @@ require ( github.com/multiformats/go-multihash v0.2.3 // indirect github.com/multiformats/go-multistream v0.4.1 // indirect github.com/multiformats/go-varint v0.0.7 // indirect - github.com/onsi/ginkgo/v2 v2.9.2 // indirect + github.com/onsi/ginkgo/v2 v2.9.7 // indirect github.com/opencontainers/runtime-spec v1.0.2 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/openzipkin/zipkin-go v0.4.1 // indirect @@ -143,14 +143,14 @@ require ( github.com/pkg/errors v0.9.1 // indirect github.com/polydawn/refmt v0.89.0 // indirect github.com/prometheus/client_golang v1.14.0 // indirect - github.com/prometheus/client_model v0.3.0 // indirect + github.com/prometheus/client_model v0.4.0 // indirect github.com/prometheus/common v0.42.0 // indirect github.com/prometheus/procfs v0.9.0 // indirect github.com/quic-go/qpack v0.4.0 // indirect github.com/quic-go/qtls-go1-19 v0.3.2 // indirect github.com/quic-go/qtls-go1-20 v0.2.2 // indirect github.com/quic-go/quic-go v0.33.0 // indirect - github.com/quic-go/webtransport-go v0.5.2 // indirect + github.com/quic-go/webtransport-go v0.5.3 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/samber/lo v1.36.0 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect @@ -181,14 +181,14 @@ require ( go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.24.0 // indirect go4.org v0.0.0-20230225012048-214862532bf5 // indirect - golang.org/x/crypto v0.9.0 // indirect + golang.org/x/crypto v0.10.0 // indirect golang.org/x/exp v0.0.0-20230321023759-10a507213a29 // indirect golang.org/x/mod v0.10.0 // indirect golang.org/x/net v0.10.0 // indirect - golang.org/x/sync v0.1.0 // indirect - golang.org/x/sys v0.8.0 // indirect - golang.org/x/text v0.9.0 // indirect - golang.org/x/tools v0.7.0 // indirect + golang.org/x/sync v0.2.0 // indirect + golang.org/x/sys v0.9.0 // indirect + golang.org/x/text v0.10.0 // indirect + golang.org/x/tools v0.9.1 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect gonum.org/v1/gonum v0.13.0 // indirect google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 922906c35..d2ff0d772 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -56,8 +56,9 @@ github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYU github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= -github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o= +github.com/benbjohnson/clock v1.3.5/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= @@ -272,8 +273,8 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20230405160723-4a4c7d95572b h1:Qcx5LM0fSiks9uCyFZwDBUasd3lxd1RM0GYpL+Li5o4= -github.com/google/pprof v0.0.0-20230405160723-4a4c7d95572b/go.mod h1:79YE0hCXdHag9sBkw2o+N/YnZtTkXi0UT9Nnixa5eYk= +github.com/google/pprof v0.0.0-20230602150820-91b7bce49751 h1:hR7/MlvK23p6+lIw9SN1TigNLn9ZnF3W4SYRKq2gAHs= +github.com/google/pprof v0.0.0-20230602150820-91b7bce49751/go.mod h1:Jh3hGz2jkYak8qXPD19ryItVnUgpgeqzdkY/D0EaeuA= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -312,8 +313,8 @@ github.com/hashicorp/golang-lru/v2 v2.0.2/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyf github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= -github.com/huin/goupnp v1.1.0 h1:gEe0Dp/lZmPZiDFzJJaOfUpOvv2MKUkoBX8lDrn9vKU= -github.com/huin/goupnp v1.1.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= +github.com/huin/goupnp v1.2.0 h1:uOKW26NG1hsSSbXIZ1IR7XP9Gjd1U8pnLaCMgntmkmY= +github.com/huin/goupnp v1.2.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= @@ -452,8 +453,8 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI 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.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/klauspost/compress v1.16.4 h1:91KN02FnsOYhuunwU4ssRe8lc2JosWmizWa91B5v1PU= -github.com/klauspost/compress v1.16.4/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/compress v1.16.5 h1:IFV2oUNUzZaz+XyusxpLzpzS8Pt5rh0Z16For/djlyI= +github.com/klauspost/compress v1.16.5/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= @@ -486,17 +487,17 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.27.5 h1:KwA7pXKXpz8hG6Cr1fMA7UkgleogcwQj0sxl5qquWRg= -github.com/libp2p/go-libp2p v0.27.5/go.mod h1:oMfQGTb9CHnrOuSM6yMmyK2lXz3qIhnkn2+oK3B1Y2g= +github.com/libp2p/go-libp2p v0.27.6 h1:KmGU5kskCaaerm53heqzfGOlrW2z8icZ+fnyqgrZs38= +github.com/libp2p/go-libp2p v0.27.6/go.mod h1:oMfQGTb9CHnrOuSM6yMmyK2lXz3qIhnkn2+oK3B1Y2g= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= github.com/libp2p/go-libp2p-core v0.3.0/go.mod h1:ACp3DmS3/N64c2jDzcV429ukDpicbL6+TrrxANBjPGw= -github.com/libp2p/go-libp2p-kad-dht v0.24.0 h1:nZnFDQEFU4N8GzclnR+IGxIgR7k4PPCDk/GK9A28onk= -github.com/libp2p/go-libp2p-kad-dht v0.24.0/go.mod h1:lfu5T01EH+r6uDZ/8G+ObhwgzVyd0b1nb54AdT8XGhc= +github.com/libp2p/go-libp2p-kad-dht v0.24.1 h1:XH9vIWqc6e+w6z2Nvt9R5EhkBNnOQl7tyxxM6soejwo= +github.com/libp2p/go-libp2p-kad-dht v0.24.1/go.mod h1:1meiUvgOxfSPBx1pracS4VyYwmusorvv+TVRI3mXaJI= github.com/libp2p/go-libp2p-kbucket v0.3.1/go.mod h1:oyjT5O7tS9CQurok++ERgc46YLwEpuGoFq9ubvoUOio= -github.com/libp2p/go-libp2p-kbucket v0.6.1 h1:Y/NIvALuY5/fJlOpaJor9Azg4eor15JskGs9Lb2EhH0= -github.com/libp2p/go-libp2p-kbucket v0.6.1/go.mod h1:dvWO707Oq/vhMVuUhyfLkw0QsOrJFETepbNfpVHSELI= +github.com/libp2p/go-libp2p-kbucket v0.6.3 h1:p507271wWzpy2f1XxPzCQG9NiN6R6lHL9GiSErbQQo0= +github.com/libp2p/go-libp2p-kbucket v0.6.3/go.mod h1:RCseT7AH6eJWxxk2ol03xtP9pEHetYSPXOaJnOiD8i0= github.com/libp2p/go-libp2p-peerstore v0.1.4/go.mod h1:+4BDbDiiKf4PzpANZDAT+knVdLxvqh7hXOujessqdzs= github.com/libp2p/go-libp2p-pubsub v0.9.3 h1:ihcz9oIBMaCK9kcx+yHWm3mLAFBMAUsM4ux42aikDxo= github.com/libp2p/go-libp2p-pubsub v0.9.3/go.mod h1:RYA7aM9jIic5VV47WXu4GkcRxRhrdElWf8xtyli+Dzc= @@ -521,8 +522,8 @@ github.com/libp2p/go-netroute v0.2.1 h1:V8kVrpD8GK0Riv15/7VN6RbUQ3URNZVosw7H2v9t github.com/libp2p/go-netroute v0.2.1/go.mod h1:hraioZr0fhBjG0ZRXJJ6Zj2IVEVNx6tDTFQfSmcq7mQ= 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= -github.com/libp2p/go-reuseport v0.2.0 h1:18PRvIMlpY6ZK85nIAicSBuXXvrYoSw3dsBAR7zc560= -github.com/libp2p/go-reuseport v0.2.0/go.mod h1:bvVho6eLMm6Bz5hmU0LYN3ixd3nPPvtIlaURZZgOY4k= +github.com/libp2p/go-reuseport v0.3.0 h1:iiZslO5byUYZEg9iCwJGf5h+sf1Agmqx2V2FDjPyvUw= +github.com/libp2p/go-reuseport v0.3.0/go.mod h1:laea40AimhtfEqysZ71UpYj4S+R9VpH8PgqLo7L+SwI= github.com/libp2p/go-sockaddr v0.0.2/go.mod h1:syPvOmNs24S3dFVGJA1/mrqdeijPxLV2Le3BRLKd68k= github.com/libp2p/go-yamux/v4 v4.0.0 h1:+Y80dV2Yx/kv7Y7JKu0LECyVdMXm1VUoko+VQ9rBfZQ= github.com/libp2p/go-yamux/v4 v4.0.0/go.mod h1:NWjl8ZTLOGlozrXSOZ/HlfG++39iKNnM5wwmtQP1YB4= @@ -550,8 +551,8 @@ github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyex github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= -github.com/miekg/dns v1.1.53 h1:ZBkuHr5dxHtB1caEOlZTLPo7D3L3TWckgUUs/RHfDxw= -github.com/miekg/dns v1.1.53/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= +github.com/miekg/dns v1.1.54 h1:5jon9mWcb0sFJGpnI99tOMhCPyJ+RPVz5b63MQG0VWI= +github.com/miekg/dns v1.1.54/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c h1:bzE/A84HN25pxAuk9Eej1Kz9OUelF97nAc82bDquQI8= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c/go.mod h1:0SQS9kMwD2VsyFEB++InYyBJroV/FRmBgcydeSUcJms= github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= @@ -628,12 +629,12 @@ github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= -github.com/onsi/ginkgo/v2 v2.9.2 h1:BA2GMJOtfGAfagzYtrAlufIP0lq6QERkFmHLMLPwFSU= -github.com/onsi/ginkgo/v2 v2.9.2/go.mod h1:WHcJJG2dIlcCqVfBAwUCrJxSPFb6v4azBwgxeMeDuts= +github.com/onsi/ginkgo/v2 v2.9.7 h1:06xGQy5www2oN160RtEZoTvnP2sPhEfePYmCDc2szss= +github.com/onsi/ginkgo/v2 v2.9.7/go.mod h1:cxrmXWykAwTwhQsJOPfdIDiJ+l2RYq7U8hFU+M/1uw0= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.27.4 h1:Z2AnStgsdSayCMDiCU42qIz+HLqEPcgiOCXjAU/w+8E= +github.com/onsi/gomega v1.27.7 h1:fVih9JD6ogIiHUN6ePK7HJidyEDpWGVB5mzM7cWNXoU= github.com/opencontainers/runtime-spec v1.0.2 h1:UfAcuLBJB9Coz72x1hgl8O5RVzTdNiaglX6v2DM6FI0= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= @@ -662,8 +663,8 @@ github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= -github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= +github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY= +github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM= github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= @@ -678,8 +679,8 @@ github.com/quic-go/qtls-go1-20 v0.2.2 h1:WLOPx6OY/hxtTxKV1Zrq20FtXtDEkeY00CGQm8G github.com/quic-go/qtls-go1-20 v0.2.2/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= github.com/quic-go/quic-go v0.33.0 h1:ItNoTDN/Fm/zBlq769lLJc8ECe9gYaW40veHCCco7y0= github.com/quic-go/quic-go v0.33.0/go.mod h1:YMuhaAV9/jIu0XclDXwZPAsP/2Kgr5yMYhe9oxhhOFA= -github.com/quic-go/webtransport-go v0.5.2 h1:GA6Bl6oZY+g/flt00Pnu0XtivSD8vukOu3lYhJjnGEk= -github.com/quic-go/webtransport-go v0.5.2/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= +github.com/quic-go/webtransport-go v0.5.3 h1:5XMlzemqB4qmOlgIus5zB45AcZ2kCgCy2EptUrfOPWU= +github.com/quic-go/webtransport-go v0.5.3/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= @@ -880,8 +881,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g= -golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= +golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM= +golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -984,8 +985,8 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI= +golang.org/x/sync v0.2.0/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-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1046,8 +1047,8 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s= +golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -1061,8 +1062,8 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58= +golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1120,8 +1121,8 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4= -golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= +golang.org/x/tools v0.9.1 h1:8WMNJAz3zrtPmnYC7ISf5dEn3MT0gY7jBJfw27yrrLo= +golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/go.mod b/go.mod index bd0296e80..aedd07bc9 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/ipfs/kubo require ( bazil.org/fuse v0.0.0-20200117225306-7b5117fecadc contrib.go.opencensus.io/exporter/prometheus v0.4.2 - github.com/benbjohnson/clock v1.3.0 + github.com/benbjohnson/clock v1.3.5 github.com/blang/semver/v4 v4.0.0 github.com/cenkalti/backoff/v4 v4.2.1 github.com/ceramicnetwork/go-dag-jose v0.1.0 @@ -45,10 +45,10 @@ require ( github.com/jbenet/goprocess v0.1.4 github.com/julienschmidt/httprouter v1.3.0 github.com/libp2p/go-doh-resolver v0.4.0 - github.com/libp2p/go-libp2p v0.27.5 + github.com/libp2p/go-libp2p v0.27.6 github.com/libp2p/go-libp2p-http v0.5.0 - github.com/libp2p/go-libp2p-kad-dht v0.24.0 - github.com/libp2p/go-libp2p-kbucket v0.6.1 + github.com/libp2p/go-libp2p-kad-dht v0.24.1 + github.com/libp2p/go-libp2p-kbucket v0.6.3 github.com/libp2p/go-libp2p-pubsub v0.9.3 github.com/libp2p/go-libp2p-pubsub-router v0.6.0 github.com/libp2p/go-libp2p-record v0.2.0 @@ -81,11 +81,11 @@ require ( go.uber.org/fx v1.19.3 go.uber.org/multierr v1.11.0 go.uber.org/zap v1.24.0 - golang.org/x/crypto v0.9.0 + golang.org/x/crypto v0.10.0 golang.org/x/exp v0.0.0-20230321023759-10a507213a29 golang.org/x/mod v0.10.0 - golang.org/x/sync v0.1.0 - golang.org/x/sys v0.8.0 + golang.org/x/sync v0.2.0 + golang.org/x/sys v0.9.0 ) require ( @@ -121,14 +121,14 @@ require ( github.com/golang/protobuf v1.5.3 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/gopacket v1.1.19 // indirect - github.com/google/pprof v0.0.0-20230405160723-4a4c7d95572b // indirect + github.com/google/pprof v0.0.0-20230602150820-91b7bce49751 // indirect github.com/gorilla/mux v1.8.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 // indirect github.com/hannahhoward/go-pubsub v0.0.0-20200423002714-8d62886cc36e // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/golang-lru v0.5.4 // indirect github.com/hashicorp/golang-lru/v2 v2.0.2 // indirect - github.com/huin/goupnp v1.1.0 // indirect + github.com/huin/goupnp v1.2.0 // indirect github.com/ipfs/bbloom v0.0.4 // indirect github.com/ipfs/go-bitfield v1.1.0 // indirect github.com/ipfs/go-ipfs-blockstore v1.3.0 // indirect @@ -142,7 +142,7 @@ require ( github.com/ipfs/go-peertaskqueue v0.8.1 // indirect github.com/ipld/edelweiss v0.2.0 // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect - github.com/klauspost/compress v1.16.4 // indirect + github.com/klauspost/compress v1.16.5 // indirect github.com/klauspost/cpuid/v2 v2.2.5 // indirect github.com/koron/go-ssdp v0.0.4 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect @@ -155,7 +155,7 @@ require ( github.com/libp2p/go-msgio v0.3.0 // indirect github.com/libp2p/go-nat v0.1.0 // indirect github.com/libp2p/go-netroute v0.2.1 // indirect - github.com/libp2p/go-reuseport v0.2.0 // indirect + github.com/libp2p/go-reuseport v0.3.0 // indirect github.com/libp2p/go-yamux/v4 v4.0.0 // indirect github.com/libp2p/zeroconf/v2 v2.2.0 // indirect github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect @@ -164,7 +164,7 @@ require ( github.com/mattn/go-runewidth v0.0.4 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect - github.com/miekg/dns v1.1.53 // indirect + github.com/miekg/dns v1.1.54 // indirect github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect github.com/minio/sha256-simd v1.0.1 // indirect @@ -174,13 +174,13 @@ require ( github.com/multiformats/go-multiaddr-fmt v0.1.0 // indirect github.com/multiformats/go-multistream v0.4.1 // indirect github.com/multiformats/go-varint v0.0.7 // indirect - github.com/onsi/ginkgo/v2 v2.9.2 // indirect + github.com/onsi/ginkgo/v2 v2.9.7 // indirect github.com/opencontainers/runtime-spec v1.0.2 // indirect github.com/openzipkin/zipkin-go v0.4.1 // indirect github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/polydawn/refmt v0.89.0 // indirect - github.com/prometheus/client_model v0.3.0 // indirect + github.com/prometheus/client_model v0.4.0 // indirect github.com/prometheus/common v0.42.0 // indirect github.com/prometheus/procfs v0.9.0 // indirect github.com/prometheus/statsd_exporter v0.22.7 // indirect @@ -188,7 +188,7 @@ require ( github.com/quic-go/qtls-go1-19 v0.3.2 // indirect github.com/quic-go/qtls-go1-20 v0.2.2 // indirect github.com/quic-go/quic-go v0.33.0 // indirect - github.com/quic-go/webtransport-go v0.5.2 // indirect + github.com/quic-go/webtransport-go v0.5.3 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/rs/cors v1.7.0 // indirect github.com/samber/lo v1.36.0 // indirect @@ -219,9 +219,9 @@ require ( go4.org v0.0.0-20230225012048-214862532bf5 // indirect golang.org/x/net v0.10.0 // indirect golang.org/x/oauth2 v0.6.0 // indirect - golang.org/x/term v0.8.0 // indirect - golang.org/x/text v0.9.0 // indirect - golang.org/x/tools v0.7.0 // indirect + golang.org/x/term v0.9.0 // indirect + golang.org/x/text v0.10.0 // indirect + golang.org/x/tools v0.9.1 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect gonum.org/v1/gonum v0.13.0 // indirect google.golang.org/appengine v1.6.7 // indirect diff --git a/go.sum b/go.sum index fa503f351..a044a459b 100644 --- a/go.sum +++ b/go.sum @@ -65,8 +65,9 @@ github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYU github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= -github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o= +github.com/benbjohnson/clock v1.3.5/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -307,8 +308,8 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20230405160723-4a4c7d95572b h1:Qcx5LM0fSiks9uCyFZwDBUasd3lxd1RM0GYpL+Li5o4= -github.com/google/pprof v0.0.0-20230405160723-4a4c7d95572b/go.mod h1:79YE0hCXdHag9sBkw2o+N/YnZtTkXi0UT9Nnixa5eYk= +github.com/google/pprof v0.0.0-20230602150820-91b7bce49751 h1:hR7/MlvK23p6+lIw9SN1TigNLn9ZnF3W4SYRKq2gAHs= +github.com/google/pprof v0.0.0-20230602150820-91b7bce49751/go.mod h1:Jh3hGz2jkYak8qXPD19ryItVnUgpgeqzdkY/D0EaeuA= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -347,8 +348,8 @@ github.com/hashicorp/golang-lru/v2 v2.0.2/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyf github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= -github.com/huin/goupnp v1.1.0 h1:gEe0Dp/lZmPZiDFzJJaOfUpOvv2MKUkoBX8lDrn9vKU= -github.com/huin/goupnp v1.1.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= +github.com/huin/goupnp v1.2.0 h1:uOKW26NG1hsSSbXIZ1IR7XP9Gjd1U8pnLaCMgntmkmY= +github.com/huin/goupnp v1.2.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= @@ -500,8 +501,8 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI 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.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/klauspost/compress v1.16.4 h1:91KN02FnsOYhuunwU4ssRe8lc2JosWmizWa91B5v1PU= -github.com/klauspost/compress v1.16.4/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/compress v1.16.5 h1:IFV2oUNUzZaz+XyusxpLzpzS8Pt5rh0Z16For/djlyI= +github.com/klauspost/compress v1.16.5/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= @@ -536,8 +537,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.27.5 h1:KwA7pXKXpz8hG6Cr1fMA7UkgleogcwQj0sxl5qquWRg= -github.com/libp2p/go-libp2p v0.27.5/go.mod h1:oMfQGTb9CHnrOuSM6yMmyK2lXz3qIhnkn2+oK3B1Y2g= +github.com/libp2p/go-libp2p v0.27.6 h1:KmGU5kskCaaerm53heqzfGOlrW2z8icZ+fnyqgrZs38= +github.com/libp2p/go-libp2p v0.27.6/go.mod h1:oMfQGTb9CHnrOuSM6yMmyK2lXz3qIhnkn2+oK3B1Y2g= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= @@ -546,11 +547,11 @@ github.com/libp2p/go-libp2p-gostream v0.6.0 h1:QfAiWeQRce6pqnYfmIVWJFXNdDyfiR/qk github.com/libp2p/go-libp2p-gostream v0.6.0/go.mod h1:Nywu0gYZwfj7Jc91PQvbGU8dIpqbQQkjWgDuOrFaRdA= github.com/libp2p/go-libp2p-http v0.5.0 h1:+x0AbLaUuLBArHubbbNRTsgWz0RjNTy6DJLOxQ3/QBc= github.com/libp2p/go-libp2p-http v0.5.0/go.mod h1:glh87nZ35XCQyFsdzZps6+F4HYI6DctVFY5u1fehwSg= -github.com/libp2p/go-libp2p-kad-dht v0.24.0 h1:nZnFDQEFU4N8GzclnR+IGxIgR7k4PPCDk/GK9A28onk= -github.com/libp2p/go-libp2p-kad-dht v0.24.0/go.mod h1:lfu5T01EH+r6uDZ/8G+ObhwgzVyd0b1nb54AdT8XGhc= +github.com/libp2p/go-libp2p-kad-dht v0.24.1 h1:XH9vIWqc6e+w6z2Nvt9R5EhkBNnOQl7tyxxM6soejwo= +github.com/libp2p/go-libp2p-kad-dht v0.24.1/go.mod h1:1meiUvgOxfSPBx1pracS4VyYwmusorvv+TVRI3mXaJI= github.com/libp2p/go-libp2p-kbucket v0.3.1/go.mod h1:oyjT5O7tS9CQurok++ERgc46YLwEpuGoFq9ubvoUOio= -github.com/libp2p/go-libp2p-kbucket v0.6.1 h1:Y/NIvALuY5/fJlOpaJor9Azg4eor15JskGs9Lb2EhH0= -github.com/libp2p/go-libp2p-kbucket v0.6.1/go.mod h1:dvWO707Oq/vhMVuUhyfLkw0QsOrJFETepbNfpVHSELI= +github.com/libp2p/go-libp2p-kbucket v0.6.3 h1:p507271wWzpy2f1XxPzCQG9NiN6R6lHL9GiSErbQQo0= +github.com/libp2p/go-libp2p-kbucket v0.6.3/go.mod h1:RCseT7AH6eJWxxk2ol03xtP9pEHetYSPXOaJnOiD8i0= github.com/libp2p/go-libp2p-peerstore v0.1.4/go.mod h1:+4BDbDiiKf4PzpANZDAT+knVdLxvqh7hXOujessqdzs= github.com/libp2p/go-libp2p-pubsub v0.9.3 h1:ihcz9oIBMaCK9kcx+yHWm3mLAFBMAUsM4ux42aikDxo= github.com/libp2p/go-libp2p-pubsub v0.9.3/go.mod h1:RYA7aM9jIic5VV47WXu4GkcRxRhrdElWf8xtyli+Dzc= @@ -576,8 +577,8 @@ github.com/libp2p/go-netroute v0.2.1 h1:V8kVrpD8GK0Riv15/7VN6RbUQ3URNZVosw7H2v9t github.com/libp2p/go-netroute v0.2.1/go.mod h1:hraioZr0fhBjG0ZRXJJ6Zj2IVEVNx6tDTFQfSmcq7mQ= 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= -github.com/libp2p/go-reuseport v0.2.0 h1:18PRvIMlpY6ZK85nIAicSBuXXvrYoSw3dsBAR7zc560= -github.com/libp2p/go-reuseport v0.2.0/go.mod h1:bvVho6eLMm6Bz5hmU0LYN3ixd3nPPvtIlaURZZgOY4k= +github.com/libp2p/go-reuseport v0.3.0 h1:iiZslO5byUYZEg9iCwJGf5h+sf1Agmqx2V2FDjPyvUw= +github.com/libp2p/go-reuseport v0.3.0/go.mod h1:laea40AimhtfEqysZ71UpYj4S+R9VpH8PgqLo7L+SwI= github.com/libp2p/go-sockaddr v0.0.2/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= @@ -614,8 +615,8 @@ github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyex github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= -github.com/miekg/dns v1.1.53 h1:ZBkuHr5dxHtB1caEOlZTLPo7D3L3TWckgUUs/RHfDxw= -github.com/miekg/dns v1.1.53/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= +github.com/miekg/dns v1.1.54 h1:5jon9mWcb0sFJGpnI99tOMhCPyJ+RPVz5b63MQG0VWI= +github.com/miekg/dns v1.1.54/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c h1:bzE/A84HN25pxAuk9Eej1Kz9OUelF97nAc82bDquQI8= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c/go.mod h1:0SQS9kMwD2VsyFEB++InYyBJroV/FRmBgcydeSUcJms= github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= @@ -696,12 +697,12 @@ github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= -github.com/onsi/ginkgo/v2 v2.9.2 h1:BA2GMJOtfGAfagzYtrAlufIP0lq6QERkFmHLMLPwFSU= -github.com/onsi/ginkgo/v2 v2.9.2/go.mod h1:WHcJJG2dIlcCqVfBAwUCrJxSPFb6v4azBwgxeMeDuts= +github.com/onsi/ginkgo/v2 v2.9.7 h1:06xGQy5www2oN160RtEZoTvnP2sPhEfePYmCDc2szss= +github.com/onsi/ginkgo/v2 v2.9.7/go.mod h1:cxrmXWykAwTwhQsJOPfdIDiJ+l2RYq7U8hFU+M/1uw0= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.27.4 h1:Z2AnStgsdSayCMDiCU42qIz+HLqEPcgiOCXjAU/w+8E= +github.com/onsi/gomega v1.27.7 h1:fVih9JD6ogIiHUN6ePK7HJidyEDpWGVB5mzM7cWNXoU= github.com/opencontainers/runtime-spec v1.0.2 h1:UfAcuLBJB9Coz72x1hgl8O5RVzTdNiaglX6v2DM6FI0= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= @@ -741,8 +742,8 @@ github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1: github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= -github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= +github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY= +github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= @@ -773,8 +774,8 @@ github.com/quic-go/qtls-go1-20 v0.2.2 h1:WLOPx6OY/hxtTxKV1Zrq20FtXtDEkeY00CGQm8G github.com/quic-go/qtls-go1-20 v0.2.2/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= github.com/quic-go/quic-go v0.33.0 h1:ItNoTDN/Fm/zBlq769lLJc8ECe9gYaW40veHCCco7y0= github.com/quic-go/quic-go v0.33.0/go.mod h1:YMuhaAV9/jIu0XclDXwZPAsP/2Kgr5yMYhe9oxhhOFA= -github.com/quic-go/webtransport-go v0.5.2 h1:GA6Bl6oZY+g/flt00Pnu0XtivSD8vukOu3lYhJjnGEk= -github.com/quic-go/webtransport-go v0.5.2/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= +github.com/quic-go/webtransport-go v0.5.3 h1:5XMlzemqB4qmOlgIus5zB45AcZ2kCgCy2EptUrfOPWU= +github.com/quic-go/webtransport-go v0.5.3/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= @@ -1007,8 +1008,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g= -golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= +golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM= +golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1123,8 +1124,8 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI= +golang.org/x/sync v0.2.0/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-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1196,14 +1197,14 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s= +golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols= -golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.9.0 h1:GRRCnKYhdQrD8kfRAdQ6Zcw1P0OcELxGLKJvtjVMZ28= +golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1213,8 +1214,8 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58= +golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1272,8 +1273,8 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4= -golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= +golang.org/x/tools v0.9.1 h1:8WMNJAz3zrtPmnYC7ISf5dEn3MT0gY7jBJfw27yrrLo= +golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 2564e2bdc..ce3c34d7b 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -19,7 +19,7 @@ require ( github.com/ipld/go-ipld-prime v0.20.0 github.com/jbenet/go-random v0.0.0-20190219211222-123a90aedc0c github.com/jbenet/go-random-files v0.0.0-20190219210431-31b3f20ebded - github.com/libp2p/go-libp2p v0.27.5 + github.com/libp2p/go-libp2p v0.27.6 github.com/multiformats/go-multiaddr v0.9.0 github.com/multiformats/go-multihash v0.2.3 gotest.tools/gotestsum v0.4.2 @@ -39,7 +39,7 @@ require ( github.com/alingse/asasalint v0.0.11 // indirect github.com/ashanbrown/forbidigo v1.3.0 // indirect github.com/ashanbrown/makezero v1.1.1 // indirect - github.com/benbjohnson/clock v1.3.0 // indirect + github.com/benbjohnson/clock v1.3.5 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bkielbasa/cyclop v1.2.0 // indirect github.com/blizzy78/varnamelen v0.8.0 // indirect @@ -101,7 +101,7 @@ require ( github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4 // indirect github.com/google/go-cmp v0.5.9 // indirect github.com/google/gopacket v1.1.19 // indirect - github.com/google/pprof v0.0.0-20230405160723-4a4c7d95572b // indirect + github.com/google/pprof v0.0.0-20230602150820-91b7bce49751 // indirect github.com/google/uuid v1.3.0 // indirect github.com/gordonklaus/ineffassign v0.0.0-20210914165742-4cc7213b9bc8 // indirect github.com/gostaticanalysis/analysisutil v0.7.1 // indirect @@ -116,7 +116,7 @@ require ( github.com/hashicorp/golang-lru v0.5.4 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/hexops/gotextdiff v1.0.3 // indirect - github.com/huin/goupnp v1.1.0 // indirect + github.com/huin/goupnp v1.2.0 // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/ipfs/bbloom v0.0.4 // indirect github.com/ipfs/go-bitfield v1.1.0 // indirect @@ -144,7 +144,7 @@ require ( github.com/julz/importas v0.1.0 // indirect github.com/kisielk/errcheck v1.6.2 // indirect github.com/kisielk/gotool v1.0.0 // indirect - github.com/klauspost/compress v1.16.4 // indirect + github.com/klauspost/compress v1.16.5 // indirect github.com/klauspost/cpuid/v2 v2.2.5 // indirect github.com/koron/go-ssdp v0.0.4 // indirect github.com/kulti/thelper v0.6.3 // indirect @@ -160,7 +160,7 @@ require ( github.com/libp2p/go-msgio v0.3.0 // indirect github.com/libp2p/go-nat v0.1.0 // indirect github.com/libp2p/go-netroute v0.2.1 // indirect - github.com/libp2p/go-reuseport v0.2.0 // indirect + github.com/libp2p/go-reuseport v0.3.0 // indirect github.com/libp2p/go-yamux/v4 v4.0.0 // indirect github.com/lufeee/execinquery v1.2.1 // indirect github.com/magiconair/properties v1.8.6 // indirect @@ -173,7 +173,7 @@ require ( github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/mbilski/exhaustivestruct v1.2.0 // indirect github.com/mgechev/revive v1.2.3 // indirect - github.com/miekg/dns v1.1.53 // indirect + github.com/miekg/dns v1.1.54 // indirect github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect github.com/minio/sha256-simd v1.0.1 // indirect @@ -194,7 +194,7 @@ require ( github.com/nishanths/exhaustive v0.8.1 // indirect github.com/nishanths/predeclared v0.2.2 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect - github.com/onsi/ginkgo/v2 v2.9.2 // indirect + github.com/onsi/ginkgo/v2 v2.9.7 // indirect github.com/opencontainers/runtime-spec v1.0.2 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect @@ -206,7 +206,7 @@ require ( github.com/polydawn/refmt v0.89.0 // indirect github.com/polyfloyd/go-errorlint v1.0.2 // indirect github.com/prometheus/client_golang v1.14.0 // indirect - github.com/prometheus/client_model v0.3.0 // indirect + github.com/prometheus/client_model v0.4.0 // indirect github.com/prometheus/common v0.42.0 // indirect github.com/prometheus/procfs v0.9.0 // indirect github.com/quasilyte/go-ruleguard v0.3.17 // indirect @@ -217,7 +217,7 @@ require ( github.com/quic-go/qtls-go1-19 v0.3.2 // indirect github.com/quic-go/qtls-go1-20 v0.2.2 // indirect github.com/quic-go/quic-go v0.33.0 // indirect - github.com/quic-go/webtransport-go v0.5.2 // indirect + github.com/quic-go/webtransport-go v0.5.3 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/ryancurrah/gomodguard v1.2.4 // indirect @@ -267,16 +267,16 @@ require ( go.uber.org/fx v1.19.3 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.24.0 // indirect - golang.org/x/crypto v0.9.0 // indirect + golang.org/x/crypto v0.10.0 // indirect golang.org/x/exp v0.0.0-20230321023759-10a507213a29 // indirect golang.org/x/exp/typeparams v0.0.0-20220613132600-b0d781184e0d // indirect golang.org/x/mod v0.10.0 // indirect golang.org/x/net v0.10.0 // indirect - golang.org/x/sync v0.1.0 // indirect - golang.org/x/sys v0.8.0 // indirect - golang.org/x/term v0.8.0 // indirect - golang.org/x/text v0.9.0 // indirect - golang.org/x/tools v0.7.0 // indirect + golang.org/x/sync v0.2.0 // indirect + golang.org/x/sys v0.9.0 // indirect + golang.org/x/term v0.9.0 // indirect + golang.org/x/text v0.10.0 // indirect + golang.org/x/tools v0.9.1 // indirect google.golang.org/protobuf v1.30.0 // indirect gopkg.in/ini.v1 v1.66.6 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index a8ed1279e..431fcdbba 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -80,8 +80,9 @@ github.com/ashanbrown/forbidigo v1.3.0/go.mod h1:vVW7PEdqEFqapJe95xHkTfB1+XvZXBF github.com/ashanbrown/makezero v1.1.1 h1:iCQ87C0V0vSyO+M9E/FZYbu65auqH0lnsOkf5FcB28s= github.com/ashanbrown/makezero v1.1.1/go.mod h1:i1bJLCRSCHOcOa9Y6MyF2FTfMZMFdHvxKHxgO5Z1axI= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= -github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o= +github.com/benbjohnson/clock v1.3.5/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -346,8 +347,8 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20230405160723-4a4c7d95572b h1:Qcx5LM0fSiks9uCyFZwDBUasd3lxd1RM0GYpL+Li5o4= -github.com/google/pprof v0.0.0-20230405160723-4a4c7d95572b/go.mod h1:79YE0hCXdHag9sBkw2o+N/YnZtTkXi0UT9Nnixa5eYk= +github.com/google/pprof v0.0.0-20230602150820-91b7bce49751 h1:hR7/MlvK23p6+lIw9SN1TigNLn9ZnF3W4SYRKq2gAHs= +github.com/google/pprof v0.0.0-20230602150820-91b7bce49751/go.mod h1:Jh3hGz2jkYak8qXPD19ryItVnUgpgeqzdkY/D0EaeuA= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -403,8 +404,8 @@ github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUq github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= -github.com/huin/goupnp v1.1.0 h1:gEe0Dp/lZmPZiDFzJJaOfUpOvv2MKUkoBX8lDrn9vKU= -github.com/huin/goupnp v1.1.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= +github.com/huin/goupnp v1.2.0 h1:uOKW26NG1hsSSbXIZ1IR7XP9Gjd1U8pnLaCMgntmkmY= +github.com/huin/goupnp v1.2.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= @@ -523,8 +524,8 @@ github.com/kisielk/errcheck v1.6.2/go.mod h1:nXw/i/MfnvRHqXa7XXmQMUB0oNFGuBrNI8d github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/klauspost/compress v1.16.4 h1:91KN02FnsOYhuunwU4ssRe8lc2JosWmizWa91B5v1PU= -github.com/klauspost/compress v1.16.4/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/compress v1.16.5 h1:IFV2oUNUzZaz+XyusxpLzpzS8Pt5rh0Z16For/djlyI= +github.com/klauspost/compress v1.16.5/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -564,8 +565,8 @@ github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38y github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.27.5 h1:KwA7pXKXpz8hG6Cr1fMA7UkgleogcwQj0sxl5qquWRg= -github.com/libp2p/go-libp2p v0.27.5/go.mod h1:oMfQGTb9CHnrOuSM6yMmyK2lXz3qIhnkn2+oK3B1Y2g= +github.com/libp2p/go-libp2p v0.27.6 h1:KmGU5kskCaaerm53heqzfGOlrW2z8icZ+fnyqgrZs38= +github.com/libp2p/go-libp2p v0.27.6/go.mod h1:oMfQGTb9CHnrOuSM6yMmyK2lXz3qIhnkn2+oK3B1Y2g= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= @@ -577,8 +578,8 @@ 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.2.1 h1:V8kVrpD8GK0Riv15/7VN6RbUQ3URNZVosw7H2v9tksU= github.com/libp2p/go-netroute v0.2.1/go.mod h1:hraioZr0fhBjG0ZRXJJ6Zj2IVEVNx6tDTFQfSmcq7mQ= -github.com/libp2p/go-reuseport v0.2.0 h1:18PRvIMlpY6ZK85nIAicSBuXXvrYoSw3dsBAR7zc560= -github.com/libp2p/go-reuseport v0.2.0/go.mod h1:bvVho6eLMm6Bz5hmU0LYN3ixd3nPPvtIlaURZZgOY4k= +github.com/libp2p/go-reuseport v0.3.0 h1:iiZslO5byUYZEg9iCwJGf5h+sf1Agmqx2V2FDjPyvUw= +github.com/libp2p/go-reuseport v0.3.0/go.mod h1:laea40AimhtfEqysZ71UpYj4S+R9VpH8PgqLo7L+SwI= github.com/libp2p/go-sockaddr v0.0.2/go.mod h1:syPvOmNs24S3dFVGJA1/mrqdeijPxLV2Le3BRLKd68k= github.com/libp2p/go-yamux/v4 v4.0.0 h1:+Y80dV2Yx/kv7Y7JKu0LECyVdMXm1VUoko+VQ9rBfZQ= github.com/libp2p/go-yamux/v4 v4.0.0/go.mod h1:NWjl8ZTLOGlozrXSOZ/HlfG++39iKNnM5wwmtQP1YB4= @@ -618,8 +619,8 @@ github.com/mgechev/revive v1.2.3 h1:NzIEEa9+WimQ6q2Ov7OcNeySS/IOcwtkQ8RAh0R5UJ4= github.com/mgechev/revive v1.2.3/go.mod h1:iAWlQishqCuj4yhV24FTnKSXGpbAA+0SckXB8GQMX/Q= github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= -github.com/miekg/dns v1.1.53 h1:ZBkuHr5dxHtB1caEOlZTLPo7D3L3TWckgUUs/RHfDxw= -github.com/miekg/dns v1.1.53/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= +github.com/miekg/dns v1.1.54 h1:5jon9mWcb0sFJGpnI99tOMhCPyJ+RPVz5b63MQG0VWI= +github.com/miekg/dns v1.1.54/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c h1:bzE/A84HN25pxAuk9Eej1Kz9OUelF97nAc82bDquQI8= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c/go.mod h1:0SQS9kMwD2VsyFEB++InYyBJroV/FRmBgcydeSUcJms= github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= @@ -693,10 +694,10 @@ github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo/v2 v2.9.2 h1:BA2GMJOtfGAfagzYtrAlufIP0lq6QERkFmHLMLPwFSU= -github.com/onsi/ginkgo/v2 v2.9.2/go.mod h1:WHcJJG2dIlcCqVfBAwUCrJxSPFb6v4azBwgxeMeDuts= +github.com/onsi/ginkgo/v2 v2.9.7 h1:06xGQy5www2oN160RtEZoTvnP2sPhEfePYmCDc2szss= +github.com/onsi/ginkgo/v2 v2.9.7/go.mod h1:cxrmXWykAwTwhQsJOPfdIDiJ+l2RYq7U8hFU+M/1uw0= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.27.4 h1:Z2AnStgsdSayCMDiCU42qIz+HLqEPcgiOCXjAU/w+8E= +github.com/onsi/gomega v1.27.7 h1:fVih9JD6ogIiHUN6ePK7HJidyEDpWGVB5mzM7cWNXoU= github.com/opencontainers/runtime-spec v1.0.2 h1:UfAcuLBJB9Coz72x1hgl8O5RVzTdNiaglX6v2DM6FI0= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= @@ -740,8 +741,8 @@ github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1: github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= -github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= +github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY= +github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= @@ -778,8 +779,8 @@ github.com/quic-go/qtls-go1-20 v0.2.2 h1:WLOPx6OY/hxtTxKV1Zrq20FtXtDEkeY00CGQm8G github.com/quic-go/qtls-go1-20 v0.2.2/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= github.com/quic-go/quic-go v0.33.0 h1:ItNoTDN/Fm/zBlq769lLJc8ECe9gYaW40veHCCco7y0= github.com/quic-go/quic-go v0.33.0/go.mod h1:YMuhaAV9/jIu0XclDXwZPAsP/2Kgr5yMYhe9oxhhOFA= -github.com/quic-go/webtransport-go v0.5.2 h1:GA6Bl6oZY+g/flt00Pnu0XtivSD8vukOu3lYhJjnGEk= -github.com/quic-go/webtransport-go v0.5.2/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= +github.com/quic-go/webtransport-go v0.5.3 h1:5XMlzemqB4qmOlgIus5zB45AcZ2kCgCy2EptUrfOPWU= +github.com/quic-go/webtransport-go v0.5.3/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= @@ -990,8 +991,8 @@ golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g= -golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= +golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM= +golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1107,8 +1108,8 @@ 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/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI= +golang.org/x/sync v0.2.0/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-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1177,12 +1178,12 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s= +golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols= -golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.9.0 h1:GRRCnKYhdQrD8kfRAdQ6Zcw1P0OcELxGLKJvtjVMZ28= +golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1191,8 +1192,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58= +golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1285,8 +1286,8 @@ golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/tools v0.1.11/go.mod h1:SgwaegtQh8clINPpECJMqnxLv9I09HLqnW3RMqW0CA4= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4= -golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= +golang.org/x/tools v0.9.1 h1:8WMNJAz3zrtPmnYC7ISf5dEn3MT0gY7jBJfw27yrrLo= +golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From aa4e8838c72ed3bfae19aea398e075388106b38b Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Tue, 13 Jun 2023 14:43:57 +0200 Subject: [PATCH 0724/1212] fix: more stable prometheus test (#9944) --- .../t0119-prometheus-data/prometheus_metrics | 379 ------------------ test/sharness/t0119-prometheus.sh | 4 +- 2 files changed, 2 insertions(+), 381 deletions(-) diff --git a/test/sharness/t0119-prometheus-data/prometheus_metrics b/test/sharness/t0119-prometheus-data/prometheus_metrics index 5db8a7665..22239ff19 100644 --- a/test/sharness/t0119-prometheus-data/prometheus_metrics +++ b/test/sharness/t0119-prometheus-data/prometheus_metrics @@ -1,169 +1,83 @@ flatfs_datastore_batchcommit_errors_total flatfs_datastore_batchcommit_latency_seconds_bucket -flatfs_datastore_batchcommit_latency_seconds_bucket -flatfs_datastore_batchcommit_latency_seconds_bucket -flatfs_datastore_batchcommit_latency_seconds_bucket -flatfs_datastore_batchcommit_latency_seconds_bucket -flatfs_datastore_batchcommit_latency_seconds_bucket flatfs_datastore_batchcommit_latency_seconds_count flatfs_datastore_batchcommit_latency_seconds_sum flatfs_datastore_batchcommit_total flatfs_datastore_batchdelete_errors_total flatfs_datastore_batchdelete_latency_seconds_bucket -flatfs_datastore_batchdelete_latency_seconds_bucket -flatfs_datastore_batchdelete_latency_seconds_bucket -flatfs_datastore_batchdelete_latency_seconds_bucket -flatfs_datastore_batchdelete_latency_seconds_bucket -flatfs_datastore_batchdelete_latency_seconds_bucket flatfs_datastore_batchdelete_latency_seconds_count flatfs_datastore_batchdelete_latency_seconds_sum flatfs_datastore_batchdelete_total flatfs_datastore_batchput_errors_total flatfs_datastore_batchput_latency_seconds_bucket -flatfs_datastore_batchput_latency_seconds_bucket -flatfs_datastore_batchput_latency_seconds_bucket -flatfs_datastore_batchput_latency_seconds_bucket -flatfs_datastore_batchput_latency_seconds_bucket -flatfs_datastore_batchput_latency_seconds_bucket flatfs_datastore_batchput_latency_seconds_count flatfs_datastore_batchput_latency_seconds_sum flatfs_datastore_batchput_size_bytes_bucket -flatfs_datastore_batchput_size_bytes_bucket -flatfs_datastore_batchput_size_bytes_bucket -flatfs_datastore_batchput_size_bytes_bucket -flatfs_datastore_batchput_size_bytes_bucket flatfs_datastore_batchput_size_bytes_count flatfs_datastore_batchput_size_bytes_sum flatfs_datastore_batchput_total flatfs_datastore_check_errors_total flatfs_datastore_check_latency_seconds_bucket -flatfs_datastore_check_latency_seconds_bucket -flatfs_datastore_check_latency_seconds_bucket -flatfs_datastore_check_latency_seconds_bucket -flatfs_datastore_check_latency_seconds_bucket -flatfs_datastore_check_latency_seconds_bucket flatfs_datastore_check_latency_seconds_count flatfs_datastore_check_latency_seconds_sum flatfs_datastore_check_total flatfs_datastore_delete_errors_total flatfs_datastore_delete_latency_seconds_bucket -flatfs_datastore_delete_latency_seconds_bucket -flatfs_datastore_delete_latency_seconds_bucket -flatfs_datastore_delete_latency_seconds_bucket -flatfs_datastore_delete_latency_seconds_bucket -flatfs_datastore_delete_latency_seconds_bucket flatfs_datastore_delete_latency_seconds_count flatfs_datastore_delete_latency_seconds_sum flatfs_datastore_delete_total flatfs_datastore_du_errors_total flatfs_datastore_du_latency_seconds_bucket -flatfs_datastore_du_latency_seconds_bucket -flatfs_datastore_du_latency_seconds_bucket -flatfs_datastore_du_latency_seconds_bucket -flatfs_datastore_du_latency_seconds_bucket -flatfs_datastore_du_latency_seconds_bucket flatfs_datastore_du_latency_seconds_count flatfs_datastore_du_latency_seconds_sum flatfs_datastore_du_total flatfs_datastore_gc_errors_total flatfs_datastore_gc_latency_seconds_bucket -flatfs_datastore_gc_latency_seconds_bucket -flatfs_datastore_gc_latency_seconds_bucket -flatfs_datastore_gc_latency_seconds_bucket -flatfs_datastore_gc_latency_seconds_bucket -flatfs_datastore_gc_latency_seconds_bucket flatfs_datastore_gc_latency_seconds_count flatfs_datastore_gc_latency_seconds_sum flatfs_datastore_gc_total flatfs_datastore_get_errors_total flatfs_datastore_get_latency_seconds_bucket -flatfs_datastore_get_latency_seconds_bucket -flatfs_datastore_get_latency_seconds_bucket -flatfs_datastore_get_latency_seconds_bucket -flatfs_datastore_get_latency_seconds_bucket -flatfs_datastore_get_latency_seconds_bucket flatfs_datastore_get_latency_seconds_count flatfs_datastore_get_latency_seconds_sum flatfs_datastore_get_size_bytes_bucket -flatfs_datastore_get_size_bytes_bucket -flatfs_datastore_get_size_bytes_bucket -flatfs_datastore_get_size_bytes_bucket -flatfs_datastore_get_size_bytes_bucket flatfs_datastore_get_size_bytes_count flatfs_datastore_get_size_bytes_sum flatfs_datastore_get_total flatfs_datastore_getsize_errors_total flatfs_datastore_getsize_latency_seconds_bucket -flatfs_datastore_getsize_latency_seconds_bucket -flatfs_datastore_getsize_latency_seconds_bucket -flatfs_datastore_getsize_latency_seconds_bucket -flatfs_datastore_getsize_latency_seconds_bucket -flatfs_datastore_getsize_latency_seconds_bucket flatfs_datastore_getsize_latency_seconds_count flatfs_datastore_getsize_latency_seconds_sum flatfs_datastore_getsize_total flatfs_datastore_has_errors_total flatfs_datastore_has_latency_seconds_bucket -flatfs_datastore_has_latency_seconds_bucket -flatfs_datastore_has_latency_seconds_bucket -flatfs_datastore_has_latency_seconds_bucket -flatfs_datastore_has_latency_seconds_bucket -flatfs_datastore_has_latency_seconds_bucket flatfs_datastore_has_latency_seconds_count flatfs_datastore_has_latency_seconds_sum flatfs_datastore_has_total flatfs_datastore_put_errors_total flatfs_datastore_put_latency_seconds_bucket -flatfs_datastore_put_latency_seconds_bucket -flatfs_datastore_put_latency_seconds_bucket -flatfs_datastore_put_latency_seconds_bucket -flatfs_datastore_put_latency_seconds_bucket -flatfs_datastore_put_latency_seconds_bucket flatfs_datastore_put_latency_seconds_count flatfs_datastore_put_latency_seconds_sum flatfs_datastore_put_size_bytes_bucket -flatfs_datastore_put_size_bytes_bucket -flatfs_datastore_put_size_bytes_bucket -flatfs_datastore_put_size_bytes_bucket -flatfs_datastore_put_size_bytes_bucket flatfs_datastore_put_size_bytes_count flatfs_datastore_put_size_bytes_sum flatfs_datastore_put_total flatfs_datastore_query_errors_total flatfs_datastore_query_latency_seconds_bucket -flatfs_datastore_query_latency_seconds_bucket -flatfs_datastore_query_latency_seconds_bucket -flatfs_datastore_query_latency_seconds_bucket -flatfs_datastore_query_latency_seconds_bucket -flatfs_datastore_query_latency_seconds_bucket flatfs_datastore_query_latency_seconds_count flatfs_datastore_query_latency_seconds_sum flatfs_datastore_query_total flatfs_datastore_scrub_errors_total flatfs_datastore_scrub_latency_seconds_bucket -flatfs_datastore_scrub_latency_seconds_bucket -flatfs_datastore_scrub_latency_seconds_bucket -flatfs_datastore_scrub_latency_seconds_bucket -flatfs_datastore_scrub_latency_seconds_bucket -flatfs_datastore_scrub_latency_seconds_bucket flatfs_datastore_scrub_latency_seconds_count flatfs_datastore_scrub_latency_seconds_sum flatfs_datastore_scrub_total flatfs_datastore_sync_errors_total flatfs_datastore_sync_latency_seconds_bucket -flatfs_datastore_sync_latency_seconds_bucket -flatfs_datastore_sync_latency_seconds_bucket -flatfs_datastore_sync_latency_seconds_bucket -flatfs_datastore_sync_latency_seconds_bucket -flatfs_datastore_sync_latency_seconds_bucket flatfs_datastore_sync_latency_seconds_count flatfs_datastore_sync_latency_seconds_sum flatfs_datastore_sync_total go_gc_duration_seconds -go_gc_duration_seconds -go_gc_duration_seconds -go_gc_duration_seconds -go_gc_duration_seconds go_gc_duration_seconds_count go_gc_duration_seconds_sum go_goroutines @@ -197,40 +111,15 @@ ipfs_bitswap_active_tasks ipfs_bitswap_pending_block_tasks ipfs_bitswap_pending_tasks ipfs_bitswap_recv_all_blocks_bytes_bucket -ipfs_bitswap_recv_all_blocks_bytes_bucket -ipfs_bitswap_recv_all_blocks_bytes_bucket -ipfs_bitswap_recv_all_blocks_bytes_bucket -ipfs_bitswap_recv_all_blocks_bytes_bucket -ipfs_bitswap_recv_all_blocks_bytes_bucket -ipfs_bitswap_recv_all_blocks_bytes_bucket ipfs_bitswap_recv_all_blocks_bytes_count ipfs_bitswap_recv_all_blocks_bytes_sum ipfs_bitswap_recv_dup_blocks_bytes_bucket -ipfs_bitswap_recv_dup_blocks_bytes_bucket -ipfs_bitswap_recv_dup_blocks_bytes_bucket -ipfs_bitswap_recv_dup_blocks_bytes_bucket -ipfs_bitswap_recv_dup_blocks_bytes_bucket -ipfs_bitswap_recv_dup_blocks_bytes_bucket -ipfs_bitswap_recv_dup_blocks_bytes_bucket ipfs_bitswap_recv_dup_blocks_bytes_count ipfs_bitswap_recv_dup_blocks_bytes_sum ipfs_bitswap_send_times_bucket -ipfs_bitswap_send_times_bucket -ipfs_bitswap_send_times_bucket -ipfs_bitswap_send_times_bucket -ipfs_bitswap_send_times_bucket -ipfs_bitswap_send_times_bucket -ipfs_bitswap_send_times_bucket -ipfs_bitswap_send_times_bucket ipfs_bitswap_send_times_count ipfs_bitswap_send_times_sum ipfs_bitswap_sent_all_blocks_bytes_bucket -ipfs_bitswap_sent_all_blocks_bytes_bucket -ipfs_bitswap_sent_all_blocks_bytes_bucket -ipfs_bitswap_sent_all_blocks_bytes_bucket -ipfs_bitswap_sent_all_blocks_bytes_bucket -ipfs_bitswap_sent_all_blocks_bytes_bucket -ipfs_bitswap_sent_all_blocks_bytes_bucket ipfs_bitswap_sent_all_blocks_bytes_count ipfs_bitswap_sent_all_blocks_bytes_sum ipfs_bitswap_want_blocks_total @@ -239,340 +128,170 @@ ipfs_bs_cache_arc_hits_total ipfs_bs_cache_arc_total ipfs_fsrepo_datastore_batchcommit_errors_total ipfs_fsrepo_datastore_batchcommit_latency_seconds_bucket -ipfs_fsrepo_datastore_batchcommit_latency_seconds_bucket -ipfs_fsrepo_datastore_batchcommit_latency_seconds_bucket -ipfs_fsrepo_datastore_batchcommit_latency_seconds_bucket -ipfs_fsrepo_datastore_batchcommit_latency_seconds_bucket -ipfs_fsrepo_datastore_batchcommit_latency_seconds_bucket ipfs_fsrepo_datastore_batchcommit_latency_seconds_count ipfs_fsrepo_datastore_batchcommit_latency_seconds_sum ipfs_fsrepo_datastore_batchcommit_total ipfs_fsrepo_datastore_batchdelete_errors_total ipfs_fsrepo_datastore_batchdelete_latency_seconds_bucket -ipfs_fsrepo_datastore_batchdelete_latency_seconds_bucket -ipfs_fsrepo_datastore_batchdelete_latency_seconds_bucket -ipfs_fsrepo_datastore_batchdelete_latency_seconds_bucket -ipfs_fsrepo_datastore_batchdelete_latency_seconds_bucket -ipfs_fsrepo_datastore_batchdelete_latency_seconds_bucket ipfs_fsrepo_datastore_batchdelete_latency_seconds_count ipfs_fsrepo_datastore_batchdelete_latency_seconds_sum ipfs_fsrepo_datastore_batchdelete_total ipfs_fsrepo_datastore_batchput_errors_total ipfs_fsrepo_datastore_batchput_latency_seconds_bucket -ipfs_fsrepo_datastore_batchput_latency_seconds_bucket -ipfs_fsrepo_datastore_batchput_latency_seconds_bucket -ipfs_fsrepo_datastore_batchput_latency_seconds_bucket -ipfs_fsrepo_datastore_batchput_latency_seconds_bucket -ipfs_fsrepo_datastore_batchput_latency_seconds_bucket ipfs_fsrepo_datastore_batchput_latency_seconds_count ipfs_fsrepo_datastore_batchput_latency_seconds_sum ipfs_fsrepo_datastore_batchput_size_bytes_bucket -ipfs_fsrepo_datastore_batchput_size_bytes_bucket -ipfs_fsrepo_datastore_batchput_size_bytes_bucket -ipfs_fsrepo_datastore_batchput_size_bytes_bucket -ipfs_fsrepo_datastore_batchput_size_bytes_bucket ipfs_fsrepo_datastore_batchput_size_bytes_count ipfs_fsrepo_datastore_batchput_size_bytes_sum ipfs_fsrepo_datastore_batchput_total ipfs_fsrepo_datastore_check_errors_total ipfs_fsrepo_datastore_check_latency_seconds_bucket -ipfs_fsrepo_datastore_check_latency_seconds_bucket -ipfs_fsrepo_datastore_check_latency_seconds_bucket -ipfs_fsrepo_datastore_check_latency_seconds_bucket -ipfs_fsrepo_datastore_check_latency_seconds_bucket -ipfs_fsrepo_datastore_check_latency_seconds_bucket ipfs_fsrepo_datastore_check_latency_seconds_count ipfs_fsrepo_datastore_check_latency_seconds_sum ipfs_fsrepo_datastore_check_total ipfs_fsrepo_datastore_delete_errors_total ipfs_fsrepo_datastore_delete_latency_seconds_bucket -ipfs_fsrepo_datastore_delete_latency_seconds_bucket -ipfs_fsrepo_datastore_delete_latency_seconds_bucket -ipfs_fsrepo_datastore_delete_latency_seconds_bucket -ipfs_fsrepo_datastore_delete_latency_seconds_bucket -ipfs_fsrepo_datastore_delete_latency_seconds_bucket ipfs_fsrepo_datastore_delete_latency_seconds_count ipfs_fsrepo_datastore_delete_latency_seconds_sum ipfs_fsrepo_datastore_delete_total ipfs_fsrepo_datastore_du_errors_total ipfs_fsrepo_datastore_du_latency_seconds_bucket -ipfs_fsrepo_datastore_du_latency_seconds_bucket -ipfs_fsrepo_datastore_du_latency_seconds_bucket -ipfs_fsrepo_datastore_du_latency_seconds_bucket -ipfs_fsrepo_datastore_du_latency_seconds_bucket -ipfs_fsrepo_datastore_du_latency_seconds_bucket ipfs_fsrepo_datastore_du_latency_seconds_count ipfs_fsrepo_datastore_du_latency_seconds_sum ipfs_fsrepo_datastore_du_total ipfs_fsrepo_datastore_gc_errors_total ipfs_fsrepo_datastore_gc_latency_seconds_bucket -ipfs_fsrepo_datastore_gc_latency_seconds_bucket -ipfs_fsrepo_datastore_gc_latency_seconds_bucket -ipfs_fsrepo_datastore_gc_latency_seconds_bucket -ipfs_fsrepo_datastore_gc_latency_seconds_bucket -ipfs_fsrepo_datastore_gc_latency_seconds_bucket ipfs_fsrepo_datastore_gc_latency_seconds_count ipfs_fsrepo_datastore_gc_latency_seconds_sum ipfs_fsrepo_datastore_gc_total ipfs_fsrepo_datastore_get_errors_total ipfs_fsrepo_datastore_get_latency_seconds_bucket -ipfs_fsrepo_datastore_get_latency_seconds_bucket -ipfs_fsrepo_datastore_get_latency_seconds_bucket -ipfs_fsrepo_datastore_get_latency_seconds_bucket -ipfs_fsrepo_datastore_get_latency_seconds_bucket -ipfs_fsrepo_datastore_get_latency_seconds_bucket ipfs_fsrepo_datastore_get_latency_seconds_count ipfs_fsrepo_datastore_get_latency_seconds_sum ipfs_fsrepo_datastore_get_size_bytes_bucket -ipfs_fsrepo_datastore_get_size_bytes_bucket -ipfs_fsrepo_datastore_get_size_bytes_bucket -ipfs_fsrepo_datastore_get_size_bytes_bucket -ipfs_fsrepo_datastore_get_size_bytes_bucket ipfs_fsrepo_datastore_get_size_bytes_count ipfs_fsrepo_datastore_get_size_bytes_sum ipfs_fsrepo_datastore_get_total ipfs_fsrepo_datastore_getsize_errors_total ipfs_fsrepo_datastore_getsize_latency_seconds_bucket -ipfs_fsrepo_datastore_getsize_latency_seconds_bucket -ipfs_fsrepo_datastore_getsize_latency_seconds_bucket -ipfs_fsrepo_datastore_getsize_latency_seconds_bucket -ipfs_fsrepo_datastore_getsize_latency_seconds_bucket -ipfs_fsrepo_datastore_getsize_latency_seconds_bucket ipfs_fsrepo_datastore_getsize_latency_seconds_count ipfs_fsrepo_datastore_getsize_latency_seconds_sum ipfs_fsrepo_datastore_getsize_total ipfs_fsrepo_datastore_has_errors_total ipfs_fsrepo_datastore_has_latency_seconds_bucket -ipfs_fsrepo_datastore_has_latency_seconds_bucket -ipfs_fsrepo_datastore_has_latency_seconds_bucket -ipfs_fsrepo_datastore_has_latency_seconds_bucket -ipfs_fsrepo_datastore_has_latency_seconds_bucket -ipfs_fsrepo_datastore_has_latency_seconds_bucket ipfs_fsrepo_datastore_has_latency_seconds_count ipfs_fsrepo_datastore_has_latency_seconds_sum ipfs_fsrepo_datastore_has_total ipfs_fsrepo_datastore_put_errors_total ipfs_fsrepo_datastore_put_latency_seconds_bucket -ipfs_fsrepo_datastore_put_latency_seconds_bucket -ipfs_fsrepo_datastore_put_latency_seconds_bucket -ipfs_fsrepo_datastore_put_latency_seconds_bucket -ipfs_fsrepo_datastore_put_latency_seconds_bucket -ipfs_fsrepo_datastore_put_latency_seconds_bucket ipfs_fsrepo_datastore_put_latency_seconds_count ipfs_fsrepo_datastore_put_latency_seconds_sum ipfs_fsrepo_datastore_put_size_bytes_bucket -ipfs_fsrepo_datastore_put_size_bytes_bucket -ipfs_fsrepo_datastore_put_size_bytes_bucket -ipfs_fsrepo_datastore_put_size_bytes_bucket -ipfs_fsrepo_datastore_put_size_bytes_bucket ipfs_fsrepo_datastore_put_size_bytes_count ipfs_fsrepo_datastore_put_size_bytes_sum ipfs_fsrepo_datastore_put_total ipfs_fsrepo_datastore_query_errors_total ipfs_fsrepo_datastore_query_latency_seconds_bucket -ipfs_fsrepo_datastore_query_latency_seconds_bucket -ipfs_fsrepo_datastore_query_latency_seconds_bucket -ipfs_fsrepo_datastore_query_latency_seconds_bucket -ipfs_fsrepo_datastore_query_latency_seconds_bucket -ipfs_fsrepo_datastore_query_latency_seconds_bucket ipfs_fsrepo_datastore_query_latency_seconds_count ipfs_fsrepo_datastore_query_latency_seconds_sum ipfs_fsrepo_datastore_query_total ipfs_fsrepo_datastore_scrub_errors_total ipfs_fsrepo_datastore_scrub_latency_seconds_bucket -ipfs_fsrepo_datastore_scrub_latency_seconds_bucket -ipfs_fsrepo_datastore_scrub_latency_seconds_bucket -ipfs_fsrepo_datastore_scrub_latency_seconds_bucket -ipfs_fsrepo_datastore_scrub_latency_seconds_bucket -ipfs_fsrepo_datastore_scrub_latency_seconds_bucket ipfs_fsrepo_datastore_scrub_latency_seconds_count ipfs_fsrepo_datastore_scrub_latency_seconds_sum ipfs_fsrepo_datastore_scrub_total ipfs_fsrepo_datastore_sync_errors_total ipfs_fsrepo_datastore_sync_latency_seconds_bucket -ipfs_fsrepo_datastore_sync_latency_seconds_bucket -ipfs_fsrepo_datastore_sync_latency_seconds_bucket -ipfs_fsrepo_datastore_sync_latency_seconds_bucket -ipfs_fsrepo_datastore_sync_latency_seconds_bucket -ipfs_fsrepo_datastore_sync_latency_seconds_bucket ipfs_fsrepo_datastore_sync_latency_seconds_count ipfs_fsrepo_datastore_sync_latency_seconds_sum ipfs_fsrepo_datastore_sync_total ipfs_http_request_duration_seconds -ipfs_http_request_duration_seconds -ipfs_http_request_duration_seconds ipfs_http_request_duration_seconds_count ipfs_http_request_duration_seconds_sum ipfs_http_request_size_bytes -ipfs_http_request_size_bytes -ipfs_http_request_size_bytes ipfs_http_request_size_bytes_count ipfs_http_request_size_bytes_sum ipfs_http_requests_total ipfs_http_response_size_bytes -ipfs_http_response_size_bytes -ipfs_http_response_size_bytes ipfs_http_response_size_bytes_count ipfs_http_response_size_bytes_sum ipfs_info leveldb_datastore_batchcommit_errors_total leveldb_datastore_batchcommit_latency_seconds_bucket -leveldb_datastore_batchcommit_latency_seconds_bucket -leveldb_datastore_batchcommit_latency_seconds_bucket -leveldb_datastore_batchcommit_latency_seconds_bucket -leveldb_datastore_batchcommit_latency_seconds_bucket -leveldb_datastore_batchcommit_latency_seconds_bucket leveldb_datastore_batchcommit_latency_seconds_count leveldb_datastore_batchcommit_latency_seconds_sum leveldb_datastore_batchcommit_total leveldb_datastore_batchdelete_errors_total leveldb_datastore_batchdelete_latency_seconds_bucket -leveldb_datastore_batchdelete_latency_seconds_bucket -leveldb_datastore_batchdelete_latency_seconds_bucket -leveldb_datastore_batchdelete_latency_seconds_bucket -leveldb_datastore_batchdelete_latency_seconds_bucket -leveldb_datastore_batchdelete_latency_seconds_bucket leveldb_datastore_batchdelete_latency_seconds_count leveldb_datastore_batchdelete_latency_seconds_sum leveldb_datastore_batchdelete_total leveldb_datastore_batchput_errors_total leveldb_datastore_batchput_latency_seconds_bucket -leveldb_datastore_batchput_latency_seconds_bucket -leveldb_datastore_batchput_latency_seconds_bucket -leveldb_datastore_batchput_latency_seconds_bucket -leveldb_datastore_batchput_latency_seconds_bucket -leveldb_datastore_batchput_latency_seconds_bucket leveldb_datastore_batchput_latency_seconds_count leveldb_datastore_batchput_latency_seconds_sum leveldb_datastore_batchput_size_bytes_bucket -leveldb_datastore_batchput_size_bytes_bucket -leveldb_datastore_batchput_size_bytes_bucket -leveldb_datastore_batchput_size_bytes_bucket -leveldb_datastore_batchput_size_bytes_bucket leveldb_datastore_batchput_size_bytes_count leveldb_datastore_batchput_size_bytes_sum leveldb_datastore_batchput_total leveldb_datastore_check_errors_total leveldb_datastore_check_latency_seconds_bucket -leveldb_datastore_check_latency_seconds_bucket -leveldb_datastore_check_latency_seconds_bucket -leveldb_datastore_check_latency_seconds_bucket -leveldb_datastore_check_latency_seconds_bucket -leveldb_datastore_check_latency_seconds_bucket leveldb_datastore_check_latency_seconds_count leveldb_datastore_check_latency_seconds_sum leveldb_datastore_check_total leveldb_datastore_delete_errors_total leveldb_datastore_delete_latency_seconds_bucket -leveldb_datastore_delete_latency_seconds_bucket -leveldb_datastore_delete_latency_seconds_bucket -leveldb_datastore_delete_latency_seconds_bucket -leveldb_datastore_delete_latency_seconds_bucket -leveldb_datastore_delete_latency_seconds_bucket leveldb_datastore_delete_latency_seconds_count leveldb_datastore_delete_latency_seconds_sum leveldb_datastore_delete_total leveldb_datastore_du_errors_total leveldb_datastore_du_latency_seconds_bucket -leveldb_datastore_du_latency_seconds_bucket -leveldb_datastore_du_latency_seconds_bucket -leveldb_datastore_du_latency_seconds_bucket -leveldb_datastore_du_latency_seconds_bucket -leveldb_datastore_du_latency_seconds_bucket leveldb_datastore_du_latency_seconds_count leveldb_datastore_du_latency_seconds_sum leveldb_datastore_du_total leveldb_datastore_gc_errors_total leveldb_datastore_gc_latency_seconds_bucket -leveldb_datastore_gc_latency_seconds_bucket -leveldb_datastore_gc_latency_seconds_bucket -leveldb_datastore_gc_latency_seconds_bucket -leveldb_datastore_gc_latency_seconds_bucket -leveldb_datastore_gc_latency_seconds_bucket leveldb_datastore_gc_latency_seconds_count leveldb_datastore_gc_latency_seconds_sum leveldb_datastore_gc_total leveldb_datastore_get_errors_total leveldb_datastore_get_latency_seconds_bucket -leveldb_datastore_get_latency_seconds_bucket -leveldb_datastore_get_latency_seconds_bucket -leveldb_datastore_get_latency_seconds_bucket -leveldb_datastore_get_latency_seconds_bucket -leveldb_datastore_get_latency_seconds_bucket leveldb_datastore_get_latency_seconds_count leveldb_datastore_get_latency_seconds_sum leveldb_datastore_get_size_bytes_bucket -leveldb_datastore_get_size_bytes_bucket -leveldb_datastore_get_size_bytes_bucket -leveldb_datastore_get_size_bytes_bucket -leveldb_datastore_get_size_bytes_bucket leveldb_datastore_get_size_bytes_count leveldb_datastore_get_size_bytes_sum leveldb_datastore_get_total leveldb_datastore_getsize_errors_total leveldb_datastore_getsize_latency_seconds_bucket -leveldb_datastore_getsize_latency_seconds_bucket -leveldb_datastore_getsize_latency_seconds_bucket -leveldb_datastore_getsize_latency_seconds_bucket -leveldb_datastore_getsize_latency_seconds_bucket -leveldb_datastore_getsize_latency_seconds_bucket leveldb_datastore_getsize_latency_seconds_count leveldb_datastore_getsize_latency_seconds_sum leveldb_datastore_getsize_total leveldb_datastore_has_errors_total leveldb_datastore_has_latency_seconds_bucket -leveldb_datastore_has_latency_seconds_bucket -leveldb_datastore_has_latency_seconds_bucket -leveldb_datastore_has_latency_seconds_bucket -leveldb_datastore_has_latency_seconds_bucket -leveldb_datastore_has_latency_seconds_bucket leveldb_datastore_has_latency_seconds_count leveldb_datastore_has_latency_seconds_sum leveldb_datastore_has_total leveldb_datastore_put_errors_total leveldb_datastore_put_latency_seconds_bucket -leveldb_datastore_put_latency_seconds_bucket -leveldb_datastore_put_latency_seconds_bucket -leveldb_datastore_put_latency_seconds_bucket -leveldb_datastore_put_latency_seconds_bucket -leveldb_datastore_put_latency_seconds_bucket leveldb_datastore_put_latency_seconds_count leveldb_datastore_put_latency_seconds_sum leveldb_datastore_put_size_bytes_bucket -leveldb_datastore_put_size_bytes_bucket -leveldb_datastore_put_size_bytes_bucket -leveldb_datastore_put_size_bytes_bucket -leveldb_datastore_put_size_bytes_bucket leveldb_datastore_put_size_bytes_count leveldb_datastore_put_size_bytes_sum leveldb_datastore_put_total leveldb_datastore_query_errors_total leveldb_datastore_query_latency_seconds_bucket -leveldb_datastore_query_latency_seconds_bucket -leveldb_datastore_query_latency_seconds_bucket -leveldb_datastore_query_latency_seconds_bucket -leveldb_datastore_query_latency_seconds_bucket -leveldb_datastore_query_latency_seconds_bucket leveldb_datastore_query_latency_seconds_count leveldb_datastore_query_latency_seconds_sum leveldb_datastore_query_total leveldb_datastore_scrub_errors_total leveldb_datastore_scrub_latency_seconds_bucket -leveldb_datastore_scrub_latency_seconds_bucket -leveldb_datastore_scrub_latency_seconds_bucket -leveldb_datastore_scrub_latency_seconds_bucket -leveldb_datastore_scrub_latency_seconds_bucket -leveldb_datastore_scrub_latency_seconds_bucket leveldb_datastore_scrub_latency_seconds_count leveldb_datastore_scrub_latency_seconds_sum leveldb_datastore_scrub_total leveldb_datastore_sync_errors_total leveldb_datastore_sync_latency_seconds_bucket -leveldb_datastore_sync_latency_seconds_bucket -leveldb_datastore_sync_latency_seconds_bucket -leveldb_datastore_sync_latency_seconds_bucket -leveldb_datastore_sync_latency_seconds_bucket -leveldb_datastore_sync_latency_seconds_bucket leveldb_datastore_sync_latency_seconds_count leveldb_datastore_sync_latency_seconds_sum leveldb_datastore_sync_total @@ -581,126 +300,28 @@ libp2p_autonat_reachability_status libp2p_autonat_reachability_status_confidence libp2p_autorelay_candidate_loop_state libp2p_autorelay_candidates_circuit_v2_support_total -libp2p_autorelay_candidates_circuit_v2_support_total libp2p_autorelay_desired_reservations libp2p_autorelay_relay_addresses_count libp2p_autorelay_relay_addresses_updated_total libp2p_autorelay_reservation_requests_outcome_total -libp2p_autorelay_reservation_requests_outcome_total libp2p_autorelay_reservations_closed_total libp2p_autorelay_reservations_opened_total libp2p_autorelay_status libp2p_eventbus_events_emitted_total -libp2p_eventbus_events_emitted_total -libp2p_eventbus_subscriber_event_queued -libp2p_eventbus_subscriber_event_queued libp2p_eventbus_subscriber_event_queued libp2p_eventbus_subscriber_queue_full -libp2p_eventbus_subscriber_queue_full -libp2p_eventbus_subscriber_queue_full libp2p_eventbus_subscriber_queue_length -libp2p_eventbus_subscriber_queue_length -libp2p_eventbus_subscriber_queue_length -libp2p_eventbus_subscribers_total -libp2p_eventbus_subscribers_total -libp2p_eventbus_subscribers_total -libp2p_eventbus_subscribers_total -libp2p_eventbus_subscribers_total libp2p_eventbus_subscribers_total libp2p_identify_addrs_count libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket -libp2p_identify_addrs_received_bucket libp2p_identify_addrs_received_count libp2p_identify_addrs_received_sum libp2p_identify_identify_pushes_triggered_total -libp2p_identify_identify_pushes_triggered_total libp2p_identify_protocols_count libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket -libp2p_identify_protocols_received_bucket libp2p_identify_protocols_received_count libp2p_identify_protocols_received_sum libp2p_relaysvc_connection_duration_seconds_bucket -libp2p_relaysvc_connection_duration_seconds_bucket -libp2p_relaysvc_connection_duration_seconds_bucket -libp2p_relaysvc_connection_duration_seconds_bucket -libp2p_relaysvc_connection_duration_seconds_bucket -libp2p_relaysvc_connection_duration_seconds_bucket -libp2p_relaysvc_connection_duration_seconds_bucket -libp2p_relaysvc_connection_duration_seconds_bucket -libp2p_relaysvc_connection_duration_seconds_bucket -libp2p_relaysvc_connection_duration_seconds_bucket -libp2p_relaysvc_connection_duration_seconds_bucket -libp2p_relaysvc_connection_duration_seconds_bucket libp2p_relaysvc_connection_duration_seconds_count libp2p_relaysvc_connection_duration_seconds_sum libp2p_relaysvc_data_transferred_bytes_total diff --git a/test/sharness/t0119-prometheus.sh b/test/sharness/t0119-prometheus.sh index 3387f4feb..0e00f088a 100755 --- a/test/sharness/t0119-prometheus.sh +++ b/test/sharness/t0119-prometheus.sh @@ -23,7 +23,7 @@ test_expect_success "collect metrics" ' test_kill_ipfs_daemon test_expect_success "filter metrics" ' - sed -ne "s/^\([a-z0-9_]\+\).*/\1/p" raw_metrics | LC_ALL=C sort > filtered_metrics + sed -ne "s/^\([a-z0-9_]\+\).*/\1/p" raw_metrics | LC_ALL=C sort | uniq > filtered_metrics ' test_expect_success "make sure metrics haven't changed" ' @@ -50,7 +50,7 @@ test_kill_ipfs_daemon test_expect_success "filter metrics and find ones added by enabling ResourceMgr" ' sed -ne "s/^\([a-z0-9_]\+\).*/\1/p" raw_metrics | LC_ALL=C sort > filtered_metrics && - grep -v -x -f ../t0119-prometheus-data/prometheus_metrics filtered_metrics > rcmgr_metrics + grep -v -x -f ../t0119-prometheus-data/prometheus_metrics filtered_metrics | LC_ALL=C sort | uniq > rcmgr_metrics ' test_expect_success "make sure initial metrics added by setting ResourceMgr.Enabled haven't changed" ' From df5c0620ec00a4ecf0955fe61a0a73e29b3c5b8b Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Wed, 14 Jun 2023 00:37:03 +0200 Subject: [PATCH 0725/1212] =?UTF-8?q?chore(docs):=20typo=20http=E2=86=92ht?= =?UTF-8?q?tps?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/changelogs/v0.21.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/changelogs/v0.21.md b/docs/changelogs/v0.21.md index 034201748..1ac92adb7 100644 --- a/docs/changelogs/v0.21.md +++ b/docs/changelogs/v0.21.md @@ -99,7 +99,7 @@ for clients that do not follow redirects by default: ```console $ curl "https://subdomain-gw.example.net/ipfs/${cid}/" -Moved Permanently. +Moved Permanently. ``` Rationale can be found in [kubo#9913](https://github.com/ipfs/kubo/pull/9913). From c4959145290ef673f22727552dfe0d789120d5a8 Mon Sep 17 00:00:00 2001 From: Russell Dempsey <1173416+SgtPooki@users.noreply.github.com> Date: Wed, 14 Jun 2023 01:12:41 -0700 Subject: [PATCH 0726/1212] feat: webui@4.0.1 (#9940) --- .github/workflows/build.yml | 2 +- core/corehttp/webui.go | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d3dce10a0..3caee6bac 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -145,7 +145,7 @@ jobs: steps: - uses: actions/setup-node@v3 with: - node-version: 16.12.0 + node-version: 18.14.0 - uses: actions/download-artifact@v3 with: name: kubo diff --git a/core/corehttp/webui.go b/core/corehttp/webui.go index 9b7cf776d..e5abd3922 100644 --- a/core/corehttp/webui.go +++ b/core/corehttp/webui.go @@ -1,11 +1,12 @@ package corehttp // TODO: move to IPNS -const WebUIPath = "/ipfs/bafybeic4gops3d3lyrisqku37uio33nvt6fqxvkxihrwlqsuvf76yln4fm" // v3.0.0 +const WebUIPath = "/ipfs/bafybeigs6d53gpgu34553mbi5bbkb26e4ikruoaaar75jpfdywpup2r3my" // v4.0.1 // WebUIPaths is a list of all past webUI paths. var WebUIPaths = []string{ WebUIPath, + "/ipfs/bafybeic4gops3d3lyrisqku37uio33nvt6fqxvkxihrwlqsuvf76yln4fm", "/ipfs/bafybeifeqt7mvxaniphyu2i3qhovjaf3sayooxbh5enfdqtiehxjv2ldte", "/ipfs/bafybeiequgo72mrvuml56j4gk7crewig5bavumrrzhkqbim6b3s2yqi7ty", "/ipfs/bafybeibjbq3tmmy7wuihhhwvbladjsd3gx3kfjepxzkq6wylik6wc3whzy", From 75a315a2620002f84765efead4dbe2683cbd499f Mon Sep 17 00:00:00 2001 From: GitHub Date: Wed, 14 Jun 2023 11:14:35 +0000 Subject: [PATCH 0727/1212] chore: Update .github/workflows/stale.yml [skip ci] --- .github/workflows/stale.yml | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 6f6d895d1..668bd07d4 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -6,21 +6,4 @@ on: jobs: stale: - - runs-on: ubuntu-latest - permissions: - issues: write - pull-requests: write - - steps: - - uses: actions/stale@v3 - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - stale-issue-message: 'Oops, seems like we needed more information for this issue, please comment with more details or this issue will be closed in 7 days.' - close-issue-message: 'This issue was closed because it is missing author input.' - stale-issue-label: 'kind/stale' - any-of-labels: 'need/author-input' - exempt-issue-labels: 'need/triage,need/community-input,need/maintainer-input,need/maintainers-input,need/analysis,status/blocked,status/in-progress,status/ready,status/deferred,status/inactive' - days-before-issue-stale: 6 - days-before-issue-close: 7 - enable-statistics: true + uses: pl-strflt/.github/.github/workflows/reusable-stale-issue.yml@v0.3 From 859e8d3ba5e44fdeb4f7ce5faaee92adb377441b Mon Sep 17 00:00:00 2001 From: "ipfs-mgmt-read-write[bot]" <104492829+ipfs-mgmt-read-write[bot]@users.noreply.github.com> Date: Wed, 14 Jun 2023 13:05:45 +0000 Subject: [PATCH 0728/1212] chore: label dependabot PRs --- .github/dependabot.yml | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 14f776456..6ff8dba1f 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,10 +1,14 @@ version: 2 updates: -- package-ecosystem: gomod - directory: "/" - schedule: - interval: daily - time: "11:00" - open-pull-requests-limit: 10 - labels: - - "topic/dependencies" + - package-ecosystem: gomod + directory: "/" + schedule: + interval: daily + time: "11:00" + open-pull-requests-limit: 10 + labels: + - "topic/dependencies" + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" From 0e52389016de1299d7a83b7d4d32289004690074 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Wed, 14 Jun 2023 20:55:31 +0200 Subject: [PATCH 0729/1212] fix(cmd): useful errors in dag import (#9945) * fix: useful errors during dag import Most of the time the error is either a bitflip in one of blocks, or a truncation of car stream. This allows user to understand what happened and at which place in the car stream, making debug more humane. * fix: correct message when root pin failed this also correctly exits CLI commands with code 1 (was silent false-positive 0 before) --- core/commands/dag/dag.go | 2 +- core/commands/dag/import.go | 25 +++++++++++++++++++++---- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/core/commands/dag/dag.go b/core/commands/dag/dag.go index 7d21eb071..41fde70e5 100644 --- a/core/commands/dag/dag.go +++ b/core/commands/dag/dag.go @@ -237,7 +237,7 @@ Specification of CAR formats: https://ipld.io/specs/transport/car/ } if event.Root.PinErrorMsg != "" { - event.Root.PinErrorMsg = fmt.Sprintf("FAILED: %s", event.Root.PinErrorMsg) + return fmt.Errorf("pinning root %q FAILED: %s", enc.Encode(event.Root.Cid), event.Root.PinErrorMsg) } else { event.Root.PinErrorMsg = "success" } diff --git a/core/commands/dag/import.go b/core/commands/dag/import.go index 20f947bc2..36f4176d5 100644 --- a/core/commands/dag/import.go +++ b/core/commands/dag/import.go @@ -2,11 +2,13 @@ package dagcmd import ( "errors" + "fmt" "io" "github.com/ipfs/boxo/coreiface/options" "github.com/ipfs/boxo/files" gocarv2 "github.com/ipfs/boxo/ipld/car/v2" + blocks "github.com/ipfs/go-block-format" cid "github.com/ipfs/go-cid" cmds "github.com/ipfs/go-ipfs-cmds" ipld "github.com/ipfs/go-ipld-format" @@ -58,6 +60,18 @@ func dagImport(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment roots := cid.NewSet() var blockCount, blockBytesCount uint64 + // remember last valid block and provide a meaningful error message + // when a truncated/mangled CAR is being imported + importError := func(previous blocks.Block, current blocks.Block, err error) error { + if current != nil { + return fmt.Errorf("import failed at block %q: %w", current.Cid(), err) + } + if previous != nil { + return fmt.Errorf("import failed after block %q: %w", previous.Cid(), err) + } + return fmt.Errorf("import failed: %w", err) + } + it := req.Files.Entries() for it.Next() { file := files.FileFromEntry(it) @@ -75,6 +89,8 @@ func dagImport(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment // this won't/can't help with not running out of handles defer file.Close() + var previous blocks.Block + car, err := gocarv2.NewBlockReader(file) if err != nil { return err @@ -87,25 +103,26 @@ func dagImport(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment for { block, err := car.Next() if err != nil && err != io.EOF { - return err + return importError(previous, block, err) } else if block == nil { break } if err := cmdutils.CheckBlockSize(req, uint64(len(block.RawData()))); err != nil { - return err + return importError(previous, block, err) } // the double-decode is suboptimal, but we need it for batching nd, err := blockDecoder.DecodeNode(req.Context, block) if err != nil { - return err + return importError(previous, block, err) } if err := batch.Add(req.Context, nd); err != nil { - return err + return importError(previous, block, err) } blockCount++ blockBytesCount += uint64(len(block.RawData())) + previous = block } return nil }() From 5b2bc580844aea8b3d948a6813dd7df3c75d2890 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Thu, 15 Jun 2023 12:43:48 +0200 Subject: [PATCH 0730/1212] chore: update dht and libp2p for identify stream block Streams used to be blocked on ping IO because we didn't handled the DHT ping check asynchronously. Include fixes from libp2p/go-libp2p-kad-dht#851 Fixes #9957 --- docs/examples/kubo-as-a-library/go.mod | 34 ++++++------ docs/examples/kubo-as-a-library/go.sum | 69 ++++++++++++------------ go.mod | 36 ++++++------- go.sum | 73 +++++++++++++------------- test/dependencies/go.mod | 32 +++++------ test/dependencies/go.sum | 65 ++++++++++++----------- 6 files changed, 156 insertions(+), 153 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index cda83aeb4..bfbe48843 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -9,7 +9,7 @@ replace github.com/ipfs/kubo => ./../../.. require ( github.com/ipfs/boxo v0.10.0 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 - github.com/libp2p/go-libp2p v0.27.5 + github.com/libp2p/go-libp2p v0.27.6 github.com/multiformats/go-multiaddr v0.9.0 ) @@ -18,7 +18,7 @@ require ( github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 // indirect github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5 // indirect - github.com/benbjohnson/clock v1.3.0 // indirect + github.com/benbjohnson/clock v1.3.5 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver/v4 v4.0.0 // indirect github.com/cenkalti/backoff/v4 v4.2.1 // indirect @@ -49,7 +49,7 @@ require ( github.com/golang/protobuf v1.5.3 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/gopacket v1.1.19 // indirect - github.com/google/pprof v0.0.0-20230405160723-4a4c7d95572b // indirect + github.com/google/pprof v0.0.0-20230602150820-91b7bce49751 // indirect github.com/google/uuid v1.3.0 // indirect github.com/gorilla/mux v1.8.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 // indirect @@ -58,7 +58,7 @@ require ( github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/golang-lru v0.5.4 // indirect github.com/hashicorp/golang-lru/v2 v2.0.2 // indirect - github.com/huin/goupnp v1.1.0 // indirect + github.com/huin/goupnp v1.2.0 // indirect github.com/ipfs/bbloom v0.0.4 // indirect github.com/ipfs/go-bitfield v1.1.0 // indirect github.com/ipfs/go-block-format v0.1.2 // indirect @@ -94,7 +94,7 @@ require ( github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect github.com/jbenet/goprocess v0.1.4 // indirect - github.com/klauspost/compress v1.16.4 // indirect + github.com/klauspost/compress v1.16.5 // indirect github.com/klauspost/cpuid/v2 v2.2.5 // indirect github.com/koron/go-ssdp v0.0.4 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect @@ -102,8 +102,8 @@ require ( github.com/libp2p/go-doh-resolver v0.4.0 // indirect github.com/libp2p/go-flow-metrics v0.1.0 // indirect github.com/libp2p/go-libp2p-asn-util v0.3.0 // indirect - github.com/libp2p/go-libp2p-kad-dht v0.24.0 // indirect - github.com/libp2p/go-libp2p-kbucket v0.6.1 // indirect + github.com/libp2p/go-libp2p-kad-dht v0.24.1 // indirect + github.com/libp2p/go-libp2p-kbucket v0.6.3 // indirect github.com/libp2p/go-libp2p-pubsub v0.9.3 // indirect github.com/libp2p/go-libp2p-pubsub-router v0.6.0 // indirect github.com/libp2p/go-libp2p-record v0.2.0 // indirect @@ -113,13 +113,13 @@ require ( github.com/libp2p/go-msgio v0.3.0 // indirect github.com/libp2p/go-nat v0.1.0 // indirect github.com/libp2p/go-netroute v0.2.1 // indirect - github.com/libp2p/go-reuseport v0.2.0 // indirect + github.com/libp2p/go-reuseport v0.3.0 // indirect github.com/libp2p/go-yamux/v4 v4.0.0 // indirect github.com/libp2p/zeroconf/v2 v2.2.0 // indirect github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect github.com/mattn/go-isatty v0.0.19 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect - github.com/miekg/dns v1.1.53 // indirect + github.com/miekg/dns v1.1.54 // indirect github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect github.com/minio/sha256-simd v1.0.1 // indirect @@ -134,7 +134,7 @@ require ( github.com/multiformats/go-multihash v0.2.3 // indirect github.com/multiformats/go-multistream v0.4.1 // indirect github.com/multiformats/go-varint v0.0.7 // indirect - github.com/onsi/ginkgo/v2 v2.9.2 // indirect + github.com/onsi/ginkgo/v2 v2.9.7 // indirect github.com/opencontainers/runtime-spec v1.0.2 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/openzipkin/zipkin-go v0.4.1 // indirect @@ -143,14 +143,14 @@ require ( github.com/pkg/errors v0.9.1 // indirect github.com/polydawn/refmt v0.89.0 // indirect github.com/prometheus/client_golang v1.14.0 // indirect - github.com/prometheus/client_model v0.3.0 // indirect + github.com/prometheus/client_model v0.4.0 // indirect github.com/prometheus/common v0.42.0 // indirect github.com/prometheus/procfs v0.9.0 // indirect github.com/quic-go/qpack v0.4.0 // indirect github.com/quic-go/qtls-go1-19 v0.3.2 // indirect github.com/quic-go/qtls-go1-20 v0.2.2 // indirect github.com/quic-go/quic-go v0.33.0 // indirect - github.com/quic-go/webtransport-go v0.5.2 // indirect + github.com/quic-go/webtransport-go v0.5.3 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/samber/lo v1.36.0 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect @@ -181,14 +181,14 @@ require ( go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.24.0 // indirect go4.org v0.0.0-20230225012048-214862532bf5 // indirect - golang.org/x/crypto v0.9.0 // indirect + golang.org/x/crypto v0.10.0 // indirect golang.org/x/exp v0.0.0-20230321023759-10a507213a29 // indirect golang.org/x/mod v0.10.0 // indirect golang.org/x/net v0.10.0 // indirect - golang.org/x/sync v0.1.0 // indirect - golang.org/x/sys v0.8.0 // indirect - golang.org/x/text v0.9.0 // indirect - golang.org/x/tools v0.7.0 // indirect + golang.org/x/sync v0.2.0 // indirect + golang.org/x/sys v0.9.0 // indirect + golang.org/x/text v0.10.0 // indirect + golang.org/x/tools v0.9.1 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect gonum.org/v1/gonum v0.13.0 // indirect google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 922906c35..d2ff0d772 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -56,8 +56,9 @@ github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYU github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= -github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o= +github.com/benbjohnson/clock v1.3.5/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= @@ -272,8 +273,8 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20230405160723-4a4c7d95572b h1:Qcx5LM0fSiks9uCyFZwDBUasd3lxd1RM0GYpL+Li5o4= -github.com/google/pprof v0.0.0-20230405160723-4a4c7d95572b/go.mod h1:79YE0hCXdHag9sBkw2o+N/YnZtTkXi0UT9Nnixa5eYk= +github.com/google/pprof v0.0.0-20230602150820-91b7bce49751 h1:hR7/MlvK23p6+lIw9SN1TigNLn9ZnF3W4SYRKq2gAHs= +github.com/google/pprof v0.0.0-20230602150820-91b7bce49751/go.mod h1:Jh3hGz2jkYak8qXPD19ryItVnUgpgeqzdkY/D0EaeuA= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -312,8 +313,8 @@ github.com/hashicorp/golang-lru/v2 v2.0.2/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyf github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= -github.com/huin/goupnp v1.1.0 h1:gEe0Dp/lZmPZiDFzJJaOfUpOvv2MKUkoBX8lDrn9vKU= -github.com/huin/goupnp v1.1.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= +github.com/huin/goupnp v1.2.0 h1:uOKW26NG1hsSSbXIZ1IR7XP9Gjd1U8pnLaCMgntmkmY= +github.com/huin/goupnp v1.2.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= @@ -452,8 +453,8 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI 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.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/klauspost/compress v1.16.4 h1:91KN02FnsOYhuunwU4ssRe8lc2JosWmizWa91B5v1PU= -github.com/klauspost/compress v1.16.4/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/compress v1.16.5 h1:IFV2oUNUzZaz+XyusxpLzpzS8Pt5rh0Z16For/djlyI= +github.com/klauspost/compress v1.16.5/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= @@ -486,17 +487,17 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.27.5 h1:KwA7pXKXpz8hG6Cr1fMA7UkgleogcwQj0sxl5qquWRg= -github.com/libp2p/go-libp2p v0.27.5/go.mod h1:oMfQGTb9CHnrOuSM6yMmyK2lXz3qIhnkn2+oK3B1Y2g= +github.com/libp2p/go-libp2p v0.27.6 h1:KmGU5kskCaaerm53heqzfGOlrW2z8icZ+fnyqgrZs38= +github.com/libp2p/go-libp2p v0.27.6/go.mod h1:oMfQGTb9CHnrOuSM6yMmyK2lXz3qIhnkn2+oK3B1Y2g= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= github.com/libp2p/go-libp2p-core v0.3.0/go.mod h1:ACp3DmS3/N64c2jDzcV429ukDpicbL6+TrrxANBjPGw= -github.com/libp2p/go-libp2p-kad-dht v0.24.0 h1:nZnFDQEFU4N8GzclnR+IGxIgR7k4PPCDk/GK9A28onk= -github.com/libp2p/go-libp2p-kad-dht v0.24.0/go.mod h1:lfu5T01EH+r6uDZ/8G+ObhwgzVyd0b1nb54AdT8XGhc= +github.com/libp2p/go-libp2p-kad-dht v0.24.1 h1:XH9vIWqc6e+w6z2Nvt9R5EhkBNnOQl7tyxxM6soejwo= +github.com/libp2p/go-libp2p-kad-dht v0.24.1/go.mod h1:1meiUvgOxfSPBx1pracS4VyYwmusorvv+TVRI3mXaJI= github.com/libp2p/go-libp2p-kbucket v0.3.1/go.mod h1:oyjT5O7tS9CQurok++ERgc46YLwEpuGoFq9ubvoUOio= -github.com/libp2p/go-libp2p-kbucket v0.6.1 h1:Y/NIvALuY5/fJlOpaJor9Azg4eor15JskGs9Lb2EhH0= -github.com/libp2p/go-libp2p-kbucket v0.6.1/go.mod h1:dvWO707Oq/vhMVuUhyfLkw0QsOrJFETepbNfpVHSELI= +github.com/libp2p/go-libp2p-kbucket v0.6.3 h1:p507271wWzpy2f1XxPzCQG9NiN6R6lHL9GiSErbQQo0= +github.com/libp2p/go-libp2p-kbucket v0.6.3/go.mod h1:RCseT7AH6eJWxxk2ol03xtP9pEHetYSPXOaJnOiD8i0= github.com/libp2p/go-libp2p-peerstore v0.1.4/go.mod h1:+4BDbDiiKf4PzpANZDAT+knVdLxvqh7hXOujessqdzs= github.com/libp2p/go-libp2p-pubsub v0.9.3 h1:ihcz9oIBMaCK9kcx+yHWm3mLAFBMAUsM4ux42aikDxo= github.com/libp2p/go-libp2p-pubsub v0.9.3/go.mod h1:RYA7aM9jIic5VV47WXu4GkcRxRhrdElWf8xtyli+Dzc= @@ -521,8 +522,8 @@ github.com/libp2p/go-netroute v0.2.1 h1:V8kVrpD8GK0Riv15/7VN6RbUQ3URNZVosw7H2v9t github.com/libp2p/go-netroute v0.2.1/go.mod h1:hraioZr0fhBjG0ZRXJJ6Zj2IVEVNx6tDTFQfSmcq7mQ= 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= -github.com/libp2p/go-reuseport v0.2.0 h1:18PRvIMlpY6ZK85nIAicSBuXXvrYoSw3dsBAR7zc560= -github.com/libp2p/go-reuseport v0.2.0/go.mod h1:bvVho6eLMm6Bz5hmU0LYN3ixd3nPPvtIlaURZZgOY4k= +github.com/libp2p/go-reuseport v0.3.0 h1:iiZslO5byUYZEg9iCwJGf5h+sf1Agmqx2V2FDjPyvUw= +github.com/libp2p/go-reuseport v0.3.0/go.mod h1:laea40AimhtfEqysZ71UpYj4S+R9VpH8PgqLo7L+SwI= github.com/libp2p/go-sockaddr v0.0.2/go.mod h1:syPvOmNs24S3dFVGJA1/mrqdeijPxLV2Le3BRLKd68k= github.com/libp2p/go-yamux/v4 v4.0.0 h1:+Y80dV2Yx/kv7Y7JKu0LECyVdMXm1VUoko+VQ9rBfZQ= github.com/libp2p/go-yamux/v4 v4.0.0/go.mod h1:NWjl8ZTLOGlozrXSOZ/HlfG++39iKNnM5wwmtQP1YB4= @@ -550,8 +551,8 @@ github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyex github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= -github.com/miekg/dns v1.1.53 h1:ZBkuHr5dxHtB1caEOlZTLPo7D3L3TWckgUUs/RHfDxw= -github.com/miekg/dns v1.1.53/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= +github.com/miekg/dns v1.1.54 h1:5jon9mWcb0sFJGpnI99tOMhCPyJ+RPVz5b63MQG0VWI= +github.com/miekg/dns v1.1.54/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c h1:bzE/A84HN25pxAuk9Eej1Kz9OUelF97nAc82bDquQI8= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c/go.mod h1:0SQS9kMwD2VsyFEB++InYyBJroV/FRmBgcydeSUcJms= github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= @@ -628,12 +629,12 @@ github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= -github.com/onsi/ginkgo/v2 v2.9.2 h1:BA2GMJOtfGAfagzYtrAlufIP0lq6QERkFmHLMLPwFSU= -github.com/onsi/ginkgo/v2 v2.9.2/go.mod h1:WHcJJG2dIlcCqVfBAwUCrJxSPFb6v4azBwgxeMeDuts= +github.com/onsi/ginkgo/v2 v2.9.7 h1:06xGQy5www2oN160RtEZoTvnP2sPhEfePYmCDc2szss= +github.com/onsi/ginkgo/v2 v2.9.7/go.mod h1:cxrmXWykAwTwhQsJOPfdIDiJ+l2RYq7U8hFU+M/1uw0= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.27.4 h1:Z2AnStgsdSayCMDiCU42qIz+HLqEPcgiOCXjAU/w+8E= +github.com/onsi/gomega v1.27.7 h1:fVih9JD6ogIiHUN6ePK7HJidyEDpWGVB5mzM7cWNXoU= github.com/opencontainers/runtime-spec v1.0.2 h1:UfAcuLBJB9Coz72x1hgl8O5RVzTdNiaglX6v2DM6FI0= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= @@ -662,8 +663,8 @@ github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= -github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= +github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY= +github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM= github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= @@ -678,8 +679,8 @@ github.com/quic-go/qtls-go1-20 v0.2.2 h1:WLOPx6OY/hxtTxKV1Zrq20FtXtDEkeY00CGQm8G github.com/quic-go/qtls-go1-20 v0.2.2/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= github.com/quic-go/quic-go v0.33.0 h1:ItNoTDN/Fm/zBlq769lLJc8ECe9gYaW40veHCCco7y0= github.com/quic-go/quic-go v0.33.0/go.mod h1:YMuhaAV9/jIu0XclDXwZPAsP/2Kgr5yMYhe9oxhhOFA= -github.com/quic-go/webtransport-go v0.5.2 h1:GA6Bl6oZY+g/flt00Pnu0XtivSD8vukOu3lYhJjnGEk= -github.com/quic-go/webtransport-go v0.5.2/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= +github.com/quic-go/webtransport-go v0.5.3 h1:5XMlzemqB4qmOlgIus5zB45AcZ2kCgCy2EptUrfOPWU= +github.com/quic-go/webtransport-go v0.5.3/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= @@ -880,8 +881,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g= -golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= +golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM= +golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -984,8 +985,8 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI= +golang.org/x/sync v0.2.0/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-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1046,8 +1047,8 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s= +golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -1061,8 +1062,8 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58= +golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1120,8 +1121,8 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4= -golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= +golang.org/x/tools v0.9.1 h1:8WMNJAz3zrtPmnYC7ISf5dEn3MT0gY7jBJfw27yrrLo= +golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/go.mod b/go.mod index bd0296e80..aedd07bc9 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/ipfs/kubo require ( bazil.org/fuse v0.0.0-20200117225306-7b5117fecadc contrib.go.opencensus.io/exporter/prometheus v0.4.2 - github.com/benbjohnson/clock v1.3.0 + github.com/benbjohnson/clock v1.3.5 github.com/blang/semver/v4 v4.0.0 github.com/cenkalti/backoff/v4 v4.2.1 github.com/ceramicnetwork/go-dag-jose v0.1.0 @@ -45,10 +45,10 @@ require ( github.com/jbenet/goprocess v0.1.4 github.com/julienschmidt/httprouter v1.3.0 github.com/libp2p/go-doh-resolver v0.4.0 - github.com/libp2p/go-libp2p v0.27.5 + github.com/libp2p/go-libp2p v0.27.6 github.com/libp2p/go-libp2p-http v0.5.0 - github.com/libp2p/go-libp2p-kad-dht v0.24.0 - github.com/libp2p/go-libp2p-kbucket v0.6.1 + github.com/libp2p/go-libp2p-kad-dht v0.24.1 + github.com/libp2p/go-libp2p-kbucket v0.6.3 github.com/libp2p/go-libp2p-pubsub v0.9.3 github.com/libp2p/go-libp2p-pubsub-router v0.6.0 github.com/libp2p/go-libp2p-record v0.2.0 @@ -81,11 +81,11 @@ require ( go.uber.org/fx v1.19.3 go.uber.org/multierr v1.11.0 go.uber.org/zap v1.24.0 - golang.org/x/crypto v0.9.0 + golang.org/x/crypto v0.10.0 golang.org/x/exp v0.0.0-20230321023759-10a507213a29 golang.org/x/mod v0.10.0 - golang.org/x/sync v0.1.0 - golang.org/x/sys v0.8.0 + golang.org/x/sync v0.2.0 + golang.org/x/sys v0.9.0 ) require ( @@ -121,14 +121,14 @@ require ( github.com/golang/protobuf v1.5.3 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/gopacket v1.1.19 // indirect - github.com/google/pprof v0.0.0-20230405160723-4a4c7d95572b // indirect + github.com/google/pprof v0.0.0-20230602150820-91b7bce49751 // indirect github.com/gorilla/mux v1.8.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 // indirect github.com/hannahhoward/go-pubsub v0.0.0-20200423002714-8d62886cc36e // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/golang-lru v0.5.4 // indirect github.com/hashicorp/golang-lru/v2 v2.0.2 // indirect - github.com/huin/goupnp v1.1.0 // indirect + github.com/huin/goupnp v1.2.0 // indirect github.com/ipfs/bbloom v0.0.4 // indirect github.com/ipfs/go-bitfield v1.1.0 // indirect github.com/ipfs/go-ipfs-blockstore v1.3.0 // indirect @@ -142,7 +142,7 @@ require ( github.com/ipfs/go-peertaskqueue v0.8.1 // indirect github.com/ipld/edelweiss v0.2.0 // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect - github.com/klauspost/compress v1.16.4 // indirect + github.com/klauspost/compress v1.16.5 // indirect github.com/klauspost/cpuid/v2 v2.2.5 // indirect github.com/koron/go-ssdp v0.0.4 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect @@ -155,7 +155,7 @@ require ( github.com/libp2p/go-msgio v0.3.0 // indirect github.com/libp2p/go-nat v0.1.0 // indirect github.com/libp2p/go-netroute v0.2.1 // indirect - github.com/libp2p/go-reuseport v0.2.0 // indirect + github.com/libp2p/go-reuseport v0.3.0 // indirect github.com/libp2p/go-yamux/v4 v4.0.0 // indirect github.com/libp2p/zeroconf/v2 v2.2.0 // indirect github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect @@ -164,7 +164,7 @@ require ( github.com/mattn/go-runewidth v0.0.4 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect - github.com/miekg/dns v1.1.53 // indirect + github.com/miekg/dns v1.1.54 // indirect github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect github.com/minio/sha256-simd v1.0.1 // indirect @@ -174,13 +174,13 @@ require ( github.com/multiformats/go-multiaddr-fmt v0.1.0 // indirect github.com/multiformats/go-multistream v0.4.1 // indirect github.com/multiformats/go-varint v0.0.7 // indirect - github.com/onsi/ginkgo/v2 v2.9.2 // indirect + github.com/onsi/ginkgo/v2 v2.9.7 // indirect github.com/opencontainers/runtime-spec v1.0.2 // indirect github.com/openzipkin/zipkin-go v0.4.1 // indirect github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/polydawn/refmt v0.89.0 // indirect - github.com/prometheus/client_model v0.3.0 // indirect + github.com/prometheus/client_model v0.4.0 // indirect github.com/prometheus/common v0.42.0 // indirect github.com/prometheus/procfs v0.9.0 // indirect github.com/prometheus/statsd_exporter v0.22.7 // indirect @@ -188,7 +188,7 @@ require ( github.com/quic-go/qtls-go1-19 v0.3.2 // indirect github.com/quic-go/qtls-go1-20 v0.2.2 // indirect github.com/quic-go/quic-go v0.33.0 // indirect - github.com/quic-go/webtransport-go v0.5.2 // indirect + github.com/quic-go/webtransport-go v0.5.3 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/rs/cors v1.7.0 // indirect github.com/samber/lo v1.36.0 // indirect @@ -219,9 +219,9 @@ require ( go4.org v0.0.0-20230225012048-214862532bf5 // indirect golang.org/x/net v0.10.0 // indirect golang.org/x/oauth2 v0.6.0 // indirect - golang.org/x/term v0.8.0 // indirect - golang.org/x/text v0.9.0 // indirect - golang.org/x/tools v0.7.0 // indirect + golang.org/x/term v0.9.0 // indirect + golang.org/x/text v0.10.0 // indirect + golang.org/x/tools v0.9.1 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect gonum.org/v1/gonum v0.13.0 // indirect google.golang.org/appengine v1.6.7 // indirect diff --git a/go.sum b/go.sum index fa503f351..a044a459b 100644 --- a/go.sum +++ b/go.sum @@ -65,8 +65,9 @@ github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYU github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= -github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o= +github.com/benbjohnson/clock v1.3.5/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -307,8 +308,8 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20230405160723-4a4c7d95572b h1:Qcx5LM0fSiks9uCyFZwDBUasd3lxd1RM0GYpL+Li5o4= -github.com/google/pprof v0.0.0-20230405160723-4a4c7d95572b/go.mod h1:79YE0hCXdHag9sBkw2o+N/YnZtTkXi0UT9Nnixa5eYk= +github.com/google/pprof v0.0.0-20230602150820-91b7bce49751 h1:hR7/MlvK23p6+lIw9SN1TigNLn9ZnF3W4SYRKq2gAHs= +github.com/google/pprof v0.0.0-20230602150820-91b7bce49751/go.mod h1:Jh3hGz2jkYak8qXPD19ryItVnUgpgeqzdkY/D0EaeuA= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -347,8 +348,8 @@ github.com/hashicorp/golang-lru/v2 v2.0.2/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyf github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= -github.com/huin/goupnp v1.1.0 h1:gEe0Dp/lZmPZiDFzJJaOfUpOvv2MKUkoBX8lDrn9vKU= -github.com/huin/goupnp v1.1.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= +github.com/huin/goupnp v1.2.0 h1:uOKW26NG1hsSSbXIZ1IR7XP9Gjd1U8pnLaCMgntmkmY= +github.com/huin/goupnp v1.2.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= @@ -500,8 +501,8 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI 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.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/klauspost/compress v1.16.4 h1:91KN02FnsOYhuunwU4ssRe8lc2JosWmizWa91B5v1PU= -github.com/klauspost/compress v1.16.4/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/compress v1.16.5 h1:IFV2oUNUzZaz+XyusxpLzpzS8Pt5rh0Z16For/djlyI= +github.com/klauspost/compress v1.16.5/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= @@ -536,8 +537,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.27.5 h1:KwA7pXKXpz8hG6Cr1fMA7UkgleogcwQj0sxl5qquWRg= -github.com/libp2p/go-libp2p v0.27.5/go.mod h1:oMfQGTb9CHnrOuSM6yMmyK2lXz3qIhnkn2+oK3B1Y2g= +github.com/libp2p/go-libp2p v0.27.6 h1:KmGU5kskCaaerm53heqzfGOlrW2z8icZ+fnyqgrZs38= +github.com/libp2p/go-libp2p v0.27.6/go.mod h1:oMfQGTb9CHnrOuSM6yMmyK2lXz3qIhnkn2+oK3B1Y2g= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= @@ -546,11 +547,11 @@ github.com/libp2p/go-libp2p-gostream v0.6.0 h1:QfAiWeQRce6pqnYfmIVWJFXNdDyfiR/qk github.com/libp2p/go-libp2p-gostream v0.6.0/go.mod h1:Nywu0gYZwfj7Jc91PQvbGU8dIpqbQQkjWgDuOrFaRdA= github.com/libp2p/go-libp2p-http v0.5.0 h1:+x0AbLaUuLBArHubbbNRTsgWz0RjNTy6DJLOxQ3/QBc= github.com/libp2p/go-libp2p-http v0.5.0/go.mod h1:glh87nZ35XCQyFsdzZps6+F4HYI6DctVFY5u1fehwSg= -github.com/libp2p/go-libp2p-kad-dht v0.24.0 h1:nZnFDQEFU4N8GzclnR+IGxIgR7k4PPCDk/GK9A28onk= -github.com/libp2p/go-libp2p-kad-dht v0.24.0/go.mod h1:lfu5T01EH+r6uDZ/8G+ObhwgzVyd0b1nb54AdT8XGhc= +github.com/libp2p/go-libp2p-kad-dht v0.24.1 h1:XH9vIWqc6e+w6z2Nvt9R5EhkBNnOQl7tyxxM6soejwo= +github.com/libp2p/go-libp2p-kad-dht v0.24.1/go.mod h1:1meiUvgOxfSPBx1pracS4VyYwmusorvv+TVRI3mXaJI= github.com/libp2p/go-libp2p-kbucket v0.3.1/go.mod h1:oyjT5O7tS9CQurok++ERgc46YLwEpuGoFq9ubvoUOio= -github.com/libp2p/go-libp2p-kbucket v0.6.1 h1:Y/NIvALuY5/fJlOpaJor9Azg4eor15JskGs9Lb2EhH0= -github.com/libp2p/go-libp2p-kbucket v0.6.1/go.mod h1:dvWO707Oq/vhMVuUhyfLkw0QsOrJFETepbNfpVHSELI= +github.com/libp2p/go-libp2p-kbucket v0.6.3 h1:p507271wWzpy2f1XxPzCQG9NiN6R6lHL9GiSErbQQo0= +github.com/libp2p/go-libp2p-kbucket v0.6.3/go.mod h1:RCseT7AH6eJWxxk2ol03xtP9pEHetYSPXOaJnOiD8i0= github.com/libp2p/go-libp2p-peerstore v0.1.4/go.mod h1:+4BDbDiiKf4PzpANZDAT+knVdLxvqh7hXOujessqdzs= github.com/libp2p/go-libp2p-pubsub v0.9.3 h1:ihcz9oIBMaCK9kcx+yHWm3mLAFBMAUsM4ux42aikDxo= github.com/libp2p/go-libp2p-pubsub v0.9.3/go.mod h1:RYA7aM9jIic5VV47WXu4GkcRxRhrdElWf8xtyli+Dzc= @@ -576,8 +577,8 @@ github.com/libp2p/go-netroute v0.2.1 h1:V8kVrpD8GK0Riv15/7VN6RbUQ3URNZVosw7H2v9t github.com/libp2p/go-netroute v0.2.1/go.mod h1:hraioZr0fhBjG0ZRXJJ6Zj2IVEVNx6tDTFQfSmcq7mQ= 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= -github.com/libp2p/go-reuseport v0.2.0 h1:18PRvIMlpY6ZK85nIAicSBuXXvrYoSw3dsBAR7zc560= -github.com/libp2p/go-reuseport v0.2.0/go.mod h1:bvVho6eLMm6Bz5hmU0LYN3ixd3nPPvtIlaURZZgOY4k= +github.com/libp2p/go-reuseport v0.3.0 h1:iiZslO5byUYZEg9iCwJGf5h+sf1Agmqx2V2FDjPyvUw= +github.com/libp2p/go-reuseport v0.3.0/go.mod h1:laea40AimhtfEqysZ71UpYj4S+R9VpH8PgqLo7L+SwI= github.com/libp2p/go-sockaddr v0.0.2/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= @@ -614,8 +615,8 @@ github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyex github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= -github.com/miekg/dns v1.1.53 h1:ZBkuHr5dxHtB1caEOlZTLPo7D3L3TWckgUUs/RHfDxw= -github.com/miekg/dns v1.1.53/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= +github.com/miekg/dns v1.1.54 h1:5jon9mWcb0sFJGpnI99tOMhCPyJ+RPVz5b63MQG0VWI= +github.com/miekg/dns v1.1.54/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c h1:bzE/A84HN25pxAuk9Eej1Kz9OUelF97nAc82bDquQI8= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c/go.mod h1:0SQS9kMwD2VsyFEB++InYyBJroV/FRmBgcydeSUcJms= github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= @@ -696,12 +697,12 @@ github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= -github.com/onsi/ginkgo/v2 v2.9.2 h1:BA2GMJOtfGAfagzYtrAlufIP0lq6QERkFmHLMLPwFSU= -github.com/onsi/ginkgo/v2 v2.9.2/go.mod h1:WHcJJG2dIlcCqVfBAwUCrJxSPFb6v4azBwgxeMeDuts= +github.com/onsi/ginkgo/v2 v2.9.7 h1:06xGQy5www2oN160RtEZoTvnP2sPhEfePYmCDc2szss= +github.com/onsi/ginkgo/v2 v2.9.7/go.mod h1:cxrmXWykAwTwhQsJOPfdIDiJ+l2RYq7U8hFU+M/1uw0= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.27.4 h1:Z2AnStgsdSayCMDiCU42qIz+HLqEPcgiOCXjAU/w+8E= +github.com/onsi/gomega v1.27.7 h1:fVih9JD6ogIiHUN6ePK7HJidyEDpWGVB5mzM7cWNXoU= github.com/opencontainers/runtime-spec v1.0.2 h1:UfAcuLBJB9Coz72x1hgl8O5RVzTdNiaglX6v2DM6FI0= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= @@ -741,8 +742,8 @@ github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1: github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= -github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= +github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY= +github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= @@ -773,8 +774,8 @@ github.com/quic-go/qtls-go1-20 v0.2.2 h1:WLOPx6OY/hxtTxKV1Zrq20FtXtDEkeY00CGQm8G github.com/quic-go/qtls-go1-20 v0.2.2/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= github.com/quic-go/quic-go v0.33.0 h1:ItNoTDN/Fm/zBlq769lLJc8ECe9gYaW40veHCCco7y0= github.com/quic-go/quic-go v0.33.0/go.mod h1:YMuhaAV9/jIu0XclDXwZPAsP/2Kgr5yMYhe9oxhhOFA= -github.com/quic-go/webtransport-go v0.5.2 h1:GA6Bl6oZY+g/flt00Pnu0XtivSD8vukOu3lYhJjnGEk= -github.com/quic-go/webtransport-go v0.5.2/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= +github.com/quic-go/webtransport-go v0.5.3 h1:5XMlzemqB4qmOlgIus5zB45AcZ2kCgCy2EptUrfOPWU= +github.com/quic-go/webtransport-go v0.5.3/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= @@ -1007,8 +1008,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g= -golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= +golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM= +golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1123,8 +1124,8 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI= +golang.org/x/sync v0.2.0/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-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1196,14 +1197,14 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s= +golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols= -golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.9.0 h1:GRRCnKYhdQrD8kfRAdQ6Zcw1P0OcELxGLKJvtjVMZ28= +golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1213,8 +1214,8 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58= +golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1272,8 +1273,8 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4= -golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= +golang.org/x/tools v0.9.1 h1:8WMNJAz3zrtPmnYC7ISf5dEn3MT0gY7jBJfw27yrrLo= +golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 2564e2bdc..ce3c34d7b 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -19,7 +19,7 @@ require ( github.com/ipld/go-ipld-prime v0.20.0 github.com/jbenet/go-random v0.0.0-20190219211222-123a90aedc0c github.com/jbenet/go-random-files v0.0.0-20190219210431-31b3f20ebded - github.com/libp2p/go-libp2p v0.27.5 + github.com/libp2p/go-libp2p v0.27.6 github.com/multiformats/go-multiaddr v0.9.0 github.com/multiformats/go-multihash v0.2.3 gotest.tools/gotestsum v0.4.2 @@ -39,7 +39,7 @@ require ( github.com/alingse/asasalint v0.0.11 // indirect github.com/ashanbrown/forbidigo v1.3.0 // indirect github.com/ashanbrown/makezero v1.1.1 // indirect - github.com/benbjohnson/clock v1.3.0 // indirect + github.com/benbjohnson/clock v1.3.5 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bkielbasa/cyclop v1.2.0 // indirect github.com/blizzy78/varnamelen v0.8.0 // indirect @@ -101,7 +101,7 @@ require ( github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4 // indirect github.com/google/go-cmp v0.5.9 // indirect github.com/google/gopacket v1.1.19 // indirect - github.com/google/pprof v0.0.0-20230405160723-4a4c7d95572b // indirect + github.com/google/pprof v0.0.0-20230602150820-91b7bce49751 // indirect github.com/google/uuid v1.3.0 // indirect github.com/gordonklaus/ineffassign v0.0.0-20210914165742-4cc7213b9bc8 // indirect github.com/gostaticanalysis/analysisutil v0.7.1 // indirect @@ -116,7 +116,7 @@ require ( github.com/hashicorp/golang-lru v0.5.4 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/hexops/gotextdiff v1.0.3 // indirect - github.com/huin/goupnp v1.1.0 // indirect + github.com/huin/goupnp v1.2.0 // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/ipfs/bbloom v0.0.4 // indirect github.com/ipfs/go-bitfield v1.1.0 // indirect @@ -144,7 +144,7 @@ require ( github.com/julz/importas v0.1.0 // indirect github.com/kisielk/errcheck v1.6.2 // indirect github.com/kisielk/gotool v1.0.0 // indirect - github.com/klauspost/compress v1.16.4 // indirect + github.com/klauspost/compress v1.16.5 // indirect github.com/klauspost/cpuid/v2 v2.2.5 // indirect github.com/koron/go-ssdp v0.0.4 // indirect github.com/kulti/thelper v0.6.3 // indirect @@ -160,7 +160,7 @@ require ( github.com/libp2p/go-msgio v0.3.0 // indirect github.com/libp2p/go-nat v0.1.0 // indirect github.com/libp2p/go-netroute v0.2.1 // indirect - github.com/libp2p/go-reuseport v0.2.0 // indirect + github.com/libp2p/go-reuseport v0.3.0 // indirect github.com/libp2p/go-yamux/v4 v4.0.0 // indirect github.com/lufeee/execinquery v1.2.1 // indirect github.com/magiconair/properties v1.8.6 // indirect @@ -173,7 +173,7 @@ require ( github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/mbilski/exhaustivestruct v1.2.0 // indirect github.com/mgechev/revive v1.2.3 // indirect - github.com/miekg/dns v1.1.53 // indirect + github.com/miekg/dns v1.1.54 // indirect github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect github.com/minio/sha256-simd v1.0.1 // indirect @@ -194,7 +194,7 @@ require ( github.com/nishanths/exhaustive v0.8.1 // indirect github.com/nishanths/predeclared v0.2.2 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect - github.com/onsi/ginkgo/v2 v2.9.2 // indirect + github.com/onsi/ginkgo/v2 v2.9.7 // indirect github.com/opencontainers/runtime-spec v1.0.2 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect @@ -206,7 +206,7 @@ require ( github.com/polydawn/refmt v0.89.0 // indirect github.com/polyfloyd/go-errorlint v1.0.2 // indirect github.com/prometheus/client_golang v1.14.0 // indirect - github.com/prometheus/client_model v0.3.0 // indirect + github.com/prometheus/client_model v0.4.0 // indirect github.com/prometheus/common v0.42.0 // indirect github.com/prometheus/procfs v0.9.0 // indirect github.com/quasilyte/go-ruleguard v0.3.17 // indirect @@ -217,7 +217,7 @@ require ( github.com/quic-go/qtls-go1-19 v0.3.2 // indirect github.com/quic-go/qtls-go1-20 v0.2.2 // indirect github.com/quic-go/quic-go v0.33.0 // indirect - github.com/quic-go/webtransport-go v0.5.2 // indirect + github.com/quic-go/webtransport-go v0.5.3 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/ryancurrah/gomodguard v1.2.4 // indirect @@ -267,16 +267,16 @@ require ( go.uber.org/fx v1.19.3 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.24.0 // indirect - golang.org/x/crypto v0.9.0 // indirect + golang.org/x/crypto v0.10.0 // indirect golang.org/x/exp v0.0.0-20230321023759-10a507213a29 // indirect golang.org/x/exp/typeparams v0.0.0-20220613132600-b0d781184e0d // indirect golang.org/x/mod v0.10.0 // indirect golang.org/x/net v0.10.0 // indirect - golang.org/x/sync v0.1.0 // indirect - golang.org/x/sys v0.8.0 // indirect - golang.org/x/term v0.8.0 // indirect - golang.org/x/text v0.9.0 // indirect - golang.org/x/tools v0.7.0 // indirect + golang.org/x/sync v0.2.0 // indirect + golang.org/x/sys v0.9.0 // indirect + golang.org/x/term v0.9.0 // indirect + golang.org/x/text v0.10.0 // indirect + golang.org/x/tools v0.9.1 // indirect google.golang.org/protobuf v1.30.0 // indirect gopkg.in/ini.v1 v1.66.6 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index a8ed1279e..431fcdbba 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -80,8 +80,9 @@ github.com/ashanbrown/forbidigo v1.3.0/go.mod h1:vVW7PEdqEFqapJe95xHkTfB1+XvZXBF github.com/ashanbrown/makezero v1.1.1 h1:iCQ87C0V0vSyO+M9E/FZYbu65auqH0lnsOkf5FcB28s= github.com/ashanbrown/makezero v1.1.1/go.mod h1:i1bJLCRSCHOcOa9Y6MyF2FTfMZMFdHvxKHxgO5Z1axI= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= -github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o= +github.com/benbjohnson/clock v1.3.5/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -346,8 +347,8 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20230405160723-4a4c7d95572b h1:Qcx5LM0fSiks9uCyFZwDBUasd3lxd1RM0GYpL+Li5o4= -github.com/google/pprof v0.0.0-20230405160723-4a4c7d95572b/go.mod h1:79YE0hCXdHag9sBkw2o+N/YnZtTkXi0UT9Nnixa5eYk= +github.com/google/pprof v0.0.0-20230602150820-91b7bce49751 h1:hR7/MlvK23p6+lIw9SN1TigNLn9ZnF3W4SYRKq2gAHs= +github.com/google/pprof v0.0.0-20230602150820-91b7bce49751/go.mod h1:Jh3hGz2jkYak8qXPD19ryItVnUgpgeqzdkY/D0EaeuA= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -403,8 +404,8 @@ github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUq github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= -github.com/huin/goupnp v1.1.0 h1:gEe0Dp/lZmPZiDFzJJaOfUpOvv2MKUkoBX8lDrn9vKU= -github.com/huin/goupnp v1.1.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= +github.com/huin/goupnp v1.2.0 h1:uOKW26NG1hsSSbXIZ1IR7XP9Gjd1U8pnLaCMgntmkmY= +github.com/huin/goupnp v1.2.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= @@ -523,8 +524,8 @@ github.com/kisielk/errcheck v1.6.2/go.mod h1:nXw/i/MfnvRHqXa7XXmQMUB0oNFGuBrNI8d github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/klauspost/compress v1.16.4 h1:91KN02FnsOYhuunwU4ssRe8lc2JosWmizWa91B5v1PU= -github.com/klauspost/compress v1.16.4/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/compress v1.16.5 h1:IFV2oUNUzZaz+XyusxpLzpzS8Pt5rh0Z16For/djlyI= +github.com/klauspost/compress v1.16.5/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -564,8 +565,8 @@ github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38y github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.27.5 h1:KwA7pXKXpz8hG6Cr1fMA7UkgleogcwQj0sxl5qquWRg= -github.com/libp2p/go-libp2p v0.27.5/go.mod h1:oMfQGTb9CHnrOuSM6yMmyK2lXz3qIhnkn2+oK3B1Y2g= +github.com/libp2p/go-libp2p v0.27.6 h1:KmGU5kskCaaerm53heqzfGOlrW2z8icZ+fnyqgrZs38= +github.com/libp2p/go-libp2p v0.27.6/go.mod h1:oMfQGTb9CHnrOuSM6yMmyK2lXz3qIhnkn2+oK3B1Y2g= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= @@ -577,8 +578,8 @@ 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.2.1 h1:V8kVrpD8GK0Riv15/7VN6RbUQ3URNZVosw7H2v9tksU= github.com/libp2p/go-netroute v0.2.1/go.mod h1:hraioZr0fhBjG0ZRXJJ6Zj2IVEVNx6tDTFQfSmcq7mQ= -github.com/libp2p/go-reuseport v0.2.0 h1:18PRvIMlpY6ZK85nIAicSBuXXvrYoSw3dsBAR7zc560= -github.com/libp2p/go-reuseport v0.2.0/go.mod h1:bvVho6eLMm6Bz5hmU0LYN3ixd3nPPvtIlaURZZgOY4k= +github.com/libp2p/go-reuseport v0.3.0 h1:iiZslO5byUYZEg9iCwJGf5h+sf1Agmqx2V2FDjPyvUw= +github.com/libp2p/go-reuseport v0.3.0/go.mod h1:laea40AimhtfEqysZ71UpYj4S+R9VpH8PgqLo7L+SwI= github.com/libp2p/go-sockaddr v0.0.2/go.mod h1:syPvOmNs24S3dFVGJA1/mrqdeijPxLV2Le3BRLKd68k= github.com/libp2p/go-yamux/v4 v4.0.0 h1:+Y80dV2Yx/kv7Y7JKu0LECyVdMXm1VUoko+VQ9rBfZQ= github.com/libp2p/go-yamux/v4 v4.0.0/go.mod h1:NWjl8ZTLOGlozrXSOZ/HlfG++39iKNnM5wwmtQP1YB4= @@ -618,8 +619,8 @@ github.com/mgechev/revive v1.2.3 h1:NzIEEa9+WimQ6q2Ov7OcNeySS/IOcwtkQ8RAh0R5UJ4= github.com/mgechev/revive v1.2.3/go.mod h1:iAWlQishqCuj4yhV24FTnKSXGpbAA+0SckXB8GQMX/Q= github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= -github.com/miekg/dns v1.1.53 h1:ZBkuHr5dxHtB1caEOlZTLPo7D3L3TWckgUUs/RHfDxw= -github.com/miekg/dns v1.1.53/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= +github.com/miekg/dns v1.1.54 h1:5jon9mWcb0sFJGpnI99tOMhCPyJ+RPVz5b63MQG0VWI= +github.com/miekg/dns v1.1.54/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c h1:bzE/A84HN25pxAuk9Eej1Kz9OUelF97nAc82bDquQI8= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c/go.mod h1:0SQS9kMwD2VsyFEB++InYyBJroV/FRmBgcydeSUcJms= github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= @@ -693,10 +694,10 @@ github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo/v2 v2.9.2 h1:BA2GMJOtfGAfagzYtrAlufIP0lq6QERkFmHLMLPwFSU= -github.com/onsi/ginkgo/v2 v2.9.2/go.mod h1:WHcJJG2dIlcCqVfBAwUCrJxSPFb6v4azBwgxeMeDuts= +github.com/onsi/ginkgo/v2 v2.9.7 h1:06xGQy5www2oN160RtEZoTvnP2sPhEfePYmCDc2szss= +github.com/onsi/ginkgo/v2 v2.9.7/go.mod h1:cxrmXWykAwTwhQsJOPfdIDiJ+l2RYq7U8hFU+M/1uw0= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.27.4 h1:Z2AnStgsdSayCMDiCU42qIz+HLqEPcgiOCXjAU/w+8E= +github.com/onsi/gomega v1.27.7 h1:fVih9JD6ogIiHUN6ePK7HJidyEDpWGVB5mzM7cWNXoU= github.com/opencontainers/runtime-spec v1.0.2 h1:UfAcuLBJB9Coz72x1hgl8O5RVzTdNiaglX6v2DM6FI0= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= @@ -740,8 +741,8 @@ github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1: github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= -github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= +github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY= +github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= @@ -778,8 +779,8 @@ github.com/quic-go/qtls-go1-20 v0.2.2 h1:WLOPx6OY/hxtTxKV1Zrq20FtXtDEkeY00CGQm8G github.com/quic-go/qtls-go1-20 v0.2.2/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= github.com/quic-go/quic-go v0.33.0 h1:ItNoTDN/Fm/zBlq769lLJc8ECe9gYaW40veHCCco7y0= github.com/quic-go/quic-go v0.33.0/go.mod h1:YMuhaAV9/jIu0XclDXwZPAsP/2Kgr5yMYhe9oxhhOFA= -github.com/quic-go/webtransport-go v0.5.2 h1:GA6Bl6oZY+g/flt00Pnu0XtivSD8vukOu3lYhJjnGEk= -github.com/quic-go/webtransport-go v0.5.2/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= +github.com/quic-go/webtransport-go v0.5.3 h1:5XMlzemqB4qmOlgIus5zB45AcZ2kCgCy2EptUrfOPWU= +github.com/quic-go/webtransport-go v0.5.3/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= @@ -990,8 +991,8 @@ golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g= -golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= +golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM= +golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1107,8 +1108,8 @@ 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/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI= +golang.org/x/sync v0.2.0/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-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1177,12 +1178,12 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s= +golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols= -golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.9.0 h1:GRRCnKYhdQrD8kfRAdQ6Zcw1P0OcELxGLKJvtjVMZ28= +golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1191,8 +1192,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58= +golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1285,8 +1286,8 @@ golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/tools v0.1.11/go.mod h1:SgwaegtQh8clINPpECJMqnxLv9I09HLqnW3RMqW0CA4= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4= -golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= +golang.org/x/tools v0.9.1 h1:8WMNJAz3zrtPmnYC7ISf5dEn3MT0gY7jBJfw27yrrLo= +golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From e5ac0454a6182e76870dd8e0ba579fa5d7d5b461 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Thu, 15 Jun 2023 11:15:42 +0000 Subject: [PATCH 0731/1212] chore: update version --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index dce4e39ec..98ee37fc5 100644 --- a/version.go +++ b/version.go @@ -11,7 +11,7 @@ import ( var CurrentCommit string // CurrentVersionNumber is the current application's version literal -const CurrentVersionNumber = "0.21.0-rc1" +const CurrentVersionNumber = "0.21.0-rc2" const ApiVersion = "/kubo/" + CurrentVersionNumber + "/" //nolint From 2cbee81b9befb4a1c59335217de462dc193bd5ef Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Thu, 15 Jun 2023 14:53:45 +0200 Subject: [PATCH 0732/1212] docs: fix 0.21 changelog --- CHANGELOG.md | 1 + docs/changelogs/v0.21.md | 22 ---------------------- docs/changelogs/v0.22.md | 40 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 41 insertions(+), 22 deletions(-) create mode 100644 docs/changelogs/v0.22.md diff --git a/CHANGELOG.md b/CHANGELOG.md index b99ff4f15..0138eb231 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ # Kubo Changelogs +- [v0.22](docs/changelogs/v0.22.md) - [v0.21](docs/changelogs/v0.21.md) - [v0.20](docs/changelogs/v0.20.md) - [v0.19](docs/changelogs/v0.19.md) diff --git a/docs/changelogs/v0.21.md b/docs/changelogs/v0.21.md index 0f5ea1cf6..394059472 100644 --- a/docs/changelogs/v0.21.md +++ b/docs/changelogs/v0.21.md @@ -12,7 +12,6 @@ - [Gateway: DAG-CBOR/-JSON previews and improved error pages](#gateway-dag-cbor-json-previews-and-improved-error-pages) - [Gateway: subdomain redirects are now `text/html`](#gateway-subdomain-redirects-are-now-texthtml) - [Gateway: support for partial CAR export parameters (IPIP-402)](#gateway-support-for-partial-car-export-parameters-ipip-402) - - [`ipfs dag import` no longer pins by default](#ipfs-dag-import-no-longer-pins-by-default) - [`ipfs dag stat` deduping statistics](#ipfs-dag-stat-deduping-statistics) - [Accelerated DHT Client is no longer experimental](#accelerated-dht-client-is-no-longer-experimental) - [📝 Changelog](#-changelog) @@ -116,27 +115,6 @@ Batch block retrieval minimizes round trips, catering to the requirements of light HTTP clients for directory enumeration, range requests, and content path resolution. -#### `ipfs dag import` no longer pins by default - -With the gateway now capable of handling partial CAR exports -([IPIP-402](https://github.com/ipfs/specs/pull/402)) and incomplete DAG CARs -becoming more prevalent, there have been changes to the pinning mode when using -`ipfs dag import`. - -Recursive pinning of the entire DAG within an imported CAR is now optional. To -explicitly attempt pinning the DAG referenced by any roots present in the CAR, -you can opt in by using the `--pin-roots` option. - -Pinning incomplete DAG will produce an error: - -```console -$ curl 'http://127.0.0.1:8080/ipns/docs.ipfs.tech?format=car&dag-scope=entity' > ./partial-entity.car # Kubo 0.21.0 with IPIP-402 (only root block of unixfs dir) -$ ipfs dag import --stats --pin-roots=true ./partial-entity.car -Error pinning QmPDC11yLAbVw3dX5jMeEuSdk4BiVjSd9X87zaYRdVjzW3 FAILED: block was not found locally (offline): ipld: could not find QmPDvrDAz2aHeLjPVQ4uh1neyknUmDpf1GsBzAbpFhS8ro -Imported 1 blocks (1618 bytes) -[exit code 1] -``` - #### `ipfs dag stat` deduping statistics `ipfs dat stat` now accept multiple CIDs and will dump advanced statistics diff --git a/docs/changelogs/v0.22.md b/docs/changelogs/v0.22.md new file mode 100644 index 000000000..aba6a4ac7 --- /dev/null +++ b/docs/changelogs/v0.22.md @@ -0,0 +1,40 @@ +# Kubo changelog v0.22 + +- [v0.22.0](#v0220) + +## v0.22.0 + +- [Overview](#overview) +- [🔦 Highlights](#-highlights) + - [`ipfs dag import` no longer pins by default](#ipfs-dag-import-no-longer-pins-by-default) +- [📝 Changelog](#-changelog) +- [👨‍👩‍👧‍👦 Contributors](#-contributors) + +### Overview + +### 🔦 Highlights + +#### `ipfs dag import` no longer pins by default + +With the gateway now capable of handling partial CAR exports +([IPIP-402](https://github.com/ipfs/specs/pull/402)) and incomplete DAG CARs +becoming more prevalent, there have been changes to the pinning mode when using +`ipfs dag import`. + +Recursive pinning of the entire DAG within an imported CAR is now optional. To +explicitly attempt pinning the DAG referenced by any roots present in the CAR, +you can opt in by using the `--pin-roots` option. + +Pinning incomplete DAG will produce an error: + +```console +$ curl 'http://127.0.0.1:8080/ipns/docs.ipfs.tech?format=car&dag-scope=entity' > ./partial-entity.car # Kubo 0.21.0 with IPIP-402 (only root block of unixfs dir) +$ ipfs dag import --stats --pin-roots=true ./partial-entity.car +Error pinning QmPDC11yLAbVw3dX5jMeEuSdk4BiVjSd9X87zaYRdVjzW3 FAILED: block was not found locally (offline): ipld: could not find QmPDvrDAz2aHeLjPVQ4uh1neyknUmDpf1GsBzAbpFhS8ro +Imported 1 blocks (1618 bytes) +[exit code 1] +``` + +### 📝 Changelog + +### 👨‍👩‍👧‍👦 Contributors From 82fd9ec329f0423b509f6ee2fe1859243026397b Mon Sep 17 00:00:00 2001 From: Jorropo Date: Thu, 15 Jun 2023 16:41:59 +0200 Subject: [PATCH 0733/1212] cmds/dag/import: pin roots by default (#9966) This is a partial revert of b685355ca8ceaaf55619ee3b8cffa612a4106569. Closes #9765 with compromise agreed in https://github.com/ipfs/kubo/issues/9765#issuecomment-1593117410 --- core/commands/dag/dag.go | 13 +++++------- docs/changelogs/v0.22.md | 22 -------------------- test/sharness/t0054-dag-car-import-export.sh | 21 ++++++++----------- test/sharness/t0124-gateway-ipns-record.sh | 2 +- test/sharness/t0400-api-no-gateway.sh | 2 +- 5 files changed, 16 insertions(+), 44 deletions(-) diff --git a/core/commands/dag/dag.go b/core/commands/dag/dag.go index 505f9770d..41fde70e5 100644 --- a/core/commands/dag/dag.go +++ b/core/commands/dag/dag.go @@ -176,16 +176,13 @@ var DagImportCmd = &cmds.Command{ Tagline: "Import the contents of .car files", ShortDescription: ` 'ipfs dag import' imports all blocks present in supplied .car -( Content Address aRchive ) files, optionally recursively pinning any -roots specified in the CAR file headers if --pin-roots is set. +( Content Address aRchive ) files, recursively pinning any roots +specified in the CAR file headers, unless --pin-roots is set to false. Note: This command will import all blocks in the CAR file, not just those - reachable from the specified roots. However, when using --pin-roots, - these other blocks will not be pinned and may be garbage collected - later. When not using --pin-roots, all blocks imported may be garbage - collected if no other pin operation is performed on them, or a root - that references them. + reachable from the specified roots. However, these other blocks will + not be pinned and may be garbage collected later. The pinning of the roots happens after all car files are processed, permitting import of DAGs spanning multiple files. @@ -203,7 +200,7 @@ Specification of CAR formats: https://ipld.io/specs/transport/car/ cmds.FileArg("path", true, true, "The path of a .car file.").EnableStdin(), }, Options: []cmds.Option{ - cmds.BoolOption(pinRootsOptionName, "Pin optional roots listed in the .car headers after importing."), + cmds.BoolOption(pinRootsOptionName, "Pin optional roots listed in the .car headers after importing.").WithDefault(true), cmds.BoolOption(silentOptionName, "No output."), cmds.BoolOption(statsOptionName, "Output stats."), cmdutils.AllowBigBlockOption, diff --git a/docs/changelogs/v0.22.md b/docs/changelogs/v0.22.md index aba6a4ac7..6fabdad7d 100644 --- a/docs/changelogs/v0.22.md +++ b/docs/changelogs/v0.22.md @@ -6,7 +6,6 @@ - [Overview](#overview) - [🔦 Highlights](#-highlights) - - [`ipfs dag import` no longer pins by default](#ipfs-dag-import-no-longer-pins-by-default) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -14,27 +13,6 @@ ### 🔦 Highlights -#### `ipfs dag import` no longer pins by default - -With the gateway now capable of handling partial CAR exports -([IPIP-402](https://github.com/ipfs/specs/pull/402)) and incomplete DAG CARs -becoming more prevalent, there have been changes to the pinning mode when using -`ipfs dag import`. - -Recursive pinning of the entire DAG within an imported CAR is now optional. To -explicitly attempt pinning the DAG referenced by any roots present in the CAR, -you can opt in by using the `--pin-roots` option. - -Pinning incomplete DAG will produce an error: - -```console -$ curl 'http://127.0.0.1:8080/ipns/docs.ipfs.tech?format=car&dag-scope=entity' > ./partial-entity.car # Kubo 0.21.0 with IPIP-402 (only root block of unixfs dir) -$ ipfs dag import --stats --pin-roots=true ./partial-entity.car -Error pinning QmPDC11yLAbVw3dX5jMeEuSdk4BiVjSd9X87zaYRdVjzW3 FAILED: block was not found locally (offline): ipld: could not find QmPDvrDAz2aHeLjPVQ4uh1neyknUmDpf1GsBzAbpFhS8ro -Imported 1 blocks (1618 bytes) -[exit code 1] -``` - ### 📝 Changelog ### 👨‍👩‍👧‍👦 Contributors diff --git a/test/sharness/t0054-dag-car-import-export.sh b/test/sharness/t0054-dag-car-import-export.sh index 65195cb05..0482f24d9 100755 --- a/test/sharness/t0054-dag-car-import-export.sh +++ b/test/sharness/t0054-dag-car-import-export.sh @@ -41,7 +41,7 @@ do_import() { while [[ -e spin.gc ]]; do ipfsi "$node" repo gc &>/dev/null; done & while [[ -e spin.gc ]]; do ipfsi "$node" repo gc &>/dev/null; done & - ipfsi "$node" dag import --pin-roots "$@" 2>&1 && ipfsi "$node" repo verify &>/dev/null + ipfsi "$node" dag import "$@" 2>&1 && ipfsi "$node" repo verify &>/dev/null result=$? rm -f spin.gc &>/dev/null @@ -117,7 +117,7 @@ EOE ' test_expect_success "import/pin naked roots only, relying on local blockstore having all the data" ' - ipfsi 1 dag import --stats --enc=json --pin-roots ../t0054-dag-car-import-export-data/combined_naked_roots_genesis_and_128.car \ + ipfsi 1 dag import --stats --enc=json ../t0054-dag-car-import-export-data/combined_naked_roots_genesis_and_128.car \ > naked_import_result_json_actual ' @@ -197,14 +197,14 @@ EOE head -3 multiroot_import_json_stats_expected > multiroot_import_json_expected test_expect_success "multiroot import works (--enc=json)" ' - ipfs dag import --enc=json --pin-roots ../t0054-dag-car-import-export-data/lotus_testnet_export_256_multiroot.car > multiroot_import_json_actual + ipfs dag import --enc=json ../t0054-dag-car-import-export-data/lotus_testnet_export_256_multiroot.car > multiroot_import_json_actual ' test_expect_success "multiroot import expected output" ' test_cmp_sorted multiroot_import_json_expected multiroot_import_json_actual ' test_expect_success "multiroot import works with --stats" ' - ipfs dag import --stats --enc=json --pin-roots ../t0054-dag-car-import-export-data/lotus_testnet_export_256_multiroot.car > multiroot_import_json_actual + ipfs dag import --stats --enc=json ../t0054-dag-car-import-export-data/lotus_testnet_export_256_multiroot.car > multiroot_import_json_actual ' test_expect_success "multiroot import expected output" ' test_cmp_sorted multiroot_import_json_stats_expected multiroot_import_json_actual @@ -215,18 +215,18 @@ cat >pin_import_expected << EOE {"Stats":{"BlockCount":1198,"BlockBytesCount":468513}} EOE test_expect_success "pin-less import works" ' - ipfs dag import --stats --enc=json \ + ipfs dag import --stats --enc=json --pin-roots=false \ ../t0054-dag-car-import-export-data/lotus_devnet_genesis.car \ ../t0054-dag-car-import-export-data/lotus_testnet_export_128.car \ > no-pin_import_actual ' -test_expect_success "expected no pins on" ' +test_expect_success "expected no pins on --pin-roots=false" ' test_cmp pin_import_expected no-pin_import_actual ' test_expect_success "naked root import works" ' - ipfs dag import --stats --enc=json --pin-roots ../t0054-dag-car-import-export-data/combined_naked_roots_genesis_and_128.car \ + ipfs dag import --stats --enc=json ../t0054-dag-car-import-export-data/combined_naked_roots_genesis_and_128.car \ > naked_root_import_json_actual ' test_expect_success "naked root import expected output" ' @@ -253,7 +253,7 @@ cat > version_2_import_expected << EOE EOE test_expect_success "version 2 import" ' - ipfs dag import --stats --enc=json --pin-roots \ + ipfs dag import --stats --enc=json \ ../t0054-dag-car-import-export-data/lotus_testnet_export_128_v2.car \ ../t0054-dag-car-import-export-data/lotus_devnet_genesis_v2.car \ > version_2_import_actual @@ -299,9 +299,6 @@ test_expect_success "'ipfs dag import' without pinning works fine with incomplet ipfs dag import --stats --enc=json --pin-roots=false ../t0054-dag-car-import-export-data/partial-dag-scope-entity.car >partial_nopin_import_out 2>&1 && test_cmp partial_nopin_import_expected partial_nopin_import_out ' -test_expect_success "'ipfs dag import' with no params in CLI mode produces exit code 0 (unixfs dir exported as dag-scope=entity from IPIP-402)" ' - test_expect_code 0 ipfs dag import ../t0054-dag-car-import-export-data/partial-dag-scope-entity.car -' test_expect_success "'ipfs dag import' with pinning errors due to incomplete DAG (unixfs dir exported as dag-scope=entity from IPIP-402)" ' ipfs dag import --stats --enc=json --pin-roots=true ../t0054-dag-car-import-export-data/partial-dag-scope-entity.car >partial_pin_import_out 2>&1 && @@ -309,7 +306,7 @@ test_expect_success "'ipfs dag import' with pinning errors due to incomplete DAG ' test_expect_success "'ipfs dag import' pin error in default CLI mode produces exit code 1 (unixfs dir exported as dag-scope=entity from IPIP-402)" ' - test_expect_code 1 ipfs dag import --pin-roots ../t0054-dag-car-import-export-data/partial-dag-scope-entity.car >partial_pin_import_out 2>&1 && + test_expect_code 1 ipfs dag import ../t0054-dag-car-import-export-data/partial-dag-scope-entity.car >partial_pin_import_out 2>&1 && test_should_contain "Error: pinning root \"QmPDC11yLAbVw3dX5jMeEuSdk4BiVjSd9X87zaYRdVjzW3\" FAILED: block was not found locally" partial_pin_import_out ' diff --git a/test/sharness/t0124-gateway-ipns-record.sh b/test/sharness/t0124-gateway-ipns-record.sh index 605252c0f..1d05b5698 100755 --- a/test/sharness/t0124-gateway-ipns-record.sh +++ b/test/sharness/t0124-gateway-ipns-record.sh @@ -12,7 +12,7 @@ test_launch_ipfs_daemon IPNS_KEY=k51qzi5uqu5dh71qgwangrt6r0nd4094i88nsady6qgd1dhjcyfsaqmpp143ab FILE_CID=bafkreidfdrlkeq4m4xnxuyx6iae76fdm4wgl5d4xzsb77ixhyqwumhz244 # A file containing Hello IPFS test_expect_success "Add the test directory & IPNS records" ' - ipfs dag import --pin-roots ../t0124-gateway-ipns-record/fixtures.car && + ipfs dag import ../t0124-gateway-ipns-record/fixtures.car && ipfs routing put /ipns/${IPNS_KEY} ../t0124-gateway-ipns-record/${IPNS_KEY}.ipns-record ' diff --git a/test/sharness/t0400-api-no-gateway.sh b/test/sharness/t0400-api-no-gateway.sh index 7518db427..d0daeece3 100755 --- a/test/sharness/t0400-api-no-gateway.sh +++ b/test/sharness/t0400-api-no-gateway.sh @@ -13,7 +13,7 @@ test_init_ipfs # Import test case # See the static fixtures in ./t0400-api-no-gateway/ test_expect_success "Add the test directory" ' - ipfs dag import --pin-roots ../t0400-api-no-gateway/fixtures.car + ipfs dag import ../t0400-api-no-gateway/fixtures.car ' HASH=QmNYERzV2LfD2kkfahtfv44ocHzEFK1sLBaE7zdcYT2GAZ # a file containing the string "testing" From 27398ce93f191b4ab92a7236794a43a73ac8d831 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 15 Jun 2023 17:17:13 +0200 Subject: [PATCH 0734/1212] chore(deps): bump docker/build-push-action from 2 to 4 (#9954) Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 2 to 4. - [Release notes](https://github.com/docker/build-push-action/releases) - [Commits](https://github.com/docker/build-push-action/compare/v2...v4) --- updated-dependencies: - dependency-name: docker/build-push-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/docker-image.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index 520e37833..c3f95f158 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -54,7 +54,7 @@ jobs: password: ${{ secrets.DOCKER_PASSWORD }} - name: Build Docker image and publish to Docker Hub - uses: docker/build-push-action@v2 + uses: docker/build-push-action@v4 with: platforms: linux/amd64,linux/arm/v7,linux/arm64/v8 context: . From 364686ae1d512f59fffebaf78309bb50912f3483 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 15 Jun 2023 17:18:29 +0200 Subject: [PATCH 0735/1212] chore(deps): bump docker/setup-buildx-action from 1 to 2 (#9952) Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 1 to 2. - [Release notes](https://github.com/docker/setup-buildx-action/releases) - [Commits](https://github.com/docker/setup-buildx-action/compare/v1...v2) --- updated-dependencies: - dependency-name: docker/setup-buildx-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/docker-image.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index c3f95f158..ad6b192b7 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -29,7 +29,7 @@ jobs: uses: docker/setup-qemu-action@v1 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v1 + uses: docker/setup-buildx-action@v2 - name: Cache Docker layers uses: actions/cache@v3 From d4eb09f79da411a4e7e4a98fe622906a6b9cfe8b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 15 Jun 2023 17:18:45 +0200 Subject: [PATCH 0736/1212] chore(deps): bump codecov/codecov-action from 3.1.0 to 3.1.4 (#9951) Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 3.1.0 to 3.1.4. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/81cd2dc8148241f03f5839d295e000b8f761e378...eaaf4bedf32dbdc6b720b63067d99c4d77d6047d) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/gotest.yml | 2 +- .github/workflows/sharness.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/gotest.yml b/.github/workflows/gotest.yml index 3f6db57ae..08a741532 100644 --- a/.github/workflows/gotest.yml +++ b/.github/workflows/gotest.yml @@ -47,7 +47,7 @@ jobs: make -j "$PARALLEL" test/unit/gotest.junit.xml && [[ ! $(jq -s -c 'map(select(.Action == "fail")) | .[]' test/unit/gotest.json) ]] - name: Upload coverage to Codecov - uses: codecov/codecov-action@81cd2dc8148241f03f5839d295e000b8f761e378 # v3.1.0 + uses: codecov/codecov-action@eaaf4bedf32dbdc6b720b63067d99c4d77d6047d # v3.1.4 if: failure() || success() with: name: unittests diff --git a/.github/workflows/sharness.yml b/.github/workflows/sharness.yml index cc9ead442..d88abe89c 100644 --- a/.github/workflows/sharness.yml +++ b/.github/workflows/sharness.yml @@ -59,7 +59,7 @@ jobs: # increasing parallelism beyond 10 doesn't speed up the tests much PARALLEL: ${{ github.repository == 'ipfs/kubo' && 10 || 3 }} - name: Upload coverage report - uses: codecov/codecov-action@81cd2dc8148241f03f5839d295e000b8f761e378 # v3.1.0 + uses: codecov/codecov-action@eaaf4bedf32dbdc6b720b63067d99c4d77d6047d # v3.1.4 if: failure() || success() with: name: sharness From 9298e31bbaa627a94193b64a2163adf09ccd02d1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 15 Jun 2023 17:35:34 +0200 Subject: [PATCH 0737/1212] chore(deps): bump docker/setup-qemu-action from 1 to 2 (#9953) Bumps [docker/setup-qemu-action](https://github.com/docker/setup-qemu-action) from 1 to 2. - [Release notes](https://github.com/docker/setup-qemu-action/releases) - [Commits](https://github.com/docker/setup-qemu-action/compare/v1...v2) --- updated-dependencies: - dependency-name: docker/setup-qemu-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/docker-image.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index ad6b192b7..eb991c5ac 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -26,7 +26,7 @@ jobs: uses: actions/checkout@v2 - name: Set up QEMU - uses: docker/setup-qemu-action@v1 + uses: docker/setup-qemu-action@v2 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v2 From 6c47b8119602b90c592d710cff677e11104883eb Mon Sep 17 00:00:00 2001 From: GitHub Date: Mon, 19 Jun 2023 12:28:29 +0000 Subject: [PATCH 0738/1212] chore: Update .github/dependabot.yml [skip ci] From 8bba03d8bf46b4153e8724767c5098f92d9e363e Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Mon, 19 Jun 2023 15:07:33 +0200 Subject: [PATCH 0739/1212] chore: bump boxo to 0.10.1 (#9970) --- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- test/dependencies/go.mod | 2 +- test/dependencies/go.sum | 4 ++-- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index bfbe48843..27ecf1fae 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.18 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.10.0 + github.com/ipfs/boxo v0.10.1 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.27.6 github.com/multiformats/go-multiaddr v0.9.0 diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index d2ff0d772..319c81189 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -320,8 +320,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.10.0 h1:tdDAxq8jrsbRkYoF+5Rcqyeb91hgWe2hp7iLu7ORZLY= -github.com/ipfs/boxo v0.10.0/go.mod h1:Fg+BnfxZ0RPzR0nOodzdIq3A7KgoWAOWsEIImrIQdBM= +github.com/ipfs/boxo v0.10.1 h1:q0ZhbyN6iNZLipd6txt1xotCiP/icfvdAQ4YpUi+cL4= +github.com/ipfs/boxo v0.10.1/go.mod h1:1qgKq45mPRCxf4ZPoJV2lnXxyxucigILMJOrQrVivv8= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= diff --git a/go.mod b/go.mod index aedd07bc9..4ad1375b1 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/gogo/protobuf v1.3.2 github.com/google/uuid v1.3.0 github.com/hashicorp/go-multierror v1.1.1 - github.com/ipfs/boxo v0.10.0 + github.com/ipfs/boxo v0.10.1 github.com/ipfs/go-block-format v0.1.2 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 diff --git a/go.sum b/go.sum index a044a459b..dcfbd3cb0 100644 --- a/go.sum +++ b/go.sum @@ -355,8 +355,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.10.0 h1:tdDAxq8jrsbRkYoF+5Rcqyeb91hgWe2hp7iLu7ORZLY= -github.com/ipfs/boxo v0.10.0/go.mod h1:Fg+BnfxZ0RPzR0nOodzdIq3A7KgoWAOWsEIImrIQdBM= +github.com/ipfs/boxo v0.10.1 h1:q0ZhbyN6iNZLipd6txt1xotCiP/icfvdAQ4YpUi+cL4= +github.com/ipfs/boxo v0.10.1/go.mod h1:1qgKq45mPRCxf4ZPoJV2lnXxyxucigILMJOrQrVivv8= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index ce3c34d7b..a902d6cf8 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -7,7 +7,7 @@ replace github.com/ipfs/kubo => ../../ require ( github.com/Kubuxu/gocovmerge v0.0.0-20161216165753-7ecaa51963cd github.com/golangci/golangci-lint v1.49.0 - github.com/ipfs/boxo v0.10.0 + github.com/ipfs/boxo v0.10.1 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 github.com/ipfs/go-datastore v0.6.0 diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 431fcdbba..2840c44c2 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -413,8 +413,8 @@ github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NH github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.10.0 h1:tdDAxq8jrsbRkYoF+5Rcqyeb91hgWe2hp7iLu7ORZLY= -github.com/ipfs/boxo v0.10.0/go.mod h1:Fg+BnfxZ0RPzR0nOodzdIq3A7KgoWAOWsEIImrIQdBM= +github.com/ipfs/boxo v0.10.1 h1:q0ZhbyN6iNZLipd6txt1xotCiP/icfvdAQ4YpUi+cL4= +github.com/ipfs/boxo v0.10.1/go.mod h1:1qgKq45mPRCxf4ZPoJV2lnXxyxucigILMJOrQrVivv8= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.1.2 h1:GAjkfhVx1f4YTODS6Esrj1wt2HhrtwTnhEr+DyPUaJo= From f3ca75947f074a416e8e9e2de54e8dc18b5c2f70 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Tue, 20 Jun 2023 05:00:58 +0200 Subject: [PATCH 0740/1212] chore: bump go-libp2p-kad-dht for deadlock fix --- docs/examples/kubo-as-a-library/go.mod | 4 ++-- docs/examples/kubo-as-a-library/go.sum | 8 ++++---- go.mod | 4 ++-- go.sum | 8 ++++---- test/dependencies/go.mod | 2 +- test/dependencies/go.sum | 4 ++-- 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 27ecf1fae..0fda8880c 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -9,7 +9,7 @@ replace github.com/ipfs/kubo => ./../../.. require ( github.com/ipfs/boxo v0.10.1 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 - github.com/libp2p/go-libp2p v0.27.6 + github.com/libp2p/go-libp2p v0.27.7 github.com/multiformats/go-multiaddr v0.9.0 ) @@ -102,7 +102,7 @@ require ( github.com/libp2p/go-doh-resolver v0.4.0 // indirect github.com/libp2p/go-flow-metrics v0.1.0 // indirect github.com/libp2p/go-libp2p-asn-util v0.3.0 // indirect - github.com/libp2p/go-libp2p-kad-dht v0.24.1 // indirect + github.com/libp2p/go-libp2p-kad-dht v0.24.2 // indirect github.com/libp2p/go-libp2p-kbucket v0.6.3 // indirect github.com/libp2p/go-libp2p-pubsub v0.9.3 // indirect github.com/libp2p/go-libp2p-pubsub-router v0.6.0 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 319c81189..d18d571e4 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -487,14 +487,14 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.27.6 h1:KmGU5kskCaaerm53heqzfGOlrW2z8icZ+fnyqgrZs38= -github.com/libp2p/go-libp2p v0.27.6/go.mod h1:oMfQGTb9CHnrOuSM6yMmyK2lXz3qIhnkn2+oK3B1Y2g= +github.com/libp2p/go-libp2p v0.27.7 h1:nhMs03CRxslKkkK2uLuN8f72uwNkE6RJS1JFb3H9UIQ= +github.com/libp2p/go-libp2p v0.27.7/go.mod h1:oMfQGTb9CHnrOuSM6yMmyK2lXz3qIhnkn2+oK3B1Y2g= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= github.com/libp2p/go-libp2p-core v0.3.0/go.mod h1:ACp3DmS3/N64c2jDzcV429ukDpicbL6+TrrxANBjPGw= -github.com/libp2p/go-libp2p-kad-dht v0.24.1 h1:XH9vIWqc6e+w6z2Nvt9R5EhkBNnOQl7tyxxM6soejwo= -github.com/libp2p/go-libp2p-kad-dht v0.24.1/go.mod h1:1meiUvgOxfSPBx1pracS4VyYwmusorvv+TVRI3mXaJI= +github.com/libp2p/go-libp2p-kad-dht v0.24.2 h1:zd7myKBKCmtZBhI3I0zm8xBkb28v3gmSEtQfBdAdFwc= +github.com/libp2p/go-libp2p-kad-dht v0.24.2/go.mod h1:BShPzRbK6+fN3hk8a0WGAYKpb8m4k+DtchkqouGTrSg= github.com/libp2p/go-libp2p-kbucket v0.3.1/go.mod h1:oyjT5O7tS9CQurok++ERgc46YLwEpuGoFq9ubvoUOio= github.com/libp2p/go-libp2p-kbucket v0.6.3 h1:p507271wWzpy2f1XxPzCQG9NiN6R6lHL9GiSErbQQo0= github.com/libp2p/go-libp2p-kbucket v0.6.3/go.mod h1:RCseT7AH6eJWxxk2ol03xtP9pEHetYSPXOaJnOiD8i0= diff --git a/go.mod b/go.mod index 4ad1375b1..1b675c12e 100644 --- a/go.mod +++ b/go.mod @@ -45,9 +45,9 @@ require ( github.com/jbenet/goprocess v0.1.4 github.com/julienschmidt/httprouter v1.3.0 github.com/libp2p/go-doh-resolver v0.4.0 - github.com/libp2p/go-libp2p v0.27.6 + github.com/libp2p/go-libp2p v0.27.7 github.com/libp2p/go-libp2p-http v0.5.0 - github.com/libp2p/go-libp2p-kad-dht v0.24.1 + github.com/libp2p/go-libp2p-kad-dht v0.24.2 github.com/libp2p/go-libp2p-kbucket v0.6.3 github.com/libp2p/go-libp2p-pubsub v0.9.3 github.com/libp2p/go-libp2p-pubsub-router v0.6.0 diff --git a/go.sum b/go.sum index dcfbd3cb0..6ba018697 100644 --- a/go.sum +++ b/go.sum @@ -537,8 +537,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.27.6 h1:KmGU5kskCaaerm53heqzfGOlrW2z8icZ+fnyqgrZs38= -github.com/libp2p/go-libp2p v0.27.6/go.mod h1:oMfQGTb9CHnrOuSM6yMmyK2lXz3qIhnkn2+oK3B1Y2g= +github.com/libp2p/go-libp2p v0.27.7 h1:nhMs03CRxslKkkK2uLuN8f72uwNkE6RJS1JFb3H9UIQ= +github.com/libp2p/go-libp2p v0.27.7/go.mod h1:oMfQGTb9CHnrOuSM6yMmyK2lXz3qIhnkn2+oK3B1Y2g= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= @@ -547,8 +547,8 @@ github.com/libp2p/go-libp2p-gostream v0.6.0 h1:QfAiWeQRce6pqnYfmIVWJFXNdDyfiR/qk github.com/libp2p/go-libp2p-gostream v0.6.0/go.mod h1:Nywu0gYZwfj7Jc91PQvbGU8dIpqbQQkjWgDuOrFaRdA= github.com/libp2p/go-libp2p-http v0.5.0 h1:+x0AbLaUuLBArHubbbNRTsgWz0RjNTy6DJLOxQ3/QBc= github.com/libp2p/go-libp2p-http v0.5.0/go.mod h1:glh87nZ35XCQyFsdzZps6+F4HYI6DctVFY5u1fehwSg= -github.com/libp2p/go-libp2p-kad-dht v0.24.1 h1:XH9vIWqc6e+w6z2Nvt9R5EhkBNnOQl7tyxxM6soejwo= -github.com/libp2p/go-libp2p-kad-dht v0.24.1/go.mod h1:1meiUvgOxfSPBx1pracS4VyYwmusorvv+TVRI3mXaJI= +github.com/libp2p/go-libp2p-kad-dht v0.24.2 h1:zd7myKBKCmtZBhI3I0zm8xBkb28v3gmSEtQfBdAdFwc= +github.com/libp2p/go-libp2p-kad-dht v0.24.2/go.mod h1:BShPzRbK6+fN3hk8a0WGAYKpb8m4k+DtchkqouGTrSg= github.com/libp2p/go-libp2p-kbucket v0.3.1/go.mod h1:oyjT5O7tS9CQurok++ERgc46YLwEpuGoFq9ubvoUOio= github.com/libp2p/go-libp2p-kbucket v0.6.3 h1:p507271wWzpy2f1XxPzCQG9NiN6R6lHL9GiSErbQQo0= github.com/libp2p/go-libp2p-kbucket v0.6.3/go.mod h1:RCseT7AH6eJWxxk2ol03xtP9pEHetYSPXOaJnOiD8i0= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index a902d6cf8..f119128d2 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -19,7 +19,7 @@ require ( github.com/ipld/go-ipld-prime v0.20.0 github.com/jbenet/go-random v0.0.0-20190219211222-123a90aedc0c github.com/jbenet/go-random-files v0.0.0-20190219210431-31b3f20ebded - github.com/libp2p/go-libp2p v0.27.6 + github.com/libp2p/go-libp2p v0.27.7 github.com/multiformats/go-multiaddr v0.9.0 github.com/multiformats/go-multihash v0.2.3 gotest.tools/gotestsum v0.4.2 diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 2840c44c2..5c3a5ef94 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -565,8 +565,8 @@ github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38y github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.27.6 h1:KmGU5kskCaaerm53heqzfGOlrW2z8icZ+fnyqgrZs38= -github.com/libp2p/go-libp2p v0.27.6/go.mod h1:oMfQGTb9CHnrOuSM6yMmyK2lXz3qIhnkn2+oK3B1Y2g= +github.com/libp2p/go-libp2p v0.27.7 h1:nhMs03CRxslKkkK2uLuN8f72uwNkE6RJS1JFb3H9UIQ= +github.com/libp2p/go-libp2p v0.27.7/go.mod h1:oMfQGTb9CHnrOuSM6yMmyK2lXz3qIhnkn2+oK3B1Y2g= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= From 308274f886858acbe0055ec28f04657a99539969 Mon Sep 17 00:00:00 2001 From: Rod Vagg Date: Thu, 15 Jun 2023 06:45:34 +1000 Subject: [PATCH 0741/1212] feat!: dag import - don't pin roots by default (#9926) * feat!: dag import - don't pin roots by default Fixes: https://github.com/ipfs/kubo/issues/9765 * test(ipip-402): dag import this adds basic regression test that guards behavior around partial cars with or without pinning * docs(ipip-402): ipip and dag import changelog --------- Co-authored-by: Marcin Rataj --- core/commands/dag/dag.go | 13 +++--- docs/changelogs/v0.21.md | 35 ++++++++++++++-- .../README.md | 4 ++ .../partial-dag-scope-entity.car | Bin 0 -> 1711 bytes test/sharness/t0054-dag-car-import-export.sh | 38 ++++++++++++++---- test/sharness/t0109-gateway-web-_redirects.sh | 2 +- test/sharness/t0113-gateway-symlink.sh | 2 +- test/sharness/t0114-gateway-subdomains.sh | 2 +- test/sharness/t0115-gateway-dir-listing.sh | 2 +- test/sharness/t0116-gateway-cache.sh | 2 +- test/sharness/t0117-gateway-block.sh | 2 +- test/sharness/t0122-gateway-tar.sh | 6 +-- test/sharness/t0123-gateway-json-cbor.sh | 8 ++-- test/sharness/t0124-gateway-ipns-record.sh | 2 +- test/sharness/t0400-api-no-gateway.sh | 2 +- testplans/bitswap/main.go | 6 +-- 16 files changed, 92 insertions(+), 34 deletions(-) create mode 100644 test/sharness/t0054-dag-car-import-export-data/partial-dag-scope-entity.car diff --git a/core/commands/dag/dag.go b/core/commands/dag/dag.go index 41fde70e5..505f9770d 100644 --- a/core/commands/dag/dag.go +++ b/core/commands/dag/dag.go @@ -176,13 +176,16 @@ var DagImportCmd = &cmds.Command{ Tagline: "Import the contents of .car files", ShortDescription: ` 'ipfs dag import' imports all blocks present in supplied .car -( Content Address aRchive ) files, recursively pinning any roots -specified in the CAR file headers, unless --pin-roots is set to false. +( Content Address aRchive ) files, optionally recursively pinning any +roots specified in the CAR file headers if --pin-roots is set. Note: This command will import all blocks in the CAR file, not just those - reachable from the specified roots. However, these other blocks will - not be pinned and may be garbage collected later. + reachable from the specified roots. However, when using --pin-roots, + these other blocks will not be pinned and may be garbage collected + later. When not using --pin-roots, all blocks imported may be garbage + collected if no other pin operation is performed on them, or a root + that references them. The pinning of the roots happens after all car files are processed, permitting import of DAGs spanning multiple files. @@ -200,7 +203,7 @@ Specification of CAR formats: https://ipld.io/specs/transport/car/ cmds.FileArg("path", true, true, "The path of a .car file.").EnableStdin(), }, Options: []cmds.Option{ - cmds.BoolOption(pinRootsOptionName, "Pin optional roots listed in the .car headers after importing.").WithDefault(true), + cmds.BoolOption(pinRootsOptionName, "Pin optional roots listed in the .car headers after importing."), cmds.BoolOption(silentOptionName, "No output."), cmds.BoolOption(statsOptionName, "Output stats."), cmdutils.AllowBigBlockOption, diff --git a/docs/changelogs/v0.21.md b/docs/changelogs/v0.21.md index 1ac92adb7..0f5ea1cf6 100644 --- a/docs/changelogs/v0.21.md +++ b/docs/changelogs/v0.21.md @@ -11,8 +11,10 @@ - [`client/rpc` migration of `go-ipfs-http-client`](#clientrpc-migration-of-go-ipfs-http-client) - [Gateway: DAG-CBOR/-JSON previews and improved error pages](#gateway-dag-cbor-json-previews-and-improved-error-pages) - [Gateway: subdomain redirects are now `text/html`](#gateway-subdomain-redirects-are-now-texthtml) + - [Gateway: support for partial CAR export parameters (IPIP-402)](#gateway-support-for-partial-car-export-parameters-ipip-402) + - [`ipfs dag import` no longer pins by default](#ipfs-dag-import-no-longer-pins-by-default) - [`ipfs dag stat` deduping statistics](#ipfs-dag-stat-deduping-statistics) - - [Accelerated DHT Client is no longer experimental](#--empty-repo-is-now-the-default) + - [Accelerated DHT Client is no longer experimental](#accelerated-dht-client-is-no-longer-experimental) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -104,9 +106,36 @@ $ curl "https://subdomain-gw.example.net/ipfs/${cid}/" Rationale can be found in [kubo#9913](https://github.com/ipfs/kubo/pull/9913). -#### Gateway: support for CAR parameters of IPIP-402 +#### Gateway: support for partial CAR export parameters (IPIP-402) -The gateway now supports partial CAR export parameters as indicated in [IPIP-402](https://github.com/ipfs/specs/pull/402). +The gateway now supports optional CAR export parameters +`dag-scope=block|entity|all` and `entity-bytes=from:to` as specified in +[IPIP-402](https://github.com/ipfs/specs/pull/402). + +Batch block retrieval minimizes round trips, catering to the requirements of +light HTTP clients for directory enumeration, range requests, and content path +resolution. + +#### `ipfs dag import` no longer pins by default + +With the gateway now capable of handling partial CAR exports +([IPIP-402](https://github.com/ipfs/specs/pull/402)) and incomplete DAG CARs +becoming more prevalent, there have been changes to the pinning mode when using +`ipfs dag import`. + +Recursive pinning of the entire DAG within an imported CAR is now optional. To +explicitly attempt pinning the DAG referenced by any roots present in the CAR, +you can opt in by using the `--pin-roots` option. + +Pinning incomplete DAG will produce an error: + +```console +$ curl 'http://127.0.0.1:8080/ipns/docs.ipfs.tech?format=car&dag-scope=entity' > ./partial-entity.car # Kubo 0.21.0 with IPIP-402 (only root block of unixfs dir) +$ ipfs dag import --stats --pin-roots=true ./partial-entity.car +Error pinning QmPDC11yLAbVw3dX5jMeEuSdk4BiVjSd9X87zaYRdVjzW3 FAILED: block was not found locally (offline): ipld: could not find QmPDvrDAz2aHeLjPVQ4uh1neyknUmDpf1GsBzAbpFhS8ro +Imported 1 blocks (1618 bytes) +[exit code 1] +``` #### `ipfs dag stat` deduping statistics diff --git a/test/sharness/t0054-dag-car-import-export-data/README.md b/test/sharness/t0054-dag-car-import-export-data/README.md index 033f837a0..786f9ade0 100644 --- a/test/sharness/t0054-dag-car-import-export-data/README.md +++ b/test/sharness/t0054-dag-car-import-export-data/README.md @@ -26,3 +26,7 @@ - lotus_devnet_genesis_v2.car - generated with `car index lotus_testnet_export_128.car > lotus_testnet_export_128_v2.car` - install `go-car` CLI from https://github.com/ipld/go-car + +- partial-dag-scope-entity.car + - unixfs directory entity exported from gateway via `?format=car&dag-scope=entity` ([IPIP-402](https://github.com/ipfs/specs/pull/402)) + - CAR roots includes directory CID, but only the root block is included in the CAR, making the DAG incomplete diff --git a/test/sharness/t0054-dag-car-import-export-data/partial-dag-scope-entity.car b/test/sharness/t0054-dag-car-import-export-data/partial-dag-scope-entity.car new file mode 100644 index 0000000000000000000000000000000000000000..b149a18df7ceb2921d2c53dd40b919e8ce25cdd1 GIT binary patch literal 1711 zcmai#dpJ~i7{?7(86*5m+eu8rw2PQQlT>vBb@4xeT-|z4Hd*APwpN}Zz zasuDhF?%&f53m_;rG~=4INA}rju?Y9X{4%*!|E}$tKg@X|Hj|&dO)0jC~;Jd(Z(46 z|1nrhw*&0>*#*V=+N6fI__`2bNd(g(+ub&OnzXT{u6@*0U>5_dU`(i#qe8AgqLj-J zuG@k+8uIWIm>6oBLKPYG9C-!%pBgZ~Qs(xej2i^JhG>Na%c_3-l$}!%nw;~WB6Hm5 zX~^@f$Pp&+)+tGqjIW*<+~Hpd*H?vBPB@;_uN6(z+4ACU=#=Ar~rosUBE&e zkQ)_i(*J7E_kBbDmh*NXu0$-riYzX;FF*Qtx=)U)1X#o=l-_KVYKOBZBXmEhLw-DgUO^q0iq!7sD0uKxH`tvuB$Vr zAet{J!WkF}<)jzKjVUi&pMMG*x6!hg0bcO6wFB!M zB#lq4t43krJ*V>4U>hE=5Wxw$SK_+O)3{MjebIno7x|TW2RN|~ExteeXTr1EerE5@ zlh2-q?zK%>W!|H0mi^1}=V{2~(x8hW3JfN*wKu0klqTxvha*!JK(WpuP>391biQOJw zX4zMI9BRnCARbJCUPKvs&uHr%V~SaK!6X#J30NwH>RJJC*IoaG9V2;@Q(o^|mz^bN zGgf*HIY!>9Og5>lvQewC@tQS&fntPGE>sB!GCrUZ9yPP7h?f3J*9A#$l8`oK_1Aj# z^U@DcW0TM!v7YS~w%Gufq6!hto$ET6l9(Azagn(vi)Pu(ys@+pO5A>V@};^ZcT=~p zmV4;&JPk4qV(q|G24koQ!3o|5ob2~bA9(6y_B|P#s4XZB>k7+yJo~2X^IkzD_Q&y~ zsZK?Cxe*1Oy8w{k1WIOro4c!qJl_H!;|IzXy^5L-5i?)MBWAvhsk<#(tY@wrim#b! za=v*W>x1uS8knR|$~Pba0&31Pru<*O;+@REzb3Y1;pTy3OY}}C_l>cl z``oSp`bHHhh$qcd5>UZ5BWfeXo`Gf-jsA$Esmx+i%p;c9lG>oW3=8owj`2j$bhZ{4 zD-jW*M92k$PSm?o8#!dKa{OnGSGJ>vC=@iqZ%_0lKhV%l9kwhD#yk2IazIzgj5qeAe;s{199=ZEcvpi_jcxAaa5H8R8<^lIfyiLR zx1efIqLy>F`FPp&+q1$}gg#7Jey1(1UD7||XgoTaneG|h7;$R?n5z*fnK=kIPK8Q^ P/dev/null; done & while [[ -e spin.gc ]]; do ipfsi "$node" repo gc &>/dev/null; done & - ipfsi "$node" dag import "$@" 2>&1 && ipfsi "$node" repo verify &>/dev/null + ipfsi "$node" dag import --pin-roots "$@" 2>&1 && ipfsi "$node" repo verify &>/dev/null result=$? rm -f spin.gc &>/dev/null @@ -117,7 +117,7 @@ EOE ' test_expect_success "import/pin naked roots only, relying on local blockstore having all the data" ' - ipfsi 1 dag import --stats --enc=json ../t0054-dag-car-import-export-data/combined_naked_roots_genesis_and_128.car \ + ipfsi 1 dag import --stats --enc=json --pin-roots ../t0054-dag-car-import-export-data/combined_naked_roots_genesis_and_128.car \ > naked_import_result_json_actual ' @@ -197,14 +197,14 @@ EOE head -3 multiroot_import_json_stats_expected > multiroot_import_json_expected test_expect_success "multiroot import works (--enc=json)" ' - ipfs dag import --enc=json ../t0054-dag-car-import-export-data/lotus_testnet_export_256_multiroot.car > multiroot_import_json_actual + ipfs dag import --enc=json --pin-roots ../t0054-dag-car-import-export-data/lotus_testnet_export_256_multiroot.car > multiroot_import_json_actual ' test_expect_success "multiroot import expected output" ' test_cmp_sorted multiroot_import_json_expected multiroot_import_json_actual ' test_expect_success "multiroot import works with --stats" ' - ipfs dag import --stats --enc=json ../t0054-dag-car-import-export-data/lotus_testnet_export_256_multiroot.car > multiroot_import_json_actual + ipfs dag import --stats --enc=json --pin-roots ../t0054-dag-car-import-export-data/lotus_testnet_export_256_multiroot.car > multiroot_import_json_actual ' test_expect_success "multiroot import expected output" ' test_cmp_sorted multiroot_import_json_stats_expected multiroot_import_json_actual @@ -215,18 +215,18 @@ cat >pin_import_expected << EOE {"Stats":{"BlockCount":1198,"BlockBytesCount":468513}} EOE test_expect_success "pin-less import works" ' - ipfs dag import --stats --enc=json --pin-roots=false \ + ipfs dag import --stats --enc=json \ ../t0054-dag-car-import-export-data/lotus_devnet_genesis.car \ ../t0054-dag-car-import-export-data/lotus_testnet_export_128.car \ > no-pin_import_actual ' -test_expect_success "expected no pins on --pin-roots=false" ' +test_expect_success "expected no pins on" ' test_cmp pin_import_expected no-pin_import_actual ' test_expect_success "naked root import works" ' - ipfs dag import --stats --enc=json ../t0054-dag-car-import-export-data/combined_naked_roots_genesis_and_128.car \ + ipfs dag import --stats --enc=json --pin-roots ../t0054-dag-car-import-export-data/combined_naked_roots_genesis_and_128.car \ > naked_root_import_json_actual ' test_expect_success "naked root import expected output" ' @@ -253,7 +253,7 @@ cat > version_2_import_expected << EOE EOE test_expect_success "version 2 import" ' - ipfs dag import --stats --enc=json \ + ipfs dag import --stats --enc=json --pin-roots \ ../t0054-dag-car-import-export-data/lotus_testnet_export_128_v2.car \ ../t0054-dag-car-import-export-data/lotus_devnet_genesis_v2.car \ > version_2_import_actual @@ -291,4 +291,26 @@ test_expect_success "'ipfs dag import' decode IPLD 'cbor' codec works" ' rm cbor.car ' +# IPIP-402 +cat > partial_nopin_import_expected << EOE +{"Stats":{"BlockCount":1,"BlockBytesCount":1618}} +EOE +test_expect_success "'ipfs dag import' without pinning works fine with incomplete DAG (unixfs dir exported as dag-scope=entity from IPIP-402)" ' + ipfs dag import --stats --enc=json --pin-roots=false ../t0054-dag-car-import-export-data/partial-dag-scope-entity.car >partial_nopin_import_out 2>&1 && + test_cmp partial_nopin_import_expected partial_nopin_import_out +' +test_expect_success "'ipfs dag import' with no params in CLI mode produces exit code 0 (unixfs dir exported as dag-scope=entity from IPIP-402)" ' + test_expect_code 0 ipfs dag import ../t0054-dag-car-import-export-data/partial-dag-scope-entity.car +' + +test_expect_success "'ipfs dag import' with pinning errors due to incomplete DAG (unixfs dir exported as dag-scope=entity from IPIP-402)" ' + ipfs dag import --stats --enc=json --pin-roots=true ../t0054-dag-car-import-export-data/partial-dag-scope-entity.car >partial_pin_import_out 2>&1 && + test_should_contain "\"PinErrorMsg\":\"block was not found locally" partial_pin_import_out +' + +test_expect_success "'ipfs dag import' pin error in default CLI mode produces exit code 1 (unixfs dir exported as dag-scope=entity from IPIP-402)" ' + test_expect_code 1 ipfs dag import --pin-roots ../t0054-dag-car-import-export-data/partial-dag-scope-entity.car >partial_pin_import_out 2>&1 && + test_should_contain "Error: pinning root \"QmPDC11yLAbVw3dX5jMeEuSdk4BiVjSd9X87zaYRdVjzW3\" FAILED: block was not found locally" partial_pin_import_out +' + test_done diff --git a/test/sharness/t0109-gateway-web-_redirects.sh b/test/sharness/t0109-gateway-web-_redirects.sh index 9ebfb911e..0bc2a23b6 100755 --- a/test/sharness/t0109-gateway-web-_redirects.sh +++ b/test/sharness/t0109-gateway-web-_redirects.sh @@ -14,7 +14,7 @@ test_launch_ipfs_daemon # Import test case # Run `ipfs cat /ipfs/$REDIRECTS_DIR_CID/_redirects` to see sample _redirects file test_expect_success "Add the _redirects file test directory" ' - ipfs dag import ../t0109-gateway-web-_redirects-data/redirects.car + ipfs dag import --pin-roots ../t0109-gateway-web-_redirects-data/redirects.car ' CAR_ROOT_CID=QmQyqMY5vUBSbSxyitJqthgwZunCQjDVtNd8ggVCxzuPQ4 diff --git a/test/sharness/t0113-gateway-symlink.sh b/test/sharness/t0113-gateway-symlink.sh index 29e5b960d..2cb4f3195 100755 --- a/test/sharness/t0113-gateway-symlink.sh +++ b/test/sharness/t0113-gateway-symlink.sh @@ -12,7 +12,7 @@ test_launch_ipfs_daemon # Import test case # See the static fixtures in ./t0113-gateway-symlink/ test_expect_success "Add the test directory with symlinks" ' - ipfs dag import ../t0113-gateway-symlink/testfiles.car + ipfs dag import --pin-roots ../t0113-gateway-symlink/testfiles.car ' ROOT_DIR_CID=QmWvY6FaqFMS89YAQ9NAPjVP4WZKA1qbHbicc9HeSKQTgt # ./testfiles/ diff --git a/test/sharness/t0114-gateway-subdomains.sh b/test/sharness/t0114-gateway-subdomains.sh index 1d19a6570..8be102c4f 100755 --- a/test/sharness/t0114-gateway-subdomains.sh +++ b/test/sharness/t0114-gateway-subdomains.sh @@ -113,7 +113,7 @@ IPNS_ED25519_B58MH=12D3KooWLQzUv2FHWGVPXTXSZpdHs7oHbXub2G5WC8Tx4NQhyd2d IPNS_ED25519_B36CID=k51qzi5uqu5dk3v4rmjber23h16xnr23bsggmqqil9z2gduiis5se8dht36dam test_expect_success "Add the test fixtures" ' - ipfs dag import ../t0114-gateway-subdomains/fixtures.car && + ipfs dag import --pin-roots ../t0114-gateway-subdomains/fixtures.car && ipfs routing put --allow-offline /ipns/${RSA_KEY} ../t0114-gateway-subdomains/${RSA_KEY}.ipns-record && ipfs routing put --allow-offline /ipns/${ED25519_KEY} ../t0114-gateway-subdomains/${ED25519_KEY}.ipns-record ' diff --git a/test/sharness/t0115-gateway-dir-listing.sh b/test/sharness/t0115-gateway-dir-listing.sh index cf95bf4b0..1ce0861b2 100755 --- a/test/sharness/t0115-gateway-dir-listing.sh +++ b/test/sharness/t0115-gateway-dir-listing.sh @@ -21,7 +21,7 @@ test_launch_ipfs_daemon_without_network # Import test case # See the static fixtures in ./t0115-gateway-dir-listing/ test_expect_success "Add the test directory" ' - ipfs dag import ../t0115-gateway-dir-listing/fixtures.car + ipfs dag import --pin-roots ../t0115-gateway-dir-listing/fixtures.car ' DIR_CID=bafybeig6ka5mlwkl4subqhaiatalkcleo4jgnr3hqwvpmsqfca27cijp3i # ./rootDir/ FILE_CID=bafkreialihlqnf5uwo4byh4n3cmwlntwqzxxs2fg5vanqdi3d7tb2l5xkm # ./rootDir/ą/ę/file-źł.txt diff --git a/test/sharness/t0116-gateway-cache.sh b/test/sharness/t0116-gateway-cache.sh index b2e6b3af3..2c0f2f833 100755 --- a/test/sharness/t0116-gateway-cache.sh +++ b/test/sharness/t0116-gateway-cache.sh @@ -35,7 +35,7 @@ TEST_IPNS_ID=k51qzi5uqu5dlxdsdu5fpuu7h69wu4ohp32iwm9pdt9nq3y5rpn3ln9j12zfhe # Import test case # See the static fixtures in ./t0116-gateway-cache/ test_expect_success "Add the test directory" ' - ipfs dag import ../t0116-gateway-cache/fixtures.car + ipfs dag import --pin-roots ../t0116-gateway-cache/fixtures.car ipfs routing put --allow-offline /ipns/${TEST_IPNS_ID} ../t0116-gateway-cache/${TEST_IPNS_ID}.ipns-record ' diff --git a/test/sharness/t0117-gateway-block.sh b/test/sharness/t0117-gateway-block.sh index b21425bc4..a4a661bd1 100755 --- a/test/sharness/t0117-gateway-block.sh +++ b/test/sharness/t0117-gateway-block.sh @@ -10,7 +10,7 @@ test_launch_ipfs_daemon_without_network # Import test case # See the static fixtures in ./t0117-gateway-block/ test_expect_success "Add the dir test directory" ' - ipfs dag import ../t0117-gateway-block/fixtures.car + ipfs dag import --pin-roots ../t0117-gateway-block/fixtures.car ' ROOT_DIR_CID=bafybeie72edlprgtlwwctzljf6gkn2wnlrddqjbkxo3jomh4n7omwblxly # ./ FILE_CID=bafkreihhpc5y2pqvl5rbe5uuyhqjouybfs3rvlmisccgzue2kkt5zq6upq # ./dir/ascii.txt diff --git a/test/sharness/t0122-gateway-tar.sh b/test/sharness/t0122-gateway-tar.sh index 20cc1bf4c..435623547 100755 --- a/test/sharness/t0122-gateway-tar.sh +++ b/test/sharness/t0122-gateway-tar.sh @@ -13,7 +13,7 @@ INSIDE_ROOT_CID="bafybeibfevfxlvxp5vxobr5oapczpf7resxnleb7tkqmdorc4gl5cdva3y" # Import test case # See the static fixtures in ./t0122-gateway-tar/ test_expect_success "Add the test directory" ' - ipfs dag import ../t0122-gateway-tar/fixtures.car + ipfs dag import --pin-roots ../t0122-gateway-tar/fixtures.car ' DIR_CID=bafybeig6ka5mlwkl4subqhaiatalkcleo4jgnr3hqwvpmsqfca27cijp3i # ./rootDir FILE_CID=bafkreialihlqnf5uwo4byh4n3cmwlntwqzxxs2fg5vanqdi3d7tb2l5xkm # ./rootDir/ą/ę/file-źł.txt @@ -63,9 +63,9 @@ test_expect_success "GET TAR with explicit ?filename= succeeds with modified Con " test_expect_success "Add CARs with relative paths to test with" ' - ipfs dag import ../t0122-gateway-tar/outside-root.car > import_output && + ipfs dag import --pin-roots ../t0122-gateway-tar/outside-root.car > import_output && test_should_contain $OUTSIDE_ROOT_CID import_output && - ipfs dag import ../t0122-gateway-tar/inside-root.car > import_output && + ipfs dag import --pin-roots ../t0122-gateway-tar/inside-root.car > import_output && test_should_contain $INSIDE_ROOT_CID import_output ' diff --git a/test/sharness/t0123-gateway-json-cbor.sh b/test/sharness/t0123-gateway-json-cbor.sh index b4b0446ff..323d23d58 100755 --- a/test/sharness/t0123-gateway-json-cbor.sh +++ b/test/sharness/t0123-gateway-json-cbor.sh @@ -10,7 +10,7 @@ test_launch_ipfs_daemon_without_network # Import test case # See the static fixtures in ./t0123-gateway-json-cbor/ test_expect_success "Add the test directory" ' - ipfs dag import ../t0123-gateway-json-cbor/fixtures.car + ipfs dag import --pin-roots ../t0123-gateway-json-cbor/fixtures.car ' DIR_CID=bafybeiafyvqlazbbbtjnn6how5d6h6l6rxbqc4qgpbmteaiskjrffmyy4a # ./rootDir FILE_JSON_CID=bafkreibrppizs3g7axs2jdlnjua6vgpmltv7k72l7v7sa6mmht6mne3qqe # ./rootDir/ą/ę/t.json @@ -155,11 +155,11 @@ DAG_JSON_TRAVERSAL_CID="baguqeeram5ujjqrwheyaty3w5gdsmoz6vittchvhk723jjqxk7hakxk DAG_PB_CID="bafybeiegxwlgmoh2cny7qlolykdf7aq7g6dlommarldrbm7c4hbckhfcke" test_expect_success "Add CARs for path traversal and DAG-PB representation tests" ' - ipfs dag import ../t0123-gateway-json-cbor/dag-cbor-traversal.car > import_output && + ipfs dag import --pin-roots ../t0123-gateway-json-cbor/dag-cbor-traversal.car > import_output && test_should_contain $DAG_CBOR_TRAVERSAL_CID import_output && - ipfs dag import ../t0123-gateway-json-cbor/dag-json-traversal.car > import_output && + ipfs dag import --pin-roots ../t0123-gateway-json-cbor/dag-json-traversal.car > import_output && test_should_contain $DAG_JSON_TRAVERSAL_CID import_output && - ipfs dag import ../t0123-gateway-json-cbor/dag-pb.car > import_output && + ipfs dag import --pin-roots ../t0123-gateway-json-cbor/dag-pb.car > import_output && test_should_contain $DAG_PB_CID import_output ' diff --git a/test/sharness/t0124-gateway-ipns-record.sh b/test/sharness/t0124-gateway-ipns-record.sh index 1d05b5698..605252c0f 100755 --- a/test/sharness/t0124-gateway-ipns-record.sh +++ b/test/sharness/t0124-gateway-ipns-record.sh @@ -12,7 +12,7 @@ test_launch_ipfs_daemon IPNS_KEY=k51qzi5uqu5dh71qgwangrt6r0nd4094i88nsady6qgd1dhjcyfsaqmpp143ab FILE_CID=bafkreidfdrlkeq4m4xnxuyx6iae76fdm4wgl5d4xzsb77ixhyqwumhz244 # A file containing Hello IPFS test_expect_success "Add the test directory & IPNS records" ' - ipfs dag import ../t0124-gateway-ipns-record/fixtures.car && + ipfs dag import --pin-roots ../t0124-gateway-ipns-record/fixtures.car && ipfs routing put /ipns/${IPNS_KEY} ../t0124-gateway-ipns-record/${IPNS_KEY}.ipns-record ' diff --git a/test/sharness/t0400-api-no-gateway.sh b/test/sharness/t0400-api-no-gateway.sh index d0daeece3..7518db427 100755 --- a/test/sharness/t0400-api-no-gateway.sh +++ b/test/sharness/t0400-api-no-gateway.sh @@ -13,7 +13,7 @@ test_init_ipfs # Import test case # See the static fixtures in ./t0400-api-no-gateway/ test_expect_success "Add the test directory" ' - ipfs dag import ../t0400-api-no-gateway/fixtures.car + ipfs dag import --pin-roots ../t0400-api-no-gateway/fixtures.car ' HASH=QmNYERzV2LfD2kkfahtfv44ocHzEFK1sLBaE7zdcYT2GAZ # a file containing the string "testing" diff --git a/testplans/bitswap/main.go b/testplans/bitswap/main.go index aa98d4f31..0af2ad95c 100644 --- a/testplans/bitswap/main.go +++ b/testplans/bitswap/main.go @@ -12,14 +12,14 @@ import ( "github.com/testground/sdk-go/runtime" "github.com/testground/sdk-go/sync" - bitswap "github.com/ipfs/go-libipfs/bitswap" - bsnet "github.com/ipfs/go-libipfs/bitswap/network" - block "github.com/ipfs/go-libipfs/blocks" "github.com/ipfs/go-cid" datastore "github.com/ipfs/go-datastore" blockstore "github.com/ipfs/go-ipfs-blockstore" exchange "github.com/ipfs/go-ipfs-exchange-interface" bstats "github.com/ipfs/go-ipfs-regression/bitswap" + bitswap "github.com/ipfs/go-libipfs/bitswap" + bsnet "github.com/ipfs/go-libipfs/bitswap/network" + block "github.com/ipfs/go-libipfs/blocks" "github.com/libp2p/go-libp2p" dht "github.com/libp2p/go-libp2p-kad-dht" "github.com/libp2p/go-libp2p/core/host" From 91835546c7cc677d99dc95a342138dc1ee28d12a Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Thu, 15 Jun 2023 14:53:45 +0200 Subject: [PATCH 0742/1212] docs: fix 0.21 changelog --- CHANGELOG.md | 1 + docs/changelogs/v0.21.md | 22 ---------------------- docs/changelogs/v0.22.md | 40 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 41 insertions(+), 22 deletions(-) create mode 100644 docs/changelogs/v0.22.md diff --git a/CHANGELOG.md b/CHANGELOG.md index b99ff4f15..0138eb231 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ # Kubo Changelogs +- [v0.22](docs/changelogs/v0.22.md) - [v0.21](docs/changelogs/v0.21.md) - [v0.20](docs/changelogs/v0.20.md) - [v0.19](docs/changelogs/v0.19.md) diff --git a/docs/changelogs/v0.21.md b/docs/changelogs/v0.21.md index 0f5ea1cf6..394059472 100644 --- a/docs/changelogs/v0.21.md +++ b/docs/changelogs/v0.21.md @@ -12,7 +12,6 @@ - [Gateway: DAG-CBOR/-JSON previews and improved error pages](#gateway-dag-cbor-json-previews-and-improved-error-pages) - [Gateway: subdomain redirects are now `text/html`](#gateway-subdomain-redirects-are-now-texthtml) - [Gateway: support for partial CAR export parameters (IPIP-402)](#gateway-support-for-partial-car-export-parameters-ipip-402) - - [`ipfs dag import` no longer pins by default](#ipfs-dag-import-no-longer-pins-by-default) - [`ipfs dag stat` deduping statistics](#ipfs-dag-stat-deduping-statistics) - [Accelerated DHT Client is no longer experimental](#accelerated-dht-client-is-no-longer-experimental) - [📝 Changelog](#-changelog) @@ -116,27 +115,6 @@ Batch block retrieval minimizes round trips, catering to the requirements of light HTTP clients for directory enumeration, range requests, and content path resolution. -#### `ipfs dag import` no longer pins by default - -With the gateway now capable of handling partial CAR exports -([IPIP-402](https://github.com/ipfs/specs/pull/402)) and incomplete DAG CARs -becoming more prevalent, there have been changes to the pinning mode when using -`ipfs dag import`. - -Recursive pinning of the entire DAG within an imported CAR is now optional. To -explicitly attempt pinning the DAG referenced by any roots present in the CAR, -you can opt in by using the `--pin-roots` option. - -Pinning incomplete DAG will produce an error: - -```console -$ curl 'http://127.0.0.1:8080/ipns/docs.ipfs.tech?format=car&dag-scope=entity' > ./partial-entity.car # Kubo 0.21.0 with IPIP-402 (only root block of unixfs dir) -$ ipfs dag import --stats --pin-roots=true ./partial-entity.car -Error pinning QmPDC11yLAbVw3dX5jMeEuSdk4BiVjSd9X87zaYRdVjzW3 FAILED: block was not found locally (offline): ipld: could not find QmPDvrDAz2aHeLjPVQ4uh1neyknUmDpf1GsBzAbpFhS8ro -Imported 1 blocks (1618 bytes) -[exit code 1] -``` - #### `ipfs dag stat` deduping statistics `ipfs dat stat` now accept multiple CIDs and will dump advanced statistics diff --git a/docs/changelogs/v0.22.md b/docs/changelogs/v0.22.md new file mode 100644 index 000000000..aba6a4ac7 --- /dev/null +++ b/docs/changelogs/v0.22.md @@ -0,0 +1,40 @@ +# Kubo changelog v0.22 + +- [v0.22.0](#v0220) + +## v0.22.0 + +- [Overview](#overview) +- [🔦 Highlights](#-highlights) + - [`ipfs dag import` no longer pins by default](#ipfs-dag-import-no-longer-pins-by-default) +- [📝 Changelog](#-changelog) +- [👨‍👩‍👧‍👦 Contributors](#-contributors) + +### Overview + +### 🔦 Highlights + +#### `ipfs dag import` no longer pins by default + +With the gateway now capable of handling partial CAR exports +([IPIP-402](https://github.com/ipfs/specs/pull/402)) and incomplete DAG CARs +becoming more prevalent, there have been changes to the pinning mode when using +`ipfs dag import`. + +Recursive pinning of the entire DAG within an imported CAR is now optional. To +explicitly attempt pinning the DAG referenced by any roots present in the CAR, +you can opt in by using the `--pin-roots` option. + +Pinning incomplete DAG will produce an error: + +```console +$ curl 'http://127.0.0.1:8080/ipns/docs.ipfs.tech?format=car&dag-scope=entity' > ./partial-entity.car # Kubo 0.21.0 with IPIP-402 (only root block of unixfs dir) +$ ipfs dag import --stats --pin-roots=true ./partial-entity.car +Error pinning QmPDC11yLAbVw3dX5jMeEuSdk4BiVjSd9X87zaYRdVjzW3 FAILED: block was not found locally (offline): ipld: could not find QmPDvrDAz2aHeLjPVQ4uh1neyknUmDpf1GsBzAbpFhS8ro +Imported 1 blocks (1618 bytes) +[exit code 1] +``` + +### 📝 Changelog + +### 👨‍👩‍👧‍👦 Contributors From 02fb0a4ad427c8993f2be77ae9db6bab3bd9dbb4 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Thu, 15 Jun 2023 16:41:59 +0200 Subject: [PATCH 0743/1212] cmds/dag/import: pin roots by default (#9966) This is a partial revert of b685355ca8ceaaf55619ee3b8cffa612a4106569. Closes #9765 with compromise agreed in https://github.com/ipfs/kubo/issues/9765#issuecomment-1593117410 --- core/commands/dag/dag.go | 13 +++++------- docs/changelogs/v0.22.md | 22 -------------------- test/sharness/t0054-dag-car-import-export.sh | 21 ++++++++----------- test/sharness/t0124-gateway-ipns-record.sh | 2 +- test/sharness/t0400-api-no-gateway.sh | 2 +- 5 files changed, 16 insertions(+), 44 deletions(-) diff --git a/core/commands/dag/dag.go b/core/commands/dag/dag.go index 505f9770d..41fde70e5 100644 --- a/core/commands/dag/dag.go +++ b/core/commands/dag/dag.go @@ -176,16 +176,13 @@ var DagImportCmd = &cmds.Command{ Tagline: "Import the contents of .car files", ShortDescription: ` 'ipfs dag import' imports all blocks present in supplied .car -( Content Address aRchive ) files, optionally recursively pinning any -roots specified in the CAR file headers if --pin-roots is set. +( Content Address aRchive ) files, recursively pinning any roots +specified in the CAR file headers, unless --pin-roots is set to false. Note: This command will import all blocks in the CAR file, not just those - reachable from the specified roots. However, when using --pin-roots, - these other blocks will not be pinned and may be garbage collected - later. When not using --pin-roots, all blocks imported may be garbage - collected if no other pin operation is performed on them, or a root - that references them. + reachable from the specified roots. However, these other blocks will + not be pinned and may be garbage collected later. The pinning of the roots happens after all car files are processed, permitting import of DAGs spanning multiple files. @@ -203,7 +200,7 @@ Specification of CAR formats: https://ipld.io/specs/transport/car/ cmds.FileArg("path", true, true, "The path of a .car file.").EnableStdin(), }, Options: []cmds.Option{ - cmds.BoolOption(pinRootsOptionName, "Pin optional roots listed in the .car headers after importing."), + cmds.BoolOption(pinRootsOptionName, "Pin optional roots listed in the .car headers after importing.").WithDefault(true), cmds.BoolOption(silentOptionName, "No output."), cmds.BoolOption(statsOptionName, "Output stats."), cmdutils.AllowBigBlockOption, diff --git a/docs/changelogs/v0.22.md b/docs/changelogs/v0.22.md index aba6a4ac7..6fabdad7d 100644 --- a/docs/changelogs/v0.22.md +++ b/docs/changelogs/v0.22.md @@ -6,7 +6,6 @@ - [Overview](#overview) - [🔦 Highlights](#-highlights) - - [`ipfs dag import` no longer pins by default](#ipfs-dag-import-no-longer-pins-by-default) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -14,27 +13,6 @@ ### 🔦 Highlights -#### `ipfs dag import` no longer pins by default - -With the gateway now capable of handling partial CAR exports -([IPIP-402](https://github.com/ipfs/specs/pull/402)) and incomplete DAG CARs -becoming more prevalent, there have been changes to the pinning mode when using -`ipfs dag import`. - -Recursive pinning of the entire DAG within an imported CAR is now optional. To -explicitly attempt pinning the DAG referenced by any roots present in the CAR, -you can opt in by using the `--pin-roots` option. - -Pinning incomplete DAG will produce an error: - -```console -$ curl 'http://127.0.0.1:8080/ipns/docs.ipfs.tech?format=car&dag-scope=entity' > ./partial-entity.car # Kubo 0.21.0 with IPIP-402 (only root block of unixfs dir) -$ ipfs dag import --stats --pin-roots=true ./partial-entity.car -Error pinning QmPDC11yLAbVw3dX5jMeEuSdk4BiVjSd9X87zaYRdVjzW3 FAILED: block was not found locally (offline): ipld: could not find QmPDvrDAz2aHeLjPVQ4uh1neyknUmDpf1GsBzAbpFhS8ro -Imported 1 blocks (1618 bytes) -[exit code 1] -``` - ### 📝 Changelog ### 👨‍👩‍👧‍👦 Contributors diff --git a/test/sharness/t0054-dag-car-import-export.sh b/test/sharness/t0054-dag-car-import-export.sh index 65195cb05..0482f24d9 100755 --- a/test/sharness/t0054-dag-car-import-export.sh +++ b/test/sharness/t0054-dag-car-import-export.sh @@ -41,7 +41,7 @@ do_import() { while [[ -e spin.gc ]]; do ipfsi "$node" repo gc &>/dev/null; done & while [[ -e spin.gc ]]; do ipfsi "$node" repo gc &>/dev/null; done & - ipfsi "$node" dag import --pin-roots "$@" 2>&1 && ipfsi "$node" repo verify &>/dev/null + ipfsi "$node" dag import "$@" 2>&1 && ipfsi "$node" repo verify &>/dev/null result=$? rm -f spin.gc &>/dev/null @@ -117,7 +117,7 @@ EOE ' test_expect_success "import/pin naked roots only, relying on local blockstore having all the data" ' - ipfsi 1 dag import --stats --enc=json --pin-roots ../t0054-dag-car-import-export-data/combined_naked_roots_genesis_and_128.car \ + ipfsi 1 dag import --stats --enc=json ../t0054-dag-car-import-export-data/combined_naked_roots_genesis_and_128.car \ > naked_import_result_json_actual ' @@ -197,14 +197,14 @@ EOE head -3 multiroot_import_json_stats_expected > multiroot_import_json_expected test_expect_success "multiroot import works (--enc=json)" ' - ipfs dag import --enc=json --pin-roots ../t0054-dag-car-import-export-data/lotus_testnet_export_256_multiroot.car > multiroot_import_json_actual + ipfs dag import --enc=json ../t0054-dag-car-import-export-data/lotus_testnet_export_256_multiroot.car > multiroot_import_json_actual ' test_expect_success "multiroot import expected output" ' test_cmp_sorted multiroot_import_json_expected multiroot_import_json_actual ' test_expect_success "multiroot import works with --stats" ' - ipfs dag import --stats --enc=json --pin-roots ../t0054-dag-car-import-export-data/lotus_testnet_export_256_multiroot.car > multiroot_import_json_actual + ipfs dag import --stats --enc=json ../t0054-dag-car-import-export-data/lotus_testnet_export_256_multiroot.car > multiroot_import_json_actual ' test_expect_success "multiroot import expected output" ' test_cmp_sorted multiroot_import_json_stats_expected multiroot_import_json_actual @@ -215,18 +215,18 @@ cat >pin_import_expected << EOE {"Stats":{"BlockCount":1198,"BlockBytesCount":468513}} EOE test_expect_success "pin-less import works" ' - ipfs dag import --stats --enc=json \ + ipfs dag import --stats --enc=json --pin-roots=false \ ../t0054-dag-car-import-export-data/lotus_devnet_genesis.car \ ../t0054-dag-car-import-export-data/lotus_testnet_export_128.car \ > no-pin_import_actual ' -test_expect_success "expected no pins on" ' +test_expect_success "expected no pins on --pin-roots=false" ' test_cmp pin_import_expected no-pin_import_actual ' test_expect_success "naked root import works" ' - ipfs dag import --stats --enc=json --pin-roots ../t0054-dag-car-import-export-data/combined_naked_roots_genesis_and_128.car \ + ipfs dag import --stats --enc=json ../t0054-dag-car-import-export-data/combined_naked_roots_genesis_and_128.car \ > naked_root_import_json_actual ' test_expect_success "naked root import expected output" ' @@ -253,7 +253,7 @@ cat > version_2_import_expected << EOE EOE test_expect_success "version 2 import" ' - ipfs dag import --stats --enc=json --pin-roots \ + ipfs dag import --stats --enc=json \ ../t0054-dag-car-import-export-data/lotus_testnet_export_128_v2.car \ ../t0054-dag-car-import-export-data/lotus_devnet_genesis_v2.car \ > version_2_import_actual @@ -299,9 +299,6 @@ test_expect_success "'ipfs dag import' without pinning works fine with incomplet ipfs dag import --stats --enc=json --pin-roots=false ../t0054-dag-car-import-export-data/partial-dag-scope-entity.car >partial_nopin_import_out 2>&1 && test_cmp partial_nopin_import_expected partial_nopin_import_out ' -test_expect_success "'ipfs dag import' with no params in CLI mode produces exit code 0 (unixfs dir exported as dag-scope=entity from IPIP-402)" ' - test_expect_code 0 ipfs dag import ../t0054-dag-car-import-export-data/partial-dag-scope-entity.car -' test_expect_success "'ipfs dag import' with pinning errors due to incomplete DAG (unixfs dir exported as dag-scope=entity from IPIP-402)" ' ipfs dag import --stats --enc=json --pin-roots=true ../t0054-dag-car-import-export-data/partial-dag-scope-entity.car >partial_pin_import_out 2>&1 && @@ -309,7 +306,7 @@ test_expect_success "'ipfs dag import' with pinning errors due to incomplete DAG ' test_expect_success "'ipfs dag import' pin error in default CLI mode produces exit code 1 (unixfs dir exported as dag-scope=entity from IPIP-402)" ' - test_expect_code 1 ipfs dag import --pin-roots ../t0054-dag-car-import-export-data/partial-dag-scope-entity.car >partial_pin_import_out 2>&1 && + test_expect_code 1 ipfs dag import ../t0054-dag-car-import-export-data/partial-dag-scope-entity.car >partial_pin_import_out 2>&1 && test_should_contain "Error: pinning root \"QmPDC11yLAbVw3dX5jMeEuSdk4BiVjSd9X87zaYRdVjzW3\" FAILED: block was not found locally" partial_pin_import_out ' diff --git a/test/sharness/t0124-gateway-ipns-record.sh b/test/sharness/t0124-gateway-ipns-record.sh index 605252c0f..1d05b5698 100755 --- a/test/sharness/t0124-gateway-ipns-record.sh +++ b/test/sharness/t0124-gateway-ipns-record.sh @@ -12,7 +12,7 @@ test_launch_ipfs_daemon IPNS_KEY=k51qzi5uqu5dh71qgwangrt6r0nd4094i88nsady6qgd1dhjcyfsaqmpp143ab FILE_CID=bafkreidfdrlkeq4m4xnxuyx6iae76fdm4wgl5d4xzsb77ixhyqwumhz244 # A file containing Hello IPFS test_expect_success "Add the test directory & IPNS records" ' - ipfs dag import --pin-roots ../t0124-gateway-ipns-record/fixtures.car && + ipfs dag import ../t0124-gateway-ipns-record/fixtures.car && ipfs routing put /ipns/${IPNS_KEY} ../t0124-gateway-ipns-record/${IPNS_KEY}.ipns-record ' diff --git a/test/sharness/t0400-api-no-gateway.sh b/test/sharness/t0400-api-no-gateway.sh index 7518db427..d0daeece3 100755 --- a/test/sharness/t0400-api-no-gateway.sh +++ b/test/sharness/t0400-api-no-gateway.sh @@ -13,7 +13,7 @@ test_init_ipfs # Import test case # See the static fixtures in ./t0400-api-no-gateway/ test_expect_success "Add the test directory" ' - ipfs dag import --pin-roots ../t0400-api-no-gateway/fixtures.car + ipfs dag import ../t0400-api-no-gateway/fixtures.car ' HASH=QmNYERzV2LfD2kkfahtfv44ocHzEFK1sLBaE7zdcYT2GAZ # a file containing the string "testing" From 9fac88260c3f0f9b99de0c989704dc6dcc983f03 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 15 Jun 2023 17:17:13 +0200 Subject: [PATCH 0744/1212] chore(deps): bump docker/build-push-action from 2 to 4 (#9954) Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 2 to 4. - [Release notes](https://github.com/docker/build-push-action/releases) - [Commits](https://github.com/docker/build-push-action/compare/v2...v4) --- updated-dependencies: - dependency-name: docker/build-push-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/docker-image.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index 520e37833..c3f95f158 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -54,7 +54,7 @@ jobs: password: ${{ secrets.DOCKER_PASSWORD }} - name: Build Docker image and publish to Docker Hub - uses: docker/build-push-action@v2 + uses: docker/build-push-action@v4 with: platforms: linux/amd64,linux/arm/v7,linux/arm64/v8 context: . From d35e3ab6a81c0f2ddfd69df75136e18dd98a6512 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 15 Jun 2023 17:18:29 +0200 Subject: [PATCH 0745/1212] chore(deps): bump docker/setup-buildx-action from 1 to 2 (#9952) Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 1 to 2. - [Release notes](https://github.com/docker/setup-buildx-action/releases) - [Commits](https://github.com/docker/setup-buildx-action/compare/v1...v2) --- updated-dependencies: - dependency-name: docker/setup-buildx-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/docker-image.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index c3f95f158..ad6b192b7 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -29,7 +29,7 @@ jobs: uses: docker/setup-qemu-action@v1 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v1 + uses: docker/setup-buildx-action@v2 - name: Cache Docker layers uses: actions/cache@v3 From 591066fe2277170de238198f4754f7e99a430adf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 15 Jun 2023 17:18:45 +0200 Subject: [PATCH 0746/1212] chore(deps): bump codecov/codecov-action from 3.1.0 to 3.1.4 (#9951) Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 3.1.0 to 3.1.4. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/81cd2dc8148241f03f5839d295e000b8f761e378...eaaf4bedf32dbdc6b720b63067d99c4d77d6047d) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/gotest.yml | 2 +- .github/workflows/sharness.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/gotest.yml b/.github/workflows/gotest.yml index 3f6db57ae..08a741532 100644 --- a/.github/workflows/gotest.yml +++ b/.github/workflows/gotest.yml @@ -47,7 +47,7 @@ jobs: make -j "$PARALLEL" test/unit/gotest.junit.xml && [[ ! $(jq -s -c 'map(select(.Action == "fail")) | .[]' test/unit/gotest.json) ]] - name: Upload coverage to Codecov - uses: codecov/codecov-action@81cd2dc8148241f03f5839d295e000b8f761e378 # v3.1.0 + uses: codecov/codecov-action@eaaf4bedf32dbdc6b720b63067d99c4d77d6047d # v3.1.4 if: failure() || success() with: name: unittests diff --git a/.github/workflows/sharness.yml b/.github/workflows/sharness.yml index cc9ead442..d88abe89c 100644 --- a/.github/workflows/sharness.yml +++ b/.github/workflows/sharness.yml @@ -59,7 +59,7 @@ jobs: # increasing parallelism beyond 10 doesn't speed up the tests much PARALLEL: ${{ github.repository == 'ipfs/kubo' && 10 || 3 }} - name: Upload coverage report - uses: codecov/codecov-action@81cd2dc8148241f03f5839d295e000b8f761e378 # v3.1.0 + uses: codecov/codecov-action@eaaf4bedf32dbdc6b720b63067d99c4d77d6047d # v3.1.4 if: failure() || success() with: name: sharness From dc88f660d9f9da91d13fdb02fd1e24ec191df44c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 15 Jun 2023 17:35:34 +0200 Subject: [PATCH 0747/1212] chore(deps): bump docker/setup-qemu-action from 1 to 2 (#9953) Bumps [docker/setup-qemu-action](https://github.com/docker/setup-qemu-action) from 1 to 2. - [Release notes](https://github.com/docker/setup-qemu-action/releases) - [Commits](https://github.com/docker/setup-qemu-action/compare/v1...v2) --- updated-dependencies: - dependency-name: docker/setup-qemu-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/docker-image.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index ad6b192b7..eb991c5ac 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -26,7 +26,7 @@ jobs: uses: actions/checkout@v2 - name: Set up QEMU - uses: docker/setup-qemu-action@v1 + uses: docker/setup-qemu-action@v2 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v2 From 4c0ca3883c0fa3a0a58b601c047a349afd31bfc7 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Mon, 19 Jun 2023 15:07:33 +0200 Subject: [PATCH 0748/1212] chore: bump boxo to 0.10.1 (#9970) --- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- test/dependencies/go.mod | 2 +- test/dependencies/go.sum | 4 ++-- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index bfbe48843..27ecf1fae 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.18 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.10.0 + github.com/ipfs/boxo v0.10.1 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.27.6 github.com/multiformats/go-multiaddr v0.9.0 diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index d2ff0d772..319c81189 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -320,8 +320,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.10.0 h1:tdDAxq8jrsbRkYoF+5Rcqyeb91hgWe2hp7iLu7ORZLY= -github.com/ipfs/boxo v0.10.0/go.mod h1:Fg+BnfxZ0RPzR0nOodzdIq3A7KgoWAOWsEIImrIQdBM= +github.com/ipfs/boxo v0.10.1 h1:q0ZhbyN6iNZLipd6txt1xotCiP/icfvdAQ4YpUi+cL4= +github.com/ipfs/boxo v0.10.1/go.mod h1:1qgKq45mPRCxf4ZPoJV2lnXxyxucigILMJOrQrVivv8= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= diff --git a/go.mod b/go.mod index aedd07bc9..4ad1375b1 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/gogo/protobuf v1.3.2 github.com/google/uuid v1.3.0 github.com/hashicorp/go-multierror v1.1.1 - github.com/ipfs/boxo v0.10.0 + github.com/ipfs/boxo v0.10.1 github.com/ipfs/go-block-format v0.1.2 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 diff --git a/go.sum b/go.sum index a044a459b..dcfbd3cb0 100644 --- a/go.sum +++ b/go.sum @@ -355,8 +355,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.10.0 h1:tdDAxq8jrsbRkYoF+5Rcqyeb91hgWe2hp7iLu7ORZLY= -github.com/ipfs/boxo v0.10.0/go.mod h1:Fg+BnfxZ0RPzR0nOodzdIq3A7KgoWAOWsEIImrIQdBM= +github.com/ipfs/boxo v0.10.1 h1:q0ZhbyN6iNZLipd6txt1xotCiP/icfvdAQ4YpUi+cL4= +github.com/ipfs/boxo v0.10.1/go.mod h1:1qgKq45mPRCxf4ZPoJV2lnXxyxucigILMJOrQrVivv8= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index ce3c34d7b..a902d6cf8 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -7,7 +7,7 @@ replace github.com/ipfs/kubo => ../../ require ( github.com/Kubuxu/gocovmerge v0.0.0-20161216165753-7ecaa51963cd github.com/golangci/golangci-lint v1.49.0 - github.com/ipfs/boxo v0.10.0 + github.com/ipfs/boxo v0.10.1 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 github.com/ipfs/go-datastore v0.6.0 diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 431fcdbba..2840c44c2 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -413,8 +413,8 @@ github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NH github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.10.0 h1:tdDAxq8jrsbRkYoF+5Rcqyeb91hgWe2hp7iLu7ORZLY= -github.com/ipfs/boxo v0.10.0/go.mod h1:Fg+BnfxZ0RPzR0nOodzdIq3A7KgoWAOWsEIImrIQdBM= +github.com/ipfs/boxo v0.10.1 h1:q0ZhbyN6iNZLipd6txt1xotCiP/icfvdAQ4YpUi+cL4= +github.com/ipfs/boxo v0.10.1/go.mod h1:1qgKq45mPRCxf4ZPoJV2lnXxyxucigILMJOrQrVivv8= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.1.2 h1:GAjkfhVx1f4YTODS6Esrj1wt2HhrtwTnhEr+DyPUaJo= From 56f39735ae13ac969db9b46298ff8b2d364070d3 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Tue, 20 Jun 2023 05:00:58 +0200 Subject: [PATCH 0749/1212] chore: bump go-libp2p-kad-dht for deadlock fix --- docs/examples/kubo-as-a-library/go.mod | 4 ++-- docs/examples/kubo-as-a-library/go.sum | 8 ++++---- go.mod | 4 ++-- go.sum | 8 ++++---- test/dependencies/go.mod | 2 +- test/dependencies/go.sum | 4 ++-- 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 27ecf1fae..0fda8880c 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -9,7 +9,7 @@ replace github.com/ipfs/kubo => ./../../.. require ( github.com/ipfs/boxo v0.10.1 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 - github.com/libp2p/go-libp2p v0.27.6 + github.com/libp2p/go-libp2p v0.27.7 github.com/multiformats/go-multiaddr v0.9.0 ) @@ -102,7 +102,7 @@ require ( github.com/libp2p/go-doh-resolver v0.4.0 // indirect github.com/libp2p/go-flow-metrics v0.1.0 // indirect github.com/libp2p/go-libp2p-asn-util v0.3.0 // indirect - github.com/libp2p/go-libp2p-kad-dht v0.24.1 // indirect + github.com/libp2p/go-libp2p-kad-dht v0.24.2 // indirect github.com/libp2p/go-libp2p-kbucket v0.6.3 // indirect github.com/libp2p/go-libp2p-pubsub v0.9.3 // indirect github.com/libp2p/go-libp2p-pubsub-router v0.6.0 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 319c81189..d18d571e4 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -487,14 +487,14 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.27.6 h1:KmGU5kskCaaerm53heqzfGOlrW2z8icZ+fnyqgrZs38= -github.com/libp2p/go-libp2p v0.27.6/go.mod h1:oMfQGTb9CHnrOuSM6yMmyK2lXz3qIhnkn2+oK3B1Y2g= +github.com/libp2p/go-libp2p v0.27.7 h1:nhMs03CRxslKkkK2uLuN8f72uwNkE6RJS1JFb3H9UIQ= +github.com/libp2p/go-libp2p v0.27.7/go.mod h1:oMfQGTb9CHnrOuSM6yMmyK2lXz3qIhnkn2+oK3B1Y2g= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= github.com/libp2p/go-libp2p-core v0.3.0/go.mod h1:ACp3DmS3/N64c2jDzcV429ukDpicbL6+TrrxANBjPGw= -github.com/libp2p/go-libp2p-kad-dht v0.24.1 h1:XH9vIWqc6e+w6z2Nvt9R5EhkBNnOQl7tyxxM6soejwo= -github.com/libp2p/go-libp2p-kad-dht v0.24.1/go.mod h1:1meiUvgOxfSPBx1pracS4VyYwmusorvv+TVRI3mXaJI= +github.com/libp2p/go-libp2p-kad-dht v0.24.2 h1:zd7myKBKCmtZBhI3I0zm8xBkb28v3gmSEtQfBdAdFwc= +github.com/libp2p/go-libp2p-kad-dht v0.24.2/go.mod h1:BShPzRbK6+fN3hk8a0WGAYKpb8m4k+DtchkqouGTrSg= github.com/libp2p/go-libp2p-kbucket v0.3.1/go.mod h1:oyjT5O7tS9CQurok++ERgc46YLwEpuGoFq9ubvoUOio= github.com/libp2p/go-libp2p-kbucket v0.6.3 h1:p507271wWzpy2f1XxPzCQG9NiN6R6lHL9GiSErbQQo0= github.com/libp2p/go-libp2p-kbucket v0.6.3/go.mod h1:RCseT7AH6eJWxxk2ol03xtP9pEHetYSPXOaJnOiD8i0= diff --git a/go.mod b/go.mod index 4ad1375b1..1b675c12e 100644 --- a/go.mod +++ b/go.mod @@ -45,9 +45,9 @@ require ( github.com/jbenet/goprocess v0.1.4 github.com/julienschmidt/httprouter v1.3.0 github.com/libp2p/go-doh-resolver v0.4.0 - github.com/libp2p/go-libp2p v0.27.6 + github.com/libp2p/go-libp2p v0.27.7 github.com/libp2p/go-libp2p-http v0.5.0 - github.com/libp2p/go-libp2p-kad-dht v0.24.1 + github.com/libp2p/go-libp2p-kad-dht v0.24.2 github.com/libp2p/go-libp2p-kbucket v0.6.3 github.com/libp2p/go-libp2p-pubsub v0.9.3 github.com/libp2p/go-libp2p-pubsub-router v0.6.0 diff --git a/go.sum b/go.sum index dcfbd3cb0..6ba018697 100644 --- a/go.sum +++ b/go.sum @@ -537,8 +537,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.27.6 h1:KmGU5kskCaaerm53heqzfGOlrW2z8icZ+fnyqgrZs38= -github.com/libp2p/go-libp2p v0.27.6/go.mod h1:oMfQGTb9CHnrOuSM6yMmyK2lXz3qIhnkn2+oK3B1Y2g= +github.com/libp2p/go-libp2p v0.27.7 h1:nhMs03CRxslKkkK2uLuN8f72uwNkE6RJS1JFb3H9UIQ= +github.com/libp2p/go-libp2p v0.27.7/go.mod h1:oMfQGTb9CHnrOuSM6yMmyK2lXz3qIhnkn2+oK3B1Y2g= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= @@ -547,8 +547,8 @@ github.com/libp2p/go-libp2p-gostream v0.6.0 h1:QfAiWeQRce6pqnYfmIVWJFXNdDyfiR/qk github.com/libp2p/go-libp2p-gostream v0.6.0/go.mod h1:Nywu0gYZwfj7Jc91PQvbGU8dIpqbQQkjWgDuOrFaRdA= github.com/libp2p/go-libp2p-http v0.5.0 h1:+x0AbLaUuLBArHubbbNRTsgWz0RjNTy6DJLOxQ3/QBc= github.com/libp2p/go-libp2p-http v0.5.0/go.mod h1:glh87nZ35XCQyFsdzZps6+F4HYI6DctVFY5u1fehwSg= -github.com/libp2p/go-libp2p-kad-dht v0.24.1 h1:XH9vIWqc6e+w6z2Nvt9R5EhkBNnOQl7tyxxM6soejwo= -github.com/libp2p/go-libp2p-kad-dht v0.24.1/go.mod h1:1meiUvgOxfSPBx1pracS4VyYwmusorvv+TVRI3mXaJI= +github.com/libp2p/go-libp2p-kad-dht v0.24.2 h1:zd7myKBKCmtZBhI3I0zm8xBkb28v3gmSEtQfBdAdFwc= +github.com/libp2p/go-libp2p-kad-dht v0.24.2/go.mod h1:BShPzRbK6+fN3hk8a0WGAYKpb8m4k+DtchkqouGTrSg= github.com/libp2p/go-libp2p-kbucket v0.3.1/go.mod h1:oyjT5O7tS9CQurok++ERgc46YLwEpuGoFq9ubvoUOio= github.com/libp2p/go-libp2p-kbucket v0.6.3 h1:p507271wWzpy2f1XxPzCQG9NiN6R6lHL9GiSErbQQo0= github.com/libp2p/go-libp2p-kbucket v0.6.3/go.mod h1:RCseT7AH6eJWxxk2ol03xtP9pEHetYSPXOaJnOiD8i0= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index a902d6cf8..f119128d2 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -19,7 +19,7 @@ require ( github.com/ipld/go-ipld-prime v0.20.0 github.com/jbenet/go-random v0.0.0-20190219211222-123a90aedc0c github.com/jbenet/go-random-files v0.0.0-20190219210431-31b3f20ebded - github.com/libp2p/go-libp2p v0.27.6 + github.com/libp2p/go-libp2p v0.27.7 github.com/multiformats/go-multiaddr v0.9.0 github.com/multiformats/go-multihash v0.2.3 gotest.tools/gotestsum v0.4.2 diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 2840c44c2..5c3a5ef94 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -565,8 +565,8 @@ github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38y github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.27.6 h1:KmGU5kskCaaerm53heqzfGOlrW2z8icZ+fnyqgrZs38= -github.com/libp2p/go-libp2p v0.27.6/go.mod h1:oMfQGTb9CHnrOuSM6yMmyK2lXz3qIhnkn2+oK3B1Y2g= +github.com/libp2p/go-libp2p v0.27.7 h1:nhMs03CRxslKkkK2uLuN8f72uwNkE6RJS1JFb3H9UIQ= +github.com/libp2p/go-libp2p v0.27.7/go.mod h1:oMfQGTb9CHnrOuSM6yMmyK2lXz3qIhnkn2+oK3B1Y2g= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= From ff34819871ea3c25a9ceb654de26f2d63594c547 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Tue, 20 Jun 2023 06:14:18 +0000 Subject: [PATCH 0750/1212] chore: update version --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index 98ee37fc5..06c8914db 100644 --- a/version.go +++ b/version.go @@ -11,7 +11,7 @@ import ( var CurrentCommit string // CurrentVersionNumber is the current application's version literal -const CurrentVersionNumber = "0.21.0-rc2" +const CurrentVersionNumber = "0.21.0-rc3" const ApiVersion = "/kubo/" + CurrentVersionNumber + "/" //nolint From d6464864cbff0cc96d4cb11b292daba77c2366d1 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Tue, 20 Jun 2023 14:08:22 +0200 Subject: [PATCH 0751/1212] feat(ipns): refactored IPNS package with lean records (#339) This commit was moved from ipfs/boxo@417c5f7d61ff5dcf0fef88b19dde54c8d5097a0f --- core/coreiface/name.go | 11 +- core/coreiface/options/name.go | 20 ++- core/coreiface/options/namesys/opts.go | 12 +- core/coreiface/tests/name.go | 209 ++++++------------------- core/coreiface/tests/routing.go | 91 ++++------- 5 files changed, 109 insertions(+), 234 deletions(-) diff --git a/core/coreiface/name.go b/core/coreiface/name.go index 0c06183e6..8c3e8e89a 100644 --- a/core/coreiface/name.go +++ b/core/coreiface/name.go @@ -5,20 +5,13 @@ import ( "errors" path "github.com/ipfs/boxo/coreiface/path" + "github.com/ipfs/boxo/ipns" "github.com/ipfs/boxo/coreiface/options" ) var ErrResolveFailed = errors.New("could not resolve name") -// IpnsEntry specifies the interface to IpnsEntries -type IpnsEntry interface { - // Name returns IpnsEntry name - Name() string - // Value returns IpnsEntry value - Value() path.Path -} - type IpnsResult struct { path.Path Err error @@ -34,7 +27,7 @@ type IpnsResult struct { // You can use .Key API to list and generate more names and their respective keys. type NameAPI interface { // Publish announces new IPNS name - Publish(ctx context.Context, path path.Path, opts ...options.NamePublishOption) (IpnsEntry, error) + Publish(ctx context.Context, path path.Path, opts ...options.NamePublishOption) (ipns.Name, error) // Resolve attempts to resolve the newest version of the specified name Resolve(ctx context.Context, name string, opts ...options.NameResolveOption) (path.Path, error) diff --git a/core/coreiface/options/name.go b/core/coreiface/options/name.go index ae8be9ae9..8e9b5183d 100644 --- a/core/coreiface/options/name.go +++ b/core/coreiface/options/name.go @@ -11,12 +11,11 @@ const ( ) type NamePublishSettings struct { - ValidTime time.Duration - Key string - - TTL *time.Duration - - AllowOffline bool + ValidTime time.Duration + Key string + TTL *time.Duration + CompatibleWithV1 bool + AllowOffline bool } type NameResolveSettings struct { @@ -104,6 +103,15 @@ func (nameOpts) TTL(ttl time.Duration) NamePublishOption { } } +// CompatibleWithV1 is an option for [Name.Publish] which specifies if the +// created record should be backwards compatible with V1 IPNS Records. +func (nameOpts) CompatibleWithV1(compatible bool) NamePublishOption { + return func(settings *NamePublishSettings) error { + settings.CompatibleWithV1 = compatible + return nil + } +} + // Cache is an option for Name.Resolve which specifies if cache should be used. // Default value is true func (nameOpts) Cache(cache bool) NameResolveOption { diff --git a/core/coreiface/options/namesys/opts.go b/core/coreiface/options/namesys/opts.go index 0cd1ba778..ed568200b 100644 --- a/core/coreiface/options/namesys/opts.go +++ b/core/coreiface/options/namesys/opts.go @@ -84,8 +84,9 @@ func ProcessOpts(opts []ResolveOpt) ResolveOpts { // PublishOptions specifies options for publishing an IPNS record. type PublishOptions struct { - EOL time.Time - TTL time.Duration + EOL time.Time + TTL time.Duration + CompatibleWithV1 bool } // DefaultPublishOptions returns the default options for publishing an IPNS record. @@ -113,6 +114,13 @@ func PublishWithTTL(ttl time.Duration) PublishOption { } } +// PublishCompatibleWithV1 sets compatibility with IPNS Records V1. +func PublishCompatibleWithV1(compatible bool) PublishOption { + return func(o *PublishOptions) { + o.CompatibleWithV1 = compatible + } +} + // ProcessPublishOptions converts an array of PublishOpt into a PublishOpts object. func ProcessPublishOptions(opts []PublishOption) PublishOptions { rsopts := DefaultPublishOptions() diff --git a/core/coreiface/tests/name.go b/core/coreiface/tests/name.go index 8fa733567..ab55d0425 100644 --- a/core/coreiface/tests/name.go +++ b/core/coreiface/tests/name.go @@ -8,12 +8,12 @@ import ( "testing" "time" - path "github.com/ipfs/boxo/coreiface/path" - - "github.com/ipfs/boxo/files" - coreiface "github.com/ipfs/boxo/coreiface" opt "github.com/ipfs/boxo/coreiface/options" + path "github.com/ipfs/boxo/coreiface/path" + "github.com/ipfs/boxo/files" + "github.com/ipfs/boxo/ipns" + "github.com/stretchr/testify/require" ) func (tp *TestSuite) TestName(t *testing.T) { @@ -44,138 +44,68 @@ func (tp *TestSuite) TestPublishResolve(t *testing.T) { defer cancel() init := func() (coreiface.CoreAPI, path.Path) { apis, err := tp.MakeAPISwarm(t, ctx, 5) - if err != nil { - t.Fatal(err) - return nil, nil - } + require.NoError(t, err) api := apis[0] p, err := addTestObject(ctx, api) - if err != nil { - t.Fatal(err) - return nil, nil - } + require.NoError(t, err) return api, p } run := func(t *testing.T, ropts []opt.NameResolveOption) { t.Run("basic", func(t *testing.T) { api, p := init() - e, err := api.Name().Publish(ctx, p) - if err != nil { - t.Fatal(err) - } + name, err := api.Name().Publish(ctx, p) + require.NoError(t, err) self, err := api.Key().Self(ctx) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) + require.Equal(t, name.String(), ipns.NameFromPeer(self.ID()).String()) - if e.Name() != coreiface.FormatKeyID(self.ID()) { - t.Errorf("expected e.Name to equal '%s', got '%s'", coreiface.FormatKeyID(self.ID()), e.Name()) - } - - if e.Value().String() != p.String() { - t.Errorf("expected paths to match, '%s'!='%s'", e.Value().String(), p.String()) - } - - resPath, err := api.Name().Resolve(ctx, e.Name(), ropts...) - if err != nil { - t.Fatal(err) - } - - if resPath.String() != p.String() { - t.Errorf("expected paths to match, '%s'!='%s'", resPath.String(), p.String()) - } + resPath, err := api.Name().Resolve(ctx, name.String(), ropts...) + require.NoError(t, err) + require.Equal(t, p.String(), resPath.String()) }) t.Run("publishPath", func(t *testing.T) { api, p := init() - e, err := api.Name().Publish(ctx, appendPath(p, "/test")) - if err != nil { - t.Fatal(err) - } + name, err := api.Name().Publish(ctx, appendPath(p, "/test")) + require.NoError(t, err) self, err := api.Key().Self(ctx) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) + require.Equal(t, name.String(), ipns.NameFromPeer(self.ID()).String()) - if e.Name() != coreiface.FormatKeyID(self.ID()) { - t.Errorf("expected e.Name to equal '%s', got '%s'", coreiface.FormatKeyID(self.ID()), e.Name()) - } - - if e.Value().String() != p.String()+"/test" { - t.Errorf("expected paths to match, '%s'!='%s'", e.Value().String(), p.String()) - } - - resPath, err := api.Name().Resolve(ctx, e.Name(), ropts...) - if err != nil { - t.Fatal(err) - } - - if resPath.String() != p.String()+"/test" { - t.Errorf("expected paths to match, '%s'!='%s'", resPath.String(), p.String()+"/test") - } + resPath, err := api.Name().Resolve(ctx, name.String(), ropts...) + require.NoError(t, err) + require.Equal(t, p.String()+"/test", resPath.String()) }) t.Run("revolvePath", func(t *testing.T) { api, p := init() - e, err := api.Name().Publish(ctx, p) - if err != nil { - t.Fatal(err) - } + name, err := api.Name().Publish(ctx, p) + require.NoError(t, err) self, err := api.Key().Self(ctx) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) + require.Equal(t, name.String(), ipns.NameFromPeer(self.ID()).String()) - if e.Name() != coreiface.FormatKeyID(self.ID()) { - t.Errorf("expected e.Name to equal '%s', got '%s'", coreiface.FormatKeyID(self.ID()), e.Name()) - } - - if e.Value().String() != p.String() { - t.Errorf("expected paths to match, '%s'!='%s'", e.Value().String(), p.String()) - } - - resPath, err := api.Name().Resolve(ctx, e.Name()+"/test", ropts...) - if err != nil { - t.Fatal(err) - } - - if resPath.String() != p.String()+"/test" { - t.Errorf("expected paths to match, '%s'!='%s'", resPath.String(), p.String()+"/test") - } + resPath, err := api.Name().Resolve(ctx, name.String()+"/test", ropts...) + require.NoError(t, err) + require.Equal(t, p.String()+"/test", resPath.String()) }) t.Run("publishRevolvePath", func(t *testing.T) { api, p := init() - e, err := api.Name().Publish(ctx, appendPath(p, "/a")) - if err != nil { - t.Fatal(err) - } + name, err := api.Name().Publish(ctx, appendPath(p, "/a")) + require.NoError(t, err) self, err := api.Key().Self(ctx) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) + require.Equal(t, name.String(), ipns.NameFromPeer(self.ID()).String()) - if e.Name() != coreiface.FormatKeyID(self.ID()) { - t.Errorf("expected e.Name to equal '%s', got '%s'", coreiface.FormatKeyID(self.ID()), e.Name()) - } - - if e.Value().String() != p.String()+"/a" { - t.Errorf("expected paths to match, '%s'!='%s'", e.Value().String(), p.String()) - } - - resPath, err := api.Name().Resolve(ctx, e.Name()+"/b", ropts...) - if err != nil { - t.Fatal(err) - } - - if resPath.String() != p.String()+"/a/b" { - t.Errorf("expected paths to match, '%s'!='%s'", resPath.String(), p.String()+"/a/b") - } + resPath, err := api.Name().Resolve(ctx, name.String()+"/b", ropts...) + require.NoError(t, err) + require.Equal(t, p.String()+"/a/b", resPath.String()) }) } @@ -192,42 +122,22 @@ func (tp *TestSuite) TestBasicPublishResolveKey(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() apis, err := tp.MakeAPISwarm(t, ctx, 5) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) api := apis[0] k, err := api.Key().Generate(ctx, "foo") - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) p, err := addTestObject(ctx, api) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - e, err := api.Name().Publish(ctx, p, opt.Name.Key(k.Name())) - if err != nil { - t.Fatal(err) - } + name, err := api.Name().Publish(ctx, p, opt.Name.Key(k.Name())) + require.NoError(t, err) + require.Equal(t, name.String(), ipns.NameFromPeer(k.ID()).String()) - if e.Name() != coreiface.FormatKey(k) { - t.Errorf("expected e.Name to equal %s, got '%s'", e.Name(), coreiface.FormatKey(k)) - } - - if e.Value().String() != p.String() { - t.Errorf("expected paths to match, '%s'!='%s'", e.Value().String(), p.String()) - } - - resPath, err := api.Name().Resolve(ctx, e.Name()) - if err != nil { - t.Fatal(err) - } - - if resPath.String() != p.String() { - t.Errorf("expected paths to match, '%s'!='%s'", resPath.String(), p.String()) - } + resPath, err := api.Name().Resolve(ctx, name.String()) + require.NoError(t, err) + require.Equal(t, p.String(), resPath.String()) } func (tp *TestSuite) TestBasicPublishResolveTimeout(t *testing.T) { @@ -236,39 +146,22 @@ func (tp *TestSuite) TestBasicPublishResolveTimeout(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() apis, err := tp.MakeAPISwarm(t, ctx, 5) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) api := apis[0] p, err := addTestObject(ctx, api) - if err != nil { - t.Fatal(err) - } - - e, err := api.Name().Publish(ctx, p, opt.Name.ValidTime(time.Millisecond*100)) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) self, err := api.Key().Self(ctx) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - if e.Name() != coreiface.FormatKeyID(self.ID()) { - t.Errorf("expected e.Name to equal '%s', got '%s'", coreiface.FormatKeyID(self.ID()), e.Name()) - } - - if e.Value().String() != p.String() { - t.Errorf("expected paths to match, '%s'!='%s'", e.Value().String(), p.String()) - } + name, err := api.Name().Publish(ctx, p, opt.Name.ValidTime(time.Millisecond*100)) + require.NoError(t, err) + require.Equal(t, name.String(), ipns.NameFromPeer(self.ID()).String()) time.Sleep(time.Second) - _, err = api.Name().Resolve(ctx, e.Name()) - if err == nil { - t.Fatal("Expected an error") - } + _, err = api.Name().Resolve(ctx, name.String()) + require.NoError(t, err) } //TODO: When swarm api is created, add multinode tests diff --git a/core/coreiface/tests/routing.go b/core/coreiface/tests/routing.go index 6fca1a003..fd10dffcd 100644 --- a/core/coreiface/tests/routing.go +++ b/core/coreiface/tests/routing.go @@ -5,10 +5,11 @@ import ( "testing" "time" - "github.com/gogo/protobuf/proto" iface "github.com/ipfs/boxo/coreiface" "github.com/ipfs/boxo/coreiface/options" - ipns_pb "github.com/ipfs/boxo/ipns/pb" + "github.com/ipfs/boxo/coreiface/path" + "github.com/ipfs/boxo/ipns" + "github.com/stretchr/testify/require" ) func (tp *TestSuite) TestRouting(t *testing.T) { @@ -24,19 +25,15 @@ func (tp *TestSuite) TestRouting(t *testing.T) { t.Run("TestRoutingPutOffline", tp.TestRoutingPutOffline) } -func (tp *TestSuite) testRoutingPublishKey(t *testing.T, ctx context.Context, api iface.CoreAPI, opts ...options.NamePublishOption) iface.IpnsEntry { +func (tp *TestSuite) testRoutingPublishKey(t *testing.T, ctx context.Context, api iface.CoreAPI, opts ...options.NamePublishOption) (path.Path, ipns.Name) { p, err := addTestObject(ctx, api) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - entry, err := api.Name().Publish(ctx, p, opts...) - if err != nil { - t.Fatal(err) - } + name, err := api.Name().Publish(ctx, p, opts...) + require.NoError(t, err) time.Sleep(3 * time.Second) - return entry + return p, name } func (tp *TestSuite) TestRoutingGet(t *testing.T) { @@ -44,53 +41,39 @@ func (tp *TestSuite) TestRoutingGet(t *testing.T) { defer cancel() apis, err := tp.MakeAPISwarm(t, ctx, 2) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) // Node 1: publishes an IPNS name - ipnsEntry := tp.testRoutingPublishKey(t, ctx, apis[0]) + p, name := tp.testRoutingPublishKey(t, ctx, apis[0]) // Node 2: retrieves the best value for the IPNS name. - data, err := apis[1].Routing().Get(ctx, "/ipns/"+ipnsEntry.Name()) - if err != nil { - t.Fatal(err) - } + data, err := apis[1].Routing().Get(ctx, ipns.NamespacePrefix+name.String()) + require.NoError(t, err) - // Checks if values match. - var entry ipns_pb.IpnsEntry - err = proto.Unmarshal(data, &entry) - if err != nil { - t.Fatal(err) - } + rec, err := ipns.UnmarshalRecord(data) + require.NoError(t, err) - if string(entry.GetValue()) != ipnsEntry.Value().String() { - t.Fatalf("routing key has wrong value, expected %s, got %s", ipnsEntry.Value().String(), string(entry.GetValue())) - } + val, err := rec.Value() + require.NoError(t, err) + require.Equal(t, p.String(), val.String()) } func (tp *TestSuite) TestRoutingPut(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() apis, err := tp.MakeAPISwarm(t, ctx, 2) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) // Create and publish IPNS entry. - ipnsEntry := tp.testRoutingPublishKey(t, ctx, apis[0]) + _, name := tp.testRoutingPublishKey(t, ctx, apis[0]) // Get valid routing value. - data, err := apis[0].Routing().Get(ctx, "/ipns/"+ipnsEntry.Name()) - if err != nil { - t.Fatal(err) - } + data, err := apis[0].Routing().Get(ctx, ipns.NamespacePrefix+name.String()) + require.NoError(t, err) // Put routing value. - err = apis[1].Routing().Put(ctx, "/ipns/"+ipnsEntry.Name(), data) - if err != nil { - t.Fatal(err) - } + err = apis[1].Routing().Put(ctx, ipns.NamespacePrefix+name.String(), data) + require.NoError(t, err) } func (tp *TestSuite) TestRoutingPutOffline(t *testing.T) { @@ -99,29 +82,19 @@ func (tp *TestSuite) TestRoutingPutOffline(t *testing.T) { // init a swarm & publish an IPNS entry to get a valid payload apis, err := tp.MakeAPISwarm(t, ctx, 2) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - ipnsEntry := tp.testRoutingPublishKey(t, ctx, apis[0], options.Name.AllowOffline(true)) - data, err := apis[0].Routing().Get(ctx, "/ipns/"+ipnsEntry.Name()) - if err != nil { - t.Fatal(err) - } + _, name := tp.testRoutingPublishKey(t, ctx, apis[0], options.Name.AllowOffline(true)) + data, err := apis[0].Routing().Get(ctx, ipns.NamespacePrefix+name.String()) + require.NoError(t, err) // init our offline node and try to put the payload api, err := tp.makeAPIWithIdentityAndOffline(t, ctx) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - err = api.Routing().Put(ctx, "/ipns/"+ipnsEntry.Name(), data) - if err == nil { - t.Fatal("this operation should fail because we are offline") - } + err = api.Routing().Put(ctx, ipns.NamespacePrefix+name.String(), data) + require.Error(t, err, "this operation should fail because we are offline") - err = api.Routing().Put(ctx, "/ipns/"+ipnsEntry.Name(), data, options.Put.AllowOffline(true)) - if err != nil { - t.Fatal(err) - } + err = api.Routing().Put(ctx, ipns.NamespacePrefix+name.String(), data, options.Put.AllowOffline(true)) + require.NoError(t, err) } From 5156f2116256c45b45720161d1169eab85378f48 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Tue, 20 Jun 2023 14:24:31 +0200 Subject: [PATCH 0752/1212] feat(ipns): records with V2-only signatures (#9932) --- client/rpc/name.go | 24 +- config/routing.go | 11 +- config/routing_test.go | 77 +----- core/commands/dht_test.go | 4 +- core/commands/name/name.go | 169 ++++++------ core/commands/name/publish.go | 21 +- core/core_test.go | 296 --------------------- core/coreapi/name.go | 38 +-- docs/changelogs/v0.22.md | 10 + docs/examples/kubo-as-a-library/go.mod | 4 +- docs/examples/kubo-as-a-library/go.sum | 8 +- go.mod | 10 +- go.sum | 8 +- routing/delegated.go | 79 ------ routing/delegated_test.go | 114 ++++---- routing/wrapper.go | 28 -- test/cli/fixtures/TestName.car | Bin 0 -> 421 bytes test/cli/name_test.go | 266 +++++++++++++++++++ test/dependencies/go.mod | 2 +- test/dependencies/go.sum | 4 +- test/sharness/t0100-name.sh | 345 ------------------------- 21 files changed, 464 insertions(+), 1054 deletions(-) create mode 100644 test/cli/fixtures/TestName.car create mode 100644 test/cli/name_test.go delete mode 100755 test/sharness/t0100-name.sh diff --git a/client/rpc/name.go b/client/rpc/name.go index e6c726c58..5ad9d16cb 100644 --- a/client/rpc/name.go +++ b/client/rpc/name.go @@ -10,29 +10,20 @@ import ( caopts "github.com/ipfs/boxo/coreiface/options" nsopts "github.com/ipfs/boxo/coreiface/options/namesys" "github.com/ipfs/boxo/coreiface/path" + "github.com/ipfs/boxo/ipns" ) type NameAPI HttpApi type ipnsEntry struct { - JName string `json:"Name"` - JValue string `json:"Value"` - - path path.Path + Name string `json:"Name"` + Value string `json:"Value"` } -func (e *ipnsEntry) Name() string { - return e.JName -} - -func (e *ipnsEntry) Value() path.Path { - return e.path -} - -func (api *NameAPI) Publish(ctx context.Context, p path.Path, opts ...caopts.NamePublishOption) (iface.IpnsEntry, error) { +func (api *NameAPI) Publish(ctx context.Context, p path.Path, opts ...caopts.NamePublishOption) (ipns.Name, error) { options, err := caopts.NamePublishOptions(opts...) if err != nil { - return nil, err + return ipns.Name{}, err } req := api.core().Request("name/publish", p.String()). @@ -47,10 +38,9 @@ func (api *NameAPI) Publish(ctx context.Context, p path.Path, opts ...caopts.Nam var out ipnsEntry if err := req.Exec(ctx, &out); err != nil { - return nil, err + return ipns.Name{}, err } - out.path = path.New(out.JValue) - return &out, out.path.IsValid() + return ipns.NameFromString(out.Name) } func (api *NameAPI) Search(ctx context.Context, name string, opts ...caopts.NameResolveOption) (<-chan iface.IpnsResult, error) { diff --git a/config/routing.go b/config/routing.go index 7f5e48aa2..ede8f0f9e 100644 --- a/config/routing.go +++ b/config/routing.go @@ -28,7 +28,7 @@ type Router struct { Type RouterType // Parameters are extra configuration that this router might need. - // A common one for reframe router is "Endpoint". + // A common one for HTTP router is "Endpoint". Parameters interface{} } @@ -81,8 +81,6 @@ func (r *RouterParser) UnmarshalJSON(b []byte) error { switch out.Type { case RouterTypeHTTP: p = &HTTPRouterParams{} - case RouterTypeReframe: - p = &ReframeRouterParams{} case RouterTypeDHT: p = &DHTRouterParams{} case RouterTypeSequential: @@ -106,7 +104,6 @@ func (r *RouterParser) UnmarshalJSON(b []byte) error { type RouterType string const ( - RouterTypeReframe RouterType = "reframe" // More info here: https://github.com/ipfs/specs/tree/main/reframe . Actually deprecated. RouterTypeHTTP RouterType = "http" // HTTP JSON API for delegated routing systems (IPIP-337). RouterTypeDHT RouterType = "dht" // DHT router. RouterTypeSequential RouterType = "sequential" // Router helper to execute several routers sequentially. @@ -133,12 +130,6 @@ const ( var MethodNameList = []MethodName{MethodNameProvide, MethodNameFindPeers, MethodNameFindProviders, MethodNameGetIPNS, MethodNamePutIPNS} -type ReframeRouterParams struct { - // Endpoint is the URL where the routing implementation will point to get the information. - // Usually used for reframe Routers. - Endpoint string -} - type HTTPRouterParams struct { // Endpoint is the URL where the routing implementation will point to get the information. Endpoint string diff --git a/config/routing_test.go b/config/routing_test.go index 49068f976..4dfc54ccb 100644 --- a/config/routing_test.go +++ b/config/routing_test.go @@ -23,12 +23,6 @@ func TestRouterParameters(t *testing.T) { PublicIPNetwork: false, }, }}, - "router-reframe": {Router{ - Type: RouterTypeReframe, - Parameters: ReframeRouterParams{ - Endpoint: "reframe-endpoint", - }, - }}, "router-parallel": {Router{ Type: RouterTypeParallel, Parameters: ComposableRouterParams{ @@ -39,7 +33,7 @@ func TestRouterParameters(t *testing.T) { IgnoreErrors: true, }, { - RouterName: "router-reframe", + RouterName: "router-dht", Timeout: Duration{10 * time.Second}, IgnoreErrors: false, ExecuteAfter: &OptionalDuration{&sec}, @@ -58,7 +52,7 @@ func TestRouterParameters(t *testing.T) { IgnoreErrors: true, }, { - RouterName: "router-reframe", + RouterName: "router-dht", Timeout: Duration{10 * time.Second}, IgnoreErrors: false, }, @@ -69,7 +63,7 @@ func TestRouterParameters(t *testing.T) { }, Methods: Methods{ MethodNameFindPeers: { - RouterName: "router-reframe", + RouterName: "router-dht", }, MethodNameFindProviders: { RouterName: "router-dht", @@ -99,9 +93,6 @@ func TestRouterParameters(t *testing.T) { dhtp := r2.Routers["router-dht"].Parameters require.IsType(&DHTRouterParams{}, dhtp) - rp := r2.Routers["router-reframe"].Parameters - require.IsType(&ReframeRouterParams{}, rp) - sp := r2.Routers["router-sequential"].Parameters require.IsType(&ComposableRouterParams{}, sp) @@ -109,68 +100,24 @@ func TestRouterParameters(t *testing.T) { require.IsType(&ComposableRouterParams{}, pp) } -func TestRouterMissingParameters(t *testing.T) { - require := require.New(t) - - r := Routing{ - Type: NewOptionalString("custom"), - Routers: map[string]RouterParser{ - "router-wrong-reframe": {Router{ - Type: RouterTypeReframe, - Parameters: DHTRouterParams{ - Mode: "auto", - AcceleratedDHTClient: true, - PublicIPNetwork: false, - }, - }}, - }, - Methods: Methods{ - MethodNameFindPeers: { - RouterName: "router-wrong-reframe", - }, - MethodNameFindProviders: { - RouterName: "router-wrong-reframe", - }, - MethodNameGetIPNS: { - RouterName: "router-wrong-reframe", - }, - MethodNameProvide: { - RouterName: "router-wrong-reframe", - }, - MethodNamePutIPNS: { - RouterName: "router-wrong-reframe", - }, - }, - } - - out, err := json.Marshal(r) - require.NoError(err) - - r2 := &Routing{} - - err = json.Unmarshal(out, r2) - require.NoError(err) - require.Empty(r2.Routers["router-wrong-reframe"].Parameters.(*ReframeRouterParams).Endpoint) -} - func TestMethods(t *testing.T) { require := require.New(t) methodsOK := Methods{ MethodNameFindPeers: { - RouterName: "router-wrong-reframe", + RouterName: "router-wrong", }, MethodNameFindProviders: { - RouterName: "router-wrong-reframe", + RouterName: "router-wrong", }, MethodNameGetIPNS: { - RouterName: "router-wrong-reframe", + RouterName: "router-wrong", }, MethodNameProvide: { - RouterName: "router-wrong-reframe", + RouterName: "router-wrong", }, MethodNamePutIPNS: { - RouterName: "router-wrong-reframe", + RouterName: "router-wrong", }, } @@ -178,16 +125,16 @@ func TestMethods(t *testing.T) { methodsMissing := Methods{ MethodNameFindPeers: { - RouterName: "router-wrong-reframe", + RouterName: "router-wrong", }, MethodNameGetIPNS: { - RouterName: "router-wrong-reframe", + RouterName: "router-wrong", }, MethodNameProvide: { - RouterName: "router-wrong-reframe", + RouterName: "router-wrong", }, MethodNamePutIPNS: { - RouterName: "router-wrong-reframe", + RouterName: "router-wrong", }, } diff --git a/core/commands/dht_test.go b/core/commands/dht_test.go index 961d906ab..d6a87c954 100644 --- a/core/commands/dht_test.go +++ b/core/commands/dht_test.go @@ -12,7 +12,7 @@ import ( func TestKeyTranslation(t *testing.T) { pid := test.RandPeerIDFatal(t) pkname := namesys.PkKeyForID(pid) - ipnsname := ipns.RecordKey(pid) + ipnsname := ipns.NameFromPeer(pid).RoutingKey() pkk, err := escapeDhtKey("/pk/" + pid.Pretty()) if err != nil { @@ -28,7 +28,7 @@ func TestKeyTranslation(t *testing.T) { t.Fatal("keys didn't match!") } - if ipnsk != ipnsname { + if ipnsk != string(ipnsname) { t.Fatal("keys didn't match!") } } diff --git a/core/commands/name/name.go b/core/commands/name/name.go index 94f05290c..3bcb5c8e4 100644 --- a/core/commands/name/name.go +++ b/core/commands/name/name.go @@ -2,23 +2,18 @@ package name import ( "bytes" - "encoding/json" + "encoding/hex" "fmt" "io" - "strings" "text/tabwriter" "time" - "github.com/gogo/protobuf/proto" "github.com/ipfs/boxo/ipns" ipns_pb "github.com/ipfs/boxo/ipns/pb" + "github.com/ipfs/boxo/path" cmds "github.com/ipfs/go-ipfs-cmds" cmdenv "github.com/ipfs/kubo/core/commands/cmdenv" - "github.com/ipld/go-ipld-prime" - "github.com/ipld/go-ipld-prime/codec/dagcbor" - "github.com/ipld/go-ipld-prime/codec/dagjson" - "github.com/libp2p/go-libp2p/core/peer" - mbase "github.com/multiformats/go-multibase" + "google.golang.org/protobuf/proto" ) type IpnsEntry struct { @@ -84,28 +79,27 @@ Resolve the value of a dnslink: } type IpnsInspectValidation struct { - Valid bool - Reason string - PublicKey peer.ID + Valid bool + Reason string + Name string } // IpnsInspectEntry contains the deserialized values from an IPNS Entry: // https://github.com/ipfs/specs/blob/main/ipns/IPNS.md#record-serialization-format type IpnsInspectEntry struct { - Value string - ValidityType *ipns_pb.IpnsEntry_ValidityType + Value *path.Path + ValidityType *ipns.ValidityType Validity *time.Time - Sequence uint64 - TTL *uint64 - PublicKey string - SignatureV1 string - SignatureV2 string - Data interface{} + Sequence *uint64 + TTL *time.Duration } type IpnsInspectResult struct { - Entry IpnsInspectEntry - Validation *IpnsInspectValidation + Entry IpnsInspectEntry + PbSize int + SignatureType string + HexDump string + Validation *IpnsInspectValidation } var IpnsInspectCmd = &cmds.Command{ @@ -136,6 +130,7 @@ Passing --verify will verify signature against provided public key. }, Options: []cmds.Option{ cmds.StringOption("verify", "CID of the public IPNS key to validate against."), + cmds.BoolOption("dump", "Include a full hex dump of the raw Protobuf record.").WithDefault(true), }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { file, err := cmdenv.GetFileArg(req.Files.Entries()) @@ -151,71 +146,62 @@ Passing --verify will verify signature against provided public key. return err } - var entry ipns_pb.IpnsEntry - err = proto.Unmarshal(b.Bytes(), &entry) - if err != nil { - return err - } - - encoder, err := mbase.EncoderByName("base64") + rec, err := ipns.UnmarshalRecord(b.Bytes()) if err != nil { return err } result := &IpnsInspectResult{ - Entry: IpnsInspectEntry{ - Value: string(entry.Value), - ValidityType: entry.ValidityType, - Sequence: *entry.Sequence, - TTL: entry.Ttl, - PublicKey: encoder.Encode(entry.PubKey), - SignatureV1: encoder.Encode(entry.SignatureV1), - SignatureV2: encoder.Encode(entry.SignatureV2), - Data: nil, - }, + Entry: IpnsInspectEntry{}, } - if len(entry.Data) != 0 { - // This is hacky. The variable node (datamodel.Node) doesn't directly marshal - // to JSON. Therefore, we need to first decode from DAG-CBOR, then encode in - // DAG-JSON and finally unmarshal it from JSON. Since DAG-JSON is a subset - // of JSON, that should work. Then, we can store the final value in the - // result.Entry.Data for further inspection. - node, err := ipld.Decode(entry.Data, dagcbor.Decode) - if err != nil { - return err - } - - var buf bytes.Buffer - err = dagjson.Encode(node, &buf) - if err != nil { - return err - } - - err = json.Unmarshal(buf.Bytes(), &result.Entry.Data) - if err != nil { - return err - } + // Best effort to get the fields. Show everything we can. + if v, err := rec.Value(); err == nil { + result.Entry.Value = &v } - validity, err := ipns.GetEOL(&entry) - if err == nil { - result.Entry.Validity = &validity + if v, err := rec.ValidityType(); err == nil { + result.Entry.ValidityType = &v } - verify, ok := req.Options["verify"].(string) - if ok { - key := strings.TrimPrefix(verify, "/ipns/") - id, err := peer.Decode(key) + if v, err := rec.Validity(); err == nil { + result.Entry.Validity = &v + } + + if v, err := rec.Sequence(); err == nil { + result.Entry.Sequence = &v + } + + if v, err := rec.TTL(); err == nil { + result.Entry.TTL = &v + } + + // Here we need the raw protobuf just to decide the version. + var pbRecord ipns_pb.IpnsRecord + err = proto.Unmarshal(b.Bytes(), &pbRecord) + if err != nil { + return err + } + if len(pbRecord.SignatureV1) != 0 || len(pbRecord.Value) != 0 { + result.SignatureType = "V1+V2" + } else if pbRecord.Data != nil { + result.SignatureType = "V2" + } else { + result.SignatureType = "Unknown" + } + result.PbSize = proto.Size(&pbRecord) + + if verify, ok := req.Options["verify"].(string); ok { + name, err := ipns.NameFromString(verify) if err != nil { return err } result.Validation = &IpnsInspectValidation{ - PublicKey: id, + Name: name.String(), } - err = ipns.ValidateWithPeerID(id, &entry) + err = ipns.ValidateWithName(rec, name) if err == nil { result.Validation.Valid = true } else { @@ -223,6 +209,10 @@ Passing --verify will verify signature against provided public key. } } + if dump, ok := req.Options["dump"].(bool); ok && dump { + result.HexDump = hex.Dump(b.Bytes()) + } + return cmds.EmitOnce(res, result) }, Type: IpnsInspectResult{}, @@ -231,24 +221,28 @@ Passing --verify will verify signature against provided public key. tw := tabwriter.NewWriter(w, 0, 0, 1, ' ', 0) defer tw.Flush() - fmt.Fprintf(tw, "Value:\t%q\n", string(out.Entry.Value)) - fmt.Fprintf(tw, "Validity Type:\t%q\n", out.Entry.ValidityType) - if out.Entry.Validity != nil { - fmt.Fprintf(tw, "Validity:\t%s\n", out.Entry.Validity.Format(time.RFC3339Nano)) + if out.Entry.Value != nil { + fmt.Fprintf(tw, "Value:\t%q\n", out.Entry.Value.String()) } - fmt.Fprintf(tw, "Sequence:\t%d\n", out.Entry.Sequence) - if out.Entry.TTL != nil { - fmt.Fprintf(tw, "TTL:\t%d\n", *out.Entry.TTL) - } - fmt.Fprintf(tw, "PublicKey:\t%q\n", out.Entry.PublicKey) - fmt.Fprintf(tw, "Signature V1:\t%q\n", out.Entry.SignatureV1) - fmt.Fprintf(tw, "Signature V2:\t%q\n", out.Entry.SignatureV2) - data, err := json.Marshal(out.Entry.Data) - if err != nil { - return err + if out.Entry.ValidityType != nil { + fmt.Fprintf(tw, "Validity Type:\t%q\n", *out.Entry.ValidityType) } - fmt.Fprintf(tw, "Data:\t%s\n", string(data)) + + if out.Entry.Validity != nil { + fmt.Fprintf(tw, "Validity:\t%q\n", out.Entry.Validity.Format(time.RFC3339Nano)) + } + + if out.Entry.Sequence != nil { + fmt.Fprintf(tw, "Sequence:\t%d\n", *out.Entry.Sequence) + } + + if out.Entry.TTL != nil { + fmt.Fprintf(tw, "TTL:\t%s\n", out.Entry.TTL.String()) + } + + fmt.Fprintf(tw, "Protobuf Size:\t%d\n", out.PbSize) + fmt.Fprintf(tw, "Signature Type:\t%s\n", out.SignatureType) if out.Validation == nil { tw.Flush() @@ -261,7 +255,14 @@ Passing --verify will verify signature against provided public key. if out.Validation.Reason != "" { fmt.Fprintf(tw, "\tReason:\t%s\n", out.Validation.Reason) } - fmt.Fprintf(tw, "\tPublicKey:\t%s\n", out.Validation.PublicKey) + fmt.Fprintf(tw, "\tName:\t%s\n", out.Validation.Name) + } + + if out.HexDump != "" { + tw.Flush() + + fmt.Fprintf(w, "\nHex Dump:\n") + fmt.Fprintf(w, out.HexDump) } return nil diff --git a/core/commands/name/publish.go b/core/commands/name/publish.go index b104aaeb5..bb4a4b708 100644 --- a/core/commands/name/publish.go +++ b/core/commands/name/publish.go @@ -13,7 +13,6 @@ import ( path "github.com/ipfs/boxo/coreiface/path" cmds "github.com/ipfs/go-ipfs-cmds" ke "github.com/ipfs/kubo/core/commands/keyencode" - peer "github.com/libp2p/go-libp2p/core/peer" ) var ( @@ -28,6 +27,7 @@ const ( ttlOptionName = "ttl" keyOptionName = "key" quieterOptionName = "quieter" + v1compatOptionName = "v1compat" ) var PublishCmd = &cmds.Command{ @@ -83,6 +83,7 @@ Alternatively, publish an using a valid PeerID (as listed by cmds.StringOption(ttlOptionName, "Time duration this record should be cached for. Uses the same syntax as the lifetime option. (caution: experimental)"), cmds.StringOption(keyOptionName, "k", "Name of the key to be used or a valid PeerID, as listed by 'ipfs key list -l'.").WithDefault("self"), cmds.BoolOption(quieterOptionName, "Q", "Write only final hash."), + cmds.BoolOption(v1compatOptionName, "Produce a backward-compatible IPNS Record by including fields for both V1 and V2 signatures.").WithDefault(true), ke.OptionIPNSBase, }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { @@ -90,12 +91,9 @@ Alternatively, publish an using a valid PeerID (as listed by if err != nil { return err } - keyEnc, err := ke.KeyEncoderFromString(req.Options[ke.OptionIPNSBase.Name()].(string)) - if err != nil { - return err - } allowOffline, _ := req.Options[allowOfflineOptionName].(bool) + compatibleWithV1, _ := req.Options[v1compatOptionName].(bool) kname, _ := req.Options[keyOptionName].(string) validTimeOpt, _ := req.Options[lifeTimeOptionName].(string) @@ -108,6 +106,7 @@ Alternatively, publish an using a valid PeerID (as listed by options.Name.AllowOffline(allowOffline), options.Name.Key(kname), options.Name.ValidTime(validTime), + options.Name.CompatibleWithV1(compatibleWithV1), } if ttl, found := req.Options[ttlOptionName].(string); found { @@ -128,7 +127,7 @@ Alternatively, publish an using a valid PeerID (as listed by } } - out, err := api.Name().Publish(req.Context, p, opts...) + name, err := api.Name().Publish(req.Context, p, opts...) if err != nil { if err == iface.ErrOffline { err = errAllowOffline @@ -136,15 +135,9 @@ Alternatively, publish an using a valid PeerID (as listed by return err } - // parse path, extract cid, re-base cid, reconstruct path - pid, err := peer.Decode(out.Name()) - if err != nil { - return err - } - return cmds.EmitOnce(res, &IpnsEntry{ - Name: keyEnc.FormatID(pid), - Value: out.Value().String(), + Name: name.String(), + Value: p.String(), }) }, Encoders: cmds.EncoderMap{ diff --git a/core/core_test.go b/core/core_test.go index 2d7e8927c..42dd543d7 100644 --- a/core/core_test.go +++ b/core/core_test.go @@ -1,28 +1,14 @@ package core import ( - "crypto/rand" - "errors" - "fmt" - "net/http/httptest" - "path" "testing" - "time" context "context" - "github.com/ipfs/boxo/ipns" - "github.com/ipfs/go-cid" - "github.com/ipfs/go-delegated-routing/client" - "github.com/ipfs/kubo/core/node/libp2p" "github.com/ipfs/kubo/repo" - "github.com/libp2p/go-libp2p/core/crypto" - peer "github.com/libp2p/go-libp2p/core/peer" - "github.com/stretchr/testify/require" datastore "github.com/ipfs/go-datastore" syncds "github.com/ipfs/go-datastore/sync" - drs "github.com/ipfs/go-delegated-routing/server" config "github.com/ipfs/kubo/config" ) @@ -79,285 +65,3 @@ var testIdentity = config.Identity{ PeerID: "QmNgdzLieYi8tgfo2WfTUzNVH5hQK9oAYGVf6dxN12NrHt", PrivKey: "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", } - -var errNotSupported = errors.New("method not supported") - -func TestDelegatedRoutingSingle(t *testing.T) { - require := require.New(t) - - pID1, priv1, err := GeneratePeerID() - require.NoError(err) - - pID2, _, err := GeneratePeerID() - require.NoError(err) - - theID := path.Join("/ipns", string(pID1)) - theErrorID := path.Join("/ipns", string(pID2)) - - d := &delegatedRoutingService{ - goodPeerID: pID1, - badPeerID: pID2, - pk1: priv1, - } - - url := StartRoutingServer(t, d) - n := GetNode(t, url) - - ctx := context.Background() - - v, err := n.Routing.GetValue(ctx, theID) - require.NoError(err) - require.NotNil(v) - require.Contains(string(v), "RECORD FROM SERVICE 0") - - v, err = n.Routing.GetValue(ctx, theErrorID) - require.Nil(v) - require.Error(err) - - err = n.Routing.PutValue(ctx, theID, v) - require.NoError(err) - -} - -func TestDelegatedRoutingMulti(t *testing.T) { - require := require.New(t) - - pID1, priv1, err := GeneratePeerID() - require.NoError(err) - - pID2, priv2, err := GeneratePeerID() - require.NoError(err) - - theID1 := path.Join("/ipns", string(pID1)) - theID2 := path.Join("/ipns", string(pID2)) - - d1 := &delegatedRoutingService{ - goodPeerID: pID1, - badPeerID: pID2, - pk1: priv1, - serviceID: 1, - } - - url1 := StartRoutingServer(t, d1) - - d2 := &delegatedRoutingService{ - goodPeerID: pID2, - badPeerID: pID1, - pk1: priv2, - serviceID: 2, - } - - url2 := StartRoutingServer(t, d2) - - n := GetNode(t, url1, url2) - - ctx := context.Background() - - v, err := n.Routing.GetValue(ctx, theID1) - require.NoError(err) - require.NotNil(v) - require.Contains(string(v), "RECORD FROM SERVICE 1") - - v, err = n.Routing.GetValue(ctx, theID2) - require.NoError(err) - require.NotNil(v) - require.Contains(string(v), "RECORD FROM SERVICE 2") -} - -func StartRoutingServer(t *testing.T, d drs.DelegatedRoutingService) string { - t.Helper() - - f := drs.DelegatedRoutingAsyncHandler(d) - svr := httptest.NewServer(f) - t.Cleanup(func() { - svr.Close() - }) - - return svr.URL -} - -func GetNode(t *testing.T, reframeURLs ...string) *IpfsNode { - t.Helper() - - routers := make(config.Routers) - var routerNames []string - for i, ru := range reframeURLs { - rn := fmt.Sprintf("reframe-%d", i) - routerNames = append(routerNames, rn) - routers[rn] = - config.RouterParser{ - Router: config.Router{ - Type: config.RouterTypeReframe, - Parameters: &config.ReframeRouterParams{ - Endpoint: ru, - }, - }, - } - } - - var crs []config.ConfigRouter - for _, rn := range routerNames { - crs = append(crs, config.ConfigRouter{ - RouterName: rn, - IgnoreErrors: true, - Timeout: config.Duration{Duration: time.Minute}, - }) - } - - const parallelRouterName = "parallel-router" - - routers[parallelRouterName] = config.RouterParser{ - Router: config.Router{ - Type: config.RouterTypeParallel, - Parameters: &config.ComposableRouterParams{ - Routers: crs, - }, - }, - } - cfg := config.Config{ - Identity: testIdentity, - Addresses: config.Addresses{ - Swarm: []string{"/ip4/0.0.0.0/tcp/0", "/ip4/0.0.0.0/udp/0/quic"}, - API: []string{"/ip4/127.0.0.1/tcp/0"}, - }, - Routing: config.Routing{ - Type: config.NewOptionalString("custom"), - Routers: routers, - Methods: config.Methods{ - config.MethodNameFindPeers: config.Method{ - RouterName: parallelRouterName, - }, - config.MethodNameFindProviders: config.Method{ - RouterName: parallelRouterName, - }, - config.MethodNameGetIPNS: config.Method{ - RouterName: parallelRouterName, - }, - config.MethodNameProvide: config.Method{ - RouterName: parallelRouterName, - }, - config.MethodNamePutIPNS: config.Method{ - RouterName: parallelRouterName, - }, - }, - }, - } - - r := &repo.Mock{ - C: cfg, - D: syncds.MutexWrap(datastore.NewMapDatastore()), - } - - n, err := NewNode(context.Background(), - &BuildCfg{ - Repo: r, - Online: true, - Routing: libp2p.ConstructDelegatedRouting( - cfg.Routing.Routers, - cfg.Routing.Methods, - cfg.Identity.PeerID, - cfg.Addresses, - cfg.Identity.PrivKey, - ), - }, - ) - require.NoError(t, err) - - return n -} - -func GeneratePeerID() (peer.ID, crypto.PrivKey, error) { - priv, pk, err := crypto.GenerateEd25519Key(rand.Reader) - if err != nil { - return peer.ID(""), nil, err - } - - pid, err := peer.IDFromPublicKey(pk) - return pid, priv, err -} - -type delegatedRoutingService struct { - goodPeerID, badPeerID peer.ID - pk1 crypto.PrivKey - serviceID int -} - -func (drs *delegatedRoutingService) FindProviders(ctx context.Context, key cid.Cid) (<-chan client.FindProvidersAsyncResult, error) { - return nil, errNotSupported -} - -func (drs *delegatedRoutingService) Provide(ctx context.Context, req *client.ProvideRequest) (<-chan client.ProvideAsyncResult, error) { - return nil, errNotSupported -} - -func (drs *delegatedRoutingService) GetIPNS(ctx context.Context, id []byte) (<-chan client.GetIPNSAsyncResult, error) { - ctx, cancel := context.WithCancel(ctx) - ch := make(chan client.GetIPNSAsyncResult) - go func() { - defer close(ch) - defer cancel() - - var out client.GetIPNSAsyncResult - switch peer.ID(id) { - case drs.goodPeerID: - ie, err := ipns.Create(drs.pk1, []byte(fmt.Sprintf("RECORD FROM SERVICE %d", drs.serviceID)), 0, time.Now().Add(10*time.Hour), 100*time.Hour) - if err != nil { - log.Fatal(err) - } - ieb, err := ie.Marshal() - if err != nil { - log.Fatal(err) - } - - out = client.GetIPNSAsyncResult{ - Record: ieb, - Err: nil, - } - case drs.badPeerID: - out = client.GetIPNSAsyncResult{ - Record: nil, - Err: errors.New("THE ERROR"), - } - default: - return - } - - select { - case <-ctx.Done(): - return - case ch <- out: - } - }() - - return ch, nil - -} - -func (drs *delegatedRoutingService) PutIPNS(ctx context.Context, id []byte, record []byte) (<-chan client.PutIPNSAsyncResult, error) { - ctx, cancel := context.WithCancel(ctx) - ch := make(chan client.PutIPNSAsyncResult) - go func() { - defer close(ch) - defer cancel() - - var out client.PutIPNSAsyncResult - switch peer.ID(id) { - case drs.goodPeerID: - out = client.PutIPNSAsyncResult{} - case drs.badPeerID: - out = client.PutIPNSAsyncResult{ - Err: fmt.Errorf("THE ERROR %d", drs.serviceID), - } - default: - return - } - - select { - case <-ctx.Done(): - return - case ch <- out: - } - }() - - return ch, nil -} diff --git a/core/coreapi/name.go b/core/coreapi/name.go index f07cfcd0c..3bf59a00c 100644 --- a/core/coreapi/name.go +++ b/core/coreapi/name.go @@ -6,6 +6,7 @@ import ( "strings" "time" + "github.com/ipfs/boxo/ipns" keystore "github.com/ipfs/boxo/keystore" "github.com/ipfs/boxo/namesys" "github.com/ipfs/kubo/tracing" @@ -23,33 +24,18 @@ import ( type NameAPI CoreAPI -type ipnsEntry struct { - name string - value path.Path -} - -// Name returns the ipnsEntry name. -func (e *ipnsEntry) Name() string { - return e.name -} - -// Value returns the ipnsEntry value. -func (e *ipnsEntry) Value() path.Path { - return e.value -} - // Publish announces new IPNS name and returns the new IPNS entry. -func (api *NameAPI) Publish(ctx context.Context, p path.Path, opts ...caopts.NamePublishOption) (coreiface.IpnsEntry, error) { +func (api *NameAPI) Publish(ctx context.Context, p path.Path, opts ...caopts.NamePublishOption) (ipns.Name, error) { ctx, span := tracing.Span(ctx, "CoreAPI.NameAPI", "Publish", trace.WithAttributes(attribute.String("path", p.String()))) defer span.End() if err := api.checkPublishAllowed(); err != nil { - return nil, err + return ipns.Name{}, err } options, err := caopts.NamePublishOptions(opts...) if err != nil { - return nil, err + return ipns.Name{}, err } span.SetAttributes( attribute.Bool("allowoffline", options.AllowOffline), @@ -62,23 +48,24 @@ func (api *NameAPI) Publish(ctx context.Context, p path.Path, opts ...caopts.Nam err = api.checkOnline(options.AllowOffline) if err != nil { - return nil, err + return ipns.Name{}, err } pth, err := ipath.ParsePath(p.String()) if err != nil { - return nil, err + return ipns.Name{}, err } k, err := keylookup(api.privateKey, api.repo.Keystore(), options.Key) if err != nil { - return nil, err + return ipns.Name{}, err } eol := time.Now().Add(options.ValidTime) publishOptions := []nsopts.PublishOption{ nsopts.PublishWithEOL(eol), + nsopts.PublishCompatibleWithV1(options.CompatibleWithV1), } if options.TTL != nil { @@ -87,18 +74,15 @@ func (api *NameAPI) Publish(ctx context.Context, p path.Path, opts ...caopts.Nam err = api.namesys.Publish(ctx, k, pth, publishOptions...) if err != nil { - return nil, err + return ipns.Name{}, err } pid, err := peer.IDFromPrivateKey(k) if err != nil { - return nil, err + return ipns.Name{}, err } - return &ipnsEntry{ - name: coreiface.FormatKeyID(pid), - value: p, - }, nil + return ipns.NameFromPeer(pid), nil } func (api *NameAPI) Search(ctx context.Context, name string, opts ...caopts.NameResolveOption) (<-chan coreiface.IpnsResult, error) { diff --git a/docs/changelogs/v0.22.md b/docs/changelogs/v0.22.md index 6fabdad7d..633741c88 100644 --- a/docs/changelogs/v0.22.md +++ b/docs/changelogs/v0.22.md @@ -6,6 +6,7 @@ - [Overview](#overview) - [🔦 Highlights](#-highlights) + - [`ipfs name publish` now supports V2 only IPNS records](#ipfs-name-publish-now-supports-v2-only-ipns-records) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -13,6 +14,15 @@ ### 🔦 Highlights +#### `ipfs name publish` now supports V2 only IPNS records + +When publishing an IPNS record, you are now able to create v2 only records +by passing `--v1compat=false`. By default, we still create V1+V2 records, such +that there is the highest chance of backwards compatibility. The goal is to move +to V2 only in the future. + +**TODO**: add links to IPIP https://github.com/ipfs/specs/issues/376 + ### 📝 Changelog ### 👨‍👩‍👧‍👦 Contributors diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 0fda8880c..abbd3eb72 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.18 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.10.1 + github.com/ipfs/boxo v0.10.2-0.20230620120822-417c5f7d61ff github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.27.7 github.com/multiformats/go-multiaddr v0.9.0 @@ -65,7 +65,6 @@ require ( github.com/ipfs/go-cid v0.4.1 // indirect github.com/ipfs/go-cidutil v0.1.0 // indirect github.com/ipfs/go-datastore v0.6.0 // indirect - github.com/ipfs/go-delegated-routing v0.8.0 // indirect github.com/ipfs/go-ds-badger v0.3.0 // indirect github.com/ipfs/go-ds-flatfs v0.5.1 // indirect github.com/ipfs/go-ds-leveldb v0.5.0 // indirect @@ -88,7 +87,6 @@ require ( github.com/ipfs/go-metrics-interface v0.0.1 // indirect github.com/ipfs/go-peertaskqueue v0.8.1 // indirect github.com/ipfs/go-unixfsnode v1.7.1 // indirect - github.com/ipld/edelweiss v0.2.0 // indirect github.com/ipld/go-codec-dagpb v1.6.0 // indirect github.com/ipld/go-ipld-prime v0.20.0 // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index d18d571e4..c438e3138 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -320,8 +320,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.10.1 h1:q0ZhbyN6iNZLipd6txt1xotCiP/icfvdAQ4YpUi+cL4= -github.com/ipfs/boxo v0.10.1/go.mod h1:1qgKq45mPRCxf4ZPoJV2lnXxyxucigILMJOrQrVivv8= +github.com/ipfs/boxo v0.10.2-0.20230620120822-417c5f7d61ff h1:QnYD2h1e55nX9lSl5k8YVij1VIOICR7lPJlhbKOQjNM= +github.com/ipfs/boxo v0.10.2-0.20230620120822-417c5f7d61ff/go.mod h1:OGMmq97krQBiKx8LRGyf5DgWHeu+PDdIHNN2YnQlWjs= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= @@ -344,8 +344,6 @@ github.com/ipfs/go-datastore v0.1.1/go.mod h1:w38XXW9kVFNp57Zj5knbKWM2T+KOZCGDRV github.com/ipfs/go-datastore v0.5.0/go.mod h1:9zhEApYMTl17C8YDp7JmU7sQZi2/wqiYh73hakZ90Bk= github.com/ipfs/go-datastore v0.6.0 h1:JKyz+Gvz1QEZw0LsX1IBn+JFCJQH4SJVFtM4uWU0Myk= github.com/ipfs/go-datastore v0.6.0/go.mod h1:rt5M3nNbSO/8q1t4LNkLyUwRs8HupMeN/8O4Vn9YAT8= -github.com/ipfs/go-delegated-routing v0.8.0 h1:faiRi4k8YioTxU2x7+pnrLQjR7jIQhGWN2JvCwcQ/aU= -github.com/ipfs/go-delegated-routing v0.8.0/go.mod h1:18Dds6ZoNTsff9S/7R49Nh2t2YNXIIKR/RLQmBZdjjY= github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk= github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps= github.com/ipfs/go-ds-badger v0.0.7/go.mod h1:qt0/fWzZDoPW6jpQeqUjR5kBfhDNB65jd9YlmAvpQBk= @@ -413,8 +411,6 @@ github.com/ipfs/go-unixfs v0.4.5 h1:wj8JhxvV1G6CD7swACwSKYa+NgtdWC1RUit+gFnymDU= github.com/ipfs/go-unixfsnode v1.7.1 h1:RRxO2b6CSr5UQ/kxnGzaChTjp5LWTdf3Y4n8ANZgB/s= github.com/ipfs/go-unixfsnode v1.7.1/go.mod h1:PVfoyZkX1B34qzT3vJO4nsLUpRCyhnMuHBznRcXirlk= github.com/ipfs/go-verifcid v0.0.2 h1:XPnUv0XmdH+ZIhLGKg6U2vaPaRDXb9urMyNVCE7uvTs= -github.com/ipld/edelweiss v0.2.0 h1:KfAZBP8eeJtrLxLhi7r3N0cBCo7JmwSRhOJp3WSpNjk= -github.com/ipld/edelweiss v0.2.0/go.mod h1:FJAzJRCep4iI8FOFlRriN9n0b7OuX3T/S9++NpBDmA4= github.com/ipld/go-car/v2 v2.9.1-0.20230325062757-fff0e4397a3d h1:22g+x1tgWSXK34i25qjs+afr7basaneEkHaglBshd2g= github.com/ipld/go-codec-dagpb v1.6.0 h1:9nYazfyu9B1p3NAgfVdpRco3Fs2nFC72DqVsMj6rOcc= github.com/ipld/go-codec-dagpb v1.6.0/go.mod h1:ANzFhfP2uMJxRBr8CE+WQWs5UsNa0pYtmKZ+agnUw9s= diff --git a/go.mod b/go.mod index 1b675c12e..6730b1914 100644 --- a/go.mod +++ b/go.mod @@ -13,15 +13,13 @@ require ( github.com/elgris/jsondiff v0.0.0-20160530203242-765b5c24c302 github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5 github.com/fsnotify/fsnotify v1.6.0 - github.com/gogo/protobuf v1.3.2 github.com/google/uuid v1.3.0 github.com/hashicorp/go-multierror v1.1.1 - github.com/ipfs/boxo v0.10.1 + github.com/ipfs/boxo v0.10.2-0.20230620120822-417c5f7d61ff github.com/ipfs/go-block-format v0.1.2 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 github.com/ipfs/go-datastore v0.6.0 - github.com/ipfs/go-delegated-routing v0.8.0 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 @@ -86,6 +84,7 @@ require ( golang.org/x/mod v0.10.0 golang.org/x/sync v0.2.0 golang.org/x/sys v0.9.0 + google.golang.org/protobuf v1.30.0 ) require ( @@ -116,6 +115,7 @@ require ( github.com/go-logr/stdr v1.2.2 // indirect github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/godbus/dbus/v5 v5.1.0 // indirect + github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/mock v1.6.0 // indirect github.com/golang/protobuf v1.5.3 // indirect @@ -140,7 +140,6 @@ require ( github.com/ipfs/go-ipld-cbor v0.0.6 // indirect github.com/ipfs/go-libipfs v0.7.0 // indirect github.com/ipfs/go-peertaskqueue v0.8.1 // indirect - github.com/ipld/edelweiss v0.2.0 // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/klauspost/compress v1.16.5 // indirect github.com/klauspost/cpuid/v2 v2.2.5 // indirect @@ -227,7 +226,6 @@ require ( google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect google.golang.org/grpc v1.55.0 // indirect - google.golang.org/protobuf v1.30.0 // indirect gopkg.in/square/go-jose.v2 v2.5.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect @@ -235,4 +233,4 @@ require ( nhooyr.io/websocket v1.8.7 // indirect ) -go 1.18 +go 1.19 diff --git a/go.sum b/go.sum index 6ba018697..87987a0df 100644 --- a/go.sum +++ b/go.sum @@ -355,8 +355,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.10.1 h1:q0ZhbyN6iNZLipd6txt1xotCiP/icfvdAQ4YpUi+cL4= -github.com/ipfs/boxo v0.10.1/go.mod h1:1qgKq45mPRCxf4ZPoJV2lnXxyxucigILMJOrQrVivv8= +github.com/ipfs/boxo v0.10.2-0.20230620120822-417c5f7d61ff h1:QnYD2h1e55nX9lSl5k8YVij1VIOICR7lPJlhbKOQjNM= +github.com/ipfs/boxo v0.10.2-0.20230620120822-417c5f7d61ff/go.mod h1:OGMmq97krQBiKx8LRGyf5DgWHeu+PDdIHNN2YnQlWjs= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= @@ -379,8 +379,6 @@ github.com/ipfs/go-datastore v0.1.1/go.mod h1:w38XXW9kVFNp57Zj5knbKWM2T+KOZCGDRV github.com/ipfs/go-datastore v0.5.0/go.mod h1:9zhEApYMTl17C8YDp7JmU7sQZi2/wqiYh73hakZ90Bk= github.com/ipfs/go-datastore v0.6.0 h1:JKyz+Gvz1QEZw0LsX1IBn+JFCJQH4SJVFtM4uWU0Myk= github.com/ipfs/go-datastore v0.6.0/go.mod h1:rt5M3nNbSO/8q1t4LNkLyUwRs8HupMeN/8O4Vn9YAT8= -github.com/ipfs/go-delegated-routing v0.8.0 h1:faiRi4k8YioTxU2x7+pnrLQjR7jIQhGWN2JvCwcQ/aU= -github.com/ipfs/go-delegated-routing v0.8.0/go.mod h1:18Dds6ZoNTsff9S/7R49Nh2t2YNXIIKR/RLQmBZdjjY= github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk= github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps= github.com/ipfs/go-ds-badger v0.0.7/go.mod h1:qt0/fWzZDoPW6jpQeqUjR5kBfhDNB65jd9YlmAvpQBk= @@ -452,8 +450,6 @@ github.com/ipfs/go-unixfs v0.4.5 h1:wj8JhxvV1G6CD7swACwSKYa+NgtdWC1RUit+gFnymDU= github.com/ipfs/go-unixfsnode v1.7.1 h1:RRxO2b6CSr5UQ/kxnGzaChTjp5LWTdf3Y4n8ANZgB/s= github.com/ipfs/go-unixfsnode v1.7.1/go.mod h1:PVfoyZkX1B34qzT3vJO4nsLUpRCyhnMuHBznRcXirlk= github.com/ipfs/go-verifcid v0.0.2 h1:XPnUv0XmdH+ZIhLGKg6U2vaPaRDXb9urMyNVCE7uvTs= -github.com/ipld/edelweiss v0.2.0 h1:KfAZBP8eeJtrLxLhi7r3N0cBCo7JmwSRhOJp3WSpNjk= -github.com/ipld/edelweiss v0.2.0/go.mod h1:FJAzJRCep4iI8FOFlRriN9n0b7OuX3T/S9++NpBDmA4= github.com/ipld/go-car v0.5.0 h1:kcCEa3CvYMs0iE5BzD5sV7O2EwMiCIp3uF8tA6APQT8= github.com/ipld/go-car/v2 v2.9.1-0.20230325062757-fff0e4397a3d h1:22g+x1tgWSXK34i25qjs+afr7basaneEkHaglBshd2g= github.com/ipld/go-codec-dagpb v1.6.0 h1:9nYazfyu9B1p3NAgfVdpRco3Fs2nFC72DqVsMj6rOcc= diff --git a/routing/delegated.go b/routing/delegated.go index 90a9c0807..26340fb72 100644 --- a/routing/delegated.go +++ b/routing/delegated.go @@ -10,8 +10,6 @@ import ( drclient "github.com/ipfs/boxo/routing/http/client" "github.com/ipfs/boxo/routing/http/contentrouter" "github.com/ipfs/go-datastore" - drc "github.com/ipfs/go-delegated-routing/client" - drp "github.com/ipfs/go-delegated-routing/gen/proto" logging "github.com/ipfs/go-log" version "github.com/ipfs/kubo" "github.com/ipfs/kubo/config" @@ -25,7 +23,6 @@ import ( "github.com/libp2p/go-libp2p/core/peer" "github.com/libp2p/go-libp2p/core/routing" ma "github.com/multiformats/go-multiaddr" - "github.com/multiformats/go-multicodec" "go.opencensus.io/stats/view" ) @@ -96,8 +93,6 @@ func parse(visited map[string]bool, switch cfg.Type { case config.RouterTypeHTTP: router, err = httpRoutingFromConfig(cfg.Router, extraHTTP) - case config.RouterTypeReframe: - router, err = reframeRoutingFromConfig(cfg.Router, extraHTTP) case config.RouterTypeDHT: router, err = dhtRoutingFromConfig(cfg.Router, extraDHT) case config.RouterTypeParallel: @@ -232,67 +227,6 @@ func httpRoutingFromConfig(conf config.Router, extraHTTP *ExtraHTTPParams) (rout }, nil } -func reframeRoutingFromConfig(conf config.Router, extraReframe *ExtraHTTPParams) (routing.Routing, error) { - var dr drp.DelegatedRouting_Client - - params := conf.Parameters.(*config.ReframeRouterParams) - - if params.Endpoint == "" { - return nil, NewParamNeededErr("Endpoint", conf.Type) - } - - // Increase per-host connection pool since we are making lots of concurrent requests. - transport := http.DefaultTransport.(*http.Transport).Clone() - transport.MaxIdleConns = 500 - transport.MaxIdleConnsPerHost = 100 - - delegateHTTPClient := &http.Client{ - Transport: transport, - } - dr, err := drp.New_DelegatedRouting_Client(params.Endpoint, - drp.DelegatedRouting_Client_WithHTTPClient(delegateHTTPClient), - ) - if err != nil { - return nil, err - } - - var c *drc.Client - - err = view.Register(drc.DefaultViews...) - if err != nil { - return nil, fmt.Errorf("registering delegated routing views: %w", err) - } - - // this path is for tests only - if extraReframe == nil { - c, err = drc.NewClient(dr, nil, nil) - if err != nil { - return nil, err - } - } else { - prov, err := createProvider(extraReframe.PeerID, extraReframe.Addrs) - if err != nil { - return nil, err - } - - key, err := decodePrivKey(extraReframe.PrivKeyB64) - if err != nil { - return nil, err - } - - c, err = drc.NewClient(dr, prov, key) - if err != nil { - return nil, err - } - } - - crc := drc.NewContentRoutingClient(c) - return &reframeRoutingWrapper{ - Client: c, - ContentRoutingClient: crc, - }, nil -} - func decodePrivKey(keyB64 string) (ic.PrivKey, error) { pk, err := base64.StdEncoding.DecodeString(keyB64) if err != nil { @@ -324,19 +258,6 @@ func createAddrInfo(peerID string, addrs []string) (peer.AddrInfo, error) { }, nil } -func createProvider(peerID string, addrs []string) (*drc.Provider, error) { - addrInfo, err := createAddrInfo(peerID, addrs) - if err != nil { - return nil, err - } - return &drc.Provider{ - Peer: addrInfo, - ProviderProto: []drc.TransferProtocol{ - {Codec: multicodec.TransportBitswap}, - }, - }, nil -} - type ExtraDHTParams struct { BootstrapPeers []peer.AddrInfo Host host.Host diff --git a/routing/delegated_test.go b/routing/delegated_test.go index ee7543114..da0210f5e 100644 --- a/routing/delegated_test.go +++ b/routing/delegated_test.go @@ -1,68 +1,27 @@ package routing import ( + "crypto/rand" "encoding/base64" "testing" "github.com/ipfs/kubo/config" - crypto "github.com/libp2p/go-libp2p/core/crypto" - peer "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/peer" "github.com/stretchr/testify/require" ) -func TestReframeRoutingFromConfig(t *testing.T) { - require := require.New(t) - - r, err := reframeRoutingFromConfig(config.Router{ - Type: config.RouterTypeReframe, - Parameters: &config.ReframeRouterParams{}, - }, nil) - - require.Nil(r) - require.EqualError(err, "configuration param 'Endpoint' is needed for reframe delegated routing types") - - r, err = reframeRoutingFromConfig(config.Router{ - Type: config.RouterTypeReframe, - Parameters: &config.ReframeRouterParams{ - Endpoint: "test", - }, - }, nil) - - require.NoError(err) - require.NotNil(r) - - priv, pub, err := crypto.GenerateKeyPair(crypto.RSA, 2048) - require.NoError(err) - - id, err := peer.IDFromPublicKey(pub) - require.NoError(err) - - privM, err := crypto.MarshalPrivateKey(priv) - require.NoError(err) - - r, err = reframeRoutingFromConfig(config.Router{ - Type: config.RouterTypeReframe, - Parameters: &config.ReframeRouterParams{ - Endpoint: "test", - }, - }, &ExtraHTTPParams{ - PeerID: id.String(), - Addrs: []string{"/ip4/0.0.0.0/tcp/4001"}, - PrivKeyB64: base64.StdEncoding.EncodeToString(privM), - }) - - require.NotNil(r) - require.NoError(err) -} - func TestParser(t *testing.T) { require := require.New(t) + pid, sk, err := generatePeerID() + require.NoError(err) + router, err := Parse(config.Routers{ "r1": config.RouterParser{ Router: config.Router{ - Type: config.RouterTypeReframe, - Parameters: &config.ReframeRouterParams{ + Type: config.RouterTypeHTTP, + Parameters: &config.HTTPRouterParams{ Endpoint: "testEndpoint", }, }, @@ -95,7 +54,10 @@ func TestParser(t *testing.T) { config.MethodNameProvide: config.Method{ RouterName: "r2", }, - }, &ExtraDHTParams{}, nil) + }, &ExtraDHTParams{}, &ExtraHTTPParams{ + PeerID: string(pid), + PrivKeyB64: sk, + }) require.NoError(err) @@ -109,27 +71,30 @@ func TestParser(t *testing.T) { func TestParserRecursive(t *testing.T) { require := require.New(t) + pid, sk, err := generatePeerID() + require.NoError(err) + router, err := Parse(config.Routers{ - "reframe1": config.RouterParser{ + "http1": config.RouterParser{ Router: config.Router{ - Type: config.RouterTypeReframe, - Parameters: &config.ReframeRouterParams{ + Type: config.RouterTypeHTTP, + Parameters: &config.HTTPRouterParams{ Endpoint: "testEndpoint1", }, }, }, - "reframe2": config.RouterParser{ + "http2": config.RouterParser{ Router: config.Router{ - Type: config.RouterTypeReframe, - Parameters: &config.ReframeRouterParams{ + Type: config.RouterTypeHTTP, + Parameters: &config.HTTPRouterParams{ Endpoint: "testEndpoint2", }, }, }, - "reframe3": config.RouterParser{ + "http3": config.RouterParser{ Router: config.Router{ - Type: config.RouterTypeReframe, - Parameters: &config.ReframeRouterParams{ + Type: config.RouterTypeHTTP, + Parameters: &config.HTTPRouterParams{ Endpoint: "testEndpoint3", }, }, @@ -140,10 +105,10 @@ func TestParserRecursive(t *testing.T) { Parameters: &config.ComposableRouterParams{ Routers: []config.ConfigRouter{ { - RouterName: "reframe1", + RouterName: "http1", }, { - RouterName: "reframe2", + RouterName: "http2", }, }, }, @@ -158,7 +123,7 @@ func TestParserRecursive(t *testing.T) { RouterName: "composable1", }, { - RouterName: "reframe3", + RouterName: "http3", }, }, }, @@ -180,7 +145,10 @@ func TestParserRecursive(t *testing.T) { config.MethodNameProvide: config.Method{ RouterName: "composable2", }, - }, &ExtraDHTParams{}, nil) + }, &ExtraDHTParams{}, &ExtraHTTPParams{ + PeerID: string(pid), + PrivKeyB64: sk, + }) require.NoError(err) @@ -237,3 +205,23 @@ func TestParserRecursiveLoop(t *testing.T) { require.ErrorContains(err, "dependency loop creating router with name \"composable2\"") } + +func generatePeerID() (string, string, error) { + sk, pk, err := crypto.GenerateEd25519Key(rand.Reader) + if err != nil { + return "", "", err + } + + bytes, err := crypto.MarshalPrivateKey(sk) + if err != nil { + return "", "", err + } + + enc := base64.StdEncoding.EncodeToString(bytes) + if err != nil { + return "", "", err + } + + pid, err := peer.IDFromPublicKey(pk) + return pid.String(), enc, err +} diff --git a/routing/wrapper.go b/routing/wrapper.go index d4215ca9c..f6a753843 100644 --- a/routing/wrapper.go +++ b/routing/wrapper.go @@ -3,39 +3,11 @@ package routing import ( "context" - "github.com/ipfs/go-cid" - drc "github.com/ipfs/go-delegated-routing/client" routinghelpers "github.com/libp2p/go-libp2p-routing-helpers" "github.com/libp2p/go-libp2p/core/peer" "github.com/libp2p/go-libp2p/core/routing" ) -var _ routing.Routing = &reframeRoutingWrapper{} -var _ routinghelpers.ProvideManyRouter = &reframeRoutingWrapper{} - -// reframeRoutingWrapper is a wrapper needed to construct the routing.Routing interface from -// delegated-routing library. -type reframeRoutingWrapper struct { - *drc.Client - *drc.ContentRoutingClient -} - -func (c *reframeRoutingWrapper) Provide(ctx context.Context, id cid.Cid, announce bool) error { - return c.ContentRoutingClient.Provide(ctx, id, announce) -} - -func (c *reframeRoutingWrapper) FindProvidersAsync(ctx context.Context, cid cid.Cid, count int) <-chan peer.AddrInfo { - return c.ContentRoutingClient.FindProvidersAsync(ctx, cid, count) -} - -func (c *reframeRoutingWrapper) Bootstrap(ctx context.Context) error { - return nil -} - -func (c *reframeRoutingWrapper) FindPeer(ctx context.Context, id peer.ID) (peer.AddrInfo, error) { - return peer.AddrInfo{}, routing.ErrNotSupported -} - type ProvideManyRouter interface { routinghelpers.ProvideManyRouter routing.Routing diff --git a/test/cli/fixtures/TestName.car b/test/cli/fixtures/TestName.car new file mode 100644 index 0000000000000000000000000000000000000000..5e3fd57b264508c46f73cbccc7a5e215e41658e0 GIT binary patch literal 421 zcmcColvbS!!+Z+3iVHF56Bq#a{Zm0QZ&DJ^|Br{{|^0i zp%>E2Qj3Z+^Ya)x7>Q9Xq|2qkSO_$B&fevpjLjaK+2!z-Sbo0g7jUdE?>00RLC%|>(rgQUzL_E-u$B1_QT@^ i7B>TBY!2+yiUj$NkRr02Ye0+#!QN9S&o9bJ;Q|08?65BY literal 0 HcmV?d00001 diff --git a/test/cli/name_test.go b/test/cli/name_test.go new file mode 100644 index 000000000..e0f2f0909 --- /dev/null +++ b/test/cli/name_test.go @@ -0,0 +1,266 @@ +package cli + +import ( + "bytes" + "encoding/json" + "fmt" + "os" + "strings" + "testing" + + "github.com/ipfs/boxo/ipns" + "github.com/ipfs/kubo/core/commands/name" + "github.com/ipfs/kubo/test/cli/harness" + "github.com/stretchr/testify/require" +) + +func TestName(t *testing.T) { + const ( + fixturePath = "fixtures/TestName.car" + fixtureCid = "bafybeidg3uxibfrt7uqh7zd5yaodetik7wjwi4u7rwv2ndbgj6ec7lsv2a" + dagCid = "bafyreidgts62p4rtg3rtmptmbv2dt46zjzin275fr763oku3wfod3quzay" + ) + + makeDaemon := func(t *testing.T, initArgs []string) *harness.Node { + node := harness.NewT(t).NewNode().Init(append([]string{"--profile=test"}, initArgs...)...) + r, err := os.Open(fixturePath) + require.Nil(t, err) + defer r.Close() + err = node.IPFSDagImport(r, fixtureCid) + require.NoError(t, err) + return node + } + + testPublishingWithSelf := func(keyType string) { + t.Run("Publishing with self (keyType = "+keyType+")", func(t *testing.T) { + t.Parallel() + + args := []string{} + if keyType != "default" { + args = append(args, "-a="+keyType) + } + + node := makeDaemon(t, args) + name := ipns.NameFromPeer(node.PeerID()) + + t.Run("Publishing a CID", func(t *testing.T) { + publishPath := "/ipfs/" + fixtureCid + + res := node.IPFS("name", "publish", "--allow-offline", publishPath) + require.Equal(t, fmt.Sprintf("Published to %s: %s\n", name.String(), publishPath), res.Stdout.String()) + + res = node.IPFS("name", "resolve", "/ipns/"+name.String()) + require.Equal(t, publishPath+"\n", res.Stdout.String()) + }) + + t.Run("Publishing a CID with -Q option", func(t *testing.T) { + publishPath := "/ipfs/" + fixtureCid + + res := node.IPFS("name", "publish", "--allow-offline", "-Q", publishPath) + require.Equal(t, name.String()+"\n", res.Stdout.String()) + + res = node.IPFS("name", "resolve", "/ipns/"+name.String()) + require.Equal(t, publishPath+"\n", res.Stdout.String()) + }) + + t.Run("Publishing a CID+subpath", func(t *testing.T) { + publishPath := "/ipfs/" + fixtureCid + "/hello" + + res := node.IPFS("name", "publish", "--allow-offline", publishPath) + require.Equal(t, fmt.Sprintf("Published to %s: %s\n", name.String(), publishPath), res.Stdout.String()) + + res = node.IPFS("name", "resolve", "/ipns/"+name.String()) + require.Equal(t, publishPath+"\n", res.Stdout.String()) + }) + + t.Run("Publishing nothing fails", func(t *testing.T) { + res := node.RunIPFS("name", "publish") + require.Error(t, res.Err) + require.Equal(t, 1, res.ExitCode()) + require.Contains(t, res.Stderr.String(), `argument "ipfs-path" is required`) + }) + + t.Run("Publishing with IPLD works", func(t *testing.T) { + publishPath := "/ipld/" + dagCid + "/thing" + res := node.IPFS("name", "publish", "--allow-offline", publishPath) + require.Equal(t, fmt.Sprintf("Published to %s: %s\n", name.String(), publishPath), res.Stdout.String()) + + res = node.IPFS("name", "resolve", "/ipns/"+name.String()) + require.Equal(t, publishPath+"\n", res.Stdout.String()) + }) + + publishPath := "/ipfs/" + fixtureCid + res := node.IPFS("name", "publish", "--allow-offline", publishPath) + require.Equal(t, fmt.Sprintf("Published to %s: %s\n", name.String(), publishPath), res.Stdout.String()) + + t.Run("Resolving self offline succeeds (daemon off)", func(t *testing.T) { + res = node.IPFS("name", "resolve", "--offline", "/ipns/"+name.String()) + require.Equal(t, publishPath+"\n", res.Stdout.String()) + + // Test without cache. + res = node.IPFS("name", "resolve", "--offline", "-n", "/ipns/"+name.String()) + require.Equal(t, publishPath+"\n", res.Stdout.String()) + }) + + node.StartDaemon() + + t.Run("Resolving self offline succeeds (daemon on)", func(t *testing.T) { + res = node.IPFS("name", "resolve", "--offline", "/ipns/"+name.String()) + require.Equal(t, publishPath+"\n", res.Stdout.String()) + + // Test without cache. + res = node.IPFS("name", "resolve", "--offline", "-n", "/ipns/"+name.String()) + require.Equal(t, publishPath+"\n", res.Stdout.String()) + }) + }) + } + + testPublishingWithSelf("default") + testPublishingWithSelf("rsa") + testPublishingWithSelf("ed25519") + + testPublishWithKey := func(name string, keyArgs ...string) { + t.Run(name, func(t *testing.T) { + t.Parallel() + node := makeDaemon(t, nil) + + keyGenArgs := []string{"key", "gen"} + keyGenArgs = append(keyGenArgs, keyArgs...) + keyGenArgs = append(keyGenArgs, "key") + + res := node.IPFS(keyGenArgs...) + key := strings.TrimSpace(res.Stdout.String()) + + publishPath := "/ipfs/" + fixtureCid + name, err := ipns.NameFromString(key) + require.NoError(t, err) + + res = node.IPFS("name", "publish", "--allow-offline", "--key="+key, publishPath) + require.Equal(t, fmt.Sprintf("Published to %s: %s\n", name.String(), publishPath), res.Stdout.String()) + }) + } + + testPublishWithKey("Publishing with RSA (with b58mh) Key", "--ipns-base=b58mh", "--type=rsa", "--size=2048") + testPublishWithKey("Publishing with ED25519 (with b58mh) Key", "--ipns-base=b58mh", "--type=ed25519") + testPublishWithKey("Publishing with ED25519 (with base36) Key", "--ipns-base=base36", "--type=ed25519") + + t.Run("Fails to publish in offline mode", func(t *testing.T) { + t.Parallel() + node := makeDaemon(t, nil).StartDaemon("--offline") + res := node.RunIPFS("name", "publish", "/ipfs/"+fixtureCid) + require.Error(t, res.Err) + require.Equal(t, 1, res.ExitCode()) + require.Contains(t, res.Stderr.String(), `can't publish while offline`) + }) + + t.Run("Publish V2-only record", func(t *testing.T) { + t.Parallel() + + node := makeDaemon(t, nil).StartDaemon() + ipnsName := ipns.NameFromPeer(node.PeerID()).String() + ipnsPath := ipns.NamespacePrefix + ipnsName + publishPath := "/ipfs/" + fixtureCid + + res := node.IPFS("name", "publish", "--ttl=30m", "--v1compat=false", publishPath) + require.Equal(t, fmt.Sprintf("Published to %s: %s\n", ipnsName, publishPath), res.Stdout.String()) + + res = node.IPFS("name", "resolve", ipnsPath) + require.Equal(t, publishPath+"\n", res.Stdout.String()) + + res = node.IPFS("routing", "get", ipnsPath) + record := res.Stdout.Bytes() + + res = node.PipeToIPFS(bytes.NewReader(record), "name", "inspect") + out := res.Stdout.String() + require.Contains(t, out, "This record was not validated.") + require.Contains(t, out, publishPath) + require.Contains(t, out, "30m") + + res = node.PipeToIPFS(bytes.NewReader(record), "name", "inspect", "--verify="+ipnsPath) + out = res.Stdout.String() + require.Contains(t, out, "Valid: true") + require.Contains(t, out, "Signature Type: V2") + require.Contains(t, out, fmt.Sprintf("Protobuf Size: %d", len(record))) + }) + + t.Run("Publish with TTL and inspect record", func(t *testing.T) { + t.Parallel() + + node := makeDaemon(t, nil).StartDaemon() + ipnsPath := ipns.NamespacePrefix + ipns.NameFromPeer(node.PeerID()).String() + publishPath := "/ipfs/" + fixtureCid + + _ = node.IPFS("name", "publish", "--ttl=30m", publishPath) + res := node.IPFS("routing", "get", ipnsPath) + record := res.Stdout.Bytes() + + t.Run("Inspect record shows correct TTL and that it is not validated", func(t *testing.T) { + t.Parallel() + res = node.PipeToIPFS(bytes.NewReader(record), "name", "inspect") + out := res.Stdout.String() + require.Contains(t, out, "This record was not validated.") + require.Contains(t, out, publishPath) + require.Contains(t, out, "30m") + require.Contains(t, out, "Signature Type: V1+V2") + require.Contains(t, out, fmt.Sprintf("Protobuf Size: %d", len(record))) + }) + + t.Run("Inspect record shows valid with correct name", func(t *testing.T) { + t.Parallel() + res := node.PipeToIPFS(bytes.NewReader(record), "name", "inspect", "--enc=json", "--verify="+ipnsPath) + val := name.IpnsInspectResult{} + err := json.Unmarshal(res.Stdout.Bytes(), &val) + require.NoError(t, err) + require.True(t, val.Validation.Valid) + }) + + t.Run("Inspect record shows invalid with wrong name", func(t *testing.T) { + t.Parallel() + res := node.PipeToIPFS(bytes.NewReader(record), "name", "inspect", "--enc=json", "--verify=12D3KooWRirYjmmQATx2kgHBfky6DADsLP7ex1t7BRxJ6nqLs9WH") + val := name.IpnsInspectResult{} + err := json.Unmarshal(res.Stdout.Bytes(), &val) + require.NoError(t, err) + require.False(t, val.Validation.Valid) + }) + }) + + t.Run("Inspect with verification using wrong RSA key errors", func(t *testing.T) { + t.Parallel() + node := makeDaemon(t, nil).StartDaemon() + + // Prepare RSA Key 1 + res := node.IPFS("key", "gen", "--type=rsa", "--size=4096", "key1") + key1 := strings.TrimSpace(res.Stdout.String()) + name1, err := ipns.NameFromString(key1) + require.NoError(t, err) + + // Prepare RSA Key 2 + res = node.IPFS("key", "gen", "--type=rsa", "--size=4096", "key2") + key2 := strings.TrimSpace(res.Stdout.String()) + name2, err := ipns.NameFromString(key2) + require.NoError(t, err) + + // Publish using Key 1 + publishPath := "/ipfs/" + fixtureCid + res = node.IPFS("name", "publish", "--allow-offline", "--key="+key1, publishPath) + require.Equal(t, fmt.Sprintf("Published to %s: %s\n", name1.String(), publishPath), res.Stdout.String()) + + // Get IPNS Record + res = node.IPFS("routing", "get", ipns.NamespacePrefix+name1.String()) + record := res.Stdout.Bytes() + + // Validate with correct key succeeds + res = node.PipeToIPFS(bytes.NewReader(record), "name", "inspect", "--verify="+name1.String(), "--enc=json") + val := name.IpnsInspectResult{} + err = json.Unmarshal(res.Stdout.Bytes(), &val) + require.NoError(t, err) + require.True(t, val.Validation.Valid) + + // Validate with wrong key fails + res = node.PipeToIPFS(bytes.NewReader(record), "name", "inspect", "--verify="+name2.String(), "--enc=json") + val = name.IpnsInspectResult{} + err = json.Unmarshal(res.Stdout.Bytes(), &val) + require.NoError(t, err) + require.False(t, val.Validation.Valid) + }) +} diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index f119128d2..7d7cdcaff 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -7,7 +7,7 @@ replace github.com/ipfs/kubo => ../../ require ( github.com/Kubuxu/gocovmerge v0.0.0-20161216165753-7ecaa51963cd github.com/golangci/golangci-lint v1.49.0 - github.com/ipfs/boxo v0.10.1 + github.com/ipfs/boxo v0.10.2-0.20230620120822-417c5f7d61ff github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 github.com/ipfs/go-datastore v0.6.0 diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 5c3a5ef94..cb27e68af 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -413,8 +413,8 @@ github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NH github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.10.1 h1:q0ZhbyN6iNZLipd6txt1xotCiP/icfvdAQ4YpUi+cL4= -github.com/ipfs/boxo v0.10.1/go.mod h1:1qgKq45mPRCxf4ZPoJV2lnXxyxucigILMJOrQrVivv8= +github.com/ipfs/boxo v0.10.2-0.20230620120822-417c5f7d61ff h1:QnYD2h1e55nX9lSl5k8YVij1VIOICR7lPJlhbKOQjNM= +github.com/ipfs/boxo v0.10.2-0.20230620120822-417c5f7d61ff/go.mod h1:OGMmq97krQBiKx8LRGyf5DgWHeu+PDdIHNN2YnQlWjs= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.1.2 h1:GAjkfhVx1f4YTODS6Esrj1wt2HhrtwTnhEr+DyPUaJo= diff --git a/test/sharness/t0100-name.sh b/test/sharness/t0100-name.sh deleted file mode 100755 index f49df3417..000000000 --- a/test/sharness/t0100-name.sh +++ /dev/null @@ -1,345 +0,0 @@ -#!/usr/bin/env bash -# -# Copyright (c) 2014 Jeromy Johnson -# MIT Licensed; see the LICENSE file in this repository. -# - -test_description="Test ipfs repo operations" - -. lib/test-lib.sh - -test_name_with_self() { - SELF_ALG=$1 - - test_expect_success "ipfs init (variant self $SELF_ALG)" ' - export IPFS_PATH="$(pwd)/.ipfs" && - case $SELF_ALG in - default) - ipfs init --empty-repo=false --profile=test > /dev/null - ;; - rsa) - ipfs init --empty-repo=false --profile=test -a=rsa > /dev/null - ;; - ed25519) - ipfs init --empty-repo=false --profile=test -a=ed25519 > /dev/null - ;; - esac && - export PEERID=`ipfs key list --ipns-base=base36 -l | grep self | cut -d " " -f1` && - test_check_peerid "${PEERID}" - ' - - # test publishing a hash - - test_expect_success "'ipfs name publish --allow-offline' succeeds" ' - ipfs name publish --allow-offline "/ipfs/$HASH_WELCOME_DOCS" >publish_out - ' - - test_expect_success "publish output looks good" ' - echo "Published to ${PEERID}: /ipfs/$HASH_WELCOME_DOCS" >expected1 && - test_cmp expected1 publish_out - ' - - test_expect_success "'ipfs name resolve' succeeds" ' - ipfs name resolve "$PEERID" >output - ' - - test_expect_success "resolve output looks good" ' - printf "/ipfs/%s\n" "$HASH_WELCOME_DOCS" >expected2 && - test_cmp expected2 output - ' - - # test publishing with -Q option - - test_expect_success "'ipfs name publish --quieter' succeeds" ' - ipfs name publish --allow-offline -Q "/ipfs/$HASH_WELCOME_DOCS" >publish_out - ' - - test_expect_success "publish --quieter output looks good" ' - echo "${PEERID}" >expected1 && - test_cmp expected1 publish_out - ' - - test_expect_success "'ipfs name resolve' succeeds" ' - ipfs name resolve "$PEERID" >output - ' - - test_expect_success "resolve output looks good" ' - printf "/ipfs/%s\n" "$HASH_WELCOME_DOCS" >expected2 && - test_cmp expected2 output - ' - - # now test with a path - - test_expect_success "'ipfs name publish --allow-offline' succeeds" ' - ipfs name publish --allow-offline "/ipfs/$HASH_WELCOME_DOCS/help" >publish_out - ' - - test_expect_success "publish a path looks good" ' - echo "Published to ${PEERID}: /ipfs/$HASH_WELCOME_DOCS/help" >expected3 && - test_cmp expected3 publish_out - ' - - test_expect_success "'ipfs name resolve' succeeds" ' - ipfs name resolve "$PEERID" >output - ' - - test_expect_success "resolve output looks good" ' - printf "/ipfs/%s/help\n" "$HASH_WELCOME_DOCS" >expected4 && - test_cmp expected4 output - ' - - test_expect_success "ipfs cat on published content succeeds" ' - ipfs cat "/ipfs/$HASH_WELCOME_DOCS/help" >expected && - ipfs cat "/ipns/$PEERID" >actual && - test_cmp expected actual - ' - - # publish with an explicit node ID - - test_expect_failure "'ipfs name publish --allow-offline ' succeeds" ' - echo ipfs name publish --allow-offline "${PEERID}" "/ipfs/$HASH_WELCOME_DOCS" && - ipfs name publish --allow-offline "${PEERID}" "/ipfs/$HASH_WELCOME_DOCS" >actual_node_id_publish - ' - - test_expect_failure "publish with our explicit node ID looks good" ' - echo "Published to ${PEERID}: /ipfs/$HASH_WELCOME_DOCS" >expected_node_id_publish && - test_cmp expected_node_id_publish actual_node_id_publish - ' - - # test publishing with B36CID and B58MH resolve to the same B36CID - - test_expect_success "verify self key output" ' - B58MH_ID=`ipfs key list --ipns-base=b58mh -l | grep self | cut -d " " -f1` && - B36CID_ID=`ipfs key list --ipns-base=base36 -l | grep self | cut -d " " -f1` && - test_check_peerid "${B58MH_ID}" && - test_check_peerid "${B36CID_ID}" - ' - - test_expect_success "'ipfs name publish --allow-offline --key= ' succeeds" ' - ipfs name publish --allow-offline --key=${B58MH_ID} "/ipfs/$HASH_WELCOME_DOCS" >b58mh_published_id_base36 && - ipfs name publish --allow-offline --key=${B36CID_ID} "/ipfs/$HASH_WELCOME_DOCS" >base36_published_id_base36 && - ipfs name publish --allow-offline --key=${B58MH_ID} --ipns-base=b58mh "/ipfs/$HASH_WELCOME_DOCS" >b58mh_published_id_b58mh && - ipfs name publish --allow-offline --key=${B36CID_ID} --ipns-base=b58mh "/ipfs/$HASH_WELCOME_DOCS" >base36_published_id_b58mh - ' - - test_expect_success "publish an explicit node ID as two key in B58MH and B36CID, name looks good" ' - echo "Published to ${B36CID_ID}: /ipfs/$HASH_WELCOME_DOCS" >expected_published_id_base36 && - echo "Published to ${B58MH_ID}: /ipfs/$HASH_WELCOME_DOCS" >expected_published_id_b58mh && - test_cmp expected_published_id_base36 b58mh_published_id_base36 && - test_cmp expected_published_id_base36 base36_published_id_base36 && - test_cmp expected_published_id_b58mh b58mh_published_id_b58mh && - test_cmp expected_published_id_b58mh base36_published_id_b58mh - ' - - test_expect_success "'ipfs name resolve' succeeds" ' - ipfs name resolve "$B36CID_ID" >output - ' - - test_expect_success "resolve output looks good" ' - printf "/ipfs/%s\n" "$HASH_WELCOME_DOCS" >expected2 && - test_cmp expected2 output - ' - - # test IPNS + IPLD - - test_expect_success "'ipfs dag put' succeeds" ' - HELLO_HASH="$(echo "\"hello world\"" | ipfs dag put)" && - OBJECT_HASH="$(echo "{\"thing\": {\"/\": \"${HELLO_HASH}\" }}" | ipfs dag put)" - ' - test_expect_success "'ipfs name publish --allow-offline /ipld/...' succeeds" ' - test_check_peerid "${PEERID}" && - ipfs name publish --allow-offline "/ipld/$OBJECT_HASH/thing" >publish_out - ' - test_expect_success "publish a path looks good" ' - echo "Published to ${PEERID}: /ipld/$OBJECT_HASH/thing" >expected3 && - test_cmp expected3 publish_out - ' - test_expect_success "'ipfs name resolve' succeeds" ' - ipfs name resolve "$PEERID" >output - ' - test_expect_success "resolve output looks good (IPNS + IPLD)" ' - printf "/ipld/%s/thing\n" "$OBJECT_HASH" >expected4 && - test_cmp expected4 output - ' - - # test publishing nothing - - test_expect_success "'ipfs name publish' fails" ' - printf '' | test_expect_code 1 ipfs name publish --allow-offline >publish_out 2>&1 - ' - - test_expect_success "publish output has the correct error" ' - grep "argument \"ipfs-path\" is required" publish_out - ' - - test_expect_success "'ipfs name publish' fails" ' - printf '' | test_expect_code 1 ipfs name publish -Q --allow-offline >publish_out 2>&1 - ' - - test_expect_success "publish output has the correct error" ' - grep "argument \"ipfs-path\" is required" publish_out - ' - - test_expect_success "'ipfs name publish --help' succeeds" ' - ipfs name publish --help - ' - - # test offline resolve - - test_expect_success "'ipfs name resolve --offline' succeeds" ' - ipfs name resolve --offline "$PEERID" >output - ' - test_expect_success "resolve output looks good (offline resolve)" ' - printf "/ipld/%s/thing\n" "$OBJECT_HASH" >expected4 && - test_cmp expected4 output - ' - - test_expect_success "'ipfs name resolve --offline -n' succeeds" ' - ipfs name resolve --offline -n "$PEERID" >output - ' - test_expect_success "resolve output looks good (offline resolve, -n)" ' - printf "/ipld/%s/thing\n" "$OBJECT_HASH" >expected4 && - test_cmp expected4 output - ' - - test_launch_ipfs_daemon - - test_expect_success "'ipfs name resolve --offline' succeeds" ' - ipfs name resolve --offline "$PEERID" >output - ' - test_expect_success "resolve output looks good (with daemon)" ' - printf "/ipld/%s/thing\n" "$OBJECT_HASH" >expected4 && - test_cmp expected4 output - ' - - test_expect_success "'ipfs name resolve --offline -n' succeeds" ' - ipfs name resolve --offline -n "$PEERID" >output - ' - test_expect_success "resolve output looks good (with daemon, -n)" ' - printf "/ipld/%s/thing\n" "$OBJECT_HASH" >expected4 && - test_cmp expected4 output - ' - - test_expect_success "empty request to name publish doesn't panic and returns error" ' - curl -X POST "http://$API_ADDR/api/v0/name/publish" > curl_out || true && - grep "argument \"ipfs-path\" is required" curl_out - ' - - # Test Publishing with TTL and Inspecting Records - test_expect_success "'ipfs name publish --ttl=30m' succeeds" ' - ipfs name publish --ttl=30m --allow-offline "/ipfs/$HASH_WELCOME_DOCS" - ' - - test_expect_success "retrieve IPNS key for further inspection" ' - ipfs routing get "/ipns/$PEERID" > ipns_record - ' - - test_expect_success "'ipfs name inspect' has correct TTL (30m)" ' - ipfs name inspect < ipns_record > verify_output && - test_should_contain "This record was not validated." verify_output && - test_should_contain "$HASH_WELCOME_DOCS" verify_output && - test_should_contain "1800000000000" verify_output - ' - - test_expect_success "'ipfs name inspect --verify' has '.Validation.Validity' set to 'true' with correct Peer ID" ' - ipfs name inspect --verify $PEERID --enc json < ipns_record | jq -e ".Validation.Valid == true and .Entry.TTL == .Entry.Data.TTL" - ' - - test_expect_success "'ipfs name inspect --verify' has '.Validation.Validity' set to 'false' with incorrect Peer ID" ' - ipfs name inspect --verify 12D3KooWRirYjmmQATx2kgHBfky6DADsLP7ex1t7BRxJ6nqLs9WH --enc json < ipns_record | jq -e ".Validation.Valid == false" - ' - - test_kill_ipfs_daemon - - # Test daemon in offline mode - test_launch_ipfs_daemon_without_network - - test_expect_success "'ipfs name publish' fails offline mode" ' - test_expect_code 1 ipfs name publish "/ipfs/$HASH_WELCOME_DOCS" - ' - - test_kill_ipfs_daemon - - test_expect_success "clean up ipfs dir" ' - rm -rf "$IPFS_PATH" - ' -} -test_name_with_self 'default' -test_name_with_self 'rsa' -test_name_with_self 'ed25519' - -test_name_with_key() { - GEN_ALG=$1 - - test_expect_success "ipfs init (key variant $GEN_ALG)" ' - export IPFS_PATH="$(pwd)/.ipfs" && - ipfs init --empty-repo=false --profile=test > /dev/null - ' - - test_expect_success "'prepare keys" ' - case $GEN_ALG in - rsa) - export KEY=`ipfs key gen --ipns-base=b58mh --type=rsa --size=2048 key` && - export KEY_B36CID=`ipfs key list --ipns-base=base36 -l | grep key | cut -d " " -f1` - ;; - ed25519_b58) - export KEY=`ipfs key gen --ipns-base=b58mh --type=ed25519 key` - export KEY_B36CID=`ipfs key list --ipns-base=base36 -l | grep key | cut -d " " -f1` - ;; - ed25519_b36) - export KEY=`ipfs key gen --ipns-base=base36 --type=ed25519 key` - export KEY_B36CID=$KEY - ;; - esac && - test_check_peerid "${KEY}" - ' - - # publish with an explicit node ID as key name - - test_expect_success "'ipfs name publish --allow-offline --key= ' succeeds" ' - ipfs name publish --allow-offline --key=${KEY} "/ipfs/$HASH_WELCOME_DOCS" >actual_node_id_publish - ' - - test_expect_success "publish an explicit node ID as key name looks good" ' - echo "Published to ${KEY_B36CID}: /ipfs/$HASH_WELCOME_DOCS" >expected_node_id_publish && - test_cmp expected_node_id_publish actual_node_id_publish - ' - - # cleanup - test_expect_success "clean up ipfs dir" ' - rm -rf "$IPFS_PATH" - ' -} -test_name_with_key 'rsa' -test_name_with_key 'ed25519_b58' -test_name_with_key 'ed25519_b36' - - -# `ipfs name inspect --verify` using the wrong RSA key should not succeed - -test_init_ipfs --empty-repo=false -test_launch_ipfs_daemon - -test_expect_success "prepare RSA keys" ' - export KEY_1=`ipfs key gen --type=rsa --size=4096 key1` && - export KEY_2=`ipfs key gen --type=rsa --size=4096 key2` && - export PEERID_1=`ipfs key list --ipns-base=base36 -l | grep key1 | cut -d " " -f1` && - export PEERID_2=`ipfs key list --ipns-base=base36 -l | grep key2 | cut -d " " -f1` -' - -test_expect_success "ipfs name publish --allow-offline --key= ' succeeds" ' - ipfs name publish --allow-offline --key=${KEY_1} "/ipfs/$( echo "helloworld" | ipfs add --inline -q )" && - ipfs routing get "/ipns/$PEERID_1" > ipns_record -' - -test_expect_success "ipfs name inspect --verify' has '.Validation.Validity' set to 'true' with correct Peer ID" ' - ipfs name inspect --verify $PEERID_1 --enc json < ipns_record | jq -e ".Validation.Valid == true" -' - -test_expect_success "ipfs name inspect --verify' has '.Validation.Validity' set to 'false' when we verify the wrong Peer ID" ' - ipfs name inspect --verify $PEERID_2 --enc json < ipns_record | jq -e ".Validation.Valid == false" -' - -test_kill_ipfs_daemon - -test_done From 05bcae456a4d21429c62536f1d02db09189209ba Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 22 Jun 2023 10:06:30 +0200 Subject: [PATCH 0753/1212] chore(deps): bump actions/checkout from 2 to 3 (#9975) Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 3. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v2...v3) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/codeql-analysis.yml | 2 +- .github/workflows/docker-image.yml | 2 +- .github/workflows/golang-analysis.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 49a47476a..04c695467 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -29,7 +29,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index eb991c5ac..51cabd9bc 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -23,7 +23,7 @@ jobs: LEGACY_IMAGE_NAME: ipfs/go-ipfs steps: - name: Check out the repo - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Set up QEMU uses: docker/setup-qemu-action@v2 diff --git a/.github/workflows/golang-analysis.yml b/.github/workflows/golang-analysis.yml index 684223edd..f65a6d22d 100644 --- a/.github/workflows/golang-analysis.yml +++ b/.github/workflows/golang-analysis.yml @@ -22,7 +22,7 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 10 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: submodules: recursive - uses: actions/setup-go@v2 From 873c6e15d574b59900fafb6fbf4379e0351fd256 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 22 Jun 2023 11:17:23 +0200 Subject: [PATCH 0754/1212] chore(deps): bump actions/github-script from 4 to 6 (#9977) * chore(deps): bump actions/github-script from 4 to 6 Bumps [actions/github-script](https://github.com/actions/github-script) from 4 to 6. - [Release notes](https://github.com/actions/github-script/releases) - [Commits](https://github.com/actions/github-script/compare/v4...v6) --- updated-dependencies: - dependency-name: actions/github-script dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] * Update sync-release-assets.yml --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Piotr Galar --- .github/workflows/sync-release-assets.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/sync-release-assets.yml b/.github/workflows/sync-release-assets.yml index 23bf90748..2ade3cbcc 100644 --- a/.github/workflows/sync-release-assets.yml +++ b/.github/workflows/sync-release-assets.yml @@ -26,14 +26,14 @@ jobs: with: node-version: 14 - name: Sync the latest 5 github releases - uses: actions/github-script@v4 + uses: actions/github-script@v6 with: script: | const fs = require('fs').promises const max_synced = 5 // fetch github releases - resp = await github.repos.listReleases({ + resp = await github.rest.repos.listReleases({ owner: context.repo.owner, repo: context.repo.repo, page: 1, @@ -116,7 +116,7 @@ jobs: } console.log("uploading", file, "to github release", release.tag_name) - const uploadReleaseAsset = async (file) => github.repos.uploadReleaseAsset({ + const uploadReleaseAsset = async (file) => github.rest.repos.uploadReleaseAsset({ owner: context.repo.owner, repo: context.repo.repo, release_id: release.id, From 67cd516ca57e548317494cf846d6e4f269de9436 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 22 Jun 2023 11:18:04 +0200 Subject: [PATCH 0755/1212] chore(deps): bump docker/login-action from 1.10.0 to 2.2.0 (#9979) Bumps [docker/login-action](https://github.com/docker/login-action) from 1.10.0 to 2.2.0. - [Release notes](https://github.com/docker/login-action/releases) - [Commits](https://github.com/docker/login-action/compare/f054a8b539a109f9f41c372932f1ae047eff08c9...465a07811f14bebb1938fbed4728c6a1ff8901fc) --- updated-dependencies: - dependency-name: docker/login-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/docker-image.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index 51cabd9bc..e64850c33 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -48,7 +48,7 @@ jobs: shell: bash - name: Log in to Docker Hub - uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9 + uses: docker/login-action@465a07811f14bebb1938fbed4728c6a1ff8901fc with: username: ${{ vars.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} From 37b215afa6a452f34aa1c58993e541d61105d954 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Thu, 22 Jun 2023 09:33:47 +0000 Subject: [PATCH 0756/1212] chore: update version --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index 06c8914db..cfe20ca70 100644 --- a/version.go +++ b/version.go @@ -11,7 +11,7 @@ import ( var CurrentCommit string // CurrentVersionNumber is the current application's version literal -const CurrentVersionNumber = "0.21.0-rc3" +const CurrentVersionNumber = "0.21.0" const ApiVersion = "/kubo/" + CurrentVersionNumber + "/" //nolint From 1972a49f91e878007c7efa1f6eb55ea19d97184b Mon Sep 17 00:00:00 2001 From: Dennis Trautwein Date: Mon, 26 Jun 2023 19:54:08 +0200 Subject: [PATCH 0757/1212] fix: docker repository initialization race condition When running the health check command without passing the `--api` command line flag and if the Kubo daemon is not active, executing `ipfs dag stat` will initialize the repository. It is common for the health check command to be run with root privileges. As a result, the repository will be owned by the root user. Then, if the Kubo daemon process attempts to access the repository later on, it will encounter a permission denied error because it runs as a non-privileged user by default. Hence, this modification simply provides the `--api` flag to the `ipfs dag stat` command. Given that we are operating within the limited confines of a docker container, we can make a few assumptions. I can't come up with a scenario where one would desire to assign a different port to the internal API rather than using the default 5001. Therefore, I have hard-coded the value accordingly. --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index e70abcc1a..a5c8d816c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -118,7 +118,7 @@ ENTRYPOINT ["/sbin/tini", "--", "/usr/local/bin/start_ipfs"] # Healthcheck for the container # QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn is the CID of empty folder HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ - CMD ipfs dag stat /ipfs/QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn || exit 1 + CMD ipfs --api=/ip4/127.0.0.1/tcp/5001 dag stat /ipfs/QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn || exit 1 # Execute the daemon subcommand by default CMD ["daemon", "--migrate=true", "--agent-version-suffix=docker"] From 61f0aa073715f9660b121494672484f8c4b335c2 Mon Sep 17 00:00:00 2001 From: Piotr Galar Date: Tue, 27 Jun 2023 12:57:54 +0200 Subject: [PATCH 0758/1212] ci: fix checking state of CI in ipfs-webui (#9969) --- .github/workflows/build.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3caee6bac..f6a2ced2b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -175,11 +175,11 @@ jobs: working-directory: ipfs-webui - id: state env: - GITHUB_REPOSITORY: ipfs/ipfs-webui - GITHUB_REF: ${{ steps.ref.outputs.ref }} GITHUB_TOKEN: ${{ github.token }} - run: | - echo "state=$(curl -L -H "Authorization: Bearer $GITHUB_TOKEN" "https://api.github.com/repos/$GITHUB_REPOSITORY/commits/$GITHUB_REF/status" --jq '.state')" | tee -a $GITHUB_OUTPUT + ENDPOINT: repos/ipfs/ipfs-webui/commits/${{ steps.ref.outputs.ref }}/status + SELECTOR: .state + KEY: state + run: gh api "$ENDPOINT" --jq "$SELECTOR" | xargs -I{} echo "$KEY={}" | tee -a $GITHUB_OUTPUT - name: Build ipfs-webui@main (state=${{ steps.state.outputs.state }}) run: npm run test:build working-directory: ipfs-webui From 3da4e5b409d4d360a182ce44fd499c92422202cd Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Tue, 27 Jun 2023 13:11:21 +0200 Subject: [PATCH 0759/1212] fix(gateway): include CORS on subdomain redirects (#9994) --- config/init.go | 8 ++--- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 +-- go.mod | 2 +- go.sum | 4 +-- test/dependencies/go.mod | 2 +- test/dependencies/go.sum | 4 +-- test/sharness/t0112-gateway-cors.sh | 45 +++++++++++++++++--------- 8 files changed, 41 insertions(+), 30 deletions(-) diff --git a/config/init.go b/config/init.go index 646d1e6e0..a6e3c46cc 100644 --- a/config/init.go +++ b/config/init.go @@ -67,12 +67,8 @@ func InitWithIdentity(identity Identity) (*Config, error) { RootRedirect: "", NoFetch: false, PathPrefixes: []string{}, - HTTPHeaders: map[string][]string{ - "Access-Control-Allow-Origin": {"*"}, - "Access-Control-Allow-Methods": {"GET"}, - "Access-Control-Allow-Headers": {"X-Requested-With", "Range", "User-Agent"}, - }, - APICommands: []string{}, + HTTPHeaders: map[string][]string{}, + APICommands: []string{}, }, Reprovider: Reprovider{ Interval: nil, diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index abbd3eb72..89600bb60 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.18 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.10.2-0.20230620120822-417c5f7d61ff + github.com/ipfs/boxo v0.10.2-0.20230627105028-a87f9ed0b2a9 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.27.7 github.com/multiformats/go-multiaddr v0.9.0 diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index c438e3138..baf37e35d 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -320,8 +320,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.10.2-0.20230620120822-417c5f7d61ff h1:QnYD2h1e55nX9lSl5k8YVij1VIOICR7lPJlhbKOQjNM= -github.com/ipfs/boxo v0.10.2-0.20230620120822-417c5f7d61ff/go.mod h1:OGMmq97krQBiKx8LRGyf5DgWHeu+PDdIHNN2YnQlWjs= +github.com/ipfs/boxo v0.10.2-0.20230627105028-a87f9ed0b2a9 h1:n66pkk54aXcGOrK2qJm+krxLQJWzo88skyefbuFqU44= +github.com/ipfs/boxo v0.10.2-0.20230627105028-a87f9ed0b2a9/go.mod h1:OGMmq97krQBiKx8LRGyf5DgWHeu+PDdIHNN2YnQlWjs= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= diff --git a/go.mod b/go.mod index 6730b1914..e2659eaff 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( github.com/fsnotify/fsnotify v1.6.0 github.com/google/uuid v1.3.0 github.com/hashicorp/go-multierror v1.1.1 - github.com/ipfs/boxo v0.10.2-0.20230620120822-417c5f7d61ff + github.com/ipfs/boxo v0.10.2-0.20230627105028-a87f9ed0b2a9 github.com/ipfs/go-block-format v0.1.2 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 diff --git a/go.sum b/go.sum index 87987a0df..c9e7af6b6 100644 --- a/go.sum +++ b/go.sum @@ -355,8 +355,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.10.2-0.20230620120822-417c5f7d61ff h1:QnYD2h1e55nX9lSl5k8YVij1VIOICR7lPJlhbKOQjNM= -github.com/ipfs/boxo v0.10.2-0.20230620120822-417c5f7d61ff/go.mod h1:OGMmq97krQBiKx8LRGyf5DgWHeu+PDdIHNN2YnQlWjs= +github.com/ipfs/boxo v0.10.2-0.20230627105028-a87f9ed0b2a9 h1:n66pkk54aXcGOrK2qJm+krxLQJWzo88skyefbuFqU44= +github.com/ipfs/boxo v0.10.2-0.20230627105028-a87f9ed0b2a9/go.mod h1:OGMmq97krQBiKx8LRGyf5DgWHeu+PDdIHNN2YnQlWjs= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 7d7cdcaff..c3ec0f64d 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -7,7 +7,7 @@ replace github.com/ipfs/kubo => ../../ require ( github.com/Kubuxu/gocovmerge v0.0.0-20161216165753-7ecaa51963cd github.com/golangci/golangci-lint v1.49.0 - github.com/ipfs/boxo v0.10.2-0.20230620120822-417c5f7d61ff + github.com/ipfs/boxo v0.10.2-0.20230627105028-a87f9ed0b2a9 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 github.com/ipfs/go-datastore v0.6.0 diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index cb27e68af..a06eb63ad 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -413,8 +413,8 @@ github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NH github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.10.2-0.20230620120822-417c5f7d61ff h1:QnYD2h1e55nX9lSl5k8YVij1VIOICR7lPJlhbKOQjNM= -github.com/ipfs/boxo v0.10.2-0.20230620120822-417c5f7d61ff/go.mod h1:OGMmq97krQBiKx8LRGyf5DgWHeu+PDdIHNN2YnQlWjs= +github.com/ipfs/boxo v0.10.2-0.20230627105028-a87f9ed0b2a9 h1:n66pkk54aXcGOrK2qJm+krxLQJWzo88skyefbuFqU44= +github.com/ipfs/boxo v0.10.2-0.20230627105028-a87f9ed0b2a9/go.mod h1:OGMmq97krQBiKx8LRGyf5DgWHeu+PDdIHNN2YnQlWjs= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.1.2 h1:GAjkfhVx1f4YTODS6Esrj1wt2HhrtwTnhEr+DyPUaJo= diff --git a/test/sharness/t0112-gateway-cors.sh b/test/sharness/t0112-gateway-cors.sh index 98b92f7de..e4fb57122 100755 --- a/test/sharness/t0112-gateway-cors.sh +++ b/test/sharness/t0112-gateway-cors.sh @@ -7,21 +7,9 @@ test_description="Test CORS behavior on Gateway port" test_init_ipfs # Default config -test_expect_success "Default Gateway.HTTPHeaders config match expected values" ' +test_expect_success "Default Gateway.HTTPHeaders is empty (implicit CORS values from boxo/gateway)" ' cat < expected -{ - "Access-Control-Allow-Headers": [ - "X-Requested-With", - "Range", - "User-Agent" - ], - "Access-Control-Allow-Methods": [ - "GET" - ], - "Access-Control-Allow-Origin": [ - "*" - ] -} +{} EOF ipfs config --json Gateway.HTTPHeaders > actual && test_cmp expected actual @@ -43,13 +31,19 @@ test_expect_success "GET to Gateway succeeds" ' test_expect_success "GET response for Gateway resource looks good" ' test_should_contain "< Access-Control-Allow-Origin: \*" curl_output && test_should_contain "< Access-Control-Allow-Methods: GET" curl_output && + test_should_contain "< Access-Control-Allow-Methods: HEAD" curl_output && + test_should_contain "< Access-Control-Allow-Methods: OPTIONS" curl_output && + test_should_contain "< Access-Control-Allow-Headers: Content-Type" curl_output && test_should_contain "< Access-Control-Allow-Headers: Range" curl_output && + test_should_contain "< Access-Control-Allow-Headers: User-Agent" curl_output && + test_should_contain "< Access-Control-Allow-Headers: X-Requested-With" curl_output && test_should_contain "< Access-Control-Expose-Headers: Content-Range" curl_output && test_should_contain "< Access-Control-Expose-Headers: Content-Length" curl_output && + test_should_contain "< Access-Control-Expose-Headers: X-Chunked-Output" curl_output && + test_should_contain "< Access-Control-Expose-Headers: X-Stream-Output" curl_output && test_should_contain "< Access-Control-Expose-Headers: X-Ipfs-Path" curl_output && test_should_contain "< Access-Control-Expose-Headers: X-Ipfs-Roots" curl_output ' - # HTTP OPTIONS Request test_expect_success "OPTIONS to Gateway succeeds" ' curl -svX OPTIONS -H "Origin: https://example.com" "http://127.0.0.1:$GWAY_PORT/ipfs/$thash" 2>curl_output && @@ -60,13 +54,34 @@ test_expect_success "OPTIONS to Gateway succeeds" ' test_expect_success "OPTIONS response for Gateway resource looks good" ' test_should_contain "< Access-Control-Allow-Origin: \*" curl_output && test_should_contain "< Access-Control-Allow-Methods: GET" curl_output && + test_should_contain "< Access-Control-Allow-Methods: HEAD" curl_output && + test_should_contain "< Access-Control-Allow-Methods: OPTIONS" curl_output && + test_should_contain "< Access-Control-Allow-Headers: Content-Type" curl_output && test_should_contain "< Access-Control-Allow-Headers: Range" curl_output && + test_should_contain "< Access-Control-Allow-Headers: User-Agent" curl_output && + test_should_contain "< Access-Control-Allow-Headers: X-Requested-With" curl_output && test_should_contain "< Access-Control-Expose-Headers: Content-Range" curl_output && test_should_contain "< Access-Control-Expose-Headers: Content-Length" curl_output && + test_should_contain "< Access-Control-Expose-Headers: X-Chunked-Output" curl_output && + test_should_contain "< Access-Control-Expose-Headers: X-Stream-Output" curl_output && test_should_contain "< Access-Control-Expose-Headers: X-Ipfs-Path" curl_output && test_should_contain "< Access-Control-Expose-Headers: X-Ipfs-Roots" curl_output ' +# HTTP OPTIONS Request on path → subdomain HTTP 301 redirect +# (regression test for https://github.com/ipfs/kubo/issues/9983#issuecomment-1599673976) +test_expect_success "OPTIONS to Gateway succeeds" ' + curl -svX OPTIONS -H "Origin: https://example.com" "http://localhost:$GWAY_PORT/ipfs/$thash" 2>curl_output && + cat curl_output +' +# OPTION Response from Gateway should contain CORS headers +test_expect_success "OPTIONS response for subdomain redirect looks good" ' + test_should_contain "HTTP/1.1 301 Moved Permanently" curl_output && + test_should_contain "Location" curl_output && + test_should_contain "< Access-Control-Allow-Origin: \*" curl_output && + test_should_contain "< Access-Control-Allow-Methods: GET" curl_output +' + test_kill_ipfs_daemon # Test CORS safelisting of custom headers From 40476501e9ac7f16fa45e5c8e41e06822473a0dd Mon Sep 17 00:00:00 2001 From: Laurent Senta Date: Tue, 27 Jun 2023 13:00:04 +0200 Subject: [PATCH 0760/1212] feat: update conformance to v0.2 --- .github/workflows/gateway-conformance.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/gateway-conformance.yml b/.github/workflows/gateway-conformance.yml index 8825f9bce..56457ea34 100644 --- a/.github/workflows/gateway-conformance.yml +++ b/.github/workflows/gateway-conformance.yml @@ -23,7 +23,7 @@ jobs: steps: # 1. Download the gateway-conformance fixtures - name: Download gateway-conformance fixtures - uses: ipfs/gateway-conformance/.github/actions/extract-fixtures@v0.1 + uses: ipfs/gateway-conformance/.github/actions/extract-fixtures@v0.2 with: output: fixtures @@ -47,6 +47,7 @@ jobs: { "example.com": { "UseSubdomains": true, + "InlineDNSLink": true, "Paths": ["/ipfs", "/ipns"] }, "localhost": { @@ -76,7 +77,8 @@ jobs: # Import dnslink records # the IPFS_NS_MAP env will be used by the daemon - export IPFS_NS_MAP=$(cat ./fixtures/dnslinks.json | jq -r 'to_entries | map("\(.key).example.com:\(.value)") | join(",")') + export IPFS_NS_MAP=$(cat "./fixtures/dnslinks.json" | jq -r '.subdomains | to_entries | map("\(.key).example.com:\(.value)") | join(",")') + export IPFS_NS_MAP="$(cat "./fixtures/dnslinks.json" | jq -r '.domains | to_entries | map("\(.key):\(.value)") | join(",")'),${IPFS_NS_MAP}" echo "IPFS_NS_MAP=${IPFS_NS_MAP}" >> $GITHUB_ENV # 5. Start the kubo-gateway @@ -87,7 +89,7 @@ jobs: # 6. Run the gateway-conformance tests - name: Run gateway-conformance tests - uses: ipfs/gateway-conformance/.github/actions/test@v0.1 + uses: ipfs/gateway-conformance/.github/actions/test@v0.2 with: gateway-url: http://127.0.0.1:8080 json: output.json From f2a6c4f7648e9a60c13ba5b040809e51e72c3266 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Tue, 27 Jun 2023 11:15:30 +0200 Subject: [PATCH 0761/1212] fix: correctly handle migration of configs readPluginsConfig was copied from ReadMigrationConfig and switched erroring fields to a bool so it can be omitemptied. --- config/config.go | 2 +- config/types.go | 13 +++++++++---- plugin/loader/loader.go | 38 ++++++++++++++++++++++++++++++++------ 3 files changed, 42 insertions(+), 11 deletions(-) diff --git a/config/config.go b/config/config.go index 93494265d..bc8ea371f 100644 --- a/config/config.go +++ b/config/config.go @@ -83,7 +83,7 @@ func Path(configroot, extension string) (string, error) { // - If the user-provided configuration file path is only a file name, use the // configuration root directory, otherwise use only the user-provided path // and ignore the configuration root. -func Filename(configroot string, userConfigFile string) (string, error) { +func Filename(configroot, userConfigFile string) (string, error) { if userConfigFile == "" { return Path(configroot, DefaultConfigFile) } diff --git a/config/types.go b/config/types.go index a781f023a..2171a53f5 100644 --- a/config/types.go +++ b/config/types.go @@ -415,9 +415,9 @@ func (p OptionalString) String() string { var _ json.Unmarshaler = (*OptionalInteger)(nil) var _ json.Marshaler = (*OptionalInteger)(nil) -type swarmLimits struct{} +type swarmLimits doNotUse -var _ json.Unmarshaler = swarmLimits{} +var _ json.Unmarshaler = swarmLimits(false) func (swarmLimits) UnmarshalJSON(b []byte) error { d := json.NewDecoder(bytes.NewReader(b)) @@ -439,9 +439,9 @@ func (swarmLimits) UnmarshalJSON(b []byte) error { } } -type experimentalAcceleratedDHTClient struct{} +type experimentalAcceleratedDHTClient doNotUse -var _ json.Unmarshaler = experimentalAcceleratedDHTClient{} +var _ json.Unmarshaler = experimentalAcceleratedDHTClient(false) func (experimentalAcceleratedDHTClient) UnmarshalJSON(b []byte) error { d := json.NewDecoder(bytes.NewReader(b)) @@ -462,3 +462,8 @@ func (experimentalAcceleratedDHTClient) UnmarshalJSON(b []byte) error { } } } + +// doNotUse is a type you must not use, it should be struct{} but encoding/json +// does not support omitempty on structs and I can't be bothered to write custom +// marshalers on all structs that have a doNotUse field. +type doNotUse bool diff --git a/plugin/loader/loader.go b/plugin/loader/loader.go index f891bb570..84ebdc0fc 100644 --- a/plugin/loader/loader.go +++ b/plugin/loader/loader.go @@ -1,6 +1,7 @@ package loader import ( + "encoding/json" "fmt" "io" "os" @@ -9,7 +10,6 @@ import ( "strings" config "github.com/ipfs/kubo/config" - cserialize "github.com/ipfs/kubo/config/serialize" "github.com/ipld/go-ipld-prime/multicodec" "github.com/ipfs/kubo/core" @@ -97,11 +97,10 @@ type PluginLoader struct { func NewPluginLoader(repo string) (*PluginLoader, error) { loader := &PluginLoader{plugins: make([]plugin.Plugin, 0, len(preloadPlugins)), repo: repo} if repo != "" { - cfg, err := cserialize.Load(filepath.Join(repo, config.DefaultConfigFile)) - switch err { - case cserialize.ErrNotInitialized: - case nil: - loader.config = cfg.Plugins + switch plugins, err := readPluginsConfig(repo, config.DefaultConfigFile); { + case err == nil: + loader.config = plugins + case os.IsNotExist(err): default: return nil, err } @@ -119,6 +118,33 @@ func NewPluginLoader(repo string) (*PluginLoader, error) { return loader, nil } +// readPluginsConfig reads the Plugins section of the IPFS config, avoiding +// reading anything other than the Plugin section. That way, we're free to +// make arbitrary changes to all _other_ sections in migrations. +func readPluginsConfig(repoRoot string, userConfigFile string) (config.Plugins, error) { + var cfg struct { + Plugins config.Plugins + } + + cfgPath, err := config.Filename(repoRoot, userConfigFile) + if err != nil { + return config.Plugins{}, err + } + + cfgFile, err := os.Open(cfgPath) + if err != nil { + return config.Plugins{}, err + } + defer cfgFile.Close() + + err = json.NewDecoder(cfgFile).Decode(&cfg) + if err != nil { + return config.Plugins{}, err + } + + return cfg.Plugins, nil +} + func (loader *PluginLoader) assertState(state loaderState) error { if loader.state != state { return fmt.Errorf("loader state must be %s, was %s", state, loader.state) From 92f651fda94970043a3e1272de491756c0f42a5e Mon Sep 17 00:00:00 2001 From: GitHub Date: Wed, 28 Jun 2023 08:49:44 +0000 Subject: [PATCH 0762/1212] chore: Update .github/workflows/stale.yml [skip ci] --- .github/workflows/stale.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 668bd07d4..16d65d721 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -2,7 +2,11 @@ name: Close and mark stale issue on: schedule: - - cron: '0 0 * * *' + - cron: '0 0 * * *' + +permissions: + issues: write + pull-requests: write jobs: stale: From dae41836c0859b0c0a6aa99e45b7b2893f36ea2d Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Thu, 29 Jun 2023 11:48:47 +0200 Subject: [PATCH 0763/1212] chore: bump to boxo master --- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- test/dependencies/go.mod | 3 ++- test/dependencies/go.sum | 6 ++++-- test/sharness/t0119-prometheus-data/prometheus_metrics | 4 ++-- test/sharness/t0600-issues-and-regressions-online.sh | 2 +- 8 files changed, 15 insertions(+), 12 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 89600bb60..7ac4a4cff 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.18 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.10.2-0.20230627105028-a87f9ed0b2a9 + github.com/ipfs/boxo v0.10.2-0.20230628084958-a91e44dbdbd4 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.27.7 github.com/multiformats/go-multiaddr v0.9.0 diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index baf37e35d..cd09c1a1d 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -320,8 +320,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.10.2-0.20230627105028-a87f9ed0b2a9 h1:n66pkk54aXcGOrK2qJm+krxLQJWzo88skyefbuFqU44= -github.com/ipfs/boxo v0.10.2-0.20230627105028-a87f9ed0b2a9/go.mod h1:OGMmq97krQBiKx8LRGyf5DgWHeu+PDdIHNN2YnQlWjs= +github.com/ipfs/boxo v0.10.2-0.20230628084958-a91e44dbdbd4 h1:TBdjIPaVgphrmtdbz/4BKyYgA1XLBOEBhRDbKXp4jnc= +github.com/ipfs/boxo v0.10.2-0.20230628084958-a91e44dbdbd4/go.mod h1:eVXIkLOG+fTJSuXtkANlwLllV1CEayOZnbDClK8ZOQY= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= diff --git a/go.mod b/go.mod index e2659eaff..950be507d 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( github.com/fsnotify/fsnotify v1.6.0 github.com/google/uuid v1.3.0 github.com/hashicorp/go-multierror v1.1.1 - github.com/ipfs/boxo v0.10.2-0.20230627105028-a87f9ed0b2a9 + github.com/ipfs/boxo v0.10.2-0.20230628084958-a91e44dbdbd4 github.com/ipfs/go-block-format v0.1.2 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 diff --git a/go.sum b/go.sum index c9e7af6b6..b8440afda 100644 --- a/go.sum +++ b/go.sum @@ -355,8 +355,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.10.2-0.20230627105028-a87f9ed0b2a9 h1:n66pkk54aXcGOrK2qJm+krxLQJWzo88skyefbuFqU44= -github.com/ipfs/boxo v0.10.2-0.20230627105028-a87f9ed0b2a9/go.mod h1:OGMmq97krQBiKx8LRGyf5DgWHeu+PDdIHNN2YnQlWjs= +github.com/ipfs/boxo v0.10.2-0.20230628084958-a91e44dbdbd4 h1:TBdjIPaVgphrmtdbz/4BKyYgA1XLBOEBhRDbKXp4jnc= +github.com/ipfs/boxo v0.10.2-0.20230628084958-a91e44dbdbd4/go.mod h1:eVXIkLOG+fTJSuXtkANlwLllV1CEayOZnbDClK8ZOQY= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index c3ec0f64d..63a267249 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -7,7 +7,7 @@ replace github.com/ipfs/kubo => ../../ require ( github.com/Kubuxu/gocovmerge v0.0.0-20161216165753-7ecaa51963cd github.com/golangci/golangci-lint v1.49.0 - github.com/ipfs/boxo v0.10.2-0.20230627105028-a87f9ed0b2a9 + github.com/ipfs/boxo v0.10.2-0.20230628084958-a91e44dbdbd4 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 github.com/ipfs/go-datastore v0.6.0 @@ -114,6 +114,7 @@ require ( github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-version v1.6.0 // indirect github.com/hashicorp/golang-lru v0.5.4 // indirect + github.com/hashicorp/golang-lru/v2 v2.0.2 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/hexops/gotextdiff v1.0.3 // indirect github.com/huin/goupnp v1.2.0 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index a06eb63ad..482bbfac1 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -398,6 +398,8 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/golang-lru/v2 v2.0.2 h1:Dwmkdr5Nc/oBiXgJS3CDHNhJtIHkuZ3DZF5twqnfBdU= +github.com/hashicorp/golang-lru/v2 v2.0.2/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= @@ -413,8 +415,8 @@ github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NH github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.10.2-0.20230627105028-a87f9ed0b2a9 h1:n66pkk54aXcGOrK2qJm+krxLQJWzo88skyefbuFqU44= -github.com/ipfs/boxo v0.10.2-0.20230627105028-a87f9ed0b2a9/go.mod h1:OGMmq97krQBiKx8LRGyf5DgWHeu+PDdIHNN2YnQlWjs= +github.com/ipfs/boxo v0.10.2-0.20230628084958-a91e44dbdbd4 h1:TBdjIPaVgphrmtdbz/4BKyYgA1XLBOEBhRDbKXp4jnc= +github.com/ipfs/boxo v0.10.2-0.20230628084958-a91e44dbdbd4/go.mod h1:eVXIkLOG+fTJSuXtkANlwLllV1CEayOZnbDClK8ZOQY= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.1.2 h1:GAjkfhVx1f4YTODS6Esrj1wt2HhrtwTnhEr+DyPUaJo= diff --git a/test/sharness/t0119-prometheus-data/prometheus_metrics b/test/sharness/t0119-prometheus-data/prometheus_metrics index 22239ff19..1b88486f0 100644 --- a/test/sharness/t0119-prometheus-data/prometheus_metrics +++ b/test/sharness/t0119-prometheus-data/prometheus_metrics @@ -124,8 +124,8 @@ ipfs_bitswap_sent_all_blocks_bytes_count ipfs_bitswap_sent_all_blocks_bytes_sum ipfs_bitswap_want_blocks_total ipfs_bitswap_wantlist_total -ipfs_bs_cache_arc_hits_total -ipfs_bs_cache_arc_total +ipfs_bs_cache_boxo_blockstore_cache_hits +ipfs_bs_cache_boxo_blockstore_cache_total ipfs_fsrepo_datastore_batchcommit_errors_total ipfs_fsrepo_datastore_batchcommit_latency_seconds_bucket ipfs_fsrepo_datastore_batchcommit_latency_seconds_count diff --git a/test/sharness/t0600-issues-and-regressions-online.sh b/test/sharness/t0600-issues-and-regressions-online.sh index 56384c0d0..809121640 100755 --- a/test/sharness/t0600-issues-and-regressions-online.sh +++ b/test/sharness/t0600-issues-and-regressions-online.sh @@ -29,7 +29,7 @@ test_expect_success "no panic traces on daemon" ' test_expect_success "metrics work" ' curl -X POST "$API_ADDR/debug/metrics/prometheus" > pro_data && - grep "ipfs_bs_cache_arc_hits_total" < pro_data || + grep "ipfs_bs_cache_boxo_blockstore_cache_total" < pro_data || test_fsh cat pro_data ' From 394d72db4cfaeb8a73ca7c64cafe65917e56afd5 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Thu, 29 Jun 2023 10:14:46 +0200 Subject: [PATCH 0764/1212] refactor: replace boxo/ipld/car by ipld/go-car --- core/commands/dag/export.go | 2 +- core/commands/dag/import.go | 2 +- docs/examples/kubo-as-a-library/go.mod | 3 ++- docs/examples/kubo-as-a-library/go.sum | 9 +++++---- go.mod | 8 +++++++- go.sum | 16 ++++++++++++---- test/dependencies/go.mod | 2 +- test/dependencies/go.sum | 9 +++++---- 8 files changed, 34 insertions(+), 17 deletions(-) diff --git a/core/commands/dag/export.go b/core/commands/dag/export.go index 9a8e11af1..337d8ce8f 100644 --- a/core/commands/dag/export.go +++ b/core/commands/dag/export.go @@ -15,8 +15,8 @@ import ( ipld "github.com/ipfs/go-ipld-format" "github.com/ipfs/kubo/core/commands/cmdenv" - gocar "github.com/ipfs/boxo/ipld/car" cmds "github.com/ipfs/go-ipfs-cmds" + gocar "github.com/ipld/go-car" selectorparse "github.com/ipld/go-ipld-prime/traversal/selector/parse" ) diff --git a/core/commands/dag/import.go b/core/commands/dag/import.go index 36f4176d5..76fa045ff 100644 --- a/core/commands/dag/import.go +++ b/core/commands/dag/import.go @@ -7,12 +7,12 @@ import ( "github.com/ipfs/boxo/coreiface/options" "github.com/ipfs/boxo/files" - gocarv2 "github.com/ipfs/boxo/ipld/car/v2" blocks "github.com/ipfs/go-block-format" cid "github.com/ipfs/go-cid" cmds "github.com/ipfs/go-ipfs-cmds" ipld "github.com/ipfs/go-ipld-format" ipldlegacy "github.com/ipfs/go-ipld-legacy" + gocarv2 "github.com/ipld/go-car/v2" "github.com/ipfs/kubo/core/commands/cmdenv" "github.com/ipfs/kubo/core/commands/cmdutils" diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 7ac4a4cff..4cf0ab9dc 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.18 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.10.2-0.20230628084958-a91e44dbdbd4 + github.com/ipfs/boxo v0.10.2-0.20230629140307-fdad9f921191 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.27.7 github.com/multiformats/go-multiaddr v0.9.0 @@ -87,6 +87,7 @@ require ( github.com/ipfs/go-metrics-interface v0.0.1 // indirect github.com/ipfs/go-peertaskqueue v0.8.1 // indirect github.com/ipfs/go-unixfsnode v1.7.1 // indirect + github.com/ipld/go-car/v2 v2.10.2-0.20230622090957-499d0c909d33 // indirect github.com/ipld/go-codec-dagpb v1.6.0 // indirect github.com/ipld/go-ipld-prime v0.20.0 // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index cd09c1a1d..103339ffb 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -320,8 +320,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.10.2-0.20230628084958-a91e44dbdbd4 h1:TBdjIPaVgphrmtdbz/4BKyYgA1XLBOEBhRDbKXp4jnc= -github.com/ipfs/boxo v0.10.2-0.20230628084958-a91e44dbdbd4/go.mod h1:eVXIkLOG+fTJSuXtkANlwLllV1CEayOZnbDClK8ZOQY= +github.com/ipfs/boxo v0.10.2-0.20230629140307-fdad9f921191 h1:oNiEZXJYb4B6zmvUc3F5vvS4xtll8naN8rz1hKftgd4= +github.com/ipfs/boxo v0.10.2-0.20230629140307-fdad9f921191/go.mod h1:8IfDmp+FzFGcF4zjAgHMVPpwYw4AjN9ePEzDfkaYJ1w= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= @@ -402,7 +402,7 @@ github.com/ipfs/go-log/v2 v2.1.3/go.mod h1:/8d0SH3Su5Ooc31QlL1WysJhvyOTDCjcCZ9Ax github.com/ipfs/go-log/v2 v2.3.0/go.mod h1:QqGoj30OTpnKaG/LKTGTxoP2mmQtjVMEnK72gynbe/g= github.com/ipfs/go-log/v2 v2.5.1 h1:1XdUzF7048prq4aBjDQQ4SL5RxftpRGdXhNRwKSAlcY= github.com/ipfs/go-log/v2 v2.5.1/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOLU9U5UI= -github.com/ipfs/go-merkledag v0.10.0 h1:IUQhj/kzTZfam4e+LnaEpoiZ9vZF6ldimVlby+6OXL4= +github.com/ipfs/go-merkledag v0.11.0 h1:DgzwK5hprESOzS4O1t/wi6JDpyVQdvm9Bs59N/jqfBY= github.com/ipfs/go-metrics-interface v0.0.1 h1:j+cpbjYvu4R8zbleSs36gvB7jR+wsL2fGD6n0jO4kdg= github.com/ipfs/go-metrics-interface v0.0.1/go.mod h1:6s6euYU4zowdslK0GKHmqaIZ3j/b/tL7HTWtJ4VPgWY= github.com/ipfs/go-peertaskqueue v0.8.1 h1:YhxAs1+wxb5jk7RvS0LHdyiILpNmRIRnZVztekOF0pg= @@ -411,7 +411,8 @@ github.com/ipfs/go-unixfs v0.4.5 h1:wj8JhxvV1G6CD7swACwSKYa+NgtdWC1RUit+gFnymDU= github.com/ipfs/go-unixfsnode v1.7.1 h1:RRxO2b6CSr5UQ/kxnGzaChTjp5LWTdf3Y4n8ANZgB/s= github.com/ipfs/go-unixfsnode v1.7.1/go.mod h1:PVfoyZkX1B34qzT3vJO4nsLUpRCyhnMuHBznRcXirlk= github.com/ipfs/go-verifcid v0.0.2 h1:XPnUv0XmdH+ZIhLGKg6U2vaPaRDXb9urMyNVCE7uvTs= -github.com/ipld/go-car/v2 v2.9.1-0.20230325062757-fff0e4397a3d h1:22g+x1tgWSXK34i25qjs+afr7basaneEkHaglBshd2g= +github.com/ipld/go-car/v2 v2.10.2-0.20230622090957-499d0c909d33 h1:0OZwzSYWIuiKEOXd/2vm5cMcEmmGLFn+1h6lHELCm3s= +github.com/ipld/go-car/v2 v2.10.2-0.20230622090957-499d0c909d33/go.mod h1:sQEkXVM3csejlb1kCCb+vQ/pWBKX9QtvsrysMQjOgOg= github.com/ipld/go-codec-dagpb v1.6.0 h1:9nYazfyu9B1p3NAgfVdpRco3Fs2nFC72DqVsMj6rOcc= github.com/ipld/go-codec-dagpb v1.6.0/go.mod h1:ANzFhfP2uMJxRBr8CE+WQWs5UsNa0pYtmKZ+agnUw9s= github.com/ipld/go-ipld-prime v0.11.0/go.mod h1:+WIAkokurHmZ/KwzDOMUuoeJgaRQktHtEaLglS3ZeV8= diff --git a/go.mod b/go.mod index 950be507d..2b66a8a35 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( github.com/fsnotify/fsnotify v1.6.0 github.com/google/uuid v1.3.0 github.com/hashicorp/go-multierror v1.1.1 - github.com/ipfs/boxo v0.10.2-0.20230628084958-a91e44dbdbd4 + github.com/ipfs/boxo v0.10.2-0.20230629140307-fdad9f921191 github.com/ipfs/go-block-format v0.1.2 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 @@ -36,6 +36,8 @@ require ( github.com/ipfs/go-metrics-interface v0.0.1 github.com/ipfs/go-metrics-prometheus v0.0.2 github.com/ipfs/go-unixfsnode v1.7.1 + github.com/ipld/go-car v0.5.0 + github.com/ipld/go-car/v2 v2.10.2-0.20230622090957-499d0c909d33 github.com/ipld/go-codec-dagpb v1.6.0 github.com/ipld/go-ipld-prime v0.20.0 github.com/jbenet/go-random v0.0.0-20190219211222-123a90aedc0c @@ -131,15 +133,19 @@ require ( github.com/huin/goupnp v1.2.0 // indirect github.com/ipfs/bbloom v0.0.4 // indirect github.com/ipfs/go-bitfield v1.1.0 // indirect + github.com/ipfs/go-blockservice v0.5.0 // indirect github.com/ipfs/go-ipfs-blockstore v1.3.0 // indirect github.com/ipfs/go-ipfs-delay v0.0.1 // indirect github.com/ipfs/go-ipfs-ds-help v1.1.0 // indirect + github.com/ipfs/go-ipfs-exchange-interface v0.2.0 // indirect github.com/ipfs/go-ipfs-pq v0.0.3 // indirect github.com/ipfs/go-ipfs-redirects-file v0.1.1 // indirect github.com/ipfs/go-ipfs-util v0.0.3 // indirect github.com/ipfs/go-ipld-cbor v0.0.6 // indirect github.com/ipfs/go-libipfs v0.7.0 // indirect + github.com/ipfs/go-merkledag v0.11.0 // indirect github.com/ipfs/go-peertaskqueue v0.8.1 // indirect + github.com/ipfs/go-verifcid v0.0.2 // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/klauspost/compress v1.16.5 // indirect github.com/klauspost/cpuid/v2 v2.2.5 // indirect diff --git a/go.sum b/go.sum index b8440afda..7b07ea02b 100644 --- a/go.sum +++ b/go.sum @@ -355,15 +355,17 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.10.2-0.20230628084958-a91e44dbdbd4 h1:TBdjIPaVgphrmtdbz/4BKyYgA1XLBOEBhRDbKXp4jnc= -github.com/ipfs/boxo v0.10.2-0.20230628084958-a91e44dbdbd4/go.mod h1:eVXIkLOG+fTJSuXtkANlwLllV1CEayOZnbDClK8ZOQY= +github.com/ipfs/boxo v0.10.2-0.20230629140307-fdad9f921191 h1:oNiEZXJYb4B6zmvUc3F5vvS4xtll8naN8rz1hKftgd4= +github.com/ipfs/boxo v0.10.2-0.20230629140307-fdad9f921191/go.mod h1:8IfDmp+FzFGcF4zjAgHMVPpwYw4AjN9ePEzDfkaYJ1w= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= +github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= github.com/ipfs/go-block-format v0.0.3/go.mod h1:4LmD4ZUw0mhO+JSKdpWwrzATiEfM7WWgQ8H5l6P8MVk= github.com/ipfs/go-block-format v0.1.2 h1:GAjkfhVx1f4YTODS6Esrj1wt2HhrtwTnhEr+DyPUaJo= github.com/ipfs/go-block-format v0.1.2/go.mod h1:mACVcrxarQKstUU3Yf/RdwbC4DzPV6++rO2a3d+a/KE= github.com/ipfs/go-blockservice v0.5.0 h1:B2mwhhhVQl2ntW2EIpaWPwSCxSuqr5fFA93Ms4bYLEY= +github.com/ipfs/go-blockservice v0.5.0/go.mod h1:W6brZ5k20AehbmERplmERn8o2Ni3ZZubvAxaIUeaT6w= github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.3/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.4/go.mod h1:4LLaPOQwmk5z9LBgQnpkivrx8BJjUyGwTXCd5Xfj6+M= @@ -407,6 +409,7 @@ github.com/ipfs/go-ipfs-delay v0.0.1/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG github.com/ipfs/go-ipfs-ds-help v1.1.0 h1:yLE2w9RAsl31LtfMt91tRZcrx+e61O5mDxFRR994w4Q= github.com/ipfs/go-ipfs-ds-help v1.1.0/go.mod h1:YR5+6EaebOhfcqVCyqemItCLthrpVNot+rsOU/5IatU= github.com/ipfs/go-ipfs-exchange-interface v0.2.0 h1:8lMSJmKogZYNo2jjhUs0izT+dck05pqUw4mWNW9Pw6Y= +github.com/ipfs/go-ipfs-exchange-interface v0.2.0/go.mod h1:z6+RhJuDQbqKguVyslSOuVDhqF9JtTrO3eptSAiW2/Y= github.com/ipfs/go-ipfs-exchange-offline v0.3.0 h1:c/Dg8GDPzixGd0MC8Jh6mjOwU57uYokgWRFidfvEkuA= github.com/ipfs/go-ipfs-files v0.3.0 h1:fallckyc5PYjuMEitPNrjRfpwl7YFt69heCOUhsbGxQ= github.com/ipfs/go-ipfs-posinfo v0.0.1 h1:Esoxj+1JgSjX0+ylc0hUmJCOv6V2vFoZiETLR6OtpRs= @@ -414,6 +417,7 @@ github.com/ipfs/go-ipfs-pq v0.0.3 h1:YpoHVJB+jzK15mr/xsWC574tyDLkezVrDNeaalQBsTE github.com/ipfs/go-ipfs-pq v0.0.3/go.mod h1:btNw5hsHBpRcSSgZtiNm/SLj5gYIZ18AKtv3kERkRb4= github.com/ipfs/go-ipfs-redirects-file v0.1.1 h1:Io++k0Vf/wK+tfnhEh63Yte1oQK5VGT2hIEYpD0Rzx8= github.com/ipfs/go-ipfs-redirects-file v0.1.1/go.mod h1:tAwRjCV0RjLTjH8DR/AU7VYvfQECg+lpUy2Mdzv7gyk= +github.com/ipfs/go-ipfs-routing v0.3.0 h1:9W/W3N+g+y4ZDeffSgqhgo7BsBSJwPMcyssET9OWevc= github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyBCNzQxlJBc= github.com/ipfs/go-ipfs-util v0.0.2/go.mod h1:CbPtkWJzjLdEcezDns2XYaehFVNXG9zrdrtMecczcsQ= github.com/ipfs/go-ipfs-util v0.0.3 h1:2RFdGez6bu2ZlZdI+rWfIdbQb1KudQp3VGwPtdNCmE0= @@ -439,7 +443,8 @@ github.com/ipfs/go-log/v2 v2.1.3/go.mod h1:/8d0SH3Su5Ooc31QlL1WysJhvyOTDCjcCZ9Ax github.com/ipfs/go-log/v2 v2.3.0/go.mod h1:QqGoj30OTpnKaG/LKTGTxoP2mmQtjVMEnK72gynbe/g= github.com/ipfs/go-log/v2 v2.5.1 h1:1XdUzF7048prq4aBjDQQ4SL5RxftpRGdXhNRwKSAlcY= github.com/ipfs/go-log/v2 v2.5.1/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOLU9U5UI= -github.com/ipfs/go-merkledag v0.10.0 h1:IUQhj/kzTZfam4e+LnaEpoiZ9vZF6ldimVlby+6OXL4= +github.com/ipfs/go-merkledag v0.11.0 h1:DgzwK5hprESOzS4O1t/wi6JDpyVQdvm9Bs59N/jqfBY= +github.com/ipfs/go-merkledag v0.11.0/go.mod h1:Q4f/1ezvBiJV0YCIXvt51W/9/kqJGH4I1LsA7+djsM4= github.com/ipfs/go-metrics-interface v0.0.1 h1:j+cpbjYvu4R8zbleSs36gvB7jR+wsL2fGD6n0jO4kdg= github.com/ipfs/go-metrics-interface v0.0.1/go.mod h1:6s6euYU4zowdslK0GKHmqaIZ3j/b/tL7HTWtJ4VPgWY= github.com/ipfs/go-metrics-prometheus v0.0.2 h1:9i2iljLg12S78OhC6UAiXi176xvQGiZaGVF1CUVdE+s= @@ -450,8 +455,11 @@ github.com/ipfs/go-unixfs v0.4.5 h1:wj8JhxvV1G6CD7swACwSKYa+NgtdWC1RUit+gFnymDU= github.com/ipfs/go-unixfsnode v1.7.1 h1:RRxO2b6CSr5UQ/kxnGzaChTjp5LWTdf3Y4n8ANZgB/s= github.com/ipfs/go-unixfsnode v1.7.1/go.mod h1:PVfoyZkX1B34qzT3vJO4nsLUpRCyhnMuHBznRcXirlk= github.com/ipfs/go-verifcid v0.0.2 h1:XPnUv0XmdH+ZIhLGKg6U2vaPaRDXb9urMyNVCE7uvTs= +github.com/ipfs/go-verifcid v0.0.2/go.mod h1:40cD9x1y4OWnFXbLNJYRe7MpNvWlMn3LZAG5Wb4xnPU= github.com/ipld/go-car v0.5.0 h1:kcCEa3CvYMs0iE5BzD5sV7O2EwMiCIp3uF8tA6APQT8= -github.com/ipld/go-car/v2 v2.9.1-0.20230325062757-fff0e4397a3d h1:22g+x1tgWSXK34i25qjs+afr7basaneEkHaglBshd2g= +github.com/ipld/go-car v0.5.0/go.mod h1:ppiN5GWpjOZU9PgpAZ9HbZd9ZgSpwPMr48fGRJOWmvE= +github.com/ipld/go-car/v2 v2.10.2-0.20230622090957-499d0c909d33 h1:0OZwzSYWIuiKEOXd/2vm5cMcEmmGLFn+1h6lHELCm3s= +github.com/ipld/go-car/v2 v2.10.2-0.20230622090957-499d0c909d33/go.mod h1:sQEkXVM3csejlb1kCCb+vQ/pWBKX9QtvsrysMQjOgOg= github.com/ipld/go-codec-dagpb v1.6.0 h1:9nYazfyu9B1p3NAgfVdpRco3Fs2nFC72DqVsMj6rOcc= github.com/ipld/go-codec-dagpb v1.6.0/go.mod h1:ANzFhfP2uMJxRBr8CE+WQWs5UsNa0pYtmKZ+agnUw9s= github.com/ipld/go-ipld-prime v0.11.0/go.mod h1:+WIAkokurHmZ/KwzDOMUuoeJgaRQktHtEaLglS3ZeV8= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 63a267249..302f7b803 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -7,7 +7,7 @@ replace github.com/ipfs/kubo => ../../ require ( github.com/Kubuxu/gocovmerge v0.0.0-20161216165753-7ecaa51963cd github.com/golangci/golangci-lint v1.49.0 - github.com/ipfs/boxo v0.10.2-0.20230628084958-a91e44dbdbd4 + github.com/ipfs/boxo v0.10.2-0.20230629140307-fdad9f921191 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 github.com/ipfs/go-datastore v0.6.0 diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 482bbfac1..bcf7966a5 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -415,8 +415,8 @@ github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NH github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.10.2-0.20230628084958-a91e44dbdbd4 h1:TBdjIPaVgphrmtdbz/4BKyYgA1XLBOEBhRDbKXp4jnc= -github.com/ipfs/boxo v0.10.2-0.20230628084958-a91e44dbdbd4/go.mod h1:eVXIkLOG+fTJSuXtkANlwLllV1CEayOZnbDClK8ZOQY= +github.com/ipfs/boxo v0.10.2-0.20230629140307-fdad9f921191 h1:oNiEZXJYb4B6zmvUc3F5vvS4xtll8naN8rz1hKftgd4= +github.com/ipfs/boxo v0.10.2-0.20230629140307-fdad9f921191/go.mod h1:8IfDmp+FzFGcF4zjAgHMVPpwYw4AjN9ePEzDfkaYJ1w= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.1.2 h1:GAjkfhVx1f4YTODS6Esrj1wt2HhrtwTnhEr+DyPUaJo= @@ -462,7 +462,7 @@ github.com/ipfs/go-log v1.0.5/go.mod h1:j0b8ZoR+7+R99LD9jZ6+AJsrzkPbSXbZfGakb5JP github.com/ipfs/go-log/v2 v2.1.3/go.mod h1:/8d0SH3Su5Ooc31QlL1WysJhvyOTDCjcCZ9Axpmri6g= github.com/ipfs/go-log/v2 v2.5.1 h1:1XdUzF7048prq4aBjDQQ4SL5RxftpRGdXhNRwKSAlcY= github.com/ipfs/go-log/v2 v2.5.1/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOLU9U5UI= -github.com/ipfs/go-merkledag v0.10.0 h1:IUQhj/kzTZfam4e+LnaEpoiZ9vZF6ldimVlby+6OXL4= +github.com/ipfs/go-merkledag v0.11.0 h1:DgzwK5hprESOzS4O1t/wi6JDpyVQdvm9Bs59N/jqfBY= github.com/ipfs/go-metrics-interface v0.0.1 h1:j+cpbjYvu4R8zbleSs36gvB7jR+wsL2fGD6n0jO4kdg= github.com/ipfs/go-metrics-interface v0.0.1/go.mod h1:6s6euYU4zowdslK0GKHmqaIZ3j/b/tL7HTWtJ4VPgWY= github.com/ipfs/go-peertaskqueue v0.8.1 h1:YhxAs1+wxb5jk7RvS0LHdyiILpNmRIRnZVztekOF0pg= @@ -477,7 +477,8 @@ github.com/ipfs/iptb v1.4.0 h1:YFYTrCkLMRwk/35IMyC6+yjoQSHTEcNcefBStLJzgvo= github.com/ipfs/iptb v1.4.0/go.mod h1:1rzHpCYtNp87/+hTxG5TfCVn/yMY3dKnLn8tBiMfdmg= github.com/ipfs/iptb-plugins v0.5.0 h1:zEMLlWAb531mLpD36KFy/yc0egT6FkBEHQtdERexNao= github.com/ipfs/iptb-plugins v0.5.0/go.mod h1:/6crDf3s58T70BhZ+m9SyyKpK7VvSDS2Ny4kafxXDp4= -github.com/ipld/go-car/v2 v2.9.1-0.20230325062757-fff0e4397a3d h1:22g+x1tgWSXK34i25qjs+afr7basaneEkHaglBshd2g= +github.com/ipld/go-car v0.5.0 h1:kcCEa3CvYMs0iE5BzD5sV7O2EwMiCIp3uF8tA6APQT8= +github.com/ipld/go-car/v2 v2.10.2-0.20230622090957-499d0c909d33 h1:0OZwzSYWIuiKEOXd/2vm5cMcEmmGLFn+1h6lHELCm3s= github.com/ipld/go-codec-dagpb v1.6.0 h1:9nYazfyu9B1p3NAgfVdpRco3Fs2nFC72DqVsMj6rOcc= github.com/ipld/go-codec-dagpb v1.6.0/go.mod h1:ANzFhfP2uMJxRBr8CE+WQWs5UsNa0pYtmKZ+agnUw9s= github.com/ipld/go-ipld-prime v0.20.0 h1:Ud3VwE9ClxpO2LkCYP7vWPc0Fo+dYdYzgxUJZ3uRG4g= From d1e31417521913dcdc6c90a6da13313e37ea807d Mon Sep 17 00:00:00 2001 From: Dennis Trautwein Date: Mon, 26 Jun 2023 19:54:08 +0200 Subject: [PATCH 0765/1212] fix: docker repository initialization race condition When running the health check command without passing the `--api` command line flag and if the Kubo daemon is not active, executing `ipfs dag stat` will initialize the repository. It is common for the health check command to be run with root privileges. As a result, the repository will be owned by the root user. Then, if the Kubo daemon process attempts to access the repository later on, it will encounter a permission denied error because it runs as a non-privileged user by default. Hence, this modification simply provides the `--api` flag to the `ipfs dag stat` command. Given that we are operating within the limited confines of a docker container, we can make a few assumptions. I can't come up with a scenario where one would desire to assign a different port to the internal API rather than using the default 5001. Therefore, I have hard-coded the value accordingly. (cherry picked from commit 1972a49f91e878007c7efa1f6eb55ea19d97184b) --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index e70abcc1a..a5c8d816c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -118,7 +118,7 @@ ENTRYPOINT ["/sbin/tini", "--", "/usr/local/bin/start_ipfs"] # Healthcheck for the container # QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn is the CID of empty folder HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ - CMD ipfs dag stat /ipfs/QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn || exit 1 + CMD ipfs --api=/ip4/127.0.0.1/tcp/5001 dag stat /ipfs/QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn || exit 1 # Execute the daemon subcommand by default CMD ["daemon", "--migrate=true", "--agent-version-suffix=docker"] From 76fe5fcd5b30c3e35c6480690de90363f50d5a22 Mon Sep 17 00:00:00 2001 From: Piotr Galar Date: Tue, 27 Jun 2023 12:57:54 +0200 Subject: [PATCH 0766/1212] ci: fix checking state of CI in ipfs-webui (#9969) (cherry picked from commit 61f0aa073715f9660b121494672484f8c4b335c2) --- .github/workflows/build.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3caee6bac..f6a2ced2b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -175,11 +175,11 @@ jobs: working-directory: ipfs-webui - id: state env: - GITHUB_REPOSITORY: ipfs/ipfs-webui - GITHUB_REF: ${{ steps.ref.outputs.ref }} GITHUB_TOKEN: ${{ github.token }} - run: | - echo "state=$(curl -L -H "Authorization: Bearer $GITHUB_TOKEN" "https://api.github.com/repos/$GITHUB_REPOSITORY/commits/$GITHUB_REF/status" --jq '.state')" | tee -a $GITHUB_OUTPUT + ENDPOINT: repos/ipfs/ipfs-webui/commits/${{ steps.ref.outputs.ref }}/status + SELECTOR: .state + KEY: state + run: gh api "$ENDPOINT" --jq "$SELECTOR" | xargs -I{} echo "$KEY={}" | tee -a $GITHUB_OUTPUT - name: Build ipfs-webui@main (state=${{ steps.state.outputs.state }}) run: npm run test:build working-directory: ipfs-webui From 9737e8871a2fe020a2ded8e6ca0be9c1ffb469b1 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Tue, 27 Jun 2023 13:11:21 +0200 Subject: [PATCH 0767/1212] fix(gateway): include CORS on subdomain redirects (#9994) (cherry picked from commit 3da4e5b409d4d360a182ce44fd499c92422202cd) --- config/init.go | 8 ++--- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 +-- go.mod | 2 +- go.sum | 4 +-- test/dependencies/go.mod | 2 +- test/dependencies/go.sum | 4 +-- test/sharness/t0112-gateway-cors.sh | 45 +++++++++++++++++--------- 8 files changed, 41 insertions(+), 30 deletions(-) diff --git a/config/init.go b/config/init.go index 646d1e6e0..a6e3c46cc 100644 --- a/config/init.go +++ b/config/init.go @@ -67,12 +67,8 @@ func InitWithIdentity(identity Identity) (*Config, error) { RootRedirect: "", NoFetch: false, PathPrefixes: []string{}, - HTTPHeaders: map[string][]string{ - "Access-Control-Allow-Origin": {"*"}, - "Access-Control-Allow-Methods": {"GET"}, - "Access-Control-Allow-Headers": {"X-Requested-With", "Range", "User-Agent"}, - }, - APICommands: []string{}, + HTTPHeaders: map[string][]string{}, + APICommands: []string{}, }, Reprovider: Reprovider{ Interval: nil, diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 0fda8880c..638934100 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.18 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.10.1 + github.com/ipfs/boxo v0.10.2-0.20230627105028-a87f9ed0b2a9 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.27.7 github.com/multiformats/go-multiaddr v0.9.0 diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index d18d571e4..284e07d3f 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -320,8 +320,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.10.1 h1:q0ZhbyN6iNZLipd6txt1xotCiP/icfvdAQ4YpUi+cL4= -github.com/ipfs/boxo v0.10.1/go.mod h1:1qgKq45mPRCxf4ZPoJV2lnXxyxucigILMJOrQrVivv8= +github.com/ipfs/boxo v0.10.2-0.20230627105028-a87f9ed0b2a9 h1:n66pkk54aXcGOrK2qJm+krxLQJWzo88skyefbuFqU44= +github.com/ipfs/boxo v0.10.2-0.20230627105028-a87f9ed0b2a9/go.mod h1:OGMmq97krQBiKx8LRGyf5DgWHeu+PDdIHNN2YnQlWjs= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= diff --git a/go.mod b/go.mod index 1b675c12e..2e999c47a 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/gogo/protobuf v1.3.2 github.com/google/uuid v1.3.0 github.com/hashicorp/go-multierror v1.1.1 - github.com/ipfs/boxo v0.10.1 + github.com/ipfs/boxo v0.10.2-0.20230627105028-a87f9ed0b2a9 github.com/ipfs/go-block-format v0.1.2 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 diff --git a/go.sum b/go.sum index 6ba018697..2a674d80c 100644 --- a/go.sum +++ b/go.sum @@ -355,8 +355,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.10.1 h1:q0ZhbyN6iNZLipd6txt1xotCiP/icfvdAQ4YpUi+cL4= -github.com/ipfs/boxo v0.10.1/go.mod h1:1qgKq45mPRCxf4ZPoJV2lnXxyxucigILMJOrQrVivv8= +github.com/ipfs/boxo v0.10.2-0.20230627105028-a87f9ed0b2a9 h1:n66pkk54aXcGOrK2qJm+krxLQJWzo88skyefbuFqU44= +github.com/ipfs/boxo v0.10.2-0.20230627105028-a87f9ed0b2a9/go.mod h1:OGMmq97krQBiKx8LRGyf5DgWHeu+PDdIHNN2YnQlWjs= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index f119128d2..c3ec0f64d 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -7,7 +7,7 @@ replace github.com/ipfs/kubo => ../../ require ( github.com/Kubuxu/gocovmerge v0.0.0-20161216165753-7ecaa51963cd github.com/golangci/golangci-lint v1.49.0 - github.com/ipfs/boxo v0.10.1 + github.com/ipfs/boxo v0.10.2-0.20230627105028-a87f9ed0b2a9 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 github.com/ipfs/go-datastore v0.6.0 diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 5c3a5ef94..a06eb63ad 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -413,8 +413,8 @@ github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NH github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.10.1 h1:q0ZhbyN6iNZLipd6txt1xotCiP/icfvdAQ4YpUi+cL4= -github.com/ipfs/boxo v0.10.1/go.mod h1:1qgKq45mPRCxf4ZPoJV2lnXxyxucigILMJOrQrVivv8= +github.com/ipfs/boxo v0.10.2-0.20230627105028-a87f9ed0b2a9 h1:n66pkk54aXcGOrK2qJm+krxLQJWzo88skyefbuFqU44= +github.com/ipfs/boxo v0.10.2-0.20230627105028-a87f9ed0b2a9/go.mod h1:OGMmq97krQBiKx8LRGyf5DgWHeu+PDdIHNN2YnQlWjs= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.1.2 h1:GAjkfhVx1f4YTODS6Esrj1wt2HhrtwTnhEr+DyPUaJo= diff --git a/test/sharness/t0112-gateway-cors.sh b/test/sharness/t0112-gateway-cors.sh index 98b92f7de..e4fb57122 100755 --- a/test/sharness/t0112-gateway-cors.sh +++ b/test/sharness/t0112-gateway-cors.sh @@ -7,21 +7,9 @@ test_description="Test CORS behavior on Gateway port" test_init_ipfs # Default config -test_expect_success "Default Gateway.HTTPHeaders config match expected values" ' +test_expect_success "Default Gateway.HTTPHeaders is empty (implicit CORS values from boxo/gateway)" ' cat < expected -{ - "Access-Control-Allow-Headers": [ - "X-Requested-With", - "Range", - "User-Agent" - ], - "Access-Control-Allow-Methods": [ - "GET" - ], - "Access-Control-Allow-Origin": [ - "*" - ] -} +{} EOF ipfs config --json Gateway.HTTPHeaders > actual && test_cmp expected actual @@ -43,13 +31,19 @@ test_expect_success "GET to Gateway succeeds" ' test_expect_success "GET response for Gateway resource looks good" ' test_should_contain "< Access-Control-Allow-Origin: \*" curl_output && test_should_contain "< Access-Control-Allow-Methods: GET" curl_output && + test_should_contain "< Access-Control-Allow-Methods: HEAD" curl_output && + test_should_contain "< Access-Control-Allow-Methods: OPTIONS" curl_output && + test_should_contain "< Access-Control-Allow-Headers: Content-Type" curl_output && test_should_contain "< Access-Control-Allow-Headers: Range" curl_output && + test_should_contain "< Access-Control-Allow-Headers: User-Agent" curl_output && + test_should_contain "< Access-Control-Allow-Headers: X-Requested-With" curl_output && test_should_contain "< Access-Control-Expose-Headers: Content-Range" curl_output && test_should_contain "< Access-Control-Expose-Headers: Content-Length" curl_output && + test_should_contain "< Access-Control-Expose-Headers: X-Chunked-Output" curl_output && + test_should_contain "< Access-Control-Expose-Headers: X-Stream-Output" curl_output && test_should_contain "< Access-Control-Expose-Headers: X-Ipfs-Path" curl_output && test_should_contain "< Access-Control-Expose-Headers: X-Ipfs-Roots" curl_output ' - # HTTP OPTIONS Request test_expect_success "OPTIONS to Gateway succeeds" ' curl -svX OPTIONS -H "Origin: https://example.com" "http://127.0.0.1:$GWAY_PORT/ipfs/$thash" 2>curl_output && @@ -60,13 +54,34 @@ test_expect_success "OPTIONS to Gateway succeeds" ' test_expect_success "OPTIONS response for Gateway resource looks good" ' test_should_contain "< Access-Control-Allow-Origin: \*" curl_output && test_should_contain "< Access-Control-Allow-Methods: GET" curl_output && + test_should_contain "< Access-Control-Allow-Methods: HEAD" curl_output && + test_should_contain "< Access-Control-Allow-Methods: OPTIONS" curl_output && + test_should_contain "< Access-Control-Allow-Headers: Content-Type" curl_output && test_should_contain "< Access-Control-Allow-Headers: Range" curl_output && + test_should_contain "< Access-Control-Allow-Headers: User-Agent" curl_output && + test_should_contain "< Access-Control-Allow-Headers: X-Requested-With" curl_output && test_should_contain "< Access-Control-Expose-Headers: Content-Range" curl_output && test_should_contain "< Access-Control-Expose-Headers: Content-Length" curl_output && + test_should_contain "< Access-Control-Expose-Headers: X-Chunked-Output" curl_output && + test_should_contain "< Access-Control-Expose-Headers: X-Stream-Output" curl_output && test_should_contain "< Access-Control-Expose-Headers: X-Ipfs-Path" curl_output && test_should_contain "< Access-Control-Expose-Headers: X-Ipfs-Roots" curl_output ' +# HTTP OPTIONS Request on path → subdomain HTTP 301 redirect +# (regression test for https://github.com/ipfs/kubo/issues/9983#issuecomment-1599673976) +test_expect_success "OPTIONS to Gateway succeeds" ' + curl -svX OPTIONS -H "Origin: https://example.com" "http://localhost:$GWAY_PORT/ipfs/$thash" 2>curl_output && + cat curl_output +' +# OPTION Response from Gateway should contain CORS headers +test_expect_success "OPTIONS response for subdomain redirect looks good" ' + test_should_contain "HTTP/1.1 301 Moved Permanently" curl_output && + test_should_contain "Location" curl_output && + test_should_contain "< Access-Control-Allow-Origin: \*" curl_output && + test_should_contain "< Access-Control-Allow-Methods: GET" curl_output +' + test_kill_ipfs_daemon # Test CORS safelisting of custom headers From 60c969d8e55f6bc16883f5a9b1c8ee3de909d922 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Tue, 27 Jun 2023 11:15:30 +0200 Subject: [PATCH 0768/1212] fix: correctly handle migration of configs readPluginsConfig was copied from ReadMigrationConfig and switched erroring fields to a bool so it can be omitemptied. (cherry picked from commit f2a6c4f7648e9a60c13ba5b040809e51e72c3266) --- config/config.go | 2 +- config/types.go | 13 +++++++++---- plugin/loader/loader.go | 38 ++++++++++++++++++++++++++++++++------ 3 files changed, 42 insertions(+), 11 deletions(-) diff --git a/config/config.go b/config/config.go index 93494265d..bc8ea371f 100644 --- a/config/config.go +++ b/config/config.go @@ -83,7 +83,7 @@ func Path(configroot, extension string) (string, error) { // - If the user-provided configuration file path is only a file name, use the // configuration root directory, otherwise use only the user-provided path // and ignore the configuration root. -func Filename(configroot string, userConfigFile string) (string, error) { +func Filename(configroot, userConfigFile string) (string, error) { if userConfigFile == "" { return Path(configroot, DefaultConfigFile) } diff --git a/config/types.go b/config/types.go index a781f023a..2171a53f5 100644 --- a/config/types.go +++ b/config/types.go @@ -415,9 +415,9 @@ func (p OptionalString) String() string { var _ json.Unmarshaler = (*OptionalInteger)(nil) var _ json.Marshaler = (*OptionalInteger)(nil) -type swarmLimits struct{} +type swarmLimits doNotUse -var _ json.Unmarshaler = swarmLimits{} +var _ json.Unmarshaler = swarmLimits(false) func (swarmLimits) UnmarshalJSON(b []byte) error { d := json.NewDecoder(bytes.NewReader(b)) @@ -439,9 +439,9 @@ func (swarmLimits) UnmarshalJSON(b []byte) error { } } -type experimentalAcceleratedDHTClient struct{} +type experimentalAcceleratedDHTClient doNotUse -var _ json.Unmarshaler = experimentalAcceleratedDHTClient{} +var _ json.Unmarshaler = experimentalAcceleratedDHTClient(false) func (experimentalAcceleratedDHTClient) UnmarshalJSON(b []byte) error { d := json.NewDecoder(bytes.NewReader(b)) @@ -462,3 +462,8 @@ func (experimentalAcceleratedDHTClient) UnmarshalJSON(b []byte) error { } } } + +// doNotUse is a type you must not use, it should be struct{} but encoding/json +// does not support omitempty on structs and I can't be bothered to write custom +// marshalers on all structs that have a doNotUse field. +type doNotUse bool diff --git a/plugin/loader/loader.go b/plugin/loader/loader.go index f891bb570..84ebdc0fc 100644 --- a/plugin/loader/loader.go +++ b/plugin/loader/loader.go @@ -1,6 +1,7 @@ package loader import ( + "encoding/json" "fmt" "io" "os" @@ -9,7 +10,6 @@ import ( "strings" config "github.com/ipfs/kubo/config" - cserialize "github.com/ipfs/kubo/config/serialize" "github.com/ipld/go-ipld-prime/multicodec" "github.com/ipfs/kubo/core" @@ -97,11 +97,10 @@ type PluginLoader struct { func NewPluginLoader(repo string) (*PluginLoader, error) { loader := &PluginLoader{plugins: make([]plugin.Plugin, 0, len(preloadPlugins)), repo: repo} if repo != "" { - cfg, err := cserialize.Load(filepath.Join(repo, config.DefaultConfigFile)) - switch err { - case cserialize.ErrNotInitialized: - case nil: - loader.config = cfg.Plugins + switch plugins, err := readPluginsConfig(repo, config.DefaultConfigFile); { + case err == nil: + loader.config = plugins + case os.IsNotExist(err): default: return nil, err } @@ -119,6 +118,33 @@ func NewPluginLoader(repo string) (*PluginLoader, error) { return loader, nil } +// readPluginsConfig reads the Plugins section of the IPFS config, avoiding +// reading anything other than the Plugin section. That way, we're free to +// make arbitrary changes to all _other_ sections in migrations. +func readPluginsConfig(repoRoot string, userConfigFile string) (config.Plugins, error) { + var cfg struct { + Plugins config.Plugins + } + + cfgPath, err := config.Filename(repoRoot, userConfigFile) + if err != nil { + return config.Plugins{}, err + } + + cfgFile, err := os.Open(cfgPath) + if err != nil { + return config.Plugins{}, err + } + defer cfgFile.Close() + + err = json.NewDecoder(cfgFile).Decode(&cfg) + if err != nil { + return config.Plugins{}, err + } + + return cfg.Plugins, nil +} + func (loader *PluginLoader) assertState(state loaderState) error { if loader.state != state { return fmt.Errorf("loader state must be %s, was %s", state, loader.state) From ac7f04d00fbf7de9aff227e9f9abd175faf72025 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Thu, 29 Jun 2023 16:35:03 +0200 Subject: [PATCH 0769/1212] chore: bump to boxo 0.10.2 --- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- test/dependencies/go.mod | 2 +- test/dependencies/go.sum | 4 ++-- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 638934100..40a4c8e45 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.18 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.10.2-0.20230627105028-a87f9ed0b2a9 + github.com/ipfs/boxo v0.10.2-0.20230629143123-2d3edc552442 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.27.7 github.com/multiformats/go-multiaddr v0.9.0 diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 284e07d3f..55b93e23a 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -320,8 +320,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.10.2-0.20230627105028-a87f9ed0b2a9 h1:n66pkk54aXcGOrK2qJm+krxLQJWzo88skyefbuFqU44= -github.com/ipfs/boxo v0.10.2-0.20230627105028-a87f9ed0b2a9/go.mod h1:OGMmq97krQBiKx8LRGyf5DgWHeu+PDdIHNN2YnQlWjs= +github.com/ipfs/boxo v0.10.2-0.20230629143123-2d3edc552442 h1:SGbw381zt6c1VFf3QCBaJ+eVJ4AwD9fPaFKFp9U9Apk= +github.com/ipfs/boxo v0.10.2-0.20230629143123-2d3edc552442/go.mod h1:1qgKq45mPRCxf4ZPoJV2lnXxyxucigILMJOrQrVivv8= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= diff --git a/go.mod b/go.mod index 2e999c47a..cd58e5cff 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/gogo/protobuf v1.3.2 github.com/google/uuid v1.3.0 github.com/hashicorp/go-multierror v1.1.1 - github.com/ipfs/boxo v0.10.2-0.20230627105028-a87f9ed0b2a9 + github.com/ipfs/boxo v0.10.2-0.20230629143123-2d3edc552442 github.com/ipfs/go-block-format v0.1.2 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 diff --git a/go.sum b/go.sum index 2a674d80c..319148117 100644 --- a/go.sum +++ b/go.sum @@ -355,8 +355,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.10.2-0.20230627105028-a87f9ed0b2a9 h1:n66pkk54aXcGOrK2qJm+krxLQJWzo88skyefbuFqU44= -github.com/ipfs/boxo v0.10.2-0.20230627105028-a87f9ed0b2a9/go.mod h1:OGMmq97krQBiKx8LRGyf5DgWHeu+PDdIHNN2YnQlWjs= +github.com/ipfs/boxo v0.10.2-0.20230629143123-2d3edc552442 h1:SGbw381zt6c1VFf3QCBaJ+eVJ4AwD9fPaFKFp9U9Apk= +github.com/ipfs/boxo v0.10.2-0.20230629143123-2d3edc552442/go.mod h1:1qgKq45mPRCxf4ZPoJV2lnXxyxucigILMJOrQrVivv8= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index c3ec0f64d..18d3d834e 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -7,7 +7,7 @@ replace github.com/ipfs/kubo => ../../ require ( github.com/Kubuxu/gocovmerge v0.0.0-20161216165753-7ecaa51963cd github.com/golangci/golangci-lint v1.49.0 - github.com/ipfs/boxo v0.10.2-0.20230627105028-a87f9ed0b2a9 + github.com/ipfs/boxo v0.10.2-0.20230629143123-2d3edc552442 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 github.com/ipfs/go-datastore v0.6.0 diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index a06eb63ad..bb4f8ebf5 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -413,8 +413,8 @@ github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NH github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.10.2-0.20230627105028-a87f9ed0b2a9 h1:n66pkk54aXcGOrK2qJm+krxLQJWzo88skyefbuFqU44= -github.com/ipfs/boxo v0.10.2-0.20230627105028-a87f9ed0b2a9/go.mod h1:OGMmq97krQBiKx8LRGyf5DgWHeu+PDdIHNN2YnQlWjs= +github.com/ipfs/boxo v0.10.2-0.20230629143123-2d3edc552442 h1:SGbw381zt6c1VFf3QCBaJ+eVJ4AwD9fPaFKFp9U9Apk= +github.com/ipfs/boxo v0.10.2-0.20230629143123-2d3edc552442/go.mod h1:1qgKq45mPRCxf4ZPoJV2lnXxyxucigILMJOrQrVivv8= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.1.2 h1:GAjkfhVx1f4YTODS6Esrj1wt2HhrtwTnhEr+DyPUaJo= From 4d5f2b89e97bb04b35c1463a8af442bc610cc600 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Thu, 29 Jun 2023 15:13:51 +0000 Subject: [PATCH 0770/1212] chore: update changelog for v0.21 --- docs/changelogs/v0.21.md | 188 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 188 insertions(+) diff --git a/docs/changelogs/v0.21.md b/docs/changelogs/v0.21.md index 394059472..b798c0d7b 100644 --- a/docs/changelogs/v0.21.md +++ b/docs/changelogs/v0.21.md @@ -152,4 +152,192 @@ should be using AcceleratedDHTClient because they are falling behind. ### 📝 Changelog +
Full Changelog + +- github.com/ipfs/kubo: + - fix: correctly handle migration of configs + - fix(gateway): include CORS on subdomain redirects (#9994) ([ipfs/kubo#9994](https://github.com/ipfs/kubo/pull/9994)) + - fix: docker repository initialization race condition + - chore: update version + - ([ipfs/kubo#9981](https://github.com/ipfs/kubo/pull/9981)) + - ([ipfs/kubo#9960](https://github.com/ipfs/kubo/pull/9960)) + - ([ipfs/kubo#9936](https://github.com/ipfs/kubo/pull/9936)) +- github.com/ipfs/boxo (v0.8.1 -> v0.10.2-0.20230629143123-2d3edc552442): + - chore: version 0.10.2 + - fix(gateway): include CORS on subdomain redirects (#395) ([ipfs/boxo#395](https://github.com/ipfs/boxo/pull/395)) + - fix(gateway): ensure 'X-Ipfs-Root' header is valid (#337) ([ipfs/boxo#337](https://github.com/ipfs/boxo/pull/337)) + - docs: prepare changelog for next release [ci skip] + - chore: version 0.10.1 (#359) ([ipfs/boxo#359](https://github.com/ipfs/boxo/pull/359)) + - fix(gateway): allow CAR trustless requests with path + - blockstore: replace go.uber.org/atomic with sync/atomic + - fix(gateway): remove handleUnsupportedHeaders after go-ipfs 0.13 (#350) ([ipfs/boxo#350](https://github.com/ipfs/boxo/pull/350)) + - docs: update RELEASE.md based on 0.9 release (#343) ([ipfs/boxo#343](https://github.com/ipfs/boxo/pull/343)) + - chore: v0.10.0 (#345) ([ipfs/boxo#345](https://github.com/ipfs/boxo/pull/345)) + - docs(changelog): car params from ipip-402 + - docs(changelog): add gateway deserialized responses (#341) ([ipfs/boxo#341](https://github.com/ipfs/boxo/pull/341)) + - feat(gateway): implement IPIP-402 extensions for gateway CAR requests (#303) ([ipfs/boxo#303](https://github.com/ipfs/boxo/pull/303)) + - chore: release v0.9.0 + - changelog: update for 0.8.1 and 0.9.0 + - provider: second round of reprovider refactor + - feat(unixfs): change protobuf package name to unixfs.v1.pb to prevent collisions with go-unixfs. Also regenerate protobufs with latest gogo + - feat(ipld/merkledag): remove use of go-ipld-format global registry + - feat(ipld/merkledag): updated to use its own global go-ipld-legacy registry instead of a shared global registry + - chore: do not rely on deprecated logger + - changelog: add changelog for async pin listing (#336) ([ipfs/boxo#336](https://github.com/ipfs/boxo/pull/336)) + - pinner: change the interface to have async pin listing + - provider: revert throughput callback and related refactor + - fix(gateway): question marks in url.Path when redirecting (#313) ([ipfs/boxo#313](https://github.com/ipfs/boxo/pull/313)) + - fix(gateway)!: no duplicate payload during subdomain redirects (#326) ([ipfs/boxo#326](https://github.com/ipfs/boxo/pull/326)) + - provider: add breaking changes to the changelog (#330) ([ipfs/boxo#330](https://github.com/ipfs/boxo/pull/330)) + - relocated magic numbers, updated Reprovide Interval from 24h to 22h + - provider: refactor to only maintain one batched implementation and add throughput callback + - feat(gateway): HTML preview for dag-cbor and dag-json (#315) ([ipfs/boxo#315](https://github.com/ipfs/boxo/pull/315)) + - coreiface: add a testing.T argument to the provider + - feat(gateway): improved templates, user friendly errors (#298) ([ipfs/boxo#298](https://github.com/ipfs/boxo/pull/298)) + - feat(gateway)!: deserialised responses turned off by default (#252) ([ipfs/boxo#252](https://github.com/ipfs/boxo/pull/252)) + - fix(gw): missing return in error case ([ipfs/boxo#319](https://github.com/ipfs/boxo/pull/319)) + - feat(routing/http): pass records limit on routing.FindProviders (#299) ([ipfs/boxo#299](https://github.com/ipfs/boxo/pull/299)) + - bitswap/client: fix PeerResponseTrackerProbabilityOneKnownOneUnknownPeer + - feat(gw): add ipfs_http_gw_car_stream_fail_duration_seconds (#312) ([ipfs/boxo#312](https://github.com/ipfs/boxo/pull/312)) + - feat(gw): add ipfs_http_gw_request_types metric (#311) ([ipfs/boxo#311](https://github.com/ipfs/boxo/pull/311)) + - refactor: simplify ipns validation in example + - feat: add deprecator + - fix(routing/v1): add newline in NDJSON responses (#300) ([ipfs/boxo#300](https://github.com/ipfs/boxo/pull/300)) + - feat(gateway): redirect ipns b58mh to cid (#236) ([ipfs/boxo#236](https://github.com/ipfs/boxo/pull/236)) + - refactor: replace assert.Nil for assert.NoError + - tar: add test cases for validatePlatformPath + - feat(ipns): helper ValidateWithPeerID and UnmarshalIpnsEntry (#294) ([ipfs/boxo#294](https://github.com/ipfs/boxo/pull/294)) + - Revert "feat: reusable ipns verify (#292)" + - feat: reusable ipns verify (#292) ([ipfs/boxo#292](https://github.com/ipfs/boxo/pull/292)) + - refactor: remove badger, leveldb dependencies (#286) ([ipfs/boxo#286](https://github.com/ipfs/boxo/pull/286)) + - feat(routing/http): add streaming support (#18) ([ipfs/boxo#18](https://github.com/ipfs/boxo/pull/18)) + - feat(routing): allow-offline with routing put (#278) ([ipfs/boxo#278](https://github.com/ipfs/boxo/pull/278)) + - refactor(gateway): switch to xxhash/v2 (#285) ([ipfs/boxo#285](https://github.com/ipfs/boxo/pull/285)) +- github.com/ipfs/go-ipfs-util (v0.0.2 -> v0.0.3): + - docs: remove contribution section + - chore: bump version + - chore: deprecate types and readme + - sync: update CI config files (#12) ([ipfs/go-ipfs-util#12](https://github.com/ipfs/go-ipfs-util/pull/12)) + - fix staticcheck ([ipfs/go-ipfs-util#9](https://github.com/ipfs/go-ipfs-util/pull/9)) +- github.com/ipfs/go-ipld-format (v0.4.0 -> v0.5.0): + - chore: release version v0.5.0 + - feat: remove block decoding global registry + - sync: update CI config files (#75) ([ipfs/go-ipld-format#75](https://github.com/ipfs/go-ipld-format/pull/75)) + - sync: update CI config files (#74) ([ipfs/go-ipld-format#74](https://github.com/ipfs/go-ipld-format/pull/74)) +- github.com/ipfs/go-ipld-legacy (v0.1.1 -> v0.2.1): + - v0.2.1 ([ipfs/go-ipld-legacy#15](https://github.com/ipfs/go-ipld-legacy/pull/15)) + - Expose a constructor for making a decoder with an existing link system ([ipfs/go-ipld-legacy#14](https://github.com/ipfs/go-ipld-legacy/pull/14)) + - Update to v0.2.0 ([ipfs/go-ipld-legacy#13](https://github.com/ipfs/go-ipld-legacy/pull/13)) + - Remove global variable ([ipfs/go-ipld-legacy#12](https://github.com/ipfs/go-ipld-legacy/pull/12)) + - sync: update CI config files (#8) ([ipfs/go-ipld-legacy#8](https://github.com/ipfs/go-ipld-legacy/pull/8)) +- github.com/ipfs/go-unixfsnode (v1.6.0 -> v1.7.1): + - chore: bump to v1.7.1 + - test: remove unnecessary t.Log + - test: check if reader reads only necessary blocks + - fix: do not read extra block if offset = at+childSize + - doc: added simple doc for testutil package + - bump v1.7.0 + - feat(testutil): add test data generation utils (extracted from Lassie) +- github.com/libp2p/go-libp2p (v0.27.3 -> v0.27.7): + - Release v0.27.7 (#2374) ([libp2p/go-libp2p#2374](https://github.com/libp2p/go-libp2p/pull/2374)) + - Release v0.27.6 (#2359) ([libp2p/go-libp2p#2359](https://github.com/libp2p/go-libp2p/pull/2359)) + - Release v0.27.5 (#2324) ([libp2p/go-libp2p#2324](https://github.com/libp2p/go-libp2p/pull/2324)) + - Bump version to v0.27.4 + - identify: reject signed peer records on peer ID mismatch + - swarm: change maps with multiaddress keys to use strings (#2284) ([libp2p/go-libp2p#2284](https://github.com/libp2p/go-libp2p/pull/2284)) + - identify: avoid spuriously triggering pushes (#2299) ([libp2p/go-libp2p#2299](https://github.com/libp2p/go-libp2p/pull/2299)) +- github.com/libp2p/go-libp2p-kad-dht (v0.23.0 -> v0.24.2): + - chore: release v0.24.2 + - chore: release v0.24.1 + - fix: decrease tests noise, update kbucket and fix fixRTIUfNeeded + - refactor: remove goprocess + - fix: leaking go routines + - chore: release v0.24.0 + - fix: don't add unresponsive DHT servers to the Routing Table (#820) ([libp2p/go-libp2p-kad-dht#820](https://github.com/libp2p/go-libp2p-kad-dht/pull/820)) +- github.com/libp2p/go-libp2p-kbucket (v0.5.0 -> v0.6.3): + - fix: fix abba bug in UsefullNewPeer ([libp2p/go-libp2p-kbucket#122](https://github.com/libp2p/go-libp2p-kbucket/pull/122)) + - chore: release v0.6.2 ([libp2p/go-libp2p-kbucket#121](https://github.com/libp2p/go-libp2p-kbucket/pull/121)) + - Replacing UsefulPeer() with UsefulNewPeer() ([libp2p/go-libp2p-kbucket#120](https://github.com/libp2p/go-libp2p-kbucket/pull/120)) + - chore: release 0.6.1 ([libp2p/go-libp2p-kbucket#119](https://github.com/libp2p/go-libp2p-kbucket/pull/119)) + - UsefulPeer function ([libp2p/go-libp2p-kbucket#113](https://github.com/libp2p/go-libp2p-kbucket/pull/113)) + - Fixed peer replacement with bucket size of 1. ([libp2p/go-libp2p-kbucket#117](https://github.com/libp2p/go-libp2p-kbucket/pull/117)) + - GenRandomKey function ([libp2p/go-libp2p-kbucket#116](https://github.com/libp2p/go-libp2p-kbucket/pull/116)) + - Removed maintainers from readme ([libp2p/go-libp2p-kbucket#115](https://github.com/libp2p/go-libp2p-kbucket/pull/115)) + - Add maintainers ([libp2p/go-libp2p-kbucket#114](https://github.com/libp2p/go-libp2p-kbucket/pull/114)) + - sync: update CI config files (#112) ([libp2p/go-libp2p-kbucket#112](https://github.com/libp2p/go-libp2p-kbucket/pull/112)) +- github.com/libp2p/go-libp2p-routing-helpers (v0.6.2 -> v0.7.0): + - chore: release v0.7.0 + - fix: iterate over keys manually in ProvideMany +- github.com/libp2p/go-reuseport (v0.2.0 -> v0.3.0): + - release v0.3.0 (#103) ([libp2p/go-reuseport#103](https://github.com/libp2p/go-reuseport/pull/103)) + - fix error handling when setting socket options (#102) ([libp2p/go-reuseport#102](https://github.com/libp2p/go-reuseport/pull/102)) + - minor README updates (#96) ([libp2p/go-reuseport#96](https://github.com/libp2p/go-reuseport/pull/96)) + - sync: update CI config files (#94) ([libp2p/go-reuseport#94](https://github.com/libp2p/go-reuseport/pull/94)) + - feat: add a DialTimeout function ([libp2p/go-reuseport#92](https://github.com/libp2p/go-reuseport/pull/92)) +- github.com/multiformats/go-multicodec (v0.8.1 -> v0.9.0): + - Bump v0.9.0 + - Bump v0.8.2 + - chore: update submodules and go generate + - chore: update submodules and go generate + - chore: update submodules and go generate + - chore: update submodules and go generate + - chore: update submodules and go generate + - chore: update submodules and go generate +- github.com/multiformats/go-multihash (v0.2.1 -> v0.2.3): + - chore: release v0.2.3 + - perf: outline logic in Decode to allow for stack allocations + - chore: release v0.2.2 + - sha256: drop minio in favor of crypto/sha256 for go1.21 and above + - sync: update CI config files (#169) ([multiformats/go-multihash#169](https://github.com/multiformats/go-multihash/pull/169)) + - add handler for hasher.Write returned error ([multiformats/go-multihash#167](https://github.com/multiformats/go-multihash/pull/167)) + - sync: update CI config files (#165) ([multiformats/go-multihash#165](https://github.com/multiformats/go-multihash/pull/165)) + - test: add benchmark for all hash functions Sum + +
+ ### 👨‍👩‍👧‍👦 Contributors + +| Contributor | Commits | Lines ± | Files Changed | +|-------------|---------|---------|---------------| +| Jorropo | 47 | +4394/-4458 | 202 | +| Henrique Dias | 48 | +4344/-3962 | 205 | +| Łukasz Magiera | 68 | +3604/-886 | 172 | +| Adin Schmahmann | 8 | +1754/-1057 | 37 | +| galargh | 7 | +1355/-1302 | 15 | +| Gus Eggert | 7 | +1566/-655 | 33 | +| rvagg | 1 | +396/-389 | 3 | +| Michael Muré | 3 | +547/-202 | 14 | +| Guillaume Michel - guissou | 5 | +153/-494 | 17 | +| guillaumemichel | 15 | +446/-189 | 28 | +| Laurent Senta | 4 | +472/-152 | 29 | +| Rod Vagg | 6 | +554/-37 | 23 | +| Marcin Rataj | 11 | +330/-82 | 21 | +| Arthur Gavazza | 1 | +296/-87 | 7 | +| Lucas Molas | 1 | +323/-56 | 6 | +| Marco Munizaga | 5 | +227/-97 | 17 | +| Alex | 8 | +163/-116 | 10 | +| Steven Allen | 11 | +154/-114 | 14 | +| Marten Seemann | 6 | +214/-41 | 12 | +| web3-bot | 9 | +76/-75 | 28 | +| Hector Sanjuan | 2 | +5/-96 | 4 | +| Sukun | 1 | +83/-17 | 3 | +| Steve Loeppky | 2 | +100/-0 | 2 | +| Edgar Lee | 1 | +46/-46 | 12 | +| Ivan Schasny | 1 | +67/-5 | 4 | +| imthe1 | 1 | +65/-3 | 5 | +| godcong | 2 | +30/-31 | 5 | +| Will Scott | 4 | +36/-23 | 6 | +| Petar Maymounkov | 1 | +45/-9 | 1 | +| Ross Jones | 1 | +43/-1 | 2 | +| William Entriken | 1 | +38/-0 | 1 | +| João Pedro | 1 | +35/-0 | 1 | +| jhertz | 1 | +21/-0 | 2 | +| Nikhilesh Susarla | 1 | +21/-0 | 3 | +| Matt Joiner | 1 | +11/-9 | 2 | +| Vlad | 2 | +4/-2 | 2 | +| Russell Dempsey | 2 | +4/-2 | 2 | +| Will | 2 | +2/-2 | 2 | +| Piotr Galar | 1 | +1/-1 | 1 | +| Joel Gustafson | 1 | +1/-1 | 1 | +| Dennis Trautwein | 1 | +1/-1 | 1 | +| Bryan Stenson | 1 | +1/-1 | 1 | From da44c9f7a1edcbce1308fc0b7ee9ee5e47a40d9d Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Fri, 30 Jun 2023 03:49:47 +0200 Subject: [PATCH 0771/1212] docs: Gateway.HTTPHeaders --- docs/config.md | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/docs/config.md b/docs/config.md index 7b304476e..b7e21e12a 100644 --- a/docs/config.md +++ b/docs/config.md @@ -663,20 +663,7 @@ Type: `flag` Headers to set on gateway responses. -Default: -```json -{ - "Access-Control-Allow-Headers": [ - "X-Requested-With" - ], - "Access-Control-Allow-Methods": [ - "GET" - ], - "Access-Control-Allow-Origin": [ - "*" - ] -} -``` +Default: `{}` + implicit CORS headers from `boxo/gateway#AddAccessControlHeaders` and [ipfs/specs#423](https://github.com/ipfs/specs/issues/423) Type: `object[string -> array[string]]` From 0d5a9337624d1fda213b8410f75ead4f5eaea5a3 Mon Sep 17 00:00:00 2001 From: Piotr Galar Date: Fri, 30 Jun 2023 15:35:00 +0200 Subject: [PATCH 0772/1212] docs: update refs to kuboreleaser in RELEASE_ISSUE_TEMPLATE.md --- docs/RELEASE_ISSUE_TEMPLATE.md | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/docs/RELEASE_ISSUE_TEMPLATE.md b/docs/RELEASE_ISSUE_TEMPLATE.md index ed181126e..df17d645e 100644 --- a/docs/RELEASE_ISSUE_TEMPLATE.md +++ b/docs/RELEASE_ISSUE_TEMPLATE.md @@ -84,7 +84,7 @@ This section covers tasks to be done ahead of the release. This section covers tasks to be done during each release. -- [ ] Prepare the release branch and update version numbers accordingly
using `kuboreleaser release --version vX.Y.Z(-rcN) prepare-branch` or ... +- [ ] Prepare the release branch and update version numbers accordingly
using `./kuboreleaser release --version vX.Y.Z(-rcN) prepare-branch` or ... - [ ] create a new branch `release-vX.Y.Z` - use `master` as base if `Z == 0` - use `release` as base if `Z > 0` @@ -105,7 +105,7 @@ This section covers tasks to be done during each release.
- [ ] Run Thunderdome testing, see the [Thunderdome release docs](./releases_thunderdome.md) for details - [ ] create a PR and merge the experiment config into Thunderdome -- [ ] Create the release tag
using `kuboreleaser release --version vX.Y.Z(-rcN) tag` or ... +- [ ] Create the release tag
using `./kuboreleaser release --version vX.Y.Z(-rcN) tag` or ... - This is a dangerous operation! Go and Docker publishing are difficult to reverse! Have the release reviewer verify all the commands marked with ⚠️! - [ ] ⚠️ ![](https://img.shields.io/badge/only-RC-blue?style=flat-square) tag the HEAD commit using `git tag -s vX.Y.Z(-RCN) -m 'Prerelease X.Y.Z(-RCN)'` - [ ] ⚠️ ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) tag the HEAD commit of the `release` branch using `git tag -s vX.Y.Z(-RCN) -m 'Release X.Y.Z(-RCN)'` @@ -113,10 +113,10 @@ This section covers tasks to be done during each release. - [ ] ⚠️ push the tag to GitHub using `git push origin vX.Y.Z(-RCN)` - do **NOT** use `git push --tags` because it pushes all your local tags
-- [ ] Publish the release to [DockerHub](https://hub.docker.com/r/ipfs/kubo/)
using `kuboreleaser --skip-check-before --skip-run release --version vX.Y.Z(-rcN) publish-to-dockerhub` or ... +- [ ] Publish the release to [DockerHub](https://hub.docker.com/r/ipfs/kubo/)
using `./kuboreleaser --skip-check-before --skip-run release --version vX.Y.Z(-rcN) publish-to-dockerhub` or ... - [ ] Wait for [Publish docker image](https://github.com/ipfs/kubo/actions/workflows/docker-image.yml) workflow run initiated by the tag push to finish - [ ] verify the image is available on [Docker Hub](https://hub.docker.com/r/ipfs/kubo/tags) -- [ ] Publish the release to [ipfs.tech](https://dist.ipfs.tech)
using `kuboreleaser release --version vX.Y.Z(-rcN) publish-to-distributions` or ... +- [ ] Publish the release to [ipfs.tech](https://dist.ipfs.tech)
using `./kuboreleaser release --version vX.Y.Z(-rcN) publish-to-distributions` or ... - [ ] check out [ipfs/distributions](https://github.com/ipfs/distributions) - [ ] run `./dist.sh add-version kubo vX.Y.Z(-RCN)` to add the new version to the `versions` file - [usage](https://github.com/ipfs/distributions#usage) @@ -125,12 +125,12 @@ This section covers tasks to be done during each release. - [ ] wait for the [CI](https://github.com/ipfs/distributions/actions/workflows/main.yml) workflow run initiated by the merge to master to finish - [ ] verify the release is available on [dist.ipfs.io](https://dist.ipfs.io/#kubo)
-- [ ] Publish the release to [NPM](https://www.npmjs.com/package/go-ipfs?activeTab=versions)
using `kuboreleaser release --version vX.Y.Z(-rcN) publish-to-npm` or ... +- [ ] Publish the release to [NPM](https://www.npmjs.com/package/go-ipfs?activeTab=versions)
using `./kuboreleaser release --version vX.Y.Z(-rcN) publish-to-npm` or ... - [ ] run the [Release to npm](https://github.com/ipfs/npm-go-ipfs/actions/workflows/main.yml) workflow - [ ] check [Release to npm](https://github.com/ipfs/npm-go-ipfs/actions/workflows/main.yml) workflow run logs to verify it discovered the new release - [ ] verify the release is available on [NPM](https://www.npmjs.com/package/go-ipfs?activeTab=versions)
-- [ ] Publish the release to [GitHub](https://github.com/ipfs/kubo/releases)
using `kuboreleaser release --version vX.Y.Z(-rcN) publish-to-github` or ... +- [ ] Publish the release to [GitHub](https://github.com/ipfs/kubo/releases)
using `./kuboreleaser release --version vX.Y.Z(-rcN) publish-to-github` or ... - [ ] create a new release on [GitHub](https://docs.github.com/en/repositories/releasing-projects-on-github/managing-releases-in-a-repository#creating-a-release) - [RC example](https://github.com/ipfs/kubo/releases/tag/v0.17.0-rc1) - [FINAL example](https://github.com/ipfs/kubo/releases/tag/v0.17.0) @@ -144,7 +144,7 @@ This section covers tasks to be done during each release. - [ ] wait for the [sync-release-assets](https://github.com/ipfs/kubo/actions/workflows/sync-release-assets.yml) workflow run to finish - [ ] verify the release assets are present in the [GitHub release](https://github.com/ipfs/kubo/releases/tag/vX.Y.Z(-RCN))
-- [ ] Promote the release
using `kuboreleaser release --version vX.Y.Z(-rcN) promote` or ... +- [ ] Promote the release
using `./kuboreleaser release --version vX.Y.Z(-rcN) promote` or ... - [ ] create an [IPFS Discourse](https://discuss.ipfs.tech) topic - [prerelease example](https://discuss.ipfs.tech/t/kubo-v0-16-0-rc1-release-candidate-is-out/15248) - [release example](https://discuss.ipfs.tech/t/kubo-v0-16-0-release-is-out/15249) @@ -169,38 +169,38 @@ This section covers tasks to be done during each release. - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) post the link to the [GitHub Release](https://github.com/ipfs/kubo/releases/tag/vX.Y.Z(-RCN)) to [Reddit](https://reddit.com/r/ipfs) - [example](https://www.reddit.com/r/ipfs/comments/9x0q0k/kubo_v0160_release_is_out/)
-- [ ] Test the new version with `ipfs-companion`
using `kuboreleaser release --version vX.Y.Z(-rcN) test-ipfs-companion` or ... +- [ ] Test the new version with `ipfs-companion`
using `./kuboreleaser release --version vX.Y.Z(-rcN) test-ipfs-companion` or ... - [ ] run the [e2e](https://github.com/ipfs/ipfs-companion/actions/workflows/e2e.yml) - use `vX.Y.Z(-RCN)` as the Kubo image version - [ ] wait for the [e2e](https://github.com/ipfs/ipfs-companion/actions/workflows/e2e.yml) workflow run to finish
-- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Update Kubo in [interop](https://github.com/ipfs/interop)
using `kuboreleaser release --version vX.Y.Z(-rcN) update-interop` or ... +- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Update Kubo in [interop](https://github.com/ipfs/interop)
using `./kuboreleaser release --version vX.Y.Z(-rcN) update-interop` or ... - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) check out [ipfs/interop](https://github.com/ipfs/interop) - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) run `npm install` - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) create a PR which updates `package.json` and `package-lock.json` - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) merge the PR
-- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Update Kubo in [ipfs-desktop](https://github.com/ipfs/ipfs-desktop)
using `kuboreleaser release --version vX.Y.Z(-rcN) update-ipfs-desktop` or ... +- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Update Kubo in [ipfs-desktop](https://github.com/ipfs/ipfs-desktop)
using `./kuboreleaser release --version vX.Y.Z(-rcN) update-ipfs-desktop` or ... - [ ] check out [ipfs/ipfs-desktop](https://github.com/ipfs/ipfs-desktop) - [ ] run `npm install` - [ ] create a PR which updates `package.json` and `package-lock.json` - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) add @SgtPooki and @whizzzkid as reviewers
-- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Update Kubo docs
using `kuboreleaser release --version vX.Y.Z(-rcN) update-ipfs-docs` or ... +- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Update Kubo docs
using `./kuboreleaser release --version vX.Y.Z(-rcN) update-ipfs-docs` or ... - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) run the [update-on-new-ipfs-tag.yml](https://github.com/ipfs/ipfs-docs/actions/workflows/update-on-new-ipfs-tag.yml) workflow - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) merge the PR created by the [update-on-new-ipfs-tag.yml](https://github.com/ipfs/ipfs-docs/actions/workflows/update-on-new-ipfs-tag.yml) workflow run
-- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Create a blog entry on [ipfs.tech](https://blog.ipfs.tech)
using `kuboreleaser release --version vX.Y.Z(-rcN) update-ipfs-blog --date YYYY-MM-DD` or ... +- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Create a blog entry on [ipfs.tech](https://blog.ipfs.tech)
using `./kuboreleaser release --version vX.Y.Z(-rcN) update-ipfs-blog --date YYYY-MM-DD` or ... - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) create a PR which adds a release note for the new Kubo version - [example](https://github.com/ipfs/ipfs-blog/pull/529) - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) merge the PR - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) verify the blog entry was published
-- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Merge the [release](https://github.com/ipfs/kubo/tree/release) branch back into [master](https://github.com/ipfs/kubo/tree/master), ignoring the changes to [version.go](version.go) (keep the `-dev`) version,
using `kuboreleaser release --version vX.Y.Z(-rcN) merge-branch` or ... +- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Merge the [release](https://github.com/ipfs/kubo/tree/release) branch back into [master](https://github.com/ipfs/kubo/tree/master), ignoring the changes to [version.go](version.go) (keep the `-dev`) version,
using `./kuboreleaser release --version vX.Y.Z(-rcN) merge-branch` or ... - [ ] create a new branch `merge-release-vX.Y.Z` from `release` - [ ] create and merge a PR from `merge-release-vX.Y.Z` to `master`
-- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) Prepare for the next release
using `kuboreleaser release --version vX.Y.Z(-rcN) prepare-next` or ... +- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) Prepare for the next release
using `./kuboreleaser release --version vX.Y.Z(-rcN) prepare-next` or ... - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) Create the next [changelog](https://github.com/ipfs/kubo/blob/master/docs/changelogs/vX.(Y+1).md) - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) Link to the new changelog in the [CHANGELOG.md](CHANGELOG.md) file - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) Create the next release issue From c00cee50b189874e6fa7028489a1e85a10668990 Mon Sep 17 00:00:00 2001 From: Piotr Galar Date: Fri, 30 Jun 2023 15:40:17 +0200 Subject: [PATCH 0773/1212] docs: update RELEASE_ISSUE_TEMPLATE.md with a warning about npm publish --- docs/RELEASE_ISSUE_TEMPLATE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/RELEASE_ISSUE_TEMPLATE.md b/docs/RELEASE_ISSUE_TEMPLATE.md index df17d645e..a24aff4da 100644 --- a/docs/RELEASE_ISSUE_TEMPLATE.md +++ b/docs/RELEASE_ISSUE_TEMPLATE.md @@ -125,7 +125,7 @@ This section covers tasks to be done during each release. - [ ] wait for the [CI](https://github.com/ipfs/distributions/actions/workflows/main.yml) workflow run initiated by the merge to master to finish - [ ] verify the release is available on [dist.ipfs.io](https://dist.ipfs.io/#kubo)
-- [ ] Publish the release to [NPM](https://www.npmjs.com/package/go-ipfs?activeTab=versions)
using `./kuboreleaser release --version vX.Y.Z(-rcN) publish-to-npm` or ... +- [ ] Publish the release to [NPM](https://www.npmjs.com/package/go-ipfs?activeTab=versions)
using `./kuboreleaser release --version vX.Y.Z(-rcN) publish-to-npm` (⚠️ you might need to run the command a couple of times because GHA might not be able to see the new distribution straight away due to caching) or ... - [ ] run the [Release to npm](https://github.com/ipfs/npm-go-ipfs/actions/workflows/main.yml) workflow - [ ] check [Release to npm](https://github.com/ipfs/npm-go-ipfs/actions/workflows/main.yml) workflow run logs to verify it discovered the new release - [ ] verify the release is available on [NPM](https://www.npmjs.com/package/go-ipfs?activeTab=versions) From f797e9e6d388a51c3f8473c614d4276da9683e28 Mon Sep 17 00:00:00 2001 From: Piotr Galar Date: Fri, 30 Jun 2023 16:11:51 +0200 Subject: [PATCH 0774/1212] docs: skip check before prepare branch in RELEASE_ISSUE_TEMPLATE.md --- docs/RELEASE_ISSUE_TEMPLATE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/RELEASE_ISSUE_TEMPLATE.md b/docs/RELEASE_ISSUE_TEMPLATE.md index a24aff4da..aa674b49b 100644 --- a/docs/RELEASE_ISSUE_TEMPLATE.md +++ b/docs/RELEASE_ISSUE_TEMPLATE.md @@ -84,7 +84,7 @@ This section covers tasks to be done ahead of the release. This section covers tasks to be done during each release. -- [ ] Prepare the release branch and update version numbers accordingly
using `./kuboreleaser release --version vX.Y.Z(-rcN) prepare-branch` or ... +- [ ] Prepare the release branch and update version numbers accordingly
using `./kuboreleaser --skip-check-before release --version vX.Y.Z(-rcN) prepare-branch` or ... - [ ] create a new branch `release-vX.Y.Z` - use `master` as base if `Z == 0` - use `release` as base if `Z > 0` From 82e0a44587f85ad1833a50a89d4c132c0f1d5ec3 Mon Sep 17 00:00:00 2001 From: Russell Dempsey <1173416+SgtPooki@users.noreply.github.com> Date: Mon, 3 Jul 2023 17:03:51 -0700 Subject: [PATCH 0775/1212] feat: webui@4.0.2 see https://github.com/ipfs/ipfs-webui/releases/tag/v4.0.2 --- core/corehttp/webui.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/corehttp/webui.go b/core/corehttp/webui.go index e5abd3922..4030a0053 100644 --- a/core/corehttp/webui.go +++ b/core/corehttp/webui.go @@ -1,11 +1,12 @@ package corehttp // TODO: move to IPNS -const WebUIPath = "/ipfs/bafybeigs6d53gpgu34553mbi5bbkb26e4ikruoaaar75jpfdywpup2r3my" // v4.0.1 +const WebUIPath = "/ipfs/bafybeicyp7ssbnj3hdzehcibmapmpuc3atrsc4ch3q6acldfh4ojjdbcxe" // v4.0.2 // WebUIPaths is a list of all past webUI paths. var WebUIPaths = []string{ WebUIPath, + "/ipfs/bafybeigs6d53gpgu34553mbi5bbkb26e4ikruoaaar75jpfdywpup2r3my", "/ipfs/bafybeic4gops3d3lyrisqku37uio33nvt6fqxvkxihrwlqsuvf76yln4fm", "/ipfs/bafybeifeqt7mvxaniphyu2i3qhovjaf3sayooxbh5enfdqtiehxjv2ldte", "/ipfs/bafybeiequgo72mrvuml56j4gk7crewig5bavumrrzhkqbim6b3s2yqi7ty", From c293d6269861614e0efd4c4e9d996d193150fbf5 Mon Sep 17 00:00:00 2001 From: Piotr Galar Date: Thu, 6 Jul 2023 08:13:27 +0200 Subject: [PATCH 0776/1212] ci: add changelog update checker workflow [skip changelog] (#10002) * ci: add changelog update checker workflow * ci: trigger changelog workflow when modifying Go files only * ci: disable js-rv-js tests in interop (#10007) --- .github/pull_request_template.md | 5 ++-- .github/workflows/build.yml | 2 +- .github/workflows/changelog.yml | 39 ++++++++++++++++++++++++++++++++ 3 files changed, 43 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/changelog.yml diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 6d06659db..4224fd04c 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,4 +1,5 @@ diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f6a2ced2b..33d9f828a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -81,7 +81,7 @@ jobs: npm install ipfs-interop@^10.0.1 working-directory: interop # Run the interop tests while ignoring the js-js interop test cases - - run: npx ipfs-interop -- -t node --grep '^(?!.*(js\d? -> js\d?|js-js-js))' --parallel + - run: npx ipfs-interop -- -t node --grep '^(?!.*(js\d? -> js\d?|js-js-js|js-rv\d?-js))' --parallel env: LIBP2P_TCP_REUSEPORT: false LIBP2P_ALLOW_WEAK_RSA_KEYS: 1 diff --git a/.github/workflows/changelog.yml b/.github/workflows/changelog.yml new file mode 100644 index 000000000..85f2dbf2b --- /dev/null +++ b/.github/workflows/changelog.yml @@ -0,0 +1,39 @@ +name: Changelog + +on: + pull_request: + types: + - opened + - edited + - synchronize + - reopened + - labeled + - unlabeled + paths: + - '**.go' + - '**/go.mod' + - '**/go.sum' + +jobs: + changelog: + if: contains(github.event.pull_request.title, '[skip changelog]') == false && + contains(github.event.pull_request.labels.*.name, 'skip/changelog') == false + runs-on: ubuntu-latest + name: Changelog + steps: + - id: changelog + env: + GITHUB_TOKEN: ${{ github.token }} + ENDPOINT: repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/files + SELECTOR: 'map(select(.filename | startswith("docs/changelogs/"))) | length' + run: gh api "$ENDPOINT" --jq "$SELECTOR" | xargs -I{} echo "modified={}" | tee -a $GITHUB_OUTPUT + - if: steps.changelog.outputs.modified == '0' + env: + MESSAGE: | + docs/changelogs/ was not modified in this PR. Please do one of the following: + - add a changelog entry + - add `[skip changelog]` to the PR title + - label the PR with `skip/changelog` + run: | + echo "::error::${MESSAGE//$'\n'/%0A}" + exit 1 From 4a5e99d7eaeada5596a0686fe93d4fa2da212452 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Thu, 6 Jul 2023 11:21:48 +0200 Subject: [PATCH 0777/1212] docs: add Brave to RELEASE_ISSUE_TEMPLATE.md (#10012) * docs: add Brave to RELEASE_ISSUE_TEMPLATE.md * docs: update docs/RELEASE_ISSUE_TEMPLATE.md --------- Co-authored-by: Piotr Galar --- docs/RELEASE_ISSUE_TEMPLATE.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/RELEASE_ISSUE_TEMPLATE.md b/docs/RELEASE_ISSUE_TEMPLATE.md index aa674b49b..d3f8e1d7f 100644 --- a/docs/RELEASE_ISSUE_TEMPLATE.md +++ b/docs/RELEASE_ISSUE_TEMPLATE.md @@ -116,7 +116,7 @@ This section covers tasks to be done during each release. - [ ] Publish the release to [DockerHub](https://hub.docker.com/r/ipfs/kubo/)
using `./kuboreleaser --skip-check-before --skip-run release --version vX.Y.Z(-rcN) publish-to-dockerhub` or ... - [ ] Wait for [Publish docker image](https://github.com/ipfs/kubo/actions/workflows/docker-image.yml) workflow run initiated by the tag push to finish - [ ] verify the image is available on [Docker Hub](https://hub.docker.com/r/ipfs/kubo/tags) -- [ ] Publish the release to [ipfs.tech](https://dist.ipfs.tech)
using `./kuboreleaser release --version vX.Y.Z(-rcN) publish-to-distributions` or ... +- [ ] Publish the release to [dist.ipfs.tech](https://dist.ipfs.tech)
using `./kuboreleaser release --version vX.Y.Z(-rcN) publish-to-distributions` or ... - [ ] check out [ipfs/distributions](https://github.com/ipfs/distributions) - [ ] run `./dist.sh add-version kubo vX.Y.Z(-RCN)` to add the new version to the `versions` file - [usage](https://github.com/ipfs/distributions#usage) @@ -190,7 +190,11 @@ This section covers tasks to be done during each release. - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) run the [update-on-new-ipfs-tag.yml](https://github.com/ipfs/ipfs-docs/actions/workflows/update-on-new-ipfs-tag.yml) workflow - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) merge the PR created by the [update-on-new-ipfs-tag.yml](https://github.com/ipfs/ipfs-docs/actions/workflows/update-on-new-ipfs-tag.yml) workflow run
-- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Create a blog entry on [ipfs.tech](https://blog.ipfs.tech)
using `./kuboreleaser release --version vX.Y.Z(-rcN) update-ipfs-blog --date YYYY-MM-DD` or ... +- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Ask Brave to update Kubo in Brave Desktop + - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) use [this link](https://github.com/brave/brave-browser/issues/new?assignees=&labels=OS%2FDesktop&projects=&template=desktop.md&title=) to create an issue for the new Kubo version + - [basic example](https://github.com/brave/brave-browser/issues/31453), [example with additional notes](https://github.com/brave/brave-browser/issues/27965) + - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) post link to the issue in `#shared-pl-brave` for visibility +- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Create a blog entry on [blog.ipfs.tech](https://blog.ipfs.tech)
using `./kuboreleaser release --version vX.Y.Z(-rcN) update-ipfs-blog --date YYYY-MM-DD` or ... - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) create a PR which adds a release note for the new Kubo version - [example](https://github.com/ipfs/ipfs-blog/pull/529) - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) merge the PR From 1fe17a4165da1ea1213b618ff4f47b9588a00f86 Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Thu, 20 Jul 2023 11:25:56 -0400 Subject: [PATCH 0778/1212] docs(commands): explain that swarm connect can reuse existing connections or known addresses (#10015) --- core/commands/swarm.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/core/commands/swarm.go b/core/commands/swarm.go index c9259bef0..3d2adb757 100644 --- a/core/commands/swarm.go +++ b/core/commands/swarm.go @@ -650,11 +650,13 @@ var swarmAddrsListenCmd = &cmds.Command{ var swarmConnectCmd = &cmds.Command{ Helptext: cmds.HelpText{ - Tagline: "Open connection to a given address.", + Tagline: "Open connection to a given peer.", ShortDescription: ` -'ipfs swarm connect' opens a new direct connection to a peer address. +'ipfs swarm connect' attempts to ensure a connection to a given peer. -The address format is an IPFS multiaddr: +Multiaddresses given are advisory, for example the node may already be aware of other addresses for a given peer or may already have an established connection to the peer. + +The address format is a libp2p multiaddr: ipfs swarm connect /ip4/104.131.131.82/tcp/4001/p2p/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ `, From a8c63537f22ca61769f3f7eba56324b6e76cbdfd Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Mon, 24 Jul 2023 11:09:09 +0200 Subject: [PATCH 0779/1212] feat(gateway): support for ipip-412 parameters --- docs/changelogs/v0.22.md | 23 +++++++++++++++++++++++ docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- test/dependencies/go.mod | 2 +- test/dependencies/go.sum | 4 ++-- 7 files changed, 32 insertions(+), 9 deletions(-) diff --git a/docs/changelogs/v0.22.md b/docs/changelogs/v0.22.md index 633741c88..d34e42bad 100644 --- a/docs/changelogs/v0.22.md +++ b/docs/changelogs/v0.22.md @@ -6,6 +6,7 @@ - [Overview](#overview) - [🔦 Highlights](#-highlights) + - [Gateway: support for `order=` and `dups=` parameters (IPIP-412)](#gateway-support-for-order-and-dups-parameters-ipip-412) - [`ipfs name publish` now supports V2 only IPNS records](#ipfs-name-publish-now-supports-v2-only-ipns-records) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -14,6 +15,28 @@ ### 🔦 Highlights +#### Gateway: support for `order=` and `dups=` parameters (IPIP-412) + +The updated [`boxo/gateway` library](https://github.com/ipfs/boxo/tree/main/gateway) +introduces support for ordered CAR responses through the inclusion of optional +CAR content type parameters: `order=dfs` and `dups=y|n` from +[IPIP-412](https://github.com/ipfs/specs/pull/412). + +Previously, Kubo already provided CARs in DFS order without duplicate blocks. +With the implementation of IPIP-412, this behavior is now explicitly defined +rather than implied. + +In the absence of `dups` or `order` in `Accept` request reader, the default CAR +response will have the `Content-Type: application/vnd.ipld.car; version=1; order=dfs; dups=n` +and the same blocks as Kubo 0.21. + +Kubo 0.22 still only supports DFS block ordering (`order=dfs`). However, it is +now possible to request a DFS CAR stream with duplicate blocks by opting in via +`Accept: application/vnd.ipld.car; order=dfs; dups=y`. This opt-in feature can be +beneficial for memory-constrained clients and IoT devices, as it allows for +streaming large DAGs without the need to store all previously encountered +blocks in memory. + #### `ipfs name publish` now supports V2 only IPNS records When publishing an IPNS record, you are now able to create v2 only records diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 4cf0ab9dc..d1ca4f5be 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.18 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.10.2-0.20230629140307-fdad9f921191 + github.com/ipfs/boxo v0.10.3-0.20230724084731-f6b448b4263a github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.27.7 github.com/multiformats/go-multiaddr v0.9.0 diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 103339ffb..37ed3ee5c 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -320,8 +320,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.10.2-0.20230629140307-fdad9f921191 h1:oNiEZXJYb4B6zmvUc3F5vvS4xtll8naN8rz1hKftgd4= -github.com/ipfs/boxo v0.10.2-0.20230629140307-fdad9f921191/go.mod h1:8IfDmp+FzFGcF4zjAgHMVPpwYw4AjN9ePEzDfkaYJ1w= +github.com/ipfs/boxo v0.10.3-0.20230724084731-f6b448b4263a h1:eDO++KVTMF7wNqHHhNCZnW/Ocf2K6zCSizAbWoIMREo= +github.com/ipfs/boxo v0.10.3-0.20230724084731-f6b448b4263a/go.mod h1:8IfDmp+FzFGcF4zjAgHMVPpwYw4AjN9ePEzDfkaYJ1w= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= diff --git a/go.mod b/go.mod index 2b66a8a35..73b5a3310 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( github.com/fsnotify/fsnotify v1.6.0 github.com/google/uuid v1.3.0 github.com/hashicorp/go-multierror v1.1.1 - github.com/ipfs/boxo v0.10.2-0.20230629140307-fdad9f921191 + github.com/ipfs/boxo v0.10.3-0.20230724084731-f6b448b4263a github.com/ipfs/go-block-format v0.1.2 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 diff --git a/go.sum b/go.sum index 7b07ea02b..08585f448 100644 --- a/go.sum +++ b/go.sum @@ -355,8 +355,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.10.2-0.20230629140307-fdad9f921191 h1:oNiEZXJYb4B6zmvUc3F5vvS4xtll8naN8rz1hKftgd4= -github.com/ipfs/boxo v0.10.2-0.20230629140307-fdad9f921191/go.mod h1:8IfDmp+FzFGcF4zjAgHMVPpwYw4AjN9ePEzDfkaYJ1w= +github.com/ipfs/boxo v0.10.3-0.20230724084731-f6b448b4263a h1:eDO++KVTMF7wNqHHhNCZnW/Ocf2K6zCSizAbWoIMREo= +github.com/ipfs/boxo v0.10.3-0.20230724084731-f6b448b4263a/go.mod h1:8IfDmp+FzFGcF4zjAgHMVPpwYw4AjN9ePEzDfkaYJ1w= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 302f7b803..e7b10c191 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -7,7 +7,7 @@ replace github.com/ipfs/kubo => ../../ require ( github.com/Kubuxu/gocovmerge v0.0.0-20161216165753-7ecaa51963cd github.com/golangci/golangci-lint v1.49.0 - github.com/ipfs/boxo v0.10.2-0.20230629140307-fdad9f921191 + github.com/ipfs/boxo v0.10.3-0.20230724084731-f6b448b4263a github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 github.com/ipfs/go-datastore v0.6.0 diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index bcf7966a5..c8a237e6b 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -415,8 +415,8 @@ github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NH github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.10.2-0.20230629140307-fdad9f921191 h1:oNiEZXJYb4B6zmvUc3F5vvS4xtll8naN8rz1hKftgd4= -github.com/ipfs/boxo v0.10.2-0.20230629140307-fdad9f921191/go.mod h1:8IfDmp+FzFGcF4zjAgHMVPpwYw4AjN9ePEzDfkaYJ1w= +github.com/ipfs/boxo v0.10.3-0.20230724084731-f6b448b4263a h1:eDO++KVTMF7wNqHHhNCZnW/Ocf2K6zCSizAbWoIMREo= +github.com/ipfs/boxo v0.10.3-0.20230724084731-f6b448b4263a/go.mod h1:8IfDmp+FzFGcF4zjAgHMVPpwYw4AjN9ePEzDfkaYJ1w= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.1.2 h1:GAjkfhVx1f4YTODS6Esrj1wt2HhrtwTnhEr+DyPUaJo= From 9c02eecad7859d9b4424d0ee36c9e4658d090cf5 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Tue, 25 Jul 2023 19:39:21 +0200 Subject: [PATCH 0780/1212] fix: mark all routers DoNotWaitForSearchValue (#10020) * fix: mark ipns pubsub router DoNotWaitForSearchValue That means if the DHT has finished searching and no one responded over pubsub *yet*, we will not spend 1 minute searching for no reason. This also include other error handling bug fixes inside `go-libp2p-routing-helpers`. Fixes: #9927 * routing: bring back the old IPNS behaviour Stop making this configurable let everything race like it used to do. --- core/node/libp2p/routing.go | 7 ++++--- core/node/libp2p/routingopt.go | 16 +++++++++------- docs/changelogs/v0.22.md | 9 +++++++++ docs/examples/kubo-as-a-library/go.mod | 3 ++- docs/examples/kubo-as-a-library/go.sum | 6 ++++-- go.mod | 3 ++- go.sum | 6 ++++-- routing/delegated.go | 9 +++++---- 8 files changed, 39 insertions(+), 20 deletions(-) diff --git a/core/node/libp2p/routing.go b/core/node/libp2p/routing.go index 0b642ed8c..007ff3397 100644 --- a/core/node/libp2p/routing.go +++ b/core/node/libp2p/routing.go @@ -126,7 +126,7 @@ func BaseRouting(cfg *config.Config) interface{} { return out, err } routers := []*routinghelpers.ParallelRouter{ - {Router: fullRTClient}, + {Router: fullRTClient, DoNotWaitForSearchValue: true}, } routers = append(routers, httpRouters...) router := routinghelpers.NewComposableParallel(routers) @@ -197,8 +197,9 @@ func Routing(in p2pOnlineRoutingIn) irouting.ProvideManyRouter { var cRouters []*routinghelpers.ParallelRouter for _, v := range routers { cRouters = append(cRouters, &routinghelpers.ParallelRouter{ - IgnoreError: true, - Router: v.Routing, + IgnoreError: true, + DoNotWaitForSearchValue: true, + Router: v.Routing, }) } diff --git a/core/node/libp2p/routingopt.go b/core/node/libp2p/routingopt.go index da940837f..82b68361d 100644 --- a/core/node/libp2p/routingopt.go +++ b/core/node/libp2p/routingopt.go @@ -61,10 +61,11 @@ func constructDefaultHTTPRouters(cfg *config.Config) ([]*routinghelpers.Parallel } routers = append(routers, &routinghelpers.ParallelRouter{ - Router: r, - IgnoreError: true, // https://github.com/ipfs/kubo/pull/9475#discussion_r1042507387 - Timeout: 15 * time.Second, // 5x server value from https://github.com/ipfs/kubo/pull/9475#discussion_r1042428529 - ExecuteAfter: 0, + Router: r, + IgnoreError: true, // https://github.com/ipfs/kubo/pull/9475#discussion_r1042507387 + Timeout: 15 * time.Second, // 5x server value from https://github.com/ipfs/kubo/pull/9475#discussion_r1042428529 + DoNotWaitForSearchValue: true, + ExecuteAfter: 0, }) } return routers, nil @@ -82,9 +83,10 @@ func ConstructDefaultRouting(cfg *config.Config, routingOpt RoutingOption) Routi return nil, err } routers = append(routers, &routinghelpers.ParallelRouter{ - Router: dhtRouting, - IgnoreError: false, - ExecuteAfter: 0, + Router: dhtRouting, + IgnoreError: false, + DoNotWaitForSearchValue: true, + ExecuteAfter: 0, }) httpRouters, err := constructDefaultHTTPRouters(cfg) diff --git a/docs/changelogs/v0.22.md b/docs/changelogs/v0.22.md index d34e42bad..b1cac4532 100644 --- a/docs/changelogs/v0.22.md +++ b/docs/changelogs/v0.22.md @@ -8,6 +8,7 @@ - [🔦 Highlights](#-highlights) - [Gateway: support for `order=` and `dups=` parameters (IPIP-412)](#gateway-support-for-order-and-dups-parameters-ipip-412) - [`ipfs name publish` now supports V2 only IPNS records](#ipfs-name-publish-now-supports-v2-only-ipns-records) + - [IPNS name resolution has been fixed](#ipns-name-resolution-has-been-fixed) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -46,6 +47,14 @@ to V2 only in the future. **TODO**: add links to IPIP https://github.com/ipfs/specs/issues/376 +#### IPNS name resolution has been fixed + +IPNS name resolution had a regression where if IPNS over PubSub was enabled, but the name was not also available via IPNS over PubSub it would take 1 minute to for the lookup to complete (if the record was not yet cached). + +This has been fixed and as before will give the best record from either the DHT subsystem or IPNS over PubSub, whichever comes back first. + +For details see [#9927](https://github.com/ipfs/kubo/issues/9927) and [#10020](https://github.com/ipfs/kubo/pull/10020). + ### 📝 Changelog ### 👨‍👩‍👧‍👦 Contributors diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index d1ca4f5be..fcd582a7b 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -16,6 +16,7 @@ require ( require ( bazil.org/fuse v0.0.0-20200117225306-7b5117fecadc // indirect github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 // indirect + github.com/Jorropo/jsync v1.0.1 // indirect github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5 // indirect github.com/benbjohnson/clock v1.3.5 // indirect @@ -106,7 +107,7 @@ require ( github.com/libp2p/go-libp2p-pubsub v0.9.3 // indirect github.com/libp2p/go-libp2p-pubsub-router v0.6.0 // indirect github.com/libp2p/go-libp2p-record v0.2.0 // indirect - github.com/libp2p/go-libp2p-routing-helpers v0.7.0 // indirect + github.com/libp2p/go-libp2p-routing-helpers v0.7.1 // indirect github.com/libp2p/go-libp2p-xor v0.1.0 // indirect github.com/libp2p/go-mplex v0.7.0 // indirect github.com/libp2p/go-msgio v0.3.0 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 37ed3ee5c..217d783a9 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -45,6 +45,8 @@ github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 h1:cTp8I5+VIo github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/Jorropo/jsync v1.0.1 h1:6HgRolFZnsdfzRUj+ImB9og1JYOxQoReSywkHOGSaUU= +github.com/Jorropo/jsync v1.0.1/go.mod h1:jCOZj3vrBCri3bSU3ErUYvevKlnbssrXeCivybS5ABQ= github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= @@ -502,8 +504,8 @@ github.com/libp2p/go-libp2p-pubsub-router v0.6.0 h1:D30iKdlqDt5ZmLEYhHELCMRj8b4s github.com/libp2p/go-libp2p-pubsub-router v0.6.0/go.mod h1:FY/q0/RBTKsLA7l4vqC2cbRbOvyDotg8PJQ7j8FDudE= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= github.com/libp2p/go-libp2p-record v0.2.0/go.mod h1:I+3zMkvvg5m2OcSdoL0KPljyJyvNDFGKX7QdlpYUcwk= -github.com/libp2p/go-libp2p-routing-helpers v0.7.0 h1:sirOYVD0wGWjkDwHZvinunIpaqPLBXkcnXApVHwZFGA= -github.com/libp2p/go-libp2p-routing-helpers v0.7.0/go.mod h1:R289GUxUMzRXIbWGSuUUTPrlVJZ3Y/pPz495+qgXJX8= +github.com/libp2p/go-libp2p-routing-helpers v0.7.1 h1:kc0kWCZecbBPAiFEHhxfGJZPqjg1g9zV+X+ovR4Tmnc= +github.com/libp2p/go-libp2p-routing-helpers v0.7.1/go.mod h1:cHStPSRC/wgbfpb5jYdMP7zaSmc2wWcb1mkzNr6AR8o= github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA= github.com/libp2p/go-libp2p-xor v0.1.0 h1:hhQwT4uGrBcuAkUGXADuPltalOdpf9aag9kaYNT2tLA= github.com/libp2p/go-libp2p-xor v0.1.0/go.mod h1:LSTM5yRnjGZbWNTA/hRwq2gGFrvRIbQJscoIL/u6InY= diff --git a/go.mod b/go.mod index 73b5a3310..5785d84da 100644 --- a/go.mod +++ b/go.mod @@ -52,7 +52,7 @@ require ( github.com/libp2p/go-libp2p-pubsub v0.9.3 github.com/libp2p/go-libp2p-pubsub-router v0.6.0 github.com/libp2p/go-libp2p-record v0.2.0 - github.com/libp2p/go-libp2p-routing-helpers v0.7.0 + github.com/libp2p/go-libp2p-routing-helpers v0.7.1 github.com/libp2p/go-libp2p-testing v0.12.0 github.com/libp2p/go-socket-activation v0.1.0 github.com/mitchellh/go-homedir v1.1.0 @@ -91,6 +91,7 @@ require ( require ( github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 // indirect + github.com/Jorropo/jsync v1.0.1 // indirect github.com/Kubuxu/go-os-helper v0.0.1 // indirect github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5 // indirect diff --git a/go.sum b/go.sum index 08585f448..bd719ec82 100644 --- a/go.sum +++ b/go.sum @@ -47,6 +47,8 @@ github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 h1:cTp8I5+VIo github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/Jorropo/jsync v1.0.1 h1:6HgRolFZnsdfzRUj+ImB9og1JYOxQoReSywkHOGSaUU= +github.com/Jorropo/jsync v1.0.1/go.mod h1:jCOZj3vrBCri3bSU3ErUYvevKlnbssrXeCivybS5ABQ= github.com/Kubuxu/go-os-helper v0.0.1 h1:EJiD2VUQyh5A9hWJLmc6iWg6yIcJ7jpBcwC8GMGXfDk= github.com/Kubuxu/go-os-helper v0.0.1/go.mod h1:N8B+I7vPCT80IcP58r50u4+gEEcsZETFUpAzWW2ep1Y= github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= @@ -563,8 +565,8 @@ github.com/libp2p/go-libp2p-pubsub-router v0.6.0 h1:D30iKdlqDt5ZmLEYhHELCMRj8b4s github.com/libp2p/go-libp2p-pubsub-router v0.6.0/go.mod h1:FY/q0/RBTKsLA7l4vqC2cbRbOvyDotg8PJQ7j8FDudE= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= github.com/libp2p/go-libp2p-record v0.2.0/go.mod h1:I+3zMkvvg5m2OcSdoL0KPljyJyvNDFGKX7QdlpYUcwk= -github.com/libp2p/go-libp2p-routing-helpers v0.7.0 h1:sirOYVD0wGWjkDwHZvinunIpaqPLBXkcnXApVHwZFGA= -github.com/libp2p/go-libp2p-routing-helpers v0.7.0/go.mod h1:R289GUxUMzRXIbWGSuUUTPrlVJZ3Y/pPz495+qgXJX8= +github.com/libp2p/go-libp2p-routing-helpers v0.7.1 h1:kc0kWCZecbBPAiFEHhxfGJZPqjg1g9zV+X+ovR4Tmnc= +github.com/libp2p/go-libp2p-routing-helpers v0.7.1/go.mod h1:cHStPSRC/wgbfpb5jYdMP7zaSmc2wWcb1mkzNr6AR8o= github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA= github.com/libp2p/go-libp2p-testing v0.12.0/go.mod h1:KcGDRXyN7sQCllucn1cOOS+Dmm7ujhfEyXQL5lvkcPg= github.com/libp2p/go-libp2p-xor v0.1.0 h1:hhQwT4uGrBcuAkUGXADuPltalOdpf9aag9kaYNT2tLA= diff --git a/routing/delegated.go b/routing/delegated.go index 26340fb72..6d34970f5 100644 --- a/routing/delegated.go +++ b/routing/delegated.go @@ -105,10 +105,11 @@ func parse(visited map[string]bool, } pr = append(pr, &routinghelpers.ParallelRouter{ - Router: ri, - IgnoreError: cr.IgnoreErrors, - Timeout: cr.Timeout.Duration, - ExecuteAfter: cr.ExecuteAfter.WithDefault(0), + Router: ri, + IgnoreError: cr.IgnoreErrors, + DoNotWaitForSearchValue: true, + Timeout: cr.Timeout.Duration, + ExecuteAfter: cr.ExecuteAfter.WithDefault(0), }) } From c08313f032373e6cd97553f5af58cd1fee6ff0ce Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Tue, 27 Jun 2023 09:30:10 -0700 Subject: [PATCH 0781/1212] chore: update go-libp2p to v0.28.1 Co-authored-by: Jorropo --- core/commands/id.go | 2 - core/corehttp/gateway.go | 8 ++- core/corehttp/gateway_test.go | 17 +++--- docs/examples/kubo-as-a-library/go.mod | 6 +-- docs/examples/kubo-as-a-library/go.sum | 53 ++----------------- go.mod | 6 +-- go.sum | 50 ++--------------- test/dependencies/go.mod | 6 +-- test/dependencies/go.sum | 51 +++--------------- .../t0119-prometheus-data/prometheus_metrics | 5 ++ 10 files changed, 39 insertions(+), 165 deletions(-) diff --git a/core/commands/id.go b/core/commands/id.go index 2c4223bb4..ba40a699d 100644 --- a/core/commands/id.go +++ b/core/commands/id.go @@ -21,7 +21,6 @@ import ( "github.com/libp2p/go-libp2p/core/peer" pstore "github.com/libp2p/go-libp2p/core/peerstore" "github.com/libp2p/go-libp2p/core/protocol" - "github.com/libp2p/go-libp2p/p2p/protocol/identify" ) const offlineIDErrorMessage = "'ipfs id' cannot query information on remote peers without a running daemon; if you only want to convert --peerid-base, pass --offline option" @@ -217,7 +216,6 @@ func printSelf(keyEnc ke.KeyEncoder, node *core.IpfsNode) (interface{}, error) { info.Protocols = node.PeerHost.Mux().Protocols() sort.Slice(info.Protocols, func(i, j int) bool { return info.Protocols[i] < info.Protocols[j] }) } - info.ProtocolVersion = identify.DefaultProtocolVersion info.AgentVersion = version.GetUserAgentVersion() return info, nil } diff --git a/core/corehttp/gateway.go b/core/corehttp/gateway.go index 25ec19e0f..105fa89af 100644 --- a/core/corehttp/gateway.go +++ b/core/corehttp/gateway.go @@ -16,13 +16,12 @@ import ( "github.com/ipfs/boxo/gateway" "github.com/ipfs/boxo/namesys" offlineroute "github.com/ipfs/boxo/routing/offline" - cid "github.com/ipfs/go-cid" + "github.com/ipfs/go-cid" version "github.com/ipfs/kubo" - config "github.com/ipfs/kubo/config" - core "github.com/ipfs/kubo/core" + "github.com/ipfs/kubo/config" + "github.com/ipfs/kubo/core" "github.com/ipfs/kubo/core/node" "github.com/libp2p/go-libp2p/core/routing" - id "github.com/libp2p/go-libp2p/p2p/protocol/identify" "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" ) @@ -72,7 +71,6 @@ func VersionOption() ServeOption { mux.HandleFunc("/version", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Commit: %s\n", version.CurrentCommit) fmt.Fprintf(w, "Client Version: %s\n", version.GetUserAgentVersion()) - fmt.Fprintf(w, "Protocol Version: %s\n", id.DefaultProtocolVersion) }) return mux, nil } diff --git a/core/corehttp/gateway_test.go b/core/corehttp/gateway_test.go index cfc245137..172988bba 100644 --- a/core/corehttp/gateway_test.go +++ b/core/corehttp/gateway_test.go @@ -9,21 +9,20 @@ import ( "strings" "testing" - namesys "github.com/ipfs/boxo/namesys" + "github.com/ipfs/boxo/namesys" version "github.com/ipfs/kubo" - core "github.com/ipfs/kubo/core" + "github.com/ipfs/kubo/core" "github.com/ipfs/kubo/core/coreapi" - repo "github.com/ipfs/kubo/repo" + "github.com/ipfs/kubo/repo" "github.com/stretchr/testify/assert" iface "github.com/ipfs/boxo/coreiface" nsopts "github.com/ipfs/boxo/coreiface/options/namesys" - path "github.com/ipfs/boxo/path" - datastore "github.com/ipfs/go-datastore" + "github.com/ipfs/boxo/path" + "github.com/ipfs/go-datastore" syncds "github.com/ipfs/go-datastore/sync" - config "github.com/ipfs/kubo/config" + "github.com/ipfs/kubo/config" ci "github.com/libp2p/go-libp2p/core/crypto" - id "github.com/libp2p/go-libp2p/p2p/protocol/identify" ) type mockNamesys map[string]path.Path @@ -169,10 +168,6 @@ func TestVersion(t *testing.T) { if !strings.Contains(s, "Client Version: "+version.GetUserAgentVersion()) { t.Fatalf("response doesn't contain client version:\n%s", s) } - - if !strings.Contains(s, "Protocol Version: "+id.DefaultProtocolVersion) { - t.Fatalf("response doesn't contain protocol version:\n%s", s) - } } func TestDeserializedResponsesInheritance(t *testing.T) { diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index fcd582a7b..8be3eff9a 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -9,7 +9,7 @@ replace github.com/ipfs/kubo => ./../../.. require ( github.com/ipfs/boxo v0.10.3-0.20230724084731-f6b448b4263a github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 - github.com/libp2p/go-libp2p v0.27.7 + github.com/libp2p/go-libp2p v0.28.1 github.com/multiformats/go-multiaddr v0.9.0 ) @@ -53,6 +53,7 @@ require ( github.com/google/pprof v0.0.0-20230602150820-91b7bce49751 // indirect github.com/google/uuid v1.3.0 // indirect github.com/gorilla/mux v1.8.0 // indirect + github.com/gorilla/websocket v1.5.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 // indirect github.com/hannahhoward/go-pubsub v0.0.0-20200423002714-8d62886cc36e // indirect github.com/hashicorp/errwrap v1.1.0 // indirect @@ -111,7 +112,7 @@ require ( github.com/libp2p/go-libp2p-xor v0.1.0 // indirect github.com/libp2p/go-mplex v0.7.0 // indirect github.com/libp2p/go-msgio v0.3.0 // indirect - github.com/libp2p/go-nat v0.1.0 // indirect + github.com/libp2p/go-nat v0.2.0 // indirect github.com/libp2p/go-netroute v0.2.1 // indirect github.com/libp2p/go-reuseport v0.3.0 // indirect github.com/libp2p/go-yamux/v4 v4.0.0 // indirect @@ -196,5 +197,4 @@ require ( google.golang.org/protobuf v1.30.0 // indirect gopkg.in/square/go-jose.v2 v2.5.1 // indirect lukechampine.com/blake3 v1.2.1 // indirect - nhooyr.io/websocket v1.8.7 // indirect ) diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 217d783a9..c8b02ff38 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -166,10 +166,6 @@ github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4 github.com/gabriel-vasile/mimetype v1.4.1 h1:TRWk7se+TOjCYgRth7+1/OYLNiRNIotknkFtf/dnN7Q= github.com/gabriel-vasile/mimetype v1.4.1/go.mod h1:05Vi0w3Y9c/lNvJOdmIwvrrAhX3rYhfQQCaf9VJcv7M= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= -github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= -github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14= -github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= @@ -181,22 +177,9 @@ github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= -github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= -github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= -github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= -github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= -github.com/go-playground/validator/v10 v10.2.0 h1:KgJ0snyC2R9VXYN2rneOtQcw5aHQB1Vv0sFl1UcHBOY= -github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0= -github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0= -github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= -github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8= -github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= -github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo= -github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= @@ -262,8 +245,6 @@ github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/gopacket v1.1.17/go.mod h1:UdDNZ1OO62aGYVnPhxT1U6aI7ukYtA/kB8vaU0diBUM= github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= @@ -290,8 +271,8 @@ github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORR github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c h1:7lF+Vz0LqiRidnzC1Oq86fpX1q/iEv2KJdrCtttYjT4= github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= -github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= +github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= @@ -314,10 +295,8 @@ github.com/hashicorp/golang-lru/v2 v2.0.2 h1:Dwmkdr5Nc/oBiXgJS3CDHNhJtIHkuZ3DZF5 github.com/hashicorp/golang-lru/v2 v2.0.2/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= github.com/huin/goupnp v1.2.0 h1:uOKW26NG1hsSSbXIZ1IR7XP9Gjd1U8pnLaCMgntmkmY= github.com/huin/goupnp v1.2.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= -github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= @@ -438,8 +417,6 @@ github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= @@ -451,7 +428,6 @@ github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQL 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.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.16.5 h1:IFV2oUNUzZaz+XyusxpLzpzS8Pt5rh0Z16For/djlyI= github.com/klauspost/compress v1.16.5/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= @@ -459,7 +435,6 @@ github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa02 github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/koron/go-ssdp v0.0.0-20191105050749-2e1c40ed0b5d/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk= github.com/koron/go-ssdp v0.0.4 h1:1IDwrghSKYM7yLf7XCzbByg2sJ/JcNOZRXS2jczTwz0= github.com/koron/go-ssdp v0.0.4/go.mod h1:oDXq+E5IL5q0U8uSBcoAXzTzInwy5lEgC91HoKtbmZk= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= @@ -472,8 +447,6 @@ github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= -github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/libp2p/go-buffer-pool v0.0.1/go.mod h1:xtyIz9PMobb13WaxR6Zo1Pd1zXJKYg0a8KiIvDp3TzQ= github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM= github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= @@ -486,8 +459,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.27.7 h1:nhMs03CRxslKkkK2uLuN8f72uwNkE6RJS1JFb3H9UIQ= -github.com/libp2p/go-libp2p v0.27.7/go.mod h1:oMfQGTb9CHnrOuSM6yMmyK2lXz3qIhnkn2+oK3B1Y2g= +github.com/libp2p/go-libp2p v0.28.1 h1:YurK+ZAI6cKfASLJBVFkpVBdl3wGhFi6fusOt725ii8= +github.com/libp2p/go-libp2p v0.28.1/go.mod h1:s3Xabc9LSwOcnv9UD4nORnXKTsWkPMkIMB/JIGXVnzk= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= @@ -514,16 +487,14 @@ github.com/libp2p/go-mplex v0.7.0/go.mod h1:rW8ThnRcYWft/Jb2jeORBmPd6xuG3dGxWN/W github.com/libp2p/go-msgio v0.0.4/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= github.com/libp2p/go-msgio v0.3.0 h1:mf3Z8B1xcFN314sWX+2vOTShIE0Mmn2TXn3YCUQGNj0= github.com/libp2p/go-msgio v0.3.0/go.mod h1:nyRM819GmVaF9LX3l03RMh10QdOroF++NBbxAb0mmDM= -github.com/libp2p/go-nat v0.1.0 h1:MfVsH6DLcpa04Xr+p8hmVRG4juse0s3J8HyNWYHffXg= -github.com/libp2p/go-nat v0.1.0/go.mod h1:X7teVkwRHNInVNWQiO/tAiAVRwSr5zoRz4YSTC3uRBM= -github.com/libp2p/go-netroute v0.1.2/go.mod h1:jZLDV+1PE8y5XxBySEBgbuVAXbhtuHSdmLPL2n9MKbk= +github.com/libp2p/go-nat v0.2.0 h1:Tyz+bUFAYqGyJ/ppPPymMGbIgNRH+WqC5QrT5fKrrGk= +github.com/libp2p/go-nat v0.2.0/go.mod h1:3MJr+GRpRkyT65EpVPBstXLvOlAPzUVlG6Pwg9ohLJk= github.com/libp2p/go-netroute v0.2.1 h1:V8kVrpD8GK0Riv15/7VN6RbUQ3URNZVosw7H2v9tksU= github.com/libp2p/go-netroute v0.2.1/go.mod h1:hraioZr0fhBjG0ZRXJJ6Zj2IVEVNx6tDTFQfSmcq7mQ= 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= github.com/libp2p/go-reuseport v0.3.0 h1:iiZslO5byUYZEg9iCwJGf5h+sf1Agmqx2V2FDjPyvUw= github.com/libp2p/go-reuseport v0.3.0/go.mod h1:laea40AimhtfEqysZ71UpYj4S+R9VpH8PgqLo7L+SwI= -github.com/libp2p/go-sockaddr v0.0.2/go.mod h1:syPvOmNs24S3dFVGJA1/mrqdeijPxLV2Le3BRLKd68k= github.com/libp2p/go-yamux/v4 v4.0.0 h1:+Y80dV2Yx/kv7Y7JKu0LECyVdMXm1VUoko+VQ9rBfZQ= github.com/libp2p/go-yamux/v4 v4.0.0/go.mod h1:NWjl8ZTLOGlozrXSOZ/HlfG++39iKNnM5wwmtQP1YB4= github.com/libp2p/zeroconf/v2 v2.2.0 h1:Cup06Jv6u81HLhIj1KasuNM/RHHrJ8T7wOTS4+Tv53Q= @@ -538,7 +509,6 @@ github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaO github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= @@ -568,12 +538,8 @@ github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5 github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mr-tron/base58 v1.1.3/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= @@ -763,11 +729,7 @@ github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c h1:u6SKchux2yDvFQnDH github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM= github.com/ucarion/urlpath v0.0.0-20200424170820-7ccc79b76bbb h1:Ywfo8sUltxogBpFuMOFRrrSifO788kAFxmvVw31PtQQ= github.com/ucarion/urlpath v0.0.0-20200424170820-7ccc79b76bbb/go.mod h1:ikPs9bRWicNw3S7XpJ8sK/smGwU9WcSVU3dy9qahYBM= -github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= -github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= -github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU= @@ -922,7 +884,6 @@ golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -995,10 +956,8 @@ golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190405154228-4b34438f7a67/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1269,8 +1228,6 @@ honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9 lukechampine.com/blake3 v1.1.6/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= lukechampine.com/blake3 v1.2.1 h1:YuqqRuaqsGV71BV/nm9xlI0MKUv4QC54jQnBChWbGnI= lukechampine.com/blake3 v1.2.1/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= -nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g= -nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= pgregory.net/rapid v0.4.7 h1:MTNRktPuv5FNqOO151TM9mDTa+XHcX6ypYeISDVD14g= pgregory.net/rapid v0.4.7/go.mod h1:UYpPVyjFHzYBGHIxLFoupi8vwk6rXNzRY9OMvVxFIOU= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= diff --git a/go.mod b/go.mod index 5785d84da..ed2356777 100644 --- a/go.mod +++ b/go.mod @@ -45,7 +45,7 @@ require ( github.com/jbenet/goprocess v0.1.4 github.com/julienschmidt/httprouter v1.3.0 github.com/libp2p/go-doh-resolver v0.4.0 - github.com/libp2p/go-libp2p v0.27.7 + github.com/libp2p/go-libp2p v0.28.1 github.com/libp2p/go-libp2p-http v0.5.0 github.com/libp2p/go-libp2p-kad-dht v0.24.2 github.com/libp2p/go-libp2p-kbucket v0.6.3 @@ -126,6 +126,7 @@ require ( github.com/google/gopacket v1.1.19 // indirect github.com/google/pprof v0.0.0-20230602150820-91b7bce49751 // indirect github.com/gorilla/mux v1.8.0 // indirect + github.com/gorilla/websocket v1.5.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 // indirect github.com/hannahhoward/go-pubsub v0.0.0-20200423002714-8d62886cc36e // indirect github.com/hashicorp/errwrap v1.1.0 // indirect @@ -159,7 +160,7 @@ require ( github.com/libp2p/go-libp2p-xor v0.1.0 // indirect github.com/libp2p/go-mplex v0.7.0 // indirect github.com/libp2p/go-msgio v0.3.0 // indirect - github.com/libp2p/go-nat v0.1.0 // indirect + github.com/libp2p/go-nat v0.2.0 // indirect github.com/libp2p/go-netroute v0.2.1 // indirect github.com/libp2p/go-reuseport v0.3.0 // indirect github.com/libp2p/go-yamux/v4 v4.0.0 // indirect @@ -237,7 +238,6 @@ require ( gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect lukechampine.com/blake3 v1.2.1 // indirect - nhooyr.io/websocket v1.8.7 // indirect ) go 1.19 diff --git a/go.sum b/go.sum index bd719ec82..b9d4212dd 100644 --- a/go.sum +++ b/go.sum @@ -187,10 +187,6 @@ github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbS github.com/gabriel-vasile/mimetype v1.4.1 h1:TRWk7se+TOjCYgRth7+1/OYLNiRNIotknkFtf/dnN7Q= github.com/gabriel-vasile/mimetype v1.4.1/go.mod h1:05Vi0w3Y9c/lNvJOdmIwvrrAhX3rYhfQQCaf9VJcv7M= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= -github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= -github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14= -github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= @@ -213,23 +209,10 @@ github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= -github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= -github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= -github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= -github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= -github.com/go-playground/validator/v10 v10.2.0 h1:KgJ0snyC2R9VXYN2rneOtQcw5aHQB1Vv0sFl1UcHBOY= -github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0= -github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0= -github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= -github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8= -github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= -github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo= -github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= @@ -298,7 +281,6 @@ github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/gopacket v1.1.17/go.mod h1:UdDNZ1OO62aGYVnPhxT1U6aI7ukYtA/kB8vaU0diBUM= github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= @@ -325,8 +307,8 @@ github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORR github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c h1:7lF+Vz0LqiRidnzC1Oq86fpX1q/iEv2KJdrCtttYjT4= github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= -github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= +github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= @@ -349,10 +331,8 @@ github.com/hashicorp/golang-lru/v2 v2.0.2 h1:Dwmkdr5Nc/oBiXgJS3CDHNhJtIHkuZ3DZF5 github.com/hashicorp/golang-lru/v2 v2.0.2/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= github.com/huin/goupnp v1.2.0 h1:uOKW26NG1hsSSbXIZ1IR7XP9Gjd1U8pnLaCMgntmkmY= github.com/huin/goupnp v1.2.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= -github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= @@ -487,10 +467,8 @@ github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJS github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= @@ -506,7 +484,6 @@ github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQL 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.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.16.5 h1:IFV2oUNUzZaz+XyusxpLzpzS8Pt5rh0Z16For/djlyI= github.com/klauspost/compress v1.16.5/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= @@ -515,7 +492,6 @@ github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/q github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/koron/go-ssdp v0.0.0-20191105050749-2e1c40ed0b5d/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk= github.com/koron/go-ssdp v0.0.4 h1:1IDwrghSKYM7yLf7XCzbByg2sJ/JcNOZRXS2jczTwz0= github.com/koron/go-ssdp v0.0.4/go.mod h1:oDXq+E5IL5q0U8uSBcoAXzTzInwy5lEgC91HoKtbmZk= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= @@ -529,8 +505,6 @@ github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= -github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/libp2p/go-buffer-pool v0.0.1/go.mod h1:xtyIz9PMobb13WaxR6Zo1Pd1zXJKYg0a8KiIvDp3TzQ= github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM= github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= @@ -543,8 +517,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.27.7 h1:nhMs03CRxslKkkK2uLuN8f72uwNkE6RJS1JFb3H9UIQ= -github.com/libp2p/go-libp2p v0.27.7/go.mod h1:oMfQGTb9CHnrOuSM6yMmyK2lXz3qIhnkn2+oK3B1Y2g= +github.com/libp2p/go-libp2p v0.28.1 h1:YurK+ZAI6cKfASLJBVFkpVBdl3wGhFi6fusOt725ii8= +github.com/libp2p/go-libp2p v0.28.1/go.mod h1:s3Xabc9LSwOcnv9UD4nORnXKTsWkPMkIMB/JIGXVnzk= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= @@ -576,16 +550,14 @@ github.com/libp2p/go-mplex v0.7.0/go.mod h1:rW8ThnRcYWft/Jb2jeORBmPd6xuG3dGxWN/W github.com/libp2p/go-msgio v0.0.4/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= github.com/libp2p/go-msgio v0.3.0 h1:mf3Z8B1xcFN314sWX+2vOTShIE0Mmn2TXn3YCUQGNj0= github.com/libp2p/go-msgio v0.3.0/go.mod h1:nyRM819GmVaF9LX3l03RMh10QdOroF++NBbxAb0mmDM= -github.com/libp2p/go-nat v0.1.0 h1:MfVsH6DLcpa04Xr+p8hmVRG4juse0s3J8HyNWYHffXg= -github.com/libp2p/go-nat v0.1.0/go.mod h1:X7teVkwRHNInVNWQiO/tAiAVRwSr5zoRz4YSTC3uRBM= -github.com/libp2p/go-netroute v0.1.2/go.mod h1:jZLDV+1PE8y5XxBySEBgbuVAXbhtuHSdmLPL2n9MKbk= +github.com/libp2p/go-nat v0.2.0 h1:Tyz+bUFAYqGyJ/ppPPymMGbIgNRH+WqC5QrT5fKrrGk= +github.com/libp2p/go-nat v0.2.0/go.mod h1:3MJr+GRpRkyT65EpVPBstXLvOlAPzUVlG6Pwg9ohLJk= github.com/libp2p/go-netroute v0.2.1 h1:V8kVrpD8GK0Riv15/7VN6RbUQ3URNZVosw7H2v9tksU= github.com/libp2p/go-netroute v0.2.1/go.mod h1:hraioZr0fhBjG0ZRXJJ6Zj2IVEVNx6tDTFQfSmcq7mQ= 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= github.com/libp2p/go-reuseport v0.3.0 h1:iiZslO5byUYZEg9iCwJGf5h+sf1Agmqx2V2FDjPyvUw= github.com/libp2p/go-reuseport v0.3.0/go.mod h1:laea40AimhtfEqysZ71UpYj4S+R9VpH8PgqLo7L+SwI= -github.com/libp2p/go-sockaddr v0.0.2/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= github.com/libp2p/go-yamux/v4 v4.0.0 h1:+Y80dV2Yx/kv7Y7JKu0LECyVdMXm1VUoko+VQ9rBfZQ= @@ -606,7 +578,6 @@ 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.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= @@ -640,11 +611,9 @@ github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= @@ -882,11 +851,7 @@ github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c h1:u6SKchux2yDvFQnDH github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM= github.com/ucarion/urlpath v0.0.0-20200424170820-7ccc79b76bbb h1:Ywfo8sUltxogBpFuMOFRrrSifO788kAFxmvVw31PtQQ= github.com/ucarion/urlpath v0.0.0-20200424170820-7ccc79b76bbb/go.mod h1:ikPs9bRWicNw3S7XpJ8sK/smGwU9WcSVU3dy9qahYBM= -github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= -github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= -github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU= @@ -1056,7 +1021,6 @@ golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1142,10 +1106,8 @@ golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190405154228-4b34438f7a67/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1434,8 +1396,6 @@ honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9 lukechampine.com/blake3 v1.1.6/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= lukechampine.com/blake3 v1.2.1 h1:YuqqRuaqsGV71BV/nm9xlI0MKUv4QC54jQnBChWbGnI= lukechampine.com/blake3 v1.2.1/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= -nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g= -nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= pgregory.net/rapid v0.4.7 h1:MTNRktPuv5FNqOO151TM9mDTa+XHcX6ypYeISDVD14g= pgregory.net/rapid v0.4.7/go.mod h1:UYpPVyjFHzYBGHIxLFoupi8vwk6rXNzRY9OMvVxFIOU= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index e7b10c191..bbb8edde5 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -19,7 +19,7 @@ require ( github.com/ipld/go-ipld-prime v0.20.0 github.com/jbenet/go-random v0.0.0-20190219211222-123a90aedc0c github.com/jbenet/go-random-files v0.0.0-20190219210431-31b3f20ebded - github.com/libp2p/go-libp2p v0.27.7 + github.com/libp2p/go-libp2p v0.28.1 github.com/multiformats/go-multiaddr v0.9.0 github.com/multiformats/go-multihash v0.2.3 gotest.tools/gotestsum v0.4.2 @@ -104,6 +104,7 @@ require ( github.com/google/pprof v0.0.0-20230602150820-91b7bce49751 // indirect github.com/google/uuid v1.3.0 // indirect github.com/gordonklaus/ineffassign v0.0.0-20210914165742-4cc7213b9bc8 // indirect + github.com/gorilla/websocket v1.5.0 // indirect github.com/gostaticanalysis/analysisutil v0.7.1 // indirect github.com/gostaticanalysis/comment v1.4.2 // indirect github.com/gostaticanalysis/forcetypeassert v0.1.0 // indirect @@ -159,7 +160,7 @@ require ( github.com/libp2p/go-flow-metrics v0.1.0 // indirect github.com/libp2p/go-libp2p-asn-util v0.3.0 // indirect github.com/libp2p/go-msgio v0.3.0 // indirect - github.com/libp2p/go-nat v0.1.0 // indirect + github.com/libp2p/go-nat v0.2.0 // indirect github.com/libp2p/go-netroute v0.2.1 // indirect github.com/libp2p/go-reuseport v0.3.0 // indirect github.com/libp2p/go-yamux/v4 v4.0.0 // indirect @@ -288,5 +289,4 @@ require ( mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed // indirect mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b // indirect mvdan.cc/unparam v0.0.0-20220706161116-678bad134442 // indirect - nhooyr.io/websocket v1.8.7 // indirect ) diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index c8a237e6b..8c1d830e0 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -187,10 +187,6 @@ github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbS github.com/fzipp/gocyclo v0.6.0 h1:lsblElZG7d3ALtGMx9fmxeTKZaLLpU8mET09yN4BBLo= github.com/fzipp/gocyclo v0.6.0/go.mod h1:rXPyn8fnlpa0R2csP/31uerbiVBugk5whMdlyaLkLoA= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= -github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= -github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14= -github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/go-critic/go-critic v0.6.4 h1:tucuG1pvOyYgpBIrVxw0R6gwO42lNa92Aq3VaDoIs+E= github.com/go-critic/go-critic v0.6.4/go.mod h1:qL5SOlk7NtY6sJPoVCTKDIgzNOxHkkkOCVDyi9wJe1U= @@ -209,13 +205,6 @@ github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= -github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= -github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= -github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= -github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= -github.com/go-playground/validator/v10 v10.2.0 h1:KgJ0snyC2R9VXYN2rneOtQcw5aHQB1Vv0sFl1UcHBOY= -github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= @@ -244,12 +233,6 @@ github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b/go.mod h1:aUCEOzz github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= -github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0= -github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= -github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8= -github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= -github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo= -github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= @@ -331,7 +314,6 @@ github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/gopacket v1.1.17/go.mod h1:UdDNZ1OO62aGYVnPhxT1U6aI7ukYtA/kB8vaU0diBUM= github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= @@ -363,8 +345,8 @@ github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORR github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c h1:7lF+Vz0LqiRidnzC1Oq86fpX1q/iEv2KJdrCtttYjT4= github.com/gordonklaus/ineffassign v0.0.0-20210914165742-4cc7213b9bc8 h1:PVRE9d4AQKmbelZ7emNig1+NT27DUmKZn5qXxfio54U= github.com/gordonklaus/ineffassign v0.0.0-20210914165742-4cc7213b9bc8/go.mod h1:Qcp2HIAYhR7mNUVSIxZww3Guk4it82ghYcEXIAk+QT0= -github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM= -github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= +github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE= github.com/gostaticanalysis/analysisutil v0.0.3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE= github.com/gostaticanalysis/analysisutil v0.1.0/go.mod h1:dMhHRU9KTiDcuLGdy87/2gTR8WruwYZrKdRq9m1O6uw= @@ -405,10 +387,8 @@ github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= github.com/huin/goupnp v1.2.0 h1:uOKW26NG1hsSSbXIZ1IR7XP9Gjd1U8pnLaCMgntmkmY= github.com/huin/goupnp v1.2.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= -github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= @@ -507,10 +487,8 @@ github.com/jonboulle/clockwork v0.2.0 h1:J2SLSdy7HgElq8ekSl2Mxh6vrRNFxqbXGenYH2I github.com/jonboulle/clockwork v0.2.0/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= @@ -526,14 +504,12 @@ github.com/kisielk/errcheck v1.6.2 h1:uGQ9xI8/pgc9iOoCe7kWQgRE6SBTrCGmTSf0LrEtY7 github.com/kisielk/errcheck v1.6.2/go.mod h1:nXw/i/MfnvRHqXa7XXmQMUB0oNFGuBrNI8d8NLy0LPw= github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.16.5 h1:IFV2oUNUzZaz+XyusxpLzpzS8Pt5rh0Z16For/djlyI= github.com/klauspost/compress v1.16.5/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/koron/go-ssdp v0.0.0-20191105050749-2e1c40ed0b5d/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk= github.com/koron/go-ssdp v0.0.4 h1:1IDwrghSKYM7yLf7XCzbByg2sJ/JcNOZRXS2jczTwz0= github.com/koron/go-ssdp v0.0.4/go.mod h1:oDXq+E5IL5q0U8uSBcoAXzTzInwy5lEgC91HoKtbmZk= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= @@ -557,8 +533,6 @@ github.com/ldez/gomoddirectives v0.2.3 h1:y7MBaisZVDYmKvt9/l1mjNCiSA1BVn34U0ObUc github.com/ldez/gomoddirectives v0.2.3/go.mod h1:cpgBogWITnCfRq2qGoDkKMEVSaarhdBr6g8G04uz6d0= github.com/ldez/tagliatelle v0.3.1 h1:3BqVVlReVUZwafJUwQ+oxbx2BEX2vUG4Yu/NOfMiKiM= github.com/ldez/tagliatelle v0.3.1/go.mod h1:8s6WJQwEYHbKZDsp/LjArytKOG8qaMrKQQ3mFukHs88= -github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= -github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/leonklingele/grouper v1.1.0 h1:tC2y/ygPbMFSBOs3DcyaEMKnnwH7eYKzohOtRrf0SAg= github.com/leonklingele/grouper v1.1.0/go.mod h1:uk3I3uDfi9B6PeUjsCKi6ndcf63Uy7snXgR4yDYQVDY= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= @@ -568,22 +542,20 @@ github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38y github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.27.7 h1:nhMs03CRxslKkkK2uLuN8f72uwNkE6RJS1JFb3H9UIQ= -github.com/libp2p/go-libp2p v0.27.7/go.mod h1:oMfQGTb9CHnrOuSM6yMmyK2lXz3qIhnkn2+oK3B1Y2g= +github.com/libp2p/go-libp2p v0.28.1 h1:YurK+ZAI6cKfASLJBVFkpVBdl3wGhFi6fusOt725ii8= +github.com/libp2p/go-libp2p v0.28.1/go.mod h1:s3Xabc9LSwOcnv9UD4nORnXKTsWkPMkIMB/JIGXVnzk= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA= github.com/libp2p/go-msgio v0.3.0 h1:mf3Z8B1xcFN314sWX+2vOTShIE0Mmn2TXn3YCUQGNj0= github.com/libp2p/go-msgio v0.3.0/go.mod h1:nyRM819GmVaF9LX3l03RMh10QdOroF++NBbxAb0mmDM= -github.com/libp2p/go-nat v0.1.0 h1:MfVsH6DLcpa04Xr+p8hmVRG4juse0s3J8HyNWYHffXg= -github.com/libp2p/go-nat v0.1.0/go.mod h1:X7teVkwRHNInVNWQiO/tAiAVRwSr5zoRz4YSTC3uRBM= -github.com/libp2p/go-netroute v0.1.2/go.mod h1:jZLDV+1PE8y5XxBySEBgbuVAXbhtuHSdmLPL2n9MKbk= +github.com/libp2p/go-nat v0.2.0 h1:Tyz+bUFAYqGyJ/ppPPymMGbIgNRH+WqC5QrT5fKrrGk= +github.com/libp2p/go-nat v0.2.0/go.mod h1:3MJr+GRpRkyT65EpVPBstXLvOlAPzUVlG6Pwg9ohLJk= github.com/libp2p/go-netroute v0.2.1 h1:V8kVrpD8GK0Riv15/7VN6RbUQ3URNZVosw7H2v9tksU= github.com/libp2p/go-netroute v0.2.1/go.mod h1:hraioZr0fhBjG0ZRXJJ6Zj2IVEVNx6tDTFQfSmcq7mQ= github.com/libp2p/go-reuseport v0.3.0 h1:iiZslO5byUYZEg9iCwJGf5h+sf1Agmqx2V2FDjPyvUw= github.com/libp2p/go-reuseport v0.3.0/go.mod h1:laea40AimhtfEqysZ71UpYj4S+R9VpH8PgqLo7L+SwI= -github.com/libp2p/go-sockaddr v0.0.2/go.mod h1:syPvOmNs24S3dFVGJA1/mrqdeijPxLV2Le3BRLKd68k= github.com/libp2p/go-yamux/v4 v4.0.0 h1:+Y80dV2Yx/kv7Y7JKu0LECyVdMXm1VUoko+VQ9rBfZQ= github.com/libp2p/go-yamux/v4 v4.0.0/go.mod h1:NWjl8ZTLOGlozrXSOZ/HlfG++39iKNnM5wwmtQP1YB4= github.com/lufeee/execinquery v1.2.1 h1:hf0Ems4SHcUGBxpGN7Jz78z1ppVkP/837ZlETPCEtOM= @@ -639,11 +611,9 @@ github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrk github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/moricho/tparallel v0.2.1 h1:95FytivzT6rYzdJLdtfn6m1bfFJylOJK41+lgv/EHf4= github.com/moricho/tparallel v0.2.1/go.mod h1:fXEIZxG2vdfl0ZF8b42f5a78EhjjD5mX8qUplsoSU4k= @@ -910,10 +880,6 @@ github.com/tomarrell/wrapcheck/v2 v2.6.2 h1:3dI6YNcrJTQ/CJQ6M/DUkc0gnqYSIk6o0rCh github.com/tomarrell/wrapcheck/v2 v2.6.2/go.mod h1:ao7l5p0aOlUNJKI0qVwB4Yjlqutd0IvAB9Rdwyilxvg= github.com/tommy-muehle/go-mnd/v2 v2.5.0 h1:iAj0a8e6+dXSL7Liq0aXPox36FiN1dBbjA6lt9fl65s= github.com/tommy-muehle/go-mnd/v2 v2.5.0/go.mod h1:WsUAkMJMYww6l/ufffCD3m+P7LEvr8TnZn9lwVDlgzw= -github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= -github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= -github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= -github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/ultraware/funlen v0.0.3 h1:5ylVWm8wsNwH5aWo9438pwvsK0QiqVuUrt9bn7S/iLA= github.com/ultraware/funlen v0.0.3/go.mod h1:Dp4UiAus7Wdb9KUZsYWZEWiRzGuM2kXM1lPbfaF6xhA= github.com/ultraware/whitespace v0.0.5 h1:hh+/cpIcopyMYbZNVov9iSxvJU3OYQg78Sfaqzi/CzI= @@ -1044,7 +1010,6 @@ golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1120,10 +1085,8 @@ golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190405154228-4b34438f7a67/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1452,8 +1415,6 @@ mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b h1:DxJ5nJdkhDlLok9K6qO+5290kphD mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4= mvdan.cc/unparam v0.0.0-20220706161116-678bad134442 h1:seuXWbRB1qPrS3NQnHmFKLJLtskWyueeIzmLXghMGgk= mvdan.cc/unparam v0.0.0-20220706161116-678bad134442/go.mod h1:F/Cxw/6mVrNKqrR2YjFf5CaW0Bw4RL8RfbEf4GRggJk= -nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g= -nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/test/sharness/t0119-prometheus-data/prometheus_metrics b/test/sharness/t0119-prometheus-data/prometheus_metrics index 1b88486f0..56be74698 100644 --- a/test/sharness/t0119-prometheus-data/prometheus_metrics +++ b/test/sharness/t0119-prometheus-data/prometheus_metrics @@ -312,6 +312,8 @@ libp2p_eventbus_subscriber_event_queued libp2p_eventbus_subscriber_queue_full libp2p_eventbus_subscriber_queue_length libp2p_eventbus_subscribers_total +libp2p_holepunch_address_outcomes_total +libp2p_holepunch_outcomes_total libp2p_identify_addrs_count libp2p_identify_addrs_received_bucket libp2p_identify_addrs_received_count @@ -326,6 +328,9 @@ libp2p_relaysvc_connection_duration_seconds_count libp2p_relaysvc_connection_duration_seconds_sum libp2p_relaysvc_data_transferred_bytes_total libp2p_relaysvc_status +libp2p_swarm_dial_ranking_delay_seconds_bucket +libp2p_swarm_dial_ranking_delay_seconds_count +libp2p_swarm_dial_ranking_delay_seconds_sum process_cpu_seconds_total process_max_fds process_open_fds From 649283bb6c2a43a4df00e39f655008ed29f2a02d Mon Sep 17 00:00:00 2001 From: Marco Munizaga Date: Fri, 14 Jul 2023 10:26:00 -0700 Subject: [PATCH 0782/1212] chore: update go-libp2p to v0.29.0 --- core/node/libp2p/rcmgr.go | 3 +- docs/examples/kubo-as-a-library/go.mod | 42 ++++---- docs/examples/kubo-as-a-library/go.sum | 88 ++++++++--------- go.mod | 46 ++++----- go.sum | 96 +++++++++---------- test/dependencies/go.mod | 44 ++++----- test/dependencies/go.sum | 92 +++++++++--------- test/sharness/t0026-id.sh | 6 -- test/sharness/t0041-ping.sh | 2 +- .../t0119-prometheus-data/prometheus_metrics | 26 +++++ 10 files changed, 232 insertions(+), 213 deletions(-) diff --git a/core/node/libp2p/rcmgr.go b/core/node/libp2p/rcmgr.go index bc723d7e3..65b97a8d4 100644 --- a/core/node/libp2p/rcmgr.go +++ b/core/node/libp2p/rcmgr.go @@ -14,7 +14,6 @@ import ( "github.com/libp2p/go-libp2p/core/peer" "github.com/libp2p/go-libp2p/core/protocol" rcmgr "github.com/libp2p/go-libp2p/p2p/host/resource-manager" - rcmgrObs "github.com/libp2p/go-libp2p/p2p/host/resource-manager/obs" "github.com/multiformats/go-multiaddr" "go.uber.org/fx" @@ -70,7 +69,7 @@ filled in with autocomputed defaults.`) return nil, opts, err } - str, err := rcmgrObs.NewStatsTraceReporter() + str, err := rcmgr.NewStatsTraceReporter() if err != nil { return nil, opts, err } diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 8be3eff9a..f4d3016c4 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -9,8 +9,8 @@ replace github.com/ipfs/kubo => ./../../.. require ( github.com/ipfs/boxo v0.10.3-0.20230724084731-f6b448b4263a github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 - github.com/libp2p/go-libp2p v0.28.1 - github.com/multiformats/go-multiaddr v0.9.0 + github.com/libp2p/go-libp2p v0.29.0 + github.com/multiformats/go-multiaddr v0.10.1 ) require ( @@ -50,7 +50,7 @@ require ( github.com/golang/protobuf v1.5.3 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/gopacket v1.1.19 // indirect - github.com/google/pprof v0.0.0-20230602150820-91b7bce49751 // indirect + github.com/google/pprof v0.0.0-20230705174524-200ffdc848b8 // indirect github.com/google/uuid v1.3.0 // indirect github.com/gorilla/mux v1.8.0 // indirect github.com/gorilla/websocket v1.5.0 // indirect @@ -95,7 +95,7 @@ require ( github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect github.com/jbenet/goprocess v0.1.4 // indirect - github.com/klauspost/compress v1.16.5 // indirect + github.com/klauspost/compress v1.16.7 // indirect github.com/klauspost/cpuid/v2 v2.2.5 // indirect github.com/koron/go-ssdp v0.0.4 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect @@ -115,12 +115,12 @@ require ( github.com/libp2p/go-nat v0.2.0 // indirect github.com/libp2p/go-netroute v0.2.1 // indirect github.com/libp2p/go-reuseport v0.3.0 // indirect - github.com/libp2p/go-yamux/v4 v4.0.0 // indirect + github.com/libp2p/go-yamux/v4 v4.0.1 // indirect github.com/libp2p/zeroconf/v2 v2.2.0 // indirect github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect github.com/mattn/go-isatty v0.0.19 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect - github.com/miekg/dns v1.1.54 // indirect + github.com/miekg/dns v1.1.55 // indirect github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect github.com/minio/sha256-simd v1.0.1 // indirect @@ -135,7 +135,7 @@ require ( github.com/multiformats/go-multihash v0.2.3 // indirect github.com/multiformats/go-multistream v0.4.1 // indirect github.com/multiformats/go-varint v0.0.7 // indirect - github.com/onsi/ginkgo/v2 v2.9.7 // indirect + github.com/onsi/ginkgo/v2 v2.11.0 // indirect github.com/opencontainers/runtime-spec v1.0.2 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/openzipkin/zipkin-go v0.4.1 // indirect @@ -143,14 +143,14 @@ require ( github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/polydawn/refmt v0.89.0 // indirect - github.com/prometheus/client_golang v1.14.0 // indirect + github.com/prometheus/client_golang v1.16.0 // indirect github.com/prometheus/client_model v0.4.0 // indirect - github.com/prometheus/common v0.42.0 // indirect - github.com/prometheus/procfs v0.9.0 // indirect + github.com/prometheus/common v0.44.0 // indirect + github.com/prometheus/procfs v0.11.0 // indirect github.com/quic-go/qpack v0.4.0 // indirect github.com/quic-go/qtls-go1-19 v0.3.2 // indirect github.com/quic-go/qtls-go1-20 v0.2.2 // indirect - github.com/quic-go/quic-go v0.33.0 // indirect + github.com/quic-go/quic-go v0.36.2 // indirect github.com/quic-go/webtransport-go v0.5.3 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/samber/lo v1.36.0 // indirect @@ -178,23 +178,23 @@ require ( go.opentelemetry.io/proto/otlp v0.19.0 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/dig v1.17.0 // indirect - go.uber.org/fx v1.19.3 // indirect + go.uber.org/fx v1.20.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.24.0 // indirect go4.org v0.0.0-20230225012048-214862532bf5 // indirect - golang.org/x/crypto v0.10.0 // indirect - golang.org/x/exp v0.0.0-20230321023759-10a507213a29 // indirect - golang.org/x/mod v0.10.0 // indirect - golang.org/x/net v0.10.0 // indirect - golang.org/x/sync v0.2.0 // indirect - golang.org/x/sys v0.9.0 // indirect - golang.org/x/text v0.10.0 // indirect - golang.org/x/tools v0.9.1 // indirect + golang.org/x/crypto v0.11.0 // indirect + golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 // indirect + golang.org/x/mod v0.12.0 // indirect + golang.org/x/net v0.12.0 // indirect + golang.org/x/sync v0.3.0 // indirect + golang.org/x/sys v0.10.0 // indirect + golang.org/x/text v0.11.0 // indirect + golang.org/x/tools v0.11.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect gonum.org/v1/gonum v0.13.0 // indirect google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect google.golang.org/grpc v1.55.0 // indirect - google.golang.org/protobuf v1.30.0 // indirect + google.golang.org/protobuf v1.31.0 // indirect gopkg.in/square/go-jose.v2 v2.5.1 // indirect lukechampine.com/blake3 v1.2.1 // indirect ) diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index c8b02ff38..37f4ce54c 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -256,8 +256,8 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20230602150820-91b7bce49751 h1:hR7/MlvK23p6+lIw9SN1TigNLn9ZnF3W4SYRKq2gAHs= -github.com/google/pprof v0.0.0-20230602150820-91b7bce49751/go.mod h1:Jh3hGz2jkYak8qXPD19ryItVnUgpgeqzdkY/D0EaeuA= +github.com/google/pprof v0.0.0-20230705174524-200ffdc848b8 h1:n6vlPhxsA+BW/XsS5+uqi7GyzaLa5MH7qlSLBZtRdiA= +github.com/google/pprof v0.0.0-20230705174524-200ffdc848b8/go.mod h1:Jh3hGz2jkYak8qXPD19ryItVnUgpgeqzdkY/D0EaeuA= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -428,8 +428,8 @@ github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQL 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.16.5 h1:IFV2oUNUzZaz+XyusxpLzpzS8Pt5rh0Z16For/djlyI= -github.com/klauspost/compress v1.16.5/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I= +github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= @@ -459,8 +459,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.28.1 h1:YurK+ZAI6cKfASLJBVFkpVBdl3wGhFi6fusOt725ii8= -github.com/libp2p/go-libp2p v0.28.1/go.mod h1:s3Xabc9LSwOcnv9UD4nORnXKTsWkPMkIMB/JIGXVnzk= +github.com/libp2p/go-libp2p v0.29.0 h1:QduJ2XQr/Crg4EnloueWDL0Jj86N3Ezhyyj7XH+XwHI= +github.com/libp2p/go-libp2p v0.29.0/go.mod h1:iNKL7mEnZ9wAss+03IjAwM9ZAQXfVUAPUUmOACQfQ/g= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= @@ -495,8 +495,8 @@ github.com/libp2p/go-openssl v0.0.3/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO github.com/libp2p/go-openssl v0.0.4/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= github.com/libp2p/go-reuseport v0.3.0 h1:iiZslO5byUYZEg9iCwJGf5h+sf1Agmqx2V2FDjPyvUw= github.com/libp2p/go-reuseport v0.3.0/go.mod h1:laea40AimhtfEqysZ71UpYj4S+R9VpH8PgqLo7L+SwI= -github.com/libp2p/go-yamux/v4 v4.0.0 h1:+Y80dV2Yx/kv7Y7JKu0LECyVdMXm1VUoko+VQ9rBfZQ= -github.com/libp2p/go-yamux/v4 v4.0.0/go.mod h1:NWjl8ZTLOGlozrXSOZ/HlfG++39iKNnM5wwmtQP1YB4= +github.com/libp2p/go-yamux/v4 v4.0.1 h1:FfDR4S1wj6Bw2Pqbc8Uz7pCxeRBPbwsBbEdfwiCypkQ= +github.com/libp2p/go-yamux/v4 v4.0.1/go.mod h1:NWjl8ZTLOGlozrXSOZ/HlfG++39iKNnM5wwmtQP1YB4= github.com/libp2p/zeroconf/v2 v2.2.0 h1:Cup06Jv6u81HLhIj1KasuNM/RHHrJ8T7wOTS4+Tv53Q= github.com/libp2p/zeroconf/v2 v2.2.0/go.mod h1:fuJqLnUwZTshS3U/bMRJ3+ow/v9oid1n0DmyYyNO1Xs= github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= @@ -520,8 +520,8 @@ github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyex github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= -github.com/miekg/dns v1.1.54 h1:5jon9mWcb0sFJGpnI99tOMhCPyJ+RPVz5b63MQG0VWI= -github.com/miekg/dns v1.1.54/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= +github.com/miekg/dns v1.1.55 h1:GoQ4hpsj0nFLYe+bWiCToyrBEJXkQfOOIvFGFy0lEgo= +github.com/miekg/dns v1.1.55/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c h1:bzE/A84HN25pxAuk9Eej1Kz9OUelF97nAc82bDquQI8= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c/go.mod h1:0SQS9kMwD2VsyFEB++InYyBJroV/FRmBgcydeSUcJms= github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= @@ -554,8 +554,8 @@ github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a github.com/multiformats/go-multiaddr v0.1.0/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo= github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4= -github.com/multiformats/go-multiaddr v0.9.0 h1:3h4V1LHIk5w4hJHekMKWALPXErDfz/sggzwC/NcqbDQ= -github.com/multiformats/go-multiaddr v0.9.0/go.mod h1:mI67Lb1EeTOYb8GQfL/7wpIZwc46ElrvzhYnoJOmTT0= +github.com/multiformats/go-multiaddr v0.10.1 h1:HghtFrWyZEPrpTvgAMFJi6gFdgHfs2cb0pyfDsk+lqU= +github.com/multiformats/go-multiaddr v0.10.1/go.mod h1:jLEZsA61rwWNZQTHHnqq2HNa+4os/Hz54eqiRnsRqYQ= github.com/multiformats/go-multiaddr-dns v0.3.0/go.mod h1:mNzQ4eTGDg0ll1N9jKPOUogZPoJ30W8a7zk66FQPpdQ= github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A= github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk= @@ -594,12 +594,12 @@ github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= -github.com/onsi/ginkgo/v2 v2.9.7 h1:06xGQy5www2oN160RtEZoTvnP2sPhEfePYmCDc2szss= -github.com/onsi/ginkgo/v2 v2.9.7/go.mod h1:cxrmXWykAwTwhQsJOPfdIDiJ+l2RYq7U8hFU+M/1uw0= +github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU= +github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.27.7 h1:fVih9JD6ogIiHUN6ePK7HJidyEDpWGVB5mzM7cWNXoU= +github.com/onsi/gomega v1.27.8 h1:gegWiwZjBsf2DgiSbf5hpokZ98JVDMcWkUiigk6/KXc= github.com/opencontainers/runtime-spec v1.0.2 h1:UfAcuLBJB9Coz72x1hgl8O5RVzTdNiaglX6v2DM6FI0= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= @@ -624,26 +624,26 @@ github.com/polydawn/refmt v0.0.0-20201211092308-30ac6d18308e/go.mod h1:uIp+gprXx github.com/polydawn/refmt v0.89.0 h1:ADJTApkvkeBZsN0tBTx8QjpD9JkmxbKp0cxfr9qszm4= github.com/polydawn/refmt v0.89.0/go.mod h1:/zvteZs/GwLtCgZ4BL6CBsk9IKIlexP43ObX9AxTqTw= github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw= -github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= +github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8= +github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY= github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM= -github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= +github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY= +github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= -github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= +github.com/prometheus/procfs v0.11.0 h1:5EAgkfkMl659uZPbe9AS2N68a7Cc1TJbPEuGzFuRbyk= +github.com/prometheus/procfs v0.11.0/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= github.com/quic-go/qtls-go1-19 v0.3.2 h1:tFxjCFcTQzK+oMxG6Zcvp4Dq8dx4yD3dDiIiyc86Z5U= github.com/quic-go/qtls-go1-19 v0.3.2/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI= github.com/quic-go/qtls-go1-20 v0.2.2 h1:WLOPx6OY/hxtTxKV1Zrq20FtXtDEkeY00CGQm8GEa3E= github.com/quic-go/qtls-go1-20 v0.2.2/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= -github.com/quic-go/quic-go v0.33.0 h1:ItNoTDN/Fm/zBlq769lLJc8ECe9gYaW40veHCCco7y0= -github.com/quic-go/quic-go v0.33.0/go.mod h1:YMuhaAV9/jIu0XclDXwZPAsP/2Kgr5yMYhe9oxhhOFA= +github.com/quic-go/quic-go v0.36.2 h1:ZX/UNQ4gvpCv2RmwdbA6lrRjF6EBm5yZ7TMoT4NQVrA= +github.com/quic-go/quic-go v0.36.2/go.mod h1:zPetvwDlILVxt15n3hr3Gf/I3mDf7LpLKPhR4Ez0AZQ= github.com/quic-go/webtransport-go v0.5.3 h1:5XMlzemqB4qmOlgIus5zB45AcZ2kCgCy2EptUrfOPWU= github.com/quic-go/webtransport-go v0.5.3/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= @@ -651,7 +651,7 @@ github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtD github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= -github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd/go.mod h1:hPqNNc0+uJM6H+SuU8sEs5K5IQeKccPqeSjfgcKGgPk= @@ -805,8 +805,8 @@ go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/dig v1.17.0 h1:5Chju+tUvcC+N7N6EV08BJz41UZuO3BmHcN4A287ZLI= go.uber.org/dig v1.17.0/go.mod h1:rTxpf7l5I0eBTlE6/9RL+lDybC7WFwY2QH55ZSjy1mU= -go.uber.org/fx v1.19.3 h1:YqMRE4+2IepTYCMOvXqQpRa+QAVdiSTnsHU4XNWBceA= -go.uber.org/fx v1.19.3/go.mod h1:w2HrQg26ql9fLK7hlBiZ6JsRUKV+Lj/atT1KCjT8YhM= +go.uber.org/fx v1.20.0 h1:ZMC/pnRvhsthOZh9MZjMq5U8Or3mA9zBSPaLnzs3ihQ= +go.uber.org/fx v1.20.0/go.mod h1:qCUj0btiR3/JnanEr1TYEePfSw6o/4qYJscgvzQ5Ub0= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= @@ -842,8 +842,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM= -golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= +golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA= +golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -854,8 +854,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20230321023759-10a507213a29 h1:ooxPy7fPvB4kwsA2h+iBNHkAbp/4JxTSwCmvdjEYmug= -golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= +golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 h1:MGwJjxBy0HJshjDNfLsYO8xppfqWlA5ZT9OhtUUhTNw= +golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -879,8 +879,8 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk= -golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= +golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -923,8 +923,8 @@ golang.org/x/net v0.0.0-20210423184538-5f58ad60dda6/go.mod h1:OJAsFXCWl8Ukc7SiCT golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= -golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50= +golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -945,8 +945,8 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI= -golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= +golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/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= @@ -1005,8 +1005,8 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s= -golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= +golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -1020,8 +1020,8 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58= -golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4= +golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1079,8 +1079,8 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.9.1 h1:8WMNJAz3zrtPmnYC7ISf5dEn3MT0gY7jBJfw27yrrLo= -golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= +golang.org/x/tools v0.11.0 h1:EMCa6U9S2LtZXLAMoWiR/R8dAQFRqbAitmbJ2UKhoi8= +golang.org/x/tools v0.11.0/go.mod h1:anzJrxPjNtfgiYQYirP2CPGzGLxrH2u2QBhn6Bf3qY8= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1188,8 +1188,8 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= -google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/go.mod b/go.mod index ed2356777..c609d0473 100644 --- a/go.mod +++ b/go.mod @@ -45,7 +45,7 @@ require ( github.com/jbenet/goprocess v0.1.4 github.com/julienschmidt/httprouter v1.3.0 github.com/libp2p/go-doh-resolver v0.4.0 - github.com/libp2p/go-libp2p v0.28.1 + github.com/libp2p/go-libp2p v0.29.0 github.com/libp2p/go-libp2p-http v0.5.0 github.com/libp2p/go-libp2p-kad-dht v0.24.2 github.com/libp2p/go-libp2p-kbucket v0.6.3 @@ -56,7 +56,7 @@ require ( github.com/libp2p/go-libp2p-testing v0.12.0 github.com/libp2p/go-socket-activation v0.1.0 github.com/mitchellh/go-homedir v1.1.0 - github.com/multiformats/go-multiaddr v0.9.0 + github.com/multiformats/go-multiaddr v0.10.1 github.com/multiformats/go-multiaddr-dns v0.3.1 github.com/multiformats/go-multibase v0.2.0 github.com/multiformats/go-multicodec v0.9.0 @@ -64,7 +64,7 @@ require ( github.com/opentracing/opentracing-go v1.2.0 github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 github.com/pkg/errors v0.9.1 - github.com/prometheus/client_golang v1.14.0 + github.com/prometheus/client_golang v1.16.0 github.com/stretchr/testify v1.8.4 github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 github.com/tidwall/gjson v1.14.4 @@ -78,15 +78,15 @@ require ( go.opentelemetry.io/otel/sdk v1.16.0 go.opentelemetry.io/otel/trace v1.16.0 go.uber.org/dig v1.17.0 - go.uber.org/fx v1.19.3 + go.uber.org/fx v1.20.0 go.uber.org/multierr v1.11.0 go.uber.org/zap v1.24.0 - golang.org/x/crypto v0.10.0 - golang.org/x/exp v0.0.0-20230321023759-10a507213a29 - golang.org/x/mod v0.10.0 - golang.org/x/sync v0.2.0 - golang.org/x/sys v0.9.0 - google.golang.org/protobuf v1.30.0 + golang.org/x/crypto v0.11.0 + golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 + golang.org/x/mod v0.12.0 + golang.org/x/sync v0.3.0 + golang.org/x/sys v0.10.0 + google.golang.org/protobuf v1.31.0 ) require ( @@ -124,7 +124,7 @@ require ( github.com/golang/protobuf v1.5.3 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/gopacket v1.1.19 // indirect - github.com/google/pprof v0.0.0-20230602150820-91b7bce49751 // indirect + github.com/google/pprof v0.0.0-20230705174524-200ffdc848b8 // indirect github.com/gorilla/mux v1.8.0 // indirect github.com/gorilla/websocket v1.5.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 // indirect @@ -149,7 +149,7 @@ require ( github.com/ipfs/go-peertaskqueue v0.8.1 // indirect github.com/ipfs/go-verifcid v0.0.2 // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect - github.com/klauspost/compress v1.16.5 // indirect + github.com/klauspost/compress v1.16.7 // indirect github.com/klauspost/cpuid/v2 v2.2.5 // indirect github.com/koron/go-ssdp v0.0.4 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect @@ -163,7 +163,7 @@ require ( github.com/libp2p/go-nat v0.2.0 // indirect github.com/libp2p/go-netroute v0.2.1 // indirect github.com/libp2p/go-reuseport v0.3.0 // indirect - github.com/libp2p/go-yamux/v4 v4.0.0 // indirect + github.com/libp2p/go-yamux/v4 v4.0.1 // indirect github.com/libp2p/zeroconf/v2 v2.2.0 // indirect github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect github.com/mattn/go-colorable v0.1.4 // indirect @@ -171,7 +171,7 @@ require ( github.com/mattn/go-runewidth v0.0.4 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect - github.com/miekg/dns v1.1.54 // indirect + github.com/miekg/dns v1.1.55 // indirect github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect github.com/minio/sha256-simd v1.0.1 // indirect @@ -181,20 +181,20 @@ require ( github.com/multiformats/go-multiaddr-fmt v0.1.0 // indirect github.com/multiformats/go-multistream v0.4.1 // indirect github.com/multiformats/go-varint v0.0.7 // indirect - github.com/onsi/ginkgo/v2 v2.9.7 // indirect + github.com/onsi/ginkgo/v2 v2.11.0 // indirect github.com/opencontainers/runtime-spec v1.0.2 // indirect github.com/openzipkin/zipkin-go v0.4.1 // indirect github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/polydawn/refmt v0.89.0 // indirect github.com/prometheus/client_model v0.4.0 // indirect - github.com/prometheus/common v0.42.0 // indirect - github.com/prometheus/procfs v0.9.0 // indirect + github.com/prometheus/common v0.44.0 // indirect + github.com/prometheus/procfs v0.11.0 // indirect github.com/prometheus/statsd_exporter v0.22.7 // indirect github.com/quic-go/qpack v0.4.0 // indirect github.com/quic-go/qtls-go1-19 v0.3.2 // indirect github.com/quic-go/qtls-go1-20 v0.2.2 // indirect - github.com/quic-go/quic-go v0.33.0 // indirect + github.com/quic-go/quic-go v0.36.2 // indirect github.com/quic-go/webtransport-go v0.5.3 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/rs/cors v1.7.0 // indirect @@ -224,11 +224,11 @@ require ( go.opentelemetry.io/proto/otlp v0.19.0 // indirect go.uber.org/atomic v1.11.0 // indirect go4.org v0.0.0-20230225012048-214862532bf5 // indirect - golang.org/x/net v0.10.0 // indirect - golang.org/x/oauth2 v0.6.0 // indirect - golang.org/x/term v0.9.0 // indirect - golang.org/x/text v0.10.0 // indirect - golang.org/x/tools v0.9.1 // indirect + golang.org/x/net v0.12.0 // indirect + golang.org/x/oauth2 v0.8.0 // indirect + golang.org/x/term v0.10.0 // indirect + golang.org/x/text v0.11.0 // indirect + golang.org/x/tools v0.11.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect gonum.org/v1/gonum v0.13.0 // indirect google.golang.org/appengine v1.6.7 // indirect diff --git a/go.sum b/go.sum index b9d4212dd..5cd23dd27 100644 --- a/go.sum +++ b/go.sum @@ -292,8 +292,8 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20230602150820-91b7bce49751 h1:hR7/MlvK23p6+lIw9SN1TigNLn9ZnF3W4SYRKq2gAHs= -github.com/google/pprof v0.0.0-20230602150820-91b7bce49751/go.mod h1:Jh3hGz2jkYak8qXPD19ryItVnUgpgeqzdkY/D0EaeuA= +github.com/google/pprof v0.0.0-20230705174524-200ffdc848b8 h1:n6vlPhxsA+BW/XsS5+uqi7GyzaLa5MH7qlSLBZtRdiA= +github.com/google/pprof v0.0.0-20230705174524-200ffdc848b8/go.mod h1:Jh3hGz2jkYak8qXPD19ryItVnUgpgeqzdkY/D0EaeuA= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -484,8 +484,8 @@ github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQL 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.16.5 h1:IFV2oUNUzZaz+XyusxpLzpzS8Pt5rh0Z16For/djlyI= -github.com/klauspost/compress v1.16.5/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I= +github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= @@ -517,8 +517,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.28.1 h1:YurK+ZAI6cKfASLJBVFkpVBdl3wGhFi6fusOt725ii8= -github.com/libp2p/go-libp2p v0.28.1/go.mod h1:s3Xabc9LSwOcnv9UD4nORnXKTsWkPMkIMB/JIGXVnzk= +github.com/libp2p/go-libp2p v0.29.0 h1:QduJ2XQr/Crg4EnloueWDL0Jj86N3Ezhyyj7XH+XwHI= +github.com/libp2p/go-libp2p v0.29.0/go.mod h1:iNKL7mEnZ9wAss+03IjAwM9ZAQXfVUAPUUmOACQfQ/g= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= @@ -560,8 +560,8 @@ github.com/libp2p/go-reuseport v0.3.0 h1:iiZslO5byUYZEg9iCwJGf5h+sf1Agmqx2V2FDjP github.com/libp2p/go-reuseport v0.3.0/go.mod h1:laea40AimhtfEqysZ71UpYj4S+R9VpH8PgqLo7L+SwI= 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= -github.com/libp2p/go-yamux/v4 v4.0.0 h1:+Y80dV2Yx/kv7Y7JKu0LECyVdMXm1VUoko+VQ9rBfZQ= -github.com/libp2p/go-yamux/v4 v4.0.0/go.mod h1:NWjl8ZTLOGlozrXSOZ/HlfG++39iKNnM5wwmtQP1YB4= +github.com/libp2p/go-yamux/v4 v4.0.1 h1:FfDR4S1wj6Bw2Pqbc8Uz7pCxeRBPbwsBbEdfwiCypkQ= +github.com/libp2p/go-yamux/v4 v4.0.1/go.mod h1:NWjl8ZTLOGlozrXSOZ/HlfG++39iKNnM5wwmtQP1YB4= github.com/libp2p/zeroconf/v2 v2.2.0 h1:Cup06Jv6u81HLhIj1KasuNM/RHHrJ8T7wOTS4+Tv53Q= github.com/libp2p/zeroconf/v2 v2.2.0/go.mod h1:fuJqLnUwZTshS3U/bMRJ3+ow/v9oid1n0DmyYyNO1Xs= github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= @@ -592,8 +592,8 @@ github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyex github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= -github.com/miekg/dns v1.1.54 h1:5jon9mWcb0sFJGpnI99tOMhCPyJ+RPVz5b63MQG0VWI= -github.com/miekg/dns v1.1.54/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= +github.com/miekg/dns v1.1.55 h1:GoQ4hpsj0nFLYe+bWiCToyrBEJXkQfOOIvFGFy0lEgo= +github.com/miekg/dns v1.1.55/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c h1:bzE/A84HN25pxAuk9Eej1Kz9OUelF97nAc82bDquQI8= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c/go.mod h1:0SQS9kMwD2VsyFEB++InYyBJroV/FRmBgcydeSUcJms= github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= @@ -630,8 +630,8 @@ github.com/multiformats/go-multiaddr v0.1.0/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lg github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo= github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4= github.com/multiformats/go-multiaddr v0.4.0/go.mod h1:YcpyLH8ZPudLxQlemYBPhSm0/oCXAT8Z4mzFpyoPyRc= -github.com/multiformats/go-multiaddr v0.9.0 h1:3h4V1LHIk5w4hJHekMKWALPXErDfz/sggzwC/NcqbDQ= -github.com/multiformats/go-multiaddr v0.9.0/go.mod h1:mI67Lb1EeTOYb8GQfL/7wpIZwc46ElrvzhYnoJOmTT0= +github.com/multiformats/go-multiaddr v0.10.1 h1:HghtFrWyZEPrpTvgAMFJi6gFdgHfs2cb0pyfDsk+lqU= +github.com/multiformats/go-multiaddr v0.10.1/go.mod h1:jLEZsA61rwWNZQTHHnqq2HNa+4os/Hz54eqiRnsRqYQ= github.com/multiformats/go-multiaddr-dns v0.3.0/go.mod h1:mNzQ4eTGDg0ll1N9jKPOUogZPoJ30W8a7zk66FQPpdQ= github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A= github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk= @@ -672,12 +672,12 @@ github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= -github.com/onsi/ginkgo/v2 v2.9.7 h1:06xGQy5www2oN160RtEZoTvnP2sPhEfePYmCDc2szss= -github.com/onsi/ginkgo/v2 v2.9.7/go.mod h1:cxrmXWykAwTwhQsJOPfdIDiJ+l2RYq7U8hFU+M/1uw0= +github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU= +github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.27.7 h1:fVih9JD6ogIiHUN6ePK7HJidyEDpWGVB5mzM7cWNXoU= +github.com/onsi/gomega v1.27.8 h1:gegWiwZjBsf2DgiSbf5hpokZ98JVDMcWkUiigk6/KXc= github.com/opencontainers/runtime-spec v1.0.2 h1:UfAcuLBJB9Coz72x1hgl8O5RVzTdNiaglX6v2DM6FI0= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= @@ -711,8 +711,8 @@ github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqr github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_golang v1.12.2/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_golang v1.13.0/go.mod h1:vTeo+zgvILHsnnj/39Ou/1fPN5nJFOEMgftOUOmlvYQ= -github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw= -github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= +github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8= +github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -727,8 +727,8 @@ github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9 github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/common v0.35.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= -github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM= -github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= +github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY= +github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= @@ -737,8 +737,8 @@ github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4O github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= -github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= -github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= +github.com/prometheus/procfs v0.11.0 h1:5EAgkfkMl659uZPbe9AS2N68a7Cc1TJbPEuGzFuRbyk= +github.com/prometheus/procfs v0.11.0/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM= github.com/prometheus/statsd_exporter v0.22.7 h1:7Pji/i2GuhK6Lu7DHrtTkFmNBCudCPT1pX2CziuyQR0= github.com/prometheus/statsd_exporter v0.22.7/go.mod h1:N/TevpjkIh9ccs6nuzY3jQn9dFqnUakOjnEuMPJJJnI= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= @@ -747,8 +747,8 @@ github.com/quic-go/qtls-go1-19 v0.3.2 h1:tFxjCFcTQzK+oMxG6Zcvp4Dq8dx4yD3dDiIiyc8 github.com/quic-go/qtls-go1-19 v0.3.2/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI= github.com/quic-go/qtls-go1-20 v0.2.2 h1:WLOPx6OY/hxtTxKV1Zrq20FtXtDEkeY00CGQm8GEa3E= github.com/quic-go/qtls-go1-20 v0.2.2/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= -github.com/quic-go/quic-go v0.33.0 h1:ItNoTDN/Fm/zBlq769lLJc8ECe9gYaW40veHCCco7y0= -github.com/quic-go/quic-go v0.33.0/go.mod h1:YMuhaAV9/jIu0XclDXwZPAsP/2Kgr5yMYhe9oxhhOFA= +github.com/quic-go/quic-go v0.36.2 h1:ZX/UNQ4gvpCv2RmwdbA6lrRjF6EBm5yZ7TMoT4NQVrA= +github.com/quic-go/quic-go v0.36.2/go.mod h1:zPetvwDlILVxt15n3hr3Gf/I3mDf7LpLKPhR4Ez0AZQ= github.com/quic-go/webtransport-go v0.5.3 h1:5XMlzemqB4qmOlgIus5zB45AcZ2kCgCy2EptUrfOPWU= github.com/quic-go/webtransport-go v0.5.3/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= @@ -756,7 +756,7 @@ github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtD github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= -github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= @@ -942,8 +942,8 @@ go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/dig v1.17.0 h1:5Chju+tUvcC+N7N6EV08BJz41UZuO3BmHcN4A287ZLI= go.uber.org/dig v1.17.0/go.mod h1:rTxpf7l5I0eBTlE6/9RL+lDybC7WFwY2QH55ZSjy1mU= -go.uber.org/fx v1.19.3 h1:YqMRE4+2IepTYCMOvXqQpRa+QAVdiSTnsHU4XNWBceA= -go.uber.org/fx v1.19.3/go.mod h1:w2HrQg26ql9fLK7hlBiZ6JsRUKV+Lj/atT1KCjT8YhM= +go.uber.org/fx v1.20.0 h1:ZMC/pnRvhsthOZh9MZjMq5U8Or3mA9zBSPaLnzs3ihQ= +go.uber.org/fx v1.20.0/go.mod h1:qCUj0btiR3/JnanEr1TYEePfSw6o/4qYJscgvzQ5Ub0= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= @@ -979,8 +979,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM= -golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= +golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA= +golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -991,8 +991,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20230321023759-10a507213a29 h1:ooxPy7fPvB4kwsA2h+iBNHkAbp/4JxTSwCmvdjEYmug= -golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= +golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 h1:MGwJjxBy0HJshjDNfLsYO8xppfqWlA5ZT9OhtUUhTNw= +golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1016,8 +1016,8 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk= -golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= +golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1066,8 +1066,8 @@ golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= -golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50= +golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1078,8 +1078,8 @@ golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4Iltr golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.6.0 h1:Lh8GPgSKBfWSwFvtuWOfeI3aAAnbXTSutYxJiOJFgIw= -golang.org/x/oauth2 v0.6.0/go.mod h1:ycmewcwgD4Rpr3eZJLSB4Kyyljb3qDh40vJ8STE5HKw= +golang.org/x/oauth2 v0.8.0 h1:6dkIjl3j3LtZ/O3sTgZTMsLKSftL/B8Zgq4huOIIUu8= +golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE= golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1094,8 +1094,8 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI= -golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= +golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/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= @@ -1165,14 +1165,14 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s= -golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= +golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.9.0 h1:GRRCnKYhdQrD8kfRAdQ6Zcw1P0OcELxGLKJvtjVMZ28= -golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo= +golang.org/x/term v0.10.0 h1:3R7pNqamzBraeqj/Tj8qt1aQ2HpmlC+Cx/qL/7hn4/c= +golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1182,8 +1182,8 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58= -golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4= +golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1241,8 +1241,8 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.9.1 h1:8WMNJAz3zrtPmnYC7ISf5dEn3MT0gY7jBJfw27yrrLo= -golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= +golang.org/x/tools v0.11.0 h1:EMCa6U9S2LtZXLAMoWiR/R8dAQFRqbAitmbJ2UKhoi8= +golang.org/x/tools v0.11.0/go.mod h1:anzJrxPjNtfgiYQYirP2CPGzGLxrH2u2QBhn6Bf3qY8= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1354,8 +1354,8 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= -google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index bbb8edde5..a217d31cc 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -19,8 +19,8 @@ require ( github.com/ipld/go-ipld-prime v0.20.0 github.com/jbenet/go-random v0.0.0-20190219211222-123a90aedc0c github.com/jbenet/go-random-files v0.0.0-20190219210431-31b3f20ebded - github.com/libp2p/go-libp2p v0.28.1 - github.com/multiformats/go-multiaddr v0.9.0 + github.com/libp2p/go-libp2p v0.29.0 + github.com/multiformats/go-multiaddr v0.10.1 github.com/multiformats/go-multihash v0.2.3 gotest.tools/gotestsum v0.4.2 ) @@ -101,7 +101,7 @@ require ( github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4 // indirect github.com/google/go-cmp v0.5.9 // indirect github.com/google/gopacket v1.1.19 // indirect - github.com/google/pprof v0.0.0-20230602150820-91b7bce49751 // indirect + github.com/google/pprof v0.0.0-20230705174524-200ffdc848b8 // indirect github.com/google/uuid v1.3.0 // indirect github.com/gordonklaus/ineffassign v0.0.0-20210914165742-4cc7213b9bc8 // indirect github.com/gorilla/websocket v1.5.0 // indirect @@ -146,7 +146,7 @@ require ( github.com/julz/importas v0.1.0 // indirect github.com/kisielk/errcheck v1.6.2 // indirect github.com/kisielk/gotool v1.0.0 // indirect - github.com/klauspost/compress v1.16.5 // indirect + github.com/klauspost/compress v1.16.7 // indirect github.com/klauspost/cpuid/v2 v2.2.5 // indirect github.com/koron/go-ssdp v0.0.4 // indirect github.com/kulti/thelper v0.6.3 // indirect @@ -163,7 +163,7 @@ require ( github.com/libp2p/go-nat v0.2.0 // indirect github.com/libp2p/go-netroute v0.2.1 // indirect github.com/libp2p/go-reuseport v0.3.0 // indirect - github.com/libp2p/go-yamux/v4 v4.0.0 // indirect + github.com/libp2p/go-yamux/v4 v4.0.1 // indirect github.com/lufeee/execinquery v1.2.1 // indirect github.com/magiconair/properties v1.8.6 // indirect github.com/maratori/testpackage v1.1.0 // indirect @@ -175,7 +175,7 @@ require ( github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/mbilski/exhaustivestruct v1.2.0 // indirect github.com/mgechev/revive v1.2.3 // indirect - github.com/miekg/dns v1.1.54 // indirect + github.com/miekg/dns v1.1.55 // indirect github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect github.com/minio/sha256-simd v1.0.1 // indirect @@ -196,7 +196,7 @@ require ( github.com/nishanths/exhaustive v0.8.1 // indirect github.com/nishanths/predeclared v0.2.2 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect - github.com/onsi/ginkgo/v2 v2.9.7 // indirect + github.com/onsi/ginkgo/v2 v2.11.0 // indirect github.com/opencontainers/runtime-spec v1.0.2 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect @@ -207,10 +207,10 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect github.com/polydawn/refmt v0.89.0 // indirect github.com/polyfloyd/go-errorlint v1.0.2 // indirect - github.com/prometheus/client_golang v1.14.0 // indirect + github.com/prometheus/client_golang v1.16.0 // indirect github.com/prometheus/client_model v0.4.0 // indirect - github.com/prometheus/common v0.42.0 // indirect - github.com/prometheus/procfs v0.9.0 // indirect + github.com/prometheus/common v0.44.0 // indirect + github.com/prometheus/procfs v0.11.0 // indirect github.com/quasilyte/go-ruleguard v0.3.17 // indirect github.com/quasilyte/gogrep v0.0.0-20220120141003-628d8b3623b5 // indirect github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95 // indirect @@ -218,7 +218,7 @@ require ( github.com/quic-go/qpack v0.4.0 // indirect github.com/quic-go/qtls-go1-19 v0.3.2 // indirect github.com/quic-go/qtls-go1-20 v0.2.2 // indirect - github.com/quic-go/quic-go v0.33.0 // indirect + github.com/quic-go/quic-go v0.36.2 // indirect github.com/quic-go/webtransport-go v0.5.3 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect @@ -266,20 +266,20 @@ require ( go.opentelemetry.io/otel/trace v1.16.0 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/dig v1.17.0 // indirect - go.uber.org/fx v1.19.3 // indirect + go.uber.org/fx v1.20.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.24.0 // indirect - golang.org/x/crypto v0.10.0 // indirect - golang.org/x/exp v0.0.0-20230321023759-10a507213a29 // indirect + golang.org/x/crypto v0.11.0 // indirect + golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 // indirect golang.org/x/exp/typeparams v0.0.0-20220613132600-b0d781184e0d // indirect - golang.org/x/mod v0.10.0 // indirect - golang.org/x/net v0.10.0 // indirect - golang.org/x/sync v0.2.0 // indirect - golang.org/x/sys v0.9.0 // indirect - golang.org/x/term v0.9.0 // indirect - golang.org/x/text v0.10.0 // indirect - golang.org/x/tools v0.9.1 // indirect - google.golang.org/protobuf v1.30.0 // indirect + golang.org/x/mod v0.12.0 // indirect + golang.org/x/net v0.12.0 // indirect + golang.org/x/sync v0.3.0 // indirect + golang.org/x/sys v0.10.0 // indirect + golang.org/x/term v0.10.0 // indirect + golang.org/x/text v0.11.0 // indirect + golang.org/x/tools v0.11.0 // indirect + google.golang.org/protobuf v1.31.0 // indirect gopkg.in/ini.v1 v1.66.6 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 8c1d830e0..34d6d1b4f 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -329,8 +329,8 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20230602150820-91b7bce49751 h1:hR7/MlvK23p6+lIw9SN1TigNLn9ZnF3W4SYRKq2gAHs= -github.com/google/pprof v0.0.0-20230602150820-91b7bce49751/go.mod h1:Jh3hGz2jkYak8qXPD19ryItVnUgpgeqzdkY/D0EaeuA= +github.com/google/pprof v0.0.0-20230705174524-200ffdc848b8 h1:n6vlPhxsA+BW/XsS5+uqi7GyzaLa5MH7qlSLBZtRdiA= +github.com/google/pprof v0.0.0-20230705174524-200ffdc848b8/go.mod h1:Jh3hGz2jkYak8qXPD19ryItVnUgpgeqzdkY/D0EaeuA= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -504,8 +504,8 @@ github.com/kisielk/errcheck v1.6.2 h1:uGQ9xI8/pgc9iOoCe7kWQgRE6SBTrCGmTSf0LrEtY7 github.com/kisielk/errcheck v1.6.2/go.mod h1:nXw/i/MfnvRHqXa7XXmQMUB0oNFGuBrNI8d8NLy0LPw= github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.16.5 h1:IFV2oUNUzZaz+XyusxpLzpzS8Pt5rh0Z16For/djlyI= -github.com/klauspost/compress v1.16.5/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I= +github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -542,8 +542,8 @@ github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38y github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.28.1 h1:YurK+ZAI6cKfASLJBVFkpVBdl3wGhFi6fusOt725ii8= -github.com/libp2p/go-libp2p v0.28.1/go.mod h1:s3Xabc9LSwOcnv9UD4nORnXKTsWkPMkIMB/JIGXVnzk= +github.com/libp2p/go-libp2p v0.29.0 h1:QduJ2XQr/Crg4EnloueWDL0Jj86N3Ezhyyj7XH+XwHI= +github.com/libp2p/go-libp2p v0.29.0/go.mod h1:iNKL7mEnZ9wAss+03IjAwM9ZAQXfVUAPUUmOACQfQ/g= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= @@ -556,8 +556,8 @@ github.com/libp2p/go-netroute v0.2.1 h1:V8kVrpD8GK0Riv15/7VN6RbUQ3URNZVosw7H2v9t github.com/libp2p/go-netroute v0.2.1/go.mod h1:hraioZr0fhBjG0ZRXJJ6Zj2IVEVNx6tDTFQfSmcq7mQ= github.com/libp2p/go-reuseport v0.3.0 h1:iiZslO5byUYZEg9iCwJGf5h+sf1Agmqx2V2FDjPyvUw= github.com/libp2p/go-reuseport v0.3.0/go.mod h1:laea40AimhtfEqysZ71UpYj4S+R9VpH8PgqLo7L+SwI= -github.com/libp2p/go-yamux/v4 v4.0.0 h1:+Y80dV2Yx/kv7Y7JKu0LECyVdMXm1VUoko+VQ9rBfZQ= -github.com/libp2p/go-yamux/v4 v4.0.0/go.mod h1:NWjl8ZTLOGlozrXSOZ/HlfG++39iKNnM5wwmtQP1YB4= +github.com/libp2p/go-yamux/v4 v4.0.1 h1:FfDR4S1wj6Bw2Pqbc8Uz7pCxeRBPbwsBbEdfwiCypkQ= +github.com/libp2p/go-yamux/v4 v4.0.1/go.mod h1:NWjl8ZTLOGlozrXSOZ/HlfG++39iKNnM5wwmtQP1YB4= github.com/lufeee/execinquery v1.2.1 h1:hf0Ems4SHcUGBxpGN7Jz78z1ppVkP/837ZlETPCEtOM= github.com/lufeee/execinquery v1.2.1/go.mod h1:EC7DrEKView09ocscGHC+apXMIaorh4xqSxS/dy8SbM= github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= @@ -594,8 +594,8 @@ github.com/mgechev/revive v1.2.3 h1:NzIEEa9+WimQ6q2Ov7OcNeySS/IOcwtkQ8RAh0R5UJ4= github.com/mgechev/revive v1.2.3/go.mod h1:iAWlQishqCuj4yhV24FTnKSXGpbAA+0SckXB8GQMX/Q= github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= -github.com/miekg/dns v1.1.54 h1:5jon9mWcb0sFJGpnI99tOMhCPyJ+RPVz5b63MQG0VWI= -github.com/miekg/dns v1.1.54/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= +github.com/miekg/dns v1.1.55 h1:GoQ4hpsj0nFLYe+bWiCToyrBEJXkQfOOIvFGFy0lEgo= +github.com/miekg/dns v1.1.55/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c h1:bzE/A84HN25pxAuk9Eej1Kz9OUelF97nAc82bDquQI8= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c/go.mod h1:0SQS9kMwD2VsyFEB++InYyBJroV/FRmBgcydeSUcJms= github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= @@ -629,8 +629,8 @@ github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9 github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4= github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo= github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4= -github.com/multiformats/go-multiaddr v0.9.0 h1:3h4V1LHIk5w4hJHekMKWALPXErDfz/sggzwC/NcqbDQ= -github.com/multiformats/go-multiaddr v0.9.0/go.mod h1:mI67Lb1EeTOYb8GQfL/7wpIZwc46ElrvzhYnoJOmTT0= +github.com/multiformats/go-multiaddr v0.10.1 h1:HghtFrWyZEPrpTvgAMFJi6gFdgHfs2cb0pyfDsk+lqU= +github.com/multiformats/go-multiaddr v0.10.1/go.mod h1:jLEZsA61rwWNZQTHHnqq2HNa+4os/Hz54eqiRnsRqYQ= github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A= github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk= github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E= @@ -667,10 +667,10 @@ github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo/v2 v2.9.7 h1:06xGQy5www2oN160RtEZoTvnP2sPhEfePYmCDc2szss= -github.com/onsi/ginkgo/v2 v2.9.7/go.mod h1:cxrmXWykAwTwhQsJOPfdIDiJ+l2RYq7U8hFU+M/1uw0= +github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU= +github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.27.7 h1:fVih9JD6ogIiHUN6ePK7HJidyEDpWGVB5mzM7cWNXoU= +github.com/onsi/gomega v1.27.8 h1:gegWiwZjBsf2DgiSbf5hpokZ98JVDMcWkUiigk6/KXc= github.com/opencontainers/runtime-spec v1.0.2 h1:UfAcuLBJB9Coz72x1hgl8O5RVzTdNiaglX6v2DM6FI0= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= @@ -708,8 +708,8 @@ github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5Fsn github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= -github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw= -github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= +github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8= +github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -721,16 +721,16 @@ github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8 github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= -github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM= -github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= +github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY= +github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= -github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= +github.com/prometheus/procfs v0.11.0 h1:5EAgkfkMl659uZPbe9AS2N68a7Cc1TJbPEuGzFuRbyk= +github.com/prometheus/procfs v0.11.0/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM= github.com/quasilyte/go-ruleguard v0.3.1-0.20210203134552-1b5a410e1cc8/go.mod h1:KsAh3x0e7Fkpgs+Q9pNLS5XpFSvYCEVl5gP9Pp1xp30= github.com/quasilyte/go-ruleguard v0.3.17 h1:cDdoaSbQg11LXPDQqiCK54QmQXsEQQCTIgdcpeULGSI= github.com/quasilyte/go-ruleguard v0.3.17/go.mod h1:sST5PvaR7yb/Az5ksX8oc88usJ4EGjmJv7cK7y3jyig= @@ -750,14 +750,14 @@ github.com/quic-go/qtls-go1-19 v0.3.2 h1:tFxjCFcTQzK+oMxG6Zcvp4Dq8dx4yD3dDiIiyc8 github.com/quic-go/qtls-go1-19 v0.3.2/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI= github.com/quic-go/qtls-go1-20 v0.2.2 h1:WLOPx6OY/hxtTxKV1Zrq20FtXtDEkeY00CGQm8GEa3E= github.com/quic-go/qtls-go1-20 v0.2.2/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= -github.com/quic-go/quic-go v0.33.0 h1:ItNoTDN/Fm/zBlq769lLJc8ECe9gYaW40veHCCco7y0= -github.com/quic-go/quic-go v0.33.0/go.mod h1:YMuhaAV9/jIu0XclDXwZPAsP/2Kgr5yMYhe9oxhhOFA= +github.com/quic-go/quic-go v0.36.2 h1:ZX/UNQ4gvpCv2RmwdbA6lrRjF6EBm5yZ7TMoT4NQVrA= +github.com/quic-go/quic-go v0.36.2/go.mod h1:zPetvwDlILVxt15n3hr3Gf/I3mDf7LpLKPhR4Ez0AZQ= github.com/quic-go/webtransport-go v0.5.3 h1:5XMlzemqB4qmOlgIus5zB45AcZ2kCgCy2EptUrfOPWU= github.com/quic-go/webtransport-go v0.5.3/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= @@ -931,8 +931,8 @@ go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/dig v1.17.0 h1:5Chju+tUvcC+N7N6EV08BJz41UZuO3BmHcN4A287ZLI= go.uber.org/dig v1.17.0/go.mod h1:rTxpf7l5I0eBTlE6/9RL+lDybC7WFwY2QH55ZSjy1mU= -go.uber.org/fx v1.19.3 h1:YqMRE4+2IepTYCMOvXqQpRa+QAVdiSTnsHU4XNWBceA= -go.uber.org/fx v1.19.3/go.mod h1:w2HrQg26ql9fLK7hlBiZ6JsRUKV+Lj/atT1KCjT8YhM= +go.uber.org/fx v1.20.0 h1:ZMC/pnRvhsthOZh9MZjMq5U8Or3mA9zBSPaLnzs3ihQ= +go.uber.org/fx v1.20.0/go.mod h1:qCUj0btiR3/JnanEr1TYEePfSw6o/4qYJscgvzQ5Ub0= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= @@ -960,8 +960,8 @@ golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM= -golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= +golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA= +golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -972,8 +972,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20230321023759-10a507213a29 h1:ooxPy7fPvB4kwsA2h+iBNHkAbp/4JxTSwCmvdjEYmug= -golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= +golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 h1:MGwJjxBy0HJshjDNfLsYO8xppfqWlA5ZT9OhtUUhTNw= +golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= golang.org/x/exp/typeparams v0.0.0-20220428152302-39d4317da171/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/exp/typeparams v0.0.0-20220613132600-b0d781184e0d h1:+W8Qf4iJtMGKkyAygcKohjxTk4JPsL9DpzApJ22m5Ic= golang.org/x/exp/typeparams v0.0.0-20220613132600-b0d781184e0d/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= @@ -1005,8 +1005,8 @@ golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk= -golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= +golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1049,8 +1049,8 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= -golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50= +golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1076,8 +1076,8 @@ 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/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI= -golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= +golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/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= @@ -1144,12 +1144,12 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s= -golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= +golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.9.0 h1:GRRCnKYhdQrD8kfRAdQ6Zcw1P0OcELxGLKJvtjVMZ28= -golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo= +golang.org/x/term v0.10.0 h1:3R7pNqamzBraeqj/Tj8qt1aQ2HpmlC+Cx/qL/7hn4/c= +golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1158,8 +1158,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58= -golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4= +golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1252,8 +1252,8 @@ golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/tools v0.1.11/go.mod h1:SgwaegtQh8clINPpECJMqnxLv9I09HLqnW3RMqW0CA4= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.9.1 h1:8WMNJAz3zrtPmnYC7ISf5dEn3MT0gY7jBJfw27yrrLo= -golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= +golang.org/x/tools v0.11.0 h1:EMCa6U9S2LtZXLAMoWiR/R8dAQFRqbAitmbJ2UKhoi8= +golang.org/x/tools v0.11.0/go.mod h1:anzJrxPjNtfgiYQYirP2CPGzGLxrH2u2QBhn6Bf3qY8= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1361,8 +1361,8 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= -google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/test/sharness/t0026-id.sh b/test/sharness/t0026-id.sh index 5d6d3db09..5ae5f5006 100755 --- a/test/sharness/t0026-id.sh +++ b/test/sharness/t0026-id.sh @@ -32,12 +32,6 @@ test_expect_success "checking AgentVersion" ' test_cmp expected-agent-version actual-agent-version ' -test_expect_success "checking ProtocolVersion" ' - echo "ipfs/0.1.0" > expected-protocol-version && - ipfs id -f "\n" > actual-protocol-version && - test_cmp expected-protocol-version actual-protocol-version -' - test_expect_success "checking ID of self" ' ipfs config Identity.PeerID > expected-id && ipfs id -f "\n" > actual-id && diff --git a/test/sharness/t0041-ping.sh b/test/sharness/t0041-ping.sh index 14268989d..4bbf89969 100755 --- a/test/sharness/t0041-ping.sh +++ b/test/sharness/t0041-ping.sh @@ -27,7 +27,7 @@ test_expect_success "test ping other" ' test_expect_success "test ping unreachable peer" ' printf "Looking up peer %s\n" "$BAD_PEER" > bad_ping_exp && - printf "PING QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJx.\nPing error: no addresses\nError: ping failed\n" >> bad_ping_exp && + printf "PING QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJx.\nPing error: failed to dial: no addresses\nError: ping failed\n" >> bad_ping_exp && ! ipfsi 0 ping -n2 -- "$BAD_PEER" > bad_ping_actual 2>&1 && test_cmp bad_ping_exp bad_ping_actual ' diff --git a/test/sharness/t0119-prometheus-data/prometheus_metrics b/test/sharness/t0119-prometheus-data/prometheus_metrics index 56be74698..f3ba65c97 100644 --- a/test/sharness/t0119-prometheus-data/prometheus_metrics +++ b/test/sharness/t0119-prometheus-data/prometheus_metrics @@ -323,6 +323,32 @@ libp2p_identify_protocols_count libp2p_identify_protocols_received_bucket libp2p_identify_protocols_received_count libp2p_identify_protocols_received_sum +libp2p_rcmgr_conn_memory_bucket +libp2p_rcmgr_conn_memory_count +libp2p_rcmgr_conn_memory_sum +libp2p_rcmgr_connections +libp2p_rcmgr_fds +libp2p_rcmgr_peer_connections_bucket +libp2p_rcmgr_peer_connections_count +libp2p_rcmgr_peer_connections_sum +libp2p_rcmgr_peer_memory_bucket +libp2p_rcmgr_peer_memory_count +libp2p_rcmgr_peer_memory_sum +libp2p_rcmgr_peer_streams_bucket +libp2p_rcmgr_peer_streams_count +libp2p_rcmgr_peer_streams_sum +libp2p_rcmgr_previous_conn_memory_bucket +libp2p_rcmgr_previous_conn_memory_count +libp2p_rcmgr_previous_conn_memory_sum +libp2p_rcmgr_previous_peer_connections_bucket +libp2p_rcmgr_previous_peer_connections_count +libp2p_rcmgr_previous_peer_connections_sum +libp2p_rcmgr_previous_peer_memory_bucket +libp2p_rcmgr_previous_peer_memory_count +libp2p_rcmgr_previous_peer_memory_sum +libp2p_rcmgr_previous_peer_streams_bucket +libp2p_rcmgr_previous_peer_streams_count +libp2p_rcmgr_previous_peer_streams_sum libp2p_relaysvc_connection_duration_seconds_bucket libp2p_relaysvc_connection_duration_seconds_count libp2p_relaysvc_connection_duration_seconds_sum From 6be6630e4e838cf3ef0202d058a3657c7241b06e Mon Sep 17 00:00:00 2001 From: Jorropo Date: Fri, 21 Jul 2023 20:36:59 +0200 Subject: [PATCH 0783/1212] libp2p: stop reporting ProtocolVersion --- core/commands/id.go | 17 +++++------------ core/commands/swarm.go | 5 ----- docs/changelogs/v0.22.md | 7 +++++++ test/cli/swarm_test.go | 14 +++++--------- 4 files changed, 17 insertions(+), 26 deletions(-) diff --git a/core/commands/id.go b/core/commands/id.go index ba40a699d..3446fc267 100644 --- a/core/commands/id.go +++ b/core/commands/id.go @@ -26,12 +26,11 @@ import ( const offlineIDErrorMessage = "'ipfs id' cannot query information on remote peers without a running daemon; if you only want to convert --peerid-base, pass --offline option" type IdOutput struct { // nolint - ID string - PublicKey string - Addresses []string - AgentVersion string - ProtocolVersion string - Protocols []protocol.ID + ID string + PublicKey string + Addresses []string + AgentVersion string + Protocols []protocol.ID } const ( @@ -126,7 +125,6 @@ EXAMPLE: output := format output = strings.Replace(output, "", out.ID, -1) output = strings.Replace(output, "", out.AgentVersion, -1) - output = strings.Replace(output, "", out.ProtocolVersion, -1) output = strings.Replace(output, "", out.PublicKey, -1) output = strings.Replace(output, "", strings.Join(out.Addresses, "\n"), -1) output = strings.Replace(output, "", strings.Join(protocol.ConvertToStrings(out.Protocols), "\n"), -1) @@ -178,11 +176,6 @@ func printPeer(keyEnc ke.KeyEncoder, ps pstore.Peerstore, p peer.ID) (interface{ info.Protocols = append(info.Protocols, protocols...) sort.Slice(info.Protocols, func(i, j int) bool { return info.Protocols[i] < info.Protocols[j] }) - if v, err := ps.Get(p, "ProtocolVersion"); err == nil { - if vs, ok := v.(string); ok { - info.ProtocolVersion = vs - } - } if v, err := ps.Get(p, "AgentVersion"); err == nil { if vs, ok := v.(string); ok { info.AgentVersion = vs diff --git a/core/commands/swarm.go b/core/commands/swarm.go index 3d2adb757..0e28c7175 100644 --- a/core/commands/swarm.go +++ b/core/commands/swarm.go @@ -490,11 +490,6 @@ func (ci *connInfo) identifyPeer(ps pstore.Peerstore, p peer.ID) (IdOutput, erro sort.Slice(info.Protocols, func(i, j int) bool { return info.Protocols[i] < info.Protocols[j] }) } - if v, err := ps.Get(p, "ProtocolVersion"); err == nil { - if vs, ok := v.(string); ok { - info.ProtocolVersion = vs - } - } if v, err := ps.Get(p, "AgentVersion"); err == nil { if vs, ok := v.(string); ok { info.AgentVersion = vs diff --git a/docs/changelogs/v0.22.md b/docs/changelogs/v0.22.md index b1cac4532..366244346 100644 --- a/docs/changelogs/v0.22.md +++ b/docs/changelogs/v0.22.md @@ -9,6 +9,7 @@ - [Gateway: support for `order=` and `dups=` parameters (IPIP-412)](#gateway-support-for-order-and-dups-parameters-ipip-412) - [`ipfs name publish` now supports V2 only IPNS records](#ipfs-name-publish-now-supports-v2-only-ipns-records) - [IPNS name resolution has been fixed](#ipns-name-resolution-has-been-fixed) + - [go-libp2p v0.29.0 update with smart dialing](#go-libp2p-v0.29.0-update-with-smart-dialing) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -55,6 +56,12 @@ This has been fixed and as before will give the best record from either the DHT For details see [#9927](https://github.com/ipfs/kubo/issues/9927) and [#10020](https://github.com/ipfs/kubo/pull/10020). +# go-libp2p v0.29.0 update with smart dialing + +We updated from [go-libp2p](https://github.com/libp2p/go-libp2p) [v0.27.7](https://github.com/libp2p/go-libp2p/releases/tag/v0.27.7) to [v0.29.0](https://github.com/libp2p/go-libp2p/releases/tag/v0.29.0). This release includes smart dialing, which is a prioritization algorithm that will try to rank addresses and protocols rather than attempting all options in parallel. Anecdotally, we have observed [Kubo nodes make 30% less dials](https://github.com/libp2p/go-libp2p/issues/2326#issuecomment-1644332863) with no to low latency impact. + +This includes a breaking change to `ipfs id` and some of the `ipfs swarm` commands. We no longer report `ProtocolVersion`. This used to be hardcoded as `ipfs/0.1.0` and sent to other peers but was not providing any distinguishing value. See [libp2p/go-libp2p#2294](https://github.com/libp2p/go-libp2p/issues/2294) for more information. + ### 📝 Changelog ### 👨‍👩‍👧‍👦 Contributors diff --git a/test/cli/swarm_test.go b/test/cli/swarm_test.go index d1a4b5c6c..920d310ba 100644 --- a/test/cli/swarm_test.go +++ b/test/cli/swarm_test.go @@ -13,12 +13,11 @@ import ( // TODO: Migrate the rest of the sharness swarm test. func TestSwarm(t *testing.T) { type identifyType struct { - ID string - PublicKey string - Addresses []string - AgentVersion string - ProtocolVersion string - Protocols []string + ID string + PublicKey string + Addresses []string + AgentVersion string + Protocols []string } type peer struct { Identify identifyType @@ -53,7 +52,6 @@ func TestSwarm(t *testing.T) { actualPublicKey := output.Peers[0].Identify.PublicKey actualAgentVersion := output.Peers[0].Identify.AgentVersion actualAdresses := output.Peers[0].Identify.Addresses - actualProtocolVersion := output.Peers[0].Identify.ProtocolVersion actualProtocols := output.Peers[0].Identify.Protocols expectedID := otherNode.PeerID().String() @@ -62,7 +60,6 @@ func TestSwarm(t *testing.T) { assert.Equal(t, actualID, expectedID) assert.NotNil(t, actualPublicKey) assert.NotNil(t, actualAgentVersion) - assert.NotNil(t, actualProtocolVersion) assert.Len(t, actualAdresses, 1) assert.Equal(t, expectedAddresses[0], actualAdresses[0]) assert.Greater(t, len(actualProtocols), 0) @@ -89,7 +86,6 @@ func TestSwarm(t *testing.T) { assert.Equal(t, outputIdentify.ID, otherNodeIDOutput.ID) assert.Equal(t, outputIdentify.PublicKey, otherNodeIDOutput.PublicKey) assert.Equal(t, outputIdentify.AgentVersion, otherNodeIDOutput.AgentVersion) - assert.Equal(t, outputIdentify.ProtocolVersion, otherNodeIDOutput.ProtocolVersion) assert.ElementsMatch(t, outputIdentify.Addresses, otherNodeIDOutput.Addresses) assert.ElementsMatch(t, outputIdentify.Protocols, otherNodeIDOutput.Protocols) From 4c35289556ca4594b3bfbf83d7bbc10fcf0195b1 Mon Sep 17 00:00:00 2001 From: Mohamed MHAMDI Date: Wed, 26 Jul 2023 15:43:36 +0200 Subject: [PATCH 0784/1212] fix(relay): apply user provider options --- core/node/libp2p/relay.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/node/libp2p/relay.go b/core/node/libp2p/relay.go index 925fe7bd3..89567e30d 100644 --- a/core/node/libp2p/relay.go +++ b/core/node/libp2p/relay.go @@ -37,9 +37,9 @@ func RelayService(enable bool, relayOpts config.RelayService) func() (opts Libp2 BufferSize: int(relayOpts.BufferSize.WithDefault(int64(def.BufferSize))), ReservationTTL: relayOpts.ReservationTTL.WithDefault(def.ReservationTTL), MaxReservations: int(relayOpts.MaxReservations.WithDefault(int64(def.MaxReservations))), - MaxReservationsPerIP: int(relayOpts.MaxReservations.WithDefault(int64(def.MaxReservationsPerIP))), - MaxReservationsPerPeer: int(relayOpts.MaxReservations.WithDefault(int64(def.MaxReservationsPerPeer))), - MaxReservationsPerASN: int(relayOpts.MaxReservations.WithDefault(int64(def.MaxReservationsPerASN))), + MaxReservationsPerIP: int(relayOpts.MaxReservationsPerIP.WithDefault(int64(def.MaxReservationsPerIP))), + MaxReservationsPerPeer: int(relayOpts.MaxReservationsPerPeer.WithDefault(int64(def.MaxReservationsPerPeer))), + MaxReservationsPerASN: int(relayOpts.MaxReservationsPerASN.WithDefault(int64(def.MaxReservationsPerASN))), }))) } return From 5a0a9ede158de4905a220773b5ff5fc6dbf05682 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Wed, 26 Jul 2023 16:27:13 +0200 Subject: [PATCH 0785/1212] chore: bump boxo to v0.11.0 for release --- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- test/dependencies/go.mod | 2 +- test/dependencies/go.sum | 4 ++-- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index f4d3016c4..29123db14 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.18 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.10.3-0.20230724084731-f6b448b4263a + github.com/ipfs/boxo v0.11.0 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.29.0 github.com/multiformats/go-multiaddr v0.10.1 diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 37f4ce54c..5c1c2bd0c 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -301,8 +301,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.10.3-0.20230724084731-f6b448b4263a h1:eDO++KVTMF7wNqHHhNCZnW/Ocf2K6zCSizAbWoIMREo= -github.com/ipfs/boxo v0.10.3-0.20230724084731-f6b448b4263a/go.mod h1:8IfDmp+FzFGcF4zjAgHMVPpwYw4AjN9ePEzDfkaYJ1w= +github.com/ipfs/boxo v0.11.0 h1:urMxhZ3xoF4HssJVD3+0ssGT9pptEfHfbL8DYdoWFlg= +github.com/ipfs/boxo v0.11.0/go.mod h1:8IfDmp+FzFGcF4zjAgHMVPpwYw4AjN9ePEzDfkaYJ1w= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= diff --git a/go.mod b/go.mod index c609d0473..02f0972b2 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( github.com/fsnotify/fsnotify v1.6.0 github.com/google/uuid v1.3.0 github.com/hashicorp/go-multierror v1.1.1 - github.com/ipfs/boxo v0.10.3-0.20230724084731-f6b448b4263a + github.com/ipfs/boxo v0.11.0 github.com/ipfs/go-block-format v0.1.2 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 diff --git a/go.sum b/go.sum index 5cd23dd27..75bdfb9b4 100644 --- a/go.sum +++ b/go.sum @@ -337,8 +337,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.10.3-0.20230724084731-f6b448b4263a h1:eDO++KVTMF7wNqHHhNCZnW/Ocf2K6zCSizAbWoIMREo= -github.com/ipfs/boxo v0.10.3-0.20230724084731-f6b448b4263a/go.mod h1:8IfDmp+FzFGcF4zjAgHMVPpwYw4AjN9ePEzDfkaYJ1w= +github.com/ipfs/boxo v0.11.0 h1:urMxhZ3xoF4HssJVD3+0ssGT9pptEfHfbL8DYdoWFlg= +github.com/ipfs/boxo v0.11.0/go.mod h1:8IfDmp+FzFGcF4zjAgHMVPpwYw4AjN9ePEzDfkaYJ1w= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index a217d31cc..fb1a0ec0a 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -7,7 +7,7 @@ replace github.com/ipfs/kubo => ../../ require ( github.com/Kubuxu/gocovmerge v0.0.0-20161216165753-7ecaa51963cd github.com/golangci/golangci-lint v1.49.0 - github.com/ipfs/boxo v0.10.3-0.20230724084731-f6b448b4263a + github.com/ipfs/boxo v0.11.0 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 github.com/ipfs/go-datastore v0.6.0 diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 34d6d1b4f..152ccc4e1 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -395,8 +395,8 @@ github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NH github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.10.3-0.20230724084731-f6b448b4263a h1:eDO++KVTMF7wNqHHhNCZnW/Ocf2K6zCSizAbWoIMREo= -github.com/ipfs/boxo v0.10.3-0.20230724084731-f6b448b4263a/go.mod h1:8IfDmp+FzFGcF4zjAgHMVPpwYw4AjN9ePEzDfkaYJ1w= +github.com/ipfs/boxo v0.11.0 h1:urMxhZ3xoF4HssJVD3+0ssGT9pptEfHfbL8DYdoWFlg= +github.com/ipfs/boxo v0.11.0/go.mod h1:8IfDmp+FzFGcF4zjAgHMVPpwYw4AjN9ePEzDfkaYJ1w= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.1.2 h1:GAjkfhVx1f4YTODS6Esrj1wt2HhrtwTnhEr+DyPUaJo= From 9d6012c1307b5a080eb42275e858ef341539b9e2 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Thu, 27 Jul 2023 11:37:49 +0000 Subject: [PATCH 0786/1212] chore: update version --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index 8050b14d1..75a86953b 100644 --- a/version.go +++ b/version.go @@ -11,7 +11,7 @@ import ( var CurrentCommit string // CurrentVersionNumber is the current application's version literal -const CurrentVersionNumber = "0.22.0-dev" +const CurrentVersionNumber = "0.22.0" const ApiVersion = "/kubo/" + CurrentVersionNumber + "/" //nolint From 149190c5a6182b797e9959293ea2571bf622c8b6 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Thu, 27 Jul 2023 11:55:23 +0000 Subject: [PATCH 0787/1212] chore: update changelog for v0.22 --- docs/changelogs/v0.22.md | 186 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 186 insertions(+) diff --git a/docs/changelogs/v0.22.md b/docs/changelogs/v0.22.md index 366244346..46eee4275 100644 --- a/docs/changelogs/v0.22.md +++ b/docs/changelogs/v0.22.md @@ -64,4 +64,190 @@ This includes a breaking change to `ipfs id` and some of the `ipfs swarm` comman ### 📝 Changelog +
Full Changelog + +- github.com/ipfs/kubo: + - chore: update version + - fix(relay): apply user provider options + - libp2p: stop reporting ProtocolVersion + - chore: update go-libp2p to v0.29.0 + - chore: update go-libp2p to v0.28.1 + - fix: mark all routers DoNotWaitForSearchValue (#10020) ([ipfs/kubo#10020](https://github.com/ipfs/kubo/pull/10020)) + - feat(gateway): support for ipip-412 parameters + - docs(commands): explain that swarm connect can reuse existing connections or known addresses (#10015) ([ipfs/kubo#10015](https://github.com/ipfs/kubo/pull/10015)) + - docs: add Brave to RELEASE_ISSUE_TEMPLATE.md (#10012) ([ipfs/kubo#10012](https://github.com/ipfs/kubo/pull/10012)) + - feat: webui@4.0.2 + - ([ipfs/kubo#10008](https://github.com/ipfs/kubo/pull/10008)) + - docs: skip check before prepare branch in RELEASE_ISSUE_TEMPLATE.md + - docs: update RELEASE_ISSUE_TEMPLATE.md with a warning about npm publish + - docs: update refs to kuboreleaser in RELEASE_ISSUE_TEMPLATE.md + - docs: Gateway.HTTPHeaders + - refactor: replace boxo/ipld/car by ipld/go-car + - chore: bump to boxo master + - fix: correctly handle migration of configs + - fix(gateway): include CORS on subdomain redirects (#9994) ([ipfs/kubo#9994](https://github.com/ipfs/kubo/pull/9994)) + - fix: docker repository initialization race condition + - feat(ipns): records with V2-only signatures (#9932) ([ipfs/kubo#9932](https://github.com/ipfs/kubo/pull/9932)) + - cmds/dag/import: pin roots by default (#9966) ([ipfs/kubo#9966](https://github.com/ipfs/kubo/pull/9966)) + - docs: fix 0.21 changelog + - feat!: dag import - don't pin roots by default (#9926) ([ipfs/kubo#9926](https://github.com/ipfs/kubo/pull/9926)) + - fix(cmd): useful errors in dag import (#9945) ([ipfs/kubo#9945](https://github.com/ipfs/kubo/pull/9945)) + - feat: webui@4.0.1 (#9940) ([ipfs/kubo#9940](https://github.com/ipfs/kubo/pull/9940)) + - chore(docs): typo http→https + - fix: more stable prometheus test (#9944) ([ipfs/kubo#9944](https://github.com/ipfs/kubo/pull/9944)) + - ([ipfs/kubo#9937](https://github.com/ipfs/kubo/pull/9937)) +- github.com/ipfs/boxo (v0.10.2-0.20230629143123-2d3edc552442 -> v0.11.0): + - Release v0.11.0 ([ipfs/boxo#417](https://github.com/ipfs/boxo/pull/417)) + - ([ipfs/boxo#401](https://github.com/ipfs/boxo/pull/401)) +- github.com/ipfs/go-merkledag (v0.10.0 -> v0.11.0): + - chore: update v0.11.0 (#106) ([ipfs/go-merkledag#106](https://github.com/ipfs/go-merkledag/pull/106)) + - update merkeldag to use the explicit decoder registry (#104) ([ipfs/go-merkledag#104](https://github.com/ipfs/go-merkledag/pull/104)) + - Update status in README.md and added CODEOWNERS (#101) ([ipfs/go-merkledag#101](https://github.com/ipfs/go-merkledag/pull/101)) +- github.com/ipld/go-car/v2 (v2.9.1-0.20230325062757-fff0e4397a3d -> v2.10.2-0.20230622090957-499d0c909d33): + - feat: add inverse and version to filter cmd ([ipld/go-car#457](https://github.com/ipld/go-car/pull/457)) + - v0.6.1 bump + - chore: update usage of merkledag by go-car (#437) ([ipld/go-car#437](https://github.com/ipld/go-car/pull/437)) + - feat(cmd/car): add '--no-wrap' option to 'create' command ([ipld/go-car#432](https://github.com/ipld/go-car/pull/432)) + - fix: remove github.com/ipfs/go-ipfs-blockstore dependency + - feat: expose index for StorageCar + - perf: reduce NewCarReader allocations + - fix(deps): update deps for cmd (use master go-car and go-car/v2 for now) + - fix: new error strings from go-cid + - fix: tests should match stderr for verbose output + - fix: reading from stdin should broadcast EOF to block loaders + - refactor insertion index to be publicly accessible ([ipld/go-car#408](https://github.com/ipld/go-car/pull/408)) +- github.com/libp2p/go-libp2p (v0.27.7 -> v0.29.0): + - Release version v0.29.0 (#2431) ([libp2p/go-libp2p#2431](https://github.com/libp2p/go-libp2p/pull/2431)) + - webtransport: reject listening on a multiaddr with a certhash (#2426) ([libp2p/go-libp2p#2426](https://github.com/libp2p/go-libp2p/pull/2426)) + - swarm: deprecate libp2p.DialRanker option (#2430) ([libp2p/go-libp2p#2430](https://github.com/libp2p/go-libp2p/pull/2430)) + - quic: Update to quic-go v0.36.2 (#2424) ([libp2p/go-libp2p#2424](https://github.com/libp2p/go-libp2p/pull/2424)) + - autonat: fix typo in WithSchedule option comment (#2425) ([libp2p/go-libp2p#2425](https://github.com/libp2p/go-libp2p/pull/2425)) + - identify: filter nat64 well-known prefix ipv6 addresses (#2392) ([libp2p/go-libp2p#2392](https://github.com/libp2p/go-libp2p/pull/2392)) + - update go-multiaddr to v0.10.1, use Unique function from there (#2407) ([libp2p/go-libp2p#2407](https://github.com/libp2p/go-libp2p/pull/2407)) + - swarm: enable smart dialing by default (#2420) ([libp2p/go-libp2p#2420](https://github.com/libp2p/go-libp2p/pull/2420)) + - transport integration tests: make TestMoreStreamsThanOurLimits less flaky (#2410) ([libp2p/go-libp2p#2410](https://github.com/libp2p/go-libp2p/pull/2410)) + - holepunch: skip racy TestDirectDialWorks (#2419) ([libp2p/go-libp2p#2419](https://github.com/libp2p/go-libp2p/pull/2419)) + - swarm: change relay dial delay to 500ms (#2421) ([libp2p/go-libp2p#2421](https://github.com/libp2p/go-libp2p/pull/2421)) + - identify: disable racy TestLargeIdentifyMessage with race detector (#2401) ([libp2p/go-libp2p#2401](https://github.com/libp2p/go-libp2p/pull/2401)) + - swarm: make black hole detection configurable (#2403) ([libp2p/go-libp2p#2403](https://github.com/libp2p/go-libp2p/pull/2403)) + - net/mock: support ConnectionGater in MockNet (#2297) ([libp2p/go-libp2p#2297](https://github.com/libp2p/go-libp2p/pull/2297)) + - docs: Add a Github workflow for checking dead links (#2406) ([libp2p/go-libp2p#2406](https://github.com/libp2p/go-libp2p/pull/2406)) + - rcmgr: enable metrics by default (#2389) (#2409) ([libp2p/go-libp2p#2409](https://github.com/libp2p/go-libp2p/pull/2409)) + - chore: remove outdated info in README and link to libp2p-implementers slack (#2405) ([libp2p/go-libp2p#2405](https://github.com/libp2p/go-libp2p/pull/2405)) + - metrics: deduplicate code in examples (#2404) ([libp2p/go-libp2p#2404](https://github.com/libp2p/go-libp2p/pull/2404)) + - transport tests: remove mplex tests (#2402) ([libp2p/go-libp2p#2402](https://github.com/libp2p/go-libp2p/pull/2402)) + - swarm: implement Happy Eyeballs ranking (#2365) ([libp2p/go-libp2p#2365](https://github.com/libp2p/go-libp2p/pull/2365)) + - docs: fix some comments (#2391) ([libp2p/go-libp2p#2391](https://github.com/libp2p/go-libp2p/pull/2391)) + - metrics: provide separate docker-compose files for OSX and Linux (#2397) ([libp2p/go-libp2p#2397](https://github.com/libp2p/go-libp2p/pull/2397)) + - identify: use zero-alloc slice sorting function (#2396) ([libp2p/go-libp2p#2396](https://github.com/libp2p/go-libp2p/pull/2396)) + - rcmgr: move StatsTraceReporter to rcmgr package (#2388) ([libp2p/go-libp2p#2388](https://github.com/libp2p/go-libp2p/pull/2388)) + - swarm: implement blackhole detection (#2320) ([libp2p/go-libp2p#2320](https://github.com/libp2p/go-libp2p/pull/2320)) + - basichost / blankhost: wrap errors (#2331) ([libp2p/go-libp2p#2331](https://github.com/libp2p/go-libp2p/pull/2331)) + - network: don't allocate in DedupAddrs (#2395) ([libp2p/go-libp2p#2395](https://github.com/libp2p/go-libp2p/pull/2395)) + - rcmgr: test snapshot defaults and that we keep consistent defaults (#2315) ([libp2p/go-libp2p#2315](https://github.com/libp2p/go-libp2p/pull/2315)) + - rcmgr: register prometheus metrics with the libp2p registerer (#2370) ([libp2p/go-libp2p#2370](https://github.com/libp2p/go-libp2p/pull/2370)) + - metrics: make it possible to spin up Grafana using docker-compose (#2383) ([libp2p/go-libp2p#2383](https://github.com/libp2p/go-libp2p/pull/2383)) + - identify: set stream deadlines for Identify and Identify Push streams (#2382) ([libp2p/go-libp2p#2382](https://github.com/libp2p/go-libp2p/pull/2382)) + - fix: in the swarm move Connectedness emit after releasing conns (#2373) ([libp2p/go-libp2p#2373](https://github.com/libp2p/go-libp2p/pull/2373)) + - metrics: add example for metrics and dashboard (#2232) ([libp2p/go-libp2p#2232](https://github.com/libp2p/go-libp2p/pull/2232)) + - dashboards: finish metrics effort (#2362) ([libp2p/go-libp2p#2362](https://github.com/libp2p/go-libp2p/pull/2362)) + - transport tests: many streams and lots of data (#2296) ([libp2p/go-libp2p#2296](https://github.com/libp2p/go-libp2p/pull/2296)) + - webtransport: close the challenge stream after the Noise handshake (#2305) ([libp2p/go-libp2p#2305](https://github.com/libp2p/go-libp2p/pull/2305)) + - test: document why InstantTimer is required (#2351) ([libp2p/go-libp2p#2351](https://github.com/libp2p/go-libp2p/pull/2351)) + - rcmgr: fix link to dashboards in README (#2363) ([libp2p/go-libp2p#2363](https://github.com/libp2p/go-libp2p/pull/2363)) + - docs: fix some comments errors (#2356) ([libp2p/go-libp2p#2356](https://github.com/libp2p/go-libp2p/pull/2356)) + - release v0.28.0 (#2344) ([libp2p/go-libp2p#2344](https://github.com/libp2p/go-libp2p/pull/2344)) + - nat: add HasDiscoveredNAT method for checking NAT environments (#2358) ([libp2p/go-libp2p#2358](https://github.com/libp2p/go-libp2p/pull/2358)) + - swarm: fix stale DialBackoff comment (#2353) ([libp2p/go-libp2p#2353](https://github.com/libp2p/go-libp2p/pull/2353)) + - swarm: use RLock for DialBackoff reads (#2354) ([libp2p/go-libp2p#2354](https://github.com/libp2p/go-libp2p/pull/2354)) + - Clear stream scope if we error (#2345) ([libp2p/go-libp2p#2345](https://github.com/libp2p/go-libp2p/pull/2345)) + - changelog: improve description of smart dialing (#2342) ([libp2p/go-libp2p#2342](https://github.com/libp2p/go-libp2p/pull/2342)) + - swarm: make smart-dialing opt in (#2340) ([libp2p/go-libp2p#2340](https://github.com/libp2p/go-libp2p/pull/2340)) + - swarm: cleanup address filtering logic (#2333) ([libp2p/go-libp2p#2333](https://github.com/libp2p/go-libp2p/pull/2333)) + - chore: add 0.28.0 changelog (#2335) ([libp2p/go-libp2p#2335](https://github.com/libp2p/go-libp2p/pull/2335)) + - swarm: improve documentation for the DefaultDialRanker (#2336) ([libp2p/go-libp2p#2336](https://github.com/libp2p/go-libp2p/pull/2336)) + - holepunch: add metrics (#2246) ([libp2p/go-libp2p#2246](https://github.com/libp2p/go-libp2p/pull/2246)) + - swarm: implement smart dialing logic (#2260) ([libp2p/go-libp2p#2260](https://github.com/libp2p/go-libp2p/pull/2260)) + - revert "feat:add contexts to all peerstore methods (#2312)" (#2328) ([libp2p/go-libp2p#2328](https://github.com/libp2p/go-libp2p/pull/2328)) + - identify: don't save signed peer records (#2325) ([libp2p/go-libp2p#2325](https://github.com/libp2p/go-libp2p/pull/2325)) + - feat:add contexts to all peerstore methods (#2312) ([libp2p/go-libp2p#2312](https://github.com/libp2p/go-libp2p/pull/2312)) + - swarm: Dedup addresses to dial (#2322) ([libp2p/go-libp2p#2322](https://github.com/libp2p/go-libp2p/pull/2322)) + - identify: filter received addresses based on the node's remote address (#2300) ([libp2p/go-libp2p#2300](https://github.com/libp2p/go-libp2p/pull/2300)) + - update go-nat to v0.2.0, use context on AddMapping and RemoveMapping (#2319) ([libp2p/go-libp2p#2319](https://github.com/libp2p/go-libp2p/pull/2319)) + - transport integration tests: add tests for resource manager (#2285) ([libp2p/go-libp2p#2285](https://github.com/libp2p/go-libp2p/pull/2285)) + - identify: reject signed peer records on peer ID mismatch + - identify: don't send default protocol version (#2303) ([libp2p/go-libp2p#2303](https://github.com/libp2p/go-libp2p/pull/2303)) + - metrics: add instance filter to all dashboards (#2301) ([libp2p/go-libp2p#2301](https://github.com/libp2p/go-libp2p/pull/2301)) + - identify: avoid spuriously triggering pushes (#2299) ([libp2p/go-libp2p#2299](https://github.com/libp2p/go-libp2p/pull/2299)) + - net/mock: mimic Swarm's event and notification behavior in MockNet (#2287) ([libp2p/go-libp2p#2287](https://github.com/libp2p/go-libp2p/pull/2287)) + - examples: fix flaky multipro TestMain (#2289) ([libp2p/go-libp2p#2289](https://github.com/libp2p/go-libp2p/pull/2289)) + - swarm: change maps with multiaddress keys to use strings (#2284) ([libp2p/go-libp2p#2284](https://github.com/libp2p/go-libp2p/pull/2284)) + - tests: add comprehensive end-to-end tests for connection gating (#2200) ([libp2p/go-libp2p#2200](https://github.com/libp2p/go-libp2p/pull/2200)) + - swarm: log unexpected listener errors (#2277) ([libp2p/go-libp2p#2277](https://github.com/libp2p/go-libp2p/pull/2277)) + - websocket: switch back to the gorilla library (#2280) ([libp2p/go-libp2p#2280](https://github.com/libp2p/go-libp2p/pull/2280)) + - quic: prioritise listen connections for reuse (#2262) ([libp2p/go-libp2p#2262](https://github.com/libp2p/go-libp2p/pull/2262)) + - quic virtual listener: don't panic when quic-go's accept call errors (#2276) ([libp2p/go-libp2p#2276](https://github.com/libp2p/go-libp2p/pull/2276)) + - tests: add docks for debugging flaky tests (#2216) ([libp2p/go-libp2p#2216](https://github.com/libp2p/go-libp2p/pull/2216)) + - webtransport: only add cert hashes if we already started listening (#2271) ([libp2p/go-libp2p#2271](https://github.com/libp2p/go-libp2p/pull/2271)) + - Revert "webtransport: initialize the certmanager when creating the transport (#2268)" (#2273) ([libp2p/go-libp2p#2273](https://github.com/libp2p/go-libp2p/pull/2273)) + - webtransport: initialize the certmanager when creating the transport (#2268) ([libp2p/go-libp2p#2268](https://github.com/libp2p/go-libp2p/pull/2268)) + - move NAT mapping logic out of the host, add tests for NAT handling ([libp2p/go-libp2p#2248](https://github.com/libp2p/go-libp2p/pull/2248)) + - githooks: add a githook to check that the test-plans go.mod is tidied (#2256) ([libp2p/go-libp2p#2256](https://github.com/libp2p/go-libp2p/pull/2256)) + - quic: fix race condition when generating random holepunch packet (#2263) ([libp2p/go-libp2p#2263](https://github.com/libp2p/go-libp2p/pull/2263)) + - swarm: remove unused variable in addrDial (#2257) ([libp2p/go-libp2p#2257](https://github.com/libp2p/go-libp2p/pull/2257)) +- github.com/libp2p/go-libp2p-routing-helpers (v0.7.0 -> v0.7.1): + - chore: release v0.7.1 + - fix: for comparallel never return nil channel for FindProvidersAsync + - chore: rename DoNotWaitForStreamingResponses to DoNotWaitForSearchValue + - feat: add DoNotWaitForStreamingResponses to ParallelRouter + - chore: cleanup error handling in compparallel + - fix: correctly handle errors in compparallel + - fix: make the ProvideMany docs clearer + - perf: remove goroutine that just waits before closing with a synchrous waitgroup +- github.com/libp2p/go-nat (v0.1.0 -> v0.2.0): + - release v0.2.0 (#30) ([libp2p/go-nat#30](https://github.com/libp2p/go-nat/pull/30)) + - update deps, use contexts on UPnP functions (#29) ([libp2p/go-nat#29](https://github.com/libp2p/go-nat/pull/29)) + - sync: update CI config files (#28) ([libp2p/go-nat#28](https://github.com/libp2p/go-nat/pull/28)) + - sync: update CI config files (#24) ([libp2p/go-nat#24](https://github.com/libp2p/go-nat/pull/24)) +- github.com/libp2p/go-yamux/v4 (v4.0.0 -> v4.0.1): + - Release v4.0.1 ([libp2p/go-yamux#106](https://github.com/libp2p/go-yamux/pull/106)) + - fix: sendWindowUpdate respects deadlines (#105) ([libp2p/go-yamux#105](https://github.com/libp2p/go-yamux/pull/105)) +- github.com/multiformats/go-multiaddr (v0.9.0 -> v0.10.1): + - release v0.10.1 (#206) ([multiformats/go-multiaddr#206](https://github.com/multiformats/go-multiaddr/pull/206)) + - fix nat64 well-known prefix check (#205) ([multiformats/go-multiaddr#205](https://github.com/multiformats/go-multiaddr/pull/205)) + - release v0.10.0 (#204) ([multiformats/go-multiaddr#204](https://github.com/multiformats/go-multiaddr/pull/204)) + - add a Unique function (#203) ([multiformats/go-multiaddr#203](https://github.com/multiformats/go-multiaddr/pull/203)) + - manet: add function to test if address is NAT64 IPv4 converted IPv6 address (#202) ([multiformats/go-multiaddr#202](https://github.com/multiformats/go-multiaddr/pull/202)) + - sync: update CI config files (#190) ([multiformats/go-multiaddr#190](https://github.com/multiformats/go-multiaddr/pull/190)) + +
+ ### 👨‍👩‍👧‍👦 Contributors + +| Contributor | Commits | Lines ± | Files Changed | +|-------------|---------|---------|---------------| +| Henrique Dias | 14 | +3735/-17889 | 185 | +| Sukun | 27 | +5829/-957 | 98 | +| Marten Seemann | 39 | +2924/-1831 | 161 | +| Marco Munizaga | 17 | +1498/-580 | 76 | +| Prem Chaitanya Prathi | 1 | +757/-740 | 61 | +| Jorropo | 20 | +639/-444 | 49 | +| Marcin Rataj | 9 | +331/-194 | 20 | +| Will | 2 | +118/-211 | 9 | +| Adin Schmahmann | 4 | +275/-41 | 8 | +| Rod Vagg | 8 | +228/-46 | 28 | +| Adrian Sutton | 1 | +190/-17 | 4 | +| Hlib Kanunnikov | 3 | +139/-40 | 9 | +| VM | 2 | +80/-79 | 49 | +| web3-bot | 3 | +22/-46 | 4 | +| Will Scott | 2 | +29/-28 | 6 | +| Prithvi Shahi | 2 | +40/-7 | 2 | +| Laurent Senta | 1 | +40/-4 | 2 | +| Brad Fitzpatrick | 1 | +42/-2 | 2 | +| Piotr Galar | 3 | +16/-16 | 3 | +| Steve Loeppky | 1 | +6/-23 | 2 | +| Sahib Yar | 1 | +4/-4 | 3 | +| Russell Dempsey | 2 | +4/-2 | 2 | +| Mohamed MHAMDI | 1 | +3/-3 | 1 | +| Bryan White | 1 | +2/-2 | 1 | +| Dennis Trautwein | 1 | +1/-1 | 1 | From 51cc921d3c7bc2a98021997e1b64e6a700c7e6a0 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Thu, 27 Jul 2023 12:03:43 +0000 Subject: [PATCH 0788/1212] chore: update version --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index 8050b14d1..265ec937e 100644 --- a/version.go +++ b/version.go @@ -11,7 +11,7 @@ import ( var CurrentCommit string // CurrentVersionNumber is the current application's version literal -const CurrentVersionNumber = "0.22.0-dev" +const CurrentVersionNumber = "0.23.0-dev" const ApiVersion = "/kubo/" + CurrentVersionNumber + "/" //nolint From 9db33d319157e6befa2c3e365549786adf4deed5 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Thu, 27 Jul 2023 14:17:04 +0200 Subject: [PATCH 0789/1212] chore: fix version to v0.22.0-rc1 --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index 75a86953b..197690afe 100644 --- a/version.go +++ b/version.go @@ -11,7 +11,7 @@ import ( var CurrentCommit string // CurrentVersionNumber is the current application's version literal -const CurrentVersionNumber = "0.22.0" +const CurrentVersionNumber = "0.22.0-rc1" const ApiVersion = "/kubo/" + CurrentVersionNumber + "/" //nolint From c5868a86be16e3c0cd31f95da194060670407bdf Mon Sep 17 00:00:00 2001 From: Piotr Galar Date: Thu, 27 Jul 2023 18:53:24 +0100 Subject: [PATCH 0790/1212] refactor(ci): simplify Dockerfile and add docker image testing (#10021) --- .github/workflows/docker-build.yml | 2 + .github/workflows/docker-image.yml | 61 +++++++++++++++++++++++- Dockerfile | 74 +++++++++++++----------------- bin/container_daemon | 4 +- 4 files changed, 96 insertions(+), 45 deletions(-) diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml index 6c9187364..23278ec63 100644 --- a/.github/workflows/docker-build.yml +++ b/.github/workflows/docker-build.yml @@ -1,3 +1,4 @@ +# If we decide to run build-image.yml on every PR, we could deprecate this workflow. name: Docker Build on: @@ -30,3 +31,4 @@ jobs: go-version: 1.19.x - uses: actions/checkout@v3 - run: docker build -t $IMAGE_NAME:$WIP_IMAGE_TAG . + - run: docker run --rm $IMAGE_NAME:$WIP_IMAGE_TAG --version diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index e64850c33..0a346f310 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -2,6 +2,16 @@ name: Docker Push on: workflow_dispatch: + inputs: + push: + description: 'Push to Docker Hub' + required: true + default: 'false' + # # If we decide to build all images on every PR, we should make sure that + # # they are NOT pushed to Docker Hub. + # pull_request: + # paths-ignore: + # - '**/*.md' push: branches: - 'master' @@ -53,7 +63,54 @@ jobs: username: ${{ vars.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} - - name: Build Docker image and publish to Docker Hub + # We have to build each platform separately because when using multi-arch + # builds, only one platform is being loaded into the cache. This would + # prevent us from testing the other platforms. + - name: Build Docker image (linux/amd64) + uses: docker/build-push-action@v4 + with: + platforms: linux/amd64 + context: . + push: false + load: true + file: ./Dockerfile + tags: ${{ env.IMAGE_NAME }}:linux-amd64 + cache-from: type=local,src=/tmp/.buildx-cache + cache-to: type=local,dest=/tmp/.buildx-cache-new + + - name: Build Docker image (linux/arm/v7) + uses: docker/build-push-action@v4 + with: + platforms: linux/arm/v7 + context: . + push: false + load: true + file: ./Dockerfile + tags: ${{ env.IMAGE_NAME }}:linux-arm-v7 + cache-from: type=local,src=/tmp/.buildx-cache + cache-to: type=local,dest=/tmp/.buildx-cache-new + + - name: Build Docker image (linux/arm64/v8) + uses: docker/build-push-action@v4 + with: + platforms: linux/arm64/v8 + context: . + push: false + load: true + file: ./Dockerfile + tags: ${{ env.IMAGE_NAME }}:linux-arm64-v8 + cache-from: type=local,src=/tmp/.buildx-cache + cache-to: type=local,dest=/tmp/.buildx-cache-new + + # We test all the images on amd64 host here. This uses QEMU to emulate + # the other platforms. + - run: docker run --rm $IMAGE_NAME:linux-amd64 --version + - run: docker run --rm $IMAGE_NAME:linux-arm-v7 --version + - run: docker run --rm $IMAGE_NAME:linux-arm64-v8 --version + + # This will only push the previously built images. + - if: github.event_name != 'workflow_dispatch' || github.event.inputs.push == 'true' + name: Publish to Docker Hub uses: docker/build-push-action@v4 with: platforms: linux/amd64,linux/arm/v7,linux/arm64/v8 @@ -61,7 +118,7 @@ jobs: push: true file: ./Dockerfile tags: "${{ steps.tags.outputs.value }}" - cache-from: type=local,src=/tmp/.buildx-cache + cache-from: type=local,src=/tmp/.buildx-cache-new cache-to: type=local,dest=/tmp/.buildx-cache-new # https://github.com/docker/build-push-action/issues/252 diff --git a/Dockerfile b/Dockerfile index a5c8d816c..acdb70b31 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,16 +1,6 @@ -FROM --platform=${BUILDPLATFORM:-linux/amd64} golang:1.19-buster -LABEL maintainer="Steven Allen " +FROM --platform=${BUILDPLATFORM:-linux/amd64} golang:1.19-buster AS builder -ARG TARGETPLATFORM -ARG BUILDPLATFORM -ARG TARGETOS -ARG TARGETARCH - -# Install deps -RUN apt-get update && apt-get install -y \ - libssl-dev \ - ca-certificates \ - fuse +ARG TARGETPLATFORM TARGETOS TARGETARCH ENV SRC_DIR /kubo @@ -31,38 +21,40 @@ RUN cd $SRC_DIR \ && mkdir -p .git/objects \ && GOOS=$TARGETOS GOARCH=$TARGETARCH GOFLAGS=-buildvcs=false make build GOTAGS=openssl IPFS_PLUGINS=$IPFS_PLUGINS -# Get su-exec, a very minimal tool for dropping privileges, -# and tini, a very minimal init daemon for containers -ENV SUEXEC_VERSION v0.2 -ENV TINI_VERSION v0.19.0 +# Using Debian Buster because the version of busybox we're using is based on it +# and we want to make sure the libraries we're using are compatible. That's also +# why we're running this for the target platform. +FROM debian:buster-slim AS utilities RUN set -eux; \ - dpkgArch="$(dpkg --print-architecture)"; \ - case "${dpkgArch##*-}" in \ - "amd64" | "armhf" | "arm64") tiniArch="tini-static-$dpkgArch" ;;\ - *) echo >&2 "unsupported architecture: ${dpkgArch}"; exit 1 ;; \ - esac; \ - cd /tmp \ - && git clone https://github.com/ncopa/su-exec.git \ - && cd su-exec \ - && git checkout -q $SUEXEC_VERSION \ - && make su-exec-static \ - && cd /tmp \ - && wget -q -O tini https://github.com/krallin/tini/releases/download/$TINI_VERSION/$tiniArch \ - && chmod +x tini + apt-get update; \ + apt-get install -y \ + tini \ + # Using gosu (~2MB) instead of su-exec (~20KB) because it's easier to + # install on Debian. Useful links: + # - https://github.com/ncopa/su-exec#why-reinvent-gosu + # - https://github.com/tianon/gosu/issues/52#issuecomment-441946745 + gosu \ + # This installs fusermount which we later copy over to the target image. + fuse \ + ca-certificates \ + # This installs libssl.so and libcrypto.so which we later copy over to the + # target image. We need these to be able to use the OpenSSL plugin. + libssl-dev \ + ; \ + rm -rf /var/lib/apt/lists/* # Now comes the actual target image, which aims to be as small as possible. -FROM --platform=${BUILDPLATFORM:-linux/amd64} busybox:1.31.1-glibc -LABEL maintainer="Steven Allen " +FROM busybox:1.31.1-glibc # Get the ipfs binary, entrypoint script, and TLS CAs from the build container. ENV SRC_DIR /kubo -COPY --from=0 $SRC_DIR/cmd/ipfs/ipfs /usr/local/bin/ipfs -COPY --from=0 $SRC_DIR/bin/container_daemon /usr/local/bin/start_ipfs -COPY --from=0 $SRC_DIR/bin/container_init_run /usr/local/bin/container_init_run -COPY --from=0 /tmp/su-exec/su-exec-static /sbin/su-exec -COPY --from=0 /tmp/tini /sbin/tini -COPY --from=0 /bin/fusermount /usr/local/bin/fusermount -COPY --from=0 /etc/ssl/certs /etc/ssl/certs +COPY --from=builder $SRC_DIR/cmd/ipfs/ipfs /usr/local/bin/ipfs +COPY --from=builder $SRC_DIR/bin/container_daemon /usr/local/bin/start_ipfs +COPY --from=builder $SRC_DIR/bin/container_init_run /usr/local/bin/container_init_run +COPY --from=utilities /usr/sbin/gosu /sbin/gosu +COPY --from=utilities /usr/bin/tini /sbin/tini +COPY --from=utilities /bin/fusermount /usr/local/bin/fusermount +COPY --from=utilities /etc/ssl/certs /etc/ssl/certs # Add suid bit on fusermount so it will run properly RUN chmod 4755 /usr/local/bin/fusermount @@ -71,11 +63,11 @@ RUN chmod 4755 /usr/local/bin/fusermount RUN chmod 0755 /usr/local/bin/start_ipfs # This shared lib (part of glibc) doesn't seem to be included with busybox. -COPY --from=0 /lib/*-linux-gnu*/libdl.so.2 /lib/ +COPY --from=utilities /lib/*-linux-gnu*/libdl.so.2 /lib/ # Copy over SSL libraries. -COPY --from=0 /usr/lib/*-linux-gnu*/libssl.so* /usr/lib/ -COPY --from=0 /usr/lib/*-linux-gnu*/libcrypto.so* /usr/lib/ +COPY --from=utilities /usr/lib/*-linux-gnu*/libssl.so* /usr/lib/ +COPY --from=utilities /usr/lib/*-linux-gnu*/libcrypto.so* /usr/lib/ # Swarm TCP; should be exposed to the public EXPOSE 4001 diff --git a/bin/container_daemon b/bin/container_daemon index ae8725be5..9651ad55d 100755 --- a/bin/container_daemon +++ b/bin/container_daemon @@ -7,9 +7,9 @@ repo="$IPFS_PATH" if [ "$(id -u)" -eq 0 ]; then echo "Changing user to $user" # ensure folder is writable - su-exec "$user" test -w "$repo" || chown -R -- "$user" "$repo" + gosu "$user" test -w "$repo" || chown -R -- "$user" "$repo" # restart script with new privileges - exec su-exec "$user" "$0" "$@" + exec gosu "$user" "$0" "$@" fi # 2nd invocation with regular user From afa891b0edf13333580e8b8a2aba6be624d63ad9 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Thu, 27 Jul 2023 20:14:30 +0200 Subject: [PATCH 0791/1212] docs: changelog v0.21 fixes (#10037) Co-authored-by: Jorropo --- docs/changelogs/v0.21.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/changelogs/v0.21.md b/docs/changelogs/v0.21.md index b798c0d7b..d9dbbe2ab 100644 --- a/docs/changelogs/v0.21.md +++ b/docs/changelogs/v0.21.md @@ -109,7 +109,7 @@ Rationale can be found in [kubo#9913](https://github.com/ipfs/kubo/pull/9913). The gateway now supports optional CAR export parameters `dag-scope=block|entity|all` and `entity-bytes=from:to` as specified in -[IPIP-402](https://github.com/ipfs/specs/pull/402). +[IPIP-402](https://specs.ipfs.tech/ipips/ipip-0402/). Batch block retrieval minimizes round trips, catering to the requirements of light HTTP clients for directory enumeration, range requests, and content path @@ -144,7 +144,7 @@ By trading some upfront DHT caching and increased memory usage, one gets provider throughput improvements up to 6 millions times bigger dataset. See [the docs](docs/config.md#routingaccelerateddhtclient) for more info. -The `Experimental.AcceleratedDHTClient` flag moved to `[Routing.AcceleratedDHTClient](docs/config.md#routingaccelerateddhtclient)`. +The `Experimental.AcceleratedDHTClient` flag moved to [`Routing.AcceleratedDHTClient`](/docs/config.md#routingaccelerateddhtclient). A config migration has been added to handle this automatically. A new tracker estimates the providing speed and warns users if they @@ -228,7 +228,7 @@ should be using AcceleratedDHTClient because they are falling behind. - v0.2.1 ([ipfs/go-ipld-legacy#15](https://github.com/ipfs/go-ipld-legacy/pull/15)) - Expose a constructor for making a decoder with an existing link system ([ipfs/go-ipld-legacy#14](https://github.com/ipfs/go-ipld-legacy/pull/14)) - Update to v0.2.0 ([ipfs/go-ipld-legacy#13](https://github.com/ipfs/go-ipld-legacy/pull/13)) - - Remove global variable ([ipfs/go-ipld-legacy#12](https://github.com/ipfs/go-ipld-legacy/pull/12)) + - Remove global variable ([ipfs/go-ipld-legacy#12](https://github.com/ipfs/go-ipld-legacy/pull/12)) - sync: update CI config files (#8) ([ipfs/go-ipld-legacy#8](https://github.com/ipfs/go-ipld-legacy/pull/8)) - github.com/ipfs/go-unixfsnode (v1.6.0 -> v1.7.1): - chore: bump to v1.7.1 From e5050d014b94621cea1f48d1548f50bff21c08b8 Mon Sep 17 00:00:00 2001 From: Laurent Senta Date: Mon, 31 Jul 2023 12:04:48 +0200 Subject: [PATCH 0792/1212] chore: gateway conformance v0.3 --- .github/workflows/gateway-conformance.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/gateway-conformance.yml b/.github/workflows/gateway-conformance.yml index 56457ea34..4ce8215a2 100644 --- a/.github/workflows/gateway-conformance.yml +++ b/.github/workflows/gateway-conformance.yml @@ -23,7 +23,7 @@ jobs: steps: # 1. Download the gateway-conformance fixtures - name: Download gateway-conformance fixtures - uses: ipfs/gateway-conformance/.github/actions/extract-fixtures@v0.2 + uses: ipfs/gateway-conformance/.github/actions/extract-fixtures@v0.3 with: output: fixtures @@ -89,7 +89,7 @@ jobs: # 6. Run the gateway-conformance tests - name: Run gateway-conformance tests - uses: ipfs/gateway-conformance/.github/actions/test@v0.2 + uses: ipfs/gateway-conformance/.github/actions/test@v0.3 with: gateway-url: http://127.0.0.1:8080 json: output.json From 2cf65f28eb9cdc6970820de55fc017c859097f7a Mon Sep 17 00:00:00 2001 From: Antonio Navarro Perez Date: Mon, 31 Jul 2023 15:34:17 +0200 Subject: [PATCH 0793/1212] chore: update early testers list (#9218) * chore: Update early testers list * cleaning up early testers --------- Co-authored-by: Adin Schmahmann Co-authored-by: Piotr Galar --- docs/EARLY_TESTERS.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/EARLY_TESTERS.md b/docs/EARLY_TESTERS.md index d0dd4a867..40c40310d 100644 --- a/docs/EARLY_TESTERS.md +++ b/docs/EARLY_TESTERS.md @@ -29,7 +29,6 @@ We will ask early testers to participate at two points in the process: - [ ] pacman.store (@RubenKelevra) - [ ] Pinata (@obo20) - [ ] PL EngRes bifrost (@gmasgras) -- [ ] RTrade (@postables) - [ ] Siderus (@koalalorenzo) - [ ] Textile (@sanderpick) From 9013cf99562fdbd07021042caea3778101391922 Mon Sep 17 00:00:00 2001 From: Marco Munizaga Date: Mon, 12 Jun 2023 13:23:24 -0700 Subject: [PATCH 0794/1212] Fix usage numbers --- core/node/libp2p/rcmgr.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/node/libp2p/rcmgr.go b/core/node/libp2p/rcmgr.go index 65b97a8d4..c11c7262c 100644 --- a/core/node/libp2p/rcmgr.go +++ b/core/node/libp2p/rcmgr.go @@ -319,11 +319,11 @@ func mergeResourceLimitsAndScopeStatToResourceLimitsAndUsage(rl rcmgr.ResourceLi ConnsInbound: rl.ConnsInbound, ConnsInboundUsage: ss.NumConnsInbound, Streams: rl.Streams, - StreamsUsage: ss.NumStreamsOutbound + ss.NumConnsInbound, + StreamsUsage: ss.NumStreamsOutbound + ss.NumStreamsInbound, StreamsOutbound: rl.StreamsOutbound, - StreamsOutboundUsage: ss.NumConnsOutbound, + StreamsOutboundUsage: ss.NumStreamsOutbound, StreamsInbound: rl.StreamsInbound, - StreamsInboundUsage: ss.NumConnsInbound, + StreamsInboundUsage: ss.NumStreamsInbound, } } From 67ac4f40782053a4910727bf652543edb621e19b Mon Sep 17 00:00:00 2001 From: Jorropo Date: Mon, 31 Jul 2023 17:08:29 +0200 Subject: [PATCH 0795/1212] chore: change orbitdb to haydenyoung EARLY_TESTERS https://github.com/ipfs/kubo/issues/9911#issuecomment-1658468324 --- docs/EARLY_TESTERS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/EARLY_TESTERS.md b/docs/EARLY_TESTERS.md index 40c40310d..635890676 100644 --- a/docs/EARLY_TESTERS.md +++ b/docs/EARLY_TESTERS.md @@ -25,7 +25,7 @@ We will ask early testers to participate at two points in the process: - [ ] Charity Engine (@rytiss, @tristanolive) - [ ] Fission (@bmann) - [ ] Infura (@MichaelMure) -- [ ] OrbitDB (@aphelionz) +- [ ] OrbitDB (@haydenyoung) - [ ] pacman.store (@RubenKelevra) - [ ] Pinata (@obo20) - [ ] PL EngRes bifrost (@gmasgras) From 5bec4d67566f545a8d4965e36ec9b76c3827e63c Mon Sep 17 00:00:00 2001 From: Jorropo Date: Wed, 2 Aug 2023 17:01:41 +0200 Subject: [PATCH 0796/1212] ci: switch from testing against js-ipfs to helia (#10042) * ci: switch interop tests from js-ipfs to helia Fixes #10013 * Update .github/workflows/build.yml Co-authored-by: Henrique Dias --------- Co-authored-by: Henrique Dias --- .github/workflows/build.yml | 54 ++++++++++++++++++++++------------ docs/RELEASE_ISSUE_TEMPLATE.md | 6 ---- 2 files changed, 35 insertions(+), 25 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 33d9f828a..468d121a9 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -48,45 +48,61 @@ jobs: with: name: kubo path: cmd/ipfs/ipfs - interop: + helia-interop: needs: [interop-prep] runs-on: ${{ fromJSON(github.repository == 'ipfs/kubo' && '["self-hosted", "linux", "x64", "2xlarge"]' || '"ubuntu-latest"') }} timeout-minutes: 20 defaults: run: shell: bash + strategy: + matrix: + repo-to-test-against: ["helia", "helia-ipns", "helia-unixfs"] # this needs to be manually kept in sync as new helia tests are written steps: - uses: actions/setup-node@v3 with: - node-version: 16.12.0 + node-version: lts/* - uses: actions/download-artifact@v3 with: name: kubo path: cmd/ipfs - run: chmod +x cmd/ipfs/ipfs - - run: | - echo "dir=$(npm config get cache)" >> $GITHUB_OUTPUT + - run: echo "dir=$(npm config get cache)" >> $GITHUB_OUTPUT id: npm-cache-dir - uses: actions/cache@v3 with: path: ${{ steps.npm-cache-dir.outputs.dir }} - key: ${{ runner.os }}-${{ github.job }}-${{ hashFiles('**/package-lock.json') }} - restore-keys: | - ${{ runner.os }}-${{ github.job }}- - - run: mkdir interop - - run: | - npm init -y - npm install ipfs@^0.66.0 - npm install kubo-rpc-client@^3.0.1 - npm install ipfs-interop@^10.0.1 + key: ${{ runner.os }}-${{ github.job }}-${{ matrix.repo-to-test-against }}-${{ hashFiles('**/package-lock.json') }} + restore-keys: ${{ runner.os }}-${{ github.job }}-${{ matrix.repo-to-test-against }}- + - run: sudo apt update + - run: sudo apt install -y libxkbcommon0 libxdamage1 libgbm1 libpango-1.0-0 libcairo2 # dependencies for playwright + - uses: actions/checkout@v3 + with: + repository: ipfs/${{ matrix.repo-to-test-against }} + fetch-depth: 0 + path: interop + - name: Checkout latest tag + run: | + exit 0 # temporary while theses pull requests are released: + # https://github.com/ipfs/helia/pull/200 + # https://github.com/ipfs/helia-unixfs/pull/68 + # https://github.com/ipfs/helia-ipns/pull/72 + export TAG="$(git describe --tags --abbrev=0)" + echo "Running tests against: $TAG" + git checkout "$TAG" working-directory: interop - # Run the interop tests while ignoring the js-js interop test cases - - run: npx ipfs-interop -- -t node --grep '^(?!.*(js\d? -> js\d?|js-js-js|js-rv\d?-js))' --parallel + - run: npm install + working-directory: interop + - run: npm run build + working-directory: interop + - run: npm install + working-directory: interop/packages/interop + - run: npm install --ignore-scripts --save "ipfs/npm-go-ipfs#4441b8a60f1cfee3035a9e4bb824dfcca08e9b01" # temporary while https://github.com/ipfs/npm-go-ipfs/pull/62 is being bubbled + working-directory: interop/packages/interop + - run: npm test + working-directory: interop/packages/interop env: - LIBP2P_TCP_REUSEPORT: false - LIBP2P_ALLOW_WEAK_RSA_KEYS: 1 - IPFS_GO_EXEC: ${{ github.workspace }}/cmd/ipfs/ipfs - working-directory: interop + KUBO_BINARY: ${{ github.workspace }}/cmd/ipfs/ipfs go-ipfs-api: needs: [interop-prep] runs-on: ubuntu-latest diff --git a/docs/RELEASE_ISSUE_TEMPLATE.md b/docs/RELEASE_ISSUE_TEMPLATE.md index d3f8e1d7f..0b10ea8ae 100644 --- a/docs/RELEASE_ISSUE_TEMPLATE.md +++ b/docs/RELEASE_ISSUE_TEMPLATE.md @@ -174,12 +174,6 @@ This section covers tasks to be done during each release. - use `vX.Y.Z(-RCN)` as the Kubo image version - [ ] wait for the [e2e](https://github.com/ipfs/ipfs-companion/actions/workflows/e2e.yml) workflow run to finish
-- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Update Kubo in [interop](https://github.com/ipfs/interop)
using `./kuboreleaser release --version vX.Y.Z(-rcN) update-interop` or ... - - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) check out [ipfs/interop](https://github.com/ipfs/interop) - - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) run `npm install` - - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) create a PR which updates `package.json` and `package-lock.json` - - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) merge the PR -
- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Update Kubo in [ipfs-desktop](https://github.com/ipfs/ipfs-desktop)
using `./kuboreleaser release --version vX.Y.Z(-rcN) update-ipfs-desktop` or ... - [ ] check out [ipfs/ipfs-desktop](https://github.com/ipfs/ipfs-desktop) - [ ] run `npm install` From 7977f26e862449f47d313c2cb1d2977f227638d7 Mon Sep 17 00:00:00 2001 From: Laurent Senta Date: Wed, 2 Aug 2023 19:15:27 +0200 Subject: [PATCH 0797/1212] chore: remove sharness tests ported to conformance testing (#9999) * test(t0112): drop test ported to conformance * test(t0113): drop test ported to conformance * test(t0114): drop test ported to conformance * test(t0114): drop test ported to conformance * test(t0115): drop test ported to conformance * test(t0122): drop test ported to conformance * test(t0123): drop test ported to conformance * test(t0117): drop test ported to conformance * test(t0124): drop test ported to conformance * test(t0114): simplify tests * test(t0112): drop test ported to conformance * test(t0116): drop test ported to conformance * t0114: restore tests flagged by lidel * t0112: restore * t0116: restore dirindex check * t0109: restore file * t0115: restore full file * t0114: restored rest of file * fix: kill the iptb cluster --- test/sharness/t0026-id.sh | 2 + test/sharness/t0113-gateway-symlink.sh | 33 -- test/sharness/t0113-gateway-symlink/README.md | 17 - .../t0113-gateway-symlink/testfiles.car | Bin 282 -> 0 bytes test/sharness/t0114-gateway-subdomains.sh | 28 +- test/sharness/t0116-gateway-cache.sh | 214 ---------- test/sharness/t0116-gateway-cache/README.md | 39 -- .../sharness/t0116-gateway-cache/fixtures.car | Bin 468 -> 0 bytes ...p32iwm9pdt9nq3y5rpn3ln9j12zfhe.ipns-record | Bin 394 -> 0 bytes test/sharness/t0117-gateway-block.sh | 90 ----- test/sharness/t0117-gateway-block/README.md | 21 - .../sharness/t0117-gateway-block/fixtures.car | Bin 309 -> 0 bytes test/sharness/t0122-gateway-tar.sh | 85 ---- test/sharness/t0122-gateway-tar/README.md | 37 -- test/sharness/t0122-gateway-tar/fixtures.car | Bin 1053 -> 0 bytes .../t0122-gateway-tar/inside-root.car | Bin 383 -> 0 bytes .../t0122-gateway-tar/outside-root.car | Bin 249 -> 0 bytes test/sharness/t0123-gateway-json-cbor.sh | 379 ------------------ .../t0123-gateway-json-cbor/README.md | 66 --- .../dag-cbor-traversal.car | Bin 318 -> 0 bytes .../dag-json-traversal.car | Bin 406 -> 0 bytes .../t0123-gateway-json-cbor/dag-pb.car | Bin 392 -> 0 bytes .../t0123-gateway-json-cbor/dag-pb.json | 23 -- .../t0123-gateway-json-cbor/fixtures.car | Bin 1179 -> 0 bytes ...xckoqzwqeqwudfr74kfd11zcyk3b7l.ipns-record | Bin 394 -> 0 bytes ...e2z4pwgp15pgv3ho1azvidttzh8yy2.ipns-record | Bin 398 -> 0 bytes test/sharness/t0124-gateway-ipns-record.sh | 58 --- .../t0124-gateway-ipns-record/README.md | 27 -- .../t0124-gateway-ipns-record/fixtures.car | Bin 107 -> 0 bytes ...i88nsady6qgd1dhjcyfsaqmpp143ab.ipns-record | Bin 392 -> 0 bytes 30 files changed, 29 insertions(+), 1090 deletions(-) delete mode 100755 test/sharness/t0113-gateway-symlink.sh delete mode 100644 test/sharness/t0113-gateway-symlink/README.md delete mode 100644 test/sharness/t0113-gateway-symlink/testfiles.car mode change 100755 => 100644 test/sharness/t0116-gateway-cache.sh delete mode 100644 test/sharness/t0116-gateway-cache/README.md delete mode 100644 test/sharness/t0116-gateway-cache/fixtures.car delete mode 100644 test/sharness/t0116-gateway-cache/k51qzi5uqu5dlxdsdu5fpuu7h69wu4ohp32iwm9pdt9nq3y5rpn3ln9j12zfhe.ipns-record delete mode 100755 test/sharness/t0117-gateway-block.sh delete mode 100644 test/sharness/t0117-gateway-block/README.md delete mode 100644 test/sharness/t0117-gateway-block/fixtures.car delete mode 100755 test/sharness/t0122-gateway-tar.sh delete mode 100644 test/sharness/t0122-gateway-tar/README.md delete mode 100644 test/sharness/t0122-gateway-tar/fixtures.car delete mode 100644 test/sharness/t0122-gateway-tar/inside-root.car delete mode 100644 test/sharness/t0122-gateway-tar/outside-root.car delete mode 100755 test/sharness/t0123-gateway-json-cbor.sh delete mode 100644 test/sharness/t0123-gateway-json-cbor/README.md delete mode 100644 test/sharness/t0123-gateway-json-cbor/dag-cbor-traversal.car delete mode 100644 test/sharness/t0123-gateway-json-cbor/dag-json-traversal.car delete mode 100644 test/sharness/t0123-gateway-json-cbor/dag-pb.car delete mode 100644 test/sharness/t0123-gateway-json-cbor/dag-pb.json delete mode 100644 test/sharness/t0123-gateway-json-cbor/fixtures.car delete mode 100644 test/sharness/t0123-gateway-json-cbor/k51qzi5uqu5dghjous0agrwavl8vzl64xckoqzwqeqwudfr74kfd11zcyk3b7l.ipns-record delete mode 100644 test/sharness/t0123-gateway-json-cbor/k51qzi5uqu5dhjghbwdvbo6mi40htrq6e2z4pwgp15pgv3ho1azvidttzh8yy2.ipns-record delete mode 100755 test/sharness/t0124-gateway-ipns-record.sh delete mode 100644 test/sharness/t0124-gateway-ipns-record/README.md delete mode 100644 test/sharness/t0124-gateway-ipns-record/fixtures.car delete mode 100644 test/sharness/t0124-gateway-ipns-record/k51qzi5uqu5dh71qgwangrt6r0nd4094i88nsady6qgd1dhjcyfsaqmpp143ab.ipns-record diff --git a/test/sharness/t0026-id.sh b/test/sharness/t0026-id.sh index 5ae5f5006..d4248c562 100755 --- a/test/sharness/t0026-id.sh +++ b/test/sharness/t0026-id.sh @@ -61,6 +61,8 @@ test_expect_success "checking AgentVersion with suffix (fetched via libp2p ident ipfsi 1 id "$(ipfsi 0 config Identity.PeerID)" -f "\n" > actual-libp2p-identify-agent-version && test_cmp expected-identify-agent-version actual-libp2p-identify-agent-version ' +iptb stop + test_kill_ipfs_daemon diff --git a/test/sharness/t0113-gateway-symlink.sh b/test/sharness/t0113-gateway-symlink.sh deleted file mode 100755 index 2cb4f3195..000000000 --- a/test/sharness/t0113-gateway-symlink.sh +++ /dev/null @@ -1,33 +0,0 @@ -#!/usr/bin/env bash -# -# Copyright (c) Protocol Labs - -test_description="Test symlink support on the HTTP gateway" - -. lib/test-lib.sh - -test_init_ipfs -test_launch_ipfs_daemon - -# Import test case -# See the static fixtures in ./t0113-gateway-symlink/ -test_expect_success "Add the test directory with symlinks" ' - ipfs dag import --pin-roots ../t0113-gateway-symlink/testfiles.car -' -ROOT_DIR_CID=QmWvY6FaqFMS89YAQ9NAPjVP4WZKA1qbHbicc9HeSKQTgt # ./testfiles/ - -test_expect_success "Test the directory listing" ' - curl "$GWAY_ADDR/ipfs/$ROOT_DIR_CID/" > list_response && - test_should_contain ">foo<" list_response && - test_should_contain ">bar<" list_response -' - -test_expect_success "Test the symlink" ' - curl "$GWAY_ADDR/ipfs/$ROOT_DIR_CID/bar" > bar_actual && - echo -n "foo" > bar_expected && - test_cmp bar_expected bar_actual -' - -test_kill_ipfs_daemon - -test_done diff --git a/test/sharness/t0113-gateway-symlink/README.md b/test/sharness/t0113-gateway-symlink/README.md deleted file mode 100644 index 31a257bdd..000000000 --- a/test/sharness/t0113-gateway-symlink/README.md +++ /dev/null @@ -1,17 +0,0 @@ -# Dataset description/sources - -- testfiles.car - - raw CARv1 - -generated with: - -```sh -# using ipfs version 0.18.1 -mkdir testfiles && -echo "content" > testfiles/foo && -ln -s foo testfiles/bar && -ROOT_DIR_CID=$(ipfs add -Qr testfiles) && -ipfs dag export $ROOT_DIR_CID > testfiles.car - -# ROOT_DIR_CID=QmWvY6FaqFMS89YAQ9NAPjVP4WZKA1qbHbicc9HeSKQTgt -``` diff --git a/test/sharness/t0113-gateway-symlink/testfiles.car b/test/sharness/t0113-gateway-symlink/testfiles.car deleted file mode 100644 index 88e5825f3029ceb158138812c946825544704d26..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 282 zcmcCmlvG!RGgWg$JoF~Sh0{cmy(cz`^^ncIdY^b8_T#q9k%X>mgtKR@Vd1l;Qez>Zf=ID z2|~NuBOwJsCUfy|FbQ!a=jWBA=9O?sZ~y=yG;7fS diff --git a/test/sharness/t0114-gateway-subdomains.sh b/test/sharness/t0114-gateway-subdomains.sh index 8be102c4f..2596bb492 100755 --- a/test/sharness/t0114-gateway-subdomains.sh +++ b/test/sharness/t0114-gateway-subdomains.sh @@ -162,6 +162,9 @@ test_localhost_gateway_response_should_contain \ "http://localhost:$GWAY_PORT/ipfs/$DIR_CID/" \ "Location: http://$DIR_CID.ipfs.localhost:$GWAY_PORT/" +# Kubo specific end-to-end test +# (independend of gateway-conformance) + # We return human-readable body with HTTP 301 so existing cli scripts that use path-based # gateway are informed to enable following HTTP redirects test_localhost_gateway_response_should_contain \ @@ -169,6 +172,8 @@ test_localhost_gateway_response_should_contain \ "http://localhost:$GWAY_PORT/ipfs/$CIDv1" \ ">Moved Permanently" +# end Kubo specific end-to-end test + test_localhost_gateway_response_should_contain \ "request for localhost/ipfs/{CIDv0} redirects to CIDv1 representation in subdomain" \ "http://localhost:$GWAY_PORT/ipfs/$CIDv0" \ @@ -188,11 +193,16 @@ test_localhost_gateway_response_should_contain \ # /ipns/ +# Kubo specific end-to-end test +# (independend of gateway-conformance) + test_localhost_gateway_response_should_contain \ "request for localhost/ipns/{fqdn} redirects to DNSLink in subdomain" \ "http://localhost:$GWAY_PORT/ipns/en.wikipedia-on-ipfs.org/wiki" \ "Location: http://en.wikipedia-on-ipfs.org.ipns.localhost:$GWAY_PORT/wiki" +# end Kubo specific end-to-end test + # API on localhost subdomain gateway # /api/v0 present on the root hostname @@ -236,6 +246,10 @@ test_localhost_gateway_response_should_contain \ "http://${DIR_CID}.ipfs.localhost:$GWAY_PORT/ipfs/file.txt" \ "I am a txt file" +# Kubo specific end-to-end test +# (independend of gateway-conformance) +# This tests link to parent specific to boxo + relative pathing end-to-end tests specific to Kubo. + # {CID}.ipfs.localhost/sub/dir (Directory Listing) DIR_HOSTNAME="${DIR_CID}.ipfs.localhost:$GWAY_PORT" @@ -255,7 +269,7 @@ test_expect_success "request for deep path resource at {cid}.ipfs.localhost/sub/ curl -s --resolve $DIR_HOSTNAME:127.0.0.1 "http://$DIR_HOSTNAME/ipfs/ipns/bar" > list_response && test_should_contain "text-file-content" list_response ' - +# end Kubo specific end-to-end test # *.ipns.localhost @@ -441,6 +455,10 @@ test_hostname_gateway_response_should_contain \ "http://127.0.0.1:$GWAY_PORT/ipfs/$CIDv1" \ "404 Not Found" +# Kubo specific end-to-end test +# (independend of gateway-conformance) +# HTML specific to Boxo/Kubo, and relative pathing specific to code in Kubo + # {CID}.ipfs.example.com/sub/dir (Directory Listing) DIR_FQDN="${DIR_CID}.ipfs.example.com" @@ -464,6 +482,8 @@ test_expect_success "valid breadcrumb links in the header of directory listing a test_should_contain "/ipfs/${DIR_CID}/ipfs/ipns" list_response ' +# end Kubo specific end-to-end test + test_expect_success "request for deep path resource {cid}.ipfs.example.com/sub/dir/file" ' curl -s -H "Host: $DIR_FQDN" http://127.0.0.1:$GWAY_PORT/ipfs/ipns/bar > list_response && test_should_contain "text-file-content" list_response @@ -855,6 +875,10 @@ test_expect_success "request for http://fake.domain.com/ipfs/{CID} with X-Forwar test_should_contain \"Location: https://$CIDv1.ipfs.example.com/\" response " +# Kubo specific end-to-end test +# (independend of gateway-conformance) +# test cofiguration beign wired up correctly end-to-end + ## ============================================================================ ## Test support for wildcards in gateway config ## ============================================================================ @@ -966,3 +990,5 @@ test_expect_success "clean up ipfs dir" ' ' test_done + +# end Kubo specific end-to-end test \ No newline at end of file diff --git a/test/sharness/t0116-gateway-cache.sh b/test/sharness/t0116-gateway-cache.sh old mode 100755 new mode 100644 index 2c0f2f833..0986ffa41 --- a/test/sharness/t0116-gateway-cache.sh +++ b/test/sharness/t0116-gateway-cache.sh @@ -39,156 +39,6 @@ test_expect_success "Add the test directory" ' ipfs routing put --allow-offline /ipns/${TEST_IPNS_ID} ../t0116-gateway-cache/${TEST_IPNS_ID}.ipns-record ' -# GET /ipfs/ - # unixfs - test_expect_success "GET for /ipfs/ unixfs dir listing succeeds" ' - curl -svX GET "http://127.0.0.1:$GWAY_PORT/ipfs/$ROOT1_CID/root2/root3/" >/dev/null 2>curl_ipfs_dir_listing_output - ' - test_expect_success "GET for /ipfs/ unixfs dir with index.html succeeds" ' - curl -svX GET "http://127.0.0.1:$GWAY_PORT/ipfs/$ROOT1_CID/root2/root3/root4/" >/dev/null 2>curl_ipfs_dir_index.html_output - ' - test_expect_success "GET for /ipfs/ unixfs file succeeds" ' - curl -svX GET "http://127.0.0.1:$GWAY_PORT/ipfs/$ROOT1_CID/root2/root3/root4/index.html" >/dev/null 2>curl_ipfs_file_output - ' - # unixfs dir as dag-json - test_expect_success "GET for /ipfs/ unixfs dir as DAG-JSON succeeds" ' - curl -svX GET "http://127.0.0.1:$GWAY_PORT/ipfs/$ROOT1_CID/root2/root3/root4/?format=dag-json" >/dev/null 2>curl_ipfs_dir_dag-json_output && - curl -svX GET "http://127.0.0.1:$GWAY_PORT/ipfs/$ROOT1_CID/root2/root3/root4/?format=json" >/dev/null 2>curl_ipfs_dir_json_output - ' -# GET /ipns/ - # unixfs - test_expect_success "GET for /ipns/ unixfs dir listing succeeds" ' - curl -svX GET "http://127.0.0.1:$GWAY_PORT/ipns/$TEST_IPNS_ID/root2/root3/" >/dev/null 2>curl_ipns_dir_listing_output - ' - test_expect_success "GET for /ipns/ unixfs dir with index.html succeeds" ' - curl -svX GET "http://127.0.0.1:$GWAY_PORT/ipns/$TEST_IPNS_ID/root2/root3/root4/" >/dev/null 2>curl_ipns_dir_index.html_output - ' - test_expect_success "GET for /ipns/ unixfs file succeeds" ' - curl -svX GET "http://127.0.0.1:$GWAY_PORT/ipns/$TEST_IPNS_ID/root2/root3/root4/index.html" >/dev/null 2>curl_ipns_file_output - ' - # unixfs dir as dag-json - test_expect_success "GET for /ipns/ unixfs dir as DAG-JSON succeeds" ' - curl -svX GET "http://127.0.0.1:$GWAY_PORT/ipns/$TEST_IPNS_ID/root2/root3/root4/?format=dag-json" >/dev/null 2>curl_ipns_dir_dag-json_output && - curl -svX GET "http://127.0.0.1:$GWAY_PORT/ipns/$TEST_IPNS_ID/root2/root3/root4/?format=json" >/dev/null 2>curl_ipns_dir_json_output - ' - -# Cache-Control - -# Cache-Control: immutable /ipfs/ file - test_expect_success "GET /ipfs/ unixfs file has expected Cache-Control" ' - test_should_contain "< Cache-Control: public, max-age=29030400, immutable" curl_ipfs_file_output - ' -# Cache-Control: generated /ipfs/dir/ (listing) - # TODO: test_should_contain "< Cache-Control: public, max-age=TBD" curl_ipfs_dir_listing_output - test_expect_success "GET /ipfs/ unixfs dir listing has no Cache-Control" ' - test_should_not_contain "< Cache-Control" curl_ipns_dir_listing_output - ' -# Cache-Control: immutable /ipfs/dir/ (index.html) - test_expect_success "GET /ipfs/ unixfs dir with index.html has expected Cache-Control" ' - test_should_contain "< Cache-Control: public, max-age=29030400, immutable" curl_ipfs_dir_index.html_output - ' -# Cache-Control: immutable /ipfs/ unixfs dir as dag-json - test_expect_success "GET /ipfs/ dag-json has expected Cache-Control" ' - test_should_contain "< Cache-Control: public, max-age=29030400, immutable" curl_ipfs_dir_dag-json_output - ' -# Cache-Control: immutable /ipfs/ unixfs dir as json - test_expect_success "GET /ipfs/ unixfs dir as json has expected Cache-Control" ' - test_should_contain "< Cache-Control: public, max-age=29030400, immutable" curl_ipfs_dir_json_output - ' -# Cache-Control: mutable /ipns/ file - test_expect_success "GET /ipns/ unixfs file has no Cache-Control" ' - test_should_not_contain "< Cache-Control" curl_ipns_file_output - ' -# Cache-Control: mutable /ipns/dir/ (generated listing) - test_expect_success "GET /ipns/ unixfs dir listing has no Cache-Control" ' - test_should_not_contain "< Cache-Control" curl_ipns_dir_listing_output - ' -# Cache-Control: mutable /ipns/dir/ (index.html) - test_expect_success "GET /ipns/ unixfs dir with index.html has no Cache-Control" ' - test_should_not_contain "< Cache-Control" curl_ipns_dir_index.html_output - ' -# Cache-Control: mutable /ipns/dir/ as dag-json - test_expect_success "GET /ipns/ unixfs dir as dag-json has no Cache-Control" ' - test_should_not_contain "< Cache-Control" curl_ipns_dir_dag-json_output - ' -# Cache-Control: mutable /ipns/dir/ as json - test_expect_success "GET /ipns/ unixfs dir as json has no Cache-Control" ' - test_should_not_contain "< Cache-Control" curl_ipns_dir_json_output - ' - -# Cache-Control: only-if-cached - test_expect_success "HEAD for /ipfs/ with only-if-cached succeeds when in local datastore" ' - curl -sv -I -H "Cache-Control: only-if-cached" "http://127.0.0.1:$GWAY_PORT/ipfs/$ROOT1_CID/root2/root3/root4/index.html" > curl_onlyifcached_postitive_head 2>&1 && - cat curl_onlyifcached_postitive_head && - grep "< HTTP/1.1 200 OK" curl_onlyifcached_postitive_head - ' - test_expect_success "HEAD for /ipfs/ with only-if-cached fails when not in local datastore" ' - curl -sv -I -H "Cache-Control: only-if-cached" "http://127.0.0.1:$GWAY_PORT/ipfs/$(date | ipfs add --only-hash -Q)" > curl_onlyifcached_negative_head 2>&1 && - cat curl_onlyifcached_negative_head && - grep "< HTTP/1.1 412 Precondition Failed" curl_onlyifcached_negative_head - ' - test_expect_success "GET for /ipfs/ with only-if-cached succeeds when in local datastore" ' - curl -svX GET -H "Cache-Control: only-if-cached" "http://127.0.0.1:$GWAY_PORT/ipfs/$ROOT1_CID/root2/root3/root4/index.html" >/dev/null 2>curl_onlyifcached_postitive_out && - cat curl_onlyifcached_postitive_out && - grep "< HTTP/1.1 200 OK" curl_onlyifcached_postitive_out - ' - test_expect_success "GET for /ipfs/ with only-if-cached fails when not in local datastore" ' - curl -svX GET -H "Cache-Control: only-if-cached" "http://127.0.0.1:$GWAY_PORT/ipfs/$(date | ipfs add --only-hash -Q)" >/dev/null 2>curl_onlyifcached_negative_out && - cat curl_onlyifcached_negative_out && - grep "< HTTP/1.1 412 Precondition Failed" curl_onlyifcached_negative_out - ' - -# X-Ipfs-Path - - ## dir generated listing - test_expect_success "GET /ipfs/ dir listing response has original content path in X-Ipfs-Path" ' - test_should_contain "< X-Ipfs-Path: /ipfs/$ROOT1_CID/root2/root3" curl_ipfs_dir_listing_output - ' - test_expect_success "GET /ipns/ dir listing response has original content path in X-Ipfs-Path" ' - test_should_contain "< X-Ipfs-Path: /ipns/$TEST_IPNS_ID/root2/root3" curl_ipns_dir_listing_output - ' - - ## dir static index.html - test_expect_success "GET /ipfs/ dir index.html response has original content path in X-Ipfs-Path" ' - test_should_contain "< X-Ipfs-Path: /ipfs/$ROOT1_CID/root2/root3/root4/" curl_ipfs_dir_index.html_output - ' - test_expect_success "GET /ipns/ dir index.html response has original content path in X-Ipfs-Path" ' - test_should_contain "< X-Ipfs-Path: /ipns/$TEST_IPNS_ID/root2/root3/root4/" curl_ipns_dir_index.html_output - ' - - # file - test_expect_success "GET /ipfs/ file response has original content path in X-Ipfs-Path" ' - test_should_contain "< X-Ipfs-Path: /ipfs/$ROOT1_CID/root2/root3/root4/index.html" curl_ipfs_file_output - ' - test_expect_success "GET /ipns/ file response has original content path in X-Ipfs-Path" ' - test_should_contain "< X-Ipfs-Path: /ipns/$TEST_IPNS_ID/root2/root3/root4/index.html" curl_ipns_file_output - ' - -# X-Ipfs-Roots - - ## dir generated listing - test_expect_success "GET /ipfs/ dir listing response has logical CID roots in X-Ipfs-Roots" ' - test_should_contain "< X-Ipfs-Roots: ${ROOT1_CID},${ROOT2_CID},${ROOT3_CID}" curl_ipfs_dir_listing_output - ' - test_expect_success "GET /ipns/ dir listing response has logical CID roots in X-Ipfs-Roots" ' - test_should_contain "< X-Ipfs-Roots: ${ROOT1_CID},${ROOT2_CID},${ROOT3_CID}" curl_ipns_dir_listing_output - ' - - ## dir static index.html - test_expect_success "GET /ipfs/ dir index.html response has logical CID roots in X-Ipfs-Roots" ' - test_should_contain "< X-Ipfs-Roots: ${ROOT1_CID},${ROOT2_CID},${ROOT3_CID},${ROOT4_CID}" curl_ipfs_dir_index.html_output - ' - test_expect_success "GET /ipns/ dir index.html response has logical CID roots in X-Ipfs-Roots" ' - test_should_contain "< X-Ipfs-Roots: ${ROOT1_CID},${ROOT2_CID},${ROOT3_CID},${ROOT4_CID}" curl_ipns_dir_index.html_output - ' - - ## file - test_expect_success "GET /ipfs/ file response has logical CID roots in X-Ipfs-Roots" ' - test_should_contain "< X-Ipfs-Roots: ${ROOT1_CID},${ROOT2_CID},${ROOT3_CID},${ROOT4_CID},${FILE_CID}" curl_ipfs_file_output - ' - test_expect_success "GET /ipns/ file response has logical CID roots in X-Ipfs-Roots" ' - test_should_contain "< X-Ipfs-Roots: ${ROOT1_CID},${ROOT2_CID},${ROOT3_CID},${ROOT4_CID},${FILE_CID}" curl_ipns_file_output - ' # Etag @@ -202,70 +52,6 @@ test_expect_success "Add the test directory" ' grep -E "< Etag: \"DirIndex-.+_CID-${ROOT3_CID}\"" curl_ipns_dir_listing_output ' - ## dir static index.html should use CID of the index.html file for improved HTTP caching - test_expect_success "GET /ipfs/ dir index.html response has dir CID as Etag" ' - test_should_contain "< Etag: \"${ROOT4_CID}\"" curl_ipfs_dir_index.html_output - ' - test_expect_success "GET /ipns/ dir index.html response has dir CID as Etag" ' - test_should_contain "< Etag: \"${ROOT4_CID}\"" curl_ipns_dir_index.html_output - ' - - ## file - test_expect_success "GET /ipfs/ response has CID as Etag for a file" ' - test_should_contain "< Etag: \"${FILE_CID}\"" curl_ipfs_file_output - ' - test_expect_success "GET /ipns/ response has CID as Etag for a file" ' - test_should_contain "< Etag: \"${FILE_CID}\"" curl_ipns_file_output - ' - -# If-None-Match (return 304 Not Modified when client sends matching Etag they already have) - - test_expect_success "GET for /ipfs/ file with matching Etag in If-None-Match returns 304 Not Modified" ' - curl -svX GET -H "If-None-Match: \"$FILE_CID\"" "http://127.0.0.1:$GWAY_PORT/ipfs/$ROOT1_CID/root2/root3/root4/index.html" >/dev/null 2>curl_output && - test_should_contain "304 Not Modified" curl_output - ' - - test_expect_success "GET for /ipfs/ dir with index.html file with matching Etag in If-None-Match returns 304 Not Modified" ' - curl -svX GET -H "If-None-Match: \"$ROOT4_CID\"" "http://127.0.0.1:$GWAY_PORT/ipfs/$ROOT1_CID/root2/root3/root4/" >/dev/null 2>curl_output && - test_should_contain "304 Not Modified" curl_output - ' - - test_expect_success "GET for /ipfs/ file with matching third Etag in If-None-Match returns 304 Not Modified" ' - curl -svX GET -H "If-None-Match: \"fakeEtag1\", \"fakeEtag2\", \"$FILE_CID\"" "http://127.0.0.1:$GWAY_PORT/ipfs/$ROOT1_CID/root2/root3/root4/index.html" >/dev/null 2>curl_output && - test_should_contain "304 Not Modified" curl_output - ' - - test_expect_success "GET for /ipfs/ file with matching weak Etag in If-None-Match returns 304 Not Modified" ' - curl -svX GET -H "If-None-Match: W/\"$FILE_CID\"" "http://127.0.0.1:$GWAY_PORT/ipfs/$ROOT1_CID/root2/root3/root4/index.html" >/dev/null 2>curl_output && - test_should_contain "304 Not Modified" curl_output - ' - - test_expect_success "GET for /ipfs/ file with wildcard Etag in If-None-Match returns 304 Not Modified" ' - curl -svX GET -H "If-None-Match: *" "http://127.0.0.1:$GWAY_PORT/ipfs/$ROOT1_CID/root2/root3/root4/index.html" >/dev/null 2>curl_output && - test_should_contain "304 Not Modified" curl_output - ' - - test_expect_success "GET for /ipns/ file with matching Etag in If-None-Match returns 304 Not Modified" ' - curl -svX GET -H "If-None-Match: \"$FILE_CID\"" "http://127.0.0.1:$GWAY_PORT/ipns/$TEST_IPNS_ID/root2/root3/root4/index.html" >/dev/null 2>curl_output && - test_should_contain "304 Not Modified" curl_output - ' - - test_expect_success "GET for /ipfs/ dir listing with matching weak Etag in If-None-Match returns 304 Not Modified" ' - curl -svX GET -H "If-None-Match: W/\"$ROOT3_CID\"" "http://127.0.0.1:$GWAY_PORT/ipfs/$ROOT1_CID/root2/root3/" >/dev/null 2>curl_output && - test_should_contain "304 Not Modified" curl_output - ' - - # DirIndex etag is based on xxhash(./assets/dir-index-html), so we need to fetch it dynamically - test_expect_success "GET for /ipfs/ dir listing with matching strong Etag in If-None-Match returns 304 Not Modified" ' - curl -Is "http://127.0.0.1:$GWAY_PORT/ipfs/$ROOT1_CID/root2/root3/"| grep -i Etag | cut -f2- -d: | tr -d "[:space:]\"" > dir_index_etag && - curl -svX GET -H "If-None-Match: \"$(/dev/null 2>curl_output && - test_should_contain "304 Not Modified" curl_output - ' - test_expect_success "GET for /ipfs/ dir listing with matching weak Etag in If-None-Match returns 304 Not Modified" ' - curl -Is "http://127.0.0.1:$GWAY_PORT/ipfs/$ROOT1_CID/root2/root3/"| grep -i Etag | cut -f2- -d: | tr -d "[:space:]\"" > dir_index_etag && - curl -svX GET -H "If-None-Match: W/\"$(/dev/null 2>curl_output && - test_should_contain "304 Not Modified" curl_output - ' test_kill_ipfs_daemon diff --git a/test/sharness/t0116-gateway-cache/README.md b/test/sharness/t0116-gateway-cache/README.md deleted file mode 100644 index 1be92f454..000000000 --- a/test/sharness/t0116-gateway-cache/README.md +++ /dev/null @@ -1,39 +0,0 @@ -# Dataset description/sources - -- fixtures.car - - raw CARv1 - -generated with: - -```sh -# using ipfs version 0.21.0-dev (03a98280e3e642774776cd3d0435ab53e5dfa867) - -mkdir -p root2/root3/root4 && -echo "hello" > root2/root3/root4/index.html && -ROOT1_CID=$(ipfs add -Qrw --cid-version 1 root2) -ROOT2_CID=$(ipfs resolve -r /ipfs/$ROOT1_CID/root2 | cut -d "/" -f3) -ROOT3_CID=$(ipfs resolve -r /ipfs/$ROOT1_CID/root2/root3 | cut -d "/" -f3) -ROOT4_CID=$(ipfs resolve -r /ipfs/$ROOT1_CID/root2/root3/root4 | cut -d "/" -f3) -FILE_CID=$(ipfs resolve -r /ipfs/$ROOT1_CID/root2/root3/root4/index.html | cut -d "/" -f3) - -TEST_IPNS_ID=$(ipfs key gen --ipns-base=base36 --type=ed25519 cache_test_key | head -n1 | tr -d "\n") -# publish a record valid for a 100 years -ipfs name publish --key cache_test_key --allow-offline -Q --ttl=876600h --lifetime=876600h "/ipfs/$ROOT1_CID" -ipfs routing get /ipns/${TEST_IPNS_ID} > ${TEST_IPNS_ID}.ipns-record - -echo ROOT1_CID=${ROOT1_CID} # ./ -echo ROOT2_CID=${ROOT2_CID} # ./root2 -echo ROOT3_CID=${ROOT3_CID} # ./root2/root3 -echo ROOT4_CID=${ROOT4_CID} # ./root2/root3/root4 -echo FILE_CID=${FILE_CID} # ./root2/root3/root4/index.html -echo TEST_IPNS_ID=${TEST_IPNS_ID} - -ipfs dag export ${ROOT1_CID} > ./fixtures.car - -# ROOT1_CID=bafybeib3ffl2teiqdncv3mkz4r23b5ctrwkzrrhctdbne6iboayxuxk5ui # ./ -# ROOT2_CID=bafybeih2w7hjocxjg6g2ku25hvmd53zj7og4txpby3vsusfefw5rrg5sii # ./root2 -# ROOT3_CID=bafybeiawdvhmjcz65x5egzx4iukxc72hg4woks6v6fvgyupiyt3oczk5ja # ./root2/root3 -# ROOT4_CID=bafybeifq2rzpqnqrsdupncmkmhs3ckxxjhuvdcbvydkgvch3ms24k5lo7q # ./root2/root3/root4 -# FILE_CID=bafkreicysg23kiwv34eg2d7qweipxwosdo2py4ldv42nbauguluen5v6am # ./root2/root3/root4/index.html -# TEST_IPNS_ID=k51qzi5uqu5dlxdsdu5fpuu7h69wu4ohp32iwm9pdt9nq3y5rpn3ln9j12zfhe -``` diff --git a/test/sharness/t0116-gateway-cache/fixtures.car b/test/sharness/t0116-gateway-cache/fixtures.car deleted file mode 100644 index 43e570e1d6acb0a03531b47feb540318f5027204..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 468 zcmcColvx?P5~W2SVzij7-;r*+x4)dz{ z2?vnLaUeGn)L{a2bEuF)#Kf&zm9F0B$mRdAQQ-H@OVV5Z6eh1XxzN*OUp4TNzE)w$xALX&dsheDKaunGEFWiD$lMeD#}PM zNlD5}HOoxOPpqsct;jYl%@lIj#Aa`PX!4XzpKmQY)6e$9U7<`kzNU$F%{D)#mwVMZ z{GZ-h%zgj3z3+a9thHt*l@~txHDQw3!_thyQ+_E$H*2s|5P0dSAWyk;;nVFJVQW=5IUpX*UA(aKG3;+eR BnWX># diff --git a/test/sharness/t0117-gateway-block.sh b/test/sharness/t0117-gateway-block.sh deleted file mode 100755 index a4a661bd1..000000000 --- a/test/sharness/t0117-gateway-block.sh +++ /dev/null @@ -1,90 +0,0 @@ -#!/usr/bin/env bash - -test_description="Test HTTP Gateway Raw Block (application/vnd.ipld.raw) Support" - -. lib/test-lib.sh - -test_init_ipfs -test_launch_ipfs_daemon_without_network - -# Import test case -# See the static fixtures in ./t0117-gateway-block/ -test_expect_success "Add the dir test directory" ' - ipfs dag import --pin-roots ../t0117-gateway-block/fixtures.car -' -ROOT_DIR_CID=bafybeie72edlprgtlwwctzljf6gkn2wnlrddqjbkxo3jomh4n7omwblxly # ./ -FILE_CID=bafkreihhpc5y2pqvl5rbe5uuyhqjouybfs3rvlmisccgzue2kkt5zq6upq # ./dir/ascii.txt - -# GET unixfs dir root block and compare it with `ipfs block get` output - - test_expect_success "GET with format=raw param returns a raw block" ' - ipfs block get "/ipfs/$ROOT_DIR_CID/dir" > expected && - curl -sX GET "http://127.0.0.1:$GWAY_PORT/ipfs/$ROOT_DIR_CID/dir?format=raw" -o curl_ipfs_dir_block_param_output && - test_cmp expected curl_ipfs_dir_block_param_output - ' - - test_expect_success "GET for application/vnd.ipld.raw returns a raw block" ' - ipfs block get "/ipfs/$ROOT_DIR_CID/dir" > expected_block && - curl -sX GET -H "Accept: application/vnd.ipld.raw" "http://127.0.0.1:$GWAY_PORT/ipfs/$ROOT_DIR_CID/dir" -o curl_ipfs_dir_block_accept_output && - test_cmp expected_block curl_ipfs_dir_block_accept_output - ' - - test_expect_success "GET for application/vnd.ipld.raw with single range request includes correct bytes" ' - echo -n "application" > expected_file_block_single_range && - curl -sX GET -H "Accept: application/vnd.ipld.raw" -H "Range: bytes=6-16" "http://127.0.0.1:$GWAY_PORT/ipfs/$FILE_CID" -o curl_ipfs_file_block_single_range && - test_cmp expected_file_block_single_range curl_ipfs_file_block_single_range - ' - - test_expect_success "GET for application/vnd.ipld.raw with multiple range request includes correct bytes" ' - curl -sX GET -H "Accept: application/vnd.ipld.raw" -H "Range: bytes=6-16,0-4" "http://127.0.0.1:$GWAY_PORT/ipfs/$FILE_CID" -o curl_ipfs_file_block_multiple_range && - test_should_contain "Content-Range: bytes 6-16/31" curl_ipfs_file_block_multiple_range && - test_should_contain "Content-Type: application/vnd.ipld.raw" curl_ipfs_file_block_multiple_range && - test_should_contain "application" curl_ipfs_file_block_multiple_range && - test_should_contain "Content-Range: bytes 0-4/31" curl_ipfs_file_block_multiple_range && - test_should_contain "hello" curl_ipfs_file_block_multiple_range - ' - -# Make sure expected HTTP headers are returned with the block bytes - - test_expect_success "GET response for application/vnd.ipld.raw has expected Content-Type" ' - curl -svX GET -H "Accept: application/vnd.ipld.raw" "http://127.0.0.1:$GWAY_PORT/ipfs/$ROOT_DIR_CID/dir/ascii.txt" >/dev/null 2>curl_output && - test_should_contain "< Content-Type: application/vnd.ipld.raw" curl_output - ' - - test_expect_success "GET response for application/vnd.ipld.raw includes Content-Length" ' - BYTES=$(ipfs block get $FILE_CID | wc --bytes) - test_should_contain "< Content-Length: $BYTES" curl_output - ' - - test_expect_success "GET response for application/vnd.ipld.raw includes Content-Disposition" ' - test_should_contain "< Content-Disposition: attachment\; filename=\"${FILE_CID}.bin\"" curl_output - ' - - test_expect_success "GET response for application/vnd.ipld.raw includes nosniff hint" ' - test_should_contain "< X-Content-Type-Options: nosniff" curl_output - ' - - test_expect_success "GET for application/vnd.ipld.raw with query filename includes Content-Disposition with custom filename" ' - curl -svX GET -H "Accept: application/vnd.ipld.raw" "http://127.0.0.1:$GWAY_PORT/ipfs/$ROOT_DIR_CID/dir/ascii.txt?filename=foobar.bin" >/dev/null 2>curl_output_filename && - test_should_contain "< Content-Disposition: attachment\; filename=\"foobar.bin\"" curl_output_filename - ' - -# Cache control HTTP headers -# (basic checks, detailed behavior is tested in t0116-gateway-cache.sh) - - test_expect_success "GET response for application/vnd.ipld.raw includes Etag" ' - test_should_contain "< Etag: \"${FILE_CID}.raw\"" curl_output - ' - - test_expect_success "GET response for application/vnd.ipld.raw includes X-Ipfs-Path and X-Ipfs-Roots" ' - test_should_contain "< X-Ipfs-Path" curl_output && - test_should_contain "< X-Ipfs-Roots" curl_output - ' - - test_expect_success "GET response for application/vnd.ipld.raw includes Cache-Control" ' - test_should_contain "< Cache-Control: public, max-age=29030400, immutable" curl_output - ' - -test_kill_ipfs_daemon - -test_done diff --git a/test/sharness/t0117-gateway-block/README.md b/test/sharness/t0117-gateway-block/README.md deleted file mode 100644 index 4ce37ae08..000000000 --- a/test/sharness/t0117-gateway-block/README.md +++ /dev/null @@ -1,21 +0,0 @@ -# Dataset description/sources - -- fixtures.car - - raw CARv1 - -generated with: - -```sh -# using ipfs version 0.18.1 -mkdir -p dir && -echo "hello application/vnd.ipld.raw" > dir/ascii.txt && -ROOT_DIR_CID=$(ipfs add -Qrw --cid-version 1 dir) && -FILE_CID=$(ipfs resolve -r /ipfs/$ROOT_DIR_CID/dir/ascii.txt | cut -d "/" -f3) && -ipfs dag export $ROOT_DIR_CID > fixtures.car - -echo ROOT_DIR_CID=${ROOT_DIR_CID} # ./ -echo FILE_CID=${FILE_CID} # ./dir/ascii.txt - -# ROOT_DIR_CID=bafybeie72edlprgtlwwctzljf6gkn2wnlrddqjbkxo3jomh4n7omwblxly # ./ -# FILE_CID=bafkreihhpc5y2pqvl5rbe5uuyhqjouybfs3rvlmisccgzue2kkt5zq6upq # ./dir/ascii.txt -``` diff --git a/test/sharness/t0117-gateway-block/fixtures.car b/test/sharness/t0117-gateway-block/fixtures.car deleted file mode 100644 index 77da1b5542e281eb1c80a4a8763c85bd7424b60b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 309 zcmcColveYNahp`Ifpb-g~vLz*Snd z?RAF`b4q5BLWzWsh6*V>uh`vdCmNq5R5s<{gXzJHI@_hzc1&o=xiBke z`JKa8YJ@lwi<2`m^-3yAB;-M+I}@WTBQ+-{Um>xeASW|9u>|N@{j$6iz087~6uqLv GaxMV9-hqPv diff --git a/test/sharness/t0122-gateway-tar.sh b/test/sharness/t0122-gateway-tar.sh deleted file mode 100755 index 435623547..000000000 --- a/test/sharness/t0122-gateway-tar.sh +++ /dev/null @@ -1,85 +0,0 @@ -#!/usr/bin/env bash - -test_description="Test HTTP Gateway TAR (application/x-tar) Support" - -. lib/test-lib.sh - -test_init_ipfs -test_launch_ipfs_daemon_without_network - -OUTSIDE_ROOT_CID="bafybeicaj7kvxpcv4neaqzwhrqqmdstu4dhrwfpknrgebq6nzcecfucvyu" -INSIDE_ROOT_CID="bafybeibfevfxlvxp5vxobr5oapczpf7resxnleb7tkqmdorc4gl5cdva3y" - -# Import test case -# See the static fixtures in ./t0122-gateway-tar/ -test_expect_success "Add the test directory" ' - ipfs dag import --pin-roots ../t0122-gateway-tar/fixtures.car -' -DIR_CID=bafybeig6ka5mlwkl4subqhaiatalkcleo4jgnr3hqwvpmsqfca27cijp3i # ./rootDir -FILE_CID=bafkreialihlqnf5uwo4byh4n3cmwlntwqzxxs2fg5vanqdi3d7tb2l5xkm # ./rootDir/ą/ę/file-źł.txt -FILE_SIZE=34 - -test_expect_success "GET TAR with format=tar and extract" ' - curl "http://127.0.0.1:$GWAY_PORT/ipfs/$FILE_CID?format=tar" | tar -x -' - -test_expect_success "GET TAR with 'Accept: application/x-tar' and extract" ' - curl -H "Accept: application/x-tar" "http://127.0.0.1:$GWAY_PORT/ipfs/$FILE_CID" | tar -x -' - -test_expect_success "GET TAR with format=tar has expected Content-Type" ' - curl -sD - "http://127.0.0.1:$GWAY_PORT/ipfs/$FILE_CID?format=tar" > curl_output_filename 2>&1 && - test_should_contain "Content-Disposition: attachment;" curl_output_filename && - test_should_contain "Etag: W/\"$FILE_CID.x-tar" curl_output_filename && - test_should_contain "Content-Type: application/x-tar" curl_output_filename -' - -test_expect_success "GET TAR with 'Accept: application/x-tar' has expected Content-Type" ' - curl -sD - -H "Accept: application/x-tar" "http://127.0.0.1:$GWAY_PORT/ipfs/$FILE_CID" > curl_output_filename 2>&1 && - test_should_contain "Content-Disposition: attachment;" curl_output_filename && - test_should_contain "Etag: W/\"$FILE_CID.x-tar" curl_output_filename && - test_should_contain "Content-Type: application/x-tar" curl_output_filename -' - -test_expect_success "GET TAR has expected root file" ' - rm -rf outputDir && mkdir outputDir && - curl "http://127.0.0.1:$GWAY_PORT/ipfs/$FILE_CID?format=tar" | tar -x -C outputDir && - test -f "outputDir/$FILE_CID" && - echo "I am a txt file on path with utf8" > expected && - test_cmp expected outputDir/$FILE_CID -' - -test_expect_success "GET TAR has expected root directory" ' - rm -rf outputDir && mkdir outputDir && - curl "http://127.0.0.1:$GWAY_PORT/ipfs/$DIR_CID?format=tar" | tar -x -C outputDir && - test -d "outputDir/$DIR_CID" && - echo "I am a txt file on path with utf8" > expected && - test_cmp expected outputDir/$DIR_CID/ą/ę/file-źł.txt -' - -test_expect_success "GET TAR with explicit ?filename= succeeds with modified Content-Disposition header" " - curl -fo actual -D actual_headers 'http://127.0.0.1:$GWAY_PORT/ipfs/$DIR_CID?filename=testтест.tar&format=tar' && - grep -F 'Content-Disposition: attachment; filename=\"test____.tar\"; filename*=UTF-8'\'\''test%D1%82%D0%B5%D1%81%D1%82.tar' actual_headers -" - -test_expect_success "Add CARs with relative paths to test with" ' - ipfs dag import --pin-roots ../t0122-gateway-tar/outside-root.car > import_output && - test_should_contain $OUTSIDE_ROOT_CID import_output && - ipfs dag import --pin-roots ../t0122-gateway-tar/inside-root.car > import_output && - test_should_contain $INSIDE_ROOT_CID import_output -' - -test_expect_success "GET TAR with relative paths outside root fails" ' - curl -o - "http://127.0.0.1:$GWAY_PORT/ipfs/$OUTSIDE_ROOT_CID?format=tar" > curl_output_filename && - test_should_contain "relative UnixFS paths outside the root are now allowed" curl_output_filename -' - -test_expect_success "GET TAR with relative paths inside root works" ' - rm -rf outputDir && mkdir outputDir && - curl "http://127.0.0.1:$GWAY_PORT/ipfs/$INSIDE_ROOT_CID?format=tar" | tar -x -C outputDir && - test -f outputDir/$INSIDE_ROOT_CID/foobar/file -' - -test_kill_ipfs_daemon - -test_done diff --git a/test/sharness/t0122-gateway-tar/README.md b/test/sharness/t0122-gateway-tar/README.md deleted file mode 100644 index 8b9311277..000000000 --- a/test/sharness/t0122-gateway-tar/README.md +++ /dev/null @@ -1,37 +0,0 @@ -# Dataset description/sources - -- inside-root.car - -- outside-root.car - -- fixtures.car - - raw CARv1 - -generated with: - -```sh -# ipfs version 0.18.1 - -mkdir -p rootDir/ipfs && -mkdir -p rootDir/ipns && -mkdir -p rootDir/api && -mkdir -p rootDir/ą/ę && -echo "I am a txt file on path with utf8" > rootDir/ą/ę/file-źł.txt && -echo "I am a txt file in confusing /api dir" > rootDir/api/file.txt && -echo "I am a txt file in confusing /ipfs dir" > rootDir/ipfs/file.txt && -echo "I am a txt file in confusing /ipns dir" > rootDir/ipns/file.txt && -DIR_CID=$(ipfs add -Qr --cid-version 1 rootDir) && -FILE_CID=$(ipfs files stat --enc=json /ipfs/$DIR_CID/ą/ę/file-źł.txt | jq -r .Hash) && -FILE_SIZE=$(ipfs files stat --enc=json /ipfs/$DIR_CID/ą/ę/file-źł.txt | jq -r .Size) -echo "$FILE_CID / $FILE_SIZE" - -echo DIR_CID=${DIR_CID} # ./rootDir -echo FILE_CID=${FILE_CID} # ./rootDir/ą/ę/file-źł.txt -echo FILE_SIZE=${FILE_SIZE} - -ipfs dag export ${DIR_CID} > ./fixtures.car - -# DIR_CID=bafybeig6ka5mlwkl4subqhaiatalkcleo4jgnr3hqwvpmsqfca27cijp3i # ./rootDir -# FILE_CID=bafkreialihlqnf5uwo4byh4n3cmwlntwqzxxs2fg5vanqdi3d7tb2l5xkm # ./rootDir/ą/ę/file-źł.txt -# FILE_SIZE=34 -``` diff --git a/test/sharness/t0122-gateway-tar/fixtures.car b/test/sharness/t0122-gateway-tar/fixtures.car deleted file mode 100644 index 71a5603822741f25320438bd70823589120e313c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1053 zcmcColvR$Z!{1TqeSN@tUjjg{Tlgc7mrAdS5w!gPn*17KH6I(#F3Vnld4xzQ6ixRGTe(8O`Zyg zxeAF2KuroD-3pm`3d#9-X{E)PdFcxJz;IJY$t>amyOUtJLEZWM>i;({85gv-W(d_V zKa@*2eN@-d)vWbj%$Z-NzS6vINbXbzxziiuPC}aSyAu>)2!|4kFsMU?&s>>u#q@K) zg=4JD+Ddu%u4<)wm#M_8IM$cG*3(nQFic@T$&fnuIuO3{I&*k2EHJEuD( zXEu8GPP(?~NTtQ!*2R(r|4!eUF1UKJ@frzWikc}A4+_gfkg)`nn?n*5x8rrT>037M zkdg1bF*9{rSzCT(#hs2>E#m S1&JjY3gwwVqO>Hee^xFHkc@K`SV?H{4`bU*@S0~udT5xce(!=Q& z`4-$uFH0>d&dkqaj37p}kRF!`NF7V9N~fsTRp-u?;^j5_^n32ysn~q^+RC22)y!qz zgARrYv8CnbCnXkfF>x?P6Q#irV(`1uv2n9Mx30H1R<)FoX-6hgLt#_gqO@SXiDDIH zM?cOJ;!MdbN=+`wFRFx_O;8WW>`)|0=|$r>CEmpD)2Dq)Vg@=A^_T2|g|+4n`wlZ170U$;sDID9 curl_output 2>&1 && - curl -sD headers_accept -H "Accept: application/json" "http://127.0.0.1:$GWAY_PORT/ipfs/$FILE_JSON_CID" > curl_output_accept 2>&1 && - ipfs cat $FILE_JSON_CID > ipfs_cat_output 2>&1 && - test_should_contain "Content-Type: application/json" headers && - test_should_contain "Content-Type: application/json" headers_accept && - test_cmp ipfs_cat_output curl_output && - test_cmp curl_output curl_output_accept -' - - -## Reading UnixFS (data encoded with dag-pb codec) as DAG-CBOR and DAG-JSON -## (returns representation defined in https://ipld.io/specs/codecs/dag-pb/spec/#logical-format) - -test_dag_pb_conversion () { - name=$1 - format=$2 - disposition=$3 - - test_expect_success "GET UnixFS file as $name with format=dag-$format converts to the expected Content-Type" ' - curl -sD headers "http://127.0.0.1:$GWAY_PORT/ipfs/$FILE_CID?format=dag-$format" > curl_output 2>&1 && - ipfs dag get --output-codec dag-$format $FILE_CID > ipfs_dag_get_output 2>&1 && - test_cmp ipfs_dag_get_output curl_output && - test_should_contain "Content-Type: application/vnd.ipld.dag-$format" headers && - test_should_contain "Content-Disposition: ${disposition}\; filename=\"${FILE_CID}.${format}\"" headers && - test_should_not_contain "Content-Type: application/$format" headers - ' - - test_expect_success "GET UnixFS directory as $name with format=dag-$format converts to the expected Content-Type" ' - curl -sD headers "http://127.0.0.1:$GWAY_PORT/ipfs/$DIR_CID?format=dag-$format" > curl_output 2>&1 && - ipfs dag get --output-codec dag-$format $DIR_CID > ipfs_dag_get_output 2>&1 && - test_cmp ipfs_dag_get_output curl_output && - test_should_contain "Content-Type: application/vnd.ipld.dag-$format" headers && - test_should_contain "Content-Disposition: ${disposition}\; filename=\"${DIR_CID}.${format}\"" headers && - test_should_not_contain "Content-Type: application/$format" headers - ' - - test_expect_success "GET UnixFS as $name with 'Accept: application/vnd.ipld.dag-$format' converts to the expected Content-Type" ' - curl -sD - -H "Accept: application/vnd.ipld.dag-$format" "http://127.0.0.1:$GWAY_PORT/ipfs/$FILE_CID" > curl_output 2>&1 && - test_should_contain "Content-Disposition: ${disposition}\; filename=\"${FILE_CID}.${format}\"" curl_output && - test_should_contain "Content-Type: application/vnd.ipld.dag-$format" curl_output && - test_should_not_contain "Content-Type: application/$format" curl_output - ' - - test_expect_success "GET UnixFS as $name with 'Accept: foo, application/vnd.ipld.dag-$format,bar' converts to the expected Content-Type" ' - curl -sD - -H "Accept: foo, application/vnd.ipld.dag-$format,text/plain" "http://127.0.0.1:$GWAY_PORT/ipfs/$FILE_CID" > curl_output 2>&1 && - test_should_contain "Content-Type: application/vnd.ipld.dag-$format" curl_output - ' - - test_expect_success "GET UnixFS with format=$format (not dag-$format) is no-op (no conversion)" ' - curl -sD headers "http://127.0.0.1:$GWAY_PORT/ipfs/$FILE_CID?format=$format" > curl_output 2>&1 && - ipfs cat $FILE_CID > cat_output && - test_cmp cat_output curl_output && - test_should_contain "Content-Type: text/plain" headers && - test_should_not_contain "Content-Type: application/$format" headers && - test_should_not_contain "Content-Type: application/vnd.ipld.dag-$format" headers - ' - - test_expect_success "GET UnixFS with 'Accept: application/$format' (not dag-$format) is no-op (no conversion)" ' - curl -sD headers -H "Accept: application/$format" "http://127.0.0.1:$GWAY_PORT/ipfs/$FILE_CID" > curl_output 2>&1 && - ipfs cat $FILE_CID > cat_output && - test_cmp cat_output curl_output && - test_should_contain "Content-Type: text/plain" headers && - test_should_not_contain "Content-Type: application/$format" headers && - test_should_not_contain "Content-Type: application/vnd.ipld.dag-$format" headers - ' -} - -test_dag_pb_conversion "DAG-JSON" "json" "inline" -test_dag_pb_conversion "DAG-CBOR" "cbor" "attachment" - - -# Requesting CID with plain json (0x0200) and cbor (0x51) codecs -# (note these are not UnixFS, not DAG-* variants, just raw block identified by a CID with a special codec) -test_plain_codec () { - name=$1 - format=$2 - disposition=$3 - - # no explicit format, just codec in CID - test_expect_success "GET $name without Accept or format= has expected $format Content-Type and body as-is" ' - CID=$(echo "{ \"test\": \"plain json\" }" | ipfs dag put --input-codec json --store-codec $format) && - curl -sD headers "http://127.0.0.1:$GWAY_PORT/ipfs/$CID" > curl_output 2>&1 && - ipfs block get $CID > ipfs_block_output 2>&1 && - test_cmp ipfs_block_output curl_output && - test_should_contain "Content-Disposition: ${disposition}\; filename=\"${CID}.${format}\"" headers && - test_should_contain "Content-Type: application/$format" headers - ' - - # explicit format still gives correct output, just codec in CID - test_expect_success "GET $name with ?format= has expected $format Content-Type and body as-is" ' - CID=$(echo "{ \"test\": \"plain json\" }" | ipfs dag put --input-codec json --store-codec $format) && - curl -sD headers "http://127.0.0.1:$GWAY_PORT/ipfs/$CID?format=$format" > curl_output 2>&1 && - ipfs block get $CID > ipfs_block_output 2>&1 && - test_cmp ipfs_block_output curl_output && - test_should_contain "Content-Disposition: ${disposition}\; filename=\"${CID}.${format}\"" headers && - test_should_contain "Content-Type: application/$format" headers - ' - - # explicit format still gives correct output, just codec in CID - test_expect_success "GET $name with Accept has expected $format Content-Type and body as-is" ' - CID=$(echo "{ \"test\": \"plain json\" }" | ipfs dag put --input-codec json --store-codec $format) && - curl -sD headers -H "Accept: application/$format" "http://127.0.0.1:$GWAY_PORT/ipfs/$CID" > curl_output 2>&1 && - ipfs block get $CID > ipfs_block_output 2>&1 && - test_cmp ipfs_block_output curl_output && - test_should_contain "Content-Disposition: ${disposition}\; filename=\"${CID}.${format}\"" headers && - test_should_contain "Content-Type: application/$format" headers - ' - - # explicit dag-* format passed, attempt to parse as dag* variant - ## Note: this works only for simple JSON that can be upgraded to DAG-JSON. - test_expect_success "GET $name with format=dag-$format interprets $format as dag-* variant and produces expected Content-Type and body" ' - CID=$(echo "{ \"test\": \"plain-json-that-can-also-be-dag-json\" }" | ipfs dag put --input-codec json --store-codec $format) && - curl -sD headers "http://127.0.0.1:$GWAY_PORT/ipfs/$CID?format=dag-$format" > curl_output_param 2>&1 && - ipfs dag get --output-codec dag-$format $CID > ipfs_dag_get_output 2>&1 && - test_cmp ipfs_dag_get_output curl_output_param && - test_should_contain "Content-Disposition: ${disposition}\; filename=\"${CID}.${format}\"" headers && - test_should_contain "Content-Type: application/vnd.ipld.dag-$format" headers && - curl -s -H "Accept: application/vnd.ipld.dag-$format" "http://127.0.0.1:$GWAY_PORT/ipfs/$CID" > curl_output_accept 2>&1 && - test_cmp curl_output_param curl_output_accept - ' - -} - -test_plain_codec "plain JSON codec" "json" "inline" -test_plain_codec "plain CBOR codec" "cbor" "attachment" - -## Pathing, traversal over DAG-JSON and DAG-CBOR - -DAG_CBOR_TRAVERSAL_CID="bafyreibs4utpgbn7uqegmd2goqz4bkyflre2ek2iwv743fhvylwi4zeeim" -DAG_JSON_TRAVERSAL_CID="baguqeeram5ujjqrwheyaty3w5gdsmoz6vittchvhk723jjqxk7hakxkd47xq" -DAG_PB_CID="bafybeiegxwlgmoh2cny7qlolykdf7aq7g6dlommarldrbm7c4hbckhfcke" - -test_expect_success "Add CARs for path traversal and DAG-PB representation tests" ' - ipfs dag import --pin-roots ../t0123-gateway-json-cbor/dag-cbor-traversal.car > import_output && - test_should_contain $DAG_CBOR_TRAVERSAL_CID import_output && - ipfs dag import --pin-roots ../t0123-gateway-json-cbor/dag-json-traversal.car > import_output && - test_should_contain $DAG_JSON_TRAVERSAL_CID import_output && - ipfs dag import --pin-roots ../t0123-gateway-json-cbor/dag-pb.car > import_output && - test_should_contain $DAG_PB_CID import_output -' - -IPNS_ID_DAG_JSON=k51qzi5uqu5dhjghbwdvbo6mi40htrq6e2z4pwgp15pgv3ho1azvidttzh8yy2 -IPNS_ID_DAG_CBOR=k51qzi5uqu5dghjous0agrwavl8vzl64xckoqzwqeqwudfr74kfd11zcyk3b7l - -test_expect_success "Add ipns records for path traversal and DAG-PB representation tests" ' - ipfs routing put --allow-offline /ipns/${IPNS_ID_DAG_JSON} ../t0123-gateway-json-cbor/${IPNS_ID_DAG_JSON}.ipns-record && - ipfs routing put --allow-offline /ipns/${IPNS_ID_DAG_CBOR} ../t0123-gateway-json-cbor/${IPNS_ID_DAG_CBOR}.ipns-record -' - -test_expect_success "GET DAG-JSON traversal returns 501 if there is path remainder" ' - curl -sD - "http://127.0.0.1:$GWAY_PORT/ipfs/$DAG_JSON_TRAVERSAL_CID/foo?format=dag-json" > curl_output 2>&1 && - test_should_contain "501 Not Implemented" curl_output && - test_should_contain "reading IPLD Kinds other than Links (CBOR Tag 42) is not implemented" curl_output -' - -test_expect_success "GET DAG-JSON traverses multiple links" ' - curl -s "http://127.0.0.1:$GWAY_PORT/ipfs/$DAG_JSON_TRAVERSAL_CID/foo/link/bar?format=dag-json" > curl_output 2>&1 && - jq --sort-keys . curl_output > actual && - echo "{ \"hello\": \"this is not a link\" }" | jq --sort-keys . > expected && - test_cmp expected actual -' - -test_expect_success "GET DAG-CBOR traversal returns 501 if there is path remainder" ' - curl -sD - "http://127.0.0.1:$GWAY_PORT/ipfs/$DAG_CBOR_TRAVERSAL_CID/foo?format=dag-cbor" > curl_output 2>&1 && - test_should_contain "501 Not Implemented" curl_output && - test_should_contain "reading IPLD Kinds other than Links (CBOR Tag 42) is not implemented" curl_output -' - -test_expect_success "GET DAG-CBOR traverses multiple links" ' - curl -s "http://127.0.0.1:$GWAY_PORT/ipfs/$DAG_CBOR_TRAVERSAL_CID/foo/link/bar?format=dag-json" > curl_output 2>&1 && - jq --sort-keys . curl_output > actual && - echo "{ \"hello\": \"this is not a link\" }" | jq --sort-keys . > expected && - test_cmp expected actual -' - -## NATIVE TESTS for DAG-JSON (0x0129) and DAG-CBOR (0x71): -## DAG- regression tests for core behaviors when native DAG-(CBOR|JSON) is requested - -test_native_dag () { - name=$1 - format=$2 - disposition=$3 - CID=$4 - IPNS_ID=$5 - - # GET without explicit format and Accept: text/html returns raw block - - test_expect_success "GET $name from /ipfs without explicit format returns the same payload as the raw block" ' - ipfs block get "/ipfs/$CID" > expected && - curl -sX GET "http://127.0.0.1:$GWAY_PORT/ipfs/$CID" -o curl_output && - test_cmp expected curl_output - ' - - # GET dag-cbor block via Accept and ?format and ensure both are the same as `ipfs block get` output - - test_expect_success "GET $name from /ipfs with format=dag-$format returns the same payload as the raw block" ' - ipfs block get "/ipfs/$CID" > expected && - curl -sX GET "http://127.0.0.1:$GWAY_PORT/ipfs/$CID?format=dag-$format" -o curl_ipfs_dag_param_output && - test_cmp expected curl_ipfs_dag_param_output - ' - - test_expect_success "GET $name from /ipfs for application/$format returns the same payload as format=dag-$format" ' - curl -sX GET "http://127.0.0.1:$GWAY_PORT/ipfs/$CID?format=dag-$format" -o expected && - curl -sX GET "http://127.0.0.1:$GWAY_PORT/ipfs/$CID?format=$format" -o plain_output && - test_cmp expected plain_output - ' - - test_expect_success "GET $name from /ipfs with application/vnd.ipld.dag-$format returns the same payload as the raw block" ' - ipfs block get "/ipfs/$CID" > expected_block && - curl -sX GET -H "Accept: application/vnd.ipld.dag-$format" "http://127.0.0.1:$GWAY_PORT/ipfs/$CID" -o curl_ipfs_dag_block_accept_output && - test_cmp expected_block curl_ipfs_dag_block_accept_output - ' - - # Make sure DAG-* can be requested as plain JSON or CBOR and response has plain Content-Type for interop purposes - - test_expect_success "GET $name with format=$format returns same payload as format=dag-$format but with plain Content-Type" ' - curl -s "http://127.0.0.1:$GWAY_PORT/ipfs/$CID?format=dag-$format" -o expected && - curl -sD plain_headers "http://127.0.0.1:$GWAY_PORT/ipfs/$CID?format=$format" -o plain_output && - test_should_contain "Content-Type: application/$format" plain_headers && - test_cmp expected plain_output - ' - - test_expect_success "GET $name with Accept: application/$format returns same payload as application/vnd.ipld.dag-$format but with plain Content-Type" ' - curl -s -H "Accept: application/vnd.ipld.dag-$format" "http://127.0.0.1:$GWAY_PORT/ipfs/$CID" > expected && - curl -sD plain_headers -H "Accept: application/$format" "http://127.0.0.1:$GWAY_PORT/ipfs/$CID" > plain_output && - test_should_contain "Content-Type: application/$format" plain_headers && - test_cmp expected plain_output - ' - - - # Make sure expected HTTP headers are returned with the dag- block - - test_expect_success "GET response for application/vnd.ipld.dag-$format has expected Content-Type" ' - curl -svX GET -H "Accept: application/vnd.ipld.dag-$format" "http://127.0.0.1:$GWAY_PORT/ipfs/$CID" >/dev/null 2>curl_output && - test_should_contain "< Content-Type: application/vnd.ipld.dag-$format" curl_output - ' - - test_expect_success "GET response for application/vnd.ipld.dag-$format includes Content-Length" ' - BYTES=$(ipfs block get $CID | wc --bytes) - test_should_contain "< Content-Length: $BYTES" curl_output - ' - - test_expect_success "GET response for application/vnd.ipld.dag-$format includes Content-Disposition" ' - test_should_contain "< Content-Disposition: ${disposition}\; filename=\"${CID}.${format}\"" curl_output - ' - - test_expect_success "GET response for application/vnd.ipld.dag-$format includes nosniff hint" ' - test_should_contain "< X-Content-Type-Options: nosniff" curl_output - ' - - test_expect_success "GET for application/vnd.ipld.dag-$format with query filename includes Content-Disposition with custom filename" ' - curl -svX GET -H "Accept: application/vnd.ipld.dag-$format" "http://127.0.0.1:$GWAY_PORT/ipfs/$CID?filename=foobar.$format" >/dev/null 2>curl_output_filename && - test_should_contain "< Content-Disposition: ${disposition}\; filename=\"foobar.$format\"" curl_output_filename - ' - - test_expect_success "GET for application/vnd.ipld.dag-$format with ?download=true forces Content-Disposition: attachment" ' - curl -svX GET -H "Accept: application/vnd.ipld.dag-$format" "http://127.0.0.1:$GWAY_PORT/ipfs/$CID?filename=foobar.$format&download=true" >/dev/null 2>curl_output_filename && - test_should_contain "< Content-Disposition: attachment" curl_output_filename - ' - - # Cache control HTTP headers - # (basic checks, detailed behavior is tested in t0116-gateway-cache.sh) - - test_expect_success "GET response for application/vnd.ipld.dag-$format includes Etag" ' - test_should_contain "< Etag: \"${CID}.dag-$format\"" curl_output - ' - - test_expect_success "GET response for application/vnd.ipld.dag-$format includes X-Ipfs-Path and X-Ipfs-Roots" ' - test_should_contain "< X-Ipfs-Path" curl_output && - test_should_contain "< X-Ipfs-Roots" curl_output - ' - - test_expect_success "GET response for application/vnd.ipld.dag-$format includes Cache-Control" ' - test_should_contain "< Cache-Control: public, max-age=29030400, immutable" curl_output - ' - - # HTTP HEAD behavior - test_expect_success "HEAD $name with no explicit format returns HTTP 200" ' - curl -I "http://127.0.0.1:$GWAY_PORT/ipfs/$CID" -o output && - test_should_contain "HTTP/1.1 200 OK" output && - test_should_contain "Content-Type: application/vnd.ipld.dag-$format" output && - test_should_contain "Content-Length: " output - ' - test_expect_success "HEAD $name with an explicit DAG-JSON format returns HTTP 200" ' - curl -I "http://127.0.0.1:$GWAY_PORT/ipfs/$CID?format=dag-json" -o output && - test_should_contain "HTTP/1.1 200 OK" output && - test_should_contain "Etag: \"$CID.dag-json\"" output && - test_should_contain "Content-Type: application/vnd.ipld.dag-json" output && - test_should_contain "Content-Length: " output - ' - test_expect_success "HEAD $name with only-if-cached for missing block returns HTTP 412 Precondition Failed" ' - MISSING_CID=$(echo "{\"t\": \"$(date +%s)\"}" | ipfs dag put --store-codec=dag-${format}) && - ipfs block rm -f -q $MISSING_CID && - curl -I -H "Cache-Control: only-if-cached" "http://127.0.0.1:$GWAY_PORT/ipfs/$MISSING_CID" -o output && - test_should_contain "HTTP/1.1 412 Precondition Failed" output - ' - - # IPNS behavior (should be same as immutable /ipfs, but with different caching headers) - # To keep tests small we only confirm payload is the same, and then only test delta around caching headers. - - test_expect_success "GET $name from /ipns without explicit format returns the same payload as /ipfs" ' - curl -sX GET "http://127.0.0.1:$GWAY_PORT/ipfs/$CID" -o ipfs_output && - curl -sX GET "http://127.0.0.1:$GWAY_PORT/ipns/$IPNS_ID" -o ipns_output && - test_cmp ipfs_output ipns_output - ' - - test_expect_success "GET $name from /ipns without explicit format returns the same payload as /ipfs" ' - curl -sX GET "http://127.0.0.1:$GWAY_PORT/ipfs/$CID?format=dag-$format" -o ipfs_output && - curl -sX GET "http://127.0.0.1:$GWAY_PORT/ipns/$IPNS_ID?format=dag-$format" -o ipns_output && - test_cmp ipfs_output ipns_output - ' - - test_expect_success "GET $name from /ipns with explicit application/vnd.ipld.dag-$format has expected headers" ' - curl -svX GET -H "Accept: application/vnd.ipld.dag-$format" "http://127.0.0.1:$GWAY_PORT/ipns/$IPNS_ID" >/dev/null 2>curl_output && - test_should_not_contain "Cache-Control" curl_output && - test_should_contain "< Content-Type: application/vnd.ipld.dag-$format" curl_output && - test_should_contain "< Etag: \"${CID}.dag-$format\"" curl_output && - test_should_contain "< X-Ipfs-Path" curl_output && - test_should_contain "< X-Ipfs-Roots" curl_output - ' - - - # When Accept header includes text/html and no explicit format is requested for DAG-(CBOR|JSON) - # The gateway returns generated HTML index (see dag-index-html) for web browsers (similar to dir-index-html returned for unixfs dirs) - # As this is generated, we don't return immutable Cache-Control, even on /ipfs (same as for dir-index-html) - - test_expect_success "GET $name on /ipfs with Accept: text/html returns HTML (dag-index-html)" ' - curl -sD - -H "Accept: text/html" "http://127.0.0.1:$GWAY_PORT/ipfs/$CID/" > curl_output 2>&1 && - test_should_not_contain "Content-Disposition" curl_output && - test_should_not_contain "Cache-Control" curl_output && - test_should_contain "Etag: \"DagIndex-" curl_output && - test_should_contain "Content-Type: text/html" curl_output && - test_should_contain "" curl_output - ' - - test_expect_success "GET $name on /ipns with Accept: text/html returns HTML (dag-index-html)" ' - curl -sD - -H "Accept: text/html" "http://127.0.0.1:$GWAY_PORT/ipns/$IPNS_ID/" > curl_output 2>&1 && - test_should_not_contain "Content-Disposition" curl_output && - test_should_not_contain "Cache-Control" curl_output && - test_should_contain "Etag: \"DagIndex-" curl_output && - test_should_contain "Content-Type: text/html" curl_output && - test_should_contain "" curl_output - ' - - -} - -test_native_dag "DAG-JSON" "json" "inline" "$DAG_JSON_TRAVERSAL_CID" ${IPNS_ID_DAG_JSON} -test_native_dag "DAG-CBOR" "cbor" "attachment" "$DAG_CBOR_TRAVERSAL_CID" ${IPNS_ID_DAG_CBOR} - -test_kill_ipfs_daemon - -test_done - -# vim: set ts=2 sw=2 et: diff --git a/test/sharness/t0123-gateway-json-cbor/README.md b/test/sharness/t0123-gateway-json-cbor/README.md deleted file mode 100644 index 5a63b192a..000000000 --- a/test/sharness/t0123-gateway-json-cbor/README.md +++ /dev/null @@ -1,66 +0,0 @@ -# Dataset description/sources - -- dag-cbor-traversal.car - -- dag-json-traversal.car - -- dag-pb.car - -- dag-pb.json - -- fixtures.car - - raw CARv1 - -generated with: - -```sh -# using ipfs version 0.21.0-dev (03a98280e3e642774776cd3d0435ab53e5dfa867) - -mkdir -p rootDir/ipfs && -mkdir -p rootDir/ipns && -mkdir -p rootDir/api && -mkdir -p rootDir/ą/ę && -echo "{ \"test\": \"i am a plain json file\" }" > rootDir/ą/ę/t.json && -echo "I am a txt file on path with utf8" > rootDir/ą/ę/file-źł.txt && -echo "I am a txt file in confusing /api dir" > rootDir/api/file.txt && -echo "I am a txt file in confusing /ipfs dir" > rootDir/ipfs/file.txt && -echo "I am a txt file in confusing /ipns dir" > rootDir/ipns/file.txt && -DIR_CID=$(ipfs add -Qr --cid-version 1 rootDir) && -FILE_JSON_CID=$(ipfs files stat --enc=json /ipfs/$DIR_CID/ą/ę/t.json | jq -r .Hash) && -FILE_CID=$(ipfs files stat --enc=json /ipfs/$DIR_CID/ą/ę/file-źł.txt | jq -r .Hash) && -FILE_SIZE=$(ipfs files stat --enc=json /ipfs/$DIR_CID/ą/ę/file-źł.txt | jq -r .Size) -echo "$FILE_CID / $FILE_SIZE" - -echo DIR_CID=${DIR_CID} # ./rootDir -echo FILE_JSON_CID=${FILE_JSON_CID} # ./rootDir/ą/ę/t.json -echo FILE_CID=${FILE_CID} # ./rootDir/ą/ę/file-źł.txt -echo FILE_SIZE=${FILE_SIZE} - -ipfs dag export ${DIR_CID} > fixtures.car - -DAG_CBOR_TRAVERSAL_CID="bafyreibs4utpgbn7uqegmd2goqz4bkyflre2ek2iwv743fhvylwi4zeeim" -DAG_JSON_TRAVERSAL_CID="baguqeeram5ujjqrwheyaty3w5gdsmoz6vittchvhk723jjqxk7hakxkd47xq" -DAG_PB_CID="bafybeiegxwlgmoh2cny7qlolykdf7aq7g6dlommarldrbm7c4hbckhfcke" - -test_native_dag() { - NAME=$1 - CID=$2 - - IPNS_ID=$(ipfs key gen --ipns-base=base36 --type=ed25519 ${NAME}_test_key | head -n1 | tr -d "\n") - ipfs name publish --key ${NAME}_test_key --allow-offline --ttl=876600h --lifetime=876600h -Q "/ipfs/${CID}" > name_publish_out - - ipfs routing get /ipns/${IPNS_ID} > ${IPNS_ID}.ipns-record - - echo "IPNS_ID_${NAME}=${IPNS_ID}" -} - -test_native_dag "DAG_JSON" "$DAG_JSON_TRAVERSAL_CID" -test_native_dag "DAG_CBOR" "$DAG_CBOR_TRAVERSAL_CID" - -# DIR_CID=bafybeiafyvqlazbbbtjnn6how5d6h6l6rxbqc4qgpbmteaiskjrffmyy4a # ./rootDir -# FILE_JSON_CID=bafkreibrppizs3g7axs2jdlnjua6vgpmltv7k72l7v7sa6mmht6mne3qqe # ./rootDir/ą/ę/t.json -# FILE_CID=bafkreialihlqnf5uwo4byh4n3cmwlntwqzxxs2fg5vanqdi3d7tb2l5xkm # ./rootDir/ą/ę/file-źł.txt -# FILE_SIZE=34 -# IPNS_ID_DAG_JSON=k51qzi5uqu5dhjghbwdvbo6mi40htrq6e2z4pwgp15pgv3ho1azvidttzh8yy2 -# IPNS_ID_DAG_CBOR=k51qzi5uqu5dghjous0agrwavl8vzl64xckoqzwqeqwudfr74kfd11zcyk3b7l -``` diff --git a/test/sharness/t0123-gateway-json-cbor/dag-cbor-traversal.car b/test/sharness/t0123-gateway-json-cbor/dag-cbor-traversal.car deleted file mode 100644 index 92c3d4f3e21718627007431c6b6d0cc1693be206..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 318 zcmcColvlXV(2oIMVptN{kPzW{vS&r0ub_{_K>mhu-w1 zv^b}ir4|)u=I1dM5Tklwa$0`=qLiG>yll7)cbQITWL7ctu-q3j&R(lE-F}^dl&{i> zKYDy?e%dYj{535;Oie9HtSCq+tW3+S zN-Qr(GOx-pP0uSxH_s|J&aEu1%u6yc%1f`xP0cs2$TQ8(%{47ZOe!%eRI1fc%1_El zO)dc$mz0EK_&Lb+xI#2#-t#MrbvfF8z zZSAu%HyyJ6o*#0o^a0ObkQqf7E=#I1%FigR$SF!oPs}qet|&?`PD`!KG%e4s$jmO! z&n(R|%`{C;EzUElN-r=@Ez7Mm0lKW#8EhqA$>U3}JAK&Rg?BCqN|fEat~K(+;;O!m mNqL*n-%L%jtX9fM&B*}i+sBr1Tzs1^WU$DR8C diff --git a/test/sharness/t0123-gateway-json-cbor/dag-pb.car b/test/sharness/t0123-gateway-json-cbor/dag-pb.car deleted file mode 100644 index a6bb076c7e323e449dfe3f6290adbe7e3826cf21..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 392 zcmcColv6N9G>c!tg+FvpA8Lzlk~eSLZrIRuTwwE~hlf;U z76qo4r4|)u=I1eXF%qL(NS8|mq^|IQa`O8b2I)OECVzyMewgCAPNpIter34l*}|*5 zT4#fWnA7s}C0vCJfyzUL6rzjWn-?3Nly$m#PLi+f!g;?F8kf!m7^ME`R`a{7@j*j~ z9jIKdq@qNEmy3ymF`6hVpl07>^l?*Z@mjj;ut>RWcE+qL>A(DBr2-c2SUERp>UaIG uLhMP2MPRe}KxP|(+(Sr@M`}(^zK%k9eo;<}B9|dCUVv)x3~&opR$Z!{1Tq}`!({@E*_B@ucod~pEh~Fe6+Vnh$AgCCsnVcqC`RsWVjbGnmiQ} za}^R5fSMFQx)n0>6q57v(n^an^U@Xcf#If*l3BzBb|=AbgSzwi)&Fl^GA?Lu%@C?# zekhl4`lzm@t6A&6m@~gjeWiKbkld*ba;G=QorE;ucPA*q5Dq06VNiz(pSd#Sis|Qo z3&&WQwUzSjUDZnWE>nqFajY+Wv%U0UCaex6q=}G2^B@il2gN+Wlmbmr3p)>Tspfra zzuq^&%Z+8;aog1@_L@tNFW#`M%_oCfEfAQZW=d=Wr>M!`oI_B9IV4GOJ6>m-zGd?c z8TsBDGgG&fwdGf4EPLy4gI8MqnXLZyU?E;mqR>6M>u3`=T`36}Kr|XwU!0k9pY`dI z-dtbCS2N$ly#8A6{kLABvd8AnvB?FELTn{^S;hHz5~`pWb_2yQA-m86EKFpafyI_VZ5QMu0#h}}HQ*$!q)^KR00zs~cmMzZ diff --git a/test/sharness/t0123-gateway-json-cbor/k51qzi5uqu5dghjous0agrwavl8vzl64xckoqzwqeqwudfr74kfd11zcyk3b7l.ipns-record b/test/sharness/t0123-gateway-json-cbor/k51qzi5uqu5dghjous0agrwavl8vzl64xckoqzwqeqwudfr74kfd11zcyk3b7l.ipns-record deleted file mode 100644 index 7186c709e3ceb29fbfda0fd38b4e43109f26ce55..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 394 zcmd;b)XywPE7ng+OsgzP%}gpbDJ>~TPs%edElf?%O)*N(FRU_2%C1byDM~d;%{Iy` zFEckWPRl5(%qh<_sY*@F%oTE|Wo^}bx%d5*Sx4q7wQu^*{jh&wK$gukjlQ6!w<^zC z3zgkZ3FJ7HbjEJnE2pg~YAb1T`}pU#Pwl?`TRqWK?I))MgOaq7p^>q!fr+l6afpG1 zm4T&|siB^QrJ=E@n00{M& AZ2$lO diff --git a/test/sharness/t0123-gateway-json-cbor/k51qzi5uqu5dhjghbwdvbo6mi40htrq6e2z4pwgp15pgv3ho1azvidttzh8yy2.ipns-record b/test/sharness/t0123-gateway-json-cbor/k51qzi5uqu5dhjghbwdvbo6mi40htrq6e2z4pwgp15pgv3ho1azvidttzh8yy2.ipns-record deleted file mode 100644 index 28676f4d9a8824989d039a03376aeea9ae63d0d3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 398 zcmd;b*3T?RE7ng+OfM}=O)W~yH7(7`Dl96`NUcmPsWdJ(O;0J#&95>m%Pc8L&M3>s zHa9W`DyYad&q&O!$WAdauP799P;T3(=A&^x$Y#D|lG@q>LT5|;wEh}r>YUo65W?xX z)~)KP*_E#3s?1Ys{Wt72pZosTYWup`{b6o#URK<3lJD3g7?h-q42_I+4NPq4G7B@V2@KoE$;q~X{`u_XeTsd(Ml(;WP%n0C_P+X~( z`|*~;{f_SyrzS~i|89=(;gu+H(2(HipQ0Kl{`~X07?TnkT`#}eZV&jprZX;04hiv* z);`_Lz>>_skQ$blQ<@q curl_output_filename && - test_should_contain "Hello IPFS" curl_output_filename -' - -test_expect_success "GET KEY with format=ipns-record and validate key" ' - curl "http://127.0.0.1:$GWAY_PORT/ipns/$IPNS_KEY?format=ipns-record" > curl_output_filename && - ipfs name inspect --verify $IPNS_KEY < curl_output_filename > verify_output && - test_should_contain "$FILE_CID" verify_output -' - -test_expect_success "GET KEY with 'Accept: application/vnd.ipfs.ipns-record' and validate key" ' - curl -H "Accept: application/vnd.ipfs.ipns-record" "http://127.0.0.1:$GWAY_PORT/ipns/$IPNS_KEY" > curl_output_filename && - ipfs name inspect --verify $IPNS_KEY < curl_output_filename > verify_output && - test_should_contain "$FILE_CID" verify_output -' - -test_expect_success "GET KEY with format=ipns-record has expected HTTP headers" ' - curl -sD - "http://127.0.0.1:$GWAY_PORT/ipns/$IPNS_KEY?format=ipns-record" > curl_output_filename 2>&1 && - test_should_contain "Content-Disposition: attachment;" curl_output_filename && - test_should_contain "Content-Type: application/vnd.ipfs.ipns-record" curl_output_filename && - test_should_contain "Cache-Control: public, max-age=3155760000" curl_output_filename -' - -test_expect_success "GET KEY with 'Accept: application/vnd.ipfs.ipns-record' has expected HTTP headers" ' - curl -H "Accept: application/vnd.ipfs.ipns-record" -sD - "http://127.0.0.1:$GWAY_PORT/ipns/$IPNS_KEY" > curl_output_filename 2>&1 && - test_should_contain "Content-Disposition: attachment;" curl_output_filename && - test_should_contain "Content-Type: application/vnd.ipfs.ipns-record" curl_output_filename && - test_should_contain "Cache-Control: public, max-age=3155760000" curl_output_filename -' - -test_expect_success "GET KEY with expliciy ?filename= succeeds with modified Content-Disposition header" ' - curl -sD - "http://127.0.0.1:$GWAY_PORT/ipns/$IPNS_KEY?format=ipns-record&filename=testтест.ipns-record" > curl_output_filename 2>&1 && - grep -F "Content-Disposition: attachment; filename=\"test____.ipns-record\"; filename*=UTF-8'\'\''test%D1%82%D0%B5%D1%81%D1%82.ipns-record" curl_output_filename && - test_should_contain "Content-Type: application/vnd.ipfs.ipns-record" curl_output_filename -' - -test_kill_ipfs_daemon - -test_done diff --git a/test/sharness/t0124-gateway-ipns-record/README.md b/test/sharness/t0124-gateway-ipns-record/README.md deleted file mode 100644 index 8ada577d4..000000000 --- a/test/sharness/t0124-gateway-ipns-record/README.md +++ /dev/null @@ -1,27 +0,0 @@ -# Dataset description/sources - -- fixtures.car - - raw CARv1 - -- k51....ipns-record - - ipns record, encoded with protocol buffer - -generated with: - -```sh -# using ipfs version 0.21.0-dev (03a98280e3e642774776cd3d0435ab53e5dfa867) -FILE_CID=$(echo "Hello IPFS" | ipfs add --cid-version 1 -q) -IPNS_KEY=$(ipfs key gen ipns-record) - -ipfs dag export ${FILE_CID} > fixtures.car - -# publish a record valid for a 100 years -ipfs name publish --key=ipns-record --quieter --ttl=876600h --lifetime=876600h /ipfs/${FILE_CID} -ipfs routing get /ipns/${IPNS_KEY} > ${IPNS_KEY}.ipns-record - -echo IPNS_KEY=${IPNS_KEY} -echo FILE_CID=${FILE_CID} # A file containing "Hello IPFS" - -# IPNS_KEY=k51qzi5uqu5dh71qgwangrt6r0nd4094i88nsady6qgd1dhjcyfsaqmpp143ab -# FILE_CID=bafkreidfdrlkeq4m4xnxuyx6iae76fdm4wgl5d4xzsb77ixhyqwumhz244 # A file containing Hello IPFS -``` diff --git a/test/sharness/t0124-gateway-ipns-record/fixtures.car b/test/sharness/t0124-gateway-ipns-record/fixtures.car deleted file mode 100644 index 5c541e430ea6d1aed7c20545c40c9a56994ac546..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 107 zcmcColvSFJ04j^dIZkA-4vOEfq6H0ie39ZWWO|7T-n zhTD&u+CmfaOSEsE-5&R2o=I`u(JdVUdxTlHr4_DQ%+Dynpd@8vXk@HwV4`bi6k=#> zWo%|;YN2OjY;I&8rNLm((9pBE;lYEa+D;DZwog8P;JtWuR2%!>xl6YFEuU6)>E){C z#}a3ym{+MAwLQ!K{b1W$zOv&|S}J#Rzj~K(y{i5eAFDB8+QsA7xBcYvn!>m=IV8kK zTKjY}14}XkLuy!JPHAcc<>8PKoLX3#nwOl)kO4F@GbOX6G6Ijca$t%=DhpB>023mb A4*&oF From 4cd49cfca8d7d693ad6aa54f22dcc8ac25b554a1 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Fri, 4 Aug 2023 18:11:42 +0200 Subject: [PATCH 0798/1212] chore: bump go-libp2p v0.29.1 --- docs/examples/kubo-as-a-library/go.mod | 8 ++++---- docs/examples/kubo-as-a-library/go.sum | 16 ++++++++-------- go.mod | 8 ++++---- go.sum | 16 ++++++++-------- test/dependencies/go.mod | 8 ++++---- test/dependencies/go.sum | 16 ++++++++-------- 6 files changed, 36 insertions(+), 36 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 29123db14..86f8a1e8f 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -9,7 +9,7 @@ replace github.com/ipfs/kubo => ./../../.. require ( github.com/ipfs/boxo v0.11.0 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 - github.com/libp2p/go-libp2p v0.29.0 + github.com/libp2p/go-libp2p v0.29.1 github.com/multiformats/go-multiaddr v0.10.1 ) @@ -148,9 +148,9 @@ require ( github.com/prometheus/common v0.44.0 // indirect github.com/prometheus/procfs v0.11.0 // indirect github.com/quic-go/qpack v0.4.0 // indirect - github.com/quic-go/qtls-go1-19 v0.3.2 // indirect - github.com/quic-go/qtls-go1-20 v0.2.2 // indirect - github.com/quic-go/quic-go v0.36.2 // indirect + github.com/quic-go/qtls-go1-19 v0.3.3 // indirect + github.com/quic-go/qtls-go1-20 v0.2.3 // indirect + github.com/quic-go/quic-go v0.36.3 // indirect github.com/quic-go/webtransport-go v0.5.3 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/samber/lo v1.36.0 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 5c1c2bd0c..339fffed4 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -459,8 +459,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.29.0 h1:QduJ2XQr/Crg4EnloueWDL0Jj86N3Ezhyyj7XH+XwHI= -github.com/libp2p/go-libp2p v0.29.0/go.mod h1:iNKL7mEnZ9wAss+03IjAwM9ZAQXfVUAPUUmOACQfQ/g= +github.com/libp2p/go-libp2p v0.29.1 h1:yNeg6XgP8gbdc4YSrwiIt5T1TGOrVjH8dzl8h0GIOfQ= +github.com/libp2p/go-libp2p v0.29.1/go.mod h1:20El+LLy3/YhdUYIvGbLnvVJN32nMdqY6KXBENRAfLY= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= @@ -638,12 +638,12 @@ github.com/prometheus/procfs v0.11.0 h1:5EAgkfkMl659uZPbe9AS2N68a7Cc1TJbPEuGzFuR github.com/prometheus/procfs v0.11.0/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= -github.com/quic-go/qtls-go1-19 v0.3.2 h1:tFxjCFcTQzK+oMxG6Zcvp4Dq8dx4yD3dDiIiyc86Z5U= -github.com/quic-go/qtls-go1-19 v0.3.2/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI= -github.com/quic-go/qtls-go1-20 v0.2.2 h1:WLOPx6OY/hxtTxKV1Zrq20FtXtDEkeY00CGQm8GEa3E= -github.com/quic-go/qtls-go1-20 v0.2.2/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= -github.com/quic-go/quic-go v0.36.2 h1:ZX/UNQ4gvpCv2RmwdbA6lrRjF6EBm5yZ7TMoT4NQVrA= -github.com/quic-go/quic-go v0.36.2/go.mod h1:zPetvwDlILVxt15n3hr3Gf/I3mDf7LpLKPhR4Ez0AZQ= +github.com/quic-go/qtls-go1-19 v0.3.3 h1:wznEHvJwd+2X3PqftRha0SUKmGsnb6dfArMhy9PeJVE= +github.com/quic-go/qtls-go1-19 v0.3.3/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI= +github.com/quic-go/qtls-go1-20 v0.2.3 h1:m575dovXn1y2ATOb1XrRFcrv0F+EQmlowTkoraNkDPI= +github.com/quic-go/qtls-go1-20 v0.2.3/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= +github.com/quic-go/quic-go v0.36.3 h1:f+yOqeGhMoRX7/M3wmEw/djhzKWr15FtQysox85/834= +github.com/quic-go/quic-go v0.36.3/go.mod h1:qxQumdeKw5GmWs1OsTZZnOxzSI+RJWuhf1O8FN35L2o= github.com/quic-go/webtransport-go v0.5.3 h1:5XMlzemqB4qmOlgIus5zB45AcZ2kCgCy2EptUrfOPWU= github.com/quic-go/webtransport-go v0.5.3/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= diff --git a/go.mod b/go.mod index 02f0972b2..525406548 100644 --- a/go.mod +++ b/go.mod @@ -45,7 +45,7 @@ require ( github.com/jbenet/goprocess v0.1.4 github.com/julienschmidt/httprouter v1.3.0 github.com/libp2p/go-doh-resolver v0.4.0 - github.com/libp2p/go-libp2p v0.29.0 + github.com/libp2p/go-libp2p v0.29.1 github.com/libp2p/go-libp2p-http v0.5.0 github.com/libp2p/go-libp2p-kad-dht v0.24.2 github.com/libp2p/go-libp2p-kbucket v0.6.3 @@ -192,9 +192,9 @@ require ( github.com/prometheus/procfs v0.11.0 // indirect github.com/prometheus/statsd_exporter v0.22.7 // indirect github.com/quic-go/qpack v0.4.0 // indirect - github.com/quic-go/qtls-go1-19 v0.3.2 // indirect - github.com/quic-go/qtls-go1-20 v0.2.2 // indirect - github.com/quic-go/quic-go v0.36.2 // indirect + github.com/quic-go/qtls-go1-19 v0.3.3 // indirect + github.com/quic-go/qtls-go1-20 v0.2.3 // indirect + github.com/quic-go/quic-go v0.36.3 // indirect github.com/quic-go/webtransport-go v0.5.3 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/rs/cors v1.7.0 // indirect diff --git a/go.sum b/go.sum index 75bdfb9b4..d84840748 100644 --- a/go.sum +++ b/go.sum @@ -517,8 +517,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.29.0 h1:QduJ2XQr/Crg4EnloueWDL0Jj86N3Ezhyyj7XH+XwHI= -github.com/libp2p/go-libp2p v0.29.0/go.mod h1:iNKL7mEnZ9wAss+03IjAwM9ZAQXfVUAPUUmOACQfQ/g= +github.com/libp2p/go-libp2p v0.29.1 h1:yNeg6XgP8gbdc4YSrwiIt5T1TGOrVjH8dzl8h0GIOfQ= +github.com/libp2p/go-libp2p v0.29.1/go.mod h1:20El+LLy3/YhdUYIvGbLnvVJN32nMdqY6KXBENRAfLY= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= @@ -743,12 +743,12 @@ github.com/prometheus/statsd_exporter v0.22.7 h1:7Pji/i2GuhK6Lu7DHrtTkFmNBCudCPT github.com/prometheus/statsd_exporter v0.22.7/go.mod h1:N/TevpjkIh9ccs6nuzY3jQn9dFqnUakOjnEuMPJJJnI= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= -github.com/quic-go/qtls-go1-19 v0.3.2 h1:tFxjCFcTQzK+oMxG6Zcvp4Dq8dx4yD3dDiIiyc86Z5U= -github.com/quic-go/qtls-go1-19 v0.3.2/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI= -github.com/quic-go/qtls-go1-20 v0.2.2 h1:WLOPx6OY/hxtTxKV1Zrq20FtXtDEkeY00CGQm8GEa3E= -github.com/quic-go/qtls-go1-20 v0.2.2/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= -github.com/quic-go/quic-go v0.36.2 h1:ZX/UNQ4gvpCv2RmwdbA6lrRjF6EBm5yZ7TMoT4NQVrA= -github.com/quic-go/quic-go v0.36.2/go.mod h1:zPetvwDlILVxt15n3hr3Gf/I3mDf7LpLKPhR4Ez0AZQ= +github.com/quic-go/qtls-go1-19 v0.3.3 h1:wznEHvJwd+2X3PqftRha0SUKmGsnb6dfArMhy9PeJVE= +github.com/quic-go/qtls-go1-19 v0.3.3/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI= +github.com/quic-go/qtls-go1-20 v0.2.3 h1:m575dovXn1y2ATOb1XrRFcrv0F+EQmlowTkoraNkDPI= +github.com/quic-go/qtls-go1-20 v0.2.3/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= +github.com/quic-go/quic-go v0.36.3 h1:f+yOqeGhMoRX7/M3wmEw/djhzKWr15FtQysox85/834= +github.com/quic-go/quic-go v0.36.3/go.mod h1:qxQumdeKw5GmWs1OsTZZnOxzSI+RJWuhf1O8FN35L2o= github.com/quic-go/webtransport-go v0.5.3 h1:5XMlzemqB4qmOlgIus5zB45AcZ2kCgCy2EptUrfOPWU= github.com/quic-go/webtransport-go v0.5.3/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index fb1a0ec0a..a601b6c3b 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -19,7 +19,7 @@ require ( github.com/ipld/go-ipld-prime v0.20.0 github.com/jbenet/go-random v0.0.0-20190219211222-123a90aedc0c github.com/jbenet/go-random-files v0.0.0-20190219210431-31b3f20ebded - github.com/libp2p/go-libp2p v0.29.0 + github.com/libp2p/go-libp2p v0.29.1 github.com/multiformats/go-multiaddr v0.10.1 github.com/multiformats/go-multihash v0.2.3 gotest.tools/gotestsum v0.4.2 @@ -216,9 +216,9 @@ require ( github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95 // indirect github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 // indirect github.com/quic-go/qpack v0.4.0 // indirect - github.com/quic-go/qtls-go1-19 v0.3.2 // indirect - github.com/quic-go/qtls-go1-20 v0.2.2 // indirect - github.com/quic-go/quic-go v0.36.2 // indirect + github.com/quic-go/qtls-go1-19 v0.3.3 // indirect + github.com/quic-go/qtls-go1-20 v0.2.3 // indirect + github.com/quic-go/quic-go v0.36.3 // indirect github.com/quic-go/webtransport-go v0.5.3 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 152ccc4e1..5dc56ba47 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -542,8 +542,8 @@ github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38y github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.29.0 h1:QduJ2XQr/Crg4EnloueWDL0Jj86N3Ezhyyj7XH+XwHI= -github.com/libp2p/go-libp2p v0.29.0/go.mod h1:iNKL7mEnZ9wAss+03IjAwM9ZAQXfVUAPUUmOACQfQ/g= +github.com/libp2p/go-libp2p v0.29.1 h1:yNeg6XgP8gbdc4YSrwiIt5T1TGOrVjH8dzl8h0GIOfQ= +github.com/libp2p/go-libp2p v0.29.1/go.mod h1:20El+LLy3/YhdUYIvGbLnvVJN32nMdqY6KXBENRAfLY= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= @@ -746,12 +746,12 @@ github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 h1:M8mH9eK4OUR4l github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567/go.mod h1:DWNGW8A4Y+GyBgPuaQJuWiy0XYftx4Xm/y5Jqk9I6VQ= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= -github.com/quic-go/qtls-go1-19 v0.3.2 h1:tFxjCFcTQzK+oMxG6Zcvp4Dq8dx4yD3dDiIiyc86Z5U= -github.com/quic-go/qtls-go1-19 v0.3.2/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI= -github.com/quic-go/qtls-go1-20 v0.2.2 h1:WLOPx6OY/hxtTxKV1Zrq20FtXtDEkeY00CGQm8GEa3E= -github.com/quic-go/qtls-go1-20 v0.2.2/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= -github.com/quic-go/quic-go v0.36.2 h1:ZX/UNQ4gvpCv2RmwdbA6lrRjF6EBm5yZ7TMoT4NQVrA= -github.com/quic-go/quic-go v0.36.2/go.mod h1:zPetvwDlILVxt15n3hr3Gf/I3mDf7LpLKPhR4Ez0AZQ= +github.com/quic-go/qtls-go1-19 v0.3.3 h1:wznEHvJwd+2X3PqftRha0SUKmGsnb6dfArMhy9PeJVE= +github.com/quic-go/qtls-go1-19 v0.3.3/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI= +github.com/quic-go/qtls-go1-20 v0.2.3 h1:m575dovXn1y2ATOb1XrRFcrv0F+EQmlowTkoraNkDPI= +github.com/quic-go/qtls-go1-20 v0.2.3/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= +github.com/quic-go/quic-go v0.36.3 h1:f+yOqeGhMoRX7/M3wmEw/djhzKWr15FtQysox85/834= +github.com/quic-go/quic-go v0.36.3/go.mod h1:qxQumdeKw5GmWs1OsTZZnOxzSI+RJWuhf1O8FN35L2o= github.com/quic-go/webtransport-go v0.5.3 h1:5XMlzemqB4qmOlgIus5zB45AcZ2kCgCy2EptUrfOPWU= github.com/quic-go/webtransport-go v0.5.3/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= From c5cc835fb8312db289d1bc2fc1d094f2e95d9d42 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Fri, 2 Dec 2022 16:18:29 +0100 Subject: [PATCH 0799/1212] docs(readme): unofficial packages badge --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 6b6154065..c511de3e6 100644 --- a/README.md +++ b/README.md @@ -165,8 +165,12 @@ $ ipfs get /ipns/dist.ipfs.tech/kubo/$VERSION/kubo_$VERSION_windows-amd64.zip ### Unofficial Linux packages + + Packaging status + + - [ArchLinux](#arch-linux) -- [Nix](#nix) +- [Nix](#nix-linux) - [Solus](#solus) - [openSUSE](#opensuse) - [Guix](#guix) From 95cf3369007d835bdf8343537265a2a670325686 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Tue, 8 Aug 2023 11:36:29 +0200 Subject: [PATCH 0800/1212] chore: update version to v0.21.1-dev --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index cfe20ca70..890013c42 100644 --- a/version.go +++ b/version.go @@ -11,7 +11,7 @@ import ( var CurrentCommit string // CurrentVersionNumber is the current application's version literal -const CurrentVersionNumber = "0.21.0" +const CurrentVersionNumber = "0.21.1-dev" const ApiVersion = "/kubo/" + CurrentVersionNumber + "/" //nolint From 3fe788028c38218ff153b7026c716d9487fe2ff0 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Mon, 7 Aug 2023 17:44:55 +0200 Subject: [PATCH 0801/1212] chore: bump go-libp2p to v0.27.8 --- docs/examples/kubo-as-a-library/go.mod | 6 +++--- docs/examples/kubo-as-a-library/go.sum | 12 ++++++------ go.mod | 6 +++--- go.sum | 12 ++++++------ test/dependencies/go.mod | 6 +++--- test/dependencies/go.sum | 12 ++++++------ 6 files changed, 27 insertions(+), 27 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 40a4c8e45..14bf2b82d 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -9,7 +9,7 @@ replace github.com/ipfs/kubo => ./../../.. require ( github.com/ipfs/boxo v0.10.2-0.20230629143123-2d3edc552442 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 - github.com/libp2p/go-libp2p v0.27.7 + github.com/libp2p/go-libp2p v0.27.8 github.com/multiformats/go-multiaddr v0.9.0 ) @@ -147,8 +147,8 @@ require ( github.com/prometheus/common v0.42.0 // indirect github.com/prometheus/procfs v0.9.0 // indirect github.com/quic-go/qpack v0.4.0 // indirect - github.com/quic-go/qtls-go1-19 v0.3.2 // indirect - github.com/quic-go/qtls-go1-20 v0.2.2 // indirect + github.com/quic-go/qtls-go1-19 v0.3.3 // indirect + github.com/quic-go/qtls-go1-20 v0.2.3 // indirect github.com/quic-go/quic-go v0.33.0 // indirect github.com/quic-go/webtransport-go v0.5.3 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 55b93e23a..492ae2d74 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -487,8 +487,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.27.7 h1:nhMs03CRxslKkkK2uLuN8f72uwNkE6RJS1JFb3H9UIQ= -github.com/libp2p/go-libp2p v0.27.7/go.mod h1:oMfQGTb9CHnrOuSM6yMmyK2lXz3qIhnkn2+oK3B1Y2g= +github.com/libp2p/go-libp2p v0.27.8 h1:IX5x/4yKwyPQeVS2AXHZ3J4YATM9oHBGH1gBc23jBAI= +github.com/libp2p/go-libp2p v0.27.8/go.mod h1:eCFFtd0s5i/EVKR7+5Ki8bM7qwkNW3TPTTSSW9sz8NE= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= @@ -673,10 +673,10 @@ github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJf github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= -github.com/quic-go/qtls-go1-19 v0.3.2 h1:tFxjCFcTQzK+oMxG6Zcvp4Dq8dx4yD3dDiIiyc86Z5U= -github.com/quic-go/qtls-go1-19 v0.3.2/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI= -github.com/quic-go/qtls-go1-20 v0.2.2 h1:WLOPx6OY/hxtTxKV1Zrq20FtXtDEkeY00CGQm8GEa3E= -github.com/quic-go/qtls-go1-20 v0.2.2/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= +github.com/quic-go/qtls-go1-19 v0.3.3 h1:wznEHvJwd+2X3PqftRha0SUKmGsnb6dfArMhy9PeJVE= +github.com/quic-go/qtls-go1-19 v0.3.3/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI= +github.com/quic-go/qtls-go1-20 v0.2.3 h1:m575dovXn1y2ATOb1XrRFcrv0F+EQmlowTkoraNkDPI= +github.com/quic-go/qtls-go1-20 v0.2.3/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= github.com/quic-go/quic-go v0.33.0 h1:ItNoTDN/Fm/zBlq769lLJc8ECe9gYaW40veHCCco7y0= github.com/quic-go/quic-go v0.33.0/go.mod h1:YMuhaAV9/jIu0XclDXwZPAsP/2Kgr5yMYhe9oxhhOFA= github.com/quic-go/webtransport-go v0.5.3 h1:5XMlzemqB4qmOlgIus5zB45AcZ2kCgCy2EptUrfOPWU= diff --git a/go.mod b/go.mod index cd58e5cff..3900be8e9 100644 --- a/go.mod +++ b/go.mod @@ -45,7 +45,7 @@ require ( github.com/jbenet/goprocess v0.1.4 github.com/julienschmidt/httprouter v1.3.0 github.com/libp2p/go-doh-resolver v0.4.0 - github.com/libp2p/go-libp2p v0.27.7 + github.com/libp2p/go-libp2p v0.27.8 github.com/libp2p/go-libp2p-http v0.5.0 github.com/libp2p/go-libp2p-kad-dht v0.24.2 github.com/libp2p/go-libp2p-kbucket v0.6.3 @@ -185,8 +185,8 @@ require ( github.com/prometheus/procfs v0.9.0 // indirect github.com/prometheus/statsd_exporter v0.22.7 // indirect github.com/quic-go/qpack v0.4.0 // indirect - github.com/quic-go/qtls-go1-19 v0.3.2 // indirect - github.com/quic-go/qtls-go1-20 v0.2.2 // indirect + github.com/quic-go/qtls-go1-19 v0.3.3 // indirect + github.com/quic-go/qtls-go1-20 v0.2.3 // indirect github.com/quic-go/quic-go v0.33.0 // indirect github.com/quic-go/webtransport-go v0.5.3 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect diff --git a/go.sum b/go.sum index 319148117..1e6bf1dd7 100644 --- a/go.sum +++ b/go.sum @@ -537,8 +537,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.27.7 h1:nhMs03CRxslKkkK2uLuN8f72uwNkE6RJS1JFb3H9UIQ= -github.com/libp2p/go-libp2p v0.27.7/go.mod h1:oMfQGTb9CHnrOuSM6yMmyK2lXz3qIhnkn2+oK3B1Y2g= +github.com/libp2p/go-libp2p v0.27.8 h1:IX5x/4yKwyPQeVS2AXHZ3J4YATM9oHBGH1gBc23jBAI= +github.com/libp2p/go-libp2p v0.27.8/go.mod h1:eCFFtd0s5i/EVKR7+5Ki8bM7qwkNW3TPTTSSW9sz8NE= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= @@ -768,10 +768,10 @@ github.com/prometheus/statsd_exporter v0.22.7 h1:7Pji/i2GuhK6Lu7DHrtTkFmNBCudCPT github.com/prometheus/statsd_exporter v0.22.7/go.mod h1:N/TevpjkIh9ccs6nuzY3jQn9dFqnUakOjnEuMPJJJnI= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= -github.com/quic-go/qtls-go1-19 v0.3.2 h1:tFxjCFcTQzK+oMxG6Zcvp4Dq8dx4yD3dDiIiyc86Z5U= -github.com/quic-go/qtls-go1-19 v0.3.2/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI= -github.com/quic-go/qtls-go1-20 v0.2.2 h1:WLOPx6OY/hxtTxKV1Zrq20FtXtDEkeY00CGQm8GEa3E= -github.com/quic-go/qtls-go1-20 v0.2.2/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= +github.com/quic-go/qtls-go1-19 v0.3.3 h1:wznEHvJwd+2X3PqftRha0SUKmGsnb6dfArMhy9PeJVE= +github.com/quic-go/qtls-go1-19 v0.3.3/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI= +github.com/quic-go/qtls-go1-20 v0.2.3 h1:m575dovXn1y2ATOb1XrRFcrv0F+EQmlowTkoraNkDPI= +github.com/quic-go/qtls-go1-20 v0.2.3/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= github.com/quic-go/quic-go v0.33.0 h1:ItNoTDN/Fm/zBlq769lLJc8ECe9gYaW40veHCCco7y0= github.com/quic-go/quic-go v0.33.0/go.mod h1:YMuhaAV9/jIu0XclDXwZPAsP/2Kgr5yMYhe9oxhhOFA= github.com/quic-go/webtransport-go v0.5.3 h1:5XMlzemqB4qmOlgIus5zB45AcZ2kCgCy2EptUrfOPWU= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 18d3d834e..f14d825a4 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -19,7 +19,7 @@ require ( github.com/ipld/go-ipld-prime v0.20.0 github.com/jbenet/go-random v0.0.0-20190219211222-123a90aedc0c github.com/jbenet/go-random-files v0.0.0-20190219210431-31b3f20ebded - github.com/libp2p/go-libp2p v0.27.7 + github.com/libp2p/go-libp2p v0.27.8 github.com/multiformats/go-multiaddr v0.9.0 github.com/multiformats/go-multihash v0.2.3 gotest.tools/gotestsum v0.4.2 @@ -214,8 +214,8 @@ require ( github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95 // indirect github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 // indirect github.com/quic-go/qpack v0.4.0 // indirect - github.com/quic-go/qtls-go1-19 v0.3.2 // indirect - github.com/quic-go/qtls-go1-20 v0.2.2 // indirect + github.com/quic-go/qtls-go1-19 v0.3.3 // indirect + github.com/quic-go/qtls-go1-20 v0.2.3 // indirect github.com/quic-go/quic-go v0.33.0 // indirect github.com/quic-go/webtransport-go v0.5.3 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index bb4f8ebf5..e25e3b107 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -565,8 +565,8 @@ github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38y github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.27.7 h1:nhMs03CRxslKkkK2uLuN8f72uwNkE6RJS1JFb3H9UIQ= -github.com/libp2p/go-libp2p v0.27.7/go.mod h1:oMfQGTb9CHnrOuSM6yMmyK2lXz3qIhnkn2+oK3B1Y2g= +github.com/libp2p/go-libp2p v0.27.8 h1:IX5x/4yKwyPQeVS2AXHZ3J4YATM9oHBGH1gBc23jBAI= +github.com/libp2p/go-libp2p v0.27.8/go.mod h1:eCFFtd0s5i/EVKR7+5Ki8bM7qwkNW3TPTTSSW9sz8NE= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= @@ -773,10 +773,10 @@ github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 h1:M8mH9eK4OUR4l github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567/go.mod h1:DWNGW8A4Y+GyBgPuaQJuWiy0XYftx4Xm/y5Jqk9I6VQ= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= -github.com/quic-go/qtls-go1-19 v0.3.2 h1:tFxjCFcTQzK+oMxG6Zcvp4Dq8dx4yD3dDiIiyc86Z5U= -github.com/quic-go/qtls-go1-19 v0.3.2/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI= -github.com/quic-go/qtls-go1-20 v0.2.2 h1:WLOPx6OY/hxtTxKV1Zrq20FtXtDEkeY00CGQm8GEa3E= -github.com/quic-go/qtls-go1-20 v0.2.2/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= +github.com/quic-go/qtls-go1-19 v0.3.3 h1:wznEHvJwd+2X3PqftRha0SUKmGsnb6dfArMhy9PeJVE= +github.com/quic-go/qtls-go1-19 v0.3.3/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI= +github.com/quic-go/qtls-go1-20 v0.2.3 h1:m575dovXn1y2ATOb1XrRFcrv0F+EQmlowTkoraNkDPI= +github.com/quic-go/qtls-go1-20 v0.2.3/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= github.com/quic-go/quic-go v0.33.0 h1:ItNoTDN/Fm/zBlq769lLJc8ECe9gYaW40veHCCco7y0= github.com/quic-go/quic-go v0.33.0/go.mod h1:YMuhaAV9/jIu0XclDXwZPAsP/2Kgr5yMYhe9oxhhOFA= github.com/quic-go/webtransport-go v0.5.3 h1:5XMlzemqB4qmOlgIus5zB45AcZ2kCgCy2EptUrfOPWU= From cfc142d85b1f0c4ec72ea322195cd7d526b5a1da Mon Sep 17 00:00:00 2001 From: Jorropo Date: Tue, 8 Aug 2023 12:55:08 +0200 Subject: [PATCH 0802/1212] ci: add workflow_dispatch to gateway conformance --- .github/workflows/gateway-conformance.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/gateway-conformance.yml b/.github/workflows/gateway-conformance.yml index 4ce8215a2..380dd4d28 100644 --- a/.github/workflows/gateway-conformance.yml +++ b/.github/workflows/gateway-conformance.yml @@ -1,6 +1,7 @@ name: Gateway Conformance on: + workflow_dispatch: push: branches: - master From cee9052f2bbd0fea0434e6fccd8991c2e618f817 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Tue, 8 Aug 2023 12:17:33 +0200 Subject: [PATCH 0803/1212] chore: update boxo to v0.10.3 --- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- test/dependencies/go.mod | 2 +- test/dependencies/go.sum | 4 ++-- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 14bf2b82d..ed5da920b 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.18 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.10.2-0.20230629143123-2d3edc552442 + github.com/ipfs/boxo v0.10.3 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.27.8 github.com/multiformats/go-multiaddr v0.9.0 diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 492ae2d74..335f0eb73 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -320,8 +320,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.10.2-0.20230629143123-2d3edc552442 h1:SGbw381zt6c1VFf3QCBaJ+eVJ4AwD9fPaFKFp9U9Apk= -github.com/ipfs/boxo v0.10.2-0.20230629143123-2d3edc552442/go.mod h1:1qgKq45mPRCxf4ZPoJV2lnXxyxucigILMJOrQrVivv8= +github.com/ipfs/boxo v0.10.3 h1:FvoLUdc0J/12UeVmV89gem686bj3QIEBnlNEUeJ6+Xk= +github.com/ipfs/boxo v0.10.3/go.mod h1:1qgKq45mPRCxf4ZPoJV2lnXxyxucigILMJOrQrVivv8= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= diff --git a/go.mod b/go.mod index 3900be8e9..e8ea1ffc6 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/gogo/protobuf v1.3.2 github.com/google/uuid v1.3.0 github.com/hashicorp/go-multierror v1.1.1 - github.com/ipfs/boxo v0.10.2-0.20230629143123-2d3edc552442 + github.com/ipfs/boxo v0.10.3 github.com/ipfs/go-block-format v0.1.2 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 diff --git a/go.sum b/go.sum index 1e6bf1dd7..12ca4e08d 100644 --- a/go.sum +++ b/go.sum @@ -355,8 +355,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.10.2-0.20230629143123-2d3edc552442 h1:SGbw381zt6c1VFf3QCBaJ+eVJ4AwD9fPaFKFp9U9Apk= -github.com/ipfs/boxo v0.10.2-0.20230629143123-2d3edc552442/go.mod h1:1qgKq45mPRCxf4ZPoJV2lnXxyxucigILMJOrQrVivv8= +github.com/ipfs/boxo v0.10.3 h1:FvoLUdc0J/12UeVmV89gem686bj3QIEBnlNEUeJ6+Xk= +github.com/ipfs/boxo v0.10.3/go.mod h1:1qgKq45mPRCxf4ZPoJV2lnXxyxucigILMJOrQrVivv8= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index f14d825a4..252101a2b 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -7,7 +7,7 @@ replace github.com/ipfs/kubo => ../../ require ( github.com/Kubuxu/gocovmerge v0.0.0-20161216165753-7ecaa51963cd github.com/golangci/golangci-lint v1.49.0 - github.com/ipfs/boxo v0.10.2-0.20230629143123-2d3edc552442 + github.com/ipfs/boxo v0.10.3 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 github.com/ipfs/go-datastore v0.6.0 diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index e25e3b107..66d92b321 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -413,8 +413,8 @@ github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NH github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.10.2-0.20230629143123-2d3edc552442 h1:SGbw381zt6c1VFf3QCBaJ+eVJ4AwD9fPaFKFp9U9Apk= -github.com/ipfs/boxo v0.10.2-0.20230629143123-2d3edc552442/go.mod h1:1qgKq45mPRCxf4ZPoJV2lnXxyxucigILMJOrQrVivv8= +github.com/ipfs/boxo v0.10.3 h1:FvoLUdc0J/12UeVmV89gem686bj3QIEBnlNEUeJ6+Xk= +github.com/ipfs/boxo v0.10.3/go.mod h1:1qgKq45mPRCxf4ZPoJV2lnXxyxucigILMJOrQrVivv8= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.1.2 h1:GAjkfhVx1f4YTODS6Esrj1wt2HhrtwTnhEr+DyPUaJo= From 50e03fdd1d19ede1590df76c341ec937a21f9225 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Tue, 8 Aug 2023 12:24:21 +0200 Subject: [PATCH 0804/1212] chore: update go-libp2p to v0.27.9 --- docs/examples/kubo-as-a-library/go.mod | 4 ++-- docs/examples/kubo-as-a-library/go.sum | 8 ++++---- go.mod | 4 ++-- go.sum | 8 ++++---- test/dependencies/go.mod | 4 ++-- test/dependencies/go.sum | 8 ++++---- 6 files changed, 18 insertions(+), 18 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index ed5da920b..6836c3664 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -9,7 +9,7 @@ replace github.com/ipfs/kubo => ./../../.. require ( github.com/ipfs/boxo v0.10.3 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 - github.com/libp2p/go-libp2p v0.27.8 + github.com/libp2p/go-libp2p v0.27.9 github.com/multiformats/go-multiaddr v0.9.0 ) @@ -149,7 +149,7 @@ require ( github.com/quic-go/qpack v0.4.0 // indirect github.com/quic-go/qtls-go1-19 v0.3.3 // indirect github.com/quic-go/qtls-go1-20 v0.2.3 // indirect - github.com/quic-go/quic-go v0.33.0 // indirect + github.com/quic-go/quic-go v0.33.1 // indirect github.com/quic-go/webtransport-go v0.5.3 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/samber/lo v1.36.0 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 335f0eb73..bfea29e96 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -487,8 +487,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.27.8 h1:IX5x/4yKwyPQeVS2AXHZ3J4YATM9oHBGH1gBc23jBAI= -github.com/libp2p/go-libp2p v0.27.8/go.mod h1:eCFFtd0s5i/EVKR7+5Ki8bM7qwkNW3TPTTSSW9sz8NE= +github.com/libp2p/go-libp2p v0.27.9 h1:n5p5bQD469v7I/1qncaHDq0BeSx4iT2fHF3NyNuKOmY= +github.com/libp2p/go-libp2p v0.27.9/go.mod h1:Tdx7ZuJl9NE78PkB4FjPVbf6kaQNOh2ppU/OVvVB6Wc= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= @@ -677,8 +677,8 @@ github.com/quic-go/qtls-go1-19 v0.3.3 h1:wznEHvJwd+2X3PqftRha0SUKmGsnb6dfArMhy9P github.com/quic-go/qtls-go1-19 v0.3.3/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI= github.com/quic-go/qtls-go1-20 v0.2.3 h1:m575dovXn1y2ATOb1XrRFcrv0F+EQmlowTkoraNkDPI= github.com/quic-go/qtls-go1-20 v0.2.3/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= -github.com/quic-go/quic-go v0.33.0 h1:ItNoTDN/Fm/zBlq769lLJc8ECe9gYaW40veHCCco7y0= -github.com/quic-go/quic-go v0.33.0/go.mod h1:YMuhaAV9/jIu0XclDXwZPAsP/2Kgr5yMYhe9oxhhOFA= +github.com/quic-go/quic-go v0.33.1 h1:EVsG7O/7FVZI8Za71GzpHDoWpBTKdjDv1/x0KFcckho= +github.com/quic-go/quic-go v0.33.1/go.mod h1:YMuhaAV9/jIu0XclDXwZPAsP/2Kgr5yMYhe9oxhhOFA= github.com/quic-go/webtransport-go v0.5.3 h1:5XMlzemqB4qmOlgIus5zB45AcZ2kCgCy2EptUrfOPWU= github.com/quic-go/webtransport-go v0.5.3/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= diff --git a/go.mod b/go.mod index e8ea1ffc6..5357f8e9b 100644 --- a/go.mod +++ b/go.mod @@ -45,7 +45,7 @@ require ( github.com/jbenet/goprocess v0.1.4 github.com/julienschmidt/httprouter v1.3.0 github.com/libp2p/go-doh-resolver v0.4.0 - github.com/libp2p/go-libp2p v0.27.8 + github.com/libp2p/go-libp2p v0.27.9 github.com/libp2p/go-libp2p-http v0.5.0 github.com/libp2p/go-libp2p-kad-dht v0.24.2 github.com/libp2p/go-libp2p-kbucket v0.6.3 @@ -187,7 +187,7 @@ require ( github.com/quic-go/qpack v0.4.0 // indirect github.com/quic-go/qtls-go1-19 v0.3.3 // indirect github.com/quic-go/qtls-go1-20 v0.2.3 // indirect - github.com/quic-go/quic-go v0.33.0 // indirect + github.com/quic-go/quic-go v0.33.1 // indirect github.com/quic-go/webtransport-go v0.5.3 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/rs/cors v1.7.0 // indirect diff --git a/go.sum b/go.sum index 12ca4e08d..ab0e7b1a9 100644 --- a/go.sum +++ b/go.sum @@ -537,8 +537,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.27.8 h1:IX5x/4yKwyPQeVS2AXHZ3J4YATM9oHBGH1gBc23jBAI= -github.com/libp2p/go-libp2p v0.27.8/go.mod h1:eCFFtd0s5i/EVKR7+5Ki8bM7qwkNW3TPTTSSW9sz8NE= +github.com/libp2p/go-libp2p v0.27.9 h1:n5p5bQD469v7I/1qncaHDq0BeSx4iT2fHF3NyNuKOmY= +github.com/libp2p/go-libp2p v0.27.9/go.mod h1:Tdx7ZuJl9NE78PkB4FjPVbf6kaQNOh2ppU/OVvVB6Wc= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= @@ -772,8 +772,8 @@ github.com/quic-go/qtls-go1-19 v0.3.3 h1:wznEHvJwd+2X3PqftRha0SUKmGsnb6dfArMhy9P github.com/quic-go/qtls-go1-19 v0.3.3/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI= github.com/quic-go/qtls-go1-20 v0.2.3 h1:m575dovXn1y2ATOb1XrRFcrv0F+EQmlowTkoraNkDPI= github.com/quic-go/qtls-go1-20 v0.2.3/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= -github.com/quic-go/quic-go v0.33.0 h1:ItNoTDN/Fm/zBlq769lLJc8ECe9gYaW40veHCCco7y0= -github.com/quic-go/quic-go v0.33.0/go.mod h1:YMuhaAV9/jIu0XclDXwZPAsP/2Kgr5yMYhe9oxhhOFA= +github.com/quic-go/quic-go v0.33.1 h1:EVsG7O/7FVZI8Za71GzpHDoWpBTKdjDv1/x0KFcckho= +github.com/quic-go/quic-go v0.33.1/go.mod h1:YMuhaAV9/jIu0XclDXwZPAsP/2Kgr5yMYhe9oxhhOFA= github.com/quic-go/webtransport-go v0.5.3 h1:5XMlzemqB4qmOlgIus5zB45AcZ2kCgCy2EptUrfOPWU= github.com/quic-go/webtransport-go v0.5.3/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 252101a2b..97600dc6d 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -19,7 +19,7 @@ require ( github.com/ipld/go-ipld-prime v0.20.0 github.com/jbenet/go-random v0.0.0-20190219211222-123a90aedc0c github.com/jbenet/go-random-files v0.0.0-20190219210431-31b3f20ebded - github.com/libp2p/go-libp2p v0.27.8 + github.com/libp2p/go-libp2p v0.27.9 github.com/multiformats/go-multiaddr v0.9.0 github.com/multiformats/go-multihash v0.2.3 gotest.tools/gotestsum v0.4.2 @@ -216,7 +216,7 @@ require ( github.com/quic-go/qpack v0.4.0 // indirect github.com/quic-go/qtls-go1-19 v0.3.3 // indirect github.com/quic-go/qtls-go1-20 v0.2.3 // indirect - github.com/quic-go/quic-go v0.33.0 // indirect + github.com/quic-go/quic-go v0.33.1 // indirect github.com/quic-go/webtransport-go v0.5.3 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 66d92b321..c78815cbc 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -565,8 +565,8 @@ github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38y github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.27.8 h1:IX5x/4yKwyPQeVS2AXHZ3J4YATM9oHBGH1gBc23jBAI= -github.com/libp2p/go-libp2p v0.27.8/go.mod h1:eCFFtd0s5i/EVKR7+5Ki8bM7qwkNW3TPTTSSW9sz8NE= +github.com/libp2p/go-libp2p v0.27.9 h1:n5p5bQD469v7I/1qncaHDq0BeSx4iT2fHF3NyNuKOmY= +github.com/libp2p/go-libp2p v0.27.9/go.mod h1:Tdx7ZuJl9NE78PkB4FjPVbf6kaQNOh2ppU/OVvVB6Wc= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= @@ -777,8 +777,8 @@ github.com/quic-go/qtls-go1-19 v0.3.3 h1:wznEHvJwd+2X3PqftRha0SUKmGsnb6dfArMhy9P github.com/quic-go/qtls-go1-19 v0.3.3/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI= github.com/quic-go/qtls-go1-20 v0.2.3 h1:m575dovXn1y2ATOb1XrRFcrv0F+EQmlowTkoraNkDPI= github.com/quic-go/qtls-go1-20 v0.2.3/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= -github.com/quic-go/quic-go v0.33.0 h1:ItNoTDN/Fm/zBlq769lLJc8ECe9gYaW40veHCCco7y0= -github.com/quic-go/quic-go v0.33.0/go.mod h1:YMuhaAV9/jIu0XclDXwZPAsP/2Kgr5yMYhe9oxhhOFA= +github.com/quic-go/quic-go v0.33.1 h1:EVsG7O/7FVZI8Za71GzpHDoWpBTKdjDv1/x0KFcckho= +github.com/quic-go/quic-go v0.33.1/go.mod h1:YMuhaAV9/jIu0XclDXwZPAsP/2Kgr5yMYhe9oxhhOFA= github.com/quic-go/webtransport-go v0.5.3 h1:5XMlzemqB4qmOlgIus5zB45AcZ2kCgCy2EptUrfOPWU= github.com/quic-go/webtransport-go v0.5.3/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= From 61e0779f663fdf246151e71745483700d6d33501 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Tue, 8 Aug 2023 12:23:16 +0200 Subject: [PATCH 0805/1212] changelog: make v0.21.1 --- docs/changelogs/v0.21.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/docs/changelogs/v0.21.md b/docs/changelogs/v0.21.md index b798c0d7b..d7a0d8b7f 100644 --- a/docs/changelogs/v0.21.md +++ b/docs/changelogs/v0.21.md @@ -1,7 +1,15 @@ # Kubo changelog v0.21 +- [v0.21.1](#v0211) - [v0.21.0](#v0210) +## v0.21.1 + +- Update go-libp2p: + - [v0.27.8](https://github.com/libp2p/go-libp2p/releases/tag/v0.27.8) + - [v0.27.9](https://github.com/libp2p/go-libp2p/releases/tag/v0.27.9) +- Update Boxo to v0.10.3 ([ipfs/boxo#412](https://github.com/ipfs/boxo/pull/412)). + ## v0.21.0 - [Overview](#overview) @@ -228,7 +236,8 @@ should be using AcceleratedDHTClient because they are falling behind. - v0.2.1 ([ipfs/go-ipld-legacy#15](https://github.com/ipfs/go-ipld-legacy/pull/15)) - Expose a constructor for making a decoder with an existing link system ([ipfs/go-ipld-legacy#14](https://github.com/ipfs/go-ipld-legacy/pull/14)) - Update to v0.2.0 ([ipfs/go-ipld-legacy#13](https://github.com/ipfs/go-ipld-legacy/pull/13)) - - Remove global variable ([ipfs/go-ipld-legacy#12](https://github.com/ipfs/go-ipld-legacy/pull/12)) + - Remove global variable + ([ipfs/go-ipld-legacy#12](https://github.com/ipfs/go-ipld-legacy/pull/12)) - sync: update CI config files (#8) ([ipfs/go-ipld-legacy#8](https://github.com/ipfs/go-ipld-legacy/pull/8)) - github.com/ipfs/go-unixfsnode (v1.6.0 -> v1.7.1): - chore: bump to v1.7.1 From bc0d1a460778f4f6e2fa6dfce6d0351baaafeb55 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Tue, 8 Aug 2023 12:26:57 +0200 Subject: [PATCH 0806/1212] chore: change version to 0.21.1 --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index 890013c42..38d5dbd7d 100644 --- a/version.go +++ b/version.go @@ -11,7 +11,7 @@ import ( var CurrentCommit string // CurrentVersionNumber is the current application's version literal -const CurrentVersionNumber = "0.21.1-dev" +const CurrentVersionNumber = "0.21.1" const ApiVersion = "/kubo/" + CurrentVersionNumber + "/" //nolint From c37485ad2904a06e50beb63ddf44cae7e381fc2c Mon Sep 17 00:00:00 2001 From: Jorropo Date: Tue, 8 Aug 2023 12:55:08 +0200 Subject: [PATCH 0807/1212] ci: add workflow_dispatch to gateway conformance (cherry picked from commit cfc142d85b1f0c4ec72ea322195cd7d526b5a1da) --- .github/workflows/gateway-conformance.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/gateway-conformance.yml b/.github/workflows/gateway-conformance.yml index 8825f9bce..01800ceb9 100644 --- a/.github/workflows/gateway-conformance.yml +++ b/.github/workflows/gateway-conformance.yml @@ -1,6 +1,7 @@ name: Gateway Conformance on: + workflow_dispatch: push: branches: - master From b8e393056c238d44d7b98dadba4aaaffda98deb4 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Tue, 8 Aug 2023 13:26:22 +0200 Subject: [PATCH 0808/1212] chore: bump go-libp2p v0.29.2 --- docs/examples/kubo-as-a-library/go.mod | 4 ++-- docs/examples/kubo-as-a-library/go.sum | 8 ++++---- go.mod | 4 ++-- go.sum | 8 ++++---- test/dependencies/go.mod | 4 ++-- test/dependencies/go.sum | 8 ++++---- 6 files changed, 18 insertions(+), 18 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 86f8a1e8f..5cc1054a2 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -9,7 +9,7 @@ replace github.com/ipfs/kubo => ./../../.. require ( github.com/ipfs/boxo v0.11.0 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 - github.com/libp2p/go-libp2p v0.29.1 + github.com/libp2p/go-libp2p v0.29.2 github.com/multiformats/go-multiaddr v0.10.1 ) @@ -150,7 +150,7 @@ require ( github.com/quic-go/qpack v0.4.0 // indirect github.com/quic-go/qtls-go1-19 v0.3.3 // indirect github.com/quic-go/qtls-go1-20 v0.2.3 // indirect - github.com/quic-go/quic-go v0.36.3 // indirect + github.com/quic-go/quic-go v0.36.4 // indirect github.com/quic-go/webtransport-go v0.5.3 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/samber/lo v1.36.0 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 339fffed4..3213c24eb 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -459,8 +459,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.29.1 h1:yNeg6XgP8gbdc4YSrwiIt5T1TGOrVjH8dzl8h0GIOfQ= -github.com/libp2p/go-libp2p v0.29.1/go.mod h1:20El+LLy3/YhdUYIvGbLnvVJN32nMdqY6KXBENRAfLY= +github.com/libp2p/go-libp2p v0.29.2 h1:uPw/c8hOxoLP/KhFnzlc5Ejqf+OmAL1dwIsqE31WBtY= +github.com/libp2p/go-libp2p v0.29.2/go.mod h1:OU7nSq0aEZMsV2wY8nXn1+XNNt9q2UiR8LjW3Kmp2UE= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= @@ -642,8 +642,8 @@ github.com/quic-go/qtls-go1-19 v0.3.3 h1:wznEHvJwd+2X3PqftRha0SUKmGsnb6dfArMhy9P github.com/quic-go/qtls-go1-19 v0.3.3/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI= github.com/quic-go/qtls-go1-20 v0.2.3 h1:m575dovXn1y2ATOb1XrRFcrv0F+EQmlowTkoraNkDPI= github.com/quic-go/qtls-go1-20 v0.2.3/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= -github.com/quic-go/quic-go v0.36.3 h1:f+yOqeGhMoRX7/M3wmEw/djhzKWr15FtQysox85/834= -github.com/quic-go/quic-go v0.36.3/go.mod h1:qxQumdeKw5GmWs1OsTZZnOxzSI+RJWuhf1O8FN35L2o= +github.com/quic-go/quic-go v0.36.4 h1:CXn/ZLN5Vntlk53fjR+kUMC8Jt7flfQe+I5Ty5A+k0o= +github.com/quic-go/quic-go v0.36.4/go.mod h1:qxQumdeKw5GmWs1OsTZZnOxzSI+RJWuhf1O8FN35L2o= github.com/quic-go/webtransport-go v0.5.3 h1:5XMlzemqB4qmOlgIus5zB45AcZ2kCgCy2EptUrfOPWU= github.com/quic-go/webtransport-go v0.5.3/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= diff --git a/go.mod b/go.mod index 525406548..d730dd2f3 100644 --- a/go.mod +++ b/go.mod @@ -45,7 +45,7 @@ require ( github.com/jbenet/goprocess v0.1.4 github.com/julienschmidt/httprouter v1.3.0 github.com/libp2p/go-doh-resolver v0.4.0 - github.com/libp2p/go-libp2p v0.29.1 + github.com/libp2p/go-libp2p v0.29.2 github.com/libp2p/go-libp2p-http v0.5.0 github.com/libp2p/go-libp2p-kad-dht v0.24.2 github.com/libp2p/go-libp2p-kbucket v0.6.3 @@ -194,7 +194,7 @@ require ( github.com/quic-go/qpack v0.4.0 // indirect github.com/quic-go/qtls-go1-19 v0.3.3 // indirect github.com/quic-go/qtls-go1-20 v0.2.3 // indirect - github.com/quic-go/quic-go v0.36.3 // indirect + github.com/quic-go/quic-go v0.36.4 // indirect github.com/quic-go/webtransport-go v0.5.3 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/rs/cors v1.7.0 // indirect diff --git a/go.sum b/go.sum index d84840748..22b6ea3cf 100644 --- a/go.sum +++ b/go.sum @@ -517,8 +517,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.29.1 h1:yNeg6XgP8gbdc4YSrwiIt5T1TGOrVjH8dzl8h0GIOfQ= -github.com/libp2p/go-libp2p v0.29.1/go.mod h1:20El+LLy3/YhdUYIvGbLnvVJN32nMdqY6KXBENRAfLY= +github.com/libp2p/go-libp2p v0.29.2 h1:uPw/c8hOxoLP/KhFnzlc5Ejqf+OmAL1dwIsqE31WBtY= +github.com/libp2p/go-libp2p v0.29.2/go.mod h1:OU7nSq0aEZMsV2wY8nXn1+XNNt9q2UiR8LjW3Kmp2UE= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= @@ -747,8 +747,8 @@ github.com/quic-go/qtls-go1-19 v0.3.3 h1:wznEHvJwd+2X3PqftRha0SUKmGsnb6dfArMhy9P github.com/quic-go/qtls-go1-19 v0.3.3/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI= github.com/quic-go/qtls-go1-20 v0.2.3 h1:m575dovXn1y2ATOb1XrRFcrv0F+EQmlowTkoraNkDPI= github.com/quic-go/qtls-go1-20 v0.2.3/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= -github.com/quic-go/quic-go v0.36.3 h1:f+yOqeGhMoRX7/M3wmEw/djhzKWr15FtQysox85/834= -github.com/quic-go/quic-go v0.36.3/go.mod h1:qxQumdeKw5GmWs1OsTZZnOxzSI+RJWuhf1O8FN35L2o= +github.com/quic-go/quic-go v0.36.4 h1:CXn/ZLN5Vntlk53fjR+kUMC8Jt7flfQe+I5Ty5A+k0o= +github.com/quic-go/quic-go v0.36.4/go.mod h1:qxQumdeKw5GmWs1OsTZZnOxzSI+RJWuhf1O8FN35L2o= github.com/quic-go/webtransport-go v0.5.3 h1:5XMlzemqB4qmOlgIus5zB45AcZ2kCgCy2EptUrfOPWU= github.com/quic-go/webtransport-go v0.5.3/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index a601b6c3b..bfee9a0a7 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -19,7 +19,7 @@ require ( github.com/ipld/go-ipld-prime v0.20.0 github.com/jbenet/go-random v0.0.0-20190219211222-123a90aedc0c github.com/jbenet/go-random-files v0.0.0-20190219210431-31b3f20ebded - github.com/libp2p/go-libp2p v0.29.1 + github.com/libp2p/go-libp2p v0.29.2 github.com/multiformats/go-multiaddr v0.10.1 github.com/multiformats/go-multihash v0.2.3 gotest.tools/gotestsum v0.4.2 @@ -218,7 +218,7 @@ require ( github.com/quic-go/qpack v0.4.0 // indirect github.com/quic-go/qtls-go1-19 v0.3.3 // indirect github.com/quic-go/qtls-go1-20 v0.2.3 // indirect - github.com/quic-go/quic-go v0.36.3 // indirect + github.com/quic-go/quic-go v0.36.4 // indirect github.com/quic-go/webtransport-go v0.5.3 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 5dc56ba47..4967be85f 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -542,8 +542,8 @@ github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38y github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.29.1 h1:yNeg6XgP8gbdc4YSrwiIt5T1TGOrVjH8dzl8h0GIOfQ= -github.com/libp2p/go-libp2p v0.29.1/go.mod h1:20El+LLy3/YhdUYIvGbLnvVJN32nMdqY6KXBENRAfLY= +github.com/libp2p/go-libp2p v0.29.2 h1:uPw/c8hOxoLP/KhFnzlc5Ejqf+OmAL1dwIsqE31WBtY= +github.com/libp2p/go-libp2p v0.29.2/go.mod h1:OU7nSq0aEZMsV2wY8nXn1+XNNt9q2UiR8LjW3Kmp2UE= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= @@ -750,8 +750,8 @@ github.com/quic-go/qtls-go1-19 v0.3.3 h1:wznEHvJwd+2X3PqftRha0SUKmGsnb6dfArMhy9P github.com/quic-go/qtls-go1-19 v0.3.3/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI= github.com/quic-go/qtls-go1-20 v0.2.3 h1:m575dovXn1y2ATOb1XrRFcrv0F+EQmlowTkoraNkDPI= github.com/quic-go/qtls-go1-20 v0.2.3/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= -github.com/quic-go/quic-go v0.36.3 h1:f+yOqeGhMoRX7/M3wmEw/djhzKWr15FtQysox85/834= -github.com/quic-go/quic-go v0.36.3/go.mod h1:qxQumdeKw5GmWs1OsTZZnOxzSI+RJWuhf1O8FN35L2o= +github.com/quic-go/quic-go v0.36.4 h1:CXn/ZLN5Vntlk53fjR+kUMC8Jt7flfQe+I5Ty5A+k0o= +github.com/quic-go/quic-go v0.36.4/go.mod h1:qxQumdeKw5GmWs1OsTZZnOxzSI+RJWuhf1O8FN35L2o= github.com/quic-go/webtransport-go v0.5.3 h1:5XMlzemqB4qmOlgIus5zB45AcZ2kCgCy2EptUrfOPWU= github.com/quic-go/webtransport-go v0.5.3/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= From 2a20180819aa30abf064eb2ef4b2ece1d7472f9f Mon Sep 17 00:00:00 2001 From: UnkwUsr Date: Sat, 5 Aug 2023 18:22:15 +0300 Subject: [PATCH 0809/1212] chore(misc/README.md): trim duplicated content --- misc/README.md | 124 ------------------------------------------------- 1 file changed, 124 deletions(-) diff --git a/misc/README.md b/misc/README.md index 8462532f6..16abf0441 100644 --- a/misc/README.md +++ b/misc/README.md @@ -120,130 +120,6 @@ The reason for running `ipfs` under a shell is to avoid needing to hard-code the Notes: -- To check that the job is running, run `launchctl list | grep ipfs`. -- IPFS should now start whenever you log in (and exit when you log out). -- [LaunchControl](http://www.soma-zone.com/LaunchControl/) is a GUI tool which simplifies management of LaunchAgents.## init system integration - -go-ipfs can be started by your operating system's native init system. - -- [systemd](#systemd) -- [LSB init script](#initd) -- [Upstart/startup job](#upstart) -- [launchd](#launchd) - -### systemd - -For `systemd`, the best approach is to run the daemon in a user session. Here is a sample service file: - -```systemd -[Unit] -Description=IPFS daemon - -[Service] -# Environment="IPFS_PATH=/data/ipfs" # optional path to ipfs init directory if not default ($HOME/.ipfs) -ExecStart=/usr/bin/ipfs daemon -Restart=on-failure - -[Install] -WantedBy=default.target -``` - -To run this in your user session, save it as `~/.config/systemd/user/ipfs.service` (creating directories as necessary). Once you run `ipfs init` to create your IPFS settings, you can control the daemon using the following commands: - -* `systemctl --user start ipfs` - start the daemon -* `systemctl --user stop ipfs` - stop the daemon -* `systemctl --user status ipfs` - get status of the daemon -* `systemctl --user enable ipfs` - enable starting the daemon at boot -* `systemctl --user disable ipfs` - disable starting the daemon at boot - -*Note:* If you want this `--user` service to run at system boot, you must [`enable-linger`](http://www.freedesktop.org/software/systemd/man/loginctl.html) on the account that runs the service: - -``` -# loginctl enable-linger [user] -``` -Read more about `--user` services here: [wiki.archlinux.org:Systemd ](https://wiki.archlinux.org/index.php/Systemd/User#Automatic_start-up_of_systemd_user_instances) - -### initd - -- Here is a full-featured sample service file: https://github.com/dylanPowers/ipfs-linux-service/blob/master/init.d/ipfs -- Use `service` or your distribution's equivalent to control the service. - -## upstart - -- And below is a very basic sample upstart job. **Note the username jbenet**. - -``` -cat /etc/init/ipfs.conf -``` -``` -description "ipfs: interplanetary filesystem" - -start on (local-filesystems and net-device-up IFACE!=lo) -stop on runlevel [!2345] - -limit nofile 524288 1048576 -limit nproc 524288 1048576 -setuid jbenet -chdir /home/jbenet -respawn -exec ipfs daemon -``` - -Another version is available here: - -```sh -ipfs cat /ipfs/QmbYCwVeA23vz6mzAiVQhJNa2JSiRH4ebef1v2e5EkDEZS/ipfs.conf >/etc/init/ipfs.conf -``` - -For both, edit to replace occurrences of `jbenet` with whatever user you want it to run as: - -```sh -sed -i s/jbenet// /etc/init/ipfs.conf -``` - -Once you run `ipfs init` to create your IPFS settings, you can control the daemon using the `init.d` commands: - -```sh -sudo service ipfs start -sudo service ipfs stop -sudo service ipfs restart -... -``` - -## launchd - -Similar to `systemd`, on macOS you can run `go-ipfs` via a user LaunchAgent. - -- Create `~/Library/LaunchAgents/io.ipfs.go-ipfs.plist`: - -```xml - - - - - KeepAlive - - Label - io.ipfs.go-ipfs - ProcessType - Background - ProgramArguments - - /bin/sh - -c - ~/go/bin/ipfs daemon - - RunAtLoad - - - -``` -The reason for running `ipfs` under a shell is to avoid needing to hard-code the user's home directory in the job. - -- To start the job, run `launchctl load ~/Library/LaunchAgents/io.ipfs.go-ipfs.plist` - -Notes: - - To check that the job is running, run `launchctl list | grep ipfs`. - IPFS should now start whenever you log in (and exit when you log out). - [LaunchControl](http://www.soma-zone.com/LaunchControl/) is a GUI tool which simplifies management of LaunchAgents. From efa179fce4824313f23ef1b801ef5b68e2d33bd9 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Tue, 8 Aug 2023 16:41:55 +0200 Subject: [PATCH 0810/1212] changelog: add mkreleaselog for v0.22 --- docs/changelogs/v0.22.md | 58 +++++++++++++++++++++++++++++++++------- 1 file changed, 48 insertions(+), 10 deletions(-) diff --git a/docs/changelogs/v0.22.md b/docs/changelogs/v0.22.md index 46eee4275..47292db72 100644 --- a/docs/changelogs/v0.22.md +++ b/docs/changelogs/v0.22.md @@ -67,6 +67,18 @@ This includes a breaking change to `ipfs id` and some of the `ipfs swarm` comman
Full Changelog - github.com/ipfs/kubo: + - chore: change version to v0.22.0 + - chore(misc/README.md): trim duplicated content + - Merge branch 'release-v0.21' back into master + - docs(readme): unofficial packages badge + - chore: remove sharness tests ported to conformance testing (#9999) ([ipfs/kubo#9999](https://github.com/ipfs/kubo/pull/9999)) + - ci: switch from testing against js-ipfs to helia (#10042) ([ipfs/kubo#10042](https://github.com/ipfs/kubo/pull/10042)) + - chore: merge release back into master + - chore: change orbitdb to haydenyoung EARLY_TESTERS + - Fix usage numbers + - chore: update early testers list (#9218) ([ipfs/kubo#9218](https://github.com/ipfs/kubo/pull/9218)) + - docs: changelog v0.21 fixes (#10037) ([ipfs/kubo#10037](https://github.com/ipfs/kubo/pull/10037)) + - refactor(ci): simplify Dockerfile and add docker image testing (#10021) ([ipfs/kubo#10021](https://github.com/ipfs/kubo/pull/10021)) - chore: update version - fix(relay): apply user provider options - libp2p: stop reporting ProtocolVersion @@ -96,9 +108,25 @@ This includes a breaking change to `ipfs id` and some of the `ipfs swarm` comman - chore(docs): typo http→https - fix: more stable prometheus test (#9944) ([ipfs/kubo#9944](https://github.com/ipfs/kubo/pull/9944)) - ([ipfs/kubo#9937](https://github.com/ipfs/kubo/pull/9937)) -- github.com/ipfs/boxo (v0.10.2-0.20230629143123-2d3edc552442 -> v0.11.0): +- github.com/ipfs/boxo (v0.10.3 -> v0.11.0): - Release v0.11.0 ([ipfs/boxo#417](https://github.com/ipfs/boxo/pull/417)) - - ([ipfs/boxo#401](https://github.com/ipfs/boxo/pull/401)) +- github.com/ipfs/go-bitswap (null -> v0.11.0): + - chore: release v0.11.0 + - chore: release v0.10.2 + - fix: create a copy of the protocol slice in network.processSettings + - chore: release v0.10.1 + - fix: incorrect type in the WithTracer polyfill option + - chore: fix incorrect log message when a bad option is passed + - chore: release v0.10.0 + - chore: update go-libp2p v0.22.0 + - chore: release v0.9.0 + - feat: split client and server ([ipfs/go-bitswap#570](https://github.com/ipfs/go-bitswap/pull/570)) + - chore: remove goprocess from blockstoremanager + - Don't add blocks to the datastore ([ipfs/go-bitswap#571](https://github.com/ipfs/go-bitswap/pull/571)) + - Remove dependency on travis package from go-libp2p-testing ([ipfs/go-bitswap#569](https://github.com/ipfs/go-bitswap/pull/569)) + - feat: add basic tracing (#562) ([ipfs/go-bitswap#562](https://github.com/ipfs/go-bitswap/pull/562)) + - chore: release v0.7.0 (#566) ([ipfs/go-bitswap#566](https://github.com/ipfs/go-bitswap/pull/566)) + - feat: coalesce and queue connection event handling (#565) ([ipfs/go-bitswap#565](https://github.com/ipfs/go-bitswap/pull/565)) - github.com/ipfs/go-merkledag (v0.10.0 -> v0.11.0): - chore: update v0.11.0 (#106) ([ipfs/go-merkledag#106](https://github.com/ipfs/go-merkledag/pull/106)) - update merkeldag to use the explicit decoder registry (#104) ([ipfs/go-merkledag#104](https://github.com/ipfs/go-merkledag/pull/104)) @@ -116,7 +144,11 @@ This includes a breaking change to `ipfs id` and some of the `ipfs swarm` comman - fix: tests should match stderr for verbose output - fix: reading from stdin should broadcast EOF to block loaders - refactor insertion index to be publicly accessible ([ipld/go-car#408](https://github.com/ipld/go-car/pull/408)) -- github.com/libp2p/go-libp2p (v0.27.7 -> v0.29.0): +- github.com/libp2p/go-libp2p (v0.27.9 -> v0.29.2): + - release v0.29.2 + - release v0.29.1 + - swarm: don't open new streams over transient connections (#2450) ([libp2p/go-libp2p#2450](https://github.com/libp2p/go-libp2p/pull/2450)) + - core/crypto: restrict RSA keys to <= 8192 bits (#2454) ([libp2p/go-libp2p#2454](https://github.com/libp2p/go-libp2p/pull/2454)) - Release version v0.29.0 (#2431) ([libp2p/go-libp2p#2431](https://github.com/libp2p/go-libp2p/pull/2431)) - webtransport: reject listening on a multiaddr with a certhash (#2426) ([libp2p/go-libp2p#2426](https://github.com/libp2p/go-libp2p/pull/2426)) - swarm: deprecate libp2p.DialRanker option (#2430) ([libp2p/go-libp2p#2430](https://github.com/libp2p/go-libp2p/pull/2430)) @@ -227,27 +259,33 @@ This includes a breaking change to `ipfs id` and some of the `ipfs swarm` comman | Contributor | Commits | Lines ± | Files Changed | |-------------|---------|---------|---------------| | Henrique Dias | 14 | +3735/-17889 | 185 | -| Sukun | 27 | +5829/-957 | 98 | -| Marten Seemann | 39 | +2924/-1831 | 161 | -| Marco Munizaga | 17 | +1498/-580 | 76 | +| Sukun | 28 | +5910/-957 | 100 | +| Jorropo | 40 | +2913/-2112 | 205 | +| Marten Seemann | 41 | +2926/-1833 | 163 | +| Marco Munizaga | 20 | +1559/-586 | 81 | | Prem Chaitanya Prathi | 1 | +757/-740 | 61 | -| Jorropo | 20 | +639/-444 | 49 | -| Marcin Rataj | 9 | +331/-194 | 20 | +| Laurent Senta | 2 | +69/-1094 | 32 | +| Marcin Rataj | 11 | +339/-198 | 22 | +| Steven Allen | 2 | +313/-161 | 9 | | Will | 2 | +118/-211 | 9 | | Adin Schmahmann | 4 | +275/-41 | 8 | +| Michael Muré | 1 | +113/-164 | 6 | | Rod Vagg | 8 | +228/-46 | 28 | +| Gus Eggert | 5 | +156/-93 | 21 | | Adrian Sutton | 1 | +190/-17 | 4 | | Hlib Kanunnikov | 3 | +139/-40 | 9 | | VM | 2 | +80/-79 | 49 | +| UnkwUsr | 1 | +0/-124 | 1 | +| Piotr Galar | 4 | +51/-59 | 5 | | web3-bot | 3 | +22/-46 | 4 | | Will Scott | 2 | +29/-28 | 6 | | Prithvi Shahi | 2 | +40/-7 | 2 | -| Laurent Senta | 1 | +40/-4 | 2 | | Brad Fitzpatrick | 1 | +42/-2 | 2 | -| Piotr Galar | 3 | +16/-16 | 3 | | Steve Loeppky | 1 | +6/-23 | 2 | | Sahib Yar | 1 | +4/-4 | 3 | | Russell Dempsey | 2 | +4/-2 | 2 | | Mohamed MHAMDI | 1 | +3/-3 | 1 | | Bryan White | 1 | +2/-2 | 1 | | Dennis Trautwein | 1 | +1/-1 | 1 | +| Antonio Navarro Perez | 1 | +0/-1 | 1 | + From f5164d77eb27ee5a1a062d524b0138bbd6ee50f3 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Tue, 8 Aug 2023 16:01:56 +0200 Subject: [PATCH 0811/1212] chore: change version to v0.22.0 --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index 265ec937e..75a86953b 100644 --- a/version.go +++ b/version.go @@ -11,7 +11,7 @@ import ( var CurrentCommit string // CurrentVersionNumber is the current application's version literal -const CurrentVersionNumber = "0.23.0-dev" +const CurrentVersionNumber = "0.22.0" const ApiVersion = "/kubo/" + CurrentVersionNumber + "/" //nolint From 54ac8124c3bf2a19ebfd60f9a5edcea943c7b392 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Wed, 9 Aug 2023 20:58:54 +0200 Subject: [PATCH 0812/1212] chore: fix link in v0.22 changelog --- docs/changelogs/v0.22.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/changelogs/v0.22.md b/docs/changelogs/v0.22.md index 46eee4275..6f335d535 100644 --- a/docs/changelogs/v0.22.md +++ b/docs/changelogs/v0.22.md @@ -9,7 +9,7 @@ - [Gateway: support for `order=` and `dups=` parameters (IPIP-412)](#gateway-support-for-order-and-dups-parameters-ipip-412) - [`ipfs name publish` now supports V2 only IPNS records](#ipfs-name-publish-now-supports-v2-only-ipns-records) - [IPNS name resolution has been fixed](#ipns-name-resolution-has-been-fixed) - - [go-libp2p v0.29.0 update with smart dialing](#go-libp2p-v0.29.0-update-with-smart-dialing) + - [go-libp2p v0.29.0 update with smart dialing](#go-libp2p-v0290-update-with-smart-dialing) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) From fe94dade32997bfbdfba1007d90736c126b6b720 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Mon, 14 Aug 2023 15:03:39 +0200 Subject: [PATCH 0813/1212] docs: add v0.23.md --- CHANGELOG.md | 1 + docs/changelogs/v0.23.md | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 docs/changelogs/v0.23.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 0138eb231..f15248cc1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ # Kubo Changelogs +- [v0.23](docs/changelogs/v0.23.md) - [v0.22](docs/changelogs/v0.22.md) - [v0.21](docs/changelogs/v0.21.md) - [v0.20](docs/changelogs/v0.20.md) diff --git a/docs/changelogs/v0.23.md b/docs/changelogs/v0.23.md new file mode 100644 index 000000000..5b43d6096 --- /dev/null +++ b/docs/changelogs/v0.23.md @@ -0,0 +1,19 @@ +# Kubo changelog v0.23 + +- [v0.23.0](#v0230) + +## v0.23.0 + +- [Overview](#overview) +- [🔦 Highlights](#-highlights) +- [📝 Changelog](#-changelog) +- [👨‍👩‍👧‍👦 Contributors](#-contributors) + +### Overview + +### 🔦 Highlights + +### 📝 Changelog + +### 👨‍👩‍👧‍👦 Contributors + From 0c57a4f6229b73ecd69d7a3354aa33367aa1d201 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Mon, 14 Aug 2023 15:45:36 +0200 Subject: [PATCH 0814/1212] docs(readme): minimal reqs (#10066) --- README.md | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index c511de3e6..9cdb87429 100644 --- a/README.md +++ b/README.md @@ -47,8 +47,8 @@ Before opening an issue, consider using one of the following locations to ensure - [Next milestones](#next-milestones) - [Table of Contents](#table-of-contents) - [Security Issues](#security-issues) +- [Minimal System Requirements](#minimal-system-requirements) - [Install](#install) - - [System Requirements](#system-requirements) - [Docker](#docker) - [Official prebuilt binaries](#official-prebuilt-binaries) - [Updating](#updating) @@ -93,19 +93,14 @@ Before opening an issue, consider using one of the following locations to ensure Please follow [`SECURITY.md`](SECURITY.md). +### Minimal System Requirements + +IPFS can run on most Linux, macOS, and Windows systems. We recommend running it on a machine with at least 4 GB of RAM and 2 CPU cores (kubo is highly parallel). On systems with less memory, it may not be completely stable, and you run on your own risk. + ## Install The canonical download instructions for IPFS are over at: https://docs.ipfs.tech/install/. It is **highly recommended** you follow those instructions if you are not interested in working on IPFS development. -### System Requirements - -IPFS can run on most Linux, macOS, and Windows systems. We recommend running it on a machine with at least 2 GB of RAM and 2 CPU cores (kubo is highly parallel). On systems with less memory, it may not be completely stable. - -If your system is resource-constrained, we recommend: - -1. Installing OpenSSL and rebuilding kubo manually with `make build GOTAGS=openssl`. See the [download and compile](#download-and-compile-ipfs) section for more information on compiling kubo. -2. Initializing your daemon with `ipfs init --profile=lowpower` - ### Docker Official images are published at https://hub.docker.com/r/ipfs/kubo/: From 7220409394005c85509448217686e79b1779554b Mon Sep 17 00:00:00 2001 From: Jorropo Date: Thu, 9 Feb 2023 16:43:12 +0100 Subject: [PATCH 0815/1212] feat: remove Mplex Mplex does not implement backpressure, our implementation will randomly reset streams if buffers overflow instead of risking deadlocks. In the past we had a bug where kubo nodes would prefer mplex over yamux. Turning off mplex make our connections to thoses nodes negociate yamux. Closes #9958 --- core/node/libp2p/smux.go | 48 +++++--------------------- docs/changelogs/v0.23.md | 11 +++++- docs/config.md | 24 +++++-------- docs/examples/kubo-as-a-library/go.mod | 1 - docs/examples/kubo-as-a-library/go.sum | 2 -- go.mod | 1 - go.sum | 2 -- test/cli/transports_test.go | 12 ------- 8 files changed, 27 insertions(+), 74 deletions(-) diff --git a/core/node/libp2p/smux.go b/core/node/libp2p/smux.go index c906b6e02..04a3f2b4e 100644 --- a/core/node/libp2p/smux.go +++ b/core/node/libp2p/smux.go @@ -3,13 +3,11 @@ package libp2p import ( "fmt" "os" - "strings" "github.com/ipfs/kubo/config" "github.com/libp2p/go-libp2p" "github.com/libp2p/go-libp2p/core/network" - "github.com/libp2p/go-libp2p/p2p/muxer/mplex" "github.com/libp2p/go-libp2p/p2p/muxer/yamux" ) @@ -23,45 +21,17 @@ func yamuxTransport() network.Multiplexer { } func makeSmuxTransportOption(tptConfig config.Transports) (libp2p.Option, error) { - const yamuxID = "/yamux/1.0.0" - const mplexID = "/mplex/6.7.0" - if prefs := os.Getenv("LIBP2P_MUX_PREFS"); prefs != "" { - // Using legacy LIBP2P_MUX_PREFS variable. - log.Error("LIBP2P_MUX_PREFS is now deprecated.") - log.Error("Use the `Swarm.Transports.Multiplexers' config field.") - muxers := strings.Fields(prefs) - enabled := make(map[string]bool, len(muxers)) - - var opts []libp2p.Option - for _, tpt := range muxers { - if enabled[tpt] { - return nil, fmt.Errorf( - "duplicate muxer found in LIBP2P_MUX_PREFS: %s", - tpt, - ) - } - switch tpt { - case yamuxID: - opts = append(opts, libp2p.Muxer(tpt, yamuxTransport())) - case mplexID: - opts = append(opts, libp2p.Muxer(tpt, mplex.DefaultTransport)) - default: - return nil, fmt.Errorf("unknown muxer: %s", tpt) - } - } - return libp2p.ChainOptions(opts...), nil - } else { - return prioritizeOptions([]priorityOption{{ - priority: tptConfig.Multiplexers.Yamux, - defaultPriority: 100, - opt: libp2p.Muxer(yamuxID, yamuxTransport()), - }, { - priority: tptConfig.Multiplexers.Mplex, - defaultPriority: 200, - opt: libp2p.Muxer(mplexID, mplex.DefaultTransport), - }}), nil + return nil, fmt.Errorf("configuring muxers with LIBP2P_MUX_PREFS is no longer supported") } + if tptConfig.Multiplexers.Mplex != 0 { + return nil, fmt.Errorf("Swarm.Transports.Multiplexers.Mplex is no longer supported") + } + if tptConfig.Multiplexers.Yamux < 0 { + return nil, fmt.Errorf("Swarm.Transports.Multiplexers.Yamux is disabled even tho it is the only multiplexer available") + } + + return libp2p.Muxer(yamux.ID, yamuxTransport()), nil } func SmuxTransport(tptConfig config.Transports) func() (opts Libp2pOpts, err error) { diff --git a/docs/changelogs/v0.23.md b/docs/changelogs/v0.23.md index 5b43d6096..79fbc54cf 100644 --- a/docs/changelogs/v0.23.md +++ b/docs/changelogs/v0.23.md @@ -6,6 +6,7 @@ - [Overview](#overview) - [🔦 Highlights](#-highlights) + - [Mplex removal](#mplex-removal) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -13,7 +14,15 @@ ### 🔦 Highlights +#### Mplex removal + +Support for Mplex was removed, this is because it is unreliable and would +randomly drop streams when sending data too fast. + +New pieces of code rely on backpressure, that means the stream will dynamicaly +slow down the sending rate if data is getting backed up. +Backpressure is provided by Yamux and QUIC. + ### 📝 Changelog ### 👨‍👩‍👧‍👦 Contributors - diff --git a/docs/config.md b/docs/config.md index b7e21e12a..a31ff17b7 100644 --- a/docs/config.md +++ b/docs/config.md @@ -2052,6 +2052,8 @@ Type: `flag` Configuration section for libp2p _security_ transports. Transports enabled in this section will be used to secure unencrypted connections. +This does not concern all the QUIC transports which use QUIC's builtin encryption. + Security transports are configured with the `priority` type. When establishing an _outbound_ connection, Kubo will try each security @@ -2094,11 +2096,13 @@ Type: `priority` Configuration section for libp2p _multiplexer_ transports. Transports enabled in this section will be used to multiplex duplex connections. -Multiplexer transports are secured the same way security transports are, with +This does not concern all the QUIC transports which use QUIC's builtin muxing. + +Multiplexer transports are configured the same way security transports are, with the `priority` type. Like with security transports, the initiator gets their first choice. -Supported transports are: Yamux (priority 100) and Mplex (priority 200) +Supported transport is only: Yamux (priority 100) No default priority will ever be less than 100. @@ -2112,21 +2116,9 @@ Type: `priority` ### `Swarm.Transports.Multiplexers.Mplex` -Mplex is the default multiplexer used when communicating between Kubo and all -other IPFS and libp2p implementations. Unlike Yamux: +**DEPRECATED**: See https://github.com/ipfs/kubo/issues/9958 -* Mplex is a simpler protocol. -* Mplex is more efficient. -* Mplex does not have built-in keepalives. -* Mplex does not support backpressure. Unfortunately, this means that, if a - single stream to a peer gets backed up for a period of time, the mplex - transport will kill the stream to allow the others to proceed. On the other - hand, the lack of backpressure means mplex can be significantly faster on some - high-latency connections. - -Default: `200` - -Type: `priority` +Support for Mplex has been removed. Please remove this option from your config. ## `DNS` diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 5cc1054a2..804b3d17b 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -110,7 +110,6 @@ require ( github.com/libp2p/go-libp2p-record v0.2.0 // indirect github.com/libp2p/go-libp2p-routing-helpers v0.7.1 // indirect github.com/libp2p/go-libp2p-xor v0.1.0 // indirect - github.com/libp2p/go-mplex v0.7.0 // indirect github.com/libp2p/go-msgio v0.3.0 // indirect github.com/libp2p/go-nat v0.2.0 // indirect github.com/libp2p/go-netroute v0.2.1 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 3213c24eb..ae65f1eb6 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -482,8 +482,6 @@ github.com/libp2p/go-libp2p-routing-helpers v0.7.1/go.mod h1:cHStPSRC/wgbfpb5jYd github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA= github.com/libp2p/go-libp2p-xor v0.1.0 h1:hhQwT4uGrBcuAkUGXADuPltalOdpf9aag9kaYNT2tLA= github.com/libp2p/go-libp2p-xor v0.1.0/go.mod h1:LSTM5yRnjGZbWNTA/hRwq2gGFrvRIbQJscoIL/u6InY= -github.com/libp2p/go-mplex v0.7.0 h1:BDhFZdlk5tbr0oyFq/xv/NPGfjbnrsDam1EvutpBDbY= -github.com/libp2p/go-mplex v0.7.0/go.mod h1:rW8ThnRcYWft/Jb2jeORBmPd6xuG3dGxWN/W168L9EU= github.com/libp2p/go-msgio v0.0.4/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= github.com/libp2p/go-msgio v0.3.0 h1:mf3Z8B1xcFN314sWX+2vOTShIE0Mmn2TXn3YCUQGNj0= github.com/libp2p/go-msgio v0.3.0/go.mod h1:nyRM819GmVaF9LX3l03RMh10QdOroF++NBbxAb0mmDM= diff --git a/go.mod b/go.mod index d730dd2f3..8885a0089 100644 --- a/go.mod +++ b/go.mod @@ -158,7 +158,6 @@ require ( github.com/libp2p/go-libp2p-asn-util v0.3.0 // indirect github.com/libp2p/go-libp2p-gostream v0.6.0 // indirect github.com/libp2p/go-libp2p-xor v0.1.0 // indirect - github.com/libp2p/go-mplex v0.7.0 // indirect github.com/libp2p/go-msgio v0.3.0 // indirect github.com/libp2p/go-nat v0.2.0 // indirect github.com/libp2p/go-netroute v0.2.1 // indirect diff --git a/go.sum b/go.sum index 22b6ea3cf..c6e2e4b52 100644 --- a/go.sum +++ b/go.sum @@ -545,8 +545,6 @@ github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUI github.com/libp2p/go-libp2p-testing v0.12.0/go.mod h1:KcGDRXyN7sQCllucn1cOOS+Dmm7ujhfEyXQL5lvkcPg= github.com/libp2p/go-libp2p-xor v0.1.0 h1:hhQwT4uGrBcuAkUGXADuPltalOdpf9aag9kaYNT2tLA= github.com/libp2p/go-libp2p-xor v0.1.0/go.mod h1:LSTM5yRnjGZbWNTA/hRwq2gGFrvRIbQJscoIL/u6InY= -github.com/libp2p/go-mplex v0.7.0 h1:BDhFZdlk5tbr0oyFq/xv/NPGfjbnrsDam1EvutpBDbY= -github.com/libp2p/go-mplex v0.7.0/go.mod h1:rW8ThnRcYWft/Jb2jeORBmPd6xuG3dGxWN/W168L9EU= github.com/libp2p/go-msgio v0.0.4/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= github.com/libp2p/go-msgio v0.3.0 h1:mf3Z8B1xcFN314sWX+2vOTShIE0Mmn2TXn3YCUQGNj0= github.com/libp2p/go-msgio v0.3.0/go.mod h1:nyRM819GmVaF9LX3l03RMh10QdOroF++NBbxAb0mmDM= diff --git a/test/cli/transports_test.go b/test/cli/transports_test.go index 3a7b5ed93..601f85892 100644 --- a/test/cli/transports_test.go +++ b/test/cli/transports_test.go @@ -71,18 +71,6 @@ func TestTransports(t *testing.T) { runTests(nodes) }) - t.Run("tcp with mplex", func(t *testing.T) { - t.Parallel() - nodes := tcpNodes(t) - nodes.ForEachPar(func(n *harness.Node) { - n.UpdateConfig(func(cfg *config.Config) { - cfg.Swarm.Transports.Multiplexers.Yamux = config.Disabled - }) - }) - nodes.StartDaemons().Connect() - runTests(nodes) - }) - t.Run("tcp with NOISE", func(t *testing.T) { t.Parallel() nodes := tcpNodes(t) From f805b9fcda91d7f0ab11f930c30ab10a17fd048d Mon Sep 17 00:00:00 2001 From: Jorropo Date: Tue, 15 Aug 2023 14:29:40 +0200 Subject: [PATCH 0816/1212] feat: allow users to optin again into mplex This is a partial revert of 7220409394005c85509448217686e79b1779554b. Closes #9958 --- config/swarm.go | 2 +- core/node/libp2p/smux.go | 55 +++++++++++++++++--------- docs/changelogs/v0.23.md | 19 ++++++--- docs/config.md | 14 ++++++- docs/examples/kubo-as-a-library/go.mod | 1 + docs/examples/kubo-as-a-library/go.sum | 2 + go.mod | 1 + go.sum | 2 + test/cli/transports_test.go | 14 +++++++ 9 files changed, 84 insertions(+), 26 deletions(-) diff --git a/config/swarm.go b/config/swarm.go index d7e40e27c..cbd46e5e1 100644 --- a/config/swarm.go +++ b/config/swarm.go @@ -122,7 +122,7 @@ type Transports struct { Multiplexers struct { // Defaults to 100. Yamux Priority `json:",omitempty"` - // Defaults to 200. + // Defaults to -1. Mplex Priority `json:",omitempty"` } } diff --git a/core/node/libp2p/smux.go b/core/node/libp2p/smux.go index 04a3f2b4e..0777928a8 100644 --- a/core/node/libp2p/smux.go +++ b/core/node/libp2p/smux.go @@ -3,35 +3,52 @@ package libp2p import ( "fmt" "os" + "strings" "github.com/ipfs/kubo/config" "github.com/libp2p/go-libp2p" - "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/p2p/muxer/mplex" "github.com/libp2p/go-libp2p/p2p/muxer/yamux" ) -func yamuxTransport() network.Multiplexer { - tpt := *yamux.DefaultTransport - tpt.AcceptBacklog = 512 - if os.Getenv("YAMUX_DEBUG") != "" { - tpt.LogOutput = os.Stderr - } - return &tpt -} - func makeSmuxTransportOption(tptConfig config.Transports) (libp2p.Option, error) { if prefs := os.Getenv("LIBP2P_MUX_PREFS"); prefs != "" { - return nil, fmt.Errorf("configuring muxers with LIBP2P_MUX_PREFS is no longer supported") - } - if tptConfig.Multiplexers.Mplex != 0 { - return nil, fmt.Errorf("Swarm.Transports.Multiplexers.Mplex is no longer supported") - } - if tptConfig.Multiplexers.Yamux < 0 { - return nil, fmt.Errorf("Swarm.Transports.Multiplexers.Yamux is disabled even tho it is the only multiplexer available") - } + // Using legacy LIBP2P_MUX_PREFS variable. + log.Error("LIBP2P_MUX_PREFS is now deprecated.") + log.Error("Use the `Swarm.Transports.Multiplexers' config field.") + muxers := strings.Fields(prefs) + enabled := make(map[string]bool, len(muxers)) - return libp2p.Muxer(yamux.ID, yamuxTransport()), nil + var opts []libp2p.Option + for _, tpt := range muxers { + if enabled[tpt] { + return nil, fmt.Errorf( + "duplicate muxer found in LIBP2P_MUX_PREFS: %s", + tpt, + ) + } + switch tpt { + case yamux.ID: + opts = append(opts, libp2p.Muxer(tpt, yamux.DefaultTransport)) + case mplex.ID: + opts = append(opts, libp2p.Muxer(tpt, mplex.DefaultTransport)) + default: + return nil, fmt.Errorf("unknown muxer: %s", tpt) + } + } + return libp2p.ChainOptions(opts...), nil + } else { + return prioritizeOptions([]priorityOption{{ + priority: tptConfig.Multiplexers.Yamux, + defaultPriority: 100, + opt: libp2p.Muxer(yamux.ID, yamux.DefaultTransport), + }, { + priority: tptConfig.Multiplexers.Mplex, + defaultPriority: config.Disabled, + opt: libp2p.Muxer(mplex.ID, mplex.DefaultTransport), + }}), nil + } } func SmuxTransport(tptConfig config.Transports) func() (opts Libp2pOpts, err error) { diff --git a/docs/changelogs/v0.23.md b/docs/changelogs/v0.23.md index 79fbc54cf..a53639d88 100644 --- a/docs/changelogs/v0.23.md +++ b/docs/changelogs/v0.23.md @@ -6,7 +6,7 @@ - [Overview](#overview) - [🔦 Highlights](#-highlights) - - [Mplex removal](#mplex-removal) + - [Mplex deprecation](#mplex-deprecation) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -14,14 +14,23 @@ ### 🔦 Highlights -#### Mplex removal +#### Mplex deprecation -Support for Mplex was removed, this is because it is unreliable and would -randomly drop streams when sending data too fast. +Mplex is being deprecated, this is because it is unreliable and +randomly drop streams when sending data *too fast*. New pieces of code rely on backpressure, that means the stream will dynamicaly slow down the sending rate if data is getting backed up. -Backpressure is provided by Yamux and QUIC. +Backpressure is provided by **Yamux** and **QUIC**. + +In case you need compatibility with older implementations that do not ship with +Yamux (like default's JS-IPFS) you can turned it back ON in the config with: +```console +$ ipfs config --json Swarm.Transports.Multiplexers.Mplex 200 +``` + +We will completely remove Mplex in v0.24 as it makes protocols very bad to implement, +if you are in this situation you need to add yamux support to your other implementation. ### 📝 Changelog diff --git a/docs/config.md b/docs/config.md index a31ff17b7..6b8b271b7 100644 --- a/docs/config.md +++ b/docs/config.md @@ -2118,7 +2118,19 @@ Type: `priority` **DEPRECATED**: See https://github.com/ipfs/kubo/issues/9958 -Support for Mplex has been removed. Please remove this option from your config. +Mplex is deprecated, this is because it is unreliable and +randomly drop streams when sending data *too fast*. + +New pieces of code rely on backpressure, that means the stream will dynamicaly +slow down the sending rate if data is getting backed up. +Backpressure is provided by **Yamux** and **QUIC**. + +If you want to turn it back on make sure to have a higher (lower is better) +priority than `Yamux`, you don't want your Kubo to start defaulting to Mplex. + +Default: `200` + +Type: `priority` ## `DNS` diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 804b3d17b..5cc1054a2 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -110,6 +110,7 @@ require ( github.com/libp2p/go-libp2p-record v0.2.0 // indirect github.com/libp2p/go-libp2p-routing-helpers v0.7.1 // indirect github.com/libp2p/go-libp2p-xor v0.1.0 // indirect + github.com/libp2p/go-mplex v0.7.0 // indirect github.com/libp2p/go-msgio v0.3.0 // indirect github.com/libp2p/go-nat v0.2.0 // indirect github.com/libp2p/go-netroute v0.2.1 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index ae65f1eb6..3213c24eb 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -482,6 +482,8 @@ github.com/libp2p/go-libp2p-routing-helpers v0.7.1/go.mod h1:cHStPSRC/wgbfpb5jYd github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA= github.com/libp2p/go-libp2p-xor v0.1.0 h1:hhQwT4uGrBcuAkUGXADuPltalOdpf9aag9kaYNT2tLA= github.com/libp2p/go-libp2p-xor v0.1.0/go.mod h1:LSTM5yRnjGZbWNTA/hRwq2gGFrvRIbQJscoIL/u6InY= +github.com/libp2p/go-mplex v0.7.0 h1:BDhFZdlk5tbr0oyFq/xv/NPGfjbnrsDam1EvutpBDbY= +github.com/libp2p/go-mplex v0.7.0/go.mod h1:rW8ThnRcYWft/Jb2jeORBmPd6xuG3dGxWN/W168L9EU= github.com/libp2p/go-msgio v0.0.4/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= github.com/libp2p/go-msgio v0.3.0 h1:mf3Z8B1xcFN314sWX+2vOTShIE0Mmn2TXn3YCUQGNj0= github.com/libp2p/go-msgio v0.3.0/go.mod h1:nyRM819GmVaF9LX3l03RMh10QdOroF++NBbxAb0mmDM= diff --git a/go.mod b/go.mod index 8885a0089..d730dd2f3 100644 --- a/go.mod +++ b/go.mod @@ -158,6 +158,7 @@ require ( github.com/libp2p/go-libp2p-asn-util v0.3.0 // indirect github.com/libp2p/go-libp2p-gostream v0.6.0 // indirect github.com/libp2p/go-libp2p-xor v0.1.0 // indirect + github.com/libp2p/go-mplex v0.7.0 // indirect github.com/libp2p/go-msgio v0.3.0 // indirect github.com/libp2p/go-nat v0.2.0 // indirect github.com/libp2p/go-netroute v0.2.1 // indirect diff --git a/go.sum b/go.sum index c6e2e4b52..22b6ea3cf 100644 --- a/go.sum +++ b/go.sum @@ -545,6 +545,8 @@ github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUI github.com/libp2p/go-libp2p-testing v0.12.0/go.mod h1:KcGDRXyN7sQCllucn1cOOS+Dmm7ujhfEyXQL5lvkcPg= github.com/libp2p/go-libp2p-xor v0.1.0 h1:hhQwT4uGrBcuAkUGXADuPltalOdpf9aag9kaYNT2tLA= github.com/libp2p/go-libp2p-xor v0.1.0/go.mod h1:LSTM5yRnjGZbWNTA/hRwq2gGFrvRIbQJscoIL/u6InY= +github.com/libp2p/go-mplex v0.7.0 h1:BDhFZdlk5tbr0oyFq/xv/NPGfjbnrsDam1EvutpBDbY= +github.com/libp2p/go-mplex v0.7.0/go.mod h1:rW8ThnRcYWft/Jb2jeORBmPd6xuG3dGxWN/W168L9EU= github.com/libp2p/go-msgio v0.0.4/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= github.com/libp2p/go-msgio v0.3.0 h1:mf3Z8B1xcFN314sWX+2vOTShIE0Mmn2TXn3YCUQGNj0= github.com/libp2p/go-msgio v0.3.0/go.mod h1:nyRM819GmVaF9LX3l03RMh10QdOroF++NBbxAb0mmDM= diff --git a/test/cli/transports_test.go b/test/cli/transports_test.go index 601f85892..73f08c2e5 100644 --- a/test/cli/transports_test.go +++ b/test/cli/transports_test.go @@ -71,6 +71,20 @@ func TestTransports(t *testing.T) { runTests(nodes) }) + t.Run("tcp with mplex", func(t *testing.T) { + // FIXME(#10069): we don't want this to exists anymore + t.Parallel() + nodes := tcpNodes(t) + nodes.ForEachPar(func(n *harness.Node) { + n.UpdateConfig(func(cfg *config.Config) { + cfg.Swarm.Transports.Multiplexers.Yamux = config.Disabled + cfg.Swarm.Transports.Multiplexers.Mplex = 200 + }) + }) + nodes.StartDaemons().Connect() + runTests(nodes) + }) + t.Run("tcp with NOISE", func(t *testing.T) { t.Parallel() nodes := tcpNodes(t) From 3bcc89b78a5db0bd3a8761eca0c8cc2a92be7e54 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Tue, 15 Aug 2023 17:46:33 +0200 Subject: [PATCH 0817/1212] chore: remove deprecated testground plans --- .../bitswap/_compositions/large-k8s.toml | 32 - .../bitswap/_compositions/medium-k8s.toml | 33 - .../bitswap/_compositions/small-docker.toml | 30 - .../bitswap/_compositions/small-k8s.toml | 33 - testplans/bitswap/go.mod | 22 - testplans/bitswap/go.sum | 1230 ----------------- testplans/bitswap/main.go | 201 --- testplans/bitswap/manifest.toml | 19 - 8 files changed, 1600 deletions(-) delete mode 100644 testplans/bitswap/_compositions/large-k8s.toml delete mode 100644 testplans/bitswap/_compositions/medium-k8s.toml delete mode 100644 testplans/bitswap/_compositions/small-docker.toml delete mode 100644 testplans/bitswap/_compositions/small-k8s.toml delete mode 100644 testplans/bitswap/go.mod delete mode 100644 testplans/bitswap/go.sum delete mode 100644 testplans/bitswap/main.go delete mode 100644 testplans/bitswap/manifest.toml diff --git a/testplans/bitswap/_compositions/large-k8s.toml b/testplans/bitswap/_compositions/large-k8s.toml deleted file mode 100644 index fea91d000..000000000 --- a/testplans/bitswap/_compositions/large-k8s.toml +++ /dev/null @@ -1,32 +0,0 @@ -[metadata] - -[global] - plan = "bitswap" - case = "speed-test" - total_instances = 20 - builder = "docker:go" - runner = "cluster:k8s" - -[global.build_config] - push_registry=true - go_proxy_mode="remote" - go_proxy_url="http://localhost:8081" - registry_type="aws" - -[global.run.test_params] -size = "1MB" -count = "1000" - -[[groups]] - id = "providers" - instances = { count = 1 } - [groups.resources] - memory = "4096Mi" - cpu = "1000m" - -[[groups]] - id = "requestors" - instances = { count = 19 } - [groups.resources] - memory = "4096Mi" - cpu = "1000m" diff --git a/testplans/bitswap/_compositions/medium-k8s.toml b/testplans/bitswap/_compositions/medium-k8s.toml deleted file mode 100644 index 816d91fe4..000000000 --- a/testplans/bitswap/_compositions/medium-k8s.toml +++ /dev/null @@ -1,33 +0,0 @@ -[metadata] - name = "bitswap-medium-speed-test" - -[global] - plan = "bitswap" - case = "speed-test" - total_instances = 5 - builder = "docker:go" - runner = "cluster:k8s" - -[global.build_config] - push_registry=true - go_proxy_mode="remote" - go_proxy_url="http://localhost:8081" - registry_type="aws" - -[global.run.test_params] -size = "1MB" -count = "1000" - -[[groups]] - id = "providers" - instances = { count = 1 } - [groups.resources] - memory = "4096Mi" - cpu = "1000m" - -[[groups]] - id = "requestors" - instances = { count = 4 } - [groups.resources] - memory = "4096Mi" - cpu = "1000m" diff --git a/testplans/bitswap/_compositions/small-docker.toml b/testplans/bitswap/_compositions/small-docker.toml deleted file mode 100644 index b0e9f96ae..000000000 --- a/testplans/bitswap/_compositions/small-docker.toml +++ /dev/null @@ -1,30 +0,0 @@ -[metadata] - name = "bitswap-local-speed-test" - -[global] - plan = "bitswap" - case = "speed-test" - total_instances = 2 - builder = "docker:go" - runner = "local:docker" - -[global.build_config] - push_registry=false - -[global.run.test_params] -size = "1MB" -count = "1000" - -[[groups]] - id = "providers" - instances = { count = 1 } - [groups.resources] - memory = "4096Mi" - cpu = "1000m" - -[[groups]] - id = "requestors" - instances = { count = 1 } - [groups.resources] - memory = "4096Mi" - cpu = "1000m" diff --git a/testplans/bitswap/_compositions/small-k8s.toml b/testplans/bitswap/_compositions/small-k8s.toml deleted file mode 100644 index 3f454412d..000000000 --- a/testplans/bitswap/_compositions/small-k8s.toml +++ /dev/null @@ -1,33 +0,0 @@ -[metadata] - name = "bitswap-small-speed-test" - -[global] - plan = "bitswap" - case = "speed-test" - total_instances = 2 - builder = "docker:go" - runner = "cluster:k8s" - -[global.build_config] - push_registry=true - go_proxy_mode="remote" - go_proxy_url="http://localhost:8081" - registry_type="aws" - -[global.run.test_params] -size = "1MB" -count = "1000" - -[[groups]] - id = "providers" - instances = { count = 1 } - [groups.resources] - memory = "4096Mi" - cpu = "1000m" - -[[groups]] - id = "requestors" - instances = { count = 1 } - [groups.resources] - memory = "4096Mi" - cpu = "1000m" diff --git a/testplans/bitswap/go.mod b/testplans/bitswap/go.mod deleted file mode 100644 index 79925df14..000000000 --- a/testplans/bitswap/go.mod +++ /dev/null @@ -1,22 +0,0 @@ -module github.com/ipfs/go-ipfs/testplans/bitswap - -require ( - github.com/gopherjs/gopherjs v0.0.0-20190812055157-5d271430af9f // indirect - github.com/ipfs/go-cid v0.3.2 - github.com/ipfs/go-datastore v0.6.0 - github.com/ipfs/go-ipfs-blockstore v1.2.0 - github.com/ipfs/go-ipfs-exchange-interface v0.2.0 - github.com/ipfs/go-ipfs-regression v0.0.1 - github.com/ipfs/go-libipfs v0.4.0 - github.com/ipld/go-ipld-prime v0.9.1-0.20210324083106-dc342a9917db // indirect - github.com/libp2p/go-libp2p v0.23.4 - github.com/libp2p/go-libp2p-kad-dht v0.18.0 - github.com/multiformats/go-multiaddr v0.8.0 - github.com/multiformats/go-multihash v0.2.1 - github.com/polydawn/refmt v0.0.0-20201211092308-30ac6d18308e // indirect - github.com/smartystreets/assertions v1.0.1 // indirect - github.com/testground/sdk-go v0.2.7 - golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5 // indirect -) - -go 1.15 diff --git a/testplans/bitswap/go.sum b/testplans/bitswap/go.sum deleted file mode 100644 index 5cb07e8c0..000000000 --- a/testplans/bitswap/go.sum +++ /dev/null @@ -1,1230 +0,0 @@ -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.31.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.37.0/go.mod h1:TS1dMSSfndXH133OKGwekG838Om/cQT0BUHV3HcBgoo= -cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= -cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= -cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= -cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= -cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= -cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= -cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= -cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= -cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= -cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= -cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= -cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= -cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= -cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= -cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= -cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= -cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= -cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= -cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= -cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= -cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= -cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= -cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= -cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= -cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= -cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= -cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= -cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU= -dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU= -dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4= -dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU= -git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg= -github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= -github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= -github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= -github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/avast/retry-go v2.6.0+incompatible h1:FelcMrm7Bxacr1/RM8+/eqkDkmVN7tjlsy51dOzB3LI= -github.com/avast/retry-go v2.6.0+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY= -github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= -github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= -github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= -github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= -github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= -github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= -github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= -github.com/btcsuite/btcd v0.0.0-20190824003749-130ea5bddde3/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= -github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= -github.com/btcsuite/btcd v0.22.1/go.mod h1:wqgTSL29+50LRkmOVknEdmt8ZojIzhuWvgu/iptuN7Y= -github.com/btcsuite/btcd/btcec/v2 v2.1.3/go.mod h1:ctjw4H1kknNJmRN4iP1R7bTQ+v3GJkZBd6mui8ZsAZE= -github.com/btcsuite/btcd/chaincfg/chainhash v1.0.0/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= -github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= -github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= -github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= -github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce/go.mod h1:0DVlHczLPewLcPGEIeUEzfOJhqGPQ0mJJRDBtD307+o= -github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= -github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= -github.com/btcsuite/goleveldb v1.0.0/go.mod h1:QiK9vBlgftBg6rWQIj6wFzbPfRjiykIEhBH4obrXJ/I= -github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= -github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= -github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= -github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= -github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= -github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= -github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= -github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= -github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cheekybits/genny v1.0.0/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ= -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/cilium/ebpf v0.4.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= -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= -github.com/containerd/cgroups v0.0.0-20201119153540-4cbc285b3327/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE= -github.com/containerd/cgroups v1.0.4 h1:jN/mbWBEaz+T1pi5OFtnkQ+8qnmEbAr1Oo1FRm5B0dA= -github.com/containerd/cgroups v1.0.4/go.mod h1:nLNQtsF7Sl2HxNebu77i1R0oDlhiTG+kO4JTrUzo6IA= -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= -github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -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.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= -github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -github.com/coreos/go-systemd/v22 v22.4.0 h1:y9YHcjnjynCd/DVbg5j9L/33jQM3MxJlbj/zWskzfGU= -github.com/coreos/go-systemd/v22 v22.4.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -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/go.mod h1:p1d6YEZWvFzEh4KLyvBcVSnrfNDDvK2zfK/4x2v/4pE= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/cskr/pubsub v1.0.2 h1:vlOzMhl6PFn60gRlTQQsIfVwaPB/B/8MziK8FhEPt/0= -github.com/cskr/pubsub v1.0.2/go.mod h1:/8MzYXk/NJAz782G8RPkFzXTZVu63VotefPnR9TIRis= -github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c h1:pFUpOrbxDR6AkioZ1ySsx5yxlDQZ8stG2b88gTPxgJU= -github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c/go.mod h1:6UhI8N9EjYm1c2odKpFpAYeR8dsBeM7PtzQhRgxRr9U= -github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= -github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 h1:HbphB4TFFXpv7MNrT52FGrrgVXF1owhMVTHFZIlnvd4= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0/go.mod h1:DZGJHZMqrU4JJqFAWUS2UO1+lbSKsdiOoYi9Zzey7Fc= -github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= -github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= -github.com/dgraph-io/badger v1.6.1/go.mod h1:FRmFw3uxvcpa8zG3Rxs0th+hCLIuaQg8HlNV5bjgnuU= -github.com/dgraph-io/badger v1.6.2/go.mod h1:JW2yswe3V058sS0kZ2h/AXeDSqFjxnZcRrVH//y2UQE= -github.com/dgraph-io/ristretto v0.0.2/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= -github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= -github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= -github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= -github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/elastic/gosigar v0.12.0/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= -github.com/elastic/gosigar v0.14.2 h1:Dg80n8cr90OZ7x+bAax/QjoW/XqTI11RmA79ZwIm9/4= -github.com/elastic/gosigar v0.14.2/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= -github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= -github.com/flynn/noise v1.0.0 h1:DlTHqmzmvcEiKj+4RYo/imoswx/4r6iBlCMfVtrMXpQ= -github.com/flynn/noise v1.0.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag= -github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk= -github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= -github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI= -github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= -github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= -github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= -github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= -github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= -github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= -github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= -github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= -github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= -github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= -github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-redis/redis/v7 v7.4.0 h1:7obg6wUoj05T0EpY0o8B59S9w5yeMWql7sw2kwNW1x4= -github.com/go-redis/redis/v7 v7.4.0/go.mod h1:JDNMw23GTyLNC4GZu9njt15ctBQVn7xjRfnwdHj/Dcg= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -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/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= -github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= -github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= -github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= -github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= -github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY= -github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= -github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= -github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= -github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -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= -github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= -github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= -github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= -github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/gopacket v1.1.17/go.mod h1:UdDNZ1OO62aGYVnPhxT1U6aI7ukYtA/kB8vaU0diBUM= -github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= -github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= -github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= -github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg= -github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gopherjs/gopherjs v0.0.0-20190812055157-5d271430af9f h1:KMlcu9X58lhTA/KrfX8Bi1LQSO4pzoVjTiL3h4Jk+Zk= -github.com/gopherjs/gopherjs v0.0.0-20190812055157-5d271430af9f/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= -github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= -github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= -github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= -github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= -github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= -github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= -github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= -github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= -github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= -github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= -github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= -github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= -github.com/huin/goupnp v1.0.3 h1:N8No57ls+MnjlB+JPiCVSOyy/ot7MJTqlo7rn+NYSqQ= -github.com/huin/goupnp v1.0.3/go.mod h1:ZxNlw5WqJj6wSsRK5+YfflQGXYfccj5VgQsMNixHM7Y= -github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= -github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/influxdata/influxdb1-client v0.0.0-20200515024757-02f0bf5dbca3 h1:k3/6a1Shi7GGCp9QpyYuXsMM6ncTOjCzOE9Fd6CDA+Q= -github.com/influxdata/influxdb1-client v0.0.0-20200515024757-02f0bf5dbca3/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= -github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= -github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= -github.com/ipfs/go-block-format v0.0.3/go.mod h1:4LmD4ZUw0mhO+JSKdpWwrzATiEfM7WWgQ8H5l6P8MVk= -github.com/ipfs/go-block-format v0.1.1 h1:129vSO3zwbsYADcyQWcOYiuCpAqt462SFfqFHdFJhhI= -github.com/ipfs/go-block-format v0.1.1/go.mod h1:+McEIT+g52p+zz5xGAABGSOKrzmrdX97bc0USBdWPUs= -github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= -github.com/ipfs/go-cid v0.0.2/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= -github.com/ipfs/go-cid v0.0.3/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= -github.com/ipfs/go-cid v0.0.4/go.mod h1:4LLaPOQwmk5z9LBgQnpkivrx8BJjUyGwTXCd5Xfj6+M= -github.com/ipfs/go-cid v0.0.5/go.mod h1:plgt+Y5MnOey4vO4UlUazGqdbEXuFYitED67FexhXog= -github.com/ipfs/go-cid v0.0.7/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I= -github.com/ipfs/go-cid v0.2.0/go.mod h1:P+HXFDF4CVhaVayiEb4wkAy7zBHxBwsJyt0Y5U6MLro= -github.com/ipfs/go-cid v0.3.2 h1:OGgOd+JCFM+y1DjWPmVH+2/4POtpDzwcr7VgnB7mZXc= -github.com/ipfs/go-cid v0.3.2/go.mod h1:gQ8pKqT/sUxGY+tIwy1RPpAojYu7jAyCp5Tz1svoupw= -github.com/ipfs/go-datastore v0.1.0/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= -github.com/ipfs/go-datastore v0.1.1/go.mod h1:w38XXW9kVFNp57Zj5knbKWM2T+KOZCGDRVNdgPHtbHw= -github.com/ipfs/go-datastore v0.4.1/go.mod h1:SX/xMIKoCszPqp+z9JhPYCmoOoXTvaa13XEbGtsFUhA= -github.com/ipfs/go-datastore v0.4.4/go.mod h1:SX/xMIKoCszPqp+z9JhPYCmoOoXTvaa13XEbGtsFUhA= -github.com/ipfs/go-datastore v0.5.0/go.mod h1:9zhEApYMTl17C8YDp7JmU7sQZi2/wqiYh73hakZ90Bk= -github.com/ipfs/go-datastore v0.5.1/go.mod h1:9zhEApYMTl17C8YDp7JmU7sQZi2/wqiYh73hakZ90Bk= -github.com/ipfs/go-datastore v0.6.0 h1:JKyz+Gvz1QEZw0LsX1IBn+JFCJQH4SJVFtM4uWU0Myk= -github.com/ipfs/go-datastore v0.6.0/go.mod h1:rt5M3nNbSO/8q1t4LNkLyUwRs8HupMeN/8O4Vn9YAT8= -github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk= -github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps= -github.com/ipfs/go-ds-badger v0.0.7/go.mod h1:qt0/fWzZDoPW6jpQeqUjR5kBfhDNB65jd9YlmAvpQBk= -github.com/ipfs/go-ds-badger v0.2.3/go.mod h1:pEYw0rgg3FIrywKKnL+Snr+w/LjJZVMTBRn4FS6UHUk= -github.com/ipfs/go-ds-badger v0.3.0/go.mod h1:1ke6mXNqeV8K3y5Ak2bAA0osoTfmxUdupVCGm4QUIek= -github.com/ipfs/go-ds-leveldb v0.1.0/go.mod h1:hqAW8y4bwX5LWcCtku2rFNX3vjDZCy5LZCg+cSZvYb8= -github.com/ipfs/go-ds-leveldb v0.4.2/go.mod h1:jpbku/YqBSsBc1qgME8BkWS4AxzF2cEu1Ii2r79Hh9s= -github.com/ipfs/go-ds-leveldb v0.5.0/go.mod h1:d3XG9RUDzQ6V4SHi8+Xgj9j1XuEk1z82lquxrVbml/Q= -github.com/ipfs/go-ipfs-blockstore v1.2.0 h1:n3WTeJ4LdICWs/0VSfjHrlqpPpl6MZ+ySd3j8qz0ykw= -github.com/ipfs/go-ipfs-blockstore v1.2.0/go.mod h1:eh8eTFLiINYNSNawfZOC7HOxNTxpB1PFuA5E1m/7exE= -github.com/ipfs/go-ipfs-blocksutil v0.0.1 h1:Eh/H4pc1hsvhzsQoMEP3Bke/aW5P5rVM1IWFJMcGIPQ= -github.com/ipfs/go-ipfs-blocksutil v0.0.1/go.mod h1:Yq4M86uIOmxmGPUHv/uI7uKqZNtLb449gwKqXjIsnRk= -github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= -github.com/ipfs/go-ipfs-delay v0.0.1 h1:r/UXYyRcddO6thwOnhiznIAiSvxMECGgtv35Xs1IeRQ= -github.com/ipfs/go-ipfs-delay v0.0.1/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= -github.com/ipfs/go-ipfs-ds-help v1.1.0 h1:yLE2w9RAsl31LtfMt91tRZcrx+e61O5mDxFRR994w4Q= -github.com/ipfs/go-ipfs-ds-help v1.1.0/go.mod h1:YR5+6EaebOhfcqVCyqemItCLthrpVNot+rsOU/5IatU= -github.com/ipfs/go-ipfs-exchange-interface v0.2.0 h1:8lMSJmKogZYNo2jjhUs0izT+dck05pqUw4mWNW9Pw6Y= -github.com/ipfs/go-ipfs-exchange-interface v0.2.0/go.mod h1:z6+RhJuDQbqKguVyslSOuVDhqF9JtTrO3eptSAiW2/Y= -github.com/ipfs/go-ipfs-pq v0.0.2 h1:e1vOOW6MuOwG2lqxcLA+wEn93i/9laCY8sXAw76jFOY= -github.com/ipfs/go-ipfs-pq v0.0.2/go.mod h1:LWIqQpqfRG3fNc5XsnIhz/wQ2XXGyugQwls7BgUmUfY= -github.com/ipfs/go-ipfs-regression v0.0.1 h1:LX3lrYYgiCE9QmL/qlc4Mh0cewdOHRl5pArbeQRllsU= -github.com/ipfs/go-ipfs-regression v0.0.1/go.mod h1:I9yKzBjbirC5D0ND0DBkiQ5PPSQ2R2YjhcqHPj8L28A= -github.com/ipfs/go-ipfs-routing v0.3.0 h1:9W/W3N+g+y4ZDeffSgqhgo7BsBSJwPMcyssET9OWevc= -github.com/ipfs/go-ipfs-routing v0.3.0/go.mod h1:dKqtTFIql7e1zYsEuWLyuOU+E0WJWW8JjbTPLParDWo= -github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyBCNzQxlJBc= -github.com/ipfs/go-ipfs-util v0.0.2 h1:59Sswnk1MFaiq+VcaknX7aYEyGyGDAA73ilhEK2POp8= -github.com/ipfs/go-ipfs-util v0.0.2/go.mod h1:CbPtkWJzjLdEcezDns2XYaehFVNXG9zrdrtMecczcsQ= -github.com/ipfs/go-ipld-format v0.3.0 h1:Mwm2oRLzIuUwEPewWAWyMuuBQUsn3awfFEYVb8akMOQ= -github.com/ipfs/go-ipld-format v0.3.0/go.mod h1:co/SdBE8h99968X0hViiw1MNlh6fvxxnHpvVLnH7jSM= -github.com/ipfs/go-ipns v0.2.0/go.mod h1:3cLT2rbvgPZGkHJoPO1YMJeh6LtkxopCkKFcio/wE24= -github.com/ipfs/go-ipns v0.3.0 h1:ai791nTgVo+zTuq2bLvEGmWP1M0A6kGTXUsgv/Yq67A= -github.com/ipfs/go-ipns v0.3.0/go.mod h1:3cLT2rbvgPZGkHJoPO1YMJeh6LtkxopCkKFcio/wE24= -github.com/ipfs/go-libipfs v0.3.0/go.mod h1:pSUHZ5qPJTAidsxe9bAeHp3KIiw2ODEW2a2kM3v+iXI= -github.com/ipfs/go-libipfs v0.4.0 h1:TkUxJGjtPnSzAgkw7VjS0/DBay3MPjmTBa4dGdUQCDE= -github.com/ipfs/go-libipfs v0.4.0/go.mod h1:XsU2cP9jBhDrXoJDe0WxikB8XcVmD3k2MEZvB3dbYu8= -github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= -github.com/ipfs/go-log v1.0.3/go.mod h1:OsLySYkwIbiSUR/yBTdv1qPtcE4FW3WPWk/ewz9Ru+A= -github.com/ipfs/go-log v1.0.4/go.mod h1:oDCg2FkjogeFOhqqb+N39l2RpTNPL6F/StPkB3kPgcs= -github.com/ipfs/go-log v1.0.5 h1:2dOuUCB1Z7uoczMWgAyDck5JLb72zHzrMnGnCNNbvY8= -github.com/ipfs/go-log v1.0.5/go.mod h1:j0b8ZoR+7+R99LD9jZ6+AJsrzkPbSXbZfGakb5JPtIo= -github.com/ipfs/go-log/v2 v2.0.3/go.mod h1:O7P1lJt27vWHhOwQmcFEvlmo49ry2VY2+JfBWFaa9+0= -github.com/ipfs/go-log/v2 v2.0.5/go.mod h1:eZs4Xt4ZUJQFM3DlanGhy7TkwwawCZcSByscwkWG+dw= -github.com/ipfs/go-log/v2 v2.1.3/go.mod h1:/8d0SH3Su5Ooc31QlL1WysJhvyOTDCjcCZ9Axpmri6g= -github.com/ipfs/go-log/v2 v2.5.0/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOLU9U5UI= -github.com/ipfs/go-log/v2 v2.5.1 h1:1XdUzF7048prq4aBjDQQ4SL5RxftpRGdXhNRwKSAlcY= -github.com/ipfs/go-log/v2 v2.5.1/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOLU9U5UI= -github.com/ipfs/go-metrics-interface v0.0.1 h1:j+cpbjYvu4R8zbleSs36gvB7jR+wsL2fGD6n0jO4kdg= -github.com/ipfs/go-metrics-interface v0.0.1/go.mod h1:6s6euYU4zowdslK0GKHmqaIZ3j/b/tL7HTWtJ4VPgWY= -github.com/ipfs/go-peertaskqueue v0.8.0 h1:JyNO144tfu9bx6Hpo119zvbEL9iQ760FHOiJYsUjqaU= -github.com/ipfs/go-peertaskqueue v0.8.0/go.mod h1:cz8hEnnARq4Du5TGqiWKgMr/BOSQ5XOgMOh1K5YYKKM= -github.com/ipld/go-ipld-prime v0.9.0/go.mod h1:KvBLMr4PX1gWptgkzRjVZCrLmSGcZCb/jioOQwCqZN8= -github.com/ipld/go-ipld-prime v0.9.1-0.20210324083106-dc342a9917db h1:kFwGn8rXa/Z31ev1OFNQsYeNKNCdifnTPl/NvPy5L38= -github.com/ipld/go-ipld-prime v0.9.1-0.20210324083106-dc342a9917db/go.mod h1:KvBLMr4PX1gWptgkzRjVZCrLmSGcZCb/jioOQwCqZN8= -github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= -github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= -github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA= -github.com/jbenet/go-temp-err-catcher v0.1.0 h1:zpb3ZH6wIE8Shj2sKS+khgRvf7T7RABoLk/+KKHggpk= -github.com/jbenet/go-temp-err-catcher v0.1.0/go.mod h1:0kJRvmDZXNMIiJirNPEYfhpPwbGVtZVWC34vc5WLsDk= -github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY= -github.com/jbenet/goprocess v0.1.3/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= -github.com/jbenet/goprocess v0.1.4 h1:DRGOFReOMqqDNXwW70QkacFW0YN9QnwLV0Vqk+3oU0o= -github.com/jbenet/goprocess v0.1.4/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= -github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU= -github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= -github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= -github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= -github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= -github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= -github.com/kami-zh/go-capturer v0.0.0-20171211120116-e492ea43421d/go.mod h1:P2viExyCEfeWGU259JnaQ34Inuec4R38JCyBx2edgD0= -github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= -github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= -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.15.1/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/compress v1.15.10 h1:Ai8UzuomSCDw90e1qNMtb15msBXsNpH6gzkkENQNcJo= -github.com/klauspost/compress v1.15.10/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= -github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.1.0/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= -github.com/klauspost/cpuid/v2 v2.1.1 h1:t0wUqjowdm8ezddV5k0tLWVklVuvLJpoHeb4WBdydm0= -github.com/klauspost/cpuid/v2 v2.1.1/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/koron/go-ssdp v0.0.0-20191105050749-2e1c40ed0b5d/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk= -github.com/koron/go-ssdp v0.0.3 h1:JivLMY45N76b4p/vsWGOKewBQu6uf39y8l+AQ7sDKx8= -github.com/koron/go-ssdp v0.0.3/go.mod h1:b2MxI6yh02pKrsyNoQUsk4+YNikaGhe4894J+Q5lDvA= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -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-buffer-pool v0.0.1/go.mod h1:xtyIz9PMobb13WaxR6Zo1Pd1zXJKYg0a8KiIvDp3TzQ= -github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM= -github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= -github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= -github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38yPW7c= -github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic= -github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8= -github.com/libp2p/go-flow-metrics v0.0.2/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= -github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= -github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= -github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.22.0/go.mod h1:UDolmweypBSjQb2f7xutPnwZ/fxioLbMBxSjRksxxU4= -github.com/libp2p/go-libp2p v0.23.4 h1:hWi9XHSOVFR1oDWRk7rigfyA4XNMuYL20INNybP9LP8= -github.com/libp2p/go-libp2p v0.23.4/go.mod h1:s9DEa5NLR4g+LZS+md5uGU4emjMWFiqkZr6hBTY8UxI= -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.2.0 h1:rg3+Os8jbnO5DxkC7K/Utdi+DkY3q/d1/1q+8WeNAsw= -github.com/libp2p/go-libp2p-asn-util v0.2.0/go.mod h1:WoaWxbHKBymSN41hWSq/lGKJEca7TNm58+gGJi2WsLI= -github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= -github.com/libp2p/go-libp2p-core v0.2.5/go.mod h1:6+5zJmKhsf7yHn1RbmYDu08qDUpIUxGdqHuEZckmZOA= -github.com/libp2p/go-libp2p-core v0.3.0/go.mod h1:ACp3DmS3/N64c2jDzcV429ukDpicbL6+TrrxANBjPGw= -github.com/libp2p/go-libp2p-core v0.5.3/go.mod h1:uN7L2D4EvPCvzSH5SrhR72UWbnSGpt5/a35Sm4upn4Y= -github.com/libp2p/go-libp2p-core v0.5.4/go.mod h1:uN7L2D4EvPCvzSH5SrhR72UWbnSGpt5/a35Sm4upn4Y= -github.com/libp2p/go-libp2p-core v0.6.1/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= -github.com/libp2p/go-libp2p-core v0.19.0/go.mod h1:AkA+FUKQfYt1FLNef5fOPlo/naAWjKy/RCjkcPjqzYg= -github.com/libp2p/go-libp2p-core v0.20.0 h1:PGKM74+T+O/FaZNARNW32i90RMBHCcgd/hkum2UQ5eY= -github.com/libp2p/go-libp2p-core v0.20.0/go.mod h1:6zR8H7CvQWgYLsbG4on6oLNSGcyKaYFSEYyDt51+bIY= -github.com/libp2p/go-libp2p-kad-dht v0.18.0 h1:akqO3gPMwixR7qFSFq70ezRun97g5hrA/lBW9jrjUYM= -github.com/libp2p/go-libp2p-kad-dht v0.18.0/go.mod h1:Gb92MYIPm3K2pJLGn8wl0m8wiKDvHrYpg+rOd0GzzPA= -github.com/libp2p/go-libp2p-kbucket v0.3.1/go.mod h1:oyjT5O7tS9CQurok++ERgc46YLwEpuGoFq9ubvoUOio= -github.com/libp2p/go-libp2p-kbucket v0.4.7 h1:spZAcgxifvFZHBD8tErvppbnNiKA5uokDu3CV7axu70= -github.com/libp2p/go-libp2p-kbucket v0.4.7/go.mod h1:XyVo99AfQH0foSf176k4jY1xUJ2+jUJIZCSDm7r2YKk= -github.com/libp2p/go-libp2p-peerstore v0.1.4/go.mod h1:+4BDbDiiKf4PzpANZDAT+knVdLxvqh7hXOujessqdzs= -github.com/libp2p/go-libp2p-peerstore v0.2.6/go.mod h1:ss/TWTgHZTMpsU/oKVVPQCGuDHItOpf2W8RxAi50P2s= -github.com/libp2p/go-libp2p-peerstore v0.8.0 h1:bzTG693TA1Ju/zKmUCQzDLSqiJnyRFVwPpuloZ/OZtI= -github.com/libp2p/go-libp2p-peerstore v0.8.0/go.mod h1:9geHWmNA3YDlQBjL/uPEJD6vpDK12aDNlUNHJ6kio/s= -github.com/libp2p/go-libp2p-record v0.1.2/go.mod h1:pal0eNcT5nqZaTV7UGhqeGqxFgGdsU/9W//C8dqjQDk= -github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= -github.com/libp2p/go-libp2p-record v0.2.0/go.mod h1:I+3zMkvvg5m2OcSdoL0KPljyJyvNDFGKX7QdlpYUcwk= -github.com/libp2p/go-libp2p-routing-helpers v0.2.3/go.mod h1:795bh+9YeoFl99rMASoiVgHdi5bjack0N1+AFAdbvBw= -github.com/libp2p/go-libp2p-testing v0.11.0/go.mod h1:qG4sF27dfKFoK9KlVzK2y52LQKhp0VEmLjV5aDqr1Hg= -github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA= -github.com/libp2p/go-libp2p-testing v0.12.0/go.mod h1:KcGDRXyN7sQCllucn1cOOS+Dmm7ujhfEyXQL5lvkcPg= -github.com/libp2p/go-libp2p-xor v0.1.0/go.mod h1:LSTM5yRnjGZbWNTA/hRwq2gGFrvRIbQJscoIL/u6InY= -github.com/libp2p/go-maddr-filter v0.1.0/go.mod h1:VzZhTXkMucEGGEOSKddrwGiOv0tUhgnKqNEmIAz/bPU= -github.com/libp2p/go-mplex v0.7.0/go.mod h1:rW8ThnRcYWft/Jb2jeORBmPd6xuG3dGxWN/W168L9EU= -github.com/libp2p/go-msgio v0.0.4/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= -github.com/libp2p/go-msgio v0.0.6/go.mod h1:4ecVB6d9f4BDSL5fqvPiC4A3KivjWn+Venn/1ALLMWA= -github.com/libp2p/go-msgio v0.2.0 h1:W6shmB+FeynDrUVl2dgFQvzfBZcXiyqY4VmpQLu9FqU= -github.com/libp2p/go-msgio v0.2.0/go.mod h1:dBVM1gW3Jk9XqHkU4eKdGvVHdLa51hoGfll6jMJMSlY= -github.com/libp2p/go-nat v0.1.0 h1:MfVsH6DLcpa04Xr+p8hmVRG4juse0s3J8HyNWYHffXg= -github.com/libp2p/go-nat v0.1.0/go.mod h1:X7teVkwRHNInVNWQiO/tAiAVRwSr5zoRz4YSTC3uRBM= -github.com/libp2p/go-netroute v0.1.2/go.mod h1:jZLDV+1PE8y5XxBySEBgbuVAXbhtuHSdmLPL2n9MKbk= -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.3/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= -github.com/libp2p/go-openssl v0.0.4/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= -github.com/libp2p/go-openssl v0.0.7/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= -github.com/libp2p/go-openssl v0.1.0 h1:LBkKEcUv6vtZIQLVTegAil8jbNpJErQ9AnT+bWV+Ooo= -github.com/libp2p/go-openssl v0.1.0/go.mod h1:OiOxwPpL3n4xlenjx2h7AwSGaFSC/KZvf6gNdOBQMtc= -github.com/libp2p/go-reuseport v0.2.0 h1:18PRvIMlpY6ZK85nIAicSBuXXvrYoSw3dsBAR7zc560= -github.com/libp2p/go-reuseport v0.2.0/go.mod h1:bvVho6eLMm6Bz5hmU0LYN3ixd3nPPvtIlaURZZgOY4k= -github.com/libp2p/go-sockaddr v0.0.2/go.mod h1:syPvOmNs24S3dFVGJA1/mrqdeijPxLV2Le3BRLKd68k= -github.com/libp2p/go-yamux/v3 v3.1.2/go.mod h1:jeLEQgLXqE2YqX1ilAClIfCMDY+0uXQUKmmb/qp0gT4= -github.com/libp2p/go-yamux/v4 v4.0.0 h1:+Y80dV2Yx/kv7Y7JKu0LECyVdMXm1VUoko+VQ9rBfZQ= -github.com/libp2p/go-yamux/v4 v4.0.0/go.mod h1:NWjl8ZTLOGlozrXSOZ/HlfG++39iKNnM5wwmtQP1YB4= -github.com/libp2p/zeroconf/v2 v2.2.0/go.mod h1:fuJqLnUwZTshS3U/bMRJ3+ow/v9oid1n0DmyYyNO1Xs= -github.com/lucas-clemente/quic-go v0.28.1/go.mod h1:oGz5DKK41cJt5+773+BSO9BXDsREY4HLf7+0odGAPO0= -github.com/lucas-clemente/quic-go v0.29.1 h1:Z+WMJ++qMLhvpFkRZA+jl3BTxUjm415YBmWanXB8zP0= -github.com/lucas-clemente/quic-go v0.29.1/go.mod h1:CTcNfLYJS2UuRNB+zcNlgvkjBhxX6Hm3WUxxAQx2mgE= -github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= -github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/marten-seemann/qpack v0.2.1 h1:jvTsT/HpCn2UZJdP+UUB53FfUUgeOyG5K1ns0OJOGVs= -github.com/marten-seemann/qpack v0.2.1/go.mod h1:F7Gl5L1jIgN1D11ucXefiuJS9UMVP2opoCp2jDKb7wc= -github.com/marten-seemann/qtls-go1-16 v0.1.5/go.mod h1:gNpI2Ol+lRS3WwSOtIUUtRwZEQMXjYK+dQSBFbethAk= -github.com/marten-seemann/qtls-go1-17 v0.1.2/go.mod h1:C2ekUKcDdz9SDWxec1N/MvcXBpaX9l3Nx67XaR84L5s= -github.com/marten-seemann/qtls-go1-18 v0.1.2 h1:JH6jmzbduz0ITVQ7ShevK10Av5+jBEKAHMntXmIV7kM= -github.com/marten-seemann/qtls-go1-18 v0.1.2/go.mod h1:mJttiymBAByA49mhlNZZGrH5u1uXYZJ+RW28Py7f4m4= -github.com/marten-seemann/qtls-go1-19 v0.1.0-beta.1/go.mod h1:5HTDWtVudo/WFsHKRNuOhWlbdjrfs5JHrYb0wIJqGpI= -github.com/marten-seemann/qtls-go1-19 v0.1.0 h1:rLFKD/9mp/uq1SYGYuVZhm83wkmU95pK5df3GufyYYU= -github.com/marten-seemann/qtls-go1-19 v0.1.0/go.mod h1:5HTDWtVudo/WFsHKRNuOhWlbdjrfs5JHrYb0wIJqGpI= -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/marten-seemann/webtransport-go v0.1.1 h1:TnyKp3pEXcDooTaNn4s9dYpMJ7kMnTp7k5h+SgYP/mc= -github.com/marten-seemann/webtransport-go v0.1.1/go.mod h1:kBEh5+RSvOA4troP1vyOVBWK4MIMzDICXVrvCPrYcrM= -github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= -github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-pointer v0.0.1 h1:n+XhsuGeVO6MEAp7xyEukFINEa+Quek5psIR/ylA6o0= -github.com/mattn/go-pointer v0.0.1/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc= -github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= -github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= -github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= -github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= -github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= -github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA= -github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= -github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c h1:bzE/A84HN25pxAuk9Eej1Kz9OUelF97nAc82bDquQI8= -github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c/go.mod h1:0SQS9kMwD2VsyFEB++InYyBJroV/FRmBgcydeSUcJms= -github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= -github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b/go.mod h1:lxPUiZwKoFL8DUUmalo2yJJUCxbPKtm8OKfqr2/FTNU= -github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc h1:PTfri+PuQmWDqERdnNMiD9ZejrlswWrCpBEZgWOiTrc= -github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc/go.mod h1:cGKTAVKx4SxOuR/czcZ/E2RSJ3sfHs8FpHhQ5CWMf9s= -github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= -github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= -github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= -github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= -github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g= -github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM= -github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= -github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= -github.com/mr-tron/base58 v1.1.3/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= -github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= -github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= -github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= -github.com/multiformats/go-base32 v0.0.4/go.mod h1:jNLFzjPZtp3aIARHbJRZIaPuspdH0J6q39uUM5pnABM= -github.com/multiformats/go-base32 v0.1.0 h1:pVx9xoSPqEIQG8o+UbAe7DNi51oej1NtK+aGkbLYxPE= -github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYgtWibDcT0rExnbI= -github.com/multiformats/go-base36 v0.1.0 h1:JR6TyF7JjGd3m6FbLU2cOxhC0Li8z8dLNGQ89tUg4F4= -github.com/multiformats/go-base36 v0.1.0/go.mod h1:kFGE83c6s80PklsHO9sRn2NCoffoRdUUOENyW/Vv6sM= -github.com/multiformats/go-multiaddr v0.1.0/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= -github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo= -github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4= -github.com/multiformats/go-multiaddr v0.2.1/go.mod h1:s/Apk6IyxfvMjDafnhJgJ3/46z7tZ04iMk5wP4QMGGE= -github.com/multiformats/go-multiaddr v0.2.2/go.mod h1:NtfXiOtHvghW9KojvtySjH5y0u0xW5UouOmQQrn6a3Y= -github.com/multiformats/go-multiaddr v0.3.0/go.mod h1:dF9kph9wfJ+3VLAaeBqo9Of8x4fJxp6ggJGteB8HQTI= -github.com/multiformats/go-multiaddr v0.3.1/go.mod h1:uPbspcUPd5AfaP6ql3ujFY+QWzmBD8uLLL4bXW0XfGc= -github.com/multiformats/go-multiaddr v0.4.1/go.mod h1:3afI9HfVW8csiF8UZqtpYRiDyew8pRX7qLIGHu9FLuM= -github.com/multiformats/go-multiaddr v0.6.0/go.mod h1:F4IpaKZuPP360tOMn2Tpyu0At8w23aRyVqeK0DbFeGM= -github.com/multiformats/go-multiaddr v0.7.0/go.mod h1:Fs50eBDWvZu+l3/9S6xAE7ZYj6yhxlvaVZjakWN7xRs= -github.com/multiformats/go-multiaddr v0.8.0 h1:aqjksEcqK+iD/Foe1RRFsGZh8+XFiGo7FgUCZlpv3LU= -github.com/multiformats/go-multiaddr v0.8.0/go.mod h1:Fs50eBDWvZu+l3/9S6xAE7ZYj6yhxlvaVZjakWN7xRs= -github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A= -github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk= -github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E= -github.com/multiformats/go-multiaddr-fmt v0.1.0/go.mod h1:hGtDIW4PU4BqJ50gW2quDuPVjyWNZxToGUh/HwTZYJo= -github.com/multiformats/go-multiaddr-net v0.1.1/go.mod h1:5JNbcfBOP4dnhoZOv10JJVkJO0pCCEf8mTnipAo2UZQ= -github.com/multiformats/go-multiaddr-net v0.1.4/go.mod h1:ilNnaM9HbmVFqsb/qcNysjCu4PVONlrBZpHIrw/qQuA= -github.com/multiformats/go-multiaddr-net v0.2.0/go.mod h1:gGdH3UXny6U3cKKYCvpXI5rnK7YaOIEOPVDI9tsJbEA= -github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= -github.com/multiformats/go-multibase v0.0.3/go.mod h1:5+1R4eQrT3PkYZ24C3W2Ue2tPwIdYQD509ZjSb5y9Oc= -github.com/multiformats/go-multibase v0.1.1 h1:3ASCDsuLX8+j4kx58qnJ4YFq/JWTJpCyDW27ztsVTOI= -github.com/multiformats/go-multibase v0.1.1/go.mod h1:ZEjHE+IsUrgp5mhlEAYjMtZwK1k4haNkcaPg9aoe1a8= -github.com/multiformats/go-multicodec v0.4.1/go.mod h1:1Hj/eHRaVWSXiSNNfcEPcwZleTmdNP81xlxDLnWU9GQ= -github.com/multiformats/go-multicodec v0.5.0/go.mod h1:DiY2HFaEp5EhEXb/iYzVAunmyX/aSFMxq2KMKfWEues= -github.com/multiformats/go-multicodec v0.6.0 h1:KhH2kSuCARyuJraYMFxrNO3DqIaYhOdS039kbhgVwpE= -github.com/multiformats/go-multicodec v0.6.0/go.mod h1:GUC8upxSBE4oG+q3kWZRw/+6yC1BqO550bjhWsJbZlw= -github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= -github.com/multiformats/go-multihash v0.0.8/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= -github.com/multiformats/go-multihash v0.0.9/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= -github.com/multiformats/go-multihash v0.0.10/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= -github.com/multiformats/go-multihash v0.0.13/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= -github.com/multiformats/go-multihash v0.0.14/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= -github.com/multiformats/go-multihash v0.0.15/go.mod h1:D6aZrWNLFTV/ynMpKsNtB40mJzmCl4jb1alC0OvHiHg= -github.com/multiformats/go-multihash v0.2.1 h1:aem8ZT0VA2nCHHk7bPJ1BjUbHNciqZC/d16Vve9l108= -github.com/multiformats/go-multihash v0.2.1/go.mod h1:WxoMcYG85AZVQUyRyo9s4wULvW5qrI9vb2Lt6evduFc= -github.com/multiformats/go-multistream v0.3.3 h1:d5PZpjwRgVlbwfdTDjife7XszfZd8KYWfROYFlGcR8o= -github.com/multiformats/go-multistream v0.3.3/go.mod h1:ODRoqamLUsETKS9BNcII4gcRsJBU5VAwRIv7O39cEXg= -github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= -github.com/multiformats/go-varint v0.0.2/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= -github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= -github.com/multiformats/go-varint v0.0.6 h1:gk85QWKxh3TazbLxED/NlDVv8+q+ReFJk7Y2W/KhfNY= -github.com/multiformats/go-varint v0.0.6/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= -github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= -github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= -github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= -github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= -github.com/onsi/ginkgo v1.16.2/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E= -github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= -github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= -github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= -github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.13.0 h1:7lLHu94wT9Ij0o6EWWclhu0aOh32VxhkwEJvzuWPeak= -github.com/onsi/gomega v1.13.0/go.mod h1:lRk9szgn8TxENtWd0Tp4c3wjlRfMTMH27I+3Je41yGY= -github.com/opencontainers/runtime-spec v1.0.2 h1:UfAcuLBJB9Coz72x1hgl8O5RVzTdNiaglX6v2DM6FI0= -github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= -github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= -github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= -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/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/polydawn/refmt v0.0.0-20190807091052-3d65705ee9f1/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= -github.com/polydawn/refmt v0.0.0-20201211092308-30ac6d18308e h1:ZOcivgkkFRnjfoTcGsDq3UQYiBmekwLA+qg0OjyB/ls= -github.com/polydawn/refmt v0.0.0-20201211092308-30ac6d18308e/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= -github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= -github.com/prometheus/client_golang v1.13.0 h1:b71QUfeo5M8gq2+evJdTPfZhYMAU0uKPkyPJ7TPsloU= -github.com/prometheus/client_golang v1.13.0/go.mod h1:vTeo+zgvILHsnnj/39Ou/1fPN5nJFOEMgftOUOmlvYQ= -github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= -github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= -github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= -github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= -github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE= -github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= -github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo= -github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= -github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= -github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU= -github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 h1:MkV+77GLUNo5oJ0jf870itWm3D0Sjh7+Za9gazKc5LQ= -github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= -github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= -github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/samber/lo v1.36.0/go.mod h1:HLeWcJRRyLKp3+/XBJvOrerCQn9mhdKMHyd7IRlgeQ8= -github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= -github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY= -github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM= -github.com/shurcooL/github_flavored_markdown v0.0.0-20181002035957-2122de532470/go.mod h1:2dOwnU2uBioM+SGy2aZoq1f/Sd1l9OkAeAUvjSyvgU0= -github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= -github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ= -github.com/shurcooL/gofontwoff v0.0.0-20180329035133-29b52fc0a18d/go.mod h1:05UtEgK5zq39gLST6uB0cf3NEHjETfB4Fgr3Gx5R9Vw= -github.com/shurcooL/gopherjslib v0.0.0-20160914041154-feb6d3990c2c/go.mod h1:8d3azKNyqcHP1GaQE/c6dDgjkgSx2BZ4IoEi4F1reUI= -github.com/shurcooL/highlight_diff v0.0.0-20170515013008-09bb4053de1b/go.mod h1:ZpfEhSmds4ytuByIcDnOLkTHGUI6KNqRNPDLHDk+mUU= -github.com/shurcooL/highlight_go v0.0.0-20181028180052-98c3abbbae20/go.mod h1:UDKB5a1T23gOMUJrI+uSuH0VRDStOiUVSjBTRDVBVag= -github.com/shurcooL/home v0.0.0-20181020052607-80b7ffcb30f9/go.mod h1:+rgNQw2P9ARFAs37qieuu7ohDNQ3gds9msbT2yn85sg= -github.com/shurcooL/htmlg v0.0.0-20170918183704-d01228ac9e50/go.mod h1:zPn1wHpTIePGnXSHpsVPWEktKXHr6+SS6x/IKRb7cpw= -github.com/shurcooL/httperror v0.0.0-20170206035902-86b7830d14cc/go.mod h1:aYMfkZ6DWSJPJ6c4Wwz3QtW22G7mf/PEgaB9k/ik5+Y= -github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= -github.com/shurcooL/httpgzip v0.0.0-20180522190206-b1c53ac65af9/go.mod h1:919LwcH0M7/W4fcZ0/jy0qGght1GIhqyS/EgWGH2j5Q= -github.com/shurcooL/issues v0.0.0-20181008053335-6292fdc1e191/go.mod h1:e2qWDig5bLteJ4fwvDAc2NHzqFEthkqn7aOZAOpj+PQ= -github.com/shurcooL/issuesapp v0.0.0-20180602232740-048589ce2241/go.mod h1:NPpHK2TI7iSaM0buivtFUc9offApnI0Alt/K8hcHy0I= -github.com/shurcooL/notifications v0.0.0-20181007000457-627ab5aea122/go.mod h1:b5uSkrEVM1jQUspwbixRBhaIjIzL2xazXp6kntxYle0= -github.com/shurcooL/octicon v0.0.0-20181028054416-fa4f57f9efb2/go.mod h1:eWdoE5JD4R5UVWDucdOPg1g2fqQRq78IQa9zlOV1vpQ= -github.com/shurcooL/reactions v0.0.0-20181006231557-f2e0b4ca5b82/go.mod h1:TCR1lToEk4d2s07G3XGfz2QrgHXg4RJBvjrOozvoWfk= -github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYEDaXHZDBsXlPCDqdhQuJkuw4NOtaxYe3xii4= -github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw= -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/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/assertions v1.0.1 h1:voD4ITNjPL5jjBfgR/r8fPIIBrliWrWHeiJApdr3r4w= -github.com/smartystreets/assertions v1.0.1/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= -github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= -github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/smola/gocompat v0.2.0/go.mod h1:1B0MlxbmoZNo3h8guHp8HztB3BSYR5itql9qtVc0ypY= -github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE= -github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA= -github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU= -github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= -github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= -github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= -github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= -github.com/src-d/envconfig v1.0.0/go.mod h1:Q9YQZ7BKITldTBnoxsE5gOeB5y66RyPXeue/R4aaNBc= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= -github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= -github.com/testground/sdk-go v0.2.7 h1:SDLDukPZIaZOeG2gQjCNsh5EB3QL3mOhOM4p0BMpqlc= -github.com/testground/sdk-go v0.2.7/go.mod h1:Q4dnWsUBH+dZ1u7aEGDBHWGUaLfhitjUq3UJQqxeTmk= -github.com/thoas/go-funk v0.9.1/go.mod h1:+IWnUfUmFO1+WVYQWQtIJHeRRdaIyyYglZN7xzUPe4Q= -github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU= -github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM= -github.com/wangjia184/sortedset v0.0.0-20160527075905-f5d03557ba30/go.mod h1:YkocrP2K2tcw938x9gCOmT5G5eCD6jsTz0SZuyAqwIE= -github.com/warpfork/go-wish v0.0.0-20200122115046-b9ea61034e4a h1:G++j5e0OC488te356JvdhaM8YS6nMsjLAYF7JxCv07w= -github.com/warpfork/go-wish v0.0.0-20200122115046-b9ea61034e4a/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= -github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 h1:EKhdznlJHPMoKr0XTrX+IlJs1LH3lyx2nfr1dOlZ79k= -github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc= -github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= -github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE= -github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= -github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA= -go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= -go.opencensus.io v0.22.1/go.mod h1:Ap50jQcDJrx6rB6VgeeFPtuPIf3wMRvRfrfYDO6+BmA= -go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= -go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= -go.opentelemetry.io/otel v1.7.0 h1:Z2lA3Tdch0iDcrhJXDIlC94XE+bxok1F9B+4Lz/lGsM= -go.opentelemetry.io/otel v1.7.0/go.mod h1:5BdUoMIz5WEs0vt0CUEMtSSaTSHBBVwrhnz7+nrD5xk= -go.opentelemetry.io/otel/trace v1.7.0 h1:O37Iogk1lEkMRXewVtZ1BBTVn5JEp8GrJvP92bJqC6o= -go.opentelemetry.io/otel/trace v1.7.0/go.mod h1:fzLSB9nqR2eXzxPXb2JW9IKE+ScyXA48yyE4TNvoHqU= -go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= -go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= -go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/goleak v1.0.0/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/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= -go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA= -go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= -go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= -go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= -go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= -go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8= -go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= -go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= -go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -go.uber.org/zap v1.14.1/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= -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.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= -go.uber.org/zap v1.22.0/go.mod h1:H4siCOZOrAolnUPJEkfaSjDqyP+BDS0DdDWzwcgt3+U= -go.uber.org/zap v1.23.0 h1:OjGQ5KQDEUawVHxNwQgPpiypGHOxo2mNZsOqTak4fFY= -go.uber.org/zap v1.23.0/go.mod h1:D+nX8jyLsMHMYrln8A0rJjFt/T/9/bGgIhAqxv5URuY= -go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= -golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw= -golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200602180216-279210d13fed/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20210506145944-38f3c27a63bf/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e h1:T8NU3HyQ8ClP4SEE+KbFlg6n0NhuTsN4MyznaarGsZM= -golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= -golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= -golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17/go.mod h1:lgLbSvA5ygNOMpwM/9anMpWVlVJ7Z+cHWq/eFuinpGE= -golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA= -golang.org/x/exp v0.0.0-20220916125017-b168a2c6b86b h1:SCE/18RnFsLrjydh/R/s5EVvHoZprqEQUuoxK8q2Pc4= -golang.org/x/exp v0.0.0-20220916125017-b168a2c6b86b/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE= -golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= -golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5 h1:2M3HP5CCK1Si9FQhwnzYhXdG6DXeebvUHFpre8QvbyI= -golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= -golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= -golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= -golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= -golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= -golang.org/x/mod v0.6.0-dev.0.20211013180041-c96bc1413d57/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= -golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20210423184538-5f58ad60dda6/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.0.0-20220812174116-3211cb980234/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= -golang.org/x/net v0.0.0-20220920183852-bf014ff85ad5 h1:KafLifaRFIuSJ5C+7CyFJOF9haxKNC1CEIDk8GX6X0k= -golang.org/x/net v0.0.0-20220920183852-bf014ff85ad5/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 h1:uVc8UZUe6tr40fFVnUP5Oj+veunVezqYl9z7DYw9xzw= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/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-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190405154228-4b34438f7a67/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/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= -golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210426080607-c94f62235c83/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab h1:2QkjZIsXupsJbJIdSjjUOgWK3aEtzyuh2mPt3l/CkeU= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181130052023-1c3d964395ce/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= -golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.8-0.20211029000441-d6a9af8af023/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= -golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= -golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= -google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= -google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y= -google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= -google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= -google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg= -google.golang.org/genproto v0.0.0-20190306203927-b5d61aea6440/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= -google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= -google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= -google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= -google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= -google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= -google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= -google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= -google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/src-d/go-cli.v0 v0.0.0-20181105080154-d492247bbc0d/go.mod h1:z+K8VcOYVYcSwSjGebuDL6176A1XskgbtNl64NSg+n8= -gopkg.in/src-d/go-log.v1 v1.0.1/go.mod h1:GN34hKP0g305ysm2/hctJ0Y8nWP3zxXXJ8GFabTyABE= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o= -honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -lukechampine.com/blake3 v1.1.6/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= -lukechampine.com/blake3 v1.1.7 h1:GgRMhmdsuK8+ii6UZFDL8Nb+VyMwadAgcJyfYHxG6n0= -lukechampine.com/blake3 v1.1.7/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= -rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= -rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= -rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck= -sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0= diff --git a/testplans/bitswap/main.go b/testplans/bitswap/main.go deleted file mode 100644 index 0af2ad95c..000000000 --- a/testplans/bitswap/main.go +++ /dev/null @@ -1,201 +0,0 @@ -package main - -import ( - "context" - "errors" - "fmt" - "math/rand" - "time" - - "github.com/testground/sdk-go/network" - "github.com/testground/sdk-go/run" - "github.com/testground/sdk-go/runtime" - "github.com/testground/sdk-go/sync" - - "github.com/ipfs/go-cid" - datastore "github.com/ipfs/go-datastore" - blockstore "github.com/ipfs/go-ipfs-blockstore" - exchange "github.com/ipfs/go-ipfs-exchange-interface" - bstats "github.com/ipfs/go-ipfs-regression/bitswap" - bitswap "github.com/ipfs/go-libipfs/bitswap" - bsnet "github.com/ipfs/go-libipfs/bitswap/network" - block "github.com/ipfs/go-libipfs/blocks" - "github.com/libp2p/go-libp2p" - dht "github.com/libp2p/go-libp2p-kad-dht" - "github.com/libp2p/go-libp2p/core/host" - "github.com/libp2p/go-libp2p/core/peer" - "github.com/multiformats/go-multiaddr" - "github.com/multiformats/go-multihash" -) - -var ( - testcases = map[string]interface{}{ - "speed-test": run.InitializedTestCaseFn(runSpeedTest), - } - networkState = sync.State("network-configured") - readyState = sync.State("ready-to-publish") - readyDLState = sync.State("ready-to-download") - doneState = sync.State("done") - providerTopic = sync.NewTopic("provider", &peer.AddrInfo{}) - blockTopic = sync.NewTopic("blocks", &multihash.Multihash{}) -) - -func main() { - run.InvokeMap(testcases) -} - -func runSpeedTest(runenv *runtime.RunEnv, initCtx *run.InitContext) error { - runenv.RecordMessage("running speed-test") - ctx := context.Background() - linkShape := network.LinkShape{} - // linkShape := network.LinkShape{ - // Latency: 50 * time.Millisecond, - // Jitter: 20 * time.Millisecond, - // Bandwidth: 3e6, - // // Filter: (not implemented) - // Loss: 0.02, - // Corrupt: 0.01, - // CorruptCorr: 0.1, - // Reorder: 0.01, - // ReorderCorr: 0.1, - // Duplicate: 0.02, - // DuplicateCorr: 0.1, - // } - initCtx.NetClient.MustConfigureNetwork(ctx, &network.Config{ - Network: "default", - Enable: true, - Default: linkShape, - CallbackState: networkState, - CallbackTarget: runenv.TestGroupInstanceCount, - RoutingPolicy: network.AllowAll, - }) - listen, err := multiaddr.NewMultiaddr(fmt.Sprintf("/ip4/%s/tcp/3333", initCtx.NetClient.MustGetDataNetworkIP().String())) - if err != nil { - return err - } - h, err := libp2p.New(libp2p.ListenAddrs(listen)) - if err != nil { - return err - } - defer h.Close() - kad, err := dht.New(ctx, h) - if err != nil { - return err - } - for _, a := range h.Addrs() { - runenv.RecordMessage("listening on addr: %s", a.String()) - } - bstore := blockstore.NewBlockstore(datastore.NewMapDatastore()) - ex := bitswap.New(ctx, bsnet.NewFromIpfsHost(h, kad), bstore) - switch runenv.TestGroupID { - case "providers": - runenv.RecordMessage("running provider") - err = runProvide(ctx, runenv, h, bstore, ex) - case "requestors": - runenv.RecordMessage("running requestor") - err = runRequest(ctx, runenv, h, bstore, ex) - default: - runenv.RecordMessage("not part of a group") - err = errors.New("unknown test group id") - } - return err -} - -func runProvide(ctx context.Context, runenv *runtime.RunEnv, h host.Host, bstore blockstore.Blockstore, ex exchange.Interface) error { - tgc := sync.MustBoundClient(ctx, runenv) - ai := peer.AddrInfo{ - ID: h.ID(), - Addrs: h.Addrs(), - } - tgc.MustPublish(ctx, providerTopic, &ai) - tgc.MustSignalAndWait(ctx, readyState, runenv.TestInstanceCount) - - size := runenv.SizeParam("size") - count := runenv.IntParam("count") - for i := 0; i <= count; i++ { - runenv.RecordMessage("generating %d-sized random block", size) - buf := make([]byte, size) - rand.Read(buf) - blk := block.NewBlock(buf) - err := bstore.Put(ctx, blk) - if err != nil { - return err - } - mh := blk.Multihash() - runenv.RecordMessage("publishing block %s", mh.String()) - tgc.MustPublish(ctx, blockTopic, &mh) - } - tgc.MustSignalAndWait(ctx, readyDLState, runenv.TestInstanceCount) - tgc.MustSignalAndWait(ctx, doneState, runenv.TestInstanceCount) - return nil -} - -func runRequest(ctx context.Context, runenv *runtime.RunEnv, h host.Host, bstore blockstore.Blockstore, ex exchange.Interface) error { - tgc := sync.MustBoundClient(ctx, runenv) - providers := make(chan *peer.AddrInfo) - blkmhs := make(chan *multihash.Multihash) - providerSub, err := tgc.Subscribe(ctx, providerTopic, providers) - if err != nil { - return err - } - ai := <-providers - - runenv.RecordMessage("connecting to provider provider: %s", fmt.Sprint(*ai)) - providerSub.Done() - - err = h.Connect(ctx, *ai) - if err != nil { - return fmt.Errorf("could not connect to provider: %w", err) - } - - runenv.RecordMessage("connected to provider") - - blockmhSub, err := tgc.Subscribe(ctx, blockTopic, blkmhs) - if err != nil { - return fmt.Errorf("could not subscribe to block sub: %w", err) - } - defer blockmhSub.Done() - - // tell the provider that we're ready for it to publish blocks - tgc.MustSignalAndWait(ctx, readyState, runenv.TestInstanceCount) - // wait until the provider is ready for us to start downloading - tgc.MustSignalAndWait(ctx, readyDLState, runenv.TestInstanceCount) - - begin := time.Now() - count := runenv.IntParam("count") - for i := 0; i <= count; i++ { - mh := <-blkmhs - runenv.RecordMessage("downloading block %s", mh.String()) - dlBegin := time.Now() - blk, err := ex.GetBlock(ctx, cid.NewCidV0(*mh)) - if err != nil { - return fmt.Errorf("could not download get block %s: %w", mh.String(), err) - } - dlDuration := time.Since(dlBegin) - s := &bstats.BitswapStat{ - SingleDownloadSpeed: &bstats.SingleDownloadSpeed{ - Cid: blk.Cid().String(), - DownloadDuration: dlDuration, - }, - } - runenv.RecordMessage(bstats.Marshal(s)) - - stored, err := bstore.Has(ctx, blk.Cid()) - if err != nil { - return fmt.Errorf("error checking if blck was stored %s: %w", mh.String(), err) - } - if !stored { - return fmt.Errorf("block was not stored %s: %w", mh.String(), err) - } - } - duration := time.Since(begin) - s := &bstats.BitswapStat{ - MultipleDownloadSpeed: &bstats.MultipleDownloadSpeed{ - BlockCount: count, - TotalDuration: duration, - }, - } - runenv.RecordMessage(bstats.Marshal(s)) - tgc.MustSignalEntry(ctx, doneState) - return nil -} diff --git a/testplans/bitswap/manifest.toml b/testplans/bitswap/manifest.toml deleted file mode 100644 index cc6e2720a..000000000 --- a/testplans/bitswap/manifest.toml +++ /dev/null @@ -1,19 +0,0 @@ -name = "bitswap" - -[builders] - "docker:go" = { enabled = true, enable_go_build_cache = true } - -[runners] - "local:docker" = { enabled = true } - "cluster:k8s" = { enabled = true } - -[global.build_config] - enable_go_build_cache = true - -[[testcases]] - name = "speed-test" - instances = { min = 2, max = 100, default = 2 } - - [testcases.params] - size = { type = "int", desc = "size of file to transfer, in human-friendly form", default = "1MiB" } - count = { type = "int", desc = "number of transfers", default = "10" } From 9e078e6d46f2a9c8ab794f9cd06d5d2ffcc852f6 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Thu, 17 Aug 2023 07:45:45 +0200 Subject: [PATCH 0818/1212] chore: remove outdated comment (#10077) The link is present line 100 --- core/node/provider.go | 1 - 1 file changed, 1 deletion(-) diff --git a/core/node/provider.go b/core/node/provider.go index 215e0adac..c1c99e600 100644 --- a/core/node/provider.go +++ b/core/node/provider.go @@ -85,7 +85,6 @@ https://github.com/ipfs/kubo/blob/master/docs/config.md#routingaccelerateddhtcli // How long per block that lasts us. expectedProvideSpeed := reprovideInterval / time.Duration(count) if avgProvideSpeed > expectedProvideSpeed { - // FIXME(@Jorropo): add link to the accelerated DHT client docs once this isn't experimental anymore. logger.Errorf(` 🔔🔔🔔 YOU ARE FALLING BEHIND DHT REPROVIDES! 🔔🔔🔔 From b4f415088f0d04916a4de6f6fa1e9ddf16c6bd53 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Thu, 17 Aug 2023 13:01:50 +0200 Subject: [PATCH 0819/1212] chore: bump boxo for verifcid breaking changes This is a Q&D fix to get kubo building again, this is completely equivalent to what we used to have. I'll submit a patch that DI the verifcid.Allowlist interface with fx later but this is needed to unblock something else. --- core/commands/cid.go | 2 +- core/commands/pin/pin.go | 2 +- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- gc/gc.go | 2 +- go.mod | 2 +- go.sum | 4 ++-- test/dependencies/go.mod | 2 +- test/dependencies/go.sum | 4 ++-- thirdparty/verifbs/verifbs.go | 12 ++++++------ 10 files changed, 18 insertions(+), 18 deletions(-) diff --git a/core/commands/cid.go b/core/commands/cid.go index 7590b35b4..017a5d191 100644 --- a/core/commands/cid.go +++ b/core/commands/cid.go @@ -377,7 +377,7 @@ var hashesCmd = &cmds.Command{ var res []CodeAndName // use mhash.Codes in case at some point there are multiple names for a given code for code, name := range mhash.Codes { - if !verifcid.IsGoodHash(code) { + if !verifcid.DefaultAllowlist.IsAllowed(code) { continue } res = append(res, CodeAndName{int(code), name}) diff --git a/core/commands/pin/pin.go b/core/commands/pin/pin.go index 673afc971..9402f5b2c 100644 --- a/core/commands/pin/pin.go +++ b/core/commands/pin/pin.go @@ -688,7 +688,7 @@ func pinVerify(ctx context.Context, n *core.IpfsNode, opts pinVerifyOpts, enc ci return status } - if err := verifcid.ValidateCid(root); err != nil { + if err := verifcid.ValidateCid(verifcid.DefaultAllowlist, root); err != nil { status := PinStatus{Ok: false} if opts.explain { status.BadNodes = []BadNode{{Cid: enc.Encode(key), Err: err.Error()}} diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 5cc1054a2..c0806d180 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.18 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.11.0 + github.com/ipfs/boxo v0.11.1-0.20230817061817-1d2f5e511e9f github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.29.2 github.com/multiformats/go-multiaddr v0.10.1 diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 3213c24eb..710497500 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -301,8 +301,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.11.0 h1:urMxhZ3xoF4HssJVD3+0ssGT9pptEfHfbL8DYdoWFlg= -github.com/ipfs/boxo v0.11.0/go.mod h1:8IfDmp+FzFGcF4zjAgHMVPpwYw4AjN9ePEzDfkaYJ1w= +github.com/ipfs/boxo v0.11.1-0.20230817061817-1d2f5e511e9f h1:sXqGLIATCsBdHse7S9n6e328NhORvVM64+4IRuFlpmI= +github.com/ipfs/boxo v0.11.1-0.20230817061817-1d2f5e511e9f/go.mod h1:8IfDmp+FzFGcF4zjAgHMVPpwYw4AjN9ePEzDfkaYJ1w= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= diff --git a/gc/gc.go b/gc/gc.go index 6df598741..031ba16dc 100644 --- a/gc/gc.go +++ b/gc/gc.go @@ -156,7 +156,7 @@ func GC(ctx context.Context, bs bstore.GCBlockstore, dstor dstore.Datastore, pn // to walk the tree. func Descendants(ctx context.Context, getLinks dag.GetLinks, set *cid.Set, roots <-chan pin.StreamedCid) error { verifyGetLinks := func(ctx context.Context, c cid.Cid) ([]*ipld.Link, error) { - err := verifcid.ValidateCid(c) + err := verifcid.ValidateCid(verifcid.DefaultAllowlist, c) if err != nil { return nil, err } diff --git a/go.mod b/go.mod index d730dd2f3..f6d60148b 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( github.com/fsnotify/fsnotify v1.6.0 github.com/google/uuid v1.3.0 github.com/hashicorp/go-multierror v1.1.1 - github.com/ipfs/boxo v0.11.0 + github.com/ipfs/boxo v0.11.1-0.20230817061817-1d2f5e511e9f github.com/ipfs/go-block-format v0.1.2 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 diff --git a/go.sum b/go.sum index 22b6ea3cf..083a052ca 100644 --- a/go.sum +++ b/go.sum @@ -337,8 +337,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.11.0 h1:urMxhZ3xoF4HssJVD3+0ssGT9pptEfHfbL8DYdoWFlg= -github.com/ipfs/boxo v0.11.0/go.mod h1:8IfDmp+FzFGcF4zjAgHMVPpwYw4AjN9ePEzDfkaYJ1w= +github.com/ipfs/boxo v0.11.1-0.20230817061817-1d2f5e511e9f h1:sXqGLIATCsBdHse7S9n6e328NhORvVM64+4IRuFlpmI= +github.com/ipfs/boxo v0.11.1-0.20230817061817-1d2f5e511e9f/go.mod h1:8IfDmp+FzFGcF4zjAgHMVPpwYw4AjN9ePEzDfkaYJ1w= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index bfee9a0a7..fb8b087ad 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -7,7 +7,7 @@ replace github.com/ipfs/kubo => ../../ require ( github.com/Kubuxu/gocovmerge v0.0.0-20161216165753-7ecaa51963cd github.com/golangci/golangci-lint v1.49.0 - github.com/ipfs/boxo v0.11.0 + github.com/ipfs/boxo v0.11.1-0.20230817061817-1d2f5e511e9f github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 github.com/ipfs/go-datastore v0.6.0 diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 4967be85f..3fbd086a5 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -395,8 +395,8 @@ github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NH github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.11.0 h1:urMxhZ3xoF4HssJVD3+0ssGT9pptEfHfbL8DYdoWFlg= -github.com/ipfs/boxo v0.11.0/go.mod h1:8IfDmp+FzFGcF4zjAgHMVPpwYw4AjN9ePEzDfkaYJ1w= +github.com/ipfs/boxo v0.11.1-0.20230817061817-1d2f5e511e9f h1:sXqGLIATCsBdHse7S9n6e328NhORvVM64+4IRuFlpmI= +github.com/ipfs/boxo v0.11.1-0.20230817061817-1d2f5e511e9f/go.mod h1:8IfDmp+FzFGcF4zjAgHMVPpwYw4AjN9ePEzDfkaYJ1w= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.1.2 h1:GAjkfhVx1f4YTODS6Esrj1wt2HhrtwTnhEr+DyPUaJo= diff --git a/thirdparty/verifbs/verifbs.go b/thirdparty/verifbs/verifbs.go index 929e8cde9..2fcc52bb9 100644 --- a/thirdparty/verifbs/verifbs.go +++ b/thirdparty/verifbs/verifbs.go @@ -14,7 +14,7 @@ type VerifBSGC struct { } func (bs *VerifBSGC) Put(ctx context.Context, b blocks.Block) error { - if err := verifcid.ValidateCid(b.Cid()); err != nil { + if err := verifcid.ValidateCid(verifcid.DefaultAllowlist, b.Cid()); err != nil { return err } return bs.GCBlockstore.Put(ctx, b) @@ -22,7 +22,7 @@ func (bs *VerifBSGC) Put(ctx context.Context, b blocks.Block) error { func (bs *VerifBSGC) PutMany(ctx context.Context, blks []blocks.Block) error { for _, b := range blks { - if err := verifcid.ValidateCid(b.Cid()); err != nil { + if err := verifcid.ValidateCid(verifcid.DefaultAllowlist, b.Cid()); err != nil { return err } } @@ -30,7 +30,7 @@ func (bs *VerifBSGC) PutMany(ctx context.Context, blks []blocks.Block) error { } func (bs *VerifBSGC) Get(ctx context.Context, c cid.Cid) (blocks.Block, error) { - if err := verifcid.ValidateCid(c); err != nil { + if err := verifcid.ValidateCid(verifcid.DefaultAllowlist, c); err != nil { return nil, err } return bs.GCBlockstore.Get(ctx, c) @@ -41,7 +41,7 @@ type VerifBS struct { } func (bs *VerifBS) Put(ctx context.Context, b blocks.Block) error { - if err := verifcid.ValidateCid(b.Cid()); err != nil { + if err := verifcid.ValidateCid(verifcid.DefaultAllowlist, b.Cid()); err != nil { return err } return bs.Blockstore.Put(ctx, b) @@ -49,7 +49,7 @@ func (bs *VerifBS) Put(ctx context.Context, b blocks.Block) error { func (bs *VerifBS) PutMany(ctx context.Context, blks []blocks.Block) error { for _, b := range blks { - if err := verifcid.ValidateCid(b.Cid()); err != nil { + if err := verifcid.ValidateCid(verifcid.DefaultAllowlist, b.Cid()); err != nil { return err } } @@ -57,7 +57,7 @@ func (bs *VerifBS) PutMany(ctx context.Context, blks []blocks.Block) error { } func (bs *VerifBS) Get(ctx context.Context, c cid.Cid) (blocks.Block, error) { - if err := verifcid.ValidateCid(c); err != nil { + if err := verifcid.ValidateCid(verifcid.DefaultAllowlist, c); err != nil { return nil, err } return bs.Blockstore.Get(ctx, c) From f12b372af9cc32975ff48397708fac3ec1f9966f Mon Sep 17 00:00:00 2001 From: Kay Date: Thu, 17 Aug 2023 15:32:08 +0330 Subject: [PATCH 0820/1212] style: gofumpt and godot [skip changelog] (#10081) --- assets/assets.go | 4 +- client/rpc/api.go | 10 +-- client/rpc/apifile.go | 13 ++-- client/rpc/block.go | 2 +- client/rpc/dag.go | 10 +-- client/rpc/errors.go | 4 +- client/rpc/object.go | 2 +- client/rpc/path.go | 2 +- client/rpc/pin.go | 2 +- client/rpc/pubsub.go | 3 +- client/rpc/response.go | 5 +- client/rpc/routing.go | 1 - cmd/ipfs/add_migrations.go | 4 +- cmd/ipfs/daemon.go | 20 +++--- cmd/ipfs/dnsresolve_test.go | 3 +- cmd/ipfs/init.go | 2 +- cmd/ipfs/ipfs.go | 2 +- cmd/ipfs/main.go | 12 ++-- cmd/ipfs/pinmfs.go | 2 +- cmd/ipfs/runmain_test.go | 4 +- cmd/ipfs/util/ulimit.go | 10 +-- cmd/ipfswatch/main.go | 11 ++-- commands/context.go | 4 +- commands/reqlog.go | 16 ++--- config/autonat.go | 2 +- config/config.go | 10 +-- config/datastore.go | 2 +- config/dns.go | 2 +- config/gateway.go | 1 - config/identity.go | 10 +-- config/init.go | 6 +- config/migration.go | 2 +- config/mounts.go | 2 +- config/profile.go | 6 +- config/reprovider.go | 6 +- config/routing.go | 10 +-- config/routing_test.go | 66 ++++++++++--------- config/serialize/serialize.go | 6 +- config/serialize/serialize_test.go | 2 +- config/swarm.go | 2 +- config/types.go | 58 +++++++++------- config/types_test.go | 3 - core/bootstrap/bootstrap.go | 2 - core/commands/bootstrap.go | 4 +- core/commands/cmdenv/cidbase.go | 6 +- core/commands/cmdutils/utils.go | 1 - core/commands/commands_test.go | 1 + core/commands/completion.go | 1 - core/commands/config.go | 1 - core/commands/config_test.go | 1 - core/commands/dag/dag.go | 9 +-- core/commands/dag/export.go | 1 - core/commands/external.go | 2 +- core/commands/files.go | 9 ++- core/commands/keystore.go | 3 - core/commands/name/publish.go | 4 +- core/commands/p2p.go | 4 +- core/commands/pin/remotepin.go | 22 ++++--- core/commands/pin/remotepin_test.go | 1 - core/commands/root.go | 6 +- core/commands/routing.go | 11 ++-- core/commands/swarm.go | 3 +- core/core.go | 1 - core/coreapi/swarm.go | 6 +- core/coreapi/unixfs.go | 13 ++-- core/corehttp/commands.go | 12 ++-- core/corehttp/metrics.go | 12 ++-- core/coreunix/add_test.go | 2 - core/node/groups.go | 1 - core/node/helpers/helpers.go | 1 + core/node/libp2p/rcmgr.go | 3 +- core/node/libp2p/rcmgr_logging.go | 30 ++++++++- core/node/libp2p/routing.go | 1 - core/node/libp2p/topicdiscovery.go | 1 - core/node/libp2p/transport.go | 3 +- docs/examples/kubo-as-a-library/main.go | 4 +- fuse/ipns/ipns_test.go | 19 +++--- fuse/ipns/ipns_unix.go | 24 +++---- fuse/ipns/link_unix.go | 2 +- fuse/mount/fuse.go | 4 +- fuse/mount/mount.go | 4 +- fuse/node/mount_darwin.go | 2 +- fuse/node/mount_test.go | 2 +- fuse/node/mount_unix.go | 6 +- fuse/readonly/ipfs_test.go | 12 ++-- fuse/readonly/readonly_unix.go | 16 ++--- gc/gc.go | 1 - p2p/listener.go | 6 +- p2p/local.go | 4 +- p2p/p2p.go | 6 +- p2p/remote.go | 4 +- p2p/stream.go | 12 ++-- peering/peering.go | 3 +- plugin/datastore.go | 2 +- plugin/ipld.go | 2 +- plugin/loader/loader.go | 6 +- plugin/plugins/badgerds/badgerds.go | 6 +- plugin/plugins/dagjose/dagjose.go | 2 +- plugin/plugins/flatfs/flatfs.go | 4 +- plugin/plugins/git/git.go | 2 +- plugin/plugins/levelds/levelds.go | 4 +- plugin/plugins/peerlog/peerlog.go | 6 +- plugin/tracer.go | 2 +- repo/common/common.go | 2 +- repo/fsrepo/config_test.go | 2 +- repo/fsrepo/datastores.go | 19 +++--- repo/fsrepo/fsrepo.go | 26 ++++---- repo/fsrepo/migrations/fetch.go | 4 +- repo/fsrepo/migrations/fetch_test.go | 4 +- repo/fsrepo/migrations/fetcher.go | 7 +- repo/fsrepo/migrations/httpfetcher.go | 4 +- repo/fsrepo/migrations/ipfsdir.go | 2 +- repo/fsrepo/migrations/ipfsdir_test.go | 2 +- .../migrations/ipfsfetcher/ipfsfetcher.go | 4 +- .../ipfsfetcher/ipfsfetcher_test.go | 3 +- repo/fsrepo/migrations/migrations.go | 2 +- repo/fsrepo/migrations/migrations_test.go | 2 +- repo/fsrepo/migrations/unpack_test.go | 7 +- repo/mock.go | 2 +- repo/repo.go | 4 +- routing/composer.go | 7 +- routing/delegated_test.go | 1 - routing/wrapper.go | 6 +- tar/format.go | 8 ++- test/cli/basic_commands_test.go | 2 - test/cli/content_routing_http_test.go | 1 + test/cli/dag_test.go | 1 - test/cli/delegated_routing_http_test.go | 1 - test/cli/dht_legacy_test.go | 1 - test/cli/gateway_test.go | 3 - test/cli/harness/harness.go | 6 +- test/cli/harness/node.go | 2 +- test/cli/harness/peering.go | 1 - test/cli/harness/run.go | 8 +-- test/cli/init_test.go | 4 +- test/cli/pins_test.go | 2 - test/cli/swarm_test.go | 3 - test/cli/testutils/random_files.go | 8 ++- test/cli/tracing_test.go | 2 +- test/cli/transports_test.go | 3 +- test/dependencies/iptb/iptb.go | 1 - test/dependencies/ma-pipe-unidir/main.go | 4 +- test/integration/bench_test.go | 1 - test/integration/wan_lan_dht_test.go | 6 +- thirdparty/dir/dir.go | 2 +- thirdparty/notifier/notifier_test.go | 4 +- thirdparty/unit/unit.go | 3 +- version.go | 6 +- 148 files changed, 449 insertions(+), 433 deletions(-) diff --git a/assets/assets.go b/assets/assets.go index 945e8e10a..9dff80e07 100644 --- a/assets/assets.go +++ b/assets/assets.go @@ -17,7 +17,7 @@ import ( //go:embed init-doc var Asset embed.FS -// initDocPaths lists the paths for the docs we want to seed during --init +// initDocPaths lists the paths for the docs we want to seed during --init. var initDocPaths = []string{ gopath.Join("init-doc", "about"), gopath.Join("init-doc", "readme"), @@ -28,7 +28,7 @@ var initDocPaths = []string{ gopath.Join("init-doc", "ping"), } -// SeedInitDocs adds the list of embedded init documentation to the passed node, pins it and returns the root key +// SeedInitDocs adds the list of embedded init documentation to the passed node, pins it and returns the root key. func SeedInitDocs(nd *core.IpfsNode) (cid.Cid, error) { return addAssetList(nd, initDocPaths) } diff --git a/client/rpc/api.go b/client/rpc/api.go index 404f4b312..cb791e7ee 100644 --- a/client/rpc/api.go +++ b/client/rpc/api.go @@ -48,7 +48,7 @@ type HttpApi struct { // IPFS daemon // // Daemon api address is pulled from the $IPFS_PATH/api file. -// If $IPFS_PATH env var is not present, it defaults to ~/.ipfs +// If $IPFS_PATH env var is not present, it defaults to ~/.ipfs. func NewLocalApi() (*HttpApi, error) { baseDir := os.Getenv(EnvDir) if baseDir == "" { @@ -59,7 +59,7 @@ func NewLocalApi() (*HttpApi, error) { } // NewPathApi constructs new HttpApi by pulling api address from specified -// ipfspath. Api file should be located at $ipfspath/api +// ipfspath. Api file should be located at $ipfspath/api. func NewPathApi(ipfspath string) (*HttpApi, error) { a, err := ApiAddr(ipfspath) if err != nil { @@ -71,7 +71,7 @@ func NewPathApi(ipfspath string) (*HttpApi, error) { return NewApi(a) } -// ApiAddr reads api file in specified ipfs path +// ApiAddr reads api file in specified ipfs path. func ApiAddr(ipfspath string) (ma.Multiaddr, error) { baseDir, err := homedir.Expand(ipfspath) if err != nil { @@ -88,7 +88,7 @@ func ApiAddr(ipfspath string) (ma.Multiaddr, error) { return ma.NewMultiaddr(strings.TrimSpace(string(api))) } -// NewApi constructs HttpApi with specified endpoint +// NewApi constructs HttpApi with specified endpoint. func NewApi(a ma.Multiaddr) (*HttpApi, error) { c := &http.Client{ Transport: &http.Transport{ @@ -100,7 +100,7 @@ func NewApi(a ma.Multiaddr) (*HttpApi, error) { return NewApiWithClient(a, c) } -// NewApiWithClient constructs HttpApi with specified endpoint and custom http client +// NewApiWithClient constructs HttpApi with specified endpoint and custom http client. func NewApiWithClient(a ma.Multiaddr, c *http.Client) (*HttpApi, error) { _, url, err := manet.DialArgs(a) if err != nil { diff --git a/client/rpc/apifile.go b/client/rpc/apifile.go index 24e93a834..873a67b7b 100644 --- a/client/rpc/apifile.go +++ b/client/rpc/apifile.go @@ -12,7 +12,7 @@ import ( "github.com/ipfs/go-cid" ) -const forwardSeekLimit = 1 << 14 //16k +const forwardSeekLimit = 1 << 14 // 16k func (api *UnixfsAPI) Get(ctx context.Context, p path.Path) (files.Node, error) { if p.Mutable() { // use resolved path in case we are dealing with IPNS / MFS @@ -107,11 +107,11 @@ func (f *apiFile) Seek(offset int64, whence int) (int64, error) { case io.SeekCurrent: offset = f.at + offset } - if f.at == offset { //noop + if f.at == offset { // noop return offset, nil } - if f.at < offset && offset-f.at < forwardSeekLimit { //forward skip + if f.at < offset && offset-f.at < forwardSeekLimit { // forward skip r, err := io.CopyN(io.Discard, f.r.Output, offset-f.at) f.at += r @@ -246,7 +246,6 @@ func (api *UnixfsAPI) getDir(ctx context.Context, p path.Path, size int64) (file resp, err := api.core().Request("ls", p.String()). Option("resolve-size", true). Option("stream", true).Send(ctx) - if err != nil { return nil, err } @@ -266,5 +265,7 @@ func (api *UnixfsAPI) getDir(ctx context.Context, p path.Path, size int64) (file return d, nil } -var _ files.File = &apiFile{} -var _ files.Directory = &apiDir{} +var ( + _ files.File = &apiFile{} + _ files.Directory = &apiDir{} +) diff --git a/client/rpc/block.go b/client/rpc/block.go index a11e5e655..2b0048380 100644 --- a/client/rpc/block.go +++ b/client/rpc/block.go @@ -83,7 +83,7 @@ func (api *BlockAPI) Get(ctx context.Context, p path.Path) (io.Reader, error) { return nil, parseErrNotFoundWithFallbackToError(resp.Error) } - //TODO: make get return ReadCloser to avoid copying + // TODO: make get return ReadCloser to avoid copying defer resp.Close() b := new(bytes.Buffer) if _, err := io.Copy(b, resp.Output); err != nil { diff --git a/client/rpc/dag.go b/client/rpc/dag.go index 69f83abfe..f4c9be351 100644 --- a/client/rpc/dag.go +++ b/client/rpc/dag.go @@ -14,9 +14,11 @@ import ( multicodec "github.com/multiformats/go-multicodec" ) -type httpNodeAdder HttpApi -type HttpDagServ httpNodeAdder -type pinningHttpNodeAdder httpNodeAdder +type ( + httpNodeAdder HttpApi + HttpDagServ httpNodeAdder + pinningHttpNodeAdder httpNodeAdder +) func (api *HttpDagServ) Get(ctx context.Context, c cid.Cid) (format.Node, error) { r, err := api.core().Block().Get(ctx, path.IpldPath(c)) @@ -114,7 +116,7 @@ func (api *HttpDagServ) Pinning() format.NodeAdder { } func (api *HttpDagServ) Remove(ctx context.Context, c cid.Cid) error { - return api.core().Block().Rm(ctx, path.IpldPath(c)) //TODO: should we force rm? + return api.core().Block().Rm(ctx, path.IpldPath(c)) // TODO: should we force rm? } func (api *HttpDagServ) RemoveMany(ctx context.Context, cids []cid.Cid) error { diff --git a/client/rpc/errors.go b/client/rpc/errors.go index dc5946be3..84340b550 100644 --- a/client/rpc/errors.go +++ b/client/rpc/errors.go @@ -68,7 +68,7 @@ func parseErrNotFound(msg string) (error, bool) { // Assume CIDs break on: // - Whitespaces: " \t\n\r\v\f" // - Semicolon: ";" this is to parse ipld.ErrNotFound wrapped in multierr -// - Double Quotes: "\"" this is for parsing %q and %#v formating +// - Double Quotes: "\"" this is for parsing %q and %#v formating. const cidBreakSet = " \t\n\r\v\f;\"" func parseIPLDErrNotFound(msg string) (error, bool) { @@ -139,7 +139,7 @@ func parseIPLDErrNotFound(msg string) (error, bool) { // This is a simple error type that just return msg as Error(). // But that also match ipld.ErrNotFound when called with Is(err). // That is needed to keep compatiblity with code that use string.Contains(err.Error(), "blockstore: block not found") -// and code using ipld.ErrNotFound +// and code using ipld.ErrNotFound. type blockstoreNotFoundMatchingIPLDErrNotFound struct { msg string } diff --git a/client/rpc/object.go b/client/rpc/object.go index 5860c7661..7464cea1a 100644 --- a/client/rpc/object.go +++ b/client/rpc/object.go @@ -87,7 +87,7 @@ func (api *ObjectAPI) Data(ctx context.Context, p path.Path) (io.Reader, error) return nil, resp.Error } - //TODO: make Data return ReadCloser to avoid copying + // TODO: make Data return ReadCloser to avoid copying defer resp.Close() b := new(bytes.Buffer) if _, err := io.Copy(b, resp.Output); err != nil { diff --git a/client/rpc/path.go b/client/rpc/path.go index 6edf0e797..1b88eb07d 100644 --- a/client/rpc/path.go +++ b/client/rpc/path.go @@ -15,7 +15,7 @@ func (api *HttpApi) ResolvePath(ctx context.Context, p path.Path) (path.Resolved RemPath string } - //TODO: this is hacky, fixing https://github.com/ipfs/go-ipfs/issues/5703 would help + // TODO: this is hacky, fixing https://github.com/ipfs/go-ipfs/issues/5703 would help var err error if p.Namespace() == "ipns" { diff --git a/client/rpc/pin.go b/client/rpc/pin.go index dc85b9f30..e8aecf11c 100644 --- a/client/rpc/pin.go +++ b/client/rpc/pin.go @@ -112,7 +112,7 @@ func (api *PinAPI) Ls(ctx context.Context, opts ...caopts.PinLsOption) (<-chan i } // IsPinned returns whether or not the given cid is pinned -// and an explanation of why its pinned +// and an explanation of why its pinned. func (api *PinAPI) IsPinned(ctx context.Context, p path.Path, opts ...caopts.PinIsPinnedOption) (string, bool, error) { options, err := caopts.PinIsPinnedOptions(opts...) if err != nil { diff --git a/client/rpc/pubsub.go b/client/rpc/pubsub.go index a386c80a1..f255da5ad 100644 --- a/client/rpc/pubsub.go +++ b/client/rpc/pubsub.go @@ -152,7 +152,6 @@ func (api *PubsubAPI) Subscribe(ctx context.Context, topic string, opts ...caopt } */ resp, err := api.core().Request("pubsub/sub", toMultibase([]byte(topic))).Send(ctx) - if err != nil { return nil, err } @@ -207,7 +206,7 @@ func (api *PubsubAPI) core() *HttpApi { return (*HttpApi)(api) } -// Encodes bytes into URL-safe multibase that can be sent over HTTP RPC (URL or body) +// Encodes bytes into URL-safe multibase that can be sent over HTTP RPC (URL or body). func toMultibase(data []byte) string { mb, _ := mbase.Encode(mbase.Base64url, data) return mb diff --git a/client/rpc/response.go b/client/rpc/response.go index bad274777..c47da4a68 100644 --- a/client/rpc/response.go +++ b/client/rpc/response.go @@ -54,7 +54,7 @@ func (r *Response) Close() error { return nil } -// Cancel aborts running request (without draining request body) +// Cancel aborts running request (without draining request body). func (r *Response) Cancel() error { if r.Output != nil { return r.Output.Close() @@ -63,7 +63,7 @@ func (r *Response) Cancel() error { return nil } -// Decode reads request body and decodes it as json +// Decode reads request body and decodes it as json. func (r *Response) decode(dec interface{}) error { if r.Error != nil { return r.Error @@ -157,7 +157,6 @@ func (r *Request) Send(c *http.Client) (*Response, error) { } func (r *Request) getURL() string { - values := make(url.Values) for _, arg := range r.Args { values.Add("arg", arg) diff --git a/client/rpc/routing.go b/client/rpc/routing.go index a6c4f5c08..babed15fb 100644 --- a/client/rpc/routing.go +++ b/client/rpc/routing.go @@ -49,7 +49,6 @@ func (api *RoutingAPI) Put(ctx context.Context, key string, value []byte, opts . Option("allow-offline", cfg.AllowOffline). FileBody(bytes.NewReader(value)). Send(ctx) - if err != nil { return err } diff --git a/cmd/ipfs/add_migrations.go b/cmd/ipfs/add_migrations.go index e0a5d7101..e01381121 100644 --- a/cmd/ipfs/add_migrations.go +++ b/cmd/ipfs/add_migrations.go @@ -19,7 +19,7 @@ import ( "github.com/libp2p/go-libp2p/core/peer" ) -// addMigrations adds any migration downloaded by the fetcher to the IPFS node +// addMigrations adds any migration downloaded by the fetcher to the IPFS node. func addMigrations(ctx context.Context, node *core.IpfsNode, fetcher migrations.Fetcher, pin bool) error { var fetchers []migrations.Fetcher if mf, ok := fetcher.(*migrations.MultiFetcher); ok { @@ -63,7 +63,7 @@ func addMigrations(ctx context.Context, node *core.IpfsNode, fetcher migrations. return nil } -// addMigrationFiles adds the files at paths to IPFS, optionally pinning them +// addMigrationFiles adds the files at paths to IPFS, optionally pinning them. func addMigrationFiles(ctx context.Context, node *core.IpfsNode, paths []string, pin bool) error { if len(paths) == 0 { return nil diff --git a/cmd/ipfs/daemon.go b/cmd/ipfs/daemon.go index 5788bf3ce..7be97e23b 100644 --- a/cmd/ipfs/daemon.go +++ b/cmd/ipfs/daemon.go @@ -73,7 +73,7 @@ const ( enableMultiplexKwd = "enable-mplex-experiment" agentVersionSuffix = "agent-version-suffix" // apiAddrKwd = "address-api" - // swarmAddrKwd = "address-swarm" + // swarmAddrKwd = "address-swarm". ) var daemonCmd = &cmds.Command{ @@ -389,7 +389,7 @@ func daemonFunc(req *cmds.Request, re cmds.ResponseEmitter, env cmds.Environment "pubsub": pubsub, "ipnsps": ipnsps, }, - //TODO(Kubuxu): refactor Online vs Offline by adding Permanent vs Ephemeral + // TODO(Kubuxu): refactor Online vs Offline by adding Permanent vs Ephemeral } routingOption, _ := req.Options[routingOptionKwd].(string) @@ -552,7 +552,7 @@ take effect. } // Add ipfs version info to prometheus metrics - var ipfsInfoMetric = promauto.NewGaugeVec(prometheus.GaugeOpts{ + ipfsInfoMetric := promauto.NewGaugeVec(prometheus.GaugeOpts{ Name: "ipfs_info", Help: "IPFS version information.", }, []string{"version", "commit"}) @@ -607,7 +607,6 @@ take effect. log.Error("failed to bootstrap (no peers found): consider updating Bootstrap or Peering section of your config") } }) - } // Hard deprecation notice if someone still uses IPFS_REUSEPORT @@ -627,7 +626,7 @@ take effect. return errs } -// serveHTTPApi collects options, creates listener, prints status message and starts serving requests +// serveHTTPApi collects options, creates listener, prints status message and starts serving requests. func serveHTTPApi(req *cmds.Request, cctx *oldcmds.Context) (<-chan error, error) { cfg, err := cctx.GetConfig() if err != nil { @@ -690,7 +689,7 @@ func serveHTTPApi(req *cmds.Request, cctx *oldcmds.Context) (<-chan error, error gatewayOpt = corehttp.GatewayOption("/ipfs", "/ipns") } - var opts = []corehttp.ServeOption{ + opts := []corehttp.ServeOption{ corehttp.MetricsCollectionOption("api"), corehttp.MetricsOpenCensusCollectionOption(), corehttp.MetricsOpenCensusDefaultPrometheusRegistry(), @@ -752,7 +751,7 @@ func rewriteMaddrToUseLocalhostIfItsAny(maddr ma.Multiaddr) ma.Multiaddr { } } -// printSwarmAddrs prints the addresses of the host +// printSwarmAddrs prints the addresses of the host. func printSwarmAddrs(node *core.IpfsNode) { if !node.IsOnline { fmt.Println("Swarm not listening, running in offline mode.") @@ -781,10 +780,9 @@ func printSwarmAddrs(node *core.IpfsNode) { for _, addr := range addrs { fmt.Printf("Swarm announcing %s\n", addr) } - } -// serveHTTPGateway collects options, creates listener, prints status message and starts serving requests +// serveHTTPGateway collects options, creates listener, prints status message and starts serving requests. func serveHTTPGateway(req *cmds.Request, cctx *oldcmds.Context) (<-chan error, error) { cfg, err := cctx.GetConfig() if err != nil { @@ -837,7 +835,7 @@ func serveHTTPGateway(req *cmds.Request, cctx *oldcmds.Context) (<-chan error, e cmdctx := *cctx cmdctx.Gateway = true - var opts = []corehttp.ServeOption{ + opts := []corehttp.ServeOption{ corehttp.MetricsCollectionOption("gateway"), corehttp.HostnameOption(), corehttp.GatewayOption("/ipfs", "/ipns"), @@ -891,7 +889,7 @@ func serveHTTPGateway(req *cmds.Request, cctx *oldcmds.Context) (<-chan error, e return errc, nil } -// collects options and opens the fuse mountpoint +// collects options and opens the fuse mountpoint. func mountFuse(req *cmds.Request, cctx *oldcmds.Context) error { cfg, err := cctx.GetConfig() if err != nil { diff --git a/cmd/ipfs/dnsresolve_test.go b/cmd/ipfs/dnsresolve_test.go index fcba5d697..8ffa0ebde 100644 --- a/cmd/ipfs/dnsresolve_test.go +++ b/cmd/ipfs/dnsresolve_test.go @@ -25,7 +25,8 @@ func makeResolver(t *testing.T, n uint8) *madns.Resolver { backend := &madns.MockResolver{ IP: map[string][]net.IPAddr{ "example.com": results, - }} + }, + } resolver, err := madns.NewResolver(madns.WithDefaultResolver(backend)) if err != nil { diff --git a/cmd/ipfs/init.go b/cmd/ipfs/init.go index 28845faa5..0c5223d7f 100644 --- a/cmd/ipfs/init.go +++ b/cmd/ipfs/init.go @@ -194,7 +194,7 @@ func checkWritable(dir string) error { if os.IsNotExist(err) { // dir doesn't exist, check that we can create it - return os.Mkdir(dir, 0775) + return os.Mkdir(dir, 0o775) } if os.IsPermission(err) { diff --git a/cmd/ipfs/ipfs.go b/cmd/ipfs/ipfs.go index 24aea66c7..3b953c40c 100644 --- a/cmd/ipfs/ipfs.go +++ b/cmd/ipfs/ipfs.go @@ -14,7 +14,7 @@ var Root = &cmds.Command{ Helptext: commands.Root.Helptext, } -// commandsClientCmd is the "ipfs commands" command for local cli +// commandsClientCmd is the "ipfs commands" command for local cli. var commandsClientCmd = commands.CommandsCmd(Root) // Commands in localCommands should always be run locally (even if daemon is running). diff --git a/cmd/ipfs/main.go b/cmd/ipfs/main.go index c1e529932..22fdca91b 100644 --- a/cmd/ipfs/main.go +++ b/cmd/ipfs/main.go @@ -39,11 +39,13 @@ import ( "go.opentelemetry.io/otel/trace" ) -// log is the command logger -var log = logging.Logger("cmd/ipfs") -var tracer trace.Tracer +// log is the command logger. +var ( + log = logging.Logger("cmd/ipfs") + tracer trace.Tracer +) -// declared as a var for testing purposes +// declared as a var for testing purposes. var dnsResolver = madns.DefaultResolver const ( @@ -73,7 +75,7 @@ func loadPlugins(repoPath string) (*loader.PluginLoader, error) { // - if user requests help, print it and exit. // - run the command invocation // - output the response -// - if anything fails, print error, maybe with help +// - if anything fails, print error, maybe with help. func main() { os.Exit(mainRet()) } diff --git a/cmd/ipfs/pinmfs.go b/cmd/ipfs/pinmfs.go index c2c0cb8b7..977d96ba0 100644 --- a/cmd/ipfs/pinmfs.go +++ b/cmd/ipfs/pinmfs.go @@ -18,7 +18,7 @@ import ( "github.com/ipfs/kubo/core" ) -// mfslog is the logger for remote mfs pinning +// mfslog is the logger for remote mfs pinning. var mfslog = logging.Logger("remotepinning/mfs") type lastPin struct { diff --git a/cmd/ipfs/runmain_test.go b/cmd/ipfs/runmain_test.go index d91879112..4d73cfd43 100644 --- a/cmd/ipfs/runmain_test.go +++ b/cmd/ipfs/runmain_test.go @@ -12,7 +12,7 @@ import ( // this abuses go so much that I felt dirty writing this code // but it is the only way to do it without writing custom compiler that would -// be a clone of go-build with go-test +// be a clone of go-build with go-test. func TestRunMain(t *testing.T) { args := flag.Args() os.Args = append([]string{os.Args[0]}, args...) @@ -20,7 +20,7 @@ func TestRunMain(t *testing.T) { p := os.Getenv("IPFS_COVER_RET_FILE") if len(p) != 0 { - os.WriteFile(p, []byte(fmt.Sprintf("%d\n", ret)), 0777) + os.WriteFile(p, []byte(fmt.Sprintf("%d\n", ret)), 0o777) } // close outputs so go testing doesn't print anything diff --git a/cmd/ipfs/util/ulimit.go b/cmd/ipfs/util/ulimit.go index e024ced84..a00e81076 100644 --- a/cmd/ipfs/util/ulimit.go +++ b/cmd/ipfs/util/ulimit.go @@ -14,19 +14,19 @@ var log = logging.Logger("ulimit") var ( supportsFDManagement = false - // getlimit returns the soft and hard limits of file descriptors counts + // getlimit returns the soft and hard limits of file descriptors counts. getLimit func() (uint64, uint64, error) - // set limit sets the soft and hard limits of file descriptors counts + // set limit sets the soft and hard limits of file descriptors counts. setLimit func(uint64, uint64) error ) -// minimum file descriptor limit before we complain +// minimum file descriptor limit before we complain. const minFds = 2048 // default max file descriptor limit. const maxFds = 8192 -// userMaxFDs returns the value of IPFS_FD_MAX +// userMaxFDs returns the value of IPFS_FD_MAX. func userMaxFDs() uint64 { // check if the IPFS_FD_MAX is set up and if it does // not have a valid fds number notify the user @@ -42,7 +42,7 @@ func userMaxFDs() uint64 { } // ManageFdLimit raise the current max file descriptor count -// of the process based on the IPFS_FD_MAX value +// of the process based on the IPFS_FD_MAX value. func ManageFdLimit() (changed bool, newLimit uint64, err error) { if !supportsFDManagement { return false, 0, nil diff --git a/cmd/ipfswatch/main.go b/cmd/ipfswatch/main.go index 9f2558e25..0f0283fb8 100644 --- a/cmd/ipfswatch/main.go +++ b/cmd/ipfswatch/main.go @@ -24,9 +24,11 @@ import ( homedir "github.com/mitchellh/go-homedir" ) -var http = flag.Bool("http", false, "expose IPFS HTTP API") -var repoPath = flag.String("repo", os.Getenv("IPFS_PATH"), "IPFS_PATH to use") -var watchPath = flag.String("path", ".", "the path to watch") +var ( + http = flag.Bool("http", false, "expose IPFS HTTP API") + repoPath = flag.String("repo", os.Getenv("IPFS_PATH"), "IPFS_PATH to use") + watchPath = flag.String("path", ".", "the path to watch") +) func main() { flag.Parse() @@ -52,7 +54,6 @@ func main() { } func run(ipfsPath, watchPath string) error { - proc := process.WithParent(process.Background()) log.Printf("running IPFSWatch on '%s' using repo at '%s'...", watchPath, ipfsPath) @@ -93,7 +94,7 @@ func run(ipfsPath, watchPath string) error { if *http { addr := "/ip4/127.0.0.1/tcp/5001" - var opts = []corehttp.ServeOption{ + opts := []corehttp.ServeOption{ corehttp.GatewayOption("/ipfs", "/ipns"), corehttp.WebUIOption, corehttp.CommandsOption(cmdCtx(node, ipfsPath)), diff --git a/commands/context.go b/commands/context.go index fa1022819..855db1afe 100644 --- a/commands/context.go +++ b/commands/context.go @@ -19,7 +19,7 @@ import ( var log = logging.Logger("command") -// Context represents request context +// Context represents request context. type Context struct { ConfigRoot string ReqLog *ReqLog @@ -54,7 +54,7 @@ func (c *Context) GetNode() (*core.IpfsNode, error) { } // GetAPI returns CoreAPI instance backed by ipfs node. -// It may construct the node with the provided function +// It may construct the node with the provided function. func (c *Context) GetAPI() (coreiface.CoreAPI, error) { if c.api == nil { n, err := c.GetNode() diff --git a/commands/reqlog.go b/commands/reqlog.go index 14c10a7c0..444bbcd3e 100644 --- a/commands/reqlog.go +++ b/commands/reqlog.go @@ -5,7 +5,7 @@ import ( "time" ) -// ReqLogEntry is an entry in the request log +// ReqLogEntry is an entry in the request log. type ReqLogEntry struct { StartTime time.Time EndTime time.Time @@ -18,14 +18,14 @@ type ReqLogEntry struct { log *ReqLog } -// Copy returns a copy of the ReqLogEntry +// Copy returns a copy of the ReqLogEntry. func (r *ReqLogEntry) Copy() *ReqLogEntry { out := *r out.log = nil return &out } -// ReqLog is a log of requests +// ReqLog is a log of requests. type ReqLog struct { Requests []*ReqLogEntry nextID int @@ -33,7 +33,7 @@ type ReqLog struct { keep time.Duration } -// AddEntry adds an entry to the log +// AddEntry adds an entry to the log. func (rl *ReqLog) AddEntry(rle *ReqLogEntry) { rl.lock.Lock() defer rl.lock.Unlock() @@ -47,7 +47,7 @@ func (rl *ReqLog) AddEntry(rle *ReqLogEntry) { } } -// ClearInactive removes stale entries +// ClearInactive removes stale entries. func (rl *ReqLog) ClearInactive() { rl.lock.Lock() defer rl.lock.Unlock() @@ -79,14 +79,14 @@ func (rl *ReqLog) cleanup() { rl.Requests = rl.Requests[:i] } -// SetKeepTime sets a duration after which an entry will be considered inactive +// SetKeepTime sets a duration after which an entry will be considered inactive. func (rl *ReqLog) SetKeepTime(t time.Duration) { rl.lock.Lock() defer rl.lock.Unlock() rl.keep = t } -// Report generates a copy of all the entries in the requestlog +// Report generates a copy of all the entries in the requestlog. func (rl *ReqLog) Report() []*ReqLogEntry { rl.lock.Lock() defer rl.lock.Unlock() @@ -99,7 +99,7 @@ func (rl *ReqLog) Report() []*ReqLogEntry { return out } -// Finish marks an entry in the log as finished +// Finish marks an entry in the log as finished. func (rl *ReqLog) Finish(rle *ReqLogEntry) { rl.lock.Lock() defer rl.lock.Unlock() diff --git a/config/autonat.go b/config/autonat.go index 64856faa6..eb87b48e6 100644 --- a/config/autonat.go +++ b/config/autonat.go @@ -64,7 +64,7 @@ type AutoNATConfig struct { Throttle *AutoNATThrottleConfig `json:",omitempty"` } -// AutoNATThrottleConfig configures the throttle limites +// AutoNATThrottleConfig configures the throttle limites. type AutoNATThrottleConfig struct { // GlobalLimit and PeerLimit sets the global and per-peer dialback // limits. The AutoNAT service will only perform the specified number of diff --git a/config/config.go b/config/config.go index bc8ea371f..035fbe296 100644 --- a/config/config.go +++ b/config/config.go @@ -41,17 +41,17 @@ type Config struct { } const ( - // DefaultPathName is the default config dir name + // DefaultPathName is the default config dir name. DefaultPathName = ".ipfs" // DefaultPathRoot is the path to the default config dir location. DefaultPathRoot = "~/" + DefaultPathName - // DefaultConfigFile is the filename of the configuration file + // DefaultConfigFile is the filename of the configuration file. DefaultConfigFile = "config" // EnvDir is the environment variable used to change the path root. EnvDir = "IPFS_PATH" ) -// PathRoot returns the default configuration root directory +// PathRoot returns the default configuration root directory. func PathRoot() (string, error) { dir := os.Getenv(EnvDir) var err error @@ -95,7 +95,7 @@ func Filename(configroot, userConfigFile string) (string, error) { return userConfigFile, nil } -// HumanOutput gets a config value ready for printing +// HumanOutput gets a config value ready for printing. func HumanOutput(value interface{}) ([]byte, error) { s, ok := value.(string) if ok { @@ -104,7 +104,7 @@ func HumanOutput(value interface{}) ([]byte, error) { return Marshal(value) } -// Marshal configuration with JSON +// Marshal configuration with JSON. func Marshal(value interface{}) ([]byte, error) { // need to prettyprint, hence MarshalIndent, instead of Encoder return json.MarshalIndent(value, "", " ") diff --git a/config/datastore.go b/config/datastore.go index 2b2bcb518..1a5994a17 100644 --- a/config/datastore.go +++ b/config/datastore.go @@ -26,7 +26,7 @@ type Datastore struct { } // DataStorePath returns the default data store path given a configuration root -// (set an empty string to have the default configuration root) +// (set an empty string to have the default configuration root). func DataStorePath(configroot string) (string, error) { return Path(configroot, DefaultDataStoreDirectory) } diff --git a/config/dns.go b/config/dns.go index 444d99088..8e1fc85a5 100644 --- a/config/dns.go +++ b/config/dns.go @@ -1,6 +1,6 @@ package config -// DNS specifies DNS resolution rules using custom resolvers +// DNS specifies DNS resolution rules using custom resolvers. type DNS struct { // Resolvers is a map of FQDNs to URLs for custom DNS resolution. // URLs starting with `https://` indicate DoH endpoints. diff --git a/config/gateway.go b/config/gateway.go index 816b1f48d..a65582849 100644 --- a/config/gateway.go +++ b/config/gateway.go @@ -37,7 +37,6 @@ type GatewaySpec struct { // Gateway contains options for the HTTP gateway server. type Gateway struct { - // HTTPHeaders configures the headers that should be returned by this // gateway. HTTPHeaders map[string][]string // HTTP headers to return with the gateway diff --git a/config/identity.go b/config/identity.go index 6117365c9..5b661dfb4 100644 --- a/config/identity.go +++ b/config/identity.go @@ -6,9 +6,11 @@ import ( ic "github.com/libp2p/go-libp2p/core/crypto" ) -const IdentityTag = "Identity" -const PrivKeyTag = "PrivKey" -const PrivKeySelector = IdentityTag + "." + PrivKeyTag +const ( + IdentityTag = "Identity" + PrivKeyTag = "PrivKey" + PrivKeySelector = IdentityTag + "." + PrivKeyTag +) // Identity tracks the configuration of the local node's identity. type Identity struct { @@ -16,7 +18,7 @@ type Identity struct { PrivKey string `json:",omitempty"` } -// DecodePrivateKey is a helper to decode the users PrivateKey +// DecodePrivateKey is a helper to decode the users PrivateKey. func (i *Identity) DecodePrivateKey(passphrase string) (ic.PrivKey, error) { pkb, err := base64.StdEncoding.DecodeString(i.PrivKey) if err != nil { diff --git a/config/init.go b/config/init.go index a6e3c46cc..9b0bf9dbf 100644 --- a/config/init.go +++ b/config/init.go @@ -90,15 +90,15 @@ func InitWithIdentity(identity Identity) (*Config, error) { } // DefaultConnMgrHighWater is the default value for the connection managers -// 'high water' mark +// 'high water' mark. const DefaultConnMgrHighWater = 96 // DefaultConnMgrLowWater is the default value for the connection managers 'low -// water' mark +// water' mark. const DefaultConnMgrLowWater = 32 // DefaultConnMgrGracePeriod is the default value for the connection managers -// grace period +// grace period. const DefaultConnMgrGracePeriod = time.Second * 20 // DefaultConnMgrType is the default value for the connection managers diff --git a/config/migration.go b/config/migration.go index 27d4b3c70..e172988a9 100644 --- a/config/migration.go +++ b/config/migration.go @@ -5,7 +5,7 @@ const DefaultMigrationKeep = "cache" var DefaultMigrationDownloadSources = []string{"HTTPS", "IPFS"} // Migration configures how migrations are downloaded and if the downloads are -// added to IPFS locally +// added to IPFS locally. type Migration struct { // Sources in order of preference, where "IPFS" means use IPFS and "HTTPS" // means use default gateways. Any other values are interpreted as diff --git a/config/mounts.go b/config/mounts.go index b23d30b2e..dfdd1e5bf 100644 --- a/config/mounts.go +++ b/config/mounts.go @@ -1,6 +1,6 @@ package config -// Mounts stores the (string) mount points +// Mounts stores the (string) mount points. type Mounts struct { IPFS string IPNS string diff --git a/config/profile.go b/config/profile.go index 1a4013918..83d53359d 100644 --- a/config/profile.go +++ b/config/profile.go @@ -6,10 +6,10 @@ import ( "time" ) -// Transformer is a function which takes configuration and applies some filter to it +// Transformer is a function which takes configuration and applies some filter to it. type Transformer func(c *Config) error -// Profile contains the profile transformer the description of the profile +// Profile contains the profile transformer the description of the profile. type Profile struct { // Description briefly describes the functionality of the profile. Description string @@ -43,7 +43,7 @@ var defaultServerFilters = []string{ "/ip6/fe80::/ipcidr/10", } -// Profiles is a map holding configuration transformers. Docs are in docs/config.md +// Profiles is a map holding configuration transformers. Docs are in docs/config.md. var Profiles = map[string]Profile{ "server": { Description: `Disables local host discovery, recommended when diff --git a/config/reprovider.go b/config/reprovider.go index 19ee1c58d..dae9ae6de 100644 --- a/config/reprovider.go +++ b/config/reprovider.go @@ -2,8 +2,10 @@ package config import "time" -const DefaultReproviderInterval = time.Hour * 22 // https://github.com/ipfs/kubo/pull/9326 -const DefaultReproviderStrategy = "all" +const ( + DefaultReproviderInterval = time.Hour * 22 // https://github.com/ipfs/kubo/pull/9326 + DefaultReproviderStrategy = "all" +) type Reprovider struct { Interval *OptionalDuration `json:",omitempty"` // Time period to reprovide locally stored objects to the network diff --git a/config/routing.go b/config/routing.go index ede8f0f9e..60faa605c 100644 --- a/config/routing.go +++ b/config/routing.go @@ -6,7 +6,7 @@ import ( "runtime" ) -// Routing defines configuration options for libp2p routing +// Routing defines configuration options for libp2p routing. type Routing struct { // Type sets default daemon routing mode. // @@ -23,7 +23,6 @@ type Routing struct { } type Router struct { - // Router type ID. See RouterType for more info. Type RouterType @@ -32,11 +31,12 @@ type Router struct { Parameters interface{} } -type Routers map[string]RouterParser -type Methods map[MethodName]Method +type ( + Routers map[string]RouterParser + Methods map[MethodName]Method +) func (m Methods) Check() error { - // Check supported methods for _, mn := range MethodNameList { _, ok := m[mn] diff --git a/config/routing_test.go b/config/routing_test.go index 4dfc54ccb..87a4f8cce 100644 --- a/config/routing_test.go +++ b/config/routing_test.go @@ -23,42 +23,46 @@ func TestRouterParameters(t *testing.T) { PublicIPNetwork: false, }, }}, - "router-parallel": {Router{ - Type: RouterTypeParallel, - Parameters: ComposableRouterParams{ - Routers: []ConfigRouter{ - { - RouterName: "router-dht", - Timeout: Duration{10 * time.Second}, - IgnoreErrors: true, - }, - { - RouterName: "router-dht", - Timeout: Duration{10 * time.Second}, - IgnoreErrors: false, - ExecuteAfter: &OptionalDuration{&sec}, + "router-parallel": { + Router{ + Type: RouterTypeParallel, + Parameters: ComposableRouterParams{ + Routers: []ConfigRouter{ + { + RouterName: "router-dht", + Timeout: Duration{10 * time.Second}, + IgnoreErrors: true, + }, + { + RouterName: "router-dht", + Timeout: Duration{10 * time.Second}, + IgnoreErrors: false, + ExecuteAfter: &OptionalDuration{&sec}, + }, }, + Timeout: &OptionalDuration{&min}, }, - Timeout: &OptionalDuration{&min}, - }}, + }, }, - "router-sequential": {Router{ - Type: RouterTypeSequential, - Parameters: ComposableRouterParams{ - Routers: []ConfigRouter{ - { - RouterName: "router-dht", - Timeout: Duration{10 * time.Second}, - IgnoreErrors: true, - }, - { - RouterName: "router-dht", - Timeout: Duration{10 * time.Second}, - IgnoreErrors: false, + "router-sequential": { + Router{ + Type: RouterTypeSequential, + Parameters: ComposableRouterParams{ + Routers: []ConfigRouter{ + { + RouterName: "router-dht", + Timeout: Duration{10 * time.Second}, + IgnoreErrors: true, + }, + { + RouterName: "router-dht", + Timeout: Duration{10 * time.Second}, + IgnoreErrors: false, + }, }, + Timeout: &OptionalDuration{&min}, }, - Timeout: &OptionalDuration{&min}, - }}, + }, }, }, Methods: Methods{ diff --git a/config/serialize/serialize.go b/config/serialize/serialize.go index d20e48118..616e529cb 100644 --- a/config/serialize/serialize.go +++ b/config/serialize/serialize.go @@ -35,12 +35,12 @@ func ReadConfigFile(filename string, cfg interface{}) error { // WriteConfigFile writes the config from `cfg` into `filename`. func WriteConfigFile(filename string, cfg interface{}) error { - err := os.MkdirAll(filepath.Dir(filename), 0755) + err := os.MkdirAll(filepath.Dir(filename), 0o755) if err != nil { return err } - f, err := atomicfile.New(filename, 0600) + f, err := atomicfile.New(filename, 0o600) if err != nil { return err } @@ -49,7 +49,7 @@ func WriteConfigFile(filename string, cfg interface{}) error { return encode(f, cfg) } -// encode configuration with JSON +// encode configuration with JSON. func encode(w io.Writer, value interface{}) error { // need to prettyprint, hence MarshalIndent, instead of Encoder buf, err := config.Marshal(value) diff --git a/config/serialize/serialize_test.go b/config/serialize/serialize_test.go index cc161c80d..bf4b8b16f 100644 --- a/config/serialize/serialize_test.go +++ b/config/serialize/serialize_test.go @@ -30,7 +30,7 @@ func TestConfig(t *testing.T) { } if runtime.GOOS != "windows" { // see https://golang.org/src/os/types_windows.go - if g := st.Mode().Perm(); g&0117 != 0 { + if g := st.Mode().Perm(); g&0o117 != 0 { t.Fatalf("config file should not be executable or accessible to world: %v", g) } } diff --git a/config/swarm.go b/config/swarm.go index cbd46e5e1..45b8a9a52 100644 --- a/config/swarm.go +++ b/config/swarm.go @@ -127,7 +127,7 @@ type Transports struct { } } -// ConnMgr defines configuration options for the libp2p connection manager +// ConnMgr defines configuration options for the libp2p connection manager. type ConnMgr struct { Type *OptionalString `json:",omitempty"` LowWater *OptionalInteger `json:",omitempty"` diff --git a/config/types.go b/config/types.go index 2171a53f5..131324efe 100644 --- a/config/types.go +++ b/config/types.go @@ -42,8 +42,10 @@ func (o Strings) MarshalJSON() ([]byte, error) { } } -var _ json.Unmarshaler = (*Strings)(nil) -var _ json.Marshaler = (*Strings)(nil) +var ( + _ json.Unmarshaler = (*Strings)(nil) + _ json.Marshaler = (*Strings)(nil) +) // Flag represents a ternary value: false (-1), default (0), or true (+1). // @@ -113,8 +115,10 @@ func (f Flag) String() string { } } -var _ json.Unmarshaler = (*Flag)(nil) -var _ json.Marshaler = (*Flag)(nil) +var ( + _ json.Unmarshaler = (*Flag)(nil) + _ json.Marshaler = (*Flag)(nil) +) // Priority represents a value with a priority where 0 means "default" and -1 // means "disabled". @@ -210,17 +214,19 @@ func (p Priority) String() string { } } -var _ json.Unmarshaler = (*Priority)(nil) -var _ json.Marshaler = (*Priority)(nil) +var ( + _ json.Unmarshaler = (*Priority)(nil) + _ json.Marshaler = (*Priority)(nil) +) // OptionalDuration wraps time.Duration to provide json serialization and deserialization. // -// NOTE: the zero value encodes to JSON nill +// NOTE: the zero value encodes to JSON nill. type OptionalDuration struct { value *time.Duration } -// NewOptionalDuration returns an OptionalDuration from a string +// NewOptionalDuration returns an OptionalDuration from a string. func NewOptionalDuration(d time.Duration) *OptionalDuration { return &OptionalDuration{value: &d} } @@ -266,8 +272,10 @@ func (d OptionalDuration) String() string { return d.value.String() } -var _ json.Unmarshaler = (*OptionalDuration)(nil) -var _ json.Marshaler = (*OptionalDuration)(nil) +var ( + _ json.Unmarshaler = (*OptionalDuration)(nil) + _ json.Marshaler = (*OptionalDuration)(nil) +) type Duration struct { time.Duration @@ -298,17 +306,19 @@ func (d *Duration) UnmarshalJSON(b []byte) error { } } -var _ json.Unmarshaler = (*Duration)(nil) -var _ json.Marshaler = (*Duration)(nil) +var ( + _ json.Unmarshaler = (*Duration)(nil) + _ json.Marshaler = (*Duration)(nil) +) // OptionalInteger represents an integer that has a default value // -// When encoded in json, Default is encoded as "null" +// When encoded in json, Default is encoded as "null". type OptionalInteger struct { value *int64 } -// NewOptionalInteger returns an OptionalInteger from a int64 +// NewOptionalInteger returns an OptionalInteger from a int64. func NewOptionalInteger(v int64) *OptionalInteger { return &OptionalInteger{value: &v} } @@ -321,7 +331,7 @@ func (p *OptionalInteger) WithDefault(defaultValue int64) (value int64) { return *p.value } -// IsDefault returns if this is a default optional integer +// IsDefault returns if this is a default optional integer. func (p *OptionalInteger) IsDefault() bool { return p == nil || p.value == nil } @@ -355,17 +365,19 @@ func (p OptionalInteger) String() string { return fmt.Sprintf("%d", *p.value) } -var _ json.Unmarshaler = (*OptionalInteger)(nil) -var _ json.Marshaler = (*OptionalInteger)(nil) +var ( + _ json.Unmarshaler = (*OptionalInteger)(nil) + _ json.Marshaler = (*OptionalInteger)(nil) +) // OptionalString represents a string that has a default value // -// When encoded in json, Default is encoded as "null" +// When encoded in json, Default is encoded as "null". type OptionalString struct { value *string } -// NewOptionalString returns an OptionalString from a string +// NewOptionalString returns an OptionalString from a string. func NewOptionalString(s string) *OptionalString { return &OptionalString{value: &s} } @@ -378,7 +390,7 @@ func (p *OptionalString) WithDefault(defaultValue string) (value string) { return *p.value } -// IsDefault returns if this is a default optional integer +// IsDefault returns if this is a default optional integer. func (p *OptionalString) IsDefault() bool { return p == nil || p.value == nil } @@ -412,8 +424,10 @@ func (p OptionalString) String() string { return *p.value } -var _ json.Unmarshaler = (*OptionalInteger)(nil) -var _ json.Marshaler = (*OptionalInteger)(nil) +var ( + _ json.Unmarshaler = (*OptionalInteger)(nil) + _ json.Marshaler = (*OptionalInteger)(nil) +) type swarmLimits doNotUse diff --git a/config/types_test.go b/config/types_test.go index caef2b112..7ea7506f1 100644 --- a/config/types_test.go +++ b/config/types_test.go @@ -129,7 +129,6 @@ func TestOneStrings(t *testing.T) { out, err := json.Marshal(Strings{"one"}) if err != nil { t.Fatal(err) - } expected := "\"one\"" if string(out) != expected { @@ -141,7 +140,6 @@ func TestNoStrings(t *testing.T) { out, err := json.Marshal(Strings{}) if err != nil { t.Fatal(err) - } expected := "null" if string(out) != expected { @@ -153,7 +151,6 @@ func TestManyStrings(t *testing.T) { out, err := json.Marshal(Strings{"one", "two"}) if err != nil { t.Fatal(err) - } expected := "[\"one\",\"two\"]" if string(out) != expected { diff --git a/core/bootstrap/bootstrap.go b/core/bootstrap/bootstrap.go index b566e0e97..ed95d74e1 100644 --- a/core/bootstrap/bootstrap.go +++ b/core/bootstrap/bootstrap.go @@ -85,7 +85,6 @@ func BootstrapConfigWithPeers(pis []peer.AddrInfo) BootstrapConfig { // connections to well-known bootstrap peers. It also kicks off subsystem // bootstrapping (i.e. routing). func Bootstrap(id peer.ID, host host.Host, rt routing.Routing, cfg BootstrapConfig) (io.Closer, error) { - // make a signal to wait for one bootstrap round to complete. doneWithRound := make(chan struct{}) @@ -219,7 +218,6 @@ func saveConnectedPeersAsTemporaryBootstrap(ctx context.Context, host host.Host, // Peers can be original bootstrap or temporary ones (drawn from a list of // persisted previously connected peers). func bootstrapRound(ctx context.Context, host host.Host, cfg BootstrapConfig) error { - ctx, cancel := context.WithTimeout(ctx, cfg.ConnectionTimeout) defer cancel() id := host.ID() diff --git a/core/commands/bootstrap.go b/core/commands/bootstrap.go index 07cdcbe79..decf2b271 100644 --- a/core/commands/bootstrap.go +++ b/core/commands/bootstrap.go @@ -374,9 +374,7 @@ func bootstrapRemove(r repo.Repo, cfg *config.Config, toRemove []string) ([]stri removed = append(removed, p) continue } - var ( - keptAddrs, removedAddrs []ma.Multiaddr - ) + var keptAddrs, removedAddrs []ma.Multiaddr // remove specific addresses filter: for _, addr := range p.Addrs { diff --git a/core/commands/cmdenv/cidbase.go b/core/commands/cmdenv/cidbase.go index 32f2c2157..55815f524 100644 --- a/core/commands/cmdenv/cidbase.go +++ b/core/commands/cmdenv/cidbase.go @@ -10,8 +10,10 @@ import ( mbase "github.com/multiformats/go-multibase" ) -var OptionCidBase = cmds.StringOption("cid-base", "Multibase encoding used for version 1 CIDs in output.") -var OptionUpgradeCidV0InOutput = cmds.BoolOption("upgrade-cidv0-in-output", "Upgrade version 0 to version 1 CIDs in output.") +var ( + OptionCidBase = cmds.StringOption("cid-base", "Multibase encoding used for version 1 CIDs in output.") + OptionUpgradeCidV0InOutput = cmds.BoolOption("upgrade-cidv0-in-output", "Upgrade version 0 to version 1 CIDs in output.") +) // GetCidEncoder processes the `cid-base` and `output-cidv1` options and // returns a encoder to use based on those parameters. diff --git a/core/commands/cmdutils/utils.go b/core/commands/cmdutils/utils.go index 9b498933b..954f476b6 100644 --- a/core/commands/cmdutils/utils.go +++ b/core/commands/cmdutils/utils.go @@ -47,5 +47,4 @@ func CheckBlockSize(req *cmds.Request, size uint64) error { return fmt.Errorf("produced block is over 1MiB: big blocks can't be exchanged with other peers. consider using UnixFS for automatic chunking of bigger files, or pass --allow-big-block to override") } return nil - } diff --git a/core/commands/commands_test.go b/core/commands/commands_test.go index bf1b76450..0f2b0721b 100644 --- a/core/commands/commands_test.go +++ b/core/commands/commands_test.go @@ -71,6 +71,7 @@ func TestROCommands(t *testing.T) { } } } + func TestCommands(t *testing.T) { list := []string{ "/add", diff --git a/core/commands/completion.go b/core/commands/completion.go index c4fb1ba41..8babaac36 100644 --- a/core/commands/completion.go +++ b/core/commands/completion.go @@ -208,7 +208,6 @@ complete -c ipfs --keep-order --no-files {{ template "command" . }} `)) - } // writeBashCompletions generates a bash completion script for the given command tree. diff --git a/core/commands/config.go b/core/commands/config.go index 4d2ea4f0d..b24551027 100644 --- a/core/commands/config.go +++ b/core/commands/config.go @@ -581,5 +581,4 @@ func getRemotePinningServices(r repo.Repo) (map[string]config.RemotePinningServi } } return oldServices, nil - } diff --git a/core/commands/config_test.go b/core/commands/config_test.go index 9e244f54f..5eb79c153 100644 --- a/core/commands/config_test.go +++ b/core/commands/config_test.go @@ -12,6 +12,5 @@ func TestScrubMapInternalDelete(t *testing.T) { } if len(m) != 0 { t.Errorf("expecting an empty map, got a non-empty map") - } } diff --git a/core/commands/dag/dag.go b/core/commands/dag/dag.go index 41fde70e5..ac6f25d7d 100644 --- a/core/commands/dag/dag.go +++ b/core/commands/dag/dag.go @@ -13,9 +13,9 @@ import ( cid "github.com/ipfs/go-cid" cidenc "github.com/ipfs/go-cidutil/cidenc" cmds "github.com/ipfs/go-ipfs-cmds" - //gipfree "github.com/ipld/go-ipld-prime/impl/free" - //gipselector "github.com/ipld/go-ipld-prime/traversal/selector" - //gipselectorbuilder "github.com/ipld/go-ipld-prime/traversal/selector/builder" + // gipfree "github.com/ipld/go-ipld-prime/impl/free" + // gipselector "github.com/ipld/go-ipld-prime/traversal/selector" + // gipselectorbuilder "github.com/ipld/go-ipld-prime/traversal/selector/builder" ) const ( @@ -209,7 +209,6 @@ Specification of CAR formats: https://ipld.io/specs/transport/car/ Run: dagImport, Encoders: cmds.EncoderMap{ cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, event *CarImportOutput) error { - silent, _ := req.Options[silentOptionName].(bool) if silent { return nil @@ -343,9 +342,11 @@ func (s *DagStatSummary) String() string { func (s *DagStatSummary) incrementTotalSize(size uint64) { s.TotalSize += size } + func (s *DagStatSummary) incrementRedundantSize(size uint64) { s.redundantSize += size } + func (s *DagStatSummary) appendStats(stats *DagStat) { s.DagStatsArray = append(s.DagStatsArray, stats) } diff --git a/core/commands/dag/export.go b/core/commands/dag/export.go index 337d8ce8f..d46fa6e21 100644 --- a/core/commands/dag/export.go +++ b/core/commands/dag/export.go @@ -79,7 +79,6 @@ func dagExport(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment } func finishCLIExport(res cmds.Response, re cmds.ResponseEmitter) error { - var showProgress bool val, specified := res.Request().Options[progressOptionName] if !specified { diff --git a/core/commands/external.go b/core/commands/external.go index 0eb4de036..65ddcea4d 100644 --- a/core/commands/external.go +++ b/core/commands/external.go @@ -41,7 +41,7 @@ func ExternalBinary(instructions string) *cmds.Command { cmd := exec.Command(binname, req.Arguments...) // TODO: make commands lib be able to pass stdin through daemon - //cmd.Stdin = req.Stdin() + // cmd.Stdin = req.Stdin() cmd.Stdin = io.LimitReader(nil, 0) cmd.Stdout = w cmd.Stderr = w diff --git a/core/commands/files.go b/core/commands/files.go index 9c0c6e5a9..ce1cf1cfc 100644 --- a/core/commands/files.go +++ b/core/commands/files.go @@ -88,8 +88,10 @@ const ( filesHashOptionName = "hash" ) -var cidVersionOption = cmds.IntOption(filesCidVersionOptionName, "cid-ver", "Cid version to use. (experimental)") -var hashOption = cmds.StringOption(filesHashOptionName, "Hash function to use. Will set Cid version to 1 if used. (experimental)") +var ( + cidVersionOption = cmds.IntOption(filesCidVersionOptionName, "cid-ver", "Cid version to use. (experimental)") + hashOption = cmds.StringOption(filesHashOptionName, "Hash function to use. Will set Cid version to 1 if used. (experimental)") +) var errFormat = errors.New("format was set by multiple options. Only one format option is allowed") @@ -131,7 +133,6 @@ var filesStatCmd = &cmds.Command{ cmds.BoolOption(filesWithLocalOptionName, "Compute the amount of the dag that is local, and if possible the total size"), }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - _, err := statGetFormatOptions(req) if err != nil { return cmds.Errorf(cmds.ErrClient, err.Error()) @@ -225,7 +226,6 @@ func moreThanOne(a, b, c bool) bool { } func statGetFormatOptions(req *cmds.Request) (string, error) { - hash, _ := req.Options[filesHashOptionName].(bool) size, _ := req.Options[filesSizeOptionName].(bool) format, _ := req.Options[filesFormatOptionName].(string) @@ -307,7 +307,6 @@ func walkBlock(ctx context.Context, dagserv ipld.DAGService, nd ipld.Node) (bool } childLocal, childLocalSize, err := walkBlock(ctx, dagserv, child) - if err != nil { return local, sizeLocal, err } diff --git a/core/commands/keystore.go b/core/commands/keystore.go index ed0d5d4e9..d68801cad 100644 --- a/core/commands/keystore.go +++ b/core/commands/keystore.go @@ -118,7 +118,6 @@ var keyGenCmd = &cmds.Command{ } key, err := api.Key().Generate(req.Context, name, opts...) - if err != nil { return err } @@ -211,7 +210,6 @@ elsewhere. For example, using openssl to get a PEM with public key: stdKey, err := crypto.PrivKeyToStdKey(sk) if err != nil { return fmt.Errorf("converting libp2p private key to std Go key: %w", err) - } // For some reason the ed25519.PrivateKey does not use pointer // receivers, so we need to convert it for MarshalPKCS8PrivateKey. @@ -375,7 +373,6 @@ The PEM format allows for key generation outside of the IPFS node: sk, _, err = crypto.KeyPairFromStdKey(stdKey) if err != nil { return fmt.Errorf("converting std Go key to libp2p key: %w", err) - } case keyFormatLibp2pCleartextOption: sk, err = crypto.UnmarshalPrivateKey(data) diff --git a/core/commands/name/publish.go b/core/commands/name/publish.go index bb4a4b708..6cc51df14 100644 --- a/core/commands/name/publish.go +++ b/core/commands/name/publish.go @@ -15,9 +15,7 @@ import ( ke "github.com/ipfs/kubo/core/commands/keyencode" ) -var ( - errAllowOffline = errors.New("can't publish while offline: pass `--allow-offline` to override") -) +var errAllowOffline = errors.New("can't publish while offline: pass `--allow-offline` to override") const ( ipfsPathOptionName = "ipfs-path" diff --git a/core/commands/p2p.go b/core/commands/p2p.go index 7aaa7fee2..7b8b416e5 100644 --- a/core/commands/p2p.go +++ b/core/commands/p2p.go @@ -370,9 +370,7 @@ var p2pCloseCmd = &cmds.Command{ proto := protocol.ID(protoOpt) - var ( - target, listen ma.Multiaddr - ) + var target, listen ma.Multiaddr if l { listen, err = ma.NewMultiaddr(listenOpt) diff --git a/core/commands/pin/remotepin.go b/core/commands/pin/remotepin.go index bbec1a73d..2fe615c14 100644 --- a/core/commands/pin/remotepin.go +++ b/core/commands/pin/remotepin.go @@ -54,16 +54,18 @@ var remotePinServiceCmd = &cmds.Command{ }, } -const pinNameOptionName = "name" -const pinCIDsOptionName = "cid" -const pinStatusOptionName = "status" -const pinServiceNameOptionName = "service" -const pinServiceNameArgName = pinServiceNameOptionName -const pinServiceEndpointArgName = "endpoint" -const pinServiceKeyArgName = "key" -const pinServiceStatOptionName = "stat" -const pinBackgroundOptionName = "background" -const pinForceOptionName = "force" +const ( + pinNameOptionName = "name" + pinCIDsOptionName = "cid" + pinStatusOptionName = "status" + pinServiceNameOptionName = "service" + pinServiceNameArgName = pinServiceNameOptionName + pinServiceEndpointArgName = "endpoint" + pinServiceKeyArgName = "key" + pinServiceStatOptionName = "stat" + pinBackgroundOptionName = "background" + pinForceOptionName = "force" +) type RemotePinOutput struct { Status string diff --git a/core/commands/pin/remotepin_test.go b/core/commands/pin/remotepin_test.go index d1dfa8fd5..98bb707a8 100644 --- a/core/commands/pin/remotepin_test.go +++ b/core/commands/pin/remotepin_test.go @@ -63,5 +63,4 @@ func TestNormalizeEndpoint(t *testing.T) { continue } } - } diff --git a/core/commands/root.go b/core/commands/root.go index 76e110e2b..0e274f087 100644 --- a/core/commands/root.go +++ b/core/commands/root.go @@ -16,8 +16,10 @@ import ( var log = logging.Logger("core/commands") -var ErrNotOnline = errors.New("this command must be run in online mode. Try running 'ipfs daemon' first") -var ErrSelfUnsupported = errors.New("finding your own node in the DHT is currently not supported") +var ( + ErrNotOnline = errors.New("this command must be run in online mode. Try running 'ipfs daemon' first") + ErrSelfUnsupported = errors.New("finding your own node in the DHT is currently not supported") +) const ( RepoDirOption = "repo-dir" diff --git a/core/commands/routing.go b/core/commands/routing.go index 44ca2e29f..e2071fd40 100644 --- a/core/commands/routing.go +++ b/core/commands/routing.go @@ -21,9 +21,7 @@ import ( routing "github.com/libp2p/go-libp2p/core/routing" ) -var ( - errAllowOffline = errors.New("can't put while offline: pass `--allow-offline` to override") -) +var errAllowOffline = errors.New("can't put while offline: pass `--allow-offline` to override") const ( dhtVerboseOptionName = "verbose" @@ -75,7 +73,6 @@ var findProvidersRoutingCmd = &cmds.Command{ } c, err := cid.Parse(req.Arguments[0]) - if err != nil { return err } @@ -495,8 +492,10 @@ identified by QmFoo. Type: routing.QueryEvent{}, } -type printFunc func(obj *routing.QueryEvent, out io.Writer, verbose bool) error -type pfuncMap map[routing.QueryEventType]printFunc +type ( + printFunc func(obj *routing.QueryEvent, out io.Writer, verbose bool) error + pfuncMap map[routing.QueryEventType]printFunc +) func printEvent(obj *routing.QueryEvent, out io.Writer, verbose bool, override pfuncMap) error { if verbose { diff --git a/core/commands/swarm.go b/core/commands/swarm.go index 0e28c7175..fc4d8f7d2 100644 --- a/core/commands/swarm.go +++ b/core/commands/swarm.go @@ -345,7 +345,8 @@ var swarmResourcesCmd = &cmds.Command{ Get a summary of all resources accounted for by the libp2p Resource Manager. This includes the limits and the usage against those limits. This can output a human readable table and JSON encoding. -`}, +`, + }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { node, err := cmdenv.GetNode(env) if err != nil { diff --git a/core/core.go b/core/core.go index 5c0a7ef2c..a0e06324f 100644 --- a/core/core.go +++ b/core/core.go @@ -64,7 +64,6 @@ var log = logging.Logger("core") // IpfsNode is IPFS Core module. It represents an IPFS instance. type IpfsNode struct { - // Self Identity peer.ID // the local node's identity diff --git a/core/coreapi/swarm.go b/core/coreapi/swarm.go index 778a46e72..d3b6a0e43 100644 --- a/core/coreapi/swarm.go +++ b/core/coreapi/swarm.go @@ -29,8 +29,10 @@ type connInfo struct { } // tag used in the connection manager when explicitly connecting to a peer. -const connectionManagerTag = "user-connect" -const connectionManagerWeight = 100 +const ( + connectionManagerTag = "user-connect" + connectionManagerWeight = 100 +) func (api *SwarmAPI) Connect(ctx context.Context, pi peer.AddrInfo) error { ctx, span := tracing.Span(ctx, "CoreAPI.SwarmAPI", "Connect", trace.WithAttributes(attribute.String("peerid", pi.ID.String()))) diff --git a/core/coreapi/unixfs.go b/core/coreapi/unixfs.go index dd6db41fb..e1a607d73 100644 --- a/core/coreapi/unixfs.go +++ b/core/coreapi/unixfs.go @@ -32,8 +32,10 @@ import ( type UnixfsAPI CoreAPI -var nilNode *core.IpfsNode -var once sync.Once +var ( + nilNode *core.IpfsNode + once sync.Once +) func getOrCreateNilNode() (*core.IpfsNode, error) { once.Do(func() { @@ -41,7 +43,7 @@ func getOrCreateNilNode() (*core.IpfsNode, error) { return } node, err := core.NewNode(context.Background(), &core.BuildCfg{ - //TODO: need this to be true or all files + // TODO: need this to be true or all files // hashed will be stored in memory! NilRepo: true, }) @@ -253,7 +255,6 @@ func (api *UnixfsAPI) processLink(ctx context.Context, linkres ft.LinkResult, se defer span.End() if linkres.Link != nil { span.SetAttributes(attribute.String("linkname", linkres.Link.Name), attribute.String("cid", linkres.Link.Cid.String())) - } if linkres.Err != nil { @@ -314,7 +315,7 @@ func (api *UnixfsAPI) lsFromLinksAsync(ctx context.Context, dir uio.Directory, s defer close(out) for l := range dir.EnumLinksAsync(ctx) { select { - case out <- api.processLink(ctx, l, settings): //TODO: perf: processing can be done in background and in parallel + case out <- api.processLink(ctx, l, settings): // TODO: perf: processing can be done in background and in parallel case <-ctx.Done(): return } @@ -329,7 +330,7 @@ func (api *UnixfsAPI) lsFromLinks(ctx context.Context, ndlinks []*ipld.Link, set for _, l := range ndlinks { lr := ft.LinkResult{Link: &ipld.Link{Name: l.Name, Size: l.Size, Cid: l.Cid}} - links <- api.processLink(ctx, lr, settings) //TODO: can be parallel if settings.Async + links <- api.processLink(ctx, lr, settings) // TODO: can be parallel if settings.Async } close(links) return links, nil diff --git a/core/corehttp/commands.go b/core/corehttp/commands.go index e7ac14289..63abc5922 100644 --- a/core/corehttp/commands.go +++ b/core/corehttp/commands.go @@ -20,12 +20,11 @@ import ( "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" ) -var ( - errAPIVersionMismatch = errors.New("api version mismatch") -) +var errAPIVersionMismatch = errors.New("api version mismatch") -const originEnvKey = "API_ORIGIN" -const originEnvKeyDeprecate = `You are using the ` + originEnvKey + `ENV Variable. +const ( + originEnvKey = "API_ORIGIN" + originEnvKeyDeprecate = `You are using the ` + originEnvKey + `ENV Variable. This functionality is deprecated, and will be removed in future versions. Instead, try either adding headers to the config, or passing them via cli arguments: @@ -33,6 +32,7 @@ cli arguments: ipfs config API.HTTPHeaders --json '{"Access-Control-Allow-Origin": ["*"]}' ipfs daemon ` +) // APIPath is the path at which the API is mounted. const APIPath = "/api/v0" @@ -100,7 +100,6 @@ func addCORSDefaults(c *cmdsHttp.ServerConfig) { } func patchCORSVars(c *cmdsHttp.ServerConfig, addr net.Addr) { - // we have to grab the port from an addr, which may be an ip6 addr. // TODO: this should take multiaddrs and derive port from there. port := "" @@ -125,7 +124,6 @@ func patchCORSVars(c *cmdsHttp.ServerConfig, addr net.Addr) { func commandsOption(cctx oldcmds.Context, command *cmds.Command, allowGet bool) ServeOption { return func(n *core.IpfsNode, l net.Listener, mux *http.ServeMux) (*http.ServeMux, error) { - cfg := cmdsHttp.NewServerConfig() cfg.AllowGet = allowGet corsAllowedMethods := []string{http.MethodPost} diff --git a/core/corehttp/metrics.go b/core/corehttp/metrics.go index e26be1ca9..f43362ff7 100644 --- a/core/corehttp/metrics.go +++ b/core/corehttp/metrics.go @@ -151,13 +151,11 @@ func MetricsCollectionOption(handlerName string) ServeOption { } } -var ( - peersTotalMetric = prometheus.NewDesc( - prometheus.BuildFQName("ipfs", "p2p", "peers_total"), - "Number of connected peers", - []string{"transport"}, - nil, - ) +var peersTotalMetric = prometheus.NewDesc( + prometheus.BuildFQName("ipfs", "p2p", "peers_total"), + "Number of connected peers", + []string{"transport"}, + nil, ) type IpfsNodeCollector struct { diff --git a/core/coreunix/add_test.go b/core/coreunix/add_test.go index 4560d9964..be6f98ed7 100644 --- a/core/coreunix/add_test.go +++ b/core/coreunix/add_test.go @@ -179,11 +179,9 @@ func TestAddGCLive(t *testing.T) { defer close(addDone) defer close(out) _, err := adder.AddAllAndPin(context.Background(), slf) - if err != nil { t.Error(err) } - }() addedHashes := make(map[string]struct{}) diff --git a/core/node/groups.go b/core/node/groups.go index a626a5cae..e101bb3ed 100644 --- a/core/node/groups.go +++ b/core/node/groups.go @@ -248,7 +248,6 @@ var IPNS = fx.Options( // Online groups online-only units func Online(bcfg *BuildCfg, cfg *config.Config, userResourceOverrides rcmgr.PartialLimitConfig) fx.Option { - // Namesys params ipnsCacheSize := cfg.Ipns.ResolveCacheSize diff --git a/core/node/helpers/helpers.go b/core/node/helpers/helpers.go index 546c8e977..4c3a04881 100644 --- a/core/node/helpers/helpers.go +++ b/core/node/helpers/helpers.go @@ -2,6 +2,7 @@ package helpers import ( "context" + "go.uber.org/fx" ) diff --git a/core/node/libp2p/rcmgr.go b/core/node/libp2p/rcmgr.go index c11c7262c..47a823d5d 100644 --- a/core/node/libp2p/rcmgr.go +++ b/core/node/libp2p/rcmgr.go @@ -118,7 +118,8 @@ filled in with autocomputed defaults.`) lc.Append(fx.Hook{ OnStop: func(_ context.Context) error { return manager.Close() - }}) + }, + }) return manager, opts, nil } diff --git a/core/node/libp2p/rcmgr_logging.go b/core/node/libp2p/rcmgr_logging.go index 978222bfe..56e017b82 100644 --- a/core/node/libp2p/rcmgr_logging.go +++ b/core/node/libp2p/rcmgr_logging.go @@ -31,8 +31,10 @@ type loggingScope struct { countErrs func(error) } -var _ network.ResourceManager = (*loggingResourceManager)(nil) -var _ rcmgr.ResourceManagerState = (*loggingResourceManager)(nil) +var ( + _ network.ResourceManager = (*loggingResourceManager)(nil) + _ rcmgr.ResourceManagerState = (*loggingResourceManager)(nil) +) func (n *loggingResourceManager) start(ctx context.Context) { logInterval := n.logInterval @@ -85,36 +87,43 @@ func (n *loggingResourceManager) countErrs(err error) { func (n *loggingResourceManager) ViewSystem(f func(network.ResourceScope) error) error { return n.delegate.ViewSystem(f) } + func (n *loggingResourceManager) ViewTransient(f func(network.ResourceScope) error) error { return n.delegate.ViewTransient(func(s network.ResourceScope) error { return f(&loggingScope{logger: n.logger, delegate: s, countErrs: n.countErrs}) }) } + func (n *loggingResourceManager) ViewService(svc string, f func(network.ServiceScope) error) error { return n.delegate.ViewService(svc, func(s network.ServiceScope) error { return f(&loggingScope{logger: n.logger, delegate: s, countErrs: n.countErrs}) }) } + func (n *loggingResourceManager) ViewProtocol(p protocol.ID, f func(network.ProtocolScope) error) error { return n.delegate.ViewProtocol(p, func(s network.ProtocolScope) error { return f(&loggingScope{logger: n.logger, delegate: s, countErrs: n.countErrs}) }) } + func (n *loggingResourceManager) ViewPeer(p peer.ID, f func(network.PeerScope) error) error { return n.delegate.ViewPeer(p, func(s network.PeerScope) error { return f(&loggingScope{logger: n.logger, delegate: s, countErrs: n.countErrs}) }) } + func (n *loggingResourceManager) OpenConnection(dir network.Direction, usefd bool, remote ma.Multiaddr) (network.ConnManagementScope, error) { connMgmtScope, err := n.delegate.OpenConnection(dir, usefd, remote) n.countErrs(err) return connMgmtScope, err } + func (n *loggingResourceManager) OpenStream(p peer.ID, dir network.Direction) (network.StreamManagementScope, error) { connMgmtScope, err := n.delegate.OpenStream(p, dir) n.countErrs(err) return connMgmtScope, err } + func (n *loggingResourceManager) Close() error { return n.delegate.Close() } @@ -127,6 +136,7 @@ func (n *loggingResourceManager) ListServices() []string { return rapi.ListServices() } + func (n *loggingResourceManager) ListProtocols() []protocol.ID { rapi, ok := n.delegate.(rcmgr.ResourceManagerState) if !ok { @@ -135,6 +145,7 @@ func (n *loggingResourceManager) ListProtocols() []protocol.ID { return rapi.ListProtocols() } + func (n *loggingResourceManager) ListPeers() []peer.ID { rapi, ok := n.delegate.(rcmgr.ResourceManagerState) if !ok { @@ -158,54 +169,69 @@ func (s *loggingScope) ReserveMemory(size int, prio uint8) error { s.countErrs(err) return err } + func (s *loggingScope) ReleaseMemory(size int) { s.delegate.ReleaseMemory(size) } + func (s *loggingScope) Stat() network.ScopeStat { return s.delegate.Stat() } + func (s *loggingScope) BeginSpan() (network.ResourceScopeSpan, error) { return s.delegate.BeginSpan() } + func (s *loggingScope) Done() { s.delegate.(network.ResourceScopeSpan).Done() } + func (s *loggingScope) Name() string { return s.delegate.(network.ServiceScope).Name() } + func (s *loggingScope) Protocol() protocol.ID { return s.delegate.(network.ProtocolScope).Protocol() } + func (s *loggingScope) Peer() peer.ID { return s.delegate.(network.PeerScope).Peer() } + func (s *loggingScope) PeerScope() network.PeerScope { return s.delegate.(network.PeerScope) } + func (s *loggingScope) SetPeer(p peer.ID) error { err := s.delegate.(network.ConnManagementScope).SetPeer(p) s.countErrs(err) return err } + func (s *loggingScope) ProtocolScope() network.ProtocolScope { return s.delegate.(network.ProtocolScope) } + func (s *loggingScope) SetProtocol(proto protocol.ID) error { err := s.delegate.(network.StreamManagementScope).SetProtocol(proto) s.countErrs(err) return err } + func (s *loggingScope) ServiceScope() network.ServiceScope { return s.delegate.(network.ServiceScope) } + func (s *loggingScope) SetService(srv string) error { err := s.delegate.(network.StreamManagementScope).SetService(srv) s.countErrs(err) return err } + func (s *loggingScope) Limit() rcmgr.Limit { return s.delegate.(rcmgr.ResourceScopeLimiter).Limit() } + func (s *loggingScope) SetLimit(limit rcmgr.Limit) { s.delegate.(rcmgr.ResourceScopeLimiter).SetLimit(limit) } diff --git a/core/node/libp2p/routing.go b/core/node/libp2p/routing.go index 007ff3397..98234f5ce 100644 --- a/core/node/libp2p/routing.go +++ b/core/node/libp2p/routing.go @@ -232,7 +232,6 @@ func PubsubRouter(mctx helpers.MetricsCtx, lc fx.Lifecycle, in p2pPSRoutingIn) ( in.Validator, namesys.WithRebroadcastInterval(time.Minute), ) - if err != nil { return p2pRouterOut{}, nil, err } diff --git a/core/node/libp2p/topicdiscovery.go b/core/node/libp2p/topicdiscovery.go index 81bec285f..8d0254383 100644 --- a/core/node/libp2p/topicdiscovery.go +++ b/core/node/libp2p/topicdiscovery.go @@ -21,7 +21,6 @@ func TopicDiscovery() interface{} { baseDisc, backoff.NewExponentialBackoff(minBackoff, maxBackoff, backoff.FullJitter, time.Second, 5.0, 0, rng), ) - if err != nil { return nil, err } diff --git a/core/node/libp2p/transport.go b/core/node/libp2p/transport.go index f737c6086..8e04a63ff 100644 --- a/core/node/libp2p/transport.go +++ b/core/node/libp2p/transport.go @@ -18,7 +18,8 @@ func Transports(tptConfig config.Transports) interface{} { return func(pnet struct { fx.In Fprint PNetFingerprint `optional:"true"` - }) (opts Libp2pOpts, err error) { + }, + ) (opts Libp2pOpts, err error) { privateNetworkEnabled := pnet.Fprint != nil if tptConfig.Network.TCP.WithDefault(true) { diff --git a/docs/examples/kubo-as-a-library/main.go b/docs/examples/kubo-as-a-library/main.go index ce19a5a64..785973c5b 100644 --- a/docs/examples/kubo-as-a-library/main.go +++ b/docs/examples/kubo-as-a-library/main.go @@ -85,7 +85,7 @@ func createTempRepo() (string, error) { /// ------ Spawning the node -// Creates an IPFS node and returns its coreAPI +// Creates an IPFS node and returns its coreAPI. func createNode(ctx context.Context, repoPath string) (*core.IpfsNode, error) { // Open the repo repo, err := fsrepo.Open(repoPath) @@ -107,7 +107,7 @@ func createNode(ctx context.Context, repoPath string) (*core.IpfsNode, error) { var loadPluginsOnce sync.Once -// Spawns a node to be used just for this run (i.e. creates a tmp repo) +// Spawns a node to be used just for this run (i.e. creates a tmp repo). func spawnEphemeral(ctx context.Context) (icore.CoreAPI, *core.IpfsNode, error) { var onceErr error loadPluginsOnce.Do(func() { diff --git a/fuse/ipns/ipns_test.go b/fuse/ipns/ipns_test.go index 05a4e467e..ca2ec4c1a 100644 --- a/fuse/ipns/ipns_test.go +++ b/fuse/ipns/ipns_test.go @@ -56,7 +56,7 @@ func writeFileOrFail(t *testing.T, size int, path string) []byte { func writeFile(size int, path string) ([]byte, error) { data := randBytes(size) - err := os.WriteFile(path, data, 0666) + err := os.WriteFile(path, data, 0o666) return data, err } @@ -156,7 +156,7 @@ func TestIpnsLocalLink(t *testing.T) { } } -// Test writing a file and reading it back +// Test writing a file and reading it back. func TestIpnsBasicIO(t *testing.T) { if testing.Short() { t.SkipNow() @@ -187,7 +187,7 @@ func TestIpnsBasicIO(t *testing.T) { } } -// Test to make sure file changes persist over mounts of ipns +// Test to make sure file changes persist over mounts of ipns. func TestFilePersistence(t *testing.T) { if testing.Short() { t.SkipNow() @@ -250,7 +250,7 @@ func TestMultipleDirs(t *testing.T) { mnt.Close() } -// Test to make sure the filesystem reports file sizes correctly +// Test to make sure the filesystem reports file sizes correctly. func TestFileSizeReporting(t *testing.T) { if testing.Short() { t.SkipNow() @@ -271,7 +271,7 @@ func TestFileSizeReporting(t *testing.T) { } } -// Test to make sure you can't create multiple entries with the same name +// Test to make sure you can't create multiple entries with the same name. func TestDoubleEntryFailure(t *testing.T) { if testing.Short() { t.SkipNow() @@ -280,12 +280,12 @@ func TestDoubleEntryFailure(t *testing.T) { defer mnt.Close() dname := mnt.Dir + "/local/thisisadir" - err := os.Mkdir(dname, 0777) + err := os.Mkdir(dname, 0o777) if err != nil { t.Fatal(err) } - err = os.Mkdir(dname, 0777) + err = os.Mkdir(dname, 0o777) if err == nil { t.Fatal("Should have gotten error one creating new directory.") } @@ -301,7 +301,7 @@ func TestAppendFile(t *testing.T) { fname := mnt.Dir + "/local/file" data := writeFileOrFail(t, 1300, fname) - fi, err := os.OpenFile(fname, os.O_RDWR|os.O_APPEND, 0666) + fi, err := os.OpenFile(fname, os.O_RDWR|os.O_APPEND, 0o666) if err != nil { t.Fatal(err) } @@ -463,9 +463,8 @@ func TestFSThrash(t *testing.T) { } } -// Test writing a medium sized file one byte at a time +// Test writing a medium sized file one byte at a time. func TestMultiWrite(t *testing.T) { - if testing.Short() { t.SkipNow() } diff --git a/fuse/ipns/ipns_unix.go b/fuse/ipns/ipns_unix.go index 9db0d61f9..e4f49cf12 100644 --- a/fuse/ipns/ipns_unix.go +++ b/fuse/ipns/ipns_unix.go @@ -149,7 +149,7 @@ func CreateRoot(ctx context.Context, ipfs iface.CoreAPI, keys map[string]iface.K // Attr returns file attributes. func (r *Root) Attr(ctx context.Context, a *fuse.Attr) error { log.Debug("Root Attr") - a.Mode = os.ModeDir | 0111 // -rw+x + a.Mode = os.ModeDir | 0o111 // -rw+x return nil } @@ -212,7 +212,7 @@ func (r *Root) Forget() { } // ReadDirAll reads a particular directory. Will show locally available keys -// as well as a symlink to the peerID key +// as well as a symlink to the peerID key. func (r *Root) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) { log.Debug("Root ReadDirAll") @@ -231,7 +231,7 @@ func (r *Root) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) { return listing, nil } -// Directory is wrapper over an mfs directory to satisfy the fuse fs interface +// Directory is wrapper over an mfs directory to satisfy the fuse fs interface. type Directory struct { dir *mfs.Directory } @@ -240,7 +240,7 @@ type FileNode struct { fi *mfs.File } -// File is wrapper over an mfs file to satisfy the fuse fs interface +// File is wrapper over an mfs file to satisfy the fuse fs interface. type File struct { fi mfs.FileDescriptor } @@ -248,7 +248,7 @@ type File struct { // Attr returns the attributes of a given node. func (d *Directory) Attr(ctx context.Context, a *fuse.Attr) error { log.Debug("Directory Attr") - a.Mode = os.ModeDir | 0555 + a.Mode = os.ModeDir | 0o555 a.Uid = uint32(os.Getuid()) a.Gid = uint32(os.Getgid()) return nil @@ -262,7 +262,7 @@ func (fi *FileNode) Attr(ctx context.Context, a *fuse.Attr) error { // In this case, the dag node in question may not be unixfs return fmt.Errorf("fuse/ipns: failed to get file.Size(): %s", err) } - a.Mode = os.FileMode(0666) + a.Mode = os.FileMode(0o666) a.Size = uint64(size) a.Uid = uint32(os.Getuid()) a.Gid = uint32(os.Getgid()) @@ -289,7 +289,7 @@ func (d *Directory) Lookup(ctx context.Context, name string) (fs.Node, error) { } } -// ReadDirAll reads the link structure as directory entries +// ReadDirAll reads the link structure as directory entries. func (d *Directory) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) { listing, err := d.dir.List(ctx) if err != nil { @@ -491,7 +491,7 @@ func (d *Directory) Remove(ctx context.Context, req *fuse.RemoveRequest) error { return nil } -// Rename implements NodeRenamer +// Rename implements NodeRenamer. func (d *Directory) Rename(ctx context.Context, req *fuse.RenameRequest, newDir fs.Node) error { cur, err := d.dir.Child(req.OldName) if err != nil { @@ -531,7 +531,7 @@ func min(a, b int) int { return b } -// to check that out Node implements all the interfaces we want +// to check that out Node implements all the interfaces we want. type ipnsRoot interface { fs.Node fs.HandleReadDirAller @@ -565,5 +565,7 @@ type ipnsFileNode interface { fs.NodeOpener } -var _ ipnsFileNode = (*FileNode)(nil) -var _ ipnsFile = (*File)(nil) +var ( + _ ipnsFileNode = (*FileNode)(nil) + _ ipnsFile = (*File)(nil) +) diff --git a/fuse/ipns/link_unix.go b/fuse/ipns/link_unix.go index 355787b3c..da810c8f9 100644 --- a/fuse/ipns/link_unix.go +++ b/fuse/ipns/link_unix.go @@ -17,7 +17,7 @@ type Link struct { func (l *Link) Attr(ctx context.Context, a *fuse.Attr) error { log.Debug("Link attr.") - a.Mode = os.ModeSymlink | 0555 + a.Mode = os.ModeSymlink | 0o555 return nil } diff --git a/fuse/mount/fuse.go b/fuse/mount/fuse.go index b1060e6fd..2dcb8ccae 100644 --- a/fuse/mount/fuse.go +++ b/fuse/mount/fuse.go @@ -16,7 +16,7 @@ import ( var ErrNotMounted = errors.New("not mounted") -// mount implements go-ipfs/fuse/mount +// mount implements go-ipfs/fuse/mount. type mount struct { mpoint string filesys fs.FS @@ -34,7 +34,7 @@ func NewMount(p goprocess.Process, fsys fs.FS, mountpoint string, allowOther boo var conn *fuse.Conn var err error - var mountOpts = []fuse.MountOption{ + mountOpts := []fuse.MountOption{ fuse.MaxReadahead(64 * 1024 * 1024), fuse.AsyncRead(), } diff --git a/fuse/mount/mount.go b/fuse/mount/mount.go index 52784a16d..a52374dd8 100644 --- a/fuse/mount/mount.go +++ b/fuse/mount/mount.go @@ -16,7 +16,7 @@ var log = logging.Logger("mount") var MountTimeout = time.Second * 5 -// Mount represents a filesystem mount +// Mount represents a filesystem mount. type Mount interface { // MountPoint is the path at which this mount is mounted MountPoint() string @@ -65,7 +65,7 @@ func ForceUnmount(m Mount) error { } // UnmountCmd creates an exec.Cmd that is GOOS-specific -// for unmount a FUSE mount +// for unmount a FUSE mount. func UnmountCmd(point string) (*exec.Cmd, error) { switch runtime.GOOS { case "darwin": diff --git a/fuse/node/mount_darwin.go b/fuse/node/mount_darwin.go index 73fa86772..bd0bbb3ae 100644 --- a/fuse/node/mount_darwin.go +++ b/fuse/node/mount_darwin.go @@ -25,7 +25,7 @@ func init() { // skip fuse checks. const dontCheckOSXFUSEConfigKey = "DontCheckOSXFUSE" -// fuseVersionPkg is the go pkg url for fuse-version +// fuseVersionPkg is the go pkg url for fuse-version. const fuseVersionPkg = "github.com/jbenet/go-fuse-version/fuse-version" // errStrFuseRequired is returned when we're sure the user does not have fuse. diff --git a/fuse/node/mount_test.go b/fuse/node/mount_test.go index 1691cfa5b..178fddcf6 100644 --- a/fuse/node/mount_test.go +++ b/fuse/node/mount_test.go @@ -32,7 +32,7 @@ func mkdir(t *testing.T, path string) { } } -// Test externally unmounting, then trying to unmount in code +// Test externally unmounting, then trying to unmount in code. func TestExternalUnmount(t *testing.T) { if testing.Short() { t.SkipNow() diff --git a/fuse/node/mount_unix.go b/fuse/node/mount_unix.go index 84795b13d..1e509a243 100644 --- a/fuse/node/mount_unix.go +++ b/fuse/node/mount_unix.go @@ -19,14 +19,14 @@ import ( var log = logging.Logger("node") -// fuseNoDirectory used to check the returning fuse error +// fuseNoDirectory used to check the returning fuse error. const fuseNoDirectory = "fusermount: failed to access mountpoint" -// fuseExitStatus1 used to check the returning fuse error +// fuseExitStatus1 used to check the returning fuse error. const fuseExitStatus1 = "fusermount: exit status 1" // platformFuseChecks can get overridden by arch-specific files -// to run fuse checks (like checking the OSXFUSE version) +// to run fuse checks (like checking the OSXFUSE version). var platformFuseChecks = func(*core.IpfsNode) error { return nil } diff --git a/fuse/readonly/ipfs_test.go b/fuse/readonly/ipfs_test.go index ffe86509d..bc6204abb 100644 --- a/fuse/readonly/ipfs_test.go +++ b/fuse/readonly/ipfs_test.go @@ -79,7 +79,7 @@ func setupIpfsTest(t *testing.T, node *core.IpfsNode) (*core.IpfsNode, *fstest.M return node, mnt } -// Test writing an object and reading it back through fuse +// Test writing an object and reading it back through fuse. func TestIpfsBasicRead(t *testing.T) { if testing.Short() { t.SkipNow() @@ -122,7 +122,7 @@ func getPaths(t *testing.T, ipfs *core.IpfsNode, name string, n *dag.ProtoNode) return out } -// Perform a large number of concurrent reads to stress the system +// Perform a large number of concurrent reads to stress the system. func TestIpfsStressRead(t *testing.T) { if testing.Short() { t.SkipNow() @@ -194,8 +194,8 @@ func TestIpfsStressRead(t *testing.T) { errs <- err } - //nd.Context() is never closed which leads to - //hitting 8128 goroutine limit in go test -race mode + // nd.Context() is never closed which leads to + // hitting 8128 goroutine limit in go test -race mode ctx, cancelFunc := context.WithCancel(context.Background()) read, err := api.Unixfs().Get(ctx, item) @@ -229,7 +229,7 @@ func TestIpfsStressRead(t *testing.T) { } } -// Test writing a file and reading it back +// Test writing a file and reading it back. func TestIpfsBasicDirRead(t *testing.T) { if testing.Short() { t.SkipNow() @@ -280,7 +280,7 @@ func TestIpfsBasicDirRead(t *testing.T) { } } -// Test to make sure the filesystem reports file sizes correctly +// Test to make sure the filesystem reports file sizes correctly. func TestFileSizeReporting(t *testing.T) { if testing.Short() { t.SkipNow() diff --git a/fuse/readonly/readonly_unix.go b/fuse/readonly/readonly_unix.go index d925ec8c2..c75a35fbd 100644 --- a/fuse/readonly/readonly_unix.go +++ b/fuse/readonly/readonly_unix.go @@ -49,7 +49,7 @@ type Root struct { // Attr returns file attributes. func (*Root) Attr(ctx context.Context, a *fuse.Attr) error { - a.Mode = os.ModeDir | 0111 // -rw+x + a.Mode = os.ModeDir | 0o111 // -rw+x return nil } @@ -139,7 +139,7 @@ func (s *Node) loadData() error { func (s *Node) Attr(ctx context.Context, a *fuse.Attr) error { log.Debug("Node attr") if rawnd, ok := s.Nd.(*mdag.RawNode); ok { - a.Mode = 0444 + a.Mode = 0o444 a.Size = uint64(len(rawnd.RawData())) a.Blocks = 1 return nil @@ -152,18 +152,18 @@ func (s *Node) Attr(ctx context.Context, a *fuse.Attr) error { } switch s.cached.Type() { case ft.TDirectory, ft.THAMTShard: - a.Mode = os.ModeDir | 0555 + a.Mode = os.ModeDir | 0o555 case ft.TFile: size := s.cached.FileSize() - a.Mode = 0444 + a.Mode = 0o444 a.Size = uint64(size) a.Blocks = uint64(len(s.Nd.Links())) case ft.TRaw: - a.Mode = 0444 + a.Mode = 0o444 a.Size = uint64(len(s.cached.Data())) a.Blocks = uint64(len(s.Nd.Links())) case ft.TSymlink: - a.Mode = 0777 | os.ModeSymlink + a.Mode = 0o777 | os.ModeSymlink a.Size = uint64(len(s.cached.Data())) default: return fmt.Errorf("invalid data type - %s", s.cached.Type()) @@ -195,7 +195,7 @@ func (s *Node) Lookup(ctx context.Context, name string) (fs.Node, error) { return &Node{Ipfs: s.Ipfs, Nd: nd}, nil } -// ReadDirAll reads the link structure as directory entries +// ReadDirAll reads the link structure as directory entries. func (s *Node) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) { log.Debug("Node ReadDir") dir, err := uio.NewDirectoryFromNode(s.Ipfs.DAG, s.Nd) @@ -284,7 +284,7 @@ func (s *Node) Read(ctx context.Context, req *fuse.ReadRequest, resp *fuse.ReadR return nil // may be non-nil / not succeeded } -// to check that out Node implements all the interfaces we want +// to check that out Node implements all the interfaces we want. type roRoot interface { fs.Node fs.HandleReadDirAller diff --git a/gc/gc.go b/gc/gc.go index 031ba16dc..c85f9d6bf 100644 --- a/gc/gc.go +++ b/gc/gc.go @@ -191,7 +191,6 @@ func Descendants(ctx context.Context, getLinks dag.GetLinks, set *cid.Set, roots err := dag.Walk(ctx, verifyGetLinks, wrapper.C, func(k cid.Cid) bool { return set.Visit(toCidV1(k)) }, dag.Concurrent()) - if err != nil { err = verboseCidError(err) return err diff --git a/p2p/listener.go b/p2p/listener.go index 906137ea1..f5942ffa0 100644 --- a/p2p/listener.go +++ b/p2p/listener.go @@ -10,7 +10,7 @@ import ( ma "github.com/multiformats/go-multiaddr" ) -// Listener listens for connections and proxies them to a target +// Listener listens for connections and proxies them to a target. type Listener interface { Protocol() protocol.ID ListenAddress() ma.Multiaddr @@ -23,7 +23,7 @@ type Listener interface { } // Listeners manages a group of Listener implementations, -// checking for conflicts and optionally dispatching connections +// checking for conflicts and optionally dispatching connections. type Listeners struct { sync.RWMutex @@ -60,7 +60,7 @@ func newListenersP2P(host p2phost.Host) *Listeners { return reg } -// Register registers listenerInfo into this registry and starts it +// Register registers listenerInfo into this registry and starts it. func (r *Listeners) Register(l Listener) error { r.Lock() defer r.Unlock() diff --git a/p2p/local.go b/p2p/local.go index 85baf948b..6ef110c39 100644 --- a/p2p/local.go +++ b/p2p/local.go @@ -12,7 +12,7 @@ import ( manet "github.com/multiformats/go-multiaddr/net" ) -// localListener manet streams and proxies them to libp2p services +// localListener manet streams and proxies them to libp2p services. type localListener struct { ctx context.Context @@ -25,7 +25,7 @@ type localListener struct { listener manet.Listener } -// ForwardLocal creates new P2P stream to a remote listener +// ForwardLocal creates new P2P stream to a remote listener. func (p2p *P2P) ForwardLocal(ctx context.Context, peer peer.ID, proto protocol.ID, bindAddr ma.Multiaddr) (Listener, error) { listener := &localListener{ ctx: ctx, diff --git a/p2p/p2p.go b/p2p/p2p.go index e18488c2d..1d0989421 100644 --- a/p2p/p2p.go +++ b/p2p/p2p.go @@ -10,7 +10,7 @@ import ( var log = logging.Logger("p2p-mount") -// P2P structure holds information on currently running streams/Listeners +// P2P structure holds information on currently running streams/Listeners. type P2P struct { ListenersLocal *Listeners ListenersP2P *Listeners @@ -21,7 +21,7 @@ type P2P struct { peerstore pstore.Peerstore } -// New creates new P2P struct +// New creates new P2P struct. func New(identity peer.ID, peerHost p2phost.Host, peerstore pstore.Peerstore) *P2P { return &P2P{ identity: identity, @@ -40,7 +40,7 @@ func New(identity peer.ID, peerHost p2phost.Host, peerstore pstore.Peerstore) *P } // CheckProtoExists checks whether a proto handler is registered to -// mux handler +// mux handler. func (p2p *P2P) CheckProtoExists(proto protocol.ID) bool { protos := p2p.peerHost.Mux().Protocols() diff --git a/p2p/remote.go b/p2p/remote.go index ac540e9a5..a90155a21 100644 --- a/p2p/remote.go +++ b/p2p/remote.go @@ -12,7 +12,7 @@ import ( var maPrefix = "/" + ma.ProtocolWithCode(ma.P_IPFS).Name + "/" -// remoteListener accepts libp2p streams and proxies them to a manet host +// remoteListener accepts libp2p streams and proxies them to a manet host. type remoteListener struct { p2p *P2P @@ -27,7 +27,7 @@ type remoteListener struct { reportRemote bool } -// ForwardRemote creates new p2p listener +// ForwardRemote creates new p2p listener. func (p2p *P2P) ForwardRemote(ctx context.Context, proto protocol.ID, addr ma.Multiaddr, reportRemote bool) (Listener, error) { listener := &remoteListener{ p2p: p2p, diff --git a/p2p/stream.go b/p2p/stream.go index ec8bac508..5d05cba79 100644 --- a/p2p/stream.go +++ b/p2p/stream.go @@ -30,12 +30,12 @@ type Stream struct { Registry *StreamRegistry } -// close stream endpoints and deregister it +// close stream endpoints and deregister it. func (s *Stream) close() { s.Registry.Close(s) } -// reset closes stream endpoints and deregisters it +// reset closes stream endpoints and deregisters it. func (s *Stream) reset() { s.Registry.Reset(s) } @@ -71,7 +71,7 @@ type StreamRegistry struct { ifconnmgr.ConnManager } -// Register registers a stream to the registry +// Register registers a stream to the registry. func (r *StreamRegistry) Register(streamInfo *Stream) { r.Lock() defer r.Unlock() @@ -86,7 +86,7 @@ func (r *StreamRegistry) Register(streamInfo *Stream) { streamInfo.startStreaming() } -// Deregister deregisters stream from the registry +// Deregister deregisters stream from the registry. func (r *StreamRegistry) Deregister(streamID uint64) { r.Lock() defer r.Unlock() @@ -105,14 +105,14 @@ func (r *StreamRegistry) Deregister(streamID uint64) { delete(r.Streams, streamID) } -// Close stream endpoints and deregister it +// Close stream endpoints and deregister it. func (r *StreamRegistry) Close(s *Stream) { _ = s.Local.Close() _ = s.Remote.Close() s.Registry.Deregister(s.id) } -// Reset closes stream endpoints and deregisters it +// Reset closes stream endpoints and deregisters it. func (r *StreamRegistry) Reset(s *Stream) { _ = s.Local.Close() _ = s.Remote.Reset() diff --git a/peering/peering.go b/peering/peering.go index 00801626f..291d9491c 100644 --- a/peering/peering.go +++ b/peering/peering.go @@ -201,7 +201,7 @@ func (ps *PeeringService) Start() error { return nil } -// GetState get the State of the PeeringService +// GetState get the State of the PeeringService. func (ps *PeeringService) GetState() State { ps.mu.RLock() defer ps.mu.RUnlock() @@ -306,6 +306,7 @@ func (nn *netNotifee) Connected(_ network.Network, c network.Conn) { go handler.stopIfConnected() } } + func (nn *netNotifee) Disconnected(_ network.Network, c network.Conn) { ps := (*PeeringService)(nn) diff --git a/plugin/datastore.go b/plugin/datastore.go index 15d93f3e6..e31a144d4 100644 --- a/plugin/datastore.go +++ b/plugin/datastore.go @@ -5,7 +5,7 @@ import ( ) // PluginDatastore is an interface that can be implemented to add handlers for -// for different datastores +// for different datastores. type PluginDatastore interface { Plugin diff --git a/plugin/ipld.go b/plugin/ipld.go index 2f783a612..d366b92cc 100644 --- a/plugin/ipld.go +++ b/plugin/ipld.go @@ -5,7 +5,7 @@ import ( ) // PluginIPLD is an interface that can be implemented to add handlers for -// for different IPLD codecs +// for different IPLD codecs. type PluginIPLD interface { Plugin diff --git a/plugin/loader/loader.go b/plugin/loader/loader.go index 84ebdc0fc..80cc9a1b6 100644 --- a/plugin/loader/loader.go +++ b/plugin/loader/loader.go @@ -93,7 +93,7 @@ type PluginLoader struct { repo string } -// NewPluginLoader creates new plugin loader +// NewPluginLoader creates new plugin loader. func NewPluginLoader(repo string) (*PluginLoader, error) { loader := &PluginLoader{plugins: make([]plugin.Plugin, 0, len(preloadPlugins)), repo: repo} if repo != "" { @@ -226,7 +226,7 @@ func loadDynamicPlugins(pluginDir string) ([]plugin.Plugin, error) { return nil } - if info.Mode().Perm()&0111 == 0 { + if info.Mode().Perm()&0o111 == 0 { // file is not executable let's not load it // this is to prevent loading plugins from for example non-executable // mounts, some /tmp mounts are marked as such for security @@ -245,7 +245,7 @@ func loadDynamicPlugins(pluginDir string) ([]plugin.Plugin, error) { return plugins, err } -// Initialize initializes all loaded plugins +// Initialize initializes all loaded plugins. func (loader *PluginLoader) Initialize() error { if err := loader.transition(loaderLoading, loaderInitializing); err != nil { return err diff --git a/plugin/plugins/badgerds/badgerds.go b/plugin/plugins/badgerds/badgerds.go index 3d3f69061..5f5781f8f 100644 --- a/plugin/plugins/badgerds/badgerds.go +++ b/plugin/plugins/badgerds/badgerds.go @@ -13,7 +13,7 @@ import ( badgerds "github.com/ipfs/go-ds-badger" ) -// Plugins is exported list of plugins that will be loaded +// Plugins is exported list of plugins that will be loaded. var Plugins = []plugin.Plugin{ &badgerdsPlugin{}, } @@ -47,7 +47,7 @@ type datastoreConfig struct { } // BadgerdsDatastoreConfig returns a configuration stub for a badger datastore -// from the given parameters +// from the given parameters. func (*badgerdsPlugin) DatastoreConfigParser() fsrepo.ConfigFromMap { return func(params map[string]interface{}) (fsrepo.DatastoreConfig, error) { var c datastoreConfig @@ -113,7 +113,7 @@ func (c *datastoreConfig) Create(path string) (repo.Datastore, error) { p = filepath.Join(path, p) } - err := os.MkdirAll(p, 0755) + err := os.MkdirAll(p, 0o755) if err != nil { return nil, err } diff --git a/plugin/plugins/dagjose/dagjose.go b/plugin/plugins/dagjose/dagjose.go index 943214629..4545e2e96 100644 --- a/plugin/plugins/dagjose/dagjose.go +++ b/plugin/plugins/dagjose/dagjose.go @@ -8,7 +8,7 @@ import ( mc "github.com/multiformats/go-multicodec" ) -// Plugins is exported list of plugins that will be loaded +// Plugins is exported list of plugins that will be loaded. var Plugins = []plugin.Plugin{ &dagjosePlugin{}, } diff --git a/plugin/plugins/flatfs/flatfs.go b/plugin/plugins/flatfs/flatfs.go index 40b8b37d0..1a23dfcca 100644 --- a/plugin/plugins/flatfs/flatfs.go +++ b/plugin/plugins/flatfs/flatfs.go @@ -11,7 +11,7 @@ import ( flatfs "github.com/ipfs/go-ds-flatfs" ) -// Plugins is exported list of plugins that will be loaded +// Plugins is exported list of plugins that will be loaded. var Plugins = []plugin.Plugin{ &flatfsPlugin{}, } @@ -43,7 +43,7 @@ type datastoreConfig struct { } // BadgerdsDatastoreConfig returns a configuration stub for a badger datastore -// from the given parameters +// from the given parameters. func (*flatfsPlugin) DatastoreConfigParser() fsrepo.ConfigFromMap { return func(params map[string]interface{}) (fsrepo.DatastoreConfig, error) { var c datastoreConfig diff --git a/plugin/plugins/git/git.go b/plugin/plugins/git/git.go index 2c56d8339..baaea6c35 100644 --- a/plugin/plugins/git/git.go +++ b/plugin/plugins/git/git.go @@ -13,7 +13,7 @@ import ( mc "github.com/multiformats/go-multicodec" ) -// Plugins is exported list of plugins that will be loaded +// Plugins is exported list of plugins that will be loaded. var Plugins = []plugin.Plugin{ &gitPlugin{}, } diff --git a/plugin/plugins/levelds/levelds.go b/plugin/plugins/levelds/levelds.go index ccb7c08f8..b08872de6 100644 --- a/plugin/plugins/levelds/levelds.go +++ b/plugin/plugins/levelds/levelds.go @@ -12,7 +12,7 @@ import ( ldbopts "github.com/syndtr/goleveldb/leveldb/opt" ) -// Plugins is exported list of plugins that will be loaded +// Plugins is exported list of plugins that will be loaded. var Plugins = []plugin.Plugin{ &leveldsPlugin{}, } @@ -43,7 +43,7 @@ type datastoreConfig struct { } // BadgerdsDatastoreConfig returns a configuration stub for a badger datastore -// from the given parameters +// from the given parameters. func (*leveldsPlugin) DatastoreConfigParser() fsrepo.ConfigFromMap { return func(params map[string]interface{}) (fsrepo.DatastoreConfig, error) { var c datastoreConfig diff --git a/plugin/plugins/peerlog/peerlog.go b/plugin/plugins/peerlog/peerlog.go index 1b71cb1ae..f41a8b654 100644 --- a/plugin/plugins/peerlog/peerlog.go +++ b/plugin/plugins/peerlog/peerlog.go @@ -20,7 +20,7 @@ var log = logging.Logger("plugin/peerlog") type eventType int var ( - // size of the event queue buffer + // size of the event queue buffer. eventQueueSize = 64 * 1024 // number of events to drop when busy. busyDropAmount = eventQueueSize / 8 @@ -54,7 +54,7 @@ type peerLogPlugin struct { var _ plugin.PluginDaemonInternal = (*peerLogPlugin)(nil) -// Plugins is exported list of plugins that will be loaded +// Plugins is exported list of plugins that will be loaded. var Plugins = []plugin.Plugin{ &peerLogPlugin{}, } @@ -94,7 +94,7 @@ func extractEnabled(config interface{}) bool { return enabled } -// Init initializes plugin +// Init initializes plugin. func (pl *peerLogPlugin) Init(env *plugin.Environment) error { pl.events = make(chan plEvent, eventQueueSize) pl.enabled = extractEnabled(env.Config) diff --git a/plugin/tracer.go b/plugin/tracer.go index b6b56939d..97aa84846 100644 --- a/plugin/tracer.go +++ b/plugin/tracer.go @@ -4,7 +4,7 @@ import ( "github.com/opentracing/opentracing-go" ) -// PluginTracer is an interface that can be implemented to add a tracer +// PluginTracer is an interface that can be implemented to add a tracer. type PluginTracer interface { Plugin diff --git a/repo/common/common.go b/repo/common/common.go index e9c56e65e..ab74ffca8 100644 --- a/repo/common/common.go +++ b/repo/common/common.go @@ -62,7 +62,7 @@ func MapSetKV(v map[string]interface{}, key string, value interface{}) error { } // Merges the right map into the left map, recursively traversing child maps -// until a non-map value is found +// until a non-map value is found. func MapMergeDeep(left, right map[string]interface{}) map[string]interface{} { // We want to alter a copy of the map, not the original result := make(map[string]interface{}) diff --git a/repo/fsrepo/config_test.go b/repo/fsrepo/config_test.go index 060d0222a..3c914ff82 100644 --- a/repo/fsrepo/config_test.go +++ b/repo/fsrepo/config_test.go @@ -12,7 +12,7 @@ import ( ) // note: to test sorting of the mountpoints in the disk spec they are -// specified out of order in the test config +// specified out of order in the test config. var defaultConfig = []byte(`{ "StorageMax": "10GB", "StorageGCWatermark": 90, diff --git a/repo/fsrepo/datastores.go b/repo/fsrepo/datastores.go index 0f60056aa..86ed0a863 100644 --- a/repo/fsrepo/datastores.go +++ b/repo/fsrepo/datastores.go @@ -14,12 +14,12 @@ import ( "github.com/ipfs/go-ds-measure" ) -// ConfigFromMap creates a new datastore config from a map +// ConfigFromMap creates a new datastore config from a map. type ConfigFromMap func(map[string]interface{}) (DatastoreConfig, error) // DatastoreConfig is an abstraction of a datastore config. A "spec" // is first converted to a DatastoreConfig and then Create() is called -// to instantiate a new datastore +// to instantiate a new datastore. type DatastoreConfig interface { // DiskSpec returns a minimal configuration of the datastore // represting what is stored on disk. Run time values are @@ -38,7 +38,7 @@ type DatastoreConfig interface { // here. type DiskSpec map[string]interface{} -// Bytes returns a minimal JSON encoding of the DiskSpec +// Bytes returns a minimal JSON encoding of the DiskSpec. func (spec DiskSpec) Bytes() []byte { b, err := json.Marshal(spec) if err != nil { @@ -48,7 +48,7 @@ func (spec DiskSpec) Bytes() []byte { return bytes.TrimSpace(b) } -// String returns a minimal JSON encoding of the DiskSpec +// String returns a minimal JSON encoding of the DiskSpec. func (spec DiskSpec) String() string { return string(spec.Bytes()) } @@ -75,7 +75,7 @@ func AddDatastoreConfigHandler(name string, dsc ConfigFromMap) error { } // AnyDatastoreConfig returns a DatastoreConfig from a spec based on -// the "type" parameter +// the "type" parameter. func AnyDatastoreConfig(params map[string]interface{}) (DatastoreConfig, error) { which, ok := params["type"].(string) if !ok { @@ -97,7 +97,7 @@ type premount struct { prefix ds.Key } -// MountDatastoreConfig returns a mount DatastoreConfig from a spec +// MountDatastoreConfig returns a mount DatastoreConfig from a spec. func MountDatastoreConfig(params map[string]interface{}) (DatastoreConfig, error) { var res mountDatastoreConfig mounts, ok := params["mounts"].([]interface{}) @@ -165,7 +165,7 @@ type memDatastoreConfig struct { cfg map[string]interface{} } -// MemDatastoreConfig returns a memory DatastoreConfig from a spec +// MemDatastoreConfig returns a memory DatastoreConfig from a spec. func MemDatastoreConfig(params map[string]interface{}) (DatastoreConfig, error) { return &memDatastoreConfig{params}, nil } @@ -183,7 +183,7 @@ type logDatastoreConfig struct { name string } -// LogDatastoreConfig returns a log DatastoreConfig from a spec +// LogDatastoreConfig returns a log DatastoreConfig from a spec. func LogDatastoreConfig(params map[string]interface{}) (DatastoreConfig, error) { childField, ok := params["child"].(map[string]interface{}) if !ok { @@ -198,7 +198,6 @@ func LogDatastoreConfig(params map[string]interface{}) (DatastoreConfig, error) return nil, fmt.Errorf("'name' field was missing or not a string") } return &logDatastoreConfig{child, name}, nil - } func (c *logDatastoreConfig) Create(path string) (repo.Datastore, error) { @@ -218,7 +217,7 @@ type measureDatastoreConfig struct { prefix string } -// MeasureDatastoreConfig returns a measure DatastoreConfig from a spec +// MeasureDatastoreConfig returns a measure DatastoreConfig from a spec. func MeasureDatastoreConfig(params map[string]interface{}) (DatastoreConfig, error) { childField, ok := params["child"].(map[string]interface{}) if !ok { diff --git a/repo/fsrepo/fsrepo.go b/repo/fsrepo/fsrepo.go index 3c4a709c1..c2f7ca72a 100644 --- a/repo/fsrepo/fsrepo.go +++ b/repo/fsrepo/fsrepo.go @@ -31,12 +31,12 @@ import ( ) // LockFile is the filename of the repo lock, relative to config dir -// TODO rename repo lock and hide name +// TODO rename repo lock and hide name. const LockFile = "repo.lock" var log = logging.Logger("fsrepo") -// RepoVersion is the version number that we are currently expecting to see +// RepoVersion is the version number that we are currently expecting to see. var RepoVersion = 14 var migrationInstructions = `See https://github.com/ipfs/fs-repo-migrations/blob/master/run.md @@ -64,9 +64,11 @@ func (err NoRepoError) Error() string { return fmt.Sprintf("no IPFS repo found in %s.\nplease run: 'ipfs init'", err.Path) } -const apiFile = "api" -const gatewayFile = "gateway" -const swarmKeyFile = "swarm.key" +const ( + apiFile = "api" + gatewayFile = "gateway" + swarmKeyFile = "swarm.key" +) const specFn = "datastore_spec" @@ -277,13 +279,12 @@ func initSpec(path string, conf map[string]interface{}) error { } bytes := dsc.DiskSpec().Bytes() - return os.WriteFile(fn, bytes, 0600) + return os.WriteFile(fn, bytes, 0o600) } // Init initializes a new FSRepo at the given path with the provided config. // TODO add support for custom datastores. func Init(repoPath string, conf *config.Config) error { - // packageLock must be held to ensure that the repo is not initialized more // than once. packageLock.Lock() @@ -597,7 +598,7 @@ func (r *FSRepo) BackupConfig(prefix string) (string, error) { } defer temp.Close() - orig, err := os.OpenFile(r.configFilePath, os.O_RDONLY, 0600) + orig, err := os.OpenFile(r.configFilePath, os.O_RDONLY, 0o600) if err != nil { return "", err } @@ -626,7 +627,6 @@ func (r *FSRepo) BackupConfig(prefix string) (string, error) { // We need to comb SetConfig calls and replace them when possible with a // JSON map variant. func (r *FSRepo) SetConfig(updated *config.Config) error { - // packageLock is held to provide thread-safety. packageLock.Lock() defer packageLock.Unlock() @@ -725,7 +725,7 @@ func (r *FSRepo) Datastore() repo.Datastore { return d } -// GetStorageUsage computes the storage space taken by the repo in bytes +// GetStorageUsage computes the storage space taken by the repo in bytes. func (r *FSRepo) GetStorageUsage(ctx context.Context) (uint64, error) { return ds.DiskUsage(ctx, r.Datastore()) } @@ -746,8 +746,10 @@ func (r *FSRepo) SwarmKey() ([]byte, error) { return io.ReadAll(f) } -var _ io.Closer = &FSRepo{} -var _ repo.Repo = &FSRepo{} +var ( + _ io.Closer = &FSRepo{} + _ repo.Repo = &FSRepo{} +) // IsInitialized returns true if the repo is initialized at provided |path|. func IsInitialized(path string) bool { diff --git a/repo/fsrepo/migrations/fetch.go b/repo/fsrepo/migrations/fetch.go index 7feeac6e9..60081210f 100644 --- a/repo/fsrepo/migrations/fetch.go +++ b/repo/fsrepo/migrations/fetch.go @@ -130,7 +130,7 @@ func FetchBinary(ctx context.Context, fetcher Fetcher, dist, ver, binName, out s } // Set mode of binary to executable - err = os.Chmod(out, 0755) + err = os.Chmod(out, 0o755) if err != nil { return "", err } @@ -184,7 +184,7 @@ func osWithVariant() (string, error) { // "go-ipfs_v0.8.0-rc2_linux-amd64.tar.gz" // // This would form the path: -// go-ipfs/v0.8.0/go-ipfs_v0.8.0_linux-amd64.tar.gz +// go-ipfs/v0.8.0/go-ipfs_v0.8.0_linux-amd64.tar.gz. func makeArchivePath(dist, name, ver, atype string) (string, string) { arcName := fmt.Sprintf("%s_%s_%s-%s.%s", name, ver, runtime.GOOS, runtime.GOARCH, atype) return fmt.Sprintf("%s/%s/%s", dist, ver, arcName), arcName diff --git a/repo/fsrepo/migrations/fetch_test.go b/repo/fsrepo/migrations/fetch_test.go index 2273cb5e9..27452d386 100644 --- a/repo/fsrepo/migrations/fetch_test.go +++ b/repo/fsrepo/migrations/fetch_test.go @@ -184,7 +184,7 @@ func TestFetchBinary(t *testing.T) { // Windows doesn't have read-only directories https://github.com/golang/go/issues/35042 this would need to be // tested another way if runtime.GOOS != "windows" { - err = os.Chmod(tmpDir, 0555) + err = os.Chmod(tmpDir, 0o555) if err != nil { panic(err) } @@ -200,7 +200,7 @@ func TestFetchBinary(t *testing.T) { if err != nil { panic(err) } - err = os.Chmod(tmpDir, 0755) + err = os.Chmod(tmpDir, 0o755) if err != nil { panic(err) } diff --git a/repo/fsrepo/migrations/fetcher.go b/repo/fsrepo/migrations/fetcher.go index 1dc4d0345..dc6d3c642 100644 --- a/repo/fsrepo/migrations/fetcher.go +++ b/repo/fsrepo/migrations/fetcher.go @@ -10,12 +10,12 @@ import ( ) const ( - // Current distribution to fetch migrations from + // Current distribution to fetch migrations from. CurrentIpfsDist = "/ipfs/QmYerugGRCZWA8yQMKDsd9daEVXUR3C5nuw3VXuX1mggHa" // fs-repo-13-to-14 v1.0.0 // Latest distribution path. Default for fetchers. LatestIpfsDist = "/ipns/dist.ipfs.tech" - // Distribution environ variable + // Distribution environ variable. envIpfsDistPath = "IPFS_DIST_PATH" ) @@ -40,7 +40,6 @@ type limitReadCloser struct { // NewMultiFetcher creates a MultiFetcher with the given Fetchers. The // Fetchers are tried in order, then passed to this function. func NewMultiFetcher(f ...Fetcher) *MultiFetcher { - mf := &MultiFetcher{ fetchers: make([]Fetcher, len(f)), } @@ -95,7 +94,7 @@ func NewLimitReadCloser(rc io.ReadCloser, limit int64) io.ReadCloser { // then returns the IPNS path. // // To get the IPFS path of the latest distribution, if not overriddin by the -// environ variable: GetDistPathEnv(CurrentIpfsDist) +// environ variable: GetDistPathEnv(CurrentIpfsDist). func GetDistPathEnv(distPath string) string { if dist := os.Getenv(envIpfsDistPath); dist != "" { return dist diff --git a/repo/fsrepo/migrations/httpfetcher.go b/repo/fsrepo/migrations/httpfetcher.go index 81e0e406d..588a01ead 100644 --- a/repo/fsrepo/migrations/httpfetcher.go +++ b/repo/fsrepo/migrations/httpfetcher.go @@ -11,11 +11,11 @@ import ( const ( defaultGatewayURL = "https://ipfs.io" - // Default maximum download size + // Default maximum download size. defaultFetchLimit = 1024 * 1024 * 512 ) -// HttpFetcher fetches files over HTTP +// HttpFetcher fetches files over HTTP. type HttpFetcher struct { //nolint distPath string gateway string diff --git a/repo/fsrepo/migrations/ipfsdir.go b/repo/fsrepo/migrations/ipfsdir.go index 1f1c320bf..464118d1c 100644 --- a/repo/fsrepo/migrations/ipfsdir.go +++ b/repo/fsrepo/migrations/ipfsdir.go @@ -84,7 +84,7 @@ func WriteRepoVersion(ipfsDir string, version int) error { } vFilePath := filepath.Join(ipfsDir, versionFile) - return os.WriteFile(vFilePath, []byte(fmt.Sprintf("%d\n", version)), 0644) + return os.WriteFile(vFilePath, []byte(fmt.Sprintf("%d\n", version)), 0o644) } func repoVersion(ipfsDir string) (int, error) { diff --git a/repo/fsrepo/migrations/ipfsdir_test.go b/repo/fsrepo/migrations/ipfsdir_test.go index a92a6a6d0..e4e626794 100644 --- a/repo/fsrepo/migrations/ipfsdir_test.go +++ b/repo/fsrepo/migrations/ipfsdir_test.go @@ -138,7 +138,7 @@ func testRepoVersion(t *testing.T) { t.Fatal(err) } vFilePath := filepath.Join(ipfsDir, versionFile) - err = os.WriteFile(vFilePath, []byte("bad-version-data\n"), 0644) + err = os.WriteFile(vFilePath, []byte("bad-version-data\n"), 0o644) if err != nil { panic(err) } diff --git a/repo/fsrepo/migrations/ipfsfetcher/ipfsfetcher.go b/repo/fsrepo/migrations/ipfsfetcher/ipfsfetcher.go index 977b31656..b35cab683 100644 --- a/repo/fsrepo/migrations/ipfsfetcher/ipfsfetcher.go +++ b/repo/fsrepo/migrations/ipfsfetcher/ipfsfetcher.go @@ -25,7 +25,7 @@ import ( ) const ( - // Default maximum download size + // Default maximum download size. defaultFetchLimit = 1024 * 1024 * 512 tempNodeTCPAddr = "/ip4/127.0.0.1/tcp/0" @@ -155,7 +155,7 @@ func (f *IpfsFetcher) AddrInfo() peer.AddrInfo { return f.addrInfo } -// FetchedPaths returns the IPFS paths of all items fetched by this fetcher +// FetchedPaths returns the IPFS paths of all items fetched by this fetcher. func (f *IpfsFetcher) FetchedPaths() []ipath.Path { f.mutex.Lock() defer f.mutex.Unlock() diff --git a/repo/fsrepo/migrations/ipfsfetcher/ipfsfetcher_test.go b/repo/fsrepo/migrations/ipfsfetcher/ipfsfetcher_test.go index f3a2a9313..7323d0172 100644 --- a/repo/fsrepo/migrations/ipfsfetcher/ipfsfetcher_test.go +++ b/repo/fsrepo/migrations/ipfsfetcher/ipfsfetcher_test.go @@ -55,7 +55,6 @@ func TestIpfsFetcher(t *testing.T) { if _, err = fetcher.Fetch(ctx, "/no_such_file"); err == nil { t.Fatal("expected error 404") } - } func TestInitIpfsFetcher(t *testing.T) { @@ -110,7 +109,7 @@ func TestInitIpfsFetcher(t *testing.T) { } func TestReadIpfsConfig(t *testing.T) { - var testConfig = ` + testConfig := ` { "Bootstrap": [ "/dnsaddr/bootstrap.libp2p.io/p2p/QmcZf59bWwK5XFi76CZX8cbJ4BhTzzA3gU1ZjYZcYW3dwt", diff --git a/repo/fsrepo/migrations/migrations.go b/repo/fsrepo/migrations/migrations.go index 7e764b731..14cc6c2de 100644 --- a/repo/fsrepo/migrations/migrations.go +++ b/repo/fsrepo/migrations/migrations.go @@ -151,7 +151,7 @@ func ReadMigrationConfig(repoRoot string, userConfigFile string) (*config.Migrat } // GetMigrationFetcher creates one or more fetchers according to -// downloadSources, +// downloadSources,. func GetMigrationFetcher(downloadSources []string, distPath string, newIpfsFetcher func(string) Fetcher) (Fetcher, error) { const httpUserAgent = "go-ipfs" const numTriesPerHTTP = 3 diff --git a/repo/fsrepo/migrations/migrations_test.go b/repo/fsrepo/migrations/migrations_test.go index 5f029e6a1..2fd75b7e9 100644 --- a/repo/fsrepo/migrations/migrations_test.go +++ b/repo/fsrepo/migrations/migrations_test.go @@ -191,7 +191,7 @@ func createFakeBin(from, to int, tmpDir string) { panic(err) } emptyFile.Close() - err = os.Chmod(migPath, 0755) + err = os.Chmod(migPath, 0o755) if err != nil { panic(err) } diff --git a/repo/fsrepo/migrations/unpack_test.go b/repo/fsrepo/migrations/unpack_test.go index be5bb4f39..e1152e2ca 100644 --- a/repo/fsrepo/migrations/unpack_test.go +++ b/repo/fsrepo/migrations/unpack_test.go @@ -35,7 +35,7 @@ func TestUnpackTgz(t *testing.T) { tmpDir := t.TempDir() badTarGzip := filepath.Join(tmpDir, "bad.tar.gz") - err := os.WriteFile(badTarGzip, []byte("bad-data\n"), 0644) + err := os.WriteFile(badTarGzip, []byte("bad-data\n"), 0o644) if err != nil { panic(err) } @@ -72,14 +72,13 @@ func TestUnpackTgz(t *testing.T) { if fi.Size() != int64(len(testData)) { t.Fatal("unpacked file size is", fi.Size(), "expected", len(testData)) } - } func TestUnpackZip(t *testing.T) { tmpDir := t.TempDir() badZip := filepath.Join(tmpDir, "bad.zip") - err := os.WriteFile(badZip, []byte("bad-data\n"), 0644) + err := os.WriteFile(badZip, []byte("bad-data\n"), 0o644) if err != nil { panic(err) } @@ -153,7 +152,7 @@ func writeTarGzip(root, fileName, data string, w io.Writer) error { if fileName != "" { hdr := &tar.Header{ Name: path.Join(root, fileName), - Mode: 0600, + Mode: 0o600, Size: int64(len(data)), } // Write header diff --git a/repo/mock.go b/repo/mock.go index ae4d98d3b..46bb0cb42 100644 --- a/repo/mock.go +++ b/repo/mock.go @@ -15,7 +15,7 @@ import ( var errTODO = errors.New("TODO: mock repo") -// Mock is not thread-safe +// Mock is not thread-safe. type Mock struct { C config.Config D Datastore diff --git a/repo/repo.go b/repo/repo.go index 05e938825..9abdf867e 100644 --- a/repo/repo.go +++ b/repo/repo.go @@ -15,9 +15,7 @@ import ( ma "github.com/multiformats/go-multiaddr" ) -var ( - ErrApiNotRunning = errors.New("api not running") //nolint -) +var ErrApiNotRunning = errors.New("api not running") //nolint // Repo represents all persistent data of a given ipfs node. type Repo interface { diff --git a/routing/composer.go b/routing/composer.go index 24af9b356..92c351fc5 100644 --- a/routing/composer.go +++ b/routing/composer.go @@ -11,8 +11,10 @@ import ( "github.com/multiformats/go-multihash" ) -var _ routinghelpers.ProvideManyRouter = &Composer{} -var _ routing.Routing = &Composer{} +var ( + _ routinghelpers.ProvideManyRouter = &Composer{} + _ routing.Routing = &Composer{} +) type Composer struct { GetValueRouter routing.Routing @@ -27,7 +29,6 @@ func (c *Composer) Provide(ctx context.Context, cid cid.Cid, provide bool) error err := c.ProvideRouter.Provide(ctx, cid, provide) if err != nil { log.Debug("composer: calling provide: ", cid, " error: ", err) - } return err diff --git a/routing/delegated_test.go b/routing/delegated_test.go index da0210f5e..028f3b465 100644 --- a/routing/delegated_test.go +++ b/routing/delegated_test.go @@ -154,7 +154,6 @@ func TestParserRecursive(t *testing.T) { _, ok := router.(*Composer) require.True(ok) - } func TestParserRecursiveLoop(t *testing.T) { diff --git a/routing/wrapper.go b/routing/wrapper.go index f6a753843..10df177e0 100644 --- a/routing/wrapper.go +++ b/routing/wrapper.go @@ -13,8 +13,10 @@ type ProvideManyRouter interface { routing.Routing } -var _ routing.Routing = &httpRoutingWrapper{} -var _ routinghelpers.ProvideManyRouter = &httpRoutingWrapper{} +var ( + _ routing.Routing = &httpRoutingWrapper{} + _ routinghelpers.ProvideManyRouter = &httpRoutingWrapper{} +) // httpRoutingWrapper is a wrapper needed to construct the routing.Routing interface from // http delegated routing. diff --git a/tar/format.go b/tar/format.go index f3a2d3fb5..626e0982b 100644 --- a/tar/format.go +++ b/tar/format.go @@ -21,8 +21,10 @@ import ( var log = logging.Logger("tarfmt") -var blockSize = 512 -var zeroBlock = make([]byte, blockSize) +var ( + blockSize = 512 + zeroBlock = make([]byte, blockSize) +) func marshalHeader(h *tar.Header) ([]byte, error) { buf := new(bytes.Buffer) @@ -91,7 +93,7 @@ func ImportTar(ctx context.Context, r io.Reader, ds ipld.DAGService) (*dag.Proto } // adds a '-' to the beginning of each path element so we can use 'data' as a -// special link in the structure without having to worry about +// special link in the structure without having to worry about. func escapePath(pth string) string { elems := path.SplitList(strings.Trim(pth, "/")) for i, e := range elems { diff --git a/test/cli/basic_commands_test.go b/test/cli/basic_commands_test.go index 220ef2854..59444332a 100644 --- a/test/cli/basic_commands_test.go +++ b/test/cli/basic_commands_test.go @@ -210,7 +210,6 @@ func TestCommandDocsWidth(t *testing.T) { for _, line := range SplitLines(res) { assert.LessOrEqualf(t, len(line), 80, "expected width %d < 80 for %q", len(line), cmd) } - }) } } @@ -226,7 +225,6 @@ func TestAllCommandsFailWhenPassedBadFlag(t *testing.T) { assert.Equal(t, 1, res.Cmd.ProcessState.ExitCode()) }) } - } func TestCommandsFlags(t *testing.T) { diff --git a/test/cli/content_routing_http_test.go b/test/cli/content_routing_http_test.go index c1ea64d3f..2734e2600 100644 --- a/test/cli/content_routing_http_test.go +++ b/test/cli/content_routing_http_test.go @@ -37,6 +37,7 @@ func (r *fakeHTTPContentRouter) ProvideBitswap(ctx context.Context, req *server. r.provideCalls++ return 0, nil } + func (r *fakeHTTPContentRouter) Provide(ctx context.Context, req *server.WriteProvideRequest) (types.ProviderResponse, error) { r.m.Lock() defer r.m.Unlock() diff --git a/test/cli/dag_test.go b/test/cli/dag_test.go index edcacffae..d17b71cfb 100644 --- a/test/cli/dag_test.go +++ b/test/cli/dag_test.go @@ -101,5 +101,4 @@ func TestDag(t *testing.T) { stat := node.RunIPFS("dag", "stat", "--progress=false", node1Cid, node2Cid) assert.Equal(t, content, stat.Stdout.Bytes()) }) - } diff --git a/test/cli/delegated_routing_http_test.go b/test/cli/delegated_routing_http_test.go index b1ebacd14..c02264f94 100644 --- a/test/cli/delegated_routing_http_test.go +++ b/test/cli/delegated_routing_http_test.go @@ -155,5 +155,4 @@ func TestHTTPDelegatedRouting(t *testing.T) { resp := node.APIClient().Get("/debug/metrics/prometheus") assert.Contains(t, resp.Body, "routing_http_client_length_count") }) - } diff --git a/test/cli/dht_legacy_test.go b/test/cli/dht_legacy_test.go index 5a84b8963..2b90d164c 100644 --- a/test/cli/dht_legacy_test.go +++ b/test/cli/dht_legacy_test.go @@ -107,7 +107,6 @@ func TestLegacyDHT(t *testing.T) { sort.IntSlice(counts).Sort() assert.Equal(t, []int{1, 4}, counts) }) - }) t.Run("dht commands fail when offline", func(t *testing.T) { diff --git a/test/cli/gateway_test.go b/test/cli/gateway_test.go index eb955b593..b2729da3c 100644 --- a/test/cli/gateway_test.go +++ b/test/cli/gateway_test.go @@ -196,9 +196,7 @@ func TestGateway(t *testing.T) { resp.Body, fmt.Sprintf(``, peerID), ) - }) - }) t.Run("GET invalid IPFS path errors", func(t *testing.T) { @@ -583,7 +581,6 @@ func TestGateway(t *testing.T) { assert.Equal(t, test.deserializedGatewayStaticCode, client.Get(deserializedPath, setHost).StatusCode) assert.Equal(t, test.deserializedGatewayStaticCode, client.Get(deserializedPath, withHostAndAccept("application/json")).StatusCode) - } } diff --git a/test/cli/harness/harness.go b/test/cli/harness/harness.go index e68116b5e..067608cdc 100644 --- a/test/cli/harness/harness.go +++ b/test/cli/harness/harness.go @@ -127,11 +127,11 @@ func (h *Harness) WriteFile(filename, contents string) { log.Panicf("%s must be a relative path", filename) } absPath := filepath.Join(h.Runner.Dir, filename) - err := os.MkdirAll(filepath.Dir(absPath), 0777) + err := os.MkdirAll(filepath.Dir(absPath), 0o777) if err != nil { log.Panicf("creating intermediate dirs for %q: %s", filename, err.Error()) } - err = os.WriteFile(absPath, []byte(contents), 0644) + err = os.WriteFile(absPath, []byte(contents), 0o644) if err != nil { log.Panicf("writing %q (%q): %s", filename, absPath, err.Error()) } @@ -166,7 +166,7 @@ func (h *Harness) Mkdirs(paths ...string) { log.Panicf("%s must be a relative path when making dirs", path) } absPath := filepath.Join(h.Runner.Dir, path) - err := os.MkdirAll(absPath, 0777) + err := os.MkdirAll(absPath, 0o777) if err != nil { log.Panicf("recursively making dirs under %s: %s", absPath, err) } diff --git a/test/cli/harness/node.go b/test/cli/harness/node.go index 0516c2b45..9fc01f4d7 100644 --- a/test/cli/harness/node.go +++ b/test/cli/harness/node.go @@ -46,7 +46,7 @@ type Node struct { func BuildNode(ipfsBin, baseDir string, id int) *Node { dir := filepath.Join(baseDir, strconv.Itoa(id)) - if err := os.MkdirAll(dir, 0755); err != nil { + if err := os.MkdirAll(dir, 0o755); err != nil { panic(err) } diff --git a/test/cli/harness/peering.go b/test/cli/harness/peering.go index 13c3430f0..7680eaf57 100644 --- a/test/cli/harness/peering.go +++ b/test/cli/harness/peering.go @@ -26,7 +26,6 @@ func CreatePeerNodes(t *testing.T, n int, peerings []Peering) (*Harness, Nodes) cfg.Routing.Type = config.NewOptionalString("none") cfg.Addresses.Swarm = []string{fmt.Sprintf("/ip4/127.0.0.1/tcp/%d", NewRandPort())} }) - }) for _, peering := range peerings { diff --git a/test/cli/harness/run.go b/test/cli/harness/run.go index 75c07bcc2..bec05fbce 100644 --- a/test/cli/harness/run.go +++ b/test/cli/harness/run.go @@ -14,8 +14,10 @@ type Runner struct { Verbose bool } -type CmdOpt func(*exec.Cmd) -type RunFunc func(*exec.Cmd) error +type ( + CmdOpt func(*exec.Cmd) + RunFunc func(*exec.Cmd) error +) var RunFuncStart = (*exec.Cmd).Start @@ -100,11 +102,9 @@ func (r *Runner) AssertNoError(result *RunResult) { if result.ExitErr != nil { log.Panicf("'%s' returned error, code: %d, err: %s\nstdout:%s\nstderr:%s\n", result.Cmd.Args, result.ExitErr.ExitCode(), result.ExitErr.Error(), result.Stdout.String(), result.Stderr.String()) - } if result.Err != nil { log.Panicf("unable to run %s: %s", result.Cmd.Path, result.Err) - } } diff --git a/test/cli/init_test.go b/test/cli/init_test.go index a45ef05d5..217ec64c3 100644 --- a/test/cli/init_test.go +++ b/test/cli/init_test.go @@ -88,13 +88,12 @@ func TestInit(t *testing.T) { t.Parallel() node := harness.NewT(t).NewNode() badDir := fp.Join(node.Dir, ".badipfs") - err := os.Mkdir(badDir, 0000) + err := os.Mkdir(badDir, 0o000) require.NoError(t, err) res := node.RunIPFS("init", "--repo-dir", badDir) assert.NotEqual(t, 0, res.Cmd.ProcessState.ExitCode()) assert.Contains(t, res.Stderr.String(), "permission denied") - }) t.Run("init with ed25519", func(t *testing.T) { @@ -160,5 +159,4 @@ func TestInit(t *testing.T) { assert.NotEqual(t, 0, res.ExitErr.ExitCode()) assert.Contains(t, res.Stderr.String(), "Error: ipfs daemon is running. please stop it to run this command") }) - } diff --git a/test/cli/pins_test.go b/test/cli/pins_test.go index 14a3dc238..8a36d4695 100644 --- a/test/cli/pins_test.go +++ b/test/cli/pins_test.go @@ -76,7 +76,6 @@ func testPins(t *testing.T, args testPinsArgs) { for _, cid := range cids { assert.Contains(t, verboseVerifyOut, fmt.Sprintf("%s ok", cid)) } - }) t.Run("ls output should contain the cids", func(t *testing.T) { lsOut := ipfsPinLS() @@ -195,7 +194,6 @@ func TestPins(t *testing.T) { testPins(t, testPinsArgs{pinArg: "--progress", lsArg: "--stream"}) testPins(t, testPinsArgs{baseArg: "--cid-base=base32"}) testPins(t, testPinsArgs{lsArg: "--stream", baseArg: "--cid-base=base32"}) - }) t.Run("test pinning with daemon running without network", func(t *testing.T) { diff --git a/test/cli/swarm_test.go b/test/cli/swarm_test.go index 920d310ba..ecb668362 100644 --- a/test/cli/swarm_test.go +++ b/test/cli/swarm_test.go @@ -36,7 +36,6 @@ func TestSwarm(t *testing.T) { err := json.Unmarshal(res.Stdout.Bytes(), &output) assert.NoError(t, err) assert.Equal(t, 0, len(output.Peers)) - }) t.Run("ipfs swarm peers with flag identify outputs expected identify information about connected peers", func(t *testing.T) { t.Parallel() @@ -63,7 +62,6 @@ func TestSwarm(t *testing.T) { assert.Len(t, actualAdresses, 1) assert.Equal(t, expectedAddresses[0], actualAdresses[0]) assert.Greater(t, len(actualProtocols), 0) - }) t.Run("ipfs swarm peers with flag identify outputs Identify field with data that matches calling ipfs id on a peer", func(t *testing.T) { @@ -88,6 +86,5 @@ func TestSwarm(t *testing.T) { assert.Equal(t, outputIdentify.AgentVersion, otherNodeIDOutput.AgentVersion) assert.ElementsMatch(t, outputIdentify.Addresses, otherNodeIDOutput.Addresses) assert.ElementsMatch(t, outputIdentify.Protocols, otherNodeIDOutput.Protocols) - }) } diff --git a/test/cli/testutils/random_files.go b/test/cli/testutils/random_files.go index 0e550a125..c7dca10d6 100644 --- a/test/cli/testutils/random_files.go +++ b/test/cli/testutils/random_files.go @@ -9,8 +9,10 @@ import ( "time" ) -var AlphabetEasy = []rune("abcdefghijklmnopqrstuvwxyz01234567890-_") -var AlphabetHard = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890!@#$%^&*()-_+= ;.,<>'\"[]{}() ") +var ( + AlphabetEasy = []rune("abcdefghijklmnopqrstuvwxyz01234567890-_") + AlphabetHard = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890!@#$%^&*()-_+= ;.,<>'\"[]{}() ") +) type RandFiles struct { Rand *rand.Rand @@ -104,7 +106,7 @@ func (r *RandFiles) WriteRandomDir(root string, depth int) error { n := rand.Intn(r.FilenameSize-4) + 4 name := r.RandomFilename(n) root = path.Join(root, name) - if err := os.MkdirAll(root, 0755); err != nil { + if err := os.MkdirAll(root, 0o755); err != nil { return fmt.Errorf("creating random dir: %w", err) } diff --git a/test/cli/tracing_test.go b/test/cli/tracing_test.go index ef717716e..6f19759be 100644 --- a/test/cli/tracing_test.go +++ b/test/cli/tracing_test.go @@ -45,7 +45,7 @@ func TestTracing(t *testing.T) { // touch traces.json and give it 777 perms in case Docker runs as a different user node.WriteBytes("traces.json", nil) - err := os.Chmod(filepath.Join(node.Dir, "traces.json"), 0777) + err := os.Chmod(filepath.Join(node.Dir, "traces.json"), 0o777) require.NoError(t, err) dockerBin, err := exec.LookPath("docker") diff --git a/test/cli/transports_test.go b/test/cli/transports_test.go index 73f08c2e5..d37c78aad 100644 --- a/test/cli/transports_test.go +++ b/test/cli/transports_test.go @@ -32,7 +32,7 @@ func TestTransports(t *testing.T) { } checkRandomDir := func(nodes harness.Nodes) { randDir := filepath.Join(nodes[0].Dir, "foobar") - require.NoError(t, os.Mkdir(randDir, 0777)) + require.NoError(t, os.Mkdir(randDir, 0o777)) rf := testutils.NewRandFiles() rf.FanoutDirs = 3 rf.FanoutFiles = 6 @@ -148,5 +148,4 @@ func TestTransports(t *testing.T) { nodes.StartDaemons().Connect() runTests(nodes) }) - } diff --git a/test/dependencies/iptb/iptb.go b/test/dependencies/iptb/iptb.go index e3668c0a1..3344c656b 100644 --- a/test/dependencies/iptb/iptb.go +++ b/test/dependencies/iptb/iptb.go @@ -19,7 +19,6 @@ func init() { PluginName: plugin.PluginName, BuiltIn: true, }, false) - if err != nil { panic(err) } diff --git a/test/dependencies/ma-pipe-unidir/main.go b/test/dependencies/ma-pipe-unidir/main.go index 5fdd3e09e..f8a2e32dc 100644 --- a/test/dependencies/ma-pipe-unidir/main.go +++ b/test/dependencies/ma-pipe-unidir/main.go @@ -57,7 +57,7 @@ func app() int { if len(opts.PidFile) > 0 { data := []byte(strconv.Itoa(os.Getpid())) - err := os.WriteFile(opts.PidFile, data, 0644) + err := os.WriteFile(opts.PidFile, data, 0o644) if err != nil { return 1 } @@ -78,7 +78,7 @@ func app() int { if len(opts.PidFile) > 0 { data := []byte(strconv.Itoa(os.Getpid())) - err := os.WriteFile(opts.PidFile, data, 0644) + err := os.WriteFile(opts.PidFile, data, 0o644) if err != nil { return 1 } diff --git a/test/integration/bench_test.go b/test/integration/bench_test.go index b702bae03..c269eddad 100644 --- a/test/integration/bench_test.go +++ b/test/integration/bench_test.go @@ -8,7 +8,6 @@ import ( ) func benchmarkAddCat(numBytes int64, conf testutil.LatencyConfig, b *testing.B) { - b.StopTimer() b.SetBytes(numBytes) data := RandomBytes(numBytes) // we don't want to measure the time it takes to generate this data diff --git a/test/integration/wan_lan_dht_test.go b/test/integration/wan_lan_dht_test.go index 58558de33..7c70aa98f 100644 --- a/test/integration/wan_lan_dht_test.go +++ b/test/integration/wan_lan_dht_test.go @@ -51,8 +51,10 @@ func TestDHTConnectivitySlowRouting(t *testing.T) { } // wan prefix must have a real corresponding ASN for the peer diversity filter to work. -var wanPrefix = net.ParseIP("2001:218:3004::") -var lanPrefix = net.ParseIP("fe80::") +var ( + wanPrefix = net.ParseIP("2001:218:3004::") + lanPrefix = net.ParseIP("fe80::") +) func makeAddr(n uint32, wan bool) ma.Multiaddr { var ip net.IP diff --git a/thirdparty/dir/dir.go b/thirdparty/dir/dir.go index 1549cc80b..5aa93c329 100644 --- a/thirdparty/dir/dir.go +++ b/thirdparty/dir/dir.go @@ -8,7 +8,7 @@ import ( "path/filepath" ) -// Writable ensures the directory exists and is writable +// Writable ensures the directory exists and is writable. func Writable(path string) error { // Construct the path if missing if err := os.MkdirAll(path, os.ModePerm); err != nil { diff --git a/thirdparty/notifier/notifier_test.go b/thirdparty/notifier/notifier_test.go index 9b9692ef1..401b3b02a 100644 --- a/thirdparty/notifier/notifier_test.go +++ b/thirdparty/notifier/notifier_test.go @@ -7,7 +7,7 @@ import ( "time" ) -// test data structures +// test data structures. type Router struct { queue chan Packet notifier Notifier @@ -36,7 +36,6 @@ func (r *Router) notifyAll(notify func(n RouterNotifiee)) { } func (r *Router) Receive(p Packet) { - select { case r.queue <- p: // enqueued r.notifyAll(func(n RouterNotifiee) { @@ -100,7 +99,6 @@ func (m *Metrics) String() string { } func TestNotifies(t *testing.T) { - m := Metrics{received: make(chan struct{})} r := Router{queue: make(chan Packet, 10)} r.Notify(&m) diff --git a/thirdparty/unit/unit.go b/thirdparty/unit/unit.go index feeaa42bb..3b10db44c 100644 --- a/thirdparty/unit/unit.go +++ b/thirdparty/unit/unit.go @@ -15,11 +15,10 @@ const ( ) func (i Information) String() string { - tmp := int64(i) // default - var d = tmp + d := tmp symbol := "B" switch { diff --git a/version.go b/version.go index 265ec937e..5eb0e2981 100644 --- a/version.go +++ b/version.go @@ -7,10 +7,10 @@ import ( "github.com/ipfs/kubo/repo/fsrepo" ) -// CurrentCommit is the current git commit, this is set as a ldflag in the Makefile +// CurrentCommit is the current git commit, this is set as a ldflag in the Makefile. var CurrentCommit string -// CurrentVersionNumber is the current application's version literal +// CurrentVersionNumber is the current application's version literal. const CurrentVersionNumber = "0.23.0-dev" const ApiVersion = "/kubo/" + CurrentVersionNumber + "/" //nolint @@ -48,7 +48,7 @@ func GetVersionInfo() *VersionInfo { Version: CurrentVersionNumber, Commit: CurrentCommit, Repo: fmt.Sprint(fsrepo.RepoVersion), - System: runtime.GOARCH + "/" + runtime.GOOS, //TODO: Precise version here + System: runtime.GOARCH + "/" + runtime.GOOS, // TODO: Precise version here Golang: runtime.Version(), } } From cc79eeb91ce63631d6c772cc0af6c361c03b38d4 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Thu, 17 Aug 2023 14:15:42 +0200 Subject: [PATCH 0821/1212] style: remove commented imports [skip changelog] --- core/commands/dag/dag.go | 3 --- repo/fsrepo/migrations/fetch.go | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/core/commands/dag/dag.go b/core/commands/dag/dag.go index ac6f25d7d..649142fd0 100644 --- a/core/commands/dag/dag.go +++ b/core/commands/dag/dag.go @@ -13,9 +13,6 @@ import ( cid "github.com/ipfs/go-cid" cidenc "github.com/ipfs/go-cidutil/cidenc" cmds "github.com/ipfs/go-ipfs-cmds" - // gipfree "github.com/ipld/go-ipld-prime/impl/free" - // gipselector "github.com/ipld/go-ipld-prime/traversal/selector" - // gipselectorbuilder "github.com/ipld/go-ipld-prime/traversal/selector/builder" ) const ( diff --git a/repo/fsrepo/migrations/fetch.go b/repo/fsrepo/migrations/fetch.go index 60081210f..ee1deefa0 100644 --- a/repo/fsrepo/migrations/fetch.go +++ b/repo/fsrepo/migrations/fetch.go @@ -184,7 +184,7 @@ func osWithVariant() (string, error) { // "go-ipfs_v0.8.0-rc2_linux-amd64.tar.gz" // // This would form the path: -// go-ipfs/v0.8.0/go-ipfs_v0.8.0_linux-amd64.tar.gz. +// go-ipfs/v0.8.0/go-ipfs_v0.8.0_linux-amd64.tar.gz func makeArchivePath(dist, name, ver, atype string) (string, string) { arcName := fmt.Sprintf("%s_%s_%s-%s.%s", name, ver, runtime.GOOS, runtime.GOARCH, atype) return fmt.Sprintf("%s/%s/%s", dist, ver, arcName), arcName From ced348366c13c841c93ec5734732e5789cba4cbb Mon Sep 17 00:00:00 2001 From: Amir Mohammad Fakhimi <79265203+AmirMohammadFakhimi@users.noreply.github.com> Date: Thu, 17 Aug 2023 18:13:27 +0330 Subject: [PATCH 0822/1212] feat: add zsh completions (#10040) Co-authored-by: Henrique Dias --- .github/workflows/gotest.yml | 2 ++ core/commands/commands.go | 29 ++++++++++++++++++++++++++++- core/commands/commands_test.go | 2 ++ core/commands/completion.go | 29 ++++++++++++++++++++++++++++- docs/command-completion.md | 13 +++++++++++++ test/cli/completion_test.go | 26 ++++++++++++++++++++++++++ 6 files changed, 99 insertions(+), 2 deletions(-) diff --git a/.github/workflows/gotest.yml b/.github/workflows/gotest.yml index 08a741532..630160fbb 100644 --- a/.github/workflows/gotest.yml +++ b/.github/workflows/gotest.yml @@ -35,6 +35,8 @@ jobs: go-version: 1.19.x - name: Check out Kubo uses: actions/checkout@v3 + - name: Install missing tools + run: sudo apt update && sudo apt install -y zsh - name: Restore Go cache uses: protocol/cache-go-action@v1 with: diff --git a/core/commands/commands.go b/core/commands/commands.go index 794e1a592..249f0ffbe 100644 --- a/core/commands/commands.go +++ b/core/commands/commands.go @@ -13,7 +13,7 @@ import ( "sort" "strings" - "github.com/ipfs/go-ipfs-cmds" + cmds "github.com/ipfs/go-ipfs-cmds" ) type commandEncoder struct { @@ -169,6 +169,33 @@ To install the completions permanently, they can be moved to return res.Emit(&buf) }, }, + "zsh": { + Helptext: cmds.HelpText{ + Tagline: "Generate zsh shell completions.", + ShortDescription: "Generates command completions for the zsh shell.", + LongDescription: ` +Generates command completions for the zsh shell. + +The simplest way to see it working is write the completions +to a file and then source it: + + > ipfs commands completion zsh > ipfs-completion.zsh + > source ./ipfs-completion.zsh + +To install the completions permanently, they can be moved to +/etc/zsh/completions or sourced from your ~/.zshrc file. +`, + }, + NoRemote: true, + Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { + var buf bytes.Buffer + if err := writeZshCompletions(root, &buf); err != nil { + return err + } + res.SetLength(uint64(buf.Len())) + return res.Emit(&buf) + }, + }, "fish": { Helptext: cmds.HelpText{ Tagline: "Generate fish shell completions.", diff --git a/core/commands/commands_test.go b/core/commands/commands_test.go index 0f2b0721b..a73a0338e 100644 --- a/core/commands/commands_test.go +++ b/core/commands/commands_test.go @@ -25,6 +25,7 @@ func TestROCommands(t *testing.T) { "/commands/completion", "/commands/completion/bash", "/commands/completion/fish", + "/commands/completion/zsh", "/dag", "/dag/get", "/dag/resolve", @@ -102,6 +103,7 @@ func TestCommands(t *testing.T) { "/commands/completion", "/commands/completion/bash", "/commands/completion/fish", + "/commands/completion/zsh", "/config", "/config/edit", "/config/profile", diff --git a/core/commands/completion.go b/core/commands/completion.go index 8babaac36..2f5b8b61e 100644 --- a/core/commands/completion.go +++ b/core/commands/completion.go @@ -83,7 +83,7 @@ func commandToCompletions(name string, fullName string, cmd *cmds.Command) *comp return parsed } -var bashCompletionTemplate, fishCompletionTemplate *template.Template +var bashCompletionTemplate, fishCompletionTemplate, zshCompletionTemplate *template.Template func init() { commandTemplate := template.Must(template.New("command").Parse(` @@ -153,6 +153,28 @@ _ipfs() { {{ template "command" . }} } complete -o nosort -o nospace -o default -F _ipfs ipfs +`)) + + zshCompletionTemplate = template.Must(commandTemplate.New("root").Parse(`#!bin/zsh +autoload bashcompinit +bashcompinit +_ipfs_compgen() { +local oldifs="$IFS" +IFS=$'\n' +while read -r line; do + COMPREPLY+=("$line") +done < <(compgen "$@") +IFS="$oldifs" +} + +_ipfs() { +COMPREPLY=() +local index=1 +local argidx=0 +local word="${COMP_WORDS[COMP_CWORD]}" +{{ template "command" . }} +} +complete -o nosort -o nospace -o default -F _ipfs ipfs `)) fishCommandTemplate := template.Must(template.New("command").Parse(` @@ -221,3 +243,8 @@ func writeFishCompletions(cmd *cmds.Command, out io.Writer) error { cmds := commandToCompletions("ipfs", "", cmd) return fishCompletionTemplate.Execute(out, cmds) } + +func writeZshCompletions(cmd *cmds.Command, out io.Writer) error { + cmds := commandToCompletions("ipfs", "", cmd) + return zshCompletionTemplate.Execute(out, cmds) +} diff --git a/docs/command-completion.md b/docs/command-completion.md index b84483e61..207f611bf 100644 --- a/docs/command-completion.md +++ b/docs/command-completion.md @@ -24,3 +24,16 @@ The simplest way to use the completions logic: To install the completions permanently, they can be moved to `/etc/fish/completions` or `~/.config/fish/completions` or sourced from your `~/.config/fish/config.fish` file. + +## ZSH + +The zsh shell is also supported: + +The simplest way to "eval" the completions logic: + +```bash +> eval "$(ipfs commands completion zsh)" +``` + +To install the completions permanently, they can be moved to +`/etc/bash_completion.d` or sourced from your `~/.zshrc` file. diff --git a/test/cli/completion_test.go b/test/cli/completion_test.go index 0c40eb02b..548cb17a2 100644 --- a/test/cli/completion_test.go +++ b/test/cli/completion_test.go @@ -29,3 +29,29 @@ func TestBashCompletion(t *testing.T) { assert.NoError(t, res.Err) }) } + +func TestZshCompletion(t *testing.T) { + t.Parallel() + h := harness.NewT(t) + node := h.NewNode() + + res := node.IPFS("commands", "completion", "zsh") + + length := len(res.Stdout.String()) + if length < 100 { + t.Fatalf("expected a long Bash completion file, but got one of length %d", length) + } + + t.Run("completion file can be loaded in bash", func(t *testing.T) { + RequiresLinux(t) + + completionFile := h.WriteToTemp(res.Stdout.String()) + res = h.Runner.Run(harness.RunRequest{ + Path: "zsh", + Args: []string{"-c", fmt.Sprintf("autoload -Uz compinit && compinit && source %s && echo -E $_comps[ipfs]", completionFile)}, + }) + + assert.NoError(t, res.Err) + assert.NotEmpty(t, res.Stdout.String()) + }) +} From 733b01a37b6da42ca46b6606a8c12f76e6cc50ed Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Fri, 18 Aug 2023 08:54:08 +0200 Subject: [PATCH 0823/1212] fix(gw): useful IPIP-402 CARs on not found errors (#10084) Co-authored-by: Henrique Dias --- docs/changelogs/v0.23.md | 11 +++++++++++ docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- test/cli/gateway_test.go | 2 +- test/dependencies/go.mod | 2 +- test/dependencies/go.sum | 4 ++-- 8 files changed, 21 insertions(+), 10 deletions(-) diff --git a/docs/changelogs/v0.23.md b/docs/changelogs/v0.23.md index a53639d88..641f20f8b 100644 --- a/docs/changelogs/v0.23.md +++ b/docs/changelogs/v0.23.md @@ -7,6 +7,7 @@ - [Overview](#overview) - [🔦 Highlights](#-highlights) - [Mplex deprecation](#mplex-deprecation) + - [Gateway: meaningful CAR responses on Not Found errors](#gateway-meaningful-car-responses-on-not-found-errors) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -32,6 +33,16 @@ $ ipfs config --json Swarm.Transports.Multiplexers.Mplex 200 We will completely remove Mplex in v0.24 as it makes protocols very bad to implement, if you are in this situation you need to add yamux support to your other implementation. +#### Gateway: meaningful CAR responses on Not Found errors + +When requesting a CAR from the gateway, the root of the CAR might no longer be +meaningful. By default, the CAR root will be the last resolvable segment of the +path. However, in situations where the path cannot be resolved, such as when +the path does not exist, a CAR will be sent with a root of `bafkqaaa` (empty CID). + +This CAR will contain all blocks necessary to validate that the path does not +exist without having to trust the gateway. + ### 📝 Changelog ### 👨‍👩‍👧‍👦 Contributors diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index c0806d180..9d79aa782 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.18 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.11.1-0.20230817061817-1d2f5e511e9f + github.com/ipfs/boxo v0.11.1-0.20230818062747-654231b2bda3 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.29.2 github.com/multiformats/go-multiaddr v0.10.1 diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 710497500..acfc47fcb 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -301,8 +301,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.11.1-0.20230817061817-1d2f5e511e9f h1:sXqGLIATCsBdHse7S9n6e328NhORvVM64+4IRuFlpmI= -github.com/ipfs/boxo v0.11.1-0.20230817061817-1d2f5e511e9f/go.mod h1:8IfDmp+FzFGcF4zjAgHMVPpwYw4AjN9ePEzDfkaYJ1w= +github.com/ipfs/boxo v0.11.1-0.20230818062747-654231b2bda3 h1:oiMqmivloEHtlCkS+8rCq1Pkz/rf6m3sC45lL4cnwBA= +github.com/ipfs/boxo v0.11.1-0.20230818062747-654231b2bda3/go.mod h1:8IfDmp+FzFGcF4zjAgHMVPpwYw4AjN9ePEzDfkaYJ1w= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= diff --git a/go.mod b/go.mod index f6d60148b..638513c7b 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( github.com/fsnotify/fsnotify v1.6.0 github.com/google/uuid v1.3.0 github.com/hashicorp/go-multierror v1.1.1 - github.com/ipfs/boxo v0.11.1-0.20230817061817-1d2f5e511e9f + github.com/ipfs/boxo v0.11.1-0.20230818062747-654231b2bda3 github.com/ipfs/go-block-format v0.1.2 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 diff --git a/go.sum b/go.sum index 083a052ca..7dac8bc22 100644 --- a/go.sum +++ b/go.sum @@ -337,8 +337,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.11.1-0.20230817061817-1d2f5e511e9f h1:sXqGLIATCsBdHse7S9n6e328NhORvVM64+4IRuFlpmI= -github.com/ipfs/boxo v0.11.1-0.20230817061817-1d2f5e511e9f/go.mod h1:8IfDmp+FzFGcF4zjAgHMVPpwYw4AjN9ePEzDfkaYJ1w= +github.com/ipfs/boxo v0.11.1-0.20230818062747-654231b2bda3 h1:oiMqmivloEHtlCkS+8rCq1Pkz/rf6m3sC45lL4cnwBA= +github.com/ipfs/boxo v0.11.1-0.20230818062747-654231b2bda3/go.mod h1:8IfDmp+FzFGcF4zjAgHMVPpwYw4AjN9ePEzDfkaYJ1w= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= diff --git a/test/cli/gateway_test.go b/test/cli/gateway_test.go index b2729da3c..168acfdb9 100644 --- a/test/cli/gateway_test.go +++ b/test/cli/gateway_test.go @@ -487,7 +487,7 @@ func TestGateway(t *testing.T) { t.Run("not present key from node 1", func(t *testing.T) { t.Parallel() - assert.Equal(t, 404, node1.GatewayClient().Get("/ipfs/"+cidFoo).StatusCode) + assert.Equal(t, 500, node1.GatewayClient().Get("/ipfs/"+cidFoo).StatusCode) }) t.Run("not present IPNS key from node 1", func(t *testing.T) { diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index fb8b087ad..ed17f6ad8 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -7,7 +7,7 @@ replace github.com/ipfs/kubo => ../../ require ( github.com/Kubuxu/gocovmerge v0.0.0-20161216165753-7ecaa51963cd github.com/golangci/golangci-lint v1.49.0 - github.com/ipfs/boxo v0.11.1-0.20230817061817-1d2f5e511e9f + github.com/ipfs/boxo v0.11.1-0.20230818062747-654231b2bda3 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 github.com/ipfs/go-datastore v0.6.0 diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 3fbd086a5..8e943ec0b 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -395,8 +395,8 @@ github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NH github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.11.1-0.20230817061817-1d2f5e511e9f h1:sXqGLIATCsBdHse7S9n6e328NhORvVM64+4IRuFlpmI= -github.com/ipfs/boxo v0.11.1-0.20230817061817-1d2f5e511e9f/go.mod h1:8IfDmp+FzFGcF4zjAgHMVPpwYw4AjN9ePEzDfkaYJ1w= +github.com/ipfs/boxo v0.11.1-0.20230818062747-654231b2bda3 h1:oiMqmivloEHtlCkS+8rCq1Pkz/rf6m3sC45lL4cnwBA= +github.com/ipfs/boxo v0.11.1-0.20230818062747-654231b2bda3/go.mod h1:8IfDmp+FzFGcF4zjAgHMVPpwYw4AjN9ePEzDfkaYJ1w= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.1.2 h1:GAjkfhVx1f4YTODS6Esrj1wt2HhrtwTnhEr+DyPUaJo= From 535d35e161db08b5c12c5243a8363206437b2679 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Fri, 18 Aug 2023 09:34:42 +0200 Subject: [PATCH 0824/1212] chore: restore exec perms for t0116-gateway-cache.sh and fixtures (#10085) --- test/sharness/t0116-gateway-cache.sh | 8 +++- test/sharness/t0116-gateway-cache/README.md | 39 ++++++++++++++++++ .../sharness/t0116-gateway-cache/fixtures.car | Bin 0 -> 468 bytes ...p32iwm9pdt9nq3y5rpn3ln9j12zfhe.ipns-record | Bin 0 -> 394 bytes 4 files changed, 46 insertions(+), 1 deletion(-) mode change 100644 => 100755 test/sharness/t0116-gateway-cache.sh create mode 100644 test/sharness/t0116-gateway-cache/README.md create mode 100644 test/sharness/t0116-gateway-cache/fixtures.car create mode 100644 test/sharness/t0116-gateway-cache/k51qzi5uqu5dlxdsdu5fpuu7h69wu4ohp32iwm9pdt9nq3y5rpn3ln9j12zfhe.ipns-record diff --git a/test/sharness/t0116-gateway-cache.sh b/test/sharness/t0116-gateway-cache.sh old mode 100644 new mode 100755 index 0986ffa41..6dd81657c --- a/test/sharness/t0116-gateway-cache.sh +++ b/test/sharness/t0116-gateway-cache.sh @@ -39,8 +39,14 @@ test_expect_success "Add the test directory" ' ipfs routing put --allow-offline /ipns/${TEST_IPNS_ID} ../t0116-gateway-cache/${TEST_IPNS_ID}.ipns-record ' - # Etag + test_expect_success "GET for /ipfs/ unixfs dir listing succeeds" ' + curl -svX GET "http://127.0.0.1:$GWAY_PORT/ipfs/$ROOT1_CID/root2/root3/" >/dev/null 2>curl_ipfs_dir_listing_output + ' + + test_expect_success "GET for /ipns/ unixfs dir listing succeeds" ' + curl -svX GET "http://127.0.0.1:$GWAY_PORT/ipns/$TEST_IPNS_ID/root2/root3/" >/dev/null 2>curl_ipns_dir_listing_output + ' ## dir generated listing test_expect_success "GET /ipfs/ dir response has special Etag for generated dir listing" ' diff --git a/test/sharness/t0116-gateway-cache/README.md b/test/sharness/t0116-gateway-cache/README.md new file mode 100644 index 000000000..1be92f454 --- /dev/null +++ b/test/sharness/t0116-gateway-cache/README.md @@ -0,0 +1,39 @@ +# Dataset description/sources + +- fixtures.car + - raw CARv1 + +generated with: + +```sh +# using ipfs version 0.21.0-dev (03a98280e3e642774776cd3d0435ab53e5dfa867) + +mkdir -p root2/root3/root4 && +echo "hello" > root2/root3/root4/index.html && +ROOT1_CID=$(ipfs add -Qrw --cid-version 1 root2) +ROOT2_CID=$(ipfs resolve -r /ipfs/$ROOT1_CID/root2 | cut -d "/" -f3) +ROOT3_CID=$(ipfs resolve -r /ipfs/$ROOT1_CID/root2/root3 | cut -d "/" -f3) +ROOT4_CID=$(ipfs resolve -r /ipfs/$ROOT1_CID/root2/root3/root4 | cut -d "/" -f3) +FILE_CID=$(ipfs resolve -r /ipfs/$ROOT1_CID/root2/root3/root4/index.html | cut -d "/" -f3) + +TEST_IPNS_ID=$(ipfs key gen --ipns-base=base36 --type=ed25519 cache_test_key | head -n1 | tr -d "\n") +# publish a record valid for a 100 years +ipfs name publish --key cache_test_key --allow-offline -Q --ttl=876600h --lifetime=876600h "/ipfs/$ROOT1_CID" +ipfs routing get /ipns/${TEST_IPNS_ID} > ${TEST_IPNS_ID}.ipns-record + +echo ROOT1_CID=${ROOT1_CID} # ./ +echo ROOT2_CID=${ROOT2_CID} # ./root2 +echo ROOT3_CID=${ROOT3_CID} # ./root2/root3 +echo ROOT4_CID=${ROOT4_CID} # ./root2/root3/root4 +echo FILE_CID=${FILE_CID} # ./root2/root3/root4/index.html +echo TEST_IPNS_ID=${TEST_IPNS_ID} + +ipfs dag export ${ROOT1_CID} > ./fixtures.car + +# ROOT1_CID=bafybeib3ffl2teiqdncv3mkz4r23b5ctrwkzrrhctdbne6iboayxuxk5ui # ./ +# ROOT2_CID=bafybeih2w7hjocxjg6g2ku25hvmd53zj7og4txpby3vsusfefw5rrg5sii # ./root2 +# ROOT3_CID=bafybeiawdvhmjcz65x5egzx4iukxc72hg4woks6v6fvgyupiyt3oczk5ja # ./root2/root3 +# ROOT4_CID=bafybeifq2rzpqnqrsdupncmkmhs3ckxxjhuvdcbvydkgvch3ms24k5lo7q # ./root2/root3/root4 +# FILE_CID=bafkreicysg23kiwv34eg2d7qweipxwosdo2py4ldv42nbauguluen5v6am # ./root2/root3/root4/index.html +# TEST_IPNS_ID=k51qzi5uqu5dlxdsdu5fpuu7h69wu4ohp32iwm9pdt9nq3y5rpn3ln9j12zfhe +``` diff --git a/test/sharness/t0116-gateway-cache/fixtures.car b/test/sharness/t0116-gateway-cache/fixtures.car new file mode 100644 index 0000000000000000000000000000000000000000..43e570e1d6acb0a03531b47feb540318f5027204 GIT binary patch literal 468 zcmcColvx?P5~W2SVzij7-;r*+x4)dz{ z2?vnLaUeGn)L{a2bEuF)#Kf&zm9F0B$mRdAQQ-H@OVV5Z6eh1XxzN*OUp4TNzE)w$xALX&dsheDKaunGEFWiD$lMeD#}PM zNlD5}HOoxOPpqsct;jYl%@lIj#Aa`PX!4XzpKmQY)6e$9U7<`kzNU$F%{D)#mwVMZ z{GZ-h%zgj3z3+a9thHt*l@~txHDQw3!_thyQ+_E$H*2s|5P0dSAWyk;;nVFJVQW=5IUpX*UA(aKG3;+eR BnWX># literal 0 HcmV?d00001 From af2bdf1e00bdcdf8f545d8de287c84dfc3ecce5b Mon Sep 17 00:00:00 2001 From: Jorropo Date: Fri, 18 Aug 2023 20:16:35 +0200 Subject: [PATCH 0825/1212] docker: bump debian version to bookworm --- Dockerfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index acdb70b31..2093688cd 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM --platform=${BUILDPLATFORM:-linux/amd64} golang:1.19-buster AS builder +FROM --platform=${BUILDPLATFORM:-linux/amd64} golang:1.19-bookworm AS builder ARG TARGETPLATFORM TARGETOS TARGETARCH @@ -24,7 +24,7 @@ RUN cd $SRC_DIR \ # Using Debian Buster because the version of busybox we're using is based on it # and we want to make sure the libraries we're using are compatible. That's also # why we're running this for the target platform. -FROM debian:buster-slim AS utilities +FROM debian:bookworm-slim AS utilities RUN set -eux; \ apt-get update; \ apt-get install -y \ @@ -44,7 +44,7 @@ RUN set -eux; \ rm -rf /var/lib/apt/lists/* # Now comes the actual target image, which aims to be as small as possible. -FROM busybox:1.31.1-glibc +FROM busybox:1.36.1-glibc # Get the ipfs binary, entrypoint script, and TLS CAs from the build container. ENV SRC_DIR /kubo From b3e8ddf717692cc43fd86fc47be5148e1a64c583 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Sat, 19 Aug 2023 00:44:21 +0200 Subject: [PATCH 0826/1212] docker: change to releases that follow debian's updates --- Dockerfile | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/Dockerfile b/Dockerfile index 2093688cd..73597b3cb 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ -FROM --platform=${BUILDPLATFORM:-linux/amd64} golang:1.19-bookworm AS builder +FROM --platform=${BUILDPLATFORM:-linux/amd64} golang:1.19 AS builder -ARG TARGETPLATFORM TARGETOS TARGETARCH +ARG TARGETOS TARGETARCH ENV SRC_DIR /kubo @@ -19,12 +19,12 @@ ARG IPFS_PLUGINS # Also: fix getting HEAD commit hash via git rev-parse. RUN cd $SRC_DIR \ && mkdir -p .git/objects \ - && GOOS=$TARGETOS GOARCH=$TARGETARCH GOFLAGS=-buildvcs=false make build GOTAGS=openssl IPFS_PLUGINS=$IPFS_PLUGINS + && GOOS=$TARGETOS GOARCH=$TARGETARCH GOFLAGS=-buildvcs=false make build IPFS_PLUGINS=$IPFS_PLUGINS # Using Debian Buster because the version of busybox we're using is based on it # and we want to make sure the libraries we're using are compatible. That's also # why we're running this for the target platform. -FROM debian:bookworm-slim AS utilities +FROM debian:stable-slim AS utilities RUN set -eux; \ apt-get update; \ apt-get install -y \ @@ -37,14 +37,11 @@ RUN set -eux; \ # This installs fusermount which we later copy over to the target image. fuse \ ca-certificates \ - # This installs libssl.so and libcrypto.so which we later copy over to the - # target image. We need these to be able to use the OpenSSL plugin. - libssl-dev \ ; \ rm -rf /var/lib/apt/lists/* # Now comes the actual target image, which aims to be as small as possible. -FROM busybox:1.36.1-glibc +FROM busybox:stable-glibc # Get the ipfs binary, entrypoint script, and TLS CAs from the build container. ENV SRC_DIR /kubo @@ -62,13 +59,6 @@ RUN chmod 4755 /usr/local/bin/fusermount # Fix permissions on start_ipfs (ignore the build machine's permissions) RUN chmod 0755 /usr/local/bin/start_ipfs -# This shared lib (part of glibc) doesn't seem to be included with busybox. -COPY --from=utilities /lib/*-linux-gnu*/libdl.so.2 /lib/ - -# Copy over SSL libraries. -COPY --from=utilities /usr/lib/*-linux-gnu*/libssl.so* /usr/lib/ -COPY --from=utilities /usr/lib/*-linux-gnu*/libcrypto.so* /usr/lib/ - # Swarm TCP; should be exposed to the public EXPOSE 4001 # Swarm UDP; should be exposed to the public From 334308f532243a1a3f4ff5ab1a988c4a76b5891e Mon Sep 17 00:00:00 2001 From: Jorropo Date: Mon, 21 Aug 2023 10:01:00 +0200 Subject: [PATCH 0827/1212] style: run gofumpt This commit was moved from ipfs/boxo@c5a805eed56de5df9c8a220a4ce72b7bc3a0ae38 --- core/coreiface/options/block.go | 7 ++++--- core/coreiface/options/dht.go | 6 ++++-- core/coreiface/options/key.go | 6 ++++-- core/coreiface/options/name.go | 6 ++++-- core/coreiface/options/object.go | 8 +++++--- core/coreiface/options/pubsub.go | 6 ++++-- core/coreiface/options/unixfs.go | 6 ++++-- core/coreiface/tests/dag.go | 16 +++++++--------- core/coreiface/tests/name.go | 2 +- core/coreiface/tests/object.go | 2 +- core/coreiface/tests/unixfs.go | 8 +++++--- 11 files changed, 43 insertions(+), 30 deletions(-) diff --git a/core/coreiface/options/block.go b/core/coreiface/options/block.go index 130648682..83a43702c 100644 --- a/core/coreiface/options/block.go +++ b/core/coreiface/options/block.go @@ -17,8 +17,10 @@ type BlockRmSettings struct { Force bool } -type BlockPutOption func(*BlockPutSettings) error -type BlockRmOption func(*BlockRmSettings) error +type ( + BlockPutOption func(*BlockPutSettings) error + BlockRmOption func(*BlockRmSettings) error +) func BlockPutOptions(opts ...BlockPutOption) (*BlockPutSettings, error) { var cidPrefix cid.Prefix @@ -131,7 +133,6 @@ func (blockOpts) Format(format string) BlockPutOption { return nil } - } // Hash is an option for Block.Put which specifies the multihash settings to use diff --git a/core/coreiface/options/dht.go b/core/coreiface/options/dht.go index e13e16020..b43bf3e7a 100644 --- a/core/coreiface/options/dht.go +++ b/core/coreiface/options/dht.go @@ -8,8 +8,10 @@ type DhtFindProvidersSettings struct { NumProviders int } -type DhtProvideOption func(*DhtProvideSettings) error -type DhtFindProvidersOption func(*DhtFindProvidersSettings) error +type ( + DhtProvideOption func(*DhtProvideSettings) error + DhtFindProvidersOption func(*DhtFindProvidersSettings) error +) func DhtProvideOptions(opts ...DhtProvideOption) (*DhtProvideSettings, error) { options := &DhtProvideSettings{ diff --git a/core/coreiface/options/key.go b/core/coreiface/options/key.go index 4bc53a65f..ebff6d5a7 100644 --- a/core/coreiface/options/key.go +++ b/core/coreiface/options/key.go @@ -16,8 +16,10 @@ type KeyRenameSettings struct { Force bool } -type KeyGenerateOption func(*KeyGenerateSettings) error -type KeyRenameOption func(*KeyRenameSettings) error +type ( + KeyGenerateOption func(*KeyGenerateSettings) error + KeyRenameOption func(*KeyRenameSettings) error +) func KeyGenerateOptions(opts ...KeyGenerateOption) (*KeyGenerateSettings, error) { options := &KeyGenerateSettings{ diff --git a/core/coreiface/options/name.go b/core/coreiface/options/name.go index 8e9b5183d..35e78c394 100644 --- a/core/coreiface/options/name.go +++ b/core/coreiface/options/name.go @@ -24,8 +24,10 @@ type NameResolveSettings struct { ResolveOpts []ropts.ResolveOpt } -type NamePublishOption func(*NamePublishSettings) error -type NameResolveOption func(*NameResolveSettings) error +type ( + NamePublishOption func(*NamePublishSettings) error + NameResolveOption func(*NameResolveSettings) error +) func NamePublishOptions(opts ...NamePublishOption) (*NamePublishSettings, error) { options := &NamePublishSettings{ diff --git a/core/coreiface/options/object.go b/core/coreiface/options/object.go index e484a9f36..b5625a1d6 100644 --- a/core/coreiface/options/object.go +++ b/core/coreiface/options/object.go @@ -14,9 +14,11 @@ type ObjectAddLinkSettings struct { Create bool } -type ObjectNewOption func(*ObjectNewSettings) error -type ObjectPutOption func(*ObjectPutSettings) error -type ObjectAddLinkOption func(*ObjectAddLinkSettings) error +type ( + ObjectNewOption func(*ObjectNewSettings) error + ObjectPutOption func(*ObjectPutSettings) error + ObjectAddLinkOption func(*ObjectAddLinkSettings) error +) func ObjectNewOptions(opts ...ObjectNewOption) (*ObjectNewSettings, error) { options := &ObjectNewSettings{ diff --git a/core/coreiface/options/pubsub.go b/core/coreiface/options/pubsub.go index c387d613d..839ef97b1 100644 --- a/core/coreiface/options/pubsub.go +++ b/core/coreiface/options/pubsub.go @@ -8,8 +8,10 @@ type PubSubSubscribeSettings struct { Discover bool } -type PubSubPeersOption func(*PubSubPeersSettings) error -type PubSubSubscribeOption func(*PubSubSubscribeSettings) error +type ( + PubSubPeersOption func(*PubSubPeersSettings) error + PubSubSubscribeOption func(*PubSubSubscribeSettings) error +) func PubSubPeersOptions(opts ...PubSubPeersOption) (*PubSubPeersSettings, error) { options := &PubSubPeersSettings{ diff --git a/core/coreiface/options/unixfs.go b/core/coreiface/options/unixfs.go index dd12502e6..f00fffb87 100644 --- a/core/coreiface/options/unixfs.go +++ b/core/coreiface/options/unixfs.go @@ -43,8 +43,10 @@ type UnixfsLsSettings struct { UseCumulativeSize bool } -type UnixfsAddOption func(*UnixfsAddSettings) error -type UnixfsLsOption func(*UnixfsLsSettings) error +type ( + UnixfsAddOption func(*UnixfsAddSettings) error + UnixfsLsOption func(*UnixfsLsSettings) error +) func UnixfsAddOptions(opts ...UnixfsAddOption) (*UnixfsAddSettings, cid.Prefix, error) { options := &UnixfsAddSettings{ diff --git a/core/coreiface/tests/dag.go b/core/coreiface/tests/dag.go index ba74031f9..b9a03c8f4 100644 --- a/core/coreiface/tests/dag.go +++ b/core/coreiface/tests/dag.go @@ -31,15 +31,13 @@ func (tp *TestSuite) TestDag(t *testing.T) { t.Run("TestBatch", tp.TestBatch) } -var ( - treeExpected = map[string]struct{}{ - "a": {}, - "b": {}, - "c": {}, - "c/d": {}, - "c/e": {}, - } -) +var treeExpected = map[string]struct{}{ + "a": {}, + "b": {}, + "c": {}, + "c/d": {}, + "c/e": {}, +} func (tp *TestSuite) TestPut(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) diff --git a/core/coreiface/tests/name.go b/core/coreiface/tests/name.go index ab55d0425..74d88edff 100644 --- a/core/coreiface/tests/name.go +++ b/core/coreiface/tests/name.go @@ -164,4 +164,4 @@ func (tp *TestSuite) TestBasicPublishResolveTimeout(t *testing.T) { require.NoError(t, err) } -//TODO: When swarm api is created, add multinode tests +// TODO: When swarm api is created, add multinode tests diff --git a/core/coreiface/tests/object.go b/core/coreiface/tests/object.go index 77061b699..63c218eb3 100644 --- a/core/coreiface/tests/object.go +++ b/core/coreiface/tests/object.go @@ -74,7 +74,7 @@ func (tp *TestSuite) TestObjectPut(t *testing.T) { t.Fatal(err) } - p2, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"YmFy"}`), opt.Object.DataType("base64")) //bar + p2, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"YmFy"}`), opt.Object.DataType("base64")) // bar if err != nil { t.Fatal(err) } diff --git a/core/coreiface/tests/unixfs.go b/core/coreiface/tests/unixfs.go index 2842b47bc..25c3ac1b7 100644 --- a/core/coreiface/tests/unixfs.go +++ b/core/coreiface/tests/unixfs.go @@ -53,8 +53,10 @@ func (tp *TestSuite) TestUnixfs(t *testing.T) { } // `echo -n 'hello, world!' | ipfs add` -var hello = "/ipfs/QmQy2Dw4Wk7rdJKjThjYXzfFJNaRKRHhHP5gHHXroJMYxk" -var helloStr = "hello, world!" +var ( + hello = "/ipfs/QmQy2Dw4Wk7rdJKjThjYXzfFJNaRKRHhHP5gHHXroJMYxk" + helloStr = "hello, world!" +) // `echo -n | ipfs add` var emptyFile = "/ipfs/QmbFMke1KXqnYyBBWxB74N4c5SBnJMVAiMNRcGu6x1AwQH" @@ -213,7 +215,7 @@ func (tp *TestSuite) TestAdd(t *testing.T) { path: "/ipfs/bafkqaaa", opts: []options.UnixfsAddOption{options.Unixfs.InlineLimit(0), options.Unixfs.Inline(true), options.Unixfs.RawLeaves(true)}, }, - { //TODO: after coreapi add is used in `ipfs add`, consider making this default for inline + { // TODO: after coreapi add is used in `ipfs add`, consider making this default for inline name: "addInlineRaw", data: strFile(helloStr), path: "/ipfs/bafkqadlimvwgy3zmeb3w64tmmqqq", From 400dc1b2e457316cc49291812862edebcf9e0711 Mon Sep 17 00:00:00 2001 From: Laurent Senta Date: Mon, 21 Aug 2023 12:49:38 +0200 Subject: [PATCH 0828/1212] ci: upload conformance logs --- .github/workflows/gateway-conformance.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/gateway-conformance.yml b/.github/workflows/gateway-conformance.yml index 380dd4d28..c1c732f4c 100644 --- a/.github/workflows/gateway-conformance.yml +++ b/.github/workflows/gateway-conformance.yml @@ -109,3 +109,9 @@ jobs: with: name: gateway-conformance.html path: output.html + - name: Upload JSON report + if: failure() || success() + uses: actions/upload-artifact@v3 + with: + name: gateway-conformance.json + path: output.json From c3492488912b5a667e22e2d414d933751840b3fc Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Tue, 22 Aug 2023 11:20:14 +0200 Subject: [PATCH 0829/1212] docs(readme): new logo and header --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 9cdb87429..8438c7ce7 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,11 @@ +

+Kubo logo +
+Kubo: IPFS Implementation in GO +

+

The first implementation of IPFS.

-![kubo, an IPFS node in Go](https://ipfs.io/ipfs/bafykbzacecaesuqmivkauix25v6i6xxxsvsrtxknhgb5zak3xxsg2nb4dhs2u/ipfs.go.png) +
[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square&cacheSeconds=3600)](https://protocol.ai) [![GoDoc](https://img.shields.io/badge/godoc-reference-5272B4.svg?style=flat-square&cacheSeconds=3600)](https://godoc.org/github.com/ipfs/kubo) From 2aa721b121166c20e6a7901088693eb852912c04 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Tue, 15 Aug 2023 12:56:05 +0200 Subject: [PATCH 0830/1212] chore: bump to go 1.20 - Bumps golangci-lint to work for the new Go version - Removes rand.Seed, which has been deprecated. It is seeded by default with a random value since Go 1.20. - Replaces deprecated Fuse errors with syscall.Errno --- .github/workflows/build.yml | 2 +- .github/workflows/docker-build.yml | 2 +- .github/workflows/gateway-conformance.yml | 2 +- .github/workflows/gobuild.yml | 2 +- .github/workflows/golang-analysis.yml | 2 +- .github/workflows/golint.yml | 2 +- .github/workflows/gotest.yml | 2 +- .github/workflows/sharness.yml | 2 +- Dockerfile | 2 +- cmd/ipfs/main.go | 2 - docs/examples/kubo-as-a-library/go.mod | 2 +- fuse/ipns/ipns_unix.go | 19 +- fuse/readonly/readonly_unix.go | 22 +- go.mod | 2 +- test/dependencies/go.mod | 168 ++++----- test/dependencies/go.sum | 401 +++++++++++----------- 16 files changed, 325 insertions(+), 309 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 468d121a9..1c46f5371 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -10,7 +10,7 @@ on: - 'master' env: - GO_VERSION: 1.19.x + GO_VERSION: 1.20.x concurrency: group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.event_name == 'push' && github.sha || github.ref }} diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml index 23278ec63..bfbd57d9a 100644 --- a/.github/workflows/docker-build.yml +++ b/.github/workflows/docker-build.yml @@ -28,7 +28,7 @@ jobs: steps: - uses: actions/setup-go@v3 with: - go-version: 1.19.x + go-version: 1.20.x - uses: actions/checkout@v3 - run: docker build -t $IMAGE_NAME:$WIP_IMAGE_TAG . - run: docker run --rm $IMAGE_NAME:$WIP_IMAGE_TAG --version diff --git a/.github/workflows/gateway-conformance.yml b/.github/workflows/gateway-conformance.yml index c1c732f4c..928d51c70 100644 --- a/.github/workflows/gateway-conformance.yml +++ b/.github/workflows/gateway-conformance.yml @@ -32,7 +32,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v3 with: - go-version: 1.19.x + go-version: 1.20.x - name: Checkout kubo-gateway uses: actions/checkout@v3 with: diff --git a/.github/workflows/gobuild.yml b/.github/workflows/gobuild.yml index b4a596afc..a299e1115 100644 --- a/.github/workflows/gobuild.yml +++ b/.github/workflows/gobuild.yml @@ -30,7 +30,7 @@ jobs: steps: - uses: actions/setup-go@v3 with: - go-version: 1.19.x + go-version: 1.20.x - uses: actions/checkout@v3 - uses: protocol/cache-go-action@v1 with: diff --git a/.github/workflows/golang-analysis.yml b/.github/workflows/golang-analysis.yml index f65a6d22d..9e70e6b0f 100644 --- a/.github/workflows/golang-analysis.yml +++ b/.github/workflows/golang-analysis.yml @@ -27,7 +27,7 @@ jobs: submodules: recursive - uses: actions/setup-go@v2 with: - go-version: "1.19.x" + go-version: "1.20.x" - name: Check that go.mod is tidy uses: protocol/multiple-go-modules@v1.2 with: diff --git a/.github/workflows/golint.yml b/.github/workflows/golint.yml index 791f41e1b..28a13b87a 100644 --- a/.github/workflows/golint.yml +++ b/.github/workflows/golint.yml @@ -31,7 +31,7 @@ jobs: steps: - uses: actions/setup-go@v3 with: - go-version: 1.19.x + go-version: 1.20.x - uses: actions/checkout@v3 - uses: protocol/cache-go-action@v1 with: diff --git a/.github/workflows/gotest.yml b/.github/workflows/gotest.yml index 630160fbb..1ca6f4619 100644 --- a/.github/workflows/gotest.yml +++ b/.github/workflows/gotest.yml @@ -32,7 +32,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v3 with: - go-version: 1.19.x + go-version: 1.20.x - name: Check out Kubo uses: actions/checkout@v3 - name: Install missing tools diff --git a/.github/workflows/sharness.yml b/.github/workflows/sharness.yml index d88abe89c..8bed22793 100644 --- a/.github/workflows/sharness.yml +++ b/.github/workflows/sharness.yml @@ -25,7 +25,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v3 with: - go-version: 1.19.x + go-version: 1.20.x - name: Checkout Kubo uses: actions/checkout@v3 with: diff --git a/Dockerfile b/Dockerfile index 73597b3cb..9eafe6c60 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM --platform=${BUILDPLATFORM:-linux/amd64} golang:1.19 AS builder +FROM --platform=${BUILDPLATFORM:-linux/amd64} golang:1.20 AS builder ARG TARGETOS TARGETARCH diff --git a/cmd/ipfs/main.go b/cmd/ipfs/main.go index 22fdca91b..10fa66678 100644 --- a/cmd/ipfs/main.go +++ b/cmd/ipfs/main.go @@ -5,7 +5,6 @@ import ( "context" "errors" "fmt" - "math/rand" "net" "net/http" "os" @@ -96,7 +95,6 @@ func newUUID(key string) logging.Metadata { } func mainRet() (exitCode int) { - rand.Seed(time.Now().UnixNano()) ctx := logging.ContextWithLoggable(context.Background(), newUUID("session")) tp, err := tracing.NewTracerProvider(ctx) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 9d79aa782..9aeb6112b 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -1,6 +1,6 @@ module github.com/ipfs/kubo/examples/kubo-as-a-library -go 1.18 +go 1.20 // Used to keep this in sync with the current version of kubo. You should remove // this if you copy this example. diff --git a/fuse/ipns/ipns_unix.go b/fuse/ipns/ipns_unix.go index e4f49cf12..b66634015 100644 --- a/fuse/ipns/ipns_unix.go +++ b/fuse/ipns/ipns_unix.go @@ -12,6 +12,7 @@ import ( "io" "os" "strings" + "syscall" path "github.com/ipfs/boxo/coreiface/path" dag "github.com/ipfs/boxo/ipld/merkledag" @@ -158,7 +159,7 @@ func (r *Root) Lookup(ctx context.Context, name string) (fs.Node, error) { switch name { case "mach_kernel", ".hidden", "._.": // Just quiet some log noise on OS X. - return nil, fuse.ENOENT + return nil, syscall.Errno(syscall.ENOENT) } if lnk, ok := r.LocalLinks[name]; ok { @@ -173,7 +174,7 @@ func (r *Root) Lookup(ctx context.Context, name string) (fs.Node, error) { case *FileNode: return nd, nil default: - return nil, fuse.EIO + return nil, syscall.Errno(syscall.EIO) } } @@ -182,7 +183,7 @@ func (r *Root) Lookup(ctx context.Context, name string) (fs.Node, error) { resolved, err := r.Ipfs.Name().Resolve(ctx, ipnsName) if err != nil { log.Warnf("ipns: namesys resolve error: %s", err) - return nil, fuse.ENOENT + return nil, syscall.Errno(syscall.ENOENT) } if resolved.Namespace() != "ipfs" { @@ -274,7 +275,7 @@ func (d *Directory) Lookup(ctx context.Context, name string) (fs.Node, error) { child, err := d.dir.Child(name) if err != nil { // todo: make this error more versatile. - return nil, fuse.ENOENT + return nil, syscall.Errno(syscall.ENOENT) } switch child := child.(type) { @@ -312,7 +313,7 @@ func (d *Directory) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) { if len(entries) > 0 { return entries, nil } - return nil, fuse.ENOENT + return nil, syscall.Errno(syscall.ENOENT) } func (fi *File) Read(ctx context.Context, req *fuse.ReadRequest, resp *fuse.ReadResponse) error { @@ -423,7 +424,7 @@ func (fi *FileNode) Open(ctx context.Context, req *fuse.OpenRequest, resp *fuse. if req.Flags&fuse.OpenTruncate != 0 { if req.Flags.IsReadOnly() { log.Error("tried to open a readonly file with truncate") - return nil, fuse.ENOTSUP + return nil, syscall.Errno(syscall.ENOTSUP) } log.Info("Need to truncate file!") err := fd.Truncate(0) @@ -434,7 +435,7 @@ func (fi *FileNode) Open(ctx context.Context, req *fuse.OpenRequest, resp *fuse. log.Info("Need to append to file!") if req.Flags.IsReadOnly() { log.Error("tried to open a readonly file with append") - return nil, fuse.ENOTSUP + return nil, syscall.Errno(syscall.ENOTSUP) } _, err := fd.Seek(0, io.SeekEnd) @@ -486,7 +487,7 @@ func (d *Directory) Create(ctx context.Context, req *fuse.CreateRequest, resp *f func (d *Directory) Remove(ctx context.Context, req *fuse.RemoveRequest) error { err := d.dir.Unlink(req.Name) if err != nil { - return fuse.ENOENT + return syscall.Errno(syscall.ENOENT) } return nil } @@ -516,7 +517,7 @@ func (d *Directory) Rename(ctx context.Context, req *fuse.RenameRequest, newDir } case *FileNode: log.Error("Cannot move node into a file!") - return fuse.EPERM + return syscall.Errno(syscall.EPERM) default: log.Error("Unknown node type for rename target dir!") return errors.New("unknown fs node type") diff --git a/fuse/readonly/readonly_unix.go b/fuse/readonly/readonly_unix.go index c75a35fbd..924aa7893 100644 --- a/fuse/readonly/readonly_unix.go +++ b/fuse/readonly/readonly_unix.go @@ -59,32 +59,32 @@ func (s *Root) Lookup(ctx context.Context, name string) (fs.Node, error) { switch name { case "mach_kernel", ".hidden", "._.": // Just quiet some log noise on OS X. - return nil, fuse.ENOENT + return nil, syscall.Errno(syscall.ENOENT) } p, err := path.ParsePath(name) if err != nil { log.Debugf("fuse failed to parse path: %q: %s", name, err) - return nil, fuse.ENOENT + return nil, syscall.Errno(syscall.ENOENT) } nd, ndLnk, err := s.Ipfs.UnixFSPathResolver.ResolvePath(ctx, p) if err != nil { // todo: make this error more versatile. - return nil, fuse.ENOENT + return nil, syscall.Errno(syscall.ENOENT) } cidLnk, ok := ndLnk.(cidlink.Link) if !ok { log.Debugf("non-cidlink returned from ResolvePath: %v", ndLnk) - return nil, fuse.ENOENT + return nil, syscall.Errno(syscall.ENOENT) } // convert ipld-prime node to universal node blk, err := s.Ipfs.Blockstore.Get(ctx, cidLnk.Cid) if err != nil { log.Debugf("fuse failed to retrieve block: %v: %s", cidLnk, err) - return nil, fuse.ENOENT + return nil, syscall.Errno(syscall.ENOENT) } var fnd ipld.Node @@ -101,11 +101,11 @@ func (s *Root) Lookup(ctx context.Context, name string) (fs.Node, error) { fnd, err = mdag.RawNodeConverter(blk, nd) default: log.Error("fuse node was not a supported type") - return nil, fuse.ENOTSUP + return nil, syscall.Errno(syscall.ENOTSUP) } if err != nil { log.Error("could not convert protobuf or raw node") - return nil, fuse.ENOENT + return nil, syscall.Errno(syscall.ENOENT) } return &Node{Ipfs: s.Ipfs, Nd: fnd}, nil @@ -114,7 +114,7 @@ func (s *Root) Lookup(ctx context.Context, name string) (fs.Node, error) { // ReadDirAll reads a particular directory. Disallowed for root. func (*Root) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) { log.Debug("read Root") - return nil, fuse.EPERM + return nil, syscall.Errno(syscall.EPERM) } // Node is the core object representing a filesystem tree node. @@ -178,12 +178,12 @@ func (s *Node) Lookup(ctx context.Context, name string) (fs.Node, error) { switch err { case os.ErrNotExist, mdag.ErrLinkNotFound: // todo: make this error more versatile. - return nil, fuse.ENOENT + return nil, syscall.Errno(syscall.ENOENT) case nil: // noop default: log.Errorf("fuse lookup %q: %s", name, err) - return nil, fuse.EIO + return nil, syscall.Errno(syscall.EIO) } nd, err := s.Ipfs.DAG.Get(ctx, link.Cid) @@ -246,7 +246,7 @@ func (s *Node) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) { if len(entries) > 0 { return entries, nil } - return nil, fuse.ENOENT + return nil, syscall.Errno(syscall.ENOENT) } func (s *Node) Getxattr(ctx context.Context, req *fuse.GetxattrRequest, resp *fuse.GetxattrResponse) error { diff --git a/go.mod b/go.mod index 638513c7b..129b2926a 100644 --- a/go.mod +++ b/go.mod @@ -240,4 +240,4 @@ require ( lukechampine.com/blake3 v1.2.1 // indirect ) -go 1.19 +go 1.20 diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index ed17f6ad8..2b3a1536d 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -1,12 +1,12 @@ module github.com/ipfs/kubo/test/dependencies -go 1.18 +go 1.20 replace github.com/ipfs/kubo => ../../ require ( github.com/Kubuxu/gocovmerge v0.0.0-20161216165753-7ecaa51963cd - github.com/golangci/golangci-lint v1.49.0 + github.com/golangci/golangci-lint v1.54.1 github.com/ipfs/boxo v0.11.1-0.20230818062747-654231b2bda3 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 @@ -26,35 +26,40 @@ require ( ) require ( - 4d63.com/gochecknoglobals v0.1.0 // indirect - github.com/Antonboom/errname v0.1.7 // indirect - github.com/Antonboom/nilnil v0.1.1 // indirect - github.com/BurntSushi/toml v1.2.0 // indirect + 4d63.com/gocheckcompilerdirectives v1.2.1 // indirect + 4d63.com/gochecknoglobals v0.2.1 // indirect + github.com/4meepo/tagalign v1.3.2 // indirect + github.com/Abirdcfly/dupword v0.0.12 // indirect + github.com/Antonboom/errname v0.1.10 // indirect + github.com/Antonboom/nilnil v0.1.5 // indirect + github.com/BurntSushi/toml v1.3.2 // indirect github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 // indirect - github.com/GaijinEntertainment/go-exhaustruct/v2 v2.3.0 // indirect + github.com/GaijinEntertainment/go-exhaustruct/v3 v3.1.0 // indirect github.com/Masterminds/semver v1.5.0 // indirect - github.com/OpenPeeDeeP/depguard v1.1.0 // indirect + github.com/OpenPeeDeeP/depguard/v2 v2.1.0 // indirect github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect + github.com/alexkohler/nakedret/v2 v2.0.2 // indirect github.com/alexkohler/prealloc v1.0.0 // indirect github.com/alingse/asasalint v0.0.11 // indirect - github.com/ashanbrown/forbidigo v1.3.0 // indirect + github.com/ashanbrown/forbidigo v1.6.0 // indirect github.com/ashanbrown/makezero v1.1.1 // indirect github.com/benbjohnson/clock v1.3.5 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/bkielbasa/cyclop v1.2.0 // indirect + github.com/bkielbasa/cyclop v1.2.1 // indirect github.com/blizzy78/varnamelen v0.8.0 // indirect - github.com/bombsimon/wsl/v3 v3.3.0 // indirect - github.com/breml/bidichk v0.2.3 // indirect - github.com/breml/errchkjson v0.3.0 // indirect - github.com/butuzov/ireturn v0.1.1 // indirect + github.com/bombsimon/wsl/v3 v3.4.0 // indirect + github.com/breml/bidichk v0.2.4 // indirect + github.com/breml/errchkjson v0.3.1 // indirect + github.com/butuzov/ireturn v0.2.0 // indirect + github.com/butuzov/mirror v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect - github.com/charithe/durationcheck v0.0.9 // indirect - github.com/chavacava/garif v0.0.0-20220630083739-93517212f375 // indirect + github.com/charithe/durationcheck v0.0.10 // indirect + github.com/chavacava/garif v0.0.0-20230227094218-b8c73b2037b8 // indirect github.com/containerd/cgroups v1.1.0 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect - github.com/curioswitch/go-reassign v0.1.2 // indirect - github.com/daixiang0/gci v0.6.3 // indirect + github.com/curioswitch/go-reassign v0.2.0 // indirect + github.com/daixiang0/gci v0.11.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect @@ -65,25 +70,25 @@ require ( github.com/esimonov/ifshort v1.0.4 // indirect github.com/ettle/strcase v0.1.1 // indirect github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5 // indirect - github.com/fatih/color v1.13.0 // indirect + github.com/fatih/color v1.15.0 // indirect github.com/fatih/structtag v1.2.0 // indirect github.com/firefart/nonamedreturns v1.0.4 // indirect github.com/flynn/noise v1.0.0 // indirect github.com/francoispqt/gojay v1.2.13 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/fzipp/gocyclo v0.6.0 // indirect - github.com/go-critic/go-critic v0.6.4 // indirect + github.com/go-critic/go-critic v0.9.0 // indirect github.com/go-logr/logr v1.2.4 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect - github.com/go-toolsmith/astcast v1.0.0 // indirect - github.com/go-toolsmith/astcopy v1.0.1 // indirect - github.com/go-toolsmith/astequal v1.0.2 // indirect - github.com/go-toolsmith/astfmt v1.0.0 // indirect - github.com/go-toolsmith/astp v1.0.0 // indirect - github.com/go-toolsmith/strparse v1.0.0 // indirect - github.com/go-toolsmith/typep v1.0.2 // indirect - github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b // indirect + github.com/go-toolsmith/astcast v1.1.0 // indirect + github.com/go-toolsmith/astcopy v1.1.0 // indirect + github.com/go-toolsmith/astequal v1.1.0 // indirect + github.com/go-toolsmith/astfmt v1.1.0 // indirect + github.com/go-toolsmith/astp v1.1.0 // indirect + github.com/go-toolsmith/strparse v1.1.0 // indirect + github.com/go-toolsmith/typep v1.1.0 // indirect + github.com/go-xmlfmt/xmlfmt v1.1.2 // indirect github.com/gobwas/glob v0.2.3 // indirect github.com/godbus/dbus/v5 v5.1.0 // indirect github.com/gofrs/flock v0.8.1 // indirect @@ -96,14 +101,14 @@ require ( github.com/golangci/gofmt v0.0.0-20220901101216-f2edd75033f2 // indirect github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0 // indirect github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca // indirect - github.com/golangci/misspell v0.3.5 // indirect + github.com/golangci/misspell v0.4.1 // indirect github.com/golangci/revgrep v0.0.0-20220804021717-745bb2f7c2e6 // indirect github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4 // indirect github.com/google/go-cmp v0.5.9 // indirect github.com/google/gopacket v1.1.19 // indirect github.com/google/pprof v0.0.0-20230705174524-200ffdc848b8 // indirect github.com/google/uuid v1.3.0 // indirect - github.com/gordonklaus/ineffassign v0.0.0-20210914165742-4cc7213b9bc8 // indirect + github.com/gordonklaus/ineffassign v0.0.0-20230610083614-0e73809eb601 // indirect github.com/gorilla/websocket v1.5.0 // indirect github.com/gostaticanalysis/analysisutil v0.7.1 // indirect github.com/gostaticanalysis/comment v1.4.2 // indirect @@ -119,7 +124,7 @@ require ( github.com/hashicorp/hcl v1.0.0 // indirect github.com/hexops/gotextdiff v1.0.3 // indirect github.com/huin/goupnp v1.2.0 // indirect - github.com/inconshreveable/mousetrap v1.0.0 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/ipfs/bbloom v0.0.4 // indirect github.com/ipfs/go-bitfield v1.1.0 // indirect github.com/ipfs/go-block-format v0.1.2 // indirect @@ -144,17 +149,18 @@ require ( github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af // indirect github.com/jonboulle/clockwork v0.2.0 // indirect github.com/julz/importas v0.1.0 // indirect - github.com/kisielk/errcheck v1.6.2 // indirect + github.com/kisielk/errcheck v1.6.3 // indirect github.com/kisielk/gotool v1.0.0 // indirect + github.com/kkHAIKE/contextcheck v1.1.4 // indirect github.com/klauspost/compress v1.16.7 // indirect github.com/klauspost/cpuid/v2 v2.2.5 // indirect github.com/koron/go-ssdp v0.0.4 // indirect github.com/kulti/thelper v0.6.3 // indirect - github.com/kunwardeep/paralleltest v1.0.6 // indirect - github.com/kyoh86/exportloopref v0.1.8 // indirect + github.com/kunwardeep/paralleltest v1.0.8 // indirect + github.com/kyoh86/exportloopref v0.1.11 // indirect github.com/ldez/gomoddirectives v0.2.3 // indirect - github.com/ldez/tagliatelle v0.3.1 // indirect - github.com/leonklingele/grouper v1.1.0 // indirect + github.com/ldez/tagliatelle v0.5.0 // indirect + github.com/leonklingele/grouper v1.1.1 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/libp2p/go-cidranger v1.1.0 // indirect github.com/libp2p/go-flow-metrics v0.1.0 // indirect @@ -166,22 +172,23 @@ require ( github.com/libp2p/go-yamux/v4 v4.0.1 // indirect github.com/lufeee/execinquery v1.2.1 // indirect github.com/magiconair/properties v1.8.6 // indirect - github.com/maratori/testpackage v1.1.0 // indirect + github.com/maratori/testableexamples v1.0.0 // indirect + github.com/maratori/testpackage v1.1.1 // indirect github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect - github.com/matoous/godox v0.0.0-20210227103229-6504466cf951 // indirect + github.com/matoous/godox v0.0.0-20230222163458-006bad1f9d26 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.19 // indirect github.com/mattn/go-runewidth v0.0.9 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/mbilski/exhaustivestruct v1.2.0 // indirect - github.com/mgechev/revive v1.2.3 // indirect + github.com/mgechev/revive v1.3.2 // indirect github.com/miekg/dns v1.1.55 // indirect github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect github.com/minio/sha256-simd v1.0.1 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect - github.com/moricho/tparallel v0.2.1 // indirect + github.com/moricho/tparallel v0.3.1 // indirect github.com/mr-tron/base58 v1.2.0 // indirect github.com/multiformats/go-base32 v0.1.0 // indirect github.com/multiformats/go-base36 v0.2.0 // indirect @@ -193,27 +200,27 @@ require ( github.com/multiformats/go-varint v0.0.7 // indirect github.com/nakabonne/nestif v0.3.1 // indirect github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354 // indirect - github.com/nishanths/exhaustive v0.8.1 // indirect + github.com/nishanths/exhaustive v0.11.0 // indirect github.com/nishanths/predeclared v0.2.2 // indirect + github.com/nunnatsa/ginkgolinter v0.13.3 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/onsi/ginkgo/v2 v2.11.0 // indirect github.com/opencontainers/runtime-spec v1.0.2 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect github.com/pelletier/go-toml v1.9.5 // indirect - github.com/pelletier/go-toml/v2 v2.0.2 // indirect - github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d // indirect + github.com/pelletier/go-toml/v2 v2.0.5 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/polydawn/refmt v0.89.0 // indirect - github.com/polyfloyd/go-errorlint v1.0.2 // indirect + github.com/polyfloyd/go-errorlint v1.4.3 // indirect github.com/prometheus/client_golang v1.16.0 // indirect github.com/prometheus/client_model v0.4.0 // indirect github.com/prometheus/common v0.44.0 // indirect github.com/prometheus/procfs v0.11.0 // indirect - github.com/quasilyte/go-ruleguard v0.3.17 // indirect - github.com/quasilyte/gogrep v0.0.0-20220120141003-628d8b3623b5 // indirect - github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95 // indirect + github.com/quasilyte/go-ruleguard v0.4.0 // indirect + github.com/quasilyte/gogrep v0.5.0 // indirect + github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727 // indirect github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 // indirect github.com/quic-go/qpack v0.4.0 // indirect github.com/quic-go/qtls-go1-19 v0.3.3 // indirect @@ -222,23 +229,23 @@ require ( github.com/quic-go/webtransport-go v0.5.3 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect - github.com/ryancurrah/gomodguard v1.2.4 // indirect - github.com/ryanrolds/sqlclosecheck v0.3.0 // indirect - github.com/sanposhiho/wastedassign/v2 v2.0.6 // indirect + github.com/ryancurrah/gomodguard v1.3.0 // indirect + github.com/ryanrolds/sqlclosecheck v0.4.0 // indirect + github.com/sanposhiho/wastedassign/v2 v2.0.7 // indirect github.com/sashamelentyev/interfacebloat v1.1.0 // indirect - github.com/sashamelentyev/usestdlibvars v1.13.0 // indirect - github.com/securego/gosec/v2 v2.13.1 // indirect + github.com/sashamelentyev/usestdlibvars v1.23.0 // indirect + github.com/securego/gosec/v2 v2.16.0 // indirect github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c // indirect - github.com/sirupsen/logrus v1.9.0 // indirect - github.com/sivchari/containedctx v1.0.2 // indirect + github.com/sirupsen/logrus v1.9.3 // indirect + github.com/sivchari/containedctx v1.0.3 // indirect github.com/sivchari/nosnakecase v1.7.0 // indirect - github.com/sivchari/tenv v1.7.0 // indirect - github.com/sonatard/noctx v0.0.1 // indirect - github.com/sourcegraph/go-diff v0.6.1 // indirect + github.com/sivchari/tenv v1.7.1 // indirect + github.com/sonatard/noctx v0.0.2 // indirect + github.com/sourcegraph/go-diff v0.7.0 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/spf13/afero v1.8.2 // indirect github.com/spf13/cast v1.5.0 // indirect - github.com/spf13/cobra v1.5.0 // indirect + github.com/spf13/cobra v1.7.0 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/spf13/viper v1.12.0 // indirect @@ -246,47 +253,50 @@ require ( github.com/stbenjam/no-sprintf-host-port v0.1.1 // indirect github.com/stretchr/objx v0.5.0 // indirect github.com/stretchr/testify v1.8.4 // indirect - github.com/subosito/gotenv v1.4.0 // indirect - github.com/sylvia7788/contextcheck v1.0.6 // indirect - github.com/tdakkota/asciicheck v0.1.1 // indirect + github.com/subosito/gotenv v1.4.1 // indirect + github.com/t-yuki/gocover-cobertura v0.0.0-20180217150009-aaee18c8195c // indirect + github.com/tdakkota/asciicheck v0.2.0 // indirect github.com/tetafro/godot v1.4.11 // indirect - github.com/timakin/bodyclose v0.0.0-20210704033933-f49887972144 // indirect - github.com/timonwong/logrlint v0.1.0 // indirect - github.com/tomarrell/wrapcheck/v2 v2.6.2 // indirect - github.com/tommy-muehle/go-mnd/v2 v2.5.0 // indirect - github.com/ultraware/funlen v0.0.3 // indirect + github.com/timakin/bodyclose v0.0.0-20230421092635-574207250966 // indirect + github.com/timonwong/loggercheck v0.9.4 // indirect + github.com/tomarrell/wrapcheck/v2 v2.8.1 // indirect + github.com/tommy-muehle/go-mnd/v2 v2.5.1 // indirect + github.com/ultraware/funlen v0.1.0 // indirect github.com/ultraware/whitespace v0.0.5 // indirect github.com/urfave/cli v1.22.10 // indirect - github.com/uudashr/gocognit v1.0.6 // indirect + github.com/uudashr/gocognit v1.0.7 // indirect + github.com/xen0n/gosmopolitan v1.2.1 // indirect github.com/yagipy/maintidx v1.0.0 // indirect github.com/yeya24/promlinter v0.2.0 // indirect - gitlab.com/bosi/decorder v0.2.3 // indirect + github.com/ykadowak/zerologlint v0.1.3 // indirect + gitlab.com/bosi/decorder v0.4.0 // indirect go.opentelemetry.io/otel v1.16.0 // indirect go.opentelemetry.io/otel/metric v1.16.0 // indirect go.opentelemetry.io/otel/trace v1.16.0 // indirect + go.tmz.dev/musttag v0.7.1 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/dig v1.17.0 // indirect go.uber.org/fx v1.20.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.24.0 // indirect - golang.org/x/crypto v0.11.0 // indirect + golang.org/x/crypto v0.12.0 // indirect golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 // indirect - golang.org/x/exp/typeparams v0.0.0-20220613132600-b0d781184e0d // indirect + golang.org/x/exp/typeparams v0.0.0-20230307190834-24139beb5833 // indirect golang.org/x/mod v0.12.0 // indirect - golang.org/x/net v0.12.0 // indirect + golang.org/x/net v0.14.0 // indirect golang.org/x/sync v0.3.0 // indirect - golang.org/x/sys v0.10.0 // indirect - golang.org/x/term v0.10.0 // indirect - golang.org/x/text v0.11.0 // indirect - golang.org/x/tools v0.11.0 // indirect + golang.org/x/sys v0.11.0 // indirect + golang.org/x/term v0.11.0 // indirect + golang.org/x/text v0.12.0 // indirect + golang.org/x/tools v0.12.0 // indirect google.golang.org/protobuf v1.31.0 // indirect - gopkg.in/ini.v1 v1.66.6 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - honnef.co/go/tools v0.3.3 // indirect + honnef.co/go/tools v0.4.3 // indirect lukechampine.com/blake3 v1.2.1 // indirect - mvdan.cc/gofumpt v0.3.1 // indirect + mvdan.cc/gofumpt v0.5.0 // indirect mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed // indirect mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b // indirect - mvdan.cc/unparam v0.0.0-20220706161116-678bad134442 // indirect + mvdan.cc/unparam v0.0.0-20221223090309-7455f1af531d // indirect ) diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 8e943ec0b..5c7a860aa 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -1,5 +1,7 @@ -4d63.com/gochecknoglobals v0.1.0 h1:zeZSRqj5yCg28tCkIV/z/lWbwvNm5qnKVS15PI8nhD0= -4d63.com/gochecknoglobals v0.1.0/go.mod h1:wfdC5ZjKSPr7CybKEcgJhUOgeAQW1+7WcyK8OvUilfo= +4d63.com/gocheckcompilerdirectives v1.2.1 h1:AHcMYuw56NPjq/2y615IGg2kYkBdTvOaojYCBcRE7MA= +4d63.com/gocheckcompilerdirectives v1.2.1/go.mod h1:yjDJSxmDTtIHHCqX0ufRYZDL6vQtMG7tJdKVeWwsqvs= +4d63.com/gochecknoglobals v0.2.1 h1:1eiorGsgHOFOuoOiJDy2psSrQbRdIHrlge0IJIkUgDc= +4d63.com/gochecknoglobals v0.2.1/go.mod h1:KRE8wtJB3CXCsb1xy421JfTHIIbmT3U5ruxw2Qu8fSU= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.31.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= @@ -45,24 +47,28 @@ dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBr dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4= dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU= git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg= -github.com/Antonboom/errname v0.1.7 h1:mBBDKvEYwPl4WFFNwec1CZO096G6vzK9vvDQzAwkako= -github.com/Antonboom/errname v0.1.7/go.mod h1:g0ONh16msHIPgJSGsecu1G/dcF2hlYR/0SddnIAGavU= -github.com/Antonboom/nilnil v0.1.1 h1:PHhrh5ANKFWRBh7TdYmyyq2gyT2lotnvFvvFbylF81Q= -github.com/Antonboom/nilnil v0.1.1/go.mod h1:L1jBqoWM7AOeTD+tSquifKSesRHs4ZdaxvZR+xdJEaI= +github.com/4meepo/tagalign v1.3.2 h1:1idD3yxlRGV18VjqtDbqYvQ5pXqQS0wO2dn6M3XstvI= +github.com/4meepo/tagalign v1.3.2/go.mod h1:Q9c1rYMZJc9dPRkbQPpcBNCLEmY2njbAsXhQOZFE2dE= +github.com/Abirdcfly/dupword v0.0.12 h1:56NnOyrXzChj07BDFjeRA+IUzSz01jmzEq+G4kEgFhc= +github.com/Abirdcfly/dupword v0.0.12/go.mod h1:+us/TGct/nI9Ndcbcp3rgNcQzctTj68pq7TcgNpLfdI= +github.com/Antonboom/errname v0.1.10 h1:RZ7cYo/GuZqjr1nuJLNe8ZH+a+Jd9DaZzttWzak9Bls= +github.com/Antonboom/errname v0.1.10/go.mod h1:xLeiCIrvVNpUtsN0wxAh05bNIZpqE22/qDMnTBTttiA= +github.com/Antonboom/nilnil v0.1.5 h1:X2JAdEVcbPaOom2TUa1FxZ3uyuUlex0XMLGYMemu6l0= +github.com/Antonboom/nilnil v0.1.5/go.mod h1:I24toVuBKhfP5teihGWctrRiPbRKHwZIFOvc6v3HZXk= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/toml v1.2.0 h1:Rt8g24XnyGTyglgET/PRUNlrUeu9F5L+7FilkXfZgs0= -github.com/BurntSushi/toml v1.2.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= +github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 h1:sHglBQTwgx+rWPdisA5ynNEsoARbiCBOyGcJM4/OzsM= github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs= -github.com/GaijinEntertainment/go-exhaustruct/v2 v2.3.0 h1:+r1rSv4gvYn0wmRjC8X7IAzX8QezqtFV9m0MUHFJgts= -github.com/GaijinEntertainment/go-exhaustruct/v2 v2.3.0/go.mod h1:b3g59n2Y+T5xmcxJL+UEG2f8cQploZm1mR/v6BW0mU0= +github.com/GaijinEntertainment/go-exhaustruct/v3 v3.1.0 h1:3ZBs7LAezy8gh0uECsA6CGU43FF3zsx5f4eah5FxTMA= +github.com/GaijinEntertainment/go-exhaustruct/v3 v3.1.0/go.mod h1:rZLTje5A9kFBe0pzhpe2TdhRniBF++PRHQuRpR8esVc= github.com/Kubuxu/gocovmerge v0.0.0-20161216165753-7ecaa51963cd h1:HNhzThEtZW714v8Eda8sWWRcu9WSzJC+oCyjRjvZgRA= github.com/Kubuxu/gocovmerge v0.0.0-20161216165753-7ecaa51963cd/go.mod h1:bqoB8kInrTeEtYAwaIXoSRqdwnjQmFhsfusnzyui6yY= github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= -github.com/OpenPeeDeeP/depguard v1.1.0 h1:pjK9nLPS1FwQYGGpPxoMYpe7qACHOhAWQMQzV71i49o= -github.com/OpenPeeDeeP/depguard v1.1.0/go.mod h1:JtAMzWkmFEzDPyAd+W0NHl1lvpQKTvT9jnRVsohBKpc= +github.com/OpenPeeDeeP/depguard/v2 v2.1.0 h1:aQl70G173h/GZYhWf36aE5H0KaujXfVMnn/f1kSDVYY= +github.com/OpenPeeDeeP/depguard/v2 v2.1.0/go.mod h1:PUBgk35fX4i7JDmwzlJwJ+GMe6NfO1723wmJMgPThNQ= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= @@ -70,13 +76,15 @@ github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRF github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 h1:s6gZFSlWYmbqAuRjVTiNNhvNRfY2Wxp9nhfyel4rklc= github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= +github.com/alexkohler/nakedret/v2 v2.0.2 h1:qnXuZNvv3/AxkAb22q/sEsEpcA99YxLFACDtEw9TPxE= +github.com/alexkohler/nakedret/v2 v2.0.2/go.mod h1:2b8Gkk0GsOrqQv/gPWjNLDSKwG8I5moSXG1K4VIBcTQ= github.com/alexkohler/prealloc v1.0.0 h1:Hbq0/3fJPQhNkN0dR95AVrr6R7tou91y0uHG5pOcUuw= github.com/alexkohler/prealloc v1.0.0/go.mod h1:VetnK3dIgFBBKmg0YnD9F9x6Icjd+9cvfHR56wJVlKE= github.com/alingse/asasalint v0.0.11 h1:SFwnQXJ49Kx/1GghOFz1XGqHYKp21Kq1nHad/0WQRnw= github.com/alingse/asasalint v0.0.11/go.mod h1:nCaoMhw7a9kSJObvQyVzNTPBDbNpdocqrSP7t/cW5+I= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= -github.com/ashanbrown/forbidigo v1.3.0 h1:VkYIwb/xxdireGAdJNZoo24O4lmnEWkactplBlWTShc= -github.com/ashanbrown/forbidigo v1.3.0/go.mod h1:vVW7PEdqEFqapJe95xHkTfB1+XvZXBFg8t0sG2FIxmI= +github.com/ashanbrown/forbidigo v1.6.0 h1:D3aewfM37Yb3pxHujIPSpTf6oQk9sc9WZi8gerOIVIY= +github.com/ashanbrown/forbidigo v1.6.0/go.mod h1:Y8j9jy9ZYAEHXdu723cUlraTqbzjKF1MUyfOKL+AjcU= github.com/ashanbrown/makezero v1.1.1 h1:iCQ87C0V0vSyO+M9E/FZYbu65auqH0lnsOkf5FcB28s= github.com/ashanbrown/makezero v1.1.1/go.mod h1:i1bJLCRSCHOcOa9Y6MyF2FTfMZMFdHvxKHxgO5Z1axI= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= @@ -87,29 +95,31 @@ github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24 github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/bkielbasa/cyclop v1.2.0 h1:7Jmnh0yL2DjKfw28p86YTd/B4lRGcNuu12sKE35sM7A= -github.com/bkielbasa/cyclop v1.2.0/go.mod h1:qOI0yy6A7dYC4Zgsa72Ppm9kONl0RoIlPbzot9mhmeI= +github.com/bkielbasa/cyclop v1.2.1 h1:AeF71HZDob1P2/pRm1so9cd1alZnrpyc4q2uP2l0gJY= +github.com/bkielbasa/cyclop v1.2.1/go.mod h1:K/dT/M0FPAiYjBgQGau7tz+3TMh4FWAEqlMhzFWCrgM= github.com/blizzy78/varnamelen v0.8.0 h1:oqSblyuQvFsW1hbBHh1zfwrKe3kcSj0rnXkKzsQ089M= github.com/blizzy78/varnamelen v0.8.0/go.mod h1:V9TzQZ4fLJ1DSrjVDfl89H7aMnTvKkApdHeyESmyR7k= -github.com/bombsimon/wsl/v3 v3.3.0 h1:Mka/+kRLoQJq7g2rggtgQsjuI/K5Efd87WX96EWFxjM= -github.com/bombsimon/wsl/v3 v3.3.0/go.mod h1:st10JtZYLE4D5sC7b8xV4zTKZwAQjCH/Hy2Pm1FNZIc= +github.com/bombsimon/wsl/v3 v3.4.0 h1:RkSxjT3tmlptwfgEgTgU+KYKLI35p/tviNXNXiL2aNU= +github.com/bombsimon/wsl/v3 v3.4.0/go.mod h1:KkIB+TXkqy6MvK9BDZVbZxKNYsE1/oLRJbIFtf14qqo= github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= -github.com/breml/bidichk v0.2.3 h1:qe6ggxpTfA8E75hdjWPZ581sY3a2lnl0IRxLQFelECI= -github.com/breml/bidichk v0.2.3/go.mod h1:8u2C6DnAy0g2cEq+k/A2+tr9O1s+vHGxWn0LTc70T2A= -github.com/breml/errchkjson v0.3.0 h1:YdDqhfqMT+I1vIxPSas44P+9Z9HzJwCeAzjB8PxP1xw= -github.com/breml/errchkjson v0.3.0/go.mod h1:9Cogkyv9gcT8HREpzi3TiqBxCqDzo8awa92zSDFcofU= +github.com/breml/bidichk v0.2.4 h1:i3yedFWWQ7YzjdZJHnPo9d/xURinSq3OM+gyM43K4/8= +github.com/breml/bidichk v0.2.4/go.mod h1:7Zk0kRFt1LIZxtQdl9W9JwGAcLTTkOs+tN7wuEYGJ3s= +github.com/breml/errchkjson v0.3.1 h1:hlIeXuspTyt8Y/UmP5qy1JocGNR00KQHgfaNtRAjoxQ= +github.com/breml/errchkjson v0.3.1/go.mod h1:XroxrzKjdiutFyW3nWhw34VGg7kiMsDQox73yWCGI2U= github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= -github.com/butuzov/ireturn v0.1.1 h1:QvrO2QF2+/Cx1WA/vETCIYBKtRjc30vesdoPUNo1EbY= -github.com/butuzov/ireturn v0.1.1/go.mod h1:Wh6Zl3IMtTpaIKbmwzqi6olnM9ptYQxxVacMsOEFPoc= +github.com/butuzov/ireturn v0.2.0 h1:kCHi+YzC150GE98WFuZQu9yrTn6GEydO2AuPLbTgnO4= +github.com/butuzov/ireturn v0.2.0/go.mod h1:Wh6Zl3IMtTpaIKbmwzqi6olnM9ptYQxxVacMsOEFPoc= +github.com/butuzov/mirror v1.1.0 h1:ZqX54gBVMXu78QLoiqdwpl2mgmoOJTk7s4p4o+0avZI= +github.com/butuzov/mirror v1.1.0/go.mod h1:8Q0BdQU6rC6WILDiBM60DBfvV78OLJmMmixe7GF45AE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/charithe/durationcheck v0.0.9 h1:mPP4ucLrf/rKZiIG/a9IPXHGlh8p4CzgpyTy6EEutYk= -github.com/charithe/durationcheck v0.0.9/go.mod h1:SSbRIBVfMjCi/kEB6K65XEA83D6prSM8ap1UCpNKtgg= -github.com/chavacava/garif v0.0.0-20220630083739-93517212f375 h1:E7LT642ysztPWE0dfz43cWOvMiF42DyTRC+eZIaO4yI= -github.com/chavacava/garif v0.0.0-20220630083739-93517212f375/go.mod h1:4m1Rv7xfuwWPNKXlThldNuJvutYM6J95wNuuVmn55To= +github.com/charithe/durationcheck v0.0.10 h1:wgw73BiocdBDQPik+zcEoBG/ob8uyBHf2iyoHGPf5w4= +github.com/charithe/durationcheck v0.0.10/go.mod h1:bCWXb7gYRysD1CU3C+u4ceO49LoGOY1C1L6uouGNreQ= +github.com/chavacava/garif v0.0.0-20230227094218-b8c73b2037b8 h1:W9o46d2kbNL06lq7UNDPV0zYLzkrde/bjIqO02eoll0= +github.com/chavacava/garif v0.0.0-20230227094218-b8c73b2037b8/go.mod h1:gakxgyXaaPkxvLw1XQxNGK4I37ys9iBRzNUx/B7pUCo= 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= @@ -130,13 +140,11 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsr github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/crackcomm/go-gitignore v0.0.0-20170627025303-887ab5e44cc3 h1:HVTnpeuvF6Owjd5mniCL8DEXo7uYXdQEmOP4FJbV5tg= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/cristalhq/acmd v0.7.0/go.mod h1:LG5oa43pE/BbxtfMoImHCQN++0Su7dzipdgBjMCBVDQ= github.com/cskr/pubsub v1.0.2 h1:vlOzMhl6PFn60gRlTQQsIfVwaPB/B/8MziK8FhEPt/0= -github.com/curioswitch/go-reassign v0.1.2 h1:ekM07+z+VFT560Exz4mTv0/s1yU9gem6CJc/tlYpkmI= -github.com/curioswitch/go-reassign v0.1.2/go.mod h1:bFJIHgtTM3hRm2sKXSPkbwNjSFyGURQXyn4IXD2qwfQ= -github.com/daixiang0/gci v0.6.3 h1:wUAqXChk8HbwXn8AfxD9DYSCp9Bpz1L3e6Q4Roe+q9E= -github.com/daixiang0/gci v0.6.3/go.mod h1:EpVfrztufwVgQRXjnX4zuNinEpLj5OmMjtu/+MB0V0c= +github.com/curioswitch/go-reassign v0.2.0 h1:G9UZyOcpk/d7Gd6mqYgd8XYWFMw/znxwGDUstnC9DIo= +github.com/curioswitch/go-reassign v0.2.0/go.mod h1:x6OpXuWvgfQaMGks2BZybTngWjT84hqJfKoO8Tt/Roc= +github.com/daixiang0/gci v0.11.0 h1:XeQbFKkCRxvVyn06EOuNY6LPGBLVuB/W130c8FrnX6A= +github.com/daixiang0/gci v0.11.0/go.mod h1:xtHP9N7AHdNvtRNfcx9gwTDfw7FRJx4bZUsiEfiNNAI= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -169,8 +177,8 @@ github.com/ettle/strcase v0.1.1/go.mod h1:hzDLsPC7/lwKyBOywSHEP89nt2pDgdy+No1NBA github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5 h1:BBso6MBKW8ncyZLv37o+KNyy0HrrHgfnOaGQC2qvN+A= github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5/go.mod h1:JpoxHjuQauoxiFMl1ie8Xc/7TfLuMZ5eOCONd1sUBHg= github.com/fatih/color v1.6.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= -github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= +github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= +github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4= github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94= github.com/firefart/nonamedreturns v1.0.4 h1:abzI1p7mAEPYuR4A+VLKn4eNDOycjYo2phmY9sfv40Y= @@ -188,8 +196,8 @@ github.com/fzipp/gocyclo v0.6.0 h1:lsblElZG7d3ALtGMx9fmxeTKZaLLpU8mET09yN4BBLo= github.com/fzipp/gocyclo v0.6.0/go.mod h1:rXPyn8fnlpa0R2csP/31uerbiVBugk5whMdlyaLkLoA= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= -github.com/go-critic/go-critic v0.6.4 h1:tucuG1pvOyYgpBIrVxw0R6gwO42lNa92Aq3VaDoIs+E= -github.com/go-critic/go-critic v0.6.4/go.mod h1:qL5SOlk7NtY6sJPoVCTKDIgzNOxHkkkOCVDyi9wJe1U= +github.com/go-critic/go-critic v0.9.0 h1:Pmys9qvU3pSML/3GEQ2Xd9RZ/ip+aXHKILuxczKGV/U= +github.com/go-critic/go-critic v0.9.0/go.mod h1:5P8tdXL7m/6qnyG6oRAlYLORvoXH0WDypYgAEmagT40= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -205,31 +213,28 @@ github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= -github.com/go-toolsmith/astcast v1.0.0 h1:JojxlmI6STnFVG9yOImLeGREv8W2ocNUM+iOhR6jE7g= -github.com/go-toolsmith/astcast v1.0.0/go.mod h1:mt2OdQTeAQcY4DQgPSArJjHCcOwlX+Wl/kwN+LbLGQ4= -github.com/go-toolsmith/astcopy v1.0.0/go.mod h1:vrgyG+5Bxrnz4MZWPF+pI4R8h3qKRjjyvV/DSez4WVQ= -github.com/go-toolsmith/astcopy v1.0.1 h1:l09oBhAPyV74kLJ3ZO31iBU8htZGTwr9LTjuMCyL8go= -github.com/go-toolsmith/astcopy v1.0.1/go.mod h1:4TcEdbElGc9twQEYpVo/aieIXfHhiuLh4aLAck6dO7Y= -github.com/go-toolsmith/astequal v1.0.0/go.mod h1:H+xSiq0+LtiDC11+h1G32h7Of5O3CYFJ99GVbS5lDKY= -github.com/go-toolsmith/astequal v1.0.1/go.mod h1:4oGA3EZXTVItV/ipGiOx7NWkY5veFfcsOJVS2YxltLw= -github.com/go-toolsmith/astequal v1.0.2 h1:+XvaV8zNxua+9+Oa4AHmgmpo4RYAbwr/qjNppLfX2yM= -github.com/go-toolsmith/astequal v1.0.2/go.mod h1:9Ai4UglvtR+4up+bAD4+hCj7iTo4m/OXVTSLnCyTAx4= -github.com/go-toolsmith/astfmt v1.0.0 h1:A0vDDXt+vsvLEdbMFJAUBI/uTbRw1ffOPnxsILnFL6k= -github.com/go-toolsmith/astfmt v1.0.0/go.mod h1:cnWmsOAuq4jJY6Ct5YWlVLmcmLMn1JUPuQIHCY7CJDw= -github.com/go-toolsmith/astp v1.0.0 h1:alXE75TXgcmupDsMK1fRAy0YUzLzqPVvBKoyWV+KPXg= -github.com/go-toolsmith/astp v1.0.0/go.mod h1:RSyrtpVlfTFGDYRbrjyWP1pYu//tSFcvdYrA8meBmLI= -github.com/go-toolsmith/pkgload v1.0.2-0.20220101231613-e814995d17c5 h1:eD9POs68PHkwrx7hAB78z1cb6PfGq/jyWn3wJywsH1o= -github.com/go-toolsmith/pkgload v1.0.2-0.20220101231613-e814995d17c5/go.mod h1:3NAwwmD4uY/yggRxoEjk/S00MIV3A+H7rrE3i87eYxM= -github.com/go-toolsmith/strparse v1.0.0 h1:Vcw78DnpCAKlM20kSbAyO4mPfJn/lyYA4BJUDxe2Jb4= +github.com/go-toolsmith/astcast v1.1.0 h1:+JN9xZV1A+Re+95pgnMgDboWNVnIMMQXwfBwLRPgSC8= +github.com/go-toolsmith/astcast v1.1.0/go.mod h1:qdcuFWeGGS2xX5bLM/c3U9lewg7+Zu4mr+xPwZIB4ZU= +github.com/go-toolsmith/astcopy v1.1.0 h1:YGwBN0WM+ekI/6SS6+52zLDEf8Yvp3n2seZITCUBt5s= +github.com/go-toolsmith/astcopy v1.1.0/go.mod h1:hXM6gan18VA1T/daUEHCFcYiW8Ai1tIwIzHY6srfEAw= +github.com/go-toolsmith/astequal v1.0.3/go.mod h1:9Ai4UglvtR+4up+bAD4+hCj7iTo4m/OXVTSLnCyTAx4= +github.com/go-toolsmith/astequal v1.1.0 h1:kHKm1AWqClYn15R0K1KKE4RG614D46n+nqUQ06E1dTw= +github.com/go-toolsmith/astequal v1.1.0/go.mod h1:sedf7VIdCL22LD8qIvv7Nn9MuWJruQA/ysswh64lffQ= +github.com/go-toolsmith/astfmt v1.1.0 h1:iJVPDPp6/7AaeLJEruMsBUlOYCmvg0MoCfJprsOmcco= +github.com/go-toolsmith/astfmt v1.1.0/go.mod h1:OrcLlRwu0CuiIBp/8b5PYF9ktGVZUjlNMV634mhwuQ4= +github.com/go-toolsmith/astp v1.1.0 h1:dXPuCl6u2llURjdPLLDxJeZInAeZ0/eZwFJmqZMnpQA= +github.com/go-toolsmith/astp v1.1.0/go.mod h1:0T1xFGz9hicKs8Z5MfAqSUitoUYS30pDMsRVIDHs8CA= +github.com/go-toolsmith/pkgload v1.2.2 h1:0CtmHq/02QhxcF7E9N5LIFcYFsMR5rdovfqTtRKkgIk= github.com/go-toolsmith/strparse v1.0.0/go.mod h1:YI2nUKP9YGZnL/L1/DLFBfixrcjslWct4wyljWhSRy8= -github.com/go-toolsmith/typep v1.0.2 h1:8xdsa1+FSIH/RhEkgnD1j2CJOy5mNllW1Q9tRiYwvlk= -github.com/go-toolsmith/typep v1.0.2/go.mod h1:JSQCQMUPdRlMZFswiq3TGpNp1GMktqkR2Ns5AIQkATU= -github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b h1:khEcpUM4yFcxg4/FHQWkvVRmgijNXRfzkIDHh23ggEo= -github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM= +github.com/go-toolsmith/strparse v1.1.0 h1:GAioeZUK9TGxnLS+qfdqNbA4z0SSm5zVNtCQiyP2Bvw= +github.com/go-toolsmith/strparse v1.1.0/go.mod h1:7ksGy58fsaQkGQlY8WVoBFNyEPMGuJin1rfoPS4lBSQ= +github.com/go-toolsmith/typep v1.1.0 h1:fIRYDyF+JywLfqzyhdiHzRop/GQDxxNhLGQ6gFUNHus= +github.com/go-toolsmith/typep v1.1.0/go.mod h1:fVIw+7zjdsMxDA3ITWnH1yOiw1rnTQKCsF/sk2H/qig= +github.com/go-xmlfmt/xmlfmt v1.1.2 h1:Nea7b4icn8s57fTx1M5AI4qQT5HEM3rVUO8MuE6g80U= +github.com/go-xmlfmt/xmlfmt v1.1.2/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM= github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= @@ -283,14 +288,14 @@ github.com/golangci/go-misc v0.0.0-20220329215616-d24fe342adfe h1:6RGUuS7EGotKx6 github.com/golangci/go-misc v0.0.0-20220329215616-d24fe342adfe/go.mod h1:gjqyPShc/m8pEMpk0a3SeagVb0kaqvhscv+i9jI5ZhQ= github.com/golangci/gofmt v0.0.0-20220901101216-f2edd75033f2 h1:amWTbTGqOZ71ruzrdA+Nx5WA3tV1N0goTspwmKCQvBY= github.com/golangci/gofmt v0.0.0-20220901101216-f2edd75033f2/go.mod h1:9wOXstvyDRshQ9LggQuzBCGysxs3b6Uo/1MvYCR2NMs= -github.com/golangci/golangci-lint v1.49.0 h1:I8WHOavragDttlLHtSraHn/h39C+R60bEQ5NoGcHQr8= -github.com/golangci/golangci-lint v1.49.0/go.mod h1:+V/7lLv449R6w9mQ3WdV0EKh7Je/jTylMeSwBZcLeWE= +github.com/golangci/golangci-lint v1.54.1 h1:0qMrH1gkeIBqCZaaAm5Fwq4xys9rO/lJofHfZURIFFk= +github.com/golangci/golangci-lint v1.54.1/go.mod h1:JK47+qksV/t2mAz9YvndwT0ZLW4A1rvDljOs3g9jblo= github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0 h1:MfyDlzVjl1hoaPzPD4Gpb/QgoRfSBR0jdhwGyAWwMSA= github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0/go.mod h1:66R6K6P6VWk9I95jvqGxkqJxVWGFy9XlDwLwVz1RCFg= github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca h1:kNY3/svz5T29MYHubXix4aDDuE3RWHkPvopM/EDv/MA= github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca/go.mod h1:tvlJhZqDe4LMs4ZHD0oMUlt9G2LWuDGoisJTBzLMV9o= -github.com/golangci/misspell v0.3.5 h1:pLzmVdl3VxTOncgzHcvLOKirdvcx/TydsClUQXTehjo= -github.com/golangci/misspell v0.3.5/go.mod h1:dEbvlSfYbMQDtrpRMQU675gSDLDNa8sCPPChZ7PhiVA= +github.com/golangci/misspell v0.4.1 h1:+y73iSicVy2PqyX7kmUefHusENlrP9YwuHZHPLGQj/g= +github.com/golangci/misspell v0.4.1/go.mod h1:9mAN1quEo3DlpbaIKKyEvRxK1pwqR9s/Sea1bJCtlNI= github.com/golangci/revgrep v0.0.0-20220804021717-745bb2f7c2e6 h1:DIPQnGy2Gv2FSA4B/hh8Q7xx3B7AIDk3DAMeHclH1vQ= github.com/golangci/revgrep v0.0.0-20220804021717-745bb2f7c2e6/go.mod h1:0AKcRCkMoKvUvlf89F6O7H2LYdhr1zBh736mBItOdRs= github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4 h1:zwtduBRr5SSWhqsYNgcuWO2kFlpdOZbP0+yRjmvPGys= @@ -343,16 +348,12 @@ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5m github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c h1:7lF+Vz0LqiRidnzC1Oq86fpX1q/iEv2KJdrCtttYjT4= -github.com/gordonklaus/ineffassign v0.0.0-20210914165742-4cc7213b9bc8 h1:PVRE9d4AQKmbelZ7emNig1+NT27DUmKZn5qXxfio54U= -github.com/gordonklaus/ineffassign v0.0.0-20210914165742-4cc7213b9bc8/go.mod h1:Qcp2HIAYhR7mNUVSIxZww3Guk4it82ghYcEXIAk+QT0= +github.com/gordonklaus/ineffassign v0.0.0-20230610083614-0e73809eb601 h1:mrEEilTAUmaAORhssPPkxj84TsHrPMLBGW2Z4SoTxm8= +github.com/gordonklaus/ineffassign v0.0.0-20230610083614-0e73809eb601/go.mod h1:Qcp2HIAYhR7mNUVSIxZww3Guk4it82ghYcEXIAk+QT0= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE= -github.com/gostaticanalysis/analysisutil v0.0.3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE= -github.com/gostaticanalysis/analysisutil v0.1.0/go.mod h1:dMhHRU9KTiDcuLGdy87/2gTR8WruwYZrKdRq9m1O6uw= github.com/gostaticanalysis/analysisutil v0.7.1 h1:ZMCjoue3DtDWQ5WyU16YbjbQEQ3VuzwxALrpYd+HeKk= github.com/gostaticanalysis/analysisutil v0.7.1/go.mod h1:v21E3hY37WKMGSnbsw2S/ojApNWb6C1//mXO48CXbVc= -github.com/gostaticanalysis/comment v1.3.0/go.mod h1:xMicKDx7XRXYdVwY9f9wQpDJVnqWxw9wCauCMKp+IBI= github.com/gostaticanalysis/comment v1.4.1/go.mod h1:ih6ZxzTHLdadaiSnF5WY3dxUoXfXAlTaRzuaNDlSado= github.com/gostaticanalysis/comment v1.4.2 h1:hlnx5+S2fY9Zo9ePo4AhgYsYHbM2+eAv8m/s1JiCd6Q= github.com/gostaticanalysis/comment v1.4.2/go.mod h1:KLUTGDv6HOCotCH8h2erHKmpci2ZoR8VPu34YA2uzdM= @@ -391,8 +392,8 @@ github.com/huin/goupnp v1.2.0 h1:uOKW26NG1hsSSbXIZ1IR7XP9Gjd1U8pnLaCMgntmkmY= github.com/huin/goupnp v1.2.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= -github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= github.com/ipfs/boxo v0.11.1-0.20230818062747-654231b2bda3 h1:oiMqmivloEHtlCkS+8rCq1Pkz/rf6m3sC45lL4cnwBA= @@ -481,7 +482,6 @@ github.com/jingyugao/rowserrcheck v1.1.1 h1:zibz55j/MJtLsjP1OF4bSdgXxwL1b+Vn7Tjz github.com/jingyugao/rowserrcheck v1.1.1/go.mod h1:4yvlZSDb3IyDTUZJUmpZfm2Hwok+Dtp+nu2qOq+er9c= github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af h1:KA9BjwUk7KlCh6S9EAGWBt1oExIUv9WyNCiRz5amv48= github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af/go.mod h1:HEWGJkRDzjJY2sqdDwxccsGicWEf9BQOZsq2tV+xzM0= -github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jonboulle/clockwork v0.2.0 h1:J2SLSdy7HgElq8ekSl2Mxh6vrRNFxqbXGenYH2I02Vs= github.com/jonboulle/clockwork v0.2.0/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= @@ -500,10 +500,12 @@ github.com/julz/importas v0.1.0 h1:F78HnrsjY3cR7j0etXy5+TU1Zuy7Xt08X/1aJnH5xXY= github.com/julz/importas v0.1.0/go.mod h1:oSFU2R4XK/P7kNBrnL/FEQlDGN1/6WoxXEjSSXO0DV0= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= -github.com/kisielk/errcheck v1.6.2 h1:uGQ9xI8/pgc9iOoCe7kWQgRE6SBTrCGmTSf0LrEtY7c= -github.com/kisielk/errcheck v1.6.2/go.mod h1:nXw/i/MfnvRHqXa7XXmQMUB0oNFGuBrNI8d8NLy0LPw= +github.com/kisielk/errcheck v1.6.3 h1:dEKh+GLHcWm2oN34nMvDzn1sqI0i0WxPvrgiJA5JuM8= +github.com/kisielk/errcheck v1.6.3/go.mod h1:nXw/i/MfnvRHqXa7XXmQMUB0oNFGuBrNI8d8NLy0LPw= github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kkHAIKE/contextcheck v1.1.4 h1:B6zAaLhOEEcjvUgIYEqystmnFk1Oemn8bvJhbt0GMb8= +github.com/kkHAIKE/contextcheck v1.1.4/go.mod h1:1+i/gWqokIa+dm31mqGLZhZJ7Uh44DJGZVmr6QRBNJg= github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I= github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= @@ -522,20 +524,18 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kulti/thelper v0.6.3 h1:ElhKf+AlItIu+xGnI990no4cE2+XaSu1ULymV2Yulxs= github.com/kulti/thelper v0.6.3/go.mod h1:DsqKShOvP40epevkFrvIwkCMNYxMeTNjdWL4dqWHZ6I= -github.com/kunwardeep/paralleltest v1.0.6 h1:FCKYMF1OF2+RveWlABsdnmsvJrei5aoyZoaGS+Ugg8g= -github.com/kunwardeep/paralleltest v1.0.6/go.mod h1:Y0Y0XISdZM5IKm3TREQMZ6iteqn1YuwCsJO/0kL9Zes= -github.com/kyoh86/exportloopref v0.1.8 h1:5Ry/at+eFdkX9Vsdw3qU4YkvGtzuVfzT4X7S77LoN/M= -github.com/kyoh86/exportloopref v0.1.8/go.mod h1:1tUcJeiioIs7VWe5gcOObrux3lb66+sBqGZrRkMwPgg= +github.com/kunwardeep/paralleltest v1.0.8 h1:Ul2KsqtzFxTlSU7IP0JusWlLiNqQaloB9vguyjbE558= +github.com/kunwardeep/paralleltest v1.0.8/go.mod h1:2C7s65hONVqY7Q5Efj5aLzRCNLjw2h4eMc9EcypGjcY= +github.com/kyoh86/exportloopref v0.1.11 h1:1Z0bcmTypkL3Q4k+IDHMWTcnCliEZcaPiIe0/ymEyhQ= +github.com/kyoh86/exportloopref v0.1.11/go.mod h1:qkV4UF1zGl6EkF1ox8L5t9SwyeBAZ3qLMd6up458uqA= github.com/ldez/gomoddirectives v0.2.3 h1:y7MBaisZVDYmKvt9/l1mjNCiSA1BVn34U0ObUcJwlhA= github.com/ldez/gomoddirectives v0.2.3/go.mod h1:cpgBogWITnCfRq2qGoDkKMEVSaarhdBr6g8G04uz6d0= -github.com/ldez/tagliatelle v0.3.1 h1:3BqVVlReVUZwafJUwQ+oxbx2BEX2vUG4Yu/NOfMiKiM= -github.com/ldez/tagliatelle v0.3.1/go.mod h1:8s6WJQwEYHbKZDsp/LjArytKOG8qaMrKQQ3mFukHs88= -github.com/leonklingele/grouper v1.1.0 h1:tC2y/ygPbMFSBOs3DcyaEMKnnwH7eYKzohOtRrf0SAg= -github.com/leonklingele/grouper v1.1.0/go.mod h1:uk3I3uDfi9B6PeUjsCKi6ndcf63Uy7snXgR4yDYQVDY= -github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/ldez/tagliatelle v0.5.0 h1:epgfuYt9v0CG3fms0pEgIMNPuFf/LpPIfjk4kyqSioo= +github.com/ldez/tagliatelle v0.5.0/go.mod h1:rj1HmWiL1MiKQuOONhd09iySTEkUuE/8+5jtPYz9xa4= +github.com/leonklingele/grouper v1.1.1 h1:suWXRU57D4/Enn6pXR0QVqqWWrnJ9Osrz+5rjt8ivzU= +github.com/leonklingele/grouper v1.1.1/go.mod h1:uk3I3uDfi9B6PeUjsCKi6ndcf63Uy7snXgR4yDYQVDY= github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38yPW7c= @@ -564,34 +564,33 @@ github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo= github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/maratori/testpackage v1.1.0 h1:GJY4wlzQhuBusMF1oahQCBtUV/AQ/k69IZ68vxaac2Q= -github.com/maratori/testpackage v1.1.0/go.mod h1:PeAhzU8qkCwdGEMTEupsHJNlQu2gZopMC6RjbhmHeDc= +github.com/maratori/testableexamples v1.0.0 h1:dU5alXRrD8WKSjOUnmJZuzdxWOEQ57+7s93SLMxb2vI= +github.com/maratori/testableexamples v1.0.0/go.mod h1:4rhjL1n20TUTT4vdh3RDqSizKLyXp7K2u6HgraZCGzE= +github.com/maratori/testpackage v1.1.1 h1:S58XVV5AD7HADMmD0fNnziNHqKvSdDuEKdPD1rNTU04= +github.com/maratori/testpackage v1.1.1/go.mod h1:s4gRK/ym6AMrqpOa/kEbQTV4Q4jb7WeLZzVhVVVOQMc= 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/matoous/godox v0.0.0-20210227103229-6504466cf951 h1:pWxk9e//NbPwfxat7RXkts09K+dEBJWakUWwICVqYbA= -github.com/matoous/godox v0.0.0-20210227103229-6504466cf951/go.mod h1:1BELzlh859Sh1c6+90blK8lbYy0kwQf1bYlBhBysy1s= +github.com/matoous/godox v0.0.0-20230222163458-006bad1f9d26 h1:gWg6ZQ4JhDfJPqlo2srm/LN17lpybq15AryXIRcWYLE= +github.com/matoous/godox v0.0.0-20230222163458-006bad1f9d26/go.mod h1:1BELzlh859Sh1c6+90blK8lbYy0kwQf1bYlBhBysy1s= github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE= github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= -github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/mbilski/exhaustivestruct v1.2.0 h1:wCBmUnSYufAHO6J4AVWY6ff+oxWxsVFrwgOdMUQePUo= github.com/mbilski/exhaustivestruct v1.2.0/go.mod h1:OeTBVxQWoEmB2J2JCHmXWPJ0aksxSUOUy+nvtVEfzXc= -github.com/mgechev/revive v1.2.3 h1:NzIEEa9+WimQ6q2Ov7OcNeySS/IOcwtkQ8RAh0R5UJ4= -github.com/mgechev/revive v1.2.3/go.mod h1:iAWlQishqCuj4yhV24FTnKSXGpbAA+0SckXB8GQMX/Q= +github.com/mgechev/revive v1.3.2 h1:Wb8NQKBaALBJ3xrrj4zpwJwqwNA6nDpyJSEQWcCka6U= +github.com/mgechev/revive v1.3.2/go.mod h1:UCLtc7o5vg5aXCwdUTU1kEBQ1v+YXPAkYDIDXbrs5I0= github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= github.com/miekg/dns v1.1.55 h1:GoQ4hpsj0nFLYe+bWiCToyrBEJXkQfOOIvFGFy0lEgo= @@ -615,8 +614,8 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/moricho/tparallel v0.2.1 h1:95FytivzT6rYzdJLdtfn6m1bfFJylOJK41+lgv/EHf4= -github.com/moricho/tparallel v0.2.1/go.mod h1:fXEIZxG2vdfl0ZF8b42f5a78EhjjD5mX8qUplsoSU4k= +github.com/moricho/tparallel v0.3.1 h1:fQKD4U1wRMAYNngDonW5XupoB/ZGJHdpzrWqgyg9krA= +github.com/moricho/tparallel v0.3.1/go.mod h1:leENX2cUv7Sv2qDgdi0D0fCftN8fRC67Bcn8pqzeYNI= github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mr-tron/base58 v1.1.3/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= @@ -658,11 +657,12 @@ github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354 h1:4kuARK6Y6Fx github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354/go.mod h1:KSVJerMDfblTH7p5MZaTt+8zaT2iEk3AkVb9PQdZuE8= github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/nishanths/exhaustive v0.8.1 h1:0QKNascWv9qIHY7zRoZSxeRr6kuk5aAT3YXLTiDmjTo= -github.com/nishanths/exhaustive v0.8.1/go.mod h1:qj+zJJUgJ76tR92+25+03oYUhzF4R7/2Wk7fGTfCHmg= +github.com/nishanths/exhaustive v0.11.0 h1:T3I8nUGhl/Cwu5Z2hfc92l0e04D2GEW6e0l8pzda2l0= +github.com/nishanths/exhaustive v0.11.0/go.mod h1:RqwDsZ1xY0dNdqHho2z6X+bgzizwbLYOWnZbbl2wLB4= github.com/nishanths/predeclared v0.2.2 h1:V2EPdZPliZymNAn79T8RkNApBjMmVKh5XRpLm/w98Vk= github.com/nishanths/predeclared v0.2.2/go.mod h1:RROzoN6TnGQupbC+lqggsOlcgysk3LMK/HI84Mp280c= +github.com/nunnatsa/ginkgolinter v0.13.3 h1:wEvjrzSMfDdnoWkctignX9QTf4rT9f4GkQ3uVoXBmiU= +github.com/nunnatsa/ginkgolinter v0.13.3/go.mod h1:aTKXo8WddENYxNEFT+4ZxEgWXqlD9uMD3w9Bfw/ABEc= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -686,11 +686,9 @@ github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2D github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y= github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= -github.com/pelletier/go-toml/v2 v2.0.2 h1:+jQXlF3scKIcSEKkdHzXhCTDLPFi5r1wnK6yPS+49Gw= -github.com/pelletier/go-toml/v2 v2.0.2/go.mod h1:MovirKjgVRESsAvNZlAjtFwV867yGuwRkXbG66OzopI= +github.com/pelletier/go-toml/v2 v2.0.5 h1:ipoSadvV8oGUjnUbMub59IDPPwfxF694nG/jwbMiyQg= +github.com/pelletier/go-toml/v2 v2.0.5/go.mod h1:OMHamSCAODeSsVrwwvcJOaoN0LIUIaFVNZzmWyNfXas= github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 h1:1/WtZae0yGtPq+TI6+Tv1WTxkukpXeMlviSxvL7SRgk= -github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d h1:CdDQnGF8Nq9ocOS/xlSptM1N3BbrA6/kmaep5ggwaIA= -github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d/go.mod h1:3OzsM7FXDQlpCiw2j81fOmAwQLnZnLGXVKUzeKQXIAw= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -700,8 +698,8 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/polydawn/refmt v0.89.0 h1:ADJTApkvkeBZsN0tBTx8QjpD9JkmxbKp0cxfr9qszm4= github.com/polydawn/refmt v0.89.0/go.mod h1:/zvteZs/GwLtCgZ4BL6CBsk9IKIlexP43ObX9AxTqTw= -github.com/polyfloyd/go-errorlint v1.0.2 h1:kp1yvHflYhTmw5m3MmBy8SCyQkKPjwDthVuMH0ug6Yk= -github.com/polyfloyd/go-errorlint v1.0.2/go.mod h1:APVvOesVSAnne5SClsPxPdfvZTVDojXh1/G3qb5wjGI= +github.com/polyfloyd/go-errorlint v1.4.3 h1:P6NALOLV8BrWhm6PsqOraUK05E5h8IZnpXYJ+CIg+0U= +github.com/polyfloyd/go-errorlint v1.4.3/go.mod h1:VPlWPh6hB/wruVG803SuNpLuTGNjLHYlvcdSy4RhdPA= github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= @@ -731,17 +729,12 @@ github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1 github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.11.0 h1:5EAgkfkMl659uZPbe9AS2N68a7Cc1TJbPEuGzFuRbyk= github.com/prometheus/procfs v0.11.0/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM= -github.com/quasilyte/go-ruleguard v0.3.1-0.20210203134552-1b5a410e1cc8/go.mod h1:KsAh3x0e7Fkpgs+Q9pNLS5XpFSvYCEVl5gP9Pp1xp30= -github.com/quasilyte/go-ruleguard v0.3.17 h1:cDdoaSbQg11LXPDQqiCK54QmQXsEQQCTIgdcpeULGSI= -github.com/quasilyte/go-ruleguard v0.3.17/go.mod h1:sST5PvaR7yb/Az5ksX8oc88usJ4EGjmJv7cK7y3jyig= -github.com/quasilyte/go-ruleguard/dsl v0.3.0/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU= -github.com/quasilyte/go-ruleguard/dsl v0.3.21/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU= -github.com/quasilyte/go-ruleguard/rules v0.0.0-20201231183845-9e62ed36efe1/go.mod h1:7JTjp89EGyU1d6XfBiXihJNG37wB2VRkd125Q1u7Plc= -github.com/quasilyte/go-ruleguard/rules v0.0.0-20211022131956-028d6511ab71/go.mod h1:4cgAphtvu7Ftv7vOT2ZOYhC6CvBxZixcasr8qIOTA50= -github.com/quasilyte/gogrep v0.0.0-20220120141003-628d8b3623b5 h1:PDWGei+Rf2bBiuZIbZmM20J2ftEy9IeUCHA8HbQqed8= -github.com/quasilyte/gogrep v0.0.0-20220120141003-628d8b3623b5/go.mod h1:wSEyW6O61xRV6zb6My3HxrQ5/8ke7NE2OayqCHa3xRM= -github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95 h1:L8QM9bvf68pVdQ3bCFZMDmnt9yqcMBro1pC7F+IPYMY= -github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95/go.mod h1:rlzQ04UMyJXu/aOvhd8qT+hvDrFpiwqp8MRXDY9szc0= +github.com/quasilyte/go-ruleguard v0.4.0 h1:DyM6r+TKL+xbKB4Nm7Afd1IQh9kEUKQs2pboWGKtvQo= +github.com/quasilyte/go-ruleguard v0.4.0/go.mod h1:Eu76Z/R8IXtViWUIHkE3p8gdH3/PKk1eh3YGfaEof10= +github.com/quasilyte/gogrep v0.5.0 h1:eTKODPXbI8ffJMN+W2aE0+oL0z/nh8/5eNdiO34SOAo= +github.com/quasilyte/gogrep v0.5.0/go.mod h1:Cm9lpz9NZjEoL1tgZ2OgeUKPIxL1meE7eo60Z6Sk+Ng= +github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727 h1:TCg2WBOl980XxGFEZSS6KlBGIV0diGdySzxATTWoqaU= +github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727/go.mod h1:rlzQ04UMyJXu/aOvhd8qT+hvDrFpiwqp8MRXDY9szc0= github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 h1:M8mH9eK4OUR4lu7Gd+PU1fV2/qnDNfzT635KRSObncs= github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567/go.mod h1:DWNGW8A4Y+GyBgPuaQJuWiy0XYftx4Xm/y5Jqk9I6VQ= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= @@ -762,18 +755,18 @@ github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/ryancurrah/gomodguard v1.2.4 h1:CpMSDKan0LtNGGhPrvupAoLeObRFjND8/tU1rEOtBp4= -github.com/ryancurrah/gomodguard v1.2.4/go.mod h1:+Kem4VjWwvFpUJRJSwa16s1tBJe+vbv02+naTow2f6M= -github.com/ryanrolds/sqlclosecheck v0.3.0 h1:AZx+Bixh8zdUBxUA1NxbxVAS78vTPq4rCb8OUZI9xFw= -github.com/ryanrolds/sqlclosecheck v0.3.0/go.mod h1:1gREqxyTGR3lVtpngyFo3hZAgk0KCtEdgEkHwDbigdA= -github.com/sanposhiho/wastedassign/v2 v2.0.6 h1:+6/hQIHKNJAUixEj6EmOngGIisyeI+T3335lYTyxRoA= -github.com/sanposhiho/wastedassign/v2 v2.0.6/go.mod h1:KyZ0MWTwxxBmfwn33zh3k1dmsbF2ud9pAAGfoLfjhtI= +github.com/ryancurrah/gomodguard v1.3.0 h1:q15RT/pd6UggBXVBuLps8BXRvl5GPBcwVA7BJHMLuTw= +github.com/ryancurrah/gomodguard v1.3.0/go.mod h1:ggBxb3luypPEzqVtq33ee7YSN35V28XeGnid8dnni50= +github.com/ryanrolds/sqlclosecheck v0.4.0 h1:i8SX60Rppc1wRuyQjMciLqIzV3xnoHB7/tXbr6RGYNI= +github.com/ryanrolds/sqlclosecheck v0.4.0/go.mod h1:TBRRjzL31JONc9i4XMinicuo+s+E8yKZ5FN8X3G6CKQ= +github.com/sanposhiho/wastedassign/v2 v2.0.7 h1:J+6nrY4VW+gC9xFzUc+XjPD3g3wF3je/NsJFwFK7Uxc= +github.com/sanposhiho/wastedassign/v2 v2.0.7/go.mod h1:KyZ0MWTwxxBmfwn33zh3k1dmsbF2ud9pAAGfoLfjhtI= github.com/sashamelentyev/interfacebloat v1.1.0 h1:xdRdJp0irL086OyW1H/RTZTr1h/tMEOsumirXcOJqAw= github.com/sashamelentyev/interfacebloat v1.1.0/go.mod h1:+Y9yU5YdTkrNvoX0xHc84dxiN1iBi9+G8zZIhPVoNjQ= -github.com/sashamelentyev/usestdlibvars v1.13.0 h1:uObNudVEEHf6JbOJy5bgKJloA1bWjxR9fwgNFpPzKnI= -github.com/sashamelentyev/usestdlibvars v1.13.0/go.mod h1:D2Wb7niIYmTB+gB8z7kh8tyP5ccof1dQ+SFk+WW5NtY= -github.com/securego/gosec/v2 v2.13.1 h1:7mU32qn2dyC81MH9L2kefnQyRMUarfDER3iQyMHcjYM= -github.com/securego/gosec/v2 v2.13.1/go.mod h1:EO1sImBMBWFjOTFzMWfTRrZW6M15gm60ljzrmy/wtHo= +github.com/sashamelentyev/usestdlibvars v1.23.0 h1:01h+/2Kd+NblNItNeux0veSL5cBF1jbEOPrEhDzGYq0= +github.com/sashamelentyev/usestdlibvars v1.23.0/go.mod h1:YPwr/Y1LATzHI93CqoPUN/2BzGQ/6N/cl/KwgR0B/aU= +github.com/securego/gosec/v2 v2.16.0 h1:Pi0JKoasQQ3NnoRao/ww/N/XdynIB9NRYYZT5CyOs5U= +github.com/securego/gosec/v2 v2.16.0/go.mod h1:xvLcVZqUfo4aAQu56TNv7/Ltz6emAOQAEsrZrt7uGlI= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c h1:W65qqJCIOVP4jpqPQ0YvHYKwcMEMVWIzWC5iNQQfBTU= github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c/go.mod h1:/PevMnwAxekIXwN8qQyfc5gl2NlkB3CQlkizAbOkeBs= @@ -805,23 +798,23 @@ github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPx 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/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= -github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/sivchari/containedctx v1.0.2 h1:0hLQKpgC53OVF1VT7CeoFHk9YKstur1XOgfYIc1yrHI= -github.com/sivchari/containedctx v1.0.2/go.mod h1:PwZOeqm4/DLoJOqMSIJs3aKqXRX4YO+uXww087KZ7Bw= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/sivchari/containedctx v1.0.3 h1:x+etemjbsh2fB5ewm5FeLNi5bUjK0V8n0RB+Wwfd0XE= +github.com/sivchari/containedctx v1.0.3/go.mod h1:c1RDvCbnJLtH4lLcYD/GqwiBSSf4F5Qk0xld2rBqzJ4= github.com/sivchari/nosnakecase v1.7.0 h1:7QkpWIRMe8x25gckkFd2A5Pi6Ymo0qgr4JrhGt95do8= github.com/sivchari/nosnakecase v1.7.0/go.mod h1:CwDzrzPea40/GB6uynrNLiorAlgFRvRbFSgJx2Gs+QY= -github.com/sivchari/tenv v1.7.0 h1:d4laZMBK6jpe5PWepxlV9S+LC0yXqvYHiq8E6ceoVVE= -github.com/sivchari/tenv v1.7.0/go.mod h1:64yStXKSOxDfX47NlhVwND4dHwfZDdbp2Lyl018Icvg= +github.com/sivchari/tenv v1.7.1 h1:PSpuD4bu6fSmtWMxSGWcvqUUgIn7k3yOJhOIzVWn8Ak= +github.com/sivchari/tenv v1.7.1/go.mod h1:64yStXKSOxDfX47NlhVwND4dHwfZDdbp2Lyl018Icvg= github.com/smartystreets/assertions v1.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N3yZFZkDFs= github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo= github.com/smartystreets/goconvey v1.7.2 h1:9RBaZCeXEQ3UselpuwUQHltGVXvdwm6cv1hgR6gDIPg= github.com/smartystreets/goconvey v1.7.2/go.mod h1:Vw0tHAZW6lzCRk3xgdin6fKYcG+G3Pg9vgXWeJpQFMM= -github.com/sonatard/noctx v0.0.1 h1:VC1Qhl6Oxx9vvWo3UDgrGXYCeKCe3Wbw7qAWL6FrmTY= -github.com/sonatard/noctx v0.0.1/go.mod h1:9D2D/EoULe8Yy2joDHJj7bv3sZoq9AaSb8B4lqBjiZI= +github.com/sonatard/noctx v0.0.2 h1:L7Dz4De2zDQhW8S0t+KUjY0MAQJd6SgVwhzNIc4ok00= +github.com/sonatard/noctx v0.0.2/go.mod h1:kzFz+CzWSjQ2OzIm46uJZoXuBpa2+0y3T36U18dWqIo= github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE= -github.com/sourcegraph/go-diff v0.6.1 h1:hmA1LzxW0n1c3Q4YbrFgg4P99GSnebYa3x8gr0HZqLQ= -github.com/sourcegraph/go-diff v0.6.1/go.mod h1:iBszgVvyxdc8SFZ7gm69go2KDdt3ag071iBaWPF6cjs= +github.com/sourcegraph/go-diff v0.7.0 h1:9uLlrd5T46OXs5qpp8L/MTltk0zikUGi0sNNyCpA8G0= +github.com/sourcegraph/go-diff v0.7.0/go.mod h1:iBszgVvyxdc8SFZ7gm69go2KDdt3ag071iBaWPF6cjs= github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= @@ -829,8 +822,8 @@ github.com/spf13/afero v1.8.2 h1:xehSyVa0YnHWsJ49JFljMpg1HX19V6NDZ1fkm1Xznbo= github.com/spf13/afero v1.8.2/go.mod h1:CtAatgMJh6bJEIs48Ay/FOnkljP3WeGUG0MC1RfAqwo= github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= -github.com/spf13/cobra v1.5.0 h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU= -github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM= +github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= +github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= @@ -855,41 +848,41 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/subosito/gotenv v1.4.0 h1:yAzM1+SmVcz5R4tXGsNMu1jUl2aOJXoiWUCEwwnGrvs= -github.com/subosito/gotenv v1.4.0/go.mod h1:mZd6rFysKEcUhUHXJk0C/08wAgyDBFuwEYL7vWWGaGo= -github.com/sylvia7788/contextcheck v1.0.6 h1:o2EZgVPyMKE/Mtoqym61DInKEjwEbsmyoxg3VrmjNO4= -github.com/sylvia7788/contextcheck v1.0.6/go.mod h1:9XDxwvxyuKD+8N+a7Gs7bfWLityh5t70g/GjdEt2N2M= +github.com/subosito/gotenv v1.4.1 h1:jyEFiXpy21Wm81FBN71l9VoMMV8H8jG+qIK3GCpY6Qs= +github.com/subosito/gotenv v1.4.1/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= +github.com/t-yuki/gocover-cobertura v0.0.0-20180217150009-aaee18c8195c h1:+aPplBwWcHBo6q9xrfWdMrT9o4kltkmmvpemgIjep/8= +github.com/t-yuki/gocover-cobertura v0.0.0-20180217150009-aaee18c8195c/go.mod h1:SbErYREK7xXdsRiigaQiQkI9McGRzYMvlKYaP3Nimdk= github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= -github.com/tdakkota/asciicheck v0.1.1 h1:PKzG7JUTUmVspQTDqtkX9eSiLGossXTybutHwTXuO0A= -github.com/tdakkota/asciicheck v0.1.1/go.mod h1:yHp0ai0Z9gUljN3o0xMhYJnH/IcvkdTBOX2fmJ93JEM= +github.com/tdakkota/asciicheck v0.2.0 h1:o8jvnUANo0qXtnslk2d3nMKTFNlOnJjRrNcj0j9qkHM= +github.com/tdakkota/asciicheck v0.2.0/go.mod h1:Qb7Y9EgjCLJGup51gDHFzbI08/gbGhL/UVhYIPWG2rg= github.com/tenntenn/modver v1.0.1 h1:2klLppGhDgzJrScMpkj9Ujy3rXPUspSjAcev9tSEBgA= github.com/tenntenn/modver v1.0.1/go.mod h1:bePIyQPb7UeioSRkw3Q0XeMhYZSMx9B8ePqg6SAMGH0= github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3 h1:f+jULpRQGxTSkNYKJ51yaw6ChIqO+Je8UqsTKN/cDag= github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3/go.mod h1:ON8b8w4BN/kE1EOhwT0o+d62W65a6aPw1nouo9LMgyY= github.com/tetafro/godot v1.4.11 h1:BVoBIqAf/2QdbFmSwAWnaIqDivZdOV0ZRwEm6jivLKw= github.com/tetafro/godot v1.4.11/go.mod h1:LR3CJpxDVGlYOWn3ZZg1PgNZdTUvzsZWu8xaEohUpn8= -github.com/timakin/bodyclose v0.0.0-20210704033933-f49887972144 h1:kl4KhGNsJIbDHS9/4U9yQo1UcPQM0kOMJHn29EoH/Ro= -github.com/timakin/bodyclose v0.0.0-20210704033933-f49887972144/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk= -github.com/timonwong/logrlint v0.1.0 h1:phZCcypL/vtx6cGxObJgWZ5wexZF5SXFPLOM+ru0e/M= -github.com/timonwong/logrlint v0.1.0/go.mod h1:Zleg4Gw+kRxNej+Ra7o+tEaW5k1qthTaYKU7rSD39LU= -github.com/tomarrell/wrapcheck/v2 v2.6.2 h1:3dI6YNcrJTQ/CJQ6M/DUkc0gnqYSIk6o0rChn9E/D0M= -github.com/tomarrell/wrapcheck/v2 v2.6.2/go.mod h1:ao7l5p0aOlUNJKI0qVwB4Yjlqutd0IvAB9Rdwyilxvg= -github.com/tommy-muehle/go-mnd/v2 v2.5.0 h1:iAj0a8e6+dXSL7Liq0aXPox36FiN1dBbjA6lt9fl65s= -github.com/tommy-muehle/go-mnd/v2 v2.5.0/go.mod h1:WsUAkMJMYww6l/ufffCD3m+P7LEvr8TnZn9lwVDlgzw= -github.com/ultraware/funlen v0.0.3 h1:5ylVWm8wsNwH5aWo9438pwvsK0QiqVuUrt9bn7S/iLA= -github.com/ultraware/funlen v0.0.3/go.mod h1:Dp4UiAus7Wdb9KUZsYWZEWiRzGuM2kXM1lPbfaF6xhA= +github.com/timakin/bodyclose v0.0.0-20230421092635-574207250966 h1:quvGphlmUVU+nhpFa4gg4yJyTRJ13reZMDHrKwYw53M= +github.com/timakin/bodyclose v0.0.0-20230421092635-574207250966/go.mod h1:27bSVNWSBOHm+qRp1T9qzaIpsWEP6TbUnei/43HK+PQ= +github.com/timonwong/loggercheck v0.9.4 h1:HKKhqrjcVj8sxL7K77beXh0adEm6DLjV/QOGeMXEVi4= +github.com/timonwong/loggercheck v0.9.4/go.mod h1:caz4zlPcgvpEkXgVnAJGowHAMW2NwHaNlpS8xDbVhTg= +github.com/tomarrell/wrapcheck/v2 v2.8.1 h1:HxSqDSN0sAt0yJYsrcYVoEeyM4aI9yAm3KQpIXDJRhQ= +github.com/tomarrell/wrapcheck/v2 v2.8.1/go.mod h1:/n2Q3NZ4XFT50ho6Hbxg+RV1uyo2Uow/Vdm9NQcl5SE= +github.com/tommy-muehle/go-mnd/v2 v2.5.1 h1:NowYhSdyE/1zwK9QCLeRb6USWdoif80Ie+v+yU8u1Zw= +github.com/tommy-muehle/go-mnd/v2 v2.5.1/go.mod h1:WsUAkMJMYww6l/ufffCD3m+P7LEvr8TnZn9lwVDlgzw= +github.com/ultraware/funlen v0.1.0 h1:BuqclbkY6pO+cvxoq7OsktIXZpgBSkYTQtmwhAK81vI= +github.com/ultraware/funlen v0.1.0/go.mod h1:XJqmOQja6DpxarLj6Jj1U7JuoS8PvL4nEqDaQhy22p4= github.com/ultraware/whitespace v0.0.5 h1:hh+/cpIcopyMYbZNVov9iSxvJU3OYQg78Sfaqzi/CzI= github.com/ultraware/whitespace v0.0.5/go.mod h1:aVMh/gQve5Maj9hQ/hg+F75lr/X5A89uZnzAmWSineA= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.10 h1:p8Fspmz3iTctJstry1PYS3HVdllxnEzTEsgIgtxTrCk= github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/uudashr/gocognit v1.0.6 h1:2Cgi6MweCsdB6kpcVQp7EW4U23iBFQWfTXiWlyp842Y= -github.com/uudashr/gocognit v1.0.6/go.mod h1:nAIUuVBnYU7pcninia3BHOvQkpQCeO76Uscky5BOwcY= +github.com/uudashr/gocognit v1.0.7 h1:e9aFXgKgUJrQ5+bs61zBigmj7bFJ/5cC6HmMahVzuDo= +github.com/uudashr/gocognit v1.0.7/go.mod h1:nAIUuVBnYU7pcninia3BHOvQkpQCeO76Uscky5BOwcY= github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU= github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM= github.com/warpfork/go-testmark v0.11.0 h1:J6LnV8KpceDvo7spaNU4+DauH2n1x+6RaO2rJrmpQ9U= @@ -898,10 +891,14 @@ github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0/go.mod h1:x6AKhvS github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11 h1:5HZfQkwe0mIfyDmc1Em5GqlNRzcdtlv4HTNmdpt7XH0= github.com/whyrusleeping/cbor-gen v0.0.0-20230126041949-52956bd4c9aa h1:EyA027ZAkuaCLoxVX4r1TZMPy1d31fM6hbfQ4OU4I5o= github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f h1:jQa4QT2UP9WYv2nzyawpKMOCl+Z/jW7djv2/J50lj9E= +github.com/xen0n/gosmopolitan v1.2.1 h1:3pttnTuFumELBRSh+KQs1zcz4fN6Zy7aB0xlnQSn1Iw= +github.com/xen0n/gosmopolitan v1.2.1/go.mod h1:JsHq/Brs1o050OOdmzHeOr0N7OtlnKRAGAsElF8xBQA= github.com/yagipy/maintidx v1.0.0 h1:h5NvIsCz+nRDapQ0exNv4aJ0yXSI0420omVANTv3GJM= github.com/yagipy/maintidx v1.0.0/go.mod h1:0qNf/I/CCZXSMhsRsrEPDZ+DkekpKLXAJfsTACwgXLk= github.com/yeya24/promlinter v0.2.0 h1:xFKDQ82orCU5jQujdaD8stOHiv8UN68BSdn2a8u8Y3o= github.com/yeya24/promlinter v0.2.0/go.mod h1:u54lkmBOZrpEbQQ6gox2zWKKLKu2SGe+2KOiextY+IA= +github.com/ykadowak/zerologlint v0.1.3 h1:TLy1dTW3Nuc+YE3bYRPToG1Q9Ej78b5UUN6bjbGdxPE= +github.com/ykadowak/zerologlint v0.1.3/go.mod h1:KaUskqF3e/v59oPmdq1U1DnKcuHokl2/K1U4pmIELKg= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -909,8 +906,9 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -gitlab.com/bosi/decorder v0.2.3 h1:gX4/RgK16ijY8V+BRQHAySfQAb354T7/xQpDB2n10P0= -gitlab.com/bosi/decorder v0.2.3/go.mod h1:9K1RB5+VPNQYtXtTDAzd2OEftsZb1oV0IrJrzChSdGE= +gitlab.com/bosi/decorder v0.4.0 h1:HWuxAhSxIvsITcXeP+iIRg9d1cVfvVkmlF7M68GaoDY= +gitlab.com/bosi/decorder v0.4.0/go.mod h1:xarnteyUoJiOTEldDysquWKTVDCKo2TOIOIibSuWqOg= +go-simpler.org/assert v0.5.0 h1:+5L/lajuQtzmbtEfh69sr5cRf2/xZzyJhFjoOz/PPqs= go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= @@ -925,6 +923,8 @@ go.opentelemetry.io/otel/metric v1.16.0/go.mod h1:QE47cpOmkwipPiefDwo2wDzwJrlfxx go.opentelemetry.io/otel/sdk v1.16.0 h1:Z1Ok1YsijYL0CSJpHt4cS3wDDh7p572grzNrBMiMWgE= go.opentelemetry.io/otel/trace v1.16.0 h1:8JRpaObFoW0pxuVPapkgH8UhHQj+bJW8jJsCZEu5MQs= go.opentelemetry.io/otel/trace v1.16.0/go.mod h1:Yt9vYq1SdNz3xdjZZK7wcXv1qv2pwLkqr2QVwea0ef0= +go.tmz.dev/musttag v0.7.1 h1:9lFmeSFnFfPuMq4IksHGomItE6NgKMNW2Nt2FPOhCfU= +go.tmz.dev/musttag v0.7.1/go.mod h1:oJLkpR56EsIryktZJk/B0IroSMi37YWver47fibGh5U= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= @@ -960,8 +960,9 @@ golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA= -golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= +golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= +golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk= +golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -975,8 +976,9 @@ golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMk golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 h1:MGwJjxBy0HJshjDNfLsYO8xppfqWlA5ZT9OhtUUhTNw= golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= golang.org/x/exp/typeparams v0.0.0-20220428152302-39d4317da171/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= -golang.org/x/exp/typeparams v0.0.0-20220613132600-b0d781184e0d h1:+W8Qf4iJtMGKkyAygcKohjxTk4JPsL9DpzApJ22m5Ic= -golang.org/x/exp/typeparams v0.0.0-20220613132600-b0d781184e0d/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= +golang.org/x/exp/typeparams v0.0.0-20230203172020-98cc5a0785f9/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= +golang.org/x/exp/typeparams v0.0.0-20230307190834-24139beb5833 h1:jWGQJV4niP+CCmFW9ekjA9Zx8vYORzOUH2/Nl5WPuLQ= +golang.org/x/exp/typeparams v0.0.0-20230307190834-24139beb5833/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1005,6 +1007,9 @@ golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= +golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1049,8 +1054,12 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50= -golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= +golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14= +golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1076,6 +1085,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/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1100,7 +1110,6 @@ golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 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= @@ -1142,14 +1151,21 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= -golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.10.0 h1:3R7pNqamzBraeqj/Tj8qt1aQ2HpmlC+Cx/qL/7hn4/c= -golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= +golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.11.0 h1:F9tnn/DA/Im8nCwm+fX+1/eBwi4qFjRT++MhtVC4ZX0= +golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1158,26 +1174,25 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4= -golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc= +golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190307163923-6a08e3108db3/go.mod h1:25r3+/G6/xytQM8iWZKq3Hn0kr0rgFKPUNVEL/dr3z4= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190311215038-5c2858a9cfe5/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190321232350-e250d351ecad/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190322203728-c1a832b0ad89/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= @@ -1189,7 +1204,6 @@ golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgw golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190910044552-dd2b5c81c578/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190916130336-e45ffcd953cc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -1202,7 +1216,6 @@ golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200117220505-0cba7a3a9ee9/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= @@ -1215,30 +1228,22 @@ golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjs golang.org/x/tools v0.0.0-20200324003944-a576cf524670/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= golang.org/x/tools v0.0.0-20200329025819-fd4102a86c65/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= -golang.org/x/tools v0.0.0-20200414032229-332987a829c3/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200622203043-20e05c1c8ffa/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200624225443-88f3c62a19ff/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200625211823-6506e20df31f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200724022722-7017fd6b1305/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200812195022-5ae4c3c160a0/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200820010801-b793a1359eac/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200831203904-5a2aa26beb65/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= golang.org/x/tools v0.0.0-20201001104356-43ebab892c4c/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= -golang.org/x/tools v0.0.0-20201002184944-ecd9fd270d5d/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= golang.org/x/tools v0.0.0-20201023174141-c8cfbd0f21e6/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201230224404-63754364767c/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= @@ -1247,13 +1252,16 @@ golang.org/x/tools v0.1.1-0.20210205202024-ef80cdb6ec6d/go.mod h1:9bzcO0MWcOuT0t golang.org/x/tools v0.1.1-0.20210302220138-2ac05c832e1a/go.mod h1:9bzcO0MWcOuT0tm1iBGzDVPshzfwoVvREIui8C+MHqU= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.9-0.20211228192929-ee1ca4ffc4da/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/tools v0.1.11/go.mod h1:SgwaegtQh8clINPpECJMqnxLv9I09HLqnW3RMqW0CA4= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.11.0 h1:EMCa6U9S2LtZXLAMoWiR/R8dAQFRqbAitmbJ2UKhoi8= -golang.org/x/tools v0.11.0/go.mod h1:anzJrxPjNtfgiYQYirP2CPGzGLxrH2u2QBhn6Bf3qY8= +golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= +golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= +golang.org/x/tools v0.5.0/go.mod h1:N+Kgy78s5I24c24dU8OfWNEotWjutIs8SnJvn5IDq+k= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.12.0 h1:YW6HUoUmYBpwSgyaGaZq1fHjrBjX1rlpZ54T6mu2kss= +golang.org/x/tools v0.12.0/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1368,15 +1376,14 @@ gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLks gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/ini.v1 v1.66.6 h1:LATuAqN/shcYAOkv3wl2L4rkaKqkcgTBQjOyYDvcPKI= -gopkg.in/ini.v1 v1.66.6/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= +gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -1403,18 +1410,18 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.3.3 h1:oDx7VAwstgpYpb3wv0oxiZlxY+foCpRAwY7Vk6XpAgA= -honnef.co/go/tools v0.3.3/go.mod h1:jzwdWgg7Jdq75wlfblQxO4neNaFFSvgc1tD5Wv8U0Yw= +honnef.co/go/tools v0.4.3 h1:o/n5/K5gXqk8Gozvs2cnL0F2S1/g1vcGCAx2vETjITw= +honnef.co/go/tools v0.4.3/go.mod h1:36ZgoUOrqOk1GxwHhyryEkq8FQWkUO2xGuSMhUCcdvA= lukechampine.com/blake3 v1.2.1 h1:YuqqRuaqsGV71BV/nm9xlI0MKUv4QC54jQnBChWbGnI= lukechampine.com/blake3 v1.2.1/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= -mvdan.cc/gofumpt v0.3.1 h1:avhhrOmv0IuvQVK7fvwV91oFSGAk5/6Po8GXTzICeu8= -mvdan.cc/gofumpt v0.3.1/go.mod h1:w3ymliuxvzVx8DAutBnVyDqYb1Niy/yCJt/lk821YCE= +mvdan.cc/gofumpt v0.5.0 h1:0EQ+Z56k8tXjj/6TQD25BFNKQXpCvT0rnansIc7Ug5E= +mvdan.cc/gofumpt v0.5.0/go.mod h1:HBeVDtMKRZpXyxFciAirzdKklDlGu8aAy1wEbH5Y9js= mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed h1:WX1yoOaKQfddO/mLzdV4wptyWgoH/6hwLs7QHTixo0I= mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc= mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b h1:DxJ5nJdkhDlLok9K6qO+5290kphDJbHOQO1DFFFTeBo= mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4= -mvdan.cc/unparam v0.0.0-20220706161116-678bad134442 h1:seuXWbRB1qPrS3NQnHmFKLJLtskWyueeIzmLXghMGgk= -mvdan.cc/unparam v0.0.0-20220706161116-678bad134442/go.mod h1:F/Cxw/6mVrNKqrR2YjFf5CaW0Bw4RL8RfbEf4GRggJk= +mvdan.cc/unparam v0.0.0-20221223090309-7455f1af531d h1:3rvTIIM22r9pvXk+q3swxUQAQOxksVMGK7sml4nG57w= +mvdan.cc/unparam v0.0.0-20221223090309-7455f1af531d/go.mod h1:IeHQjmn6TOD+e4Z3RFiZMMsLVL+A96Nvptar8Fj71is= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= From 5e9bad98040d24df2ec29e8f87add881d6d7c0d9 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Tue, 15 Aug 2023 15:57:42 +0200 Subject: [PATCH 0831/1212] fix: open /dev/null with read write permissions The way we create the kubo binary for coverage is very hacky. It uses the testing tool. In order to simulate a Kubo binary, we need to supress all the output that would otherwise be printed by 'go test'. So far, we were setting os.Stdout and os.Stderr as a read-only /dev/null file descriptor. This is causing issues with the new versions of Go: error generating coverage report: write /dev/null: bad file descriptor exit status 2 Updating it to a Read-Write file descriptor solves the problem. I did not try looking into what is causing this issue now. There have been some updates to the 'go test' tool in Go 1.20 and it is likely that some error is now being checked for that hasn't been checked before. Writing to a read-only file descriptor always failed. But the error was just supressed somehow. --- cmd/ipfs/runmain_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/ipfs/runmain_test.go b/cmd/ipfs/runmain_test.go index 4d73cfd43..c9f3f0198 100644 --- a/cmd/ipfs/runmain_test.go +++ b/cmd/ipfs/runmain_test.go @@ -24,7 +24,7 @@ func TestRunMain(t *testing.T) { } // close outputs so go testing doesn't print anything - null, _ := os.Open(os.DevNull) + null, _ := os.OpenFile(os.DevNull, os.O_RDWR, 0755) os.Stderr = null os.Stdout = null } From 1e5ce936596c3404f7a2890ea1827ae743de5fc0 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Tue, 15 Aug 2023 15:11:19 +0200 Subject: [PATCH 0832/1212] fix: use %-encoded headers in most compatible way --- client/rpc/api.go | 59 +++++++++++++++++++--- client/rpc/requestbuilder.go | 33 +++++++++--- client/rpc/unixfs.go | 8 ++- cmd/ipfs/main.go | 59 +++++++++++++++++++++- docs/changelogs/v0.23.md | 16 ++++++ docs/examples/kubo-as-a-library/go.mod | 4 +- docs/examples/kubo-as-a-library/go.sum | 12 ++--- go.mod | 9 ++-- go.sum | 22 ++++---- test/cli/content_routing_http_test.go | 10 ++++ test/dependencies/go.mod | 4 +- test/dependencies/go.sum | 12 ++--- test/sharness/t0235-cli-request.sh | 17 ++++++- test/sharness/t0236-cli-api-dns-resolve.sh | 17 ++++++- 14 files changed, 233 insertions(+), 49 deletions(-) diff --git a/client/rpc/api.go b/client/rpc/api.go index cb791e7ee..c00f6b598 100644 --- a/client/rpc/api.go +++ b/client/rpc/api.go @@ -1,18 +1,24 @@ package rpc import ( + "context" + "encoding/json" "errors" "fmt" "net/http" "os" "path/filepath" "strings" + "sync" + "time" + "github.com/blang/semver/v4" iface "github.com/ipfs/boxo/coreiface" caopts "github.com/ipfs/boxo/coreiface/options" "github.com/ipfs/boxo/ipld/merkledag" "github.com/ipfs/go-cid" legacy "github.com/ipfs/go-ipld-legacy" + ipfs "github.com/ipfs/kubo" dagpb "github.com/ipld/go-codec-dagpb" _ "github.com/ipld/go-ipld-prime/codec/dagcbor" "github.com/ipld/go-ipld-prime/node/basicnode" @@ -42,6 +48,8 @@ type HttpApi struct { Headers http.Header applyGlobal func(*requestBuilder) ipldDecoder *legacy.Decoder + versionMu sync.Mutex + version *semver.Version } // NewLocalApi tries to construct new HttpApi instance communicating with local @@ -151,6 +159,7 @@ func NewURLApiWithClient(url string, c *http.Client) (*HttpApi, error) { api.httpcli.CheckRedirect = func(_ *http.Request, _ []*http.Request) error { return fmt.Errorf("unexpected redirect") } + return api, nil } @@ -160,14 +169,19 @@ func (api *HttpApi) WithOptions(opts ...caopts.ApiOption) (iface.CoreAPI, error) return nil, err } - subApi := *api - subApi.applyGlobal = func(req *requestBuilder) { - if options.Offline { - req.Option("offline", options.Offline) - } + subApi := &HttpApi{ + url: api.url, + httpcli: api.httpcli, + Headers: api.Headers, + applyGlobal: func(req *requestBuilder) { + if options.Offline { + req.Option("offline", options.Offline) + } + }, + ipldDecoder: api.ipldDecoder, } - return &subApi, nil + return subApi, nil } func (api *HttpApi) Request(command string, args ...string) RequestBuilder { @@ -228,3 +242,36 @@ func (api *HttpApi) PubSub() iface.PubSubAPI { func (api *HttpApi) Routing() iface.RoutingAPI { return (*RoutingAPI)(api) } + +func (api *HttpApi) loadRemoteVersion() (*semver.Version, error) { + api.versionMu.Lock() + defer api.versionMu.Unlock() + + if api.version == nil { + ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(time.Second*30)) + defer cancel() + + resp, err := api.Request("version").Send(ctx) + if err != nil { + return nil, err + } + if resp.Error != nil { + return nil, resp.Error + } + defer resp.Close() + var out ipfs.VersionInfo + dec := json.NewDecoder(resp.Output) + if err := dec.Decode(&out); err != nil { + return nil, err + } + + remoteVersion, err := semver.New(out.Version) + if err != nil { + return nil, err + } + + api.version = remoteVersion + } + + return api.version, nil +} diff --git a/client/rpc/requestbuilder.go b/client/rpc/requestbuilder.go index 63206be40..e060c19b4 100644 --- a/client/rpc/requestbuilder.go +++ b/client/rpc/requestbuilder.go @@ -8,6 +8,7 @@ import ( "strconv" "strings" + "github.com/blang/semver/v4" "github.com/ipfs/boxo/files" ) @@ -23,13 +24,18 @@ type RequestBuilder interface { Exec(ctx context.Context, res interface{}) error } +// encodedAbsolutePathVersion is the version from which the absolute path header in +// multipart requests is %-encoded. Before this version, its sent raw. +var encodedAbsolutePathVersion = semver.MustParse("0.23.0-dev") + // requestBuilder is an IPFS commands request builder. type requestBuilder struct { - command string - args []string - opts map[string]string - headers map[string]string - body io.Reader + command string + args []string + opts map[string]string + headers map[string]string + body io.Reader + buildError error shell *HttpApi } @@ -60,7 +66,18 @@ func (r *requestBuilder) Body(body io.Reader) RequestBuilder { func (r *requestBuilder) FileBody(body io.Reader) RequestBuilder { pr, _ := files.NewReaderPathFile("/dev/stdin", io.NopCloser(body), nil) d := files.NewMapDirectory(map[string]files.Node{"": pr}) - r.body = files.NewMultiFileReader(d, false) + + version, err := r.shell.loadRemoteVersion() + if err != nil { + // Unfortunately, we cannot return an error here. Changing this API is also + // not the best since we would otherwise have an inconsistent RequestBuilder. + // We save the error and return it when calling [requestBuilder.Send]. + r.buildError = err + return r + } + + useEncodedAbsPaths := version.LT(encodedAbsolutePathVersion) + r.body = files.NewMultiFileReader(d, false, useEncodedAbsPaths) return r } @@ -97,6 +114,10 @@ func (r *requestBuilder) Header(name, value string) RequestBuilder { // Send sends the request and return the response. func (r *requestBuilder) Send(ctx context.Context) (*Response, error) { + if r.buildError != nil { + return nil, r.buildError + } + r.shell.applyGlobal(r) req := NewRequest(ctx, r.shell.url, r.command, r.args...) diff --git a/client/rpc/unixfs.go b/client/rpc/unixfs.go index 2099f190b..e19deec22 100644 --- a/client/rpc/unixfs.go +++ b/client/rpc/unixfs.go @@ -62,7 +62,13 @@ func (api *UnixfsAPI) Add(ctx context.Context, f files.Node, opts ...caopts.Unix } d := files.NewMapDirectory(map[string]files.Node{"": f}) // unwrapped on the other side - req.Body(files.NewMultiFileReader(d, false)) + + version, err := api.core().loadRemoteVersion() + if err != nil { + return nil, err + } + useEncodedAbsPaths := version.LT(encodedAbsolutePathVersion) + req.Body(files.NewMultiFileReader(d, false, useEncodedAbsPaths)) var out addEvent resp, err := req.Send(ctx) diff --git a/cmd/ipfs/main.go b/cmd/ipfs/main.go index 10fa66678..3909e1816 100644 --- a/cmd/ipfs/main.go +++ b/cmd/ipfs/main.go @@ -2,9 +2,12 @@ package main import ( + "bytes" "context" + "encoding/json" "errors" "fmt" + "io" "net" "net/http" "os" @@ -12,12 +15,14 @@ import ( "strings" "time" + "github.com/blang/semver/v4" "github.com/google/uuid" u "github.com/ipfs/boxo/util" cmds "github.com/ipfs/go-ipfs-cmds" "github.com/ipfs/go-ipfs-cmds/cli" cmdhttp "github.com/ipfs/go-ipfs-cmds/http" logging "github.com/ipfs/go-log" + ipfs "github.com/ipfs/kubo" "github.com/ipfs/kubo/cmd/ipfs/util" oldcmds "github.com/ipfs/kubo/commands" "github.com/ipfs/kubo/core" @@ -224,6 +229,10 @@ func apiAddrOption(req *cmds.Request) (ma.Multiaddr, error) { return ma.NewMultiaddr(apiAddrStr) } +// encodedAbsolutePathVersion is the version from which the absolute path header in +// multipart requests is %-encoded. Before this version, its sent raw. +var encodedAbsolutePathVersion = semver.MustParse("0.23.0-dev") + func makeExecutor(req *cmds.Request, env interface{}) (cmds.Executor, error) { exe := tracingWrappedExecutor{cmds.NewExecutor(req.Root)} cctx := env.(*oldcmds.Context) @@ -315,9 +324,18 @@ func makeExecutor(req *cmds.Request, env interface{}) (cmds.Executor, error) { default: return nil, fmt.Errorf("unsupported API address: %s", apiAddr) } - opts = append(opts, cmdhttp.ClientWithHTTPClient(&http.Client{ + + httpClient := &http.Client{ Transport: otelhttp.NewTransport(tpt), - })) + } + opts = append(opts, cmdhttp.ClientWithHTTPClient(httpClient)) + + // Fetch remove version, as some feature compatibility might change depending on it. + remoteVersion, err := getRemoteVersion(tracingWrappedExecutor{cmdhttp.NewClient(host, opts...)}) + if err != nil { + return nil, err + } + opts = append(opts, cmdhttp.ClientWithRawAbsPath(remoteVersion.LT(encodedAbsolutePathVersion))) return tracingWrappedExecutor{cmdhttp.NewClient(host, opts...)}, nil } @@ -417,3 +435,40 @@ func resolveAddr(ctx context.Context, addr ma.Multiaddr) (ma.Multiaddr, error) { return addrs[0], nil } + +type nopWriter struct { + io.Writer +} + +func (nw nopWriter) Close() error { + return nil +} + +func getRemoteVersion(exe cmds.Executor) (*semver.Version, error) { + ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(time.Second*30)) + defer cancel() + + req, err := cmds.NewRequest(ctx, []string{"version"}, nil, nil, nil, Root) + if err != nil { + return nil, err + } + + var buf bytes.Buffer + re, err := cmds.NewWriterResponseEmitter(nopWriter{&buf}, req) + if err != nil { + return nil, err + } + + err = exe.Execute(req, re, nil) + if err != nil { + return nil, err + } + + var out ipfs.VersionInfo + dec := json.NewDecoder(&buf) + if err := dec.Decode(&out); err != nil { + return nil, err + } + + return semver.New(out.Version) +} diff --git a/docs/changelogs/v0.23.md b/docs/changelogs/v0.23.md index 641f20f8b..c2267a8e1 100644 --- a/docs/changelogs/v0.23.md +++ b/docs/changelogs/v0.23.md @@ -8,6 +8,7 @@ - [🔦 Highlights](#-highlights) - [Mplex deprecation](#mplex-deprecation) - [Gateway: meaningful CAR responses on Not Found errors](#gateway-meaningful-car-responses-on-not-found-errors) + - [Binary characters in file names: no longer works with old clients and new Kubo servers](#binary-characters-in-file-names-no-longer-works-with-old-clients-and-new-kubo-servers) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -43,6 +44,21 @@ the path does not exist, a CAR will be sent with a root of `bafkqaaa` (empty CID This CAR will contain all blocks necessary to validate that the path does not exist without having to trust the gateway. +#### Binary characters in file names: no longer works with old clients and new Kubo servers + +In this version, we updated Kubo to support Go 1.20+. In Go 1.20, a regression +regarding multipart headers was [introduced](https://github.com/golang/go/issues/60674). +This only affects `ipfs add` when a file name has binary characters in its name. +As a consequence, we had to update the encoding of the file name headers. This is +the compatibility table: + +| | New Client | Old Client | +|------------|------------|-------------| +| New Server | ✅ | 🟡* | +| Old Server | ✅ | ✅ | + +*Old clients can only send Unicode file paths to the server. + ### 📝 Changelog ### 👨‍👩‍👧‍👦 Contributors diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 9aeb6112b..153968077 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.20 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.11.1-0.20230818062747-654231b2bda3 + github.com/ipfs/boxo v0.12.0 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.29.2 github.com/multiformats/go-multiaddr v0.10.1 @@ -91,7 +91,7 @@ require ( github.com/ipfs/go-unixfsnode v1.7.1 // indirect github.com/ipld/go-car/v2 v2.10.2-0.20230622090957-499d0c909d33 // indirect github.com/ipld/go-codec-dagpb v1.6.0 // indirect - github.com/ipld/go-ipld-prime v0.20.0 // indirect + github.com/ipld/go-ipld-prime v0.21.0 // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect github.com/jbenet/goprocess v0.1.4 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index acfc47fcb..2f877d604 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -159,7 +159,7 @@ github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJn github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/frankban/quicktest v1.14.0/go.mod h1:NeW+ay9A/U67EYXNFA1nPE8e/tnQv/09mUdL/ijj8og= -github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= +github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= @@ -301,8 +301,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.11.1-0.20230818062747-654231b2bda3 h1:oiMqmivloEHtlCkS+8rCq1Pkz/rf6m3sC45lL4cnwBA= -github.com/ipfs/boxo v0.11.1-0.20230818062747-654231b2bda3/go.mod h1:8IfDmp+FzFGcF4zjAgHMVPpwYw4AjN9ePEzDfkaYJ1w= +github.com/ipfs/boxo v0.12.0 h1:AXHg/1ONZdRQHQLgG5JHsSC3XoE4DjCAMgK+asZvUcQ= +github.com/ipfs/boxo v0.12.0/go.mod h1:xAnfiU6PtxWCnRqu7dcXQ10bB5/kvI1kXRotuGqGBhg= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= @@ -398,8 +398,8 @@ github.com/ipld/go-codec-dagpb v1.6.0 h1:9nYazfyu9B1p3NAgfVdpRco3Fs2nFC72DqVsMj6 github.com/ipld/go-codec-dagpb v1.6.0/go.mod h1:ANzFhfP2uMJxRBr8CE+WQWs5UsNa0pYtmKZ+agnUw9s= github.com/ipld/go-ipld-prime v0.11.0/go.mod h1:+WIAkokurHmZ/KwzDOMUuoeJgaRQktHtEaLglS3ZeV8= github.com/ipld/go-ipld-prime v0.14.1/go.mod h1:QcE4Y9n/ZZr8Ijg5bGPT0GqYWgZ1704nH0RDcQtgTP0= -github.com/ipld/go-ipld-prime v0.20.0 h1:Ud3VwE9ClxpO2LkCYP7vWPc0Fo+dYdYzgxUJZ3uRG4g= -github.com/ipld/go-ipld-prime v0.20.0/go.mod h1:PzqZ/ZR981eKbgdr3y2DJYeD/8bgMawdGVlJDE8kK+M= +github.com/ipld/go-ipld-prime v0.21.0 h1:n4JmcpOlPDIxBcY037SVfpd1G+Sj1nKZah0m6QH9C2E= +github.com/ipld/go-ipld-prime v0.21.0/go.mod h1:3RLqy//ERg/y5oShXXdx5YIp50cFGOanyMctpPjsvxQ= github.com/ipld/go-ipld-prime/storage/bsadapter v0.0.0-20230102063945-1a409dc236dd h1:gMlw/MhNr2Wtp5RwGdsW23cs+yCuj9k2ON7i9MiJlRo= github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= @@ -737,7 +737,7 @@ github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMI github.com/wangjia184/sortedset v0.0.0-20160527075905-f5d03557ba30/go.mod h1:YkocrP2K2tcw938x9gCOmT5G5eCD6jsTz0SZuyAqwIE= github.com/warpfork/go-testmark v0.3.0/go.mod h1:jhEf8FVxd+F17juRubpmut64NEG6I2rgkUhlcqqXwE0= github.com/warpfork/go-testmark v0.9.0/go.mod h1:jhEf8FVxd+F17juRubpmut64NEG6I2rgkUhlcqqXwE0= -github.com/warpfork/go-testmark v0.11.0 h1:J6LnV8KpceDvo7spaNU4+DauH2n1x+6RaO2rJrmpQ9U= +github.com/warpfork/go-testmark v0.12.1 h1:rMgCpJfwy1sJ50x0M0NgyphxYYPMOODIJHhsXyEHU0s= github.com/warpfork/go-wish v0.0.0-20180510122957-5ad1f5abf436/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= github.com/warpfork/go-wish v0.0.0-20200122115046-b9ea61034e4a/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0 h1:GDDkbFiaK8jsSDJfjId/PEGEShv6ugrt4kYsC5UIDaQ= diff --git a/go.mod b/go.mod index 129b2926a..b0dded118 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( github.com/fsnotify/fsnotify v1.6.0 github.com/google/uuid v1.3.0 github.com/hashicorp/go-multierror v1.1.1 - github.com/ipfs/boxo v0.11.1-0.20230818062747-654231b2bda3 + github.com/ipfs/boxo v0.12.0 github.com/ipfs/go-block-format v0.1.2 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 @@ -27,7 +27,7 @@ require ( github.com/ipfs/go-ds-measure v0.2.0 github.com/ipfs/go-fs-lock v0.0.7 github.com/ipfs/go-graphsync v0.14.4 - github.com/ipfs/go-ipfs-cmds v0.9.0 + github.com/ipfs/go-ipfs-cmds v0.10.0 github.com/ipfs/go-ipld-format v0.5.0 github.com/ipfs/go-ipld-git v0.1.1 github.com/ipfs/go-ipld-legacy v0.2.1 @@ -39,7 +39,7 @@ require ( github.com/ipld/go-car v0.5.0 github.com/ipld/go-car/v2 v2.10.2-0.20230622090957-499d0c909d33 github.com/ipld/go-codec-dagpb v1.6.0 - github.com/ipld/go-ipld-prime v0.20.0 + github.com/ipld/go-ipld-prime v0.21.0 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 @@ -92,7 +92,6 @@ require ( require ( github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 // indirect github.com/Jorropo/jsync v1.0.1 // indirect - github.com/Kubuxu/go-os-helper v0.0.1 // indirect github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5 // indirect github.com/beorn7/perks v1.0.1 // indirect @@ -166,7 +165,7 @@ require ( github.com/libp2p/go-yamux/v4 v4.0.1 // indirect github.com/libp2p/zeroconf/v2 v2.2.0 // indirect github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect - github.com/mattn/go-colorable v0.1.4 // indirect + github.com/mattn/go-colorable v0.1.6 // indirect github.com/mattn/go-isatty v0.0.19 // indirect github.com/mattn/go-runewidth v0.0.4 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect diff --git a/go.sum b/go.sum index 7dac8bc22..6e4845f99 100644 --- a/go.sum +++ b/go.sum @@ -49,8 +49,6 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/Jorropo/jsync v1.0.1 h1:6HgRolFZnsdfzRUj+ImB9og1JYOxQoReSywkHOGSaUU= github.com/Jorropo/jsync v1.0.1/go.mod h1:jCOZj3vrBCri3bSU3ErUYvevKlnbssrXeCivybS5ABQ= -github.com/Kubuxu/go-os-helper v0.0.1 h1:EJiD2VUQyh5A9hWJLmc6iWg6yIcJ7jpBcwC8GMGXfDk= -github.com/Kubuxu/go-os-helper v0.0.1/go.mod h1:N8B+I7vPCT80IcP58r50u4+gEEcsZETFUpAzWW2ep1Y= github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= @@ -179,7 +177,7 @@ github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJn github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/frankban/quicktest v1.14.0/go.mod h1:NeW+ay9A/U67EYXNFA1nPE8e/tnQv/09mUdL/ijj8og= -github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= +github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= @@ -337,8 +335,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.11.1-0.20230818062747-654231b2bda3 h1:oiMqmivloEHtlCkS+8rCq1Pkz/rf6m3sC45lL4cnwBA= -github.com/ipfs/boxo v0.11.1-0.20230818062747-654231b2bda3/go.mod h1:8IfDmp+FzFGcF4zjAgHMVPpwYw4AjN9ePEzDfkaYJ1w= +github.com/ipfs/boxo v0.12.0 h1:AXHg/1ONZdRQHQLgG5JHsSC3XoE4DjCAMgK+asZvUcQ= +github.com/ipfs/boxo v0.12.0/go.mod h1:xAnfiU6PtxWCnRqu7dcXQ10bB5/kvI1kXRotuGqGBhg= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= @@ -383,8 +381,8 @@ github.com/ipfs/go-ipfs-blockstore v1.3.0 h1:m2EXaWgwTzAfsmt5UdJ7Is6l4gJcaM/A12X github.com/ipfs/go-ipfs-blockstore v1.3.0/go.mod h1:KgtZyc9fq+P2xJUiCAzbRdhhqJHvsw8u2Dlqy2MyRTE= github.com/ipfs/go-ipfs-blocksutil v0.0.1 h1:Eh/H4pc1hsvhzsQoMEP3Bke/aW5P5rVM1IWFJMcGIPQ= github.com/ipfs/go-ipfs-chunker v0.0.5 h1:ojCf7HV/m+uS2vhUGWcogIIxiO5ubl5O57Q7NapWLY8= -github.com/ipfs/go-ipfs-cmds v0.9.0 h1:K0VcXg1l1k6aY6sHnoxYcyimyJQbcV1ueXuWgThmK9Q= -github.com/ipfs/go-ipfs-cmds v0.9.0/go.mod h1:SBFHK8WNwC416QWH9Vz1Ql42SSMAOqKpaHUMBu3jpLo= +github.com/ipfs/go-ipfs-cmds v0.10.0 h1:ZB4+RgYaH4UARfJY0uLKl5UXgApqnRjKbuCiJVcErYk= +github.com/ipfs/go-ipfs-cmds v0.10.0/go.mod h1:sX5d7jkCft9XLPnkgEfXY0z2UBOB5g6fh/obBS0enJE= github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= github.com/ipfs/go-ipfs-delay v0.0.1 h1:r/UXYyRcddO6thwOnhiznIAiSvxMECGgtv35Xs1IeRQ= github.com/ipfs/go-ipfs-delay v0.0.1/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= @@ -446,8 +444,8 @@ github.com/ipld/go-codec-dagpb v1.6.0 h1:9nYazfyu9B1p3NAgfVdpRco3Fs2nFC72DqVsMj6 github.com/ipld/go-codec-dagpb v1.6.0/go.mod h1:ANzFhfP2uMJxRBr8CE+WQWs5UsNa0pYtmKZ+agnUw9s= github.com/ipld/go-ipld-prime v0.11.0/go.mod h1:+WIAkokurHmZ/KwzDOMUuoeJgaRQktHtEaLglS3ZeV8= github.com/ipld/go-ipld-prime v0.14.1/go.mod h1:QcE4Y9n/ZZr8Ijg5bGPT0GqYWgZ1704nH0RDcQtgTP0= -github.com/ipld/go-ipld-prime v0.20.0 h1:Ud3VwE9ClxpO2LkCYP7vWPc0Fo+dYdYzgxUJZ3uRG4g= -github.com/ipld/go-ipld-prime v0.20.0/go.mod h1:PzqZ/ZR981eKbgdr3y2DJYeD/8bgMawdGVlJDE8kK+M= +github.com/ipld/go-ipld-prime v0.21.0 h1:n4JmcpOlPDIxBcY037SVfpd1G+Sj1nKZah0m6QH9C2E= +github.com/ipld/go-ipld-prime v0.21.0/go.mod h1:3RLqy//ERg/y5oShXXdx5YIp50cFGOanyMctpPjsvxQ= github.com/ipld/go-ipld-prime/storage/bsadapter v0.0.0-20230102063945-1a409dc236dd h1:gMlw/MhNr2Wtp5RwGdsW23cs+yCuj9k2ON7i9MiJlRo= github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= @@ -572,12 +570,14 @@ github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd h1:br0buuQ854V8 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= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= -github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.6 h1:6Su7aK7lXmJ/U79bYtBjLNaha4Fs1Rg9plHpcH+vvnE= +github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= 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.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= @@ -859,7 +859,7 @@ github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMI github.com/wangjia184/sortedset v0.0.0-20160527075905-f5d03557ba30/go.mod h1:YkocrP2K2tcw938x9gCOmT5G5eCD6jsTz0SZuyAqwIE= github.com/warpfork/go-testmark v0.3.0/go.mod h1:jhEf8FVxd+F17juRubpmut64NEG6I2rgkUhlcqqXwE0= github.com/warpfork/go-testmark v0.9.0/go.mod h1:jhEf8FVxd+F17juRubpmut64NEG6I2rgkUhlcqqXwE0= -github.com/warpfork/go-testmark v0.11.0 h1:J6LnV8KpceDvo7spaNU4+DauH2n1x+6RaO2rJrmpQ9U= +github.com/warpfork/go-testmark v0.12.1 h1:rMgCpJfwy1sJ50x0M0NgyphxYYPMOODIJHhsXyEHU0s= github.com/warpfork/go-wish v0.0.0-20180510122957-5ad1f5abf436/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= github.com/warpfork/go-wish v0.0.0-20200122115046-b9ea61034e4a/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0 h1:GDDkbFiaK8jsSDJfjId/PEGEShv6ugrt4kYsC5UIDaQ= diff --git a/test/cli/content_routing_http_test.go b/test/cli/content_routing_http_test.go index 2734e2600..01b602bb7 100644 --- a/test/cli/content_routing_http_test.go +++ b/test/cli/content_routing_http_test.go @@ -9,12 +9,14 @@ import ( "testing" "time" + "github.com/ipfs/boxo/ipns" "github.com/ipfs/boxo/routing/http/server" "github.com/ipfs/boxo/routing/http/types" "github.com/ipfs/boxo/routing/http/types/iter" "github.com/ipfs/go-cid" "github.com/ipfs/kubo/test/cli/harness" "github.com/ipfs/kubo/test/cli/testutils" + "github.com/libp2p/go-libp2p/core/routing" "github.com/stretchr/testify/assert" ) @@ -45,6 +47,14 @@ func (r *fakeHTTPContentRouter) Provide(ctx context.Context, req *server.WritePr return nil, nil } +func (r *fakeHTTPContentRouter) FindIPNSRecord(ctx context.Context, name ipns.Name) (*ipns.Record, error) { + return nil, routing.ErrNotSupported +} + +func (r *fakeHTTPContentRouter) ProvideIPNSRecord(ctx context.Context, name ipns.Name, rec *ipns.Record) error { + return routing.ErrNotSupported +} + func (r *fakeHTTPContentRouter) numFindProvidersCalls() int { r.m.Lock() defer r.m.Unlock() diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 2b3a1536d..7a99935a3 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -7,7 +7,7 @@ replace github.com/ipfs/kubo => ../../ require ( github.com/Kubuxu/gocovmerge v0.0.0-20161216165753-7ecaa51963cd github.com/golangci/golangci-lint v1.54.1 - github.com/ipfs/boxo v0.11.1-0.20230818062747-654231b2bda3 + github.com/ipfs/boxo v0.12.0 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 github.com/ipfs/go-datastore v0.6.0 @@ -16,7 +16,7 @@ require ( github.com/ipfs/hang-fds v0.1.0 github.com/ipfs/iptb v1.4.0 github.com/ipfs/iptb-plugins v0.5.0 - github.com/ipld/go-ipld-prime v0.20.0 + github.com/ipld/go-ipld-prime v0.21.0 github.com/jbenet/go-random v0.0.0-20190219211222-123a90aedc0c github.com/jbenet/go-random-files v0.0.0-20190219210431-31b3f20ebded github.com/libp2p/go-libp2p v0.29.2 diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 5c7a860aa..dbe3b4faf 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -188,7 +188,7 @@ github.com/flynn/noise v1.0.0 h1:DlTHqmzmvcEiKj+4RYo/imoswx/4r6iBlCMfVtrMXpQ= github.com/flynn/noise v1.0.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag= github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk= github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= -github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= +github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= @@ -396,8 +396,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.11.1-0.20230818062747-654231b2bda3 h1:oiMqmivloEHtlCkS+8rCq1Pkz/rf6m3sC45lL4cnwBA= -github.com/ipfs/boxo v0.11.1-0.20230818062747-654231b2bda3/go.mod h1:8IfDmp+FzFGcF4zjAgHMVPpwYw4AjN9ePEzDfkaYJ1w= +github.com/ipfs/boxo v0.12.0 h1:AXHg/1ONZdRQHQLgG5JHsSC3XoE4DjCAMgK+asZvUcQ= +github.com/ipfs/boxo v0.12.0/go.mod h1:xAnfiU6PtxWCnRqu7dcXQ10bB5/kvI1kXRotuGqGBhg= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.1.2 h1:GAjkfhVx1f4YTODS6Esrj1wt2HhrtwTnhEr+DyPUaJo= @@ -462,8 +462,8 @@ github.com/ipld/go-car v0.5.0 h1:kcCEa3CvYMs0iE5BzD5sV7O2EwMiCIp3uF8tA6APQT8= github.com/ipld/go-car/v2 v2.10.2-0.20230622090957-499d0c909d33 h1:0OZwzSYWIuiKEOXd/2vm5cMcEmmGLFn+1h6lHELCm3s= github.com/ipld/go-codec-dagpb v1.6.0 h1:9nYazfyu9B1p3NAgfVdpRco3Fs2nFC72DqVsMj6rOcc= github.com/ipld/go-codec-dagpb v1.6.0/go.mod h1:ANzFhfP2uMJxRBr8CE+WQWs5UsNa0pYtmKZ+agnUw9s= -github.com/ipld/go-ipld-prime v0.20.0 h1:Ud3VwE9ClxpO2LkCYP7vWPc0Fo+dYdYzgxUJZ3uRG4g= -github.com/ipld/go-ipld-prime v0.20.0/go.mod h1:PzqZ/ZR981eKbgdr3y2DJYeD/8bgMawdGVlJDE8kK+M= +github.com/ipld/go-ipld-prime v0.21.0 h1:n4JmcpOlPDIxBcY037SVfpd1G+Sj1nKZah0m6QH9C2E= +github.com/ipld/go-ipld-prime v0.21.0/go.mod h1:3RLqy//ERg/y5oShXXdx5YIp50cFGOanyMctpPjsvxQ= github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA= @@ -885,7 +885,7 @@ github.com/uudashr/gocognit v1.0.7 h1:e9aFXgKgUJrQ5+bs61zBigmj7bFJ/5cC6HmMahVzuD github.com/uudashr/gocognit v1.0.7/go.mod h1:nAIUuVBnYU7pcninia3BHOvQkpQCeO76Uscky5BOwcY= github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU= github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM= -github.com/warpfork/go-testmark v0.11.0 h1:J6LnV8KpceDvo7spaNU4+DauH2n1x+6RaO2rJrmpQ9U= +github.com/warpfork/go-testmark v0.12.1 h1:rMgCpJfwy1sJ50x0M0NgyphxYYPMOODIJHhsXyEHU0s= github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0 h1:GDDkbFiaK8jsSDJfjId/PEGEShv6ugrt4kYsC5UIDaQ= github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11 h1:5HZfQkwe0mIfyDmc1Em5GqlNRzcdtlv4HTNmdpt7XH0= diff --git a/test/sharness/t0235-cli-request.sh b/test/sharness/t0235-cli-request.sh index 3d50a2e62..3b2281894 100755 --- a/test/sharness/t0235-cli-request.sh +++ b/test/sharness/t0235-cli-request.sh @@ -31,7 +31,22 @@ test_expect_success "can make http request against nc server" ' ipfs cat /ipfs/Qmabcdef --api /ip4/127.0.0.1/tcp/5005 & IPFSPID=$! - # handle request + # handle request for /api/v0/version + while read line; do + if [[ "$line" == "$(echo -e "\r")" ]]; then + break + fi + echo "$line" + done <&7 >nc_out && + + echo -e "HTTP/1.1 200 OK\r" >&6 && + echo -e "Content-Type: application/json\r" >&6 && + echo -e "Content-Length: 21\r" >&6 && + echo -e "\r" >&6 && + echo -e "{\"Version\":\"0.23.0\"}\r" >&6 && + echo -e "\r" >&6 && + + # handle request for /api/v0/cat while read line; do if [[ "$line" == "$(echo -e "\r")" ]]; then break diff --git a/test/sharness/t0236-cli-api-dns-resolve.sh b/test/sharness/t0236-cli-api-dns-resolve.sh index eddbc93da..b42131834 100755 --- a/test/sharness/t0236-cli-api-dns-resolve.sh +++ b/test/sharness/t0236-cli-api-dns-resolve.sh @@ -30,7 +30,22 @@ test_expect_success "can make http request against dns resolved nc server" ' ipfs cat /ipfs/Qmabcdef --api /dns4/localhost/tcp/5006 & IPFSPID=$! - # handle request + # handle request for /api/v0/version + while read line; do + if [[ "$line" == "$(echo -e "\r")" ]]; then + break + fi + echo "$line" + done <&7 >nc_out && + + echo -e "HTTP/1.1 200 OK\r" >&6 && + echo -e "Content-Type: application/json\r" >&6 && + echo -e "Content-Length: 21\r" >&6 && + echo -e "\r" >&6 && + echo -e "{\"Version\":\"0.23.0\"}\r" >&6 && + echo -e "\r" >&6 && + + # handle request for /api/v0/cat while read line; do if [[ "$line" == "$(echo -e "\r")" ]]; then break From 2b7c20fc66faeea5c74c8d0c14691238f2304553 Mon Sep 17 00:00:00 2001 From: Kay Date: Tue, 22 Aug 2023 18:23:29 +0330 Subject: [PATCH 0833/1212] refactor: using error is instead of == (#10093) --- cmd/ipfs/util/ulimit.go | 4 ++-- config/bootstrap_peers.go | 2 +- config/config.go | 8 ++++---- config/serialize/serialize.go | 2 +- repo/fsrepo/fsrepo.go | 2 +- repo/fsrepo/migrations/httpfetcher.go | 6 +++--- repo/fsrepo/migrations/migrations.go | 10 +++++----- repo/fsrepo/migrations/versions.go | 2 +- routing/composer.go | 3 ++- tar/format.go | 2 +- 10 files changed, 21 insertions(+), 20 deletions(-) diff --git a/cmd/ipfs/util/ulimit.go b/cmd/ipfs/util/ulimit.go index a00e81076..188444d67 100644 --- a/cmd/ipfs/util/ulimit.go +++ b/cmd/ipfs/util/ulimit.go @@ -82,7 +82,7 @@ func ManageFdLimit() (changed bool, newLimit uint64, err error) { // set the soft value err = setLimit(targetLimit, hard) if err != nil { - err = fmt.Errorf("error setting ulimit without hard limit: %s", err) + err = fmt.Errorf("error setting ulimit without hard limit: %w", err) break } newLimit = targetLimit @@ -107,7 +107,7 @@ func ManageFdLimit() (changed bool, newLimit uint64, err error) { break } default: - err = fmt.Errorf("error setting: ulimit: %s", err) + err = fmt.Errorf("error setting: ulimit: %w", err) } return newLimit > 0, newLimit, err diff --git a/config/bootstrap_peers.go b/config/bootstrap_peers.go index 6222cd623..6b9434ae5 100644 --- a/config/bootstrap_peers.go +++ b/config/bootstrap_peers.go @@ -36,7 +36,7 @@ func (c *Config) BootstrapPeers() ([]peer.AddrInfo, error) { func DefaultBootstrapPeers() ([]peer.AddrInfo, error) { ps, err := ParseBootstrapPeers(DefaultBootstrapAddresses) if err != nil { - return nil, fmt.Errorf(`failed to parse hardcoded bootstrap peers: %s + return nil, fmt.Errorf(`failed to parse hardcoded bootstrap peers: %w This is a problem with the ipfs codebase. Please report it to the dev team`, err) } return ps, nil diff --git a/config/config.go b/config/config.go index 035fbe296..1951784dd 100644 --- a/config/config.go +++ b/config/config.go @@ -117,7 +117,7 @@ func FromMap(v map[string]interface{}) (*Config, error) { } var conf Config if err := json.NewDecoder(buf).Decode(&conf); err != nil { - return nil, fmt.Errorf("failure to decode config: %s", err) + return nil, fmt.Errorf("failure to decode config: %w", err) } return &conf, nil } @@ -129,7 +129,7 @@ func ToMap(conf *Config) (map[string]interface{}, error) { } var m map[string]interface{} if err := json.NewDecoder(buf).Decode(&m); err != nil { - return nil, fmt.Errorf("failure to decode config: %s", err) + return nil, fmt.Errorf("failure to decode config: %w", err) } return m, nil } @@ -140,11 +140,11 @@ func (c *Config) Clone() (*Config, error) { var buf bytes.Buffer if err := json.NewEncoder(&buf).Encode(c); err != nil { - return nil, fmt.Errorf("failure to encode config: %s", err) + return nil, fmt.Errorf("failure to encode config: %w", err) } if err := json.NewDecoder(&buf).Decode(&newConfig); err != nil { - return nil, fmt.Errorf("failure to decode config: %s", err) + return nil, fmt.Errorf("failure to decode config: %w", err) } return &newConfig, nil diff --git a/config/serialize/serialize.go b/config/serialize/serialize.go index 616e529cb..7cb479f6b 100644 --- a/config/serialize/serialize.go +++ b/config/serialize/serialize.go @@ -28,7 +28,7 @@ func ReadConfigFile(filename string, cfg interface{}) error { } defer f.Close() if err := json.NewDecoder(f).Decode(cfg); err != nil { - return fmt.Errorf("failure to decode config: %s", err) + return fmt.Errorf("failure to decode config: %w", err) } return nil } diff --git a/repo/fsrepo/fsrepo.go b/repo/fsrepo/fsrepo.go index c2f7ca72a..13e7e4150 100644 --- a/repo/fsrepo/fsrepo.go +++ b/repo/fsrepo/fsrepo.go @@ -449,7 +449,7 @@ func (r *FSRepo) openConfig() error { func (r *FSRepo) openUserResourceOverrides() error { // This filepath is documented in docs/libp2p-resource-management.md and be kept in sync. err := serialize.ReadConfigFile(filepath.Join(r.path, "libp2p-resource-limit-overrides.json"), &r.userResourceOverrides) - if err == serialize.ErrNotInitialized { + if errors.Is(err, serialize.ErrNotInitialized) { err = nil } return err diff --git a/repo/fsrepo/migrations/httpfetcher.go b/repo/fsrepo/migrations/httpfetcher.go index 588a01ead..1f3d575a9 100644 --- a/repo/fsrepo/migrations/httpfetcher.go +++ b/repo/fsrepo/migrations/httpfetcher.go @@ -66,7 +66,7 @@ func (f *HttpFetcher) Fetch(ctx context.Context, filePath string) ([]byte, error req, err := http.NewRequestWithContext(ctx, http.MethodGet, gwURL, nil) if err != nil { - return nil, fmt.Errorf("http.NewRequest error: %s", err) + return nil, fmt.Errorf("http.NewRequest error: %w", err) } if f.userAgent != "" { @@ -75,14 +75,14 @@ func (f *HttpFetcher) Fetch(ctx context.Context, filePath string) ([]byte, error resp, err := http.DefaultClient.Do(req) if err != nil { - return nil, fmt.Errorf("http.DefaultClient.Do error: %s", err) + return nil, fmt.Errorf("http.DefaultClient.Do error: %w", err) } if resp.StatusCode >= 400 { defer resp.Body.Close() mes, err := io.ReadAll(resp.Body) if err != nil { - return nil, fmt.Errorf("error reading error body: %s", err) + return nil, fmt.Errorf("error reading error body: %w", err) } return nil, fmt.Errorf("GET %s error: %s: %s", gwURL, resp.Status, string(mes)) } diff --git a/repo/fsrepo/migrations/migrations.go b/repo/fsrepo/migrations/migrations.go index 14cc6c2de..6894d73a7 100644 --- a/repo/fsrepo/migrations/migrations.go +++ b/repo/fsrepo/migrations/migrations.go @@ -32,7 +32,7 @@ func RunMigration(ctx context.Context, fetcher Fetcher, targetVer int, ipfsDir s } fromVer, err := RepoVersion(ipfsDir) if err != nil { - return fmt.Errorf("could not get repo version: %s", err) + return fmt.Errorf("could not get repo version: %w", err) } if fromVer == targetVer { // repo already at target version number @@ -87,7 +87,7 @@ func RunMigration(ctx context.Context, fetcher Fetcher, targetVer int, ipfsDir s logger.Println("Running migration", migration, "...") err = runMigration(ctx, binPaths[migration], ipfsDir, revert, logger) if err != nil { - return fmt.Errorf("migration %s failed: %s", migration, err) + return fmt.Errorf("migration %s failed: %w", migration, err) } } logger.Printf("Success: fs-repo migrated to version %d.\n", targetVer) @@ -98,7 +98,7 @@ func RunMigration(ctx context.Context, fetcher Fetcher, targetVer int, ipfsDir s func NeedMigration(target int) (bool, error) { vnum, err := RepoVersion("") if err != nil { - return false, fmt.Errorf("could not get repo version: %s", err) + return false, fmt.Errorf("could not get repo version: %w", err) } return vnum != target, nil @@ -171,7 +171,7 @@ func GetMigrationFetcher(downloadSources []string, distPath string, newIpfsFetch default: u, err := url.Parse(src) if err != nil { - return nil, fmt.Errorf("bad gateway address: %s", err) + return nil, fmt.Errorf("bad gateway address: %w", err) } switch u.Scheme { case "": @@ -293,7 +293,7 @@ func fetchMigrations(ctx context.Context, fetcher Fetcher, needed []string, dest if len(fails) != 0 { err = fmt.Errorf("failed to download migrations: %s", strings.Join(fails, " ")) if ctx.Err() != nil { - err = fmt.Errorf("%s, %s", ctx.Err(), err) + err = fmt.Errorf("%s, %w", ctx.Err(), err) } return nil, err } diff --git a/repo/fsrepo/migrations/versions.go b/repo/fsrepo/migrations/versions.go index af5bbbbd9..056671c07 100644 --- a/repo/fsrepo/migrations/versions.go +++ b/repo/fsrepo/migrations/versions.go @@ -57,7 +57,7 @@ func DistVersions(ctx context.Context, fetcher Fetcher, dist string, sortDesc bo vers = append(vers, ver) } if scan.Err() != nil { - return nil, fmt.Errorf("could not read versions: %s", scan.Err()) + return nil, fmt.Errorf("could not read versions: %w", scan.Err()) } if sortDesc { diff --git a/routing/composer.go b/routing/composer.go index 92c351fc5..3541fc7dd 100644 --- a/routing/composer.go +++ b/routing/composer.go @@ -2,6 +2,7 @@ package routing import ( "context" + "errors" "github.com/hashicorp/go-multierror" "github.com/ipfs/go-cid" @@ -103,7 +104,7 @@ func (c *Composer) SearchValue(ctx context.Context, key string, opts ...routing. ch, err := c.GetValueRouter.SearchValue(ctx, key, opts...) // avoid nil channels on implementations not supporting SearchValue method. - if err == routing.ErrNotFound && ch == nil { + if errors.Is(err, routing.ErrNotFound) && ch == nil { out := make(chan []byte) close(out) return out, err diff --git a/tar/format.go b/tar/format.go index 626e0982b..bde923980 100644 --- a/tar/format.go +++ b/tar/format.go @@ -175,7 +175,7 @@ func (tr *tarReader) Read(b []byte) (int, error) { tr.hdrBuf = bytes.NewReader(hndpb.Data()) dataNd, err := hndpb.GetLinkedProtoNode(tr.ctx, tr.ds, "data") - if err != nil && err != dag.ErrLinkNotFound { + if err != nil && !errors.Is(err, dag.ErrLinkNotFound) { return 0, err } From 8ac25bbbef9a3284d65e0561a12ac791dcf2320a Mon Sep 17 00:00:00 2001 From: Jorropo Date: Wed, 23 Aug 2023 21:52:20 +0200 Subject: [PATCH 0834/1212] dockerfile: reorder copy order for better layer caching Because Kubo is the part changing more often it's better to copy after so docker can reuse the utilities layers. --- Dockerfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index 9eafe6c60..348fbc440 100644 --- a/Dockerfile +++ b/Dockerfile @@ -45,13 +45,13 @@ FROM busybox:stable-glibc # Get the ipfs binary, entrypoint script, and TLS CAs from the build container. ENV SRC_DIR /kubo -COPY --from=builder $SRC_DIR/cmd/ipfs/ipfs /usr/local/bin/ipfs -COPY --from=builder $SRC_DIR/bin/container_daemon /usr/local/bin/start_ipfs -COPY --from=builder $SRC_DIR/bin/container_init_run /usr/local/bin/container_init_run COPY --from=utilities /usr/sbin/gosu /sbin/gosu COPY --from=utilities /usr/bin/tini /sbin/tini COPY --from=utilities /bin/fusermount /usr/local/bin/fusermount COPY --from=utilities /etc/ssl/certs /etc/ssl/certs +COPY --from=builder $SRC_DIR/cmd/ipfs/ipfs /usr/local/bin/ipfs +COPY --from=builder $SRC_DIR/bin/container_daemon /usr/local/bin/start_ipfs +COPY --from=builder $SRC_DIR/bin/container_init_run /usr/local/bin/container_init_run # Add suid bit on fusermount so it will run properly RUN chmod 4755 /usr/local/bin/fusermount From 5ea58251d5fb7cb1518382921aa5421ec7ecca89 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Thu, 24 Aug 2023 08:11:02 +0200 Subject: [PATCH 0835/1212] chore: update boxo, go-libp2p, and internalize mplex (#10095) --- config/bootstrap_peers.go | 4 +- config/init.go | 2 - core/core_test.go | 4 +- core/corehttp/metrics_test.go | 2 +- core/node/builder.go | 2 +- core/node/libp2p/internal/mplex/conn.go | 49 +++++++++++++ core/node/libp2p/internal/mplex/stream.go | 65 +++++++++++++++++ core/node/libp2p/internal/mplex/transport.go | 29 ++++++++ .../libp2p/internal/mplex/transport_test.go | 53 ++++++++++++++ core/node/libp2p/routingopt_test.go | 12 +-- core/node/libp2p/smux.go | 2 +- docs/config.md | 15 ++-- docs/examples/kubo-as-a-library/go.mod | 35 +++++---- docs/examples/kubo-as-a-library/go.sum | 69 +++++++++--------- docs/file-transfer.md | 10 +-- go.mod | 39 +++++----- go.sum | 73 +++++++++---------- test/dependencies/go.mod | 27 ++++--- test/dependencies/go.sum | 55 +++++++------- test/sharness/t0120-bootstrap.sh | 2 +- test/sharness/t0190-quic-ping.sh | 4 +- 21 files changed, 370 insertions(+), 183 deletions(-) create mode 100644 core/node/libp2p/internal/mplex/conn.go create mode 100644 core/node/libp2p/internal/mplex/stream.go create mode 100644 core/node/libp2p/internal/mplex/transport.go create mode 100644 core/node/libp2p/internal/mplex/transport_test.go diff --git a/config/bootstrap_peers.go b/config/bootstrap_peers.go index 6b9434ae5..1671d9f81 100644 --- a/config/bootstrap_peers.go +++ b/config/bootstrap_peers.go @@ -19,8 +19,8 @@ var DefaultBootstrapAddresses = []string{ "/dnsaddr/bootstrap.libp2p.io/p2p/QmQCU2EcMqAqQPR2i9bChDtGNJchTbq5TbXJJ16u19uLTa", "/dnsaddr/bootstrap.libp2p.io/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb", "/dnsaddr/bootstrap.libp2p.io/p2p/QmcZf59bWwK5XFi76CZX8cbJ4BhTzzA3gU1ZjYZcYW3dwt", - "/ip4/104.131.131.82/tcp/4001/p2p/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ", // mars.i.ipfs.io - "/ip4/104.131.131.82/udp/4001/quic/p2p/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ", // mars.i.ipfs.io + "/ip4/104.131.131.82/tcp/4001/p2p/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ", // mars.i.ipfs.io + "/ip4/104.131.131.82/udp/4001/quic-v1/p2p/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ", // mars.i.ipfs.io } // ErrInvalidPeerAddr signals an address is not a valid peer address. diff --git a/config/init.go b/config/init.go index 9b0bf9dbf..1ccfc7251 100644 --- a/config/init.go +++ b/config/init.go @@ -114,10 +114,8 @@ func addressesConfig() Addresses { Swarm: []string{ "/ip4/0.0.0.0/tcp/4001", "/ip6/::/tcp/4001", - "/ip4/0.0.0.0/udp/4001/quic", "/ip4/0.0.0.0/udp/4001/quic-v1", "/ip4/0.0.0.0/udp/4001/quic-v1/webtransport", - "/ip6/::/udp/4001/quic", "/ip6/::/udp/4001/quic-v1", "/ip6/::/udp/4001/quic-v1/webtransport", }, diff --git a/core/core_test.go b/core/core_test.go index 42dd543d7..5d004937a 100644 --- a/core/core_test.go +++ b/core/core_test.go @@ -20,7 +20,7 @@ func TestInitialization(t *testing.T) { { Identity: id, Addresses: config.Addresses{ - Swarm: []string{"/ip4/0.0.0.0/tcp/4001", "/ip4/0.0.0.0/udp/4001/quic"}, + Swarm: []string{"/ip4/0.0.0.0/tcp/4001", "/ip4/0.0.0.0/udp/4001/quic-v1"}, API: []string{"/ip4/127.0.0.1/tcp/8000"}, }, }, @@ -28,7 +28,7 @@ func TestInitialization(t *testing.T) { { Identity: id, Addresses: config.Addresses{ - Swarm: []string{"/ip4/0.0.0.0/tcp/4001", "/ip4/0.0.0.0/udp/4001/quic"}, + Swarm: []string{"/ip4/0.0.0.0/tcp/4001", "/ip4/0.0.0.0/udp/4001/quic-v1"}, API: []string{"/ip4/127.0.0.1/tcp/8000"}, }, }, diff --git a/core/corehttp/metrics_test.go b/core/corehttp/metrics_test.go index 267d4ae97..f1bb39617 100644 --- a/core/corehttp/metrics_test.go +++ b/core/corehttp/metrics_test.go @@ -49,7 +49,7 @@ func TestPeersTotal(t *testing.T) { t.Fatalf("expected at most 2 peers transport (tcp and upd/quic), got %d, transport map %v", len(peersTransport), peersTransport) } - totalPeers := peersTransport["/ip4/tcp"] + peersTransport["/ip4/udp/quic"] + totalPeers := peersTransport["/ip4/tcp"] + peersTransport["/ip4/udp/quic-v1"] if totalPeers != 3 { t.Fatalf("expected 3 peers in either tcp or upd/quic transport, got %f", totalPeers) } diff --git a/core/node/builder.go b/core/node/builder.go index cd68bbfcb..9c4951801 100644 --- a/core/node/builder.go +++ b/core/node/builder.go @@ -140,7 +140,7 @@ func defaultRepo(dstore repo.Datastore) (repo.Repo, error) { } c.Bootstrap = cfg.DefaultBootstrapAddresses - c.Addresses.Swarm = []string{"/ip4/0.0.0.0/tcp/4001", "/ip4/0.0.0.0/udp/4001/quic"} + c.Addresses.Swarm = []string{"/ip4/0.0.0.0/tcp/4001", "/ip4/0.0.0.0/udp/4001/quic-v1"} c.Identity.PeerID = pid.Pretty() c.Identity.PrivKey = base64.StdEncoding.EncodeToString(privkeyb) diff --git a/core/node/libp2p/internal/mplex/conn.go b/core/node/libp2p/internal/mplex/conn.go new file mode 100644 index 000000000..4a6ca87c3 --- /dev/null +++ b/core/node/libp2p/internal/mplex/conn.go @@ -0,0 +1,49 @@ +// Code copied from https://github.com/libp2p/go-libp2p/blob/9bd85029550a084fca63ec6ff9184122cdf06591/p2p/muxer/mplex/conn.go +package mplex + +import ( + "context" + + "github.com/libp2p/go-libp2p/core/network" + + mp "github.com/libp2p/go-mplex" +) + +type conn mp.Multiplex + +var _ network.MuxedConn = &conn{} + +// NewMuxedConn constructs a new Conn from a *mp.Multiplex. +func NewMuxedConn(m *mp.Multiplex) network.MuxedConn { + return (*conn)(m) +} + +func (c *conn) Close() error { + return c.mplex().Close() +} + +func (c *conn) IsClosed() bool { + return c.mplex().IsClosed() +} + +// OpenStream creates a new stream. +func (c *conn) OpenStream(ctx context.Context) (network.MuxedStream, error) { + s, err := c.mplex().NewStream(ctx) + if err != nil { + return nil, err + } + return (*stream)(s), nil +} + +// AcceptStream accepts a stream opened by the other side. +func (c *conn) AcceptStream() (network.MuxedStream, error) { + s, err := c.mplex().Accept() + if err != nil { + return nil, err + } + return (*stream)(s), nil +} + +func (c *conn) mplex() *mp.Multiplex { + return (*mp.Multiplex)(c) +} diff --git a/core/node/libp2p/internal/mplex/stream.go b/core/node/libp2p/internal/mplex/stream.go new file mode 100644 index 000000000..34d9cfb14 --- /dev/null +++ b/core/node/libp2p/internal/mplex/stream.go @@ -0,0 +1,65 @@ +// Code copied from https://github.com/libp2p/go-libp2p/blob/9bd85029550a084fca63ec6ff9184122cdf06591/p2p/muxer/mplex/stream.go +package mplex + +import ( + "time" + + "github.com/libp2p/go-libp2p/core/network" + + mp "github.com/libp2p/go-mplex" +) + +// stream implements network.MuxedStream over mplex.Stream. +type stream mp.Stream + +var _ network.MuxedStream = &stream{} + +func (s *stream) Read(b []byte) (n int, err error) { + n, err = s.mplex().Read(b) + if err == mp.ErrStreamReset { + err = network.ErrReset + } + + return n, err +} + +func (s *stream) Write(b []byte) (n int, err error) { + n, err = s.mplex().Write(b) + if err == mp.ErrStreamReset { + err = network.ErrReset + } + + return n, err +} + +func (s *stream) Close() error { + return s.mplex().Close() +} + +func (s *stream) CloseWrite() error { + return s.mplex().CloseWrite() +} + +func (s *stream) CloseRead() error { + return s.mplex().CloseRead() +} + +func (s *stream) Reset() error { + return s.mplex().Reset() +} + +func (s *stream) SetDeadline(t time.Time) error { + return s.mplex().SetDeadline(t) +} + +func (s *stream) SetReadDeadline(t time.Time) error { + return s.mplex().SetReadDeadline(t) +} + +func (s *stream) SetWriteDeadline(t time.Time) error { + return s.mplex().SetWriteDeadline(t) +} + +func (s *stream) mplex() *mp.Stream { + return (*mp.Stream)(s) +} diff --git a/core/node/libp2p/internal/mplex/transport.go b/core/node/libp2p/internal/mplex/transport.go new file mode 100644 index 000000000..e7df384b9 --- /dev/null +++ b/core/node/libp2p/internal/mplex/transport.go @@ -0,0 +1,29 @@ +// Code copied from https://github.com/libp2p/go-libp2p/blob/9bd85029550a084fca63ec6ff9184122cdf06591/p2p/muxer/mplex/transport.go +package mplex + +import ( + "net" + + "github.com/libp2p/go-libp2p/core/network" + + mp "github.com/libp2p/go-mplex" +) + +// DefaultTransport has default settings for Transport +var DefaultTransport = &Transport{} + +const ID = "/mplex/6.7.0" + +var _ network.Multiplexer = &Transport{} + +// Transport implements mux.Multiplexer that constructs +// mplex-backed muxed connections. +type Transport struct{} + +func (t *Transport) NewConn(nc net.Conn, isServer bool, scope network.PeerScope) (network.MuxedConn, error) { + m, err := mp.NewMultiplex(nc, isServer, scope) + if err != nil { + return nil, err + } + return NewMuxedConn(m), nil +} diff --git a/core/node/libp2p/internal/mplex/transport_test.go b/core/node/libp2p/internal/mplex/transport_test.go new file mode 100644 index 000000000..1e3a1dec9 --- /dev/null +++ b/core/node/libp2p/internal/mplex/transport_test.go @@ -0,0 +1,53 @@ +// Code copied from https://github.com/libp2p/go-libp2p/blob/9bd85029550a084fca63ec6ff9184122cdf06591/p2p/muxer/mplex/transport_test.go +package mplex + +import ( + "errors" + "net" + "testing" + + "github.com/libp2p/go-libp2p/core/network" + test "github.com/libp2p/go-libp2p/p2p/muxer/testsuite" +) + +func TestDefaultTransport(t *testing.T) { + test.SubtestAll(t, DefaultTransport) +} + +type memoryScope struct { + network.PeerScope + limit int + reserved int +} + +func (m *memoryScope) ReserveMemory(size int, prio uint8) error { + if m.reserved+size > m.limit { + return errors.New("too much") + } + m.reserved += size + return nil +} + +func (m *memoryScope) ReleaseMemory(size int) { + m.reserved -= size + if m.reserved < 0 { + panic("too much memory released") + } +} + +type memoryLimitedTransport struct { + Transport +} + +func (t *memoryLimitedTransport) NewConn(nc net.Conn, isServer bool, scope network.PeerScope) (network.MuxedConn, error) { + return t.Transport.NewConn(nc, isServer, &memoryScope{ + limit: 3 * 1 << 20, + PeerScope: scope, + }) +} + +func TestDefaultTransportWithMemoryLimit(t *testing.T) { + test.SubtestAll(t, &memoryLimitedTransport{ + Transport: *DefaultTransport, + }) +} diff --git a/core/node/libp2p/routingopt_test.go b/core/node/libp2p/routingopt_test.go index 7a19b9d84..801fc0344 100644 --- a/core/node/libp2p/routingopt_test.go +++ b/core/node/libp2p/routingopt_test.go @@ -8,26 +8,26 @@ import ( ) func TestHttpAddrsFromConfig(t *testing.T) { - require.Equal(t, []string{"/ip4/0.0.0.0/tcp/4001", "/ip4/0.0.0.0/udp/4001/quic"}, + require.Equal(t, []string{"/ip4/0.0.0.0/tcp/4001", "/ip4/0.0.0.0/udp/4001/quic-v1"}, httpAddrsFromConfig(config.Addresses{ - Swarm: []string{"/ip4/0.0.0.0/tcp/4001", "/ip4/0.0.0.0/udp/4001/quic"}, + Swarm: []string{"/ip4/0.0.0.0/tcp/4001", "/ip4/0.0.0.0/udp/4001/quic-v1"}, }), "Swarm addrs should be taken by default") require.Equal(t, []string{"/ip4/192.168.0.1/tcp/4001"}, httpAddrsFromConfig(config.Addresses{ - Swarm: []string{"/ip4/0.0.0.0/tcp/4001", "/ip4/0.0.0.0/udp/4001/quic"}, + Swarm: []string{"/ip4/0.0.0.0/tcp/4001", "/ip4/0.0.0.0/udp/4001/quic-v1"}, Announce: []string{"/ip4/192.168.0.1/tcp/4001"}, }), "Announce addrs should override Swarm if specified") - require.Equal(t, []string{"/ip4/0.0.0.0/udp/4001/quic"}, + require.Equal(t, []string{"/ip4/0.0.0.0/udp/4001/quic-v1"}, httpAddrsFromConfig(config.Addresses{ - Swarm: []string{"/ip4/0.0.0.0/tcp/4001", "/ip4/0.0.0.0/udp/4001/quic"}, + Swarm: []string{"/ip4/0.0.0.0/tcp/4001", "/ip4/0.0.0.0/udp/4001/quic-v1"}, NoAnnounce: []string{"/ip4/0.0.0.0/tcp/4001"}, }), "Swarm addrs should not contain NoAnnounce addrs") require.Equal(t, []string{"/ip4/192.168.0.1/tcp/4001", "/ip4/192.168.0.2/tcp/4001"}, httpAddrsFromConfig(config.Addresses{ - Swarm: []string{"/ip4/0.0.0.0/tcp/4001", "/ip4/0.0.0.0/udp/4001/quic"}, + Swarm: []string{"/ip4/0.0.0.0/tcp/4001", "/ip4/0.0.0.0/udp/4001/quic-v1"}, Announce: []string{"/ip4/192.168.0.1/tcp/4001"}, AppendAnnounce: []string{"/ip4/192.168.0.2/tcp/4001"}, }), "AppendAnnounce addrs should be included if specified") diff --git a/core/node/libp2p/smux.go b/core/node/libp2p/smux.go index 0777928a8..d96dacf0a 100644 --- a/core/node/libp2p/smux.go +++ b/core/node/libp2p/smux.go @@ -7,8 +7,8 @@ import ( "github.com/ipfs/kubo/config" + "github.com/ipfs/kubo/core/node/libp2p/internal/mplex" "github.com/libp2p/go-libp2p" - "github.com/libp2p/go-libp2p/p2p/muxer/mplex" "github.com/libp2p/go-libp2p/p2p/muxer/yamux" ) diff --git a/docs/config.md b/docs/config.md index 6b8b271b7..c24b2b23f 100644 --- a/docs/config.md +++ b/docs/config.md @@ -372,19 +372,18 @@ Supported Transports: * tcp/ip{4,6} - `/ipN/.../tcp/...` * websocket - `/ipN/.../tcp/.../ws` -* quic (Draft-29) - `/ipN/.../udp/.../quic` - can share the same two tuple with `/quic-v1` and `/quic-v1/webtransport` -* quicv1 (RFC9000) - `/ipN/.../udp/.../quic-v1` - can share the same two tuple with `/quic` and `/quic-v1/webtransport` -* webtransport `/ipN/.../udp/.../quic-v1/webtransport` - can share the same two tuple with `/quic` and `/quic-v1` +* quicv1 (RFC9000) - `/ipN/.../udp/.../quic-v1` - can share the same two tuple with `/quic-v1/webtransport` +* webtransport `/ipN/.../udp/.../quic-v1/webtransport` - can share the same two tuple with `/quic-v1` + +Note that quic (Draft-29) used to be supported with the format `/ipN/.../udp/.../quic`, but has since been [removed](https://github.com/libp2p/go-libp2p/releases/tag/v0.30.0). Default: ```json [ "/ip4/0.0.0.0/tcp/4001", "/ip6/::/tcp/4001", - "/ip4/0.0.0.0/udp/4001/quic", "/ip4/0.0.0.0/udp/4001/quic-v1", "/ip4/0.0.0.0/udp/4001/quic-v1/webtransport", - "/ip6/::/udp/4001/quic", "/ip6/::/udp/4001/quic-v1", "/ip6/::/udp/4001/quic-v1/webtransport" ] @@ -1315,7 +1314,7 @@ The set of peers with which to peer. }, { "ID": "QmPeerID2", - "Addrs": ["/ip4/18.1.1.2/tcp/4001", "/ip4/18.1.1.2/udp/4001/quic"] + "Addrs": ["/ip4/18.1.1.2/tcp/4001", "/ip4/18.1.1.2/udp/4001/quic-v1"] } ] } @@ -1999,8 +1998,8 @@ Default: Enabled Type: `flag` Listen Addresses: -* /ip4/0.0.0.0/udp/4001/quic (default) -* /ip6/::/udp/4001/quic (default) +* /ip4/0.0.0.0/udp/4001/quic-v1 (default) +* /ip6/::/udp/4001/quic-v1 (default) #### `Swarm.Transports.Network.Relay` diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 153968077..29aa6c5a7 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,10 +7,10 @@ go 1.20 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.12.0 + github.com/ipfs/boxo v0.12.1-0.20230822135301-303595bcdba7 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 - github.com/libp2p/go-libp2p v0.29.2 - github.com/multiformats/go-multiaddr v0.10.1 + github.com/libp2p/go-libp2p v0.30.0 + github.com/multiformats/go-multiaddr v0.11.0 ) require ( @@ -50,7 +50,7 @@ require ( github.com/golang/protobuf v1.5.3 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/gopacket v1.1.19 // indirect - github.com/google/pprof v0.0.0-20230705174524-200ffdc848b8 // indirect + github.com/google/pprof v0.0.0-20230821062121-407c9e7a662f // indirect github.com/google/uuid v1.3.0 // indirect github.com/gorilla/mux v1.8.0 // indirect github.com/gorilla/websocket v1.5.0 // indirect @@ -59,7 +59,7 @@ require ( github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/golang-lru v0.5.4 // indirect - github.com/hashicorp/golang-lru/v2 v2.0.2 // indirect + github.com/hashicorp/golang-lru/v2 v2.0.5 // indirect github.com/huin/goupnp v1.2.0 // indirect github.com/ipfs/bbloom v0.0.4 // indirect github.com/ipfs/go-bitfield v1.1.0 // indirect @@ -114,7 +114,7 @@ require ( github.com/libp2p/go-msgio v0.3.0 // indirect github.com/libp2p/go-nat v0.2.0 // indirect github.com/libp2p/go-netroute v0.2.1 // indirect - github.com/libp2p/go-reuseport v0.3.0 // indirect + github.com/libp2p/go-reuseport v0.4.0 // indirect github.com/libp2p/go-yamux/v4 v4.0.1 // indirect github.com/libp2p/zeroconf/v2 v2.2.0 // indirect github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect @@ -136,7 +136,7 @@ require ( github.com/multiformats/go-multistream v0.4.1 // indirect github.com/multiformats/go-varint v0.0.7 // indirect github.com/onsi/ginkgo/v2 v2.11.0 // indirect - github.com/opencontainers/runtime-spec v1.0.2 // indirect + github.com/opencontainers/runtime-spec v1.1.0 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/openzipkin/zipkin-go v0.4.1 // indirect github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect @@ -146,11 +146,10 @@ require ( github.com/prometheus/client_golang v1.16.0 // indirect github.com/prometheus/client_model v0.4.0 // indirect github.com/prometheus/common v0.44.0 // indirect - github.com/prometheus/procfs v0.11.0 // indirect + github.com/prometheus/procfs v0.11.1 // indirect github.com/quic-go/qpack v0.4.0 // indirect - github.com/quic-go/qtls-go1-19 v0.3.3 // indirect - github.com/quic-go/qtls-go1-20 v0.2.3 // indirect - github.com/quic-go/quic-go v0.36.4 // indirect + github.com/quic-go/qtls-go1-20 v0.3.3 // indirect + github.com/quic-go/quic-go v0.38.0 // indirect github.com/quic-go/webtransport-go v0.5.3 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/samber/lo v1.36.0 // indirect @@ -180,16 +179,16 @@ require ( go.uber.org/dig v1.17.0 // indirect go.uber.org/fx v1.20.0 // indirect go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap v1.24.0 // indirect + go.uber.org/zap v1.25.0 // indirect go4.org v0.0.0-20230225012048-214862532bf5 // indirect - golang.org/x/crypto v0.11.0 // indirect - golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 // indirect + golang.org/x/crypto v0.12.0 // indirect + golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 // indirect golang.org/x/mod v0.12.0 // indirect - golang.org/x/net v0.12.0 // indirect + golang.org/x/net v0.14.0 // indirect golang.org/x/sync v0.3.0 // indirect - golang.org/x/sys v0.10.0 // indirect - golang.org/x/text v0.11.0 // indirect - golang.org/x/tools v0.11.0 // indirect + golang.org/x/sys v0.11.0 // indirect + golang.org/x/text v0.12.0 // indirect + golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect gonum.org/v1/gonum v0.13.0 // indirect google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 2f877d604..0a262a497 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -256,8 +256,8 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20230705174524-200ffdc848b8 h1:n6vlPhxsA+BW/XsS5+uqi7GyzaLa5MH7qlSLBZtRdiA= -github.com/google/pprof v0.0.0-20230705174524-200ffdc848b8/go.mod h1:Jh3hGz2jkYak8qXPD19ryItVnUgpgeqzdkY/D0EaeuA= +github.com/google/pprof v0.0.0-20230821062121-407c9e7a662f h1:pDhu5sgp8yJlEF/g6osliIIpF9K4F5jvkULXa4daRDQ= +github.com/google/pprof v0.0.0-20230821062121-407c9e7a662f/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -291,8 +291,8 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= -github.com/hashicorp/golang-lru/v2 v2.0.2 h1:Dwmkdr5Nc/oBiXgJS3CDHNhJtIHkuZ3DZF5twqnfBdU= -github.com/hashicorp/golang-lru/v2 v2.0.2/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= +github.com/hashicorp/golang-lru/v2 v2.0.5 h1:wW7h1TG88eUIJ2i69gaE3uNVtEPIagzhGvHgwfx2Vm4= +github.com/hashicorp/golang-lru/v2 v2.0.5/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huin/goupnp v1.2.0 h1:uOKW26NG1hsSSbXIZ1IR7XP9Gjd1U8pnLaCMgntmkmY= @@ -301,8 +301,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.12.0 h1:AXHg/1ONZdRQHQLgG5JHsSC3XoE4DjCAMgK+asZvUcQ= -github.com/ipfs/boxo v0.12.0/go.mod h1:xAnfiU6PtxWCnRqu7dcXQ10bB5/kvI1kXRotuGqGBhg= +github.com/ipfs/boxo v0.12.1-0.20230822135301-303595bcdba7 h1:f7n4M8UIf+4BY6Q0kcZ5FbpkxKaIqq/BW3evqI87DNo= +github.com/ipfs/boxo v0.12.1-0.20230822135301-303595bcdba7/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= @@ -459,8 +459,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.29.2 h1:uPw/c8hOxoLP/KhFnzlc5Ejqf+OmAL1dwIsqE31WBtY= -github.com/libp2p/go-libp2p v0.29.2/go.mod h1:OU7nSq0aEZMsV2wY8nXn1+XNNt9q2UiR8LjW3Kmp2UE= +github.com/libp2p/go-libp2p v0.30.0 h1:9EZwFtJPFBcs/yJTnP90TpN1hgrT/EsFfM+OZuwV87U= +github.com/libp2p/go-libp2p v0.30.0/go.mod h1:nr2g5V7lfftwgiJ78/HrID+pwvayLyqKCEirT2Y3Byg= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= @@ -493,8 +493,8 @@ github.com/libp2p/go-netroute v0.2.1 h1:V8kVrpD8GK0Riv15/7VN6RbUQ3URNZVosw7H2v9t github.com/libp2p/go-netroute v0.2.1/go.mod h1:hraioZr0fhBjG0ZRXJJ6Zj2IVEVNx6tDTFQfSmcq7mQ= 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= -github.com/libp2p/go-reuseport v0.3.0 h1:iiZslO5byUYZEg9iCwJGf5h+sf1Agmqx2V2FDjPyvUw= -github.com/libp2p/go-reuseport v0.3.0/go.mod h1:laea40AimhtfEqysZ71UpYj4S+R9VpH8PgqLo7L+SwI= +github.com/libp2p/go-reuseport v0.4.0 h1:nR5KU7hD0WxXCJbmw7r2rhRYruNRl2koHw8fQscQm2s= +github.com/libp2p/go-reuseport v0.4.0/go.mod h1:ZtI03j/wO5hZVDFo2jKywN6bYKWLOy8Se6DrI2E1cLU= github.com/libp2p/go-yamux/v4 v4.0.1 h1:FfDR4S1wj6Bw2Pqbc8Uz7pCxeRBPbwsBbEdfwiCypkQ= github.com/libp2p/go-yamux/v4 v4.0.1/go.mod h1:NWjl8ZTLOGlozrXSOZ/HlfG++39iKNnM5wwmtQP1YB4= github.com/libp2p/zeroconf/v2 v2.2.0 h1:Cup06Jv6u81HLhIj1KasuNM/RHHrJ8T7wOTS4+Tv53Q= @@ -554,8 +554,8 @@ github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a github.com/multiformats/go-multiaddr v0.1.0/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo= github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4= -github.com/multiformats/go-multiaddr v0.10.1 h1:HghtFrWyZEPrpTvgAMFJi6gFdgHfs2cb0pyfDsk+lqU= -github.com/multiformats/go-multiaddr v0.10.1/go.mod h1:jLEZsA61rwWNZQTHHnqq2HNa+4os/Hz54eqiRnsRqYQ= +github.com/multiformats/go-multiaddr v0.11.0 h1:XqGyJ8ufbCE0HmTDwx2kPdsrQ36AGPZNZX6s6xfJH10= +github.com/multiformats/go-multiaddr v0.11.0/go.mod h1:gWUm0QLR4thQ6+ZF6SXUw8YjtwQSPapICM+NmCkxHSM= github.com/multiformats/go-multiaddr-dns v0.3.0/go.mod h1:mNzQ4eTGDg0ll1N9jKPOUogZPoJ30W8a7zk66FQPpdQ= github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A= github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk= @@ -600,8 +600,9 @@ github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1Cpa github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.27.8 h1:gegWiwZjBsf2DgiSbf5hpokZ98JVDMcWkUiigk6/KXc= -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/opencontainers/runtime-spec v1.1.0 h1:HHUyrt9mwHUjtasSbXSMvs4cyFxh+Bll4AjJ9odEGpg= +github.com/opencontainers/runtime-spec v1.1.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= @@ -634,16 +635,14 @@ github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7q github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY= github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.11.0 h1:5EAgkfkMl659uZPbe9AS2N68a7Cc1TJbPEuGzFuRbyk= -github.com/prometheus/procfs v0.11.0/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM= +github.com/prometheus/procfs v0.11.1 h1:xRC8Iq1yyca5ypa9n1EZnWZkt7dwcoRPQwX/5gwaUuI= +github.com/prometheus/procfs v0.11.1/go.mod h1:eesXgaPo1q7lBpVMoMy0ZOFTth9hBn4W/y0/p/ScXhY= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= -github.com/quic-go/qtls-go1-19 v0.3.3 h1:wznEHvJwd+2X3PqftRha0SUKmGsnb6dfArMhy9PeJVE= -github.com/quic-go/qtls-go1-19 v0.3.3/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI= -github.com/quic-go/qtls-go1-20 v0.2.3 h1:m575dovXn1y2ATOb1XrRFcrv0F+EQmlowTkoraNkDPI= -github.com/quic-go/qtls-go1-20 v0.2.3/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= -github.com/quic-go/quic-go v0.36.4 h1:CXn/ZLN5Vntlk53fjR+kUMC8Jt7flfQe+I5Ty5A+k0o= -github.com/quic-go/quic-go v0.36.4/go.mod h1:qxQumdeKw5GmWs1OsTZZnOxzSI+RJWuhf1O8FN35L2o= +github.com/quic-go/qtls-go1-20 v0.3.3 h1:17/glZSLI9P9fDAeyCHBFSWSqJcwx1byhLwP5eUIDCM= +github.com/quic-go/qtls-go1-20 v0.3.3/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= +github.com/quic-go/quic-go v0.38.0 h1:T45lASr5q/TrVwt+jrVccmqHhPL2XuSyoCLVCpfOSLc= +github.com/quic-go/quic-go v0.38.0/go.mod h1:MPCuRq7KBK2hNcfKj/1iD1BGuN3eAYMeNxp3T42LRUg= github.com/quic-go/webtransport-go v0.5.3 h1:5XMlzemqB4qmOlgIus5zB45AcZ2kCgCy2EptUrfOPWU= github.com/quic-go/webtransport-go v0.5.3/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= @@ -819,8 +818,8 @@ go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.14.1/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= -go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= -go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= +go.uber.org/zap v1.25.0 h1:4Hvk6GtkucQ790dqmj7l1eEnRdKm3k3ZUrUMS2d5+5c= +go.uber.org/zap v1.25.0/go.mod h1:JIAUzQIH94IC4fOJQm7gMmBJP5k7wQfdcnYdPoEXJYk= go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= go4.org v0.0.0-20200411211856-f5505b9728dd/go.mod h1:CIiUVy99QCPfoE13bO4EZaz5GZMZXMSBGhxRdsvzbkg= go4.org v0.0.0-20230225012048-214862532bf5 h1:nifaUDeh+rPaBCMPMQHZmvJf+QdpLFnuQPwx+LxVmtc= @@ -842,8 +841,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA= -golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= +golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk= +golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -854,8 +853,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 h1:MGwJjxBy0HJshjDNfLsYO8xppfqWlA5ZT9OhtUUhTNw= -golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= +golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 h1:m64FZMko/V45gv0bNmrNYoDEq8U5YUhetc9cBWKS1TQ= +golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63/go.mod h1:0v4NqG35kSWCMzLaMeX+IQrlSnVE/bqGSyC2cz/9Le8= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -923,8 +922,8 @@ golang.org/x/net v0.0.0-20210423184538-5f58ad60dda6/go.mod h1:OJAsFXCWl8Ukc7SiCT golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50= -golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= +golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14= +golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1005,8 +1004,8 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= -golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -1020,8 +1019,8 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4= -golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc= +golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1079,8 +1078,8 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.11.0 h1:EMCa6U9S2LtZXLAMoWiR/R8dAQFRqbAitmbJ2UKhoi8= -golang.org/x/tools v0.11.0/go.mod h1:anzJrxPjNtfgiYQYirP2CPGzGLxrH2u2QBhn6Bf3qY8= +golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 h1:Vve/L0v7CXXuxUmaMGIEK/dEeq7uiqb5qBgQrZzIE7E= +golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/docs/file-transfer.md b/docs/file-transfer.md index 8f38ca765..a1a1d1c59 100644 --- a/docs/file-transfer.md +++ b/docs/file-transfer.md @@ -46,9 +46,9 @@ addresses (like the example below), then your nodes are online. "PublicKey": "CAASpgIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZb6znj3LQZKP1+X81exf+vbnqNCMtHjZ5RKTCm7Fytnfe+AI1fhs9YbZdkgFkM1HLxmIOLQj2bMXPIGxUM+EnewN8tWurx4B3+lR/LWNwNYcCFL+jF2ltc6SE6BC8kMLEZd4zidOLPZ8lIRpd0x3qmsjhGefuRwrKeKlR4tQ3C76ziOms47uLdiVVkl5LyJ5+mn4rXOjNKt/oy2O4m1St7X7/yNt8qQgYsPfe/hCOywxCEIHEkqmil+vn7bu4RpAtsUzCcBDoLUIWuU3i6qfytD05hP8Clo+at+l//ctjMxylf3IQ5qyP+yfvazk+WHcsB0tWueEmiU5P2nfUUIR3AgMBAAE=", "Addresses": [ "/ip4/127.0.0.1/tcp/4001/p2p/QmTNwsFkLAed15kQEC1ZJWPfoNbBQnMFojfJKQ9sZj1dk8", - "/ip4/127.0.0.1/udp/4001/quic/p2p/QmTNwsFkLAed15kQEC1ZJWPfoNbBQnMFojfJKQ9sZj1dk8", + "/ip4/127.0.0.1/udp/4001/quic-v1/p2p/QmTNwsFkLAed15kQEC1ZJWPfoNbBQnMFojfJKQ9sZj1dk8", "/ip4/192.168.2.131/tcp/4001/p2p/QmTNwsFkLAed15kQEC1ZJWPfoNbBQnMFojfJKQ9sZj1dk8", - "/ip4/192.168.2.131/udp/4001/quic/p2p/QmTNwsFkLAed15kQEC1ZJWPfoNbBQnMFojfJKQ9sZj1dk8", + "/ip4/192.168.2.131/udp/4001/quic-v1/p2p/QmTNwsFkLAed15kQEC1ZJWPfoNbBQnMFojfJKQ9sZj1dk8", ], "AgentVersion": "go-ipfs/0.4.11-dev/", "ProtocolVersion": "ipfs/0.1.0" @@ -92,11 +92,11 @@ Example output of addresses might look something like this: ``` /ip4/127.0.0.1/tcp/4001 -/ip4/127.0.0.1/udp/4001/quic +/ip4/127.0.0.1/udp/4001/quic-v1 /ip4/192.168.2.133/tcp/4001 -/ip4/192.168.2.133/udp/4001/quic +/ip4/192.168.2.133/udp/4001/quic-v1 /ip4/88.157.217.196/tcp/63674 -/ip4/88.157.217.196/udp/63674/quic +/ip4/88.157.217.196/udp/63674/quic-v1 ``` In this case, we can see a localhost (127.0.0.1) address, a LAN address (the diff --git a/go.mod b/go.mod index b0dded118..caebd660e 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( github.com/fsnotify/fsnotify v1.6.0 github.com/google/uuid v1.3.0 github.com/hashicorp/go-multierror v1.1.1 - github.com/ipfs/boxo v0.12.0 + github.com/ipfs/boxo v0.12.1-0.20230822135301-303595bcdba7 github.com/ipfs/go-block-format v0.1.2 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 @@ -45,7 +45,7 @@ require ( github.com/jbenet/goprocess v0.1.4 github.com/julienschmidt/httprouter v1.3.0 github.com/libp2p/go-doh-resolver v0.4.0 - github.com/libp2p/go-libp2p v0.29.2 + github.com/libp2p/go-libp2p v0.30.0 github.com/libp2p/go-libp2p-http v0.5.0 github.com/libp2p/go-libp2p-kad-dht v0.24.2 github.com/libp2p/go-libp2p-kbucket v0.6.3 @@ -54,9 +54,10 @@ require ( github.com/libp2p/go-libp2p-record v0.2.0 github.com/libp2p/go-libp2p-routing-helpers v0.7.1 github.com/libp2p/go-libp2p-testing v0.12.0 + github.com/libp2p/go-mplex v0.7.0 github.com/libp2p/go-socket-activation v0.1.0 github.com/mitchellh/go-homedir v1.1.0 - github.com/multiformats/go-multiaddr v0.10.1 + github.com/multiformats/go-multiaddr v0.11.0 github.com/multiformats/go-multiaddr-dns v0.3.1 github.com/multiformats/go-multibase v0.2.0 github.com/multiformats/go-multicodec v0.9.0 @@ -80,12 +81,12 @@ require ( go.uber.org/dig v1.17.0 go.uber.org/fx v1.20.0 go.uber.org/multierr v1.11.0 - go.uber.org/zap v1.24.0 - golang.org/x/crypto v0.11.0 - golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 + go.uber.org/zap v1.25.0 + golang.org/x/crypto v0.12.0 + golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 golang.org/x/mod v0.12.0 golang.org/x/sync v0.3.0 - golang.org/x/sys v0.10.0 + golang.org/x/sys v0.11.0 google.golang.org/protobuf v1.31.0 ) @@ -123,14 +124,14 @@ require ( github.com/golang/protobuf v1.5.3 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/gopacket v1.1.19 // indirect - github.com/google/pprof v0.0.0-20230705174524-200ffdc848b8 // indirect + github.com/google/pprof v0.0.0-20230821062121-407c9e7a662f // indirect github.com/gorilla/mux v1.8.0 // indirect github.com/gorilla/websocket v1.5.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 // indirect github.com/hannahhoward/go-pubsub v0.0.0-20200423002714-8d62886cc36e // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/golang-lru v0.5.4 // indirect - github.com/hashicorp/golang-lru/v2 v2.0.2 // indirect + github.com/hashicorp/golang-lru/v2 v2.0.5 // indirect github.com/huin/goupnp v1.2.0 // indirect github.com/ipfs/bbloom v0.0.4 // indirect github.com/ipfs/go-bitfield v1.1.0 // indirect @@ -157,11 +158,10 @@ require ( github.com/libp2p/go-libp2p-asn-util v0.3.0 // indirect github.com/libp2p/go-libp2p-gostream v0.6.0 // indirect github.com/libp2p/go-libp2p-xor v0.1.0 // indirect - github.com/libp2p/go-mplex v0.7.0 // indirect github.com/libp2p/go-msgio v0.3.0 // indirect github.com/libp2p/go-nat v0.2.0 // indirect github.com/libp2p/go-netroute v0.2.1 // indirect - github.com/libp2p/go-reuseport v0.3.0 // indirect + github.com/libp2p/go-reuseport v0.4.0 // indirect github.com/libp2p/go-yamux/v4 v4.0.1 // indirect github.com/libp2p/zeroconf/v2 v2.2.0 // indirect github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect @@ -181,19 +181,18 @@ require ( github.com/multiformats/go-multistream v0.4.1 // indirect github.com/multiformats/go-varint v0.0.7 // indirect github.com/onsi/ginkgo/v2 v2.11.0 // indirect - github.com/opencontainers/runtime-spec v1.0.2 // indirect + github.com/opencontainers/runtime-spec v1.1.0 // indirect github.com/openzipkin/zipkin-go v0.4.1 // indirect github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/polydawn/refmt v0.89.0 // indirect github.com/prometheus/client_model v0.4.0 // indirect github.com/prometheus/common v0.44.0 // indirect - github.com/prometheus/procfs v0.11.0 // indirect + github.com/prometheus/procfs v0.11.1 // indirect github.com/prometheus/statsd_exporter v0.22.7 // indirect github.com/quic-go/qpack v0.4.0 // indirect - github.com/quic-go/qtls-go1-19 v0.3.3 // indirect - github.com/quic-go/qtls-go1-20 v0.2.3 // indirect - github.com/quic-go/quic-go v0.36.4 // indirect + github.com/quic-go/qtls-go1-20 v0.3.3 // indirect + github.com/quic-go/quic-go v0.38.0 // indirect github.com/quic-go/webtransport-go v0.5.3 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/rs/cors v1.7.0 // indirect @@ -223,11 +222,11 @@ require ( go.opentelemetry.io/proto/otlp v0.19.0 // indirect go.uber.org/atomic v1.11.0 // indirect go4.org v0.0.0-20230225012048-214862532bf5 // indirect - golang.org/x/net v0.12.0 // indirect + golang.org/x/net v0.14.0 // indirect golang.org/x/oauth2 v0.8.0 // indirect - golang.org/x/term v0.10.0 // indirect - golang.org/x/text v0.11.0 // indirect - golang.org/x/tools v0.11.0 // indirect + golang.org/x/term v0.11.0 // indirect + golang.org/x/text v0.12.0 // indirect + golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect gonum.org/v1/gonum v0.13.0 // indirect google.golang.org/appengine v1.6.7 // indirect diff --git a/go.sum b/go.sum index 6e4845f99..2ffd7ff35 100644 --- a/go.sum +++ b/go.sum @@ -290,8 +290,8 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20230705174524-200ffdc848b8 h1:n6vlPhxsA+BW/XsS5+uqi7GyzaLa5MH7qlSLBZtRdiA= -github.com/google/pprof v0.0.0-20230705174524-200ffdc848b8/go.mod h1:Jh3hGz2jkYak8qXPD19ryItVnUgpgeqzdkY/D0EaeuA= +github.com/google/pprof v0.0.0-20230821062121-407c9e7a662f h1:pDhu5sgp8yJlEF/g6osliIIpF9K4F5jvkULXa4daRDQ= +github.com/google/pprof v0.0.0-20230821062121-407c9e7a662f/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -325,8 +325,8 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= -github.com/hashicorp/golang-lru/v2 v2.0.2 h1:Dwmkdr5Nc/oBiXgJS3CDHNhJtIHkuZ3DZF5twqnfBdU= -github.com/hashicorp/golang-lru/v2 v2.0.2/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= +github.com/hashicorp/golang-lru/v2 v2.0.5 h1:wW7h1TG88eUIJ2i69gaE3uNVtEPIagzhGvHgwfx2Vm4= +github.com/hashicorp/golang-lru/v2 v2.0.5/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huin/goupnp v1.2.0 h1:uOKW26NG1hsSSbXIZ1IR7XP9Gjd1U8pnLaCMgntmkmY= @@ -335,8 +335,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.12.0 h1:AXHg/1ONZdRQHQLgG5JHsSC3XoE4DjCAMgK+asZvUcQ= -github.com/ipfs/boxo v0.12.0/go.mod h1:xAnfiU6PtxWCnRqu7dcXQ10bB5/kvI1kXRotuGqGBhg= +github.com/ipfs/boxo v0.12.1-0.20230822135301-303595bcdba7 h1:f7n4M8UIf+4BY6Q0kcZ5FbpkxKaIqq/BW3evqI87DNo= +github.com/ipfs/boxo v0.12.1-0.20230822135301-303595bcdba7/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= @@ -515,8 +515,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.29.2 h1:uPw/c8hOxoLP/KhFnzlc5Ejqf+OmAL1dwIsqE31WBtY= -github.com/libp2p/go-libp2p v0.29.2/go.mod h1:OU7nSq0aEZMsV2wY8nXn1+XNNt9q2UiR8LjW3Kmp2UE= +github.com/libp2p/go-libp2p v0.30.0 h1:9EZwFtJPFBcs/yJTnP90TpN1hgrT/EsFfM+OZuwV87U= +github.com/libp2p/go-libp2p v0.30.0/go.mod h1:nr2g5V7lfftwgiJ78/HrID+pwvayLyqKCEirT2Y3Byg= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= @@ -554,8 +554,8 @@ github.com/libp2p/go-netroute v0.2.1 h1:V8kVrpD8GK0Riv15/7VN6RbUQ3URNZVosw7H2v9t github.com/libp2p/go-netroute v0.2.1/go.mod h1:hraioZr0fhBjG0ZRXJJ6Zj2IVEVNx6tDTFQfSmcq7mQ= 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= -github.com/libp2p/go-reuseport v0.3.0 h1:iiZslO5byUYZEg9iCwJGf5h+sf1Agmqx2V2FDjPyvUw= -github.com/libp2p/go-reuseport v0.3.0/go.mod h1:laea40AimhtfEqysZ71UpYj4S+R9VpH8PgqLo7L+SwI= +github.com/libp2p/go-reuseport v0.4.0 h1:nR5KU7hD0WxXCJbmw7r2rhRYruNRl2koHw8fQscQm2s= +github.com/libp2p/go-reuseport v0.4.0/go.mod h1:ZtI03j/wO5hZVDFo2jKywN6bYKWLOy8Se6DrI2E1cLU= 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= github.com/libp2p/go-yamux/v4 v4.0.1 h1:FfDR4S1wj6Bw2Pqbc8Uz7pCxeRBPbwsBbEdfwiCypkQ= @@ -630,8 +630,8 @@ github.com/multiformats/go-multiaddr v0.1.0/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lg github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo= github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4= github.com/multiformats/go-multiaddr v0.4.0/go.mod h1:YcpyLH8ZPudLxQlemYBPhSm0/oCXAT8Z4mzFpyoPyRc= -github.com/multiformats/go-multiaddr v0.10.1 h1:HghtFrWyZEPrpTvgAMFJi6gFdgHfs2cb0pyfDsk+lqU= -github.com/multiformats/go-multiaddr v0.10.1/go.mod h1:jLEZsA61rwWNZQTHHnqq2HNa+4os/Hz54eqiRnsRqYQ= +github.com/multiformats/go-multiaddr v0.11.0 h1:XqGyJ8ufbCE0HmTDwx2kPdsrQ36AGPZNZX6s6xfJH10= +github.com/multiformats/go-multiaddr v0.11.0/go.mod h1:gWUm0QLR4thQ6+ZF6SXUw8YjtwQSPapICM+NmCkxHSM= github.com/multiformats/go-multiaddr-dns v0.3.0/go.mod h1:mNzQ4eTGDg0ll1N9jKPOUogZPoJ30W8a7zk66FQPpdQ= github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A= github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk= @@ -678,8 +678,9 @@ github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1Cpa github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.27.8 h1:gegWiwZjBsf2DgiSbf5hpokZ98JVDMcWkUiigk6/KXc= -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/opencontainers/runtime-spec v1.1.0 h1:HHUyrt9mwHUjtasSbXSMvs4cyFxh+Bll4AjJ9odEGpg= +github.com/opencontainers/runtime-spec v1.1.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= @@ -737,18 +738,16 @@ github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4O github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= -github.com/prometheus/procfs v0.11.0 h1:5EAgkfkMl659uZPbe9AS2N68a7Cc1TJbPEuGzFuRbyk= -github.com/prometheus/procfs v0.11.0/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM= +github.com/prometheus/procfs v0.11.1 h1:xRC8Iq1yyca5ypa9n1EZnWZkt7dwcoRPQwX/5gwaUuI= +github.com/prometheus/procfs v0.11.1/go.mod h1:eesXgaPo1q7lBpVMoMy0ZOFTth9hBn4W/y0/p/ScXhY= github.com/prometheus/statsd_exporter v0.22.7 h1:7Pji/i2GuhK6Lu7DHrtTkFmNBCudCPT1pX2CziuyQR0= github.com/prometheus/statsd_exporter v0.22.7/go.mod h1:N/TevpjkIh9ccs6nuzY3jQn9dFqnUakOjnEuMPJJJnI= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= -github.com/quic-go/qtls-go1-19 v0.3.3 h1:wznEHvJwd+2X3PqftRha0SUKmGsnb6dfArMhy9PeJVE= -github.com/quic-go/qtls-go1-19 v0.3.3/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI= -github.com/quic-go/qtls-go1-20 v0.2.3 h1:m575dovXn1y2ATOb1XrRFcrv0F+EQmlowTkoraNkDPI= -github.com/quic-go/qtls-go1-20 v0.2.3/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= -github.com/quic-go/quic-go v0.36.4 h1:CXn/ZLN5Vntlk53fjR+kUMC8Jt7flfQe+I5Ty5A+k0o= -github.com/quic-go/quic-go v0.36.4/go.mod h1:qxQumdeKw5GmWs1OsTZZnOxzSI+RJWuhf1O8FN35L2o= +github.com/quic-go/qtls-go1-20 v0.3.3 h1:17/glZSLI9P9fDAeyCHBFSWSqJcwx1byhLwP5eUIDCM= +github.com/quic-go/qtls-go1-20 v0.3.3/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= +github.com/quic-go/quic-go v0.38.0 h1:T45lASr5q/TrVwt+jrVccmqHhPL2XuSyoCLVCpfOSLc= +github.com/quic-go/quic-go v0.38.0/go.mod h1:MPCuRq7KBK2hNcfKj/1iD1BGuN3eAYMeNxp3T42LRUg= github.com/quic-go/webtransport-go v0.5.3 h1:5XMlzemqB4qmOlgIus5zB45AcZ2kCgCy2EptUrfOPWU= github.com/quic-go/webtransport-go v0.5.3/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= @@ -956,8 +955,8 @@ go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.14.1/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= -go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= -go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= +go.uber.org/zap v1.25.0 h1:4Hvk6GtkucQ790dqmj7l1eEnRdKm3k3ZUrUMS2d5+5c= +go.uber.org/zap v1.25.0/go.mod h1:JIAUzQIH94IC4fOJQm7gMmBJP5k7wQfdcnYdPoEXJYk= go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= go4.org v0.0.0-20200411211856-f5505b9728dd/go.mod h1:CIiUVy99QCPfoE13bO4EZaz5GZMZXMSBGhxRdsvzbkg= go4.org v0.0.0-20230225012048-214862532bf5 h1:nifaUDeh+rPaBCMPMQHZmvJf+QdpLFnuQPwx+LxVmtc= @@ -979,8 +978,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA= -golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= +golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk= +golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -991,8 +990,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 h1:MGwJjxBy0HJshjDNfLsYO8xppfqWlA5ZT9OhtUUhTNw= -golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= +golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 h1:m64FZMko/V45gv0bNmrNYoDEq8U5YUhetc9cBWKS1TQ= +golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63/go.mod h1:0v4NqG35kSWCMzLaMeX+IQrlSnVE/bqGSyC2cz/9Le8= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1066,8 +1065,8 @@ golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50= -golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= +golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14= +golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1165,14 +1164,14 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= -golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.10.0 h1:3R7pNqamzBraeqj/Tj8qt1aQ2HpmlC+Cx/qL/7hn4/c= -golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= +golang.org/x/term v0.11.0 h1:F9tnn/DA/Im8nCwm+fX+1/eBwi4qFjRT++MhtVC4ZX0= +golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1182,8 +1181,8 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4= -golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc= +golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1241,8 +1240,8 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.11.0 h1:EMCa6U9S2LtZXLAMoWiR/R8dAQFRqbAitmbJ2UKhoi8= -golang.org/x/tools v0.11.0/go.mod h1:anzJrxPjNtfgiYQYirP2CPGzGLxrH2u2QBhn6Bf3qY8= +golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 h1:Vve/L0v7CXXuxUmaMGIEK/dEeq7uiqb5qBgQrZzIE7E= +golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 7a99935a3..0f4d63482 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -7,7 +7,7 @@ replace github.com/ipfs/kubo => ../../ require ( github.com/Kubuxu/gocovmerge v0.0.0-20161216165753-7ecaa51963cd github.com/golangci/golangci-lint v1.54.1 - github.com/ipfs/boxo v0.12.0 + github.com/ipfs/boxo v0.12.1-0.20230822135301-303595bcdba7 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 github.com/ipfs/go-datastore v0.6.0 @@ -19,8 +19,8 @@ require ( github.com/ipld/go-ipld-prime v0.21.0 github.com/jbenet/go-random v0.0.0-20190219211222-123a90aedc0c github.com/jbenet/go-random-files v0.0.0-20190219210431-31b3f20ebded - github.com/libp2p/go-libp2p v0.29.2 - github.com/multiformats/go-multiaddr v0.10.1 + github.com/libp2p/go-libp2p v0.30.0 + github.com/multiformats/go-multiaddr v0.11.0 github.com/multiformats/go-multihash v0.2.3 gotest.tools/gotestsum v0.4.2 ) @@ -106,7 +106,7 @@ require ( github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4 // indirect github.com/google/go-cmp v0.5.9 // indirect github.com/google/gopacket v1.1.19 // indirect - github.com/google/pprof v0.0.0-20230705174524-200ffdc848b8 // indirect + github.com/google/pprof v0.0.0-20230821062121-407c9e7a662f // indirect github.com/google/uuid v1.3.0 // indirect github.com/gordonklaus/ineffassign v0.0.0-20230610083614-0e73809eb601 // indirect github.com/gorilla/websocket v1.5.0 // indirect @@ -120,7 +120,7 @@ require ( github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-version v1.6.0 // indirect github.com/hashicorp/golang-lru v0.5.4 // indirect - github.com/hashicorp/golang-lru/v2 v2.0.2 // indirect + github.com/hashicorp/golang-lru/v2 v2.0.5 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/hexops/gotextdiff v1.0.3 // indirect github.com/huin/goupnp v1.2.0 // indirect @@ -168,7 +168,7 @@ require ( github.com/libp2p/go-msgio v0.3.0 // indirect github.com/libp2p/go-nat v0.2.0 // indirect github.com/libp2p/go-netroute v0.2.1 // indirect - github.com/libp2p/go-reuseport v0.3.0 // indirect + github.com/libp2p/go-reuseport v0.4.0 // indirect github.com/libp2p/go-yamux/v4 v4.0.1 // indirect github.com/lufeee/execinquery v1.2.1 // indirect github.com/magiconair/properties v1.8.6 // indirect @@ -205,7 +205,7 @@ require ( github.com/nunnatsa/ginkgolinter v0.13.3 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/onsi/ginkgo/v2 v2.11.0 // indirect - github.com/opencontainers/runtime-spec v1.0.2 // indirect + github.com/opencontainers/runtime-spec v1.1.0 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect github.com/pelletier/go-toml v1.9.5 // indirect @@ -217,15 +217,14 @@ require ( github.com/prometheus/client_golang v1.16.0 // indirect github.com/prometheus/client_model v0.4.0 // indirect github.com/prometheus/common v0.44.0 // indirect - github.com/prometheus/procfs v0.11.0 // indirect + github.com/prometheus/procfs v0.11.1 // indirect github.com/quasilyte/go-ruleguard v0.4.0 // indirect github.com/quasilyte/gogrep v0.5.0 // indirect github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727 // indirect github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 // indirect github.com/quic-go/qpack v0.4.0 // indirect - github.com/quic-go/qtls-go1-19 v0.3.3 // indirect - github.com/quic-go/qtls-go1-20 v0.2.3 // indirect - github.com/quic-go/quic-go v0.36.4 // indirect + github.com/quic-go/qtls-go1-20 v0.3.3 // indirect + github.com/quic-go/quic-go v0.38.0 // indirect github.com/quic-go/webtransport-go v0.5.3 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect @@ -278,9 +277,9 @@ require ( go.uber.org/dig v1.17.0 // indirect go.uber.org/fx v1.20.0 // indirect go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap v1.24.0 // indirect + go.uber.org/zap v1.25.0 // indirect golang.org/x/crypto v0.12.0 // indirect - golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 // indirect + golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 // indirect golang.org/x/exp/typeparams v0.0.0-20230307190834-24139beb5833 // indirect golang.org/x/mod v0.12.0 // indirect golang.org/x/net v0.14.0 // indirect @@ -288,7 +287,7 @@ require ( golang.org/x/sys v0.11.0 // indirect golang.org/x/term v0.11.0 // indirect golang.org/x/text v0.12.0 // indirect - golang.org/x/tools v0.12.0 // indirect + golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 // indirect google.golang.org/protobuf v1.31.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index dbe3b4faf..c662b3ea3 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -334,8 +334,8 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20230705174524-200ffdc848b8 h1:n6vlPhxsA+BW/XsS5+uqi7GyzaLa5MH7qlSLBZtRdiA= -github.com/google/pprof v0.0.0-20230705174524-200ffdc848b8/go.mod h1:Jh3hGz2jkYak8qXPD19ryItVnUgpgeqzdkY/D0EaeuA= +github.com/google/pprof v0.0.0-20230821062121-407c9e7a662f h1:pDhu5sgp8yJlEF/g6osliIIpF9K4F5jvkULXa4daRDQ= +github.com/google/pprof v0.0.0-20230821062121-407c9e7a662f/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -381,8 +381,8 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= -github.com/hashicorp/golang-lru/v2 v2.0.2 h1:Dwmkdr5Nc/oBiXgJS3CDHNhJtIHkuZ3DZF5twqnfBdU= -github.com/hashicorp/golang-lru/v2 v2.0.2/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= +github.com/hashicorp/golang-lru/v2 v2.0.5 h1:wW7h1TG88eUIJ2i69gaE3uNVtEPIagzhGvHgwfx2Vm4= +github.com/hashicorp/golang-lru/v2 v2.0.5/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= @@ -396,8 +396,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.12.0 h1:AXHg/1ONZdRQHQLgG5JHsSC3XoE4DjCAMgK+asZvUcQ= -github.com/ipfs/boxo v0.12.0/go.mod h1:xAnfiU6PtxWCnRqu7dcXQ10bB5/kvI1kXRotuGqGBhg= +github.com/ipfs/boxo v0.12.1-0.20230822135301-303595bcdba7 h1:f7n4M8UIf+4BY6Q0kcZ5FbpkxKaIqq/BW3evqI87DNo= +github.com/ipfs/boxo v0.12.1-0.20230822135301-303595bcdba7/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.1.2 h1:GAjkfhVx1f4YTODS6Esrj1wt2HhrtwTnhEr+DyPUaJo= @@ -542,8 +542,8 @@ github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38y github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.29.2 h1:uPw/c8hOxoLP/KhFnzlc5Ejqf+OmAL1dwIsqE31WBtY= -github.com/libp2p/go-libp2p v0.29.2/go.mod h1:OU7nSq0aEZMsV2wY8nXn1+XNNt9q2UiR8LjW3Kmp2UE= +github.com/libp2p/go-libp2p v0.30.0 h1:9EZwFtJPFBcs/yJTnP90TpN1hgrT/EsFfM+OZuwV87U= +github.com/libp2p/go-libp2p v0.30.0/go.mod h1:nr2g5V7lfftwgiJ78/HrID+pwvayLyqKCEirT2Y3Byg= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= @@ -554,8 +554,8 @@ github.com/libp2p/go-nat v0.2.0 h1:Tyz+bUFAYqGyJ/ppPPymMGbIgNRH+WqC5QrT5fKrrGk= github.com/libp2p/go-nat v0.2.0/go.mod h1:3MJr+GRpRkyT65EpVPBstXLvOlAPzUVlG6Pwg9ohLJk= github.com/libp2p/go-netroute v0.2.1 h1:V8kVrpD8GK0Riv15/7VN6RbUQ3URNZVosw7H2v9tksU= github.com/libp2p/go-netroute v0.2.1/go.mod h1:hraioZr0fhBjG0ZRXJJ6Zj2IVEVNx6tDTFQfSmcq7mQ= -github.com/libp2p/go-reuseport v0.3.0 h1:iiZslO5byUYZEg9iCwJGf5h+sf1Agmqx2V2FDjPyvUw= -github.com/libp2p/go-reuseport v0.3.0/go.mod h1:laea40AimhtfEqysZ71UpYj4S+R9VpH8PgqLo7L+SwI= +github.com/libp2p/go-reuseport v0.4.0 h1:nR5KU7hD0WxXCJbmw7r2rhRYruNRl2koHw8fQscQm2s= +github.com/libp2p/go-reuseport v0.4.0/go.mod h1:ZtI03j/wO5hZVDFo2jKywN6bYKWLOy8Se6DrI2E1cLU= github.com/libp2p/go-yamux/v4 v4.0.1 h1:FfDR4S1wj6Bw2Pqbc8Uz7pCxeRBPbwsBbEdfwiCypkQ= github.com/libp2p/go-yamux/v4 v4.0.1/go.mod h1:NWjl8ZTLOGlozrXSOZ/HlfG++39iKNnM5wwmtQP1YB4= github.com/lufeee/execinquery v1.2.1 h1:hf0Ems4SHcUGBxpGN7Jz78z1ppVkP/837ZlETPCEtOM= @@ -628,8 +628,8 @@ github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9 github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4= github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo= github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4= -github.com/multiformats/go-multiaddr v0.10.1 h1:HghtFrWyZEPrpTvgAMFJi6gFdgHfs2cb0pyfDsk+lqU= -github.com/multiformats/go-multiaddr v0.10.1/go.mod h1:jLEZsA61rwWNZQTHHnqq2HNa+4os/Hz54eqiRnsRqYQ= +github.com/multiformats/go-multiaddr v0.11.0 h1:XqGyJ8ufbCE0HmTDwx2kPdsrQ36AGPZNZX6s6xfJH10= +github.com/multiformats/go-multiaddr v0.11.0/go.mod h1:gWUm0QLR4thQ6+ZF6SXUw8YjtwQSPapICM+NmCkxHSM= github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A= github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk= github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E= @@ -671,8 +671,9 @@ github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.27.8 h1:gegWiwZjBsf2DgiSbf5hpokZ98JVDMcWkUiigk6/KXc= -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/opencontainers/runtime-spec v1.1.0 h1:HHUyrt9mwHUjtasSbXSMvs4cyFxh+Bll4AjJ9odEGpg= +github.com/opencontainers/runtime-spec v1.1.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= @@ -727,8 +728,8 @@ github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsT github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.11.0 h1:5EAgkfkMl659uZPbe9AS2N68a7Cc1TJbPEuGzFuRbyk= -github.com/prometheus/procfs v0.11.0/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM= +github.com/prometheus/procfs v0.11.1 h1:xRC8Iq1yyca5ypa9n1EZnWZkt7dwcoRPQwX/5gwaUuI= +github.com/prometheus/procfs v0.11.1/go.mod h1:eesXgaPo1q7lBpVMoMy0ZOFTth9hBn4W/y0/p/ScXhY= github.com/quasilyte/go-ruleguard v0.4.0 h1:DyM6r+TKL+xbKB4Nm7Afd1IQh9kEUKQs2pboWGKtvQo= github.com/quasilyte/go-ruleguard v0.4.0/go.mod h1:Eu76Z/R8IXtViWUIHkE3p8gdH3/PKk1eh3YGfaEof10= github.com/quasilyte/gogrep v0.5.0 h1:eTKODPXbI8ffJMN+W2aE0+oL0z/nh8/5eNdiO34SOAo= @@ -739,12 +740,10 @@ github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 h1:M8mH9eK4OUR4l github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567/go.mod h1:DWNGW8A4Y+GyBgPuaQJuWiy0XYftx4Xm/y5Jqk9I6VQ= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= -github.com/quic-go/qtls-go1-19 v0.3.3 h1:wznEHvJwd+2X3PqftRha0SUKmGsnb6dfArMhy9PeJVE= -github.com/quic-go/qtls-go1-19 v0.3.3/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI= -github.com/quic-go/qtls-go1-20 v0.2.3 h1:m575dovXn1y2ATOb1XrRFcrv0F+EQmlowTkoraNkDPI= -github.com/quic-go/qtls-go1-20 v0.2.3/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= -github.com/quic-go/quic-go v0.36.4 h1:CXn/ZLN5Vntlk53fjR+kUMC8Jt7flfQe+I5Ty5A+k0o= -github.com/quic-go/quic-go v0.36.4/go.mod h1:qxQumdeKw5GmWs1OsTZZnOxzSI+RJWuhf1O8FN35L2o= +github.com/quic-go/qtls-go1-20 v0.3.3 h1:17/glZSLI9P9fDAeyCHBFSWSqJcwx1byhLwP5eUIDCM= +github.com/quic-go/qtls-go1-20 v0.3.3/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= +github.com/quic-go/quic-go v0.38.0 h1:T45lASr5q/TrVwt+jrVccmqHhPL2XuSyoCLVCpfOSLc= +github.com/quic-go/quic-go v0.38.0/go.mod h1:MPCuRq7KBK2hNcfKj/1iD1BGuN3eAYMeNxp3T42LRUg= github.com/quic-go/webtransport-go v0.5.3 h1:5XMlzemqB4qmOlgIus5zB45AcZ2kCgCy2EptUrfOPWU= github.com/quic-go/webtransport-go v0.5.3/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= @@ -934,7 +933,7 @@ go.uber.org/dig v1.17.0/go.mod h1:rTxpf7l5I0eBTlE6/9RL+lDybC7WFwY2QH55ZSjy1mU= go.uber.org/fx v1.20.0 h1:ZMC/pnRvhsthOZh9MZjMq5U8Or3mA9zBSPaLnzs3ihQ= go.uber.org/fx v1.20.0/go.mod h1:qCUj0btiR3/JnanEr1TYEePfSw6o/4qYJscgvzQ5Ub0= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= -go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA= +go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= @@ -942,8 +941,8 @@ go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN8 go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= -go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= -go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= +go.uber.org/zap v1.25.0 h1:4Hvk6GtkucQ790dqmj7l1eEnRdKm3k3ZUrUMS2d5+5c= +go.uber.org/zap v1.25.0/go.mod h1:JIAUzQIH94IC4fOJQm7gMmBJP5k7wQfdcnYdPoEXJYk= go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -973,8 +972,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 h1:MGwJjxBy0HJshjDNfLsYO8xppfqWlA5ZT9OhtUUhTNw= -golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= +golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 h1:m64FZMko/V45gv0bNmrNYoDEq8U5YUhetc9cBWKS1TQ= +golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63/go.mod h1:0v4NqG35kSWCMzLaMeX+IQrlSnVE/bqGSyC2cz/9Le8= golang.org/x/exp/typeparams v0.0.0-20220428152302-39d4317da171/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/exp/typeparams v0.0.0-20230203172020-98cc5a0785f9/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/exp/typeparams v0.0.0-20230307190834-24139beb5833 h1:jWGQJV4niP+CCmFW9ekjA9Zx8vYORzOUH2/Nl5WPuLQ= @@ -1260,8 +1259,8 @@ golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= golang.org/x/tools v0.5.0/go.mod h1:N+Kgy78s5I24c24dU8OfWNEotWjutIs8SnJvn5IDq+k= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.12.0 h1:YW6HUoUmYBpwSgyaGaZq1fHjrBjX1rlpZ54T6mu2kss= -golang.org/x/tools v0.12.0/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM= +golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 h1:Vve/L0v7CXXuxUmaMGIEK/dEeq7uiqb5qBgQrZzIE7E= +golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/test/sharness/t0120-bootstrap.sh b/test/sharness/t0120-bootstrap.sh index 892c538f1..2922533c6 100755 --- a/test/sharness/t0120-bootstrap.sh +++ b/test/sharness/t0120-bootstrap.sh @@ -10,7 +10,7 @@ BP2="/dnsaddr/bootstrap.libp2p.io/p2p/QmQCU2EcMqAqQPR2i9bChDtGNJchTbq5TbXJJ16u19 BP3="/dnsaddr/bootstrap.libp2p.io/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb" BP4="/dnsaddr/bootstrap.libp2p.io/p2p/QmcZf59bWwK5XFi76CZX8cbJ4BhTzzA3gU1ZjYZcYW3dwt" BP5="/ip4/104.131.131.82/tcp/4001/p2p/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ" -BP6="/ip4/104.131.131.82/udp/4001/quic/p2p/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ" +BP6="/ip4/104.131.131.82/udp/4001/quic-v1/p2p/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ" test_description="Test ipfs repo operations" diff --git a/test/sharness/t0190-quic-ping.sh b/test/sharness/t0190-quic-ping.sh index 0c2970cb9..28335870d 100755 --- a/test/sharness/t0190-quic-ping.sh +++ b/test/sharness/t0190-quic-ping.sh @@ -11,8 +11,8 @@ test_expect_success 'init iptb' ' iptb testbed create -type localipfs -count 2 -init ' -addr1='"[\"/ip4/127.0.0.1/udp/0/quic\"]"' -addr2='"[\"/ip4/127.0.0.1/udp/0/quic\"]"' +addr1='"[\"/ip4/127.0.0.1/udp/0/quic-v1\"]"' +addr2='"[\"/ip4/127.0.0.1/udp/0/quic-v1\"]"' test_expect_success "add QUIC swarm addresses" ' ipfsi 0 config --json Addresses.Swarm '$addr1' && ipfsi 1 config --json Addresses.Swarm '$addr2' From 16859b3c70ee28905deb38a3c6e38420b93f3609 Mon Sep 17 00:00:00 2001 From: Piotr Galar Date: Fri, 25 Aug 2023 08:24:19 +0200 Subject: [PATCH 0836/1212] ci: allow custom tags in docker-image workflow (#10099) * ci: allow custom ref and tags in docker-image workflow * fix: ref default in case the workflow runs on push * chore: remove customisable ref from docker-image --- .github/workflows/docker-image.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index 0a346f310..a4fd6d6e3 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -7,6 +7,10 @@ on: description: 'Push to Docker Hub' required: true default: 'false' + tags: + description: 'Custom tags to use for the push' + required: false + default: '' # # If we decide to build all images on every PR, we should make sure that # # they are NOT pushed to Docker Hub. # pull_request: @@ -51,6 +55,7 @@ jobs: - name: Get tags id: tags + if: github.event.inputs.tags == '' run: | echo "value<> $GITHUB_OUTPUT ./bin/get-docker-tags.sh "$(date -u +%F)" >> $GITHUB_OUTPUT @@ -117,7 +122,7 @@ jobs: context: . push: true file: ./Dockerfile - tags: "${{ steps.tags.outputs.value }}" + tags: "${{ github.event.inputs.tags || steps.tags.outputs.value }}" cache-from: type=local,src=/tmp/.buildx-cache-new cache-to: type=local,dest=/tmp/.buildx-cache-new From 86bde2894fd89e53d7194be9bacd03de45991f12 Mon Sep 17 00:00:00 2001 From: Will Scott Date: Fri, 25 Aug 2023 14:51:47 +0200 Subject: [PATCH 0837/1212] improve error in fuse node failures --- fuse/readonly/readonly_unix.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fuse/readonly/readonly_unix.go b/fuse/readonly/readonly_unix.go index 924aa7893..3ecda1cf3 100644 --- a/fuse/readonly/readonly_unix.go +++ b/fuse/readonly/readonly_unix.go @@ -104,7 +104,7 @@ func (s *Root) Lookup(ctx context.Context, name string) (fs.Node, error) { return nil, syscall.Errno(syscall.ENOTSUP) } if err != nil { - log.Error("could not convert protobuf or raw node") + log.Errorf("could not convert protobuf or raw node: %s", err) return nil, syscall.Errno(syscall.ENOENT) } From 460658620792eb433331142b1435dad89630b15a Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Fri, 25 Aug 2023 17:30:04 +0200 Subject: [PATCH 0838/1212] feat(gateway): expose /routing/v1 server (opt-in) (#9877) --- cmd/ipfs/daemon.go | 10 ++ config/gateway.go | 5 + core/corehttp/routing.go | 129 +++++++++++++++ core/node/libp2p/routingopt.go | 3 +- docs/changelogs/v0.23.md | 8 + docs/config.md | 10 ++ docs/examples/kubo-as-a-library/go.mod | 3 +- docs/examples/kubo-as-a-library/go.sum | 5 +- go.mod | 2 +- go.sum | 4 +- routing/delegated.go | 2 + routing/wrapper.go | 21 +-- test/cli/content_routing_http_test.go | 25 +-- ... delegated_routing_v1_http_client_test.go} | 36 +++-- .../delegated_routing_v1_http_proxy_test.go | 147 ++++++++++++++++++ .../delegated_routing_v1_http_server_test.go | 145 +++++++++++++++++ test/dependencies/go.mod | 2 +- test/dependencies/go.sum | 4 +- 18 files changed, 505 insertions(+), 56 deletions(-) create mode 100644 core/corehttp/routing.go rename test/cli/{delegated_routing_http_test.go => delegated_routing_v1_http_client_test.go} (87%) create mode 100644 test/cli/delegated_routing_v1_http_proxy_test.go create mode 100644 test/cli/delegated_routing_v1_http_server_test.go diff --git a/cmd/ipfs/daemon.go b/cmd/ipfs/daemon.go index 7be97e23b..55ecaf2c0 100644 --- a/cmd/ipfs/daemon.go +++ b/cmd/ipfs/daemon.go @@ -832,6 +832,12 @@ func serveHTTPGateway(req *cmds.Request, cctx *oldcmds.Context) (<-chan error, e fmt.Printf("Gateway server listening on %s\n", listener.Multiaddr()) } + if cfg.Gateway.ExposeRoutingAPI.WithDefault(config.DefaultExposeRoutingAPI) { + for _, listener := range listeners { + fmt.Printf("Routing V1 API exposed at http://%s/routing/v1\n", listener.Addr()) + } + } + cmdctx := *cctx cmdctx.Gateway = true @@ -848,6 +854,10 @@ func serveHTTPGateway(req *cmds.Request, cctx *oldcmds.Context) (<-chan error, e opts = append(opts, corehttp.P2PProxyOption()) } + if cfg.Gateway.ExposeRoutingAPI.WithDefault(config.DefaultExposeRoutingAPI) { + opts = append(opts, corehttp.RoutingOption()) + } + if len(cfg.Gateway.RootRedirect) > 0 { opts = append(opts, corehttp.RedirectOption("", cfg.Gateway.RootRedirect)) } diff --git a/config/gateway.go b/config/gateway.go index a65582849..dee0a93e2 100644 --- a/config/gateway.go +++ b/config/gateway.go @@ -3,6 +3,7 @@ package config const ( DefaultInlineDNSLink = false DefaultDeserializedResponses = true + DefaultExposeRoutingAPI = false ) type GatewaySpec struct { @@ -72,4 +73,8 @@ type Gateway struct { // PublicGateways configures behavior of known public gateways. // Each key is a fully qualified domain name (FQDN). PublicGateways map[string]*GatewaySpec + + // ExposeRoutingAPI configures the gateway port to expose + // routing system as HTTP API at /routing/v1 (https://specs.ipfs.tech/routing/http-routing-v1/). + ExposeRoutingAPI Flag } diff --git a/core/corehttp/routing.go b/core/corehttp/routing.go new file mode 100644 index 000000000..357122a45 --- /dev/null +++ b/core/corehttp/routing.go @@ -0,0 +1,129 @@ +package corehttp + +import ( + "context" + "net" + "net/http" + "time" + + "github.com/ipfs/boxo/ipns" + "github.com/ipfs/boxo/routing/http/server" + "github.com/ipfs/boxo/routing/http/types" + "github.com/ipfs/boxo/routing/http/types/iter" + cid "github.com/ipfs/go-cid" + core "github.com/ipfs/kubo/core" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/routing" +) + +func RoutingOption() ServeOption { + return func(n *core.IpfsNode, _ net.Listener, mux *http.ServeMux) (*http.ServeMux, error) { + handler := server.Handler(&contentRouter{n}) + mux.Handle("/routing/v1/", handler) + return mux, nil + } +} + +type contentRouter struct { + n *core.IpfsNode +} + +func (r *contentRouter) FindProviders(ctx context.Context, key cid.Cid, limit int) (iter.ResultIter[types.Record], error) { + ctx, cancel := context.WithCancel(ctx) + ch := r.n.Routing.FindProvidersAsync(ctx, key, limit) + return iter.ToResultIter[types.Record](&peerChanIter{ + ch: ch, + cancel: cancel, + }), nil +} + +// nolint deprecated +func (r *contentRouter) ProvideBitswap(ctx context.Context, req *server.BitswapWriteProvideRequest) (time.Duration, error) { + return 0, routing.ErrNotSupported +} + +func (r *contentRouter) FindPeers(ctx context.Context, pid peer.ID, limit int) (iter.ResultIter[types.Record], error) { + ctx, cancel := context.WithCancel(ctx) + defer cancel() + + addr, err := r.n.Routing.FindPeer(ctx, pid) + if err != nil { + return nil, err + } + + rec := &types.PeerRecord{ + Schema: types.SchemaPeer, + ID: &addr.ID, + } + + for _, addr := range addr.Addrs { + rec.Addrs = append(rec.Addrs, types.Multiaddr{Multiaddr: addr}) + } + + return iter.ToResultIter[types.Record](iter.FromSlice[types.Record]([]types.Record{rec})), nil +} + +func (r *contentRouter) GetIPNS(ctx context.Context, name ipns.Name) (*ipns.Record, error) { + ctx, cancel := context.WithCancel(ctx) + defer cancel() + + raw, err := r.n.Routing.GetValue(ctx, string(name.RoutingKey())) + if err != nil { + return nil, err + } + + return ipns.UnmarshalRecord(raw) +} + +func (r *contentRouter) PutIPNS(ctx context.Context, name ipns.Name, record *ipns.Record) error { + ctx, cancel := context.WithCancel(ctx) + defer cancel() + + raw, err := ipns.MarshalRecord(record) + if err != nil { + return err + } + + // The caller guarantees that name matches the record. This is double checked + // by the internals of PutValue. + return r.n.Routing.PutValue(ctx, string(name.RoutingKey()), raw) +} + +type peerChanIter struct { + ch <-chan peer.AddrInfo + cancel context.CancelFunc + next *peer.AddrInfo +} + +func (it *peerChanIter) Next() bool { + addr, ok := <-it.ch + if ok { + it.next = &addr + return true + } else { + it.next = nil + return false + } +} + +func (it *peerChanIter) Val() types.Record { + if it.next == nil { + return nil + } + + rec := &types.PeerRecord{ + Schema: types.SchemaPeer, + ID: &it.next.ID, + } + + for _, addr := range it.next.Addrs { + rec.Addrs = append(rec.Addrs, types.Multiaddr{Multiaddr: addr}) + } + + return rec +} + +func (it *peerChanIter) Close() error { + it.cancel() + return nil +} diff --git a/core/node/libp2p/routingopt.go b/core/node/libp2p/routingopt.go index 82b68361d..a58a8c498 100644 --- a/core/node/libp2p/routingopt.go +++ b/core/node/libp2p/routingopt.go @@ -139,7 +139,8 @@ func ConstructDelegatedRouting(routers config.Routers, methods config.Methods, p PeerID: peerID, Addrs: httpAddrsFromConfig(addrs), PrivKeyB64: privKey, - }) + }, + ) } } diff --git a/docs/changelogs/v0.23.md b/docs/changelogs/v0.23.md index c2267a8e1..df6a1c031 100644 --- a/docs/changelogs/v0.23.md +++ b/docs/changelogs/v0.23.md @@ -9,6 +9,7 @@ - [Mplex deprecation](#mplex-deprecation) - [Gateway: meaningful CAR responses on Not Found errors](#gateway-meaningful-car-responses-on-not-found-errors) - [Binary characters in file names: no longer works with old clients and new Kubo servers](#binary-characters-in-file-names-no-longer-works-with-old-clients-and-new-kubo-servers) + - [Self-hosting `/routing/v1` endpoint for delegated routing needs](#self-hosting-routingv1-endpoint-for-delegated-routing-needs) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -59,6 +60,13 @@ the compatibility table: *Old clients can only send Unicode file paths to the server. +#### Self-hosting `/routing/v1` endpoint for delegated routing needs + +The `Routing` system configured in Kubo can be now exposed on the gateway port as a standard +HTTP [Routing V1](https://specs.ipfs.tech/routing/http-routing-v1/) API endpoint. This allows +self-hosting and experimentation with custom delegated routers. This is disabled by default, +but can be enabled by setting [`Gateway.ExposeRoutingAPI`](https://github.com/ipfs/kubo/blob/master/docs/config.md#gatewayexposeroutingapi) to `true` . + ### 📝 Changelog ### 👨‍👩‍👧‍👦 Contributors diff --git a/docs/config.md b/docs/config.md index c24b2b23f..dd3eed390 100644 --- a/docs/config.md +++ b/docs/config.md @@ -658,6 +658,16 @@ Default: `true` Type: `flag` +#### `Gateway.ExposeRoutingAPI` + +An optional flag to expose Kubo `Routing` system on the gateway port as a [Routing +V1](https://specs.ipfs.tech/routing/routing-v1/) endpoint. This only affects your +local gateway, at `127.0.0.1`. + +Default: `false` + +Type: `flag` + ### `Gateway.HTTPHeaders` Headers to set on gateway responses. diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 29aa6c5a7..bb88ad996 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.20 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.12.1-0.20230822135301-303595bcdba7 + github.com/ipfs/boxo v0.12.1-0.20230825151903-13569468babd github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.30.0 github.com/multiformats/go-multiaddr v0.11.0 @@ -52,7 +52,6 @@ require ( github.com/google/gopacket v1.1.19 // indirect github.com/google/pprof v0.0.0-20230821062121-407c9e7a662f // indirect github.com/google/uuid v1.3.0 // indirect - github.com/gorilla/mux v1.8.0 // indirect github.com/gorilla/websocket v1.5.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 // indirect github.com/hannahhoward/go-pubsub v0.0.0-20200423002714-8d62886cc36e // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 0a262a497..0ab47be1a 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -270,7 +270,6 @@ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5m github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c h1:7lF+Vz0LqiRidnzC1Oq86fpX1q/iEv2KJdrCtttYjT4= github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= -github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= @@ -301,8 +300,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.12.1-0.20230822135301-303595bcdba7 h1:f7n4M8UIf+4BY6Q0kcZ5FbpkxKaIqq/BW3evqI87DNo= -github.com/ipfs/boxo v0.12.1-0.20230822135301-303595bcdba7/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk= +github.com/ipfs/boxo v0.12.1-0.20230825151903-13569468babd h1:uAp9W7FRQ7W16FENlURZqBh7/3PnakG0DjHpKPirKVY= +github.com/ipfs/boxo v0.12.1-0.20230825151903-13569468babd/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= diff --git a/go.mod b/go.mod index caebd660e..d3ff353c6 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( github.com/fsnotify/fsnotify v1.6.0 github.com/google/uuid v1.3.0 github.com/hashicorp/go-multierror v1.1.1 - github.com/ipfs/boxo v0.12.1-0.20230822135301-303595bcdba7 + github.com/ipfs/boxo v0.12.1-0.20230825151903-13569468babd github.com/ipfs/go-block-format v0.1.2 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 diff --git a/go.sum b/go.sum index 2ffd7ff35..e478ea733 100644 --- a/go.sum +++ b/go.sum @@ -335,8 +335,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.12.1-0.20230822135301-303595bcdba7 h1:f7n4M8UIf+4BY6Q0kcZ5FbpkxKaIqq/BW3evqI87DNo= -github.com/ipfs/boxo v0.12.1-0.20230822135301-303595bcdba7/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk= +github.com/ipfs/boxo v0.12.1-0.20230825151903-13569468babd h1:uAp9W7FRQ7W16FENlURZqBh7/3PnakG0DjHpKPirKVY= +github.com/ipfs/boxo v0.12.1-0.20230825151903-13569468babd/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= diff --git a/routing/delegated.go b/routing/delegated.go index 6d34970f5..e830c1aa1 100644 --- a/routing/delegated.go +++ b/routing/delegated.go @@ -224,6 +224,8 @@ func httpRoutingFromConfig(conf config.Router, extraHTTP *ExtraHTTPParams) (rout return &httpRoutingWrapper{ ContentRouting: cr, + PeerRouting: cr, + ValueStore: cr, ProvideManyRouter: cr, }, nil } diff --git a/routing/wrapper.go b/routing/wrapper.go index 10df177e0..680aef263 100644 --- a/routing/wrapper.go +++ b/routing/wrapper.go @@ -4,7 +4,6 @@ import ( "context" routinghelpers "github.com/libp2p/go-libp2p-routing-helpers" - "github.com/libp2p/go-libp2p/core/peer" "github.com/libp2p/go-libp2p/core/routing" ) @@ -22,27 +21,11 @@ var ( // http delegated routing. type httpRoutingWrapper struct { routing.ContentRouting + routing.PeerRouting + routing.ValueStore routinghelpers.ProvideManyRouter } func (c *httpRoutingWrapper) Bootstrap(ctx context.Context) error { return nil } - -func (c *httpRoutingWrapper) FindPeer(ctx context.Context, id peer.ID) (peer.AddrInfo, error) { - return peer.AddrInfo{}, routing.ErrNotSupported -} - -func (c *httpRoutingWrapper) PutValue(context.Context, string, []byte, ...routing.Option) error { - return routing.ErrNotSupported -} - -func (c *httpRoutingWrapper) GetValue(context.Context, string, ...routing.Option) ([]byte, error) { - return nil, routing.ErrNotSupported -} - -func (c *httpRoutingWrapper) SearchValue(context.Context, string, ...routing.Option) (<-chan []byte, error) { - out := make(chan []byte) - close(out) - return out, routing.ErrNotSupported -} diff --git a/test/cli/content_routing_http_test.go b/test/cli/content_routing_http_test.go index 01b602bb7..652c8ac59 100644 --- a/test/cli/content_routing_http_test.go +++ b/test/cli/content_routing_http_test.go @@ -16,42 +16,45 @@ import ( "github.com/ipfs/go-cid" "github.com/ipfs/kubo/test/cli/harness" "github.com/ipfs/kubo/test/cli/testutils" + "github.com/libp2p/go-libp2p/core/peer" "github.com/libp2p/go-libp2p/core/routing" "github.com/stretchr/testify/assert" ) type fakeHTTPContentRouter struct { - m sync.Mutex - findProvidersCalls int - provideCalls int + m sync.Mutex + provideBitswapCalls int + findProvidersCalls int + findPeersCalls int } -func (r *fakeHTTPContentRouter) FindProviders(ctx context.Context, key cid.Cid, limit int) (iter.ResultIter[types.ProviderResponse], error) { +func (r *fakeHTTPContentRouter) FindProviders(ctx context.Context, key cid.Cid, limit int) (iter.ResultIter[types.Record], error) { r.m.Lock() defer r.m.Unlock() r.findProvidersCalls++ - return iter.FromSlice([]iter.Result[types.ProviderResponse]{}), nil + return iter.FromSlice([]iter.Result[types.Record]{}), nil } +// nolint deprecated func (r *fakeHTTPContentRouter) ProvideBitswap(ctx context.Context, req *server.BitswapWriteProvideRequest) (time.Duration, error) { r.m.Lock() defer r.m.Unlock() - r.provideCalls++ + r.provideBitswapCalls++ return 0, nil } -func (r *fakeHTTPContentRouter) Provide(ctx context.Context, req *server.WriteProvideRequest) (types.ProviderResponse, error) { +func (r *fakeHTTPContentRouter) FindPeers(ctx context.Context, pid peer.ID, limit int) (iter.ResultIter[types.Record], error) { r.m.Lock() defer r.m.Unlock() - r.provideCalls++ - return nil, nil + r.findPeersCalls++ + return iter.FromSlice([]iter.Result[types.Record]{}), nil } -func (r *fakeHTTPContentRouter) FindIPNSRecord(ctx context.Context, name ipns.Name) (*ipns.Record, error) { +func (r *fakeHTTPContentRouter) GetIPNS(ctx context.Context, name ipns.Name) (*ipns.Record, error) { return nil, routing.ErrNotSupported } -func (r *fakeHTTPContentRouter) ProvideIPNSRecord(ctx context.Context, name ipns.Name, rec *ipns.Record) error { +func (r *fakeHTTPContentRouter) PutIPNS(ctx context.Context, name ipns.Name, rec *ipns.Record) error { return routing.ErrNotSupported } diff --git a/test/cli/delegated_routing_http_test.go b/test/cli/delegated_routing_v1_http_client_test.go similarity index 87% rename from test/cli/delegated_routing_http_test.go rename to test/cli/delegated_routing_v1_http_client_test.go index c02264f94..44e62246b 100644 --- a/test/cli/delegated_routing_http_test.go +++ b/test/cli/delegated_routing_v1_http_client_test.go @@ -88,12 +88,20 @@ func TestHTTPDelegatedRouting(t *testing.T) { t.Run("adding HTTP delegated routing endpoint to Routing.Routers config works", func(t *testing.T) { server := fakeServer("application/json", ToJSONStr(JSONObj{ - "Providers": []JSONObj{{ - "Protocol": "transport-bitswap", - "Schema": "bitswap", - "ID": provs[0], - "Addrs": []string{"/ip4/0.0.0.0/tcp/4001", "/ip4/0.0.0.0/tcp/4002"}, - }}, + "Providers": []JSONObj{ + { + "Schema": "bitswap", // Legacy bitswap schema. + "Protocol": "transport-bitswap", + "ID": provs[1], + "Addrs": []string{"/ip4/0.0.0.0/tcp/4001", "/ip4/0.0.0.0/tcp/4002"}, + }, + { + "Schema": "peer", + "Protocols": []string{"transport-bitswap"}, + "ID": provs[0], + "Addrs": []string{"/ip4/0.0.0.0/tcp/4001", "/ip4/0.0.0.0/tcp/4002"}, + }, + }, })) t.Cleanup(server.Close) @@ -117,21 +125,21 @@ func TestHTTPDelegatedRouting(t *testing.T) { node.StartDaemon() res = node.IPFS("routing", "findprovs", findProvsCID) - assert.Equal(t, provs[0], res.Stdout.Trimmed()) + assert.Equal(t, provs[1]+"\n"+provs[0], res.Stdout.Trimmed()) }) node.StopDaemon() t.Run("adding HTTP delegated routing endpoint to Routing.Routers config works (streaming)", func(t *testing.T) { server := fakeServer("application/x-ndjson", ToJSONStr(JSONObj{ - "Protocol": "transport-bitswap", - "Schema": "bitswap", - "ID": provs[1], - "Addrs": []string{"/ip4/0.0.0.0/tcp/4001", "/ip4/0.0.0.0/tcp/4002"}, + "Schema": "peer", + "Protocols": []string{"transport-bitswap"}, + "ID": provs[0], + "Addrs": []string{"/ip4/0.0.0.0/tcp/4001", "/ip4/0.0.0.0/tcp/4002"}, }), ToJSONStr(JSONObj{ + "Schema": "bitswap", // Legacy bitswap schema. "Protocol": "transport-bitswap", - "Schema": "bitswap", - "ID": provs[0], + "ID": provs[1], "Addrs": []string{"/ip4/0.0.0.0/tcp/4001", "/ip4/0.0.0.0/tcp/4002"}, })) t.Cleanup(server.Close) @@ -148,7 +156,7 @@ func TestHTTPDelegatedRouting(t *testing.T) { node.StartDaemon() res = node.IPFS("routing", "findprovs", findProvsCID) - assert.Equal(t, provs[1]+"\n"+provs[0], res.Stdout.Trimmed()) + assert.Equal(t, provs[0]+"\n"+provs[1], res.Stdout.Trimmed()) }) t.Run("HTTP client should emit OpenCensus metrics", func(t *testing.T) { diff --git a/test/cli/delegated_routing_v1_http_proxy_test.go b/test/cli/delegated_routing_v1_http_proxy_test.go new file mode 100644 index 000000000..1d80ae50a --- /dev/null +++ b/test/cli/delegated_routing_v1_http_proxy_test.go @@ -0,0 +1,147 @@ +package cli + +import ( + "testing" + + "github.com/ipfs/boxo/ipns" + "github.com/ipfs/kubo/config" + "github.com/ipfs/kubo/test/cli/harness" + "github.com/ipfs/kubo/test/cli/testutils" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestRoutingV1Proxy(t *testing.T) { + t.Parallel() + + setupNodes := func(t *testing.T) harness.Nodes { + nodes := harness.NewT(t).NewNodes(2).Init() + + // Node 0 uses DHT and exposes the Routing API. + nodes[0].UpdateConfig(func(cfg *config.Config) { + cfg.Gateway.ExposeRoutingAPI = config.True + cfg.Discovery.MDNS.Enabled = false + cfg.Routing.Type = config.NewOptionalString("dht") + }) + nodes[0].StartDaemon() + + // Node 1 uses Node 0 as Routing V1 source, no DHT. + nodes[1].UpdateConfig(func(cfg *config.Config) { + cfg.Discovery.MDNS.Enabled = false + cfg.Routing.Type = config.NewOptionalString("custom") + cfg.Routing.Methods = config.Methods{ + config.MethodNameFindPeers: {RouterName: "KuboA"}, + config.MethodNameFindProviders: {RouterName: "KuboA"}, + config.MethodNameGetIPNS: {RouterName: "KuboA"}, + config.MethodNamePutIPNS: {RouterName: "KuboA"}, + config.MethodNameProvide: {RouterName: "KuboA"}, + } + cfg.Routing.Routers = config.Routers{ + "KuboA": config.RouterParser{ + Router: config.Router{ + Type: config.RouterTypeHTTP, + Parameters: &config.HTTPRouterParams{ + Endpoint: nodes[0].GatewayURL(), + }, + }, + }, + } + }) + nodes[1].StartDaemon() + + // Connect them. + nodes.Connect() + + return nodes + } + + t.Run("Kubo can find provider for CID via Routing V1", func(t *testing.T) { + t.Parallel() + nodes := setupNodes(t) + + cidStr := nodes[0].IPFSAddStr(testutils.RandomStr(1000)) + + res := nodes[1].IPFS("routing", "findprovs", cidStr) + assert.Equal(t, nodes[0].PeerID().String(), res.Stdout.Trimmed()) + }) + + t.Run("Kubo can find peer via Routing V1", func(t *testing.T) { + t.Parallel() + nodes := setupNodes(t) + + // Start lonely node that is not connected to other nodes. + node := harness.NewT(t).NewNode().Init() + node.UpdateConfig(func(cfg *config.Config) { + cfg.Discovery.MDNS.Enabled = false + cfg.Routing.Type = config.NewOptionalString("dht") + }) + node.StartDaemon() + + // Connect Node 0 to Lonely Node. + nodes[0].Connect(node) + + // Node 1 must find Lonely Node through Node 0 Routing V1. + res := nodes[1].IPFS("routing", "findpeer", node.PeerID().String()) + assert.Equal(t, node.SwarmAddrs()[0].String(), res.Stdout.Trimmed()) + }) + + t.Run("Kubo can retrieve IPNS record via Routing V1", func(t *testing.T) { + t.Parallel() + nodes := setupNodes(t) + + nodeName := "/ipns/" + ipns.NameFromPeer(nodes[0].PeerID()).String() + + // Can't resolve the name as isn't published yet. + res := nodes[1].RunIPFS("routing", "get", nodeName) + require.Error(t, res.ExitErr) + + // Publish record on Node 0. + path := "/ipfs/" + nodes[0].IPFSAddStr(testutils.RandomStr(1000)) + nodes[0].IPFS("name", "publish", "--allow-offline", path) + + // Get record on Node 1 (no DHT). + res = nodes[1].IPFS("routing", "get", nodeName) + record, err := ipns.UnmarshalRecord(res.Stdout.Bytes()) + require.NoError(t, err) + value, err := record.Value() + require.NoError(t, err) + require.Equal(t, path, value.String()) + }) + + t.Run("Kubo can resolve IPNS name via Routing V1", func(t *testing.T) { + t.Parallel() + nodes := setupNodes(t) + + nodeName := "/ipns/" + ipns.NameFromPeer(nodes[0].PeerID()).String() + + // Can't resolve the name as isn't published yet. + res := nodes[1].RunIPFS("routing", "get", nodeName) + require.Error(t, res.ExitErr) + + // Publish name. + path := "/ipfs/" + nodes[0].IPFSAddStr(testutils.RandomStr(1000)) + nodes[0].IPFS("name", "publish", "--allow-offline", path) + + // Resolve IPNS name + res = nodes[1].IPFS("name", "resolve", nodeName) + require.Equal(t, path, res.Stdout.Trimmed()) + }) + + t.Run("Kubo can provide IPNS record via Routing V1", func(t *testing.T) { + t.Parallel() + nodes := setupNodes(t) + + // Publish something on Node 1 (no DHT). + nodeName := "/ipns/" + ipns.NameFromPeer(nodes[1].PeerID()).String() + path := "/ipfs/" + nodes[1].IPFSAddStr(testutils.RandomStr(1000)) + nodes[1].IPFS("name", "publish", "--allow-offline", path) + + // Retrieve through Node 0. + res := nodes[0].IPFS("routing", "get", nodeName) + record, err := ipns.UnmarshalRecord(res.Stdout.Bytes()) + require.NoError(t, err) + value, err := record.Value() + require.NoError(t, err) + require.Equal(t, path, value.String()) + }) +} diff --git a/test/cli/delegated_routing_v1_http_server_test.go b/test/cli/delegated_routing_v1_http_server_test.go new file mode 100644 index 000000000..440510c1f --- /dev/null +++ b/test/cli/delegated_routing_v1_http_server_test.go @@ -0,0 +1,145 @@ +package cli + +import ( + "context" + "testing" + + "github.com/google/uuid" + "github.com/ipfs/boxo/ipns" + "github.com/ipfs/boxo/routing/http/client" + "github.com/ipfs/boxo/routing/http/types" + "github.com/ipfs/boxo/routing/http/types/iter" + "github.com/ipfs/go-cid" + "github.com/ipfs/kubo/config" + "github.com/ipfs/kubo/test/cli/harness" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/stretchr/testify/assert" +) + +func TestRoutingV1Server(t *testing.T) { + t.Parallel() + + setupNodes := func(t *testing.T) harness.Nodes { + nodes := harness.NewT(t).NewNodes(5).Init() + nodes.ForEachPar(func(node *harness.Node) { + node.UpdateConfig(func(cfg *config.Config) { + cfg.Gateway.ExposeRoutingAPI = config.True + cfg.Routing.Type = config.NewOptionalString("dht") + }) + }) + nodes.StartDaemons().Connect() + return nodes + } + + t.Run("Get Providers Responds With Correct Peers", func(t *testing.T) { + t.Parallel() + nodes := setupNodes(t) + + text := "hello world " + uuid.New().String() + cidStr := nodes[2].IPFSAddStr(text) + _ = nodes[3].IPFSAddStr(text) + + cid, err := cid.Decode(cidStr) + assert.NoError(t, err) + + c, err := client.New(nodes[1].GatewayURL()) + assert.NoError(t, err) + + resultsIter, err := c.FindProviders(context.Background(), cid) + assert.NoError(t, err) + + records, err := iter.ReadAllResults(resultsIter) + assert.NoError(t, err) + + var peers []peer.ID + for _, record := range records { + assert.Equal(t, types.SchemaPeer, record.GetSchema()) + + peer, ok := record.(*types.PeerRecord) + assert.True(t, ok) + peers = append(peers, *peer.ID) + } + + assert.Contains(t, peers, nodes[2].PeerID()) + assert.Contains(t, peers, nodes[3].PeerID()) + }) + + t.Run("Get Peers Responds With Correct Peers", func(t *testing.T) { + t.Parallel() + nodes := setupNodes(t) + + c, err := client.New(nodes[1].GatewayURL()) + assert.NoError(t, err) + + resultsIter, err := c.FindPeers(context.Background(), nodes[2].PeerID()) + assert.NoError(t, err) + + records, err := iter.ReadAllResults(resultsIter) + assert.NoError(t, err) + assert.Len(t, records, 1) + assert.IsType(t, records[0].GetSchema(), records[0].GetSchema()) + assert.IsType(t, records[0], &types.PeerRecord{}) + + peer := records[0].(*types.PeerRecord) + assert.Equal(t, nodes[2].PeerID().String(), peer.ID.String()) + assert.NotEmpty(t, peer.Addrs) + }) + + t.Run("Get IPNS Record Responds With Correct Record", func(t *testing.T) { + t.Parallel() + nodes := setupNodes(t) + + text := "hello ipns test " + uuid.New().String() + cidStr := nodes[0].IPFSAddStr(text) + nodes[0].IPFS("name", "publish", "--allow-offline", cidStr) + + // Ask for record from a different peer. + c, err := client.New(nodes[1].GatewayURL()) + assert.NoError(t, err) + + record, err := c.GetIPNS(context.Background(), ipns.NameFromPeer(nodes[0].PeerID())) + assert.NoError(t, err) + + value, err := record.Value() + assert.NoError(t, err) + assert.Equal(t, "/ipfs/"+cidStr, value.String()) + }) + + t.Run("Put IPNS Record Succeeds", func(t *testing.T) { + t.Parallel() + nodes := setupNodes(t) + + // Publish a record and confirm the /routing/v1/ipns API exposes the IPNS record + text := "hello ipns test " + uuid.New().String() + cidStr := nodes[0].IPFSAddStr(text) + nodes[0].IPFS("name", "publish", "--allow-offline", cidStr) + c, err := client.New(nodes[0].GatewayURL()) + assert.NoError(t, err) + record, err := c.GetIPNS(context.Background(), ipns.NameFromPeer(nodes[0].PeerID())) + assert.NoError(t, err) + value, err := record.Value() + assert.NoError(t, err) + assert.Equal(t, "/ipfs/"+cidStr, value.String()) + + // Start lonely node that is not connected to other nodes. + node := harness.NewT(t).NewNode().Init() + node.UpdateConfig(func(cfg *config.Config) { + cfg.Gateway.ExposeRoutingAPI = config.True + cfg.Routing.Type = config.NewOptionalString("dht") + }) + node.StartDaemon() + + // Put IPNS record in lonely node. It should be accepted as it is a valid record. + c, err = client.New(node.GatewayURL()) + assert.NoError(t, err) + err = c.PutIPNS(context.Background(), ipns.NameFromPeer(nodes[0].PeerID()), record) + assert.NoError(t, err) + + // Get the record from lonely node and double check. + record, err = c.GetIPNS(context.Background(), ipns.NameFromPeer(nodes[0].PeerID())) + assert.NoError(t, err) + value, err = record.Value() + assert.NoError(t, err) + assert.Equal(t, "/ipfs/"+cidStr, value.String()) + }) +} diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 0f4d63482..094cd9797 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -7,7 +7,7 @@ replace github.com/ipfs/kubo => ../../ require ( github.com/Kubuxu/gocovmerge v0.0.0-20161216165753-7ecaa51963cd github.com/golangci/golangci-lint v1.54.1 - github.com/ipfs/boxo v0.12.1-0.20230822135301-303595bcdba7 + github.com/ipfs/boxo v0.12.1-0.20230825151903-13569468babd github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 github.com/ipfs/go-datastore v0.6.0 diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index c662b3ea3..3c8cb6f87 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -396,8 +396,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.12.1-0.20230822135301-303595bcdba7 h1:f7n4M8UIf+4BY6Q0kcZ5FbpkxKaIqq/BW3evqI87DNo= -github.com/ipfs/boxo v0.12.1-0.20230822135301-303595bcdba7/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk= +github.com/ipfs/boxo v0.12.1-0.20230825151903-13569468babd h1:uAp9W7FRQ7W16FENlURZqBh7/3PnakG0DjHpKPirKVY= +github.com/ipfs/boxo v0.12.1-0.20230825151903-13569468babd/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.1.2 h1:GAjkfhVx1f4YTODS6Esrj1wt2HhrtwTnhEr+DyPUaJo= From f7ab1e0b246a9d3c6f933bffc41dd0186f9f51ef Mon Sep 17 00:00:00 2001 From: Santiago Botto Date: Wed, 30 Aug 2023 02:19:37 -0300 Subject: [PATCH 0839/1212] docs: remove link to deleted #accelerated-dht-client --- docs/experimental-features.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/experimental-features.md b/docs/experimental-features.md index 07f7f30f5..587d136d5 100644 --- a/docs/experimental-features.md +++ b/docs/experimental-features.md @@ -26,7 +26,6 @@ the above issue. - [Strategic Providing](#strategic-providing) - [Graphsync](#graphsync) - [Noise](#noise) -- [Accelerated DHT Client](#accelerated-dht-client) - [Optimistic Provide](#optimistic-provide) --- From f7aa1204b177231a3797576e1c01e560bacf66d9 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Wed, 30 Aug 2023 18:47:56 +0200 Subject: [PATCH 0840/1212] feat: add gateway to http over libp2p --- cmd/ipfs/daemon.go | 53 +++++++++++++++++++++++--- core/corehttp/commands.go | 4 +- core/corehttp/corehttp.go | 6 +-- core/corehttp/gateway.go | 27 ++++++++++++- core/corehttp/gateway_test.go | 2 +- docs/examples/kubo-as-a-library/go.mod | 4 +- docs/examples/kubo-as-a-library/go.sum | 8 ++-- go.mod | 4 +- go.sum | 8 ++-- test/dependencies/go.mod | 4 +- test/dependencies/go.sum | 8 ++-- 11 files changed, 96 insertions(+), 32 deletions(-) diff --git a/cmd/ipfs/daemon.go b/cmd/ipfs/daemon.go index 55ecaf2c0..08f49d76c 100644 --- a/cmd/ipfs/daemon.go +++ b/cmd/ipfs/daemon.go @@ -15,6 +15,9 @@ import ( multierror "github.com/hashicorp/go-multierror" + options "github.com/ipfs/boxo/coreiface/options" + cmds "github.com/ipfs/go-ipfs-cmds" + mprome "github.com/ipfs/go-metrics-prometheus" version "github.com/ipfs/kubo" utilmain "github.com/ipfs/kubo/cmd/ipfs/util" oldcmds "github.com/ipfs/kubo/commands" @@ -30,14 +33,12 @@ import ( fsrepo "github.com/ipfs/kubo/repo/fsrepo" "github.com/ipfs/kubo/repo/fsrepo/migrations" "github.com/ipfs/kubo/repo/fsrepo/migrations/ipfsfetcher" + goprocess "github.com/jbenet/goprocess" p2pcrypto "github.com/libp2p/go-libp2p/core/crypto" pnet "github.com/libp2p/go-libp2p/core/pnet" + "github.com/libp2p/go-libp2p/core/protocol" + p2phttp "github.com/libp2p/go-libp2p/p2p/http" sockets "github.com/libp2p/go-socket-activation" - - options "github.com/ipfs/boxo/coreiface/options" - cmds "github.com/ipfs/go-ipfs-cmds" - mprome "github.com/ipfs/go-metrics-prometheus" - goprocess "github.com/jbenet/goprocess" ma "github.com/multiformats/go-multiaddr" manet "github.com/multiformats/go-multiaddr/net" prometheus "github.com/prometheus/client_golang/prometheus" @@ -551,6 +552,12 @@ take effect. return err } + // add trustless gateway over libp2p + p2pGwErrc, err := serveTrustlessGatewayOverLibp2p(cctx) + if err != nil { + return err + } + // Add ipfs version info to prometheus metrics ipfsInfoMetric := promauto.NewGaugeVec(prometheus.GaugeOpts{ Name: "ipfs_info", @@ -617,7 +624,7 @@ take effect. // collect long-running errors and block for shutdown // TODO(cryptix): our fuse currently doesn't follow this pattern for graceful shutdown var errs error - for err := range merge(apiErrc, gwErrc, gcErrc) { + for err := range merge(apiErrc, gwErrc, gcErrc, p2pGwErrc) { if err != nil { errs = multierror.Append(errs, err) } @@ -899,6 +906,40 @@ func serveHTTPGateway(req *cmds.Request, cctx *oldcmds.Context) (<-chan error, e return errc, nil } +const gatewayProtocolID protocol.ID = "/ipfs-gateway" // FIXME: specify https://github.com/ipfs/specs/issues/433 + +func serveTrustlessGatewayOverLibp2p(cctx *oldcmds.Context) (<-chan error, error) { + opts := []corehttp.ServeOption{ + corehttp.MetricsCollectionOption("libp2p-gateway"), + corehttp.TrustlessGatewayOption(), + corehttp.VersionOption(), + } + + node, err := cctx.ConstructNode() + if err != nil { + return nil, fmt.Errorf("serveHTTPGateway: ConstructNode() failed: %s", err) + } + + handler, err := corehttp.MakeHandler(node, nil, opts...) + if err != nil { + return nil, err + } + + h := p2phttp.Host{ + StreamHost: node.PeerHost, + } + + h.SetHTTPHandler(gatewayProtocolID, handler) + + errc := make(chan error, 1) + go func() { + defer close(errc) + errc <- h.Serve() + }() + + return errc, nil +} + // collects options and opens the fuse mountpoint. func mountFuse(req *cmds.Request, cctx *oldcmds.Context) error { cfg, err := cctx.GetConfig() diff --git a/core/corehttp/commands.go b/core/corehttp/commands.go index 63abc5922..53041e86b 100644 --- a/core/corehttp/commands.go +++ b/core/corehttp/commands.go @@ -166,7 +166,7 @@ func CommandsROOption(cctx oldcmds.Context) ServeOption { func CheckVersionOption() ServeOption { daemonVersion := version.ApiVersion - return ServeOption(func(n *core.IpfsNode, l net.Listener, parent *http.ServeMux) (*http.ServeMux, error) { + return func(n *core.IpfsNode, l net.Listener, parent *http.ServeMux) (*http.ServeMux, error) { mux := http.NewServeMux() parent.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { if strings.HasPrefix(r.URL.Path, APIPath) { @@ -188,5 +188,5 @@ func CheckVersionOption() ServeOption { }) return mux, nil - }) + } } diff --git a/core/corehttp/corehttp.go b/core/corehttp/corehttp.go index b1a317f3c..6a9f43b51 100644 --- a/core/corehttp/corehttp.go +++ b/core/corehttp/corehttp.go @@ -31,9 +31,9 @@ const shutdownTimeout = 30 * time.Second // initially passed in if not. type ServeOption func(*core.IpfsNode, net.Listener, *http.ServeMux) (*http.ServeMux, error) -// makeHandler turns a list of ServeOptions into a http.Handler that implements +// MakeHandler turns a list of ServeOptions into a http.Handler that implements // all of the given options, in order. -func makeHandler(n *core.IpfsNode, l net.Listener, options ...ServeOption) (http.Handler, error) { +func MakeHandler(n *core.IpfsNode, l net.Listener, options ...ServeOption) (http.Handler, error) { topMux := http.NewServeMux() mux := topMux for _, option := range options { @@ -86,7 +86,7 @@ func Serve(node *core.IpfsNode, lis net.Listener, options ...ServeOption) error // make sure we close this no matter what. defer lis.Close() - handler, err := makeHandler(node, lis, options...) + handler, err := MakeHandler(node, lis, options...) if err != nil { return err } diff --git a/core/corehttp/gateway.go b/core/corehttp/gateway.go index 105fa89af..a954c92f3 100644 --- a/core/corehttp/gateway.go +++ b/core/corehttp/gateway.go @@ -41,7 +41,7 @@ func GatewayOption(paths ...string) ServeOption { handler = otelhttp.NewHandler(handler, "Gateway") for _, p := range paths { - mux.HandleFunc(p+"/", handler.ServeHTTP) + mux.Handle(p+"/", handler) } return mux, nil @@ -61,7 +61,7 @@ func HostnameOption() ServeOption { } childMux := http.NewServeMux() - mux.HandleFunc("/", gateway.NewHostnameHandler(config, backend, childMux).ServeHTTP) + mux.Handle("/", gateway.NewHostnameHandler(config, backend, childMux)) return childMux, nil } } @@ -76,6 +76,29 @@ func VersionOption() ServeOption { } } +func TrustlessGatewayOption() ServeOption { + return func(n *core.IpfsNode, _ net.Listener, mux *http.ServeMux) (*http.ServeMux, error) { + config, err := getGatewayConfig(n) + if err != nil { + return nil, err + } + + bserv := blockservice.New(n.Blocks.Blockstore(), offline.Exchange(n.Blocks.Blockstore())) + + backend, err := gateway.NewBlocksBackend(bserv) + if err != nil { + return nil, err + } + + handler := gateway.NewHandler(config, &offlineGatewayErrWrapper{gwimpl: backend}) + handler = otelhttp.NewHandler(handler, "Libp2p-Gateway") + + mux.Handle("/ipfs/", handler) + + return mux, nil + } +} + func newGatewayBackend(n *core.IpfsNode) (gateway.IPFSBackend, error) { cfg, err := n.Repo.Config() if err != nil { diff --git a/core/corehttp/gateway_test.go b/core/corehttp/gateway_test.go index 172988bba..b3acda31c 100644 --- a/core/corehttp/gateway_test.go +++ b/core/corehttp/gateway_test.go @@ -121,7 +121,7 @@ func newTestServerAndNode(t *testing.T, ns mockNamesys) (*httptest.Server, iface ts := httptest.NewServer(dh) t.Cleanup(func() { ts.Close() }) - dh.Handler, err = makeHandler(n, + dh.Handler, err = MakeHandler(n, ts.Listener, HostnameOption(), GatewayOption("/ipfs", "/ipns"), diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index bb88ad996..ea374715a 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -9,7 +9,7 @@ replace github.com/ipfs/kubo => ./../../.. require ( github.com/ipfs/boxo v0.12.1-0.20230825151903-13569468babd github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 - github.com/libp2p/go-libp2p v0.30.0 + github.com/libp2p/go-libp2p v0.31.0 github.com/multiformats/go-multiaddr v0.11.0 ) @@ -148,7 +148,7 @@ require ( github.com/prometheus/procfs v0.11.1 // indirect github.com/quic-go/qpack v0.4.0 // indirect github.com/quic-go/qtls-go1-20 v0.3.3 // indirect - github.com/quic-go/quic-go v0.38.0 // indirect + github.com/quic-go/quic-go v0.38.1 // indirect github.com/quic-go/webtransport-go v0.5.3 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/samber/lo v1.36.0 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 0ab47be1a..d401c6fae 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -458,8 +458,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.30.0 h1:9EZwFtJPFBcs/yJTnP90TpN1hgrT/EsFfM+OZuwV87U= -github.com/libp2p/go-libp2p v0.30.0/go.mod h1:nr2g5V7lfftwgiJ78/HrID+pwvayLyqKCEirT2Y3Byg= +github.com/libp2p/go-libp2p v0.31.0 h1:LFShhP8F6xthWiBBq3euxbKjZsoRajVEyBS9snfHxYg= +github.com/libp2p/go-libp2p v0.31.0/go.mod h1:W/FEK1c/t04PbRH3fA9i5oucu5YcgrG0JVoBWT1B7Eg= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= @@ -640,8 +640,8 @@ github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= github.com/quic-go/qtls-go1-20 v0.3.3 h1:17/glZSLI9P9fDAeyCHBFSWSqJcwx1byhLwP5eUIDCM= github.com/quic-go/qtls-go1-20 v0.3.3/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= -github.com/quic-go/quic-go v0.38.0 h1:T45lASr5q/TrVwt+jrVccmqHhPL2XuSyoCLVCpfOSLc= -github.com/quic-go/quic-go v0.38.0/go.mod h1:MPCuRq7KBK2hNcfKj/1iD1BGuN3eAYMeNxp3T42LRUg= +github.com/quic-go/quic-go v0.38.1 h1:M36YWA5dEhEeT+slOu/SwMEucbYd0YFidxG3KlGPZaE= +github.com/quic-go/quic-go v0.38.1/go.mod h1:ijnZM7JsFIkp4cRyjxJNIzdSfCLmUMg9wdyhGmg+SN4= github.com/quic-go/webtransport-go v0.5.3 h1:5XMlzemqB4qmOlgIus5zB45AcZ2kCgCy2EptUrfOPWU= github.com/quic-go/webtransport-go v0.5.3/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= diff --git a/go.mod b/go.mod index d3ff353c6..4150653e2 100644 --- a/go.mod +++ b/go.mod @@ -45,7 +45,7 @@ require ( github.com/jbenet/goprocess v0.1.4 github.com/julienschmidt/httprouter v1.3.0 github.com/libp2p/go-doh-resolver v0.4.0 - github.com/libp2p/go-libp2p v0.30.0 + github.com/libp2p/go-libp2p v0.31.0 github.com/libp2p/go-libp2p-http v0.5.0 github.com/libp2p/go-libp2p-kad-dht v0.24.2 github.com/libp2p/go-libp2p-kbucket v0.6.3 @@ -192,7 +192,7 @@ require ( github.com/prometheus/statsd_exporter v0.22.7 // indirect github.com/quic-go/qpack v0.4.0 // indirect github.com/quic-go/qtls-go1-20 v0.3.3 // indirect - github.com/quic-go/quic-go v0.38.0 // indirect + github.com/quic-go/quic-go v0.38.1 // indirect github.com/quic-go/webtransport-go v0.5.3 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/rs/cors v1.7.0 // indirect diff --git a/go.sum b/go.sum index e478ea733..b116f9894 100644 --- a/go.sum +++ b/go.sum @@ -515,8 +515,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.30.0 h1:9EZwFtJPFBcs/yJTnP90TpN1hgrT/EsFfM+OZuwV87U= -github.com/libp2p/go-libp2p v0.30.0/go.mod h1:nr2g5V7lfftwgiJ78/HrID+pwvayLyqKCEirT2Y3Byg= +github.com/libp2p/go-libp2p v0.31.0 h1:LFShhP8F6xthWiBBq3euxbKjZsoRajVEyBS9snfHxYg= +github.com/libp2p/go-libp2p v0.31.0/go.mod h1:W/FEK1c/t04PbRH3fA9i5oucu5YcgrG0JVoBWT1B7Eg= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= @@ -746,8 +746,8 @@ github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= github.com/quic-go/qtls-go1-20 v0.3.3 h1:17/glZSLI9P9fDAeyCHBFSWSqJcwx1byhLwP5eUIDCM= github.com/quic-go/qtls-go1-20 v0.3.3/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= -github.com/quic-go/quic-go v0.38.0 h1:T45lASr5q/TrVwt+jrVccmqHhPL2XuSyoCLVCpfOSLc= -github.com/quic-go/quic-go v0.38.0/go.mod h1:MPCuRq7KBK2hNcfKj/1iD1BGuN3eAYMeNxp3T42LRUg= +github.com/quic-go/quic-go v0.38.1 h1:M36YWA5dEhEeT+slOu/SwMEucbYd0YFidxG3KlGPZaE= +github.com/quic-go/quic-go v0.38.1/go.mod h1:ijnZM7JsFIkp4cRyjxJNIzdSfCLmUMg9wdyhGmg+SN4= github.com/quic-go/webtransport-go v0.5.3 h1:5XMlzemqB4qmOlgIus5zB45AcZ2kCgCy2EptUrfOPWU= github.com/quic-go/webtransport-go v0.5.3/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 094cd9797..64a0f9bff 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -19,7 +19,7 @@ require ( github.com/ipld/go-ipld-prime v0.21.0 github.com/jbenet/go-random v0.0.0-20190219211222-123a90aedc0c github.com/jbenet/go-random-files v0.0.0-20190219210431-31b3f20ebded - github.com/libp2p/go-libp2p v0.30.0 + github.com/libp2p/go-libp2p v0.31.0 github.com/multiformats/go-multiaddr v0.11.0 github.com/multiformats/go-multihash v0.2.3 gotest.tools/gotestsum v0.4.2 @@ -224,7 +224,7 @@ require ( github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 // indirect github.com/quic-go/qpack v0.4.0 // indirect github.com/quic-go/qtls-go1-20 v0.3.3 // indirect - github.com/quic-go/quic-go v0.38.0 // indirect + github.com/quic-go/quic-go v0.38.1 // indirect github.com/quic-go/webtransport-go v0.5.3 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 3c8cb6f87..89ae1027e 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -542,8 +542,8 @@ github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38y github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.30.0 h1:9EZwFtJPFBcs/yJTnP90TpN1hgrT/EsFfM+OZuwV87U= -github.com/libp2p/go-libp2p v0.30.0/go.mod h1:nr2g5V7lfftwgiJ78/HrID+pwvayLyqKCEirT2Y3Byg= +github.com/libp2p/go-libp2p v0.31.0 h1:LFShhP8F6xthWiBBq3euxbKjZsoRajVEyBS9snfHxYg= +github.com/libp2p/go-libp2p v0.31.0/go.mod h1:W/FEK1c/t04PbRH3fA9i5oucu5YcgrG0JVoBWT1B7Eg= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= @@ -742,8 +742,8 @@ github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= github.com/quic-go/qtls-go1-20 v0.3.3 h1:17/glZSLI9P9fDAeyCHBFSWSqJcwx1byhLwP5eUIDCM= github.com/quic-go/qtls-go1-20 v0.3.3/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= -github.com/quic-go/quic-go v0.38.0 h1:T45lASr5q/TrVwt+jrVccmqHhPL2XuSyoCLVCpfOSLc= -github.com/quic-go/quic-go v0.38.0/go.mod h1:MPCuRq7KBK2hNcfKj/1iD1BGuN3eAYMeNxp3T42LRUg= +github.com/quic-go/quic-go v0.38.1 h1:M36YWA5dEhEeT+slOu/SwMEucbYd0YFidxG3KlGPZaE= +github.com/quic-go/quic-go v0.38.1/go.mod h1:ijnZM7JsFIkp4cRyjxJNIzdSfCLmUMg9wdyhGmg+SN4= github.com/quic-go/webtransport-go v0.5.3 h1:5XMlzemqB4qmOlgIus5zB45AcZ2kCgCy2EptUrfOPWU= github.com/quic-go/webtransport-go v0.5.3/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= From a11c5424085771fde748702185a958d301ebb8f7 Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Thu, 31 Aug 2023 00:30:56 -0400 Subject: [PATCH 0841/1212] test(harness): skip environment variables starting with = --- test/cli/harness/run.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/cli/harness/run.go b/test/cli/harness/run.go index bec05fbce..8ca85eb63 100644 --- a/test/cli/harness/run.go +++ b/test/cli/harness/run.go @@ -48,6 +48,11 @@ func environToMap(environ []string) map[string]string { m := map[string]string{} for _, e := range environ { kv := strings.Split(e, "=") + // Skip environment variables that start with = + // These can occur in Windows https://github.com/golang/go/issues/61956 + if kv[0] == "" { + continue + } m[kv[0]] = kv[1] } return m From fb5cacac86786597bd31d88867d5487ac0224b89 Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Thu, 31 Aug 2023 01:47:35 -0400 Subject: [PATCH 0842/1212] test(harness): use SIGKILL to terminate daemons in Windows testing --- test/cli/harness/node.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/test/cli/harness/node.go b/test/cli/harness/node.go index 9fc01f4d7..7db1d5538 100644 --- a/test/cli/harness/node.go +++ b/test/cli/harness/node.go @@ -11,6 +11,7 @@ import ( "os" "os/exec" "path/filepath" + "runtime" "strconv" "strings" "syscall" @@ -278,6 +279,15 @@ func (n *Node) StopDaemon() *Node { _, _ = n.Daemon.Cmd.Process.Wait() watch <- struct{}{} }() + + // os.Interrupt does not support interrupts on Windows https://github.com/golang/go/issues/46345 + if runtime.GOOS == "windows" { + if n.signalAndWait(watch, syscall.SIGKILL, 5*time.Second) { + return n + } + log.Panicf("timed out stopping node %d with peer ID %s", n.ID, n.PeerID()) + } + log.Debugf("signaling node %d with SIGTERM", n.ID) if n.signalAndWait(watch, syscall.SIGTERM, 1*time.Second) { return n From 5b0da083330841bc031f410b4e503ccc12d9cd49 Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Thu, 31 Aug 2023 03:48:23 -0400 Subject: [PATCH 0843/1212] fix: use /ipfs/gateway as the protocol ID for serving the gateway over libp2p --- cmd/ipfs/daemon.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/ipfs/daemon.go b/cmd/ipfs/daemon.go index 08f49d76c..ed8040c01 100644 --- a/cmd/ipfs/daemon.go +++ b/cmd/ipfs/daemon.go @@ -906,7 +906,7 @@ func serveHTTPGateway(req *cmds.Request, cctx *oldcmds.Context) (<-chan error, e return errc, nil } -const gatewayProtocolID protocol.ID = "/ipfs-gateway" // FIXME: specify https://github.com/ipfs/specs/issues/433 +const gatewayProtocolID protocol.ID = "/ipfs/gateway" // FIXME: specify https://github.com/ipfs/specs/issues/433 func serveTrustlessGatewayOverLibp2p(cctx *oldcmds.Context) (<-chan error, error) { opts := []corehttp.ServeOption{ From 9d32f71e22299604ba7748549eaad4e667198712 Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Thu, 31 Aug 2023 03:49:35 -0400 Subject: [PATCH 0844/1212] move the gateway-over-libp2p mountpoint to the root --- cmd/ipfs/daemon.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/cmd/ipfs/daemon.go b/cmd/ipfs/daemon.go index ed8040c01..b28b59764 100644 --- a/cmd/ipfs/daemon.go +++ b/cmd/ipfs/daemon.go @@ -929,7 +929,13 @@ func serveTrustlessGatewayOverLibp2p(cctx *oldcmds.Context) (<-chan error, error StreamHost: node.PeerHost, } - h.SetHTTPHandler(gatewayProtocolID, handler) + tmpProtocol := protocol.ID("/kubo/delete-me") + h.SetHTTPHandler(tmpProtocol, http.NotFoundHandler()) + h.WellKnownHandler.RemoveProtocolMeta(tmpProtocol) + + h.WellKnownHandler.AddProtocolMeta(gatewayProtocolID, p2phttp.ProtocolMeta{Path: "/"}) + h.ServeMux = http.NewServeMux() + h.ServeMux.Handle("/", handler) errc := make(chan error, 1) go func() { From bc6bee15857b3ca24d319c2d8eb62b75a245b0df Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Thu, 31 Aug 2023 03:51:48 -0400 Subject: [PATCH 0845/1212] rename Libp2pGatewayOption and hard code its gateway configuration --- cmd/ipfs/daemon.go | 2 +- core/corehttp/gateway.go | 16 +++++++++------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/cmd/ipfs/daemon.go b/cmd/ipfs/daemon.go index b28b59764..f11d86952 100644 --- a/cmd/ipfs/daemon.go +++ b/cmd/ipfs/daemon.go @@ -911,7 +911,7 @@ const gatewayProtocolID protocol.ID = "/ipfs/gateway" // FIXME: specify https:// func serveTrustlessGatewayOverLibp2p(cctx *oldcmds.Context) (<-chan error, error) { opts := []corehttp.ServeOption{ corehttp.MetricsCollectionOption("libp2p-gateway"), - corehttp.TrustlessGatewayOption(), + corehttp.Libp2pGatewayOption(), corehttp.VersionOption(), } diff --git a/core/corehttp/gateway.go b/core/corehttp/gateway.go index a954c92f3..4a4f08780 100644 --- a/core/corehttp/gateway.go +++ b/core/corehttp/gateway.go @@ -76,13 +76,8 @@ func VersionOption() ServeOption { } } -func TrustlessGatewayOption() ServeOption { +func Libp2pGatewayOption() ServeOption { return func(n *core.IpfsNode, _ net.Listener, mux *http.ServeMux) (*http.ServeMux, error) { - config, err := getGatewayConfig(n) - if err != nil { - return nil, err - } - bserv := blockservice.New(n.Blocks.Blockstore(), offline.Exchange(n.Blocks.Blockstore())) backend, err := gateway.NewBlocksBackend(bserv) @@ -90,7 +85,14 @@ func TrustlessGatewayOption() ServeOption { return nil, err } - handler := gateway.NewHandler(config, &offlineGatewayErrWrapper{gwimpl: backend}) + gwConfig := gateway.Config{ + DeserializedResponses: false, + NoDNSLink: true, + PublicGateways: nil, + Menu: nil, + } + + handler := gateway.NewHandler(gwConfig, &offlineGatewayErrWrapper{gwimpl: backend}) handler = otelhttp.NewHandler(handler, "Libp2p-Gateway") mux.Handle("/ipfs/", handler) From bf548a3cc625438828aaae9a081b0a97dfb0e821 Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Thu, 31 Aug 2023 04:07:10 -0400 Subject: [PATCH 0846/1212] fix(gateway): close http-over-libp2p host when the node is ready to shutdown --- cmd/ipfs/daemon.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/cmd/ipfs/daemon.go b/cmd/ipfs/daemon.go index f11d86952..0763f6eb2 100644 --- a/cmd/ipfs/daemon.go +++ b/cmd/ipfs/daemon.go @@ -943,6 +943,11 @@ func serveTrustlessGatewayOverLibp2p(cctx *oldcmds.Context) (<-chan error, error errc <- h.Serve() }() + go func() { + <-node.Process.Closing() + h.Close() + }() + return errc, nil } From 2a1d91f67abda10c02072d14539940b777df500b Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Thu, 31 Aug 2023 03:52:51 -0400 Subject: [PATCH 0847/1212] test(gateway): add harness tests for gateway over libp2p --- test/cli/http_gateway_over_libp2p_test.go | 106 ++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 test/cli/http_gateway_over_libp2p_test.go diff --git a/test/cli/http_gateway_over_libp2p_test.go b/test/cli/http_gateway_over_libp2p_test.go new file mode 100644 index 000000000..b4b2cf105 --- /dev/null +++ b/test/cli/http_gateway_over_libp2p_test.go @@ -0,0 +1,106 @@ +package cli + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "testing" + + "github.com/ipfs/go-cid" + "github.com/ipfs/kubo/core/commands" + "github.com/ipfs/kubo/test/cli/harness" + "github.com/libp2p/go-libp2p" + "github.com/libp2p/go-libp2p/core/peer" + libp2phttp "github.com/libp2p/go-libp2p/p2p/http" + "github.com/multiformats/go-multiaddr" + manet "github.com/multiformats/go-multiaddr/net" + "github.com/stretchr/testify/require" +) + +func TestGatewayOverLibp2p(t *testing.T) { + t.Parallel() + nodes := harness.NewT(t).NewNodes(2).Init() + + // Setup streaming functionality + nodes.ForEachPar(func(node *harness.Node) { + node.IPFS("config", "--json", "Experimental.Libp2pStreamMounting", "true") + }) + + gwNode := nodes[0] + p2pProxyNode := nodes[1] + + nodes.StartDaemons().Connect() + + // Add data to the gateway node + cidDataOnGatewayNode := cid.MustParse(gwNode.IPFSAddStr("Hello Worlds2!")) + r := gwNode.GatewayClient().Get(fmt.Sprintf("/ipfs/%s?format=raw", cidDataOnGatewayNode)) + blockDataOnGatewayNode := []byte(r.Body) + + // Add data to the non-gateway node + cidDataNotOnGatewayNode := cid.MustParse(p2pProxyNode.IPFSAddStr("Hello Worlds!")) + r = p2pProxyNode.GatewayClient().Get(fmt.Sprintf("/ipfs/%s?format=raw", cidDataNotOnGatewayNode)) + blockDataNotOnGatewayNode := []byte(r.Body) + _ = blockDataNotOnGatewayNode + + // Setup one of the nodes as http to http-over-libp2p proxy + p2pProxyNode.IPFS("p2p", "forward", "--allow-custom-protocol", "/http/1.1", "/ip4/127.0.0.1/tcp/0", fmt.Sprintf("/p2p/%s", gwNode.PeerID())) + lsOutput := commands.P2PLsOutput{} + if err := json.Unmarshal(p2pProxyNode.IPFS("p2p", "ls", "--enc=json").Stdout.Bytes(), &lsOutput); err != nil { + t.Fatal(err) + } + require.Len(t, lsOutput.Listeners, 1) + p2pProxyNodeHTTPListenMA, err := multiaddr.NewMultiaddr(lsOutput.Listeners[0].ListenAddress) + require.NoError(t, err) + + p2pProxyNodeHTTPListenAddr, err := manet.ToNetAddr(p2pProxyNodeHTTPListenMA) + require.NoError(t, err) + + // Note: the bare HTTP requests here assume that the gateway is mounted at `/` + t.Run("WillNotServeRemoteContent", func(t *testing.T) { + resp, err := http.Get(fmt.Sprintf("http://%s/ipfs/%s?format=raw", p2pProxyNodeHTTPListenAddr, cidDataNotOnGatewayNode)) + require.NoError(t, err) + require.Equal(t, 500, resp.StatusCode) + }) + + t.Run("WillNotServeDeserializedResponses", func(t *testing.T) { + resp, err := http.Get(fmt.Sprintf("http://%s/ipfs/%s", p2pProxyNodeHTTPListenAddr, cidDataOnGatewayNode)) + require.NoError(t, err) + require.Equal(t, http.StatusNotAcceptable, resp.StatusCode) + }) + + t.Run("ServeBlock", func(t *testing.T) { + t.Run("UsingKuboProxy", func(t *testing.T) { + resp, err := http.Get(fmt.Sprintf("http://%s/ipfs/%s?format=raw", p2pProxyNodeHTTPListenAddr, cidDataOnGatewayNode)) + require.NoError(t, err) + defer resp.Body.Close() + require.Equal(t, 200, resp.StatusCode) + body, err := io.ReadAll(resp.Body) + require.NoError(t, err) + require.Equal(t, blockDataOnGatewayNode, body) + }) + t.Run("UsingLibp2pClientWithPathDiscovery", func(t *testing.T) { + clientHost, err := libp2p.New(libp2p.NoListenAddrs) + require.NoError(t, err) + err = clientHost.Connect(context.Background(), peer.AddrInfo{ + ID: gwNode.PeerID(), + Addrs: gwNode.SwarmAddrs(), + }) + require.NoError(t, err) + + client, err := (&libp2phttp.Host{StreamHost: clientHost}).NamespacedClient("/ipfs/gateway", peer.AddrInfo{ID: gwNode.PeerID()}) + require.NoError(t, err) + + resp, err := client.Get(fmt.Sprintf("/ipfs/%s?format=raw", cidDataOnGatewayNode)) + require.NoError(t, err) + defer resp.Body.Close() + require.Equal(t, 200, resp.StatusCode) + + body, err := io.ReadAll(resp.Body) + require.NoError(t, err) + + require.Equal(t, blockDataOnGatewayNode, body) + }) + }) +} From b8c741d8bf18080e1f29c3dadd384b580953ce83 Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Thu, 31 Aug 2023 03:53:48 -0400 Subject: [PATCH 0848/1212] test(gateway-conformance): also run gateway conformance tests against a gateway-over-libp2p endpoint --- .github/workflows/gateway-conformance.yml | 104 +++++++++++++++++++++- 1 file changed, 102 insertions(+), 2 deletions(-) diff --git a/.github/workflows/gateway-conformance.yml b/.github/workflows/gateway-conformance.yml index 928d51c70..a1b96402a 100644 --- a/.github/workflows/gateway-conformance.yml +++ b/.github/workflows/gateway-conformance.yml @@ -58,8 +58,10 @@ jobs: } } run: | - ./ipfs init + ./ipfs init --profile=test ./ipfs config --json Gateway.PublicGateways "$GATEWAY_PUBLIC_GATEWAYS" + ./ipfs config Addresses.Gateway "/ip4/127.0.0.1/tcp/8080" + ./ipfs config Addresses.API "/ip4/127.0.0.1/tcp/5001" working-directory: kubo-gateway/cmd/ipfs # 4. Populate the Kubo gateway with the gateway-conformance fixtures @@ -85,7 +87,28 @@ jobs: # 5. Start the kubo-gateway - name: Start kubo-gateway run: | - ./ipfs daemon --offline & + ./ipfs daemon & + endpoint="http://127.0.0.1:5001/api/v0/version" + max_retries=5 + retry_interval=3 + + check_endpoint() { + curl -X POST --silent --fail "$endpoint" > /dev/null + return $? + } + + retries=0 + while ! check_endpoint; do + retries=$((retries+1)) + + if [ $retries -ge $max_retries ]; then + echo "daemon took too long to start" + exit 1 + fi + + sleep $retry_interval + done + echo "daemon started and ready to receive API calls" working-directory: kubo-gateway/cmd/ipfs # 6. Run the gateway-conformance tests @@ -115,3 +138,80 @@ jobs: with: name: gateway-conformance.json path: output.json + + # 8. Setup a kubo http-p2p-proxy to run gateway conformance tests + - name: Init p2p-proxy kubo node + env: + IPFS_PATH: "~/.kubo-p2p-proxy" + run: | + ./ipfs init --profile=test + ./ipfs config --json Experimental.Libp2pStreamMounting true + ./ipfs config Addresses.Gateway "/ip4/127.0.0.1/tcp/8081" + ./ipfs config Addresses.API "/ip4/127.0.0.1/tcp/5002" + working-directory: kubo-gateway/cmd/ipfs + + # 9. Start the kubo http-p2p-proxy + - name: Start kubo http-p2p-proxy + env: + IPFS_PATH: "~/.kubo-p2p-proxy" + run: | + ./ipfs daemon & + + endpoint="http://127.0.0.1:5002/api/v0/version" + max_retries=5 + retry_interval=3 + + check_endpoint() { + curl -X POST --silent --fail "$endpoint" > /dev/null + return $? + } + + retries=0 + while ! check_endpoint; do + retries=$((retries+1)) + + if [ $retries -ge $max_retries ]; then + echo "daemon took too long to start" + exit 1 + fi + + sleep $retry_interval + done + echo "daemon started and ready to receive API calls" + working-directory: kubo-gateway/cmd/ipfs + + # 10. Start forwarding data from the http-p2p-proxy to the node serving the Gateway API over libp2p + - name: Start http-over-libp2p forwarding proxy + run: | + gatewayNodeId=$(./ipfs --api=/ip4/127.0.0.1/tcp/5001 id -f="") + ./ipfs --api=/ip4/127.0.0.1/tcp/5002 swarm connect $(./ipfs --api=/ip4/127.0.0.1/tcp/5001 swarm addrs local --id | head -n 1) + ./ipfs --api=/ip4/127.0.0.1/tcp/5002 p2p forward --allow-custom-protocol /http/1.1 /ip4/127.0.0.1/tcp/8082 /p2p/$gatewayNodeId + working-directory: kubo-gateway/cmd/ipfs + + # 11. Run the gateway-conformance tests over libp2p + - name: Run gateway-conformance tests over libp2p + uses: ipfs/gateway-conformance/.github/actions/test@v0.3 + with: + gateway-url: http://127.0.0.1:8081 + json: output.json + xml: output.xml + html: output.html + markdown: output.md + args: --specs "trustless-gateway,-trustless-ipns-gateway" -skip 'TestGatewayCar/GET_response_for_application/vnd.ipld.car/Header_Content-Length' + + # 11. Upload the results + - name: Upload MD summary + if: failure() || success() + run: cat output.md >> $GITHUB_STEP_SUMMARY + - name: Upload HTML report + if: failure() || success() + uses: actions/upload-artifact@v3 + with: + name: gateway-conformance-libp2p.html + path: output.html + - name: Upload JSON report + if: failure() || success() + uses: actions/upload-artifact@v3 + with: + name: gateway-conformance-libp2p.json + path: output.json \ No newline at end of file From f2c43d5bbfb4efec8e32573eff929feed472e734 Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Thu, 31 Aug 2023 05:22:51 -0400 Subject: [PATCH 0849/1212] feat(config): Add gateway-over-libp2p experiment --- .github/workflows/gateway-conformance.yml | 1 + cmd/ipfs/daemon.go | 20 +++++++++--- config/experiments.go | 1 + docs/experimental-features.md | 37 +++++++++++++++++++++++ test/cli/http_gateway_over_libp2p_test.go | 10 ++++++ 5 files changed, 64 insertions(+), 5 deletions(-) diff --git a/.github/workflows/gateway-conformance.yml b/.github/workflows/gateway-conformance.yml index a1b96402a..d49291a43 100644 --- a/.github/workflows/gateway-conformance.yml +++ b/.github/workflows/gateway-conformance.yml @@ -60,6 +60,7 @@ jobs: run: | ./ipfs init --profile=test ./ipfs config --json Gateway.PublicGateways "$GATEWAY_PUBLIC_GATEWAYS" + ./ipfs config --json Experimental.GatewayOverLibp2p true ./ipfs config Addresses.Gateway "/ip4/127.0.0.1/tcp/8080" ./ipfs config Addresses.API "/ip4/127.0.0.1/tcp/5001" working-directory: kubo-gateway/cmd/ipfs diff --git a/cmd/ipfs/daemon.go b/cmd/ipfs/daemon.go index 0763f6eb2..d9207b0f6 100644 --- a/cmd/ipfs/daemon.go +++ b/cmd/ipfs/daemon.go @@ -909,17 +909,27 @@ func serveHTTPGateway(req *cmds.Request, cctx *oldcmds.Context) (<-chan error, e const gatewayProtocolID protocol.ID = "/ipfs/gateway" // FIXME: specify https://github.com/ipfs/specs/issues/433 func serveTrustlessGatewayOverLibp2p(cctx *oldcmds.Context) (<-chan error, error) { + node, err := cctx.ConstructNode() + if err != nil { + return nil, fmt.Errorf("serveHTTPGatewayOverLibp2p: ConstructNode() failed: %s", err) + } + cfg, err := node.Repo.Config() + if err != nil { + return nil, fmt.Errorf("could not read config: %w", err) + } + + if !cfg.Experimental.GatewayOverLibp2p { + errCh := make(chan error) + close(errCh) + return errCh, nil + } + opts := []corehttp.ServeOption{ corehttp.MetricsCollectionOption("libp2p-gateway"), corehttp.Libp2pGatewayOption(), corehttp.VersionOption(), } - node, err := cctx.ConstructNode() - if err != nil { - return nil, fmt.Errorf("serveHTTPGateway: ConstructNode() failed: %s", err) - } - handler, err := corehttp.MakeHandler(node, nil, opts...) if err != nil { return nil, err diff --git a/config/experiments.go b/config/experiments.go index f5ecf4be6..3a63d253d 100644 --- a/config/experiments.go +++ b/config/experiments.go @@ -11,4 +11,5 @@ type Experiments struct { AcceleratedDHTClient experimentalAcceleratedDHTClient `json:",omitempty"` OptimisticProvide bool OptimisticProvideJobsPoolSize int + GatewayOverLibp2p bool `json:",omitempty"` } diff --git a/docs/experimental-features.md b/docs/experimental-features.md index 587d136d5..52bfe703d 100644 --- a/docs/experimental-features.md +++ b/docs/experimental-features.md @@ -27,6 +27,7 @@ the above issue. - [Graphsync](#graphsync) - [Noise](#noise) - [Optimistic Provide](#optimistic-provide) +- [HTTP Gateway over Libp2p](#http-gateway-over-libp2p) --- @@ -617,3 +618,39 @@ ipfs config --json Experimental.OptimisticProvideJobsPoolSize 120 - [ ] Needs more people to use and report on how well it works - [ ] Should prove at least equivalent availability of provider records as the classic approach + +## HTTP Gateway over Libp2p + +### In Version + +0.23.0 + +### State + +Experimental, disabled by default. + +Enables serving the [IPFS HTTP Gateway](https://specs.ipfs.tech/http-gateways/) protocol over libp2p transports and +as described in the [specification](https://github.com/ipfs/specs/pull/434). + +Notes: +- This feature currently is only about serving the gateway requests over libp2p, not about fetching data this way using +[Trustless Gateway Specification](https://specs.ipfs.tech/http-gateways/trustless-gateway/). +- While kubo currently mounts the gateway API at the root (i.e. `/`) of the libp2p `/http/1.1` protocol that is subject to +change. The way to reliably discover where a given HTTP protocol is mounted on a libp2p endpoint is via the `.well-known/libp2p` +resource specified in the [http+libp2p specification](https://github.com/libp2p/specs/pull/508) +- Kubo currently hard codes the gateway-over-libp2p behavior to: + - Only operate on `/ipfs` resources + - Only satisfy the Trustless Gateway API + - Only serve data that is already local to the node (i.e. similar to a `NoFetch` gateway) + +### How to enable + +Modify your ipfs config: + +``` +ipfs config --json Experimental.GatewayOverLibp2p true +``` + +### Road to being a real feature + +- [ ] Needs more people to use and report on how well it works \ No newline at end of file diff --git a/test/cli/http_gateway_over_libp2p_test.go b/test/cli/http_gateway_over_libp2p_test.go index b4b2cf105..ee5717571 100644 --- a/test/cli/http_gateway_over_libp2p_test.go +++ b/test/cli/http_gateway_over_libp2p_test.go @@ -57,6 +57,16 @@ func TestGatewayOverLibp2p(t *testing.T) { p2pProxyNodeHTTPListenAddr, err := manet.ToNetAddr(p2pProxyNodeHTTPListenMA) require.NoError(t, err) + t.Run("DoesNotWorkWithoutExperimentalConfig", func(t *testing.T) { + _, err := http.Get(fmt.Sprintf("http://%s/ipfs/%s?format=raw", p2pProxyNodeHTTPListenAddr, cidDataOnGatewayNode)) + require.Error(t, err) + }) + + // Enable the experimental feature and reconnect the nodes + gwNode.IPFS("config", "--json", "Experimental.GatewayOverLibp2p", "true") + gwNode.StopDaemon().StartDaemon() + nodes.Connect() + // Note: the bare HTTP requests here assume that the gateway is mounted at `/` t.Run("WillNotServeRemoteContent", func(t *testing.T) { resp, err := http.Get(fmt.Sprintf("http://%s/ipfs/%s?format=raw", p2pProxyNodeHTTPListenAddr, cidDataNotOnGatewayNode)) From d86192a9bf3d5336298a4c08a62b8656addb6600 Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Thu, 31 Aug 2023 05:23:39 -0400 Subject: [PATCH 0850/1212] changelog(gateway-over-libp2p): add gateway-over-libp2p changelog --- docs/changelogs/v0.23.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/docs/changelogs/v0.23.md b/docs/changelogs/v0.23.md index df6a1c031..701f05701 100644 --- a/docs/changelogs/v0.23.md +++ b/docs/changelogs/v0.23.md @@ -10,6 +10,7 @@ - [Gateway: meaningful CAR responses on Not Found errors](#gateway-meaningful-car-responses-on-not-found-errors) - [Binary characters in file names: no longer works with old clients and new Kubo servers](#binary-characters-in-file-names-no-longer-works-with-old-clients-and-new-kubo-servers) - [Self-hosting `/routing/v1` endpoint for delegated routing needs](#self-hosting-routingv1-endpoint-for-delegated-routing-needs) + - [Gateway Over Libp2p Experiment](#gateway-over-libp2p-experiment) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -67,6 +68,20 @@ HTTP [Routing V1](https://specs.ipfs.tech/routing/http-routing-v1/) API endpoint self-hosting and experimentation with custom delegated routers. This is disabled by default, but can be enabled by setting [`Gateway.ExposeRoutingAPI`](https://github.com/ipfs/kubo/blob/master/docs/config.md#gatewayexposeroutingapi) to `true` . +#### Gateway Over Libp2p Experiment + +It is now possible to serve [Trustless Gateway API](https://specs.ipfs.tech/http-gateways/trustless-gateway/) responses +such as for blocks and CARs over libp2p. This takes advantage of the [specification work](https://github.com/libp2p/specs/pull/508) +in libp2p expanding beyond the basics of performing HTTP requests over libp2p streams that have been available in libp2p +and in kubo experimental features such as [p2p-http-proxy](https://github.com/ipfs/kubo/blob/master/docs/experimental-features.md#p2p-http-proxy). + +This means that implementations that want to use the Trustless Gateway API as a data transport mechanism can do so even +when standard HTTP transports would fail (e.g. when the endpoint is behind a firewall, or wants to serve data to a browser +but does not have a CA certificate). + +See [HTTP Gateway over Libp2p](https://github.com/ipfs/kubo/blob/master/docs/experimental-features.md#http-gateway-over-libp2p) +for more details. + ### 📝 Changelog ### 👨‍👩‍👧‍👦 Contributors From df66dacc263c79b5bae54f03cdea5eb16388fa54 Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Fri, 1 Sep 2023 14:28:35 -0400 Subject: [PATCH 0851/1212] test(sharness): update ping test since go-libp2p v0.31.0 changed the reported error message --- test/sharness/t0041-ping.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/sharness/t0041-ping.sh b/test/sharness/t0041-ping.sh index 4bbf89969..6a817060a 100755 --- a/test/sharness/t0041-ping.sh +++ b/test/sharness/t0041-ping.sh @@ -27,7 +27,7 @@ test_expect_success "test ping other" ' test_expect_success "test ping unreachable peer" ' printf "Looking up peer %s\n" "$BAD_PEER" > bad_ping_exp && - printf "PING QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJx.\nPing error: failed to dial: no addresses\nError: ping failed\n" >> bad_ping_exp && + printf "PING QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJx.\nPing error: failed to dial: failed to dial QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJx: no addresses\nError: ping failed\n" >> bad_ping_exp && ! ipfsi 0 ping -n2 -- "$BAD_PEER" > bad_ping_actual 2>&1 && test_cmp bad_ping_exp bad_ping_actual ' From 6e1b731a65b1ae669be0ed9897d5477ce7d12961 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Mon, 4 Sep 2023 10:25:43 +0200 Subject: [PATCH 0852/1212] chore: bump repo version to 15 --- repo/fsrepo/fsrepo.go | 2 +- repo/fsrepo/migrations/fetcher.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/repo/fsrepo/fsrepo.go b/repo/fsrepo/fsrepo.go index 13e7e4150..591d25aee 100644 --- a/repo/fsrepo/fsrepo.go +++ b/repo/fsrepo/fsrepo.go @@ -37,7 +37,7 @@ const LockFile = "repo.lock" var log = logging.Logger("fsrepo") // RepoVersion is the version number that we are currently expecting to see. -var RepoVersion = 14 +var RepoVersion = 15 var migrationInstructions = `See https://github.com/ipfs/fs-repo-migrations/blob/master/run.md Sorry for the inconvenience. In the future, these will run automatically.` diff --git a/repo/fsrepo/migrations/fetcher.go b/repo/fsrepo/migrations/fetcher.go index dc6d3c642..8e18c1b10 100644 --- a/repo/fsrepo/migrations/fetcher.go +++ b/repo/fsrepo/migrations/fetcher.go @@ -11,7 +11,7 @@ import ( const ( // Current distribution to fetch migrations from. - CurrentIpfsDist = "/ipfs/QmYerugGRCZWA8yQMKDsd9daEVXUR3C5nuw3VXuX1mggHa" // fs-repo-13-to-14 v1.0.0 + CurrentIpfsDist = "/ipfs/QmVYvjxCiUxqGjDeREFDy8SbX3zj7vhgeuprk28hgvKEq5" // fs-repo-14-to-15 v1.0.0 // Latest distribution path. Default for fetchers. LatestIpfsDist = "/ipns/dist.ipfs.tech" From 2690e083b4711496c7921f7323e0f17ae8a33b27 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 5 Sep 2023 08:33:32 +0200 Subject: [PATCH 0853/1212] chore(deps): bump actions/checkout from 3 to 4 (#10112) Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 8 ++++---- .github/workflows/codeql-analysis.yml | 2 +- .github/workflows/docker-build.yml | 2 +- .github/workflows/docker-image.yml | 2 +- .github/workflows/gateway-conformance.yml | 2 +- .github/workflows/gobuild.yml | 2 +- .github/workflows/golang-analysis.yml | 2 +- .github/workflows/golint.yml | 2 +- .github/workflows/gotest.yml | 2 +- .github/workflows/sharness.yml | 2 +- 10 files changed, 13 insertions(+), 13 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1c46f5371..a51bddcb2 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -39,7 +39,7 @@ jobs: - uses: actions/setup-go@v3 with: go-version: ${{ env.GO_VERSION }} - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: protocol/cache-go-action@v1 with: name: ${{ github.job }} @@ -76,7 +76,7 @@ jobs: restore-keys: ${{ runner.os }}-${{ github.job }}-${{ matrix.repo-to-test-against }}- - run: sudo apt update - run: sudo apt install -y libxkbcommon0 libxdamage1 libgbm1 libpango-1.0-0 libcairo2 # dependencies for playwright - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: repository: ipfs/${{ matrix.repo-to-test-against }} fetch-depth: 0 @@ -126,7 +126,7 @@ jobs: name: kubo path: cmd/ipfs - run: chmod +x cmd/ipfs/ipfs - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: repository: ipfs/go-ipfs-api path: go-ipfs-api @@ -167,7 +167,7 @@ jobs: name: kubo path: cmd/ipfs - run: chmod +x cmd/ipfs/ipfs - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: repository: ipfs/ipfs-webui path: ipfs-webui diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 04c695467..60bc3c409 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -29,7 +29,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml index bfbd57d9a..3e50cc1f8 100644 --- a/.github/workflows/docker-build.yml +++ b/.github/workflows/docker-build.yml @@ -29,6 +29,6 @@ jobs: - uses: actions/setup-go@v3 with: go-version: 1.20.x - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - run: docker build -t $IMAGE_NAME:$WIP_IMAGE_TAG . - run: docker run --rm $IMAGE_NAME:$WIP_IMAGE_TAG --version diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index a4fd6d6e3..c1e77112d 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -37,7 +37,7 @@ jobs: LEGACY_IMAGE_NAME: ipfs/go-ipfs steps: - name: Check out the repo - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Set up QEMU uses: docker/setup-qemu-action@v2 diff --git a/.github/workflows/gateway-conformance.yml b/.github/workflows/gateway-conformance.yml index 928d51c70..fa422e500 100644 --- a/.github/workflows/gateway-conformance.yml +++ b/.github/workflows/gateway-conformance.yml @@ -34,7 +34,7 @@ jobs: with: go-version: 1.20.x - name: Checkout kubo-gateway - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: path: kubo-gateway - name: Build kubo-gateway diff --git a/.github/workflows/gobuild.yml b/.github/workflows/gobuild.yml index a299e1115..2fc457711 100644 --- a/.github/workflows/gobuild.yml +++ b/.github/workflows/gobuild.yml @@ -31,7 +31,7 @@ jobs: - uses: actions/setup-go@v3 with: go-version: 1.20.x - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: protocol/cache-go-action@v1 with: name: ${{ github.job }} diff --git a/.github/workflows/golang-analysis.yml b/.github/workflows/golang-analysis.yml index 9e70e6b0f..d887bff47 100644 --- a/.github/workflows/golang-analysis.yml +++ b/.github/workflows/golang-analysis.yml @@ -22,7 +22,7 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 10 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: submodules: recursive - uses: actions/setup-go@v2 diff --git a/.github/workflows/golint.yml b/.github/workflows/golint.yml index 28a13b87a..16db613ef 100644 --- a/.github/workflows/golint.yml +++ b/.github/workflows/golint.yml @@ -32,7 +32,7 @@ jobs: - uses: actions/setup-go@v3 with: go-version: 1.20.x - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: protocol/cache-go-action@v1 with: name: ${{ github.job }} diff --git a/.github/workflows/gotest.yml b/.github/workflows/gotest.yml index 1ca6f4619..24d46bd49 100644 --- a/.github/workflows/gotest.yml +++ b/.github/workflows/gotest.yml @@ -34,7 +34,7 @@ jobs: with: go-version: 1.20.x - name: Check out Kubo - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Install missing tools run: sudo apt update && sudo apt install -y zsh - name: Restore Go cache diff --git a/.github/workflows/sharness.yml b/.github/workflows/sharness.yml index 8bed22793..ab80ba4d7 100644 --- a/.github/workflows/sharness.yml +++ b/.github/workflows/sharness.yml @@ -27,7 +27,7 @@ jobs: with: go-version: 1.20.x - name: Checkout Kubo - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: path: kubo - name: Install missing tools From d8bcc4a7f28ed8db6009593a58cbad87258bca14 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 5 Sep 2023 08:45:39 +0200 Subject: [PATCH 0854/1212] chore(deps): bump actions/setup-node from 2 to 3 (#9993) Bumps [actions/setup-node](https://github.com/actions/setup-node) from 2 to 3. - [Release notes](https://github.com/actions/setup-node/releases) - [Commits](https://github.com/actions/setup-node/compare/v2...v3) --- updated-dependencies: - dependency-name: actions/setup-node dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Piotr Galar --- .github/workflows/sync-release-assets.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/sync-release-assets.yml b/.github/workflows/sync-release-assets.yml index 2ade3cbcc..bc7eaed8d 100644 --- a/.github/workflows/sync-release-assets.yml +++ b/.github/workflows/sync-release-assets.yml @@ -22,7 +22,7 @@ jobs: - uses: ipfs/start-ipfs-daemon-action@v1 with: args: --init --init-profile=flatfs,server --enable-gc=false - - uses: actions/setup-node@v2 + - uses: actions/setup-node@v3 with: node-version: 14 - name: Sync the latest 5 github releases From 666fc9f924efc1ace5e1b99e2506007d67b86353 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 5 Sep 2023 08:45:49 +0200 Subject: [PATCH 0855/1212] chore(deps): bump protocol/multiple-go-modules from 1.2 to 1.4 (#9978) Bumps [protocol/multiple-go-modules](https://github.com/protocol/multiple-go-modules) from 1.2 to 1.4. - [Release notes](https://github.com/protocol/multiple-go-modules/releases) - [Commits](https://github.com/protocol/multiple-go-modules/compare/v1.2...v1.4) --- updated-dependencies: - dependency-name: protocol/multiple-go-modules dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Piotr Galar --- .github/workflows/golang-analysis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/golang-analysis.yml b/.github/workflows/golang-analysis.yml index d887bff47..356c5797a 100644 --- a/.github/workflows/golang-analysis.yml +++ b/.github/workflows/golang-analysis.yml @@ -29,7 +29,7 @@ jobs: with: go-version: "1.20.x" - name: Check that go.mod is tidy - uses: protocol/multiple-go-modules@v1.2 + uses: protocol/multiple-go-modules@v1.4 with: run: | go mod tidy @@ -49,6 +49,6 @@ jobs: fi - name: go vet if: always() # run this step even if the previous one failed - uses: protocol/multiple-go-modules@v1.2 + uses: protocol/multiple-go-modules@v1.4 with: run: go vet ./... From ac4d10faae7a5cdc4be5a5293092b38c2e290f6f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 5 Sep 2023 08:45:59 +0200 Subject: [PATCH 0856/1212] chore(deps): bump actions/setup-go from 2 to 4 (#9976) Bumps [actions/setup-go](https://github.com/actions/setup-go) from 2 to 4. - [Release notes](https://github.com/actions/setup-go/releases) - [Commits](https://github.com/actions/setup-go/compare/v2...v4) --- updated-dependencies: - dependency-name: actions/setup-go dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Piotr Galar --- .github/workflows/build.yml | 4 ++-- .github/workflows/docker-build.yml | 2 +- .github/workflows/gateway-conformance.yml | 2 +- .github/workflows/gobuild.yml | 2 +- .github/workflows/golang-analysis.yml | 2 +- .github/workflows/golint.yml | 2 +- .github/workflows/gotest.yml | 2 +- .github/workflows/sharness.yml | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a51bddcb2..fb8921d94 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -36,7 +36,7 @@ jobs: run: shell: bash steps: - - uses: actions/setup-go@v3 + - uses: actions/setup-go@v4 with: go-version: ${{ env.GO_VERSION }} - uses: actions/checkout@v4 @@ -118,7 +118,7 @@ jobs: run: shell: bash steps: - - uses: actions/setup-go@v3 + - uses: actions/setup-go@v4 with: go-version: ${{ env.GO_VERSION }} - uses: actions/download-artifact@v3 diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml index 3e50cc1f8..b0f607bca 100644 --- a/.github/workflows/docker-build.yml +++ b/.github/workflows/docker-build.yml @@ -26,7 +26,7 @@ jobs: run: shell: bash steps: - - uses: actions/setup-go@v3 + - uses: actions/setup-go@v4 with: go-version: 1.20.x - uses: actions/checkout@v4 diff --git a/.github/workflows/gateway-conformance.yml b/.github/workflows/gateway-conformance.yml index fa422e500..bfb6c3d96 100644 --- a/.github/workflows/gateway-conformance.yml +++ b/.github/workflows/gateway-conformance.yml @@ -30,7 +30,7 @@ jobs: # 2. Build the kubo-gateway - name: Setup Go - uses: actions/setup-go@v3 + uses: actions/setup-go@v4 with: go-version: 1.20.x - name: Checkout kubo-gateway diff --git a/.github/workflows/gobuild.yml b/.github/workflows/gobuild.yml index 2fc457711..ea158c434 100644 --- a/.github/workflows/gobuild.yml +++ b/.github/workflows/gobuild.yml @@ -28,7 +28,7 @@ jobs: run: shell: bash steps: - - uses: actions/setup-go@v3 + - uses: actions/setup-go@v4 with: go-version: 1.20.x - uses: actions/checkout@v4 diff --git a/.github/workflows/golang-analysis.yml b/.github/workflows/golang-analysis.yml index 356c5797a..e87bdfff3 100644 --- a/.github/workflows/golang-analysis.yml +++ b/.github/workflows/golang-analysis.yml @@ -25,7 +25,7 @@ jobs: - uses: actions/checkout@v4 with: submodules: recursive - - uses: actions/setup-go@v2 + - uses: actions/setup-go@v4 with: go-version: "1.20.x" - name: Check that go.mod is tidy diff --git a/.github/workflows/golint.yml b/.github/workflows/golint.yml index 16db613ef..000f61613 100644 --- a/.github/workflows/golint.yml +++ b/.github/workflows/golint.yml @@ -29,7 +29,7 @@ jobs: run: shell: bash steps: - - uses: actions/setup-go@v3 + - uses: actions/setup-go@v4 with: go-version: 1.20.x - uses: actions/checkout@v4 diff --git a/.github/workflows/gotest.yml b/.github/workflows/gotest.yml index 24d46bd49..e033e81f2 100644 --- a/.github/workflows/gotest.yml +++ b/.github/workflows/gotest.yml @@ -30,7 +30,7 @@ jobs: shell: bash steps: - name: Set up Go - uses: actions/setup-go@v3 + uses: actions/setup-go@v4 with: go-version: 1.20.x - name: Check out Kubo diff --git a/.github/workflows/sharness.yml b/.github/workflows/sharness.yml index ab80ba4d7..1d5ab9583 100644 --- a/.github/workflows/sharness.yml +++ b/.github/workflows/sharness.yml @@ -23,7 +23,7 @@ jobs: shell: bash steps: - name: Setup Go - uses: actions/setup-go@v3 + uses: actions/setup-go@v4 with: go-version: 1.20.x - name: Checkout Kubo From 3e5e91dbbe6edf31388d893bb60b838a0d974ca3 Mon Sep 17 00:00:00 2001 From: Piotr Galar Date: Tue, 5 Sep 2023 09:30:09 +0200 Subject: [PATCH 0857/1212] ci: remove obsolete protocol/cache-go-action (#10114) --- .github/workflows/build.yml | 6 ------ .github/workflows/gobuild.yml | 3 --- .github/workflows/golint.yml | 3 --- .github/workflows/gotest.yml | 4 ---- .github/workflows/sharness.yml | 4 ---- 5 files changed, 20 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fb8921d94..7222876d0 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -40,9 +40,6 @@ jobs: with: go-version: ${{ env.GO_VERSION }} - uses: actions/checkout@v4 - - uses: protocol/cache-go-action@v1 - with: - name: ${{ github.job }} - run: make build - uses: actions/upload-artifact@v3 with: @@ -136,9 +133,6 @@ jobs: sleep 1 done timeout-minutes: 5 - - uses: protocol/cache-go-action@v1 - with: - name: ${{ github.job }} - run: go test -count=1 -v ./... working-directory: go-ipfs-api - run: cmd/ipfs/ipfs shutdown diff --git a/.github/workflows/gobuild.yml b/.github/workflows/gobuild.yml index ea158c434..d8854b3b6 100644 --- a/.github/workflows/gobuild.yml +++ b/.github/workflows/gobuild.yml @@ -32,9 +32,6 @@ jobs: with: go-version: 1.20.x - uses: actions/checkout@v4 - - uses: protocol/cache-go-action@v1 - with: - name: ${{ github.job }} - run: make cmd/ipfs-try-build env: TEST_FUSE: 1 diff --git a/.github/workflows/golint.yml b/.github/workflows/golint.yml index 000f61613..602adc8b7 100644 --- a/.github/workflows/golint.yml +++ b/.github/workflows/golint.yml @@ -33,7 +33,4 @@ jobs: with: go-version: 1.20.x - uses: actions/checkout@v4 - - uses: protocol/cache-go-action@v1 - with: - name: ${{ github.job }} - run: make -O test_go_lint diff --git a/.github/workflows/gotest.yml b/.github/workflows/gotest.yml index e033e81f2..cfd3abb01 100644 --- a/.github/workflows/gotest.yml +++ b/.github/workflows/gotest.yml @@ -37,10 +37,6 @@ jobs: uses: actions/checkout@v4 - name: Install missing tools run: sudo apt update && sudo apt install -y zsh - - name: Restore Go cache - uses: protocol/cache-go-action@v1 - with: - name: ${{ github.job }} - name: 👉️ If this step failed, go to «Summary» (top left) → inspect the «Failures/Errors» table env: # increasing parallelism beyond 2 doesn't speed up the tests much diff --git a/.github/workflows/sharness.yml b/.github/workflows/sharness.yml index 1d5ab9583..26b06dece 100644 --- a/.github/workflows/sharness.yml +++ b/.github/workflows/sharness.yml @@ -32,10 +32,6 @@ jobs: path: kubo - name: Install missing tools run: sudo apt update && sudo apt install -y socat net-tools fish libxml2-utils - - name: Restore Go Cache - uses: protocol/cache-go-action@v1 - with: - name: ${{ github.job }} - uses: actions/cache@v3 with: path: test/sharness/lib/dependencies From 2c66ea6995cee698e16c95dc6fb2db6c4b3f8aa8 Mon Sep 17 00:00:00 2001 From: Kay Date: Tue, 5 Sep 2023 17:05:51 +0330 Subject: [PATCH 0858/1212] refactor: if statement (#10105) --- core/commands/dag/dag.go | 4 ++-- core/corehttp/option_test.go | 7 +++---- core/corehttp/routing.go | 5 ++--- core/node/libp2p/smux.go | 19 +++++++++---------- fuse/node/mount_darwin.go | 3 +-- 5 files changed, 17 insertions(+), 21 deletions(-) diff --git a/core/commands/dag/dag.go b/core/commands/dag/dag.go index 649142fd0..07851eb31 100644 --- a/core/commands/dag/dag.go +++ b/core/commands/dag/dag.go @@ -234,10 +234,10 @@ Specification of CAR formats: https://ipld.io/specs/transport/car/ if event.Root.PinErrorMsg != "" { return fmt.Errorf("pinning root %q FAILED: %s", enc.Encode(event.Root.Cid), event.Root.PinErrorMsg) - } else { - event.Root.PinErrorMsg = "success" } + event.Root.PinErrorMsg = "success" + _, err = fmt.Fprintf( w, "Pinned root\t%s\t%s\n", diff --git a/core/corehttp/option_test.go b/core/corehttp/option_test.go index b401be9d5..be4f3afaa 100644 --- a/core/corehttp/option_test.go +++ b/core/corehttp/option_test.go @@ -51,10 +51,9 @@ func TestCheckVersionOption(t *testing.T) { called = true if !tc.shouldHandle { t.Error("handler was called even though version didn't match") - } else { - if _, err := io.WriteString(w, "check!"); err != nil { - t.Error(err) - } + } + if _, err := io.WriteString(w, "check!"); err != nil { + t.Error(err) } }) diff --git a/core/corehttp/routing.go b/core/corehttp/routing.go index 357122a45..e648afb4e 100644 --- a/core/corehttp/routing.go +++ b/core/corehttp/routing.go @@ -100,10 +100,9 @@ func (it *peerChanIter) Next() bool { if ok { it.next = &addr return true - } else { - it.next = nil - return false } + it.next = nil + return false } func (it *peerChanIter) Val() types.Record { diff --git a/core/node/libp2p/smux.go b/core/node/libp2p/smux.go index d96dacf0a..0966dfaf2 100644 --- a/core/node/libp2p/smux.go +++ b/core/node/libp2p/smux.go @@ -38,17 +38,16 @@ func makeSmuxTransportOption(tptConfig config.Transports) (libp2p.Option, error) } } return libp2p.ChainOptions(opts...), nil - } else { - return prioritizeOptions([]priorityOption{{ - priority: tptConfig.Multiplexers.Yamux, - defaultPriority: 100, - opt: libp2p.Muxer(yamux.ID, yamux.DefaultTransport), - }, { - priority: tptConfig.Multiplexers.Mplex, - defaultPriority: config.Disabled, - opt: libp2p.Muxer(mplex.ID, mplex.DefaultTransport), - }}), nil } + return prioritizeOptions([]priorityOption{{ + priority: tptConfig.Multiplexers.Yamux, + defaultPriority: 100, + opt: libp2p.Muxer(yamux.ID, yamux.DefaultTransport), + }, { + priority: tptConfig.Multiplexers.Mplex, + defaultPriority: config.Disabled, + opt: libp2p.Muxer(mplex.ID, mplex.DefaultTransport), + }}), nil } func SmuxTransport(tptConfig config.Transports) func() (opts Libp2pOpts, err error) { diff --git a/fuse/node/mount_darwin.go b/fuse/node/mount_darwin.go index bd0bbb3ae..4d2446ecd 100644 --- a/fuse/node/mount_darwin.go +++ b/fuse/node/mount_darwin.go @@ -141,9 +141,8 @@ func darwinFuseCheckVersion(node *core.IpfsNode) error { return err } else if skip { return nil // user told us not to check version... ok.... - } else { - return errGFV } + return errGFV } log.Debug("mount: osxfuse version:", ov) From 0eeb1f5a2f86b6656170279df53295916b83b039 Mon Sep 17 00:00:00 2001 From: Russell Dempsey <1173416+SgtPooki@users.noreply.github.com> Date: Tue, 5 Sep 2023 09:42:20 -0700 Subject: [PATCH 0859/1212] fix: hamt traversal in ipld-explorer (webui@4.1.0) (#10025) https://github.com/ipfs/ipfs-webui/releases/tag/v4.1.0 --- core/corehttp/webui.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/corehttp/webui.go b/core/corehttp/webui.go index 4030a0053..e54d31afd 100644 --- a/core/corehttp/webui.go +++ b/core/corehttp/webui.go @@ -1,11 +1,12 @@ package corehttp // TODO: move to IPNS -const WebUIPath = "/ipfs/bafybeicyp7ssbnj3hdzehcibmapmpuc3atrsc4ch3q6acldfh4ojjdbcxe" // v4.0.2 +const WebUIPath = "/ipfs/bafybeieqdeoqkf7xf4aozd524qncgiloh33qgr25lyzrkusbcre4c3fxay" // v4.1.0 // WebUIPaths is a list of all past webUI paths. var WebUIPaths = []string{ WebUIPath, + "/ipfs/bafybeicyp7ssbnj3hdzehcibmapmpuc3atrsc4ch3q6acldfh4ojjdbcxe", "/ipfs/bafybeigs6d53gpgu34553mbi5bbkb26e4ikruoaaar75jpfdywpup2r3my", "/ipfs/bafybeic4gops3d3lyrisqku37uio33nvt6fqxvkxihrwlqsuvf76yln4fm", "/ipfs/bafybeifeqt7mvxaniphyu2i3qhovjaf3sayooxbh5enfdqtiehxjv2ldte", From 1efd9d47aa6ff05072bdfc9115a02797a4d50e40 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Wed, 6 Sep 2023 01:33:39 +0200 Subject: [PATCH 0860/1212] refactor(ci): libp2p conformance is separate job this ensures the libp2p experiment runs independently and its failure does not impact the result of job that tests stable features on http port --- .github/workflows/gateway-conformance.yml | 155 ++++++++++++---------- 1 file changed, 83 insertions(+), 72 deletions(-) diff --git a/.github/workflows/gateway-conformance.yml b/.github/workflows/gateway-conformance.yml index d49291a43..06e2701d2 100644 --- a/.github/workflows/gateway-conformance.yml +++ b/.github/workflows/gateway-conformance.yml @@ -17,7 +17,24 @@ defaults: run: shell: bash +env: + # hostnames expected by https://github.com/ipfs/gateway-conformance + GATEWAY_PUBLIC_GATEWAYS: | + { + "example.com": { + "UseSubdomains": true, + "InlineDNSLink": true, + "Paths": ["/ipfs", "/ipns"] + }, + "localhost": { + "UseSubdomains": true, + "InlineDNSLink": true, + "Paths": ["/ipfs", "/ipns"] + } + } + jobs: + # Testing all gateway features via TCP port specified in Addresses.Gateway gateway-conformance: runs-on: ubuntu-latest timeout-minutes: 10 @@ -30,11 +47,14 @@ jobs: # 2. Build the kubo-gateway - name: Setup Go - uses: actions/setup-go@v3 + uses: actions/setup-go@v4 with: go-version: 1.20.x + - uses: protocol/cache-go-action@v1 + with: + name: ${{ github.job }} - name: Checkout kubo-gateway - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: path: kubo-gateway - name: Build kubo-gateway @@ -43,26 +63,9 @@ jobs: # 3. Init the kubo-gateway - name: Init kubo-gateway - env: - GATEWAY_PUBLIC_GATEWAYS: | - { - "example.com": { - "UseSubdomains": true, - "InlineDNSLink": true, - "Paths": ["/ipfs", "/ipns"] - }, - "localhost": { - "UseSubdomains": true, - "InlineDNSLink": true, - "Paths": ["/ipfs", "/ipns"] - } - } run: | - ./ipfs init --profile=test + ./ipfs init -e ./ipfs config --json Gateway.PublicGateways "$GATEWAY_PUBLIC_GATEWAYS" - ./ipfs config --json Experimental.GatewayOverLibp2p true - ./ipfs config Addresses.Gateway "/ip4/127.0.0.1/tcp/8080" - ./ipfs config Addresses.API "/ip4/127.0.0.1/tcp/5001" working-directory: kubo-gateway/cmd/ipfs # 4. Populate the Kubo gateway with the gateway-conformance fixtures @@ -88,28 +91,7 @@ jobs: # 5. Start the kubo-gateway - name: Start kubo-gateway run: | - ./ipfs daemon & - endpoint="http://127.0.0.1:5001/api/v0/version" - max_retries=5 - retry_interval=3 - - check_endpoint() { - curl -X POST --silent --fail "$endpoint" > /dev/null - return $? - } - - retries=0 - while ! check_endpoint; do - retries=$((retries+1)) - - if [ $retries -ge $max_retries ]; then - echo "daemon took too long to start" - exit 1 - fi - - sleep $retry_interval - done - echo "daemon started and ready to receive API calls" + ./ipfs daemon --offline & working-directory: kubo-gateway/cmd/ipfs # 6. Run the gateway-conformance tests @@ -140,48 +122,77 @@ jobs: name: gateway-conformance.json path: output.json - # 8. Setup a kubo http-p2p-proxy to run gateway conformance tests + # Testing trustless gateway feature subset exposed as libp2p protocol + gateway-conformance-libp2p-experiment: + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + # 1. Download the gateway-conformance fixtures + - name: Download gateway-conformance fixtures + uses: ipfs/gateway-conformance/.github/actions/extract-fixtures@v0.3 + with: + output: fixtures + + # 2. Build the kubo-gateway + - name: Setup Go + uses: actions/setup-go@v4 + with: + go-version: 1.20.x + - uses: protocol/cache-go-action@v1 + with: + name: ${{ github.job }} + - name: Checkout kubo-gateway + uses: actions/checkout@v3 + with: + path: kubo-gateway + - name: Build kubo-gateway + run: make build + working-directory: kubo-gateway + + # 3. Init the kubo-gateway + - name: Init kubo-gateway + run: | + ./ipfs init --profile=test + ./ipfs config --json Gateway.PublicGateways "$GATEWAY_PUBLIC_GATEWAYS" + ./ipfs config --json Experimental.GatewayOverLibp2p true + ./ipfs config Addresses.Gateway "/ip4/127.0.0.1/tcp/8080" + ./ipfs config Addresses.API "/ip4/127.0.0.1/tcp/5001" + working-directory: kubo-gateway/cmd/ipfs + + # 4. Populate the Kubo gateway with the gateway-conformance fixtures + - name: Import fixtures + run: | + # Import car files + find ./fixtures -name '*.car' -exec kubo-gateway/cmd/ipfs/ipfs dag import --pin-roots=false {} \; + + # 5. Start the kubo-gateway + - name: Start kubo-gateway + run: | + ( ./ipfs daemon & ) | sed '/Daemon is ready/q' + while [[ "$(./ipfs id | jq '.Addresses | length')" == '0' ]]; do sleep 1; done + working-directory: kubo-gateway/cmd/ipfs + + # 6. Setup a kubo http-p2p-proxy to expose libp2p protocol as a regular HTTP port for gateway conformance tests - name: Init p2p-proxy kubo node env: IPFS_PATH: "~/.kubo-p2p-proxy" run: | - ./ipfs init --profile=test + ./ipfs init --profile=test -e ./ipfs config --json Experimental.Libp2pStreamMounting true ./ipfs config Addresses.Gateway "/ip4/127.0.0.1/tcp/8081" ./ipfs config Addresses.API "/ip4/127.0.0.1/tcp/5002" working-directory: kubo-gateway/cmd/ipfs - # 9. Start the kubo http-p2p-proxy + # 7. Start the kubo http-p2p-proxy - name: Start kubo http-p2p-proxy env: IPFS_PATH: "~/.kubo-p2p-proxy" run: | - ./ipfs daemon & - - endpoint="http://127.0.0.1:5002/api/v0/version" - max_retries=5 - retry_interval=3 - - check_endpoint() { - curl -X POST --silent --fail "$endpoint" > /dev/null - return $? - } - - retries=0 - while ! check_endpoint; do - retries=$((retries+1)) - - if [ $retries -ge $max_retries ]; then - echo "daemon took too long to start" - exit 1 - fi - - sleep $retry_interval - done - echo "daemon started and ready to receive API calls" + ( ./ipfs daemon & ) | sed '/Daemon is ready/q' + while [[ "$(./ipfs id | jq '.Addresses | length')" == '0' ]]; do sleep 1; done working-directory: kubo-gateway/cmd/ipfs - # 10. Start forwarding data from the http-p2p-proxy to the node serving the Gateway API over libp2p + # 8. Start forwarding data from the http-p2p-proxy to the node serving the Gateway API over libp2p - name: Start http-over-libp2p forwarding proxy run: | gatewayNodeId=$(./ipfs --api=/ip4/127.0.0.1/tcp/5001 id -f="") @@ -189,7 +200,7 @@ jobs: ./ipfs --api=/ip4/127.0.0.1/tcp/5002 p2p forward --allow-custom-protocol /http/1.1 /ip4/127.0.0.1/tcp/8082 /p2p/$gatewayNodeId working-directory: kubo-gateway/cmd/ipfs - # 11. Run the gateway-conformance tests over libp2p + # 9. Run the gateway-conformance tests over libp2p - name: Run gateway-conformance tests over libp2p uses: ipfs/gateway-conformance/.github/actions/test@v0.3 with: @@ -200,7 +211,7 @@ jobs: markdown: output.md args: --specs "trustless-gateway,-trustless-ipns-gateway" -skip 'TestGatewayCar/GET_response_for_application/vnd.ipld.car/Header_Content-Length' - # 11. Upload the results + # 10. Upload the results - name: Upload MD summary if: failure() || success() run: cat output.md >> $GITHUB_STEP_SUMMARY @@ -215,4 +226,4 @@ jobs: uses: actions/upload-artifact@v3 with: name: gateway-conformance-libp2p.json - path: output.json \ No newline at end of file + path: output.json From 8d28507814021d9705ea9d2d5480f6e580237cf6 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Wed, 6 Sep 2023 02:57:14 +0200 Subject: [PATCH 0861/1212] docs: gateway-http-over-libp2p --- docs/changelogs/v0.23.md | 23 ++++++++++++----------- docs/experimental-features.md | 33 +++++++++++++++++++++------------ 2 files changed, 33 insertions(+), 23 deletions(-) diff --git a/docs/changelogs/v0.23.md b/docs/changelogs/v0.23.md index 701f05701..6085c21c7 100644 --- a/docs/changelogs/v0.23.md +++ b/docs/changelogs/v0.23.md @@ -10,7 +10,7 @@ - [Gateway: meaningful CAR responses on Not Found errors](#gateway-meaningful-car-responses-on-not-found-errors) - [Binary characters in file names: no longer works with old clients and new Kubo servers](#binary-characters-in-file-names-no-longer-works-with-old-clients-and-new-kubo-servers) - [Self-hosting `/routing/v1` endpoint for delegated routing needs](#self-hosting-routingv1-endpoint-for-delegated-routing-needs) - - [Gateway Over Libp2p Experiment](#gateway-over-libp2p-experiment) + - [Trustless Gateway Over Libp2p Experiment](#trustless-gateway-over-libp2p-experiment) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -68,19 +68,20 @@ HTTP [Routing V1](https://specs.ipfs.tech/routing/http-routing-v1/) API endpoint self-hosting and experimentation with custom delegated routers. This is disabled by default, but can be enabled by setting [`Gateway.ExposeRoutingAPI`](https://github.com/ipfs/kubo/blob/master/docs/config.md#gatewayexposeroutingapi) to `true` . -#### Gateway Over Libp2p Experiment +#### Trustless Gateway Over Libp2p Experiment -It is now possible to serve [Trustless Gateway API](https://specs.ipfs.tech/http-gateways/trustless-gateway/) responses -such as for blocks and CARs over libp2p. This takes advantage of the [specification work](https://github.com/libp2p/specs/pull/508) -in libp2p expanding beyond the basics of performing HTTP requests over libp2p streams that have been available in libp2p -and in kubo experimental features such as [p2p-http-proxy](https://github.com/ipfs/kubo/blob/master/docs/experimental-features.md#p2p-http-proxy). +In this update, we've introduced an experimental opt-in feature allowing users to +serve a subset of [Trustless Gateway](https://specs.ipfs.tech/http-gateways/trustless-gateway/) responses, +such as blocks and CARs, over libp2p. This enhancement leverages the ongoing +[`/http/1.1` specification work in libp2p](https://github.com/libp2p/specs/pull/508) +to make it easier to support HTTP semantics over libp2p streams. -This means that implementations that want to use the Trustless Gateway API as a data transport mechanism can do so even -when standard HTTP transports would fail (e.g. when the endpoint is behind a firewall, or wants to serve data to a browser -but does not have a CA certificate). +This development means that if users wish to utilize the Trustless Gateway API +for data transport, they can now do so even in scenarios where standard HTTP +might be problematic, such as when the endpoint is behind a firewall or when +attempting to serve data to a browser without a CA certificate. -See [HTTP Gateway over Libp2p](https://github.com/ipfs/kubo/blob/master/docs/experimental-features.md#http-gateway-over-libp2p) -for more details. +See [HTTP Gateway over Libp2p](https://github.com/ipfs/kubo/blob/master/docs/experimental-features.md#http-gateway-over-libp2p) for details about this experiment. ### 📝 Changelog diff --git a/docs/experimental-features.md b/docs/experimental-features.md index 52bfe703d..6527f883b 100644 --- a/docs/experimental-features.md +++ b/docs/experimental-features.md @@ -629,19 +629,25 @@ ipfs config --json Experimental.OptimisticProvideJobsPoolSize 120 Experimental, disabled by default. -Enables serving the [IPFS HTTP Gateway](https://specs.ipfs.tech/http-gateways/) protocol over libp2p transports and -as described in the [specification](https://github.com/ipfs/specs/pull/434). +Enables serving a subset of the [IPFS HTTP Gateway](https://specs.ipfs.tech/http-gateways/) semantics over libp2p `/http/1.1` protocol. Notes: -- This feature currently is only about serving the gateway requests over libp2p, not about fetching data this way using -[Trustless Gateway Specification](https://specs.ipfs.tech/http-gateways/trustless-gateway/). -- While kubo currently mounts the gateway API at the root (i.e. `/`) of the libp2p `/http/1.1` protocol that is subject to -change. The way to reliably discover where a given HTTP protocol is mounted on a libp2p endpoint is via the `.well-known/libp2p` -resource specified in the [http+libp2p specification](https://github.com/libp2p/specs/pull/508) -- Kubo currently hard codes the gateway-over-libp2p behavior to: - - Only operate on `/ipfs` resources - - Only satisfy the Trustless Gateway API - - Only serve data that is already local to the node (i.e. similar to a `NoFetch` gateway) +- This feature only about serving verifiable gateway requests over libp2p: + - Deserialized responses are not supported. + - Only operate on `/ipfs` resources (no `/ipns` atm) + - Only support requests for `application/vnd.ipld.raw` and + `application/vnd.ipld.car` (from [Trustless Gateway Specification](https://specs.ipfs.tech/http-gateways/trustless-gateway/), + where data integrity can be verified). + - Only serve data that is already local to the node (i.e. similar to a + [`Gateway.NoFetch`](https://github.com/ipfs/kubo/blob/master/docs/config.md#gatewaynofetch)) +- While Kubo currently mounts the gateway API at the root (i.e. `/`) of the + libp2p `/http/1.1` protocol, that is subject to change. + - The way to reliably discover where a given HTTP protocol is mounted on a + libp2p endpoint is via the `.well-known/libp2p` resource specified in the + [http+libp2p specification](https://github.com/libp2p/specs/pull/508) + - The identifier of the protocol mount point under `/http/1.1` listener is + `/ipfs/gateway`, as noted in + [ipfs/specs#434](https://github.com/ipfs/specs/pull/434). ### How to enable @@ -653,4 +659,7 @@ ipfs config --json Experimental.GatewayOverLibp2p true ### Road to being a real feature -- [ ] Needs more people to use and report on how well it works \ No newline at end of file +- [ ] Needs more people to use and report on how well it works +- [ ] Needs UX work for exposing non-recursive "HTTP transport" (NoFetch) over both libp2p and plain TCP (and sharing the configuration) +- [ ] Needs a mechanism for HTTP handler to signal supported features ([IPIP-425](https://github.com/ipfs/specs/pull/425)) +- [ ] Needs an option for Kubo to detect peers that have it enabled and prefer HTTP transport before falling back to bitswap (and use CAR if peer supports dag-scope=entity from [IPIP-402](https://github.com/ipfs/specs/pull/402)) From 3fa7ef8879a35b3f0474decb5b77d1d90437fcf7 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Wed, 6 Sep 2023 03:20:12 +0200 Subject: [PATCH 0862/1212] fix: run http+libp2p test against correct port seems we were testing regular gateway instead of proxied one --- .github/workflows/gateway-conformance.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/gateway-conformance.yml b/.github/workflows/gateway-conformance.yml index 06e2701d2..d91319585 100644 --- a/.github/workflows/gateway-conformance.yml +++ b/.github/workflows/gateway-conformance.yml @@ -197,14 +197,14 @@ jobs: run: | gatewayNodeId=$(./ipfs --api=/ip4/127.0.0.1/tcp/5001 id -f="") ./ipfs --api=/ip4/127.0.0.1/tcp/5002 swarm connect $(./ipfs --api=/ip4/127.0.0.1/tcp/5001 swarm addrs local --id | head -n 1) - ./ipfs --api=/ip4/127.0.0.1/tcp/5002 p2p forward --allow-custom-protocol /http/1.1 /ip4/127.0.0.1/tcp/8082 /p2p/$gatewayNodeId + ./ipfs --api=/ip4/127.0.0.1/tcp/5002 p2p forward --allow-custom-protocol /http/1.1 /ip4/127.0.0.1/tcp/8092 /p2p/$gatewayNodeId working-directory: kubo-gateway/cmd/ipfs # 9. Run the gateway-conformance tests over libp2p - name: Run gateway-conformance tests over libp2p uses: ipfs/gateway-conformance/.github/actions/test@v0.3 with: - gateway-url: http://127.0.0.1:8081 + gateway-url: http://127.0.0.1:8092 json: output.json xml: output.xml html: output.html From dbf6a05f420f866d7cb331dc449c21476e68cfe3 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Thu, 14 Sep 2023 18:46:21 +0200 Subject: [PATCH 0863/1212] docs(changelog): link to relevant IPIP --- docs/changelogs/v0.22.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/changelogs/v0.22.md b/docs/changelogs/v0.22.md index db51a1b00..3aa55f30e 100644 --- a/docs/changelogs/v0.22.md +++ b/docs/changelogs/v0.22.md @@ -46,7 +46,8 @@ by passing `--v1compat=false`. By default, we still create V1+V2 records, such that there is the highest chance of backwards compatibility. The goal is to move to V2 only in the future. -**TODO**: add links to IPIP https://github.com/ipfs/specs/issues/376 +For more details, see [IPIP-428](https://specs.ipfs.tech/ipips/ipip-0428/) +and the updated [IPNS Record Verification](https://specs.ipfs.tech/ipns/ipns-record/#record-verification) logic. #### IPNS name resolution has been fixed From 1f0f2a72f4f1226c1edf7256479bc1f3b0805385 Mon Sep 17 00:00:00 2001 From: "P. Reis" <76563803+patrickReiis@users.noreply.github.com> Date: Thu, 7 Sep 2023 18:07:28 -0300 Subject: [PATCH 0864/1212] docs(readonly): fix typo --- fuse/readonly/readonly_unix.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fuse/readonly/readonly_unix.go b/fuse/readonly/readonly_unix.go index 3ecda1cf3..e944f1b6e 100644 --- a/fuse/readonly/readonly_unix.go +++ b/fuse/readonly/readonly_unix.go @@ -284,7 +284,7 @@ func (s *Node) Read(ctx context.Context, req *fuse.ReadRequest, resp *fuse.ReadR return nil // may be non-nil / not succeeded } -// to check that out Node implements all the interfaces we want. +// to check that our Node implements all the interfaces we want. type roRoot interface { fs.Node fs.HandleReadDirAller From 9fdb0856052f35c93373822255dee8105f6255e9 Mon Sep 17 00:00:00 2001 From: Icarus9913 Date: Mon, 18 Sep 2023 21:58:15 +0800 Subject: [PATCH 0865/1212] refactor: stop using go-libp2p deprecated peer.ID.Pretty Signed-off-by: Icarus9913 --- client/rpc/dht.go | 2 +- client/rpc/swarm.go | 2 +- config/init.go | 2 +- core/commands/dht_test.go | 4 ++-- core/commands/name/ipns.go | 2 +- core/commands/ping.go | 4 ++-- core/commands/pubsub.go | 4 ++-- core/commands/routing.go | 4 ++-- core/commands/swarm.go | 10 +++++----- core/coreapi/test/api_test.go | 2 +- core/node/builder.go | 2 +- core/node/libp2p/hostopt.go | 2 +- core/node/libp2p/rcmgr.go | 2 +- fuse/ipns/ipns_test.go | 4 ++-- fuse/ipns/ipns_unix.go | 2 +- p2p/local.go | 4 ++-- p2p/remote.go | 6 +++--- plugin/plugins/peerlog/peerlog.go | 2 +- 18 files changed, 30 insertions(+), 30 deletions(-) diff --git a/client/rpc/dht.go b/client/rpc/dht.go index 1d3b24643..ffdf39681 100644 --- a/client/rpc/dht.go +++ b/client/rpc/dht.go @@ -17,7 +17,7 @@ func (api *DhtAPI) FindPeer(ctx context.Context, p peer.ID) (peer.AddrInfo, erro Type routing.QueryEventType Responses []peer.AddrInfo } - resp, err := api.core().Request("dht/findpeer", p.Pretty()).Send(ctx) + resp, err := api.core().Request("dht/findpeer", p.String()).Send(ctx) if err != nil { return peer.AddrInfo{}, err } diff --git a/client/rpc/swarm.go b/client/rpc/swarm.go index 49ece0d07..7d257a2d1 100644 --- a/client/rpc/swarm.go +++ b/client/rpc/swarm.go @@ -14,7 +14,7 @@ import ( type SwarmAPI HttpApi func (api *SwarmAPI) Connect(ctx context.Context, pi peer.AddrInfo) error { - pidma, err := multiaddr.NewComponent("p2p", pi.ID.Pretty()) + pidma, err := multiaddr.NewComponent("p2p", pi.ID.String()) if err != nil { return err } diff --git a/config/init.go b/config/init.go index 1ccfc7251..f40d373bb 100644 --- a/config/init.go +++ b/config/init.go @@ -237,7 +237,7 @@ func CreateIdentity(out io.Writer, opts []options.KeyGenerateOption) (Identity, if err != nil { return ident, err } - ident.PeerID = id.Pretty() + ident.PeerID = id.String() fmt.Fprintf(out, "peer identity: %s\n", ident.PeerID) return ident, nil } diff --git a/core/commands/dht_test.go b/core/commands/dht_test.go index d6a87c954..b0e03f5cd 100644 --- a/core/commands/dht_test.go +++ b/core/commands/dht_test.go @@ -14,12 +14,12 @@ func TestKeyTranslation(t *testing.T) { pkname := namesys.PkKeyForID(pid) ipnsname := ipns.NameFromPeer(pid).RoutingKey() - pkk, err := escapeDhtKey("/pk/" + pid.Pretty()) + pkk, err := escapeDhtKey("/pk/" + pid.String()) if err != nil { t.Fatal(err) } - ipnsk, err := escapeDhtKey("/ipns/" + pid.Pretty()) + ipnsk, err := escapeDhtKey("/ipns/" + pid.String()) if err != nil { t.Fatal(err) } diff --git a/core/commands/name/ipns.go b/core/commands/name/ipns.go index 8c2b755d5..b5c7fd7e3 100644 --- a/core/commands/name/ipns.go +++ b/core/commands/name/ipns.go @@ -93,7 +93,7 @@ Resolve the value of a dnslink: if err != nil { return err } - name = self.ID().Pretty() + name = self.ID().String() } else { name = req.Arguments[0] } diff --git a/core/commands/ping.go b/core/commands/ping.go index 26e2e3d12..dabc1a248 100644 --- a/core/commands/ping.go +++ b/core/commands/ping.go @@ -79,7 +79,7 @@ trip latency information. if len(n.Peerstore.Addrs(pid)) == 0 { // Make sure we can find the node in question if err := res.Emit(&PingResult{ - Text: fmt.Sprintf("Looking up peer %s", pid.Pretty()), + Text: fmt.Sprintf("Looking up peer %s", pid), Success: true, }); err != nil { return err @@ -95,7 +95,7 @@ trip latency information. } if err := res.Emit(&PingResult{ - Text: fmt.Sprintf("PING %s.", pid.Pretty()), + Text: fmt.Sprintf("PING %s.", pid), Success: true, }); err != nil { return err diff --git a/core/commands/pubsub.go b/core/commands/pubsub.go index aadc681d9..1c2e82799 100644 --- a/core/commands/pubsub.go +++ b/core/commands/pubsub.go @@ -110,7 +110,7 @@ TOPIC AND DATA ENCODING encoder, _ := mbase.EncoderByName("base64url") psm := pubsubMessage{ Data: encoder.Encode(msg.Data()), - From: msg.From().Pretty(), + From: msg.From().String(), Seqno: encoder.Encode(msg.Seq()), } for _, topic := range msg.Topics() { @@ -323,7 +323,7 @@ TOPIC AND DATA ENCODING list := &stringList{make([]string, 0, len(peers))} for _, peer := range peers { - list.Strings = append(list.Strings, peer.Pretty()) + list.Strings = append(list.Strings, peer.String()) } sort.Strings(list.Strings) return cmds.EmitOnce(res, list) diff --git a/core/commands/routing.go b/core/commands/routing.go index e2071fd40..c0955456a 100644 --- a/core/commands/routing.go +++ b/core/commands/routing.go @@ -114,7 +114,7 @@ var findProvidersRoutingCmd = &cmds.Command{ if verbose { fmt.Fprintf(out, "provider: ") } - fmt.Fprintf(out, "%s\n", prov.ID.Pretty()) + fmt.Fprintf(out, "%s\n", prov.ID) if verbose { for _, a := range prov.Addrs { fmt.Fprintf(out, "\t%s\n", a) @@ -479,7 +479,7 @@ identified by QmFoo. return nil }, routing.Value: func(obj *routing.QueryEvent, out io.Writer, verbose bool) error { - fmt.Fprintf(out, "%s\n", obj.ID.Pretty()) + fmt.Fprintf(out, "%s\n", obj.ID) return nil }, } diff --git a/core/commands/swarm.go b/core/commands/swarm.go index fc4d8f7d2..4fe535ffc 100644 --- a/core/commands/swarm.go +++ b/core/commands/swarm.go @@ -262,7 +262,7 @@ var swarmPeersCmd = &cmds.Command{ for _, c := range conns { ci := connInfo{ Addr: c.Address().String(), - Peer: c.ID().Pretty(), + Peer: c.ID().String(), } if verbose || direction { @@ -536,7 +536,7 @@ var swarmAddrsCmd = &cmds.Command{ out := make(map[string][]string) for p, paddrs := range addrs { - s := p.Pretty() + s := p.String() for _, a := range paddrs { out[s] = append(out[s], a.String()) } @@ -599,7 +599,7 @@ var swarmAddrsLocalCmd = &cmds.Command{ for _, addr := range maddrs { saddr := addr.String() if showid { - saddr = path.Join(saddr, p2pProtocolName, self.ID().Pretty()) + saddr = path.Join(saddr, p2pProtocolName, self.ID().String()) } addrs = append(addrs, saddr) } @@ -680,7 +680,7 @@ ipfs swarm connect /ip4/104.131.131.82/tcp/4001/p2p/QmaCpDMGvV2BGHeYERUEnRQAwe3N output := make([]string, len(pis)) for i, pi := range pis { - output[i] = "connect " + pi.ID.Pretty() + output[i] = "connect " + pi.ID.String() err := api.Swarm().Connect(req.Context, pi) if err != nil { @@ -745,7 +745,7 @@ it will reconnect. // a good backwards compat solution. Right now, I'm just // preserving the current behavior. for _, addr := range maddrs { - msg := "disconnect " + ainfo.ID.Pretty() + msg := "disconnect " + ainfo.ID.String() if err := api.Swarm().Disconnect(req.Context, addr); err != nil { msg += " failure: " + err.Error() } else { diff --git a/core/coreapi/test/api_test.go b/core/coreapi/test/api_test.go index fa09a96d8..3ae74b97e 100644 --- a/core/coreapi/test/api_test.go +++ b/core/coreapi/test/api_test.go @@ -56,7 +56,7 @@ func (NodeProvider) MakeAPISwarm(t *testing.T, ctx context.Context, fullIdentity } ident = config.Identity{ - PeerID: id.Pretty(), + PeerID: id.String(), PrivKey: base64.StdEncoding.EncodeToString(kbytes), } } else { diff --git a/core/node/builder.go b/core/node/builder.go index 9c4951801..57fa20945 100644 --- a/core/node/builder.go +++ b/core/node/builder.go @@ -141,7 +141,7 @@ func defaultRepo(dstore repo.Datastore) (repo.Repo, error) { c.Bootstrap = cfg.DefaultBootstrapAddresses c.Addresses.Swarm = []string{"/ip4/0.0.0.0/tcp/4001", "/ip4/0.0.0.0/udp/4001/quic-v1"} - c.Identity.PeerID = pid.Pretty() + c.Identity.PeerID = pid.String() c.Identity.PrivKey = base64.StdEncoding.EncodeToString(privkeyb) return &repo.Mock{ diff --git a/core/node/libp2p/hostopt.go b/core/node/libp2p/hostopt.go index 74d6e5723..1dc671487 100644 --- a/core/node/libp2p/hostopt.go +++ b/core/node/libp2p/hostopt.go @@ -17,7 +17,7 @@ var DefaultHostOption HostOption = constructPeerHost func constructPeerHost(id peer.ID, ps peerstore.Peerstore, options ...libp2p.Option) (host.Host, error) { pkey := ps.PrivKey(id) if pkey == nil { - return nil, fmt.Errorf("missing private key for node ID: %s", id.Pretty()) + return nil, fmt.Errorf("missing private key for node ID: %s", id) } options = append([]libp2p.Option{libp2p.Identity(pkey), libp2p.Peerstore(ps)}, options...) return libp2p.New(options...) diff --git a/core/node/libp2p/rcmgr.go b/core/node/libp2p/rcmgr.go index 47a823d5d..f545126c4 100644 --- a/core/node/libp2p/rcmgr.go +++ b/core/node/libp2p/rcmgr.go @@ -360,7 +360,7 @@ func LimitConfigsToInfo(stats LimitsConfigAndUsage) ResourceInfos { for i, p := range stats.Peers { result = append(result, resourceLimitsAndUsageToResourceInfo( - config.ResourceMgrPeerScopePrefix+i.Pretty(), + config.ResourceMgrPeerScopePrefix+i.String(), p, )...) } diff --git a/fuse/ipns/ipns_test.go b/fuse/ipns/ipns_test.go index ca2ec4c1a..d26e78c4d 100644 --- a/fuse/ipns/ipns_test.go +++ b/fuse/ipns/ipns_test.go @@ -151,7 +151,7 @@ func TestIpnsLocalLink(t *testing.T) { t.Fatal(err) } - if linksto != nd.Identity.Pretty() { + if linksto != nd.Identity.String() { t.Fatal("Link invalid") } } @@ -176,7 +176,7 @@ func TestIpnsBasicIO(t *testing.T) { t.Fatal("Incorrect Read!") } - fname2 := mnt.Dir + "/" + nd.Identity.Pretty() + "/testfile" + fname2 := mnt.Dir + "/" + nd.Identity.String() + "/testfile" rbuf, err = os.ReadFile(fname2) if err != nil { t.Fatal(err) diff --git a/fuse/ipns/ipns_unix.go b/fuse/ipns/ipns_unix.go index b66634015..2cb25d332 100644 --- a/fuse/ipns/ipns_unix.go +++ b/fuse/ipns/ipns_unix.go @@ -220,7 +220,7 @@ func (r *Root) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) { listing := make([]fuse.Dirent, 0, len(r.Keys)*2) for alias, k := range r.Keys { ent := fuse.Dirent{ - Name: k.ID().Pretty(), + Name: k.ID().String(), Type: fuse.DT_Dir, } link := fuse.Dirent{ diff --git a/p2p/local.go b/p2p/local.go index 6ef110c39..98028c5d4 100644 --- a/p2p/local.go +++ b/p2p/local.go @@ -76,7 +76,7 @@ func (l *localListener) setupStream(local manet.Conn) { remote, err := l.dial(l.ctx) if err != nil { local.Close() - log.Warnf("failed to dial to remote %s/%s", l.peer.Pretty(), l.proto) + log.Warnf("failed to dial to remote %s/%s", l.peer, l.proto) return } @@ -109,7 +109,7 @@ func (l *localListener) ListenAddress() ma.Multiaddr { } func (l *localListener) TargetAddress() ma.Multiaddr { - addr, err := ma.NewMultiaddr(maPrefix + l.peer.Pretty()) + addr, err := ma.NewMultiaddr(maPrefix + l.peer.String()) if err != nil { panic(err) } diff --git a/p2p/remote.go b/p2p/remote.go index a90155a21..b867cb313 100644 --- a/p2p/remote.go +++ b/p2p/remote.go @@ -55,13 +55,13 @@ func (l *remoteListener) handleStream(remote net.Stream) { peer := remote.Conn().RemotePeer() if l.reportRemote { - if _, err := fmt.Fprintf(local, "%s\n", peer.Pretty()); err != nil { + if _, err := fmt.Fprintf(local, "%s\n", peer); err != nil { _ = remote.Reset() return } } - peerMa, err := ma.NewMultiaddr(maPrefix + peer.Pretty()) + peerMa, err := ma.NewMultiaddr(maPrefix + peer.String()) if err != nil { _ = remote.Reset() return @@ -88,7 +88,7 @@ func (l *remoteListener) Protocol() protocol.ID { } func (l *remoteListener) ListenAddress() ma.Multiaddr { - addr, err := ma.NewMultiaddr(maPrefix + l.p2p.identity.Pretty()) + addr, err := ma.NewMultiaddr(maPrefix + l.p2p.identity.String()) if err != nil { panic(err) } diff --git a/plugin/plugins/peerlog/peerlog.go b/plugin/plugins/peerlog/peerlog.go index f41a8b654..d55a7f0b9 100644 --- a/plugin/plugins/peerlog/peerlog.go +++ b/plugin/plugins/peerlog/peerlog.go @@ -148,7 +148,7 @@ func (pl *peerLogPlugin) collectEvents(node *core.IpfsNode) { case e = <-pl.events: } - peerID := zap.String("peer", e.peer.Pretty()) + peerID := zap.String("peer", e.peer.String()) switch e.kind { case eventConnect: From a9737e4d6a9d97ebb8c58ba66f4b06b8b4cfcc4d Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Mon, 18 Sep 2023 09:40:43 -0400 Subject: [PATCH 0866/1212] chore: update to build with Go 1.21 --- .github/workflows/build.yml | 2 +- .github/workflows/docker-build.yml | 2 +- .github/workflows/gateway-conformance.yml | 2 +- .github/workflows/gobuild.yml | 2 +- .github/workflows/golang-analysis.yml | 2 +- .github/workflows/golint.yml | 2 +- .github/workflows/gotest.yml | 2 +- .github/workflows/sharness.yml | 2 +- Dockerfile | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7222876d0..49ac96690 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -10,7 +10,7 @@ on: - 'master' env: - GO_VERSION: 1.20.x + GO_VERSION: 1.21.x concurrency: group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.event_name == 'push' && github.sha || github.ref }} diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml index b0f607bca..d05429a6c 100644 --- a/.github/workflows/docker-build.yml +++ b/.github/workflows/docker-build.yml @@ -28,7 +28,7 @@ jobs: steps: - uses: actions/setup-go@v4 with: - go-version: 1.20.x + go-version: 1.21.x - uses: actions/checkout@v4 - run: docker build -t $IMAGE_NAME:$WIP_IMAGE_TAG . - run: docker run --rm $IMAGE_NAME:$WIP_IMAGE_TAG --version diff --git a/.github/workflows/gateway-conformance.yml b/.github/workflows/gateway-conformance.yml index bfb6c3d96..33727bd34 100644 --- a/.github/workflows/gateway-conformance.yml +++ b/.github/workflows/gateway-conformance.yml @@ -32,7 +32,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v4 with: - go-version: 1.20.x + go-version: 1.21.x - name: Checkout kubo-gateway uses: actions/checkout@v4 with: diff --git a/.github/workflows/gobuild.yml b/.github/workflows/gobuild.yml index d8854b3b6..13eabc0fc 100644 --- a/.github/workflows/gobuild.yml +++ b/.github/workflows/gobuild.yml @@ -30,7 +30,7 @@ jobs: steps: - uses: actions/setup-go@v4 with: - go-version: 1.20.x + go-version: 1.21.x - uses: actions/checkout@v4 - run: make cmd/ipfs-try-build env: diff --git a/.github/workflows/golang-analysis.yml b/.github/workflows/golang-analysis.yml index e87bdfff3..eddaba988 100644 --- a/.github/workflows/golang-analysis.yml +++ b/.github/workflows/golang-analysis.yml @@ -27,7 +27,7 @@ jobs: submodules: recursive - uses: actions/setup-go@v4 with: - go-version: "1.20.x" + go-version: "1.21.x" - name: Check that go.mod is tidy uses: protocol/multiple-go-modules@v1.4 with: diff --git a/.github/workflows/golint.yml b/.github/workflows/golint.yml index 602adc8b7..d6191e6f3 100644 --- a/.github/workflows/golint.yml +++ b/.github/workflows/golint.yml @@ -31,6 +31,6 @@ jobs: steps: - uses: actions/setup-go@v4 with: - go-version: 1.20.x + go-version: 1.21.x - uses: actions/checkout@v4 - run: make -O test_go_lint diff --git a/.github/workflows/gotest.yml b/.github/workflows/gotest.yml index cfd3abb01..a1042cf7a 100644 --- a/.github/workflows/gotest.yml +++ b/.github/workflows/gotest.yml @@ -32,7 +32,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v4 with: - go-version: 1.20.x + go-version: 1.21.x - name: Check out Kubo uses: actions/checkout@v4 - name: Install missing tools diff --git a/.github/workflows/sharness.yml b/.github/workflows/sharness.yml index 26b06dece..448e112de 100644 --- a/.github/workflows/sharness.yml +++ b/.github/workflows/sharness.yml @@ -25,7 +25,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v4 with: - go-version: 1.20.x + go-version: 1.21.x - name: Checkout Kubo uses: actions/checkout@v4 with: diff --git a/Dockerfile b/Dockerfile index 348fbc440..15dff4aea 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM --platform=${BUILDPLATFORM:-linux/amd64} golang:1.20 AS builder +FROM --platform=${BUILDPLATFORM:-linux/amd64} golang:1.21 AS builder ARG TARGETOS TARGETARCH From d4c4f6c39c8354e2b54513d0dbe4c92868340a4b Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Wed, 20 Sep 2023 08:38:39 +0200 Subject: [PATCH 0867/1212] chore: bump boxo to 0.13.0 --- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- test/dependencies/go.mod | 2 +- test/dependencies/go.sum | 4 ++-- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index bb88ad996..9d6e97782 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.20 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.12.1-0.20230825151903-13569468babd + github.com/ipfs/boxo v0.13.0 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.30.0 github.com/multiformats/go-multiaddr v0.11.0 diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 0ab47be1a..0dc8d6414 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -300,8 +300,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.12.1-0.20230825151903-13569468babd h1:uAp9W7FRQ7W16FENlURZqBh7/3PnakG0DjHpKPirKVY= -github.com/ipfs/boxo v0.12.1-0.20230825151903-13569468babd/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk= +github.com/ipfs/boxo v0.13.0 h1:uzCQekieYS4PysbYYdodNmKLuqOdLjlUziXVZ19oDeQ= +github.com/ipfs/boxo v0.13.0/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= diff --git a/go.mod b/go.mod index d3ff353c6..3deaf1cf7 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( github.com/fsnotify/fsnotify v1.6.0 github.com/google/uuid v1.3.0 github.com/hashicorp/go-multierror v1.1.1 - github.com/ipfs/boxo v0.12.1-0.20230825151903-13569468babd + github.com/ipfs/boxo v0.13.0 github.com/ipfs/go-block-format v0.1.2 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 diff --git a/go.sum b/go.sum index e478ea733..7f32f7277 100644 --- a/go.sum +++ b/go.sum @@ -335,8 +335,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.12.1-0.20230825151903-13569468babd h1:uAp9W7FRQ7W16FENlURZqBh7/3PnakG0DjHpKPirKVY= -github.com/ipfs/boxo v0.12.1-0.20230825151903-13569468babd/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk= +github.com/ipfs/boxo v0.13.0 h1:uzCQekieYS4PysbYYdodNmKLuqOdLjlUziXVZ19oDeQ= +github.com/ipfs/boxo v0.13.0/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 094cd9797..286b6303d 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -7,7 +7,7 @@ replace github.com/ipfs/kubo => ../../ require ( github.com/Kubuxu/gocovmerge v0.0.0-20161216165753-7ecaa51963cd github.com/golangci/golangci-lint v1.54.1 - github.com/ipfs/boxo v0.12.1-0.20230825151903-13569468babd + github.com/ipfs/boxo v0.13.0 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 github.com/ipfs/go-datastore v0.6.0 diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 3c8cb6f87..cbc14e5d0 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -396,8 +396,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.12.1-0.20230825151903-13569468babd h1:uAp9W7FRQ7W16FENlURZqBh7/3PnakG0DjHpKPirKVY= -github.com/ipfs/boxo v0.12.1-0.20230825151903-13569468babd/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk= +github.com/ipfs/boxo v0.13.0 h1:uzCQekieYS4PysbYYdodNmKLuqOdLjlUziXVZ19oDeQ= +github.com/ipfs/boxo v0.13.0/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.1.2 h1:GAjkfhVx1f4YTODS6Esrj1wt2HhrtwTnhEr+DyPUaJo= From 2acb6c6cbb719b9a5ad62ea5919ec5f0b0ba7656 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Wed, 20 Sep 2023 07:38:48 +0200 Subject: [PATCH 0868/1212] migration: update 14-to-15 to v1.0.1 --- repo/fsrepo/migrations/fetcher.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/repo/fsrepo/migrations/fetcher.go b/repo/fsrepo/migrations/fetcher.go index 8e18c1b10..880492b92 100644 --- a/repo/fsrepo/migrations/fetcher.go +++ b/repo/fsrepo/migrations/fetcher.go @@ -11,7 +11,7 @@ import ( const ( // Current distribution to fetch migrations from. - CurrentIpfsDist = "/ipfs/QmVYvjxCiUxqGjDeREFDy8SbX3zj7vhgeuprk28hgvKEq5" // fs-repo-14-to-15 v1.0.0 + CurrentIpfsDist = "/ipfs/QmZPedUiZNe6Gq9oDvoizuuCMVoeb7shwq9xKhysq7exMo" // fs-repo-14-to-15 v1.0.1 // Latest distribution path. Default for fetchers. LatestIpfsDist = "/ipns/dist.ipfs.tech" From 4e3008fdf349e9506c95e36839b8bc832c3aab54 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Wed, 20 Sep 2023 13:27:52 +0200 Subject: [PATCH 0869/1212] docs: add changelog info for QUIC Draft 29 (#10132) Co-authored-by: Adin Schmahmann --- docs/changelogs/v0.23.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/docs/changelogs/v0.23.md b/docs/changelogs/v0.23.md index 6085c21c7..d374f0173 100644 --- a/docs/changelogs/v0.23.md +++ b/docs/changelogs/v0.23.md @@ -11,6 +11,7 @@ - [Binary characters in file names: no longer works with old clients and new Kubo servers](#binary-characters-in-file-names-no-longer-works-with-old-clients-and-new-kubo-servers) - [Self-hosting `/routing/v1` endpoint for delegated routing needs](#self-hosting-routingv1-endpoint-for-delegated-routing-needs) - [Trustless Gateway Over Libp2p Experiment](#trustless-gateway-over-libp2p-experiment) + - [Removal of `/quic` (Draft 29) support](#removal-of-quic-draft-29-support) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -83,6 +84,19 @@ attempting to serve data to a browser without a CA certificate. See [HTTP Gateway over Libp2p](https://github.com/ipfs/kubo/blob/master/docs/experimental-features.md#http-gateway-over-libp2p) for details about this experiment. +#### Removal of `/quic` (Draft 29) support + +Kubo no longer supports QUIC Draft 29. This means that older nodes aren't able to connect +to newer nodes using QUIC Draft 29. However, they are still able to connect through any other +transport that both nodes talk (such as QUIC RFC 9000, or TCP). QUIC Draft 29 was a preliminary implementation of QUIC before +the official RFC 9000 was published, and it has now been dropped by [`go-libp2p`](https://github.com/libp2p/go-libp2p/releases/tag/v0.30.0) +and therefore Kubo. + +In [Kubo 0.18](https://github.com/ipfs/kubo/releases/tag/v0.18.0), we shipped a migration +to have listeners for both `/quic` (Draft 29) and `/quic-v1` (RFC 9000). Similarly, in this +version we are shipping a migration to remove the current `/quic` addresses, maintaining +the `/quic-v1` addresses only. For more background information, check [issue #9496](https://github.com/ipfs/kubo/issues/9496). + ### 📝 Changelog ### 👨‍👩‍👧‍👦 Contributors From f46bf77c801028152aef3636c88d9dbe72b0276d Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Thu, 21 Sep 2023 16:37:26 +0200 Subject: [PATCH 0870/1212] fix(migrations): use dweb.link (#10133) this is a quick fix to allow users who's ISP is blocking ipfs.io to benefit from HTTPS mirror --- repo/fsrepo/migrations/httpfetcher.go | 3 ++- repo/fsrepo/migrations/migrations.go | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/repo/fsrepo/migrations/httpfetcher.go b/repo/fsrepo/migrations/httpfetcher.go index 1f3d575a9..9665a1e98 100644 --- a/repo/fsrepo/migrations/httpfetcher.go +++ b/repo/fsrepo/migrations/httpfetcher.go @@ -10,7 +10,8 @@ import ( ) const ( - defaultGatewayURL = "https://ipfs.io" + // default is different name than ipfs.io which is being blocked by some ISPs + defaultGatewayURL = "https://dweb.link" // Default maximum download size. defaultFetchLimit = 1024 * 1024 * 512 ) diff --git a/repo/fsrepo/migrations/migrations.go b/repo/fsrepo/migrations/migrations.go index 6894d73a7..e612b8abb 100644 --- a/repo/fsrepo/migrations/migrations.go +++ b/repo/fsrepo/migrations/migrations.go @@ -153,7 +153,7 @@ func ReadMigrationConfig(repoRoot string, userConfigFile string) (*config.Migrat // GetMigrationFetcher creates one or more fetchers according to // downloadSources,. func GetMigrationFetcher(downloadSources []string, distPath string, newIpfsFetcher func(string) Fetcher) (Fetcher, error) { - const httpUserAgent = "go-ipfs" + const httpUserAgent = "kubo/migration" const numTriesPerHTTP = 3 var fetchers []Fetcher From 0bac56c3aa85292b1a74dd6a35800b5c8fb5c52c Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Thu, 21 Sep 2023 17:03:17 +0200 Subject: [PATCH 0871/1212] feat: add Gateway.DisableHTMLErrors option (#10137) --- config/gateway.go | 5 ++++ core/corehttp/gateway.go | 1 + docs/changelogs/v0.23.md | 8 ++++++ docs/config.md | 20 +++++++++++++-- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 +-- go.mod | 2 +- go.sum | 4 +-- test/cli/gateway_test.go | 35 ++++++++++++++++++++++++++ test/dependencies/go.mod | 2 +- test/dependencies/go.sum | 4 +-- 11 files changed, 76 insertions(+), 11 deletions(-) diff --git a/config/gateway.go b/config/gateway.go index dee0a93e2..9c0830c50 100644 --- a/config/gateway.go +++ b/config/gateway.go @@ -3,6 +3,7 @@ package config const ( DefaultInlineDNSLink = false DefaultDeserializedResponses = true + DefaultDisableHTMLErrors = false DefaultExposeRoutingAPI = false ) @@ -70,6 +71,10 @@ type Gateway struct { // be overridden per FQDN in PublicGateways. DeserializedResponses Flag + // DisableHTMLErrors disables pretty HTML pages when an error occurs. Instead, a `text/plain` + // page will be sent with the raw error message. + DisableHTMLErrors Flag + // PublicGateways configures behavior of known public gateways. // Each key is a fully qualified domain name (FQDN). PublicGateways map[string]*GatewaySpec diff --git a/core/corehttp/gateway.go b/core/corehttp/gateway.go index 4a4f08780..67da588ca 100644 --- a/core/corehttp/gateway.go +++ b/core/corehttp/gateway.go @@ -237,6 +237,7 @@ func getGatewayConfig(n *core.IpfsNode) (gateway.Config, error) { gwCfg := gateway.Config{ Headers: headers, DeserializedResponses: cfg.Gateway.DeserializedResponses.WithDefault(config.DefaultDeserializedResponses), + DisableHTMLErrors: cfg.Gateway.DisableHTMLErrors.WithDefault(config.DefaultDisableHTMLErrors), NoDNSLink: cfg.Gateway.NoDNSLink, PublicGateways: map[string]*gateway.PublicGateway{}, } diff --git a/docs/changelogs/v0.23.md b/docs/changelogs/v0.23.md index d374f0173..62cbac220 100644 --- a/docs/changelogs/v0.23.md +++ b/docs/changelogs/v0.23.md @@ -8,6 +8,7 @@ - [🔦 Highlights](#-highlights) - [Mplex deprecation](#mplex-deprecation) - [Gateway: meaningful CAR responses on Not Found errors](#gateway-meaningful-car-responses-on-not-found-errors) + - [Gateway: added `Gateway.DisableHTMLErrors` configuration option](#gateway-added-gatewaydisablehtmlerrors-configuration-option) - [Binary characters in file names: no longer works with old clients and new Kubo servers](#binary-characters-in-file-names-no-longer-works-with-old-clients-and-new-kubo-servers) - [Self-hosting `/routing/v1` endpoint for delegated routing needs](#self-hosting-routingv1-endpoint-for-delegated-routing-needs) - [Trustless Gateway Over Libp2p Experiment](#trustless-gateway-over-libp2p-experiment) @@ -47,6 +48,13 @@ the path does not exist, a CAR will be sent with a root of `bafkqaaa` (empty CID This CAR will contain all blocks necessary to validate that the path does not exist without having to trust the gateway. +#### Gateway: added `Gateway.DisableHTMLErrors` configuration option + +The `Gateway.DisableHTMLErrors` configuration option forces errors to be +displayed in browsers as plain text (`text/plain`) rather than HTML error +pages. It's especially beneficial for whitelabel or middleware deployments that +wish to avoid IPFS branding and links on error pages in browsers. + #### Binary characters in file names: no longer works with old clients and new Kubo servers In this version, we updated Kubo to support Go 1.20+. In Go 1.20, a regression diff --git a/docs/config.md b/docs/config.md index dd3eed390..176b69e09 100644 --- a/docs/config.md +++ b/docs/config.md @@ -51,6 +51,8 @@ config file at runtime. - [`Gateway.NoFetch`](#gatewaynofetch) - [`Gateway.NoDNSLink`](#gatewaynodnslink) - [`Gateway.DeserializedResponses`](#gatewaydeserializedresponses) + - [`Gateway.DisableHTMLErrors`](#gatewaydisablehtmlerrors) + - [`Gateway.ExposeRoutingAPI`](#gatewayexposeroutingapi) - [`Gateway.HTTPHeaders`](#gatewayhttpheaders) - [`Gateway.RootRedirect`](#gatewayrootredirect) - [`Gateway.FastDirIndexThreshold`](#gatewayfastdirindexthreshold) @@ -648,7 +650,7 @@ Default: `false` Type: `bool` -#### `Gateway.DeserializedResponses` +### `Gateway.DeserializedResponses` An optional flag to explicitly configure whether this gateway responds to deserialized requests, or not. By default, it is enabled. When disabling this option, the gateway @@ -658,12 +660,26 @@ Default: `true` Type: `flag` -#### `Gateway.ExposeRoutingAPI` +### `Gateway.DisableHTMLErrors` + +An optional flag to disable the pretty HTML error pages of the gateway. Instead, +a `text/plain` page will be returned with the raw error message from Kubo. + +It is useful for whitelabel or middleware deployments that wish to avoid +`text/html` responses with IPFS branding and links on error pages in browsers. + +Default: `false` + +Type: `flag` + +### `Gateway.ExposeRoutingAPI` An optional flag to expose Kubo `Routing` system on the gateway port as a [Routing V1](https://specs.ipfs.tech/routing/routing-v1/) endpoint. This only affects your local gateway, at `127.0.0.1`. +This endpoint can be used by other Kubo instance, as illustrated in [`delegated_routing_v1_http_proxy_test.go`](https://github.com/ipfs/kubo/blob/master/test/cli/delegated_routing_v1_http_proxy_test.go). + Default: `false` Type: `flag` diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index e6c84006e..154550ff7 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.20 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.13.0 + github.com/ipfs/boxo v0.13.1 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.31.0 github.com/multiformats/go-multiaddr v0.11.0 diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index cf646229e..711c9b581 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -300,8 +300,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.13.0 h1:uzCQekieYS4PysbYYdodNmKLuqOdLjlUziXVZ19oDeQ= -github.com/ipfs/boxo v0.13.0/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk= +github.com/ipfs/boxo v0.13.1 h1:nQ5oQzcMZR3oL41REJDcTbrvDvuZh3J9ckc9+ILeRQI= +github.com/ipfs/boxo v0.13.1/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= diff --git a/go.mod b/go.mod index ff7cbba6d..c298dc99c 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( github.com/fsnotify/fsnotify v1.6.0 github.com/google/uuid v1.3.0 github.com/hashicorp/go-multierror v1.1.1 - github.com/ipfs/boxo v0.13.0 + github.com/ipfs/boxo v0.13.1 github.com/ipfs/go-block-format v0.1.2 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 diff --git a/go.sum b/go.sum index 5193ebfe9..7e703072d 100644 --- a/go.sum +++ b/go.sum @@ -335,8 +335,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.13.0 h1:uzCQekieYS4PysbYYdodNmKLuqOdLjlUziXVZ19oDeQ= -github.com/ipfs/boxo v0.13.0/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk= +github.com/ipfs/boxo v0.13.1 h1:nQ5oQzcMZR3oL41REJDcTbrvDvuZh3J9ckc9+ILeRQI= +github.com/ipfs/boxo v0.13.1/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= diff --git a/test/cli/gateway_test.go b/test/cli/gateway_test.go index 168acfdb9..a1c2fa8c9 100644 --- a/test/cli/gateway_test.go +++ b/test/cli/gateway_test.go @@ -593,4 +593,39 @@ func TestGateway(t *testing.T) { t.Run(test.message, makeTest(test)) } }) + + t.Run("DisableHTMLErrors", func(t *testing.T) { + t.Parallel() + + t.Run("Returns HTML error without DisableHTMLErrors, Accept contains text/html", func(t *testing.T) { + t.Parallel() + + node := harness.NewT(t).NewNode().Init() + node.StartDaemon() + client := node.GatewayClient() + + res := client.Get("/ipfs/invalid-thing", func(r *http.Request) { + r.Header.Set("Accept", "text/html") + }) + assert.NotEqual(t, http.StatusOK, res.StatusCode) + assert.Contains(t, res.Resp.Header.Get("Content-Type"), "text/html") + }) + + t.Run("Does not return HTML error with DisableHTMLErrors enabled, and Accept contains text/html", func(t *testing.T) { + t.Parallel() + + node := harness.NewT(t).NewNode().Init() + node.UpdateConfig(func(cfg *config.Config) { + cfg.Gateway.DisableHTMLErrors = config.True + }) + node.StartDaemon() + client := node.GatewayClient() + + res := client.Get("/ipfs/invalid-thing", func(r *http.Request) { + r.Header.Set("Accept", "text/html") + }) + assert.NotEqual(t, http.StatusOK, res.StatusCode) + assert.NotContains(t, res.Resp.Header.Get("Content-Type"), "text/html") + }) + }) } diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 064cdbfb9..9f5122156 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -7,7 +7,7 @@ replace github.com/ipfs/kubo => ../../ require ( github.com/Kubuxu/gocovmerge v0.0.0-20161216165753-7ecaa51963cd github.com/golangci/golangci-lint v1.54.1 - github.com/ipfs/boxo v0.13.0 + github.com/ipfs/boxo v0.13.1 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 github.com/ipfs/go-datastore v0.6.0 diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index fb6929682..b3af2abeb 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -396,8 +396,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.13.0 h1:uzCQekieYS4PysbYYdodNmKLuqOdLjlUziXVZ19oDeQ= -github.com/ipfs/boxo v0.13.0/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk= +github.com/ipfs/boxo v0.13.1 h1:nQ5oQzcMZR3oL41REJDcTbrvDvuZh3J9ckc9+ILeRQI= +github.com/ipfs/boxo v0.13.1/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.1.2 h1:GAjkfhVx1f4YTODS6Esrj1wt2HhrtwTnhEr+DyPUaJo= From c46cbecb832b9a25f74a275b946b3a0ff3aefaba Mon Sep 17 00:00:00 2001 From: Andrew Gillis Date: Thu, 21 Sep 2023 09:29:38 -0700 Subject: [PATCH 0872/1212] core/bootstrap: fix panic without backup bootstrap peer functions (#10029) Fix panic when backup bootstrap peer load and save funcs are nil A panic occurs when the first bootstrap round runs is these functions are not assigned in the configuration: - `LoadBackupBootstrapPeers` - `SaveBackupBootstrapPeers` This fix assumes that it is acceptable for these functions to be nil, as it may be desirable to disable the backup peer load and save functionality. --- core/bootstrap/bootstrap.go | 50 ++++++++++++-- core/bootstrap/bootstrap_test.go | 114 +++++++++++++++++++++++++++++++ core/core.go | 9 ++- 3 files changed, 161 insertions(+), 12 deletions(-) diff --git a/core/bootstrap/bootstrap.go b/core/bootstrap/bootstrap.go index ed95d74e1..acd7ef672 100644 --- a/core/bootstrap/bootstrap.go +++ b/core/bootstrap/bootstrap.go @@ -59,8 +59,8 @@ type BootstrapConfig struct { // as backup bootstrap peers. MaxBackupBootstrapSize int - SaveBackupBootstrapPeers func(context.Context, []peer.AddrInfo) - LoadBackupBootstrapPeers func(context.Context) []peer.AddrInfo + saveBackupBootstrapPeers func(context.Context, []peer.AddrInfo) + loadBackupBootstrapPeers func(context.Context) []peer.AddrInfo } // DefaultBootstrapConfig specifies default sane parameters for bootstrapping. @@ -72,14 +72,41 @@ var DefaultBootstrapConfig = BootstrapConfig{ MaxBackupBootstrapSize: 20, } -func BootstrapConfigWithPeers(pis []peer.AddrInfo) BootstrapConfig { +// BootstrapConfigWithPeers creates a default BootstrapConfig configured with +// the specified peers, and optional functions to load and save backup peers. +func BootstrapConfigWithPeers(pis []peer.AddrInfo, options ...func(*BootstrapConfig)) BootstrapConfig { cfg := DefaultBootstrapConfig cfg.BootstrapPeers = func() []peer.AddrInfo { return pis } + for _, opt := range options { + opt(&cfg) + } return cfg } +// WithBackupPeers configures functions to load and save backup bootstrap peers. +func WithBackupPeers(load func(context.Context) []peer.AddrInfo, save func(context.Context, []peer.AddrInfo)) func(*BootstrapConfig) { + if save == nil && load != nil || save != nil && load == nil { + panic("both load and save backup bootstrap peers functions must be defined") + } + return func(cfg *BootstrapConfig) { + cfg.loadBackupBootstrapPeers = load + cfg.saveBackupBootstrapPeers = save + } +} + +// BackupPeers returns the load and save backup peers functions. +func (cfg *BootstrapConfig) BackupPeers() (func(context.Context) []peer.AddrInfo, func(context.Context, []peer.AddrInfo)) { + return cfg.loadBackupBootstrapPeers, cfg.saveBackupBootstrapPeers +} + +// SetBackupPeers sets the load and save backup peers functions. +func (cfg *BootstrapConfig) SetBackupPeers(load func(context.Context) []peer.AddrInfo, save func(context.Context, []peer.AddrInfo)) { + opt := WithBackupPeers(load, save) + opt(cfg) +} + // Bootstrap kicks off IpfsNode bootstrapping. This function will periodically // check the number of open connections and -- if there are too few -- initiate // connections to well-known bootstrap peers. It also kicks off subsystem @@ -124,7 +151,11 @@ func Bootstrap(id peer.ID, host host.Host, rt routing.Routing, cfg BootstrapConf doneWithRound <- struct{}{} close(doneWithRound) // it no longer blocks periodic - startSavePeersAsTemporaryBootstrapProc(cfg, host, proc) + // If loadBackupBootstrapPeers is not nil then saveBackupBootstrapPeers + // must also not be nil. + if cfg.loadBackupBootstrapPeers != nil { + startSavePeersAsTemporaryBootstrapProc(cfg, host, proc) + } return proc, nil } @@ -185,7 +216,7 @@ func saveConnectedPeersAsTemporaryBootstrap(ctx context.Context, host host.Host, // If we didn't reach the target number use previously stored connected peers. if len(backupPeers) < cfg.MaxBackupBootstrapSize { - oldSavedPeers := cfg.LoadBackupBootstrapPeers(ctx) + oldSavedPeers := cfg.loadBackupBootstrapPeers(ctx) log.Debugf("missing %d peers to reach backup bootstrap target of %d, trying from previous list of %d saved peers", cfg.MaxBackupBootstrapSize-len(backupPeers), cfg.MaxBackupBootstrapSize, len(oldSavedPeers)) @@ -209,7 +240,7 @@ func saveConnectedPeersAsTemporaryBootstrap(ctx context.Context, host host.Host, } } - cfg.SaveBackupBootstrapPeers(ctx, backupPeers) + cfg.saveBackupBootstrapPeers(ctx, backupPeers) log.Debugf("saved %d peers (of %d target) as bootstrap backup in the config", len(backupPeers), cfg.MaxBackupBootstrapSize) return nil } @@ -241,9 +272,14 @@ func bootstrapRound(ctx context.Context, host host.Host, cfg BootstrapConfig) er } } + if cfg.loadBackupBootstrapPeers == nil { + log.Debugf("not enough bootstrap peers to fill the remaining target of %d connections", numToDial) + return ErrNotEnoughBootstrapPeers + } + log.Debugf("not enough bootstrap peers to fill the remaining target of %d connections, trying backup list", numToDial) - tempBootstrapPeers := cfg.LoadBackupBootstrapPeers(ctx) + tempBootstrapPeers := cfg.loadBackupBootstrapPeers(ctx) if len(tempBootstrapPeers) > 0 { numToDial -= int(peersConnect(ctx, host, tempBootstrapPeers, numToDial, false)) if numToDial <= 0 { diff --git a/core/bootstrap/bootstrap_test.go b/core/bootstrap/bootstrap_test.go index 39490a474..d933379d4 100644 --- a/core/bootstrap/bootstrap_test.go +++ b/core/bootstrap/bootstrap_test.go @@ -1,8 +1,14 @@ package bootstrap import ( + "context" + "crypto/rand" + "reflect" "testing" + "time" + "github.com/libp2p/go-libp2p" + "github.com/libp2p/go-libp2p/core/crypto" "github.com/libp2p/go-libp2p/core/peer" "github.com/libp2p/go-libp2p/core/test" ) @@ -23,3 +29,111 @@ func TestRandomizeAddressList(t *testing.T) { t.Fail() } } + +func TestLoadAndSaveOptions(t *testing.T) { + loadFunc := func(_ context.Context) []peer.AddrInfo { return nil } + saveFunc := func(_ context.Context, _ []peer.AddrInfo) {} + + bootCfg := BootstrapConfigWithPeers(nil, WithBackupPeers(loadFunc, saveFunc)) + load, save := bootCfg.BackupPeers() + if load == nil { + t.Fatal("load function not assigned") + } + if reflect.ValueOf(load).Pointer() != reflect.ValueOf(loadFunc).Pointer() { + t.Fatal("load not assigned correct function") + } + if save == nil { + t.Fatal("save function not assigned") + } + if reflect.ValueOf(save).Pointer() != reflect.ValueOf(saveFunc).Pointer() { + t.Fatal("save not assigned correct function") + } + + assertPanics(t, "with only load func", func() { + BootstrapConfigWithPeers(nil, WithBackupPeers(loadFunc, nil)) + }) + + assertPanics(t, "with only save func", func() { + BootstrapConfigWithPeers(nil, WithBackupPeers(nil, saveFunc)) + }) + + bootCfg = BootstrapConfigWithPeers(nil, WithBackupPeers(nil, nil)) + load, save = bootCfg.BackupPeers() + if load != nil || save != nil { + t.Fatal("load and save functions should both be nil") + } +} + +func TestSetBackupPeers(t *testing.T) { + loadFunc := func(_ context.Context) []peer.AddrInfo { return nil } + saveFunc := func(_ context.Context, _ []peer.AddrInfo) {} + + bootCfg := DefaultBootstrapConfig + bootCfg.SetBackupPeers(loadFunc, saveFunc) + load, save := bootCfg.BackupPeers() + if load == nil { + t.Fatal("load function not assigned") + } + if reflect.ValueOf(load).Pointer() != reflect.ValueOf(loadFunc).Pointer() { + t.Fatal("load not assigned correct function") + } + if save == nil { + t.Fatal("save function not assigned") + } + if reflect.ValueOf(save).Pointer() != reflect.ValueOf(saveFunc).Pointer() { + t.Fatal("save not assigned correct function") + } + + assertPanics(t, "with only load func", func() { + bootCfg.SetBackupPeers(loadFunc, nil) + }) + + assertPanics(t, "with only save func", func() { + bootCfg.SetBackupPeers(nil, saveFunc) + }) + + bootCfg.SetBackupPeers(nil, nil) + load, save = bootCfg.BackupPeers() + if load != nil || save != nil { + t.Fatal("load and save functions should both be nil") + } +} + +func TestNoTempPeersLoadAndSave(t *testing.T) { + period := 500 * time.Millisecond + bootCfg := BootstrapConfigWithPeers(nil) + bootCfg.MinPeerThreshold = 2 + bootCfg.Period = period + + priv, pub, err := crypto.GenerateEd25519Key(rand.Reader) + if err != nil { + t.Fatal(err) + } + peerID, err := peer.IDFromPublicKey(pub) + if err != nil { + t.Fatal(err) + } + p2pHost, err := libp2p.New(libp2p.Identity(priv)) + if err != nil { + t.Fatal(err) + } + + bootstrapper, err := Bootstrap(peerID, p2pHost, nil, bootCfg) + if err != nil { + t.Fatal(err) + } + + time.Sleep(4 * period) + bootstrapper.Close() + +} + +func assertPanics(t *testing.T, name string, f func()) { + defer func() { + if r := recover(); r == nil { + t.Errorf("%s: did not panic as expected", name) + } + }() + + f() +} diff --git a/core/core.go b/core/core.go index a0e06324f..c35d3e445 100644 --- a/core/core.go +++ b/core/core.go @@ -168,17 +168,15 @@ func (n *IpfsNode) Bootstrap(cfg bootstrap.BootstrapConfig) error { return ps } } - if cfg.SaveBackupBootstrapPeers == nil { - cfg.SaveBackupBootstrapPeers = func(ctx context.Context, peerList []peer.AddrInfo) { + if load, _ := cfg.BackupPeers(); load == nil { + save := func(ctx context.Context, peerList []peer.AddrInfo) { err := n.saveTempBootstrapPeers(ctx, peerList) if err != nil { log.Warnf("saveTempBootstrapPeers failed: %s", err) return } } - } - if cfg.LoadBackupBootstrapPeers == nil { - cfg.LoadBackupBootstrapPeers = func(ctx context.Context) []peer.AddrInfo { + load = func(ctx context.Context) []peer.AddrInfo { peerList, err := n.loadTempBootstrapPeers(ctx) if err != nil { log.Warnf("loadTempBootstrapPeers failed: %s", err) @@ -186,6 +184,7 @@ func (n *IpfsNode) Bootstrap(cfg bootstrap.BootstrapConfig) error { } return peerList } + cfg.SetBackupPeers(load, save) } repoConf, err := n.Repo.Config() From 73860d6ee77dd3990e7d3575f6ae85d7beb1ebad Mon Sep 17 00:00:00 2001 From: Russell Dempsey <1173416+SgtPooki@users.noreply.github.com> Date: Thu, 21 Sep 2023 10:35:16 -0700 Subject: [PATCH 0873/1212] chore: webui v4.1.1 (#10120) https://github.com/ipfs/ipfs-webui/releases/tag/v4.1.1 (translation updates) --- core/corehttp/webui.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/corehttp/webui.go b/core/corehttp/webui.go index e54d31afd..4c8e04723 100644 --- a/core/corehttp/webui.go +++ b/core/corehttp/webui.go @@ -1,11 +1,12 @@ package corehttp // TODO: move to IPNS -const WebUIPath = "/ipfs/bafybeieqdeoqkf7xf4aozd524qncgiloh33qgr25lyzrkusbcre4c3fxay" // v4.1.0 +const WebUIPath = "/ipfs/bafybeiamycmd52xvg6k3nzr6z3n33de6a2teyhquhj4kspdtnvetnkrfim" // v4.1.1 // WebUIPaths is a list of all past webUI paths. var WebUIPaths = []string{ WebUIPath, + "/ipfs/bafybeieqdeoqkf7xf4aozd524qncgiloh33qgr25lyzrkusbcre4c3fxay", "/ipfs/bafybeicyp7ssbnj3hdzehcibmapmpuc3atrsc4ch3q6acldfh4ojjdbcxe", "/ipfs/bafybeigs6d53gpgu34553mbi5bbkb26e4ikruoaaar75jpfdywpup2r3my", "/ipfs/bafybeic4gops3d3lyrisqku37uio33nvt6fqxvkxihrwlqsuvf76yln4fm", From 551b36b83f663ee2afc757b6a7a720b26bfe1b88 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Tue, 5 Sep 2023 17:49:16 +0200 Subject: [PATCH 0874/1212] chore: update go-libp2p-kad-dht --- docs/examples/kubo-as-a-library/go.mod | 4 ++-- docs/examples/kubo-as-a-library/go.sum | 8 ++++---- go.mod | 4 ++-- go.sum | 8 ++++---- test/cli/ping_test.go | 4 +++- 5 files changed, 15 insertions(+), 13 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 154550ff7..0699d4119 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -102,12 +102,12 @@ require ( github.com/libp2p/go-doh-resolver v0.4.0 // indirect github.com/libp2p/go-flow-metrics v0.1.0 // indirect github.com/libp2p/go-libp2p-asn-util v0.3.0 // indirect - github.com/libp2p/go-libp2p-kad-dht v0.24.2 // indirect + github.com/libp2p/go-libp2p-kad-dht v0.24.4 // indirect github.com/libp2p/go-libp2p-kbucket v0.6.3 // indirect github.com/libp2p/go-libp2p-pubsub v0.9.3 // indirect github.com/libp2p/go-libp2p-pubsub-router v0.6.0 // indirect github.com/libp2p/go-libp2p-record v0.2.0 // indirect - github.com/libp2p/go-libp2p-routing-helpers v0.7.1 // indirect + github.com/libp2p/go-libp2p-routing-helpers v0.7.2 // indirect github.com/libp2p/go-libp2p-xor v0.1.0 // indirect github.com/libp2p/go-mplex v0.7.0 // indirect github.com/libp2p/go-msgio v0.3.0 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 711c9b581..a6079b5eb 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -464,8 +464,8 @@ github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLE github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= github.com/libp2p/go-libp2p-core v0.3.0/go.mod h1:ACp3DmS3/N64c2jDzcV429ukDpicbL6+TrrxANBjPGw= -github.com/libp2p/go-libp2p-kad-dht v0.24.2 h1:zd7myKBKCmtZBhI3I0zm8xBkb28v3gmSEtQfBdAdFwc= -github.com/libp2p/go-libp2p-kad-dht v0.24.2/go.mod h1:BShPzRbK6+fN3hk8a0WGAYKpb8m4k+DtchkqouGTrSg= +github.com/libp2p/go-libp2p-kad-dht v0.24.4 h1:ktNiJe7ffsJ1wX3ULpMCwXts99mPqGFSE/Qn1i8pErQ= +github.com/libp2p/go-libp2p-kad-dht v0.24.4/go.mod h1:ybWBJ5Fbvz9sSLkNtXt+2+bK0JB8+tRPvhBbRGHegRU= github.com/libp2p/go-libp2p-kbucket v0.3.1/go.mod h1:oyjT5O7tS9CQurok++ERgc46YLwEpuGoFq9ubvoUOio= github.com/libp2p/go-libp2p-kbucket v0.6.3 h1:p507271wWzpy2f1XxPzCQG9NiN6R6lHL9GiSErbQQo0= github.com/libp2p/go-libp2p-kbucket v0.6.3/go.mod h1:RCseT7AH6eJWxxk2ol03xtP9pEHetYSPXOaJnOiD8i0= @@ -476,8 +476,8 @@ github.com/libp2p/go-libp2p-pubsub-router v0.6.0 h1:D30iKdlqDt5ZmLEYhHELCMRj8b4s github.com/libp2p/go-libp2p-pubsub-router v0.6.0/go.mod h1:FY/q0/RBTKsLA7l4vqC2cbRbOvyDotg8PJQ7j8FDudE= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= github.com/libp2p/go-libp2p-record v0.2.0/go.mod h1:I+3zMkvvg5m2OcSdoL0KPljyJyvNDFGKX7QdlpYUcwk= -github.com/libp2p/go-libp2p-routing-helpers v0.7.1 h1:kc0kWCZecbBPAiFEHhxfGJZPqjg1g9zV+X+ovR4Tmnc= -github.com/libp2p/go-libp2p-routing-helpers v0.7.1/go.mod h1:cHStPSRC/wgbfpb5jYdMP7zaSmc2wWcb1mkzNr6AR8o= +github.com/libp2p/go-libp2p-routing-helpers v0.7.2 h1:xJMFyhQ3Iuqnk9Q2dYE1eUTzsah7NLw3Qs2zjUV78T0= +github.com/libp2p/go-libp2p-routing-helpers v0.7.2/go.mod h1:cN4mJAD/7zfPKXBcs9ze31JGYAZgzdABEm+q/hkswb8= github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA= github.com/libp2p/go-libp2p-xor v0.1.0 h1:hhQwT4uGrBcuAkUGXADuPltalOdpf9aag9kaYNT2tLA= github.com/libp2p/go-libp2p-xor v0.1.0/go.mod h1:LSTM5yRnjGZbWNTA/hRwq2gGFrvRIbQJscoIL/u6InY= diff --git a/go.mod b/go.mod index c298dc99c..a341b465f 100644 --- a/go.mod +++ b/go.mod @@ -47,12 +47,12 @@ require ( github.com/libp2p/go-doh-resolver v0.4.0 github.com/libp2p/go-libp2p v0.31.0 github.com/libp2p/go-libp2p-http v0.5.0 - github.com/libp2p/go-libp2p-kad-dht v0.24.2 + github.com/libp2p/go-libp2p-kad-dht v0.24.4 github.com/libp2p/go-libp2p-kbucket v0.6.3 github.com/libp2p/go-libp2p-pubsub v0.9.3 github.com/libp2p/go-libp2p-pubsub-router v0.6.0 github.com/libp2p/go-libp2p-record v0.2.0 - github.com/libp2p/go-libp2p-routing-helpers v0.7.1 + github.com/libp2p/go-libp2p-routing-helpers v0.7.2 github.com/libp2p/go-libp2p-testing v0.12.0 github.com/libp2p/go-mplex v0.7.0 github.com/libp2p/go-socket-activation v0.1.0 diff --git a/go.sum b/go.sum index 7e703072d..742557ba7 100644 --- a/go.sum +++ b/go.sum @@ -525,8 +525,8 @@ github.com/libp2p/go-libp2p-gostream v0.6.0 h1:QfAiWeQRce6pqnYfmIVWJFXNdDyfiR/qk github.com/libp2p/go-libp2p-gostream v0.6.0/go.mod h1:Nywu0gYZwfj7Jc91PQvbGU8dIpqbQQkjWgDuOrFaRdA= github.com/libp2p/go-libp2p-http v0.5.0 h1:+x0AbLaUuLBArHubbbNRTsgWz0RjNTy6DJLOxQ3/QBc= github.com/libp2p/go-libp2p-http v0.5.0/go.mod h1:glh87nZ35XCQyFsdzZps6+F4HYI6DctVFY5u1fehwSg= -github.com/libp2p/go-libp2p-kad-dht v0.24.2 h1:zd7myKBKCmtZBhI3I0zm8xBkb28v3gmSEtQfBdAdFwc= -github.com/libp2p/go-libp2p-kad-dht v0.24.2/go.mod h1:BShPzRbK6+fN3hk8a0WGAYKpb8m4k+DtchkqouGTrSg= +github.com/libp2p/go-libp2p-kad-dht v0.24.4 h1:ktNiJe7ffsJ1wX3ULpMCwXts99mPqGFSE/Qn1i8pErQ= +github.com/libp2p/go-libp2p-kad-dht v0.24.4/go.mod h1:ybWBJ5Fbvz9sSLkNtXt+2+bK0JB8+tRPvhBbRGHegRU= github.com/libp2p/go-libp2p-kbucket v0.3.1/go.mod h1:oyjT5O7tS9CQurok++ERgc46YLwEpuGoFq9ubvoUOio= github.com/libp2p/go-libp2p-kbucket v0.6.3 h1:p507271wWzpy2f1XxPzCQG9NiN6R6lHL9GiSErbQQo0= github.com/libp2p/go-libp2p-kbucket v0.6.3/go.mod h1:RCseT7AH6eJWxxk2ol03xtP9pEHetYSPXOaJnOiD8i0= @@ -537,8 +537,8 @@ github.com/libp2p/go-libp2p-pubsub-router v0.6.0 h1:D30iKdlqDt5ZmLEYhHELCMRj8b4s github.com/libp2p/go-libp2p-pubsub-router v0.6.0/go.mod h1:FY/q0/RBTKsLA7l4vqC2cbRbOvyDotg8PJQ7j8FDudE= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= github.com/libp2p/go-libp2p-record v0.2.0/go.mod h1:I+3zMkvvg5m2OcSdoL0KPljyJyvNDFGKX7QdlpYUcwk= -github.com/libp2p/go-libp2p-routing-helpers v0.7.1 h1:kc0kWCZecbBPAiFEHhxfGJZPqjg1g9zV+X+ovR4Tmnc= -github.com/libp2p/go-libp2p-routing-helpers v0.7.1/go.mod h1:cHStPSRC/wgbfpb5jYdMP7zaSmc2wWcb1mkzNr6AR8o= +github.com/libp2p/go-libp2p-routing-helpers v0.7.2 h1:xJMFyhQ3Iuqnk9Q2dYE1eUTzsah7NLw3Qs2zjUV78T0= +github.com/libp2p/go-libp2p-routing-helpers v0.7.2/go.mod h1:cN4mJAD/7zfPKXBcs9ze31JGYAZgzdABEm+q/hkswb8= github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA= github.com/libp2p/go-libp2p-testing v0.12.0/go.mod h1:KcGDRXyN7sQCllucn1cOOS+Dmm7ujhfEyXQL5lvkcPg= github.com/libp2p/go-libp2p-xor v0.1.0 h1:hhQwT4uGrBcuAkUGXADuPltalOdpf9aag9kaYNT2tLA= diff --git a/test/cli/ping_test.go b/test/cli/ping_test.go index c4195024a..9470e67d8 100644 --- a/test/cli/ping_test.go +++ b/test/cli/ping_test.go @@ -2,6 +2,7 @@ package cli import ( "fmt" + "strings" "testing" "github.com/ipfs/kubo/test/cli/harness" @@ -29,7 +30,8 @@ func TestPing(t *testing.T) { badPeer := "QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJx" res := node1.RunIPFS("ping", "-n", "2", "--", badPeer) assert.Contains(t, res.Stdout.String(), fmt.Sprintf("Looking up peer %s", badPeer)) - assert.Contains(t, res.Stderr.String(), "Error: ping failed") + msg := res.Stderr.String() + assert.Truef(t, strings.HasPrefix(msg, "Error:"), "should fail got this instead: %q", msg) }) t.Run("self", func(t *testing.T) { From 66590e350f6dbdf9da77e9548a91f9ce96d803dd Mon Sep 17 00:00:00 2001 From: Jorropo Date: Wed, 6 Sep 2023 00:32:10 +0200 Subject: [PATCH 0875/1212] perf: make bootstrap saves O(N) --- core/bootstrap/bootstrap.go | 39 +++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/core/bootstrap/bootstrap.go b/core/bootstrap/bootstrap.go index acd7ef672..5cde50371 100644 --- a/core/bootstrap/bootstrap.go +++ b/core/bootstrap/bootstrap.go @@ -192,22 +192,24 @@ func saveConnectedPeersAsTemporaryBootstrap(ctx context.Context, host host.Host, bootstrapPeers := cfg.BootstrapPeers() backupPeers := make([]peer.AddrInfo, 0, cfg.MaxBackupBootstrapSize) + foundPeers := make(map[peer.ID]struct{}, cfg.MaxBackupBootstrapSize+len(bootstrapPeers)) + + // Don't record bootstrap peers + for _, b := range bootstrapPeers { + foundPeers[b.ID] = struct{}{} + } // Choose peers to save and filter out the ones that are already bootstrap nodes. for _, p := range connectedPeers { - found := false - for _, bootstrapPeer := range bootstrapPeers { - if p == bootstrapPeer.ID { - found = true - break - } - } - if !found { - backupPeers = append(backupPeers, peer.AddrInfo{ - ID: p, - Addrs: host.Network().Peerstore().Addrs(p), - }) + if _, found := foundPeers[p]; found { + continue } + foundPeers[p] = struct{}{} + + backupPeers = append(backupPeers, peer.AddrInfo{ + ID: p, + Addrs: host.Network().Peerstore().Addrs(p), + }) if len(backupPeers) >= cfg.MaxBackupBootstrapSize { break @@ -222,17 +224,12 @@ func saveConnectedPeersAsTemporaryBootstrap(ctx context.Context, host host.Host, // Add some of the old saved peers. Ensure we don't duplicate them. for _, p := range oldSavedPeers { - found := false - for _, sp := range backupPeers { - if p.ID == sp.ID { - found = true - break - } + if _, found := foundPeers[p.ID]; found { + continue } + foundPeers[p.ID] = struct{}{} - if !found { - backupPeers = append(backupPeers, p) - } + backupPeers = append(backupPeers, p) if len(backupPeers) >= cfg.MaxBackupBootstrapSize { break From 93b36793d6121b454391f7c4fbaafbd3957250a3 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Wed, 6 Sep 2023 00:32:35 +0200 Subject: [PATCH 0876/1212] chore: update go-libp2p-routing-helpers --- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 0699d4119..0eae30fda 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -107,7 +107,7 @@ require ( github.com/libp2p/go-libp2p-pubsub v0.9.3 // indirect github.com/libp2p/go-libp2p-pubsub-router v0.6.0 // indirect github.com/libp2p/go-libp2p-record v0.2.0 // indirect - github.com/libp2p/go-libp2p-routing-helpers v0.7.2 // indirect + github.com/libp2p/go-libp2p-routing-helpers v0.7.3 // indirect github.com/libp2p/go-libp2p-xor v0.1.0 // indirect github.com/libp2p/go-mplex v0.7.0 // indirect github.com/libp2p/go-msgio v0.3.0 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index a6079b5eb..71e949367 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -476,8 +476,8 @@ github.com/libp2p/go-libp2p-pubsub-router v0.6.0 h1:D30iKdlqDt5ZmLEYhHELCMRj8b4s github.com/libp2p/go-libp2p-pubsub-router v0.6.0/go.mod h1:FY/q0/RBTKsLA7l4vqC2cbRbOvyDotg8PJQ7j8FDudE= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= github.com/libp2p/go-libp2p-record v0.2.0/go.mod h1:I+3zMkvvg5m2OcSdoL0KPljyJyvNDFGKX7QdlpYUcwk= -github.com/libp2p/go-libp2p-routing-helpers v0.7.2 h1:xJMFyhQ3Iuqnk9Q2dYE1eUTzsah7NLw3Qs2zjUV78T0= -github.com/libp2p/go-libp2p-routing-helpers v0.7.2/go.mod h1:cN4mJAD/7zfPKXBcs9ze31JGYAZgzdABEm+q/hkswb8= +github.com/libp2p/go-libp2p-routing-helpers v0.7.3 h1:u1LGzAMVRK9Nqq5aYDVOiq/HaB93U9WWczBzGyAC5ZY= +github.com/libp2p/go-libp2p-routing-helpers v0.7.3/go.mod h1:cN4mJAD/7zfPKXBcs9ze31JGYAZgzdABEm+q/hkswb8= github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA= github.com/libp2p/go-libp2p-xor v0.1.0 h1:hhQwT4uGrBcuAkUGXADuPltalOdpf9aag9kaYNT2tLA= github.com/libp2p/go-libp2p-xor v0.1.0/go.mod h1:LSTM5yRnjGZbWNTA/hRwq2gGFrvRIbQJscoIL/u6InY= diff --git a/go.mod b/go.mod index a341b465f..a72131737 100644 --- a/go.mod +++ b/go.mod @@ -52,7 +52,7 @@ require ( github.com/libp2p/go-libp2p-pubsub v0.9.3 github.com/libp2p/go-libp2p-pubsub-router v0.6.0 github.com/libp2p/go-libp2p-record v0.2.0 - github.com/libp2p/go-libp2p-routing-helpers v0.7.2 + github.com/libp2p/go-libp2p-routing-helpers v0.7.3 github.com/libp2p/go-libp2p-testing v0.12.0 github.com/libp2p/go-mplex v0.7.0 github.com/libp2p/go-socket-activation v0.1.0 diff --git a/go.sum b/go.sum index 742557ba7..bd444c738 100644 --- a/go.sum +++ b/go.sum @@ -537,8 +537,8 @@ github.com/libp2p/go-libp2p-pubsub-router v0.6.0 h1:D30iKdlqDt5ZmLEYhHELCMRj8b4s github.com/libp2p/go-libp2p-pubsub-router v0.6.0/go.mod h1:FY/q0/RBTKsLA7l4vqC2cbRbOvyDotg8PJQ7j8FDudE= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= github.com/libp2p/go-libp2p-record v0.2.0/go.mod h1:I+3zMkvvg5m2OcSdoL0KPljyJyvNDFGKX7QdlpYUcwk= -github.com/libp2p/go-libp2p-routing-helpers v0.7.2 h1:xJMFyhQ3Iuqnk9Q2dYE1eUTzsah7NLw3Qs2zjUV78T0= -github.com/libp2p/go-libp2p-routing-helpers v0.7.2/go.mod h1:cN4mJAD/7zfPKXBcs9ze31JGYAZgzdABEm+q/hkswb8= +github.com/libp2p/go-libp2p-routing-helpers v0.7.3 h1:u1LGzAMVRK9Nqq5aYDVOiq/HaB93U9WWczBzGyAC5ZY= +github.com/libp2p/go-libp2p-routing-helpers v0.7.3/go.mod h1:cN4mJAD/7zfPKXBcs9ze31JGYAZgzdABEm+q/hkswb8= github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA= github.com/libp2p/go-libp2p-testing v0.12.0/go.mod h1:KcGDRXyN7sQCllucn1cOOS+Dmm7ujhfEyXQL5lvkcPg= github.com/libp2p/go-libp2p-xor v0.1.0 h1:hhQwT4uGrBcuAkUGXADuPltalOdpf9aag9kaYNT2tLA= From 593614a08f8ce3784be562ffe9c615663cff6409 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Thu, 21 Sep 2023 18:42:40 +0200 Subject: [PATCH 0877/1212] tests: remove sharness ping tests This was ported in 579175f81d400000881af5701c06351373df3fb8 but we forgot to remove it. --- test/sharness/t0041-ping.sh | 54 ------------------------------------- 1 file changed, 54 deletions(-) delete mode 100755 test/sharness/t0041-ping.sh diff --git a/test/sharness/t0041-ping.sh b/test/sharness/t0041-ping.sh deleted file mode 100755 index 6a817060a..000000000 --- a/test/sharness/t0041-ping.sh +++ /dev/null @@ -1,54 +0,0 @@ -#!/usr/bin/env bash - -test_description="Test ping command" - -. lib/test-lib.sh - -test_init_ipfs - -BAD_PEER="QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJx" - -# start iptb + wait for peering -test_expect_success 'init iptb' ' - iptb testbed create -type localipfs -count 2 -init -' - -startup_cluster 2 - -test_expect_success 'peer ids' ' - PEERID_0=$(iptb attr get 0 id) && - PEERID_1=$(iptb attr get 1 id) -' - -test_expect_success "test ping other" ' - ipfsi 0 ping -n2 -- "$PEERID_1" && - ipfsi 1 ping -n2 -- "$PEERID_0" -' - -test_expect_success "test ping unreachable peer" ' - printf "Looking up peer %s\n" "$BAD_PEER" > bad_ping_exp && - printf "PING QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJx.\nPing error: failed to dial: failed to dial QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJx: no addresses\nError: ping failed\n" >> bad_ping_exp && - ! ipfsi 0 ping -n2 -- "$BAD_PEER" > bad_ping_actual 2>&1 && - test_cmp bad_ping_exp bad_ping_actual -' - -test_expect_success "test ping self" ' - ! ipfsi 0 ping -n2 -- "$PEERID_0" && - ! ipfsi 1 ping -n2 -- "$PEERID_1" -' - -test_expect_success "test ping 0" ' - ! ipfsi 0 ping -n0 -- "$PEERID_1" && - ! ipfsi 1 ping -n0 -- "$PEERID_0" -' - -test_expect_success "test ping offline" ' - iptb stop 1 && sleep 2 && - ! ipfsi 0 ping -n2 -- "$PEERID_1" -' - -test_expect_success 'stop iptb' ' - iptb stop 0 -' - -test_done From c079a099c00c85de347603b07cffb8d988719d16 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Thu, 21 Sep 2023 19:57:21 +0200 Subject: [PATCH 0878/1212] changelog: mention probelab RFM17.1 dht improvement --- docs/changelogs/v0.23.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/changelogs/v0.23.md b/docs/changelogs/v0.23.md index 62cbac220..6343a9a27 100644 --- a/docs/changelogs/v0.23.md +++ b/docs/changelogs/v0.23.md @@ -13,6 +13,7 @@ - [Self-hosting `/routing/v1` endpoint for delegated routing needs](#self-hosting-routingv1-endpoint-for-delegated-routing-needs) - [Trustless Gateway Over Libp2p Experiment](#trustless-gateway-over-libp2p-experiment) - [Removal of `/quic` (Draft 29) support](#removal-of-quic-draft-29-support) + - [Better Caching of multiaddresses for providers in DHT servers](#better-caching-of-multiaddresses-for-providers-in-dht-servers) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -105,6 +106,15 @@ to have listeners for both `/quic` (Draft 29) and `/quic-v1` (RFC 9000). Similar version we are shipping a migration to remove the current `/quic` addresses, maintaining the `/quic-v1` addresses only. For more background information, check [issue #9496](https://github.com/ipfs/kubo/issues/9496). +#### Better Caching of multiaddresses for providers in DHT servers + +Thanks to [probelab.io's RFM17.1](https://github.com/plprobelab/network-measurements/blob/master/results/rfm17.1-sharing-prs-with-multiaddresses.md) DHT servers will [now cache the addresses of content hosts for the lifetime of the provider record](https://github.com/libp2p/go-libp2p-kad-dht/commit/777160f164b8c187c534debd293157031e9f3a02). + +This means clients who resolve content from theses servers get a responses which include both peer id and multiaddresses. +In most cases this enables skipping a second query which resolves the peer id to multiaddresses for stable enough peers. + +This will improve content fetching lantency in the network overtime as servers updates. + ### 📝 Changelog ### 👨‍👩‍👧‍👦 Contributors From 5c0508b8dd127070a2ab436eccd45034b2241b5c Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Thu, 21 Sep 2023 22:57:38 +0200 Subject: [PATCH 0879/1212] docs: s/ipfs dht/amino dht/ --- docs/config.md | 22 +++++++++++----------- docs/delegated-routing.md | 19 ++++++++++++++----- docs/experimental-features.md | 4 ++-- 3 files changed, 27 insertions(+), 18 deletions(-) diff --git a/docs/config.md b/docs/config.md index 176b69e09..849af4f36 100644 --- a/docs/config.md +++ b/docs/config.md @@ -251,10 +251,10 @@ documented in `ipfs config profile --help`. Reduces daemon overhead on the system. Affects node functionality - performance of content discovery and data - fetching may be degraded. Local data won't be announced on routing systems like DHT. + fetching may be degraded. Local data won't be announced on routing systems like Amino DHT. - `Swarm.ConnMgr` set to maintain minimum number of p2p connections at a time. - - Disables [`Reprovider`](#reprovider) service → no CID will be announced on DHT and other routing systems(!) + - Disables [`Reprovider`](#reprovider) service → no CID will be announced on Amino DHT and other routing systems(!) - Disables AutoNAT. Use this profile with caution. @@ -1006,7 +1006,7 @@ Type: `optionalInteger` (byte count, `null` means default which is 1MB) ### `Internal.Bitswap.ProviderSearchDelay` This parameter determines how long to wait before looking for providers outside of bitswap. -Other routing systems like the DHT are able to provide results in less than a second, so lowering +Other routing systems like the Amino DHT are able to provide results in less than a second, so lowering this number will allow faster peers lookups in some cases. Type: `optionalDuration` (`null` means default which is 1s) @@ -1348,7 +1348,7 @@ The set of peers with which to peer. } ``` -Where `ID` is the peer ID and `Addrs` is a set of known addresses for the peer. If no addresses are specified, the DHT will be queried. +Where `ID` is the peer ID and `Addrs` is a set of known addresses for the peer. If no addresses are specified, the Amino DHT will be queried. Additional fields may be added in the future. @@ -1395,7 +1395,7 @@ Contains options for content, peer, and IPNS routing mechanisms. There are multiple routing options: "auto", "autoclient", "none", "dht", "dhtclient", and "custom". -* **DEFAULT:** If unset, or set to "auto", your node will use the IPFS DHT +* **DEFAULT:** If unset, or set to "auto", your node will use the public IPFS DHT (aka "Amino") and parallel HTTP routers listed below for additional speed. * If set to "autoclient", your node will behave as in "auto" but without running a DHT server. @@ -1403,7 +1403,7 @@ There are multiple routing options: "auto", "autoclient", "none", "dht", "dhtcli * If set to "none", your node will use _no_ routing system. You'll have to explicitly connect to peers that have the content you're looking for. -* If set to "dht" (or "dhtclient"/"dhtserver"), your node will ONLY use the IPFS DHT (no HTTP routers). +* If set to "dht" (or "dhtclient"/"dhtserver"), your node will ONLY use the Amino DHT (no HTTP routers). * If set to "custom", all default routers are disabled, and only ones defined in `Routing.Routers` will be used. @@ -1421,7 +1421,7 @@ When `Routing.Type` is set to `auto` or `dht`, your node will start as a DHT cli switch to a DHT server when and if it determines that it's reachable from the public internet (e.g., it's not behind a firewall). -To force a specific DHT-only mode, client or server, set `Routing.Type` to +To force a specific Amino DHT-only mode, client or server, set `Routing.Type` to `dhtclient` or `dhtserver` respectively. Please do not set this to `dhtserver` unless you're sure your node is reachable from the public network. @@ -1439,7 +1439,7 @@ Type: `optionalString` (`null`/missing means the default) ### `Routing.AcceleratedDHTClient` -This alternative DHT client with a Full-Routing-Table strategy will +This alternative Amino DHT client with a Full-Routing-Table strategy will do a complete scan of the DHT every hour and record all nodes found. Then when a lookup is tried instead of having to go through multiple Kad hops it is able to find the 20 final nodes by looking up the in-memory recorded network table. @@ -1489,7 +1489,7 @@ Type: `bool` (missing means `false`) Map of additional Routers. -Allows for extending the default routing (DHT) with alternative Router +Allows for extending the default routing (Amino DHT) with alternative Router implementations. The map key is a name of a Router, and the value is its configuration. @@ -1524,7 +1524,7 @@ HTTP: - `MaxProvideConcurrency`: It determines the number of threads used when providing content. GOMAXPROCS by default. DHT: - - `"Mode"`: Mode used by the DHT. Possible values: "server", "client", "auto" + - `"Mode"`: Mode used by the Amino DHT. Possible values: "server", "client", "auto" - `"AcceleratedDHTClient"`: Set to `true` if you want to use the acceleratedDHT. - `"PublicIPNetwork"`: Set to `true` to create a `WAN` DHT. Set to `false` to create a `LAN` DHT. @@ -1558,7 +1558,7 @@ Type: `object[string->object]` **Examples:** -Complete example using 2 Routers, DHT (LAN/WAN) and parallel. +Complete example using 2 Routers, Amino DHT (LAN/WAN) and parallel. ``` $ ipfs config Routing.Type --json '"custom"' diff --git a/docs/delegated-routing.md b/docs/delegated-routing.md index 32f7a7552..f4207f409 100644 --- a/docs/delegated-routing.md +++ b/docs/delegated-routing.md @@ -4,12 +4,21 @@ - Related Issues: - https://github.com/ipfs/kubo/issues/9188 - https://github.com/ipfs/kubo/issues/9079 + - https://github.com/ipfs/kubo/pull/9877 ## Summary -Previously we only used DHT for content routing and content providing. After kubo-0.14.0 release we added support for [delegated routing using Reframe protocol](https://github.com/ipfs/kubo/pull/8997). +Previously we only used the Amino DHT for content routing and content +providing. -Now we need a better way to add different routers using different protocols like Reframe or DHT, and be able to configure them to cover different use cases. +Kubo 0.14 introduced experimental support for [delegated routing using Reframe protocol](https://github.com/ipfs/kubo/pull/8997). +Since then, Reframe got deprecated and superseded by [Routing V1 HTTP API](https://specs.ipfs.tech/routing/http-routing-v1/). + +Kubo 0.23.0 release added support for [self-hosting Routing V1 HTTP API server](https://github.com/ipfs/kubo/blob/master/docs/changelogs/v0.23.md#self-hosting-routingv1-endpoint-for-delegated-routing-needs). + +Now we need a better way to add different routers using different protocols +like [Routing V1](https://specs.ipfs.tech/routing/http-routing-v1/) or Amino +DHT, and be able to configure them (future routing systems to come) to cover different use cases. ## Motivation @@ -43,12 +52,12 @@ Params: - `"Endpoint"`: URL endpoint implementing Reframe protocol. -##### DHT +##### Amino DHT Params: -- `"Mode"`: Mode used by the DHT. Possible values: "server", "client", "auto" +- `"Mode"`: Mode used by the Amino DHT. Possible values: "server", "client", "auto" - `"AcceleratedDHTClient"`: Set to `true` if you want to use the experimentalDHT. -- `"PublicIPNetwork"`: Set to `true` to create a `WAN` DHT. Set to `false` to create a `LAN` DHT. +- `"PublicIPNetwork"`: Set to `true` to create a `WAN` Amino DHT. Set to `false` to create a `LAN` DHT. ##### Parallel diff --git a/docs/experimental-features.md b/docs/experimental-features.md index 6527f883b..1f02dc3c8 100644 --- a/docs/experimental-features.md +++ b/docs/experimental-features.md @@ -556,7 +556,7 @@ Stable, enabled by default Experimental, disabled by default. -When the DHT client tries to store a provider in the DHT, it typically searches for the 20 peers that are closest to the +When the Amino DHT client tries to store a provider in the DHT, it typically searches for the 20 peers that are closest to the target key. However, this process can be time-consuming, as the search terminates only after no closer peers are found among the three currently (during the query) known closest ones. In cases where these closest peers are slow to respond (which often happens if they are located at the edge of the DHT network), the query gets blocked by the slowest peer. @@ -569,7 +569,7 @@ ones. This heuristic approach can significantly speed up the process, resulting When it is enabled: -- DHT provide operations should complete much faster than with it disabled +- Amino DHT provide operations should complete much faster than with it disabled - This can be tested with commands such as `ipfs routing provide` **Tradeoffs** From cc3c224c6278c4c62b8d732fefc54cf7246308d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Criado-P=C3=A9rez?= Date: Fri, 22 Sep 2023 13:08:26 +0200 Subject: [PATCH 0880/1212] docs: fix typos --- core/commands/block.go | 2 +- core/node/libp2p/rcmgr.go | 2 +- core/node/libp2p/rcmgr_defaults.go | 6 +++--- docs/config.md | 4 ++-- docs/libp2p-resource-management.md | 6 +++--- peering/peering.go | 2 +- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/core/commands/block.go b/core/commands/block.go index 45b8f2a72..4ad191554 100644 --- a/core/commands/block.go +++ b/core/commands/block.go @@ -169,7 +169,7 @@ only for backward compatibility when a legacy CIDv0 is required (--format=v0). cidCodec, _ := req.Options[blockCidCodecOptionName].(string) format, _ := req.Options[blockFormatOptionName].(string) // deprecated - // use of legacy 'format' needs to supress 'cid-codec' + // use of legacy 'format' needs to suppress 'cid-codec' if format != "" { if cidCodec != "" && cidCodec != "raw" { return fmt.Errorf("unable to use %q (deprecated) and a custom %q at the same time", blockFormatOptionName, blockCidCodecOptionName) diff --git a/core/node/libp2p/rcmgr.go b/core/node/libp2p/rcmgr.go index f545126c4..8ec83601b 100644 --- a/core/node/libp2p/rcmgr.go +++ b/core/node/libp2p/rcmgr.go @@ -181,7 +181,7 @@ func LimitConfig(cfg config.SwarmConfig, userResourceOverrides rcmgr.PartialLimi // This effectively overrides the computed default LimitConfig with any non-"useDefault" values from the userResourceOverrides file. // Because of how how Build works, any rcmgr.Default value in userResourceOverrides - // will be overriden with a computed default value. + // will be overridden with a computed default value. limitConfig = userResourceOverrides.Build(limitConfig) return limitConfig, msg, nil diff --git a/core/node/libp2p/rcmgr_defaults.go b/core/node/libp2p/rcmgr_defaults.go index 7a0e5a282..98fdccb99 100644 --- a/core/node/libp2p/rcmgr_defaults.go +++ b/core/node/libp2p/rcmgr_defaults.go @@ -32,7 +32,7 @@ func createDefaultLimitConfig(cfg config.SwarmConfig) (limitConfig rcmgr.Concret // At least as of 2023-01-25, it's possible to open a connection that // doesn't ask for any memory usage with the libp2p Resource Manager/Accountant // (see https://github.com/libp2p/go-libp2p/issues/2010#issuecomment-1404280736). - // As a result, we can't curretly rely on Memory limits to full protect us. + // As a result, we can't currently rely on Memory limits to full protect us. // Until https://github.com/libp2p/go-libp2p/issues/2010 is addressed, // we take a proxy now of restricting to 1 inbound connection per MB. // Note: this is more generous than go-libp2p's default autoscaled limits which do @@ -114,7 +114,7 @@ func createDefaultLimitConfig(cfg config.SwarmConfig) (limitConfig rcmgr.Concret // Anything in scalingLimitConfig that wasn't defined in partialLimits above will be added (e.g., libp2p's default service limits). partialLimits = partialLimits.Build(scalingLimitConfig.Scale(int64(maxMemory), maxFD)).ToPartialLimitConfig() - // Simple checks to overide autoscaling ensuring limits make sense versus the connmgr values. + // Simple checks to override autoscaling ensuring limits make sense versus the connmgr values. // There are ways to break this, but this should catch most problems already. // We might improve this in the future. // See: https://github.com/ipfs/kubo/issues/9545 @@ -140,7 +140,7 @@ Computed default go-libp2p Resource Manager limits based on: - 'Swarm.ResourceMgr.MaxMemory': %q - 'Swarm.ResourceMgr.MaxFileDescriptors': %d -Theses can be inspected with 'ipfs swarm resources'. +These can be inspected with 'ipfs swarm resources'. `, maxMemoryString, maxFD) diff --git a/docs/config.md b/docs/config.md index 849af4f36..e70b54b3a 100644 --- a/docs/config.md +++ b/docs/config.md @@ -1450,7 +1450,7 @@ However the latency of individual read/write operations should be ~10x faster and the provide throughput up to 6 million times faster on larger datasets! This is not compatible with `Routing.Type` `custom`. If you are using composable routers -you can configure this individualy on each router. +you can configure this individually on each router. When it is enabled: - Client DHT operations (reads and writes) should complete much faster @@ -2146,7 +2146,7 @@ Type: `priority` Mplex is deprecated, this is because it is unreliable and randomly drop streams when sending data *too fast*. -New pieces of code rely on backpressure, that means the stream will dynamicaly +New pieces of code rely on backpressure, that means the stream will dynamically slow down the sending rate if data is getting backed up. Backpressure is provided by **Yamux** and **QUIC**. diff --git a/docs/libp2p-resource-management.md b/docs/libp2p-resource-management.md index b7dbf4bae..410982dab 100644 --- a/docs/libp2p-resource-management.md +++ b/docs/libp2p-resource-management.md @@ -83,7 +83,7 @@ since we assume libp2p knows best here. Source: [core/node/libp2p/rcmgr_defaults.go](https://github.com/ipfs/kubo/blob/master/core/node/libp2p/rcmgr_defaults.go) ### User Supplied Override Limits -A user who wants fine control over the limits used by the go-libp2p resoure manager can specify overrides to the [computed default limits](#computed-default-limits). +A user who wants fine control over the limits used by the go-libp2p resource manager can specify overrides to the [computed default limits](#computed-default-limits). This is done by defining limits in ``$IPFS_PATH/libp2p-resource-limit-overrides.json``. These values trump anything else and are parsed directly by go-libp2p. (See the [go-libp2p Resource Manager README](https://github.com/libp2p/go-libp2p/blob/master/p2p/host/resource-manager/README.md) for formatting.) @@ -98,7 +98,7 @@ As an example: > Protected from exceeding resource limits 2 times: "system: cannot reserve inbound connection: resource limit exceeded" This means that there were 2 recent occurrences where the libp2p resource manager prevented an inbound connection at the "system" [scope](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#resource-scopes). -Specificaly the ``System.ConnsInbound`` limit was hit. +Specifically the ``System.ConnsInbound`` limit was hit. This can be analyzed by viewing the limit and current usage with `ipfs swarm resources`. `System.ConnsInbound` is likely close or at the limit value. @@ -136,7 +136,7 @@ If `Swarm.ConnMgr.HighWater` is greater than resource manager's `System.ConnsInb existing low priority idle connections can prevent new high priority connections from being established. The ResourceMgr doesn't know that the new connection is high priority and simply blocks it because of the limit its enforcing. -To ensure the ConnMgr and ResourceMgr are congruent, the ResourceMgr [computed default limts](#computed-default-limits) are adjusted such that: +To ensure the ConnMgr and ResourceMgr are congruent, the ResourceMgr [computed default limits](#computed-default-limits) are adjusted such that: 1. `System.ConnsInbound` >= `max(Swarm.ConnMgr.HighWater * 2, DefaultResourceMgrMinInboundConns)` AND 2. `System.StreamsInbound` is greater than any new/adjusted `Swarm.ResourceMgr.Limits.System.ConnsInbound` value so that there's enough streams per connection. diff --git a/peering/peering.go b/peering/peering.go index 291d9491c..34647d63c 100644 --- a/peering/peering.go +++ b/peering/peering.go @@ -44,7 +44,7 @@ func (s State) String() string { case StateStopped: return "stopped" default: - return "unkown peering state: " + strconv.FormatUint(uint64(s), 10) + return "unknown peering state: " + strconv.FormatUint(uint64(s), 10) } } From 00e26e9396c39713133bbda5286ee7caf809316e Mon Sep 17 00:00:00 2001 From: Johannes Maria Frank Date: Fri, 22 Sep 2023 14:40:02 +0100 Subject: [PATCH 0881/1212] fix(docker): allow nofuse builds for MacOS (#10135) --- Dockerfile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 15dff4aea..d68e525b9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -15,11 +15,14 @@ COPY . $SRC_DIR # e.g. docker build --build-arg IPFS_PLUGINS="foo bar baz" ARG IPFS_PLUGINS +# Allow for other targets to be built, e.g.: docker build --build-arg MAKE_TARGET="nofuse" +ARG MAKE_TARGET=build + # Build the thing. # Also: fix getting HEAD commit hash via git rev-parse. RUN cd $SRC_DIR \ && mkdir -p .git/objects \ - && GOOS=$TARGETOS GOARCH=$TARGETARCH GOFLAGS=-buildvcs=false make build IPFS_PLUGINS=$IPFS_PLUGINS + && GOOS=$TARGETOS GOARCH=$TARGETARCH GOFLAGS=-buildvcs=false make ${MAKE_TARGET} IPFS_PLUGINS=$IPFS_PLUGINS # Using Debian Buster because the version of busybox we're using is based on it # and we want to make sure the libraries we're using are compatible. That's also From edce05c4cf4cf47bf9de681f38cb4bd5c1a05340 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Mon, 25 Sep 2023 10:07:26 +0200 Subject: [PATCH 0882/1212] docs(readme): header improvements (#10144) --- README.md | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 8438c7ce7..066f0790a 100644 --- a/README.md +++ b/README.md @@ -1,25 +1,35 @@

-Kubo logo -
-Kubo: IPFS Implementation in GO +
+ Kubo logo +
+ Kubo: IPFS Implementation in GO +

+

The first implementation of IPFS.

-
+

+ Official Part of IPFS Project + Discourse Forum + Matrix + ci + GitHub release + godoc reference +

-[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square&cacheSeconds=3600)](https://protocol.ai) -[![GoDoc](https://img.shields.io/badge/godoc-reference-5272B4.svg?style=flat-square&cacheSeconds=3600)](https://godoc.org/github.com/ipfs/kubo) +
## What is Kubo? Kubo was the first IPFS implementation and is the most widely used one today. Implementing the *Interplanetary Filesystem* - the Web3 standard for content-addressing, interoperable with HTTP. Thus powered by IPLD's data models and the libp2p for network communication. Kubo is written in Go. Featureset -- Runs an IPFS-Node as a network service -- [Command Line Interface](https://docs.ipfs.tech/reference/kubo/cli/) to IPFS-Nodes -- Local [Web2-to-Web3 HTTP Gateway functionality](https://github.com/ipfs/specs/tree/main/http-gateways#readme) -- HTTP RPC API (`/api/v0`) to access and control the daemon -- IPFS's internal Webgui can be used to manage the Kubo nodes +- Runs an IPFS-Node as a network service that is part of LAN and WAN DHT +- [HTTP Gateway](https://specs.ipfs.tech/http-gateways/) (`/ipfs` and `/ipns`) functionality for trusted and [trustless](https://docs.ipfs.tech/reference/http/gateway/#trustless-verifiable-retrieval) content retrieval +- [HTTP Routing V1](https://specs.ipfs.tech/routing/http-routing-v1/) (`/routing/v1`) client and server implementation for [delegated routing](./docs/delegated-routing.md) lookups +- [HTTP Kubo RPC API](https://docs.ipfs.tech/reference/kubo/rpc/) (`/api/v0`) to access and control the daemon +- [Command Line Interface](https://docs.ipfs.tech/reference/kubo/cli/) based on (`/api/v0`) RPC API +- [WebUI](https://github.com/ipfs/ipfs-webui/#readme) to manage the Kubo node ### Other implementations From 717317879920185386782188402c3f030c429701 Mon Sep 17 00:00:00 2001 From: "Bernhard M. Wiedemann" Date: Fri, 22 Sep 2023 14:51:05 +0200 Subject: [PATCH 0883/1212] Update go-unixfsnode to 1.8.0 to fix FUSE Fixes #9044 regression in 0.13.0 FUSE access to some files --- docs/changelogs/v0.23.md | 4 ++++ docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- test/dependencies/go.mod | 2 +- test/dependencies/go.sum | 4 ++-- 7 files changed, 13 insertions(+), 9 deletions(-) diff --git a/docs/changelogs/v0.23.md b/docs/changelogs/v0.23.md index 6343a9a27..cb0b41276 100644 --- a/docs/changelogs/v0.23.md +++ b/docs/changelogs/v0.23.md @@ -115,6 +115,10 @@ In most cases this enables skipping a second query which resolves the peer id to This will improve content fetching lantency in the network overtime as servers updates. +#### FUSE working again + +A regression in 0.13.0 broke FUSE and was finally fixed. + ### 📝 Changelog ### 👨‍👩‍👧‍👦 Contributors diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 0eae30fda..233949733 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -87,7 +87,7 @@ require ( github.com/ipfs/go-log/v2 v2.5.1 // indirect github.com/ipfs/go-metrics-interface v0.0.1 // indirect github.com/ipfs/go-peertaskqueue v0.8.1 // indirect - github.com/ipfs/go-unixfsnode v1.7.1 // indirect + github.com/ipfs/go-unixfsnode v1.8.0 // indirect github.com/ipld/go-car/v2 v2.10.2-0.20230622090957-499d0c909d33 // indirect github.com/ipld/go-codec-dagpb v1.6.0 // indirect github.com/ipld/go-ipld-prime v0.21.0 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 71e949367..7eac57168 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -388,8 +388,8 @@ github.com/ipfs/go-metrics-interface v0.0.1/go.mod h1:6s6euYU4zowdslK0GKHmqaIZ3j github.com/ipfs/go-peertaskqueue v0.8.1 h1:YhxAs1+wxb5jk7RvS0LHdyiILpNmRIRnZVztekOF0pg= github.com/ipfs/go-peertaskqueue v0.8.1/go.mod h1:Oxxd3eaK279FxeydSPPVGHzbwVeHjatZ2GA8XD+KbPU= github.com/ipfs/go-unixfs v0.4.5 h1:wj8JhxvV1G6CD7swACwSKYa+NgtdWC1RUit+gFnymDU= -github.com/ipfs/go-unixfsnode v1.7.1 h1:RRxO2b6CSr5UQ/kxnGzaChTjp5LWTdf3Y4n8ANZgB/s= -github.com/ipfs/go-unixfsnode v1.7.1/go.mod h1:PVfoyZkX1B34qzT3vJO4nsLUpRCyhnMuHBznRcXirlk= +github.com/ipfs/go-unixfsnode v1.8.0 h1:yCkakzuE365glu+YkgzZt6p38CSVEBPgngL9ZkfnyQU= +github.com/ipfs/go-unixfsnode v1.8.0/go.mod h1:HxRu9HYHOjK6HUqFBAi++7DVoWAHn0o4v/nZ/VA+0g8= github.com/ipfs/go-verifcid v0.0.2 h1:XPnUv0XmdH+ZIhLGKg6U2vaPaRDXb9urMyNVCE7uvTs= github.com/ipld/go-car/v2 v2.10.2-0.20230622090957-499d0c909d33 h1:0OZwzSYWIuiKEOXd/2vm5cMcEmmGLFn+1h6lHELCm3s= github.com/ipld/go-car/v2 v2.10.2-0.20230622090957-499d0c909d33/go.mod h1:sQEkXVM3csejlb1kCCb+vQ/pWBKX9QtvsrysMQjOgOg= diff --git a/go.mod b/go.mod index a72131737..273293194 100644 --- a/go.mod +++ b/go.mod @@ -35,7 +35,7 @@ require ( github.com/ipfs/go-log/v2 v2.5.1 github.com/ipfs/go-metrics-interface v0.0.1 github.com/ipfs/go-metrics-prometheus v0.0.2 - github.com/ipfs/go-unixfsnode v1.7.1 + github.com/ipfs/go-unixfsnode v1.8.0 github.com/ipld/go-car v0.5.0 github.com/ipld/go-car/v2 v2.10.2-0.20230622090957-499d0c909d33 github.com/ipld/go-codec-dagpb v1.6.0 diff --git a/go.sum b/go.sum index bd444c738..5fc2fe3e7 100644 --- a/go.sum +++ b/go.sum @@ -432,8 +432,8 @@ github.com/ipfs/go-metrics-prometheus v0.0.2/go.mod h1:ELLU99AQQNi+zX6GCGm2lAgnz github.com/ipfs/go-peertaskqueue v0.8.1 h1:YhxAs1+wxb5jk7RvS0LHdyiILpNmRIRnZVztekOF0pg= github.com/ipfs/go-peertaskqueue v0.8.1/go.mod h1:Oxxd3eaK279FxeydSPPVGHzbwVeHjatZ2GA8XD+KbPU= github.com/ipfs/go-unixfs v0.4.5 h1:wj8JhxvV1G6CD7swACwSKYa+NgtdWC1RUit+gFnymDU= -github.com/ipfs/go-unixfsnode v1.7.1 h1:RRxO2b6CSr5UQ/kxnGzaChTjp5LWTdf3Y4n8ANZgB/s= -github.com/ipfs/go-unixfsnode v1.7.1/go.mod h1:PVfoyZkX1B34qzT3vJO4nsLUpRCyhnMuHBznRcXirlk= +github.com/ipfs/go-unixfsnode v1.8.0 h1:yCkakzuE365glu+YkgzZt6p38CSVEBPgngL9ZkfnyQU= +github.com/ipfs/go-unixfsnode v1.8.0/go.mod h1:HxRu9HYHOjK6HUqFBAi++7DVoWAHn0o4v/nZ/VA+0g8= github.com/ipfs/go-verifcid v0.0.2 h1:XPnUv0XmdH+ZIhLGKg6U2vaPaRDXb9urMyNVCE7uvTs= github.com/ipfs/go-verifcid v0.0.2/go.mod h1:40cD9x1y4OWnFXbLNJYRe7MpNvWlMn3LZAG5Wb4xnPU= github.com/ipld/go-car v0.5.0 h1:kcCEa3CvYMs0iE5BzD5sV7O2EwMiCIp3uF8tA6APQT8= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 9f5122156..866d375e1 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -138,7 +138,7 @@ require ( github.com/ipfs/go-log/v2 v2.5.1 // indirect github.com/ipfs/go-metrics-interface v0.0.1 // indirect github.com/ipfs/go-peertaskqueue v0.8.1 // indirect - github.com/ipfs/go-unixfsnode v1.7.1 // indirect + github.com/ipfs/go-unixfsnode v1.8.0 // indirect github.com/ipfs/kubo v0.16.0 // indirect github.com/ipld/go-codec-dagpb v1.6.0 // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index b3af2abeb..8b6db0089 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -449,8 +449,8 @@ github.com/ipfs/go-metrics-interface v0.0.1/go.mod h1:6s6euYU4zowdslK0GKHmqaIZ3j github.com/ipfs/go-peertaskqueue v0.8.1 h1:YhxAs1+wxb5jk7RvS0LHdyiILpNmRIRnZVztekOF0pg= github.com/ipfs/go-peertaskqueue v0.8.1/go.mod h1:Oxxd3eaK279FxeydSPPVGHzbwVeHjatZ2GA8XD+KbPU= github.com/ipfs/go-unixfs v0.4.5 h1:wj8JhxvV1G6CD7swACwSKYa+NgtdWC1RUit+gFnymDU= -github.com/ipfs/go-unixfsnode v1.7.1 h1:RRxO2b6CSr5UQ/kxnGzaChTjp5LWTdf3Y4n8ANZgB/s= -github.com/ipfs/go-unixfsnode v1.7.1/go.mod h1:PVfoyZkX1B34qzT3vJO4nsLUpRCyhnMuHBznRcXirlk= +github.com/ipfs/go-unixfsnode v1.8.0 h1:yCkakzuE365glu+YkgzZt6p38CSVEBPgngL9ZkfnyQU= +github.com/ipfs/go-unixfsnode v1.8.0/go.mod h1:HxRu9HYHOjK6HUqFBAi++7DVoWAHn0o4v/nZ/VA+0g8= github.com/ipfs/go-verifcid v0.0.2 h1:XPnUv0XmdH+ZIhLGKg6U2vaPaRDXb9urMyNVCE7uvTs= github.com/ipfs/hang-fds v0.1.0 h1:deBiFlWHsVGzJ0ZMaqscEqRM1r2O1rFZ59UiQXb1Xko= github.com/ipfs/hang-fds v0.1.0/go.mod h1:29VLWOn3ftAgNNgXg/al7b11UzuQ+w7AwtCGcTaWkbM= From 0f1ec5949e71e52545cda1c58bbbfe80e930d4a3 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Mon, 25 Sep 2023 15:23:12 +0200 Subject: [PATCH 0884/1212] changelog: update fuse 9044's entry --- docs/changelogs/v0.23.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/changelogs/v0.23.md b/docs/changelogs/v0.23.md index cb0b41276..a9b824537 100644 --- a/docs/changelogs/v0.23.md +++ b/docs/changelogs/v0.23.md @@ -14,6 +14,7 @@ - [Trustless Gateway Over Libp2p Experiment](#trustless-gateway-over-libp2p-experiment) - [Removal of `/quic` (Draft 29) support](#removal-of-quic-draft-29-support) - [Better Caching of multiaddresses for providers in DHT servers](#better-caching-of-multiaddresses-for-providers-in-dht-servers) + - [fixed FUSE directory listings](#fixed-fuse-directory-listings) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -115,9 +116,10 @@ In most cases this enables skipping a second query which resolves the peer id to This will improve content fetching lantency in the network overtime as servers updates. -#### FUSE working again +#### fixed FUSE directory listings -A regression in 0.13.0 broke FUSE and was finally fixed. +`ls`ing directories with fuse have been fixed. [#9044](https://github.com/ipfs/kubo/issues/9044) +Thx a lot @bmwiedemann for debugging this issue. ### 📝 Changelog From 7cca58ea270dea771713534dd02c22116b6422f2 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Tue, 26 Sep 2023 11:22:15 +0200 Subject: [PATCH 0885/1212] changelog: generalize fuse 9044's entry --- docs/changelogs/v0.23.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/changelogs/v0.23.md b/docs/changelogs/v0.23.md index a9b824537..ae904c62e 100644 --- a/docs/changelogs/v0.23.md +++ b/docs/changelogs/v0.23.md @@ -14,7 +14,7 @@ - [Trustless Gateway Over Libp2p Experiment](#trustless-gateway-over-libp2p-experiment) - [Removal of `/quic` (Draft 29) support](#removal-of-quic-draft-29-support) - [Better Caching of multiaddresses for providers in DHT servers](#better-caching-of-multiaddresses-for-providers-in-dht-servers) - - [fixed FUSE directory listings](#fixed-fuse-directory-listings) + - [fixed FUSE multiblock structures](#fixed-fuse-multiblock-structures) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -116,9 +116,9 @@ In most cases this enables skipping a second query which resolves the peer id to This will improve content fetching lantency in the network overtime as servers updates. -#### fixed FUSE directory listings +#### fixed FUSE multiblock structures -`ls`ing directories with fuse have been fixed. [#9044](https://github.com/ipfs/kubo/issues/9044) +`ls`ing directories and reading dag-pb files on a fuse volume have been fixed. [#9044](https://github.com/ipfs/kubo/issues/9044) Thx a lot @bmwiedemann for debugging this issue. ### 📝 Changelog From 9cd2c8c99c434d13639a7aaa06d7ffd26755ff50 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Sep 2023 13:42:22 +0000 Subject: [PATCH 0886/1212] chore(deps): bump github.com/ipfs/go-unixfsnode from 1.7.1 to 1.8.1 Bumps [github.com/ipfs/go-unixfsnode](https://github.com/ipfs/go-unixfsnode) from 1.7.1 to 1.8.1. - [Release notes](https://github.com/ipfs/go-unixfsnode/releases) - [Commits](https://github.com/ipfs/go-unixfsnode/compare/v1.7.1...v1.8.1) --- updated-dependencies: - dependency-name: github.com/ipfs/go-unixfsnode dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- test/dependencies/go.mod | 2 +- test/dependencies/go.sum | 4 ++-- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 233949733..732b21b16 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -87,7 +87,7 @@ require ( github.com/ipfs/go-log/v2 v2.5.1 // indirect github.com/ipfs/go-metrics-interface v0.0.1 // indirect github.com/ipfs/go-peertaskqueue v0.8.1 // indirect - github.com/ipfs/go-unixfsnode v1.8.0 // indirect + github.com/ipfs/go-unixfsnode v1.8.1 // indirect github.com/ipld/go-car/v2 v2.10.2-0.20230622090957-499d0c909d33 // indirect github.com/ipld/go-codec-dagpb v1.6.0 // indirect github.com/ipld/go-ipld-prime v0.21.0 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 7eac57168..f640f0ee4 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -388,8 +388,8 @@ github.com/ipfs/go-metrics-interface v0.0.1/go.mod h1:6s6euYU4zowdslK0GKHmqaIZ3j github.com/ipfs/go-peertaskqueue v0.8.1 h1:YhxAs1+wxb5jk7RvS0LHdyiILpNmRIRnZVztekOF0pg= github.com/ipfs/go-peertaskqueue v0.8.1/go.mod h1:Oxxd3eaK279FxeydSPPVGHzbwVeHjatZ2GA8XD+KbPU= github.com/ipfs/go-unixfs v0.4.5 h1:wj8JhxvV1G6CD7swACwSKYa+NgtdWC1RUit+gFnymDU= -github.com/ipfs/go-unixfsnode v1.8.0 h1:yCkakzuE365glu+YkgzZt6p38CSVEBPgngL9ZkfnyQU= -github.com/ipfs/go-unixfsnode v1.8.0/go.mod h1:HxRu9HYHOjK6HUqFBAi++7DVoWAHn0o4v/nZ/VA+0g8= +github.com/ipfs/go-unixfsnode v1.8.1 h1:nEWQl2XL+Zoyh6u0OMzNI8mUeCKLyRgg65WDbTm/oNU= +github.com/ipfs/go-unixfsnode v1.8.1/go.mod h1:HxRu9HYHOjK6HUqFBAi++7DVoWAHn0o4v/nZ/VA+0g8= github.com/ipfs/go-verifcid v0.0.2 h1:XPnUv0XmdH+ZIhLGKg6U2vaPaRDXb9urMyNVCE7uvTs= github.com/ipld/go-car/v2 v2.10.2-0.20230622090957-499d0c909d33 h1:0OZwzSYWIuiKEOXd/2vm5cMcEmmGLFn+1h6lHELCm3s= github.com/ipld/go-car/v2 v2.10.2-0.20230622090957-499d0c909d33/go.mod h1:sQEkXVM3csejlb1kCCb+vQ/pWBKX9QtvsrysMQjOgOg= diff --git a/go.mod b/go.mod index 273293194..134551254 100644 --- a/go.mod +++ b/go.mod @@ -35,7 +35,7 @@ require ( github.com/ipfs/go-log/v2 v2.5.1 github.com/ipfs/go-metrics-interface v0.0.1 github.com/ipfs/go-metrics-prometheus v0.0.2 - github.com/ipfs/go-unixfsnode v1.8.0 + github.com/ipfs/go-unixfsnode v1.8.1 github.com/ipld/go-car v0.5.0 github.com/ipld/go-car/v2 v2.10.2-0.20230622090957-499d0c909d33 github.com/ipld/go-codec-dagpb v1.6.0 diff --git a/go.sum b/go.sum index 5fc2fe3e7..96655891b 100644 --- a/go.sum +++ b/go.sum @@ -432,8 +432,8 @@ github.com/ipfs/go-metrics-prometheus v0.0.2/go.mod h1:ELLU99AQQNi+zX6GCGm2lAgnz github.com/ipfs/go-peertaskqueue v0.8.1 h1:YhxAs1+wxb5jk7RvS0LHdyiILpNmRIRnZVztekOF0pg= github.com/ipfs/go-peertaskqueue v0.8.1/go.mod h1:Oxxd3eaK279FxeydSPPVGHzbwVeHjatZ2GA8XD+KbPU= github.com/ipfs/go-unixfs v0.4.5 h1:wj8JhxvV1G6CD7swACwSKYa+NgtdWC1RUit+gFnymDU= -github.com/ipfs/go-unixfsnode v1.8.0 h1:yCkakzuE365glu+YkgzZt6p38CSVEBPgngL9ZkfnyQU= -github.com/ipfs/go-unixfsnode v1.8.0/go.mod h1:HxRu9HYHOjK6HUqFBAi++7DVoWAHn0o4v/nZ/VA+0g8= +github.com/ipfs/go-unixfsnode v1.8.1 h1:nEWQl2XL+Zoyh6u0OMzNI8mUeCKLyRgg65WDbTm/oNU= +github.com/ipfs/go-unixfsnode v1.8.1/go.mod h1:HxRu9HYHOjK6HUqFBAi++7DVoWAHn0o4v/nZ/VA+0g8= github.com/ipfs/go-verifcid v0.0.2 h1:XPnUv0XmdH+ZIhLGKg6U2vaPaRDXb9urMyNVCE7uvTs= github.com/ipfs/go-verifcid v0.0.2/go.mod h1:40cD9x1y4OWnFXbLNJYRe7MpNvWlMn3LZAG5Wb4xnPU= github.com/ipld/go-car v0.5.0 h1:kcCEa3CvYMs0iE5BzD5sV7O2EwMiCIp3uF8tA6APQT8= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 866d375e1..e96e9e658 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -138,7 +138,7 @@ require ( github.com/ipfs/go-log/v2 v2.5.1 // indirect github.com/ipfs/go-metrics-interface v0.0.1 // indirect github.com/ipfs/go-peertaskqueue v0.8.1 // indirect - github.com/ipfs/go-unixfsnode v1.8.0 // indirect + github.com/ipfs/go-unixfsnode v1.8.1 // indirect github.com/ipfs/kubo v0.16.0 // indirect github.com/ipld/go-codec-dagpb v1.6.0 // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 8b6db0089..ffefae099 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -449,8 +449,8 @@ github.com/ipfs/go-metrics-interface v0.0.1/go.mod h1:6s6euYU4zowdslK0GKHmqaIZ3j github.com/ipfs/go-peertaskqueue v0.8.1 h1:YhxAs1+wxb5jk7RvS0LHdyiILpNmRIRnZVztekOF0pg= github.com/ipfs/go-peertaskqueue v0.8.1/go.mod h1:Oxxd3eaK279FxeydSPPVGHzbwVeHjatZ2GA8XD+KbPU= github.com/ipfs/go-unixfs v0.4.5 h1:wj8JhxvV1G6CD7swACwSKYa+NgtdWC1RUit+gFnymDU= -github.com/ipfs/go-unixfsnode v1.8.0 h1:yCkakzuE365glu+YkgzZt6p38CSVEBPgngL9ZkfnyQU= -github.com/ipfs/go-unixfsnode v1.8.0/go.mod h1:HxRu9HYHOjK6HUqFBAi++7DVoWAHn0o4v/nZ/VA+0g8= +github.com/ipfs/go-unixfsnode v1.8.1 h1:nEWQl2XL+Zoyh6u0OMzNI8mUeCKLyRgg65WDbTm/oNU= +github.com/ipfs/go-unixfsnode v1.8.1/go.mod h1:HxRu9HYHOjK6HUqFBAi++7DVoWAHn0o4v/nZ/VA+0g8= github.com/ipfs/go-verifcid v0.0.2 h1:XPnUv0XmdH+ZIhLGKg6U2vaPaRDXb9urMyNVCE7uvTs= github.com/ipfs/hang-fds v0.1.0 h1:deBiFlWHsVGzJ0ZMaqscEqRM1r2O1rFZ59UiQXb1Xko= github.com/ipfs/hang-fds v0.1.0/go.mod h1:29VLWOn3ftAgNNgXg/al7b11UzuQ+w7AwtCGcTaWkbM= From f138b47d86174ad97fd506375b531b8af5ceb6d7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Sep 2023 13:41:35 +0000 Subject: [PATCH 0887/1212] chore(deps): bump github.com/ipfs/go-graphsync from 0.14.4 to 0.15.1 Bumps [github.com/ipfs/go-graphsync](https://github.com/ipfs/go-graphsync) from 0.14.4 to 0.15.1. - [Release notes](https://github.com/ipfs/go-graphsync/releases) - [Changelog](https://github.com/ipfs/go-graphsync/blob/main/CHANGELOG.md) - [Commits](https://github.com/ipfs/go-graphsync/compare/v0.14.4...v0.15.1) --- updated-dependencies: - dependency-name: github.com/ipfs/go-graphsync dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- test/dependencies/go.mod | 2 +- test/dependencies/go.sum | 4 ++-- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 732b21b16..80f8172c4 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -71,7 +71,7 @@ require ( github.com/ipfs/go-ds-leveldb v0.5.0 // indirect github.com/ipfs/go-ds-measure v0.2.0 // indirect github.com/ipfs/go-fs-lock v0.0.7 // indirect - github.com/ipfs/go-graphsync v0.14.4 // indirect + github.com/ipfs/go-graphsync v0.15.1 // indirect github.com/ipfs/go-ipfs-blockstore v1.3.0 // indirect github.com/ipfs/go-ipfs-delay v0.0.1 // indirect github.com/ipfs/go-ipfs-ds-help v1.1.0 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index f640f0ee4..feaef33b5 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -338,8 +338,8 @@ github.com/ipfs/go-ds-measure v0.2.0 h1:sG4goQe0KDTccHMyT45CY1XyUbxe5VwTKpg2LjAp github.com/ipfs/go-ds-measure v0.2.0/go.mod h1:SEUD/rE2PwRa4IQEC5FuNAmjJCyYObZr9UvVh8V3JxE= github.com/ipfs/go-fs-lock v0.0.7 h1:6BR3dajORFrFTkb5EpCUFIAypsoxpGpDSVUdFwzgL9U= github.com/ipfs/go-fs-lock v0.0.7/go.mod h1:Js8ka+FNYmgQRLrRXzU3CB/+Csr1BwrRilEcvYrHhhc= -github.com/ipfs/go-graphsync v0.14.4 h1:ysazATpwsIjYtYEZH5CdD/HRaonCJd4pASUtnzESewk= -github.com/ipfs/go-graphsync v0.14.4/go.mod h1:yT0AfjFgicOoWdAlUJ96tQ5AkuGI4r1taIQX/aHbBQo= +github.com/ipfs/go-graphsync v0.15.1 h1:7v4VfRQ/8pKzPuE0wHeMaWhKu8D/RlezIrzvGWIBtHQ= +github.com/ipfs/go-graphsync v0.15.1/go.mod h1:eUIYS0OKkdBbG4vHhfGkY3lZ7h1G5Dlwd+HxTCe18vA= github.com/ipfs/go-ipfs-blockstore v1.3.0 h1:m2EXaWgwTzAfsmt5UdJ7Is6l4gJcaM/A12XwJyvYvMM= github.com/ipfs/go-ipfs-blockstore v1.3.0/go.mod h1:KgtZyc9fq+P2xJUiCAzbRdhhqJHvsw8u2Dlqy2MyRTE= github.com/ipfs/go-ipfs-blocksutil v0.0.1 h1:Eh/H4pc1hsvhzsQoMEP3Bke/aW5P5rVM1IWFJMcGIPQ= diff --git a/go.mod b/go.mod index 134551254..3dc7f6827 100644 --- a/go.mod +++ b/go.mod @@ -26,7 +26,7 @@ require ( github.com/ipfs/go-ds-leveldb v0.5.0 github.com/ipfs/go-ds-measure v0.2.0 github.com/ipfs/go-fs-lock v0.0.7 - github.com/ipfs/go-graphsync v0.14.4 + github.com/ipfs/go-graphsync v0.15.1 github.com/ipfs/go-ipfs-cmds v0.10.0 github.com/ipfs/go-ipld-format v0.5.0 github.com/ipfs/go-ipld-git v0.1.1 diff --git a/go.sum b/go.sum index 96655891b..9e06cc307 100644 --- a/go.sum +++ b/go.sum @@ -375,8 +375,8 @@ github.com/ipfs/go-ds-measure v0.2.0 h1:sG4goQe0KDTccHMyT45CY1XyUbxe5VwTKpg2LjAp github.com/ipfs/go-ds-measure v0.2.0/go.mod h1:SEUD/rE2PwRa4IQEC5FuNAmjJCyYObZr9UvVh8V3JxE= github.com/ipfs/go-fs-lock v0.0.7 h1:6BR3dajORFrFTkb5EpCUFIAypsoxpGpDSVUdFwzgL9U= github.com/ipfs/go-fs-lock v0.0.7/go.mod h1:Js8ka+FNYmgQRLrRXzU3CB/+Csr1BwrRilEcvYrHhhc= -github.com/ipfs/go-graphsync v0.14.4 h1:ysazATpwsIjYtYEZH5CdD/HRaonCJd4pASUtnzESewk= -github.com/ipfs/go-graphsync v0.14.4/go.mod h1:yT0AfjFgicOoWdAlUJ96tQ5AkuGI4r1taIQX/aHbBQo= +github.com/ipfs/go-graphsync v0.15.1 h1:7v4VfRQ/8pKzPuE0wHeMaWhKu8D/RlezIrzvGWIBtHQ= +github.com/ipfs/go-graphsync v0.15.1/go.mod h1:eUIYS0OKkdBbG4vHhfGkY3lZ7h1G5Dlwd+HxTCe18vA= github.com/ipfs/go-ipfs-blockstore v1.3.0 h1:m2EXaWgwTzAfsmt5UdJ7Is6l4gJcaM/A12XwJyvYvMM= github.com/ipfs/go-ipfs-blockstore v1.3.0/go.mod h1:KgtZyc9fq+P2xJUiCAzbRdhhqJHvsw8u2Dlqy2MyRTE= github.com/ipfs/go-ipfs-blocksutil v0.0.1 h1:Eh/H4pc1hsvhzsQoMEP3Bke/aW5P5rVM1IWFJMcGIPQ= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index e96e9e658..509ad2c8c 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -11,7 +11,7 @@ require ( github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 github.com/ipfs/go-datastore v0.6.0 - github.com/ipfs/go-graphsync v0.14.4 + github.com/ipfs/go-graphsync v0.15.1 github.com/ipfs/go-log v1.0.5 github.com/ipfs/hang-fds v0.1.0 github.com/ipfs/iptb v1.4.0 diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index ffefae099..71d07193f 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -413,8 +413,8 @@ github.com/ipfs/go-datastore v0.6.0 h1:JKyz+Gvz1QEZw0LsX1IBn+JFCJQH4SJVFtM4uWU0M github.com/ipfs/go-datastore v0.6.0/go.mod h1:rt5M3nNbSO/8q1t4LNkLyUwRs8HupMeN/8O4Vn9YAT8= github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk= github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps= -github.com/ipfs/go-graphsync v0.14.4 h1:ysazATpwsIjYtYEZH5CdD/HRaonCJd4pASUtnzESewk= -github.com/ipfs/go-graphsync v0.14.4/go.mod h1:yT0AfjFgicOoWdAlUJ96tQ5AkuGI4r1taIQX/aHbBQo= +github.com/ipfs/go-graphsync v0.15.1 h1:7v4VfRQ/8pKzPuE0wHeMaWhKu8D/RlezIrzvGWIBtHQ= +github.com/ipfs/go-graphsync v0.15.1/go.mod h1:eUIYS0OKkdBbG4vHhfGkY3lZ7h1G5Dlwd+HxTCe18vA= github.com/ipfs/go-ipfs-blockstore v1.3.0 h1:m2EXaWgwTzAfsmt5UdJ7Is6l4gJcaM/A12XwJyvYvMM= github.com/ipfs/go-ipfs-blockstore v1.3.0/go.mod h1:KgtZyc9fq+P2xJUiCAzbRdhhqJHvsw8u2Dlqy2MyRTE= github.com/ipfs/go-ipfs-blocksutil v0.0.1 h1:Eh/H4pc1hsvhzsQoMEP3Bke/aW5P5rVM1IWFJMcGIPQ= From 8eecfcb4a637f36e952e7aaefc39a0fdb44eac1d Mon Sep 17 00:00:00 2001 From: Jorropo Date: Tue, 26 Sep 2023 11:35:08 +0200 Subject: [PATCH 0888/1212] tests: use the latest tag to run helia interop All PRs have been merged: - https://github.com/ipfs/helia/pull/200 - https://github.com/ipfs/helia-unixfs/pull/68 - https://github.com/ipfs/helia-ipns/pull/72 --- .github/workflows/build.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 49ac96690..16fd611d5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -80,10 +80,6 @@ jobs: path: interop - name: Checkout latest tag run: | - exit 0 # temporary while theses pull requests are released: - # https://github.com/ipfs/helia/pull/200 - # https://github.com/ipfs/helia-unixfs/pull/68 - # https://github.com/ipfs/helia-ipns/pull/72 export TAG="$(git describe --tags --abbrev=0)" echo "Running tests against: $TAG" git checkout "$TAG" From 1d295eae92e5b61cfd75e1629b990acb331b79ce Mon Sep 17 00:00:00 2001 From: Jorropo Date: Tue, 26 Sep 2023 11:37:30 +0200 Subject: [PATCH 0889/1212] tests: use latest npm-kubo https://github.com/ipfs/npm-kubo/pull/62 has been released in v0.22.0. --- .github/workflows/build.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 16fd611d5..e3090696f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -90,8 +90,6 @@ jobs: working-directory: interop - run: npm install working-directory: interop/packages/interop - - run: npm install --ignore-scripts --save "ipfs/npm-go-ipfs#4441b8a60f1cfee3035a9e4bb824dfcca08e9b01" # temporary while https://github.com/ipfs/npm-go-ipfs/pull/62 is being bubbled - working-directory: interop/packages/interop - run: npm test working-directory: interop/packages/interop env: From 9dbe4f4cca9d5c1a2f404052dff40a2d061a5a0e Mon Sep 17 00:00:00 2001 From: Jorropo Date: Tue, 26 Sep 2023 10:22:54 +0000 Subject: [PATCH 0890/1212] chore: update version --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index 5eb0e2981..c8c434d10 100644 --- a/version.go +++ b/version.go @@ -11,7 +11,7 @@ import ( var CurrentCommit string // CurrentVersionNumber is the current application's version literal. -const CurrentVersionNumber = "0.23.0-dev" +const CurrentVersionNumber = "0.23.0-rc1" const ApiVersion = "/kubo/" + CurrentVersionNumber + "/" //nolint From 600c71bc3c024bb646a8e72d8f072ef9ab23147e Mon Sep 17 00:00:00 2001 From: Jorropo Date: Tue, 26 Sep 2023 10:33:05 +0000 Subject: [PATCH 0891/1212] chore: update version --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index 5eb0e2981..bed881f01 100644 --- a/version.go +++ b/version.go @@ -11,7 +11,7 @@ import ( var CurrentCommit string // CurrentVersionNumber is the current application's version literal. -const CurrentVersionNumber = "0.23.0-dev" +const CurrentVersionNumber = "0.24.0-dev" const ApiVersion = "/kubo/" + CurrentVersionNumber + "/" //nolint From de173df9e36f1cff9e237f482ecb609ea90d9e35 Mon Sep 17 00:00:00 2001 From: "P. Reis" <76563803+patrickReiis@users.noreply.github.com> Date: Wed, 27 Sep 2023 05:36:49 -0300 Subject: [PATCH 0892/1212] fix(commands/cid): error on CIDv0 w/ custom -b, upgrade to CIDv1 w/ custom -b, empty -v Co-authored-by: Henrique Dias --- core/commands/cid.go | 7 ++- core/commands/cid_test.go | 111 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 core/commands/cid_test.go diff --git a/core/commands/cid.go b/core/commands/cid.go index 017a5d191..b2e8f131d 100644 --- a/core/commands/cid.go +++ b/core/commands/cid.go @@ -80,11 +80,16 @@ The optional format string is a printf style format string: switch verStr { case "": - // noop + if baseStr != "" { + opts.verConv = toCidV1 + } case "0": if opts.newCodec != 0 && opts.newCodec != cid.DagProtobuf { return fmt.Errorf("cannot convert to CIDv0 with any codec other than dag-pb") } + if baseStr != "" && baseStr != "base58btc" { + return fmt.Errorf("cannot convert to CIDv0 with any multibase other than the implicit base58btc") + } opts.verConv = toCidV0 case "1": opts.verConv = toCidV1 diff --git a/core/commands/cid_test.go b/core/commands/cid_test.go new file mode 100644 index 000000000..106296282 --- /dev/null +++ b/core/commands/cid_test.go @@ -0,0 +1,111 @@ +package commands + +import ( + "testing" + + cmds "github.com/ipfs/go-ipfs-cmds" + "github.com/multiformats/go-multibase" +) + +func TestCidFmtCmd(t *testing.T) { + t.Parallel() + + // Test 'error when -v 0 is present and a custom -b is passed' + t.Run("ipfs cid format -b z -v 0", func(t *testing.T) { + t.Parallel() + + type testV0PresentAndCustomBaseCase struct { + MultibaseName string + ExpectedErrMsg string + } + + var testV0PresentAndCustomBaseCases []testV0PresentAndCustomBaseCase + + for _, e := range multibase.EncodingToStr { + var testCase testV0PresentAndCustomBaseCase + + if e == "base58btc" { + testCase.MultibaseName = e + testCase.ExpectedErrMsg = "" + testV0PresentAndCustomBaseCases = append(testV0PresentAndCustomBaseCases, testCase) + continue + } + testCase.MultibaseName = e + testCase.ExpectedErrMsg = "cannot convert to CIDv0 with any multibase other than the implicit base58btc" + testV0PresentAndCustomBaseCases = append(testV0PresentAndCustomBaseCases, testCase) + } + + for _, e := range testV0PresentAndCustomBaseCases { + + // Mock request + req := &cmds.Request{ + Options: map[string]interface{}{ + cidVerisonOptionName: "0", + cidMultibaseOptionName: e.MultibaseName, + cidFormatOptionName: "%s", + }, + } + + // Response emitter + resp := cmds.ResponseEmitter(nil) + + // Call the CidFmtCmd function with the mock request and response + err := cidFmtCmd.Run(req, resp, nil) + if err == nil && e.MultibaseName == "base58btc" { + continue + } + + errMsg := err.Error() + if errMsg != e.ExpectedErrMsg { + t.Errorf("Expected %s, got %s instead", e.ExpectedErrMsg, errMsg) + } + } + }) + + // Test 'upgrade CID to v1 when passing a custom -b and no -v is specified' + t.Run("ipfs cid format -b z", func(t *testing.T) { + t.Parallel() + + type testImplicitVersionAndCustomMultibaseCase struct { + Ver string + CidV1 string + CidV0 string + MultibaseName string + } + + var testCases = []testImplicitVersionAndCustomMultibaseCase{ + { + Ver: "", + CidV1: "zdj7WWwMSWGoyxYkkT7mHgYvr6tV8CYd77aYxxqSbg9HsiMcE", + CidV0: "QmPr755CxWUwt39C2Yiw4UGKrv16uZhSgeZJmoHUUS9TSJ", + MultibaseName: "z", + }, + { + Ver: "", + CidV1: "CAFYBEIDI7ZABPGG3S63QW3AJG2XAZNE4NJQPN777WLWYRAIDG3TE5QFN3A======", + CidV0: "QmVQVyEijmLb2cBQrowNQsaPbnUnJhfDK1sYe3wepm6ySf", + MultibaseName: "base32padupper", + }, + } + for _, e := range testCases { + // Mock request + req := &cmds.Request{ + Options: map[string]interface{}{ + cidVerisonOptionName: e.Ver, + cidMultibaseOptionName: e.MultibaseName, + cidFormatOptionName: "%s", + }, + } + + // Response emitter + resp := cmds.ResponseEmitter(nil) + + // Call the CidFmtCmd function with the mock request and response + err := cidFmtCmd.Run(req, resp, nil) + + if err != nil { + t.Error(err) + } + } + }) +} From a4efea5c76f95438956a43228f32a0cd61960190 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Sep 2023 21:52:41 +0000 Subject: [PATCH 0893/1212] chore(deps): bump actions/checkout from 3 to 4 Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/gateway-conformance.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gateway-conformance.yml b/.github/workflows/gateway-conformance.yml index f663cebd3..b766b2a9f 100644 --- a/.github/workflows/gateway-conformance.yml +++ b/.github/workflows/gateway-conformance.yml @@ -142,7 +142,7 @@ jobs: with: name: ${{ github.job }} - name: Checkout kubo-gateway - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: path: kubo-gateway - name: Build kubo-gateway From 695bf66674931a138862b6fa2cb0b16dc2f6ddd8 Mon Sep 17 00:00:00 2001 From: Laurent Senta Date: Mon, 2 Oct 2023 12:05:19 +0200 Subject: [PATCH 0894/1212] ci: gateway-conformance v0.4 --- .github/workflows/gateway-conformance.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/gateway-conformance.yml b/.github/workflows/gateway-conformance.yml index b766b2a9f..754a2e5a8 100644 --- a/.github/workflows/gateway-conformance.yml +++ b/.github/workflows/gateway-conformance.yml @@ -41,7 +41,7 @@ jobs: steps: # 1. Download the gateway-conformance fixtures - name: Download gateway-conformance fixtures - uses: ipfs/gateway-conformance/.github/actions/extract-fixtures@v0.3 + uses: ipfs/gateway-conformance/.github/actions/extract-fixtures@v0.4 with: output: fixtures @@ -96,7 +96,7 @@ jobs: # 6. Run the gateway-conformance tests - name: Run gateway-conformance tests - uses: ipfs/gateway-conformance/.github/actions/test@v0.3 + uses: ipfs/gateway-conformance/.github/actions/test@v0.4 with: gateway-url: http://127.0.0.1:8080 json: output.json @@ -129,7 +129,7 @@ jobs: steps: # 1. Download the gateway-conformance fixtures - name: Download gateway-conformance fixtures - uses: ipfs/gateway-conformance/.github/actions/extract-fixtures@v0.3 + uses: ipfs/gateway-conformance/.github/actions/extract-fixtures@v0.4 with: output: fixtures @@ -202,7 +202,7 @@ jobs: # 9. Run the gateway-conformance tests over libp2p - name: Run gateway-conformance tests over libp2p - uses: ipfs/gateway-conformance/.github/actions/test@v0.3 + uses: ipfs/gateway-conformance/.github/actions/test@v0.4 with: gateway-url: http://127.0.0.1:8092 json: output.json From 97527472fe4c037bb897aa2c7d4e0b2243b58f85 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Mon, 2 Oct 2023 16:43:52 +0200 Subject: [PATCH 0895/1212] feat(gateway): update gateway api, no multi-range support --- CHANGELOG.md | 1 + core/corehttp/gateway.go | 2 +- docs/changelogs/v0.24.md | 27 ++++++++++++++++++ docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 +-- go.mod | 2 +- go.sum | 4 +-- test/cli/gateway_range_test.go | 39 +++++++++++++++++++++----- test/dependencies/go.mod | 2 +- test/dependencies/go.sum | 4 +-- 10 files changed, 70 insertions(+), 17 deletions(-) create mode 100644 docs/changelogs/v0.24.md diff --git a/CHANGELOG.md b/CHANGELOG.md index f15248cc1..0f75314a9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ # Kubo Changelogs +- [v0.24](docs/changelogs/v0.24.md) - [v0.23](docs/changelogs/v0.23.md) - [v0.22](docs/changelogs/v0.22.md) - [v0.21](docs/changelogs/v0.21.md) diff --git a/core/corehttp/gateway.go b/core/corehttp/gateway.go index 67da588ca..767934123 100644 --- a/core/corehttp/gateway.go +++ b/core/corehttp/gateway.go @@ -167,7 +167,7 @@ func (o *offlineGatewayErrWrapper) GetBlock(ctx context.Context, path gateway.Im return md, n, err } -func (o *offlineGatewayErrWrapper) Head(ctx context.Context, path gateway.ImmutablePath) (gateway.ContentPathMetadata, files.Node, error) { +func (o *offlineGatewayErrWrapper) Head(ctx context.Context, path gateway.ImmutablePath) (gateway.ContentPathMetadata, *gateway.HeadResponse, error) { md, n, err := o.gwimpl.Head(ctx, path) err = offlineErrWrap(err) return md, n, err diff --git a/docs/changelogs/v0.24.md b/docs/changelogs/v0.24.md new file mode 100644 index 000000000..a19526ad1 --- /dev/null +++ b/docs/changelogs/v0.24.md @@ -0,0 +1,27 @@ +# Kubo changelog v0.24 + +- [v0.24.0](#v0240) + +## v0.24.0 + +- [Overview](#overview) +- [🔦 Highlights](#-highlights) + - [Gateway: the root of the CARs are no longer meaningful](#gateway-the-root-of-the-cars-are-no-longer-meaningful) +- [📝 Changelog](#-changelog) +- [👨‍👩‍👧‍👦 Contributors](#-contributors) + +### Overview + +### 🔦 Highlights + +#### Gateway: the root of the CARs are no longer meaningful + +When requesting a CAR from the gateway, the root of the CAR might no longer be +meaningful. By default, the CAR root will be the last resolvable segment of the +path. However, in situations where the path cannot be resolved, such as when +the path does not exist, a CAR will be sent with a root of `bafkqaaa` (empty CID). +This CAR will contain all blocks necessary to validate that the path does not exist. + +### 📝 Changelog + +### 👨‍👩‍👧‍👦 Contributors diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 80f8172c4..a465c7cc6 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.20 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.13.1 + github.com/ipfs/boxo v0.13.2-0.20231002142647-c28c847582f0 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.31.0 github.com/multiformats/go-multiaddr v0.11.0 diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index feaef33b5..c35386932 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -300,8 +300,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.13.1 h1:nQ5oQzcMZR3oL41REJDcTbrvDvuZh3J9ckc9+ILeRQI= -github.com/ipfs/boxo v0.13.1/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk= +github.com/ipfs/boxo v0.13.2-0.20231002142647-c28c847582f0 h1:oss04OCg1/QW0h3OfSCZJiUQErpYPOsz7+X4tpgwODs= +github.com/ipfs/boxo v0.13.2-0.20231002142647-c28c847582f0/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= diff --git a/go.mod b/go.mod index 3dc7f6827..e9280f996 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( github.com/fsnotify/fsnotify v1.6.0 github.com/google/uuid v1.3.0 github.com/hashicorp/go-multierror v1.1.1 - github.com/ipfs/boxo v0.13.1 + github.com/ipfs/boxo v0.13.2-0.20231002142647-c28c847582f0 github.com/ipfs/go-block-format v0.1.2 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 diff --git a/go.sum b/go.sum index 9e06cc307..441c156ae 100644 --- a/go.sum +++ b/go.sum @@ -335,8 +335,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.13.1 h1:nQ5oQzcMZR3oL41REJDcTbrvDvuZh3J9ckc9+ILeRQI= -github.com/ipfs/boxo v0.13.1/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk= +github.com/ipfs/boxo v0.13.2-0.20231002142647-c28c847582f0 h1:oss04OCg1/QW0h3OfSCZJiUQErpYPOsz7+X4tpgwODs= +github.com/ipfs/boxo v0.13.2-0.20231002142647-c28c847582f0/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= diff --git a/test/cli/gateway_range_test.go b/test/cli/gateway_range_test.go index 7440e6341..2d8ce1a3e 100644 --- a/test/cli/gateway_range_test.go +++ b/test/cli/gateway_range_test.go @@ -41,7 +41,7 @@ func TestGatewayHAMTDirectory(t *testing.T) { assert.Equal(t, http.StatusOK, resp.StatusCode) } -func TestGatewayMultiRange(t *testing.T) { +func TestGatewayHAMTRanges(t *testing.T) { t.Parallel() const ( @@ -65,11 +65,36 @@ func TestGatewayMultiRange(t *testing.T) { err = node.IPFSDagImport(r, fixtureCid) assert.NoError(t, err) - // Succeeds fetching a range of blocks we have - resp := client.Get(fmt.Sprintf("/ipfs/%s", fileCid), func(r *http.Request) { - r.Header.Set("Range", "bytes=1276-1279, 29839070-29839080") + t.Run("Succeeds Fetching Range", func(t *testing.T) { + t.Parallel() + + resp := client.Get(fmt.Sprintf("/ipfs/%s", fileCid), func(r *http.Request) { + r.Header.Set("Range", "bytes=1276-1279") + }) + assert.Equal(t, http.StatusPartialContent, resp.StatusCode) + assert.Equal(t, "bytes 1276-1279/109266405", resp.Headers.Get("Content-Range")) + assert.Equal(t, "iana", resp.Body) + }) + + t.Run("Succeeds Fetching Second Range", func(t *testing.T) { + t.Parallel() + + resp := client.Get(fmt.Sprintf("/ipfs/%s", fileCid), func(r *http.Request) { + r.Header.Set("Range", "bytes=29839070-29839080") + }) + assert.Equal(t, http.StatusPartialContent, resp.StatusCode) + assert.Equal(t, "bytes 29839070-29839080/109266405", resp.Headers.Get("Content-Range")) + assert.Equal(t, "EXAMPLE.COM", resp.Body) + }) + + t.Run("Succeeds Fetching First Range of Multi-range Request", func(t *testing.T) { + t.Parallel() + + resp := client.Get(fmt.Sprintf("/ipfs/%s", fileCid), func(r *http.Request) { + r.Header.Set("Range", "bytes=1276-1279, 29839070-29839080") + }) + assert.Equal(t, http.StatusPartialContent, resp.StatusCode) + assert.Equal(t, "bytes 1276-1279/109266405", resp.Headers.Get("Content-Range")) + assert.Equal(t, "iana", resp.Body) }) - assert.Equal(t, http.StatusPartialContent, resp.StatusCode) - assert.Contains(t, resp.Body, "Content-Range: bytes 1276-1279/109266405\r\nContent-Type: text/plain; charset=utf-8\r\n\r\niana\r\n") - assert.Contains(t, resp.Body, "Content-Range: bytes 29839070-29839080/109266405\r\nContent-Type: text/plain; charset=utf-8\r\n\r\nEXAMPLE.COM\r\n") } diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 509ad2c8c..ab9cb3810 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -7,7 +7,7 @@ replace github.com/ipfs/kubo => ../../ require ( github.com/Kubuxu/gocovmerge v0.0.0-20161216165753-7ecaa51963cd github.com/golangci/golangci-lint v1.54.1 - github.com/ipfs/boxo v0.13.1 + github.com/ipfs/boxo v0.13.2-0.20231002142647-c28c847582f0 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 github.com/ipfs/go-datastore v0.6.0 diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 71d07193f..a314fbac0 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -396,8 +396,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.13.1 h1:nQ5oQzcMZR3oL41REJDcTbrvDvuZh3J9ckc9+ILeRQI= -github.com/ipfs/boxo v0.13.1/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk= +github.com/ipfs/boxo v0.13.2-0.20231002142647-c28c847582f0 h1:oss04OCg1/QW0h3OfSCZJiUQErpYPOsz7+X4tpgwODs= +github.com/ipfs/boxo v0.13.2-0.20231002142647-c28c847582f0/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.1.2 h1:GAjkfhVx1f4YTODS6Esrj1wt2HhrtwTnhEr+DyPUaJo= From c80a5a867b8e81f51cf78615abd3c58e5bf289c3 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Wed, 4 Oct 2023 11:53:08 +0200 Subject: [PATCH 0896/1212] docs: capitalize headers for consistency --- docs/changelogs/v0.23.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/changelogs/v0.23.md b/docs/changelogs/v0.23.md index ae904c62e..5b7879601 100644 --- a/docs/changelogs/v0.23.md +++ b/docs/changelogs/v0.23.md @@ -14,7 +14,7 @@ - [Trustless Gateway Over Libp2p Experiment](#trustless-gateway-over-libp2p-experiment) - [Removal of `/quic` (Draft 29) support](#removal-of-quic-draft-29-support) - [Better Caching of multiaddresses for providers in DHT servers](#better-caching-of-multiaddresses-for-providers-in-dht-servers) - - [fixed FUSE multiblock structures](#fixed-fuse-multiblock-structures) + - [Fixed FUSE multiblock structures](#fixed-fuse-multiblock-structures) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -116,7 +116,7 @@ In most cases this enables skipping a second query which resolves the peer id to This will improve content fetching lantency in the network overtime as servers updates. -#### fixed FUSE multiblock structures +#### Fixed FUSE multiblock structures `ls`ing directories and reading dag-pb files on a fuse volume have been fixed. [#9044](https://github.com/ipfs/kubo/issues/9044) Thx a lot @bmwiedemann for debugging this issue. From 6dbae768180d1f454f4d9d24920be4bc161216b6 Mon Sep 17 00:00:00 2001 From: Andrej Manduch Date: Thu, 5 Oct 2023 09:29:10 +0200 Subject: [PATCH 0897/1212] fix: align systemd unit file with default IPFS installation path (#10163) --- misc/README.md | 2 +- misc/systemd/ipfs-hardened.service | 4 ++-- misc/systemd/ipfs.service | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/misc/README.md b/misc/README.md index 16abf0441..28511d3fc 100644 --- a/misc/README.md +++ b/misc/README.md @@ -17,7 +17,7 @@ Description=IPFS daemon [Service] # Environment="IPFS_PATH=/data/ipfs" # optional path to ipfs init directory if not default ($HOME/.ipfs) -ExecStart=/usr/bin/ipfs daemon +ExecStart=/usr/local/bin/ipfs daemon Restart=on-failure [Install] diff --git a/misc/systemd/ipfs-hardened.service b/misc/systemd/ipfs-hardened.service index 261b82e2a..785a59829 100644 --- a/misc/systemd/ipfs-hardened.service +++ b/misc/systemd/ipfs-hardened.service @@ -8,7 +8,7 @@ # To overwrite a variable, like ExecStart you have to specify it once # blank and a second time with a new value, like: # ExecStart= -# ExecStart=/usr/bin/ipfs daemon --flag1 --flag2 +# ExecStart=/usr/local/bin/ipfs daemon --flag1 --flag2 # # For more info about custom unit files see systemd.unit(5). @@ -70,7 +70,7 @@ User=ipfs Group=ipfs StateDirectory=ipfs Environment=IPFS_PATH="${HOME}" -ExecStart=/usr/bin/ipfs daemon --init --migrate +ExecStart=/usr/local/bin/ipfs daemon --init --migrate Restart=on-failure KillSignal=SIGINT diff --git a/misc/systemd/ipfs.service b/misc/systemd/ipfs.service index 0051dffdd..ab074e22e 100644 --- a/misc/systemd/ipfs.service +++ b/misc/systemd/ipfs.service @@ -8,7 +8,7 @@ # To overwrite a variable, like ExecStart you have to specify it once # blank and a second time with a new value, like: # ExecStart= -# ExecStart=/usr/bin/ipfs daemon --flag1 --flag2 +# ExecStart=/usr/local/bin/ipfs daemon --flag1 --flag2 # # For more info about custom unit files see systemd.unit(5). @@ -41,7 +41,7 @@ User=ipfs Group=ipfs StateDirectory=ipfs Environment=IPFS_PATH="${HOME}" -ExecStart=/usr/bin/ipfs daemon --init --migrate +ExecStart=/usr/local/bin/ipfs daemon --init --migrate Restart=on-failure KillSignal=SIGINT From bd36a9d06b65bab4d915d29905cc84a75cb86559 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Wed, 4 Oct 2023 11:53:08 +0200 Subject: [PATCH 0898/1212] docs: capitalize headers for consistency (cherry picked from commit c80a5a867b8e81f51cf78615abd3c58e5bf289c3) --- docs/changelogs/v0.23.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/changelogs/v0.23.md b/docs/changelogs/v0.23.md index ae904c62e..5b7879601 100644 --- a/docs/changelogs/v0.23.md +++ b/docs/changelogs/v0.23.md @@ -14,7 +14,7 @@ - [Trustless Gateway Over Libp2p Experiment](#trustless-gateway-over-libp2p-experiment) - [Removal of `/quic` (Draft 29) support](#removal-of-quic-draft-29-support) - [Better Caching of multiaddresses for providers in DHT servers](#better-caching-of-multiaddresses-for-providers-in-dht-servers) - - [fixed FUSE multiblock structures](#fixed-fuse-multiblock-structures) + - [Fixed FUSE multiblock structures](#fixed-fuse-multiblock-structures) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -116,7 +116,7 @@ In most cases this enables skipping a second query which resolves the peer id to This will improve content fetching lantency in the network overtime as servers updates. -#### fixed FUSE multiblock structures +#### Fixed FUSE multiblock structures `ls`ing directories and reading dag-pb files on a fuse volume have been fixed. [#9044](https://github.com/ipfs/kubo/issues/9044) Thx a lot @bmwiedemann for debugging this issue. From 7d26d78cf01f3656428f6fd4739e15b6c5170e5d Mon Sep 17 00:00:00 2001 From: Andrej Manduch Date: Thu, 5 Oct 2023 09:29:10 +0200 Subject: [PATCH 0899/1212] fix: align systemd unit file with default IPFS installation path (#10163) (cherry picked from commit 6dbae768180d1f454f4d9d24920be4bc161216b6) --- misc/README.md | 2 +- misc/systemd/ipfs-hardened.service | 4 ++-- misc/systemd/ipfs.service | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/misc/README.md b/misc/README.md index 16abf0441..28511d3fc 100644 --- a/misc/README.md +++ b/misc/README.md @@ -17,7 +17,7 @@ Description=IPFS daemon [Service] # Environment="IPFS_PATH=/data/ipfs" # optional path to ipfs init directory if not default ($HOME/.ipfs) -ExecStart=/usr/bin/ipfs daemon +ExecStart=/usr/local/bin/ipfs daemon Restart=on-failure [Install] diff --git a/misc/systemd/ipfs-hardened.service b/misc/systemd/ipfs-hardened.service index 261b82e2a..785a59829 100644 --- a/misc/systemd/ipfs-hardened.service +++ b/misc/systemd/ipfs-hardened.service @@ -8,7 +8,7 @@ # To overwrite a variable, like ExecStart you have to specify it once # blank and a second time with a new value, like: # ExecStart= -# ExecStart=/usr/bin/ipfs daemon --flag1 --flag2 +# ExecStart=/usr/local/bin/ipfs daemon --flag1 --flag2 # # For more info about custom unit files see systemd.unit(5). @@ -70,7 +70,7 @@ User=ipfs Group=ipfs StateDirectory=ipfs Environment=IPFS_PATH="${HOME}" -ExecStart=/usr/bin/ipfs daemon --init --migrate +ExecStart=/usr/local/bin/ipfs daemon --init --migrate Restart=on-failure KillSignal=SIGINT diff --git a/misc/systemd/ipfs.service b/misc/systemd/ipfs.service index 0051dffdd..ab074e22e 100644 --- a/misc/systemd/ipfs.service +++ b/misc/systemd/ipfs.service @@ -8,7 +8,7 @@ # To overwrite a variable, like ExecStart you have to specify it once # blank and a second time with a new value, like: # ExecStart= -# ExecStart=/usr/bin/ipfs daemon --flag1 --flag2 +# ExecStart=/usr/local/bin/ipfs daemon --flag1 --flag2 # # For more info about custom unit files see systemd.unit(5). @@ -41,7 +41,7 @@ User=ipfs Group=ipfs StateDirectory=ipfs Environment=IPFS_PATH="${HOME}" -ExecStart=/usr/bin/ipfs daemon --init --migrate +ExecStart=/usr/local/bin/ipfs daemon --init --migrate Restart=on-failure KillSignal=SIGINT From c9d1c3bfea0d7936d4aa41264d647ad40c45e308 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Thu, 5 Oct 2023 15:40:42 +0000 Subject: [PATCH 0900/1212] chore: update changelog for v0.23 --- docs/changelogs/v0.23.md | 261 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 261 insertions(+) diff --git a/docs/changelogs/v0.23.md b/docs/changelogs/v0.23.md index 5b7879601..70c1d460a 100644 --- a/docs/changelogs/v0.23.md +++ b/docs/changelogs/v0.23.md @@ -123,4 +123,265 @@ Thx a lot @bmwiedemann for debugging this issue. ### 📝 Changelog +
Full Changelog + +- github.com/ipfs/kubo: + - fix: align systemd unit file with default IPFS installation path (#10163) ([ipfs/kubo#10163](https://github.com/ipfs/kubo/pull/10163)) + - docs: capitalize headers for consistency + - Merge commit '695bf66674931a138862b6fa2cb0b16dc2f6ddd8' into release-v0.23.0 + - chore: update version + - changelog: generalize fuse 9044's entry + - changelog: update fuse 9044's entry + - Update go-unixfsnode to 1.8.0 to fix FUSE + - docs(readme): header improvements (#10144) ([ipfs/kubo#10144](https://github.com/ipfs/kubo/pull/10144)) + - fix(docker): allow nofuse builds for MacOS (#10135) ([ipfs/kubo#10135](https://github.com/ipfs/kubo/pull/10135)) + - docs: fix typos + - docs: s/ipfs dht/amino dht/ + - changelog: mention probelab RFM17.1 dht improvement + - tests: remove sharness ping tests + - perf: make bootstrap saves O(N) + - chore: update go-libp2p-kad-dht + - chore: webui v4.1.1 (#10120) ([ipfs/kubo#10120](https://github.com/ipfs/kubo/pull/10120)) + - core/bootstrap: fix panic without backup bootstrap peer functions (#10029) ([ipfs/kubo#10029](https://github.com/ipfs/kubo/pull/10029)) + - feat: add Gateway.DisableHTMLErrors option (#10137) ([ipfs/kubo#10137](https://github.com/ipfs/kubo/pull/10137)) + - fix(migrations): use dweb.link (#10133) ([ipfs/kubo#10133](https://github.com/ipfs/kubo/pull/10133)) + - docs: add changelog info for QUIC Draft 29 (#10132) ([ipfs/kubo#10132](https://github.com/ipfs/kubo/pull/10132)) + - feat: add gateway to http over libp2p ([ipfs/kubo#10108](https://github.com/ipfs/kubo/pull/10108)) + - migration: update 14-to-15 to v1.0.1 + - chore: update to build with Go 1.21 + - refactor: stop using go-libp2p deprecated peer.ID.Pretty + - docs(readonly): fix typo + - docs(changelog): link to relevant IPIP + - fix: hamt traversal in ipld-explorer (webui@4.1.0) (#10025) ([ipfs/kubo#10025](https://github.com/ipfs/kubo/pull/10025)) + - refactor: if statement (#10105) ([ipfs/kubo#10105](https://github.com/ipfs/kubo/pull/10105)) + - chore: bump repo version to 15 + - docs: remove link to deleted #accelerated-dht-client + - feat(gateway): expose /routing/v1 server (opt-in) (#9877) ([ipfs/kubo#9877](https://github.com/ipfs/kubo/pull/9877)) + - improve error in fuse node failures + - chore: update boxo, go-libp2p, and internalize mplex (#10095) ([ipfs/kubo#10095](https://github.com/ipfs/kubo/pull/10095)) + - dockerfile: reorder copy order for better layer caching + - refactor: using error is instead of == (#10093) ([ipfs/kubo#10093](https://github.com/ipfs/kubo/pull/10093)) + - fix: use %-encoded headers in most compatible way + - fix: open /dev/null with read write permissions + - chore: bump to go 1.20 + - docs(readme): new logo and header + - docker: change to releases that follow debian's updates + - docker: bump debian version to bookworm + - chore: restore exec perms for t0116-gateway-cache.sh and fixtures (#10085) ([ipfs/kubo#10085](https://github.com/ipfs/kubo/pull/10085)) + - fix(gw): useful IPIP-402 CARs on not found errors (#10084) ([ipfs/kubo#10084](https://github.com/ipfs/kubo/pull/10084)) + - feat: add zsh completions (#10040) ([ipfs/kubo#10040](https://github.com/ipfs/kubo/pull/10040)) + - style: remove commented imports [skip changelog] + - style: gofumpt and godot [skip changelog] (#10081) ([ipfs/kubo#10081](https://github.com/ipfs/kubo/pull/10081)) + - chore: bump boxo for verifcid breaking changes + - chore: remove outdated comment (#10077) ([ipfs/kubo#10077](https://github.com/ipfs/kubo/pull/10077)) + - chore: remove deprecated testground plans + - feat: allow users to optin again into mplex + - feat: remove Mplex + - docs(readme): minimal reqs (#10066) ([ipfs/kubo#10066](https://github.com/ipfs/kubo/pull/10066)) + - docs: add v0.23.md + - docs: get ready for v0.23 + - chore: fix link in v0.22 changelog +- github.com/ipfs/boxo (v0.11.0 -> v0.13.1): + - Release v0.13.1 ([ipfs/boxo#469](https://github.com/ipfs/boxo/pull/469)) + - Release v0.13.0 ([ipfs/boxo#465](https://github.com/ipfs/boxo/pull/465)) + - Release v0.12 ([ipfs/boxo#446](https://github.com/ipfs/boxo/pull/446)) +- github.com/ipfs/go-graphsync (v0.14.4 -> v0.15.1): + - v0.15.1 bump + - fix: partial revert of 1be7c1a20; make traverser process identity CIDs + - v0.15.0 bump + - chore: add identity CID parse tests + - fix: traverser should skip over identity CIDs + - fix(ipld): update ipld deps, only slurp LargeBytesNode when matching + - docs(version): update for v0.14.7 + - Handle context cancellation properly (#428) ([ipfs/go-graphsync#428](https://github.com/ipfs/go-graphsync/pull/428)) + - chore(version.json): update for v0.14.6 + - feat: MaxLinks for requests (#420) ([ipfs/go-graphsync#420](https://github.com/ipfs/go-graphsync/pull/420)) + - fix(responsemanager): network disconnect reliability (#425) ([ipfs/go-graphsync#425](https://github.com/ipfs/go-graphsync/pull/425)) + - Update version to reflect latest fixes (#424) ([ipfs/go-graphsync#424](https://github.com/ipfs/go-graphsync/pull/424)) + - Fix shutdown bug in #412 (#422) ([ipfs/go-graphsync#422](https://github.com/ipfs/go-graphsync/pull/422)) +- github.com/ipfs/go-ipfs-cmds (v0.9.0 -> v0.10.0): + - chore: version 0.10.0 + - fix: panic when calling .SetLength for writerResponseEmitter + - fix!: client with raw abs path option + - doc: clarify flag inheritance explanation + - ci: uci/copy-templates ([ipfs/go-ipfs-cmds#242](https://github.com/ipfs/go-ipfs-cmds/pull/242)) + - chore: remove dep on github.com/Kubuxu/go-os-helper +- github.com/ipfs/go-unixfsnode (v1.7.1 -> v1.8.1): + - v1.8.1 bump + - testutil: relax DirEntry usage for non-dag-pb + - v1.8.0 bump + - fix: add cross-impl shard test + - files returned from unixfsnode should be traversable back to their substrate + - fix: better import name + - chore: refactor and add tests with fixtures + - fix: proper tsize encoding in sharded files + - rel 1.7.4 + - Provide path for getting sizes on directory iteration ([ipfs/go-unixfsnode#60](https://github.com/ipfs/go-unixfsnode/pull/60)) + - tag 1.7.3 ([ipfs/go-unixfsnode#57](https://github.com/ipfs/go-unixfsnode/pull/57)) + - Fail to construct preload hamt shards when traversal fails ([ipfs/go-unixfsnode#55](https://github.com/ipfs/go-unixfsnode/pull/55)) + - fix: large files support io.SeekCurrent ([ipfs/go-unixfsnode#56](https://github.com/ipfs/go-unixfsnode/pull/56)) + - chore(version): update version number + - feat: add entity matcher w/o preload, add matcher fn for consuming bytes ([ipfs/go-unixfsnode#52](https://github.com/ipfs/go-unixfsnode/pull/52)) +- github.com/ipld/go-ipld-prime (v0.20.0 -> v0.21.0): + - v0.21.0 release + - fix(selectors): document ranges in slice matcher + - fix(selectors): update ipld/ipld submodule with latest fixtures + - fix(selectors): more permissive with slice "from" underflow + - chore: extract simpleBytes to testutil package + - feat(selectors): negative values for slice matcher's From and To + - chore: extract MultiByteNote to testutil package + - feat(test): add matcher/slice selector test cases + - feat: remove hard-error when slice matcher reaches non-string/bytes node + - fix: cache offsets for sequential reads + - feat: add inline union representation to schema parser + - fix: basic.NewInt returns pointer (like others) + - fix(bindnode): listpairs value assembly handles complex reprs + - fix(bindnode): listpairs repr assembler handles AssignNode + - fix(schema): handle parsing of "listpairs" in the DSL + - fix: remove _skipAbsent labels + - fix: make listpairs repr [[k1,v1],[k2,v2]...] + - feat(bindnode): support listpairs struct representation + - fix(windows,test): avoid "already exists" error on codegen tests for Windows + - Make traversal.WalkTransforming() work + - doc: clean up and expand on traversal pkg docs + - doc: add lots of notes about using the preloader and the budget + - doc: expand on preloader docs + - fix: inline initialPhase() logic for clarity + - feat: preload walk using phase state, call preloader once per link + - fix: handle Budget & SeenLinks + - chore: remove BufferedLoader + - fix: recurse preloader at block level + - fix: Context->PreloadContext for clarity and consistency with LinkContext + - fix: replace ioutil.ReadAll + - fix: fix tooling complaints + - feat: add BufferedLoader + - feat(traversal): allow preloading functionality + - fix: address dodgy test case variable capture + - stop using the deprecated io/ioutil package + - stop using the deprecated io/ioutil package + - stop using the deprecated io/ioutil package + - fix: make StartAtPath work properly for matching walks +- github.com/libp2p/go-libp2p (v0.29.2 -> v0.31.0): + - release v0.31.0 (#2543) ([libp2p/go-libp2p#2543](https://github.com/libp2p/go-libp2p/pull/2543)) + - dashboards: improve naming for black hole panel (#2539) ([libp2p/go-libp2p#2539](https://github.com/libp2p/go-libp2p/pull/2539)) + - reuseport: use DialContext instead of Dial to fail quickly (#2541) ([libp2p/go-libp2p#2541](https://github.com/libp2p/go-libp2p/pull/2541)) + - swarm: track dial cancellation reason (#2532) ([libp2p/go-libp2p#2532](https://github.com/libp2p/go-libp2p/pull/2532)) + - p2p/http: cache json wellknown mappings in the .well-known handler (#2537) ([libp2p/go-libp2p#2537](https://github.com/libp2p/go-libp2p/pull/2537)) + - feat: Implement HTTP spec (#2438) ([libp2p/go-libp2p#2438](https://github.com/libp2p/go-libp2p/pull/2438)) + - move libp2p/go-libp2p-gostream to p2p/net/gostream ([libp2p/go-libp2p#2535](https://github.com/libp2p/go-libp2p/pull/2535)) + - host: disable black hole detection on autonat dialer (#2529) ([libp2p/go-libp2p#2529](https://github.com/libp2p/go-libp2p/pull/2529)) + - identify: disable racy test when running with race detector (#2526) ([libp2p/go-libp2p#2526](https://github.com/libp2p/go-libp2p/pull/2526)) + - swarm: return a more meaningful error when dialing QUIC draft-29 (#2524) ([libp2p/go-libp2p#2524](https://github.com/libp2p/go-libp2p/pull/2524)) + - swarm: fix Unwrap for DialError, implement Unwrap for TransportError (#2437) ([libp2p/go-libp2p#2437](https://github.com/libp2p/go-libp2p/pull/2437)) + - swarm: return errors on filtered addresses when dialing (#2461) ([libp2p/go-libp2p#2461](https://github.com/libp2p/go-libp2p/pull/2461)) + - core: add ErrPeerIDMismatch error type to replace ad-hoc errors (#2451) ([libp2p/go-libp2p#2451](https://github.com/libp2p/go-libp2p/pull/2451)) + - update quic-go to v0.38.1 (#2506) ([libp2p/go-libp2p#2506](https://github.com/libp2p/go-libp2p/pull/2506)) + - quic: don't claim to be able to dial draft-29 in CanDial (#2520) ([libp2p/go-libp2p#2520](https://github.com/libp2p/go-libp2p/pull/2520)) + - examples: update go-libp2p to v0.30.0 (#2507) ([libp2p/go-libp2p#2507](https://github.com/libp2p/go-libp2p/pull/2507)) + - metrics: update dashboard names from libp2p to go-libp2p (#2512) ([libp2p/go-libp2p#2512](https://github.com/libp2p/go-libp2p/pull/2512)) + - chore: be more descriptive about where public dashboards come from (#2508) ([libp2p/go-libp2p#2508](https://github.com/libp2p/go-libp2p/pull/2508)) + - release v0.30.0 (#2505) ([libp2p/go-libp2p#2505](https://github.com/libp2p/go-libp2p/pull/2505)) + - transport tests: add deadline tests (#2286) ([libp2p/go-libp2p#2286](https://github.com/libp2p/go-libp2p/pull/2286)) + - chore: remove unused and outdated package-list.json (#2499) ([libp2p/go-libp2p#2499](https://github.com/libp2p/go-libp2p/pull/2499)) + - muxer: remove support for mplex (#2498) ([libp2p/go-libp2p#2498](https://github.com/libp2p/go-libp2p/pull/2498)) + - transport tests: refactor workers in TestMoreStreamsThanOurLimits (#2472) ([libp2p/go-libp2p#2472](https://github.com/libp2p/go-libp2p/pull/2472)) + - use standard library sha256 implementation for Go 1.21 (#2309) ([libp2p/go-libp2p#2309](https://github.com/libp2p/go-libp2p/pull/2309)) + - quic: update quic-go to v0.37.5 (#2497) ([libp2p/go-libp2p#2497](https://github.com/libp2p/go-libp2p/pull/2497)) + - cleanup: add continue in case of failure in the (*BasicHost).Addrs certhash loop (#2492) ([libp2p/go-libp2p#2492](https://github.com/libp2p/go-libp2p/pull/2492)) + - tests: add a CertHashes testcase in TestInferWebtransportAddrsFromQuic (#2495) ([libp2p/go-libp2p#2495](https://github.com/libp2p/go-libp2p/pull/2495)) + - basichost: use byte representation of WebTransport multiaddr as map key (#2494) ([libp2p/go-libp2p#2494](https://github.com/libp2p/go-libp2p/pull/2494)) + - webtransport: check for UDP multiaddr component in address matcher (#2491) ([libp2p/go-libp2p#2491](https://github.com/libp2p/go-libp2p/pull/2491)) + - swarm: remove unnecessary reqno for pending request tracking (#2460) ([libp2p/go-libp2p#2460](https://github.com/libp2p/go-libp2p/pull/2460)) + - quic: drop support for QUIC draft-29 (#2487) ([libp2p/go-libp2p#2487](https://github.com/libp2p/go-libp2p/pull/2487)) + - metrics: add links to public dashboards (#2486) ([libp2p/go-libp2p#2486](https://github.com/libp2p/go-libp2p/pull/2486)) + - swarm: remove leftover TODO (#2474) ([libp2p/go-libp2p#2474](https://github.com/libp2p/go-libp2p/pull/2474)) + - peerstore: deprecate the database-backed peerstore (#2475) ([libp2p/go-libp2p#2475](https://github.com/libp2p/go-libp2p/pull/2475)) + - identify: fix sorting of observed addresses (#2476) ([libp2p/go-libp2p#2476](https://github.com/libp2p/go-libp2p/pull/2476)) + - update go-multiaddr to v0.11.0 (#2467) ([libp2p/go-libp2p#2467](https://github.com/libp2p/go-libp2p/pull/2467)) + - chore: update golang-lru to v2.0.4, fixing semver violation (#2448) ([libp2p/go-libp2p#2448](https://github.com/libp2p/go-libp2p/pull/2448)) + - swarm: don't open new streams over transient connections (#2450) ([libp2p/go-libp2p#2450](https://github.com/libp2p/go-libp2p/pull/2450)) + - core/crypto: restrict RSA keys to <= 8192 bits (#2454) ([libp2p/go-libp2p#2454](https://github.com/libp2p/go-libp2p/pull/2454)) + - chore: add notable project requirement (#2453) ([libp2p/go-libp2p#2453](https://github.com/libp2p/go-libp2p/pull/2453)) + - examples: update go-libp2p to v0.29.0 (#2432) ([libp2p/go-libp2p#2432](https://github.com/libp2p/go-libp2p/pull/2432)) + - examples: fix description of command line flags for pubsub (#2400) ([libp2p/go-libp2p#2400](https://github.com/libp2p/go-libp2p/pull/2400)) + - basichost: remove invalid comment (#2435) ([libp2p/go-libp2p#2435](https://github.com/libp2p/go-libp2p/pull/2435)) +- github.com/libp2p/go-libp2p-kad-dht (v0.24.2 -> v0.24.4): + - Make v0.24.4 ([libp2p/go-libp2p-kad-dht#931](https://github.com/libp2p/go-libp2p-kad-dht/pull/931)) +- github.com/libp2p/go-libp2p-routing-helpers (v0.7.1 -> v0.7.3): + - chore: release v0.7.3 + - nit: invert if + - fix: for getValueOrErrorParallel do not return values if they come with errors + - test: add test to make sure we return not found when we get errors back with values + - chore: release v0.7.2 + - tracing: do not leak goroutines when the context is canceled + - tracing: allow for reuse of the tracing + - tracing: add tracing to compose parallel's worker + - tests: add more tests + - tests: mark all tests Parallel + - tracing: add highlevel APIs records on the composable routers +- github.com/libp2p/go-reuseport (v0.3.0 -> v0.4.0): + - release v0.4.0 (#111) ([libp2p/go-reuseport#111](https://github.com/libp2p/go-reuseport/pull/111)) + - use SO_REUSEPORT_LB on FreeBSD (#106) ([libp2p/go-reuseport#106](https://github.com/libp2p/go-reuseport/pull/106)) +- github.com/multiformats/go-multiaddr (v0.10.1 -> v0.11.0): + - release v0.11.0 (#214) ([multiformats/go-multiaddr#214](https://github.com/multiformats/go-multiaddr/pull/214)) + - update golang.org/x/exp slice comparison to match standard library version (#210) ([multiformats/go-multiaddr#210](https://github.com/multiformats/go-multiaddr/pull/210)) +- github.com/warpfork/go-testmark (v0.11.0 -> v0.12.1): + - suite: allow disabling file parallelism. + - Suite feature ([warpfork/go-testmark#16](https://github.com/warpfork/go-testmark/pull/16)) + - fix unchecked error in a test + - accept a simplification suggestion from linters + - Trailing whitespace error ([warpfork/go-testmark#15](https://github.com/warpfork/go-testmark/pull/15)) + - FS implementation (#11) ([warpfork/go-testmark#11](https://github.com/warpfork/go-testmark/pull/11)) + - Add a readme for the testexec extension and its conventions. ([warpfork/go-testmark#14](https://github.com/warpfork/go-testmark/pull/14)) + - Strict mode for testexec structure ([warpfork/go-testmark#12](https://github.com/warpfork/go-testmark/pull/12)) + +
+ ### 👨‍👩‍👧‍👦 Contributors + +| Contributor | Commits | Lines ± | Files Changed | +|-------------|---------|---------|---------------| +| Rod Vagg | 48 | +3578/-1789 | 110 | +| Henrique Dias | 24 | +3173/-1128 | 104 | +| Jorropo | 51 | +1721/-1297 | 252 | +| Marco Munizaga | 6 | +1989/-505 | 39 | +| Kay | 3 | +487/-474 | 163 | +| hannahhoward | 8 | +626/-136 | 23 | +| Calvin Behling | 6 | +496/-259 | 20 | +| Eric Myhre | 9 | +610/-121 | 16 | +| Adin Schmahmann | 17 | +659/-45 | 35 | +| Marten Seemann | 17 | +218/-477 | 119 | +| Sukun | 11 | +481/-174 | 29 | +| CJB | 1 | +639/-2 | 5 | +| Hector Sanjuan | 10 | +450/-127 | 21 | +| Wondertan | 2 | +203/-127 | 8 | +| Marcin Rataj | 11 | +148/-86 | 18 | +| Andrew Gillis | 2 | +163/-14 | 5 | +| P. Reis | 3 | +120/-4 | 4 | +| Will Scott | 4 | +107/-12 | 6 | +| Amir Mohammad Fakhimi | 1 | +97/-2 | 5 | +| Ed Schouten | 1 | +55/-7 | 2 | +| Icarus9913 | 1 | +30/-30 | 18 | +| Dirk McCormick | 1 | +3/-42 | 1 | +| Raúl Kripalani | 1 | +20/-18 | 4 | +| Michael Muré | 1 | +26/-7 | 5 | +| Prem Chaitanya Prathi | 1 | +28/-1 | 2 | +| ShengTao | 1 | +13/-14 | 4 | +| Prithvi Shahi | 3 | +14/-13 | 3 | +| web3-bot | 5 | +12/-10 | 9 | +| Alejandro Criado-Pérez | 1 | +11/-11 | 6 | +| Steven Allen | 2 | +6/-10 | 2 | +| Andrej Manduch | 1 | +5/-5 | 3 | +| Russell Dempsey | 2 | +4/-2 | 2 | +| Johannes Maria Frank | 1 | +4/-1 | 1 | +| downIoads | 1 | +2/-2 | 1 | +| Will | 2 | +2/-2 | 2 | +| Marin Kirkov | 1 | +2/-2 | 2 | +| Gus Eggert | 1 | +2/-2 | 1 | +| Bernhard M. Wiedemann | 1 | +4/-0 | 1 | +| Dennis Trautwein | 1 | +1/-2 | 1 | +| “GheisMohammadi” | 1 | +1/-1 | 1 | +| cce | 1 | +1/-1 | 1 | +| Joao Andrade | 1 | +1/-1 | 1 | +| guillaumemichel | 1 | +1/-0 | 1 | +| Santiago Botto | 1 | +0/-1 | 1 | From ecda7ae2f59eb7c7afd15107fb433f2e681738ec Mon Sep 17 00:00:00 2001 From: Jorropo Date: Thu, 5 Oct 2023 20:53:38 +0200 Subject: [PATCH 0901/1212] chore: update deps I only updated otel to 1.17.0 since we need to handle breaking changes with newer releases (it doesn't build). I also didn't update go-multistream since it's touched by libp2p and break stuff. --- docs/examples/kubo-as-a-library/go.mod | 34 ++++++------ docs/examples/kubo-as-a-library/go.sum | 68 ++++++++++++------------ go.mod | 36 ++++++------- go.sum | 72 +++++++++++++------------- test/dependencies/go.mod | 36 ++++++------- test/dependencies/go.sum | 72 +++++++++++++------------- 6 files changed, 159 insertions(+), 159 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index a465c7cc6..ec52691ea 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -51,18 +51,18 @@ require ( github.com/golang/snappy v0.0.4 // indirect github.com/google/gopacket v1.1.19 // indirect github.com/google/pprof v0.0.0-20230821062121-407c9e7a662f // indirect - github.com/google/uuid v1.3.0 // indirect + github.com/google/uuid v1.3.1 // indirect github.com/gorilla/websocket v1.5.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 // indirect github.com/hannahhoward/go-pubsub v0.0.0-20200423002714-8d62886cc36e // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/golang-lru v0.5.4 // indirect - github.com/hashicorp/golang-lru/v2 v2.0.5 // indirect + github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/huin/goupnp v1.2.0 // indirect github.com/ipfs/bbloom v0.0.4 // indirect github.com/ipfs/go-bitfield v1.1.0 // indirect - github.com/ipfs/go-block-format v0.1.2 // indirect + github.com/ipfs/go-block-format v0.2.0 // indirect github.com/ipfs/go-cid v0.4.1 // indirect github.com/ipfs/go-cidutil v0.1.0 // indirect github.com/ipfs/go-datastore v0.6.0 // indirect @@ -80,7 +80,7 @@ require ( github.com/ipfs/go-ipfs-redirects-file v0.1.1 // indirect github.com/ipfs/go-ipfs-util v0.0.3 // indirect github.com/ipfs/go-ipld-cbor v0.0.6 // indirect - github.com/ipfs/go-ipld-format v0.5.0 // indirect + github.com/ipfs/go-ipld-format v0.6.0 // indirect github.com/ipfs/go-ipld-git v0.1.1 // indirect github.com/ipfs/go-ipld-legacy v0.2.1 // indirect github.com/ipfs/go-log v1.0.5 // indirect @@ -142,10 +142,10 @@ require ( github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/polydawn/refmt v0.89.0 // indirect - github.com/prometheus/client_golang v1.16.0 // indirect - github.com/prometheus/client_model v0.4.0 // indirect + github.com/prometheus/client_golang v1.17.0 // indirect + github.com/prometheus/client_model v0.5.0 // indirect github.com/prometheus/common v0.44.0 // indirect - github.com/prometheus/procfs v0.11.1 // indirect + github.com/prometheus/procfs v0.12.0 // indirect github.com/quic-go/qpack v0.4.0 // indirect github.com/quic-go/qtls-go1-20 v0.3.3 // indirect github.com/quic-go/quic-go v0.38.1 // indirect @@ -162,7 +162,7 @@ require ( github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 // indirect go.opencensus.io v0.24.0 // indirect - go.opentelemetry.io/otel v1.16.0 // indirect + go.opentelemetry.io/otel v1.17.0 // indirect go.opentelemetry.io/otel/exporters/jaeger v1.14.0 // indirect go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.16.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.16.0 // indirect @@ -170,24 +170,24 @@ require ( go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.16.0 // indirect go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.14.0 // indirect go.opentelemetry.io/otel/exporters/zipkin v1.14.0 // indirect - go.opentelemetry.io/otel/metric v1.16.0 // indirect + go.opentelemetry.io/otel/metric v1.17.0 // indirect go.opentelemetry.io/otel/sdk v1.16.0 // indirect - go.opentelemetry.io/otel/trace v1.16.0 // indirect + go.opentelemetry.io/otel/trace v1.17.0 // indirect go.opentelemetry.io/proto/otlp v0.19.0 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/dig v1.17.0 // indirect go.uber.org/fx v1.20.0 // indirect go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap v1.25.0 // indirect + go.uber.org/zap v1.26.0 // indirect go4.org v0.0.0-20230225012048-214862532bf5 // indirect - golang.org/x/crypto v0.12.0 // indirect - golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 // indirect + golang.org/x/crypto v0.14.0 // indirect + golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect golang.org/x/mod v0.12.0 // indirect - golang.org/x/net v0.14.0 // indirect + golang.org/x/net v0.15.0 // indirect golang.org/x/sync v0.3.0 // indirect - golang.org/x/sys v0.11.0 // indirect - golang.org/x/text v0.12.0 // indirect - golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 // indirect + golang.org/x/sys v0.13.0 // indirect + golang.org/x/text v0.13.0 // indirect + golang.org/x/tools v0.13.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect gonum.org/v1/gonum v0.13.0 // indirect google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index c35386932..9813cb922 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -261,8 +261,8 @@ github.com/google/pprof v0.0.0-20230821062121-407c9e7a662f/go.mod h1:czg5+yv1E0Z github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= +github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= @@ -290,8 +290,8 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= -github.com/hashicorp/golang-lru/v2 v2.0.5 h1:wW7h1TG88eUIJ2i69gaE3uNVtEPIagzhGvHgwfx2Vm4= -github.com/hashicorp/golang-lru/v2 v2.0.5/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= +github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= +github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huin/goupnp v1.2.0 h1:uOKW26NG1hsSSbXIZ1IR7XP9Gjd1U8pnLaCMgntmkmY= @@ -306,8 +306,8 @@ github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbG github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= github.com/ipfs/go-block-format v0.0.3/go.mod h1:4LmD4ZUw0mhO+JSKdpWwrzATiEfM7WWgQ8H5l6P8MVk= -github.com/ipfs/go-block-format v0.1.2 h1:GAjkfhVx1f4YTODS6Esrj1wt2HhrtwTnhEr+DyPUaJo= -github.com/ipfs/go-block-format v0.1.2/go.mod h1:mACVcrxarQKstUU3Yf/RdwbC4DzPV6++rO2a3d+a/KE= +github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs= +github.com/ipfs/go-block-format v0.2.0/go.mod h1:+jpL11nFx5A/SPpsoBn6Bzkra/zaArfSmsknbPMYgzM= github.com/ipfs/go-blockservice v0.5.0 h1:B2mwhhhVQl2ntW2EIpaWPwSCxSuqr5fFA93Ms4bYLEY= github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.3/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= @@ -365,8 +365,8 @@ github.com/ipfs/go-ipfs-util v0.0.3/go.mod h1:LHzG1a0Ig4G+iZ26UUOMjHd+lfM84LZCrn github.com/ipfs/go-ipld-cbor v0.0.6 h1:pYuWHyvSpIsOOLw4Jy7NbBkCyzLDcl64Bf/LZW7eBQ0= github.com/ipfs/go-ipld-cbor v0.0.6/go.mod h1:ssdxxaLJPXH7OjF5V4NSjBbcfh+evoR4ukuru0oPXMA= github.com/ipfs/go-ipld-format v0.0.1/go.mod h1:kyJtbkDALmFHv3QR6et67i35QzO3S0dCDnkOJhcZkms= -github.com/ipfs/go-ipld-format v0.5.0 h1:WyEle9K96MSrvr47zZHKKcDxJ/vlpET6PSiQsAFO+Ds= -github.com/ipfs/go-ipld-format v0.5.0/go.mod h1:ImdZqJQaEouMjCvqCe0ORUS+uoBmf7Hf+EO/jh+nk3M= +github.com/ipfs/go-ipld-format v0.6.0 h1:VEJlA2kQ3LqFSIm5Vu6eIlSxD/Ze90xtc4Meten1F5U= +github.com/ipfs/go-ipld-format v0.6.0/go.mod h1:g4QVMTn3marU3qXchwjpKPKgJv+zF+OlaKMyhJ4LHPg= github.com/ipfs/go-ipld-git v0.1.1 h1:TWGnZjS0htmEmlMFEkA3ogrNCqWjIxwr16x1OsdhG+Y= github.com/ipfs/go-ipld-git v0.1.1/go.mod h1:+VyMqF5lMcJh4rwEppV0e6g4nCCHXThLYYDpKUkJubI= github.com/ipfs/go-ipld-legacy v0.2.1 h1:mDFtrBpmU7b//LzLSypVrXsD8QxkEWxu5qVxN99/+tk= @@ -624,18 +624,18 @@ github.com/polydawn/refmt v0.0.0-20201211092308-30ac6d18308e/go.mod h1:uIp+gprXx github.com/polydawn/refmt v0.89.0 h1:ADJTApkvkeBZsN0tBTx8QjpD9JkmxbKp0cxfr9qszm4= github.com/polydawn/refmt v0.89.0/go.mod h1:/zvteZs/GwLtCgZ4BL6CBsk9IKIlexP43ObX9AxTqTw= github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8= -github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc= +github.com/prometheus/client_golang v1.17.0 h1:rl2sfwZMtSthVU752MqfjQozy7blglC+1SOtjMAMh+Q= +github.com/prometheus/client_golang v1.17.0/go.mod h1:VeL+gMmOAxkS2IqfCq0ZmHSL+LjWfWDUmp1mBz9JgUY= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY= -github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= +github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= +github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY= github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.11.1 h1:xRC8Iq1yyca5ypa9n1EZnWZkt7dwcoRPQwX/5gwaUuI= -github.com/prometheus/procfs v0.11.1/go.mod h1:eesXgaPo1q7lBpVMoMy0ZOFTth9hBn4W/y0/p/ScXhY= +github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= +github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= github.com/quic-go/qtls-go1-20 v0.3.3 h1:17/glZSLI9P9fDAeyCHBFSWSqJcwx1byhLwP5eUIDCM= @@ -771,8 +771,8 @@ go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/otel v1.16.0 h1:Z7GVAX/UkAXPKsy94IU+i6thsQS4nb7LviLpnaNeW8s= -go.opentelemetry.io/otel v1.16.0/go.mod h1:vl0h9NUa1D5s1nv3A5vZOYWn8av4K8Ml6JDeHrT/bx4= +go.opentelemetry.io/otel v1.17.0 h1:MW+phZ6WZ5/uk2nd93ANk/6yJ+dVrvNWUjGhnnFU5jM= +go.opentelemetry.io/otel v1.17.0/go.mod h1:I2vmBGtFaODIVMBSTPVDlJSzBDNf93k60E6Ft0nyjo0= go.opentelemetry.io/otel/exporters/jaeger v1.14.0 h1:CjbUNd4iN2hHmWekmOqZ+zSCU+dzZppG8XsV+A3oc8Q= go.opentelemetry.io/otel/exporters/jaeger v1.14.0/go.mod h1:4Ay9kk5vELRrbg5z4cpP9EtmQRFap2Wb0woPG4lujZA= go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.16.0 h1:t4ZwRPU+emrcvM2e9DHd0Fsf0JTPVcbfa/BhTDF03d0= @@ -787,12 +787,12 @@ go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.14.0 h1:sEL90JjOO/4yhqu go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.14.0/go.mod h1:oCslUcizYdpKYyS9e8srZEqM6BB8fq41VJBjLAE6z1w= go.opentelemetry.io/otel/exporters/zipkin v1.14.0 h1:reEVE1upBF9tcujgvSqLJS0SrI7JQPaTKP4s4rymnSs= go.opentelemetry.io/otel/exporters/zipkin v1.14.0/go.mod h1:RcjvOAcvhzcufQP8aHmzRw1gE9g/VEZufDdo2w+s4sk= -go.opentelemetry.io/otel/metric v1.16.0 h1:RbrpwVG1Hfv85LgnZ7+txXioPDoh6EdbZHo26Q3hqOo= -go.opentelemetry.io/otel/metric v1.16.0/go.mod h1:QE47cpOmkwipPiefDwo2wDzwJrlfxxNYodqc4xnGCo4= +go.opentelemetry.io/otel/metric v1.17.0 h1:iG6LGVz5Gh+IuO0jmgvpTB6YVrCGngi8QGm+pMd8Pdc= +go.opentelemetry.io/otel/metric v1.17.0/go.mod h1:h4skoxdZI17AxwITdmdZjjYJQH5nzijUUjm+wtPph5o= go.opentelemetry.io/otel/sdk v1.16.0 h1:Z1Ok1YsijYL0CSJpHt4cS3wDDh7p572grzNrBMiMWgE= go.opentelemetry.io/otel/sdk v1.16.0/go.mod h1:tMsIuKXuuIWPBAOrH+eHtvhTL+SntFtXF9QD68aP6p4= -go.opentelemetry.io/otel/trace v1.16.0 h1:8JRpaObFoW0pxuVPapkgH8UhHQj+bJW8jJsCZEu5MQs= -go.opentelemetry.io/otel/trace v1.16.0/go.mod h1:Yt9vYq1SdNz3xdjZZK7wcXv1qv2pwLkqr2QVwea0ef0= +go.opentelemetry.io/otel/trace v1.17.0 h1:/SWhSRHmDPOImIAetP1QAeMnZYiQXrTy4fMMYOdSKWQ= +go.opentelemetry.io/otel/trace v1.17.0/go.mod h1:I/4vKTgFclIsXRVucpH25X0mpFSczM7aHeaz0ZBLWjY= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.opentelemetry.io/proto/otlp v0.19.0 h1:IVN6GR+mhC4s5yfcTbmzHYODqvWAp3ZedA2SJPI1Nnw= go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= @@ -817,8 +817,8 @@ go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.14.1/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= -go.uber.org/zap v1.25.0 h1:4Hvk6GtkucQ790dqmj7l1eEnRdKm3k3ZUrUMS2d5+5c= -go.uber.org/zap v1.25.0/go.mod h1:JIAUzQIH94IC4fOJQm7gMmBJP5k7wQfdcnYdPoEXJYk= +go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= +go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= go4.org v0.0.0-20200411211856-f5505b9728dd/go.mod h1:CIiUVy99QCPfoE13bO4EZaz5GZMZXMSBGhxRdsvzbkg= go4.org v0.0.0-20230225012048-214862532bf5 h1:nifaUDeh+rPaBCMPMQHZmvJf+QdpLFnuQPwx+LxVmtc= @@ -840,8 +840,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk= -golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= +golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= +golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -852,8 +852,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 h1:m64FZMko/V45gv0bNmrNYoDEq8U5YUhetc9cBWKS1TQ= -golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63/go.mod h1:0v4NqG35kSWCMzLaMeX+IQrlSnVE/bqGSyC2cz/9Le8= +golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g= +golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -921,8 +921,8 @@ golang.org/x/net v0.0.0-20210423184538-5f58ad60dda6/go.mod h1:OJAsFXCWl8Ukc7SiCT golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14= -golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= +golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8= +golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1003,8 +1003,8 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= -golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -1018,8 +1018,8 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc= -golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1077,8 +1077,8 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 h1:Vve/L0v7CXXuxUmaMGIEK/dEeq7uiqb5qBgQrZzIE7E= -golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM= +golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ= +golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/go.mod b/go.mod index e9280f996..aab31f8b5 100644 --- a/go.mod +++ b/go.mod @@ -13,10 +13,10 @@ require ( github.com/elgris/jsondiff v0.0.0-20160530203242-765b5c24c302 github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5 github.com/fsnotify/fsnotify v1.6.0 - github.com/google/uuid v1.3.0 + github.com/google/uuid v1.3.1 github.com/hashicorp/go-multierror v1.1.1 github.com/ipfs/boxo v0.13.2-0.20231002142647-c28c847582f0 - github.com/ipfs/go-block-format v0.1.2 + github.com/ipfs/go-block-format v0.2.0 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 github.com/ipfs/go-datastore v0.6.0 @@ -28,7 +28,7 @@ require ( github.com/ipfs/go-fs-lock v0.0.7 github.com/ipfs/go-graphsync v0.15.1 github.com/ipfs/go-ipfs-cmds v0.10.0 - github.com/ipfs/go-ipld-format v0.5.0 + github.com/ipfs/go-ipld-format v0.6.0 github.com/ipfs/go-ipld-git v0.1.1 github.com/ipfs/go-ipld-legacy v0.2.1 github.com/ipfs/go-log v1.0.5 @@ -65,7 +65,7 @@ require ( github.com/opentracing/opentracing-go v1.2.0 github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 github.com/pkg/errors v0.9.1 - github.com/prometheus/client_golang v1.16.0 + github.com/prometheus/client_golang v1.17.0 github.com/stretchr/testify v1.8.4 github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 github.com/tidwall/gjson v1.14.4 @@ -75,18 +75,18 @@ require ( go.opencensus.io v0.24.0 go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.42.0 go.opentelemetry.io/contrib/propagators/autoprop v0.42.0 - go.opentelemetry.io/otel v1.16.0 + go.opentelemetry.io/otel v1.17.0 go.opentelemetry.io/otel/sdk v1.16.0 - go.opentelemetry.io/otel/trace v1.16.0 + go.opentelemetry.io/otel/trace v1.17.0 go.uber.org/dig v1.17.0 go.uber.org/fx v1.20.0 go.uber.org/multierr v1.11.0 - go.uber.org/zap v1.25.0 - golang.org/x/crypto v0.12.0 - golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 + go.uber.org/zap v1.26.0 + golang.org/x/crypto v0.14.0 + golang.org/x/exp v0.0.0-20230905200255-921286631fa9 golang.org/x/mod v0.12.0 golang.org/x/sync v0.3.0 - golang.org/x/sys v0.11.0 + golang.org/x/sys v0.13.0 google.golang.org/protobuf v1.31.0 ) @@ -131,7 +131,7 @@ require ( github.com/hannahhoward/go-pubsub v0.0.0-20200423002714-8d62886cc36e // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/golang-lru v0.5.4 // indirect - github.com/hashicorp/golang-lru/v2 v2.0.5 // indirect + github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/huin/goupnp v1.2.0 // indirect github.com/ipfs/bbloom v0.0.4 // indirect github.com/ipfs/go-bitfield v1.1.0 // indirect @@ -186,9 +186,9 @@ require ( github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/polydawn/refmt v0.89.0 // indirect - github.com/prometheus/client_model v0.4.0 // indirect + github.com/prometheus/client_model v0.5.0 // indirect github.com/prometheus/common v0.44.0 // indirect - github.com/prometheus/procfs v0.11.1 // indirect + github.com/prometheus/procfs v0.12.0 // indirect github.com/prometheus/statsd_exporter v0.22.7 // indirect github.com/quic-go/qpack v0.4.0 // indirect github.com/quic-go/qtls-go1-20 v0.3.3 // indirect @@ -218,15 +218,15 @@ require ( go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.16.0 // indirect go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.14.0 // indirect go.opentelemetry.io/otel/exporters/zipkin v1.14.0 // indirect - go.opentelemetry.io/otel/metric v1.16.0 // indirect + go.opentelemetry.io/otel/metric v1.17.0 // indirect go.opentelemetry.io/proto/otlp v0.19.0 // indirect go.uber.org/atomic v1.11.0 // indirect go4.org v0.0.0-20230225012048-214862532bf5 // indirect - golang.org/x/net v0.14.0 // indirect + golang.org/x/net v0.15.0 // indirect golang.org/x/oauth2 v0.8.0 // indirect - golang.org/x/term v0.11.0 // indirect - golang.org/x/text v0.12.0 // indirect - golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 // indirect + golang.org/x/term v0.13.0 // indirect + golang.org/x/text v0.13.0 // indirect + golang.org/x/tools v0.13.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect gonum.org/v1/gonum v0.13.0 // indirect google.golang.org/appengine v1.6.7 // indirect diff --git a/go.sum b/go.sum index 441c156ae..33bccc877 100644 --- a/go.sum +++ b/go.sum @@ -295,8 +295,8 @@ github.com/google/pprof v0.0.0-20230821062121-407c9e7a662f/go.mod h1:czg5+yv1E0Z github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= +github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= @@ -325,8 +325,8 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= -github.com/hashicorp/golang-lru/v2 v2.0.5 h1:wW7h1TG88eUIJ2i69gaE3uNVtEPIagzhGvHgwfx2Vm4= -github.com/hashicorp/golang-lru/v2 v2.0.5/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= +github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= +github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huin/goupnp v1.2.0 h1:uOKW26NG1hsSSbXIZ1IR7XP9Gjd1U8pnLaCMgntmkmY= @@ -342,8 +342,8 @@ github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= github.com/ipfs/go-block-format v0.0.3/go.mod h1:4LmD4ZUw0mhO+JSKdpWwrzATiEfM7WWgQ8H5l6P8MVk= -github.com/ipfs/go-block-format v0.1.2 h1:GAjkfhVx1f4YTODS6Esrj1wt2HhrtwTnhEr+DyPUaJo= -github.com/ipfs/go-block-format v0.1.2/go.mod h1:mACVcrxarQKstUU3Yf/RdwbC4DzPV6++rO2a3d+a/KE= +github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs= +github.com/ipfs/go-block-format v0.2.0/go.mod h1:+jpL11nFx5A/SPpsoBn6Bzkra/zaArfSmsknbPMYgzM= github.com/ipfs/go-blockservice v0.5.0 h1:B2mwhhhVQl2ntW2EIpaWPwSCxSuqr5fFA93Ms4bYLEY= github.com/ipfs/go-blockservice v0.5.0/go.mod h1:W6brZ5k20AehbmERplmERn8o2Ni3ZZubvAxaIUeaT6w= github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= @@ -405,8 +405,8 @@ github.com/ipfs/go-ipfs-util v0.0.3/go.mod h1:LHzG1a0Ig4G+iZ26UUOMjHd+lfM84LZCrn github.com/ipfs/go-ipld-cbor v0.0.6 h1:pYuWHyvSpIsOOLw4Jy7NbBkCyzLDcl64Bf/LZW7eBQ0= github.com/ipfs/go-ipld-cbor v0.0.6/go.mod h1:ssdxxaLJPXH7OjF5V4NSjBbcfh+evoR4ukuru0oPXMA= github.com/ipfs/go-ipld-format v0.0.1/go.mod h1:kyJtbkDALmFHv3QR6et67i35QzO3S0dCDnkOJhcZkms= -github.com/ipfs/go-ipld-format v0.5.0 h1:WyEle9K96MSrvr47zZHKKcDxJ/vlpET6PSiQsAFO+Ds= -github.com/ipfs/go-ipld-format v0.5.0/go.mod h1:ImdZqJQaEouMjCvqCe0ORUS+uoBmf7Hf+EO/jh+nk3M= +github.com/ipfs/go-ipld-format v0.6.0 h1:VEJlA2kQ3LqFSIm5Vu6eIlSxD/Ze90xtc4Meten1F5U= +github.com/ipfs/go-ipld-format v0.6.0/go.mod h1:g4QVMTn3marU3qXchwjpKPKgJv+zF+OlaKMyhJ4LHPg= github.com/ipfs/go-ipld-git v0.1.1 h1:TWGnZjS0htmEmlMFEkA3ogrNCqWjIxwr16x1OsdhG+Y= github.com/ipfs/go-ipld-git v0.1.1/go.mod h1:+VyMqF5lMcJh4rwEppV0e6g4nCCHXThLYYDpKUkJubI= github.com/ipfs/go-ipld-legacy v0.2.1 h1:mDFtrBpmU7b//LzLSypVrXsD8QxkEWxu5qVxN99/+tk= @@ -712,14 +712,14 @@ github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqr github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_golang v1.12.2/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_golang v1.13.0/go.mod h1:vTeo+zgvILHsnnj/39Ou/1fPN5nJFOEMgftOUOmlvYQ= -github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8= -github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc= +github.com/prometheus/client_golang v1.17.0 h1:rl2sfwZMtSthVU752MqfjQozy7blglC+1SOtjMAMh+Q= +github.com/prometheus/client_golang v1.17.0/go.mod h1:VeL+gMmOAxkS2IqfCq0ZmHSL+LjWfWDUmp1mBz9JgUY= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY= -github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= +github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= +github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= @@ -738,8 +738,8 @@ github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4O github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= -github.com/prometheus/procfs v0.11.1 h1:xRC8Iq1yyca5ypa9n1EZnWZkt7dwcoRPQwX/5gwaUuI= -github.com/prometheus/procfs v0.11.1/go.mod h1:eesXgaPo1q7lBpVMoMy0ZOFTth9hBn4W/y0/p/ScXhY= +github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= +github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= github.com/prometheus/statsd_exporter v0.22.7 h1:7Pji/i2GuhK6Lu7DHrtTkFmNBCudCPT1pX2CziuyQR0= github.com/prometheus/statsd_exporter v0.22.7/go.mod h1:N/TevpjkIh9ccs6nuzY3jQn9dFqnUakOjnEuMPJJJnI= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= @@ -909,8 +909,8 @@ go.opentelemetry.io/contrib/propagators/jaeger v1.17.0 h1:Zbpbmwav32Ea5jSotpmkWE go.opentelemetry.io/contrib/propagators/jaeger v1.17.0/go.mod h1:tcTUAlmO8nuInPDSBVfG+CP6Mzjy5+gNV4mPxMbL0IA= go.opentelemetry.io/contrib/propagators/ot v1.17.0 h1:ufo2Vsz8l76eI47jFjuVyjyB3Ae2DmfiCV/o6Vc8ii0= go.opentelemetry.io/contrib/propagators/ot v1.17.0/go.mod h1:SbKPj5XGp8K/sGm05XblaIABgMgw2jDczP8gGeuaVLk= -go.opentelemetry.io/otel v1.16.0 h1:Z7GVAX/UkAXPKsy94IU+i6thsQS4nb7LviLpnaNeW8s= -go.opentelemetry.io/otel v1.16.0/go.mod h1:vl0h9NUa1D5s1nv3A5vZOYWn8av4K8Ml6JDeHrT/bx4= +go.opentelemetry.io/otel v1.17.0 h1:MW+phZ6WZ5/uk2nd93ANk/6yJ+dVrvNWUjGhnnFU5jM= +go.opentelemetry.io/otel v1.17.0/go.mod h1:I2vmBGtFaODIVMBSTPVDlJSzBDNf93k60E6Ft0nyjo0= go.opentelemetry.io/otel/exporters/jaeger v1.14.0 h1:CjbUNd4iN2hHmWekmOqZ+zSCU+dzZppG8XsV+A3oc8Q= go.opentelemetry.io/otel/exporters/jaeger v1.14.0/go.mod h1:4Ay9kk5vELRrbg5z4cpP9EtmQRFap2Wb0woPG4lujZA= go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.16.0 h1:t4ZwRPU+emrcvM2e9DHd0Fsf0JTPVcbfa/BhTDF03d0= @@ -925,12 +925,12 @@ go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.14.0 h1:sEL90JjOO/4yhqu go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.14.0/go.mod h1:oCslUcizYdpKYyS9e8srZEqM6BB8fq41VJBjLAE6z1w= go.opentelemetry.io/otel/exporters/zipkin v1.14.0 h1:reEVE1upBF9tcujgvSqLJS0SrI7JQPaTKP4s4rymnSs= go.opentelemetry.io/otel/exporters/zipkin v1.14.0/go.mod h1:RcjvOAcvhzcufQP8aHmzRw1gE9g/VEZufDdo2w+s4sk= -go.opentelemetry.io/otel/metric v1.16.0 h1:RbrpwVG1Hfv85LgnZ7+txXioPDoh6EdbZHo26Q3hqOo= -go.opentelemetry.io/otel/metric v1.16.0/go.mod h1:QE47cpOmkwipPiefDwo2wDzwJrlfxxNYodqc4xnGCo4= +go.opentelemetry.io/otel/metric v1.17.0 h1:iG6LGVz5Gh+IuO0jmgvpTB6YVrCGngi8QGm+pMd8Pdc= +go.opentelemetry.io/otel/metric v1.17.0/go.mod h1:h4skoxdZI17AxwITdmdZjjYJQH5nzijUUjm+wtPph5o= go.opentelemetry.io/otel/sdk v1.16.0 h1:Z1Ok1YsijYL0CSJpHt4cS3wDDh7p572grzNrBMiMWgE= go.opentelemetry.io/otel/sdk v1.16.0/go.mod h1:tMsIuKXuuIWPBAOrH+eHtvhTL+SntFtXF9QD68aP6p4= -go.opentelemetry.io/otel/trace v1.16.0 h1:8JRpaObFoW0pxuVPapkgH8UhHQj+bJW8jJsCZEu5MQs= -go.opentelemetry.io/otel/trace v1.16.0/go.mod h1:Yt9vYq1SdNz3xdjZZK7wcXv1qv2pwLkqr2QVwea0ef0= +go.opentelemetry.io/otel/trace v1.17.0 h1:/SWhSRHmDPOImIAetP1QAeMnZYiQXrTy4fMMYOdSKWQ= +go.opentelemetry.io/otel/trace v1.17.0/go.mod h1:I/4vKTgFclIsXRVucpH25X0mpFSczM7aHeaz0ZBLWjY= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.opentelemetry.io/proto/otlp v0.19.0 h1:IVN6GR+mhC4s5yfcTbmzHYODqvWAp3ZedA2SJPI1Nnw= go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= @@ -955,8 +955,8 @@ go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.14.1/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= -go.uber.org/zap v1.25.0 h1:4Hvk6GtkucQ790dqmj7l1eEnRdKm3k3ZUrUMS2d5+5c= -go.uber.org/zap v1.25.0/go.mod h1:JIAUzQIH94IC4fOJQm7gMmBJP5k7wQfdcnYdPoEXJYk= +go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= +go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= go4.org v0.0.0-20200411211856-f5505b9728dd/go.mod h1:CIiUVy99QCPfoE13bO4EZaz5GZMZXMSBGhxRdsvzbkg= go4.org v0.0.0-20230225012048-214862532bf5 h1:nifaUDeh+rPaBCMPMQHZmvJf+QdpLFnuQPwx+LxVmtc= @@ -978,8 +978,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk= -golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= +golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= +golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -990,8 +990,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 h1:m64FZMko/V45gv0bNmrNYoDEq8U5YUhetc9cBWKS1TQ= -golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63/go.mod h1:0v4NqG35kSWCMzLaMeX+IQrlSnVE/bqGSyC2cz/9Le8= +golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g= +golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1065,8 +1065,8 @@ golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14= -golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= +golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8= +golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1164,14 +1164,14 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= -golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.11.0 h1:F9tnn/DA/Im8nCwm+fX+1/eBwi4qFjRT++MhtVC4ZX0= -golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= +golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= +golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1181,8 +1181,8 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc= -golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1240,8 +1240,8 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 h1:Vve/L0v7CXXuxUmaMGIEK/dEeq7uiqb5qBgQrZzIE7E= -golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM= +golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ= +golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index ab9cb3810..6c7f890aa 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -107,7 +107,7 @@ require ( github.com/google/go-cmp v0.5.9 // indirect github.com/google/gopacket v1.1.19 // indirect github.com/google/pprof v0.0.0-20230821062121-407c9e7a662f // indirect - github.com/google/uuid v1.3.0 // indirect + github.com/google/uuid v1.3.1 // indirect github.com/gordonklaus/ineffassign v0.0.0-20230610083614-0e73809eb601 // indirect github.com/gorilla/websocket v1.5.0 // indirect github.com/gostaticanalysis/analysisutil v0.7.1 // indirect @@ -120,20 +120,20 @@ require ( github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-version v1.6.0 // indirect github.com/hashicorp/golang-lru v0.5.4 // indirect - github.com/hashicorp/golang-lru/v2 v2.0.5 // indirect + github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/hexops/gotextdiff v1.0.3 // indirect github.com/huin/goupnp v1.2.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/ipfs/bbloom v0.0.4 // indirect github.com/ipfs/go-bitfield v1.1.0 // indirect - github.com/ipfs/go-block-format v0.1.2 // indirect + github.com/ipfs/go-block-format v0.2.0 // indirect github.com/ipfs/go-ipfs-blockstore v1.3.0 // indirect github.com/ipfs/go-ipfs-ds-help v1.1.0 // indirect github.com/ipfs/go-ipfs-files v0.2.0 // indirect github.com/ipfs/go-ipfs-pq v0.0.3 // indirect github.com/ipfs/go-ipfs-util v0.0.3 // indirect - github.com/ipfs/go-ipld-format v0.5.0 // indirect + github.com/ipfs/go-ipld-format v0.6.0 // indirect github.com/ipfs/go-ipld-legacy v0.2.1 // indirect github.com/ipfs/go-log/v2 v2.5.1 // indirect github.com/ipfs/go-metrics-interface v0.0.1 // indirect @@ -214,10 +214,10 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect github.com/polydawn/refmt v0.89.0 // indirect github.com/polyfloyd/go-errorlint v1.4.3 // indirect - github.com/prometheus/client_golang v1.16.0 // indirect - github.com/prometheus/client_model v0.4.0 // indirect + github.com/prometheus/client_golang v1.17.0 // indirect + github.com/prometheus/client_model v0.5.0 // indirect github.com/prometheus/common v0.44.0 // indirect - github.com/prometheus/procfs v0.11.1 // indirect + github.com/prometheus/procfs v0.12.0 // indirect github.com/quasilyte/go-ruleguard v0.4.0 // indirect github.com/quasilyte/gogrep v0.5.0 // indirect github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727 // indirect @@ -269,25 +269,25 @@ require ( github.com/yeya24/promlinter v0.2.0 // indirect github.com/ykadowak/zerologlint v0.1.3 // indirect gitlab.com/bosi/decorder v0.4.0 // indirect - go.opentelemetry.io/otel v1.16.0 // indirect - go.opentelemetry.io/otel/metric v1.16.0 // indirect - go.opentelemetry.io/otel/trace v1.16.0 // indirect + go.opentelemetry.io/otel v1.19.0 // indirect + go.opentelemetry.io/otel/metric v1.19.0 // indirect + go.opentelemetry.io/otel/trace v1.19.0 // indirect go.tmz.dev/musttag v0.7.1 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/dig v1.17.0 // indirect go.uber.org/fx v1.20.0 // indirect go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap v1.25.0 // indirect - golang.org/x/crypto v0.12.0 // indirect - golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 // indirect + go.uber.org/zap v1.26.0 // indirect + golang.org/x/crypto v0.14.0 // indirect + golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect golang.org/x/exp/typeparams v0.0.0-20230307190834-24139beb5833 // indirect golang.org/x/mod v0.12.0 // indirect - golang.org/x/net v0.14.0 // indirect + golang.org/x/net v0.15.0 // indirect golang.org/x/sync v0.3.0 // indirect - golang.org/x/sys v0.11.0 // indirect - golang.org/x/term v0.11.0 // indirect - golang.org/x/text v0.12.0 // indirect - golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 // indirect + golang.org/x/sys v0.13.0 // indirect + golang.org/x/term v0.13.0 // indirect + golang.org/x/text v0.13.0 // indirect + golang.org/x/tools v0.13.0 // indirect google.golang.org/protobuf v1.31.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index a314fbac0..c296c573e 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -339,8 +339,8 @@ github.com/google/pprof v0.0.0-20230821062121-407c9e7a662f/go.mod h1:czg5+yv1E0Z github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= +github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= @@ -381,8 +381,8 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= -github.com/hashicorp/golang-lru/v2 v2.0.5 h1:wW7h1TG88eUIJ2i69gaE3uNVtEPIagzhGvHgwfx2Vm4= -github.com/hashicorp/golang-lru/v2 v2.0.5/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= +github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= +github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= @@ -400,8 +400,8 @@ github.com/ipfs/boxo v0.13.2-0.20231002142647-c28c847582f0 h1:oss04OCg1/QW0h3OfS github.com/ipfs/boxo v0.13.2-0.20231002142647-c28c847582f0/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= -github.com/ipfs/go-block-format v0.1.2 h1:GAjkfhVx1f4YTODS6Esrj1wt2HhrtwTnhEr+DyPUaJo= -github.com/ipfs/go-block-format v0.1.2/go.mod h1:mACVcrxarQKstUU3Yf/RdwbC4DzPV6++rO2a3d+a/KE= +github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs= +github.com/ipfs/go-block-format v0.2.0/go.mod h1:+jpL11nFx5A/SPpsoBn6Bzkra/zaArfSmsknbPMYgzM= github.com/ipfs/go-blockservice v0.5.0 h1:B2mwhhhVQl2ntW2EIpaWPwSCxSuqr5fFA93Ms4bYLEY= github.com/ipfs/go-cid v0.0.5/go.mod h1:plgt+Y5MnOey4vO4UlUazGqdbEXuFYitED67FexhXog= github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= @@ -433,8 +433,8 @@ github.com/ipfs/go-ipfs-pq v0.0.3/go.mod h1:btNw5hsHBpRcSSgZtiNm/SLj5gYIZ18AKtv3 github.com/ipfs/go-ipfs-util v0.0.3 h1:2RFdGez6bu2ZlZdI+rWfIdbQb1KudQp3VGwPtdNCmE0= github.com/ipfs/go-ipfs-util v0.0.3/go.mod h1:LHzG1a0Ig4G+iZ26UUOMjHd+lfM84LZCrn17xAKWBvs= github.com/ipfs/go-ipld-cbor v0.0.6 h1:pYuWHyvSpIsOOLw4Jy7NbBkCyzLDcl64Bf/LZW7eBQ0= -github.com/ipfs/go-ipld-format v0.5.0 h1:WyEle9K96MSrvr47zZHKKcDxJ/vlpET6PSiQsAFO+Ds= -github.com/ipfs/go-ipld-format v0.5.0/go.mod h1:ImdZqJQaEouMjCvqCe0ORUS+uoBmf7Hf+EO/jh+nk3M= +github.com/ipfs/go-ipld-format v0.6.0 h1:VEJlA2kQ3LqFSIm5Vu6eIlSxD/Ze90xtc4Meten1F5U= +github.com/ipfs/go-ipld-format v0.6.0/go.mod h1:g4QVMTn3marU3qXchwjpKPKgJv+zF+OlaKMyhJ4LHPg= github.com/ipfs/go-ipld-legacy v0.2.1 h1:mDFtrBpmU7b//LzLSypVrXsD8QxkEWxu5qVxN99/+tk= github.com/ipfs/go-ipld-legacy v0.2.1/go.mod h1:782MOUghNzMO2DER0FlBR94mllfdCJCkTtDtPM51otM= github.com/ipfs/go-libipfs v0.7.0 h1:Mi54WJTODaOL2/ZSm5loi3SwI3jI2OuFWUrQIkJ5cpM= @@ -707,14 +707,14 @@ github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5Fsn github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= -github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8= -github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc= +github.com/prometheus/client_golang v1.17.0 h1:rl2sfwZMtSthVU752MqfjQozy7blglC+1SOtjMAMh+Q= +github.com/prometheus/client_golang v1.17.0/go.mod h1:VeL+gMmOAxkS2IqfCq0ZmHSL+LjWfWDUmp1mBz9JgUY= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY= -github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= +github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= +github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= @@ -728,8 +728,8 @@ github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsT github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.11.1 h1:xRC8Iq1yyca5ypa9n1EZnWZkt7dwcoRPQwX/5gwaUuI= -github.com/prometheus/procfs v0.11.1/go.mod h1:eesXgaPo1q7lBpVMoMy0ZOFTth9hBn4W/y0/p/ScXhY= +github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= +github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= github.com/quasilyte/go-ruleguard v0.4.0 h1:DyM6r+TKL+xbKB4Nm7Afd1IQh9kEUKQs2pboWGKtvQo= github.com/quasilyte/go-ruleguard v0.4.0/go.mod h1:Eu76Z/R8IXtViWUIHkE3p8gdH3/PKk1eh3YGfaEof10= github.com/quasilyte/gogrep v0.5.0 h1:eTKODPXbI8ffJMN+W2aE0+oL0z/nh8/5eNdiO34SOAo= @@ -915,13 +915,13 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= -go.opentelemetry.io/otel v1.16.0 h1:Z7GVAX/UkAXPKsy94IU+i6thsQS4nb7LviLpnaNeW8s= -go.opentelemetry.io/otel v1.16.0/go.mod h1:vl0h9NUa1D5s1nv3A5vZOYWn8av4K8Ml6JDeHrT/bx4= -go.opentelemetry.io/otel/metric v1.16.0 h1:RbrpwVG1Hfv85LgnZ7+txXioPDoh6EdbZHo26Q3hqOo= -go.opentelemetry.io/otel/metric v1.16.0/go.mod h1:QE47cpOmkwipPiefDwo2wDzwJrlfxxNYodqc4xnGCo4= +go.opentelemetry.io/otel v1.19.0 h1:MuS/TNf4/j4IXsZuJegVzI1cwut7Qc00344rgH7p8bs= +go.opentelemetry.io/otel v1.19.0/go.mod h1:i0QyjOq3UPoTzff0PJB2N66fb4S0+rSbSB15/oyH9fY= +go.opentelemetry.io/otel/metric v1.19.0 h1:aTzpGtV0ar9wlV4Sna9sdJyII5jTVJEvKETPiOKwvpE= +go.opentelemetry.io/otel/metric v1.19.0/go.mod h1:L5rUsV9kM1IxCj1MmSdS+JQAcVm319EUrDVLrt7jqt8= go.opentelemetry.io/otel/sdk v1.16.0 h1:Z1Ok1YsijYL0CSJpHt4cS3wDDh7p572grzNrBMiMWgE= -go.opentelemetry.io/otel/trace v1.16.0 h1:8JRpaObFoW0pxuVPapkgH8UhHQj+bJW8jJsCZEu5MQs= -go.opentelemetry.io/otel/trace v1.16.0/go.mod h1:Yt9vYq1SdNz3xdjZZK7wcXv1qv2pwLkqr2QVwea0ef0= +go.opentelemetry.io/otel/trace v1.19.0 h1:DFVQmlVbfVeOuBRrwdtaehRrWiL1JoVs9CPIQ1Dzxpg= +go.opentelemetry.io/otel/trace v1.19.0/go.mod h1:mfaSyvGyEJEI0nyV2I4qhNQnbBOUUmYZpYojqMnX2vo= go.tmz.dev/musttag v0.7.1 h1:9lFmeSFnFfPuMq4IksHGomItE6NgKMNW2Nt2FPOhCfU= go.tmz.dev/musttag v0.7.1/go.mod h1:oJLkpR56EsIryktZJk/B0IroSMi37YWver47fibGh5U= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= @@ -941,8 +941,8 @@ go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN8 go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= -go.uber.org/zap v1.25.0 h1:4Hvk6GtkucQ790dqmj7l1eEnRdKm3k3ZUrUMS2d5+5c= -go.uber.org/zap v1.25.0/go.mod h1:JIAUzQIH94IC4fOJQm7gMmBJP5k7wQfdcnYdPoEXJYk= +go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= +go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -960,8 +960,8 @@ golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= -golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk= -golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= +golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= +golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -972,8 +972,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 h1:m64FZMko/V45gv0bNmrNYoDEq8U5YUhetc9cBWKS1TQ= -golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63/go.mod h1:0v4NqG35kSWCMzLaMeX+IQrlSnVE/bqGSyC2cz/9Le8= +golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g= +golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= golang.org/x/exp/typeparams v0.0.0-20220428152302-39d4317da171/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/exp/typeparams v0.0.0-20230203172020-98cc5a0785f9/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/exp/typeparams v0.0.0-20230307190834-24139beb5833 h1:jWGQJV4niP+CCmFW9ekjA9Zx8vYORzOUH2/Nl5WPuLQ= @@ -1057,8 +1057,8 @@ golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14= -golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= +golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8= +golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1155,16 +1155,16 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= -golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.11.0 h1:F9tnn/DA/Im8nCwm+fX+1/eBwi4qFjRT++MhtVC4ZX0= -golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= +golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= +golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1176,8 +1176,8 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc= -golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1259,8 +1259,8 @@ golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= golang.org/x/tools v0.5.0/go.mod h1:N+Kgy78s5I24c24dU8OfWNEotWjutIs8SnJvn5IDq+k= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 h1:Vve/L0v7CXXuxUmaMGIEK/dEeq7uiqb5qBgQrZzIE7E= -golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM= +golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ= +golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From 5bac37c7351a5b70474ef2a5e426669bff86cfae Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Fri, 6 Oct 2023 16:04:23 +0200 Subject: [PATCH 0902/1212] feat(path)!: consolidated path libraries (#334) This commit was moved from ipfs/boxo@85c180e26664367f79de453c592020b4f279669f --- core/coreiface/block.go | 5 +- core/coreiface/coreapi.go | 9 +- core/coreiface/dht.go | 2 +- core/coreiface/key.go | 2 +- core/coreiface/name.go | 5 +- core/coreiface/object.go | 17 ++- core/coreiface/path/path.go | 199 -------------------------------- core/coreiface/pin.go | 6 +- core/coreiface/tests/block.go | 37 +++--- core/coreiface/tests/dag.go | 15 +-- core/coreiface/tests/name.go | 21 ++-- core/coreiface/tests/object.go | 14 +-- core/coreiface/tests/path.go | 191 ++++++++++++------------------ core/coreiface/tests/pin.go | 89 +++++++------- core/coreiface/tests/routing.go | 2 +- core/coreiface/tests/unixfs.go | 28 ++--- core/coreiface/unixfs.go | 11 +- 17 files changed, 206 insertions(+), 447 deletions(-) delete mode 100644 core/coreiface/path/path.go diff --git a/core/coreiface/block.go b/core/coreiface/block.go index dbe31e9f8..cdd5fcee2 100644 --- a/core/coreiface/block.go +++ b/core/coreiface/block.go @@ -4,9 +4,8 @@ import ( "context" "io" - path "github.com/ipfs/boxo/coreiface/path" - "github.com/ipfs/boxo/coreiface/options" + "github.com/ipfs/boxo/path" ) // BlockStat contains information about a block @@ -15,7 +14,7 @@ type BlockStat interface { Size() int // Path returns path to the block - Path() path.Resolved + Path() path.ImmutablePath } // BlockAPI specifies the interface to the block layer diff --git a/core/coreiface/coreapi.go b/core/coreiface/coreapi.go index 7276a3f60..25e54a37b 100644 --- a/core/coreiface/coreapi.go +++ b/core/coreiface/coreapi.go @@ -5,9 +5,8 @@ package iface import ( "context" - path "github.com/ipfs/boxo/coreiface/path" - "github.com/ipfs/boxo/coreiface/options" + "github.com/ipfs/boxo/path" ipld "github.com/ipfs/go-ipld-format" ) @@ -47,8 +46,10 @@ type CoreAPI interface { // Routing returns an implementation of Routing API Routing() RoutingAPI - // ResolvePath resolves the path using Unixfs resolver - ResolvePath(context.Context, path.Path) (path.Resolved, error) + // ResolvePath resolves the path using UnixFS resolver, and returns the resolved + // immutable path, and the remainder of the path segments that cannot be resolved + // within UnixFS. + ResolvePath(context.Context, path.Path) (path.ImmutablePath, []string, error) // ResolveNode resolves the path (if not resolved already) using Unixfs // resolver, gets and returns the resolved Node diff --git a/core/coreiface/dht.go b/core/coreiface/dht.go index 93027a406..d9418ebfc 100644 --- a/core/coreiface/dht.go +++ b/core/coreiface/dht.go @@ -3,7 +3,7 @@ package iface import ( "context" - "github.com/ipfs/boxo/coreiface/path" + "github.com/ipfs/boxo/path" "github.com/ipfs/boxo/coreiface/options" diff --git a/core/coreiface/key.go b/core/coreiface/key.go index 118fe2e4f..4a1cbae80 100644 --- a/core/coreiface/key.go +++ b/core/coreiface/key.go @@ -3,7 +3,7 @@ package iface import ( "context" - "github.com/ipfs/boxo/coreiface/path" + "github.com/ipfs/boxo/path" "github.com/ipfs/boxo/coreiface/options" diff --git a/core/coreiface/name.go b/core/coreiface/name.go index 8c3e8e89a..f832033ef 100644 --- a/core/coreiface/name.go +++ b/core/coreiface/name.go @@ -4,10 +4,9 @@ import ( "context" "errors" - path "github.com/ipfs/boxo/coreiface/path" - "github.com/ipfs/boxo/ipns" - "github.com/ipfs/boxo/coreiface/options" + "github.com/ipfs/boxo/ipns" + "github.com/ipfs/boxo/path" ) var ErrResolveFailed = errors.New("could not resolve name") diff --git a/core/coreiface/object.go b/core/coreiface/object.go index d983fa49b..4a73f22ea 100644 --- a/core/coreiface/object.go +++ b/core/coreiface/object.go @@ -4,9 +4,8 @@ import ( "context" "io" - path "github.com/ipfs/boxo/coreiface/path" - "github.com/ipfs/boxo/coreiface/options" + "github.com/ipfs/boxo/path" "github.com/ipfs/go-cid" ipld "github.com/ipfs/go-ipld-format" @@ -60,11 +59,11 @@ type ObjectChange struct { // Before holds the link path before the change. Note that when a link is // added, this will be nil. - Before path.Resolved + Before path.ImmutablePath // After holds the link path after the change. Note that when a link is // removed, this will be nil. - After path.Resolved + After path.ImmutablePath } // ObjectAPI specifies the interface to MerkleDAG and contains useful utilities @@ -74,7 +73,7 @@ type ObjectAPI interface { New(context.Context, ...options.ObjectNewOption) (ipld.Node, error) // Put imports the data into merkledag - Put(context.Context, io.Reader, ...options.ObjectPutOption) (path.Resolved, error) + Put(context.Context, io.Reader, ...options.ObjectPutOption) (path.ImmutablePath, error) // Get returns the node for the path Get(context.Context, path.Path) (ipld.Node, error) @@ -91,16 +90,16 @@ type ObjectAPI interface { // AddLink adds a link under the specified path. child path can point to a // subdirectory within the patent which must be present (can be overridden // with WithCreate option). - AddLink(ctx context.Context, base path.Path, name string, child path.Path, opts ...options.ObjectAddLinkOption) (path.Resolved, error) + AddLink(ctx context.Context, base path.Path, name string, child path.Path, opts ...options.ObjectAddLinkOption) (path.ImmutablePath, error) // RmLink removes a link from the node - RmLink(ctx context.Context, base path.Path, link string) (path.Resolved, error) + RmLink(ctx context.Context, base path.Path, link string) (path.ImmutablePath, error) // AppendData appends data to the node - AppendData(context.Context, path.Path, io.Reader) (path.Resolved, error) + AppendData(context.Context, path.Path, io.Reader) (path.ImmutablePath, error) // SetData sets the data contained in the node - SetData(context.Context, path.Path, io.Reader) (path.Resolved, error) + SetData(context.Context, path.Path, io.Reader) (path.ImmutablePath, error) // Diff returns a set of changes needed to transform the first object into the // second. diff --git a/core/coreiface/path/path.go b/core/coreiface/path/path.go deleted file mode 100644 index c26b8692b..000000000 --- a/core/coreiface/path/path.go +++ /dev/null @@ -1,199 +0,0 @@ -package path - -import ( - "strings" - - ipfspath "github.com/ipfs/boxo/path" - cid "github.com/ipfs/go-cid" -) - -// Path is a generic wrapper for paths used in the API. A path can be resolved -// to a CID using one of Resolve functions in the API. -// -// Paths must be prefixed with a valid prefix: -// -// * /ipfs - Immutable unixfs path (files) -// * /ipld - Immutable ipld path (data) -// * /ipns - Mutable names. Usually resolves to one of the immutable paths -// TODO: /local (MFS) -type Path interface { - // String returns the path as a string. - String() string - - // Namespace returns the first component of the path. - // - // For example path "/ipfs/QmHash", calling Namespace() will return "ipfs" - // - // Calling this method on invalid paths (IsValid() != nil) will result in - // empty string - Namespace() string - - // Mutable returns false if the data pointed to by this path in guaranteed - // to not change. - // - // Note that resolved mutable path can be immutable. - Mutable() bool - - // IsValid checks if this path is a valid ipfs Path, returning nil iff it is - // valid - IsValid() error -} - -// Resolved is a path which was resolved to the last resolvable node. -// ResolvedPaths are guaranteed to return nil from `IsValid` -type Resolved interface { - // Cid returns the CID of the node referenced by the path. Remainder of the - // path is guaranteed to be within the node. - // - // Examples: - // If you have 3 linked objects: QmRoot -> A -> B: - // - // cidB := {"foo": {"bar": 42 }} - // cidA := {"B": {"/": cidB }} - // cidRoot := {"A": {"/": cidA }} - // - // And resolve paths: - // - // * "/ipfs/${cidRoot}" - // * Calling Cid() will return `cidRoot` - // * Calling Root() will return `cidRoot` - // * Calling Remainder() will return `` - // - // * "/ipfs/${cidRoot}/A" - // * Calling Cid() will return `cidA` - // * Calling Root() will return `cidRoot` - // * Calling Remainder() will return `` - // - // * "/ipfs/${cidRoot}/A/B/foo" - // * Calling Cid() will return `cidB` - // * Calling Root() will return `cidRoot` - // * Calling Remainder() will return `foo` - // - // * "/ipfs/${cidRoot}/A/B/foo/bar" - // * Calling Cid() will return `cidB` - // * Calling Root() will return `cidRoot` - // * Calling Remainder() will return `foo/bar` - Cid() cid.Cid - - // Root returns the CID of the root object of the path - // - // Example: - // If you have 3 linked objects: QmRoot -> A -> B, and resolve path - // "/ipfs/QmRoot/A/B", the Root method will return the CID of object QmRoot - // - // For more examples see the documentation of Cid() method - Root() cid.Cid - - // Remainder returns unresolved part of the path - // - // Example: - // If you have 2 linked objects: QmRoot -> A, where A is a CBOR node - // containing the following data: - // - // {"foo": {"bar": 42 }} - // - // When resolving "/ipld/QmRoot/A/foo/bar", Remainder will return "foo/bar" - // - // For more examples see the documentation of Cid() method - Remainder() string - - Path -} - -// path implements coreiface.Path -type path struct { - path string -} - -// resolvedPath implements coreiface.resolvedPath -type resolvedPath struct { - path - cid cid.Cid - root cid.Cid - remainder string -} - -// Join appends provided segments to the base path -func Join(base Path, a ...string) Path { - s := strings.Join(append([]string{base.String()}, a...), "/") - return &path{path: s} -} - -// IpfsPath creates new /ipfs path from the provided CID -func IpfsPath(c cid.Cid) Resolved { - return &resolvedPath{ - path: path{"/ipfs/" + c.String()}, - cid: c, - root: c, - remainder: "", - } -} - -// IpldPath creates new /ipld path from the provided CID -func IpldPath(c cid.Cid) Resolved { - return &resolvedPath{ - path: path{"/ipld/" + c.String()}, - cid: c, - root: c, - remainder: "", - } -} - -// New parses string path to a Path -func New(p string) Path { - if pp, err := ipfspath.ParsePath(p); err == nil { - p = pp.String() - } - - return &path{path: p} -} - -// NewResolvedPath creates new Resolved path. This function performs no checks -// and is intended to be used by resolver implementations. Incorrect inputs may -// cause panics. Handle with care. -func NewResolvedPath(ipath ipfspath.Path, c cid.Cid, root cid.Cid, remainder string) Resolved { - return &resolvedPath{ - path: path{ipath.String()}, - cid: c, - root: root, - remainder: remainder, - } -} - -func (p *path) String() string { - return p.path -} - -func (p *path) Namespace() string { - ip, err := ipfspath.ParsePath(p.path) - if err != nil { - return "" - } - - if len(ip.Segments()) < 1 { - panic("path without namespace") // this shouldn't happen under any scenario - } - return ip.Segments()[0] -} - -func (p *path) Mutable() bool { - // TODO: MFS: check for /local - return p.Namespace() == "ipns" -} - -func (p *path) IsValid() error { - _, err := ipfspath.ParsePath(p.path) - return err -} - -func (p *resolvedPath) Cid() cid.Cid { - return p.cid -} - -func (p *resolvedPath) Root() cid.Cid { - return p.root -} - -func (p *resolvedPath) Remainder() string { - return p.remainder -} diff --git a/core/coreiface/pin.go b/core/coreiface/pin.go index 6b97c6ca5..057516d08 100644 --- a/core/coreiface/pin.go +++ b/core/coreiface/pin.go @@ -3,7 +3,7 @@ package iface import ( "context" - path "github.com/ipfs/boxo/coreiface/path" + "github.com/ipfs/boxo/path" "github.com/ipfs/boxo/coreiface/options" ) @@ -11,7 +11,7 @@ import ( // Pin holds information about pinned resource type Pin interface { // Path to the pinned object - Path() path.Resolved + Path() path.ImmutablePath // Type of the pin Type() string @@ -35,7 +35,7 @@ type PinStatus interface { // BadPinNode is a node that has been marked as bad by Pin.Verify type BadPinNode interface { // Path is the path of the node - Path() path.Resolved + Path() path.ImmutablePath // Err is the reason why the node has been marked as bad Err() error diff --git a/core/coreiface/tests/block.go b/core/coreiface/tests/block.go index 5dcb16e4f..6e254063e 100644 --- a/core/coreiface/tests/block.go +++ b/core/coreiface/tests/block.go @@ -9,9 +9,8 @@ import ( coreiface "github.com/ipfs/boxo/coreiface" opt "github.com/ipfs/boxo/coreiface/options" - "github.com/ipfs/boxo/coreiface/path" + "github.com/ipfs/boxo/path" ipld "github.com/ipfs/go-ipld-format" - mh "github.com/multiformats/go-multihash" ) @@ -68,8 +67,8 @@ func (tp *TestSuite) TestBlockPut(t *testing.T) { t.Fatal(err) } - if res.Path().Cid().String() != rawCid { - t.Errorf("got wrong cid: %s", res.Path().Cid().String()) + if res.Path().RootCid().String() != rawCid { + t.Errorf("got wrong cid: %s", res.Path().RootCid().String()) } } @@ -88,8 +87,8 @@ func (tp *TestSuite) TestBlockPutFormatDagCbor(t *testing.T) { t.Fatal(err) } - if res.Path().Cid().String() != cborCid { - t.Errorf("got wrong cid: %s", res.Path().Cid().String()) + if res.Path().RootCid().String() != cborCid { + t.Errorf("got wrong cid: %s", res.Path().RootCid().String()) } } @@ -108,8 +107,8 @@ func (tp *TestSuite) TestBlockPutFormatDagPb(t *testing.T) { t.Fatal(err) } - if res.Path().Cid().String() != pbCid { - t.Errorf("got wrong cid: %s", res.Path().Cid().String()) + if res.Path().RootCid().String() != pbCid { + t.Errorf("got wrong cid: %s", res.Path().RootCid().String()) } } @@ -128,8 +127,8 @@ func (tp *TestSuite) TestBlockPutFormatV0(t *testing.T) { t.Fatal(err) } - if res.Path().Cid().String() != pbCidV0 { - t.Errorf("got wrong cid: %s", res.Path().Cid().String()) + if res.Path().RootCid().String() != pbCidV0 { + t.Errorf("got wrong cid: %s", res.Path().RootCid().String()) } } @@ -146,8 +145,8 @@ func (tp *TestSuite) TestBlockPutCidCodecDagCbor(t *testing.T) { t.Fatal(err) } - if res.Path().Cid().String() != cborCid { - t.Errorf("got wrong cid: %s", res.Path().Cid().String()) + if res.Path().RootCid().String() != cborCid { + t.Errorf("got wrong cid: %s", res.Path().RootCid().String()) } } @@ -164,8 +163,8 @@ func (tp *TestSuite) TestBlockPutCidCodecDagPb(t *testing.T) { t.Fatal(err) } - if res.Path().Cid().String() != pbCid { - t.Errorf("got wrong cid: %s", res.Path().Cid().String()) + if res.Path().RootCid().String() != pbCid { + t.Errorf("got wrong cid: %s", res.Path().RootCid().String()) } } @@ -187,8 +186,8 @@ func (tp *TestSuite) TestBlockPutHash(t *testing.T) { t.Fatal(err) } - if res.Path().Cid().String() != cborKCid { - t.Errorf("got wrong cid: %s", res.Path().Cid().String()) + if res.Path().RootCid().String() != cborKCid { + t.Errorf("got wrong cid: %s", res.Path().RootCid().String()) } } @@ -219,13 +218,13 @@ func (tp *TestSuite) TestBlockGet(t *testing.T) { t.Error("didn't get correct data back") } - p := path.New("/ipfs/" + res.Path().Cid().String()) + p := path.FromCid(res.Path().RootCid()) - rp, err := api.ResolvePath(ctx, p) + rp, _, err := api.ResolvePath(ctx, p) if err != nil { t.Fatal(err) } - if rp.Cid().String() != res.Path().Cid().String() { + if rp.RootCid().String() != res.Path().RootCid().String() { t.Error("paths didn't match") } } diff --git a/core/coreiface/tests/dag.go b/core/coreiface/tests/dag.go index b9a03c8f4..a106788d6 100644 --- a/core/coreiface/tests/dag.go +++ b/core/coreiface/tests/dag.go @@ -3,13 +3,11 @@ package tests import ( "context" "math" - gopath "path" "strings" "testing" - path "github.com/ipfs/boxo/coreiface/path" - coreiface "github.com/ipfs/boxo/coreiface" + "github.com/ipfs/boxo/path" ipldcbor "github.com/ipfs/go-ipld-cbor" ipld "github.com/ipfs/go-ipld-format" @@ -113,14 +111,17 @@ func (tp *TestSuite) TestDagPath(t *testing.T) { t.Fatal(err) } - p := path.New(gopath.Join(nd.Cid().String(), "lnk")) - - rp, err := api.ResolvePath(ctx, p) + p, err := path.Join(path.FromCid(nd.Cid()), "lnk") if err != nil { t.Fatal(err) } - ndd, err := api.Dag().Get(ctx, rp.Cid()) + rp, _, err := api.ResolvePath(ctx, p) + if err != nil { + t.Fatal(err) + } + + ndd, err := api.Dag().Get(ctx, rp.RootCid()) if err != nil { t.Fatal(err) } diff --git a/core/coreiface/tests/name.go b/core/coreiface/tests/name.go index 74d88edff..2b6b7ec49 100644 --- a/core/coreiface/tests/name.go +++ b/core/coreiface/tests/name.go @@ -4,15 +4,14 @@ import ( "context" "io" "math/rand" - gopath "path" "testing" "time" coreiface "github.com/ipfs/boxo/coreiface" opt "github.com/ipfs/boxo/coreiface/options" - path "github.com/ipfs/boxo/coreiface/path" "github.com/ipfs/boxo/files" "github.com/ipfs/boxo/ipns" + "github.com/ipfs/boxo/path" "github.com/stretchr/testify/require" ) @@ -35,10 +34,6 @@ func addTestObject(ctx context.Context, api coreiface.CoreAPI) (path.Path, error return api.Unixfs().Add(ctx, files.NewReaderFile(&io.LimitedReader{R: rnd, N: 4092})) } -func appendPath(p path.Path, sub string) path.Path { - return path.New(gopath.Join(p.String(), sub)) -} - func (tp *TestSuite) TestPublishResolve(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() @@ -68,7 +63,10 @@ func (tp *TestSuite) TestPublishResolve(t *testing.T) { t.Run("publishPath", func(t *testing.T) { api, p := init() - name, err := api.Name().Publish(ctx, appendPath(p, "/test")) + p, err := path.Join(p, "/test") + require.NoError(t, err) + + name, err := api.Name().Publish(ctx, p) require.NoError(t, err) self, err := api.Key().Self(ctx) @@ -77,7 +75,7 @@ func (tp *TestSuite) TestPublishResolve(t *testing.T) { resPath, err := api.Name().Resolve(ctx, name.String(), ropts...) require.NoError(t, err) - require.Equal(t, p.String()+"/test", resPath.String()) + require.Equal(t, p.String(), resPath.String()) }) t.Run("revolvePath", func(t *testing.T) { @@ -96,7 +94,10 @@ func (tp *TestSuite) TestPublishResolve(t *testing.T) { t.Run("publishRevolvePath", func(t *testing.T) { api, p := init() - name, err := api.Name().Publish(ctx, appendPath(p, "/a")) + p, err := path.Join(p, "/a") + require.NoError(t, err) + + name, err := api.Name().Publish(ctx, p) require.NoError(t, err) self, err := api.Key().Self(ctx) @@ -105,7 +106,7 @@ func (tp *TestSuite) TestPublishResolve(t *testing.T) { resPath, err := api.Name().Resolve(ctx, name.String()+"/b", ropts...) require.NoError(t, err) - require.Equal(t, p.String()+"/a/b", resPath.String()) + require.Equal(t, p.String()+"/b", resPath.String()) }) } diff --git a/core/coreiface/tests/object.go b/core/coreiface/tests/object.go index 63c218eb3..5c6ba828c 100644 --- a/core/coreiface/tests/object.go +++ b/core/coreiface/tests/object.go @@ -166,7 +166,7 @@ func (tp *TestSuite) TestObjectLinks(t *testing.T) { t.Fatal(err) } - p2, err := api.Object().Put(ctx, strings.NewReader(`{"Links":[{"Name":"bar", "Hash":"`+p1.Cid().String()+`"}]}`)) + p2, err := api.Object().Put(ctx, strings.NewReader(`{"Links":[{"Name":"bar", "Hash":"`+p1.RootCid().String()+`"}]}`)) if err != nil { t.Fatal(err) } @@ -180,7 +180,7 @@ func (tp *TestSuite) TestObjectLinks(t *testing.T) { t.Errorf("unexpected number of links: %d", len(links)) } - if links[0].Cid.String() != p1.Cid().String() { + if links[0].Cid.String() != p1.RootCid().String() { t.Fatal("cids didn't batch") } @@ -202,7 +202,7 @@ func (tp *TestSuite) TestObjectStat(t *testing.T) { t.Fatal(err) } - p2, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"bazz", "Links":[{"Name":"bar", "Hash":"`+p1.Cid().String()+`", "Size":3}]}`)) + p2, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"bazz", "Links":[{"Name":"bar", "Hash":"`+p1.RootCid().String()+`", "Size":3}]}`)) if err != nil { t.Fatal(err) } @@ -212,7 +212,7 @@ func (tp *TestSuite) TestObjectStat(t *testing.T) { t.Fatal(err) } - if stat.Cid.String() != p2.Cid().String() { + if stat.Cid.String() != p2.RootCid().String() { t.Error("unexpected stat.Cid") } @@ -250,7 +250,7 @@ func (tp *TestSuite) TestObjectAddLink(t *testing.T) { t.Fatal(err) } - p2, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"bazz", "Links":[{"Name":"bar", "Hash":"`+p1.Cid().String()+`", "Size":3}]}`)) + p2, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"bazz", "Links":[{"Name":"bar", "Hash":"`+p1.RootCid().String()+`", "Size":3}]}`)) if err != nil { t.Fatal(err) } @@ -291,7 +291,7 @@ func (tp *TestSuite) TestObjectAddLinkCreate(t *testing.T) { t.Fatal(err) } - p2, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"bazz", "Links":[{"Name":"bar", "Hash":"`+p1.Cid().String()+`", "Size":3}]}`)) + p2, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"bazz", "Links":[{"Name":"bar", "Hash":"`+p1.RootCid().String()+`", "Size":3}]}`)) if err != nil { t.Fatal(err) } @@ -340,7 +340,7 @@ func (tp *TestSuite) TestObjectRmLink(t *testing.T) { t.Fatal(err) } - p2, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"bazz", "Links":[{"Name":"bar", "Hash":"`+p1.Cid().String()+`", "Size":3}]}`)) + p2, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"bazz", "Links":[{"Name":"bar", "Hash":"`+p1.RootCid().String()+`", "Size":3}]}`)) if err != nil { t.Fatal(err) } diff --git a/core/coreiface/tests/path.go b/core/coreiface/tests/path.go index 06f3aa1f8..116aed2e7 100644 --- a/core/coreiface/tests/path.go +++ b/core/coreiface/tests/path.go @@ -2,17 +2,26 @@ package tests import ( "context" + "fmt" "math" "strings" "testing" - "github.com/ipfs/boxo/coreiface/path" - "github.com/ipfs/boxo/coreiface/options" - + "github.com/ipfs/boxo/path" + "github.com/ipfs/go-cid" ipldcbor "github.com/ipfs/go-ipld-cbor" + "github.com/stretchr/testify/require" ) +func newIPLDPath(t *testing.T, cid cid.Cid) path.ImmutablePath { + p, err := path.NewPath(fmt.Sprintf("/%s/%s", path.IPLDNamespace, cid.String())) + require.NoError(t, err) + im, err := path.NewImmutablePath(p) + require.NoError(t, err) + return im +} + func (tp *TestSuite) TestPath(t *testing.T) { t.Run("TestMutablePath", tp.TestMutablePath) t.Run("TestPathRemainder", tp.TestPathRemainder) @@ -25,173 +34,115 @@ func (tp *TestSuite) TestPath(t *testing.T) { func (tp *TestSuite) TestMutablePath(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() + api, err := tp.makeAPI(t, ctx) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) blk, err := api.Block().Put(ctx, strings.NewReader(`foo`)) - if err != nil { - t.Fatal(err) - } - - if blk.Path().Mutable() { - t.Error("expected /ipld path to be immutable") - } - - // get self /ipns path - - if api.Key() == nil { - t.Fatal(".Key not implemented") - } + require.NoError(t, err) + require.False(t, blk.Path().Mutable()) + require.NotNil(t, api.Key()) keys, err := api.Key().List(ctx) - if err != nil { - t.Fatal(err) - } - - if !keys[0].Path().Mutable() { - t.Error("expected self /ipns path to be mutable") - } + require.NoError(t, err) + require.True(t, keys[0].Path().Mutable()) } func (tp *TestSuite) TestPathRemainder(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(t, ctx) - if err != nil { - t.Fatal(err) - } - if api.Dag() == nil { - t.Fatal(".Dag not implemented") - } + api, err := tp.makeAPI(t, ctx) + require.NoError(t, err) + require.NotNil(t, api.Dag()) nd, err := ipldcbor.FromJSON(strings.NewReader(`{"foo": {"bar": "baz"}}`), math.MaxUint64, -1) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - if err := api.Dag().Add(ctx, nd); err != nil { - t.Fatal(err) - } + err = api.Dag().Add(ctx, nd) + require.NoError(t, err) - rp1, err := api.ResolvePath(ctx, path.New(nd.String()+"/foo/bar")) - if err != nil { - t.Fatal(err) - } + p, err := path.Join(path.FromCid(nd.Cid()), "foo", "bar") + require.NoError(t, err) - if rp1.Remainder() != "foo/bar" { - t.Error("expected to get path remainder") - } + _, remainder, err := api.ResolvePath(ctx, p) + require.NoError(t, err) + require.Equal(t, "/foo/bar", path.SegmentsToString(remainder...)) } func (tp *TestSuite) TestEmptyPathRemainder(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(t, ctx) - if err != nil { - t.Fatal(err) - } - if api.Dag() == nil { - t.Fatal(".Dag not implemented") - } + api, err := tp.makeAPI(t, ctx) + require.NoError(t, err) + require.NotNil(t, api.Dag()) nd, err := ipldcbor.FromJSON(strings.NewReader(`{"foo": {"bar": "baz"}}`), math.MaxUint64, -1) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - if err := api.Dag().Add(ctx, nd); err != nil { - t.Fatal(err) - } + err = api.Dag().Add(ctx, nd) + require.NoError(t, err) - rp1, err := api.ResolvePath(ctx, path.New(nd.Cid().String())) - if err != nil { - t.Fatal(err) - } - - if rp1.Remainder() != "" { - t.Error("expected the resolved path to not have a remainder") - } + _, remainder, err := api.ResolvePath(ctx, path.FromCid(nd.Cid())) + require.NoError(t, err) + require.Empty(t, remainder) } func (tp *TestSuite) TestInvalidPathRemainder(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(t, ctx) - if err != nil { - t.Fatal(err) - } - if api.Dag() == nil { - t.Fatal(".Dag not implemented") - } + api, err := tp.makeAPI(t, ctx) + require.NoError(t, err) + require.NotNil(t, api.Dag()) nd, err := ipldcbor.FromJSON(strings.NewReader(`{"foo": {"bar": "baz"}}`), math.MaxUint64, -1) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - if err := api.Dag().Add(ctx, nd); err != nil { - t.Fatal(err) - } + err = api.Dag().Add(ctx, nd) + require.NoError(t, err) - _, err = api.ResolvePath(ctx, path.New("/ipld/"+nd.Cid().String()+"/bar/baz")) - if err == nil || !strings.Contains(err.Error(), `no link named "bar"`) { - t.Fatalf("unexpected error: %s", err) - } + p, err := path.Join(newIPLDPath(t, nd.Cid()), "/bar/baz") + require.NoError(t, err) + + _, _, err = api.ResolvePath(ctx, p) + require.NotNil(t, err) + require.ErrorContains(t, err, `no link named "bar"`) } func (tp *TestSuite) TestPathRoot(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(t, ctx) - if err != nil { - t.Fatal(err) - } - if api.Block() == nil { - t.Fatal(".Block not implemented") - } + api, err := tp.makeAPI(t, ctx) + require.NoError(t, err) + require.NotNil(t, api.Block()) blk, err := api.Block().Put(ctx, strings.NewReader(`foo`), options.Block.Format("raw")) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) + require.NotNil(t, api.Dag()) - if api.Dag() == nil { - t.Fatal(".Dag not implemented") - } + nd, err := ipldcbor.FromJSON(strings.NewReader(`{"foo": {"/": "`+blk.Path().RootCid().String()+`"}}`), math.MaxUint64, -1) + require.NoError(t, err) - nd, err := ipldcbor.FromJSON(strings.NewReader(`{"foo": {"/": "`+blk.Path().Cid().String()+`"}}`), math.MaxUint64, -1) - if err != nil { - t.Fatal(err) - } + err = api.Dag().Add(ctx, nd) + require.NoError(t, err) - if err := api.Dag().Add(ctx, nd); err != nil { - t.Fatal(err) - } + p, err := path.Join(newIPLDPath(t, nd.Cid()), "/foo") + require.NoError(t, err) - rp, err := api.ResolvePath(ctx, path.New("/ipld/"+nd.Cid().String()+"/foo")) - if err != nil { - t.Fatal(err) - } - - if rp.Root().String() != nd.Cid().String() { - t.Error("unexpected path root") - } - - if rp.Cid().String() != blk.Path().Cid().String() { - t.Error("unexpected path cid") - } + rp, _, err := api.ResolvePath(ctx, p) + require.NoError(t, err) + require.Equal(t, rp.RootCid().String(), blk.Path().RootCid().String()) } func (tp *TestSuite) TestPathJoin(t *testing.T) { - p1 := path.New("/ipfs/QmYNmQKp6SuaVrpgWRsPTgCQCnpxUYGq76YEKBXuj2N4H6/bar/baz") + p1, err := path.NewPath("/ipfs/QmYNmQKp6SuaVrpgWRsPTgCQCnpxUYGq76YEKBXuj2N4H6/bar/baz") + require.NoError(t, err) - if path.Join(p1, "foo").String() != "/ipfs/QmYNmQKp6SuaVrpgWRsPTgCQCnpxUYGq76YEKBXuj2N4H6/bar/baz/foo" { - t.Error("unexpected path") - } + p2, err := path.Join(p1, "foo") + require.NoError(t, err) + + require.Equal(t, "/ipfs/QmYNmQKp6SuaVrpgWRsPTgCQCnpxUYGq76YEKBXuj2N4H6/bar/baz/foo", p2.String()) } diff --git a/core/coreiface/tests/pin.go b/core/coreiface/tests/pin.go index 4b0fea01d..49499b36a 100644 --- a/core/coreiface/tests/pin.go +++ b/core/coreiface/tests/pin.go @@ -8,8 +8,7 @@ import ( iface "github.com/ipfs/boxo/coreiface" opt "github.com/ipfs/boxo/coreiface/options" - "github.com/ipfs/boxo/coreiface/path" - + "github.com/ipfs/boxo/path" "github.com/ipfs/go-cid" ipldcbor "github.com/ipfs/go-ipld-cbor" ipld "github.com/ipfs/go-ipld-format" @@ -77,7 +76,7 @@ func (tp *TestSuite) TestPinSimple(t *testing.T) { t.Errorf("unexpected pin list len: %d", len(list)) } - if list[0].Path().Cid().String() != p.Cid().String() { + if list[0].Path().RootCid().String() != p.RootCid().String() { t.Error("paths don't match") } @@ -120,12 +119,12 @@ func (tp *TestSuite) TestPinRecursive(t *testing.T) { t.Fatal(err) } - nd2, err := ipldcbor.FromJSON(strings.NewReader(`{"lnk": {"/": "`+p0.Cid().String()+`"}}`), math.MaxUint64, -1) + nd2, err := ipldcbor.FromJSON(strings.NewReader(`{"lnk": {"/": "`+p0.RootCid().String()+`"}}`), math.MaxUint64, -1) if err != nil { t.Fatal(err) } - nd3, err := ipldcbor.FromJSON(strings.NewReader(`{"lnk": {"/": "`+p1.Cid().String()+`"}}`), math.MaxUint64, -1) + nd3, err := ipldcbor.FromJSON(strings.NewReader(`{"lnk": {"/": "`+p1.RootCid().String()+`"}}`), math.MaxUint64, -1) if err != nil { t.Fatal(err) } @@ -134,12 +133,12 @@ func (tp *TestSuite) TestPinRecursive(t *testing.T) { t.Fatal(err) } - err = api.Pin().Add(ctx, path.IpldPath(nd2.Cid())) + err = api.Pin().Add(ctx, path.FromCid(nd2.Cid())) if err != nil { t.Fatal(err) } - err = api.Pin().Add(ctx, path.IpldPath(nd3.Cid()), opt.Pin.Recursive(false)) + err = api.Pin().Add(ctx, path.FromCid(nd3.Cid()), opt.Pin.Recursive(false)) if err != nil { t.Fatal(err) } @@ -162,8 +161,8 @@ func (tp *TestSuite) TestPinRecursive(t *testing.T) { t.Errorf("unexpected pin list len: %d", len(list)) } - if list[0].Path().String() != path.IpldPath(nd3.Cid()).String() { - t.Errorf("unexpected path, %s != %s", list[0].Path().String(), path.IpfsPath(nd3.Cid()).String()) + if list[0].Path().String() != path.FromCid(nd3.Cid()).String() { + t.Errorf("unexpected path, %s != %s", list[0].Path().String(), path.FromCid(nd3.Cid()).String()) } list, err = accPins(api.Pin().Ls(ctx, opt.Pin.Ls.Recursive())) @@ -175,8 +174,8 @@ func (tp *TestSuite) TestPinRecursive(t *testing.T) { t.Errorf("unexpected pin list len: %d", len(list)) } - if list[0].Path().String() != path.IpldPath(nd2.Cid()).String() { - t.Errorf("unexpected path, %s != %s", list[0].Path().String(), path.IpldPath(nd2.Cid()).String()) + if list[0].Path().String() != path.FromCid(nd2.Cid()).String() { + t.Errorf("unexpected path, %s != %s", list[0].Path().String(), path.FromCid(nd2.Cid()).String()) } list, err = accPins(api.Pin().Ls(ctx, opt.Pin.Ls.Indirect())) @@ -188,8 +187,8 @@ func (tp *TestSuite) TestPinRecursive(t *testing.T) { t.Errorf("unexpected pin list len: %d", len(list)) } - if list[0].Path().Cid().String() != p0.Cid().String() { - t.Errorf("unexpected path, %s != %s", list[0].Path().Cid().String(), p0.Cid().String()) + if list[0].Path().RootCid().String() != p0.RootCid().String() { + t.Errorf("unexpected path, %s != %s", list[0].Path().RootCid().String(), p0.RootCid().String()) } res, err := api.Pin().Verify(ctx) @@ -259,12 +258,12 @@ func (tp *TestSuite) TestPinLsIndirect(t *testing.T) { leaf, parent, grandparent := getThreeChainedNodes(t, ctx, api, "foo") - err = api.Pin().Add(ctx, path.IpldPath(grandparent.Cid())) + err = api.Pin().Add(ctx, path.FromCid(grandparent.Cid())) if err != nil { t.Fatal(err) } - err = api.Pin().Add(ctx, path.IpldPath(parent.Cid()), opt.Pin.Recursive(false)) + err = api.Pin().Add(ctx, path.FromCid(parent.Cid()), opt.Pin.Recursive(false)) if err != nil { t.Fatal(err) } @@ -293,12 +292,12 @@ func (tp *TestSuite) TestPinLsPredenceRecursiveIndirect(t *testing.T) { // Test recursive > indirect leaf, parent, grandparent := getThreeChainedNodes(t, ctx, api, "recursive > indirect") - err = api.Pin().Add(ctx, path.IpldPath(grandparent.Cid())) + err = api.Pin().Add(ctx, path.FromCid(grandparent.Cid())) if err != nil { t.Fatal(err) } - err = api.Pin().Add(ctx, path.IpldPath(parent.Cid())) + err = api.Pin().Add(ctx, path.FromCid(parent.Cid())) if err != nil { t.Fatal(err) } @@ -317,12 +316,12 @@ func (tp *TestSuite) TestPinLsPrecedenceDirectIndirect(t *testing.T) { // Test direct > indirect leaf, parent, grandparent := getThreeChainedNodes(t, ctx, api, "direct > indirect") - err = api.Pin().Add(ctx, path.IpldPath(grandparent.Cid())) + err = api.Pin().Add(ctx, path.FromCid(grandparent.Cid())) if err != nil { t.Fatal(err) } - err = api.Pin().Add(ctx, path.IpldPath(parent.Cid()), opt.Pin.Recursive(false)) + err = api.Pin().Add(ctx, path.FromCid(parent.Cid()), opt.Pin.Recursive(false)) if err != nil { t.Fatal(err) } @@ -341,24 +340,24 @@ func (tp *TestSuite) TestPinLsPrecedenceRecursiveDirect(t *testing.T) { // Test recursive > direct leaf, parent, grandparent := getThreeChainedNodes(t, ctx, api, "recursive + direct = error") - err = api.Pin().Add(ctx, path.IpldPath(parent.Cid())) + err = api.Pin().Add(ctx, path.FromCid(parent.Cid())) if err != nil { t.Fatal(err) } - err = api.Pin().Add(ctx, path.IpldPath(parent.Cid()), opt.Pin.Recursive(false)) + err = api.Pin().Add(ctx, path.FromCid(parent.Cid()), opt.Pin.Recursive(false)) if err == nil { t.Fatal("expected error directly pinning a recursively pinned node") } assertPinTypes(t, ctx, api, []cidContainer{parent}, []cidContainer{}, []cidContainer{leaf}) - err = api.Pin().Add(ctx, path.IpldPath(grandparent.Cid()), opt.Pin.Recursive(false)) + err = api.Pin().Add(ctx, path.FromCid(grandparent.Cid()), opt.Pin.Recursive(false)) if err != nil { t.Fatal(err) } - err = api.Pin().Add(ctx, path.IpldPath(grandparent.Cid())) + err = api.Pin().Add(ctx, path.FromCid(grandparent.Cid())) if err != nil { t.Fatal(err) } @@ -376,40 +375,48 @@ func (tp *TestSuite) TestPinIsPinned(t *testing.T) { leaf, parent, grandparent := getThreeChainedNodes(t, ctx, api, "foofoo") - assertNotPinned(t, ctx, api, path.IpldPath(grandparent.Cid())) - assertNotPinned(t, ctx, api, path.IpldPath(parent.Cid())) - assertNotPinned(t, ctx, api, path.IpldPath(leaf.Cid())) + assertNotPinned(t, ctx, api, newIPLDPath(t, grandparent.Cid())) + assertNotPinned(t, ctx, api, newIPLDPath(t, parent.Cid())) + assertNotPinned(t, ctx, api, newIPLDPath(t, leaf.Cid())) - err = api.Pin().Add(ctx, path.IpldPath(parent.Cid()), opt.Pin.Recursive(true)) + err = api.Pin().Add(ctx, newIPLDPath(t, parent.Cid()), opt.Pin.Recursive(true)) if err != nil { t.Fatal(err) } - assertNotPinned(t, ctx, api, path.IpldPath(grandparent.Cid())) - assertIsPinned(t, ctx, api, path.IpldPath(parent.Cid()), "recursive") - assertIsPinned(t, ctx, api, path.IpldPath(leaf.Cid()), "indirect") + assertNotPinned(t, ctx, api, newIPLDPath(t, grandparent.Cid())) + assertIsPinned(t, ctx, api, newIPLDPath(t, parent.Cid()), "recursive") + assertIsPinned(t, ctx, api, newIPLDPath(t, leaf.Cid()), "indirect") - err = api.Pin().Add(ctx, path.IpldPath(grandparent.Cid()), opt.Pin.Recursive(false)) + err = api.Pin().Add(ctx, newIPLDPath(t, grandparent.Cid()), opt.Pin.Recursive(false)) if err != nil { t.Fatal(err) } - assertIsPinned(t, ctx, api, path.IpldPath(grandparent.Cid()), "direct") - assertIsPinned(t, ctx, api, path.IpldPath(parent.Cid()), "recursive") - assertIsPinned(t, ctx, api, path.IpldPath(leaf.Cid()), "indirect") + assertIsPinned(t, ctx, api, newIPLDPath(t, grandparent.Cid()), "direct") + assertIsPinned(t, ctx, api, newIPLDPath(t, parent.Cid()), "recursive") + assertIsPinned(t, ctx, api, newIPLDPath(t, leaf.Cid()), "indirect") } type cidContainer interface { Cid() cid.Cid } +type immutablePathCidContainer struct { + path.ImmutablePath +} + +func (i immutablePathCidContainer) Cid() cid.Cid { + return i.RootCid() +} + func getThreeChainedNodes(t *testing.T, ctx context.Context, api iface.CoreAPI, leafData string) (cidContainer, cidContainer, cidContainer) { leaf, err := api.Unixfs().Add(ctx, strFile(leafData)()) if err != nil { t.Fatal(err) } - parent, err := ipldcbor.FromJSON(strings.NewReader(`{"lnk": {"/": "`+leaf.Cid().String()+`"}}`), math.MaxUint64, -1) + parent, err := ipldcbor.FromJSON(strings.NewReader(`{"lnk": {"/": "`+leaf.RootCid().String()+`"}}`), math.MaxUint64, -1) if err != nil { t.Fatal(err) } @@ -423,7 +430,7 @@ func getThreeChainedNodes(t *testing.T, ctx context.Context, api iface.CoreAPI, t.Fatal(err) } - return leaf, parent, grandparent + return immutablePathCidContainer{leaf}, parent, grandparent } func assertPinTypes(t *testing.T, ctx context.Context, api iface.CoreAPI, recusive, direct, indirect []cidContainer) { @@ -466,7 +473,7 @@ func assertPinCids(t *testing.T, pins []iface.Pin, cids ...cidContainer) { valid := true for _, p := range pins { - c := p.Path().Cid() + c := p.Path().RootCid() if cSet.Has(c) { cSet.Remove(c) } else { @@ -480,7 +487,7 @@ func assertPinCids(t *testing.T, pins []iface.Pin, cids ...cidContainer) { if !valid { pinStrs := make([]string, len(pins)) for i, p := range pins { - pinStrs[i] = p.Path().Cid().String() + pinStrs[i] = p.Path().RootCid().String() } pathStrs := make([]string, len(cids)) for i, c := range cids { @@ -511,13 +518,13 @@ func assertPinLsAllConsistency(t *testing.T, ctx context.Context, api iface.Core } for _, p := range allPins { - if !all.Visit(p.Path().Cid()) { + if !all.Visit(p.Path().RootCid()) { t.Fatalf("pin ls returned the same cid multiple times") } typeStr := p.Type() if typeSet, ok := typeMap[p.Type()]; ok { - typeSet.Add(p.Path().Cid()) + typeSet.Add(p.Path().RootCid()) } else { t.Fatalf("unknown pin type: %s", typeStr) } @@ -538,7 +545,7 @@ func assertPinLsAllConsistency(t *testing.T, ctx context.Context, api iface.Core t.Fatalf("returned wrong pin type: expected %s, got %s", typeStr, pinType) } - if c := p.Path().Cid(); !pinProps.Has(c) { + if c := p.Path().RootCid(); !pinProps.Has(c) { t.Fatalf("%s expected to be in pin ls all as type %s", c.String(), typeStr) } } diff --git a/core/coreiface/tests/routing.go b/core/coreiface/tests/routing.go index fd10dffcd..c56e91659 100644 --- a/core/coreiface/tests/routing.go +++ b/core/coreiface/tests/routing.go @@ -7,8 +7,8 @@ import ( iface "github.com/ipfs/boxo/coreiface" "github.com/ipfs/boxo/coreiface/options" - "github.com/ipfs/boxo/coreiface/path" "github.com/ipfs/boxo/ipns" + "github.com/ipfs/boxo/path" "github.com/stretchr/testify/require" ) diff --git a/core/coreiface/tests/unixfs.go b/core/coreiface/tests/unixfs.go index 25c3ac1b7..e0c37fce4 100644 --- a/core/coreiface/tests/unixfs.go +++ b/core/coreiface/tests/unixfs.go @@ -14,10 +14,9 @@ import ( "sync" "testing" - "github.com/ipfs/boxo/coreiface/path" - coreiface "github.com/ipfs/boxo/coreiface" "github.com/ipfs/boxo/coreiface/options" + "github.com/ipfs/boxo/path" "github.com/ipfs/boxo/files" mdag "github.com/ipfs/boxo/ipld/merkledag" @@ -106,12 +105,12 @@ func (tp *TestSuite) TestAdd(t *testing.T) { t.Fatal(err) } - p := func(h string) path.Resolved { + p := func(h string) path.ImmutablePath { c, err := cid.Parse(h) if err != nil { t.Fatal(err) } - return path.IpfsPath(c) + return path.FromCid(c) } rf, err := os.CreateTemp(os.TempDir(), "unixfs-add-real") @@ -410,7 +409,7 @@ func (tp *TestSuite) TestAdd(t *testing.T) { } if expected[0].Path != nil && event.Path != nil { - if expected[0].Path.Cid().String() != event.Path.Cid().String() { + if expected[0].Path.RootCid().String() != event.Path.RootCid().String() { t.Errorf("Event.Hash didn't match, %s != %s", expected[0].Path, event.Path) } } else if event.Path != expected[0].Path { @@ -553,7 +552,7 @@ func (tp *TestSuite) TestAddPinned(t *testing.T) { t.Fatalf("expected 1 pin, got %d", len(pins)) } - if pins[0].Path().String() != "/ipld/QmQy2Dw4Wk7rdJKjThjYXzfFJNaRKRHhHP5gHHXroJMYxk" { + if pins[0].Path().String() != "/ipfs/QmQy2Dw4Wk7rdJKjThjYXzfFJNaRKRHhHP5gHHXroJMYxk" { t.Fatalf("got unexpected pin: %s", pins[0].Path().String()) } } @@ -597,7 +596,10 @@ func (tp *TestSuite) TestGetEmptyFile(t *testing.T) { t.Fatal(err) } - emptyFilePath := path.New(emptyFile) + emptyFilePath, err := path.NewPath(emptyFile) + if err != nil { + t.Fatal(err) + } r, err := api.Unixfs().Get(ctx, emptyFilePath) if err != nil { @@ -626,18 +628,18 @@ func (tp *TestSuite) TestGetDir(t *testing.T) { if err != nil { t.Fatal(err) } - p := path.IpfsPath(edir.Cid()) + p := path.FromCid(edir.Cid()) emptyDir, err := api.Object().New(ctx, options.Object.Type("unixfs-dir")) if err != nil { t.Fatal(err) } - if p.String() != path.IpfsPath(emptyDir.Cid()).String() { + if p.String() != path.FromCid(emptyDir.Cid()).String() { t.Fatalf("expected path %s, got: %s", emptyDir.Cid(), p.String()) } - r, err := api.Unixfs().Get(ctx, path.IpfsPath(emptyDir.Cid())) + r, err := api.Unixfs().Get(ctx, path.FromCid(emptyDir.Cid())) if err != nil { t.Fatal(err) } @@ -661,7 +663,7 @@ func (tp *TestSuite) TestGetNonUnixfs(t *testing.T) { t.Fatal(err) } - _, err = api.Unixfs().Get(ctx, path.IpfsPath(nd.Cid())) + _, err = api.Unixfs().Get(ctx, path.FromCid(nd.Cid())) if !strings.Contains(err.Error(), "proto: required field") { t.Fatalf("expected protobuf error, got: %s", err) } @@ -787,7 +789,7 @@ func (tp *TestSuite) TestLsEmptyDir(t *testing.T) { t.Fatal(err) } - links, err := api.Unixfs().Ls(ctx, path.IpfsPath(emptyDir.Cid())) + links, err := api.Unixfs().Ls(ctx, path.FromCid(emptyDir.Cid())) if err != nil { t.Fatal(err) } @@ -816,7 +818,7 @@ func (tp *TestSuite) TestLsNonUnixfs(t *testing.T) { t.Fatal(err) } - links, err := api.Unixfs().Ls(ctx, path.IpfsPath(nd.Cid())) + links, err := api.Unixfs().Ls(ctx, path.FromCid(nd.Cid())) if err != nil { t.Fatal(err) } diff --git a/core/coreiface/unixfs.go b/core/coreiface/unixfs.go index 606bc8e78..35e108c02 100644 --- a/core/coreiface/unixfs.go +++ b/core/coreiface/unixfs.go @@ -4,17 +4,16 @@ import ( "context" "github.com/ipfs/boxo/coreiface/options" - path "github.com/ipfs/boxo/coreiface/path" - "github.com/ipfs/boxo/files" + "github.com/ipfs/boxo/path" "github.com/ipfs/go-cid" ) type AddEvent struct { Name string - Path path.Resolved `json:",omitempty"` - Bytes int64 `json:",omitempty"` - Size string `json:",omitempty"` + Path path.ImmutablePath `json:",omitempty"` + Bytes int64 `json:",omitempty"` + Size string `json:",omitempty"` } // FileType is an enum of possible UnixFS file types. @@ -66,7 +65,7 @@ type UnixfsAPI interface { // Add imports the data from the reader into merkledag file // // TODO: a long useful comment on how to use this for many different scenarios - Add(context.Context, files.Node, ...options.UnixfsAddOption) (path.Resolved, error) + Add(context.Context, files.Node, ...options.UnixfsAddOption) (path.ImmutablePath, error) // Get returns a read-only handle to a file tree referenced by a path // From a7c65184976e8717ac23d7efaa5b0d477ad15deb Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Fri, 6 Oct 2023 16:14:44 +0200 Subject: [PATCH 0903/1212] feat: path consolidation (#10063) --- assets/assets.go | 6 +- client/rpc/api_test.go | 14 +++- client/rpc/apifile.go | 8 +- client/rpc/block.go | 6 +- client/rpc/dag.go | 12 +-- client/rpc/dht.go | 10 +-- client/rpc/key.go | 76 ++++++++++++------- client/rpc/name.go | 10 ++- client/rpc/object.go | 26 +++---- client/rpc/path.go | 28 +++---- client/rpc/pin.go | 12 +-- client/rpc/unixfs.go | 8 +- cmd/ipfs/add_migrations.go | 6 +- cmd/ipfs/init.go | 2 +- core/commands/add.go | 4 +- core/commands/block.go | 31 ++++++-- core/commands/cat.go | 11 ++- core/commands/cmdutils/utils.go | 17 +++++ core/commands/dag/dag.go | 4 +- core/commands/dag/get.go | 16 ++-- core/commands/dag/resolve.go | 14 +++- core/commands/dag/stat.go | 14 ++-- core/commands/dns.go | 4 +- core/commands/files.go | 9 ++- core/commands/get.go | 7 +- core/commands/ls.go | 9 ++- core/commands/name/ipns.go | 13 +++- core/commands/name/name.go | 9 +-- core/commands/name/publish.go | 7 +- core/commands/object/diff.go | 17 +++-- core/commands/object/object.go | 30 ++++++-- core/commands/object/patch.go | 44 +++++++---- core/commands/pin/pin.go | 49 +++++++++--- core/commands/pin/remotepin.go | 13 +++- core/commands/refs.go | 10 ++- core/commands/resolve.go | 34 ++++++--- core/commands/routing.go | 7 +- core/commands/tar.go | 9 ++- core/commands/unixfs/ls.go | 9 ++- core/commands/urlstore.go | 2 +- core/coreapi/block.go | 22 +++--- core/coreapi/dht.go | 10 +-- core/coreapi/key.go | 46 ++++++++--- core/coreapi/name.go | 12 +-- core/coreapi/object.go | 38 +++++----- core/coreapi/path.go | 59 +++++++------- core/coreapi/pin.go | 28 +++---- core/coreapi/routing.go | 6 +- core/coreapi/test/path_test.go | 13 +++- core/coreapi/unixfs.go | 6 +- core/corehttp/commands.go | 3 +- core/corehttp/gateway.go | 16 ++-- core/corehttp/gateway_test.go | 2 +- core/coreunix/add.go | 4 +- core/coreunix/add_test.go | 8 +- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 +- docs/examples/kubo-as-a-library/main.go | 6 +- fuse/ipns/common.go | 2 +- fuse/ipns/ipns_unix.go | 6 +- fuse/readonly/ipfs_test.go | 22 +++--- fuse/readonly/readonly_unix.go | 12 ++- go.mod | 2 +- go.sum | 4 +- .../migrations/ipfsfetcher/ipfsfetcher.go | 20 +++-- tar/format.go | 6 +- test/cli/gateway_test.go | 4 +- test/dependencies/go.mod | 2 +- test/dependencies/go.sum | 4 +- test/sharness/t0090-get.sh | 3 +- 70 files changed, 608 insertions(+), 381 deletions(-) diff --git a/assets/assets.go b/assets/assets.go index 9dff80e07..bb320b4fd 100644 --- a/assets/assets.go +++ b/assets/assets.go @@ -9,8 +9,8 @@ import ( "github.com/ipfs/kubo/core/coreapi" options "github.com/ipfs/boxo/coreiface/options" - "github.com/ipfs/boxo/coreiface/path" "github.com/ipfs/boxo/files" + "github.com/ipfs/boxo/path" cid "github.com/ipfs/go-cid" ) @@ -44,7 +44,7 @@ func addAssetList(nd *core.IpfsNode, l []string) (cid.Cid, error) { return cid.Cid{}, err } - basePath := path.IpfsPath(dirb.Cid()) + basePath := path.FromCid(dirb.Cid()) for _, p := range l { d, err := Asset.ReadFile(p) @@ -69,5 +69,5 @@ func addAssetList(nd *core.IpfsNode, l []string) (cid.Cid, error) { return cid.Cid{}, err } - return basePath.Cid(), nil + return basePath.RootCid(), nil } diff --git a/client/rpc/api_test.go b/client/rpc/api_test.go index 51f8cf89d..e2838cb16 100644 --- a/client/rpc/api_test.go +++ b/client/rpc/api_test.go @@ -12,8 +12,8 @@ import ( "time" iface "github.com/ipfs/boxo/coreiface" - "github.com/ipfs/boxo/coreiface/path" "github.com/ipfs/boxo/coreiface/tests" + "github.com/ipfs/boxo/path" "github.com/ipfs/kubo/test/cli/harness" ma "github.com/multiformats/go-multiaddr" "go.uber.org/multierr" @@ -70,7 +70,11 @@ func (np NodeProvider) MakeAPISwarm(t *testing.T, ctx context.Context, fullIdent apis[i] = api // empty node is pinned even with --empty-repo, we don't want that - emptyNode := path.New("/ipfs/QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn") + emptyNode, err := path.NewPath("/ipfs/QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn") + if err != nil { + return err + } + if err := api.Pin().Rm(ctx, emptyNode); err != nil { return err } @@ -126,7 +130,11 @@ func Test_NewURLApiWithClient_With_Headers(t *testing.T) { t.Fatal(err) } api.Headers.Set(headerToTest, expectedHeaderValue) - if err := api.Pin().Rm(context.Background(), path.New("/ipfs/QmS4ustL54uo8FzR9455qaxZwuMiUhyvMcX9Ba8nUH4uVv")); err != nil { + p, err := path.NewPath("/ipfs/QmS4ustL54uo8FzR9455qaxZwuMiUhyvMcX9Ba8nUH4uVv") + if err != nil { + t.Fatal(err) + } + if err := api.Pin().Rm(context.Background(), p); err != nil { t.Fatal(err) } } diff --git a/client/rpc/apifile.go b/client/rpc/apifile.go index 873a67b7b..7a54995b1 100644 --- a/client/rpc/apifile.go +++ b/client/rpc/apifile.go @@ -6,9 +6,9 @@ import ( "fmt" "io" - "github.com/ipfs/boxo/coreiface/path" "github.com/ipfs/boxo/files" unixfs "github.com/ipfs/boxo/ipld/unixfs" + "github.com/ipfs/boxo/path" "github.com/ipfs/go-cid" ) @@ -17,7 +17,7 @@ const forwardSeekLimit = 1 << 14 // 16k func (api *UnixfsAPI) Get(ctx context.Context, p path.Path) (files.Node, error) { if p.Mutable() { // use resolved path in case we are dealing with IPNS / MFS var err error - p, err = api.core().ResolvePath(ctx, p) + p, _, err = api.core().ResolvePath(ctx, p) if err != nil { return nil, err } @@ -195,13 +195,13 @@ func (it *apiIter) Next() bool { switch it.cur.Type { case unixfs.THAMTShard, unixfs.TMetadata, unixfs.TDirectory: - it.curFile, err = it.core.getDir(it.ctx, path.IpfsPath(c), int64(it.cur.Size)) + it.curFile, err = it.core.getDir(it.ctx, path.FromCid(c), int64(it.cur.Size)) if err != nil { it.err = err return false } case unixfs.TFile: - it.curFile, err = it.core.getFile(it.ctx, path.IpfsPath(c), int64(it.cur.Size)) + it.curFile, err = it.core.getFile(it.ctx, path.FromCid(c), int64(it.cur.Size)) if err != nil { it.err = err return false diff --git a/client/rpc/block.go b/client/rpc/block.go index 2b0048380..a5882a57e 100644 --- a/client/rpc/block.go +++ b/client/rpc/block.go @@ -8,7 +8,7 @@ import ( iface "github.com/ipfs/boxo/coreiface" caopts "github.com/ipfs/boxo/coreiface/options" - "github.com/ipfs/boxo/coreiface/path" + "github.com/ipfs/boxo/path" "github.com/ipfs/go-cid" mc "github.com/multiformats/go-multicodec" mh "github.com/multiformats/go-multihash" @@ -27,8 +27,8 @@ func (s *blockStat) Size() int { return s.BSize } -func (s *blockStat) Path() path.Resolved { - return path.IpldPath(s.cid) +func (s *blockStat) Path() path.ImmutablePath { + return path.FromCid(s.cid) } func (api *BlockAPI) Put(ctx context.Context, r io.Reader, opts ...caopts.BlockPutOption) (iface.BlockStat, error) { diff --git a/client/rpc/dag.go b/client/rpc/dag.go index f4c9be351..098a959d8 100644 --- a/client/rpc/dag.go +++ b/client/rpc/dag.go @@ -7,8 +7,8 @@ import ( "io" "github.com/ipfs/boxo/coreiface/options" - "github.com/ipfs/boxo/coreiface/path" - "github.com/ipfs/go-block-format" + "github.com/ipfs/boxo/path" + blocks "github.com/ipfs/go-block-format" "github.com/ipfs/go-cid" format "github.com/ipfs/go-ipld-format" multicodec "github.com/multiformats/go-multicodec" @@ -21,7 +21,7 @@ type ( ) func (api *HttpDagServ) Get(ctx context.Context, c cid.Cid) (format.Node, error) { - r, err := api.core().Block().Get(ctx, path.IpldPath(c)) + r, err := api.core().Block().Get(ctx, path.FromCid(c)) if err != nil { return nil, err } @@ -79,8 +79,8 @@ func (api *httpNodeAdder) add(ctx context.Context, nd format.Node, pin bool) err if err != nil { return err } - if !stat.Path().Cid().Equals(c) { - return fmt.Errorf("cids didn't match - local %s, remote %s", c.String(), stat.Path().Cid().String()) + if !stat.Path().RootCid().Equals(c) { + return fmt.Errorf("cids didn't match - local %s, remote %s", c.String(), stat.Path().RootCid().String()) } return nil } @@ -116,7 +116,7 @@ func (api *HttpDagServ) Pinning() format.NodeAdder { } func (api *HttpDagServ) Remove(ctx context.Context, c cid.Cid) error { - return api.core().Block().Rm(ctx, path.IpldPath(c)) // TODO: should we force rm? + return api.core().Block().Rm(ctx, path.FromCid(c)) // TODO: should we force rm? } func (api *HttpDagServ) RemoveMany(ctx context.Context, cids []cid.Cid) error { diff --git a/client/rpc/dht.go b/client/rpc/dht.go index ffdf39681..852c18976 100644 --- a/client/rpc/dht.go +++ b/client/rpc/dht.go @@ -5,7 +5,7 @@ import ( "encoding/json" caopts "github.com/ipfs/boxo/coreiface/options" - "github.com/ipfs/boxo/coreiface/path" + "github.com/ipfs/boxo/path" "github.com/libp2p/go-libp2p/core/peer" "github.com/libp2p/go-libp2p/core/routing" ) @@ -42,12 +42,12 @@ func (api *DhtAPI) FindProviders(ctx context.Context, p path.Path, opts ...caopt return nil, err } - rp, err := api.core().ResolvePath(ctx, p) + rp, _, err := api.core().ResolvePath(ctx, p) if err != nil { return nil, err } - resp, err := api.core().Request("dht/findprovs", rp.Cid().String()). + resp, err := api.core().Request("dht/findprovs", rp.RootCid().String()). Option("num-providers", options.NumProviders). Send(ctx) if err != nil { @@ -98,12 +98,12 @@ func (api *DhtAPI) Provide(ctx context.Context, p path.Path, opts ...caopts.DhtP return err } - rp, err := api.core().ResolvePath(ctx, p) + rp, _, err := api.core().ResolvePath(ctx, p) if err != nil { return err } - return api.core().Request("dht/provide", rp.Cid().String()). + return api.core().Request("dht/provide", rp.RootCid().String()). Option("recursive", options.Recursive). Exec(ctx, nil) } diff --git a/client/rpc/key.go b/client/rpc/key.go index 487c14c3d..40027aa46 100644 --- a/client/rpc/key.go +++ b/client/rpc/key.go @@ -6,31 +6,50 @@ import ( iface "github.com/ipfs/boxo/coreiface" caopts "github.com/ipfs/boxo/coreiface/options" - "github.com/ipfs/boxo/coreiface/path" + "github.com/ipfs/boxo/ipns" + "github.com/ipfs/boxo/path" "github.com/libp2p/go-libp2p/core/peer" ) type KeyAPI HttpApi -type keyOutput struct { - JName string `json:"Name"` - Id string - - pid peer.ID +type key struct { + name string + pid peer.ID + path path.Path } -func (k *keyOutput) Name() string { - return k.JName +func newKey(name, pidStr string) (*key, error) { + pid, err := peer.Decode(pidStr) + if err != nil { + return nil, err + } + + path, err := path.NewPath("/ipns/" + ipns.NameFromPeer(pid).String()) + if err != nil { + return nil, err + } + + return &key{name: name, pid: pid, path: path}, nil } -func (k *keyOutput) Path() path.Path { - return path.New("/ipns/" + k.Id) +func (k *key) Name() string { + return k.name } -func (k *keyOutput) ID() peer.ID { +func (k *key) Path() path.Path { + return k.path +} + +func (k *key) ID() peer.ID { return k.pid } +type keyOutput struct { + Name string + Id string +} + func (api *KeyAPI) Generate(ctx context.Context, name string, opts ...caopts.KeyGenerateOption) (iface.Key, error) { options, err := caopts.KeyGenerateOptions(opts...) if err != nil { @@ -45,8 +64,8 @@ func (api *KeyAPI) Generate(ctx context.Context, name string, opts ...caopts.Key if err != nil { return nil, err } - out.pid, err = peer.Decode(out.Id) - return &out, err + + return newKey(out.Name, out.Id) } func (api *KeyAPI) Rename(ctx context.Context, oldName string, newName string, opts ...caopts.KeyRenameOption) (iface.Key, bool, error) { @@ -68,25 +87,29 @@ func (api *KeyAPI) Rename(ctx context.Context, oldName string, newName string, o return nil, false, err } - id := &keyOutput{JName: out.Now, Id: out.Id} - id.pid, err = peer.Decode(id.Id) - return id, out.Overwrite, err + key, err := newKey(out.Now, out.Id) + if err != nil { + return nil, false, err + } + + return key, out.Overwrite, err } func (api *KeyAPI) List(ctx context.Context) ([]iface.Key, error) { - var out struct{ Keys []*keyOutput } + var out struct { + Keys []keyOutput + } if err := api.core().Request("key/list").Exec(ctx, &out); err != nil { return nil, err } res := make([]iface.Key, len(out.Keys)) for i, k := range out.Keys { - var err error - k.pid, err = peer.Decode(k.Id) + key, err := newKey(k.Name, k.Id) if err != nil { return nil, err } - res[i] = k + res[i] = key } return res, nil @@ -98,14 +121,13 @@ func (api *KeyAPI) Self(ctx context.Context) (iface.Key, error) { return nil, err } - var err error - out := keyOutput{JName: "self", Id: id.ID} - out.pid, err = peer.Decode(out.Id) - return &out, err + return newKey("self", id.ID) } func (api *KeyAPI) Remove(ctx context.Context, name string) (iface.Key, error) { - var out struct{ Keys []keyOutput } + var out struct { + Keys []keyOutput + } if err := api.core().Request("key/rm", name).Exec(ctx, &out); err != nil { return nil, err } @@ -113,9 +135,7 @@ func (api *KeyAPI) Remove(ctx context.Context, name string) (iface.Key, error) { return nil, errors.New("got unexpected number of keys back") } - var err error - out.Keys[0].pid, err = peer.Decode(out.Keys[0].Id) - return &out.Keys[0], err + return newKey(out.Keys[0].Name, out.Keys[0].Id) } func (api *KeyAPI) core() *HttpApi { diff --git a/client/rpc/name.go b/client/rpc/name.go index 5ad9d16cb..223b7a226 100644 --- a/client/rpc/name.go +++ b/client/rpc/name.go @@ -9,8 +9,8 @@ import ( iface "github.com/ipfs/boxo/coreiface" caopts "github.com/ipfs/boxo/coreiface/options" nsopts "github.com/ipfs/boxo/coreiface/options/namesys" - "github.com/ipfs/boxo/coreiface/path" "github.com/ipfs/boxo/ipns" + "github.com/ipfs/boxo/path" ) type NameAPI HttpApi @@ -84,7 +84,11 @@ func (api *NameAPI) Search(ctx context.Context, name string, opts ...caopts.Name } var ires iface.IpnsResult if err == nil { - ires.Path = path.New(out.Path) + p, err := path.NewPath(out.Path) + if err != nil { + return + } + ires.Path = p } select { @@ -122,7 +126,7 @@ func (api *NameAPI) Resolve(ctx context.Context, name string, opts ...caopts.Nam return nil, err } - return path.New(out.Path), nil + return path.NewPath(out.Path) } func (api *NameAPI) core() *HttpApi { diff --git a/client/rpc/object.go b/client/rpc/object.go index 7464cea1a..7296308a7 100644 --- a/client/rpc/object.go +++ b/client/rpc/object.go @@ -8,9 +8,9 @@ import ( iface "github.com/ipfs/boxo/coreiface" caopts "github.com/ipfs/boxo/coreiface/options" - "github.com/ipfs/boxo/coreiface/path" "github.com/ipfs/boxo/ipld/merkledag" ft "github.com/ipfs/boxo/ipld/unixfs" + "github.com/ipfs/boxo/path" "github.com/ipfs/go-cid" ipld "github.com/ipfs/go-ipld-format" ) @@ -40,7 +40,7 @@ func (api *ObjectAPI) New(ctx context.Context, opts ...caopts.ObjectNewOption) ( return n, nil } -func (api *ObjectAPI) Put(ctx context.Context, r io.Reader, opts ...caopts.ObjectPutOption) (path.Resolved, error) { +func (api *ObjectAPI) Put(ctx context.Context, r io.Reader, opts ...caopts.ObjectPutOption) (path.ImmutablePath, error) { options, err := caopts.ObjectPutOptions(opts...) if err != nil { return nil, err @@ -62,7 +62,7 @@ func (api *ObjectAPI) Put(ctx context.Context, r io.Reader, opts ...caopts.Objec return nil, err } - return path.IpfsPath(c), nil + return path.FromCid(c), nil } func (api *ObjectAPI) Get(ctx context.Context, p path.Path) (ipld.Node, error) { @@ -153,7 +153,7 @@ func (api *ObjectAPI) Stat(ctx context.Context, p path.Path) (*iface.ObjectStat, }, nil } -func (api *ObjectAPI) AddLink(ctx context.Context, base path.Path, name string, child path.Path, opts ...caopts.ObjectAddLinkOption) (path.Resolved, error) { +func (api *ObjectAPI) AddLink(ctx context.Context, base path.Path, name string, child path.Path, opts ...caopts.ObjectAddLinkOption) (path.ImmutablePath, error) { options, err := caopts.ObjectAddLinkOptions(opts...) if err != nil { return nil, err @@ -172,10 +172,10 @@ func (api *ObjectAPI) AddLink(ctx context.Context, base path.Path, name string, return nil, err } - return path.IpfsPath(c), nil + return path.FromCid(c), nil } -func (api *ObjectAPI) RmLink(ctx context.Context, base path.Path, link string) (path.Resolved, error) { +func (api *ObjectAPI) RmLink(ctx context.Context, base path.Path, link string) (path.ImmutablePath, error) { var out objectOut err := api.core().Request("object/patch/rm-link", base.String(), link). Exec(ctx, &out) @@ -188,10 +188,10 @@ func (api *ObjectAPI) RmLink(ctx context.Context, base path.Path, link string) ( return nil, err } - return path.IpfsPath(c), nil + return path.FromCid(c), nil } -func (api *ObjectAPI) AppendData(ctx context.Context, p path.Path, r io.Reader) (path.Resolved, error) { +func (api *ObjectAPI) AppendData(ctx context.Context, p path.Path, r io.Reader) (path.ImmutablePath, error) { var out objectOut err := api.core().Request("object/patch/append-data", p.String()). FileBody(r). @@ -205,10 +205,10 @@ func (api *ObjectAPI) AppendData(ctx context.Context, p path.Path, r io.Reader) return nil, err } - return path.IpfsPath(c), nil + return path.FromCid(c), nil } -func (api *ObjectAPI) SetData(ctx context.Context, p path.Path, r io.Reader) (path.Resolved, error) { +func (api *ObjectAPI) SetData(ctx context.Context, p path.Path, r io.Reader) (path.ImmutablePath, error) { var out objectOut err := api.core().Request("object/patch/set-data", p.String()). FileBody(r). @@ -222,7 +222,7 @@ func (api *ObjectAPI) SetData(ctx context.Context, p path.Path, r io.Reader) (pa return nil, err } - return path.IpfsPath(c), nil + return path.FromCid(c), nil } type change struct { @@ -246,10 +246,10 @@ func (api *ObjectAPI) Diff(ctx context.Context, a path.Path, b path.Path) ([]ifa Path: ch.Path, } if ch.Before != cid.Undef { - res[i].Before = path.IpfsPath(ch.Before) + res[i].Before = path.FromCid(ch.Before) } if ch.After != cid.Undef { - res[i].After = path.IpfsPath(ch.After) + res[i].After = path.FromCid(ch.After) } } return res, nil diff --git a/client/rpc/path.go b/client/rpc/path.go index 1b88eb07d..558203515 100644 --- a/client/rpc/path.go +++ b/client/rpc/path.go @@ -3,50 +3,46 @@ package rpc import ( "context" - "github.com/ipfs/boxo/coreiface/path" - ipfspath "github.com/ipfs/boxo/path" + "github.com/ipfs/boxo/path" cid "github.com/ipfs/go-cid" ipld "github.com/ipfs/go-ipld-format" ) -func (api *HttpApi) ResolvePath(ctx context.Context, p path.Path) (path.Resolved, error) { +func (api *HttpApi) ResolvePath(ctx context.Context, p path.Path) (path.ImmutablePath, []string, error) { var out struct { Cid cid.Cid RemPath string } - // TODO: this is hacky, fixing https://github.com/ipfs/go-ipfs/issues/5703 would help - var err error - if p.Namespace() == "ipns" { + if p.Namespace() == path.IPNSNamespace { if p, err = api.Name().Resolve(ctx, p.String()); err != nil { - return nil, err + return nil, nil, err } } if err := api.Request("dag/resolve", p.String()).Exec(ctx, &out); err != nil { - return nil, err + return nil, nil, err } - // TODO: - ipath, err := ipfspath.FromSegments("/"+p.Namespace()+"/", out.Cid.String(), out.RemPath) + p, err = path.NewPathFromSegments(p.Namespace(), out.Cid.String(), out.RemPath) if err != nil { - return nil, err + return nil, nil, err } - root, err := cid.Parse(ipfspath.Path(p.String()).Segments()[1]) + imPath, err := path.NewImmutablePath(p) if err != nil { - return nil, err + return nil, nil, err } - return path.NewResolvedPath(ipath, out.Cid, root, out.RemPath), nil + return imPath, path.StringToSegments(out.RemPath), nil } func (api *HttpApi) ResolveNode(ctx context.Context, p path.Path) (ipld.Node, error) { - rp, err := api.ResolvePath(ctx, p) + rp, _, err := api.ResolvePath(ctx, p) if err != nil { return nil, err } - return api.Dag().Get(ctx, rp.Cid()) + return api.Dag().Get(ctx, rp.RootCid()) } diff --git a/client/rpc/pin.go b/client/rpc/pin.go index e8aecf11c..486e5115b 100644 --- a/client/rpc/pin.go +++ b/client/rpc/pin.go @@ -8,7 +8,7 @@ import ( iface "github.com/ipfs/boxo/coreiface" caopts "github.com/ipfs/boxo/coreiface/options" - "github.com/ipfs/boxo/coreiface/path" + "github.com/ipfs/boxo/path" "github.com/ipfs/go-cid" "github.com/pkg/errors" ) @@ -24,7 +24,7 @@ type pinRefKeyList struct { } type pin struct { - path path.Resolved + path path.ImmutablePath typ string err error } @@ -33,7 +33,7 @@ func (p pin) Err() error { return p.err } -func (p pin) Path() path.Resolved { +func (p pin) Path() path.ImmutablePath { return p.path } @@ -102,7 +102,7 @@ func (api *PinAPI) Ls(ctx context.Context, opts ...caopts.PinLsOption) (<-chan i } select { - case ch <- pin{typ: out.Type, path: path.IpldPath(c)}: + case ch <- pin{typ: out.Type, path: path.FromCid(c)}: case <-ctx.Done(): return } @@ -182,8 +182,8 @@ type badNode struct { cid cid.Cid } -func (n badNode) Path() path.Resolved { - return path.IpldPath(n.cid) +func (n badNode) Path() path.ImmutablePath { + return path.FromCid(n.cid) } func (n badNode) Err() error { diff --git a/client/rpc/unixfs.go b/client/rpc/unixfs.go index e19deec22..077d3f5a6 100644 --- a/client/rpc/unixfs.go +++ b/client/rpc/unixfs.go @@ -9,10 +9,10 @@ import ( iface "github.com/ipfs/boxo/coreiface" caopts "github.com/ipfs/boxo/coreiface/options" - "github.com/ipfs/boxo/coreiface/path" "github.com/ipfs/boxo/files" unixfs "github.com/ipfs/boxo/ipld/unixfs" unixfs_pb "github.com/ipfs/boxo/ipld/unixfs/pb" + "github.com/ipfs/boxo/path" "github.com/ipfs/go-cid" mh "github.com/multiformats/go-multihash" ) @@ -26,7 +26,7 @@ type addEvent struct { type UnixfsAPI HttpApi -func (api *UnixfsAPI) Add(ctx context.Context, f files.Node, opts ...caopts.UnixfsAddOption) (path.Resolved, error) { +func (api *UnixfsAPI) Add(ctx context.Context, f files.Node, opts ...caopts.UnixfsAddOption) (path.ImmutablePath, error) { options, _, err := caopts.UnixfsAddOptions(opts...) if err != nil { return nil, err @@ -105,7 +105,7 @@ loop: return nil, err } - ifevt.Path = path.IpfsPath(c) + ifevt.Path = path.FromCid(c) } select { @@ -121,7 +121,7 @@ loop: return nil, err } - return path.IpfsPath(c), nil + return path.FromCid(c), nil } type lsLink struct { diff --git a/cmd/ipfs/add_migrations.go b/cmd/ipfs/add_migrations.go index e01381121..566158d0f 100644 --- a/cmd/ipfs/add_migrations.go +++ b/cmd/ipfs/add_migrations.go @@ -10,8 +10,8 @@ import ( coreiface "github.com/ipfs/boxo/coreiface" "github.com/ipfs/boxo/coreiface/options" - ipath "github.com/ipfs/boxo/coreiface/path" "github.com/ipfs/boxo/files" + "github.com/ipfs/boxo/path" "github.com/ipfs/kubo/core" "github.com/ipfs/kubo/core/coreapi" "github.com/ipfs/kubo/repo/fsrepo/migrations" @@ -98,7 +98,7 @@ func addMigrationFiles(ctx context.Context, node *core.IpfsNode, paths []string, // addMigrationPaths adds the files at paths to IPFS, optionally pinning // them. This is done after connecting to the peer. -func addMigrationPaths(ctx context.Context, node *core.IpfsNode, peerInfo peer.AddrInfo, paths []ipath.Path, pin bool) error { +func addMigrationPaths(ctx context.Context, node *core.IpfsNode, peerInfo peer.AddrInfo, paths []path.Path, pin bool) error { if len(paths) == 0 { return errors.New("nothing downloaded by ipfs fetcher") } @@ -142,7 +142,7 @@ func addMigrationPaths(ctx context.Context, node *core.IpfsNode, peerInfo peer.A return nil } -func ipfsGet(ctx context.Context, ufs coreiface.UnixfsAPI, ipfsPath ipath.Path) error { +func ipfsGet(ctx context.Context, ufs coreiface.UnixfsAPI, ipfsPath path.Path) error { nd, err := ufs.Get(ctx, ipfsPath) if err != nil { return err diff --git a/cmd/ipfs/init.go b/cmd/ipfs/init.go index 0c5223d7f..6d03b12c9 100644 --- a/cmd/ipfs/init.go +++ b/cmd/ipfs/init.go @@ -11,7 +11,7 @@ import ( "strings" unixfs "github.com/ipfs/boxo/ipld/unixfs" - path "github.com/ipfs/boxo/path" + "github.com/ipfs/boxo/path" assets "github.com/ipfs/kubo/assets" oldcmds "github.com/ipfs/kubo/commands" core "github.com/ipfs/kubo/core" diff --git a/core/commands/add.go b/core/commands/add.go index fa78d7074..eb855fe93 100644 --- a/core/commands/add.go +++ b/core/commands/add.go @@ -317,7 +317,7 @@ See 'dag export' and 'dag import' for more information. } var nodeAdded ipld.Node - nodeAdded, err = api.Dag().Get(req.Context, pathAdded.Cid()) + nodeAdded, err = api.Dag().Get(req.Context, pathAdded.RootCid()) if err != nil { errCh <- err return @@ -340,7 +340,7 @@ See 'dag export' and 'dag import' for more information. h := "" if output.Path != nil { - h = enc.Encode(output.Path.Cid()) + h = enc.Encode(output.Path.RootCid()) } if !dir && addit.Name() != "" { diff --git a/core/commands/block.go b/core/commands/block.go index 4ad191554..103addcaf 100644 --- a/core/commands/block.go +++ b/core/commands/block.go @@ -12,7 +12,7 @@ import ( "github.com/ipfs/kubo/core/commands/cmdutils" options "github.com/ipfs/boxo/coreiface/options" - path "github.com/ipfs/boxo/coreiface/path" + cmds "github.com/ipfs/go-ipfs-cmds" mh "github.com/multiformats/go-multihash" ) @@ -66,13 +66,18 @@ on raw IPFS blocks. It outputs the following to stdout: return err } - b, err := api.Block().Stat(req.Context, path.New(req.Arguments[0])) + p, err := cmdutils.PathOrCidPath(req.Arguments[0]) + if err != nil { + return err + } + + b, err := api.Block().Stat(req.Context, p) if err != nil { return err } return cmds.EmitOnce(res, &BlockStat{ - Key: b.Path().Cid().String(), + Key: b.Path().RootCid().String(), Size: b.Size(), }) }, @@ -103,7 +108,12 @@ It takes a , and outputs the block to stdout. return err } - r, err := api.Block().Get(req.Context, path.New(req.Arguments[0])) + p, err := cmdutils.PathOrCidPath(req.Arguments[0]) + if err != nil { + return err + } + + r, err := api.Block().Get(req.Context, p) if err != nil { return err } @@ -200,7 +210,7 @@ only for backward compatibility when a legacy CIDv0 is required (--format=v0). } err = res.Emit(&BlockStat{ - Key: p.Path().Cid().String(), + Key: p.Path().RootCid().String(), Size: p.Size(), }) if err != nil { @@ -255,7 +265,12 @@ It takes a list of CIDs to remove from the local datastore.. // TODO: use batching coreapi when done for _, b := range req.Arguments { - rp, err := api.ResolvePath(req.Context, path.New(b)) + p, err := cmdutils.PathOrCidPath(b) + if err != nil { + return err + } + + rp, _, err := api.ResolvePath(req.Context, p) if err != nil { return err } @@ -263,7 +278,7 @@ It takes a list of CIDs to remove from the local datastore.. err = api.Block().Rm(req.Context, rp, options.Block.Force(force)) if err != nil { if err := res.Emit(&removedBlock{ - Hash: rp.Cid().String(), + Hash: rp.RootCid().String(), Error: err.Error(), }); err != nil { return err @@ -273,7 +288,7 @@ It takes a list of CIDs to remove from the local datastore.. if !quiet { err := res.Emit(&removedBlock{ - Hash: rp.Cid().String(), + Hash: rp.RootCid().String(), }) if err != nil { return err diff --git a/core/commands/cat.go b/core/commands/cat.go index 92b045235..79e78cc77 100644 --- a/core/commands/cat.go +++ b/core/commands/cat.go @@ -7,10 +7,10 @@ import ( "os" "github.com/ipfs/kubo/core/commands/cmdenv" + "github.com/ipfs/kubo/core/commands/cmdutils" "github.com/cheggaaa/pb" iface "github.com/ipfs/boxo/coreiface" - "github.com/ipfs/boxo/coreiface/path" "github.com/ipfs/boxo/files" cmds "github.com/ipfs/go-ipfs-cmds" ) @@ -127,8 +127,13 @@ func cat(ctx context.Context, api iface.CoreAPI, paths []string, offset int64, m if max == 0 { return nil, 0, nil } - for _, p := range paths { - f, err := api.Unixfs().Get(ctx, path.New(p)) + for _, pString := range paths { + p, err := cmdutils.PathOrCidPath(pString) + if err != nil { + return nil, 0, err + } + + f, err := api.Unixfs().Get(ctx, p) if err != nil { return nil, 0, err } diff --git a/core/commands/cmdutils/utils.go b/core/commands/cmdutils/utils.go index 954f476b6..87ddb9655 100644 --- a/core/commands/cmdutils/utils.go +++ b/core/commands/cmdutils/utils.go @@ -6,6 +6,7 @@ import ( cmds "github.com/ipfs/go-ipfs-cmds" coreiface "github.com/ipfs/boxo/coreiface" + "github.com/ipfs/boxo/path" "github.com/ipfs/go-cid" ) @@ -48,3 +49,19 @@ func CheckBlockSize(req *cmds.Request, size uint64) error { } return nil } + +// PathOrCidPath returns a path.Path built from the argument. It keeps the old +// behaviour by building a path from a CID string. +func PathOrCidPath(str string) (path.Path, error) { + p, err := path.NewPath(str) + if err == nil { + return p, nil + } + + if p, err := path.NewPath("/ipfs/" + str); err == nil { + return p, nil + } + + // Send back original err. + return nil, err +} diff --git a/core/commands/dag/dag.go b/core/commands/dag/dag.go index 07851eb31..56aae4105 100644 --- a/core/commands/dag/dag.go +++ b/core/commands/dag/dag.go @@ -5,11 +5,11 @@ import ( "encoding/json" "fmt" "io" + "path" "github.com/ipfs/kubo/core/commands/cmdenv" "github.com/ipfs/kubo/core/commands/cmdutils" - ipfspath "github.com/ipfs/boxo/path" cid "github.com/ipfs/go-cid" cidenc "github.com/ipfs/go-cidutil/cidenc" cmds "github.com/ipfs/go-ipfs-cmds" @@ -157,7 +157,7 @@ var DagResolveCmd = &cmds.Command{ } p := enc.Encode(out.Cid) if out.RemPath != "" { - p = ipfspath.Join([]string{p, out.RemPath}) + p = path.Join(p, out.RemPath) } fmt.Fprint(w, p) diff --git a/core/commands/dag/get.go b/core/commands/dag/get.go index 1252293a8..d15d2b69e 100644 --- a/core/commands/dag/get.go +++ b/core/commands/dag/get.go @@ -4,9 +4,10 @@ import ( "fmt" "io" - "github.com/ipfs/boxo/coreiface/path" + "github.com/ipfs/boxo/path" ipldlegacy "github.com/ipfs/go-ipld-legacy" "github.com/ipfs/kubo/core/commands/cmdenv" + "github.com/ipfs/kubo/core/commands/cmdutils" "github.com/ipld/go-ipld-prime" "github.com/ipld/go-ipld-prime/multicodec" @@ -28,12 +29,17 @@ func dagGet(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) e return err } - rp, err := api.ResolvePath(req.Context, path.New(req.Arguments[0])) + p, err := cmdutils.PathOrCidPath(req.Arguments[0]) if err != nil { return err } - obj, err := api.Dag().Get(req.Context, rp.Cid()) + rp, remainder, err := api.ResolvePath(req.Context, p) + if err != nil { + return err + } + + obj, err := api.Dag().Get(req.Context, rp.RootCid()) if err != nil { return err } @@ -45,8 +51,8 @@ func dagGet(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) e finalNode := universal.(ipld.Node) - if len(rp.Remainder()) > 0 { - remainderPath := ipld.ParsePath(rp.Remainder()) + if len(remainder) > 0 { + remainderPath := ipld.ParsePath(path.SegmentsToString(remainder...)) finalNode, err = traversal.Get(finalNode, remainderPath) if err != nil { diff --git a/core/commands/dag/resolve.go b/core/commands/dag/resolve.go index 0f252be9d..f8a4b36cd 100644 --- a/core/commands/dag/resolve.go +++ b/core/commands/dag/resolve.go @@ -1,8 +1,9 @@ package dagcmd import ( - "github.com/ipfs/boxo/coreiface/path" + "github.com/ipfs/boxo/path" "github.com/ipfs/kubo/core/commands/cmdenv" + "github.com/ipfs/kubo/core/commands/cmdutils" cmds "github.com/ipfs/go-ipfs-cmds" ) @@ -13,13 +14,18 @@ func dagResolve(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environmen return err } - rp, err := api.ResolvePath(req.Context, path.New(req.Arguments[0])) + p, err := cmdutils.PathOrCidPath(req.Arguments[0]) + if err != nil { + return err + } + + rp, remainder, err := api.ResolvePath(req.Context, p) if err != nil { return err } return cmds.EmitOnce(res, &ResolveOutput{ - Cid: rp.Cid(), - RemPath: rp.Remainder(), + Cid: rp.RootCid(), + RemPath: path.SegmentsToString(remainder...), }) } diff --git a/core/commands/dag/stat.go b/core/commands/dag/stat.go index 23f4ab481..bb9be7e0d 100644 --- a/core/commands/dag/stat.go +++ b/core/commands/dag/stat.go @@ -5,12 +5,12 @@ import ( "io" "os" - "github.com/ipfs/boxo/coreiface/path" mdag "github.com/ipfs/boxo/ipld/merkledag" "github.com/ipfs/boxo/ipld/merkledag/traverse" cid "github.com/ipfs/go-cid" cmds "github.com/ipfs/go-ipfs-cmds" "github.com/ipfs/kubo/core/commands/cmdenv" + "github.com/ipfs/kubo/core/commands/cmdutils" "github.com/ipfs/kubo/core/commands/e" ) @@ -29,19 +29,23 @@ func dagStat(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) cidSet := cid.NewSet() dagStatSummary := &DagStatSummary{DagStatsArray: []*DagStat{}} for _, a := range req.Arguments { - rp, err := api.ResolvePath(req.Context, path.New(a)) + p, err := cmdutils.PathOrCidPath(a) if err != nil { return err } - if len(rp.Remainder()) > 0 { + rp, remainder, err := api.ResolvePath(req.Context, p) + if err != nil { + return err + } + if len(remainder) > 0 { return fmt.Errorf("cannot return size for anything other than a DAG with a root CID") } - obj, err := nodeGetter.Get(req.Context, rp.Cid()) + obj, err := nodeGetter.Get(req.Context, rp.RootCid()) if err != nil { return err } - dagstats := &DagStat{Cid: rp.Cid()} + dagstats := &DagStat{Cid: rp.RootCid()} dagStatSummary.appendStats(dagstats) err = traverse.Traverse(obj, traverse.Options{ DAG: nodeGetter, diff --git a/core/commands/dns.go b/core/commands/dns.go index fda0cb6c3..8ab76e64d 100644 --- a/core/commands/dns.go +++ b/core/commands/dns.go @@ -56,11 +56,11 @@ It will work across multiple DNSLinks and IPNS keys. if err != nil && (recursive || err != namesys.ErrResolveRecursion) { return err } - return cmds.EmitOnce(res, &ncmd.ResolvedPath{Path: output}) + return cmds.EmitOnce(res, &ncmd.ResolvedPath{Path: output.String()}) }, Encoders: cmds.EncoderMap{ cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *ncmd.ResolvedPath) error { - fmt.Fprintln(w, cmdenv.EscNonPrint(out.Path.String())) + fmt.Fprintln(w, cmdenv.EscNonPrint(out.Path)) return nil }), }, diff --git a/core/commands/files.go b/core/commands/files.go index ce1cf1cfc..73ce9c826 100644 --- a/core/commands/files.go +++ b/core/commands/files.go @@ -16,11 +16,11 @@ import ( bservice "github.com/ipfs/boxo/blockservice" iface "github.com/ipfs/boxo/coreiface" - path "github.com/ipfs/boxo/coreiface/path" offline "github.com/ipfs/boxo/exchange/offline" dag "github.com/ipfs/boxo/ipld/merkledag" ft "github.com/ipfs/boxo/ipld/unixfs" mfs "github.com/ipfs/boxo/mfs" + "github.com/ipfs/boxo/path" cid "github.com/ipfs/go-cid" cidenc "github.com/ipfs/go-cidutil/cidenc" cmds "github.com/ipfs/go-ipfs-cmds" @@ -423,7 +423,12 @@ being GC'ed. func getNodeFromPath(ctx context.Context, node *core.IpfsNode, api iface.CoreAPI, p string) (ipld.Node, error) { switch { case strings.HasPrefix(p, "/ipfs/"): - return api.ResolveNode(ctx, path.New(p)) + pth, err := path.NewPath(p) + if err != nil { + return nil, err + } + + return api.ResolveNode(ctx, pth) default: fsn, err := mfs.Lookup(node.FilesRoot, p) if err != nil { diff --git a/core/commands/get.go b/core/commands/get.go index 35cd45c9d..5b64c281b 100644 --- a/core/commands/get.go +++ b/core/commands/get.go @@ -12,10 +12,10 @@ import ( "strings" "github.com/ipfs/kubo/core/commands/cmdenv" + "github.com/ipfs/kubo/core/commands/cmdutils" "github.com/ipfs/kubo/core/commands/e" "github.com/cheggaaa/pb" - "github.com/ipfs/boxo/coreiface/path" "github.com/ipfs/boxo/files" "github.com/ipfs/boxo/tar" cmds "github.com/ipfs/go-ipfs-cmds" @@ -72,7 +72,10 @@ may also specify the level of compression by specifying '-l=<1-9>'. return err } - p := path.New(req.Arguments[0]) + p, err := cmdutils.PathOrCidPath(req.Arguments[0]) + if err != nil { + return err + } file, err := api.Unixfs().Get(ctx, p) if err != nil { diff --git a/core/commands/ls.go b/core/commands/ls.go index 10d378562..ee360796f 100644 --- a/core/commands/ls.go +++ b/core/commands/ls.go @@ -8,10 +8,10 @@ import ( "text/tabwriter" cmdenv "github.com/ipfs/kubo/core/commands/cmdenv" + "github.com/ipfs/kubo/core/commands/cmdutils" iface "github.com/ipfs/boxo/coreiface" options "github.com/ipfs/boxo/coreiface/options" - path "github.com/ipfs/boxo/coreiface/path" unixfs "github.com/ipfs/boxo/ipld/unixfs" unixfs_pb "github.com/ipfs/boxo/ipld/unixfs/pb" cmds "github.com/ipfs/go-ipfs-cmds" @@ -131,7 +131,12 @@ The JSON output contains type information. } for i, fpath := range paths { - results, err := api.Unixfs().Ls(req.Context, path.New(fpath), + pth, err := cmdutils.PathOrCidPath(fpath) + if err != nil { + return err + } + + results, err := api.Unixfs().Ls(req.Context, pth, options.Unixfs.ResolveChildren(resolveSize || resolveType)) if err != nil { return err diff --git a/core/commands/name/ipns.go b/core/commands/name/ipns.go index b5c7fd7e3..a305c49ad 100644 --- a/core/commands/name/ipns.go +++ b/core/commands/name/ipns.go @@ -12,7 +12,7 @@ import ( options "github.com/ipfs/boxo/coreiface/options" nsopts "github.com/ipfs/boxo/coreiface/options/namesys" - path "github.com/ipfs/boxo/path" + "github.com/ipfs/boxo/path" cmds "github.com/ipfs/go-ipfs-cmds" logging "github.com/ipfs/go-log" ) @@ -20,7 +20,7 @@ import ( var log = logging.Logger("core/commands/ipns") type ResolvedPath struct { - Path path.Path + Path string } const ( @@ -134,7 +134,12 @@ Resolve the value of a dnslink: return err } - return cmds.EmitOnce(res, &ResolvedPath{path.FromString(output.String())}) + pth, err := path.NewPath(output.String()) + if err != nil { + return err + } + + return cmds.EmitOnce(res, &ResolvedPath{pth.String()}) } output, err := api.Name().Search(req.Context, name, opts...) @@ -146,7 +151,7 @@ Resolve the value of a dnslink: if v.Err != nil && (recursive || v.Err != namesys.ErrResolveRecursion) { return v.Err } - if err := res.Emit(&ResolvedPath{path.FromString(v.Path.String())}); err != nil { + if err := res.Emit(&ResolvedPath{v.Path.String()}); err != nil { return err } diff --git a/core/commands/name/name.go b/core/commands/name/name.go index 3bcb5c8e4..37ab4df53 100644 --- a/core/commands/name/name.go +++ b/core/commands/name/name.go @@ -10,7 +10,6 @@ import ( "github.com/ipfs/boxo/ipns" ipns_pb "github.com/ipfs/boxo/ipns/pb" - "github.com/ipfs/boxo/path" cmds "github.com/ipfs/go-ipfs-cmds" cmdenv "github.com/ipfs/kubo/core/commands/cmdenv" "google.golang.org/protobuf/proto" @@ -87,7 +86,7 @@ type IpnsInspectValidation struct { // IpnsInspectEntry contains the deserialized values from an IPNS Entry: // https://github.com/ipfs/specs/blob/main/ipns/IPNS.md#record-serialization-format type IpnsInspectEntry struct { - Value *path.Path + Value string ValidityType *ipns.ValidityType Validity *time.Time Sequence *uint64 @@ -157,7 +156,7 @@ Passing --verify will verify signature against provided public key. // Best effort to get the fields. Show everything we can. if v, err := rec.Value(); err == nil { - result.Entry.Value = &v + result.Entry.Value = v.String() } if v, err := rec.ValidityType(); err == nil { @@ -221,8 +220,8 @@ Passing --verify will verify signature against provided public key. tw := tabwriter.NewWriter(w, 0, 0, 1, ' ', 0) defer tw.Flush() - if out.Entry.Value != nil { - fmt.Fprintf(tw, "Value:\t%q\n", out.Entry.Value.String()) + if out.Entry.Value != "" { + fmt.Fprintf(tw, "Value:\t%q\n", out.Entry.Value) } if out.Entry.ValidityType != nil { diff --git a/core/commands/name/publish.go b/core/commands/name/publish.go index 6cc51df14..a817d52f9 100644 --- a/core/commands/name/publish.go +++ b/core/commands/name/publish.go @@ -7,10 +7,10 @@ import ( "time" cmdenv "github.com/ipfs/kubo/core/commands/cmdenv" + "github.com/ipfs/kubo/core/commands/cmdutils" iface "github.com/ipfs/boxo/coreiface" options "github.com/ipfs/boxo/coreiface/options" - path "github.com/ipfs/boxo/coreiface/path" cmds "github.com/ipfs/go-ipfs-cmds" ke "github.com/ipfs/kubo/core/commands/keyencode" ) @@ -116,7 +116,10 @@ Alternatively, publish an using a valid PeerID (as listed by opts = append(opts, options.Name.TTL(d)) } - p := path.New(req.Arguments[0]) + p, err := cmdutils.PathOrCidPath(req.Arguments[0]) + if err != nil { + return err + } if verifyExists, _ := req.Options[resolveOptionName].(bool); verifyExists { _, err := api.ResolveNode(req.Context, p) diff --git a/core/commands/object/diff.go b/core/commands/object/diff.go index fca026ac1..882fb63e1 100644 --- a/core/commands/object/diff.go +++ b/core/commands/object/diff.go @@ -4,11 +4,11 @@ import ( "fmt" "io" - path "github.com/ipfs/boxo/coreiface/path" "github.com/ipfs/boxo/ipld/merkledag/dagutils" cmds "github.com/ipfs/go-ipfs-cmds" cmdenv "github.com/ipfs/kubo/core/commands/cmdenv" + "github.com/ipfs/kubo/core/commands/cmdutils" ) const ( @@ -60,8 +60,15 @@ Example: return err } - pa := path.New(req.Arguments[0]) - pb := path.New(req.Arguments[1]) + pa, err := cmdutils.PathOrCidPath(req.Arguments[0]) + if err != nil { + return err + } + + pb, err := cmdutils.PathOrCidPath(req.Arguments[1]) + if err != nil { + return err + } changes, err := api.Object().Diff(req.Context, pa, pb) if err != nil { @@ -76,11 +83,11 @@ Example: } if change.Before != nil { - out[i].Before = change.Before.Cid() + out[i].Before = change.Before.RootCid() } if change.After != nil { - out[i].After = change.After.Cid() + out[i].After = change.After.RootCid() } } diff --git a/core/commands/object/object.go b/core/commands/object/object.go index febcf3470..8024edfe3 100644 --- a/core/commands/object/object.go +++ b/core/commands/object/object.go @@ -9,10 +9,10 @@ import ( cmds "github.com/ipfs/go-ipfs-cmds" "github.com/ipfs/kubo/core/commands/cmdenv" + "github.com/ipfs/kubo/core/commands/cmdutils" humanize "github.com/dustin/go-humanize" "github.com/ipfs/boxo/coreiface/options" - path "github.com/ipfs/boxo/coreiface/path" dag "github.com/ipfs/boxo/ipld/merkledag" "github.com/ipfs/go-cid" ipld "github.com/ipfs/go-ipld-format" @@ -95,7 +95,10 @@ is the raw data of the object. return err } - path := path.New(req.Arguments[0]) + path, err := cmdutils.PathOrCidPath(req.Arguments[0]) + if err != nil { + return err + } data, err := api.Object().Data(req.Context, path) if err != nil { @@ -135,9 +138,12 @@ multihash. Provided for legacy reasons. Use 'ipfs dag get' instead. return err } - path := path.New(req.Arguments[0]) + path, err := cmdutils.PathOrCidPath(req.Arguments[0]) + if err != nil { + return err + } - rp, err := api.ResolvePath(req.Context, path) + rp, _, err := api.ResolvePath(req.Context, path) if err != nil { return err } @@ -157,7 +163,7 @@ multihash. Provided for legacy reasons. Use 'ipfs dag get' instead. } out := &Object{ - Hash: enc.Encode(rp.Cid()), + Hash: enc.Encode(rp.RootCid()), Links: outLinks, } @@ -212,7 +218,10 @@ DEPRECATED and provided for legacy reasons. Use 'ipfs dag get' instead. return err } - path := path.New(req.Arguments[0]) + path, err := cmdutils.PathOrCidPath(req.Arguments[0]) + if err != nil { + return err + } datafieldenc, _ := req.Options[encodingOptionName].(string) if err != nil { @@ -333,7 +342,12 @@ DEPRECATED: Provided for legacy reasons. Modern replacements: return err } - ns, err := api.Object().Stat(req.Context, path.New(req.Arguments[0])) + p, err := cmdutils.PathOrCidPath(req.Arguments[0]) + if err != nil { + return err + } + + ns, err := api.Object().Stat(req.Context, p) if err != nil { return err } @@ -434,7 +448,7 @@ DEPRECATED and provided for legacy reasons. Use 'ipfs dag put' instead. return err } - return cmds.EmitOnce(res, &Object{Hash: enc.Encode(p.Cid())}) + return cmds.EmitOnce(res, &Object{Hash: enc.Encode(p.RootCid())}) }, Encoders: cmds.EncoderMap{ cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *Object) error { diff --git a/core/commands/object/patch.go b/core/commands/object/patch.go index 8ec5b3516..7e440b1af 100644 --- a/core/commands/object/patch.go +++ b/core/commands/object/patch.go @@ -9,7 +9,6 @@ import ( "github.com/ipfs/kubo/core/commands/cmdutils" "github.com/ipfs/boxo/coreiface/options" - "github.com/ipfs/boxo/coreiface/path" ) var ObjectPatchCmd = &cmds.Command{ @@ -76,7 +75,10 @@ DEPRECATED and provided for legacy reasons. Use 'ipfs add' or 'ipfs files' inste return err } - root := path.New(req.Arguments[0]) + root, err := cmdutils.PathOrCidPath(req.Arguments[0]) + if err != nil { + return err + } file, err := cmdenv.GetFileArg(req.Files.Entries()) if err != nil { @@ -88,11 +90,11 @@ DEPRECATED and provided for legacy reasons. Use 'ipfs add' or 'ipfs files' inste return err } - if err := cmdutils.CheckCIDSize(req, p.Cid(), api.Dag()); err != nil { + if err := cmdutils.CheckCIDSize(req, p.RootCid(), api.Dag()); err != nil { return err } - return cmds.EmitOnce(res, &Object{Hash: p.Cid().String()}) + return cmds.EmitOnce(res, &Object{Hash: p.RootCid().String()}) }, Type: &Object{}, Encoders: cmds.EncoderMap{ @@ -127,7 +129,10 @@ DEPRECATED and provided for legacy reasons. Use 'files cp' and 'dag put' instead return err } - root := path.New(req.Arguments[0]) + root, err := cmdutils.PathOrCidPath(req.Arguments[0]) + if err != nil { + return err + } file, err := cmdenv.GetFileArg(req.Files.Entries()) if err != nil { @@ -139,11 +144,11 @@ DEPRECATED and provided for legacy reasons. Use 'files cp' and 'dag put' instead return err } - if err := cmdutils.CheckCIDSize(req, p.Cid(), api.Dag()); err != nil { + if err := cmdutils.CheckCIDSize(req, p.RootCid(), api.Dag()); err != nil { return err } - return cmds.EmitOnce(res, &Object{Hash: p.Cid().String()}) + return cmds.EmitOnce(res, &Object{Hash: p.RootCid().String()}) }, Type: Object{}, Encoders: cmds.EncoderMap{ @@ -174,7 +179,10 @@ DEPRECATED and provided for legacy reasons. Use 'files rm' instead. return err } - root := path.New(req.Arguments[0]) + root, err := cmdutils.PathOrCidPath(req.Arguments[0]) + if err != nil { + return err + } name := req.Arguments[1] p, err := api.Object().RmLink(req.Context, root, name) @@ -182,11 +190,11 @@ DEPRECATED and provided for legacy reasons. Use 'files rm' instead. return err } - if err := cmdutils.CheckCIDSize(req, p.Cid(), api.Dag()); err != nil { + if err := cmdutils.CheckCIDSize(req, p.RootCid(), api.Dag()); err != nil { return err } - return cmds.EmitOnce(res, &Object{Hash: p.Cid().String()}) + return cmds.EmitOnce(res, &Object{Hash: p.RootCid().String()}) }, Type: Object{}, Encoders: cmds.EncoderMap{ @@ -238,9 +246,17 @@ Use MFS and 'files' commands instead: return err } - root := path.New(req.Arguments[0]) + root, err := cmdutils.PathOrCidPath(req.Arguments[0]) + if err != nil { + return err + } + name := req.Arguments[1] - child := path.New(req.Arguments[2]) + + child, err := cmdutils.PathOrCidPath(req.Arguments[2]) + if err != nil { + return err + } create, _ := req.Options[createOptionName].(bool) if err != nil { @@ -253,11 +269,11 @@ Use MFS and 'files' commands instead: return err } - if err := cmdutils.CheckCIDSize(req, p.Cid(), api.Dag()); err != nil { + if err := cmdutils.CheckCIDSize(req, p.RootCid(), api.Dag()); err != nil { return err } - return cmds.EmitOnce(res, &Object{Hash: p.Cid().String()}) + return cmds.EmitOnce(res, &Object{Hash: p.RootCid().String()}) }, Type: Object{}, Encoders: cmds.EncoderMap{ diff --git a/core/commands/pin/pin.go b/core/commands/pin/pin.go index 9402f5b2c..aa4470d70 100644 --- a/core/commands/pin/pin.go +++ b/core/commands/pin/pin.go @@ -11,7 +11,6 @@ import ( bserv "github.com/ipfs/boxo/blockservice" coreiface "github.com/ipfs/boxo/coreiface" options "github.com/ipfs/boxo/coreiface/options" - "github.com/ipfs/boxo/coreiface/path" offline "github.com/ipfs/boxo/exchange/offline" dag "github.com/ipfs/boxo/ipld/merkledag" verifcid "github.com/ipfs/boxo/verifcid" @@ -21,6 +20,7 @@ import ( core "github.com/ipfs/kubo/core" cmdenv "github.com/ipfs/kubo/core/commands/cmdenv" + "github.com/ipfs/kubo/core/commands/cmdutils" e "github.com/ipfs/kubo/core/commands/e" ) @@ -184,7 +184,12 @@ var addPinCmd = &cmds.Command{ func pinAddMany(ctx context.Context, api coreiface.CoreAPI, enc cidenc.Encoder, paths []string, recursive bool) ([]string, error) { added := make([]string, len(paths)) for i, b := range paths { - rp, err := api.ResolvePath(ctx, path.New(b)) + p, err := cmdutils.PathOrCidPath(b) + if err != nil { + return nil, err + } + + rp, _, err := api.ResolvePath(ctx, p) if err != nil { return nil, err } @@ -192,7 +197,7 @@ func pinAddMany(ctx context.Context, api coreiface.CoreAPI, enc cidenc.Encoder, if err := api.Pin().Add(ctx, rp, options.Pin.Recursive(recursive)); err != nil { return nil, err } - added[i] = enc.Encode(rp.Cid()) + added[i] = enc.Encode(rp.RootCid()) } return added, nil @@ -242,12 +247,17 @@ ipfs pin ls -t indirect pins := make([]string, 0, len(req.Arguments)) for _, b := range req.Arguments { - rp, err := api.ResolvePath(req.Context, path.New(b)) + p, err := cmdutils.PathOrCidPath(b) if err != nil { return err } - id := enc.Encode(rp.Cid()) + rp, _, err := api.ResolvePath(req.Context, p) + if err != nil { + return err + } + + id := enc.Encode(rp.RootCid()) pins = append(pins, id) if err := api.Pin().Rm(req.Context, rp, options.Pin.RmRecursive(recursive)); err != nil { return err @@ -453,7 +463,12 @@ func pinLsKeys(req *cmds.Request, typeStr string, api coreiface.CoreAPI, emit fu } for _, p := range req.Arguments { - rp, err := api.ResolvePath(req.Context, path.New(p)) + p, err := cmdutils.PathOrCidPath(p) + if err != nil { + return err + } + + rp, _, err := api.ResolvePath(req.Context, p) if err != nil { return err } @@ -476,7 +491,7 @@ func pinLsKeys(req *cmds.Request, typeStr string, api coreiface.CoreAPI, emit fu err = emit(PinLsOutputWrapper{ PinLsObject: PinLsObject{ Type: pinType, - Cid: enc.Encode(rp.Cid()), + Cid: enc.Encode(rp.RootCid()), }, }) if err != nil { @@ -517,7 +532,7 @@ func pinLsAll(req *cmds.Request, typeStr string, api coreiface.CoreAPI, emit fun err = emit(PinLsOutputWrapper{ PinLsObject: PinLsObject{ Type: p.Type(), - Cid: enc.Encode(p.Path().Cid()), + Cid: enc.Encode(p.Path().RootCid()), }, }) if err != nil { @@ -568,12 +583,22 @@ pin. unpin, _ := req.Options[pinUnpinOptionName].(bool) - // Resolve the paths ahead of time so we can return the actual CIDs - from, err := api.ResolvePath(req.Context, path.New(req.Arguments[0])) + fromPath, err := cmdutils.PathOrCidPath(req.Arguments[0]) if err != nil { return err } - to, err := api.ResolvePath(req.Context, path.New(req.Arguments[1])) + + toPath, err := cmdutils.PathOrCidPath(req.Arguments[1]) + if err != nil { + return err + } + + // Resolve the paths ahead of time so we can return the actual CIDs + from, _, err := api.ResolvePath(req.Context, fromPath) + if err != nil { + return err + } + to, _, err := api.ResolvePath(req.Context, toPath) if err != nil { return err } @@ -583,7 +608,7 @@ pin. return err } - return cmds.EmitOnce(res, &PinOutput{Pins: []string{enc.Encode(from.Cid()), enc.Encode(to.Cid())}}) + return cmds.EmitOnce(res, &PinOutput{Pins: []string{enc.Encode(from.RootCid()), enc.Encode(to.RootCid())}}) }, Encoders: cmds.EncoderMap{ cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *PinOutput) error { diff --git a/core/commands/pin/remotepin.go b/core/commands/pin/remotepin.go index 2fe615c14..132532554 100644 --- a/core/commands/pin/remotepin.go +++ b/core/commands/pin/remotepin.go @@ -15,13 +15,13 @@ import ( "golang.org/x/sync/errgroup" - path "github.com/ipfs/boxo/coreiface/path" pinclient "github.com/ipfs/boxo/pinning/remote/client" cid "github.com/ipfs/go-cid" cmds "github.com/ipfs/go-ipfs-cmds" logging "github.com/ipfs/go-log" config "github.com/ipfs/kubo/config" "github.com/ipfs/kubo/core/commands/cmdenv" + "github.com/ipfs/kubo/core/commands/cmdutils" fsrepo "github.com/ipfs/kubo/repo/fsrepo" "github.com/libp2p/go-libp2p/core/host" peer "github.com/libp2p/go-libp2p/core/peer" @@ -157,7 +157,12 @@ NOTE: a comma-separated notation is supported in CLI for convenience: if err != nil { return err } - rp, err := api.ResolvePath(ctx, path.New(req.Arguments[0])) + p, err := cmdutils.PathOrCidPath(req.Arguments[0]) + if err != nil { + return err + } + + rp, _, err := api.ResolvePath(ctx, p) if err != nil { return err } @@ -177,7 +182,7 @@ NOTE: a comma-separated notation is supported in CLI for convenience: return err } - isInBlockstore, err := node.Blockstore.Has(req.Context, rp.Cid()) + isInBlockstore, err := node.Blockstore.Has(req.Context, rp.RootCid()) if err != nil { return err } @@ -194,7 +199,7 @@ NOTE: a comma-separated notation is supported in CLI for convenience: // Execute remote pin request // TODO: fix panic when pinning service is down - ps, err := c.Add(ctx, rp.Cid(), opts...) + ps, err := c.Add(ctx, rp.RootCid(), opts...) if err != nil { return err } diff --git a/core/commands/refs.go b/core/commands/refs.go index de5206a65..3c58fe961 100644 --- a/core/commands/refs.go +++ b/core/commands/refs.go @@ -8,9 +8,9 @@ import ( "strings" cmdenv "github.com/ipfs/kubo/core/commands/cmdenv" + "github.com/ipfs/kubo/core/commands/cmdutils" iface "github.com/ipfs/boxo/coreiface" - path "github.com/ipfs/boxo/coreiface/path" merkledag "github.com/ipfs/boxo/ipld/merkledag" cid "github.com/ipfs/go-cid" cidenc "github.com/ipfs/go-cidutil/cidenc" @@ -171,11 +171,15 @@ Displays the hashes of all local objects. NOTE: This treats all local objects as func objectsForPaths(ctx context.Context, n iface.CoreAPI, paths []string) ([]cid.Cid, error) { roots := make([]cid.Cid, len(paths)) for i, sp := range paths { - o, err := n.ResolvePath(ctx, path.New(sp)) + p, err := cmdutils.PathOrCidPath(sp) if err != nil { return nil, err } - roots[i] = o.Cid() + o, _, err := n.ResolvePath(ctx, p) + if err != nil { + return nil, err + } + roots[i] = o.RootCid() } return roots, nil } diff --git a/core/commands/resolve.go b/core/commands/resolve.go index 38de57b21..5db392bf2 100644 --- a/core/commands/resolve.go +++ b/core/commands/resolve.go @@ -8,14 +8,14 @@ import ( "time" ns "github.com/ipfs/boxo/namesys" + "github.com/ipfs/boxo/path" + cidenc "github.com/ipfs/go-cidutil/cidenc" cmdenv "github.com/ipfs/kubo/core/commands/cmdenv" + "github.com/ipfs/kubo/core/commands/cmdutils" ncmd "github.com/ipfs/kubo/core/commands/name" options "github.com/ipfs/boxo/coreiface/options" nsopts "github.com/ipfs/boxo/coreiface/options/namesys" - path "github.com/ipfs/boxo/coreiface/path" - ipfspath "github.com/ipfs/boxo/path" - cidenc "github.com/ipfs/go-cidutil/cidenc" cmds "github.com/ipfs/go-ipfs-cmds" ) @@ -108,7 +108,7 @@ Resolve the value of an IPFS DAG path: if err != nil && err != ns.ErrResolveRecursion { return err } - return cmds.EmitOnce(res, &ncmd.ResolvedPath{Path: ipfspath.Path(p.String())}) + return cmds.EmitOnce(res, &ncmd.ResolvedPath{Path: p.String()}) } var enc cidenc.Encoder @@ -128,22 +128,34 @@ Resolve the value of an IPFS DAG path: } } - // else, ipfs path or ipns with recursive flag - rp, err := api.ResolvePath(req.Context, path.New(name)) + p, err := cmdutils.PathOrCidPath(name) if err != nil { return err } - encoded := "/" + rp.Namespace() + "/" + enc.Encode(rp.Cid()) - if remainder := rp.Remainder(); remainder != "" { - encoded += "/" + remainder + // else, ipfs path or ipns with recursive flag + rp, remainder, err := api.ResolvePath(req.Context, p) + if err != nil { + return err } - return cmds.EmitOnce(res, &ncmd.ResolvedPath{Path: ipfspath.Path(encoded)}) + // Trick to encode path with correct encoding. + encodedPath := "/" + rp.Namespace() + "/" + enc.Encode(rp.RootCid()) + if len(remainder) != 0 { + encodedPath += path.SegmentsToString(remainder...) + } + + // Ensure valid and sanitized. + ep, err := path.NewPath(encodedPath) + if err != nil { + return err + } + + return cmds.EmitOnce(res, &ncmd.ResolvedPath{Path: ep.String()}) }, Encoders: cmds.EncoderMap{ cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, rp *ncmd.ResolvedPath) error { - fmt.Fprintln(w, rp.Path.String()) + fmt.Fprintln(w, rp.Path) return nil }), }, diff --git a/core/commands/routing.go b/core/commands/routing.go index c0955456a..6d0ddb1c8 100644 --- a/core/commands/routing.go +++ b/core/commands/routing.go @@ -6,6 +6,7 @@ import ( "errors" "fmt" "io" + "strings" "time" cmdenv "github.com/ipfs/kubo/core/commands/cmdenv" @@ -13,7 +14,6 @@ import ( iface "github.com/ipfs/boxo/coreiface" "github.com/ipfs/boxo/coreiface/options" dag "github.com/ipfs/boxo/ipld/merkledag" - path "github.com/ipfs/boxo/path" cid "github.com/ipfs/go-cid" cmds "github.com/ipfs/go-ipfs-cmds" ipld "github.com/ipfs/go-ipld-format" @@ -549,7 +549,7 @@ func printEvent(obj *routing.QueryEvent, out io.Writer, verbose bool, override p } func escapeDhtKey(s string) (string, error) { - parts := path.SplitList(s) + parts := strings.Split(s, "/") if len(parts) != 3 || parts[0] != "" || !(parts[1] == "ipns" || parts[1] == "pk") { @@ -560,5 +560,6 @@ func escapeDhtKey(s string) (string, error) { if err != nil { return "", err } - return path.Join(append(parts[:2], string(k))), nil + + return strings.Join(append(parts[:2], string(k)), "/"), nil } diff --git a/core/commands/tar.go b/core/commands/tar.go index 50bd67943..e1094a59f 100644 --- a/core/commands/tar.go +++ b/core/commands/tar.go @@ -6,9 +6,9 @@ import ( cmds "github.com/ipfs/go-ipfs-cmds" "github.com/ipfs/kubo/core/commands/cmdenv" + "github.com/ipfs/kubo/core/commands/cmdutils" tar "github.com/ipfs/kubo/tar" - path "github.com/ipfs/boxo/coreiface/path" dag "github.com/ipfs/boxo/ipld/merkledag" ) @@ -93,7 +93,12 @@ var tarCatCmd = &cmds.Command{ return err } - root, err := api.ResolveNode(req.Context, path.New(req.Arguments[0])) + p, err := cmdutils.PathOrCidPath(req.Arguments[0]) + if err != nil { + return err + } + + root, err := api.ResolveNode(req.Context, p) if err != nil { return err } diff --git a/core/commands/unixfs/ls.go b/core/commands/unixfs/ls.go index 120b76034..c2d75c929 100644 --- a/core/commands/unixfs/ls.go +++ b/core/commands/unixfs/ls.go @@ -7,8 +7,8 @@ import ( "text/tabwriter" cmdenv "github.com/ipfs/kubo/core/commands/cmdenv" + "github.com/ipfs/kubo/core/commands/cmdutils" - path "github.com/ipfs/boxo/coreiface/path" merkledag "github.com/ipfs/boxo/ipld/merkledag" unixfs "github.com/ipfs/boxo/ipld/unixfs" cmds "github.com/ipfs/go-ipfs-cmds" @@ -96,7 +96,12 @@ If possible, please use 'ipfs ls' instead. for _, p := range paths { ctx := req.Context - merkleNode, err := api.ResolveNode(ctx, path.New(p)) + pth, err := cmdutils.PathOrCidPath(p) + if err != nil { + return err + } + + merkleNode, err := api.ResolveNode(ctx, pth) if err != nil { return err } diff --git a/core/commands/urlstore.go b/core/commands/urlstore.go index 4eec85ede..e5dd1ce4d 100644 --- a/core/commands/urlstore.go +++ b/core/commands/urlstore.go @@ -92,7 +92,7 @@ settings for 'ipfs add'. } size, _ := file.Size() return cmds.EmitOnce(res, &BlockStat{ - Key: enc.Encode(path.Cid()), + Key: enc.Encode(path.RootCid()), Size: int(size), }) }, diff --git a/core/coreapi/block.go b/core/coreapi/block.go index 55810de7e..ffbe89c8b 100644 --- a/core/coreapi/block.go +++ b/core/coreapi/block.go @@ -8,7 +8,7 @@ import ( coreiface "github.com/ipfs/boxo/coreiface" caopts "github.com/ipfs/boxo/coreiface/options" - path "github.com/ipfs/boxo/coreiface/path" + "github.com/ipfs/boxo/path" pin "github.com/ipfs/boxo/pinning/pinner" blocks "github.com/ipfs/go-block-format" cid "github.com/ipfs/go-cid" @@ -22,7 +22,7 @@ import ( type BlockAPI CoreAPI type BlockStat struct { - path path.Resolved + path path.ImmutablePath size int } @@ -68,18 +68,18 @@ func (api *BlockAPI) Put(ctx context.Context, src io.Reader, opts ...caopts.Bloc } } - return &BlockStat{path: path.IpldPath(b.Cid()), size: len(data)}, nil + return &BlockStat{path: path.FromCid(b.Cid()), size: len(data)}, nil } func (api *BlockAPI) Get(ctx context.Context, p path.Path) (io.Reader, error) { ctx, span := tracing.Span(ctx, "CoreAPI.BlockAPI", "Get", trace.WithAttributes(attribute.String("path", p.String()))) defer span.End() - rp, err := api.core().ResolvePath(ctx, p) + rp, _, err := api.core().ResolvePath(ctx, p) if err != nil { return nil, err } - b, err := api.blocks.GetBlock(ctx, rp.Cid()) + b, err := api.blocks.GetBlock(ctx, rp.RootCid()) if err != nil { return nil, err } @@ -91,7 +91,7 @@ func (api *BlockAPI) Rm(ctx context.Context, p path.Path, opts ...caopts.BlockRm ctx, span := tracing.Span(ctx, "CoreAPI.BlockAPI", "Rm", trace.WithAttributes(attribute.String("path", p.String()))) defer span.End() - rp, err := api.core().ResolvePath(ctx, p) + rp, _, err := api.core().ResolvePath(ctx, p) if err != nil { return err } @@ -100,7 +100,7 @@ func (api *BlockAPI) Rm(ctx context.Context, p path.Path, opts ...caopts.BlockRm if err != nil { return err } - cids := []cid.Cid{rp.Cid()} + cids := []cid.Cid{rp.RootCid()} o := util.RmBlocksOpts{Force: settings.Force} out, err := util.RmBlocks(ctx, api.blockstore, api.pinning, cids, o) @@ -132,18 +132,18 @@ func (api *BlockAPI) Stat(ctx context.Context, p path.Path) (coreiface.BlockStat ctx, span := tracing.Span(ctx, "CoreAPI.BlockAPI", "Stat", trace.WithAttributes(attribute.String("path", p.String()))) defer span.End() - rp, err := api.core().ResolvePath(ctx, p) + rp, _, err := api.core().ResolvePath(ctx, p) if err != nil { return nil, err } - b, err := api.blocks.GetBlock(ctx, rp.Cid()) + b, err := api.blocks.GetBlock(ctx, rp.RootCid()) if err != nil { return nil, err } return &BlockStat{ - path: path.IpldPath(b.Cid()), + path: path.FromCid(b.Cid()), size: len(b.RawData()), }, nil } @@ -152,7 +152,7 @@ func (bs *BlockStat) Size() int { return bs.size } -func (bs *BlockStat) Path() path.Resolved { +func (bs *BlockStat) Path() path.ImmutablePath { return bs.path } diff --git a/core/coreapi/dht.go b/core/coreapi/dht.go index 4feb8a76c..c960ee084 100644 --- a/core/coreapi/dht.go +++ b/core/coreapi/dht.go @@ -8,9 +8,9 @@ import ( blockstore "github.com/ipfs/boxo/blockstore" coreiface "github.com/ipfs/boxo/coreiface" caopts "github.com/ipfs/boxo/coreiface/options" - path "github.com/ipfs/boxo/coreiface/path" offline "github.com/ipfs/boxo/exchange/offline" dag "github.com/ipfs/boxo/ipld/merkledag" + "github.com/ipfs/boxo/path" cid "github.com/ipfs/go-cid" cidutil "github.com/ipfs/go-cidutil" "github.com/ipfs/kubo/tracing" @@ -53,7 +53,7 @@ func (api *DhtAPI) FindProviders(ctx context.Context, p path.Path, opts ...caopt return nil, err } - rp, err := api.core().ResolvePath(ctx, p) + rp, _, err := api.core().ResolvePath(ctx, p) if err != nil { return nil, err } @@ -63,7 +63,7 @@ func (api *DhtAPI) FindProviders(ctx context.Context, p path.Path, opts ...caopt return nil, fmt.Errorf("number of providers must be greater than 0") } - pchan := api.routing.FindProvidersAsync(ctx, rp.Cid(), numProviders) + pchan := api.routing.FindProvidersAsync(ctx, rp.RootCid(), numProviders) return pchan, nil } @@ -82,12 +82,12 @@ func (api *DhtAPI) Provide(ctx context.Context, path path.Path, opts ...caopts.D return err } - rp, err := api.core().ResolvePath(ctx, path) + rp, _, err := api.core().ResolvePath(ctx, path) if err != nil { return err } - c := rp.Cid() + c := rp.RootCid() has, err := api.blockstore.Has(ctx, c) if err != nil { diff --git a/core/coreapi/key.go b/core/coreapi/key.go index 925748a37..4c914ff3d 100644 --- a/core/coreapi/key.go +++ b/core/coreapi/key.go @@ -9,8 +9,8 @@ import ( coreiface "github.com/ipfs/boxo/coreiface" caopts "github.com/ipfs/boxo/coreiface/options" - path "github.com/ipfs/boxo/coreiface/path" - ipfspath "github.com/ipfs/boxo/path" + "github.com/ipfs/boxo/ipns" + "github.com/ipfs/boxo/path" "github.com/ipfs/kubo/tracing" crypto "github.com/libp2p/go-libp2p/core/crypto" peer "github.com/libp2p/go-libp2p/core/peer" @@ -23,6 +23,19 @@ type KeyAPI CoreAPI type key struct { name string peerID peer.ID + path path.Path +} + +func newKey(name string, pid peer.ID) (*key, error) { + p, err := path.NewPath("/ipns/" + ipns.NameFromPeer(pid).String()) + if err != nil { + return nil, err + } + return &key{ + name: name, + peerID: pid, + path: p, + }, nil } // Name returns the key name @@ -32,7 +45,7 @@ func (k *key) Name() string { // Path returns the path of the key. func (k *key) Path() path.Path { - return path.New(ipfspath.Join([]string{"/ipns", coreiface.FormatKeyID(k.peerID)})) + return k.path } // ID returns key PeerID @@ -98,7 +111,7 @@ func (api *KeyAPI) Generate(ctx context.Context, name string, opts ...caopts.Key return nil, err } - return &key{name, pid}, nil + return newKey(name, pid) } // List returns a list keys stored in keystore. @@ -114,7 +127,10 @@ func (api *KeyAPI) List(ctx context.Context) ([]coreiface.Key, error) { sort.Strings(keys) out := make([]coreiface.Key, len(keys)+1) - out[0] = &key{"self", api.identity} + out[0], err = newKey("self", api.identity) + if err != nil { + return nil, err + } for n, k := range keys { privKey, err := api.repo.Keystore().Get(k) @@ -129,7 +145,10 @@ func (api *KeyAPI) List(ctx context.Context) ([]coreiface.Key, error) { return nil, err } - out[n+1] = &key{k, pid} + out[n+1], err = newKey(k, pid) + if err != nil { + return nil, err + } } return out, nil } @@ -171,7 +190,8 @@ func (api *KeyAPI) Rename(ctx context.Context, oldName string, newName string, o // This is important, because future code will delete key `oldName` // even if it is the same as newName. if newName == oldName { - return &key{oldName, pid}, false, nil + k, err := newKey(oldName, pid) + return k, false, err } overwrite := false @@ -195,7 +215,13 @@ func (api *KeyAPI) Rename(ctx context.Context, oldName string, newName string, o return nil, false, err } - return &key{newName, pid}, overwrite, ks.Delete(oldName) + err = ks.Delete(oldName) + if err != nil { + return nil, false, err + } + + k, err := newKey(newName, pid) + return k, overwrite, err } // Remove removes keys from keystore. Returns ipns path of the removed key. @@ -226,7 +252,7 @@ func (api *KeyAPI) Remove(ctx context.Context, name string) (coreiface.Key, erro return nil, err } - return &key{"", pid}, nil + return newKey("", pid) } func (api *KeyAPI) Self(ctx context.Context) (coreiface.Key, error) { @@ -234,5 +260,5 @@ func (api *KeyAPI) Self(ctx context.Context) (coreiface.Key, error) { return nil, errors.New("identity not loaded") } - return &key{"self", api.identity}, nil + return newKey("self", api.identity) } diff --git a/core/coreapi/name.go b/core/coreapi/name.go index 3bf59a00c..0a398ef26 100644 --- a/core/coreapi/name.go +++ b/core/coreapi/name.go @@ -16,8 +16,7 @@ import ( coreiface "github.com/ipfs/boxo/coreiface" caopts "github.com/ipfs/boxo/coreiface/options" nsopts "github.com/ipfs/boxo/coreiface/options/namesys" - path "github.com/ipfs/boxo/coreiface/path" - ipath "github.com/ipfs/boxo/path" + "github.com/ipfs/boxo/path" ci "github.com/libp2p/go-libp2p/core/crypto" peer "github.com/libp2p/go-libp2p/core/peer" ) @@ -51,11 +50,6 @@ func (api *NameAPI) Publish(ctx context.Context, p path.Path, opts ...caopts.Nam return ipns.Name{}, err } - pth, err := ipath.ParsePath(p.String()) - if err != nil { - return ipns.Name{}, err - } - k, err := keylookup(api.privateKey, api.repo.Keystore(), options.Key) if err != nil { return ipns.Name{}, err @@ -72,7 +66,7 @@ func (api *NameAPI) Publish(ctx context.Context, p path.Path, opts ...caopts.Nam publishOptions = append(publishOptions, nsopts.PublishWithTTL(*options.TTL)) } - err = api.namesys.Publish(ctx, k, pth, publishOptions...) + err = api.namesys.Publish(ctx, k, p, publishOptions...) if err != nil { return ipns.Name{}, err } @@ -120,7 +114,7 @@ func (api *NameAPI) Search(ctx context.Context, name string, opts ...caopts.Name defer close(out) for res := range resolver.ResolveAsync(ctx, name, options.ResolveOpts...) { select { - case out <- coreiface.IpnsResult{Path: path.New(res.Path.String()), Err: res.Err}: + case out <- coreiface.IpnsResult{Path: res.Path, Err: res.Err}: case <-ctx.Done(): return } diff --git a/core/coreapi/object.go b/core/coreapi/object.go index 1b1caea65..b5da0d768 100644 --- a/core/coreapi/object.go +++ b/core/coreapi/object.go @@ -12,10 +12,10 @@ import ( coreiface "github.com/ipfs/boxo/coreiface" caopts "github.com/ipfs/boxo/coreiface/options" - ipath "github.com/ipfs/boxo/coreiface/path" dag "github.com/ipfs/boxo/ipld/merkledag" "github.com/ipfs/boxo/ipld/merkledag/dagutils" ft "github.com/ipfs/boxo/ipld/unixfs" + "github.com/ipfs/boxo/path" pin "github.com/ipfs/boxo/pinning/pinner" cid "github.com/ipfs/go-cid" ipld "github.com/ipfs/go-ipld-format" @@ -65,7 +65,7 @@ func (api *ObjectAPI) New(ctx context.Context, opts ...caopts.ObjectNewOption) ( return n, nil } -func (api *ObjectAPI) Put(ctx context.Context, src io.Reader, opts ...caopts.ObjectPutOption) (ipath.Resolved, error) { +func (api *ObjectAPI) Put(ctx context.Context, src io.Reader, opts ...caopts.ObjectPutOption) (path.ImmutablePath, error) { ctx, span := tracing.Span(ctx, "CoreAPI.ObjectAPI", "Put") defer span.End() @@ -143,16 +143,16 @@ func (api *ObjectAPI) Put(ctx context.Context, src io.Reader, opts ...caopts.Obj } } - return ipath.IpfsPath(dagnode.Cid()), nil + return path.FromCid(dagnode.Cid()), nil } -func (api *ObjectAPI) Get(ctx context.Context, path ipath.Path) (ipld.Node, error) { +func (api *ObjectAPI) Get(ctx context.Context, path path.Path) (ipld.Node, error) { ctx, span := tracing.Span(ctx, "CoreAPI.ObjectAPI", "Get", trace.WithAttributes(attribute.String("path", path.String()))) defer span.End() return api.core().ResolveNode(ctx, path) } -func (api *ObjectAPI) Data(ctx context.Context, path ipath.Path) (io.Reader, error) { +func (api *ObjectAPI) Data(ctx context.Context, path path.Path) (io.Reader, error) { ctx, span := tracing.Span(ctx, "CoreAPI.ObjectAPI", "Data", trace.WithAttributes(attribute.String("path", path.String()))) defer span.End() @@ -169,7 +169,7 @@ func (api *ObjectAPI) Data(ctx context.Context, path ipath.Path) (io.Reader, err return bytes.NewReader(pbnd.Data()), nil } -func (api *ObjectAPI) Links(ctx context.Context, path ipath.Path) ([]*ipld.Link, error) { +func (api *ObjectAPI) Links(ctx context.Context, path path.Path) ([]*ipld.Link, error) { ctx, span := tracing.Span(ctx, "CoreAPI.ObjectAPI", "Links", trace.WithAttributes(attribute.String("path", path.String()))) defer span.End() @@ -187,7 +187,7 @@ func (api *ObjectAPI) Links(ctx context.Context, path ipath.Path) ([]*ipld.Link, return out, nil } -func (api *ObjectAPI) Stat(ctx context.Context, path ipath.Path) (*coreiface.ObjectStat, error) { +func (api *ObjectAPI) Stat(ctx context.Context, path path.Path) (*coreiface.ObjectStat, error) { ctx, span := tracing.Span(ctx, "CoreAPI.ObjectAPI", "Stat", trace.WithAttributes(attribute.String("path", path.String()))) defer span.End() @@ -213,7 +213,7 @@ func (api *ObjectAPI) Stat(ctx context.Context, path ipath.Path) (*coreiface.Obj return out, nil } -func (api *ObjectAPI) AddLink(ctx context.Context, base ipath.Path, name string, child ipath.Path, opts ...caopts.ObjectAddLinkOption) (ipath.Resolved, error) { +func (api *ObjectAPI) AddLink(ctx context.Context, base path.Path, name string, child path.Path, opts ...caopts.ObjectAddLinkOption) (path.ImmutablePath, error) { ctx, span := tracing.Span(ctx, "CoreAPI.ObjectAPI", "AddLink", trace.WithAttributes( attribute.String("base", base.String()), attribute.String("name", name), @@ -259,10 +259,10 @@ func (api *ObjectAPI) AddLink(ctx context.Context, base ipath.Path, name string, return nil, err } - return ipath.IpfsPath(nnode.Cid()), nil + return path.FromCid(nnode.Cid()), nil } -func (api *ObjectAPI) RmLink(ctx context.Context, base ipath.Path, link string) (ipath.Resolved, error) { +func (api *ObjectAPI) RmLink(ctx context.Context, base path.Path, link string) (path.ImmutablePath, error) { ctx, span := tracing.Span(ctx, "CoreAPI.ObjectAPI", "RmLink", trace.WithAttributes( attribute.String("base", base.String()), attribute.String("link", link)), @@ -291,25 +291,25 @@ func (api *ObjectAPI) RmLink(ctx context.Context, base ipath.Path, link string) return nil, err } - return ipath.IpfsPath(nnode.Cid()), nil + return path.FromCid(nnode.Cid()), nil } -func (api *ObjectAPI) AppendData(ctx context.Context, path ipath.Path, r io.Reader) (ipath.Resolved, error) { +func (api *ObjectAPI) AppendData(ctx context.Context, path path.Path, r io.Reader) (path.ImmutablePath, error) { ctx, span := tracing.Span(ctx, "CoreAPI.ObjectAPI", "AppendData", trace.WithAttributes(attribute.String("path", path.String()))) defer span.End() return api.patchData(ctx, path, r, true) } -func (api *ObjectAPI) SetData(ctx context.Context, path ipath.Path, r io.Reader) (ipath.Resolved, error) { +func (api *ObjectAPI) SetData(ctx context.Context, path path.Path, r io.Reader) (path.ImmutablePath, error) { ctx, span := tracing.Span(ctx, "CoreAPI.ObjectAPI", "SetData", trace.WithAttributes(attribute.String("path", path.String()))) defer span.End() return api.patchData(ctx, path, r, false) } -func (api *ObjectAPI) patchData(ctx context.Context, path ipath.Path, r io.Reader, appendData bool) (ipath.Resolved, error) { - nd, err := api.core().ResolveNode(ctx, path) +func (api *ObjectAPI) patchData(ctx context.Context, p path.Path, r io.Reader, appendData bool) (path.ImmutablePath, error) { + nd, err := api.core().ResolveNode(ctx, p) if err != nil { return nil, err } @@ -334,10 +334,10 @@ func (api *ObjectAPI) patchData(ctx context.Context, path ipath.Path, r io.Reade return nil, err } - return ipath.IpfsPath(pbnd.Cid()), nil + return path.FromCid(pbnd.Cid()), nil } -func (api *ObjectAPI) Diff(ctx context.Context, before ipath.Path, after ipath.Path) ([]coreiface.ObjectChange, error) { +func (api *ObjectAPI) Diff(ctx context.Context, before path.Path, after path.Path) ([]coreiface.ObjectChange, error) { ctx, span := tracing.Span(ctx, "CoreAPI.ObjectAPI", "Diff", trace.WithAttributes( attribute.String("before", before.String()), attribute.String("after", after.String()), @@ -367,11 +367,11 @@ func (api *ObjectAPI) Diff(ctx context.Context, before ipath.Path, after ipath.P } if change.Before.Defined() { - out[i].Before = ipath.IpfsPath(change.Before) + out[i].Before = path.FromCid(change.Before) } if change.After.Defined() { - out[i].After = ipath.IpfsPath(change.After) + out[i].After = path.FromCid(change.After) } } diff --git a/core/coreapi/path.go b/core/coreapi/path.go index db07c6428..2e1ca28df 100644 --- a/core/coreapi/path.go +++ b/core/coreapi/path.go @@ -3,7 +3,6 @@ package coreapi import ( "context" "fmt" - gopath "path" "github.com/ipfs/boxo/namesys/resolve" "github.com/ipfs/kubo/tracing" @@ -12,10 +11,8 @@ import ( "go.opentelemetry.io/otel/trace" coreiface "github.com/ipfs/boxo/coreiface" - path "github.com/ipfs/boxo/coreiface/path" - ipfspath "github.com/ipfs/boxo/path" + "github.com/ipfs/boxo/path" ipfspathresolver "github.com/ipfs/boxo/path/resolver" - "github.com/ipfs/go-cid" ipld "github.com/ipfs/go-ipld-format" ) @@ -25,12 +22,12 @@ func (api *CoreAPI) ResolveNode(ctx context.Context, p path.Path) (ipld.Node, er ctx, span := tracing.Span(ctx, "CoreAPI", "ResolveNode", trace.WithAttributes(attribute.String("path", p.String()))) defer span.End() - rp, err := api.ResolvePath(ctx, p) + rp, _, err := api.ResolvePath(ctx, p) if err != nil { return nil, err } - node, err := api.dag.Get(ctx, rp.Cid()) + node, err := api.dag.Get(ctx, rp.RootCid()) if err != nil { return nil, err } @@ -39,45 +36,49 @@ func (api *CoreAPI) ResolveNode(ctx context.Context, p path.Path) (ipld.Node, er // ResolvePath resolves the path `p` using Unixfs resolver, returns the // resolved path. -func (api *CoreAPI) ResolvePath(ctx context.Context, p path.Path) (path.Resolved, error) { +func (api *CoreAPI) ResolvePath(ctx context.Context, p path.Path) (path.ImmutablePath, []string, error) { ctx, span := tracing.Span(ctx, "CoreAPI", "ResolvePath", trace.WithAttributes(attribute.String("path", p.String()))) defer span.End() - if _, ok := p.(path.Resolved); ok { - return p.(path.Resolved), nil - } - if err := p.IsValid(); err != nil { - return nil, err - } - - ipath := ipfspath.Path(p.String()) - ipath, err := resolve.ResolveIPNS(ctx, api.namesys, ipath) + p, err := resolve.ResolveIPNS(ctx, api.namesys, p) if err == resolve.ErrNoNamesys { - return nil, coreiface.ErrOffline + return nil, nil, coreiface.ErrOffline } else if err != nil { - return nil, err - } - - if ipath.Segments()[0] != "ipfs" && ipath.Segments()[0] != "ipld" { - return nil, fmt.Errorf("unsupported path namespace: %s", p.Namespace()) + return nil, nil, err } var resolver ipfspathresolver.Resolver - if ipath.Segments()[0] == "ipld" { + switch p.Namespace() { + case path.IPLDNamespace: resolver = api.ipldPathResolver - } else { + case path.IPFSNamespace: resolver = api.unixFSPathResolver + default: + return nil, nil, fmt.Errorf("unsupported path namespace: %s", p.Namespace()) } - node, rest, err := resolver.ResolveToLastNode(ctx, ipath) + imPath, err := path.NewImmutablePath(p) if err != nil { - return nil, err + return nil, nil, err } - root, err := cid.Parse(ipath.Segments()[1]) + node, remainder, err := resolver.ResolveToLastNode(ctx, imPath) if err != nil { - return nil, err + return nil, nil, err } - return path.NewResolvedPath(ipath, node, root, gopath.Join(rest...)), nil + segments := []string{p.Namespace(), node.String()} + segments = append(segments, remainder...) + + p, err = path.NewPathFromSegments(segments...) + if err != nil { + return nil, nil, err + } + + imPath, err = path.NewImmutablePath(p) + if err != nil { + return nil, nil, err + } + + return imPath, remainder, nil } diff --git a/core/coreapi/pin.go b/core/coreapi/pin.go index ec2cedb83..7c33b3ee0 100644 --- a/core/coreapi/pin.go +++ b/core/coreapi/pin.go @@ -7,9 +7,9 @@ import ( bserv "github.com/ipfs/boxo/blockservice" coreiface "github.com/ipfs/boxo/coreiface" caopts "github.com/ipfs/boxo/coreiface/options" - "github.com/ipfs/boxo/coreiface/path" offline "github.com/ipfs/boxo/exchange/offline" "github.com/ipfs/boxo/ipld/merkledag" + "github.com/ipfs/boxo/path" pin "github.com/ipfs/boxo/pinning/pinner" "github.com/ipfs/go-cid" "go.opentelemetry.io/otel/attribute" @@ -74,7 +74,7 @@ func (api *PinAPI) IsPinned(ctx context.Context, p path.Path, opts ...caopts.Pin ctx, span := tracing.Span(ctx, "CoreAPI.PinAPI", "IsPinned", trace.WithAttributes(attribute.String("path", p.String()))) defer span.End() - resolved, err := api.core().ResolvePath(ctx, p) + resolved, _, err := api.core().ResolvePath(ctx, p) if err != nil { return "", false, fmt.Errorf("error resolving path: %s", err) } @@ -91,7 +91,7 @@ func (api *PinAPI) IsPinned(ctx context.Context, p path.Path, opts ...caopts.Pin return "", false, fmt.Errorf("invalid type '%s', must be one of {direct, indirect, recursive, all}", settings.WithType) } - return api.pinning.IsPinnedWithType(ctx, resolved.Cid(), mode) + return api.pinning.IsPinnedWithType(ctx, resolved.RootCid(), mode) } // Rm pin rm api @@ -99,7 +99,7 @@ func (api *PinAPI) Rm(ctx context.Context, p path.Path, opts ...caopts.PinRmOpti ctx, span := tracing.Span(ctx, "CoreAPI.PinAPI", "Rm", trace.WithAttributes(attribute.String("path", p.String()))) defer span.End() - rp, err := api.core().ResolvePath(ctx, p) + rp, _, err := api.core().ResolvePath(ctx, p) if err != nil { return err } @@ -115,7 +115,7 @@ func (api *PinAPI) Rm(ctx context.Context, p path.Path, opts ...caopts.PinRmOpti // to take a lock to prevent a concurrent garbage collection defer api.blockstore.PinLock(ctx).Unlock(ctx) - if err = api.pinning.Unpin(ctx, rp.Cid(), settings.Recursive); err != nil { + if err = api.pinning.Unpin(ctx, rp.RootCid(), settings.Recursive); err != nil { return err } @@ -136,19 +136,19 @@ func (api *PinAPI) Update(ctx context.Context, from path.Path, to path.Path, opt span.SetAttributes(attribute.Bool("unpin", settings.Unpin)) - fp, err := api.core().ResolvePath(ctx, from) + fp, _, err := api.core().ResolvePath(ctx, from) if err != nil { return err } - tp, err := api.core().ResolvePath(ctx, to) + tp, _, err := api.core().ResolvePath(ctx, to) if err != nil { return err } defer api.blockstore.PinLock(ctx).Unlock(ctx) - err = api.pinning.Update(ctx, fp.Cid(), tp.Cid(), settings.Unpin) + err = api.pinning.Update(ctx, fp.RootCid(), tp.RootCid(), settings.Unpin) if err != nil { return err } @@ -165,7 +165,7 @@ type pinStatus struct { // BadNode is used in PinVerifyRes type badNode struct { - path path.Resolved + path path.ImmutablePath err error } @@ -181,7 +181,7 @@ func (s *pinStatus) Err() error { return s.err } -func (n *badNode) Path() path.Resolved { +func (n *badNode) Path() path.ImmutablePath { return n.path } @@ -210,7 +210,7 @@ func (api *PinAPI) Verify(ctx context.Context) (<-chan coreiface.PinStatus, erro links, err := getLinks(ctx, root) if err != nil { status := &pinStatus{ok: false, cid: root} - status.badNodes = []coreiface.BadPinNode{&badNode{path: path.IpldPath(root), err: err}} + status.badNodes = []coreiface.BadPinNode{&badNode{path: path.FromCid(root), err: err}} visited[root] = status return status } @@ -251,11 +251,11 @@ func (api *PinAPI) Verify(ctx context.Context) (<-chan coreiface.PinStatus, erro type pinInfo struct { pinType string - path path.Resolved + path path.ImmutablePath err error } -func (p *pinInfo) Path() path.Resolved { +func (p *pinInfo) Path() path.ImmutablePath { return p.path } @@ -281,7 +281,7 @@ func (api *PinAPI) pinLsAll(ctx context.Context, typeStr string) <-chan coreifac select { case out <- &pinInfo{ pinType: typeStr, - path: path.IpldPath(c), + path: path.FromCid(c), }: case <-ctx.Done(): return ctx.Err() diff --git a/core/coreapi/routing.go b/core/coreapi/routing.go index 95b50aa63..3b28e0472 100644 --- a/core/coreapi/routing.go +++ b/core/coreapi/routing.go @@ -3,10 +3,10 @@ package coreapi import ( "context" "errors" + "strings" coreiface "github.com/ipfs/boxo/coreiface" caopts "github.com/ipfs/boxo/coreiface/options" - "github.com/ipfs/boxo/path" peer "github.com/libp2p/go-libp2p/core/peer" ) @@ -45,7 +45,7 @@ func (r *RoutingAPI) Put(ctx context.Context, key string, value []byte, opts ... } func normalizeKey(s string) (string, error) { - parts := path.SplitList(s) + parts := strings.Split(s, "/") if len(parts) != 3 || parts[0] != "" || !(parts[1] == "ipns" || parts[1] == "pk") { @@ -56,5 +56,5 @@ func normalizeKey(s string) (string, error) { if err != nil { return "", err } - return path.Join(append(parts[:2], string(k))), nil + return strings.Join(append(parts[:2], string(k)), "/"), nil } diff --git a/core/coreapi/test/path_test.go b/core/coreapi/test/path_test.go index 0dce72627..6ba80423d 100644 --- a/core/coreapi/test/path_test.go +++ b/core/coreapi/test/path_test.go @@ -7,10 +7,10 @@ import ( "time" "github.com/ipfs/boxo/coreiface/options" - "github.com/ipfs/boxo/coreiface/path" "github.com/ipfs/boxo/files" "github.com/ipfs/boxo/ipld/merkledag" uio "github.com/ipfs/boxo/ipld/unixfs/io" + "github.com/ipfs/boxo/path" "github.com/ipld/go-ipld-prime" ) @@ -45,7 +45,7 @@ func TestPathUnixFSHAMTPartial(t *testing.T) { } // Get the root of the directory - nd, err := a.Dag().Get(ctx, r.Cid()) + nd, err := a.Dag().Get(ctx, r.RootCid()) if err != nil { t.Fatal(err) } @@ -55,7 +55,7 @@ func TestPathUnixFSHAMTPartial(t *testing.T) { pbNode := nd.(*merkledag.ProtoNode) // Remove one of the sharded directory blocks - if err := a.Block().Rm(ctx, path.IpfsPath(pbNode.Links()[0].Cid)); err != nil { + if err := a.Block().Rm(ctx, path.FromCid(pbNode.Links()[0].Cid)); err != nil { t.Fatal(err) } @@ -67,7 +67,12 @@ func TestPathUnixFSHAMTPartial(t *testing.T) { // The node will go out to the (non-existent) network looking for the missing block. Make sure we're erroring // because we exceeded the timeout on our query timeoutCtx, timeoutCancel := context.WithTimeout(ctx, time.Second*1) - _, err := a.ResolveNode(timeoutCtx, path.Join(r, k)) + newPath, err := path.Join(r, k) + if err != nil { + t.Fatal(err) + } + + _, err = a.ResolveNode(timeoutCtx, newPath) if err != nil { if timeoutCtx.Err() == nil { t.Fatal(err) diff --git a/core/coreapi/unixfs.go b/core/coreapi/unixfs.go index e1a607d73..3c0d6042a 100644 --- a/core/coreapi/unixfs.go +++ b/core/coreapi/unixfs.go @@ -16,7 +16,6 @@ import ( bstore "github.com/ipfs/boxo/blockstore" coreiface "github.com/ipfs/boxo/coreiface" options "github.com/ipfs/boxo/coreiface/options" - path "github.com/ipfs/boxo/coreiface/path" "github.com/ipfs/boxo/files" filestore "github.com/ipfs/boxo/filestore" merkledag "github.com/ipfs/boxo/ipld/merkledag" @@ -25,6 +24,7 @@ import ( unixfile "github.com/ipfs/boxo/ipld/unixfs/file" uio "github.com/ipfs/boxo/ipld/unixfs/io" mfs "github.com/ipfs/boxo/mfs" + "github.com/ipfs/boxo/path" cid "github.com/ipfs/go-cid" cidutil "github.com/ipfs/go-cidutil" ipld "github.com/ipfs/go-ipld-format" @@ -58,7 +58,7 @@ func getOrCreateNilNode() (*core.IpfsNode, error) { // Add builds a merkledag node from a reader, adds it to the blockstore, // and returns the key representing that node. -func (api *UnixfsAPI) Add(ctx context.Context, files files.Node, opts ...options.UnixfsAddOption) (path.Resolved, error) { +func (api *UnixfsAPI) Add(ctx context.Context, files files.Node, opts ...options.UnixfsAddOption) (path.ImmutablePath, error) { ctx, span := tracing.Span(ctx, "CoreAPI.UnixfsAPI", "Add") defer span.End() @@ -201,7 +201,7 @@ func (api *UnixfsAPI) Add(ctx context.Context, files files.Node, opts ...options } } - return path.IpfsPath(nd.Cid()), nil + return path.FromCid(nd.Cid()), nil } func (api *UnixfsAPI) Get(ctx context.Context, p path.Path) (files.Node, error) { diff --git a/core/corehttp/commands.go b/core/corehttp/commands.go index 53041e86b..804b70a7e 100644 --- a/core/corehttp/commands.go +++ b/core/corehttp/commands.go @@ -9,7 +9,6 @@ import ( "strconv" "strings" - path "github.com/ipfs/boxo/path" cmds "github.com/ipfs/go-ipfs-cmds" cmdsHttp "github.com/ipfs/go-ipfs-cmds/http" version "github.com/ipfs/kubo" @@ -171,7 +170,7 @@ func CheckVersionOption() ServeOption { parent.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { if strings.HasPrefix(r.URL.Path, APIPath) { cmdqry := r.URL.Path[len(APIPath):] - pth := path.SplitList(cmdqry) + pth := strings.Split(cmdqry, "/") // backwards compatibility to previous version check if len(pth) >= 2 && pth[1] != "version" { diff --git a/core/corehttp/gateway.go b/core/corehttp/gateway.go index 767934123..705171d79 100644 --- a/core/corehttp/gateway.go +++ b/core/corehttp/gateway.go @@ -10,11 +10,11 @@ import ( "github.com/ipfs/boxo/blockservice" iface "github.com/ipfs/boxo/coreiface" - "github.com/ipfs/boxo/coreiface/path" "github.com/ipfs/boxo/exchange/offline" "github.com/ipfs/boxo/files" "github.com/ipfs/boxo/gateway" "github.com/ipfs/boxo/namesys" + "github.com/ipfs/boxo/path" offlineroute "github.com/ipfs/boxo/routing/offline" "github.com/ipfs/go-cid" version "github.com/ipfs/kubo" @@ -149,37 +149,37 @@ func offlineErrWrap(err error) error { return err } -func (o *offlineGatewayErrWrapper) Get(ctx context.Context, path gateway.ImmutablePath, ranges ...gateway.ByteRange) (gateway.ContentPathMetadata, *gateway.GetResponse, error) { +func (o *offlineGatewayErrWrapper) Get(ctx context.Context, path path.ImmutablePath, ranges ...gateway.ByteRange) (gateway.ContentPathMetadata, *gateway.GetResponse, error) { md, n, err := o.gwimpl.Get(ctx, path, ranges...) err = offlineErrWrap(err) return md, n, err } -func (o *offlineGatewayErrWrapper) GetAll(ctx context.Context, path gateway.ImmutablePath) (gateway.ContentPathMetadata, files.Node, error) { +func (o *offlineGatewayErrWrapper) GetAll(ctx context.Context, path path.ImmutablePath) (gateway.ContentPathMetadata, files.Node, error) { md, n, err := o.gwimpl.GetAll(ctx, path) err = offlineErrWrap(err) return md, n, err } -func (o *offlineGatewayErrWrapper) GetBlock(ctx context.Context, path gateway.ImmutablePath) (gateway.ContentPathMetadata, files.File, error) { +func (o *offlineGatewayErrWrapper) GetBlock(ctx context.Context, path path.ImmutablePath) (gateway.ContentPathMetadata, files.File, error) { md, n, err := o.gwimpl.GetBlock(ctx, path) err = offlineErrWrap(err) return md, n, err } -func (o *offlineGatewayErrWrapper) Head(ctx context.Context, path gateway.ImmutablePath) (gateway.ContentPathMetadata, *gateway.HeadResponse, error) { +func (o *offlineGatewayErrWrapper) Head(ctx context.Context, path path.ImmutablePath) (gateway.ContentPathMetadata, *gateway.HeadResponse, error) { md, n, err := o.gwimpl.Head(ctx, path) err = offlineErrWrap(err) return md, n, err } -func (o *offlineGatewayErrWrapper) ResolvePath(ctx context.Context, path gateway.ImmutablePath) (gateway.ContentPathMetadata, error) { +func (o *offlineGatewayErrWrapper) ResolvePath(ctx context.Context, path path.ImmutablePath) (gateway.ContentPathMetadata, error) { md, err := o.gwimpl.ResolvePath(ctx, path) err = offlineErrWrap(err) return md, err } -func (o *offlineGatewayErrWrapper) GetCAR(ctx context.Context, path gateway.ImmutablePath, params gateway.CarParams) (gateway.ContentPathMetadata, io.ReadCloser, error) { +func (o *offlineGatewayErrWrapper) GetCAR(ctx context.Context, path path.ImmutablePath, params gateway.CarParams) (gateway.ContentPathMetadata, io.ReadCloser, error) { md, data, err := o.gwimpl.GetCAR(ctx, path, params) err = offlineErrWrap(err) return md, data, err @@ -195,7 +195,7 @@ func (o *offlineGatewayErrWrapper) GetIPNSRecord(ctx context.Context, c cid.Cid) return rec, err } -func (o *offlineGatewayErrWrapper) ResolveMutable(ctx context.Context, path path.Path) (gateway.ImmutablePath, error) { +func (o *offlineGatewayErrWrapper) ResolveMutable(ctx context.Context, path path.Path) (path.ImmutablePath, error) { imPath, err := o.gwimpl.ResolveMutable(ctx, path) err = offlineErrWrap(err) return imPath, err diff --git a/core/corehttp/gateway_test.go b/core/corehttp/gateway_test.go index b3acda31c..352f10490 100644 --- a/core/corehttp/gateway_test.go +++ b/core/corehttp/gateway_test.go @@ -46,7 +46,7 @@ func (m mockNamesys) Resolve(ctx context.Context, name string, opts ...nsopts.Re var ok bool value, ok = m[name] if !ok { - return "", namesys.ErrResolveFailed + return nil, namesys.ErrResolveFailed } name = value.String() } diff --git a/core/coreunix/add.go b/core/coreunix/add.go index 31a867b03..123c9fe65 100644 --- a/core/coreunix/add.go +++ b/core/coreunix/add.go @@ -11,7 +11,6 @@ import ( bstore "github.com/ipfs/boxo/blockstore" chunker "github.com/ipfs/boxo/chunker" coreiface "github.com/ipfs/boxo/coreiface" - "github.com/ipfs/boxo/coreiface/path" "github.com/ipfs/boxo/files" posinfo "github.com/ipfs/boxo/filestore/posinfo" dag "github.com/ipfs/boxo/ipld/merkledag" @@ -20,6 +19,7 @@ import ( ihelper "github.com/ipfs/boxo/ipld/unixfs/importer/helpers" "github.com/ipfs/boxo/ipld/unixfs/importer/trickle" "github.com/ipfs/boxo/mfs" + "github.com/ipfs/boxo/path" pin "github.com/ipfs/boxo/pinning/pinner" "github.com/ipfs/go-cid" ipld "github.com/ipfs/go-ipld-format" @@ -506,7 +506,7 @@ func getOutput(dagnode ipld.Node) (*coreiface.AddEvent, error) { } output := &coreiface.AddEvent{ - Path: path.IpfsPath(c), + Path: path.FromCid(c), Size: strconv.FormatUint(s, 10), } diff --git a/core/coreunix/add_test.go b/core/coreunix/add_test.go index be6f98ed7..a09fd5d2b 100644 --- a/core/coreunix/add_test.go +++ b/core/coreunix/add_test.go @@ -133,7 +133,7 @@ func TestAddMultipleGCLive(t *testing.T) { } for o := range out { - if _, ok := removedHashes[o.(*coreiface.AddEvent).Path.Cid().String()]; ok { + if _, ok := removedHashes[o.(*coreiface.AddEvent).Path.RootCid().String()]; ok { t.Fatal("gc'ed a hash we just added") } } @@ -187,7 +187,7 @@ func TestAddGCLive(t *testing.T) { addedHashes := make(map[string]struct{}) select { case o := <-out: - addedHashes[o.(*coreiface.AddEvent).Path.Cid().String()] = struct{}{} + addedHashes[o.(*coreiface.AddEvent).Path.RootCid().String()] = struct{}{} case <-addDone: t.Fatal("add shouldn't complete yet") } @@ -217,7 +217,7 @@ func TestAddGCLive(t *testing.T) { // receive next object from adder o := <-out - addedHashes[o.(*coreiface.AddEvent).Path.Cid().String()] = struct{}{} + addedHashes[o.(*coreiface.AddEvent).Path.RootCid().String()] = struct{}{} <-gcstarted @@ -233,7 +233,7 @@ func TestAddGCLive(t *testing.T) { var last cid.Cid for a := range out { // wait for it to finish - c, err := cid.Decode(a.(*coreiface.AddEvent).Path.Cid().String()) + c, err := cid.Decode(a.(*coreiface.AddEvent).Path.RootCid().String()) if err != nil { t.Fatal(err) } diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index ec52691ea..d2ffa7330 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.20 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.13.2-0.20231002142647-c28c847582f0 + github.com/ipfs/boxo v0.13.2-0.20231006140423-85c180e26664 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.31.0 github.com/multiformats/go-multiaddr v0.11.0 diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 9813cb922..1c7a27132 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -300,8 +300,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.13.2-0.20231002142647-c28c847582f0 h1:oss04OCg1/QW0h3OfSCZJiUQErpYPOsz7+X4tpgwODs= -github.com/ipfs/boxo v0.13.2-0.20231002142647-c28c847582f0/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk= +github.com/ipfs/boxo v0.13.2-0.20231006140423-85c180e26664 h1:wserB+u/lpguBpxuKNNzwJR+rOSHxWufm3ZzNgN3d24= +github.com/ipfs/boxo v0.13.2-0.20231006140423-85c180e26664/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= diff --git a/docs/examples/kubo-as-a-library/main.go b/docs/examples/kubo-as-a-library/main.go index 785973c5b..b7764a206 100644 --- a/docs/examples/kubo-as-a-library/main.go +++ b/docs/examples/kubo-as-a-library/main.go @@ -12,8 +12,8 @@ import ( "sync" icore "github.com/ipfs/boxo/coreiface" - icorepath "github.com/ipfs/boxo/coreiface/path" "github.com/ipfs/boxo/files" + "github.com/ipfs/boxo/path" ma "github.com/multiformats/go-multiaddr" "github.com/ipfs/kubo/config" @@ -320,11 +320,11 @@ func main() { } }() - exampleCIDStr := peerCidFile.Cid().String() + exampleCIDStr := peerCidFile.RootCid().String() fmt.Printf("Fetching a file from the network with CID %s\n", exampleCIDStr) outputPath := outputBasePath + exampleCIDStr - testCID := icorepath.New(exampleCIDStr) + testCID := path.FromCid(peerCidFile.RootCid()) rootNode, err := ipfsB.Unixfs().Get(ctx, testCID) if err != nil { diff --git a/fuse/ipns/common.go b/fuse/ipns/common.go index db231fe45..69924738e 100644 --- a/fuse/ipns/common.go +++ b/fuse/ipns/common.go @@ -5,7 +5,7 @@ import ( ft "github.com/ipfs/boxo/ipld/unixfs" nsys "github.com/ipfs/boxo/namesys" - path "github.com/ipfs/boxo/path" + "github.com/ipfs/boxo/path" "github.com/ipfs/kubo/core" ci "github.com/libp2p/go-libp2p/core/crypto" ) diff --git a/fuse/ipns/ipns_unix.go b/fuse/ipns/ipns_unix.go index 2cb25d332..77cb8b18f 100644 --- a/fuse/ipns/ipns_unix.go +++ b/fuse/ipns/ipns_unix.go @@ -14,9 +14,9 @@ import ( "strings" "syscall" - path "github.com/ipfs/boxo/coreiface/path" dag "github.com/ipfs/boxo/ipld/merkledag" ft "github.com/ipfs/boxo/ipld/unixfs" + "github.com/ipfs/boxo/path" fuse "bazil.org/fuse" fs "bazil.org/fuse/fs" @@ -86,7 +86,7 @@ type Root struct { func ipnsPubFunc(ipfs iface.CoreAPI, key iface.Key) mfs.PubFunc { return func(ctx context.Context, c cid.Cid) error { - _, err := ipfs.Name().Publish(ctx, path.IpfsPath(c), options.Name.Key(key.Name())) + _, err := ipfs.Name().Publish(ctx, path.FromCid(c), options.Name.Key(key.Name())) return err } } @@ -186,7 +186,7 @@ func (r *Root) Lookup(ctx context.Context, name string) (fs.Node, error) { return nil, syscall.Errno(syscall.ENOENT) } - if resolved.Namespace() != "ipfs" { + if resolved.Namespace() != path.IPFSNamespace { return nil, errors.New("invalid path from ipns record") } diff --git a/fuse/readonly/ipfs_test.go b/fuse/readonly/ipfs_test.go index bc6204abb..385ae1272 100644 --- a/fuse/readonly/ipfs_test.go +++ b/fuse/readonly/ipfs_test.go @@ -11,7 +11,7 @@ import ( "io" "math/rand" "os" - "path" + gopath "path" "strings" "sync" "testing" @@ -24,11 +24,11 @@ import ( fstest "bazil.org/fuse/fs/fstestutil" chunker "github.com/ipfs/boxo/chunker" - ipath "github.com/ipfs/boxo/coreiface/path" "github.com/ipfs/boxo/files" dag "github.com/ipfs/boxo/ipld/merkledag" importer "github.com/ipfs/boxo/ipld/unixfs/importer" uio "github.com/ipfs/boxo/ipld/unixfs/io" + "github.com/ipfs/boxo/path" u "github.com/ipfs/boxo/util" ipld "github.com/ipfs/go-ipld-format" ci "github.com/libp2p/go-libp2p-testing/ci" @@ -89,7 +89,7 @@ func TestIpfsBasicRead(t *testing.T) { fi, data := randObj(t, nd, 10000) k := fi.Cid() - fname := path.Join(mnt.Dir, k.String()) + fname := gopath.Join(mnt.Dir, k.String()) rbuf, err := os.ReadFile(fname) if err != nil { t.Fatal(err) @@ -116,7 +116,7 @@ func getPaths(t *testing.T, ipfs *core.IpfsNode, name string, n *dag.ProtoNode) t.Fatal(dag.ErrNotProtobuf) } - sub := getPaths(t, ipfs, path.Join(name, lnk.Name), childpb) + sub := getPaths(t, ipfs, gopath.Join(name, lnk.Name), childpb) out = append(out, sub...) } return out @@ -184,10 +184,14 @@ func TestIpfsStressRead(t *testing.T) { defer wg.Done() for i := 0; i < 2000; i++ { - item := ipath.New(paths[rand.Intn(len(paths))]) + item, err := path.NewPath(paths[rand.Intn(len(paths))]) + if err != nil { + errs <- err + continue + } relpath := strings.Replace(item.String(), item.Namespace(), "", 1) - fname := path.Join(mnt.Dir, relpath) + fname := gopath.Join(mnt.Dir, relpath) rbuf, err := os.ReadFile(fname) if err != nil { @@ -257,8 +261,8 @@ func TestIpfsBasicDirRead(t *testing.T) { t.Fatal(err) } - dirname := path.Join(mnt.Dir, d1nd.Cid().String()) - fname := path.Join(dirname, "actual") + dirname := gopath.Join(mnt.Dir, d1nd.Cid().String()) + fname := gopath.Join(dirname, "actual") rbuf, err := os.ReadFile(fname) if err != nil { t.Fatal(err) @@ -291,7 +295,7 @@ func TestFileSizeReporting(t *testing.T) { fi, data := randObj(t, nd, 10000) k := fi.Cid() - fname := path.Join(mnt.Dir, k.String()) + fname := gopath.Join(mnt.Dir, k.String()) finfo, err := os.Stat(fname) if err != nil { diff --git a/fuse/readonly/readonly_unix.go b/fuse/readonly/readonly_unix.go index e944f1b6e..9dca9c1a9 100644 --- a/fuse/readonly/readonly_unix.go +++ b/fuse/readonly/readonly_unix.go @@ -16,7 +16,7 @@ import ( mdag "github.com/ipfs/boxo/ipld/merkledag" ft "github.com/ipfs/boxo/ipld/unixfs" uio "github.com/ipfs/boxo/ipld/unixfs/io" - path "github.com/ipfs/boxo/path" + "github.com/ipfs/boxo/path" "github.com/ipfs/go-cid" ipld "github.com/ipfs/go-ipld-format" logging "github.com/ipfs/go-log" @@ -62,13 +62,19 @@ func (s *Root) Lookup(ctx context.Context, name string) (fs.Node, error) { return nil, syscall.Errno(syscall.ENOENT) } - p, err := path.ParsePath(name) + p, err := path.NewPath(name) if err != nil { log.Debugf("fuse failed to parse path: %q: %s", name, err) return nil, syscall.Errno(syscall.ENOENT) } - nd, ndLnk, err := s.Ipfs.UnixFSPathResolver.ResolvePath(ctx, p) + imPath, err := path.NewImmutablePath(p) + if err != nil { + log.Debugf("fuse failed to convert path: %q: %s", name, err) + return nil, syscall.Errno(syscall.ENOENT) + } + + nd, ndLnk, err := s.Ipfs.UnixFSPathResolver.ResolvePath(ctx, imPath) if err != nil { // todo: make this error more versatile. return nil, syscall.Errno(syscall.ENOENT) diff --git a/go.mod b/go.mod index aab31f8b5..da6cf3101 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( github.com/fsnotify/fsnotify v1.6.0 github.com/google/uuid v1.3.1 github.com/hashicorp/go-multierror v1.1.1 - github.com/ipfs/boxo v0.13.2-0.20231002142647-c28c847582f0 + github.com/ipfs/boxo v0.13.2-0.20231006140423-85c180e26664 github.com/ipfs/go-block-format v0.2.0 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 diff --git a/go.sum b/go.sum index 33bccc877..6d98a46a8 100644 --- a/go.sum +++ b/go.sum @@ -335,8 +335,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.13.2-0.20231002142647-c28c847582f0 h1:oss04OCg1/QW0h3OfSCZJiUQErpYPOsz7+X4tpgwODs= -github.com/ipfs/boxo v0.13.2-0.20231002142647-c28c847582f0/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk= +github.com/ipfs/boxo v0.13.2-0.20231006140423-85c180e26664 h1:wserB+u/lpguBpxuKNNzwJR+rOSHxWufm3ZzNgN3d24= +github.com/ipfs/boxo v0.13.2-0.20231006140423-85c180e26664/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= diff --git a/repo/fsrepo/migrations/ipfsfetcher/ipfsfetcher.go b/repo/fsrepo/migrations/ipfsfetcher/ipfsfetcher.go index b35cab683..cd6a5182e 100644 --- a/repo/fsrepo/migrations/ipfsfetcher/ipfsfetcher.go +++ b/repo/fsrepo/migrations/ipfsfetcher/ipfsfetcher.go @@ -7,14 +7,14 @@ import ( "io" "net/url" "os" - "path" + gopath "path" "strings" "sync" iface "github.com/ipfs/boxo/coreiface" "github.com/ipfs/boxo/coreiface/options" - ipath "github.com/ipfs/boxo/coreiface/path" "github.com/ipfs/boxo/files" + "github.com/ipfs/boxo/path" "github.com/ipfs/kubo/config" "github.com/ipfs/kubo/core" "github.com/ipfs/kubo/core/coreapi" @@ -46,7 +46,7 @@ type IpfsFetcher struct { ipfsTmpDir string ipfsStopFunc func() - fetched []ipath.Path + fetched []path.Path mutex sync.Mutex addrInfo peer.AddrInfo @@ -108,7 +108,7 @@ func (f *IpfsFetcher) Fetch(ctx context.Context, filePath string) ([]byte, error return nil, f.openErr } - iPath, err := parsePath(path.Join(f.distPath, filePath)) + iPath, err := parsePath(gopath.Join(f.distPath, filePath)) if err != nil { return nil, err } @@ -156,13 +156,13 @@ func (f *IpfsFetcher) AddrInfo() peer.AddrInfo { } // FetchedPaths returns the IPFS paths of all items fetched by this fetcher. -func (f *IpfsFetcher) FetchedPaths() []ipath.Path { +func (f *IpfsFetcher) FetchedPaths() []path.Path { f.mutex.Lock() defer f.mutex.Unlock() return f.fetched } -func (f *IpfsFetcher) recordFetched(fetchedPath ipath.Path) { +func (f *IpfsFetcher) recordFetched(fetchedPath path.Path) { // Mutex protects against update by concurrent calls to Fetch f.mutex.Lock() defer f.mutex.Unlock() @@ -267,9 +267,8 @@ func (f *IpfsFetcher) startTempNode(ctx context.Context) error { return nil } -func parsePath(fetchPath string) (ipath.Path, error) { - ipfsPath := ipath.New(fetchPath) - if ipfsPath.IsValid() == nil { +func parsePath(fetchPath string) (path.Path, error) { + if ipfsPath, err := path.NewPath(fetchPath); err == nil { return ipfsPath, nil } @@ -280,11 +279,10 @@ func parsePath(fetchPath string) (ipath.Path, error) { switch proto := u.Scheme; proto { case "ipfs", "ipld", "ipns": - ipfsPath = ipath.New(path.Join("/", proto, u.Host, u.Path)) + return path.NewPath(gopath.Join("/", proto, u.Host, u.Path)) default: return nil, fmt.Errorf("%q is not an IPFS path", fetchPath) } - return ipfsPath, ipfsPath.IsValid() } func readIpfsConfig(repoRoot *string, userConfigFile string) (bootstrap []string, peers []peer.AddrInfo) { diff --git a/tar/format.go b/tar/format.go index bde923980..a1fe455b4 100644 --- a/tar/format.go +++ b/tar/format.go @@ -6,13 +6,13 @@ import ( "context" "errors" "io" + "path" "strings" dag "github.com/ipfs/boxo/ipld/merkledag" "github.com/ipfs/boxo/ipld/merkledag/dagutils" importer "github.com/ipfs/boxo/ipld/unixfs/importer" uio "github.com/ipfs/boxo/ipld/unixfs/io" - path "github.com/ipfs/boxo/path" chunker "github.com/ipfs/boxo/chunker" ipld "github.com/ipfs/go-ipld-format" @@ -95,11 +95,11 @@ func ImportTar(ctx context.Context, r io.Reader, ds ipld.DAGService) (*dag.Proto // adds a '-' to the beginning of each path element so we can use 'data' as a // special link in the structure without having to worry about. func escapePath(pth string) string { - elems := path.SplitList(strings.Trim(pth, "/")) + elems := strings.Split(strings.Trim(pth, "/"), "/") for i, e := range elems { elems[i] = "-" + e } - return path.Join(elems) + return path.Join(elems...) } type tarReader struct { diff --git a/test/cli/gateway_test.go b/test/cli/gateway_test.go index a1c2fa8c9..719567531 100644 --- a/test/cli/gateway_test.go +++ b/test/cli/gateway_test.go @@ -408,9 +408,9 @@ func TestGateway(t *testing.T) { t.Parallel() gatewayAddr := URLStrToMultiaddr(node.GatewayURL()) res := node.RunIPFS("--api", gatewayAddr.String(), "refs", "local") - assert.Equal(t, - `Error: invalid path "local": invalid cid: selected encoding not supported`, + assert.Contains(t, res.Stderr.Trimmed(), + `Error: invalid path "local":`, ) }) diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 6c7f890aa..803e72615 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -7,7 +7,7 @@ replace github.com/ipfs/kubo => ../../ require ( github.com/Kubuxu/gocovmerge v0.0.0-20161216165753-7ecaa51963cd github.com/golangci/golangci-lint v1.54.1 - github.com/ipfs/boxo v0.13.2-0.20231002142647-c28c847582f0 + github.com/ipfs/boxo v0.13.2-0.20231006140423-85c180e26664 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 github.com/ipfs/go-datastore v0.6.0 diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index c296c573e..563fc3d5a 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -396,8 +396,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.13.2-0.20231002142647-c28c847582f0 h1:oss04OCg1/QW0h3OfSCZJiUQErpYPOsz7+X4tpgwODs= -github.com/ipfs/boxo v0.13.2-0.20231002142647-c28c847582f0/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk= +github.com/ipfs/boxo v0.13.2-0.20231006140423-85c180e26664 h1:wserB+u/lpguBpxuKNNzwJR+rOSHxWufm3ZzNgN3d24= +github.com/ipfs/boxo v0.13.2-0.20231006140423-85c180e26664/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs= diff --git a/test/sharness/t0090-get.sh b/test/sharness/t0090-get.sh index 2f3838db4..67fee8909 100755 --- a/test/sharness/t0090-get.sh +++ b/test/sharness/t0090-get.sh @@ -129,9 +129,8 @@ test_get_cmd() { ' test_expect_success "ipfs get ../.. should fail" ' - echo "Error: invalid path \"../..\": invalid cid: selected encoding not supported" >expected && test_must_fail ipfs get ../.. 2>actual && - test_cmp expected actual + test_should_contain "Error: invalid path \"../..\"" actual ' test_expect_success "create small file" ' From dafdce89838f358180a52a5bfbb4b198be25b8da Mon Sep 17 00:00:00 2001 From: Jorropo Date: Fri, 6 Oct 2023 21:17:13 +0200 Subject: [PATCH 0904/1212] path: replace ImmutablePath interface with struct Let's not repeat https://github.com/ipfs/go-block-format/issues/45 interface for struct with one implementation and no value added. This commit was moved from ipfs/boxo@45c797e0ccea0a3186795e64d9e5ed60b5d7544c --- core/coreiface/tests/unixfs.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/coreiface/tests/unixfs.go b/core/coreiface/tests/unixfs.go index e0c37fce4..31ac1b5c9 100644 --- a/core/coreiface/tests/unixfs.go +++ b/core/coreiface/tests/unixfs.go @@ -408,7 +408,7 @@ func (tp *TestSuite) TestAdd(t *testing.T) { t.Errorf("Event.Name didn't match, %s != %s", expected[0].Name, event.Name) } - if expected[0].Path != nil && event.Path != nil { + if (expected[0].Path != path.ImmutablePath{} && event.Path != path.ImmutablePath{}) { if expected[0].Path.RootCid().String() != event.Path.RootCid().String() { t.Errorf("Event.Hash didn't match, %s != %s", expected[0].Path, event.Path) } From a5668d22ba802afb1db269d47ce88dfb1f29473e Mon Sep 17 00:00:00 2001 From: Jorropo Date: Fri, 6 Oct 2023 21:48:28 +0200 Subject: [PATCH 0905/1212] chore: update boxo for structification of ImmutablePath --- client/rpc/object.go | 24 ++++++------- client/rpc/path.go | 8 ++--- client/rpc/unixfs.go | 18 +++++----- core/commands/add.go | 13 +++---- core/commands/object/diff.go | 5 +-- core/coreapi/object.go | 50 +++++++++++++------------- core/coreapi/path.go | 14 ++++---- core/coreapi/unixfs.go | 20 +++++------ docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 +-- go.mod | 2 +- go.sum | 4 +-- test/dependencies/go.mod | 2 +- test/dependencies/go.sum | 4 +-- 14 files changed, 86 insertions(+), 84 deletions(-) diff --git a/client/rpc/object.go b/client/rpc/object.go index 7296308a7..b8d09752f 100644 --- a/client/rpc/object.go +++ b/client/rpc/object.go @@ -43,7 +43,7 @@ func (api *ObjectAPI) New(ctx context.Context, opts ...caopts.ObjectNewOption) ( func (api *ObjectAPI) Put(ctx context.Context, r io.Reader, opts ...caopts.ObjectPutOption) (path.ImmutablePath, error) { options, err := caopts.ObjectPutOptions(opts...) if err != nil { - return nil, err + return path.ImmutablePath{}, err } var out objectOut @@ -54,12 +54,12 @@ func (api *ObjectAPI) Put(ctx context.Context, r io.Reader, opts ...caopts.Objec FileBody(r). Exec(ctx, &out) if err != nil { - return nil, err + return path.ImmutablePath{}, err } c, err := cid.Parse(out.Hash) if err != nil { - return nil, err + return path.ImmutablePath{}, err } return path.FromCid(c), nil @@ -156,7 +156,7 @@ func (api *ObjectAPI) Stat(ctx context.Context, p path.Path) (*iface.ObjectStat, func (api *ObjectAPI) AddLink(ctx context.Context, base path.Path, name string, child path.Path, opts ...caopts.ObjectAddLinkOption) (path.ImmutablePath, error) { options, err := caopts.ObjectAddLinkOptions(opts...) if err != nil { - return nil, err + return path.ImmutablePath{}, err } var out objectOut @@ -164,12 +164,12 @@ func (api *ObjectAPI) AddLink(ctx context.Context, base path.Path, name string, Option("create", options.Create). Exec(ctx, &out) if err != nil { - return nil, err + return path.ImmutablePath{}, err } c, err := cid.Parse(out.Hash) if err != nil { - return nil, err + return path.ImmutablePath{}, err } return path.FromCid(c), nil @@ -180,12 +180,12 @@ func (api *ObjectAPI) RmLink(ctx context.Context, base path.Path, link string) ( err := api.core().Request("object/patch/rm-link", base.String(), link). Exec(ctx, &out) if err != nil { - return nil, err + return path.ImmutablePath{}, err } c, err := cid.Parse(out.Hash) if err != nil { - return nil, err + return path.ImmutablePath{}, err } return path.FromCid(c), nil @@ -197,12 +197,12 @@ func (api *ObjectAPI) AppendData(ctx context.Context, p path.Path, r io.Reader) FileBody(r). Exec(ctx, &out) if err != nil { - return nil, err + return path.ImmutablePath{}, err } c, err := cid.Parse(out.Hash) if err != nil { - return nil, err + return path.ImmutablePath{}, err } return path.FromCid(c), nil @@ -214,12 +214,12 @@ func (api *ObjectAPI) SetData(ctx context.Context, p path.Path, r io.Reader) (pa FileBody(r). Exec(ctx, &out) if err != nil { - return nil, err + return path.ImmutablePath{}, err } c, err := cid.Parse(out.Hash) if err != nil { - return nil, err + return path.ImmutablePath{}, err } return path.FromCid(c), nil diff --git a/client/rpc/path.go b/client/rpc/path.go index 558203515..03d3dfa55 100644 --- a/client/rpc/path.go +++ b/client/rpc/path.go @@ -17,22 +17,22 @@ func (api *HttpApi) ResolvePath(ctx context.Context, p path.Path) (path.Immutabl var err error if p.Namespace() == path.IPNSNamespace { if p, err = api.Name().Resolve(ctx, p.String()); err != nil { - return nil, nil, err + return path.ImmutablePath{}, nil, err } } if err := api.Request("dag/resolve", p.String()).Exec(ctx, &out); err != nil { - return nil, nil, err + return path.ImmutablePath{}, nil, err } p, err = path.NewPathFromSegments(p.Namespace(), out.Cid.String(), out.RemPath) if err != nil { - return nil, nil, err + return path.ImmutablePath{}, nil, err } imPath, err := path.NewImmutablePath(p) if err != nil { - return nil, nil, err + return path.ImmutablePath{}, nil, err } return imPath, path.StringToSegments(out.RemPath), nil diff --git a/client/rpc/unixfs.go b/client/rpc/unixfs.go index 077d3f5a6..be8ddb22d 100644 --- a/client/rpc/unixfs.go +++ b/client/rpc/unixfs.go @@ -29,12 +29,12 @@ type UnixfsAPI HttpApi func (api *UnixfsAPI) Add(ctx context.Context, f files.Node, opts ...caopts.UnixfsAddOption) (path.ImmutablePath, error) { options, _, err := caopts.UnixfsAddOptions(opts...) if err != nil { - return nil, err + return path.ImmutablePath{}, err } mht, ok := mh.Codes[options.MhType] if !ok { - return nil, fmt.Errorf("unknowm mhType %d", options.MhType) + return path.ImmutablePath{}, fmt.Errorf("unknowm mhType %d", options.MhType) } req := api.core().Request("add"). @@ -65,7 +65,7 @@ func (api *UnixfsAPI) Add(ctx context.Context, f files.Node, opts ...caopts.Unix version, err := api.core().loadRemoteVersion() if err != nil { - return nil, err + return path.ImmutablePath{}, err } useEncodedAbsPaths := version.LT(encodedAbsolutePathVersion) req.Body(files.NewMultiFileReader(d, false, useEncodedAbsPaths)) @@ -73,10 +73,10 @@ func (api *UnixfsAPI) Add(ctx context.Context, f files.Node, opts ...caopts.Unix var out addEvent resp, err := req.Send(ctx) if err != nil { - return nil, err + return path.ImmutablePath{}, err } if resp.Error != nil { - return nil, resp.Error + return path.ImmutablePath{}, resp.Error } defer resp.Output.Close() dec := json.NewDecoder(resp.Output) @@ -88,7 +88,7 @@ loop: case io.EOF: break loop default: - return nil, err + return path.ImmutablePath{}, err } out = evt @@ -102,7 +102,7 @@ loop: if out.Hash != "" { c, err := cid.Parse(out.Hash) if err != nil { - return nil, err + return path.ImmutablePath{}, err } ifevt.Path = path.FromCid(c) @@ -111,14 +111,14 @@ loop: select { case options.Events <- ifevt: case <-ctx.Done(): - return nil, ctx.Err() + return path.ImmutablePath{}, ctx.Err() } } } c, err := cid.Parse(out.Hash) if err != nil { - return nil, err + return path.ImmutablePath{}, err } return path.FromCid(c), nil diff --git a/core/commands/add.go b/core/commands/add.go index eb855fe93..bdde6cb41 100644 --- a/core/commands/add.go +++ b/core/commands/add.go @@ -5,7 +5,7 @@ import ( "fmt" "io" "os" - "path" + gopath "path" "strings" "github.com/ipfs/kubo/core/commands/cmdenv" @@ -15,6 +15,7 @@ import ( "github.com/ipfs/boxo/coreiface/options" "github.com/ipfs/boxo/files" mfs "github.com/ipfs/boxo/mfs" + "github.com/ipfs/boxo/path" cmds "github.com/ipfs/go-ipfs-cmds" ipld "github.com/ipfs/go-ipld-format" mh "github.com/multiformats/go-multihash" @@ -301,7 +302,7 @@ See 'dag export' and 'dag import' for more information. return } // if MFS destination is a dir, append filename to the dir path - toFilesDst += path.Base(addit.Name()) + toFilesDst += gopath.Base(addit.Name()) } // error if we try to overwrite a preexisting file destination @@ -310,9 +311,9 @@ See 'dag export' and 'dag import' for more information. return } - _, err = mfs.Lookup(ipfsNode.FilesRoot, path.Dir(toFilesDst)) + _, err = mfs.Lookup(ipfsNode.FilesRoot, gopath.Dir(toFilesDst)) if err != nil { - errCh <- fmt.Errorf("%s: MFS destination parent %q %q does not exist: %w", toFilesOptionName, toFilesDst, path.Dir(toFilesDst), err) + errCh <- fmt.Errorf("%s: MFS destination parent %q %q does not exist: %w", toFilesOptionName, toFilesDst, gopath.Dir(toFilesDst), err) return } @@ -339,14 +340,14 @@ See 'dag export' and 'dag import' for more information. } h := "" - if output.Path != nil { + if (output.Path != path.ImmutablePath{}) { h = enc.Encode(output.Path.RootCid()) } if !dir && addit.Name() != "" { output.Name = addit.Name() } else { - output.Name = path.Join(addit.Name(), output.Name) + output.Name = gopath.Join(addit.Name(), output.Name) } if err := res.Emit(&AddEvent{ diff --git a/core/commands/object/diff.go b/core/commands/object/diff.go index 882fb63e1..275f465d8 100644 --- a/core/commands/object/diff.go +++ b/core/commands/object/diff.go @@ -5,6 +5,7 @@ import ( "io" "github.com/ipfs/boxo/ipld/merkledag/dagutils" + "github.com/ipfs/boxo/path" cmds "github.com/ipfs/go-ipfs-cmds" cmdenv "github.com/ipfs/kubo/core/commands/cmdenv" @@ -82,11 +83,11 @@ Example: Path: change.Path, } - if change.Before != nil { + if (change.Before != path.ImmutablePath{}) { out[i].Before = change.Before.RootCid() } - if change.After != nil { + if (change.After != path.ImmutablePath{}) { out[i].After = change.After.RootCid() } } diff --git a/core/coreapi/object.go b/core/coreapi/object.go index b5da0d768..3c63372e0 100644 --- a/core/coreapi/object.go +++ b/core/coreapi/object.go @@ -71,7 +71,7 @@ func (api *ObjectAPI) Put(ctx context.Context, src io.Reader, opts ...caopts.Obj options, err := caopts.ObjectPutOptions(opts...) if err != nil { - return nil, err + return path.ImmutablePath{}, err } span.SetAttributes( attribute.Bool("pin", options.Pin), @@ -81,7 +81,7 @@ func (api *ObjectAPI) Put(ctx context.Context, src io.Reader, opts ...caopts.Obj data, err := io.ReadAll(io.LimitReader(src, inputLimit+10)) if err != nil { - return nil, err + return path.ImmutablePath{}, err } var dagnode *dag.ProtoNode @@ -92,12 +92,12 @@ func (api *ObjectAPI) Put(ctx context.Context, src io.Reader, opts ...caopts.Obj decoder.DisallowUnknownFields() err = decoder.Decode(node) if err != nil { - return nil, err + return path.ImmutablePath{}, err } dagnode, err = deserializeNode(node, options.DataType) if err != nil { - return nil, err + return path.ImmutablePath{}, err } case "protobuf": @@ -107,20 +107,20 @@ func (api *ObjectAPI) Put(ctx context.Context, src io.Reader, opts ...caopts.Obj node := new(Node) err = xml.Unmarshal(data, node) if err != nil { - return nil, err + return path.ImmutablePath{}, err } dagnode, err = deserializeNode(node, options.DataType) if err != nil { - return nil, err + return path.ImmutablePath{}, err } default: - return nil, errors.New("unknown object encoding") + return path.ImmutablePath{}, errors.New("unknown object encoding") } if err != nil { - return nil, err + return path.ImmutablePath{}, err } if options.Pin { @@ -129,17 +129,17 @@ func (api *ObjectAPI) Put(ctx context.Context, src io.Reader, opts ...caopts.Obj err = api.dag.Add(ctx, dagnode) if err != nil { - return nil, err + return path.ImmutablePath{}, err } if options.Pin { if err := api.pinning.PinWithMode(ctx, dagnode.Cid(), pin.Recursive); err != nil { - return nil, err + return path.ImmutablePath{}, err } err = api.pinning.Flush(ctx) if err != nil { - return nil, err + return path.ImmutablePath{}, err } } @@ -223,23 +223,23 @@ func (api *ObjectAPI) AddLink(ctx context.Context, base path.Path, name string, options, err := caopts.ObjectAddLinkOptions(opts...) if err != nil { - return nil, err + return path.ImmutablePath{}, err } span.SetAttributes(attribute.Bool("create", options.Create)) baseNd, err := api.core().ResolveNode(ctx, base) if err != nil { - return nil, err + return path.ImmutablePath{}, err } childNd, err := api.core().ResolveNode(ctx, child) if err != nil { - return nil, err + return path.ImmutablePath{}, err } basePb, ok := baseNd.(*dag.ProtoNode) if !ok { - return nil, dag.ErrNotProtobuf + return path.ImmutablePath{}, dag.ErrNotProtobuf } var createfunc func() *dag.ProtoNode @@ -251,12 +251,12 @@ func (api *ObjectAPI) AddLink(ctx context.Context, base path.Path, name string, err = e.InsertNodeAtPath(ctx, name, childNd, createfunc) if err != nil { - return nil, err + return path.ImmutablePath{}, err } nnode, err := e.Finalize(ctx, api.dag) if err != nil { - return nil, err + return path.ImmutablePath{}, err } return path.FromCid(nnode.Cid()), nil @@ -271,24 +271,24 @@ func (api *ObjectAPI) RmLink(ctx context.Context, base path.Path, link string) ( baseNd, err := api.core().ResolveNode(ctx, base) if err != nil { - return nil, err + return path.ImmutablePath{}, err } basePb, ok := baseNd.(*dag.ProtoNode) if !ok { - return nil, dag.ErrNotProtobuf + return path.ImmutablePath{}, dag.ErrNotProtobuf } e := dagutils.NewDagEditor(basePb, api.dag) err = e.RmLink(ctx, link) if err != nil { - return nil, err + return path.ImmutablePath{}, err } nnode, err := e.Finalize(ctx, api.dag) if err != nil { - return nil, err + return path.ImmutablePath{}, err } return path.FromCid(nnode.Cid()), nil @@ -311,17 +311,17 @@ func (api *ObjectAPI) SetData(ctx context.Context, path path.Path, r io.Reader) func (api *ObjectAPI) patchData(ctx context.Context, p path.Path, r io.Reader, appendData bool) (path.ImmutablePath, error) { nd, err := api.core().ResolveNode(ctx, p) if err != nil { - return nil, err + return path.ImmutablePath{}, err } pbnd, ok := nd.(*dag.ProtoNode) if !ok { - return nil, dag.ErrNotProtobuf + return path.ImmutablePath{}, dag.ErrNotProtobuf } data, err := io.ReadAll(r) if err != nil { - return nil, err + return path.ImmutablePath{}, err } if appendData { @@ -331,7 +331,7 @@ func (api *ObjectAPI) patchData(ctx context.Context, p path.Path, r io.Reader, a err = api.dag.Add(ctx, pbnd) if err != nil { - return nil, err + return path.ImmutablePath{}, err } return path.FromCid(pbnd.Cid()), nil diff --git a/core/coreapi/path.go b/core/coreapi/path.go index 2e1ca28df..63d277ff2 100644 --- a/core/coreapi/path.go +++ b/core/coreapi/path.go @@ -42,9 +42,9 @@ func (api *CoreAPI) ResolvePath(ctx context.Context, p path.Path) (path.Immutabl p, err := resolve.ResolveIPNS(ctx, api.namesys, p) if err == resolve.ErrNoNamesys { - return nil, nil, coreiface.ErrOffline + return path.ImmutablePath{}, nil, coreiface.ErrOffline } else if err != nil { - return nil, nil, err + return path.ImmutablePath{}, nil, err } var resolver ipfspathresolver.Resolver @@ -54,17 +54,17 @@ func (api *CoreAPI) ResolvePath(ctx context.Context, p path.Path) (path.Immutabl case path.IPFSNamespace: resolver = api.unixFSPathResolver default: - return nil, nil, fmt.Errorf("unsupported path namespace: %s", p.Namespace()) + return path.ImmutablePath{}, nil, fmt.Errorf("unsupported path namespace: %s", p.Namespace()) } imPath, err := path.NewImmutablePath(p) if err != nil { - return nil, nil, err + return path.ImmutablePath{}, nil, err } node, remainder, err := resolver.ResolveToLastNode(ctx, imPath) if err != nil { - return nil, nil, err + return path.ImmutablePath{}, nil, err } segments := []string{p.Namespace(), node.String()} @@ -72,12 +72,12 @@ func (api *CoreAPI) ResolvePath(ctx context.Context, p path.Path) (path.Immutabl p, err = path.NewPathFromSegments(segments...) if err != nil { - return nil, nil, err + return path.ImmutablePath{}, nil, err } imPath, err = path.NewImmutablePath(p) if err != nil { - return nil, nil, err + return path.ImmutablePath{}, nil, err } return imPath, remainder, nil diff --git a/core/coreapi/unixfs.go b/core/coreapi/unixfs.go index 3c0d6042a..a7cac6a00 100644 --- a/core/coreapi/unixfs.go +++ b/core/coreapi/unixfs.go @@ -64,7 +64,7 @@ func (api *UnixfsAPI) Add(ctx context.Context, files files.Node, opts ...options settings, prefix, err := options.UnixfsAddOptions(opts...) if err != nil { - return nil, err + return path.ImmutablePath{}, err } span.SetAttributes( @@ -85,7 +85,7 @@ func (api *UnixfsAPI) Add(ctx context.Context, files files.Node, opts ...options cfg, err := api.repo.Config() if err != nil { - return nil, err + return path.ImmutablePath{}, err } // check if repo will exceed storage limit if added @@ -97,7 +97,7 @@ func (api *UnixfsAPI) Add(ctx context.Context, files files.Node, opts ...options //} if settings.NoCopy && !(cfg.Experimental.FilestoreEnabled || cfg.Experimental.UrlstoreEnabled) { - return nil, fmt.Errorf("either the filestore or the urlstore must be enabled to use nocopy, see: https://github.com/ipfs/kubo/blob/master/docs/experimental-features.md#ipfs-filestore") + return path.ImmutablePath{}, fmt.Errorf("either the filestore or the urlstore must be enabled to use nocopy, see: https://github.com/ipfs/kubo/blob/master/docs/experimental-features.md#ipfs-filestore") } addblockstore := api.blockstore @@ -110,7 +110,7 @@ func (api *UnixfsAPI) Add(ctx context.Context, files files.Node, opts ...options if settings.OnlyHash { node, err := getOrCreateNilNode() if err != nil { - return nil, err + return path.ImmutablePath{}, err } addblockstore = node.Blockstore exch = node.Exchange @@ -144,7 +144,7 @@ func (api *UnixfsAPI) Add(ctx context.Context, files files.Node, opts ...options fileAdder, err := coreunix.NewAdder(ctx, pinning, addblockstore, syncDserv) if err != nil { - return nil, err + return path.ImmutablePath{}, err } fileAdder.Chunker = settings.Chunker @@ -164,7 +164,7 @@ func (api *UnixfsAPI) Add(ctx context.Context, files files.Node, opts ...options case options.TrickleLayout: fileAdder.Trickle = true default: - return nil, fmt.Errorf("unknown layout: %d", settings.Layout) + return path.ImmutablePath{}, fmt.Errorf("unknown layout: %d", settings.Layout) } if settings.Inline { @@ -180,11 +180,11 @@ func (api *UnixfsAPI) Add(ctx context.Context, files files.Node, opts ...options // Use the same prefix for the "empty" MFS root as for the file adder. err := emptyDirNode.SetCidBuilder(fileAdder.CidBuilder) if err != nil { - return nil, err + return path.ImmutablePath{}, err } mr, err := mfs.NewRoot(ctx, md, emptyDirNode, nil) if err != nil { - return nil, err + return path.ImmutablePath{}, err } fileAdder.SetMfsRoot(mr) @@ -192,12 +192,12 @@ func (api *UnixfsAPI) Add(ctx context.Context, files files.Node, opts ...options nd, err := fileAdder.AddAllAndPin(ctx, files) if err != nil { - return nil, err + return path.ImmutablePath{}, err } if !settings.OnlyHash { if err := api.provider.Provide(nd.Cid()); err != nil { - return nil, err + return path.ImmutablePath{}, err } } diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index d2ffa7330..65d168407 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.20 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.13.2-0.20231006140423-85c180e26664 + github.com/ipfs/boxo v0.13.2-0.20231009073559-45c797e0ccea github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.31.0 github.com/multiformats/go-multiaddr v0.11.0 diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 1c7a27132..1c5e4864c 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -300,8 +300,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.13.2-0.20231006140423-85c180e26664 h1:wserB+u/lpguBpxuKNNzwJR+rOSHxWufm3ZzNgN3d24= -github.com/ipfs/boxo v0.13.2-0.20231006140423-85c180e26664/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk= +github.com/ipfs/boxo v0.13.2-0.20231009073559-45c797e0ccea h1:CygWxN8BL+d1F6PBOI+02UKqkpASP0ai459aw6ANZTg= +github.com/ipfs/boxo v0.13.2-0.20231009073559-45c797e0ccea/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= diff --git a/go.mod b/go.mod index da6cf3101..5805f1cbe 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( github.com/fsnotify/fsnotify v1.6.0 github.com/google/uuid v1.3.1 github.com/hashicorp/go-multierror v1.1.1 - github.com/ipfs/boxo v0.13.2-0.20231006140423-85c180e26664 + github.com/ipfs/boxo v0.13.2-0.20231009073559-45c797e0ccea github.com/ipfs/go-block-format v0.2.0 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 diff --git a/go.sum b/go.sum index 6d98a46a8..0905dc22d 100644 --- a/go.sum +++ b/go.sum @@ -335,8 +335,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.13.2-0.20231006140423-85c180e26664 h1:wserB+u/lpguBpxuKNNzwJR+rOSHxWufm3ZzNgN3d24= -github.com/ipfs/boxo v0.13.2-0.20231006140423-85c180e26664/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk= +github.com/ipfs/boxo v0.13.2-0.20231009073559-45c797e0ccea h1:CygWxN8BL+d1F6PBOI+02UKqkpASP0ai459aw6ANZTg= +github.com/ipfs/boxo v0.13.2-0.20231009073559-45c797e0ccea/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 803e72615..773c9a2c9 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -7,7 +7,7 @@ replace github.com/ipfs/kubo => ../../ require ( github.com/Kubuxu/gocovmerge v0.0.0-20161216165753-7ecaa51963cd github.com/golangci/golangci-lint v1.54.1 - github.com/ipfs/boxo v0.13.2-0.20231006140423-85c180e26664 + github.com/ipfs/boxo v0.13.2-0.20231009073559-45c797e0ccea github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 github.com/ipfs/go-datastore v0.6.0 diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 563fc3d5a..d47325a08 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -396,8 +396,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.13.2-0.20231006140423-85c180e26664 h1:wserB+u/lpguBpxuKNNzwJR+rOSHxWufm3ZzNgN3d24= -github.com/ipfs/boxo v0.13.2-0.20231006140423-85c180e26664/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk= +github.com/ipfs/boxo v0.13.2-0.20231009073559-45c797e0ccea h1:CygWxN8BL+d1F6PBOI+02UKqkpASP0ai459aw6ANZTg= +github.com/ipfs/boxo v0.13.2-0.20231009073559-45c797e0ccea/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs= From 4c043112579733b6a91cf401104b713281ab01bb Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Mon, 9 Oct 2023 11:18:00 +0200 Subject: [PATCH 0906/1212] docs: clean mentions of go-ipfs-api, go-ipfs-http-api --- core/coreapi/coreapi.go | 11 +++--- docs/http-rpc-clients.md | 6 ---- package-list.json | 73 ---------------------------------------- 3 files changed, 4 insertions(+), 86 deletions(-) delete mode 100644 package-list.json diff --git a/core/coreapi/coreapi.go b/core/coreapi/coreapi.go index 5a7e321a9..81d05b58d 100644 --- a/core/coreapi/coreapi.go +++ b/core/coreapi/coreapi.go @@ -1,15 +1,12 @@ /* +**NOTE: this package is experimental.** + Package coreapi provides direct access to the core commands in IPFS. If you are embedding IPFS directly in your Go program, this package is the public interface you should use to read and write files or otherwise control IPFS. -If you are running IPFS as a separate process, you should use `go-ipfs-api` to -work with it via HTTP. As we finalize the interfaces here, `go-ipfs-api` will -transparently adopt them so you can use the same code with either package. - -**NOTE: this package is experimental.** `go-ipfs` has mainly been developed -as a standalone application and library-style use of this package is still new. -Interfaces here aren't yet completely stable. +If you are running IPFS as a separate process, you should use `client/rpc` to +work with it via HTTP. */ package coreapi diff --git a/docs/http-rpc-clients.md b/docs/http-rpc-clients.md index 0b4baa1b0..74094a4ca 100644 --- a/docs/http-rpc-clients.md +++ b/docs/http-rpc-clients.md @@ -2,12 +2,6 @@ Kubo provides official HTTP RPC (`/api/v0`) clients for selected languages: -- [`js-kubo-rpc-client`](https://github.com/ipfs/js-kubo-rpc-client) - Official JS client for talking to Kubo RPC over HTTP -- [`go-ipfs-api`](https://github.com/ipfs/go-ipfs-api) - The go interface to ipfs's HTTP RPC - Follow https://github.com/ipfs/kubo/issues/9124 for coming changes. -- [`httpapi`](./client/rpc) (previously `go-ipfs-http-client`) - [`coreiface.CoreAPI`](https://pkg.go.dev/github.com/ipfs/boxo/coreiface#CoreAPI) implementation using HTTP RPC - -## Recommended clients - | Language | Package Name | Github Repository | |:--------:|:-------------------:|--------------------------------------------| | JS | kubo-rpc-client | https://github.com/ipfs/js-kubo-rpc-client | diff --git a/package-list.json b/package-list.json deleted file mode 100644 index 7dfc5648c..000000000 --- a/package-list.json +++ /dev/null @@ -1,73 +0,0 @@ -{ - "columns": [ - "Name", - "CI/Travis", - "Coverage", - "Description" - ], - "rows": [ - "Libp2p", - ["libp2p/go-libp2p", "go-libp2p", "p2p networking library"], - ["libp2p/go-libp2p-pubsub", "go-libp2p-pubsub", "pubsub built on libp2p"], - ["libp2p/go-libp2p-kad-dht", "go-libp2p-kad-dht", "dht-backed router"], - ["libp2p/go-libp2p-pubsub-router", "go-libp2p-pubsub-router", "pubsub-backed router"], - - "Multiformats", - ["ipfs/go-cid", "go-cid", "CID implementation"], - ["multiformats/go-multiaddr", "go-multiaddr", "multiaddr implementation"], - ["multiformats/go-multihash", "go-multihash", "multihash implementation"], - ["multiformats/go-multibase", "go-multibase", "mulitbase implementation"], - - "Files", - ["ipfs/go-unixfs", "go-unixfs", "the core 'filesystem' logic"], - ["ipfs/go-mfs", "go-mfs", "a mutable filesystem editor for unixfs"], - ["ipfs/go-ipfs-posinfo", "go-ipfs-posinfo", "helper datatypes for the filestore"], - ["ipfs/go-ipfs-chunker", "go-ipfs-chunker", "file chunkers"], - - "Exchange", - ["ipfs/go-ipfs-exchange-interface", "go-ipfs-exchange-interface", "exchange service interface"], - ["ipfs/go-ipfs-exchange-offline", "go-ipfs-exchange-offline", "(dummy) offline implementation of the exchange service"], - ["ipfs/go-bitswap", "go-bitswap", "bitswap protocol implementation"], - ["ipfs/go-blockservice", "go-blockservice", "service that plugs a blockstore and an exchange together"], - - "Datastores", - ["ipfs/go-datastore", "go-datastore", "datastore interfaces, adapters, and basic implementations"], - ["ipfs/go-ipfs-ds-help", "go-ipfs-ds-help", "datastore utility functions"], - ["ipfs/go-ds-flatfs", "go-ds-flatfs", "a filesystem-based datastore"], - ["ipfs/go-ds-measure", "go-ds-measure", "a metric-collecting database adapter"], - ["ipfs/go-ds-leveldb", "go-ds-leveldb", "a leveldb based datastore"], - ["ipfs/go-ds-badger", "go-ds-badger", "a badgerdb based datastore"], - - "Namesys", - ["ipfs/go-ipns", "go-ipns", "IPNS datastructures and validation logic"], - - "Repo", - ["ipfs/go-fs-lock", "go-fs-lock", "lockfile management functions"], - ["ipfs/fs-repo-migrations", "fs-repo-migrations", "repo migrations"], - - "IPLD", - ["ipfs/go-block-format", "go-block-format", "block interfaces and implementations"], - ["ipfs/go-ipfs-blockstore", "go-ipfs-blockstore", "blockstore interfaces and implementations"], - ["ipfs/go-ipld-format", "go-ipld-format", "IPLD interfaces"], - ["ipfs/go-ipld-cbor", "go-ipld-cbor", "IPLD-CBOR implementation"], - ["ipfs/go-ipld-git", "go-ipld-git", "IPLD-Git implementation"], - ["ipfs/go-merkledag", "go-merkledag", "IPLD-Merkledag implementation (and then some)"], - - "Commands", - ["ipfs/go-ipfs-cmds", "go-ipfs-cmds", "CLI & HTTP commands library"], - ["ipfs/go-ipfs-files", "go-ipfs-files", "CLI & HTTP commands library"], - ["ipfs/go-ipfs-api", "go-ipfs-api", "an old, stable shell for the IPFS HTTP API"], - ["ipfs/go-ipfs-http-client", "go-ipfs-http-client", "a new, unstable shell for the IPFS HTTP API"], - ["ipfs/interface-go-ipfs-core", "interface-go-ipfs-core", "core go-ipfs API interface definitions"], - - "Metrics & Logging", - ["ipfs/go-metrics-interface", "go-metrics-interface", "metrics collection interfaces"], - ["ipfs/go-metrics-prometheus", "go-metrics-prometheus", "prometheus-backed metrics collector"], - ["ipfs/go-log", "go-log", "logging framework"], - - "Generics/Utils", - ["ipfs/go-ipfs-routing", "go-ipfs-routing", "routing (content, peer, value) helpers"], - ["ipfs/go-ipfs-util", "go-ipfs-util", "the kitchen sink"], - ["ipfs/go-ipfs-addr", "go-ipfs-addr", "utility functions for parsing IPFS multiaddrs"] - ] -} From 40d459b6938bf5a9439359053098129f99766e72 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Mon, 9 Oct 2023 11:23:33 +0200 Subject: [PATCH 0907/1212] ci: do not run tests against go-ipfs-api --- .github/workflows/build.yml | 37 ------------------------------------- 1 file changed, 37 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e3090696f..dd1648f21 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -94,43 +94,6 @@ jobs: working-directory: interop/packages/interop env: KUBO_BINARY: ${{ github.workspace }}/cmd/ipfs/ipfs - go-ipfs-api: - needs: [interop-prep] - runs-on: ubuntu-latest - timeout-minutes: 5 - env: - TEST_DOCKER: 0 - TEST_FUSE: 0 - TEST_VERBOSE: 1 - TRAVIS: 1 - GIT_PAGER: cat - IPFS_CHECK_RCMGR_DEFAULTS: 1 - defaults: - run: - shell: bash - steps: - - uses: actions/setup-go@v4 - with: - go-version: ${{ env.GO_VERSION }} - - uses: actions/download-artifact@v3 - with: - name: kubo - path: cmd/ipfs - - run: chmod +x cmd/ipfs/ipfs - - uses: actions/checkout@v4 - with: - repository: ipfs/go-ipfs-api - path: go-ipfs-api - - run: cmd/ipfs/ipfs daemon --init --enable-namesys-pubsub & - - run: | - while ! cmd/ipfs/ipfs id --api=/ip4/127.0.0.1/tcp/5001 2>/dev/null; do - sleep 1 - done - timeout-minutes: 5 - - run: go test -count=1 -v ./... - working-directory: go-ipfs-api - - run: cmd/ipfs/ipfs shutdown - if: always() ipfs-webui: needs: [interop-prep] runs-on: ${{ fromJSON(github.repository == 'ipfs/kubo' && '["self-hosted", "linux", "x64", "2xlarge"]' || '"ubuntu-latest"') }} From 170686b42047f8f5f4a585c4b63cb8d5111ce399 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Tue, 17 Oct 2023 19:02:26 +0200 Subject: [PATCH 0908/1212] chore: update types to match boxos (#10179) --- core/corehttp/routing.go | 4 ++-- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- test/cli/content_routing_http_test.go | 4 ++-- test/cli/delegated_routing_v1_http_server_test.go | 2 +- test/dependencies/go.mod | 2 +- test/dependencies/go.sum | 4 ++-- 9 files changed, 14 insertions(+), 14 deletions(-) diff --git a/core/corehttp/routing.go b/core/corehttp/routing.go index e648afb4e..88d9de886 100644 --- a/core/corehttp/routing.go +++ b/core/corehttp/routing.go @@ -42,7 +42,7 @@ func (r *contentRouter) ProvideBitswap(ctx context.Context, req *server.BitswapW return 0, routing.ErrNotSupported } -func (r *contentRouter) FindPeers(ctx context.Context, pid peer.ID, limit int) (iter.ResultIter[types.Record], error) { +func (r *contentRouter) FindPeers(ctx context.Context, pid peer.ID, limit int) (iter.ResultIter[*types.PeerRecord], error) { ctx, cancel := context.WithCancel(ctx) defer cancel() @@ -60,7 +60,7 @@ func (r *contentRouter) FindPeers(ctx context.Context, pid peer.ID, limit int) ( rec.Addrs = append(rec.Addrs, types.Multiaddr{Multiaddr: addr}) } - return iter.ToResultIter[types.Record](iter.FromSlice[types.Record]([]types.Record{rec})), nil + return iter.ToResultIter[*types.PeerRecord](iter.FromSlice[*types.PeerRecord]([]*types.PeerRecord{rec})), nil } func (r *contentRouter) GetIPNS(ctx context.Context, name ipns.Name) (*ipns.Record, error) { diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 65d168407..2ee7b6d6c 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.20 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.13.2-0.20231009073559-45c797e0ccea + github.com/ipfs/boxo v0.13.2-0.20231017164040-0a566c9ee75f github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.31.0 github.com/multiformats/go-multiaddr v0.11.0 diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 1c5e4864c..b8632f40d 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -300,8 +300,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.13.2-0.20231009073559-45c797e0ccea h1:CygWxN8BL+d1F6PBOI+02UKqkpASP0ai459aw6ANZTg= -github.com/ipfs/boxo v0.13.2-0.20231009073559-45c797e0ccea/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk= +github.com/ipfs/boxo v0.13.2-0.20231017164040-0a566c9ee75f h1:iSo5r2GcXv5lX+UwVmarbSB9OjtvfnqQ4nwiiWWib8I= +github.com/ipfs/boxo v0.13.2-0.20231017164040-0a566c9ee75f/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= diff --git a/go.mod b/go.mod index 5805f1cbe..041ca6ef3 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( github.com/fsnotify/fsnotify v1.6.0 github.com/google/uuid v1.3.1 github.com/hashicorp/go-multierror v1.1.1 - github.com/ipfs/boxo v0.13.2-0.20231009073559-45c797e0ccea + github.com/ipfs/boxo v0.13.2-0.20231017164040-0a566c9ee75f github.com/ipfs/go-block-format v0.2.0 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 diff --git a/go.sum b/go.sum index 0905dc22d..71507968a 100644 --- a/go.sum +++ b/go.sum @@ -335,8 +335,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.13.2-0.20231009073559-45c797e0ccea h1:CygWxN8BL+d1F6PBOI+02UKqkpASP0ai459aw6ANZTg= -github.com/ipfs/boxo v0.13.2-0.20231009073559-45c797e0ccea/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk= +github.com/ipfs/boxo v0.13.2-0.20231017164040-0a566c9ee75f h1:iSo5r2GcXv5lX+UwVmarbSB9OjtvfnqQ4nwiiWWib8I= +github.com/ipfs/boxo v0.13.2-0.20231017164040-0a566c9ee75f/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= diff --git a/test/cli/content_routing_http_test.go b/test/cli/content_routing_http_test.go index 652c8ac59..aea5c41ca 100644 --- a/test/cli/content_routing_http_test.go +++ b/test/cli/content_routing_http_test.go @@ -43,11 +43,11 @@ func (r *fakeHTTPContentRouter) ProvideBitswap(ctx context.Context, req *server. return 0, nil } -func (r *fakeHTTPContentRouter) FindPeers(ctx context.Context, pid peer.ID, limit int) (iter.ResultIter[types.Record], error) { +func (r *fakeHTTPContentRouter) FindPeers(ctx context.Context, pid peer.ID, limit int) (iter.ResultIter[*types.PeerRecord], error) { r.m.Lock() defer r.m.Unlock() r.findPeersCalls++ - return iter.FromSlice([]iter.Result[types.Record]{}), nil + return iter.FromSlice([]iter.Result[*types.PeerRecord]{}), nil } func (r *fakeHTTPContentRouter) GetIPNS(ctx context.Context, name ipns.Name) (*ipns.Record, error) { diff --git a/test/cli/delegated_routing_v1_http_server_test.go b/test/cli/delegated_routing_v1_http_server_test.go index 440510c1f..f2bd98cb7 100644 --- a/test/cli/delegated_routing_v1_http_server_test.go +++ b/test/cli/delegated_routing_v1_http_server_test.go @@ -80,7 +80,7 @@ func TestRoutingV1Server(t *testing.T) { assert.IsType(t, records[0].GetSchema(), records[0].GetSchema()) assert.IsType(t, records[0], &types.PeerRecord{}) - peer := records[0].(*types.PeerRecord) + peer := records[0] assert.Equal(t, nodes[2].PeerID().String(), peer.ID.String()) assert.NotEmpty(t, peer.Addrs) }) diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 773c9a2c9..3a9350bc3 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -7,7 +7,7 @@ replace github.com/ipfs/kubo => ../../ require ( github.com/Kubuxu/gocovmerge v0.0.0-20161216165753-7ecaa51963cd github.com/golangci/golangci-lint v1.54.1 - github.com/ipfs/boxo v0.13.2-0.20231009073559-45c797e0ccea + github.com/ipfs/boxo v0.13.2-0.20231017164040-0a566c9ee75f github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 github.com/ipfs/go-datastore v0.6.0 diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index d47325a08..4d5ed7e80 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -396,8 +396,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.13.2-0.20231009073559-45c797e0ccea h1:CygWxN8BL+d1F6PBOI+02UKqkpASP0ai459aw6ANZTg= -github.com/ipfs/boxo v0.13.2-0.20231009073559-45c797e0ccea/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk= +github.com/ipfs/boxo v0.13.2-0.20231017164040-0a566c9ee75f h1:iSo5r2GcXv5lX+UwVmarbSB9OjtvfnqQ4nwiiWWib8I= +github.com/ipfs/boxo v0.13.2-0.20231017164040-0a566c9ee75f/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs= From faac7c183588115aa2acc3c1ab5df408d2477845 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Wed, 18 Oct 2023 10:12:37 +0200 Subject: [PATCH 0909/1212] feat!: namesys refactor, ipns TTL bubbled up to gateway (#459) This commit was moved from ipfs/boxo@a50f784985ddfc25ec8d25aced2ca058469a3390 --- core/coreiface/options/name.go | 6 +- core/coreiface/options/namesys/opts.go | 131 ------------------------- 2 files changed, 3 insertions(+), 134 deletions(-) delete mode 100644 core/coreiface/options/namesys/opts.go diff --git a/core/coreiface/options/name.go b/core/coreiface/options/name.go index 35e78c394..7b4b6a8fd 100644 --- a/core/coreiface/options/name.go +++ b/core/coreiface/options/name.go @@ -3,7 +3,7 @@ package options import ( "time" - ropts "github.com/ipfs/boxo/coreiface/options/namesys" + "github.com/ipfs/boxo/namesys" ) const ( @@ -21,7 +21,7 @@ type NamePublishSettings struct { type NameResolveSettings struct { Cache bool - ResolveOpts []ropts.ResolveOpt + ResolveOpts []namesys.ResolveOption } type ( @@ -123,7 +123,7 @@ func (nameOpts) Cache(cache bool) NameResolveOption { } } -func (nameOpts) ResolveOption(opt ropts.ResolveOpt) NameResolveOption { +func (nameOpts) ResolveOption(opt namesys.ResolveOption) NameResolveOption { return func(settings *NameResolveSettings) error { settings.ResolveOpts = append(settings.ResolveOpts, opt) return nil diff --git a/core/coreiface/options/namesys/opts.go b/core/coreiface/options/namesys/opts.go deleted file mode 100644 index ed568200b..000000000 --- a/core/coreiface/options/namesys/opts.go +++ /dev/null @@ -1,131 +0,0 @@ -package nsopts - -import ( - "time" -) - -const ( - // DefaultDepthLimit is the default depth limit used by Resolve. - DefaultDepthLimit = 32 - - // UnlimitedDepth allows infinite recursion in Resolve. You - // probably don't want to use this, but it's here if you absolutely - // trust resolution to eventually complete and can't put an upper - // limit on how many steps it will take. - UnlimitedDepth = 0 - - // DefaultIPNSRecordTTL specifies the time that the record can be cached - // before checking if its validity again. - DefaultIPNSRecordTTL = time.Minute - - // DefaultIPNSRecordEOL specifies the time that the network will cache IPNS - // records after being published. Records should be re-published before this - // interval expires. We use the same default expiration as the DHT. - DefaultIPNSRecordEOL = 48 * time.Hour -) - -// ResolveOpts specifies options for resolving an IPNS path -type ResolveOpts struct { - // Recursion depth limit - Depth uint - // The number of IPNS records to retrieve from the DHT - // (the best record is selected from this set) - DhtRecordCount uint - // The amount of time to wait for DHT records to be fetched - // and verified. A zero value indicates that there is no explicit - // timeout (although there is an implicit timeout due to dial - // timeouts within the DHT) - DhtTimeout time.Duration -} - -// DefaultResolveOpts returns the default options for resolving -// an IPNS path -func DefaultResolveOpts() ResolveOpts { - return ResolveOpts{ - Depth: DefaultDepthLimit, - DhtRecordCount: 16, - DhtTimeout: time.Minute, - } -} - -// ResolveOpt is used to set an option -type ResolveOpt func(*ResolveOpts) - -// Depth is the recursion depth limit -func Depth(depth uint) ResolveOpt { - return func(o *ResolveOpts) { - o.Depth = depth - } -} - -// DhtRecordCount is the number of IPNS records to retrieve from the DHT -func DhtRecordCount(count uint) ResolveOpt { - return func(o *ResolveOpts) { - o.DhtRecordCount = count - } -} - -// DhtTimeout is the amount of time to wait for DHT records to be fetched -// and verified. A zero value indicates that there is no explicit timeout -func DhtTimeout(timeout time.Duration) ResolveOpt { - return func(o *ResolveOpts) { - o.DhtTimeout = timeout - } -} - -// ProcessOpts converts an array of ResolveOpt into a ResolveOpts object -func ProcessOpts(opts []ResolveOpt) ResolveOpts { - rsopts := DefaultResolveOpts() - for _, option := range opts { - option(&rsopts) - } - return rsopts -} - -// PublishOptions specifies options for publishing an IPNS record. -type PublishOptions struct { - EOL time.Time - TTL time.Duration - CompatibleWithV1 bool -} - -// DefaultPublishOptions returns the default options for publishing an IPNS record. -func DefaultPublishOptions() PublishOptions { - return PublishOptions{ - EOL: time.Now().Add(DefaultIPNSRecordEOL), - TTL: DefaultIPNSRecordTTL, - } -} - -// PublishOption is used to set an option for PublishOpts. -type PublishOption func(*PublishOptions) - -// PublishWithEOL sets an EOL. -func PublishWithEOL(eol time.Time) PublishOption { - return func(o *PublishOptions) { - o.EOL = eol - } -} - -// PublishWithEOL sets a TTL. -func PublishWithTTL(ttl time.Duration) PublishOption { - return func(o *PublishOptions) { - o.TTL = ttl - } -} - -// PublishCompatibleWithV1 sets compatibility with IPNS Records V1. -func PublishCompatibleWithV1(compatible bool) PublishOption { - return func(o *PublishOptions) { - o.CompatibleWithV1 = compatible - } -} - -// ProcessPublishOptions converts an array of PublishOpt into a PublishOpts object. -func ProcessPublishOptions(opts []PublishOption) PublishOptions { - rsopts := DefaultPublishOptions() - for _, option := range opts { - option(&rsopts) - } - return rsopts -} From 4695fd9fed4c46a13076c569e5abc0dcc9a0acd8 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Wed, 18 Oct 2023 10:23:50 +0200 Subject: [PATCH 0910/1212] refactor: namesys cleanup, gateway /ipns/ ttl (#10115) --- client/rpc/name.go | 14 +++++----- core/commands/dht_test.go | 2 +- core/commands/dns.go | 15 +++++++---- core/commands/name/ipns.go | 16 +++++------ core/commands/name/publish.go | 16 +++++------ core/commands/resolve.go | 9 +++---- core/coreapi/name.go | 16 ++++++----- core/coreapi/path.go | 8 +++--- core/corehttp/gateway.go | 7 ++--- core/corehttp/gateway_test.go | 33 +++++++++++++---------- docs/changelogs/v0.24.md | 37 ++++++++++++++++++++++++++ docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 +-- fuse/ipns/common.go | 4 +-- go.mod | 2 +- go.sum | 4 +-- test/cli/gateway_test.go | 15 ++++++++++- test/dependencies/go.mod | 10 ++++++- test/dependencies/go.sum | 23 ++++++++++++++-- test/sharness/t0160-resolve.sh | 5 +++- 20 files changed, 167 insertions(+), 75 deletions(-) diff --git a/client/rpc/name.go b/client/rpc/name.go index 223b7a226..eb01ee3cd 100644 --- a/client/rpc/name.go +++ b/client/rpc/name.go @@ -8,8 +8,8 @@ import ( iface "github.com/ipfs/boxo/coreiface" caopts "github.com/ipfs/boxo/coreiface/options" - nsopts "github.com/ipfs/boxo/coreiface/options/namesys" "github.com/ipfs/boxo/ipns" + "github.com/ipfs/boxo/namesys" "github.com/ipfs/boxo/path" ) @@ -49,9 +49,9 @@ func (api *NameAPI) Search(ctx context.Context, name string, opts ...caopts.Name return nil, err } - ropts := nsopts.ProcessOpts(options.ResolveOpts) - if ropts.Depth != nsopts.DefaultDepthLimit && ropts.Depth != 1 { - return nil, fmt.Errorf("Name.Resolve: depth other than 1 or %d not supported", nsopts.DefaultDepthLimit) + ropts := namesys.ProcessResolveOptions(options.ResolveOpts) + if ropts.Depth != namesys.DefaultDepthLimit && ropts.Depth != 1 { + return nil, fmt.Errorf("Name.Resolve: depth other than 1 or %d not supported", namesys.DefaultDepthLimit) } req := api.core().Request("name/resolve", name). @@ -110,9 +110,9 @@ func (api *NameAPI) Resolve(ctx context.Context, name string, opts ...caopts.Nam return nil, err } - ropts := nsopts.ProcessOpts(options.ResolveOpts) - if ropts.Depth != nsopts.DefaultDepthLimit && ropts.Depth != 1 { - return nil, fmt.Errorf("Name.Resolve: depth other than 1 or %d not supported", nsopts.DefaultDepthLimit) + ropts := namesys.ProcessResolveOptions(options.ResolveOpts) + if ropts.Depth != namesys.DefaultDepthLimit && ropts.Depth != 1 { + return nil, fmt.Errorf("Name.Resolve: depth other than 1 or %d not supported", namesys.DefaultDepthLimit) } req := api.core().Request("name/resolve", name). diff --git a/core/commands/dht_test.go b/core/commands/dht_test.go index b0e03f5cd..f0f7de703 100644 --- a/core/commands/dht_test.go +++ b/core/commands/dht_test.go @@ -11,7 +11,7 @@ import ( func TestKeyTranslation(t *testing.T) { pid := test.RandPeerIDFatal(t) - pkname := namesys.PkKeyForID(pid) + pkname := namesys.PkRoutingKey(pid) ipnsname := ipns.NameFromPeer(pid).RoutingKey() pkk, err := escapeDhtKey("/pk/" + pid.String()) diff --git a/core/commands/dns.go b/core/commands/dns.go index 8ab76e64d..5126a6cb1 100644 --- a/core/commands/dns.go +++ b/core/commands/dns.go @@ -4,8 +4,8 @@ import ( "fmt" "io" - nsopts "github.com/ipfs/boxo/coreiface/options/namesys" namesys "github.com/ipfs/boxo/namesys" + "github.com/ipfs/boxo/path" cmdenv "github.com/ipfs/kubo/core/commands/cmdenv" ncmd "github.com/ipfs/kubo/core/commands/name" @@ -47,16 +47,21 @@ It will work across multiple DNSLinks and IPNS keys. name := req.Arguments[0] resolver := namesys.NewDNSResolver(node.DNSResolver.LookupTXT) - var routing []nsopts.ResolveOpt + var routing []namesys.ResolveOption if !recursive { - routing = append(routing, nsopts.Depth(1)) + routing = append(routing, namesys.ResolveWithDepth(1)) } - output, err := resolver.Resolve(req.Context, name, routing...) + p, err := path.NewPath(name) + if err != nil { + return err + } + + val, err := resolver.Resolve(req.Context, p, routing...) if err != nil && (recursive || err != namesys.ErrResolveRecursion) { return err } - return cmds.EmitOnce(res, &ncmd.ResolvedPath{Path: output.String()}) + return cmds.EmitOnce(res, &ncmd.ResolvedPath{Path: val.Path.String()}) }, Encoders: cmds.EncoderMap{ cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *ncmd.ResolvedPath) error { diff --git a/core/commands/name/ipns.go b/core/commands/name/ipns.go index a305c49ad..e03b9c66b 100644 --- a/core/commands/name/ipns.go +++ b/core/commands/name/ipns.go @@ -7,14 +7,12 @@ import ( "strings" "time" - namesys "github.com/ipfs/boxo/namesys" - cmdenv "github.com/ipfs/kubo/core/commands/cmdenv" - options "github.com/ipfs/boxo/coreiface/options" - nsopts "github.com/ipfs/boxo/coreiface/options/namesys" + "github.com/ipfs/boxo/namesys" "github.com/ipfs/boxo/path" cmds "github.com/ipfs/go-ipfs-cmds" logging "github.com/ipfs/go-log" + cmdenv "github.com/ipfs/kubo/core/commands/cmdenv" ) var log = logging.Logger("core/commands/ipns") @@ -75,8 +73,8 @@ Resolve the value of a dnslink: Options: []cmds.Option{ cmds.BoolOption(recursiveOptionName, "r", "Resolve until the result is not an IPNS name.").WithDefault(true), cmds.BoolOption(nocacheOptionName, "n", "Do not use cached entries."), - cmds.UintOption(dhtRecordCountOptionName, "dhtrc", "Number of records to request for DHT resolution."), - cmds.StringOption(dhtTimeoutOptionName, "dhtt", "Max time to collect values during DHT resolution eg \"30s\". Pass 0 for no timeout."), + cmds.UintOption(dhtRecordCountOptionName, "dhtrc", "Number of records to request for DHT resolution.").WithDefault(uint(namesys.DefaultResolverDhtRecordCount)), + cmds.StringOption(dhtTimeoutOptionName, "dhtt", "Max time to collect values during DHT resolution eg \"30s\". Pass 0 for no timeout.").WithDefault(namesys.DefaultResolverDhtTimeout.String()), cmds.BoolOption(streamOptionName, "s", "Stream entries as they are found."), }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { @@ -108,10 +106,10 @@ Resolve the value of a dnslink: } if !recursive { - opts = append(opts, options.Name.ResolveOption(nsopts.Depth(1))) + opts = append(opts, options.Name.ResolveOption(namesys.ResolveWithDepth(1))) } if rcok { - opts = append(opts, options.Name.ResolveOption(nsopts.DhtRecordCount(rc))) + opts = append(opts, options.Name.ResolveOption(namesys.ResolveWithDhtRecordCount(rc))) } if dhttok { d, err := time.ParseDuration(dhtt) @@ -121,7 +119,7 @@ Resolve the value of a dnslink: if d < 0 { return errors.New("DHT timeout value must be >= 0") } - opts = append(opts, options.Name.ResolveOption(nsopts.DhtTimeout(d))) + opts = append(opts, options.Name.ResolveOption(namesys.ResolveWithDhtTimeout(d))) } if !strings.HasPrefix(name, "/ipns/") { diff --git a/core/commands/name/publish.go b/core/commands/name/publish.go index a817d52f9..6365470b6 100644 --- a/core/commands/name/publish.go +++ b/core/commands/name/publish.go @@ -11,6 +11,7 @@ import ( iface "github.com/ipfs/boxo/coreiface" options "github.com/ipfs/boxo/coreiface/options" + ipns "github.com/ipfs/boxo/ipns" cmds "github.com/ipfs/go-ipfs-cmds" ke "github.com/ipfs/kubo/core/commands/keyencode" ) @@ -59,7 +60,7 @@ Publish an with another name, added by an 'ipfs key' command: > ipfs name publish --key=mykey /ipfs/QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy Published to QmSrPmbaUKA3ZodhzPWZnpFgcPMFWF4QsxXbkWfEptTBJd: /ipfs/QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy -Alternatively, publish an using a valid PeerID (as listed by +Alternatively, publish an using a valid PeerID (as listed by 'ipfs key list -l'): > ipfs name publish --key=QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n /ipfs/QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy @@ -72,16 +73,13 @@ Alternatively, publish an using a valid PeerID (as listed by cmds.StringArg(ipfsPathOptionName, true, false, "ipfs path of the object to be published.").EnableStdin(), }, Options: []cmds.Option{ - cmds.BoolOption(resolveOptionName, "Check if the given path can be resolved before publishing.").WithDefault(true), - cmds.StringOption(lifeTimeOptionName, "t", - `Time duration that the record will be valid for. <> - This accepts durations such as "300s", "1.5h" or "2h45m". Valid time units are - "ns", "us" (or "µs"), "ms", "s", "m", "h".`).WithDefault("24h"), - cmds.BoolOption(allowOfflineOptionName, "When offline, save the IPNS record to the the local datastore without broadcasting to the network instead of simply failing."), - cmds.StringOption(ttlOptionName, "Time duration this record should be cached for. Uses the same syntax as the lifetime option. (caution: experimental)"), cmds.StringOption(keyOptionName, "k", "Name of the key to be used or a valid PeerID, as listed by 'ipfs key list -l'.").WithDefault("self"), - cmds.BoolOption(quieterOptionName, "Q", "Write only final hash."), + cmds.BoolOption(resolveOptionName, "Check if the given path can be resolved before publishing.").WithDefault(true), + cmds.StringOption(lifeTimeOptionName, "t", `Time duration the signed record will be valid for. Accepts durations such as "300s", "1.5h" or "7d2h45m"`).WithDefault(ipns.DefaultRecordLifetime.String()), + cmds.StringOption(ttlOptionName, "Time duration hint, akin to --lifetime, indicating how long to cache this record before checking for updates.").WithDefault(ipns.DefaultRecordTTL.String()), + cmds.BoolOption(quieterOptionName, "Q", "Write only final IPNS Name encoded as CIDv1 (for use in /ipns content paths)."), cmds.BoolOption(v1compatOptionName, "Produce a backward-compatible IPNS Record by including fields for both V1 and V2 signatures.").WithDefault(true), + cmds.BoolOption(allowOfflineOptionName, "When --offline, save the IPNS record to the the local datastore without broadcasting to the network (instead of failing)."), ke.OptionIPNSBase, }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { diff --git a/core/commands/resolve.go b/core/commands/resolve.go index 5db392bf2..67450f4cb 100644 --- a/core/commands/resolve.go +++ b/core/commands/resolve.go @@ -8,14 +8,13 @@ import ( "time" ns "github.com/ipfs/boxo/namesys" - "github.com/ipfs/boxo/path" cidenc "github.com/ipfs/go-cidutil/cidenc" cmdenv "github.com/ipfs/kubo/core/commands/cmdenv" "github.com/ipfs/kubo/core/commands/cmdutils" ncmd "github.com/ipfs/kubo/core/commands/name" options "github.com/ipfs/boxo/coreiface/options" - nsopts "github.com/ipfs/boxo/coreiface/options/namesys" + "github.com/ipfs/boxo/path" cmds "github.com/ipfs/go-ipfs-cmds" ) @@ -87,11 +86,11 @@ Resolve the value of an IPFS DAG path: rc, rcok := req.Options[resolveDhtRecordCountOptionName].(uint) dhtt, dhttok := req.Options[resolveDhtTimeoutOptionName].(string) ropts := []options.NameResolveOption{ - options.Name.ResolveOption(nsopts.Depth(1)), + options.Name.ResolveOption(ns.ResolveWithDepth(1)), } if rcok { - ropts = append(ropts, options.Name.ResolveOption(nsopts.DhtRecordCount(rc))) + ropts = append(ropts, options.Name.ResolveOption(ns.ResolveWithDhtRecordCount(rc))) } if dhttok { d, err := time.ParseDuration(dhtt) @@ -101,7 +100,7 @@ Resolve the value of an IPFS DAG path: if d < 0 { return errors.New("DHT timeout value must be >= 0") } - ropts = append(ropts, options.Name.ResolveOption(nsopts.DhtTimeout(d))) + ropts = append(ropts, options.Name.ResolveOption(ns.ResolveWithDhtTimeout(d))) } p, err := api.Name().Resolve(req.Context, name, ropts...) // ErrResolveRecursion is fine diff --git a/core/coreapi/name.go b/core/coreapi/name.go index 0a398ef26..4f6c1a3cc 100644 --- a/core/coreapi/name.go +++ b/core/coreapi/name.go @@ -15,7 +15,6 @@ import ( coreiface "github.com/ipfs/boxo/coreiface" caopts "github.com/ipfs/boxo/coreiface/options" - nsopts "github.com/ipfs/boxo/coreiface/options/namesys" "github.com/ipfs/boxo/path" ci "github.com/libp2p/go-libp2p/core/crypto" peer "github.com/libp2p/go-libp2p/core/peer" @@ -57,13 +56,13 @@ func (api *NameAPI) Publish(ctx context.Context, p path.Path, opts ...caopts.Nam eol := time.Now().Add(options.ValidTime) - publishOptions := []nsopts.PublishOption{ - nsopts.PublishWithEOL(eol), - nsopts.PublishCompatibleWithV1(options.CompatibleWithV1), + publishOptions := []namesys.PublishOption{ + namesys.PublishWithEOL(eol), + namesys.PublishWithIPNSOption(ipns.WithV1Compatibility(options.CompatibleWithV1)), } if options.TTL != nil { - publishOptions = append(publishOptions, nsopts.PublishWithTTL(*options.TTL)) + publishOptions = append(publishOptions, namesys.PublishWithTTL(*options.TTL)) } err = api.namesys.Publish(ctx, k, p, publishOptions...) @@ -109,10 +108,15 @@ func (api *NameAPI) Search(ctx context.Context, name string, opts ...caopts.Name name = "/ipns/" + name } + p, err := path.NewPath(name) + if err != nil { + return nil, err + } + out := make(chan coreiface.IpnsResult) go func() { defer close(out) - for res := range resolver.ResolveAsync(ctx, name, options.ResolveOpts...) { + for res := range resolver.ResolveAsync(ctx, p, options.ResolveOpts...) { select { case out <- coreiface.IpnsResult{Path: res.Path, Err: res.Err}: case <-ctx.Done(): diff --git a/core/coreapi/path.go b/core/coreapi/path.go index 63d277ff2..1d8e868e4 100644 --- a/core/coreapi/path.go +++ b/core/coreapi/path.go @@ -2,9 +2,10 @@ package coreapi import ( "context" + "errors" "fmt" - "github.com/ipfs/boxo/namesys/resolve" + "github.com/ipfs/boxo/namesys" "github.com/ipfs/kubo/tracing" "go.opentelemetry.io/otel/attribute" @@ -40,12 +41,13 @@ func (api *CoreAPI) ResolvePath(ctx context.Context, p path.Path) (path.Immutabl ctx, span := tracing.Span(ctx, "CoreAPI", "ResolvePath", trace.WithAttributes(attribute.String("path", p.String()))) defer span.End() - p, err := resolve.ResolveIPNS(ctx, api.namesys, p) - if err == resolve.ErrNoNamesys { + res, err := namesys.Resolve(ctx, api.namesys, p) + if errors.Is(err, namesys.ErrNoNamesys) { return path.ImmutablePath{}, nil, coreiface.ErrOffline } else if err != nil { return path.ImmutablePath{}, nil, err } + p = res.Path var resolver ipfspathresolver.Resolver switch p.Namespace() { diff --git a/core/corehttp/gateway.go b/core/corehttp/gateway.go index 705171d79..ec9abef8e 100644 --- a/core/corehttp/gateway.go +++ b/core/corehttp/gateway.go @@ -7,6 +7,7 @@ import ( "io" "net" "net/http" + "time" "github.com/ipfs/boxo/blockservice" iface "github.com/ipfs/boxo/coreiface" @@ -195,10 +196,10 @@ func (o *offlineGatewayErrWrapper) GetIPNSRecord(ctx context.Context, c cid.Cid) return rec, err } -func (o *offlineGatewayErrWrapper) ResolveMutable(ctx context.Context, path path.Path) (path.ImmutablePath, error) { - imPath, err := o.gwimpl.ResolveMutable(ctx, path) +func (o *offlineGatewayErrWrapper) ResolveMutable(ctx context.Context, path path.Path) (path.ImmutablePath, time.Duration, time.Time, error) { + imPath, ttl, lastMod, err := o.gwimpl.ResolveMutable(ctx, path) err = offlineErrWrap(err) - return imPath, err + return imPath, ttl, lastMod, err } func (o *offlineGatewayErrWrapper) GetDNSLinkRecord(ctx context.Context, s string) (path.Path, error) { diff --git a/core/corehttp/gateway_test.go b/core/corehttp/gateway_test.go index 352f10490..41a1c5821 100644 --- a/core/corehttp/gateway_test.go +++ b/core/corehttp/gateway_test.go @@ -17,7 +17,6 @@ import ( "github.com/stretchr/testify/assert" iface "github.com/ipfs/boxo/coreiface" - nsopts "github.com/ipfs/boxo/coreiface/options/namesys" "github.com/ipfs/boxo/path" "github.com/ipfs/go-datastore" syncds "github.com/ipfs/go-datastore/sync" @@ -27,41 +26,47 @@ import ( type mockNamesys map[string]path.Path -func (m mockNamesys) Resolve(ctx context.Context, name string, opts ...nsopts.ResolveOpt) (value path.Path, err error) { - cfg := nsopts.DefaultResolveOpts() +func (m mockNamesys) Resolve(ctx context.Context, p path.Path, opts ...namesys.ResolveOption) (namesys.Result, error) { + cfg := namesys.DefaultResolveOptions() for _, o := range opts { o(&cfg) } depth := cfg.Depth - if depth == nsopts.UnlimitedDepth { + if depth == namesys.UnlimitedDepth { // max uint depth = ^uint(0) } + var ( + value path.Path + ) + name := path.SegmentsToString(p.Segments()[:2]...) for strings.HasPrefix(name, "/ipns/") { if depth == 0 { - return value, namesys.ErrResolveRecursion + return namesys.Result{Path: value}, namesys.ErrResolveRecursion } depth-- - var ok bool - value, ok = m[name] + v, ok := m[name] if !ok { - return nil, namesys.ErrResolveFailed + return namesys.Result{}, namesys.ErrResolveFailed } + value = v name = value.String() } - return value, nil + + value, err := path.Join(value, p.Segments()[2:]...) + return namesys.Result{Path: value}, err } -func (m mockNamesys) ResolveAsync(ctx context.Context, name string, opts ...nsopts.ResolveOpt) <-chan namesys.Result { - out := make(chan namesys.Result, 1) - v, err := m.Resolve(ctx, name, opts...) - out <- namesys.Result{Path: v, Err: err} +func (m mockNamesys) ResolveAsync(ctx context.Context, p path.Path, opts ...namesys.ResolveOption) <-chan namesys.AsyncResult { + out := make(chan namesys.AsyncResult, 1) + res, err := m.Resolve(ctx, p, opts...) + out <- namesys.AsyncResult{Path: res.Path, TTL: res.TTL, LastMod: res.LastMod, Err: err} close(out) return out } -func (m mockNamesys) Publish(ctx context.Context, name ci.PrivKey, value path.Path, opts ...nsopts.PublishOption) error { +func (m mockNamesys) Publish(ctx context.Context, name ci.PrivKey, value path.Path, opts ...namesys.PublishOption) error { return errors.New("not implemented for mockNamesys") } diff --git a/docs/changelogs/v0.24.md b/docs/changelogs/v0.24.md index a19526ad1..ad3374838 100644 --- a/docs/changelogs/v0.24.md +++ b/docs/changelogs/v0.24.md @@ -7,6 +7,8 @@ - [Overview](#overview) - [🔦 Highlights](#-highlights) - [Gateway: the root of the CARs are no longer meaningful](#gateway-the-root-of-the-cars-are-no-longer-meaningful) + - [IPNS: improved publishing defaults](#ipns-improved-publishing-defaults) + - [IPNS: record TTL is used for caching](#ipns-record-ttl-is-used-for-caching) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -22,6 +24,41 @@ path. However, in situations where the path cannot be resolved, such as when the path does not exist, a CAR will be sent with a root of `bafkqaaa` (empty CID). This CAR will contain all blocks necessary to validate that the path does not exist. +#### IPNS: improved publishing defaults + +This release changes the default values used when publishing IPNS record +via `ipfs name publish` command: + +- Default `--lifetime` increased from `24h` to `48h` to take full advantage of + the increased expiration window of Amino DHT + ([go-libp2p-kad-dht#793](https://github.com/libp2p/go-libp2p-kad-dht/pull/793)) +- Default `--ttl` increased from `1m` to `1h` to improve website caching and follow + saner defaults present in similar systems like DNS + ([specs#371](https://github.com/ipfs/specs/pull/371)) + +This change only impacts the implicit defaults, when mentioned parameters are omitted +during publishing. Users are free to override the default if different value +makes more sense for their use case. + +#### IPNS: record TTL is used for caching + +In this release, we've made significant improvements to IPNS caching. + +Previously, the TTL value in IPNS records was not utilized, and the +`boxo/namesys` library maintained a static one-minute resolution cache. + +With this update, IPNS publishers gain more control over how long a valid IPNS +record remains cached before checking an upstream routing system, such as Amino +DHT, for updates. The TTL value in the IPNS record now serves as a hint for: + +- `boxo/namesys`: the internal cache, determining how long the IPNS resolution + result is cached before asking upsteam routing systems for updates. +- `boxo/gateway`: the `Cache-Control` HTTP header in responses to requests made + for `/ipns/name` content paths. + +These changes make it easier for rarely updated IPNS-hosted websites to be +cached more efficiently and load faster in browser contexts. + ### 📝 Changelog ### 👨‍👩‍👧‍👦 Contributors diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 2ee7b6d6c..8c2edff6d 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.20 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.13.2-0.20231017164040-0a566c9ee75f + github.com/ipfs/boxo v0.13.2-0.20231018081237-a50f784985dd github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.31.0 github.com/multiformats/go-multiaddr v0.11.0 diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index b8632f40d..8fab68dde 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -300,8 +300,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.13.2-0.20231017164040-0a566c9ee75f h1:iSo5r2GcXv5lX+UwVmarbSB9OjtvfnqQ4nwiiWWib8I= -github.com/ipfs/boxo v0.13.2-0.20231017164040-0a566c9ee75f/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk= +github.com/ipfs/boxo v0.13.2-0.20231018081237-a50f784985dd h1:CWz2mhz+cmkLRlKgQYlKXkDtx4oWYkCorSSF4ZWkH3o= +github.com/ipfs/boxo v0.13.2-0.20231018081237-a50f784985dd/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= diff --git a/fuse/ipns/common.go b/fuse/ipns/common.go index 69924738e..7306196c8 100644 --- a/fuse/ipns/common.go +++ b/fuse/ipns/common.go @@ -4,7 +4,7 @@ import ( "context" ft "github.com/ipfs/boxo/ipld/unixfs" - nsys "github.com/ipfs/boxo/namesys" + "github.com/ipfs/boxo/namesys" "github.com/ipfs/boxo/path" "github.com/ipfs/kubo/core" ci "github.com/libp2p/go-libp2p/core/crypto" @@ -28,7 +28,7 @@ func InitializeKeyspace(n *core.IpfsNode, key ci.PrivKey) error { return err } - pub := nsys.NewIpnsPublisher(n.Routing, n.Repo.Datastore()) + pub := namesys.NewIPNSPublisher(n.Routing, n.Repo.Datastore()) return pub.Publish(ctx, key, path.FromCid(emptyDir.Cid())) } diff --git a/go.mod b/go.mod index 041ca6ef3..68db957cd 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( github.com/fsnotify/fsnotify v1.6.0 github.com/google/uuid v1.3.1 github.com/hashicorp/go-multierror v1.1.1 - github.com/ipfs/boxo v0.13.2-0.20231017164040-0a566c9ee75f + github.com/ipfs/boxo v0.13.2-0.20231018081237-a50f784985dd github.com/ipfs/go-block-format v0.2.0 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 diff --git a/go.sum b/go.sum index 71507968a..5b612c73a 100644 --- a/go.sum +++ b/go.sum @@ -335,8 +335,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.13.2-0.20231017164040-0a566c9ee75f h1:iSo5r2GcXv5lX+UwVmarbSB9OjtvfnqQ4nwiiWWib8I= -github.com/ipfs/boxo v0.13.2-0.20231017164040-0a566c9ee75f/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk= +github.com/ipfs/boxo v0.13.2-0.20231018081237-a50f784985dd h1:CWz2mhz+cmkLRlKgQYlKXkDtx4oWYkCorSSF4ZWkH3o= +github.com/ipfs/boxo v0.13.2-0.20231018081237-a50f784985dd/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= diff --git a/test/cli/gateway_test.go b/test/cli/gateway_test.go index 719567531..c98c62c47 100644 --- a/test/cli/gateway_test.go +++ b/test/cli/gateway_test.go @@ -8,6 +8,8 @@ import ( "os" "path/filepath" "regexp" + "strconv" + "strings" "testing" "github.com/ipfs/kubo/config" @@ -169,7 +171,7 @@ func TestGateway(t *testing.T) { t.Run("IPNS", func(t *testing.T) { t.Parallel() - node.IPFS("name", "publish", "--allow-offline", cid) + node.IPFS("name", "publish", "--allow-offline", "--ttl", "42h", cid) t.Run("GET invalid IPNS root returns 500 (Internal Server Error)", func(t *testing.T) { t.Parallel() @@ -184,6 +186,17 @@ func TestGateway(t *testing.T) { assert.Equal(t, "Hello Worlds!", resp.Body) }) + t.Run("GET IPNS path has correct Cache-Control", func(t *testing.T) { + t.Parallel() + resp := client.Get("/ipns/{{.PeerID}}") + assert.Equal(t, 200, resp.StatusCode) + cacheControl := resp.Headers.Get("Cache-Control") + assert.True(t, strings.HasPrefix(cacheControl, "public, max-age=")) + maxAge, err := strconv.Atoi(strings.TrimPrefix(cacheControl, "public, max-age=")) + assert.NoError(t, err) + assert.True(t, maxAge-151200 < 60) // MaxAge within 42h and 42h-1m + }) + t.Run("GET /ipfs/ipns/{peerid} returns redirect to the valid path", func(t *testing.T) { t.Parallel() resp := client.Get("/ipfs/ipns/{{.PeerID}}?query=to-remember") diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 3a9350bc3..fd8c94585 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -7,7 +7,7 @@ replace github.com/ipfs/kubo => ../../ require ( github.com/Kubuxu/gocovmerge v0.0.0-20161216165753-7ecaa51963cd github.com/golangci/golangci-lint v1.54.1 - github.com/ipfs/boxo v0.13.2-0.20231017164040-0a566c9ee75f + github.com/ipfs/boxo v0.13.2-0.20231018081237-a50f784985dd github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 github.com/ipfs/go-datastore v0.6.0 @@ -165,6 +165,10 @@ require ( github.com/libp2p/go-cidranger v1.1.0 // indirect github.com/libp2p/go-flow-metrics v0.1.0 // indirect github.com/libp2p/go-libp2p-asn-util v0.3.0 // indirect + github.com/libp2p/go-libp2p-kad-dht v0.24.4 // indirect + github.com/libp2p/go-libp2p-kbucket v0.6.3 // indirect + github.com/libp2p/go-libp2p-record v0.2.0 // indirect + github.com/libp2p/go-libp2p-routing-helpers v0.7.3 // indirect github.com/libp2p/go-msgio v0.3.0 // indirect github.com/libp2p/go-nat v0.2.0 // indirect github.com/libp2p/go-netroute v0.2.1 // indirect @@ -264,11 +268,14 @@ require ( github.com/ultraware/whitespace v0.0.5 // indirect github.com/urfave/cli v1.22.10 // indirect github.com/uudashr/gocognit v1.0.7 // indirect + github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc // indirect + github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect github.com/xen0n/gosmopolitan v1.2.1 // indirect github.com/yagipy/maintidx v1.0.0 // indirect github.com/yeya24/promlinter v0.2.0 // indirect github.com/ykadowak/zerologlint v0.1.3 // indirect gitlab.com/bosi/decorder v0.4.0 // indirect + go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/otel v1.19.0 // indirect go.opentelemetry.io/otel/metric v1.19.0 // indirect go.opentelemetry.io/otel/trace v1.19.0 // indirect @@ -288,6 +295,7 @@ require ( golang.org/x/term v0.13.0 // indirect golang.org/x/text v0.13.0 // indirect golang.org/x/tools v0.13.0 // indirect + gonum.org/v1/gonum v0.13.0 // indirect google.golang.org/protobuf v1.31.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 4d5ed7e80..d37a47fe0 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -252,6 +252,7 @@ github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfU github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= @@ -310,6 +311,7 @@ github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ 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= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= @@ -396,8 +398,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.13.2-0.20231017164040-0a566c9ee75f h1:iSo5r2GcXv5lX+UwVmarbSB9OjtvfnqQ4nwiiWWib8I= -github.com/ipfs/boxo v0.13.2-0.20231017164040-0a566c9ee75f/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk= +github.com/ipfs/boxo v0.13.2-0.20231018081237-a50f784985dd h1:CWz2mhz+cmkLRlKgQYlKXkDtx4oWYkCorSSF4ZWkH3o= +github.com/ipfs/boxo v0.13.2-0.20231018081237-a50f784985dd/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs= @@ -546,7 +548,14 @@ github.com/libp2p/go-libp2p v0.31.0 h1:LFShhP8F6xthWiBBq3euxbKjZsoRajVEyBS9snfHx github.com/libp2p/go-libp2p v0.31.0/go.mod h1:W/FEK1c/t04PbRH3fA9i5oucu5YcgrG0JVoBWT1B7Eg= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= +github.com/libp2p/go-libp2p-kad-dht v0.24.4 h1:ktNiJe7ffsJ1wX3ULpMCwXts99mPqGFSE/Qn1i8pErQ= +github.com/libp2p/go-libp2p-kad-dht v0.24.4/go.mod h1:ybWBJ5Fbvz9sSLkNtXt+2+bK0JB8+tRPvhBbRGHegRU= +github.com/libp2p/go-libp2p-kbucket v0.6.3 h1:p507271wWzpy2f1XxPzCQG9NiN6R6lHL9GiSErbQQo0= +github.com/libp2p/go-libp2p-kbucket v0.6.3/go.mod h1:RCseT7AH6eJWxxk2ol03xtP9pEHetYSPXOaJnOiD8i0= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= +github.com/libp2p/go-libp2p-record v0.2.0/go.mod h1:I+3zMkvvg5m2OcSdoL0KPljyJyvNDFGKX7QdlpYUcwk= +github.com/libp2p/go-libp2p-routing-helpers v0.7.3 h1:u1LGzAMVRK9Nqq5aYDVOiq/HaB93U9WWczBzGyAC5ZY= +github.com/libp2p/go-libp2p-routing-helpers v0.7.3/go.mod h1:cN4mJAD/7zfPKXBcs9ze31JGYAZgzdABEm+q/hkswb8= github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA= github.com/libp2p/go-msgio v0.3.0 h1:mf3Z8B1xcFN314sWX+2vOTShIE0Mmn2TXn3YCUQGNj0= github.com/libp2p/go-msgio v0.3.0/go.mod h1:nyRM819GmVaF9LX3l03RMh10QdOroF++NBbxAb0mmDM= @@ -848,6 +857,7 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= @@ -887,9 +897,13 @@ github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMI github.com/warpfork/go-testmark v0.12.1 h1:rMgCpJfwy1sJ50x0M0NgyphxYYPMOODIJHhsXyEHU0s= github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0 h1:GDDkbFiaK8jsSDJfjId/PEGEShv6ugrt4kYsC5UIDaQ= github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= +github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc h1:BCPnHtcboadS0DvysUuJXZ4lWVv5Bh5i7+tbIyi+ck4= +github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc/go.mod h1:r45hJU7yEoA81k6MWNhpMj/kms0n14dkzkxYHoB96UM= github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11 h1:5HZfQkwe0mIfyDmc1Em5GqlNRzcdtlv4HTNmdpt7XH0= github.com/whyrusleeping/cbor-gen v0.0.0-20230126041949-52956bd4c9aa h1:EyA027ZAkuaCLoxVX4r1TZMPy1d31fM6hbfQ4OU4I5o= github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f h1:jQa4QT2UP9WYv2nzyawpKMOCl+Z/jW7djv2/J50lj9E= +github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 h1:EKhdznlJHPMoKr0XTrX+IlJs1LH3lyx2nfr1dOlZ79k= +github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc= github.com/xen0n/gosmopolitan v1.2.1 h1:3pttnTuFumELBRSh+KQs1zcz4fN6Zy7aB0xlnQSn1Iw= github.com/xen0n/gosmopolitan v1.2.1/go.mod h1:JsHq/Brs1o050OOdmzHeOr0N7OtlnKRAGAsElF8xBQA= github.com/yagipy/maintidx v1.0.0 h1:h5NvIsCz+nRDapQ0exNv4aJ0yXSI0420omVANTv3GJM= @@ -915,6 +929,8 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= +go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/otel v1.19.0 h1:MuS/TNf4/j4IXsZuJegVzI1cwut7Qc00344rgH7p8bs= go.opentelemetry.io/otel v1.19.0/go.mod h1:i0QyjOq3UPoTzff0PJB2N66fb4S0+rSbSB15/oyH9fY= go.opentelemetry.io/otel/metric v1.19.0 h1:aTzpGtV0ar9wlV4Sna9sdJyII5jTVJEvKETPiOKwvpE= @@ -1045,6 +1061,7 @@ golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= @@ -1266,6 +1283,8 @@ golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= +gonum.org/v1/gonum v0.13.0 h1:a0T3bh+7fhRyqeNbiC3qVHYmkiQgit3wnNan/2c0HMM= +gonum.org/v1/gonum v0.13.0/go.mod h1:/WPYRckkfWrhWefxyYTfrTtQR0KH4iyHNuzxqXAKyAU= google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y= diff --git a/test/sharness/t0160-resolve.sh b/test/sharness/t0160-resolve.sh index f65b29c11..5ec3f99be 100755 --- a/test/sharness/t0160-resolve.sh +++ b/test/sharness/t0160-resolve.sh @@ -30,8 +30,11 @@ test_resolve_setup_name() { local key="$1" local ref="$2" + # we pass here --ttl=0s to ensure that it does not get cached by namesys. + # the alternative would be to wait between tests to ensure that the namesys + # cache gets purged in time, but that adds runtime time for the tests. test_expect_success "resolve: prepare $key" ' - ipfs name publish --key="$key" --allow-offline "$ref" + ipfs name publish --key="$key" --ttl=0s --allow-offline "$ref" ' } From 89a476948b1d57cff3c7f07457aaccf2ea4feaf9 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Thu, 5 Oct 2023 21:14:32 +0200 Subject: [PATCH 0911/1212] tests: add new helia intergration tests --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index dd1648f21..fd7ba120d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -54,7 +54,7 @@ jobs: shell: bash strategy: matrix: - repo-to-test-against: ["helia", "helia-ipns", "helia-unixfs"] # this needs to be manually kept in sync as new helia tests are written + repo-to-test-against: ["helia", "helia-ipns", "helia-unixfs", "helia-car", "helia-dag-json", "helia-dag-cbor", "helia-json", "helia-mfs"] # this needs to be manually kept in sync as new helia tests are written steps: - uses: actions/setup-node@v3 with: From 4f303d3208babbe7f5bb40a312a24d73dbf9c9dd Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Thu, 26 Oct 2023 18:30:43 +0700 Subject: [PATCH 0912/1212] docs: remove OpenSSL section from README (#10186) --- README.md | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/README.md b/README.md index 066f0790a..c261ea699 100644 --- a/README.md +++ b/README.md @@ -88,7 +88,6 @@ Before opening an issue, consider using one of the following locations to ensure - [Install Go](#install-go) - [Download and Compile IPFS](#download-and-compile-ipfs) - [Cross Compiling](#cross-compiling) - - [OpenSSL](#openssl) - [Troubleshooting](#troubleshooting) - [Getting Started](#getting-started) - [Usage](#usage) @@ -327,15 +326,6 @@ Compiling for a different platform is as simple as running: make build GOOS=myTargetOS GOARCH=myTargetArchitecture ``` -##### OpenSSL - -To build go-ipfs with OpenSSL support, append `GOTAGS=openssl` to your `make` invocation. Building with OpenSSL should significantly reduce the background CPU usage on nodes that frequently make or receive new connections. - -Note: OpenSSL requires CGO support and, by default, CGO is disabled when cross-compiling. To cross-compile with OpenSSL support, you must: - -1. Install a compiler toolchain for the target platform. -2. Set the `CGO_ENABLED=1` environment variable. - #### Troubleshooting - Separate [instructions are available for building on Windows](docs/windows.md). From a0f34b16ddc8151fd0ba8ab9674db25354232495 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Sat, 28 Oct 2023 05:34:14 +0200 Subject: [PATCH 0913/1212] feat: built-in content blocking based on IPIP-383 (#10161) Fixes #8492 This introduces "nopfs" as a preloaded plugin into Kubo with support for denylists from https://github.com/ipfs/specs/pull/383 It automatically makes Kubo watch *.deny files found in: - /etc/ipfs/denylists - $XDG_CONFIG_HOME/ipfs/denylists - $IPFS_PATH/denylists * test: Gateway.NoFetch and GatewayOverLibp2p adds missing tests for "no fetch" gateways one can expose, in both cases the offline mode is done by passing custom blockservice/exchange into path resolver, which means global path resolver that has nopfs intercept is not used, and the content blocking does not happen on these gateways. * fix: use offline path resolvers where appropriate this fixes the problem described in https://github.com/ipfs/kubo/pull/10161#issuecomment-1782175955 by adding explicit offline path resolvers that are backed by offline exchange, and using them in NoFetch gateways instead of the default online ones --------- Co-authored-by: Henrique Dias Co-authored-by: Marcin Rataj --- README.md | 1 + core/commands/dag/export.go | 16 +- core/core.go | 58 ++-- core/corehttp/gateway.go | 18 +- core/node/core.go | 51 ++-- docs/changelogs/v0.24.md | 9 + docs/content-blocking.md | 73 +++++ docs/environment-variables.md | 6 + docs/examples/kubo-as-a-library/go.mod | 6 +- docs/examples/kubo-as-a-library/go.sum | 10 +- go.mod | 4 +- go.sum | 8 +- plugin/loader/preload.go | 2 + plugin/loader/preload_list | 1 + plugin/plugins/nopfs/nopfs.go | 85 ++++++ test/cli/content_blocking_test.go | 303 +++++++++++++++++++ test/dependencies/go.mod | 2 +- test/dependencies/go.sum | 4 +- test/sharness/t0054-dag-car-import-export.sh | 4 +- 19 files changed, 596 insertions(+), 65 deletions(-) create mode 100644 docs/content-blocking.md create mode 100644 plugin/plugins/nopfs/nopfs.go create mode 100644 test/cli/content_blocking_test.go diff --git a/README.md b/README.md index c261ea699..74b53c3ad 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,7 @@ Featureset - [HTTP Kubo RPC API](https://docs.ipfs.tech/reference/kubo/rpc/) (`/api/v0`) to access and control the daemon - [Command Line Interface](https://docs.ipfs.tech/reference/kubo/cli/) based on (`/api/v0`) RPC API - [WebUI](https://github.com/ipfs/ipfs-webui/#readme) to manage the Kubo node +- [Content blocking](/docs/content-blocking.md) support for operators of public nodes ### Other implementations diff --git a/core/commands/dag/export.go b/core/commands/dag/export.go index d46fa6e21..d97718d20 100644 --- a/core/commands/dag/export.go +++ b/core/commands/dag/export.go @@ -14,6 +14,7 @@ import ( cid "github.com/ipfs/go-cid" ipld "github.com/ipfs/go-ipld-format" "github.com/ipfs/kubo/core/commands/cmdenv" + "github.com/ipfs/kubo/core/commands/cmdutils" cmds "github.com/ipfs/go-ipfs-cmds" gocar "github.com/ipld/go-car" @@ -21,12 +22,10 @@ import ( ) func dagExport(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - c, err := cid.Decode(req.Arguments[0]) + // Accept CID or a content path + p, err := cmdutils.PathOrCidPath(req.Arguments[0]) if err != nil { - return fmt.Errorf( - "unable to parse root specification (currently only bare CIDs are supported): %s", - err, - ) + return err } api, err := cmdenv.GetApi(env, req) @@ -34,6 +33,13 @@ func dagExport(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment return err } + // Resolve path and confirm the root block is available, fail fast if not + b, err := api.Block().Stat(req.Context, p) + if err != nil { + return err + } + c := b.Path().RootCid() + pipeR, pipeW := io.Pipe() errCh := make(chan error, 2) // we only report the 1st error diff --git a/core/core.go b/core/core.go index c35d3e445..c9bec6b8b 100644 --- a/core/core.go +++ b/core/core.go @@ -76,35 +76,39 @@ type IpfsNode struct { PNetFingerprint libp2p.PNetFingerprint `optional:"true"` // fingerprint of private network // Services - Peerstore pstore.Peerstore `optional:"true"` // storage for other Peer instances - Blockstore bstore.GCBlockstore // the block store (lower level) - Filestore *filestore.Filestore `optional:"true"` // the filestore blockstore - BaseBlocks node.BaseBlocks // the raw blockstore, no filestore wrapping - GCLocker bstore.GCLocker // the locker used to protect the blockstore during gc - Blocks bserv.BlockService // the block service, get/add blocks. - DAG ipld.DAGService // the merkle dag service, get/add objects. - IPLDFetcherFactory fetcher.Factory `name:"ipldFetcher"` // fetcher that paths over the IPLD data model - UnixFSFetcherFactory fetcher.Factory `name:"unixfsFetcher"` // fetcher that interprets UnixFS data - Reporter *metrics.BandwidthCounter `optional:"true"` - Discovery mdns.Service `optional:"true"` - FilesRoot *mfs.Root - RecordValidator record.Validator + Peerstore pstore.Peerstore `optional:"true"` // storage for other Peer instances + Blockstore bstore.GCBlockstore // the block store (lower level) + Filestore *filestore.Filestore `optional:"true"` // the filestore blockstore + BaseBlocks node.BaseBlocks // the raw blockstore, no filestore wrapping + GCLocker bstore.GCLocker // the locker used to protect the blockstore during gc + Blocks bserv.BlockService // the block service, get/add blocks. + DAG ipld.DAGService // the merkle dag service, get/add objects. + IPLDFetcherFactory fetcher.Factory `name:"ipldFetcher"` // fetcher that paths over the IPLD data model + UnixFSFetcherFactory fetcher.Factory `name:"unixfsFetcher"` // fetcher that interprets UnixFS data + OfflineIPLDFetcherFactory fetcher.Factory `name:"offlineIpldFetcher"` // fetcher that paths over the IPLD data model without fetching new blocks + OfflineUnixFSFetcherFactory fetcher.Factory `name:"offlineUnixfsFetcher"` // fetcher that interprets UnixFS data without fetching new blocks + Reporter *metrics.BandwidthCounter `optional:"true"` + Discovery mdns.Service `optional:"true"` + FilesRoot *mfs.Root + 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 irouting.ProvideManyRouter `optional:"true"` // the routing system. recommend ipfs-dht - DNSResolver *madns.Resolver // the DNS resolver - IPLDPathResolver pathresolver.Resolver `name:"ipldPathResolver"` // The IPLD path resolver - UnixFSPathResolver pathresolver.Resolver `name:"unixFSPathResolver"` // The UnixFS path 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"` + 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 irouting.ProvideManyRouter `optional:"true"` // the routing system. recommend ipfs-dht + DNSResolver *madns.Resolver // the DNS resolver + IPLDPathResolver pathresolver.Resolver `name:"ipldPathResolver"` // The IPLD path resolver + UnixFSPathResolver pathresolver.Resolver `name:"unixFSPathResolver"` // The UnixFS path resolver + OfflineIPLDPathResolver pathresolver.Resolver `name:"offlineIpldPathResolver"` // The IPLD path resolver that uses only locally available blocks + OfflineUnixFSPathResolver pathresolver.Resolver `name:"offlineUnixFSPathResolver"` // The UnixFS path resolver that uses only locally available blocks + 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/corehttp/gateway.go b/core/corehttp/gateway.go index ec9abef8e..3e0380d5a 100644 --- a/core/corehttp/gateway.go +++ b/core/corehttp/gateway.go @@ -81,7 +81,11 @@ func Libp2pGatewayOption() ServeOption { return func(n *core.IpfsNode, _ net.Listener, mux *http.ServeMux) (*http.ServeMux, error) { bserv := blockservice.New(n.Blocks.Blockstore(), offline.Exchange(n.Blocks.Blockstore())) - backend, err := gateway.NewBlocksBackend(bserv) + backend, err := gateway.NewBlocksBackend(bserv, + // GatewayOverLibp2p only returns things that are in local blockstore + // (same as Gateway.NoFetch=true), we have to pass offline path resolver + gateway.WithResolver(n.OfflineUnixFSPathResolver), + ) if err != nil { return nil, err } @@ -111,6 +115,8 @@ func newGatewayBackend(n *core.IpfsNode) (gateway.IPFSBackend, error) { bserv := n.Blocks var vsRouting routing.ValueStore = n.Routing nsys := n.Namesys + pathResolver := n.UnixFSPathResolver + if cfg.Gateway.NoFetch { bserv = blockservice.New(bserv.Blockstore(), offline.Exchange(bserv.Blockstore())) @@ -130,9 +136,17 @@ func newGatewayBackend(n *core.IpfsNode) (gateway.IPFSBackend, error) { if err != nil { return nil, fmt.Errorf("error constructing namesys: %w", err) } + + // Gateway.NoFetch=true requires offline path resolver + // to avoid fetching missing blocks during path traversal + pathResolver = n.OfflineUnixFSPathResolver } - backend, err := gateway.NewBlocksBackend(bserv, gateway.WithValueStore(vsRouting), gateway.WithNameSystem(nsys)) + backend, err := gateway.NewBlocksBackend(bserv, + gateway.WithValueStore(vsRouting), + gateway.WithNameSystem(nsys), + gateway.WithResolver(pathResolver), + ) if err != nil { return nil, err } diff --git a/core/node/core.go b/core/node/core.go index d2d2c63d7..9a2035a4c 100644 --- a/core/node/core.go +++ b/core/node/core.go @@ -7,6 +7,7 @@ import ( "github.com/ipfs/boxo/blockservice" blockstore "github.com/ipfs/boxo/blockstore" exchange "github.com/ipfs/boxo/exchange" + offline "github.com/ipfs/boxo/exchange/offline" "github.com/ipfs/boxo/fetcher" bsfetcher "github.com/ipfs/boxo/fetcher/impl/blockservice" "github.com/ipfs/boxo/filestore" @@ -21,9 +22,6 @@ import ( format "github.com/ipfs/go-ipld-format" "github.com/ipfs/go-unixfsnode" dagpb "github.com/ipld/go-codec-dagpb" - "github.com/ipld/go-ipld-prime" - basicnode "github.com/ipld/go-ipld-prime/node/basic" - "github.com/ipld/go-ipld-prime/schema" "go.uber.org/fx" "github.com/ipfs/kubo/core/node/helpers" @@ -87,43 +85,58 @@ func (s *syncDagService) Session(ctx context.Context) format.NodeGetter { // FetchersOut allows injection of fetchers. type FetchersOut struct { fx.Out - IPLDFetcher fetcher.Factory `name:"ipldFetcher"` - UnixfsFetcher fetcher.Factory `name:"unixfsFetcher"` + IPLDFetcher fetcher.Factory `name:"ipldFetcher"` + UnixfsFetcher fetcher.Factory `name:"unixfsFetcher"` + OfflineIPLDFetcher fetcher.Factory `name:"offlineIpldFetcher"` + OfflineUnixfsFetcher fetcher.Factory `name:"offlineUnixfsFetcher"` } // FetchersIn allows using fetchers for other dependencies. type FetchersIn struct { fx.In - IPLDFetcher fetcher.Factory `name:"ipldFetcher"` - UnixfsFetcher fetcher.Factory `name:"unixfsFetcher"` + IPLDFetcher fetcher.Factory `name:"ipldFetcher"` + UnixfsFetcher fetcher.Factory `name:"unixfsFetcher"` + OfflineIPLDFetcher fetcher.Factory `name:"offlineIpldFetcher"` + OfflineUnixfsFetcher fetcher.Factory `name:"offlineUnixfsFetcher"` } // FetcherConfig returns a fetcher config that can build new fetcher instances func FetcherConfig(bs blockservice.BlockService) FetchersOut { ipldFetcher := bsfetcher.NewFetcherConfig(bs) - ipldFetcher.PrototypeChooser = dagpb.AddSupportToChooser(func(lnk ipld.Link, lnkCtx ipld.LinkContext) (ipld.NodePrototype, error) { - if tlnkNd, ok := lnkCtx.LinkNode.(schema.TypedLinkNode); ok { - return tlnkNd.LinkTargetNodePrototype(), nil - } - return basicnode.Prototype.Any, nil - }) - + ipldFetcher.PrototypeChooser = dagpb.AddSupportToChooser(bsfetcher.DefaultPrototypeChooser) unixFSFetcher := ipldFetcher.WithReifier(unixfsnode.Reify) - return FetchersOut{IPLDFetcher: ipldFetcher, UnixfsFetcher: unixFSFetcher} + + // Construct offline versions which we can safely use in contexts where + // path resolution should not fetch new blocks via exchange. + offlineBs := blockservice.New(bs.Blockstore(), offline.Exchange(bs.Blockstore())) + offlineIpldFetcher := bsfetcher.NewFetcherConfig(offlineBs) + offlineIpldFetcher.PrototypeChooser = dagpb.AddSupportToChooser(bsfetcher.DefaultPrototypeChooser) + offlineUnixFSFetcher := offlineIpldFetcher.WithReifier(unixfsnode.Reify) + + return FetchersOut{ + IPLDFetcher: ipldFetcher, + UnixfsFetcher: unixFSFetcher, + OfflineIPLDFetcher: offlineIpldFetcher, + OfflineUnixfsFetcher: offlineUnixFSFetcher, + } } // PathResolversOut allows injection of path resolvers type PathResolversOut struct { fx.Out - IPLDPathResolver pathresolver.Resolver `name:"ipldPathResolver"` - UnixFSPathResolver pathresolver.Resolver `name:"unixFSPathResolver"` + IPLDPathResolver pathresolver.Resolver `name:"ipldPathResolver"` + UnixFSPathResolver pathresolver.Resolver `name:"unixFSPathResolver"` + OfflineIPLDPathResolver pathresolver.Resolver `name:"offlineIpldPathResolver"` + OfflineUnixFSPathResolver pathresolver.Resolver `name:"offlineUnixFSPathResolver"` } // PathResolverConfig creates path resolvers with the given fetchers. func PathResolverConfig(fetchers FetchersIn) PathResolversOut { return PathResolversOut{ - IPLDPathResolver: pathresolver.NewBasicResolver(fetchers.IPLDFetcher), - UnixFSPathResolver: pathresolver.NewBasicResolver(fetchers.UnixfsFetcher), + IPLDPathResolver: pathresolver.NewBasicResolver(fetchers.IPLDFetcher), + UnixFSPathResolver: pathresolver.NewBasicResolver(fetchers.UnixfsFetcher), + OfflineIPLDPathResolver: pathresolver.NewBasicResolver(fetchers.OfflineIPLDFetcher), + OfflineUnixFSPathResolver: pathresolver.NewBasicResolver(fetchers.OfflineUnixfsFetcher), } } diff --git a/docs/changelogs/v0.24.md b/docs/changelogs/v0.24.md index ad3374838..29d88d9cb 100644 --- a/docs/changelogs/v0.24.md +++ b/docs/changelogs/v0.24.md @@ -6,6 +6,7 @@ - [Overview](#overview) - [🔦 Highlights](#-highlights) + - [Support for content blocking](#support-for-content-blocking) - [Gateway: the root of the CARs are no longer meaningful](#gateway-the-root-of-the-cars-are-no-longer-meaningful) - [IPNS: improved publishing defaults](#ipns-improved-publishing-defaults) - [IPNS: record TTL is used for caching](#ipns-record-ttl-is-used-for-caching) @@ -16,6 +17,14 @@ ### 🔦 Highlights +#### Support for content blocking + +This Kubo release ships with built-in content-blocking subsystem [announced earlier this year](https://blog.ipfs.tech/2023-content-blocking-for-the-ipfs-stack/). +Content blocking is an opt-in decision made by the operator of `ipfs daemon`. +The official build does not ship with any denylists. + +Learn more at [`/docs/content-blocking.md`](https://github.com/ipfs/kubo/blob/master/docs/content-blocking.md) + #### Gateway: the root of the CARs are no longer meaningful When requesting a CAR from the gateway, the root of the CAR might no longer be diff --git a/docs/content-blocking.md b/docs/content-blocking.md new file mode 100644 index 000000000..ebc84bba3 --- /dev/null +++ b/docs/content-blocking.md @@ -0,0 +1,73 @@ +

+
+ content blocking logo +
+ Content Blocking in Kubo +
+

+ +Kubo ships with built-in support for denylist format from [IPIP-383](https://github.com/ipfs/specs/pull/383). + +## Default behavior + +Official Kubo build does not ship with any denylists enabled by default. + +Content blocking is an opt-in decision made by the operator of `ipfs daemon`. + +## How to enable blocking + +Place a `*.deny` file in one of directories: + +- `$IPFS_PATH/denylists/` (`$HOME/.ipfs/denylists/` if `IPFS_PATH` is not set) +- `$XDG_CONFIG_HOME/ipfs/denylists/` (`$HOME/.config/ipfs/denylists/` if `XDG_CONFIG_HOME` is not set) +- `/etc/ipfs/denylists/` (global) + +Files need to be present before starting the `ipfs daemon` in order to be watched for updates. + +If a new denylist file is added, `ipfs daemon` needs to be restarted. + +CLI and Gateway users will receive errors in response to request impacted by a blocklist: + +``` +Error: /ipfs/QmQvjk82hPkSaZsyJ8vNER5cmzKW7HyGX5XVusK7EAenCN is blocked and cannot be provided +``` + +End user is not informed about the exact reason, see [How to +debug](#how-to-debug) if you need to find out which line of which denylist +caused the request to be blocked. + +## Denylist file format + +[NOpfs](https://github.com/ipfs-shipyard/nopfs) supports the format from [IPIP-383](https://github.com/ipfs/specs/pull/383). + +Clear-text rules are simple: just put content paths to block, one per line. +Paths with unicode and whitespace need to be percend-encoded: + +``` +/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR +/ipfs/bafybeihfg3d7rdltd43u3tfvncx7n5loqofbsobojcadtmokrljfthuc7y/927%20-%20Standards/927%20-%20Standards.png +``` + +Sensitive content paths can be double-hashed to block without revealing them. +Double-hashed list example: https://badbits.dwebops.pub/badbits.deny + +See [IPIP-383](https://github.com/ipfs/specs/pull/383) for detailed format specification and more examples. + +## How to suspend blocking without removing denylists + +Set `IPFS_CONTENT_BLOCKING_DISABLE` environment variable to `true` and restart the daemon. + + +## How to debug + +Debug logging of `nopfs` subsystem can be enabled with `GOLOG_LOG_LEVEL="nopfs=debug"` + +All block events are logged as warnings on a separate level named `nopfs-blocks`. + +To only log requests for blocked content set `GOLOG_LOG_LEVEL="nopfs-blocks=warn"`: + +``` +WARN (...) QmRFniDxwxoG2n4AcnGhRdjqDjCM5YeUcBE75K8WXmioH3: blocked (test.deny:9) +``` + + diff --git a/docs/environment-variables.md b/docs/environment-variables.md index 4113be09b..f0f6b3f18 100644 --- a/docs/environment-variables.md +++ b/docs/environment-variables.md @@ -131,6 +131,12 @@ The above will replace implicit HTTP routers with single one, allowing for inspection/debug of HTTP requests sent by Kubo via `while true ; do nc -l 7423; done` or more advanced tools like [mitmproxy](https://docs.mitmproxy.org/stable/#mitmproxy). + +## `IPFS_CONTENT_BLOCKING_DISABLE` + +Disables the content-blocking subsystem. No denylists will be watched and no +content will be blocked. + ## `LIBP2P_TCP_REUSEPORT` Kubo tries to reuse the same source port for all connections to improve NAT diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 8c2edff6d..dfb7848b0 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.20 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.13.2-0.20231018081237-a50f784985dd + github.com/ipfs/boxo v0.13.2-0.20231028021353-182e86f5bb9b github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.31.0 github.com/multiformats/go-multiaddr v0.11.0 @@ -40,6 +40,7 @@ require ( github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5 // indirect github.com/flynn/noise v1.0.0 // indirect github.com/francoispqt/gojay v1.2.13 // indirect + github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/gabriel-vasile/mimetype v1.4.1 // indirect github.com/go-logr/logr v1.2.4 // indirect github.com/go-logr/stdr v1.2.2 // indirect @@ -60,6 +61,8 @@ require ( github.com/hashicorp/golang-lru v0.5.4 // indirect github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/huin/goupnp v1.2.0 // indirect + github.com/ipfs-shipyard/nopfs v0.0.12-0.20231027223058-cde3b5ba964c // indirect + github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c // indirect github.com/ipfs/bbloom v0.0.4 // indirect github.com/ipfs/go-bitfield v1.1.0 // indirect github.com/ipfs/go-block-format v0.2.0 // indirect @@ -194,5 +197,6 @@ require ( google.golang.org/grpc v1.55.0 // indirect google.golang.org/protobuf v1.31.0 // indirect gopkg.in/square/go-jose.v2 v2.5.1 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect lukechampine.com/blake3 v1.2.1 // indirect ) diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 8fab68dde..49dbacfee 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -163,6 +163,7 @@ github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHk github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= +github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/gabriel-vasile/mimetype v1.4.1 h1:TRWk7se+TOjCYgRth7+1/OYLNiRNIotknkFtf/dnN7Q= github.com/gabriel-vasile/mimetype v1.4.1/go.mod h1:05Vi0w3Y9c/lNvJOdmIwvrrAhX3rYhfQQCaf9VJcv7M= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= @@ -298,10 +299,14 @@ github.com/huin/goupnp v1.2.0 h1:uOKW26NG1hsSSbXIZ1IR7XP9Gjd1U8pnLaCMgntmkmY= github.com/huin/goupnp v1.2.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/ipfs-shipyard/nopfs v0.0.12-0.20231027223058-cde3b5ba964c h1:17FO7HnKiFhO7iadu3zCgII+EblpdRmJt5qg9FqQo8Y= +github.com/ipfs-shipyard/nopfs v0.0.12-0.20231027223058-cde3b5ba964c/go.mod h1:1oj4+g/mN6JRuZiXHt5iFRG02e62wp5AKcB3gdgknbk= +github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7UynTbtdlt+w08ggb1UGLGaGjp1mMaZhoTZSctpn5Ak= +github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.13.2-0.20231018081237-a50f784985dd h1:CWz2mhz+cmkLRlKgQYlKXkDtx4oWYkCorSSF4ZWkH3o= -github.com/ipfs/boxo v0.13.2-0.20231018081237-a50f784985dd/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk= +github.com/ipfs/boxo v0.13.2-0.20231028021353-182e86f5bb9b h1:0Qi1EhB82x3SZJOBieG51BtPvjU3kSy4H8OpMnxKvtk= +github.com/ipfs/boxo v0.13.2-0.20231028021353-182e86f5bb9b/go.mod h1:pu8HsZvuyYeYJsqtLDCoYSvy8rHj6vI3dlh8P0f83Zs= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= @@ -1001,6 +1006,7 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= diff --git a/go.mod b/go.mod index 68db957cd..c94a251cb 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,9 @@ require ( github.com/fsnotify/fsnotify v1.6.0 github.com/google/uuid v1.3.1 github.com/hashicorp/go-multierror v1.1.1 - github.com/ipfs/boxo v0.13.2-0.20231018081237-a50f784985dd + github.com/ipfs-shipyard/nopfs v0.0.12-0.20231027223058-cde3b5ba964c + github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c + github.com/ipfs/boxo v0.13.2-0.20231028021353-182e86f5bb9b github.com/ipfs/go-block-format v0.2.0 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 diff --git a/go.sum b/go.sum index 5b612c73a..928433eaa 100644 --- a/go.sum +++ b/go.sum @@ -333,10 +333,14 @@ github.com/huin/goupnp v1.2.0 h1:uOKW26NG1hsSSbXIZ1IR7XP9Gjd1U8pnLaCMgntmkmY= github.com/huin/goupnp v1.2.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/ipfs-shipyard/nopfs v0.0.12-0.20231027223058-cde3b5ba964c h1:17FO7HnKiFhO7iadu3zCgII+EblpdRmJt5qg9FqQo8Y= +github.com/ipfs-shipyard/nopfs v0.0.12-0.20231027223058-cde3b5ba964c/go.mod h1:1oj4+g/mN6JRuZiXHt5iFRG02e62wp5AKcB3gdgknbk= +github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7UynTbtdlt+w08ggb1UGLGaGjp1mMaZhoTZSctpn5Ak= +github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.13.2-0.20231018081237-a50f784985dd h1:CWz2mhz+cmkLRlKgQYlKXkDtx4oWYkCorSSF4ZWkH3o= -github.com/ipfs/boxo v0.13.2-0.20231018081237-a50f784985dd/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk= +github.com/ipfs/boxo v0.13.2-0.20231028021353-182e86f5bb9b h1:0Qi1EhB82x3SZJOBieG51BtPvjU3kSy4H8OpMnxKvtk= +github.com/ipfs/boxo v0.13.2-0.20231028021353-182e86f5bb9b/go.mod h1:pu8HsZvuyYeYJsqtLDCoYSvy8rHj6vI3dlh8P0f83Zs= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= diff --git a/plugin/loader/preload.go b/plugin/loader/preload.go index 430486211..2ad84e594 100644 --- a/plugin/loader/preload.go +++ b/plugin/loader/preload.go @@ -7,6 +7,7 @@ import ( pluginfxtest "github.com/ipfs/kubo/plugin/plugins/fxtest" pluginipldgit "github.com/ipfs/kubo/plugin/plugins/git" pluginlevelds "github.com/ipfs/kubo/plugin/plugins/levelds" + pluginnopfs "github.com/ipfs/kubo/plugin/plugins/nopfs" pluginpeerlog "github.com/ipfs/kubo/plugin/plugins/peerlog" ) @@ -22,4 +23,5 @@ func init() { Preload(pluginlevelds.Plugins...) Preload(pluginpeerlog.Plugins...) Preload(pluginfxtest.Plugins...) + Preload(pluginnopfs.Plugins...) } diff --git a/plugin/loader/preload_list b/plugin/loader/preload_list index c18ea80cc..462a3f393 100644 --- a/plugin/loader/preload_list +++ b/plugin/loader/preload_list @@ -11,3 +11,4 @@ flatfs github.com/ipfs/kubo/plugin/plugins/flatfs * levelds github.com/ipfs/kubo/plugin/plugins/levelds * peerlog github.com/ipfs/kubo/plugin/plugins/peerlog * fxtest github.com/ipfs/kubo/plugin/plugins/fxtest * +nopfs github.com/ipfs/kubo/plugin/plugins/nopfs * \ No newline at end of file diff --git a/plugin/plugins/nopfs/nopfs.go b/plugin/plugins/nopfs/nopfs.go new file mode 100644 index 000000000..64350830f --- /dev/null +++ b/plugin/plugins/nopfs/nopfs.go @@ -0,0 +1,85 @@ +package nopfs + +import ( + "os" + "path/filepath" + + "github.com/ipfs-shipyard/nopfs" + "github.com/ipfs-shipyard/nopfs/ipfs" + "github.com/ipfs/kubo/config" + "github.com/ipfs/kubo/core" + "github.com/ipfs/kubo/core/node" + "github.com/ipfs/kubo/plugin" + "go.uber.org/fx" +) + +// Plugins sets the list of plugins to be loaded. +var Plugins = []plugin.Plugin{ + &nopfsPlugin{}, +} + +// fxtestPlugin is used for testing the fx plugin. +// It merely adds an fx option that logs a debug statement, so we can verify that it works in tests. +type nopfsPlugin struct{} + +var _ plugin.PluginFx = (*nopfsPlugin)(nil) + +func (p *nopfsPlugin) Name() string { + return "nopfs" +} + +func (p *nopfsPlugin) Version() string { + return "0.0.10" +} + +func (p *nopfsPlugin) Init(env *plugin.Environment) error { + return nil +} + +// MakeBlocker is a factory for the blocker so that it can be provided with Fx. +func MakeBlocker() (*nopfs.Blocker, error) { + ipfsPath, err := config.PathRoot() + if err != nil { + return nil, err + } + + defaultFiles, err := nopfs.GetDenylistFiles() + if err != nil { + return nil, err + } + + kuboFiles, err := nopfs.GetDenylistFilesInDir(filepath.Join(ipfsPath, "denylists")) + if err != nil { + return nil, err + } + + files := append(defaultFiles, kuboFiles...) + + return nopfs.NewBlocker(files) +} + +// PathResolvers returns wrapped PathResolvers for Kubo. +func PathResolvers(fetchers node.FetchersIn, blocker *nopfs.Blocker) node.PathResolversOut { + res := node.PathResolverConfig(fetchers) + return node.PathResolversOut{ + IPLDPathResolver: ipfs.WrapResolver(res.IPLDPathResolver, blocker), + UnixFSPathResolver: ipfs.WrapResolver(res.UnixFSPathResolver, blocker), + OfflineIPLDPathResolver: ipfs.WrapResolver(res.OfflineIPLDPathResolver, blocker), + OfflineUnixFSPathResolver: ipfs.WrapResolver(res.OfflineUnixFSPathResolver, blocker), + } +} + +func (p *nopfsPlugin) Options(info core.FXNodeInfo) ([]fx.Option, error) { + if os.Getenv("IPFS_CONTENT_BLOCKING_DISABLE") != "" { + return info.FXOptions, nil + } + + opts := append( + info.FXOptions, + fx.Provide(MakeBlocker), + fx.Decorate(ipfs.WrapBlockService), + fx.Decorate(ipfs.WrapNameSystem), + fx.Decorate(PathResolvers), + ) + return opts, nil +} diff --git a/test/cli/content_blocking_test.go b/test/cli/content_blocking_test.go new file mode 100644 index 000000000..ddb7c951e --- /dev/null +++ b/test/cli/content_blocking_test.go @@ -0,0 +1,303 @@ +package cli + +import ( + "context" + "fmt" + "io" + "log" + "net/http" + "net/url" + "os" + "path/filepath" + "strings" + "testing" + + "github.com/ipfs/kubo/test/cli/harness" + "github.com/libp2p/go-libp2p" + "github.com/libp2p/go-libp2p/core/peer" + libp2phttp "github.com/libp2p/go-libp2p/p2p/http" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestContentBlocking(t *testing.T) { + // NOTE: we can't run this with t.Parallel() because we set IPFS_NS_MAP + // and running in parallel could impact other tests + + const blockedMsg = "blocked and cannot be provided" + const statusExpl = "specific HTTP error code is expected" + const bodyExpl = "Error message informing about content block is expected" + + h := harness.NewT(t) + + // Init IPFS_PATH + node := h.NewNode().Init("--empty-repo", "--profile=test") + + // Create CIDs we use in test + h.WriteFile("blocked-dir/subdir/indirectly-blocked-file.txt", "indirectly blocked file content") + parentDirCID := node.IPFS("add", "--raw-leaves", "-Q", "-r", filepath.Join(h.Dir, "blocked-dir")).Stdout.Trimmed() + + h.WriteFile("directly-blocked-file.txt", "directly blocked file content") + blockedCID := node.IPFS("add", "--raw-leaves", "-Q", filepath.Join(h.Dir, "directly-blocked-file.txt")).Stdout.Trimmed() + + h.WriteFile("not-blocked-file.txt", "not blocked file content") + allowedCID := node.IPFS("add", "--raw-leaves", "-Q", filepath.Join(h.Dir, "not-blocked-file.txt")).Stdout.Trimmed() + + // Create denylist at $IPFS_PATH/denylists/test.deny + denylistTmp := h.WriteToTemp("name: test list\n---\n" + + "//QmX9dhRcQcKUw3Ws8485T5a9dtjrSCQaUAHnG4iK9i4ceM\n" + // Double hash (sha256) CID block: base58btc(sha256-multihash(QmVTF1yEejXd9iMgoRTFDxBv7HAz9kuZcQNBzHrceuK9HR)) + "//gW813G35CnLsy7gRYYHuf63hrz71U1xoLFDVeV7actx6oX\n" + // Double hash (blake3) Path block under blake3 root CID: base58btc(blake3-multihash(gW7Nhu4HrfDtphEivm3Z9NNE7gpdh5Tga8g6JNZc1S8E47/path)) + "//8526ba05eec55e28f8db5974cc891d0d92c8af69d386fc6464f1e9f372caf549\n" + // Legacy CID double-hash block: sha256(bafkqahtcnrxwg23fmqqgi33vmjwgk2dbonuca3dfm5qwg6jamnuwicq/) + "//e5b7d2ce2594e2e09901596d8e1f29fa249b74c8c9e32ea01eda5111e4d33f07\n" + // Legacy Path double-hash block: sha256(bafyaagyscufaqalqaacauaqiaejao43vmjygc5didacauaqiae/subpath) + "/ipfs/" + blockedCID + "\n" + // block specific CID + "/ipfs/" + parentDirCID + "/subdir*\n" + // block only specific subpath + "/ipns/blocked-cid.example.com\n" + + "/ipns/blocked-dnslink.example.com\n") + + if err := os.MkdirAll(filepath.Join(node.Dir, "denylists"), 0o777); err != nil { + log.Panicf("failed to create denylists dir: %s", err.Error()) + } + if err := os.Rename(denylistTmp, filepath.Join(node.Dir, "denylists", "test.deny")); err != nil { + log.Panicf("failed to create test denylist: %s", err.Error()) + } + + // Add two entries to namesys resolution cache + // /ipns/blocked-cid.example.com point at a blocked CID (to confirm blocking impacts /ipns resolution) + // /ipns/blocked-dnslink.example.com with safe CID (to test blocking of /ipns/ paths) + os.Setenv("IPFS_NS_MAP", "blocked-cid.example.com:/ipfs/"+blockedCID+",blocked-dnslink.example.com/ipns/QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn") + defer os.Unsetenv("IPFS_NS_MAP") + + // Enable GatewayOverLibp2p as we want to test denylist there too + node.IPFS("config", "--json", "Experimental.GatewayOverLibp2p", "true") + + // Start daemon, it should pick up denylist from $IPFS_PATH/denylists/test.deny + node.StartDaemon() // we need online mode for GatewayOverLibp2p tests + client := node.GatewayClient() + + // First, confirm gateway works + t.Run("Gateway Allows CID that is not blocked", func(t *testing.T) { + t.Parallel() + resp := client.Get("/ipfs/" + allowedCID) + assert.Equal(t, http.StatusOK, resp.StatusCode) + assert.Equal(t, "not blocked file content", resp.Body) + }) + + // Then, does the most basic blocking case work? + t.Run("Gateway Denies directly blocked CID", func(t *testing.T) { + t.Parallel() + resp := client.Get("/ipfs/" + blockedCID) + assert.Equal(t, http.StatusGone, resp.StatusCode, statusExpl) + assert.NotEqual(t, "directly blocked file content", resp.Body) + assert.Contains(t, resp.Body, blockedMsg, bodyExpl) + }) + + // Confirm parent of blocked subpath is not blocked + t.Run("Gateway Allows parent Path that is not blocked", func(t *testing.T) { + t.Parallel() + resp := client.Get("/ipfs/" + parentDirCID) + assert.Equal(t, http.StatusOK, resp.StatusCode) + }) + + // Ok, now the full list of test cases we want to cover in both CLI and Gateway + testCases := []struct { + name string + path string + }{ + { + name: "directly blocked CID", + path: "/ipfs/" + blockedCID, + }, + { + name: "indirectly blocked file (on a blocked subpath)", + path: "/ipfs/" + parentDirCID + "/subdir/indirectly-blocked-file.txt", + }, + { + name: "/ipns path that resolves to a blocked CID", + path: "/ipns/blocked-cid.example.com", + }, + { + name: "/ipns Path that is blocked by DNSLink name", + path: "/ipns/blocked-dnslink.example.com", + }, + { + name: "double-hash CID block (sha256-multihash)", + path: "/ipfs/QmVTF1yEejXd9iMgoRTFDxBv7HAz9kuZcQNBzHrceuK9HR", + }, + { + name: "double-hash Path block (blake3-multihash)", + path: "/ipfs/bafyb4ieqht3b2rssdmc7sjv2cy2gfdilxkfh7623nvndziyqnawkmo266a/path", + }, + { + name: "legacy CID double-hash block (sha256)", + path: "/ipfs/bafkqahtcnrxwg23fmqqgi33vmjwgk2dbonuca3dfm5qwg6jamnuwicq", + }, + + { + name: "legacy Path double-hash block (sha256)", + path: "/ipfs/bafyaagyscufaqalqaacauaqiaejao43vmjygc5didacauaqiae/subpath", + }, + } + + // Which specific cliCmds we test against testCases + cliCmds := [][]string{ + {"block", "get"}, + {"block", "stat"}, + {"dag", "get"}, + {"dag", "export"}, + {"dag", "stat"}, + {"cat"}, + {"ls"}, + {"get"}, + {"refs"}, + } + + expectedMsg := blockedMsg + for _, testCase := range testCases { + + // Confirm that denylist is active for every command in 'cliCmds' x 'testCases' + for _, cmd := range cliCmds { + cmd := cmd + cliTestName := fmt.Sprintf("CLI '%s' denies %s", strings.Join(cmd, " "), testCase.name) + t.Run(cliTestName, func(t *testing.T) { + t.Parallel() + args := append(cmd, testCase.path) + errMsg := node.RunIPFS(args...).Stderr.Trimmed() + if !strings.Contains(errMsg, expectedMsg) { + t.Errorf("Expected STDERR error message %q, but got: %q", expectedMsg, errMsg) + } + }) + } + + // Confirm that denylist is active for every content path in 'testCases' + gwTestName := fmt.Sprintf("Gateway denies %s", testCase.name) + t.Run(gwTestName, func(t *testing.T) { + resp := client.Get(testCase.path) + assert.Equal(t, http.StatusGone, resp.StatusCode, statusExpl) + assert.Contains(t, resp.Body, blockedMsg, bodyExpl) + }) + + } + + // Extra edge cases on subdomain gateway + + t.Run("Gateway Denies /ipns Path that is blocked by DNSLink name (subdomain redirect)", func(t *testing.T) { + t.Parallel() + + gwURL, _ := url.Parse(node.GatewayURL()) + resp := client.Get("/ipns/blocked-dnslink.example.com", func(r *http.Request) { + r.Host = "localhost:" + gwURL.Port() + }) + + assert.Equal(t, http.StatusGone, resp.StatusCode, statusExpl) + assert.Contains(t, resp.Body, blockedMsg, bodyExpl) + }) + + t.Run("Gateway Denies /ipns Path that is blocked by DNSLink name (subdomain, no TLS)", func(t *testing.T) { + t.Parallel() + + gwURL, _ := url.Parse(node.GatewayURL()) + resp := client.Get("/", func(r *http.Request) { + r.Host = "blocked-dnslink.example.com.ipns.localhost:" + gwURL.Port() + }) + + assert.Equal(t, http.StatusGone, resp.StatusCode, statusExpl) + assert.Contains(t, resp.Body, blockedMsg, bodyExpl) + }) + + t.Run("Gateway Denies /ipns Path that is blocked by DNSLink name (subdomain, inlined for TLS)", func(t *testing.T) { + t.Parallel() + + gwURL, _ := url.Parse(node.GatewayURL()) + resp := client.Get("/", func(r *http.Request) { + // Inlined DNSLink to fit in single DNS label for TLS interop: + // https://specs.ipfs.tech/http-gateways/subdomain-gateway/#host-request-header + r.Host = "blocked--dnslink-example-com.ipns.localhost:" + gwURL.Port() + }) + + assert.Equal(t, http.StatusGone, resp.StatusCode, statusExpl) + assert.Contains(t, resp.Body, blockedMsg, bodyExpl) + }) + + // We need to confirm denylist is active when gateway is run in NoFetch + // mode (which usually swaps blockservice to a read-only one, and that swap + // may cause denylists to not be applied, as it is a separate code path) + t.Run("GatewayNoFetch", func(t *testing.T) { + // NOTE: we don't run this in parallel, as it requires restart with different config + + // Switch gateway to NoFetch mode + node.StopDaemon() + node.IPFS("config", "--json", "Gateway.NoFetch", "true") + node.StartDaemon() + + // update client, as the port of test node might've changed after restart + client = node.GatewayClient() + + // First, confirm gateway works + t.Run("Allows CID that is not blocked", func(t *testing.T) { + resp := client.Get("/ipfs/" + allowedCID) + assert.Equal(t, http.StatusOK, resp.StatusCode) + assert.Equal(t, "not blocked file content", resp.Body) + }) + + // Then, does the most basic blocking case work? + t.Run("Denies directly blocked CID", func(t *testing.T) { + resp := client.Get("/ipfs/" + blockedCID) + assert.Equal(t, http.StatusGone, resp.StatusCode, statusExpl) + assert.NotEqual(t, "directly blocked file content", resp.Body) + assert.Contains(t, resp.Body, blockedMsg, bodyExpl) + }) + + // Restore default + node.StopDaemon() + node.IPFS("config", "--json", "Gateway.NoFetch", "false") + node.StartDaemon() + client = node.GatewayClient() + }) + + // We need to confirm denylist is active on the + // trustless gateway exposed over libp2p + // when Experimental.GatewayOverLibp2p=true + // (https://github.com/ipfs/kubo/blob/master/docs/experimental-features.md#http-gateway-over-libp2p) + // NOTE: this type fo gateway is hardcoded to be NoFetch: it does not fetch + // data that is not in local store, so we only need to run it once: a + // simple smoke-test for allowed CID and blockedCID. + t.Run("GatewayOverLibp2p", func(t *testing.T) { + t.Parallel() + + // Create libp2p client that connects to our node over + // /http1.1 and then talks gateway semantics over the /ipfs/gateway sub-protocol + clientHost, err := libp2p.New(libp2p.NoListenAddrs) + require.NoError(t, err) + err = clientHost.Connect(context.Background(), peer.AddrInfo{ + ID: node.PeerID(), + Addrs: node.SwarmAddrs(), + }) + require.NoError(t, err) + + libp2pClient, err := (&libp2phttp.Host{StreamHost: clientHost}).NamespacedClient("/ipfs/gateway", peer.AddrInfo{ID: node.PeerID()}) + require.NoError(t, err) + + t.Run("Serves Allowed CID", func(t *testing.T) { + t.Parallel() + resp, err := libp2pClient.Get(fmt.Sprintf("/ipfs/%s?format=raw", allowedCID)) + require.NoError(t, err) + defer resp.Body.Close() + assert.Equal(t, http.StatusOK, resp.StatusCode) + body, err := io.ReadAll(resp.Body) + require.NoError(t, err) + require.Equal(t, string(body), "not blocked file content", bodyExpl) + }) + + t.Run("Denies Blocked CID", func(t *testing.T) { + t.Parallel() + resp, err := libp2pClient.Get(fmt.Sprintf("/ipfs/%s?format=raw", blockedCID)) + require.NoError(t, err) + defer resp.Body.Close() + assert.Equal(t, http.StatusGone, resp.StatusCode, statusExpl) + body, err := io.ReadAll(resp.Body) + require.NoError(t, err) + assert.NotEqual(t, string(body), "directly blocked file content") + assert.Contains(t, string(body), blockedMsg, bodyExpl) + }) + }) +} diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index fd8c94585..cbc577f9b 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -7,7 +7,7 @@ replace github.com/ipfs/kubo => ../../ require ( github.com/Kubuxu/gocovmerge v0.0.0-20161216165753-7ecaa51963cd github.com/golangci/golangci-lint v1.54.1 - github.com/ipfs/boxo v0.13.2-0.20231018081237-a50f784985dd + github.com/ipfs/boxo v0.13.2-0.20231028021353-182e86f5bb9b github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 github.com/ipfs/go-datastore v0.6.0 diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index d37a47fe0..90a00aebc 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -398,8 +398,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.13.2-0.20231018081237-a50f784985dd h1:CWz2mhz+cmkLRlKgQYlKXkDtx4oWYkCorSSF4ZWkH3o= -github.com/ipfs/boxo v0.13.2-0.20231018081237-a50f784985dd/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk= +github.com/ipfs/boxo v0.13.2-0.20231028021353-182e86f5bb9b h1:0Qi1EhB82x3SZJOBieG51BtPvjU3kSy4H8OpMnxKvtk= +github.com/ipfs/boxo v0.13.2-0.20231028021353-182e86f5bb9b/go.mod h1:pu8HsZvuyYeYJsqtLDCoYSvy8rHj6vI3dlh8P0f83Zs= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs= diff --git a/test/sharness/t0054-dag-car-import-export.sh b/test/sharness/t0054-dag-car-import-export.sh index 0482f24d9..e277cc466 100755 --- a/test/sharness/t0054-dag-car-import-export.sh +++ b/test/sharness/t0054-dag-car-import-export.sh @@ -178,13 +178,11 @@ test_expect_success "basic offline export of 'getting started' dag works" ' ipfs dag export "$HASH_WELCOME_DOCS" >/dev/null ' - -echo "Error: block was not found locally (offline): ipld: could not find QmYwAPJXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX (currently offline, perhaps retry after attaching to the network)" > offline_fetch_error_expected test_expect_success "basic offline export of nonexistent cid" ' ! ipfs dag export QmYwAPJXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 2> offline_fetch_error_actual >/dev/null ' test_expect_success "correct error" ' - test_cmp_sorted offline_fetch_error_expected offline_fetch_error_actual + test_should_contain "Error: block was not found locally (offline): ipld: could not find QmYwAPJXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" offline_fetch_error_actual ' cat >multiroot_import_json_stats_expected < Date: Tue, 31 Oct 2023 12:03:16 +0100 Subject: [PATCH 0914/1212] chore: bump boxo (#10188) --- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- test/dependencies/go.mod | 2 +- test/dependencies/go.sum | 4 ++-- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index dfb7848b0..a2e7ec6a8 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.20 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.13.2-0.20231028021353-182e86f5bb9b + github.com/ipfs/boxo v0.13.2-0.20231031104528-b0a265b5cdcc github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.31.0 github.com/multiformats/go-multiaddr v0.11.0 diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 49dbacfee..eb14a99fd 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -305,8 +305,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.13.2-0.20231028021353-182e86f5bb9b h1:0Qi1EhB82x3SZJOBieG51BtPvjU3kSy4H8OpMnxKvtk= -github.com/ipfs/boxo v0.13.2-0.20231028021353-182e86f5bb9b/go.mod h1:pu8HsZvuyYeYJsqtLDCoYSvy8rHj6vI3dlh8P0f83Zs= +github.com/ipfs/boxo v0.13.2-0.20231031104528-b0a265b5cdcc h1:jKrgzSr4RC04aG2LX8lA0emMOxSrckORZE4GKRZUt0Y= +github.com/ipfs/boxo v0.13.2-0.20231031104528-b0a265b5cdcc/go.mod h1:pu8HsZvuyYeYJsqtLDCoYSvy8rHj6vI3dlh8P0f83Zs= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= diff --git a/go.mod b/go.mod index c94a251cb..8970cf2be 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,7 @@ require ( github.com/hashicorp/go-multierror v1.1.1 github.com/ipfs-shipyard/nopfs v0.0.12-0.20231027223058-cde3b5ba964c github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c - github.com/ipfs/boxo v0.13.2-0.20231028021353-182e86f5bb9b + github.com/ipfs/boxo v0.13.2-0.20231031104528-b0a265b5cdcc github.com/ipfs/go-block-format v0.2.0 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 diff --git a/go.sum b/go.sum index 928433eaa..aad5e5150 100644 --- a/go.sum +++ b/go.sum @@ -339,8 +339,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.13.2-0.20231028021353-182e86f5bb9b h1:0Qi1EhB82x3SZJOBieG51BtPvjU3kSy4H8OpMnxKvtk= -github.com/ipfs/boxo v0.13.2-0.20231028021353-182e86f5bb9b/go.mod h1:pu8HsZvuyYeYJsqtLDCoYSvy8rHj6vI3dlh8P0f83Zs= +github.com/ipfs/boxo v0.13.2-0.20231031104528-b0a265b5cdcc h1:jKrgzSr4RC04aG2LX8lA0emMOxSrckORZE4GKRZUt0Y= +github.com/ipfs/boxo v0.13.2-0.20231031104528-b0a265b5cdcc/go.mod h1:pu8HsZvuyYeYJsqtLDCoYSvy8rHj6vI3dlh8P0f83Zs= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index cbc577f9b..5d7623cf2 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -7,7 +7,7 @@ replace github.com/ipfs/kubo => ../../ require ( github.com/Kubuxu/gocovmerge v0.0.0-20161216165753-7ecaa51963cd github.com/golangci/golangci-lint v1.54.1 - github.com/ipfs/boxo v0.13.2-0.20231028021353-182e86f5bb9b + github.com/ipfs/boxo v0.13.2-0.20231031104528-b0a265b5cdcc github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 github.com/ipfs/go-datastore v0.6.0 diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 90a00aebc..447099e12 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -398,8 +398,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.13.2-0.20231028021353-182e86f5bb9b h1:0Qi1EhB82x3SZJOBieG51BtPvjU3kSy4H8OpMnxKvtk= -github.com/ipfs/boxo v0.13.2-0.20231028021353-182e86f5bb9b/go.mod h1:pu8HsZvuyYeYJsqtLDCoYSvy8rHj6vI3dlh8P0f83Zs= +github.com/ipfs/boxo v0.13.2-0.20231031104528-b0a265b5cdcc h1:jKrgzSr4RC04aG2LX8lA0emMOxSrckORZE4GKRZUt0Y= +github.com/ipfs/boxo v0.13.2-0.20231031104528-b0a265b5cdcc/go.mod h1:pu8HsZvuyYeYJsqtLDCoYSvy8rHj6vI3dlh8P0f83Zs= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs= From ab7630fcd497c3761ecff76d35e1e9987dbbbec2 Mon Sep 17 00:00:00 2001 From: Andrew Gillis Date: Tue, 31 Oct 2023 06:45:51 -0700 Subject: [PATCH 0915/1212] chore: migrate peering to ipfs/boxo (#10157) Co-authored-by: Henrique Dias --- core/core.go | 2 +- core/node/peering.go | 5 +- peering/peering.go | 325 ---------------------------------------- peering/peering_test.go | 172 --------------------- 4 files changed, 4 insertions(+), 500 deletions(-) delete mode 100644 peering/peering.go delete mode 100644 peering/peering_test.go diff --git a/core/core.go b/core/core.go index c9bec6b8b..53c97c221 100644 --- a/core/core.go +++ b/core/core.go @@ -49,13 +49,13 @@ import ( "github.com/ipfs/boxo/namesys" ipnsrp "github.com/ipfs/boxo/namesys/republisher" + "github.com/ipfs/boxo/peering" "github.com/ipfs/kubo/config" "github.com/ipfs/kubo/core/bootstrap" "github.com/ipfs/kubo/core/node" "github.com/ipfs/kubo/core/node/libp2p" "github.com/ipfs/kubo/fuse/mount" "github.com/ipfs/kubo/p2p" - "github.com/ipfs/kubo/peering" "github.com/ipfs/kubo/repo" irouting "github.com/ipfs/kubo/routing" ) diff --git a/core/node/peering.go b/core/node/peering.go index eba165ef9..d6b563835 100644 --- a/core/node/peering.go +++ b/core/node/peering.go @@ -3,7 +3,7 @@ package node import ( "context" - "github.com/ipfs/kubo/peering" + "github.com/ipfs/boxo/peering" "github.com/libp2p/go-libp2p/core/host" "github.com/libp2p/go-libp2p/core/peer" "go.uber.org/fx" @@ -18,7 +18,8 @@ func Peering(lc fx.Lifecycle, host host.Host) *peering.PeeringService { return ps.Start() }, OnStop: func(context.Context) error { - return ps.Stop() + ps.Stop() + return nil }, }) return ps diff --git a/peering/peering.go b/peering/peering.go deleted file mode 100644 index 34647d63c..000000000 --- a/peering/peering.go +++ /dev/null @@ -1,325 +0,0 @@ -package peering - -import ( - "context" - "errors" - "math/rand" - "strconv" - "sync" - "time" - - "github.com/ipfs/go-log" - "github.com/libp2p/go-libp2p/core/host" - "github.com/libp2p/go-libp2p/core/network" - "github.com/libp2p/go-libp2p/core/peer" - "github.com/multiformats/go-multiaddr" -) - -// Seed the random number generator. -// -// We don't need good randomness, but we do need randomness. -const ( - // maxBackoff is the maximum time between reconnect attempts. - maxBackoff = 10 * time.Minute - // The backoff will be cut off when we get within 10% of the actual max. - // If we go over the max, we'll adjust the delay down to a random value - // between 90-100% of the max backoff. - maxBackoffJitter = 10 // % - connmgrTag = "ipfs-peering" - // This needs to be sufficient to prevent two sides from simultaneously - // dialing. - initialDelay = 5 * time.Second -) - -var logger = log.Logger("peering") - -type State uint - -func (s State) String() string { - switch s { - case StateInit: - return "init" - case StateRunning: - return "running" - case StateStopped: - return "stopped" - default: - return "unknown peering state: " + strconv.FormatUint(uint64(s), 10) - } -} - -const ( - StateInit State = iota - StateRunning - StateStopped -) - -// peerHandler keeps track of all state related to a specific "peering" peer. -type peerHandler struct { - peer peer.ID - host host.Host - ctx context.Context - cancel context.CancelFunc - - mu sync.Mutex - addrs []multiaddr.Multiaddr - reconnectTimer *time.Timer - - nextDelay time.Duration -} - -// setAddrs sets the addresses for this peer. -func (ph *peerHandler) setAddrs(addrs []multiaddr.Multiaddr) { - // Not strictly necessary, but it helps to not trust the calling code. - addrCopy := make([]multiaddr.Multiaddr, len(addrs)) - copy(addrCopy, addrs) - - ph.mu.Lock() - defer ph.mu.Unlock() - ph.addrs = addrCopy -} - -// getAddrs returns a shared slice of addresses for this peer. Do not modify. -func (ph *peerHandler) getAddrs() []multiaddr.Multiaddr { - ph.mu.Lock() - defer ph.mu.Unlock() - return ph.addrs -} - -// stop permanently stops the peer handler. -func (ph *peerHandler) stop() { - ph.cancel() - - ph.mu.Lock() - defer ph.mu.Unlock() - if ph.reconnectTimer != nil { - ph.reconnectTimer.Stop() - ph.reconnectTimer = nil - } -} - -func (ph *peerHandler) nextBackoff() time.Duration { - if ph.nextDelay < maxBackoff { - ph.nextDelay += ph.nextDelay/2 + time.Duration(rand.Int63n(int64(ph.nextDelay))) - } - - // If we've gone over the max backoff, reduce it under the max. - if ph.nextDelay > maxBackoff { - ph.nextDelay = maxBackoff - // randomize the backoff a bit (10%). - ph.nextDelay -= time.Duration(rand.Int63n(int64(maxBackoff) * maxBackoffJitter / 100)) - } - - return ph.nextDelay -} - -func (ph *peerHandler) reconnect() { - // Try connecting - addrs := ph.getAddrs() - logger.Debugw("reconnecting", "peer", ph.peer, "addrs", addrs) - - err := ph.host.Connect(ph.ctx, peer.AddrInfo{ID: ph.peer, Addrs: addrs}) - if err != nil { - logger.Debugw("failed to reconnect", "peer", ph.peer, "error", err) - // Ok, we failed. Extend the timeout. - ph.mu.Lock() - if ph.reconnectTimer != nil { - // Only counts if the reconnectTimer still exists. If not, a - // connection _was_ somehow established. - ph.reconnectTimer.Reset(ph.nextBackoff()) - } - // Otherwise, someone else has stopped us so we can assume that - // we're either connected or someone else will start us. - ph.mu.Unlock() - } - - // Always call this. We could have connected since we processed the - // error. - ph.stopIfConnected() -} - -func (ph *peerHandler) stopIfConnected() { - ph.mu.Lock() - defer ph.mu.Unlock() - - if ph.reconnectTimer != nil && ph.host.Network().Connectedness(ph.peer) == network.Connected { - logger.Debugw("successfully reconnected", "peer", ph.peer) - ph.reconnectTimer.Stop() - ph.reconnectTimer = nil - ph.nextDelay = initialDelay - } -} - -// startIfDisconnected is the inverse of stopIfConnected. -func (ph *peerHandler) startIfDisconnected() { - ph.mu.Lock() - defer ph.mu.Unlock() - - if ph.reconnectTimer == nil && ph.host.Network().Connectedness(ph.peer) != network.Connected { - logger.Debugw("disconnected from peer", "peer", ph.peer) - // Always start with a short timeout so we can stagger things a bit. - ph.reconnectTimer = time.AfterFunc(ph.nextBackoff(), ph.reconnect) - } -} - -// PeeringService maintains connections to specified peers, reconnecting on -// disconnect with a back-off. -type PeeringService struct { - host host.Host - - mu sync.RWMutex - peers map[peer.ID]*peerHandler - state State -} - -// NewPeeringService constructs a new peering service. Peers can be added and -// removed immediately, but connections won't be formed until `Start` is called. -func NewPeeringService(host host.Host) *PeeringService { - return &PeeringService{host: host, peers: make(map[peer.ID]*peerHandler)} -} - -// Start starts the peering service, connecting and maintaining connections to -// all registered peers. It returns an error if the service has already been -// stopped. -func (ps *PeeringService) Start() error { - ps.mu.Lock() - defer ps.mu.Unlock() - - switch ps.state { - case StateInit: - logger.Infow("starting") - case StateRunning: - return nil - case StateStopped: - return errors.New("already stopped") - } - ps.host.Network().Notify((*netNotifee)(ps)) - ps.state = StateRunning - for _, handler := range ps.peers { - go handler.startIfDisconnected() - } - return nil -} - -// GetState get the State of the PeeringService. -func (ps *PeeringService) GetState() State { - ps.mu.RLock() - defer ps.mu.RUnlock() - return ps.state -} - -// Stop stops the peering service. -func (ps *PeeringService) Stop() error { - ps.host.Network().StopNotify((*netNotifee)(ps)) - ps.mu.Lock() - defer ps.mu.Unlock() - - switch ps.state { - case StateInit, StateRunning: - logger.Infow("stopping") - for _, handler := range ps.peers { - handler.stop() - } - ps.state = StateStopped - } - return nil -} - -// AddPeer adds a peer to the peering service. This function may be safely -// called at any time: before the service is started, while running, or after it -// stops. -// -// Add peer may also be called multiple times for the same peer. The new -// addresses will replace the old. -func (ps *PeeringService) AddPeer(info peer.AddrInfo) { - ps.mu.Lock() - defer ps.mu.Unlock() - - if handler, ok := ps.peers[info.ID]; ok { - logger.Infow("updating addresses", "peer", info.ID, "addrs", info.Addrs) - handler.setAddrs(info.Addrs) - } else { - logger.Infow("peer added", "peer", info.ID, "addrs", info.Addrs) - ps.host.ConnManager().Protect(info.ID, connmgrTag) - - handler = &peerHandler{ - host: ps.host, - peer: info.ID, - addrs: info.Addrs, - nextDelay: initialDelay, - } - handler.ctx, handler.cancel = context.WithCancel(context.Background()) - ps.peers[info.ID] = handler - switch ps.state { - case StateRunning: - go handler.startIfDisconnected() - case StateStopped: - // We still construct everything in this state because - // it's easier to reason about. But we should still free - // resources. - handler.cancel() - } - } -} - -// ListPeers lists peers in the peering service. -func (ps *PeeringService) ListPeers() []peer.AddrInfo { - ps.mu.RLock() - defer ps.mu.RUnlock() - - out := make([]peer.AddrInfo, 0, len(ps.peers)) - for id, addrs := range ps.peers { - ai := peer.AddrInfo{ID: id} - ai.Addrs = append(ai.Addrs, addrs.addrs...) - out = append(out, ai) - } - return out -} - -// RemovePeer removes a peer from the peering service. This function may be -// safely called at any time: before the service is started, while running, or -// after it stops. -func (ps *PeeringService) RemovePeer(id peer.ID) { - ps.mu.Lock() - defer ps.mu.Unlock() - - if handler, ok := ps.peers[id]; ok { - logger.Infow("peer removed", "peer", id) - ps.host.ConnManager().Unprotect(id, connmgrTag) - - handler.stop() - delete(ps.peers, id) - } -} - -type netNotifee PeeringService - -func (nn *netNotifee) Connected(_ network.Network, c network.Conn) { - ps := (*PeeringService)(nn) - - p := c.RemotePeer() - ps.mu.RLock() - defer ps.mu.RUnlock() - - if handler, ok := ps.peers[p]; ok { - // use a goroutine to avoid blocking events. - go handler.stopIfConnected() - } -} - -func (nn *netNotifee) Disconnected(_ network.Network, c network.Conn) { - ps := (*PeeringService)(nn) - - p := c.RemotePeer() - ps.mu.RLock() - defer ps.mu.RUnlock() - - if handler, ok := ps.peers[p]; ok { - // use a goroutine to avoid blocking events. - go handler.startIfDisconnected() - } -} -func (nn *netNotifee) OpenedStream(network.Network, network.Stream) {} -func (nn *netNotifee) ClosedStream(network.Network, network.Stream) {} -func (nn *netNotifee) Listen(network.Network, multiaddr.Multiaddr) {} -func (nn *netNotifee) ListenClose(network.Network, multiaddr.Multiaddr) {} diff --git a/peering/peering_test.go b/peering/peering_test.go deleted file mode 100644 index de07789c2..000000000 --- a/peering/peering_test.go +++ /dev/null @@ -1,172 +0,0 @@ -package peering - -import ( - "context" - "testing" - "time" - - "github.com/libp2p/go-libp2p" - "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(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(cm), - ) - require.NoError(t, err) - return h -} - -func TestPeeringService(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - h1 := newNode(t) - ps1 := NewPeeringService(h1) - - h2 := newNode(t) - h3 := newNode(t) - h4 := newNode(t) - - // peer 1 -> 2 - ps1.AddPeer(peer.AddrInfo{ID: h2.ID(), Addrs: h2.Addrs()}) - require.Contains(t, ps1.ListPeers(), peer.AddrInfo{ID: h2.ID(), Addrs: h2.Addrs()}) - - // We haven't started so we shouldn't have any peers. - require.Never(t, func() bool { - return len(h1.Network().Peers()) > 0 - }, 100*time.Millisecond, 1*time.Second, "expected host 1 to have no peers") - - // Use p4 to take up the one slot we have in the connection manager. - for _, h := range []host.Host{h1, h2} { - require.NoError(t, h.Connect(ctx, peer.AddrInfo{ID: h4.ID(), Addrs: h4.Addrs()})) - h.ConnManager().TagPeer(h4.ID(), "sticky-peer", 1000) - } - - // Now start. - require.NoError(t, ps1.Start()) - // starting twice is fine. - require.NoError(t, ps1.Start()) - - // We should eventually connect. - t.Logf("waiting for h1 to connect to h2") - require.Eventually(t, func() bool { - return h1.Network().Connectedness(h2.ID()) == network.Connected - }, 30*time.Second, 10*time.Millisecond) - - // Now explicitly connect to h3. - t.Logf("waiting for h1's connection to h3 to work") - require.NoError(t, h1.Connect(ctx, peer.AddrInfo{ID: h3.ID(), Addrs: h3.Addrs()})) - require.Eventually(t, func() bool { - return h1.Network().Connectedness(h3.ID()) == network.Connected - }, 30*time.Second, 100*time.Millisecond) - - require.Len(t, h1.Network().Peers(), 3) - - // force a disconnect - h1.ConnManager().TrimOpenConns(ctx) - - // Should disconnect from h3. - t.Logf("waiting for h1's connection to h3 to disconnect") - require.Eventually(t, func() bool { - return h1.Network().Connectedness(h3.ID()) != network.Connected - }, 5*time.Second, 10*time.Millisecond) - - // Should remain connected to p2 - require.Never(t, func() bool { - return h1.Network().Connectedness(h2.ID()) != network.Connected - }, 5*time.Second, 1*time.Second) - - // Now force h2 to disconnect (we have an asymmetric peering). - conns := h2.Network().ConnsToPeer(h1.ID()) - require.NotEmpty(t, conns) - h2.ConnManager().TrimOpenConns(ctx) - - // All conns to peer should eventually close. - t.Logf("waiting for all connections to close") - for _, c := range conns { - require.Eventually(t, func() bool { - s, err := c.NewStream(context.Background()) - if s != nil { - _ = s.Reset() - } - return err != nil - }, 5*time.Second, 10*time.Millisecond) - } - - // Should eventually re-connect. - require.Eventually(t, func() bool { - return h1.Network().Connectedness(h2.ID()) == network.Connected - }, 30*time.Second, 1*time.Second) - - // Unprotect 2 from 1. - ps1.RemovePeer(h2.ID()) - require.NotContains(t, ps1.ListPeers(), peer.AddrInfo{ID: h2.ID(), Addrs: h2.Addrs()}) - - // Trim connections. - h1.ConnManager().TrimOpenConns(ctx) - - // Should disconnect - t.Logf("waiting for h1 to disconnect from h2") - require.Eventually(t, func() bool { - return h1.Network().Connectedness(h2.ID()) != network.Connected - }, 5*time.Second, 10*time.Millisecond) - - // Should never reconnect. - t.Logf("ensuring h1 is not connected to h2 again") - require.Never(t, func() bool { - return h1.Network().Connectedness(h2.ID()) == network.Connected - }, 20*time.Second, 1*time.Second) - - // Until added back - ps1.AddPeer(peer.AddrInfo{ID: h2.ID(), Addrs: h2.Addrs()}) - require.Contains(t, ps1.ListPeers(), peer.AddrInfo{ID: h2.ID(), Addrs: h2.Addrs()}) - ps1.AddPeer(peer.AddrInfo{ID: h3.ID(), Addrs: h3.Addrs()}) - require.Contains(t, ps1.ListPeers(), peer.AddrInfo{ID: h3.ID(), Addrs: h3.Addrs()}) - t.Logf("wait for h1 to connect to h2 and h3 again") - require.Eventually(t, func() bool { - return h1.Network().Connectedness(h2.ID()) == network.Connected - }, 30*time.Second, 1*time.Second) - require.Eventually(t, func() bool { - return h1.Network().Connectedness(h3.ID()) == network.Connected - }, 30*time.Second, 1*time.Second) - - // Should be able to repeatedly stop. - require.NoError(t, ps1.Stop()) - require.NoError(t, ps1.Stop()) - - // Adding and removing should work after stopping. - ps1.AddPeer(peer.AddrInfo{ID: h4.ID(), Addrs: h4.Addrs()}) - require.Contains(t, ps1.ListPeers(), peer.AddrInfo{ID: h4.ID(), Addrs: h4.Addrs()}) - ps1.RemovePeer(h2.ID()) - require.NotContains(t, ps1.ListPeers(), peer.AddrInfo{ID: h2.ID(), Addrs: h2.Addrs()}) -} - -func TestNextBackoff(t *testing.T) { - minMaxBackoff := (100 - maxBackoffJitter) / 100 * maxBackoff - for x := 0; x < 1000; x++ { - ph := peerHandler{nextDelay: time.Second} - for min, max := time.Second*3/2, time.Second*5/2; min < minMaxBackoff; min, max = min*3/2, max*5/2 { - b := ph.nextBackoff() - if b > max || b < min { - t.Errorf("expected backoff %s to be between %s and %s", b, min, max) - } - } - for i := 0; i < 100; i++ { - b := ph.nextBackoff() - if b < minMaxBackoff || b > maxBackoff { - t.Fatal("failed to stay within max bounds") - } - } - } -} From d1ccdf052b6414c7f3b8fb284c0deb2477fdb2ed Mon Sep 17 00:00:00 2001 From: Andrew Gillis Date: Tue, 31 Oct 2023 10:25:14 -0700 Subject: [PATCH 0916/1212] chore: migrate bootstrap to ipfs/boxo (#10158) --- core/bootstrap/bootstrap.go | 371 ------------------ core/bootstrap/bootstrap_test.go | 139 ------- core/builder.go | 2 +- core/core.go | 2 +- core/coreapi/test/api_test.go | 2 +- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 +- go.mod | 2 +- go.sum | 4 +- test/dependencies/go.mod | 2 +- test/dependencies/go.sum | 4 +- test/integration/addcat_test.go | 2 +- test/integration/bench_cat_test.go | 2 +- .../integration/pubsub_msg_seen_cache_test.go | 2 +- test/integration/three_legged_cat_test.go | 2 +- 15 files changed, 16 insertions(+), 526 deletions(-) delete mode 100644 core/bootstrap/bootstrap.go delete mode 100644 core/bootstrap/bootstrap_test.go diff --git a/core/bootstrap/bootstrap.go b/core/bootstrap/bootstrap.go deleted file mode 100644 index 5cde50371..000000000 --- a/core/bootstrap/bootstrap.go +++ /dev/null @@ -1,371 +0,0 @@ -package bootstrap - -import ( - "context" - "errors" - "io" - "math/rand" - "sync" - "sync/atomic" - "time" - - logging "github.com/ipfs/go-log" - "github.com/jbenet/goprocess" - goprocessctx "github.com/jbenet/goprocess/context" - periodicproc "github.com/jbenet/goprocess/periodic" - "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/core/peerstore" - "github.com/libp2p/go-libp2p/core/routing" -) - -var log = logging.Logger("bootstrap") - -// ErrNotEnoughBootstrapPeers signals that we do not have enough bootstrap -// peers to bootstrap correctly. -var ErrNotEnoughBootstrapPeers = errors.New("not enough bootstrap peers to bootstrap") - -// BootstrapConfig specifies parameters used in an IpfsNode's network -// bootstrapping process. -type BootstrapConfig struct { - // MinPeerThreshold governs whether to bootstrap more connections. If the - // node has less open connections than this number, it will open connections - // to the bootstrap nodes. From there, the routing system should be able - // to use the connections to the bootstrap nodes to connect to even more - // peers. Routing systems like the IpfsDHT do so in their own Bootstrap - // process, which issues random queries to find more peers. - MinPeerThreshold int - - // Period governs the periodic interval at which the node will - // attempt to bootstrap. The bootstrap process is not very expensive, so - // this threshold can afford to be small (<=30s). - Period time.Duration - - // ConnectionTimeout determines how long to wait for a bootstrap - // connection attempt before cancelling it. - ConnectionTimeout time.Duration - - // BootstrapPeers is a function that returns a set of bootstrap peers - // for the bootstrap process to use. This makes it possible for clients - // to control the peers the process uses at any moment. - BootstrapPeers func() []peer.AddrInfo - - // BackupBootstrapInterval governs the periodic interval at which the node will - // attempt to save connected nodes to use as temporary bootstrap peers. - BackupBootstrapInterval time.Duration - - // MaxBackupBootstrapSize controls the maximum number of peers we're saving - // as backup bootstrap peers. - MaxBackupBootstrapSize int - - saveBackupBootstrapPeers func(context.Context, []peer.AddrInfo) - loadBackupBootstrapPeers func(context.Context) []peer.AddrInfo -} - -// DefaultBootstrapConfig specifies default sane parameters for bootstrapping. -var DefaultBootstrapConfig = BootstrapConfig{ - MinPeerThreshold: 4, - Period: 30 * time.Second, - ConnectionTimeout: (30 * time.Second) / 3, // Perod / 3 - BackupBootstrapInterval: 1 * time.Hour, - MaxBackupBootstrapSize: 20, -} - -// BootstrapConfigWithPeers creates a default BootstrapConfig configured with -// the specified peers, and optional functions to load and save backup peers. -func BootstrapConfigWithPeers(pis []peer.AddrInfo, options ...func(*BootstrapConfig)) BootstrapConfig { - cfg := DefaultBootstrapConfig - cfg.BootstrapPeers = func() []peer.AddrInfo { - return pis - } - for _, opt := range options { - opt(&cfg) - } - return cfg -} - -// WithBackupPeers configures functions to load and save backup bootstrap peers. -func WithBackupPeers(load func(context.Context) []peer.AddrInfo, save func(context.Context, []peer.AddrInfo)) func(*BootstrapConfig) { - if save == nil && load != nil || save != nil && load == nil { - panic("both load and save backup bootstrap peers functions must be defined") - } - return func(cfg *BootstrapConfig) { - cfg.loadBackupBootstrapPeers = load - cfg.saveBackupBootstrapPeers = save - } -} - -// BackupPeers returns the load and save backup peers functions. -func (cfg *BootstrapConfig) BackupPeers() (func(context.Context) []peer.AddrInfo, func(context.Context, []peer.AddrInfo)) { - return cfg.loadBackupBootstrapPeers, cfg.saveBackupBootstrapPeers -} - -// SetBackupPeers sets the load and save backup peers functions. -func (cfg *BootstrapConfig) SetBackupPeers(load func(context.Context) []peer.AddrInfo, save func(context.Context, []peer.AddrInfo)) { - opt := WithBackupPeers(load, save) - opt(cfg) -} - -// Bootstrap kicks off IpfsNode bootstrapping. This function will periodically -// check the number of open connections and -- if there are too few -- initiate -// connections to well-known bootstrap peers. It also kicks off subsystem -// bootstrapping (i.e. routing). -func Bootstrap(id peer.ID, host host.Host, rt routing.Routing, cfg BootstrapConfig) (io.Closer, error) { - // make a signal to wait for one bootstrap round to complete. - doneWithRound := make(chan struct{}) - - if len(cfg.BootstrapPeers()) == 0 { - // We *need* to bootstrap but we have no bootstrap peers - // configured *at all*, inform the user. - log.Warn("no bootstrap nodes configured: go-ipfs may have difficulty connecting to the network") - } - - // the periodic bootstrap function -- the connection supervisor - periodic := func(worker goprocess.Process) { - ctx := goprocessctx.OnClosingContext(worker) - - if err := bootstrapRound(ctx, host, cfg); err != nil { - log.Debugf("%s bootstrap error: %s", id, err) - } - - // Exit the first call (triggered independently by `proc.Go`, not `Tick`) - // only after being done with the *single* Routing.Bootstrap call. Following - // periodic calls (`Tick`) will not block on this. - <-doneWithRound - } - - // kick off the node's periodic bootstrapping - proc := periodicproc.Tick(cfg.Period, periodic) - proc.Go(periodic) // run one right now. - - // kick off Routing.Bootstrap - if rt != nil { - ctx := goprocessctx.OnClosingContext(proc) - if err := rt.Bootstrap(ctx); err != nil { - proc.Close() - return nil, err - } - } - - doneWithRound <- struct{}{} - close(doneWithRound) // it no longer blocks periodic - - // If loadBackupBootstrapPeers is not nil then saveBackupBootstrapPeers - // must also not be nil. - if cfg.loadBackupBootstrapPeers != nil { - startSavePeersAsTemporaryBootstrapProc(cfg, host, proc) - } - - return proc, nil -} - -// Aside of the main bootstrap process we also run a secondary one that saves -// connected peers as a backup measure if we can't connect to the official -// bootstrap ones. These peers will serve as *temporary* bootstrap nodes. -func startSavePeersAsTemporaryBootstrapProc(cfg BootstrapConfig, host host.Host, bootstrapProc goprocess.Process) { - savePeersFn := func(worker goprocess.Process) { - ctx := goprocessctx.OnClosingContext(worker) - - if err := saveConnectedPeersAsTemporaryBootstrap(ctx, host, cfg); err != nil { - log.Debugf("saveConnectedPeersAsTemporaryBootstrap error: %s", err) - } - } - savePeersProc := periodicproc.Tick(cfg.BackupBootstrapInterval, savePeersFn) - - // When the main bootstrap process ends also terminate the 'save connected - // peers' ones. Coupling the two seems the easiest way to handle this backup - // process without additional complexity. - go func() { - <-bootstrapProc.Closing() - savePeersProc.Close() - }() - - // Run the first round now (after the first bootstrap process has finished) - // as the SavePeersPeriod can be much longer than bootstrap. - savePeersProc.Go(savePeersFn) -} - -func saveConnectedPeersAsTemporaryBootstrap(ctx context.Context, host host.Host, cfg BootstrapConfig) error { - // Randomize the list of connected peers, we don't prioritize anyone. - connectedPeers := randomizeList(host.Network().Peers()) - - bootstrapPeers := cfg.BootstrapPeers() - backupPeers := make([]peer.AddrInfo, 0, cfg.MaxBackupBootstrapSize) - foundPeers := make(map[peer.ID]struct{}, cfg.MaxBackupBootstrapSize+len(bootstrapPeers)) - - // Don't record bootstrap peers - for _, b := range bootstrapPeers { - foundPeers[b.ID] = struct{}{} - } - - // Choose peers to save and filter out the ones that are already bootstrap nodes. - for _, p := range connectedPeers { - if _, found := foundPeers[p]; found { - continue - } - foundPeers[p] = struct{}{} - - backupPeers = append(backupPeers, peer.AddrInfo{ - ID: p, - Addrs: host.Network().Peerstore().Addrs(p), - }) - - if len(backupPeers) >= cfg.MaxBackupBootstrapSize { - break - } - } - - // If we didn't reach the target number use previously stored connected peers. - if len(backupPeers) < cfg.MaxBackupBootstrapSize { - oldSavedPeers := cfg.loadBackupBootstrapPeers(ctx) - log.Debugf("missing %d peers to reach backup bootstrap target of %d, trying from previous list of %d saved peers", - cfg.MaxBackupBootstrapSize-len(backupPeers), cfg.MaxBackupBootstrapSize, len(oldSavedPeers)) - - // Add some of the old saved peers. Ensure we don't duplicate them. - for _, p := range oldSavedPeers { - if _, found := foundPeers[p.ID]; found { - continue - } - foundPeers[p.ID] = struct{}{} - - backupPeers = append(backupPeers, p) - - if len(backupPeers) >= cfg.MaxBackupBootstrapSize { - break - } - } - } - - cfg.saveBackupBootstrapPeers(ctx, backupPeers) - log.Debugf("saved %d peers (of %d target) as bootstrap backup in the config", len(backupPeers), cfg.MaxBackupBootstrapSize) - return nil -} - -// Connect to as many peers needed to reach the BootstrapConfig.MinPeerThreshold. -// Peers can be original bootstrap or temporary ones (drawn from a list of -// persisted previously connected peers). -func bootstrapRound(ctx context.Context, host host.Host, cfg BootstrapConfig) error { - ctx, cancel := context.WithTimeout(ctx, cfg.ConnectionTimeout) - defer cancel() - id := host.ID() - - // get bootstrap peers from config. retrieving them here makes - // sure we remain observant of changes to client configuration. - peers := cfg.BootstrapPeers() - // determine how many bootstrap connections to open - connected := host.Network().Peers() - if len(connected) >= cfg.MinPeerThreshold { - log.Debugf("%s core bootstrap skipped -- connected to %d (> %d) nodes", - id, len(connected), cfg.MinPeerThreshold) - return nil - } - numToDial := cfg.MinPeerThreshold - len(connected) // numToDial > 0 - - if len(peers) > 0 { - numToDial -= int(peersConnect(ctx, host, peers, numToDial, true)) - if numToDial <= 0 { - return nil - } - } - - if cfg.loadBackupBootstrapPeers == nil { - log.Debugf("not enough bootstrap peers to fill the remaining target of %d connections", numToDial) - return ErrNotEnoughBootstrapPeers - } - - log.Debugf("not enough bootstrap peers to fill the remaining target of %d connections, trying backup list", numToDial) - - tempBootstrapPeers := cfg.loadBackupBootstrapPeers(ctx) - if len(tempBootstrapPeers) > 0 { - numToDial -= int(peersConnect(ctx, host, tempBootstrapPeers, numToDial, false)) - if numToDial <= 0 { - return nil - } - } - - log.Debugf("tried both original bootstrap peers and temporary ones but still missing target of %d connections", numToDial) - - return ErrNotEnoughBootstrapPeers -} - -// Attempt to make `needed` connections from the `availablePeers` list. Mark -// peers as either `permanent` or temporary when adding them to the Peerstore. -// Return the number of connections completed. We eagerly over-connect in parallel, -// so we might connect to more than needed. -// (We spawn as many routines and attempt connections as the number of availablePeers, -// but this list comes from restricted sets of original or temporary bootstrap -// nodes which will keep it under a sane value.) -func peersConnect(ctx context.Context, ph host.Host, availablePeers []peer.AddrInfo, needed int, permanent bool) uint64 { - peers := randomizeList(availablePeers) - - // Monitor the number of connections and stop if we reach the target. - var connected uint64 - ctx, cancel := context.WithCancel(ctx) - defer cancel() - go func() { - for { - select { - case <-ctx.Done(): - return - case <-time.After(1 * time.Second): - if int(atomic.LoadUint64(&connected)) >= needed { - cancel() - return - } - } - } - }() - - var wg sync.WaitGroup - for _, p := range peers { - - // performed asynchronously because when performed synchronously, if - // one `Connect` call hangs, subsequent calls are more likely to - // fail/abort due to an expiring context. - // Also, performed asynchronously for dial speed. - - if int(atomic.LoadUint64(&connected)) >= needed { - cancel() - break - } - - wg.Add(1) - go func(p peer.AddrInfo) { - defer wg.Done() - - // Skip addresses belonging to a peer we're already connected to. - // (Not a guarantee but a best-effort policy.) - if ph.Network().Connectedness(p.ID) == network.Connected { - return - } - log.Debugf("%s bootstrapping to %s", ph.ID(), p.ID) - - if err := ph.Connect(ctx, p); err != nil { - if ctx.Err() != context.Canceled { - log.Debugf("failed to bootstrap with %v: %s", p.ID, err) - } - return - } - if permanent { - // We're connecting to an original bootstrap peer, mark it as - // a permanent address (Connect will register it as TempAddrTTL). - ph.Peerstore().AddAddrs(p.ID, p.Addrs, peerstore.PermanentAddrTTL) - } - - log.Infof("bootstrapped with %v", p.ID) - atomic.AddUint64(&connected, 1) - }(p) - } - wg.Wait() - - return connected -} - -func randomizeList[T any](in []T) []T { - out := make([]T, len(in)) - for i, val := range rand.Perm(len(in)) { - out[i] = in[val] - } - return out -} diff --git a/core/bootstrap/bootstrap_test.go b/core/bootstrap/bootstrap_test.go deleted file mode 100644 index d933379d4..000000000 --- a/core/bootstrap/bootstrap_test.go +++ /dev/null @@ -1,139 +0,0 @@ -package bootstrap - -import ( - "context" - "crypto/rand" - "reflect" - "testing" - "time" - - "github.com/libp2p/go-libp2p" - "github.com/libp2p/go-libp2p/core/crypto" - "github.com/libp2p/go-libp2p/core/peer" - "github.com/libp2p/go-libp2p/core/test" -) - -func TestRandomizeAddressList(t *testing.T) { - var ps []peer.AddrInfo - sizeofSlice := 10 - for i := 0; i < sizeofSlice; i++ { - pid, err := test.RandPeerID() - if err != nil { - t.Fatal(err) - } - - ps = append(ps, peer.AddrInfo{ID: pid}) - } - out := randomizeList(ps) - if len(out) != len(ps) { - t.Fail() - } -} - -func TestLoadAndSaveOptions(t *testing.T) { - loadFunc := func(_ context.Context) []peer.AddrInfo { return nil } - saveFunc := func(_ context.Context, _ []peer.AddrInfo) {} - - bootCfg := BootstrapConfigWithPeers(nil, WithBackupPeers(loadFunc, saveFunc)) - load, save := bootCfg.BackupPeers() - if load == nil { - t.Fatal("load function not assigned") - } - if reflect.ValueOf(load).Pointer() != reflect.ValueOf(loadFunc).Pointer() { - t.Fatal("load not assigned correct function") - } - if save == nil { - t.Fatal("save function not assigned") - } - if reflect.ValueOf(save).Pointer() != reflect.ValueOf(saveFunc).Pointer() { - t.Fatal("save not assigned correct function") - } - - assertPanics(t, "with only load func", func() { - BootstrapConfigWithPeers(nil, WithBackupPeers(loadFunc, nil)) - }) - - assertPanics(t, "with only save func", func() { - BootstrapConfigWithPeers(nil, WithBackupPeers(nil, saveFunc)) - }) - - bootCfg = BootstrapConfigWithPeers(nil, WithBackupPeers(nil, nil)) - load, save = bootCfg.BackupPeers() - if load != nil || save != nil { - t.Fatal("load and save functions should both be nil") - } -} - -func TestSetBackupPeers(t *testing.T) { - loadFunc := func(_ context.Context) []peer.AddrInfo { return nil } - saveFunc := func(_ context.Context, _ []peer.AddrInfo) {} - - bootCfg := DefaultBootstrapConfig - bootCfg.SetBackupPeers(loadFunc, saveFunc) - load, save := bootCfg.BackupPeers() - if load == nil { - t.Fatal("load function not assigned") - } - if reflect.ValueOf(load).Pointer() != reflect.ValueOf(loadFunc).Pointer() { - t.Fatal("load not assigned correct function") - } - if save == nil { - t.Fatal("save function not assigned") - } - if reflect.ValueOf(save).Pointer() != reflect.ValueOf(saveFunc).Pointer() { - t.Fatal("save not assigned correct function") - } - - assertPanics(t, "with only load func", func() { - bootCfg.SetBackupPeers(loadFunc, nil) - }) - - assertPanics(t, "with only save func", func() { - bootCfg.SetBackupPeers(nil, saveFunc) - }) - - bootCfg.SetBackupPeers(nil, nil) - load, save = bootCfg.BackupPeers() - if load != nil || save != nil { - t.Fatal("load and save functions should both be nil") - } -} - -func TestNoTempPeersLoadAndSave(t *testing.T) { - period := 500 * time.Millisecond - bootCfg := BootstrapConfigWithPeers(nil) - bootCfg.MinPeerThreshold = 2 - bootCfg.Period = period - - priv, pub, err := crypto.GenerateEd25519Key(rand.Reader) - if err != nil { - t.Fatal(err) - } - peerID, err := peer.IDFromPublicKey(pub) - if err != nil { - t.Fatal(err) - } - p2pHost, err := libp2p.New(libp2p.Identity(priv)) - if err != nil { - t.Fatal(err) - } - - bootstrapper, err := Bootstrap(peerID, p2pHost, nil, bootCfg) - if err != nil { - t.Fatal(err) - } - - time.Sleep(4 * period) - bootstrapper.Close() - -} - -func assertPanics(t *testing.T, name string, f func()) { - defer func() { - if r := recover(); r == nil { - t.Errorf("%s: did not panic as expected", name) - } - }() - - f() -} diff --git a/core/builder.go b/core/builder.go index 7a1d6fef2..4c54ddf8c 100644 --- a/core/builder.go +++ b/core/builder.go @@ -7,7 +7,7 @@ import ( "sync" "time" - "github.com/ipfs/kubo/core/bootstrap" + "github.com/ipfs/boxo/bootstrap" "github.com/ipfs/kubo/core/node" "github.com/ipfs/go-metrics-interface" diff --git a/core/core.go b/core/core.go index 53c97c221..40c680859 100644 --- a/core/core.go +++ b/core/core.go @@ -47,11 +47,11 @@ import ( ma "github.com/multiformats/go-multiaddr" madns "github.com/multiformats/go-multiaddr-dns" + "github.com/ipfs/boxo/bootstrap" "github.com/ipfs/boxo/namesys" ipnsrp "github.com/ipfs/boxo/namesys/republisher" "github.com/ipfs/boxo/peering" "github.com/ipfs/kubo/config" - "github.com/ipfs/kubo/core/bootstrap" "github.com/ipfs/kubo/core/node" "github.com/ipfs/kubo/core/node/libp2p" "github.com/ipfs/kubo/fuse/mount" diff --git a/core/coreapi/test/api_test.go b/core/coreapi/test/api_test.go index 3ae74b97e..d9591f835 100644 --- a/core/coreapi/test/api_test.go +++ b/core/coreapi/test/api_test.go @@ -8,10 +8,10 @@ import ( "path/filepath" "testing" + "github.com/ipfs/boxo/bootstrap" "github.com/ipfs/boxo/filestore" keystore "github.com/ipfs/boxo/keystore" "github.com/ipfs/kubo/core" - "github.com/ipfs/kubo/core/bootstrap" "github.com/ipfs/kubo/core/coreapi" mock "github.com/ipfs/kubo/core/mock" "github.com/ipfs/kubo/core/node/libp2p" diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index a2e7ec6a8..142f342f9 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.20 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.13.2-0.20231031104528-b0a265b5cdcc + github.com/ipfs/boxo v0.13.2-0.20231031170949-08b11e5df06e github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.31.0 github.com/multiformats/go-multiaddr v0.11.0 diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index eb14a99fd..b45088174 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -305,8 +305,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.13.2-0.20231031104528-b0a265b5cdcc h1:jKrgzSr4RC04aG2LX8lA0emMOxSrckORZE4GKRZUt0Y= -github.com/ipfs/boxo v0.13.2-0.20231031104528-b0a265b5cdcc/go.mod h1:pu8HsZvuyYeYJsqtLDCoYSvy8rHj6vI3dlh8P0f83Zs= +github.com/ipfs/boxo v0.13.2-0.20231031170949-08b11e5df06e h1:+A0lJ8vc6YtiMiq3UodN0BgZJTso/VJDrECdyHpsFDY= +github.com/ipfs/boxo v0.13.2-0.20231031170949-08b11e5df06e/go.mod h1:pu8HsZvuyYeYJsqtLDCoYSvy8rHj6vI3dlh8P0f83Zs= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= diff --git a/go.mod b/go.mod index 8970cf2be..50555089b 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,7 @@ require ( github.com/hashicorp/go-multierror v1.1.1 github.com/ipfs-shipyard/nopfs v0.0.12-0.20231027223058-cde3b5ba964c github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c - github.com/ipfs/boxo v0.13.2-0.20231031104528-b0a265b5cdcc + github.com/ipfs/boxo v0.13.2-0.20231031170949-08b11e5df06e github.com/ipfs/go-block-format v0.2.0 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 diff --git a/go.sum b/go.sum index aad5e5150..e83c67de2 100644 --- a/go.sum +++ b/go.sum @@ -339,8 +339,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.13.2-0.20231031104528-b0a265b5cdcc h1:jKrgzSr4RC04aG2LX8lA0emMOxSrckORZE4GKRZUt0Y= -github.com/ipfs/boxo v0.13.2-0.20231031104528-b0a265b5cdcc/go.mod h1:pu8HsZvuyYeYJsqtLDCoYSvy8rHj6vI3dlh8P0f83Zs= +github.com/ipfs/boxo v0.13.2-0.20231031170949-08b11e5df06e h1:+A0lJ8vc6YtiMiq3UodN0BgZJTso/VJDrECdyHpsFDY= +github.com/ipfs/boxo v0.13.2-0.20231031170949-08b11e5df06e/go.mod h1:pu8HsZvuyYeYJsqtLDCoYSvy8rHj6vI3dlh8P0f83Zs= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 5d7623cf2..30f462704 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -7,7 +7,7 @@ replace github.com/ipfs/kubo => ../../ require ( github.com/Kubuxu/gocovmerge v0.0.0-20161216165753-7ecaa51963cd github.com/golangci/golangci-lint v1.54.1 - github.com/ipfs/boxo v0.13.2-0.20231031104528-b0a265b5cdcc + github.com/ipfs/boxo v0.13.2-0.20231031170949-08b11e5df06e github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 github.com/ipfs/go-datastore v0.6.0 diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 447099e12..c9708b27b 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -398,8 +398,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.13.2-0.20231031104528-b0a265b5cdcc h1:jKrgzSr4RC04aG2LX8lA0emMOxSrckORZE4GKRZUt0Y= -github.com/ipfs/boxo v0.13.2-0.20231031104528-b0a265b5cdcc/go.mod h1:pu8HsZvuyYeYJsqtLDCoYSvy8rHj6vI3dlh8P0f83Zs= +github.com/ipfs/boxo v0.13.2-0.20231031170949-08b11e5df06e h1:+A0lJ8vc6YtiMiq3UodN0BgZJTso/VJDrECdyHpsFDY= +github.com/ipfs/boxo v0.13.2-0.20231031170949-08b11e5df06e/go.mod h1:pu8HsZvuyYeYJsqtLDCoYSvy8rHj6vI3dlh8P0f83Zs= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs= diff --git a/test/integration/addcat_test.go b/test/integration/addcat_test.go index 2974f51fb..222326de2 100644 --- a/test/integration/addcat_test.go +++ b/test/integration/addcat_test.go @@ -11,10 +11,10 @@ import ( "testing" "time" + "github.com/ipfs/boxo/bootstrap" "github.com/ipfs/boxo/files" logging "github.com/ipfs/go-log" "github.com/ipfs/kubo/core" - "github.com/ipfs/kubo/core/bootstrap" "github.com/ipfs/kubo/core/coreapi" mock "github.com/ipfs/kubo/core/mock" "github.com/ipfs/kubo/thirdparty/unit" diff --git a/test/integration/bench_cat_test.go b/test/integration/bench_cat_test.go index e95ff87df..d0c0a4b89 100644 --- a/test/integration/bench_cat_test.go +++ b/test/integration/bench_cat_test.go @@ -8,9 +8,9 @@ import ( "math" "testing" + "github.com/ipfs/boxo/bootstrap" "github.com/ipfs/boxo/files" "github.com/ipfs/kubo/core" - "github.com/ipfs/kubo/core/bootstrap" "github.com/ipfs/kubo/core/coreapi" mock "github.com/ipfs/kubo/core/mock" "github.com/ipfs/kubo/thirdparty/unit" diff --git a/test/integration/pubsub_msg_seen_cache_test.go b/test/integration/pubsub_msg_seen_cache_test.go index 4194881a5..85cc8ae9f 100644 --- a/test/integration/pubsub_msg_seen_cache_test.go +++ b/test/integration/pubsub_msg_seen_cache_test.go @@ -10,9 +10,9 @@ import ( "go.uber.org/fx" + "github.com/ipfs/boxo/bootstrap" "github.com/ipfs/kubo/config" "github.com/ipfs/kubo/core" - "github.com/ipfs/kubo/core/bootstrap" "github.com/ipfs/kubo/core/coreapi" libp2p2 "github.com/ipfs/kubo/core/node/libp2p" "github.com/ipfs/kubo/repo" diff --git a/test/integration/three_legged_cat_test.go b/test/integration/three_legged_cat_test.go index e8a838e1f..fa594f1e5 100644 --- a/test/integration/three_legged_cat_test.go +++ b/test/integration/three_legged_cat_test.go @@ -9,7 +9,7 @@ import ( "testing" "time" - bootstrap2 "github.com/ipfs/kubo/core/bootstrap" + bootstrap2 "github.com/ipfs/boxo/bootstrap" "github.com/ipfs/kubo/core/coreapi" mock "github.com/ipfs/kubo/core/mock" "github.com/ipfs/kubo/thirdparty/unit" From e068f1458ca7c548f41e894bcc30f4186bfb3ea5 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Wed, 1 Nov 2023 11:09:10 +0100 Subject: [PATCH 0917/1212] chore: bump to boxo 0.14.0 --- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- test/dependencies/go.mod | 2 +- test/dependencies/go.sum | 4 ++-- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 142f342f9..b2b90bf3b 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.20 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.13.2-0.20231031170949-08b11e5df06e + github.com/ipfs/boxo v0.14.0 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.31.0 github.com/multiformats/go-multiaddr v0.11.0 diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index b45088174..ba1c192a2 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -305,8 +305,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.13.2-0.20231031170949-08b11e5df06e h1:+A0lJ8vc6YtiMiq3UodN0BgZJTso/VJDrECdyHpsFDY= -github.com/ipfs/boxo v0.13.2-0.20231031170949-08b11e5df06e/go.mod h1:pu8HsZvuyYeYJsqtLDCoYSvy8rHj6vI3dlh8P0f83Zs= +github.com/ipfs/boxo v0.14.0 h1:gwSGW3xqUbtUOdn71oqBknpBFKpQm352g3I+RkebrX0= +github.com/ipfs/boxo v0.14.0/go.mod h1:pu8HsZvuyYeYJsqtLDCoYSvy8rHj6vI3dlh8P0f83Zs= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= diff --git a/go.mod b/go.mod index 50555089b..1acc57dae 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,7 @@ require ( github.com/hashicorp/go-multierror v1.1.1 github.com/ipfs-shipyard/nopfs v0.0.12-0.20231027223058-cde3b5ba964c github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c - github.com/ipfs/boxo v0.13.2-0.20231031170949-08b11e5df06e + github.com/ipfs/boxo v0.14.0 github.com/ipfs/go-block-format v0.2.0 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 diff --git a/go.sum b/go.sum index e83c67de2..69ae8aff6 100644 --- a/go.sum +++ b/go.sum @@ -339,8 +339,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.13.2-0.20231031170949-08b11e5df06e h1:+A0lJ8vc6YtiMiq3UodN0BgZJTso/VJDrECdyHpsFDY= -github.com/ipfs/boxo v0.13.2-0.20231031170949-08b11e5df06e/go.mod h1:pu8HsZvuyYeYJsqtLDCoYSvy8rHj6vI3dlh8P0f83Zs= +github.com/ipfs/boxo v0.14.0 h1:gwSGW3xqUbtUOdn71oqBknpBFKpQm352g3I+RkebrX0= +github.com/ipfs/boxo v0.14.0/go.mod h1:pu8HsZvuyYeYJsqtLDCoYSvy8rHj6vI3dlh8P0f83Zs= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 30f462704..7593700c5 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -7,7 +7,7 @@ replace github.com/ipfs/kubo => ../../ require ( github.com/Kubuxu/gocovmerge v0.0.0-20161216165753-7ecaa51963cd github.com/golangci/golangci-lint v1.54.1 - github.com/ipfs/boxo v0.13.2-0.20231031170949-08b11e5df06e + github.com/ipfs/boxo v0.14.0 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 github.com/ipfs/go-datastore v0.6.0 diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index c9708b27b..99ffc1795 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -398,8 +398,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.13.2-0.20231031170949-08b11e5df06e h1:+A0lJ8vc6YtiMiq3UodN0BgZJTso/VJDrECdyHpsFDY= -github.com/ipfs/boxo v0.13.2-0.20231031170949-08b11e5df06e/go.mod h1:pu8HsZvuyYeYJsqtLDCoYSvy8rHj6vI3dlh8P0f83Zs= +github.com/ipfs/boxo v0.14.0 h1:gwSGW3xqUbtUOdn71oqBknpBFKpQm352g3I+RkebrX0= +github.com/ipfs/boxo v0.14.0/go.mod h1:pu8HsZvuyYeYJsqtLDCoYSvy8rHj6vI3dlh8P0f83Zs= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs= From 385131165f477f579c7dcbe59fd9271b51c9f97f Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Wed, 1 Nov 2023 10:24:37 +0000 Subject: [PATCH 0918/1212] chore: update version --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index 2491eeffb..cb9d87a61 100644 --- a/version.go +++ b/version.go @@ -11,7 +11,7 @@ import ( var CurrentCommit string // CurrentVersionNumber is the current application's version literal. -const CurrentVersionNumber = "0.23.0" +const CurrentVersionNumber = "0.24.0-rc1" const ApiVersion = "/kubo/" + CurrentVersionNumber + "/" //nolint From 0f6f02cbea658a3436dc0e772aabb9e85c5fc554 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Wed, 1 Nov 2023 10:25:48 +0000 Subject: [PATCH 0919/1212] chore: update version --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index 2491eeffb..2799f0e85 100644 --- a/version.go +++ b/version.go @@ -11,7 +11,7 @@ import ( var CurrentCommit string // CurrentVersionNumber is the current application's version literal. -const CurrentVersionNumber = "0.23.0" +const CurrentVersionNumber = "0.25.0-dev" const ApiVersion = "/kubo/" + CurrentVersionNumber + "/" //nolint From e238a869adff1e96cefcdce9a706f67820b981f2 Mon Sep 17 00:00:00 2001 From: Steve Loeppky Date: Fri, 3 Nov 2023 08:03:07 +0100 Subject: [PATCH 0920/1212] docs: update EARLY_TESTERS.md (#10194) --- docs/EARLY_TESTERS.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/EARLY_TESTERS.md b/docs/EARLY_TESTERS.md index 635890676..6c5b09b15 100644 --- a/docs/EARLY_TESTERS.md +++ b/docs/EARLY_TESTERS.md @@ -26,11 +26,11 @@ We will ask early testers to participate at two points in the process: - [ ] Fission (@bmann) - [ ] Infura (@MichaelMure) - [ ] OrbitDB (@haydenyoung) -- [ ] pacman.store (@RubenKelevra) - [ ] Pinata (@obo20) -- [ ] PL EngRes bifrost (@gmasgras) +- [ ] PL EngRes bifrost (@cewood ns4plabs) - [ ] Siderus (@koalalorenzo) - [ ] Textile (@sanderpick) +- [ ] @RubenKelevra ## How to sign up? From f1fec717825c891242c0054078192618c14b797c Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Fri, 3 Nov 2023 08:17:00 +0100 Subject: [PATCH 0921/1212] chore: go-libp2p v0.32.0 --- docs/examples/kubo-as-a-library/go.mod | 46 ++++++------- docs/examples/kubo-as-a-library/go.sum | 95 +++++++++++++------------- go.mod | 46 ++++++------- go.sum | 95 +++++++++++++------------- test/dependencies/go.mod | 44 ++++++------ test/dependencies/go.sum | 90 ++++++++++++------------ 6 files changed, 207 insertions(+), 209 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index b2b90bf3b..da95b3f70 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,10 +7,10 @@ go 1.20 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.14.0 + github.com/ipfs/boxo v0.15.0 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 - github.com/libp2p/go-libp2p v0.31.0 - github.com/multiformats/go-multiaddr v0.11.0 + github.com/libp2p/go-libp2p v0.32.0 + github.com/multiformats/go-multiaddr v0.12.0 ) require ( @@ -47,11 +47,10 @@ require ( github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/godbus/dbus/v5 v5.1.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang/mock v1.6.0 // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/gopacket v1.1.19 // indirect - github.com/google/pprof v0.0.0-20230821062121-407c9e7a662f // indirect + github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b // indirect github.com/google/uuid v1.3.1 // indirect github.com/gorilla/websocket v1.5.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 // indirect @@ -60,7 +59,7 @@ require ( github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/golang-lru v0.5.4 // indirect github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect - github.com/huin/goupnp v1.2.0 // indirect + github.com/huin/goupnp v1.3.0 // indirect github.com/ipfs-shipyard/nopfs v0.0.12-0.20231027223058-cde3b5ba964c // indirect github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c // indirect github.com/ipfs/bbloom v0.0.4 // indirect @@ -74,7 +73,7 @@ require ( github.com/ipfs/go-ds-leveldb v0.5.0 // indirect github.com/ipfs/go-ds-measure v0.2.0 // indirect github.com/ipfs/go-fs-lock v0.0.7 // indirect - github.com/ipfs/go-graphsync v0.15.1 // indirect + github.com/ipfs/go-graphsync v0.16.0 // indirect github.com/ipfs/go-ipfs-blockstore v1.3.0 // indirect github.com/ipfs/go-ipfs-delay v0.0.1 // indirect github.com/ipfs/go-ipfs-ds-help v1.1.0 // indirect @@ -97,7 +96,7 @@ require ( github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect github.com/jbenet/goprocess v0.1.4 // indirect - github.com/klauspost/compress v1.16.7 // indirect + github.com/klauspost/compress v1.17.2 // indirect github.com/klauspost/cpuid/v2 v2.2.5 // indirect github.com/koron/go-ssdp v0.0.4 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect @@ -107,7 +106,7 @@ require ( github.com/libp2p/go-libp2p-asn-util v0.3.0 // indirect github.com/libp2p/go-libp2p-kad-dht v0.24.4 // indirect github.com/libp2p/go-libp2p-kbucket v0.6.3 // indirect - github.com/libp2p/go-libp2p-pubsub v0.9.3 // indirect + github.com/libp2p/go-libp2p-pubsub v0.10.0 // indirect github.com/libp2p/go-libp2p-pubsub-router v0.6.0 // indirect github.com/libp2p/go-libp2p-record v0.2.0 // indirect github.com/libp2p/go-libp2p-routing-helpers v0.7.3 // indirect @@ -120,9 +119,9 @@ require ( github.com/libp2p/go-yamux/v4 v4.0.1 // indirect github.com/libp2p/zeroconf/v2 v2.2.0 // indirect github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect - github.com/mattn/go-isatty v0.0.19 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect - github.com/miekg/dns v1.1.55 // indirect + github.com/miekg/dns v1.1.56 // indirect github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect github.com/minio/sha256-simd v1.0.1 // indirect @@ -135,9 +134,9 @@ require ( github.com/multiformats/go-multibase v0.2.0 // indirect github.com/multiformats/go-multicodec v0.9.0 // indirect github.com/multiformats/go-multihash v0.2.3 // indirect - github.com/multiformats/go-multistream v0.4.1 // indirect + github.com/multiformats/go-multistream v0.5.0 // indirect github.com/multiformats/go-varint v0.0.7 // indirect - github.com/onsi/ginkgo/v2 v2.11.0 // indirect + github.com/onsi/ginkgo/v2 v2.13.0 // indirect github.com/opencontainers/runtime-spec v1.1.0 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/openzipkin/zipkin-go v0.4.1 // indirect @@ -150,9 +149,9 @@ require ( github.com/prometheus/common v0.44.0 // indirect github.com/prometheus/procfs v0.12.0 // indirect github.com/quic-go/qpack v0.4.0 // indirect - github.com/quic-go/qtls-go1-20 v0.3.3 // indirect - github.com/quic-go/quic-go v0.38.1 // indirect - github.com/quic-go/webtransport-go v0.5.3 // indirect + github.com/quic-go/qtls-go1-20 v0.3.4 // indirect + github.com/quic-go/quic-go v0.39.3 // indirect + github.com/quic-go/webtransport-go v0.6.0 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/samber/lo v1.36.0 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect @@ -178,19 +177,20 @@ require ( go.opentelemetry.io/otel/trace v1.17.0 // indirect go.opentelemetry.io/proto/otlp v0.19.0 // indirect go.uber.org/atomic v1.11.0 // indirect - go.uber.org/dig v1.17.0 // indirect - go.uber.org/fx v1.20.0 // indirect + go.uber.org/dig v1.17.1 // indirect + go.uber.org/fx v1.20.1 // indirect + go.uber.org/mock v0.3.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.26.0 // indirect go4.org v0.0.0-20230225012048-214862532bf5 // indirect golang.org/x/crypto v0.14.0 // indirect - golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect - golang.org/x/mod v0.12.0 // indirect - golang.org/x/net v0.15.0 // indirect - golang.org/x/sync v0.3.0 // indirect + golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect + golang.org/x/mod v0.13.0 // indirect + golang.org/x/net v0.17.0 // indirect + golang.org/x/sync v0.4.0 // indirect golang.org/x/sys v0.13.0 // indirect golang.org/x/text v0.13.0 // indirect - golang.org/x/tools v0.13.0 // indirect + golang.org/x/tools v0.14.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect gonum.org/v1/gonum v0.13.0 // indirect google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index ba1c192a2..42bb1aa30 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -206,8 +206,6 @@ github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= -github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= -github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -257,8 +255,8 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20230821062121-407c9e7a662f h1:pDhu5sgp8yJlEF/g6osliIIpF9K4F5jvkULXa4daRDQ= -github.com/google/pprof v0.0.0-20230821062121-407c9e7a662f/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= +github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b h1:RMpPgZTSApbPf7xaVel+QkoGPRLFLrwFO89uDUHEGf0= +github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -295,8 +293,8 @@ github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/huin/goupnp v1.2.0 h1:uOKW26NG1hsSSbXIZ1IR7XP9Gjd1U8pnLaCMgntmkmY= -github.com/huin/goupnp v1.2.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= +github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= +github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs-shipyard/nopfs v0.0.12-0.20231027223058-cde3b5ba964c h1:17FO7HnKiFhO7iadu3zCgII+EblpdRmJt5qg9FqQo8Y= @@ -305,8 +303,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.14.0 h1:gwSGW3xqUbtUOdn71oqBknpBFKpQm352g3I+RkebrX0= -github.com/ipfs/boxo v0.14.0/go.mod h1:pu8HsZvuyYeYJsqtLDCoYSvy8rHj6vI3dlh8P0f83Zs= +github.com/ipfs/boxo v0.15.0 h1:BriLydj2nlK1nKeJQHxcKSuG5ZXcoutzhBklOtxC5pk= +github.com/ipfs/boxo v0.15.0/go.mod h1:X5ulcbR5Nh7sm3Db8+08AApUo6FsGC5mb23QDKAoB/M= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= @@ -343,8 +341,8 @@ github.com/ipfs/go-ds-measure v0.2.0 h1:sG4goQe0KDTccHMyT45CY1XyUbxe5VwTKpg2LjAp github.com/ipfs/go-ds-measure v0.2.0/go.mod h1:SEUD/rE2PwRa4IQEC5FuNAmjJCyYObZr9UvVh8V3JxE= github.com/ipfs/go-fs-lock v0.0.7 h1:6BR3dajORFrFTkb5EpCUFIAypsoxpGpDSVUdFwzgL9U= github.com/ipfs/go-fs-lock v0.0.7/go.mod h1:Js8ka+FNYmgQRLrRXzU3CB/+Csr1BwrRilEcvYrHhhc= -github.com/ipfs/go-graphsync v0.15.1 h1:7v4VfRQ/8pKzPuE0wHeMaWhKu8D/RlezIrzvGWIBtHQ= -github.com/ipfs/go-graphsync v0.15.1/go.mod h1:eUIYS0OKkdBbG4vHhfGkY3lZ7h1G5Dlwd+HxTCe18vA= +github.com/ipfs/go-graphsync v0.16.0 h1:0BX7whXlV13Y9FZ/jRg+xaGHaGYbtGxGppKD6tncw6k= +github.com/ipfs/go-graphsync v0.16.0/go.mod h1:WfbMW3hhmX5GQEQ+KJxsFzVJVBKgC5szfrYK7Zc7xIM= github.com/ipfs/go-ipfs-blockstore v1.3.0 h1:m2EXaWgwTzAfsmt5UdJ7Is6l4gJcaM/A12XwJyvYvMM= github.com/ipfs/go-ipfs-blockstore v1.3.0/go.mod h1:KgtZyc9fq+P2xJUiCAzbRdhhqJHvsw8u2Dlqy2MyRTE= github.com/ipfs/go-ipfs-blocksutil v0.0.1 h1:Eh/H4pc1hsvhzsQoMEP3Bke/aW5P5rVM1IWFJMcGIPQ= @@ -432,8 +430,8 @@ github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQL 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.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I= -github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/compress v1.17.2 h1:RlWWUY/Dr4fL8qk9YG7DTZ7PDgME2V4csBXA8L/ixi4= +github.com/klauspost/compress v1.17.2/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= @@ -463,8 +461,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.31.0 h1:LFShhP8F6xthWiBBq3euxbKjZsoRajVEyBS9snfHxYg= -github.com/libp2p/go-libp2p v0.31.0/go.mod h1:W/FEK1c/t04PbRH3fA9i5oucu5YcgrG0JVoBWT1B7Eg= +github.com/libp2p/go-libp2p v0.32.0 h1:86I4B7nBUPIyTgw3+5Ibq6K7DdKRCuZw8URCfPc1hQM= +github.com/libp2p/go-libp2p v0.32.0/go.mod h1:hXXC3kXPlBZ1eu8Q2hptGrMB4mZ3048JUoS4EKaHW5c= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= @@ -475,8 +473,8 @@ github.com/libp2p/go-libp2p-kbucket v0.3.1/go.mod h1:oyjT5O7tS9CQurok++ERgc46YLw github.com/libp2p/go-libp2p-kbucket v0.6.3 h1:p507271wWzpy2f1XxPzCQG9NiN6R6lHL9GiSErbQQo0= github.com/libp2p/go-libp2p-kbucket v0.6.3/go.mod h1:RCseT7AH6eJWxxk2ol03xtP9pEHetYSPXOaJnOiD8i0= github.com/libp2p/go-libp2p-peerstore v0.1.4/go.mod h1:+4BDbDiiKf4PzpANZDAT+knVdLxvqh7hXOujessqdzs= -github.com/libp2p/go-libp2p-pubsub v0.9.3 h1:ihcz9oIBMaCK9kcx+yHWm3mLAFBMAUsM4ux42aikDxo= -github.com/libp2p/go-libp2p-pubsub v0.9.3/go.mod h1:RYA7aM9jIic5VV47WXu4GkcRxRhrdElWf8xtyli+Dzc= +github.com/libp2p/go-libp2p-pubsub v0.10.0 h1:wS0S5FlISavMaAbxyQn3dxMOe2eegMfswM471RuHJwA= +github.com/libp2p/go-libp2p-pubsub v0.10.0/go.mod h1:1OxbaT/pFRO5h+Dpze8hdHQ63R0ke55XTs6b6NwLLkw= github.com/libp2p/go-libp2p-pubsub-router v0.6.0 h1:D30iKdlqDt5ZmLEYhHELCMRj8b4sFAqrUcshIUvVP/s= github.com/libp2p/go-libp2p-pubsub-router v0.6.0/go.mod h1:FY/q0/RBTKsLA7l4vqC2cbRbOvyDotg8PJQ7j8FDudE= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= @@ -515,8 +513,8 @@ 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.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= -github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= @@ -524,8 +522,8 @@ github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyex github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= -github.com/miekg/dns v1.1.55 h1:GoQ4hpsj0nFLYe+bWiCToyrBEJXkQfOOIvFGFy0lEgo= -github.com/miekg/dns v1.1.55/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= +github.com/miekg/dns v1.1.56 h1:5imZaSeoRNvpM9SzWNhEcP9QliKiz20/dA2QabIGVnE= +github.com/miekg/dns v1.1.56/go.mod h1:cRm6Oo2C8TY9ZS/TqsSrseAcncm74lfK5G+ikN2SWWY= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c h1:bzE/A84HN25pxAuk9Eej1Kz9OUelF97nAc82bDquQI8= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c/go.mod h1:0SQS9kMwD2VsyFEB++InYyBJroV/FRmBgcydeSUcJms= github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= @@ -558,8 +556,8 @@ github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a github.com/multiformats/go-multiaddr v0.1.0/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo= github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4= -github.com/multiformats/go-multiaddr v0.11.0 h1:XqGyJ8ufbCE0HmTDwx2kPdsrQ36AGPZNZX6s6xfJH10= -github.com/multiformats/go-multiaddr v0.11.0/go.mod h1:gWUm0QLR4thQ6+ZF6SXUw8YjtwQSPapICM+NmCkxHSM= +github.com/multiformats/go-multiaddr v0.12.0 h1:1QlibTFkoXJuDjjYsMHhE73TnzJQl8FSWatk/0gxGzE= +github.com/multiformats/go-multiaddr v0.12.0/go.mod h1:WmZXgObOQOYp9r3cslLlppkrz1FYSHmE834dfz/lWu8= github.com/multiformats/go-multiaddr-dns v0.3.0/go.mod h1:mNzQ4eTGDg0ll1N9jKPOUogZPoJ30W8a7zk66FQPpdQ= github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A= github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk= @@ -582,8 +580,8 @@ github.com/multiformats/go-multihash v0.0.15/go.mod h1:D6aZrWNLFTV/ynMpKsNtB40mJ github.com/multiformats/go-multihash v0.1.0/go.mod h1:RJlXsxt6vHGaia+S8We0ErjhojtKzPP2AH4+kYM7k84= github.com/multiformats/go-multihash v0.2.3 h1:7Lyc8XfX/IY2jWb/gI7JP+o7JEq9hOa7BFvVU9RSh+U= github.com/multiformats/go-multihash v0.2.3/go.mod h1:dXgKXCXjBzdscBLk9JkjINiEsCKRVch90MdaGiKsvSM= -github.com/multiformats/go-multistream v0.4.1 h1:rFy0Iiyn3YT0asivDUIR05leAdwZq3de4741sbiSdfo= -github.com/multiformats/go-multistream v0.4.1/go.mod h1:Mz5eykRVAjJWckE2U78c6xqdtyNUEhKSM0Lwar2p77Q= +github.com/multiformats/go-multistream v0.5.0 h1:5htLSLl7lvJk3xx3qT/8Zm9J4K8vEOf/QGkvOGQAyiE= +github.com/multiformats/go-multistream v0.5.0/go.mod h1:n6tMZiwiP2wUsR8DgfDWw1dydlEqV3l6N3/GBsX6ILA= github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/multiformats/go-varint v0.0.6/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= @@ -598,12 +596,12 @@ github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= -github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU= -github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM= +github.com/onsi/ginkgo/v2 v2.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4= +github.com/onsi/ginkgo/v2 v2.13.0/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.27.8 h1:gegWiwZjBsf2DgiSbf5hpokZ98JVDMcWkUiigk6/KXc= +github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.1.0 h1:HHUyrt9mwHUjtasSbXSMvs4cyFxh+Bll4AjJ9odEGpg= github.com/opencontainers/runtime-spec v1.1.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= @@ -643,12 +641,12 @@ github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= -github.com/quic-go/qtls-go1-20 v0.3.3 h1:17/glZSLI9P9fDAeyCHBFSWSqJcwx1byhLwP5eUIDCM= -github.com/quic-go/qtls-go1-20 v0.3.3/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= -github.com/quic-go/quic-go v0.38.1 h1:M36YWA5dEhEeT+slOu/SwMEucbYd0YFidxG3KlGPZaE= -github.com/quic-go/quic-go v0.38.1/go.mod h1:ijnZM7JsFIkp4cRyjxJNIzdSfCLmUMg9wdyhGmg+SN4= -github.com/quic-go/webtransport-go v0.5.3 h1:5XMlzemqB4qmOlgIus5zB45AcZ2kCgCy2EptUrfOPWU= -github.com/quic-go/webtransport-go v0.5.3/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= +github.com/quic-go/qtls-go1-20 v0.3.4 h1:MfFAPULvst4yoMgY9QmtpYmfij/em7O8UUi+bNVm7Cg= +github.com/quic-go/qtls-go1-20 v0.3.4/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= +github.com/quic-go/quic-go v0.39.3 h1:o3YB6t2SR+HU/pgwF29kJ6g4jJIJEwEZ8CKia1h1TKg= +github.com/quic-go/quic-go v0.39.3/go.mod h1:T09QsDQWjLiQ74ZmacDfqZmhY/NLnw5BC40MANNNZ1Q= +github.com/quic-go/webtransport-go v0.6.0 h1:CvNsKqc4W2HljHJnoT+rMmbRJybShZ0YPFDD3NxaZLY= +github.com/quic-go/webtransport-go v0.6.0/go.mod h1:9KjU4AEBqEQidGHNDkZrb8CAa1abRaosM2yGOyiikEc= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= @@ -806,12 +804,14 @@ go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/dig v1.17.0 h1:5Chju+tUvcC+N7N6EV08BJz41UZuO3BmHcN4A287ZLI= -go.uber.org/dig v1.17.0/go.mod h1:rTxpf7l5I0eBTlE6/9RL+lDybC7WFwY2QH55ZSjy1mU= -go.uber.org/fx v1.20.0 h1:ZMC/pnRvhsthOZh9MZjMq5U8Or3mA9zBSPaLnzs3ihQ= -go.uber.org/fx v1.20.0/go.mod h1:qCUj0btiR3/JnanEr1TYEePfSw6o/4qYJscgvzQ5Ub0= +go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= +go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= +go.uber.org/fx v1.20.1 h1:zVwVQGS8zYvhh9Xxcu4w1M6ESyeMzebzj2NbSayZ4Mk= +go.uber.org/fx v1.20.1/go.mod h1:iSYNbHf2y55acNCwCXKx7LbWb5WG1Bnue5RDXz1OREg= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= +go.uber.org/mock v0.3.0 h1:3mUxI1No2/60yUYax92Pt8eNOEecx2D3lcXZh2NEZJo= +go.uber.org/mock v0.3.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= @@ -857,8 +857,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g= -golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= +golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI= +golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -882,8 +882,8 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= -golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY= +golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -926,8 +926,8 @@ golang.org/x/net v0.0.0-20210423184538-5f58ad60dda6/go.mod h1:OJAsFXCWl8Ukc7SiCT golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8= -golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= +golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -948,8 +948,8 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= -golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ= +golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/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= @@ -1080,11 +1080,10 @@ golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ= -golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= +golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc= +golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/go.mod b/go.mod index 1acc57dae..b8fe887d0 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,7 @@ require ( github.com/hashicorp/go-multierror v1.1.1 github.com/ipfs-shipyard/nopfs v0.0.12-0.20231027223058-cde3b5ba964c github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c - github.com/ipfs/boxo v0.14.0 + github.com/ipfs/boxo v0.15.0 github.com/ipfs/go-block-format v0.2.0 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 @@ -28,7 +28,7 @@ require ( github.com/ipfs/go-ds-leveldb v0.5.0 github.com/ipfs/go-ds-measure v0.2.0 github.com/ipfs/go-fs-lock v0.0.7 - github.com/ipfs/go-graphsync v0.15.1 + github.com/ipfs/go-graphsync v0.16.0 github.com/ipfs/go-ipfs-cmds v0.10.0 github.com/ipfs/go-ipld-format v0.6.0 github.com/ipfs/go-ipld-git v0.1.1 @@ -47,11 +47,11 @@ require ( github.com/jbenet/goprocess v0.1.4 github.com/julienschmidt/httprouter v1.3.0 github.com/libp2p/go-doh-resolver v0.4.0 - github.com/libp2p/go-libp2p v0.31.0 + github.com/libp2p/go-libp2p v0.32.0 github.com/libp2p/go-libp2p-http v0.5.0 github.com/libp2p/go-libp2p-kad-dht v0.24.4 github.com/libp2p/go-libp2p-kbucket v0.6.3 - github.com/libp2p/go-libp2p-pubsub v0.9.3 + github.com/libp2p/go-libp2p-pubsub v0.10.0 github.com/libp2p/go-libp2p-pubsub-router v0.6.0 github.com/libp2p/go-libp2p-record v0.2.0 github.com/libp2p/go-libp2p-routing-helpers v0.7.3 @@ -59,7 +59,7 @@ require ( github.com/libp2p/go-mplex v0.7.0 github.com/libp2p/go-socket-activation v0.1.0 github.com/mitchellh/go-homedir v1.1.0 - github.com/multiformats/go-multiaddr v0.11.0 + github.com/multiformats/go-multiaddr v0.12.0 github.com/multiformats/go-multiaddr-dns v0.3.1 github.com/multiformats/go-multibase v0.2.0 github.com/multiformats/go-multicodec v0.9.0 @@ -80,14 +80,14 @@ require ( go.opentelemetry.io/otel v1.17.0 go.opentelemetry.io/otel/sdk v1.16.0 go.opentelemetry.io/otel/trace v1.17.0 - go.uber.org/dig v1.17.0 - go.uber.org/fx v1.20.0 + go.uber.org/dig v1.17.1 + go.uber.org/fx v1.20.1 go.uber.org/multierr v1.11.0 go.uber.org/zap v1.26.0 golang.org/x/crypto v0.14.0 - golang.org/x/exp v0.0.0-20230905200255-921286631fa9 - golang.org/x/mod v0.12.0 - golang.org/x/sync v0.3.0 + golang.org/x/exp v0.0.0-20231006140011-7918f672742d + golang.org/x/mod v0.13.0 + golang.org/x/sync v0.4.0 golang.org/x/sys v0.13.0 google.golang.org/protobuf v1.31.0 ) @@ -122,11 +122,10 @@ require ( github.com/godbus/dbus/v5 v5.1.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/golang/mock v1.6.0 // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/gopacket v1.1.19 // indirect - github.com/google/pprof v0.0.0-20230821062121-407c9e7a662f // indirect + github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b // indirect github.com/gorilla/mux v1.8.0 // indirect github.com/gorilla/websocket v1.5.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 // indirect @@ -134,7 +133,7 @@ require ( github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/golang-lru v0.5.4 // indirect github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect - github.com/huin/goupnp v1.2.0 // indirect + github.com/huin/goupnp v1.3.0 // indirect github.com/ipfs/bbloom v0.0.4 // indirect github.com/ipfs/go-bitfield v1.1.0 // indirect github.com/ipfs/go-blockservice v0.5.0 // indirect @@ -151,7 +150,7 @@ require ( github.com/ipfs/go-peertaskqueue v0.8.1 // indirect github.com/ipfs/go-verifcid v0.0.2 // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect - github.com/klauspost/compress v1.16.7 // indirect + github.com/klauspost/compress v1.17.2 // indirect github.com/klauspost/cpuid/v2 v2.2.5 // indirect github.com/koron/go-ssdp v0.0.4 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect @@ -168,11 +167,11 @@ require ( github.com/libp2p/zeroconf/v2 v2.2.0 // indirect github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect github.com/mattn/go-colorable v0.1.6 // indirect - github.com/mattn/go-isatty v0.0.19 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-runewidth v0.0.4 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect - github.com/miekg/dns v1.1.55 // indirect + github.com/miekg/dns v1.1.56 // indirect github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect github.com/minio/sha256-simd v1.0.1 // indirect @@ -180,9 +179,9 @@ require ( github.com/multiformats/go-base32 v0.1.0 // indirect github.com/multiformats/go-base36 v0.2.0 // indirect github.com/multiformats/go-multiaddr-fmt v0.1.0 // indirect - github.com/multiformats/go-multistream v0.4.1 // indirect + github.com/multiformats/go-multistream v0.5.0 // indirect github.com/multiformats/go-varint v0.0.7 // indirect - github.com/onsi/ginkgo/v2 v2.11.0 // indirect + github.com/onsi/ginkgo/v2 v2.13.0 // indirect github.com/opencontainers/runtime-spec v1.1.0 // indirect github.com/openzipkin/zipkin-go v0.4.1 // indirect github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 // indirect @@ -193,9 +192,9 @@ require ( github.com/prometheus/procfs v0.12.0 // indirect github.com/prometheus/statsd_exporter v0.22.7 // indirect github.com/quic-go/qpack v0.4.0 // indirect - github.com/quic-go/qtls-go1-20 v0.3.3 // indirect - github.com/quic-go/quic-go v0.38.1 // indirect - github.com/quic-go/webtransport-go v0.5.3 // indirect + github.com/quic-go/qtls-go1-20 v0.3.4 // indirect + github.com/quic-go/quic-go v0.39.3 // indirect + github.com/quic-go/webtransport-go v0.6.0 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/rs/cors v1.7.0 // indirect github.com/samber/lo v1.36.0 // indirect @@ -223,12 +222,13 @@ require ( go.opentelemetry.io/otel/metric v1.17.0 // indirect go.opentelemetry.io/proto/otlp v0.19.0 // indirect go.uber.org/atomic v1.11.0 // indirect + go.uber.org/mock v0.3.0 // indirect go4.org v0.0.0-20230225012048-214862532bf5 // indirect - golang.org/x/net v0.15.0 // indirect + golang.org/x/net v0.17.0 // indirect golang.org/x/oauth2 v0.8.0 // indirect golang.org/x/term v0.13.0 // indirect golang.org/x/text v0.13.0 // indirect - golang.org/x/tools v0.13.0 // indirect + golang.org/x/tools v0.14.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect gonum.org/v1/gonum v0.13.0 // indirect google.golang.org/appengine v1.6.7 // indirect diff --git a/go.sum b/go.sum index 69ae8aff6..c07381487 100644 --- a/go.sum +++ b/go.sum @@ -237,8 +237,6 @@ github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= -github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= -github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -290,8 +288,8 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20230821062121-407c9e7a662f h1:pDhu5sgp8yJlEF/g6osliIIpF9K4F5jvkULXa4daRDQ= -github.com/google/pprof v0.0.0-20230821062121-407c9e7a662f/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= +github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b h1:RMpPgZTSApbPf7xaVel+QkoGPRLFLrwFO89uDUHEGf0= +github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -329,8 +327,8 @@ github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/huin/goupnp v1.2.0 h1:uOKW26NG1hsSSbXIZ1IR7XP9Gjd1U8pnLaCMgntmkmY= -github.com/huin/goupnp v1.2.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= +github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= +github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs-shipyard/nopfs v0.0.12-0.20231027223058-cde3b5ba964c h1:17FO7HnKiFhO7iadu3zCgII+EblpdRmJt5qg9FqQo8Y= @@ -339,8 +337,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.14.0 h1:gwSGW3xqUbtUOdn71oqBknpBFKpQm352g3I+RkebrX0= -github.com/ipfs/boxo v0.14.0/go.mod h1:pu8HsZvuyYeYJsqtLDCoYSvy8rHj6vI3dlh8P0f83Zs= +github.com/ipfs/boxo v0.15.0 h1:BriLydj2nlK1nKeJQHxcKSuG5ZXcoutzhBklOtxC5pk= +github.com/ipfs/boxo v0.15.0/go.mod h1:X5ulcbR5Nh7sm3Db8+08AApUo6FsGC5mb23QDKAoB/M= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= @@ -379,8 +377,8 @@ github.com/ipfs/go-ds-measure v0.2.0 h1:sG4goQe0KDTccHMyT45CY1XyUbxe5VwTKpg2LjAp github.com/ipfs/go-ds-measure v0.2.0/go.mod h1:SEUD/rE2PwRa4IQEC5FuNAmjJCyYObZr9UvVh8V3JxE= github.com/ipfs/go-fs-lock v0.0.7 h1:6BR3dajORFrFTkb5EpCUFIAypsoxpGpDSVUdFwzgL9U= github.com/ipfs/go-fs-lock v0.0.7/go.mod h1:Js8ka+FNYmgQRLrRXzU3CB/+Csr1BwrRilEcvYrHhhc= -github.com/ipfs/go-graphsync v0.15.1 h1:7v4VfRQ/8pKzPuE0wHeMaWhKu8D/RlezIrzvGWIBtHQ= -github.com/ipfs/go-graphsync v0.15.1/go.mod h1:eUIYS0OKkdBbG4vHhfGkY3lZ7h1G5Dlwd+HxTCe18vA= +github.com/ipfs/go-graphsync v0.16.0 h1:0BX7whXlV13Y9FZ/jRg+xaGHaGYbtGxGppKD6tncw6k= +github.com/ipfs/go-graphsync v0.16.0/go.mod h1:WfbMW3hhmX5GQEQ+KJxsFzVJVBKgC5szfrYK7Zc7xIM= github.com/ipfs/go-ipfs-blockstore v1.3.0 h1:m2EXaWgwTzAfsmt5UdJ7Is6l4gJcaM/A12XwJyvYvMM= github.com/ipfs/go-ipfs-blockstore v1.3.0/go.mod h1:KgtZyc9fq+P2xJUiCAzbRdhhqJHvsw8u2Dlqy2MyRTE= github.com/ipfs/go-ipfs-blocksutil v0.0.1 h1:Eh/H4pc1hsvhzsQoMEP3Bke/aW5P5rVM1IWFJMcGIPQ= @@ -486,8 +484,8 @@ github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQL 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.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I= -github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/compress v1.17.2 h1:RlWWUY/Dr4fL8qk9YG7DTZ7PDgME2V4csBXA8L/ixi4= +github.com/klauspost/compress v1.17.2/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= @@ -519,8 +517,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.31.0 h1:LFShhP8F6xthWiBBq3euxbKjZsoRajVEyBS9snfHxYg= -github.com/libp2p/go-libp2p v0.31.0/go.mod h1:W/FEK1c/t04PbRH3fA9i5oucu5YcgrG0JVoBWT1B7Eg= +github.com/libp2p/go-libp2p v0.32.0 h1:86I4B7nBUPIyTgw3+5Ibq6K7DdKRCuZw8URCfPc1hQM= +github.com/libp2p/go-libp2p v0.32.0/go.mod h1:hXXC3kXPlBZ1eu8Q2hptGrMB4mZ3048JUoS4EKaHW5c= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= @@ -535,8 +533,8 @@ github.com/libp2p/go-libp2p-kbucket v0.3.1/go.mod h1:oyjT5O7tS9CQurok++ERgc46YLw github.com/libp2p/go-libp2p-kbucket v0.6.3 h1:p507271wWzpy2f1XxPzCQG9NiN6R6lHL9GiSErbQQo0= github.com/libp2p/go-libp2p-kbucket v0.6.3/go.mod h1:RCseT7AH6eJWxxk2ol03xtP9pEHetYSPXOaJnOiD8i0= github.com/libp2p/go-libp2p-peerstore v0.1.4/go.mod h1:+4BDbDiiKf4PzpANZDAT+knVdLxvqh7hXOujessqdzs= -github.com/libp2p/go-libp2p-pubsub v0.9.3 h1:ihcz9oIBMaCK9kcx+yHWm3mLAFBMAUsM4ux42aikDxo= -github.com/libp2p/go-libp2p-pubsub v0.9.3/go.mod h1:RYA7aM9jIic5VV47WXu4GkcRxRhrdElWf8xtyli+Dzc= +github.com/libp2p/go-libp2p-pubsub v0.10.0 h1:wS0S5FlISavMaAbxyQn3dxMOe2eegMfswM471RuHJwA= +github.com/libp2p/go-libp2p-pubsub v0.10.0/go.mod h1:1OxbaT/pFRO5h+Dpze8hdHQ63R0ke55XTs6b6NwLLkw= github.com/libp2p/go-libp2p-pubsub-router v0.6.0 h1:D30iKdlqDt5ZmLEYhHELCMRj8b4sFAqrUcshIUvVP/s= github.com/libp2p/go-libp2p-pubsub-router v0.6.0/go.mod h1:FY/q0/RBTKsLA7l4vqC2cbRbOvyDotg8PJQ7j8FDudE= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= @@ -584,8 +582,8 @@ github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOA github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= -github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= 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= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= @@ -596,8 +594,8 @@ github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyex github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= -github.com/miekg/dns v1.1.55 h1:GoQ4hpsj0nFLYe+bWiCToyrBEJXkQfOOIvFGFy0lEgo= -github.com/miekg/dns v1.1.55/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= +github.com/miekg/dns v1.1.56 h1:5imZaSeoRNvpM9SzWNhEcP9QliKiz20/dA2QabIGVnE= +github.com/miekg/dns v1.1.56/go.mod h1:cRm6Oo2C8TY9ZS/TqsSrseAcncm74lfK5G+ikN2SWWY= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c h1:bzE/A84HN25pxAuk9Eej1Kz9OUelF97nAc82bDquQI8= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c/go.mod h1:0SQS9kMwD2VsyFEB++InYyBJroV/FRmBgcydeSUcJms= github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= @@ -634,8 +632,8 @@ github.com/multiformats/go-multiaddr v0.1.0/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lg github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo= github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4= github.com/multiformats/go-multiaddr v0.4.0/go.mod h1:YcpyLH8ZPudLxQlemYBPhSm0/oCXAT8Z4mzFpyoPyRc= -github.com/multiformats/go-multiaddr v0.11.0 h1:XqGyJ8ufbCE0HmTDwx2kPdsrQ36AGPZNZX6s6xfJH10= -github.com/multiformats/go-multiaddr v0.11.0/go.mod h1:gWUm0QLR4thQ6+ZF6SXUw8YjtwQSPapICM+NmCkxHSM= +github.com/multiformats/go-multiaddr v0.12.0 h1:1QlibTFkoXJuDjjYsMHhE73TnzJQl8FSWatk/0gxGzE= +github.com/multiformats/go-multiaddr v0.12.0/go.mod h1:WmZXgObOQOYp9r3cslLlppkrz1FYSHmE834dfz/lWu8= github.com/multiformats/go-multiaddr-dns v0.3.0/go.mod h1:mNzQ4eTGDg0ll1N9jKPOUogZPoJ30W8a7zk66FQPpdQ= github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A= github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk= @@ -658,8 +656,8 @@ github.com/multiformats/go-multihash v0.0.15/go.mod h1:D6aZrWNLFTV/ynMpKsNtB40mJ github.com/multiformats/go-multihash v0.1.0/go.mod h1:RJlXsxt6vHGaia+S8We0ErjhojtKzPP2AH4+kYM7k84= github.com/multiformats/go-multihash v0.2.3 h1:7Lyc8XfX/IY2jWb/gI7JP+o7JEq9hOa7BFvVU9RSh+U= github.com/multiformats/go-multihash v0.2.3/go.mod h1:dXgKXCXjBzdscBLk9JkjINiEsCKRVch90MdaGiKsvSM= -github.com/multiformats/go-multistream v0.4.1 h1:rFy0Iiyn3YT0asivDUIR05leAdwZq3de4741sbiSdfo= -github.com/multiformats/go-multistream v0.4.1/go.mod h1:Mz5eykRVAjJWckE2U78c6xqdtyNUEhKSM0Lwar2p77Q= +github.com/multiformats/go-multistream v0.5.0 h1:5htLSLl7lvJk3xx3qT/8Zm9J4K8vEOf/QGkvOGQAyiE= +github.com/multiformats/go-multistream v0.5.0/go.mod h1:n6tMZiwiP2wUsR8DgfDWw1dydlEqV3l6N3/GBsX6ILA= github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/multiformats/go-varint v0.0.6/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= @@ -676,12 +674,12 @@ github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= -github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU= -github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM= +github.com/onsi/ginkgo/v2 v2.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4= +github.com/onsi/ginkgo/v2 v2.13.0/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.27.8 h1:gegWiwZjBsf2DgiSbf5hpokZ98JVDMcWkUiigk6/KXc= +github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.1.0 h1:HHUyrt9mwHUjtasSbXSMvs4cyFxh+Bll4AjJ9odEGpg= github.com/opencontainers/runtime-spec v1.1.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= @@ -748,12 +746,12 @@ github.com/prometheus/statsd_exporter v0.22.7 h1:7Pji/i2GuhK6Lu7DHrtTkFmNBCudCPT github.com/prometheus/statsd_exporter v0.22.7/go.mod h1:N/TevpjkIh9ccs6nuzY3jQn9dFqnUakOjnEuMPJJJnI= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= -github.com/quic-go/qtls-go1-20 v0.3.3 h1:17/glZSLI9P9fDAeyCHBFSWSqJcwx1byhLwP5eUIDCM= -github.com/quic-go/qtls-go1-20 v0.3.3/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= -github.com/quic-go/quic-go v0.38.1 h1:M36YWA5dEhEeT+slOu/SwMEucbYd0YFidxG3KlGPZaE= -github.com/quic-go/quic-go v0.38.1/go.mod h1:ijnZM7JsFIkp4cRyjxJNIzdSfCLmUMg9wdyhGmg+SN4= -github.com/quic-go/webtransport-go v0.5.3 h1:5XMlzemqB4qmOlgIus5zB45AcZ2kCgCy2EptUrfOPWU= -github.com/quic-go/webtransport-go v0.5.3/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= +github.com/quic-go/qtls-go1-20 v0.3.4 h1:MfFAPULvst4yoMgY9QmtpYmfij/em7O8UUi+bNVm7Cg= +github.com/quic-go/qtls-go1-20 v0.3.4/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= +github.com/quic-go/quic-go v0.39.3 h1:o3YB6t2SR+HU/pgwF29kJ6g4jJIJEwEZ8CKia1h1TKg= +github.com/quic-go/quic-go v0.39.3/go.mod h1:T09QsDQWjLiQ74ZmacDfqZmhY/NLnw5BC40MANNNZ1Q= +github.com/quic-go/webtransport-go v0.6.0 h1:CvNsKqc4W2HljHJnoT+rMmbRJybShZ0YPFDD3NxaZLY= +github.com/quic-go/webtransport-go v0.6.0/go.mod h1:9KjU4AEBqEQidGHNDkZrb8CAa1abRaosM2yGOyiikEc= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= @@ -943,12 +941,14 @@ go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/dig v1.17.0 h1:5Chju+tUvcC+N7N6EV08BJz41UZuO3BmHcN4A287ZLI= -go.uber.org/dig v1.17.0/go.mod h1:rTxpf7l5I0eBTlE6/9RL+lDybC7WFwY2QH55ZSjy1mU= -go.uber.org/fx v1.20.0 h1:ZMC/pnRvhsthOZh9MZjMq5U8Or3mA9zBSPaLnzs3ihQ= -go.uber.org/fx v1.20.0/go.mod h1:qCUj0btiR3/JnanEr1TYEePfSw6o/4qYJscgvzQ5Ub0= +go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= +go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= +go.uber.org/fx v1.20.1 h1:zVwVQGS8zYvhh9Xxcu4w1M6ESyeMzebzj2NbSayZ4Mk= +go.uber.org/fx v1.20.1/go.mod h1:iSYNbHf2y55acNCwCXKx7LbWb5WG1Bnue5RDXz1OREg= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= +go.uber.org/mock v0.3.0 h1:3mUxI1No2/60yUYax92Pt8eNOEecx2D3lcXZh2NEZJo= +go.uber.org/mock v0.3.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= @@ -994,8 +994,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g= -golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= +golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI= +golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1019,8 +1019,8 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= -golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY= +golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1069,8 +1069,8 @@ golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8= -golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= +golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1097,8 +1097,8 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= -golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ= +golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/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= @@ -1241,11 +1241,10 @@ golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ= -golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= +golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc= +golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 7593700c5..b10e8c00f 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -7,11 +7,11 @@ replace github.com/ipfs/kubo => ../../ require ( github.com/Kubuxu/gocovmerge v0.0.0-20161216165753-7ecaa51963cd github.com/golangci/golangci-lint v1.54.1 - github.com/ipfs/boxo v0.14.0 + github.com/ipfs/boxo v0.15.0 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 github.com/ipfs/go-datastore v0.6.0 - github.com/ipfs/go-graphsync v0.15.1 + github.com/ipfs/go-graphsync v0.16.0 github.com/ipfs/go-log v1.0.5 github.com/ipfs/hang-fds v0.1.0 github.com/ipfs/iptb v1.4.0 @@ -19,8 +19,8 @@ require ( github.com/ipld/go-ipld-prime v0.21.0 github.com/jbenet/go-random v0.0.0-20190219211222-123a90aedc0c github.com/jbenet/go-random-files v0.0.0-20190219210431-31b3f20ebded - github.com/libp2p/go-libp2p v0.31.0 - github.com/multiformats/go-multiaddr v0.11.0 + github.com/libp2p/go-libp2p v0.32.0 + github.com/multiformats/go-multiaddr v0.12.0 github.com/multiformats/go-multihash v0.2.3 gotest.tools/gotestsum v0.4.2 ) @@ -93,7 +93,6 @@ require ( github.com/godbus/dbus/v5 v5.1.0 // indirect github.com/gofrs/flock v0.8.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang/mock v1.6.0 // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2 // indirect github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a // indirect @@ -106,7 +105,7 @@ require ( github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4 // indirect github.com/google/go-cmp v0.5.9 // indirect github.com/google/gopacket v1.1.19 // indirect - github.com/google/pprof v0.0.0-20230821062121-407c9e7a662f // indirect + github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b // indirect github.com/google/uuid v1.3.1 // indirect github.com/gordonklaus/ineffassign v0.0.0-20230610083614-0e73809eb601 // indirect github.com/gorilla/websocket v1.5.0 // indirect @@ -123,7 +122,7 @@ require ( github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/hexops/gotextdiff v1.0.3 // indirect - github.com/huin/goupnp v1.2.0 // indirect + github.com/huin/goupnp v1.3.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/ipfs/bbloom v0.0.4 // indirect github.com/ipfs/go-bitfield v1.1.0 // indirect @@ -152,7 +151,7 @@ require ( github.com/kisielk/errcheck v1.6.3 // indirect github.com/kisielk/gotool v1.0.0 // indirect github.com/kkHAIKE/contextcheck v1.1.4 // indirect - github.com/klauspost/compress v1.16.7 // indirect + github.com/klauspost/compress v1.17.2 // indirect github.com/klauspost/cpuid/v2 v2.2.5 // indirect github.com/koron/go-ssdp v0.0.4 // indirect github.com/kulti/thelper v0.6.3 // indirect @@ -181,12 +180,12 @@ require ( github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect github.com/matoous/godox v0.0.0-20230222163458-006bad1f9d26 // indirect github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.19 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-runewidth v0.0.9 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/mbilski/exhaustivestruct v1.2.0 // indirect github.com/mgechev/revive v1.3.2 // indirect - github.com/miekg/dns v1.1.55 // indirect + github.com/miekg/dns v1.1.56 // indirect github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect github.com/minio/sha256-simd v1.0.1 // indirect @@ -200,7 +199,7 @@ require ( github.com/multiformats/go-multiaddr-fmt v0.1.0 // indirect github.com/multiformats/go-multibase v0.2.0 // indirect github.com/multiformats/go-multicodec v0.9.0 // indirect - github.com/multiformats/go-multistream v0.4.1 // indirect + github.com/multiformats/go-multistream v0.5.0 // indirect github.com/multiformats/go-varint v0.0.7 // indirect github.com/nakabonne/nestif v0.3.1 // indirect github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354 // indirect @@ -208,7 +207,7 @@ require ( github.com/nishanths/predeclared v0.2.2 // indirect github.com/nunnatsa/ginkgolinter v0.13.3 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect - github.com/onsi/ginkgo/v2 v2.11.0 // indirect + github.com/onsi/ginkgo/v2 v2.13.0 // indirect github.com/opencontainers/runtime-spec v1.1.0 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect @@ -227,9 +226,9 @@ require ( github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727 // indirect github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 // indirect github.com/quic-go/qpack v0.4.0 // indirect - github.com/quic-go/qtls-go1-20 v0.3.3 // indirect - github.com/quic-go/quic-go v0.38.1 // indirect - github.com/quic-go/webtransport-go v0.5.3 // indirect + github.com/quic-go/qtls-go1-20 v0.3.4 // indirect + github.com/quic-go/quic-go v0.39.3 // indirect + github.com/quic-go/webtransport-go v0.6.0 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/ryancurrah/gomodguard v1.3.0 // indirect @@ -281,20 +280,21 @@ require ( go.opentelemetry.io/otel/trace v1.19.0 // indirect go.tmz.dev/musttag v0.7.1 // indirect go.uber.org/atomic v1.11.0 // indirect - go.uber.org/dig v1.17.0 // indirect - go.uber.org/fx v1.20.0 // indirect + go.uber.org/dig v1.17.1 // indirect + go.uber.org/fx v1.20.1 // indirect + go.uber.org/mock v0.3.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.26.0 // indirect golang.org/x/crypto v0.14.0 // indirect - golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect + golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect golang.org/x/exp/typeparams v0.0.0-20230307190834-24139beb5833 // indirect - golang.org/x/mod v0.12.0 // indirect - golang.org/x/net v0.15.0 // indirect - golang.org/x/sync v0.3.0 // indirect + golang.org/x/mod v0.13.0 // indirect + golang.org/x/net v0.17.0 // indirect + golang.org/x/sync v0.4.0 // indirect golang.org/x/sys v0.13.0 // indirect golang.org/x/term v0.13.0 // indirect golang.org/x/text v0.13.0 // indirect - golang.org/x/tools v0.13.0 // indirect + golang.org/x/tools v0.14.0 // indirect gonum.org/v1/gonum v0.13.0 // indirect google.golang.org/protobuf v1.31.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 99ffc1795..1c01c6320 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -261,8 +261,6 @@ github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= -github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= -github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -336,8 +334,8 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20230821062121-407c9e7a662f h1:pDhu5sgp8yJlEF/g6osliIIpF9K4F5jvkULXa4daRDQ= -github.com/google/pprof v0.0.0-20230821062121-407c9e7a662f/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= +github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b h1:RMpPgZTSApbPf7xaVel+QkoGPRLFLrwFO89uDUHEGf0= +github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -390,16 +388,16 @@ github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/huin/goupnp v1.2.0 h1:uOKW26NG1hsSSbXIZ1IR7XP9Gjd1U8pnLaCMgntmkmY= -github.com/huin/goupnp v1.2.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= +github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= +github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.14.0 h1:gwSGW3xqUbtUOdn71oqBknpBFKpQm352g3I+RkebrX0= -github.com/ipfs/boxo v0.14.0/go.mod h1:pu8HsZvuyYeYJsqtLDCoYSvy8rHj6vI3dlh8P0f83Zs= +github.com/ipfs/boxo v0.15.0 h1:BriLydj2nlK1nKeJQHxcKSuG5ZXcoutzhBklOtxC5pk= +github.com/ipfs/boxo v0.15.0/go.mod h1:X5ulcbR5Nh7sm3Db8+08AApUo6FsGC5mb23QDKAoB/M= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs= @@ -415,8 +413,8 @@ github.com/ipfs/go-datastore v0.6.0 h1:JKyz+Gvz1QEZw0LsX1IBn+JFCJQH4SJVFtM4uWU0M github.com/ipfs/go-datastore v0.6.0/go.mod h1:rt5M3nNbSO/8q1t4LNkLyUwRs8HupMeN/8O4Vn9YAT8= github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk= github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps= -github.com/ipfs/go-graphsync v0.15.1 h1:7v4VfRQ/8pKzPuE0wHeMaWhKu8D/RlezIrzvGWIBtHQ= -github.com/ipfs/go-graphsync v0.15.1/go.mod h1:eUIYS0OKkdBbG4vHhfGkY3lZ7h1G5Dlwd+HxTCe18vA= +github.com/ipfs/go-graphsync v0.16.0 h1:0BX7whXlV13Y9FZ/jRg+xaGHaGYbtGxGppKD6tncw6k= +github.com/ipfs/go-graphsync v0.16.0/go.mod h1:WfbMW3hhmX5GQEQ+KJxsFzVJVBKgC5szfrYK7Zc7xIM= github.com/ipfs/go-ipfs-blockstore v1.3.0 h1:m2EXaWgwTzAfsmt5UdJ7Is6l4gJcaM/A12XwJyvYvMM= github.com/ipfs/go-ipfs-blockstore v1.3.0/go.mod h1:KgtZyc9fq+P2xJUiCAzbRdhhqJHvsw8u2Dlqy2MyRTE= github.com/ipfs/go-ipfs-blocksutil v0.0.1 h1:Eh/H4pc1hsvhzsQoMEP3Bke/aW5P5rVM1IWFJMcGIPQ= @@ -508,8 +506,8 @@ github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kkHAIKE/contextcheck v1.1.4 h1:B6zAaLhOEEcjvUgIYEqystmnFk1Oemn8bvJhbt0GMb8= github.com/kkHAIKE/contextcheck v1.1.4/go.mod h1:1+i/gWqokIa+dm31mqGLZhZJ7Uh44DJGZVmr6QRBNJg= -github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I= -github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/compress v1.17.2 h1:RlWWUY/Dr4fL8qk9YG7DTZ7PDgME2V4csBXA8L/ixi4= +github.com/klauspost/compress v1.17.2/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -544,8 +542,8 @@ github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38y github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.31.0 h1:LFShhP8F6xthWiBBq3euxbKjZsoRajVEyBS9snfHxYg= -github.com/libp2p/go-libp2p v0.31.0/go.mod h1:W/FEK1c/t04PbRH3fA9i5oucu5YcgrG0JVoBWT1B7Eg= +github.com/libp2p/go-libp2p v0.32.0 h1:86I4B7nBUPIyTgw3+5Ibq6K7DdKRCuZw8URCfPc1hQM= +github.com/libp2p/go-libp2p v0.32.0/go.mod h1:hXXC3kXPlBZ1eu8Q2hptGrMB4mZ3048JUoS4EKaHW5c= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-kad-dht v0.24.4 h1:ktNiJe7ffsJ1wX3ULpMCwXts99mPqGFSE/Qn1i8pErQ= @@ -589,8 +587,8 @@ github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovk github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= -github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= @@ -602,8 +600,8 @@ github.com/mgechev/revive v1.3.2 h1:Wb8NQKBaALBJ3xrrj4zpwJwqwNA6nDpyJSEQWcCka6U= github.com/mgechev/revive v1.3.2/go.mod h1:UCLtc7o5vg5aXCwdUTU1kEBQ1v+YXPAkYDIDXbrs5I0= github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= -github.com/miekg/dns v1.1.55 h1:GoQ4hpsj0nFLYe+bWiCToyrBEJXkQfOOIvFGFy0lEgo= -github.com/miekg/dns v1.1.55/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= +github.com/miekg/dns v1.1.56 h1:5imZaSeoRNvpM9SzWNhEcP9QliKiz20/dA2QabIGVnE= +github.com/miekg/dns v1.1.56/go.mod h1:cRm6Oo2C8TY9ZS/TqsSrseAcncm74lfK5G+ikN2SWWY= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c h1:bzE/A84HN25pxAuk9Eej1Kz9OUelF97nAc82bDquQI8= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c/go.mod h1:0SQS9kMwD2VsyFEB++InYyBJroV/FRmBgcydeSUcJms= github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= @@ -637,8 +635,8 @@ github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9 github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4= github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo= github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4= -github.com/multiformats/go-multiaddr v0.11.0 h1:XqGyJ8ufbCE0HmTDwx2kPdsrQ36AGPZNZX6s6xfJH10= -github.com/multiformats/go-multiaddr v0.11.0/go.mod h1:gWUm0QLR4thQ6+ZF6SXUw8YjtwQSPapICM+NmCkxHSM= +github.com/multiformats/go-multiaddr v0.12.0 h1:1QlibTFkoXJuDjjYsMHhE73TnzJQl8FSWatk/0gxGzE= +github.com/multiformats/go-multiaddr v0.12.0/go.mod h1:WmZXgObOQOYp9r3cslLlppkrz1FYSHmE834dfz/lWu8= github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A= github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk= github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E= @@ -652,8 +650,8 @@ github.com/multiformats/go-multihash v0.0.8/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa github.com/multiformats/go-multihash v0.0.13/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= github.com/multiformats/go-multihash v0.2.3 h1:7Lyc8XfX/IY2jWb/gI7JP+o7JEq9hOa7BFvVU9RSh+U= github.com/multiformats/go-multihash v0.2.3/go.mod h1:dXgKXCXjBzdscBLk9JkjINiEsCKRVch90MdaGiKsvSM= -github.com/multiformats/go-multistream v0.4.1 h1:rFy0Iiyn3YT0asivDUIR05leAdwZq3de4741sbiSdfo= -github.com/multiformats/go-multistream v0.4.1/go.mod h1:Mz5eykRVAjJWckE2U78c6xqdtyNUEhKSM0Lwar2p77Q= +github.com/multiformats/go-multistream v0.5.0 h1:5htLSLl7lvJk3xx3qT/8Zm9J4K8vEOf/QGkvOGQAyiE= +github.com/multiformats/go-multistream v0.5.0/go.mod h1:n6tMZiwiP2wUsR8DgfDWw1dydlEqV3l6N3/GBsX6ILA= github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8= @@ -676,10 +674,10 @@ github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU= -github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM= +github.com/onsi/ginkgo/v2 v2.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4= +github.com/onsi/ginkgo/v2 v2.13.0/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.27.8 h1:gegWiwZjBsf2DgiSbf5hpokZ98JVDMcWkUiigk6/KXc= +github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.1.0 h1:HHUyrt9mwHUjtasSbXSMvs4cyFxh+Bll4AjJ9odEGpg= github.com/opencontainers/runtime-spec v1.1.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= @@ -749,12 +747,12 @@ github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 h1:M8mH9eK4OUR4l github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567/go.mod h1:DWNGW8A4Y+GyBgPuaQJuWiy0XYftx4Xm/y5Jqk9I6VQ= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= -github.com/quic-go/qtls-go1-20 v0.3.3 h1:17/glZSLI9P9fDAeyCHBFSWSqJcwx1byhLwP5eUIDCM= -github.com/quic-go/qtls-go1-20 v0.3.3/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= -github.com/quic-go/quic-go v0.38.1 h1:M36YWA5dEhEeT+slOu/SwMEucbYd0YFidxG3KlGPZaE= -github.com/quic-go/quic-go v0.38.1/go.mod h1:ijnZM7JsFIkp4cRyjxJNIzdSfCLmUMg9wdyhGmg+SN4= -github.com/quic-go/webtransport-go v0.5.3 h1:5XMlzemqB4qmOlgIus5zB45AcZ2kCgCy2EptUrfOPWU= -github.com/quic-go/webtransport-go v0.5.3/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= +github.com/quic-go/qtls-go1-20 v0.3.4 h1:MfFAPULvst4yoMgY9QmtpYmfij/em7O8UUi+bNVm7Cg= +github.com/quic-go/qtls-go1-20 v0.3.4/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= +github.com/quic-go/quic-go v0.39.3 h1:o3YB6t2SR+HU/pgwF29kJ6g4jJIJEwEZ8CKia1h1TKg= +github.com/quic-go/quic-go v0.39.3/go.mod h1:T09QsDQWjLiQ74ZmacDfqZmhY/NLnw5BC40MANNNZ1Q= +github.com/quic-go/webtransport-go v0.6.0 h1:CvNsKqc4W2HljHJnoT+rMmbRJybShZ0YPFDD3NxaZLY= +github.com/quic-go/webtransport-go v0.6.0/go.mod h1:9KjU4AEBqEQidGHNDkZrb8CAa1abRaosM2yGOyiikEc= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= @@ -944,12 +942,14 @@ go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/dig v1.17.0 h1:5Chju+tUvcC+N7N6EV08BJz41UZuO3BmHcN4A287ZLI= -go.uber.org/dig v1.17.0/go.mod h1:rTxpf7l5I0eBTlE6/9RL+lDybC7WFwY2QH55ZSjy1mU= -go.uber.org/fx v1.20.0 h1:ZMC/pnRvhsthOZh9MZjMq5U8Or3mA9zBSPaLnzs3ihQ= -go.uber.org/fx v1.20.0/go.mod h1:qCUj0btiR3/JnanEr1TYEePfSw6o/4qYJscgvzQ5Ub0= +go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= +go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= +go.uber.org/fx v1.20.1 h1:zVwVQGS8zYvhh9Xxcu4w1M6ESyeMzebzj2NbSayZ4Mk= +go.uber.org/fx v1.20.1/go.mod h1:iSYNbHf2y55acNCwCXKx7LbWb5WG1Bnue5RDXz1OREg= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= +go.uber.org/mock v0.3.0 h1:3mUxI1No2/60yUYax92Pt8eNOEecx2D3lcXZh2NEZJo= +go.uber.org/mock v0.3.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= @@ -988,8 +988,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g= -golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= +golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI= +golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo= golang.org/x/exp/typeparams v0.0.0-20220428152302-39d4317da171/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/exp/typeparams v0.0.0-20230203172020-98cc5a0785f9/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/exp/typeparams v0.0.0-20230307190834-24139beb5833 h1:jWGQJV4niP+CCmFW9ekjA9Zx8vYORzOUH2/Nl5WPuLQ= @@ -1025,8 +1025,8 @@ golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91 golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= -golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY= +golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1074,8 +1074,8 @@ golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8= -golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= +golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1102,8 +1102,8 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= -golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ= +golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/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= @@ -1276,8 +1276,8 @@ golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= golang.org/x/tools v0.5.0/go.mod h1:N+Kgy78s5I24c24dU8OfWNEotWjutIs8SnJvn5IDq+k= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ= -golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= +golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc= +golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From 9f3251c1b0f59b06d6a1210d866d6bd10c60f465 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Fri, 3 Nov 2023 08:37:51 +0100 Subject: [PATCH 0922/1212] feat: add WebRTC Direct support --- config/swarm.go | 11 ++-- core/node/libp2p/transport.go | 10 ++++ docs/changelogs/v0.24.md | 12 ++++ docs/config.md | 14 +++++ docs/examples/kubo-as-a-library/go.mod | 19 +++++++ docs/examples/kubo-as-a-library/go.sum | 77 ++++++++++++++++++++++++++ go.mod | 16 ++++++ go.sum | 76 +++++++++++++++++++++++++ test/cli/transports_test.go | 18 ++++++ 9 files changed, 248 insertions(+), 5 deletions(-) diff --git a/config/swarm.go b/config/swarm.go index 45b8a9a52..16c52b4a5 100644 --- a/config/swarm.go +++ b/config/swarm.go @@ -98,12 +98,13 @@ type Transports struct { // listen on a transport, add the transport to your Addresses.Swarm. Network struct { // All default to on. - QUIC Flag `json:",omitempty"` - TCP Flag `json:",omitempty"` - Websocket Flag `json:",omitempty"` - Relay Flag `json:",omitempty"` - // except WebTransport which is experimental and optin. + QUIC Flag `json:",omitempty"` + TCP Flag `json:",omitempty"` + Websocket Flag `json:",omitempty"` + Relay Flag `json:",omitempty"` WebTransport Flag `json:",omitempty"` + // except WebRTCDirect which is experimental and opt-in. + WebRTCDirect Flag `json:",omitempty"` } // Security specifies the transports used to encrypt insecure network diff --git a/core/node/libp2p/transport.go b/core/node/libp2p/transport.go index 8e04a63ff..797917b72 100644 --- a/core/node/libp2p/transport.go +++ b/core/node/libp2p/transport.go @@ -8,6 +8,7 @@ import ( "github.com/libp2p/go-libp2p/core/metrics" quic "github.com/libp2p/go-libp2p/p2p/transport/quic" "github.com/libp2p/go-libp2p/p2p/transport/tcp" + webrtc "github.com/libp2p/go-libp2p/p2p/transport/webrtc" "github.com/libp2p/go-libp2p/p2p/transport/websocket" webtransport "github.com/libp2p/go-libp2p/p2p/transport/webtransport" @@ -49,6 +50,15 @@ func Transports(tptConfig config.Transports) interface{} { opts.Opts = append(opts.Opts, libp2p.Transport(webtransport.New)) } + if tptConfig.Network.WebRTCDirect.WithDefault(false) { + if privateNetworkEnabled { + return opts, fmt.Errorf( + "WebRTC Direct transport does not support private networks, please disable Swarm.Transports.Network.WebRTCDirect", + ) + } + opts.Opts = append(opts.Opts, libp2p.Transport(webrtc.New)) + } + return opts, nil } } diff --git a/docs/changelogs/v0.24.md b/docs/changelogs/v0.24.md index 29d88d9cb..1a80e3437 100644 --- a/docs/changelogs/v0.24.md +++ b/docs/changelogs/v0.24.md @@ -10,6 +10,7 @@ - [Gateway: the root of the CARs are no longer meaningful](#gateway-the-root-of-the-cars-are-no-longer-meaningful) - [IPNS: improved publishing defaults](#ipns-improved-publishing-defaults) - [IPNS: record TTL is used for caching](#ipns-record-ttl-is-used-for-caching) + - [WebRTC Direct Transport](#webrtc-direct-transport) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -68,6 +69,17 @@ DHT, for updates. The TTL value in the IPNS record now serves as a hint for: These changes make it easier for rarely updated IPNS-hosted websites to be cached more efficiently and load faster in browser contexts. +#### WebRTC Direct Transport + +[WebRTC Direct](https://github.com/libp2p/go-libp2p/pull/2337) has now been introduced +in [`go-libp2p`](https://github.com/libp2p/go-libp2p/releases/tag/v0.32.0) v0.32.0. This +transport protocol allows browser nodes to connect to other nodes without special configuration, +such as TLS certificates. This can be useful for browsers that do not yet support +WebTransport, for example. + +Note that, at the moment, WebRTC Direct cannot be used to connect to a browser node to a +node that is behind a NAT or firewall. This is being worked on [`go-libp2p#2009`](https://github.com/libp2p/go-libp2p/issues/2009). + ### 📝 Changelog ### 👨‍👩‍👧‍👦 Contributors diff --git a/docs/config.md b/docs/config.md index e70b54b3a..1280ec9f4 100644 --- a/docs/config.md +++ b/docs/config.md @@ -159,6 +159,7 @@ config file at runtime. - [`Swarm.Transports.Network.QUIC`](#swarmtransportsnetworkquic) - [`Swarm.Transports.Network.Relay`](#swarmtransportsnetworkrelay) - [`Swarm.Transports.Network.WebTransport`](#swarmtransportsnetworkwebtransport) + - [`Swarm.Transports.Network.WebRTCDirect`](#swarmtransportsnetworkwebrtcdirect) - [`Swarm.Transports.Security`](#swarmtransportssecurity) - [`Swarm.Transports.Security.TLS`](#swarmtransportssecuritytls) - [`Swarm.Transports.Security.SECIO`](#swarmtransportssecuritysecio) @@ -2072,6 +2073,19 @@ Default: Enabled Type: `flag` +#### `Swarm.Transports.Network.WebRTCDirect` + +A new feature of [`go-libp2p`](https://github.com/libp2p/go-libp2p/releases/tag/v0.32.0) +is the [WebRTC Direct](https://github.com/libp2p/go-libp2p/pull/2337) transport. + +WebRTC Direct is a transport protocol that provides another way for browsers to connect to the rest of the libp2p network. WebRTC Direct allows for browser nodes to connect to other nodes without special configuration, such as TLS certificates. This can be useful for browser nodes that do not yet support WebTransport, for example. + +Note that, at the moment, WebRTC Direct cannot be used to connect to a browser node to a node that is behind a NAT or firewall. This is being worked on [`go-libp2p#2009`](https://github.com/libp2p/go-libp2p/issues/2009). + +Default: Disabled + +Type: `flag` + ### `Swarm.Transports.Security` Configuration section for libp2p _security_ transports. Transports enabled in diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index da95b3f70..5b129929c 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -30,6 +30,7 @@ require ( github.com/coreos/go-systemd/v22 v22.5.0 // indirect github.com/crackcomm/go-gitignore v0.0.0-20170627025303-887ab5e44cc3 // indirect github.com/cskr/pubsub v1.0.2 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect github.com/dgraph-io/badger v1.6.2 // indirect @@ -142,7 +143,24 @@ require ( github.com/openzipkin/zipkin-go v0.4.1 // indirect github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 // indirect + github.com/pion/datachannel v1.5.5 // indirect + github.com/pion/dtls/v2 v2.2.7 // indirect + github.com/pion/ice/v2 v2.3.6 // indirect + github.com/pion/interceptor v0.1.17 // indirect + github.com/pion/logging v0.2.2 // indirect + github.com/pion/mdns v0.0.7 // indirect + github.com/pion/randutil v0.1.0 // indirect + github.com/pion/rtcp v1.2.10 // indirect + github.com/pion/rtp v1.7.13 // indirect + github.com/pion/sctp v1.8.7 // indirect + github.com/pion/sdp/v3 v3.0.6 // indirect + github.com/pion/srtp/v2 v2.0.15 // indirect + github.com/pion/stun v0.6.0 // indirect + github.com/pion/transport/v2 v2.2.1 // indirect + github.com/pion/turn/v2 v2.1.0 // indirect + github.com/pion/webrtc/v3 v3.2.9 // indirect github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect github.com/polydawn/refmt v0.89.0 // indirect github.com/prometheus/client_golang v1.17.0 // indirect github.com/prometheus/client_model v0.5.0 // indirect @@ -155,6 +173,7 @@ require ( github.com/raulk/go-watchdog v1.3.0 // indirect github.com/samber/lo v1.36.0 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect + github.com/stretchr/testify v1.8.4 // indirect github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect github.com/ucarion/urlpath v0.0.0-20200424170820-7ccc79b76bbb // indirect github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 42bb1aa30..f5f0385e3 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -178,6 +178,7 @@ github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0= @@ -260,6 +261,7 @@ github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b/go.mod h1:czg5+yv1E0Z github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= @@ -591,16 +593,20 @@ github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJE github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= +github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/ginkgo/v2 v2.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4= github.com/onsi/ginkgo/v2 v2.13.0/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.1.0 h1:HHUyrt9mwHUjtasSbXSMvs4cyFxh+Bll4AjJ9odEGpg= @@ -617,6 +623,45 @@ github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhM github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 h1:1/WtZae0yGtPq+TI6+Tv1WTxkukpXeMlviSxvL7SRgk= github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9/go.mod h1:x3N5drFsm2uilKKuuYo6LdyD8vZAW55sH/9w+pbo1sw= +github.com/pion/datachannel v1.5.5 h1:10ef4kwdjije+M9d7Xm9im2Y3O6A6ccQb0zcqZcJew8= +github.com/pion/datachannel v1.5.5/go.mod h1:iMz+lECmfdCMqFRhXhcA/219B0SQlbpoR2V118yimL0= +github.com/pion/dtls/v2 v2.2.7 h1:cSUBsETxepsCSFSxC3mc/aDo14qQLMSL+O6IjG28yV8= +github.com/pion/dtls/v2 v2.2.7/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s= +github.com/pion/ice/v2 v2.3.6 h1:Jgqw36cAud47iD+N6rNX225uHvrgWtAlHfVyOQc3Heg= +github.com/pion/ice/v2 v2.3.6/go.mod h1:9/TzKDRwBVAPsC+YOrKH/e3xDrubeTRACU9/sHQarsU= +github.com/pion/interceptor v0.1.17 h1:prJtgwFh/gB8zMqGZoOgJPHivOwVAp61i2aG61Du/1w= +github.com/pion/interceptor v0.1.17/go.mod h1:SY8kpmfVBvrbUzvj2bsXz7OJt5JvmVNZ+4Kjq7FcwrI= +github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY= +github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms= +github.com/pion/mdns v0.0.7 h1:P0UB4Sr6xDWEox0kTVxF0LmQihtCbSAdW0H2nEgkA3U= +github.com/pion/mdns v0.0.7/go.mod h1:4iP2UbeFhLI/vWju/bw6ZfwjJzk0z8DNValjGxR/dD8= +github.com/pion/randutil v0.1.0 h1:CFG1UdESneORglEsnimhUjf33Rwjubwj6xfiOXBa3mA= +github.com/pion/randutil v0.1.0/go.mod h1:XcJrSMMbbMRhASFVOlj/5hQial/Y8oH/HVo7TBZq+j8= +github.com/pion/rtcp v1.2.10 h1:nkr3uj+8Sp97zyItdN60tE/S6vk4al5CPRR6Gejsdjc= +github.com/pion/rtcp v1.2.10/go.mod h1:ztfEwXZNLGyF1oQDttz/ZKIBaeeg/oWbRYqzBM9TL1I= +github.com/pion/rtp v1.7.13 h1:qcHwlmtiI50t1XivvoawdCGTP4Uiypzfrsap+bijcoA= +github.com/pion/rtp v1.7.13/go.mod h1:bDb5n+BFZxXx0Ea7E5qe+klMuqiBrP+w8XSjiWtCUko= +github.com/pion/sctp v1.8.5/go.mod h1:SUFFfDpViyKejTAdwD1d/HQsCu+V/40cCs2nZIvC3s0= +github.com/pion/sctp v1.8.7 h1:JnABvFakZueGAn4KU/4PSKg+GWbF6QWbKTWZOSGJjXw= +github.com/pion/sctp v1.8.7/go.mod h1:g1Ul+ARqZq5JEmoFy87Q/4CePtKnTJ1QCL9dBBdN6AU= +github.com/pion/sdp/v3 v3.0.6 h1:WuDLhtuFUUVpTfus9ILC4HRyHsW6TdugjEX/QY9OiUw= +github.com/pion/sdp/v3 v3.0.6/go.mod h1:iiFWFpQO8Fy3S5ldclBkpXqmWy02ns78NOKoLLL0YQw= +github.com/pion/srtp/v2 v2.0.15 h1:+tqRtXGsGwHC0G0IUIAzRmdkHvriF79IHVfZGfHrQoA= +github.com/pion/srtp/v2 v2.0.15/go.mod h1:b/pQOlDrbB0HEH5EUAQXzSYxikFbNcNuKmF8tM0hCtw= +github.com/pion/stun v0.4.0/go.mod h1:QPsh1/SbXASntw3zkkrIk3ZJVKz4saBY2G7S10P3wCw= +github.com/pion/stun v0.6.0 h1:JHT/2iyGDPrFWE8NNC15wnddBN8KifsEDw8swQmrEmU= +github.com/pion/stun v0.6.0/go.mod h1:HPqcfoeqQn9cuaet7AOmB5e5xkObu9DwBdurwLKO9oA= +github.com/pion/transport v0.14.1 h1:XSM6olwW+o8J4SCmOBb/BpwZypkHeyM0PGFCxNQBr40= +github.com/pion/transport v0.14.1/go.mod h1:4tGmbk00NeYA3rUa9+n+dzCCoKkcy3YlYb99Jn2fNnI= +github.com/pion/transport/v2 v2.0.0/go.mod h1:HS2MEBJTwD+1ZI2eSXSvHJx/HnzQqRy2/LXxt6eVMHc= +github.com/pion/transport/v2 v2.1.0/go.mod h1:AdSw4YBZVDkZm8fpoz+fclXyQwANWmZAlDuQdctTThQ= +github.com/pion/transport/v2 v2.2.0/go.mod h1:AdSw4YBZVDkZm8fpoz+fclXyQwANWmZAlDuQdctTThQ= +github.com/pion/transport/v2 v2.2.1 h1:7qYnCBlpgSJNYMbLCKuSY9KbQdBFoETvPNETv0y4N7c= +github.com/pion/transport/v2 v2.2.1/go.mod h1:cXXWavvCnFF6McHTft3DWS9iic2Mftcz1Aq29pGcU5g= +github.com/pion/turn/v2 v2.1.0 h1:5wGHSgGhJhP/RpabkUb/T9PdsAjkGLS6toYz5HNzoSI= +github.com/pion/turn/v2 v2.1.0/go.mod h1:yrT5XbXSGX1VFSF31A3c1kCNB5bBZgk/uu5LET162qs= +github.com/pion/webrtc/v3 v3.2.9 h1:U8NSjQDlZZ+Iy/hg42Q/u6mhEVSXYvKrOIZiZwYTfLc= +github.com/pion/webrtc/v3 v3.2.9/go.mod h1:gjQLMZeyN3jXBGdxGmUYCyKjOuYX/c99BDjGqmadq0A= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -658,6 +703,7 @@ github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd/go.mod h1:hPqNNc0+uJM6H+SuU8sEs5K5IQeKccPqeSjfgcKGgPk= github.com/samber/lo v1.36.0 h1:4LaOxH1mHnbDGhTVE0i1z8v/lWaQW8AIfOD3HU4mSaw= github.com/samber/lo v1.36.0/go.mod h1:HLeWcJRRyLKp3+/XBJvOrerCQn9mhdKMHyd7IRlgeQ8= +github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY= github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM= @@ -719,7 +765,10 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= @@ -845,6 +894,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= +golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -882,6 +933,7 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY= golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -923,9 +975,16 @@ golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210423184538-5f58ad60dda6/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= +golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -948,6 +1007,7 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ= golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -996,6 +1056,7 @@ golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1007,14 +1068,24 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1023,7 +1094,11 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1079,9 +1154,11 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc= golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/go.mod b/go.mod index b8fe887d0..5efc4d526 100644 --- a/go.mod +++ b/go.mod @@ -185,6 +185,22 @@ require ( github.com/opencontainers/runtime-spec v1.1.0 // indirect github.com/openzipkin/zipkin-go v0.4.1 // indirect github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 // indirect + github.com/pion/datachannel v1.5.5 // indirect + github.com/pion/dtls/v2 v2.2.7 // indirect + github.com/pion/ice/v2 v2.3.6 // indirect + github.com/pion/interceptor v0.1.17 // indirect + github.com/pion/logging v0.2.2 // indirect + github.com/pion/mdns v0.0.7 // indirect + github.com/pion/randutil v0.1.0 // indirect + github.com/pion/rtcp v1.2.10 // indirect + github.com/pion/rtp v1.7.13 // indirect + github.com/pion/sctp v1.8.7 // indirect + github.com/pion/sdp/v3 v3.0.6 // indirect + github.com/pion/srtp/v2 v2.0.15 // indirect + github.com/pion/stun v0.6.0 // indirect + github.com/pion/transport/v2 v2.2.1 // indirect + github.com/pion/turn/v2 v2.1.0 // indirect + github.com/pion/webrtc/v3 v3.2.9 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/polydawn/refmt v0.89.0 // indirect github.com/prometheus/client_model v0.5.0 // indirect diff --git a/go.sum b/go.sum index c07381487..fed65f74a 100644 --- a/go.sum +++ b/go.sum @@ -208,6 +208,7 @@ github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbV github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0= @@ -293,6 +294,7 @@ github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b/go.mod h1:czg5+yv1E0Z github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= @@ -669,16 +671,20 @@ github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJE github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= +github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/ginkgo/v2 v2.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4= github.com/onsi/ginkgo/v2 v2.13.0/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.1.0 h1:HHUyrt9mwHUjtasSbXSMvs4cyFxh+Bll4AjJ9odEGpg= @@ -695,6 +701,45 @@ github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhM github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 h1:1/WtZae0yGtPq+TI6+Tv1WTxkukpXeMlviSxvL7SRgk= github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9/go.mod h1:x3N5drFsm2uilKKuuYo6LdyD8vZAW55sH/9w+pbo1sw= +github.com/pion/datachannel v1.5.5 h1:10ef4kwdjije+M9d7Xm9im2Y3O6A6ccQb0zcqZcJew8= +github.com/pion/datachannel v1.5.5/go.mod h1:iMz+lECmfdCMqFRhXhcA/219B0SQlbpoR2V118yimL0= +github.com/pion/dtls/v2 v2.2.7 h1:cSUBsETxepsCSFSxC3mc/aDo14qQLMSL+O6IjG28yV8= +github.com/pion/dtls/v2 v2.2.7/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s= +github.com/pion/ice/v2 v2.3.6 h1:Jgqw36cAud47iD+N6rNX225uHvrgWtAlHfVyOQc3Heg= +github.com/pion/ice/v2 v2.3.6/go.mod h1:9/TzKDRwBVAPsC+YOrKH/e3xDrubeTRACU9/sHQarsU= +github.com/pion/interceptor v0.1.17 h1:prJtgwFh/gB8zMqGZoOgJPHivOwVAp61i2aG61Du/1w= +github.com/pion/interceptor v0.1.17/go.mod h1:SY8kpmfVBvrbUzvj2bsXz7OJt5JvmVNZ+4Kjq7FcwrI= +github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY= +github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms= +github.com/pion/mdns v0.0.7 h1:P0UB4Sr6xDWEox0kTVxF0LmQihtCbSAdW0H2nEgkA3U= +github.com/pion/mdns v0.0.7/go.mod h1:4iP2UbeFhLI/vWju/bw6ZfwjJzk0z8DNValjGxR/dD8= +github.com/pion/randutil v0.1.0 h1:CFG1UdESneORglEsnimhUjf33Rwjubwj6xfiOXBa3mA= +github.com/pion/randutil v0.1.0/go.mod h1:XcJrSMMbbMRhASFVOlj/5hQial/Y8oH/HVo7TBZq+j8= +github.com/pion/rtcp v1.2.10 h1:nkr3uj+8Sp97zyItdN60tE/S6vk4al5CPRR6Gejsdjc= +github.com/pion/rtcp v1.2.10/go.mod h1:ztfEwXZNLGyF1oQDttz/ZKIBaeeg/oWbRYqzBM9TL1I= +github.com/pion/rtp v1.7.13 h1:qcHwlmtiI50t1XivvoawdCGTP4Uiypzfrsap+bijcoA= +github.com/pion/rtp v1.7.13/go.mod h1:bDb5n+BFZxXx0Ea7E5qe+klMuqiBrP+w8XSjiWtCUko= +github.com/pion/sctp v1.8.5/go.mod h1:SUFFfDpViyKejTAdwD1d/HQsCu+V/40cCs2nZIvC3s0= +github.com/pion/sctp v1.8.7 h1:JnABvFakZueGAn4KU/4PSKg+GWbF6QWbKTWZOSGJjXw= +github.com/pion/sctp v1.8.7/go.mod h1:g1Ul+ARqZq5JEmoFy87Q/4CePtKnTJ1QCL9dBBdN6AU= +github.com/pion/sdp/v3 v3.0.6 h1:WuDLhtuFUUVpTfus9ILC4HRyHsW6TdugjEX/QY9OiUw= +github.com/pion/sdp/v3 v3.0.6/go.mod h1:iiFWFpQO8Fy3S5ldclBkpXqmWy02ns78NOKoLLL0YQw= +github.com/pion/srtp/v2 v2.0.15 h1:+tqRtXGsGwHC0G0IUIAzRmdkHvriF79IHVfZGfHrQoA= +github.com/pion/srtp/v2 v2.0.15/go.mod h1:b/pQOlDrbB0HEH5EUAQXzSYxikFbNcNuKmF8tM0hCtw= +github.com/pion/stun v0.4.0/go.mod h1:QPsh1/SbXASntw3zkkrIk3ZJVKz4saBY2G7S10P3wCw= +github.com/pion/stun v0.6.0 h1:JHT/2iyGDPrFWE8NNC15wnddBN8KifsEDw8swQmrEmU= +github.com/pion/stun v0.6.0/go.mod h1:HPqcfoeqQn9cuaet7AOmB5e5xkObu9DwBdurwLKO9oA= +github.com/pion/transport v0.14.1 h1:XSM6olwW+o8J4SCmOBb/BpwZypkHeyM0PGFCxNQBr40= +github.com/pion/transport v0.14.1/go.mod h1:4tGmbk00NeYA3rUa9+n+dzCCoKkcy3YlYb99Jn2fNnI= +github.com/pion/transport/v2 v2.0.0/go.mod h1:HS2MEBJTwD+1ZI2eSXSvHJx/HnzQqRy2/LXxt6eVMHc= +github.com/pion/transport/v2 v2.1.0/go.mod h1:AdSw4YBZVDkZm8fpoz+fclXyQwANWmZAlDuQdctTThQ= +github.com/pion/transport/v2 v2.2.0/go.mod h1:AdSw4YBZVDkZm8fpoz+fclXyQwANWmZAlDuQdctTThQ= +github.com/pion/transport/v2 v2.2.1 h1:7qYnCBlpgSJNYMbLCKuSY9KbQdBFoETvPNETv0y4N7c= +github.com/pion/transport/v2 v2.2.1/go.mod h1:cXXWavvCnFF6McHTft3DWS9iic2Mftcz1Aq29pGcU5g= +github.com/pion/turn/v2 v2.1.0 h1:5wGHSgGhJhP/RpabkUb/T9PdsAjkGLS6toYz5HNzoSI= +github.com/pion/turn/v2 v2.1.0/go.mod h1:yrT5XbXSGX1VFSF31A3c1kCNB5bBZgk/uu5LET162qs= +github.com/pion/webrtc/v3 v3.2.9 h1:U8NSjQDlZZ+Iy/hg42Q/u6mhEVSXYvKrOIZiZwYTfLc= +github.com/pion/webrtc/v3 v3.2.9/go.mod h1:gjQLMZeyN3jXBGdxGmUYCyKjOuYX/c99BDjGqmadq0A= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -765,6 +810,7 @@ github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd/go.mod h1:hPqNNc0+uJM6H+SuU8sEs5K5IQeKccPqeSjfgcKGgPk= github.com/samber/lo v1.36.0 h1:4LaOxH1mHnbDGhTVE0i1z8v/lWaQW8AIfOD3HU4mSaw= github.com/samber/lo v1.36.0/go.mod h1:HLeWcJRRyLKp3+/XBJvOrerCQn9mhdKMHyd7IRlgeQ8= +github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY= github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM= @@ -828,6 +874,8 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stvp/go-udp-testing v0.0.0-20201019212854-469649b16807/go.mod h1:7jxmlfBCDBXRzr0eAQJ48XC1hBu1np4CS5+cHEYfwpc= @@ -982,6 +1030,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= +golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1019,6 +1069,7 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY= golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1063,12 +1114,19 @@ golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210423184538-5f58ad60dda6/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= +golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1097,6 +1155,7 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ= golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1150,6 +1209,7 @@ golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1166,14 +1226,24 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220708085239-5a0f0661e09d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1184,7 +1254,11 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1240,9 +1314,11 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc= golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/test/cli/transports_test.go b/test/cli/transports_test.go index d37c78aad..c1642c602 100644 --- a/test/cli/transports_test.go +++ b/test/cli/transports_test.go @@ -58,6 +58,7 @@ func TestTransports(t *testing.T) { cfg.Swarm.Transports.Network.QUIC = config.False cfg.Swarm.Transports.Network.Relay = config.False cfg.Swarm.Transports.Network.WebTransport = config.False + cfg.Swarm.Transports.Network.WebRTCDirect = config.False cfg.Swarm.Transports.Network.Websocket = config.False }) }) @@ -148,4 +149,21 @@ func TestTransports(t *testing.T) { nodes.StartDaemons().Connect() runTests(nodes) }) + + t.Run("WebRTC Direct", func(t *testing.T) { + t.Parallel() + nodes := harness.NewT(t).NewNodes(5).Init() + nodes.ForEachPar(func(n *harness.Node) { + n.UpdateConfig(func(cfg *config.Config) { + cfg.Addresses.Swarm = []string{"/ip4/127.0.0.1/udp/0/webrtc-direct"} + cfg.Swarm.Transports.Network.TCP = config.False + cfg.Swarm.Transports.Network.QUIC = config.False + cfg.Swarm.Transports.Network.WebTransport = config.False + cfg.Swarm.Transports.Network.WebRTCDirect = config.True + }) + }) + disableRouting(nodes) + nodes.StartDaemons().Connect() + runTests(nodes) + }) } From 884a3f36d44e3359f3f5112abb87344cd6d51b49 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Fri, 3 Nov 2023 14:49:35 +0100 Subject: [PATCH 0923/1212] docs: make it clear Web RTC Direct is experimental --- docs/changelogs/v0.24.md | 4 ++-- docs/config.md | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/changelogs/v0.24.md b/docs/changelogs/v0.24.md index 1a80e3437..34a8490b0 100644 --- a/docs/changelogs/v0.24.md +++ b/docs/changelogs/v0.24.md @@ -10,7 +10,7 @@ - [Gateway: the root of the CARs are no longer meaningful](#gateway-the-root-of-the-cars-are-no-longer-meaningful) - [IPNS: improved publishing defaults](#ipns-improved-publishing-defaults) - [IPNS: record TTL is used for caching](#ipns-record-ttl-is-used-for-caching) - - [WebRTC Direct Transport](#webrtc-direct-transport) + - [Experimental Transport: WebRTC Direct](#experimental-transport-webrtc-direct) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -69,7 +69,7 @@ DHT, for updates. The TTL value in the IPNS record now serves as a hint for: These changes make it easier for rarely updated IPNS-hosted websites to be cached more efficiently and load faster in browser contexts. -#### WebRTC Direct Transport +#### Experimental Transport: WebRTC Direct [WebRTC Direct](https://github.com/libp2p/go-libp2p/pull/2337) has now been introduced in [`go-libp2p`](https://github.com/libp2p/go-libp2p/releases/tag/v0.32.0) v0.32.0. This diff --git a/docs/config.md b/docs/config.md index 1280ec9f4..1c8b0ed86 100644 --- a/docs/config.md +++ b/docs/config.md @@ -2075,6 +2075,8 @@ Type: `flag` #### `Swarm.Transports.Network.WebRTCDirect` +**Experimental:** the support for WebRTC Direct is currently experimental. + A new feature of [`go-libp2p`](https://github.com/libp2p/go-libp2p/releases/tag/v0.32.0) is the [WebRTC Direct](https://github.com/libp2p/go-libp2p/pull/2337) transport. From 3fa239c64b839949c00339504f209c73bb4d3014 Mon Sep 17 00:00:00 2001 From: Steve Loeppky Date: Fri, 3 Nov 2023 08:03:07 +0100 Subject: [PATCH 0924/1212] docs: update EARLY_TESTERS.md (#10194) --- docs/EARLY_TESTERS.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/EARLY_TESTERS.md b/docs/EARLY_TESTERS.md index 635890676..6c5b09b15 100644 --- a/docs/EARLY_TESTERS.md +++ b/docs/EARLY_TESTERS.md @@ -26,11 +26,11 @@ We will ask early testers to participate at two points in the process: - [ ] Fission (@bmann) - [ ] Infura (@MichaelMure) - [ ] OrbitDB (@haydenyoung) -- [ ] pacman.store (@RubenKelevra) - [ ] Pinata (@obo20) -- [ ] PL EngRes bifrost (@gmasgras) +- [ ] PL EngRes bifrost (@cewood ns4plabs) - [ ] Siderus (@koalalorenzo) - [ ] Textile (@sanderpick) +- [ ] @RubenKelevra ## How to sign up? From d8754c62630b0169f29043e1d4e93763b237a31d Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Fri, 3 Nov 2023 08:17:00 +0100 Subject: [PATCH 0925/1212] chore: go-libp2p v0.32.0 --- docs/examples/kubo-as-a-library/go.mod | 46 ++++++------- docs/examples/kubo-as-a-library/go.sum | 95 +++++++++++++------------- go.mod | 46 ++++++------- go.sum | 95 +++++++++++++------------- test/dependencies/go.mod | 44 ++++++------ test/dependencies/go.sum | 90 ++++++++++++------------ 6 files changed, 207 insertions(+), 209 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index b2b90bf3b..da95b3f70 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,10 +7,10 @@ go 1.20 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.14.0 + github.com/ipfs/boxo v0.15.0 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 - github.com/libp2p/go-libp2p v0.31.0 - github.com/multiformats/go-multiaddr v0.11.0 + github.com/libp2p/go-libp2p v0.32.0 + github.com/multiformats/go-multiaddr v0.12.0 ) require ( @@ -47,11 +47,10 @@ require ( github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/godbus/dbus/v5 v5.1.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang/mock v1.6.0 // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/gopacket v1.1.19 // indirect - github.com/google/pprof v0.0.0-20230821062121-407c9e7a662f // indirect + github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b // indirect github.com/google/uuid v1.3.1 // indirect github.com/gorilla/websocket v1.5.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 // indirect @@ -60,7 +59,7 @@ require ( github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/golang-lru v0.5.4 // indirect github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect - github.com/huin/goupnp v1.2.0 // indirect + github.com/huin/goupnp v1.3.0 // indirect github.com/ipfs-shipyard/nopfs v0.0.12-0.20231027223058-cde3b5ba964c // indirect github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c // indirect github.com/ipfs/bbloom v0.0.4 // indirect @@ -74,7 +73,7 @@ require ( github.com/ipfs/go-ds-leveldb v0.5.0 // indirect github.com/ipfs/go-ds-measure v0.2.0 // indirect github.com/ipfs/go-fs-lock v0.0.7 // indirect - github.com/ipfs/go-graphsync v0.15.1 // indirect + github.com/ipfs/go-graphsync v0.16.0 // indirect github.com/ipfs/go-ipfs-blockstore v1.3.0 // indirect github.com/ipfs/go-ipfs-delay v0.0.1 // indirect github.com/ipfs/go-ipfs-ds-help v1.1.0 // indirect @@ -97,7 +96,7 @@ require ( github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect github.com/jbenet/goprocess v0.1.4 // indirect - github.com/klauspost/compress v1.16.7 // indirect + github.com/klauspost/compress v1.17.2 // indirect github.com/klauspost/cpuid/v2 v2.2.5 // indirect github.com/koron/go-ssdp v0.0.4 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect @@ -107,7 +106,7 @@ require ( github.com/libp2p/go-libp2p-asn-util v0.3.0 // indirect github.com/libp2p/go-libp2p-kad-dht v0.24.4 // indirect github.com/libp2p/go-libp2p-kbucket v0.6.3 // indirect - github.com/libp2p/go-libp2p-pubsub v0.9.3 // indirect + github.com/libp2p/go-libp2p-pubsub v0.10.0 // indirect github.com/libp2p/go-libp2p-pubsub-router v0.6.0 // indirect github.com/libp2p/go-libp2p-record v0.2.0 // indirect github.com/libp2p/go-libp2p-routing-helpers v0.7.3 // indirect @@ -120,9 +119,9 @@ require ( github.com/libp2p/go-yamux/v4 v4.0.1 // indirect github.com/libp2p/zeroconf/v2 v2.2.0 // indirect github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect - github.com/mattn/go-isatty v0.0.19 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect - github.com/miekg/dns v1.1.55 // indirect + github.com/miekg/dns v1.1.56 // indirect github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect github.com/minio/sha256-simd v1.0.1 // indirect @@ -135,9 +134,9 @@ require ( github.com/multiformats/go-multibase v0.2.0 // indirect github.com/multiformats/go-multicodec v0.9.0 // indirect github.com/multiformats/go-multihash v0.2.3 // indirect - github.com/multiformats/go-multistream v0.4.1 // indirect + github.com/multiformats/go-multistream v0.5.0 // indirect github.com/multiformats/go-varint v0.0.7 // indirect - github.com/onsi/ginkgo/v2 v2.11.0 // indirect + github.com/onsi/ginkgo/v2 v2.13.0 // indirect github.com/opencontainers/runtime-spec v1.1.0 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/openzipkin/zipkin-go v0.4.1 // indirect @@ -150,9 +149,9 @@ require ( github.com/prometheus/common v0.44.0 // indirect github.com/prometheus/procfs v0.12.0 // indirect github.com/quic-go/qpack v0.4.0 // indirect - github.com/quic-go/qtls-go1-20 v0.3.3 // indirect - github.com/quic-go/quic-go v0.38.1 // indirect - github.com/quic-go/webtransport-go v0.5.3 // indirect + github.com/quic-go/qtls-go1-20 v0.3.4 // indirect + github.com/quic-go/quic-go v0.39.3 // indirect + github.com/quic-go/webtransport-go v0.6.0 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/samber/lo v1.36.0 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect @@ -178,19 +177,20 @@ require ( go.opentelemetry.io/otel/trace v1.17.0 // indirect go.opentelemetry.io/proto/otlp v0.19.0 // indirect go.uber.org/atomic v1.11.0 // indirect - go.uber.org/dig v1.17.0 // indirect - go.uber.org/fx v1.20.0 // indirect + go.uber.org/dig v1.17.1 // indirect + go.uber.org/fx v1.20.1 // indirect + go.uber.org/mock v0.3.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.26.0 // indirect go4.org v0.0.0-20230225012048-214862532bf5 // indirect golang.org/x/crypto v0.14.0 // indirect - golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect - golang.org/x/mod v0.12.0 // indirect - golang.org/x/net v0.15.0 // indirect - golang.org/x/sync v0.3.0 // indirect + golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect + golang.org/x/mod v0.13.0 // indirect + golang.org/x/net v0.17.0 // indirect + golang.org/x/sync v0.4.0 // indirect golang.org/x/sys v0.13.0 // indirect golang.org/x/text v0.13.0 // indirect - golang.org/x/tools v0.13.0 // indirect + golang.org/x/tools v0.14.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect gonum.org/v1/gonum v0.13.0 // indirect google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index ba1c192a2..42bb1aa30 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -206,8 +206,6 @@ github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= -github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= -github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -257,8 +255,8 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20230821062121-407c9e7a662f h1:pDhu5sgp8yJlEF/g6osliIIpF9K4F5jvkULXa4daRDQ= -github.com/google/pprof v0.0.0-20230821062121-407c9e7a662f/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= +github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b h1:RMpPgZTSApbPf7xaVel+QkoGPRLFLrwFO89uDUHEGf0= +github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -295,8 +293,8 @@ github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/huin/goupnp v1.2.0 h1:uOKW26NG1hsSSbXIZ1IR7XP9Gjd1U8pnLaCMgntmkmY= -github.com/huin/goupnp v1.2.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= +github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= +github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs-shipyard/nopfs v0.0.12-0.20231027223058-cde3b5ba964c h1:17FO7HnKiFhO7iadu3zCgII+EblpdRmJt5qg9FqQo8Y= @@ -305,8 +303,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.14.0 h1:gwSGW3xqUbtUOdn71oqBknpBFKpQm352g3I+RkebrX0= -github.com/ipfs/boxo v0.14.0/go.mod h1:pu8HsZvuyYeYJsqtLDCoYSvy8rHj6vI3dlh8P0f83Zs= +github.com/ipfs/boxo v0.15.0 h1:BriLydj2nlK1nKeJQHxcKSuG5ZXcoutzhBklOtxC5pk= +github.com/ipfs/boxo v0.15.0/go.mod h1:X5ulcbR5Nh7sm3Db8+08AApUo6FsGC5mb23QDKAoB/M= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= @@ -343,8 +341,8 @@ github.com/ipfs/go-ds-measure v0.2.0 h1:sG4goQe0KDTccHMyT45CY1XyUbxe5VwTKpg2LjAp github.com/ipfs/go-ds-measure v0.2.0/go.mod h1:SEUD/rE2PwRa4IQEC5FuNAmjJCyYObZr9UvVh8V3JxE= github.com/ipfs/go-fs-lock v0.0.7 h1:6BR3dajORFrFTkb5EpCUFIAypsoxpGpDSVUdFwzgL9U= github.com/ipfs/go-fs-lock v0.0.7/go.mod h1:Js8ka+FNYmgQRLrRXzU3CB/+Csr1BwrRilEcvYrHhhc= -github.com/ipfs/go-graphsync v0.15.1 h1:7v4VfRQ/8pKzPuE0wHeMaWhKu8D/RlezIrzvGWIBtHQ= -github.com/ipfs/go-graphsync v0.15.1/go.mod h1:eUIYS0OKkdBbG4vHhfGkY3lZ7h1G5Dlwd+HxTCe18vA= +github.com/ipfs/go-graphsync v0.16.0 h1:0BX7whXlV13Y9FZ/jRg+xaGHaGYbtGxGppKD6tncw6k= +github.com/ipfs/go-graphsync v0.16.0/go.mod h1:WfbMW3hhmX5GQEQ+KJxsFzVJVBKgC5szfrYK7Zc7xIM= github.com/ipfs/go-ipfs-blockstore v1.3.0 h1:m2EXaWgwTzAfsmt5UdJ7Is6l4gJcaM/A12XwJyvYvMM= github.com/ipfs/go-ipfs-blockstore v1.3.0/go.mod h1:KgtZyc9fq+P2xJUiCAzbRdhhqJHvsw8u2Dlqy2MyRTE= github.com/ipfs/go-ipfs-blocksutil v0.0.1 h1:Eh/H4pc1hsvhzsQoMEP3Bke/aW5P5rVM1IWFJMcGIPQ= @@ -432,8 +430,8 @@ github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQL 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.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I= -github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/compress v1.17.2 h1:RlWWUY/Dr4fL8qk9YG7DTZ7PDgME2V4csBXA8L/ixi4= +github.com/klauspost/compress v1.17.2/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= @@ -463,8 +461,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.31.0 h1:LFShhP8F6xthWiBBq3euxbKjZsoRajVEyBS9snfHxYg= -github.com/libp2p/go-libp2p v0.31.0/go.mod h1:W/FEK1c/t04PbRH3fA9i5oucu5YcgrG0JVoBWT1B7Eg= +github.com/libp2p/go-libp2p v0.32.0 h1:86I4B7nBUPIyTgw3+5Ibq6K7DdKRCuZw8URCfPc1hQM= +github.com/libp2p/go-libp2p v0.32.0/go.mod h1:hXXC3kXPlBZ1eu8Q2hptGrMB4mZ3048JUoS4EKaHW5c= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= @@ -475,8 +473,8 @@ github.com/libp2p/go-libp2p-kbucket v0.3.1/go.mod h1:oyjT5O7tS9CQurok++ERgc46YLw github.com/libp2p/go-libp2p-kbucket v0.6.3 h1:p507271wWzpy2f1XxPzCQG9NiN6R6lHL9GiSErbQQo0= github.com/libp2p/go-libp2p-kbucket v0.6.3/go.mod h1:RCseT7AH6eJWxxk2ol03xtP9pEHetYSPXOaJnOiD8i0= github.com/libp2p/go-libp2p-peerstore v0.1.4/go.mod h1:+4BDbDiiKf4PzpANZDAT+knVdLxvqh7hXOujessqdzs= -github.com/libp2p/go-libp2p-pubsub v0.9.3 h1:ihcz9oIBMaCK9kcx+yHWm3mLAFBMAUsM4ux42aikDxo= -github.com/libp2p/go-libp2p-pubsub v0.9.3/go.mod h1:RYA7aM9jIic5VV47WXu4GkcRxRhrdElWf8xtyli+Dzc= +github.com/libp2p/go-libp2p-pubsub v0.10.0 h1:wS0S5FlISavMaAbxyQn3dxMOe2eegMfswM471RuHJwA= +github.com/libp2p/go-libp2p-pubsub v0.10.0/go.mod h1:1OxbaT/pFRO5h+Dpze8hdHQ63R0ke55XTs6b6NwLLkw= github.com/libp2p/go-libp2p-pubsub-router v0.6.0 h1:D30iKdlqDt5ZmLEYhHELCMRj8b4sFAqrUcshIUvVP/s= github.com/libp2p/go-libp2p-pubsub-router v0.6.0/go.mod h1:FY/q0/RBTKsLA7l4vqC2cbRbOvyDotg8PJQ7j8FDudE= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= @@ -515,8 +513,8 @@ 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.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= -github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= @@ -524,8 +522,8 @@ github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyex github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= -github.com/miekg/dns v1.1.55 h1:GoQ4hpsj0nFLYe+bWiCToyrBEJXkQfOOIvFGFy0lEgo= -github.com/miekg/dns v1.1.55/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= +github.com/miekg/dns v1.1.56 h1:5imZaSeoRNvpM9SzWNhEcP9QliKiz20/dA2QabIGVnE= +github.com/miekg/dns v1.1.56/go.mod h1:cRm6Oo2C8TY9ZS/TqsSrseAcncm74lfK5G+ikN2SWWY= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c h1:bzE/A84HN25pxAuk9Eej1Kz9OUelF97nAc82bDquQI8= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c/go.mod h1:0SQS9kMwD2VsyFEB++InYyBJroV/FRmBgcydeSUcJms= github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= @@ -558,8 +556,8 @@ github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a github.com/multiformats/go-multiaddr v0.1.0/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo= github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4= -github.com/multiformats/go-multiaddr v0.11.0 h1:XqGyJ8ufbCE0HmTDwx2kPdsrQ36AGPZNZX6s6xfJH10= -github.com/multiformats/go-multiaddr v0.11.0/go.mod h1:gWUm0QLR4thQ6+ZF6SXUw8YjtwQSPapICM+NmCkxHSM= +github.com/multiformats/go-multiaddr v0.12.0 h1:1QlibTFkoXJuDjjYsMHhE73TnzJQl8FSWatk/0gxGzE= +github.com/multiformats/go-multiaddr v0.12.0/go.mod h1:WmZXgObOQOYp9r3cslLlppkrz1FYSHmE834dfz/lWu8= github.com/multiformats/go-multiaddr-dns v0.3.0/go.mod h1:mNzQ4eTGDg0ll1N9jKPOUogZPoJ30W8a7zk66FQPpdQ= github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A= github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk= @@ -582,8 +580,8 @@ github.com/multiformats/go-multihash v0.0.15/go.mod h1:D6aZrWNLFTV/ynMpKsNtB40mJ github.com/multiformats/go-multihash v0.1.0/go.mod h1:RJlXsxt6vHGaia+S8We0ErjhojtKzPP2AH4+kYM7k84= github.com/multiformats/go-multihash v0.2.3 h1:7Lyc8XfX/IY2jWb/gI7JP+o7JEq9hOa7BFvVU9RSh+U= github.com/multiformats/go-multihash v0.2.3/go.mod h1:dXgKXCXjBzdscBLk9JkjINiEsCKRVch90MdaGiKsvSM= -github.com/multiformats/go-multistream v0.4.1 h1:rFy0Iiyn3YT0asivDUIR05leAdwZq3de4741sbiSdfo= -github.com/multiformats/go-multistream v0.4.1/go.mod h1:Mz5eykRVAjJWckE2U78c6xqdtyNUEhKSM0Lwar2p77Q= +github.com/multiformats/go-multistream v0.5.0 h1:5htLSLl7lvJk3xx3qT/8Zm9J4K8vEOf/QGkvOGQAyiE= +github.com/multiformats/go-multistream v0.5.0/go.mod h1:n6tMZiwiP2wUsR8DgfDWw1dydlEqV3l6N3/GBsX6ILA= github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/multiformats/go-varint v0.0.6/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= @@ -598,12 +596,12 @@ github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= -github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU= -github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM= +github.com/onsi/ginkgo/v2 v2.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4= +github.com/onsi/ginkgo/v2 v2.13.0/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.27.8 h1:gegWiwZjBsf2DgiSbf5hpokZ98JVDMcWkUiigk6/KXc= +github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.1.0 h1:HHUyrt9mwHUjtasSbXSMvs4cyFxh+Bll4AjJ9odEGpg= github.com/opencontainers/runtime-spec v1.1.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= @@ -643,12 +641,12 @@ github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= -github.com/quic-go/qtls-go1-20 v0.3.3 h1:17/glZSLI9P9fDAeyCHBFSWSqJcwx1byhLwP5eUIDCM= -github.com/quic-go/qtls-go1-20 v0.3.3/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= -github.com/quic-go/quic-go v0.38.1 h1:M36YWA5dEhEeT+slOu/SwMEucbYd0YFidxG3KlGPZaE= -github.com/quic-go/quic-go v0.38.1/go.mod h1:ijnZM7JsFIkp4cRyjxJNIzdSfCLmUMg9wdyhGmg+SN4= -github.com/quic-go/webtransport-go v0.5.3 h1:5XMlzemqB4qmOlgIus5zB45AcZ2kCgCy2EptUrfOPWU= -github.com/quic-go/webtransport-go v0.5.3/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= +github.com/quic-go/qtls-go1-20 v0.3.4 h1:MfFAPULvst4yoMgY9QmtpYmfij/em7O8UUi+bNVm7Cg= +github.com/quic-go/qtls-go1-20 v0.3.4/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= +github.com/quic-go/quic-go v0.39.3 h1:o3YB6t2SR+HU/pgwF29kJ6g4jJIJEwEZ8CKia1h1TKg= +github.com/quic-go/quic-go v0.39.3/go.mod h1:T09QsDQWjLiQ74ZmacDfqZmhY/NLnw5BC40MANNNZ1Q= +github.com/quic-go/webtransport-go v0.6.0 h1:CvNsKqc4W2HljHJnoT+rMmbRJybShZ0YPFDD3NxaZLY= +github.com/quic-go/webtransport-go v0.6.0/go.mod h1:9KjU4AEBqEQidGHNDkZrb8CAa1abRaosM2yGOyiikEc= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= @@ -806,12 +804,14 @@ go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/dig v1.17.0 h1:5Chju+tUvcC+N7N6EV08BJz41UZuO3BmHcN4A287ZLI= -go.uber.org/dig v1.17.0/go.mod h1:rTxpf7l5I0eBTlE6/9RL+lDybC7WFwY2QH55ZSjy1mU= -go.uber.org/fx v1.20.0 h1:ZMC/pnRvhsthOZh9MZjMq5U8Or3mA9zBSPaLnzs3ihQ= -go.uber.org/fx v1.20.0/go.mod h1:qCUj0btiR3/JnanEr1TYEePfSw6o/4qYJscgvzQ5Ub0= +go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= +go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= +go.uber.org/fx v1.20.1 h1:zVwVQGS8zYvhh9Xxcu4w1M6ESyeMzebzj2NbSayZ4Mk= +go.uber.org/fx v1.20.1/go.mod h1:iSYNbHf2y55acNCwCXKx7LbWb5WG1Bnue5RDXz1OREg= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= +go.uber.org/mock v0.3.0 h1:3mUxI1No2/60yUYax92Pt8eNOEecx2D3lcXZh2NEZJo= +go.uber.org/mock v0.3.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= @@ -857,8 +857,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g= -golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= +golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI= +golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -882,8 +882,8 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= -golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY= +golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -926,8 +926,8 @@ golang.org/x/net v0.0.0-20210423184538-5f58ad60dda6/go.mod h1:OJAsFXCWl8Ukc7SiCT golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8= -golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= +golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -948,8 +948,8 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= -golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ= +golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/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= @@ -1080,11 +1080,10 @@ golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ= -golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= +golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc= +golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/go.mod b/go.mod index 1acc57dae..b8fe887d0 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,7 @@ require ( github.com/hashicorp/go-multierror v1.1.1 github.com/ipfs-shipyard/nopfs v0.0.12-0.20231027223058-cde3b5ba964c github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c - github.com/ipfs/boxo v0.14.0 + github.com/ipfs/boxo v0.15.0 github.com/ipfs/go-block-format v0.2.0 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 @@ -28,7 +28,7 @@ require ( github.com/ipfs/go-ds-leveldb v0.5.0 github.com/ipfs/go-ds-measure v0.2.0 github.com/ipfs/go-fs-lock v0.0.7 - github.com/ipfs/go-graphsync v0.15.1 + github.com/ipfs/go-graphsync v0.16.0 github.com/ipfs/go-ipfs-cmds v0.10.0 github.com/ipfs/go-ipld-format v0.6.0 github.com/ipfs/go-ipld-git v0.1.1 @@ -47,11 +47,11 @@ require ( github.com/jbenet/goprocess v0.1.4 github.com/julienschmidt/httprouter v1.3.0 github.com/libp2p/go-doh-resolver v0.4.0 - github.com/libp2p/go-libp2p v0.31.0 + github.com/libp2p/go-libp2p v0.32.0 github.com/libp2p/go-libp2p-http v0.5.0 github.com/libp2p/go-libp2p-kad-dht v0.24.4 github.com/libp2p/go-libp2p-kbucket v0.6.3 - github.com/libp2p/go-libp2p-pubsub v0.9.3 + github.com/libp2p/go-libp2p-pubsub v0.10.0 github.com/libp2p/go-libp2p-pubsub-router v0.6.0 github.com/libp2p/go-libp2p-record v0.2.0 github.com/libp2p/go-libp2p-routing-helpers v0.7.3 @@ -59,7 +59,7 @@ require ( github.com/libp2p/go-mplex v0.7.0 github.com/libp2p/go-socket-activation v0.1.0 github.com/mitchellh/go-homedir v1.1.0 - github.com/multiformats/go-multiaddr v0.11.0 + github.com/multiformats/go-multiaddr v0.12.0 github.com/multiformats/go-multiaddr-dns v0.3.1 github.com/multiformats/go-multibase v0.2.0 github.com/multiformats/go-multicodec v0.9.0 @@ -80,14 +80,14 @@ require ( go.opentelemetry.io/otel v1.17.0 go.opentelemetry.io/otel/sdk v1.16.0 go.opentelemetry.io/otel/trace v1.17.0 - go.uber.org/dig v1.17.0 - go.uber.org/fx v1.20.0 + go.uber.org/dig v1.17.1 + go.uber.org/fx v1.20.1 go.uber.org/multierr v1.11.0 go.uber.org/zap v1.26.0 golang.org/x/crypto v0.14.0 - golang.org/x/exp v0.0.0-20230905200255-921286631fa9 - golang.org/x/mod v0.12.0 - golang.org/x/sync v0.3.0 + golang.org/x/exp v0.0.0-20231006140011-7918f672742d + golang.org/x/mod v0.13.0 + golang.org/x/sync v0.4.0 golang.org/x/sys v0.13.0 google.golang.org/protobuf v1.31.0 ) @@ -122,11 +122,10 @@ require ( github.com/godbus/dbus/v5 v5.1.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/golang/mock v1.6.0 // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/gopacket v1.1.19 // indirect - github.com/google/pprof v0.0.0-20230821062121-407c9e7a662f // indirect + github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b // indirect github.com/gorilla/mux v1.8.0 // indirect github.com/gorilla/websocket v1.5.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 // indirect @@ -134,7 +133,7 @@ require ( github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/golang-lru v0.5.4 // indirect github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect - github.com/huin/goupnp v1.2.0 // indirect + github.com/huin/goupnp v1.3.0 // indirect github.com/ipfs/bbloom v0.0.4 // indirect github.com/ipfs/go-bitfield v1.1.0 // indirect github.com/ipfs/go-blockservice v0.5.0 // indirect @@ -151,7 +150,7 @@ require ( github.com/ipfs/go-peertaskqueue v0.8.1 // indirect github.com/ipfs/go-verifcid v0.0.2 // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect - github.com/klauspost/compress v1.16.7 // indirect + github.com/klauspost/compress v1.17.2 // indirect github.com/klauspost/cpuid/v2 v2.2.5 // indirect github.com/koron/go-ssdp v0.0.4 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect @@ -168,11 +167,11 @@ require ( github.com/libp2p/zeroconf/v2 v2.2.0 // indirect github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect github.com/mattn/go-colorable v0.1.6 // indirect - github.com/mattn/go-isatty v0.0.19 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-runewidth v0.0.4 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect - github.com/miekg/dns v1.1.55 // indirect + github.com/miekg/dns v1.1.56 // indirect github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect github.com/minio/sha256-simd v1.0.1 // indirect @@ -180,9 +179,9 @@ require ( github.com/multiformats/go-base32 v0.1.0 // indirect github.com/multiformats/go-base36 v0.2.0 // indirect github.com/multiformats/go-multiaddr-fmt v0.1.0 // indirect - github.com/multiformats/go-multistream v0.4.1 // indirect + github.com/multiformats/go-multistream v0.5.0 // indirect github.com/multiformats/go-varint v0.0.7 // indirect - github.com/onsi/ginkgo/v2 v2.11.0 // indirect + github.com/onsi/ginkgo/v2 v2.13.0 // indirect github.com/opencontainers/runtime-spec v1.1.0 // indirect github.com/openzipkin/zipkin-go v0.4.1 // indirect github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 // indirect @@ -193,9 +192,9 @@ require ( github.com/prometheus/procfs v0.12.0 // indirect github.com/prometheus/statsd_exporter v0.22.7 // indirect github.com/quic-go/qpack v0.4.0 // indirect - github.com/quic-go/qtls-go1-20 v0.3.3 // indirect - github.com/quic-go/quic-go v0.38.1 // indirect - github.com/quic-go/webtransport-go v0.5.3 // indirect + github.com/quic-go/qtls-go1-20 v0.3.4 // indirect + github.com/quic-go/quic-go v0.39.3 // indirect + github.com/quic-go/webtransport-go v0.6.0 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/rs/cors v1.7.0 // indirect github.com/samber/lo v1.36.0 // indirect @@ -223,12 +222,13 @@ require ( go.opentelemetry.io/otel/metric v1.17.0 // indirect go.opentelemetry.io/proto/otlp v0.19.0 // indirect go.uber.org/atomic v1.11.0 // indirect + go.uber.org/mock v0.3.0 // indirect go4.org v0.0.0-20230225012048-214862532bf5 // indirect - golang.org/x/net v0.15.0 // indirect + golang.org/x/net v0.17.0 // indirect golang.org/x/oauth2 v0.8.0 // indirect golang.org/x/term v0.13.0 // indirect golang.org/x/text v0.13.0 // indirect - golang.org/x/tools v0.13.0 // indirect + golang.org/x/tools v0.14.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect gonum.org/v1/gonum v0.13.0 // indirect google.golang.org/appengine v1.6.7 // indirect diff --git a/go.sum b/go.sum index 69ae8aff6..c07381487 100644 --- a/go.sum +++ b/go.sum @@ -237,8 +237,6 @@ github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= -github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= -github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -290,8 +288,8 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20230821062121-407c9e7a662f h1:pDhu5sgp8yJlEF/g6osliIIpF9K4F5jvkULXa4daRDQ= -github.com/google/pprof v0.0.0-20230821062121-407c9e7a662f/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= +github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b h1:RMpPgZTSApbPf7xaVel+QkoGPRLFLrwFO89uDUHEGf0= +github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -329,8 +327,8 @@ github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/huin/goupnp v1.2.0 h1:uOKW26NG1hsSSbXIZ1IR7XP9Gjd1U8pnLaCMgntmkmY= -github.com/huin/goupnp v1.2.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= +github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= +github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs-shipyard/nopfs v0.0.12-0.20231027223058-cde3b5ba964c h1:17FO7HnKiFhO7iadu3zCgII+EblpdRmJt5qg9FqQo8Y= @@ -339,8 +337,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.14.0 h1:gwSGW3xqUbtUOdn71oqBknpBFKpQm352g3I+RkebrX0= -github.com/ipfs/boxo v0.14.0/go.mod h1:pu8HsZvuyYeYJsqtLDCoYSvy8rHj6vI3dlh8P0f83Zs= +github.com/ipfs/boxo v0.15.0 h1:BriLydj2nlK1nKeJQHxcKSuG5ZXcoutzhBklOtxC5pk= +github.com/ipfs/boxo v0.15.0/go.mod h1:X5ulcbR5Nh7sm3Db8+08AApUo6FsGC5mb23QDKAoB/M= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= @@ -379,8 +377,8 @@ github.com/ipfs/go-ds-measure v0.2.0 h1:sG4goQe0KDTccHMyT45CY1XyUbxe5VwTKpg2LjAp github.com/ipfs/go-ds-measure v0.2.0/go.mod h1:SEUD/rE2PwRa4IQEC5FuNAmjJCyYObZr9UvVh8V3JxE= github.com/ipfs/go-fs-lock v0.0.7 h1:6BR3dajORFrFTkb5EpCUFIAypsoxpGpDSVUdFwzgL9U= github.com/ipfs/go-fs-lock v0.0.7/go.mod h1:Js8ka+FNYmgQRLrRXzU3CB/+Csr1BwrRilEcvYrHhhc= -github.com/ipfs/go-graphsync v0.15.1 h1:7v4VfRQ/8pKzPuE0wHeMaWhKu8D/RlezIrzvGWIBtHQ= -github.com/ipfs/go-graphsync v0.15.1/go.mod h1:eUIYS0OKkdBbG4vHhfGkY3lZ7h1G5Dlwd+HxTCe18vA= +github.com/ipfs/go-graphsync v0.16.0 h1:0BX7whXlV13Y9FZ/jRg+xaGHaGYbtGxGppKD6tncw6k= +github.com/ipfs/go-graphsync v0.16.0/go.mod h1:WfbMW3hhmX5GQEQ+KJxsFzVJVBKgC5szfrYK7Zc7xIM= github.com/ipfs/go-ipfs-blockstore v1.3.0 h1:m2EXaWgwTzAfsmt5UdJ7Is6l4gJcaM/A12XwJyvYvMM= github.com/ipfs/go-ipfs-blockstore v1.3.0/go.mod h1:KgtZyc9fq+P2xJUiCAzbRdhhqJHvsw8u2Dlqy2MyRTE= github.com/ipfs/go-ipfs-blocksutil v0.0.1 h1:Eh/H4pc1hsvhzsQoMEP3Bke/aW5P5rVM1IWFJMcGIPQ= @@ -486,8 +484,8 @@ github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQL 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.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I= -github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/compress v1.17.2 h1:RlWWUY/Dr4fL8qk9YG7DTZ7PDgME2V4csBXA8L/ixi4= +github.com/klauspost/compress v1.17.2/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= @@ -519,8 +517,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.31.0 h1:LFShhP8F6xthWiBBq3euxbKjZsoRajVEyBS9snfHxYg= -github.com/libp2p/go-libp2p v0.31.0/go.mod h1:W/FEK1c/t04PbRH3fA9i5oucu5YcgrG0JVoBWT1B7Eg= +github.com/libp2p/go-libp2p v0.32.0 h1:86I4B7nBUPIyTgw3+5Ibq6K7DdKRCuZw8URCfPc1hQM= +github.com/libp2p/go-libp2p v0.32.0/go.mod h1:hXXC3kXPlBZ1eu8Q2hptGrMB4mZ3048JUoS4EKaHW5c= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= @@ -535,8 +533,8 @@ github.com/libp2p/go-libp2p-kbucket v0.3.1/go.mod h1:oyjT5O7tS9CQurok++ERgc46YLw github.com/libp2p/go-libp2p-kbucket v0.6.3 h1:p507271wWzpy2f1XxPzCQG9NiN6R6lHL9GiSErbQQo0= github.com/libp2p/go-libp2p-kbucket v0.6.3/go.mod h1:RCseT7AH6eJWxxk2ol03xtP9pEHetYSPXOaJnOiD8i0= github.com/libp2p/go-libp2p-peerstore v0.1.4/go.mod h1:+4BDbDiiKf4PzpANZDAT+knVdLxvqh7hXOujessqdzs= -github.com/libp2p/go-libp2p-pubsub v0.9.3 h1:ihcz9oIBMaCK9kcx+yHWm3mLAFBMAUsM4ux42aikDxo= -github.com/libp2p/go-libp2p-pubsub v0.9.3/go.mod h1:RYA7aM9jIic5VV47WXu4GkcRxRhrdElWf8xtyli+Dzc= +github.com/libp2p/go-libp2p-pubsub v0.10.0 h1:wS0S5FlISavMaAbxyQn3dxMOe2eegMfswM471RuHJwA= +github.com/libp2p/go-libp2p-pubsub v0.10.0/go.mod h1:1OxbaT/pFRO5h+Dpze8hdHQ63R0ke55XTs6b6NwLLkw= github.com/libp2p/go-libp2p-pubsub-router v0.6.0 h1:D30iKdlqDt5ZmLEYhHELCMRj8b4sFAqrUcshIUvVP/s= github.com/libp2p/go-libp2p-pubsub-router v0.6.0/go.mod h1:FY/q0/RBTKsLA7l4vqC2cbRbOvyDotg8PJQ7j8FDudE= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= @@ -584,8 +582,8 @@ github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOA github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= -github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= 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= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= @@ -596,8 +594,8 @@ github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyex github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= -github.com/miekg/dns v1.1.55 h1:GoQ4hpsj0nFLYe+bWiCToyrBEJXkQfOOIvFGFy0lEgo= -github.com/miekg/dns v1.1.55/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= +github.com/miekg/dns v1.1.56 h1:5imZaSeoRNvpM9SzWNhEcP9QliKiz20/dA2QabIGVnE= +github.com/miekg/dns v1.1.56/go.mod h1:cRm6Oo2C8TY9ZS/TqsSrseAcncm74lfK5G+ikN2SWWY= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c h1:bzE/A84HN25pxAuk9Eej1Kz9OUelF97nAc82bDquQI8= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c/go.mod h1:0SQS9kMwD2VsyFEB++InYyBJroV/FRmBgcydeSUcJms= github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= @@ -634,8 +632,8 @@ github.com/multiformats/go-multiaddr v0.1.0/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lg github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo= github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4= github.com/multiformats/go-multiaddr v0.4.0/go.mod h1:YcpyLH8ZPudLxQlemYBPhSm0/oCXAT8Z4mzFpyoPyRc= -github.com/multiformats/go-multiaddr v0.11.0 h1:XqGyJ8ufbCE0HmTDwx2kPdsrQ36AGPZNZX6s6xfJH10= -github.com/multiformats/go-multiaddr v0.11.0/go.mod h1:gWUm0QLR4thQ6+ZF6SXUw8YjtwQSPapICM+NmCkxHSM= +github.com/multiformats/go-multiaddr v0.12.0 h1:1QlibTFkoXJuDjjYsMHhE73TnzJQl8FSWatk/0gxGzE= +github.com/multiformats/go-multiaddr v0.12.0/go.mod h1:WmZXgObOQOYp9r3cslLlppkrz1FYSHmE834dfz/lWu8= github.com/multiformats/go-multiaddr-dns v0.3.0/go.mod h1:mNzQ4eTGDg0ll1N9jKPOUogZPoJ30W8a7zk66FQPpdQ= github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A= github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk= @@ -658,8 +656,8 @@ github.com/multiformats/go-multihash v0.0.15/go.mod h1:D6aZrWNLFTV/ynMpKsNtB40mJ github.com/multiformats/go-multihash v0.1.0/go.mod h1:RJlXsxt6vHGaia+S8We0ErjhojtKzPP2AH4+kYM7k84= github.com/multiformats/go-multihash v0.2.3 h1:7Lyc8XfX/IY2jWb/gI7JP+o7JEq9hOa7BFvVU9RSh+U= github.com/multiformats/go-multihash v0.2.3/go.mod h1:dXgKXCXjBzdscBLk9JkjINiEsCKRVch90MdaGiKsvSM= -github.com/multiformats/go-multistream v0.4.1 h1:rFy0Iiyn3YT0asivDUIR05leAdwZq3de4741sbiSdfo= -github.com/multiformats/go-multistream v0.4.1/go.mod h1:Mz5eykRVAjJWckE2U78c6xqdtyNUEhKSM0Lwar2p77Q= +github.com/multiformats/go-multistream v0.5.0 h1:5htLSLl7lvJk3xx3qT/8Zm9J4K8vEOf/QGkvOGQAyiE= +github.com/multiformats/go-multistream v0.5.0/go.mod h1:n6tMZiwiP2wUsR8DgfDWw1dydlEqV3l6N3/GBsX6ILA= github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/multiformats/go-varint v0.0.6/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= @@ -676,12 +674,12 @@ github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= -github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU= -github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM= +github.com/onsi/ginkgo/v2 v2.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4= +github.com/onsi/ginkgo/v2 v2.13.0/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.27.8 h1:gegWiwZjBsf2DgiSbf5hpokZ98JVDMcWkUiigk6/KXc= +github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.1.0 h1:HHUyrt9mwHUjtasSbXSMvs4cyFxh+Bll4AjJ9odEGpg= github.com/opencontainers/runtime-spec v1.1.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= @@ -748,12 +746,12 @@ github.com/prometheus/statsd_exporter v0.22.7 h1:7Pji/i2GuhK6Lu7DHrtTkFmNBCudCPT github.com/prometheus/statsd_exporter v0.22.7/go.mod h1:N/TevpjkIh9ccs6nuzY3jQn9dFqnUakOjnEuMPJJJnI= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= -github.com/quic-go/qtls-go1-20 v0.3.3 h1:17/glZSLI9P9fDAeyCHBFSWSqJcwx1byhLwP5eUIDCM= -github.com/quic-go/qtls-go1-20 v0.3.3/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= -github.com/quic-go/quic-go v0.38.1 h1:M36YWA5dEhEeT+slOu/SwMEucbYd0YFidxG3KlGPZaE= -github.com/quic-go/quic-go v0.38.1/go.mod h1:ijnZM7JsFIkp4cRyjxJNIzdSfCLmUMg9wdyhGmg+SN4= -github.com/quic-go/webtransport-go v0.5.3 h1:5XMlzemqB4qmOlgIus5zB45AcZ2kCgCy2EptUrfOPWU= -github.com/quic-go/webtransport-go v0.5.3/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= +github.com/quic-go/qtls-go1-20 v0.3.4 h1:MfFAPULvst4yoMgY9QmtpYmfij/em7O8UUi+bNVm7Cg= +github.com/quic-go/qtls-go1-20 v0.3.4/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= +github.com/quic-go/quic-go v0.39.3 h1:o3YB6t2SR+HU/pgwF29kJ6g4jJIJEwEZ8CKia1h1TKg= +github.com/quic-go/quic-go v0.39.3/go.mod h1:T09QsDQWjLiQ74ZmacDfqZmhY/NLnw5BC40MANNNZ1Q= +github.com/quic-go/webtransport-go v0.6.0 h1:CvNsKqc4W2HljHJnoT+rMmbRJybShZ0YPFDD3NxaZLY= +github.com/quic-go/webtransport-go v0.6.0/go.mod h1:9KjU4AEBqEQidGHNDkZrb8CAa1abRaosM2yGOyiikEc= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= @@ -943,12 +941,14 @@ go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/dig v1.17.0 h1:5Chju+tUvcC+N7N6EV08BJz41UZuO3BmHcN4A287ZLI= -go.uber.org/dig v1.17.0/go.mod h1:rTxpf7l5I0eBTlE6/9RL+lDybC7WFwY2QH55ZSjy1mU= -go.uber.org/fx v1.20.0 h1:ZMC/pnRvhsthOZh9MZjMq5U8Or3mA9zBSPaLnzs3ihQ= -go.uber.org/fx v1.20.0/go.mod h1:qCUj0btiR3/JnanEr1TYEePfSw6o/4qYJscgvzQ5Ub0= +go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= +go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= +go.uber.org/fx v1.20.1 h1:zVwVQGS8zYvhh9Xxcu4w1M6ESyeMzebzj2NbSayZ4Mk= +go.uber.org/fx v1.20.1/go.mod h1:iSYNbHf2y55acNCwCXKx7LbWb5WG1Bnue5RDXz1OREg= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= +go.uber.org/mock v0.3.0 h1:3mUxI1No2/60yUYax92Pt8eNOEecx2D3lcXZh2NEZJo= +go.uber.org/mock v0.3.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= @@ -994,8 +994,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g= -golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= +golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI= +golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1019,8 +1019,8 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= -golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY= +golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1069,8 +1069,8 @@ golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8= -golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= +golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1097,8 +1097,8 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= -golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ= +golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/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= @@ -1241,11 +1241,10 @@ golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ= -golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= +golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc= +golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 7593700c5..b10e8c00f 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -7,11 +7,11 @@ replace github.com/ipfs/kubo => ../../ require ( github.com/Kubuxu/gocovmerge v0.0.0-20161216165753-7ecaa51963cd github.com/golangci/golangci-lint v1.54.1 - github.com/ipfs/boxo v0.14.0 + github.com/ipfs/boxo v0.15.0 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 github.com/ipfs/go-datastore v0.6.0 - github.com/ipfs/go-graphsync v0.15.1 + github.com/ipfs/go-graphsync v0.16.0 github.com/ipfs/go-log v1.0.5 github.com/ipfs/hang-fds v0.1.0 github.com/ipfs/iptb v1.4.0 @@ -19,8 +19,8 @@ require ( github.com/ipld/go-ipld-prime v0.21.0 github.com/jbenet/go-random v0.0.0-20190219211222-123a90aedc0c github.com/jbenet/go-random-files v0.0.0-20190219210431-31b3f20ebded - github.com/libp2p/go-libp2p v0.31.0 - github.com/multiformats/go-multiaddr v0.11.0 + github.com/libp2p/go-libp2p v0.32.0 + github.com/multiformats/go-multiaddr v0.12.0 github.com/multiformats/go-multihash v0.2.3 gotest.tools/gotestsum v0.4.2 ) @@ -93,7 +93,6 @@ require ( github.com/godbus/dbus/v5 v5.1.0 // indirect github.com/gofrs/flock v0.8.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang/mock v1.6.0 // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2 // indirect github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a // indirect @@ -106,7 +105,7 @@ require ( github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4 // indirect github.com/google/go-cmp v0.5.9 // indirect github.com/google/gopacket v1.1.19 // indirect - github.com/google/pprof v0.0.0-20230821062121-407c9e7a662f // indirect + github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b // indirect github.com/google/uuid v1.3.1 // indirect github.com/gordonklaus/ineffassign v0.0.0-20230610083614-0e73809eb601 // indirect github.com/gorilla/websocket v1.5.0 // indirect @@ -123,7 +122,7 @@ require ( github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/hexops/gotextdiff v1.0.3 // indirect - github.com/huin/goupnp v1.2.0 // indirect + github.com/huin/goupnp v1.3.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/ipfs/bbloom v0.0.4 // indirect github.com/ipfs/go-bitfield v1.1.0 // indirect @@ -152,7 +151,7 @@ require ( github.com/kisielk/errcheck v1.6.3 // indirect github.com/kisielk/gotool v1.0.0 // indirect github.com/kkHAIKE/contextcheck v1.1.4 // indirect - github.com/klauspost/compress v1.16.7 // indirect + github.com/klauspost/compress v1.17.2 // indirect github.com/klauspost/cpuid/v2 v2.2.5 // indirect github.com/koron/go-ssdp v0.0.4 // indirect github.com/kulti/thelper v0.6.3 // indirect @@ -181,12 +180,12 @@ require ( github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect github.com/matoous/godox v0.0.0-20230222163458-006bad1f9d26 // indirect github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.19 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-runewidth v0.0.9 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/mbilski/exhaustivestruct v1.2.0 // indirect github.com/mgechev/revive v1.3.2 // indirect - github.com/miekg/dns v1.1.55 // indirect + github.com/miekg/dns v1.1.56 // indirect github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect github.com/minio/sha256-simd v1.0.1 // indirect @@ -200,7 +199,7 @@ require ( github.com/multiformats/go-multiaddr-fmt v0.1.0 // indirect github.com/multiformats/go-multibase v0.2.0 // indirect github.com/multiformats/go-multicodec v0.9.0 // indirect - github.com/multiformats/go-multistream v0.4.1 // indirect + github.com/multiformats/go-multistream v0.5.0 // indirect github.com/multiformats/go-varint v0.0.7 // indirect github.com/nakabonne/nestif v0.3.1 // indirect github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354 // indirect @@ -208,7 +207,7 @@ require ( github.com/nishanths/predeclared v0.2.2 // indirect github.com/nunnatsa/ginkgolinter v0.13.3 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect - github.com/onsi/ginkgo/v2 v2.11.0 // indirect + github.com/onsi/ginkgo/v2 v2.13.0 // indirect github.com/opencontainers/runtime-spec v1.1.0 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect @@ -227,9 +226,9 @@ require ( github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727 // indirect github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 // indirect github.com/quic-go/qpack v0.4.0 // indirect - github.com/quic-go/qtls-go1-20 v0.3.3 // indirect - github.com/quic-go/quic-go v0.38.1 // indirect - github.com/quic-go/webtransport-go v0.5.3 // indirect + github.com/quic-go/qtls-go1-20 v0.3.4 // indirect + github.com/quic-go/quic-go v0.39.3 // indirect + github.com/quic-go/webtransport-go v0.6.0 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/ryancurrah/gomodguard v1.3.0 // indirect @@ -281,20 +280,21 @@ require ( go.opentelemetry.io/otel/trace v1.19.0 // indirect go.tmz.dev/musttag v0.7.1 // indirect go.uber.org/atomic v1.11.0 // indirect - go.uber.org/dig v1.17.0 // indirect - go.uber.org/fx v1.20.0 // indirect + go.uber.org/dig v1.17.1 // indirect + go.uber.org/fx v1.20.1 // indirect + go.uber.org/mock v0.3.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.26.0 // indirect golang.org/x/crypto v0.14.0 // indirect - golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect + golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect golang.org/x/exp/typeparams v0.0.0-20230307190834-24139beb5833 // indirect - golang.org/x/mod v0.12.0 // indirect - golang.org/x/net v0.15.0 // indirect - golang.org/x/sync v0.3.0 // indirect + golang.org/x/mod v0.13.0 // indirect + golang.org/x/net v0.17.0 // indirect + golang.org/x/sync v0.4.0 // indirect golang.org/x/sys v0.13.0 // indirect golang.org/x/term v0.13.0 // indirect golang.org/x/text v0.13.0 // indirect - golang.org/x/tools v0.13.0 // indirect + golang.org/x/tools v0.14.0 // indirect gonum.org/v1/gonum v0.13.0 // indirect google.golang.org/protobuf v1.31.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 99ffc1795..1c01c6320 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -261,8 +261,6 @@ github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= -github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= -github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -336,8 +334,8 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20230821062121-407c9e7a662f h1:pDhu5sgp8yJlEF/g6osliIIpF9K4F5jvkULXa4daRDQ= -github.com/google/pprof v0.0.0-20230821062121-407c9e7a662f/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= +github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b h1:RMpPgZTSApbPf7xaVel+QkoGPRLFLrwFO89uDUHEGf0= +github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -390,16 +388,16 @@ github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/huin/goupnp v1.2.0 h1:uOKW26NG1hsSSbXIZ1IR7XP9Gjd1U8pnLaCMgntmkmY= -github.com/huin/goupnp v1.2.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= +github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= +github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.14.0 h1:gwSGW3xqUbtUOdn71oqBknpBFKpQm352g3I+RkebrX0= -github.com/ipfs/boxo v0.14.0/go.mod h1:pu8HsZvuyYeYJsqtLDCoYSvy8rHj6vI3dlh8P0f83Zs= +github.com/ipfs/boxo v0.15.0 h1:BriLydj2nlK1nKeJQHxcKSuG5ZXcoutzhBklOtxC5pk= +github.com/ipfs/boxo v0.15.0/go.mod h1:X5ulcbR5Nh7sm3Db8+08AApUo6FsGC5mb23QDKAoB/M= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs= @@ -415,8 +413,8 @@ github.com/ipfs/go-datastore v0.6.0 h1:JKyz+Gvz1QEZw0LsX1IBn+JFCJQH4SJVFtM4uWU0M github.com/ipfs/go-datastore v0.6.0/go.mod h1:rt5M3nNbSO/8q1t4LNkLyUwRs8HupMeN/8O4Vn9YAT8= github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk= github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps= -github.com/ipfs/go-graphsync v0.15.1 h1:7v4VfRQ/8pKzPuE0wHeMaWhKu8D/RlezIrzvGWIBtHQ= -github.com/ipfs/go-graphsync v0.15.1/go.mod h1:eUIYS0OKkdBbG4vHhfGkY3lZ7h1G5Dlwd+HxTCe18vA= +github.com/ipfs/go-graphsync v0.16.0 h1:0BX7whXlV13Y9FZ/jRg+xaGHaGYbtGxGppKD6tncw6k= +github.com/ipfs/go-graphsync v0.16.0/go.mod h1:WfbMW3hhmX5GQEQ+KJxsFzVJVBKgC5szfrYK7Zc7xIM= github.com/ipfs/go-ipfs-blockstore v1.3.0 h1:m2EXaWgwTzAfsmt5UdJ7Is6l4gJcaM/A12XwJyvYvMM= github.com/ipfs/go-ipfs-blockstore v1.3.0/go.mod h1:KgtZyc9fq+P2xJUiCAzbRdhhqJHvsw8u2Dlqy2MyRTE= github.com/ipfs/go-ipfs-blocksutil v0.0.1 h1:Eh/H4pc1hsvhzsQoMEP3Bke/aW5P5rVM1IWFJMcGIPQ= @@ -508,8 +506,8 @@ github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kkHAIKE/contextcheck v1.1.4 h1:B6zAaLhOEEcjvUgIYEqystmnFk1Oemn8bvJhbt0GMb8= github.com/kkHAIKE/contextcheck v1.1.4/go.mod h1:1+i/gWqokIa+dm31mqGLZhZJ7Uh44DJGZVmr6QRBNJg= -github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I= -github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/compress v1.17.2 h1:RlWWUY/Dr4fL8qk9YG7DTZ7PDgME2V4csBXA8L/ixi4= +github.com/klauspost/compress v1.17.2/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -544,8 +542,8 @@ github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38y github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.31.0 h1:LFShhP8F6xthWiBBq3euxbKjZsoRajVEyBS9snfHxYg= -github.com/libp2p/go-libp2p v0.31.0/go.mod h1:W/FEK1c/t04PbRH3fA9i5oucu5YcgrG0JVoBWT1B7Eg= +github.com/libp2p/go-libp2p v0.32.0 h1:86I4B7nBUPIyTgw3+5Ibq6K7DdKRCuZw8URCfPc1hQM= +github.com/libp2p/go-libp2p v0.32.0/go.mod h1:hXXC3kXPlBZ1eu8Q2hptGrMB4mZ3048JUoS4EKaHW5c= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-kad-dht v0.24.4 h1:ktNiJe7ffsJ1wX3ULpMCwXts99mPqGFSE/Qn1i8pErQ= @@ -589,8 +587,8 @@ github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovk github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= -github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= @@ -602,8 +600,8 @@ github.com/mgechev/revive v1.3.2 h1:Wb8NQKBaALBJ3xrrj4zpwJwqwNA6nDpyJSEQWcCka6U= github.com/mgechev/revive v1.3.2/go.mod h1:UCLtc7o5vg5aXCwdUTU1kEBQ1v+YXPAkYDIDXbrs5I0= github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= -github.com/miekg/dns v1.1.55 h1:GoQ4hpsj0nFLYe+bWiCToyrBEJXkQfOOIvFGFy0lEgo= -github.com/miekg/dns v1.1.55/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= +github.com/miekg/dns v1.1.56 h1:5imZaSeoRNvpM9SzWNhEcP9QliKiz20/dA2QabIGVnE= +github.com/miekg/dns v1.1.56/go.mod h1:cRm6Oo2C8TY9ZS/TqsSrseAcncm74lfK5G+ikN2SWWY= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c h1:bzE/A84HN25pxAuk9Eej1Kz9OUelF97nAc82bDquQI8= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c/go.mod h1:0SQS9kMwD2VsyFEB++InYyBJroV/FRmBgcydeSUcJms= github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= @@ -637,8 +635,8 @@ github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9 github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4= github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo= github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4= -github.com/multiformats/go-multiaddr v0.11.0 h1:XqGyJ8ufbCE0HmTDwx2kPdsrQ36AGPZNZX6s6xfJH10= -github.com/multiformats/go-multiaddr v0.11.0/go.mod h1:gWUm0QLR4thQ6+ZF6SXUw8YjtwQSPapICM+NmCkxHSM= +github.com/multiformats/go-multiaddr v0.12.0 h1:1QlibTFkoXJuDjjYsMHhE73TnzJQl8FSWatk/0gxGzE= +github.com/multiformats/go-multiaddr v0.12.0/go.mod h1:WmZXgObOQOYp9r3cslLlppkrz1FYSHmE834dfz/lWu8= github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A= github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk= github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E= @@ -652,8 +650,8 @@ github.com/multiformats/go-multihash v0.0.8/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa github.com/multiformats/go-multihash v0.0.13/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= github.com/multiformats/go-multihash v0.2.3 h1:7Lyc8XfX/IY2jWb/gI7JP+o7JEq9hOa7BFvVU9RSh+U= github.com/multiformats/go-multihash v0.2.3/go.mod h1:dXgKXCXjBzdscBLk9JkjINiEsCKRVch90MdaGiKsvSM= -github.com/multiformats/go-multistream v0.4.1 h1:rFy0Iiyn3YT0asivDUIR05leAdwZq3de4741sbiSdfo= -github.com/multiformats/go-multistream v0.4.1/go.mod h1:Mz5eykRVAjJWckE2U78c6xqdtyNUEhKSM0Lwar2p77Q= +github.com/multiformats/go-multistream v0.5.0 h1:5htLSLl7lvJk3xx3qT/8Zm9J4K8vEOf/QGkvOGQAyiE= +github.com/multiformats/go-multistream v0.5.0/go.mod h1:n6tMZiwiP2wUsR8DgfDWw1dydlEqV3l6N3/GBsX6ILA= github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8= @@ -676,10 +674,10 @@ github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU= -github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM= +github.com/onsi/ginkgo/v2 v2.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4= +github.com/onsi/ginkgo/v2 v2.13.0/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.27.8 h1:gegWiwZjBsf2DgiSbf5hpokZ98JVDMcWkUiigk6/KXc= +github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.1.0 h1:HHUyrt9mwHUjtasSbXSMvs4cyFxh+Bll4AjJ9odEGpg= github.com/opencontainers/runtime-spec v1.1.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= @@ -749,12 +747,12 @@ github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 h1:M8mH9eK4OUR4l github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567/go.mod h1:DWNGW8A4Y+GyBgPuaQJuWiy0XYftx4Xm/y5Jqk9I6VQ= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= -github.com/quic-go/qtls-go1-20 v0.3.3 h1:17/glZSLI9P9fDAeyCHBFSWSqJcwx1byhLwP5eUIDCM= -github.com/quic-go/qtls-go1-20 v0.3.3/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= -github.com/quic-go/quic-go v0.38.1 h1:M36YWA5dEhEeT+slOu/SwMEucbYd0YFidxG3KlGPZaE= -github.com/quic-go/quic-go v0.38.1/go.mod h1:ijnZM7JsFIkp4cRyjxJNIzdSfCLmUMg9wdyhGmg+SN4= -github.com/quic-go/webtransport-go v0.5.3 h1:5XMlzemqB4qmOlgIus5zB45AcZ2kCgCy2EptUrfOPWU= -github.com/quic-go/webtransport-go v0.5.3/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= +github.com/quic-go/qtls-go1-20 v0.3.4 h1:MfFAPULvst4yoMgY9QmtpYmfij/em7O8UUi+bNVm7Cg= +github.com/quic-go/qtls-go1-20 v0.3.4/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= +github.com/quic-go/quic-go v0.39.3 h1:o3YB6t2SR+HU/pgwF29kJ6g4jJIJEwEZ8CKia1h1TKg= +github.com/quic-go/quic-go v0.39.3/go.mod h1:T09QsDQWjLiQ74ZmacDfqZmhY/NLnw5BC40MANNNZ1Q= +github.com/quic-go/webtransport-go v0.6.0 h1:CvNsKqc4W2HljHJnoT+rMmbRJybShZ0YPFDD3NxaZLY= +github.com/quic-go/webtransport-go v0.6.0/go.mod h1:9KjU4AEBqEQidGHNDkZrb8CAa1abRaosM2yGOyiikEc= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= @@ -944,12 +942,14 @@ go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/dig v1.17.0 h1:5Chju+tUvcC+N7N6EV08BJz41UZuO3BmHcN4A287ZLI= -go.uber.org/dig v1.17.0/go.mod h1:rTxpf7l5I0eBTlE6/9RL+lDybC7WFwY2QH55ZSjy1mU= -go.uber.org/fx v1.20.0 h1:ZMC/pnRvhsthOZh9MZjMq5U8Or3mA9zBSPaLnzs3ihQ= -go.uber.org/fx v1.20.0/go.mod h1:qCUj0btiR3/JnanEr1TYEePfSw6o/4qYJscgvzQ5Ub0= +go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= +go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= +go.uber.org/fx v1.20.1 h1:zVwVQGS8zYvhh9Xxcu4w1M6ESyeMzebzj2NbSayZ4Mk= +go.uber.org/fx v1.20.1/go.mod h1:iSYNbHf2y55acNCwCXKx7LbWb5WG1Bnue5RDXz1OREg= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= +go.uber.org/mock v0.3.0 h1:3mUxI1No2/60yUYax92Pt8eNOEecx2D3lcXZh2NEZJo= +go.uber.org/mock v0.3.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= @@ -988,8 +988,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g= -golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= +golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI= +golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo= golang.org/x/exp/typeparams v0.0.0-20220428152302-39d4317da171/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/exp/typeparams v0.0.0-20230203172020-98cc5a0785f9/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/exp/typeparams v0.0.0-20230307190834-24139beb5833 h1:jWGQJV4niP+CCmFW9ekjA9Zx8vYORzOUH2/Nl5WPuLQ= @@ -1025,8 +1025,8 @@ golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91 golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= -golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY= +golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1074,8 +1074,8 @@ golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8= -golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= +golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1102,8 +1102,8 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= -golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ= +golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/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= @@ -1276,8 +1276,8 @@ golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= golang.org/x/tools v0.5.0/go.mod h1:N+Kgy78s5I24c24dU8OfWNEotWjutIs8SnJvn5IDq+k= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ= -golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= +golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc= +golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From 10eb459f84f0285f01c661acbd40a5c682a719b1 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Fri, 3 Nov 2023 08:37:51 +0100 Subject: [PATCH 0926/1212] feat: add WebRTC Direct support --- config/swarm.go | 11 ++-- core/node/libp2p/transport.go | 10 ++++ docs/changelogs/v0.24.md | 12 ++++ docs/config.md | 14 +++++ docs/examples/kubo-as-a-library/go.mod | 19 +++++++ docs/examples/kubo-as-a-library/go.sum | 77 ++++++++++++++++++++++++++ go.mod | 16 ++++++ go.sum | 76 +++++++++++++++++++++++++ test/cli/transports_test.go | 18 ++++++ 9 files changed, 248 insertions(+), 5 deletions(-) diff --git a/config/swarm.go b/config/swarm.go index 45b8a9a52..16c52b4a5 100644 --- a/config/swarm.go +++ b/config/swarm.go @@ -98,12 +98,13 @@ type Transports struct { // listen on a transport, add the transport to your Addresses.Swarm. Network struct { // All default to on. - QUIC Flag `json:",omitempty"` - TCP Flag `json:",omitempty"` - Websocket Flag `json:",omitempty"` - Relay Flag `json:",omitempty"` - // except WebTransport which is experimental and optin. + QUIC Flag `json:",omitempty"` + TCP Flag `json:",omitempty"` + Websocket Flag `json:",omitempty"` + Relay Flag `json:",omitempty"` WebTransport Flag `json:",omitempty"` + // except WebRTCDirect which is experimental and opt-in. + WebRTCDirect Flag `json:",omitempty"` } // Security specifies the transports used to encrypt insecure network diff --git a/core/node/libp2p/transport.go b/core/node/libp2p/transport.go index 8e04a63ff..797917b72 100644 --- a/core/node/libp2p/transport.go +++ b/core/node/libp2p/transport.go @@ -8,6 +8,7 @@ import ( "github.com/libp2p/go-libp2p/core/metrics" quic "github.com/libp2p/go-libp2p/p2p/transport/quic" "github.com/libp2p/go-libp2p/p2p/transport/tcp" + webrtc "github.com/libp2p/go-libp2p/p2p/transport/webrtc" "github.com/libp2p/go-libp2p/p2p/transport/websocket" webtransport "github.com/libp2p/go-libp2p/p2p/transport/webtransport" @@ -49,6 +50,15 @@ func Transports(tptConfig config.Transports) interface{} { opts.Opts = append(opts.Opts, libp2p.Transport(webtransport.New)) } + if tptConfig.Network.WebRTCDirect.WithDefault(false) { + if privateNetworkEnabled { + return opts, fmt.Errorf( + "WebRTC Direct transport does not support private networks, please disable Swarm.Transports.Network.WebRTCDirect", + ) + } + opts.Opts = append(opts.Opts, libp2p.Transport(webrtc.New)) + } + return opts, nil } } diff --git a/docs/changelogs/v0.24.md b/docs/changelogs/v0.24.md index 29d88d9cb..1a80e3437 100644 --- a/docs/changelogs/v0.24.md +++ b/docs/changelogs/v0.24.md @@ -10,6 +10,7 @@ - [Gateway: the root of the CARs are no longer meaningful](#gateway-the-root-of-the-cars-are-no-longer-meaningful) - [IPNS: improved publishing defaults](#ipns-improved-publishing-defaults) - [IPNS: record TTL is used for caching](#ipns-record-ttl-is-used-for-caching) + - [WebRTC Direct Transport](#webrtc-direct-transport) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -68,6 +69,17 @@ DHT, for updates. The TTL value in the IPNS record now serves as a hint for: These changes make it easier for rarely updated IPNS-hosted websites to be cached more efficiently and load faster in browser contexts. +#### WebRTC Direct Transport + +[WebRTC Direct](https://github.com/libp2p/go-libp2p/pull/2337) has now been introduced +in [`go-libp2p`](https://github.com/libp2p/go-libp2p/releases/tag/v0.32.0) v0.32.0. This +transport protocol allows browser nodes to connect to other nodes without special configuration, +such as TLS certificates. This can be useful for browsers that do not yet support +WebTransport, for example. + +Note that, at the moment, WebRTC Direct cannot be used to connect to a browser node to a +node that is behind a NAT or firewall. This is being worked on [`go-libp2p#2009`](https://github.com/libp2p/go-libp2p/issues/2009). + ### 📝 Changelog ### 👨‍👩‍👧‍👦 Contributors diff --git a/docs/config.md b/docs/config.md index e70b54b3a..1280ec9f4 100644 --- a/docs/config.md +++ b/docs/config.md @@ -159,6 +159,7 @@ config file at runtime. - [`Swarm.Transports.Network.QUIC`](#swarmtransportsnetworkquic) - [`Swarm.Transports.Network.Relay`](#swarmtransportsnetworkrelay) - [`Swarm.Transports.Network.WebTransport`](#swarmtransportsnetworkwebtransport) + - [`Swarm.Transports.Network.WebRTCDirect`](#swarmtransportsnetworkwebrtcdirect) - [`Swarm.Transports.Security`](#swarmtransportssecurity) - [`Swarm.Transports.Security.TLS`](#swarmtransportssecuritytls) - [`Swarm.Transports.Security.SECIO`](#swarmtransportssecuritysecio) @@ -2072,6 +2073,19 @@ Default: Enabled Type: `flag` +#### `Swarm.Transports.Network.WebRTCDirect` + +A new feature of [`go-libp2p`](https://github.com/libp2p/go-libp2p/releases/tag/v0.32.0) +is the [WebRTC Direct](https://github.com/libp2p/go-libp2p/pull/2337) transport. + +WebRTC Direct is a transport protocol that provides another way for browsers to connect to the rest of the libp2p network. WebRTC Direct allows for browser nodes to connect to other nodes without special configuration, such as TLS certificates. This can be useful for browser nodes that do not yet support WebTransport, for example. + +Note that, at the moment, WebRTC Direct cannot be used to connect to a browser node to a node that is behind a NAT or firewall. This is being worked on [`go-libp2p#2009`](https://github.com/libp2p/go-libp2p/issues/2009). + +Default: Disabled + +Type: `flag` + ### `Swarm.Transports.Security` Configuration section for libp2p _security_ transports. Transports enabled in diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index da95b3f70..5b129929c 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -30,6 +30,7 @@ require ( github.com/coreos/go-systemd/v22 v22.5.0 // indirect github.com/crackcomm/go-gitignore v0.0.0-20170627025303-887ab5e44cc3 // indirect github.com/cskr/pubsub v1.0.2 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect github.com/dgraph-io/badger v1.6.2 // indirect @@ -142,7 +143,24 @@ require ( github.com/openzipkin/zipkin-go v0.4.1 // indirect github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 // indirect + github.com/pion/datachannel v1.5.5 // indirect + github.com/pion/dtls/v2 v2.2.7 // indirect + github.com/pion/ice/v2 v2.3.6 // indirect + github.com/pion/interceptor v0.1.17 // indirect + github.com/pion/logging v0.2.2 // indirect + github.com/pion/mdns v0.0.7 // indirect + github.com/pion/randutil v0.1.0 // indirect + github.com/pion/rtcp v1.2.10 // indirect + github.com/pion/rtp v1.7.13 // indirect + github.com/pion/sctp v1.8.7 // indirect + github.com/pion/sdp/v3 v3.0.6 // indirect + github.com/pion/srtp/v2 v2.0.15 // indirect + github.com/pion/stun v0.6.0 // indirect + github.com/pion/transport/v2 v2.2.1 // indirect + github.com/pion/turn/v2 v2.1.0 // indirect + github.com/pion/webrtc/v3 v3.2.9 // indirect github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect github.com/polydawn/refmt v0.89.0 // indirect github.com/prometheus/client_golang v1.17.0 // indirect github.com/prometheus/client_model v0.5.0 // indirect @@ -155,6 +173,7 @@ require ( github.com/raulk/go-watchdog v1.3.0 // indirect github.com/samber/lo v1.36.0 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect + github.com/stretchr/testify v1.8.4 // indirect github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect github.com/ucarion/urlpath v0.0.0-20200424170820-7ccc79b76bbb // indirect github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 42bb1aa30..f5f0385e3 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -178,6 +178,7 @@ github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0= @@ -260,6 +261,7 @@ github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b/go.mod h1:czg5+yv1E0Z github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= @@ -591,16 +593,20 @@ github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJE github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= +github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/ginkgo/v2 v2.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4= github.com/onsi/ginkgo/v2 v2.13.0/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.1.0 h1:HHUyrt9mwHUjtasSbXSMvs4cyFxh+Bll4AjJ9odEGpg= @@ -617,6 +623,45 @@ github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhM github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 h1:1/WtZae0yGtPq+TI6+Tv1WTxkukpXeMlviSxvL7SRgk= github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9/go.mod h1:x3N5drFsm2uilKKuuYo6LdyD8vZAW55sH/9w+pbo1sw= +github.com/pion/datachannel v1.5.5 h1:10ef4kwdjije+M9d7Xm9im2Y3O6A6ccQb0zcqZcJew8= +github.com/pion/datachannel v1.5.5/go.mod h1:iMz+lECmfdCMqFRhXhcA/219B0SQlbpoR2V118yimL0= +github.com/pion/dtls/v2 v2.2.7 h1:cSUBsETxepsCSFSxC3mc/aDo14qQLMSL+O6IjG28yV8= +github.com/pion/dtls/v2 v2.2.7/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s= +github.com/pion/ice/v2 v2.3.6 h1:Jgqw36cAud47iD+N6rNX225uHvrgWtAlHfVyOQc3Heg= +github.com/pion/ice/v2 v2.3.6/go.mod h1:9/TzKDRwBVAPsC+YOrKH/e3xDrubeTRACU9/sHQarsU= +github.com/pion/interceptor v0.1.17 h1:prJtgwFh/gB8zMqGZoOgJPHivOwVAp61i2aG61Du/1w= +github.com/pion/interceptor v0.1.17/go.mod h1:SY8kpmfVBvrbUzvj2bsXz7OJt5JvmVNZ+4Kjq7FcwrI= +github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY= +github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms= +github.com/pion/mdns v0.0.7 h1:P0UB4Sr6xDWEox0kTVxF0LmQihtCbSAdW0H2nEgkA3U= +github.com/pion/mdns v0.0.7/go.mod h1:4iP2UbeFhLI/vWju/bw6ZfwjJzk0z8DNValjGxR/dD8= +github.com/pion/randutil v0.1.0 h1:CFG1UdESneORglEsnimhUjf33Rwjubwj6xfiOXBa3mA= +github.com/pion/randutil v0.1.0/go.mod h1:XcJrSMMbbMRhASFVOlj/5hQial/Y8oH/HVo7TBZq+j8= +github.com/pion/rtcp v1.2.10 h1:nkr3uj+8Sp97zyItdN60tE/S6vk4al5CPRR6Gejsdjc= +github.com/pion/rtcp v1.2.10/go.mod h1:ztfEwXZNLGyF1oQDttz/ZKIBaeeg/oWbRYqzBM9TL1I= +github.com/pion/rtp v1.7.13 h1:qcHwlmtiI50t1XivvoawdCGTP4Uiypzfrsap+bijcoA= +github.com/pion/rtp v1.7.13/go.mod h1:bDb5n+BFZxXx0Ea7E5qe+klMuqiBrP+w8XSjiWtCUko= +github.com/pion/sctp v1.8.5/go.mod h1:SUFFfDpViyKejTAdwD1d/HQsCu+V/40cCs2nZIvC3s0= +github.com/pion/sctp v1.8.7 h1:JnABvFakZueGAn4KU/4PSKg+GWbF6QWbKTWZOSGJjXw= +github.com/pion/sctp v1.8.7/go.mod h1:g1Ul+ARqZq5JEmoFy87Q/4CePtKnTJ1QCL9dBBdN6AU= +github.com/pion/sdp/v3 v3.0.6 h1:WuDLhtuFUUVpTfus9ILC4HRyHsW6TdugjEX/QY9OiUw= +github.com/pion/sdp/v3 v3.0.6/go.mod h1:iiFWFpQO8Fy3S5ldclBkpXqmWy02ns78NOKoLLL0YQw= +github.com/pion/srtp/v2 v2.0.15 h1:+tqRtXGsGwHC0G0IUIAzRmdkHvriF79IHVfZGfHrQoA= +github.com/pion/srtp/v2 v2.0.15/go.mod h1:b/pQOlDrbB0HEH5EUAQXzSYxikFbNcNuKmF8tM0hCtw= +github.com/pion/stun v0.4.0/go.mod h1:QPsh1/SbXASntw3zkkrIk3ZJVKz4saBY2G7S10P3wCw= +github.com/pion/stun v0.6.0 h1:JHT/2iyGDPrFWE8NNC15wnddBN8KifsEDw8swQmrEmU= +github.com/pion/stun v0.6.0/go.mod h1:HPqcfoeqQn9cuaet7AOmB5e5xkObu9DwBdurwLKO9oA= +github.com/pion/transport v0.14.1 h1:XSM6olwW+o8J4SCmOBb/BpwZypkHeyM0PGFCxNQBr40= +github.com/pion/transport v0.14.1/go.mod h1:4tGmbk00NeYA3rUa9+n+dzCCoKkcy3YlYb99Jn2fNnI= +github.com/pion/transport/v2 v2.0.0/go.mod h1:HS2MEBJTwD+1ZI2eSXSvHJx/HnzQqRy2/LXxt6eVMHc= +github.com/pion/transport/v2 v2.1.0/go.mod h1:AdSw4YBZVDkZm8fpoz+fclXyQwANWmZAlDuQdctTThQ= +github.com/pion/transport/v2 v2.2.0/go.mod h1:AdSw4YBZVDkZm8fpoz+fclXyQwANWmZAlDuQdctTThQ= +github.com/pion/transport/v2 v2.2.1 h1:7qYnCBlpgSJNYMbLCKuSY9KbQdBFoETvPNETv0y4N7c= +github.com/pion/transport/v2 v2.2.1/go.mod h1:cXXWavvCnFF6McHTft3DWS9iic2Mftcz1Aq29pGcU5g= +github.com/pion/turn/v2 v2.1.0 h1:5wGHSgGhJhP/RpabkUb/T9PdsAjkGLS6toYz5HNzoSI= +github.com/pion/turn/v2 v2.1.0/go.mod h1:yrT5XbXSGX1VFSF31A3c1kCNB5bBZgk/uu5LET162qs= +github.com/pion/webrtc/v3 v3.2.9 h1:U8NSjQDlZZ+Iy/hg42Q/u6mhEVSXYvKrOIZiZwYTfLc= +github.com/pion/webrtc/v3 v3.2.9/go.mod h1:gjQLMZeyN3jXBGdxGmUYCyKjOuYX/c99BDjGqmadq0A= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -658,6 +703,7 @@ github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd/go.mod h1:hPqNNc0+uJM6H+SuU8sEs5K5IQeKccPqeSjfgcKGgPk= github.com/samber/lo v1.36.0 h1:4LaOxH1mHnbDGhTVE0i1z8v/lWaQW8AIfOD3HU4mSaw= github.com/samber/lo v1.36.0/go.mod h1:HLeWcJRRyLKp3+/XBJvOrerCQn9mhdKMHyd7IRlgeQ8= +github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY= github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM= @@ -719,7 +765,10 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= @@ -845,6 +894,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= +golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -882,6 +933,7 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY= golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -923,9 +975,16 @@ golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210423184538-5f58ad60dda6/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= +golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -948,6 +1007,7 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ= golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -996,6 +1056,7 @@ golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1007,14 +1068,24 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1023,7 +1094,11 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1079,9 +1154,11 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc= golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/go.mod b/go.mod index b8fe887d0..5efc4d526 100644 --- a/go.mod +++ b/go.mod @@ -185,6 +185,22 @@ require ( github.com/opencontainers/runtime-spec v1.1.0 // indirect github.com/openzipkin/zipkin-go v0.4.1 // indirect github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 // indirect + github.com/pion/datachannel v1.5.5 // indirect + github.com/pion/dtls/v2 v2.2.7 // indirect + github.com/pion/ice/v2 v2.3.6 // indirect + github.com/pion/interceptor v0.1.17 // indirect + github.com/pion/logging v0.2.2 // indirect + github.com/pion/mdns v0.0.7 // indirect + github.com/pion/randutil v0.1.0 // indirect + github.com/pion/rtcp v1.2.10 // indirect + github.com/pion/rtp v1.7.13 // indirect + github.com/pion/sctp v1.8.7 // indirect + github.com/pion/sdp/v3 v3.0.6 // indirect + github.com/pion/srtp/v2 v2.0.15 // indirect + github.com/pion/stun v0.6.0 // indirect + github.com/pion/transport/v2 v2.2.1 // indirect + github.com/pion/turn/v2 v2.1.0 // indirect + github.com/pion/webrtc/v3 v3.2.9 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/polydawn/refmt v0.89.0 // indirect github.com/prometheus/client_model v0.5.0 // indirect diff --git a/go.sum b/go.sum index c07381487..fed65f74a 100644 --- a/go.sum +++ b/go.sum @@ -208,6 +208,7 @@ github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbV github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0= @@ -293,6 +294,7 @@ github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b/go.mod h1:czg5+yv1E0Z github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= @@ -669,16 +671,20 @@ github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJE github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= +github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/ginkgo/v2 v2.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4= github.com/onsi/ginkgo/v2 v2.13.0/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.1.0 h1:HHUyrt9mwHUjtasSbXSMvs4cyFxh+Bll4AjJ9odEGpg= @@ -695,6 +701,45 @@ github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhM github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 h1:1/WtZae0yGtPq+TI6+Tv1WTxkukpXeMlviSxvL7SRgk= github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9/go.mod h1:x3N5drFsm2uilKKuuYo6LdyD8vZAW55sH/9w+pbo1sw= +github.com/pion/datachannel v1.5.5 h1:10ef4kwdjije+M9d7Xm9im2Y3O6A6ccQb0zcqZcJew8= +github.com/pion/datachannel v1.5.5/go.mod h1:iMz+lECmfdCMqFRhXhcA/219B0SQlbpoR2V118yimL0= +github.com/pion/dtls/v2 v2.2.7 h1:cSUBsETxepsCSFSxC3mc/aDo14qQLMSL+O6IjG28yV8= +github.com/pion/dtls/v2 v2.2.7/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s= +github.com/pion/ice/v2 v2.3.6 h1:Jgqw36cAud47iD+N6rNX225uHvrgWtAlHfVyOQc3Heg= +github.com/pion/ice/v2 v2.3.6/go.mod h1:9/TzKDRwBVAPsC+YOrKH/e3xDrubeTRACU9/sHQarsU= +github.com/pion/interceptor v0.1.17 h1:prJtgwFh/gB8zMqGZoOgJPHivOwVAp61i2aG61Du/1w= +github.com/pion/interceptor v0.1.17/go.mod h1:SY8kpmfVBvrbUzvj2bsXz7OJt5JvmVNZ+4Kjq7FcwrI= +github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY= +github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms= +github.com/pion/mdns v0.0.7 h1:P0UB4Sr6xDWEox0kTVxF0LmQihtCbSAdW0H2nEgkA3U= +github.com/pion/mdns v0.0.7/go.mod h1:4iP2UbeFhLI/vWju/bw6ZfwjJzk0z8DNValjGxR/dD8= +github.com/pion/randutil v0.1.0 h1:CFG1UdESneORglEsnimhUjf33Rwjubwj6xfiOXBa3mA= +github.com/pion/randutil v0.1.0/go.mod h1:XcJrSMMbbMRhASFVOlj/5hQial/Y8oH/HVo7TBZq+j8= +github.com/pion/rtcp v1.2.10 h1:nkr3uj+8Sp97zyItdN60tE/S6vk4al5CPRR6Gejsdjc= +github.com/pion/rtcp v1.2.10/go.mod h1:ztfEwXZNLGyF1oQDttz/ZKIBaeeg/oWbRYqzBM9TL1I= +github.com/pion/rtp v1.7.13 h1:qcHwlmtiI50t1XivvoawdCGTP4Uiypzfrsap+bijcoA= +github.com/pion/rtp v1.7.13/go.mod h1:bDb5n+BFZxXx0Ea7E5qe+klMuqiBrP+w8XSjiWtCUko= +github.com/pion/sctp v1.8.5/go.mod h1:SUFFfDpViyKejTAdwD1d/HQsCu+V/40cCs2nZIvC3s0= +github.com/pion/sctp v1.8.7 h1:JnABvFakZueGAn4KU/4PSKg+GWbF6QWbKTWZOSGJjXw= +github.com/pion/sctp v1.8.7/go.mod h1:g1Ul+ARqZq5JEmoFy87Q/4CePtKnTJ1QCL9dBBdN6AU= +github.com/pion/sdp/v3 v3.0.6 h1:WuDLhtuFUUVpTfus9ILC4HRyHsW6TdugjEX/QY9OiUw= +github.com/pion/sdp/v3 v3.0.6/go.mod h1:iiFWFpQO8Fy3S5ldclBkpXqmWy02ns78NOKoLLL0YQw= +github.com/pion/srtp/v2 v2.0.15 h1:+tqRtXGsGwHC0G0IUIAzRmdkHvriF79IHVfZGfHrQoA= +github.com/pion/srtp/v2 v2.0.15/go.mod h1:b/pQOlDrbB0HEH5EUAQXzSYxikFbNcNuKmF8tM0hCtw= +github.com/pion/stun v0.4.0/go.mod h1:QPsh1/SbXASntw3zkkrIk3ZJVKz4saBY2G7S10P3wCw= +github.com/pion/stun v0.6.0 h1:JHT/2iyGDPrFWE8NNC15wnddBN8KifsEDw8swQmrEmU= +github.com/pion/stun v0.6.0/go.mod h1:HPqcfoeqQn9cuaet7AOmB5e5xkObu9DwBdurwLKO9oA= +github.com/pion/transport v0.14.1 h1:XSM6olwW+o8J4SCmOBb/BpwZypkHeyM0PGFCxNQBr40= +github.com/pion/transport v0.14.1/go.mod h1:4tGmbk00NeYA3rUa9+n+dzCCoKkcy3YlYb99Jn2fNnI= +github.com/pion/transport/v2 v2.0.0/go.mod h1:HS2MEBJTwD+1ZI2eSXSvHJx/HnzQqRy2/LXxt6eVMHc= +github.com/pion/transport/v2 v2.1.0/go.mod h1:AdSw4YBZVDkZm8fpoz+fclXyQwANWmZAlDuQdctTThQ= +github.com/pion/transport/v2 v2.2.0/go.mod h1:AdSw4YBZVDkZm8fpoz+fclXyQwANWmZAlDuQdctTThQ= +github.com/pion/transport/v2 v2.2.1 h1:7qYnCBlpgSJNYMbLCKuSY9KbQdBFoETvPNETv0y4N7c= +github.com/pion/transport/v2 v2.2.1/go.mod h1:cXXWavvCnFF6McHTft3DWS9iic2Mftcz1Aq29pGcU5g= +github.com/pion/turn/v2 v2.1.0 h1:5wGHSgGhJhP/RpabkUb/T9PdsAjkGLS6toYz5HNzoSI= +github.com/pion/turn/v2 v2.1.0/go.mod h1:yrT5XbXSGX1VFSF31A3c1kCNB5bBZgk/uu5LET162qs= +github.com/pion/webrtc/v3 v3.2.9 h1:U8NSjQDlZZ+Iy/hg42Q/u6mhEVSXYvKrOIZiZwYTfLc= +github.com/pion/webrtc/v3 v3.2.9/go.mod h1:gjQLMZeyN3jXBGdxGmUYCyKjOuYX/c99BDjGqmadq0A= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -765,6 +810,7 @@ github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd/go.mod h1:hPqNNc0+uJM6H+SuU8sEs5K5IQeKccPqeSjfgcKGgPk= github.com/samber/lo v1.36.0 h1:4LaOxH1mHnbDGhTVE0i1z8v/lWaQW8AIfOD3HU4mSaw= github.com/samber/lo v1.36.0/go.mod h1:HLeWcJRRyLKp3+/XBJvOrerCQn9mhdKMHyd7IRlgeQ8= +github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY= github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM= @@ -828,6 +874,8 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stvp/go-udp-testing v0.0.0-20201019212854-469649b16807/go.mod h1:7jxmlfBCDBXRzr0eAQJ48XC1hBu1np4CS5+cHEYfwpc= @@ -982,6 +1030,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= +golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1019,6 +1069,7 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY= golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1063,12 +1114,19 @@ golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210423184538-5f58ad60dda6/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= +golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1097,6 +1155,7 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ= golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1150,6 +1209,7 @@ golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1166,14 +1226,24 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220708085239-5a0f0661e09d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1184,7 +1254,11 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1240,9 +1314,11 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc= golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/test/cli/transports_test.go b/test/cli/transports_test.go index d37c78aad..c1642c602 100644 --- a/test/cli/transports_test.go +++ b/test/cli/transports_test.go @@ -58,6 +58,7 @@ func TestTransports(t *testing.T) { cfg.Swarm.Transports.Network.QUIC = config.False cfg.Swarm.Transports.Network.Relay = config.False cfg.Swarm.Transports.Network.WebTransport = config.False + cfg.Swarm.Transports.Network.WebRTCDirect = config.False cfg.Swarm.Transports.Network.Websocket = config.False }) }) @@ -148,4 +149,21 @@ func TestTransports(t *testing.T) { nodes.StartDaemons().Connect() runTests(nodes) }) + + t.Run("WebRTC Direct", func(t *testing.T) { + t.Parallel() + nodes := harness.NewT(t).NewNodes(5).Init() + nodes.ForEachPar(func(n *harness.Node) { + n.UpdateConfig(func(cfg *config.Config) { + cfg.Addresses.Swarm = []string{"/ip4/127.0.0.1/udp/0/webrtc-direct"} + cfg.Swarm.Transports.Network.TCP = config.False + cfg.Swarm.Transports.Network.QUIC = config.False + cfg.Swarm.Transports.Network.WebTransport = config.False + cfg.Swarm.Transports.Network.WebRTCDirect = config.True + }) + }) + disableRouting(nodes) + nodes.StartDaemons().Connect() + runTests(nodes) + }) } From a87e305793283184862dd6752c88a6f3b60f19a2 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Fri, 3 Nov 2023 14:49:35 +0100 Subject: [PATCH 0927/1212] docs: make it clear Web RTC Direct is experimental --- docs/changelogs/v0.24.md | 4 ++-- docs/config.md | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/changelogs/v0.24.md b/docs/changelogs/v0.24.md index 1a80e3437..34a8490b0 100644 --- a/docs/changelogs/v0.24.md +++ b/docs/changelogs/v0.24.md @@ -10,7 +10,7 @@ - [Gateway: the root of the CARs are no longer meaningful](#gateway-the-root-of-the-cars-are-no-longer-meaningful) - [IPNS: improved publishing defaults](#ipns-improved-publishing-defaults) - [IPNS: record TTL is used for caching](#ipns-record-ttl-is-used-for-caching) - - [WebRTC Direct Transport](#webrtc-direct-transport) + - [Experimental Transport: WebRTC Direct](#experimental-transport-webrtc-direct) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -69,7 +69,7 @@ DHT, for updates. The TTL value in the IPNS record now serves as a hint for: These changes make it easier for rarely updated IPNS-hosted websites to be cached more efficiently and load faster in browser contexts. -#### WebRTC Direct Transport +#### Experimental Transport: WebRTC Direct [WebRTC Direct](https://github.com/libp2p/go-libp2p/pull/2337) has now been introduced in [`go-libp2p`](https://github.com/libp2p/go-libp2p/releases/tag/v0.32.0) v0.32.0. This diff --git a/docs/config.md b/docs/config.md index 1280ec9f4..1c8b0ed86 100644 --- a/docs/config.md +++ b/docs/config.md @@ -2075,6 +2075,8 @@ Type: `flag` #### `Swarm.Transports.Network.WebRTCDirect` +**Experimental:** the support for WebRTC Direct is currently experimental. + A new feature of [`go-libp2p`](https://github.com/libp2p/go-libp2p/releases/tag/v0.32.0) is the [WebRTC Direct](https://github.com/libp2p/go-libp2p/pull/2337) transport. From bd06ef73d898a6e19569f080c44b97fa1927d3c8 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Fri, 3 Nov 2023 13:51:01 +0000 Subject: [PATCH 0928/1212] chore: update version --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index cb9d87a61..5cf3be25e 100644 --- a/version.go +++ b/version.go @@ -11,7 +11,7 @@ import ( var CurrentCommit string // CurrentVersionNumber is the current application's version literal. -const CurrentVersionNumber = "0.24.0-rc1" +const CurrentVersionNumber = "0.24.0-rc2" const ApiVersion = "/kubo/" + CurrentVersionNumber + "/" //nolint From f17a06419355afbae3cdb1675675500fa5e17b9d Mon Sep 17 00:00:00 2001 From: Jonas Keunecke Date: Mon, 6 Nov 2023 00:49:12 +0100 Subject: [PATCH 0929/1212] docs/config: remove extra commas in PublicGateways example entries --- docs/config.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/config.md b/docs/config.md index 1c8b0ed86..630532381 100644 --- a/docs/config.md +++ b/docs/config.md @@ -761,7 +761,7 @@ between content roots. "PublicGateways": { "dweb.link": { "UseSubdomains": true, - "Paths": ["/ipfs", "/ipns"], + "Paths": ["/ipfs", "/ipns"] } } } @@ -776,7 +776,7 @@ between content roots. "PublicGateways": { "ipfs.io": { "UseSubdomains": false, - "Paths": ["/ipfs", "/ipns", "/api"], + "Paths": ["/ipfs", "/ipns", "/api"] } } } From 63e89d4987294b09e55ee3571fb945efdf1539ac Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Mon, 6 Nov 2023 15:24:06 +0100 Subject: [PATCH 0930/1212] docs: fix accelerated-dht-client --- docs/experimental-features.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/experimental-features.md b/docs/experimental-features.md index 1f02dc3c8..6826a38c2 100644 --- a/docs/experimental-features.md +++ b/docs/experimental-features.md @@ -663,3 +663,7 @@ ipfs config --json Experimental.GatewayOverLibp2p true - [ ] Needs UX work for exposing non-recursive "HTTP transport" (NoFetch) over both libp2p and plain TCP (and sharing the configuration) - [ ] Needs a mechanism for HTTP handler to signal supported features ([IPIP-425](https://github.com/ipfs/specs/pull/425)) - [ ] Needs an option for Kubo to detect peers that have it enabled and prefer HTTP transport before falling back to bitswap (and use CAR if peer supports dag-scope=entity from [IPIP-402](https://github.com/ipfs/specs/pull/402)) + +## Accelerated DHT Client + +This feature now lives at [`Routing.AcceleratedDHTClient`](https://github.com/ipfs/kubo/blob/master/docs/config.md#routingaccelerateddhtclient). From 068f17650d49f48e8ed179e173a21745013690ff Mon Sep 17 00:00:00 2001 From: Jorropo Date: Tue, 7 Nov 2023 18:10:59 +0100 Subject: [PATCH 0931/1212] chore: update go-libp2p --- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- test/dependencies/go.mod | 2 +- test/dependencies/go.sum | 4 ++-- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 5b129929c..a370e26a3 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -9,7 +9,7 @@ replace github.com/ipfs/kubo => ./../../.. require ( github.com/ipfs/boxo v0.15.0 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 - github.com/libp2p/go-libp2p v0.32.0 + github.com/libp2p/go-libp2p v0.32.1 github.com/multiformats/go-multiaddr v0.12.0 ) diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index f5f0385e3..527925973 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -463,8 +463,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.32.0 h1:86I4B7nBUPIyTgw3+5Ibq6K7DdKRCuZw8URCfPc1hQM= -github.com/libp2p/go-libp2p v0.32.0/go.mod h1:hXXC3kXPlBZ1eu8Q2hptGrMB4mZ3048JUoS4EKaHW5c= +github.com/libp2p/go-libp2p v0.32.1 h1:wy1J4kZIZxOaej6NveTWCZmHiJ/kY7GoAqXgqNCnPps= +github.com/libp2p/go-libp2p v0.32.1/go.mod h1:hXXC3kXPlBZ1eu8Q2hptGrMB4mZ3048JUoS4EKaHW5c= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= diff --git a/go.mod b/go.mod index 5efc4d526..b4797b84a 100644 --- a/go.mod +++ b/go.mod @@ -47,7 +47,7 @@ require ( github.com/jbenet/goprocess v0.1.4 github.com/julienschmidt/httprouter v1.3.0 github.com/libp2p/go-doh-resolver v0.4.0 - github.com/libp2p/go-libp2p v0.32.0 + github.com/libp2p/go-libp2p v0.32.1 github.com/libp2p/go-libp2p-http v0.5.0 github.com/libp2p/go-libp2p-kad-dht v0.24.4 github.com/libp2p/go-libp2p-kbucket v0.6.3 diff --git a/go.sum b/go.sum index fed65f74a..0a52cb585 100644 --- a/go.sum +++ b/go.sum @@ -519,8 +519,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.32.0 h1:86I4B7nBUPIyTgw3+5Ibq6K7DdKRCuZw8URCfPc1hQM= -github.com/libp2p/go-libp2p v0.32.0/go.mod h1:hXXC3kXPlBZ1eu8Q2hptGrMB4mZ3048JUoS4EKaHW5c= +github.com/libp2p/go-libp2p v0.32.1 h1:wy1J4kZIZxOaej6NveTWCZmHiJ/kY7GoAqXgqNCnPps= +github.com/libp2p/go-libp2p v0.32.1/go.mod h1:hXXC3kXPlBZ1eu8Q2hptGrMB4mZ3048JUoS4EKaHW5c= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index b10e8c00f..dd6346b62 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -19,7 +19,7 @@ require ( github.com/ipld/go-ipld-prime v0.21.0 github.com/jbenet/go-random v0.0.0-20190219211222-123a90aedc0c github.com/jbenet/go-random-files v0.0.0-20190219210431-31b3f20ebded - github.com/libp2p/go-libp2p v0.32.0 + github.com/libp2p/go-libp2p v0.32.1 github.com/multiformats/go-multiaddr v0.12.0 github.com/multiformats/go-multihash v0.2.3 gotest.tools/gotestsum v0.4.2 diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 1c01c6320..8c9012722 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -542,8 +542,8 @@ github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38y github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.32.0 h1:86I4B7nBUPIyTgw3+5Ibq6K7DdKRCuZw8URCfPc1hQM= -github.com/libp2p/go-libp2p v0.32.0/go.mod h1:hXXC3kXPlBZ1eu8Q2hptGrMB4mZ3048JUoS4EKaHW5c= +github.com/libp2p/go-libp2p v0.32.1 h1:wy1J4kZIZxOaej6NveTWCZmHiJ/kY7GoAqXgqNCnPps= +github.com/libp2p/go-libp2p v0.32.1/go.mod h1:hXXC3kXPlBZ1eu8Q2hptGrMB4mZ3048JUoS4EKaHW5c= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-kad-dht v0.24.4 h1:ktNiJe7ffsJ1wX3ULpMCwXts99mPqGFSE/Qn1i8pErQ= From 9371d18b5325030807abc1c064efc36055205cf3 Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Wed, 8 Nov 2023 01:07:10 -0500 Subject: [PATCH 0932/1212] fixes to routing put command (#10205) * fix(commands): routing put command returns the IPNS ID rather than the host's ID * fix(commands): routing put command errors with the allow-offline hint if the error is an offline error * fix: test expects correct error message --------- Co-authored-by: Henrique Dias --- core/commands/routing.go | 7 ++++--- test/cli/dht_legacy_test.go | 2 +- test/cli/routing_dht_test.go | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/core/commands/routing.go b/core/commands/routing.go index 6d0ddb1c8..99aa4a78d 100644 --- a/core/commands/routing.go +++ b/core/commands/routing.go @@ -14,6 +14,7 @@ import ( iface "github.com/ipfs/boxo/coreiface" "github.com/ipfs/boxo/coreiface/options" dag "github.com/ipfs/boxo/ipld/merkledag" + "github.com/ipfs/boxo/ipns" cid "github.com/ipfs/go-cid" cmds "github.com/ipfs/go-ipfs-cmds" ipld "github.com/ipfs/go-ipld-format" @@ -451,12 +452,12 @@ identified by QmFoo. options.Put.AllowOffline(allowOffline), } - err = api.Routing().Put(req.Context, req.Arguments[0], data, opts...) + ipnsName, err := ipns.NameFromString(req.Arguments[0]) if err != nil { return err } - id, err := api.Key().Self(req.Context) + err = api.Routing().Put(req.Context, req.Arguments[0], data, opts...) if err != nil { if err == iface.ErrOffline { err = errAllowOffline @@ -466,7 +467,7 @@ identified by QmFoo. return res.Emit(routing.QueryEvent{ Type: routing.Value, - ID: id.ID(), + ID: ipnsName.Peer(), }) }, Encoders: cmds.EncoderMap{ diff --git a/test/cli/dht_legacy_test.go b/test/cli/dht_legacy_test.go index 2b90d164c..cfcb4f0cd 100644 --- a/test/cli/dht_legacy_test.go +++ b/test/cli/dht_legacy_test.go @@ -131,7 +131,7 @@ func TestLegacyDHT(t *testing.T) { node.WriteBytes("foo", []byte("foo")) res := node.RunIPFS("dht", "put", "/ipns/"+node.PeerID().String(), "foo") assert.Equal(t, 1, res.ExitCode()) - assert.Contains(t, res.Stderr.String(), "this action must be run in online mode") + assert.Contains(t, res.Stderr.String(), "can't put while offline: pass `--allow-offline` to override") }) }) } diff --git a/test/cli/routing_dht_test.go b/test/cli/routing_dht_test.go index 3a3adc51c..fb0d39195 100644 --- a/test/cli/routing_dht_test.go +++ b/test/cli/routing_dht_test.go @@ -111,7 +111,7 @@ func testRoutingDHT(t *testing.T, enablePubsub bool) { node.WriteBytes("foo", []byte("foo")) res := node.RunIPFS("routing", "put", "/ipns/"+node.PeerID().String(), "foo") assert.Equal(t, 1, res.ExitCode()) - assert.Contains(t, res.Stderr.String(), "this action must be run in online mode") + assert.Contains(t, res.Stderr.String(), "can't put while offline: pass `--allow-offline` to override") }) }) }) From 846310e5ac98dee29eae1b71bf5ef7e2a022f490 Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Wed, 8 Nov 2023 01:09:29 -0500 Subject: [PATCH 0933/1212] fix: allow event emitting to happen in parallel with getting the query channel --- core/commands/routing.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/core/commands/routing.go b/core/commands/routing.go index 99aa4a78d..1f96c4dea 100644 --- a/core/commands/routing.go +++ b/core/commands/routing.go @@ -81,10 +81,9 @@ var findProvidersRoutingCmd = &cmds.Command{ ctx, cancel := context.WithCancel(req.Context) ctx, events := routing.RegisterForQueryEvents(ctx) - pchan := n.Routing.FindProvidersAsync(ctx, c, numProviders) - go func() { defer cancel() + pchan := n.Routing.FindProvidersAsync(ctx, c, numProviders) for p := range pchan { np := p routing.PublishQueryEvent(ctx, &routing.QueryEvent{ From 9c99ad5c71fbdfd7f255d670a83f76cdf88792af Mon Sep 17 00:00:00 2001 From: Jonas Keunecke Date: Mon, 6 Nov 2023 00:49:12 +0100 Subject: [PATCH 0934/1212] docs/config: remove extra commas in PublicGateways example entries --- docs/config.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/config.md b/docs/config.md index 1c8b0ed86..630532381 100644 --- a/docs/config.md +++ b/docs/config.md @@ -761,7 +761,7 @@ between content roots. "PublicGateways": { "dweb.link": { "UseSubdomains": true, - "Paths": ["/ipfs", "/ipns"], + "Paths": ["/ipfs", "/ipns"] } } } @@ -776,7 +776,7 @@ between content roots. "PublicGateways": { "ipfs.io": { "UseSubdomains": false, - "Paths": ["/ipfs", "/ipns", "/api"], + "Paths": ["/ipfs", "/ipns", "/api"] } } } From ccf3a71bc76dca2c2527eb967ffe8772adbdbe2c Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Mon, 6 Nov 2023 15:24:06 +0100 Subject: [PATCH 0935/1212] docs: fix accelerated-dht-client --- docs/experimental-features.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/experimental-features.md b/docs/experimental-features.md index 1f02dc3c8..6826a38c2 100644 --- a/docs/experimental-features.md +++ b/docs/experimental-features.md @@ -663,3 +663,7 @@ ipfs config --json Experimental.GatewayOverLibp2p true - [ ] Needs UX work for exposing non-recursive "HTTP transport" (NoFetch) over both libp2p and plain TCP (and sharing the configuration) - [ ] Needs a mechanism for HTTP handler to signal supported features ([IPIP-425](https://github.com/ipfs/specs/pull/425)) - [ ] Needs an option for Kubo to detect peers that have it enabled and prefer HTTP transport before falling back to bitswap (and use CAR if peer supports dag-scope=entity from [IPIP-402](https://github.com/ipfs/specs/pull/402)) + +## Accelerated DHT Client + +This feature now lives at [`Routing.AcceleratedDHTClient`](https://github.com/ipfs/kubo/blob/master/docs/config.md#routingaccelerateddhtclient). From 0b97630c93534f8b70704c12ce9c039cc2c69c63 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Tue, 7 Nov 2023 18:10:59 +0100 Subject: [PATCH 0936/1212] chore: update go-libp2p --- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- test/dependencies/go.mod | 2 +- test/dependencies/go.sum | 4 ++-- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 5b129929c..a370e26a3 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -9,7 +9,7 @@ replace github.com/ipfs/kubo => ./../../.. require ( github.com/ipfs/boxo v0.15.0 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 - github.com/libp2p/go-libp2p v0.32.0 + github.com/libp2p/go-libp2p v0.32.1 github.com/multiformats/go-multiaddr v0.12.0 ) diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index f5f0385e3..527925973 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -463,8 +463,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.32.0 h1:86I4B7nBUPIyTgw3+5Ibq6K7DdKRCuZw8URCfPc1hQM= -github.com/libp2p/go-libp2p v0.32.0/go.mod h1:hXXC3kXPlBZ1eu8Q2hptGrMB4mZ3048JUoS4EKaHW5c= +github.com/libp2p/go-libp2p v0.32.1 h1:wy1J4kZIZxOaej6NveTWCZmHiJ/kY7GoAqXgqNCnPps= +github.com/libp2p/go-libp2p v0.32.1/go.mod h1:hXXC3kXPlBZ1eu8Q2hptGrMB4mZ3048JUoS4EKaHW5c= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= diff --git a/go.mod b/go.mod index 5efc4d526..b4797b84a 100644 --- a/go.mod +++ b/go.mod @@ -47,7 +47,7 @@ require ( github.com/jbenet/goprocess v0.1.4 github.com/julienschmidt/httprouter v1.3.0 github.com/libp2p/go-doh-resolver v0.4.0 - github.com/libp2p/go-libp2p v0.32.0 + github.com/libp2p/go-libp2p v0.32.1 github.com/libp2p/go-libp2p-http v0.5.0 github.com/libp2p/go-libp2p-kad-dht v0.24.4 github.com/libp2p/go-libp2p-kbucket v0.6.3 diff --git a/go.sum b/go.sum index fed65f74a..0a52cb585 100644 --- a/go.sum +++ b/go.sum @@ -519,8 +519,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.32.0 h1:86I4B7nBUPIyTgw3+5Ibq6K7DdKRCuZw8URCfPc1hQM= -github.com/libp2p/go-libp2p v0.32.0/go.mod h1:hXXC3kXPlBZ1eu8Q2hptGrMB4mZ3048JUoS4EKaHW5c= +github.com/libp2p/go-libp2p v0.32.1 h1:wy1J4kZIZxOaej6NveTWCZmHiJ/kY7GoAqXgqNCnPps= +github.com/libp2p/go-libp2p v0.32.1/go.mod h1:hXXC3kXPlBZ1eu8Q2hptGrMB4mZ3048JUoS4EKaHW5c= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index b10e8c00f..dd6346b62 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -19,7 +19,7 @@ require ( github.com/ipld/go-ipld-prime v0.21.0 github.com/jbenet/go-random v0.0.0-20190219211222-123a90aedc0c github.com/jbenet/go-random-files v0.0.0-20190219210431-31b3f20ebded - github.com/libp2p/go-libp2p v0.32.0 + github.com/libp2p/go-libp2p v0.32.1 github.com/multiformats/go-multiaddr v0.12.0 github.com/multiformats/go-multihash v0.2.3 gotest.tools/gotestsum v0.4.2 diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 1c01c6320..8c9012722 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -542,8 +542,8 @@ github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38y github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.32.0 h1:86I4B7nBUPIyTgw3+5Ibq6K7DdKRCuZw8URCfPc1hQM= -github.com/libp2p/go-libp2p v0.32.0/go.mod h1:hXXC3kXPlBZ1eu8Q2hptGrMB4mZ3048JUoS4EKaHW5c= +github.com/libp2p/go-libp2p v0.32.1 h1:wy1J4kZIZxOaej6NveTWCZmHiJ/kY7GoAqXgqNCnPps= +github.com/libp2p/go-libp2p v0.32.1/go.mod h1:hXXC3kXPlBZ1eu8Q2hptGrMB4mZ3048JUoS4EKaHW5c= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-kad-dht v0.24.4 h1:ktNiJe7ffsJ1wX3ULpMCwXts99mPqGFSE/Qn1i8pErQ= From 151624c47bb57d3de43799d88ad4a6a98065d7dc Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Wed, 8 Nov 2023 01:07:10 -0500 Subject: [PATCH 0937/1212] fixes to routing put command (#10205) * fix(commands): routing put command returns the IPNS ID rather than the host's ID * fix(commands): routing put command errors with the allow-offline hint if the error is an offline error * fix: test expects correct error message --------- Co-authored-by: Henrique Dias --- core/commands/routing.go | 7 ++++--- test/cli/dht_legacy_test.go | 2 +- test/cli/routing_dht_test.go | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/core/commands/routing.go b/core/commands/routing.go index 6d0ddb1c8..99aa4a78d 100644 --- a/core/commands/routing.go +++ b/core/commands/routing.go @@ -14,6 +14,7 @@ import ( iface "github.com/ipfs/boxo/coreiface" "github.com/ipfs/boxo/coreiface/options" dag "github.com/ipfs/boxo/ipld/merkledag" + "github.com/ipfs/boxo/ipns" cid "github.com/ipfs/go-cid" cmds "github.com/ipfs/go-ipfs-cmds" ipld "github.com/ipfs/go-ipld-format" @@ -451,12 +452,12 @@ identified by QmFoo. options.Put.AllowOffline(allowOffline), } - err = api.Routing().Put(req.Context, req.Arguments[0], data, opts...) + ipnsName, err := ipns.NameFromString(req.Arguments[0]) if err != nil { return err } - id, err := api.Key().Self(req.Context) + err = api.Routing().Put(req.Context, req.Arguments[0], data, opts...) if err != nil { if err == iface.ErrOffline { err = errAllowOffline @@ -466,7 +467,7 @@ identified by QmFoo. return res.Emit(routing.QueryEvent{ Type: routing.Value, - ID: id.ID(), + ID: ipnsName.Peer(), }) }, Encoders: cmds.EncoderMap{ diff --git a/test/cli/dht_legacy_test.go b/test/cli/dht_legacy_test.go index 2b90d164c..cfcb4f0cd 100644 --- a/test/cli/dht_legacy_test.go +++ b/test/cli/dht_legacy_test.go @@ -131,7 +131,7 @@ func TestLegacyDHT(t *testing.T) { node.WriteBytes("foo", []byte("foo")) res := node.RunIPFS("dht", "put", "/ipns/"+node.PeerID().String(), "foo") assert.Equal(t, 1, res.ExitCode()) - assert.Contains(t, res.Stderr.String(), "this action must be run in online mode") + assert.Contains(t, res.Stderr.String(), "can't put while offline: pass `--allow-offline` to override") }) }) } diff --git a/test/cli/routing_dht_test.go b/test/cli/routing_dht_test.go index 3a3adc51c..fb0d39195 100644 --- a/test/cli/routing_dht_test.go +++ b/test/cli/routing_dht_test.go @@ -111,7 +111,7 @@ func testRoutingDHT(t *testing.T, enablePubsub bool) { node.WriteBytes("foo", []byte("foo")) res := node.RunIPFS("routing", "put", "/ipns/"+node.PeerID().String(), "foo") assert.Equal(t, 1, res.ExitCode()) - assert.Contains(t, res.Stderr.String(), "this action must be run in online mode") + assert.Contains(t, res.Stderr.String(), "can't put while offline: pass `--allow-offline` to override") }) }) }) From c6ae7165c8e23b6cedde7c986e19d2fc35efb2a8 Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Wed, 8 Nov 2023 01:09:29 -0500 Subject: [PATCH 0938/1212] fix: allow event emitting to happen in parallel with getting the query channel --- core/commands/routing.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/core/commands/routing.go b/core/commands/routing.go index 99aa4a78d..1f96c4dea 100644 --- a/core/commands/routing.go +++ b/core/commands/routing.go @@ -81,10 +81,9 @@ var findProvidersRoutingCmd = &cmds.Command{ ctx, cancel := context.WithCancel(req.Context) ctx, events := routing.RegisterForQueryEvents(ctx) - pchan := n.Routing.FindProvidersAsync(ctx, c, numProviders) - go func() { defer cancel() + pchan := n.Routing.FindProvidersAsync(ctx, c, numProviders) for p := range pchan { np := p routing.PublishQueryEvent(ctx, &routing.QueryEvent{ From cb4e20eabc895af309a8ba946166953a509b964b Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Wed, 8 Nov 2023 09:23:58 +0000 Subject: [PATCH 0939/1212] chore: update version --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index 5cf3be25e..de886ec43 100644 --- a/version.go +++ b/version.go @@ -11,7 +11,7 @@ import ( var CurrentCommit string // CurrentVersionNumber is the current application's version literal. -const CurrentVersionNumber = "0.24.0-rc2" +const CurrentVersionNumber = "0.24.0" const ApiVersion = "/kubo/" + CurrentVersionNumber + "/" //nolint From 2d4a20e9cc9708e573a1ab317dd94fb60dd75451 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Wed, 8 Nov 2023 09:27:34 +0000 Subject: [PATCH 0940/1212] chore: update changelog for v0.24 --- docs/changelogs/v0.24.md | 118 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) diff --git a/docs/changelogs/v0.24.md b/docs/changelogs/v0.24.md index 34a8490b0..7bc04dc92 100644 --- a/docs/changelogs/v0.24.md +++ b/docs/changelogs/v0.24.md @@ -82,4 +82,122 @@ node that is behind a NAT or firewall. This is being worked on [`go-libp2p#2009` ### 📝 Changelog +
Full Changelog + +- github.com/ipfs/kubo: + - chore: update version + - fix: allow event emitting to happen in parallel with getting the query channel + - fixes to routing put command (#10205) ([ipfs/kubo#10205](https://github.com/ipfs/kubo/pull/10205)) + - docs: fix accelerated-dht-client + - docs/config: remove extra commas in PublicGateways example entries + - chore: update version + - docs: make it clear Web RTC Direct is experimental + - feat: add WebRTC Direct support + - docs: update EARLY_TESTERS.md (#10194) ([ipfs/kubo#10194](https://github.com/ipfs/kubo/pull/10194)) + - Release: v0.24.0-1 ([ipfs/kubo#10190](https://github.com/ipfs/kubo/pull/10190)) +- github.com/ipfs/boxo (v0.13.1 -> v0.15.0): + - Release v0.15.0 ([ipfs/boxo#505](https://github.com/ipfs/boxo/pull/505)) + - Release v0.14.0 ([ipfs/boxo#500](https://github.com/ipfs/boxo/pull/500)) +- github.com/ipfs/go-block-format (v0.1.2 -> v0.2.0): + - v0.2.0 bump +- github.com/ipfs/go-graphsync (v0.15.1 -> v0.16.0): + - chore: release 0.16.0 + - chore: bump go-libp2p to 0.32.0 +- github.com/ipfs/go-ipld-format (v0.5.0 -> v0.6.0): + - v0.6.0 bump + - chore: update deps + - fix: stop using the deprecated io/ioutil package +- github.com/libp2p/go-libp2p (v0.31.0 -> v0.32.1): + - release v0.32.1 (#2637) ([libp2p/go-libp2p#2637](https://github.com/libp2p/go-libp2p/pull/2637)) + - swarm: fix timer Leak in the dial loop (#2636) ([libp2p/go-libp2p#2636](https://github.com/libp2p/go-libp2p/pull/2636)) + - release v0.32.0 (#2625) ([libp2p/go-libp2p#2625](https://github.com/libp2p/go-libp2p/pull/2625)) + - chore: update js-libp2p examples repo (#2624) ([libp2p/go-libp2p#2624](https://github.com/libp2p/go-libp2p/pull/2624)) + - identify: don't filter dns addresses based on remote addr type (#2553) ([libp2p/go-libp2p#2553](https://github.com/libp2p/go-libp2p/pull/2553)) + - webrtc: fix race in TestRemoveConnByUfrag (#2620) ([libp2p/go-libp2p#2620](https://github.com/libp2p/go-libp2p/pull/2620)) + - swarm: fix recursive resolving of DNS multiaddrs (#2564) ([libp2p/go-libp2p#2564](https://github.com/libp2p/go-libp2p/pull/2564)) + - ci: migrate to renamed interop test action (#2617) ([libp2p/go-libp2p#2617](https://github.com/libp2p/go-libp2p/pull/2617)) + - quic: update quic-go to v0.39.1, set a static resumption token generator key (#2572) ([libp2p/go-libp2p#2572](https://github.com/libp2p/go-libp2p/pull/2572)) + - test/basichost: fix flaky test due to rcmgr (#2613) ([libp2p/go-libp2p#2613](https://github.com/libp2p/go-libp2p/pull/2613)) + - swarm: use typed atomics (#2612) ([libp2p/go-libp2p#2612](https://github.com/libp2p/go-libp2p/pull/2612)) + - swarm: cleanup stream handler goroutine (#2610) ([libp2p/go-libp2p#2610](https://github.com/libp2p/go-libp2p/pull/2610)) + - circuitv2: don't check ASN for private addrs (#2611) ([libp2p/go-libp2p#2611](https://github.com/libp2p/go-libp2p/pull/2611)) + - swarm: use happy eyeballs ranking for TCP dials (#2573) ([libp2p/go-libp2p#2573](https://github.com/libp2p/go-libp2p/pull/2573)) + - webrtc: fix race in TestMuxedConnection (#2607) ([libp2p/go-libp2p#2607](https://github.com/libp2p/go-libp2p/pull/2607)) + - tcp: fix build on riscv64 (#2590) ([libp2p/go-libp2p#2590](https://github.com/libp2p/go-libp2p/pull/2590)) + - Fix missing deprecation tag (#2605) ([libp2p/go-libp2p#2605](https://github.com/libp2p/go-libp2p/pull/2605)) + - swarm: wait for transient connections to upgrade for NewStream (#2542) ([libp2p/go-libp2p#2542](https://github.com/libp2p/go-libp2p/pull/2542)) + - docs: fix typos (#2604) ([libp2p/go-libp2p#2604](https://github.com/libp2p/go-libp2p/pull/2604)) + - webrtc: correctly report incoming packet address on muxed connection (#2586) ([libp2p/go-libp2p#2586](https://github.com/libp2p/go-libp2p/pull/2586)) + - swarm: add loopback to low timeout filter (#2595) ([libp2p/go-libp2p#2595](https://github.com/libp2p/go-libp2p/pull/2595)) + - Fix typos in comments and a test failure message (#2600) ([libp2p/go-libp2p#2600](https://github.com/libp2p/go-libp2p/pull/2600)) + - libp2phttp: don't strip `/` suffix when mounting handler (#2552) ([libp2p/go-libp2p#2552](https://github.com/libp2p/go-libp2p/pull/2552)) + - interop: fix redis env var (#2585) ([libp2p/go-libp2p#2585](https://github.com/libp2p/go-libp2p/pull/2585)) + - quicreuse: remove QUIC metrics tracer (#2582) ([libp2p/go-libp2p#2582](https://github.com/libp2p/go-libp2p/pull/2582)) + - config: warn if connmgr limits conflict with rcmgr (#2527) ([libp2p/go-libp2p#2527](https://github.com/libp2p/go-libp2p/pull/2527)) + - update gomock to v0.3.0 (#2581) ([libp2p/go-libp2p#2581](https://github.com/libp2p/go-libp2p/pull/2581)) + - webrtc: fix deadlock on connection close (#2580) ([libp2p/go-libp2p#2580](https://github.com/libp2p/go-libp2p/pull/2580)) + - webrtc: put buffer back to pool (#2574) ([libp2p/go-libp2p#2574](https://github.com/libp2p/go-libp2p/pull/2574)) + - webrtc: fail Write early if deadline has exceeded before the call (#2578) ([libp2p/go-libp2p#2578](https://github.com/libp2p/go-libp2p/pull/2578)) + - swarm: fix DialPeer behaviour for transient connections (#2547) ([libp2p/go-libp2p#2547](https://github.com/libp2p/go-libp2p/pull/2547)) + - websocket: don't resolve /dnsaddr addresses (#2571) ([libp2p/go-libp2p#2571](https://github.com/libp2p/go-libp2p/pull/2571)) + - core/peer: remove deprecated ID.Pretty method (#2565) ([libp2p/go-libp2p#2565](https://github.com/libp2p/go-libp2p/pull/2565)) + - core/peer: remove deprecated Encode function (#2566) ([libp2p/go-libp2p#2566](https://github.com/libp2p/go-libp2p/pull/2566)) + - mock: use go.uber.org/mock (#2540) ([libp2p/go-libp2p#2540](https://github.com/libp2p/go-libp2p/pull/2540)) + - add WebRTC Direct transport implementation (#2337) ([libp2p/go-libp2p#2337](https://github.com/libp2p/go-libp2p/pull/2337)) + - upgrader: drop support for multistream simultaneous open (#2557) ([libp2p/go-libp2p#2557](https://github.com/libp2p/go-libp2p/pull/2557)) + - examples: stop using deprecated peer.ID.Pretty (#2563) ([libp2p/go-libp2p#2563](https://github.com/libp2p/go-libp2p/pull/2563)) + - swarm: don't dial unspecified addresses (#2560) ([libp2p/go-libp2p#2560](https://github.com/libp2p/go-libp2p/pull/2560)) + - basichost: handle the SetProtocol error in NewStream (#2555) ([libp2p/go-libp2p#2555](https://github.com/libp2p/go-libp2p/pull/2555)) + - libp2phttp: don't initialise ServeMux if not nil (#2548) ([libp2p/go-libp2p#2548](https://github.com/libp2p/go-libp2p/pull/2548)) +- github.com/libp2p/go-libp2p-pubsub (v0.9.3 -> v0.10.0): + - chore: update go-libp2p to v0.32 (#548) ([libp2p/go-libp2p-pubsub#548](https://github.com/libp2p/go-libp2p-pubsub/pull/548)) + - remove usage of deprecated peerid.Pretty method (#542) ([libp2p/go-libp2p-pubsub#542](https://github.com/libp2p/go-libp2p-pubsub/pull/542)) + - Revert "fix: topicscore params can't be set for dynamically subscribed topic (#540)" (#541) ([libp2p/go-libp2p-pubsub#541](https://github.com/libp2p/go-libp2p-pubsub/pull/541)) + - fix: topicscore params can't be set for dynamically subscribed topic (#540) ([libp2p/go-libp2p-pubsub#540](https://github.com/libp2p/go-libp2p-pubsub/pull/540)) +- github.com/multiformats/go-multiaddr (v0.11.0 -> v0.12.0): + - release v0.12.0 (#223) ([multiformats/go-multiaddr#223](https://github.com/multiformats/go-multiaddr/pull/223)) + - net: consider /dns/localhost as private address (#221) ([multiformats/go-multiaddr#221](https://github.com/multiformats/go-multiaddr/pull/221)) + - net: consider dns addresses as public (#220) ([multiformats/go-multiaddr#220](https://github.com/multiformats/go-multiaddr/pull/220)) +- github.com/multiformats/go-multistream (v0.4.1 -> v0.5.0): + - remove support for the simultaneous open extension (#107) ([multiformats/go-multistream#107](https://github.com/multiformats/go-multistream/pull/107)) + +
+ ### 👨‍👩‍👧‍👦 Contributors + +| Contributor | Commits | Lines ± | Files Changed | +|-------------|---------|---------|---------------| +| Henrique Dias | 27 | +4505/-3853 | 244 | +| Marten Seemann | 18 | +4260/-1173 | 101 | +| Sukun | 24 | +1499/-340 | 79 | +| Andrew Gillis | 4 | +169/-1025 | 16 | +| Adin Schmahmann | 4 | +788/-184 | 19 | +| Hector Sanjuan | 6 | +619/-72 | 19 | +| Steven Allen | 11 | +489/-101 | 14 | +| Jorropo | 10 | +221/-192 | 28 | +| Łukasz Magiera | 2 | +306/-9 | 3 | +| Lucas Molas | 1 | +183/-52 | 2 | +| Marcin Rataj | 5 | +160/-25 | 6 | +| piersy | 1 | +57/-0 | 6 | +| Raúl Kripalani | 1 | +25/-25 | 2 | +| Alvin Reyes | 1 | +34/-14 | 1 | +| Dennis Trautwein | 1 | +1/-40 | 2 | +| Icarus9913 | 1 | +14/-14 | 10 | +| Takashi Matsuda | 2 | +18/-1 | 3 | +| gammazero | 4 | +8/-5 | 7 | +| xiaolou86 | 1 | +6/-6 | 5 | +| Daniel Martí | 1 | +9/-2 | 1 | +| Rod Vagg | 3 | +5/-5 | 4 | +| Andrej Manduch | 1 | +5/-5 | 3 | +| vuittont60 | 1 | +4/-4 | 3 | +| vyzo | 1 | +5/-1 | 1 | +| tkzktk | 1 | +3/-3 | 3 | +| tk | 1 | +3/-3 | 2 | +| Prem Chaitanya Prathi | 1 | +1/-5 | 1 | +| Kay | 2 | +2/-3 | 2 | +| Thomas Eizinger | 1 | +2/-2 | 1 | +| Steve Loeppky | 1 | +2/-2 | 1 | +| Jonas Keunecke | 1 | +2/-2 | 1 | +| Alejandro Criado-Pérez | 1 | +1/-1 | 1 | +| web3-bot | 1 | +1/-0 | 1 | +| Eric | 1 | +1/-0 | 1 | From 9655d9290857f54e68b5266439a596b4015e02c4 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Wed, 8 Nov 2023 13:02:58 +0000 Subject: [PATCH 0941/1212] chore: create next changelog --- CHANGELOG.md | 1 + docs/changelogs/v0.25.md | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 docs/changelogs/v0.25.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f75314a9..7fd7e8f76 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ # Kubo Changelogs +- [v0.25](docs/changelogs/v0.25.md) - [v0.24](docs/changelogs/v0.24.md) - [v0.23](docs/changelogs/v0.23.md) - [v0.22](docs/changelogs/v0.22.md) diff --git a/docs/changelogs/v0.25.md b/docs/changelogs/v0.25.md new file mode 100644 index 000000000..1388ddd90 --- /dev/null +++ b/docs/changelogs/v0.25.md @@ -0,0 +1,18 @@ +# Kubo changelog v0.25 + +- [v0.25.0](#v0250) + +## v0.25.0 + +- [Overview](#overview) +- [🔦 Highlights](#-highlights) +- [📝 Changelog](#-changelog) +- [👨‍👩‍👧‍👦 Contributors](#-contributors) + +### Overview + +### 🔦 Highlights + +### 📝 Changelog + +### 👨‍👩‍👧‍👦 Contributors From 7834a26d034dad9fda0e08d4bcd31052bbb969f5 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Thu, 9 Nov 2023 01:42:04 +0100 Subject: [PATCH 0942/1212] docs(changelog): clarify webrtc in v0.24 This sets the expectations (not production ready) and gives users hint how to enable it by adding `/udp/4001/webrtc-direct` listener. --- docs/changelogs/v0.24.md | 20 +++++++++++++------- docs/config.md | 20 ++++++++++++++++---- 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/docs/changelogs/v0.24.md b/docs/changelogs/v0.24.md index 7bc04dc92..9ca7fa84e 100644 --- a/docs/changelogs/v0.24.md +++ b/docs/changelogs/v0.24.md @@ -71,14 +71,20 @@ cached more efficiently and load faster in browser contexts. #### Experimental Transport: WebRTC Direct -[WebRTC Direct](https://github.com/libp2p/go-libp2p/pull/2337) has now been introduced -in [`go-libp2p`](https://github.com/libp2p/go-libp2p/releases/tag/v0.32.0) v0.32.0. This -transport protocol allows browser nodes to connect to other nodes without special configuration, -such as TLS certificates. This can be useful for browsers that do not yet support -WebTransport, for example. +This Kubo release includes the initial work towards WebRTC Direct +introduced in [`go-libp2p`](https://github.com/libp2p/go-libp2p/releases/tag/v0.32.0) v0.32: -Note that, at the moment, WebRTC Direct cannot be used to connect to a browser node to a -node that is behind a NAT or firewall. This is being worked on [`go-libp2p#2009`](https://github.com/libp2p/go-libp2p/issues/2009). +> [WebRTC Direct](https://github.com/libp2p/specs/blob/master/webrtc/webrtc-direct.md) +> allows browser nodes to connect to go-libp2p nodes directly, +> without any configuration (e.g. TLS certificates) needed on the go-libp2p +> side. This is useful for browser nodes that aren’t able to use +> [WebTransport](https://blog.libp2p.io/2022-12-19-libp2p-webtransport/). + +The `/webrtc-direct` transport is disabled by default in Kubo 0.24, +and not ready for production use yet, but we plan to enable it in a future release. + +See [`Swarm.Transports.Network.WebRTCDirect`](https://github.com/ipfs/kubo/blob/master/docs/config.md#swarmtransportsnetworkwebrtcdirect) +to learn how to enable it manually, and what current limitations are. ### 📝 Changelog diff --git a/docs/config.md b/docs/config.md index 630532381..49e761100 100644 --- a/docs/config.md +++ b/docs/config.md @@ -2076,13 +2076,25 @@ Type: `flag` #### `Swarm.Transports.Network.WebRTCDirect` **Experimental:** the support for WebRTC Direct is currently experimental. +This feature was introduced in [`go-libp2p@v0.32.0`](https://github.com/libp2p/go-libp2p/releases/tag/v0.32.0). -A new feature of [`go-libp2p`](https://github.com/libp2p/go-libp2p/releases/tag/v0.32.0) -is the [WebRTC Direct](https://github.com/libp2p/go-libp2p/pull/2337) transport. +[WebRTC Direct](https://github.com/libp2p/specs/blob/master/webrtc/webrtc-direct.md) +is a transport protocol that provides another way for browsers to +connect to the rest of the libp2p network. WebRTC Direct allows for browser +nodes to connect to other nodes without special configuration, such as TLS +certificates. This can be useful for browser nodes that do not yet support +[WebTransport](https://blog.libp2p.io/2022-12-19-libp2p-webtransport/). -WebRTC Direct is a transport protocol that provides another way for browsers to connect to the rest of the libp2p network. WebRTC Direct allows for browser nodes to connect to other nodes without special configuration, such as TLS certificates. This can be useful for browser nodes that do not yet support WebTransport, for example. +Enabling this transport allows Kubo node to act on `/udp/4001/webrtc-direct` +listeners defined in `Addresses.Swarm`, `Addresses.Announce` or +`Addresses.AppendAnnounce`. -Note that, at the moment, WebRTC Direct cannot be used to connect to a browser node to a node that is behind a NAT or firewall. This is being worked on [`go-libp2p#2009`](https://github.com/libp2p/go-libp2p/issues/2009). +**NOTE:** at the moment, WebRTC Direct cannot be used to connect to a browser +node to a node that is behind a NAT or firewall. +This requires using normal +[WebRTC](https://github.com/libp2p/specs/blob/master/webrtc/webrtc.md), +which is currently being worked on in +[go-libp2p#2009](https://github.com/libp2p/go-libp2p/issues/2009). Default: Disabled From 670ce7043e3b0af52a25a69569464cd3c256d3ee Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Wed, 8 Nov 2023 21:30:38 +0100 Subject: [PATCH 0943/1212] fix: regression in 'ipfs dns' this command used to work with domain without `/ipns/` prefix. we've switched it to the same backend as `resolve` command, which requires the prefix, so we add it if it is missing --- core/commands/dns.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/core/commands/dns.go b/core/commands/dns.go index 5126a6cb1..065b4acdc 100644 --- a/core/commands/dns.go +++ b/core/commands/dns.go @@ -3,6 +3,7 @@ package commands import ( "fmt" "io" + "strings" namesys "github.com/ipfs/boxo/namesys" "github.com/ipfs/boxo/path" @@ -19,7 +20,7 @@ const ( var DNSCmd = &cmds.Command{ Status: cmds.Deprecated, // https://github.com/ipfs/kubo/issues/8607 Helptext: cmds.HelpText{ - Tagline: "Resolve DNSLink records.", + Tagline: "Resolve DNSLink records. Deprecated: Use 'ipfs resolve /ipns/domain-name' instead.", ShortDescription: ` This command can only recursively resolve DNSLink TXT records. It will fail to recursively resolve through IPNS keys etc. @@ -52,6 +53,10 @@ It will work across multiple DNSLinks and IPNS keys. routing = append(routing, namesys.ResolveWithDepth(1)) } + if !strings.HasPrefix(name, "/ipns/") { + name = "/ipns/" + name + } + p, err := path.NewPath(name) if err != nil { return err From 0770702289fcc77952e92814242764e99557edb9 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Wed, 15 Nov 2023 15:32:25 +0100 Subject: [PATCH 0944/1212] docs: clarify ipfs id agent version --- cmd/ipfs/daemon.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/ipfs/daemon.go b/cmd/ipfs/daemon.go index d9207b0f6..62d5616c7 100644 --- a/cmd/ipfs/daemon.go +++ b/cmd/ipfs/daemon.go @@ -175,7 +175,7 @@ Headers. cmds.BoolOption(enablePubSubKwd, "DEPRECATED"), cmds.BoolOption(enableIPNSPubSubKwd, "Enable IPNS over pubsub. Implicitly enables pubsub, overrides Ipns.UsePubsub config."), cmds.BoolOption(enableMultiplexKwd, "DEPRECATED"), - cmds.StringOption(agentVersionSuffix, "Optional suffix to the AgentVersion presented by `ipfs id` and also advertised through BitSwap."), + cmds.StringOption(agentVersionSuffix, "Optional suffix to the AgentVersion presented by `ipfs id` and exposed via libp2p identify protocol."), // TODO: add way to override addresses. tricky part: updating the config if also --init. // cmds.StringOption(apiAddrKwd, "Address for the daemon rpc API (overrides config)"), From 01cc5eab57ed7acab1593280c7b5565d18c8f3ae Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Fri, 17 Nov 2023 01:29:29 +0100 Subject: [PATCH 0945/1212] feat(rpc): Opt-in HTTP RPC API Authorization (#10218) Context: https://github.com/ipfs/kubo/issues/10187 Co-authored-by: Marcin Rataj --- client/rpc/auth/auth.go | 29 +++++++ cmd/ipfs/daemon.go | 4 + cmd/ipfs/main.go | 8 ++ config/api.go | 62 ++++++++++++++- config/api_test.go | 22 ++++++ core/commands/config.go | 5 ++ core/commands/root.go | 4 +- core/corehttp/commands.go | 51 ++++++++++++ docs/changelogs/v0.25.md | 14 ++++ docs/config.md | 84 ++++++++++++++++++++ test/cli/harness/node.go | 29 +++++-- test/cli/rpc_auth_test.go | 162 ++++++++++++++++++++++++++++++++++++++ 12 files changed, 464 insertions(+), 10 deletions(-) create mode 100644 client/rpc/auth/auth.go create mode 100644 config/api_test.go create mode 100644 test/cli/rpc_auth_test.go diff --git a/client/rpc/auth/auth.go b/client/rpc/auth/auth.go new file mode 100644 index 000000000..a6ed273cd --- /dev/null +++ b/client/rpc/auth/auth.go @@ -0,0 +1,29 @@ +package auth + +import "net/http" + +var _ http.RoundTripper = &AuthorizedRoundTripper{} + +type AuthorizedRoundTripper struct { + authorization string + roundTripper http.RoundTripper +} + +// NewAuthorizedRoundTripper creates a new [http.RoundTripper] that will set the +// Authorization HTTP header with the value of [authorization]. The given [roundTripper] is +// the base [http.RoundTripper]. If it is nil, [http.DefaultTransport] is used. +func NewAuthorizedRoundTripper(authorization string, roundTripper http.RoundTripper) http.RoundTripper { + if roundTripper == nil { + roundTripper = http.DefaultTransport + } + + return &AuthorizedRoundTripper{ + authorization: authorization, + roundTripper: roundTripper, + } +} + +func (tp *AuthorizedRoundTripper) RoundTrip(r *http.Request) (*http.Response, error) { + r.Header.Set("Authorization", tp.authorization) + return tp.roundTripper.RoundTrip(r) +} diff --git a/cmd/ipfs/daemon.go b/cmd/ipfs/daemon.go index 62d5616c7..1375d464d 100644 --- a/cmd/ipfs/daemon.go +++ b/cmd/ipfs/daemon.go @@ -676,6 +676,10 @@ func serveHTTPApi(req *cmds.Request, cctx *oldcmds.Context) (<-chan error, error listeners = append(listeners, apiLis) } + if len(cfg.API.Authorizations) > 0 && len(listeners) > 0 { + fmt.Printf("RPC API access is limited by the rules defined in API.Authorizations\n") + } + for _, listener := range listeners { // we might have listened to /tcp/0 - let's see what we are listing on fmt.Printf("RPC API server listening on %s\n", listener.Multiaddr()) diff --git a/cmd/ipfs/main.go b/cmd/ipfs/main.go index 3909e1816..f135f28fe 100644 --- a/cmd/ipfs/main.go +++ b/cmd/ipfs/main.go @@ -23,8 +23,10 @@ import ( cmdhttp "github.com/ipfs/go-ipfs-cmds/http" logging "github.com/ipfs/go-log" ipfs "github.com/ipfs/kubo" + "github.com/ipfs/kubo/client/rpc/auth" "github.com/ipfs/kubo/cmd/ipfs/util" oldcmds "github.com/ipfs/kubo/commands" + config "github.com/ipfs/kubo/config" "github.com/ipfs/kubo/core" corecmds "github.com/ipfs/kubo/core/commands" "github.com/ipfs/kubo/core/corehttp" @@ -325,6 +327,12 @@ func makeExecutor(req *cmds.Request, env interface{}) (cmds.Executor, error) { return nil, fmt.Errorf("unsupported API address: %s", apiAddr) } + apiAuth, specified := req.Options[corecmds.ApiAuthOption].(string) + if specified { + authorization := config.ConvertAuthSecret(apiAuth) + tpt = auth.NewAuthorizedRoundTripper(authorization, tpt) + } + httpClient := &http.Client{ Transport: otelhttp.NewTransport(tpt), } diff --git a/config/api.go b/config/api.go index b36b10803..a626a272a 100644 --- a/config/api.go +++ b/config/api.go @@ -1,5 +1,63 @@ package config -type API struct { - HTTPHeaders map[string][]string // HTTP headers to return with the API. +import ( + "encoding/base64" + "strings" +) + +const ( + APITag = "API" + AuthorizationTag = "Authorizations" +) + +type RPCAuthScope struct { + // AuthSecret is the secret that will be compared to the HTTP "Authorization". + // header. A secret is in the format "type:value". Check the documentation for + // supported types. + AuthSecret string + + // AllowedPaths is an explicit list of RPC path prefixes to allow. + // By default, none are allowed. ["/api/v0"] exposes all RPCs. + AllowedPaths []string +} + +type API struct { + // HTTPHeaders are the HTTP headers to return with the API. + HTTPHeaders map[string][]string + + // Authorization is a map of authorizations used to authenticate in the API. + // If the map is empty, then the RPC API is exposed to everyone. Check the + // documentation for more details. + Authorizations map[string]*RPCAuthScope `json:",omitempty"` +} + +// ConvertAuthSecret converts the given secret in the format "type:value" into an +// HTTP Authorization header value. It can handle 'bearer' and 'basic' as type. +// If type exists and is not known, an empty string is returned. If type does not +// exist, 'bearer' type is assumed. +func ConvertAuthSecret(secret string) string { + if secret == "" { + return secret + } + + split := strings.SplitN(secret, ":", 2) + if len(split) < 2 { + // No prefix: assume bearer token. + return "Bearer " + secret + } + + if strings.HasPrefix(secret, "basic:") { + if strings.Contains(split[1], ":") { + // Assume basic:user:password + return "Basic " + base64.StdEncoding.EncodeToString([]byte(split[1])) + } else { + // Assume already base64 encoded. + return "Basic " + split[1] + } + } else if strings.HasPrefix(secret, "bearer:") { + return "Bearer " + split[1] + } + + // Unknown. Type is present, but we can't handle it. + return "" } diff --git a/config/api_test.go b/config/api_test.go new file mode 100644 index 000000000..daf8a5375 --- /dev/null +++ b/config/api_test.go @@ -0,0 +1,22 @@ +package config + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestConvertAuthSecret(t *testing.T) { + for _, testCase := range []struct { + input string + output string + }{ + {"", ""}, + {"someToken", "Bearer someToken"}, + {"bearer:someToken", "Bearer someToken"}, + {"basic:user:pass", "Basic dXNlcjpwYXNz"}, + {"basic:dXNlcjpwYXNz", "Basic dXNlcjpwYXNz"}, + } { + assert.Equal(t, testCase.output, ConvertAuthSecret(testCase.input)) + } +} diff --git a/core/commands/config.go b/core/commands/config.go index b24551027..b52c05af2 100644 --- a/core/commands/config.go +++ b/core/commands/config.go @@ -208,6 +208,11 @@ NOTE: For security reasons, this command will omit your private key and remote s return err } + cfg, err = scrubValue(cfg, []string{config.APITag, config.AuthorizationTag}) + if err != nil { + return err + } + cfg, err = scrubOptionalValue(cfg, config.PinningConcealSelector) if err != nil { return err diff --git a/core/commands/root.go b/core/commands/root.go index 0e274f087..b812573fc 100644 --- a/core/commands/root.go +++ b/core/commands/root.go @@ -28,7 +28,8 @@ const ( DebugOption = "debug" LocalOption = "local" // DEPRECATED: use OfflineOption OfflineOption = "offline" - ApiOption = "api" //nolint + ApiOption = "api" //nolint + ApiAuthOption = "api-auth" //nolint ) var Root = &cmds.Command{ @@ -110,6 +111,7 @@ The CLI will exit with one of the following values: cmds.BoolOption(LocalOption, "L", "Run the command locally, instead of using the daemon. DEPRECATED: use --offline."), cmds.BoolOption(OfflineOption, "Run the command offline."), cmds.StringOption(ApiOption, "Use a specific API instance (defaults to /ip4/127.0.0.1/tcp/5001)"), + cmds.StringOption(ApiAuthOption, "Optional RPC API authorization secret (defined as AuthSecret in API.Authorizations config)"), // global options, added to every command cmdenv.OptionCidBase, diff --git a/core/corehttp/commands.go b/core/corehttp/commands.go index 804b70a7e..314822ff2 100644 --- a/core/corehttp/commands.go +++ b/core/corehttp/commands.go @@ -143,12 +143,63 @@ func commandsOption(cctx oldcmds.Context, command *cmds.Command, allowGet bool) patchCORSVars(cfg, l.Addr()) cmdHandler := cmdsHttp.NewHandler(&cctx, command, cfg) + + if len(rcfg.API.Authorizations) > 0 { + authorizations := convertAuthorizationsMap(rcfg.API.Authorizations) + cmdHandler = withAuthSecrets(authorizations, cmdHandler) + } + cmdHandler = otelhttp.NewHandler(cmdHandler, "corehttp.cmdsHandler") mux.Handle(APIPath+"/", cmdHandler) return mux, nil } } +type rpcAuthScopeWithUser struct { + config.RPCAuthScope + User string +} + +func convertAuthorizationsMap(authScopes map[string]*config.RPCAuthScope) map[string]rpcAuthScopeWithUser { + // authorizations is a map where we can just check for the header value to match. + authorizations := map[string]rpcAuthScopeWithUser{} + for user, authScope := range authScopes { + expectedHeader := config.ConvertAuthSecret(authScope.AuthSecret) + if expectedHeader != "" { + authorizations[expectedHeader] = rpcAuthScopeWithUser{ + RPCAuthScope: *authScopes[user], + User: user, + } + } + } + + return authorizations +} + +func withAuthSecrets(authorizations map[string]rpcAuthScopeWithUser, next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + authorizationHeader := r.Header.Get("Authorization") + auth, ok := authorizations[authorizationHeader] + + if ok { + // version check is implicitly allowed + if r.URL.Path == "/api/v0/version" { + next.ServeHTTP(w, r) + return + } + // everything else has to be safelisted via AllowedPaths + for _, prefix := range auth.AllowedPaths { + if strings.HasPrefix(r.URL.Path, prefix) { + next.ServeHTTP(w, r) + return + } + } + } + + http.Error(w, "Kubo RPC Access Denied: Please provide a valid authorization token as defined in the API.Authorizations configuration.", http.StatusForbidden) + }) +} + // CommandsOption constructs a ServerOption for hooking the commands into the // HTTP server. It will NOT allow GET requests. func CommandsOption(cctx oldcmds.Context) ServeOption { diff --git a/docs/changelogs/v0.25.md b/docs/changelogs/v0.25.md index 1388ddd90..1ad032ed3 100644 --- a/docs/changelogs/v0.25.md +++ b/docs/changelogs/v0.25.md @@ -6,6 +6,7 @@ - [Overview](#overview) - [🔦 Highlights](#-highlights) + - [RPC `API.Authorizations`](#rpc-apiauthorizations) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -13,6 +14,19 @@ ### 🔦 Highlights +#### RPC `API.Authorizations` + +Kubo RPC API now supports optional HTTP Authorization. + +Granular control over user access to the RPC can be defined in the +[`API.Authorizations`](https://github.com/ipfs/kubo/blob/master/docs/config.md#apiauthorizations) +map in the configuration file, allowing different users or apps to have unique +access secrets and allowed paths. + +This feature is opt-in. By default, no authorization is set up. +For configuration instructions, +refer to the [documentation](https://github.com/ipfs/kubo/blob/master/docs/config.md#apiauthorizations). + ### 📝 Changelog ### 👨‍👩‍👧‍👦 Contributors diff --git a/docs/config.md b/docs/config.md index 49e761100..0b33fa3fd 100644 --- a/docs/config.md +++ b/docs/config.md @@ -28,6 +28,9 @@ config file at runtime. - [`Addresses.NoAnnounce`](#addressesnoannounce) - [`API`](#api) - [`API.HTTPHeaders`](#apihttpheaders) + - [`API.Authorizations`](#apiauthorizations) + - [`API.Authorizations: AuthSecret`](#apiauthorizations-authsecret) + - [`API.Authorizations: AllowedPaths`](#apiauthorizations-allowedpaths) - [`AutoNAT`](#autonat) - [`AutoNAT.ServiceMode`](#autonatservicemode) - [`AutoNAT.Throttle`](#autonatthrottle) @@ -438,6 +441,87 @@ Default: `null` Type: `object[string -> array[string]]` (header names -> array of header values) +### `API.Authorizations` + +The `API.Authorizations` field defines user-based access restrictions for the +[Kubo RPC API](https://docs.ipfs.tech/reference/kubo/rpc/), which is located at +`Addresses.API` under `/api/v0` paths. + +By default, the RPC API is accessible without restrictions as it is only +exposed on `127.0.0.1` and safeguarded with Origin check and implicit +[CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) headers that +block random websites from accessing the RPC. + +When entries are defined in `API.Authorizations`, RPC requests will be declined +unless a corresponding secret is present in the HTTP [`Authorization` header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Authorization), +and the requested path is included in the `AllowedPaths` list for that specific +secret. + +Default: `null` + +Type: `object[string -> object]` (user name -> authorization object, see bellow) + +For example, to limit RPC access to Alice (access `id` and MFS `files` commands with HTTP Basic Auth) +and Bob (full access with Bearer token): + +```json +{ + "API": { + "Authorizations": { + "Alice": { + "AuthSecret": "basic:alice:password123", + "AllowedPaths": ["/api/v0/id", "/api/v0/files"] + }, + "Bob": { + "AuthSecret": "bearer:secret-token123", + "AllowedPaths": ["/api/v0"] + } + } + } +} + +``` + +#### `API.Authorizations: AuthSecret` + +The `AuthSecret` field denotes the secret used by a user to authenticate, +usually via HTTP [`Authorization` header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Authorization). + +Field format is `type:value`, and the following types are supported: + +- `bearer:` For secret Bearer tokens, set as `bearer:token`. + - If no known `type:` prefix is present, `bearer:` is assumed. +- `basic`: For HTTP Basic Auth introduced in [RFC7617](https://datatracker.ietf.org/doc/html/rfc7617). Value can be: + - `basic:user:pass` + - `basic:base64EncodedBasicAuth` + +One can use the config value for authentication via the command line: + +``` +ipfs id --api-auth basic:user:pass +``` + +Type: `string` + +#### `API.Authorizations: AllowedPaths` + +The `AllowedPaths` field is an array of strings containing allowed RPC path +prefixes. Users authorized with the related `AuthSecret` will only be able to +access paths prefixed by the specified prefixes. + +For instance: + +- If set to `["/api/v0"]`, the user will have access to the complete RPC API. +- If set to `["/api/v0/id", "/api/v0/files"]`, the user will only have access + to the `id` command and all MFS commands under `files`. + +Note that `/api/v0/version` is always permitted access to allow version check +to ensure compatibility. + +Default: `[]` + +Type: `array[string]` + ## `AutoNAT` Contains the configuration options for the AutoNAT service. The AutoNAT service diff --git a/test/cli/harness/node.go b/test/cli/harness/node.go index 7db1d5538..d030c7c94 100644 --- a/test/cli/harness/node.go +++ b/test/cli/harness/node.go @@ -223,7 +223,7 @@ func (n *Node) Init(ipfsArgs ...string) *Node { // harness.RunWithStdout(os.Stdout), // }, // }) -func (n *Node) StartDaemonWithReq(req RunRequest) *Node { +func (n *Node) StartDaemonWithReq(req RunRequest, authorization string) *Node { alive := n.IsAlive() if alive { log.Panicf("node %d is already running", n.ID) @@ -239,14 +239,20 @@ func (n *Node) StartDaemonWithReq(req RunRequest) *Node { n.Daemon = res log.Debugf("node %d started, checking API", n.ID) - n.WaitOnAPI() + n.WaitOnAPI(authorization) return n } func (n *Node) StartDaemon(ipfsArgs ...string) *Node { return n.StartDaemonWithReq(RunRequest{ Args: ipfsArgs, - }) + }, "") +} + +func (n *Node) StartDaemonWithAuthorization(secret string, ipfsArgs ...string) *Node { + return n.StartDaemonWithReq(RunRequest{ + Args: ipfsArgs, + }, secret) } func (n *Node) signalAndWait(watch <-chan struct{}, signal os.Signal, t time.Duration) bool { @@ -337,7 +343,7 @@ func (n *Node) TryAPIAddr() (multiaddr.Multiaddr, error) { return ma, nil } -func (n *Node) checkAPI() bool { +func (n *Node) checkAPI(authorization string) bool { apiAddr, err := n.TryAPIAddr() if err != nil { log.Debugf("node %d API addr not available yet: %s", n.ID, err.Error()) @@ -353,7 +359,16 @@ func (n *Node) checkAPI() bool { } url := fmt.Sprintf("http://%s:%s/api/v0/id", ip, port) log.Debugf("checking API for node %d at %s", n.ID, url) - httpResp, err := http.Post(url, "", nil) + + req, err := http.NewRequest(http.MethodPost, url, nil) + if err != nil { + panic(err) + } + if authorization != "" { + req.Header.Set("Authorization", authorization) + } + + httpResp, err := http.DefaultClient.Do(req) if err != nil { log.Debugf("node %d API check error: %s", err.Error()) return false @@ -402,10 +417,10 @@ func (n *Node) PeerID() peer.ID { return id } -func (n *Node) WaitOnAPI() *Node { +func (n *Node) WaitOnAPI(authorization string) *Node { log.Debugf("waiting on API for node %d", n.ID) for i := 0; i < 50; i++ { - if n.checkAPI() { + if n.checkAPI(authorization) { log.Debugf("daemon API found, daemon stdout: %s", n.Daemon.Stdout.String()) return n } diff --git a/test/cli/rpc_auth_test.go b/test/cli/rpc_auth_test.go new file mode 100644 index 000000000..c30b107cf --- /dev/null +++ b/test/cli/rpc_auth_test.go @@ -0,0 +1,162 @@ +package cli + +import ( + "net/http" + "testing" + + "github.com/ipfs/kubo/client/rpc/auth" + "github.com/ipfs/kubo/config" + "github.com/ipfs/kubo/test/cli/harness" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +const rpcDeniedMsg = "Kubo RPC Access Denied: Please provide a valid authorization token as defined in the API.Authorizations configuration." + +func TestRPCAuth(t *testing.T) { + t.Parallel() + + makeAndStartProtectedNode := func(t *testing.T, authorizations map[string]*config.RPCAuthScope) *harness.Node { + authorizations["test-node-starter"] = &config.RPCAuthScope{ + AuthSecret: "bearer:test-node-starter", + AllowedPaths: []string{"/api/v0"}, + } + + node := harness.NewT(t).NewNode().Init() + node.UpdateConfig(func(cfg *config.Config) { + cfg.API.Authorizations = authorizations + }) + node.StartDaemonWithAuthorization("Bearer test-node-starter") + return node + } + + makeHTTPTest := func(authSecret, header string) func(t *testing.T) { + return func(t *testing.T) { + t.Parallel() + t.Log(authSecret, header) + + node := makeAndStartProtectedNode(t, map[string]*config.RPCAuthScope{ + "userA": { + AuthSecret: authSecret, + AllowedPaths: []string{"/api/v0/id"}, + }, + }) + + apiClient := node.APIClient() + apiClient.Client = &http.Client{ + Transport: auth.NewAuthorizedRoundTripper(header, http.DefaultTransport), + } + + // Can access /id with valid token + resp := apiClient.Post("/api/v0/id", nil) + assert.Equal(t, 200, resp.StatusCode) + + // But not /config/show + resp = apiClient.Post("/api/v0/config/show", nil) + assert.Equal(t, 403, resp.StatusCode) + + // create client which sends invalid access token + invalidApiClient := node.APIClient() + invalidApiClient.Client = &http.Client{ + Transport: auth.NewAuthorizedRoundTripper("Bearer invalid", http.DefaultTransport), + } + + // Can't access /id with invalid token + errResp := invalidApiClient.Post("/api/v0/id", nil) + assert.Equal(t, 403, errResp.StatusCode) + + node.StopDaemon() + } + } + + makeCLITest := func(authSecret string) func(t *testing.T) { + return func(t *testing.T) { + t.Parallel() + + node := makeAndStartProtectedNode(t, map[string]*config.RPCAuthScope{ + "userA": { + AuthSecret: authSecret, + AllowedPaths: []string{"/api/v0/id"}, + }, + }) + + // Can access 'ipfs id' + resp := node.RunIPFS("id", "--api-auth", authSecret) + require.NoError(t, resp.Err) + + // But not 'ipfs config show' + resp = node.RunIPFS("config", "show", "--api-auth", authSecret) + require.Error(t, resp.Err) + require.Contains(t, resp.Stderr.String(), rpcDeniedMsg) + + node.StopDaemon() + } + } + + for _, testCase := range []struct { + name string + authSecret string + header string + }{ + {"Bearer (no type)", "myToken", "Bearer myToken"}, + {"Bearer", "bearer:myToken", "Bearer myToken"}, + {"Basic (user:pass)", "basic:user:pass", "Basic dXNlcjpwYXNz"}, + {"Basic (encoded)", "basic:dXNlcjpwYXNz", "Basic dXNlcjpwYXNz"}, + } { + t.Run("AllowedPaths on CLI "+testCase.name, makeCLITest(testCase.authSecret)) + t.Run("AllowedPaths on HTTP "+testCase.name, makeHTTPTest(testCase.authSecret, testCase.header)) + } + + t.Run("AllowedPaths set to /api/v0 Gives Full Access", func(t *testing.T) { + t.Parallel() + + node := makeAndStartProtectedNode(t, map[string]*config.RPCAuthScope{ + "userA": { + AuthSecret: "bearer:userAToken", + AllowedPaths: []string{"/api/v0"}, + }, + }) + + apiClient := node.APIClient() + apiClient.Client = &http.Client{ + Transport: auth.NewAuthorizedRoundTripper("Bearer userAToken", http.DefaultTransport), + } + + resp := apiClient.Post("/api/v0/id", nil) + assert.Equal(t, 200, resp.StatusCode) + + node.StopDaemon() + }) + + t.Run("API.Authorizations set to nil disables Authorization header check", func(t *testing.T) { + t.Parallel() + + node := harness.NewT(t).NewNode().Init() + node.UpdateConfig(func(cfg *config.Config) { + cfg.API.Authorizations = nil + }) + node.StartDaemon() + + apiClient := node.APIClient() + resp := apiClient.Post("/api/v0/id", nil) + assert.Equal(t, 200, resp.StatusCode) + + node.StopDaemon() + }) + + t.Run("API.Authorizations set to empty map disables Authorization header check", func(t *testing.T) { + t.Parallel() + + node := harness.NewT(t).NewNode().Init() + node.UpdateConfig(func(cfg *config.Config) { + cfg.API.Authorizations = map[string]*config.RPCAuthScope{} + }) + node.StartDaemon() + + apiClient := node.APIClient() + resp := apiClient.Post("/api/v0/id", nil) + assert.Equal(t, 200, resp.StatusCode) + + node.StopDaemon() + }) +} From 48865a9092d1086952c3f2959b830dfac88ed126 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Mon, 20 Nov 2023 23:22:45 +0100 Subject: [PATCH 0946/1212] docs: move kubo-specific docs (#10226) * docs: move kubo-specific docs * chore: note crypt cmd does not exist Context: https://github.com/ipfs/specs/pull/455 --------- Co-authored-by: Marcin Rataj --- docs/specifications/fs-datastore.png | Bin 0 -> 49319 bytes docs/specifications/ipfs-repo-contents.png | Bin 0 -> 16097 bytes docs/specifications/keystore.md | 295 +++++++++++++++++++++ docs/specifications/repository.md | 131 +++++++++ docs/specifications/repository_fs.md | 279 +++++++++++++++++++ 5 files changed, 705 insertions(+) create mode 100644 docs/specifications/fs-datastore.png create mode 100644 docs/specifications/ipfs-repo-contents.png create mode 100644 docs/specifications/keystore.md create mode 100644 docs/specifications/repository.md create mode 100644 docs/specifications/repository_fs.md diff --git a/docs/specifications/fs-datastore.png b/docs/specifications/fs-datastore.png new file mode 100644 index 0000000000000000000000000000000000000000..0a5eaaa87ddfb226272f33334e9e25ee74be62e4 GIT binary patch literal 49319 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 literal 0 HcmV?d00001 diff --git a/docs/specifications/ipfs-repo-contents.png b/docs/specifications/ipfs-repo-contents.png new file mode 100644 index 0000000000000000000000000000000000000000..cfda9e5d9e3636deab2f9c7241b137fc18284b97 GIT binary patch literal 16097 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 literal 0 HcmV?d00001 diff --git a/docs/specifications/keystore.md b/docs/specifications/keystore.md new file mode 100644 index 000000000..7e588ca98 --- /dev/null +++ b/docs/specifications/keystore.md @@ -0,0 +1,295 @@ +# ![](https://img.shields.io/badge/status-wip-orange.svg?style=flat-square) Keystore + +**Authors(s):** +- [whyrusleeping](github.com/whyrusleeping) +- [Hector Sanjuan](github.com/hsanjuan) + +**Abstract** + +This spec provides definitions and operations for the keystore feature in IPFS. + +# Table of Contents + +- [Goals](#goals) +- [Planned Implementation](#planned-implementation) + - [Key storage](#key-storage) + - [Interface](#interface) + - [Code changes and additions](#code-changes-and-additions) + - [Structures](#structures) + +## Goals + +To have a secure, simple and user-friendly way of storing and managing keys +for use by ipfs. As well as the ability to share these keys, encrypt, decrypt, +sign and verify data. + +## Planned Implementation + +### Key storage + +Storage layout and format is defined in the [`repository_fs`](repository_fs.md) part of the spec. + +### Interface + +#### ipfs key + +``` +USAGE + ipfs key - Create and list IPNS name keypairs + + ipfs key + + 'ipfs key gen' generates a new keypair for usage with IPNS and 'ipfs name + publish'. + + > ipfs key gen --type=rsa --size=2048 mykey + > ipfs name publish --key=mykey QmSomeHash + + 'ipfs key list' lists the available keys. + + > ipfs key list + self + mykey + + +SUBCOMMANDS + ipfs key export - Export a keypair + ipfs key gen - Create a new keypair + ipfs key import - Import a key and prints imported key id + ipfs key list - List all local keypairs. + ipfs key rename - Rename a keypair. + ipfs key rm ... - Remove a keypair. + ipfs key rotate - Rotates the IPFS identity. + + For more information about each command, use: + 'ipfs key --help' +``` + +#### ipfs crypt + +**NOTE:** as of 2023 Q4, `ipfs crypt` commands are not implemented yet. + +``` + ipfs crypt - Perform cryptographic operations using ipfs keypairs + +SUBCOMMANDS: + + ipfs crypt sign - Generates a signature for the given data with a specified key + ipfs crypt verify - Verify that the given data and signature match + ipfs crypt encrypt - Encrypt the given data + ipfs crypt decrypt - Decrypt the given data + +DESCRIPTION: + + `ipfs crypt` is a command used to perform various cryptographic operations + using ipfs keypairs, including: signing, verifying, encrypting and decrypting. +``` + +#### Some subcommands: + +##### ipfs key Gen + + +``` +USAGE + ipfs key gen - Create a new keypair + +SYNOPSIS + ipfs key gen [--type= | -t] [--size= | -s] + [--ipns-base=] [--] + +ARGUMENTS + + - name of key to create + +OPTIONS + + -t, --type string - type of the key to create: rsa, ed25519. Default: + ed25519. + -s, --size int - size of the key to generate. + --ipns-base string - Encoding used for keys: Can either be a multibase + encoded CID or a base58btc encoded multihash. Takes + {b58mh|base36|k|base32|b...}. Default: base36. +``` + +* * * + +##### Key Send + +``` +USAGE + ipfs key - Create and list IPNS name keypairs + +SYNOPSIS + ipfs key + +DESCRIPTION + + 'ipfs key gen' generates a new keypair for usage with IPNS and 'ipfs name + publish'. + + > ipfs key gen --type=rsa --size=2048 mykey + > ipfs name publish --key=mykey QmSomeHash + + 'ipfs key list' lists the available keys. + + > ipfs key list + self + mykey + + +SUBCOMMANDS + ipfs key export - Export a keypair + ipfs key gen - Create a new keypair + ipfs key import - Import a key and prints imported key id + ipfs key list - List all local keypairs. + ipfs key rename - Rename a keypair. + ipfs key rm ... - Remove a keypair. + ipfs key rotate - Rotates the IPFS identity. + + For more information about each command, use: + 'ipfs key --help' +``` + +##### Comments: + +Ensure that the user knows the implications of sending a key. + +* * * + +##### Crypt Encrypt + +``` + ipfs crypt encrypt - Encrypt the given data with a specified key + +ARGUMENTS: + + data - The filename of the data to be encrypted ("-" for stdin) + +OPTIONS: + + -k, -key string - The name of the key to use for encryption (default: localkey) + -o, -output string - The name of the output file (default: stdout) + -c, -cipher string - The cipher to use for the operation + -m, -mode string - The block cipher mode to use for the operation + +DESCRIPTION: + + 'ipfs crypt encrypt' is a command used to encypt data so that only holders of a certain + key can read it. +``` + +##### Comments: + +This should probably just operate on raw data and not on DAGs. + +* * * + +##### Other Interface Changes + +We will also need to make additions to support keys in other commands, these changes are as follows: + +- `ipfs add` + - Support for a `-encrypt-key` option, for block encrypting the file being added with the key + - also adds an 'encrypted' node above the root unixfs node + - Support for a `-sign-key` option to attach a signature node above the root unixfs node + +- `ipfs block put` + - Support for a `-encrypt-key` option, for encrypting the block before hashing and storing + +- `ipfs object put` + - Support for a `-encrypt-key` option, for encrypting the object before hashing and storing + +- `ipfs name publish` + - Support for a `-key` option to select which keyspace to publish to + +### Code changes and additions + +This sections outlines code organization around this feature. + +#### Keystore package + +The fsrepo carries a `keystore` that can be used to load/store keys. The keystore is implemented following this interface: + +```go +// Keystore provides a key management interface +type Keystore interface { + // Has returns whether or not a key exist in the Keystore + Has(string) (bool, error) + // Put stores a key in the Keystore, if a key with the same name already exists, returns ErrKeyExists + Put(string, ci.PrivKey) error + // Get retrieves a key from the Keystore if it exists, and returns ErrNoSuchKey + // otherwise. + Get(string) (ci.PrivKey, error) + // Delete removes a key from the Keystore + Delete(string) error + // List returns a list of key identifier + List() ([]string, error) +} +``` + +Note: Never store passwords as strings, strings cannot be zeroed out after they are used. +using a byte array allows you to write zeroes over the memory so that the users password +does not linger in memory. + +#### Unixfs + +- new node types, 'encrypted' and 'signed', probably shouldn't be in unixfs, just understood by it +- if new node types are not unixfs nodes, special consideration must be given to the interop + +- DagReader needs to be able to access keystore to seamlessly stream encrypted data we have keys for + - also needs to be able to verify signatures + +#### Importer + +- DagBuilderHelper needs to be able to encrypt blocks + - Dag Nodes should be generated like normal, then encrypted, and their parents should + link to the hash of the encrypted node +- DagBuilderParams should have extra parameters to accommodate creating a DBH that encrypts the blocks + +#### New 'Encrypt' package + +Should contain code for crypto operations on dags. + +Encryption of dags should work by first generating a symmetric key, and using +that key to encrypt all the data. That key should then be encrypted with the +public key chosen and stored in the Encrypted DAG structure. + +Note: One option is to simply add it to the key interface. + +### Structures +Some tentative mockups (in json) of the new DAG structures for signing and encrypting + +Signed DAG: +``` +{ + "Links" : [ + { + "Name":"@content", + "Hash":"QmTheContent", + } + ], + "Data": protobuf{ + "Type":"Signed DAG", + "Signature": "thesignature", + "PubKeyID": "QmPubKeyHash", + } +} +``` + +Encrypted DAG: +``` +{ + "Links" : [ + { + "Name":"@content", + "Hash":"QmRawEncryptedDag", + } + ], + "Data": protobuf{ + "Type":"Encrypted DAG", + "PubKeyID": "QmPubKeyHash", + "Key": "ephemeral symmetric key, encrypted with public key", + } +} +``` diff --git a/docs/specifications/repository.md b/docs/specifications/repository.md new file mode 100644 index 000000000..0e7d663d5 --- /dev/null +++ b/docs/specifications/repository.md @@ -0,0 +1,131 @@ +# ![](https://img.shields.io/badge/status-wip-orange.svg?style=flat-square) IPFS Repo Spec + +**Author(s)**: +- [Juan Benet](github.com/jbenet) + +**Abstract** + +This spec defines an IPFS Repo, its contents, and its interface. It does not specify how the repo data is actually stored, as that is done via swappable implementations. + +# Table of Contents + +- [Definition](#definition) +- [Repo Contents](#repo-contents) + - [version](#version) + - [datastore](#datastore) + - [keystore](#keystore) + - [config (state)](#config-state) + - [locks](#locks) + - [datastore\_spec](#datastore_spec) + - [hooks (TODO)](#hooks-todo) +- [Notes](#notes) + +## Definition + +A `repo` is the storage repository of an IPFS node. It is the subsystem that +actually stores the data IPFS nodes use. All IPFS objects are stored +in a repo (similar to git). + +There are many possible repo implementations, depending on the storage media +used. Most commonly, IPFS nodes use an [fs-repo](repository_fs.md). + +Repo Implementations: +- [fs-repo](repository_fs.md) - stored in the os filesystem +- mem-repo - stored in process memory +- s3-repo - stored in amazon s3 + +## Repo Contents + +The Repo stores a collection of [IPLD](https://github.com/ipld/specs#readme) objects that represent: + +- **config** - node configuration and settings +- **datastore** - content stored locally, and indexing data +- **keystore** - cryptographic keys, including node's identity +- **hooks** - scripts to run at predefined times (not yet implemented) + +Note that the IPLD objects a repo stores are divided into: +- **state** (system, control plane) used for the node's internal state +- **content** (userland, data plane) which represent the user's cached and pinned data. + +Additionally, the repo state must determine the following. These need not be IPLD objects, though it is of course encouraged: + +- **version** - the repo version, required for safe migrations +- **locks** - process semaphores for correct concurrent access +- **datastore_spec** - array of mounting points and their properties + +Finally, the repo also stores the blocks with blobs containing binary data. + +![](./ipfs-repo-contents.png) + +### version + +Repo implementations may change over time, thus they MUST include a `version` recognizable across versions. Meaning that a tool MUST be able to read the `version` of a given repo type. + +For example, the `fs-repo` simply includes a `version` file with the version number. This way, the repo contents can evolve over time but the version remains readable the same way across versions. + +### datastore + +IPFS nodes store some IPLD objects locally. These are either (a) **state objects** required for local operation -- such as the `config` and `keys` -- or (b) **content objects** used to represent data locally available. **Content objects** are either _pinned_ (stored until they are unpinned) or _cached_ (stored until the next repo garbage collection). + +The name "datastore" comes from [go-datastore](https://github.com/jbenet/go-datastore), a library for swappable key-value stores. Like its name-sake, some repo implementations feature swappable datastores, for example: +- an fs-repo with a leveldb datastore +- an fs-repo with a boltdb datastore +- an fs-repo with a union fs and leveldb datastore +- an fs-repo with an s3 datastore +- an s3-repo with a cached fs and s3 datastore + +This makes it easy to change properties or performance characteristics of a repo without an entirely new implementation. + +### keystore + +A Repo typically holds the keys a node has access to, for signing and for encryption. + +Details on operation and storage of the keystore can be found in [`repository_fs.md`](repository_fs.md) and [`keystore.md`](keystore.md). + +### config (state) + +The node's `config` (configuration) is a tree of variables, used to configure various aspects of operation. For example: +- the set of bootstrap peers IPFS uses to connect to the network +- the Swarm, API, and Gateway network listen addresses +- the Datastore configuration regarding the construction and operation of the on-disk storage system. + +There is a set of properties, which are mandatory for the repo usage. Those are `Addresses`, `Discovery`, `Bootstrap`, `Identity`, `Datastore` and `Keychain`. + +It is recommended that `config` files avoid identifying information, so that they may be re-shared across multiple nodes. + +**CHANGES**: today, implementations like js-ipfs and go-ipfs store the peer-id and private key directly in the config. These will be removed and moved out. + +### locks + +IPFS implementations may use multiple processes, or may disallow multiple processes from using the same repo simultaneously. Others may disallow using the same repo but may allow sharing _datastores_ simultaneously. This synchronization is accomplished via _locks_. + +All repos contain the following standard locks: +- `repo.lock` - prevents concurrent access to the repo. Must be held to _read_ or _write_. + +### datastore_spec + +This file is created according to the Datastore configuration specified in the `config` file. It contains an array with all the mounting points that the repo is using, as well as its properties. This way, the `datastore_spec` file must have the same mounting points as defined in the Datastore configuration. + +It is important pointing out that the `Datastore` in config must have a `Spec` property, which defines the structure of the ipfs datastore. It is a composable structure, where each datastore is represented by a json object. + +### hooks (TODO) + +Like git, IPFS nodes will allow `hooks`, a set of user configurable scripts to run at predefined moments in IPFS operations. This makes it easy to customize the behavior of IPFS nodes without changing the implementations themselves. + +## Notes + +#### A Repo uniquely identifies an IPFS Node + +A repository uniquely identifies a node. Running two different IPFS programs with identical repositories -- and thus identical identities -- WILL cause problems. + +Datastores MAY be shared -- with proper synchronization -- though note that sharing datastore access MAY erode privacy. + +#### Repo implementation changes MUST include migrations + +**DO NOT BREAK USERS' DATA.** This is critical. Thus, any changes to a repo's implementation **MUST** be accompanied by a **SAFE** migration tool. + +See https://github.com/jbenet/go-ipfs/issues/537 and https://github.com/jbenet/random-ideas/issues/33 + +#### Repo Versioning + +A repo version is a single incrementing integer. All versions are considered non-compatible. Repos of different versions MUST be run through the appropriate migration tools before use. diff --git a/docs/specifications/repository_fs.md b/docs/specifications/repository_fs.md new file mode 100644 index 000000000..01e30d1c3 --- /dev/null +++ b/docs/specifications/repository_fs.md @@ -0,0 +1,279 @@ +# ![](https://img.shields.io/badge/status-wip-orange.svg?style=flat-square) fs-repo + +**Author(s)**: +- [Juan Benet](github.com/jbenet) +- [David Dias](github.com/daviddias) +- [Hector Sanjuan](github.com/hsanjuan) + +**Abstract** + +This spec defines `fs-repo` version `1`, its formats, and semantics. + +# Table of Contents + +- [Definition](#definition) +- [Contents](#contents) + - [api](#api) + - [blocks/](#blocks) + - [config](#config) + - [hooks/](#hooks) + - [keystore/](#keystore) + - [datastore/](#datastore) + - [logs/](#logs) + - [repo.lock](#repolock) + - [version](#version) +- [Datastore](#datastore-1) +- [Notes](#notes) + - [Location](#location) + - [blocks/ with an fs-datastore](#blocks-with-an-fs-datastore) + - [Reading without the `repo.lock`](#reading-without-the-repolock) + +## Definition + +`fs-repo` is a filesystem implementation of the IPFS [repo](repository.md). + + +## Contents + +![](img/ipfs-repo-contents.png?) + +``` +.ipfs/ +├── api <--- running daemon api addr +├── blocks/ <--- objects stored directly on disk +│ └── aa <--- prefix namespacing like git +│ └── aa <--- N tiers +├── config <--- config file (json or toml) +├── hooks/ <--- hook scripts +├── keystore/ <--- cryptographic keys +│ ├── key_b32name <--- private key with base32-encoded name +├── datastore/ <--- datastore +├── logs/ <--- 1 or more files (log rotate) +│ └── events.log <--- can be tailed +├── repo.lock <--- mutex for repo +└── version <--- version file +``` + +### api + +`./api` is a file that exists to denote an API endpoint to listen to. +- It MAY exist even if the endpoint is no longer live (i.e. it is a _stale_ or left-over `./api` file). + +In the presence of an `./api` file, ipfs tools (e.g. go-ipfs `ipfs daemon`) MUST attempt to delegate to the endpoint, and MAY remove the file if reasonably certain the file is stale. (e.g. endpoint is local, but no process is live) + +The `./api` file is used in conjunction with the `repo.lock`. Clients may opt to use the api service, or wait until the process holding `repo.lock` exits. The file's content is the api endpoint as a [multiaddr](https://github.com/jbenet/multiaddr) + +``` +> cat .ipfs/api +/ip4/127.0.0.1/tcp/5001 +``` + +Notes: +- The API server must remove the api file before releasing the `repo.lock`. +- It is not enough to use the `config` file, as the API addr of a daemon may + have been overridden via ENV or flag. + +#### api file for remote control + +One use case of the `api` file is to have a repo directory like: + +``` +> tree $IPFS_PATH +/Users/jbenet/.ipfs +└── api + +0 directories, 1 files + +> cat $IPFS_PATH/api +/ip4/1.2.3.4/tcp/5001 +``` + +In go-ipfs, this has the same effect as: + +``` +ipfs --api /ip4/1.2.3.4/tcp/5001 +``` + +Meaning that it makes ipfs tools use an ipfs node at the given endpoint, instead of the local directory as a repo. + +In this use case, the rest of the `$IPFS_PATH` may be completely empty, and no other information is necessary. It cannot be said it is a _repo_ per-se. (TODO: come up with a good name for this). + +### blocks/ + +The `block/` component contains the raw data representing all IPFS objects +stored locally, whether pinned or cached. This component is controlled by the ` +datastore`. For example, it may be stored within a leveldb instance in ` +datastore/`, or it may be stored entirely with independent files, like git. + +In the default case, the user uses fs-datastore for all `/blocks` so the +objects are stored in individual files. In other cases, `/blocks` may even be +stored remotely + +- [blocks/ with an fs-datastore](#blocks-with-an-fs-datastore) + +### config + +The `config` file is a JSON or TOML file that contains the tree of +configuration variables. It MUST only be changed while holding the +`repo.lock`, or potentially lose edits. + +### hooks/ + +The `hooks` directory contains executable scripts to be called on specific +events to alter ipfs node behavior. + +Currently available hooks: + +``` +none +``` + +### keystore/ + + +The `keystore` directory holds additional private keys that the node has +access to (the public keys can be derived from them). + +The keystore repository should have `0700` permissions (readable, writable by +the owner only). + +The key files are named as `key_base32encodedNameNoPadding` where `key_` is a +fixed prefix followed by a base32 encoded identifier, **without padding and +downcased**. The identifier usually corresponds to a human-friendly name given +by the user. + +The key files should have '0400' permissions (read-only, by the owner only). + +The `self` key identifier is reserved for the peer's main key, and therefore key named +`key_onswyzq` is allowed in this folder. + +The key files themselves contain a serialized representation of the keys as +defined in the +[libp2p specification](https://github.com/libp2p/specs/blob/master/peer-ids/peer-ids.md#keys). + +### datastore/ + +The `datastore` directory contains the data for a leveldb instance used to +store operation data for the IPFS node. If the user uses a `boltdb` datastore +instead, the directory will be named `boltdb`. Thus the data files of each +database will not clash. + +TODO: consider whether all should just be named `leveldb/` + +### logs/ + +IPFS implementations put event log files inside the `logs/` directory. The +latest log file is `logs/events`. Others, rotated out may exist, with a +timestamp of their creation. For example: + + + +### repo.lock + +`repo.lock` prevents concurrent access to the repo. Its content SHOULD BE the +PID of the process currently holding the lock. This allows clients to detect +a failed lock and cleanup. + +``` +> cat .ipfs/repo.lock +42 +> ps | grep "ipfs daemon" +42 ttys000 79:05.83 ipfs daemon +``` + +**TODO, ADDRESS DISCREPANCY:** the go-ipfs implementation does not currently store the PID in the file, which in some systems causes failures after a failure or a teardown. This SHOULD NOT require any manual intervention-- a present lock should give new processes enough information to recover. Doing this correctly in a portable, safe way, with good UX is very tricky. We must be careful with TOCTTOU bugs, and multiple concurrent processes capable of running at any moment. The goal is for all processes to operate safely, to avoid bothering the user, and for the repo to always remain in a correct, consistent state. + +### version + +The `version` file contains the repo implementation name and version. This format has changed over time: + +``` +# in version 0 +> cat $repo-at-version-0/version +cat: /Users/jbenet/.ipfs/version: No such file or directory + +# in versions 1 and 2 +> cat $repo-at-version-1/version +1 +> cat $repo-at-version-2/version +2 + +# in versions >3 +> cat $repo-at-version-3/version +fs-repo/3 +``` + +_Any_ fs-repo implementation of _any_ versions `>0` MUST be able to read the +`version` file. It MUST NOT change format between versions. The sole exception is version 0, which had no file. + +**TODO: ADDRESS DISCREPANCY:** versions 1 and 2 of the go-ipfs implementation use just the integer number. It SHOULD have used `fs-repo/`. We could either change the spec and always just use the int, or change go-ipfs in version `>3`. we will have to be backwards compatible. + +## Datastore + +Both the `/blocks` and `/datastore` directories are controlled by the +`datastore` component of the repo. + +## Notes + +### Location + +The `fs-repo` can be located anywhere on the filesystem. By default +clients should search for a repo in: + +``` +~/.ipfs +``` + +Users can tell IPFS programs to look elsewhere with the env var: + +``` +IPFS_PATH=/path/to/repo +``` + +### blocks/ with an fs-datastore + +![](fs-datastore.png) + +Each object is stored in its own file. The filename is the hash of the object. +The files are nested in directories whose names are prefixes of the hash, as +in `.git/objects`. + +For example: +```sh +# multihashes +1220fe389b55ea958590769f9046b0f7268bca90a92e4a9f45cbb30930f4bf89269d # sha2 +1114f623e0ec7f8719fb14a18838d2a3ef4e550b5e53 # sha1 + +# locations of the blocks +.ipfs/blocks/1114/f6/23/e0ec7f8719fb14a18838d2a3ef4e550b5e53 +.ipfs/blocks/1220/fe/38/9b55ea958590769f9046b0f7268bca90a92e4a9f45cbb30930f4bf89269d +``` + +**Important Notes:** +- the hashes are encoded in hex, not the usual base58, because some + filesystems are case insensitive. +- the multihash prefix is two bytes, which would waste two directory levels, + thus these are combined into one. +- the git `idx` and `pack` file formats could be used to coalesce objects + +**TODO: ADDRESS DISCREPANCY:** + +the go-ipfs fs-repo in version 2 uses a different `blocks/` dir layout: + +``` +/Users/jbenet/.ipfs/blocks +├── 12200007 +│ └── 12200007d4e3a319cd8c7c9979280e150fc5dbaae1ce54e790f84ae5fd3c3c1a0475.data +├── 1220000f +│ └── 1220000fadd95a98f3a47c1ba54a26c77e15c1a175a975d88cf198cc505a06295b12.data +``` + +We MUST address whether we should change the fs-repo spec to match go-ipfs in version 2, or we should change go-ipfs to match the fs-repo spec (more tiers). We MUST also address whether the levels are a repo version parameter or a config parameter. There are filesystems in which a different fanout will have wildly different performance. These are mostly networked and legacy filesystems. + +### Reading without the `repo.lock` + +Programs MUST hold the `repo.lock` while reading and writing most files in the +repo. The only two exceptions are: + +- `repo.lock` - so clients may check for it +- `api` - so clients may use the API From 2b347a914d631b79a63246e1e028dc1b9a15512a Mon Sep 17 00:00:00 2001 From: Jorropo Date: Sat, 18 Nov 2023 00:54:09 +0300 Subject: [PATCH 0947/1212] graphsync: remove support for the server Updates: #9396 Closes: #6831 Closes: #6208 Currently the Graphsync server is not widely used due to lack of compatible software. There have been many years yet we are unable to find any production software making use of the graphsync server in Kubo. There exists some in the filecoin ecosystem but we are not aware of uses with Kubo. Even in filecoin graphsync is not the only datatransfer solution available like it could have been in the past. `go-graphsync` is also developped on many concurrent branches. The specification for graphsync are less clear than the trustless gateway one and lack a complete conformance test suite any implementation can run. It is not easily extansible either because selectors are too limited for interesting queries without sideloading ADLs, which for now are hardcoded solutions. Finaly Kubo is consistently one of the fastest software to update to a new go-libp2p release. This means the burden to track go-libp2p changes in go-graphsync falls on us, else Kubo cannot compile even if almost all users do not use this feature. We are then removing the graphsync server experiment. For people who want alternatives we would like you to try the Trustless-Gateway-over-Libp2p experiment instead, the protocol is simpler (request-response-based) and let us reuse both clients and servers with minimal injection in the network layer. If you think this is a mistake and we should put it back you should try to answer theses points: - Find a piece of opensource code which uses a graphsync client to download data from Kubo. - Why is Trustless-Gateway-over-Libp2p not suitable instead ? - Why is bitswap not suitable instead ? Implementation details such as go-graphsync performance vs boxo/gateway is not very interesting to us in this discussion unless they are really huge (in the range of 10x~100x+ more) because the gateway code is under high development and we would be interested in fixing theses. --- config/experiments.go | 5 +- config/types.go | 24 ++ core/core.go | 2 - core/node/graphsync.go | 23 -- core/node/groups.go | 1 - docs/changelogs/v0.25.md | 10 + docs/examples/kubo-as-a-library/go.mod | 5 - docs/examples/kubo-as-a-library/go.sum | 11 - docs/experimental-features.md | 20 +- go.mod | 3 - go.sum | 8 - test/bin/Rules.mk | 5 - test/dependencies/go.mod | 58 +---- test/dependencies/go.sum | 211 +----------------- .../graphsync-get/graphsync-get.go | 128 ----------- test/sharness/Rules.mk | 2 +- test/sharness/t0221-graphsync.sh | 35 --- 17 files changed, 49 insertions(+), 502 deletions(-) delete mode 100644 core/node/graphsync.go delete mode 100644 test/dependencies/graphsync-get/graphsync-get.go delete mode 100755 test/sharness/t0221-graphsync.sh diff --git a/config/experiments.go b/config/experiments.go index 3a63d253d..fab1f953c 100644 --- a/config/experiments.go +++ b/config/experiments.go @@ -4,12 +4,13 @@ type Experiments struct { FilestoreEnabled bool UrlstoreEnabled bool ShardingEnabled bool `json:",omitempty"` // deprecated by autosharding: https://github.com/ipfs/kubo/pull/8527 - GraphsyncEnabled bool Libp2pStreamMounting bool P2pHttpProxy bool //nolint StrategicProviding bool - AcceleratedDHTClient experimentalAcceleratedDHTClient `json:",omitempty"` OptimisticProvide bool OptimisticProvideJobsPoolSize int GatewayOverLibp2p bool `json:",omitempty"` + + GraphsyncEnabled graphsyncEnabled `json:",omitempty"` + AcceleratedDHTClient experimentalAcceleratedDHTClient `json:",omitempty"` } diff --git a/config/types.go b/config/types.go index 131324efe..506139318 100644 --- a/config/types.go +++ b/config/types.go @@ -481,3 +481,27 @@ func (experimentalAcceleratedDHTClient) UnmarshalJSON(b []byte) error { // does not support omitempty on structs and I can't be bothered to write custom // marshalers on all structs that have a doNotUse field. type doNotUse bool + +type graphsyncEnabled doNotUse + +var _ json.Unmarshaler = graphsyncEnabled(false) + +func (graphsyncEnabled) UnmarshalJSON(b []byte) error { + d := json.NewDecoder(bytes.NewReader(b)) + for { + switch tok, err := d.Token(); err { + case io.EOF: + return nil + case nil: + switch tok { + case json.Delim('{'), json.Delim('}'), false: + // accept empty objects and false + continue + } + //nolint + return fmt.Errorf("Support for Experimental.GraphsyncEnabled has been removed in Kubo 0.25.0, please remove this key. For more details see https://github.com/ipfs/kubo/pull/9747.") + default: + return err + } + } +} diff --git a/core/core.go b/core/core.go index 40c680859..0c9333e06 100644 --- a/core/core.go +++ b/core/core.go @@ -26,7 +26,6 @@ import ( mfs "github.com/ipfs/boxo/mfs" pathresolver "github.com/ipfs/boxo/path/resolver" provider "github.com/ipfs/boxo/provider" - "github.com/ipfs/go-graphsync" ipld "github.com/ipfs/go-ipld-format" logging "github.com/ipfs/go-log" goprocess "github.com/jbenet/goprocess" @@ -107,7 +106,6 @@ type IpfsNode struct { 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"` diff --git a/core/node/graphsync.go b/core/node/graphsync.go deleted file mode 100644 index 4425d66ff..000000000 --- a/core/node/graphsync.go +++ /dev/null @@ -1,23 +0,0 @@ -package node - -import ( - blockstore "github.com/ipfs/boxo/blockstore" - "github.com/ipfs/go-graphsync" - gsimpl "github.com/ipfs/go-graphsync/impl" - "github.com/ipfs/go-graphsync/network" - "github.com/ipfs/go-graphsync/storeutil" - libp2p "github.com/libp2p/go-libp2p/core" - "go.uber.org/fx" - - "github.com/ipfs/kubo/core/node/helpers" -) - -// Graphsync constructs a graphsync -func Graphsync(lc fx.Lifecycle, mctx helpers.MetricsCtx, host libp2p.Host, bs blockstore.GCBlockstore) graphsync.GraphExchange { - ctx := helpers.LifecycleCtx(mctx, lc) - - network := network.NewFromLibp2pHost(host) - return gsimpl.New(ctx, network, - storeutil.LinkSystemForBlockstore(bs), - ) -} diff --git a/core/node/groups.go b/core/node/groups.go index e101bb3ed..e1e2e4b9c 100644 --- a/core/node/groups.go +++ b/core/node/groups.go @@ -290,7 +290,6 @@ func Online(bcfg *BuildCfg, cfg *config.Config, userResourceOverrides rcmgr.Part return fx.Options( fx.Provide(BitswapOptions(cfg, shouldBitswapProvide)), fx.Provide(OnlineExchange()), - maybeProvide(Graphsync, cfg.Experimental.GraphsyncEnabled), fx.Provide(DNSResolver), fx.Provide(Namesys(ipnsCacheSize)), fx.Provide(Peering), diff --git a/docs/changelogs/v0.25.md b/docs/changelogs/v0.25.md index 1ad032ed3..98e2a04f9 100644 --- a/docs/changelogs/v0.25.md +++ b/docs/changelogs/v0.25.md @@ -7,6 +7,7 @@ - [Overview](#overview) - [🔦 Highlights](#-highlights) - [RPC `API.Authorizations`](#rpc-apiauthorizations) + - [Graphsync Experiment Removal](#graphsync-experiment-removal) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -27,6 +28,15 @@ This feature is opt-in. By default, no authorization is set up. For configuration instructions, refer to the [documentation](https://github.com/ipfs/kubo/blob/master/docs/config.md#apiauthorizations). +#### Graphsync Experiment Removal + +Currently the Graphsync server is to our knowledge not used +due to lack of compatible software. +And we are left to have to maintain the go-graphsync implementation when trying +to update Kubo because some dependency changed and it fails to build anymore. + +For more information see https://github.com/ipfs/kubo/pull/9747. + ### 📝 Changelog ### 👨‍👩‍👧‍👦 Contributors diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index a370e26a3..d930f99fb 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -55,7 +55,6 @@ require ( github.com/google/uuid v1.3.1 // indirect github.com/gorilla/websocket v1.5.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 // indirect - github.com/hannahhoward/go-pubsub v0.0.0-20200423002714-8d62886cc36e // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/golang-lru v0.5.4 // indirect @@ -74,11 +73,8 @@ require ( github.com/ipfs/go-ds-leveldb v0.5.0 // indirect github.com/ipfs/go-ds-measure v0.2.0 // indirect github.com/ipfs/go-fs-lock v0.0.7 // indirect - github.com/ipfs/go-graphsync v0.16.0 // indirect - github.com/ipfs/go-ipfs-blockstore v1.3.0 // indirect github.com/ipfs/go-ipfs-delay v0.0.1 // indirect github.com/ipfs/go-ipfs-ds-help v1.1.0 // indirect - github.com/ipfs/go-ipfs-files v0.3.0 // indirect github.com/ipfs/go-ipfs-pq v0.0.3 // indirect github.com/ipfs/go-ipfs-redirects-file v0.1.1 // indirect github.com/ipfs/go-ipfs-util v0.0.3 // indirect @@ -195,7 +191,6 @@ require ( go.opentelemetry.io/otel/sdk v1.16.0 // indirect go.opentelemetry.io/otel/trace v1.17.0 // indirect go.opentelemetry.io/proto/otlp v0.19.0 // indirect - go.uber.org/atomic v1.11.0 // indirect go.uber.org/dig v1.17.1 // indirect go.uber.org/fx v1.20.1 // indirect go.uber.org/mock v0.3.0 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 527925973..1dc80d229 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -280,8 +280,6 @@ github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 h1:BZHcxBETFHIdVyhyEfOvn/RdU/QG github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= -github.com/hannahhoward/go-pubsub v0.0.0-20200423002714-8d62886cc36e h1:3YKHER4nmd7b5qy5t0GWDTwSn4OyRgfAXSmo6VnryBY= -github.com/hannahhoward/go-pubsub v0.0.0-20200423002714-8d62886cc36e/go.mod h1:I8h3MITA53gN9OnWGCgaMa0JWVRdXthWw4M3CPM54OY= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -343,10 +341,7 @@ github.com/ipfs/go-ds-measure v0.2.0 h1:sG4goQe0KDTccHMyT45CY1XyUbxe5VwTKpg2LjAp github.com/ipfs/go-ds-measure v0.2.0/go.mod h1:SEUD/rE2PwRa4IQEC5FuNAmjJCyYObZr9UvVh8V3JxE= github.com/ipfs/go-fs-lock v0.0.7 h1:6BR3dajORFrFTkb5EpCUFIAypsoxpGpDSVUdFwzgL9U= github.com/ipfs/go-fs-lock v0.0.7/go.mod h1:Js8ka+FNYmgQRLrRXzU3CB/+Csr1BwrRilEcvYrHhhc= -github.com/ipfs/go-graphsync v0.16.0 h1:0BX7whXlV13Y9FZ/jRg+xaGHaGYbtGxGppKD6tncw6k= -github.com/ipfs/go-graphsync v0.16.0/go.mod h1:WfbMW3hhmX5GQEQ+KJxsFzVJVBKgC5szfrYK7Zc7xIM= github.com/ipfs/go-ipfs-blockstore v1.3.0 h1:m2EXaWgwTzAfsmt5UdJ7Is6l4gJcaM/A12XwJyvYvMM= -github.com/ipfs/go-ipfs-blockstore v1.3.0/go.mod h1:KgtZyc9fq+P2xJUiCAzbRdhhqJHvsw8u2Dlqy2MyRTE= github.com/ipfs/go-ipfs-blocksutil v0.0.1 h1:Eh/H4pc1hsvhzsQoMEP3Bke/aW5P5rVM1IWFJMcGIPQ= github.com/ipfs/go-ipfs-chunker v0.0.5 h1:ojCf7HV/m+uS2vhUGWcogIIxiO5ubl5O57Q7NapWLY8= github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= @@ -356,9 +351,6 @@ github.com/ipfs/go-ipfs-ds-help v1.1.0 h1:yLE2w9RAsl31LtfMt91tRZcrx+e61O5mDxFRR9 github.com/ipfs/go-ipfs-ds-help v1.1.0/go.mod h1:YR5+6EaebOhfcqVCyqemItCLthrpVNot+rsOU/5IatU= github.com/ipfs/go-ipfs-exchange-interface v0.2.0 h1:8lMSJmKogZYNo2jjhUs0izT+dck05pqUw4mWNW9Pw6Y= github.com/ipfs/go-ipfs-exchange-offline v0.3.0 h1:c/Dg8GDPzixGd0MC8Jh6mjOwU57uYokgWRFidfvEkuA= -github.com/ipfs/go-ipfs-files v0.3.0 h1:fallckyc5PYjuMEitPNrjRfpwl7YFt69heCOUhsbGxQ= -github.com/ipfs/go-ipfs-files v0.3.0/go.mod h1:xAUtYMwB+iu/dtf6+muHNSFQCJG2dSiStR2P6sn9tIM= -github.com/ipfs/go-ipfs-posinfo v0.0.1 h1:Esoxj+1JgSjX0+ylc0hUmJCOv6V2vFoZiETLR6OtpRs= github.com/ipfs/go-ipfs-pq v0.0.3 h1:YpoHVJB+jzK15mr/xsWC574tyDLkezVrDNeaalQBsTE= github.com/ipfs/go-ipfs-pq v0.0.3/go.mod h1:btNw5hsHBpRcSSgZtiNm/SLj5gYIZ18AKtv3kERkRb4= github.com/ipfs/go-ipfs-redirects-file v0.1.1 h1:Io++k0Vf/wK+tfnhEh63Yte1oQK5VGT2hIEYpD0Rzx8= @@ -376,7 +368,6 @@ github.com/ipfs/go-ipld-git v0.1.1 h1:TWGnZjS0htmEmlMFEkA3ogrNCqWjIxwr16x1OsdhG+ github.com/ipfs/go-ipld-git v0.1.1/go.mod h1:+VyMqF5lMcJh4rwEppV0e6g4nCCHXThLYYDpKUkJubI= github.com/ipfs/go-ipld-legacy v0.2.1 h1:mDFtrBpmU7b//LzLSypVrXsD8QxkEWxu5qVxN99/+tk= github.com/ipfs/go-ipld-legacy v0.2.1/go.mod h1:782MOUghNzMO2DER0FlBR94mllfdCJCkTtDtPM51otM= -github.com/ipfs/go-libipfs v0.7.0 h1:Mi54WJTODaOL2/ZSm5loi3SwI3jI2OuFWUrQIkJ5cpM= github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= github.com/ipfs/go-log v1.0.3/go.mod h1:OsLySYkwIbiSUR/yBTdv1qPtcE4FW3WPWk/ewz9Ru+A= github.com/ipfs/go-log v1.0.5 h1:2dOuUCB1Z7uoczMWgAyDck5JLb72zHzrMnGnCNNbvY8= @@ -409,7 +400,6 @@ github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7Bd github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/jbenet/go-cienv v0.1.0 h1:Vc/s0QbQtoxX8MwwSLWWh+xNNZvM3Lw7NsTcHrvvhMc= github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA= -github.com/jbenet/go-random v0.0.0-20190219211222-123a90aedc0c h1:uUx61FiAa1GI6ZmVd2wf2vULeQZIKG66eybjNXKYCz4= github.com/jbenet/go-temp-err-catcher v0.1.0 h1:zpb3ZH6wIE8Shj2sKS+khgRvf7T7RABoLk/+KKHggpk= github.com/jbenet/go-temp-err-catcher v0.1.0/go.mod h1:0kJRvmDZXNMIiJirNPEYfhpPwbGVtZVWC34vc5WLsDk= github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY= @@ -852,7 +842,6 @@ go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= -go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= go.uber.org/fx v1.20.1 h1:zVwVQGS8zYvhh9Xxcu4w1M6ESyeMzebzj2NbSayZ4Mk= diff --git a/docs/experimental-features.md b/docs/experimental-features.md index 6826a38c2..09640274e 100644 --- a/docs/experimental-features.md +++ b/docs/experimental-features.md @@ -518,25 +518,11 @@ ipfs config --json Experimental.StrategicProviding true ### State -Experimental, disabled by default. +Removed, no plans to reintegrate either as experimental or stable feature. -[GraphSync](https://github.com/ipfs/go-graphsync) is the next-gen graph exchange -protocol for IPFS. +[Trustless Gateway over Libp2p](#http-gateway-over-libp2p) should be easier to use for unixfs usecases and support basic wildcard car streams for non unixfs. -When this feature is enabled, IPFS will make files available over the graphsync -protocol. However, IPFS will not currently use this protocol to _fetch_ files. - -### How to enable - -Modify your ipfs config: - -``` -ipfs config --json Experimental.GraphsyncEnabled true -``` - -### Road to being a real feature - -- [ ] We need to confirm that it can't be used to DoS a node. The server-side logic for GraphSync is quite complex and, if we're not careful, the server might end up performing unbounded work when responding to a malicious request. +See https://github.com/ipfs/kubo/pull/9747 for more information. ## Noise diff --git a/go.mod b/go.mod index b4797b84a..6b114c9f7 100644 --- a/go.mod +++ b/go.mod @@ -28,7 +28,6 @@ require ( github.com/ipfs/go-ds-leveldb v0.5.0 github.com/ipfs/go-ds-measure v0.2.0 github.com/ipfs/go-fs-lock v0.0.7 - github.com/ipfs/go-graphsync v0.16.0 github.com/ipfs/go-ipfs-cmds v0.10.0 github.com/ipfs/go-ipld-format v0.6.0 github.com/ipfs/go-ipld-git v0.1.1 @@ -129,7 +128,6 @@ require ( github.com/gorilla/mux v1.8.0 // indirect github.com/gorilla/websocket v1.5.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 // indirect - github.com/hannahhoward/go-pubsub v0.0.0-20200423002714-8d62886cc36e // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/golang-lru v0.5.4 // indirect github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect @@ -145,7 +143,6 @@ require ( github.com/ipfs/go-ipfs-redirects-file v0.1.1 // indirect github.com/ipfs/go-ipfs-util v0.0.3 // indirect github.com/ipfs/go-ipld-cbor v0.0.6 // indirect - github.com/ipfs/go-libipfs v0.7.0 // indirect github.com/ipfs/go-merkledag v0.11.0 // indirect github.com/ipfs/go-peertaskqueue v0.8.1 // indirect github.com/ipfs/go-verifcid v0.0.2 // indirect diff --git a/go.sum b/go.sum index 0a52cb585..a28c6ab3b 100644 --- a/go.sum +++ b/go.sum @@ -314,8 +314,6 @@ github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 h1:BZHcxBETFHIdVyhyEfOvn/RdU/QG github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= -github.com/hannahhoward/go-pubsub v0.0.0-20200423002714-8d62886cc36e h1:3YKHER4nmd7b5qy5t0GWDTwSn4OyRgfAXSmo6VnryBY= -github.com/hannahhoward/go-pubsub v0.0.0-20200423002714-8d62886cc36e/go.mod h1:I8h3MITA53gN9OnWGCgaMa0JWVRdXthWw4M3CPM54OY= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -379,8 +377,6 @@ github.com/ipfs/go-ds-measure v0.2.0 h1:sG4goQe0KDTccHMyT45CY1XyUbxe5VwTKpg2LjAp github.com/ipfs/go-ds-measure v0.2.0/go.mod h1:SEUD/rE2PwRa4IQEC5FuNAmjJCyYObZr9UvVh8V3JxE= github.com/ipfs/go-fs-lock v0.0.7 h1:6BR3dajORFrFTkb5EpCUFIAypsoxpGpDSVUdFwzgL9U= github.com/ipfs/go-fs-lock v0.0.7/go.mod h1:Js8ka+FNYmgQRLrRXzU3CB/+Csr1BwrRilEcvYrHhhc= -github.com/ipfs/go-graphsync v0.16.0 h1:0BX7whXlV13Y9FZ/jRg+xaGHaGYbtGxGppKD6tncw6k= -github.com/ipfs/go-graphsync v0.16.0/go.mod h1:WfbMW3hhmX5GQEQ+KJxsFzVJVBKgC5szfrYK7Zc7xIM= github.com/ipfs/go-ipfs-blockstore v1.3.0 h1:m2EXaWgwTzAfsmt5UdJ7Is6l4gJcaM/A12XwJyvYvMM= github.com/ipfs/go-ipfs-blockstore v1.3.0/go.mod h1:KgtZyc9fq+P2xJUiCAzbRdhhqJHvsw8u2Dlqy2MyRTE= github.com/ipfs/go-ipfs-blocksutil v0.0.1 h1:Eh/H4pc1hsvhzsQoMEP3Bke/aW5P5rVM1IWFJMcGIPQ= @@ -395,8 +391,6 @@ github.com/ipfs/go-ipfs-ds-help v1.1.0/go.mod h1:YR5+6EaebOhfcqVCyqemItCLthrpVNo github.com/ipfs/go-ipfs-exchange-interface v0.2.0 h1:8lMSJmKogZYNo2jjhUs0izT+dck05pqUw4mWNW9Pw6Y= github.com/ipfs/go-ipfs-exchange-interface v0.2.0/go.mod h1:z6+RhJuDQbqKguVyslSOuVDhqF9JtTrO3eptSAiW2/Y= github.com/ipfs/go-ipfs-exchange-offline v0.3.0 h1:c/Dg8GDPzixGd0MC8Jh6mjOwU57uYokgWRFidfvEkuA= -github.com/ipfs/go-ipfs-files v0.3.0 h1:fallckyc5PYjuMEitPNrjRfpwl7YFt69heCOUhsbGxQ= -github.com/ipfs/go-ipfs-posinfo v0.0.1 h1:Esoxj+1JgSjX0+ylc0hUmJCOv6V2vFoZiETLR6OtpRs= github.com/ipfs/go-ipfs-pq v0.0.3 h1:YpoHVJB+jzK15mr/xsWC574tyDLkezVrDNeaalQBsTE= github.com/ipfs/go-ipfs-pq v0.0.3/go.mod h1:btNw5hsHBpRcSSgZtiNm/SLj5gYIZ18AKtv3kERkRb4= github.com/ipfs/go-ipfs-redirects-file v0.1.1 h1:Io++k0Vf/wK+tfnhEh63Yte1oQK5VGT2hIEYpD0Rzx8= @@ -415,8 +409,6 @@ github.com/ipfs/go-ipld-git v0.1.1 h1:TWGnZjS0htmEmlMFEkA3ogrNCqWjIxwr16x1OsdhG+ github.com/ipfs/go-ipld-git v0.1.1/go.mod h1:+VyMqF5lMcJh4rwEppV0e6g4nCCHXThLYYDpKUkJubI= github.com/ipfs/go-ipld-legacy v0.2.1 h1:mDFtrBpmU7b//LzLSypVrXsD8QxkEWxu5qVxN99/+tk= github.com/ipfs/go-ipld-legacy v0.2.1/go.mod h1:782MOUghNzMO2DER0FlBR94mllfdCJCkTtDtPM51otM= -github.com/ipfs/go-libipfs v0.7.0 h1:Mi54WJTODaOL2/ZSm5loi3SwI3jI2OuFWUrQIkJ5cpM= -github.com/ipfs/go-libipfs v0.7.0/go.mod h1:KsIf/03CqhICzyRGyGo68tooiBE2iFbI/rXW7FhAYr0= github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= github.com/ipfs/go-log v1.0.3/go.mod h1:OsLySYkwIbiSUR/yBTdv1qPtcE4FW3WPWk/ewz9Ru+A= github.com/ipfs/go-log v1.0.5 h1:2dOuUCB1Z7uoczMWgAyDck5JLb72zHzrMnGnCNNbvY8= diff --git a/test/bin/Rules.mk b/test/bin/Rules.mk index 02b0a4e5b..4e264106a 100644 --- a/test/bin/Rules.mk +++ b/test/bin/Rules.mk @@ -18,11 +18,6 @@ $(d)/go-sleep: github.com/ipfs/kubo/test/dependencies/go-sleep $(go-build-testdep) TGTS_$(d) += $(d)/go-sleep -.PHONY: github.com/ipfs/kubo/test/dependencies/graphsync-get -$(d)/graphsync-get: github.com/ipfs/kubo/test/dependencies/graphsync-get - $(go-build-testdep) -TGTS_$(d) += $(d)/graphsync-get - .PHONY: github.com/ipfs/kubo/test/dependencies/go-timeout $(d)/go-timeout: github.com/ipfs/kubo/test/dependencies/go-timeout $(go-build-testdep) diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index dd6346b62..5bfe4383f 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -7,19 +7,13 @@ replace github.com/ipfs/kubo => ../../ require ( github.com/Kubuxu/gocovmerge v0.0.0-20161216165753-7ecaa51963cd github.com/golangci/golangci-lint v1.54.1 - github.com/ipfs/boxo v0.15.0 - github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 - github.com/ipfs/go-datastore v0.6.0 - github.com/ipfs/go-graphsync v0.16.0 github.com/ipfs/go-log v1.0.5 github.com/ipfs/hang-fds v0.1.0 github.com/ipfs/iptb v1.4.0 github.com/ipfs/iptb-plugins v0.5.0 - github.com/ipld/go-ipld-prime v0.21.0 github.com/jbenet/go-random v0.0.0-20190219211222-123a90aedc0c github.com/jbenet/go-random-files v0.0.0-20190219210431-31b3f20ebded - github.com/libp2p/go-libp2p v0.32.1 github.com/multiformats/go-multiaddr v0.12.0 github.com/multiformats/go-multihash v0.2.3 gotest.tools/gotestsum v0.4.2 @@ -37,13 +31,11 @@ require ( github.com/GaijinEntertainment/go-exhaustruct/v3 v3.1.0 // indirect github.com/Masterminds/semver v1.5.0 // indirect github.com/OpenPeeDeeP/depguard/v2 v2.1.0 // indirect - github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect github.com/alexkohler/nakedret/v2 v2.0.2 // indirect github.com/alexkohler/prealloc v1.0.0 // indirect github.com/alingse/asasalint v0.0.11 // indirect github.com/ashanbrown/forbidigo v1.6.0 // indirect github.com/ashanbrown/makezero v1.1.1 // indirect - github.com/benbjohnson/clock v1.3.5 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bkielbasa/cyclop v1.2.1 // indirect github.com/blizzy78/varnamelen v0.8.0 // indirect @@ -55,32 +47,24 @@ require ( github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/charithe/durationcheck v0.0.10 // indirect github.com/chavacava/garif v0.0.0-20230227094218-b8c73b2037b8 // indirect - github.com/containerd/cgroups v1.1.0 // indirect - github.com/coreos/go-systemd/v22 v22.5.0 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/curioswitch/go-reassign v0.2.0 // indirect github.com/daixiang0/gci v0.11.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect github.com/denis-tingaikin/go-header v0.4.3 // indirect - github.com/docker/go-units v0.5.0 // indirect github.com/dustin/go-humanize v1.0.1 // indirect - github.com/elastic/gosigar v0.14.2 // indirect github.com/esimonov/ifshort v1.0.4 // indirect github.com/ettle/strcase v0.1.1 // indirect github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5 // indirect github.com/fatih/color v1.15.0 // indirect github.com/fatih/structtag v1.2.0 // indirect github.com/firefart/nonamedreturns v1.0.4 // indirect - github.com/flynn/noise v1.0.0 // indirect - github.com/francoispqt/gojay v1.2.13 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/fzipp/gocyclo v0.6.0 // indirect github.com/go-critic/go-critic v0.9.0 // indirect github.com/go-logr/logr v1.2.4 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/go-toolsmith/astcast v1.1.0 // indirect github.com/go-toolsmith/astcopy v1.1.0 // indirect github.com/go-toolsmith/astequal v1.1.0 // indirect @@ -90,7 +74,6 @@ require ( github.com/go-toolsmith/typep v1.1.0 // indirect github.com/go-xmlfmt/xmlfmt v1.1.2 // indirect github.com/gobwas/glob v0.2.3 // indirect - github.com/godbus/dbus/v5 v5.1.0 // indirect github.com/gofrs/flock v0.8.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.3 // indirect @@ -105,16 +88,13 @@ require ( github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4 // indirect github.com/google/go-cmp v0.5.9 // indirect github.com/google/gopacket v1.1.19 // indirect - github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b // indirect github.com/google/uuid v1.3.1 // indirect github.com/gordonklaus/ineffassign v0.0.0-20230610083614-0e73809eb601 // indirect - github.com/gorilla/websocket v1.5.0 // indirect github.com/gostaticanalysis/analysisutil v0.7.1 // indirect github.com/gostaticanalysis/comment v1.4.2 // indirect github.com/gostaticanalysis/forcetypeassert v0.1.0 // indirect github.com/gostaticanalysis/nilerr v0.1.1 // indirect github.com/gxed/go-shellwords v1.0.3 // indirect - github.com/hannahhoward/go-pubsub v0.0.0-20200423002714-8d62886cc36e // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-version v1.6.0 // indirect @@ -122,26 +102,20 @@ require ( github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/hexops/gotextdiff v1.0.3 // indirect - github.com/huin/goupnp v1.3.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/ipfs/bbloom v0.0.4 // indirect - github.com/ipfs/go-bitfield v1.1.0 // indirect + github.com/ipfs/boxo v0.15.0 // indirect github.com/ipfs/go-block-format v0.2.0 // indirect - github.com/ipfs/go-ipfs-blockstore v1.3.0 // indirect - github.com/ipfs/go-ipfs-ds-help v1.1.0 // indirect - github.com/ipfs/go-ipfs-files v0.2.0 // indirect - github.com/ipfs/go-ipfs-pq v0.0.3 // indirect + github.com/ipfs/go-cid v0.4.1 // indirect + github.com/ipfs/go-datastore v0.6.0 // indirect github.com/ipfs/go-ipfs-util v0.0.3 // indirect github.com/ipfs/go-ipld-format v0.6.0 // indirect github.com/ipfs/go-ipld-legacy v0.2.1 // indirect github.com/ipfs/go-log/v2 v2.5.1 // indirect github.com/ipfs/go-metrics-interface v0.0.1 // indirect - github.com/ipfs/go-peertaskqueue v0.8.1 // indirect - github.com/ipfs/go-unixfsnode v1.8.1 // indirect github.com/ipfs/kubo v0.16.0 // indirect github.com/ipld/go-codec-dagpb v1.6.0 // indirect - github.com/jackpal/go-nat-pmp v1.0.2 // indirect - github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect + github.com/ipld/go-ipld-prime v0.21.0 // indirect github.com/jbenet/goprocess v0.1.4 // indirect github.com/jgautheron/goconst v1.5.1 // indirect github.com/jingyugao/rowserrcheck v1.1.1 // indirect @@ -151,9 +125,7 @@ require ( github.com/kisielk/errcheck v1.6.3 // indirect github.com/kisielk/gotool v1.0.0 // indirect github.com/kkHAIKE/contextcheck v1.1.4 // indirect - github.com/klauspost/compress v1.17.2 // indirect github.com/klauspost/cpuid/v2 v2.2.5 // indirect - github.com/koron/go-ssdp v0.0.4 // indirect github.com/kulti/thelper v0.6.3 // indirect github.com/kunwardeep/paralleltest v1.0.8 // indirect github.com/kyoh86/exportloopref v0.1.11 // indirect @@ -162,22 +134,18 @@ require ( github.com/leonklingele/grouper v1.1.1 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/libp2p/go-cidranger v1.1.0 // indirect - github.com/libp2p/go-flow-metrics v0.1.0 // indirect + github.com/libp2p/go-libp2p v0.32.1 // indirect github.com/libp2p/go-libp2p-asn-util v0.3.0 // indirect github.com/libp2p/go-libp2p-kad-dht v0.24.4 // indirect github.com/libp2p/go-libp2p-kbucket v0.6.3 // indirect github.com/libp2p/go-libp2p-record v0.2.0 // indirect github.com/libp2p/go-libp2p-routing-helpers v0.7.3 // indirect github.com/libp2p/go-msgio v0.3.0 // indirect - github.com/libp2p/go-nat v0.2.0 // indirect github.com/libp2p/go-netroute v0.2.1 // indirect - github.com/libp2p/go-reuseport v0.4.0 // indirect - github.com/libp2p/go-yamux/v4 v4.0.1 // indirect github.com/lufeee/execinquery v1.2.1 // indirect github.com/magiconair/properties v1.8.6 // indirect github.com/maratori/testableexamples v1.0.0 // indirect github.com/maratori/testpackage v1.1.1 // indirect - github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect github.com/matoous/godox v0.0.0-20230222163458-006bad1f9d26 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect @@ -186,8 +154,6 @@ require ( github.com/mbilski/exhaustivestruct v1.2.0 // indirect github.com/mgechev/revive v1.3.2 // indirect github.com/miekg/dns v1.1.56 // indirect - github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect - github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect github.com/minio/sha256-simd v1.0.1 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect @@ -196,7 +162,6 @@ require ( github.com/multiformats/go-base32 v0.1.0 // indirect github.com/multiformats/go-base36 v0.2.0 // indirect github.com/multiformats/go-multiaddr-dns v0.3.1 // indirect - github.com/multiformats/go-multiaddr-fmt v0.1.0 // indirect github.com/multiformats/go-multibase v0.2.0 // indirect github.com/multiformats/go-multicodec v0.9.0 // indirect github.com/multiformats/go-multistream v0.5.0 // indirect @@ -207,10 +172,8 @@ require ( github.com/nishanths/predeclared v0.2.2 // indirect github.com/nunnatsa/ginkgolinter v0.13.3 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect - github.com/onsi/ginkgo/v2 v2.13.0 // indirect - github.com/opencontainers/runtime-spec v1.1.0 // indirect + github.com/onsi/gomega v1.27.10 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect - github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect github.com/pelletier/go-toml v1.9.5 // indirect github.com/pelletier/go-toml/v2 v2.0.5 // indirect github.com/pkg/errors v0.9.1 // indirect @@ -225,11 +188,6 @@ require ( github.com/quasilyte/gogrep v0.5.0 // indirect github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727 // indirect github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 // indirect - github.com/quic-go/qpack v0.4.0 // indirect - github.com/quic-go/qtls-go1-20 v0.3.4 // indirect - github.com/quic-go/quic-go v0.39.3 // indirect - github.com/quic-go/webtransport-go v0.6.0 // indirect - github.com/raulk/go-watchdog v1.3.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/ryancurrah/gomodguard v1.3.0 // indirect github.com/ryanrolds/sqlclosecheck v0.4.0 // indirect @@ -279,10 +237,6 @@ require ( go.opentelemetry.io/otel/metric v1.19.0 // indirect go.opentelemetry.io/otel/trace v1.19.0 // indirect go.tmz.dev/musttag v0.7.1 // indirect - go.uber.org/atomic v1.11.0 // indirect - go.uber.org/dig v1.17.1 // indirect - go.uber.org/fx v1.20.1 // indirect - go.uber.org/mock v0.3.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.26.0 // indirect golang.org/x/crypto v0.14.0 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 8c9012722..b1f18cd5f 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -3,9 +3,7 @@ 4d63.com/gochecknoglobals v0.2.1 h1:1eiorGsgHOFOuoOiJDy2psSrQbRdIHrlge0IJIkUgDc= 4d63.com/gochecknoglobals v0.2.1/go.mod h1:KRE8wtJB3CXCsb1xy421JfTHIIbmT3U5ruxw2Qu8fSU= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.31.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.37.0/go.mod h1:TS1dMSSfndXH133OKGwekG838Om/cQT0BUHV3HcBgoo= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= @@ -41,12 +39,7 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= -dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU= -dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4= -dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU= -git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg= github.com/4meepo/tagalign v1.3.2 h1:1idD3yxlRGV18VjqtDbqYvQ5pXqQS0wO2dn6M3XstvI= github.com/4meepo/tagalign v1.3.2/go.mod h1:Q9c1rYMZJc9dPRkbQPpcBNCLEmY2njbAsXhQOZFE2dE= github.com/Abirdcfly/dupword v0.0.12 h1:56NnOyrXzChj07BDFjeRA+IUzSz01jmzEq+G4kEgFhc= @@ -74,23 +67,18 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= -github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 h1:s6gZFSlWYmbqAuRjVTiNNhvNRfY2Wxp9nhfyel4rklc= -github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= github.com/alexkohler/nakedret/v2 v2.0.2 h1:qnXuZNvv3/AxkAb22q/sEsEpcA99YxLFACDtEw9TPxE= github.com/alexkohler/nakedret/v2 v2.0.2/go.mod h1:2b8Gkk0GsOrqQv/gPWjNLDSKwG8I5moSXG1K4VIBcTQ= github.com/alexkohler/prealloc v1.0.0 h1:Hbq0/3fJPQhNkN0dR95AVrr6R7tou91y0uHG5pOcUuw= github.com/alexkohler/prealloc v1.0.0/go.mod h1:VetnK3dIgFBBKmg0YnD9F9x6Icjd+9cvfHR56wJVlKE= github.com/alingse/asasalint v0.0.11 h1:SFwnQXJ49Kx/1GghOFz1XGqHYKp21Kq1nHad/0WQRnw= github.com/alingse/asasalint v0.0.11/go.mod h1:nCaoMhw7a9kSJObvQyVzNTPBDbNpdocqrSP7t/cW5+I= -github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= github.com/ashanbrown/forbidigo v1.6.0 h1:D3aewfM37Yb3pxHujIPSpTf6oQk9sc9WZi8gerOIVIY= github.com/ashanbrown/forbidigo v1.6.0/go.mod h1:Y8j9jy9ZYAEHXdu723cUlraTqbzjKF1MUyfOKL+AjcU= github.com/ashanbrown/makezero v1.1.1 h1:iCQ87C0V0vSyO+M9E/FZYbu65auqH0lnsOkf5FcB28s= github.com/ashanbrown/makezero v1.1.1/go.mod h1:i1bJLCRSCHOcOa9Y6MyF2FTfMZMFdHvxKHxgO5Z1axI= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= -github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o= -github.com/benbjohnson/clock v1.3.5/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -101,12 +89,10 @@ github.com/blizzy78/varnamelen v0.8.0 h1:oqSblyuQvFsW1hbBHh1zfwrKe3kcSj0rnXkKzsQ github.com/blizzy78/varnamelen v0.8.0/go.mod h1:V9TzQZ4fLJ1DSrjVDfl89H7aMnTvKkApdHeyESmyR7k= github.com/bombsimon/wsl/v3 v3.4.0 h1:RkSxjT3tmlptwfgEgTgU+KYKLI35p/tviNXNXiL2aNU= github.com/bombsimon/wsl/v3 v3.4.0/go.mod h1:KkIB+TXkqy6MvK9BDZVbZxKNYsE1/oLRJbIFtf14qqo= -github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= github.com/breml/bidichk v0.2.4 h1:i3yedFWWQ7YzjdZJHnPo9d/xURinSq3OM+gyM43K4/8= github.com/breml/bidichk v0.2.4/go.mod h1:7Zk0kRFt1LIZxtQdl9W9JwGAcLTTkOs+tN7wuEYGJ3s= github.com/breml/errchkjson v0.3.1 h1:hlIeXuspTyt8Y/UmP5qy1JocGNR00KQHgfaNtRAjoxQ= github.com/breml/errchkjson v0.3.1/go.mod h1:XroxrzKjdiutFyW3nWhw34VGg7kiMsDQox73yWCGI2U= -github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= github.com/butuzov/ireturn v0.2.0 h1:kCHi+YzC150GE98WFuZQu9yrTn6GEydO2AuPLbTgnO4= github.com/butuzov/ireturn v0.2.0/go.mod h1:Wh6Zl3IMtTpaIKbmwzqi6olnM9ptYQxxVacMsOEFPoc= github.com/butuzov/mirror v1.1.0 h1:ZqX54gBVMXu78QLoiqdwpl2mgmoOJTk7s4p4o+0avZI= @@ -123,23 +109,15 @@ github.com/chavacava/garif v0.0.0-20230227094218-b8c73b2037b8/go.mod h1:gakxgyXa 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/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= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/containerd/cgroups v0.0.0-20201119153540-4cbc285b3327/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE= github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM= -github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw= -github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= -github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= 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/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/crackcomm/go-gitignore v0.0.0-20170627025303-887ab5e44cc3 h1:HVTnpeuvF6Owjd5mniCL8DEXo7uYXdQEmOP4FJbV5tg= github.com/cskr/pubsub v1.0.2 h1:vlOzMhl6PFn60gRlTQQsIfVwaPB/B/8MziK8FhEPt/0= github.com/curioswitch/go-reassign v0.2.0 h1:G9UZyOcpk/d7Gd6mqYgd8XYWFMw/znxwGDUstnC9DIo= github.com/curioswitch/go-reassign v0.2.0/go.mod h1:x6OpXuWvgfQaMGks2BZybTngWjT84hqJfKoO8Tt/Roc= @@ -149,21 +127,15 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c h1:pFUpOrbxDR6AkioZ1ySsx5yxlDQZ8stG2b88gTPxgJU= -github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c/go.mod h1:6UhI8N9EjYm1c2odKpFpAYeR8dsBeM7PtzQhRgxRr9U= github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= github.com/denis-tingaikin/go-header v0.4.3 h1:tEaZKAlqql6SKCY++utLmkPLd6K8IBM20Ha7UVm+mtU= github.com/denis-tingaikin/go-header v0.4.3/go.mod h1:0wOCWuN71D5qIgE2nz9KrKmuYBAC2Mra5RassOIQ2/c= -github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= -github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= -github.com/elastic/gosigar v0.12.0/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= github.com/elastic/gosigar v0.14.2 h1:Dg80n8cr90OZ7x+bAax/QjoW/XqTI11RmA79ZwIm9/4= -github.com/elastic/gosigar v0.14.2/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -183,22 +155,16 @@ github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4 github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94= github.com/firefart/nonamedreturns v1.0.4 h1:abzI1p7mAEPYuR4A+VLKn4eNDOycjYo2phmY9sfv40Y= github.com/firefart/nonamedreturns v1.0.4/go.mod h1:TDhe/tjI1BXo48CmYbUduTV7BdIga8MAO/xbKdcVsGI= -github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/flynn/noise v1.0.0 h1:DlTHqmzmvcEiKj+4RYo/imoswx/4r6iBlCMfVtrMXpQ= -github.com/flynn/noise v1.0.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag= github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk= -github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/fzipp/gocyclo v0.6.0 h1:lsblElZG7d3ALtGMx9fmxeTKZaLLpU8mET09yN4BBLo= github.com/fzipp/gocyclo v0.6.0/go.mod h1:rXPyn8fnlpa0R2csP/31uerbiVBugk5whMdlyaLkLoA= -github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/go-critic/go-critic v0.9.0 h1:Pmys9qvU3pSML/3GEQ2Xd9RZ/ip+aXHKILuxczKGV/U= github.com/go-critic/go-critic v0.9.0/go.mod h1:5P8tdXL7m/6qnyG6oRAlYLORvoXH0WDypYgAEmagT40= -github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -215,7 +181,6 @@ github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= -github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/go-toolsmith/astcast v1.1.0 h1:+JN9xZV1A+Re+95pgnMgDboWNVnIMMQXwfBwLRPgSC8= github.com/go-toolsmith/astcast v1.1.0/go.mod h1:qdcuFWeGGS2xX5bLM/c3U9lewg7+Zu4mr+xPwZIB4ZU= github.com/go-toolsmith/astcopy v1.1.0 h1:YGwBN0WM+ekI/6SS6+52zLDEf8Yvp3n2seZITCUBt5s= @@ -238,14 +203,10 @@ github.com/go-xmlfmt/xmlfmt v1.1.2/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6C github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= -github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= -github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= @@ -253,7 +214,6 @@ github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4er github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= -github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= @@ -316,8 +276,6 @@ github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= -github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= @@ -335,14 +293,10 @@ github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b h1:RMpPgZTSApbPf7xaVel+QkoGPRLFLrwFO89uDUHEGf0= -github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= -github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= @@ -351,7 +305,6 @@ github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c h1:7lF+Vz0LqiRid github.com/gordonklaus/ineffassign v0.0.0-20230610083614-0e73809eb601 h1:mrEEilTAUmaAORhssPPkxj84TsHrPMLBGW2Z4SoTxm8= github.com/gordonklaus/ineffassign v0.0.0-20230610083614-0e73809eb601/go.mod h1:Qcp2HIAYhR7mNUVSIxZww3Guk4it82ghYcEXIAk+QT0= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= -github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gostaticanalysis/analysisutil v0.7.1 h1:ZMCjoue3DtDWQ5WyU16YbjbQEQ3VuzwxALrpYd+HeKk= github.com/gostaticanalysis/analysisutil v0.7.1/go.mod h1:v21E3hY37WKMGSnbsw2S/ojApNWb6C1//mXO48CXbVc= github.com/gostaticanalysis/comment v1.4.1/go.mod h1:ih6ZxzTHLdadaiSnF5WY3dxUoXfXAlTaRzuaNDlSado= @@ -363,12 +316,8 @@ github.com/gostaticanalysis/nilerr v0.1.1 h1:ThE+hJP0fEp4zWLkWHWcRyI2Od0p7DlgYG3 github.com/gostaticanalysis/nilerr v0.1.1/go.mod h1:wZYb6YI5YAxxq0i1+VJbY0s2YONW0HU0GPE3+5PWN4A= github.com/gostaticanalysis/testutil v0.3.1-0.20210208050101-bfb5c8eec0e4/go.mod h1:D+FIZ+7OahH3ePw/izIEeH5I06eKs1IKI4Xr64/Am3M= github.com/gostaticanalysis/testutil v0.4.0 h1:nhdCmubdmDF6VEatUNjgUZBJKWRqugoISdUv3PPQgHY= -github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= -github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= github.com/gxed/go-shellwords v1.0.3 h1:2TP32H4TAklZUdz84oj95BJhVnIrRasyx2j1cqH5K38= github.com/gxed/go-shellwords v1.0.3/go.mod h1:N7paucT91ByIjmVJHhvoarjoQnmsi3Jd3vH7VqgtMxQ= -github.com/hannahhoward/go-pubsub v0.0.0-20200423002714-8d62886cc36e h1:3YKHER4nmd7b5qy5t0GWDTwSn4OyRgfAXSmo6VnryBY= -github.com/hannahhoward/go-pubsub v0.0.0-20200423002714-8d62886cc36e/go.mod h1:I8h3MITA53gN9OnWGCgaMa0JWVRdXthWw4M3CPM54OY= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -389,7 +338,6 @@ github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUq github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= -github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= @@ -398,84 +346,52 @@ github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= github.com/ipfs/boxo v0.15.0 h1:BriLydj2nlK1nKeJQHxcKSuG5ZXcoutzhBklOtxC5pk= github.com/ipfs/boxo v0.15.0/go.mod h1:X5ulcbR5Nh7sm3Db8+08AApUo6FsGC5mb23QDKAoB/M= -github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= -github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs= github.com/ipfs/go-block-format v0.2.0/go.mod h1:+jpL11nFx5A/SPpsoBn6Bzkra/zaArfSmsknbPMYgzM= -github.com/ipfs/go-blockservice v0.5.0 h1:B2mwhhhVQl2ntW2EIpaWPwSCxSuqr5fFA93Ms4bYLEY= -github.com/ipfs/go-cid v0.0.5/go.mod h1:plgt+Y5MnOey4vO4UlUazGqdbEXuFYitED67FexhXog= github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= github.com/ipfs/go-cid v0.4.1/go.mod h1:uQHwDeX4c6CtyrFwdqyhpNcxVewur1M7l7fNU7LKwZk= github.com/ipfs/go-cidutil v0.1.0 h1:RW5hO7Vcf16dplUU60Hs0AKDkQAVPVplr7lk97CFL+Q= github.com/ipfs/go-cidutil v0.1.0/go.mod h1:e7OEVBMIv9JaOxt9zaGEmAoSlXW9jdFZ5lP/0PwcfpA= -github.com/ipfs/go-datastore v0.5.0/go.mod h1:9zhEApYMTl17C8YDp7JmU7sQZi2/wqiYh73hakZ90Bk= github.com/ipfs/go-datastore v0.6.0 h1:JKyz+Gvz1QEZw0LsX1IBn+JFCJQH4SJVFtM4uWU0Myk= github.com/ipfs/go-datastore v0.6.0/go.mod h1:rt5M3nNbSO/8q1t4LNkLyUwRs8HupMeN/8O4Vn9YAT8= github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk= github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps= -github.com/ipfs/go-graphsync v0.16.0 h1:0BX7whXlV13Y9FZ/jRg+xaGHaGYbtGxGppKD6tncw6k= -github.com/ipfs/go-graphsync v0.16.0/go.mod h1:WfbMW3hhmX5GQEQ+KJxsFzVJVBKgC5szfrYK7Zc7xIM= -github.com/ipfs/go-ipfs-blockstore v1.3.0 h1:m2EXaWgwTzAfsmt5UdJ7Is6l4gJcaM/A12XwJyvYvMM= -github.com/ipfs/go-ipfs-blockstore v1.3.0/go.mod h1:KgtZyc9fq+P2xJUiCAzbRdhhqJHvsw8u2Dlqy2MyRTE= github.com/ipfs/go-ipfs-blocksutil v0.0.1 h1:Eh/H4pc1hsvhzsQoMEP3Bke/aW5P5rVM1IWFJMcGIPQ= -github.com/ipfs/go-ipfs-chunker v0.0.5 h1:ojCf7HV/m+uS2vhUGWcogIIxiO5ubl5O57Q7NapWLY8= -github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= github.com/ipfs/go-ipfs-delay v0.0.1 h1:r/UXYyRcddO6thwOnhiznIAiSvxMECGgtv35Xs1IeRQ= -github.com/ipfs/go-ipfs-ds-help v1.1.0 h1:yLE2w9RAsl31LtfMt91tRZcrx+e61O5mDxFRR994w4Q= -github.com/ipfs/go-ipfs-ds-help v1.1.0/go.mod h1:YR5+6EaebOhfcqVCyqemItCLthrpVNot+rsOU/5IatU= -github.com/ipfs/go-ipfs-exchange-interface v0.2.0 h1:8lMSJmKogZYNo2jjhUs0izT+dck05pqUw4mWNW9Pw6Y= -github.com/ipfs/go-ipfs-exchange-offline v0.3.0 h1:c/Dg8GDPzixGd0MC8Jh6mjOwU57uYokgWRFidfvEkuA= -github.com/ipfs/go-ipfs-files v0.2.0 h1:z6MCYHQSZpDWpUSK59Kf0ajP1fi4gLCf6fIulVsp8A8= -github.com/ipfs/go-ipfs-files v0.2.0/go.mod h1:vT7uaQfIsprKktzbTPLnIsd+NGw9ZbYwSq0g3N74u0M= -github.com/ipfs/go-ipfs-posinfo v0.0.1 h1:Esoxj+1JgSjX0+ylc0hUmJCOv6V2vFoZiETLR6OtpRs= github.com/ipfs/go-ipfs-pq v0.0.3 h1:YpoHVJB+jzK15mr/xsWC574tyDLkezVrDNeaalQBsTE= -github.com/ipfs/go-ipfs-pq v0.0.3/go.mod h1:btNw5hsHBpRcSSgZtiNm/SLj5gYIZ18AKtv3kERkRb4= github.com/ipfs/go-ipfs-util v0.0.3 h1:2RFdGez6bu2ZlZdI+rWfIdbQb1KudQp3VGwPtdNCmE0= github.com/ipfs/go-ipfs-util v0.0.3/go.mod h1:LHzG1a0Ig4G+iZ26UUOMjHd+lfM84LZCrn17xAKWBvs= -github.com/ipfs/go-ipld-cbor v0.0.6 h1:pYuWHyvSpIsOOLw4Jy7NbBkCyzLDcl64Bf/LZW7eBQ0= github.com/ipfs/go-ipld-format v0.6.0 h1:VEJlA2kQ3LqFSIm5Vu6eIlSxD/Ze90xtc4Meten1F5U= github.com/ipfs/go-ipld-format v0.6.0/go.mod h1:g4QVMTn3marU3qXchwjpKPKgJv+zF+OlaKMyhJ4LHPg= github.com/ipfs/go-ipld-legacy v0.2.1 h1:mDFtrBpmU7b//LzLSypVrXsD8QxkEWxu5qVxN99/+tk= github.com/ipfs/go-ipld-legacy v0.2.1/go.mod h1:782MOUghNzMO2DER0FlBR94mllfdCJCkTtDtPM51otM= -github.com/ipfs/go-libipfs v0.7.0 h1:Mi54WJTODaOL2/ZSm5loi3SwI3jI2OuFWUrQIkJ5cpM= github.com/ipfs/go-log v1.0.5 h1:2dOuUCB1Z7uoczMWgAyDck5JLb72zHzrMnGnCNNbvY8= github.com/ipfs/go-log v1.0.5/go.mod h1:j0b8ZoR+7+R99LD9jZ6+AJsrzkPbSXbZfGakb5JPtIo= github.com/ipfs/go-log/v2 v2.1.3/go.mod h1:/8d0SH3Su5Ooc31QlL1WysJhvyOTDCjcCZ9Axpmri6g= github.com/ipfs/go-log/v2 v2.5.1 h1:1XdUzF7048prq4aBjDQQ4SL5RxftpRGdXhNRwKSAlcY= github.com/ipfs/go-log/v2 v2.5.1/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOLU9U5UI= -github.com/ipfs/go-merkledag v0.11.0 h1:DgzwK5hprESOzS4O1t/wi6JDpyVQdvm9Bs59N/jqfBY= github.com/ipfs/go-metrics-interface v0.0.1 h1:j+cpbjYvu4R8zbleSs36gvB7jR+wsL2fGD6n0jO4kdg= github.com/ipfs/go-metrics-interface v0.0.1/go.mod h1:6s6euYU4zowdslK0GKHmqaIZ3j/b/tL7HTWtJ4VPgWY= github.com/ipfs/go-peertaskqueue v0.8.1 h1:YhxAs1+wxb5jk7RvS0LHdyiILpNmRIRnZVztekOF0pg= -github.com/ipfs/go-peertaskqueue v0.8.1/go.mod h1:Oxxd3eaK279FxeydSPPVGHzbwVeHjatZ2GA8XD+KbPU= -github.com/ipfs/go-unixfs v0.4.5 h1:wj8JhxvV1G6CD7swACwSKYa+NgtdWC1RUit+gFnymDU= -github.com/ipfs/go-unixfsnode v1.8.1 h1:nEWQl2XL+Zoyh6u0OMzNI8mUeCKLyRgg65WDbTm/oNU= -github.com/ipfs/go-unixfsnode v1.8.1/go.mod h1:HxRu9HYHOjK6HUqFBAi++7DVoWAHn0o4v/nZ/VA+0g8= -github.com/ipfs/go-verifcid v0.0.2 h1:XPnUv0XmdH+ZIhLGKg6U2vaPaRDXb9urMyNVCE7uvTs= github.com/ipfs/hang-fds v0.1.0 h1:deBiFlWHsVGzJ0ZMaqscEqRM1r2O1rFZ59UiQXb1Xko= github.com/ipfs/hang-fds v0.1.0/go.mod h1:29VLWOn3ftAgNNgXg/al7b11UzuQ+w7AwtCGcTaWkbM= github.com/ipfs/iptb v1.4.0 h1:YFYTrCkLMRwk/35IMyC6+yjoQSHTEcNcefBStLJzgvo= github.com/ipfs/iptb v1.4.0/go.mod h1:1rzHpCYtNp87/+hTxG5TfCVn/yMY3dKnLn8tBiMfdmg= github.com/ipfs/iptb-plugins v0.5.0 h1:zEMLlWAb531mLpD36KFy/yc0egT6FkBEHQtdERexNao= github.com/ipfs/iptb-plugins v0.5.0/go.mod h1:/6crDf3s58T70BhZ+m9SyyKpK7VvSDS2Ny4kafxXDp4= -github.com/ipld/go-car v0.5.0 h1:kcCEa3CvYMs0iE5BzD5sV7O2EwMiCIp3uF8tA6APQT8= -github.com/ipld/go-car/v2 v2.10.2-0.20230622090957-499d0c909d33 h1:0OZwzSYWIuiKEOXd/2vm5cMcEmmGLFn+1h6lHELCm3s= github.com/ipld/go-codec-dagpb v1.6.0 h1:9nYazfyu9B1p3NAgfVdpRco3Fs2nFC72DqVsMj6rOcc= github.com/ipld/go-codec-dagpb v1.6.0/go.mod h1:ANzFhfP2uMJxRBr8CE+WQWs5UsNa0pYtmKZ+agnUw9s= github.com/ipld/go-ipld-prime v0.21.0 h1:n4JmcpOlPDIxBcY037SVfpd1G+Sj1nKZah0m6QH9C2E= github.com/ipld/go-ipld-prime v0.21.0/go.mod h1:3RLqy//ERg/y5oShXXdx5YIp50cFGOanyMctpPjsvxQ= github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= -github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA= github.com/jbenet/go-random v0.0.0-20190219211222-123a90aedc0c h1:uUx61FiAa1GI6ZmVd2wf2vULeQZIKG66eybjNXKYCz4= github.com/jbenet/go-random v0.0.0-20190219211222-123a90aedc0c/go.mod h1:sdx1xVM9UuLw1tXnhJWN3piypTUO3vCIHYmG15KE/dU= github.com/jbenet/go-random-files v0.0.0-20190219210431-31b3f20ebded h1:fHCa28iw+qaRWZK4IqrntHxXALD5kKr/ESrpOCRRdrg= github.com/jbenet/go-random-files v0.0.0-20190219210431-31b3f20ebded/go.mod h1:FKvZrl5nnaGnTAMewcq0i7wM5zHD75e0lwlnF8q46uo= github.com/jbenet/go-temp-err-catcher v0.1.0 h1:zpb3ZH6wIE8Shj2sKS+khgRvf7T7RABoLk/+KKHggpk= -github.com/jbenet/go-temp-err-catcher v0.1.0/go.mod h1:0kJRvmDZXNMIiJirNPEYfhpPwbGVtZVWC34vc5WLsDk= github.com/jbenet/goprocess v0.1.4 h1:DRGOFReOMqqDNXwW70QkacFW0YN9QnwLV0Vqk+3oU0o= github.com/jbenet/goprocess v0.1.4/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= -github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU= github.com/jgautheron/goconst v1.5.1 h1:HxVbL1MhydKs8R8n/HE5NPvzfaYmQJA3o879lE4+WcM= github.com/jgautheron/goconst v1.5.1/go.mod h1:aAosetZ5zaeC/2EfMeRswtxUFBpe2Hr7HzkgX4fanO4= github.com/jingyugao/rowserrcheck v1.1.1 h1:zibz55j/MJtLsjP1OF4bSdgXxwL1b+Vn7Tjzq7gFzUs= @@ -498,7 +414,6 @@ github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7V github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/julz/importas v0.1.0 h1:F78HnrsjY3cR7j0etXy5+TU1Zuy7Xt08X/1aJnH5xXY= github.com/julz/importas v0.1.0/go.mod h1:oSFU2R4XK/P7kNBrnL/FEQlDGN1/6WoxXEjSSXO0DV0= -github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/errcheck v1.6.3 h1:dEKh+GLHcWm2oN34nMvDzn1sqI0i0WxPvrgiJA5JuM8= github.com/kisielk/errcheck v1.6.3/go.mod h1:nXw/i/MfnvRHqXa7XXmQMUB0oNFGuBrNI8d8NLy0LPw= @@ -507,21 +422,16 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o github.com/kkHAIKE/contextcheck v1.1.4 h1:B6zAaLhOEEcjvUgIYEqystmnFk1Oemn8bvJhbt0GMb8= github.com/kkHAIKE/contextcheck v1.1.4/go.mod h1:1+i/gWqokIa+dm31mqGLZhZJ7Uh44DJGZVmr6QRBNJg= github.com/klauspost/compress v1.17.2 h1:RlWWUY/Dr4fL8qk9YG7DTZ7PDgME2V4csBXA8L/ixi4= -github.com/klauspost/compress v1.17.2/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/koron/go-ssdp v0.0.4 h1:1IDwrghSKYM7yLf7XCzbByg2sJ/JcNOZRXS2jczTwz0= -github.com/koron/go-ssdp v0.0.4/go.mod h1:oDXq+E5IL5q0U8uSBcoAXzTzInwy5lEgC91HoKtbmZk= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kulti/thelper v0.6.3 h1:ElhKf+AlItIu+xGnI990no4cE2+XaSu1ULymV2Yulxs= @@ -541,7 +451,6 @@ github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QT github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38yPW7c= github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= -github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= github.com/libp2p/go-libp2p v0.32.1 h1:wy1J4kZIZxOaej6NveTWCZmHiJ/kY7GoAqXgqNCnPps= github.com/libp2p/go-libp2p v0.32.1/go.mod h1:hXXC3kXPlBZ1eu8Q2hptGrMB4mZ3048JUoS4EKaHW5c= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= @@ -558,25 +467,19 @@ github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUI github.com/libp2p/go-msgio v0.3.0 h1:mf3Z8B1xcFN314sWX+2vOTShIE0Mmn2TXn3YCUQGNj0= github.com/libp2p/go-msgio v0.3.0/go.mod h1:nyRM819GmVaF9LX3l03RMh10QdOroF++NBbxAb0mmDM= github.com/libp2p/go-nat v0.2.0 h1:Tyz+bUFAYqGyJ/ppPPymMGbIgNRH+WqC5QrT5fKrrGk= -github.com/libp2p/go-nat v0.2.0/go.mod h1:3MJr+GRpRkyT65EpVPBstXLvOlAPzUVlG6Pwg9ohLJk= github.com/libp2p/go-netroute v0.2.1 h1:V8kVrpD8GK0Riv15/7VN6RbUQ3URNZVosw7H2v9tksU= github.com/libp2p/go-netroute v0.2.1/go.mod h1:hraioZr0fhBjG0ZRXJJ6Zj2IVEVNx6tDTFQfSmcq7mQ= github.com/libp2p/go-reuseport v0.4.0 h1:nR5KU7hD0WxXCJbmw7r2rhRYruNRl2koHw8fQscQm2s= -github.com/libp2p/go-reuseport v0.4.0/go.mod h1:ZtI03j/wO5hZVDFo2jKywN6bYKWLOy8Se6DrI2E1cLU= github.com/libp2p/go-yamux/v4 v4.0.1 h1:FfDR4S1wj6Bw2Pqbc8Uz7pCxeRBPbwsBbEdfwiCypkQ= -github.com/libp2p/go-yamux/v4 v4.0.1/go.mod h1:NWjl8ZTLOGlozrXSOZ/HlfG++39iKNnM5wwmtQP1YB4= github.com/lufeee/execinquery v1.2.1 h1:hf0Ems4SHcUGBxpGN7Jz78z1ppVkP/837ZlETPCEtOM= github.com/lufeee/execinquery v1.2.1/go.mod h1:EC7DrEKView09ocscGHC+apXMIaorh4xqSxS/dy8SbM= -github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo= github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= -github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/maratori/testableexamples v1.0.0 h1:dU5alXRrD8WKSjOUnmJZuzdxWOEQ57+7s93SLMxb2vI= github.com/maratori/testableexamples v1.0.0/go.mod h1:4rhjL1n20TUTT4vdh3RDqSizKLyXp7K2u6HgraZCGzE= github.com/maratori/testpackage v1.1.1 h1:S58XVV5AD7HADMmD0fNnziNHqKvSdDuEKdPD1rNTU04= github.com/maratori/testpackage v1.1.1/go.mod h1:s4gRK/ym6AMrqpOa/kEbQTV4Q4jb7WeLZzVhVVVOQMc= 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/matoous/godox v0.0.0-20230222163458-006bad1f9d26 h1:gWg6ZQ4JhDfJPqlo2srm/LN17lpybq15AryXIRcWYLE= github.com/matoous/godox v0.0.0-20230222163458-006bad1f9d26/go.mod h1:1BELzlh859Sh1c6+90blK8lbYy0kwQf1bYlBhBysy1s= github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE= @@ -598,16 +501,11 @@ github.com/mbilski/exhaustivestruct v1.2.0 h1:wCBmUnSYufAHO6J4AVWY6ff+oxWxsVFrwg github.com/mbilski/exhaustivestruct v1.2.0/go.mod h1:OeTBVxQWoEmB2J2JCHmXWPJ0aksxSUOUy+nvtVEfzXc= github.com/mgechev/revive v1.3.2 h1:Wb8NQKBaALBJ3xrrj4zpwJwqwNA6nDpyJSEQWcCka6U= github.com/mgechev/revive v1.3.2/go.mod h1:UCLtc7o5vg5aXCwdUTU1kEBQ1v+YXPAkYDIDXbrs5I0= -github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= github.com/miekg/dns v1.1.56 h1:5imZaSeoRNvpM9SzWNhEcP9QliKiz20/dA2QabIGVnE= github.com/miekg/dns v1.1.56/go.mod h1:cRm6Oo2C8TY9ZS/TqsSrseAcncm74lfK5G+ikN2SWWY= -github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c h1:bzE/A84HN25pxAuk9Eej1Kz9OUelF97nAc82bDquQI8= -github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c/go.mod h1:0SQS9kMwD2VsyFEB++InYyBJroV/FRmBgcydeSUcJms= github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= -github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b/go.mod h1:lxPUiZwKoFL8DUUmalo2yJJUCxbPKtm8OKfqr2/FTNU= github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc h1:PTfri+PuQmWDqERdnNMiD9ZejrlswWrCpBEZgWOiTrc= -github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc/go.mod h1:cGKTAVKx4SxOuR/czcZ/E2RSJ3sfHs8FpHhQ5CWMf9s= github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM= @@ -623,37 +521,29 @@ github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3Rllmb github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/moricho/tparallel v0.3.1 h1:fQKD4U1wRMAYNngDonW5XupoB/ZGJHdpzrWqgyg9krA= github.com/moricho/tparallel v0.3.1/go.mod h1:leENX2cUv7Sv2qDgdi0D0fCftN8fRC67Bcn8pqzeYNI= -github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= -github.com/mr-tron/base58 v1.1.3/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= -github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= github.com/multiformats/go-base32 v0.1.0 h1:pVx9xoSPqEIQG8o+UbAe7DNi51oej1NtK+aGkbLYxPE= github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYgtWibDcT0rExnbI= github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0= github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4= -github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo= github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4= github.com/multiformats/go-multiaddr v0.12.0 h1:1QlibTFkoXJuDjjYsMHhE73TnzJQl8FSWatk/0gxGzE= github.com/multiformats/go-multiaddr v0.12.0/go.mod h1:WmZXgObOQOYp9r3cslLlppkrz1FYSHmE834dfz/lWu8= github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A= github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk= github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E= -github.com/multiformats/go-multiaddr-fmt v0.1.0/go.mod h1:hGtDIW4PU4BqJ50gW2quDuPVjyWNZxToGUh/HwTZYJo= -github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= github.com/multiformats/go-multibase v0.2.0 h1:isdYCVLvksgWlMW9OZRYJEa9pZETFivncJHmHnnd87g= github.com/multiformats/go-multibase v0.2.0/go.mod h1:bFBZX4lKCA/2lyOFSAoKH5SS6oPyjtnzK/XTFDPkNuk= github.com/multiformats/go-multicodec v0.9.0 h1:pb/dlPnzee/Sxv/j4PmkDRxCOi3hXTz3IbPKOXWJkmg= github.com/multiformats/go-multicodec v0.9.0/go.mod h1:L3QTQvMIaVBkXOXXtVmYE+LI16i14xuaojr/H7Ai54k= github.com/multiformats/go-multihash v0.0.8/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= -github.com/multiformats/go-multihash v0.0.13/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= github.com/multiformats/go-multihash v0.2.3 h1:7Lyc8XfX/IY2jWb/gI7JP+o7JEq9hOa7BFvVU9RSh+U= github.com/multiformats/go-multihash v0.2.3/go.mod h1:dXgKXCXjBzdscBLk9JkjINiEsCKRVch90MdaGiKsvSM= github.com/multiformats/go-multistream v0.5.0 h1:5htLSLl7lvJk3xx3qT/8Zm9J4K8vEOf/QGkvOGQAyiE= github.com/multiformats/go-multistream v0.5.0/go.mod h1:n6tMZiwiP2wUsR8DgfDWw1dydlEqV3l6N3/GBsX6ILA= github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= -github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8= github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= @@ -662,8 +552,6 @@ github.com/nakabonne/nestif v0.3.1 h1:wm28nZjhQY5HyYPx+weN3Q65k6ilSBxDb8v5S81B81 github.com/nakabonne/nestif v0.3.1/go.mod h1:9EtoZochLn5iUprVDmDjqGKPofoUEBL8U4Ngq6aY7OE= github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354 h1:4kuARK6Y6FxaNu/BnU2OAaLF86eTVhP2hjTB6iMvItA= github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354/go.mod h1:KSVJerMDfblTH7p5MZaTt+8zaT2iEk3AkVb9PQdZuE8= -github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= -github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= github.com/nishanths/exhaustive v0.11.0 h1:T3I8nUGhl/Cwu5Z2hfc92l0e04D2GEW6e0l8pzda2l0= github.com/nishanths/exhaustive v0.11.0/go.mod h1:RqwDsZ1xY0dNdqHho2z6X+bgzizwbLYOWnZbbl2wLB4= github.com/nishanths/predeclared v0.2.2 h1:V2EPdZPliZymNAn79T8RkNApBjMmVKh5XRpLm/w98Vk= @@ -673,17 +561,15 @@ github.com/nunnatsa/ginkgolinter v0.13.3/go.mod h1:aTKXo8WddENYxNEFT+4ZxEgWXqlD9 github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w= github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo/v2 v2.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4= -github.com/onsi/ginkgo/v2 v2.13.0/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= -github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= github.com/opencontainers/runtime-spec v1.1.0 h1:HHUyrt9mwHUjtasSbXSMvs4cyFxh+Bll4AjJ9odEGpg= -github.com/opencontainers/runtime-spec v1.1.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= -github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= github.com/otiai10/copy v1.2.0 h1:HvG945u96iNadPoG2/Ja2+AUJeW5YuFQMixq9yirC+k= github.com/otiai10/copy v1.2.0/go.mod h1:rrF5dJ5F0t/EWSYODDu4j9/vEeYHMkc8jt0zJChqQWw= github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= @@ -691,12 +577,10 @@ github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6 github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo= github.com/otiai10/mint v1.3.1/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc= 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/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pelletier/go-toml/v2 v2.0.5 h1:ipoSadvV8oGUjnUbMub59IDPPwfxF694nG/jwbMiyQg= github.com/pelletier/go-toml/v2 v2.0.5/go.mod h1:OMHamSCAODeSsVrwwvcJOaoN0LIUIaFVNZzmWyNfXas= -github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 h1:1/WtZae0yGtPq+TI6+Tv1WTxkukpXeMlviSxvL7SRgk= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -708,7 +592,6 @@ github.com/polydawn/refmt v0.89.0 h1:ADJTApkvkeBZsN0tBTx8QjpD9JkmxbKp0cxfr9qszm4 github.com/polydawn/refmt v0.89.0/go.mod h1:/zvteZs/GwLtCgZ4BL6CBsk9IKIlexP43ObX9AxTqTw= github.com/polyfloyd/go-errorlint v1.4.3 h1:P6NALOLV8BrWhm6PsqOraUK05E5h8IZnpXYJ+CIg+0U= github.com/polyfloyd/go-errorlint v1.4.3/go.mod h1:VPlWPh6hB/wruVG803SuNpLuTGNjLHYlvcdSy4RhdPA= -github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= @@ -722,14 +605,12 @@ github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1: github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= -github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY= github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= -github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= @@ -746,18 +627,12 @@ github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727/go.mod h1:r github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 h1:M8mH9eK4OUR4lu7Gd+PU1fV2/qnDNfzT635KRSObncs= github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567/go.mod h1:DWNGW8A4Y+GyBgPuaQJuWiy0XYftx4Xm/y5Jqk9I6VQ= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= -github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= github.com/quic-go/qtls-go1-20 v0.3.4 h1:MfFAPULvst4yoMgY9QmtpYmfij/em7O8UUi+bNVm7Cg= -github.com/quic-go/qtls-go1-20 v0.3.4/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= github.com/quic-go/quic-go v0.39.3 h1:o3YB6t2SR+HU/pgwF29kJ6g4jJIJEwEZ8CKia1h1TKg= -github.com/quic-go/quic-go v0.39.3/go.mod h1:T09QsDQWjLiQ74ZmacDfqZmhY/NLnw5BC40MANNNZ1Q= github.com/quic-go/webtransport-go v0.6.0 h1:CvNsKqc4W2HljHJnoT+rMmbRJybShZ0YPFDD3NxaZLY= -github.com/quic-go/webtransport-go v0.6.0/go.mod h1:9KjU4AEBqEQidGHNDkZrb8CAa1abRaosM2yGOyiikEc= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= -github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= -github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= @@ -773,37 +648,15 @@ github.com/sashamelentyev/usestdlibvars v1.23.0 h1:01h+/2Kd+NblNItNeux0veSL5cBF1 github.com/sashamelentyev/usestdlibvars v1.23.0/go.mod h1:YPwr/Y1LATzHI93CqoPUN/2BzGQ/6N/cl/KwgR0B/aU= github.com/securego/gosec/v2 v2.16.0 h1:Pi0JKoasQQ3NnoRao/ww/N/XdynIB9NRYYZT5CyOs5U= github.com/securego/gosec/v2 v2.16.0/go.mod h1:xvLcVZqUfo4aAQu56TNv7/Ltz6emAOQAEsrZrt7uGlI= -github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c h1:W65qqJCIOVP4jpqPQ0YvHYKwcMEMVWIzWC5iNQQfBTU= github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c/go.mod h1:/PevMnwAxekIXwN8qQyfc5gl2NlkB3CQlkizAbOkeBs= -github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY= -github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM= -github.com/shurcooL/github_flavored_markdown v0.0.0-20181002035957-2122de532470/go.mod h1:2dOwnU2uBioM+SGy2aZoq1f/Sd1l9OkAeAUvjSyvgU0= github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ= -github.com/shurcooL/gofontwoff v0.0.0-20180329035133-29b52fc0a18d/go.mod h1:05UtEgK5zq39gLST6uB0cf3NEHjETfB4Fgr3Gx5R9Vw= -github.com/shurcooL/gopherjslib v0.0.0-20160914041154-feb6d3990c2c/go.mod h1:8d3azKNyqcHP1GaQE/c6dDgjkgSx2BZ4IoEi4F1reUI= -github.com/shurcooL/highlight_diff v0.0.0-20170515013008-09bb4053de1b/go.mod h1:ZpfEhSmds4ytuByIcDnOLkTHGUI6KNqRNPDLHDk+mUU= -github.com/shurcooL/highlight_go v0.0.0-20181028180052-98c3abbbae20/go.mod h1:UDKB5a1T23gOMUJrI+uSuH0VRDStOiUVSjBTRDVBVag= -github.com/shurcooL/home v0.0.0-20181020052607-80b7ffcb30f9/go.mod h1:+rgNQw2P9ARFAs37qieuu7ohDNQ3gds9msbT2yn85sg= -github.com/shurcooL/htmlg v0.0.0-20170918183704-d01228ac9e50/go.mod h1:zPn1wHpTIePGnXSHpsVPWEktKXHr6+SS6x/IKRb7cpw= -github.com/shurcooL/httperror v0.0.0-20170206035902-86b7830d14cc/go.mod h1:aYMfkZ6DWSJPJ6c4Wwz3QtW22G7mf/PEgaB9k/ik5+Y= -github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= -github.com/shurcooL/httpgzip v0.0.0-20180522190206-b1c53ac65af9/go.mod h1:919LwcH0M7/W4fcZ0/jy0qGght1GIhqyS/EgWGH2j5Q= -github.com/shurcooL/issues v0.0.0-20181008053335-6292fdc1e191/go.mod h1:e2qWDig5bLteJ4fwvDAc2NHzqFEthkqn7aOZAOpj+PQ= -github.com/shurcooL/issuesapp v0.0.0-20180602232740-048589ce2241/go.mod h1:NPpHK2TI7iSaM0buivtFUc9offApnI0Alt/K8hcHy0I= -github.com/shurcooL/notifications v0.0.0-20181007000457-627ab5aea122/go.mod h1:b5uSkrEVM1jQUspwbixRBhaIjIzL2xazXp6kntxYle0= -github.com/shurcooL/octicon v0.0.0-20181028054416-fa4f57f9efb2/go.mod h1:eWdoE5JD4R5UVWDucdOPg1g2fqQRq78IQa9zlOV1vpQ= -github.com/shurcooL/reactions v0.0.0-20181006231557-f2e0b4ca5b82/go.mod h1:TCR1lToEk4d2s07G3XGfz2QrgHXg4RJBvjrOozvoWfk= -github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYEDaXHZDBsXlPCDqdhQuJkuw4NOtaxYe3xii4= -github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw= github.com/sirupsen/logrus v1.0.5/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= 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/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/sivchari/containedctx v1.0.3 h1:x+etemjbsh2fB5ewm5FeLNi5bUjK0V8n0RB+Wwfd0XE= @@ -818,10 +671,8 @@ github.com/smartystreets/goconvey v1.7.2 h1:9RBaZCeXEQ3UselpuwUQHltGVXvdwm6cv1hg github.com/smartystreets/goconvey v1.7.2/go.mod h1:Vw0tHAZW6lzCRk3xgdin6fKYcG+G3Pg9vgXWeJpQFMM= github.com/sonatard/noctx v0.0.2 h1:L7Dz4De2zDQhW8S0t+KUjY0MAQJd6SgVwhzNIc4ok00= github.com/sonatard/noctx v0.0.2/go.mod h1:kzFz+CzWSjQ2OzIm46uJZoXuBpa2+0y3T36U18dWqIo= -github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE= github.com/sourcegraph/go-diff v0.7.0 h1:9uLlrd5T46OXs5qpp8L/MTltk0zikUGi0sNNyCpA8G0= github.com/sourcegraph/go-diff v0.7.0/go.mod h1:iBszgVvyxdc8SFZ7gm69go2KDdt3ag071iBaWPF6cjs= -github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.8.2 h1:xehSyVa0YnHWsJ49JFljMpg1HX19V6NDZ1fkm1Xznbo= @@ -851,7 +702,6 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= @@ -863,7 +713,6 @@ github.com/subosito/gotenv v1.4.1 h1:jyEFiXpy21Wm81FBN71l9VoMMV8H8jG+qIK3GCpY6Qs github.com/subosito/gotenv v1.4.1/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= github.com/t-yuki/gocover-cobertura v0.0.0-20180217150009-aaee18c8195c h1:+aPplBwWcHBo6q9xrfWdMrT9o4kltkmmvpemgIjep/8= github.com/t-yuki/gocover-cobertura v0.0.0-20180217150009-aaee18c8195c/go.mod h1:SbErYREK7xXdsRiigaQiQkI9McGRzYMvlKYaP3Nimdk= -github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= github.com/tdakkota/asciicheck v0.2.0 h1:o8jvnUANo0qXtnslk2d3nMKTFNlOnJjRrNcj0j9qkHM= github.com/tdakkota/asciicheck v0.2.0/go.mod h1:Qb7Y9EgjCLJGup51gDHFzbI08/gbGhL/UVhYIPWG2rg= github.com/tenntenn/modver v1.0.1 h1:2klLppGhDgzJrScMpkj9Ujy3rXPUspSjAcev9tSEBgA= @@ -885,21 +734,15 @@ github.com/ultraware/funlen v0.1.0/go.mod h1:XJqmOQja6DpxarLj6Jj1U7JuoS8PvL4nEqD github.com/ultraware/whitespace v0.0.5 h1:hh+/cpIcopyMYbZNVov9iSxvJU3OYQg78Sfaqzi/CzI= github.com/ultraware/whitespace v0.0.5/go.mod h1:aVMh/gQve5Maj9hQ/hg+F75lr/X5A89uZnzAmWSineA= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= -github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.10 h1:p8Fspmz3iTctJstry1PYS3HVdllxnEzTEsgIgtxTrCk= github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/uudashr/gocognit v1.0.7 h1:e9aFXgKgUJrQ5+bs61zBigmj7bFJ/5cC6HmMahVzuDo= github.com/uudashr/gocognit v1.0.7/go.mod h1:nAIUuVBnYU7pcninia3BHOvQkpQCeO76Uscky5BOwcY= -github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU= -github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM= github.com/warpfork/go-testmark v0.12.1 h1:rMgCpJfwy1sJ50x0M0NgyphxYYPMOODIJHhsXyEHU0s= github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0 h1:GDDkbFiaK8jsSDJfjId/PEGEShv6ugrt4kYsC5UIDaQ= github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc h1:BCPnHtcboadS0DvysUuJXZ4lWVv5Bh5i7+tbIyi+ck4= github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc/go.mod h1:r45hJU7yEoA81k6MWNhpMj/kms0n14dkzkxYHoB96UM= -github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11 h1:5HZfQkwe0mIfyDmc1Em5GqlNRzcdtlv4HTNmdpt7XH0= -github.com/whyrusleeping/cbor-gen v0.0.0-20230126041949-52956bd4c9aa h1:EyA027ZAkuaCLoxVX4r1TZMPy1d31fM6hbfQ4OU4I5o= -github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f h1:jQa4QT2UP9WYv2nzyawpKMOCl+Z/jW7djv2/J50lj9E= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 h1:EKhdznlJHPMoKr0XTrX+IlJs1LH3lyx2nfr1dOlZ79k= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc= github.com/xen0n/gosmopolitan v1.2.1 h1:3pttnTuFumELBRSh+KQs1zcz4fN6Zy7aB0xlnQSn1Iw= @@ -920,7 +763,6 @@ github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5t gitlab.com/bosi/decorder v0.4.0 h1:HWuxAhSxIvsITcXeP+iIRg9d1cVfvVkmlF7M68GaoDY= gitlab.com/bosi/decorder v0.4.0/go.mod h1:xarnteyUoJiOTEldDysquWKTVDCKo2TOIOIibSuWqOg= go-simpler.org/assert v0.5.0 h1:+5L/lajuQtzmbtEfh69sr5cRf2/xZzyJhFjoOz/PPqs= -go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= @@ -933,23 +775,17 @@ go.opentelemetry.io/otel v1.19.0 h1:MuS/TNf4/j4IXsZuJegVzI1cwut7Qc00344rgH7p8bs= go.opentelemetry.io/otel v1.19.0/go.mod h1:i0QyjOq3UPoTzff0PJB2N66fb4S0+rSbSB15/oyH9fY= go.opentelemetry.io/otel/metric v1.19.0 h1:aTzpGtV0ar9wlV4Sna9sdJyII5jTVJEvKETPiOKwvpE= go.opentelemetry.io/otel/metric v1.19.0/go.mod h1:L5rUsV9kM1IxCj1MmSdS+JQAcVm319EUrDVLrt7jqt8= -go.opentelemetry.io/otel/sdk v1.16.0 h1:Z1Ok1YsijYL0CSJpHt4cS3wDDh7p572grzNrBMiMWgE= go.opentelemetry.io/otel/trace v1.19.0 h1:DFVQmlVbfVeOuBRrwdtaehRrWiL1JoVs9CPIQ1Dzxpg= go.opentelemetry.io/otel/trace v1.19.0/go.mod h1:mfaSyvGyEJEI0nyV2I4qhNQnbBOUUmYZpYojqMnX2vo= go.tmz.dev/musttag v0.7.1 h1:9lFmeSFnFfPuMq4IksHGomItE6NgKMNW2Nt2FPOhCfU= go.tmz.dev/musttag v0.7.1/go.mod h1:oJLkpR56EsIryktZJk/B0IroSMi37YWver47fibGh5U= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= -go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= -go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= go.uber.org/fx v1.20.1 h1:zVwVQGS8zYvhh9Xxcu4w1M6ESyeMzebzj2NbSayZ4Mk= -go.uber.org/fx v1.20.1/go.mod h1:iSYNbHf2y55acNCwCXKx7LbWb5WG1Bnue5RDXz1OREg= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= go.uber.org/mock v0.3.0 h1:3mUxI1No2/60yUYax92Pt8eNOEecx2D3lcXZh2NEZJo= -go.uber.org/mock v0.3.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= @@ -959,19 +795,13 @@ go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= -go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= -golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200602180216-279210d13fed/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= @@ -996,7 +826,6 @@ golang.org/x/exp/typeparams v0.0.0-20230307190834-24139beb5833 h1:jWGQJV4niP+CCm golang.org/x/exp/typeparams v0.0.0-20230307190834-24139beb5833/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1030,13 +859,10 @@ golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -1064,7 +890,6 @@ golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= @@ -1077,8 +902,6 @@ golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1088,7 +911,6 @@ golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1104,15 +926,12 @@ golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ= golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= -golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/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= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1121,13 +940,11 @@ golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/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= @@ -1138,7 +955,6 @@ golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1195,14 +1011,10 @@ golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= @@ -1282,12 +1094,8 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= gonum.org/v1/gonum v0.13.0 h1:a0T3bh+7fhRyqeNbiC3qVHYmkiQgit3wnNan/2c0HMM= gonum.org/v1/gonum v0.13.0/go.mod h1:/WPYRckkfWrhWefxyYTfrTtQR0KH4iyHNuzxqXAKyAU= -google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= -google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= -google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= @@ -1308,8 +1116,6 @@ google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= @@ -1317,10 +1123,6 @@ google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCID google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg= -google.golang.org/genproto v0.0.0-20190306203927-b5d61aea6440/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= @@ -1356,9 +1158,6 @@ google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= -google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= -google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -1395,11 +1194,9 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= -gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= @@ -1419,8 +1216,6 @@ gotest.tools/gotestsum v0.4.2 h1:QOdtb6bnnPUuHKkR9+/QQa8e6qjpTTP7cDi7G9/10C4= gotest.tools/gotestsum v0.4.2/go.mod h1:a32lmn/7xfm0+QHj8K5NyQY1NNNNhZoAp+/OHkLs77Y= gotest.tools/v3 v3.0.2 h1:kG1BFyqVHuQoVQiR1bWGnfz/fmHvvuiSPIV7rvl360E= gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= -grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o= -honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -1443,5 +1238,3 @@ mvdan.cc/unparam v0.0.0-20221223090309-7455f1af531d/go.mod h1:IeHQjmn6TOD+e4Z3RF rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck= -sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0= diff --git a/test/dependencies/graphsync-get/graphsync-get.go b/test/dependencies/graphsync-get/graphsync-get.go deleted file mode 100644 index 9e59379ec..000000000 --- a/test/dependencies/graphsync-get/graphsync-get.go +++ /dev/null @@ -1,128 +0,0 @@ -package main - -import ( - "context" - "fmt" - "io" - "log" - "os" - - "github.com/ipfs/boxo/blockservice" - blockstore "github.com/ipfs/boxo/blockstore" - offline "github.com/ipfs/boxo/exchange/offline" - "github.com/ipfs/boxo/ipld/merkledag" - uio "github.com/ipfs/boxo/ipld/unixfs/io" - "github.com/ipfs/go-cid" - "github.com/ipfs/go-datastore" - dssync "github.com/ipfs/go-datastore/sync" - graphsync "github.com/ipfs/go-graphsync" - gsimpl "github.com/ipfs/go-graphsync/impl" - "github.com/ipfs/go-graphsync/network" - "github.com/ipfs/go-graphsync/storeutil" - "github.com/ipld/go-ipld-prime" - cidlink "github.com/ipld/go-ipld-prime/linking/cid" - basicnode "github.com/ipld/go-ipld-prime/node/basicnode" - ipldselector "github.com/ipld/go-ipld-prime/traversal/selector" - "github.com/ipld/go-ipld-prime/traversal/selector/builder" - "github.com/libp2p/go-libp2p" - "github.com/libp2p/go-libp2p/core/host" - "github.com/libp2p/go-libp2p/core/peer" - "github.com/multiformats/go-multiaddr" -) - -func newGraphsync(ctx context.Context, p2p host.Host, bs blockstore.Blockstore) (graphsync.GraphExchange, error) { - network := network.NewFromLibp2pHost(p2p) - return gsimpl.New(ctx, - network, - storeutil.LinkSystemForBlockstore(bs), - ), nil -} - -var selectAll ipld.Node = func() ipld.Node { - ssb := builder.NewSelectorSpecBuilder(basicnode.Prototype.Any) - return ssb.ExploreRecursive( - ipldselector.RecursionLimitDepth(100), // default max - ssb.ExploreAll(ssb.ExploreRecursiveEdge()), - ).Node() -}() - -func fetch(ctx context.Context, gs graphsync.GraphExchange, p peer.ID, c cid.Cid) error { - ctx, cancel := context.WithCancel(ctx) - defer cancel() - - resps, errs := gs.Request(ctx, p, cidlink.Link{Cid: c}, selectAll) - for { - select { - case <-ctx.Done(): - return ctx.Err() - case _, ok := <-resps: - if !ok { - resps = nil - } - case err, ok := <-errs: - if !ok { - // done. - return nil - } - if err != nil { - return fmt.Errorf("got an unexpected error: %s", err) - } - } - } -} - -func main() { - if len(os.Args) != 3 { - log.Fatalf("expected a multiaddr and a CID, got %d args", len(os.Args)-1) - } - addr, err := multiaddr.NewMultiaddr(os.Args[1]) - if err != nil { - log.Fatalf("failed to multiaddr '%q': %s", os.Args[1], err) - } - ai, err := peer.AddrInfoFromP2pAddr(addr) - if err != nil { - log.Fatal(err) - } - - target, err := cid.Decode(os.Args[2]) - if err != nil { - log.Fatalf("failed to decode CID '%q': %s", os.Args[2], err) - } - - p2p, err := libp2p.New(libp2p.NoListenAddrs) - if err != nil { - log.Fatal(err) - } - - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - err = p2p.Connect(ctx, *ai) - if err != nil { - log.Fatal(err) - } - - bs := blockstore.NewBlockstore(dssync.MutexWrap(datastore.NewMapDatastore())) - gs, err := newGraphsync(ctx, p2p, bs) - if err != nil { - log.Fatal("failed to start", err) - } - err = fetch(ctx, gs, ai.ID, target) - if err != nil { - log.Fatal(err) - } - - dag := merkledag.NewDAGService(blockservice.New(bs, offline.Exchange(bs))) - root, err := dag.Get(ctx, target) - if err != nil { - log.Fatal(err) - } - reader, err := uio.NewDagReader(ctx, root, dag) - if err != nil { - log.Fatal(err) - } - _, err = io.Copy(os.Stdout, reader) - if err != nil { - log.Fatal(err) - } -} diff --git a/test/sharness/Rules.mk b/test/sharness/Rules.mk index 0dcd8d2e4..c1e70eb09 100644 --- a/test/sharness/Rules.mk +++ b/test/sharness/Rules.mk @@ -7,7 +7,7 @@ T_$(d) = $(sort $(wildcard $(d)/t[0-9][0-9][0-9][0-9]-*.sh)) DEPS_$(d) := test/bin/random test/bin/multihash test/bin/pollEndpoint \ test/bin/iptb test/bin/go-sleep test/bin/random-files \ test/bin/go-timeout test/bin/hang-fds test/bin/ma-pipe-unidir \ - test/bin/cid-fmt test/bin/graphsync-get + test/bin/cid-fmt DEPS_$(d) += cmd/ipfs/ipfs DEPS_$(d) += $(d)/clean-test-results DEPS_$(d) += $(SHARNESS_$(d)) diff --git a/test/sharness/t0221-graphsync.sh b/test/sharness/t0221-graphsync.sh deleted file mode 100755 index 771ff4f8c..000000000 --- a/test/sharness/t0221-graphsync.sh +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/env bash - -test_description="Test fetching from graphsync." - -# imports -. lib/test-lib.sh - -test_init_ipfs - -test_expect_success 'configuring ipfs' ' - ipfs config --json Experimental.GraphsyncEnabled true -' - -test_expect_success 'add content' ' - HASH=$(random 1000000 | ipfs add -q) -' - -test_launch_ipfs_daemon - -test_expect_success 'get addrs' ' - ADDR="$(ipfs id --format="" | head -1)" -' - -test_expect_success 'fetch' ' - graphsync-get "$ADDR" "$HASH" > result -' - -test_expect_success 'check' ' - ipfs add -q < result > hash_actual && - echo "$HASH" > hash_expected && - test_cmp hash_expected hash_actual -' - -test_kill_ipfs_daemon -test_done From a617c52f57f20956f8ecd7cca3b4cb36e68bb67e Mon Sep 17 00:00:00 2001 From: Jorropo Date: Wed, 22 Nov 2023 06:04:24 +0100 Subject: [PATCH 0948/1212] libp2p: default to preffering TLS See https://github.com/libp2p/go-libp2p/pull/2650. --- core/node/libp2p/sec.go | 4 ++-- docs/config.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/core/node/libp2p/sec.go b/core/node/libp2p/sec.go index 820ba22d6..2d72c6177 100644 --- a/core/node/libp2p/sec.go +++ b/core/node/libp2p/sec.go @@ -31,11 +31,11 @@ func Security(enabled bool, tptConfig config.Transports) interface{} { return func() (opts Libp2pOpts) { opts.Opts = append(opts.Opts, prioritizeOptions([]priorityOption{{ priority: tptConfig.Security.TLS, - defaultPriority: 200, + defaultPriority: 100, opt: libp2p.Security(tls.ID, tls.New), }, { priority: tptConfig.Security.Noise, - defaultPriority: 100, + defaultPriority: 200, opt: libp2p.Security(noise.ID, noise.New), }})) return opts diff --git a/docs/config.md b/docs/config.md index df35d2ce8..41d37cc0b 100644 --- a/docs/config.md +++ b/docs/config.md @@ -2199,7 +2199,7 @@ receiver supports. When establishing an _inbound_ connection, Kubo will let the initiator choose the protocol, but will refuse to use any of the disabled transports. -Supported transports are: TLS (priority 100) and Noise (priority 300). +Supported transports are: TLS (priority 100) and Noise (priority 200). No default priority will ever be less than 100. @@ -2224,7 +2224,7 @@ TLS as the cross-platform, default libp2p protocol due to ease of implementation. It is currently enabled by default but with low priority as it's not yet widely supported. -Default: `300` +Default: `200` Type: `priority` From 6a51849c299dd991eb566cab42da0f7e15817d3c Mon Sep 17 00:00:00 2001 From: Jorropo Date: Tue, 22 Aug 2023 14:21:20 +0200 Subject: [PATCH 0949/1212] libp2p: remove mplex Fixes: #10069 --- core/node/libp2p/internal/mplex/conn.go | 49 -------------- core/node/libp2p/internal/mplex/stream.go | 65 ------------------- core/node/libp2p/internal/mplex/transport.go | 29 --------- .../libp2p/internal/mplex/transport_test.go | 53 --------------- core/node/libp2p/smux.go | 44 +++---------- docs/changelogs/v0.25.md | 11 ++++ docs/config.md | 17 +---- docs/examples/kubo-as-a-library/go.mod | 1 - docs/examples/kubo-as-a-library/go.sum | 2 - go.mod | 1 - go.sum | 2 - test/cli/transports_test.go | 14 ---- 12 files changed, 23 insertions(+), 265 deletions(-) delete mode 100644 core/node/libp2p/internal/mplex/conn.go delete mode 100644 core/node/libp2p/internal/mplex/stream.go delete mode 100644 core/node/libp2p/internal/mplex/transport.go delete mode 100644 core/node/libp2p/internal/mplex/transport_test.go diff --git a/core/node/libp2p/internal/mplex/conn.go b/core/node/libp2p/internal/mplex/conn.go deleted file mode 100644 index 4a6ca87c3..000000000 --- a/core/node/libp2p/internal/mplex/conn.go +++ /dev/null @@ -1,49 +0,0 @@ -// Code copied from https://github.com/libp2p/go-libp2p/blob/9bd85029550a084fca63ec6ff9184122cdf06591/p2p/muxer/mplex/conn.go -package mplex - -import ( - "context" - - "github.com/libp2p/go-libp2p/core/network" - - mp "github.com/libp2p/go-mplex" -) - -type conn mp.Multiplex - -var _ network.MuxedConn = &conn{} - -// NewMuxedConn constructs a new Conn from a *mp.Multiplex. -func NewMuxedConn(m *mp.Multiplex) network.MuxedConn { - return (*conn)(m) -} - -func (c *conn) Close() error { - return c.mplex().Close() -} - -func (c *conn) IsClosed() bool { - return c.mplex().IsClosed() -} - -// OpenStream creates a new stream. -func (c *conn) OpenStream(ctx context.Context) (network.MuxedStream, error) { - s, err := c.mplex().NewStream(ctx) - if err != nil { - return nil, err - } - return (*stream)(s), nil -} - -// AcceptStream accepts a stream opened by the other side. -func (c *conn) AcceptStream() (network.MuxedStream, error) { - s, err := c.mplex().Accept() - if err != nil { - return nil, err - } - return (*stream)(s), nil -} - -func (c *conn) mplex() *mp.Multiplex { - return (*mp.Multiplex)(c) -} diff --git a/core/node/libp2p/internal/mplex/stream.go b/core/node/libp2p/internal/mplex/stream.go deleted file mode 100644 index 34d9cfb14..000000000 --- a/core/node/libp2p/internal/mplex/stream.go +++ /dev/null @@ -1,65 +0,0 @@ -// Code copied from https://github.com/libp2p/go-libp2p/blob/9bd85029550a084fca63ec6ff9184122cdf06591/p2p/muxer/mplex/stream.go -package mplex - -import ( - "time" - - "github.com/libp2p/go-libp2p/core/network" - - mp "github.com/libp2p/go-mplex" -) - -// stream implements network.MuxedStream over mplex.Stream. -type stream mp.Stream - -var _ network.MuxedStream = &stream{} - -func (s *stream) Read(b []byte) (n int, err error) { - n, err = s.mplex().Read(b) - if err == mp.ErrStreamReset { - err = network.ErrReset - } - - return n, err -} - -func (s *stream) Write(b []byte) (n int, err error) { - n, err = s.mplex().Write(b) - if err == mp.ErrStreamReset { - err = network.ErrReset - } - - return n, err -} - -func (s *stream) Close() error { - return s.mplex().Close() -} - -func (s *stream) CloseWrite() error { - return s.mplex().CloseWrite() -} - -func (s *stream) CloseRead() error { - return s.mplex().CloseRead() -} - -func (s *stream) Reset() error { - return s.mplex().Reset() -} - -func (s *stream) SetDeadline(t time.Time) error { - return s.mplex().SetDeadline(t) -} - -func (s *stream) SetReadDeadline(t time.Time) error { - return s.mplex().SetReadDeadline(t) -} - -func (s *stream) SetWriteDeadline(t time.Time) error { - return s.mplex().SetWriteDeadline(t) -} - -func (s *stream) mplex() *mp.Stream { - return (*mp.Stream)(s) -} diff --git a/core/node/libp2p/internal/mplex/transport.go b/core/node/libp2p/internal/mplex/transport.go deleted file mode 100644 index e7df384b9..000000000 --- a/core/node/libp2p/internal/mplex/transport.go +++ /dev/null @@ -1,29 +0,0 @@ -// Code copied from https://github.com/libp2p/go-libp2p/blob/9bd85029550a084fca63ec6ff9184122cdf06591/p2p/muxer/mplex/transport.go -package mplex - -import ( - "net" - - "github.com/libp2p/go-libp2p/core/network" - - mp "github.com/libp2p/go-mplex" -) - -// DefaultTransport has default settings for Transport -var DefaultTransport = &Transport{} - -const ID = "/mplex/6.7.0" - -var _ network.Multiplexer = &Transport{} - -// Transport implements mux.Multiplexer that constructs -// mplex-backed muxed connections. -type Transport struct{} - -func (t *Transport) NewConn(nc net.Conn, isServer bool, scope network.PeerScope) (network.MuxedConn, error) { - m, err := mp.NewMultiplex(nc, isServer, scope) - if err != nil { - return nil, err - } - return NewMuxedConn(m), nil -} diff --git a/core/node/libp2p/internal/mplex/transport_test.go b/core/node/libp2p/internal/mplex/transport_test.go deleted file mode 100644 index 1e3a1dec9..000000000 --- a/core/node/libp2p/internal/mplex/transport_test.go +++ /dev/null @@ -1,53 +0,0 @@ -// Code copied from https://github.com/libp2p/go-libp2p/blob/9bd85029550a084fca63ec6ff9184122cdf06591/p2p/muxer/mplex/transport_test.go -package mplex - -import ( - "errors" - "net" - "testing" - - "github.com/libp2p/go-libp2p/core/network" - test "github.com/libp2p/go-libp2p/p2p/muxer/testsuite" -) - -func TestDefaultTransport(t *testing.T) { - test.SubtestAll(t, DefaultTransport) -} - -type memoryScope struct { - network.PeerScope - limit int - reserved int -} - -func (m *memoryScope) ReserveMemory(size int, prio uint8) error { - if m.reserved+size > m.limit { - return errors.New("too much") - } - m.reserved += size - return nil -} - -func (m *memoryScope) ReleaseMemory(size int) { - m.reserved -= size - if m.reserved < 0 { - panic("too much memory released") - } -} - -type memoryLimitedTransport struct { - Transport -} - -func (t *memoryLimitedTransport) NewConn(nc net.Conn, isServer bool, scope network.PeerScope) (network.MuxedConn, error) { - return t.Transport.NewConn(nc, isServer, &memoryScope{ - limit: 3 * 1 << 20, - PeerScope: scope, - }) -} - -func TestDefaultTransportWithMemoryLimit(t *testing.T) { - test.SubtestAll(t, &memoryLimitedTransport{ - Transport: *DefaultTransport, - }) -} diff --git a/core/node/libp2p/smux.go b/core/node/libp2p/smux.go index 0966dfaf2..a276b5ddc 100644 --- a/core/node/libp2p/smux.go +++ b/core/node/libp2p/smux.go @@ -3,51 +3,25 @@ package libp2p import ( "fmt" "os" - "strings" "github.com/ipfs/kubo/config" - "github.com/ipfs/kubo/core/node/libp2p/internal/mplex" "github.com/libp2p/go-libp2p" "github.com/libp2p/go-libp2p/p2p/muxer/yamux" ) func makeSmuxTransportOption(tptConfig config.Transports) (libp2p.Option, error) { if prefs := os.Getenv("LIBP2P_MUX_PREFS"); prefs != "" { - // Using legacy LIBP2P_MUX_PREFS variable. - log.Error("LIBP2P_MUX_PREFS is now deprecated.") - log.Error("Use the `Swarm.Transports.Multiplexers' config field.") - muxers := strings.Fields(prefs) - enabled := make(map[string]bool, len(muxers)) - - var opts []libp2p.Option - for _, tpt := range muxers { - if enabled[tpt] { - return nil, fmt.Errorf( - "duplicate muxer found in LIBP2P_MUX_PREFS: %s", - tpt, - ) - } - switch tpt { - case yamux.ID: - opts = append(opts, libp2p.Muxer(tpt, yamux.DefaultTransport)) - case mplex.ID: - opts = append(opts, libp2p.Muxer(tpt, mplex.DefaultTransport)) - default: - return nil, fmt.Errorf("unknown muxer: %s", tpt) - } - } - return libp2p.ChainOptions(opts...), nil + return nil, fmt.Errorf("configuring muxers with LIBP2P_MUX_PREFS is no longer supported, use Swarm.Transports.Multiplexers") } - return prioritizeOptions([]priorityOption{{ - priority: tptConfig.Multiplexers.Yamux, - defaultPriority: 100, - opt: libp2p.Muxer(yamux.ID, yamux.DefaultTransport), - }, { - priority: tptConfig.Multiplexers.Mplex, - defaultPriority: config.Disabled, - opt: libp2p.Muxer(mplex.ID, mplex.DefaultTransport), - }}), nil + if tptConfig.Multiplexers.Mplex != 0 { + return nil, fmt.Errorf("Swarm.Transports.Multiplexers.Mplex is no longer supported, remove it from your config, see https://github.com/libp2p/specs/issues/553") + } + if tptConfig.Multiplexers.Yamux < 0 { + return nil, fmt.Errorf("running libp2p with Swarm.Transports.Multiplexers.Yamux disabled is not supported") + } + + return libp2p.Muxer(yamux.ID, yamux.DefaultTransport), nil } func SmuxTransport(tptConfig config.Transports) func() (opts Libp2pOpts, err error) { diff --git a/docs/changelogs/v0.25.md b/docs/changelogs/v0.25.md index 98e2a04f9..1e1f05f71 100644 --- a/docs/changelogs/v0.25.md +++ b/docs/changelogs/v0.25.md @@ -7,6 +7,7 @@ - [Overview](#overview) - [🔦 Highlights](#-highlights) - [RPC `API.Authorizations`](#rpc-apiauthorizations) + - [MPLEX removal](#mplex-removal) - [Graphsync Experiment Removal](#graphsync-experiment-removal) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -28,6 +29,16 @@ This feature is opt-in. By default, no authorization is set up. For configuration instructions, refer to the [documentation](https://github.com/ipfs/kubo/blob/master/docs/config.md#apiauthorizations). +#### MPLEX Removal + +After deprecating and removing mplex support by default in [v0.23.0](https://github.com/ipfs/kubo/blob/master/docs/changelogs/v0.23.md#mplex-deprecation). + +We now fully removed it. If you still need mplex support to talk with other pieces of software, +please try updating them, and if they don't support yamux or QUIC [talk to us about it](https://github.com/ipfs/kubo/issues/new/choose). + +Mplex is unreliable by design, it will drop data and generete errors when sending data *too fast*, +yamux and QUIC support backpressure, that means if we send data faster than the remote machine can process it, we slows down to match the remote's speed. + #### Graphsync Experiment Removal Currently the Graphsync server is to our knowledge not used diff --git a/docs/config.md b/docs/config.md index 0b33fa3fd..df35d2ce8 100644 --- a/docs/config.md +++ b/docs/config.md @@ -2253,21 +2253,10 @@ Type: `priority` ### `Swarm.Transports.Multiplexers.Mplex` -**DEPRECATED**: See https://github.com/ipfs/kubo/issues/9958 +**REMOVED**: See https://github.com/ipfs/kubo/issues/9958 -Mplex is deprecated, this is because it is unreliable and -randomly drop streams when sending data *too fast*. - -New pieces of code rely on backpressure, that means the stream will dynamically -slow down the sending rate if data is getting backed up. -Backpressure is provided by **Yamux** and **QUIC**. - -If you want to turn it back on make sure to have a higher (lower is better) -priority than `Yamux`, you don't want your Kubo to start defaulting to Mplex. - -Default: `200` - -Type: `priority` +Support for Mplex has been [removed from Kubo and go-libp2p](https://github.com/libp2p/specs/issues/553). +Please remove this option from your config. ## `DNS` diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index d930f99fb..7b2e4e1bd 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -108,7 +108,6 @@ require ( github.com/libp2p/go-libp2p-record v0.2.0 // indirect github.com/libp2p/go-libp2p-routing-helpers v0.7.3 // indirect github.com/libp2p/go-libp2p-xor v0.1.0 // indirect - github.com/libp2p/go-mplex v0.7.0 // indirect github.com/libp2p/go-msgio v0.3.0 // indirect github.com/libp2p/go-nat v0.2.0 // indirect github.com/libp2p/go-netroute v0.2.1 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 1dc80d229..a15178ee2 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -476,8 +476,6 @@ github.com/libp2p/go-libp2p-routing-helpers v0.7.3/go.mod h1:cN4mJAD/7zfPKXBcs9z github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA= github.com/libp2p/go-libp2p-xor v0.1.0 h1:hhQwT4uGrBcuAkUGXADuPltalOdpf9aag9kaYNT2tLA= github.com/libp2p/go-libp2p-xor v0.1.0/go.mod h1:LSTM5yRnjGZbWNTA/hRwq2gGFrvRIbQJscoIL/u6InY= -github.com/libp2p/go-mplex v0.7.0 h1:BDhFZdlk5tbr0oyFq/xv/NPGfjbnrsDam1EvutpBDbY= -github.com/libp2p/go-mplex v0.7.0/go.mod h1:rW8ThnRcYWft/Jb2jeORBmPd6xuG3dGxWN/W168L9EU= github.com/libp2p/go-msgio v0.0.4/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= github.com/libp2p/go-msgio v0.3.0 h1:mf3Z8B1xcFN314sWX+2vOTShIE0Mmn2TXn3YCUQGNj0= github.com/libp2p/go-msgio v0.3.0/go.mod h1:nyRM819GmVaF9LX3l03RMh10QdOroF++NBbxAb0mmDM= diff --git a/go.mod b/go.mod index 6b114c9f7..6832b4091 100644 --- a/go.mod +++ b/go.mod @@ -55,7 +55,6 @@ require ( github.com/libp2p/go-libp2p-record v0.2.0 github.com/libp2p/go-libp2p-routing-helpers v0.7.3 github.com/libp2p/go-libp2p-testing v0.12.0 - github.com/libp2p/go-mplex v0.7.0 github.com/libp2p/go-socket-activation v0.1.0 github.com/mitchellh/go-homedir v1.1.0 github.com/multiformats/go-multiaddr v0.12.0 diff --git a/go.sum b/go.sum index a28c6ab3b..fbf947edc 100644 --- a/go.sum +++ b/go.sum @@ -539,8 +539,6 @@ github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUI github.com/libp2p/go-libp2p-testing v0.12.0/go.mod h1:KcGDRXyN7sQCllucn1cOOS+Dmm7ujhfEyXQL5lvkcPg= github.com/libp2p/go-libp2p-xor v0.1.0 h1:hhQwT4uGrBcuAkUGXADuPltalOdpf9aag9kaYNT2tLA= github.com/libp2p/go-libp2p-xor v0.1.0/go.mod h1:LSTM5yRnjGZbWNTA/hRwq2gGFrvRIbQJscoIL/u6InY= -github.com/libp2p/go-mplex v0.7.0 h1:BDhFZdlk5tbr0oyFq/xv/NPGfjbnrsDam1EvutpBDbY= -github.com/libp2p/go-mplex v0.7.0/go.mod h1:rW8ThnRcYWft/Jb2jeORBmPd6xuG3dGxWN/W168L9EU= github.com/libp2p/go-msgio v0.0.4/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= github.com/libp2p/go-msgio v0.3.0 h1:mf3Z8B1xcFN314sWX+2vOTShIE0Mmn2TXn3YCUQGNj0= github.com/libp2p/go-msgio v0.3.0/go.mod h1:nyRM819GmVaF9LX3l03RMh10QdOroF++NBbxAb0mmDM= diff --git a/test/cli/transports_test.go b/test/cli/transports_test.go index c1642c602..a52335181 100644 --- a/test/cli/transports_test.go +++ b/test/cli/transports_test.go @@ -72,20 +72,6 @@ func TestTransports(t *testing.T) { runTests(nodes) }) - t.Run("tcp with mplex", func(t *testing.T) { - // FIXME(#10069): we don't want this to exists anymore - t.Parallel() - nodes := tcpNodes(t) - nodes.ForEachPar(func(n *harness.Node) { - n.UpdateConfig(func(cfg *config.Config) { - cfg.Swarm.Transports.Multiplexers.Yamux = config.Disabled - cfg.Swarm.Transports.Multiplexers.Mplex = 200 - }) - }) - nodes.StartDaemons().Connect() - runTests(nodes) - }) - t.Run("tcp with NOISE", func(t *testing.T) { t.Parallel() nodes := tcpNodes(t) From 3ae04c536e65954db9e6465346108f97d285c244 Mon Sep 17 00:00:00 2001 From: sukun Date: Wed, 22 Nov 2023 14:53:29 +0530 Subject: [PATCH 0950/1212] docs: clarify WebRTCDirect cannot reuse the same port as QUIC --- docs/config.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/config.md b/docs/config.md index df35d2ce8..495e90906 100644 --- a/docs/config.md +++ b/docs/config.md @@ -2169,9 +2169,9 @@ nodes to connect to other nodes without special configuration, such as TLS certificates. This can be useful for browser nodes that do not yet support [WebTransport](https://blog.libp2p.io/2022-12-19-libp2p-webtransport/). -Enabling this transport allows Kubo node to act on `/udp/4001/webrtc-direct` +Enabling this transport allows Kubo node to act on `/udp/4002/webrtc-direct` listeners defined in `Addresses.Swarm`, `Addresses.Announce` or -`Addresses.AppendAnnounce`. +`Addresses.AppendAnnounce`. At the moment, WebRTC Direct doesn't support listening on the same port as a QUIC or WebTransport listener **NOTE:** at the moment, WebRTC Direct cannot be used to connect to a browser node to a node that is behind a NAT or firewall. From 58c29399cf83d12a1d997ce44ec5ac6a696301dc Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Wed, 29 Nov 2023 10:40:50 +0100 Subject: [PATCH 0951/1212] chore: clean migration --- assets/assets.go | 2 +- client/rpc/api.go | 4 ++-- client/rpc/api_test.go | 4 ++-- client/rpc/block.go | 4 ++-- client/rpc/dag.go | 2 +- client/rpc/dht.go | 2 +- client/rpc/key.go | 4 ++-- client/rpc/name.go | 4 ++-- client/rpc/object.go | 4 ++-- client/rpc/pin.go | 4 ++-- client/rpc/pubsub.go | 4 ++-- client/rpc/routing.go | 2 +- client/rpc/swarm.go | 2 +- client/rpc/unixfs.go | 4 ++-- cmd/ipfs/add_migrations.go | 4 ++-- cmd/ipfs/daemon.go | 2 +- cmd/ipfs/init.go | 2 +- commands/context.go | 4 ++-- config/init.go | 2 +- config/init_test.go | 2 +- core/commands/add.go | 4 ++-- core/commands/block.go | 2 +- core/commands/cat.go | 2 +- core/commands/cmdenv/env.go | 4 ++-- core/commands/cmdutils/utils.go | 2 +- core/commands/dag/export.go | 2 +- core/commands/dag/import.go | 2 +- core/commands/files.go | 2 +- core/commands/keystore.go | 2 +- core/commands/ls.go | 4 ++-- core/commands/name/ipns.go | 2 +- core/commands/name/publish.go | 4 ++-- core/commands/object/object.go | 2 +- core/commands/object/patch.go | 2 +- core/commands/pin/pin.go | 4 ++-- core/commands/pubsub.go | 2 +- core/commands/refs.go | 2 +- core/commands/resolve.go | 2 +- core/commands/routing.go | 4 ++-- core/commands/urlstore.go | 2 +- core/coreapi/block.go | 4 ++-- core/coreapi/coreapi.go | 4 ++-- core/coreapi/dht.go | 4 ++-- core/coreapi/key.go | 4 ++-- core/coreapi/name.go | 4 ++-- core/coreapi/object.go | 4 ++-- core/coreapi/path.go | 2 +- core/coreapi/pin.go | 4 ++-- core/coreapi/pubsub.go | 4 ++-- core/coreapi/routing.go | 4 ++-- core/coreapi/swarm.go | 2 +- core/coreapi/test/api_test.go | 4 ++-- core/coreapi/test/path_test.go | 2 +- core/coreapi/unixfs.go | 4 ++-- core/corehttp/gateway.go | 2 +- core/corehttp/gateway_test.go | 2 +- core/coreiface/block.go | 2 +- core/coreiface/coreapi.go | 2 +- core/coreiface/dht.go | 2 +- core/coreiface/key.go | 2 +- core/coreiface/name.go | 2 +- core/coreiface/object.go | 2 +- core/coreiface/pin.go | 2 +- core/coreiface/pubsub.go | 2 +- core/coreiface/routing.go | 2 +- core/coreiface/tests/api.go | 2 +- core/coreiface/tests/block.go | 4 ++-- core/coreiface/tests/dag.go | 2 +- core/coreiface/tests/dht.go | 4 ++-- core/coreiface/tests/key.go | 4 ++-- core/coreiface/tests/name.go | 4 ++-- core/coreiface/tests/object.go | 4 ++-- core/coreiface/tests/path.go | 2 +- core/coreiface/tests/pin.go | 4 ++-- core/coreiface/tests/pubsub.go | 4 ++-- core/coreiface/tests/routing.go | 4 ++-- core/coreiface/tests/unixfs.go | 4 ++-- core/coreiface/unixfs.go | 2 +- core/coreunix/add.go | 2 +- core/coreunix/add_test.go | 2 +- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- docs/examples/kubo-as-a-library/main.go | 2 +- fuse/ipns/ipns_unix.go | 4 ++-- go.mod | 4 ++-- go.sum | 4 ++-- plugin/daemon.go | 2 +- repo/fsrepo/migrations/ipfsfetcher/ipfsfetcher.go | 4 ++-- test/dependencies/go.mod | 3 ++- test/dependencies/go.sum | 7 +++++-- 90 files changed, 137 insertions(+), 133 deletions(-) diff --git a/assets/assets.go b/assets/assets.go index bb320b4fd..17bfa8941 100644 --- a/assets/assets.go +++ b/assets/assets.go @@ -8,10 +8,10 @@ import ( "github.com/ipfs/kubo/core" "github.com/ipfs/kubo/core/coreapi" - options "github.com/ipfs/boxo/coreiface/options" "github.com/ipfs/boxo/files" "github.com/ipfs/boxo/path" cid "github.com/ipfs/go-cid" + options "github.com/ipfs/kubo/core/coreiface/options" ) //go:embed init-doc diff --git a/client/rpc/api.go b/client/rpc/api.go index c00f6b598..48a80388f 100644 --- a/client/rpc/api.go +++ b/client/rpc/api.go @@ -13,12 +13,12 @@ import ( "time" "github.com/blang/semver/v4" - iface "github.com/ipfs/boxo/coreiface" - caopts "github.com/ipfs/boxo/coreiface/options" "github.com/ipfs/boxo/ipld/merkledag" "github.com/ipfs/go-cid" legacy "github.com/ipfs/go-ipld-legacy" ipfs "github.com/ipfs/kubo" + iface "github.com/ipfs/kubo/core/coreiface" + caopts "github.com/ipfs/kubo/core/coreiface/options" dagpb "github.com/ipld/go-codec-dagpb" _ "github.com/ipld/go-ipld-prime/codec/dagcbor" "github.com/ipld/go-ipld-prime/node/basicnode" diff --git a/client/rpc/api_test.go b/client/rpc/api_test.go index e2838cb16..25bd26cee 100644 --- a/client/rpc/api_test.go +++ b/client/rpc/api_test.go @@ -11,9 +11,9 @@ import ( "testing" "time" - iface "github.com/ipfs/boxo/coreiface" - "github.com/ipfs/boxo/coreiface/tests" "github.com/ipfs/boxo/path" + iface "github.com/ipfs/kubo/core/coreiface" + "github.com/ipfs/kubo/core/coreiface/tests" "github.com/ipfs/kubo/test/cli/harness" ma "github.com/multiformats/go-multiaddr" "go.uber.org/multierr" diff --git a/client/rpc/block.go b/client/rpc/block.go index a5882a57e..9345a5f19 100644 --- a/client/rpc/block.go +++ b/client/rpc/block.go @@ -6,10 +6,10 @@ import ( "fmt" "io" - iface "github.com/ipfs/boxo/coreiface" - caopts "github.com/ipfs/boxo/coreiface/options" "github.com/ipfs/boxo/path" "github.com/ipfs/go-cid" + iface "github.com/ipfs/kubo/core/coreiface" + caopts "github.com/ipfs/kubo/core/coreiface/options" mc "github.com/multiformats/go-multicodec" mh "github.com/multiformats/go-multihash" ) diff --git a/client/rpc/dag.go b/client/rpc/dag.go index 098a959d8..63cac8f61 100644 --- a/client/rpc/dag.go +++ b/client/rpc/dag.go @@ -6,11 +6,11 @@ import ( "fmt" "io" - "github.com/ipfs/boxo/coreiface/options" "github.com/ipfs/boxo/path" blocks "github.com/ipfs/go-block-format" "github.com/ipfs/go-cid" format "github.com/ipfs/go-ipld-format" + "github.com/ipfs/kubo/core/coreiface/options" multicodec "github.com/multiformats/go-multicodec" ) diff --git a/client/rpc/dht.go b/client/rpc/dht.go index 852c18976..1b2c86398 100644 --- a/client/rpc/dht.go +++ b/client/rpc/dht.go @@ -4,8 +4,8 @@ import ( "context" "encoding/json" - caopts "github.com/ipfs/boxo/coreiface/options" "github.com/ipfs/boxo/path" + caopts "github.com/ipfs/kubo/core/coreiface/options" "github.com/libp2p/go-libp2p/core/peer" "github.com/libp2p/go-libp2p/core/routing" ) diff --git a/client/rpc/key.go b/client/rpc/key.go index 40027aa46..daddffb23 100644 --- a/client/rpc/key.go +++ b/client/rpc/key.go @@ -4,10 +4,10 @@ import ( "context" "errors" - iface "github.com/ipfs/boxo/coreiface" - caopts "github.com/ipfs/boxo/coreiface/options" "github.com/ipfs/boxo/ipns" "github.com/ipfs/boxo/path" + iface "github.com/ipfs/kubo/core/coreiface" + caopts "github.com/ipfs/kubo/core/coreiface/options" "github.com/libp2p/go-libp2p/core/peer" ) diff --git a/client/rpc/name.go b/client/rpc/name.go index eb01ee3cd..023f0cde8 100644 --- a/client/rpc/name.go +++ b/client/rpc/name.go @@ -6,11 +6,11 @@ import ( "fmt" "io" - iface "github.com/ipfs/boxo/coreiface" - caopts "github.com/ipfs/boxo/coreiface/options" "github.com/ipfs/boxo/ipns" "github.com/ipfs/boxo/namesys" "github.com/ipfs/boxo/path" + iface "github.com/ipfs/kubo/core/coreiface" + caopts "github.com/ipfs/kubo/core/coreiface/options" ) type NameAPI HttpApi diff --git a/client/rpc/object.go b/client/rpc/object.go index b8d09752f..9e00bfb77 100644 --- a/client/rpc/object.go +++ b/client/rpc/object.go @@ -6,13 +6,13 @@ import ( "fmt" "io" - iface "github.com/ipfs/boxo/coreiface" - caopts "github.com/ipfs/boxo/coreiface/options" "github.com/ipfs/boxo/ipld/merkledag" ft "github.com/ipfs/boxo/ipld/unixfs" "github.com/ipfs/boxo/path" "github.com/ipfs/go-cid" ipld "github.com/ipfs/go-ipld-format" + iface "github.com/ipfs/kubo/core/coreiface" + caopts "github.com/ipfs/kubo/core/coreiface/options" ) type ObjectAPI HttpApi diff --git a/client/rpc/pin.go b/client/rpc/pin.go index 486e5115b..632d8f08d 100644 --- a/client/rpc/pin.go +++ b/client/rpc/pin.go @@ -6,10 +6,10 @@ import ( "io" "strings" - iface "github.com/ipfs/boxo/coreiface" - caopts "github.com/ipfs/boxo/coreiface/options" "github.com/ipfs/boxo/path" "github.com/ipfs/go-cid" + iface "github.com/ipfs/kubo/core/coreiface" + caopts "github.com/ipfs/kubo/core/coreiface/options" "github.com/pkg/errors" ) diff --git a/client/rpc/pubsub.go b/client/rpc/pubsub.go index f255da5ad..d12d7a5de 100644 --- a/client/rpc/pubsub.go +++ b/client/rpc/pubsub.go @@ -6,8 +6,8 @@ import ( "encoding/json" "io" - iface "github.com/ipfs/boxo/coreiface" - caopts "github.com/ipfs/boxo/coreiface/options" + iface "github.com/ipfs/kubo/core/coreiface" + caopts "github.com/ipfs/kubo/core/coreiface/options" "github.com/libp2p/go-libp2p/core/peer" mbase "github.com/multiformats/go-multibase" ) diff --git a/client/rpc/routing.go b/client/rpc/routing.go index babed15fb..2ecf25f8b 100644 --- a/client/rpc/routing.go +++ b/client/rpc/routing.go @@ -6,7 +6,7 @@ import ( "encoding/base64" "encoding/json" - "github.com/ipfs/boxo/coreiface/options" + "github.com/ipfs/kubo/core/coreiface/options" "github.com/libp2p/go-libp2p/core/routing" ) diff --git a/client/rpc/swarm.go b/client/rpc/swarm.go index 7d257a2d1..d54d06604 100644 --- a/client/rpc/swarm.go +++ b/client/rpc/swarm.go @@ -4,7 +4,7 @@ import ( "context" "time" - iface "github.com/ipfs/boxo/coreiface" + iface "github.com/ipfs/kubo/core/coreiface" "github.com/libp2p/go-libp2p/core/network" "github.com/libp2p/go-libp2p/core/peer" "github.com/libp2p/go-libp2p/core/protocol" diff --git a/client/rpc/unixfs.go b/client/rpc/unixfs.go index be8ddb22d..501e8d025 100644 --- a/client/rpc/unixfs.go +++ b/client/rpc/unixfs.go @@ -7,13 +7,13 @@ import ( "fmt" "io" - iface "github.com/ipfs/boxo/coreiface" - caopts "github.com/ipfs/boxo/coreiface/options" "github.com/ipfs/boxo/files" unixfs "github.com/ipfs/boxo/ipld/unixfs" unixfs_pb "github.com/ipfs/boxo/ipld/unixfs/pb" "github.com/ipfs/boxo/path" "github.com/ipfs/go-cid" + iface "github.com/ipfs/kubo/core/coreiface" + caopts "github.com/ipfs/kubo/core/coreiface/options" mh "github.com/multiformats/go-multihash" ) diff --git a/cmd/ipfs/add_migrations.go b/cmd/ipfs/add_migrations.go index 566158d0f..14a98e04c 100644 --- a/cmd/ipfs/add_migrations.go +++ b/cmd/ipfs/add_migrations.go @@ -8,12 +8,12 @@ import ( "os" "path/filepath" - coreiface "github.com/ipfs/boxo/coreiface" - "github.com/ipfs/boxo/coreiface/options" "github.com/ipfs/boxo/files" "github.com/ipfs/boxo/path" "github.com/ipfs/kubo/core" "github.com/ipfs/kubo/core/coreapi" + coreiface "github.com/ipfs/kubo/core/coreiface" + "github.com/ipfs/kubo/core/coreiface/options" "github.com/ipfs/kubo/repo/fsrepo/migrations" "github.com/ipfs/kubo/repo/fsrepo/migrations/ipfsfetcher" "github.com/libp2p/go-libp2p/core/peer" diff --git a/cmd/ipfs/daemon.go b/cmd/ipfs/daemon.go index 1375d464d..f46dbdd8c 100644 --- a/cmd/ipfs/daemon.go +++ b/cmd/ipfs/daemon.go @@ -15,7 +15,6 @@ import ( multierror "github.com/hashicorp/go-multierror" - options "github.com/ipfs/boxo/coreiface/options" cmds "github.com/ipfs/go-ipfs-cmds" mprome "github.com/ipfs/go-metrics-prometheus" version "github.com/ipfs/kubo" @@ -27,6 +26,7 @@ import ( commands "github.com/ipfs/kubo/core/commands" "github.com/ipfs/kubo/core/coreapi" corehttp "github.com/ipfs/kubo/core/corehttp" + options "github.com/ipfs/kubo/core/coreiface/options" corerepo "github.com/ipfs/kubo/core/corerepo" libp2p "github.com/ipfs/kubo/core/node/libp2p" nodeMount "github.com/ipfs/kubo/fuse/node" diff --git a/cmd/ipfs/init.go b/cmd/ipfs/init.go index 6d03b12c9..82c622ab5 100644 --- a/cmd/ipfs/init.go +++ b/cmd/ipfs/init.go @@ -18,10 +18,10 @@ import ( "github.com/ipfs/kubo/core/commands" fsrepo "github.com/ipfs/kubo/repo/fsrepo" - options "github.com/ipfs/boxo/coreiface/options" "github.com/ipfs/boxo/files" cmds "github.com/ipfs/go-ipfs-cmds" config "github.com/ipfs/kubo/config" + options "github.com/ipfs/kubo/core/coreiface/options" ) const ( diff --git a/commands/context.go b/commands/context.go index 855db1afe..cc95d55f4 100644 --- a/commands/context.go +++ b/commands/context.go @@ -10,11 +10,11 @@ import ( coreapi "github.com/ipfs/kubo/core/coreapi" loader "github.com/ipfs/kubo/plugin/loader" - coreiface "github.com/ipfs/boxo/coreiface" - options "github.com/ipfs/boxo/coreiface/options" cmds "github.com/ipfs/go-ipfs-cmds" logging "github.com/ipfs/go-log" config "github.com/ipfs/kubo/config" + coreiface "github.com/ipfs/kubo/core/coreiface" + options "github.com/ipfs/kubo/core/coreiface/options" ) var log = logging.Logger("command") diff --git a/config/init.go b/config/init.go index f40d373bb..e4cb1e95a 100644 --- a/config/init.go +++ b/config/init.go @@ -7,7 +7,7 @@ import ( "io" "time" - "github.com/ipfs/boxo/coreiface/options" + "github.com/ipfs/kubo/core/coreiface/options" "github.com/libp2p/go-libp2p/core/crypto" "github.com/libp2p/go-libp2p/core/peer" ) diff --git a/config/init_test.go b/config/init_test.go index 762ad3976..8a6888de3 100644 --- a/config/init_test.go +++ b/config/init_test.go @@ -4,7 +4,7 @@ import ( "bytes" "testing" - "github.com/ipfs/boxo/coreiface/options" + "github.com/ipfs/kubo/core/coreiface/options" crypto_pb "github.com/libp2p/go-libp2p/core/crypto/pb" ) diff --git a/core/commands/add.go b/core/commands/add.go index bdde6cb41..33d79a2eb 100644 --- a/core/commands/add.go +++ b/core/commands/add.go @@ -11,13 +11,13 @@ import ( "github.com/ipfs/kubo/core/commands/cmdenv" "github.com/cheggaaa/pb" - coreiface "github.com/ipfs/boxo/coreiface" - "github.com/ipfs/boxo/coreiface/options" "github.com/ipfs/boxo/files" mfs "github.com/ipfs/boxo/mfs" "github.com/ipfs/boxo/path" cmds "github.com/ipfs/go-ipfs-cmds" ipld "github.com/ipfs/go-ipld-format" + coreiface "github.com/ipfs/kubo/core/coreiface" + "github.com/ipfs/kubo/core/coreiface/options" mh "github.com/multiformats/go-multihash" ) diff --git a/core/commands/block.go b/core/commands/block.go index 103addcaf..6ceb258f6 100644 --- a/core/commands/block.go +++ b/core/commands/block.go @@ -11,7 +11,7 @@ import ( cmdenv "github.com/ipfs/kubo/core/commands/cmdenv" "github.com/ipfs/kubo/core/commands/cmdutils" - options "github.com/ipfs/boxo/coreiface/options" + options "github.com/ipfs/kubo/core/coreiface/options" cmds "github.com/ipfs/go-ipfs-cmds" mh "github.com/multiformats/go-multihash" diff --git a/core/commands/cat.go b/core/commands/cat.go index 79e78cc77..6fa1f71b7 100644 --- a/core/commands/cat.go +++ b/core/commands/cat.go @@ -10,9 +10,9 @@ import ( "github.com/ipfs/kubo/core/commands/cmdutils" "github.com/cheggaaa/pb" - iface "github.com/ipfs/boxo/coreiface" "github.com/ipfs/boxo/files" cmds "github.com/ipfs/go-ipfs-cmds" + iface "github.com/ipfs/kubo/core/coreiface" ) const ( diff --git a/core/commands/cmdenv/env.go b/core/commands/cmdenv/env.go index 69ad2dc74..fb538dc12 100644 --- a/core/commands/cmdenv/env.go +++ b/core/commands/cmdenv/env.go @@ -8,10 +8,10 @@ import ( "github.com/ipfs/kubo/commands" "github.com/ipfs/kubo/core" - coreiface "github.com/ipfs/boxo/coreiface" - options "github.com/ipfs/boxo/coreiface/options" cmds "github.com/ipfs/go-ipfs-cmds" logging "github.com/ipfs/go-log" + coreiface "github.com/ipfs/kubo/core/coreiface" + options "github.com/ipfs/kubo/core/coreiface/options" ) var log = logging.Logger("core/commands/cmdenv") diff --git a/core/commands/cmdutils/utils.go b/core/commands/cmdutils/utils.go index 87ddb9655..be295f9e3 100644 --- a/core/commands/cmdutils/utils.go +++ b/core/commands/cmdutils/utils.go @@ -5,9 +5,9 @@ import ( cmds "github.com/ipfs/go-ipfs-cmds" - coreiface "github.com/ipfs/boxo/coreiface" "github.com/ipfs/boxo/path" "github.com/ipfs/go-cid" + coreiface "github.com/ipfs/kubo/core/coreiface" ) const ( diff --git a/core/commands/dag/export.go b/core/commands/dag/export.go index d97718d20..a729cf752 100644 --- a/core/commands/dag/export.go +++ b/core/commands/dag/export.go @@ -9,12 +9,12 @@ import ( "time" "github.com/cheggaaa/pb" - iface "github.com/ipfs/boxo/coreiface" blocks "github.com/ipfs/go-block-format" cid "github.com/ipfs/go-cid" ipld "github.com/ipfs/go-ipld-format" "github.com/ipfs/kubo/core/commands/cmdenv" "github.com/ipfs/kubo/core/commands/cmdutils" + iface "github.com/ipfs/kubo/core/coreiface" cmds "github.com/ipfs/go-ipfs-cmds" gocar "github.com/ipld/go-car" diff --git a/core/commands/dag/import.go b/core/commands/dag/import.go index 76fa045ff..d95ff7198 100644 --- a/core/commands/dag/import.go +++ b/core/commands/dag/import.go @@ -5,13 +5,13 @@ import ( "fmt" "io" - "github.com/ipfs/boxo/coreiface/options" "github.com/ipfs/boxo/files" blocks "github.com/ipfs/go-block-format" cid "github.com/ipfs/go-cid" cmds "github.com/ipfs/go-ipfs-cmds" ipld "github.com/ipfs/go-ipld-format" ipldlegacy "github.com/ipfs/go-ipld-legacy" + "github.com/ipfs/kubo/core/coreiface/options" gocarv2 "github.com/ipld/go-car/v2" "github.com/ipfs/kubo/core/commands/cmdenv" diff --git a/core/commands/files.go b/core/commands/files.go index 73ce9c826..9a7ee639a 100644 --- a/core/commands/files.go +++ b/core/commands/files.go @@ -15,7 +15,6 @@ import ( "github.com/ipfs/kubo/core/commands/cmdenv" bservice "github.com/ipfs/boxo/blockservice" - iface "github.com/ipfs/boxo/coreiface" offline "github.com/ipfs/boxo/exchange/offline" dag "github.com/ipfs/boxo/ipld/merkledag" ft "github.com/ipfs/boxo/ipld/unixfs" @@ -26,6 +25,7 @@ import ( cmds "github.com/ipfs/go-ipfs-cmds" ipld "github.com/ipfs/go-ipld-format" logging "github.com/ipfs/go-log" + iface "github.com/ipfs/kubo/core/coreiface" mh "github.com/multiformats/go-multihash" ) diff --git a/core/commands/keystore.go b/core/commands/keystore.go index d68801cad..2ad2f7dbd 100644 --- a/core/commands/keystore.go +++ b/core/commands/keystore.go @@ -12,7 +12,6 @@ import ( "strings" "text/tabwriter" - options "github.com/ipfs/boxo/coreiface/options" keystore "github.com/ipfs/boxo/keystore" cmds "github.com/ipfs/go-ipfs-cmds" oldcmds "github.com/ipfs/kubo/commands" @@ -20,6 +19,7 @@ import ( cmdenv "github.com/ipfs/kubo/core/commands/cmdenv" "github.com/ipfs/kubo/core/commands/e" ke "github.com/ipfs/kubo/core/commands/keyencode" + options "github.com/ipfs/kubo/core/coreiface/options" fsrepo "github.com/ipfs/kubo/repo/fsrepo" migrations "github.com/ipfs/kubo/repo/fsrepo/migrations" "github.com/libp2p/go-libp2p/core/crypto" diff --git a/core/commands/ls.go b/core/commands/ls.go index ee360796f..6fd535282 100644 --- a/core/commands/ls.go +++ b/core/commands/ls.go @@ -10,11 +10,11 @@ import ( cmdenv "github.com/ipfs/kubo/core/commands/cmdenv" "github.com/ipfs/kubo/core/commands/cmdutils" - iface "github.com/ipfs/boxo/coreiface" - options "github.com/ipfs/boxo/coreiface/options" unixfs "github.com/ipfs/boxo/ipld/unixfs" unixfs_pb "github.com/ipfs/boxo/ipld/unixfs/pb" cmds "github.com/ipfs/go-ipfs-cmds" + iface "github.com/ipfs/kubo/core/coreiface" + options "github.com/ipfs/kubo/core/coreiface/options" ) // LsLink contains printable data for a single ipld link in ls output diff --git a/core/commands/name/ipns.go b/core/commands/name/ipns.go index e03b9c66b..f556baf7c 100644 --- a/core/commands/name/ipns.go +++ b/core/commands/name/ipns.go @@ -7,12 +7,12 @@ import ( "strings" "time" - options "github.com/ipfs/boxo/coreiface/options" "github.com/ipfs/boxo/namesys" "github.com/ipfs/boxo/path" cmds "github.com/ipfs/go-ipfs-cmds" logging "github.com/ipfs/go-log" cmdenv "github.com/ipfs/kubo/core/commands/cmdenv" + options "github.com/ipfs/kubo/core/coreiface/options" ) var log = logging.Logger("core/commands/ipns") diff --git a/core/commands/name/publish.go b/core/commands/name/publish.go index 6365470b6..9c8d837cb 100644 --- a/core/commands/name/publish.go +++ b/core/commands/name/publish.go @@ -9,11 +9,11 @@ import ( cmdenv "github.com/ipfs/kubo/core/commands/cmdenv" "github.com/ipfs/kubo/core/commands/cmdutils" - iface "github.com/ipfs/boxo/coreiface" - options "github.com/ipfs/boxo/coreiface/options" ipns "github.com/ipfs/boxo/ipns" cmds "github.com/ipfs/go-ipfs-cmds" ke "github.com/ipfs/kubo/core/commands/keyencode" + iface "github.com/ipfs/kubo/core/coreiface" + options "github.com/ipfs/kubo/core/coreiface/options" ) var errAllowOffline = errors.New("can't publish while offline: pass `--allow-offline` to override") diff --git a/core/commands/object/object.go b/core/commands/object/object.go index 8024edfe3..5a8577cf2 100644 --- a/core/commands/object/object.go +++ b/core/commands/object/object.go @@ -12,10 +12,10 @@ import ( "github.com/ipfs/kubo/core/commands/cmdutils" humanize "github.com/dustin/go-humanize" - "github.com/ipfs/boxo/coreiface/options" dag "github.com/ipfs/boxo/ipld/merkledag" "github.com/ipfs/go-cid" ipld "github.com/ipfs/go-ipld-format" + "github.com/ipfs/kubo/core/coreiface/options" ) type Node struct { diff --git a/core/commands/object/patch.go b/core/commands/object/patch.go index 7e440b1af..7c35151fb 100644 --- a/core/commands/object/patch.go +++ b/core/commands/object/patch.go @@ -8,7 +8,7 @@ import ( "github.com/ipfs/kubo/core/commands/cmdenv" "github.com/ipfs/kubo/core/commands/cmdutils" - "github.com/ipfs/boxo/coreiface/options" + "github.com/ipfs/kubo/core/coreiface/options" ) var ObjectPatchCmd = &cmds.Command{ diff --git a/core/commands/pin/pin.go b/core/commands/pin/pin.go index aa4470d70..db623a7e6 100644 --- a/core/commands/pin/pin.go +++ b/core/commands/pin/pin.go @@ -9,14 +9,14 @@ import ( "time" bserv "github.com/ipfs/boxo/blockservice" - coreiface "github.com/ipfs/boxo/coreiface" - options "github.com/ipfs/boxo/coreiface/options" offline "github.com/ipfs/boxo/exchange/offline" dag "github.com/ipfs/boxo/ipld/merkledag" verifcid "github.com/ipfs/boxo/verifcid" cid "github.com/ipfs/go-cid" cidenc "github.com/ipfs/go-cidutil/cidenc" cmds "github.com/ipfs/go-ipfs-cmds" + coreiface "github.com/ipfs/kubo/core/coreiface" + options "github.com/ipfs/kubo/core/coreiface/options" core "github.com/ipfs/kubo/core" cmdenv "github.com/ipfs/kubo/core/commands/cmdenv" diff --git a/core/commands/pubsub.go b/core/commands/pubsub.go index 1c2e82799..8f52881a3 100644 --- a/core/commands/pubsub.go +++ b/core/commands/pubsub.go @@ -11,8 +11,8 @@ import ( mbase "github.com/multiformats/go-multibase" "github.com/pkg/errors" - options "github.com/ipfs/boxo/coreiface/options" cmds "github.com/ipfs/go-ipfs-cmds" + options "github.com/ipfs/kubo/core/coreiface/options" ) var PubsubCmd = &cmds.Command{ diff --git a/core/commands/refs.go b/core/commands/refs.go index 3c58fe961..cefd8af90 100644 --- a/core/commands/refs.go +++ b/core/commands/refs.go @@ -10,12 +10,12 @@ import ( cmdenv "github.com/ipfs/kubo/core/commands/cmdenv" "github.com/ipfs/kubo/core/commands/cmdutils" - iface "github.com/ipfs/boxo/coreiface" merkledag "github.com/ipfs/boxo/ipld/merkledag" cid "github.com/ipfs/go-cid" cidenc "github.com/ipfs/go-cidutil/cidenc" cmds "github.com/ipfs/go-ipfs-cmds" ipld "github.com/ipfs/go-ipld-format" + iface "github.com/ipfs/kubo/core/coreiface" ) var refsEncoderMap = cmds.EncoderMap{ diff --git a/core/commands/resolve.go b/core/commands/resolve.go index 67450f4cb..d60eb0633 100644 --- a/core/commands/resolve.go +++ b/core/commands/resolve.go @@ -13,9 +13,9 @@ import ( "github.com/ipfs/kubo/core/commands/cmdutils" ncmd "github.com/ipfs/kubo/core/commands/name" - options "github.com/ipfs/boxo/coreiface/options" "github.com/ipfs/boxo/path" cmds "github.com/ipfs/go-ipfs-cmds" + options "github.com/ipfs/kubo/core/coreiface/options" ) const ( diff --git a/core/commands/routing.go b/core/commands/routing.go index 1f96c4dea..2442570ac 100644 --- a/core/commands/routing.go +++ b/core/commands/routing.go @@ -11,13 +11,13 @@ import ( cmdenv "github.com/ipfs/kubo/core/commands/cmdenv" - iface "github.com/ipfs/boxo/coreiface" - "github.com/ipfs/boxo/coreiface/options" dag "github.com/ipfs/boxo/ipld/merkledag" "github.com/ipfs/boxo/ipns" cid "github.com/ipfs/go-cid" cmds "github.com/ipfs/go-ipfs-cmds" ipld "github.com/ipfs/go-ipld-format" + iface "github.com/ipfs/kubo/core/coreiface" + "github.com/ipfs/kubo/core/coreiface/options" peer "github.com/libp2p/go-libp2p/core/peer" routing "github.com/libp2p/go-libp2p/core/routing" ) diff --git a/core/commands/urlstore.go b/core/commands/urlstore.go index e5dd1ce4d..c4ee08c90 100644 --- a/core/commands/urlstore.go +++ b/core/commands/urlstore.go @@ -8,9 +8,9 @@ import ( filestore "github.com/ipfs/boxo/filestore" cmdenv "github.com/ipfs/kubo/core/commands/cmdenv" - "github.com/ipfs/boxo/coreiface/options" "github.com/ipfs/boxo/files" cmds "github.com/ipfs/go-ipfs-cmds" + "github.com/ipfs/kubo/core/coreiface/options" ) var urlStoreCmd = &cmds.Command{ diff --git a/core/coreapi/block.go b/core/coreapi/block.go index ffbe89c8b..0c5597c8d 100644 --- a/core/coreapi/block.go +++ b/core/coreapi/block.go @@ -6,12 +6,12 @@ import ( "errors" "io" - coreiface "github.com/ipfs/boxo/coreiface" - caopts "github.com/ipfs/boxo/coreiface/options" "github.com/ipfs/boxo/path" pin "github.com/ipfs/boxo/pinning/pinner" blocks "github.com/ipfs/go-block-format" cid "github.com/ipfs/go-cid" + coreiface "github.com/ipfs/kubo/core/coreiface" + caopts "github.com/ipfs/kubo/core/coreiface/options" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" diff --git a/core/coreapi/coreapi.go b/core/coreapi/coreapi.go index 81d05b58d..3efe03778 100644 --- a/core/coreapi/coreapi.go +++ b/core/coreapi/coreapi.go @@ -17,8 +17,6 @@ import ( bserv "github.com/ipfs/boxo/blockservice" blockstore "github.com/ipfs/boxo/blockstore" - coreiface "github.com/ipfs/boxo/coreiface" - "github.com/ipfs/boxo/coreiface/options" exchange "github.com/ipfs/boxo/exchange" offlinexch "github.com/ipfs/boxo/exchange/offline" "github.com/ipfs/boxo/fetcher" @@ -28,6 +26,8 @@ import ( provider "github.com/ipfs/boxo/provider" offlineroute "github.com/ipfs/boxo/routing/offline" ipld "github.com/ipfs/go-ipld-format" + coreiface "github.com/ipfs/kubo/core/coreiface" + "github.com/ipfs/kubo/core/coreiface/options" pubsub "github.com/libp2p/go-libp2p-pubsub" record "github.com/libp2p/go-libp2p-record" ci "github.com/libp2p/go-libp2p/core/crypto" diff --git a/core/coreapi/dht.go b/core/coreapi/dht.go index c960ee084..7b5d4eb84 100644 --- a/core/coreapi/dht.go +++ b/core/coreapi/dht.go @@ -6,13 +6,13 @@ import ( blockservice "github.com/ipfs/boxo/blockservice" blockstore "github.com/ipfs/boxo/blockstore" - coreiface "github.com/ipfs/boxo/coreiface" - caopts "github.com/ipfs/boxo/coreiface/options" offline "github.com/ipfs/boxo/exchange/offline" dag "github.com/ipfs/boxo/ipld/merkledag" "github.com/ipfs/boxo/path" cid "github.com/ipfs/go-cid" cidutil "github.com/ipfs/go-cidutil" + coreiface "github.com/ipfs/kubo/core/coreiface" + caopts "github.com/ipfs/kubo/core/coreiface/options" "github.com/ipfs/kubo/tracing" peer "github.com/libp2p/go-libp2p/core/peer" routing "github.com/libp2p/go-libp2p/core/routing" diff --git a/core/coreapi/key.go b/core/coreapi/key.go index 4c914ff3d..e78868067 100644 --- a/core/coreapi/key.go +++ b/core/coreapi/key.go @@ -7,10 +7,10 @@ import ( "fmt" "sort" - coreiface "github.com/ipfs/boxo/coreiface" - caopts "github.com/ipfs/boxo/coreiface/options" "github.com/ipfs/boxo/ipns" "github.com/ipfs/boxo/path" + coreiface "github.com/ipfs/kubo/core/coreiface" + caopts "github.com/ipfs/kubo/core/coreiface/options" "github.com/ipfs/kubo/tracing" crypto "github.com/libp2p/go-libp2p/core/crypto" peer "github.com/libp2p/go-libp2p/core/peer" diff --git a/core/coreapi/name.go b/core/coreapi/name.go index 4f6c1a3cc..3c4145ed5 100644 --- a/core/coreapi/name.go +++ b/core/coreapi/name.go @@ -13,9 +13,9 @@ import ( "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" - coreiface "github.com/ipfs/boxo/coreiface" - caopts "github.com/ipfs/boxo/coreiface/options" "github.com/ipfs/boxo/path" + coreiface "github.com/ipfs/kubo/core/coreiface" + caopts "github.com/ipfs/kubo/core/coreiface/options" ci "github.com/libp2p/go-libp2p/core/crypto" peer "github.com/libp2p/go-libp2p/core/peer" ) diff --git a/core/coreapi/object.go b/core/coreapi/object.go index 3c63372e0..e8f94b1d5 100644 --- a/core/coreapi/object.go +++ b/core/coreapi/object.go @@ -10,8 +10,6 @@ import ( "fmt" "io" - coreiface "github.com/ipfs/boxo/coreiface" - caopts "github.com/ipfs/boxo/coreiface/options" dag "github.com/ipfs/boxo/ipld/merkledag" "github.com/ipfs/boxo/ipld/merkledag/dagutils" ft "github.com/ipfs/boxo/ipld/unixfs" @@ -19,6 +17,8 @@ import ( pin "github.com/ipfs/boxo/pinning/pinner" cid "github.com/ipfs/go-cid" ipld "github.com/ipfs/go-ipld-format" + coreiface "github.com/ipfs/kubo/core/coreiface" + caopts "github.com/ipfs/kubo/core/coreiface/options" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" diff --git a/core/coreapi/path.go b/core/coreapi/path.go index 1d8e868e4..1eb1f7181 100644 --- a/core/coreapi/path.go +++ b/core/coreapi/path.go @@ -11,10 +11,10 @@ import ( "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" - coreiface "github.com/ipfs/boxo/coreiface" "github.com/ipfs/boxo/path" ipfspathresolver "github.com/ipfs/boxo/path/resolver" ipld "github.com/ipfs/go-ipld-format" + coreiface "github.com/ipfs/kubo/core/coreiface" ) // ResolveNode resolves the path `p` using Unixfs resolver, gets and returns the diff --git a/core/coreapi/pin.go b/core/coreapi/pin.go index 7c33b3ee0..5cb92a819 100644 --- a/core/coreapi/pin.go +++ b/core/coreapi/pin.go @@ -5,13 +5,13 @@ import ( "fmt" bserv "github.com/ipfs/boxo/blockservice" - coreiface "github.com/ipfs/boxo/coreiface" - caopts "github.com/ipfs/boxo/coreiface/options" offline "github.com/ipfs/boxo/exchange/offline" "github.com/ipfs/boxo/ipld/merkledag" "github.com/ipfs/boxo/path" pin "github.com/ipfs/boxo/pinning/pinner" "github.com/ipfs/go-cid" + coreiface "github.com/ipfs/kubo/core/coreiface" + caopts "github.com/ipfs/kubo/core/coreiface/options" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" diff --git a/core/coreapi/pubsub.go b/core/coreapi/pubsub.go index 9e180c149..27c6813fe 100644 --- a/core/coreapi/pubsub.go +++ b/core/coreapi/pubsub.go @@ -4,8 +4,8 @@ import ( "context" "errors" - coreiface "github.com/ipfs/boxo/coreiface" - caopts "github.com/ipfs/boxo/coreiface/options" + coreiface "github.com/ipfs/kubo/core/coreiface" + caopts "github.com/ipfs/kubo/core/coreiface/options" "github.com/ipfs/kubo/tracing" pubsub "github.com/libp2p/go-libp2p-pubsub" peer "github.com/libp2p/go-libp2p/core/peer" diff --git a/core/coreapi/routing.go b/core/coreapi/routing.go index 3b28e0472..d784a738d 100644 --- a/core/coreapi/routing.go +++ b/core/coreapi/routing.go @@ -5,8 +5,8 @@ import ( "errors" "strings" - coreiface "github.com/ipfs/boxo/coreiface" - caopts "github.com/ipfs/boxo/coreiface/options" + coreiface "github.com/ipfs/kubo/core/coreiface" + caopts "github.com/ipfs/kubo/core/coreiface/options" peer "github.com/libp2p/go-libp2p/core/peer" ) diff --git a/core/coreapi/swarm.go b/core/coreapi/swarm.go index d3b6a0e43..e5332a217 100644 --- a/core/coreapi/swarm.go +++ b/core/coreapi/swarm.go @@ -5,7 +5,7 @@ import ( "sort" "time" - coreiface "github.com/ipfs/boxo/coreiface" + coreiface "github.com/ipfs/kubo/core/coreiface" "github.com/ipfs/kubo/tracing" inet "github.com/libp2p/go-libp2p/core/network" "github.com/libp2p/go-libp2p/core/peer" diff --git a/core/coreapi/test/api_test.go b/core/coreapi/test/api_test.go index d9591f835..d647a32c8 100644 --- a/core/coreapi/test/api_test.go +++ b/core/coreapi/test/api_test.go @@ -17,11 +17,11 @@ import ( "github.com/ipfs/kubo/core/node/libp2p" "github.com/ipfs/kubo/repo" - coreiface "github.com/ipfs/boxo/coreiface" - "github.com/ipfs/boxo/coreiface/tests" "github.com/ipfs/go-datastore" syncds "github.com/ipfs/go-datastore/sync" "github.com/ipfs/kubo/config" + coreiface "github.com/ipfs/kubo/core/coreiface" + "github.com/ipfs/kubo/core/coreiface/tests" "github.com/libp2p/go-libp2p/core/crypto" "github.com/libp2p/go-libp2p/core/peer" mocknet "github.com/libp2p/go-libp2p/p2p/net/mock" diff --git a/core/coreapi/test/path_test.go b/core/coreapi/test/path_test.go index 6ba80423d..692853a9a 100644 --- a/core/coreapi/test/path_test.go +++ b/core/coreapi/test/path_test.go @@ -6,11 +6,11 @@ import ( "testing" "time" - "github.com/ipfs/boxo/coreiface/options" "github.com/ipfs/boxo/files" "github.com/ipfs/boxo/ipld/merkledag" uio "github.com/ipfs/boxo/ipld/unixfs/io" "github.com/ipfs/boxo/path" + "github.com/ipfs/kubo/core/coreiface/options" "github.com/ipld/go-ipld-prime" ) diff --git a/core/coreapi/unixfs.go b/core/coreapi/unixfs.go index a7cac6a00..452e6017b 100644 --- a/core/coreapi/unixfs.go +++ b/core/coreapi/unixfs.go @@ -14,8 +14,6 @@ import ( blockservice "github.com/ipfs/boxo/blockservice" bstore "github.com/ipfs/boxo/blockstore" - coreiface "github.com/ipfs/boxo/coreiface" - options "github.com/ipfs/boxo/coreiface/options" "github.com/ipfs/boxo/files" filestore "github.com/ipfs/boxo/filestore" merkledag "github.com/ipfs/boxo/ipld/merkledag" @@ -28,6 +26,8 @@ import ( cid "github.com/ipfs/go-cid" cidutil "github.com/ipfs/go-cidutil" ipld "github.com/ipfs/go-ipld-format" + coreiface "github.com/ipfs/kubo/core/coreiface" + options "github.com/ipfs/kubo/core/coreiface/options" ) type UnixfsAPI CoreAPI diff --git a/core/corehttp/gateway.go b/core/corehttp/gateway.go index 3e0380d5a..a2567d8f0 100644 --- a/core/corehttp/gateway.go +++ b/core/corehttp/gateway.go @@ -10,7 +10,6 @@ import ( "time" "github.com/ipfs/boxo/blockservice" - iface "github.com/ipfs/boxo/coreiface" "github.com/ipfs/boxo/exchange/offline" "github.com/ipfs/boxo/files" "github.com/ipfs/boxo/gateway" @@ -21,6 +20,7 @@ import ( version "github.com/ipfs/kubo" "github.com/ipfs/kubo/config" "github.com/ipfs/kubo/core" + iface "github.com/ipfs/kubo/core/coreiface" "github.com/ipfs/kubo/core/node" "github.com/libp2p/go-libp2p/core/routing" "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" diff --git a/core/corehttp/gateway_test.go b/core/corehttp/gateway_test.go index 41a1c5821..c2e0073d9 100644 --- a/core/corehttp/gateway_test.go +++ b/core/corehttp/gateway_test.go @@ -16,11 +16,11 @@ import ( "github.com/ipfs/kubo/repo" "github.com/stretchr/testify/assert" - iface "github.com/ipfs/boxo/coreiface" "github.com/ipfs/boxo/path" "github.com/ipfs/go-datastore" syncds "github.com/ipfs/go-datastore/sync" "github.com/ipfs/kubo/config" + iface "github.com/ipfs/kubo/core/coreiface" ci "github.com/libp2p/go-libp2p/core/crypto" ) diff --git a/core/coreiface/block.go b/core/coreiface/block.go index cdd5fcee2..bf518f7fd 100644 --- a/core/coreiface/block.go +++ b/core/coreiface/block.go @@ -4,8 +4,8 @@ import ( "context" "io" - "github.com/ipfs/boxo/coreiface/options" "github.com/ipfs/boxo/path" + "github.com/ipfs/kubo/core/coreiface/options" ) // BlockStat contains information about a block diff --git a/core/coreiface/coreapi.go b/core/coreiface/coreapi.go index 25e54a37b..4fd6851af 100644 --- a/core/coreiface/coreapi.go +++ b/core/coreiface/coreapi.go @@ -5,8 +5,8 @@ package iface import ( "context" - "github.com/ipfs/boxo/coreiface/options" "github.com/ipfs/boxo/path" + "github.com/ipfs/kubo/core/coreiface/options" ipld "github.com/ipfs/go-ipld-format" ) diff --git a/core/coreiface/dht.go b/core/coreiface/dht.go index d9418ebfc..a916dbf3d 100644 --- a/core/coreiface/dht.go +++ b/core/coreiface/dht.go @@ -5,7 +5,7 @@ import ( "github.com/ipfs/boxo/path" - "github.com/ipfs/boxo/coreiface/options" + "github.com/ipfs/kubo/core/coreiface/options" "github.com/libp2p/go-libp2p/core/peer" ) diff --git a/core/coreiface/key.go b/core/coreiface/key.go index 4a1cbae80..9d61cc95b 100644 --- a/core/coreiface/key.go +++ b/core/coreiface/key.go @@ -5,7 +5,7 @@ import ( "github.com/ipfs/boxo/path" - "github.com/ipfs/boxo/coreiface/options" + "github.com/ipfs/kubo/core/coreiface/options" "github.com/libp2p/go-libp2p/core/peer" ) diff --git a/core/coreiface/name.go b/core/coreiface/name.go index f832033ef..f7c8f634c 100644 --- a/core/coreiface/name.go +++ b/core/coreiface/name.go @@ -4,9 +4,9 @@ import ( "context" "errors" - "github.com/ipfs/boxo/coreiface/options" "github.com/ipfs/boxo/ipns" "github.com/ipfs/boxo/path" + "github.com/ipfs/kubo/core/coreiface/options" ) var ErrResolveFailed = errors.New("could not resolve name") diff --git a/core/coreiface/object.go b/core/coreiface/object.go index 4a73f22ea..fa378ac6c 100644 --- a/core/coreiface/object.go +++ b/core/coreiface/object.go @@ -4,8 +4,8 @@ import ( "context" "io" - "github.com/ipfs/boxo/coreiface/options" "github.com/ipfs/boxo/path" + "github.com/ipfs/kubo/core/coreiface/options" "github.com/ipfs/go-cid" ipld "github.com/ipfs/go-ipld-format" diff --git a/core/coreiface/pin.go b/core/coreiface/pin.go index 057516d08..25a775965 100644 --- a/core/coreiface/pin.go +++ b/core/coreiface/pin.go @@ -5,7 +5,7 @@ import ( "github.com/ipfs/boxo/path" - "github.com/ipfs/boxo/coreiface/options" + "github.com/ipfs/kubo/core/coreiface/options" ) // Pin holds information about pinned resource diff --git a/core/coreiface/pubsub.go b/core/coreiface/pubsub.go index bbd1da4ec..5cf8de54d 100644 --- a/core/coreiface/pubsub.go +++ b/core/coreiface/pubsub.go @@ -4,7 +4,7 @@ import ( "context" "io" - "github.com/ipfs/boxo/coreiface/options" + "github.com/ipfs/kubo/core/coreiface/options" "github.com/libp2p/go-libp2p/core/peer" ) diff --git a/core/coreiface/routing.go b/core/coreiface/routing.go index 5099c3de0..c64e7baef 100644 --- a/core/coreiface/routing.go +++ b/core/coreiface/routing.go @@ -3,7 +3,7 @@ package iface import ( "context" - "github.com/ipfs/boxo/coreiface/options" + "github.com/ipfs/kubo/core/coreiface/options" ) // RoutingAPI specifies the interface to the routing layer. diff --git a/core/coreiface/tests/api.go b/core/coreiface/tests/api.go index a66e2abeb..c1fcb672d 100644 --- a/core/coreiface/tests/api.go +++ b/core/coreiface/tests/api.go @@ -6,7 +6,7 @@ import ( "testing" "time" - coreiface "github.com/ipfs/boxo/coreiface" + coreiface "github.com/ipfs/kubo/core/coreiface" ) var errAPINotImplemented = errors.New("api not implemented") diff --git a/core/coreiface/tests/block.go b/core/coreiface/tests/block.go index 6e254063e..3b4ca0bc0 100644 --- a/core/coreiface/tests/block.go +++ b/core/coreiface/tests/block.go @@ -7,10 +7,10 @@ import ( "strings" "testing" - coreiface "github.com/ipfs/boxo/coreiface" - opt "github.com/ipfs/boxo/coreiface/options" "github.com/ipfs/boxo/path" ipld "github.com/ipfs/go-ipld-format" + coreiface "github.com/ipfs/kubo/core/coreiface" + opt "github.com/ipfs/kubo/core/coreiface/options" mh "github.com/multiformats/go-multihash" ) diff --git a/core/coreiface/tests/dag.go b/core/coreiface/tests/dag.go index a106788d6..3a388c556 100644 --- a/core/coreiface/tests/dag.go +++ b/core/coreiface/tests/dag.go @@ -6,8 +6,8 @@ import ( "strings" "testing" - coreiface "github.com/ipfs/boxo/coreiface" "github.com/ipfs/boxo/path" + coreiface "github.com/ipfs/kubo/core/coreiface" ipldcbor "github.com/ipfs/go-ipld-cbor" ipld "github.com/ipfs/go-ipld-format" diff --git a/core/coreiface/tests/dht.go b/core/coreiface/tests/dht.go index 3b3ac1d61..6a908c5d3 100644 --- a/core/coreiface/tests/dht.go +++ b/core/coreiface/tests/dht.go @@ -6,8 +6,8 @@ import ( "testing" "time" - iface "github.com/ipfs/boxo/coreiface" - "github.com/ipfs/boxo/coreiface/options" + iface "github.com/ipfs/kubo/core/coreiface" + "github.com/ipfs/kubo/core/coreiface/options" ) func (tp *TestSuite) TestDht(t *testing.T) { diff --git a/core/coreiface/tests/key.go b/core/coreiface/tests/key.go index 0b755380e..c4c86b748 100644 --- a/core/coreiface/tests/key.go +++ b/core/coreiface/tests/key.go @@ -5,9 +5,9 @@ import ( "strings" "testing" - iface "github.com/ipfs/boxo/coreiface" - opt "github.com/ipfs/boxo/coreiface/options" "github.com/ipfs/go-cid" + iface "github.com/ipfs/kubo/core/coreiface" + opt "github.com/ipfs/kubo/core/coreiface/options" mbase "github.com/multiformats/go-multibase" ) diff --git a/core/coreiface/tests/name.go b/core/coreiface/tests/name.go index 2b6b7ec49..1e739fdd0 100644 --- a/core/coreiface/tests/name.go +++ b/core/coreiface/tests/name.go @@ -7,11 +7,11 @@ import ( "testing" "time" - coreiface "github.com/ipfs/boxo/coreiface" - opt "github.com/ipfs/boxo/coreiface/options" "github.com/ipfs/boxo/files" "github.com/ipfs/boxo/ipns" "github.com/ipfs/boxo/path" + coreiface "github.com/ipfs/kubo/core/coreiface" + opt "github.com/ipfs/kubo/core/coreiface/options" "github.com/stretchr/testify/require" ) diff --git a/core/coreiface/tests/object.go b/core/coreiface/tests/object.go index 5c6ba828c..9e0463ab6 100644 --- a/core/coreiface/tests/object.go +++ b/core/coreiface/tests/object.go @@ -8,8 +8,8 @@ import ( "strings" "testing" - iface "github.com/ipfs/boxo/coreiface" - opt "github.com/ipfs/boxo/coreiface/options" + iface "github.com/ipfs/kubo/core/coreiface" + opt "github.com/ipfs/kubo/core/coreiface/options" ) func (tp *TestSuite) TestObject(t *testing.T) { diff --git a/core/coreiface/tests/path.go b/core/coreiface/tests/path.go index 116aed2e7..87dce2c91 100644 --- a/core/coreiface/tests/path.go +++ b/core/coreiface/tests/path.go @@ -7,10 +7,10 @@ import ( "strings" "testing" - "github.com/ipfs/boxo/coreiface/options" "github.com/ipfs/boxo/path" "github.com/ipfs/go-cid" ipldcbor "github.com/ipfs/go-ipld-cbor" + "github.com/ipfs/kubo/core/coreiface/options" "github.com/stretchr/testify/require" ) diff --git a/core/coreiface/tests/pin.go b/core/coreiface/tests/pin.go index 49499b36a..fdd7c15cc 100644 --- a/core/coreiface/tests/pin.go +++ b/core/coreiface/tests/pin.go @@ -6,12 +6,12 @@ import ( "strings" "testing" - iface "github.com/ipfs/boxo/coreiface" - opt "github.com/ipfs/boxo/coreiface/options" "github.com/ipfs/boxo/path" "github.com/ipfs/go-cid" ipldcbor "github.com/ipfs/go-ipld-cbor" ipld "github.com/ipfs/go-ipld-format" + iface "github.com/ipfs/kubo/core/coreiface" + opt "github.com/ipfs/kubo/core/coreiface/options" ) func (tp *TestSuite) TestPin(t *testing.T) { diff --git a/core/coreiface/tests/pubsub.go b/core/coreiface/tests/pubsub.go index 8cbc6a3eb..6ae95f27b 100644 --- a/core/coreiface/tests/pubsub.go +++ b/core/coreiface/tests/pubsub.go @@ -5,8 +5,8 @@ import ( "testing" "time" - iface "github.com/ipfs/boxo/coreiface" - "github.com/ipfs/boxo/coreiface/options" + iface "github.com/ipfs/kubo/core/coreiface" + "github.com/ipfs/kubo/core/coreiface/options" ) func (tp *TestSuite) TestPubSub(t *testing.T) { diff --git a/core/coreiface/tests/routing.go b/core/coreiface/tests/routing.go index c56e91659..3f1f95d75 100644 --- a/core/coreiface/tests/routing.go +++ b/core/coreiface/tests/routing.go @@ -5,10 +5,10 @@ import ( "testing" "time" - iface "github.com/ipfs/boxo/coreiface" - "github.com/ipfs/boxo/coreiface/options" "github.com/ipfs/boxo/ipns" "github.com/ipfs/boxo/path" + iface "github.com/ipfs/kubo/core/coreiface" + "github.com/ipfs/kubo/core/coreiface/options" "github.com/stretchr/testify/require" ) diff --git a/core/coreiface/tests/unixfs.go b/core/coreiface/tests/unixfs.go index 31ac1b5c9..538f4d8ed 100644 --- a/core/coreiface/tests/unixfs.go +++ b/core/coreiface/tests/unixfs.go @@ -14,9 +14,9 @@ import ( "sync" "testing" - coreiface "github.com/ipfs/boxo/coreiface" - "github.com/ipfs/boxo/coreiface/options" "github.com/ipfs/boxo/path" + coreiface "github.com/ipfs/kubo/core/coreiface" + "github.com/ipfs/kubo/core/coreiface/options" "github.com/ipfs/boxo/files" mdag "github.com/ipfs/boxo/ipld/merkledag" diff --git a/core/coreiface/unixfs.go b/core/coreiface/unixfs.go index 35e108c02..d0dc4d8ce 100644 --- a/core/coreiface/unixfs.go +++ b/core/coreiface/unixfs.go @@ -3,10 +3,10 @@ package iface import ( "context" - "github.com/ipfs/boxo/coreiface/options" "github.com/ipfs/boxo/files" "github.com/ipfs/boxo/path" "github.com/ipfs/go-cid" + "github.com/ipfs/kubo/core/coreiface/options" ) type AddEvent struct { diff --git a/core/coreunix/add.go b/core/coreunix/add.go index 123c9fe65..83bec6d03 100644 --- a/core/coreunix/add.go +++ b/core/coreunix/add.go @@ -10,7 +10,6 @@ import ( bstore "github.com/ipfs/boxo/blockstore" chunker "github.com/ipfs/boxo/chunker" - coreiface "github.com/ipfs/boxo/coreiface" "github.com/ipfs/boxo/files" posinfo "github.com/ipfs/boxo/filestore/posinfo" dag "github.com/ipfs/boxo/ipld/merkledag" @@ -24,6 +23,7 @@ import ( "github.com/ipfs/go-cid" ipld "github.com/ipfs/go-ipld-format" logging "github.com/ipfs/go-log" + coreiface "github.com/ipfs/kubo/core/coreiface" "github.com/ipfs/kubo/tracing" ) diff --git a/core/coreunix/add_test.go b/core/coreunix/add_test.go index a09fd5d2b..1eb050ee9 100644 --- a/core/coreunix/add_test.go +++ b/core/coreunix/add_test.go @@ -16,7 +16,6 @@ import ( "github.com/ipfs/boxo/blockservice" blockstore "github.com/ipfs/boxo/blockstore" - coreiface "github.com/ipfs/boxo/coreiface" "github.com/ipfs/boxo/files" pi "github.com/ipfs/boxo/filestore/posinfo" dag "github.com/ipfs/boxo/ipld/merkledag" @@ -25,6 +24,7 @@ import ( "github.com/ipfs/go-datastore" syncds "github.com/ipfs/go-datastore/sync" config "github.com/ipfs/kubo/config" + coreiface "github.com/ipfs/kubo/core/coreiface" ) const testPeerID = "QmTFauExutTsy4XP6JbMFcw2Wa9645HJt2bTqL6qYDCKfe" diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 7b2e4e1bd..9a39a46a1 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.20 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.15.0 + github.com/ipfs/boxo v0.15.1-0.20231129112844-08959f281f86 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.32.1 github.com/multiformats/go-multiaddr v0.12.0 diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index a15178ee2..1bcbaf5df 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -303,8 +303,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.15.0 h1:BriLydj2nlK1nKeJQHxcKSuG5ZXcoutzhBklOtxC5pk= -github.com/ipfs/boxo v0.15.0/go.mod h1:X5ulcbR5Nh7sm3Db8+08AApUo6FsGC5mb23QDKAoB/M= +github.com/ipfs/boxo v0.15.1-0.20231129112844-08959f281f86 h1:9a7ug9Llglmdbzgj/gdKbPoZrd3EoaartzepObr/jlc= +github.com/ipfs/boxo v0.15.1-0.20231129112844-08959f281f86/go.mod h1:jAgpNQn7T7BnibUeReXcKU9Ha1xmYNyOlwVEl193ow0= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= diff --git a/docs/examples/kubo-as-a-library/main.go b/docs/examples/kubo-as-a-library/main.go index b7764a206..765e83c6d 100644 --- a/docs/examples/kubo-as-a-library/main.go +++ b/docs/examples/kubo-as-a-library/main.go @@ -11,9 +11,9 @@ import ( "strings" "sync" - icore "github.com/ipfs/boxo/coreiface" "github.com/ipfs/boxo/files" "github.com/ipfs/boxo/path" + icore "github.com/ipfs/kubo/core/coreiface" ma "github.com/multiformats/go-multiaddr" "github.com/ipfs/kubo/config" diff --git a/fuse/ipns/ipns_unix.go b/fuse/ipns/ipns_unix.go index 77cb8b18f..23704cabd 100644 --- a/fuse/ipns/ipns_unix.go +++ b/fuse/ipns/ipns_unix.go @@ -20,11 +20,11 @@ import ( fuse "bazil.org/fuse" fs "bazil.org/fuse/fs" - iface "github.com/ipfs/boxo/coreiface" - options "github.com/ipfs/boxo/coreiface/options" mfs "github.com/ipfs/boxo/mfs" cid "github.com/ipfs/go-cid" logging "github.com/ipfs/go-log" + iface "github.com/ipfs/kubo/core/coreiface" + options "github.com/ipfs/kubo/core/coreiface/options" ) func init() { diff --git a/go.mod b/go.mod index 6832b4091..d1514137b 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,7 @@ require ( github.com/hashicorp/go-multierror v1.1.1 github.com/ipfs-shipyard/nopfs v0.0.12-0.20231027223058-cde3b5ba964c github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c - github.com/ipfs/boxo v0.15.0 + github.com/ipfs/boxo v0.15.1-0.20231129112844-08959f281f86 github.com/ipfs/go-block-format v0.2.0 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 @@ -29,6 +29,7 @@ require ( github.com/ipfs/go-ds-measure v0.2.0 github.com/ipfs/go-fs-lock v0.0.7 github.com/ipfs/go-ipfs-cmds v0.10.0 + github.com/ipfs/go-ipld-cbor v0.0.6 github.com/ipfs/go-ipld-format v0.6.0 github.com/ipfs/go-ipld-git v0.1.1 github.com/ipfs/go-ipld-legacy v0.2.1 @@ -141,7 +142,6 @@ require ( github.com/ipfs/go-ipfs-pq v0.0.3 // indirect github.com/ipfs/go-ipfs-redirects-file v0.1.1 // indirect github.com/ipfs/go-ipfs-util v0.0.3 // indirect - github.com/ipfs/go-ipld-cbor v0.0.6 // indirect github.com/ipfs/go-merkledag v0.11.0 // indirect github.com/ipfs/go-peertaskqueue v0.8.1 // indirect github.com/ipfs/go-verifcid v0.0.2 // indirect diff --git a/go.sum b/go.sum index fbf947edc..bb4d9dda7 100644 --- a/go.sum +++ b/go.sum @@ -337,8 +337,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.15.0 h1:BriLydj2nlK1nKeJQHxcKSuG5ZXcoutzhBklOtxC5pk= -github.com/ipfs/boxo v0.15.0/go.mod h1:X5ulcbR5Nh7sm3Db8+08AApUo6FsGC5mb23QDKAoB/M= +github.com/ipfs/boxo v0.15.1-0.20231129112844-08959f281f86 h1:9a7ug9Llglmdbzgj/gdKbPoZrd3EoaartzepObr/jlc= +github.com/ipfs/boxo v0.15.1-0.20231129112844-08959f281f86/go.mod h1:jAgpNQn7T7BnibUeReXcKU9Ha1xmYNyOlwVEl193ow0= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= diff --git a/plugin/daemon.go b/plugin/daemon.go index 6ea58a921..9f75099d6 100644 --- a/plugin/daemon.go +++ b/plugin/daemon.go @@ -1,7 +1,7 @@ package plugin import ( - coreiface "github.com/ipfs/boxo/coreiface" + coreiface "github.com/ipfs/kubo/core/coreiface" ) // PluginDaemon is an interface for daemon plugins. These plugins will be run on diff --git a/repo/fsrepo/migrations/ipfsfetcher/ipfsfetcher.go b/repo/fsrepo/migrations/ipfsfetcher/ipfsfetcher.go index cd6a5182e..ea020dfcc 100644 --- a/repo/fsrepo/migrations/ipfsfetcher/ipfsfetcher.go +++ b/repo/fsrepo/migrations/ipfsfetcher/ipfsfetcher.go @@ -11,13 +11,13 @@ import ( "strings" "sync" - iface "github.com/ipfs/boxo/coreiface" - "github.com/ipfs/boxo/coreiface/options" "github.com/ipfs/boxo/files" "github.com/ipfs/boxo/path" "github.com/ipfs/kubo/config" "github.com/ipfs/kubo/core" "github.com/ipfs/kubo/core/coreapi" + iface "github.com/ipfs/kubo/core/coreiface" + "github.com/ipfs/kubo/core/coreiface/options" "github.com/ipfs/kubo/core/node/libp2p" "github.com/ipfs/kubo/repo/fsrepo" "github.com/ipfs/kubo/repo/fsrepo/migrations" diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 5bfe4383f..c27e946f4 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -104,7 +104,7 @@ require ( github.com/hexops/gotextdiff v1.0.3 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/ipfs/bbloom v0.0.4 // indirect - github.com/ipfs/boxo v0.15.0 // indirect + github.com/ipfs/boxo v0.15.1-0.20231129112844-08959f281f86 // indirect github.com/ipfs/go-block-format v0.2.0 // indirect github.com/ipfs/go-cid v0.4.1 // indirect github.com/ipfs/go-datastore v0.6.0 // indirect @@ -191,6 +191,7 @@ require ( github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/ryancurrah/gomodguard v1.3.0 // indirect github.com/ryanrolds/sqlclosecheck v0.4.0 // indirect + github.com/samber/lo v1.36.0 // indirect github.com/sanposhiho/wastedassign/v2 v2.0.7 // indirect github.com/sashamelentyev/interfacebloat v1.1.0 // indirect github.com/sashamelentyev/usestdlibvars v1.23.0 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index b1f18cd5f..918fda6f5 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -344,8 +344,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.15.0 h1:BriLydj2nlK1nKeJQHxcKSuG5ZXcoutzhBklOtxC5pk= -github.com/ipfs/boxo v0.15.0/go.mod h1:X5ulcbR5Nh7sm3Db8+08AApUo6FsGC5mb23QDKAoB/M= +github.com/ipfs/boxo v0.15.1-0.20231129112844-08959f281f86 h1:9a7ug9Llglmdbzgj/gdKbPoZrd3EoaartzepObr/jlc= +github.com/ipfs/boxo v0.15.1-0.20231129112844-08959f281f86/go.mod h1:jAgpNQn7T7BnibUeReXcKU9Ha1xmYNyOlwVEl193ow0= github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs= github.com/ipfs/go-block-format v0.2.0/go.mod h1:+jpL11nFx5A/SPpsoBn6Bzkra/zaArfSmsknbPMYgzM= github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= @@ -640,6 +640,8 @@ github.com/ryancurrah/gomodguard v1.3.0 h1:q15RT/pd6UggBXVBuLps8BXRvl5GPBcwVA7BJ github.com/ryancurrah/gomodguard v1.3.0/go.mod h1:ggBxb3luypPEzqVtq33ee7YSN35V28XeGnid8dnni50= github.com/ryanrolds/sqlclosecheck v0.4.0 h1:i8SX60Rppc1wRuyQjMciLqIzV3xnoHB7/tXbr6RGYNI= github.com/ryanrolds/sqlclosecheck v0.4.0/go.mod h1:TBRRjzL31JONc9i4XMinicuo+s+E8yKZ5FN8X3G6CKQ= +github.com/samber/lo v1.36.0 h1:4LaOxH1mHnbDGhTVE0i1z8v/lWaQW8AIfOD3HU4mSaw= +github.com/samber/lo v1.36.0/go.mod h1:HLeWcJRRyLKp3+/XBJvOrerCQn9mhdKMHyd7IRlgeQ8= github.com/sanposhiho/wastedassign/v2 v2.0.7 h1:J+6nrY4VW+gC9xFzUc+XjPD3g3wF3je/NsJFwFK7Uxc= github.com/sanposhiho/wastedassign/v2 v2.0.7/go.mod h1:KyZ0MWTwxxBmfwn33zh3k1dmsbF2ud9pAAGfoLfjhtI= github.com/sashamelentyev/interfacebloat v1.1.0 h1:xdRdJp0irL086OyW1H/RTZTr1h/tMEOsumirXcOJqAw= @@ -721,6 +723,7 @@ github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3 h1:f+jULpR github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3/go.mod h1:ON8b8w4BN/kE1EOhwT0o+d62W65a6aPw1nouo9LMgyY= github.com/tetafro/godot v1.4.11 h1:BVoBIqAf/2QdbFmSwAWnaIqDivZdOV0ZRwEm6jivLKw= github.com/tetafro/godot v1.4.11/go.mod h1:LR3CJpxDVGlYOWn3ZZg1PgNZdTUvzsZWu8xaEohUpn8= +github.com/thoas/go-funk v0.9.1 h1:O549iLZqPpTUQ10ykd26sZhzD+rmR5pWhuElrhbC20M= github.com/timakin/bodyclose v0.0.0-20230421092635-574207250966 h1:quvGphlmUVU+nhpFa4gg4yJyTRJ13reZMDHrKwYw53M= github.com/timakin/bodyclose v0.0.0-20230421092635-574207250966/go.mod h1:27bSVNWSBOHm+qRp1T9qzaIpsWEP6TbUnei/43HK+PQ= github.com/timonwong/loggercheck v0.9.4 h1:HKKhqrjcVj8sxL7K77beXh0adEm6DLjV/QOGeMXEVi4= From d882642168ed22711c554cdb84012f145b099926 Mon Sep 17 00:00:00 2001 From: Russell Dempsey <1173416+SgtPooki@users.noreply.github.com> Date: Sun, 3 Dec 2023 13:48:28 -0800 Subject: [PATCH 0952/1212] feat: webui v4.2.0 (#10241) https://github.com/ipfs/ipfs-webui/releases/tag/v4.2.0 Co-authored-by: Marcin Rataj --- core/corehttp/webui.go | 3 ++- docs/changelogs/v0.25.md | 9 ++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/core/corehttp/webui.go b/core/corehttp/webui.go index 4c8e04723..5ec6edf15 100644 --- a/core/corehttp/webui.go +++ b/core/corehttp/webui.go @@ -1,11 +1,12 @@ package corehttp // TODO: move to IPNS -const WebUIPath = "/ipfs/bafybeiamycmd52xvg6k3nzr6z3n33de6a2teyhquhj4kspdtnvetnkrfim" // v4.1.1 +const WebUIPath = "/ipfs/bafybeidf7cpkwsjkq6xs3r6fbbxghbugilx3jtezbza7gua3k5wjixpmba" // v4.2.0 // WebUIPaths is a list of all past webUI paths. var WebUIPaths = []string{ WebUIPath, + "/ipfs/bafybeiamycmd52xvg6k3nzr6z3n33de6a2teyhquhj4kspdtnvetnkrfim", "/ipfs/bafybeieqdeoqkf7xf4aozd524qncgiloh33qgr25lyzrkusbcre4c3fxay", "/ipfs/bafybeicyp7ssbnj3hdzehcibmapmpuc3atrsc4ch3q6acldfh4ojjdbcxe", "/ipfs/bafybeigs6d53gpgu34553mbi5bbkb26e4ikruoaaar75jpfdywpup2r3my", diff --git a/docs/changelogs/v0.25.md b/docs/changelogs/v0.25.md index 1e1f05f71..ed8275f2f 100644 --- a/docs/changelogs/v0.25.md +++ b/docs/changelogs/v0.25.md @@ -6,8 +6,9 @@ - [Overview](#overview) - [🔦 Highlights](#-highlights) + - [WebUI: Updated Peers View](#webui-updated-peers-view) - [RPC `API.Authorizations`](#rpc-apiauthorizations) - - [MPLEX removal](#mplex-removal) + - [MPLEX Removal](#mplex-removal) - [Graphsync Experiment Removal](#graphsync-experiment-removal) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -16,6 +17,12 @@ ### 🔦 Highlights +#### WebUI: Updated Peers View + +WebUI [v4.2.0](https://github.com/ipfs/ipfs-webui/releases/tag/v4.2.0) shipped +with updated [ipfs-geoip](https://www.npmjs.com/package/ipfs-geoip) dataset +and [ability to filter the peers table](https://github.com/ipfs/ipfs-webui/pull/2181). + #### RPC `API.Authorizations` Kubo RPC API now supports optional HTTP Authorization. From 7b05b5dd33eebd18d0325202d8f2dc312e74dc5a Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Fri, 1 Dec 2023 01:21:36 +0100 Subject: [PATCH 0953/1212] docs(cli): fix spelling this fixes lint errors in RPC docs that were raised by vole in https://github.com/ipfs/ipfs-docs/pull/1772 so we don't get them in kubo 0.25 --- core/commands/name/ipns.go | 2 +- core/commands/resolve.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/commands/name/ipns.go b/core/commands/name/ipns.go index f556baf7c..92cbb59a3 100644 --- a/core/commands/name/ipns.go +++ b/core/commands/name/ipns.go @@ -74,7 +74,7 @@ Resolve the value of a dnslink: cmds.BoolOption(recursiveOptionName, "r", "Resolve until the result is not an IPNS name.").WithDefault(true), cmds.BoolOption(nocacheOptionName, "n", "Do not use cached entries."), cmds.UintOption(dhtRecordCountOptionName, "dhtrc", "Number of records to request for DHT resolution.").WithDefault(uint(namesys.DefaultResolverDhtRecordCount)), - cmds.StringOption(dhtTimeoutOptionName, "dhtt", "Max time to collect values during DHT resolution eg \"30s\". Pass 0 for no timeout.").WithDefault(namesys.DefaultResolverDhtTimeout.String()), + cmds.StringOption(dhtTimeoutOptionName, "dhtt", "Max time to collect values during DHT resolution e.g. \"30s\". Pass 0 for no timeout.").WithDefault(namesys.DefaultResolverDhtTimeout.String()), cmds.BoolOption(streamOptionName, "s", "Stream entries as they are found."), }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { diff --git a/core/commands/resolve.go b/core/commands/resolve.go index d60eb0633..b786ed23d 100644 --- a/core/commands/resolve.go +++ b/core/commands/resolve.go @@ -70,7 +70,7 @@ Resolve the value of an IPFS DAG path: Options: []cmds.Option{ cmds.BoolOption(resolveRecursiveOptionName, "r", "Resolve until the result is an IPFS name.").WithDefault(true), cmds.IntOption(resolveDhtRecordCountOptionName, "dhtrc", "Number of records to request for DHT resolution."), - cmds.StringOption(resolveDhtTimeoutOptionName, "dhtt", "Max time to collect values during DHT resolution eg \"30s\". Pass 0 for no timeout."), + cmds.StringOption(resolveDhtTimeoutOptionName, "dhtt", "Max time to collect values during DHT resolution e.g. \"30s\". Pass 0 for no timeout."), }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { api, err := cmdenv.GetApi(env, req) From 8ab2de5ff05e1427a22be868b31efbcd58a6ee13 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Mon, 4 Dec 2023 09:51:26 +0100 Subject: [PATCH 0954/1212] feat: ipfs key sign|verify (#10235) --- client/rpc/key.go | 52 ++++ core/commands/commands_test.go | 2 + core/commands/keystore.go | 136 +++++++++ core/coreapi/key.go | 80 +++++ core/coreiface/key.go | 8 + core/coreiface/tests/key.go | 533 +++++++++++++-------------------- docs/changelogs/v0.25.md | 9 + 7 files changed, 498 insertions(+), 322 deletions(-) diff --git a/client/rpc/key.go b/client/rpc/key.go index daddffb23..710d9fb06 100644 --- a/client/rpc/key.go +++ b/client/rpc/key.go @@ -1,6 +1,7 @@ package rpc import ( + "bytes" "context" "errors" @@ -9,6 +10,7 @@ import ( iface "github.com/ipfs/kubo/core/coreiface" caopts "github.com/ipfs/kubo/core/coreiface/options" "github.com/libp2p/go-libp2p/core/peer" + "github.com/multiformats/go-multibase" ) type KeyAPI HttpApi @@ -141,3 +143,53 @@ func (api *KeyAPI) Remove(ctx context.Context, name string) (iface.Key, error) { func (api *KeyAPI) core() *HttpApi { return (*HttpApi)(api) } + +func (api *KeyAPI) Sign(ctx context.Context, name string, data []byte) (iface.Key, []byte, error) { + var out struct { + Key keyOutput + Signature string + } + + err := api.core().Request("key/sign"). + Option("key", name). + FileBody(bytes.NewReader(data)). + Exec(ctx, &out) + if err != nil { + return nil, nil, err + } + + key, err := newKey(out.Key.Name, out.Key.Id) + if err != nil { + return nil, nil, err + } + + _, signature, err := multibase.Decode(out.Signature) + if err != nil { + return nil, nil, err + } + + return key, signature, nil +} + +func (api *KeyAPI) Verify(ctx context.Context, keyOrName string, signature, data []byte) (iface.Key, bool, error) { + var out struct { + Key keyOutput + SignatureValid bool + } + + err := api.core().Request("key/verify"). + Option("key", keyOrName). + Option("signature", toMultibase(signature)). + FileBody(bytes.NewReader(data)). + Exec(ctx, &out) + if err != nil { + return nil, false, err + } + + key, err := newKey(out.Key.Name, out.Key.Id) + if err != nil { + return nil, false, err + } + + return key, out.SignatureValid, nil +} diff --git a/core/commands/commands_test.go b/core/commands/commands_test.go index a73a0338e..a34aab448 100644 --- a/core/commands/commands_test.go +++ b/core/commands/commands_test.go @@ -164,6 +164,8 @@ func TestCommands(t *testing.T) { "/key/rename", "/key/rm", "/key/rotate", + "/key/sign", + "/key/verify", "/log", "/log/level", "/log/ls", diff --git a/core/commands/keystore.go b/core/commands/keystore.go index 2ad2f7dbd..a86fb281a 100644 --- a/core/commands/keystore.go +++ b/core/commands/keystore.go @@ -24,6 +24,7 @@ import ( migrations "github.com/ipfs/kubo/repo/fsrepo/migrations" "github.com/libp2p/go-libp2p/core/crypto" peer "github.com/libp2p/go-libp2p/core/peer" + mbase "github.com/multiformats/go-multibase" ) var KeyCmd = &cmds.Command{ @@ -51,6 +52,8 @@ publish'. "rename": keyRenameCmd, "rm": keyRmCmd, "rotate": keyRotateCmd, + "sign": keySignCmd, + "verify": keyVerifyCmd, }, } @@ -688,6 +691,139 @@ func keyOutputListEncoders() cmds.EncoderFunc { }) } +type KeySignOutput struct { + Key KeyOutput + Signature string +} + +var keySignCmd = &cmds.Command{ + Status: cmds.Experimental, + Helptext: cmds.HelpText{ + Tagline: "Generates a signature for the given data with a specified key. Useful for proving the key ownership.", + LongDescription: ` +Sign arbitrary bytes, such as to prove ownership of a Peer ID or an IPNS Name. +To avoid signature reuse, the signed payload is always prefixed with +"libp2p-key signed message:". +`, + }, + Options: []cmds.Option{ + cmds.StringOption("key", "k", "The name of the key to use for signing."), + ke.OptionIPNSBase, + }, + Arguments: []cmds.Argument{ + cmds.FileArg("data", true, false, "The data to sign.").EnableStdin(), + }, + Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { + api, err := cmdenv.GetApi(env, req) + if err != nil { + return err + } + keyEnc, err := ke.KeyEncoderFromString(req.Options[ke.OptionIPNSBase.Name()].(string)) + if err != nil { + return err + } + + name, _ := req.Options["key"].(string) + + file, err := cmdenv.GetFileArg(req.Files.Entries()) + if err != nil { + return err + } + defer file.Close() + + data, err := io.ReadAll(file) + if err != nil { + return err + } + + key, signature, err := api.Key().Sign(req.Context, name, data) + if err != nil { + return err + } + + encodedSignature, err := mbase.Encode(mbase.Base64url, signature) + if err != nil { + return err + } + + return res.Emit(&KeySignOutput{ + Key: KeyOutput{ + Name: key.Name(), + Id: keyEnc.FormatID(key.ID()), + }, + Signature: encodedSignature, + }) + }, + Type: KeySignOutput{}, +} + +type KeyVerifyOutput struct { + Key KeyOutput + SignatureValid bool +} + +var keyVerifyCmd = &cmds.Command{ + Status: cmds.Experimental, + Helptext: cmds.HelpText{ + Tagline: "Verify that the given data and signature match.", + LongDescription: ` +Verify if the given data and signatures match. To avoid the signature reuse, +the signed payload is always prefixed with "libp2p-key signed message:". +`, + }, + Options: []cmds.Option{ + cmds.StringOption("key", "k", "The name of the key to use for signing."), + cmds.StringOption("signature", "s", "Multibase-encoded signature to verify."), + ke.OptionIPNSBase, + }, + Arguments: []cmds.Argument{ + cmds.FileArg("data", true, false, "The data to verify against the given signature.").EnableStdin(), + }, + Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { + api, err := cmdenv.GetApi(env, req) + if err != nil { + return err + } + keyEnc, err := ke.KeyEncoderFromString(req.Options[ke.OptionIPNSBase.Name()].(string)) + if err != nil { + return err + } + + name, _ := req.Options["key"].(string) + encodedSignature, _ := req.Options["signature"].(string) + + _, signature, err := mbase.Decode(encodedSignature) + if err != nil { + return err + } + + file, err := cmdenv.GetFileArg(req.Files.Entries()) + if err != nil { + return err + } + defer file.Close() + + data, err := io.ReadAll(file) + if err != nil { + return err + } + + key, valid, err := api.Key().Verify(req.Context, name, signature, data) + if err != nil { + return err + } + + return res.Emit(&KeyVerifyOutput{ + Key: KeyOutput{ + Name: key.Name(), + Id: keyEnc.FormatID(key.ID()), + }, + SignatureValid: valid, + }) + }, + Type: KeyVerifyOutput{}, +} + // DaemonNotRunning checks to see if the ipfs repo is locked, indicating that // the daemon is running, and returns and error if the daemon is running. func DaemonNotRunning(req *cmds.Request, env cmds.Environment) error { diff --git a/core/coreapi/key.go b/core/coreapi/key.go index e78868067..a6101dae8 100644 --- a/core/coreapi/key.go +++ b/core/coreapi/key.go @@ -262,3 +262,83 @@ func (api *KeyAPI) Self(ctx context.Context) (coreiface.Key, error) { return newKey("self", api.identity) } + +const signedMessagePrefix = "libp2p-key signed message:" + +func (api *KeyAPI) Sign(ctx context.Context, name string, data []byte) (coreiface.Key, []byte, error) { + var ( + sk crypto.PrivKey + err error + ) + if name == "" || name == "self" { + name = "self" + sk = api.privateKey + } else { + sk, err = api.repo.Keystore().Get(name) + } + if err != nil { + return nil, nil, err + } + + pid, err := peer.IDFromPrivateKey(sk) + if err != nil { + return nil, nil, err + } + + key, err := newKey(name, pid) + if err != nil { + return nil, nil, err + } + + data = append([]byte(signedMessagePrefix), data...) + + sig, err := sk.Sign(data) + if err != nil { + return nil, nil, err + } + + return key, sig, nil +} + +func (api *KeyAPI) Verify(ctx context.Context, keyOrName string, signature, data []byte) (coreiface.Key, bool, error) { + var ( + name string + pk crypto.PubKey + err error + ) + if keyOrName == "" || keyOrName == "self" { + name = "self" + pk = api.privateKey.GetPublic() + } else if sk, err := api.repo.Keystore().Get(keyOrName); err == nil { + name = keyOrName + pk = sk.GetPublic() + } else if ipnsName, err := ipns.NameFromString(keyOrName); err == nil { + // This works for both IPNS names and Peer IDs. + name = "" + pk, err = ipnsName.Peer().ExtractPublicKey() + if err != nil { + return nil, false, err + } + } else { + return nil, false, fmt.Errorf("'%q' is not a known key, an IPNS Name, or a valid PeerID", keyOrName) + } + + pid, err := peer.IDFromPublicKey(pk) + if err != nil { + return nil, false, err + } + + key, err := newKey(name, pid) + if err != nil { + return nil, false, err + } + + data = append([]byte(signedMessagePrefix), data...) + + valid, err := pk.Verify(data, signature) + if err != nil { + return nil, false, err + } + + return key, valid, nil +} diff --git a/core/coreiface/key.go b/core/coreiface/key.go index 9d61cc95b..6125e593b 100644 --- a/core/coreiface/key.go +++ b/core/coreiface/key.go @@ -40,4 +40,12 @@ type KeyAPI interface { // Remove removes keys from keystore. Returns ipns path of the removed key Remove(ctx context.Context, name string) (Key, error) + + // Sign signs the given data with the key named name. Returns the key used + // for signing, the signature, and an error. + Sign(ctx context.Context, name string, data []byte) (Key, []byte, error) + + // Verify verifies if the given data and signatures match. Returns the key used + // for verification, whether signature and data match, and an error. + Verify(ctx context.Context, keyOrName string, signature, data []byte) (Key, bool, error) } diff --git a/core/coreiface/tests/key.go b/core/coreiface/tests/key.go index c4c86b748..90936b0e2 100644 --- a/core/coreiface/tests/key.go +++ b/core/coreiface/tests/key.go @@ -5,10 +5,14 @@ import ( "strings" "testing" + "github.com/ipfs/boxo/ipns" "github.com/ipfs/go-cid" iface "github.com/ipfs/kubo/core/coreiface" opt "github.com/ipfs/kubo/core/coreiface/options" + "github.com/libp2p/go-libp2p/core/peer" mbase "github.com/multiformats/go-multibase" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func (tp *TestSuite) TestKey(t *testing.T) { @@ -34,151 +38,90 @@ func (tp *TestSuite) TestKey(t *testing.T) { t.Run("TestRenameOverwrite", tp.TestRenameOverwrite) t.Run("TestRenameSameNameNoForce", tp.TestRenameSameNameNoForce) t.Run("TestRenameSameName", tp.TestRenameSameName) - t.Run("TestRemove", tp.TestRemove) + t.Run("TestSign", tp.TestSign) + t.Run("TestVerify", tp.TestVerify) } func (tp *TestSuite) TestListSelf(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() + api, err := tp.makeAPI(t, ctx) - if err != nil { - t.Fatal(err) - return - } + require.NoError(t, err) self, err := api.Key().Self(ctx) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) keys, err := api.Key().List(ctx) - if err != nil { - t.Fatalf("failed to list keys: %s", err) - return - } - - if len(keys) != 1 { - t.Fatalf("there should be 1 key (self), got %d", len(keys)) - return - } - - if keys[0].Name() != "self" { - t.Errorf("expected the key to be called 'self', got '%s'", keys[0].Name()) - } - - if keys[0].Path().String() != "/ipns/"+iface.FormatKeyID(self.ID()) { - t.Errorf("expected the key to have path '/ipns/%s', got '%s'", iface.FormatKeyID(self.ID()), keys[0].Path().String()) - } + require.NoError(t, err) + require.Len(t, keys, 1) + assert.Equal(t, "self", keys[0].Name()) + assert.Equal(t, "/ipns/"+iface.FormatKeyID(self.ID()), keys[0].Path().String()) } func (tp *TestSuite) TestRenameSelf(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() + api, err := tp.makeAPI(t, ctx) - if err != nil { - t.Fatal(err) - return - } + require.NoError(t, err) _, _, err = api.Key().Rename(ctx, "self", "foo") - if err == nil { - t.Error("expected error to not be nil") - } else { - if !strings.Contains(err.Error(), "cannot rename key with name 'self'") { - t.Fatalf("expected error 'cannot rename key with name 'self'', got '%s'", err.Error()) - } - } + require.ErrorContains(t, err, "cannot rename key with name 'self'") _, _, err = api.Key().Rename(ctx, "self", "foo", opt.Key.Force(true)) - if err == nil { - t.Error("expected error to not be nil") - } else { - if !strings.Contains(err.Error(), "cannot rename key with name 'self'") { - t.Fatalf("expected error 'cannot rename key with name 'self'', got '%s'", err.Error()) - } - } + require.ErrorContains(t, err, "cannot rename key with name 'self'") } func (tp *TestSuite) TestRemoveSelf(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() + api, err := tp.makeAPI(t, ctx) - if err != nil { - t.Fatal(err) - return - } + require.NoError(t, err) _, err = api.Key().Remove(ctx, "self") - if err == nil { - t.Error("expected error to not be nil") - } else { - if !strings.Contains(err.Error(), "cannot remove key with name 'self'") { - t.Fatalf("expected error 'cannot remove key with name 'self'', got '%s'", err.Error()) - } - } + require.ErrorContains(t, err, "cannot remove key with name 'self'") } func (tp *TestSuite) TestGenerate(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() + api, err := tp.makeAPI(t, ctx) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) k, err := api.Key().Generate(ctx, "foo") - if err != nil { - t.Fatal(err) - return - } - - if k.Name() != "foo" { - t.Errorf("expected the key to be called 'foo', got '%s'", k.Name()) - } + require.NoError(t, err) + require.Equal(t, "foo", k.Name()) verifyIPNSPath(t, k.Path().String()) } -func verifyIPNSPath(t *testing.T, p string) bool { +func verifyIPNSPath(t *testing.T, p string) { t.Helper() - if !strings.HasPrefix(p, "/ipns/") { - t.Errorf("path %q does not look like an IPNS path", p) - return false - } + + require.True(t, strings.HasPrefix(p, "/ipns/")) + k := p[len("/ipns/"):] c, err := cid.Decode(k) - if err != nil { - t.Errorf("failed to decode IPNS key %q (%v)", k, err) - return false - } + require.NoError(t, err) + b36, err := c.StringOfBase(mbase.Base36) - if err != nil { - t.Fatalf("cid cannot format itself in b36") - return false - } - if b36 != k { - t.Errorf("IPNS key is not base36") - } - return true + require.NoError(t, err) + require.Equal(t, k, b36) } func (tp *TestSuite) TestGenerateSize(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() + api, err := tp.makeAPI(t, ctx) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) k, err := api.Key().Generate(ctx, "foo", opt.Key.Size(2048)) - if err != nil { - t.Fatal(err) - return - } - - if k.Name() != "foo" { - t.Errorf("expected the key to be called 'foo', got '%s'", k.Name()) - } + require.NoError(t, err) + require.Equal(t, "foo", k.Name()) verifyIPNSPath(t, k.Path().String()) } @@ -190,93 +133,47 @@ func (tp *TestSuite) TestGenerateType(t *testing.T) { defer cancel() api, err := tp.makeAPI(t, ctx) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) k, err := api.Key().Generate(ctx, "bar", opt.Key.Type(opt.Ed25519Key)) - if err != nil { - t.Fatal(err) - return - } - - if k.Name() != "bar" { - t.Errorf("expected the key to be called 'foo', got '%s'", k.Name()) - } - + require.NoError(t, err) + require.Equal(t, "bar", k.Name()) // Expected to be an inlined identity hash. - if !strings.HasPrefix(k.Path().String(), "/ipns/12") { - t.Errorf("expected the key to be prefixed with '/ipns/12', got '%s'", k.Path().String()) - } + require.True(t, strings.HasPrefix(k.Path().String(), "/ipns/12")) } func (tp *TestSuite) TestGenerateExisting(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() + api, err := tp.makeAPI(t, ctx) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) _, err = api.Key().Generate(ctx, "foo") - if err != nil { - t.Fatal(err) - return - } + require.NoError(t, err) _, err = api.Key().Generate(ctx, "foo") - if err == nil { - t.Error("expected error to not be nil") - } else { - if !strings.Contains(err.Error(), "key with name 'foo' already exists") { - t.Fatalf("expected error 'key with name 'foo' already exists', got '%s'", err.Error()) - } - } + require.ErrorContains(t, err, "key with name 'foo' already exists") _, err = api.Key().Generate(ctx, "self") - if err == nil { - t.Error("expected error to not be nil") - } else { - if !strings.Contains(err.Error(), "cannot create key with name 'self'") { - t.Fatalf("expected error 'cannot create key with name 'self'', got '%s'", err.Error()) - } - } + require.ErrorContains(t, err, "cannot create key with name 'self'") } func (tp *TestSuite) TestList(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() + api, err := tp.makeAPI(t, ctx) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) _, err = api.Key().Generate(ctx, "foo") - if err != nil { - t.Fatal(err) - return - } + require.NoError(t, err) l, err := api.Key().List(ctx) - if err != nil { - t.Fatal(err) - return - } - - if len(l) != 2 { - t.Fatalf("expected to get 2 keys, got %d", len(l)) - return - } - - if l[0].Name() != "self" { - t.Fatalf("expected key 0 to be called 'self', got '%s'", l[0].Name()) - return - } - - if l[1].Name() != "foo" { - t.Fatalf("expected key 1 to be called 'foo', got '%s'", l[1].Name()) - return - } + require.NoError(t, err) + require.Len(t, l, 2) + require.Equal(t, "self", l[0].Name()) + require.Equal(t, "foo", l[1].Name()) verifyIPNSPath(t, l[0].Path().String()) verifyIPNSPath(t, l[1].Path().String()) @@ -285,254 +182,246 @@ func (tp *TestSuite) TestList(t *testing.T) { func (tp *TestSuite) TestRename(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() + api, err := tp.makeAPI(t, ctx) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) _, err = api.Key().Generate(ctx, "foo") - if err != nil { - t.Fatal(err) - return - } + require.NoError(t, err) k, overwrote, err := api.Key().Rename(ctx, "foo", "bar") - if err != nil { - t.Fatal(err) - return - } - - if overwrote { - t.Error("overwrote should be false") - } - - if k.Name() != "bar" { - t.Errorf("returned key should be called 'bar', got '%s'", k.Name()) - } + require.NoError(t, err) + assert.False(t, overwrote) + assert.Equal(t, "bar", k.Name()) } func (tp *TestSuite) TestRenameToSelf(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() + api, err := tp.makeAPI(t, ctx) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) _, err = api.Key().Generate(ctx, "foo") - if err != nil { - t.Fatal(err) - return - } + require.NoError(t, err) _, _, err = api.Key().Rename(ctx, "foo", "self") - if err == nil { - t.Error("expected error to not be nil") - } else { - if !strings.Contains(err.Error(), "cannot overwrite key with name 'self'") { - t.Fatalf("expected error 'cannot overwrite key with name 'self'', got '%s'", err.Error()) - } - } + require.ErrorContains(t, err, "cannot overwrite key with name 'self'") } func (tp *TestSuite) TestRenameToSelfForce(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() + api, err := tp.makeAPI(t, ctx) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) _, err = api.Key().Generate(ctx, "foo") - if err != nil { - t.Fatal(err) - return - } + require.NoError(t, err) _, _, err = api.Key().Rename(ctx, "foo", "self", opt.Key.Force(true)) - if err == nil { - t.Error("expected error to not be nil") - } else { - if !strings.Contains(err.Error(), "cannot overwrite key with name 'self'") { - t.Fatalf("expected error 'cannot overwrite key with name 'self'', got '%s'", err.Error()) - } - } + require.ErrorContains(t, err, "cannot overwrite key with name 'self'") } func (tp *TestSuite) TestRenameOverwriteNoForce(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() + api, err := tp.makeAPI(t, ctx) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) _, err = api.Key().Generate(ctx, "foo") - if err != nil { - t.Fatal(err) - return - } + require.NoError(t, err) _, err = api.Key().Generate(ctx, "bar") - if err != nil { - t.Fatal(err) - return - } + require.NoError(t, err) _, _, err = api.Key().Rename(ctx, "foo", "bar") - if err == nil { - t.Error("expected error to not be nil") - } else { - if !strings.Contains(err.Error(), "key by that name already exists, refusing to overwrite") { - t.Fatalf("expected error 'key by that name already exists, refusing to overwrite', got '%s'", err.Error()) - } - } + require.ErrorContains(t, err, "key by that name already exists, refusing to overwrite") } func (tp *TestSuite) TestRenameOverwrite(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() + api, err := tp.makeAPI(t, ctx) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) kfoo, err := api.Key().Generate(ctx, "foo") - if err != nil { - t.Fatal(err) - return - } + require.NoError(t, err) _, err = api.Key().Generate(ctx, "bar") - if err != nil { - t.Fatal(err) - return - } + require.NoError(t, err) k, overwrote, err := api.Key().Rename(ctx, "foo", "bar", opt.Key.Force(true)) - if err != nil { - t.Fatal(err) - return - } - - if !overwrote { - t.Error("overwrote should be true") - } - - if k.Name() != "bar" { - t.Errorf("returned key should be called 'bar', got '%s'", k.Name()) - } - - if k.Path().String() != kfoo.Path().String() { - t.Errorf("k and kfoo should have equal paths, '%s'!='%s'", k.Path().String(), kfoo.Path().String()) - } + require.NoError(t, err) + require.True(t, overwrote) + assert.Equal(t, "bar", k.Name()) + assert.Equal(t, kfoo.Path().String(), k.Path().String()) } func (tp *TestSuite) TestRenameSameNameNoForce(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() + api, err := tp.makeAPI(t, ctx) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) _, err = api.Key().Generate(ctx, "foo") - if err != nil { - t.Fatal(err) - return - } + require.NoError(t, err) k, overwrote, err := api.Key().Rename(ctx, "foo", "foo") - if err != nil { - t.Fatal(err) - return - } - - if overwrote { - t.Error("overwrote should be false") - } - - if k.Name() != "foo" { - t.Errorf("returned key should be called 'foo', got '%s'", k.Name()) - } + require.NoError(t, err) + assert.False(t, overwrote) + assert.Equal(t, "foo", k.Name()) } func (tp *TestSuite) TestRenameSameName(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() + api, err := tp.makeAPI(t, ctx) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) _, err = api.Key().Generate(ctx, "foo") - if err != nil { - t.Fatal(err) - return - } + require.NoError(t, err) k, overwrote, err := api.Key().Rename(ctx, "foo", "foo", opt.Key.Force(true)) - if err != nil { - t.Fatal(err) - return - } - - if overwrote { - t.Error("overwrote should be false") - } - - if k.Name() != "foo" { - t.Errorf("returned key should be called 'foo', got '%s'", k.Name()) - } + require.NoError(t, err) + assert.False(t, overwrote) + assert.Equal(t, "foo", k.Name()) } func (tp *TestSuite) TestRemove(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() + api, err := tp.makeAPI(t, ctx) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) k, err := api.Key().Generate(ctx, "foo") - if err != nil { - t.Fatal(err) - return - } + require.NoError(t, err) l, err := api.Key().List(ctx) - if err != nil { - t.Fatal(err) - return - } - - if len(l) != 2 { - t.Fatalf("expected to get 2 keys, got %d", len(l)) - return - } + require.NoError(t, err) + require.Len(t, l, 2) p, err := api.Key().Remove(ctx, "foo") - if err != nil { - t.Fatal(err) - return - } - - if k.Path().String() != p.Path().String() { - t.Errorf("k and p should have equal paths, '%s'!='%s'", k.Path().String(), p.Path().String()) - } + require.NoError(t, err) + assert.Equal(t, p.Path().String(), k.Path().String()) l, err = api.Key().List(ctx) - if err != nil { - t.Fatal(err) - return - } - - if len(l) != 1 { - t.Fatalf("expected to get 1 key, got %d", len(l)) - return - } - - if l[0].Name() != "self" { - t.Errorf("expected the key to be called 'self', got '%s'", l[0].Name()) - } + require.NoError(t, err) + require.Len(t, l, 1) + assert.Equal(t, "self", l[0].Name()) +} + +func (tp *TestSuite) TestSign(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + api, err := tp.makeAPI(t, ctx) + require.NoError(t, err) + + key1, err := api.Key().Generate(ctx, "foo", opt.Key.Type(opt.Ed25519Key)) + require.NoError(t, err) + + data := []byte("hello world") + + key2, signature, err := api.Key().Sign(ctx, "foo", data) + require.NoError(t, err) + + require.Equal(t, key1.Name(), key2.Name()) + require.Equal(t, key1.ID(), key2.ID()) + + pk, err := key1.ID().ExtractPublicKey() + require.NoError(t, err) + + valid, err := pk.Verify(append([]byte("libp2p-key signed message:"), data...), signature) + require.NoError(t, err) + require.True(t, valid) +} + +func (tp *TestSuite) TestVerify(t *testing.T) { + t.Parallel() + + t.Run("Verify Own Key", func(t *testing.T) { + t.Parallel() + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + api, err := tp.makeAPI(t, ctx) + require.NoError(t, err) + + _, err = api.Key().Generate(ctx, "foo", opt.Key.Type(opt.Ed25519Key)) + require.NoError(t, err) + + data := []byte("hello world") + + _, signature, err := api.Key().Sign(ctx, "foo", data) + require.NoError(t, err) + + _, valid, err := api.Key().Verify(ctx, "foo", signature, data) + require.NoError(t, err) + require.True(t, valid) + }) + + t.Run("Verify Self", func(t *testing.T) { + t.Parallel() + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + api, err := tp.makeAPIWithIdentityAndOffline(t, ctx) + require.NoError(t, err) + + data := []byte("hello world") + + _, signature, err := api.Key().Sign(ctx, "", data) + require.NoError(t, err) + + _, valid, err := api.Key().Verify(ctx, "", signature, data) + require.NoError(t, err) + require.True(t, valid) + }) + + t.Run("Verify With Key In Different Formats", func(t *testing.T) { + t.Parallel() + + // Spin some node and get signature out. + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + api, err := tp.makeAPI(t, ctx) + require.NoError(t, err) + + key, err := api.Key().Generate(ctx, "foo", opt.Key.Type(opt.Ed25519Key)) + require.NoError(t, err) + + data := []byte("hello world") + + _, signature, err := api.Key().Sign(ctx, "foo", data) + require.NoError(t, err) + + for _, testCase := range [][]string{ + {"Base58 Encoded Peer ID", key.ID().String()}, + {"CIDv1 Encoded Peer ID", peer.ToCid(key.ID()).String()}, + {"CIDv1 Encoded IPNS Name", ipns.NameFromPeer(key.ID()).String()}, + {"Prefixed IPNS Path", ipns.NameFromPeer(key.ID()).AsPath().String()}, + } { + t.Run(testCase[0], func(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + // Spin new node. + api, err := tp.makeAPI(t, ctx) + require.NoError(t, err) + + _, valid, err := api.Key().Verify(ctx, testCase[1], signature, data) + require.NoError(t, err) + require.True(t, valid) + }) + } + }) } diff --git a/docs/changelogs/v0.25.md b/docs/changelogs/v0.25.md index ed8275f2f..059e437b2 100644 --- a/docs/changelogs/v0.25.md +++ b/docs/changelogs/v0.25.md @@ -10,6 +10,7 @@ - [RPC `API.Authorizations`](#rpc-apiauthorizations) - [MPLEX Removal](#mplex-removal) - [Graphsync Experiment Removal](#graphsync-experiment-removal) + - [Commands `ipfs key sign` and `ipfs key verify`](#commands-ipfs-key-sign-and-ipfs-key-verify) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -55,6 +56,14 @@ to update Kubo because some dependency changed and it fails to build anymore. For more information see https://github.com/ipfs/kubo/pull/9747. +##### Commands `ipfs key sign` and `ipfs key verify` + +This allows the Kubo node to sign arbitrary bytes to prove ownership of a PeerID or an IPNS Name. To avoid signature reuse, the signed payload is always prefixed with `libp2p-key signed message:`. + +These commands are also both available through the RPC client and implemented in `client/rpc`. + +For more information see https://github.com/ipfs/kubo/issues/10230. + ### 📝 Changelog ### 👨‍👩‍👧‍👦 Contributors From d6d79ce45fa8362b4cb882d2690ebee58d43dbb1 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Wed, 6 Dec 2023 10:48:14 +0100 Subject: [PATCH 0955/1212] chore: bump to boxo 0.16.0 --- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- test/dependencies/go.mod | 2 +- test/dependencies/go.sum | 4 ++-- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 9a39a46a1..eb12048d2 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.20 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.15.1-0.20231129112844-08959f281f86 + github.com/ipfs/boxo v0.16.0 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.32.1 github.com/multiformats/go-multiaddr v0.12.0 diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 1bcbaf5df..9ec412293 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -303,8 +303,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.15.1-0.20231129112844-08959f281f86 h1:9a7ug9Llglmdbzgj/gdKbPoZrd3EoaartzepObr/jlc= -github.com/ipfs/boxo v0.15.1-0.20231129112844-08959f281f86/go.mod h1:jAgpNQn7T7BnibUeReXcKU9Ha1xmYNyOlwVEl193ow0= +github.com/ipfs/boxo v0.16.0 h1:A9dUmef5a+mEFki6kbyG7el5gl65CiUBzrDeZxzTWKY= +github.com/ipfs/boxo v0.16.0/go.mod h1:jAgpNQn7T7BnibUeReXcKU9Ha1xmYNyOlwVEl193ow0= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= diff --git a/go.mod b/go.mod index d1514137b..cafc38a3d 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,7 @@ require ( github.com/hashicorp/go-multierror v1.1.1 github.com/ipfs-shipyard/nopfs v0.0.12-0.20231027223058-cde3b5ba964c github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c - github.com/ipfs/boxo v0.15.1-0.20231129112844-08959f281f86 + github.com/ipfs/boxo v0.16.0 github.com/ipfs/go-block-format v0.2.0 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 diff --git a/go.sum b/go.sum index bb4d9dda7..12e1e7634 100644 --- a/go.sum +++ b/go.sum @@ -337,8 +337,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.15.1-0.20231129112844-08959f281f86 h1:9a7ug9Llglmdbzgj/gdKbPoZrd3EoaartzepObr/jlc= -github.com/ipfs/boxo v0.15.1-0.20231129112844-08959f281f86/go.mod h1:jAgpNQn7T7BnibUeReXcKU9Ha1xmYNyOlwVEl193ow0= +github.com/ipfs/boxo v0.16.0 h1:A9dUmef5a+mEFki6kbyG7el5gl65CiUBzrDeZxzTWKY= +github.com/ipfs/boxo v0.16.0/go.mod h1:jAgpNQn7T7BnibUeReXcKU9Ha1xmYNyOlwVEl193ow0= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index c27e946f4..2ec1bb758 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -104,7 +104,7 @@ require ( github.com/hexops/gotextdiff v1.0.3 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/ipfs/bbloom v0.0.4 // indirect - github.com/ipfs/boxo v0.15.1-0.20231129112844-08959f281f86 // indirect + github.com/ipfs/boxo v0.16.0 // indirect github.com/ipfs/go-block-format v0.2.0 // indirect github.com/ipfs/go-cid v0.4.1 // indirect github.com/ipfs/go-datastore v0.6.0 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 918fda6f5..ec2426722 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -344,8 +344,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.15.1-0.20231129112844-08959f281f86 h1:9a7ug9Llglmdbzgj/gdKbPoZrd3EoaartzepObr/jlc= -github.com/ipfs/boxo v0.15.1-0.20231129112844-08959f281f86/go.mod h1:jAgpNQn7T7BnibUeReXcKU9Ha1xmYNyOlwVEl193ow0= +github.com/ipfs/boxo v0.16.0 h1:A9dUmef5a+mEFki6kbyG7el5gl65CiUBzrDeZxzTWKY= +github.com/ipfs/boxo v0.16.0/go.mod h1:jAgpNQn7T7BnibUeReXcKU9Ha1xmYNyOlwVEl193ow0= github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs= github.com/ipfs/go-block-format v0.2.0/go.mod h1:+jpL11nFx5A/SPpsoBn6Bzkra/zaArfSmsknbPMYgzM= github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= From 48e379a748e65ed383b86b8606d1f9f966cdb4f5 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Wed, 6 Dec 2023 11:16:49 +0100 Subject: [PATCH 0956/1212] chore: update dependencies --- docs/examples/kubo-as-a-library/go.mod | 34 ++++++------ docs/examples/kubo-as-a-library/go.sum | 69 ++++++++++++----------- go.mod | 38 ++++++------- go.sum | 77 +++++++++++++------------- test/dependencies/go.mod | 37 ++++++------- test/dependencies/go.sum | 75 ++++++++++++------------- 6 files changed, 162 insertions(+), 168 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index eb12048d2..3d46b2ef7 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -43,7 +43,7 @@ require ( github.com/francoispqt/gojay v1.2.13 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/gabriel-vasile/mimetype v1.4.1 // indirect - github.com/go-logr/logr v1.2.4 // indirect + github.com/go-logr/logr v1.3.0 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/godbus/dbus/v5 v5.1.0 // indirect @@ -52,12 +52,12 @@ require ( github.com/golang/snappy v0.0.4 // indirect github.com/google/gopacket v1.1.19 // indirect github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b // indirect - github.com/google/uuid v1.3.1 // indirect + github.com/google/uuid v1.4.0 // indirect github.com/gorilla/websocket v1.5.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect - github.com/hashicorp/golang-lru v0.5.4 // indirect + github.com/hashicorp/golang-lru v1.0.2 // indirect github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/huin/goupnp v1.3.0 // indirect github.com/ipfs-shipyard/nopfs v0.0.12-0.20231027223058-cde3b5ba964c // indirect @@ -94,7 +94,7 @@ require ( github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect github.com/jbenet/goprocess v0.1.4 // indirect github.com/klauspost/compress v1.17.2 // indirect - github.com/klauspost/cpuid/v2 v2.2.5 // indirect + github.com/klauspost/cpuid/v2 v2.2.6 // indirect github.com/koron/go-ssdp v0.0.4 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/libp2p/go-cidranger v1.1.0 // indirect @@ -116,8 +116,8 @@ require ( github.com/libp2p/zeroconf/v2 v2.2.0 // indirect github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect - github.com/miekg/dns v1.1.56 // indirect + github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect + github.com/miekg/dns v1.1.57 // indirect github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect github.com/minio/sha256-simd v1.0.1 // indirect @@ -159,14 +159,14 @@ require ( github.com/polydawn/refmt v0.89.0 // indirect github.com/prometheus/client_golang v1.17.0 // indirect github.com/prometheus/client_model v0.5.0 // indirect - github.com/prometheus/common v0.44.0 // indirect + github.com/prometheus/common v0.45.0 // indirect github.com/prometheus/procfs v0.12.0 // indirect github.com/quic-go/qpack v0.4.0 // indirect github.com/quic-go/qtls-go1-20 v0.3.4 // indirect github.com/quic-go/quic-go v0.39.3 // indirect github.com/quic-go/webtransport-go v0.6.0 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect - github.com/samber/lo v1.36.0 // indirect + github.com/samber/lo v1.39.0 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/stretchr/testify v1.8.4 // indirect github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect @@ -196,16 +196,16 @@ require ( go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.26.0 // indirect go4.org v0.0.0-20230225012048-214862532bf5 // indirect - golang.org/x/crypto v0.14.0 // indirect - golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect - golang.org/x/mod v0.13.0 // indirect - golang.org/x/net v0.17.0 // indirect - golang.org/x/sync v0.4.0 // indirect - golang.org/x/sys v0.13.0 // indirect - golang.org/x/text v0.13.0 // indirect - golang.org/x/tools v0.14.0 // indirect + golang.org/x/crypto v0.16.0 // indirect + golang.org/x/exp v0.0.0-20231127185646-65229373498e // indirect + golang.org/x/mod v0.14.0 // indirect + golang.org/x/net v0.19.0 // indirect + golang.org/x/sync v0.5.0 // indirect + golang.org/x/sys v0.15.0 // indirect + golang.org/x/text v0.14.0 // indirect + golang.org/x/tools v0.16.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect - gonum.org/v1/gonum v0.13.0 // indirect + gonum.org/v1/gonum v0.14.0 // indirect google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect google.golang.org/grpc v1.55.0 // indirect google.golang.org/protobuf v1.31.0 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 9ec412293..0216b2681 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -174,8 +174,8 @@ github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= -github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY= +github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= @@ -262,8 +262,8 @@ github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm4 github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= -github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= +github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= @@ -287,8 +287,8 @@ github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+l github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= -github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c= +github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= @@ -426,8 +426,8 @@ github.com/klauspost/compress v1.17.2 h1:RlWWUY/Dr4fL8qk9YG7DTZ7PDgME2V4csBXA8L/ github.com/klauspost/compress v1.17.2/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= -github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/48xc= +github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/koron/go-ssdp v0.0.4 h1:1IDwrghSKYM7yLf7XCzbByg2sJ/JcNOZRXS2jczTwz0= github.com/koron/go-ssdp v0.0.4/go.mod h1:oDXq+E5IL5q0U8uSBcoAXzTzInwy5lEgC91HoKtbmZk= @@ -506,14 +506,14 @@ github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27k github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= -github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg= +github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k= github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= -github.com/miekg/dns v1.1.56 h1:5imZaSeoRNvpM9SzWNhEcP9QliKiz20/dA2QabIGVnE= -github.com/miekg/dns v1.1.56/go.mod h1:cRm6Oo2C8TY9ZS/TqsSrseAcncm74lfK5G+ikN2SWWY= +github.com/miekg/dns v1.1.57 h1:Jzi7ApEIzwEPLHWRcafCN9LZSBbqQpxjt/wpgvg7wcM= +github.com/miekg/dns v1.1.57/go.mod h1:uqRjCRUuEAA6qsOiJvDd+CFo/vW+y5WR6SNmHE55hZk= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c h1:bzE/A84HN25pxAuk9Eej1Kz9OUelF97nAc82bDquQI8= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c/go.mod h1:0SQS9kMwD2VsyFEB++InYyBJroV/FRmBgcydeSUcJms= github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= @@ -667,8 +667,8 @@ github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1: github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY= -github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= +github.com/prometheus/common v0.45.0 h1:2BGz0eBc2hdMDLnO/8n0jeB3oPrt2D08CekT0lneoxM= +github.com/prometheus/common v0.45.0/go.mod h1:YJmSTw9BoKxJplESWWxlbyttQR4uaEcGyv9MZjVOJsY= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= @@ -689,8 +689,8 @@ github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjR github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd/go.mod h1:hPqNNc0+uJM6H+SuU8sEs5K5IQeKccPqeSjfgcKGgPk= -github.com/samber/lo v1.36.0 h1:4LaOxH1mHnbDGhTVE0i1z8v/lWaQW8AIfOD3HU4mSaw= -github.com/samber/lo v1.36.0/go.mod h1:HLeWcJRRyLKp3+/XBJvOrerCQn9mhdKMHyd7IRlgeQ8= +github.com/samber/lo v1.39.0 h1:4gTz1wUhNYLhFSKl6O+8peW0v2F4BCY034GRpU9WnuA= +github.com/samber/lo v1.39.0/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA= github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY= @@ -761,7 +761,6 @@ github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpP github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= -github.com/thoas/go-funk v0.9.1 h1:O549iLZqPpTUQ10ykd26sZhzD+rmR5pWhuElrhbC20M= github.com/tj/assert v0.0.3 h1:Df/BlaZ20mq6kuai7f5z2TvPFiwC3xaWJSDQNiIS3Rk= github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c h1:u6SKchux2yDvFQnDHS3lPnIRmfVJ5Sxy3ao2SIdysLQ= github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM= @@ -883,8 +882,8 @@ golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= -golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= -golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= +golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY= +golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -895,8 +894,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI= -golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo= +golang.org/x/exp v0.0.0-20231127185646-65229373498e h1:Gvh4YaCaXNs6dKTlfgismwWZKyjVZXwOPfIyUaqU3No= +golang.org/x/exp v0.0.0-20231127185646-65229373498e/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -921,8 +920,8 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY= -golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= +golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -972,8 +971,8 @@ golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= -golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= +golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -995,8 +994,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ= -golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= +golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/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= @@ -1062,8 +1061,8 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= +golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -1086,8 +1085,8 @@ golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1146,16 +1145,16 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc= -golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= +golang.org/x/tools v0.16.0 h1:GO788SKMRunPIBCXiQyo2AaexLstOrVhuAL5YwsckQM= +golang.org/x/tools v0.16.0/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= -gonum.org/v1/gonum v0.13.0 h1:a0T3bh+7fhRyqeNbiC3qVHYmkiQgit3wnNan/2c0HMM= -gonum.org/v1/gonum v0.13.0/go.mod h1:/WPYRckkfWrhWefxyYTfrTtQR0KH4iyHNuzxqXAKyAU= +gonum.org/v1/gonum v0.14.0 h1:2NiG67LD1tEH0D7kM+ps2V+fXmsAnpUeec7n8tcr4S0= +gonum.org/v1/gonum v0.14.0/go.mod h1:AoWeoz0becf9QMWtE8iWXNXc27fK4fNeHNf/oMejGfU= google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y= diff --git a/go.mod b/go.mod index cafc38a3d..eb50dde80 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( github.com/elgris/jsondiff v0.0.0-20160530203242-765b5c24c302 github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5 github.com/fsnotify/fsnotify v1.6.0 - github.com/google/uuid v1.3.1 + github.com/google/uuid v1.4.0 github.com/hashicorp/go-multierror v1.1.1 github.com/ipfs-shipyard/nopfs v0.0.12-0.20231027223058-cde3b5ba964c github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c @@ -83,11 +83,11 @@ require ( go.uber.org/fx v1.20.1 go.uber.org/multierr v1.11.0 go.uber.org/zap v1.26.0 - golang.org/x/crypto v0.14.0 - golang.org/x/exp v0.0.0-20231006140011-7918f672742d - golang.org/x/mod v0.13.0 - golang.org/x/sync v0.4.0 - golang.org/x/sys v0.13.0 + golang.org/x/crypto v0.16.0 + golang.org/x/exp v0.0.0-20231127185646-65229373498e + golang.org/x/mod v0.14.0 + golang.org/x/sync v0.5.0 + golang.org/x/sys v0.15.0 google.golang.org/protobuf v1.31.0 ) @@ -115,7 +115,7 @@ require ( github.com/gabriel-vasile/mimetype v1.4.1 // indirect github.com/go-kit/log v0.2.1 // indirect github.com/go-logfmt/logfmt v0.5.1 // indirect - github.com/go-logr/logr v1.2.4 // indirect + github.com/go-logr/logr v1.3.0 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/godbus/dbus/v5 v5.1.0 // indirect @@ -129,7 +129,7 @@ require ( github.com/gorilla/websocket v1.5.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect - github.com/hashicorp/golang-lru v0.5.4 // indirect + github.com/hashicorp/golang-lru v1.0.2 // indirect github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/huin/goupnp v1.3.0 // indirect github.com/ipfs/bbloom v0.0.4 // indirect @@ -147,7 +147,7 @@ require ( github.com/ipfs/go-verifcid v0.0.2 // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/klauspost/compress v1.17.2 // indirect - github.com/klauspost/cpuid/v2 v2.2.5 // indirect + github.com/klauspost/cpuid/v2 v2.2.6 // indirect github.com/koron/go-ssdp v0.0.4 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/libp2p/go-cidranger v1.1.0 // indirect @@ -165,9 +165,9 @@ require ( github.com/mattn/go-colorable v0.1.6 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-runewidth v0.0.4 // indirect - github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect + github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect - github.com/miekg/dns v1.1.56 // indirect + github.com/miekg/dns v1.1.57 // indirect github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect github.com/minio/sha256-simd v1.0.1 // indirect @@ -200,7 +200,7 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect github.com/polydawn/refmt v0.89.0 // indirect github.com/prometheus/client_model v0.5.0 // indirect - github.com/prometheus/common v0.44.0 // indirect + github.com/prometheus/common v0.45.0 // indirect github.com/prometheus/procfs v0.12.0 // indirect github.com/prometheus/statsd_exporter v0.22.7 // indirect github.com/quic-go/qpack v0.4.0 // indirect @@ -209,7 +209,7 @@ require ( github.com/quic-go/webtransport-go v0.6.0 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/rs/cors v1.7.0 // indirect - github.com/samber/lo v1.36.0 // indirect + github.com/samber/lo v1.39.0 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/texttheater/golang-levenshtein v0.0.0-20180516184445-d188e65d659e // indirect github.com/tidwall/match v1.1.1 // indirect @@ -236,13 +236,13 @@ require ( go.uber.org/atomic v1.11.0 // indirect go.uber.org/mock v0.3.0 // indirect go4.org v0.0.0-20230225012048-214862532bf5 // indirect - golang.org/x/net v0.17.0 // indirect - golang.org/x/oauth2 v0.8.0 // indirect - golang.org/x/term v0.13.0 // indirect - golang.org/x/text v0.13.0 // indirect - golang.org/x/tools v0.14.0 // indirect + golang.org/x/net v0.19.0 // indirect + golang.org/x/oauth2 v0.12.0 // indirect + golang.org/x/term v0.15.0 // indirect + golang.org/x/text v0.14.0 // indirect + golang.org/x/tools v0.16.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect - gonum.org/v1/gonum v0.13.0 // indirect + gonum.org/v1/gonum v0.14.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect google.golang.org/grpc v1.55.0 // indirect diff --git a/go.sum b/go.sum index 12e1e7634..66d5d38d9 100644 --- a/go.sum +++ b/go.sum @@ -203,8 +203,8 @@ github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA= github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= -github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY= +github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= @@ -295,8 +295,8 @@ github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm4 github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= -github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= +github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= @@ -321,8 +321,8 @@ github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+l github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= -github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c= +github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= @@ -482,8 +482,8 @@ github.com/klauspost/compress v1.17.2 h1:RlWWUY/Dr4fL8qk9YG7DTZ7PDgME2V4csBXA8L/ github.com/klauspost/compress v1.17.2/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= -github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/48xc= +github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/koron/go-ssdp v0.0.4 h1:1IDwrghSKYM7yLf7XCzbByg2sJ/JcNOZRXS2jczTwz0= @@ -579,15 +579,15 @@ github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D 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= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= -github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg= +github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k= github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4= github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= -github.com/miekg/dns v1.1.56 h1:5imZaSeoRNvpM9SzWNhEcP9QliKiz20/dA2QabIGVnE= -github.com/miekg/dns v1.1.56/go.mod h1:cRm6Oo2C8TY9ZS/TqsSrseAcncm74lfK5G+ikN2SWWY= +github.com/miekg/dns v1.1.57 h1:Jzi7ApEIzwEPLHWRcafCN9LZSBbqQpxjt/wpgvg7wcM= +github.com/miekg/dns v1.1.57/go.mod h1:uqRjCRUuEAA6qsOiJvDd+CFo/vW+y5WR6SNmHE55hZk= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c h1:bzE/A84HN25pxAuk9Eej1Kz9OUelF97nAc82bDquQI8= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c/go.mod h1:0SQS9kMwD2VsyFEB++InYyBJroV/FRmBgcydeSUcJms= github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= @@ -765,8 +765,8 @@ github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9 github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/common v0.35.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= -github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY= -github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= +github.com/prometheus/common v0.45.0 h1:2BGz0eBc2hdMDLnO/8n0jeB3oPrt2D08CekT0lneoxM= +github.com/prometheus/common v0.45.0/go.mod h1:YJmSTw9BoKxJplESWWxlbyttQR4uaEcGyv9MZjVOJsY= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= @@ -798,8 +798,8 @@ github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd/go.mod h1:hPqNNc0+uJM6H+SuU8sEs5K5IQeKccPqeSjfgcKGgPk= -github.com/samber/lo v1.36.0 h1:4LaOxH1mHnbDGhTVE0i1z8v/lWaQW8AIfOD3HU4mSaw= -github.com/samber/lo v1.36.0/go.mod h1:HLeWcJRRyLKp3+/XBJvOrerCQn9mhdKMHyd7IRlgeQ8= +github.com/samber/lo v1.39.0 h1:4gTz1wUhNYLhFSKl6O+8peW0v2F4BCY034GRpU9WnuA= +github.com/samber/lo v1.39.0/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA= github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY= @@ -875,7 +875,6 @@ github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45 github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= github.com/texttheater/golang-levenshtein v0.0.0-20180516184445-d188e65d659e h1:T5PdfK/M1xyrHwynxMIVMWLS7f/qHwfslZphxtGnw7s= github.com/texttheater/golang-levenshtein v0.0.0-20180516184445-d188e65d659e/go.mod h1:XDKHRm5ThF8YJjx001LtgelzsoaEcvnA7lVWz9EeX3g= -github.com/thoas/go-funk v0.9.1 h1:O549iLZqPpTUQ10ykd26sZhzD+rmR5pWhuElrhbC20M= github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/gjson v1.14.4 h1:uo0p8EbA09J7RQaflQ1aBRffTR7xedD2bcIVSYxLnkM= github.com/tidwall/gjson v1.14.4/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= @@ -1022,8 +1021,8 @@ golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= -golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= -golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= +golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY= +golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1034,8 +1033,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI= -golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo= +golang.org/x/exp v0.0.0-20231127185646-65229373498e h1:Gvh4YaCaXNs6dKTlfgismwWZKyjVZXwOPfIyUaqU3No= +golang.org/x/exp v0.0.0-20231127185646-65229373498e/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1060,8 +1059,8 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY= -golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= +golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1117,8 +1116,8 @@ golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= -golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= +golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1129,8 +1128,8 @@ golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4Iltr golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.8.0 h1:6dkIjl3j3LtZ/O3sTgZTMsLKSftL/B8Zgq4huOIIUu8= -golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE= +golang.org/x/oauth2 v0.12.0 h1:smVPGxink+n1ZI5pkQa8y6fZT0RW0MgCO5bFpepy4B4= +golang.org/x/oauth2 v0.12.0/go.mod h1:A74bZ3aGXgCY0qaIC9Ahg6Lglin4AMAco8cIv9baba4= golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1146,8 +1145,8 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ= -golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= +golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/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= @@ -1223,8 +1222,8 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= +golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -1234,8 +1233,8 @@ golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= -golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= -golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= +golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4= +golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1249,8 +1248,8 @@ golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1309,16 +1308,16 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc= -golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= +golang.org/x/tools v0.16.0 h1:GO788SKMRunPIBCXiQyo2AaexLstOrVhuAL5YwsckQM= +golang.org/x/tools v0.16.0/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= -gonum.org/v1/gonum v0.13.0 h1:a0T3bh+7fhRyqeNbiC3qVHYmkiQgit3wnNan/2c0HMM= -gonum.org/v1/gonum v0.13.0/go.mod h1:/WPYRckkfWrhWefxyYTfrTtQR0KH4iyHNuzxqXAKyAU= +gonum.org/v1/gonum v0.14.0 h1:2NiG67LD1tEH0D7kM+ps2V+fXmsAnpUeec7n8tcr4S0= +gonum.org/v1/gonum v0.14.0/go.mod h1:AoWeoz0becf9QMWtE8iWXNXc27fK4fNeHNf/oMejGfU= google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 2ec1bb758..e7ec1b90f 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -63,7 +63,7 @@ require ( github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/fzipp/gocyclo v0.6.0 // indirect github.com/go-critic/go-critic v0.9.0 // indirect - github.com/go-logr/logr v1.2.4 // indirect + github.com/go-logr/logr v1.3.0 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-toolsmith/astcast v1.1.0 // indirect github.com/go-toolsmith/astcopy v1.1.0 // indirect @@ -76,7 +76,6 @@ require ( github.com/gobwas/glob v0.2.3 // indirect github.com/gofrs/flock v0.8.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang/protobuf v1.5.3 // indirect github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2 // indirect github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a // indirect github.com/golangci/go-misc v0.0.0-20220329215616-d24fe342adfe // indirect @@ -88,7 +87,7 @@ require ( github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4 // indirect github.com/google/go-cmp v0.5.9 // indirect github.com/google/gopacket v1.1.19 // indirect - github.com/google/uuid v1.3.1 // indirect + github.com/google/uuid v1.4.0 // indirect github.com/gordonklaus/ineffassign v0.0.0-20230610083614-0e73809eb601 // indirect github.com/gostaticanalysis/analysisutil v0.7.1 // indirect github.com/gostaticanalysis/comment v1.4.2 // indirect @@ -98,7 +97,7 @@ require ( github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-version v1.6.0 // indirect - github.com/hashicorp/golang-lru v0.5.4 // indirect + github.com/hashicorp/golang-lru v1.0.2 // indirect github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/hexops/gotextdiff v1.0.3 // indirect @@ -125,7 +124,7 @@ require ( github.com/kisielk/errcheck v1.6.3 // indirect github.com/kisielk/gotool v1.0.0 // indirect github.com/kkHAIKE/contextcheck v1.1.4 // indirect - github.com/klauspost/cpuid/v2 v2.2.5 // indirect + github.com/klauspost/cpuid/v2 v2.2.6 // indirect github.com/kulti/thelper v0.6.3 // indirect github.com/kunwardeep/paralleltest v1.0.8 // indirect github.com/kyoh86/exportloopref v0.1.11 // indirect @@ -150,10 +149,10 @@ require ( github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-runewidth v0.0.9 // indirect - github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect + github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect github.com/mbilski/exhaustivestruct v1.2.0 // indirect github.com/mgechev/revive v1.3.2 // indirect - github.com/miekg/dns v1.1.56 // indirect + github.com/miekg/dns v1.1.57 // indirect github.com/minio/sha256-simd v1.0.1 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect @@ -182,7 +181,7 @@ require ( github.com/polyfloyd/go-errorlint v1.4.3 // indirect github.com/prometheus/client_golang v1.17.0 // indirect github.com/prometheus/client_model v0.5.0 // indirect - github.com/prometheus/common v0.44.0 // indirect + github.com/prometheus/common v0.45.0 // indirect github.com/prometheus/procfs v0.12.0 // indirect github.com/quasilyte/go-ruleguard v0.4.0 // indirect github.com/quasilyte/gogrep v0.5.0 // indirect @@ -191,7 +190,7 @@ require ( github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/ryancurrah/gomodguard v1.3.0 // indirect github.com/ryanrolds/sqlclosecheck v0.4.0 // indirect - github.com/samber/lo v1.36.0 // indirect + github.com/samber/lo v1.39.0 // indirect github.com/sanposhiho/wastedassign/v2 v2.0.7 // indirect github.com/sashamelentyev/interfacebloat v1.1.0 // indirect github.com/sashamelentyev/usestdlibvars v1.23.0 // indirect @@ -240,17 +239,17 @@ require ( go.tmz.dev/musttag v0.7.1 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.26.0 // indirect - golang.org/x/crypto v0.14.0 // indirect - golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect + golang.org/x/crypto v0.16.0 // indirect + golang.org/x/exp v0.0.0-20231127185646-65229373498e // indirect golang.org/x/exp/typeparams v0.0.0-20230307190834-24139beb5833 // indirect - golang.org/x/mod v0.13.0 // indirect - golang.org/x/net v0.17.0 // indirect - golang.org/x/sync v0.4.0 // indirect - golang.org/x/sys v0.13.0 // indirect - golang.org/x/term v0.13.0 // indirect - golang.org/x/text v0.13.0 // indirect - golang.org/x/tools v0.14.0 // indirect - gonum.org/v1/gonum v0.13.0 // indirect + golang.org/x/mod v0.14.0 // indirect + golang.org/x/net v0.19.0 // indirect + golang.org/x/sync v0.5.0 // indirect + golang.org/x/sys v0.15.0 // indirect + golang.org/x/term v0.15.0 // indirect + golang.org/x/text v0.14.0 // indirect + golang.org/x/tools v0.16.0 // indirect + gonum.org/v1/gonum v0.14.0 // indirect google.golang.org/protobuf v1.31.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index ec2426722..9e5c96d46 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -175,8 +175,8 @@ github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9 github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= -github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY= +github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= @@ -237,8 +237,6 @@ github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2 h1:23T5iq8rbUYlhpt5DB4XJkc6BU31uODLD1o1gKvZmD0= github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2/go.mod h1:k9Qvh+8juN+UKMCS/3jFtGICgW8O96FVaZsaxdzDkR4= github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a h1:w8hkcTqaFpzKqonE9uMCefW1WDie15eSP/4MssdenaM= @@ -295,8 +293,8 @@ github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b h1:RMpPgZTSApbPf7xaVel+QkoGPRLFLrwFO89uDUHEGf0= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= -github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= +github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= @@ -328,8 +326,8 @@ github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mO github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= -github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c= +github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= @@ -422,8 +420,8 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o github.com/kkHAIKE/contextcheck v1.1.4 h1:B6zAaLhOEEcjvUgIYEqystmnFk1Oemn8bvJhbt0GMb8= github.com/kkHAIKE/contextcheck v1.1.4/go.mod h1:1+i/gWqokIa+dm31mqGLZhZJ7Uh44DJGZVmr6QRBNJg= github.com/klauspost/compress v1.17.2 h1:RlWWUY/Dr4fL8qk9YG7DTZ7PDgME2V4csBXA8L/ixi4= -github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= -github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/48xc= +github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/koron/go-ssdp v0.0.4 h1:1IDwrghSKYM7yLf7XCzbByg2sJ/JcNOZRXS2jczTwz0= @@ -495,15 +493,15 @@ github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= -github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg= +github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k= github.com/mbilski/exhaustivestruct v1.2.0 h1:wCBmUnSYufAHO6J4AVWY6ff+oxWxsVFrwgOdMUQePUo= github.com/mbilski/exhaustivestruct v1.2.0/go.mod h1:OeTBVxQWoEmB2J2JCHmXWPJ0aksxSUOUy+nvtVEfzXc= github.com/mgechev/revive v1.3.2 h1:Wb8NQKBaALBJ3xrrj4zpwJwqwNA6nDpyJSEQWcCka6U= github.com/mgechev/revive v1.3.2/go.mod h1:UCLtc7o5vg5aXCwdUTU1kEBQ1v+YXPAkYDIDXbrs5I0= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= -github.com/miekg/dns v1.1.56 h1:5imZaSeoRNvpM9SzWNhEcP9QliKiz20/dA2QabIGVnE= -github.com/miekg/dns v1.1.56/go.mod h1:cRm6Oo2C8TY9ZS/TqsSrseAcncm74lfK5G+ikN2SWWY= +github.com/miekg/dns v1.1.57 h1:Jzi7ApEIzwEPLHWRcafCN9LZSBbqQpxjt/wpgvg7wcM= +github.com/miekg/dns v1.1.57/go.mod h1:uqRjCRUuEAA6qsOiJvDd+CFo/vW+y5WR6SNmHE55hZk= github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc h1:PTfri+PuQmWDqERdnNMiD9ZejrlswWrCpBEZgWOiTrc= github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= @@ -609,8 +607,8 @@ github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8 github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= -github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY= -github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= +github.com/prometheus/common v0.45.0 h1:2BGz0eBc2hdMDLnO/8n0jeB3oPrt2D08CekT0lneoxM= +github.com/prometheus/common v0.45.0/go.mod h1:YJmSTw9BoKxJplESWWxlbyttQR4uaEcGyv9MZjVOJsY= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= @@ -640,8 +638,8 @@ github.com/ryancurrah/gomodguard v1.3.0 h1:q15RT/pd6UggBXVBuLps8BXRvl5GPBcwVA7BJ github.com/ryancurrah/gomodguard v1.3.0/go.mod h1:ggBxb3luypPEzqVtq33ee7YSN35V28XeGnid8dnni50= github.com/ryanrolds/sqlclosecheck v0.4.0 h1:i8SX60Rppc1wRuyQjMciLqIzV3xnoHB7/tXbr6RGYNI= github.com/ryanrolds/sqlclosecheck v0.4.0/go.mod h1:TBRRjzL31JONc9i4XMinicuo+s+E8yKZ5FN8X3G6CKQ= -github.com/samber/lo v1.36.0 h1:4LaOxH1mHnbDGhTVE0i1z8v/lWaQW8AIfOD3HU4mSaw= -github.com/samber/lo v1.36.0/go.mod h1:HLeWcJRRyLKp3+/XBJvOrerCQn9mhdKMHyd7IRlgeQ8= +github.com/samber/lo v1.39.0 h1:4gTz1wUhNYLhFSKl6O+8peW0v2F4BCY034GRpU9WnuA= +github.com/samber/lo v1.39.0/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA= github.com/sanposhiho/wastedassign/v2 v2.0.7 h1:J+6nrY4VW+gC9xFzUc+XjPD3g3wF3je/NsJFwFK7Uxc= github.com/sanposhiho/wastedassign/v2 v2.0.7/go.mod h1:KyZ0MWTwxxBmfwn33zh3k1dmsbF2ud9pAAGfoLfjhtI= github.com/sashamelentyev/interfacebloat v1.1.0 h1:xdRdJp0irL086OyW1H/RTZTr1h/tMEOsumirXcOJqAw= @@ -723,7 +721,6 @@ github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3 h1:f+jULpR github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3/go.mod h1:ON8b8w4BN/kE1EOhwT0o+d62W65a6aPw1nouo9LMgyY= github.com/tetafro/godot v1.4.11 h1:BVoBIqAf/2QdbFmSwAWnaIqDivZdOV0ZRwEm6jivLKw= github.com/tetafro/godot v1.4.11/go.mod h1:LR3CJpxDVGlYOWn3ZZg1PgNZdTUvzsZWu8xaEohUpn8= -github.com/thoas/go-funk v0.9.1 h1:O549iLZqPpTUQ10ykd26sZhzD+rmR5pWhuElrhbC20M= github.com/timakin/bodyclose v0.0.0-20230421092635-574207250966 h1:quvGphlmUVU+nhpFa4gg4yJyTRJ13reZMDHrKwYw53M= github.com/timakin/bodyclose v0.0.0-20230421092635-574207250966/go.mod h1:27bSVNWSBOHm+qRp1T9qzaIpsWEP6TbUnei/43HK+PQ= github.com/timonwong/loggercheck v0.9.4 h1:HKKhqrjcVj8sxL7K77beXh0adEm6DLjV/QOGeMXEVi4= @@ -809,8 +806,8 @@ golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= -golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= -golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= +golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY= +golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -821,8 +818,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI= -golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo= +golang.org/x/exp v0.0.0-20231127185646-65229373498e h1:Gvh4YaCaXNs6dKTlfgismwWZKyjVZXwOPfIyUaqU3No= +golang.org/x/exp v0.0.0-20231127185646-65229373498e/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI= golang.org/x/exp/typeparams v0.0.0-20220428152302-39d4317da171/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/exp/typeparams v0.0.0-20230203172020-98cc5a0785f9/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/exp/typeparams v0.0.0-20230307190834-24139beb5833 h1:jWGQJV4niP+CCmFW9ekjA9Zx8vYORzOUH2/Nl5WPuLQ= @@ -857,8 +854,8 @@ golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91 golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY= -golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= +golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -902,8 +899,8 @@ golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= -golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= +golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -927,8 +924,8 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ= -golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= +golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= 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= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -991,16 +988,16 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= +golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= -golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= +golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4= +golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1012,8 +1009,8 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1091,14 +1088,14 @@ golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= golang.org/x/tools v0.5.0/go.mod h1:N+Kgy78s5I24c24dU8OfWNEotWjutIs8SnJvn5IDq+k= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc= -golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= +golang.org/x/tools v0.16.0 h1:GO788SKMRunPIBCXiQyo2AaexLstOrVhuAL5YwsckQM= +golang.org/x/tools v0.16.0/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gonum.org/v1/gonum v0.13.0 h1:a0T3bh+7fhRyqeNbiC3qVHYmkiQgit3wnNan/2c0HMM= -gonum.org/v1/gonum v0.13.0/go.mod h1:/WPYRckkfWrhWefxyYTfrTtQR0KH4iyHNuzxqXAKyAU= +gonum.org/v1/gonum v0.14.0 h1:2NiG67LD1tEH0D7kM+ps2V+fXmsAnpUeec7n8tcr4S0= +gonum.org/v1/gonum v0.14.0/go.mod h1:AoWeoz0becf9QMWtE8iWXNXc27fK4fNeHNf/oMejGfU= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= From 0c6f08c2f700596d485c00665409a8de061f2980 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Wed, 6 Dec 2023 10:38:37 +0000 Subject: [PATCH 0957/1212] chore: update version --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index 2799f0e85..30c8f12ef 100644 --- a/version.go +++ b/version.go @@ -11,7 +11,7 @@ import ( var CurrentCommit string // CurrentVersionNumber is the current application's version literal. -const CurrentVersionNumber = "0.25.0-dev" +const CurrentVersionNumber = "0.25.0-rc1" const ApiVersion = "/kubo/" + CurrentVersionNumber + "/" //nolint From 1a89365c9364fa5affeeb77e02f5eb6e3a256fad Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Wed, 6 Dec 2023 10:39:31 +0000 Subject: [PATCH 0958/1212] chore: update version --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index 2799f0e85..93f181c37 100644 --- a/version.go +++ b/version.go @@ -11,7 +11,7 @@ import ( var CurrentCommit string // CurrentVersionNumber is the current application's version literal. -const CurrentVersionNumber = "0.25.0-dev" +const CurrentVersionNumber = "0.26.0-dev" const ApiVersion = "/kubo/" + CurrentVersionNumber + "/" //nolint From 8c4bdd8556e0c8b1a4ea3a6d703402bd6cfe1229 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Mon, 11 Dec 2023 11:45:08 +0100 Subject: [PATCH 0959/1212] fix: allow daemon to start correctly if the API is null (#10062) --- cmd/ipfs/daemon.go | 7 +++++-- test/cli/daemon_test.go | 25 +++++++++++++++++++++++++ test/cli/harness/ipfs.go | 17 ++++++++++++++--- 3 files changed, 44 insertions(+), 5 deletions(-) create mode 100644 test/cli/daemon_test.go diff --git a/cmd/ipfs/daemon.go b/cmd/ipfs/daemon.go index f46dbdd8c..4ad9b629c 100644 --- a/cmd/ipfs/daemon.go +++ b/cmd/ipfs/daemon.go @@ -727,8 +727,11 @@ func serveHTTPApi(req *cmds.Request, cctx *oldcmds.Context) (<-chan error, error return nil, fmt.Errorf("serveHTTPApi: ConstructNode() failed: %s", err) } - if err := node.Repo.SetAPIAddr(rewriteMaddrToUseLocalhostIfItsAny(listeners[0].Multiaddr())); err != nil { - return nil, fmt.Errorf("serveHTTPApi: SetAPIAddr() failed: %w", err) + if len(listeners) > 0 { + // Only add an api file if the API is running. + if err := node.Repo.SetAPIAddr(rewriteMaddrToUseLocalhostIfItsAny(listeners[0].Multiaddr())); err != nil { + return nil, fmt.Errorf("serveHTTPApi: SetAPIAddr() failed: %w", err) + } } errc := make(chan error) diff --git a/test/cli/daemon_test.go b/test/cli/daemon_test.go new file mode 100644 index 000000000..7a8c583a2 --- /dev/null +++ b/test/cli/daemon_test.go @@ -0,0 +1,25 @@ +package cli + +import ( + "os/exec" + "testing" + + "github.com/ipfs/kubo/test/cli/harness" +) + +func TestDaemon(t *testing.T) { + t.Parallel() + + t.Run("daemon starts if api is set to null", func(t *testing.T) { + t.Parallel() + node := harness.NewT(t).NewNode().Init() + node.SetIPFSConfig("Addresses.API", nil) + node.Runner.MustRun(harness.RunRequest{ + Path: node.IPFSBin, + Args: []string{"daemon"}, + RunFunc: (*exec.Cmd).Start, // Start without waiting for completion. + }) + + node.StopDaemon() + }) +} diff --git a/test/cli/harness/ipfs.go b/test/cli/harness/ipfs.go index dde7e3495..8537e2aa2 100644 --- a/test/cli/harness/ipfs.go +++ b/test/cli/harness/ipfs.go @@ -38,9 +38,20 @@ func (n *Node) SetIPFSConfig(key string, val interface{}, flags ...string) { n.IPFS(args...) // validate the config was set correctly - var newVal string - n.GetIPFSConfig(key, &newVal) - if val != newVal { + + // Create a new value which is a pointer to the same type as the source. + var newVal any + if val != nil { + // If it is not nil grab the type with reflect. + newVal = reflect.New(reflect.TypeOf(val)).Interface() + } else { + // else just set a pointer to an any. + var anything any + newVal = &anything + } + n.GetIPFSConfig(key, newVal) + // dereference newVal using reflect to load the resulting value + if !reflect.DeepEqual(val, reflect.ValueOf(newVal).Elem().Interface()) { log.Panicf("key '%s' did not retain value '%s' after it was set, got '%s'", key, val, newVal) } } From 5c31db3a3d189dc1c85ffc74420358d81de25d28 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Tue, 12 Dec 2023 18:21:52 +0100 Subject: [PATCH 0960/1212] commands: remove several deprecated commands Removes the following commands: ipfs tar, ipfs urlstore, ipfs repo fsck, ipfs file ls, ipfs dns. --- CHANGELOG.md | 1 + core/commands/commands_test.go | 10 -- core/commands/dns.go | 78 ---------- core/commands/repo.go | 22 --- core/commands/root.go | 6 - core/commands/tar.go | 118 ---------------- core/commands/unixfs/ls.go | 236 ------------------------------- core/commands/unixfs/unixfs.go | 20 --- core/commands/urlstore.go | 105 -------------- docs/changelogs/v0.26.md | 29 ++++ tar/format.go | 227 ----------------------------- test/cli/basic_commands_test.go | 6 - test/sharness/t0200-unixfs-ls.sh | 140 ------------------ test/sharness/t0210-tar.sh | 58 -------- test/sharness/t0272-urlstore.sh | 1 - 15 files changed, 30 insertions(+), 1027 deletions(-) delete mode 100644 core/commands/dns.go delete mode 100644 core/commands/tar.go delete mode 100644 core/commands/unixfs/ls.go delete mode 100644 core/commands/unixfs/unixfs.go delete mode 100644 core/commands/urlstore.go create mode 100644 docs/changelogs/v0.26.md delete mode 100644 tar/format.go delete mode 100755 test/sharness/t0200-unixfs-ls.sh delete mode 100755 test/sharness/t0210-tar.sh diff --git a/CHANGELOG.md b/CHANGELOG.md index 7fd7e8f76..a0a5f78e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ # Kubo Changelogs +- [v0.26](docs/changelogs/v0.26.md) - [v0.25](docs/changelogs/v0.25.md) - [v0.24](docs/changelogs/v0.24.md) - [v0.23](docs/changelogs/v0.23.md) diff --git a/core/commands/commands_test.go b/core/commands/commands_test.go index a34aab448..00c09d77a 100644 --- a/core/commands/commands_test.go +++ b/core/commands/commands_test.go @@ -31,7 +31,6 @@ func TestROCommands(t *testing.T) { "/dag/resolve", "/dag/stat", "/dag/export", - "/dns", "/get", "/ls", "/name", @@ -136,9 +135,6 @@ func TestCommands(t *testing.T) { "/diag/cmds/set-time", "/diag/profile", "/diag/sys", - "/dns", - "/file", - "/file/ls", "/files", "/files/chcid", "/files/cp", @@ -229,7 +225,6 @@ func TestCommands(t *testing.T) { "/refs", "/refs/local", "/repo", - "/repo/fsck", "/repo/gc", "/repo/migrate", "/repo/stat", @@ -259,12 +254,7 @@ func TestCommands(t *testing.T) { "/swarm/peering/ls", "/swarm/peering/rm", "/swarm/resources", - "/tar", - "/tar/add", - "/tar/cat", "/update", - "/urlstore", - "/urlstore/add", "/version", "/version/deps", } diff --git a/core/commands/dns.go b/core/commands/dns.go deleted file mode 100644 index 065b4acdc..000000000 --- a/core/commands/dns.go +++ /dev/null @@ -1,78 +0,0 @@ -package commands - -import ( - "fmt" - "io" - "strings" - - namesys "github.com/ipfs/boxo/namesys" - "github.com/ipfs/boxo/path" - cmdenv "github.com/ipfs/kubo/core/commands/cmdenv" - ncmd "github.com/ipfs/kubo/core/commands/name" - - cmds "github.com/ipfs/go-ipfs-cmds" -) - -const ( - dnsRecursiveOptionName = "recursive" -) - -var DNSCmd = &cmds.Command{ - Status: cmds.Deprecated, // https://github.com/ipfs/kubo/issues/8607 - Helptext: cmds.HelpText{ - Tagline: "Resolve DNSLink records. Deprecated: Use 'ipfs resolve /ipns/domain-name' instead.", - ShortDescription: ` -This command can only recursively resolve DNSLink TXT records. -It will fail to recursively resolve through IPNS keys etc. - -DEPRECATED: superseded by 'ipfs resolve' - -For general-purpose recursive resolution, use 'ipfs resolve -r'. -It will work across multiple DNSLinks and IPNS keys. -`, - }, - - Arguments: []cmds.Argument{ - cmds.StringArg("domain-name", true, false, "The domain-name name to resolve.").EnableStdin(), - }, - Options: []cmds.Option{ - cmds.BoolOption(dnsRecursiveOptionName, "r", "Resolve until the result is not a DNS link.").WithDefault(true), - }, - Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - node, err := cmdenv.GetNode(env) - if err != nil { - return err - } - - recursive, _ := req.Options[dnsRecursiveOptionName].(bool) - name := req.Arguments[0] - resolver := namesys.NewDNSResolver(node.DNSResolver.LookupTXT) - - var routing []namesys.ResolveOption - if !recursive { - routing = append(routing, namesys.ResolveWithDepth(1)) - } - - if !strings.HasPrefix(name, "/ipns/") { - name = "/ipns/" + name - } - - p, err := path.NewPath(name) - if err != nil { - return err - } - - val, err := resolver.Resolve(req.Context, p, routing...) - if err != nil && (recursive || err != namesys.ErrResolveRecursion) { - return err - } - return cmds.EmitOnce(res, &ncmd.ResolvedPath{Path: val.Path.String()}) - }, - Encoders: cmds.EncoderMap{ - cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *ncmd.ResolvedPath) error { - fmt.Fprintln(w, cmdenv.EscNonPrint(out.Path)) - return nil - }), - }, - Type: ncmd.ResolvedPath{}, -} diff --git a/core/commands/repo.go b/core/commands/repo.go index 1f4df327a..77ce68590 100644 --- a/core/commands/repo.go +++ b/core/commands/repo.go @@ -39,7 +39,6 @@ var RepoCmd = &cmds.Command{ Subcommands: map[string]*cmds.Command{ "stat": repoStatCmd, "gc": repoGcCmd, - "fsck": repoFsckCmd, "version": repoVersionCmd, "verify": repoVerifyCmd, "migrate": repoMigrateCmd, @@ -227,27 +226,6 @@ Version string The repo version. }, } -var repoFsckCmd = &cmds.Command{ - Status: cmds.Deprecated, // https://github.com/ipfs/kubo/issues/6435 - Helptext: cmds.HelpText{ - Tagline: "Remove repo lockfiles.", - ShortDescription: ` -'ipfs repo fsck' is now a no-op. -`, - }, - NoRemote: true, - Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - return cmds.EmitOnce(res, &MessageOutput{"`ipfs repo fsck` is deprecated and does nothing.\n"}) - }, - Type: MessageOutput{}, - Encoders: cmds.EncoderMap{ - cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *MessageOutput) error { - fmt.Fprintf(w, out.Message) - return nil - }), - }, -} - type VerifyProgress struct { Msg string Progress int diff --git a/core/commands/root.go b/core/commands/root.go index b812573fc..b4e563cdb 100644 --- a/core/commands/root.go +++ b/core/commands/root.go @@ -8,7 +8,6 @@ import ( name "github.com/ipfs/kubo/core/commands/name" ocmd "github.com/ipfs/kubo/core/commands/object" "github.com/ipfs/kubo/core/commands/pin" - unixfs "github.com/ipfs/kubo/core/commands/unixfs" cmds "github.com/ipfs/go-ipfs-cmds" logging "github.com/ipfs/go-log" @@ -143,7 +142,6 @@ var rootSubcommands = map[string]*cmds.Command{ "dht": DhtCmd, "routing": RoutingCmd, "diag": DiagCmd, - "dns": DNSCmd, "id": IDCmd, "key": KeyCmd, "log": LogCmd, @@ -157,10 +155,7 @@ var rootSubcommands = map[string]*cmds.Command{ "refs": RefsCmd, "resolve": ResolveCmd, "swarm": SwarmCmd, - "tar": TarCmd, - "file": unixfs.UnixFSCmd, "update": ExternalBinary("Please see https://github.com/ipfs/ipfs-update/blob/master/README.md#install for installation instructions."), - "urlstore": urlStoreCmd, "version": VersionCmd, "shutdown": daemonShutdownCmd, "cid": CidCmd, @@ -188,7 +183,6 @@ var rootROSubcommands = map[string]*cmds.Command{ }, }, "get": GetCmd, - "dns": DNSCmd, "ls": LsCmd, "name": { Subcommands: map[string]*cmds.Command{ diff --git a/core/commands/tar.go b/core/commands/tar.go deleted file mode 100644 index e1094a59f..000000000 --- a/core/commands/tar.go +++ /dev/null @@ -1,118 +0,0 @@ -package commands - -import ( - "fmt" - "io" - - cmds "github.com/ipfs/go-ipfs-cmds" - "github.com/ipfs/kubo/core/commands/cmdenv" - "github.com/ipfs/kubo/core/commands/cmdutils" - tar "github.com/ipfs/kubo/tar" - - dag "github.com/ipfs/boxo/ipld/merkledag" -) - -var TarCmd = &cmds.Command{ - Status: cmds.Deprecated, // https://github.com/ipfs/kubo/issues/7951 - Helptext: cmds.HelpText{ - Tagline: "Utility functions for tar files in ipfs.", - }, - - Subcommands: map[string]*cmds.Command{ - "add": tarAddCmd, - "cat": tarCatCmd, - }, -} - -var tarAddCmd = &cmds.Command{ - Status: cmds.Deprecated, // https://github.com/ipfs/kubo/issues/7951 - Helptext: cmds.HelpText{ - Tagline: "Import a tar file into IPFS.", - ShortDescription: ` -'ipfs tar add' will parse a tar file and create a merkledag structure to -represent it. -`, - }, - - Arguments: []cmds.Argument{ - cmds.FileArg("file", true, false, "Tar file to add.").EnableStdin(), - }, - Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - api, err := cmdenv.GetApi(env, req) - if err != nil { - return err - } - - enc, err := cmdenv.GetCidEncoder(req) - if err != nil { - return err - } - - it := req.Files.Entries() - file, err := cmdenv.GetFileArg(it) - if err != nil { - return err - } - - node, err := tar.ImportTar(req.Context, file, api.Dag()) - if err != nil { - return err - } - - c := node.Cid() - - return cmds.EmitOnce(res, &AddEvent{ - Name: it.Name(), - Hash: enc.Encode(c), - }) - }, - Type: AddEvent{}, - Encoders: cmds.EncoderMap{ - cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *AddEvent) error { - fmt.Fprintln(w, out.Hash) - return nil - }), - }, -} - -var tarCatCmd = &cmds.Command{ - Status: cmds.Deprecated, // https://github.com/ipfs/kubo/issues/7951 - Helptext: cmds.HelpText{ - Tagline: "Export a tar file from IPFS.", - ShortDescription: ` -'ipfs tar cat' will export a tar file from a previously imported one in IPFS. -`, - }, - - Arguments: []cmds.Argument{ - cmds.StringArg("path", true, false, "ipfs path of archive to export.").EnableStdin(), - }, - Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - api, err := cmdenv.GetApi(env, req) - if err != nil { - return err - } - - p, err := cmdutils.PathOrCidPath(req.Arguments[0]) - if err != nil { - return err - } - - root, err := api.ResolveNode(req.Context, p) - if err != nil { - return err - } - - rootpb, ok := root.(*dag.ProtoNode) - if !ok { - return dag.ErrNotProtobuf - } - - r, err := tar.ExportTar(req.Context, rootpb, api.Dag()) - if err != nil { - return err - } - - return res.Emit(r) - }, -} diff --git a/core/commands/unixfs/ls.go b/core/commands/unixfs/ls.go deleted file mode 100644 index c2d75c929..000000000 --- a/core/commands/unixfs/ls.go +++ /dev/null @@ -1,236 +0,0 @@ -package unixfs - -import ( - "fmt" - "io" - "sort" - "text/tabwriter" - - cmdenv "github.com/ipfs/kubo/core/commands/cmdenv" - "github.com/ipfs/kubo/core/commands/cmdutils" - - merkledag "github.com/ipfs/boxo/ipld/merkledag" - unixfs "github.com/ipfs/boxo/ipld/unixfs" - cmds "github.com/ipfs/go-ipfs-cmds" -) - -type LsLink struct { - Name, Hash string - Size uint64 - Type string -} - -type LsObject struct { - Hash string - Size uint64 - Type string - Links []LsLink -} - -type LsOutput struct { - Arguments map[string]string - Objects map[string]*LsObject -} - -var LsCmd = &cmds.Command{ - Status: cmds.Deprecated, // https://github.com/ipfs/kubo/pull/7755 - Helptext: cmds.HelpText{ - Tagline: "List directory contents for Unix filesystem objects. Deprecated: Use 'ipfs ls' and 'ipfs files ls' instead.", - ShortDescription: ` -Displays the contents of an IPFS or IPNS object(s) at the given path. - -The JSON output contains size information. For files, the child size -is the total size of the file contents. For directories, the child -size is the IPFS link size. - -This functionality is deprecated, and will be removed in future versions as it duplicates the functionality of 'ipfs ls'. -If possible, please use 'ipfs ls' instead. -`, - LongDescription: ` -Displays the contents of an IPFS or IPNS object(s) at the given path. - -The JSON output contains size information. For files, the child size -is the total size of the file contents. For directories, the child -size is the IPFS link size. - -The path can be a prefixless ref; in this case, we assume it to be an -/ipfs ref and not /ipns. - -Example: - - > ipfs file ls QmW2WQi7j6c7UgJTarActp7tDNikE4B2qXtFCfLPdsgaTQ - cat.jpg - > ipfs file ls /ipfs/QmW2WQi7j6c7UgJTarActp7tDNikE4B2qXtFCfLPdsgaTQ - cat.jpg - -This functionality is deprecated, and will be removed in future versions as it duplicates the functionality of 'ipfs ls'. -If possible, please use 'ipfs ls' instead. -`, - }, - - Arguments: []cmds.Argument{ - cmds.StringArg("ipfs-path", true, true, "The path to the IPFS object(s) to list links from.").EnableStdin(), - }, - Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - nd, err := cmdenv.GetNode(env) - if err != nil { - return err - } - - api, err := cmdenv.GetApi(env, req) - if err != nil { - return err - } - - if err := req.ParseBodyArgs(); err != nil { - return err - } - - paths := req.Arguments - - output := LsOutput{ - Arguments: map[string]string{}, - Objects: map[string]*LsObject{}, - } - - for _, p := range paths { - ctx := req.Context - - pth, err := cmdutils.PathOrCidPath(p) - if err != nil { - return err - } - - merkleNode, err := api.ResolveNode(ctx, pth) - if err != nil { - return err - } - - c := merkleNode.Cid() - - hash := c.String() - output.Arguments[p] = hash - - if _, ok := output.Objects[hash]; ok { - // duplicate argument for an already-listed node - continue - } - - ndpb, ok := merkleNode.(*merkledag.ProtoNode) - if !ok { - return merkledag.ErrNotProtobuf - } - - unixFSNode, err := unixfs.FSNodeFromBytes(ndpb.Data()) - if err != nil { - return err - } - - t := unixFSNode.Type() - - output.Objects[hash] = &LsObject{ - Hash: c.String(), - Type: t.String(), - Size: unixFSNode.FileSize(), - } - - switch t { - case unixfs.TFile: - break - case unixfs.THAMTShard: - // We need a streaming ls API for this. - return fmt.Errorf("cannot list large directories yet") - case unixfs.TDirectory: - links := make([]LsLink, len(merkleNode.Links())) - output.Objects[hash].Links = links - for i, link := range merkleNode.Links() { - linkNode, err := link.GetNode(ctx, nd.DAG) - if err != nil { - return err - } - lnpb, ok := linkNode.(*merkledag.ProtoNode) - if !ok { - return merkledag.ErrNotProtobuf - } - - d, err := unixfs.FSNodeFromBytes(lnpb.Data()) - if err != nil { - return err - } - t := d.Type() - lsLink := LsLink{ - Name: link.Name, - Hash: link.Cid.String(), - Type: t.String(), - } - if t == unixfs.TFile { - lsLink.Size = d.FileSize() - } else { - lsLink.Size = link.Size - } - links[i] = lsLink - } - case unixfs.TSymlink: - return fmt.Errorf("cannot list symlinks yet") - default: - return fmt.Errorf("unrecognized type: %s", t) - } - } - - return cmds.EmitOnce(res, &output) - }, - Encoders: cmds.EncoderMap{ - cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *LsOutput) error { - tw := tabwriter.NewWriter(w, 1, 2, 1, ' ', 0) - - nonDirectories := []string{} - directories := []string{} - for argument, hash := range out.Arguments { - object, ok := out.Objects[hash] - if !ok { - return fmt.Errorf("unresolved hash: %s", hash) - } - - if object.Type == "Directory" { - directories = append(directories, argument) - } else { - nonDirectories = append(nonDirectories, argument) - } - } - sort.Strings(nonDirectories) - sort.Strings(directories) - - for _, argument := range nonDirectories { - fmt.Fprintf(tw, "%s\n", argument) - } - - seen := map[string]bool{} - for i, argument := range directories { - hash := out.Arguments[argument] - if _, ok := seen[hash]; ok { - continue - } - seen[hash] = true - - object := out.Objects[hash] - if i > 0 || len(nonDirectories) > 0 { - fmt.Fprintln(tw) - } - if len(out.Arguments) > 1 { - for _, arg := range directories[i:] { - if out.Arguments[arg] == hash { - fmt.Fprintf(tw, "%s:\n", cmdenv.EscNonPrint(arg)) - } - } - } - for _, link := range object.Links { - fmt.Fprintf(tw, "%s\n", cmdenv.EscNonPrint(link.Name)) - } - } - tw.Flush() - - return nil - }), - }, - Type: LsOutput{}, -} diff --git a/core/commands/unixfs/unixfs.go b/core/commands/unixfs/unixfs.go deleted file mode 100644 index b50d08d92..000000000 --- a/core/commands/unixfs/unixfs.go +++ /dev/null @@ -1,20 +0,0 @@ -package unixfs - -import ( - cmds "github.com/ipfs/go-ipfs-cmds" -) - -var UnixFSCmd = &cmds.Command{ - Status: cmds.Deprecated, // https://github.com/ipfs/kubo/pull/7755 - Helptext: cmds.HelpText{ - Tagline: "Interact with IPFS objects representing Unix filesystems.", - ShortDescription: ` -Old interface to file systems represented by UnixFS. -Superseded by modern alternatives: 'ipfs ls' and 'ipfs files' -`, - }, - - Subcommands: map[string]*cmds.Command{ - "ls": LsCmd, - }, -} diff --git a/core/commands/urlstore.go b/core/commands/urlstore.go deleted file mode 100644 index c4ee08c90..000000000 --- a/core/commands/urlstore.go +++ /dev/null @@ -1,105 +0,0 @@ -package commands - -import ( - "fmt" - "io" - "net/url" - - filestore "github.com/ipfs/boxo/filestore" - cmdenv "github.com/ipfs/kubo/core/commands/cmdenv" - - "github.com/ipfs/boxo/files" - cmds "github.com/ipfs/go-ipfs-cmds" - "github.com/ipfs/kubo/core/coreiface/options" -) - -var urlStoreCmd = &cmds.Command{ - Helptext: cmds.HelpText{ - Tagline: "Interact with urlstore.", - }, - Subcommands: map[string]*cmds.Command{ - "add": urlAdd, - }, -} - -var urlAdd = &cmds.Command{ - Status: cmds.Deprecated, - Helptext: cmds.HelpText{ - Tagline: "Add URL via urlstore.", - LongDescription: ` -DEPRECATED: Use 'ipfs add --nocopy --cid-version=1 URL'. - -Add URLs to ipfs without storing the data locally. - -The URL provided must be stable and ideally on a web server under your -control. - -The file is added using raw-leaves but otherwise using the default -settings for 'ipfs add'. -`, - }, - Options: []cmds.Option{ - cmds.BoolOption(trickleOptionName, "t", "Use trickle-dag format for dag generation."), - cmds.BoolOption(pinOptionName, "Pin this object when adding.").WithDefault(true), - }, - Arguments: []cmds.Argument{ - cmds.StringArg("url", true, false, "URL to add to IPFS"), - }, - Type: &BlockStat{}, - - Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - log.Error("The 'ipfs urlstore' command is deprecated, please use 'ipfs add --nocopy --cid-version=1") - - urlString := req.Arguments[0] - if !filestore.IsURL(req.Arguments[0]) { - return fmt.Errorf("unsupported url syntax: %s", urlString) - } - - url, err := url.Parse(urlString) - if err != nil { - return err - } - - enc, err := cmdenv.GetCidEncoder(req) - if err != nil { - return err - } - - api, err := cmdenv.GetApi(env, req) - if err != nil { - return err - } - - useTrickledag, _ := req.Options[trickleOptionName].(bool) - dopin, _ := req.Options[pinOptionName].(bool) - - opts := []options.UnixfsAddOption{ - options.Unixfs.Pin(dopin), - options.Unixfs.CidVersion(1), - options.Unixfs.RawLeaves(true), - options.Unixfs.Nocopy(true), - } - - if useTrickledag { - opts = append(opts, options.Unixfs.Layout(options.TrickleLayout)) - } - - file := files.NewWebFile(url) - - path, err := api.Unixfs().Add(req.Context, file, opts...) - if err != nil { - return err - } - size, _ := file.Size() - return cmds.EmitOnce(res, &BlockStat{ - Key: enc.Encode(path.RootCid()), - Size: int(size), - }) - }, - Encoders: cmds.EncoderMap{ - cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, bs *BlockStat) error { - _, err := fmt.Fprintln(w, bs.Key) - return err - }), - }, -} diff --git a/docs/changelogs/v0.26.md b/docs/changelogs/v0.26.md new file mode 100644 index 000000000..a5d02df63 --- /dev/null +++ b/docs/changelogs/v0.26.md @@ -0,0 +1,29 @@ +# Kubo changelog v0.26 + +- [v0.26.0](#v0260) + +## v0.26.0 + +- [Overview](#overview) +- [🔦 Highlights](#-highlights) + - [Several deprecated commands have been removed](#several-deprecated-commands-have-been-removed) +- [📝 Changelog](#-changelog) +- [👨‍👩‍👧‍👦 Contributors](#-contributors) + +### Overview + +### 🔦 Highlights + +#### Several deprecated commands have been removed + +Several deprecated commands have been removed: + +- `ipfs urlstore` deprecated in [April 2019, Kubo 0.4.21](https://github.com/ipfs/kubo/commit/8beaee63b3fa634c59b85179286ad3873921a535), use `ipfs add -q --nocopy --cid-version=1 {url}` instead. +- `ipfs repo fsck` deprecated in [July 2019, Kubo 0.5.0](https://github.com/ipfs/kubo/commit/288a83ce7dcbf4a2498e06e4a95245bbb5e30f45) +- `ipfs file` (and `ipfs file ls`) deprecated in [November 2020, Kubo 0.8.0](https://github.com/ipfs/kubo/commit/ec64dc5c396e7114590e15909384fabce0035482), use `ipfs ls` and `ipfs files ls` instead. +- `ipfs dns` deprecated in [April 2022, Kubo 0.13](https://github.com/ipfs/kubo/commit/76ae33a9f3f9abd166d1f6f23d6a8a0511510e3c), use `ipfs resolve /ipns/{name}` instead. +- `ipfs tar` deprecated [April 2022, Kubo 0.13](https://github.com/ipfs/kubo/pull/8849) + +### 📝 Changelog + +### 👨‍👩‍👧‍👦 Contributors diff --git a/tar/format.go b/tar/format.go deleted file mode 100644 index a1fe455b4..000000000 --- a/tar/format.go +++ /dev/null @@ -1,227 +0,0 @@ -package tarfmt - -import ( - "archive/tar" - "bytes" - "context" - "errors" - "io" - "path" - "strings" - - dag "github.com/ipfs/boxo/ipld/merkledag" - "github.com/ipfs/boxo/ipld/merkledag/dagutils" - importer "github.com/ipfs/boxo/ipld/unixfs/importer" - uio "github.com/ipfs/boxo/ipld/unixfs/io" - - chunker "github.com/ipfs/boxo/chunker" - ipld "github.com/ipfs/go-ipld-format" - logging "github.com/ipfs/go-log" -) - -var log = logging.Logger("tarfmt") - -var ( - blockSize = 512 - zeroBlock = make([]byte, blockSize) -) - -func marshalHeader(h *tar.Header) ([]byte, error) { - buf := new(bytes.Buffer) - w := tar.NewWriter(buf) - err := w.WriteHeader(h) - if err != nil { - return nil, err - } - return buf.Bytes(), nil -} - -// ImportTar imports a tar file into the given DAGService and returns the root -// node. -func ImportTar(ctx context.Context, r io.Reader, ds ipld.DAGService) (*dag.ProtoNode, error) { - tr := tar.NewReader(r) - - root := new(dag.ProtoNode) - root.SetData([]byte("ipfs/tar")) - - e := dagutils.NewDagEditor(root, ds) - - for { - h, err := tr.Next() - if err != nil { - if err == io.EOF { - break - } - return nil, err - } - - header := new(dag.ProtoNode) - - headerBytes, err := marshalHeader(h) - if err != nil { - return nil, err - } - - header.SetData(headerBytes) - - if h.Size > 0 { - spl := chunker.NewRabin(tr, uint64(chunker.DefaultBlockSize)) - nd, err := importer.BuildDagFromReader(ds, spl) - if err != nil { - return nil, err - } - - err = header.AddNodeLink("data", nd) - if err != nil { - return nil, err - } - } - - err = ds.Add(ctx, header) - if err != nil { - return nil, err - } - - path := escapePath(h.Name) - err = e.InsertNodeAtPath(context.Background(), path, header, func() *dag.ProtoNode { return new(dag.ProtoNode) }) - if err != nil { - return nil, err - } - } - - return e.Finalize(ctx, ds) -} - -// adds a '-' to the beginning of each path element so we can use 'data' as a -// special link in the structure without having to worry about. -func escapePath(pth string) string { - elems := strings.Split(strings.Trim(pth, "/"), "/") - for i, e := range elems { - elems[i] = "-" + e - } - return path.Join(elems...) -} - -type tarReader struct { - links []*ipld.Link - ds ipld.DAGService - - childRead *tarReader - hdrBuf *bytes.Reader - fileRead *countReader - pad int - - ctx context.Context -} - -func (tr *tarReader) Read(b []byte) (int, error) { - // if we have a header to be read, it takes priority - if tr.hdrBuf != nil { - n, err := tr.hdrBuf.Read(b) - if err == io.EOF { - tr.hdrBuf = nil - return n, nil - } - return n, err - } - - // no header remaining, check for recursive - if tr.childRead != nil { - n, err := tr.childRead.Read(b) - if err == io.EOF { - tr.childRead = nil - return n, nil - } - return n, err - } - - // check for filedata to be read - if tr.fileRead != nil { - n, err := tr.fileRead.Read(b) - if err == io.EOF { - nr := tr.fileRead.n - tr.pad = (blockSize - (nr % blockSize)) % blockSize - tr.fileRead.Close() - tr.fileRead = nil - return n, nil - } - return n, err - } - - // filedata reads must be padded out to 512 byte offsets - if tr.pad > 0 { - n := copy(b, zeroBlock[:tr.pad]) - tr.pad -= n - return n, nil - } - - if len(tr.links) == 0 { - return 0, io.EOF - } - - next := tr.links[0] - tr.links = tr.links[1:] - - headerNd, err := next.GetNode(tr.ctx, tr.ds) - if err != nil { - return 0, err - } - - hndpb, ok := headerNd.(*dag.ProtoNode) - if !ok { - return 0, dag.ErrNotProtobuf - } - - tr.hdrBuf = bytes.NewReader(hndpb.Data()) - - dataNd, err := hndpb.GetLinkedProtoNode(tr.ctx, tr.ds, "data") - if err != nil && !errors.Is(err, dag.ErrLinkNotFound) { - return 0, err - } - - if err == nil { - dr, err := uio.NewDagReader(tr.ctx, dataNd, tr.ds) - if err != nil { - log.Error("dagreader error: ", err) - return 0, err - } - - tr.fileRead = &countReader{r: dr} - } else if len(headerNd.Links()) > 0 { - tr.childRead = &tarReader{ - links: headerNd.Links(), - ds: tr.ds, - ctx: tr.ctx, - } - } - - return tr.Read(b) -} - -// ExportTar exports the passed DAG as a tar file. This function is the inverse -// of ImportTar. -func ExportTar(ctx context.Context, root *dag.ProtoNode, ds ipld.DAGService) (io.Reader, error) { - if string(root.Data()) != "ipfs/tar" { - return nil, errors.New("not an IPFS tarchive") - } - return &tarReader{ - links: root.Links(), - ds: ds, - ctx: ctx, - }, nil -} - -type countReader struct { - r io.ReadCloser - n int -} - -func (r *countReader) Read(b []byte) (int, error) { - n, err := r.r.Read(b) - r.n += n - return n, err -} - -func (r *countReader) Close() error { - return r.r.Close() -} diff --git a/test/cli/basic_commands_test.go b/test/cli/basic_commands_test.go index 59444332a..b4bb2c182 100644 --- a/test/cli/basic_commands_test.go +++ b/test/cli/basic_commands_test.go @@ -116,9 +116,6 @@ func TestAllRootCommandsAreMentionedInHelpText(t *testing.T) { notInHelp := map[string]bool{ "object": true, "shutdown": true, - "tar": true, - "urlstore": true, - "dns": true, } helpMsg := strings.TrimSpace(node.IPFS("--help").Stdout.String()) @@ -159,7 +156,6 @@ func TestCommandDocsWidth(t *testing.T) { "ipfs pin verify": true, "ipfs dht get": true, "ipfs pin remote service add": true, - "ipfs file ls": true, "ipfs pin update": true, "ipfs pin rm": true, "ipfs p2p": true, @@ -177,10 +173,8 @@ func TestCommandDocsWidth(t *testing.T) { "ipfs swarm addrs local": true, "ipfs files ls": true, "ipfs stats bw": true, - "ipfs urlstore add": true, "ipfs swarm peers": true, "ipfs pubsub sub": true, - "ipfs repo fsck": true, "ipfs files write": true, "ipfs swarm limit": true, "ipfs commands completion fish": true, diff --git a/test/sharness/t0200-unixfs-ls.sh b/test/sharness/t0200-unixfs-ls.sh deleted file mode 100755 index 7499d92ef..000000000 --- a/test/sharness/t0200-unixfs-ls.sh +++ /dev/null @@ -1,140 +0,0 @@ -#!/usr/bin/env bash -# -# Copyright (c) 2014 Christian Couder -# MIT Licensed; see the LICENSE file in this repository. -# - -test_description="Test file ls command" - -. lib/test-lib.sh - -test_init_ipfs - -test_ls_cmd() { - - test_expect_success "'ipfs add -r testData' succeeds" ' - mkdir -p testData testData/d1 testData/d2 && - echo "test" >testData/f1 && - echo "data" >testData/f2 && - echo "hello" >testData/d1/a && - random 128 42 >testData/d1/128 && - echo "world" >testData/d2/a && - random 1024 42 >testData/d2/1024 && - ipfs add -r testData >actual_add - ' - - test_expect_success "'ipfs add' output looks good" ' - cat <<-\EOF >expected_add && -added QmQNd6ubRXaNG6Prov8o6vk3bn6eWsj9FxLGrAVDUAGkGe testData/d1/128 -added QmZULkCELmmk5XNfCgTnCyFgAVxBRBXyDHGGMVoLFLiXEN testData/d1/a -added QmbQBUSRL9raZtNXfpTDeaxQapibJEG6qEY8WqAN22aUzd testData/d2/1024 -added QmaRGe7bVmVaLmxbrMiVNXqW4pRNNp3xq7hFtyRKA3mtJL testData/d2/a -added QmeomffUNfmQy76CQGy9NdmqEnnHU9soCexBnGU3ezPHVH testData/f1 -added QmNtocSs7MoDkJMc1RkyisCSKvLadujPsfJfSdJ3e1eA1M testData/f2 -added QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss testData/d1 -added QmR3jhV4XpxxPjPT3Y8vNnWvWNvakdcT3H6vqpRBsX1MLy testData/d2 -added QmfNy183bXiRVyrhyWtq3TwHn79yHEkiAGFr18P7YNzESj testData -EOF - test_cmp expected_add actual_add - ' - - test_expect_success "'ipfs file ls ' succeeds" ' - ipfs file ls QmR3jhV4XpxxPjPT3Y8vNnWvWNvakdcT3H6vqpRBsX1MLy >actual_ls_one_directory - ' - - test_expect_success "'ipfs file ls ' output looks good" ' - cat <<-\EOF >expected_ls_one_directory && -1024 -a -EOF - test_cmp expected_ls_one_directory actual_ls_one_directory - ' - - test_expect_success "'ipfs file ls ' succeeds" ' - ipfs file ls QmfNy183bXiRVyrhyWtq3TwHn79yHEkiAGFr18P7YNzESj QmR3jhV4XpxxPjPT3Y8vNnWvWNvakdcT3H6vqpRBsX1MLy QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss >actual_ls_three_directories - ' - - test_expect_success "'ipfs file ls ' output looks good" ' - cat <<-\EOF >expected_ls_three_directories && -QmR3jhV4XpxxPjPT3Y8vNnWvWNvakdcT3H6vqpRBsX1MLy: -1024 -a - -QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss: -128 -a - -QmfNy183bXiRVyrhyWtq3TwHn79yHEkiAGFr18P7YNzESj: -d1 -d2 -f1 -f2 -EOF - test_cmp expected_ls_three_directories actual_ls_three_directories - ' - - test_expect_success "'ipfs file ls ' succeeds" ' - ipfs file ls /ipfs/QmR3jhV4XpxxPjPT3Y8vNnWvWNvakdcT3H6vqpRBsX1MLy/1024 QmQNd6ubRXaNG6Prov8o6vk3bn6eWsj9FxLGrAVDUAGkGe >actual_ls_file - ' - - test_expect_success "'ipfs file ls ' output looks good" ' - cat <<-\EOF >expected_ls_file && -/ipfs/QmR3jhV4XpxxPjPT3Y8vNnWvWNvakdcT3H6vqpRBsX1MLy/1024 -QmQNd6ubRXaNG6Prov8o6vk3bn6eWsj9FxLGrAVDUAGkGe -EOF - test_cmp expected_ls_file actual_ls_file - ' - - test_expect_success "'ipfs file ls ' succeeds" ' - ipfs file ls /ipfs/QmfNy183bXiRVyrhyWtq3TwHn79yHEkiAGFr18P7YNzESj/d1 /ipfs/QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss /ipfs/QmR3jhV4XpxxPjPT3Y8vNnWvWNvakdcT3H6vqpRBsX1MLy/1024 /ipfs/QmbQBUSRL9raZtNXfpTDeaxQapibJEG6qEY8WqAN22aUzd >actual_ls_duplicates_file - ' - - test_expect_success "'ipfs file ls ' output looks good" ' - cat <<-\EOF >expected_ls_duplicates_file && -/ipfs/QmR3jhV4XpxxPjPT3Y8vNnWvWNvakdcT3H6vqpRBsX1MLy/1024 -/ipfs/QmbQBUSRL9raZtNXfpTDeaxQapibJEG6qEY8WqAN22aUzd - -/ipfs/QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss: -/ipfs/QmfNy183bXiRVyrhyWtq3TwHn79yHEkiAGFr18P7YNzESj/d1: -128 -a -EOF - test_cmp expected_ls_duplicates_file actual_ls_duplicates_file - ' - - test_expect_success "'ipfs --encoding=json file ls ' succeeds" ' - ipfs --encoding=json file ls /ipfs/QmR3jhV4XpxxPjPT3Y8vNnWvWNvakdcT3H6vqpRBsX1MLy/1024 >actual_json_ls_file - ' - - test_expect_success "'ipfs --encoding=json file ls ' output looks good" ' - cat <<-\EOF >expected_json_ls_file_trailing_newline && -{"Arguments":{"/ipfs/QmR3jhV4XpxxPjPT3Y8vNnWvWNvakdcT3H6vqpRBsX1MLy/1024":"QmbQBUSRL9raZtNXfpTDeaxQapibJEG6qEY8WqAN22aUzd"},"Objects":{"QmbQBUSRL9raZtNXfpTDeaxQapibJEG6qEY8WqAN22aUzd":{"Hash":"QmbQBUSRL9raZtNXfpTDeaxQapibJEG6qEY8WqAN22aUzd","Size":1024,"Type":"File","Links":null}}} -EOF - printf "%s\n" "$(cat expected_json_ls_file_trailing_newline)" >expected_json_ls_file && - test_cmp expected_json_ls_file actual_json_ls_file - ' - - test_expect_success "'ipfs --encoding=json file ls ' succeeds" ' - ipfs --encoding=json file ls /ipfs/QmfNy183bXiRVyrhyWtq3TwHn79yHEkiAGFr18P7YNzESj/d1 /ipfs/QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss /ipfs/QmR3jhV4XpxxPjPT3Y8vNnWvWNvakdcT3H6vqpRBsX1MLy/1024 /ipfs/QmbQBUSRL9raZtNXfpTDeaxQapibJEG6qEY8WqAN22aUzd >actual_json_ls_duplicates_file - ' - - test_expect_success "'ipfs --encoding=json file ls ' output looks good" ' - cat <<-\EOF >expected_json_ls_duplicates_file_trailing_newline && -{"Arguments":{"/ipfs/QmR3jhV4XpxxPjPT3Y8vNnWvWNvakdcT3H6vqpRBsX1MLy/1024":"QmbQBUSRL9raZtNXfpTDeaxQapibJEG6qEY8WqAN22aUzd","/ipfs/QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss":"QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss","/ipfs/QmbQBUSRL9raZtNXfpTDeaxQapibJEG6qEY8WqAN22aUzd":"QmbQBUSRL9raZtNXfpTDeaxQapibJEG6qEY8WqAN22aUzd","/ipfs/QmfNy183bXiRVyrhyWtq3TwHn79yHEkiAGFr18P7YNzESj/d1":"QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss"},"Objects":{"QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss":{"Hash":"QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss","Size":0,"Type":"Directory","Links":[{"Name":"128","Hash":"QmQNd6ubRXaNG6Prov8o6vk3bn6eWsj9FxLGrAVDUAGkGe","Size":128,"Type":"File"},{"Name":"a","Hash":"QmZULkCELmmk5XNfCgTnCyFgAVxBRBXyDHGGMVoLFLiXEN","Size":6,"Type":"File"}]},"QmbQBUSRL9raZtNXfpTDeaxQapibJEG6qEY8WqAN22aUzd":{"Hash":"QmbQBUSRL9raZtNXfpTDeaxQapibJEG6qEY8WqAN22aUzd","Size":1024,"Type":"File","Links":null}}} -EOF - printf "%s\n" "$(cat expected_json_ls_duplicates_file_trailing_newline)" >expected_json_ls_duplicates_file && - test_cmp expected_json_ls_duplicates_file actual_json_ls_duplicates_file - ' - -} - - -# should work offline -test_ls_cmd - -# should work online -test_launch_ipfs_daemon -test_ls_cmd -test_kill_ipfs_daemon - -test_done diff --git a/test/sharness/t0210-tar.sh b/test/sharness/t0210-tar.sh deleted file mode 100755 index d2b910550..000000000 --- a/test/sharness/t0210-tar.sh +++ /dev/null @@ -1,58 +0,0 @@ -#!/usr/bin/env bash -# -# Copyright (c) 2015 Jeromy Johnson -# MIT Licensed; see the LICENSE file in this repository. -# - -test_description="Test tar commands" - -. lib/test-lib.sh - -test_init_ipfs - -test_expect_success "create some random files" ' - mkdir foo && - random 10000 > foo/a && - random 12345 > foo/b && - mkdir foo/bar && - random 5432 > foo/bar/baz && - ln -s ../a foo/bar/link && - echo "exit" > foo/script && - chmod +x foo/script -' - -test_expect_success "tar those random files up" ' - tar cf files.tar foo/ -' - -test_expect_success "'ipfs tar add' succeeds" ' - TAR_HASH=$(ipfs tar add files.tar) -' - -test_expect_success "'ipfs tar cat' succeeds" ' - mkdir output && - ipfs tar cat $TAR_HASH > output/out.tar -' - -test_expect_success "can extract tar" ' - tar xf output/out.tar -C output/ -' - -test_expect_success "files look right" ' - diff foo/a output/foo/a && - diff foo/b output/foo/b && - diff foo/bar/baz output/foo/bar/baz && - [ -L output/foo/bar/link ] && - [ -x foo/script ] -' - -test_expect_success "'ipfs tar add --cid-base=base32' succeeds" ' - ipfs tar add --cid-base=base32 files.tar > actual -' - -test_expect_success "'ipfs tar add --cid-base=base32' has correct hash" ' - ipfs cid base32 $TAR_HASH > expected && - test_cmp expected actual -' - -test_done diff --git a/test/sharness/t0272-urlstore.sh b/test/sharness/t0272-urlstore.sh index 40d025454..8fa7ff3b8 100755 --- a/test/sharness/t0272-urlstore.sh +++ b/test/sharness/t0272-urlstore.sh @@ -191,7 +191,6 @@ EOF ' } -test_urlstore urlstore add test_urlstore add -q --nocopy --cid-version=1 test_done From 3932fdfe51c0a58dc0b67835c588d818d746d5a1 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Wed, 13 Dec 2023 08:59:17 +0100 Subject: [PATCH 0961/1212] chore: bump to go-libp2p 0.32.2 Update go-libp2p (and quic-go) with Honeybadger fix. --- docs/examples/kubo-as-a-library/go.mod | 4 ++-- docs/examples/kubo-as-a-library/go.sum | 8 ++++---- go.mod | 4 ++-- go.sum | 8 ++++---- test/dependencies/go.mod | 2 +- test/dependencies/go.sum | 6 +++--- 6 files changed, 16 insertions(+), 16 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 3d46b2ef7..2ad0ae269 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -9,7 +9,7 @@ replace github.com/ipfs/kubo => ./../../.. require ( github.com/ipfs/boxo v0.16.0 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 - github.com/libp2p/go-libp2p v0.32.1 + github.com/libp2p/go-libp2p v0.32.2 github.com/multiformats/go-multiaddr v0.12.0 ) @@ -163,7 +163,7 @@ require ( github.com/prometheus/procfs v0.12.0 // indirect github.com/quic-go/qpack v0.4.0 // indirect github.com/quic-go/qtls-go1-20 v0.3.4 // indirect - github.com/quic-go/quic-go v0.39.3 // indirect + github.com/quic-go/quic-go v0.39.4 // indirect github.com/quic-go/webtransport-go v0.6.0 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/samber/lo v1.39.0 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 0216b2681..d82db17e0 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -453,8 +453,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.32.1 h1:wy1J4kZIZxOaej6NveTWCZmHiJ/kY7GoAqXgqNCnPps= -github.com/libp2p/go-libp2p v0.32.1/go.mod h1:hXXC3kXPlBZ1eu8Q2hptGrMB4mZ3048JUoS4EKaHW5c= +github.com/libp2p/go-libp2p v0.32.2 h1:s8GYN4YJzgUoyeYNPdW7JZeZ5Ee31iNaIBfGYMAY4FQ= +github.com/libp2p/go-libp2p v0.32.2/go.mod h1:E0LKe+diV/ZVJVnOJby8VC5xzHF0660osg71skcxJvk= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= @@ -676,8 +676,8 @@ github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= github.com/quic-go/qtls-go1-20 v0.3.4 h1:MfFAPULvst4yoMgY9QmtpYmfij/em7O8UUi+bNVm7Cg= github.com/quic-go/qtls-go1-20 v0.3.4/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= -github.com/quic-go/quic-go v0.39.3 h1:o3YB6t2SR+HU/pgwF29kJ6g4jJIJEwEZ8CKia1h1TKg= -github.com/quic-go/quic-go v0.39.3/go.mod h1:T09QsDQWjLiQ74ZmacDfqZmhY/NLnw5BC40MANNNZ1Q= +github.com/quic-go/quic-go v0.39.4 h1:PelfiuG7wXEffUT2yceiqz5V6Pc0TA5ruOd1LcmFc1s= +github.com/quic-go/quic-go v0.39.4/go.mod h1:T09QsDQWjLiQ74ZmacDfqZmhY/NLnw5BC40MANNNZ1Q= github.com/quic-go/webtransport-go v0.6.0 h1:CvNsKqc4W2HljHJnoT+rMmbRJybShZ0YPFDD3NxaZLY= github.com/quic-go/webtransport-go v0.6.0/go.mod h1:9KjU4AEBqEQidGHNDkZrb8CAa1abRaosM2yGOyiikEc= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= diff --git a/go.mod b/go.mod index eb50dde80..1c1f5e5d4 100644 --- a/go.mod +++ b/go.mod @@ -47,7 +47,7 @@ require ( github.com/jbenet/goprocess v0.1.4 github.com/julienschmidt/httprouter v1.3.0 github.com/libp2p/go-doh-resolver v0.4.0 - github.com/libp2p/go-libp2p v0.32.1 + github.com/libp2p/go-libp2p v0.32.2 github.com/libp2p/go-libp2p-http v0.5.0 github.com/libp2p/go-libp2p-kad-dht v0.24.4 github.com/libp2p/go-libp2p-kbucket v0.6.3 @@ -205,7 +205,7 @@ require ( github.com/prometheus/statsd_exporter v0.22.7 // indirect github.com/quic-go/qpack v0.4.0 // indirect github.com/quic-go/qtls-go1-20 v0.3.4 // indirect - github.com/quic-go/quic-go v0.39.3 // indirect + github.com/quic-go/quic-go v0.39.4 // indirect github.com/quic-go/webtransport-go v0.6.0 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/rs/cors v1.7.0 // indirect diff --git a/go.sum b/go.sum index 66d5d38d9..09b15e67f 100644 --- a/go.sum +++ b/go.sum @@ -511,8 +511,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.32.1 h1:wy1J4kZIZxOaej6NveTWCZmHiJ/kY7GoAqXgqNCnPps= -github.com/libp2p/go-libp2p v0.32.1/go.mod h1:hXXC3kXPlBZ1eu8Q2hptGrMB4mZ3048JUoS4EKaHW5c= +github.com/libp2p/go-libp2p v0.32.2 h1:s8GYN4YJzgUoyeYNPdW7JZeZ5Ee31iNaIBfGYMAY4FQ= +github.com/libp2p/go-libp2p v0.32.2/go.mod h1:E0LKe+diV/ZVJVnOJby8VC5xzHF0660osg71skcxJvk= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= @@ -783,8 +783,8 @@ github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= github.com/quic-go/qtls-go1-20 v0.3.4 h1:MfFAPULvst4yoMgY9QmtpYmfij/em7O8UUi+bNVm7Cg= github.com/quic-go/qtls-go1-20 v0.3.4/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= -github.com/quic-go/quic-go v0.39.3 h1:o3YB6t2SR+HU/pgwF29kJ6g4jJIJEwEZ8CKia1h1TKg= -github.com/quic-go/quic-go v0.39.3/go.mod h1:T09QsDQWjLiQ74ZmacDfqZmhY/NLnw5BC40MANNNZ1Q= +github.com/quic-go/quic-go v0.39.4 h1:PelfiuG7wXEffUT2yceiqz5V6Pc0TA5ruOd1LcmFc1s= +github.com/quic-go/quic-go v0.39.4/go.mod h1:T09QsDQWjLiQ74ZmacDfqZmhY/NLnw5BC40MANNNZ1Q= github.com/quic-go/webtransport-go v0.6.0 h1:CvNsKqc4W2HljHJnoT+rMmbRJybShZ0YPFDD3NxaZLY= github.com/quic-go/webtransport-go v0.6.0/go.mod h1:9KjU4AEBqEQidGHNDkZrb8CAa1abRaosM2yGOyiikEc= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index e7ec1b90f..b726fb5b0 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -133,7 +133,7 @@ require ( github.com/leonklingele/grouper v1.1.1 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/libp2p/go-cidranger v1.1.0 // indirect - github.com/libp2p/go-libp2p v0.32.1 // indirect + github.com/libp2p/go-libp2p v0.32.2 // indirect github.com/libp2p/go-libp2p-asn-util v0.3.0 // indirect github.com/libp2p/go-libp2p-kad-dht v0.24.4 // indirect github.com/libp2p/go-libp2p-kbucket v0.6.3 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 9e5c96d46..047bf5f5a 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -449,8 +449,8 @@ github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QT github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38yPW7c= github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= -github.com/libp2p/go-libp2p v0.32.1 h1:wy1J4kZIZxOaej6NveTWCZmHiJ/kY7GoAqXgqNCnPps= -github.com/libp2p/go-libp2p v0.32.1/go.mod h1:hXXC3kXPlBZ1eu8Q2hptGrMB4mZ3048JUoS4EKaHW5c= +github.com/libp2p/go-libp2p v0.32.2 h1:s8GYN4YJzgUoyeYNPdW7JZeZ5Ee31iNaIBfGYMAY4FQ= +github.com/libp2p/go-libp2p v0.32.2/go.mod h1:E0LKe+diV/ZVJVnOJby8VC5xzHF0660osg71skcxJvk= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-kad-dht v0.24.4 h1:ktNiJe7ffsJ1wX3ULpMCwXts99mPqGFSE/Qn1i8pErQ= @@ -626,7 +626,7 @@ github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 h1:M8mH9eK4OUR4l github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567/go.mod h1:DWNGW8A4Y+GyBgPuaQJuWiy0XYftx4Xm/y5Jqk9I6VQ= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qtls-go1-20 v0.3.4 h1:MfFAPULvst4yoMgY9QmtpYmfij/em7O8UUi+bNVm7Cg= -github.com/quic-go/quic-go v0.39.3 h1:o3YB6t2SR+HU/pgwF29kJ6g4jJIJEwEZ8CKia1h1TKg= +github.com/quic-go/quic-go v0.39.4 h1:PelfiuG7wXEffUT2yceiqz5V6Pc0TA5ruOd1LcmFc1s= github.com/quic-go/webtransport-go v0.6.0 h1:CvNsKqc4W2HljHJnoT+rMmbRJybShZ0YPFDD3NxaZLY= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= From f93a3869849ca1e5e07ae5ae05fb615ae477a1bd Mon Sep 17 00:00:00 2001 From: Jorropo Date: Mon, 11 Dec 2023 11:45:08 +0100 Subject: [PATCH 0962/1212] fix: allow daemon to start correctly if the API is null (#10062) (cherry picked from commit 8c4bdd8556e0c8b1a4ea3a6d703402bd6cfe1229) --- cmd/ipfs/daemon.go | 7 +++++-- test/cli/daemon_test.go | 25 +++++++++++++++++++++++++ test/cli/harness/ipfs.go | 17 ++++++++++++++--- 3 files changed, 44 insertions(+), 5 deletions(-) create mode 100644 test/cli/daemon_test.go diff --git a/cmd/ipfs/daemon.go b/cmd/ipfs/daemon.go index f46dbdd8c..4ad9b629c 100644 --- a/cmd/ipfs/daemon.go +++ b/cmd/ipfs/daemon.go @@ -727,8 +727,11 @@ func serveHTTPApi(req *cmds.Request, cctx *oldcmds.Context) (<-chan error, error return nil, fmt.Errorf("serveHTTPApi: ConstructNode() failed: %s", err) } - if err := node.Repo.SetAPIAddr(rewriteMaddrToUseLocalhostIfItsAny(listeners[0].Multiaddr())); err != nil { - return nil, fmt.Errorf("serveHTTPApi: SetAPIAddr() failed: %w", err) + if len(listeners) > 0 { + // Only add an api file if the API is running. + if err := node.Repo.SetAPIAddr(rewriteMaddrToUseLocalhostIfItsAny(listeners[0].Multiaddr())); err != nil { + return nil, fmt.Errorf("serveHTTPApi: SetAPIAddr() failed: %w", err) + } } errc := make(chan error) diff --git a/test/cli/daemon_test.go b/test/cli/daemon_test.go new file mode 100644 index 000000000..7a8c583a2 --- /dev/null +++ b/test/cli/daemon_test.go @@ -0,0 +1,25 @@ +package cli + +import ( + "os/exec" + "testing" + + "github.com/ipfs/kubo/test/cli/harness" +) + +func TestDaemon(t *testing.T) { + t.Parallel() + + t.Run("daemon starts if api is set to null", func(t *testing.T) { + t.Parallel() + node := harness.NewT(t).NewNode().Init() + node.SetIPFSConfig("Addresses.API", nil) + node.Runner.MustRun(harness.RunRequest{ + Path: node.IPFSBin, + Args: []string{"daemon"}, + RunFunc: (*exec.Cmd).Start, // Start without waiting for completion. + }) + + node.StopDaemon() + }) +} diff --git a/test/cli/harness/ipfs.go b/test/cli/harness/ipfs.go index dde7e3495..8537e2aa2 100644 --- a/test/cli/harness/ipfs.go +++ b/test/cli/harness/ipfs.go @@ -38,9 +38,20 @@ func (n *Node) SetIPFSConfig(key string, val interface{}, flags ...string) { n.IPFS(args...) // validate the config was set correctly - var newVal string - n.GetIPFSConfig(key, &newVal) - if val != newVal { + + // Create a new value which is a pointer to the same type as the source. + var newVal any + if val != nil { + // If it is not nil grab the type with reflect. + newVal = reflect.New(reflect.TypeOf(val)).Interface() + } else { + // else just set a pointer to an any. + var anything any + newVal = &anything + } + n.GetIPFSConfig(key, newVal) + // dereference newVal using reflect to load the resulting value + if !reflect.DeepEqual(val, reflect.ValueOf(newVal).Elem().Interface()) { log.Panicf("key '%s' did not retain value '%s' after it was set, got '%s'", key, val, newVal) } } From b46b5ea38a97d85cce4f4f986b8540ef1bee1157 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Wed, 13 Dec 2023 08:59:17 +0100 Subject: [PATCH 0963/1212] chore: bump to go-libp2p 0.32.2 Update go-libp2p (and quic-go) with Honeybadger fix. (cherry picked from commit 3932fdfe51c0a58dc0b67835c588d818d746d5a1) --- docs/examples/kubo-as-a-library/go.mod | 4 ++-- docs/examples/kubo-as-a-library/go.sum | 8 ++++---- go.mod | 4 ++-- go.sum | 8 ++++---- test/dependencies/go.mod | 2 +- test/dependencies/go.sum | 6 +++--- 6 files changed, 16 insertions(+), 16 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 3d46b2ef7..2ad0ae269 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -9,7 +9,7 @@ replace github.com/ipfs/kubo => ./../../.. require ( github.com/ipfs/boxo v0.16.0 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 - github.com/libp2p/go-libp2p v0.32.1 + github.com/libp2p/go-libp2p v0.32.2 github.com/multiformats/go-multiaddr v0.12.0 ) @@ -163,7 +163,7 @@ require ( github.com/prometheus/procfs v0.12.0 // indirect github.com/quic-go/qpack v0.4.0 // indirect github.com/quic-go/qtls-go1-20 v0.3.4 // indirect - github.com/quic-go/quic-go v0.39.3 // indirect + github.com/quic-go/quic-go v0.39.4 // indirect github.com/quic-go/webtransport-go v0.6.0 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/samber/lo v1.39.0 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 0216b2681..d82db17e0 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -453,8 +453,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.32.1 h1:wy1J4kZIZxOaej6NveTWCZmHiJ/kY7GoAqXgqNCnPps= -github.com/libp2p/go-libp2p v0.32.1/go.mod h1:hXXC3kXPlBZ1eu8Q2hptGrMB4mZ3048JUoS4EKaHW5c= +github.com/libp2p/go-libp2p v0.32.2 h1:s8GYN4YJzgUoyeYNPdW7JZeZ5Ee31iNaIBfGYMAY4FQ= +github.com/libp2p/go-libp2p v0.32.2/go.mod h1:E0LKe+diV/ZVJVnOJby8VC5xzHF0660osg71skcxJvk= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= @@ -676,8 +676,8 @@ github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= github.com/quic-go/qtls-go1-20 v0.3.4 h1:MfFAPULvst4yoMgY9QmtpYmfij/em7O8UUi+bNVm7Cg= github.com/quic-go/qtls-go1-20 v0.3.4/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= -github.com/quic-go/quic-go v0.39.3 h1:o3YB6t2SR+HU/pgwF29kJ6g4jJIJEwEZ8CKia1h1TKg= -github.com/quic-go/quic-go v0.39.3/go.mod h1:T09QsDQWjLiQ74ZmacDfqZmhY/NLnw5BC40MANNNZ1Q= +github.com/quic-go/quic-go v0.39.4 h1:PelfiuG7wXEffUT2yceiqz5V6Pc0TA5ruOd1LcmFc1s= +github.com/quic-go/quic-go v0.39.4/go.mod h1:T09QsDQWjLiQ74ZmacDfqZmhY/NLnw5BC40MANNNZ1Q= github.com/quic-go/webtransport-go v0.6.0 h1:CvNsKqc4W2HljHJnoT+rMmbRJybShZ0YPFDD3NxaZLY= github.com/quic-go/webtransport-go v0.6.0/go.mod h1:9KjU4AEBqEQidGHNDkZrb8CAa1abRaosM2yGOyiikEc= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= diff --git a/go.mod b/go.mod index eb50dde80..1c1f5e5d4 100644 --- a/go.mod +++ b/go.mod @@ -47,7 +47,7 @@ require ( github.com/jbenet/goprocess v0.1.4 github.com/julienschmidt/httprouter v1.3.0 github.com/libp2p/go-doh-resolver v0.4.0 - github.com/libp2p/go-libp2p v0.32.1 + github.com/libp2p/go-libp2p v0.32.2 github.com/libp2p/go-libp2p-http v0.5.0 github.com/libp2p/go-libp2p-kad-dht v0.24.4 github.com/libp2p/go-libp2p-kbucket v0.6.3 @@ -205,7 +205,7 @@ require ( github.com/prometheus/statsd_exporter v0.22.7 // indirect github.com/quic-go/qpack v0.4.0 // indirect github.com/quic-go/qtls-go1-20 v0.3.4 // indirect - github.com/quic-go/quic-go v0.39.3 // indirect + github.com/quic-go/quic-go v0.39.4 // indirect github.com/quic-go/webtransport-go v0.6.0 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/rs/cors v1.7.0 // indirect diff --git a/go.sum b/go.sum index 66d5d38d9..09b15e67f 100644 --- a/go.sum +++ b/go.sum @@ -511,8 +511,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.32.1 h1:wy1J4kZIZxOaej6NveTWCZmHiJ/kY7GoAqXgqNCnPps= -github.com/libp2p/go-libp2p v0.32.1/go.mod h1:hXXC3kXPlBZ1eu8Q2hptGrMB4mZ3048JUoS4EKaHW5c= +github.com/libp2p/go-libp2p v0.32.2 h1:s8GYN4YJzgUoyeYNPdW7JZeZ5Ee31iNaIBfGYMAY4FQ= +github.com/libp2p/go-libp2p v0.32.2/go.mod h1:E0LKe+diV/ZVJVnOJby8VC5xzHF0660osg71skcxJvk= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= @@ -783,8 +783,8 @@ github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= github.com/quic-go/qtls-go1-20 v0.3.4 h1:MfFAPULvst4yoMgY9QmtpYmfij/em7O8UUi+bNVm7Cg= github.com/quic-go/qtls-go1-20 v0.3.4/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= -github.com/quic-go/quic-go v0.39.3 h1:o3YB6t2SR+HU/pgwF29kJ6g4jJIJEwEZ8CKia1h1TKg= -github.com/quic-go/quic-go v0.39.3/go.mod h1:T09QsDQWjLiQ74ZmacDfqZmhY/NLnw5BC40MANNNZ1Q= +github.com/quic-go/quic-go v0.39.4 h1:PelfiuG7wXEffUT2yceiqz5V6Pc0TA5ruOd1LcmFc1s= +github.com/quic-go/quic-go v0.39.4/go.mod h1:T09QsDQWjLiQ74ZmacDfqZmhY/NLnw5BC40MANNNZ1Q= github.com/quic-go/webtransport-go v0.6.0 h1:CvNsKqc4W2HljHJnoT+rMmbRJybShZ0YPFDD3NxaZLY= github.com/quic-go/webtransport-go v0.6.0/go.mod h1:9KjU4AEBqEQidGHNDkZrb8CAa1abRaosM2yGOyiikEc= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index e7ec1b90f..b726fb5b0 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -133,7 +133,7 @@ require ( github.com/leonklingele/grouper v1.1.1 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/libp2p/go-cidranger v1.1.0 // indirect - github.com/libp2p/go-libp2p v0.32.1 // indirect + github.com/libp2p/go-libp2p v0.32.2 // indirect github.com/libp2p/go-libp2p-asn-util v0.3.0 // indirect github.com/libp2p/go-libp2p-kad-dht v0.24.4 // indirect github.com/libp2p/go-libp2p-kbucket v0.6.3 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 9e5c96d46..047bf5f5a 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -449,8 +449,8 @@ github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QT github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38yPW7c= github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= -github.com/libp2p/go-libp2p v0.32.1 h1:wy1J4kZIZxOaej6NveTWCZmHiJ/kY7GoAqXgqNCnPps= -github.com/libp2p/go-libp2p v0.32.1/go.mod h1:hXXC3kXPlBZ1eu8Q2hptGrMB4mZ3048JUoS4EKaHW5c= +github.com/libp2p/go-libp2p v0.32.2 h1:s8GYN4YJzgUoyeYNPdW7JZeZ5Ee31iNaIBfGYMAY4FQ= +github.com/libp2p/go-libp2p v0.32.2/go.mod h1:E0LKe+diV/ZVJVnOJby8VC5xzHF0660osg71skcxJvk= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-kad-dht v0.24.4 h1:ktNiJe7ffsJ1wX3ULpMCwXts99mPqGFSE/Qn1i8pErQ= @@ -626,7 +626,7 @@ github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 h1:M8mH9eK4OUR4l github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567/go.mod h1:DWNGW8A4Y+GyBgPuaQJuWiy0XYftx4Xm/y5Jqk9I6VQ= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qtls-go1-20 v0.3.4 h1:MfFAPULvst4yoMgY9QmtpYmfij/em7O8UUi+bNVm7Cg= -github.com/quic-go/quic-go v0.39.3 h1:o3YB6t2SR+HU/pgwF29kJ6g4jJIJEwEZ8CKia1h1TKg= +github.com/quic-go/quic-go v0.39.4 h1:PelfiuG7wXEffUT2yceiqz5V6Pc0TA5ruOd1LcmFc1s= github.com/quic-go/webtransport-go v0.6.0 h1:CvNsKqc4W2HljHJnoT+rMmbRJybShZ0YPFDD3NxaZLY= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= From 78e2fab7c4b7d34bec365eec13088618c0ad06ef Mon Sep 17 00:00:00 2001 From: Bumblefudge Date: Wed, 13 Dec 2023 23:56:53 -0800 Subject: [PATCH 0964/1212] docs: add detail to NOpfs instructions in content-blocking.md --- docs/content-blocking.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/content-blocking.md b/docs/content-blocking.md index ebc84bba3..fad63ad9e 100644 --- a/docs/content-blocking.md +++ b/docs/content-blocking.md @@ -22,9 +22,12 @@ Place a `*.deny` file in one of directories: - `$XDG_CONFIG_HOME/ipfs/denylists/` (`$HOME/.config/ipfs/denylists/` if `XDG_CONFIG_HOME` is not set) - `/etc/ipfs/denylists/` (global) -Files need to be present before starting the `ipfs daemon` in order to be watched for updates. +Files need to be present before starting the `ipfs daemon` in order to be watched for any new updates +appended once started. Any other changes (such as removal of entries, prepending of entries, or +insertion of new entries before the EOF at time of daemon starting) will not be detected or processed +after boot; a restart of the daemon will be required for them to be factored in. -If a new denylist file is added, `ipfs daemon` needs to be restarted. +If an entire new denylist file is added, `ipfs daemon` also needs to be restarted to track it. CLI and Gateway users will receive errors in response to request impacted by a blocklist: From 0ab1f1c0ea976ebac6d63be71f018e441f86889b Mon Sep 17 00:00:00 2001 From: Jorropo Date: Thu, 14 Dec 2023 14:09:24 +0000 Subject: [PATCH 0965/1212] chore: update version --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index 30c8f12ef..ac23d43e8 100644 --- a/version.go +++ b/version.go @@ -11,7 +11,7 @@ import ( var CurrentCommit string // CurrentVersionNumber is the current application's version literal. -const CurrentVersionNumber = "0.25.0-rc1" +const CurrentVersionNumber = "0.25.0" const ApiVersion = "/kubo/" + CurrentVersionNumber + "/" //nolint From 87069b53554c2b2dbbcc720dced1e32164402f03 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Thu, 14 Dec 2023 14:11:25 +0000 Subject: [PATCH 0966/1212] chore: update changelog for v0.25 --- docs/changelogs/v0.25.md | 68 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/docs/changelogs/v0.25.md b/docs/changelogs/v0.25.md index 059e437b2..db610044a 100644 --- a/docs/changelogs/v0.25.md +++ b/docs/changelogs/v0.25.md @@ -66,4 +66,72 @@ For more information see https://github.com/ipfs/kubo/issues/10230. ### 📝 Changelog +
Full Changelog + +- github.com/ipfs/kubo: + - chore: update version + - fix: allow daemon to start correctly if the API is null (#10062) ([ipfs/kubo#10062](https://github.com/ipfs/kubo/pull/10062)) + - chore: update version + - feat: ipfs key sign|verify (#10235) ([ipfs/kubo#10235](https://github.com/ipfs/kubo/pull/10235)) + - docs(cli): fix spelling + - feat: webui v4.2.0 (#10241) ([ipfs/kubo#10241](https://github.com/ipfs/kubo/pull/10241)) + - Migrate coreiface ([ipfs/kubo#10237](https://github.com/ipfs/kubo/pull/10237)) + - docs: clarify WebRTCDirect cannot reuse the same port as QUIC + - libp2p: remove mplex + - graphsync: remove support for the server + - docs: move kubo-specific docs (#10226) ([ipfs/kubo#10226](https://github.com/ipfs/kubo/pull/10226)) + - feat(rpc): Opt-in HTTP RPC API Authorization (#10218) ([ipfs/kubo#10218](https://github.com/ipfs/kubo/pull/10218)) + - docs: clarify ipfs id agent version + - fix: regression in 'ipfs dns' + - docs(changelog): clarify webrtc in v0.24 + - chore: create next changelog + - Merge Release: v0.24.0 ([ipfs/kubo#10209](https://github.com/ipfs/kubo/pull/10209)) + - fix: allow event emitting to happen in parallel with getting the query channel + - fixes to routing put command (#10205) ([ipfs/kubo#10205](https://github.com/ipfs/kubo/pull/10205)) + - docs: fix accelerated-dht-client + - docs/config: remove extra commas in PublicGateways example entries + - docs: make it clear Web RTC Direct is experimental + - feat: add WebRTC Direct support + - docs: update EARLY_TESTERS.md (#10194) ([ipfs/kubo#10194](https://github.com/ipfs/kubo/pull/10194)) + - Update Version: v0.24 ([ipfs/kubo#10191](https://github.com/ipfs/kubo/pull/10191)) +- github.com/ipfs/boxo (v0.15.0 -> v0.16.0): + - Release 0.16.0 ([ipfs/boxo#518](https://github.com/ipfs/boxo/pull/518)) +- github.com/libp2p/go-libp2p (v0.32.1 -> v0.32.2): + - release v0.32.2 + +
+ ### 👨‍👩‍👧‍👦 Contributors + +| Contributor | Commits | Lines ± | Files Changed | +|-------------|---------|---------|---------------| +| Łukasz Magiera | 149 | +7833/-2505 | 375 | +| Henrique Dias | 26 | +2498/-7535 | 210 | +| Steven Allen | 48 | +497/-373 | 129 | +| Jorropo | 9 | +247/-604 | 49 | +| Michael Muré | 6 | +306/-79 | 14 | +| Adin Schmahmann | 3 | +275/-8 | 5 | +| Lucas Molas | 1 | +181/-56 | 2 | +| Laurent Senta | 1 | +109/-24 | 7 | +| Lars Gierth | 6 | +82/-18 | 8 | +| Petar Maymounkov | 1 | +66/-32 | 3 | +| web3-bot | 1 | +47/-42 | 17 | +| Marcin Rataj | 6 | +57/-23 | 8 | +| Kevin Atkinson | 5 | +31/-31 | 17 | +| Marten Seemann | 3 | +27/-28 | 16 | +| Hector Sanjuan | 3 | +28/-14 | 10 | +| Overbool | 2 | +36/-3 | 3 | +| Raúl Kripalani | 1 | +11/-12 | 4 | +| hannahhoward | 2 | +11/-7 | 6 | +| Jeromy Johnson | 5 | +9/-9 | 5 | +| ForrestWeston | 1 | +14/-1 | 1 | +| Russell Dempsey | 1 | +10/-2 | 2 | +| Will Scott | 1 | +8/-1 | 1 | +| Jeromy | 2 | +4/-4 | 2 | +| sukun | 1 | +2/-2 | 1 | +| Steve Loeppky | 1 | +2/-2 | 1 | +| Jonas Keunecke | 1 | +2/-2 | 1 | +| Edgar Lee | 1 | +3/-1 | 1 | +| Dreamacro | 1 | +2/-2 | 2 | +| godcong | 1 | +1/-1 | 1 | +| Cole Brown | 1 | +1/-1 | 1 | From 86b73f61fc9bc1b9ddd140e77ab890ee2a4e5092 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 30 Mar 2023 19:11:25 +0200 Subject: [PATCH 0967/1212] feat: cmd/ipfs: Allow passing custom BuildEnv to main --- cmd/ipfs/main.go | 106 ++++++++++++++++++++++----------------- cmd/ipfs/runmain_test.go | 2 +- 2 files changed, 60 insertions(+), 48 deletions(-) diff --git a/cmd/ipfs/main.go b/cmd/ipfs/main.go index f135f28fe..9448a5ca9 100644 --- a/cmd/ipfs/main.go +++ b/cmd/ipfs/main.go @@ -60,12 +60,20 @@ const ( heapProfile = "ipfs.memprof" ) -func loadPlugins(repoPath string) (*loader.PluginLoader, error) { +type PluginPreloader func(*loader.PluginLoader) error + +func LoadPlugins(repoPath string, preload PluginPreloader) (*loader.PluginLoader, error) { plugins, err := loader.NewPluginLoader(repoPath) if err != nil { return nil, fmt.Errorf("error loading plugins: %s", err) } + if preload != nil { + if err := preload(plugins); err != nil { + return nil, fmt.Errorf("error loading plugins (preload): %s", err) + } + } + if err := plugins.Initialize(); err != nil { return nil, fmt.Errorf("error initializing plugins: %s", err) } @@ -83,7 +91,7 @@ func loadPlugins(repoPath string) (*loader.PluginLoader, error) { // - output the response // - if anything fails, print error, maybe with help. func main() { - os.Exit(mainRet()) + os.Exit(Start(BuildDefaultEnv)) } func printErr(err error) int { @@ -101,7 +109,54 @@ func newUUID(key string) logging.Metadata { } } -func mainRet() (exitCode int) { +func BuildDefaultEnv(ctx context.Context, req *cmds.Request) (cmds.Environment, error) { + return BuildEnv(ctx, req, nil) +} + +func BuildEnv(ctx context.Context, req *cmds.Request, pl PluginPreloader) (cmds.Environment, error) { + checkDebug(req) + repoPath, err := GetRepoPath(req) + if err != nil { + return nil, err + } + log.Debugf("config path is %s", repoPath) + + plugins, err := LoadPlugins(repoPath, pl) + if err != nil { + return nil, err + } + + // this sets up the function that will initialize the node + // this is so that we can construct the node lazily. + return &oldcmds.Context{ + ConfigRoot: repoPath, + ReqLog: &oldcmds.ReqLog{}, + Plugins: plugins, + ConstructNode: func() (n *core.IpfsNode, err error) { + if req == nil { + return nil, errors.New("constructing node without a request") + } + + r, err := fsrepo.Open(repoPath) + if err != nil { // repo is owned by the node + return nil, err + } + + // ok everything is good. set it on the invocation (for ownership) + // and return it. + n, err = core.NewNode(ctx, &core.BuildCfg{ + Repo: r, + }) + if err != nil { + return nil, err + } + + return n, nil + }, + }, nil +} + +func Start(buildEnv func(ctx context.Context, req *cmds.Request) (cmds.Environment, error)) (exitCode int) { ctx := logging.ContextWithLoggable(context.Background(), newUUID("session")) tp, err := tracing.NewTracerProvider(ctx) @@ -155,49 +210,6 @@ func mainRet() (exitCode int) { // so we need to make sure it's stable os.Args[0] = "ipfs" - buildEnv := func(ctx context.Context, req *cmds.Request) (cmds.Environment, error) { - checkDebug(req) - repoPath, err := getRepoPath(req) - if err != nil { - return nil, err - } - log.Debugf("config path is %s", repoPath) - - plugins, err := loadPlugins(repoPath) - if err != nil { - return nil, err - } - - // this sets up the function that will initialize the node - // this is so that we can construct the node lazily. - return &oldcmds.Context{ - ConfigRoot: repoPath, - ReqLog: &oldcmds.ReqLog{}, - Plugins: plugins, - ConstructNode: func() (n *core.IpfsNode, err error) { - if req == nil { - return nil, errors.New("constructing node without a request") - } - - r, err := fsrepo.Open(repoPath) - if err != nil { // repo is owned by the node - return nil, err - } - - // ok everything is good. set it on the invocation (for ownership) - // and return it. - n, err = core.NewNode(ctx, &core.BuildCfg{ - Repo: r, - }) - if err != nil { - return nil, err - } - - return n, nil - }, - }, nil - } - err = cli.Run(ctx, Root, os.Args, os.Stdin, os.Stdout, os.Stderr, buildEnv, makeExecutor) if err != nil { return 1 @@ -364,7 +376,7 @@ func (twe tracingWrappedExecutor) Execute(req *cmds.Request, re cmds.ResponseEmi return err } -func getRepoPath(req *cmds.Request) (string, error) { +func GetRepoPath(req *cmds.Request) (string, error) { repoOpt, found := req.Options[corecmds.RepoDirOption].(string) if found && repoOpt != "" { return repoOpt, nil diff --git a/cmd/ipfs/runmain_test.go b/cmd/ipfs/runmain_test.go index c9f3f0198..b09a25226 100644 --- a/cmd/ipfs/runmain_test.go +++ b/cmd/ipfs/runmain_test.go @@ -16,7 +16,7 @@ import ( func TestRunMain(t *testing.T) { args := flag.Args() os.Args = append([]string{os.Args[0]}, args...) - ret := mainRet() + ret := Start() p := os.Getenv("IPFS_COVER_RET_FILE") if len(p) != 0 { From b5dddf67a23d597c63863e3401b31b0f8f31a047 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 30 Mar 2023 19:25:56 +0200 Subject: [PATCH 0968/1212] feat: cmd/ipfs: Make it possible to depend on cmd/ipfs --- cmd/ipfs/{ => kubo}/add_migrations.go | 2 +- cmd/ipfs/{ => kubo}/daemon.go | 2 +- cmd/ipfs/{ => kubo}/daemon_linux.go | 2 +- cmd/ipfs/{ => kubo}/daemon_other.go | 2 +- cmd/ipfs/{ => kubo}/debug.go | 2 +- cmd/ipfs/{ => kubo}/dnsresolve_test.go | 2 +- cmd/ipfs/{ => kubo}/init.go | 2 +- cmd/ipfs/{ => kubo}/ipfs.go | 2 +- cmd/ipfs/{ => kubo}/pinmfs.go | 2 +- cmd/ipfs/{ => kubo}/pinmfs_test.go | 2 +- cmd/ipfs/kubo/start.go | 494 +++++++++++++++++++++++++ cmd/ipfs/main.go | 487 +----------------------- cmd/ipfs/runmain_test.go | 7 +- 13 files changed, 511 insertions(+), 497 deletions(-) rename cmd/ipfs/{ => kubo}/add_migrations.go (99%) rename cmd/ipfs/{ => kubo}/daemon.go (99%) rename cmd/ipfs/{ => kubo}/daemon_linux.go (95%) rename cmd/ipfs/{ => kubo}/daemon_other.go (86%) rename cmd/ipfs/{ => kubo}/debug.go (94%) rename cmd/ipfs/{ => kubo}/dnsresolve_test.go (99%) rename cmd/ipfs/{ => kubo}/init.go (99%) rename cmd/ipfs/{ => kubo}/ipfs.go (98%) rename cmd/ipfs/{ => kubo}/pinmfs.go (99%) rename cmd/ipfs/{ => kubo}/pinmfs_test.go (99%) create mode 100644 cmd/ipfs/kubo/start.go diff --git a/cmd/ipfs/add_migrations.go b/cmd/ipfs/kubo/add_migrations.go similarity index 99% rename from cmd/ipfs/add_migrations.go rename to cmd/ipfs/kubo/add_migrations.go index 14a98e04c..557a8de84 100644 --- a/cmd/ipfs/add_migrations.go +++ b/cmd/ipfs/kubo/add_migrations.go @@ -1,4 +1,4 @@ -package main +package kubo import ( "context" diff --git a/cmd/ipfs/daemon.go b/cmd/ipfs/kubo/daemon.go similarity index 99% rename from cmd/ipfs/daemon.go rename to cmd/ipfs/kubo/daemon.go index 4ad9b629c..31e5fe28d 100644 --- a/cmd/ipfs/daemon.go +++ b/cmd/ipfs/kubo/daemon.go @@ -1,4 +1,4 @@ -package main +package kubo import ( "errors" diff --git a/cmd/ipfs/daemon_linux.go b/cmd/ipfs/kubo/daemon_linux.go similarity index 95% rename from cmd/ipfs/daemon_linux.go rename to cmd/ipfs/kubo/daemon_linux.go index d06baf286..b612738a2 100644 --- a/cmd/ipfs/daemon_linux.go +++ b/cmd/ipfs/kubo/daemon_linux.go @@ -1,7 +1,7 @@ //go:build linux // +build linux -package main +package kubo import ( daemon "github.com/coreos/go-systemd/v22/daemon" diff --git a/cmd/ipfs/daemon_other.go b/cmd/ipfs/kubo/daemon_other.go similarity index 86% rename from cmd/ipfs/daemon_other.go rename to cmd/ipfs/kubo/daemon_other.go index cb96ce1b9..c5b24053d 100644 --- a/cmd/ipfs/daemon_other.go +++ b/cmd/ipfs/kubo/daemon_other.go @@ -1,7 +1,7 @@ //go:build !linux // +build !linux -package main +package kubo func notifyReady() {} diff --git a/cmd/ipfs/debug.go b/cmd/ipfs/kubo/debug.go similarity index 94% rename from cmd/ipfs/debug.go rename to cmd/ipfs/kubo/debug.go index f1b2683d1..ce07ca8e9 100644 --- a/cmd/ipfs/debug.go +++ b/cmd/ipfs/kubo/debug.go @@ -1,4 +1,4 @@ -package main +package kubo import ( "net/http" diff --git a/cmd/ipfs/dnsresolve_test.go b/cmd/ipfs/kubo/dnsresolve_test.go similarity index 99% rename from cmd/ipfs/dnsresolve_test.go rename to cmd/ipfs/kubo/dnsresolve_test.go index 8ffa0ebde..82e4e62f5 100644 --- a/cmd/ipfs/dnsresolve_test.go +++ b/cmd/ipfs/kubo/dnsresolve_test.go @@ -1,4 +1,4 @@ -package main +package kubo import ( "context" diff --git a/cmd/ipfs/init.go b/cmd/ipfs/kubo/init.go similarity index 99% rename from cmd/ipfs/init.go rename to cmd/ipfs/kubo/init.go index 82c622ab5..47aee7aeb 100644 --- a/cmd/ipfs/init.go +++ b/cmd/ipfs/kubo/init.go @@ -1,4 +1,4 @@ -package main +package kubo import ( "context" diff --git a/cmd/ipfs/ipfs.go b/cmd/ipfs/kubo/ipfs.go similarity index 98% rename from cmd/ipfs/ipfs.go rename to cmd/ipfs/kubo/ipfs.go index 3b953c40c..58310865e 100644 --- a/cmd/ipfs/ipfs.go +++ b/cmd/ipfs/kubo/ipfs.go @@ -1,4 +1,4 @@ -package main +package kubo import ( commands "github.com/ipfs/kubo/core/commands" diff --git a/cmd/ipfs/pinmfs.go b/cmd/ipfs/kubo/pinmfs.go similarity index 99% rename from cmd/ipfs/pinmfs.go rename to cmd/ipfs/kubo/pinmfs.go index 977d96ba0..846ee8a77 100644 --- a/cmd/ipfs/pinmfs.go +++ b/cmd/ipfs/kubo/pinmfs.go @@ -1,4 +1,4 @@ -package main +package kubo import ( "context" diff --git a/cmd/ipfs/pinmfs_test.go b/cmd/ipfs/kubo/pinmfs_test.go similarity index 99% rename from cmd/ipfs/pinmfs_test.go rename to cmd/ipfs/kubo/pinmfs_test.go index 7f1ac8696..da71d362c 100644 --- a/cmd/ipfs/pinmfs_test.go +++ b/cmd/ipfs/kubo/pinmfs_test.go @@ -1,4 +1,4 @@ -package main +package kubo import ( "context" diff --git a/cmd/ipfs/kubo/start.go b/cmd/ipfs/kubo/start.go new file mode 100644 index 000000000..2a97fd490 --- /dev/null +++ b/cmd/ipfs/kubo/start.go @@ -0,0 +1,494 @@ +// cmd/ipfs implements the primary CLI binary for ipfs +package kubo + +import ( + "bytes" + "context" + "encoding/json" + "errors" + "fmt" + "io" + "net" + "net/http" + "os" + "runtime/pprof" + "strings" + "time" + + "github.com/blang/semver/v4" + "github.com/google/uuid" + u "github.com/ipfs/boxo/util" + cmds "github.com/ipfs/go-ipfs-cmds" + "github.com/ipfs/go-ipfs-cmds/cli" + cmdhttp "github.com/ipfs/go-ipfs-cmds/http" + logging "github.com/ipfs/go-log" + ipfs "github.com/ipfs/kubo" + "github.com/ipfs/kubo/client/rpc/auth" + "github.com/ipfs/kubo/cmd/ipfs/util" + oldcmds "github.com/ipfs/kubo/commands" + config "github.com/ipfs/kubo/config" + "github.com/ipfs/kubo/core" + corecmds "github.com/ipfs/kubo/core/commands" + "github.com/ipfs/kubo/core/corehttp" + "github.com/ipfs/kubo/plugin/loader" + "github.com/ipfs/kubo/repo" + "github.com/ipfs/kubo/repo/fsrepo" + "github.com/ipfs/kubo/tracing" + ma "github.com/multiformats/go-multiaddr" + madns "github.com/multiformats/go-multiaddr-dns" + manet "github.com/multiformats/go-multiaddr/net" + "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" + "go.opentelemetry.io/contrib/propagators/autoprop" + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/codes" + "go.opentelemetry.io/otel/trace" +) + +// log is the command logger. +var ( + log = logging.Logger("cmd/ipfs") + tracer trace.Tracer +) + +// declared as a var for testing purposes. +var dnsResolver = madns.DefaultResolver + +const ( + EnvEnableProfiling = "IPFS_PROF" + cpuProfile = "ipfs.cpuprof" + heapProfile = "ipfs.memprof" +) + +type PluginPreloader func(*loader.PluginLoader) error + +func LoadPlugins(repoPath string, preload PluginPreloader) (*loader.PluginLoader, error) { + plugins, err := loader.NewPluginLoader(repoPath) + if err != nil { + return nil, fmt.Errorf("error loading plugins: %s", err) + } + + if preload != nil { + if err := preload(plugins); err != nil { + return nil, fmt.Errorf("error loading plugins (preload): %s", err) + } + } + + if err := plugins.Initialize(); err != nil { + return nil, fmt.Errorf("error initializing plugins: %s", err) + } + + if err := plugins.Inject(); err != nil { + return nil, fmt.Errorf("error initializing plugins: %s", err) + } + return plugins, nil +} + +// main roadmap: +// - parse the commandline to get a cmdInvocation +// - if user requests help, print it and exit. +// - run the command invocation +// - output the response +// - if anything fails, print error, maybe with help. +func main() { + os.Exit(Start(BuildDefaultEnv)) +} + +func printErr(err error) int { + fmt.Fprintf(os.Stderr, "Error: %s\n", err.Error()) + return 1 +} + +func newUUID(key string) logging.Metadata { + ids := "#UUID-ERROR#" + if id, err := uuid.NewRandom(); err == nil { + ids = id.String() + } + return logging.Metadata{ + key: ids, + } +} + +func BuildDefaultEnv(ctx context.Context, req *cmds.Request) (cmds.Environment, error) { + return BuildEnv(ctx, req, nil) +} + +func BuildEnv(ctx context.Context, req *cmds.Request, pl PluginPreloader) (cmds.Environment, error) { + checkDebug(req) + repoPath, err := GetRepoPath(req) + if err != nil { + return nil, err + } + log.Debugf("config path is %s", repoPath) + + plugins, err := LoadPlugins(repoPath, pl) + if err != nil { + return nil, err + } + + // this sets up the function that will initialize the node + // this is so that we can construct the node lazily. + return &oldcmds.Context{ + ConfigRoot: repoPath, + ReqLog: &oldcmds.ReqLog{}, + Plugins: plugins, + ConstructNode: func() (n *core.IpfsNode, err error) { + if req == nil { + return nil, errors.New("constructing node without a request") + } + + r, err := fsrepo.Open(repoPath) + if err != nil { // repo is owned by the node + return nil, err + } + + // ok everything is good. set it on the invocation (for ownership) + // and return it. + n, err = core.NewNode(ctx, &core.BuildCfg{ + Repo: r, + }) + if err != nil { + return nil, err + } + + return n, nil + }, + }, nil +} + +func Start(buildEnv func(ctx context.Context, req *cmds.Request) (cmds.Environment, error)) (exitCode int) { + ctx := logging.ContextWithLoggable(context.Background(), newUUID("session")) + + tp, err := tracing.NewTracerProvider(ctx) + if err != nil { + return printErr(err) + } + defer func() { + if err := tp.Shutdown(ctx); err != nil { + exitCode = printErr(err) + } + }() + otel.SetTracerProvider(tp) + otel.SetTextMapPropagator(autoprop.NewTextMapPropagator()) + tracer = tp.Tracer("Kubo-cli") + + stopFunc, err := profileIfEnabled() + if err != nil { + return printErr(err) + } + defer stopFunc() // to be executed as late as possible + + intrh, ctx := util.SetupInterruptHandler(ctx) + defer intrh.Close() + + // Handle `ipfs version` or `ipfs help` + if len(os.Args) > 1 { + // Handle `ipfs --version' + if os.Args[1] == "--version" { + os.Args[1] = "version" + } + + // Handle `ipfs help` and `ipfs help ` + if os.Args[1] == "help" { + if len(os.Args) > 2 { + os.Args = append(os.Args[:1], os.Args[2:]...) + // Handle `ipfs help --help` + // append `--help`,when the command is not `ipfs help --help` + if os.Args[1] != "--help" { + os.Args = append(os.Args, "--help") + } + } else { + os.Args[1] = "--help" + } + } + } else if insideGUI() { // if no args were passed, and we're in a GUI environment + // launch the daemon instead of launching a ghost window + os.Args = append(os.Args, "daemon", "--init") + } + + // output depends on executable name passed in os.Args + // so we need to make sure it's stable + os.Args[0] = "ipfs" + + err = cli.Run(ctx, Root, os.Args, os.Stdin, os.Stdout, os.Stderr, buildEnv, makeExecutor) + if err != nil { + return 1 + } + + // everything went better than expected :) + return 0 +} + +func insideGUI() bool { + return util.InsideGUI() +} + +func checkDebug(req *cmds.Request) { + // check if user wants to debug. option OR env var. + debug, _ := req.Options["debug"].(bool) + if debug || os.Getenv("IPFS_LOGGING") == "debug" { + u.Debug = true + logging.SetDebugLogging() + } + if u.GetenvBool("DEBUG") { + u.Debug = true + } +} + +func apiAddrOption(req *cmds.Request) (ma.Multiaddr, error) { + apiAddrStr, apiSpecified := req.Options[corecmds.ApiOption].(string) + if !apiSpecified { + return nil, nil + } + return ma.NewMultiaddr(apiAddrStr) +} + +// encodedAbsolutePathVersion is the version from which the absolute path header in +// multipart requests is %-encoded. Before this version, its sent raw. +var encodedAbsolutePathVersion = semver.MustParse("0.23.0-dev") + +func makeExecutor(req *cmds.Request, env interface{}) (cmds.Executor, error) { + exe := tracingWrappedExecutor{cmds.NewExecutor(req.Root)} + cctx := env.(*oldcmds.Context) + + // Check if the command is disabled. + if req.Command.NoLocal && req.Command.NoRemote { + return nil, fmt.Errorf("command disabled: %v", req.Path) + } + + // Can we just run this locally? + if !req.Command.NoLocal { + if doesNotUseRepo, ok := corecmds.GetDoesNotUseRepo(req.Command.Extra); doesNotUseRepo && ok { + return exe, nil + } + } + + // Get the API option from the commandline. + apiAddr, err := apiAddrOption(req) + if err != nil { + return nil, err + } + + // Require that the command be run on the daemon when the API flag is + // passed (unless we're trying to _run_ the daemon). + daemonRequested := apiAddr != nil && req.Command != daemonCmd + + // Run this on the client if required. + if req.Command.NoRemote { + if daemonRequested { + // User requested that the command be run on the daemon but we can't. + // NOTE: We drop this check for the `ipfs daemon` command. + return nil, errors.New("api flag specified but command cannot be run on the daemon") + } + return exe, nil + } + + // Finally, look in the repo for an API file. + if apiAddr == nil { + var err error + apiAddr, err = fsrepo.APIAddr(cctx.ConfigRoot) + switch err { + case nil, repo.ErrApiNotRunning: + default: + return nil, err + } + } + + // Still no api specified? Run it on the client or fail. + if apiAddr == nil { + if req.Command.NoLocal { + return nil, fmt.Errorf("command must be run on the daemon: %v", req.Path) + } + return exe, nil + } + + // Resolve the API addr. + apiAddr, err = resolveAddr(req.Context, apiAddr) + if err != nil { + return nil, err + } + network, host, err := manet.DialArgs(apiAddr) + if err != nil { + return nil, err + } + + // Construct the executor. + opts := []cmdhttp.ClientOpt{ + cmdhttp.ClientWithAPIPrefix(corehttp.APIPath), + } + + // Fallback on a local executor if we (a) have a repo and (b) aren't + // forcing a daemon. + if !daemonRequested && fsrepo.IsInitialized(cctx.ConfigRoot) { + opts = append(opts, cmdhttp.ClientWithFallback(exe)) + } + + var tpt http.RoundTripper + switch network { + case "tcp", "tcp4", "tcp6": + tpt = http.DefaultTransport + case "unix": + path := host + host = "unix" + tpt = &http.Transport{ + DialContext: func(_ context.Context, _, _ string) (net.Conn, error) { + return net.Dial("unix", path) + }, + } + default: + return nil, fmt.Errorf("unsupported API address: %s", apiAddr) + } + + apiAuth, specified := req.Options[corecmds.ApiAuthOption].(string) + if specified { + authorization := config.ConvertAuthSecret(apiAuth) + tpt = auth.NewAuthorizedRoundTripper(authorization, tpt) + } + + httpClient := &http.Client{ + Transport: otelhttp.NewTransport(tpt), + } + opts = append(opts, cmdhttp.ClientWithHTTPClient(httpClient)) + + // Fetch remove version, as some feature compatibility might change depending on it. + remoteVersion, err := getRemoteVersion(tracingWrappedExecutor{cmdhttp.NewClient(host, opts...)}) + if err != nil { + return nil, err + } + opts = append(opts, cmdhttp.ClientWithRawAbsPath(remoteVersion.LT(encodedAbsolutePathVersion))) + + return tracingWrappedExecutor{cmdhttp.NewClient(host, opts...)}, nil +} + +type tracingWrappedExecutor struct { + exec cmds.Executor +} + +func (twe tracingWrappedExecutor) Execute(req *cmds.Request, re cmds.ResponseEmitter, env cmds.Environment) error { + ctx, span := tracer.Start(req.Context, "cmds."+strings.Join(req.Path, "."), trace.WithAttributes(attribute.StringSlice("Arguments", req.Arguments))) + defer span.End() + req.Context = ctx + + err := twe.exec.Execute(req, re, env) + if err != nil { + span.SetStatus(codes.Error, err.Error()) + } + return err +} + +func GetRepoPath(req *cmds.Request) (string, error) { + repoOpt, found := req.Options[corecmds.RepoDirOption].(string) + if found && repoOpt != "" { + return repoOpt, nil + } + + repoPath, err := fsrepo.BestKnownPath() + if err != nil { + return "", err + } + return repoPath, nil +} + +// startProfiling begins CPU profiling and returns a `stop` function to be +// executed as late as possible. The stop function captures the memprofile. +func startProfiling() (func(), error) { + // start CPU profiling as early as possible + ofi, err := os.Create(cpuProfile) + if err != nil { + return nil, err + } + err = pprof.StartCPUProfile(ofi) + if err != nil { + ofi.Close() + return nil, err + } + go func() { + for range time.NewTicker(time.Second * 30).C { + err := writeHeapProfileToFile() + if err != nil { + log.Error(err) + } + } + }() + + stopProfiling := func() { + pprof.StopCPUProfile() + ofi.Close() // captured by the closure + } + return stopProfiling, nil +} + +func writeHeapProfileToFile() error { + mprof, err := os.Create(heapProfile) + if err != nil { + return err + } + defer mprof.Close() // _after_ writing the heap profile + return pprof.WriteHeapProfile(mprof) +} + +func profileIfEnabled() (func(), error) { + // FIXME this is a temporary hack so profiling of asynchronous operations + // works as intended. + if os.Getenv(EnvEnableProfiling) != "" { + stopProfilingFunc, err := startProfiling() // TODO maybe change this to its own option... profiling makes it slower. + if err != nil { + return nil, err + } + return stopProfilingFunc, nil + } + return func() {}, nil +} + +func resolveAddr(ctx context.Context, addr ma.Multiaddr) (ma.Multiaddr, error) { + ctx, cancelFunc := context.WithTimeout(ctx, 10*time.Second) + defer cancelFunc() + + addrs, err := dnsResolver.Resolve(ctx, addr) + if err != nil { + return nil, err + } + + if len(addrs) == 0 { + return nil, errors.New("non-resolvable API endpoint") + } + + return addrs[0], nil +} + +type nopWriter struct { + io.Writer +} + +func (nw nopWriter) Close() error { + return nil +} + +func getRemoteVersion(exe cmds.Executor) (*semver.Version, error) { + ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(time.Second*30)) + defer cancel() + + req, err := cmds.NewRequest(ctx, []string{"version"}, nil, nil, nil, Root) + if err != nil { + return nil, err + } + + var buf bytes.Buffer + re, err := cmds.NewWriterResponseEmitter(nopWriter{&buf}, req) + if err != nil { + return nil, err + } + + err = exe.Execute(req, re, nil) + if err != nil { + return nil, err + } + + var out ipfs.VersionInfo + dec := json.NewDecoder(&buf) + if err := dec.Decode(&out); err != nil { + return nil, err + } + + return semver.New(out.Version) +} diff --git a/cmd/ipfs/main.go b/cmd/ipfs/main.go index 9448a5ca9..ae7eedc0f 100644 --- a/cmd/ipfs/main.go +++ b/cmd/ipfs/main.go @@ -1,494 +1,11 @@ -// cmd/ipfs implements the primary CLI binary for ipfs package main import ( - "bytes" - "context" - "encoding/json" - "errors" - "fmt" - "io" - "net" - "net/http" "os" - "runtime/pprof" - "strings" - "time" - "github.com/blang/semver/v4" - "github.com/google/uuid" - u "github.com/ipfs/boxo/util" - cmds "github.com/ipfs/go-ipfs-cmds" - "github.com/ipfs/go-ipfs-cmds/cli" - cmdhttp "github.com/ipfs/go-ipfs-cmds/http" - logging "github.com/ipfs/go-log" - ipfs "github.com/ipfs/kubo" - "github.com/ipfs/kubo/client/rpc/auth" - "github.com/ipfs/kubo/cmd/ipfs/util" - oldcmds "github.com/ipfs/kubo/commands" - config "github.com/ipfs/kubo/config" - "github.com/ipfs/kubo/core" - corecmds "github.com/ipfs/kubo/core/commands" - "github.com/ipfs/kubo/core/corehttp" - "github.com/ipfs/kubo/plugin/loader" - "github.com/ipfs/kubo/repo" - "github.com/ipfs/kubo/repo/fsrepo" - "github.com/ipfs/kubo/tracing" - ma "github.com/multiformats/go-multiaddr" - madns "github.com/multiformats/go-multiaddr-dns" - manet "github.com/multiformats/go-multiaddr/net" - "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" - "go.opentelemetry.io/contrib/propagators/autoprop" - "go.opentelemetry.io/otel" - "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/codes" - "go.opentelemetry.io/otel/trace" + "github.com/ipfs/kubo/cmd/ipfs/kubo" ) -// log is the command logger. -var ( - log = logging.Logger("cmd/ipfs") - tracer trace.Tracer -) - -// declared as a var for testing purposes. -var dnsResolver = madns.DefaultResolver - -const ( - EnvEnableProfiling = "IPFS_PROF" - cpuProfile = "ipfs.cpuprof" - heapProfile = "ipfs.memprof" -) - -type PluginPreloader func(*loader.PluginLoader) error - -func LoadPlugins(repoPath string, preload PluginPreloader) (*loader.PluginLoader, error) { - plugins, err := loader.NewPluginLoader(repoPath) - if err != nil { - return nil, fmt.Errorf("error loading plugins: %s", err) - } - - if preload != nil { - if err := preload(plugins); err != nil { - return nil, fmt.Errorf("error loading plugins (preload): %s", err) - } - } - - if err := plugins.Initialize(); err != nil { - return nil, fmt.Errorf("error initializing plugins: %s", err) - } - - if err := plugins.Inject(); err != nil { - return nil, fmt.Errorf("error initializing plugins: %s", err) - } - return plugins, nil -} - -// main roadmap: -// - parse the commandline to get a cmdInvocation -// - if user requests help, print it and exit. -// - run the command invocation -// - output the response -// - if anything fails, print error, maybe with help. func main() { - os.Exit(Start(BuildDefaultEnv)) -} - -func printErr(err error) int { - fmt.Fprintf(os.Stderr, "Error: %s\n", err.Error()) - return 1 -} - -func newUUID(key string) logging.Metadata { - ids := "#UUID-ERROR#" - if id, err := uuid.NewRandom(); err == nil { - ids = id.String() - } - return logging.Metadata{ - key: ids, - } -} - -func BuildDefaultEnv(ctx context.Context, req *cmds.Request) (cmds.Environment, error) { - return BuildEnv(ctx, req, nil) -} - -func BuildEnv(ctx context.Context, req *cmds.Request, pl PluginPreloader) (cmds.Environment, error) { - checkDebug(req) - repoPath, err := GetRepoPath(req) - if err != nil { - return nil, err - } - log.Debugf("config path is %s", repoPath) - - plugins, err := LoadPlugins(repoPath, pl) - if err != nil { - return nil, err - } - - // this sets up the function that will initialize the node - // this is so that we can construct the node lazily. - return &oldcmds.Context{ - ConfigRoot: repoPath, - ReqLog: &oldcmds.ReqLog{}, - Plugins: plugins, - ConstructNode: func() (n *core.IpfsNode, err error) { - if req == nil { - return nil, errors.New("constructing node without a request") - } - - r, err := fsrepo.Open(repoPath) - if err != nil { // repo is owned by the node - return nil, err - } - - // ok everything is good. set it on the invocation (for ownership) - // and return it. - n, err = core.NewNode(ctx, &core.BuildCfg{ - Repo: r, - }) - if err != nil { - return nil, err - } - - return n, nil - }, - }, nil -} - -func Start(buildEnv func(ctx context.Context, req *cmds.Request) (cmds.Environment, error)) (exitCode int) { - ctx := logging.ContextWithLoggable(context.Background(), newUUID("session")) - - tp, err := tracing.NewTracerProvider(ctx) - if err != nil { - return printErr(err) - } - defer func() { - if err := tp.Shutdown(ctx); err != nil { - exitCode = printErr(err) - } - }() - otel.SetTracerProvider(tp) - otel.SetTextMapPropagator(autoprop.NewTextMapPropagator()) - tracer = tp.Tracer("Kubo-cli") - - stopFunc, err := profileIfEnabled() - if err != nil { - return printErr(err) - } - defer stopFunc() // to be executed as late as possible - - intrh, ctx := util.SetupInterruptHandler(ctx) - defer intrh.Close() - - // Handle `ipfs version` or `ipfs help` - if len(os.Args) > 1 { - // Handle `ipfs --version' - if os.Args[1] == "--version" { - os.Args[1] = "version" - } - - // Handle `ipfs help` and `ipfs help ` - if os.Args[1] == "help" { - if len(os.Args) > 2 { - os.Args = append(os.Args[:1], os.Args[2:]...) - // Handle `ipfs help --help` - // append `--help`,when the command is not `ipfs help --help` - if os.Args[1] != "--help" { - os.Args = append(os.Args, "--help") - } - } else { - os.Args[1] = "--help" - } - } - } else if insideGUI() { // if no args were passed, and we're in a GUI environment - // launch the daemon instead of launching a ghost window - os.Args = append(os.Args, "daemon", "--init") - } - - // output depends on executable name passed in os.Args - // so we need to make sure it's stable - os.Args[0] = "ipfs" - - err = cli.Run(ctx, Root, os.Args, os.Stdin, os.Stdout, os.Stderr, buildEnv, makeExecutor) - if err != nil { - return 1 - } - - // everything went better than expected :) - return 0 -} - -func insideGUI() bool { - return util.InsideGUI() -} - -func checkDebug(req *cmds.Request) { - // check if user wants to debug. option OR env var. - debug, _ := req.Options["debug"].(bool) - if debug || os.Getenv("IPFS_LOGGING") == "debug" { - u.Debug = true - logging.SetDebugLogging() - } - if u.GetenvBool("DEBUG") { - u.Debug = true - } -} - -func apiAddrOption(req *cmds.Request) (ma.Multiaddr, error) { - apiAddrStr, apiSpecified := req.Options[corecmds.ApiOption].(string) - if !apiSpecified { - return nil, nil - } - return ma.NewMultiaddr(apiAddrStr) -} - -// encodedAbsolutePathVersion is the version from which the absolute path header in -// multipart requests is %-encoded. Before this version, its sent raw. -var encodedAbsolutePathVersion = semver.MustParse("0.23.0-dev") - -func makeExecutor(req *cmds.Request, env interface{}) (cmds.Executor, error) { - exe := tracingWrappedExecutor{cmds.NewExecutor(req.Root)} - cctx := env.(*oldcmds.Context) - - // Check if the command is disabled. - if req.Command.NoLocal && req.Command.NoRemote { - return nil, fmt.Errorf("command disabled: %v", req.Path) - } - - // Can we just run this locally? - if !req.Command.NoLocal { - if doesNotUseRepo, ok := corecmds.GetDoesNotUseRepo(req.Command.Extra); doesNotUseRepo && ok { - return exe, nil - } - } - - // Get the API option from the commandline. - apiAddr, err := apiAddrOption(req) - if err != nil { - return nil, err - } - - // Require that the command be run on the daemon when the API flag is - // passed (unless we're trying to _run_ the daemon). - daemonRequested := apiAddr != nil && req.Command != daemonCmd - - // Run this on the client if required. - if req.Command.NoRemote { - if daemonRequested { - // User requested that the command be run on the daemon but we can't. - // NOTE: We drop this check for the `ipfs daemon` command. - return nil, errors.New("api flag specified but command cannot be run on the daemon") - } - return exe, nil - } - - // Finally, look in the repo for an API file. - if apiAddr == nil { - var err error - apiAddr, err = fsrepo.APIAddr(cctx.ConfigRoot) - switch err { - case nil, repo.ErrApiNotRunning: - default: - return nil, err - } - } - - // Still no api specified? Run it on the client or fail. - if apiAddr == nil { - if req.Command.NoLocal { - return nil, fmt.Errorf("command must be run on the daemon: %v", req.Path) - } - return exe, nil - } - - // Resolve the API addr. - apiAddr, err = resolveAddr(req.Context, apiAddr) - if err != nil { - return nil, err - } - network, host, err := manet.DialArgs(apiAddr) - if err != nil { - return nil, err - } - - // Construct the executor. - opts := []cmdhttp.ClientOpt{ - cmdhttp.ClientWithAPIPrefix(corehttp.APIPath), - } - - // Fallback on a local executor if we (a) have a repo and (b) aren't - // forcing a daemon. - if !daemonRequested && fsrepo.IsInitialized(cctx.ConfigRoot) { - opts = append(opts, cmdhttp.ClientWithFallback(exe)) - } - - var tpt http.RoundTripper - switch network { - case "tcp", "tcp4", "tcp6": - tpt = http.DefaultTransport - case "unix": - path := host - host = "unix" - tpt = &http.Transport{ - DialContext: func(_ context.Context, _, _ string) (net.Conn, error) { - return net.Dial("unix", path) - }, - } - default: - return nil, fmt.Errorf("unsupported API address: %s", apiAddr) - } - - apiAuth, specified := req.Options[corecmds.ApiAuthOption].(string) - if specified { - authorization := config.ConvertAuthSecret(apiAuth) - tpt = auth.NewAuthorizedRoundTripper(authorization, tpt) - } - - httpClient := &http.Client{ - Transport: otelhttp.NewTransport(tpt), - } - opts = append(opts, cmdhttp.ClientWithHTTPClient(httpClient)) - - // Fetch remove version, as some feature compatibility might change depending on it. - remoteVersion, err := getRemoteVersion(tracingWrappedExecutor{cmdhttp.NewClient(host, opts...)}) - if err != nil { - return nil, err - } - opts = append(opts, cmdhttp.ClientWithRawAbsPath(remoteVersion.LT(encodedAbsolutePathVersion))) - - return tracingWrappedExecutor{cmdhttp.NewClient(host, opts...)}, nil -} - -type tracingWrappedExecutor struct { - exec cmds.Executor -} - -func (twe tracingWrappedExecutor) Execute(req *cmds.Request, re cmds.ResponseEmitter, env cmds.Environment) error { - ctx, span := tracer.Start(req.Context, "cmds."+strings.Join(req.Path, "."), trace.WithAttributes(attribute.StringSlice("Arguments", req.Arguments))) - defer span.End() - req.Context = ctx - - err := twe.exec.Execute(req, re, env) - if err != nil { - span.SetStatus(codes.Error, err.Error()) - } - return err -} - -func GetRepoPath(req *cmds.Request) (string, error) { - repoOpt, found := req.Options[corecmds.RepoDirOption].(string) - if found && repoOpt != "" { - return repoOpt, nil - } - - repoPath, err := fsrepo.BestKnownPath() - if err != nil { - return "", err - } - return repoPath, nil -} - -// startProfiling begins CPU profiling and returns a `stop` function to be -// executed as late as possible. The stop function captures the memprofile. -func startProfiling() (func(), error) { - // start CPU profiling as early as possible - ofi, err := os.Create(cpuProfile) - if err != nil { - return nil, err - } - err = pprof.StartCPUProfile(ofi) - if err != nil { - ofi.Close() - return nil, err - } - go func() { - for range time.NewTicker(time.Second * 30).C { - err := writeHeapProfileToFile() - if err != nil { - log.Error(err) - } - } - }() - - stopProfiling := func() { - pprof.StopCPUProfile() - ofi.Close() // captured by the closure - } - return stopProfiling, nil -} - -func writeHeapProfileToFile() error { - mprof, err := os.Create(heapProfile) - if err != nil { - return err - } - defer mprof.Close() // _after_ writing the heap profile - return pprof.WriteHeapProfile(mprof) -} - -func profileIfEnabled() (func(), error) { - // FIXME this is a temporary hack so profiling of asynchronous operations - // works as intended. - if os.Getenv(EnvEnableProfiling) != "" { - stopProfilingFunc, err := startProfiling() // TODO maybe change this to its own option... profiling makes it slower. - if err != nil { - return nil, err - } - return stopProfilingFunc, nil - } - return func() {}, nil -} - -func resolveAddr(ctx context.Context, addr ma.Multiaddr) (ma.Multiaddr, error) { - ctx, cancelFunc := context.WithTimeout(ctx, 10*time.Second) - defer cancelFunc() - - addrs, err := dnsResolver.Resolve(ctx, addr) - if err != nil { - return nil, err - } - - if len(addrs) == 0 { - return nil, errors.New("non-resolvable API endpoint") - } - - return addrs[0], nil -} - -type nopWriter struct { - io.Writer -} - -func (nw nopWriter) Close() error { - return nil -} - -func getRemoteVersion(exe cmds.Executor) (*semver.Version, error) { - ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(time.Second*30)) - defer cancel() - - req, err := cmds.NewRequest(ctx, []string{"version"}, nil, nil, nil, Root) - if err != nil { - return nil, err - } - - var buf bytes.Buffer - re, err := cmds.NewWriterResponseEmitter(nopWriter{&buf}, req) - if err != nil { - return nil, err - } - - err = exe.Execute(req, re, nil) - if err != nil { - return nil, err - } - - var out ipfs.VersionInfo - dec := json.NewDecoder(&buf) - if err := dec.Decode(&out); err != nil { - return nil, err - } - - return semver.New(out.Version) + os.Exit(kubo.Start(kubo.BuildDefaultEnv)) } diff --git a/cmd/ipfs/runmain_test.go b/cmd/ipfs/runmain_test.go index b09a25226..a37ec194c 100644 --- a/cmd/ipfs/runmain_test.go +++ b/cmd/ipfs/runmain_test.go @@ -1,13 +1,15 @@ //go:build testrunmain // +build testrunmain -package main +package main_test import ( "flag" "fmt" "os" "testing" + + "github.com/ipfs/kubo/cmd/ipfs/kubo" ) // this abuses go so much that I felt dirty writing this code @@ -16,7 +18,8 @@ import ( func TestRunMain(t *testing.T) { args := flag.Args() os.Args = append([]string{os.Args[0]}, args...) - ret := Start() + + ret := kubo.Start(kubo.BuildDefaultEnv) p := os.Getenv("IPFS_COVER_RET_FILE") if len(p) != 0 { From a8a12789f2f53849950ddcc1c28b940d84a01341 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 30 Mar 2023 19:36:33 +0200 Subject: [PATCH 0969/1212] feat: cmd/ipfs: Nicer to use BuildEnv --- cmd/ipfs/kubo/start.go | 84 +++++++++++++++++++++--------------------- 1 file changed, 43 insertions(+), 41 deletions(-) diff --git a/cmd/ipfs/kubo/start.go b/cmd/ipfs/kubo/start.go index 2a97fd490..13fad8387 100644 --- a/cmd/ipfs/kubo/start.go +++ b/cmd/ipfs/kubo/start.go @@ -110,50 +110,52 @@ func newUUID(key string) logging.Metadata { } func BuildDefaultEnv(ctx context.Context, req *cmds.Request) (cmds.Environment, error) { - return BuildEnv(ctx, req, nil) + return BuildEnv(nil)(ctx, req) } -func BuildEnv(ctx context.Context, req *cmds.Request, pl PluginPreloader) (cmds.Environment, error) { - checkDebug(req) - repoPath, err := GetRepoPath(req) - if err != nil { - return nil, err +func BuildEnv(pl PluginPreloader) func(ctx context.Context, req *cmds.Request) (cmds.Environment, error) { + return func(ctx context.Context, req *cmds.Request) (cmds.Environment, error) { + checkDebug(req) + repoPath, err := GetRepoPath(req) + if err != nil { + return nil, err + } + log.Debugf("config path is %s", repoPath) + + plugins, err := LoadPlugins(repoPath, pl) + if err != nil { + return nil, err + } + + // this sets up the function that will initialize the node + // this is so that we can construct the node lazily. + return &oldcmds.Context{ + ConfigRoot: repoPath, + ReqLog: &oldcmds.ReqLog{}, + Plugins: plugins, + ConstructNode: func() (n *core.IpfsNode, err error) { + if req == nil { + return nil, errors.New("constructing node without a request") + } + + r, err := fsrepo.Open(repoPath) + if err != nil { // repo is owned by the node + return nil, err + } + + // ok everything is good. set it on the invocation (for ownership) + // and return it. + n, err = core.NewNode(ctx, &core.BuildCfg{ + Repo: r, + }) + if err != nil { + return nil, err + } + + return n, nil + }, + }, nil } - log.Debugf("config path is %s", repoPath) - - plugins, err := LoadPlugins(repoPath, pl) - if err != nil { - return nil, err - } - - // this sets up the function that will initialize the node - // this is so that we can construct the node lazily. - return &oldcmds.Context{ - ConfigRoot: repoPath, - ReqLog: &oldcmds.ReqLog{}, - Plugins: plugins, - ConstructNode: func() (n *core.IpfsNode, err error) { - if req == nil { - return nil, errors.New("constructing node without a request") - } - - r, err := fsrepo.Open(repoPath) - if err != nil { // repo is owned by the node - return nil, err - } - - // ok everything is good. set it on the invocation (for ownership) - // and return it. - n, err = core.NewNode(ctx, &core.BuildCfg{ - Repo: r, - }) - if err != nil { - return nil, err - } - - return n, nil - }, - }, nil } func Start(buildEnv func(ctx context.Context, req *cmds.Request) (cmds.Environment, error)) (exitCode int) { From 0e83c3f2f964e9f26f25e77cb2fbf648c0fce5fa Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Tue, 14 Nov 2023 15:54:19 +0100 Subject: [PATCH 0970/1212] remove old main function --- cmd/ipfs/kubo/start.go | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/cmd/ipfs/kubo/start.go b/cmd/ipfs/kubo/start.go index 13fad8387..c60850d4b 100644 --- a/cmd/ipfs/kubo/start.go +++ b/cmd/ipfs/kubo/start.go @@ -84,16 +84,6 @@ func LoadPlugins(repoPath string, preload PluginPreloader) (*loader.PluginLoader return plugins, nil } -// main roadmap: -// - parse the commandline to get a cmdInvocation -// - if user requests help, print it and exit. -// - run the command invocation -// - output the response -// - if anything fails, print error, maybe with help. -func main() { - os.Exit(Start(BuildDefaultEnv)) -} - func printErr(err error) int { fmt.Fprintf(os.Stderr, "Error: %s\n", err.Error()) return 1 @@ -158,6 +148,12 @@ func BuildEnv(pl PluginPreloader) func(ctx context.Context, req *cmds.Request) ( } } +// Start roadmap: +// - parse the commandline to get a cmdInvocation +// - if user requests help, print it and exit. +// - run the command invocation +// - output the response +// - if anything fails, print error, maybe with help. func Start(buildEnv func(ctx context.Context, req *cmds.Request) (cmds.Environment, error)) (exitCode int) { ctx := logging.ContextWithLoggable(context.Background(), newUUID("session")) From e503c843b8174382e69cdfdcca25f7caef9f462b Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Tue, 19 Dec 2023 19:52:02 -0500 Subject: [PATCH 0971/1212] feat: unexport unneeded functions and add comments --- cmd/ipfs/kubo/start.go | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/cmd/ipfs/kubo/start.go b/cmd/ipfs/kubo/start.go index c60850d4b..cae1e2c1b 100644 --- a/cmd/ipfs/kubo/start.go +++ b/cmd/ipfs/kubo/start.go @@ -1,4 +1,4 @@ -// cmd/ipfs implements the primary CLI binary for ipfs +// cmd/ipfs/kubo implements the primary CLI binary for kubo package kubo import ( @@ -62,7 +62,7 @@ const ( type PluginPreloader func(*loader.PluginLoader) error -func LoadPlugins(repoPath string, preload PluginPreloader) (*loader.PluginLoader, error) { +func loadPlugins(repoPath string, preload PluginPreloader) (*loader.PluginLoader, error) { plugins, err := loader.NewPluginLoader(repoPath) if err != nil { return nil, fmt.Errorf("error loading plugins: %s", err) @@ -103,16 +103,18 @@ func BuildDefaultEnv(ctx context.Context, req *cmds.Request) (cmds.Environment, return BuildEnv(nil)(ctx, req) } +// BuildEnv creates an environment to be used with the kubo CLI. Note: the plugin preloader should only call functions +// associated with preloaded plugins (i.e. Load). func BuildEnv(pl PluginPreloader) func(ctx context.Context, req *cmds.Request) (cmds.Environment, error) { return func(ctx context.Context, req *cmds.Request) (cmds.Environment, error) { checkDebug(req) - repoPath, err := GetRepoPath(req) + repoPath, err := getRepoPath(req) if err != nil { return nil, err } log.Debugf("config path is %s", repoPath) - plugins, err := LoadPlugins(repoPath, pl) + plugins, err := loadPlugins(repoPath, pl) if err != nil { return nil, err } @@ -374,7 +376,7 @@ func (twe tracingWrappedExecutor) Execute(req *cmds.Request, re cmds.ResponseEmi return err } -func GetRepoPath(req *cmds.Request) (string, error) { +func getRepoPath(req *cmds.Request) (string, error) { repoOpt, found := req.Options[corecmds.RepoDirOption].(string) if found && repoOpt != "" { return repoOpt, nil From 33b785ebd9f5c224f5c14b386800043f9549ccd2 Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Tue, 19 Dec 2023 16:52:07 -0500 Subject: [PATCH 0972/1212] docs(customizing.md): add kubo binary imports description --- docs/customizing.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/customizing.md b/docs/customizing.md index 4db3c3431..0f078999f 100644 --- a/docs/customizing.md +++ b/docs/customizing.md @@ -36,6 +36,12 @@ For more information about the different types of Kubo plugins, see [plugins.md] Kubo plugins can also be injected at runtime using Go plugins (see below), but these are hard to use and not well supported by Go, so we don't recommend them. +### Kubo binary imports + +It is possible to depend on the package `cmd/ipfs/kubo` as a way of using Kubo plugins that is an alternative to recompiling Kubo with additional preloaded plugins. + +This gives a more Go-centric dependency updating flow to building a new binary with preloaded plugins by simply requiring updating a Kubo dependency rather than needing to update Kubo source code and recompile. + ## Bespoke Extension Points Certain Kubo functionality may have their own extension points. For example: From 287444bc6e56ac9bdcbb797c75ce51d0e584aea3 Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Tue, 19 Dec 2023 15:43:03 -0500 Subject: [PATCH 0973/1212] chore: update changelog --- docs/changelogs/v0.26.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/changelogs/v0.26.md b/docs/changelogs/v0.26.md index a5d02df63..3a9f088ca 100644 --- a/docs/changelogs/v0.26.md +++ b/docs/changelogs/v0.26.md @@ -14,6 +14,12 @@ ### 🔦 Highlights +#### Kubo binary imports + +For users of [Kubo preloaded plugins](https://github.com/ipfs/kubo/blob/master/docs/plugins.md#preloaded-plugins) there is now a way to create a kubo instance with your plugins by depending on the `cmd/ipfs/kubo` package rather than rebuilding kubo with the included plugins. + +See the [customization docs](https://github.com/ipfs/kubo/blob/master/docs/customizing.md) for more information. + #### Several deprecated commands have been removed Several deprecated commands have been removed: @@ -26,4 +32,6 @@ Several deprecated commands have been removed: ### 📝 Changelog +- Export a `kubo.Start` function so users can programmatically start Kubo from within a go program. + ### 👨‍👩‍👧‍👦 Contributors From f71ae3935d6fafc1fa4d36e010404aa5eee0eafb Mon Sep 17 00:00:00 2001 From: Nicholas Ericksen Date: Thu, 21 Dec 2023 02:40:50 -0500 Subject: [PATCH 0974/1212] docs: fix broken link in HTTP RPC client doc (#10267) --- docs/http-rpc-clients.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/http-rpc-clients.md b/docs/http-rpc-clients.md index 74094a4ca..31448cb86 100644 --- a/docs/http-rpc-clients.md +++ b/docs/http-rpc-clients.md @@ -5,4 +5,4 @@ Kubo provides official HTTP RPC (`/api/v0`) clients for selected languages: | Language | Package Name | Github Repository | |:--------:|:-------------------:|--------------------------------------------| | JS | kubo-rpc-client | https://github.com/ipfs/js-kubo-rpc-client | -| Go | `rpc` | [`./client/rpc`](./client/rpc) | +| Go | `rpc` | [`../client/rpc`](../client/rpc) | From 16494692efa8a092ed00f01e1740893f93e69716 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Fri, 29 Dec 2023 03:44:23 +0100 Subject: [PATCH 0975/1212] chore: update go-libp2p-asn-util Include memory usage fixes from libp2p/go-libp2p-asn-util#33. --- docs/examples/kubo-as-a-library/go.mod | 4 ++-- docs/examples/kubo-as-a-library/go.sum | 8 ++++---- go.mod | 4 ++-- go.sum | 8 ++++---- test/dependencies/go.mod | 4 ++-- test/dependencies/go.sum | 8 ++++---- 6 files changed, 18 insertions(+), 18 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 2ad0ae269..34b101c9a 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -100,7 +100,7 @@ require ( github.com/libp2p/go-cidranger v1.1.0 // indirect github.com/libp2p/go-doh-resolver v0.4.0 // indirect github.com/libp2p/go-flow-metrics v0.1.0 // indirect - github.com/libp2p/go-libp2p-asn-util v0.3.0 // indirect + github.com/libp2p/go-libp2p-asn-util v0.4.1 // indirect github.com/libp2p/go-libp2p-kad-dht v0.24.4 // indirect github.com/libp2p/go-libp2p-kbucket v0.6.3 // indirect github.com/libp2p/go-libp2p-pubsub v0.10.0 // indirect @@ -197,7 +197,7 @@ require ( go.uber.org/zap v1.26.0 // indirect go4.org v0.0.0-20230225012048-214862532bf5 // indirect golang.org/x/crypto v0.16.0 // indirect - golang.org/x/exp v0.0.0-20231127185646-65229373498e // indirect + golang.org/x/exp v0.0.0-20231214170342-aacd6d4b4611 // indirect golang.org/x/mod v0.14.0 // indirect golang.org/x/net v0.19.0 // indirect golang.org/x/sync v0.5.0 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index d82db17e0..9d63ebb13 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -455,8 +455,8 @@ github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFG github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= github.com/libp2p/go-libp2p v0.32.2 h1:s8GYN4YJzgUoyeYNPdW7JZeZ5Ee31iNaIBfGYMAY4FQ= github.com/libp2p/go-libp2p v0.32.2/go.mod h1:E0LKe+diV/ZVJVnOJby8VC5xzHF0660osg71skcxJvk= -github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= -github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= +github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94= +github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= github.com/libp2p/go-libp2p-core v0.3.0/go.mod h1:ACp3DmS3/N64c2jDzcV429ukDpicbL6+TrrxANBjPGw= github.com/libp2p/go-libp2p-kad-dht v0.24.4 h1:ktNiJe7ffsJ1wX3ULpMCwXts99mPqGFSE/Qn1i8pErQ= @@ -894,8 +894,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20231127185646-65229373498e h1:Gvh4YaCaXNs6dKTlfgismwWZKyjVZXwOPfIyUaqU3No= -golang.org/x/exp v0.0.0-20231127185646-65229373498e/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI= +golang.org/x/exp v0.0.0-20231214170342-aacd6d4b4611 h1:qCEDpW1G+vcj3Y7Fy52pEM1AWm3abj8WimGYejI3SC4= +golang.org/x/exp v0.0.0-20231214170342-aacd6d4b4611/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= diff --git a/go.mod b/go.mod index 1c1f5e5d4..74b4cd347 100644 --- a/go.mod +++ b/go.mod @@ -84,7 +84,7 @@ require ( go.uber.org/multierr v1.11.0 go.uber.org/zap v1.26.0 golang.org/x/crypto v0.16.0 - golang.org/x/exp v0.0.0-20231127185646-65229373498e + golang.org/x/exp v0.0.0-20231214170342-aacd6d4b4611 golang.org/x/mod v0.14.0 golang.org/x/sync v0.5.0 golang.org/x/sys v0.15.0 @@ -152,7 +152,7 @@ require ( github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/libp2p/go-cidranger v1.1.0 // indirect github.com/libp2p/go-flow-metrics v0.1.0 // indirect - github.com/libp2p/go-libp2p-asn-util v0.3.0 // indirect + github.com/libp2p/go-libp2p-asn-util v0.4.1 // indirect github.com/libp2p/go-libp2p-gostream v0.6.0 // indirect github.com/libp2p/go-libp2p-xor v0.1.0 // indirect github.com/libp2p/go-msgio v0.3.0 // indirect diff --git a/go.sum b/go.sum index 09b15e67f..f69fbedd0 100644 --- a/go.sum +++ b/go.sum @@ -513,8 +513,8 @@ github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFG github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= github.com/libp2p/go-libp2p v0.32.2 h1:s8GYN4YJzgUoyeYNPdW7JZeZ5Ee31iNaIBfGYMAY4FQ= github.com/libp2p/go-libp2p v0.32.2/go.mod h1:E0LKe+diV/ZVJVnOJby8VC5xzHF0660osg71skcxJvk= -github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= -github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= +github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94= +github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= github.com/libp2p/go-libp2p-core v0.3.0/go.mod h1:ACp3DmS3/N64c2jDzcV429ukDpicbL6+TrrxANBjPGw= github.com/libp2p/go-libp2p-gostream v0.6.0 h1:QfAiWeQRce6pqnYfmIVWJFXNdDyfiR/qkCnjyaZUPYU= @@ -1033,8 +1033,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20231127185646-65229373498e h1:Gvh4YaCaXNs6dKTlfgismwWZKyjVZXwOPfIyUaqU3No= -golang.org/x/exp v0.0.0-20231127185646-65229373498e/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI= +golang.org/x/exp v0.0.0-20231214170342-aacd6d4b4611 h1:qCEDpW1G+vcj3Y7Fy52pEM1AWm3abj8WimGYejI3SC4= +golang.org/x/exp v0.0.0-20231214170342-aacd6d4b4611/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index b726fb5b0..e55e9f10c 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -134,7 +134,7 @@ require ( github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/libp2p/go-cidranger v1.1.0 // indirect github.com/libp2p/go-libp2p v0.32.2 // indirect - github.com/libp2p/go-libp2p-asn-util v0.3.0 // indirect + github.com/libp2p/go-libp2p-asn-util v0.4.1 // indirect github.com/libp2p/go-libp2p-kad-dht v0.24.4 // indirect github.com/libp2p/go-libp2p-kbucket v0.6.3 // indirect github.com/libp2p/go-libp2p-record v0.2.0 // indirect @@ -240,7 +240,7 @@ require ( go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.26.0 // indirect golang.org/x/crypto v0.16.0 // indirect - golang.org/x/exp v0.0.0-20231127185646-65229373498e // indirect + golang.org/x/exp v0.0.0-20231214170342-aacd6d4b4611 // indirect golang.org/x/exp/typeparams v0.0.0-20230307190834-24139beb5833 // indirect golang.org/x/mod v0.14.0 // indirect golang.org/x/net v0.19.0 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 047bf5f5a..35f92c1a8 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -451,8 +451,8 @@ github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0 github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-libp2p v0.32.2 h1:s8GYN4YJzgUoyeYNPdW7JZeZ5Ee31iNaIBfGYMAY4FQ= github.com/libp2p/go-libp2p v0.32.2/go.mod h1:E0LKe+diV/ZVJVnOJby8VC5xzHF0660osg71skcxJvk= -github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= -github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= +github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94= +github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= github.com/libp2p/go-libp2p-kad-dht v0.24.4 h1:ktNiJe7ffsJ1wX3ULpMCwXts99mPqGFSE/Qn1i8pErQ= github.com/libp2p/go-libp2p-kad-dht v0.24.4/go.mod h1:ybWBJ5Fbvz9sSLkNtXt+2+bK0JB8+tRPvhBbRGHegRU= github.com/libp2p/go-libp2p-kbucket v0.6.3 h1:p507271wWzpy2f1XxPzCQG9NiN6R6lHL9GiSErbQQo0= @@ -818,8 +818,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20231127185646-65229373498e h1:Gvh4YaCaXNs6dKTlfgismwWZKyjVZXwOPfIyUaqU3No= -golang.org/x/exp v0.0.0-20231127185646-65229373498e/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI= +golang.org/x/exp v0.0.0-20231214170342-aacd6d4b4611 h1:qCEDpW1G+vcj3Y7Fy52pEM1AWm3abj8WimGYejI3SC4= +golang.org/x/exp v0.0.0-20231214170342-aacd6d4b4611/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI= golang.org/x/exp/typeparams v0.0.0-20220428152302-39d4317da171/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/exp/typeparams v0.0.0-20230203172020-98cc5a0785f9/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/exp/typeparams v0.0.0-20230307190834-24139beb5833 h1:jWGQJV4niP+CCmFW9ekjA9Zx8vYORzOUH2/Nl5WPuLQ= From 765cffe6c2b7d0a9d757bbdb476cc0ea15fd287c Mon Sep 17 00:00:00 2001 From: Jorropo Date: Fri, 29 Dec 2023 04:10:27 +0100 Subject: [PATCH 0976/1212] build,docker: add support for riscv64 --- .github/workflows/docker-image.yml | 15 ++++++++++++++- mk/util.mk | 1 + 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index c1e77112d..826bfad85 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -107,18 +107,31 @@ jobs: cache-from: type=local,src=/tmp/.buildx-cache cache-to: type=local,dest=/tmp/.buildx-cache-new + - name: Build Docker image (linux/riscv64) + uses: docker/build-push-action@v4 + with: + platforms: linux/riscv64 + context: . + push: false + load: true + file: ./Dockerfile + tags: ${{ env.IMAGE_NAME }}:linux-riscv64 + cache-from: type=local,src=/tmp/.buildx-cache + cache-to: type=local,dest=/tmp/.buildx-cache-new + # We test all the images on amd64 host here. This uses QEMU to emulate # the other platforms. - run: docker run --rm $IMAGE_NAME:linux-amd64 --version - run: docker run --rm $IMAGE_NAME:linux-arm-v7 --version - run: docker run --rm $IMAGE_NAME:linux-arm64-v8 --version + - run: docker run --rm $IMAGE_NAME:linux-riscv64 --version # This will only push the previously built images. - if: github.event_name != 'workflow_dispatch' || github.event.inputs.push == 'true' name: Publish to Docker Hub uses: docker/build-push-action@v4 with: - platforms: linux/amd64,linux/arm/v7,linux/arm64/v8 + platforms: linux/amd64,linux/arm/v7,linux/arm64/v8,linux/riscv64 context: . push: true file: ./Dockerfile diff --git a/mk/util.mk b/mk/util.mk index 2ce48583f..50040c17a 100644 --- a/mk/util.mk +++ b/mk/util.mk @@ -16,6 +16,7 @@ SUPPORTED_PLATFORMS += linux-arm SUPPORTED_PLATFORMS += linux-arm64 SUPPORTED_PLATFORMS += linux-386 SUPPORTED_PLATFORMS += linux-amd64 +SUPPORTED_PLATFORMS += linux-riscv64 SUPPORTED_PLATFORMS += darwin-amd64 ifeq ($(shell bin/check_go_version "1.16.0" 2>/dev/null; echo $$?),0) From a8a6bbe929b0a821d854a20e3f5ed68f6cfe601c Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Thu, 4 Jan 2024 14:25:06 +0100 Subject: [PATCH 0977/1212] feat: support optional pin names (#10261) --- client/rpc/pin.go | 8 +++- cmd/ipfs/kubo/init.go | 2 +- core/commands/dag/import.go | 2 +- core/commands/pin/pin.go | 66 ++++++++++++++++++++------ core/coreapi/block.go | 2 +- core/coreapi/dag.go | 4 +- core/coreapi/object.go | 2 +- core/coreapi/pin.go | 40 +++++++++------- core/coreiface/options/pin.go | 21 +++++++- core/coreiface/pin.go | 3 ++ core/coreunix/add.go | 2 +- docs/changelogs/v0.26.md | 5 ++ docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 +- fuse/ipns/common.go | 2 +- gc/gc.go | 16 +++---- gc/gc_test.go | 4 +- go.mod | 2 +- go.sum | 4 +- test/cli/pins_test.go | 63 ++++++++++++++++++++++++ test/dependencies/go.mod | 2 +- test/dependencies/go.sum | 4 +- 22 files changed, 200 insertions(+), 60 deletions(-) diff --git a/client/rpc/pin.go b/client/rpc/pin.go index 632d8f08d..a0469861c 100644 --- a/client/rpc/pin.go +++ b/client/rpc/pin.go @@ -26,6 +26,7 @@ type pinRefKeyList struct { type pin struct { path path.ImmutablePath typ string + name string err error } @@ -37,6 +38,10 @@ func (p pin) Path() path.ImmutablePath { return p.path } +func (p pin) Name() string { + return p.name +} + func (p pin) Type() string { return p.typ } @@ -53,6 +58,7 @@ func (api *PinAPI) Add(ctx context.Context, p path.Path, opts ...caopts.PinAddOp type pinLsObject struct { Cid string + Name string Type string } @@ -102,7 +108,7 @@ func (api *PinAPI) Ls(ctx context.Context, opts ...caopts.PinLsOption) (<-chan i } select { - case ch <- pin{typ: out.Type, path: path.FromCid(c)}: + case ch <- pin{typ: out.Type, name: out.Name, path: path.FromCid(c)}: case <-ctx.Done(): return } diff --git a/cmd/ipfs/kubo/init.go b/cmd/ipfs/kubo/init.go index 47aee7aeb..986fe90c8 100644 --- a/cmd/ipfs/kubo/init.go +++ b/cmd/ipfs/kubo/init.go @@ -252,7 +252,7 @@ func initializeIpnsKeyspace(repoRoot string) error { // pin recursively because this might already be pinned // and doing a direct pin would throw an error in that case - err = nd.Pinning.Pin(ctx, emptyDir, true) + err = nd.Pinning.Pin(ctx, emptyDir, true, "") if err != nil { return err } diff --git a/core/commands/dag/import.go b/core/commands/dag/import.go index d95ff7198..5e39393c1 100644 --- a/core/commands/dag/import.go +++ b/core/commands/dag/import.go @@ -152,7 +152,7 @@ func dagImport(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment ret.PinErrorMsg = err.Error() } else if nd, err := blockDecoder.DecodeNode(req.Context, block); err != nil { ret.PinErrorMsg = err.Error() - } else if err := node.Pinning.Pin(req.Context, nd, true); err != nil { + } else if err := node.Pinning.Pin(req.Context, nd, true, ""); err != nil { ret.PinErrorMsg = err.Error() } else if err := node.Pinning.Flush(req.Context); err != nil { ret.PinErrorMsg = err.Error() diff --git a/core/commands/pin/pin.go b/core/commands/pin/pin.go index db623a7e6..d75d5d386 100644 --- a/core/commands/pin/pin.go +++ b/core/commands/pin/pin.go @@ -57,6 +57,28 @@ var addPinCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "Pin objects to local storage.", ShortDescription: "Stores an IPFS object(s) from a given path locally to disk.", + LongDescription: ` +Create a pin for the given object, protecting resolved CID from being garbage +collected. + +An optional name can be provided, and read back via 'ipfs pin ls --names'. + +Be mindful of defaults: + +Default pin type is 'recursive' (entire DAG). +Pass -r=false to create a direct pin for a single block. +Use 'pin ls -t recursive' to only list roots of recursively pinned DAGs +(significantly faster when many big DAGs are pinned recursively) + +Default pin name is empty. Pass '--name' to 'pin add' to set one +and use 'pin ls --names' to see it. +Pin add is idempotent: pinning CID which is already pinned won't change +the name, value passed with '--name' with the original pin is preserved. +To rename pin, use 'pin rm' and 'pin add --name'. + +If daemon is running, any missing blocks will be retrieved from the network. +It may take some time. Pass '--progress' to track the progress. +`, }, Arguments: []cmds.Argument{ @@ -64,6 +86,7 @@ var addPinCmd = &cmds.Command{ }, Options: []cmds.Option{ cmds.BoolOption(pinRecursiveOptionName, "r", "Recursively pin the object linked to by the specified object(s).").WithDefault(true), + cmds.StringOption(pinNameOptionName, "n", "An optional name for created pin(s)."), cmds.BoolOption(pinProgressOptionName, "Show progress"), }, Type: AddPinOutput{}, @@ -75,6 +98,7 @@ var addPinCmd = &cmds.Command{ // set recursive flag recursive, _ := req.Options[pinRecursiveOptionName].(bool) + name, _ := req.Options[pinNameOptionName].(string) showProgress, _ := req.Options[pinProgressOptionName].(bool) if err := req.ParseBodyArgs(); err != nil { @@ -87,7 +111,7 @@ var addPinCmd = &cmds.Command{ } if !showProgress { - added, err := pinAddMany(req.Context, api, enc, req.Arguments, recursive) + added, err := pinAddMany(req.Context, api, enc, req.Arguments, recursive, name) if err != nil { return err } @@ -105,7 +129,7 @@ var addPinCmd = &cmds.Command{ ch := make(chan pinResult, 1) go func() { - added, err := pinAddMany(ctx, api, enc, req.Arguments, recursive) + added, err := pinAddMany(ctx, api, enc, req.Arguments, recursive, name) ch <- pinResult{pins: added, err: err} }() @@ -181,7 +205,7 @@ var addPinCmd = &cmds.Command{ }, } -func pinAddMany(ctx context.Context, api coreiface.CoreAPI, enc cidenc.Encoder, paths []string, recursive bool) ([]string, error) { +func pinAddMany(ctx context.Context, api coreiface.CoreAPI, enc cidenc.Encoder, paths []string, recursive bool, name string) ([]string, error) { added := make([]string, len(paths)) for i, b := range paths { p, err := cmdutils.PathOrCidPath(b) @@ -194,7 +218,7 @@ func pinAddMany(ctx context.Context, api coreiface.CoreAPI, enc cidenc.Encoder, return nil, err } - if err := api.Pin().Add(ctx, rp, options.Pin.Recursive(recursive)); err != nil { + if err := api.Pin().Add(ctx, rp, options.Pin.Recursive(recursive), options.Pin.Name(name)); err != nil { return nil, err } added[i] = enc.Encode(rp.RootCid()) @@ -281,6 +305,7 @@ const ( pinTypeOptionName = "type" pinQuietOptionName = "quiet" pinStreamOptionName = "stream" + pinNamesOptionName = "names" ) var listPinCmd = &cmds.Command{ @@ -294,6 +319,7 @@ respectively. `, LongDescription: ` Returns a list of objects that are pinned locally. + By default, all pinned objects are returned, but the '--type' flag or arguments can restrict that to a specific pin type or to some specific objects respectively. @@ -302,10 +328,13 @@ Use --type= to specify the type of pinned keys to list. Valid values are: * "direct": pin that specific object. * "recursive": pin that specific object, and indirectly pin all its - descendants + descendants * "indirect": pinned indirectly by an ancestor (like a refcount) * "all" +By default, pin names are not included (returned as empty). +Pass '--names' flag to return pin names (set with '--name' from 'pin add'). + With arguments, the command fails if any of the arguments is not a pinned object. And if --type= is additionally used, the command will also fail if any of the arguments is not of the specified type. @@ -334,6 +363,7 @@ Example: cmds.StringOption(pinTypeOptionName, "t", "The type of pinned keys to list. Can be \"direct\", \"indirect\", \"recursive\", or \"all\".").WithDefault("all"), cmds.BoolOption(pinQuietOptionName, "q", "Write just hashes of objects."), cmds.BoolOption(pinStreamOptionName, "s", "Enable streaming of pins as they are discovered."), + cmds.BoolOption(pinNamesOptionName, "n", "Enable displaying pin names (slower)."), }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { api, err := cmdenv.GetApi(env, req) @@ -343,6 +373,7 @@ Example: typeStr, _ := req.Options[pinTypeOptionName].(string) stream, _ := req.Options[pinStreamOptionName].(bool) + displayNames, _ := req.Options[pinNamesOptionName].(bool) switch typeStr { case "all", "direct", "indirect", "recursive": @@ -356,7 +387,7 @@ Example: lgcList := map[string]PinLsType{} if !stream { emit = func(v PinLsOutputWrapper) error { - lgcList[v.PinLsObject.Cid] = PinLsType{Type: v.PinLsObject.Type} + lgcList[v.PinLsObject.Cid] = PinLsType{Type: v.PinLsObject.Type, Name: v.PinLsObject.Name} return nil } } else { @@ -368,7 +399,7 @@ Example: if len(req.Arguments) > 0 { err = pinLsKeys(req, typeStr, api, emit) } else { - err = pinLsAll(req, typeStr, api, emit) + err = pinLsAll(req, typeStr, displayNames, api, emit) } if err != nil { return err @@ -402,8 +433,10 @@ Example: if stream { if quiet { fmt.Fprintf(w, "%s\n", out.PinLsObject.Cid) - } else { + } else if out.PinLsObject.Name == "" { fmt.Fprintf(w, "%s %s\n", out.PinLsObject.Cid, out.PinLsObject.Type) + } else { + fmt.Fprintf(w, "%s %s %s\n", out.PinLsObject.Cid, out.PinLsObject.Type, out.PinLsObject.Name) } return nil } @@ -411,8 +444,10 @@ Example: for k, v := range out.PinLsList.Keys { if quiet { fmt.Fprintf(w, "%s\n", k) - } else { + } else if v.Name == "" { fmt.Fprintf(w, "%s %s\n", k, v.Type) + } else { + fmt.Fprintf(w, "%s %s %s\n", k, v.Type, v.Name) } } @@ -437,11 +472,13 @@ type PinLsList struct { // PinLsType contains the type of a pin type PinLsType struct { Type string + Name string } // PinLsObject contains the description of a pin type PinLsObject struct { Cid string `json:",omitempty"` + Name string `json:",omitempty"` Type string `json:",omitempty"` } @@ -502,7 +539,7 @@ func pinLsKeys(req *cmds.Request, typeStr string, api coreiface.CoreAPI, emit fu return nil } -func pinLsAll(req *cmds.Request, typeStr string, api coreiface.CoreAPI, emit func(value PinLsOutputWrapper) error) error { +func pinLsAll(req *cmds.Request, typeStr string, detailed bool, api coreiface.CoreAPI, emit func(value PinLsOutputWrapper) error) error { enc, err := cmdenv.GetCidEncoder(req) if err != nil { return err @@ -520,7 +557,7 @@ func pinLsAll(req *cmds.Request, typeStr string, api coreiface.CoreAPI, emit fun panic("unhandled pin type") } - pins, err := api.Pin().Ls(req.Context, opt) + pins, err := api.Pin().Ls(req.Context, opt, options.Pin.Ls.Detailed(detailed)) if err != nil { return err } @@ -532,6 +569,7 @@ func pinLsAll(req *cmds.Request, typeStr string, api coreiface.CoreAPI, emit fun err = emit(PinLsOutputWrapper{ PinLsObject: PinLsObject{ Type: p.Type(), + Name: p.Name(), Cid: enc.Encode(p.Path().RootCid()), }, }) @@ -748,15 +786,15 @@ func pinVerify(ctx context.Context, n *core.IpfsNode, opts pinVerifyOpts, enc ci out := make(chan any) go func() { defer close(out) - for p := range n.Pinning.RecursiveKeys(ctx) { + for p := range n.Pinning.RecursiveKeys(ctx, false) { if p.Err != nil { out <- PinVerifyRes{Err: p.Err.Error()} return } - pinStatus := checkPin(p.C) + pinStatus := checkPin(p.Pin.Key) if !pinStatus.Ok || opts.includeOk { select { - case out <- PinVerifyRes{Cid: enc.Encode(p.C), PinStatus: pinStatus}: + case out <- PinVerifyRes{Cid: enc.Encode(p.Pin.Key), PinStatus: pinStatus}: case <-ctx.Done(): return } diff --git a/core/coreapi/block.go b/core/coreapi/block.go index 0c5597c8d..b386ecd0a 100644 --- a/core/coreapi/block.go +++ b/core/coreapi/block.go @@ -60,7 +60,7 @@ func (api *BlockAPI) Put(ctx context.Context, src io.Reader, opts ...caopts.Bloc } if settings.Pin { - if err = api.pinning.PinWithMode(ctx, b.Cid(), pin.Recursive); err != nil { + if err = api.pinning.PinWithMode(ctx, b.Cid(), pin.Recursive, ""); err != nil { return nil, err } if err := api.pinning.Flush(ctx); err != nil { diff --git a/core/coreapi/dag.go b/core/coreapi/dag.go index c4d0dc9d2..70686f62e 100644 --- a/core/coreapi/dag.go +++ b/core/coreapi/dag.go @@ -30,7 +30,7 @@ func (adder *pinningAdder) Add(ctx context.Context, nd ipld.Node) error { return err } - if err := adder.pinning.PinWithMode(ctx, nd.Cid(), pin.Recursive); err != nil { + if err := adder.pinning.PinWithMode(ctx, nd.Cid(), pin.Recursive, ""); err != nil { return err } @@ -51,7 +51,7 @@ func (adder *pinningAdder) AddMany(ctx context.Context, nds []ipld.Node) error { for _, nd := range nds { c := nd.Cid() if cids.Visit(c) { - if err := adder.pinning.PinWithMode(ctx, c, pin.Recursive); err != nil { + if err := adder.pinning.PinWithMode(ctx, c, pin.Recursive, ""); err != nil { return err } } diff --git a/core/coreapi/object.go b/core/coreapi/object.go index e8f94b1d5..fca98bc5f 100644 --- a/core/coreapi/object.go +++ b/core/coreapi/object.go @@ -133,7 +133,7 @@ func (api *ObjectAPI) Put(ctx context.Context, src io.Reader, opts ...caopts.Obj } if options.Pin { - if err := api.pinning.PinWithMode(ctx, dagnode.Cid(), pin.Recursive); err != nil { + if err := api.pinning.PinWithMode(ctx, dagnode.Cid(), pin.Recursive, ""); err != nil { return path.ImmutablePath{}, err } diff --git a/core/coreapi/pin.go b/core/coreapi/pin.go index 5cb92a819..8db582a4f 100644 --- a/core/coreapi/pin.go +++ b/core/coreapi/pin.go @@ -38,7 +38,7 @@ func (api *PinAPI) Add(ctx context.Context, p path.Path, opts ...caopts.PinAddOp defer api.blockstore.PinLock(ctx).Unlock(ctx) - err = api.pinning.Pin(ctx, dagNode, settings.Recursive) + err = api.pinning.Pin(ctx, dagNode, settings.Recursive, settings.Name) if err != nil { return fmt.Errorf("pin: %s", err) } @@ -67,7 +67,7 @@ func (api *PinAPI) Ls(ctx context.Context, opts ...caopts.PinLsOption) (<-chan c return nil, fmt.Errorf("invalid type '%s', must be one of {direct, indirect, recursive, all}", settings.Type) } - return api.pinLsAll(ctx, settings.Type), nil + return api.pinLsAll(ctx, settings.Type, settings.Detailed), nil } func (api *PinAPI) IsPinned(ctx context.Context, p path.Path, opts ...caopts.PinIsPinnedOption) (string, bool, error) { @@ -231,12 +231,12 @@ func (api *PinAPI) Verify(ctx context.Context) (<-chan coreiface.PinStatus, erro out := make(chan coreiface.PinStatus) go func() { defer close(out) - for p := range api.pinning.RecursiveKeys(ctx) { + for p := range api.pinning.RecursiveKeys(ctx, false) { var res *pinStatus if p.Err != nil { res = &pinStatus{err: p.Err} } else { - res = checkPin(p.C) + res = checkPin(p.Pin.Key) } select { case <-ctx.Done(): @@ -252,6 +252,7 @@ func (api *PinAPI) Verify(ctx context.Context) (<-chan coreiface.PinStatus, erro type pinInfo struct { pinType string path path.ImmutablePath + name string err error } @@ -263,6 +264,10 @@ func (p *pinInfo) Type() string { return p.pinType } +func (p *pinInfo) Name() string { + return p.name +} + func (p *pinInfo) Err() error { return p.err } @@ -271,16 +276,17 @@ func (p *pinInfo) Err() error { // // The caller must keep reading results until the channel is closed to prevent // leaking the goroutine that is fetching pins. -func (api *PinAPI) pinLsAll(ctx context.Context, typeStr string) <-chan coreiface.Pin { +func (api *PinAPI) pinLsAll(ctx context.Context, typeStr string, detailed bool) <-chan coreiface.Pin { out := make(chan coreiface.Pin, 1) emittedSet := cid.NewSet() - AddToResultKeys := func(c cid.Cid, typeStr string) error { + AddToResultKeys := func(c cid.Cid, name, typeStr string) error { if emittedSet.Visit(c) { select { case out <- &pinInfo{ pinType: typeStr, + name: name, path: path.FromCid(c), }: case <-ctx.Done(): @@ -296,25 +302,25 @@ func (api *PinAPI) pinLsAll(ctx context.Context, typeStr string) <-chan coreifac var rkeys []cid.Cid var err error if typeStr == "recursive" || typeStr == "all" { - for streamedCid := range api.pinning.RecursiveKeys(ctx) { + for streamedCid := range api.pinning.RecursiveKeys(ctx, detailed) { if streamedCid.Err != nil { out <- &pinInfo{err: streamedCid.Err} return } - if err = AddToResultKeys(streamedCid.C, "recursive"); err != nil { + if err = AddToResultKeys(streamedCid.Pin.Key, streamedCid.Pin.Name, "recursive"); err != nil { out <- &pinInfo{err: err} return } - rkeys = append(rkeys, streamedCid.C) + rkeys = append(rkeys, streamedCid.Pin.Key) } } if typeStr == "direct" || typeStr == "all" { - for streamedCid := range api.pinning.DirectKeys(ctx) { + for streamedCid := range api.pinning.DirectKeys(ctx, detailed) { if streamedCid.Err != nil { out <- &pinInfo{err: streamedCid.Err} return } - if err = AddToResultKeys(streamedCid.C, "direct"); err != nil { + if err = AddToResultKeys(streamedCid.Pin.Key, streamedCid.Pin.Name, "direct"); err != nil { out <- &pinInfo{err: err} return } @@ -324,21 +330,21 @@ func (api *PinAPI) pinLsAll(ctx context.Context, typeStr string) <-chan coreifac // We need to first visit the direct pins that have priority // without emitting them - for streamedCid := range api.pinning.DirectKeys(ctx) { + for streamedCid := range api.pinning.DirectKeys(ctx, detailed) { if streamedCid.Err != nil { out <- &pinInfo{err: streamedCid.Err} return } - emittedSet.Add(streamedCid.C) + emittedSet.Add(streamedCid.Pin.Key) } - for streamedCid := range api.pinning.RecursiveKeys(ctx) { + for streamedCid := range api.pinning.RecursiveKeys(ctx, detailed) { if streamedCid.Err != nil { out <- &pinInfo{err: streamedCid.Err} return } - emittedSet.Add(streamedCid.C) - rkeys = append(rkeys, streamedCid.C) + emittedSet.Add(streamedCid.Pin.Key) + rkeys = append(rkeys, streamedCid.Pin.Key) } } if typeStr == "indirect" || typeStr == "all" { @@ -353,7 +359,7 @@ func (api *PinAPI) pinLsAll(ctx context.Context, typeStr string) <-chan coreifac if emittedSet.Has(c) { return true // skipped } - err := AddToResultKeys(c, "indirect") + err := AddToResultKeys(c, "", "indirect") if err != nil { out <- &pinInfo{err: err} return false diff --git a/core/coreiface/options/pin.go b/core/coreiface/options/pin.go index 75c2b8a26..0efd853ef 100644 --- a/core/coreiface/options/pin.go +++ b/core/coreiface/options/pin.go @@ -5,11 +5,13 @@ import "fmt" // PinAddSettings represent the settings for PinAPI.Add type PinAddSettings struct { Recursive bool + Name string } // PinLsSettings represent the settings for PinAPI.Ls type PinLsSettings struct { - Type string + Type string + Detailed bool } // PinIsPinnedSettings represent the settings for PinAPI.IsPinned @@ -194,6 +196,15 @@ func (pinLsOpts) pinType(t string) PinLsOption { } } +// Detailed is an option for [Pin.Ls] which sets whether or not to return +// detailed information, such as pin names and modes. +func (pinLsOpts) Detailed(detailed bool) PinLsOption { + return func(settings *PinLsSettings) error { + settings.Detailed = detailed + return nil + } +} + type pinIsPinnedOpts struct{} // All is an option for Pin.IsPinned which will make it search in all type of pins. @@ -263,6 +274,14 @@ func (pinOpts) Recursive(recursive bool) PinAddOption { } } +// Name is an option for Pin.Add which specifies an optional name to add to the pin. +func (pinOpts) Name(name string) PinAddOption { + return func(settings *PinAddSettings) error { + settings.Name = name + return nil + } +} + // RmRecursive is an option for Pin.Rm which specifies whether to recursively // unpin the object linked to by the specified object(s). This does not remove // indirect pins referenced by other recursive pins. diff --git a/core/coreiface/pin.go b/core/coreiface/pin.go index 25a775965..ed837fc9c 100644 --- a/core/coreiface/pin.go +++ b/core/coreiface/pin.go @@ -13,6 +13,9 @@ type Pin interface { // Path to the pinned object Path() path.ImmutablePath + // Name is the name of the pin. + Name() string + // Type of the pin Type() string diff --git a/core/coreunix/add.go b/core/coreunix/add.go index 83bec6d03..a8d7e5982 100644 --- a/core/coreunix/add.go +++ b/core/coreunix/add.go @@ -186,7 +186,7 @@ func (adder *Adder) PinRoot(ctx context.Context, root ipld.Node) error { adder.tempRoot = rnk } - err = adder.pinning.PinWithMode(ctx, rnk, pin.Recursive) + err = adder.pinning.PinWithMode(ctx, rnk, pin.Recursive, "") if err != nil { return err } diff --git a/docs/changelogs/v0.26.md b/docs/changelogs/v0.26.md index 3a9f088ca..9eddcfd85 100644 --- a/docs/changelogs/v0.26.md +++ b/docs/changelogs/v0.26.md @@ -7,6 +7,7 @@ - [Overview](#overview) - [🔦 Highlights](#-highlights) - [Several deprecated commands have been removed](#several-deprecated-commands-have-been-removed) + - [Support optional pin names](#support-optional-pin-names) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -30,6 +31,10 @@ Several deprecated commands have been removed: - `ipfs dns` deprecated in [April 2022, Kubo 0.13](https://github.com/ipfs/kubo/commit/76ae33a9f3f9abd166d1f6f23d6a8a0511510e3c), use `ipfs resolve /ipns/{name}` instead. - `ipfs tar` deprecated [April 2022, Kubo 0.13](https://github.com/ipfs/kubo/pull/8849) +#### Support optional pin names + +You can now add a name to a pin when pinning a CID. To do so, use `ipfs pin add --name "Some Name" bafy...`. You can list your pins, including their names, with `ipfs pin ls --names`. + ### 📝 Changelog - Export a `kubo.Start` function so users can programmatically start Kubo from within a go program. diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 34b101c9a..b669171fd 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.20 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.16.0 + github.com/ipfs/boxo v0.16.1-0.20240104124825-38fb74f76b0d github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.32.2 github.com/multiformats/go-multiaddr v0.12.0 diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 9d63ebb13..c348ddd60 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -303,8 +303,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.16.0 h1:A9dUmef5a+mEFki6kbyG7el5gl65CiUBzrDeZxzTWKY= -github.com/ipfs/boxo v0.16.0/go.mod h1:jAgpNQn7T7BnibUeReXcKU9Ha1xmYNyOlwVEl193ow0= +github.com/ipfs/boxo v0.16.1-0.20240104124825-38fb74f76b0d h1:7tDzalCLHYr4tzrjNrfqZvIki2MEBSrpLBdc0bssDZk= +github.com/ipfs/boxo v0.16.1-0.20240104124825-38fb74f76b0d/go.mod h1:jAgpNQn7T7BnibUeReXcKU9Ha1xmYNyOlwVEl193ow0= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= diff --git a/fuse/ipns/common.go b/fuse/ipns/common.go index 7306196c8..d22086776 100644 --- a/fuse/ipns/common.go +++ b/fuse/ipns/common.go @@ -18,7 +18,7 @@ func InitializeKeyspace(n *core.IpfsNode, key ci.PrivKey) error { emptyDir := ft.EmptyDirNode() - err := n.Pinning.Pin(ctx, emptyDir, false) + err := n.Pinning.Pin(ctx, emptyDir, false, "") if err != nil { return err } diff --git a/gc/gc.go b/gc/gc.go index c85f9d6bf..51df59e54 100644 --- a/gc/gc.go +++ b/gc/gc.go @@ -154,7 +154,7 @@ func GC(ctx context.Context, bs bstore.GCBlockstore, dstor dstore.Datastore, pn // Descendants recursively finds all the descendants of the given roots and // adds them to the given cid.Set, using the provided dag.GetLinks function // to walk the tree. -func Descendants(ctx context.Context, getLinks dag.GetLinks, set *cid.Set, roots <-chan pin.StreamedCid) error { +func Descendants(ctx context.Context, getLinks dag.GetLinks, set *cid.Set, roots <-chan pin.StreamedPin) error { verifyGetLinks := func(ctx context.Context, c cid.Cid) ([]*ipld.Link, error) { err := verifcid.ValidateCid(verifcid.DefaultAllowlist, c) if err != nil { @@ -188,7 +188,7 @@ func Descendants(ctx context.Context, getLinks dag.GetLinks, set *cid.Set, roots } // Walk recursively walks the dag and adds the keys to the given set - err := dag.Walk(ctx, verifyGetLinks, wrapper.C, func(k cid.Cid) bool { + err := dag.Walk(ctx, verifyGetLinks, wrapper.Pin.Key, func(k cid.Cid) bool { return set.Visit(toCidV1(k)) }, dag.Concurrent()) if err != nil { @@ -226,7 +226,7 @@ func ColoredSet(ctx context.Context, pn pin.Pinner, ng ipld.NodeGetter, bestEffo } return links, nil } - rkeys := pn.RecursiveKeys(ctx) + rkeys := pn.RecursiveKeys(ctx, false) err := Descendants(ctx, getLinks, gcs, rkeys) if err != nil { errors = true @@ -249,14 +249,14 @@ func ColoredSet(ctx context.Context, pn pin.Pinner, ng ipld.NodeGetter, bestEffo } return links, nil } - bestEffortRootsChan := make(chan pin.StreamedCid) + bestEffortRootsChan := make(chan pin.StreamedPin) go func() { defer close(bestEffortRootsChan) for _, root := range bestEffortRoots { select { case <-ctx.Done(): return - case bestEffortRootsChan <- pin.StreamedCid{C: root}: + case bestEffortRootsChan <- pin.StreamedPin{Pin: pin.Pinned{Key: root}}: } } }() @@ -270,15 +270,15 @@ func ColoredSet(ctx context.Context, pn pin.Pinner, ng ipld.NodeGetter, bestEffo } } - dkeys := pn.DirectKeys(ctx) + dkeys := pn.DirectKeys(ctx, false) for k := range dkeys { if k.Err != nil { return nil, k.Err } - gcs.Add(toCidV1(k.C)) + gcs.Add(toCidV1(k.Pin.Key)) } - ikeys := pn.InternalPins(ctx) + ikeys := pn.InternalPins(ctx, false) err = Descendants(ctx, getLinks, gcs, ikeys) if err != nil { errors = true diff --git a/gc/gc_test.go b/gc/gc_test.go index 4fb6dbf09..c5d00714d 100644 --- a/gc/gc_test.go +++ b/gc/gc_test.go @@ -38,14 +38,14 @@ func TestGC(t *testing.T) { // direct root, _, err := daggen.MakeDagNode(dserv.Add, 0, 1) require.NoError(t, err) - err = pinner.PinWithMode(ctx, root, pin.Direct) + err = pinner.PinWithMode(ctx, root, pin.Direct, "") require.NoError(t, err) expectedKept = append(expectedKept, root.Hash()) // recursive root, allCids, err := daggen.MakeDagNode(dserv.Add, 5, 2) require.NoError(t, err) - err = pinner.PinWithMode(ctx, root, pin.Recursive) + err = pinner.PinWithMode(ctx, root, pin.Recursive, "") require.NoError(t, err) expectedKept = append(expectedKept, toMHs(allCids)...) } diff --git a/go.mod b/go.mod index 74b4cd347..b9fba0309 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,7 @@ require ( github.com/hashicorp/go-multierror v1.1.1 github.com/ipfs-shipyard/nopfs v0.0.12-0.20231027223058-cde3b5ba964c github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c - github.com/ipfs/boxo v0.16.0 + github.com/ipfs/boxo v0.16.1-0.20240104124825-38fb74f76b0d github.com/ipfs/go-block-format v0.2.0 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 diff --git a/go.sum b/go.sum index f69fbedd0..8cae85a9f 100644 --- a/go.sum +++ b/go.sum @@ -337,8 +337,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.16.0 h1:A9dUmef5a+mEFki6kbyG7el5gl65CiUBzrDeZxzTWKY= -github.com/ipfs/boxo v0.16.0/go.mod h1:jAgpNQn7T7BnibUeReXcKU9Ha1xmYNyOlwVEl193ow0= +github.com/ipfs/boxo v0.16.1-0.20240104124825-38fb74f76b0d h1:7tDzalCLHYr4tzrjNrfqZvIki2MEBSrpLBdc0bssDZk= +github.com/ipfs/boxo v0.16.1-0.20240104124825-38fb74f76b0d/go.mod h1:jAgpNQn7T7BnibUeReXcKU9Ha1xmYNyOlwVEl193ow0= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= diff --git a/test/cli/pins_test.go b/test/cli/pins_test.go index 8a36d4695..a57f1b89b 100644 --- a/test/cli/pins_test.go +++ b/test/cli/pins_test.go @@ -209,4 +209,67 @@ func TestPins(t *testing.T) { testPins(t, testPinsArgs{runDaemon: true, baseArg: "--cid-base=base32"}) testPins(t, testPinsArgs{runDaemon: true, lsArg: "--stream", baseArg: "--cid-base=base32"}) }) + + t.Run("test pinning with names cli text output", func(t *testing.T) { + t.Parallel() + + node := harness.NewT(t).NewNode().Init() + cidAStr := node.IPFSAddStr(RandomStr(1000), "--pin=false") + cidBStr := node.IPFSAddStr(RandomStr(1000), "--pin=false") + + _ = node.IPFS("pin", "add", "--name", "testPin", cidAStr) + + outARegular := cidAStr + " recursive" + outADetailed := outARegular + " testPin" + outBRegular := cidBStr + " recursive" + outBDetailed := outBRegular + " testPin" + + pinLs := func(args ...string) []string { + return strings.Split(node.IPFS(StrCat("pin", "ls", args)...).Stdout.Trimmed(), "\n") + } + + lsOut := pinLs("-t=recursive") + require.Contains(t, lsOut, outARegular) + require.NotContains(t, lsOut, outADetailed) + + lsOut = pinLs("-t=recursive", "--names") + require.Contains(t, lsOut, outADetailed) + require.NotContains(t, lsOut, outARegular) + + _ = node.IPFS("pin", "update", cidAStr, cidBStr) + lsOut = pinLs("-t=recursive", "--names") + require.Contains(t, lsOut, outBDetailed) + require.NotContains(t, lsOut, outADetailed) + }) + + // JSON that is also the wire format of /api/v0 + t.Run("test pinning with names json output", func(t *testing.T) { + t.Parallel() + + node := harness.NewT(t).NewNode().Init() + cidAStr := node.IPFSAddStr(RandomStr(1000), "--pin=false") + cidBStr := node.IPFSAddStr(RandomStr(1000), "--pin=false") + + _ = node.IPFS("pin", "add", "--name", "testPinJson", cidAStr) + + outARegular := `"` + cidAStr + `":{"Type":"recursive"` + outADetailed := outARegular + `,"Name":"testPinJson"` + outBRegular := `"` + cidBStr + `":{"Type":"recursive"` + outBDetailed := outBRegular + `,"Name":"testPinJson"` + + pinLs := func(args ...string) string { + return node.IPFS(StrCat("pin", "ls", "--enc=json", args)...).Stdout.Trimmed() + } + + lsOut := pinLs("-t=recursive") + require.Contains(t, lsOut, outARegular) + require.NotContains(t, lsOut, outADetailed) + + lsOut = pinLs("-t=recursive", "--names") + require.Contains(t, lsOut, outADetailed) + + _ = node.IPFS("pin", "update", cidAStr, cidBStr) + lsOut = pinLs("-t=recursive", "--names") + require.Contains(t, lsOut, outBDetailed) + }) } diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index e55e9f10c..2cb03508a 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -103,7 +103,7 @@ require ( github.com/hexops/gotextdiff v1.0.3 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/ipfs/bbloom v0.0.4 // indirect - github.com/ipfs/boxo v0.16.0 // indirect + github.com/ipfs/boxo v0.16.1-0.20240104124825-38fb74f76b0d // indirect github.com/ipfs/go-block-format v0.2.0 // indirect github.com/ipfs/go-cid v0.4.1 // indirect github.com/ipfs/go-datastore v0.6.0 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 35f92c1a8..8681e257c 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -342,8 +342,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.16.0 h1:A9dUmef5a+mEFki6kbyG7el5gl65CiUBzrDeZxzTWKY= -github.com/ipfs/boxo v0.16.0/go.mod h1:jAgpNQn7T7BnibUeReXcKU9Ha1xmYNyOlwVEl193ow0= +github.com/ipfs/boxo v0.16.1-0.20240104124825-38fb74f76b0d h1:7tDzalCLHYr4tzrjNrfqZvIki2MEBSrpLBdc0bssDZk= +github.com/ipfs/boxo v0.16.1-0.20240104124825-38fb74f76b0d/go.mod h1:jAgpNQn7T7BnibUeReXcKU9Ha1xmYNyOlwVEl193ow0= github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs= github.com/ipfs/go-block-format v0.2.0/go.mod h1:+jpL11nFx5A/SPpsoBn6Bzkra/zaArfSmsknbPMYgzM= github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= From 4a8badf98ea66ec926a0835542cbbcf0bd1f902e Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Thu, 4 Jan 2024 13:28:57 +0100 Subject: [PATCH 0978/1212] Revert "build,docker: add support for riscv64" This reverts commit 765cffe6c2b7d0a9d757bbdb476cc0ea15fd287c. --- .github/workflows/docker-image.yml | 15 +-------------- mk/util.mk | 1 - 2 files changed, 1 insertion(+), 15 deletions(-) diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index 826bfad85..c1e77112d 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -107,31 +107,18 @@ jobs: cache-from: type=local,src=/tmp/.buildx-cache cache-to: type=local,dest=/tmp/.buildx-cache-new - - name: Build Docker image (linux/riscv64) - uses: docker/build-push-action@v4 - with: - platforms: linux/riscv64 - context: . - push: false - load: true - file: ./Dockerfile - tags: ${{ env.IMAGE_NAME }}:linux-riscv64 - cache-from: type=local,src=/tmp/.buildx-cache - cache-to: type=local,dest=/tmp/.buildx-cache-new - # We test all the images on amd64 host here. This uses QEMU to emulate # the other platforms. - run: docker run --rm $IMAGE_NAME:linux-amd64 --version - run: docker run --rm $IMAGE_NAME:linux-arm-v7 --version - run: docker run --rm $IMAGE_NAME:linux-arm64-v8 --version - - run: docker run --rm $IMAGE_NAME:linux-riscv64 --version # This will only push the previously built images. - if: github.event_name != 'workflow_dispatch' || github.event.inputs.push == 'true' name: Publish to Docker Hub uses: docker/build-push-action@v4 with: - platforms: linux/amd64,linux/arm/v7,linux/arm64/v8,linux/riscv64 + platforms: linux/amd64,linux/arm/v7,linux/arm64/v8 context: . push: true file: ./Dockerfile diff --git a/mk/util.mk b/mk/util.mk index 50040c17a..2ce48583f 100644 --- a/mk/util.mk +++ b/mk/util.mk @@ -16,7 +16,6 @@ SUPPORTED_PLATFORMS += linux-arm SUPPORTED_PLATFORMS += linux-arm64 SUPPORTED_PLATFORMS += linux-386 SUPPORTED_PLATFORMS += linux-amd64 -SUPPORTED_PLATFORMS += linux-riscv64 SUPPORTED_PLATFORMS += darwin-amd64 ifeq ($(shell bin/check_go_version "1.16.0" 2>/dev/null; echo $$?),0) From b215d73e45b8677e40d5d4d7b7500f7592fd9d9d Mon Sep 17 00:00:00 2001 From: Jorropo Date: Thu, 4 Jan 2024 17:43:46 +0100 Subject: [PATCH 0979/1212] chore: update otlp Tracks ipfs/boxo#532 --- docs/changelogs/v0.26.md | 6 + docs/examples/kubo-as-a-library/go.mod | 33 ++-- docs/examples/kubo-as-a-library/go.sum | 205 +++++-------------------- go.mod | 47 +++--- go.sum | 125 ++++++--------- test/dependencies/go.mod | 10 +- test/dependencies/go.sum | 20 +-- tracing/doc.go | 40 ++--- tracing/tracing.go | 5 +- 9 files changed, 167 insertions(+), 324 deletions(-) diff --git a/docs/changelogs/v0.26.md b/docs/changelogs/v0.26.md index 9eddcfd85..2888483b8 100644 --- a/docs/changelogs/v0.26.md +++ b/docs/changelogs/v0.26.md @@ -8,6 +8,7 @@ - [🔦 Highlights](#-highlights) - [Several deprecated commands have been removed](#several-deprecated-commands-have-been-removed) - [Support optional pin names](#support-optional-pin-names) + - [`jaeger` trace exporter has been removed](#jaeger-trace-exporter-has-been-removed) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -35,6 +36,11 @@ Several deprecated commands have been removed: You can now add a name to a pin when pinning a CID. To do so, use `ipfs pin add --name "Some Name" bafy...`. You can list your pins, including their names, with `ipfs pin ls --names`. +#### `jaeger` trace exporter has been removed + +`jaeger` exporter has been removed from upstream, you should use `otlp` exporter instead. +See the [boxo tracing docs](https://github.com/ipfs/boxo/blob/a391d02102875ee7075a692076154bec1fa871f3/docs/tracing.md) for an example. + ### 📝 Changelog - Export a `kubo.Start` function so users can programmatically start Kubo from within a go program. diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index b669171fd..99cdca600 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.20 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.16.1-0.20240104124825-38fb74f76b0d + github.com/ipfs/boxo v0.16.1-0.20240104131845-a391d0210287 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.32.2 github.com/multiformats/go-multiaddr v0.12.0 @@ -54,7 +54,7 @@ require ( github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b // indirect github.com/google/uuid v1.4.0 // indirect github.com/gorilla/websocket v1.5.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/golang-lru v1.0.2 // indirect @@ -135,7 +135,7 @@ require ( github.com/onsi/ginkgo/v2 v2.13.0 // indirect github.com/opencontainers/runtime-spec v1.1.0 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect - github.com/openzipkin/zipkin-go v0.4.1 // indirect + github.com/openzipkin/zipkin-go v0.4.2 // indirect github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 // indirect github.com/pion/datachannel v1.5.5 // indirect @@ -178,18 +178,16 @@ require ( github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 // indirect go.opencensus.io v0.24.0 // indirect - go.opentelemetry.io/otel v1.17.0 // indirect - go.opentelemetry.io/otel/exporters/jaeger v1.14.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.16.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.16.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.14.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.16.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.14.0 // indirect - go.opentelemetry.io/otel/exporters/zipkin v1.14.0 // indirect - go.opentelemetry.io/otel/metric v1.17.0 // indirect - go.opentelemetry.io/otel/sdk v1.16.0 // indirect - go.opentelemetry.io/otel/trace v1.17.0 // indirect - go.opentelemetry.io/proto/otlp v0.19.0 // indirect + go.opentelemetry.io/otel v1.21.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.21.0 // indirect + go.opentelemetry.io/otel/exporters/zipkin v1.21.0 // indirect + go.opentelemetry.io/otel/metric v1.21.0 // indirect + go.opentelemetry.io/otel/sdk v1.21.0 // indirect + go.opentelemetry.io/otel/trace v1.21.0 // indirect + go.opentelemetry.io/proto/otlp v1.0.0 // indirect go.uber.org/dig v1.17.1 // indirect go.uber.org/fx v1.20.1 // indirect go.uber.org/mock v0.3.0 // indirect @@ -206,8 +204,9 @@ require ( golang.org/x/tools v0.16.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect gonum.org/v1/gonum v0.14.0 // indirect - google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect - google.golang.org/grpc v1.55.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect + google.golang.org/grpc v1.59.0 // indirect google.golang.org/protobuf v1.31.0 // indirect gopkg.in/square/go-jose.v2 v2.5.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index c348ddd60..59c684345 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -10,30 +10,14 @@ cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxK cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= -cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= -cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= -cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= -cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= -cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= -cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= -cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= -cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= -cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= -cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= -cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= -cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= -cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= -cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= -cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= -cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU= @@ -55,7 +39,6 @@ github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8V github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5 h1:iW0a5ljuFxkLGPNem5Ui+KBjFJzKg4Fv2fnxe4dvzpM= github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5/go.mod h1:Y2QMoi1vgtOIfc+6DhrMOGkLoGzqSV2rKp4Sm+opsyA= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= -github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= @@ -84,7 +67,6 @@ github.com/ceramicnetwork/go-dag-jose v0.1.0 h1:yJ/HVlfKpnD3LdYP03AHyTvbm3BpPiz2 github.com/ceramicnetwork/go-dag-jose v0.1.0/go.mod h1:qYA1nYt0X8u4XoMAVoOV3upUVKtrxy/I670Dg5F0wjI= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= -github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= @@ -93,12 +75,6 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMn github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs= 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= -github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= -github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/containerd/cgroups v0.0.0-20201119153540-4cbc285b3327/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE= github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM= github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw= @@ -146,9 +122,6 @@ github.com/elastic/gosigar v0.14.2/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0 github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= -github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5 h1:BBso6MBKW8ncyZLv37o+KNyy0HrrHgfnOaGQC2qvN+A= github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5/go.mod h1:JpoxHjuQauoxiFMl1ie8Xc/7TfLuMZ5eOCONd1sUBHg= @@ -172,7 +145,6 @@ github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclK github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY= github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= @@ -193,8 +165,7 @@ github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXP github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= -github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE= +github.com/golang/glog v1.1.2 h1:DVjP2PbBOzHyzA+dn3WhHIq4NdVu3Q+pvivFICf/7fo= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -204,15 +175,10 @@ github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfb github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= @@ -234,28 +200,21 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -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= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b h1:RMpPgZTSApbPf7xaVel+QkoGPRLFLrwFO89uDUHEGf0= github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= @@ -275,9 +234,8 @@ github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWm github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= -github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 h1:BZHcxBETFHIdVyhyEfOvn/RdU/QGdLI4y34qQGjGWO0= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 h1:YBftPWNWd4WwGqtY2yeZL2ef8rHAxPBD8KFhJpmcqms= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg= github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -303,8 +261,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.16.1-0.20240104124825-38fb74f76b0d h1:7tDzalCLHYr4tzrjNrfqZvIki2MEBSrpLBdc0bssDZk= -github.com/ipfs/boxo v0.16.1-0.20240104124825-38fb74f76b0d/go.mod h1:jAgpNQn7T7BnibUeReXcKU9Ha1xmYNyOlwVEl193ow0= +github.com/ipfs/boxo v0.16.1-0.20240104131845-a391d0210287 h1:My5Ct2+5I/+FN2HaFm3VCQB3Y+/A5kcWDGNS0JR1jo8= +github.com/ipfs/boxo v0.16.1-0.20240104131845-a391d0210287/go.mod h1:gCYL6EViui01M8Dr0cY8nOpRAbofxZDWASxbLSrG9Ac= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= @@ -604,8 +562,8 @@ github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFSt github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= -github.com/openzipkin/zipkin-go v0.4.1 h1:kNd/ST2yLLWhaWrkgchya40TJabe8Hioj9udfPcEO5A= -github.com/openzipkin/zipkin-go v0.4.1/go.mod h1:qY0VqDSN1pOBN94dBc6w2GJlWLiovAyg7Qt6/I9HecM= +github.com/openzipkin/zipkin-go v0.4.2 h1:zjqfqHjUpPmB3c1GlCvvgsM1G4LkvqQbBDueDOCg/jA= +github.com/openzipkin/zipkin-go v0.4.2/go.mod h1:ZeVkFjuuBiSy13y8vpSDCjMi9GoI3hPpCJSBx/EYFhY= 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/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= @@ -682,7 +640,6 @@ github.com/quic-go/webtransport-go v0.6.0 h1:CvNsKqc4W2HljHJnoT+rMmbRJybShZ0YPFD github.com/quic-go/webtransport-go v0.6.0/go.mod h1:9KjU4AEBqEQidGHNDkZrb8CAa1abRaosM2yGOyiikEc= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU= -github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= @@ -795,9 +752,7 @@ github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 h1: github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7/go.mod h1:X2c0RVCI1eSUFI8eLcY3c0423ykwiUdxLJtkDvruhjI= github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= -github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= @@ -807,34 +762,28 @@ go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.1/go.mod h1:Ap50jQcDJrx6rB6VgeeFPtuPIf3wMRvRfrfYDO6+BmA= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/otel v1.17.0 h1:MW+phZ6WZ5/uk2nd93ANk/6yJ+dVrvNWUjGhnnFU5jM= -go.opentelemetry.io/otel v1.17.0/go.mod h1:I2vmBGtFaODIVMBSTPVDlJSzBDNf93k60E6Ft0nyjo0= -go.opentelemetry.io/otel/exporters/jaeger v1.14.0 h1:CjbUNd4iN2hHmWekmOqZ+zSCU+dzZppG8XsV+A3oc8Q= -go.opentelemetry.io/otel/exporters/jaeger v1.14.0/go.mod h1:4Ay9kk5vELRrbg5z4cpP9EtmQRFap2Wb0woPG4lujZA= -go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.16.0 h1:t4ZwRPU+emrcvM2e9DHd0Fsf0JTPVcbfa/BhTDF03d0= -go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.16.0/go.mod h1:vLarbg68dH2Wa77g71zmKQqlQ8+8Rq3GRG31uc0WcWI= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.16.0 h1:cbsD4cUcviQGXdw8+bo5x2wazq10SKz8hEbtCRPcU78= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.16.0/go.mod h1:JgXSGah17croqhJfhByOLVY719k1emAXC8MVhCIJlRs= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.14.0 h1:ap+y8RXX3Mu9apKVtOkM6WSFESLM8K3wNQyOU8sWHcc= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.14.0/go.mod h1:5w41DY6S9gZrbjuq6Y+753e96WfPha5IcsOSZTtullM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.16.0 h1:iqjq9LAB8aK++sKVcELezzn655JnBNdsDhghU4G/So8= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.16.0/go.mod h1:hGXzO5bhhSHZnKvrDaXB82Y9DRFour0Nz/KrBh7reWw= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.14.0 h1:sEL90JjOO/4yhquXl5zTAkLLsZ5+MycAgX99SDsxGc8= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.14.0/go.mod h1:oCslUcizYdpKYyS9e8srZEqM6BB8fq41VJBjLAE6z1w= -go.opentelemetry.io/otel/exporters/zipkin v1.14.0 h1:reEVE1upBF9tcujgvSqLJS0SrI7JQPaTKP4s4rymnSs= -go.opentelemetry.io/otel/exporters/zipkin v1.14.0/go.mod h1:RcjvOAcvhzcufQP8aHmzRw1gE9g/VEZufDdo2w+s4sk= -go.opentelemetry.io/otel/metric v1.17.0 h1:iG6LGVz5Gh+IuO0jmgvpTB6YVrCGngi8QGm+pMd8Pdc= -go.opentelemetry.io/otel/metric v1.17.0/go.mod h1:h4skoxdZI17AxwITdmdZjjYJQH5nzijUUjm+wtPph5o= -go.opentelemetry.io/otel/sdk v1.16.0 h1:Z1Ok1YsijYL0CSJpHt4cS3wDDh7p572grzNrBMiMWgE= -go.opentelemetry.io/otel/sdk v1.16.0/go.mod h1:tMsIuKXuuIWPBAOrH+eHtvhTL+SntFtXF9QD68aP6p4= -go.opentelemetry.io/otel/trace v1.17.0 h1:/SWhSRHmDPOImIAetP1QAeMnZYiQXrTy4fMMYOdSKWQ= -go.opentelemetry.io/otel/trace v1.17.0/go.mod h1:I/4vKTgFclIsXRVucpH25X0mpFSczM7aHeaz0ZBLWjY= -go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= -go.opentelemetry.io/proto/otlp v0.19.0 h1:IVN6GR+mhC4s5yfcTbmzHYODqvWAp3ZedA2SJPI1Nnw= -go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= +go.opentelemetry.io/otel v1.21.0 h1:hzLeKBZEL7Okw2mGzZ0cc4k/A7Fta0uoPgaJCr8fsFc= +go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 h1:cl5P5/GIfFh4t6xyruOgJP5QiA1pw4fYYdv6nc6CBWw= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0/go.mod h1:zgBdWWAu7oEEMC06MMKc5NLbA/1YDXV1sMpSqEeLQLg= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0 h1:tIqheXEFWAZ7O8A7m+J0aPTmpJN3YQ7qetUAdkkkKpk= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0/go.mod h1:nUeKExfxAQVbiVFn32YXpXZZHZ61Cc3s3Rn1pDBGAb0= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0 h1:digkEZCJWobwBqMwC0cwCq8/wkkRy/OowZg5OArWZrM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0/go.mod h1:/OpE/y70qVkndM0TrxT4KBoN3RsFZP0QaofcfYrj76I= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.21.0 h1:VhlEQAPp9R1ktYfrPk5SOryw1e9LDDTZCbIPFrho0ec= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.21.0/go.mod h1:kB3ufRbfU+CQ4MlUcqtW8Z7YEOBeK2DJ6CmR5rYYF3E= +go.opentelemetry.io/otel/exporters/zipkin v1.21.0 h1:D+Gv6lSfrFBWmQYyxKjDd0Zuld9SRXpIrEsKZvE4DO4= +go.opentelemetry.io/otel/exporters/zipkin v1.21.0/go.mod h1:83oMKR6DzmHisFOW3I+yIMGZUTjxiWaiBI8M8+TU5zE= +go.opentelemetry.io/otel/metric v1.21.0 h1:tlYWfeo+Bocx5kLEloTjbcDwBuELRrIFxwdQ36PlJu4= +go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM= +go.opentelemetry.io/otel/sdk v1.21.0 h1:FTt8qirL1EysG6sTQRZ5TokkU8d0ugCj8htOgThZXQ8= +go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E= +go.opentelemetry.io/otel/trace v1.21.0 h1:WD9i5gzvoUPuXIXH24ZNBudiarZDKuekPqi/E8fpfLc= +go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ= +go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I= +go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= @@ -844,7 +793,7 @@ go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= go.uber.org/fx v1.20.1 h1:zVwVQGS8zYvhh9Xxcu4w1M6ESyeMzebzj2NbSayZ4Mk= go.uber.org/fx v1.20.1/go.mod h1:iSYNbHf2y55acNCwCXKx7LbWb5WG1Bnue5RDXz1OREg= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= -go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/mock v0.3.0 h1:3mUxI1No2/60yUYax92Pt8eNOEecx2D3lcXZh2NEZJo= go.uber.org/mock v0.3.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= @@ -891,9 +840,7 @@ golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm0 golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20231214170342-aacd6d4b4611 h1:qCEDpW1G+vcj3Y7Fy52pEM1AWm3abj8WimGYejI3SC4= golang.org/x/exp v0.0.0-20231214170342-aacd6d4b4611/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= @@ -914,7 +861,6 @@ golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCc golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= @@ -937,24 +883,13 @@ golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= @@ -980,7 +915,6 @@ golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4Iltr golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -988,8 +922,6 @@ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1015,30 +947,19 @@ golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191210023423-ac6580df4449/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -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= -golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1077,7 +998,6 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= @@ -1090,7 +1010,6 @@ golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -1118,28 +1037,12 @@ golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= -golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= @@ -1166,14 +1069,6 @@ google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsb google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= -google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -1181,7 +1076,6 @@ google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7 google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= @@ -1198,27 +1092,13 @@ google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvx google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= -google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 h1:DdoeryqhaXp1LtT/emMP1BRJPHHKFi5akj/nbx/zNTA= -google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s= +google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d h1:VBu5YqKPv6XiJ199exd8Br+Aetz+o08F+PLMnwJQHAY= +google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d h1:DoPTO70H+bcDXcd39vOqb2viZxgqeBeSGtZ55yZU4/Q= +google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d/go.mod h1:KjSP20unUpOx5kyQUFa7k4OJg0qeJ7DEZflGDu2p6Bk= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d h1:uvYuEyMHKNt+lT4K3bN6fGswmK8qSvcreM3BwjDh+y4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= @@ -1230,17 +1110,9 @@ google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQ google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= -google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= -google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc v1.55.0 h1:3Oj82/tFSCeUrRTg/5E/7d/W5A1tj6Ky1ABAuZuv5ag= -google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8= +google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk= +google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -1249,11 +1121,9 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -1272,7 +1142,6 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkep gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -1289,8 +1158,6 @@ honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= lukechampine.com/blake3 v1.1.6/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= lukechampine.com/blake3 v1.2.1 h1:YuqqRuaqsGV71BV/nm9xlI0MKUv4QC54jQnBChWbGnI= lukechampine.com/blake3 v1.2.1/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= diff --git a/go.mod b/go.mod index b9fba0309..9212964c2 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,7 @@ require ( github.com/hashicorp/go-multierror v1.1.1 github.com/ipfs-shipyard/nopfs v0.0.12-0.20231027223058-cde3b5ba964c github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c - github.com/ipfs/boxo v0.16.1-0.20240104124825-38fb74f76b0d + github.com/ipfs/boxo v0.16.1-0.20240104131845-a391d0210287 github.com/ipfs/go-block-format v0.2.0 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 @@ -74,11 +74,11 @@ 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.24.0 - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.42.0 - go.opentelemetry.io/contrib/propagators/autoprop v0.42.0 - go.opentelemetry.io/otel v1.17.0 - go.opentelemetry.io/otel/sdk v1.16.0 - go.opentelemetry.io/otel/trace v1.17.0 + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 + go.opentelemetry.io/contrib/propagators/autoprop v0.46.1 + go.opentelemetry.io/otel v1.21.0 + go.opentelemetry.io/otel/sdk v1.21.0 + go.opentelemetry.io/otel/trace v1.21.0 go.uber.org/dig v1.17.1 go.uber.org/fx v1.20.1 go.uber.org/multierr v1.11.0 @@ -109,7 +109,7 @@ require ( github.com/dgraph-io/ristretto v0.0.2 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/elastic/gosigar v0.14.2 // indirect - github.com/felixge/httpsnoop v1.0.3 // indirect + github.com/felixge/httpsnoop v1.0.4 // indirect github.com/flynn/noise v1.0.0 // indirect github.com/francoispqt/gojay v1.2.13 // indirect github.com/gabriel-vasile/mimetype v1.4.1 // indirect @@ -127,7 +127,7 @@ require ( github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b // indirect github.com/gorilla/mux v1.8.0 // indirect github.com/gorilla/websocket v1.5.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/golang-lru v1.0.2 // indirect github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect @@ -179,7 +179,7 @@ require ( github.com/multiformats/go-varint v0.0.7 // indirect github.com/onsi/ginkgo/v2 v2.13.0 // indirect github.com/opencontainers/runtime-spec v1.1.0 // indirect - github.com/openzipkin/zipkin-go v0.4.1 // indirect + github.com/openzipkin/zipkin-go v0.4.2 // indirect github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 // indirect github.com/pion/datachannel v1.5.5 // indirect github.com/pion/dtls/v2 v2.2.7 // indirect @@ -220,19 +220,17 @@ require ( github.com/whyrusleeping/cbor-gen v0.0.0-20230126041949-52956bd4c9aa // indirect github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f // indirect github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect - go.opentelemetry.io/contrib/propagators/aws v1.17.0 // indirect - go.opentelemetry.io/contrib/propagators/b3 v1.17.0 // indirect - go.opentelemetry.io/contrib/propagators/jaeger v1.17.0 // indirect - go.opentelemetry.io/contrib/propagators/ot v1.17.0 // indirect - go.opentelemetry.io/otel/exporters/jaeger v1.14.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.16.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.16.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.14.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.16.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.14.0 // indirect - go.opentelemetry.io/otel/exporters/zipkin v1.14.0 // indirect - go.opentelemetry.io/otel/metric v1.17.0 // indirect - go.opentelemetry.io/proto/otlp v0.19.0 // indirect + go.opentelemetry.io/contrib/propagators/aws v1.21.1 // indirect + go.opentelemetry.io/contrib/propagators/b3 v1.21.1 // indirect + go.opentelemetry.io/contrib/propagators/jaeger v1.21.1 // indirect + go.opentelemetry.io/contrib/propagators/ot v1.21.1 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.21.0 // indirect + go.opentelemetry.io/otel/exporters/zipkin v1.21.0 // indirect + go.opentelemetry.io/otel/metric v1.21.0 // indirect + go.opentelemetry.io/proto/otlp v1.0.0 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/mock v0.3.0 // indirect go4.org v0.0.0-20230225012048-214862532bf5 // indirect @@ -244,8 +242,9 @@ require ( golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect gonum.org/v1/gonum v0.14.0 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect - google.golang.org/grpc v1.55.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect + google.golang.org/grpc v1.59.0 // indirect gopkg.in/square/go-jose.v2 v2.5.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 8cae85a9f..927614d8b 100644 --- a/go.sum +++ b/go.sum @@ -62,7 +62,6 @@ github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8V github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5 h1:iW0a5ljuFxkLGPNem5Ui+KBjFJzKg4Fv2fnxe4dvzpM= github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5/go.mod h1:Y2QMoi1vgtOIfc+6DhrMOGkLoGzqSV2rKp4Sm+opsyA= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= -github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= @@ -104,12 +103,6 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMn github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs= 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= -github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= -github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/containerd/cgroups v0.0.0-20201119153540-4cbc285b3327/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE= github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM= github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw= @@ -160,16 +153,13 @@ github.com/elgris/jsondiff v0.0.0-20160530203242-765b5c24c302/go.mod h1:qBlWZqWe github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= -github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5 h1:BBso6MBKW8ncyZLv37o+KNyy0HrrHgfnOaGQC2qvN+A= github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5/go.mod h1:JpoxHjuQauoxiFMl1ie8Xc/7TfLuMZ5eOCONd1sUBHg= github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= -github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk= -github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= +github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/flynn/noise v1.0.0 h1:DlTHqmzmvcEiKj+4RYo/imoswx/4r6iBlCMfVtrMXpQ= github.com/flynn/noise v1.0.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag= @@ -223,8 +213,7 @@ github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXP github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= -github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE= +github.com/golang/glog v1.1.2 h1:DVjP2PbBOzHyzA+dn3WhHIq4NdVu3Q+pvivFICf/7fo= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -274,7 +263,7 @@ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -309,9 +298,8 @@ github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWm github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= -github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 h1:BZHcxBETFHIdVyhyEfOvn/RdU/QGdLI4y34qQGjGWO0= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 h1:YBftPWNWd4WwGqtY2yeZL2ef8rHAxPBD8KFhJpmcqms= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg= github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -337,8 +325,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.16.1-0.20240104124825-38fb74f76b0d h1:7tDzalCLHYr4tzrjNrfqZvIki2MEBSrpLBdc0bssDZk= -github.com/ipfs/boxo v0.16.1-0.20240104124825-38fb74f76b0d/go.mod h1:jAgpNQn7T7BnibUeReXcKU9Ha1xmYNyOlwVEl193ow0= +github.com/ipfs/boxo v0.16.1-0.20240104131845-a391d0210287 h1:My5Ct2+5I/+FN2HaFm3VCQB3Y+/A5kcWDGNS0JR1jo8= +github.com/ipfs/boxo v0.16.1-0.20240104131845-a391d0210287/go.mod h1:gCYL6EViui01M8Dr0cY8nOpRAbofxZDWASxbLSrG9Ac= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= @@ -684,8 +672,8 @@ github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFSt github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= -github.com/openzipkin/zipkin-go v0.4.1 h1:kNd/ST2yLLWhaWrkgchya40TJabe8Hioj9udfPcEO5A= -github.com/openzipkin/zipkin-go v0.4.1/go.mod h1:qY0VqDSN1pOBN94dBc6w2GJlWLiovAyg7Qt6/I9HecM= +github.com/openzipkin/zipkin-go v0.4.2 h1:zjqfqHjUpPmB3c1GlCvvgsM1G4LkvqQbBDueDOCg/jA= +github.com/openzipkin/zipkin-go v0.4.2/go.mod h1:ZeVkFjuuBiSy13y8vpSDCjMi9GoI3hPpCJSBx/EYFhY= 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/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= @@ -789,7 +777,6 @@ github.com/quic-go/webtransport-go v0.6.0 h1:CvNsKqc4W2HljHJnoT+rMmbRJybShZ0YPFD github.com/quic-go/webtransport-go v0.6.0/go.mod h1:9KjU4AEBqEQidGHNDkZrb8CAa1abRaosM2yGOyiikEc= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU= -github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= @@ -936,43 +923,38 @@ go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.42.0 h1:pginetY7+onl4qN1vl0xW/V/v6OBZ0vVdH+esuJgvmM= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.42.0/go.mod h1:XiYsayHc36K3EByOO6nbAXnAWbrUxdjUROCEeeROOH8= -go.opentelemetry.io/contrib/propagators/autoprop v0.42.0 h1:s2RzYOAqHVgG23q8fPWYChobUoZM6rJZ98EnylJr66w= -go.opentelemetry.io/contrib/propagators/autoprop v0.42.0/go.mod h1:Mv/tWNtZn+NbALDb2XcItP0OM3lWWZjAfSroINxfW+Y= -go.opentelemetry.io/contrib/propagators/aws v1.17.0 h1:IX8d7l2uRw61BlmZBOTQFaK+y22j6vytMVTs9wFrO+c= -go.opentelemetry.io/contrib/propagators/aws v1.17.0/go.mod h1:pAlCYRWff4uGqRXOVn3WP8pDZ5E0K56bEoG7a1VSL4k= -go.opentelemetry.io/contrib/propagators/b3 v1.17.0 h1:ImOVvHnku8jijXqkwCSyYKRDt2YrnGXD4BbhcpfbfJo= -go.opentelemetry.io/contrib/propagators/b3 v1.17.0/go.mod h1:IkfUfMpKWmynvvE0264trz0sf32NRTZL4nuAN9AbWRc= -go.opentelemetry.io/contrib/propagators/jaeger v1.17.0 h1:Zbpbmwav32Ea5jSotpmkWEl3a6Xvd4tw/3xxGO1i05Y= -go.opentelemetry.io/contrib/propagators/jaeger v1.17.0/go.mod h1:tcTUAlmO8nuInPDSBVfG+CP6Mzjy5+gNV4mPxMbL0IA= -go.opentelemetry.io/contrib/propagators/ot v1.17.0 h1:ufo2Vsz8l76eI47jFjuVyjyB3Ae2DmfiCV/o6Vc8ii0= -go.opentelemetry.io/contrib/propagators/ot v1.17.0/go.mod h1:SbKPj5XGp8K/sGm05XblaIABgMgw2jDczP8gGeuaVLk= -go.opentelemetry.io/otel v1.17.0 h1:MW+phZ6WZ5/uk2nd93ANk/6yJ+dVrvNWUjGhnnFU5jM= -go.opentelemetry.io/otel v1.17.0/go.mod h1:I2vmBGtFaODIVMBSTPVDlJSzBDNf93k60E6Ft0nyjo0= -go.opentelemetry.io/otel/exporters/jaeger v1.14.0 h1:CjbUNd4iN2hHmWekmOqZ+zSCU+dzZppG8XsV+A3oc8Q= -go.opentelemetry.io/otel/exporters/jaeger v1.14.0/go.mod h1:4Ay9kk5vELRrbg5z4cpP9EtmQRFap2Wb0woPG4lujZA= -go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.16.0 h1:t4ZwRPU+emrcvM2e9DHd0Fsf0JTPVcbfa/BhTDF03d0= -go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.16.0/go.mod h1:vLarbg68dH2Wa77g71zmKQqlQ8+8Rq3GRG31uc0WcWI= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.16.0 h1:cbsD4cUcviQGXdw8+bo5x2wazq10SKz8hEbtCRPcU78= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.16.0/go.mod h1:JgXSGah17croqhJfhByOLVY719k1emAXC8MVhCIJlRs= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.14.0 h1:ap+y8RXX3Mu9apKVtOkM6WSFESLM8K3wNQyOU8sWHcc= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.14.0/go.mod h1:5w41DY6S9gZrbjuq6Y+753e96WfPha5IcsOSZTtullM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.16.0 h1:iqjq9LAB8aK++sKVcELezzn655JnBNdsDhghU4G/So8= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.16.0/go.mod h1:hGXzO5bhhSHZnKvrDaXB82Y9DRFour0Nz/KrBh7reWw= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.14.0 h1:sEL90JjOO/4yhquXl5zTAkLLsZ5+MycAgX99SDsxGc8= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.14.0/go.mod h1:oCslUcizYdpKYyS9e8srZEqM6BB8fq41VJBjLAE6z1w= -go.opentelemetry.io/otel/exporters/zipkin v1.14.0 h1:reEVE1upBF9tcujgvSqLJS0SrI7JQPaTKP4s4rymnSs= -go.opentelemetry.io/otel/exporters/zipkin v1.14.0/go.mod h1:RcjvOAcvhzcufQP8aHmzRw1gE9g/VEZufDdo2w+s4sk= -go.opentelemetry.io/otel/metric v1.17.0 h1:iG6LGVz5Gh+IuO0jmgvpTB6YVrCGngi8QGm+pMd8Pdc= -go.opentelemetry.io/otel/metric v1.17.0/go.mod h1:h4skoxdZI17AxwITdmdZjjYJQH5nzijUUjm+wtPph5o= -go.opentelemetry.io/otel/sdk v1.16.0 h1:Z1Ok1YsijYL0CSJpHt4cS3wDDh7p572grzNrBMiMWgE= -go.opentelemetry.io/otel/sdk v1.16.0/go.mod h1:tMsIuKXuuIWPBAOrH+eHtvhTL+SntFtXF9QD68aP6p4= -go.opentelemetry.io/otel/trace v1.17.0 h1:/SWhSRHmDPOImIAetP1QAeMnZYiQXrTy4fMMYOdSKWQ= -go.opentelemetry.io/otel/trace v1.17.0/go.mod h1:I/4vKTgFclIsXRVucpH25X0mpFSczM7aHeaz0ZBLWjY= -go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= -go.opentelemetry.io/proto/otlp v0.19.0 h1:IVN6GR+mhC4s5yfcTbmzHYODqvWAp3ZedA2SJPI1Nnw= -go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 h1:aFJWCqJMNjENlcleuuOkGAPH82y0yULBScfXcIEdS24= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1/go.mod h1:sEGXWArGqc3tVa+ekntsN65DmVbVeW+7lTKTjZF3/Fo= +go.opentelemetry.io/contrib/propagators/autoprop v0.46.1 h1:cXTYcMjY0dsYokAuo8LbNBQxpF8VgTHdiHJJ1zlIXl4= +go.opentelemetry.io/contrib/propagators/autoprop v0.46.1/go.mod h1:WZxgny1/6+j67B1s72PLJ4bGjidoWFzSmLNfJKVt2bo= +go.opentelemetry.io/contrib/propagators/aws v1.21.1 h1:uQIQIDWb0gzyvon2ICnghpLAf9w7ADOCUiIiwCQgR2o= +go.opentelemetry.io/contrib/propagators/aws v1.21.1/go.mod h1:kCcto3ACQxm+VrkQX/NK/TkDmAd99MQhvffzyTKhzL4= +go.opentelemetry.io/contrib/propagators/b3 v1.21.1 h1:WPYiUgmw3+b7b3sQ1bFBFAf0q+Di9dvNc3AtYfnT4RQ= +go.opentelemetry.io/contrib/propagators/b3 v1.21.1/go.mod h1:EmzokPoSqsYMBVK4nRnhsfm5mbn8J1eDuz/U1UaQaWg= +go.opentelemetry.io/contrib/propagators/jaeger v1.21.1 h1:f4beMGDKiVzg9IcX7/VuWVy+oGdjx3dNJ72YehmtY5k= +go.opentelemetry.io/contrib/propagators/jaeger v1.21.1/go.mod h1:U9jhkEl8d1LL+QXY7q3kneJWJugiN3kZJV2OWz3hkBY= +go.opentelemetry.io/contrib/propagators/ot v1.21.1 h1:3TN5vkXjKYWp0YdMcnUEC/A+pBPvqz9V3nCS2xmcurk= +go.opentelemetry.io/contrib/propagators/ot v1.21.1/go.mod h1:oy0MYCbS/b3cqUDW37wBWtlwBIsutngS++Lklpgh+fc= +go.opentelemetry.io/otel v1.21.0 h1:hzLeKBZEL7Okw2mGzZ0cc4k/A7Fta0uoPgaJCr8fsFc= +go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 h1:cl5P5/GIfFh4t6xyruOgJP5QiA1pw4fYYdv6nc6CBWw= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0/go.mod h1:zgBdWWAu7oEEMC06MMKc5NLbA/1YDXV1sMpSqEeLQLg= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0 h1:tIqheXEFWAZ7O8A7m+J0aPTmpJN3YQ7qetUAdkkkKpk= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0/go.mod h1:nUeKExfxAQVbiVFn32YXpXZZHZ61Cc3s3Rn1pDBGAb0= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0 h1:digkEZCJWobwBqMwC0cwCq8/wkkRy/OowZg5OArWZrM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0/go.mod h1:/OpE/y70qVkndM0TrxT4KBoN3RsFZP0QaofcfYrj76I= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.21.0 h1:VhlEQAPp9R1ktYfrPk5SOryw1e9LDDTZCbIPFrho0ec= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.21.0/go.mod h1:kB3ufRbfU+CQ4MlUcqtW8Z7YEOBeK2DJ6CmR5rYYF3E= +go.opentelemetry.io/otel/exporters/zipkin v1.21.0 h1:D+Gv6lSfrFBWmQYyxKjDd0Zuld9SRXpIrEsKZvE4DO4= +go.opentelemetry.io/otel/exporters/zipkin v1.21.0/go.mod h1:83oMKR6DzmHisFOW3I+yIMGZUTjxiWaiBI8M8+TU5zE= +go.opentelemetry.io/otel/metric v1.21.0 h1:tlYWfeo+Bocx5kLEloTjbcDwBuELRrIFxwdQ36PlJu4= +go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM= +go.opentelemetry.io/otel/sdk v1.21.0 h1:FTt8qirL1EysG6sTQRZ5TokkU8d0ugCj8htOgThZXQ8= +go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E= +go.opentelemetry.io/otel/trace v1.21.0 h1:WD9i5gzvoUPuXIXH24ZNBudiarZDKuekPqi/E8fpfLc= +go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ= +go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I= +go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= @@ -983,7 +965,7 @@ go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= go.uber.org/fx v1.20.1 h1:zVwVQGS8zYvhh9Xxcu4w1M6ESyeMzebzj2NbSayZ4Mk= go.uber.org/fx v1.20.1/go.mod h1:iSYNbHf2y55acNCwCXKx7LbWb5WG1Bnue5RDXz1OREg= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= -go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/mock v0.3.0 h1:3mUxI1No2/60yUYax92Pt8eNOEecx2D3lcXZh2NEZJo= go.uber.org/mock v0.3.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= @@ -1126,7 +1108,6 @@ golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4Iltr golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/oauth2 v0.12.0 h1:smVPGxink+n1ZI5pkQa8y6fZT0RW0MgCO5bFpepy4B4= golang.org/x/oauth2 v0.12.0/go.mod h1:A74bZ3aGXgCY0qaIC9Ahg6Lglin4AMAco8cIv9baba4= @@ -1240,7 +1221,6 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= @@ -1374,16 +1354,17 @@ google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfG google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 h1:DdoeryqhaXp1LtT/emMP1BRJPHHKFi5akj/nbx/zNTA= -google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s= +google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d h1:VBu5YqKPv6XiJ199exd8Br+Aetz+o08F+PLMnwJQHAY= +google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d h1:DoPTO70H+bcDXcd39vOqb2viZxgqeBeSGtZ55yZU4/Q= +google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d/go.mod h1:KjSP20unUpOx5kyQUFa7k4OJg0qeJ7DEZflGDu2p6Bk= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d h1:uvYuEyMHKNt+lT4K3bN6fGswmK8qSvcreM3BwjDh+y4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= @@ -1399,13 +1380,9 @@ google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKa google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= -google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc v1.55.0 h1:3Oj82/tFSCeUrRTg/5E/7d/W5A1tj6Ky1ABAuZuv5ag= -google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8= +google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk= +google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -1418,7 +1395,6 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= @@ -1440,7 +1416,6 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkep gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 2cb03508a..d214f4f52 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -85,7 +85,7 @@ require ( github.com/golangci/misspell v0.4.1 // indirect github.com/golangci/revgrep v0.0.0-20220804021717-745bb2f7c2e6 // indirect github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4 // indirect - github.com/google/go-cmp v0.5.9 // indirect + github.com/google/go-cmp v0.6.0 // indirect github.com/google/gopacket v1.1.19 // indirect github.com/google/uuid v1.4.0 // indirect github.com/gordonklaus/ineffassign v0.0.0-20230610083614-0e73809eb601 // indirect @@ -103,7 +103,7 @@ require ( github.com/hexops/gotextdiff v1.0.3 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/ipfs/bbloom v0.0.4 // indirect - github.com/ipfs/boxo v0.16.1-0.20240104124825-38fb74f76b0d // indirect + github.com/ipfs/boxo v0.16.1-0.20240104131845-a391d0210287 // indirect github.com/ipfs/go-block-format v0.2.0 // indirect github.com/ipfs/go-cid v0.4.1 // indirect github.com/ipfs/go-datastore v0.6.0 // indirect @@ -233,9 +233,9 @@ require ( github.com/ykadowak/zerologlint v0.1.3 // indirect gitlab.com/bosi/decorder v0.4.0 // indirect go.opencensus.io v0.24.0 // indirect - go.opentelemetry.io/otel v1.19.0 // indirect - go.opentelemetry.io/otel/metric v1.19.0 // indirect - go.opentelemetry.io/otel/trace v1.19.0 // indirect + go.opentelemetry.io/otel v1.21.0 // indirect + go.opentelemetry.io/otel/metric v1.21.0 // indirect + go.opentelemetry.io/otel/trace v1.21.0 // indirect go.tmz.dev/musttag v0.7.1 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.26.0 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 8681e257c..91cdf538b 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -272,8 +272,8 @@ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= @@ -342,8 +342,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.16.1-0.20240104124825-38fb74f76b0d h1:7tDzalCLHYr4tzrjNrfqZvIki2MEBSrpLBdc0bssDZk= -github.com/ipfs/boxo v0.16.1-0.20240104124825-38fb74f76b0d/go.mod h1:jAgpNQn7T7BnibUeReXcKU9Ha1xmYNyOlwVEl193ow0= +github.com/ipfs/boxo v0.16.1-0.20240104131845-a391d0210287 h1:My5Ct2+5I/+FN2HaFm3VCQB3Y+/A5kcWDGNS0JR1jo8= +github.com/ipfs/boxo v0.16.1-0.20240104131845-a391d0210287/go.mod h1:gCYL6EViui01M8Dr0cY8nOpRAbofxZDWASxbLSrG9Ac= github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs= github.com/ipfs/go-block-format v0.2.0/go.mod h1:+jpL11nFx5A/SPpsoBn6Bzkra/zaArfSmsknbPMYgzM= github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= @@ -771,12 +771,12 @@ go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/otel v1.19.0 h1:MuS/TNf4/j4IXsZuJegVzI1cwut7Qc00344rgH7p8bs= -go.opentelemetry.io/otel v1.19.0/go.mod h1:i0QyjOq3UPoTzff0PJB2N66fb4S0+rSbSB15/oyH9fY= -go.opentelemetry.io/otel/metric v1.19.0 h1:aTzpGtV0ar9wlV4Sna9sdJyII5jTVJEvKETPiOKwvpE= -go.opentelemetry.io/otel/metric v1.19.0/go.mod h1:L5rUsV9kM1IxCj1MmSdS+JQAcVm319EUrDVLrt7jqt8= -go.opentelemetry.io/otel/trace v1.19.0 h1:DFVQmlVbfVeOuBRrwdtaehRrWiL1JoVs9CPIQ1Dzxpg= -go.opentelemetry.io/otel/trace v1.19.0/go.mod h1:mfaSyvGyEJEI0nyV2I4qhNQnbBOUUmYZpYojqMnX2vo= +go.opentelemetry.io/otel v1.21.0 h1:hzLeKBZEL7Okw2mGzZ0cc4k/A7Fta0uoPgaJCr8fsFc= +go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo= +go.opentelemetry.io/otel/metric v1.21.0 h1:tlYWfeo+Bocx5kLEloTjbcDwBuELRrIFxwdQ36PlJu4= +go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM= +go.opentelemetry.io/otel/trace v1.21.0 h1:WD9i5gzvoUPuXIXH24ZNBudiarZDKuekPqi/E8fpfLc= +go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ= go.tmz.dev/musttag v0.7.1 h1:9lFmeSFnFfPuMq4IksHGomItE6NgKMNW2Nt2FPOhCfU= go.tmz.dev/musttag v0.7.1/go.mod h1:oJLkpR56EsIryktZJk/B0IroSMi37YWver47fibGh5U= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= diff --git a/tracing/doc.go b/tracing/doc.go index 84a58febe..d442ea2db 100644 --- a/tracing/doc.go +++ b/tracing/doc.go @@ -10,21 +10,12 @@ // // OTEL_TRACES_EXPORTER: a comma-separated list of exporters: // - otlp -// - jaeger // - zipkin // - file // // Different exporters have their own set of environment variables, depending on the exporter. These are typically // standard environment variables. Some common ones: // -// Jaeger: -// -// - OTEL_EXPORTER_JAEGER_AGENT_HOST -// - OTEL_EXPORTER_JAEGER_AGENT_PORT -// - OTEL_EXPORTER_JAEGER_ENDPOINT -// - OTEL_EXPORTER_JAEGER_USER -// - OTEL_EXPORTER_JAEGER_PASSWORD -// // OTLP HTTP/gRPC: // // - OTEL_EXPORTER_OTLP_PROTOCOL @@ -47,21 +38,24 @@ // default: `$PWD/traces.json` // // For example, if you run a local IPFS daemon, you can use the jaegertracing/all-in-one Docker image to run -// a full Jaeger stack and configure go-ipfs to publish traces to it: +// a full Jaeger stack and configure Kubo to publish traces to it: // -// docker run -d --name jaeger \ -// -e COLLECTOR_ZIPKIN_HOST_PORT=:9411 \ -// -p 5775:5775/udp \ -// -p 6831:6831/udp \ -// -p 6832:6832/udp \ -// -p 5778:5778 \ -// -p 16686:16686 \ -// -p 14268:14268 \ -// -p 14269:14269 \ -// -p 14250:14250 \ -// -p 9411:9411 \ -// jaegertracing/all-in-one -// OTEL_TRACES_EXPORTER=jaeger ipfs daemon +// docker run -d --rm --name jaeger \ +// -e COLLECTOR_OTLP_ENABLED=true \ +// -e COLLECTOR_ZIPKIN_HOST_PORT=:9411 \ +// -p 5775:5775/udp \ +// -p 6831:6831/udp \ +// -p 6832:6832/udp \ +// -p 5778:5778 \ +// -p 16686:16686 \ +// -p 14250:14250 \ +// -p 14268:14268 \ +// -p 14269:14269 \ +// -p 4317:4317 \ +// -p 4318:4318 \ +// -p 9411:9411 \ +// jaegertracing/all-in-one +// OTEL_EXPORTER_OTLP_INSECURE=true OTEL_TRACES_EXPORTER=otlp ipfs daemon --init // // # In this example the Jaeger UI is available at http://localhost:16686. // diff --git a/tracing/tracing.go b/tracing/tracing.go index 8fd898d7b..061d5a7aa 100644 --- a/tracing/tracing.go +++ b/tracing/tracing.go @@ -11,6 +11,7 @@ import ( "go.opentelemetry.io/otel/sdk/trace" semconv "go.opentelemetry.io/otel/semconv/v1.4.0" traceapi "go.opentelemetry.io/otel/trace" + "go.opentelemetry.io/otel/trace/noop" ) // shutdownTracerProvider adds a shutdown method for tracer providers. @@ -18,6 +19,8 @@ import ( // Note that this doesn't directly use the provided TracerProvider interface // to avoid build breaking go-ipfs if new methods are added to it. type shutdownTracerProvider interface { + traceapi.TracerProvider + Tracer(instrumentationName string, opts ...traceapi.TracerOption) traceapi.Tracer Shutdown(ctx context.Context) error } @@ -34,7 +37,7 @@ func NewTracerProvider(ctx context.Context) (shutdownTracerProvider, error) { return nil, err } if len(exporters) == 0 { - return &noopShutdownTracerProvider{TracerProvider: traceapi.NewNoopTracerProvider()}, nil + return &noopShutdownTracerProvider{TracerProvider: noop.NewTracerProvider()}, nil } options := []trace.TracerProviderOption{} From 8a421868f0e19abaa7d79540d8bee657931bddf4 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Mon, 8 Jan 2024 11:43:44 +0100 Subject: [PATCH 0980/1212] feat(pinning): allow for overwriting pin name --- core/commands/pin/pin.go | 6 ++--- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 +-- go.mod | 2 +- go.sum | 4 +-- test/cli/pins_test.go | 34 ++++++++++++++++++++------ test/dependencies/go.mod | 2 +- test/dependencies/go.sum | 4 +-- 8 files changed, 38 insertions(+), 20 deletions(-) diff --git a/core/commands/pin/pin.go b/core/commands/pin/pin.go index d75d5d386..ca3c932bf 100644 --- a/core/commands/pin/pin.go +++ b/core/commands/pin/pin.go @@ -71,10 +71,8 @@ Use 'pin ls -t recursive' to only list roots of recursively pinned DAGs (significantly faster when many big DAGs are pinned recursively) Default pin name is empty. Pass '--name' to 'pin add' to set one -and use 'pin ls --names' to see it. -Pin add is idempotent: pinning CID which is already pinned won't change -the name, value passed with '--name' with the original pin is preserved. -To rename pin, use 'pin rm' and 'pin add --name'. +and use 'pin ls --names' to see it. Pinning a second time with a different +name will update the name of the pin. If daemon is running, any missing blocks will be retrieved from the network. It may take some time. Pass '--progress' to track the progress. diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 99cdca600..d3e438ca0 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.20 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.16.1-0.20240104131845-a391d0210287 + github.com/ipfs/boxo v0.16.1-0.20240109085802-d13d712f1c4e github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.32.2 github.com/multiformats/go-multiaddr v0.12.0 diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 59c684345..3f0463489 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -261,8 +261,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.16.1-0.20240104131845-a391d0210287 h1:My5Ct2+5I/+FN2HaFm3VCQB3Y+/A5kcWDGNS0JR1jo8= -github.com/ipfs/boxo v0.16.1-0.20240104131845-a391d0210287/go.mod h1:gCYL6EViui01M8Dr0cY8nOpRAbofxZDWASxbLSrG9Ac= +github.com/ipfs/boxo v0.16.1-0.20240109085802-d13d712f1c4e h1:GFMm0GO3tTLmjJ6uNZnTq0HpYV/kygZhe1sKYHQ/aVc= +github.com/ipfs/boxo v0.16.1-0.20240109085802-d13d712f1c4e/go.mod h1:gCYL6EViui01M8Dr0cY8nOpRAbofxZDWASxbLSrG9Ac= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= diff --git a/go.mod b/go.mod index 9212964c2..134b16bd1 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,7 @@ require ( github.com/hashicorp/go-multierror v1.1.1 github.com/ipfs-shipyard/nopfs v0.0.12-0.20231027223058-cde3b5ba964c github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c - github.com/ipfs/boxo v0.16.1-0.20240104131845-a391d0210287 + github.com/ipfs/boxo v0.16.1-0.20240109085802-d13d712f1c4e github.com/ipfs/go-block-format v0.2.0 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 diff --git a/go.sum b/go.sum index 927614d8b..4afe6d356 100644 --- a/go.sum +++ b/go.sum @@ -325,8 +325,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.16.1-0.20240104131845-a391d0210287 h1:My5Ct2+5I/+FN2HaFm3VCQB3Y+/A5kcWDGNS0JR1jo8= -github.com/ipfs/boxo v0.16.1-0.20240104131845-a391d0210287/go.mod h1:gCYL6EViui01M8Dr0cY8nOpRAbofxZDWASxbLSrG9Ac= +github.com/ipfs/boxo v0.16.1-0.20240109085802-d13d712f1c4e h1:GFMm0GO3tTLmjJ6uNZnTq0HpYV/kygZhe1sKYHQ/aVc= +github.com/ipfs/boxo v0.16.1-0.20240109085802-d13d712f1c4e/go.mod h1:gCYL6EViui01M8Dr0cY8nOpRAbofxZDWASxbLSrG9Ac= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= diff --git a/test/cli/pins_test.go b/test/cli/pins_test.go index a57f1b89b..415da8d3b 100644 --- a/test/cli/pins_test.go +++ b/test/cli/pins_test.go @@ -210,6 +210,10 @@ func TestPins(t *testing.T) { testPins(t, testPinsArgs{runDaemon: true, lsArg: "--stream", baseArg: "--cid-base=base32"}) }) + pinLs := func(node *harness.Node, args ...string) []string { + return strings.Split(node.IPFS(StrCat("pin", "ls", args)...).Stdout.Trimmed(), "\n") + } + t.Run("test pinning with names cli text output", func(t *testing.T) { t.Parallel() @@ -224,24 +228,40 @@ func TestPins(t *testing.T) { outBRegular := cidBStr + " recursive" outBDetailed := outBRegular + " testPin" - pinLs := func(args ...string) []string { - return strings.Split(node.IPFS(StrCat("pin", "ls", args)...).Stdout.Trimmed(), "\n") - } - - lsOut := pinLs("-t=recursive") + lsOut := pinLs(node, "-t=recursive") require.Contains(t, lsOut, outARegular) require.NotContains(t, lsOut, outADetailed) - lsOut = pinLs("-t=recursive", "--names") + lsOut = pinLs(node, "-t=recursive", "--names") require.Contains(t, lsOut, outADetailed) require.NotContains(t, lsOut, outARegular) _ = node.IPFS("pin", "update", cidAStr, cidBStr) - lsOut = pinLs("-t=recursive", "--names") + lsOut = pinLs(node, "-t=recursive", "--names") require.Contains(t, lsOut, outBDetailed) require.NotContains(t, lsOut, outADetailed) }) + t.Run("test overwriting pin with name", func(t *testing.T) { + t.Parallel() + + node := harness.NewT(t).NewNode().Init() + cidStr := node.IPFSAddStr(RandomStr(1000), "--pin=false") + + outBefore := cidStr + " recursive A" + outAfter := cidStr + " recursive B" + + _ = node.IPFS("pin", "add", "--name", "A", cidStr) + lsOut := pinLs(node, "-t=recursive", "--names") + require.Contains(t, lsOut, outBefore) + require.NotContains(t, lsOut, outAfter) + + _ = node.IPFS("pin", "add", "--name", "B", cidStr) + lsOut = pinLs(node, "-t=recursive", "--names") + require.Contains(t, lsOut, outAfter) + require.NotContains(t, lsOut, outBefore) + }) + // JSON that is also the wire format of /api/v0 t.Run("test pinning with names json output", func(t *testing.T) { t.Parallel() diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index d214f4f52..c788ea081 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -103,7 +103,7 @@ require ( github.com/hexops/gotextdiff v1.0.3 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/ipfs/bbloom v0.0.4 // indirect - github.com/ipfs/boxo v0.16.1-0.20240104131845-a391d0210287 // indirect + github.com/ipfs/boxo v0.16.1-0.20240109085802-d13d712f1c4e // indirect github.com/ipfs/go-block-format v0.2.0 // indirect github.com/ipfs/go-cid v0.4.1 // indirect github.com/ipfs/go-datastore v0.6.0 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 91cdf538b..186b01192 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -342,8 +342,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.16.1-0.20240104131845-a391d0210287 h1:My5Ct2+5I/+FN2HaFm3VCQB3Y+/A5kcWDGNS0JR1jo8= -github.com/ipfs/boxo v0.16.1-0.20240104131845-a391d0210287/go.mod h1:gCYL6EViui01M8Dr0cY8nOpRAbofxZDWASxbLSrG9Ac= +github.com/ipfs/boxo v0.16.1-0.20240109085802-d13d712f1c4e h1:GFMm0GO3tTLmjJ6uNZnTq0HpYV/kygZhe1sKYHQ/aVc= +github.com/ipfs/boxo v0.16.1-0.20240109085802-d13d712f1c4e/go.mod h1:gCYL6EViui01M8Dr0cY8nOpRAbofxZDWASxbLSrG9Ac= github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs= github.com/ipfs/go-block-format v0.2.0/go.mod h1:+jpL11nFx5A/SPpsoBn6Bzkra/zaArfSmsknbPMYgzM= github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= From 2f91074b5145865281a1c70392cee54afa2d8bd0 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Tue, 9 Jan 2024 10:42:00 +0100 Subject: [PATCH 0981/1212] ci: fix helia interop Fixes #10275 See https://github.com/ipfs/helia/issues/359#issuecomment-1882662783 --- .github/workflows/build.yml | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fd7ba120d..3b30da2b4 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -52,9 +52,6 @@ jobs: defaults: run: shell: bash - strategy: - matrix: - repo-to-test-against: ["helia", "helia-ipns", "helia-unixfs", "helia-car", "helia-dag-json", "helia-dag-cbor", "helia-json", "helia-mfs"] # this needs to be manually kept in sync as new helia tests are written steps: - uses: actions/setup-node@v3 with: @@ -69,17 +66,19 @@ jobs: - uses: actions/cache@v3 with: path: ${{ steps.npm-cache-dir.outputs.dir }} - key: ${{ runner.os }}-${{ github.job }}-${{ matrix.repo-to-test-against }}-${{ hashFiles('**/package-lock.json') }} - restore-keys: ${{ runner.os }}-${{ github.job }}-${{ matrix.repo-to-test-against }}- + key: ${{ runner.os }}-${{ github.job }}-helia-${{ hashFiles('**/package-lock.json') }} + restore-keys: ${{ runner.os }}-${{ github.job }}-helia- - run: sudo apt update - run: sudo apt install -y libxkbcommon0 libxdamage1 libgbm1 libpango-1.0-0 libcairo2 # dependencies for playwright - uses: actions/checkout@v4 with: - repository: ipfs/${{ matrix.repo-to-test-against }} - fetch-depth: 0 + repository: ipfs/helia + fetch-depth: 1 path: interop + ref: 'ea5533c794df844c9fb9812e85e2f5e6af09efeb' # temporary while this commit is being released - name: Checkout latest tag run: | + exit 0 # temporary while ea5533c794df844c9fb9812e85e2f5e6af09efeb is released export TAG="$(git describe --tags --abbrev=0)" echo "Running tests against: $TAG" git checkout "$TAG" From 2905b59529be7897b5f73c4c8334665c6a70344f Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Wed, 10 Jan 2024 16:11:46 +0100 Subject: [PATCH 0982/1212] chore: update boxo --- docs/examples/kubo-as-a-library/go.mod | 62 +++++----- docs/examples/kubo-as-a-library/go.sum | 140 +++++++++++----------- go.mod | 70 +++++------ go.sum | 154 ++++++++++++------------- test/dependencies/go.mod | 26 ++--- test/dependencies/go.sum | 66 +++++------ 6 files changed, 250 insertions(+), 268 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index d3e438ca0..531207eed 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,17 +7,17 @@ go 1.20 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.16.1-0.20240109085802-d13d712f1c4e + github.com/ipfs/boxo v0.16.1-0.20240110145317-d8e9d95f7d05 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.32.2 - github.com/multiformats/go-multiaddr v0.12.0 + github.com/multiformats/go-multiaddr v0.12.1 ) require ( bazil.org/fuse v0.0.0-20200117225306-7b5117fecadc // indirect github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 // indirect github.com/Jorropo/jsync v1.0.1 // indirect - github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect + github.com/alecthomas/units v0.0.0-20231202071711-9a357b53e9c9 // indirect github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5 // indirect github.com/benbjohnson/clock v1.3.5 // indirect github.com/beorn7/perks v1.0.1 // indirect @@ -28,7 +28,7 @@ require ( github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/containerd/cgroups v1.1.0 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect - github.com/crackcomm/go-gitignore v0.0.0-20170627025303-887ab5e44cc3 // indirect + github.com/crackcomm/go-gitignore v0.0.0-20231225121904-e25f5bc08668 // indirect github.com/cskr/pubsub v1.0.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect @@ -39,11 +39,11 @@ require ( github.com/dustin/go-humanize v1.0.1 // indirect github.com/elastic/gosigar v0.14.2 // indirect github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5 // indirect - github.com/flynn/noise v1.0.0 // indirect + github.com/flynn/noise v1.0.1 // indirect github.com/francoispqt/gojay v1.2.13 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect - github.com/gabriel-vasile/mimetype v1.4.1 // indirect - github.com/go-logr/logr v1.3.0 // indirect + github.com/gabriel-vasile/mimetype v1.4.3 // indirect + github.com/go-logr/logr v1.4.1 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/godbus/dbus/v5 v5.1.0 // indirect @@ -51,10 +51,10 @@ require ( github.com/golang/protobuf v1.5.3 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/gopacket v1.1.19 // indirect - github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b // indirect - github.com/google/uuid v1.4.0 // indirect + github.com/google/pprof v0.0.0-20231229205709-960ae82b1e42 // indirect + github.com/google/uuid v1.5.0 // indirect github.com/gorilla/websocket v1.5.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/golang-lru v1.0.2 // indirect @@ -78,7 +78,7 @@ require ( github.com/ipfs/go-ipfs-pq v0.0.3 // indirect github.com/ipfs/go-ipfs-redirects-file v0.1.1 // indirect github.com/ipfs/go-ipfs-util v0.0.3 // indirect - github.com/ipfs/go-ipld-cbor v0.0.6 // indirect + github.com/ipfs/go-ipld-cbor v0.1.0 // indirect github.com/ipfs/go-ipld-format v0.6.0 // indirect github.com/ipfs/go-ipld-git v0.1.1 // indirect github.com/ipfs/go-ipld-legacy v0.2.1 // indirect @@ -86,14 +86,14 @@ require ( github.com/ipfs/go-log/v2 v2.5.1 // indirect github.com/ipfs/go-metrics-interface v0.0.1 // indirect github.com/ipfs/go-peertaskqueue v0.8.1 // indirect - github.com/ipfs/go-unixfsnode v1.8.1 // indirect - github.com/ipld/go-car/v2 v2.10.2-0.20230622090957-499d0c909d33 // indirect + github.com/ipfs/go-unixfsnode v1.9.0 // indirect + github.com/ipld/go-car/v2 v2.13.1 // indirect github.com/ipld/go-codec-dagpb v1.6.0 // indirect github.com/ipld/go-ipld-prime v0.21.0 // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect github.com/jbenet/goprocess v0.1.4 // indirect - github.com/klauspost/compress v1.17.2 // indirect + github.com/klauspost/compress v1.17.4 // indirect github.com/klauspost/cpuid/v2 v2.2.6 // indirect github.com/koron/go-ssdp v0.0.4 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect @@ -132,7 +132,7 @@ require ( github.com/multiformats/go-multihash v0.2.3 // indirect github.com/multiformats/go-multistream v0.5.0 // indirect github.com/multiformats/go-varint v0.0.7 // indirect - github.com/onsi/ginkgo/v2 v2.13.0 // indirect + github.com/onsi/ginkgo/v2 v2.13.2 // indirect github.com/opencontainers/runtime-spec v1.1.0 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/openzipkin/zipkin-go v0.4.2 // indirect @@ -157,13 +157,13 @@ require ( github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/polydawn/refmt v0.89.0 // indirect - github.com/prometheus/client_golang v1.17.0 // indirect + github.com/prometheus/client_golang v1.18.0 // indirect github.com/prometheus/client_model v0.5.0 // indirect github.com/prometheus/common v0.45.0 // indirect github.com/prometheus/procfs v0.12.0 // indirect github.com/quic-go/qpack v0.4.0 // indirect - github.com/quic-go/qtls-go1-20 v0.3.4 // indirect - github.com/quic-go/quic-go v0.39.4 // indirect + github.com/quic-go/qtls-go1-20 v0.4.1 // indirect + github.com/quic-go/quic-go v0.40.1 // indirect github.com/quic-go/webtransport-go v0.6.0 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/samber/lo v1.39.0 // indirect @@ -173,7 +173,7 @@ require ( github.com/ucarion/urlpath v0.0.0-20200424170820-7ccc79b76bbb // indirect github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc // indirect github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11 // indirect - github.com/whyrusleeping/cbor-gen v0.0.0-20230126041949-52956bd4c9aa // indirect + github.com/whyrusleeping/cbor-gen v0.0.0-20240109153615-66e95c3e8a87 // indirect github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f // indirect github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 // indirect @@ -190,24 +190,24 @@ require ( go.opentelemetry.io/proto/otlp v1.0.0 // indirect go.uber.org/dig v1.17.1 // indirect go.uber.org/fx v1.20.1 // indirect - go.uber.org/mock v0.3.0 // indirect + go.uber.org/mock v0.4.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.26.0 // indirect go4.org v0.0.0-20230225012048-214862532bf5 // indirect - golang.org/x/crypto v0.16.0 // indirect - golang.org/x/exp v0.0.0-20231214170342-aacd6d4b4611 // indirect + golang.org/x/crypto v0.18.0 // indirect + golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc // indirect golang.org/x/mod v0.14.0 // indirect - golang.org/x/net v0.19.0 // indirect - golang.org/x/sync v0.5.0 // indirect - golang.org/x/sys v0.15.0 // indirect + golang.org/x/net v0.20.0 // indirect + golang.org/x/sync v0.6.0 // indirect + golang.org/x/sys v0.16.0 // indirect golang.org/x/text v0.14.0 // indirect - golang.org/x/tools v0.16.0 // indirect - golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect + golang.org/x/tools v0.16.1 // indirect + golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect gonum.org/v1/gonum v0.14.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect - google.golang.org/grpc v1.59.0 // indirect - google.golang.org/protobuf v1.31.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240108191215-35c7eff3a6b1 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240108191215-35c7eff3a6b1 // indirect + google.golang.org/grpc v1.60.1 // indirect + google.golang.org/protobuf v1.32.0 // indirect gopkg.in/square/go-jose.v2 v2.5.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect lukechampine.com/blake3 v1.2.1 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 3f0463489..601831a1d 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -34,8 +34,8 @@ github.com/Jorropo/jsync v1.0.1/go.mod h1:jCOZj3vrBCri3bSU3ErUYvevKlnbssrXeCivyb github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= -github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 h1:s6gZFSlWYmbqAuRjVTiNNhvNRfY2Wxp9nhfyel4rklc= -github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= +github.com/alecthomas/units v0.0.0-20231202071711-9a357b53e9c9 h1:ez/4by2iGztzR4L0zgAOR8lTQK9VlyBVVd7G4omaOQs= +github.com/alecthomas/units v0.0.0-20231202071711-9a357b53e9c9/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5 h1:iW0a5ljuFxkLGPNem5Ui+KBjFJzKg4Fv2fnxe4dvzpM= github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5/go.mod h1:Y2QMoi1vgtOIfc+6DhrMOGkLoGzqSV2rKp4Sm+opsyA= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= @@ -89,8 +89,8 @@ github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSV 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/crackcomm/go-gitignore v0.0.0-20231225121904-e25f5bc08668 h1:ZFUue+PNxmHlu7pYv+IYMtqlaO/0VwaGEqKepZf9JpA= +github.com/crackcomm/go-gitignore v0.0.0-20231225121904-e25f5bc08668/go.mod h1:p1d6YEZWvFzEh4KLyvBcVSnrfNDDvK2zfK/4x2v/4pE= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cskr/pubsub v1.0.2 h1:vlOzMhl6PFn60gRlTQQsIfVwaPB/B/8MziK8FhEPt/0= github.com/cskr/pubsub v1.0.2/go.mod h1:/8MzYXk/NJAz782G8RPkFzXTZVu63VotefPnR9TIRis= @@ -126,8 +126,8 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7 github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5 h1:BBso6MBKW8ncyZLv37o+KNyy0HrrHgfnOaGQC2qvN+A= github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5/go.mod h1:JpoxHjuQauoxiFMl1ie8Xc/7TfLuMZ5eOCONd1sUBHg= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= -github.com/flynn/noise v1.0.0 h1:DlTHqmzmvcEiKj+4RYo/imoswx/4r6iBlCMfVtrMXpQ= -github.com/flynn/noise v1.0.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag= +github.com/flynn/noise v1.0.1 h1:vPp/jdQLXC6ppsXSj/pM3W1BIJ5FEHE2TulSJBpb43Y= +github.com/flynn/noise v1.0.1/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag= github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk= github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= @@ -137,8 +137,8 @@ github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMo github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= -github.com/gabriel-vasile/mimetype v1.4.1 h1:TRWk7se+TOjCYgRth7+1/OYLNiRNIotknkFtf/dnN7Q= -github.com/gabriel-vasile/mimetype v1.4.1/go.mod h1:05Vi0w3Y9c/lNvJOdmIwvrrAhX3rYhfQQCaf9VJcv7M= +github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= +github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= @@ -146,8 +146,8 @@ github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY= -github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= +github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= @@ -165,7 +165,6 @@ github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXP github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.1.2 h1:DVjP2PbBOzHyzA+dn3WhHIq4NdVu3Q+pvivFICf/7fo= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -215,27 +214,27 @@ github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXi github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b h1:RMpPgZTSApbPf7xaVel+QkoGPRLFLrwFO89uDUHEGf0= -github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= +github.com/google/pprof v0.0.0-20231229205709-960ae82b1e42 h1:dHLYa5D8/Ta0aLR2XcPsrkpAgGeFs6thhMcQK0oQ0n8= +github.com/google/pprof v0.0.0-20231229205709-960ae82b1e42/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= -github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU= +github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c h1:7lF+Vz0LqiRidnzC1Oq86fpX1q/iEv2KJdrCtttYjT4= -github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= +github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 h1:YBftPWNWd4WwGqtY2yeZL2ef8rHAxPBD8KFhJpmcqms= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0 h1:Wqo399gCIufwto+VfwCSvsnfGpF/w5E9CNxSwbpD6No= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0/go.mod h1:qmOFXW2epJhM0qSnUUYpldc7gVz2KMQwJ/QYCDIa7XU= github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -261,16 +260,14 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.16.1-0.20240109085802-d13d712f1c4e h1:GFMm0GO3tTLmjJ6uNZnTq0HpYV/kygZhe1sKYHQ/aVc= -github.com/ipfs/boxo v0.16.1-0.20240109085802-d13d712f1c4e/go.mod h1:gCYL6EViui01M8Dr0cY8nOpRAbofxZDWASxbLSrG9Ac= +github.com/ipfs/boxo v0.16.1-0.20240110145317-d8e9d95f7d05 h1:xCn1uaroCjFVmZe0Q//QM8t2c8GxXO0bCG0TBu9p75A= +github.com/ipfs/boxo v0.16.1-0.20240110145317-d8e9d95f7d05/go.mod h1:pIZgTWdm3k3pLF9Uq6MB8JEcW07UDwNJjlXW1HELW80= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= -github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= github.com/ipfs/go-block-format v0.0.3/go.mod h1:4LmD4ZUw0mhO+JSKdpWwrzATiEfM7WWgQ8H5l6P8MVk= github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs= github.com/ipfs/go-block-format v0.2.0/go.mod h1:+jpL11nFx5A/SPpsoBn6Bzkra/zaArfSmsknbPMYgzM= github.com/ipfs/go-blockservice v0.5.0 h1:B2mwhhhVQl2ntW2EIpaWPwSCxSuqr5fFA93Ms4bYLEY= -github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.3/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.4/go.mod h1:4LLaPOQwmk5z9LBgQnpkivrx8BJjUyGwTXCd5Xfj6+M= github.com/ipfs/go-cid v0.0.5/go.mod h1:plgt+Y5MnOey4vO4UlUazGqdbEXuFYitED67FexhXog= @@ -317,9 +314,8 @@ github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyB github.com/ipfs/go-ipfs-util v0.0.2/go.mod h1:CbPtkWJzjLdEcezDns2XYaehFVNXG9zrdrtMecczcsQ= github.com/ipfs/go-ipfs-util v0.0.3 h1:2RFdGez6bu2ZlZdI+rWfIdbQb1KudQp3VGwPtdNCmE0= github.com/ipfs/go-ipfs-util v0.0.3/go.mod h1:LHzG1a0Ig4G+iZ26UUOMjHd+lfM84LZCrn17xAKWBvs= -github.com/ipfs/go-ipld-cbor v0.0.6 h1:pYuWHyvSpIsOOLw4Jy7NbBkCyzLDcl64Bf/LZW7eBQ0= -github.com/ipfs/go-ipld-cbor v0.0.6/go.mod h1:ssdxxaLJPXH7OjF5V4NSjBbcfh+evoR4ukuru0oPXMA= -github.com/ipfs/go-ipld-format v0.0.1/go.mod h1:kyJtbkDALmFHv3QR6et67i35QzO3S0dCDnkOJhcZkms= +github.com/ipfs/go-ipld-cbor v0.1.0 h1:dx0nS0kILVivGhfWuB6dUpMa/LAwElHPw1yOGYopoYs= +github.com/ipfs/go-ipld-cbor v0.1.0/go.mod h1:U2aYlmVrJr2wsUBU67K4KgepApSZddGRDWBYR0H4sCk= github.com/ipfs/go-ipld-format v0.6.0 h1:VEJlA2kQ3LqFSIm5Vu6eIlSxD/Ze90xtc4Meten1F5U= github.com/ipfs/go-ipld-format v0.6.0/go.mod h1:g4QVMTn3marU3qXchwjpKPKgJv+zF+OlaKMyhJ4LHPg= github.com/ipfs/go-ipld-git v0.1.1 h1:TWGnZjS0htmEmlMFEkA3ogrNCqWjIxwr16x1OsdhG+Y= @@ -342,11 +338,11 @@ github.com/ipfs/go-metrics-interface v0.0.1/go.mod h1:6s6euYU4zowdslK0GKHmqaIZ3j github.com/ipfs/go-peertaskqueue v0.8.1 h1:YhxAs1+wxb5jk7RvS0LHdyiILpNmRIRnZVztekOF0pg= github.com/ipfs/go-peertaskqueue v0.8.1/go.mod h1:Oxxd3eaK279FxeydSPPVGHzbwVeHjatZ2GA8XD+KbPU= github.com/ipfs/go-unixfs v0.4.5 h1:wj8JhxvV1G6CD7swACwSKYa+NgtdWC1RUit+gFnymDU= -github.com/ipfs/go-unixfsnode v1.8.1 h1:nEWQl2XL+Zoyh6u0OMzNI8mUeCKLyRgg65WDbTm/oNU= -github.com/ipfs/go-unixfsnode v1.8.1/go.mod h1:HxRu9HYHOjK6HUqFBAi++7DVoWAHn0o4v/nZ/VA+0g8= +github.com/ipfs/go-unixfsnode v1.9.0 h1:ubEhQhr22sPAKO2DNsyVBW7YB/zA8Zkif25aBvz8rc8= +github.com/ipfs/go-unixfsnode v1.9.0/go.mod h1:HxRu9HYHOjK6HUqFBAi++7DVoWAHn0o4v/nZ/VA+0g8= github.com/ipfs/go-verifcid v0.0.2 h1:XPnUv0XmdH+ZIhLGKg6U2vaPaRDXb9urMyNVCE7uvTs= -github.com/ipld/go-car/v2 v2.10.2-0.20230622090957-499d0c909d33 h1:0OZwzSYWIuiKEOXd/2vm5cMcEmmGLFn+1h6lHELCm3s= -github.com/ipld/go-car/v2 v2.10.2-0.20230622090957-499d0c909d33/go.mod h1:sQEkXVM3csejlb1kCCb+vQ/pWBKX9QtvsrysMQjOgOg= +github.com/ipld/go-car/v2 v2.13.1 h1:KnlrKvEPEzr5IZHKTXLAEub+tPrzeAFQVRlSQvuxBO4= +github.com/ipld/go-car/v2 v2.13.1/go.mod h1:QkdjjFNGit2GIkpQ953KBwowuoukoM75nP/JI1iDJdo= github.com/ipld/go-codec-dagpb v1.6.0 h1:9nYazfyu9B1p3NAgfVdpRco3Fs2nFC72DqVsMj6rOcc= github.com/ipld/go-codec-dagpb v1.6.0/go.mod h1:ANzFhfP2uMJxRBr8CE+WQWs5UsNa0pYtmKZ+agnUw9s= github.com/ipld/go-ipld-prime v0.11.0/go.mod h1:+WIAkokurHmZ/KwzDOMUuoeJgaRQktHtEaLglS3ZeV8= @@ -371,7 +367,6 @@ github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlT github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= -github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/kami-zh/go-capturer v0.0.0-20171211120116-e492ea43421d/go.mod h1:P2viExyCEfeWGU259JnaQ34Inuec4R38JCyBx2edgD0= @@ -380,8 +375,8 @@ github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQL 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.17.2 h1:RlWWUY/Dr4fL8qk9YG7DTZ7PDgME2V4csBXA8L/ixi4= -github.com/klauspost/compress v1.17.2/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/compress v1.17.4 h1:Ej5ixsIri7BrIjBkRZLTo6ghwrEtHFk7ijlczPW4fZ4= +github.com/klauspost/compress v1.17.4/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/48xc= @@ -504,8 +499,8 @@ github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a github.com/multiformats/go-multiaddr v0.1.0/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo= github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4= -github.com/multiformats/go-multiaddr v0.12.0 h1:1QlibTFkoXJuDjjYsMHhE73TnzJQl8FSWatk/0gxGzE= -github.com/multiformats/go-multiaddr v0.12.0/go.mod h1:WmZXgObOQOYp9r3cslLlppkrz1FYSHmE834dfz/lWu8= +github.com/multiformats/go-multiaddr v0.12.1 h1:vm+BA/WZA8QZDp1pF1FWhi5CT3g1tbi5GJmqpb6wnlk= +github.com/multiformats/go-multiaddr v0.12.1/go.mod h1:7mPkiBMmLeFipt+nNSq9pHZUeJSt8lHBgH6yhj0YQzE= github.com/multiformats/go-multiaddr-dns v0.3.0/go.mod h1:mNzQ4eTGDg0ll1N9jKPOUogZPoJ30W8a7zk66FQPpdQ= github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A= github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk= @@ -547,13 +542,13 @@ github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9k github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4= -github.com/onsi/ginkgo/v2 v2.13.0/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o= +github.com/onsi/ginkgo/v2 v2.13.2 h1:Bi2gGVkfn6gQcjNjZJVO8Gf0FHzMPf2phUei9tejVMs= +github.com/onsi/ginkgo/v2 v2.13.2/go.mod h1:XStQ8QcGwLyF4HdfcZB8SFOS/MWCgDuXMSBe6zrvLgM= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= -github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= +github.com/onsi/gomega v1.29.0 h1:KIA/t2t5UBzoirT4H9tsML45GEbo3ouUnBHsCfD2tVg= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.1.0 h1:HHUyrt9mwHUjtasSbXSMvs4cyFxh+Bll4AjJ9odEGpg= github.com/opencontainers/runtime-spec v1.1.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= @@ -613,13 +608,12 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/polydawn/refmt v0.0.0-20190221155625-df39d6c2d992/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= github.com/polydawn/refmt v0.0.0-20201211092308-30ac6d18308e/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= github.com/polydawn/refmt v0.89.0 h1:ADJTApkvkeBZsN0tBTx8QjpD9JkmxbKp0cxfr9qszm4= github.com/polydawn/refmt v0.89.0/go.mod h1:/zvteZs/GwLtCgZ4BL6CBsk9IKIlexP43ObX9AxTqTw= github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v1.17.0 h1:rl2sfwZMtSthVU752MqfjQozy7blglC+1SOtjMAMh+Q= -github.com/prometheus/client_golang v1.17.0/go.mod h1:VeL+gMmOAxkS2IqfCq0ZmHSL+LjWfWDUmp1mBz9JgUY= +github.com/prometheus/client_golang v1.18.0 h1:HzFfmkOzH5Q8L8G+kSJKUx5dtG87sewO+FoDDqP5Tbk= +github.com/prometheus/client_golang v1.18.0/go.mod h1:T+GXkCk5wSJyOqMIzVgvvjFDlkOQntgjkJWKrN5txjA= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= @@ -632,10 +626,10 @@ github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= -github.com/quic-go/qtls-go1-20 v0.3.4 h1:MfFAPULvst4yoMgY9QmtpYmfij/em7O8UUi+bNVm7Cg= -github.com/quic-go/qtls-go1-20 v0.3.4/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= -github.com/quic-go/quic-go v0.39.4 h1:PelfiuG7wXEffUT2yceiqz5V6Pc0TA5ruOd1LcmFc1s= -github.com/quic-go/quic-go v0.39.4/go.mod h1:T09QsDQWjLiQ74ZmacDfqZmhY/NLnw5BC40MANNNZ1Q= +github.com/quic-go/qtls-go1-20 v0.4.1 h1:D33340mCNDAIKBqXuAvexTNMUByrYmFYVfKfDN5nfFs= +github.com/quic-go/qtls-go1-20 v0.4.1/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= +github.com/quic-go/quic-go v0.40.1 h1:X3AGzUNFs0jVuO3esAGnTfvdgvL4fq655WaOi1snv1Q= +github.com/quic-go/quic-go v0.40.1/go.mod h1:PeN7kuVJ4xZbxSv/4OX6S1USOX8MJvydwpTx31vx60c= github.com/quic-go/webtransport-go v0.6.0 h1:CvNsKqc4W2HljHJnoT+rMmbRJybShZ0YPFDD3NxaZLY= github.com/quic-go/webtransport-go v0.6.0/go.mod h1:9KjU4AEBqEQidGHNDkZrb8CAa1abRaosM2yGOyiikEc= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= @@ -678,7 +672,6 @@ github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/assertions v1.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N3yZFZkDFs= github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo= -github.com/smartystreets/goconvey v0.0.0-20190222223459-a17d461953aa/go.mod h1:2RVY1rIf+2J2o/IM9+vPq9RzmHDSseB7FoXiSNIUsoU= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/smartystreets/goconvey v1.7.2 h1:9RBaZCeXEQ3UselpuwUQHltGVXvdwm6cv1hgR6gDIPg= github.com/smartystreets/goconvey v1.7.2/go.mod h1:Vw0tHAZW6lzCRk3xgdin6fKYcG+G3Pg9vgXWeJpQFMM= @@ -732,7 +725,6 @@ github.com/wangjia184/sortedset v0.0.0-20160527075905-f5d03557ba30/go.mod h1:Yko github.com/warpfork/go-testmark v0.3.0/go.mod h1:jhEf8FVxd+F17juRubpmut64NEG6I2rgkUhlcqqXwE0= github.com/warpfork/go-testmark v0.9.0/go.mod h1:jhEf8FVxd+F17juRubpmut64NEG6I2rgkUhlcqqXwE0= github.com/warpfork/go-testmark v0.12.1 h1:rMgCpJfwy1sJ50x0M0NgyphxYYPMOODIJHhsXyEHU0s= -github.com/warpfork/go-wish v0.0.0-20180510122957-5ad1f5abf436/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= github.com/warpfork/go-wish v0.0.0-20200122115046-b9ea61034e4a/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0 h1:GDDkbFiaK8jsSDJfjId/PEGEShv6ugrt4kYsC5UIDaQ= github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= @@ -740,9 +732,8 @@ github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc h1:BCPnHtcboa github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc/go.mod h1:r45hJU7yEoA81k6MWNhpMj/kms0n14dkzkxYHoB96UM= github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11 h1:5HZfQkwe0mIfyDmc1Em5GqlNRzcdtlv4HTNmdpt7XH0= github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11/go.mod h1:Wlo/SzPmxVp6vXpGt/zaXhHH0fn4IxgqZc82aKg6bpQ= -github.com/whyrusleeping/cbor-gen v0.0.0-20200123233031-1cdf64d27158/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI= -github.com/whyrusleeping/cbor-gen v0.0.0-20230126041949-52956bd4c9aa h1:EyA027ZAkuaCLoxVX4r1TZMPy1d31fM6hbfQ4OU4I5o= -github.com/whyrusleeping/cbor-gen v0.0.0-20230126041949-52956bd4c9aa/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= +github.com/whyrusleeping/cbor-gen v0.0.0-20240109153615-66e95c3e8a87 h1:S4wCk+ZL4WGGaI+GsmqCRyt68ISbnZWsK9dD9jYL0fA= +github.com/whyrusleeping/cbor-gen v0.0.0-20240109153615-66e95c3e8a87/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f h1:jQa4QT2UP9WYv2nzyawpKMOCl+Z/jW7djv2/J50lj9E= github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f/go.mod h1:p9UJB6dDgdPgMJZs7UjUOdulKyRr9fqkS+6JKAInPy8= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 h1:EKhdznlJHPMoKr0XTrX+IlJs1LH3lyx2nfr1dOlZ79k= @@ -794,8 +785,8 @@ go.uber.org/fx v1.20.1 h1:zVwVQGS8zYvhh9Xxcu4w1M6ESyeMzebzj2NbSayZ4Mk= go.uber.org/fx v1.20.1/go.mod h1:iSYNbHf2y55acNCwCXKx7LbWb5WG1Bnue5RDXz1OREg= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= -go.uber.org/mock v0.3.0 h1:3mUxI1No2/60yUYax92Pt8eNOEecx2D3lcXZh2NEZJo= -go.uber.org/mock v0.3.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= +go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= +go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= @@ -831,8 +822,8 @@ golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= -golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY= -golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= +golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc= +golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -841,8 +832,8 @@ golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20231214170342-aacd6d4b4611 h1:qCEDpW1G+vcj3Y7Fy52pEM1AWm3abj8WimGYejI3SC4= -golang.org/x/exp v0.0.0-20231214170342-aacd6d4b4611/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI= +golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc h1:ao2WRsKSzW6KuUY9IWPwWahcHCgR0s52IfwutMfEbdM= +golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -897,7 +888,6 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210423184538-5f58ad60dda6/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= @@ -906,8 +896,8 @@ golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= -golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= +golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= +golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -926,8 +916,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= -golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= +golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/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= @@ -982,8 +972,8 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= -golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= +golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -1048,14 +1038,14 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.16.0 h1:GO788SKMRunPIBCXiQyo2AaexLstOrVhuAL5YwsckQM= -golang.org/x/tools v0.16.0/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= +golang.org/x/tools v0.16.1 h1:TLyB3WofjdOEepBHAU20JdNC1Zbg87elYofWYAY5oZA= +golang.org/x/tools v0.16.1/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= -golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU= +golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= gonum.org/v1/gonum v0.14.0 h1:2NiG67LD1tEH0D7kM+ps2V+fXmsAnpUeec7n8tcr4S0= gonum.org/v1/gonum v0.14.0/go.mod h1:AoWeoz0becf9QMWtE8iWXNXc27fK4fNeHNf/oMejGfU= google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= @@ -1094,11 +1084,11 @@ google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvx google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d h1:VBu5YqKPv6XiJ199exd8Br+Aetz+o08F+PLMnwJQHAY= -google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d h1:DoPTO70H+bcDXcd39vOqb2viZxgqeBeSGtZ55yZU4/Q= -google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d/go.mod h1:KjSP20unUpOx5kyQUFa7k4OJg0qeJ7DEZflGDu2p6Bk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d h1:uvYuEyMHKNt+lT4K3bN6fGswmK8qSvcreM3BwjDh+y4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M= +google.golang.org/genproto v0.0.0-20240102182953-50ed04b92917 h1:nz5NESFLZbJGPFxDT/HCn+V1mZ8JGNoY4nUpmW/Y2eg= +google.golang.org/genproto/googleapis/api v0.0.0-20240108191215-35c7eff3a6b1 h1:OPXtXn7fNMaXwO3JvOmF1QyTc00jsSFFz1vXXBOdCDo= +google.golang.org/genproto/googleapis/api v0.0.0-20240108191215-35c7eff3a6b1/go.mod h1:B5xPO//w8qmBDjGReYLpR6UJPnkldGkCSMoH/2vxJeg= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240108191215-35c7eff3a6b1 h1:gphdwh0npgs8elJ4T6J+DQJHPVF7RsuJHCfwztUb4J4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240108191215-35c7eff3a6b1/go.mod h1:daQN87bsDqDoe316QbbvX60nMoJQa4r6Ds0ZuoAe5yA= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= @@ -1111,8 +1101,8 @@ google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8 google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk= -google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98= +google.golang.org/grpc v1.60.1 h1:26+wFr+cNqSGFcOXcabYC0lUVJVRa2Sb2ortSK7VrEU= +google.golang.org/grpc v1.60.1/go.mod h1:OlCHIeLYqSSsLi6i49B5QGdzaMZK9+M7LXN2FKz4eGM= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -1124,8 +1114,8 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= -google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= +google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/go.mod b/go.mod index 134b16bd1..1c18a54b9 100644 --- a/go.mod +++ b/go.mod @@ -13,11 +13,11 @@ require ( github.com/elgris/jsondiff v0.0.0-20160530203242-765b5c24c302 github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5 github.com/fsnotify/fsnotify v1.6.0 - github.com/google/uuid v1.4.0 + github.com/google/uuid v1.5.0 github.com/hashicorp/go-multierror v1.1.1 github.com/ipfs-shipyard/nopfs v0.0.12-0.20231027223058-cde3b5ba964c github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c - github.com/ipfs/boxo v0.16.1-0.20240109085802-d13d712f1c4e + github.com/ipfs/boxo v0.16.1-0.20240110145317-d8e9d95f7d05 github.com/ipfs/go-block-format v0.2.0 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 @@ -29,7 +29,7 @@ require ( github.com/ipfs/go-ds-measure v0.2.0 github.com/ipfs/go-fs-lock v0.0.7 github.com/ipfs/go-ipfs-cmds v0.10.0 - github.com/ipfs/go-ipld-cbor v0.0.6 + github.com/ipfs/go-ipld-cbor v0.1.0 github.com/ipfs/go-ipld-format v0.6.0 github.com/ipfs/go-ipld-git v0.1.1 github.com/ipfs/go-ipld-legacy v0.2.1 @@ -37,9 +37,9 @@ require ( github.com/ipfs/go-log/v2 v2.5.1 github.com/ipfs/go-metrics-interface v0.0.1 github.com/ipfs/go-metrics-prometheus v0.0.2 - github.com/ipfs/go-unixfsnode v1.8.1 + github.com/ipfs/go-unixfsnode v1.9.0 github.com/ipld/go-car v0.5.0 - github.com/ipld/go-car/v2 v2.10.2-0.20230622090957-499d0c909d33 + github.com/ipld/go-car/v2 v2.13.1 github.com/ipld/go-codec-dagpb v1.6.0 github.com/ipld/go-ipld-prime v0.21.0 github.com/jbenet/go-random v0.0.0-20190219211222-123a90aedc0c @@ -58,7 +58,7 @@ require ( github.com/libp2p/go-libp2p-testing v0.12.0 github.com/libp2p/go-socket-activation v0.1.0 github.com/mitchellh/go-homedir v1.1.0 - github.com/multiformats/go-multiaddr v0.12.0 + github.com/multiformats/go-multiaddr v0.12.1 github.com/multiformats/go-multiaddr-dns v0.3.1 github.com/multiformats/go-multibase v0.2.0 github.com/multiformats/go-multicodec v0.9.0 @@ -66,7 +66,7 @@ require ( github.com/opentracing/opentracing-go v1.2.0 github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 github.com/pkg/errors v0.9.1 - github.com/prometheus/client_golang v1.17.0 + github.com/prometheus/client_golang v1.18.0 github.com/stretchr/testify v1.8.4 github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 github.com/tidwall/gjson v1.14.4 @@ -83,24 +83,24 @@ require ( go.uber.org/fx v1.20.1 go.uber.org/multierr v1.11.0 go.uber.org/zap v1.26.0 - golang.org/x/crypto v0.16.0 - golang.org/x/exp v0.0.0-20231214170342-aacd6d4b4611 + golang.org/x/crypto v0.18.0 + golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc golang.org/x/mod v0.14.0 - golang.org/x/sync v0.5.0 - golang.org/x/sys v0.15.0 - google.golang.org/protobuf v1.31.0 + golang.org/x/sync v0.6.0 + golang.org/x/sys v0.16.0 + google.golang.org/protobuf v1.32.0 ) require ( github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 // indirect github.com/Jorropo/jsync v1.0.1 // indirect - github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect + github.com/alecthomas/units v0.0.0-20231202071711-9a357b53e9c9 // indirect github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/containerd/cgroups v1.1.0 // indirect - github.com/crackcomm/go-gitignore v0.0.0-20170627025303-887ab5e44cc3 // indirect + github.com/crackcomm/go-gitignore v0.0.0-20231225121904-e25f5bc08668 // indirect github.com/cskr/pubsub v1.0.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect @@ -110,12 +110,12 @@ require ( github.com/docker/go-units v0.5.0 // indirect github.com/elastic/gosigar v0.14.2 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect - github.com/flynn/noise v1.0.0 // indirect + github.com/flynn/noise v1.0.1 // indirect github.com/francoispqt/gojay v1.2.13 // indirect - github.com/gabriel-vasile/mimetype v1.4.1 // indirect + github.com/gabriel-vasile/mimetype v1.4.3 // indirect github.com/go-kit/log v0.2.1 // indirect github.com/go-logfmt/logfmt v0.5.1 // indirect - github.com/go-logr/logr v1.3.0 // indirect + github.com/go-logr/logr v1.4.1 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/godbus/dbus/v5 v5.1.0 // indirect @@ -124,10 +124,10 @@ require ( github.com/golang/protobuf v1.5.3 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/gopacket v1.1.19 // indirect - github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b // indirect - github.com/gorilla/mux v1.8.0 // indirect + github.com/google/pprof v0.0.0-20231229205709-960ae82b1e42 // indirect + github.com/gorilla/mux v1.8.1 // indirect github.com/gorilla/websocket v1.5.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/golang-lru v1.0.2 // indirect github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect @@ -146,7 +146,7 @@ require ( github.com/ipfs/go-peertaskqueue v0.8.1 // indirect github.com/ipfs/go-verifcid v0.0.2 // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect - github.com/klauspost/compress v1.17.2 // indirect + github.com/klauspost/compress v1.17.4 // indirect github.com/klauspost/cpuid/v2 v2.2.6 // indirect github.com/koron/go-ssdp v0.0.4 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect @@ -177,7 +177,7 @@ require ( github.com/multiformats/go-multiaddr-fmt v0.1.0 // indirect github.com/multiformats/go-multistream v0.5.0 // indirect github.com/multiformats/go-varint v0.0.7 // indirect - github.com/onsi/ginkgo/v2 v2.13.0 // indirect + github.com/onsi/ginkgo/v2 v2.13.2 // indirect github.com/opencontainers/runtime-spec v1.1.0 // indirect github.com/openzipkin/zipkin-go v0.4.2 // indirect github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 // indirect @@ -204,8 +204,8 @@ require ( github.com/prometheus/procfs v0.12.0 // indirect github.com/prometheus/statsd_exporter v0.22.7 // indirect github.com/quic-go/qpack v0.4.0 // indirect - github.com/quic-go/qtls-go1-20 v0.3.4 // indirect - github.com/quic-go/quic-go v0.39.4 // indirect + github.com/quic-go/qtls-go1-20 v0.4.1 // indirect + github.com/quic-go/quic-go v0.40.1 // indirect github.com/quic-go/webtransport-go v0.6.0 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/rs/cors v1.7.0 // indirect @@ -217,7 +217,7 @@ require ( github.com/ucarion/urlpath v0.0.0-20200424170820-7ccc79b76bbb // indirect github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc // indirect github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11 // indirect - github.com/whyrusleeping/cbor-gen v0.0.0-20230126041949-52956bd4c9aa // indirect + github.com/whyrusleeping/cbor-gen v0.0.0-20240109153615-66e95c3e8a87 // indirect github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f // indirect github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect go.opentelemetry.io/contrib/propagators/aws v1.21.1 // indirect @@ -232,19 +232,19 @@ require ( go.opentelemetry.io/otel/metric v1.21.0 // indirect go.opentelemetry.io/proto/otlp v1.0.0 // indirect go.uber.org/atomic v1.11.0 // indirect - go.uber.org/mock v0.3.0 // indirect + go.uber.org/mock v0.4.0 // indirect go4.org v0.0.0-20230225012048-214862532bf5 // indirect - golang.org/x/net v0.19.0 // indirect - golang.org/x/oauth2 v0.12.0 // indirect - golang.org/x/term v0.15.0 // indirect + golang.org/x/net v0.20.0 // indirect + golang.org/x/oauth2 v0.16.0 // indirect + golang.org/x/term v0.16.0 // indirect golang.org/x/text v0.14.0 // indirect - golang.org/x/tools v0.16.0 // indirect - golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect + golang.org/x/tools v0.16.1 // indirect + golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect gonum.org/v1/gonum v0.14.0 // indirect - google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect - google.golang.org/grpc v1.59.0 // indirect + google.golang.org/appengine v1.6.8 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240108191215-35c7eff3a6b1 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240108191215-35c7eff3a6b1 // indirect + google.golang.org/grpc v1.60.1 // indirect gopkg.in/square/go-jose.v2 v2.5.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 4afe6d356..dfa3693cb 100644 --- a/go.sum +++ b/go.sum @@ -57,8 +57,9 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= -github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 h1:s6gZFSlWYmbqAuRjVTiNNhvNRfY2Wxp9nhfyel4rklc= github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= +github.com/alecthomas/units v0.0.0-20231202071711-9a357b53e9c9 h1:ez/4by2iGztzR4L0zgAOR8lTQK9VlyBVVd7G4omaOQs= +github.com/alecthomas/units v0.0.0-20231202071711-9a357b53e9c9/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5 h1:iW0a5ljuFxkLGPNem5Ui+KBjFJzKg4Fv2fnxe4dvzpM= github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5/go.mod h1:Y2QMoi1vgtOIfc+6DhrMOGkLoGzqSV2rKp4Sm+opsyA= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= @@ -118,8 +119,8 @@ github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSV 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/crackcomm/go-gitignore v0.0.0-20231225121904-e25f5bc08668 h1:ZFUue+PNxmHlu7pYv+IYMtqlaO/0VwaGEqKepZf9JpA= +github.com/crackcomm/go-gitignore v0.0.0-20231225121904-e25f5bc08668/go.mod h1:p1d6YEZWvFzEh4KLyvBcVSnrfNDDvK2zfK/4x2v/4pE= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cskr/pubsub v1.0.2 h1:vlOzMhl6PFn60gRlTQQsIfVwaPB/B/8MziK8FhEPt/0= github.com/cskr/pubsub v1.0.2/go.mod h1:/8MzYXk/NJAz782G8RPkFzXTZVu63VotefPnR9TIRis= @@ -161,8 +162,8 @@ github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= -github.com/flynn/noise v1.0.0 h1:DlTHqmzmvcEiKj+4RYo/imoswx/4r6iBlCMfVtrMXpQ= -github.com/flynn/noise v1.0.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag= +github.com/flynn/noise v1.0.1 h1:vPp/jdQLXC6ppsXSj/pM3W1BIJ5FEHE2TulSJBpb43Y= +github.com/flynn/noise v1.0.1/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag= github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk= github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= @@ -172,8 +173,8 @@ github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMo github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= -github.com/gabriel-vasile/mimetype v1.4.1 h1:TRWk7se+TOjCYgRth7+1/OYLNiRNIotknkFtf/dnN7Q= -github.com/gabriel-vasile/mimetype v1.4.1/go.mod h1:05Vi0w3Y9c/lNvJOdmIwvrrAhX3rYhfQQCaf9VJcv7M= +github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= +github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= @@ -193,8 +194,8 @@ github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA= github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY= -github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= +github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= @@ -213,7 +214,6 @@ github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXP github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.1.2 h1:DVjP2PbBOzHyzA+dn3WhHIq4NdVu3Q+pvivFICf/7fo= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -278,28 +278,28 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b h1:RMpPgZTSApbPf7xaVel+QkoGPRLFLrwFO89uDUHEGf0= -github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= +github.com/google/pprof v0.0.0-20231229205709-960ae82b1e42 h1:dHLYa5D8/Ta0aLR2XcPsrkpAgGeFs6thhMcQK0oQ0n8= +github.com/google/pprof v0.0.0-20231229205709-960ae82b1e42/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= -github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU= +github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c h1:7lF+Vz0LqiRidnzC1Oq86fpX1q/iEv2KJdrCtttYjT4= -github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= -github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= +github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 h1:YBftPWNWd4WwGqtY2yeZL2ef8rHAxPBD8KFhJpmcqms= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0 h1:Wqo399gCIufwto+VfwCSvsnfGpF/w5E9CNxSwbpD6No= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0/go.mod h1:qmOFXW2epJhM0qSnUUYpldc7gVz2KMQwJ/QYCDIa7XU= github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -325,18 +325,16 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.16.1-0.20240109085802-d13d712f1c4e h1:GFMm0GO3tTLmjJ6uNZnTq0HpYV/kygZhe1sKYHQ/aVc= -github.com/ipfs/boxo v0.16.1-0.20240109085802-d13d712f1c4e/go.mod h1:gCYL6EViui01M8Dr0cY8nOpRAbofxZDWASxbLSrG9Ac= +github.com/ipfs/boxo v0.16.1-0.20240110145317-d8e9d95f7d05 h1:xCn1uaroCjFVmZe0Q//QM8t2c8GxXO0bCG0TBu9p75A= +github.com/ipfs/boxo v0.16.1-0.20240110145317-d8e9d95f7d05/go.mod h1:pIZgTWdm3k3pLF9Uq6MB8JEcW07UDwNJjlXW1HELW80= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= -github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= github.com/ipfs/go-block-format v0.0.3/go.mod h1:4LmD4ZUw0mhO+JSKdpWwrzATiEfM7WWgQ8H5l6P8MVk= github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs= github.com/ipfs/go-block-format v0.2.0/go.mod h1:+jpL11nFx5A/SPpsoBn6Bzkra/zaArfSmsknbPMYgzM= github.com/ipfs/go-blockservice v0.5.0 h1:B2mwhhhVQl2ntW2EIpaWPwSCxSuqr5fFA93Ms4bYLEY= github.com/ipfs/go-blockservice v0.5.0/go.mod h1:W6brZ5k20AehbmERplmERn8o2Ni3ZZubvAxaIUeaT6w= -github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.3/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.4/go.mod h1:4LLaPOQwmk5z9LBgQnpkivrx8BJjUyGwTXCd5Xfj6+M= github.com/ipfs/go-cid v0.0.5/go.mod h1:plgt+Y5MnOey4vO4UlUazGqdbEXuFYitED67FexhXog= @@ -388,9 +386,8 @@ github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyB github.com/ipfs/go-ipfs-util v0.0.2/go.mod h1:CbPtkWJzjLdEcezDns2XYaehFVNXG9zrdrtMecczcsQ= github.com/ipfs/go-ipfs-util v0.0.3 h1:2RFdGez6bu2ZlZdI+rWfIdbQb1KudQp3VGwPtdNCmE0= github.com/ipfs/go-ipfs-util v0.0.3/go.mod h1:LHzG1a0Ig4G+iZ26UUOMjHd+lfM84LZCrn17xAKWBvs= -github.com/ipfs/go-ipld-cbor v0.0.6 h1:pYuWHyvSpIsOOLw4Jy7NbBkCyzLDcl64Bf/LZW7eBQ0= -github.com/ipfs/go-ipld-cbor v0.0.6/go.mod h1:ssdxxaLJPXH7OjF5V4NSjBbcfh+evoR4ukuru0oPXMA= -github.com/ipfs/go-ipld-format v0.0.1/go.mod h1:kyJtbkDALmFHv3QR6et67i35QzO3S0dCDnkOJhcZkms= +github.com/ipfs/go-ipld-cbor v0.1.0 h1:dx0nS0kILVivGhfWuB6dUpMa/LAwElHPw1yOGYopoYs= +github.com/ipfs/go-ipld-cbor v0.1.0/go.mod h1:U2aYlmVrJr2wsUBU67K4KgepApSZddGRDWBYR0H4sCk= github.com/ipfs/go-ipld-format v0.6.0 h1:VEJlA2kQ3LqFSIm5Vu6eIlSxD/Ze90xtc4Meten1F5U= github.com/ipfs/go-ipld-format v0.6.0/go.mod h1:g4QVMTn3marU3qXchwjpKPKgJv+zF+OlaKMyhJ4LHPg= github.com/ipfs/go-ipld-git v0.1.1 h1:TWGnZjS0htmEmlMFEkA3ogrNCqWjIxwr16x1OsdhG+Y= @@ -416,14 +413,14 @@ github.com/ipfs/go-metrics-prometheus v0.0.2/go.mod h1:ELLU99AQQNi+zX6GCGm2lAgnz github.com/ipfs/go-peertaskqueue v0.8.1 h1:YhxAs1+wxb5jk7RvS0LHdyiILpNmRIRnZVztekOF0pg= github.com/ipfs/go-peertaskqueue v0.8.1/go.mod h1:Oxxd3eaK279FxeydSPPVGHzbwVeHjatZ2GA8XD+KbPU= github.com/ipfs/go-unixfs v0.4.5 h1:wj8JhxvV1G6CD7swACwSKYa+NgtdWC1RUit+gFnymDU= -github.com/ipfs/go-unixfsnode v1.8.1 h1:nEWQl2XL+Zoyh6u0OMzNI8mUeCKLyRgg65WDbTm/oNU= -github.com/ipfs/go-unixfsnode v1.8.1/go.mod h1:HxRu9HYHOjK6HUqFBAi++7DVoWAHn0o4v/nZ/VA+0g8= +github.com/ipfs/go-unixfsnode v1.9.0 h1:ubEhQhr22sPAKO2DNsyVBW7YB/zA8Zkif25aBvz8rc8= +github.com/ipfs/go-unixfsnode v1.9.0/go.mod h1:HxRu9HYHOjK6HUqFBAi++7DVoWAHn0o4v/nZ/VA+0g8= github.com/ipfs/go-verifcid v0.0.2 h1:XPnUv0XmdH+ZIhLGKg6U2vaPaRDXb9urMyNVCE7uvTs= github.com/ipfs/go-verifcid v0.0.2/go.mod h1:40cD9x1y4OWnFXbLNJYRe7MpNvWlMn3LZAG5Wb4xnPU= github.com/ipld/go-car v0.5.0 h1:kcCEa3CvYMs0iE5BzD5sV7O2EwMiCIp3uF8tA6APQT8= github.com/ipld/go-car v0.5.0/go.mod h1:ppiN5GWpjOZU9PgpAZ9HbZd9ZgSpwPMr48fGRJOWmvE= -github.com/ipld/go-car/v2 v2.10.2-0.20230622090957-499d0c909d33 h1:0OZwzSYWIuiKEOXd/2vm5cMcEmmGLFn+1h6lHELCm3s= -github.com/ipld/go-car/v2 v2.10.2-0.20230622090957-499d0c909d33/go.mod h1:sQEkXVM3csejlb1kCCb+vQ/pWBKX9QtvsrysMQjOgOg= +github.com/ipld/go-car/v2 v2.13.1 h1:KnlrKvEPEzr5IZHKTXLAEub+tPrzeAFQVRlSQvuxBO4= +github.com/ipld/go-car/v2 v2.13.1/go.mod h1:QkdjjFNGit2GIkpQ953KBwowuoukoM75nP/JI1iDJdo= github.com/ipld/go-codec-dagpb v1.6.0 h1:9nYazfyu9B1p3NAgfVdpRco3Fs2nFC72DqVsMj6rOcc= github.com/ipld/go-codec-dagpb v1.6.0/go.mod h1:ANzFhfP2uMJxRBr8CE+WQWs5UsNa0pYtmKZ+agnUw9s= github.com/ipld/go-ipld-prime v0.11.0/go.mod h1:+WIAkokurHmZ/KwzDOMUuoeJgaRQktHtEaLglS3ZeV8= @@ -454,7 +451,6 @@ github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/ github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= -github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= @@ -466,8 +462,8 @@ github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQL 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.17.2 h1:RlWWUY/Dr4fL8qk9YG7DTZ7PDgME2V4csBXA8L/ixi4= -github.com/klauspost/compress v1.17.2/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/compress v1.17.4 h1:Ej5ixsIri7BrIjBkRZLTo6ghwrEtHFk7ijlczPW4fZ4= +github.com/klauspost/compress v1.17.4/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/48xc= @@ -612,8 +608,8 @@ github.com/multiformats/go-multiaddr v0.1.0/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lg github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo= github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4= github.com/multiformats/go-multiaddr v0.4.0/go.mod h1:YcpyLH8ZPudLxQlemYBPhSm0/oCXAT8Z4mzFpyoPyRc= -github.com/multiformats/go-multiaddr v0.12.0 h1:1QlibTFkoXJuDjjYsMHhE73TnzJQl8FSWatk/0gxGzE= -github.com/multiformats/go-multiaddr v0.12.0/go.mod h1:WmZXgObOQOYp9r3cslLlppkrz1FYSHmE834dfz/lWu8= +github.com/multiformats/go-multiaddr v0.12.1 h1:vm+BA/WZA8QZDp1pF1FWhi5CT3g1tbi5GJmqpb6wnlk= +github.com/multiformats/go-multiaddr v0.12.1/go.mod h1:7mPkiBMmLeFipt+nNSq9pHZUeJSt8lHBgH6yhj0YQzE= github.com/multiformats/go-multiaddr-dns v0.3.0/go.mod h1:mNzQ4eTGDg0ll1N9jKPOUogZPoJ30W8a7zk66FQPpdQ= github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A= github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk= @@ -657,13 +653,13 @@ github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9k github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4= -github.com/onsi/ginkgo/v2 v2.13.0/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o= +github.com/onsi/ginkgo/v2 v2.13.2 h1:Bi2gGVkfn6gQcjNjZJVO8Gf0FHzMPf2phUei9tejVMs= +github.com/onsi/ginkgo/v2 v2.13.2/go.mod h1:XStQ8QcGwLyF4HdfcZB8SFOS/MWCgDuXMSBe6zrvLgM= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= -github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= +github.com/onsi/gomega v1.29.0 h1:KIA/t2t5UBzoirT4H9tsML45GEbo3ouUnBHsCfD2tVg= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.1.0 h1:HHUyrt9mwHUjtasSbXSMvs4cyFxh+Bll4AjJ9odEGpg= github.com/opencontainers/runtime-spec v1.1.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= @@ -724,7 +720,6 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/polydawn/refmt v0.0.0-20190221155625-df39d6c2d992/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= github.com/polydawn/refmt v0.0.0-20201211092308-30ac6d18308e/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= github.com/polydawn/refmt v0.89.0 h1:ADJTApkvkeBZsN0tBTx8QjpD9JkmxbKp0cxfr9qszm4= github.com/polydawn/refmt v0.89.0/go.mod h1:/zvteZs/GwLtCgZ4BL6CBsk9IKIlexP43ObX9AxTqTw= @@ -737,8 +732,8 @@ github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqr github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_golang v1.12.2/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_golang v1.13.0/go.mod h1:vTeo+zgvILHsnnj/39Ou/1fPN5nJFOEMgftOUOmlvYQ= -github.com/prometheus/client_golang v1.17.0 h1:rl2sfwZMtSthVU752MqfjQozy7blglC+1SOtjMAMh+Q= -github.com/prometheus/client_golang v1.17.0/go.mod h1:VeL+gMmOAxkS2IqfCq0ZmHSL+LjWfWDUmp1mBz9JgUY= +github.com/prometheus/client_golang v1.18.0 h1:HzFfmkOzH5Q8L8G+kSJKUx5dtG87sewO+FoDDqP5Tbk= +github.com/prometheus/client_golang v1.18.0/go.mod h1:T+GXkCk5wSJyOqMIzVgvvjFDlkOQntgjkJWKrN5txjA= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -769,10 +764,10 @@ github.com/prometheus/statsd_exporter v0.22.7 h1:7Pji/i2GuhK6Lu7DHrtTkFmNBCudCPT github.com/prometheus/statsd_exporter v0.22.7/go.mod h1:N/TevpjkIh9ccs6nuzY3jQn9dFqnUakOjnEuMPJJJnI= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= -github.com/quic-go/qtls-go1-20 v0.3.4 h1:MfFAPULvst4yoMgY9QmtpYmfij/em7O8UUi+bNVm7Cg= -github.com/quic-go/qtls-go1-20 v0.3.4/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= -github.com/quic-go/quic-go v0.39.4 h1:PelfiuG7wXEffUT2yceiqz5V6Pc0TA5ruOd1LcmFc1s= -github.com/quic-go/quic-go v0.39.4/go.mod h1:T09QsDQWjLiQ74ZmacDfqZmhY/NLnw5BC40MANNNZ1Q= +github.com/quic-go/qtls-go1-20 v0.4.1 h1:D33340mCNDAIKBqXuAvexTNMUByrYmFYVfKfDN5nfFs= +github.com/quic-go/qtls-go1-20 v0.4.1/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= +github.com/quic-go/quic-go v0.40.1 h1:X3AGzUNFs0jVuO3esAGnTfvdgvL4fq655WaOi1snv1Q= +github.com/quic-go/quic-go v0.40.1/go.mod h1:PeN7kuVJ4xZbxSv/4OX6S1USOX8MJvydwpTx31vx60c= github.com/quic-go/webtransport-go v0.6.0 h1:CvNsKqc4W2HljHJnoT+rMmbRJybShZ0YPFDD3NxaZLY= github.com/quic-go/webtransport-go v0.6.0/go.mod h1:9KjU4AEBqEQidGHNDkZrb8CAa1abRaosM2yGOyiikEc= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= @@ -819,7 +814,6 @@ github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/assertions v1.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N3yZFZkDFs= github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo= -github.com/smartystreets/goconvey v0.0.0-20190222223459-a17d461953aa/go.mod h1:2RVY1rIf+2J2o/IM9+vPq9RzmHDSseB7FoXiSNIUsoU= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/smartystreets/goconvey v1.7.2 h1:9RBaZCeXEQ3UselpuwUQHltGVXvdwm6cv1hgR6gDIPg= github.com/smartystreets/goconvey v1.7.2/go.mod h1:Vw0tHAZW6lzCRk3xgdin6fKYcG+G3Pg9vgXWeJpQFMM= @@ -885,7 +879,6 @@ github.com/wangjia184/sortedset v0.0.0-20160527075905-f5d03557ba30/go.mod h1:Yko github.com/warpfork/go-testmark v0.3.0/go.mod h1:jhEf8FVxd+F17juRubpmut64NEG6I2rgkUhlcqqXwE0= github.com/warpfork/go-testmark v0.9.0/go.mod h1:jhEf8FVxd+F17juRubpmut64NEG6I2rgkUhlcqqXwE0= github.com/warpfork/go-testmark v0.12.1 h1:rMgCpJfwy1sJ50x0M0NgyphxYYPMOODIJHhsXyEHU0s= -github.com/warpfork/go-wish v0.0.0-20180510122957-5ad1f5abf436/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= github.com/warpfork/go-wish v0.0.0-20200122115046-b9ea61034e4a/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0 h1:GDDkbFiaK8jsSDJfjId/PEGEShv6ugrt4kYsC5UIDaQ= github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= @@ -893,9 +886,8 @@ github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc h1:BCPnHtcboa github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc/go.mod h1:r45hJU7yEoA81k6MWNhpMj/kms0n14dkzkxYHoB96UM= github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11 h1:5HZfQkwe0mIfyDmc1Em5GqlNRzcdtlv4HTNmdpt7XH0= github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11/go.mod h1:Wlo/SzPmxVp6vXpGt/zaXhHH0fn4IxgqZc82aKg6bpQ= -github.com/whyrusleeping/cbor-gen v0.0.0-20200123233031-1cdf64d27158/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI= -github.com/whyrusleeping/cbor-gen v0.0.0-20230126041949-52956bd4c9aa h1:EyA027ZAkuaCLoxVX4r1TZMPy1d31fM6hbfQ4OU4I5o= -github.com/whyrusleeping/cbor-gen v0.0.0-20230126041949-52956bd4c9aa/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= +github.com/whyrusleeping/cbor-gen v0.0.0-20240109153615-66e95c3e8a87 h1:S4wCk+ZL4WGGaI+GsmqCRyt68ISbnZWsK9dD9jYL0fA= +github.com/whyrusleeping/cbor-gen v0.0.0-20240109153615-66e95c3e8a87/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f h1:jQa4QT2UP9WYv2nzyawpKMOCl+Z/jW7djv2/J50lj9E= github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f/go.mod h1:p9UJB6dDgdPgMJZs7UjUOdulKyRr9fqkS+6JKAInPy8= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 h1:EKhdznlJHPMoKr0XTrX+IlJs1LH3lyx2nfr1dOlZ79k= @@ -966,8 +958,8 @@ go.uber.org/fx v1.20.1 h1:zVwVQGS8zYvhh9Xxcu4w1M6ESyeMzebzj2NbSayZ4Mk= go.uber.org/fx v1.20.1/go.mod h1:iSYNbHf2y55acNCwCXKx7LbWb5WG1Bnue5RDXz1OREg= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= -go.uber.org/mock v0.3.0 h1:3mUxI1No2/60yUYax92Pt8eNOEecx2D3lcXZh2NEZJo= -go.uber.org/mock v0.3.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= +go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= +go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= @@ -1003,8 +995,8 @@ golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= -golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY= -golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= +golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc= +golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1015,8 +1007,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20231214170342-aacd6d4b4611 h1:qCEDpW1G+vcj3Y7Fy52pEM1AWm3abj8WimGYejI3SC4= -golang.org/x/exp v0.0.0-20231214170342-aacd6d4b4611/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI= +golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc h1:ao2WRsKSzW6KuUY9IWPwWahcHCgR0s52IfwutMfEbdM= +golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1089,7 +1081,6 @@ golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= @@ -1098,8 +1089,8 @@ golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= -golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= +golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= +golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1109,8 +1100,8 @@ golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4Iltr golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.12.0 h1:smVPGxink+n1ZI5pkQa8y6fZT0RW0MgCO5bFpepy4B4= -golang.org/x/oauth2 v0.12.0/go.mod h1:A74bZ3aGXgCY0qaIC9Ahg6Lglin4AMAco8cIv9baba4= +golang.org/x/oauth2 v0.16.0 h1:aDkGMBSYxElaoP81NpoUoz2oo2R2wHdZpGToUxfyQrQ= +golang.org/x/oauth2 v0.16.0/go.mod h1:hqZ+0LWXsiVoZpeld6jVt06P3adbS2Uu911W1SsJv2o= golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1126,8 +1117,8 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= -golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= +golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/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= @@ -1203,8 +1194,8 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= -golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= +golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -1214,8 +1205,8 @@ golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= -golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4= -golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= +golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE= +golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1223,6 +1214,7 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= @@ -1288,14 +1280,14 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.16.0 h1:GO788SKMRunPIBCXiQyo2AaexLstOrVhuAL5YwsckQM= -golang.org/x/tools v0.16.0/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= +golang.org/x/tools v0.16.1 h1:TLyB3WofjdOEepBHAU20JdNC1Zbg87elYofWYAY5oZA= +golang.org/x/tools v0.16.1/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= -golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU= +golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= gonum.org/v1/gonum v0.14.0 h1:2NiG67LD1tEH0D7kM+ps2V+fXmsAnpUeec7n8tcr4S0= gonum.org/v1/gonum v0.14.0/go.mod h1:AoWeoz0becf9QMWtE8iWXNXc27fK4fNeHNf/oMejGfU= google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= @@ -1325,8 +1317,8 @@ google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7 google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= -google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= +google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= @@ -1360,11 +1352,11 @@ google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7Fc google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d h1:VBu5YqKPv6XiJ199exd8Br+Aetz+o08F+PLMnwJQHAY= -google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d h1:DoPTO70H+bcDXcd39vOqb2viZxgqeBeSGtZ55yZU4/Q= -google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d/go.mod h1:KjSP20unUpOx5kyQUFa7k4OJg0qeJ7DEZflGDu2p6Bk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d h1:uvYuEyMHKNt+lT4K3bN6fGswmK8qSvcreM3BwjDh+y4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M= +google.golang.org/genproto v0.0.0-20240102182953-50ed04b92917 h1:nz5NESFLZbJGPFxDT/HCn+V1mZ8JGNoY4nUpmW/Y2eg= +google.golang.org/genproto/googleapis/api v0.0.0-20240108191215-35c7eff3a6b1 h1:OPXtXn7fNMaXwO3JvOmF1QyTc00jsSFFz1vXXBOdCDo= +google.golang.org/genproto/googleapis/api v0.0.0-20240108191215-35c7eff3a6b1/go.mod h1:B5xPO//w8qmBDjGReYLpR6UJPnkldGkCSMoH/2vxJeg= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240108191215-35c7eff3a6b1 h1:gphdwh0npgs8elJ4T6J+DQJHPVF7RsuJHCfwztUb4J4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240108191215-35c7eff3a6b1/go.mod h1:daQN87bsDqDoe316QbbvX60nMoJQa4r6Ds0ZuoAe5yA= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= @@ -1381,8 +1373,8 @@ google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3Iji google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk= -google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98= +google.golang.org/grpc v1.60.1 h1:26+wFr+cNqSGFcOXcabYC0lUVJVRa2Sb2ortSK7VrEU= +google.golang.org/grpc v1.60.1/go.mod h1:OlCHIeLYqSSsLi6i49B5QGdzaMZK9+M7LXN2FKz4eGM= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -1397,8 +1389,8 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= -google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= +google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index c788ea081..0fb04b5f5 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -14,7 +14,7 @@ require ( github.com/ipfs/iptb-plugins v0.5.0 github.com/jbenet/go-random v0.0.0-20190219211222-123a90aedc0c github.com/jbenet/go-random-files v0.0.0-20190219210431-31b3f20ebded - github.com/multiformats/go-multiaddr v0.12.0 + github.com/multiformats/go-multiaddr v0.12.1 github.com/multiformats/go-multihash v0.2.3 gotest.tools/gotestsum v0.4.2 ) @@ -63,7 +63,7 @@ require ( github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/fzipp/gocyclo v0.6.0 // indirect github.com/go-critic/go-critic v0.9.0 // indirect - github.com/go-logr/logr v1.3.0 // indirect + github.com/go-logr/logr v1.4.1 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-toolsmith/astcast v1.1.0 // indirect github.com/go-toolsmith/astcopy v1.1.0 // indirect @@ -87,7 +87,7 @@ require ( github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/gopacket v1.1.19 // indirect - github.com/google/uuid v1.4.0 // indirect + github.com/google/uuid v1.5.0 // indirect github.com/gordonklaus/ineffassign v0.0.0-20230610083614-0e73809eb601 // indirect github.com/gostaticanalysis/analysisutil v0.7.1 // indirect github.com/gostaticanalysis/comment v1.4.2 // indirect @@ -103,7 +103,7 @@ require ( github.com/hexops/gotextdiff v1.0.3 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/ipfs/bbloom v0.0.4 // indirect - github.com/ipfs/boxo v0.16.1-0.20240109085802-d13d712f1c4e // indirect + github.com/ipfs/boxo v0.16.1-0.20240110145317-d8e9d95f7d05 // indirect github.com/ipfs/go-block-format v0.2.0 // indirect github.com/ipfs/go-cid v0.4.1 // indirect github.com/ipfs/go-datastore v0.6.0 // indirect @@ -179,7 +179,7 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect github.com/polydawn/refmt v0.89.0 // indirect github.com/polyfloyd/go-errorlint v1.4.3 // indirect - github.com/prometheus/client_golang v1.17.0 // indirect + github.com/prometheus/client_golang v1.18.0 // indirect github.com/prometheus/client_model v0.5.0 // indirect github.com/prometheus/common v0.45.0 // indirect github.com/prometheus/procfs v0.12.0 // indirect @@ -239,18 +239,18 @@ require ( go.tmz.dev/musttag v0.7.1 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.26.0 // indirect - golang.org/x/crypto v0.16.0 // indirect - golang.org/x/exp v0.0.0-20231214170342-aacd6d4b4611 // indirect + golang.org/x/crypto v0.18.0 // indirect + golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc // indirect golang.org/x/exp/typeparams v0.0.0-20230307190834-24139beb5833 // indirect golang.org/x/mod v0.14.0 // indirect - golang.org/x/net v0.19.0 // indirect - golang.org/x/sync v0.5.0 // indirect - golang.org/x/sys v0.15.0 // indirect - golang.org/x/term v0.15.0 // indirect + golang.org/x/net v0.20.0 // indirect + golang.org/x/sync v0.6.0 // indirect + golang.org/x/sys v0.16.0 // indirect + golang.org/x/term v0.16.0 // indirect golang.org/x/text v0.14.0 // indirect - golang.org/x/tools v0.16.0 // indirect + golang.org/x/tools v0.16.1 // indirect gonum.org/v1/gonum v0.14.0 // indirect - google.golang.org/protobuf v1.31.0 // indirect + google.golang.org/protobuf v1.32.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 186b01192..7c02bd2c7 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -155,7 +155,7 @@ github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4 github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94= github.com/firefart/nonamedreturns v1.0.4 h1:abzI1p7mAEPYuR4A+VLKn4eNDOycjYo2phmY9sfv40Y= github.com/firefart/nonamedreturns v1.0.4/go.mod h1:TDhe/tjI1BXo48CmYbUduTV7BdIga8MAO/xbKdcVsGI= -github.com/flynn/noise v1.0.0 h1:DlTHqmzmvcEiKj+4RYo/imoswx/4r6iBlCMfVtrMXpQ= +github.com/flynn/noise v1.0.1 h1:vPp/jdQLXC6ppsXSj/pM3W1BIJ5FEHE2TulSJBpb43Y= github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= @@ -175,8 +175,8 @@ github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9 github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY= -github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= +github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= @@ -290,11 +290,11 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b h1:RMpPgZTSApbPf7xaVel+QkoGPRLFLrwFO89uDUHEGf0= +github.com/google/pprof v0.0.0-20231229205709-960ae82b1e42 h1:dHLYa5D8/Ta0aLR2XcPsrkpAgGeFs6thhMcQK0oQ0n8= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= -github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU= +github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= @@ -342,8 +342,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.16.1-0.20240109085802-d13d712f1c4e h1:GFMm0GO3tTLmjJ6uNZnTq0HpYV/kygZhe1sKYHQ/aVc= -github.com/ipfs/boxo v0.16.1-0.20240109085802-d13d712f1c4e/go.mod h1:gCYL6EViui01M8Dr0cY8nOpRAbofxZDWASxbLSrG9Ac= +github.com/ipfs/boxo v0.16.1-0.20240110145317-d8e9d95f7d05 h1:xCn1uaroCjFVmZe0Q//QM8t2c8GxXO0bCG0TBu9p75A= +github.com/ipfs/boxo v0.16.1-0.20240110145317-d8e9d95f7d05/go.mod h1:pIZgTWdm3k3pLF9Uq6MB8JEcW07UDwNJjlXW1HELW80= github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs= github.com/ipfs/go-block-format v0.2.0/go.mod h1:+jpL11nFx5A/SPpsoBn6Bzkra/zaArfSmsknbPMYgzM= github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= @@ -419,7 +419,7 @@ github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kkHAIKE/contextcheck v1.1.4 h1:B6zAaLhOEEcjvUgIYEqystmnFk1Oemn8bvJhbt0GMb8= github.com/kkHAIKE/contextcheck v1.1.4/go.mod h1:1+i/gWqokIa+dm31mqGLZhZJ7Uh44DJGZVmr6QRBNJg= -github.com/klauspost/compress v1.17.2 h1:RlWWUY/Dr4fL8qk9YG7DTZ7PDgME2V4csBXA8L/ixi4= +github.com/klauspost/compress v1.17.4 h1:Ej5ixsIri7BrIjBkRZLTo6ghwrEtHFk7ijlczPW4fZ4= github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/48xc= github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -527,8 +527,8 @@ github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYg github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0= github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4= github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4= -github.com/multiformats/go-multiaddr v0.12.0 h1:1QlibTFkoXJuDjjYsMHhE73TnzJQl8FSWatk/0gxGzE= -github.com/multiformats/go-multiaddr v0.12.0/go.mod h1:WmZXgObOQOYp9r3cslLlppkrz1FYSHmE834dfz/lWu8= +github.com/multiformats/go-multiaddr v0.12.1 h1:vm+BA/WZA8QZDp1pF1FWhi5CT3g1tbi5GJmqpb6wnlk= +github.com/multiformats/go-multiaddr v0.12.1/go.mod h1:7mPkiBMmLeFipt+nNSq9pHZUeJSt8lHBgH6yhj0YQzE= github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A= github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk= github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E= @@ -561,7 +561,7 @@ github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6 github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w= github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo/v2 v2.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4= +github.com/onsi/ginkgo/v2 v2.13.2 h1:Bi2gGVkfn6gQcjNjZJVO8Gf0FHzMPf2phUei9tejVMs= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= @@ -595,8 +595,8 @@ github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5Fsn github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= -github.com/prometheus/client_golang v1.17.0 h1:rl2sfwZMtSthVU752MqfjQozy7blglC+1SOtjMAMh+Q= -github.com/prometheus/client_golang v1.17.0/go.mod h1:VeL+gMmOAxkS2IqfCq0ZmHSL+LjWfWDUmp1mBz9JgUY= +github.com/prometheus/client_golang v1.18.0 h1:HzFfmkOzH5Q8L8G+kSJKUx5dtG87sewO+FoDDqP5Tbk= +github.com/prometheus/client_golang v1.18.0/go.mod h1:T+GXkCk5wSJyOqMIzVgvvjFDlkOQntgjkJWKrN5txjA= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -625,8 +625,8 @@ github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727/go.mod h1:r github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 h1:M8mH9eK4OUR4lu7Gd+PU1fV2/qnDNfzT635KRSObncs= github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567/go.mod h1:DWNGW8A4Y+GyBgPuaQJuWiy0XYftx4Xm/y5Jqk9I6VQ= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= -github.com/quic-go/qtls-go1-20 v0.3.4 h1:MfFAPULvst4yoMgY9QmtpYmfij/em7O8UUi+bNVm7Cg= -github.com/quic-go/quic-go v0.39.4 h1:PelfiuG7wXEffUT2yceiqz5V6Pc0TA5ruOd1LcmFc1s= +github.com/quic-go/qtls-go1-20 v0.4.1 h1:D33340mCNDAIKBqXuAvexTNMUByrYmFYVfKfDN5nfFs= +github.com/quic-go/quic-go v0.40.1 h1:X3AGzUNFs0jVuO3esAGnTfvdgvL4fq655WaOi1snv1Q= github.com/quic-go/webtransport-go v0.6.0 h1:CvNsKqc4W2HljHJnoT+rMmbRJybShZ0YPFDD3NxaZLY= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= @@ -785,7 +785,7 @@ go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= go.uber.org/fx v1.20.1 h1:zVwVQGS8zYvhh9Xxcu4w1M6ESyeMzebzj2NbSayZ4Mk= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= -go.uber.org/mock v0.3.0 h1:3mUxI1No2/60yUYax92Pt8eNOEecx2D3lcXZh2NEZJo= +go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= @@ -806,8 +806,8 @@ golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= -golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY= -golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= +golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc= +golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -818,8 +818,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20231214170342-aacd6d4b4611 h1:qCEDpW1G+vcj3Y7Fy52pEM1AWm3abj8WimGYejI3SC4= -golang.org/x/exp v0.0.0-20231214170342-aacd6d4b4611/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI= +golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc h1:ao2WRsKSzW6KuUY9IWPwWahcHCgR0s52IfwutMfEbdM= +golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI= golang.org/x/exp/typeparams v0.0.0-20220428152302-39d4317da171/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/exp/typeparams v0.0.0-20230203172020-98cc5a0785f9/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/exp/typeparams v0.0.0-20230307190834-24139beb5833 h1:jWGQJV4niP+CCmFW9ekjA9Zx8vYORzOUH2/Nl5WPuLQ= @@ -899,8 +899,8 @@ golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= -golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= +golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= +golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -924,8 +924,8 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= -golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= +golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= 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= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -988,16 +988,16 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= -golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= +golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4= -golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= +golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE= +golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1088,8 +1088,8 @@ golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= golang.org/x/tools v0.5.0/go.mod h1:N+Kgy78s5I24c24dU8OfWNEotWjutIs8SnJvn5IDq+k= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.16.0 h1:GO788SKMRunPIBCXiQyo2AaexLstOrVhuAL5YwsckQM= -golang.org/x/tools v0.16.0/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= +golang.org/x/tools v0.16.1 h1:TLyB3WofjdOEepBHAU20JdNC1Zbg87elYofWYAY5oZA= +golang.org/x/tools v0.16.1/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1186,8 +1186,8 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= -google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= +google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= From 02ea51872b9258a95d549ea8116c739be796cb65 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Wed, 10 Jan 2024 16:33:48 +0100 Subject: [PATCH 0983/1212] chore: boxo v0.17.0 --- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- test/dependencies/go.mod | 2 +- test/dependencies/go.sum | 4 ++-- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 531207eed..0c15ff98b 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.20 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.16.1-0.20240110145317-d8e9d95f7d05 + github.com/ipfs/boxo v0.17.0 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.32.2 github.com/multiformats/go-multiaddr v0.12.1 diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 601831a1d..93a1b4492 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -260,8 +260,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.16.1-0.20240110145317-d8e9d95f7d05 h1:xCn1uaroCjFVmZe0Q//QM8t2c8GxXO0bCG0TBu9p75A= -github.com/ipfs/boxo v0.16.1-0.20240110145317-d8e9d95f7d05/go.mod h1:pIZgTWdm3k3pLF9Uq6MB8JEcW07UDwNJjlXW1HELW80= +github.com/ipfs/boxo v0.17.0 h1:fVXAb12dNbraCX1Cdid5BB6Kl62gVLNVA+e0EYMqAU0= +github.com/ipfs/boxo v0.17.0/go.mod h1:pIZgTWdm3k3pLF9Uq6MB8JEcW07UDwNJjlXW1HELW80= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.3/go.mod h1:4LmD4ZUw0mhO+JSKdpWwrzATiEfM7WWgQ8H5l6P8MVk= diff --git a/go.mod b/go.mod index 1c18a54b9..d8440e9f0 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,7 @@ require ( github.com/hashicorp/go-multierror v1.1.1 github.com/ipfs-shipyard/nopfs v0.0.12-0.20231027223058-cde3b5ba964c github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c - github.com/ipfs/boxo v0.16.1-0.20240110145317-d8e9d95f7d05 + github.com/ipfs/boxo v0.17.0 github.com/ipfs/go-block-format v0.2.0 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 diff --git a/go.sum b/go.sum index dfa3693cb..06ecc39ae 100644 --- a/go.sum +++ b/go.sum @@ -325,8 +325,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.16.1-0.20240110145317-d8e9d95f7d05 h1:xCn1uaroCjFVmZe0Q//QM8t2c8GxXO0bCG0TBu9p75A= -github.com/ipfs/boxo v0.16.1-0.20240110145317-d8e9d95f7d05/go.mod h1:pIZgTWdm3k3pLF9Uq6MB8JEcW07UDwNJjlXW1HELW80= +github.com/ipfs/boxo v0.17.0 h1:fVXAb12dNbraCX1Cdid5BB6Kl62gVLNVA+e0EYMqAU0= +github.com/ipfs/boxo v0.17.0/go.mod h1:pIZgTWdm3k3pLF9Uq6MB8JEcW07UDwNJjlXW1HELW80= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 0fb04b5f5..82a84fc67 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -103,7 +103,7 @@ require ( github.com/hexops/gotextdiff v1.0.3 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/ipfs/bbloom v0.0.4 // indirect - github.com/ipfs/boxo v0.16.1-0.20240110145317-d8e9d95f7d05 // indirect + github.com/ipfs/boxo v0.17.0 // indirect github.com/ipfs/go-block-format v0.2.0 // indirect github.com/ipfs/go-cid v0.4.1 // indirect github.com/ipfs/go-datastore v0.6.0 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 7c02bd2c7..6c929b869 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -342,8 +342,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.16.1-0.20240110145317-d8e9d95f7d05 h1:xCn1uaroCjFVmZe0Q//QM8t2c8GxXO0bCG0TBu9p75A= -github.com/ipfs/boxo v0.16.1-0.20240110145317-d8e9d95f7d05/go.mod h1:pIZgTWdm3k3pLF9Uq6MB8JEcW07UDwNJjlXW1HELW80= +github.com/ipfs/boxo v0.17.0 h1:fVXAb12dNbraCX1Cdid5BB6Kl62gVLNVA+e0EYMqAU0= +github.com/ipfs/boxo v0.17.0/go.mod h1:pIZgTWdm3k3pLF9Uq6MB8JEcW07UDwNJjlXW1HELW80= github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs= github.com/ipfs/go-block-format v0.2.0/go.mod h1:+jpL11nFx5A/SPpsoBn6Bzkra/zaArfSmsknbPMYgzM= github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= From b3c251abc23ad522295ff1b2e6d0ff856064a5ff Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Thu, 11 Jan 2024 08:13:54 +0000 Subject: [PATCH 0984/1212] chore: update version --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index 93f181c37..d97435b0b 100644 --- a/version.go +++ b/version.go @@ -11,7 +11,7 @@ import ( var CurrentCommit string // CurrentVersionNumber is the current application's version literal. -const CurrentVersionNumber = "0.26.0-dev" +const CurrentVersionNumber = "0.26.0-rc1" const ApiVersion = "/kubo/" + CurrentVersionNumber + "/" //nolint From e17753e95199c55d28b09afcdb1583207e018714 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Thu, 11 Jan 2024 09:56:27 +0100 Subject: [PATCH 0985/1212] docs: in RELEASE_ISSUE_TEMPLATE ask releaser to ensure we are using the latest go release on the major branch --- docs/RELEASE_ISSUE_TEMPLATE.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/RELEASE_ISSUE_TEMPLATE.md b/docs/RELEASE_ISSUE_TEMPLATE.md index 0b10ea8ae..26e5ad5be 100644 --- a/docs/RELEASE_ISSUE_TEMPLATE.md +++ b/docs/RELEASE_ISSUE_TEMPLATE.md @@ -116,6 +116,7 @@ This section covers tasks to be done during each release. - [ ] Publish the release to [DockerHub](https://hub.docker.com/r/ipfs/kubo/)
using `./kuboreleaser --skip-check-before --skip-run release --version vX.Y.Z(-rcN) publish-to-dockerhub` or ... - [ ] Wait for [Publish docker image](https://github.com/ipfs/kubo/actions/workflows/docker-image.yml) workflow run initiated by the tag push to finish - [ ] verify the image is available on [Docker Hub](https://hub.docker.com/r/ipfs/kubo/tags) +- [ ] Verify [ipfs/distributions](https://github.com/ipfs/distributions)'s `.tool-versions`'s `golang` entry is set to the [latest go release](https://go.dev/doc/devel/release) on the major go branch [Kubo is being tested on](https://github.com/ipfs/kubo/blob/master/.github/workflows/gotest.yml) (see `go-version:`). - [ ] Publish the release to [dist.ipfs.tech](https://dist.ipfs.tech)
using `./kuboreleaser release --version vX.Y.Z(-rcN) publish-to-distributions` or ... - [ ] check out [ipfs/distributions](https://github.com/ipfs/distributions) - [ ] run `./dist.sh add-version kubo vX.Y.Z(-RCN)` to add the new version to the `versions` file From 2963f1051b3b8ab8f6a4a4bd9e58d15b5eea9be8 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Thu, 11 Jan 2024 10:56:31 +0100 Subject: [PATCH 0986/1212] chore: increase time of sync-release-assets Need to increase the time so we can release 0.26.0-rc1. It seems that getting the assets is taking a bit longer than normal https://github.com/ipfs/kubo/actions/runs/7486931561/job/20378282844 --- .github/workflows/sync-release-assets.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/sync-release-assets.yml b/.github/workflows/sync-release-assets.yml index bc7eaed8d..12aec86cb 100644 --- a/.github/workflows/sync-release-assets.yml +++ b/.github/workflows/sync-release-assets.yml @@ -16,7 +16,7 @@ jobs: dist-ipfs-tech: if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' runs-on: "ubuntu-latest" - timeout-minutes: 5 + timeout-minutes: 15 steps: - uses: ipfs/download-ipfs-distribution-action@v1 - uses: ipfs/start-ipfs-daemon-action@v1 From 8978b5455aa768f527b53034032f8397ed2709ec Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Thu, 11 Jan 2024 08:14:30 +0000 Subject: [PATCH 0987/1212] chore: update version --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index 93f181c37..d5b0642f8 100644 --- a/version.go +++ b/version.go @@ -11,7 +11,7 @@ import ( var CurrentCommit string // CurrentVersionNumber is the current application's version literal. -const CurrentVersionNumber = "0.26.0-dev" +const CurrentVersionNumber = "0.27.0-dev" const ApiVersion = "/kubo/" + CurrentVersionNumber + "/" //nolint From 43629b5a7f761e18eadd4311519a46196019209e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 11 Jan 2024 19:14:36 +0000 Subject: [PATCH 0988/1212] chore(deps): bump docker/setup-qemu-action from 2 to 3 Bumps [docker/setup-qemu-action](https://github.com/docker/setup-qemu-action) from 2 to 3. - [Release notes](https://github.com/docker/setup-qemu-action/releases) - [Commits](https://github.com/docker/setup-qemu-action/compare/v2...v3) --- updated-dependencies: - dependency-name: docker/setup-qemu-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/docker-image.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index c1e77112d..de01af4dc 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -40,7 +40,7 @@ jobs: uses: actions/checkout@v4 - name: Set up QEMU - uses: docker/setup-qemu-action@v2 + uses: docker/setup-qemu-action@v3 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v2 From 0ee0ec664a2e62a0bc28d4b03c77451bcc0b1030 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 11 Jan 2024 19:14:43 +0000 Subject: [PATCH 0989/1212] chore(deps): bump docker/login-action from 2.2.0 to 3.0.0 Bumps [docker/login-action](https://github.com/docker/login-action) from 2.2.0 to 3.0.0. - [Release notes](https://github.com/docker/login-action/releases) - [Commits](https://github.com/docker/login-action/compare/465a07811f14bebb1938fbed4728c6a1ff8901fc...343f7c4344506bcbf9b4de18042ae17996df046d) --- updated-dependencies: - dependency-name: docker/login-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/docker-image.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index de01af4dc..d7765d6e0 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -63,7 +63,7 @@ jobs: shell: bash - name: Log in to Docker Hub - uses: docker/login-action@465a07811f14bebb1938fbed4728c6a1ff8901fc + uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d with: username: ${{ vars.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} From 2a33a0776061ced6b2fd0773939945cd74d90a50 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 11 Jan 2024 19:14:44 +0000 Subject: [PATCH 0990/1212] chore(deps): bump actions/setup-node from 3 to 4 Bumps [actions/setup-node](https://github.com/actions/setup-node) from 3 to 4. - [Release notes](https://github.com/actions/setup-node/releases) - [Commits](https://github.com/actions/setup-node/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/setup-node dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/build.yml | 4 ++-- .github/workflows/sync-release-assets.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3b30da2b4..22520f9b8 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -53,7 +53,7 @@ jobs: run: shell: bash steps: - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: node-version: lts/* - uses: actions/download-artifact@v3 @@ -109,7 +109,7 @@ jobs: run: shell: bash steps: - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: node-version: 18.14.0 - uses: actions/download-artifact@v3 diff --git a/.github/workflows/sync-release-assets.yml b/.github/workflows/sync-release-assets.yml index 12aec86cb..8a39f3234 100644 --- a/.github/workflows/sync-release-assets.yml +++ b/.github/workflows/sync-release-assets.yml @@ -22,7 +22,7 @@ jobs: - uses: ipfs/start-ipfs-daemon-action@v1 with: args: --init --init-profile=flatfs,server --enable-gc=false - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: node-version: 14 - name: Sync the latest 5 github releases From 24b223ceacad9b902d83f97747671001f0228b89 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 11 Jan 2024 19:14:43 +0000 Subject: [PATCH 0991/1212] chore(deps): bump docker/build-push-action from 4 to 5 Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 4 to 5. - [Release notes](https://github.com/docker/build-push-action/releases) - [Commits](https://github.com/docker/build-push-action/compare/v4...v5) --- updated-dependencies: - dependency-name: docker/build-push-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/docker-image.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index d7765d6e0..7c32418a5 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -72,7 +72,7 @@ jobs: # builds, only one platform is being loaded into the cache. This would # prevent us from testing the other platforms. - name: Build Docker image (linux/amd64) - uses: docker/build-push-action@v4 + uses: docker/build-push-action@v5 with: platforms: linux/amd64 context: . @@ -84,7 +84,7 @@ jobs: cache-to: type=local,dest=/tmp/.buildx-cache-new - name: Build Docker image (linux/arm/v7) - uses: docker/build-push-action@v4 + uses: docker/build-push-action@v5 with: platforms: linux/arm/v7 context: . @@ -96,7 +96,7 @@ jobs: cache-to: type=local,dest=/tmp/.buildx-cache-new - name: Build Docker image (linux/arm64/v8) - uses: docker/build-push-action@v4 + uses: docker/build-push-action@v5 with: platforms: linux/arm64/v8 context: . @@ -116,7 +116,7 @@ jobs: # This will only push the previously built images. - if: github.event_name != 'workflow_dispatch' || github.event.inputs.push == 'true' name: Publish to Docker Hub - uses: docker/build-push-action@v4 + uses: docker/build-push-action@v5 with: platforms: linux/amd64,linux/arm/v7,linux/arm64/v8 context: . From 75f39a40cb3b5fcbdd7f5b631899769d6231a31c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 11 Jan 2024 19:14:40 +0000 Subject: [PATCH 0992/1212] chore(deps): bump docker/setup-buildx-action from 2 to 3 Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 2 to 3. - [Release notes](https://github.com/docker/setup-buildx-action/releases) - [Commits](https://github.com/docker/setup-buildx-action/compare/v2...v3) --- updated-dependencies: - dependency-name: docker/setup-buildx-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/docker-image.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index 7c32418a5..fe28293e7 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -43,7 +43,7 @@ jobs: uses: docker/setup-qemu-action@v3 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 + uses: docker/setup-buildx-action@v3 - name: Cache Docker layers uses: actions/cache@v3 From 75f3c108327bcf13ae6aa10097271646c4b726e5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 11 Jan 2024 19:57:36 +0000 Subject: [PATCH 0993/1212] chore(deps): bump github.com/ipfs-shipyard/nopfs Bumps [github.com/ipfs-shipyard/nopfs](https://github.com/ipfs-shipyard/nopfs) from 0.0.12-0.20231027223058-cde3b5ba964c to 0.0.12. - [Release notes](https://github.com/ipfs-shipyard/nopfs/releases) - [Commits](https://github.com/ipfs-shipyard/nopfs/commits/v0.0.12) --- updated-dependencies: - dependency-name: github.com/ipfs-shipyard/nopfs dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 0c15ff98b..21ef07573 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -60,7 +60,7 @@ require ( github.com/hashicorp/golang-lru v1.0.2 // indirect github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/huin/goupnp v1.3.0 // indirect - github.com/ipfs-shipyard/nopfs v0.0.12-0.20231027223058-cde3b5ba964c // indirect + github.com/ipfs-shipyard/nopfs v0.0.12 // indirect github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c // indirect github.com/ipfs/bbloom v0.0.4 // indirect github.com/ipfs/go-bitfield v1.1.0 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 93a1b4492..6fa09260f 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -254,8 +254,8 @@ github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/ipfs-shipyard/nopfs v0.0.12-0.20231027223058-cde3b5ba964c h1:17FO7HnKiFhO7iadu3zCgII+EblpdRmJt5qg9FqQo8Y= -github.com/ipfs-shipyard/nopfs v0.0.12-0.20231027223058-cde3b5ba964c/go.mod h1:1oj4+g/mN6JRuZiXHt5iFRG02e62wp5AKcB3gdgknbk= +github.com/ipfs-shipyard/nopfs v0.0.12 h1:mvwaoefDF5VI9jyvgWCmaoTJIJFAfrbyQV5fJz35hlk= +github.com/ipfs-shipyard/nopfs v0.0.12/go.mod h1:mQyd0BElYI2gB/kq/Oue97obP4B3os4eBmgfPZ+hnrE= github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7UynTbtdlt+w08ggb1UGLGaGjp1mMaZhoTZSctpn5Ak= github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= diff --git a/go.mod b/go.mod index d8440e9f0..bf197784f 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( github.com/fsnotify/fsnotify v1.6.0 github.com/google/uuid v1.5.0 github.com/hashicorp/go-multierror v1.1.1 - github.com/ipfs-shipyard/nopfs v0.0.12-0.20231027223058-cde3b5ba964c + github.com/ipfs-shipyard/nopfs v0.0.12 github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c github.com/ipfs/boxo v0.17.0 github.com/ipfs/go-block-format v0.2.0 diff --git a/go.sum b/go.sum index 06ecc39ae..7c80a6dd2 100644 --- a/go.sum +++ b/go.sum @@ -319,8 +319,8 @@ github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/ipfs-shipyard/nopfs v0.0.12-0.20231027223058-cde3b5ba964c h1:17FO7HnKiFhO7iadu3zCgII+EblpdRmJt5qg9FqQo8Y= -github.com/ipfs-shipyard/nopfs v0.0.12-0.20231027223058-cde3b5ba964c/go.mod h1:1oj4+g/mN6JRuZiXHt5iFRG02e62wp5AKcB3gdgknbk= +github.com/ipfs-shipyard/nopfs v0.0.12 h1:mvwaoefDF5VI9jyvgWCmaoTJIJFAfrbyQV5fJz35hlk= +github.com/ipfs-shipyard/nopfs v0.0.12/go.mod h1:mQyd0BElYI2gB/kq/Oue97obP4B3os4eBmgfPZ+hnrE= github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7UynTbtdlt+w08ggb1UGLGaGjp1mMaZhoTZSctpn5Ak= github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= From 9343a95f4d568deebde2df3a458f383be6934382 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Fri, 8 Dec 2023 16:19:58 +0100 Subject: [PATCH 0994/1212] docs(config): clarify ReproviderStrategy roots --- docs/config.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/config.md b/docs/config.md index 495e90906..fd0c0a23e 100644 --- a/docs/config.md +++ b/docs/config.md @@ -1467,6 +1467,13 @@ Tells reprovider what should be announced. Valid strategies are: - `"all"` - announce all CIDs of stored blocks - `"pinned"` - only announce pinned CIDs recursively (both roots and child blocks) - `"roots"` - only announce the root block of explicitly pinned CIDs + - **⚠️ BE CAREFUL:** node with `roots` strategy will not announce child blocks. + It makes sense only for use cases where the entire DAG is fetched in full, + and a graceful resume does not have to be guaranteed: the lack of child + announcements means an interrupted retrieval won't be able to find + providers for the missing block in the middle of a file, unless the peer + happens to already be connected to a provider and ask for child CID over + bitswap. Default: `"all"` From 2738b49c1a22b742993f424725aa378fc53deec1 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Thu, 30 Nov 2023 11:49:50 +0100 Subject: [PATCH 0995/1212] profile: add trace --- core/commands/profile.go | 1 + profile/profile.go | 16 ++++++++++++++++ profile/profile_test.go | 1 + 3 files changed, 18 insertions(+) diff --git a/core/commands/profile.go b/core/commands/profile.go index d25711dac..9f54e0612 100644 --- a/core/commands/profile.go +++ b/core/commands/profile.go @@ -85,6 +85,7 @@ However, it could reveal: profile.CollectorCPU, profile.CollectorMutex, profile.CollectorBlock, + profile.CollectorTrace, }), cmds.StringOption(profileTimeOption, "The amount of time spent profiling. If this is set to 0, then sampling profiles are skipped.").WithDefault("30s"), cmds.IntOption(mutexProfileFractionOption, "The fraction 1/n of mutex contention events that are reported in the mutex profile.").WithDefault(4), diff --git a/profile/profile.go b/profile/profile.go index b9ad86d2f..be1e5adbb 100644 --- a/profile/profile.go +++ b/profile/profile.go @@ -10,6 +10,7 @@ import ( "os" "runtime" "runtime/pprof" + "runtime/trace" "sync" "time" @@ -27,6 +28,7 @@ const ( CollectorCPU = "cpu" CollectorMutex = "mutex" CollectorBlock = "block" + CollectorTrace = "trace" ) var ( @@ -98,6 +100,11 @@ var collectors = map[string]collector{ collectFunc: blockProfile, enabledFunc: func(opts Options) bool { return opts.ProfileDuration > 0 && opts.BlockProfileRate > 0 }, }, + CollectorTrace: { + outputFile: "trace", + collectFunc: captureTrace, + enabledFunc: func(opts Options) bool { return opts.ProfileDuration > 0 }, + }, } type Options struct { @@ -266,6 +273,15 @@ func profileCPU(ctx context.Context, opts Options, w io.Writer) error { return waitOrCancel(ctx, opts.ProfileDuration) } +func captureTrace(ctx context.Context, opts Options, w io.Writer) error { + err := trace.Start(w) + if err != nil { + return err + } + defer trace.Stop() + return waitOrCancel(ctx, opts.ProfileDuration) +} + func waitOrCancel(ctx context.Context, d time.Duration) error { timer := time.NewTimer(d) defer timer.Stop() diff --git a/profile/profile_test.go b/profile/profile_test.go index a2fe0b51d..0c06b00de 100644 --- a/profile/profile_test.go +++ b/profile/profile_test.go @@ -22,6 +22,7 @@ func TestProfiler(t *testing.T) { CollectorCPU, CollectorMutex, CollectorBlock, + CollectorTrace, } cases := []struct { From 21b820a5ef8ad5ef7093a58a6443a3bf6800b545 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Fri, 12 Jan 2024 14:46:49 +0100 Subject: [PATCH 0996/1212] fix: profiling tests --- profile/profile_test.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/profile/profile_test.go b/profile/profile_test.go index 0c06b00de..6c2f5784e 100644 --- a/profile/profile_test.go +++ b/profile/profile_test.go @@ -50,6 +50,7 @@ func TestProfiler(t *testing.T) { "cpu.pprof", "mutex.pprof", "block.pprof", + "trace", }, }, { @@ -71,6 +72,7 @@ func TestProfiler(t *testing.T) { "cpu.pprof", "mutex.pprof", "block.pprof", + "trace", }, }, { @@ -105,6 +107,7 @@ func TestProfiler(t *testing.T) { "ipfs", "cpu.pprof", "block.pprof", + "trace", }, }, { @@ -124,6 +127,7 @@ func TestProfiler(t *testing.T) { "ipfs", "cpu.pprof", "mutex.pprof", + "trace", }, }, { From 982d8a92c0401255f596dfa1b0240b6a63eca8ca Mon Sep 17 00:00:00 2001 From: Jorropo Date: Fri, 12 Jan 2024 14:02:45 +0100 Subject: [PATCH 0997/1212] chore: update boxo --- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- test/dependencies/go.mod | 2 +- test/dependencies/go.sum | 4 ++-- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 21ef07573..2582305b6 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.20 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.17.0 + github.com/ipfs/boxo v0.17.1-0.20240112124340-bcb321c857c5 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.32.2 github.com/multiformats/go-multiaddr v0.12.1 diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 6fa09260f..5cb425214 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -260,8 +260,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.17.0 h1:fVXAb12dNbraCX1Cdid5BB6Kl62gVLNVA+e0EYMqAU0= -github.com/ipfs/boxo v0.17.0/go.mod h1:pIZgTWdm3k3pLF9Uq6MB8JEcW07UDwNJjlXW1HELW80= +github.com/ipfs/boxo v0.17.1-0.20240112124340-bcb321c857c5 h1:qGPYOK8flU2YzHGq9Cb2Yeo0jjOwompAOzxOv3VSGx8= +github.com/ipfs/boxo v0.17.1-0.20240112124340-bcb321c857c5/go.mod h1:pIZgTWdm3k3pLF9Uq6MB8JEcW07UDwNJjlXW1HELW80= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.3/go.mod h1:4LmD4ZUw0mhO+JSKdpWwrzATiEfM7WWgQ8H5l6P8MVk= diff --git a/go.mod b/go.mod index bf197784f..9e94c0f22 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,7 @@ require ( github.com/hashicorp/go-multierror v1.1.1 github.com/ipfs-shipyard/nopfs v0.0.12 github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c - github.com/ipfs/boxo v0.17.0 + github.com/ipfs/boxo v0.17.1-0.20240112124340-bcb321c857c5 github.com/ipfs/go-block-format v0.2.0 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 diff --git a/go.sum b/go.sum index 7c80a6dd2..3b8feab09 100644 --- a/go.sum +++ b/go.sum @@ -325,8 +325,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.17.0 h1:fVXAb12dNbraCX1Cdid5BB6Kl62gVLNVA+e0EYMqAU0= -github.com/ipfs/boxo v0.17.0/go.mod h1:pIZgTWdm3k3pLF9Uq6MB8JEcW07UDwNJjlXW1HELW80= +github.com/ipfs/boxo v0.17.1-0.20240112124340-bcb321c857c5 h1:qGPYOK8flU2YzHGq9Cb2Yeo0jjOwompAOzxOv3VSGx8= +github.com/ipfs/boxo v0.17.1-0.20240112124340-bcb321c857c5/go.mod h1:pIZgTWdm3k3pLF9Uq6MB8JEcW07UDwNJjlXW1HELW80= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 82a84fc67..e0f00037b 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -103,7 +103,7 @@ require ( github.com/hexops/gotextdiff v1.0.3 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/ipfs/bbloom v0.0.4 // indirect - github.com/ipfs/boxo v0.17.0 // indirect + github.com/ipfs/boxo v0.17.1-0.20240112124340-bcb321c857c5 // indirect github.com/ipfs/go-block-format v0.2.0 // indirect github.com/ipfs/go-cid v0.4.1 // indirect github.com/ipfs/go-datastore v0.6.0 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 6c929b869..02d3c3500 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -342,8 +342,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.17.0 h1:fVXAb12dNbraCX1Cdid5BB6Kl62gVLNVA+e0EYMqAU0= -github.com/ipfs/boxo v0.17.0/go.mod h1:pIZgTWdm3k3pLF9Uq6MB8JEcW07UDwNJjlXW1HELW80= +github.com/ipfs/boxo v0.17.1-0.20240112124340-bcb321c857c5 h1:qGPYOK8flU2YzHGq9Cb2Yeo0jjOwompAOzxOv3VSGx8= +github.com/ipfs/boxo v0.17.1-0.20240112124340-bcb321c857c5/go.mod h1:pIZgTWdm3k3pLF9Uq6MB8JEcW07UDwNJjlXW1HELW80= github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs= github.com/ipfs/go-block-format v0.2.0/go.mod h1:+jpL11nFx5A/SPpsoBn6Bzkra/zaArfSmsknbPMYgzM= github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= From 765147faf0ed0d63924b6e0fd0a0fd36160917ce Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Jan 2024 21:41:49 +0000 Subject: [PATCH 0998/1212] chore(deps): bump actions/setup-go from 4 to 5 Bumps [actions/setup-go](https://github.com/actions/setup-go) from 4 to 5. - [Release notes](https://github.com/actions/setup-go/releases) - [Commits](https://github.com/actions/setup-go/compare/v4...v5) --- updated-dependencies: - dependency-name: actions/setup-go dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/build.yml | 2 +- .github/workflows/docker-build.yml | 2 +- .github/workflows/gateway-conformance.yml | 4 ++-- .github/workflows/gobuild.yml | 2 +- .github/workflows/golang-analysis.yml | 2 +- .github/workflows/golint.yml | 2 +- .github/workflows/gotest.yml | 2 +- .github/workflows/sharness.yml | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 22520f9b8..73e72daf6 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -36,7 +36,7 @@ jobs: run: shell: bash steps: - - uses: actions/setup-go@v4 + - uses: actions/setup-go@v5 with: go-version: ${{ env.GO_VERSION }} - uses: actions/checkout@v4 diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml index d05429a6c..733dc2c0e 100644 --- a/.github/workflows/docker-build.yml +++ b/.github/workflows/docker-build.yml @@ -26,7 +26,7 @@ jobs: run: shell: bash steps: - - uses: actions/setup-go@v4 + - uses: actions/setup-go@v5 with: go-version: 1.21.x - uses: actions/checkout@v4 diff --git a/.github/workflows/gateway-conformance.yml b/.github/workflows/gateway-conformance.yml index 754a2e5a8..94ab1e17a 100644 --- a/.github/workflows/gateway-conformance.yml +++ b/.github/workflows/gateway-conformance.yml @@ -47,7 +47,7 @@ jobs: # 2. Build the kubo-gateway - name: Setup Go - uses: actions/setup-go@v4 + uses: actions/setup-go@v5 with: go-version: 1.21.x - uses: protocol/cache-go-action@v1 @@ -135,7 +135,7 @@ jobs: # 2. Build the kubo-gateway - name: Setup Go - uses: actions/setup-go@v4 + uses: actions/setup-go@v5 with: go-version: 1.20.x - uses: protocol/cache-go-action@v1 diff --git a/.github/workflows/gobuild.yml b/.github/workflows/gobuild.yml index 13eabc0fc..f5de9e517 100644 --- a/.github/workflows/gobuild.yml +++ b/.github/workflows/gobuild.yml @@ -28,7 +28,7 @@ jobs: run: shell: bash steps: - - uses: actions/setup-go@v4 + - uses: actions/setup-go@v5 with: go-version: 1.21.x - uses: actions/checkout@v4 diff --git a/.github/workflows/golang-analysis.yml b/.github/workflows/golang-analysis.yml index eddaba988..0643de160 100644 --- a/.github/workflows/golang-analysis.yml +++ b/.github/workflows/golang-analysis.yml @@ -25,7 +25,7 @@ jobs: - uses: actions/checkout@v4 with: submodules: recursive - - uses: actions/setup-go@v4 + - uses: actions/setup-go@v5 with: go-version: "1.21.x" - name: Check that go.mod is tidy diff --git a/.github/workflows/golint.yml b/.github/workflows/golint.yml index d6191e6f3..591507471 100644 --- a/.github/workflows/golint.yml +++ b/.github/workflows/golint.yml @@ -29,7 +29,7 @@ jobs: run: shell: bash steps: - - uses: actions/setup-go@v4 + - uses: actions/setup-go@v5 with: go-version: 1.21.x - uses: actions/checkout@v4 diff --git a/.github/workflows/gotest.yml b/.github/workflows/gotest.yml index a1042cf7a..e3bf5c4d6 100644 --- a/.github/workflows/gotest.yml +++ b/.github/workflows/gotest.yml @@ -30,7 +30,7 @@ jobs: shell: bash steps: - name: Set up Go - uses: actions/setup-go@v4 + uses: actions/setup-go@v5 with: go-version: 1.21.x - name: Check out Kubo diff --git a/.github/workflows/sharness.yml b/.github/workflows/sharness.yml index 448e112de..0b8fc8942 100644 --- a/.github/workflows/sharness.yml +++ b/.github/workflows/sharness.yml @@ -23,7 +23,7 @@ jobs: shell: bash steps: - name: Setup Go - uses: actions/setup-go@v4 + uses: actions/setup-go@v5 with: go-version: 1.21.x - name: Checkout Kubo From 2a070973a9271ed525beca80988126ff7a189418 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Jan 2024 21:41:56 +0000 Subject: [PATCH 0999/1212] chore(deps): bump actions/github-script from 6 to 7 Bumps [actions/github-script](https://github.com/actions/github-script) from 6 to 7. - [Release notes](https://github.com/actions/github-script/releases) - [Commits](https://github.com/actions/github-script/compare/v6...v7) --- updated-dependencies: - dependency-name: actions/github-script dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/sync-release-assets.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/sync-release-assets.yml b/.github/workflows/sync-release-assets.yml index 8a39f3234..0d5c8199b 100644 --- a/.github/workflows/sync-release-assets.yml +++ b/.github/workflows/sync-release-assets.yml @@ -26,7 +26,7 @@ jobs: with: node-version: 14 - name: Sync the latest 5 github releases - uses: actions/github-script@v6 + uses: actions/github-script@v7 with: script: | const fs = require('fs').promises From 22742ba782d23f5ca5ed81186d2e2eb0aff228d5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Jan 2024 21:42:13 +0000 Subject: [PATCH 1000/1212] chore(deps): bump actions/upload-artifact and actions/download-artifact from 3 to 4 Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 3 to 4. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 3 to 4. - [Release notes](https://github.com/actions/download-artifact/releases) - [Commits](https://github.com/actions/download-artifact/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/download-artifact dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/build.yml | 6 +++--- .github/workflows/gateway-conformance.yml | 8 ++++---- .github/workflows/gotest.yml | 4 ++-- .github/workflows/sharness.yml | 4 ++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 73e72daf6..9e0c91105 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -41,7 +41,7 @@ jobs: go-version: ${{ env.GO_VERSION }} - uses: actions/checkout@v4 - run: make build - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: name: kubo path: cmd/ipfs/ipfs @@ -56,7 +56,7 @@ jobs: - uses: actions/setup-node@v4 with: node-version: lts/* - - uses: actions/download-artifact@v3 + - uses: actions/download-artifact@v4 with: name: kubo path: cmd/ipfs @@ -112,7 +112,7 @@ jobs: - uses: actions/setup-node@v4 with: node-version: 18.14.0 - - uses: actions/download-artifact@v3 + - uses: actions/download-artifact@v4 with: name: kubo path: cmd/ipfs diff --git a/.github/workflows/gateway-conformance.yml b/.github/workflows/gateway-conformance.yml index 94ab1e17a..993dfca61 100644 --- a/.github/workflows/gateway-conformance.yml +++ b/.github/workflows/gateway-conformance.yml @@ -111,13 +111,13 @@ jobs: run: cat output.md >> $GITHUB_STEP_SUMMARY - name: Upload HTML report if: failure() || success() - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: gateway-conformance.html path: output.html - name: Upload JSON report if: failure() || success() - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: gateway-conformance.json path: output.json @@ -217,13 +217,13 @@ jobs: run: cat output.md >> $GITHUB_STEP_SUMMARY - name: Upload HTML report if: failure() || success() - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: gateway-conformance-libp2p.html path: output.html - name: Upload JSON report if: failure() || success() - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: gateway-conformance-libp2p.json path: output.json diff --git a/.github/workflows/gotest.yml b/.github/workflows/gotest.yml index e3bf5c4d6..c6b2cdc07 100644 --- a/.github/workflows/gotest.yml +++ b/.github/workflows/gotest.yml @@ -79,7 +79,7 @@ jobs: output: test/unit/gotest.junit.xml if: failure() || success() - name: Archive the JUnit XML report - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: unit path: test/unit/gotest.junit.xml @@ -92,7 +92,7 @@ jobs: output: test/unit/gotest.html if: failure() || success() - name: Archive the HTML report - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: html path: test/unit/gotest.html diff --git a/.github/workflows/sharness.yml b/.github/workflows/sharness.yml index 0b8fc8942..7bf3325ef 100644 --- a/.github/workflows/sharness.yml +++ b/.github/workflows/sharness.yml @@ -88,7 +88,7 @@ jobs: destination: sharness.html - name: Upload one-page HTML report if: github.repository != 'ipfs/kubo' && (failure() || success()) - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: sharness.html path: kubo/test/sharness/test-results/sharness.html @@ -108,7 +108,7 @@ jobs: destination: sharness-html/ - name: Upload full HTML report if: github.repository != 'ipfs/kubo' && (failure() || success()) - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: sharness-html path: kubo/test/sharness/test-results/sharness-html From f72c6cf9838ca2d4f72a475034926d006fc1de7e Mon Sep 17 00:00:00 2001 From: Jorropo Date: Tue, 16 Jan 2024 08:18:58 +0100 Subject: [PATCH 1001/1212] dependabot: only update github-actions We update go packages as part of the release cycle, dependant bots also never fixup all the `go.sum` in the repo so this is noisy failing PRs. --- .github/dependabot.yml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 6ff8dba1f..5ace4600a 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,13 +1,5 @@ version: 2 updates: - - package-ecosystem: gomod - directory: "/" - schedule: - interval: daily - time: "11:00" - open-pull-requests-limit: 10 - labels: - - "topic/dependencies" - package-ecosystem: "github-actions" directory: "/" schedule: From 0ec6308e8bf2c18991de7ec0da68bfe6f20ec239 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Tue, 16 Jan 2024 10:56:00 +0100 Subject: [PATCH 1002/1212] core/corehttp: wrap hostname option with otelhttp --- core/corehttp/gateway.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/core/corehttp/gateway.go b/core/corehttp/gateway.go index a2567d8f0..a15765176 100644 --- a/core/corehttp/gateway.go +++ b/core/corehttp/gateway.go @@ -62,7 +62,12 @@ func HostnameOption() ServeOption { } childMux := http.NewServeMux() - mux.Handle("/", gateway.NewHostnameHandler(config, backend, childMux)) + + var handler http.Handler + handler = gateway.NewHostnameHandler(config, backend, childMux) + handler = otelhttp.NewHandler(handler, "HostnameGateway") + + mux.Handle("/", handler) return childMux, nil } } From 35ad4aee7fead1a5a22400d1dc99685094fee898 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Tue, 16 Jan 2024 13:57:11 +0100 Subject: [PATCH 1003/1212] ci: use latest tagged @helia/interop version --- .github/workflows/build.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9e0c91105..69534112d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -73,13 +73,12 @@ jobs: - uses: actions/checkout@v4 with: repository: ipfs/helia - fetch-depth: 1 + fetch-depth: 0 path: interop - ref: 'ea5533c794df844c9fb9812e85e2f5e6af09efeb' # temporary while this commit is being released + ref: 'main' - name: Checkout latest tag run: | - exit 0 # temporary while ea5533c794df844c9fb9812e85e2f5e6af09efeb is released - export TAG="$(git describe --tags --abbrev=0)" + export TAG="$(git tag | grep "^interop-" | sort --version-sort --reverse | head -n1)" echo "Running tests against: $TAG" git checkout "$TAG" working-directory: interop From e11d7b0c13a007351ee9cc4108f2860eea15f404 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Tue, 16 Jan 2024 14:33:54 +0100 Subject: [PATCH 1004/1212] docs: improve release issue template (#10305) --- docs/RELEASE_CHECKLIST.md | 180 +++++++++++++++++++++++++++ docs/RELEASE_ISSUE_TEMPLATE.md | 221 +++------------------------------ 2 files changed, 197 insertions(+), 204 deletions(-) create mode 100644 docs/RELEASE_CHECKLIST.md diff --git a/docs/RELEASE_CHECKLIST.md b/docs/RELEASE_CHECKLIST.md new file mode 100644 index 000000000..b0a89dccc --- /dev/null +++ b/docs/RELEASE_CHECKLIST.md @@ -0,0 +1,180 @@ + + +# ✅ Release Checklist (vX.Y.Z[-rcN]) + +## Labels + +If an item should be executed for a specific release type, it should be labeled with one of the following labels: + +- ![](https://img.shields.io/badge/only-RC-blue?style=flat-square) execute **ONLY** when releasing a Release Candidate +- ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) execute **ONLY** when releasing a Final Release + +Otherwise, it means it should be executed for **ALL** release types. + +Patch releases should follow the same process as `.0` releases. If some item should **NOT** be executed for a Patch Release, it should be labeled with: + +- ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) do **NOT** execute when releasing a Patch Release + +## Before the release + +This section covers tasks to be done ahead of the release. + +- [ ] Verify you have access to all the services and tools required for the release + - [ ] [GPG signature](https://docs.github.com/en/authentication/managing-commit-signature-verification) configured in local git and in GitHub + - [ ] [admin access to IPFS Discourse](https://discuss.ipfs.tech/g/admins) + - ask the previous release owner (or @2color) for an invite + - [ ] ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) [access to #shared-pl-marketing-requests](https://filecoinproject.slack.com/archives/C018EJ8LWH1) channel in FIL Slack + - ask the previous release owner for an invite + - [ ] [access to IPFS network metrics](https://github.com/protocol/pldw/blob/624f47cf4ec14ad2cec6adf601a9f7b203ef770d/docs/sources/ipfs.md#ipfs-network-metrics) dashboards in Grafana + - open an access request in the [pldw](https://github.com/protocol/pldw/issues/new/choose) + - [example](https://github.com/protocol/pldw/issues/158) + - [ ] [kuboreleaser](https://github.com/ipfs/kuboreleaser) checked out on your system (_only if you're using [kuboreleaser](https://github.com/ipfs/kuboreleaser)_) + - [ ] [Thunderdome](https://github.com/ipfs-shipyard/thunderdome) checked out on your system and configured (see the [Thunderdome release docs](./releases_thunderdome.md) for setup) + - [ ] [docker](https://docs.docker.com/get-docker/) installed on your system (_only if you're using [kuboreleaser](https://github.com/ipfs/kuboreleaser)_) + - [ ] [npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) installed on your system (_only if you're **NOT** using [kuboreleaser](https://github.com/ipfs/kuboreleaser)_) + - [ ] [zsh](https://github.com/ohmyzsh/ohmyzsh/wiki/Installing-ZSH#install-and-set-up-zsh-as-default) installed on your system + - [ ] [kubo](https://github.com/ipfs/kubo) checked out under `$(go env GOPATH)/src/github.com/ipfs/kubo` + - you can also symlink your clone to the expected location by running `mkdir -p $(go env GOPATH)/src/github.com/ipfs && ln -s $(pwd) $(go env GOPATH)/src/github.com/ipfs/kubo` + - [ ] ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) [Reddit](https://www.reddit.com) account +- ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) Upgrade Go used in CI to the latest patch release available in [CircleCI](https://hub.docker.com/r/cimg/go/tags) in: + - [ ] ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) [ipfs/distributions](https://github.com/ipfs/distributions) + - [example](https://github.com/ipfs/distributions/pull/756) + - [ ] ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) [ipfs/ipfs-docs](https://github.com/ipfs/ipfs-docs) + - [example](https://github.com/ipfs/ipfs-docs/pull/1298) +- [ ] Verify there is nothing [left for release](-what-s-left-for-release) +- [ ] Create a release process improvement PR + - [ ] update the [release issue template](docs/RELEASE_ISSUE_TEMPLATE.md) as you go + - [ ] link it in the [Meta](#meta) section + +## The release + +This section covers tasks to be done during each release. + +- [ ] Prepare the release branch and update version numbers accordingly
using `./kuboreleaser --skip-check-before release --version vX.Y.Z(-rcN) prepare-branch` or ... + - [ ] create a new branch `release-vX.Y.Z` + - use `master` as base if `Z == 0` + - use `release` as base if `Z > 0` + - [ ] ![](https://img.shields.io/badge/only-RC-blue?style=flat-square) update the `CurrentVersionNumber` in [version.go](version.go) in the `master` branch to `vX.Y+1.0-dev` + - [example](https://github.com/ipfs/kubo/pull/9305) + - [ ] update the `CurrentVersionNumber` in [version.go](version.go) in the `release-vX.Y` branch to `vX.Y.Z(-RCN)` + - [example](https://github.com/ipfs/kubo/pull/9394) + - [ ] create a draft PR from `release-vX.Y` to `release` + - [example](https://github.com/ipfs/kubo/pull/9306) + - [ ] Cherry-pick commits from `master` to the `release-vX.Y.Z` using `git cherry-pick -x ` + - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Add full changelog and contributors to the [changelog](docs/changelogs/vX.Y.md) + - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Replace the `Changelog` and `Contributors` sections of the [changelog](docs/changelogs/vX.Y.md) with the stdout of `./bin/mkreleaselog` + - do **NOT** copy the stderr + - [ ] verify all CI checks on the PR from `release-vX.Y` to `release` are passing + - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Merge the PR from `release-vX.Y` to `release` using the `Create a merge commit` + - do **NOT** use `Squash and merge` nor `Rebase and merge` because we need to be able to sign the merge commit + - do **NOT** delete the `release-vX.Y` branch +
+- [ ] Run Thunderdome testing, see the [Thunderdome release docs](./releases_thunderdome.md) for details + - [ ] create a PR and merge the experiment config into Thunderdome +- [ ] Create the release tag
using `./kuboreleaser release --version vX.Y.Z(-rcN) tag` or ... + - This is a dangerous operation! Go and Docker publishing are difficult to reverse! Have the release reviewer verify all the commands marked with ⚠️! + - [ ] ⚠️ ![](https://img.shields.io/badge/only-RC-blue?style=flat-square) tag the HEAD commit using `git tag -s vX.Y.Z(-RCN) -m 'Prerelease X.Y.Z(-RCN)'` + - [ ] ⚠️ ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) tag the HEAD commit of the `release` branch using `git tag -s vX.Y.Z(-RCN) -m 'Release X.Y.Z(-RCN)'` + - [ ] ⚠️ verify the tag is signed and tied to the correct commit using `git show vX.Y.Z(-RCN)` + - [ ] ⚠️ push the tag to GitHub using `git push origin vX.Y.Z(-RCN)` + - do **NOT** use `git push --tags` because it pushes all your local tags +
+- [ ] Publish the release to [DockerHub](https://hub.docker.com/r/ipfs/kubo/)
using `./kuboreleaser --skip-check-before --skip-run release --version vX.Y.Z(-rcN) publish-to-dockerhub` or ... + - [ ] Wait for [Publish docker image](https://github.com/ipfs/kubo/actions/workflows/docker-image.yml) workflow run initiated by the tag push to finish + - [ ] verify the image is available on [Docker Hub](https://hub.docker.com/r/ipfs/kubo/tags) +- [ ] Verify [ipfs/distributions](https://github.com/ipfs/distributions)'s `.tool-versions`'s `golang` entry is set to the [latest go release](https://go.dev/doc/devel/release) on the major go branch [Kubo is being tested on](https://github.com/ipfs/kubo/blob/master/.github/workflows/gotest.yml) (see `go-version:`). +- [ ] Publish the release to [dist.ipfs.tech](https://dist.ipfs.tech)
using `./kuboreleaser release --version vX.Y.Z(-rcN) publish-to-distributions` or ... + - [ ] check out [ipfs/distributions](https://github.com/ipfs/distributions) + - [ ] run `./dist.sh add-version kubo vX.Y.Z(-RCN)` to add the new version to the `versions` file + - [usage](https://github.com/ipfs/distributions#usage) + - [ ] create and merge the PR which updates `dists/kubo/versions` and `dists/go-ipfs/versions` (![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) and `dists/kubo/current_version` and `dists/go-ipfs/current_version`) + - [example](https://github.com/ipfs/distributions/pull/760) + - [ ] wait for the [CI](https://github.com/ipfs/distributions/actions/workflows/main.yml) workflow run initiated by the merge to master to finish + - [ ] verify the release is available on [dist.ipfs.io](https://dist.ipfs.io/#kubo) +
+- [ ] Publish the release to [NPM](https://www.npmjs.com/package/go-ipfs?activeTab=versions)
using `./kuboreleaser release --version vX.Y.Z(-rcN) publish-to-npm` (⚠️ you might need to run the command a couple of times because GHA might not be able to see the new distribution straight away due to caching) or ... + - [ ] run the [Release to npm](https://github.com/ipfs/npm-go-ipfs/actions/workflows/main.yml) workflow + - [ ] check [Release to npm](https://github.com/ipfs/npm-go-ipfs/actions/workflows/main.yml) workflow run logs to verify it discovered the new release + - [ ] verify the release is available on [NPM](https://www.npmjs.com/package/go-ipfs?activeTab=versions) +
+- [ ] Publish the release to [GitHub](https://github.com/ipfs/kubo/releases)
using `./kuboreleaser release --version vX.Y.Z(-rcN) publish-to-github` or ... + - [ ] create a new release on [GitHub](https://docs.github.com/en/repositories/releasing-projects-on-github/managing-releases-in-a-repository#creating-a-release) + - [RC example](https://github.com/ipfs/kubo/releases/tag/v0.17.0-rc1) + - [FINAL example](https://github.com/ipfs/kubo/releases/tag/v0.17.0) + - [ ] use the `vX.Y.Z(-RCN)` tag + - [ ] link to the release issue + - [ ] ![](https://img.shields.io/badge/only-RC-blue?style=flat-square) link to the changelog in the description + - [ ] ![](https://img.shields.io/badge/only-RC-blue?style=flat-square) check the `This is a pre-release` checkbox + - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) copy the changelog (without the header) in the description + - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) do **NOT** check the `This is a pre-release` checkbox + - [ ] run the [sync-release-assets](https://github.com/ipfs/kubo/actions/workflows/sync-release-assets.yml) workflow + - [ ] wait for the [sync-release-assets](https://github.com/ipfs/kubo/actions/workflows/sync-release-assets.yml) workflow run to finish + - [ ] verify the release assets are present in the [GitHub release](https://github.com/ipfs/kubo/releases/tag/vX.Y.Z(-RCN)) +
+- [ ] Promote the release
using `./kuboreleaser release --version vX.Y.Z(-rcN) promote` or ... + - [ ] create an [IPFS Discourse](https://discuss.ipfs.tech) topic + - [prerelease example](https://discuss.ipfs.tech/t/kubo-v0-16-0-rc1-release-candidate-is-out/15248) + - [release example](https://discuss.ipfs.tech/t/kubo-v0-16-0-release-is-out/15249) + - [ ] use `Kubo vX.Y.Z(-RCN) is out!` as the title + - [ ] use `kubo` and `go-ipfs` as topics + - [ ] repeat the title as a heading (`##`) in the description + - [ ] link to the GitHub Release, binaries on IPNS, docker pull command and release notes in the description + - [ ] pin the [IPFS Discourse](https://discuss.ipfs.tech) topic globally + - you can make the topic a banner if there is no banner already + - verify the [IPFS Discourse](https://discuss.ipfs.tech) topic was copied to: + - [ ] [#ipfs-chatter](https://discord.com/channels/669268347736686612/669268347736686615) in IPFS Discord + - [ ] [#ipfs-chatter](https://filecoinproject.slack.com/archives/C018EJ8LWH1) in FIL Slack + - [ ] [#ipfs-chatter:ipfs.io](https://matrix.to/#/#ipfs-chatter:ipfs.io) in Matrix + - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Add the link to the [IPFS Discourse](https://discuss.ipfs.tech) topic to the [GitHub Release](https://github.com/ipfs/kubo/releases/tag/vX.Y.Z(-RCN)) description + - [example](https://github.com/ipfs/kubo/releases/tag/v0.17.0) + - [ ] ![](https://img.shields.io/badge/only-RC-blue?style=flat-square) create an issue comment mentioning early testers on the release issue + - [example](https://github.com/ipfs/kubo/issues/9319#issuecomment-1311002478) + - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) create an issue comment linking to the release on the release issue + - [example](https://github.com/ipfs/kubo/issues/9417#issuecomment-1400740975) + - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) ask the marketing team to tweet about the release in [#shared-pl-marketing-requests](https://filecoinproject.slack.com/archives/C018EJ8LWH1) in FIL Slack + - [example](https://filecoinproject.slack.com/archives/C018EJ8LWH1/p1664885305374900) + - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) post the link to the [GitHub Release](https://github.com/ipfs/kubo/releases/tag/vX.Y.Z(-RCN)) to [Reddit](https://reddit.com/r/ipfs) + - [example](https://www.reddit.com/r/ipfs/comments/9x0q0k/kubo_v0160_release_is_out/) +
+- [ ] Test the new version with `ipfs-companion`
using `./kuboreleaser release --version vX.Y.Z(-rcN) test-ipfs-companion` or ... + - [ ] run the [e2e](https://github.com/ipfs/ipfs-companion/actions/workflows/e2e.yml) + - use `vX.Y.Z(-RCN)` as the Kubo image version + - [ ] wait for the [e2e](https://github.com/ipfs/ipfs-companion/actions/workflows/e2e.yml) workflow run to finish +
+- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Update Kubo in [ipfs-desktop](https://github.com/ipfs/ipfs-desktop)
using `./kuboreleaser release --version vX.Y.Z(-rcN) update-ipfs-desktop` or ... + - [ ] check out [ipfs/ipfs-desktop](https://github.com/ipfs/ipfs-desktop) + - [ ] run `npm install` + - [ ] create a PR which updates `package.json` and `package-lock.json` + - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) add @SgtPooki and @whizzzkid as reviewers +
+- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Update Kubo docs
using `./kuboreleaser release --version vX.Y.Z(-rcN) update-ipfs-docs` or ... + - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) run the [update-on-new-ipfs-tag.yml](https://github.com/ipfs/ipfs-docs/actions/workflows/update-on-new-ipfs-tag.yml) workflow + - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) merge the PR created by the [update-on-new-ipfs-tag.yml](https://github.com/ipfs/ipfs-docs/actions/workflows/update-on-new-ipfs-tag.yml) workflow run +
+- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Ask Brave to update Kubo in Brave Desktop + - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) use [this link](https://github.com/brave/brave-browser/issues/new?assignees=&labels=OS%2FDesktop&projects=&template=desktop.md&title=) to create an issue for the new Kubo version + - [basic example](https://github.com/brave/brave-browser/issues/31453), [example with additional notes](https://github.com/brave/brave-browser/issues/27965) + - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) post link to the issue in `#shared-pl-brave` for visibility +- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Create a blog entry on [blog.ipfs.tech](https://blog.ipfs.tech)
using `./kuboreleaser release --version vX.Y.Z(-rcN) update-ipfs-blog --date YYYY-MM-DD` or ... + - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) create a PR which adds a release note for the new Kubo version + - [example](https://github.com/ipfs/ipfs-blog/pull/529) + - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) merge the PR + - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) verify the blog entry was published +
+- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Merge the [release](https://github.com/ipfs/kubo/tree/release) branch back into [master](https://github.com/ipfs/kubo/tree/master), ignoring the changes to [version.go](version.go) (keep the `-dev`) version,
using `./kuboreleaser release --version vX.Y.Z(-rcN) merge-branch` or ... + - [ ] create a new branch `merge-release-vX.Y.Z` from `release` + - [ ] create and merge a PR from `merge-release-vX.Y.Z` to `master` +
+- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) Prepare for the next release
using `./kuboreleaser release --version vX.Y.Z(-rcN) prepare-next` or ... + - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) Create the next [changelog](https://github.com/ipfs/kubo/blob/master/docs/changelogs/vX.(Y+1).md) + - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) Link to the new changelog in the [CHANGELOG.md](CHANGELOG.md) file + - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) Create the next release issue +
+- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) Create a dependency update PR + - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) check out [ipfs/kubo](https://github.com/ipfs/kubo) + - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) run `go get -u` in root directory + - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) run `go mod tidy` in root directory + - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) run `go mod tidy` in `docs/examples/kubo-as-a-library` directory + - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) create a PR which updates `go.mod` and `go.sum` + - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) add the PR to the next release milestone +- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Close the release issue diff --git a/docs/RELEASE_ISSUE_TEMPLATE.md b/docs/RELEASE_ISSUE_TEMPLATE.md index 26e5ad5be..61c7ee095 100644 --- a/docs/RELEASE_ISSUE_TEMPLATE.md +++ b/docs/RELEASE_ISSUE_TEMPLATE.md @@ -1,222 +1,35 @@ - + # Items to do upon creating the release issue + - [ ] Fill in the Meta section - [ ] Assign the issue to the release owner and reviewer. - [ ] Name the issue "Release vX.Y.Z" - [ ] Set the proper values for X.Y.Z - [ ] Pin the issue + + # Meta + * Release owner: @who * Release reviewer: @who * Expected RC date: week of YYYY-MM-DD * 🚢 Expected final release date: YYYY-MM-DD -* Accompanying PR for improving the release process: (example: https://github.com/ipfs/kubo/pull/9391) +* Release PR: +* Accompanying PR for improving the release process: ([example](https://github.com/ipfs/kubo/pull/9391)) -See the [Kubo release process](https://pl-strflt.notion.site/Kubo-Release-Process-5a5d066264704009a28a79cff93062c4) for more info. +# Items In Scope -# Kubo X.Y.Z Release +## Required -We're happy to announce Kubo X.Y.Z! + -As usual, this release includes important fixes, some of which may be critical for security. Unless the fix addresses a bug being exploited in the wild, the fix will _not_ be called out in the release notes. Please make sure to update ASAP. See our [security fix policy](https://github.com/ipfs/go-ipfs/tree/master/docs/releases.md#security-fix-policy) for details. +## Nice To Have (Optional) -## 🗺 What's left for release - - - -### Required - -### Nice to have - -## 🔦 Highlights - -< top highlights for this release notes. For ANY version (final or RCs) > - -## ✅ Release Checklist - -### Labels - -If an item should be executed for a specific release type, it should be labeled with one of the following labels: - -- ![](https://img.shields.io/badge/only-RC-blue?style=flat-square) execute **ONLY** when releasing a Release Candidate -- ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) execute **ONLY** when releasing a Final Release - -Otherwise, it means it should be executed for **ALL** release types. - -Patch releases should follow the same process as `.0` releases. If some item should **NOT** be executed for a Patch Release, it should be labeled with: - -- ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) do **NOT** execute when releasing a Patch Release - -### Before the release - -This section covers tasks to be done ahead of the release. - -- [ ] Verify you have access to all the services and tools required for the release - - [ ] [GPG signature](https://docs.github.com/en/authentication/managing-commit-signature-verification) configured in local git and in GitHub - - [ ] [admin access to IPFS Discourse](https://discuss.ipfs.tech/g/admins) - - ask the previous release owner (or @2color) for an invite - - [ ] ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) [access to #shared-pl-marketing-requests](https://filecoinproject.slack.com/archives/C018EJ8LWH1) channel in FIL Slack - - ask the previous release owner for an invite - - [ ] [access to IPFS network metrics](https://github.com/protocol/pldw/blob/624f47cf4ec14ad2cec6adf601a9f7b203ef770d/docs/sources/ipfs.md#ipfs-network-metrics) dashboards in Grafana - - open an access request in the [pldw](https://github.com/protocol/pldw/issues/new/choose) - - [example](https://github.com/protocol/pldw/issues/158) - - [ ] [kuboreleaser](https://github.com/ipfs/kuboreleaser) checked out on your system (_only if you're using [kuboreleaser](https://github.com/ipfs/kuboreleaser)_) - - [ ] [Thunderdome](https://github.com/ipfs-shipyard/thunderdome) checked out on your system and configured (see the [Thunderdome release docs](./releases_thunderdome.md) for setup) - - [ ] [docker](https://docs.docker.com/get-docker/) installed on your system (_only if you're using [kuboreleaser](https://github.com/ipfs/kuboreleaser)_) - - [ ] [npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) installed on your system (_only if you're **NOT** using [kuboreleaser](https://github.com/ipfs/kuboreleaser)_) - - [ ] [zsh](https://github.com/ohmyzsh/ohmyzsh/wiki/Installing-ZSH#install-and-set-up-zsh-as-default) installed on your system - - [ ] [kubo](https://github.com/ipfs/kubo) checked out under `$(go env GOPATH)/src/github.com/ipfs/kubo` - - you can also symlink your clone to the expected location by running `mkdir -p $(go env GOPATH)/src/github.com/ipfs && ln -s $(pwd) $(go env GOPATH)/src/github.com/ipfs/kubo` - - [ ] ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) [Reddit](https://www.reddit.com) account -- ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) Upgrade Go used in CI to the latest patch release available in [CircleCI](https://hub.docker.com/r/cimg/go/tags) in: - - [ ] ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) [ipfs/distributions](https://github.com/ipfs/distributions) - - [example](https://github.com/ipfs/distributions/pull/756) - - [ ] ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) [ipfs/ipfs-docs](https://github.com/ipfs/ipfs-docs) - - [example](https://github.com/ipfs/ipfs-docs/pull/1298) -- [ ] Verify there is nothing [left for release](-what-s-left-for-release) -- [ ] Create a release process improvement PR - - [ ] update the [release issue template](docs/RELEASE_ISSUE_TEMPLATE.md) as you go - - [ ] link it in the [Meta](#meta) section - -### The release - -This section covers tasks to be done during each release. - -- [ ] Prepare the release branch and update version numbers accordingly
using `./kuboreleaser --skip-check-before release --version vX.Y.Z(-rcN) prepare-branch` or ... - - [ ] create a new branch `release-vX.Y.Z` - - use `master` as base if `Z == 0` - - use `release` as base if `Z > 0` - - [ ] ![](https://img.shields.io/badge/only-RC-blue?style=flat-square) update the `CurrentVersionNumber` in [version.go](version.go) in the `master` branch to `vX.Y+1.0-dev` - - [example](https://github.com/ipfs/kubo/pull/9305) - - [ ] update the `CurrentVersionNumber` in [version.go](version.go) in the `release-vX.Y` branch to `vX.Y.Z(-RCN)` - - [example](https://github.com/ipfs/kubo/pull/9394) - - [ ] create a draft PR from `release-vX.Y` to `release` - - [example](https://github.com/ipfs/kubo/pull/9306) - - [ ] Cherry-pick commits from `master` to the `release-vX.Y.Z` using `git cherry-pick -x ` - - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Add full changelog and contributors to the [changelog](docs/changelogs/vX.Y.md) - - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Replace the `Changelog` and `Contributors` sections of the [changelog](docs/changelogs/vX.Y.md) with the stdout of `./bin/mkreleaselog` - - do **NOT** copy the stderr - - [ ] verify all CI checks on the PR from `release-vX.Y` to `release` are passing - - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Merge the PR from `release-vX.Y` to `release` using the `Create a merge commit` - - do **NOT** use `Squash and merge` nor `Rebase and merge` because we need to be able to sign the merge commit - - do **NOT** delete the `release-vX.Y` branch -
-- [ ] Run Thunderdome testing, see the [Thunderdome release docs](./releases_thunderdome.md) for details - - [ ] create a PR and merge the experiment config into Thunderdome -- [ ] Create the release tag
using `./kuboreleaser release --version vX.Y.Z(-rcN) tag` or ... - - This is a dangerous operation! Go and Docker publishing are difficult to reverse! Have the release reviewer verify all the commands marked with ⚠️! - - [ ] ⚠️ ![](https://img.shields.io/badge/only-RC-blue?style=flat-square) tag the HEAD commit using `git tag -s vX.Y.Z(-RCN) -m 'Prerelease X.Y.Z(-RCN)'` - - [ ] ⚠️ ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) tag the HEAD commit of the `release` branch using `git tag -s vX.Y.Z(-RCN) -m 'Release X.Y.Z(-RCN)'` - - [ ] ⚠️ verify the tag is signed and tied to the correct commit using `git show vX.Y.Z(-RCN)` - - [ ] ⚠️ push the tag to GitHub using `git push origin vX.Y.Z(-RCN)` - - do **NOT** use `git push --tags` because it pushes all your local tags -
-- [ ] Publish the release to [DockerHub](https://hub.docker.com/r/ipfs/kubo/)
using `./kuboreleaser --skip-check-before --skip-run release --version vX.Y.Z(-rcN) publish-to-dockerhub` or ... - - [ ] Wait for [Publish docker image](https://github.com/ipfs/kubo/actions/workflows/docker-image.yml) workflow run initiated by the tag push to finish - - [ ] verify the image is available on [Docker Hub](https://hub.docker.com/r/ipfs/kubo/tags) -- [ ] Verify [ipfs/distributions](https://github.com/ipfs/distributions)'s `.tool-versions`'s `golang` entry is set to the [latest go release](https://go.dev/doc/devel/release) on the major go branch [Kubo is being tested on](https://github.com/ipfs/kubo/blob/master/.github/workflows/gotest.yml) (see `go-version:`). -- [ ] Publish the release to [dist.ipfs.tech](https://dist.ipfs.tech)
using `./kuboreleaser release --version vX.Y.Z(-rcN) publish-to-distributions` or ... - - [ ] check out [ipfs/distributions](https://github.com/ipfs/distributions) - - [ ] run `./dist.sh add-version kubo vX.Y.Z(-RCN)` to add the new version to the `versions` file - - [usage](https://github.com/ipfs/distributions#usage) - - [ ] create and merge the PR which updates `dists/kubo/versions` and `dists/go-ipfs/versions` (![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) and `dists/kubo/current_version` and `dists/go-ipfs/current_version`) - - [example](https://github.com/ipfs/distributions/pull/760) - - [ ] wait for the [CI](https://github.com/ipfs/distributions/actions/workflows/main.yml) workflow run initiated by the merge to master to finish - - [ ] verify the release is available on [dist.ipfs.io](https://dist.ipfs.io/#kubo) -
-- [ ] Publish the release to [NPM](https://www.npmjs.com/package/go-ipfs?activeTab=versions)
using `./kuboreleaser release --version vX.Y.Z(-rcN) publish-to-npm` (⚠️ you might need to run the command a couple of times because GHA might not be able to see the new distribution straight away due to caching) or ... - - [ ] run the [Release to npm](https://github.com/ipfs/npm-go-ipfs/actions/workflows/main.yml) workflow - - [ ] check [Release to npm](https://github.com/ipfs/npm-go-ipfs/actions/workflows/main.yml) workflow run logs to verify it discovered the new release - - [ ] verify the release is available on [NPM](https://www.npmjs.com/package/go-ipfs?activeTab=versions) -
-- [ ] Publish the release to [GitHub](https://github.com/ipfs/kubo/releases)
using `./kuboreleaser release --version vX.Y.Z(-rcN) publish-to-github` or ... - - [ ] create a new release on [GitHub](https://docs.github.com/en/repositories/releasing-projects-on-github/managing-releases-in-a-repository#creating-a-release) - - [RC example](https://github.com/ipfs/kubo/releases/tag/v0.17.0-rc1) - - [FINAL example](https://github.com/ipfs/kubo/releases/tag/v0.17.0) - - [ ] use the `vX.Y.Z(-RCN)` tag - - [ ] link to the release issue - - [ ] ![](https://img.shields.io/badge/only-RC-blue?style=flat-square) link to the changelog in the description - - [ ] ![](https://img.shields.io/badge/only-RC-blue?style=flat-square) check the `This is a pre-release` checkbox - - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) copy the changelog (without the header) in the description - - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) do **NOT** check the `This is a pre-release` checkbox - - [ ] run the [sync-release-assets](https://github.com/ipfs/kubo/actions/workflows/sync-release-assets.yml) workflow - - [ ] wait for the [sync-release-assets](https://github.com/ipfs/kubo/actions/workflows/sync-release-assets.yml) workflow run to finish - - [ ] verify the release assets are present in the [GitHub release](https://github.com/ipfs/kubo/releases/tag/vX.Y.Z(-RCN)) -
-- [ ] Promote the release
using `./kuboreleaser release --version vX.Y.Z(-rcN) promote` or ... - - [ ] create an [IPFS Discourse](https://discuss.ipfs.tech) topic - - [prerelease example](https://discuss.ipfs.tech/t/kubo-v0-16-0-rc1-release-candidate-is-out/15248) - - [release example](https://discuss.ipfs.tech/t/kubo-v0-16-0-release-is-out/15249) - - [ ] use `Kubo vX.Y.Z(-RCN) is out!` as the title - - [ ] use `kubo` and `go-ipfs` as topics - - [ ] repeat the title as a heading (`##`) in the description - - [ ] link to the GitHub Release, binaries on IPNS, docker pull command and release notes in the description - - [ ] pin the [IPFS Discourse](https://discuss.ipfs.tech) topic globally - - you can make the topic a banner if there is no banner already - - verify the [IPFS Discourse](https://discuss.ipfs.tech) topic was copied to: - - [ ] [#ipfs-chatter](https://discord.com/channels/669268347736686612/669268347736686615) in IPFS Discord - - [ ] [#ipfs-chatter](https://filecoinproject.slack.com/archives/C018EJ8LWH1) in FIL Slack - - [ ] [#ipfs-chatter:ipfs.io](https://matrix.to/#/#ipfs-chatter:ipfs.io) in Matrix - - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Add the link to the [IPFS Discourse](https://discuss.ipfs.tech) topic to the [GitHub Release](https://github.com/ipfs/kubo/releases/tag/vX.Y.Z(-RCN)) description - - [example](https://github.com/ipfs/kubo/releases/tag/v0.17.0) - - [ ] ![](https://img.shields.io/badge/only-RC-blue?style=flat-square) create an issue comment mentioning early testers on the release issue - - [example](https://github.com/ipfs/kubo/issues/9319#issuecomment-1311002478) - - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) create an issue comment linking to the release on the release issue - - [example](https://github.com/ipfs/kubo/issues/9417#issuecomment-1400740975) - - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) ask the marketing team to tweet about the release in [#shared-pl-marketing-requests](https://filecoinproject.slack.com/archives/C018EJ8LWH1) in FIL Slack - - [example](https://filecoinproject.slack.com/archives/C018EJ8LWH1/p1664885305374900) - - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) post the link to the [GitHub Release](https://github.com/ipfs/kubo/releases/tag/vX.Y.Z(-RCN)) to [Reddit](https://reddit.com/r/ipfs) - - [example](https://www.reddit.com/r/ipfs/comments/9x0q0k/kubo_v0160_release_is_out/) -
-- [ ] Test the new version with `ipfs-companion`
using `./kuboreleaser release --version vX.Y.Z(-rcN) test-ipfs-companion` or ... - - [ ] run the [e2e](https://github.com/ipfs/ipfs-companion/actions/workflows/e2e.yml) - - use `vX.Y.Z(-RCN)` as the Kubo image version - - [ ] wait for the [e2e](https://github.com/ipfs/ipfs-companion/actions/workflows/e2e.yml) workflow run to finish -
-- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Update Kubo in [ipfs-desktop](https://github.com/ipfs/ipfs-desktop)
using `./kuboreleaser release --version vX.Y.Z(-rcN) update-ipfs-desktop` or ... - - [ ] check out [ipfs/ipfs-desktop](https://github.com/ipfs/ipfs-desktop) - - [ ] run `npm install` - - [ ] create a PR which updates `package.json` and `package-lock.json` - - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) add @SgtPooki and @whizzzkid as reviewers -
-- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Update Kubo docs
using `./kuboreleaser release --version vX.Y.Z(-rcN) update-ipfs-docs` or ... - - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) run the [update-on-new-ipfs-tag.yml](https://github.com/ipfs/ipfs-docs/actions/workflows/update-on-new-ipfs-tag.yml) workflow - - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) merge the PR created by the [update-on-new-ipfs-tag.yml](https://github.com/ipfs/ipfs-docs/actions/workflows/update-on-new-ipfs-tag.yml) workflow run -
-- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Ask Brave to update Kubo in Brave Desktop - - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) use [this link](https://github.com/brave/brave-browser/issues/new?assignees=&labels=OS%2FDesktop&projects=&template=desktop.md&title=) to create an issue for the new Kubo version - - [basic example](https://github.com/brave/brave-browser/issues/31453), [example with additional notes](https://github.com/brave/brave-browser/issues/27965) - - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) post link to the issue in `#shared-pl-brave` for visibility -- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Create a blog entry on [blog.ipfs.tech](https://blog.ipfs.tech)
using `./kuboreleaser release --version vX.Y.Z(-rcN) update-ipfs-blog --date YYYY-MM-DD` or ... - - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) create a PR which adds a release note for the new Kubo version - - [example](https://github.com/ipfs/ipfs-blog/pull/529) - - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) merge the PR - - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) verify the blog entry was published -
-- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Merge the [release](https://github.com/ipfs/kubo/tree/release) branch back into [master](https://github.com/ipfs/kubo/tree/master), ignoring the changes to [version.go](version.go) (keep the `-dev`) version,
using `./kuboreleaser release --version vX.Y.Z(-rcN) merge-branch` or ... - - [ ] create a new branch `merge-release-vX.Y.Z` from `release` - - [ ] create and merge a PR from `merge-release-vX.Y.Z` to `master` -
-- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) Prepare for the next release
using `./kuboreleaser release --version vX.Y.Z(-rcN) prepare-next` or ... - - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) Create the next [changelog](https://github.com/ipfs/kubo/blob/master/docs/changelogs/vX.(Y+1).md) - - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) Link to the new changelog in the [CHANGELOG.md](CHANGELOG.md) file - - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) Create the next release issue -
-- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) Create a dependency update PR - - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) check out [ipfs/kubo](https://github.com/ipfs/kubo) - - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) run `go get -u` in root directory - - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) run `go mod tidy` in root directory - - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) run `go mod tidy` in `docs/examples/kubo-as-a-library` directory - - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) create a PR which updates `go.mod` and `go.sum` - - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) add the PR to the next release milestone -- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Close the release issue - -## How to contribute? - -Would you like to contribute to the IPFS project and don't know how? Well, there are a few places you can get started: - -- Check the issues with the `help wanted` label in the [ipfs/kubo repo](https://github.com/ipfs/kubo/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22) -- Join the discussion at [discuss.ipfs.tech](https://discuss.ipfs.tech/) and help users finding their answers. -- See other options at https://docs.ipfs.tech/community/ + From c0d7da22a204869222af11c5981a92362829f548 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Wed, 17 Jan 2024 15:59:02 +0100 Subject: [PATCH 1005/1212] docs(cli): name inspect --verify (#10308) Co-authored-by: Daniel Norman <1992255+2color@users.noreply.github.com> --- core/commands/name/name.go | 2 +- test/cli/name_test.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/core/commands/name/name.go b/core/commands/name/name.go index 37ab4df53..9445fc362 100644 --- a/core/commands/name/name.go +++ b/core/commands/name/name.go @@ -245,7 +245,7 @@ Passing --verify will verify signature against provided public key. if out.Validation == nil { tw.Flush() - fmt.Fprintf(w, "\nThis record was not validated.\n") + fmt.Fprintf(w, "\nThis record was not verified. Pass '--verify k51...' to verify.\n") } else { tw.Flush() fmt.Fprintf(w, "\nValidation results:\n") diff --git a/test/cli/name_test.go b/test/cli/name_test.go index e0f2f0909..42c649c09 100644 --- a/test/cli/name_test.go +++ b/test/cli/name_test.go @@ -172,7 +172,7 @@ func TestName(t *testing.T) { res = node.PipeToIPFS(bytes.NewReader(record), "name", "inspect") out := res.Stdout.String() - require.Contains(t, out, "This record was not validated.") + require.Contains(t, out, "This record was not verified.") require.Contains(t, out, publishPath) require.Contains(t, out, "30m") @@ -198,7 +198,7 @@ func TestName(t *testing.T) { t.Parallel() res = node.PipeToIPFS(bytes.NewReader(record), "name", "inspect") out := res.Stdout.String() - require.Contains(t, out, "This record was not validated.") + require.Contains(t, out, "This record was not verified.") require.Contains(t, out, publishPath) require.Contains(t, out, "30m") require.Contains(t, out, "Signature Type: V1+V2") From 4790618a292b5d2c7b6ad788929484a07b48b767 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Thu, 18 Jan 2024 17:26:54 +0100 Subject: [PATCH 1006/1212] chore: remove Gateway.APICommands Remove unused and undocumented gateway configuration field introduced in go-ipfs v0.4 --- config/gateway.go | 3 --- config/init.go | 1 - 2 files changed, 4 deletions(-) diff --git a/config/gateway.go b/config/gateway.go index 9c0830c50..0ed07d7cd 100644 --- a/config/gateway.go +++ b/config/gateway.go @@ -53,9 +53,6 @@ type Gateway struct { // PathPrefixes was removed: https://github.com/ipfs/go-ipfs/issues/7702 PathPrefixes []string - // FIXME: Not yet implemented: https://github.com/ipfs/kubo/issues/8059 - APICommands []string - // NoFetch configures the gateway to _not_ fetch blocks in response to // requests. NoFetch bool diff --git a/config/init.go b/config/init.go index e4cb1e95a..13d3b9b19 100644 --- a/config/init.go +++ b/config/init.go @@ -68,7 +68,6 @@ func InitWithIdentity(identity Identity) (*Config, error) { NoFetch: false, PathPrefixes: []string{}, HTTPHeaders: map[string][]string{}, - APICommands: []string{}, }, Reprovider: Reprovider{ Interval: nil, From 7e805227867a8e1df0fddd79cacb135ef0e175a1 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Mon, 22 Jan 2024 14:35:46 +0100 Subject: [PATCH 1007/1212] chore: update changelog --- docs/changelogs/v0.26.md | 78 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 77 insertions(+), 1 deletion(-) diff --git a/docs/changelogs/v0.26.md b/docs/changelogs/v0.26.md index 2888483b8..bb38a6849 100644 --- a/docs/changelogs/v0.26.md +++ b/docs/changelogs/v0.26.md @@ -43,6 +43,82 @@ See the [boxo tracing docs](https://github.com/ipfs/boxo/blob/a391d02102875ee707 ### 📝 Changelog -- Export a `kubo.Start` function so users can programmatically start Kubo from within a go program. +
Full Changelog + +- github.com/ipfs/kubo: + - chore: update version + - chore: update version + - feat(pinning): allow for overwriting pin name + - chore: update otlp + - Revert "build,docker: add support for riscv64" + - feat: support optional pin names (#10261) ([ipfs/kubo#10261](https://github.com/ipfs/kubo/pull/10261)) + - build,docker: add support for riscv64 + - feat(cmd/ipfs): Make it possible to depend on cmd/ipfs/kubo for easier preloaded plugin management ([ipfs/kubo#10219](https://github.com/ipfs/kubo/pull/10219)) + - docs: fix broken link in HTTP RPC client doc (#10267) ([ipfs/kubo#10267](https://github.com/ipfs/kubo/pull/10267)) + - Merge Release: v0.25.0 [skip changelog] ([ipfs/kubo#10260](https://github.com/ipfs/kubo/pull/10260)) + - docs: add detail to NOpfs instructions in content-blocking.md + - commands: remove several deprecated commands + - fix: allow daemon to start correctly if the API is null (#10062) ([ipfs/kubo#10062](https://github.com/ipfs/kubo/pull/10062)) + - chore: update version +- github.com/ipfs/boxo (v0.16.0 -> v0.17.0): + - Release v0.17.0 ([ipfs/boxo#542](https://github.com/ipfs/boxo/pull/542)) +- github.com/ipfs/go-ipld-cbor (v0.0.6 -> v0.1.0): + - v0.1.0 bump + - chore: add or force update version.json + - allow configuration of ipldStores default hash function ([ipfs/go-ipld-cbor#86](https://github.com/ipfs/go-ipld-cbor/pull/86)) + - sync: update CI config files (#85) ([ipfs/go-ipld-cbor#85](https://github.com/ipfs/go-ipld-cbor/pull/85)) +- github.com/ipfs/go-unixfsnode (v1.8.1 -> v1.9.0): + - v1.9.0 bump + - feat: expose ToDirEntryFrom to allow sub-dag representation + - feat: new UnixFS{File,Directory} with options pattern + - feat: testutil generator enhancements +- github.com/ipld/go-car/v2 (v2.10.2-0.20230622090957-499d0c909d33 -> v2.13.1): + - fix: BlockMetadata#Offset should be for section, not block data + - fix: add closed check, expose storage.ErrClosed + - fix: switch constructor args to match storage.New*, make roots plural + - feat: add DeferredCarWriter + - feat: fix BlockReader#SkipNext & add SourceOffset property + - v0.6.2 ([ipld/go-car#464](https://github.com/ipld/go-car/pull/464)) + - fix: opt-in way to allow empty list of roots in CAR headers ([ipld/go-car#461](https://github.com/ipld/go-car/pull/461)) +- github.com/libp2p/go-libp2p-asn-util (v0.3.0 -> v0.4.1): + - chore: release v0.4.1 + - fix: add Init method on backward compat + - chore: release v0.4.0 + - rewrite representation to a sorted binary list and embed it + - docs: fix incorrect markdown === in README + - ci: run go generate on CI (#27) ([libp2p/go-libp2p-asn-util#27](https://github.com/libp2p/go-libp2p-asn-util/pull/27)) +- github.com/multiformats/go-multiaddr (v0.12.0 -> v0.12.1): + - v0.12.1 bump + - manet: reduce allocations in resolve unspecified address +- github.com/whyrusleeping/cbor-gen (v0.0.0-20230126041949-52956bd4c9aa -> v0.0.0-20240109153615-66e95c3e8a87): + - Add a feature to preserve nil slices (#88) ([whyrusleeping/cbor-gen#88](https://github.com/whyrusleeping/cbor-gen/pull/88)) + - some cleanup for easier reading ([whyrusleeping/cbor-gen#89](https://github.com/whyrusleeping/cbor-gen/pull/89)) + - Support gen for map with value type `string` (#83) ([whyrusleeping/cbor-gen#83](https://github.com/whyrusleeping/cbor-gen/pull/83)) + - feat: add support for pointers to CIDs in slices (#86) ([whyrusleeping/cbor-gen#86](https://github.com/whyrusleeping/cbor-gen/pull/86)) + - optimize anything using WriteString ([whyrusleeping/cbor-gen#85](https://github.com/whyrusleeping/cbor-gen/pull/85)) + - Implement *bool support and support omitempty for slices ([whyrusleeping/cbor-gen#81](https://github.com/whyrusleeping/cbor-gen/pull/81)) + +
### 👨‍👩‍👧‍👦 Contributors + +| Contributor | Commits | Lines ± | Files Changed | +|-------------|---------|---------|---------------| +| Henrique Dias | 11 | +493/-1184 | 48 | +| Łukasz Magiera | 3 | +610/-582 | 16 | +| Rod Vagg | 11 | +1030/-151 | 18 | +| whyrusleeping | 6 | +553/-388 | 14 | +| Jorropo | 13 | +561/-348 | 84 | +| Jeromy Johnson | 1 | +771/-48 | 6 | +| Steven Allen | 2 | +264/-135 | 4 | +| Forrest | 1 | +214/-0 | 5 | +| Marcin Rataj | 1 | +89/-24 | 2 | +| sukun | 1 | +31/-11 | 5 | +| Will Scott | 3 | +25/-10 | 3 | +| Adin Schmahmann | 3 | +21/-5 | 3 | +| web3-bot | 2 | +8/-8 | 3 | +| Marten Seemann | 1 | +13/-1 | 1 | +| Bumblefudge | 1 | +5/-2 | 1 | +| Will | 1 | +1/-1 | 1 | +| Nicholas Ericksen | 1 | +1/-1 | 1 | +| 0xbasar | 1 | +1/-1 | 1 | From dfec50d5f7ffa1f3302f0e4046af6fb3892a5668 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Mon, 22 Jan 2024 13:30:24 +0000 Subject: [PATCH 1008/1212] chore: update version --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index d97435b0b..6a9cae7c1 100644 --- a/version.go +++ b/version.go @@ -11,7 +11,7 @@ import ( var CurrentCommit string // CurrentVersionNumber is the current application's version literal. -const CurrentVersionNumber = "0.26.0-rc1" +const CurrentVersionNumber = "0.26.0" const ApiVersion = "/kubo/" + CurrentVersionNumber + "/" //nolint From d1db95c447490d3e4ec56416a3718d8917f02b81 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Fri, 19 Jan 2024 11:20:28 +0100 Subject: [PATCH 1009/1212] config: remove all options that are marked as REMOVED Most of the removed options are many years old. In addition, they've all been removed in past iterations of Kubo. Some options were marked as removed in the config.md, but we still had a warning in the code to let users know they have been removed. I think it's been long enough for all of this options, and enough Kubo iterations in order to alert the users. It is good to keep it in the config.md for now so that people can actually check. However, I think it's time to remove them from the code itself. --- cmd/ipfs/kubo/daemon.go | 15 --------------- config/discovery.go | 4 ---- config/gateway.go | 6 ------ config/init.go | 1 - config/swarm.go | 24 ------------------------ core/node/groups.go | 18 ------------------ core/node/libp2p/sec.go | 9 --------- core/node/libp2p/smux.go | 3 --- docs/config.md | 2 +- 9 files changed, 1 insertion(+), 81 deletions(-) diff --git a/cmd/ipfs/kubo/daemon.go b/cmd/ipfs/kubo/daemon.go index 31e5fe28d..ae755648e 100644 --- a/cmd/ipfs/kubo/daemon.go +++ b/cmd/ipfs/kubo/daemon.go @@ -68,7 +68,6 @@ const ( routingOptionAutoClientKwd = "autoclient" unencryptTransportKwd = "disable-transport-encryption" unrestrictedAPIAccessKwd = "unrestricted-api" - writableKwd = "writable" enablePubSubKwd = "enable-pubsub-experiment" enableIPNSPubSubKwd = "enable-namesys-pubsub" enableMultiplexKwd = "enable-mplex-experiment" @@ -164,7 +163,6 @@ Headers. cmds.StringOption(initProfileOptionKwd, "Configuration profiles to apply for --init. See ipfs init --help for more"), cmds.StringOption(routingOptionKwd, "Overrides the routing option").WithDefault(routingOptionDefaultKwd), cmds.BoolOption(mountKwd, "Mounts IPFS to the filesystem using FUSE (experimental)"), - cmds.BoolOption(writableKwd, "Enable legacy Gateway.Writable (REMOVED)"), cmds.StringOption(ipfsMountKwd, "Path to the mountpoint for IPFS (if using --mount). Defaults to config setting."), cmds.StringOption(ipnsMountKwd, "Path to the mountpoint for IPNS (if using --mount). Defaults to config setting."), cmds.BoolOption(unrestrictedAPIAccessKwd, "Allow API access to unlisted hashes"), @@ -803,15 +801,6 @@ func serveHTTPGateway(req *cmds.Request, cctx *oldcmds.Context) (<-chan error, e return nil, fmt.Errorf("serveHTTPGateway: GetConfig() failed: %s", err) } - writable, writableOptionFound := req.Options[writableKwd].(bool) - if !writableOptionFound { - writable = cfg.Gateway.Writable.WithDefault(false) - } - - if writable { - log.Fatalf("Support for Gateway.Writable and --writable has been REMOVED. Please remove it from your config file or CLI. Modern replacement tracked in https://github.com/ipfs/specs/issues/375") - } - listeners, err := sockets.TakeListeners("io.ipfs.gateway") if err != nil { return nil, fmt.Errorf("serveHTTPGateway: socket activation failed: %s", err) @@ -876,10 +865,6 @@ func serveHTTPGateway(req *cmds.Request, cctx *oldcmds.Context) (<-chan error, e opts = append(opts, corehttp.RedirectOption("", cfg.Gateway.RootRedirect)) } - if len(cfg.Gateway.PathPrefixes) > 0 { - log.Fatal("Support for custom Gateway.PathPrefixes was removed: https://github.com/ipfs/go-ipfs/issues/7702") - } - node, err := cctx.ConstructNode() if err != nil { return nil, fmt.Errorf("serveHTTPGateway: ConstructNode() failed: %s", err) diff --git a/config/discovery.go b/config/discovery.go index 274ae051c..4ddc3a82f 100644 --- a/config/discovery.go +++ b/config/discovery.go @@ -6,8 +6,4 @@ type Discovery struct { type MDNS struct { Enabled bool - - // DEPRECATED: the time between discovery rounds is no longer configurable - // See: https://github.com/ipfs/go-ipfs/pull/9048#discussion_r906814717 - Interval *OptionalInteger `json:",omitempty"` } diff --git a/config/gateway.go b/config/gateway.go index 0ed07d7cd..fa093245d 100644 --- a/config/gateway.go +++ b/config/gateway.go @@ -47,12 +47,6 @@ type Gateway struct { // should be redirected. RootRedirect string - // REMOVED: modern replacement tracked in https://github.com/ipfs/specs/issues/375 - Writable Flag `json:",omitempty"` - - // PathPrefixes was removed: https://github.com/ipfs/go-ipfs/issues/7702 - PathPrefixes []string - // NoFetch configures the gateway to _not_ fetch blocks in response to // requests. NoFetch bool diff --git a/config/init.go b/config/init.go index 13d3b9b19..e3d0af30d 100644 --- a/config/init.go +++ b/config/init.go @@ -66,7 +66,6 @@ func InitWithIdentity(identity Identity) (*Config, error) { Gateway: Gateway{ RootRedirect: "", NoFetch: false, - PathPrefixes: []string{}, HTTPHeaders: map[string][]string{}, }, Reprovider: Reprovider{ diff --git a/config/swarm.go b/config/swarm.go index 16c52b4a5..f15634b57 100644 --- a/config/swarm.go +++ b/config/swarm.go @@ -13,26 +13,6 @@ type SwarmConfig struct { // DisableNatPortMap turns off NAT port mapping (UPnP, etc.). DisableNatPortMap bool - // DisableRelay explicitly disables the relay transport. - // - // Deprecated: This flag is deprecated and is overridden by - // `Swarm.Transports.Relay` if specified. - DisableRelay bool `json:",omitempty"` - - // EnableRelayHop makes this node act as a public relay v1 - // - // Deprecated: The circuit v1 protocol is deprecated. - // Use `Swarm.RelayService` to configure the circuit v2 relay. - EnableRelayHop bool `json:",omitempty"` - - // EnableAutoRelay enables the "auto relay user" feature. - // Node will find and use advertised public relays when it determines that - // it's not reachable from the public internet. - // - // Deprecated: This flag is deprecated and is overridden by - // `Swarm.RelayClient.Enabled` if specified. - EnableAutoRelay bool `json:",omitempty"` - // RelayClient controls the client side of "auto relay" feature. // When enabled, the node will use relays if it is not publicly reachable. RelayClient RelayClient @@ -112,8 +92,6 @@ type Transports struct { Security struct { // Defaults to 100. TLS Priority `json:",omitempty"` - // Defaults to 200. - SECIO Priority `json:",omitempty"` // Defaults to 300. Noise Priority `json:",omitempty"` } @@ -123,8 +101,6 @@ type Transports struct { Multiplexers struct { // Defaults to 100. Yamux Priority `json:",omitempty"` - // Defaults to -1. - Mplex Priority `json:",omitempty"` } } diff --git a/core/node/groups.go b/core/node/groups.go index e1e2e4b9c..4572a2ddd 100644 --- a/core/node/groups.go +++ b/core/node/groups.go @@ -122,24 +122,6 @@ func LibP2P(bcfg *BuildCfg, cfg *config.Config, userResourceOverrides rcmgr.Part } } - // Force users to migrate old config. - // nolint - if cfg.Swarm.DisableRelay { - logger.Fatal("The 'Swarm.DisableRelay' config field was removed." + - "Use the 'Swarm.Transports.Network.Relay' instead.") - } - // nolint - if cfg.Swarm.EnableAutoRelay { - logger.Fatal("The 'Swarm.EnableAutoRelay' config field was removed." + - "Use the 'Swarm.RelayClient.Enabled' instead.") - } - // nolint - if cfg.Swarm.EnableRelayHop { - logger.Fatal("The `Swarm.EnableRelayHop` config field was removed.\n" + - "Use `Swarm.RelayService` to configure the circuit v2 relay.\n" + - "If you want to continue running a circuit v1 relay, please use the standalone relay daemon: https://dist.ipfs.tech/#libp2p-relay-daemon (with RelayV1.Enabled: true)") - } - // Gather all the options opts := fx.Options( BaseLibP2P, diff --git a/core/node/libp2p/sec.go b/core/node/libp2p/sec.go index 820ba22d6..0dc6940d8 100644 --- a/core/node/libp2p/sec.go +++ b/core/node/libp2p/sec.go @@ -8,11 +8,6 @@ import ( tls "github.com/libp2p/go-libp2p/p2p/security/tls" ) -const secioEnabledWarning = `The SECIO security transport was enabled in the config but is no longer supported. - -SECIO disabled by default in go-ipfs 0.7 removed in go-ipfs 0.9. Please remove -Swarm.Transports.Security.SECIO from your IPFS config.` - func Security(enabled bool, tptConfig config.Transports) interface{} { if !enabled { return func() (opts Libp2pOpts) { @@ -23,10 +18,6 @@ func Security(enabled bool, tptConfig config.Transports) interface{} { } } - if _, enabled := tptConfig.Security.SECIO.WithDefault(config.Disabled); enabled { - log.Error(secioEnabledWarning) - } - // Using the new config options. return func() (opts Libp2pOpts) { opts.Opts = append(opts.Opts, prioritizeOptions([]priorityOption{{ diff --git a/core/node/libp2p/smux.go b/core/node/libp2p/smux.go index a276b5ddc..d52b306d8 100644 --- a/core/node/libp2p/smux.go +++ b/core/node/libp2p/smux.go @@ -14,9 +14,6 @@ func makeSmuxTransportOption(tptConfig config.Transports) (libp2p.Option, error) if prefs := os.Getenv("LIBP2P_MUX_PREFS"); prefs != "" { return nil, fmt.Errorf("configuring muxers with LIBP2P_MUX_PREFS is no longer supported, use Swarm.Transports.Multiplexers") } - if tptConfig.Multiplexers.Mplex != 0 { - return nil, fmt.Errorf("Swarm.Transports.Multiplexers.Mplex is no longer supported, remove it from your config, see https://github.com/libp2p/specs/issues/553") - } if tptConfig.Multiplexers.Yamux < 0 { return nil, fmt.Errorf("running libp2p with Swarm.Transports.Multiplexers.Yamux disabled is not supported") } diff --git a/docs/config.md b/docs/config.md index fd0c0a23e..6a336a66c 100644 --- a/docs/config.md +++ b/docs/config.md @@ -2222,7 +2222,7 @@ Type: `priority` #### `Swarm.Transports.Security.SECIO` -Support for SECIO has been removed. Please remove this option from your config. +**REMOVED**: support for SECIO has been removed. Please remove this option from your config. #### `Swarm.Transports.Security.Noise` From b4eff755a6e78ed3e3347192c8fe19f5aa31289e Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Mon, 22 Jan 2024 15:40:50 +0000 Subject: [PATCH 1010/1212] chore: create next changelog --- CHANGELOG.md | 1 + docs/changelogs/v0.27.md | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 docs/changelogs/v0.27.md diff --git a/CHANGELOG.md b/CHANGELOG.md index a0a5f78e9..bfcf27bed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ # Kubo Changelogs +- [v0.27](docs/changelogs/v0.27.md) - [v0.26](docs/changelogs/v0.26.md) - [v0.25](docs/changelogs/v0.25.md) - [v0.24](docs/changelogs/v0.24.md) diff --git a/docs/changelogs/v0.27.md b/docs/changelogs/v0.27.md new file mode 100644 index 000000000..5ca025612 --- /dev/null +++ b/docs/changelogs/v0.27.md @@ -0,0 +1,18 @@ +# Kubo changelog v0.27 + +- [v0.27.0](#v0270) + +## v0.27.0 + +- [Overview](#overview) +- [🔦 Highlights](#-highlights) +- [📝 Changelog](#-changelog) +- [👨‍👩‍👧‍👦 Contributors](#-contributors) + +### Overview + +### 🔦 Highlights + +### 📝 Changelog + +### 👨‍👩‍👧‍👦 Contributors From 5f18f4d4387f4b48a6b45e0a7a314003610136aa Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Mon, 22 Jan 2024 16:49:12 +0100 Subject: [PATCH 1011/1212] docs: remove whizzzkid --- docs/RELEASE_CHECKLIST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/RELEASE_CHECKLIST.md b/docs/RELEASE_CHECKLIST.md index b0a89dccc..d9fbd9348 100644 --- a/docs/RELEASE_CHECKLIST.md +++ b/docs/RELEASE_CHECKLIST.md @@ -145,7 +145,7 @@ This section covers tasks to be done during each release. - [ ] check out [ipfs/ipfs-desktop](https://github.com/ipfs/ipfs-desktop) - [ ] run `npm install` - [ ] create a PR which updates `package.json` and `package-lock.json` - - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) add @SgtPooki and @whizzzkid as reviewers + - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) add @SgtPooki as reviewer
- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Update Kubo docs
using `./kuboreleaser release --version vX.Y.Z(-rcN) update-ipfs-docs` or ... - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) run the [update-on-new-ipfs-tag.yml](https://github.com/ipfs/ipfs-docs/actions/workflows/update-on-new-ipfs-tag.yml) workflow From 12ed20a7a69bfef3baae27b93fd691b28c491b4b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Jan 2024 21:57:44 +0000 Subject: [PATCH 1012/1212] chore(deps): bump actions/cache from 3 to 4 Bumps [actions/cache](https://github.com/actions/cache) from 3 to 4. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/build.yml | 4 ++-- .github/workflows/docker-image.yml | 2 +- .github/workflows/sharness.yml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 69534112d..67f18331f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -63,7 +63,7 @@ jobs: - run: chmod +x cmd/ipfs/ipfs - run: echo "dir=$(npm config get cache)" >> $GITHUB_OUTPUT id: npm-cache-dir - - uses: actions/cache@v3 + - uses: actions/cache@v4 with: path: ${{ steps.npm-cache-dir.outputs.dir }} key: ${{ runner.os }}-${{ github.job }}-helia-${{ hashFiles('**/package-lock.json') }} @@ -123,7 +123,7 @@ jobs: - run: | echo "dir=$(npm config get cache)" >> $GITHUB_OUTPUT id: npm-cache-dir - - uses: actions/cache@v3 + - uses: actions/cache@v4 with: path: ${{ steps.npm-cache-dir.outputs.dir }} key: ${{ runner.os }}-${{ github.job }}-${{ hashFiles('**/package-lock.json') }} diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index fe28293e7..33c5bb549 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -46,7 +46,7 @@ jobs: uses: docker/setup-buildx-action@v3 - name: Cache Docker layers - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: /tmp/.buildx-cache key: ${{ runner.os }}-buildx-${{ github.sha }} diff --git a/.github/workflows/sharness.yml b/.github/workflows/sharness.yml index 7bf3325ef..ec678e5ec 100644 --- a/.github/workflows/sharness.yml +++ b/.github/workflows/sharness.yml @@ -32,7 +32,7 @@ jobs: path: kubo - name: Install missing tools run: sudo apt update && sudo apt install -y socat net-tools fish libxml2-utils - - uses: actions/cache@v3 + - uses: actions/cache@v4 with: path: test/sharness/lib/dependencies key: ${{ runner.os }}-test-generate-junit-html-${{ hashFiles('test/sharness/lib/test-generate-junit-html.sh') }} From 3a8495d843f090a7144d9d9e295959fa69dc9f44 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Tue, 23 Jan 2024 09:35:12 +0100 Subject: [PATCH 1013/1212] docs: add changelog link to release issue template --- docs/RELEASE_ISSUE_TEMPLATE.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/RELEASE_ISSUE_TEMPLATE.md b/docs/RELEASE_ISSUE_TEMPLATE.md index 61c7ee095..52f02fb50 100644 --- a/docs/RELEASE_ISSUE_TEMPLATE.md +++ b/docs/RELEASE_ISSUE_TEMPLATE.md @@ -23,6 +23,7 @@ * 🚢 Expected final release date: YYYY-MM-DD * Release PR: * Accompanying PR for improving the release process: ([example](https://github.com/ipfs/kubo/pull/9391)) +* Changelog: https://github.com/ipfs/kubo/blob/master/docs/changelogs/vX.Y.md # Items In Scope From be9d87adb5aa2b29f1032d7c9ad568c6146a2310 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Mon, 22 Jan 2024 16:55:01 +0100 Subject: [PATCH 1014/1212] chore: update dependencies --- docs/examples/kubo-as-a-library/go.mod | 15 ++++++------- docs/examples/kubo-as-a-library/go.sum | 30 ++++++++++++-------------- go.mod | 15 ++++++------- go.sum | 30 ++++++++++++-------------- test/dependencies/go.mod | 15 ++++++------- test/dependencies/go.sum | 30 ++++++++++++-------------- 6 files changed, 63 insertions(+), 72 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 2582305b6..27ddf9a47 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -116,8 +116,7 @@ require ( github.com/libp2p/zeroconf/v2 v2.2.0 // indirect github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect - github.com/miekg/dns v1.1.57 // indirect + github.com/miekg/dns v1.1.58 // indirect github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect github.com/minio/sha256-simd v1.0.1 // indirect @@ -159,7 +158,7 @@ require ( github.com/polydawn/refmt v0.89.0 // indirect github.com/prometheus/client_golang v1.18.0 // indirect github.com/prometheus/client_model v0.5.0 // indirect - github.com/prometheus/common v0.45.0 // indirect + github.com/prometheus/common v0.46.0 // indirect github.com/prometheus/procfs v0.12.0 // indirect github.com/quic-go/qpack v0.4.0 // indirect github.com/quic-go/qtls-go1-20 v0.4.1 // indirect @@ -178,15 +177,15 @@ require ( github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 // indirect go.opencensus.io v0.24.0 // indirect - go.opentelemetry.io/otel v1.21.0 // indirect + go.opentelemetry.io/otel v1.22.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0 // indirect go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.21.0 // indirect go.opentelemetry.io/otel/exporters/zipkin v1.21.0 // indirect - go.opentelemetry.io/otel/metric v1.21.0 // indirect + go.opentelemetry.io/otel/metric v1.22.0 // indirect go.opentelemetry.io/otel/sdk v1.21.0 // indirect - go.opentelemetry.io/otel/trace v1.21.0 // indirect + go.opentelemetry.io/otel/trace v1.22.0 // indirect go.opentelemetry.io/proto/otlp v1.0.0 // indirect go.uber.org/dig v1.17.1 // indirect go.uber.org/fx v1.20.1 // indirect @@ -195,13 +194,13 @@ require ( go.uber.org/zap v1.26.0 // indirect go4.org v0.0.0-20230225012048-214862532bf5 // indirect golang.org/x/crypto v0.18.0 // indirect - golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc // indirect + golang.org/x/exp v0.0.0-20240119083558-1b970713d09a // indirect golang.org/x/mod v0.14.0 // indirect golang.org/x/net v0.20.0 // indirect golang.org/x/sync v0.6.0 // indirect golang.org/x/sys v0.16.0 // indirect golang.org/x/text v0.14.0 // indirect - golang.org/x/tools v0.16.1 // indirect + golang.org/x/tools v0.17.0 // indirect golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect gonum.org/v1/gonum v0.14.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240108191215-35c7eff3a6b1 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 5cb425214..18a52c6f2 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -459,14 +459,12 @@ github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27k github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg= -github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k= github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= -github.com/miekg/dns v1.1.57 h1:Jzi7ApEIzwEPLHWRcafCN9LZSBbqQpxjt/wpgvg7wcM= -github.com/miekg/dns v1.1.57/go.mod h1:uqRjCRUuEAA6qsOiJvDd+CFo/vW+y5WR6SNmHE55hZk= +github.com/miekg/dns v1.1.58 h1:ca2Hdkz+cDg/7eNF6V56jjzuZ4aCAE+DbVkILdQWG/4= +github.com/miekg/dns v1.1.58/go.mod h1:Ypv+3b/KadlvW9vJfXOTf300O4UqaHFzFCuHz+rPkBY= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c h1:bzE/A84HN25pxAuk9Eej1Kz9OUelF97nAc82bDquQI8= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c/go.mod h1:0SQS9kMwD2VsyFEB++InYyBJroV/FRmBgcydeSUcJms= github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= @@ -619,8 +617,8 @@ github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1: github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.45.0 h1:2BGz0eBc2hdMDLnO/8n0jeB3oPrt2D08CekT0lneoxM= -github.com/prometheus/common v0.45.0/go.mod h1:YJmSTw9BoKxJplESWWxlbyttQR4uaEcGyv9MZjVOJsY= +github.com/prometheus/common v0.46.0 h1:doXzt5ybi1HBKpsZOL0sSkaNHJJqkyfEWZGGqqScV0Y= +github.com/prometheus/common v0.46.0/go.mod h1:Tp0qkxpb9Jsg54QMe+EAmqXkSV7Evdy1BTn+g2pa/hQ= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= @@ -755,8 +753,8 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/otel v1.21.0 h1:hzLeKBZEL7Okw2mGzZ0cc4k/A7Fta0uoPgaJCr8fsFc= -go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo= +go.opentelemetry.io/otel v1.22.0 h1:xS7Ku+7yTFvDfDraDIJVpw7XPyuHlB9MCiqqX5mcJ6Y= +go.opentelemetry.io/otel v1.22.0/go.mod h1:eoV4iAi3Ea8LkAEI9+GFT44O6T/D0GWAVFyZVCC6pMI= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 h1:cl5P5/GIfFh4t6xyruOgJP5QiA1pw4fYYdv6nc6CBWw= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0/go.mod h1:zgBdWWAu7oEEMC06MMKc5NLbA/1YDXV1sMpSqEeLQLg= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0 h1:tIqheXEFWAZ7O8A7m+J0aPTmpJN3YQ7qetUAdkkkKpk= @@ -767,12 +765,12 @@ go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.21.0 h1:VhlEQAPp9R1ktYf go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.21.0/go.mod h1:kB3ufRbfU+CQ4MlUcqtW8Z7YEOBeK2DJ6CmR5rYYF3E= go.opentelemetry.io/otel/exporters/zipkin v1.21.0 h1:D+Gv6lSfrFBWmQYyxKjDd0Zuld9SRXpIrEsKZvE4DO4= go.opentelemetry.io/otel/exporters/zipkin v1.21.0/go.mod h1:83oMKR6DzmHisFOW3I+yIMGZUTjxiWaiBI8M8+TU5zE= -go.opentelemetry.io/otel/metric v1.21.0 h1:tlYWfeo+Bocx5kLEloTjbcDwBuELRrIFxwdQ36PlJu4= -go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM= +go.opentelemetry.io/otel/metric v1.22.0 h1:lypMQnGyJYeuYPhOM/bgjbFM6WE44W1/T45er4d8Hhg= +go.opentelemetry.io/otel/metric v1.22.0/go.mod h1:evJGjVpZv0mQ5QBRJoBF64yMuOf4xCWdXjK8pzFvliY= go.opentelemetry.io/otel/sdk v1.21.0 h1:FTt8qirL1EysG6sTQRZ5TokkU8d0ugCj8htOgThZXQ8= go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E= -go.opentelemetry.io/otel/trace v1.21.0 h1:WD9i5gzvoUPuXIXH24ZNBudiarZDKuekPqi/E8fpfLc= -go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ= +go.opentelemetry.io/otel/trace v1.22.0 h1:Hg6pPujv0XG9QaVbGOBVHunyuLcCC3jN7WEhPx83XD0= +go.opentelemetry.io/otel/trace v1.22.0/go.mod h1:RbbHXVqKES9QhzZq/fE5UnOSILqRt40a21sPw2He1xo= go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I= go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= @@ -832,8 +830,8 @@ golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc h1:ao2WRsKSzW6KuUY9IWPwWahcHCgR0s52IfwutMfEbdM= -golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI= +golang.org/x/exp v0.0.0-20240119083558-1b970713d09a h1:Q8/wZp0KX97QFTc2ywcOE0YRjZPVIx+MXInMzdvQqcA= +golang.org/x/exp v0.0.0-20240119083558-1b970713d09a/go.mod h1:idGWGoKP1toJGkd5/ig9ZLuPcZBC3ewk7SzmH0uou08= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1038,8 +1036,8 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.16.1 h1:TLyB3WofjdOEepBHAU20JdNC1Zbg87elYofWYAY5oZA= -golang.org/x/tools v0.16.1/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= +golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc= +golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/go.mod b/go.mod index 9e94c0f22..1c19ce5f5 100644 --- a/go.mod +++ b/go.mod @@ -76,15 +76,15 @@ require ( go.opencensus.io v0.24.0 go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 go.opentelemetry.io/contrib/propagators/autoprop v0.46.1 - go.opentelemetry.io/otel v1.21.0 + go.opentelemetry.io/otel v1.22.0 go.opentelemetry.io/otel/sdk v1.21.0 - go.opentelemetry.io/otel/trace v1.21.0 + go.opentelemetry.io/otel/trace v1.22.0 go.uber.org/dig v1.17.1 go.uber.org/fx v1.20.1 go.uber.org/multierr v1.11.0 go.uber.org/zap v1.26.0 golang.org/x/crypto v0.18.0 - golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc + golang.org/x/exp v0.0.0-20240119083558-1b970713d09a golang.org/x/mod v0.14.0 golang.org/x/sync v0.6.0 golang.org/x/sys v0.16.0 @@ -165,9 +165,8 @@ require ( github.com/mattn/go-colorable v0.1.6 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-runewidth v0.0.4 // indirect - github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect - github.com/miekg/dns v1.1.57 // indirect + github.com/miekg/dns v1.1.58 // indirect github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect github.com/minio/sha256-simd v1.0.1 // indirect @@ -200,7 +199,7 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect github.com/polydawn/refmt v0.89.0 // indirect github.com/prometheus/client_model v0.5.0 // indirect - github.com/prometheus/common v0.45.0 // indirect + github.com/prometheus/common v0.46.0 // indirect github.com/prometheus/procfs v0.12.0 // indirect github.com/prometheus/statsd_exporter v0.22.7 // indirect github.com/quic-go/qpack v0.4.0 // indirect @@ -229,7 +228,7 @@ require ( go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0 // indirect go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.21.0 // indirect go.opentelemetry.io/otel/exporters/zipkin v1.21.0 // indirect - go.opentelemetry.io/otel/metric v1.21.0 // indirect + go.opentelemetry.io/otel/metric v1.22.0 // indirect go.opentelemetry.io/proto/otlp v1.0.0 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/mock v0.4.0 // indirect @@ -238,7 +237,7 @@ require ( golang.org/x/oauth2 v0.16.0 // indirect golang.org/x/term v0.16.0 // indirect golang.org/x/text v0.14.0 // indirect - golang.org/x/tools v0.16.1 // indirect + golang.org/x/tools v0.17.0 // indirect golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect gonum.org/v1/gonum v0.14.0 // indirect google.golang.org/appengine v1.6.8 // indirect diff --git a/go.sum b/go.sum index 3b8feab09..390b51ec8 100644 --- a/go.sum +++ b/go.sum @@ -563,15 +563,13 @@ github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D 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= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg= -github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k= github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4= github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= -github.com/miekg/dns v1.1.57 h1:Jzi7ApEIzwEPLHWRcafCN9LZSBbqQpxjt/wpgvg7wcM= -github.com/miekg/dns v1.1.57/go.mod h1:uqRjCRUuEAA6qsOiJvDd+CFo/vW+y5WR6SNmHE55hZk= +github.com/miekg/dns v1.1.58 h1:ca2Hdkz+cDg/7eNF6V56jjzuZ4aCAE+DbVkILdQWG/4= +github.com/miekg/dns v1.1.58/go.mod h1:Ypv+3b/KadlvW9vJfXOTf300O4UqaHFzFCuHz+rPkBY= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c h1:bzE/A84HN25pxAuk9Eej1Kz9OUelF97nAc82bDquQI8= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c/go.mod h1:0SQS9kMwD2VsyFEB++InYyBJroV/FRmBgcydeSUcJms= github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= @@ -748,8 +746,8 @@ github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9 github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/common v0.35.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= -github.com/prometheus/common v0.45.0 h1:2BGz0eBc2hdMDLnO/8n0jeB3oPrt2D08CekT0lneoxM= -github.com/prometheus/common v0.45.0/go.mod h1:YJmSTw9BoKxJplESWWxlbyttQR4uaEcGyv9MZjVOJsY= +github.com/prometheus/common v0.46.0 h1:doXzt5ybi1HBKpsZOL0sSkaNHJJqkyfEWZGGqqScV0Y= +github.com/prometheus/common v0.46.0/go.mod h1:Tp0qkxpb9Jsg54QMe+EAmqXkSV7Evdy1BTn+g2pa/hQ= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= @@ -927,8 +925,8 @@ go.opentelemetry.io/contrib/propagators/jaeger v1.21.1 h1:f4beMGDKiVzg9IcX7/VuWV go.opentelemetry.io/contrib/propagators/jaeger v1.21.1/go.mod h1:U9jhkEl8d1LL+QXY7q3kneJWJugiN3kZJV2OWz3hkBY= go.opentelemetry.io/contrib/propagators/ot v1.21.1 h1:3TN5vkXjKYWp0YdMcnUEC/A+pBPvqz9V3nCS2xmcurk= go.opentelemetry.io/contrib/propagators/ot v1.21.1/go.mod h1:oy0MYCbS/b3cqUDW37wBWtlwBIsutngS++Lklpgh+fc= -go.opentelemetry.io/otel v1.21.0 h1:hzLeKBZEL7Okw2mGzZ0cc4k/A7Fta0uoPgaJCr8fsFc= -go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo= +go.opentelemetry.io/otel v1.22.0 h1:xS7Ku+7yTFvDfDraDIJVpw7XPyuHlB9MCiqqX5mcJ6Y= +go.opentelemetry.io/otel v1.22.0/go.mod h1:eoV4iAi3Ea8LkAEI9+GFT44O6T/D0GWAVFyZVCC6pMI= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 h1:cl5P5/GIfFh4t6xyruOgJP5QiA1pw4fYYdv6nc6CBWw= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0/go.mod h1:zgBdWWAu7oEEMC06MMKc5NLbA/1YDXV1sMpSqEeLQLg= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0 h1:tIqheXEFWAZ7O8A7m+J0aPTmpJN3YQ7qetUAdkkkKpk= @@ -939,12 +937,12 @@ go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.21.0 h1:VhlEQAPp9R1ktYf go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.21.0/go.mod h1:kB3ufRbfU+CQ4MlUcqtW8Z7YEOBeK2DJ6CmR5rYYF3E= go.opentelemetry.io/otel/exporters/zipkin v1.21.0 h1:D+Gv6lSfrFBWmQYyxKjDd0Zuld9SRXpIrEsKZvE4DO4= go.opentelemetry.io/otel/exporters/zipkin v1.21.0/go.mod h1:83oMKR6DzmHisFOW3I+yIMGZUTjxiWaiBI8M8+TU5zE= -go.opentelemetry.io/otel/metric v1.21.0 h1:tlYWfeo+Bocx5kLEloTjbcDwBuELRrIFxwdQ36PlJu4= -go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM= +go.opentelemetry.io/otel/metric v1.22.0 h1:lypMQnGyJYeuYPhOM/bgjbFM6WE44W1/T45er4d8Hhg= +go.opentelemetry.io/otel/metric v1.22.0/go.mod h1:evJGjVpZv0mQ5QBRJoBF64yMuOf4xCWdXjK8pzFvliY= go.opentelemetry.io/otel/sdk v1.21.0 h1:FTt8qirL1EysG6sTQRZ5TokkU8d0ugCj8htOgThZXQ8= go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E= -go.opentelemetry.io/otel/trace v1.21.0 h1:WD9i5gzvoUPuXIXH24ZNBudiarZDKuekPqi/E8fpfLc= -go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ= +go.opentelemetry.io/otel/trace v1.22.0 h1:Hg6pPujv0XG9QaVbGOBVHunyuLcCC3jN7WEhPx83XD0= +go.opentelemetry.io/otel/trace v1.22.0/go.mod h1:RbbHXVqKES9QhzZq/fE5UnOSILqRt40a21sPw2He1xo= go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I= go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= @@ -1007,8 +1005,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc h1:ao2WRsKSzW6KuUY9IWPwWahcHCgR0s52IfwutMfEbdM= -golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI= +golang.org/x/exp v0.0.0-20240119083558-1b970713d09a h1:Q8/wZp0KX97QFTc2ywcOE0YRjZPVIx+MXInMzdvQqcA= +golang.org/x/exp v0.0.0-20240119083558-1b970713d09a/go.mod h1:idGWGoKP1toJGkd5/ig9ZLuPcZBC3ewk7SzmH0uou08= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1280,8 +1278,8 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.16.1 h1:TLyB3WofjdOEepBHAU20JdNC1Zbg87elYofWYAY5oZA= -golang.org/x/tools v0.16.1/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= +golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc= +golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index e0f00037b..359552807 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -149,10 +149,9 @@ require ( github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-runewidth v0.0.9 // indirect - github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect github.com/mbilski/exhaustivestruct v1.2.0 // indirect github.com/mgechev/revive v1.3.2 // indirect - github.com/miekg/dns v1.1.57 // indirect + github.com/miekg/dns v1.1.58 // indirect github.com/minio/sha256-simd v1.0.1 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect @@ -181,7 +180,7 @@ require ( github.com/polyfloyd/go-errorlint v1.4.3 // indirect github.com/prometheus/client_golang v1.18.0 // indirect github.com/prometheus/client_model v0.5.0 // indirect - github.com/prometheus/common v0.45.0 // indirect + github.com/prometheus/common v0.46.0 // indirect github.com/prometheus/procfs v0.12.0 // indirect github.com/quasilyte/go-ruleguard v0.4.0 // indirect github.com/quasilyte/gogrep v0.5.0 // indirect @@ -233,14 +232,14 @@ require ( github.com/ykadowak/zerologlint v0.1.3 // indirect gitlab.com/bosi/decorder v0.4.0 // indirect go.opencensus.io v0.24.0 // indirect - go.opentelemetry.io/otel v1.21.0 // indirect - go.opentelemetry.io/otel/metric v1.21.0 // indirect - go.opentelemetry.io/otel/trace v1.21.0 // indirect + go.opentelemetry.io/otel v1.22.0 // indirect + go.opentelemetry.io/otel/metric v1.22.0 // indirect + go.opentelemetry.io/otel/trace v1.22.0 // indirect go.tmz.dev/musttag v0.7.1 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.26.0 // indirect golang.org/x/crypto v0.18.0 // indirect - golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc // indirect + golang.org/x/exp v0.0.0-20240119083558-1b970713d09a // indirect golang.org/x/exp/typeparams v0.0.0-20230307190834-24139beb5833 // indirect golang.org/x/mod v0.14.0 // indirect golang.org/x/net v0.20.0 // indirect @@ -248,7 +247,7 @@ require ( golang.org/x/sys v0.16.0 // indirect golang.org/x/term v0.16.0 // indirect golang.org/x/text v0.14.0 // indirect - golang.org/x/tools v0.16.1 // indirect + golang.org/x/tools v0.17.0 // indirect gonum.org/v1/gonum v0.14.0 // indirect google.golang.org/protobuf v1.32.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 02d3c3500..dd39149f9 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -493,15 +493,13 @@ github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg= -github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k= github.com/mbilski/exhaustivestruct v1.2.0 h1:wCBmUnSYufAHO6J4AVWY6ff+oxWxsVFrwgOdMUQePUo= github.com/mbilski/exhaustivestruct v1.2.0/go.mod h1:OeTBVxQWoEmB2J2JCHmXWPJ0aksxSUOUy+nvtVEfzXc= github.com/mgechev/revive v1.3.2 h1:Wb8NQKBaALBJ3xrrj4zpwJwqwNA6nDpyJSEQWcCka6U= github.com/mgechev/revive v1.3.2/go.mod h1:UCLtc7o5vg5aXCwdUTU1kEBQ1v+YXPAkYDIDXbrs5I0= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= -github.com/miekg/dns v1.1.57 h1:Jzi7ApEIzwEPLHWRcafCN9LZSBbqQpxjt/wpgvg7wcM= -github.com/miekg/dns v1.1.57/go.mod h1:uqRjCRUuEAA6qsOiJvDd+CFo/vW+y5WR6SNmHE55hZk= +github.com/miekg/dns v1.1.58 h1:ca2Hdkz+cDg/7eNF6V56jjzuZ4aCAE+DbVkILdQWG/4= +github.com/miekg/dns v1.1.58/go.mod h1:Ypv+3b/KadlvW9vJfXOTf300O4UqaHFzFCuHz+rPkBY= github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc h1:PTfri+PuQmWDqERdnNMiD9ZejrlswWrCpBEZgWOiTrc= github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= @@ -607,8 +605,8 @@ github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8 github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= -github.com/prometheus/common v0.45.0 h1:2BGz0eBc2hdMDLnO/8n0jeB3oPrt2D08CekT0lneoxM= -github.com/prometheus/common v0.45.0/go.mod h1:YJmSTw9BoKxJplESWWxlbyttQR4uaEcGyv9MZjVOJsY= +github.com/prometheus/common v0.46.0 h1:doXzt5ybi1HBKpsZOL0sSkaNHJJqkyfEWZGGqqScV0Y= +github.com/prometheus/common v0.46.0/go.mod h1:Tp0qkxpb9Jsg54QMe+EAmqXkSV7Evdy1BTn+g2pa/hQ= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= @@ -771,12 +769,12 @@ go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/otel v1.21.0 h1:hzLeKBZEL7Okw2mGzZ0cc4k/A7Fta0uoPgaJCr8fsFc= -go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo= -go.opentelemetry.io/otel/metric v1.21.0 h1:tlYWfeo+Bocx5kLEloTjbcDwBuELRrIFxwdQ36PlJu4= -go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM= -go.opentelemetry.io/otel/trace v1.21.0 h1:WD9i5gzvoUPuXIXH24ZNBudiarZDKuekPqi/E8fpfLc= -go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ= +go.opentelemetry.io/otel v1.22.0 h1:xS7Ku+7yTFvDfDraDIJVpw7XPyuHlB9MCiqqX5mcJ6Y= +go.opentelemetry.io/otel v1.22.0/go.mod h1:eoV4iAi3Ea8LkAEI9+GFT44O6T/D0GWAVFyZVCC6pMI= +go.opentelemetry.io/otel/metric v1.22.0 h1:lypMQnGyJYeuYPhOM/bgjbFM6WE44W1/T45er4d8Hhg= +go.opentelemetry.io/otel/metric v1.22.0/go.mod h1:evJGjVpZv0mQ5QBRJoBF64yMuOf4xCWdXjK8pzFvliY= +go.opentelemetry.io/otel/trace v1.22.0 h1:Hg6pPujv0XG9QaVbGOBVHunyuLcCC3jN7WEhPx83XD0= +go.opentelemetry.io/otel/trace v1.22.0/go.mod h1:RbbHXVqKES9QhzZq/fE5UnOSILqRt40a21sPw2He1xo= go.tmz.dev/musttag v0.7.1 h1:9lFmeSFnFfPuMq4IksHGomItE6NgKMNW2Nt2FPOhCfU= go.tmz.dev/musttag v0.7.1/go.mod h1:oJLkpR56EsIryktZJk/B0IroSMi37YWver47fibGh5U= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= @@ -818,8 +816,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc h1:ao2WRsKSzW6KuUY9IWPwWahcHCgR0s52IfwutMfEbdM= -golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI= +golang.org/x/exp v0.0.0-20240119083558-1b970713d09a h1:Q8/wZp0KX97QFTc2ywcOE0YRjZPVIx+MXInMzdvQqcA= +golang.org/x/exp v0.0.0-20240119083558-1b970713d09a/go.mod h1:idGWGoKP1toJGkd5/ig9ZLuPcZBC3ewk7SzmH0uou08= golang.org/x/exp/typeparams v0.0.0-20220428152302-39d4317da171/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/exp/typeparams v0.0.0-20230203172020-98cc5a0785f9/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/exp/typeparams v0.0.0-20230307190834-24139beb5833 h1:jWGQJV4niP+CCmFW9ekjA9Zx8vYORzOUH2/Nl5WPuLQ= @@ -1088,8 +1086,8 @@ golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= golang.org/x/tools v0.5.0/go.mod h1:N+Kgy78s5I24c24dU8OfWNEotWjutIs8SnJvn5IDq+k= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.16.1 h1:TLyB3WofjdOEepBHAU20JdNC1Zbg87elYofWYAY5oZA= -golang.org/x/tools v0.16.1/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= +golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc= +golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From e166af975613407739d2c8f65b5b1430fa90475b Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Wed, 24 Jan 2024 10:33:23 +0100 Subject: [PATCH 1015/1212] core/corehttp: wrap gateway with headers, deprecate gateway /api/v0 --- cmd/ipfs/kubo/daemon.go | 1 + core/corehttp/commands.go | 8 ++++++++ core/corehttp/gateway.go | 20 +++++++------------- core/corehttp/gateway_test.go | 2 +- core/corehttp/routing.go | 7 +++++++ docs/changelogs/v0.27.md | 7 +++++++ docs/config.md | 11 ++++++----- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- test/dependencies/go.mod | 2 +- test/dependencies/go.sum | 4 ++-- test/sharness/t0112-gateway-cors.sh | 10 ++++++---- 14 files changed, 52 insertions(+), 32 deletions(-) diff --git a/cmd/ipfs/kubo/daemon.go b/cmd/ipfs/kubo/daemon.go index ae755648e..82f240897 100644 --- a/cmd/ipfs/kubo/daemon.go +++ b/cmd/ipfs/kubo/daemon.go @@ -850,6 +850,7 @@ func serveHTTPGateway(req *cmds.Request, cctx *oldcmds.Context) (<-chan error, e corehttp.GatewayOption("/ipfs", "/ipns"), corehttp.VersionOption(), corehttp.CheckVersionOption(), + // TODO[api-on-gw]: remove for 0.28.0: https://github.com/ipfs/kubo/issues/10312 corehttp.CommandsROOption(cmdctx), } diff --git a/core/corehttp/commands.go b/core/corehttp/commands.go index 314822ff2..4feef3359 100644 --- a/core/corehttp/commands.go +++ b/core/corehttp/commands.go @@ -9,6 +9,7 @@ import ( "strconv" "strings" + "github.com/ipfs/boxo/gateway" cmds "github.com/ipfs/go-ipfs-cmds" cmdsHttp "github.com/ipfs/go-ipfs-cmds/http" version "github.com/ipfs/kubo" @@ -149,6 +150,13 @@ func commandsOption(cctx oldcmds.Context, command *cmds.Command, allowGet bool) cmdHandler = withAuthSecrets(authorizations, cmdHandler) } + // TODO[api-on-gw]: remove for Kubo 0.28 + if command == corecommands.RootRO && allowGet { + cmdHandler = gateway.NewHeaders(map[string][]string{ + "Link": {`; rel="deprecation"; type="text/html"`}, + }).Wrap(cmdHandler) + } + cmdHandler = otelhttp.NewHandler(cmdHandler, "corehttp.cmdsHandler") mux.Handle(APIPath+"/", cmdHandler) return mux, nil diff --git a/core/corehttp/gateway.go b/core/corehttp/gateway.go index a15765176..c08d71806 100644 --- a/core/corehttp/gateway.go +++ b/core/corehttp/gateway.go @@ -28,7 +28,7 @@ import ( func GatewayOption(paths ...string) ServeOption { return func(n *core.IpfsNode, _ net.Listener, mux *http.ServeMux) (*http.ServeMux, error) { - config, err := getGatewayConfig(n) + config, headers, err := getGatewayConfig(n) if err != nil { return nil, err } @@ -39,6 +39,7 @@ func GatewayOption(paths ...string) ServeOption { } handler := gateway.NewHandler(config, backend) + handler = gateway.NewHeaders(headers).ApplyCors().Wrap(handler) handler = otelhttp.NewHandler(handler, "Gateway") for _, p := range paths { @@ -51,7 +52,7 @@ func GatewayOption(paths ...string) ServeOption { func HostnameOption() ServeOption { return func(n *core.IpfsNode, _ net.Listener, mux *http.ServeMux) (*http.ServeMux, error) { - config, err := getGatewayConfig(n) + config, headers, err := getGatewayConfig(n) if err != nil { return nil, err } @@ -65,6 +66,7 @@ func HostnameOption() ServeOption { var handler http.Handler handler = gateway.NewHostnameHandler(config, backend, childMux) + handler = gateway.NewHeaders(headers).ApplyCors().Wrap(handler) handler = otelhttp.NewHandler(handler, "HostnameGateway") mux.Handle("/", handler) @@ -240,22 +242,14 @@ var defaultKnownGateways = map[string]*gateway.PublicGateway{ "localhost": subdomainGatewaySpec, } -func getGatewayConfig(n *core.IpfsNode) (gateway.Config, error) { +func getGatewayConfig(n *core.IpfsNode) (gateway.Config, map[string][]string, error) { cfg, err := n.Repo.Config() if err != nil { - return gateway.Config{}, err + return gateway.Config{}, nil, err } - // Parse configuration headers and add the default Access Control Headers. - headers := make(map[string][]string, len(cfg.Gateway.HTTPHeaders)) - for h, v := range cfg.Gateway.HTTPHeaders { - headers[http.CanonicalHeaderKey(h)] = v - } - gateway.AddAccessControlHeaders(headers) - // Initialize gateway configuration, with empty PublicGateways, handled after. gwCfg := gateway.Config{ - Headers: headers, DeserializedResponses: cfg.Gateway.DeserializedResponses.WithDefault(config.DefaultDeserializedResponses), DisableHTMLErrors: cfg.Gateway.DisableHTMLErrors.WithDefault(config.DefaultDisableHTMLErrors), NoDNSLink: cfg.Gateway.NoDNSLink, @@ -285,5 +279,5 @@ func getGatewayConfig(n *core.IpfsNode) (gateway.Config, error) { } } - return gwCfg, nil + return gwCfg, cfg.Gateway.HTTPHeaders, nil } diff --git a/core/corehttp/gateway_test.go b/core/corehttp/gateway_test.go index c2e0073d9..df307ef73 100644 --- a/core/corehttp/gateway_test.go +++ b/core/corehttp/gateway_test.go @@ -206,7 +206,7 @@ func TestDeserializedResponsesInheritance(t *testing.T) { n, err := core.NewNode(context.Background(), &core.BuildCfg{Repo: r}) assert.NoError(t, err) - gwCfg, err := getGatewayConfig(n) + gwCfg, _, err := getGatewayConfig(n) assert.NoError(t, err) assert.Contains(t, gwCfg.PublicGateways, "example.com") diff --git a/core/corehttp/routing.go b/core/corehttp/routing.go index 88d9de886..9a2591d32 100644 --- a/core/corehttp/routing.go +++ b/core/corehttp/routing.go @@ -6,6 +6,7 @@ import ( "net/http" "time" + "github.com/ipfs/boxo/gateway" "github.com/ipfs/boxo/ipns" "github.com/ipfs/boxo/routing/http/server" "github.com/ipfs/boxo/routing/http/types" @@ -18,7 +19,13 @@ import ( func RoutingOption() ServeOption { return func(n *core.IpfsNode, _ net.Listener, mux *http.ServeMux) (*http.ServeMux, error) { + _, headers, err := getGatewayConfig(n) + if err != nil { + return nil, err + } + handler := server.Handler(&contentRouter{n}) + handler = gateway.NewHeaders(headers).ApplyCors().Wrap(handler) mux.Handle("/routing/v1/", handler) return mux, nil } diff --git a/docs/changelogs/v0.27.md b/docs/changelogs/v0.27.md index 5ca025612..1d7c5b101 100644 --- a/docs/changelogs/v0.27.md +++ b/docs/changelogs/v0.27.md @@ -6,6 +6,7 @@ - [Overview](#overview) - [🔦 Highlights](#-highlights) + - [Gateway: support for `/api/v0` is deprecated](#gateway-support-for-apiv0-is-deprecated) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -13,6 +14,12 @@ ### 🔦 Highlights +#### Gateway: support for `/api/v0` is deprecated + +Support for exposing the legacy subset of Kubo RPC via the Gateway port is deprecated and should not be used. It will be removed in the next version. You can read more in . + +If you have a legacy software that relies on this behavior, and want to expose parts of `/api/v0` next to `/ipfs`, use reverse-proxy in front of Kubo to mount both Gateway and RPC on the same port. NOTE: exposing RPC to the internet comes with security risk: make sure to specify access control via [API.Authorizations](https://github.com/ipfs/kubo/blob/master/docs/config.md#apiauthorizations). + ### 📝 Changelog ### 👨‍👩‍👧‍👦 Contributors diff --git a/docs/config.md b/docs/config.md index 6a336a66c..d6c1567f1 100644 --- a/docs/config.md +++ b/docs/config.md @@ -716,6 +716,8 @@ Toggle and configure experimental features of Kubo. Experimental features are li Options for the HTTP gateway. +**NOTE:** support for `/api/v0` under the gateway path is now deprecated. It will be removed in future versions: https://github.com/ipfs/kubo/issues/10312. + ### `Gateway.NoFetch` When set to true, the gateway will only serve content already in the local repo @@ -819,14 +821,14 @@ Example: "Gateway": { "PublicGateways": { "example.com": { - "Paths": ["/ipfs", "/ipns"], + "Paths": ["/ipfs"], } } } } ``` -Above enables `http://example.com/ipfs/*` and `http://example.com/ipns/*` but not `http://example.com/api/*` +Above enables `http://example.com/ipfs/*` but not `http://example.com/ipns/*` Default: `[]` @@ -851,7 +853,6 @@ between content roots. } ``` - **Backward-compatible:** requests for content paths such as `http://{hostname}/ipfs/{cid}` produce redirect to `http://{cid}.ipfs.{hostname}` - - **API:** if `/api` is on the `Paths` whitelist, `http://{hostname}/api/{cmd}` produces redirect to `http://api.{hostname}/api/{cmd}` - `false` - enables [path gateway](https://docs.ipfs.tech/how-to/address-ipfs-on-web/#path-gateway) at `http://{hostname}/*` - Example: @@ -860,7 +861,7 @@ between content roots. "PublicGateways": { "ipfs.io": { "UseSubdomains": false, - "Paths": ["/ipfs", "/ipns", "/api"] + "Paths": ["/ipfs", "/ipns"] } } } @@ -969,7 +970,7 @@ Below is a list of the most common public gateway setups. $ ipfs config --json Gateway.PublicGateways '{ "ipfs.io": { "UseSubdomains": false, - "Paths": ["/ipfs", "/ipns", "/api"] + "Paths": ["/ipfs", "/ipns"] } }' ``` diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 27ddf9a47..fefedc845 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.20 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.17.1-0.20240112124340-bcb321c857c5 + github.com/ipfs/boxo v0.17.1-0.20240124092521-3d57bce7998c github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.32.2 github.com/multiformats/go-multiaddr v0.12.1 diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 18a52c6f2..103cd2d79 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -260,8 +260,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.17.1-0.20240112124340-bcb321c857c5 h1:qGPYOK8flU2YzHGq9Cb2Yeo0jjOwompAOzxOv3VSGx8= -github.com/ipfs/boxo v0.17.1-0.20240112124340-bcb321c857c5/go.mod h1:pIZgTWdm3k3pLF9Uq6MB8JEcW07UDwNJjlXW1HELW80= +github.com/ipfs/boxo v0.17.1-0.20240124092521-3d57bce7998c h1:A18UHDQ4V2Ai6/YsrH7kfGjA1r5SrwjQR1Lqiq68YQU= +github.com/ipfs/boxo v0.17.1-0.20240124092521-3d57bce7998c/go.mod h1:pIZgTWdm3k3pLF9Uq6MB8JEcW07UDwNJjlXW1HELW80= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.3/go.mod h1:4LmD4ZUw0mhO+JSKdpWwrzATiEfM7WWgQ8H5l6P8MVk= diff --git a/go.mod b/go.mod index 1c19ce5f5..d2da7eb60 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,7 @@ require ( github.com/hashicorp/go-multierror v1.1.1 github.com/ipfs-shipyard/nopfs v0.0.12 github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c - github.com/ipfs/boxo v0.17.1-0.20240112124340-bcb321c857c5 + github.com/ipfs/boxo v0.17.1-0.20240124092521-3d57bce7998c github.com/ipfs/go-block-format v0.2.0 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 diff --git a/go.sum b/go.sum index 390b51ec8..91f63eedb 100644 --- a/go.sum +++ b/go.sum @@ -325,8 +325,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.17.1-0.20240112124340-bcb321c857c5 h1:qGPYOK8flU2YzHGq9Cb2Yeo0jjOwompAOzxOv3VSGx8= -github.com/ipfs/boxo v0.17.1-0.20240112124340-bcb321c857c5/go.mod h1:pIZgTWdm3k3pLF9Uq6MB8JEcW07UDwNJjlXW1HELW80= +github.com/ipfs/boxo v0.17.1-0.20240124092521-3d57bce7998c h1:A18UHDQ4V2Ai6/YsrH7kfGjA1r5SrwjQR1Lqiq68YQU= +github.com/ipfs/boxo v0.17.1-0.20240124092521-3d57bce7998c/go.mod h1:pIZgTWdm3k3pLF9Uq6MB8JEcW07UDwNJjlXW1HELW80= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 359552807..3d8f3654a 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -103,7 +103,7 @@ require ( github.com/hexops/gotextdiff v1.0.3 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/ipfs/bbloom v0.0.4 // indirect - github.com/ipfs/boxo v0.17.1-0.20240112124340-bcb321c857c5 // indirect + github.com/ipfs/boxo v0.17.1-0.20240124092521-3d57bce7998c // indirect github.com/ipfs/go-block-format v0.2.0 // indirect github.com/ipfs/go-cid v0.4.1 // indirect github.com/ipfs/go-datastore v0.6.0 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index dd39149f9..0917aef21 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -342,8 +342,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.17.1-0.20240112124340-bcb321c857c5 h1:qGPYOK8flU2YzHGq9Cb2Yeo0jjOwompAOzxOv3VSGx8= -github.com/ipfs/boxo v0.17.1-0.20240112124340-bcb321c857c5/go.mod h1:pIZgTWdm3k3pLF9Uq6MB8JEcW07UDwNJjlXW1HELW80= +github.com/ipfs/boxo v0.17.1-0.20240124092521-3d57bce7998c h1:A18UHDQ4V2Ai6/YsrH7kfGjA1r5SrwjQR1Lqiq68YQU= +github.com/ipfs/boxo v0.17.1-0.20240124092521-3d57bce7998c/go.mod h1:pIZgTWdm3k3pLF9Uq6MB8JEcW07UDwNJjlXW1HELW80= github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs= github.com/ipfs/go-block-format v0.2.0/go.mod h1:+jpL11nFx5A/SPpsoBn6Bzkra/zaArfSmsknbPMYgzM= github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= diff --git a/test/sharness/t0112-gateway-cors.sh b/test/sharness/t0112-gateway-cors.sh index e4fb57122..37027c188 100755 --- a/test/sharness/t0112-gateway-cors.sh +++ b/test/sharness/t0112-gateway-cors.sh @@ -141,9 +141,11 @@ test_expect_success "Assert the default API.HTTPHeaders config is empty" ' test_expect_success "Default CORS GET to {gw}/api/v0" ' curl -svX GET -H "Origin: https://example.com" "http://127.0.0.1:$GWAY_PORT/api/v0/cat?arg=$thash" >/dev/null 2>curl_output ' -test_expect_success "Default CORS GET response from {gw}/api/v0 is 403 Forbidden and has no CORS headers" ' +# HTTP 403 is returned because Kubo has additional protections on top of regular CORS, +# namely it only allows browser requests with localhost Origin header. +test_expect_success "Default CORS GET response from {gw}/api/v0 is 403 Forbidden and has regular CORS headers" ' test_should_contain "HTTP/1.1 403 Forbidden" curl_output && - test_should_not_contain "< Access-Control-" curl_output + test_should_contain "< Access-Control-" curl_output ' # HTTP OPTIONS Request @@ -151,8 +153,8 @@ test_expect_success "Default OPTIONS to {gw}/api/v0" ' curl -svX OPTIONS -H "Origin: https://example.com" "http://127.0.0.1:$GWAY_PORT/api/v0/cat?arg=$thash" 2>curl_output ' # OPTIONS Response from the API should NOT contain CORS headers -test_expect_success "OPTIONS response from {gw}/api/v0 has no CORS header" ' - test_should_not_contain "< Access-Control-" curl_output +test_expect_success "OPTIONS response from {gw}/api/v0 has CORS headers" ' + test_should_contain "< Access-Control-" curl_output ' test_kill_ipfs_daemon From f9edd2b88a7dc8125967f1c28820a985d995b29e Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Tue, 16 Jan 2024 17:19:33 +0100 Subject: [PATCH 1016/1212] ci: use @helia/interop directly --- .github/workflows/build.yml | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 67f18331f..2d1ce7dd2 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -70,26 +70,7 @@ jobs: restore-keys: ${{ runner.os }}-${{ github.job }}-helia- - run: sudo apt update - run: sudo apt install -y libxkbcommon0 libxdamage1 libgbm1 libpango-1.0-0 libcairo2 # dependencies for playwright - - uses: actions/checkout@v4 - with: - repository: ipfs/helia - fetch-depth: 0 - path: interop - ref: 'main' - - name: Checkout latest tag - run: | - export TAG="$(git tag | grep "^interop-" | sort --version-sort --reverse | head -n1)" - echo "Running tests against: $TAG" - git checkout "$TAG" - working-directory: interop - - run: npm install - working-directory: interop - - run: npm run build - working-directory: interop - - run: npm install - working-directory: interop/packages/interop - - run: npm test - working-directory: interop/packages/interop + - run: npx --package @helia/interop helia-interop env: KUBO_BINARY: ${{ github.workspace }}/cmd/ipfs/ipfs ipfs-webui: From 262151f2ed14a83d7f33a7dbe50b5e03bc37cd7e Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Thu, 25 Jan 2024 18:53:10 +0100 Subject: [PATCH 1017/1212] fix(gw): negative entity-bytes beyond file size (#10320) fix: https://github.com/ipfs/boxo/pull/523 tests: https://github.com/ipfs/gateway-conformance/releases/tag/v0.5.0 --- .github/workflows/gateway-conformance.yml | 8 ++++---- Rules.mk | 5 +++++ docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- test/dependencies/go.mod | 2 +- test/dependencies/go.sum | 4 ++-- 8 files changed, 18 insertions(+), 13 deletions(-) diff --git a/.github/workflows/gateway-conformance.yml b/.github/workflows/gateway-conformance.yml index 993dfca61..57563cfc2 100644 --- a/.github/workflows/gateway-conformance.yml +++ b/.github/workflows/gateway-conformance.yml @@ -41,7 +41,7 @@ jobs: steps: # 1. Download the gateway-conformance fixtures - name: Download gateway-conformance fixtures - uses: ipfs/gateway-conformance/.github/actions/extract-fixtures@v0.4 + uses: ipfs/gateway-conformance/.github/actions/extract-fixtures@v0.5 with: output: fixtures @@ -96,7 +96,7 @@ jobs: # 6. Run the gateway-conformance tests - name: Run gateway-conformance tests - uses: ipfs/gateway-conformance/.github/actions/test@v0.4 + uses: ipfs/gateway-conformance/.github/actions/test@v0.5 with: gateway-url: http://127.0.0.1:8080 json: output.json @@ -129,7 +129,7 @@ jobs: steps: # 1. Download the gateway-conformance fixtures - name: Download gateway-conformance fixtures - uses: ipfs/gateway-conformance/.github/actions/extract-fixtures@v0.4 + uses: ipfs/gateway-conformance/.github/actions/extract-fixtures@v0.5 with: output: fixtures @@ -202,7 +202,7 @@ jobs: # 9. Run the gateway-conformance tests over libp2p - name: Run gateway-conformance tests over libp2p - uses: ipfs/gateway-conformance/.github/actions/test@v0.4 + uses: ipfs/gateway-conformance/.github/actions/test@v0.5 with: gateway-url: http://127.0.0.1:8092 json: output.json diff --git a/Rules.mk b/Rules.mk index cec34cef7..c3e662aa0 100644 --- a/Rules.mk +++ b/Rules.mk @@ -66,6 +66,10 @@ clean: rm -rf $(CLEAN) .PHONY: clean +mod_tidy: + @find . -name go.mod -execdir $(GOCC) mod tidy \; +.PHONY: mod_tidy + coverage: $(COVERAGE) .PHONY: coverage @@ -119,6 +123,7 @@ help: @echo ' build - Build binary at ./cmd/ipfs/ipfs' @echo ' nofuse - Build binary with no fuse support' @echo ' install - Build binary and install into $$GOBIN' + @echo ' mod_tidy - Remove unused dependencis from go.mod files' # @echo ' dist_install - TODO: c.f. ./cmd/ipfs/dist/README.md' @echo '' @echo 'CLEANING TARGETS:' diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index fefedc845..a134ccd25 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.20 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.17.1-0.20240124092521-3d57bce7998c + github.com/ipfs/boxo v0.17.1-0.20240125173442-bf34cd0777d8 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.32.2 github.com/multiformats/go-multiaddr v0.12.1 diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 103cd2d79..f1b2b9a04 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -260,8 +260,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.17.1-0.20240124092521-3d57bce7998c h1:A18UHDQ4V2Ai6/YsrH7kfGjA1r5SrwjQR1Lqiq68YQU= -github.com/ipfs/boxo v0.17.1-0.20240124092521-3d57bce7998c/go.mod h1:pIZgTWdm3k3pLF9Uq6MB8JEcW07UDwNJjlXW1HELW80= +github.com/ipfs/boxo v0.17.1-0.20240125173442-bf34cd0777d8 h1:/d+3/JOYsHS4Uo+6WIxu2oHHlM5WjWOySYItN9V+YHs= +github.com/ipfs/boxo v0.17.1-0.20240125173442-bf34cd0777d8/go.mod h1:pIZgTWdm3k3pLF9Uq6MB8JEcW07UDwNJjlXW1HELW80= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.3/go.mod h1:4LmD4ZUw0mhO+JSKdpWwrzATiEfM7WWgQ8H5l6P8MVk= diff --git a/go.mod b/go.mod index d2da7eb60..68cfbfa5d 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,7 @@ require ( github.com/hashicorp/go-multierror v1.1.1 github.com/ipfs-shipyard/nopfs v0.0.12 github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c - github.com/ipfs/boxo v0.17.1-0.20240124092521-3d57bce7998c + github.com/ipfs/boxo v0.17.1-0.20240125173442-bf34cd0777d8 github.com/ipfs/go-block-format v0.2.0 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 diff --git a/go.sum b/go.sum index 91f63eedb..e20297647 100644 --- a/go.sum +++ b/go.sum @@ -325,8 +325,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.17.1-0.20240124092521-3d57bce7998c h1:A18UHDQ4V2Ai6/YsrH7kfGjA1r5SrwjQR1Lqiq68YQU= -github.com/ipfs/boxo v0.17.1-0.20240124092521-3d57bce7998c/go.mod h1:pIZgTWdm3k3pLF9Uq6MB8JEcW07UDwNJjlXW1HELW80= +github.com/ipfs/boxo v0.17.1-0.20240125173442-bf34cd0777d8 h1:/d+3/JOYsHS4Uo+6WIxu2oHHlM5WjWOySYItN9V+YHs= +github.com/ipfs/boxo v0.17.1-0.20240125173442-bf34cd0777d8/go.mod h1:pIZgTWdm3k3pLF9Uq6MB8JEcW07UDwNJjlXW1HELW80= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 3d8f3654a..f069c1303 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -103,7 +103,7 @@ require ( github.com/hexops/gotextdiff v1.0.3 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/ipfs/bbloom v0.0.4 // indirect - github.com/ipfs/boxo v0.17.1-0.20240124092521-3d57bce7998c // indirect + github.com/ipfs/boxo v0.17.1-0.20240125173442-bf34cd0777d8 // indirect github.com/ipfs/go-block-format v0.2.0 // indirect github.com/ipfs/go-cid v0.4.1 // indirect github.com/ipfs/go-datastore v0.6.0 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 0917aef21..35a9ed955 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -342,8 +342,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.17.1-0.20240124092521-3d57bce7998c h1:A18UHDQ4V2Ai6/YsrH7kfGjA1r5SrwjQR1Lqiq68YQU= -github.com/ipfs/boxo v0.17.1-0.20240124092521-3d57bce7998c/go.mod h1:pIZgTWdm3k3pLF9Uq6MB8JEcW07UDwNJjlXW1HELW80= +github.com/ipfs/boxo v0.17.1-0.20240125173442-bf34cd0777d8 h1:/d+3/JOYsHS4Uo+6WIxu2oHHlM5WjWOySYItN9V+YHs= +github.com/ipfs/boxo v0.17.1-0.20240125173442-bf34cd0777d8/go.mod h1:pIZgTWdm3k3pLF9Uq6MB8JEcW07UDwNJjlXW1HELW80= github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs= github.com/ipfs/go-block-format v0.2.0/go.mod h1:+jpL11nFx5A/SPpsoBn6Bzkra/zaArfSmsknbPMYgzM= github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= From 0ea879b4a1d8bee9ca2ef52d44bc96942d87aa73 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Fri, 26 Jan 2024 11:20:34 +0100 Subject: [PATCH 1018/1212] feat: add Ipns.MaxCacheTTL --- config/ipns.go | 12 ++++++++++ core/coreapi/coreapi.go | 13 +++++++---- core/corehttp/gateway.go | 10 +++++--- core/node/groups.go | 4 ++-- core/node/ipns.go | 3 ++- docs/changelogs/v0.27.md | 4 ++++ docs/config.md | 32 +++++++++++++++++++++++++- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- test/dependencies/go.mod | 2 +- test/dependencies/go.sum | 4 ++-- 13 files changed, 76 insertions(+), 20 deletions(-) diff --git a/config/ipns.go b/config/ipns.go index d51910884..288421973 100644 --- a/config/ipns.go +++ b/config/ipns.go @@ -1,11 +1,23 @@ package config +import ( + "math" + "time" +) + +const ( + DefaultIpnsMaxCacheTTL = time.Duration(math.MaxInt64) +) + type Ipns struct { RepublishPeriod string RecordLifetime string ResolveCacheSize int + // MaxCacheTTL is the maximum duration IPNS entries are valid in the cache. + MaxCacheTTL *OptionalDuration `json:",omitempty"` + // Enable namesys pubsub (--enable-namesys-pubsub) UsePubsub Flag `json:",omitempty"` } diff --git a/core/coreapi/coreapi.go b/core/coreapi/coreapi.go index 3efe03778..0723ab659 100644 --- a/core/coreapi/coreapi.go +++ b/core/coreapi/coreapi.go @@ -26,6 +26,7 @@ import ( provider "github.com/ipfs/boxo/provider" offlineroute "github.com/ipfs/boxo/routing/offline" ipld "github.com/ipfs/go-ipld-format" + "github.com/ipfs/kubo/config" coreiface "github.com/ipfs/kubo/core/coreiface" "github.com/ipfs/kubo/core/coreiface/options" pubsub "github.com/libp2p/go-libp2p-pubsub" @@ -225,12 +226,16 @@ func (api *CoreAPI) WithOptions(opts ...options.ApiOption) (coreiface.CoreAPI, e return nil, fmt.Errorf("cannot specify negative resolve cache size") } - subAPI.routing = offlineroute.NewOfflineRouter(subAPI.repo.Datastore(), subAPI.recordValidator) - - subAPI.namesys, err = namesys.NewNameSystem(subAPI.routing, + nsOptions := []namesys.Option{ namesys.WithDatastore(subAPI.repo.Datastore()), namesys.WithDNSResolver(subAPI.dnsResolver), - namesys.WithCache(cs)) + namesys.WithCache(cs), + namesys.WithMaxCacheTTL(cfg.Ipns.MaxCacheTTL.WithDefault(config.DefaultIpnsMaxCacheTTL)), + } + + subAPI.routing = offlineroute.NewOfflineRouter(subAPI.repo.Datastore(), subAPI.recordValidator) + + subAPI.namesys, err = namesys.NewNameSystem(subAPI.routing, nsOptions...) if err != nil { return nil, fmt.Errorf("error constructing namesys: %w", err) } diff --git a/core/corehttp/gateway.go b/core/corehttp/gateway.go index c08d71806..67e3c242d 100644 --- a/core/corehttp/gateway.go +++ b/core/corehttp/gateway.go @@ -135,11 +135,15 @@ func newGatewayBackend(n *core.IpfsNode) (gateway.IPFSBackend, error) { return nil, fmt.Errorf("cannot specify negative resolve cache size") } - vsRouting = offlineroute.NewOfflineRouter(n.Repo.Datastore(), n.RecordValidator) - nsys, err = namesys.NewNameSystem(vsRouting, + nsOptions := []namesys.Option{ namesys.WithDatastore(n.Repo.Datastore()), namesys.WithDNSResolver(n.DNSResolver), - namesys.WithCache(cs)) + namesys.WithCache(cs), + namesys.WithMaxCacheTTL(cfg.Ipns.MaxCacheTTL.WithDefault(config.DefaultIpnsMaxCacheTTL)), + } + + vsRouting = offlineroute.NewOfflineRouter(n.Repo.Datastore(), n.RecordValidator) + nsys, err = namesys.NewNameSystem(vsRouting, nsOptions...) if err != nil { return nil, fmt.Errorf("error constructing namesys: %w", err) } diff --git a/core/node/groups.go b/core/node/groups.go index 4572a2ddd..061087c27 100644 --- a/core/node/groups.go +++ b/core/node/groups.go @@ -273,7 +273,7 @@ func Online(bcfg *BuildCfg, cfg *config.Config, userResourceOverrides rcmgr.Part fx.Provide(BitswapOptions(cfg, shouldBitswapProvide)), fx.Provide(OnlineExchange()), fx.Provide(DNSResolver), - fx.Provide(Namesys(ipnsCacheSize)), + fx.Provide(Namesys(ipnsCacheSize, cfg.Ipns.MaxCacheTTL.WithDefault(config.DefaultIpnsMaxCacheTTL))), fx.Provide(Peering), PeerWith(cfg.Peering.Peers...), @@ -296,7 +296,7 @@ func Offline(cfg *config.Config) fx.Option { return fx.Options( fx.Provide(offline.Exchange), fx.Provide(DNSResolver), - fx.Provide(Namesys(0)), + fx.Provide(Namesys(0, 0)), fx.Provide(libp2p.Routing), fx.Provide(libp2p.ContentRouting), fx.Provide(libp2p.OfflineRouting), diff --git a/core/node/ipns.go b/core/node/ipns.go index b1b5ee6e0..5f516d035 100644 --- a/core/node/ipns.go +++ b/core/node/ipns.go @@ -28,11 +28,12 @@ func RecordValidator(ps peerstore.Peerstore) record.Validator { } // Namesys creates new name system -func Namesys(cacheSize int) func(rt irouting.ProvideManyRouter, rslv *madns.Resolver, repo repo.Repo) (namesys.NameSystem, error) { +func Namesys(cacheSize int, cacheMaxTTL time.Duration) func(rt irouting.ProvideManyRouter, rslv *madns.Resolver, repo repo.Repo) (namesys.NameSystem, error) { return func(rt irouting.ProvideManyRouter, rslv *madns.Resolver, repo repo.Repo) (namesys.NameSystem, error) { opts := []namesys.Option{ namesys.WithDatastore(repo.Datastore()), namesys.WithDNSResolver(rslv), + namesys.WithMaxCacheTTL(cacheMaxTTL), } if cacheSize > 0 { diff --git a/docs/changelogs/v0.27.md b/docs/changelogs/v0.27.md index 1d7c5b101..26a607f8a 100644 --- a/docs/changelogs/v0.27.md +++ b/docs/changelogs/v0.27.md @@ -20,6 +20,10 @@ Support for exposing the legacy subset of Kubo RPC via the Gateway port is depre If you have a legacy software that relies on this behavior, and want to expose parts of `/api/v0` next to `/ipfs`, use reverse-proxy in front of Kubo to mount both Gateway and RPC on the same port. NOTE: exposing RPC to the internet comes with security risk: make sure to specify access control via [API.Authorizations](https://github.com/ipfs/kubo/blob/master/docs/config.md#apiauthorizations). +#### IPNS resolver cache's TTL can now be configured + +You can now configure the upper-bound of a cached IPNS entry's Time-To-Live via [`Ipns.MaxCacheTTL`](https://github.com/ipfs/kubo/blob/master/docs/config.md#ipnsmaxcachettl). + ### 📝 Changelog ### 👨‍👩‍👧‍👦 Contributors diff --git a/docs/config.md b/docs/config.md index d6c1567f1..82e5c0cdb 100644 --- a/docs/config.md +++ b/docs/config.md @@ -84,6 +84,7 @@ config file at runtime. - [`Ipns.RepublishPeriod`](#ipnsrepublishperiod) - [`Ipns.RecordLifetime`](#ipnsrecordlifetime) - [`Ipns.ResolveCacheSize`](#ipnsresolvecachesize) + - [`Ipns.MaxCacheTTL`](#ipnsmaxcachettl) - [`Ipns.UsePubsub`](#ipnsusepubsub) - [`Migration`](#migration) - [`Migration.DownloadSources`](#migrationdownloadsources) @@ -1138,6 +1139,35 @@ Default: `128` Type: `integer` (non-negative, 0 means the default) +### `Ipns.MaxCacheTTL` + +Maximum duration for which entries are valid in the name system cache. Applied +to everything under `/ipns/` namespace, allows you to cap +the [Time-To-Live (TTL)](https://specs.ipfs.tech/ipns/ipns-record/#ttl-uint64) of +[IPNS Records](https://specs.ipfs.tech/ipns/ipns-record/) +AND also DNSLink TXT records (when DoH-specific [`DNS.MaxCacheTTL`](https://github.com/ipfs/kubo/blob/master/docs/config.md#dnsmaxcachettl) +is not set to a lower value). + +When `Ipns.MaxCacheTTL` is set, it defines the upper bound limit of how long a +[IPNS Name](https://specs.ipfs.tech/ipns/ipns-record/#ipns-name) lookup result +will be cached and read from cache before checking for updates. + +**Examples:** +* `"1m"` IPNS results are cached 1m or less (good compromise for system where + faster updates are desired). +* `"0s"` IPNS caching is effectively turned off (useful for testing, bad for production use) + - **Note:** setting this to `0` will turn off TTL-based caching entirely. + This is discouraged in production environments. It will make IPNS websites + artificially slow because IPNS resolution results will expire as soon as + they are retrieved, forcing expensive IPNS lookup to happen on every + request. If you want near-real-time IPNS, set it to a low, but still + sensible value, such as `1m`. + +Default: No upper bound, [TTL from IPNS Record](https://specs.ipfs.tech/ipns/ipns-record/#ttl-uint64) (see `ipns name publish --help`) is always respected. + + +Type: `optionalDuration` + ### `Ipns.UsePubsub` Enables IPFS over pubsub experiment for publishing IPNS records in real time. @@ -2317,7 +2347,7 @@ If present, the upper bound is applied to DoH resolvers in [`DNS.Resolvers`](#dn Note: this does NOT work with Go's default DNS resolver. To make this a global setting, add a `.` entry to `DNS.Resolvers` first. **Examples:** -* `"5m"` DNS entries are kept for 5 minutes or less. +* `"1m"` DNS entries are kept for 1 minute or less. * `"0s"` DNS entries expire as soon as they are retrieved. Default: Respect DNS Response TTL diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index a134ccd25..edaed2de6 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.20 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.17.1-0.20240125173442-bf34cd0777d8 + github.com/ipfs/boxo v0.17.1-0.20240126101119-fdfcfcc0708a github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.32.2 github.com/multiformats/go-multiaddr v0.12.1 diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index f1b2b9a04..491ac004c 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -260,8 +260,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.17.1-0.20240125173442-bf34cd0777d8 h1:/d+3/JOYsHS4Uo+6WIxu2oHHlM5WjWOySYItN9V+YHs= -github.com/ipfs/boxo v0.17.1-0.20240125173442-bf34cd0777d8/go.mod h1:pIZgTWdm3k3pLF9Uq6MB8JEcW07UDwNJjlXW1HELW80= +github.com/ipfs/boxo v0.17.1-0.20240126101119-fdfcfcc0708a h1:BMxa0aXrjyGh5gAkzxVsjDN71YhAWGfjbOoNvZt4/jg= +github.com/ipfs/boxo v0.17.1-0.20240126101119-fdfcfcc0708a/go.mod h1:pIZgTWdm3k3pLF9Uq6MB8JEcW07UDwNJjlXW1HELW80= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.3/go.mod h1:4LmD4ZUw0mhO+JSKdpWwrzATiEfM7WWgQ8H5l6P8MVk= diff --git a/go.mod b/go.mod index 68cfbfa5d..5e85e91b5 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,7 @@ require ( github.com/hashicorp/go-multierror v1.1.1 github.com/ipfs-shipyard/nopfs v0.0.12 github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c - github.com/ipfs/boxo v0.17.1-0.20240125173442-bf34cd0777d8 + github.com/ipfs/boxo v0.17.1-0.20240126101119-fdfcfcc0708a github.com/ipfs/go-block-format v0.2.0 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 diff --git a/go.sum b/go.sum index e20297647..54243afb8 100644 --- a/go.sum +++ b/go.sum @@ -325,8 +325,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.17.1-0.20240125173442-bf34cd0777d8 h1:/d+3/JOYsHS4Uo+6WIxu2oHHlM5WjWOySYItN9V+YHs= -github.com/ipfs/boxo v0.17.1-0.20240125173442-bf34cd0777d8/go.mod h1:pIZgTWdm3k3pLF9Uq6MB8JEcW07UDwNJjlXW1HELW80= +github.com/ipfs/boxo v0.17.1-0.20240126101119-fdfcfcc0708a h1:BMxa0aXrjyGh5gAkzxVsjDN71YhAWGfjbOoNvZt4/jg= +github.com/ipfs/boxo v0.17.1-0.20240126101119-fdfcfcc0708a/go.mod h1:pIZgTWdm3k3pLF9Uq6MB8JEcW07UDwNJjlXW1HELW80= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index f069c1303..58735de6c 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -103,7 +103,7 @@ require ( github.com/hexops/gotextdiff v1.0.3 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/ipfs/bbloom v0.0.4 // indirect - github.com/ipfs/boxo v0.17.1-0.20240125173442-bf34cd0777d8 // indirect + github.com/ipfs/boxo v0.17.1-0.20240126101119-fdfcfcc0708a // indirect github.com/ipfs/go-block-format v0.2.0 // indirect github.com/ipfs/go-cid v0.4.1 // indirect github.com/ipfs/go-datastore v0.6.0 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 35a9ed955..98ef579f5 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -342,8 +342,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.17.1-0.20240125173442-bf34cd0777d8 h1:/d+3/JOYsHS4Uo+6WIxu2oHHlM5WjWOySYItN9V+YHs= -github.com/ipfs/boxo v0.17.1-0.20240125173442-bf34cd0777d8/go.mod h1:pIZgTWdm3k3pLF9Uq6MB8JEcW07UDwNJjlXW1HELW80= +github.com/ipfs/boxo v0.17.1-0.20240126101119-fdfcfcc0708a h1:BMxa0aXrjyGh5gAkzxVsjDN71YhAWGfjbOoNvZt4/jg= +github.com/ipfs/boxo v0.17.1-0.20240126101119-fdfcfcc0708a/go.mod h1:pIZgTWdm3k3pLF9Uq6MB8JEcW07UDwNJjlXW1HELW80= github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs= github.com/ipfs/go-block-format v0.2.0/go.mod h1:+jpL11nFx5A/SPpsoBn6Bzkra/zaArfSmsknbPMYgzM= github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= From 4d3cc96c1eaf9e180487f0eceff7352e0b089acb Mon Sep 17 00:00:00 2001 From: Jorropo Date: Fri, 26 Jan 2024 15:43:45 +0100 Subject: [PATCH 1019/1212] chore: update go-multiaddr 0.12.2 --- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- test/dependencies/go.mod | 2 +- test/dependencies/go.sum | 4 ++-- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index edaed2de6..25d7edb7c 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -10,7 +10,7 @@ require ( github.com/ipfs/boxo v0.17.1-0.20240126101119-fdfcfcc0708a github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.32.2 - github.com/multiformats/go-multiaddr v0.12.1 + github.com/multiformats/go-multiaddr v0.12.2 ) require ( diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 491ac004c..5db4134e8 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -497,8 +497,8 @@ github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a github.com/multiformats/go-multiaddr v0.1.0/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo= github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4= -github.com/multiformats/go-multiaddr v0.12.1 h1:vm+BA/WZA8QZDp1pF1FWhi5CT3g1tbi5GJmqpb6wnlk= -github.com/multiformats/go-multiaddr v0.12.1/go.mod h1:7mPkiBMmLeFipt+nNSq9pHZUeJSt8lHBgH6yhj0YQzE= +github.com/multiformats/go-multiaddr v0.12.2 h1:9G9sTY/wCYajKa9lyfWPmpZAwe6oV+Wb1zcmMS1HG24= +github.com/multiformats/go-multiaddr v0.12.2/go.mod h1:GKyaTYjZRdcUhyOetrxTk9z0cW+jA/YrnqTOvKgi44M= github.com/multiformats/go-multiaddr-dns v0.3.0/go.mod h1:mNzQ4eTGDg0ll1N9jKPOUogZPoJ30W8a7zk66FQPpdQ= github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A= github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk= diff --git a/go.mod b/go.mod index 5e85e91b5..efab059a3 100644 --- a/go.mod +++ b/go.mod @@ -58,7 +58,7 @@ require ( github.com/libp2p/go-libp2p-testing v0.12.0 github.com/libp2p/go-socket-activation v0.1.0 github.com/mitchellh/go-homedir v1.1.0 - github.com/multiformats/go-multiaddr v0.12.1 + github.com/multiformats/go-multiaddr v0.12.2 github.com/multiformats/go-multiaddr-dns v0.3.1 github.com/multiformats/go-multibase v0.2.0 github.com/multiformats/go-multicodec v0.9.0 diff --git a/go.sum b/go.sum index 54243afb8..35eefb2bb 100644 --- a/go.sum +++ b/go.sum @@ -606,8 +606,8 @@ github.com/multiformats/go-multiaddr v0.1.0/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lg github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo= github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4= github.com/multiformats/go-multiaddr v0.4.0/go.mod h1:YcpyLH8ZPudLxQlemYBPhSm0/oCXAT8Z4mzFpyoPyRc= -github.com/multiformats/go-multiaddr v0.12.1 h1:vm+BA/WZA8QZDp1pF1FWhi5CT3g1tbi5GJmqpb6wnlk= -github.com/multiformats/go-multiaddr v0.12.1/go.mod h1:7mPkiBMmLeFipt+nNSq9pHZUeJSt8lHBgH6yhj0YQzE= +github.com/multiformats/go-multiaddr v0.12.2 h1:9G9sTY/wCYajKa9lyfWPmpZAwe6oV+Wb1zcmMS1HG24= +github.com/multiformats/go-multiaddr v0.12.2/go.mod h1:GKyaTYjZRdcUhyOetrxTk9z0cW+jA/YrnqTOvKgi44M= github.com/multiformats/go-multiaddr-dns v0.3.0/go.mod h1:mNzQ4eTGDg0ll1N9jKPOUogZPoJ30W8a7zk66FQPpdQ= github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A= github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 58735de6c..d12db0cbc 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -14,7 +14,7 @@ require ( github.com/ipfs/iptb-plugins v0.5.0 github.com/jbenet/go-random v0.0.0-20190219211222-123a90aedc0c github.com/jbenet/go-random-files v0.0.0-20190219210431-31b3f20ebded - github.com/multiformats/go-multiaddr v0.12.1 + github.com/multiformats/go-multiaddr v0.12.2 github.com/multiformats/go-multihash v0.2.3 gotest.tools/gotestsum v0.4.2 ) diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 98ef579f5..7fd77f188 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -525,8 +525,8 @@ github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYg github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0= github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4= github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4= -github.com/multiformats/go-multiaddr v0.12.1 h1:vm+BA/WZA8QZDp1pF1FWhi5CT3g1tbi5GJmqpb6wnlk= -github.com/multiformats/go-multiaddr v0.12.1/go.mod h1:7mPkiBMmLeFipt+nNSq9pHZUeJSt8lHBgH6yhj0YQzE= +github.com/multiformats/go-multiaddr v0.12.2 h1:9G9sTY/wCYajKa9lyfWPmpZAwe6oV+Wb1zcmMS1HG24= +github.com/multiformats/go-multiaddr v0.12.2/go.mod h1:GKyaTYjZRdcUhyOetrxTk9z0cW+jA/YrnqTOvKgi44M= github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A= github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk= github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E= From fc52fbbb9d31132b9506cc5e30dc57a03de8bfca Mon Sep 17 00:00:00 2001 From: GitHub Date: Wed, 31 Jan 2024 17:33:46 +0000 Subject: [PATCH 1020/1212] chore: Update .github/workflows/stale.yml [skip ci] From 1a3b8d7077d4d96a928a271cc8391a16d591504a Mon Sep 17 00:00:00 2001 From: GitHub Date: Wed, 31 Jan 2024 17:35:17 +0000 Subject: [PATCH 1021/1212] chore: Update .github/dependabot.yml [skip ci] From efdef7fdcfeeb30e2f1ce3dbf65b6460b58afaaf Mon Sep 17 00:00:00 2001 From: galargh Date: Thu, 1 Feb 2024 13:13:36 +0000 Subject: [PATCH 1022/1212] chore: migrate from pl-strflt to ipdxco --- .github/workflows/gotest.yml | 6 +++--- .github/workflows/sharness.yml | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/gotest.yml b/.github/workflows/gotest.yml index c6b2cdc07..df5c5227e 100644 --- a/.github/workflows/gotest.yml +++ b/.github/workflows/gotest.yml @@ -73,7 +73,7 @@ jobs: mv go.sum.bak go.sum working-directory: docs/examples/kubo-as-a-library - name: Create a proper JUnit XML report - uses: pl-strflt/gotest-json-to-junit-xml@v1 + uses: ipdxco/gotest-json-to-junit-xml@v1 with: input: test/unit/gotest.json output: test/unit/gotest.junit.xml @@ -85,7 +85,7 @@ jobs: path: test/unit/gotest.junit.xml if: failure() || success() - name: Create a HTML report - uses: pl-strflt/junit-xml-to-html@v1 + uses: ipdxco/junit-xml-to-html@v1 with: mode: no-frames input: test/unit/gotest.junit.xml @@ -98,7 +98,7 @@ jobs: path: test/unit/gotest.html if: failure() || success() - name: Create a Markdown report - uses: pl-strflt/junit-xml-to-html@v1 + uses: ipdxco/junit-xml-to-html@v1 with: mode: summary input: test/unit/gotest.junit.xml diff --git a/.github/workflows/sharness.yml b/.github/workflows/sharness.yml index ec678e5ec..82db9e130 100644 --- a/.github/workflows/sharness.yml +++ b/.github/workflows/sharness.yml @@ -73,7 +73,7 @@ jobs: echo >> $GITHUB_STEP_SUMMARY cat kubo/test/sharness/test-results/summary.txt >> $GITHUB_STEP_SUMMARY - name: Generate one-page HTML report - uses: pl-strflt/junit-xml-to-html@v1 + uses: ipdxco/junit-xml-to-html@v1 if: failure() || success() with: mode: no-frames @@ -81,7 +81,7 @@ jobs: output: kubo/test/sharness/test-results/sharness.html - name: Upload one-page HTML report to S3 id: one-page - uses: pl-strflt/tf-aws-gh-runner/.github/actions/upload-artifact@main + uses: ipdxco/custom-github-runners/.github/actions/upload-artifact@main if: github.repository == 'ipfs/kubo' && (failure() || success()) with: source: kubo/test/sharness/test-results/sharness.html @@ -93,7 +93,7 @@ jobs: name: sharness.html path: kubo/test/sharness/test-results/sharness.html - name: Generate full HTML report - uses: pl-strflt/junit-xml-to-html@v1 + uses: ipdxco/junit-xml-to-html@v1 if: failure() || success() with: mode: frames @@ -101,7 +101,7 @@ jobs: output: kubo/test/sharness/test-results/sharness-html - name: Upload full HTML report to S3 id: full - uses: pl-strflt/tf-aws-gh-runner/.github/actions/upload-artifact@main + uses: ipdxco/custom-github-runners/.github/actions/upload-artifact@main if: github.repository == 'ipfs/kubo' && (failure() || success()) with: source: kubo/test/sharness/test-results/sharness-html From 162828986aecc7b91f1558ab9f98c361389dd822 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Feb 2024 21:55:02 +0000 Subject: [PATCH 1023/1212] chore(deps): bump codecov/codecov-action from 3.1.4 to 4.0.1 Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 3.1.4 to 4.0.1. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/eaaf4bedf32dbdc6b720b63067d99c4d77d6047d...e0b68c6749509c5f83f984dd99a76a1c1a231044) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/gotest.yml | 2 +- .github/workflows/sharness.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/gotest.yml b/.github/workflows/gotest.yml index df5c5227e..a69dbc2f0 100644 --- a/.github/workflows/gotest.yml +++ b/.github/workflows/gotest.yml @@ -45,7 +45,7 @@ jobs: make -j "$PARALLEL" test/unit/gotest.junit.xml && [[ ! $(jq -s -c 'map(select(.Action == "fail")) | .[]' test/unit/gotest.json) ]] - name: Upload coverage to Codecov - uses: codecov/codecov-action@eaaf4bedf32dbdc6b720b63067d99c4d77d6047d # v3.1.4 + uses: codecov/codecov-action@e0b68c6749509c5f83f984dd99a76a1c1a231044 # v4.0.1 if: failure() || success() with: name: unittests diff --git a/.github/workflows/sharness.yml b/.github/workflows/sharness.yml index 82db9e130..436ef34a1 100644 --- a/.github/workflows/sharness.yml +++ b/.github/workflows/sharness.yml @@ -55,7 +55,7 @@ jobs: # increasing parallelism beyond 10 doesn't speed up the tests much PARALLEL: ${{ github.repository == 'ipfs/kubo' && 10 || 3 }} - name: Upload coverage report - uses: codecov/codecov-action@eaaf4bedf32dbdc6b720b63067d99c4d77d6047d # v3.1.4 + uses: codecov/codecov-action@e0b68c6749509c5f83f984dd99a76a1c1a231044 # v4.0.1 if: failure() || success() with: name: sharness From dccbfcf6b5e5ff27fe164f54baeb00622b6a3286 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Tue, 6 Feb 2024 10:23:16 +0100 Subject: [PATCH 1024/1212] refactor: superfluous namespace test redirects (#10322) --- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- test/cli/gateway_test.go | 21 ++++----------------- test/dependencies/go.mod | 2 +- test/dependencies/go.sum | 4 ++-- 7 files changed, 13 insertions(+), 26 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 25d7edb7c..39fc74017 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.20 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.17.1-0.20240126101119-fdfcfcc0708a + github.com/ipfs/boxo v0.17.1-0.20240206084652-79cb4e2886d7 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.32.2 github.com/multiformats/go-multiaddr v0.12.2 diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 5db4134e8..a2fe7949e 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -260,8 +260,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.17.1-0.20240126101119-fdfcfcc0708a h1:BMxa0aXrjyGh5gAkzxVsjDN71YhAWGfjbOoNvZt4/jg= -github.com/ipfs/boxo v0.17.1-0.20240126101119-fdfcfcc0708a/go.mod h1:pIZgTWdm3k3pLF9Uq6MB8JEcW07UDwNJjlXW1HELW80= +github.com/ipfs/boxo v0.17.1-0.20240206084652-79cb4e2886d7 h1:1xhvfhNpPSJZ6GavPT6MuR15HhN4azBQvu7wsziJph4= +github.com/ipfs/boxo v0.17.1-0.20240206084652-79cb4e2886d7/go.mod h1:pIZgTWdm3k3pLF9Uq6MB8JEcW07UDwNJjlXW1HELW80= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.3/go.mod h1:4LmD4ZUw0mhO+JSKdpWwrzATiEfM7WWgQ8H5l6P8MVk= diff --git a/go.mod b/go.mod index efab059a3..39d2e31a6 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,7 @@ require ( github.com/hashicorp/go-multierror v1.1.1 github.com/ipfs-shipyard/nopfs v0.0.12 github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c - github.com/ipfs/boxo v0.17.1-0.20240126101119-fdfcfcc0708a + github.com/ipfs/boxo v0.17.1-0.20240206084652-79cb4e2886d7 github.com/ipfs/go-block-format v0.2.0 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 diff --git a/go.sum b/go.sum index 35eefb2bb..75720e193 100644 --- a/go.sum +++ b/go.sum @@ -325,8 +325,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.17.1-0.20240126101119-fdfcfcc0708a h1:BMxa0aXrjyGh5gAkzxVsjDN71YhAWGfjbOoNvZt4/jg= -github.com/ipfs/boxo v0.17.1-0.20240126101119-fdfcfcc0708a/go.mod h1:pIZgTWdm3k3pLF9Uq6MB8JEcW07UDwNJjlXW1HELW80= +github.com/ipfs/boxo v0.17.1-0.20240206084652-79cb4e2886d7 h1:1xhvfhNpPSJZ6GavPT6MuR15HhN4azBQvu7wsziJph4= +github.com/ipfs/boxo v0.17.1-0.20240206084652-79cb4e2886d7/go.mod h1:pIZgTWdm3k3pLF9Uq6MB8JEcW07UDwNJjlXW1HELW80= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= diff --git a/test/cli/gateway_test.go b/test/cli/gateway_test.go index c98c62c47..71fb38d41 100644 --- a/test/cli/gateway_test.go +++ b/test/cli/gateway_test.go @@ -158,14 +158,8 @@ func TestGateway(t *testing.T) { t.Run("GET /ipfs/ipfs/{cid} returns redirect to the valid path", func(t *testing.T) { t.Parallel() resp := client.Get("/ipfs/ipfs/bafkqaaa?query=to-remember") - assert.Contains(t, - resp.Body, - ``, - ) - assert.Contains(t, - resp.Body, - ``, - ) + assert.Equal(t, 301, resp.StatusCode) + assert.Equal(t, "/ipfs/bafkqaaa?query=to-remember", resp.Resp.Header.Get("Location")) }) }) @@ -200,15 +194,8 @@ func TestGateway(t *testing.T) { t.Run("GET /ipfs/ipns/{peerid} returns redirect to the valid path", func(t *testing.T) { t.Parallel() resp := client.Get("/ipfs/ipns/{{.PeerID}}?query=to-remember") - - assert.Contains(t, - resp.Body, - fmt.Sprintf(``, peerID), - ) - assert.Contains(t, - resp.Body, - fmt.Sprintf(``, peerID), - ) + assert.Equal(t, 301, resp.StatusCode) + assert.Equal(t, fmt.Sprintf("/ipns/%s?query=to-remember", peerID), resp.Resp.Header.Get("Location")) }) }) diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index d12db0cbc..426ef4871 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -103,7 +103,7 @@ require ( github.com/hexops/gotextdiff v1.0.3 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/ipfs/bbloom v0.0.4 // indirect - github.com/ipfs/boxo v0.17.1-0.20240126101119-fdfcfcc0708a // indirect + github.com/ipfs/boxo v0.17.1-0.20240206084652-79cb4e2886d7 // indirect github.com/ipfs/go-block-format v0.2.0 // indirect github.com/ipfs/go-cid v0.4.1 // indirect github.com/ipfs/go-datastore v0.6.0 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 7fd77f188..c6f48a845 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -342,8 +342,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.17.1-0.20240126101119-fdfcfcc0708a h1:BMxa0aXrjyGh5gAkzxVsjDN71YhAWGfjbOoNvZt4/jg= -github.com/ipfs/boxo v0.17.1-0.20240126101119-fdfcfcc0708a/go.mod h1:pIZgTWdm3k3pLF9Uq6MB8JEcW07UDwNJjlXW1HELW80= +github.com/ipfs/boxo v0.17.1-0.20240206084652-79cb4e2886d7 h1:1xhvfhNpPSJZ6GavPT6MuR15HhN4azBQvu7wsziJph4= +github.com/ipfs/boxo v0.17.1-0.20240206084652-79cb4e2886d7/go.mod h1:pIZgTWdm3k3pLF9Uq6MB8JEcW07UDwNJjlXW1HELW80= github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs= github.com/ipfs/go-block-format v0.2.0/go.mod h1:+jpL11nFx5A/SPpsoBn6Bzkra/zaArfSmsknbPMYgzM= github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= From 80973d87ccc189b3a23b01c1f02dbca4a840b462 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Wed, 31 Jan 2024 11:07:30 +0100 Subject: [PATCH 1025/1212] core: deprecate CoreAPI.Dht, introduce CoreAPI.Routing --- client/rpc/api.go | 2 + client/rpc/dht.go | 98 ++---------------- client/rpc/routing.go | 98 ++++++++++++++++++ core/coreapi/coreapi.go | 3 +- core/coreapi/dht.go | 140 ++----------------------- core/coreapi/routing.go | 155 ++++++++++++++++++++++++++-- core/coreiface/coreapi.go | 3 +- core/coreiface/dht.go | 18 ++-- core/coreiface/options/dht.go | 77 ++++---------- core/coreiface/options/routing.go | 71 ++++++++++++- core/coreiface/routing.go | 13 +++ core/coreiface/tests/api.go | 1 - core/coreiface/tests/dht.go | 166 ------------------------------ core/coreiface/tests/routing.go | 148 +++++++++++++++++++++++++- docs/changelogs/v0.27.md | 8 ++ docs/file-transfer.md | 4 +- test/cli/dht_opt_prov_test.go | 2 +- test/sharness/lib/test-lib.sh | 4 +- 18 files changed, 541 insertions(+), 470 deletions(-) delete mode 100644 core/coreiface/tests/dht.go diff --git a/client/rpc/api.go b/client/rpc/api.go index 48a80388f..827b427c9 100644 --- a/client/rpc/api.go +++ b/client/rpc/api.go @@ -227,6 +227,8 @@ func (api *HttpApi) Object() iface.ObjectAPI { return (*ObjectAPI)(api) } +// nolint deprecated +// Deprecated: use [HttpApi.Routing] instead. func (api *HttpApi) Dht() iface.DhtAPI { return (*DhtAPI)(api) } diff --git a/client/rpc/dht.go b/client/rpc/dht.go index 1b2c86398..cfc886a49 100644 --- a/client/rpc/dht.go +++ b/client/rpc/dht.go @@ -2,110 +2,30 @@ package rpc import ( "context" - "encoding/json" "github.com/ipfs/boxo/path" caopts "github.com/ipfs/kubo/core/coreiface/options" "github.com/libp2p/go-libp2p/core/peer" - "github.com/libp2p/go-libp2p/core/routing" ) type DhtAPI HttpApi +// nolint deprecated +// Deprecated: use [RoutingAPI.FindPeer] instead. func (api *DhtAPI) FindPeer(ctx context.Context, p peer.ID) (peer.AddrInfo, error) { - var out struct { - Type routing.QueryEventType - Responses []peer.AddrInfo - } - resp, err := api.core().Request("dht/findpeer", p.String()).Send(ctx) - if err != nil { - return peer.AddrInfo{}, err - } - if resp.Error != nil { - return peer.AddrInfo{}, resp.Error - } - defer resp.Close() - dec := json.NewDecoder(resp.Output) - for { - if err := dec.Decode(&out); err != nil { - return peer.AddrInfo{}, err - } - if out.Type == routing.FinalPeer { - return out.Responses[0], nil - } - } + return api.core().Routing().FindPeer(ctx, p) } +// nolint deprecated +// Deprecated: use [RoutingAPI.FindProviders] instead. func (api *DhtAPI) FindProviders(ctx context.Context, p path.Path, opts ...caopts.DhtFindProvidersOption) (<-chan peer.AddrInfo, error) { - options, err := caopts.DhtFindProvidersOptions(opts...) - if err != nil { - return nil, err - } - - rp, _, err := api.core().ResolvePath(ctx, p) - if err != nil { - return nil, err - } - - resp, err := api.core().Request("dht/findprovs", rp.RootCid().String()). - Option("num-providers", options.NumProviders). - Send(ctx) - if err != nil { - return nil, err - } - if resp.Error != nil { - return nil, resp.Error - } - res := make(chan peer.AddrInfo) - - go func() { - defer resp.Close() - defer close(res) - dec := json.NewDecoder(resp.Output) - - for { - var out struct { - Extra string - Type routing.QueryEventType - Responses []peer.AddrInfo - } - - if err := dec.Decode(&out); err != nil { - return // todo: handle this somehow - } - if out.Type == routing.QueryError { - return // usually a 'not found' error - // todo: handle other errors - } - if out.Type == routing.Provider { - for _, pi := range out.Responses { - select { - case res <- pi: - case <-ctx.Done(): - return - } - } - } - } - }() - - return res, nil + return api.core().Routing().FindProviders(ctx, p, opts...) } +// nolint deprecated +// Deprecated: use [RoutingAPI.Provide] instead. func (api *DhtAPI) Provide(ctx context.Context, p path.Path, opts ...caopts.DhtProvideOption) error { - options, err := caopts.DhtProvideOptions(opts...) - if err != nil { - return err - } - - rp, _, err := api.core().ResolvePath(ctx, p) - if err != nil { - return err - } - - return api.core().Request("dht/provide", rp.RootCid().String()). - Option("recursive", options.Recursive). - Exec(ctx, nil) + return api.core().Routing().Provide(ctx, p, opts...) } func (api *DhtAPI) core() *HttpApi { diff --git a/client/rpc/routing.go b/client/rpc/routing.go index 2ecf25f8b..693f155c6 100644 --- a/client/rpc/routing.go +++ b/client/rpc/routing.go @@ -6,7 +6,9 @@ import ( "encoding/base64" "encoding/json" + "github.com/ipfs/boxo/path" "github.com/ipfs/kubo/core/coreiface/options" + "github.com/libp2p/go-libp2p/core/peer" "github.com/libp2p/go-libp2p/core/routing" ) @@ -58,6 +60,102 @@ func (api *RoutingAPI) Put(ctx context.Context, key string, value []byte, opts . return nil } +func (api *RoutingAPI) FindPeer(ctx context.Context, p peer.ID) (peer.AddrInfo, error) { + var out struct { + Type routing.QueryEventType + Responses []peer.AddrInfo + } + resp, err := api.core().Request("routing/findpeer", p.String()).Send(ctx) + if err != nil { + return peer.AddrInfo{}, err + } + if resp.Error != nil { + return peer.AddrInfo{}, resp.Error + } + defer resp.Close() + dec := json.NewDecoder(resp.Output) + for { + if err := dec.Decode(&out); err != nil { + return peer.AddrInfo{}, err + } + if out.Type == routing.FinalPeer { + return out.Responses[0], nil + } + } +} + +func (api *RoutingAPI) FindProviders(ctx context.Context, p path.Path, opts ...options.RoutingFindProvidersOption) (<-chan peer.AddrInfo, error) { + options, err := options.RoutingFindProvidersOptions(opts...) + if err != nil { + return nil, err + } + + rp, _, err := api.core().ResolvePath(ctx, p) + if err != nil { + return nil, err + } + + resp, err := api.core().Request("routing/findprovs", rp.RootCid().String()). + Option("num-providers", options.NumProviders). + Send(ctx) + if err != nil { + return nil, err + } + if resp.Error != nil { + return nil, resp.Error + } + res := make(chan peer.AddrInfo) + + go func() { + defer resp.Close() + defer close(res) + dec := json.NewDecoder(resp.Output) + + for { + var out struct { + Extra string + Type routing.QueryEventType + Responses []peer.AddrInfo + } + + if err := dec.Decode(&out); err != nil { + return // todo: handle this somehow + } + if out.Type == routing.QueryError { + return // usually a 'not found' error + // todo: handle other errors + } + if out.Type == routing.Provider { + for _, pi := range out.Responses { + select { + case res <- pi: + case <-ctx.Done(): + return + } + } + } + } + }() + + return res, nil +} + +func (api *RoutingAPI) Provide(ctx context.Context, p path.Path, opts ...options.RoutingProvideOption) error { + options, err := options.RoutingProvideOptions(opts...) + if err != nil { + return err + } + + rp, _, err := api.core().ResolvePath(ctx, p) + if err != nil { + return err + } + + return api.core().Request("routing/provide", rp.RootCid().String()). + Option("recursive", options.Recursive). + Exec(ctx, nil) +} + func (api *RoutingAPI) core() *HttpApi { return (*HttpApi)(api) } diff --git a/core/coreapi/coreapi.go b/core/coreapi/coreapi.go index 0723ab659..6c6aa4907 100644 --- a/core/coreapi/coreapi.go +++ b/core/coreapi/coreapi.go @@ -130,7 +130,8 @@ func (api *CoreAPI) Pin() coreiface.PinAPI { return (*PinAPI)(api) } -// Dht returns the DhtAPI interface implementation backed by the go-ipfs node +// nolint deprecated +// Deprecated: use [CoreAPI.Routing] instead. func (api *CoreAPI) Dht() coreiface.DhtAPI { return (*DhtAPI)(api) } diff --git a/core/coreapi/dht.go b/core/coreapi/dht.go index 7b5d4eb84..f9155de00 100644 --- a/core/coreapi/dht.go +++ b/core/coreapi/dht.go @@ -2,151 +2,31 @@ package coreapi import ( "context" - "fmt" - blockservice "github.com/ipfs/boxo/blockservice" - blockstore "github.com/ipfs/boxo/blockstore" - offline "github.com/ipfs/boxo/exchange/offline" - dag "github.com/ipfs/boxo/ipld/merkledag" "github.com/ipfs/boxo/path" - cid "github.com/ipfs/go-cid" - cidutil "github.com/ipfs/go-cidutil" coreiface "github.com/ipfs/kubo/core/coreiface" caopts "github.com/ipfs/kubo/core/coreiface/options" - "github.com/ipfs/kubo/tracing" peer "github.com/libp2p/go-libp2p/core/peer" - routing "github.com/libp2p/go-libp2p/core/routing" - "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/trace" ) type DhtAPI CoreAPI +// nolint deprecated +// Deprecated: use [RoutingAPI.FindPeer] instead. func (api *DhtAPI) FindPeer(ctx context.Context, p peer.ID) (peer.AddrInfo, error) { - ctx, span := tracing.Span(ctx, "CoreAPI.DhtAPI", "FindPeer", trace.WithAttributes(attribute.String("peer", p.String()))) - defer span.End() - err := api.checkOnline(false) - if err != nil { - return peer.AddrInfo{}, err - } - - pi, err := api.routing.FindPeer(ctx, peer.ID(p)) - if err != nil { - return peer.AddrInfo{}, err - } - - return pi, nil + return api.core().Routing().FindPeer(ctx, p) } +// nolint deprecated +// Deprecated: use [RoutingAPI.FindProviders] instead. func (api *DhtAPI) FindProviders(ctx context.Context, p path.Path, opts ...caopts.DhtFindProvidersOption) (<-chan peer.AddrInfo, error) { - ctx, span := tracing.Span(ctx, "CoreAPI.DhtAPI", "FindProviders", trace.WithAttributes(attribute.String("path", p.String()))) - defer span.End() - - settings, err := caopts.DhtFindProvidersOptions(opts...) - if err != nil { - return nil, err - } - span.SetAttributes(attribute.Int("numproviders", settings.NumProviders)) - - err = api.checkOnline(false) - if err != nil { - return nil, err - } - - rp, _, err := api.core().ResolvePath(ctx, p) - if err != nil { - return nil, err - } - - numProviders := settings.NumProviders - if numProviders < 1 { - return nil, fmt.Errorf("number of providers must be greater than 0") - } - - pchan := api.routing.FindProvidersAsync(ctx, rp.RootCid(), numProviders) - return pchan, nil + return api.core().Routing().FindProviders(ctx, p, opts...) } -func (api *DhtAPI) Provide(ctx context.Context, path path.Path, opts ...caopts.DhtProvideOption) error { - ctx, span := tracing.Span(ctx, "CoreAPI.DhtAPI", "Provide", trace.WithAttributes(attribute.String("path", path.String()))) - defer span.End() - - settings, err := caopts.DhtProvideOptions(opts...) - if err != nil { - return err - } - span.SetAttributes(attribute.Bool("recursive", settings.Recursive)) - - err = api.checkOnline(false) - if err != nil { - return err - } - - rp, _, err := api.core().ResolvePath(ctx, path) - if err != nil { - return err - } - - c := rp.RootCid() - - has, err := api.blockstore.Has(ctx, c) - if err != nil { - return err - } - - if !has { - return fmt.Errorf("block %s not found locally, cannot provide", c) - } - - if settings.Recursive { - err = provideKeysRec(ctx, api.routing, api.blockstore, []cid.Cid{c}) - } else { - err = provideKeys(ctx, api.routing, []cid.Cid{c}) - } - if err != nil { - return err - } - - return nil -} - -func provideKeys(ctx context.Context, r routing.Routing, cids []cid.Cid) error { - for _, c := range cids { - err := r.Provide(ctx, c, true) - if err != nil { - return err - } - } - return nil -} - -func provideKeysRec(ctx context.Context, r routing.Routing, bs blockstore.Blockstore, cids []cid.Cid) error { - provided := cidutil.NewStreamingSet() - - errCh := make(chan error) - go func() { - dserv := dag.NewDAGService(blockservice.New(bs, offline.Exchange(bs))) - for _, c := range cids { - err := dag.Walk(ctx, dag.GetLinksDirect(dserv), c, provided.Visitor(ctx)) - if err != nil { - errCh <- err - } - } - }() - - for { - select { - case k := <-provided.New: - err := r.Provide(ctx, k, true) - if err != nil { - return err - } - case err := <-errCh: - return err - case <-ctx.Done(): - return ctx.Err() - } - } +// nolint deprecated +// Deprecated: use [RoutingAPI.Provide] instead. +func (api *DhtAPI) Provide(ctx context.Context, p path.Path, opts ...caopts.DhtProvideOption) error { + return api.core().Routing().Provide(ctx, p, opts...) } func (api *DhtAPI) core() coreiface.CoreAPI { diff --git a/core/coreapi/routing.go b/core/coreapi/routing.go index d784a738d..fe273158e 100644 --- a/core/coreapi/routing.go +++ b/core/coreapi/routing.go @@ -3,17 +3,29 @@ package coreapi import ( "context" "errors" + "fmt" "strings" + blockservice "github.com/ipfs/boxo/blockservice" + blockstore "github.com/ipfs/boxo/blockstore" + offline "github.com/ipfs/boxo/exchange/offline" + dag "github.com/ipfs/boxo/ipld/merkledag" + "github.com/ipfs/boxo/path" + cid "github.com/ipfs/go-cid" + cidutil "github.com/ipfs/go-cidutil" coreiface "github.com/ipfs/kubo/core/coreiface" caopts "github.com/ipfs/kubo/core/coreiface/options" + "github.com/ipfs/kubo/tracing" peer "github.com/libp2p/go-libp2p/core/peer" + routing "github.com/libp2p/go-libp2p/core/routing" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/trace" ) type RoutingAPI CoreAPI -func (r *RoutingAPI) Get(ctx context.Context, key string) ([]byte, error) { - if !r.nd.IsOnline { +func (api *RoutingAPI) Get(ctx context.Context, key string) ([]byte, error) { + if !api.nd.IsOnline { return nil, coreiface.ErrOffline } @@ -22,16 +34,16 @@ func (r *RoutingAPI) Get(ctx context.Context, key string) ([]byte, error) { return nil, err } - return r.routing.GetValue(ctx, dhtKey) + return api.routing.GetValue(ctx, dhtKey) } -func (r *RoutingAPI) Put(ctx context.Context, key string, value []byte, opts ...caopts.RoutingPutOption) error { +func (api *RoutingAPI) Put(ctx context.Context, key string, value []byte, opts ...caopts.RoutingPutOption) error { options, err := caopts.RoutingPutOptions(opts...) if err != nil { return err } - err = r.checkOnline(options.AllowOffline) + err = api.checkOnline(options.AllowOffline) if err != nil { return err } @@ -41,7 +53,7 @@ func (r *RoutingAPI) Put(ctx context.Context, key string, value []byte, opts ... return err } - return r.routing.PutValue(ctx, dhtKey, value) + return api.routing.PutValue(ctx, dhtKey, value) } func normalizeKey(s string) (string, error) { @@ -58,3 +70,134 @@ func normalizeKey(s string) (string, error) { } return strings.Join(append(parts[:2], string(k)), "/"), nil } + +func (api *RoutingAPI) FindPeer(ctx context.Context, p peer.ID) (peer.AddrInfo, error) { + ctx, span := tracing.Span(ctx, "CoreAPI.DhtAPI", "FindPeer", trace.WithAttributes(attribute.String("peer", p.String()))) + defer span.End() + err := api.checkOnline(false) + if err != nil { + return peer.AddrInfo{}, err + } + + pi, err := api.routing.FindPeer(ctx, peer.ID(p)) + if err != nil { + return peer.AddrInfo{}, err + } + + return pi, nil +} + +func (api *RoutingAPI) FindProviders(ctx context.Context, p path.Path, opts ...caopts.RoutingFindProvidersOption) (<-chan peer.AddrInfo, error) { + ctx, span := tracing.Span(ctx, "CoreAPI.DhtAPI", "FindProviders", trace.WithAttributes(attribute.String("path", p.String()))) + defer span.End() + + settings, err := caopts.RoutingFindProvidersOptions(opts...) + if err != nil { + return nil, err + } + span.SetAttributes(attribute.Int("numproviders", settings.NumProviders)) + + err = api.checkOnline(false) + if err != nil { + return nil, err + } + + rp, _, err := api.core().ResolvePath(ctx, p) + if err != nil { + return nil, err + } + + numProviders := settings.NumProviders + if numProviders < 1 { + return nil, fmt.Errorf("number of providers must be greater than 0") + } + + pchan := api.routing.FindProvidersAsync(ctx, rp.RootCid(), numProviders) + return pchan, nil +} + +func (api *RoutingAPI) Provide(ctx context.Context, path path.Path, opts ...caopts.RoutingProvideOption) error { + ctx, span := tracing.Span(ctx, "CoreAPI.DhtAPI", "Provide", trace.WithAttributes(attribute.String("path", path.String()))) + defer span.End() + + settings, err := caopts.RoutingProvideOptions(opts...) + if err != nil { + return err + } + span.SetAttributes(attribute.Bool("recursive", settings.Recursive)) + + err = api.checkOnline(false) + if err != nil { + return err + } + + rp, _, err := api.core().ResolvePath(ctx, path) + if err != nil { + return err + } + + c := rp.RootCid() + + has, err := api.blockstore.Has(ctx, c) + if err != nil { + return err + } + + if !has { + return fmt.Errorf("block %s not found locally, cannot provide", c) + } + + if settings.Recursive { + err = provideKeysRec(ctx, api.routing, api.blockstore, []cid.Cid{c}) + } else { + err = provideKeys(ctx, api.routing, []cid.Cid{c}) + } + if err != nil { + return err + } + + return nil +} + +func provideKeys(ctx context.Context, r routing.Routing, cids []cid.Cid) error { + for _, c := range cids { + err := r.Provide(ctx, c, true) + if err != nil { + return err + } + } + return nil +} + +func provideKeysRec(ctx context.Context, r routing.Routing, bs blockstore.Blockstore, cids []cid.Cid) error { + provided := cidutil.NewStreamingSet() + + errCh := make(chan error) + go func() { + dserv := dag.NewDAGService(blockservice.New(bs, offline.Exchange(bs))) + for _, c := range cids { + err := dag.Walk(ctx, dag.GetLinksDirect(dserv), c, provided.Visitor(ctx)) + if err != nil { + errCh <- err + } + } + }() + + for { + select { + case k := <-provided.New: + err := r.Provide(ctx, k, true) + if err != nil { + return err + } + case err := <-errCh: + return err + case <-ctx.Done(): + return ctx.Err() + } + } +} + +func (api *RoutingAPI) core() coreiface.CoreAPI { + return (*CoreAPI)(api) +} diff --git a/core/coreiface/coreapi.go b/core/coreiface/coreapi.go index 4fd6851af..bcd94f381 100644 --- a/core/coreiface/coreapi.go +++ b/core/coreiface/coreapi.go @@ -34,7 +34,8 @@ type CoreAPI interface { // Object returns an implementation of Object API Object() ObjectAPI - // Dht returns an implementation of Dht API + // nolint deprecated + // Deprecated: use [Routing] instead. Dht() DhtAPI // Swarm returns an implementation of Swarm API diff --git a/core/coreiface/dht.go b/core/coreiface/dht.go index a916dbf3d..001f5856a 100644 --- a/core/coreiface/dht.go +++ b/core/coreiface/dht.go @@ -4,24 +4,22 @@ import ( "context" "github.com/ipfs/boxo/path" - "github.com/ipfs/kubo/core/coreiface/options" - "github.com/libp2p/go-libp2p/core/peer" ) -// DhtAPI specifies the interface to the DHT -// Note: This API will likely get deprecated in near future, see -// https://github.com/ipfs/interface-ipfs-core/issues/249 for more context. +// nolint deprecated +// Deprecated: use [RoutingAPI] instead. type DhtAPI interface { - // FindPeer queries the DHT for all of the multiaddresses associated with a - // Peer ID + // nolint deprecated + // Deprecated: use [RoutingAPI.FindPeer] instead. FindPeer(context.Context, peer.ID) (peer.AddrInfo, error) - // FindProviders finds peers in the DHT who can provide a specific value - // given a key. + // nolint deprecated + // Deprecated: use [RoutingAPI.FindProviders] instead. FindProviders(context.Context, path.Path, ...options.DhtFindProvidersOption) (<-chan peer.AddrInfo, error) - // Provide announces to the network that you are providing given values + // nolint deprecated + // Deprecated: use [RoutingAPI.Provide] instead. Provide(context.Context, path.Path, ...options.DhtProvideOption) error } diff --git a/core/coreiface/options/dht.go b/core/coreiface/options/dht.go index b43bf3e7a..4a6f7f86e 100644 --- a/core/coreiface/options/dht.go +++ b/core/coreiface/options/dht.go @@ -1,64 +1,29 @@ package options -type DhtProvideSettings struct { - Recursive bool -} +// nolint deprecated +// Deprecated: use [RoutingProvideSettings] instead. +type DhtProvideSettings = RoutingProvideSettings -type DhtFindProvidersSettings struct { - NumProviders int -} +// nolint deprecated +// Deprecated: use [RoutingFindProvidersSettings] instead. +type DhtFindProvidersSettings = RoutingFindProvidersSettings -type ( - DhtProvideOption func(*DhtProvideSettings) error - DhtFindProvidersOption func(*DhtFindProvidersSettings) error -) +// nolint deprecated +// Deprecated: use [RoutingProvideOption] instead. +type DhtProvideOption = RoutingProvideOption -func DhtProvideOptions(opts ...DhtProvideOption) (*DhtProvideSettings, error) { - options := &DhtProvideSettings{ - Recursive: false, - } +// nolint deprecated +// Deprecated: use [RoutingFindProvidersOption] instead. +type DhtFindProvidersOption = RoutingFindProvidersOption - for _, opt := range opts { - err := opt(options) - if err != nil { - return nil, err - } - } - return options, nil -} +// nolint deprecated +// Deprecated: use [RoutingProvideOptions] instead. +var DhtProvideOptions = RoutingProvideOptions -func DhtFindProvidersOptions(opts ...DhtFindProvidersOption) (*DhtFindProvidersSettings, error) { - options := &DhtFindProvidersSettings{ - NumProviders: 20, - } +// nolint deprecated +// Deprecated: use [RoutingFindProvidersOptions] instead. +var DhtFindProvidersOptions = RoutingFindProvidersOptions - for _, opt := range opts { - err := opt(options) - if err != nil { - return nil, err - } - } - return options, nil -} - -type dhtOpts struct{} - -var Dht dhtOpts - -// Recursive is an option for Dht.Provide which specifies whether to provide -// the given path recursively -func (dhtOpts) Recursive(recursive bool) DhtProvideOption { - return func(settings *DhtProvideSettings) error { - settings.Recursive = recursive - return nil - } -} - -// NumProviders is an option for Dht.FindProviders which specifies the -// number of peers to look for. Default is 20 -func (dhtOpts) NumProviders(numProviders int) DhtFindProvidersOption { - return func(settings *DhtFindProvidersSettings) error { - settings.NumProviders = numProviders - return nil - } -} +// nolint deprecated +// Deprecated: use [Routing] instead. +var Dht = Routing diff --git a/core/coreiface/options/routing.go b/core/coreiface/options/routing.go index d66d44a0d..8da7e7a1d 100644 --- a/core/coreiface/options/routing.go +++ b/core/coreiface/options/routing.go @@ -21,13 +21,76 @@ func RoutingPutOptions(opts ...RoutingPutOption) (*RoutingPutSettings, error) { return options, nil } -type putOpts struct{} +// nolint deprecated +// Deprecated: use [Routing] instead. +var Put = Routing -var Put putOpts +type RoutingProvideSettings struct { + Recursive bool +} -// AllowOffline is an option for Routing.Put which specifies whether to allow +type RoutingFindProvidersSettings struct { + NumProviders int +} + +type ( + RoutingProvideOption func(*DhtProvideSettings) error + RoutingFindProvidersOption func(*DhtFindProvidersSettings) error +) + +func RoutingProvideOptions(opts ...RoutingProvideOption) (*RoutingProvideSettings, error) { + options := &RoutingProvideSettings{ + Recursive: false, + } + + for _, opt := range opts { + err := opt(options) + if err != nil { + return nil, err + } + } + return options, nil +} + +func RoutingFindProvidersOptions(opts ...RoutingFindProvidersOption) (*RoutingFindProvidersSettings, error) { + options := &RoutingFindProvidersSettings{ + NumProviders: 20, + } + + for _, opt := range opts { + err := opt(options) + if err != nil { + return nil, err + } + } + return options, nil +} + +type routingOpts struct{} + +var Routing routingOpts + +// Recursive is an option for [Routing.Provide] which specifies whether to provide +// the given path recursively. +func (routingOpts) Recursive(recursive bool) RoutingProvideOption { + return func(settings *DhtProvideSettings) error { + settings.Recursive = recursive + return nil + } +} + +// NumProviders is an option for [Routing.FindProviders] which specifies the +// number of peers to look for. Default is 20. +func (routingOpts) NumProviders(numProviders int) RoutingFindProvidersOption { + return func(settings *DhtFindProvidersSettings) error { + settings.NumProviders = numProviders + return nil + } +} + +// AllowOffline is an option for [Routing.Put] which specifies whether to allow // publishing when the node is offline. Default value is false -func (putOpts) AllowOffline(allow bool) RoutingPutOption { +func (routingOpts) AllowOffline(allow bool) RoutingPutOption { return func(settings *RoutingPutSettings) error { settings.AllowOffline = allow return nil diff --git a/core/coreiface/routing.go b/core/coreiface/routing.go index c64e7baef..a17dfcad9 100644 --- a/core/coreiface/routing.go +++ b/core/coreiface/routing.go @@ -3,7 +3,9 @@ package iface import ( "context" + "github.com/ipfs/boxo/path" "github.com/ipfs/kubo/core/coreiface/options" + "github.com/libp2p/go-libp2p/core/peer" ) // RoutingAPI specifies the interface to the routing layer. @@ -13,4 +15,15 @@ type RoutingAPI interface { // Put sets a value for a given key Put(ctx context.Context, key string, value []byte, opts ...options.RoutingPutOption) error + + // FindPeer queries the routing system for all the multiaddresses associated + // with the given [peer.ID]. + FindPeer(context.Context, peer.ID) (peer.AddrInfo, error) + + // FindProviders finds the peers in the routing system who can provide a specific + // value given a key. + FindProviders(context.Context, path.Path, ...options.RoutingFindProvidersOption) (<-chan peer.AddrInfo, error) + + // Provide announces to the network that you are providing given values + Provide(context.Context, path.Path, ...options.RoutingProvideOption) error } diff --git a/core/coreiface/tests/api.go b/core/coreiface/tests/api.go index c1fcb672d..86ab60ae9 100644 --- a/core/coreiface/tests/api.go +++ b/core/coreiface/tests/api.go @@ -75,7 +75,6 @@ func TestApi(p Provider) func(t *testing.T) { return func(t *testing.T) { t.Run("Block", tp.TestBlock) t.Run("Dag", tp.TestDag) - t.Run("Dht", tp.TestDht) t.Run("Key", tp.TestKey) t.Run("Name", tp.TestName) t.Run("Object", tp.TestObject) diff --git a/core/coreiface/tests/dht.go b/core/coreiface/tests/dht.go deleted file mode 100644 index 6a908c5d3..000000000 --- a/core/coreiface/tests/dht.go +++ /dev/null @@ -1,166 +0,0 @@ -package tests - -import ( - "context" - "io" - "testing" - "time" - - iface "github.com/ipfs/kubo/core/coreiface" - "github.com/ipfs/kubo/core/coreiface/options" -) - -func (tp *TestSuite) TestDht(t *testing.T) { - tp.hasApi(t, func(api iface.CoreAPI) error { - if api.Dht() == nil { - return errAPINotImplemented - } - return nil - }) - - t.Run("TestDhtFindPeer", tp.TestDhtFindPeer) - t.Run("TestDhtFindProviders", tp.TestDhtFindProviders) - t.Run("TestDhtProvide", tp.TestDhtProvide) -} - -func (tp *TestSuite) TestDhtFindPeer(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - apis, err := tp.MakeAPISwarm(t, ctx, 5) - if err != nil { - t.Fatal(err) - } - - self0, err := apis[0].Key().Self(ctx) - if err != nil { - t.Fatal(err) - } - - laddrs0, err := apis[0].Swarm().LocalAddrs(ctx) - if err != nil { - t.Fatal(err) - } - if len(laddrs0) != 1 { - t.Fatal("unexpected number of local addrs") - } - - time.Sleep(3 * time.Second) - - pi, err := apis[2].Dht().FindPeer(ctx, self0.ID()) - if err != nil { - t.Fatal(err) - } - - if pi.Addrs[0].String() != laddrs0[0].String() { - t.Errorf("got unexpected address from FindPeer: %s", pi.Addrs[0].String()) - } - - self2, err := apis[2].Key().Self(ctx) - if err != nil { - t.Fatal(err) - } - - pi, err = apis[1].Dht().FindPeer(ctx, self2.ID()) - if err != nil { - t.Fatal(err) - } - - laddrs2, err := apis[2].Swarm().LocalAddrs(ctx) - if err != nil { - t.Fatal(err) - } - if len(laddrs2) != 1 { - t.Fatal("unexpected number of local addrs") - } - - if pi.Addrs[0].String() != laddrs2[0].String() { - t.Errorf("got unexpected address from FindPeer: %s", pi.Addrs[0].String()) - } -} - -func (tp *TestSuite) TestDhtFindProviders(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - apis, err := tp.MakeAPISwarm(t, ctx, 5) - if err != nil { - t.Fatal(err) - } - - p, err := addTestObject(ctx, apis[0]) - if err != nil { - t.Fatal(err) - } - - time.Sleep(3 * time.Second) - - out, err := apis[2].Dht().FindProviders(ctx, p, options.Dht.NumProviders(1)) - if err != nil { - t.Fatal(err) - } - - provider := <-out - - self0, err := apis[0].Key().Self(ctx) - if err != nil { - t.Fatal(err) - } - - if provider.ID.String() != self0.ID().String() { - t.Errorf("got wrong provider: %s != %s", provider.ID.String(), self0.ID().String()) - } -} - -func (tp *TestSuite) TestDhtProvide(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - apis, err := tp.MakeAPISwarm(t, ctx, 5) - if err != nil { - t.Fatal(err) - } - - off0, err := apis[0].WithOptions(options.Api.Offline(true)) - if err != nil { - t.Fatal(err) - } - - s, err := off0.Block().Put(ctx, &io.LimitedReader{R: rnd, N: 4092}) - if err != nil { - t.Fatal(err) - } - - p := s.Path() - - time.Sleep(3 * time.Second) - - out, err := apis[2].Dht().FindProviders(ctx, p, options.Dht.NumProviders(1)) - if err != nil { - t.Fatal(err) - } - - _, ok := <-out - - if ok { - t.Fatal("did not expect to find any providers") - } - - self0, err := apis[0].Key().Self(ctx) - if err != nil { - t.Fatal(err) - } - - err = apis[0].Dht().Provide(ctx, p) - if err != nil { - t.Fatal(err) - } - - out, err = apis[2].Dht().FindProviders(ctx, p, options.Dht.NumProviders(1)) - if err != nil { - t.Fatal(err) - } - - provider := <-out - - if provider.ID.String() != self0.ID().String() { - t.Errorf("got wrong provider: %s != %s", provider.ID.String(), self0.ID().String()) - } -} diff --git a/core/coreiface/tests/routing.go b/core/coreiface/tests/routing.go index 3f1f95d75..753d49550 100644 --- a/core/coreiface/tests/routing.go +++ b/core/coreiface/tests/routing.go @@ -2,6 +2,7 @@ package tests import ( "context" + "io" "testing" "time" @@ -23,6 +24,9 @@ func (tp *TestSuite) TestRouting(t *testing.T) { t.Run("TestRoutingGet", tp.TestRoutingGet) t.Run("TestRoutingPut", tp.TestRoutingPut) t.Run("TestRoutingPutOffline", tp.TestRoutingPutOffline) + t.Run("TestRoutingFindPeer", tp.TestRoutingFindPeer) + t.Run("TestRoutingFindProviders", tp.TestRoutingFindProviders) + t.Run("TestRoutingProvide", tp.TestRoutingProvide) } func (tp *TestSuite) testRoutingPublishKey(t *testing.T, ctx context.Context, api iface.CoreAPI, opts ...options.NamePublishOption) (path.Path, ipns.Name) { @@ -95,6 +99,148 @@ func (tp *TestSuite) TestRoutingPutOffline(t *testing.T) { err = api.Routing().Put(ctx, ipns.NamespacePrefix+name.String(), data) require.Error(t, err, "this operation should fail because we are offline") - err = api.Routing().Put(ctx, ipns.NamespacePrefix+name.String(), data, options.Put.AllowOffline(true)) + err = api.Routing().Put(ctx, ipns.NamespacePrefix+name.String(), data, options.Routing.AllowOffline(true)) require.NoError(t, err) } + +func (tp *TestSuite) TestRoutingFindPeer(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + apis, err := tp.MakeAPISwarm(t, ctx, 5) + if err != nil { + t.Fatal(err) + } + + self0, err := apis[0].Key().Self(ctx) + if err != nil { + t.Fatal(err) + } + + laddrs0, err := apis[0].Swarm().LocalAddrs(ctx) + if err != nil { + t.Fatal(err) + } + if len(laddrs0) != 1 { + t.Fatal("unexpected number of local addrs") + } + + time.Sleep(3 * time.Second) + + pi, err := apis[2].Routing().FindPeer(ctx, self0.ID()) + if err != nil { + t.Fatal(err) + } + + if pi.Addrs[0].String() != laddrs0[0].String() { + t.Errorf("got unexpected address from FindPeer: %s", pi.Addrs[0].String()) + } + + self2, err := apis[2].Key().Self(ctx) + if err != nil { + t.Fatal(err) + } + + pi, err = apis[1].Routing().FindPeer(ctx, self2.ID()) + if err != nil { + t.Fatal(err) + } + + laddrs2, err := apis[2].Swarm().LocalAddrs(ctx) + if err != nil { + t.Fatal(err) + } + if len(laddrs2) != 1 { + t.Fatal("unexpected number of local addrs") + } + + if pi.Addrs[0].String() != laddrs2[0].String() { + t.Errorf("got unexpected address from FindPeer: %s", pi.Addrs[0].String()) + } +} + +func (tp *TestSuite) TestRoutingFindProviders(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + apis, err := tp.MakeAPISwarm(t, ctx, 5) + if err != nil { + t.Fatal(err) + } + + p, err := addTestObject(ctx, apis[0]) + if err != nil { + t.Fatal(err) + } + + time.Sleep(3 * time.Second) + + out, err := apis[2].Routing().FindProviders(ctx, p, options.Routing.NumProviders(1)) + if err != nil { + t.Fatal(err) + } + + provider := <-out + + self0, err := apis[0].Key().Self(ctx) + if err != nil { + t.Fatal(err) + } + + if provider.ID.String() != self0.ID().String() { + t.Errorf("got wrong provider: %s != %s", provider.ID.String(), self0.ID().String()) + } +} + +func (tp *TestSuite) TestRoutingProvide(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + apis, err := tp.MakeAPISwarm(t, ctx, 5) + if err != nil { + t.Fatal(err) + } + + off0, err := apis[0].WithOptions(options.Api.Offline(true)) + if err != nil { + t.Fatal(err) + } + + s, err := off0.Block().Put(ctx, &io.LimitedReader{R: rnd, N: 4092}) + if err != nil { + t.Fatal(err) + } + + p := s.Path() + + time.Sleep(3 * time.Second) + + out, err := apis[2].Routing().FindProviders(ctx, p, options.Routing.NumProviders(1)) + if err != nil { + t.Fatal(err) + } + + _, ok := <-out + + if ok { + t.Fatal("did not expect to find any providers") + } + + self0, err := apis[0].Key().Self(ctx) + if err != nil { + t.Fatal(err) + } + + err = apis[0].Routing().Provide(ctx, p) + if err != nil { + t.Fatal(err) + } + + out, err = apis[2].Routing().FindProviders(ctx, p, options.Routing.NumProviders(1)) + if err != nil { + t.Fatal(err) + } + + provider := <-out + + if provider.ID.String() != self0.ID().String() { + t.Errorf("got wrong provider: %s != %s", provider.ID.String(), self0.ID().String()) + } +} diff --git a/docs/changelogs/v0.27.md b/docs/changelogs/v0.27.md index 26a607f8a..6455822e1 100644 --- a/docs/changelogs/v0.27.md +++ b/docs/changelogs/v0.27.md @@ -7,6 +7,8 @@ - [Overview](#overview) - [🔦 Highlights](#-highlights) - [Gateway: support for `/api/v0` is deprecated](#gateway-support-for-apiv0-is-deprecated) + - [IPNS resolver cache's TTL can now be configured](#ipns-resolver-caches-ttl-can-now-be-configured) + - [RPC client: deprecated DHT API, added Routing API](#rpc-client-deprecated-dht-api-added-routing-api) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -24,6 +26,12 @@ If you have a legacy software that relies on this behavior, and want to expose p You can now configure the upper-bound of a cached IPNS entry's Time-To-Live via [`Ipns.MaxCacheTTL`](https://github.com/ipfs/kubo/blob/master/docs/config.md#ipnsmaxcachettl). +#### RPC client: deprecated DHT API, added Routing API + +The RPC client now includes a Routing API to match the available commands in `/api/v0/routing`. In addition, the DHT API has been marked as deprecated. + +In the next version, all DHT deprecated methods will be removed from the Go RPC client. + ### 📝 Changelog ### 👨‍👩‍👧‍👦 Contributors diff --git a/docs/file-transfer.md b/docs/file-transfer.md index a1a1d1c59..f81948d26 100644 --- a/docs/file-transfer.md +++ b/docs/file-transfer.md @@ -68,12 +68,12 @@ pitfalls that people run into) ### Checking providers When requesting content on ipfs, nodes search the DHT for 'provider records' to see who has what content. Let's manually do that on node B to make sure that -node B is able to determine that node A has the data. Run `ipfs dht findprovs +node B is able to determine that node A has the data. Run `ipfs routing findprovs `. We expect to see the peer ID of node A printed out. If this command returns nothing (or returns IDs that are not node A), then no record of A having the data exists on the network. This can happen if the data is added while node A does not have a daemon running. If this happens, you can run `ipfs -dht provide ` on node A to announce to the network that you have that +routing provide ` on node A to announce to the network that you have that hash. Then if you restart the `ipfs get` command, node B should now be able to tell that node A has the content it wants. If node A's peer ID showed up in the initial `findprovs` call, or manually providing the hash didn't resolve the diff --git a/test/cli/dht_opt_prov_test.go b/test/cli/dht_opt_prov_test.go index 5481315af..f7b492066 100644 --- a/test/cli/dht_opt_prov_test.go +++ b/test/cli/dht_opt_prov_test.go @@ -22,7 +22,7 @@ func TestDHTOptimisticProvide(t *testing.T) { nodes.StartDaemons().Connect() hash := nodes[0].IPFSAddStr(testutils.RandomStr(100)) - nodes[0].IPFS("dht", "provide", hash) + nodes[0].IPFS("routing", "provide", hash) res := nodes[1].IPFS("routing", "findprovs", "--num-providers=1", hash) assert.Equal(t, nodes[0].PeerID().String(), res.Stdout.Trimmed()) diff --git a/test/sharness/lib/test-lib.sh b/test/sharness/lib/test-lib.sh index bd8f7de9b..69fd2e66c 100644 --- a/test/sharness/lib/test-lib.sh +++ b/test/sharness/lib/test-lib.sh @@ -512,7 +512,7 @@ port_from_maddr() { findprovs_empty() { test_expect_success 'findprovs '$1' succeeds' ' - ipfsi 1 dht findprovs -n 1 '$1' > findprovsOut + ipfsi 1 routing findprovs -n 1 '$1' > findprovsOut ' test_expect_success "findprovs $1 output is empty" ' @@ -522,7 +522,7 @@ findprovs_empty() { findprovs_expect() { test_expect_success 'findprovs '$1' succeeds' ' - ipfsi 1 dht findprovs -n 1 '$1' > findprovsOut && + ipfsi 1 routing findprovs -n 1 '$1' > findprovsOut && echo '$2' > expected ' From 1ef8f83a410c78aa6b048999b35c3039212e9ec5 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Wed, 7 Feb 2024 10:56:30 +0100 Subject: [PATCH 1026/1212] core/commands: remove 'ipfs dht' commands, except 'query' (#10328) --- core/commands/commands_test.go | 5 -- core/commands/dht.go | 57 +------------ docs/changelogs/v0.27.md | 7 +- docs/file-transfer.md | 2 +- test/cli/basic_commands_test.go | 2 - test/cli/dht_legacy_test.go | 137 -------------------------------- 6 files changed, 8 insertions(+), 202 deletions(-) delete mode 100644 test/cli/dht_legacy_test.go diff --git a/core/commands/commands_test.go b/core/commands/commands_test.go index 00c09d77a..99cd07988 100644 --- a/core/commands/commands_test.go +++ b/core/commands/commands_test.go @@ -117,11 +117,6 @@ func TestCommands(t *testing.T) { "/dag/resolve", "/dag/stat", "/dht", - "/dht/findpeer", - "/dht/findprovs", - "/dht/get", - "/dht/provide", - "/dht/put", "/dht/query", "/routing", "/routing/put", diff --git a/core/commands/dht.go b/core/commands/dht.go index 95ac187f5..c86b6262f 100644 --- a/core/commands/dht.go +++ b/core/commands/dht.go @@ -21,65 +21,10 @@ var DhtCmd = &cmds.Command{ }, Subcommands: map[string]*cmds.Command{ - "query": queryDhtCmd, - "findprovs": findProvidersDhtCmd, - "findpeer": findPeerDhtCmd, - "get": getValueDhtCmd, - "put": putValueDhtCmd, - "provide": provideRefDhtCmd, + "query": queryDhtCmd, }, } -var findProvidersDhtCmd = &cmds.Command{ - Helptext: findProvidersRoutingCmd.Helptext, - Arguments: findProvidersRoutingCmd.Arguments, - Options: findProvidersRoutingCmd.Options, - Run: findProvidersRoutingCmd.Run, - Encoders: findProvidersRoutingCmd.Encoders, - Type: findProvidersRoutingCmd.Type, - Status: cmds.Deprecated, -} - -var findPeerDhtCmd = &cmds.Command{ - Helptext: findPeerRoutingCmd.Helptext, - Arguments: findPeerRoutingCmd.Arguments, - Options: findPeerRoutingCmd.Options, - Run: findPeerRoutingCmd.Run, - Encoders: findPeerRoutingCmd.Encoders, - Type: findPeerRoutingCmd.Type, - Status: cmds.Deprecated, -} - -var getValueDhtCmd = &cmds.Command{ - Helptext: getValueRoutingCmd.Helptext, - Arguments: getValueRoutingCmd.Arguments, - Options: getValueRoutingCmd.Options, - Run: getValueRoutingCmd.Run, - Encoders: getValueRoutingCmd.Encoders, - Type: getValueRoutingCmd.Type, - Status: cmds.Deprecated, -} - -var putValueDhtCmd = &cmds.Command{ - Helptext: putValueRoutingCmd.Helptext, - Arguments: putValueRoutingCmd.Arguments, - Options: putValueRoutingCmd.Options, - Run: putValueRoutingCmd.Run, - Encoders: putValueRoutingCmd.Encoders, - Type: putValueRoutingCmd.Type, - Status: cmds.Deprecated, -} - -var provideRefDhtCmd = &cmds.Command{ - Helptext: provideRefRoutingCmd.Helptext, - Arguments: provideRefRoutingCmd.Arguments, - Options: provideRefRoutingCmd.Options, - Run: provideRefRoutingCmd.Run, - Encoders: provideRefRoutingCmd.Encoders, - Type: provideRefRoutingCmd.Type, - Status: cmds.Deprecated, -} - // kademlia extends the routing interface with a command to get the peers closest to the target type kademlia interface { routing.Routing diff --git a/docs/changelogs/v0.27.md b/docs/changelogs/v0.27.md index 6455822e1..3d4df68ea 100644 --- a/docs/changelogs/v0.27.md +++ b/docs/changelogs/v0.27.md @@ -9,6 +9,7 @@ - [Gateway: support for `/api/v0` is deprecated](#gateway-support-for-apiv0-is-deprecated) - [IPNS resolver cache's TTL can now be configured](#ipns-resolver-caches-ttl-can-now-be-configured) - [RPC client: deprecated DHT API, added Routing API](#rpc-client-deprecated-dht-api-added-routing-api) + - [Deprecated DHT commands removed from `/api/v0/dht`](#deprecated-dht-commands-removed-from-apiv0dht) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -28,10 +29,14 @@ You can now configure the upper-bound of a cached IPNS entry's Time-To-Live via #### RPC client: deprecated DHT API, added Routing API -The RPC client now includes a Routing API to match the available commands in `/api/v0/routing`. In addition, the DHT API has been marked as deprecated. +The RPC client for GO (`kubo/client/rpc`) now includes a Routing API to match the available commands in `/api/v0/routing`. In addition, the DHT API has been marked as deprecated. In the next version, all DHT deprecated methods will be removed from the Go RPC client. +#### Deprecated DHT commands removed from `/api/v0/dht` + +All the DHT commands that were deprecated for over a year were finally removed from `/api/v0/dht`. Users should switch to modern `/api/v0/routing` which works with [both Amino DHT and Delegated Routers](https://github.com/ipfs/kubo/blob/master/docs/config.md#routing). + ### 📝 Changelog ### 👨‍👩‍👧‍👦 Contributors diff --git a/docs/file-transfer.md b/docs/file-transfer.md index f81948d26..e61ddc1b3 100644 --- a/docs/file-transfer.md +++ b/docs/file-transfer.md @@ -85,7 +85,7 @@ In the case where node B simply cannot form a connection to node A, despite knowing that it needs to, the likely culprit is a bad NAT. When node B learns that it needs to connect to node A, it checks the DHT for addresses for node A, and then starts trying to connect to them. We can check those addresses by -running `ipfs dht findpeer ` on node B. This command should +running `ipfs routing findpeer ` on node B. This command should return a list of addresses for node A. If it doesn't return any addresses, then you should try running the manual providing command from the previous steps. Example output of addresses might look something like this: diff --git a/test/cli/basic_commands_test.go b/test/cli/basic_commands_test.go index b4bb2c182..69b0cc63b 100644 --- a/test/cli/basic_commands_test.go +++ b/test/cli/basic_commands_test.go @@ -154,7 +154,6 @@ func TestCommandDocsWidth(t *testing.T) { "ipfs pin remote rm": true, "ipfs pin remote ls": true, "ipfs pin verify": true, - "ipfs dht get": true, "ipfs pin remote service add": true, "ipfs pin update": true, "ipfs pin rm": true, @@ -167,7 +166,6 @@ func TestCommandDocsWidth(t *testing.T) { "ipfs name": true, "ipfs object patch append-data": true, "ipfs object patch set-data": true, - "ipfs dht put": true, "ipfs diag profile": true, "ipfs diag cmds": true, "ipfs swarm addrs local": true, diff --git a/test/cli/dht_legacy_test.go b/test/cli/dht_legacy_test.go deleted file mode 100644 index cfcb4f0cd..000000000 --- a/test/cli/dht_legacy_test.go +++ /dev/null @@ -1,137 +0,0 @@ -package cli - -import ( - "sort" - "sync" - "testing" - - "github.com/ipfs/kubo/test/cli/harness" - "github.com/ipfs/kubo/test/cli/testutils" - "github.com/libp2p/go-libp2p/core/peer" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func TestLegacyDHT(t *testing.T) { - t.Parallel() - nodes := harness.NewT(t).NewNodes(5).Init() - nodes.ForEachPar(func(node *harness.Node) { - node.IPFS("config", "Routing.Type", "dht") - }) - nodes.StartDaemons().Connect() - - t.Run("ipfs dht findpeer", func(t *testing.T) { - t.Parallel() - res := nodes[1].RunIPFS("dht", "findpeer", nodes[0].PeerID().String()) - assert.Equal(t, 0, res.ExitCode()) - - swarmAddr := nodes[0].SwarmAddrsWithoutPeerIDs()[0] - require.Equal(t, swarmAddr.String(), res.Stdout.Trimmed()) - }) - - t.Run("ipfs dht get ", func(t *testing.T) { - t.Parallel() - hash := nodes[2].IPFSAddStr("hello world") - nodes[2].IPFS("name", "publish", "/ipfs/"+hash) - - res := nodes[1].IPFS("dht", "get", "/ipns/"+nodes[2].PeerID().String()) - assert.Contains(t, res.Stdout.String(), "/ipfs/"+hash) - - t.Run("put round trips (#3124)", func(t *testing.T) { - t.Parallel() - nodes[0].WriteBytes("get_result", res.Stdout.Bytes()) - res := nodes[0].IPFS("dht", "put", "/ipns/"+nodes[2].PeerID().String(), "get_result") - assert.Greater(t, len(res.Stdout.Lines()), 0, "should put to at least one node") - }) - - t.Run("put with bad keys fails (issue #5113, #4611)", func(t *testing.T) { - t.Parallel() - keys := []string{"foo", "/pk/foo", "/ipns/foo"} - for _, key := range keys { - key := key - t.Run(key, func(t *testing.T) { - t.Parallel() - res := nodes[0].RunIPFS("dht", "put", key) - assert.Equal(t, 1, res.ExitCode()) - assert.Contains(t, res.Stderr.String(), "invalid") - assert.Empty(t, res.Stdout.String()) - }) - } - }) - - t.Run("get with bad keys (issue #4611)", func(t *testing.T) { - for _, key := range []string{"foo", "/pk/foo"} { - key := key - t.Run(key, func(t *testing.T) { - t.Parallel() - res := nodes[0].RunIPFS("dht", "get", key) - assert.Equal(t, 1, res.ExitCode()) - assert.Contains(t, res.Stderr.String(), "invalid") - assert.Empty(t, res.Stdout.String()) - }) - } - }) - }) - - t.Run("ipfs dht findprovs", func(t *testing.T) { - t.Parallel() - hash := nodes[3].IPFSAddStr("some stuff") - res := nodes[4].IPFS("dht", "findprovs", hash) - assert.Equal(t, nodes[3].PeerID().String(), res.Stdout.Trimmed()) - }) - - t.Run("ipfs dht query ", func(t *testing.T) { - t.Parallel() - t.Run("normal DHT configuration", func(t *testing.T) { - t.Parallel() - hash := nodes[0].IPFSAddStr("some other stuff") - peerCounts := map[string]int{} - peerCountsMut := sync.Mutex{} - harness.Nodes(nodes).ForEachPar(func(node *harness.Node) { - res := node.IPFS("dht", "query", hash) - closestPeer := res.Stdout.Lines()[0] - // check that it's a valid peer ID - _, err := peer.Decode(closestPeer) - require.NoError(t, err) - - peerCountsMut.Lock() - peerCounts[closestPeer]++ - peerCountsMut.Unlock() - }) - // 4 nodes should see the same peer ID - // 1 node (the closest) should see a different one - var counts []int - for _, count := range peerCounts { - counts = append(counts, count) - } - sort.IntSlice(counts).Sort() - assert.Equal(t, []int{1, 4}, counts) - }) - }) - - t.Run("dht commands fail when offline", func(t *testing.T) { - t.Parallel() - node := harness.NewT(t).NewNode().Init() - - // these cannot be run in parallel due to repo locking (seems like a bug) - - t.Run("dht findprovs", func(t *testing.T) { - res := node.RunIPFS("dht", "findprovs", testutils.CIDEmptyDir) - assert.Equal(t, 1, res.ExitCode()) - assert.Contains(t, res.Stderr.String(), "this command must be run in online mode") - }) - - t.Run("dht findpeer", func(t *testing.T) { - res := node.RunIPFS("dht", "findpeer", testutils.CIDEmptyDir) - assert.Equal(t, 1, res.ExitCode()) - assert.Contains(t, res.Stderr.String(), "this command must be run in online mode") - }) - - t.Run("dht put", func(t *testing.T) { - node.WriteBytes("foo", []byte("foo")) - res := node.RunIPFS("dht", "put", "/ipns/"+node.PeerID().String(), "foo") - assert.Equal(t, 1, res.ExitCode()) - assert.Contains(t, res.Stderr.String(), "can't put while offline: pass `--allow-offline` to override") - }) - }) -} From f4ff4f76dd0d54b7a9da1fa1ac64b163ea3d3a18 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Tue, 6 Feb 2024 18:35:08 +0100 Subject: [PATCH 1027/1212] docs(config): mention routing v1 spec --- docs/config.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/config.md b/docs/config.md index 82e5c0cdb..735802907 100644 --- a/docs/config.md +++ b/docs/config.md @@ -1549,10 +1549,12 @@ To force a specific Amino DHT-only mode, client or server, set `Routing.Type` to unless you're sure your node is reachable from the public network. When `Routing.Type` is set to `auto` or `autoclient` your node will accelerate some types of routing -by leveraging HTTP endpoints compatible with [IPIP-337](https://github.com/ipfs/specs/pull/337) -in addition to the IPFS DHT. +by leveraging HTTP endpoints compatible with [Delegated Routing V1 HTTP API](https://specs.ipfs.tech/routing/http-routing-v1/) +introduced in [IPIP-337](https://github.com/ipfs/specs/pull/337) +in addition to the Amino DHT. By default, an instance of [IPNI](https://github.com/ipni/specs/blob/main/IPNI.md#readme) at https://cid.contact is used. + Alternative routing rules can be configured in `Routing.Routers` after setting `Routing.Type` to `custom`. Default: `auto` (DHT + IPNI) From eb7f6635145fb1be135d20b38585c7ec99c41fab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Mur=C3=A9?= Date: Thu, 19 Oct 2023 16:00:47 +0200 Subject: [PATCH 1028/1212] commands/add: return an error when using --only-hash and --to-files In that situation, the data is not written to permanent storage, so a reference in MFS would be to p2p blocks at best. The /add command in that situation is also likely to hang as it reads immediately the root node without being able to get it (it falls back to bitswap). --- core/commands/add.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/core/commands/add.go b/core/commands/add.go index 33d79a2eb..4e59cc867 100644 --- a/core/commands/add.go +++ b/core/commands/add.go @@ -194,7 +194,7 @@ See 'dag export' and 'dag import' for more information. progress, _ := req.Options[progressOptionName].(bool) trickle, _ := req.Options[trickleOptionName].(bool) wrap, _ := req.Options[wrapOptionName].(bool) - hash, _ := req.Options[onlyHashOptionName].(bool) + onlyHash, _ := req.Options[onlyHashOptionName].(bool) silent, _ := req.Options[silentOptionName].(bool) chunker, _ := req.Options[chunkerOptionName].(string) dopin, _ := req.Options[pinOptionName].(bool) @@ -207,6 +207,10 @@ See 'dag export' and 'dag import' for more information. inlineLimit, _ := req.Options[inlineLimitOptionName].(int) toFilesStr, toFilesSet := req.Options[toFilesOptionName].(string) + if onlyHash && toFilesSet { + return fmt.Errorf("%s and %s options are not compatible", onlyHashOptionName, toFilesOptionName) + } + hashFunCode, ok := mh.Names[strings.ToLower(hashFunStr)] if !ok { return fmt.Errorf("unrecognized hash function: %q", strings.ToLower(hashFunStr)) @@ -233,7 +237,7 @@ See 'dag export' and 'dag import' for more information. options.Unixfs.Chunker(chunker), options.Unixfs.Pin(dopin), - options.Unixfs.HashOnly(hash), + options.Unixfs.HashOnly(onlyHash), options.Unixfs.FsCache(fscache), options.Unixfs.Nocopy(nocopy), From 68f955664a43a760c886bf772d7923bf063e3830 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Fri, 9 Feb 2024 16:07:11 +0100 Subject: [PATCH 1029/1212] docs: clarify Gateway.ExposeRoutingAPI (#10337) * docs: clarify Gateway.ExposeRoutingAPI Closes #10195 * Apply suggestions from code review Co-authored-by: Daniel Norman <1992255+2color@users.noreply.github.com> --------- Co-authored-by: Henrique Dias Co-authored-by: Daniel Norman <1992255+2color@users.noreply.github.com> --- docs/config.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/docs/config.md b/docs/config.md index 735802907..d324bf093 100644 --- a/docs/config.md +++ b/docs/config.md @@ -762,11 +762,15 @@ Type: `flag` ### `Gateway.ExposeRoutingAPI` -An optional flag to expose Kubo `Routing` system on the gateway port as a [Routing -V1](https://specs.ipfs.tech/routing/routing-v1/) endpoint. This only affects your -local gateway, at `127.0.0.1`. +An optional flag to expose Kubo `Routing` system on the gateway port +as an [HTTP `/routing/v1`](https://specs.ipfs.tech/routing/routing-v1/) endpoint on `127.0.0.1`. +Use reverse proxy to expose it on a different hostname. -This endpoint can be used by other Kubo instance, as illustrated in [`delegated_routing_v1_http_proxy_test.go`](https://github.com/ipfs/kubo/blob/master/test/cli/delegated_routing_v1_http_proxy_test.go). +This endpoint can be used by other Kubo instances, as illustrated in +[`delegated_routing_v1_http_proxy_test.go`](https://github.com/ipfs/kubo/blob/master/test/cli/delegated_routing_v1_http_proxy_test.go). +Kubo will filter out routing results which are not actionable, for example, all +graphsync providers will be skipped. If you need a generic pass-through, see +standalone router implementation named [someguy](https://github.com/ipfs/someguy). Default: `false` From 15147850747b3a7471427c3b00cbe00a30a14c0b Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Fri, 9 Feb 2024 17:34:57 +0100 Subject: [PATCH 1030/1212] chore: fix link --- docs/config.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/config.md b/docs/config.md index d324bf093..ca24c2d0f 100644 --- a/docs/config.md +++ b/docs/config.md @@ -763,7 +763,7 @@ Type: `flag` ### `Gateway.ExposeRoutingAPI` An optional flag to expose Kubo `Routing` system on the gateway port -as an [HTTP `/routing/v1`](https://specs.ipfs.tech/routing/routing-v1/) endpoint on `127.0.0.1`. +as an [HTTP `/routing/v1`](https://specs.ipfs.tech/routing/http-routing-v1/) endpoint on `127.0.0.1`. Use reverse proxy to expose it on a different hostname. This endpoint can be used by other Kubo instances, as illustrated in From 595e1ba26857a3f694d5fb122045867b1e946dca Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Mon, 19 Feb 2024 14:20:58 +0100 Subject: [PATCH 1031/1212] repo/fsrepo/migrations: verified HTTP migrations (#10324) --- docs/changelogs/v0.27.md | 5 + docs/gateway.md | 12 +- go.mod | 1 + go.sum | 3 + repo/fsrepo/migrations/fetch_test.go | 78 ++------ repo/fsrepo/migrations/httpfetcher.go | 177 ++++++++++++++-- repo/fsrepo/migrations/migrations_test.go | 8 +- repo/fsrepo/migrations/setup_test.go | 233 ++++++++++++++++++++++ repo/fsrepo/migrations/versions_test.go | 8 +- test/sharness/t0003-docker-migrate.sh | 21 +- 10 files changed, 445 insertions(+), 101 deletions(-) create mode 100644 repo/fsrepo/migrations/setup_test.go diff --git a/docs/changelogs/v0.27.md b/docs/changelogs/v0.27.md index 3d4df68ea..0f9808a15 100644 --- a/docs/changelogs/v0.27.md +++ b/docs/changelogs/v0.27.md @@ -10,6 +10,7 @@ - [IPNS resolver cache's TTL can now be configured](#ipns-resolver-caches-ttl-can-now-be-configured) - [RPC client: deprecated DHT API, added Routing API](#rpc-client-deprecated-dht-api-added-routing-api) - [Deprecated DHT commands removed from `/api/v0/dht`](#deprecated-dht-commands-removed-from-apiv0dht) + - [Repository migrations are now trustless](#repository-migrations-are-now-trustless) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -37,6 +38,10 @@ In the next version, all DHT deprecated methods will be removed from the Go RPC All the DHT commands that were deprecated for over a year were finally removed from `/api/v0/dht`. Users should switch to modern `/api/v0/routing` which works with [both Amino DHT and Delegated Routers](https://github.com/ipfs/kubo/blob/master/docs/config.md#routing). +#### Repository migrations are now trustless + +Kubo now only uses [trustless requests](https://specs.ipfs.tech/http-gateways/trustless-gateway/) (e.g., CAR files) when downloading repository migrations via HTTP. This further strengthens Kubo by not delegating trust to public gateways. The migration binaries are locally verified before being executed. + ### 📝 Changelog ### 👨‍👩‍👧‍👦 Contributors diff --git a/docs/gateway.md b/docs/gateway.md index b24d10f0c..531c8c6f9 100644 --- a/docs/gateway.md +++ b/docs/gateway.md @@ -12,14 +12,18 @@ Kubo's Gateway implementation follows [ipfs/specs: Specification for HTTP Gatewa By default, Kubo nodes run a [path gateway](https://docs.ipfs.tech/how-to/address-ipfs-on-web/#path-gateway) at `http://127.0.0.1:8080/` -and a [subdomain gateway](https://docs.ipfs.tech/how-to/address-ipfs-on-web/#subdomain-gateway) at `http://localhost:8080/` +and a [subdomain gateway](https://docs.ipfs.tech/how-to/address-ipfs-on-web/#subdomain-gateway) at `http://localhost:8080/`. +Both support [trustless responses](https://docs.ipfs.tech/reference/http/gateway/#trustless-verifiable-retrieval) as opt-in via `Accept` header. Additional listening addresses and gateway behaviors can be set in the [config](#configuration) file. ### Public gateways -Protocol Labs provides a public gateway at `https://ipfs.io` (path) and `https://dweb.link` (subdomain). -If you've ever seen a link in the form `https://ipfs.io/ipfs/Qm...`, that's being served from *our* gateway. +Protocol Labs provides a public gateway at +`https://ipfs.io` ([path](https://specs.ipfs.tech/http-gateways/path-gateway/)), +`https://dweb.link` ([subdomain](https://docs.ipfs.tech/how-to/address-ipfs-on-web/#subdomain-gateway)), +and `https://trustless-gateway.link` ([trustless](https://specs.ipfs.tech/http-gateways/trustless-gateway/) only). +If you've ever seen a link in the form `https://ipfs.io/ipfs/Qm...`, that's being served from a *public goods* gateway. There is a list of third-party public gateways provided by the IPFS community at https://ipfs.github.io/public-gateway-checker/ @@ -105,7 +109,7 @@ This is a rough equivalent of `ipfs dag export`. ## Deprecated Subset of RPC API -For legacy reasons, the gateway port exposes a small subset of RPC API under `/api/v0/`. +For legacy reasons, some gateways may expose a small subset of RPC API under `/api/v0/`. While this read-only API exposes a read-only, "safe" subset of the normal API, it is deprecated and should not be used for greenfield projects. diff --git a/go.mod b/go.mod index 39d2e31a6..8d7cc5ff4 100644 --- a/go.mod +++ b/go.mod @@ -136,6 +136,7 @@ require ( github.com/ipfs/go-bitfield v1.1.0 // indirect github.com/ipfs/go-blockservice v0.5.0 // indirect github.com/ipfs/go-ipfs-blockstore v1.3.0 // indirect + github.com/ipfs/go-ipfs-chunker v0.0.5 // indirect github.com/ipfs/go-ipfs-delay v0.0.1 // indirect github.com/ipfs/go-ipfs-ds-help v1.1.0 // indirect github.com/ipfs/go-ipfs-exchange-interface v0.2.0 // indirect diff --git a/go.sum b/go.sum index 75720e193..cd6030b32 100644 --- a/go.sum +++ b/go.sum @@ -330,11 +330,13 @@ github.com/ipfs/boxo v0.17.1-0.20240206084652-79cb4e2886d7/go.mod h1:pIZgTWdm3k3 github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= +github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= github.com/ipfs/go-block-format v0.0.3/go.mod h1:4LmD4ZUw0mhO+JSKdpWwrzATiEfM7WWgQ8H5l6P8MVk= github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs= github.com/ipfs/go-block-format v0.2.0/go.mod h1:+jpL11nFx5A/SPpsoBn6Bzkra/zaArfSmsknbPMYgzM= github.com/ipfs/go-blockservice v0.5.0 h1:B2mwhhhVQl2ntW2EIpaWPwSCxSuqr5fFA93Ms4bYLEY= github.com/ipfs/go-blockservice v0.5.0/go.mod h1:W6brZ5k20AehbmERplmERn8o2Ni3ZZubvAxaIUeaT6w= +github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.3/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.4/go.mod h1:4LLaPOQwmk5z9LBgQnpkivrx8BJjUyGwTXCd5Xfj6+M= github.com/ipfs/go-cid v0.0.5/go.mod h1:plgt+Y5MnOey4vO4UlUazGqdbEXuFYitED67FexhXog= @@ -367,6 +369,7 @@ github.com/ipfs/go-ipfs-blockstore v1.3.0 h1:m2EXaWgwTzAfsmt5UdJ7Is6l4gJcaM/A12X github.com/ipfs/go-ipfs-blockstore v1.3.0/go.mod h1:KgtZyc9fq+P2xJUiCAzbRdhhqJHvsw8u2Dlqy2MyRTE= github.com/ipfs/go-ipfs-blocksutil v0.0.1 h1:Eh/H4pc1hsvhzsQoMEP3Bke/aW5P5rVM1IWFJMcGIPQ= github.com/ipfs/go-ipfs-chunker v0.0.5 h1:ojCf7HV/m+uS2vhUGWcogIIxiO5ubl5O57Q7NapWLY8= +github.com/ipfs/go-ipfs-chunker v0.0.5/go.mod h1:jhgdF8vxRHycr00k13FM8Y0E+6BoalYeobXmUyTreP8= github.com/ipfs/go-ipfs-cmds v0.10.0 h1:ZB4+RgYaH4UARfJY0uLKl5UXgApqnRjKbuCiJVcErYk= github.com/ipfs/go-ipfs-cmds v0.10.0/go.mod h1:sX5d7jkCft9XLPnkgEfXY0z2UBOB5g6fh/obBS0enJE= github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= diff --git a/repo/fsrepo/migrations/fetch_test.go b/repo/fsrepo/migrations/fetch_test.go index 27452d386..6e87c966b 100644 --- a/repo/fsrepo/migrations/fetch_test.go +++ b/repo/fsrepo/migrations/fetch_test.go @@ -5,56 +5,13 @@ import ( "bytes" "context" "fmt" - "io" - "net/http" - "net/http/httptest" "os" - "path" "path/filepath" "runtime" "strings" "testing" ) -func createTestServer() *httptest.Server { - reqHandler := func(w http.ResponseWriter, r *http.Request) { - defer r.Body.Close() - if strings.Contains(r.URL.Path, "not-here") { - http.NotFound(w, r) - } else if strings.HasSuffix(r.URL.Path, "versions") { - fmt.Fprint(w, "v1.0.0\nv1.1.0\nv1.1.2\nv2.0.0-rc1\n2.0.0\nv2.0.1\n") - } else if strings.HasSuffix(r.URL.Path, ".tar.gz") { - createFakeArchive(r.URL.Path, false, w) - } else if strings.HasSuffix(r.URL.Path, "zip") { - createFakeArchive(r.URL.Path, true, w) - } else { - http.NotFound(w, r) - } - } - return httptest.NewServer(http.HandlerFunc(reqHandler)) -} - -func createFakeArchive(name string, archZip bool, w io.Writer) { - fileName := strings.Split(path.Base(name), "_")[0] - root := path.Base(path.Dir(path.Dir(name))) - - // Simulate fetching go-ipfs, which has "ipfs" as the name in the archive. - if fileName == "go-ipfs" { - fileName = "ipfs" - } - fileName = ExeName(fileName) - - var err error - if archZip { - err = writeZip(root, fileName, "FAKE DATA", w) - } else { - err = writeTarGzip(root, fileName, "FAKE DATA", w) - } - if err != nil { - panic(err) - } -} - func TestGetDistPath(t *testing.T) { os.Unsetenv(envIpfsDistPath) distPath := GetDistPathEnv("") @@ -91,12 +48,9 @@ func TestHttpFetch(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - ts := createTestServer() - defer ts.Close() + fetcher := NewHttpFetcher(testIpfsDist, testServer.URL, "", 0) - fetcher := NewHttpFetcher("", ts.URL, "", 0) - - out, err := fetcher.Fetch(ctx, "/versions") + out, err := fetcher.Fetch(ctx, "/kubo/versions") if err != nil { t.Fatal(err) } @@ -120,7 +74,7 @@ func TestHttpFetch(t *testing.T) { // Check not found _, err = fetcher.Fetch(ctx, "/no_such_file") - if err == nil || !strings.Contains(err.Error(), "404") { + if err == nil || !strings.Contains(err.Error(), "no link") { t.Fatal("expected error 404") } } @@ -131,10 +85,7 @@ func TestFetchBinary(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - ts := createTestServer() - defer ts.Close() - - fetcher := NewHttpFetcher("", ts.URL, "", 0) + fetcher := NewHttpFetcher(testIpfsDist, testServer.URL, "", 0) vers, err := DistVersions(ctx, fetcher, distFSRM, false) if err != nil { @@ -154,7 +105,7 @@ func TestFetchBinary(t *testing.T) { t.Log("downloaded and unpacked", fi.Size(), "byte file:", fi.Name()) - bin, err = FetchBinary(ctx, fetcher, "go-ipfs", "v0.3.5", "ipfs", tmpDir) + bin, err = FetchBinary(ctx, fetcher, "go-ipfs", "v1.0.0", "ipfs", tmpDir) if err != nil { t.Fatal(err) } @@ -167,12 +118,12 @@ func TestFetchBinary(t *testing.T) { t.Log("downloaded and unpacked", fi.Size(), "byte file:", fi.Name()) // Check error is destination already exists and is not directory - _, err = FetchBinary(ctx, fetcher, "go-ipfs", "v0.3.5", "ipfs", bin) + _, err = FetchBinary(ctx, fetcher, "go-ipfs", "v1.0.0", "ipfs", bin) if !os.IsExist(err) { t.Fatal("expected 'exists' error, got", err) } - _, err = FetchBinary(ctx, fetcher, "go-ipfs", "v0.3.5", "ipfs", tmpDir) + _, err = FetchBinary(ctx, fetcher, "go-ipfs", "v1.0.0", "ipfs", tmpDir) if !os.IsExist(err) { t.Error("expected 'exists' error, got:", err) } @@ -192,7 +143,7 @@ func TestFetchBinary(t *testing.T) { if err != nil { panic(err) } - _, err = FetchBinary(ctx, fetcher, "go-ipfs", "v0.3.5", "ipfs", tmpDir) + _, err = FetchBinary(ctx, fetcher, "go-ipfs", "v1.0.0", "ipfs", tmpDir) if !os.IsPermission(err) { t.Error("expected 'permission' error, got:", err) } @@ -207,13 +158,13 @@ func TestFetchBinary(t *testing.T) { } // Check error if failure to fetch due to bad dist - _, err = FetchBinary(ctx, fetcher, "not-here", "v0.3.5", "ipfs", tmpDir) - if err == nil || !strings.Contains(err.Error(), "Not Found") { + _, err = FetchBinary(ctx, fetcher, "not-here", "v1.0.0", "ipfs", tmpDir) + if err == nil || !strings.Contains(err.Error(), "no link") { t.Error("expected 'Not Found' error, got:", err) } // Check error if failure to unpack archive - _, err = FetchBinary(ctx, fetcher, "go-ipfs", "v0.3.5", "not-such-bin", tmpDir) + _, err = FetchBinary(ctx, fetcher, "go-ipfs", "v1.0.0", "not-such-bin", tmpDir) if err == nil || err.Error() != "no binary found in archive" { t.Error("expected 'no binary found in archive' error") } @@ -223,15 +174,12 @@ func TestMultiFetcher(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - ts := createTestServer() - defer ts.Close() - badFetcher := NewHttpFetcher("", "bad-url", "", 0) - fetcher := NewHttpFetcher("", ts.URL, "", 0) + fetcher := NewHttpFetcher(testIpfsDist, testServer.URL, "", 0) mf := NewMultiFetcher(badFetcher, fetcher) - vers, err := mf.Fetch(ctx, "/versions") + vers, err := mf.Fetch(ctx, "/kubo/versions") if err != nil { t.Fatal(err) } diff --git a/repo/fsrepo/migrations/httpfetcher.go b/repo/fsrepo/migrations/httpfetcher.go index 9665a1e98..2ae180b1e 100644 --- a/repo/fsrepo/migrations/httpfetcher.go +++ b/repo/fsrepo/migrations/httpfetcher.go @@ -2,21 +2,40 @@ package migrations import ( "context" + "errors" "fmt" "io" "net/http" - "path" + gopath "path" "strings" + + "github.com/ipfs/boxo/blockservice" + "github.com/ipfs/boxo/blockstore" + "github.com/ipfs/boxo/exchange/offline" + bsfetcher "github.com/ipfs/boxo/fetcher/impl/blockservice" + files "github.com/ipfs/boxo/files" + "github.com/ipfs/boxo/ipld/merkledag" + unixfile "github.com/ipfs/boxo/ipld/unixfs/file" + "github.com/ipfs/boxo/ipns" + "github.com/ipfs/boxo/namesys" + "github.com/ipfs/boxo/path" + "github.com/ipfs/boxo/path/resolver" + "github.com/ipfs/go-datastore" + dssync "github.com/ipfs/go-datastore/sync" + "github.com/ipfs/go-unixfsnode" + gocarv2 "github.com/ipld/go-car/v2" + dagpb "github.com/ipld/go-codec-dagpb" + madns "github.com/multiformats/go-multiaddr-dns" ) const ( // default is different name than ipfs.io which is being blocked by some ISPs - defaultGatewayURL = "https://dweb.link" + defaultGatewayURL = "https://trustless-gateway.link" // Default maximum download size. defaultFetchLimit = 1024 * 1024 * 512 ) -// HttpFetcher fetches files over HTTP. +// HttpFetcher fetches files over HTTP using verifiable CAR archives. type HttpFetcher struct { //nolint distPath string gateway string @@ -26,7 +45,7 @@ type HttpFetcher struct { //nolint var _ Fetcher = (*HttpFetcher)(nil) -// NewHttpFetcher creates a new HttpFetcher +// NewHttpFetcher creates a new [HttpFetcher]. // // Specifying "" for distPath sets the default IPNS path. // Specifying "" for gateway sets the default. @@ -62,13 +81,89 @@ func NewHttpFetcher(distPath, gateway, userAgent string, fetchLimit int64) *Http // Fetch attempts to fetch the file at the given path, from the distribution // site configured for this HttpFetcher. func (f *HttpFetcher) Fetch(ctx context.Context, filePath string) ([]byte, error) { - gwURL := f.gateway + path.Join(f.distPath, filePath) - fmt.Printf("Fetching with HTTP: %q\n", gwURL) + imPath, err := f.resolvePath(ctx, gopath.Join(f.distPath, filePath)) + if err != nil { + return nil, fmt.Errorf("path could not be resolved: %w", err) + } - req, err := http.NewRequestWithContext(ctx, http.MethodGet, gwURL, nil) + rc, err := f.httpRequest(ctx, imPath, "application/vnd.ipld.car") + if err != nil { + return nil, fmt.Errorf("failed to fetch CAR: %w", err) + } + + return carStreamToFileBytes(ctx, rc, imPath) +} + +func (f *HttpFetcher) Close() error { + return nil +} + +func (f *HttpFetcher) resolvePath(ctx context.Context, pathStr string) (path.ImmutablePath, error) { + p, err := path.NewPath(pathStr) + if err != nil { + return path.ImmutablePath{}, fmt.Errorf("path is invalid: %w", err) + } + + for p.Mutable() { + // Download IPNS record and verify through the gateway, or resolve the + // DNSLink with the default DNS resolver. + name, err := ipns.NameFromString(p.Segments()[1]) + if err == nil { + p, err = f.resolveIPNS(ctx, name) + } else { + p, err = f.resolveDNSLink(ctx, p) + } + + if err != nil { + return path.ImmutablePath{}, err + } + } + + return path.NewImmutablePath(p) +} + +func (f *HttpFetcher) resolveIPNS(ctx context.Context, name ipns.Name) (path.Path, error) { + rc, err := f.httpRequest(ctx, name.AsPath(), "application/vnd.ipfs.ipns-record") + if err != nil { + return path.ImmutablePath{}, err + } + + rc = NewLimitReadCloser(rc, int64(ipns.MaxRecordSize)) + rawRecord, err := io.ReadAll(rc) + if err != nil { + return path.ImmutablePath{}, err + } + + rec, err := ipns.UnmarshalRecord(rawRecord) + if err != nil { + return path.ImmutablePath{}, err + } + + err = ipns.ValidateWithName(rec, name) + if err != nil { + return path.ImmutablePath{}, err + } + + return rec.Value() +} + +func (f *HttpFetcher) resolveDNSLink(ctx context.Context, p path.Path) (path.Path, error) { + dnsResolver := namesys.NewDNSResolver(madns.DefaultResolver.LookupTXT) + res, err := dnsResolver.Resolve(ctx, p) + if err != nil { + return nil, err + } + return res.Path, nil +} + +func (f *HttpFetcher) httpRequest(ctx context.Context, p path.Path, accept string) (io.ReadCloser, error) { + url := f.gateway + p.String() + fmt.Printf("Fetching with HTTP: %q\n", url) + req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) if err != nil { return nil, fmt.Errorf("http.NewRequest error: %w", err) } + req.Header.Set("Accept", accept) if f.userAgent != "" { req.Header.Set("User-Agent", f.userAgent) @@ -85,7 +180,7 @@ func (f *HttpFetcher) Fetch(ctx context.Context, filePath string) ([]byte, error if err != nil { return nil, fmt.Errorf("error reading error body: %w", err) } - return nil, fmt.Errorf("GET %s error: %s: %s", gwURL, resp.Status, string(mes)) + return nil, fmt.Errorf("GET %s error: %s: %s", url, resp.Status, string(mes)) } var rc io.ReadCloser @@ -94,11 +189,69 @@ func (f *HttpFetcher) Fetch(ctx context.Context, filePath string) ([]byte, error } else { rc = resp.Body } - defer rc.Close() - return io.ReadAll(rc) + return rc, nil } -func (f *HttpFetcher) Close() error { - return nil +func carStreamToFileBytes(ctx context.Context, r io.ReadCloser, imPath path.ImmutablePath) ([]byte, error) { + defer r.Close() + + // Create temporary block datastore and dag service. + dataStore := dssync.MutexWrap(datastore.NewMapDatastore()) + blockStore := blockstore.NewBlockstore(dataStore) + blockService := blockservice.New(blockStore, offline.Exchange(blockStore)) + dagService := merkledag.NewDAGService(blockService) + + defer dagService.Blocks.Close() + defer dataStore.Close() + + // Create CAR reader + car, err := gocarv2.NewBlockReader(r) + if err != nil { + fmt.Println(err) + return nil, fmt.Errorf("error creating car reader: %s", err) + } + + // Add all blocks to the blockstore. + for { + block, err := car.Next() + if err != nil && err != io.EOF { + return nil, fmt.Errorf("error reading block from car: %s", err) + } else if block == nil { + break + } + + err = blockStore.Put(ctx, block) + if err != nil { + return nil, fmt.Errorf("error putting block in blockstore: %s", err) + } + } + + fetcherCfg := bsfetcher.NewFetcherConfig(blockService) + fetcherCfg.PrototypeChooser = dagpb.AddSupportToChooser(bsfetcher.DefaultPrototypeChooser) + fetcher := fetcherCfg.WithReifier(unixfsnode.Reify) + resolver := resolver.NewBasicResolver(fetcher) + + cid, _, err := resolver.ResolveToLastNode(ctx, imPath) + if err != nil { + return nil, fmt.Errorf("failed to resolve: %w", err) + } + + nd, err := dagService.Get(ctx, cid) + if err != nil { + return nil, fmt.Errorf("failed to resolve: %w", err) + } + + // Make UnixFS file out of the node. + uf, err := unixfile.NewUnixfsFile(ctx, dagService, nd) + if err != nil { + return nil, fmt.Errorf("error building unixfs file: %s", err) + } + + // Check if it's a file and return. + if f, ok := uf.(files.File); ok { + return io.ReadAll(f) + } + + return nil, errors.New("unexpected unixfs node type") } diff --git a/repo/fsrepo/migrations/migrations_test.go b/repo/fsrepo/migrations/migrations_test.go index 2fd75b7e9..96370f864 100644 --- a/repo/fsrepo/migrations/migrations_test.go +++ b/repo/fsrepo/migrations/migrations_test.go @@ -110,9 +110,7 @@ func TestFetchMigrations(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - ts := createTestServer() - defer ts.Close() - fetcher := NewHttpFetcher(CurrentIpfsDist, ts.URL, "", 0) + fetcher := NewHttpFetcher(testIpfsDist, testServer.URL, "", 0) tmpDir := t.TempDir() @@ -162,9 +160,7 @@ func TestRunMigrations(t *testing.T) { t.Fatal(err) } - ts := createTestServer() - defer ts.Close() - fetcher := NewHttpFetcher(CurrentIpfsDist, ts.URL, "", 0) + fetcher := NewHttpFetcher(testIpfsDist, testServer.URL, "", 0) ctx, cancel := context.WithCancel(context.Background()) defer cancel() diff --git a/repo/fsrepo/migrations/setup_test.go b/repo/fsrepo/migrations/setup_test.go new file mode 100644 index 000000000..2e306fda1 --- /dev/null +++ b/repo/fsrepo/migrations/setup_test.go @@ -0,0 +1,233 @@ +package migrations + +import ( + "bytes" + "context" + "fmt" + "io" + "net/http/httptest" + "os" + "path" + "path/filepath" + "strings" + "testing" + + "github.com/ipfs/boxo/blockservice" + "github.com/ipfs/boxo/exchange/offline" + "github.com/ipfs/boxo/gateway" + blocks "github.com/ipfs/go-block-format" + "github.com/ipfs/go-cid" + "github.com/ipfs/go-unixfsnode/data/builder" + "github.com/ipld/go-car/v2" + carblockstore "github.com/ipld/go-car/v2/blockstore" + "github.com/ipld/go-ipld-prime" + cidlink "github.com/ipld/go-ipld-prime/linking/cid" + "github.com/multiformats/go-multicodec" + "github.com/multiformats/go-multihash" +) + +var ( + testIpfsDist string + testServer *httptest.Server +) + +func TestMain(m *testing.M) { + // Setup test data + testDataDir := makeTestData() + defer os.RemoveAll(testDataDir) + + testCar := makeTestCar(testDataDir) + defer os.RemoveAll(testCar) + + // Setup test gateway + fd := setupTestGateway(testCar) + defer fd.Close() + + // Run tests + os.Exit(m.Run()) +} + +func makeTestData() string { + tempDir, err := os.MkdirTemp("", "kubo-migrations-test-*") + if err != nil { + panic(err) + } + + versions := []string{"v1.0.0", "v1.1.0", "v1.1.2", "v2.0.0-rc1", "2.0.0", "v2.0.1"} + packages := []string{"kubo", "go-ipfs", "fs-repo-migrations", "fs-repo-1-to-2", "fs-repo-2-to-3", "fs-repo-9-to-10", "fs-repo-10-to-11"} + + // Generate fake data + for _, name := range packages { + err = os.MkdirAll(filepath.Join(tempDir, name), 0777) + if err != nil { + panic(err) + } + + err = os.WriteFile(filepath.Join(tempDir, name, "versions"), []byte(strings.Join(versions, "\n")+"\n"), 0666) + if err != nil { + panic(err) + } + + for _, version := range versions { + filename, archName := makeArchivePath(name, name, version, "tar.gz") + createFakeArchive(filepath.Join(tempDir, filename), archName, false) + + filename, archName = makeArchivePath(name, name, version, "zip") + createFakeArchive(filepath.Join(tempDir, filename), archName, true) + } + } + + return tempDir +} + +func createFakeArchive(archName, name string, archZip bool) { + err := os.MkdirAll(filepath.Dir(archName), 0777) + if err != nil { + panic(err) + } + + fileName := strings.Split(path.Base(name), "_")[0] + root := fileName + + // Simulate fetching go-ipfs, which has "ipfs" as the name in the archive. + if fileName == "go-ipfs" || fileName == "kubo" { + fileName = "ipfs" + } + fileName = ExeName(fileName) + + if archZip { + err = writeZipFile(archName, root, fileName, "FAKE DATA") + } else { + err = writeTarGzipFile(archName, root, fileName, "FAKE DATA") + } + if err != nil { + panic(err) + } +} + +// makeTestCar makes a CAR file with the directory [testData]. This code is mostly +// sourced from https://github.com/ipld/go-car/blob/1e2f0bd2c44ee31f48a8f602b25b5671cc0c4687/cmd/car/create.go +func makeTestCar(testData string) string { + // make a cid with the right length that we eventually will patch with the root. + hasher, err := multihash.GetHasher(multihash.SHA2_256) + if err != nil { + panic(err) + } + digest := hasher.Sum([]byte{}) + hash, err := multihash.Encode(digest, multihash.SHA2_256) + if err != nil { + panic(err) + } + proxyRoot := cid.NewCidV1(uint64(multicodec.DagPb), hash) + + // Make CAR file + fd, err := os.CreateTemp("", "kubo-migrations-test-*.car") + if err != nil { + panic(err) + } + defer fd.Close() + filename := fd.Name() + + rw, err := carblockstore.OpenReadWriteFile(fd, []cid.Cid{proxyRoot}, carblockstore.WriteAsCarV1(true)) + if err != nil { + panic(err) + } + defer rw.Close() + + ctx := context.Background() + + ls := cidlink.DefaultLinkSystem() + ls.TrustedStorage = true + ls.StorageReadOpener = func(_ ipld.LinkContext, l ipld.Link) (io.Reader, error) { + cl, ok := l.(cidlink.Link) + if !ok { + return nil, fmt.Errorf("not a cidlink") + } + blk, err := rw.Get(ctx, cl.Cid) + if err != nil { + return nil, err + } + return bytes.NewBuffer(blk.RawData()), nil + } + ls.StorageWriteOpener = func(_ ipld.LinkContext) (io.Writer, ipld.BlockWriteCommitter, error) { + buf := bytes.NewBuffer(nil) + return buf, func(l ipld.Link) error { + cl, ok := l.(cidlink.Link) + if !ok { + return fmt.Errorf("not a cidlink") + } + blk, err := blocks.NewBlockWithCid(buf.Bytes(), cl.Cid) + if err != nil { + return err + } + return rw.Put(ctx, blk) + }, nil + } + + l, _, err := builder.BuildUnixFSRecursive(testData, &ls) + if err != nil { + panic(err) + } + + rcl, ok := l.(cidlink.Link) + if !ok { + panic(fmt.Errorf("could not interpret %s", l)) + } + + if err := rw.Finalize(); err != nil { + panic(err) + } + // re-open/finalize with the final root. + err = car.ReplaceRootsInFile(filename, []cid.Cid{rcl.Cid}) + if err != nil { + panic(err) + } + + return filename +} + +func setupTestGateway(testCar string) io.Closer { + blockService, roots, fd, err := newBlockServiceFromCAR(testCar) + if err != nil { + panic(err) + } + + if len(roots) != 1 { + panic("expected car with 1 root") + } + + backend, err := gateway.NewBlocksBackend(blockService) + if err != nil { + panic(err) + } + conf := gateway.Config{ + NoDNSLink: false, + DeserializedResponses: false, + } + + testIpfsDist = "/ipfs/" + roots[0].String() + testServer = httptest.NewServer(gateway.NewHandler(conf, backend)) + + return fd +} + +func newBlockServiceFromCAR(filepath string) (blockservice.BlockService, []cid.Cid, io.Closer, error) { + r, err := os.Open(filepath) + if err != nil { + return nil, nil, nil, err + } + + bs, err := carblockstore.NewReadOnly(r, nil) + if err != nil { + _ = r.Close() + return nil, nil, nil, err + } + + roots, err := bs.Roots() + if err != nil { + return nil, nil, nil, err + } + + blockService := blockservice.New(bs, offline.Exchange(bs)) + return blockService, roots, r, nil +} diff --git a/repo/fsrepo/migrations/versions_test.go b/repo/fsrepo/migrations/versions_test.go index 18de72b77..dd62f9bde 100644 --- a/repo/fsrepo/migrations/versions_test.go +++ b/repo/fsrepo/migrations/versions_test.go @@ -13,9 +13,7 @@ func TestDistVersions(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - ts := createTestServer() - defer ts.Close() - fetcher := NewHttpFetcher("", ts.URL, "", 0) + fetcher := NewHttpFetcher(testIpfsDist, testServer.URL, "", 0) vers, err := DistVersions(ctx, fetcher, testDist, true) if err != nil { @@ -32,9 +30,7 @@ func TestLatestDistVersion(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - ts := createTestServer() - defer ts.Close() - fetcher := NewHttpFetcher("", ts.URL, "", 0) + fetcher := NewHttpFetcher(testIpfsDist, testServer.URL, "", 0) latest, err := LatestDistVersion(ctx, fetcher, testDist, false) if err != nil { diff --git a/test/sharness/t0003-docker-migrate.sh b/test/sharness/t0003-docker-migrate.sh index ac3c7aee2..c2c7ce969 100755 --- a/test/sharness/t0003-docker-migrate.sh +++ b/test/sharness/t0003-docker-migrate.sh @@ -36,15 +36,20 @@ test_expect_success "configure migration sources" ' ipfs config --json Migration.DownloadSources "[\"http://127.0.0.1:17233\"]" ' -test_expect_success "make repo be version 4" ' - echo 4 > "$IPFS_PATH/version" +test_expect_success "setup http response" ' + mkdir migration && + echo "v1.1.1" > migration/versions && + mkdir -p migration/fs-repo-6-to-7 && + echo "v1.1.1" > migration/fs-repo-6-to-7/versions && + CID=$(ipfs add -r -Q migration) && + echo "HTTP/1.1 200 OK" > vers_resp && + echo "Content-Type: application/vnd.ipld.car" >> vers_resp && + echo "" >> vers_resp && + ipfs dag export $CID >> vers_resp ' -test_expect_success "setup http response" ' - echo "HTTP/1.1 200 OK" > vers_resp && - echo "Content-Length: 7" >> vers_resp && - echo "" >> vers_resp && - echo "v1.1.1" >> vers_resp +test_expect_success "make repo be version 4" ' + echo 4 > "$IPFS_PATH/version" ' test_expect_success "startup fake dists server" ' @@ -53,7 +58,7 @@ test_expect_success "startup fake dists server" ' ' test_expect_success "docker image runs" ' - DOC_ID=$(docker run -d -v "$IPFS_PATH":/data/ipfs --net=host "$IMAGE_TAG") + DOC_ID=$(docker run -d -v "$IPFS_PATH":/data/ipfs -e IPFS_DIST_PATH=/ipfs/$CID --net=host "$IMAGE_TAG") ' test_expect_success "docker container tries to pull migrations from netcat" ' From 1d659ea08cb74aa8cb04f73594110212b37a60b8 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Tue, 20 Feb 2024 10:02:59 +0100 Subject: [PATCH 1032/1212] chore: boxo v0.18.0 (#10343) --- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- test/dependencies/go.mod | 2 +- test/dependencies/go.sum | 4 ++-- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 39fc74017..07c7afcd7 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.20 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.17.1-0.20240206084652-79cb4e2886d7 + github.com/ipfs/boxo v0.18.0 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.32.2 github.com/multiformats/go-multiaddr v0.12.2 diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index a2fe7949e..c9d1b3fb1 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -260,8 +260,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.17.1-0.20240206084652-79cb4e2886d7 h1:1xhvfhNpPSJZ6GavPT6MuR15HhN4azBQvu7wsziJph4= -github.com/ipfs/boxo v0.17.1-0.20240206084652-79cb4e2886d7/go.mod h1:pIZgTWdm3k3pLF9Uq6MB8JEcW07UDwNJjlXW1HELW80= +github.com/ipfs/boxo v0.18.0 h1:MOL9/AgoV3e7jlVMInicaSdbgralfqSsbkc31dZ9tmw= +github.com/ipfs/boxo v0.18.0/go.mod h1:pIZgTWdm3k3pLF9Uq6MB8JEcW07UDwNJjlXW1HELW80= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.3/go.mod h1:4LmD4ZUw0mhO+JSKdpWwrzATiEfM7WWgQ8H5l6P8MVk= diff --git a/go.mod b/go.mod index 8d7cc5ff4..a0d60bda2 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,7 @@ require ( github.com/hashicorp/go-multierror v1.1.1 github.com/ipfs-shipyard/nopfs v0.0.12 github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c - github.com/ipfs/boxo v0.17.1-0.20240206084652-79cb4e2886d7 + github.com/ipfs/boxo v0.18.0 github.com/ipfs/go-block-format v0.2.0 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 diff --git a/go.sum b/go.sum index cd6030b32..259e0eab8 100644 --- a/go.sum +++ b/go.sum @@ -325,8 +325,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.17.1-0.20240206084652-79cb4e2886d7 h1:1xhvfhNpPSJZ6GavPT6MuR15HhN4azBQvu7wsziJph4= -github.com/ipfs/boxo v0.17.1-0.20240206084652-79cb4e2886d7/go.mod h1:pIZgTWdm3k3pLF9Uq6MB8JEcW07UDwNJjlXW1HELW80= +github.com/ipfs/boxo v0.18.0 h1:MOL9/AgoV3e7jlVMInicaSdbgralfqSsbkc31dZ9tmw= +github.com/ipfs/boxo v0.18.0/go.mod h1:pIZgTWdm3k3pLF9Uq6MB8JEcW07UDwNJjlXW1HELW80= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 426ef4871..ef6eb0f52 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -103,7 +103,7 @@ require ( github.com/hexops/gotextdiff v1.0.3 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/ipfs/bbloom v0.0.4 // indirect - github.com/ipfs/boxo v0.17.1-0.20240206084652-79cb4e2886d7 // indirect + github.com/ipfs/boxo v0.18.0 // indirect github.com/ipfs/go-block-format v0.2.0 // indirect github.com/ipfs/go-cid v0.4.1 // indirect github.com/ipfs/go-datastore v0.6.0 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index c6f48a845..095dfb022 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -342,8 +342,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.17.1-0.20240206084652-79cb4e2886d7 h1:1xhvfhNpPSJZ6GavPT6MuR15HhN4azBQvu7wsziJph4= -github.com/ipfs/boxo v0.17.1-0.20240206084652-79cb4e2886d7/go.mod h1:pIZgTWdm3k3pLF9Uq6MB8JEcW07UDwNJjlXW1HELW80= +github.com/ipfs/boxo v0.18.0 h1:MOL9/AgoV3e7jlVMInicaSdbgralfqSsbkc31dZ9tmw= +github.com/ipfs/boxo v0.18.0/go.mod h1:pIZgTWdm3k3pLF9Uq6MB8JEcW07UDwNJjlXW1HELW80= github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs= github.com/ipfs/go-block-format v0.2.0/go.mod h1:+jpL11nFx5A/SPpsoBn6Bzkra/zaArfSmsknbPMYgzM= github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= From e6c7032ab7789c25ebaf76bcc61fbe7ca8225f83 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Tue, 20 Feb 2024 09:07:07 +0000 Subject: [PATCH 1033/1212] chore: update version --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index d5b0642f8..811e491d1 100644 --- a/version.go +++ b/version.go @@ -11,7 +11,7 @@ import ( var CurrentCommit string // CurrentVersionNumber is the current application's version literal. -const CurrentVersionNumber = "0.27.0-dev" +const CurrentVersionNumber = "0.27.0-rc1" const ApiVersion = "/kubo/" + CurrentVersionNumber + "/" //nolint From 35609d608bc68e42bd04a1faf547211b3f37c3b4 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Tue, 20 Feb 2024 09:08:11 +0000 Subject: [PATCH 1034/1212] chore: update version --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index d5b0642f8..a88bf87d2 100644 --- a/version.go +++ b/version.go @@ -11,7 +11,7 @@ import ( var CurrentCommit string // CurrentVersionNumber is the current application's version literal. -const CurrentVersionNumber = "0.27.0-dev" +const CurrentVersionNumber = "0.28.0-dev" const ApiVersion = "/kubo/" + CurrentVersionNumber + "/" //nolint From 9ea10752f251171f0aed4822d6cfd4c1674018c4 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Tue, 20 Feb 2024 11:50:37 +0100 Subject: [PATCH 1035/1212] docs: improve release issue template --- docs/RELEASE_ISSUE_TEMPLATE.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/RELEASE_ISSUE_TEMPLATE.md b/docs/RELEASE_ISSUE_TEMPLATE.md index 52f02fb50..cfa975943 100644 --- a/docs/RELEASE_ISSUE_TEMPLATE.md +++ b/docs/RELEASE_ISSUE_TEMPLATE.md @@ -1,4 +1,4 @@ - + # Items to do upon creating the release issue @@ -22,6 +22,7 @@ * Expected RC date: week of YYYY-MM-DD * 🚢 Expected final release date: YYYY-MM-DD * Release PR: +* Thunderdome PR: * Accompanying PR for improving the release process: ([example](https://github.com/ipfs/kubo/pull/9391)) * Changelog: https://github.com/ipfs/kubo/blob/master/docs/changelogs/vX.Y.md From cd6d5c0828bc332fc2d286a01ca5d5458a71c000 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Tue, 27 Feb 2024 09:45:57 +0100 Subject: [PATCH 1036/1212] chore: bump to go-libp2p 0.33 --- docs/examples/kubo-as-a-library/go.mod | 65 ++++----- docs/examples/kubo-as-a-library/go.sum | 190 +++++++++++++++---------- go.mod | 67 ++++----- go.sum | 186 ++++++++++++++---------- test/dependencies/go.mod | 28 ++-- test/dependencies/go.sum | 119 +++++++++++----- 6 files changed, 394 insertions(+), 261 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 07c7afcd7..263925581 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -1,6 +1,8 @@ module github.com/ipfs/kubo/examples/kubo-as-a-library -go 1.20 +go 1.21 + +toolchain go1.21.7 // Used to keep this in sync with the current version of kubo. You should remove // this if you copy this example. @@ -9,7 +11,7 @@ replace github.com/ipfs/kubo => ./../../.. require ( github.com/ipfs/boxo v0.18.0 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 - github.com/libp2p/go-libp2p v0.32.2 + github.com/libp2p/go-libp2p v0.33.0 github.com/multiformats/go-multiaddr v0.12.2 ) @@ -39,7 +41,7 @@ require ( github.com/dustin/go-humanize v1.0.1 // indirect github.com/elastic/gosigar v0.14.2 // indirect github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5 // indirect - github.com/flynn/noise v1.0.1 // indirect + github.com/flynn/noise v1.1.0 // indirect github.com/francoispqt/gojay v1.2.13 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/gabriel-vasile/mimetype v1.4.3 // indirect @@ -51,9 +53,9 @@ require ( github.com/golang/protobuf v1.5.3 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/gopacket v1.1.19 // indirect - github.com/google/pprof v0.0.0-20231229205709-960ae82b1e42 // indirect + github.com/google/pprof v0.0.0-20240207164012-fb44976bdcd5 // indirect github.com/google/uuid v1.5.0 // indirect - github.com/gorilla/websocket v1.5.0 // indirect + github.com/gorilla/websocket v1.5.1 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect @@ -93,8 +95,8 @@ require ( github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect github.com/jbenet/goprocess v0.1.4 // indirect - github.com/klauspost/compress v1.17.4 // indirect - github.com/klauspost/cpuid/v2 v2.2.6 // indirect + github.com/klauspost/compress v1.17.6 // indirect + github.com/klauspost/cpuid/v2 v2.2.7 // indirect github.com/koron/go-ssdp v0.0.4 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/libp2p/go-cidranger v1.1.0 // indirect @@ -131,38 +133,37 @@ require ( github.com/multiformats/go-multihash v0.2.3 // indirect github.com/multiformats/go-multistream v0.5.0 // indirect github.com/multiformats/go-varint v0.0.7 // indirect - github.com/onsi/ginkgo/v2 v2.13.2 // indirect - github.com/opencontainers/runtime-spec v1.1.0 // indirect + github.com/onsi/ginkgo/v2 v2.15.0 // indirect + github.com/opencontainers/runtime-spec v1.2.0 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/openzipkin/zipkin-go v0.4.2 // indirect github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 // indirect github.com/pion/datachannel v1.5.5 // indirect - github.com/pion/dtls/v2 v2.2.7 // indirect - github.com/pion/ice/v2 v2.3.6 // indirect - github.com/pion/interceptor v0.1.17 // indirect + github.com/pion/dtls/v2 v2.2.8 // indirect + github.com/pion/ice/v2 v2.3.11 // indirect + github.com/pion/interceptor v0.1.25 // indirect github.com/pion/logging v0.2.2 // indirect - github.com/pion/mdns v0.0.7 // indirect + github.com/pion/mdns v0.0.9 // indirect github.com/pion/randutil v0.1.0 // indirect - github.com/pion/rtcp v1.2.10 // indirect - github.com/pion/rtp v1.7.13 // indirect - github.com/pion/sctp v1.8.7 // indirect + github.com/pion/rtcp v1.2.13 // indirect + github.com/pion/rtp v1.8.3 // indirect + github.com/pion/sctp v1.8.9 // indirect github.com/pion/sdp/v3 v3.0.6 // indirect - github.com/pion/srtp/v2 v2.0.15 // indirect - github.com/pion/stun v0.6.0 // indirect - github.com/pion/transport/v2 v2.2.1 // indirect - github.com/pion/turn/v2 v2.1.0 // indirect - github.com/pion/webrtc/v3 v3.2.9 // indirect + github.com/pion/srtp/v2 v2.0.18 // indirect + github.com/pion/stun v0.6.1 // indirect + github.com/pion/transport/v2 v2.2.4 // indirect + github.com/pion/turn/v2 v2.1.4 // indirect + github.com/pion/webrtc/v3 v3.2.23 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/polydawn/refmt v0.89.0 // indirect github.com/prometheus/client_golang v1.18.0 // indirect - github.com/prometheus/client_model v0.5.0 // indirect - github.com/prometheus/common v0.46.0 // indirect + github.com/prometheus/client_model v0.6.0 // indirect + github.com/prometheus/common v0.47.0 // indirect github.com/prometheus/procfs v0.12.0 // indirect github.com/quic-go/qpack v0.4.0 // indirect - github.com/quic-go/qtls-go1-20 v0.4.1 // indirect - github.com/quic-go/quic-go v0.40.1 // indirect + github.com/quic-go/quic-go v0.41.0 // indirect github.com/quic-go/webtransport-go v0.6.0 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/samber/lo v1.39.0 // indirect @@ -191,16 +192,16 @@ require ( go.uber.org/fx v1.20.1 // indirect go.uber.org/mock v0.4.0 // indirect go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap v1.26.0 // indirect + go.uber.org/zap v1.27.0 // indirect go4.org v0.0.0-20230225012048-214862532bf5 // indirect - golang.org/x/crypto v0.18.0 // indirect - golang.org/x/exp v0.0.0-20240119083558-1b970713d09a // indirect - golang.org/x/mod v0.14.0 // indirect - golang.org/x/net v0.20.0 // indirect + golang.org/x/crypto v0.19.0 // indirect + golang.org/x/exp v0.0.0-20240213143201-ec583247a57a // indirect + golang.org/x/mod v0.15.0 // indirect + golang.org/x/net v0.21.0 // indirect golang.org/x/sync v0.6.0 // indirect - golang.org/x/sys v0.16.0 // indirect + golang.org/x/sys v0.17.0 // indirect golang.org/x/text v0.14.0 // indirect - golang.org/x/tools v0.17.0 // indirect + golang.org/x/tools v0.18.0 // indirect golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect gonum.org/v1/gonum v0.14.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240108191215-35c7eff3a6b1 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index c9d1b3fb1..7238b76c1 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -101,6 +101,7 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c h1:pFUpOrbxDR6AkioZ1ySsx5yxlDQZ8stG2b88gTPxgJU= github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c/go.mod h1:6UhI8N9EjYm1c2odKpFpAYeR8dsBeM7PtzQhRgxRr9U= github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y= +github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= @@ -126,13 +127,14 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7 github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5 h1:BBso6MBKW8ncyZLv37o+KNyy0HrrHgfnOaGQC2qvN+A= github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5/go.mod h1:JpoxHjuQauoxiFMl1ie8Xc/7TfLuMZ5eOCONd1sUBHg= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= -github.com/flynn/noise v1.0.1 h1:vPp/jdQLXC6ppsXSj/pM3W1BIJ5FEHE2TulSJBpb43Y= -github.com/flynn/noise v1.0.1/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag= +github.com/flynn/noise v1.1.0 h1:KjPQoQCEFdZDiP03phOvGi11+SVVhBG2wOWAorLsstg= +github.com/flynn/noise v1.1.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag= github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk= github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/frankban/quicktest v1.14.0/go.mod h1:NeW+ay9A/U67EYXNFA1nPE8e/tnQv/09mUdL/ijj8og= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= +github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= @@ -169,6 +171,7 @@ github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4er github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= @@ -206,6 +209,7 @@ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= @@ -214,12 +218,12 @@ github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXi github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20231229205709-960ae82b1e42 h1:dHLYa5D8/Ta0aLR2XcPsrkpAgGeFs6thhMcQK0oQ0n8= -github.com/google/pprof v0.0.0-20231229205709-960ae82b1e42/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= +github.com/google/pprof v0.0.0-20240207164012-fb44976bdcd5 h1:E/LAvt58di64hlYjx7AsNS6C/ysHWYo+2qPCZKTQhRo= +github.com/google/pprof v0.0.0-20240207164012-fb44976bdcd5/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU= github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= @@ -228,9 +232,11 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c h1:7lF+Vz0LqiRidnzC1Oq86fpX1q/iEv2KJdrCtttYjT4= +github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= -github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= -github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= +github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= +github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0 h1:Wqo399gCIufwto+VfwCSvsnfGpF/w5E9CNxSwbpD6No= @@ -268,6 +274,7 @@ github.com/ipfs/go-block-format v0.0.3/go.mod h1:4LmD4ZUw0mhO+JSKdpWwrzATiEfM7WW github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs= github.com/ipfs/go-block-format v0.2.0/go.mod h1:+jpL11nFx5A/SPpsoBn6Bzkra/zaArfSmsknbPMYgzM= github.com/ipfs/go-blockservice v0.5.0 h1:B2mwhhhVQl2ntW2EIpaWPwSCxSuqr5fFA93Ms4bYLEY= +github.com/ipfs/go-blockservice v0.5.0/go.mod h1:W6brZ5k20AehbmERplmERn8o2Ni3ZZubvAxaIUeaT6w= github.com/ipfs/go-cid v0.0.3/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.4/go.mod h1:4LLaPOQwmk5z9LBgQnpkivrx8BJjUyGwTXCd5Xfj6+M= github.com/ipfs/go-cid v0.0.5/go.mod h1:plgt+Y5MnOey4vO4UlUazGqdbEXuFYitED67FexhXog= @@ -297,15 +304,20 @@ github.com/ipfs/go-ds-measure v0.2.0/go.mod h1:SEUD/rE2PwRa4IQEC5FuNAmjJCyYObZr9 github.com/ipfs/go-fs-lock v0.0.7 h1:6BR3dajORFrFTkb5EpCUFIAypsoxpGpDSVUdFwzgL9U= github.com/ipfs/go-fs-lock v0.0.7/go.mod h1:Js8ka+FNYmgQRLrRXzU3CB/+Csr1BwrRilEcvYrHhhc= github.com/ipfs/go-ipfs-blockstore v1.3.0 h1:m2EXaWgwTzAfsmt5UdJ7Is6l4gJcaM/A12XwJyvYvMM= +github.com/ipfs/go-ipfs-blockstore v1.3.0/go.mod h1:KgtZyc9fq+P2xJUiCAzbRdhhqJHvsw8u2Dlqy2MyRTE= github.com/ipfs/go-ipfs-blocksutil v0.0.1 h1:Eh/H4pc1hsvhzsQoMEP3Bke/aW5P5rVM1IWFJMcGIPQ= +github.com/ipfs/go-ipfs-blocksutil v0.0.1/go.mod h1:Yq4M86uIOmxmGPUHv/uI7uKqZNtLb449gwKqXjIsnRk= github.com/ipfs/go-ipfs-chunker v0.0.5 h1:ojCf7HV/m+uS2vhUGWcogIIxiO5ubl5O57Q7NapWLY8= +github.com/ipfs/go-ipfs-chunker v0.0.5/go.mod h1:jhgdF8vxRHycr00k13FM8Y0E+6BoalYeobXmUyTreP8= github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= github.com/ipfs/go-ipfs-delay v0.0.1 h1:r/UXYyRcddO6thwOnhiznIAiSvxMECGgtv35Xs1IeRQ= github.com/ipfs/go-ipfs-delay v0.0.1/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= github.com/ipfs/go-ipfs-ds-help v1.1.0 h1:yLE2w9RAsl31LtfMt91tRZcrx+e61O5mDxFRR994w4Q= github.com/ipfs/go-ipfs-ds-help v1.1.0/go.mod h1:YR5+6EaebOhfcqVCyqemItCLthrpVNot+rsOU/5IatU= github.com/ipfs/go-ipfs-exchange-interface v0.2.0 h1:8lMSJmKogZYNo2jjhUs0izT+dck05pqUw4mWNW9Pw6Y= +github.com/ipfs/go-ipfs-exchange-interface v0.2.0/go.mod h1:z6+RhJuDQbqKguVyslSOuVDhqF9JtTrO3eptSAiW2/Y= github.com/ipfs/go-ipfs-exchange-offline v0.3.0 h1:c/Dg8GDPzixGd0MC8Jh6mjOwU57uYokgWRFidfvEkuA= +github.com/ipfs/go-ipfs-exchange-offline v0.3.0/go.mod h1:MOdJ9DChbb5u37M1IcbrRB02e++Z7521fMxqCNRrz9s= github.com/ipfs/go-ipfs-pq v0.0.3 h1:YpoHVJB+jzK15mr/xsWC574tyDLkezVrDNeaalQBsTE= github.com/ipfs/go-ipfs-pq v0.0.3/go.mod h1:btNw5hsHBpRcSSgZtiNm/SLj5gYIZ18AKtv3kERkRb4= github.com/ipfs/go-ipfs-redirects-file v0.1.1 h1:Io++k0Vf/wK+tfnhEh63Yte1oQK5VGT2hIEYpD0Rzx8= @@ -333,14 +345,17 @@ github.com/ipfs/go-log/v2 v2.3.0/go.mod h1:QqGoj30OTpnKaG/LKTGTxoP2mmQtjVMEnK72g github.com/ipfs/go-log/v2 v2.5.1 h1:1XdUzF7048prq4aBjDQQ4SL5RxftpRGdXhNRwKSAlcY= github.com/ipfs/go-log/v2 v2.5.1/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOLU9U5UI= github.com/ipfs/go-merkledag v0.11.0 h1:DgzwK5hprESOzS4O1t/wi6JDpyVQdvm9Bs59N/jqfBY= +github.com/ipfs/go-merkledag v0.11.0/go.mod h1:Q4f/1ezvBiJV0YCIXvt51W/9/kqJGH4I1LsA7+djsM4= github.com/ipfs/go-metrics-interface v0.0.1 h1:j+cpbjYvu4R8zbleSs36gvB7jR+wsL2fGD6n0jO4kdg= github.com/ipfs/go-metrics-interface v0.0.1/go.mod h1:6s6euYU4zowdslK0GKHmqaIZ3j/b/tL7HTWtJ4VPgWY= github.com/ipfs/go-peertaskqueue v0.8.1 h1:YhxAs1+wxb5jk7RvS0LHdyiILpNmRIRnZVztekOF0pg= github.com/ipfs/go-peertaskqueue v0.8.1/go.mod h1:Oxxd3eaK279FxeydSPPVGHzbwVeHjatZ2GA8XD+KbPU= github.com/ipfs/go-unixfs v0.4.5 h1:wj8JhxvV1G6CD7swACwSKYa+NgtdWC1RUit+gFnymDU= +github.com/ipfs/go-unixfs v0.4.5/go.mod h1:BIznJNvt/gEx/ooRMI4Us9K8+qeGO7vx1ohnbk8gjFg= github.com/ipfs/go-unixfsnode v1.9.0 h1:ubEhQhr22sPAKO2DNsyVBW7YB/zA8Zkif25aBvz8rc8= github.com/ipfs/go-unixfsnode v1.9.0/go.mod h1:HxRu9HYHOjK6HUqFBAi++7DVoWAHn0o4v/nZ/VA+0g8= github.com/ipfs/go-verifcid v0.0.2 h1:XPnUv0XmdH+ZIhLGKg6U2vaPaRDXb9urMyNVCE7uvTs= +github.com/ipfs/go-verifcid v0.0.2/go.mod h1:40cD9x1y4OWnFXbLNJYRe7MpNvWlMn3LZAG5Wb4xnPU= github.com/ipld/go-car/v2 v2.13.1 h1:KnlrKvEPEzr5IZHKTXLAEub+tPrzeAFQVRlSQvuxBO4= github.com/ipld/go-car/v2 v2.13.1/go.mod h1:QkdjjFNGit2GIkpQ953KBwowuoukoM75nP/JI1iDJdo= github.com/ipld/go-codec-dagpb v1.6.0 h1:9nYazfyu9B1p3NAgfVdpRco3Fs2nFC72DqVsMj6rOcc= @@ -350,6 +365,7 @@ github.com/ipld/go-ipld-prime v0.14.1/go.mod h1:QcE4Y9n/ZZr8Ijg5bGPT0GqYWgZ1704n github.com/ipld/go-ipld-prime v0.21.0 h1:n4JmcpOlPDIxBcY037SVfpd1G+Sj1nKZah0m6QH9C2E= github.com/ipld/go-ipld-prime v0.21.0/go.mod h1:3RLqy//ERg/y5oShXXdx5YIp50cFGOanyMctpPjsvxQ= github.com/ipld/go-ipld-prime/storage/bsadapter v0.0.0-20230102063945-1a409dc236dd h1:gMlw/MhNr2Wtp5RwGdsW23cs+yCuj9k2ON7i9MiJlRo= +github.com/ipld/go-ipld-prime/storage/bsadapter v0.0.0-20230102063945-1a409dc236dd/go.mod h1:wZ8hH8UxeryOs4kJEJaiui/s00hDSbE37OKsL47g+Sw= github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/jbenet/go-cienv v0.1.0 h1:Vc/s0QbQtoxX8MwwSLWWh+xNNZvM3Lw7NsTcHrvvhMc= @@ -375,12 +391,12 @@ github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQL 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.17.4 h1:Ej5ixsIri7BrIjBkRZLTo6ghwrEtHFk7ijlczPW4fZ4= -github.com/klauspost/compress v1.17.4/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= +github.com/klauspost/compress v1.17.6 h1:60eq2E/jlfwQXtvZEeBUYADs+BwKBWURIY+Gj2eRGjI= +github.com/klauspost/compress v1.17.6/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/48xc= -github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= +github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/koron/go-ssdp v0.0.4 h1:1IDwrghSKYM7yLf7XCzbByg2sJ/JcNOZRXS2jczTwz0= github.com/koron/go-ssdp v0.0.4/go.mod h1:oDXq+E5IL5q0U8uSBcoAXzTzInwy5lEgC91HoKtbmZk= @@ -389,6 +405,7 @@ github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfn github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= @@ -406,8 +423,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.32.2 h1:s8GYN4YJzgUoyeYNPdW7JZeZ5Ee31iNaIBfGYMAY4FQ= -github.com/libp2p/go-libp2p v0.32.2/go.mod h1:E0LKe+diV/ZVJVnOJby8VC5xzHF0660osg71skcxJvk= +github.com/libp2p/go-libp2p v0.33.0 h1:yTPSr8sJRbfeEYXyeN8VPVSlTlFjtMUwGDRniwaf/xQ= +github.com/libp2p/go-libp2p v0.33.0/go.mod h1:RIJFRQVUBKy82dnW7J5f1homqqv6NcsDJAl3e7CRGfE= github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94= github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= @@ -427,6 +444,7 @@ github.com/libp2p/go-libp2p-record v0.2.0/go.mod h1:I+3zMkvvg5m2OcSdoL0KPljyJyvN github.com/libp2p/go-libp2p-routing-helpers v0.7.3 h1:u1LGzAMVRK9Nqq5aYDVOiq/HaB93U9WWczBzGyAC5ZY= github.com/libp2p/go-libp2p-routing-helpers v0.7.3/go.mod h1:cN4mJAD/7zfPKXBcs9ze31JGYAZgzdABEm+q/hkswb8= github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA= +github.com/libp2p/go-libp2p-testing v0.12.0/go.mod h1:KcGDRXyN7sQCllucn1cOOS+Dmm7ujhfEyXQL5lvkcPg= github.com/libp2p/go-libp2p-xor v0.1.0 h1:hhQwT4uGrBcuAkUGXADuPltalOdpf9aag9kaYNT2tLA= github.com/libp2p/go-libp2p-xor v0.1.0/go.mod h1:LSTM5yRnjGZbWNTA/hRwq2gGFrvRIbQJscoIL/u6InY= github.com/libp2p/go-msgio v0.0.4/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= @@ -540,16 +558,17 @@ github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9k github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.13.2 h1:Bi2gGVkfn6gQcjNjZJVO8Gf0FHzMPf2phUei9tejVMs= -github.com/onsi/ginkgo/v2 v2.13.2/go.mod h1:XStQ8QcGwLyF4HdfcZB8SFOS/MWCgDuXMSBe6zrvLgM= +github.com/onsi/ginkgo/v2 v2.15.0 h1:79HwNRBAZHOEwrczrgSOPy+eFTTlIGELKy5as+ClttY= +github.com/onsi/ginkgo/v2 v2.15.0/go.mod h1:HlxMHtYF57y6Dpf+mc5529KKmSq9h2FpCF+/ZkwUxKM= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= -github.com/onsi/gomega v1.29.0 h1:KIA/t2t5UBzoirT4H9tsML45GEbo3ouUnBHsCfD2tVg= +github.com/onsi/gomega v1.30.0 h1:hvMK7xYz4D3HapigLTeGdId/NcfQx1VHMJc60ew99+8= +github.com/onsi/gomega v1.30.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opencontainers/runtime-spec v1.1.0 h1:HHUyrt9mwHUjtasSbXSMvs4cyFxh+Bll4AjJ9odEGpg= -github.com/opencontainers/runtime-spec v1.1.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/runtime-spec v1.2.0 h1:z97+pHb3uELt/yiAWD691HNHQIF07bE7dzrbT927iTk= +github.com/opencontainers/runtime-spec v1.2.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= @@ -564,43 +583,51 @@ github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 h1:1/WtZae0yGtPq+TI6+ github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9/go.mod h1:x3N5drFsm2uilKKuuYo6LdyD8vZAW55sH/9w+pbo1sw= github.com/pion/datachannel v1.5.5 h1:10ef4kwdjije+M9d7Xm9im2Y3O6A6ccQb0zcqZcJew8= github.com/pion/datachannel v1.5.5/go.mod h1:iMz+lECmfdCMqFRhXhcA/219B0SQlbpoR2V118yimL0= -github.com/pion/dtls/v2 v2.2.7 h1:cSUBsETxepsCSFSxC3mc/aDo14qQLMSL+O6IjG28yV8= github.com/pion/dtls/v2 v2.2.7/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s= -github.com/pion/ice/v2 v2.3.6 h1:Jgqw36cAud47iD+N6rNX225uHvrgWtAlHfVyOQc3Heg= -github.com/pion/ice/v2 v2.3.6/go.mod h1:9/TzKDRwBVAPsC+YOrKH/e3xDrubeTRACU9/sHQarsU= -github.com/pion/interceptor v0.1.17 h1:prJtgwFh/gB8zMqGZoOgJPHivOwVAp61i2aG61Du/1w= -github.com/pion/interceptor v0.1.17/go.mod h1:SY8kpmfVBvrbUzvj2bsXz7OJt5JvmVNZ+4Kjq7FcwrI= +github.com/pion/dtls/v2 v2.2.8 h1:BUroldfiIbV9jSnC6cKOMnyiORRWrWWpV11JUyEu5OA= +github.com/pion/dtls/v2 v2.2.8/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s= +github.com/pion/ice/v2 v2.3.11 h1:rZjVmUwyT55cmN8ySMpL7rsS8KYsJERsrxJLLxpKhdw= +github.com/pion/ice/v2 v2.3.11/go.mod h1:hPcLC3kxMa+JGRzMHqQzjoSj3xtE9F+eoncmXLlCL4E= +github.com/pion/interceptor v0.1.25 h1:pwY9r7P6ToQ3+IF0bajN0xmk/fNw/suTgaTdlwTDmhc= +github.com/pion/interceptor v0.1.25/go.mod h1:wkbPYAak5zKsfpVDYMtEfWEy8D4zL+rpxCxPImLOg3Y= github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY= github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms= -github.com/pion/mdns v0.0.7 h1:P0UB4Sr6xDWEox0kTVxF0LmQihtCbSAdW0H2nEgkA3U= -github.com/pion/mdns v0.0.7/go.mod h1:4iP2UbeFhLI/vWju/bw6ZfwjJzk0z8DNValjGxR/dD8= +github.com/pion/mdns v0.0.8/go.mod h1:hYE72WX8WDveIhg7fmXgMKivD3Puklk0Ymzog0lSyaI= +github.com/pion/mdns v0.0.9 h1:7Ue5KZsqq8EuqStnpPWV33vYYEH0+skdDN5L7EiEsI4= +github.com/pion/mdns v0.0.9/go.mod h1:2JA5exfxwzXiCihmxpTKgFUpiQws2MnipoPK09vecIc= github.com/pion/randutil v0.1.0 h1:CFG1UdESneORglEsnimhUjf33Rwjubwj6xfiOXBa3mA= github.com/pion/randutil v0.1.0/go.mod h1:XcJrSMMbbMRhASFVOlj/5hQial/Y8oH/HVo7TBZq+j8= -github.com/pion/rtcp v1.2.10 h1:nkr3uj+8Sp97zyItdN60tE/S6vk4al5CPRR6Gejsdjc= github.com/pion/rtcp v1.2.10/go.mod h1:ztfEwXZNLGyF1oQDttz/ZKIBaeeg/oWbRYqzBM9TL1I= -github.com/pion/rtp v1.7.13 h1:qcHwlmtiI50t1XivvoawdCGTP4Uiypzfrsap+bijcoA= -github.com/pion/rtp v1.7.13/go.mod h1:bDb5n+BFZxXx0Ea7E5qe+klMuqiBrP+w8XSjiWtCUko= +github.com/pion/rtcp v1.2.12/go.mod h1:sn6qjxvnwyAkkPzPULIbVqSKI5Dv54Rv7VG0kNxh9L4= +github.com/pion/rtcp v1.2.13 h1:+EQijuisKwm/8VBs8nWllr0bIndR7Lf7cZG200mpbNo= +github.com/pion/rtcp v1.2.13/go.mod h1:sn6qjxvnwyAkkPzPULIbVqSKI5Dv54Rv7VG0kNxh9L4= +github.com/pion/rtp v1.8.2/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU= +github.com/pion/rtp v1.8.3 h1:VEHxqzSVQxCkKDSHro5/4IUUG1ea+MFdqR2R3xSpNU8= +github.com/pion/rtp v1.8.3/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU= github.com/pion/sctp v1.8.5/go.mod h1:SUFFfDpViyKejTAdwD1d/HQsCu+V/40cCs2nZIvC3s0= -github.com/pion/sctp v1.8.7 h1:JnABvFakZueGAn4KU/4PSKg+GWbF6QWbKTWZOSGJjXw= -github.com/pion/sctp v1.8.7/go.mod h1:g1Ul+ARqZq5JEmoFy87Q/4CePtKnTJ1QCL9dBBdN6AU= +github.com/pion/sctp v1.8.8/go.mod h1:igF9nZBrjh5AtmKc7U30jXltsFHicFCXSmWA2GWRaWs= +github.com/pion/sctp v1.8.9 h1:TP5ZVxV5J7rz7uZmbyvnUvsn7EJ2x/5q9uhsTtXbI3g= +github.com/pion/sctp v1.8.9/go.mod h1:cMLT45jqw3+jiJCrtHVwfQLnfR0MGZ4rgOJwUOIqLkI= github.com/pion/sdp/v3 v3.0.6 h1:WuDLhtuFUUVpTfus9ILC4HRyHsW6TdugjEX/QY9OiUw= github.com/pion/sdp/v3 v3.0.6/go.mod h1:iiFWFpQO8Fy3S5ldclBkpXqmWy02ns78NOKoLLL0YQw= -github.com/pion/srtp/v2 v2.0.15 h1:+tqRtXGsGwHC0G0IUIAzRmdkHvriF79IHVfZGfHrQoA= -github.com/pion/srtp/v2 v2.0.15/go.mod h1:b/pQOlDrbB0HEH5EUAQXzSYxikFbNcNuKmF8tM0hCtw= -github.com/pion/stun v0.4.0/go.mod h1:QPsh1/SbXASntw3zkkrIk3ZJVKz4saBY2G7S10P3wCw= -github.com/pion/stun v0.6.0 h1:JHT/2iyGDPrFWE8NNC15wnddBN8KifsEDw8swQmrEmU= -github.com/pion/stun v0.6.0/go.mod h1:HPqcfoeqQn9cuaet7AOmB5e5xkObu9DwBdurwLKO9oA= +github.com/pion/srtp/v2 v2.0.18 h1:vKpAXfawO9RtTRKZJbG4y0v1b11NZxQnxRl85kGuUlo= +github.com/pion/srtp/v2 v2.0.18/go.mod h1:0KJQjA99A6/a0DOVTu1PhDSw0CXF2jTkqOoMg3ODqdA= +github.com/pion/stun v0.6.1 h1:8lp6YejULeHBF8NmV8e2787BogQhduZugh5PdhDyyN4= +github.com/pion/stun v0.6.1/go.mod h1:/hO7APkX4hZKu/D0f2lHzNyvdkTGtIy3NDmLR7kSz/8= github.com/pion/transport v0.14.1 h1:XSM6olwW+o8J4SCmOBb/BpwZypkHeyM0PGFCxNQBr40= github.com/pion/transport v0.14.1/go.mod h1:4tGmbk00NeYA3rUa9+n+dzCCoKkcy3YlYb99Jn2fNnI= -github.com/pion/transport/v2 v2.0.0/go.mod h1:HS2MEBJTwD+1ZI2eSXSvHJx/HnzQqRy2/LXxt6eVMHc= -github.com/pion/transport/v2 v2.1.0/go.mod h1:AdSw4YBZVDkZm8fpoz+fclXyQwANWmZAlDuQdctTThQ= -github.com/pion/transport/v2 v2.2.0/go.mod h1:AdSw4YBZVDkZm8fpoz+fclXyQwANWmZAlDuQdctTThQ= -github.com/pion/transport/v2 v2.2.1 h1:7qYnCBlpgSJNYMbLCKuSY9KbQdBFoETvPNETv0y4N7c= github.com/pion/transport/v2 v2.2.1/go.mod h1:cXXWavvCnFF6McHTft3DWS9iic2Mftcz1Aq29pGcU5g= -github.com/pion/turn/v2 v2.1.0 h1:5wGHSgGhJhP/RpabkUb/T9PdsAjkGLS6toYz5HNzoSI= -github.com/pion/turn/v2 v2.1.0/go.mod h1:yrT5XbXSGX1VFSF31A3c1kCNB5bBZgk/uu5LET162qs= -github.com/pion/webrtc/v3 v3.2.9 h1:U8NSjQDlZZ+Iy/hg42Q/u6mhEVSXYvKrOIZiZwYTfLc= -github.com/pion/webrtc/v3 v3.2.9/go.mod h1:gjQLMZeyN3jXBGdxGmUYCyKjOuYX/c99BDjGqmadq0A= +github.com/pion/transport/v2 v2.2.2/go.mod h1:OJg3ojoBJopjEeECq2yJdXH9YVrUJ1uQ++NjXLOUorc= +github.com/pion/transport/v2 v2.2.3/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0= +github.com/pion/transport/v2 v2.2.4 h1:41JJK6DZQYSeVLxILA2+F4ZkKb4Xd/tFJZRFZQ9QAlo= +github.com/pion/transport/v2 v2.2.4/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0= +github.com/pion/transport/v3 v3.0.1 h1:gDTlPJwROfSfz6QfSi0ZmeCSkFcnWWiiR9ES0ouANiM= +github.com/pion/transport/v3 v3.0.1/go.mod h1:UY7kiITrlMv7/IKgd5eTUcaahZx5oUN3l9SzK5f5xE0= +github.com/pion/turn/v2 v2.1.3/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY= +github.com/pion/turn/v2 v2.1.4 h1:2xn8rduI5W6sCZQkEnIUDAkrBQNl2eYIBCHMZ3QMmP8= +github.com/pion/turn/v2 v2.1.4/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY= +github.com/pion/webrtc/v3 v3.2.23 h1:GbqEuxBbVLFhXk0GwxKAoaIJYiEa9TyoZPEZC+2HZxM= +github.com/pion/webrtc/v3 v3.2.23/go.mod h1:1CaT2fcZzZ6VZA+O1i9yK2DU4EOcXVvSbWG9pr5jefs= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -614,20 +641,18 @@ github.com/prometheus/client_golang v1.18.0 h1:HzFfmkOzH5Q8L8G+kSJKUx5dtG87sewO+ github.com/prometheus/client_golang v1.18.0/go.mod h1:T+GXkCk5wSJyOqMIzVgvvjFDlkOQntgjkJWKrN5txjA= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= -github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= +github.com/prometheus/client_model v0.6.0 h1:k1v3CzpSRUTrKMppY35TLwPvxHqBu0bYgxZzqGIgaos= +github.com/prometheus/client_model v0.6.0/go.mod h1:NTQHnmxFpouOD0DpvP4XujX3CdOAGQPoaGhyTchlyt8= github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.46.0 h1:doXzt5ybi1HBKpsZOL0sSkaNHJJqkyfEWZGGqqScV0Y= -github.com/prometheus/common v0.46.0/go.mod h1:Tp0qkxpb9Jsg54QMe+EAmqXkSV7Evdy1BTn+g2pa/hQ= +github.com/prometheus/common v0.47.0 h1:p5Cz0FNHo7SnWOmWmoRozVcjEp0bIVU8cV7OShpjL1k= +github.com/prometheus/common v0.47.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= -github.com/quic-go/qtls-go1-20 v0.4.1 h1:D33340mCNDAIKBqXuAvexTNMUByrYmFYVfKfDN5nfFs= -github.com/quic-go/qtls-go1-20 v0.4.1/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= -github.com/quic-go/quic-go v0.40.1 h1:X3AGzUNFs0jVuO3esAGnTfvdgvL4fq655WaOi1snv1Q= -github.com/quic-go/quic-go v0.40.1/go.mod h1:PeN7kuVJ4xZbxSv/4OX6S1USOX8MJvydwpTx31vx60c= +github.com/quic-go/quic-go v0.41.0 h1:aD8MmHfgqTURWNJy48IYFg2OnxwHT3JL7ahGs73lb4k= +github.com/quic-go/quic-go v0.41.0/go.mod h1:qCkNjqczPEvgsOnxZ0eCD14lv+B2LHlFAB++CNOh9hA= github.com/quic-go/webtransport-go v0.6.0 h1:CvNsKqc4W2HljHJnoT+rMmbRJybShZ0YPFDD3NxaZLY= github.com/quic-go/webtransport-go v0.6.0/go.mod h1:9KjU4AEBqEQidGHNDkZrb8CAa1abRaosM2yGOyiikEc= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= @@ -635,6 +660,7 @@ github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtD github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= +github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd/go.mod h1:hPqNNc0+uJM6H+SuU8sEs5K5IQeKccPqeSjfgcKGgPk= @@ -701,7 +727,6 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= @@ -710,6 +735,7 @@ github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70 github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= github.com/tj/assert v0.0.3 h1:Df/BlaZ20mq6kuai7f5z2TvPFiwC3xaWJSDQNiIS3Rk= +github.com/tj/assert v0.0.3/go.mod h1:Ne6X72Q+TB1AteidzQncjw9PabbMp4PBMZ1k+vd1Pvk= github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c h1:u6SKchux2yDvFQnDHS3lPnIRmfVJ5Sxy3ao2SIdysLQ= github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM= github.com/ucarion/urlpath v0.0.0-20200424170820-7ccc79b76bbb h1:Ywfo8sUltxogBpFuMOFRrrSifO788kAFxmvVw31PtQQ= @@ -723,6 +749,7 @@ github.com/wangjia184/sortedset v0.0.0-20160527075905-f5d03557ba30/go.mod h1:Yko github.com/warpfork/go-testmark v0.3.0/go.mod h1:jhEf8FVxd+F17juRubpmut64NEG6I2rgkUhlcqqXwE0= github.com/warpfork/go-testmark v0.9.0/go.mod h1:jhEf8FVxd+F17juRubpmut64NEG6I2rgkUhlcqqXwE0= github.com/warpfork/go-testmark v0.12.1 h1:rMgCpJfwy1sJ50x0M0NgyphxYYPMOODIJHhsXyEHU0s= +github.com/warpfork/go-testmark v0.12.1/go.mod h1:kHwy7wfvGSPh1rQJYKayD4AbtNaeyZdcGi9tNJTaa5Y= github.com/warpfork/go-wish v0.0.0-20200122115046-b9ea61034e4a/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0 h1:GDDkbFiaK8jsSDJfjId/PEGEShv6ugrt4kYsC5UIDaQ= github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= @@ -777,12 +804,14 @@ go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= +go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= go.uber.org/fx v1.20.1 h1:zVwVQGS8zYvhh9Xxcu4w1M6ESyeMzebzj2NbSayZ4Mk= go.uber.org/fx v1.20.1/go.mod h1:iSYNbHf2y55acNCwCXKx7LbWb5WG1Bnue5RDXz1OREg= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= @@ -795,8 +824,8 @@ go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.14.1/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= -go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= -go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= +go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= +go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= go4.org v0.0.0-20200411211856-f5505b9728dd/go.mod h1:CIiUVy99QCPfoE13bO4EZaz5GZMZXMSBGhxRdsvzbkg= go4.org v0.0.0-20230225012048-214862532bf5 h1:nifaUDeh+rPaBCMPMQHZmvJf+QdpLFnuQPwx+LxVmtc= @@ -819,9 +848,12 @@ golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWP golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= -golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= -golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc= -golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= +golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= +golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= +golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= +golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= +golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= +golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -830,8 +862,8 @@ golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20240119083558-1b970713d09a h1:Q8/wZp0KX97QFTc2ywcOE0YRjZPVIx+MXInMzdvQqcA= -golang.org/x/exp v0.0.0-20240119083558-1b970713d09a/go.mod h1:idGWGoKP1toJGkd5/ig9ZLuPcZBC3ewk7SzmH0uou08= +golang.org/x/exp v0.0.0-20240213143201-ec583247a57a h1:HinSgX1tJRX3KsL//Gxynpw5CTOAIPhgL4W8PNiIpVE= +golang.org/x/exp v0.0.0-20240213143201-ec583247a57a/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -855,8 +887,8 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= -golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8= +golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -888,14 +920,16 @@ golang.org/x/net v0.0.0-20210423184538-5f58ad60dda6/go.mod h1:OJAsFXCWl8Ukc7SiCT golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= -golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= -golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= +golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ= +golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= +golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= +golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= +golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -965,22 +999,27 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= -golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo= +golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= +golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= +golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -989,10 +1028,12 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1036,8 +1077,8 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc= -golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps= +golang.org/x/tools v0.18.0 h1:k8NLag8AGHnn+PHbl7g43CtqZAwG60vZkLqgyZgIHgQ= +golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1083,6 +1124,7 @@ google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvx google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20240102182953-50ed04b92917 h1:nz5NESFLZbJGPFxDT/HCn+V1mZ8JGNoY4nUpmW/Y2eg= +google.golang.org/genproto v0.0.0-20240102182953-50ed04b92917/go.mod h1:pZqR+glSb11aJ+JQcczCvgf47+duRuzNSKqE8YAQnV0= google.golang.org/genproto/googleapis/api v0.0.0-20240108191215-35c7eff3a6b1 h1:OPXtXn7fNMaXwO3JvOmF1QyTc00jsSFFz1vXXBOdCDo= google.golang.org/genproto/googleapis/api v0.0.0-20240108191215-35c7eff3a6b1/go.mod h1:B5xPO//w8qmBDjGReYLpR6UJPnkldGkCSMoH/2vxJeg= google.golang.org/genproto/googleapis/rpc v0.0.0-20240108191215-35c7eff3a6b1 h1:gphdwh0npgs8elJ4T6J+DQJHPVF7RsuJHCfwztUb4J4= diff --git a/go.mod b/go.mod index a0d60bda2..fae6f2f96 100644 --- a/go.mod +++ b/go.mod @@ -47,7 +47,7 @@ require ( github.com/jbenet/goprocess v0.1.4 github.com/julienschmidt/httprouter v1.3.0 github.com/libp2p/go-doh-resolver v0.4.0 - github.com/libp2p/go-libp2p v0.32.2 + github.com/libp2p/go-libp2p v0.33.0 github.com/libp2p/go-libp2p-http v0.5.0 github.com/libp2p/go-libp2p-kad-dht v0.24.4 github.com/libp2p/go-libp2p-kbucket v0.6.3 @@ -82,12 +82,12 @@ require ( go.uber.org/dig v1.17.1 go.uber.org/fx v1.20.1 go.uber.org/multierr v1.11.0 - go.uber.org/zap v1.26.0 - golang.org/x/crypto v0.18.0 - golang.org/x/exp v0.0.0-20240119083558-1b970713d09a - golang.org/x/mod v0.14.0 + go.uber.org/zap v1.27.0 + golang.org/x/crypto v0.19.0 + golang.org/x/exp v0.0.0-20240213143201-ec583247a57a + golang.org/x/mod v0.15.0 golang.org/x/sync v0.6.0 - golang.org/x/sys v0.16.0 + golang.org/x/sys v0.17.0 google.golang.org/protobuf v1.32.0 ) @@ -110,7 +110,7 @@ require ( github.com/docker/go-units v0.5.0 // indirect github.com/elastic/gosigar v0.14.2 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect - github.com/flynn/noise v1.0.1 // indirect + github.com/flynn/noise v1.1.0 // indirect github.com/francoispqt/gojay v1.2.13 // indirect github.com/gabriel-vasile/mimetype v1.4.3 // indirect github.com/go-kit/log v0.2.1 // indirect @@ -124,9 +124,9 @@ require ( github.com/golang/protobuf v1.5.3 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/gopacket v1.1.19 // indirect - github.com/google/pprof v0.0.0-20231229205709-960ae82b1e42 // indirect + github.com/google/pprof v0.0.0-20240207164012-fb44976bdcd5 // indirect github.com/gorilla/mux v1.8.1 // indirect - github.com/gorilla/websocket v1.5.0 // indirect + github.com/gorilla/websocket v1.5.1 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/golang-lru v1.0.2 // indirect @@ -147,8 +147,8 @@ require ( github.com/ipfs/go-peertaskqueue v0.8.1 // indirect github.com/ipfs/go-verifcid v0.0.2 // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect - github.com/klauspost/compress v1.17.4 // indirect - github.com/klauspost/cpuid/v2 v2.2.6 // indirect + github.com/klauspost/compress v1.17.6 // indirect + github.com/klauspost/cpuid/v2 v2.2.7 // indirect github.com/koron/go-ssdp v0.0.4 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/libp2p/go-cidranger v1.1.0 // indirect @@ -177,35 +177,34 @@ require ( github.com/multiformats/go-multiaddr-fmt v0.1.0 // indirect github.com/multiformats/go-multistream v0.5.0 // indirect github.com/multiformats/go-varint v0.0.7 // indirect - github.com/onsi/ginkgo/v2 v2.13.2 // indirect - github.com/opencontainers/runtime-spec v1.1.0 // indirect + github.com/onsi/ginkgo/v2 v2.15.0 // indirect + github.com/opencontainers/runtime-spec v1.2.0 // indirect github.com/openzipkin/zipkin-go v0.4.2 // indirect github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 // indirect github.com/pion/datachannel v1.5.5 // indirect - github.com/pion/dtls/v2 v2.2.7 // indirect - github.com/pion/ice/v2 v2.3.6 // indirect - github.com/pion/interceptor v0.1.17 // indirect + github.com/pion/dtls/v2 v2.2.8 // indirect + github.com/pion/ice/v2 v2.3.11 // indirect + github.com/pion/interceptor v0.1.25 // indirect github.com/pion/logging v0.2.2 // indirect - github.com/pion/mdns v0.0.7 // indirect + github.com/pion/mdns v0.0.9 // indirect github.com/pion/randutil v0.1.0 // indirect - github.com/pion/rtcp v1.2.10 // indirect - github.com/pion/rtp v1.7.13 // indirect - github.com/pion/sctp v1.8.7 // indirect + github.com/pion/rtcp v1.2.13 // indirect + github.com/pion/rtp v1.8.3 // indirect + github.com/pion/sctp v1.8.9 // indirect github.com/pion/sdp/v3 v3.0.6 // indirect - github.com/pion/srtp/v2 v2.0.15 // indirect - github.com/pion/stun v0.6.0 // indirect - github.com/pion/transport/v2 v2.2.1 // indirect - github.com/pion/turn/v2 v2.1.0 // indirect - github.com/pion/webrtc/v3 v3.2.9 // indirect + github.com/pion/srtp/v2 v2.0.18 // indirect + github.com/pion/stun v0.6.1 // indirect + github.com/pion/transport/v2 v2.2.4 // indirect + github.com/pion/turn/v2 v2.1.4 // indirect + github.com/pion/webrtc/v3 v3.2.23 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/polydawn/refmt v0.89.0 // indirect - github.com/prometheus/client_model v0.5.0 // indirect - github.com/prometheus/common v0.46.0 // indirect + github.com/prometheus/client_model v0.6.0 // indirect + github.com/prometheus/common v0.47.0 // indirect github.com/prometheus/procfs v0.12.0 // indirect github.com/prometheus/statsd_exporter v0.22.7 // indirect github.com/quic-go/qpack v0.4.0 // indirect - github.com/quic-go/qtls-go1-20 v0.4.1 // indirect - github.com/quic-go/quic-go v0.40.1 // indirect + github.com/quic-go/quic-go v0.41.0 // indirect github.com/quic-go/webtransport-go v0.6.0 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/rs/cors v1.7.0 // indirect @@ -234,11 +233,11 @@ require ( go.uber.org/atomic v1.11.0 // indirect go.uber.org/mock v0.4.0 // indirect go4.org v0.0.0-20230225012048-214862532bf5 // indirect - golang.org/x/net v0.20.0 // indirect + golang.org/x/net v0.21.0 // indirect golang.org/x/oauth2 v0.16.0 // indirect - golang.org/x/term v0.16.0 // indirect + golang.org/x/term v0.17.0 // indirect golang.org/x/text v0.14.0 // indirect - golang.org/x/tools v0.17.0 // indirect + golang.org/x/tools v0.18.0 // indirect golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect gonum.org/v1/gonum v0.14.0 // indirect google.golang.org/appengine v1.6.8 // indirect @@ -251,4 +250,6 @@ require ( lukechampine.com/blake3 v1.2.1 // indirect ) -go 1.20 +go 1.21 + +toolchain go1.21.7 diff --git a/go.sum b/go.sum index 259e0eab8..004c01809 100644 --- a/go.sum +++ b/go.sum @@ -131,6 +131,7 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c h1:pFUpOrbxDR6AkioZ1ySsx5yxlDQZ8stG2b88gTPxgJU= github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c/go.mod h1:6UhI8N9EjYm1c2odKpFpAYeR8dsBeM7PtzQhRgxRr9U= github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y= +github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= @@ -162,13 +163,14 @@ github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= -github.com/flynn/noise v1.0.1 h1:vPp/jdQLXC6ppsXSj/pM3W1BIJ5FEHE2TulSJBpb43Y= -github.com/flynn/noise v1.0.1/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag= +github.com/flynn/noise v1.1.0 h1:KjPQoQCEFdZDiP03phOvGi11+SVVhBG2wOWAorLsstg= +github.com/flynn/noise v1.1.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag= github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk= github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/frankban/quicktest v1.14.0/go.mod h1:NeW+ay9A/U67EYXNFA1nPE8e/tnQv/09mUdL/ijj8og= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= +github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= @@ -264,6 +266,7 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -278,12 +281,12 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20231229205709-960ae82b1e42 h1:dHLYa5D8/Ta0aLR2XcPsrkpAgGeFs6thhMcQK0oQ0n8= -github.com/google/pprof v0.0.0-20231229205709-960ae82b1e42/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= +github.com/google/pprof v0.0.0-20240207164012-fb44976bdcd5 h1:E/LAvt58di64hlYjx7AsNS6C/ysHWYo+2qPCZKTQhRo= +github.com/google/pprof v0.0.0-20240207164012-fb44976bdcd5/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU= github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= @@ -292,10 +295,11 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c h1:7lF+Vz0LqiRidnzC1Oq86fpX1q/iEv2KJdrCtttYjT4= +github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= -github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= -github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= +github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0 h1:Wqo399gCIufwto+VfwCSvsnfGpF/w5E9CNxSwbpD6No= @@ -330,6 +334,7 @@ github.com/ipfs/boxo v0.18.0/go.mod h1:pIZgTWdm3k3pLF9Uq6MB8JEcW07UDwNJjlXW1HELW github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= +github.com/ipfs/go-bitswap v0.11.0/go.mod h1:05aE8H3XOU+LXpTedeAS0OZpcO1WFsj5niYQH9a1Tmk= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= github.com/ipfs/go-block-format v0.0.3/go.mod h1:4LmD4ZUw0mhO+JSKdpWwrzATiEfM7WWgQ8H5l6P8MVk= github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs= @@ -368,6 +373,7 @@ github.com/ipfs/go-fs-lock v0.0.7/go.mod h1:Js8ka+FNYmgQRLrRXzU3CB/+Csr1BwrRilEc github.com/ipfs/go-ipfs-blockstore v1.3.0 h1:m2EXaWgwTzAfsmt5UdJ7Is6l4gJcaM/A12XwJyvYvMM= github.com/ipfs/go-ipfs-blockstore v1.3.0/go.mod h1:KgtZyc9fq+P2xJUiCAzbRdhhqJHvsw8u2Dlqy2MyRTE= github.com/ipfs/go-ipfs-blocksutil v0.0.1 h1:Eh/H4pc1hsvhzsQoMEP3Bke/aW5P5rVM1IWFJMcGIPQ= +github.com/ipfs/go-ipfs-blocksutil v0.0.1/go.mod h1:Yq4M86uIOmxmGPUHv/uI7uKqZNtLb449gwKqXjIsnRk= github.com/ipfs/go-ipfs-chunker v0.0.5 h1:ojCf7HV/m+uS2vhUGWcogIIxiO5ubl5O57Q7NapWLY8= github.com/ipfs/go-ipfs-chunker v0.0.5/go.mod h1:jhgdF8vxRHycr00k13FM8Y0E+6BoalYeobXmUyTreP8= github.com/ipfs/go-ipfs-cmds v0.10.0 h1:ZB4+RgYaH4UARfJY0uLKl5UXgApqnRjKbuCiJVcErYk= @@ -380,11 +386,13 @@ github.com/ipfs/go-ipfs-ds-help v1.1.0/go.mod h1:YR5+6EaebOhfcqVCyqemItCLthrpVNo github.com/ipfs/go-ipfs-exchange-interface v0.2.0 h1:8lMSJmKogZYNo2jjhUs0izT+dck05pqUw4mWNW9Pw6Y= github.com/ipfs/go-ipfs-exchange-interface v0.2.0/go.mod h1:z6+RhJuDQbqKguVyslSOuVDhqF9JtTrO3eptSAiW2/Y= github.com/ipfs/go-ipfs-exchange-offline v0.3.0 h1:c/Dg8GDPzixGd0MC8Jh6mjOwU57uYokgWRFidfvEkuA= +github.com/ipfs/go-ipfs-exchange-offline v0.3.0/go.mod h1:MOdJ9DChbb5u37M1IcbrRB02e++Z7521fMxqCNRrz9s= github.com/ipfs/go-ipfs-pq v0.0.3 h1:YpoHVJB+jzK15mr/xsWC574tyDLkezVrDNeaalQBsTE= github.com/ipfs/go-ipfs-pq v0.0.3/go.mod h1:btNw5hsHBpRcSSgZtiNm/SLj5gYIZ18AKtv3kERkRb4= github.com/ipfs/go-ipfs-redirects-file v0.1.1 h1:Io++k0Vf/wK+tfnhEh63Yte1oQK5VGT2hIEYpD0Rzx8= github.com/ipfs/go-ipfs-redirects-file v0.1.1/go.mod h1:tAwRjCV0RjLTjH8DR/AU7VYvfQECg+lpUy2Mdzv7gyk= github.com/ipfs/go-ipfs-routing v0.3.0 h1:9W/W3N+g+y4ZDeffSgqhgo7BsBSJwPMcyssET9OWevc= +github.com/ipfs/go-ipfs-routing v0.3.0/go.mod h1:dKqtTFIql7e1zYsEuWLyuOU+E0WJWW8JjbTPLParDWo= github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyBCNzQxlJBc= github.com/ipfs/go-ipfs-util v0.0.2/go.mod h1:CbPtkWJzjLdEcezDns2XYaehFVNXG9zrdrtMecczcsQ= github.com/ipfs/go-ipfs-util v0.0.3 h1:2RFdGez6bu2ZlZdI+rWfIdbQb1KudQp3VGwPtdNCmE0= @@ -416,6 +424,7 @@ github.com/ipfs/go-metrics-prometheus v0.0.2/go.mod h1:ELLU99AQQNi+zX6GCGm2lAgnz github.com/ipfs/go-peertaskqueue v0.8.1 h1:YhxAs1+wxb5jk7RvS0LHdyiILpNmRIRnZVztekOF0pg= github.com/ipfs/go-peertaskqueue v0.8.1/go.mod h1:Oxxd3eaK279FxeydSPPVGHzbwVeHjatZ2GA8XD+KbPU= github.com/ipfs/go-unixfs v0.4.5 h1:wj8JhxvV1G6CD7swACwSKYa+NgtdWC1RUit+gFnymDU= +github.com/ipfs/go-unixfs v0.4.5/go.mod h1:BIznJNvt/gEx/ooRMI4Us9K8+qeGO7vx1ohnbk8gjFg= github.com/ipfs/go-unixfsnode v1.9.0 h1:ubEhQhr22sPAKO2DNsyVBW7YB/zA8Zkif25aBvz8rc8= github.com/ipfs/go-unixfsnode v1.9.0/go.mod h1:HxRu9HYHOjK6HUqFBAi++7DVoWAHn0o4v/nZ/VA+0g8= github.com/ipfs/go-verifcid v0.0.2 h1:XPnUv0XmdH+ZIhLGKg6U2vaPaRDXb9urMyNVCE7uvTs= @@ -431,6 +440,7 @@ github.com/ipld/go-ipld-prime v0.14.1/go.mod h1:QcE4Y9n/ZZr8Ijg5bGPT0GqYWgZ1704n github.com/ipld/go-ipld-prime v0.21.0 h1:n4JmcpOlPDIxBcY037SVfpd1G+Sj1nKZah0m6QH9C2E= github.com/ipld/go-ipld-prime v0.21.0/go.mod h1:3RLqy//ERg/y5oShXXdx5YIp50cFGOanyMctpPjsvxQ= github.com/ipld/go-ipld-prime/storage/bsadapter v0.0.0-20230102063945-1a409dc236dd h1:gMlw/MhNr2Wtp5RwGdsW23cs+yCuj9k2ON7i9MiJlRo= +github.com/ipld/go-ipld-prime/storage/bsadapter v0.0.0-20230102063945-1a409dc236dd/go.mod h1:wZ8hH8UxeryOs4kJEJaiui/s00hDSbE37OKsL47g+Sw= github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/jbenet/go-cienv v0.1.0 h1:Vc/s0QbQtoxX8MwwSLWWh+xNNZvM3Lw7NsTcHrvvhMc= @@ -465,12 +475,12 @@ github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQL 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.17.4 h1:Ej5ixsIri7BrIjBkRZLTo6ghwrEtHFk7ijlczPW4fZ4= -github.com/klauspost/compress v1.17.4/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= +github.com/klauspost/compress v1.17.6 h1:60eq2E/jlfwQXtvZEeBUYADs+BwKBWURIY+Gj2eRGjI= +github.com/klauspost/compress v1.17.6/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/48xc= -github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= +github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/koron/go-ssdp v0.0.4 h1:1IDwrghSKYM7yLf7XCzbByg2sJ/JcNOZRXS2jczTwz0= @@ -481,6 +491,7 @@ github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfn github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= @@ -498,8 +509,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.32.2 h1:s8GYN4YJzgUoyeYNPdW7JZeZ5Ee31iNaIBfGYMAY4FQ= -github.com/libp2p/go-libp2p v0.32.2/go.mod h1:E0LKe+diV/ZVJVnOJby8VC5xzHF0660osg71skcxJvk= +github.com/libp2p/go-libp2p v0.33.0 h1:yTPSr8sJRbfeEYXyeN8VPVSlTlFjtMUwGDRniwaf/xQ= +github.com/libp2p/go-libp2p v0.33.0/go.mod h1:RIJFRQVUBKy82dnW7J5f1homqqv6NcsDJAl3e7CRGfE= github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94= github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= @@ -654,16 +665,17 @@ github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9k github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.13.2 h1:Bi2gGVkfn6gQcjNjZJVO8Gf0FHzMPf2phUei9tejVMs= -github.com/onsi/ginkgo/v2 v2.13.2/go.mod h1:XStQ8QcGwLyF4HdfcZB8SFOS/MWCgDuXMSBe6zrvLgM= +github.com/onsi/ginkgo/v2 v2.15.0 h1:79HwNRBAZHOEwrczrgSOPy+eFTTlIGELKy5as+ClttY= +github.com/onsi/ginkgo/v2 v2.15.0/go.mod h1:HlxMHtYF57y6Dpf+mc5529KKmSq9h2FpCF+/ZkwUxKM= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= -github.com/onsi/gomega v1.29.0 h1:KIA/t2t5UBzoirT4H9tsML45GEbo3ouUnBHsCfD2tVg= +github.com/onsi/gomega v1.30.0 h1:hvMK7xYz4D3HapigLTeGdId/NcfQx1VHMJc60ew99+8= +github.com/onsi/gomega v1.30.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opencontainers/runtime-spec v1.1.0 h1:HHUyrt9mwHUjtasSbXSMvs4cyFxh+Bll4AjJ9odEGpg= -github.com/opencontainers/runtime-spec v1.1.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/runtime-spec v1.2.0 h1:z97+pHb3uELt/yiAWD691HNHQIF07bE7dzrbT927iTk= +github.com/opencontainers/runtime-spec v1.2.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= @@ -678,43 +690,51 @@ github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 h1:1/WtZae0yGtPq+TI6+ github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9/go.mod h1:x3N5drFsm2uilKKuuYo6LdyD8vZAW55sH/9w+pbo1sw= github.com/pion/datachannel v1.5.5 h1:10ef4kwdjije+M9d7Xm9im2Y3O6A6ccQb0zcqZcJew8= github.com/pion/datachannel v1.5.5/go.mod h1:iMz+lECmfdCMqFRhXhcA/219B0SQlbpoR2V118yimL0= -github.com/pion/dtls/v2 v2.2.7 h1:cSUBsETxepsCSFSxC3mc/aDo14qQLMSL+O6IjG28yV8= github.com/pion/dtls/v2 v2.2.7/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s= -github.com/pion/ice/v2 v2.3.6 h1:Jgqw36cAud47iD+N6rNX225uHvrgWtAlHfVyOQc3Heg= -github.com/pion/ice/v2 v2.3.6/go.mod h1:9/TzKDRwBVAPsC+YOrKH/e3xDrubeTRACU9/sHQarsU= -github.com/pion/interceptor v0.1.17 h1:prJtgwFh/gB8zMqGZoOgJPHivOwVAp61i2aG61Du/1w= -github.com/pion/interceptor v0.1.17/go.mod h1:SY8kpmfVBvrbUzvj2bsXz7OJt5JvmVNZ+4Kjq7FcwrI= +github.com/pion/dtls/v2 v2.2.8 h1:BUroldfiIbV9jSnC6cKOMnyiORRWrWWpV11JUyEu5OA= +github.com/pion/dtls/v2 v2.2.8/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s= +github.com/pion/ice/v2 v2.3.11 h1:rZjVmUwyT55cmN8ySMpL7rsS8KYsJERsrxJLLxpKhdw= +github.com/pion/ice/v2 v2.3.11/go.mod h1:hPcLC3kxMa+JGRzMHqQzjoSj3xtE9F+eoncmXLlCL4E= +github.com/pion/interceptor v0.1.25 h1:pwY9r7P6ToQ3+IF0bajN0xmk/fNw/suTgaTdlwTDmhc= +github.com/pion/interceptor v0.1.25/go.mod h1:wkbPYAak5zKsfpVDYMtEfWEy8D4zL+rpxCxPImLOg3Y= github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY= github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms= -github.com/pion/mdns v0.0.7 h1:P0UB4Sr6xDWEox0kTVxF0LmQihtCbSAdW0H2nEgkA3U= -github.com/pion/mdns v0.0.7/go.mod h1:4iP2UbeFhLI/vWju/bw6ZfwjJzk0z8DNValjGxR/dD8= +github.com/pion/mdns v0.0.8/go.mod h1:hYE72WX8WDveIhg7fmXgMKivD3Puklk0Ymzog0lSyaI= +github.com/pion/mdns v0.0.9 h1:7Ue5KZsqq8EuqStnpPWV33vYYEH0+skdDN5L7EiEsI4= +github.com/pion/mdns v0.0.9/go.mod h1:2JA5exfxwzXiCihmxpTKgFUpiQws2MnipoPK09vecIc= github.com/pion/randutil v0.1.0 h1:CFG1UdESneORglEsnimhUjf33Rwjubwj6xfiOXBa3mA= github.com/pion/randutil v0.1.0/go.mod h1:XcJrSMMbbMRhASFVOlj/5hQial/Y8oH/HVo7TBZq+j8= -github.com/pion/rtcp v1.2.10 h1:nkr3uj+8Sp97zyItdN60tE/S6vk4al5CPRR6Gejsdjc= github.com/pion/rtcp v1.2.10/go.mod h1:ztfEwXZNLGyF1oQDttz/ZKIBaeeg/oWbRYqzBM9TL1I= -github.com/pion/rtp v1.7.13 h1:qcHwlmtiI50t1XivvoawdCGTP4Uiypzfrsap+bijcoA= -github.com/pion/rtp v1.7.13/go.mod h1:bDb5n+BFZxXx0Ea7E5qe+klMuqiBrP+w8XSjiWtCUko= +github.com/pion/rtcp v1.2.12/go.mod h1:sn6qjxvnwyAkkPzPULIbVqSKI5Dv54Rv7VG0kNxh9L4= +github.com/pion/rtcp v1.2.13 h1:+EQijuisKwm/8VBs8nWllr0bIndR7Lf7cZG200mpbNo= +github.com/pion/rtcp v1.2.13/go.mod h1:sn6qjxvnwyAkkPzPULIbVqSKI5Dv54Rv7VG0kNxh9L4= +github.com/pion/rtp v1.8.2/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU= +github.com/pion/rtp v1.8.3 h1:VEHxqzSVQxCkKDSHro5/4IUUG1ea+MFdqR2R3xSpNU8= +github.com/pion/rtp v1.8.3/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU= github.com/pion/sctp v1.8.5/go.mod h1:SUFFfDpViyKejTAdwD1d/HQsCu+V/40cCs2nZIvC3s0= -github.com/pion/sctp v1.8.7 h1:JnABvFakZueGAn4KU/4PSKg+GWbF6QWbKTWZOSGJjXw= -github.com/pion/sctp v1.8.7/go.mod h1:g1Ul+ARqZq5JEmoFy87Q/4CePtKnTJ1QCL9dBBdN6AU= +github.com/pion/sctp v1.8.8/go.mod h1:igF9nZBrjh5AtmKc7U30jXltsFHicFCXSmWA2GWRaWs= +github.com/pion/sctp v1.8.9 h1:TP5ZVxV5J7rz7uZmbyvnUvsn7EJ2x/5q9uhsTtXbI3g= +github.com/pion/sctp v1.8.9/go.mod h1:cMLT45jqw3+jiJCrtHVwfQLnfR0MGZ4rgOJwUOIqLkI= github.com/pion/sdp/v3 v3.0.6 h1:WuDLhtuFUUVpTfus9ILC4HRyHsW6TdugjEX/QY9OiUw= github.com/pion/sdp/v3 v3.0.6/go.mod h1:iiFWFpQO8Fy3S5ldclBkpXqmWy02ns78NOKoLLL0YQw= -github.com/pion/srtp/v2 v2.0.15 h1:+tqRtXGsGwHC0G0IUIAzRmdkHvriF79IHVfZGfHrQoA= -github.com/pion/srtp/v2 v2.0.15/go.mod h1:b/pQOlDrbB0HEH5EUAQXzSYxikFbNcNuKmF8tM0hCtw= -github.com/pion/stun v0.4.0/go.mod h1:QPsh1/SbXASntw3zkkrIk3ZJVKz4saBY2G7S10P3wCw= -github.com/pion/stun v0.6.0 h1:JHT/2iyGDPrFWE8NNC15wnddBN8KifsEDw8swQmrEmU= -github.com/pion/stun v0.6.0/go.mod h1:HPqcfoeqQn9cuaet7AOmB5e5xkObu9DwBdurwLKO9oA= +github.com/pion/srtp/v2 v2.0.18 h1:vKpAXfawO9RtTRKZJbG4y0v1b11NZxQnxRl85kGuUlo= +github.com/pion/srtp/v2 v2.0.18/go.mod h1:0KJQjA99A6/a0DOVTu1PhDSw0CXF2jTkqOoMg3ODqdA= +github.com/pion/stun v0.6.1 h1:8lp6YejULeHBF8NmV8e2787BogQhduZugh5PdhDyyN4= +github.com/pion/stun v0.6.1/go.mod h1:/hO7APkX4hZKu/D0f2lHzNyvdkTGtIy3NDmLR7kSz/8= github.com/pion/transport v0.14.1 h1:XSM6olwW+o8J4SCmOBb/BpwZypkHeyM0PGFCxNQBr40= github.com/pion/transport v0.14.1/go.mod h1:4tGmbk00NeYA3rUa9+n+dzCCoKkcy3YlYb99Jn2fNnI= -github.com/pion/transport/v2 v2.0.0/go.mod h1:HS2MEBJTwD+1ZI2eSXSvHJx/HnzQqRy2/LXxt6eVMHc= -github.com/pion/transport/v2 v2.1.0/go.mod h1:AdSw4YBZVDkZm8fpoz+fclXyQwANWmZAlDuQdctTThQ= -github.com/pion/transport/v2 v2.2.0/go.mod h1:AdSw4YBZVDkZm8fpoz+fclXyQwANWmZAlDuQdctTThQ= -github.com/pion/transport/v2 v2.2.1 h1:7qYnCBlpgSJNYMbLCKuSY9KbQdBFoETvPNETv0y4N7c= github.com/pion/transport/v2 v2.2.1/go.mod h1:cXXWavvCnFF6McHTft3DWS9iic2Mftcz1Aq29pGcU5g= -github.com/pion/turn/v2 v2.1.0 h1:5wGHSgGhJhP/RpabkUb/T9PdsAjkGLS6toYz5HNzoSI= -github.com/pion/turn/v2 v2.1.0/go.mod h1:yrT5XbXSGX1VFSF31A3c1kCNB5bBZgk/uu5LET162qs= -github.com/pion/webrtc/v3 v3.2.9 h1:U8NSjQDlZZ+Iy/hg42Q/u6mhEVSXYvKrOIZiZwYTfLc= -github.com/pion/webrtc/v3 v3.2.9/go.mod h1:gjQLMZeyN3jXBGdxGmUYCyKjOuYX/c99BDjGqmadq0A= +github.com/pion/transport/v2 v2.2.2/go.mod h1:OJg3ojoBJopjEeECq2yJdXH9YVrUJ1uQ++NjXLOUorc= +github.com/pion/transport/v2 v2.2.3/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0= +github.com/pion/transport/v2 v2.2.4 h1:41JJK6DZQYSeVLxILA2+F4ZkKb4Xd/tFJZRFZQ9QAlo= +github.com/pion/transport/v2 v2.2.4/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0= +github.com/pion/transport/v3 v3.0.1 h1:gDTlPJwROfSfz6QfSi0ZmeCSkFcnWWiiR9ES0ouANiM= +github.com/pion/transport/v3 v3.0.1/go.mod h1:UY7kiITrlMv7/IKgd5eTUcaahZx5oUN3l9SzK5f5xE0= +github.com/pion/turn/v2 v2.1.3/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY= +github.com/pion/turn/v2 v2.1.4 h1:2xn8rduI5W6sCZQkEnIUDAkrBQNl2eYIBCHMZ3QMmP8= +github.com/pion/turn/v2 v2.1.4/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY= +github.com/pion/webrtc/v3 v3.2.23 h1:GbqEuxBbVLFhXk0GwxKAoaIJYiEa9TyoZPEZC+2HZxM= +github.com/pion/webrtc/v3 v3.2.23/go.mod h1:1CaT2fcZzZ6VZA+O1i9yK2DU4EOcXVvSbWG9pr5jefs= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -739,8 +759,8 @@ github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1: github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= -github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= +github.com/prometheus/client_model v0.6.0 h1:k1v3CzpSRUTrKMppY35TLwPvxHqBu0bYgxZzqGIgaos= +github.com/prometheus/client_model v0.6.0/go.mod h1:NTQHnmxFpouOD0DpvP4XujX3CdOAGQPoaGhyTchlyt8= github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= @@ -749,8 +769,8 @@ github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9 github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/common v0.35.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= -github.com/prometheus/common v0.46.0 h1:doXzt5ybi1HBKpsZOL0sSkaNHJJqkyfEWZGGqqScV0Y= -github.com/prometheus/common v0.46.0/go.mod h1:Tp0qkxpb9Jsg54QMe+EAmqXkSV7Evdy1BTn+g2pa/hQ= +github.com/prometheus/common v0.47.0 h1:p5Cz0FNHo7SnWOmWmoRozVcjEp0bIVU8cV7OShpjL1k= +github.com/prometheus/common v0.47.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= @@ -765,10 +785,8 @@ github.com/prometheus/statsd_exporter v0.22.7 h1:7Pji/i2GuhK6Lu7DHrtTkFmNBCudCPT github.com/prometheus/statsd_exporter v0.22.7/go.mod h1:N/TevpjkIh9ccs6nuzY3jQn9dFqnUakOjnEuMPJJJnI= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= -github.com/quic-go/qtls-go1-20 v0.4.1 h1:D33340mCNDAIKBqXuAvexTNMUByrYmFYVfKfDN5nfFs= -github.com/quic-go/qtls-go1-20 v0.4.1/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= -github.com/quic-go/quic-go v0.40.1 h1:X3AGzUNFs0jVuO3esAGnTfvdgvL4fq655WaOi1snv1Q= -github.com/quic-go/quic-go v0.40.1/go.mod h1:PeN7kuVJ4xZbxSv/4OX6S1USOX8MJvydwpTx31vx60c= +github.com/quic-go/quic-go v0.41.0 h1:aD8MmHfgqTURWNJy48IYFg2OnxwHT3JL7ahGs73lb4k= +github.com/quic-go/quic-go v0.41.0/go.mod h1:qCkNjqczPEvgsOnxZ0eCD14lv+B2LHlFAB++CNOh9hA= github.com/quic-go/webtransport-go v0.6.0 h1:CvNsKqc4W2HljHJnoT+rMmbRJybShZ0YPFDD3NxaZLY= github.com/quic-go/webtransport-go v0.6.0/go.mod h1:9KjU4AEBqEQidGHNDkZrb8CAa1abRaosM2yGOyiikEc= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= @@ -776,6 +794,7 @@ github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtD github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= +github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= @@ -846,7 +865,6 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= @@ -867,6 +885,7 @@ github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhso github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/tj/assert v0.0.3 h1:Df/BlaZ20mq6kuai7f5z2TvPFiwC3xaWJSDQNiIS3Rk= +github.com/tj/assert v0.0.3/go.mod h1:Ne6X72Q+TB1AteidzQncjw9PabbMp4PBMZ1k+vd1Pvk= github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c h1:u6SKchux2yDvFQnDHS3lPnIRmfVJ5Sxy3ao2SIdysLQ= github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM= github.com/ucarion/urlpath v0.0.0-20200424170820-7ccc79b76bbb h1:Ywfo8sUltxogBpFuMOFRrrSifO788kAFxmvVw31PtQQ= @@ -880,6 +899,7 @@ github.com/wangjia184/sortedset v0.0.0-20160527075905-f5d03557ba30/go.mod h1:Yko github.com/warpfork/go-testmark v0.3.0/go.mod h1:jhEf8FVxd+F17juRubpmut64NEG6I2rgkUhlcqqXwE0= github.com/warpfork/go-testmark v0.9.0/go.mod h1:jhEf8FVxd+F17juRubpmut64NEG6I2rgkUhlcqqXwE0= github.com/warpfork/go-testmark v0.12.1 h1:rMgCpJfwy1sJ50x0M0NgyphxYYPMOODIJHhsXyEHU0s= +github.com/warpfork/go-testmark v0.12.1/go.mod h1:kHwy7wfvGSPh1rQJYKayD4AbtNaeyZdcGi9tNJTaa5Y= github.com/warpfork/go-wish v0.0.0-20200122115046-b9ea61034e4a/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0 h1:GDDkbFiaK8jsSDJfjId/PEGEShv6ugrt4kYsC5UIDaQ= github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= @@ -959,6 +979,7 @@ go.uber.org/fx v1.20.1 h1:zVwVQGS8zYvhh9Xxcu4w1M6ESyeMzebzj2NbSayZ4Mk= go.uber.org/fx v1.20.1/go.mod h1:iSYNbHf2y55acNCwCXKx7LbWb5WG1Bnue5RDXz1OREg= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= @@ -971,8 +992,8 @@ go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.14.1/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= -go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= -go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= +go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= +go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= go4.org v0.0.0-20200411211856-f5505b9728dd/go.mod h1:CIiUVy99QCPfoE13bO4EZaz5GZMZXMSBGhxRdsvzbkg= go4.org v0.0.0-20230225012048-214862532bf5 h1:nifaUDeh+rPaBCMPMQHZmvJf+QdpLFnuQPwx+LxVmtc= @@ -995,9 +1016,12 @@ golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWP golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= -golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= -golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc= -golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= +golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= +golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= +golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= +golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= +golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= +golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1008,8 +1032,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20240119083558-1b970713d09a h1:Q8/wZp0KX97QFTc2ywcOE0YRjZPVIx+MXInMzdvQqcA= -golang.org/x/exp v0.0.0-20240119083558-1b970713d09a/go.mod h1:idGWGoKP1toJGkd5/ig9ZLuPcZBC3ewk7SzmH0uou08= +golang.org/x/exp v0.0.0-20240213143201-ec583247a57a h1:HinSgX1tJRX3KsL//Gxynpw5CTOAIPhgL4W8PNiIpVE= +golang.org/x/exp v0.0.0-20240213143201-ec583247a57a/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1034,8 +1058,8 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= -golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8= +golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1084,14 +1108,16 @@ golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= -golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= -golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= +golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ= +golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= +golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= +golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= +golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1190,24 +1216,29 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= -golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= -golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE= -golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= +golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo= +golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= +golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= +golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= +golang.org/x/term v0.17.0 h1:mkTF7LCd6WGJNL3K1Ad7kwxNfYAW6a8a8QqtMblp/4U= +golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1217,10 +1248,12 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1281,8 +1314,8 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc= -golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps= +golang.org/x/tools v0.18.0 h1:k8NLag8AGHnn+PHbl7g43CtqZAwG60vZkLqgyZgIHgQ= +golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1354,6 +1387,7 @@ google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20240102182953-50ed04b92917 h1:nz5NESFLZbJGPFxDT/HCn+V1mZ8JGNoY4nUpmW/Y2eg= +google.golang.org/genproto v0.0.0-20240102182953-50ed04b92917/go.mod h1:pZqR+glSb11aJ+JQcczCvgf47+duRuzNSKqE8YAQnV0= google.golang.org/genproto/googleapis/api v0.0.0-20240108191215-35c7eff3a6b1 h1:OPXtXn7fNMaXwO3JvOmF1QyTc00jsSFFz1vXXBOdCDo= google.golang.org/genproto/googleapis/api v0.0.0-20240108191215-35c7eff3a6b1/go.mod h1:B5xPO//w8qmBDjGReYLpR6UJPnkldGkCSMoH/2vxJeg= google.golang.org/genproto/googleapis/rpc v0.0.0-20240108191215-35c7eff3a6b1 h1:gphdwh0npgs8elJ4T6J+DQJHPVF7RsuJHCfwztUb4J4= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index ef6eb0f52..9e38a7086 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -1,6 +1,8 @@ module github.com/ipfs/kubo/test/dependencies -go 1.20 +go 1.21 + +toolchain go1.21.7 replace github.com/ipfs/kubo => ../../ @@ -124,7 +126,7 @@ require ( github.com/kisielk/errcheck v1.6.3 // indirect github.com/kisielk/gotool v1.0.0 // indirect github.com/kkHAIKE/contextcheck v1.1.4 // indirect - github.com/klauspost/cpuid/v2 v2.2.6 // indirect + github.com/klauspost/cpuid/v2 v2.2.7 // indirect github.com/kulti/thelper v0.6.3 // indirect github.com/kunwardeep/paralleltest v1.0.8 // indirect github.com/kyoh86/exportloopref v0.1.11 // indirect @@ -133,7 +135,7 @@ require ( github.com/leonklingele/grouper v1.1.1 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/libp2p/go-cidranger v1.1.0 // indirect - github.com/libp2p/go-libp2p v0.32.2 // indirect + github.com/libp2p/go-libp2p v0.33.0 // indirect github.com/libp2p/go-libp2p-asn-util v0.4.1 // indirect github.com/libp2p/go-libp2p-kad-dht v0.24.4 // indirect github.com/libp2p/go-libp2p-kbucket v0.6.3 // indirect @@ -179,8 +181,8 @@ require ( github.com/polydawn/refmt v0.89.0 // indirect github.com/polyfloyd/go-errorlint v1.4.3 // indirect github.com/prometheus/client_golang v1.18.0 // indirect - github.com/prometheus/client_model v0.5.0 // indirect - github.com/prometheus/common v0.46.0 // indirect + github.com/prometheus/client_model v0.6.0 // indirect + github.com/prometheus/common v0.47.0 // indirect github.com/prometheus/procfs v0.12.0 // indirect github.com/quasilyte/go-ruleguard v0.4.0 // indirect github.com/quasilyte/gogrep v0.5.0 // indirect @@ -237,17 +239,17 @@ require ( go.opentelemetry.io/otel/trace v1.22.0 // indirect go.tmz.dev/musttag v0.7.1 // indirect go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap v1.26.0 // indirect - golang.org/x/crypto v0.18.0 // indirect - golang.org/x/exp v0.0.0-20240119083558-1b970713d09a // indirect + go.uber.org/zap v1.27.0 // indirect + golang.org/x/crypto v0.19.0 // indirect + golang.org/x/exp v0.0.0-20240213143201-ec583247a57a // indirect golang.org/x/exp/typeparams v0.0.0-20230307190834-24139beb5833 // indirect - golang.org/x/mod v0.14.0 // indirect - golang.org/x/net v0.20.0 // indirect + golang.org/x/mod v0.15.0 // indirect + golang.org/x/net v0.21.0 // indirect golang.org/x/sync v0.6.0 // indirect - golang.org/x/sys v0.16.0 // indirect - golang.org/x/term v0.16.0 // indirect + golang.org/x/sys v0.17.0 // indirect + golang.org/x/term v0.17.0 // indirect golang.org/x/text v0.14.0 // indirect - golang.org/x/tools v0.17.0 // indirect + golang.org/x/tools v0.18.0 // indirect gonum.org/v1/gonum v0.14.0 // indirect google.golang.org/protobuf v1.32.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 095dfb022..163c393ab 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -79,6 +79,7 @@ github.com/ashanbrown/makezero v1.1.1 h1:iCQ87C0V0vSyO+M9E/FZYbu65auqH0lnsOkf5Fc github.com/ashanbrown/makezero v1.1.1/go.mod h1:i1bJLCRSCHOcOa9Y6MyF2FTfMZMFdHvxKHxgO5Z1axI= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o= +github.com/benbjohnson/clock v1.3.5/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -114,11 +115,14 @@ github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGX github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM= +github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw= github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= +github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= 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.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/cskr/pubsub v1.0.2 h1:vlOzMhl6PFn60gRlTQQsIfVwaPB/B/8MziK8FhEPt/0= +github.com/cskr/pubsub v1.0.2/go.mod h1:/8MzYXk/NJAz782G8RPkFzXTZVu63VotefPnR9TIRis= github.com/curioswitch/go-reassign v0.2.0 h1:G9UZyOcpk/d7Gd6mqYgd8XYWFMw/znxwGDUstnC9DIo= github.com/curioswitch/go-reassign v0.2.0/go.mod h1:x6OpXuWvgfQaMGks2BZybTngWjT84hqJfKoO8Tt/Roc= github.com/daixiang0/gci v0.11.0 h1:XeQbFKkCRxvVyn06EOuNY6LPGBLVuB/W130c8FrnX6A= @@ -127,15 +131,19 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c h1:pFUpOrbxDR6AkioZ1ySsx5yxlDQZ8stG2b88gTPxgJU= +github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c/go.mod h1:6UhI8N9EjYm1c2odKpFpAYeR8dsBeM7PtzQhRgxRr9U= github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y= +github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= github.com/denis-tingaikin/go-header v0.4.3 h1:tEaZKAlqql6SKCY++utLmkPLd6K8IBM20Ha7UVm+mtU= github.com/denis-tingaikin/go-header v0.4.3/go.mod h1:0wOCWuN71D5qIgE2nz9KrKmuYBAC2Mra5RassOIQ2/c= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= +github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/elastic/gosigar v0.14.2 h1:Dg80n8cr90OZ7x+bAax/QjoW/XqTI11RmA79ZwIm9/4= +github.com/elastic/gosigar v0.14.2/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -155,9 +163,12 @@ github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4 github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94= github.com/firefart/nonamedreturns v1.0.4 h1:abzI1p7mAEPYuR4A+VLKn4eNDOycjYo2phmY9sfv40Y= github.com/firefart/nonamedreturns v1.0.4/go.mod h1:TDhe/tjI1BXo48CmYbUduTV7BdIga8MAO/xbKdcVsGI= -github.com/flynn/noise v1.0.1 h1:vPp/jdQLXC6ppsXSj/pM3W1BIJ5FEHE2TulSJBpb43Y= +github.com/flynn/noise v1.1.0 h1:KjPQoQCEFdZDiP03phOvGi11+SVVhBG2wOWAorLsstg= +github.com/flynn/noise v1.1.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag= github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk= +github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= +github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= @@ -181,6 +192,7 @@ github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/go-toolsmith/astcast v1.1.0 h1:+JN9xZV1A+Re+95pgnMgDboWNVnIMMQXwfBwLRPgSC8= github.com/go-toolsmith/astcast v1.1.0/go.mod h1:qdcuFWeGGS2xX5bLM/c3U9lewg7+Zu4mr+xPwZIB4ZU= github.com/go-toolsmith/astcopy v1.1.0 h1:YGwBN0WM+ekI/6SS6+52zLDEf8Yvp3n2seZITCUBt5s= @@ -193,6 +205,7 @@ github.com/go-toolsmith/astfmt v1.1.0/go.mod h1:OrcLlRwu0CuiIBp/8b5PYF9ktGVZUjlN github.com/go-toolsmith/astp v1.1.0 h1:dXPuCl6u2llURjdPLLDxJeZInAeZ0/eZwFJmqZMnpQA= github.com/go-toolsmith/astp v1.1.0/go.mod h1:0T1xFGz9hicKs8Z5MfAqSUitoUYS30pDMsRVIDHs8CA= github.com/go-toolsmith/pkgload v1.2.2 h1:0CtmHq/02QhxcF7E9N5LIFcYFsMR5rdovfqTtRKkgIk= +github.com/go-toolsmith/pkgload v1.2.2/go.mod h1:R2hxLNRKuAsiXCo2i5J6ZQPhnPMOVtU+f0arbFPWCus= github.com/go-toolsmith/strparse v1.0.0/go.mod h1:YI2nUKP9YGZnL/L1/DLFBfixrcjslWct4wyljWhSRy8= github.com/go-toolsmith/strparse v1.1.0 h1:GAioeZUK9TGxnLS+qfdqNbA4z0SSm5zVNtCQiyP2Bvw= github.com/go-toolsmith/strparse v1.1.0/go.mod h1:7ksGy58fsaQkGQlY8WVoBFNyEPMGuJin1rfoPS4lBSQ= @@ -204,6 +217,7 @@ github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaL github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= +github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= @@ -214,6 +228,7 @@ github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4er github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= @@ -290,7 +305,8 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20231229205709-960ae82b1e42 h1:dHLYa5D8/Ta0aLR2XcPsrkpAgGeFs6thhMcQK0oQ0n8= +github.com/google/pprof v0.0.0-20240207164012-fb44976bdcd5 h1:E/LAvt58di64hlYjx7AsNS6C/ysHWYo+2qPCZKTQhRo= +github.com/google/pprof v0.0.0-20240207164012-fb44976bdcd5/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU= @@ -300,9 +316,11 @@ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5m github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c h1:7lF+Vz0LqiRidnzC1Oq86fpX1q/iEv2KJdrCtttYjT4= +github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gordonklaus/ineffassign v0.0.0-20230610083614-0e73809eb601 h1:mrEEilTAUmaAORhssPPkxj84TsHrPMLBGW2Z4SoTxm8= github.com/gordonklaus/ineffassign v0.0.0-20230610083614-0e73809eb601/go.mod h1:Qcp2HIAYhR7mNUVSIxZww3Guk4it82ghYcEXIAk+QT0= -github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= +github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= +github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= github.com/gostaticanalysis/analysisutil v0.7.1 h1:ZMCjoue3DtDWQ5WyU16YbjbQEQ3VuzwxALrpYd+HeKk= github.com/gostaticanalysis/analysisutil v0.7.1/go.mod h1:v21E3hY37WKMGSnbsw2S/ojApNWb6C1//mXO48CXbVc= github.com/gostaticanalysis/comment v1.4.1/go.mod h1:ih6ZxzTHLdadaiSnF5WY3dxUoXfXAlTaRzuaNDlSado= @@ -314,6 +332,7 @@ github.com/gostaticanalysis/nilerr v0.1.1 h1:ThE+hJP0fEp4zWLkWHWcRyI2Od0p7DlgYG3 github.com/gostaticanalysis/nilerr v0.1.1/go.mod h1:wZYb6YI5YAxxq0i1+VJbY0s2YONW0HU0GPE3+5PWN4A= github.com/gostaticanalysis/testutil v0.3.1-0.20210208050101-bfb5c8eec0e4/go.mod h1:D+FIZ+7OahH3ePw/izIEeH5I06eKs1IKI4Xr64/Am3M= github.com/gostaticanalysis/testutil v0.4.0 h1:nhdCmubdmDF6VEatUNjgUZBJKWRqugoISdUv3PPQgHY= +github.com/gostaticanalysis/testutil v0.4.0/go.mod h1:bLIoPefWXrRi/ssLFWX1dx7Repi5x3CuviD3dgAZaBU= github.com/gxed/go-shellwords v1.0.3 h1:2TP32H4TAklZUdz84oj95BJhVnIrRasyx2j1cqH5K38= github.com/gxed/go-shellwords v1.0.3/go.mod h1:N7paucT91ByIjmVJHhvoarjoQnmsi3Jd3vH7VqgtMxQ= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -336,6 +355,7 @@ github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUq github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= +github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= @@ -355,8 +375,11 @@ github.com/ipfs/go-datastore v0.6.0/go.mod h1:rt5M3nNbSO/8q1t4LNkLyUwRs8HupMeN/8 github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk= github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps= github.com/ipfs/go-ipfs-blocksutil v0.0.1 h1:Eh/H4pc1hsvhzsQoMEP3Bke/aW5P5rVM1IWFJMcGIPQ= +github.com/ipfs/go-ipfs-blocksutil v0.0.1/go.mod h1:Yq4M86uIOmxmGPUHv/uI7uKqZNtLb449gwKqXjIsnRk= github.com/ipfs/go-ipfs-delay v0.0.1 h1:r/UXYyRcddO6thwOnhiznIAiSvxMECGgtv35Xs1IeRQ= +github.com/ipfs/go-ipfs-delay v0.0.1/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= github.com/ipfs/go-ipfs-pq v0.0.3 h1:YpoHVJB+jzK15mr/xsWC574tyDLkezVrDNeaalQBsTE= +github.com/ipfs/go-ipfs-pq v0.0.3/go.mod h1:btNw5hsHBpRcSSgZtiNm/SLj5gYIZ18AKtv3kERkRb4= github.com/ipfs/go-ipfs-util v0.0.3 h1:2RFdGez6bu2ZlZdI+rWfIdbQb1KudQp3VGwPtdNCmE0= github.com/ipfs/go-ipfs-util v0.0.3/go.mod h1:LHzG1a0Ig4G+iZ26UUOMjHd+lfM84LZCrn17xAKWBvs= github.com/ipfs/go-ipld-format v0.6.0 h1:VEJlA2kQ3LqFSIm5Vu6eIlSxD/Ze90xtc4Meten1F5U= @@ -371,6 +394,7 @@ github.com/ipfs/go-log/v2 v2.5.1/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOL github.com/ipfs/go-metrics-interface v0.0.1 h1:j+cpbjYvu4R8zbleSs36gvB7jR+wsL2fGD6n0jO4kdg= github.com/ipfs/go-metrics-interface v0.0.1/go.mod h1:6s6euYU4zowdslK0GKHmqaIZ3j/b/tL7HTWtJ4VPgWY= github.com/ipfs/go-peertaskqueue v0.8.1 h1:YhxAs1+wxb5jk7RvS0LHdyiILpNmRIRnZVztekOF0pg= +github.com/ipfs/go-peertaskqueue v0.8.1/go.mod h1:Oxxd3eaK279FxeydSPPVGHzbwVeHjatZ2GA8XD+KbPU= github.com/ipfs/hang-fds v0.1.0 h1:deBiFlWHsVGzJ0ZMaqscEqRM1r2O1rFZ59UiQXb1Xko= github.com/ipfs/hang-fds v0.1.0/go.mod h1:29VLWOn3ftAgNNgXg/al7b11UzuQ+w7AwtCGcTaWkbM= github.com/ipfs/iptb v1.4.0 h1:YFYTrCkLMRwk/35IMyC6+yjoQSHTEcNcefBStLJzgvo= @@ -382,12 +406,14 @@ github.com/ipld/go-codec-dagpb v1.6.0/go.mod h1:ANzFhfP2uMJxRBr8CE+WQWs5UsNa0pYt github.com/ipld/go-ipld-prime v0.21.0 h1:n4JmcpOlPDIxBcY037SVfpd1G+Sj1nKZah0m6QH9C2E= github.com/ipld/go-ipld-prime v0.21.0/go.mod h1:3RLqy//ERg/y5oShXXdx5YIp50cFGOanyMctpPjsvxQ= github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= +github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA= github.com/jbenet/go-random v0.0.0-20190219211222-123a90aedc0c h1:uUx61FiAa1GI6ZmVd2wf2vULeQZIKG66eybjNXKYCz4= github.com/jbenet/go-random v0.0.0-20190219211222-123a90aedc0c/go.mod h1:sdx1xVM9UuLw1tXnhJWN3piypTUO3vCIHYmG15KE/dU= github.com/jbenet/go-random-files v0.0.0-20190219210431-31b3f20ebded h1:fHCa28iw+qaRWZK4IqrntHxXALD5kKr/ESrpOCRRdrg= github.com/jbenet/go-random-files v0.0.0-20190219210431-31b3f20ebded/go.mod h1:FKvZrl5nnaGnTAMewcq0i7wM5zHD75e0lwlnF8q46uo= github.com/jbenet/go-temp-err-catcher v0.1.0 h1:zpb3ZH6wIE8Shj2sKS+khgRvf7T7RABoLk/+KKHggpk= +github.com/jbenet/go-temp-err-catcher v0.1.0/go.mod h1:0kJRvmDZXNMIiJirNPEYfhpPwbGVtZVWC34vc5WLsDk= github.com/jbenet/goprocess v0.1.4 h1:DRGOFReOMqqDNXwW70QkacFW0YN9QnwLV0Vqk+3oU0o= github.com/jbenet/goprocess v0.1.4/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= github.com/jgautheron/goconst v1.5.1 h1:HxVbL1MhydKs8R8n/HE5NPvzfaYmQJA3o879lE4+WcM= @@ -419,19 +445,23 @@ github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kkHAIKE/contextcheck v1.1.4 h1:B6zAaLhOEEcjvUgIYEqystmnFk1Oemn8bvJhbt0GMb8= github.com/kkHAIKE/contextcheck v1.1.4/go.mod h1:1+i/gWqokIa+dm31mqGLZhZJ7Uh44DJGZVmr6QRBNJg= -github.com/klauspost/compress v1.17.4 h1:Ej5ixsIri7BrIjBkRZLTo6ghwrEtHFk7ijlczPW4fZ4= -github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/48xc= -github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/klauspost/compress v1.17.6 h1:60eq2E/jlfwQXtvZEeBUYADs+BwKBWURIY+Gj2eRGjI= +github.com/klauspost/compress v1.17.6/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= +github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= +github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/koron/go-ssdp v0.0.4 h1:1IDwrghSKYM7yLf7XCzbByg2sJ/JcNOZRXS2jczTwz0= +github.com/koron/go-ssdp v0.0.4/go.mod h1:oDXq+E5IL5q0U8uSBcoAXzTzInwy5lEgC91HoKtbmZk= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kulti/thelper v0.6.3 h1:ElhKf+AlItIu+xGnI990no4cE2+XaSu1ULymV2Yulxs= github.com/kulti/thelper v0.6.3/go.mod h1:DsqKShOvP40epevkFrvIwkCMNYxMeTNjdWL4dqWHZ6I= github.com/kunwardeep/paralleltest v1.0.8 h1:Ul2KsqtzFxTlSU7IP0JusWlLiNqQaloB9vguyjbE558= @@ -449,8 +479,9 @@ github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QT github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38yPW7c= github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= -github.com/libp2p/go-libp2p v0.32.2 h1:s8GYN4YJzgUoyeYNPdW7JZeZ5Ee31iNaIBfGYMAY4FQ= -github.com/libp2p/go-libp2p v0.32.2/go.mod h1:E0LKe+diV/ZVJVnOJby8VC5xzHF0660osg71skcxJvk= +github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= +github.com/libp2p/go-libp2p v0.33.0 h1:yTPSr8sJRbfeEYXyeN8VPVSlTlFjtMUwGDRniwaf/xQ= +github.com/libp2p/go-libp2p v0.33.0/go.mod h1:RIJFRQVUBKy82dnW7J5f1homqqv6NcsDJAl3e7CRGfE= github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94= github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= github.com/libp2p/go-libp2p-kad-dht v0.24.4 h1:ktNiJe7ffsJ1wX3ULpMCwXts99mPqGFSE/Qn1i8pErQ= @@ -462,13 +493,17 @@ github.com/libp2p/go-libp2p-record v0.2.0/go.mod h1:I+3zMkvvg5m2OcSdoL0KPljyJyvN github.com/libp2p/go-libp2p-routing-helpers v0.7.3 h1:u1LGzAMVRK9Nqq5aYDVOiq/HaB93U9WWczBzGyAC5ZY= github.com/libp2p/go-libp2p-routing-helpers v0.7.3/go.mod h1:cN4mJAD/7zfPKXBcs9ze31JGYAZgzdABEm+q/hkswb8= github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA= +github.com/libp2p/go-libp2p-testing v0.12.0/go.mod h1:KcGDRXyN7sQCllucn1cOOS+Dmm7ujhfEyXQL5lvkcPg= github.com/libp2p/go-msgio v0.3.0 h1:mf3Z8B1xcFN314sWX+2vOTShIE0Mmn2TXn3YCUQGNj0= github.com/libp2p/go-msgio v0.3.0/go.mod h1:nyRM819GmVaF9LX3l03RMh10QdOroF++NBbxAb0mmDM= github.com/libp2p/go-nat v0.2.0 h1:Tyz+bUFAYqGyJ/ppPPymMGbIgNRH+WqC5QrT5fKrrGk= +github.com/libp2p/go-nat v0.2.0/go.mod h1:3MJr+GRpRkyT65EpVPBstXLvOlAPzUVlG6Pwg9ohLJk= github.com/libp2p/go-netroute v0.2.1 h1:V8kVrpD8GK0Riv15/7VN6RbUQ3URNZVosw7H2v9tksU= github.com/libp2p/go-netroute v0.2.1/go.mod h1:hraioZr0fhBjG0ZRXJJ6Zj2IVEVNx6tDTFQfSmcq7mQ= github.com/libp2p/go-reuseport v0.4.0 h1:nR5KU7hD0WxXCJbmw7r2rhRYruNRl2koHw8fQscQm2s= +github.com/libp2p/go-reuseport v0.4.0/go.mod h1:ZtI03j/wO5hZVDFo2jKywN6bYKWLOy8Se6DrI2E1cLU= github.com/libp2p/go-yamux/v4 v4.0.1 h1:FfDR4S1wj6Bw2Pqbc8Uz7pCxeRBPbwsBbEdfwiCypkQ= +github.com/libp2p/go-yamux/v4 v4.0.1/go.mod h1:NWjl8ZTLOGlozrXSOZ/HlfG++39iKNnM5wwmtQP1YB4= github.com/lufeee/execinquery v1.2.1 h1:hf0Ems4SHcUGBxpGN7Jz78z1ppVkP/837ZlETPCEtOM= github.com/lufeee/execinquery v1.2.1/go.mod h1:EC7DrEKView09ocscGHC+apXMIaorh4xqSxS/dy8SbM= github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo= @@ -478,6 +513,7 @@ github.com/maratori/testableexamples v1.0.0/go.mod h1:4rhjL1n20TUTT4vdh3RDqSizKL github.com/maratori/testpackage v1.1.1 h1:S58XVV5AD7HADMmD0fNnziNHqKvSdDuEKdPD1rNTU04= github.com/maratori/testpackage v1.1.1/go.mod h1:s4gRK/ym6AMrqpOa/kEbQTV4Q4jb7WeLZzVhVVVOQMc= 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/matoous/godox v0.0.0-20230222163458-006bad1f9d26 h1:gWg6ZQ4JhDfJPqlo2srm/LN17lpybq15AryXIRcWYLE= github.com/matoous/godox v0.0.0-20230222163458-006bad1f9d26/go.mod h1:1BELzlh859Sh1c6+90blK8lbYy0kwQf1bYlBhBysy1s= github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE= @@ -501,7 +537,9 @@ github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJys github.com/miekg/dns v1.1.58 h1:ca2Hdkz+cDg/7eNF6V56jjzuZ4aCAE+DbVkILdQWG/4= github.com/miekg/dns v1.1.58/go.mod h1:Ypv+3b/KadlvW9vJfXOTf300O4UqaHFzFCuHz+rPkBY= github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= +github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b/go.mod h1:lxPUiZwKoFL8DUUmalo2yJJUCxbPKtm8OKfqr2/FTNU= github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc h1:PTfri+PuQmWDqERdnNMiD9ZejrlswWrCpBEZgWOiTrc= +github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc/go.mod h1:cGKTAVKx4SxOuR/czcZ/E2RSJ3sfHs8FpHhQ5CWMf9s= github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM= @@ -530,6 +568,7 @@ github.com/multiformats/go-multiaddr v0.12.2/go.mod h1:GKyaTYjZRdcUhyOetrxTk9z0c github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A= github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk= github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E= +github.com/multiformats/go-multiaddr-fmt v0.1.0/go.mod h1:hGtDIW4PU4BqJ50gW2quDuPVjyWNZxToGUh/HwTZYJo= github.com/multiformats/go-multibase v0.2.0 h1:isdYCVLvksgWlMW9OZRYJEa9pZETFivncJHmHnnd87g= github.com/multiformats/go-multibase v0.2.0/go.mod h1:bFBZX4lKCA/2lyOFSAoKH5SS6oPyjtnzK/XTFDPkNuk= github.com/multiformats/go-multicodec v0.9.0 h1:pb/dlPnzee/Sxv/j4PmkDRxCOi3hXTz3IbPKOXWJkmg= @@ -559,11 +598,13 @@ github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6 github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w= github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo/v2 v2.13.2 h1:Bi2gGVkfn6gQcjNjZJVO8Gf0FHzMPf2phUei9tejVMs= +github.com/onsi/ginkgo/v2 v2.15.0 h1:79HwNRBAZHOEwrczrgSOPy+eFTTlIGELKy5as+ClttY= +github.com/onsi/ginkgo/v2 v2.15.0/go.mod h1:HlxMHtYF57y6Dpf+mc5529KKmSq9h2FpCF+/ZkwUxKM= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= -github.com/opencontainers/runtime-spec v1.1.0 h1:HHUyrt9mwHUjtasSbXSMvs4cyFxh+Bll4AjJ9odEGpg= +github.com/opencontainers/runtime-spec v1.2.0 h1:z97+pHb3uELt/yiAWD691HNHQIF07bE7dzrbT927iTk= +github.com/opencontainers/runtime-spec v1.2.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/otiai10/copy v1.2.0 h1:HvG945u96iNadPoG2/Ja2+AUJeW5YuFQMixq9yirC+k= @@ -573,6 +614,7 @@ github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6 github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo= github.com/otiai10/mint v1.3.1/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc= 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/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pelletier/go-toml/v2 v2.0.5 h1:ipoSadvV8oGUjnUbMub59IDPPwfxF694nG/jwbMiyQg= @@ -599,14 +641,14 @@ github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1: github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= -github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= +github.com/prometheus/client_model v0.6.0 h1:k1v3CzpSRUTrKMppY35TLwPvxHqBu0bYgxZzqGIgaos= +github.com/prometheus/client_model v0.6.0/go.mod h1:NTQHnmxFpouOD0DpvP4XujX3CdOAGQPoaGhyTchlyt8= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= -github.com/prometheus/common v0.46.0 h1:doXzt5ybi1HBKpsZOL0sSkaNHJJqkyfEWZGGqqScV0Y= -github.com/prometheus/common v0.46.0/go.mod h1:Tp0qkxpb9Jsg54QMe+EAmqXkSV7Evdy1BTn+g2pa/hQ= +github.com/prometheus/common v0.47.0 h1:p5Cz0FNHo7SnWOmWmoRozVcjEp0bIVU8cV7OShpjL1k= +github.com/prometheus/common v0.47.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= @@ -623,12 +665,16 @@ github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727/go.mod h1:r github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 h1:M8mH9eK4OUR4lu7Gd+PU1fV2/qnDNfzT635KRSObncs= github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567/go.mod h1:DWNGW8A4Y+GyBgPuaQJuWiy0XYftx4Xm/y5Jqk9I6VQ= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= -github.com/quic-go/qtls-go1-20 v0.4.1 h1:D33340mCNDAIKBqXuAvexTNMUByrYmFYVfKfDN5nfFs= -github.com/quic-go/quic-go v0.40.1 h1:X3AGzUNFs0jVuO3esAGnTfvdgvL4fq655WaOi1snv1Q= +github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= +github.com/quic-go/quic-go v0.41.0 h1:aD8MmHfgqTURWNJy48IYFg2OnxwHT3JL7ahGs73lb4k= +github.com/quic-go/quic-go v0.41.0/go.mod h1:qCkNjqczPEvgsOnxZ0eCD14lv+B2LHlFAB++CNOh9hA= github.com/quic-go/webtransport-go v0.6.0 h1:CvNsKqc4W2HljHJnoT+rMmbRJybShZ0YPFDD3NxaZLY= +github.com/quic-go/webtransport-go v0.6.0/go.mod h1:9KjU4AEBqEQidGHNDkZrb8CAa1abRaosM2yGOyiikEc= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= +github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= +github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= @@ -737,6 +783,7 @@ github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60Nt github.com/uudashr/gocognit v1.0.7 h1:e9aFXgKgUJrQ5+bs61zBigmj7bFJ/5cC6HmMahVzuDo= github.com/uudashr/gocognit v1.0.7/go.mod h1:nAIUuVBnYU7pcninia3BHOvQkpQCeO76Uscky5BOwcY= github.com/warpfork/go-testmark v0.12.1 h1:rMgCpJfwy1sJ50x0M0NgyphxYYPMOODIJHhsXyEHU0s= +github.com/warpfork/go-testmark v0.12.1/go.mod h1:kHwy7wfvGSPh1rQJYKayD4AbtNaeyZdcGi9tNJTaa5Y= github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0 h1:GDDkbFiaK8jsSDJfjId/PEGEShv6ugrt4kYsC5UIDaQ= github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc h1:BCPnHtcboadS0DvysUuJXZ4lWVv5Bh5i7+tbIyi+ck4= @@ -761,6 +808,7 @@ github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5t gitlab.com/bosi/decorder v0.4.0 h1:HWuxAhSxIvsITcXeP+iIRg9d1cVfvVkmlF7M68GaoDY= gitlab.com/bosi/decorder v0.4.0/go.mod h1:xarnteyUoJiOTEldDysquWKTVDCKo2TOIOIibSuWqOg= go-simpler.org/assert v0.5.0 h1:+5L/lajuQtzmbtEfh69sr5cRf2/xZzyJhFjoOz/PPqs= +go-simpler.org/assert v0.5.0/go.mod h1:74Eqh5eI6vCK6Y5l3PI8ZYFXG4Sa+tkr70OIPJAUr28= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= @@ -780,10 +828,14 @@ go.tmz.dev/musttag v0.7.1/go.mod h1:oJLkpR56EsIryktZJk/B0IroSMi37YWver47fibGh5U= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= +go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= go.uber.org/fx v1.20.1 h1:zVwVQGS8zYvhh9Xxcu4w1M6ESyeMzebzj2NbSayZ4Mk= +go.uber.org/fx v1.20.1/go.mod h1:iSYNbHf2y55acNCwCXKx7LbWb5WG1Bnue5RDXz1OREg= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= -go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= +go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= @@ -791,8 +843,8 @@ go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN8 go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= -go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= -go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= +go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= +go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -804,8 +856,8 @@ golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= -golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc= -golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= +golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= +golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -816,8 +868,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20240119083558-1b970713d09a h1:Q8/wZp0KX97QFTc2ywcOE0YRjZPVIx+MXInMzdvQqcA= -golang.org/x/exp v0.0.0-20240119083558-1b970713d09a/go.mod h1:idGWGoKP1toJGkd5/ig9ZLuPcZBC3ewk7SzmH0uou08= +golang.org/x/exp v0.0.0-20240213143201-ec583247a57a h1:HinSgX1tJRX3KsL//Gxynpw5CTOAIPhgL4W8PNiIpVE= +golang.org/x/exp v0.0.0-20240213143201-ec583247a57a/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc= golang.org/x/exp/typeparams v0.0.0-20220428152302-39d4317da171/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/exp/typeparams v0.0.0-20230203172020-98cc5a0785f9/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/exp/typeparams v0.0.0-20230307190834-24139beb5833 h1:jWGQJV4niP+CCmFW9ekjA9Zx8vYORzOUH2/Nl5WPuLQ= @@ -852,8 +904,8 @@ golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91 golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= -golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8= +golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -897,8 +949,8 @@ golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= -golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= +golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -986,16 +1038,16 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= -golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE= -golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= +golang.org/x/term v0.17.0 h1:mkTF7LCd6WGJNL3K1Ad7kwxNfYAW6a8a8QqtMblp/4U= +golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1086,8 +1138,8 @@ golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= golang.org/x/tools v0.5.0/go.mod h1:N+Kgy78s5I24c24dU8OfWNEotWjutIs8SnJvn5IDq+k= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc= -golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps= +golang.org/x/tools v0.18.0 h1:k8NLag8AGHnn+PHbl7g43CtqZAwG60vZkLqgyZgIHgQ= +golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1192,6 +1244,7 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= From dc7a0aba542c9f3e169ce653f3a30e2a07af35b1 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Tue, 27 Feb 2024 09:50:02 +0100 Subject: [PATCH 1037/1212] ci: bump conformance tests Go to 1.21 --- .github/workflows/gateway-conformance.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gateway-conformance.yml b/.github/workflows/gateway-conformance.yml index 57563cfc2..4a94287ec 100644 --- a/.github/workflows/gateway-conformance.yml +++ b/.github/workflows/gateway-conformance.yml @@ -137,7 +137,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: 1.20.x + go-version: 1.21.x - uses: protocol/cache-go-action@v1 with: name: ${{ github.job }} From 121cfaec6014037cefc9d68c02dd528704e18a50 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Tue, 27 Feb 2024 09:57:34 +0100 Subject: [PATCH 1038/1212] ci: upgrade CodeQL to v3 --- .github/workflows/codeql-analysis.yml | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 60bc3c409..69beb5e37 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -31,14 +31,19 @@ jobs: - name: Checkout repository uses: actions/checkout@v4 + - name: Setup Go + uses: actions/setup-go@v5 + with: + go-version: 1.21.x + # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v2 + uses: github/codeql-action/init@v3 with: languages: go - name: Autobuild - uses: github/codeql-action/autobuild@v2 + uses: github/codeql-action/autobuild@v3 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + uses: github/codeql-action/analyze@v3 From a01cc58c8dc4388eaf067e194ef1ee39191f86b5 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Fri, 1 Mar 2024 09:58:10 +0100 Subject: [PATCH 1039/1212] test: cleanup content blocking tests (#10360) --- test/cli/content_blocking_test.go | 80 +++++++++++++++++++++++++++---- 1 file changed, 71 insertions(+), 9 deletions(-) diff --git a/test/cli/content_blocking_test.go b/test/cli/content_blocking_test.go index ddb7c951e..6598354d1 100644 --- a/test/cli/content_blocking_test.go +++ b/test/cli/content_blocking_test.go @@ -12,7 +12,9 @@ import ( "strings" "testing" + "github.com/ipfs/go-cid" "github.com/ipfs/kubo/test/cli/harness" + carstore "github.com/ipld/go-car/v2/blockstore" "github.com/libp2p/go-libp2p" "github.com/libp2p/go-libp2p/core/peer" libp2phttp "github.com/libp2p/go-libp2p/p2p/http" @@ -34,8 +36,10 @@ func TestContentBlocking(t *testing.T) { node := h.NewNode().Init("--empty-repo", "--profile=test") // Create CIDs we use in test - h.WriteFile("blocked-dir/subdir/indirectly-blocked-file.txt", "indirectly blocked file content") - parentDirCID := node.IPFS("add", "--raw-leaves", "-Q", "-r", filepath.Join(h.Dir, "blocked-dir")).Stdout.Trimmed() + h.WriteFile("parent-dir/blocked-subdir/indirectly-blocked-file.txt", "indirectly blocked file content") + allowedParentDirCID := node.IPFS("add", "--raw-leaves", "-Q", "-r", "--pin=false", filepath.Join(h.Dir, "parent-dir")).Stdout.Trimmed() + blockedSubDirCID := node.IPFS("add", "--raw-leaves", "-Q", "-r", "--pin=false", filepath.Join(h.Dir, "parent-dir", "blocked-subdir")).Stdout.Trimmed() + node.IPFS("block", "rm", blockedSubDirCID) h.WriteFile("directly-blocked-file.txt", "directly blocked file content") blockedCID := node.IPFS("add", "--raw-leaves", "-Q", filepath.Join(h.Dir, "directly-blocked-file.txt")).Stdout.Trimmed() @@ -50,7 +54,7 @@ func TestContentBlocking(t *testing.T) { "//8526ba05eec55e28f8db5974cc891d0d92c8af69d386fc6464f1e9f372caf549\n" + // Legacy CID double-hash block: sha256(bafkqahtcnrxwg23fmqqgi33vmjwgk2dbonuca3dfm5qwg6jamnuwicq/) "//e5b7d2ce2594e2e09901596d8e1f29fa249b74c8c9e32ea01eda5111e4d33f07\n" + // Legacy Path double-hash block: sha256(bafyaagyscufaqalqaacauaqiaejao43vmjygc5didacauaqiae/subpath) "/ipfs/" + blockedCID + "\n" + // block specific CID - "/ipfs/" + parentDirCID + "/subdir*\n" + // block only specific subpath + "/ipfs/" + allowedParentDirCID + "/blocked-subdir*\n" + // block only specific subpath "/ipns/blocked-cid.example.com\n" + "/ipns/blocked-dnslink.example.com\n") @@ -94,22 +98,63 @@ func TestContentBlocking(t *testing.T) { // Confirm parent of blocked subpath is not blocked t.Run("Gateway Allows parent Path that is not blocked", func(t *testing.T) { t.Parallel() - resp := client.Get("/ipfs/" + parentDirCID) + resp := client.Get("/ipfs/" + allowedParentDirCID) assert.Equal(t, http.StatusOK, resp.StatusCode) }) + // Confirm CAR responses skip blocked subpaths + t.Run("Gateway returns CAR without blocked subpath", func(t *testing.T) { + resp := client.Get("/ipfs/" + allowedParentDirCID + "/subdir?format=car") + assert.Equal(t, http.StatusOK, resp.StatusCode) + + bs, err := carstore.NewReadOnly(strings.NewReader(resp.Body), nil) + assert.NoError(t, err) + + has, err := bs.Has(context.Background(), cid.MustParse(blockedSubDirCID)) + assert.NoError(t, err) + assert.False(t, has) + }) + + /* TODO: this was already broken in 0.26, but we should fix it + t.Run("Gateway returns CAR without directly blocked CID", func(t *testing.T) { + allowedDirWithDirectlyBlockedCID := node.IPFS("add", "--raw-leaves", "-Q", "-rw", filepath.Join(h.Dir, "directly-blocked-file.txt")).Stdout.Trimmed() + resp := client.Get("/ipfs/" + allowedDirWithDirectlyBlockedCID + "?format=car") + assert.Equal(t, http.StatusOK, resp.StatusCode) + + bs, err := carstore.NewReadOnly(strings.NewReader(resp.Body), nil) + assert.NoError(t, err) + + has, err := bs.Has(context.Background(), cid.MustParse(blockedCID)) + assert.NoError(t, err) + assert.False(t, has, "Returned CAR should not include blockedCID") + }) + */ + + // Confirm CAR responses skip blocked subpaths + t.Run("Gateway returns CAR without blocked subpath", func(t *testing.T) { + resp := client.Get("/ipfs/" + allowedParentDirCID + "/subdir?format=car") + assert.Equal(t, http.StatusOK, resp.StatusCode) + + bs, err := carstore.NewReadOnly(strings.NewReader(resp.Body), nil) + assert.NoError(t, err) + + has, err := bs.Has(context.Background(), cid.MustParse(blockedSubDirCID)) + assert.NoError(t, err) + assert.False(t, has, "Returned CAR should not include blockedSubDirCID") + }) + // Ok, now the full list of test cases we want to cover in both CLI and Gateway testCases := []struct { name string path string }{ { - name: "directly blocked CID", + name: "directly blocked file CID", path: "/ipfs/" + blockedCID, }, { name: "indirectly blocked file (on a blocked subpath)", - path: "/ipfs/" + parentDirCID + "/subdir/indirectly-blocked-file.txt", + path: "/ipfs/" + allowedParentDirCID + "/blocked-subdir/indirectly-blocked-file.txt", }, { name: "/ipns path that resolves to a blocked CID", @@ -161,9 +206,14 @@ func TestContentBlocking(t *testing.T) { t.Run(cliTestName, func(t *testing.T) { t.Parallel() args := append(cmd, testCase.path) - errMsg := node.RunIPFS(args...).Stderr.Trimmed() - if !strings.Contains(errMsg, expectedMsg) { - t.Errorf("Expected STDERR error message %q, but got: %q", expectedMsg, errMsg) + cmd := node.RunIPFS(args...) + stdout := cmd.Stdout.Trimmed() + stderr := cmd.Stderr.Trimmed() + if !strings.Contains(stderr, expectedMsg) { + t.Errorf("Expected STDERR error message %q, but got: %q", expectedMsg, stderr) + if stdout != "" { + t.Errorf("Expected STDOUT to be empty, but got: %q", stdout) + } } }) } @@ -299,5 +349,17 @@ func TestContentBlocking(t *testing.T) { assert.NotEqual(t, string(body), "directly blocked file content") assert.Contains(t, string(body), blockedMsg, bodyExpl) }) + + t.Run("Denies Blocked CID as CAR", func(t *testing.T) { + t.Parallel() + resp, err := libp2pClient.Get(fmt.Sprintf("/ipfs/%s?format=car", blockedCID)) + require.NoError(t, err) + defer resp.Body.Close() + assert.Equal(t, http.StatusGone, resp.StatusCode, statusExpl) + body, err := io.ReadAll(resp.Body) + require.NoError(t, err) + assert.NotContains(t, string(body), "directly blocked file content") + assert.Contains(t, string(body), blockedMsg, bodyExpl) + }) }) } From e803e86f96523de823736bf2887ca54ac3e91dbf Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Tue, 20 Feb 2024 11:50:37 +0100 Subject: [PATCH 1040/1212] docs: improve release issue template (cherry picked from commit 9ea10752f251171f0aed4822d6cfd4c1674018c4) --- docs/RELEASE_ISSUE_TEMPLATE.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/RELEASE_ISSUE_TEMPLATE.md b/docs/RELEASE_ISSUE_TEMPLATE.md index 52f02fb50..cfa975943 100644 --- a/docs/RELEASE_ISSUE_TEMPLATE.md +++ b/docs/RELEASE_ISSUE_TEMPLATE.md @@ -1,4 +1,4 @@ - + # Items to do upon creating the release issue @@ -22,6 +22,7 @@ * Expected RC date: week of YYYY-MM-DD * 🚢 Expected final release date: YYYY-MM-DD * Release PR: +* Thunderdome PR: * Accompanying PR for improving the release process: ([example](https://github.com/ipfs/kubo/pull/9391)) * Changelog: https://github.com/ipfs/kubo/blob/master/docs/changelogs/vX.Y.md From 30fe155b62506ad5d96187639d0435074b6b6442 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Tue, 27 Feb 2024 09:45:57 +0100 Subject: [PATCH 1041/1212] chore: bump to go-libp2p 0.33 (cherry picked from commit cd6d5c0828bc332fc2d286a01ca5d5458a71c000) --- docs/examples/kubo-as-a-library/go.mod | 65 ++++----- docs/examples/kubo-as-a-library/go.sum | 190 +++++++++++++++---------- go.mod | 67 ++++----- go.sum | 186 ++++++++++++++---------- test/dependencies/go.mod | 28 ++-- test/dependencies/go.sum | 119 +++++++++++----- 6 files changed, 394 insertions(+), 261 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 07c7afcd7..263925581 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -1,6 +1,8 @@ module github.com/ipfs/kubo/examples/kubo-as-a-library -go 1.20 +go 1.21 + +toolchain go1.21.7 // Used to keep this in sync with the current version of kubo. You should remove // this if you copy this example. @@ -9,7 +11,7 @@ replace github.com/ipfs/kubo => ./../../.. require ( github.com/ipfs/boxo v0.18.0 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 - github.com/libp2p/go-libp2p v0.32.2 + github.com/libp2p/go-libp2p v0.33.0 github.com/multiformats/go-multiaddr v0.12.2 ) @@ -39,7 +41,7 @@ require ( github.com/dustin/go-humanize v1.0.1 // indirect github.com/elastic/gosigar v0.14.2 // indirect github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5 // indirect - github.com/flynn/noise v1.0.1 // indirect + github.com/flynn/noise v1.1.0 // indirect github.com/francoispqt/gojay v1.2.13 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/gabriel-vasile/mimetype v1.4.3 // indirect @@ -51,9 +53,9 @@ require ( github.com/golang/protobuf v1.5.3 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/gopacket v1.1.19 // indirect - github.com/google/pprof v0.0.0-20231229205709-960ae82b1e42 // indirect + github.com/google/pprof v0.0.0-20240207164012-fb44976bdcd5 // indirect github.com/google/uuid v1.5.0 // indirect - github.com/gorilla/websocket v1.5.0 // indirect + github.com/gorilla/websocket v1.5.1 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect @@ -93,8 +95,8 @@ require ( github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect github.com/jbenet/goprocess v0.1.4 // indirect - github.com/klauspost/compress v1.17.4 // indirect - github.com/klauspost/cpuid/v2 v2.2.6 // indirect + github.com/klauspost/compress v1.17.6 // indirect + github.com/klauspost/cpuid/v2 v2.2.7 // indirect github.com/koron/go-ssdp v0.0.4 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/libp2p/go-cidranger v1.1.0 // indirect @@ -131,38 +133,37 @@ require ( github.com/multiformats/go-multihash v0.2.3 // indirect github.com/multiformats/go-multistream v0.5.0 // indirect github.com/multiformats/go-varint v0.0.7 // indirect - github.com/onsi/ginkgo/v2 v2.13.2 // indirect - github.com/opencontainers/runtime-spec v1.1.0 // indirect + github.com/onsi/ginkgo/v2 v2.15.0 // indirect + github.com/opencontainers/runtime-spec v1.2.0 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/openzipkin/zipkin-go v0.4.2 // indirect github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 // indirect github.com/pion/datachannel v1.5.5 // indirect - github.com/pion/dtls/v2 v2.2.7 // indirect - github.com/pion/ice/v2 v2.3.6 // indirect - github.com/pion/interceptor v0.1.17 // indirect + github.com/pion/dtls/v2 v2.2.8 // indirect + github.com/pion/ice/v2 v2.3.11 // indirect + github.com/pion/interceptor v0.1.25 // indirect github.com/pion/logging v0.2.2 // indirect - github.com/pion/mdns v0.0.7 // indirect + github.com/pion/mdns v0.0.9 // indirect github.com/pion/randutil v0.1.0 // indirect - github.com/pion/rtcp v1.2.10 // indirect - github.com/pion/rtp v1.7.13 // indirect - github.com/pion/sctp v1.8.7 // indirect + github.com/pion/rtcp v1.2.13 // indirect + github.com/pion/rtp v1.8.3 // indirect + github.com/pion/sctp v1.8.9 // indirect github.com/pion/sdp/v3 v3.0.6 // indirect - github.com/pion/srtp/v2 v2.0.15 // indirect - github.com/pion/stun v0.6.0 // indirect - github.com/pion/transport/v2 v2.2.1 // indirect - github.com/pion/turn/v2 v2.1.0 // indirect - github.com/pion/webrtc/v3 v3.2.9 // indirect + github.com/pion/srtp/v2 v2.0.18 // indirect + github.com/pion/stun v0.6.1 // indirect + github.com/pion/transport/v2 v2.2.4 // indirect + github.com/pion/turn/v2 v2.1.4 // indirect + github.com/pion/webrtc/v3 v3.2.23 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/polydawn/refmt v0.89.0 // indirect github.com/prometheus/client_golang v1.18.0 // indirect - github.com/prometheus/client_model v0.5.0 // indirect - github.com/prometheus/common v0.46.0 // indirect + github.com/prometheus/client_model v0.6.0 // indirect + github.com/prometheus/common v0.47.0 // indirect github.com/prometheus/procfs v0.12.0 // indirect github.com/quic-go/qpack v0.4.0 // indirect - github.com/quic-go/qtls-go1-20 v0.4.1 // indirect - github.com/quic-go/quic-go v0.40.1 // indirect + github.com/quic-go/quic-go v0.41.0 // indirect github.com/quic-go/webtransport-go v0.6.0 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/samber/lo v1.39.0 // indirect @@ -191,16 +192,16 @@ require ( go.uber.org/fx v1.20.1 // indirect go.uber.org/mock v0.4.0 // indirect go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap v1.26.0 // indirect + go.uber.org/zap v1.27.0 // indirect go4.org v0.0.0-20230225012048-214862532bf5 // indirect - golang.org/x/crypto v0.18.0 // indirect - golang.org/x/exp v0.0.0-20240119083558-1b970713d09a // indirect - golang.org/x/mod v0.14.0 // indirect - golang.org/x/net v0.20.0 // indirect + golang.org/x/crypto v0.19.0 // indirect + golang.org/x/exp v0.0.0-20240213143201-ec583247a57a // indirect + golang.org/x/mod v0.15.0 // indirect + golang.org/x/net v0.21.0 // indirect golang.org/x/sync v0.6.0 // indirect - golang.org/x/sys v0.16.0 // indirect + golang.org/x/sys v0.17.0 // indirect golang.org/x/text v0.14.0 // indirect - golang.org/x/tools v0.17.0 // indirect + golang.org/x/tools v0.18.0 // indirect golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect gonum.org/v1/gonum v0.14.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240108191215-35c7eff3a6b1 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index c9d1b3fb1..7238b76c1 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -101,6 +101,7 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c h1:pFUpOrbxDR6AkioZ1ySsx5yxlDQZ8stG2b88gTPxgJU= github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c/go.mod h1:6UhI8N9EjYm1c2odKpFpAYeR8dsBeM7PtzQhRgxRr9U= github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y= +github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= @@ -126,13 +127,14 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7 github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5 h1:BBso6MBKW8ncyZLv37o+KNyy0HrrHgfnOaGQC2qvN+A= github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5/go.mod h1:JpoxHjuQauoxiFMl1ie8Xc/7TfLuMZ5eOCONd1sUBHg= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= -github.com/flynn/noise v1.0.1 h1:vPp/jdQLXC6ppsXSj/pM3W1BIJ5FEHE2TulSJBpb43Y= -github.com/flynn/noise v1.0.1/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag= +github.com/flynn/noise v1.1.0 h1:KjPQoQCEFdZDiP03phOvGi11+SVVhBG2wOWAorLsstg= +github.com/flynn/noise v1.1.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag= github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk= github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/frankban/quicktest v1.14.0/go.mod h1:NeW+ay9A/U67EYXNFA1nPE8e/tnQv/09mUdL/ijj8og= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= +github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= @@ -169,6 +171,7 @@ github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4er github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= @@ -206,6 +209,7 @@ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= @@ -214,12 +218,12 @@ github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXi github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20231229205709-960ae82b1e42 h1:dHLYa5D8/Ta0aLR2XcPsrkpAgGeFs6thhMcQK0oQ0n8= -github.com/google/pprof v0.0.0-20231229205709-960ae82b1e42/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= +github.com/google/pprof v0.0.0-20240207164012-fb44976bdcd5 h1:E/LAvt58di64hlYjx7AsNS6C/ysHWYo+2qPCZKTQhRo= +github.com/google/pprof v0.0.0-20240207164012-fb44976bdcd5/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU= github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= @@ -228,9 +232,11 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c h1:7lF+Vz0LqiRidnzC1Oq86fpX1q/iEv2KJdrCtttYjT4= +github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= -github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= -github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= +github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= +github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0 h1:Wqo399gCIufwto+VfwCSvsnfGpF/w5E9CNxSwbpD6No= @@ -268,6 +274,7 @@ github.com/ipfs/go-block-format v0.0.3/go.mod h1:4LmD4ZUw0mhO+JSKdpWwrzATiEfM7WW github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs= github.com/ipfs/go-block-format v0.2.0/go.mod h1:+jpL11nFx5A/SPpsoBn6Bzkra/zaArfSmsknbPMYgzM= github.com/ipfs/go-blockservice v0.5.0 h1:B2mwhhhVQl2ntW2EIpaWPwSCxSuqr5fFA93Ms4bYLEY= +github.com/ipfs/go-blockservice v0.5.0/go.mod h1:W6brZ5k20AehbmERplmERn8o2Ni3ZZubvAxaIUeaT6w= github.com/ipfs/go-cid v0.0.3/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.4/go.mod h1:4LLaPOQwmk5z9LBgQnpkivrx8BJjUyGwTXCd5Xfj6+M= github.com/ipfs/go-cid v0.0.5/go.mod h1:plgt+Y5MnOey4vO4UlUazGqdbEXuFYitED67FexhXog= @@ -297,15 +304,20 @@ github.com/ipfs/go-ds-measure v0.2.0/go.mod h1:SEUD/rE2PwRa4IQEC5FuNAmjJCyYObZr9 github.com/ipfs/go-fs-lock v0.0.7 h1:6BR3dajORFrFTkb5EpCUFIAypsoxpGpDSVUdFwzgL9U= github.com/ipfs/go-fs-lock v0.0.7/go.mod h1:Js8ka+FNYmgQRLrRXzU3CB/+Csr1BwrRilEcvYrHhhc= github.com/ipfs/go-ipfs-blockstore v1.3.0 h1:m2EXaWgwTzAfsmt5UdJ7Is6l4gJcaM/A12XwJyvYvMM= +github.com/ipfs/go-ipfs-blockstore v1.3.0/go.mod h1:KgtZyc9fq+P2xJUiCAzbRdhhqJHvsw8u2Dlqy2MyRTE= github.com/ipfs/go-ipfs-blocksutil v0.0.1 h1:Eh/H4pc1hsvhzsQoMEP3Bke/aW5P5rVM1IWFJMcGIPQ= +github.com/ipfs/go-ipfs-blocksutil v0.0.1/go.mod h1:Yq4M86uIOmxmGPUHv/uI7uKqZNtLb449gwKqXjIsnRk= github.com/ipfs/go-ipfs-chunker v0.0.5 h1:ojCf7HV/m+uS2vhUGWcogIIxiO5ubl5O57Q7NapWLY8= +github.com/ipfs/go-ipfs-chunker v0.0.5/go.mod h1:jhgdF8vxRHycr00k13FM8Y0E+6BoalYeobXmUyTreP8= github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= github.com/ipfs/go-ipfs-delay v0.0.1 h1:r/UXYyRcddO6thwOnhiznIAiSvxMECGgtv35Xs1IeRQ= github.com/ipfs/go-ipfs-delay v0.0.1/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= github.com/ipfs/go-ipfs-ds-help v1.1.0 h1:yLE2w9RAsl31LtfMt91tRZcrx+e61O5mDxFRR994w4Q= github.com/ipfs/go-ipfs-ds-help v1.1.0/go.mod h1:YR5+6EaebOhfcqVCyqemItCLthrpVNot+rsOU/5IatU= github.com/ipfs/go-ipfs-exchange-interface v0.2.0 h1:8lMSJmKogZYNo2jjhUs0izT+dck05pqUw4mWNW9Pw6Y= +github.com/ipfs/go-ipfs-exchange-interface v0.2.0/go.mod h1:z6+RhJuDQbqKguVyslSOuVDhqF9JtTrO3eptSAiW2/Y= github.com/ipfs/go-ipfs-exchange-offline v0.3.0 h1:c/Dg8GDPzixGd0MC8Jh6mjOwU57uYokgWRFidfvEkuA= +github.com/ipfs/go-ipfs-exchange-offline v0.3.0/go.mod h1:MOdJ9DChbb5u37M1IcbrRB02e++Z7521fMxqCNRrz9s= github.com/ipfs/go-ipfs-pq v0.0.3 h1:YpoHVJB+jzK15mr/xsWC574tyDLkezVrDNeaalQBsTE= github.com/ipfs/go-ipfs-pq v0.0.3/go.mod h1:btNw5hsHBpRcSSgZtiNm/SLj5gYIZ18AKtv3kERkRb4= github.com/ipfs/go-ipfs-redirects-file v0.1.1 h1:Io++k0Vf/wK+tfnhEh63Yte1oQK5VGT2hIEYpD0Rzx8= @@ -333,14 +345,17 @@ github.com/ipfs/go-log/v2 v2.3.0/go.mod h1:QqGoj30OTpnKaG/LKTGTxoP2mmQtjVMEnK72g github.com/ipfs/go-log/v2 v2.5.1 h1:1XdUzF7048prq4aBjDQQ4SL5RxftpRGdXhNRwKSAlcY= github.com/ipfs/go-log/v2 v2.5.1/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOLU9U5UI= github.com/ipfs/go-merkledag v0.11.0 h1:DgzwK5hprESOzS4O1t/wi6JDpyVQdvm9Bs59N/jqfBY= +github.com/ipfs/go-merkledag v0.11.0/go.mod h1:Q4f/1ezvBiJV0YCIXvt51W/9/kqJGH4I1LsA7+djsM4= github.com/ipfs/go-metrics-interface v0.0.1 h1:j+cpbjYvu4R8zbleSs36gvB7jR+wsL2fGD6n0jO4kdg= github.com/ipfs/go-metrics-interface v0.0.1/go.mod h1:6s6euYU4zowdslK0GKHmqaIZ3j/b/tL7HTWtJ4VPgWY= github.com/ipfs/go-peertaskqueue v0.8.1 h1:YhxAs1+wxb5jk7RvS0LHdyiILpNmRIRnZVztekOF0pg= github.com/ipfs/go-peertaskqueue v0.8.1/go.mod h1:Oxxd3eaK279FxeydSPPVGHzbwVeHjatZ2GA8XD+KbPU= github.com/ipfs/go-unixfs v0.4.5 h1:wj8JhxvV1G6CD7swACwSKYa+NgtdWC1RUit+gFnymDU= +github.com/ipfs/go-unixfs v0.4.5/go.mod h1:BIznJNvt/gEx/ooRMI4Us9K8+qeGO7vx1ohnbk8gjFg= github.com/ipfs/go-unixfsnode v1.9.0 h1:ubEhQhr22sPAKO2DNsyVBW7YB/zA8Zkif25aBvz8rc8= github.com/ipfs/go-unixfsnode v1.9.0/go.mod h1:HxRu9HYHOjK6HUqFBAi++7DVoWAHn0o4v/nZ/VA+0g8= github.com/ipfs/go-verifcid v0.0.2 h1:XPnUv0XmdH+ZIhLGKg6U2vaPaRDXb9urMyNVCE7uvTs= +github.com/ipfs/go-verifcid v0.0.2/go.mod h1:40cD9x1y4OWnFXbLNJYRe7MpNvWlMn3LZAG5Wb4xnPU= github.com/ipld/go-car/v2 v2.13.1 h1:KnlrKvEPEzr5IZHKTXLAEub+tPrzeAFQVRlSQvuxBO4= github.com/ipld/go-car/v2 v2.13.1/go.mod h1:QkdjjFNGit2GIkpQ953KBwowuoukoM75nP/JI1iDJdo= github.com/ipld/go-codec-dagpb v1.6.0 h1:9nYazfyu9B1p3NAgfVdpRco3Fs2nFC72DqVsMj6rOcc= @@ -350,6 +365,7 @@ github.com/ipld/go-ipld-prime v0.14.1/go.mod h1:QcE4Y9n/ZZr8Ijg5bGPT0GqYWgZ1704n github.com/ipld/go-ipld-prime v0.21.0 h1:n4JmcpOlPDIxBcY037SVfpd1G+Sj1nKZah0m6QH9C2E= github.com/ipld/go-ipld-prime v0.21.0/go.mod h1:3RLqy//ERg/y5oShXXdx5YIp50cFGOanyMctpPjsvxQ= github.com/ipld/go-ipld-prime/storage/bsadapter v0.0.0-20230102063945-1a409dc236dd h1:gMlw/MhNr2Wtp5RwGdsW23cs+yCuj9k2ON7i9MiJlRo= +github.com/ipld/go-ipld-prime/storage/bsadapter v0.0.0-20230102063945-1a409dc236dd/go.mod h1:wZ8hH8UxeryOs4kJEJaiui/s00hDSbE37OKsL47g+Sw= github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/jbenet/go-cienv v0.1.0 h1:Vc/s0QbQtoxX8MwwSLWWh+xNNZvM3Lw7NsTcHrvvhMc= @@ -375,12 +391,12 @@ github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQL 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.17.4 h1:Ej5ixsIri7BrIjBkRZLTo6ghwrEtHFk7ijlczPW4fZ4= -github.com/klauspost/compress v1.17.4/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= +github.com/klauspost/compress v1.17.6 h1:60eq2E/jlfwQXtvZEeBUYADs+BwKBWURIY+Gj2eRGjI= +github.com/klauspost/compress v1.17.6/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/48xc= -github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= +github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/koron/go-ssdp v0.0.4 h1:1IDwrghSKYM7yLf7XCzbByg2sJ/JcNOZRXS2jczTwz0= github.com/koron/go-ssdp v0.0.4/go.mod h1:oDXq+E5IL5q0U8uSBcoAXzTzInwy5lEgC91HoKtbmZk= @@ -389,6 +405,7 @@ github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfn github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= @@ -406,8 +423,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.32.2 h1:s8GYN4YJzgUoyeYNPdW7JZeZ5Ee31iNaIBfGYMAY4FQ= -github.com/libp2p/go-libp2p v0.32.2/go.mod h1:E0LKe+diV/ZVJVnOJby8VC5xzHF0660osg71skcxJvk= +github.com/libp2p/go-libp2p v0.33.0 h1:yTPSr8sJRbfeEYXyeN8VPVSlTlFjtMUwGDRniwaf/xQ= +github.com/libp2p/go-libp2p v0.33.0/go.mod h1:RIJFRQVUBKy82dnW7J5f1homqqv6NcsDJAl3e7CRGfE= github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94= github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= @@ -427,6 +444,7 @@ github.com/libp2p/go-libp2p-record v0.2.0/go.mod h1:I+3zMkvvg5m2OcSdoL0KPljyJyvN github.com/libp2p/go-libp2p-routing-helpers v0.7.3 h1:u1LGzAMVRK9Nqq5aYDVOiq/HaB93U9WWczBzGyAC5ZY= github.com/libp2p/go-libp2p-routing-helpers v0.7.3/go.mod h1:cN4mJAD/7zfPKXBcs9ze31JGYAZgzdABEm+q/hkswb8= github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA= +github.com/libp2p/go-libp2p-testing v0.12.0/go.mod h1:KcGDRXyN7sQCllucn1cOOS+Dmm7ujhfEyXQL5lvkcPg= github.com/libp2p/go-libp2p-xor v0.1.0 h1:hhQwT4uGrBcuAkUGXADuPltalOdpf9aag9kaYNT2tLA= github.com/libp2p/go-libp2p-xor v0.1.0/go.mod h1:LSTM5yRnjGZbWNTA/hRwq2gGFrvRIbQJscoIL/u6InY= github.com/libp2p/go-msgio v0.0.4/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= @@ -540,16 +558,17 @@ github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9k github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.13.2 h1:Bi2gGVkfn6gQcjNjZJVO8Gf0FHzMPf2phUei9tejVMs= -github.com/onsi/ginkgo/v2 v2.13.2/go.mod h1:XStQ8QcGwLyF4HdfcZB8SFOS/MWCgDuXMSBe6zrvLgM= +github.com/onsi/ginkgo/v2 v2.15.0 h1:79HwNRBAZHOEwrczrgSOPy+eFTTlIGELKy5as+ClttY= +github.com/onsi/ginkgo/v2 v2.15.0/go.mod h1:HlxMHtYF57y6Dpf+mc5529KKmSq9h2FpCF+/ZkwUxKM= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= -github.com/onsi/gomega v1.29.0 h1:KIA/t2t5UBzoirT4H9tsML45GEbo3ouUnBHsCfD2tVg= +github.com/onsi/gomega v1.30.0 h1:hvMK7xYz4D3HapigLTeGdId/NcfQx1VHMJc60ew99+8= +github.com/onsi/gomega v1.30.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opencontainers/runtime-spec v1.1.0 h1:HHUyrt9mwHUjtasSbXSMvs4cyFxh+Bll4AjJ9odEGpg= -github.com/opencontainers/runtime-spec v1.1.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/runtime-spec v1.2.0 h1:z97+pHb3uELt/yiAWD691HNHQIF07bE7dzrbT927iTk= +github.com/opencontainers/runtime-spec v1.2.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= @@ -564,43 +583,51 @@ github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 h1:1/WtZae0yGtPq+TI6+ github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9/go.mod h1:x3N5drFsm2uilKKuuYo6LdyD8vZAW55sH/9w+pbo1sw= github.com/pion/datachannel v1.5.5 h1:10ef4kwdjije+M9d7Xm9im2Y3O6A6ccQb0zcqZcJew8= github.com/pion/datachannel v1.5.5/go.mod h1:iMz+lECmfdCMqFRhXhcA/219B0SQlbpoR2V118yimL0= -github.com/pion/dtls/v2 v2.2.7 h1:cSUBsETxepsCSFSxC3mc/aDo14qQLMSL+O6IjG28yV8= github.com/pion/dtls/v2 v2.2.7/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s= -github.com/pion/ice/v2 v2.3.6 h1:Jgqw36cAud47iD+N6rNX225uHvrgWtAlHfVyOQc3Heg= -github.com/pion/ice/v2 v2.3.6/go.mod h1:9/TzKDRwBVAPsC+YOrKH/e3xDrubeTRACU9/sHQarsU= -github.com/pion/interceptor v0.1.17 h1:prJtgwFh/gB8zMqGZoOgJPHivOwVAp61i2aG61Du/1w= -github.com/pion/interceptor v0.1.17/go.mod h1:SY8kpmfVBvrbUzvj2bsXz7OJt5JvmVNZ+4Kjq7FcwrI= +github.com/pion/dtls/v2 v2.2.8 h1:BUroldfiIbV9jSnC6cKOMnyiORRWrWWpV11JUyEu5OA= +github.com/pion/dtls/v2 v2.2.8/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s= +github.com/pion/ice/v2 v2.3.11 h1:rZjVmUwyT55cmN8ySMpL7rsS8KYsJERsrxJLLxpKhdw= +github.com/pion/ice/v2 v2.3.11/go.mod h1:hPcLC3kxMa+JGRzMHqQzjoSj3xtE9F+eoncmXLlCL4E= +github.com/pion/interceptor v0.1.25 h1:pwY9r7P6ToQ3+IF0bajN0xmk/fNw/suTgaTdlwTDmhc= +github.com/pion/interceptor v0.1.25/go.mod h1:wkbPYAak5zKsfpVDYMtEfWEy8D4zL+rpxCxPImLOg3Y= github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY= github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms= -github.com/pion/mdns v0.0.7 h1:P0UB4Sr6xDWEox0kTVxF0LmQihtCbSAdW0H2nEgkA3U= -github.com/pion/mdns v0.0.7/go.mod h1:4iP2UbeFhLI/vWju/bw6ZfwjJzk0z8DNValjGxR/dD8= +github.com/pion/mdns v0.0.8/go.mod h1:hYE72WX8WDveIhg7fmXgMKivD3Puklk0Ymzog0lSyaI= +github.com/pion/mdns v0.0.9 h1:7Ue5KZsqq8EuqStnpPWV33vYYEH0+skdDN5L7EiEsI4= +github.com/pion/mdns v0.0.9/go.mod h1:2JA5exfxwzXiCihmxpTKgFUpiQws2MnipoPK09vecIc= github.com/pion/randutil v0.1.0 h1:CFG1UdESneORglEsnimhUjf33Rwjubwj6xfiOXBa3mA= github.com/pion/randutil v0.1.0/go.mod h1:XcJrSMMbbMRhASFVOlj/5hQial/Y8oH/HVo7TBZq+j8= -github.com/pion/rtcp v1.2.10 h1:nkr3uj+8Sp97zyItdN60tE/S6vk4al5CPRR6Gejsdjc= github.com/pion/rtcp v1.2.10/go.mod h1:ztfEwXZNLGyF1oQDttz/ZKIBaeeg/oWbRYqzBM9TL1I= -github.com/pion/rtp v1.7.13 h1:qcHwlmtiI50t1XivvoawdCGTP4Uiypzfrsap+bijcoA= -github.com/pion/rtp v1.7.13/go.mod h1:bDb5n+BFZxXx0Ea7E5qe+klMuqiBrP+w8XSjiWtCUko= +github.com/pion/rtcp v1.2.12/go.mod h1:sn6qjxvnwyAkkPzPULIbVqSKI5Dv54Rv7VG0kNxh9L4= +github.com/pion/rtcp v1.2.13 h1:+EQijuisKwm/8VBs8nWllr0bIndR7Lf7cZG200mpbNo= +github.com/pion/rtcp v1.2.13/go.mod h1:sn6qjxvnwyAkkPzPULIbVqSKI5Dv54Rv7VG0kNxh9L4= +github.com/pion/rtp v1.8.2/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU= +github.com/pion/rtp v1.8.3 h1:VEHxqzSVQxCkKDSHro5/4IUUG1ea+MFdqR2R3xSpNU8= +github.com/pion/rtp v1.8.3/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU= github.com/pion/sctp v1.8.5/go.mod h1:SUFFfDpViyKejTAdwD1d/HQsCu+V/40cCs2nZIvC3s0= -github.com/pion/sctp v1.8.7 h1:JnABvFakZueGAn4KU/4PSKg+GWbF6QWbKTWZOSGJjXw= -github.com/pion/sctp v1.8.7/go.mod h1:g1Ul+ARqZq5JEmoFy87Q/4CePtKnTJ1QCL9dBBdN6AU= +github.com/pion/sctp v1.8.8/go.mod h1:igF9nZBrjh5AtmKc7U30jXltsFHicFCXSmWA2GWRaWs= +github.com/pion/sctp v1.8.9 h1:TP5ZVxV5J7rz7uZmbyvnUvsn7EJ2x/5q9uhsTtXbI3g= +github.com/pion/sctp v1.8.9/go.mod h1:cMLT45jqw3+jiJCrtHVwfQLnfR0MGZ4rgOJwUOIqLkI= github.com/pion/sdp/v3 v3.0.6 h1:WuDLhtuFUUVpTfus9ILC4HRyHsW6TdugjEX/QY9OiUw= github.com/pion/sdp/v3 v3.0.6/go.mod h1:iiFWFpQO8Fy3S5ldclBkpXqmWy02ns78NOKoLLL0YQw= -github.com/pion/srtp/v2 v2.0.15 h1:+tqRtXGsGwHC0G0IUIAzRmdkHvriF79IHVfZGfHrQoA= -github.com/pion/srtp/v2 v2.0.15/go.mod h1:b/pQOlDrbB0HEH5EUAQXzSYxikFbNcNuKmF8tM0hCtw= -github.com/pion/stun v0.4.0/go.mod h1:QPsh1/SbXASntw3zkkrIk3ZJVKz4saBY2G7S10P3wCw= -github.com/pion/stun v0.6.0 h1:JHT/2iyGDPrFWE8NNC15wnddBN8KifsEDw8swQmrEmU= -github.com/pion/stun v0.6.0/go.mod h1:HPqcfoeqQn9cuaet7AOmB5e5xkObu9DwBdurwLKO9oA= +github.com/pion/srtp/v2 v2.0.18 h1:vKpAXfawO9RtTRKZJbG4y0v1b11NZxQnxRl85kGuUlo= +github.com/pion/srtp/v2 v2.0.18/go.mod h1:0KJQjA99A6/a0DOVTu1PhDSw0CXF2jTkqOoMg3ODqdA= +github.com/pion/stun v0.6.1 h1:8lp6YejULeHBF8NmV8e2787BogQhduZugh5PdhDyyN4= +github.com/pion/stun v0.6.1/go.mod h1:/hO7APkX4hZKu/D0f2lHzNyvdkTGtIy3NDmLR7kSz/8= github.com/pion/transport v0.14.1 h1:XSM6olwW+o8J4SCmOBb/BpwZypkHeyM0PGFCxNQBr40= github.com/pion/transport v0.14.1/go.mod h1:4tGmbk00NeYA3rUa9+n+dzCCoKkcy3YlYb99Jn2fNnI= -github.com/pion/transport/v2 v2.0.0/go.mod h1:HS2MEBJTwD+1ZI2eSXSvHJx/HnzQqRy2/LXxt6eVMHc= -github.com/pion/transport/v2 v2.1.0/go.mod h1:AdSw4YBZVDkZm8fpoz+fclXyQwANWmZAlDuQdctTThQ= -github.com/pion/transport/v2 v2.2.0/go.mod h1:AdSw4YBZVDkZm8fpoz+fclXyQwANWmZAlDuQdctTThQ= -github.com/pion/transport/v2 v2.2.1 h1:7qYnCBlpgSJNYMbLCKuSY9KbQdBFoETvPNETv0y4N7c= github.com/pion/transport/v2 v2.2.1/go.mod h1:cXXWavvCnFF6McHTft3DWS9iic2Mftcz1Aq29pGcU5g= -github.com/pion/turn/v2 v2.1.0 h1:5wGHSgGhJhP/RpabkUb/T9PdsAjkGLS6toYz5HNzoSI= -github.com/pion/turn/v2 v2.1.0/go.mod h1:yrT5XbXSGX1VFSF31A3c1kCNB5bBZgk/uu5LET162qs= -github.com/pion/webrtc/v3 v3.2.9 h1:U8NSjQDlZZ+Iy/hg42Q/u6mhEVSXYvKrOIZiZwYTfLc= -github.com/pion/webrtc/v3 v3.2.9/go.mod h1:gjQLMZeyN3jXBGdxGmUYCyKjOuYX/c99BDjGqmadq0A= +github.com/pion/transport/v2 v2.2.2/go.mod h1:OJg3ojoBJopjEeECq2yJdXH9YVrUJ1uQ++NjXLOUorc= +github.com/pion/transport/v2 v2.2.3/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0= +github.com/pion/transport/v2 v2.2.4 h1:41JJK6DZQYSeVLxILA2+F4ZkKb4Xd/tFJZRFZQ9QAlo= +github.com/pion/transport/v2 v2.2.4/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0= +github.com/pion/transport/v3 v3.0.1 h1:gDTlPJwROfSfz6QfSi0ZmeCSkFcnWWiiR9ES0ouANiM= +github.com/pion/transport/v3 v3.0.1/go.mod h1:UY7kiITrlMv7/IKgd5eTUcaahZx5oUN3l9SzK5f5xE0= +github.com/pion/turn/v2 v2.1.3/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY= +github.com/pion/turn/v2 v2.1.4 h1:2xn8rduI5W6sCZQkEnIUDAkrBQNl2eYIBCHMZ3QMmP8= +github.com/pion/turn/v2 v2.1.4/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY= +github.com/pion/webrtc/v3 v3.2.23 h1:GbqEuxBbVLFhXk0GwxKAoaIJYiEa9TyoZPEZC+2HZxM= +github.com/pion/webrtc/v3 v3.2.23/go.mod h1:1CaT2fcZzZ6VZA+O1i9yK2DU4EOcXVvSbWG9pr5jefs= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -614,20 +641,18 @@ github.com/prometheus/client_golang v1.18.0 h1:HzFfmkOzH5Q8L8G+kSJKUx5dtG87sewO+ github.com/prometheus/client_golang v1.18.0/go.mod h1:T+GXkCk5wSJyOqMIzVgvvjFDlkOQntgjkJWKrN5txjA= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= -github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= +github.com/prometheus/client_model v0.6.0 h1:k1v3CzpSRUTrKMppY35TLwPvxHqBu0bYgxZzqGIgaos= +github.com/prometheus/client_model v0.6.0/go.mod h1:NTQHnmxFpouOD0DpvP4XujX3CdOAGQPoaGhyTchlyt8= github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.46.0 h1:doXzt5ybi1HBKpsZOL0sSkaNHJJqkyfEWZGGqqScV0Y= -github.com/prometheus/common v0.46.0/go.mod h1:Tp0qkxpb9Jsg54QMe+EAmqXkSV7Evdy1BTn+g2pa/hQ= +github.com/prometheus/common v0.47.0 h1:p5Cz0FNHo7SnWOmWmoRozVcjEp0bIVU8cV7OShpjL1k= +github.com/prometheus/common v0.47.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= -github.com/quic-go/qtls-go1-20 v0.4.1 h1:D33340mCNDAIKBqXuAvexTNMUByrYmFYVfKfDN5nfFs= -github.com/quic-go/qtls-go1-20 v0.4.1/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= -github.com/quic-go/quic-go v0.40.1 h1:X3AGzUNFs0jVuO3esAGnTfvdgvL4fq655WaOi1snv1Q= -github.com/quic-go/quic-go v0.40.1/go.mod h1:PeN7kuVJ4xZbxSv/4OX6S1USOX8MJvydwpTx31vx60c= +github.com/quic-go/quic-go v0.41.0 h1:aD8MmHfgqTURWNJy48IYFg2OnxwHT3JL7ahGs73lb4k= +github.com/quic-go/quic-go v0.41.0/go.mod h1:qCkNjqczPEvgsOnxZ0eCD14lv+B2LHlFAB++CNOh9hA= github.com/quic-go/webtransport-go v0.6.0 h1:CvNsKqc4W2HljHJnoT+rMmbRJybShZ0YPFDD3NxaZLY= github.com/quic-go/webtransport-go v0.6.0/go.mod h1:9KjU4AEBqEQidGHNDkZrb8CAa1abRaosM2yGOyiikEc= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= @@ -635,6 +660,7 @@ github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtD github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= +github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd/go.mod h1:hPqNNc0+uJM6H+SuU8sEs5K5IQeKccPqeSjfgcKGgPk= @@ -701,7 +727,6 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= @@ -710,6 +735,7 @@ github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70 github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= github.com/tj/assert v0.0.3 h1:Df/BlaZ20mq6kuai7f5z2TvPFiwC3xaWJSDQNiIS3Rk= +github.com/tj/assert v0.0.3/go.mod h1:Ne6X72Q+TB1AteidzQncjw9PabbMp4PBMZ1k+vd1Pvk= github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c h1:u6SKchux2yDvFQnDHS3lPnIRmfVJ5Sxy3ao2SIdysLQ= github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM= github.com/ucarion/urlpath v0.0.0-20200424170820-7ccc79b76bbb h1:Ywfo8sUltxogBpFuMOFRrrSifO788kAFxmvVw31PtQQ= @@ -723,6 +749,7 @@ github.com/wangjia184/sortedset v0.0.0-20160527075905-f5d03557ba30/go.mod h1:Yko github.com/warpfork/go-testmark v0.3.0/go.mod h1:jhEf8FVxd+F17juRubpmut64NEG6I2rgkUhlcqqXwE0= github.com/warpfork/go-testmark v0.9.0/go.mod h1:jhEf8FVxd+F17juRubpmut64NEG6I2rgkUhlcqqXwE0= github.com/warpfork/go-testmark v0.12.1 h1:rMgCpJfwy1sJ50x0M0NgyphxYYPMOODIJHhsXyEHU0s= +github.com/warpfork/go-testmark v0.12.1/go.mod h1:kHwy7wfvGSPh1rQJYKayD4AbtNaeyZdcGi9tNJTaa5Y= github.com/warpfork/go-wish v0.0.0-20200122115046-b9ea61034e4a/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0 h1:GDDkbFiaK8jsSDJfjId/PEGEShv6ugrt4kYsC5UIDaQ= github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= @@ -777,12 +804,14 @@ go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= +go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= go.uber.org/fx v1.20.1 h1:zVwVQGS8zYvhh9Xxcu4w1M6ESyeMzebzj2NbSayZ4Mk= go.uber.org/fx v1.20.1/go.mod h1:iSYNbHf2y55acNCwCXKx7LbWb5WG1Bnue5RDXz1OREg= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= @@ -795,8 +824,8 @@ go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.14.1/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= -go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= -go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= +go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= +go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= go4.org v0.0.0-20200411211856-f5505b9728dd/go.mod h1:CIiUVy99QCPfoE13bO4EZaz5GZMZXMSBGhxRdsvzbkg= go4.org v0.0.0-20230225012048-214862532bf5 h1:nifaUDeh+rPaBCMPMQHZmvJf+QdpLFnuQPwx+LxVmtc= @@ -819,9 +848,12 @@ golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWP golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= -golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= -golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc= -golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= +golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= +golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= +golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= +golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= +golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= +golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -830,8 +862,8 @@ golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20240119083558-1b970713d09a h1:Q8/wZp0KX97QFTc2ywcOE0YRjZPVIx+MXInMzdvQqcA= -golang.org/x/exp v0.0.0-20240119083558-1b970713d09a/go.mod h1:idGWGoKP1toJGkd5/ig9ZLuPcZBC3ewk7SzmH0uou08= +golang.org/x/exp v0.0.0-20240213143201-ec583247a57a h1:HinSgX1tJRX3KsL//Gxynpw5CTOAIPhgL4W8PNiIpVE= +golang.org/x/exp v0.0.0-20240213143201-ec583247a57a/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -855,8 +887,8 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= -golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8= +golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -888,14 +920,16 @@ golang.org/x/net v0.0.0-20210423184538-5f58ad60dda6/go.mod h1:OJAsFXCWl8Ukc7SiCT golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= -golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= -golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= +golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ= +golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= +golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= +golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= +golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -965,22 +999,27 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= -golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo= +golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= +golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= +golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -989,10 +1028,12 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1036,8 +1077,8 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc= -golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps= +golang.org/x/tools v0.18.0 h1:k8NLag8AGHnn+PHbl7g43CtqZAwG60vZkLqgyZgIHgQ= +golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1083,6 +1124,7 @@ google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvx google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20240102182953-50ed04b92917 h1:nz5NESFLZbJGPFxDT/HCn+V1mZ8JGNoY4nUpmW/Y2eg= +google.golang.org/genproto v0.0.0-20240102182953-50ed04b92917/go.mod h1:pZqR+glSb11aJ+JQcczCvgf47+duRuzNSKqE8YAQnV0= google.golang.org/genproto/googleapis/api v0.0.0-20240108191215-35c7eff3a6b1 h1:OPXtXn7fNMaXwO3JvOmF1QyTc00jsSFFz1vXXBOdCDo= google.golang.org/genproto/googleapis/api v0.0.0-20240108191215-35c7eff3a6b1/go.mod h1:B5xPO//w8qmBDjGReYLpR6UJPnkldGkCSMoH/2vxJeg= google.golang.org/genproto/googleapis/rpc v0.0.0-20240108191215-35c7eff3a6b1 h1:gphdwh0npgs8elJ4T6J+DQJHPVF7RsuJHCfwztUb4J4= diff --git a/go.mod b/go.mod index a0d60bda2..fae6f2f96 100644 --- a/go.mod +++ b/go.mod @@ -47,7 +47,7 @@ require ( github.com/jbenet/goprocess v0.1.4 github.com/julienschmidt/httprouter v1.3.0 github.com/libp2p/go-doh-resolver v0.4.0 - github.com/libp2p/go-libp2p v0.32.2 + github.com/libp2p/go-libp2p v0.33.0 github.com/libp2p/go-libp2p-http v0.5.0 github.com/libp2p/go-libp2p-kad-dht v0.24.4 github.com/libp2p/go-libp2p-kbucket v0.6.3 @@ -82,12 +82,12 @@ require ( go.uber.org/dig v1.17.1 go.uber.org/fx v1.20.1 go.uber.org/multierr v1.11.0 - go.uber.org/zap v1.26.0 - golang.org/x/crypto v0.18.0 - golang.org/x/exp v0.0.0-20240119083558-1b970713d09a - golang.org/x/mod v0.14.0 + go.uber.org/zap v1.27.0 + golang.org/x/crypto v0.19.0 + golang.org/x/exp v0.0.0-20240213143201-ec583247a57a + golang.org/x/mod v0.15.0 golang.org/x/sync v0.6.0 - golang.org/x/sys v0.16.0 + golang.org/x/sys v0.17.0 google.golang.org/protobuf v1.32.0 ) @@ -110,7 +110,7 @@ require ( github.com/docker/go-units v0.5.0 // indirect github.com/elastic/gosigar v0.14.2 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect - github.com/flynn/noise v1.0.1 // indirect + github.com/flynn/noise v1.1.0 // indirect github.com/francoispqt/gojay v1.2.13 // indirect github.com/gabriel-vasile/mimetype v1.4.3 // indirect github.com/go-kit/log v0.2.1 // indirect @@ -124,9 +124,9 @@ require ( github.com/golang/protobuf v1.5.3 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/gopacket v1.1.19 // indirect - github.com/google/pprof v0.0.0-20231229205709-960ae82b1e42 // indirect + github.com/google/pprof v0.0.0-20240207164012-fb44976bdcd5 // indirect github.com/gorilla/mux v1.8.1 // indirect - github.com/gorilla/websocket v1.5.0 // indirect + github.com/gorilla/websocket v1.5.1 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/golang-lru v1.0.2 // indirect @@ -147,8 +147,8 @@ require ( github.com/ipfs/go-peertaskqueue v0.8.1 // indirect github.com/ipfs/go-verifcid v0.0.2 // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect - github.com/klauspost/compress v1.17.4 // indirect - github.com/klauspost/cpuid/v2 v2.2.6 // indirect + github.com/klauspost/compress v1.17.6 // indirect + github.com/klauspost/cpuid/v2 v2.2.7 // indirect github.com/koron/go-ssdp v0.0.4 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/libp2p/go-cidranger v1.1.0 // indirect @@ -177,35 +177,34 @@ require ( github.com/multiformats/go-multiaddr-fmt v0.1.0 // indirect github.com/multiformats/go-multistream v0.5.0 // indirect github.com/multiformats/go-varint v0.0.7 // indirect - github.com/onsi/ginkgo/v2 v2.13.2 // indirect - github.com/opencontainers/runtime-spec v1.1.0 // indirect + github.com/onsi/ginkgo/v2 v2.15.0 // indirect + github.com/opencontainers/runtime-spec v1.2.0 // indirect github.com/openzipkin/zipkin-go v0.4.2 // indirect github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 // indirect github.com/pion/datachannel v1.5.5 // indirect - github.com/pion/dtls/v2 v2.2.7 // indirect - github.com/pion/ice/v2 v2.3.6 // indirect - github.com/pion/interceptor v0.1.17 // indirect + github.com/pion/dtls/v2 v2.2.8 // indirect + github.com/pion/ice/v2 v2.3.11 // indirect + github.com/pion/interceptor v0.1.25 // indirect github.com/pion/logging v0.2.2 // indirect - github.com/pion/mdns v0.0.7 // indirect + github.com/pion/mdns v0.0.9 // indirect github.com/pion/randutil v0.1.0 // indirect - github.com/pion/rtcp v1.2.10 // indirect - github.com/pion/rtp v1.7.13 // indirect - github.com/pion/sctp v1.8.7 // indirect + github.com/pion/rtcp v1.2.13 // indirect + github.com/pion/rtp v1.8.3 // indirect + github.com/pion/sctp v1.8.9 // indirect github.com/pion/sdp/v3 v3.0.6 // indirect - github.com/pion/srtp/v2 v2.0.15 // indirect - github.com/pion/stun v0.6.0 // indirect - github.com/pion/transport/v2 v2.2.1 // indirect - github.com/pion/turn/v2 v2.1.0 // indirect - github.com/pion/webrtc/v3 v3.2.9 // indirect + github.com/pion/srtp/v2 v2.0.18 // indirect + github.com/pion/stun v0.6.1 // indirect + github.com/pion/transport/v2 v2.2.4 // indirect + github.com/pion/turn/v2 v2.1.4 // indirect + github.com/pion/webrtc/v3 v3.2.23 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/polydawn/refmt v0.89.0 // indirect - github.com/prometheus/client_model v0.5.0 // indirect - github.com/prometheus/common v0.46.0 // indirect + github.com/prometheus/client_model v0.6.0 // indirect + github.com/prometheus/common v0.47.0 // indirect github.com/prometheus/procfs v0.12.0 // indirect github.com/prometheus/statsd_exporter v0.22.7 // indirect github.com/quic-go/qpack v0.4.0 // indirect - github.com/quic-go/qtls-go1-20 v0.4.1 // indirect - github.com/quic-go/quic-go v0.40.1 // indirect + github.com/quic-go/quic-go v0.41.0 // indirect github.com/quic-go/webtransport-go v0.6.0 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/rs/cors v1.7.0 // indirect @@ -234,11 +233,11 @@ require ( go.uber.org/atomic v1.11.0 // indirect go.uber.org/mock v0.4.0 // indirect go4.org v0.0.0-20230225012048-214862532bf5 // indirect - golang.org/x/net v0.20.0 // indirect + golang.org/x/net v0.21.0 // indirect golang.org/x/oauth2 v0.16.0 // indirect - golang.org/x/term v0.16.0 // indirect + golang.org/x/term v0.17.0 // indirect golang.org/x/text v0.14.0 // indirect - golang.org/x/tools v0.17.0 // indirect + golang.org/x/tools v0.18.0 // indirect golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect gonum.org/v1/gonum v0.14.0 // indirect google.golang.org/appengine v1.6.8 // indirect @@ -251,4 +250,6 @@ require ( lukechampine.com/blake3 v1.2.1 // indirect ) -go 1.20 +go 1.21 + +toolchain go1.21.7 diff --git a/go.sum b/go.sum index 259e0eab8..004c01809 100644 --- a/go.sum +++ b/go.sum @@ -131,6 +131,7 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c h1:pFUpOrbxDR6AkioZ1ySsx5yxlDQZ8stG2b88gTPxgJU= github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c/go.mod h1:6UhI8N9EjYm1c2odKpFpAYeR8dsBeM7PtzQhRgxRr9U= github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y= +github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= @@ -162,13 +163,14 @@ github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= -github.com/flynn/noise v1.0.1 h1:vPp/jdQLXC6ppsXSj/pM3W1BIJ5FEHE2TulSJBpb43Y= -github.com/flynn/noise v1.0.1/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag= +github.com/flynn/noise v1.1.0 h1:KjPQoQCEFdZDiP03phOvGi11+SVVhBG2wOWAorLsstg= +github.com/flynn/noise v1.1.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag= github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk= github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/frankban/quicktest v1.14.0/go.mod h1:NeW+ay9A/U67EYXNFA1nPE8e/tnQv/09mUdL/ijj8og= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= +github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= @@ -264,6 +266,7 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -278,12 +281,12 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20231229205709-960ae82b1e42 h1:dHLYa5D8/Ta0aLR2XcPsrkpAgGeFs6thhMcQK0oQ0n8= -github.com/google/pprof v0.0.0-20231229205709-960ae82b1e42/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= +github.com/google/pprof v0.0.0-20240207164012-fb44976bdcd5 h1:E/LAvt58di64hlYjx7AsNS6C/ysHWYo+2qPCZKTQhRo= +github.com/google/pprof v0.0.0-20240207164012-fb44976bdcd5/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU= github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= @@ -292,10 +295,11 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c h1:7lF+Vz0LqiRidnzC1Oq86fpX1q/iEv2KJdrCtttYjT4= +github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= -github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= -github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= +github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0 h1:Wqo399gCIufwto+VfwCSvsnfGpF/w5E9CNxSwbpD6No= @@ -330,6 +334,7 @@ github.com/ipfs/boxo v0.18.0/go.mod h1:pIZgTWdm3k3pLF9Uq6MB8JEcW07UDwNJjlXW1HELW github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= +github.com/ipfs/go-bitswap v0.11.0/go.mod h1:05aE8H3XOU+LXpTedeAS0OZpcO1WFsj5niYQH9a1Tmk= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= github.com/ipfs/go-block-format v0.0.3/go.mod h1:4LmD4ZUw0mhO+JSKdpWwrzATiEfM7WWgQ8H5l6P8MVk= github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs= @@ -368,6 +373,7 @@ github.com/ipfs/go-fs-lock v0.0.7/go.mod h1:Js8ka+FNYmgQRLrRXzU3CB/+Csr1BwrRilEc github.com/ipfs/go-ipfs-blockstore v1.3.0 h1:m2EXaWgwTzAfsmt5UdJ7Is6l4gJcaM/A12XwJyvYvMM= github.com/ipfs/go-ipfs-blockstore v1.3.0/go.mod h1:KgtZyc9fq+P2xJUiCAzbRdhhqJHvsw8u2Dlqy2MyRTE= github.com/ipfs/go-ipfs-blocksutil v0.0.1 h1:Eh/H4pc1hsvhzsQoMEP3Bke/aW5P5rVM1IWFJMcGIPQ= +github.com/ipfs/go-ipfs-blocksutil v0.0.1/go.mod h1:Yq4M86uIOmxmGPUHv/uI7uKqZNtLb449gwKqXjIsnRk= github.com/ipfs/go-ipfs-chunker v0.0.5 h1:ojCf7HV/m+uS2vhUGWcogIIxiO5ubl5O57Q7NapWLY8= github.com/ipfs/go-ipfs-chunker v0.0.5/go.mod h1:jhgdF8vxRHycr00k13FM8Y0E+6BoalYeobXmUyTreP8= github.com/ipfs/go-ipfs-cmds v0.10.0 h1:ZB4+RgYaH4UARfJY0uLKl5UXgApqnRjKbuCiJVcErYk= @@ -380,11 +386,13 @@ github.com/ipfs/go-ipfs-ds-help v1.1.0/go.mod h1:YR5+6EaebOhfcqVCyqemItCLthrpVNo github.com/ipfs/go-ipfs-exchange-interface v0.2.0 h1:8lMSJmKogZYNo2jjhUs0izT+dck05pqUw4mWNW9Pw6Y= github.com/ipfs/go-ipfs-exchange-interface v0.2.0/go.mod h1:z6+RhJuDQbqKguVyslSOuVDhqF9JtTrO3eptSAiW2/Y= github.com/ipfs/go-ipfs-exchange-offline v0.3.0 h1:c/Dg8GDPzixGd0MC8Jh6mjOwU57uYokgWRFidfvEkuA= +github.com/ipfs/go-ipfs-exchange-offline v0.3.0/go.mod h1:MOdJ9DChbb5u37M1IcbrRB02e++Z7521fMxqCNRrz9s= github.com/ipfs/go-ipfs-pq v0.0.3 h1:YpoHVJB+jzK15mr/xsWC574tyDLkezVrDNeaalQBsTE= github.com/ipfs/go-ipfs-pq v0.0.3/go.mod h1:btNw5hsHBpRcSSgZtiNm/SLj5gYIZ18AKtv3kERkRb4= github.com/ipfs/go-ipfs-redirects-file v0.1.1 h1:Io++k0Vf/wK+tfnhEh63Yte1oQK5VGT2hIEYpD0Rzx8= github.com/ipfs/go-ipfs-redirects-file v0.1.1/go.mod h1:tAwRjCV0RjLTjH8DR/AU7VYvfQECg+lpUy2Mdzv7gyk= github.com/ipfs/go-ipfs-routing v0.3.0 h1:9W/W3N+g+y4ZDeffSgqhgo7BsBSJwPMcyssET9OWevc= +github.com/ipfs/go-ipfs-routing v0.3.0/go.mod h1:dKqtTFIql7e1zYsEuWLyuOU+E0WJWW8JjbTPLParDWo= github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyBCNzQxlJBc= github.com/ipfs/go-ipfs-util v0.0.2/go.mod h1:CbPtkWJzjLdEcezDns2XYaehFVNXG9zrdrtMecczcsQ= github.com/ipfs/go-ipfs-util v0.0.3 h1:2RFdGez6bu2ZlZdI+rWfIdbQb1KudQp3VGwPtdNCmE0= @@ -416,6 +424,7 @@ github.com/ipfs/go-metrics-prometheus v0.0.2/go.mod h1:ELLU99AQQNi+zX6GCGm2lAgnz github.com/ipfs/go-peertaskqueue v0.8.1 h1:YhxAs1+wxb5jk7RvS0LHdyiILpNmRIRnZVztekOF0pg= github.com/ipfs/go-peertaskqueue v0.8.1/go.mod h1:Oxxd3eaK279FxeydSPPVGHzbwVeHjatZ2GA8XD+KbPU= github.com/ipfs/go-unixfs v0.4.5 h1:wj8JhxvV1G6CD7swACwSKYa+NgtdWC1RUit+gFnymDU= +github.com/ipfs/go-unixfs v0.4.5/go.mod h1:BIznJNvt/gEx/ooRMI4Us9K8+qeGO7vx1ohnbk8gjFg= github.com/ipfs/go-unixfsnode v1.9.0 h1:ubEhQhr22sPAKO2DNsyVBW7YB/zA8Zkif25aBvz8rc8= github.com/ipfs/go-unixfsnode v1.9.0/go.mod h1:HxRu9HYHOjK6HUqFBAi++7DVoWAHn0o4v/nZ/VA+0g8= github.com/ipfs/go-verifcid v0.0.2 h1:XPnUv0XmdH+ZIhLGKg6U2vaPaRDXb9urMyNVCE7uvTs= @@ -431,6 +440,7 @@ github.com/ipld/go-ipld-prime v0.14.1/go.mod h1:QcE4Y9n/ZZr8Ijg5bGPT0GqYWgZ1704n github.com/ipld/go-ipld-prime v0.21.0 h1:n4JmcpOlPDIxBcY037SVfpd1G+Sj1nKZah0m6QH9C2E= github.com/ipld/go-ipld-prime v0.21.0/go.mod h1:3RLqy//ERg/y5oShXXdx5YIp50cFGOanyMctpPjsvxQ= github.com/ipld/go-ipld-prime/storage/bsadapter v0.0.0-20230102063945-1a409dc236dd h1:gMlw/MhNr2Wtp5RwGdsW23cs+yCuj9k2ON7i9MiJlRo= +github.com/ipld/go-ipld-prime/storage/bsadapter v0.0.0-20230102063945-1a409dc236dd/go.mod h1:wZ8hH8UxeryOs4kJEJaiui/s00hDSbE37OKsL47g+Sw= github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/jbenet/go-cienv v0.1.0 h1:Vc/s0QbQtoxX8MwwSLWWh+xNNZvM3Lw7NsTcHrvvhMc= @@ -465,12 +475,12 @@ github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQL 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.17.4 h1:Ej5ixsIri7BrIjBkRZLTo6ghwrEtHFk7ijlczPW4fZ4= -github.com/klauspost/compress v1.17.4/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= +github.com/klauspost/compress v1.17.6 h1:60eq2E/jlfwQXtvZEeBUYADs+BwKBWURIY+Gj2eRGjI= +github.com/klauspost/compress v1.17.6/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/48xc= -github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= +github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/koron/go-ssdp v0.0.4 h1:1IDwrghSKYM7yLf7XCzbByg2sJ/JcNOZRXS2jczTwz0= @@ -481,6 +491,7 @@ github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfn github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= @@ -498,8 +509,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.32.2 h1:s8GYN4YJzgUoyeYNPdW7JZeZ5Ee31iNaIBfGYMAY4FQ= -github.com/libp2p/go-libp2p v0.32.2/go.mod h1:E0LKe+diV/ZVJVnOJby8VC5xzHF0660osg71skcxJvk= +github.com/libp2p/go-libp2p v0.33.0 h1:yTPSr8sJRbfeEYXyeN8VPVSlTlFjtMUwGDRniwaf/xQ= +github.com/libp2p/go-libp2p v0.33.0/go.mod h1:RIJFRQVUBKy82dnW7J5f1homqqv6NcsDJAl3e7CRGfE= github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94= github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= @@ -654,16 +665,17 @@ github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9k github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.13.2 h1:Bi2gGVkfn6gQcjNjZJVO8Gf0FHzMPf2phUei9tejVMs= -github.com/onsi/ginkgo/v2 v2.13.2/go.mod h1:XStQ8QcGwLyF4HdfcZB8SFOS/MWCgDuXMSBe6zrvLgM= +github.com/onsi/ginkgo/v2 v2.15.0 h1:79HwNRBAZHOEwrczrgSOPy+eFTTlIGELKy5as+ClttY= +github.com/onsi/ginkgo/v2 v2.15.0/go.mod h1:HlxMHtYF57y6Dpf+mc5529KKmSq9h2FpCF+/ZkwUxKM= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= -github.com/onsi/gomega v1.29.0 h1:KIA/t2t5UBzoirT4H9tsML45GEbo3ouUnBHsCfD2tVg= +github.com/onsi/gomega v1.30.0 h1:hvMK7xYz4D3HapigLTeGdId/NcfQx1VHMJc60ew99+8= +github.com/onsi/gomega v1.30.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opencontainers/runtime-spec v1.1.0 h1:HHUyrt9mwHUjtasSbXSMvs4cyFxh+Bll4AjJ9odEGpg= -github.com/opencontainers/runtime-spec v1.1.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/runtime-spec v1.2.0 h1:z97+pHb3uELt/yiAWD691HNHQIF07bE7dzrbT927iTk= +github.com/opencontainers/runtime-spec v1.2.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= @@ -678,43 +690,51 @@ github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 h1:1/WtZae0yGtPq+TI6+ github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9/go.mod h1:x3N5drFsm2uilKKuuYo6LdyD8vZAW55sH/9w+pbo1sw= github.com/pion/datachannel v1.5.5 h1:10ef4kwdjije+M9d7Xm9im2Y3O6A6ccQb0zcqZcJew8= github.com/pion/datachannel v1.5.5/go.mod h1:iMz+lECmfdCMqFRhXhcA/219B0SQlbpoR2V118yimL0= -github.com/pion/dtls/v2 v2.2.7 h1:cSUBsETxepsCSFSxC3mc/aDo14qQLMSL+O6IjG28yV8= github.com/pion/dtls/v2 v2.2.7/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s= -github.com/pion/ice/v2 v2.3.6 h1:Jgqw36cAud47iD+N6rNX225uHvrgWtAlHfVyOQc3Heg= -github.com/pion/ice/v2 v2.3.6/go.mod h1:9/TzKDRwBVAPsC+YOrKH/e3xDrubeTRACU9/sHQarsU= -github.com/pion/interceptor v0.1.17 h1:prJtgwFh/gB8zMqGZoOgJPHivOwVAp61i2aG61Du/1w= -github.com/pion/interceptor v0.1.17/go.mod h1:SY8kpmfVBvrbUzvj2bsXz7OJt5JvmVNZ+4Kjq7FcwrI= +github.com/pion/dtls/v2 v2.2.8 h1:BUroldfiIbV9jSnC6cKOMnyiORRWrWWpV11JUyEu5OA= +github.com/pion/dtls/v2 v2.2.8/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s= +github.com/pion/ice/v2 v2.3.11 h1:rZjVmUwyT55cmN8ySMpL7rsS8KYsJERsrxJLLxpKhdw= +github.com/pion/ice/v2 v2.3.11/go.mod h1:hPcLC3kxMa+JGRzMHqQzjoSj3xtE9F+eoncmXLlCL4E= +github.com/pion/interceptor v0.1.25 h1:pwY9r7P6ToQ3+IF0bajN0xmk/fNw/suTgaTdlwTDmhc= +github.com/pion/interceptor v0.1.25/go.mod h1:wkbPYAak5zKsfpVDYMtEfWEy8D4zL+rpxCxPImLOg3Y= github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY= github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms= -github.com/pion/mdns v0.0.7 h1:P0UB4Sr6xDWEox0kTVxF0LmQihtCbSAdW0H2nEgkA3U= -github.com/pion/mdns v0.0.7/go.mod h1:4iP2UbeFhLI/vWju/bw6ZfwjJzk0z8DNValjGxR/dD8= +github.com/pion/mdns v0.0.8/go.mod h1:hYE72WX8WDveIhg7fmXgMKivD3Puklk0Ymzog0lSyaI= +github.com/pion/mdns v0.0.9 h1:7Ue5KZsqq8EuqStnpPWV33vYYEH0+skdDN5L7EiEsI4= +github.com/pion/mdns v0.0.9/go.mod h1:2JA5exfxwzXiCihmxpTKgFUpiQws2MnipoPK09vecIc= github.com/pion/randutil v0.1.0 h1:CFG1UdESneORglEsnimhUjf33Rwjubwj6xfiOXBa3mA= github.com/pion/randutil v0.1.0/go.mod h1:XcJrSMMbbMRhASFVOlj/5hQial/Y8oH/HVo7TBZq+j8= -github.com/pion/rtcp v1.2.10 h1:nkr3uj+8Sp97zyItdN60tE/S6vk4al5CPRR6Gejsdjc= github.com/pion/rtcp v1.2.10/go.mod h1:ztfEwXZNLGyF1oQDttz/ZKIBaeeg/oWbRYqzBM9TL1I= -github.com/pion/rtp v1.7.13 h1:qcHwlmtiI50t1XivvoawdCGTP4Uiypzfrsap+bijcoA= -github.com/pion/rtp v1.7.13/go.mod h1:bDb5n+BFZxXx0Ea7E5qe+klMuqiBrP+w8XSjiWtCUko= +github.com/pion/rtcp v1.2.12/go.mod h1:sn6qjxvnwyAkkPzPULIbVqSKI5Dv54Rv7VG0kNxh9L4= +github.com/pion/rtcp v1.2.13 h1:+EQijuisKwm/8VBs8nWllr0bIndR7Lf7cZG200mpbNo= +github.com/pion/rtcp v1.2.13/go.mod h1:sn6qjxvnwyAkkPzPULIbVqSKI5Dv54Rv7VG0kNxh9L4= +github.com/pion/rtp v1.8.2/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU= +github.com/pion/rtp v1.8.3 h1:VEHxqzSVQxCkKDSHro5/4IUUG1ea+MFdqR2R3xSpNU8= +github.com/pion/rtp v1.8.3/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU= github.com/pion/sctp v1.8.5/go.mod h1:SUFFfDpViyKejTAdwD1d/HQsCu+V/40cCs2nZIvC3s0= -github.com/pion/sctp v1.8.7 h1:JnABvFakZueGAn4KU/4PSKg+GWbF6QWbKTWZOSGJjXw= -github.com/pion/sctp v1.8.7/go.mod h1:g1Ul+ARqZq5JEmoFy87Q/4CePtKnTJ1QCL9dBBdN6AU= +github.com/pion/sctp v1.8.8/go.mod h1:igF9nZBrjh5AtmKc7U30jXltsFHicFCXSmWA2GWRaWs= +github.com/pion/sctp v1.8.9 h1:TP5ZVxV5J7rz7uZmbyvnUvsn7EJ2x/5q9uhsTtXbI3g= +github.com/pion/sctp v1.8.9/go.mod h1:cMLT45jqw3+jiJCrtHVwfQLnfR0MGZ4rgOJwUOIqLkI= github.com/pion/sdp/v3 v3.0.6 h1:WuDLhtuFUUVpTfus9ILC4HRyHsW6TdugjEX/QY9OiUw= github.com/pion/sdp/v3 v3.0.6/go.mod h1:iiFWFpQO8Fy3S5ldclBkpXqmWy02ns78NOKoLLL0YQw= -github.com/pion/srtp/v2 v2.0.15 h1:+tqRtXGsGwHC0G0IUIAzRmdkHvriF79IHVfZGfHrQoA= -github.com/pion/srtp/v2 v2.0.15/go.mod h1:b/pQOlDrbB0HEH5EUAQXzSYxikFbNcNuKmF8tM0hCtw= -github.com/pion/stun v0.4.0/go.mod h1:QPsh1/SbXASntw3zkkrIk3ZJVKz4saBY2G7S10P3wCw= -github.com/pion/stun v0.6.0 h1:JHT/2iyGDPrFWE8NNC15wnddBN8KifsEDw8swQmrEmU= -github.com/pion/stun v0.6.0/go.mod h1:HPqcfoeqQn9cuaet7AOmB5e5xkObu9DwBdurwLKO9oA= +github.com/pion/srtp/v2 v2.0.18 h1:vKpAXfawO9RtTRKZJbG4y0v1b11NZxQnxRl85kGuUlo= +github.com/pion/srtp/v2 v2.0.18/go.mod h1:0KJQjA99A6/a0DOVTu1PhDSw0CXF2jTkqOoMg3ODqdA= +github.com/pion/stun v0.6.1 h1:8lp6YejULeHBF8NmV8e2787BogQhduZugh5PdhDyyN4= +github.com/pion/stun v0.6.1/go.mod h1:/hO7APkX4hZKu/D0f2lHzNyvdkTGtIy3NDmLR7kSz/8= github.com/pion/transport v0.14.1 h1:XSM6olwW+o8J4SCmOBb/BpwZypkHeyM0PGFCxNQBr40= github.com/pion/transport v0.14.1/go.mod h1:4tGmbk00NeYA3rUa9+n+dzCCoKkcy3YlYb99Jn2fNnI= -github.com/pion/transport/v2 v2.0.0/go.mod h1:HS2MEBJTwD+1ZI2eSXSvHJx/HnzQqRy2/LXxt6eVMHc= -github.com/pion/transport/v2 v2.1.0/go.mod h1:AdSw4YBZVDkZm8fpoz+fclXyQwANWmZAlDuQdctTThQ= -github.com/pion/transport/v2 v2.2.0/go.mod h1:AdSw4YBZVDkZm8fpoz+fclXyQwANWmZAlDuQdctTThQ= -github.com/pion/transport/v2 v2.2.1 h1:7qYnCBlpgSJNYMbLCKuSY9KbQdBFoETvPNETv0y4N7c= github.com/pion/transport/v2 v2.2.1/go.mod h1:cXXWavvCnFF6McHTft3DWS9iic2Mftcz1Aq29pGcU5g= -github.com/pion/turn/v2 v2.1.0 h1:5wGHSgGhJhP/RpabkUb/T9PdsAjkGLS6toYz5HNzoSI= -github.com/pion/turn/v2 v2.1.0/go.mod h1:yrT5XbXSGX1VFSF31A3c1kCNB5bBZgk/uu5LET162qs= -github.com/pion/webrtc/v3 v3.2.9 h1:U8NSjQDlZZ+Iy/hg42Q/u6mhEVSXYvKrOIZiZwYTfLc= -github.com/pion/webrtc/v3 v3.2.9/go.mod h1:gjQLMZeyN3jXBGdxGmUYCyKjOuYX/c99BDjGqmadq0A= +github.com/pion/transport/v2 v2.2.2/go.mod h1:OJg3ojoBJopjEeECq2yJdXH9YVrUJ1uQ++NjXLOUorc= +github.com/pion/transport/v2 v2.2.3/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0= +github.com/pion/transport/v2 v2.2.4 h1:41JJK6DZQYSeVLxILA2+F4ZkKb4Xd/tFJZRFZQ9QAlo= +github.com/pion/transport/v2 v2.2.4/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0= +github.com/pion/transport/v3 v3.0.1 h1:gDTlPJwROfSfz6QfSi0ZmeCSkFcnWWiiR9ES0ouANiM= +github.com/pion/transport/v3 v3.0.1/go.mod h1:UY7kiITrlMv7/IKgd5eTUcaahZx5oUN3l9SzK5f5xE0= +github.com/pion/turn/v2 v2.1.3/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY= +github.com/pion/turn/v2 v2.1.4 h1:2xn8rduI5W6sCZQkEnIUDAkrBQNl2eYIBCHMZ3QMmP8= +github.com/pion/turn/v2 v2.1.4/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY= +github.com/pion/webrtc/v3 v3.2.23 h1:GbqEuxBbVLFhXk0GwxKAoaIJYiEa9TyoZPEZC+2HZxM= +github.com/pion/webrtc/v3 v3.2.23/go.mod h1:1CaT2fcZzZ6VZA+O1i9yK2DU4EOcXVvSbWG9pr5jefs= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -739,8 +759,8 @@ github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1: github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= -github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= +github.com/prometheus/client_model v0.6.0 h1:k1v3CzpSRUTrKMppY35TLwPvxHqBu0bYgxZzqGIgaos= +github.com/prometheus/client_model v0.6.0/go.mod h1:NTQHnmxFpouOD0DpvP4XujX3CdOAGQPoaGhyTchlyt8= github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= @@ -749,8 +769,8 @@ github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9 github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/common v0.35.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= -github.com/prometheus/common v0.46.0 h1:doXzt5ybi1HBKpsZOL0sSkaNHJJqkyfEWZGGqqScV0Y= -github.com/prometheus/common v0.46.0/go.mod h1:Tp0qkxpb9Jsg54QMe+EAmqXkSV7Evdy1BTn+g2pa/hQ= +github.com/prometheus/common v0.47.0 h1:p5Cz0FNHo7SnWOmWmoRozVcjEp0bIVU8cV7OShpjL1k= +github.com/prometheus/common v0.47.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= @@ -765,10 +785,8 @@ github.com/prometheus/statsd_exporter v0.22.7 h1:7Pji/i2GuhK6Lu7DHrtTkFmNBCudCPT github.com/prometheus/statsd_exporter v0.22.7/go.mod h1:N/TevpjkIh9ccs6nuzY3jQn9dFqnUakOjnEuMPJJJnI= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= -github.com/quic-go/qtls-go1-20 v0.4.1 h1:D33340mCNDAIKBqXuAvexTNMUByrYmFYVfKfDN5nfFs= -github.com/quic-go/qtls-go1-20 v0.4.1/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= -github.com/quic-go/quic-go v0.40.1 h1:X3AGzUNFs0jVuO3esAGnTfvdgvL4fq655WaOi1snv1Q= -github.com/quic-go/quic-go v0.40.1/go.mod h1:PeN7kuVJ4xZbxSv/4OX6S1USOX8MJvydwpTx31vx60c= +github.com/quic-go/quic-go v0.41.0 h1:aD8MmHfgqTURWNJy48IYFg2OnxwHT3JL7ahGs73lb4k= +github.com/quic-go/quic-go v0.41.0/go.mod h1:qCkNjqczPEvgsOnxZ0eCD14lv+B2LHlFAB++CNOh9hA= github.com/quic-go/webtransport-go v0.6.0 h1:CvNsKqc4W2HljHJnoT+rMmbRJybShZ0YPFDD3NxaZLY= github.com/quic-go/webtransport-go v0.6.0/go.mod h1:9KjU4AEBqEQidGHNDkZrb8CAa1abRaosM2yGOyiikEc= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= @@ -776,6 +794,7 @@ github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtD github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= +github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= @@ -846,7 +865,6 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= @@ -867,6 +885,7 @@ github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhso github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/tj/assert v0.0.3 h1:Df/BlaZ20mq6kuai7f5z2TvPFiwC3xaWJSDQNiIS3Rk= +github.com/tj/assert v0.0.3/go.mod h1:Ne6X72Q+TB1AteidzQncjw9PabbMp4PBMZ1k+vd1Pvk= github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c h1:u6SKchux2yDvFQnDHS3lPnIRmfVJ5Sxy3ao2SIdysLQ= github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM= github.com/ucarion/urlpath v0.0.0-20200424170820-7ccc79b76bbb h1:Ywfo8sUltxogBpFuMOFRrrSifO788kAFxmvVw31PtQQ= @@ -880,6 +899,7 @@ github.com/wangjia184/sortedset v0.0.0-20160527075905-f5d03557ba30/go.mod h1:Yko github.com/warpfork/go-testmark v0.3.0/go.mod h1:jhEf8FVxd+F17juRubpmut64NEG6I2rgkUhlcqqXwE0= github.com/warpfork/go-testmark v0.9.0/go.mod h1:jhEf8FVxd+F17juRubpmut64NEG6I2rgkUhlcqqXwE0= github.com/warpfork/go-testmark v0.12.1 h1:rMgCpJfwy1sJ50x0M0NgyphxYYPMOODIJHhsXyEHU0s= +github.com/warpfork/go-testmark v0.12.1/go.mod h1:kHwy7wfvGSPh1rQJYKayD4AbtNaeyZdcGi9tNJTaa5Y= github.com/warpfork/go-wish v0.0.0-20200122115046-b9ea61034e4a/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0 h1:GDDkbFiaK8jsSDJfjId/PEGEShv6ugrt4kYsC5UIDaQ= github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= @@ -959,6 +979,7 @@ go.uber.org/fx v1.20.1 h1:zVwVQGS8zYvhh9Xxcu4w1M6ESyeMzebzj2NbSayZ4Mk= go.uber.org/fx v1.20.1/go.mod h1:iSYNbHf2y55acNCwCXKx7LbWb5WG1Bnue5RDXz1OREg= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= @@ -971,8 +992,8 @@ go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.14.1/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= -go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= -go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= +go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= +go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= go4.org v0.0.0-20200411211856-f5505b9728dd/go.mod h1:CIiUVy99QCPfoE13bO4EZaz5GZMZXMSBGhxRdsvzbkg= go4.org v0.0.0-20230225012048-214862532bf5 h1:nifaUDeh+rPaBCMPMQHZmvJf+QdpLFnuQPwx+LxVmtc= @@ -995,9 +1016,12 @@ golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWP golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= -golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= -golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc= -golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= +golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= +golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= +golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= +golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= +golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= +golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1008,8 +1032,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20240119083558-1b970713d09a h1:Q8/wZp0KX97QFTc2ywcOE0YRjZPVIx+MXInMzdvQqcA= -golang.org/x/exp v0.0.0-20240119083558-1b970713d09a/go.mod h1:idGWGoKP1toJGkd5/ig9ZLuPcZBC3ewk7SzmH0uou08= +golang.org/x/exp v0.0.0-20240213143201-ec583247a57a h1:HinSgX1tJRX3KsL//Gxynpw5CTOAIPhgL4W8PNiIpVE= +golang.org/x/exp v0.0.0-20240213143201-ec583247a57a/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1034,8 +1058,8 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= -golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8= +golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1084,14 +1108,16 @@ golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= -golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= -golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= +golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ= +golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= +golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= +golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= +golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1190,24 +1216,29 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= -golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= -golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE= -golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= +golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo= +golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= +golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= +golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= +golang.org/x/term v0.17.0 h1:mkTF7LCd6WGJNL3K1Ad7kwxNfYAW6a8a8QqtMblp/4U= +golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1217,10 +1248,12 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1281,8 +1314,8 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc= -golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps= +golang.org/x/tools v0.18.0 h1:k8NLag8AGHnn+PHbl7g43CtqZAwG60vZkLqgyZgIHgQ= +golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1354,6 +1387,7 @@ google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20240102182953-50ed04b92917 h1:nz5NESFLZbJGPFxDT/HCn+V1mZ8JGNoY4nUpmW/Y2eg= +google.golang.org/genproto v0.0.0-20240102182953-50ed04b92917/go.mod h1:pZqR+glSb11aJ+JQcczCvgf47+duRuzNSKqE8YAQnV0= google.golang.org/genproto/googleapis/api v0.0.0-20240108191215-35c7eff3a6b1 h1:OPXtXn7fNMaXwO3JvOmF1QyTc00jsSFFz1vXXBOdCDo= google.golang.org/genproto/googleapis/api v0.0.0-20240108191215-35c7eff3a6b1/go.mod h1:B5xPO//w8qmBDjGReYLpR6UJPnkldGkCSMoH/2vxJeg= google.golang.org/genproto/googleapis/rpc v0.0.0-20240108191215-35c7eff3a6b1 h1:gphdwh0npgs8elJ4T6J+DQJHPVF7RsuJHCfwztUb4J4= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index ef6eb0f52..9e38a7086 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -1,6 +1,8 @@ module github.com/ipfs/kubo/test/dependencies -go 1.20 +go 1.21 + +toolchain go1.21.7 replace github.com/ipfs/kubo => ../../ @@ -124,7 +126,7 @@ require ( github.com/kisielk/errcheck v1.6.3 // indirect github.com/kisielk/gotool v1.0.0 // indirect github.com/kkHAIKE/contextcheck v1.1.4 // indirect - github.com/klauspost/cpuid/v2 v2.2.6 // indirect + github.com/klauspost/cpuid/v2 v2.2.7 // indirect github.com/kulti/thelper v0.6.3 // indirect github.com/kunwardeep/paralleltest v1.0.8 // indirect github.com/kyoh86/exportloopref v0.1.11 // indirect @@ -133,7 +135,7 @@ require ( github.com/leonklingele/grouper v1.1.1 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/libp2p/go-cidranger v1.1.0 // indirect - github.com/libp2p/go-libp2p v0.32.2 // indirect + github.com/libp2p/go-libp2p v0.33.0 // indirect github.com/libp2p/go-libp2p-asn-util v0.4.1 // indirect github.com/libp2p/go-libp2p-kad-dht v0.24.4 // indirect github.com/libp2p/go-libp2p-kbucket v0.6.3 // indirect @@ -179,8 +181,8 @@ require ( github.com/polydawn/refmt v0.89.0 // indirect github.com/polyfloyd/go-errorlint v1.4.3 // indirect github.com/prometheus/client_golang v1.18.0 // indirect - github.com/prometheus/client_model v0.5.0 // indirect - github.com/prometheus/common v0.46.0 // indirect + github.com/prometheus/client_model v0.6.0 // indirect + github.com/prometheus/common v0.47.0 // indirect github.com/prometheus/procfs v0.12.0 // indirect github.com/quasilyte/go-ruleguard v0.4.0 // indirect github.com/quasilyte/gogrep v0.5.0 // indirect @@ -237,17 +239,17 @@ require ( go.opentelemetry.io/otel/trace v1.22.0 // indirect go.tmz.dev/musttag v0.7.1 // indirect go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap v1.26.0 // indirect - golang.org/x/crypto v0.18.0 // indirect - golang.org/x/exp v0.0.0-20240119083558-1b970713d09a // indirect + go.uber.org/zap v1.27.0 // indirect + golang.org/x/crypto v0.19.0 // indirect + golang.org/x/exp v0.0.0-20240213143201-ec583247a57a // indirect golang.org/x/exp/typeparams v0.0.0-20230307190834-24139beb5833 // indirect - golang.org/x/mod v0.14.0 // indirect - golang.org/x/net v0.20.0 // indirect + golang.org/x/mod v0.15.0 // indirect + golang.org/x/net v0.21.0 // indirect golang.org/x/sync v0.6.0 // indirect - golang.org/x/sys v0.16.0 // indirect - golang.org/x/term v0.16.0 // indirect + golang.org/x/sys v0.17.0 // indirect + golang.org/x/term v0.17.0 // indirect golang.org/x/text v0.14.0 // indirect - golang.org/x/tools v0.17.0 // indirect + golang.org/x/tools v0.18.0 // indirect gonum.org/v1/gonum v0.14.0 // indirect google.golang.org/protobuf v1.32.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 095dfb022..163c393ab 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -79,6 +79,7 @@ github.com/ashanbrown/makezero v1.1.1 h1:iCQ87C0V0vSyO+M9E/FZYbu65auqH0lnsOkf5Fc github.com/ashanbrown/makezero v1.1.1/go.mod h1:i1bJLCRSCHOcOa9Y6MyF2FTfMZMFdHvxKHxgO5Z1axI= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o= +github.com/benbjohnson/clock v1.3.5/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -114,11 +115,14 @@ github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGX github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM= +github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw= github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= +github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= 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.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/cskr/pubsub v1.0.2 h1:vlOzMhl6PFn60gRlTQQsIfVwaPB/B/8MziK8FhEPt/0= +github.com/cskr/pubsub v1.0.2/go.mod h1:/8MzYXk/NJAz782G8RPkFzXTZVu63VotefPnR9TIRis= github.com/curioswitch/go-reassign v0.2.0 h1:G9UZyOcpk/d7Gd6mqYgd8XYWFMw/znxwGDUstnC9DIo= github.com/curioswitch/go-reassign v0.2.0/go.mod h1:x6OpXuWvgfQaMGks2BZybTngWjT84hqJfKoO8Tt/Roc= github.com/daixiang0/gci v0.11.0 h1:XeQbFKkCRxvVyn06EOuNY6LPGBLVuB/W130c8FrnX6A= @@ -127,15 +131,19 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c h1:pFUpOrbxDR6AkioZ1ySsx5yxlDQZ8stG2b88gTPxgJU= +github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c/go.mod h1:6UhI8N9EjYm1c2odKpFpAYeR8dsBeM7PtzQhRgxRr9U= github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y= +github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= github.com/denis-tingaikin/go-header v0.4.3 h1:tEaZKAlqql6SKCY++utLmkPLd6K8IBM20Ha7UVm+mtU= github.com/denis-tingaikin/go-header v0.4.3/go.mod h1:0wOCWuN71D5qIgE2nz9KrKmuYBAC2Mra5RassOIQ2/c= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= +github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/elastic/gosigar v0.14.2 h1:Dg80n8cr90OZ7x+bAax/QjoW/XqTI11RmA79ZwIm9/4= +github.com/elastic/gosigar v0.14.2/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -155,9 +163,12 @@ github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4 github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94= github.com/firefart/nonamedreturns v1.0.4 h1:abzI1p7mAEPYuR4A+VLKn4eNDOycjYo2phmY9sfv40Y= github.com/firefart/nonamedreturns v1.0.4/go.mod h1:TDhe/tjI1BXo48CmYbUduTV7BdIga8MAO/xbKdcVsGI= -github.com/flynn/noise v1.0.1 h1:vPp/jdQLXC6ppsXSj/pM3W1BIJ5FEHE2TulSJBpb43Y= +github.com/flynn/noise v1.1.0 h1:KjPQoQCEFdZDiP03phOvGi11+SVVhBG2wOWAorLsstg= +github.com/flynn/noise v1.1.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag= github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk= +github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= +github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= @@ -181,6 +192,7 @@ github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/go-toolsmith/astcast v1.1.0 h1:+JN9xZV1A+Re+95pgnMgDboWNVnIMMQXwfBwLRPgSC8= github.com/go-toolsmith/astcast v1.1.0/go.mod h1:qdcuFWeGGS2xX5bLM/c3U9lewg7+Zu4mr+xPwZIB4ZU= github.com/go-toolsmith/astcopy v1.1.0 h1:YGwBN0WM+ekI/6SS6+52zLDEf8Yvp3n2seZITCUBt5s= @@ -193,6 +205,7 @@ github.com/go-toolsmith/astfmt v1.1.0/go.mod h1:OrcLlRwu0CuiIBp/8b5PYF9ktGVZUjlN github.com/go-toolsmith/astp v1.1.0 h1:dXPuCl6u2llURjdPLLDxJeZInAeZ0/eZwFJmqZMnpQA= github.com/go-toolsmith/astp v1.1.0/go.mod h1:0T1xFGz9hicKs8Z5MfAqSUitoUYS30pDMsRVIDHs8CA= github.com/go-toolsmith/pkgload v1.2.2 h1:0CtmHq/02QhxcF7E9N5LIFcYFsMR5rdovfqTtRKkgIk= +github.com/go-toolsmith/pkgload v1.2.2/go.mod h1:R2hxLNRKuAsiXCo2i5J6ZQPhnPMOVtU+f0arbFPWCus= github.com/go-toolsmith/strparse v1.0.0/go.mod h1:YI2nUKP9YGZnL/L1/DLFBfixrcjslWct4wyljWhSRy8= github.com/go-toolsmith/strparse v1.1.0 h1:GAioeZUK9TGxnLS+qfdqNbA4z0SSm5zVNtCQiyP2Bvw= github.com/go-toolsmith/strparse v1.1.0/go.mod h1:7ksGy58fsaQkGQlY8WVoBFNyEPMGuJin1rfoPS4lBSQ= @@ -204,6 +217,7 @@ github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaL github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= +github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= @@ -214,6 +228,7 @@ github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4er github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= @@ -290,7 +305,8 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20231229205709-960ae82b1e42 h1:dHLYa5D8/Ta0aLR2XcPsrkpAgGeFs6thhMcQK0oQ0n8= +github.com/google/pprof v0.0.0-20240207164012-fb44976bdcd5 h1:E/LAvt58di64hlYjx7AsNS6C/ysHWYo+2qPCZKTQhRo= +github.com/google/pprof v0.0.0-20240207164012-fb44976bdcd5/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU= @@ -300,9 +316,11 @@ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5m github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c h1:7lF+Vz0LqiRidnzC1Oq86fpX1q/iEv2KJdrCtttYjT4= +github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gordonklaus/ineffassign v0.0.0-20230610083614-0e73809eb601 h1:mrEEilTAUmaAORhssPPkxj84TsHrPMLBGW2Z4SoTxm8= github.com/gordonklaus/ineffassign v0.0.0-20230610083614-0e73809eb601/go.mod h1:Qcp2HIAYhR7mNUVSIxZww3Guk4it82ghYcEXIAk+QT0= -github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= +github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= +github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= github.com/gostaticanalysis/analysisutil v0.7.1 h1:ZMCjoue3DtDWQ5WyU16YbjbQEQ3VuzwxALrpYd+HeKk= github.com/gostaticanalysis/analysisutil v0.7.1/go.mod h1:v21E3hY37WKMGSnbsw2S/ojApNWb6C1//mXO48CXbVc= github.com/gostaticanalysis/comment v1.4.1/go.mod h1:ih6ZxzTHLdadaiSnF5WY3dxUoXfXAlTaRzuaNDlSado= @@ -314,6 +332,7 @@ github.com/gostaticanalysis/nilerr v0.1.1 h1:ThE+hJP0fEp4zWLkWHWcRyI2Od0p7DlgYG3 github.com/gostaticanalysis/nilerr v0.1.1/go.mod h1:wZYb6YI5YAxxq0i1+VJbY0s2YONW0HU0GPE3+5PWN4A= github.com/gostaticanalysis/testutil v0.3.1-0.20210208050101-bfb5c8eec0e4/go.mod h1:D+FIZ+7OahH3ePw/izIEeH5I06eKs1IKI4Xr64/Am3M= github.com/gostaticanalysis/testutil v0.4.0 h1:nhdCmubdmDF6VEatUNjgUZBJKWRqugoISdUv3PPQgHY= +github.com/gostaticanalysis/testutil v0.4.0/go.mod h1:bLIoPefWXrRi/ssLFWX1dx7Repi5x3CuviD3dgAZaBU= github.com/gxed/go-shellwords v1.0.3 h1:2TP32H4TAklZUdz84oj95BJhVnIrRasyx2j1cqH5K38= github.com/gxed/go-shellwords v1.0.3/go.mod h1:N7paucT91ByIjmVJHhvoarjoQnmsi3Jd3vH7VqgtMxQ= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -336,6 +355,7 @@ github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUq github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= +github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= @@ -355,8 +375,11 @@ github.com/ipfs/go-datastore v0.6.0/go.mod h1:rt5M3nNbSO/8q1t4LNkLyUwRs8HupMeN/8 github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk= github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps= github.com/ipfs/go-ipfs-blocksutil v0.0.1 h1:Eh/H4pc1hsvhzsQoMEP3Bke/aW5P5rVM1IWFJMcGIPQ= +github.com/ipfs/go-ipfs-blocksutil v0.0.1/go.mod h1:Yq4M86uIOmxmGPUHv/uI7uKqZNtLb449gwKqXjIsnRk= github.com/ipfs/go-ipfs-delay v0.0.1 h1:r/UXYyRcddO6thwOnhiznIAiSvxMECGgtv35Xs1IeRQ= +github.com/ipfs/go-ipfs-delay v0.0.1/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= github.com/ipfs/go-ipfs-pq v0.0.3 h1:YpoHVJB+jzK15mr/xsWC574tyDLkezVrDNeaalQBsTE= +github.com/ipfs/go-ipfs-pq v0.0.3/go.mod h1:btNw5hsHBpRcSSgZtiNm/SLj5gYIZ18AKtv3kERkRb4= github.com/ipfs/go-ipfs-util v0.0.3 h1:2RFdGez6bu2ZlZdI+rWfIdbQb1KudQp3VGwPtdNCmE0= github.com/ipfs/go-ipfs-util v0.0.3/go.mod h1:LHzG1a0Ig4G+iZ26UUOMjHd+lfM84LZCrn17xAKWBvs= github.com/ipfs/go-ipld-format v0.6.0 h1:VEJlA2kQ3LqFSIm5Vu6eIlSxD/Ze90xtc4Meten1F5U= @@ -371,6 +394,7 @@ github.com/ipfs/go-log/v2 v2.5.1/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOL github.com/ipfs/go-metrics-interface v0.0.1 h1:j+cpbjYvu4R8zbleSs36gvB7jR+wsL2fGD6n0jO4kdg= github.com/ipfs/go-metrics-interface v0.0.1/go.mod h1:6s6euYU4zowdslK0GKHmqaIZ3j/b/tL7HTWtJ4VPgWY= github.com/ipfs/go-peertaskqueue v0.8.1 h1:YhxAs1+wxb5jk7RvS0LHdyiILpNmRIRnZVztekOF0pg= +github.com/ipfs/go-peertaskqueue v0.8.1/go.mod h1:Oxxd3eaK279FxeydSPPVGHzbwVeHjatZ2GA8XD+KbPU= github.com/ipfs/hang-fds v0.1.0 h1:deBiFlWHsVGzJ0ZMaqscEqRM1r2O1rFZ59UiQXb1Xko= github.com/ipfs/hang-fds v0.1.0/go.mod h1:29VLWOn3ftAgNNgXg/al7b11UzuQ+w7AwtCGcTaWkbM= github.com/ipfs/iptb v1.4.0 h1:YFYTrCkLMRwk/35IMyC6+yjoQSHTEcNcefBStLJzgvo= @@ -382,12 +406,14 @@ github.com/ipld/go-codec-dagpb v1.6.0/go.mod h1:ANzFhfP2uMJxRBr8CE+WQWs5UsNa0pYt github.com/ipld/go-ipld-prime v0.21.0 h1:n4JmcpOlPDIxBcY037SVfpd1G+Sj1nKZah0m6QH9C2E= github.com/ipld/go-ipld-prime v0.21.0/go.mod h1:3RLqy//ERg/y5oShXXdx5YIp50cFGOanyMctpPjsvxQ= github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= +github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA= github.com/jbenet/go-random v0.0.0-20190219211222-123a90aedc0c h1:uUx61FiAa1GI6ZmVd2wf2vULeQZIKG66eybjNXKYCz4= github.com/jbenet/go-random v0.0.0-20190219211222-123a90aedc0c/go.mod h1:sdx1xVM9UuLw1tXnhJWN3piypTUO3vCIHYmG15KE/dU= github.com/jbenet/go-random-files v0.0.0-20190219210431-31b3f20ebded h1:fHCa28iw+qaRWZK4IqrntHxXALD5kKr/ESrpOCRRdrg= github.com/jbenet/go-random-files v0.0.0-20190219210431-31b3f20ebded/go.mod h1:FKvZrl5nnaGnTAMewcq0i7wM5zHD75e0lwlnF8q46uo= github.com/jbenet/go-temp-err-catcher v0.1.0 h1:zpb3ZH6wIE8Shj2sKS+khgRvf7T7RABoLk/+KKHggpk= +github.com/jbenet/go-temp-err-catcher v0.1.0/go.mod h1:0kJRvmDZXNMIiJirNPEYfhpPwbGVtZVWC34vc5WLsDk= github.com/jbenet/goprocess v0.1.4 h1:DRGOFReOMqqDNXwW70QkacFW0YN9QnwLV0Vqk+3oU0o= github.com/jbenet/goprocess v0.1.4/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= github.com/jgautheron/goconst v1.5.1 h1:HxVbL1MhydKs8R8n/HE5NPvzfaYmQJA3o879lE4+WcM= @@ -419,19 +445,23 @@ github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kkHAIKE/contextcheck v1.1.4 h1:B6zAaLhOEEcjvUgIYEqystmnFk1Oemn8bvJhbt0GMb8= github.com/kkHAIKE/contextcheck v1.1.4/go.mod h1:1+i/gWqokIa+dm31mqGLZhZJ7Uh44DJGZVmr6QRBNJg= -github.com/klauspost/compress v1.17.4 h1:Ej5ixsIri7BrIjBkRZLTo6ghwrEtHFk7ijlczPW4fZ4= -github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/48xc= -github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/klauspost/compress v1.17.6 h1:60eq2E/jlfwQXtvZEeBUYADs+BwKBWURIY+Gj2eRGjI= +github.com/klauspost/compress v1.17.6/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= +github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= +github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/koron/go-ssdp v0.0.4 h1:1IDwrghSKYM7yLf7XCzbByg2sJ/JcNOZRXS2jczTwz0= +github.com/koron/go-ssdp v0.0.4/go.mod h1:oDXq+E5IL5q0U8uSBcoAXzTzInwy5lEgC91HoKtbmZk= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kulti/thelper v0.6.3 h1:ElhKf+AlItIu+xGnI990no4cE2+XaSu1ULymV2Yulxs= github.com/kulti/thelper v0.6.3/go.mod h1:DsqKShOvP40epevkFrvIwkCMNYxMeTNjdWL4dqWHZ6I= github.com/kunwardeep/paralleltest v1.0.8 h1:Ul2KsqtzFxTlSU7IP0JusWlLiNqQaloB9vguyjbE558= @@ -449,8 +479,9 @@ github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QT github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38yPW7c= github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= -github.com/libp2p/go-libp2p v0.32.2 h1:s8GYN4YJzgUoyeYNPdW7JZeZ5Ee31iNaIBfGYMAY4FQ= -github.com/libp2p/go-libp2p v0.32.2/go.mod h1:E0LKe+diV/ZVJVnOJby8VC5xzHF0660osg71skcxJvk= +github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= +github.com/libp2p/go-libp2p v0.33.0 h1:yTPSr8sJRbfeEYXyeN8VPVSlTlFjtMUwGDRniwaf/xQ= +github.com/libp2p/go-libp2p v0.33.0/go.mod h1:RIJFRQVUBKy82dnW7J5f1homqqv6NcsDJAl3e7CRGfE= github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94= github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= github.com/libp2p/go-libp2p-kad-dht v0.24.4 h1:ktNiJe7ffsJ1wX3ULpMCwXts99mPqGFSE/Qn1i8pErQ= @@ -462,13 +493,17 @@ github.com/libp2p/go-libp2p-record v0.2.0/go.mod h1:I+3zMkvvg5m2OcSdoL0KPljyJyvN github.com/libp2p/go-libp2p-routing-helpers v0.7.3 h1:u1LGzAMVRK9Nqq5aYDVOiq/HaB93U9WWczBzGyAC5ZY= github.com/libp2p/go-libp2p-routing-helpers v0.7.3/go.mod h1:cN4mJAD/7zfPKXBcs9ze31JGYAZgzdABEm+q/hkswb8= github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA= +github.com/libp2p/go-libp2p-testing v0.12.0/go.mod h1:KcGDRXyN7sQCllucn1cOOS+Dmm7ujhfEyXQL5lvkcPg= github.com/libp2p/go-msgio v0.3.0 h1:mf3Z8B1xcFN314sWX+2vOTShIE0Mmn2TXn3YCUQGNj0= github.com/libp2p/go-msgio v0.3.0/go.mod h1:nyRM819GmVaF9LX3l03RMh10QdOroF++NBbxAb0mmDM= github.com/libp2p/go-nat v0.2.0 h1:Tyz+bUFAYqGyJ/ppPPymMGbIgNRH+WqC5QrT5fKrrGk= +github.com/libp2p/go-nat v0.2.0/go.mod h1:3MJr+GRpRkyT65EpVPBstXLvOlAPzUVlG6Pwg9ohLJk= github.com/libp2p/go-netroute v0.2.1 h1:V8kVrpD8GK0Riv15/7VN6RbUQ3URNZVosw7H2v9tksU= github.com/libp2p/go-netroute v0.2.1/go.mod h1:hraioZr0fhBjG0ZRXJJ6Zj2IVEVNx6tDTFQfSmcq7mQ= github.com/libp2p/go-reuseport v0.4.0 h1:nR5KU7hD0WxXCJbmw7r2rhRYruNRl2koHw8fQscQm2s= +github.com/libp2p/go-reuseport v0.4.0/go.mod h1:ZtI03j/wO5hZVDFo2jKywN6bYKWLOy8Se6DrI2E1cLU= github.com/libp2p/go-yamux/v4 v4.0.1 h1:FfDR4S1wj6Bw2Pqbc8Uz7pCxeRBPbwsBbEdfwiCypkQ= +github.com/libp2p/go-yamux/v4 v4.0.1/go.mod h1:NWjl8ZTLOGlozrXSOZ/HlfG++39iKNnM5wwmtQP1YB4= github.com/lufeee/execinquery v1.2.1 h1:hf0Ems4SHcUGBxpGN7Jz78z1ppVkP/837ZlETPCEtOM= github.com/lufeee/execinquery v1.2.1/go.mod h1:EC7DrEKView09ocscGHC+apXMIaorh4xqSxS/dy8SbM= github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo= @@ -478,6 +513,7 @@ github.com/maratori/testableexamples v1.0.0/go.mod h1:4rhjL1n20TUTT4vdh3RDqSizKL github.com/maratori/testpackage v1.1.1 h1:S58XVV5AD7HADMmD0fNnziNHqKvSdDuEKdPD1rNTU04= github.com/maratori/testpackage v1.1.1/go.mod h1:s4gRK/ym6AMrqpOa/kEbQTV4Q4jb7WeLZzVhVVVOQMc= 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/matoous/godox v0.0.0-20230222163458-006bad1f9d26 h1:gWg6ZQ4JhDfJPqlo2srm/LN17lpybq15AryXIRcWYLE= github.com/matoous/godox v0.0.0-20230222163458-006bad1f9d26/go.mod h1:1BELzlh859Sh1c6+90blK8lbYy0kwQf1bYlBhBysy1s= github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE= @@ -501,7 +537,9 @@ github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJys github.com/miekg/dns v1.1.58 h1:ca2Hdkz+cDg/7eNF6V56jjzuZ4aCAE+DbVkILdQWG/4= github.com/miekg/dns v1.1.58/go.mod h1:Ypv+3b/KadlvW9vJfXOTf300O4UqaHFzFCuHz+rPkBY= github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= +github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b/go.mod h1:lxPUiZwKoFL8DUUmalo2yJJUCxbPKtm8OKfqr2/FTNU= github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc h1:PTfri+PuQmWDqERdnNMiD9ZejrlswWrCpBEZgWOiTrc= +github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc/go.mod h1:cGKTAVKx4SxOuR/czcZ/E2RSJ3sfHs8FpHhQ5CWMf9s= github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM= @@ -530,6 +568,7 @@ github.com/multiformats/go-multiaddr v0.12.2/go.mod h1:GKyaTYjZRdcUhyOetrxTk9z0c github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A= github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk= github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E= +github.com/multiformats/go-multiaddr-fmt v0.1.0/go.mod h1:hGtDIW4PU4BqJ50gW2quDuPVjyWNZxToGUh/HwTZYJo= github.com/multiformats/go-multibase v0.2.0 h1:isdYCVLvksgWlMW9OZRYJEa9pZETFivncJHmHnnd87g= github.com/multiformats/go-multibase v0.2.0/go.mod h1:bFBZX4lKCA/2lyOFSAoKH5SS6oPyjtnzK/XTFDPkNuk= github.com/multiformats/go-multicodec v0.9.0 h1:pb/dlPnzee/Sxv/j4PmkDRxCOi3hXTz3IbPKOXWJkmg= @@ -559,11 +598,13 @@ github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6 github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w= github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo/v2 v2.13.2 h1:Bi2gGVkfn6gQcjNjZJVO8Gf0FHzMPf2phUei9tejVMs= +github.com/onsi/ginkgo/v2 v2.15.0 h1:79HwNRBAZHOEwrczrgSOPy+eFTTlIGELKy5as+ClttY= +github.com/onsi/ginkgo/v2 v2.15.0/go.mod h1:HlxMHtYF57y6Dpf+mc5529KKmSq9h2FpCF+/ZkwUxKM= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= -github.com/opencontainers/runtime-spec v1.1.0 h1:HHUyrt9mwHUjtasSbXSMvs4cyFxh+Bll4AjJ9odEGpg= +github.com/opencontainers/runtime-spec v1.2.0 h1:z97+pHb3uELt/yiAWD691HNHQIF07bE7dzrbT927iTk= +github.com/opencontainers/runtime-spec v1.2.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/otiai10/copy v1.2.0 h1:HvG945u96iNadPoG2/Ja2+AUJeW5YuFQMixq9yirC+k= @@ -573,6 +614,7 @@ github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6 github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo= github.com/otiai10/mint v1.3.1/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc= 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/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pelletier/go-toml/v2 v2.0.5 h1:ipoSadvV8oGUjnUbMub59IDPPwfxF694nG/jwbMiyQg= @@ -599,14 +641,14 @@ github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1: github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= -github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= +github.com/prometheus/client_model v0.6.0 h1:k1v3CzpSRUTrKMppY35TLwPvxHqBu0bYgxZzqGIgaos= +github.com/prometheus/client_model v0.6.0/go.mod h1:NTQHnmxFpouOD0DpvP4XujX3CdOAGQPoaGhyTchlyt8= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= -github.com/prometheus/common v0.46.0 h1:doXzt5ybi1HBKpsZOL0sSkaNHJJqkyfEWZGGqqScV0Y= -github.com/prometheus/common v0.46.0/go.mod h1:Tp0qkxpb9Jsg54QMe+EAmqXkSV7Evdy1BTn+g2pa/hQ= +github.com/prometheus/common v0.47.0 h1:p5Cz0FNHo7SnWOmWmoRozVcjEp0bIVU8cV7OShpjL1k= +github.com/prometheus/common v0.47.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= @@ -623,12 +665,16 @@ github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727/go.mod h1:r github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 h1:M8mH9eK4OUR4lu7Gd+PU1fV2/qnDNfzT635KRSObncs= github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567/go.mod h1:DWNGW8A4Y+GyBgPuaQJuWiy0XYftx4Xm/y5Jqk9I6VQ= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= -github.com/quic-go/qtls-go1-20 v0.4.1 h1:D33340mCNDAIKBqXuAvexTNMUByrYmFYVfKfDN5nfFs= -github.com/quic-go/quic-go v0.40.1 h1:X3AGzUNFs0jVuO3esAGnTfvdgvL4fq655WaOi1snv1Q= +github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= +github.com/quic-go/quic-go v0.41.0 h1:aD8MmHfgqTURWNJy48IYFg2OnxwHT3JL7ahGs73lb4k= +github.com/quic-go/quic-go v0.41.0/go.mod h1:qCkNjqczPEvgsOnxZ0eCD14lv+B2LHlFAB++CNOh9hA= github.com/quic-go/webtransport-go v0.6.0 h1:CvNsKqc4W2HljHJnoT+rMmbRJybShZ0YPFDD3NxaZLY= +github.com/quic-go/webtransport-go v0.6.0/go.mod h1:9KjU4AEBqEQidGHNDkZrb8CAa1abRaosM2yGOyiikEc= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= +github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= +github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= @@ -737,6 +783,7 @@ github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60Nt github.com/uudashr/gocognit v1.0.7 h1:e9aFXgKgUJrQ5+bs61zBigmj7bFJ/5cC6HmMahVzuDo= github.com/uudashr/gocognit v1.0.7/go.mod h1:nAIUuVBnYU7pcninia3BHOvQkpQCeO76Uscky5BOwcY= github.com/warpfork/go-testmark v0.12.1 h1:rMgCpJfwy1sJ50x0M0NgyphxYYPMOODIJHhsXyEHU0s= +github.com/warpfork/go-testmark v0.12.1/go.mod h1:kHwy7wfvGSPh1rQJYKayD4AbtNaeyZdcGi9tNJTaa5Y= github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0 h1:GDDkbFiaK8jsSDJfjId/PEGEShv6ugrt4kYsC5UIDaQ= github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc h1:BCPnHtcboadS0DvysUuJXZ4lWVv5Bh5i7+tbIyi+ck4= @@ -761,6 +808,7 @@ github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5t gitlab.com/bosi/decorder v0.4.0 h1:HWuxAhSxIvsITcXeP+iIRg9d1cVfvVkmlF7M68GaoDY= gitlab.com/bosi/decorder v0.4.0/go.mod h1:xarnteyUoJiOTEldDysquWKTVDCKo2TOIOIibSuWqOg= go-simpler.org/assert v0.5.0 h1:+5L/lajuQtzmbtEfh69sr5cRf2/xZzyJhFjoOz/PPqs= +go-simpler.org/assert v0.5.0/go.mod h1:74Eqh5eI6vCK6Y5l3PI8ZYFXG4Sa+tkr70OIPJAUr28= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= @@ -780,10 +828,14 @@ go.tmz.dev/musttag v0.7.1/go.mod h1:oJLkpR56EsIryktZJk/B0IroSMi37YWver47fibGh5U= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= +go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= go.uber.org/fx v1.20.1 h1:zVwVQGS8zYvhh9Xxcu4w1M6ESyeMzebzj2NbSayZ4Mk= +go.uber.org/fx v1.20.1/go.mod h1:iSYNbHf2y55acNCwCXKx7LbWb5WG1Bnue5RDXz1OREg= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= -go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= +go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= @@ -791,8 +843,8 @@ go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN8 go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= -go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= -go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= +go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= +go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -804,8 +856,8 @@ golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= -golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc= -golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= +golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= +golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -816,8 +868,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20240119083558-1b970713d09a h1:Q8/wZp0KX97QFTc2ywcOE0YRjZPVIx+MXInMzdvQqcA= -golang.org/x/exp v0.0.0-20240119083558-1b970713d09a/go.mod h1:idGWGoKP1toJGkd5/ig9ZLuPcZBC3ewk7SzmH0uou08= +golang.org/x/exp v0.0.0-20240213143201-ec583247a57a h1:HinSgX1tJRX3KsL//Gxynpw5CTOAIPhgL4W8PNiIpVE= +golang.org/x/exp v0.0.0-20240213143201-ec583247a57a/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc= golang.org/x/exp/typeparams v0.0.0-20220428152302-39d4317da171/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/exp/typeparams v0.0.0-20230203172020-98cc5a0785f9/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/exp/typeparams v0.0.0-20230307190834-24139beb5833 h1:jWGQJV4niP+CCmFW9ekjA9Zx8vYORzOUH2/Nl5WPuLQ= @@ -852,8 +904,8 @@ golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91 golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= -golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8= +golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -897,8 +949,8 @@ golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= -golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= +golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -986,16 +1038,16 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= -golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE= -golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= +golang.org/x/term v0.17.0 h1:mkTF7LCd6WGJNL3K1Ad7kwxNfYAW6a8a8QqtMblp/4U= +golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1086,8 +1138,8 @@ golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= golang.org/x/tools v0.5.0/go.mod h1:N+Kgy78s5I24c24dU8OfWNEotWjutIs8SnJvn5IDq+k= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc= -golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps= +golang.org/x/tools v0.18.0 h1:k8NLag8AGHnn+PHbl7g43CtqZAwG60vZkLqgyZgIHgQ= +golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1192,6 +1244,7 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= From 30ba0d7c6a261331046c1a9ae4714ef29c51bd96 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Tue, 27 Feb 2024 09:50:02 +0100 Subject: [PATCH 1042/1212] ci: bump conformance tests Go to 1.21 (cherry picked from commit dc7a0aba542c9f3e169ce653f3a30e2a07af35b1) --- .github/workflows/gateway-conformance.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gateway-conformance.yml b/.github/workflows/gateway-conformance.yml index 57563cfc2..4a94287ec 100644 --- a/.github/workflows/gateway-conformance.yml +++ b/.github/workflows/gateway-conformance.yml @@ -137,7 +137,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: 1.20.x + go-version: 1.21.x - uses: protocol/cache-go-action@v1 with: name: ${{ github.job }} From a9fc6dd32856d65d706ca7c0be68a7aa77adc0b1 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Tue, 27 Feb 2024 09:57:34 +0100 Subject: [PATCH 1043/1212] ci: upgrade CodeQL to v3 (cherry picked from commit 121cfaec6014037cefc9d68c02dd528704e18a50) --- .github/workflows/codeql-analysis.yml | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 60bc3c409..69beb5e37 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -31,14 +31,19 @@ jobs: - name: Checkout repository uses: actions/checkout@v4 + - name: Setup Go + uses: actions/setup-go@v5 + with: + go-version: 1.21.x + # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v2 + uses: github/codeql-action/init@v3 with: languages: go - name: Autobuild - uses: github/codeql-action/autobuild@v2 + uses: github/codeql-action/autobuild@v3 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + uses: github/codeql-action/analyze@v3 From 810955f86df86601b0830a0c32ffd0a0ae0aa0f7 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Fri, 1 Mar 2024 09:58:10 +0100 Subject: [PATCH 1044/1212] test: cleanup content blocking tests (#10360) (cherry picked from commit a01cc58c8dc4388eaf067e194ef1ee39191f86b5) --- test/cli/content_blocking_test.go | 80 +++++++++++++++++++++++++++---- 1 file changed, 71 insertions(+), 9 deletions(-) diff --git a/test/cli/content_blocking_test.go b/test/cli/content_blocking_test.go index ddb7c951e..6598354d1 100644 --- a/test/cli/content_blocking_test.go +++ b/test/cli/content_blocking_test.go @@ -12,7 +12,9 @@ import ( "strings" "testing" + "github.com/ipfs/go-cid" "github.com/ipfs/kubo/test/cli/harness" + carstore "github.com/ipld/go-car/v2/blockstore" "github.com/libp2p/go-libp2p" "github.com/libp2p/go-libp2p/core/peer" libp2phttp "github.com/libp2p/go-libp2p/p2p/http" @@ -34,8 +36,10 @@ func TestContentBlocking(t *testing.T) { node := h.NewNode().Init("--empty-repo", "--profile=test") // Create CIDs we use in test - h.WriteFile("blocked-dir/subdir/indirectly-blocked-file.txt", "indirectly blocked file content") - parentDirCID := node.IPFS("add", "--raw-leaves", "-Q", "-r", filepath.Join(h.Dir, "blocked-dir")).Stdout.Trimmed() + h.WriteFile("parent-dir/blocked-subdir/indirectly-blocked-file.txt", "indirectly blocked file content") + allowedParentDirCID := node.IPFS("add", "--raw-leaves", "-Q", "-r", "--pin=false", filepath.Join(h.Dir, "parent-dir")).Stdout.Trimmed() + blockedSubDirCID := node.IPFS("add", "--raw-leaves", "-Q", "-r", "--pin=false", filepath.Join(h.Dir, "parent-dir", "blocked-subdir")).Stdout.Trimmed() + node.IPFS("block", "rm", blockedSubDirCID) h.WriteFile("directly-blocked-file.txt", "directly blocked file content") blockedCID := node.IPFS("add", "--raw-leaves", "-Q", filepath.Join(h.Dir, "directly-blocked-file.txt")).Stdout.Trimmed() @@ -50,7 +54,7 @@ func TestContentBlocking(t *testing.T) { "//8526ba05eec55e28f8db5974cc891d0d92c8af69d386fc6464f1e9f372caf549\n" + // Legacy CID double-hash block: sha256(bafkqahtcnrxwg23fmqqgi33vmjwgk2dbonuca3dfm5qwg6jamnuwicq/) "//e5b7d2ce2594e2e09901596d8e1f29fa249b74c8c9e32ea01eda5111e4d33f07\n" + // Legacy Path double-hash block: sha256(bafyaagyscufaqalqaacauaqiaejao43vmjygc5didacauaqiae/subpath) "/ipfs/" + blockedCID + "\n" + // block specific CID - "/ipfs/" + parentDirCID + "/subdir*\n" + // block only specific subpath + "/ipfs/" + allowedParentDirCID + "/blocked-subdir*\n" + // block only specific subpath "/ipns/blocked-cid.example.com\n" + "/ipns/blocked-dnslink.example.com\n") @@ -94,22 +98,63 @@ func TestContentBlocking(t *testing.T) { // Confirm parent of blocked subpath is not blocked t.Run("Gateway Allows parent Path that is not blocked", func(t *testing.T) { t.Parallel() - resp := client.Get("/ipfs/" + parentDirCID) + resp := client.Get("/ipfs/" + allowedParentDirCID) assert.Equal(t, http.StatusOK, resp.StatusCode) }) + // Confirm CAR responses skip blocked subpaths + t.Run("Gateway returns CAR without blocked subpath", func(t *testing.T) { + resp := client.Get("/ipfs/" + allowedParentDirCID + "/subdir?format=car") + assert.Equal(t, http.StatusOK, resp.StatusCode) + + bs, err := carstore.NewReadOnly(strings.NewReader(resp.Body), nil) + assert.NoError(t, err) + + has, err := bs.Has(context.Background(), cid.MustParse(blockedSubDirCID)) + assert.NoError(t, err) + assert.False(t, has) + }) + + /* TODO: this was already broken in 0.26, but we should fix it + t.Run("Gateway returns CAR without directly blocked CID", func(t *testing.T) { + allowedDirWithDirectlyBlockedCID := node.IPFS("add", "--raw-leaves", "-Q", "-rw", filepath.Join(h.Dir, "directly-blocked-file.txt")).Stdout.Trimmed() + resp := client.Get("/ipfs/" + allowedDirWithDirectlyBlockedCID + "?format=car") + assert.Equal(t, http.StatusOK, resp.StatusCode) + + bs, err := carstore.NewReadOnly(strings.NewReader(resp.Body), nil) + assert.NoError(t, err) + + has, err := bs.Has(context.Background(), cid.MustParse(blockedCID)) + assert.NoError(t, err) + assert.False(t, has, "Returned CAR should not include blockedCID") + }) + */ + + // Confirm CAR responses skip blocked subpaths + t.Run("Gateway returns CAR without blocked subpath", func(t *testing.T) { + resp := client.Get("/ipfs/" + allowedParentDirCID + "/subdir?format=car") + assert.Equal(t, http.StatusOK, resp.StatusCode) + + bs, err := carstore.NewReadOnly(strings.NewReader(resp.Body), nil) + assert.NoError(t, err) + + has, err := bs.Has(context.Background(), cid.MustParse(blockedSubDirCID)) + assert.NoError(t, err) + assert.False(t, has, "Returned CAR should not include blockedSubDirCID") + }) + // Ok, now the full list of test cases we want to cover in both CLI and Gateway testCases := []struct { name string path string }{ { - name: "directly blocked CID", + name: "directly blocked file CID", path: "/ipfs/" + blockedCID, }, { name: "indirectly blocked file (on a blocked subpath)", - path: "/ipfs/" + parentDirCID + "/subdir/indirectly-blocked-file.txt", + path: "/ipfs/" + allowedParentDirCID + "/blocked-subdir/indirectly-blocked-file.txt", }, { name: "/ipns path that resolves to a blocked CID", @@ -161,9 +206,14 @@ func TestContentBlocking(t *testing.T) { t.Run(cliTestName, func(t *testing.T) { t.Parallel() args := append(cmd, testCase.path) - errMsg := node.RunIPFS(args...).Stderr.Trimmed() - if !strings.Contains(errMsg, expectedMsg) { - t.Errorf("Expected STDERR error message %q, but got: %q", expectedMsg, errMsg) + cmd := node.RunIPFS(args...) + stdout := cmd.Stdout.Trimmed() + stderr := cmd.Stderr.Trimmed() + if !strings.Contains(stderr, expectedMsg) { + t.Errorf("Expected STDERR error message %q, but got: %q", expectedMsg, stderr) + if stdout != "" { + t.Errorf("Expected STDOUT to be empty, but got: %q", stdout) + } } }) } @@ -299,5 +349,17 @@ func TestContentBlocking(t *testing.T) { assert.NotEqual(t, string(body), "directly blocked file content") assert.Contains(t, string(body), blockedMsg, bodyExpl) }) + + t.Run("Denies Blocked CID as CAR", func(t *testing.T) { + t.Parallel() + resp, err := libp2pClient.Get(fmt.Sprintf("/ipfs/%s?format=car", blockedCID)) + require.NoError(t, err) + defer resp.Body.Close() + assert.Equal(t, http.StatusGone, resp.StatusCode, statusExpl) + body, err := io.ReadAll(resp.Body) + require.NoError(t, err) + assert.NotContains(t, string(body), "directly blocked file content") + assert.Contains(t, string(body), blockedMsg, bodyExpl) + }) }) } From 4bc1939892fa589b3b7696f20a14f3079eec2721 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Fri, 1 Mar 2024 09:12:03 +0000 Subject: [PATCH 1045/1212] chore: update version --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index 811e491d1..eaa8ce1f2 100644 --- a/version.go +++ b/version.go @@ -11,7 +11,7 @@ import ( var CurrentCommit string // CurrentVersionNumber is the current application's version literal. -const CurrentVersionNumber = "0.27.0-rc1" +const CurrentVersionNumber = "0.27.0-rc2" const ApiVersion = "/kubo/" + CurrentVersionNumber + "/" //nolint From d44d7afa6240bbaa04283a01bbd0c25e68e8709e Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Mon, 4 Mar 2024 10:02:22 +0000 Subject: [PATCH 1046/1212] chore: update version --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index eaa8ce1f2..3c6d89428 100644 --- a/version.go +++ b/version.go @@ -11,7 +11,7 @@ import ( var CurrentCommit string // CurrentVersionNumber is the current application's version literal. -const CurrentVersionNumber = "0.27.0-rc2" +const CurrentVersionNumber = "0.27.0" const ApiVersion = "/kubo/" + CurrentVersionNumber + "/" //nolint From 10e6a20f73c1effaa9894a03537d5f01cea5d9ee Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Mon, 4 Mar 2024 10:10:56 +0000 Subject: [PATCH 1047/1212] chore: update changelog for v0.27 --- docs/changelogs/v0.27.md | 97 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) diff --git a/docs/changelogs/v0.27.md b/docs/changelogs/v0.27.md index 0f9808a15..e5bd895ca 100644 --- a/docs/changelogs/v0.27.md +++ b/docs/changelogs/v0.27.md @@ -44,4 +44,101 @@ Kubo now only uses [trustless requests](https://specs.ipfs.tech/http-gateways/tr ### 📝 Changelog +
Full Changelog + +- github.com/ipfs/kubo: + - chore: update version + - chore: update version + - test: cleanup content blocking tests (#10360) ([ipfs/kubo#10360](https://github.com/ipfs/kubo/pull/10360)) + - docs: improve release issue template + - chore: update version + - repo/fsrepo/migrations: verified HTTP migrations (#10324) ([ipfs/kubo#10324](https://github.com/ipfs/kubo/pull/10324)) + - chore: fix link + - docs: clarify Gateway.ExposeRoutingAPI (#10337) ([ipfs/kubo#10337](https://github.com/ipfs/kubo/pull/10337)) + - commands/add: return an error when using --only-hash and --to-files + - docs(config): mention routing v1 spec + - core/commands: remove 'ipfs dht' commands, except 'query' (#10328) ([ipfs/kubo#10328](https://github.com/ipfs/kubo/pull/10328)) + - core: deprecate CoreAPI.Dht, introduce CoreAPI.Routing + - refactor: superfluous namespace test redirects (#10322) ([ipfs/kubo#10322](https://github.com/ipfs/kubo/pull/10322)) + - feat: add Ipns.MaxCacheTTL + - fix(gw): negative entity-bytes beyond file size (#10320) ([ipfs/kubo#10320](https://github.com/ipfs/kubo/pull/10320)) + - core/corehttp: wrap gateway with headers, deprecate gateway /api/v0 + - docs: add changelog link to release issue template + - docs: remove whizzzkid + - chore: create next changelog + - Merge Release: v0.26.0 [skip changelog] ([ipfs/kubo#10313](https://github.com/ipfs/kubo/pull/10313)) + - config: remove all options that are marked as REMOVED + - chore: remove Gateway.APICommands + - docs(cli): name inspect --verify (#10308) ([ipfs/kubo#10308](https://github.com/ipfs/kubo/pull/10308)) + - docs: improve release issue template (#10305) ([ipfs/kubo#10305](https://github.com/ipfs/kubo/pull/10305)) + - core/corehttp: wrap hostname option with otelhttp + - fix: profiling tests + - profile: add trace + - docs(config): clarify ReproviderStrategy roots + - chore: update version + - docs: in RELEASE_ISSUE_TEMPLATE ask releaser to ensure we are using the latest go release on the major branch +- github.com/ipfs/boxo (v0.17.0 -> v0.18.0): + - Release v0.18.0 ([ipfs/boxo#581](https://github.com/ipfs/boxo/pull/581)) +- github.com/libp2p/go-libp2p (v0.32.2 -> v0.33.0): + - release v0.33.0 (#2715) ([libp2p/go-libp2p#2715](https://github.com/libp2p/go-libp2p/pull/2715)) + - chore: update deps for v0.33 (#2713) ([libp2p/go-libp2p#2713](https://github.com/libp2p/go-libp2p/pull/2713)) + - webrtc: wait for FIN_ACK before closing data channels (#2615) ([libp2p/go-libp2p#2615](https://github.com/libp2p/go-libp2p/pull/2615)) + - quic: upgrade quic-go to v0.41.0 (#2710) ([libp2p/go-libp2p#2710](https://github.com/libp2p/go-libp2p/pull/2710)) + - chore: remove unused GenerateEKeyPair function (#2711) ([libp2p/go-libp2p#2711](https://github.com/libp2p/go-libp2p/pull/2711)) + - chore: drop support for go1.20 (#2708) ([libp2p/go-libp2p#2708](https://github.com/libp2p/go-libp2p/pull/2708)) + - chore: testify fix got, expected transpositions (#2666) ([libp2p/go-libp2p#2666](https://github.com/libp2p/go-libp2p/pull/2666)) + - docs: fix broken link in README + - chore: fix typos (#2694) ([libp2p/go-libp2p#2694](https://github.com/libp2p/go-libp2p/pull/2694)) + - libp2phttp: fix flaky ExampleHost_listenOnHTTPTransportAndStreams (#2697) ([libp2p/go-libp2p#2697](https://github.com/libp2p/go-libp2p/pull/2697)) + - chore(p2p/host): fix typos (#2683) ([libp2p/go-libp2p#2683](https://github.com/libp2p/go-libp2p/pull/2683)) + - chore: fix typos (#2689) ([libp2p/go-libp2p#2689](https://github.com/libp2p/go-libp2p/pull/2689)) + - defaults: do TLS by default for encryption (#2650) ([libp2p/go-libp2p#2650](https://github.com/libp2p/go-libp2p/pull/2650)) + - webrtc: fix flaky TestMaxInFlightRequests (#2682) ([libp2p/go-libp2p#2682](https://github.com/libp2p/go-libp2p/pull/2682)) + - chore: remove unnecessary conversions (#2680) ([libp2p/go-libp2p#2680](https://github.com/libp2p/go-libp2p/pull/2680)) + - chore: update chat-with-mdns example readme (#2678) ([libp2p/go-libp2p#2678](https://github.com/libp2p/go-libp2p/pull/2678)) + - examples: call NewStream from only one side (#2677) ([libp2p/go-libp2p#2677](https://github.com/libp2p/go-libp2p/pull/2677)) + - chore: fix typos in comment (#2674) ([libp2p/go-libp2p#2674](https://github.com/libp2p/go-libp2p/pull/2674)) + - chore: update go-libp2p-asn-util (#2673) ([libp2p/go-libp2p#2673](https://github.com/libp2p/go-libp2p/pull/2673)) + - chore: update go security policy url (#2665) ([libp2p/go-libp2p#2665](https://github.com/libp2p/go-libp2p/pull/2665)) + - security: remove separate licenses for Noise and TLS (#2663) ([libp2p/go-libp2p#2663](https://github.com/libp2p/go-libp2p/pull/2663)) + - webrtc: clarify that there is no reuseport functionality (#2652) ([libp2p/go-libp2p#2652](https://github.com/libp2p/go-libp2p/pull/2652)) + - rcmgr: fix connmgr connection limit conflict warning (#2648) ([libp2p/go-libp2p#2648](https://github.com/libp2p/go-libp2p/pull/2648)) + - tcp: fix build on loong64 (#2655) ([libp2p/go-libp2p#2655](https://github.com/libp2p/go-libp2p/pull/2655)) + - swarm: fix grafana dashboard templating (#2640) ([libp2p/go-libp2p#2640](https://github.com/libp2p/go-libp2p/pull/2640)) + - chore: fix typos (#2608) ([libp2p/go-libp2p#2608](https://github.com/libp2p/go-libp2p/pull/2608)) + - chore: add resource manager dashboard to docker-compose (#2641) ([libp2p/go-libp2p#2641](https://github.com/libp2p/go-libp2p/pull/2641)) + - pstoremanager: fix race condition when removing peers from peer store (#2644) ([libp2p/go-libp2p#2644](https://github.com/libp2p/go-libp2p/pull/2644)) + - examples: remove unused 'SetStreamHandler' (#2598) ([libp2p/go-libp2p#2598](https://github.com/libp2p/go-libp2p/pull/2598)) + - Update docs from RSA to Ed25519 (#2606) ([libp2p/go-libp2p#2606](https://github.com/libp2p/go-libp2p/pull/2606)) +- github.com/multiformats/go-multiaddr (v0.12.1 -> v0.12.2): + - chore: release v0.12.2 + - tests: add round trip equality check to fuzz (#232) ([multiformats/go-multiaddr#232](https://github.com/multiformats/go-multiaddr/pull/232)) + - fix: correctly parse ports as uint16 and explicitely fail on overflows (#228) ([multiformats/go-multiaddr#228](https://github.com/multiformats/go-multiaddr/pull/228)) + - replace custom random tests with testing.F (#227) ([multiformats/go-multiaddr#227](https://github.com/multiformats/go-multiaddr/pull/227)) + +
+ ### 👨‍👩‍👧‍👦 Contributors + +| Contributor | Commits | Lines ± | Files Changed | +|-------------|---------|---------|---------------| +| Henrique Dias | 26 | +1668/-1484 | 96 | +| Sukun | 13 | +983/-618 | 68 | +| Jorropo | 18 | +501/-222 | 32 | +| Marten Seemann | 2 | +17/-244 | 5 | +| dozyio | 1 | +117/-132 | 31 | +| Marcin Rataj | 7 | +100/-20 | 8 | +| Alexandr Burdiyan | 2 | +29/-54 | 2 | +| Tyler | 1 | +17/-19 | 2 | +| KeienWang | 2 | +14/-14 | 12 | +| Håvard Anda Estensen | 1 | +14/-14 | 11 | +| Halimao | 2 | +17/-4 | 2 | +| hannahhoward | 1 | +14/-6 | 2 | +| alex | 1 | +8/-8 | 4 | +| shuoer86 | 1 | +7/-7 | 5 | +| John Chase | 1 | +0/-12 | 1 | +| GoodDaisy | 1 | +5/-5 | 4 | +| Michael Muré | 1 | +6/-2 | 1 | +| 吴小白 | 1 | +3/-3 | 3 | +| Vehorny | 1 | +3/-3 | 2 | +| Eric | 1 | +1/-1 | 1 | From ef406669efd18ffe884a7d25751d0409c21918b3 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Mon, 4 Mar 2024 12:01:14 +0000 Subject: [PATCH 1048/1212] chore: create next changelog --- CHANGELOG.md | 1 + docs/changelogs/v0.28.md | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 docs/changelogs/v0.28.md diff --git a/CHANGELOG.md b/CHANGELOG.md index bfcf27bed..cd0dc69b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ # Kubo Changelogs +- [v0.28](docs/changelogs/v0.28.md) - [v0.27](docs/changelogs/v0.27.md) - [v0.26](docs/changelogs/v0.26.md) - [v0.25](docs/changelogs/v0.25.md) diff --git a/docs/changelogs/v0.28.md b/docs/changelogs/v0.28.md new file mode 100644 index 000000000..a811e81aa --- /dev/null +++ b/docs/changelogs/v0.28.md @@ -0,0 +1,18 @@ +# Kubo changelog v0.28 + +- [v0.28.0](#v0280) + +## v0.28.0 + +- [Overview](#overview) +- [🔦 Highlights](#-highlights) +- [📝 Changelog](#-changelog) +- [👨‍👩‍👧‍👦 Contributors](#-contributors) + +### Overview + +### 🔦 Highlights + +### 📝 Changelog + +### 👨‍👩‍👧‍👦 Contributors From 2b7a39074b1b31452a53d8c51ece96e3b78e799b Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Mon, 4 Mar 2024 13:07:47 +0100 Subject: [PATCH 1049/1212] chore: update dependencies --- docs/examples/kubo-as-a-library/go.mod | 20 ++++++------ docs/examples/kubo-as-a-library/go.sum | 41 ++++++++++++----------- go.mod | 22 ++++++------- go.sum | 45 +++++++++++++------------- test/dependencies/go.mod | 18 +++++------ test/dependencies/go.sum | 36 ++++++++++----------- 6 files changed, 90 insertions(+), 92 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 263925581..03f685e7c 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -54,7 +54,7 @@ require ( github.com/golang/snappy v0.0.4 // indirect github.com/google/gopacket v1.1.19 // indirect github.com/google/pprof v0.0.0-20240207164012-fb44976bdcd5 // indirect - github.com/google/uuid v1.5.0 // indirect + github.com/google/uuid v1.6.0 // indirect github.com/gorilla/websocket v1.5.1 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect @@ -103,7 +103,7 @@ require ( github.com/libp2p/go-doh-resolver v0.4.0 // indirect github.com/libp2p/go-flow-metrics v0.1.0 // indirect github.com/libp2p/go-libp2p-asn-util v0.4.1 // indirect - github.com/libp2p/go-libp2p-kad-dht v0.24.4 // indirect + github.com/libp2p/go-libp2p-kad-dht v0.25.2 // indirect github.com/libp2p/go-libp2p-kbucket v0.6.3 // indirect github.com/libp2p/go-libp2p-pubsub v0.10.0 // indirect github.com/libp2p/go-libp2p-pubsub-router v0.6.0 // indirect @@ -158,9 +158,9 @@ require ( github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/polydawn/refmt v0.89.0 // indirect - github.com/prometheus/client_golang v1.18.0 // indirect + github.com/prometheus/client_golang v1.19.0 // indirect github.com/prometheus/client_model v0.6.0 // indirect - github.com/prometheus/common v0.47.0 // indirect + github.com/prometheus/common v0.49.0 // indirect github.com/prometheus/procfs v0.12.0 // indirect github.com/quic-go/qpack v0.4.0 // indirect github.com/quic-go/quic-go v0.41.0 // indirect @@ -173,20 +173,20 @@ require ( github.com/ucarion/urlpath v0.0.0-20200424170820-7ccc79b76bbb // indirect github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc // indirect github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11 // indirect - github.com/whyrusleeping/cbor-gen v0.0.0-20240109153615-66e95c3e8a87 // indirect + github.com/whyrusleeping/cbor-gen v0.1.0 // indirect github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f // indirect github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 // indirect go.opencensus.io v0.24.0 // indirect - go.opentelemetry.io/otel v1.22.0 // indirect + go.opentelemetry.io/otel v1.24.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0 // indirect go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.21.0 // indirect go.opentelemetry.io/otel/exporters/zipkin v1.21.0 // indirect - go.opentelemetry.io/otel/metric v1.22.0 // indirect + go.opentelemetry.io/otel/metric v1.24.0 // indirect go.opentelemetry.io/otel/sdk v1.21.0 // indirect - go.opentelemetry.io/otel/trace v1.22.0 // indirect + go.opentelemetry.io/otel/trace v1.24.0 // indirect go.opentelemetry.io/proto/otlp v1.0.0 // indirect go.uber.org/dig v1.17.1 // indirect go.uber.org/fx v1.20.1 // indirect @@ -194,8 +194,8 @@ require ( go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect go4.org v0.0.0-20230225012048-214862532bf5 // indirect - golang.org/x/crypto v0.19.0 // indirect - golang.org/x/exp v0.0.0-20240213143201-ec583247a57a // indirect + golang.org/x/crypto v0.20.0 // indirect + golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 // indirect golang.org/x/mod v0.15.0 // indirect golang.org/x/net v0.21.0 // indirect golang.org/x/sync v0.6.0 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 7238b76c1..45c82eb47 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -224,8 +224,8 @@ github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm4 github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU= -github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= @@ -278,7 +278,6 @@ github.com/ipfs/go-blockservice v0.5.0/go.mod h1:W6brZ5k20AehbmERplmERn8o2Ni3ZZu github.com/ipfs/go-cid v0.0.3/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.4/go.mod h1:4LLaPOQwmk5z9LBgQnpkivrx8BJjUyGwTXCd5Xfj6+M= github.com/ipfs/go-cid v0.0.5/go.mod h1:plgt+Y5MnOey4vO4UlUazGqdbEXuFYitED67FexhXog= -github.com/ipfs/go-cid v0.0.6/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I= github.com/ipfs/go-cid v0.0.7/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I= github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= github.com/ipfs/go-cid v0.4.1/go.mod h1:uQHwDeX4c6CtyrFwdqyhpNcxVewur1M7l7fNU7LKwZk= @@ -429,8 +428,8 @@ github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl9 github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= github.com/libp2p/go-libp2p-core v0.3.0/go.mod h1:ACp3DmS3/N64c2jDzcV429ukDpicbL6+TrrxANBjPGw= -github.com/libp2p/go-libp2p-kad-dht v0.24.4 h1:ktNiJe7ffsJ1wX3ULpMCwXts99mPqGFSE/Qn1i8pErQ= -github.com/libp2p/go-libp2p-kad-dht v0.24.4/go.mod h1:ybWBJ5Fbvz9sSLkNtXt+2+bK0JB8+tRPvhBbRGHegRU= +github.com/libp2p/go-libp2p-kad-dht v0.25.2 h1:FOIk9gHoe4YRWXTu8SY9Z1d0RILol0TrtApsMDPjAVQ= +github.com/libp2p/go-libp2p-kad-dht v0.25.2/go.mod h1:6za56ncRHYXX4Nc2vn8z7CZK0P4QiMcrn77acKLM2Oo= github.com/libp2p/go-libp2p-kbucket v0.3.1/go.mod h1:oyjT5O7tS9CQurok++ERgc46YLwEpuGoFq9ubvoUOio= github.com/libp2p/go-libp2p-kbucket v0.6.3 h1:p507271wWzpy2f1XxPzCQG9NiN6R6lHL9GiSErbQQo0= github.com/libp2p/go-libp2p-kbucket v0.6.3/go.mod h1:RCseT7AH6eJWxxk2ol03xtP9pEHetYSPXOaJnOiD8i0= @@ -637,15 +636,15 @@ github.com/polydawn/refmt v0.0.0-20201211092308-30ac6d18308e/go.mod h1:uIp+gprXx github.com/polydawn/refmt v0.89.0 h1:ADJTApkvkeBZsN0tBTx8QjpD9JkmxbKp0cxfr9qszm4= github.com/polydawn/refmt v0.89.0/go.mod h1:/zvteZs/GwLtCgZ4BL6CBsk9IKIlexP43ObX9AxTqTw= github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v1.18.0 h1:HzFfmkOzH5Q8L8G+kSJKUx5dtG87sewO+FoDDqP5Tbk= -github.com/prometheus/client_golang v1.18.0/go.mod h1:T+GXkCk5wSJyOqMIzVgvvjFDlkOQntgjkJWKrN5txjA= +github.com/prometheus/client_golang v1.19.0 h1:ygXvpU1AoN1MhdzckN+PyD9QJOSD4x7kmXYlnfbA6JU= +github.com/prometheus/client_golang v1.19.0/go.mod h1:ZRM9uEAypZakd+q/x7+gmsvXdURP+DABIEIjnmDdp+k= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.6.0 h1:k1v3CzpSRUTrKMppY35TLwPvxHqBu0bYgxZzqGIgaos= github.com/prometheus/client_model v0.6.0/go.mod h1:NTQHnmxFpouOD0DpvP4XujX3CdOAGQPoaGhyTchlyt8= github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.47.0 h1:p5Cz0FNHo7SnWOmWmoRozVcjEp0bIVU8cV7OShpjL1k= -github.com/prometheus/common v0.47.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc= +github.com/prometheus/common v0.49.0 h1:ToNTdK4zSnPVJmh698mGFkDor9wBI/iGaJy5dbH1EgI= +github.com/prometheus/common v0.49.0/go.mod h1:Kxm+EULxRbUkjGU6WFsQqo3ORzB4tyKvlWFOE9mB2sE= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= @@ -757,8 +756,8 @@ github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc h1:BCPnHtcboa github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc/go.mod h1:r45hJU7yEoA81k6MWNhpMj/kms0n14dkzkxYHoB96UM= github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11 h1:5HZfQkwe0mIfyDmc1Em5GqlNRzcdtlv4HTNmdpt7XH0= github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11/go.mod h1:Wlo/SzPmxVp6vXpGt/zaXhHH0fn4IxgqZc82aKg6bpQ= -github.com/whyrusleeping/cbor-gen v0.0.0-20240109153615-66e95c3e8a87 h1:S4wCk+ZL4WGGaI+GsmqCRyt68ISbnZWsK9dD9jYL0fA= -github.com/whyrusleeping/cbor-gen v0.0.0-20240109153615-66e95c3e8a87/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= +github.com/whyrusleeping/cbor-gen v0.1.0 h1:Jneeq3V5enErVcuL0NKEbD1Gi+iOvEeFhXOV1S1Fc6g= +github.com/whyrusleeping/cbor-gen v0.1.0/go.mod h1:pM99HXyEbSQHcosHc0iW7YFmwnscr+t9Te4ibko05so= github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f h1:jQa4QT2UP9WYv2nzyawpKMOCl+Z/jW7djv2/J50lj9E= github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f/go.mod h1:p9UJB6dDgdPgMJZs7UjUOdulKyRr9fqkS+6JKAInPy8= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 h1:EKhdznlJHPMoKr0XTrX+IlJs1LH3lyx2nfr1dOlZ79k= @@ -780,8 +779,8 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/otel v1.22.0 h1:xS7Ku+7yTFvDfDraDIJVpw7XPyuHlB9MCiqqX5mcJ6Y= -go.opentelemetry.io/otel v1.22.0/go.mod h1:eoV4iAi3Ea8LkAEI9+GFT44O6T/D0GWAVFyZVCC6pMI= +go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo= +go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 h1:cl5P5/GIfFh4t6xyruOgJP5QiA1pw4fYYdv6nc6CBWw= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0/go.mod h1:zgBdWWAu7oEEMC06MMKc5NLbA/1YDXV1sMpSqEeLQLg= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0 h1:tIqheXEFWAZ7O8A7m+J0aPTmpJN3YQ7qetUAdkkkKpk= @@ -792,12 +791,12 @@ go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.21.0 h1:VhlEQAPp9R1ktYf go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.21.0/go.mod h1:kB3ufRbfU+CQ4MlUcqtW8Z7YEOBeK2DJ6CmR5rYYF3E= go.opentelemetry.io/otel/exporters/zipkin v1.21.0 h1:D+Gv6lSfrFBWmQYyxKjDd0Zuld9SRXpIrEsKZvE4DO4= go.opentelemetry.io/otel/exporters/zipkin v1.21.0/go.mod h1:83oMKR6DzmHisFOW3I+yIMGZUTjxiWaiBI8M8+TU5zE= -go.opentelemetry.io/otel/metric v1.22.0 h1:lypMQnGyJYeuYPhOM/bgjbFM6WE44W1/T45er4d8Hhg= -go.opentelemetry.io/otel/metric v1.22.0/go.mod h1:evJGjVpZv0mQ5QBRJoBF64yMuOf4xCWdXjK8pzFvliY= +go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI= +go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco= go.opentelemetry.io/otel/sdk v1.21.0 h1:FTt8qirL1EysG6sTQRZ5TokkU8d0ugCj8htOgThZXQ8= go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E= -go.opentelemetry.io/otel/trace v1.22.0 h1:Hg6pPujv0XG9QaVbGOBVHunyuLcCC3jN7WEhPx83XD0= -go.opentelemetry.io/otel/trace v1.22.0/go.mod h1:RbbHXVqKES9QhzZq/fE5UnOSILqRt40a21sPw2He1xo= +go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI= +go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU= go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I= go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= @@ -852,8 +851,8 @@ golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45 golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= -golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= -golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/crypto v0.20.0 h1:jmAMJJZXr5KiCw05dfYK9QnqaqKLYXijU23lsEdcQqg= +golang.org/x/crypto v0.20.0/go.mod h1:Xwo95rrVNIoSMx9wa1JroENMToLWn3RNVrTBpLHgZPQ= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -862,8 +861,8 @@ golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20240213143201-ec583247a57a h1:HinSgX1tJRX3KsL//Gxynpw5CTOAIPhgL4W8PNiIpVE= -golang.org/x/exp v0.0.0-20240213143201-ec583247a57a/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc= +golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 h1:LfspQV/FYTatPTr/3HzIcmiUFH7PGP+OQ6mgDYo3yuQ= +golang.org/x/exp v0.0.0-20240222234643-814bf88cf225/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= diff --git a/go.mod b/go.mod index fae6f2f96..ca77d8b16 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( github.com/elgris/jsondiff v0.0.0-20160530203242-765b5c24c302 github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5 github.com/fsnotify/fsnotify v1.6.0 - github.com/google/uuid v1.5.0 + github.com/google/uuid v1.6.0 github.com/hashicorp/go-multierror v1.1.1 github.com/ipfs-shipyard/nopfs v0.0.12 github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c @@ -49,7 +49,7 @@ require ( github.com/libp2p/go-doh-resolver v0.4.0 github.com/libp2p/go-libp2p v0.33.0 github.com/libp2p/go-libp2p-http v0.5.0 - github.com/libp2p/go-libp2p-kad-dht v0.24.4 + github.com/libp2p/go-libp2p-kad-dht v0.25.2 github.com/libp2p/go-libp2p-kbucket v0.6.3 github.com/libp2p/go-libp2p-pubsub v0.10.0 github.com/libp2p/go-libp2p-pubsub-router v0.6.0 @@ -66,7 +66,7 @@ require ( github.com/opentracing/opentracing-go v1.2.0 github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 github.com/pkg/errors v0.9.1 - github.com/prometheus/client_golang v1.18.0 + github.com/prometheus/client_golang v1.19.0 github.com/stretchr/testify v1.8.4 github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 github.com/tidwall/gjson v1.14.4 @@ -76,15 +76,15 @@ require ( go.opencensus.io v0.24.0 go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 go.opentelemetry.io/contrib/propagators/autoprop v0.46.1 - go.opentelemetry.io/otel v1.22.0 + go.opentelemetry.io/otel v1.24.0 go.opentelemetry.io/otel/sdk v1.21.0 - go.opentelemetry.io/otel/trace v1.22.0 + go.opentelemetry.io/otel/trace v1.24.0 go.uber.org/dig v1.17.1 go.uber.org/fx v1.20.1 go.uber.org/multierr v1.11.0 go.uber.org/zap v1.27.0 - golang.org/x/crypto v0.19.0 - golang.org/x/exp v0.0.0-20240213143201-ec583247a57a + golang.org/x/crypto v0.20.0 + golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 golang.org/x/mod v0.15.0 golang.org/x/sync v0.6.0 golang.org/x/sys v0.17.0 @@ -200,7 +200,7 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect github.com/polydawn/refmt v0.89.0 // indirect github.com/prometheus/client_model v0.6.0 // indirect - github.com/prometheus/common v0.47.0 // indirect + github.com/prometheus/common v0.49.0 // indirect github.com/prometheus/procfs v0.12.0 // indirect github.com/prometheus/statsd_exporter v0.22.7 // indirect github.com/quic-go/qpack v0.4.0 // indirect @@ -216,7 +216,7 @@ require ( github.com/ucarion/urlpath v0.0.0-20200424170820-7ccc79b76bbb // indirect github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc // indirect github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11 // indirect - github.com/whyrusleeping/cbor-gen v0.0.0-20240109153615-66e95c3e8a87 // indirect + github.com/whyrusleeping/cbor-gen v0.1.0 // indirect github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f // indirect github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect go.opentelemetry.io/contrib/propagators/aws v1.21.1 // indirect @@ -228,13 +228,13 @@ require ( go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0 // indirect go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.21.0 // indirect go.opentelemetry.io/otel/exporters/zipkin v1.21.0 // indirect - go.opentelemetry.io/otel/metric v1.22.0 // indirect + go.opentelemetry.io/otel/metric v1.24.0 // indirect go.opentelemetry.io/proto/otlp v1.0.0 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/mock v0.4.0 // indirect go4.org v0.0.0-20230225012048-214862532bf5 // indirect golang.org/x/net v0.21.0 // indirect - golang.org/x/oauth2 v0.16.0 // indirect + golang.org/x/oauth2 v0.17.0 // indirect golang.org/x/term v0.17.0 // indirect golang.org/x/text v0.14.0 // indirect golang.org/x/tools v0.18.0 // indirect diff --git a/go.sum b/go.sum index 004c01809..18ab786a5 100644 --- a/go.sum +++ b/go.sum @@ -287,8 +287,8 @@ github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm4 github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU= -github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= @@ -345,7 +345,6 @@ github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUP github.com/ipfs/go-cid v0.0.3/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.4/go.mod h1:4LLaPOQwmk5z9LBgQnpkivrx8BJjUyGwTXCd5Xfj6+M= github.com/ipfs/go-cid v0.0.5/go.mod h1:plgt+Y5MnOey4vO4UlUazGqdbEXuFYitED67FexhXog= -github.com/ipfs/go-cid v0.0.6/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I= github.com/ipfs/go-cid v0.0.7/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I= github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= github.com/ipfs/go-cid v0.4.1/go.mod h1:uQHwDeX4c6CtyrFwdqyhpNcxVewur1M7l7fNU7LKwZk= @@ -519,8 +518,8 @@ github.com/libp2p/go-libp2p-gostream v0.6.0 h1:QfAiWeQRce6pqnYfmIVWJFXNdDyfiR/qk github.com/libp2p/go-libp2p-gostream v0.6.0/go.mod h1:Nywu0gYZwfj7Jc91PQvbGU8dIpqbQQkjWgDuOrFaRdA= github.com/libp2p/go-libp2p-http v0.5.0 h1:+x0AbLaUuLBArHubbbNRTsgWz0RjNTy6DJLOxQ3/QBc= github.com/libp2p/go-libp2p-http v0.5.0/go.mod h1:glh87nZ35XCQyFsdzZps6+F4HYI6DctVFY5u1fehwSg= -github.com/libp2p/go-libp2p-kad-dht v0.24.4 h1:ktNiJe7ffsJ1wX3ULpMCwXts99mPqGFSE/Qn1i8pErQ= -github.com/libp2p/go-libp2p-kad-dht v0.24.4/go.mod h1:ybWBJ5Fbvz9sSLkNtXt+2+bK0JB8+tRPvhBbRGHegRU= +github.com/libp2p/go-libp2p-kad-dht v0.25.2 h1:FOIk9gHoe4YRWXTu8SY9Z1d0RILol0TrtApsMDPjAVQ= +github.com/libp2p/go-libp2p-kad-dht v0.25.2/go.mod h1:6za56ncRHYXX4Nc2vn8z7CZK0P4QiMcrn77acKLM2Oo= github.com/libp2p/go-libp2p-kbucket v0.3.1/go.mod h1:oyjT5O7tS9CQurok++ERgc46YLwEpuGoFq9ubvoUOio= github.com/libp2p/go-libp2p-kbucket v0.6.3 h1:p507271wWzpy2f1XxPzCQG9NiN6R6lHL9GiSErbQQo0= github.com/libp2p/go-libp2p-kbucket v0.6.3/go.mod h1:RCseT7AH6eJWxxk2ol03xtP9pEHetYSPXOaJnOiD8i0= @@ -753,8 +752,8 @@ github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqr github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_golang v1.12.2/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_golang v1.13.0/go.mod h1:vTeo+zgvILHsnnj/39Ou/1fPN5nJFOEMgftOUOmlvYQ= -github.com/prometheus/client_golang v1.18.0 h1:HzFfmkOzH5Q8L8G+kSJKUx5dtG87sewO+FoDDqP5Tbk= -github.com/prometheus/client_golang v1.18.0/go.mod h1:T+GXkCk5wSJyOqMIzVgvvjFDlkOQntgjkJWKrN5txjA= +github.com/prometheus/client_golang v1.19.0 h1:ygXvpU1AoN1MhdzckN+PyD9QJOSD4x7kmXYlnfbA6JU= +github.com/prometheus/client_golang v1.19.0/go.mod h1:ZRM9uEAypZakd+q/x7+gmsvXdURP+DABIEIjnmDdp+k= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -769,8 +768,8 @@ github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9 github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/common v0.35.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= -github.com/prometheus/common v0.47.0 h1:p5Cz0FNHo7SnWOmWmoRozVcjEp0bIVU8cV7OShpjL1k= -github.com/prometheus/common v0.47.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc= +github.com/prometheus/common v0.49.0 h1:ToNTdK4zSnPVJmh698mGFkDor9wBI/iGaJy5dbH1EgI= +github.com/prometheus/common v0.49.0/go.mod h1:Kxm+EULxRbUkjGU6WFsQqo3ORzB4tyKvlWFOE9mB2sE= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= @@ -907,8 +906,8 @@ github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc h1:BCPnHtcboa github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc/go.mod h1:r45hJU7yEoA81k6MWNhpMj/kms0n14dkzkxYHoB96UM= github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11 h1:5HZfQkwe0mIfyDmc1Em5GqlNRzcdtlv4HTNmdpt7XH0= github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11/go.mod h1:Wlo/SzPmxVp6vXpGt/zaXhHH0fn4IxgqZc82aKg6bpQ= -github.com/whyrusleeping/cbor-gen v0.0.0-20240109153615-66e95c3e8a87 h1:S4wCk+ZL4WGGaI+GsmqCRyt68ISbnZWsK9dD9jYL0fA= -github.com/whyrusleeping/cbor-gen v0.0.0-20240109153615-66e95c3e8a87/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= +github.com/whyrusleeping/cbor-gen v0.1.0 h1:Jneeq3V5enErVcuL0NKEbD1Gi+iOvEeFhXOV1S1Fc6g= +github.com/whyrusleeping/cbor-gen v0.1.0/go.mod h1:pM99HXyEbSQHcosHc0iW7YFmwnscr+t9Te4ibko05so= github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f h1:jQa4QT2UP9WYv2nzyawpKMOCl+Z/jW7djv2/J50lj9E= github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f/go.mod h1:p9UJB6dDgdPgMJZs7UjUOdulKyRr9fqkS+6JKAInPy8= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 h1:EKhdznlJHPMoKr0XTrX+IlJs1LH3lyx2nfr1dOlZ79k= @@ -948,8 +947,8 @@ go.opentelemetry.io/contrib/propagators/jaeger v1.21.1 h1:f4beMGDKiVzg9IcX7/VuWV go.opentelemetry.io/contrib/propagators/jaeger v1.21.1/go.mod h1:U9jhkEl8d1LL+QXY7q3kneJWJugiN3kZJV2OWz3hkBY= go.opentelemetry.io/contrib/propagators/ot v1.21.1 h1:3TN5vkXjKYWp0YdMcnUEC/A+pBPvqz9V3nCS2xmcurk= go.opentelemetry.io/contrib/propagators/ot v1.21.1/go.mod h1:oy0MYCbS/b3cqUDW37wBWtlwBIsutngS++Lklpgh+fc= -go.opentelemetry.io/otel v1.22.0 h1:xS7Ku+7yTFvDfDraDIJVpw7XPyuHlB9MCiqqX5mcJ6Y= -go.opentelemetry.io/otel v1.22.0/go.mod h1:eoV4iAi3Ea8LkAEI9+GFT44O6T/D0GWAVFyZVCC6pMI= +go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo= +go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 h1:cl5P5/GIfFh4t6xyruOgJP5QiA1pw4fYYdv6nc6CBWw= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0/go.mod h1:zgBdWWAu7oEEMC06MMKc5NLbA/1YDXV1sMpSqEeLQLg= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0 h1:tIqheXEFWAZ7O8A7m+J0aPTmpJN3YQ7qetUAdkkkKpk= @@ -960,12 +959,12 @@ go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.21.0 h1:VhlEQAPp9R1ktYf go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.21.0/go.mod h1:kB3ufRbfU+CQ4MlUcqtW8Z7YEOBeK2DJ6CmR5rYYF3E= go.opentelemetry.io/otel/exporters/zipkin v1.21.0 h1:D+Gv6lSfrFBWmQYyxKjDd0Zuld9SRXpIrEsKZvE4DO4= go.opentelemetry.io/otel/exporters/zipkin v1.21.0/go.mod h1:83oMKR6DzmHisFOW3I+yIMGZUTjxiWaiBI8M8+TU5zE= -go.opentelemetry.io/otel/metric v1.22.0 h1:lypMQnGyJYeuYPhOM/bgjbFM6WE44W1/T45er4d8Hhg= -go.opentelemetry.io/otel/metric v1.22.0/go.mod h1:evJGjVpZv0mQ5QBRJoBF64yMuOf4xCWdXjK8pzFvliY= +go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI= +go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco= go.opentelemetry.io/otel/sdk v1.21.0 h1:FTt8qirL1EysG6sTQRZ5TokkU8d0ugCj8htOgThZXQ8= go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E= -go.opentelemetry.io/otel/trace v1.22.0 h1:Hg6pPujv0XG9QaVbGOBVHunyuLcCC3jN7WEhPx83XD0= -go.opentelemetry.io/otel/trace v1.22.0/go.mod h1:RbbHXVqKES9QhzZq/fE5UnOSILqRt40a21sPw2He1xo= +go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI= +go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU= go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I= go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= @@ -1020,8 +1019,8 @@ golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45 golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= -golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= -golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/crypto v0.20.0 h1:jmAMJJZXr5KiCw05dfYK9QnqaqKLYXijU23lsEdcQqg= +golang.org/x/crypto v0.20.0/go.mod h1:Xwo95rrVNIoSMx9wa1JroENMToLWn3RNVrTBpLHgZPQ= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1032,8 +1031,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20240213143201-ec583247a57a h1:HinSgX1tJRX3KsL//Gxynpw5CTOAIPhgL4W8PNiIpVE= -golang.org/x/exp v0.0.0-20240213143201-ec583247a57a/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc= +golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 h1:LfspQV/FYTatPTr/3HzIcmiUFH7PGP+OQ6mgDYo3yuQ= +golang.org/x/exp v0.0.0-20240222234643-814bf88cf225/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1127,8 +1126,8 @@ golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4Iltr golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.16.0 h1:aDkGMBSYxElaoP81NpoUoz2oo2R2wHdZpGToUxfyQrQ= -golang.org/x/oauth2 v0.16.0/go.mod h1:hqZ+0LWXsiVoZpeld6jVt06P3adbS2Uu911W1SsJv2o= +golang.org/x/oauth2 v0.17.0 h1:6m3ZPmLEFdVxKKWnKq4VqZ60gutO35zm+zrAHVmHyDQ= +golang.org/x/oauth2 v0.17.0/go.mod h1:OzPDGQiuQMguemayvdylqddI7qcD9lnSDb+1FiwQ5HA= golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 9e38a7086..ec9992680 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -89,7 +89,7 @@ require ( github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/gopacket v1.1.19 // indirect - github.com/google/uuid v1.5.0 // indirect + github.com/google/uuid v1.6.0 // indirect github.com/gordonklaus/ineffassign v0.0.0-20230610083614-0e73809eb601 // indirect github.com/gostaticanalysis/analysisutil v0.7.1 // indirect github.com/gostaticanalysis/comment v1.4.2 // indirect @@ -137,7 +137,7 @@ require ( github.com/libp2p/go-cidranger v1.1.0 // indirect github.com/libp2p/go-libp2p v0.33.0 // indirect github.com/libp2p/go-libp2p-asn-util v0.4.1 // indirect - github.com/libp2p/go-libp2p-kad-dht v0.24.4 // indirect + github.com/libp2p/go-libp2p-kad-dht v0.25.2 // indirect github.com/libp2p/go-libp2p-kbucket v0.6.3 // indirect github.com/libp2p/go-libp2p-record v0.2.0 // indirect github.com/libp2p/go-libp2p-routing-helpers v0.7.3 // indirect @@ -180,9 +180,9 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect github.com/polydawn/refmt v0.89.0 // indirect github.com/polyfloyd/go-errorlint v1.4.3 // indirect - github.com/prometheus/client_golang v1.18.0 // indirect + github.com/prometheus/client_golang v1.19.0 // indirect github.com/prometheus/client_model v0.6.0 // indirect - github.com/prometheus/common v0.47.0 // indirect + github.com/prometheus/common v0.49.0 // indirect github.com/prometheus/procfs v0.12.0 // indirect github.com/quasilyte/go-ruleguard v0.4.0 // indirect github.com/quasilyte/gogrep v0.5.0 // indirect @@ -234,14 +234,14 @@ require ( github.com/ykadowak/zerologlint v0.1.3 // indirect gitlab.com/bosi/decorder v0.4.0 // indirect go.opencensus.io v0.24.0 // indirect - go.opentelemetry.io/otel v1.22.0 // indirect - go.opentelemetry.io/otel/metric v1.22.0 // indirect - go.opentelemetry.io/otel/trace v1.22.0 // indirect + go.opentelemetry.io/otel v1.24.0 // indirect + go.opentelemetry.io/otel/metric v1.24.0 // indirect + go.opentelemetry.io/otel/trace v1.24.0 // indirect go.tmz.dev/musttag v0.7.1 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect - golang.org/x/crypto v0.19.0 // indirect - golang.org/x/exp v0.0.0-20240213143201-ec583247a57a // indirect + golang.org/x/crypto v0.20.0 // indirect + golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 // indirect golang.org/x/exp/typeparams v0.0.0-20230307190834-24139beb5833 // indirect golang.org/x/mod v0.15.0 // indirect golang.org/x/net v0.21.0 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 163c393ab..3c422c295 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -309,8 +309,8 @@ github.com/google/pprof v0.0.0-20240207164012-fb44976bdcd5 h1:E/LAvt58di64hlYjx7 github.com/google/pprof v0.0.0-20240207164012-fb44976bdcd5/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU= -github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= @@ -484,8 +484,8 @@ github.com/libp2p/go-libp2p v0.33.0 h1:yTPSr8sJRbfeEYXyeN8VPVSlTlFjtMUwGDRniwaf/ github.com/libp2p/go-libp2p v0.33.0/go.mod h1:RIJFRQVUBKy82dnW7J5f1homqqv6NcsDJAl3e7CRGfE= github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94= github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= -github.com/libp2p/go-libp2p-kad-dht v0.24.4 h1:ktNiJe7ffsJ1wX3ULpMCwXts99mPqGFSE/Qn1i8pErQ= -github.com/libp2p/go-libp2p-kad-dht v0.24.4/go.mod h1:ybWBJ5Fbvz9sSLkNtXt+2+bK0JB8+tRPvhBbRGHegRU= +github.com/libp2p/go-libp2p-kad-dht v0.25.2 h1:FOIk9gHoe4YRWXTu8SY9Z1d0RILol0TrtApsMDPjAVQ= +github.com/libp2p/go-libp2p-kad-dht v0.25.2/go.mod h1:6za56ncRHYXX4Nc2vn8z7CZK0P4QiMcrn77acKLM2Oo= github.com/libp2p/go-libp2p-kbucket v0.6.3 h1:p507271wWzpy2f1XxPzCQG9NiN6R6lHL9GiSErbQQo0= github.com/libp2p/go-libp2p-kbucket v0.6.3/go.mod h1:RCseT7AH6eJWxxk2ol03xtP9pEHetYSPXOaJnOiD8i0= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= @@ -635,8 +635,8 @@ github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5Fsn github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= -github.com/prometheus/client_golang v1.18.0 h1:HzFfmkOzH5Q8L8G+kSJKUx5dtG87sewO+FoDDqP5Tbk= -github.com/prometheus/client_golang v1.18.0/go.mod h1:T+GXkCk5wSJyOqMIzVgvvjFDlkOQntgjkJWKrN5txjA= +github.com/prometheus/client_golang v1.19.0 h1:ygXvpU1AoN1MhdzckN+PyD9QJOSD4x7kmXYlnfbA6JU= +github.com/prometheus/client_golang v1.19.0/go.mod h1:ZRM9uEAypZakd+q/x7+gmsvXdURP+DABIEIjnmDdp+k= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -647,8 +647,8 @@ github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8 github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= -github.com/prometheus/common v0.47.0 h1:p5Cz0FNHo7SnWOmWmoRozVcjEp0bIVU8cV7OShpjL1k= -github.com/prometheus/common v0.47.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc= +github.com/prometheus/common v0.49.0 h1:ToNTdK4zSnPVJmh698mGFkDor9wBI/iGaJy5dbH1EgI= +github.com/prometheus/common v0.49.0/go.mod h1:Kxm+EULxRbUkjGU6WFsQqo3ORzB4tyKvlWFOE9mB2sE= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= @@ -817,12 +817,12 @@ go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/otel v1.22.0 h1:xS7Ku+7yTFvDfDraDIJVpw7XPyuHlB9MCiqqX5mcJ6Y= -go.opentelemetry.io/otel v1.22.0/go.mod h1:eoV4iAi3Ea8LkAEI9+GFT44O6T/D0GWAVFyZVCC6pMI= -go.opentelemetry.io/otel/metric v1.22.0 h1:lypMQnGyJYeuYPhOM/bgjbFM6WE44W1/T45er4d8Hhg= -go.opentelemetry.io/otel/metric v1.22.0/go.mod h1:evJGjVpZv0mQ5QBRJoBF64yMuOf4xCWdXjK8pzFvliY= -go.opentelemetry.io/otel/trace v1.22.0 h1:Hg6pPujv0XG9QaVbGOBVHunyuLcCC3jN7WEhPx83XD0= -go.opentelemetry.io/otel/trace v1.22.0/go.mod h1:RbbHXVqKES9QhzZq/fE5UnOSILqRt40a21sPw2He1xo= +go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo= +go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo= +go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI= +go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco= +go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI= +go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU= go.tmz.dev/musttag v0.7.1 h1:9lFmeSFnFfPuMq4IksHGomItE6NgKMNW2Nt2FPOhCfU= go.tmz.dev/musttag v0.7.1/go.mod h1:oJLkpR56EsIryktZJk/B0IroSMi37YWver47fibGh5U= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= @@ -856,8 +856,8 @@ golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= -golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= -golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/crypto v0.20.0 h1:jmAMJJZXr5KiCw05dfYK9QnqaqKLYXijU23lsEdcQqg= +golang.org/x/crypto v0.20.0/go.mod h1:Xwo95rrVNIoSMx9wa1JroENMToLWn3RNVrTBpLHgZPQ= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -868,8 +868,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20240213143201-ec583247a57a h1:HinSgX1tJRX3KsL//Gxynpw5CTOAIPhgL4W8PNiIpVE= -golang.org/x/exp v0.0.0-20240213143201-ec583247a57a/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc= +golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 h1:LfspQV/FYTatPTr/3HzIcmiUFH7PGP+OQ6mgDYo3yuQ= +golang.org/x/exp v0.0.0-20240222234643-814bf88cf225/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc= golang.org/x/exp/typeparams v0.0.0-20220428152302-39d4317da171/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/exp/typeparams v0.0.0-20230203172020-98cc5a0785f9/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/exp/typeparams v0.0.0-20230307190834-24139beb5833 h1:jWGQJV4niP+CCmFW9ekjA9Zx8vYORzOUH2/Nl5WPuLQ= From d7fb526bf244a5fe92b09699c9c6842c6182ff9c Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Mon, 4 Mar 2024 13:14:00 +0100 Subject: [PATCH 1050/1212] revert kad dht --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index ca77d8b16..9298339df 100644 --- a/go.mod +++ b/go.mod @@ -49,7 +49,7 @@ require ( github.com/libp2p/go-doh-resolver v0.4.0 github.com/libp2p/go-libp2p v0.33.0 github.com/libp2p/go-libp2p-http v0.5.0 - github.com/libp2p/go-libp2p-kad-dht v0.25.2 + github.com/libp2p/go-libp2p-kad-dht v0.24.4 github.com/libp2p/go-libp2p-kbucket v0.6.3 github.com/libp2p/go-libp2p-pubsub v0.10.0 github.com/libp2p/go-libp2p-pubsub-router v0.6.0 diff --git a/go.sum b/go.sum index 18ab786a5..fc2a4142c 100644 --- a/go.sum +++ b/go.sum @@ -518,8 +518,8 @@ github.com/libp2p/go-libp2p-gostream v0.6.0 h1:QfAiWeQRce6pqnYfmIVWJFXNdDyfiR/qk github.com/libp2p/go-libp2p-gostream v0.6.0/go.mod h1:Nywu0gYZwfj7Jc91PQvbGU8dIpqbQQkjWgDuOrFaRdA= github.com/libp2p/go-libp2p-http v0.5.0 h1:+x0AbLaUuLBArHubbbNRTsgWz0RjNTy6DJLOxQ3/QBc= github.com/libp2p/go-libp2p-http v0.5.0/go.mod h1:glh87nZ35XCQyFsdzZps6+F4HYI6DctVFY5u1fehwSg= -github.com/libp2p/go-libp2p-kad-dht v0.25.2 h1:FOIk9gHoe4YRWXTu8SY9Z1d0RILol0TrtApsMDPjAVQ= -github.com/libp2p/go-libp2p-kad-dht v0.25.2/go.mod h1:6za56ncRHYXX4Nc2vn8z7CZK0P4QiMcrn77acKLM2Oo= +github.com/libp2p/go-libp2p-kad-dht v0.24.4 h1:ktNiJe7ffsJ1wX3ULpMCwXts99mPqGFSE/Qn1i8pErQ= +github.com/libp2p/go-libp2p-kad-dht v0.24.4/go.mod h1:ybWBJ5Fbvz9sSLkNtXt+2+bK0JB8+tRPvhBbRGHegRU= github.com/libp2p/go-libp2p-kbucket v0.3.1/go.mod h1:oyjT5O7tS9CQurok++ERgc46YLwEpuGoFq9ubvoUOio= github.com/libp2p/go-libp2p-kbucket v0.6.3 h1:p507271wWzpy2f1XxPzCQG9NiN6R6lHL9GiSErbQQo0= github.com/libp2p/go-libp2p-kbucket v0.6.3/go.mod h1:RCseT7AH6eJWxxk2ol03xtP9pEHetYSPXOaJnOiD8i0= From fcbdf390bcd1031d5b332044f5d3966abfe26c64 Mon Sep 17 00:00:00 2001 From: Russell Dempsey <1173416+SgtPooki@users.noreply.github.com> Date: Tue, 27 Feb 2024 15:22:04 -0800 Subject: [PATCH 1051/1212] chore: create FUNDING.yml --- .github/FUNDING.yml | 1 + 1 file changed, 1 insertion(+) create mode 100644 .github/FUNDING.yml diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 000000000..eeba0640d --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +custom: [ipshipyard.gitwallet.co] From d60b7cd1b1d0c36bf958c09352e8bd41707babe6 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Tue, 5 Mar 2024 08:37:34 +0100 Subject: [PATCH 1052/1212] ci: upgrade to go 1.22 (#10355) --- .github/workflows/build.yml | 2 +- .github/workflows/codeql-analysis.yml | 2 +- .github/workflows/docker-build.yml | 2 +- .github/workflows/gateway-conformance.yml | 4 ++-- .github/workflows/gobuild.yml | 2 +- .github/workflows/golang-analysis.yml | 2 +- .github/workflows/golint.yml | 2 +- .github/workflows/gotest.yml | 2 +- .github/workflows/sharness.yml | 2 +- Dockerfile | 2 +- docs/examples/kubo-as-a-library/go.mod | 4 ++-- go.mod | 4 +--- test/dependencies/go.mod | 4 ++-- test/sharness/t0051-object-data/expected_getOut | 2 +- 14 files changed, 17 insertions(+), 19 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2d1ce7dd2..2967c9997 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -10,7 +10,7 @@ on: - 'master' env: - GO_VERSION: 1.21.x + GO_VERSION: 1.22.x concurrency: group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.event_name == 'push' && github.sha || github.ref }} diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 69beb5e37..d0e082d65 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -34,7 +34,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: 1.21.x + go-version: 1.22.x # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml index 733dc2c0e..433240f42 100644 --- a/.github/workflows/docker-build.yml +++ b/.github/workflows/docker-build.yml @@ -28,7 +28,7 @@ jobs: steps: - uses: actions/setup-go@v5 with: - go-version: 1.21.x + go-version: 1.22.x - uses: actions/checkout@v4 - run: docker build -t $IMAGE_NAME:$WIP_IMAGE_TAG . - run: docker run --rm $IMAGE_NAME:$WIP_IMAGE_TAG --version diff --git a/.github/workflows/gateway-conformance.yml b/.github/workflows/gateway-conformance.yml index 4a94287ec..0f3698641 100644 --- a/.github/workflows/gateway-conformance.yml +++ b/.github/workflows/gateway-conformance.yml @@ -49,7 +49,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: 1.21.x + go-version: 1.22.x - uses: protocol/cache-go-action@v1 with: name: ${{ github.job }} @@ -137,7 +137,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: 1.21.x + go-version: 1.22.x - uses: protocol/cache-go-action@v1 with: name: ${{ github.job }} diff --git a/.github/workflows/gobuild.yml b/.github/workflows/gobuild.yml index f5de9e517..93159eadd 100644 --- a/.github/workflows/gobuild.yml +++ b/.github/workflows/gobuild.yml @@ -30,7 +30,7 @@ jobs: steps: - uses: actions/setup-go@v5 with: - go-version: 1.21.x + go-version: 1.22.x - uses: actions/checkout@v4 - run: make cmd/ipfs-try-build env: diff --git a/.github/workflows/golang-analysis.yml b/.github/workflows/golang-analysis.yml index 0643de160..e89034a92 100644 --- a/.github/workflows/golang-analysis.yml +++ b/.github/workflows/golang-analysis.yml @@ -27,7 +27,7 @@ jobs: submodules: recursive - uses: actions/setup-go@v5 with: - go-version: "1.21.x" + go-version: "1.22.x" - name: Check that go.mod is tidy uses: protocol/multiple-go-modules@v1.4 with: diff --git a/.github/workflows/golint.yml b/.github/workflows/golint.yml index 591507471..aa8b21b53 100644 --- a/.github/workflows/golint.yml +++ b/.github/workflows/golint.yml @@ -31,6 +31,6 @@ jobs: steps: - uses: actions/setup-go@v5 with: - go-version: 1.21.x + go-version: 1.22.x - uses: actions/checkout@v4 - run: make -O test_go_lint diff --git a/.github/workflows/gotest.yml b/.github/workflows/gotest.yml index a69dbc2f0..1d8c75e5e 100644 --- a/.github/workflows/gotest.yml +++ b/.github/workflows/gotest.yml @@ -32,7 +32,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v5 with: - go-version: 1.21.x + go-version: 1.22.x - name: Check out Kubo uses: actions/checkout@v4 - name: Install missing tools diff --git a/.github/workflows/sharness.yml b/.github/workflows/sharness.yml index 436ef34a1..9e6c33e7f 100644 --- a/.github/workflows/sharness.yml +++ b/.github/workflows/sharness.yml @@ -25,7 +25,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: 1.21.x + go-version: 1.22.x - name: Checkout Kubo uses: actions/checkout@v4 with: diff --git a/Dockerfile b/Dockerfile index d68e525b9..4ed07d3d4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM --platform=${BUILDPLATFORM:-linux/amd64} golang:1.21 AS builder +FROM --platform=${BUILDPLATFORM:-linux/amd64} golang:1.22 AS builder ARG TARGETOS TARGETARCH diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 03f685e7c..3ed4e2cb5 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -1,8 +1,8 @@ module github.com/ipfs/kubo/examples/kubo-as-a-library -go 1.21 +go 1.22 -toolchain go1.21.7 +toolchain go1.22.0 // Used to keep this in sync with the current version of kubo. You should remove // this if you copy this example. diff --git a/go.mod b/go.mod index 9298339df..d07b3ee8e 100644 --- a/go.mod +++ b/go.mod @@ -250,6 +250,4 @@ require ( lukechampine.com/blake3 v1.2.1 // indirect ) -go 1.21 - -toolchain go1.21.7 +go 1.22 diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index ec9992680..6fc84587f 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -1,8 +1,8 @@ module github.com/ipfs/kubo/test/dependencies -go 1.21 +go 1.22 -toolchain go1.21.7 +toolchain go1.22.0 replace github.com/ipfs/kubo => ../../ diff --git a/test/sharness/t0051-object-data/expected_getOut b/test/sharness/t0051-object-data/expected_getOut index dc12f63ba..27b23f9d3 100644 --- a/test/sharness/t0051-object-data/expected_getOut +++ b/test/sharness/t0051-object-data/expected_getOut @@ -1 +1 @@ -{"Links":[],"Data":"\u0008\u0002\u0012\nHello Mars\u0018\n"} +{"Links":[],"Data":"\b\u0002\u0012\nHello Mars\u0018\n"} From d77a9e69f792f643b11df7c2ccf54372559c576e Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Tue, 27 Feb 2024 14:59:57 +0100 Subject: [PATCH 1053/1212] client/rpc!: remove deprecated DHT commands --- client/rpc/api.go | 6 ------ client/rpc/dht.go | 33 --------------------------------- core/coreapi/coreapi.go | 6 ------ core/coreapi/dht.go | 34 ---------------------------------- core/coreiface/coreapi.go | 4 ---- core/coreiface/dht.go | 25 ------------------------- docs/changelogs/v0.28.md | 5 +++++ 7 files changed, 5 insertions(+), 108 deletions(-) delete mode 100644 client/rpc/dht.go delete mode 100644 core/coreapi/dht.go delete mode 100644 core/coreiface/dht.go diff --git a/client/rpc/api.go b/client/rpc/api.go index 827b427c9..79d42124a 100644 --- a/client/rpc/api.go +++ b/client/rpc/api.go @@ -227,12 +227,6 @@ func (api *HttpApi) Object() iface.ObjectAPI { return (*ObjectAPI)(api) } -// nolint deprecated -// Deprecated: use [HttpApi.Routing] instead. -func (api *HttpApi) Dht() iface.DhtAPI { - return (*DhtAPI)(api) -} - func (api *HttpApi) Swarm() iface.SwarmAPI { return (*SwarmAPI)(api) } diff --git a/client/rpc/dht.go b/client/rpc/dht.go deleted file mode 100644 index cfc886a49..000000000 --- a/client/rpc/dht.go +++ /dev/null @@ -1,33 +0,0 @@ -package rpc - -import ( - "context" - - "github.com/ipfs/boxo/path" - caopts "github.com/ipfs/kubo/core/coreiface/options" - "github.com/libp2p/go-libp2p/core/peer" -) - -type DhtAPI HttpApi - -// nolint deprecated -// Deprecated: use [RoutingAPI.FindPeer] instead. -func (api *DhtAPI) FindPeer(ctx context.Context, p peer.ID) (peer.AddrInfo, error) { - return api.core().Routing().FindPeer(ctx, p) -} - -// nolint deprecated -// Deprecated: use [RoutingAPI.FindProviders] instead. -func (api *DhtAPI) FindProviders(ctx context.Context, p path.Path, opts ...caopts.DhtFindProvidersOption) (<-chan peer.AddrInfo, error) { - return api.core().Routing().FindProviders(ctx, p, opts...) -} - -// nolint deprecated -// Deprecated: use [RoutingAPI.Provide] instead. -func (api *DhtAPI) Provide(ctx context.Context, p path.Path, opts ...caopts.DhtProvideOption) error { - return api.core().Routing().Provide(ctx, p, opts...) -} - -func (api *DhtAPI) core() *HttpApi { - return (*HttpApi)(api) -} diff --git a/core/coreapi/coreapi.go b/core/coreapi/coreapi.go index 6c6aa4907..b757929a2 100644 --- a/core/coreapi/coreapi.go +++ b/core/coreapi/coreapi.go @@ -130,12 +130,6 @@ func (api *CoreAPI) Pin() coreiface.PinAPI { return (*PinAPI)(api) } -// nolint deprecated -// Deprecated: use [CoreAPI.Routing] instead. -func (api *CoreAPI) Dht() coreiface.DhtAPI { - return (*DhtAPI)(api) -} - // Swarm returns the SwarmAPI interface implementation backed by the go-ipfs node func (api *CoreAPI) Swarm() coreiface.SwarmAPI { return (*SwarmAPI)(api) diff --git a/core/coreapi/dht.go b/core/coreapi/dht.go deleted file mode 100644 index f9155de00..000000000 --- a/core/coreapi/dht.go +++ /dev/null @@ -1,34 +0,0 @@ -package coreapi - -import ( - "context" - - "github.com/ipfs/boxo/path" - coreiface "github.com/ipfs/kubo/core/coreiface" - caopts "github.com/ipfs/kubo/core/coreiface/options" - peer "github.com/libp2p/go-libp2p/core/peer" -) - -type DhtAPI CoreAPI - -// nolint deprecated -// Deprecated: use [RoutingAPI.FindPeer] instead. -func (api *DhtAPI) FindPeer(ctx context.Context, p peer.ID) (peer.AddrInfo, error) { - return api.core().Routing().FindPeer(ctx, p) -} - -// nolint deprecated -// Deprecated: use [RoutingAPI.FindProviders] instead. -func (api *DhtAPI) FindProviders(ctx context.Context, p path.Path, opts ...caopts.DhtFindProvidersOption) (<-chan peer.AddrInfo, error) { - return api.core().Routing().FindProviders(ctx, p, opts...) -} - -// nolint deprecated -// Deprecated: use [RoutingAPI.Provide] instead. -func (api *DhtAPI) Provide(ctx context.Context, p path.Path, opts ...caopts.DhtProvideOption) error { - return api.core().Routing().Provide(ctx, p, opts...) -} - -func (api *DhtAPI) core() coreiface.CoreAPI { - return (*CoreAPI)(api) -} diff --git a/core/coreiface/coreapi.go b/core/coreiface/coreapi.go index bcd94f381..dbb08dd7e 100644 --- a/core/coreiface/coreapi.go +++ b/core/coreiface/coreapi.go @@ -34,10 +34,6 @@ type CoreAPI interface { // Object returns an implementation of Object API Object() ObjectAPI - // nolint deprecated - // Deprecated: use [Routing] instead. - Dht() DhtAPI - // Swarm returns an implementation of Swarm API Swarm() SwarmAPI diff --git a/core/coreiface/dht.go b/core/coreiface/dht.go deleted file mode 100644 index 001f5856a..000000000 --- a/core/coreiface/dht.go +++ /dev/null @@ -1,25 +0,0 @@ -package iface - -import ( - "context" - - "github.com/ipfs/boxo/path" - "github.com/ipfs/kubo/core/coreiface/options" - "github.com/libp2p/go-libp2p/core/peer" -) - -// nolint deprecated -// Deprecated: use [RoutingAPI] instead. -type DhtAPI interface { - // nolint deprecated - // Deprecated: use [RoutingAPI.FindPeer] instead. - FindPeer(context.Context, peer.ID) (peer.AddrInfo, error) - - // nolint deprecated - // Deprecated: use [RoutingAPI.FindProviders] instead. - FindProviders(context.Context, path.Path, ...options.DhtFindProvidersOption) (<-chan peer.AddrInfo, error) - - // nolint deprecated - // Deprecated: use [RoutingAPI.Provide] instead. - Provide(context.Context, path.Path, ...options.DhtProvideOption) error -} diff --git a/docs/changelogs/v0.28.md b/docs/changelogs/v0.28.md index a811e81aa..2bb61707a 100644 --- a/docs/changelogs/v0.28.md +++ b/docs/changelogs/v0.28.md @@ -6,6 +6,7 @@ - [Overview](#overview) - [🔦 Highlights](#-highlights) + - [RPC client: removed deprecated DHT API](#rpc-client-removed-deprecated-dht-api) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -13,6 +14,10 @@ ### 🔦 Highlights +#### RPC client: removed deprecated DHT API + +The deprecated DHT API commands in the RPC client have been removed. Instead, use the Routing API. + ### 📝 Changelog ### 👨‍👩‍👧‍👦 Contributors From e22f47ae4b4d83cf5e3f1c901c10905ebd69d492 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Tue, 5 Mar 2024 09:21:13 +0100 Subject: [PATCH 1054/1212] core/corehttp!: remove /api/v0 from gateway port --- cmd/ipfs/kubo/daemon.go | 2 - config/gateway.go | 2 +- core/commands/commands_test.go | 57 ----------------- core/commands/root.go | 63 ------------------- core/commands/root_test.go | 1 - core/corehttp/commands.go | 22 +------ core/corehttp/gateway.go | 2 +- docs/changelogs/v0.28.md | 9 ++- docs/gateway.md | 9 --- test/cli/gateway_test.go | 71 --------------------- test/sharness/t0002-docker-image.sh | 2 +- test/sharness/t0112-gateway-cors.sh | 64 ------------------- test/sharness/t0114-gateway-subdomains.sh | 75 ----------------------- 13 files changed, 12 insertions(+), 367 deletions(-) diff --git a/cmd/ipfs/kubo/daemon.go b/cmd/ipfs/kubo/daemon.go index 82f240897..b966a630e 100644 --- a/cmd/ipfs/kubo/daemon.go +++ b/cmd/ipfs/kubo/daemon.go @@ -850,8 +850,6 @@ func serveHTTPGateway(req *cmds.Request, cctx *oldcmds.Context) (<-chan error, e corehttp.GatewayOption("/ipfs", "/ipns"), corehttp.VersionOption(), corehttp.CheckVersionOption(), - // TODO[api-on-gw]: remove for 0.28.0: https://github.com/ipfs/kubo/issues/10312 - corehttp.CommandsROOption(cmdctx), } if cfg.Experimental.P2pHttpProxy { diff --git a/config/gateway.go b/config/gateway.go index fa093245d..35af598b4 100644 --- a/config/gateway.go +++ b/config/gateway.go @@ -9,7 +9,7 @@ const ( type GatewaySpec struct { // Paths is explicit list of path prefixes that should be handled by - // this gateway. Example: `["/ipfs", "/ipns", "/api"]` + // this gateway. Example: `["/ipfs", "/ipns"]` Paths []string // UseSubdomains indicates whether or not this gateway uses subdomains diff --git a/core/commands/commands_test.go b/core/commands/commands_test.go index 99cd07988..9e4da274c 100644 --- a/core/commands/commands_test.go +++ b/core/commands/commands_test.go @@ -15,63 +15,6 @@ func collectPaths(prefix string, cmd *cmds.Command, out map[string]struct{}) { } } -func TestROCommands(t *testing.T) { - list := []string{ - "/block", - "/block/get", - "/block/stat", - "/cat", - "/commands", - "/commands/completion", - "/commands/completion/bash", - "/commands/completion/fish", - "/commands/completion/zsh", - "/dag", - "/dag/get", - "/dag/resolve", - "/dag/stat", - "/dag/export", - "/get", - "/ls", - "/name", - "/name/resolve", - "/object", - "/object/data", - "/object/get", - "/object/links", - "/object/stat", - "/refs", - "/resolve", - "/version", - } - - cmdSet := make(map[string]struct{}) - collectPaths("", RootRO, cmdSet) - - for _, path := range list { - if _, ok := cmdSet[path]; !ok { - t.Errorf("%q not in result", path) - } else { - delete(cmdSet, path) - } - } - - for path := range cmdSet { - t.Errorf("%q in result but shouldn't be", path) - } - - for _, path := range list { - path = path[1:] // remove leading slash - split := strings.Split(path, "/") - sub, err := RootRO.Get(split) - if err != nil { - t.Errorf("error getting subcommand %q: %v", path, err) - } else if sub == nil { - t.Errorf("subcommand %q is nil even though there was no error", path) - } - } -} - func TestCommands(t *testing.T) { list := []string{ "/add", diff --git a/core/commands/root.go b/core/commands/root.go index b4e563cdb..d062e75b4 100644 --- a/core/commands/root.go +++ b/core/commands/root.go @@ -162,72 +162,9 @@ var rootSubcommands = map[string]*cmds.Command{ "multibase": MbaseCmd, } -// RootRO is the readonly version of Root -var RootRO = &cmds.Command{} - -var CommandsDaemonROCmd = CommandsCmd(RootRO) - -// RefsROCmd is `ipfs refs` command -var RefsROCmd = &cmds.Command{} - -// VersionROCmd is `ipfs version` command (without deps). -var VersionROCmd = &cmds.Command{} - -var rootROSubcommands = map[string]*cmds.Command{ - "commands": CommandsDaemonROCmd, - "cat": CatCmd, - "block": { - Subcommands: map[string]*cmds.Command{ - "stat": blockStatCmd, - "get": blockGetCmd, - }, - }, - "get": GetCmd, - "ls": LsCmd, - "name": { - Subcommands: map[string]*cmds.Command{ - "resolve": name.IpnsCmd, - }, - }, - "object": { - Subcommands: map[string]*cmds.Command{ - "data": ocmd.ObjectDataCmd, - "links": ocmd.ObjectLinksCmd, - "get": ocmd.ObjectGetCmd, - "stat": ocmd.ObjectStatCmd, - }, - }, - "dag": { - Subcommands: map[string]*cmds.Command{ - "get": dag.DagGetCmd, - "resolve": dag.DagResolveCmd, - "stat": dag.DagStatCmd, - "export": dag.DagExportCmd, - }, - }, - "resolve": ResolveCmd, -} - func init() { Root.ProcessHelp() - *RootRO = *Root - - // this was in the big map definition above before, - // but if we leave it there lgc.NewCommand will be executed - // before the value is updated (:/sanitize readonly refs command/) - - // sanitize readonly refs command - *RefsROCmd = *RefsCmd - RefsROCmd.Subcommands = map[string]*cmds.Command{} - rootROSubcommands["refs"] = RefsROCmd - - // sanitize readonly version command (no need to expose precise deps) - *VersionROCmd = *VersionCmd - VersionROCmd.Subcommands = map[string]*cmds.Command{} - rootROSubcommands["version"] = VersionROCmd - Root.Subcommands = rootSubcommands - RootRO.Subcommands = rootROSubcommands } type MessageOutput struct { diff --git a/core/commands/root_test.go b/core/commands/root_test.go index f5e5c248b..d1bf2e610 100644 --- a/core/commands/root_test.go +++ b/core/commands/root_test.go @@ -18,5 +18,4 @@ func TestCommandTree(t *testing.T) { } } printErrors(Root.DebugValidate()) - printErrors(RootRO.DebugValidate()) } diff --git a/core/corehttp/commands.go b/core/corehttp/commands.go index 4feef3359..8e1f84422 100644 --- a/core/corehttp/commands.go +++ b/core/corehttp/commands.go @@ -9,7 +9,6 @@ import ( "strconv" "strings" - "github.com/ipfs/boxo/gateway" cmds "github.com/ipfs/go-ipfs-cmds" cmdsHttp "github.com/ipfs/go-ipfs-cmds/http" version "github.com/ipfs/kubo" @@ -122,14 +121,10 @@ func patchCORSVars(c *cmdsHttp.ServerConfig, addr net.Addr) { c.SetAllowedOrigins(newOrigins...) } -func commandsOption(cctx oldcmds.Context, command *cmds.Command, allowGet bool) ServeOption { +func commandsOption(cctx oldcmds.Context, command *cmds.Command) ServeOption { return func(n *core.IpfsNode, l net.Listener, mux *http.ServeMux) (*http.ServeMux, error) { cfg := cmdsHttp.NewServerConfig() - cfg.AllowGet = allowGet corsAllowedMethods := []string{http.MethodPost} - if allowGet { - corsAllowedMethods = append(corsAllowedMethods, http.MethodGet) - } cfg.SetAllowedMethods(corsAllowedMethods...) cfg.APIPath = APIPath @@ -150,13 +145,6 @@ func commandsOption(cctx oldcmds.Context, command *cmds.Command, allowGet bool) cmdHandler = withAuthSecrets(authorizations, cmdHandler) } - // TODO[api-on-gw]: remove for Kubo 0.28 - if command == corecommands.RootRO && allowGet { - cmdHandler = gateway.NewHeaders(map[string][]string{ - "Link": {`; rel="deprecation"; type="text/html"`}, - }).Wrap(cmdHandler) - } - cmdHandler = otelhttp.NewHandler(cmdHandler, "corehttp.cmdsHandler") mux.Handle(APIPath+"/", cmdHandler) return mux, nil @@ -211,13 +199,7 @@ func withAuthSecrets(authorizations map[string]rpcAuthScopeWithUser, next http.H // CommandsOption constructs a ServerOption for hooking the commands into the // HTTP server. It will NOT allow GET requests. func CommandsOption(cctx oldcmds.Context) ServeOption { - return commandsOption(cctx, corecommands.Root, false) -} - -// CommandsROOption constructs a ServerOption for hooking the read-only commands -// into the HTTP server. It will allow GET requests. -func CommandsROOption(cctx oldcmds.Context) ServeOption { - return commandsOption(cctx, corecommands.RootRO, true) + return commandsOption(cctx, corecommands.Root) } // CheckVersionOption returns a ServeOption that checks whether the client ipfs version matches. Does nothing when the user agent string does not contain `/kubo/` or `/go-ipfs/` diff --git a/core/corehttp/gateway.go b/core/corehttp/gateway.go index 67e3c242d..6ac381885 100644 --- a/core/corehttp/gateway.go +++ b/core/corehttp/gateway.go @@ -235,7 +235,7 @@ func (o *offlineGatewayErrWrapper) GetDNSLinkRecord(ctx context.Context, s strin var _ gateway.IPFSBackend = (*offlineGatewayErrWrapper)(nil) -var defaultPaths = []string{"/ipfs/", "/ipns/", "/api/", "/p2p/"} +var defaultPaths = []string{"/ipfs/", "/ipns/", "/p2p/"} var subdomainGatewaySpec = &gateway.PublicGateway{ Paths: defaultPaths, diff --git a/docs/changelogs/v0.28.md b/docs/changelogs/v0.28.md index 2bb61707a..ffc816737 100644 --- a/docs/changelogs/v0.28.md +++ b/docs/changelogs/v0.28.md @@ -7,17 +7,22 @@ - [Overview](#overview) - [🔦 Highlights](#-highlights) - [RPC client: removed deprecated DHT API](#rpc-client-removed-deprecated-dht-api) + - [Gateway: `/api/v0` is removed](#gateway-apiv0-is-removed) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) ### Overview -### 🔦 Highlights - #### RPC client: removed deprecated DHT API The deprecated DHT API commands in the RPC client have been removed. Instead, use the Routing API. +#### Gateway: `/api/v0` is removed + +The legacy subset of the Kubo RPC that was available via the Gateway port and was deprecated is now completely removed. You can read more in . + +If you have a legacy software that relies on this behavior, and want to expose parts of `/api/v0` next to `/ipfs`, use reverse-proxy in front of Kubo to mount both Gateway and RPC on the same port. NOTE: exposing RPC to the internet comes with security risk: make sure to specify access control via [API.Authorizations](https://github.com/ipfs/kubo/blob/master/docs/config.md#apiauthorizations). + ### 📝 Changelog ### 👨‍👩‍👧‍👦 Contributors diff --git a/docs/gateway.md b/docs/gateway.md index 531c8c6f9..ce849486c 100644 --- a/docs/gateway.md +++ b/docs/gateway.md @@ -106,12 +106,3 @@ Right now only 'full DAG' implicit selector is implemented. Support for user-provided IPLD selectors is tracked in https://github.com/ipfs/kubo/issues/8769. This is a rough equivalent of `ipfs dag export`. - -## Deprecated Subset of RPC API - -For legacy reasons, some gateways may expose a small subset of RPC API under `/api/v0/`. -While this read-only API exposes a read-only, "safe" subset of the normal API, -it is deprecated and should not be used for greenfield projects. - -Where possible, leverage `/ipfs/` and `/ipns/` endpoints. -along with `application/vnd.ipld.*` Content-Types instead. diff --git a/test/cli/gateway_test.go b/test/cli/gateway_test.go index 71fb38d41..33212a90f 100644 --- a/test/cli/gateway_test.go +++ b/test/cli/gateway_test.go @@ -14,7 +14,6 @@ import ( "github.com/ipfs/kubo/config" "github.com/ipfs/kubo/test/cli/harness" - . "github.com/ipfs/kubo/test/cli/testutils" "github.com/libp2p/go-libp2p/core/peer" "github.com/multiformats/go-multiaddr" manet "github.com/multiformats/go-multiaddr/net" @@ -344,76 +343,6 @@ func TestGateway(t *testing.T) { }) }) - t.Run("readonly API", func(t *testing.T) { - t.Parallel() - - client := node.GatewayClient() - - fileContents := "12345" - h.WriteFile("readonly/dir/test", fileContents) - cids := node.IPFS("add", "-r", "-q", filepath.Join(h.Dir, "readonly/dir")).Stdout.Lines() - - rootCID := cids[len(cids)-1] - client.TemplateData = map[string]string{"RootCID": rootCID} - - t.Run("Get IPFS directory file through readonly API succeeds", func(t *testing.T) { - t.Parallel() - resp := client.Get("/api/v0/cat?arg={{.RootCID}}/test") - assert.Equal(t, 200, resp.StatusCode) - assert.Equal(t, fileContents, resp.Body) - }) - - t.Run("refs IPFS directory file through readonly API succeeds", func(t *testing.T) { - t.Parallel() - resp := client.Get("/api/v0/refs?arg={{.RootCID}}/test") - assert.Equal(t, 200, resp.StatusCode) - }) - - t.Run("test gateway API is sanitized", func(t *testing.T) { - t.Parallel() - for _, cmd := range []string{ - "add", - "block/put", - "bootstrap", - "config", - "dag/put", - "dag/import", - "dht", - "diag", - "id", - "mount", - "name/publish", - "object/put", - "object/new", - "object/patch", - "pin", - "ping", - "repo", - "stats", - "swarm", - "file", - "update", - "bitswap", - } { - t.Run(cmd, func(t *testing.T) { - cmd := cmd - t.Parallel() - assert.Equal(t, 404, client.Get("/api/v0/"+cmd).StatusCode) - }) - } - }) - }) - - t.Run("refs/local", func(t *testing.T) { - t.Parallel() - gatewayAddr := URLStrToMultiaddr(node.GatewayURL()) - res := node.RunIPFS("--api", gatewayAddr.String(), "refs", "local") - assert.Contains(t, - res.Stderr.Trimmed(), - `Error: invalid path "local":`, - ) - }) - t.Run("raw leaves node", func(t *testing.T) { t.Parallel() contents := "This is RAW!" diff --git a/test/sharness/t0002-docker-image.sh b/test/sharness/t0002-docker-image.sh index 11ccf01b7..2ff827806 100755 --- a/test/sharness/t0002-docker-image.sh +++ b/test/sharness/t0002-docker-image.sh @@ -50,7 +50,7 @@ test_expect_success "docker image runs" ' ' test_expect_success "docker container gateway is up" ' - pollEndpoint -host=/ip4/127.0.0.1/tcp/8080 -http-url http://localhost:8080/api/v0/version -v -tries 30 -tout 1s + pollEndpoint -host=/ip4/127.0.0.1/tcp/8080 -http-url http://localhost:8080/ipfs/bafkqaddimvwgy3zao5xxe3debi -v -tries 30 -tout 1s ' test_expect_success "docker container API is up" ' diff --git a/test/sharness/t0112-gateway-cors.sh b/test/sharness/t0112-gateway-cors.sh index 37027c188..90813ad6a 100755 --- a/test/sharness/t0112-gateway-cors.sh +++ b/test/sharness/t0112-gateway-cors.sh @@ -127,70 +127,6 @@ test_expect_success "Access-Control-Allow-Origin replaces the implicit list" ' test_should_contain "< Access-Control-Allow-Origin: localhost" curl_output ' -# Read-Only /api/v0 RPC API (legacy subset, exposed on the Gateway Port) -# TODO: we want to remove it, but for now this guards the legacy behavior to not go any further - -# also check this, as due to legacy reasons Kubo exposes small subset of /api/v0 on GW port -test_expect_success "Assert the default API.HTTPHeaders config is empty" ' - echo "{}" > expected && - ipfs config --json API.HTTPHeaders > actual && - test_cmp expected actual -' - -# HTTP GET Request -test_expect_success "Default CORS GET to {gw}/api/v0" ' - curl -svX GET -H "Origin: https://example.com" "http://127.0.0.1:$GWAY_PORT/api/v0/cat?arg=$thash" >/dev/null 2>curl_output -' -# HTTP 403 is returned because Kubo has additional protections on top of regular CORS, -# namely it only allows browser requests with localhost Origin header. -test_expect_success "Default CORS GET response from {gw}/api/v0 is 403 Forbidden and has regular CORS headers" ' - test_should_contain "HTTP/1.1 403 Forbidden" curl_output && - test_should_contain "< Access-Control-" curl_output -' - -# HTTP OPTIONS Request -test_expect_success "Default OPTIONS to {gw}/api/v0" ' - curl -svX OPTIONS -H "Origin: https://example.com" "http://127.0.0.1:$GWAY_PORT/api/v0/cat?arg=$thash" 2>curl_output -' -# OPTIONS Response from the API should NOT contain CORS headers -test_expect_success "OPTIONS response from {gw}/api/v0 has CORS headers" ' - test_should_contain "< Access-Control-" curl_output -' - -test_kill_ipfs_daemon - -# TODO: /api/v0 with CORS headers set in API.HTTPHeaders does not really work, -# as not all headers are correctly set. Below is only a basic regression test that documents -# current state. Fixing CORS on /api/v0 (RPC and Gateway port) is tracked in https://github.com/ipfs/kubo/issues/7667 - -test_expect_success "Manually set API.HTTPHeaders config to be as relaxed as Gateway.HTTPHeaders" " - ipfs config --json API.HTTPHeaders.Access-Control-Allow-Origin '[\"https://example.com\"]' -" -# TODO: ipfs config --json API.HTTPHeaders.Access-Control-Allow-Methods '[\"GET\",\"POST\"]' && -# TODO: ipfs config --json API.HTTPHeaders.Access-Control-Allow-Headers '[\"X-Requested-With\", \"Range\", \"User-Agent\"]' - -test_launch_ipfs_daemon - -# HTTP GET Request -test_expect_success "Manually relaxed CORS GET to {gw}/api/v0" ' - curl -svX GET -H "Origin: https://example.com" "http://127.0.0.1:$GWAY_PORT/api/v0/cat?arg=$thash" >/dev/null 2>curl_output -' -test_expect_success "Manually relaxed CORS GET response from {gw}/api/v0 is the same as Gateway" ' - test_should_contain "HTTP/1.1 200 OK" curl_output && - test_should_contain "< Access-Control-Allow-Origin: https://example.com" curl_output -' -# TODO: test_should_contain "< Access-Control-Allow-Methods: GET" curl_output - -# HTTP OPTIONS Request -test_expect_success "Manually relaxed OPTIONS to {gw}/api/v0" ' - curl -svX OPTIONS -H "Origin: https://example.com" "http://127.0.0.1:$GWAY_PORT/api/v0/cat?arg=$thash" 2>curl_output -' -# OPTIONS Response from the API should NOT contain CORS headers -test_expect_success "Manually relaxed OPTIONS response from {gw}/api/v0 is the same as Gateway" ' - test_should_contain "< Access-Control-Allow-Origin: https://example.com" curl_output -' -# TODO: test_should_contain "< Access-Control-Allow-Methods: GET" curl_output - test_kill_ipfs_daemon test_done diff --git a/test/sharness/t0114-gateway-subdomains.sh b/test/sharness/t0114-gateway-subdomains.sh index 2596bb492..5d9927d8e 100755 --- a/test/sharness/t0114-gateway-subdomains.sh +++ b/test/sharness/t0114-gateway-subdomains.sh @@ -203,25 +203,6 @@ test_localhost_gateway_response_should_contain \ # end Kubo specific end-to-end test -# API on localhost subdomain gateway - -# /api/v0 present on the root hostname -test_localhost_gateway_response_should_contain \ - "request for localhost/api" \ - "http://localhost:$GWAY_PORT/api/v0/refs?arg=${DIR_CID}&r=true" \ - "Ref" - -# /api/v0 not mounted on content root subdomains -test_localhost_gateway_response_should_contain \ - "request for {cid}.ipfs.localhost/api returns data if present on the content root" \ - "http://${DIR_CID}.ipfs.localhost:$GWAY_PORT/api/file.txt" \ - "I am a txt file" - -test_localhost_gateway_response_should_contain \ - "request for {cid}.ipfs.localhost/api/v0/refs returns 404" \ - "http://${DIR_CID}.ipfs.localhost:$GWAY_PORT/api/v0/refs?arg=${DIR_CID}&r=true" \ - "404 Not Found" - ## ============================================================================ ## Test subdomain-based requests to a local gateway with default config ## (origin per content root at http://*.localhost) @@ -308,14 +289,6 @@ test_localhost_gateway_response_should_contain \ "http://$DNSLINK_FQDN.ipns.localhost:$GWAY_PORT" \ "$CID_VAL" -# api.localhost/api - -# Note: we use DIR_CID so refs -r returns some CIDs for child nodes -test_localhost_gateway_response_should_contain \ - "request for api.localhost returns API response" \ - "http://api.localhost:$GWAY_PORT/api/v0/refs?arg=$DIR_CID&r=true" \ - "Ref" - ## ============================================================================ ## Test DNSLink inlining on HTTP gateways ## ============================================================================ @@ -518,54 +491,6 @@ test_hostname_gateway_response_should_contain \ "http://127.0.0.1:$GWAY_PORT" \ "Location: http://${ED25519_IPNS_IDv1}.ipns.example.com/" -# API on subdomain gateway example.com -# ============================================================================ - -# present at the root domain -test_hostname_gateway_response_should_contain \ - "request for example.com/api/v0/refs returns expected payload when /api is on Paths whitelist" \ - "example.com" \ - "http://127.0.0.1:$GWAY_PORT/api/v0/refs?arg=${DIR_CID}&r=true" \ - "Ref" - -# not mounted on content root subdomains -test_hostname_gateway_response_should_contain \ - "request for {cid}.ipfs.example.com/api returns data if present on the content root" \ - "$DIR_CID.ipfs.example.com" \ - "http://127.0.0.1:$GWAY_PORT/api/file.txt" \ - "I am a txt file" - -test_hostname_gateway_response_should_contain \ - "request for {cid}.ipfs.example.com/api/v0/refs returns 404" \ - "$CIDv1.ipfs.example.com" \ - "http://127.0.0.1:$GWAY_PORT/api/v0/refs?arg=${DIR_CID}&r=true" \ - "404 Not Found" - -# disable /api on example.com -ipfs config --json Gateway.PublicGateways '{ - "example.com": { - "UseSubdomains": true, - "Paths": ["/ipfs", "/ipns"] - } -}' || exit 1 -# restart daemon to apply config changes -test_kill_ipfs_daemon -test_launch_ipfs_daemon_without_network - -# not mounted at the root domain -test_hostname_gateway_response_should_contain \ - "request for example.com/api/v0/refs returns 404 if /api not on Paths whitelist" \ - "example.com" \ - "http://127.0.0.1:$GWAY_PORT/api/v0/refs?arg=${DIR_CID}&r=true" \ - "404 Not Found" - -# not mounted on content root subdomains -test_hostname_gateway_response_should_contain \ - "request for {cid}.ipfs.example.com/api returns data if present on the content root" \ - "$DIR_CID.ipfs.example.com" \ - "http://127.0.0.1:$GWAY_PORT/api/file.txt" \ - "I am a txt file" - # DNSLink: .ipns.example.com # (not really useful outside of localhost, as setting TLS for more than one # level of wildcard is a pain, but we support it if someone really wants it) From 23ca62ad2c231fec90ef4ebee67fb562928f6e38 Mon Sep 17 00:00:00 2001 From: Dominic Della Valle Date: Fri, 14 Jul 2023 14:00:59 -0400 Subject: [PATCH 1055/1212] fix: Unix domain socket maddrs used with `NewApi` --- client/rpc/api.go | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/client/rpc/api.go b/client/rpc/api.go index 79d42124a..80a309b91 100644 --- a/client/rpc/api.go +++ b/client/rpc/api.go @@ -5,6 +5,7 @@ import ( "encoding/json" "errors" "fmt" + "net" "net/http" "os" "path/filepath" @@ -98,11 +99,29 @@ func ApiAddr(ipfspath string) (ma.Multiaddr, error) { // NewApi constructs HttpApi with specified endpoint. func NewApi(a ma.Multiaddr) (*HttpApi, error) { + transport := &http.Transport{ + Proxy: http.ProxyFromEnvironment, + DisableKeepAlives: true, + } + + network, address, err := manet.DialArgs(a) + if err != nil { + return nil, err + } + if network == "unix" { + transport.DialContext = func(_ context.Context, _, _ string) (net.Conn, error) { + return net.Dial("unix", address) + } + c := &http.Client{ + Transport: transport, + } + // This will create an API client which + // makes requests to `http://unix`. + return NewURLApiWithClient(network, c) + } + c := &http.Client{ - Transport: &http.Transport{ - Proxy: http.ProxyFromEnvironment, - DisableKeepAlives: true, - }, + Transport: transport, } return NewApiWithClient(a, c) From 5af3cc1c025f55aa7595563c3d1a8b5180b76189 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Sat, 16 Mar 2024 00:59:22 +0100 Subject: [PATCH 1056/1212] docs: updated links and refs to external resources (#10368) --- .github/ISSUE_TEMPLATE/bug-report.yml | 2 +- .github/ISSUE_TEMPLATE/config.yml | 8 ++++---- .github/ISSUE_TEMPLATE/enhancement.yml | 4 ++-- .github/ISSUE_TEMPLATE/feature.yml | 4 ++-- README.md | 23 +++++++++++++++++++++-- cmd/ipfs/dist/README.md | 3 ++- docs/RELEASE_CHECKLIST.md | 2 +- docs/gateway.md | 18 ++++++++++++++++-- docs/http-rpc-clients.md | 5 +++++ docs/windows.md | 2 +- 10 files changed, 55 insertions(+), 16 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug-report.yml b/.github/ISSUE_TEMPLATE/bug-report.yml index 9472db123..b0d0d1f0d 100644 --- a/.github/ISSUE_TEMPLATE/bug-report.yml +++ b/.github/ISSUE_TEMPLATE/bug-report.yml @@ -18,7 +18,7 @@ body: label: Checklist description: Please verify that you've followed these steps options: - - label: This is a bug report, not a question. Ask questions on [discuss.ipfs.io](https://discuss.ipfs.io). + - label: This is a bug report, not a question. Ask questions on [discuss.ipfs.tech](https://discuss.ipfs.tech/c/help/13). required: true - label: I have searched on the [issue tracker](https://github.com/ipfs/kubo/issues?q=is%3Aissue) for my bug. required: true diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index f3f53fe6c..ec985b0bc 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,7 +1,7 @@ blank_issues_enabled: false contact_links: - name: Getting Help on IPFS - url: https://ipfs.io/help + url: https://ipfs.tech/help about: All information about how and where to get help on IPFS. - name: Kubo configuration reference url: https://github.com/ipfs/kubo/blob/master/docs/config.md#readme @@ -9,9 +9,9 @@ contact_links: - name: Kubo experimental features docs url: https://github.com/ipfs/kubo/blob/master/docs/experimental-features.md#readme about: Documentation on Private Networks, Filestore and other experimental features. - - name: RPC API Reference + - name: Kubo RPC API Reference url: https://docs.ipfs.tech/reference/kubo/rpc/ about: Documentation of all Kubo RPC API endpoints. - - name: IPFS Official Forum - url: https://discuss.ipfs.io + - name: IPFS Official Discussion Forum + url: https://discuss.ipfs.tech about: Please post general questions, support requests, and discussions here. diff --git a/.github/ISSUE_TEMPLATE/enhancement.yml b/.github/ISSUE_TEMPLATE/enhancement.yml index 9bfeba5b5..a0b241b55 100644 --- a/.github/ISSUE_TEMPLATE/enhancement.yml +++ b/.github/ISSUE_TEMPLATE/enhancement.yml @@ -6,11 +6,11 @@ body: - type: markdown attributes: value: | - Suggest an enhancement to Kubo (the program). If you'd like to suggest an improvement to the IPFS protocol, please discuss it on [the forum](https://discuss.ipfs.io). + Suggest an enhancement to Kubo (the program). If you'd like to suggest an improvement to the IPFS protocol, please discuss it on [the forum](https://discuss.ipfs.tech). Issues in this repo must be specific, actionable, and well motivated. They should be starting points for _building_ new features, not brainstorming ideas. - If you have an idea you'd like to discuss, please open a new thread on [the forum](https://discuss.ipfs.io). + If you have an idea you'd like to discuss, please open a new thread on [the forum](https://discuss.ipfs.tech). **Example:** diff --git a/.github/ISSUE_TEMPLATE/feature.yml b/.github/ISSUE_TEMPLATE/feature.yml index cf2fa8116..d368588b4 100644 --- a/.github/ISSUE_TEMPLATE/feature.yml +++ b/.github/ISSUE_TEMPLATE/feature.yml @@ -6,11 +6,11 @@ body: - type: markdown attributes: value: | - Suggest a new feature in Kubo (the program). If you'd like to suggest an improvement to the IPFS protocol, please discuss it on [the forum](https://discuss.ipfs.io). + Suggest a new feature in Kubo (the program). If you'd like to suggest an improvement to the IPFS protocol, please discuss it on [the forum](https://discuss.ipfs.tech). Issues in this repo must be specific, actionable, and well motivated. They should be starting points for _building_ new features, not brainstorming ideas. - If you have an idea you'd like to discuss, please open a new thread on [the forum](https://discuss.ipfs.io). + If you have an idea you'd like to discuss, please open a new thread on [the forum](https://discuss.ipfs.tech). **Example:** diff --git a/README.md b/README.md index 74b53c3ad..d2ff46a93 100644 --- a/README.md +++ b/README.md @@ -123,7 +123,24 @@ Official images are published at https://hub.docker.com/r/ipfs/kubo/: [![Docker Image Version (latest semver)](https://img.shields.io/docker/v/ipfs/kubo?color=blue&label=kubo%20docker%20image&logo=docker&sort=semver&style=flat-square&cacheSeconds=3600)](https://hub.docker.com/r/ipfs/kubo/) -More info on how to run Kubo (go-ipfs) inside Docker can be found [here](https://docs.ipfs.tech/how-to/run-ipfs-inside-docker/). +- 🟢 Releases + - `latest` and `release` tags always point at [the latest stable release](https://github.com/ipfs/kubo/releases/latest) + - `vN.N.N` points at a specific [release tag](https://github.com/ipfs/kubo/releases) + - These are production grade images. +- 🟠 We also provide experimental developer builds + - `master-latest` always points at the `HEAD` of the `master` branch + - `master-YYYY-DD-MM-GITSHA` points at a specific commit from the `master` branch + - These tags are used by developers for internal testing, not intended for end users or production use. + +```console +$ docker pull ipfs/kubo:latest +$ docker run --rm -it --net=host ipfs/kubo:latest +``` + +To [customize your node](https://docs.ipfs.tech/install/run-ipfs-inside-docker/#customizing-your-node), +pass necessary config via `-e` or by mounting scripts in the `/container-init.d`. + +Learn more at https://docs.ipfs.tech/install/run-ipfs-inside-docker/ ### Official prebuilt binaries @@ -428,7 +445,9 @@ We ❤️ all [our contributors](docs/AUTHORS); this project wouldn’t be what This repository falls under the IPFS [Code of Conduct](https://github.com/ipfs/community/blob/master/code-of-conduct.md). -Please reach out to us in one [chat](https://docs.ipfs.tech/community/chat/) rooms. +Members of IPFS community provide Kubo support on [discussion forum category here](https://discuss.ipfs.tech/c/help/help-kubo/23). + +Need help with IPFS itself? Learn where to get help and support at https://ipfs.tech/help. ## License diff --git a/cmd/ipfs/dist/README.md b/cmd/ipfs/dist/README.md index 4517f655b..7ff65e9f2 100644 --- a/cmd/ipfs/dist/README.md +++ b/cmd/ipfs/dist/README.md @@ -1,6 +1,7 @@ # ipfs command line tool -This is the [ipfs](http://ipfs.io) command line tool. It contains a full ipfs node. +This is a [command line tool for interacting with Kubo](https://docs.ipfs.tech/install/command-line/), +an [IPFS](https://ipfs.tech) implementation. It contains a full IPFS node. ## Install diff --git a/docs/RELEASE_CHECKLIST.md b/docs/RELEASE_CHECKLIST.md index d9fbd9348..767709db5 100644 --- a/docs/RELEASE_CHECKLIST.md +++ b/docs/RELEASE_CHECKLIST.md @@ -90,7 +90,7 @@ This section covers tasks to be done during each release. - [ ] create and merge the PR which updates `dists/kubo/versions` and `dists/go-ipfs/versions` (![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) and `dists/kubo/current_version` and `dists/go-ipfs/current_version`) - [example](https://github.com/ipfs/distributions/pull/760) - [ ] wait for the [CI](https://github.com/ipfs/distributions/actions/workflows/main.yml) workflow run initiated by the merge to master to finish - - [ ] verify the release is available on [dist.ipfs.io](https://dist.ipfs.io/#kubo) + - [ ] verify the release is available on [dist.ipfs.tech](https://dist.ipfs.tech/#kubo)
- [ ] Publish the release to [NPM](https://www.npmjs.com/package/go-ipfs?activeTab=versions)
using `./kuboreleaser release --version vX.Y.Z(-rcN) publish-to-npm` (⚠️ you might need to run the command a couple of times because GHA might not be able to see the new distribution straight away due to caching) or ... - [ ] run the [Release to npm](https://github.com/ipfs/npm-go-ipfs/actions/workflows/main.yml) workflow diff --git a/docs/gateway.md b/docs/gateway.md index ce849486c..3a616a158 100644 --- a/docs/gateway.md +++ b/docs/gateway.md @@ -13,7 +13,9 @@ Kubo's Gateway implementation follows [ipfs/specs: Specification for HTTP Gatewa By default, Kubo nodes run a [path gateway](https://docs.ipfs.tech/how-to/address-ipfs-on-web/#path-gateway) at `http://127.0.0.1:8080/` and a [subdomain gateway](https://docs.ipfs.tech/how-to/address-ipfs-on-web/#subdomain-gateway) at `http://localhost:8080/`. -Both support [trustless responses](https://docs.ipfs.tech/reference/http/gateway/#trustless-verifiable-retrieval) as opt-in via `Accept` header. + +The path one also implements [trustless gateway spec](https://specs.ipfs.tech/http-gateways/trustless-gateway/) +and supports [trustless responses](https://docs.ipfs.tech/reference/http/gateway/#trustless-verifiable-retrieval) as opt-in via `Accept` header. Additional listening addresses and gateway behaviors can be set in the [config](#configuration) file. @@ -65,7 +67,7 @@ Gateway](https://dnslink.dev/#example-ipfs-gateway) for instructions. When downloading files, browsers will usually guess a file's filename by looking at the last component of the path. Unfortunately, when linking *directly* to a file (with no containing directory), the final component is just a CID -(`Qm...`). This isn't exactly user-friendly. +(`bafy..` or `Qm...`). This isn't exactly user-friendly. To work around this issue, you can add a `filename=some_filename` parameter to your query string to explicitly specify the filename. For example: @@ -89,6 +91,11 @@ or by sending `Accept: application/vnd.ipld.{format}` HTTP header with one of su ## Content-Types +Majority of resources can be retrieved trustlessly by requesting specific content type via `Accept` header or `?format=raw|car|ipns-record` URL query parameter. + +See [trustless gateway specification](https://specs.ipfs.tech/http-gateways/trustless-gateway/) +and [verifiable retrieval documentation](https://docs.ipfs.tech/reference/http/gateway/#trustless-verifiable-retrieval) for more details. + ### `application/vnd.ipld.raw` Returns a byte array for a single `raw` block. @@ -106,3 +113,10 @@ Right now only 'full DAG' implicit selector is implemented. Support for user-provided IPLD selectors is tracked in https://github.com/ipfs/kubo/issues/8769. This is a rough equivalent of `ipfs dag export`. + +### `application/vnd.ipfs.ipns-record` + +Only works on `/ipns/{ipns-name}` content paths that use cryptographically signed [IPNS Records](https://specs.ipfs.tech/ipns/ipns-record/). + +Returns [IPNS Record in Protobuf Serialization Format](https://specs.ipfs.tech/ipns/ipns-record/#record-serialization-format) +which can be verified on end client, without trusting gateway. diff --git a/docs/http-rpc-clients.md b/docs/http-rpc-clients.md index 31448cb86..c53c0b5d0 100644 --- a/docs/http-rpc-clients.md +++ b/docs/http-rpc-clients.md @@ -6,3 +6,8 @@ Kubo provides official HTTP RPC (`/api/v0`) clients for selected languages: |:--------:|:-------------------:|--------------------------------------------| | JS | kubo-rpc-client | https://github.com/ipfs/js-kubo-rpc-client | | Go | `rpc` | [`../client/rpc`](../client/rpc) | + +There are community-maintained libraries for other languages, +but the Kubo team does provide support for them, YMMV: + +- https://docs.ipfs.tech/reference/kubo-rpc-cli/ diff --git a/docs/windows.md b/docs/windows.md index 590f270af..3ed0e4ab2 100644 --- a/docs/windows.md +++ b/docs/windows.md @@ -153,6 +153,6 @@ If you get authentication problems with Git, you might want to take a look at ht `git config --global credential.helper wincred` - **Anything else** -Please search [https://discuss.ipfs.io](https://discuss.ipfs.io/search?q=windows%20category%3A13) for any additional issues you may encounter. If you can't find any existing resolution, feel free to post a question asking for help. +Please search [https://discuss.ipfs.tech](https://discuss.ipfs.tech/search?q=windows%20category%3A13) for any additional issues you may encounter. If you can't find any existing resolution, feel free to post a question asking for help. If you encounter a bug with `kubo` itself (not related to building) please use the [issue tracker](https://github.com/ipfs/kubo/issues) to report it. From 0bdfe9427261580358651ebfeae61db701d7a3ba Mon Sep 17 00:00:00 2001 From: shuangcui Date: Tue, 19 Mar 2024 19:10:34 +0800 Subject: [PATCH 1057/1212] docs: remove repetitive words (#10370) Signed-off-by: shuangcui --- core/commands/name/publish.go | 2 +- core/commands/routing.go | 2 +- docs/changelogs/v0.4.md | 4 ++-- docs/changelogs/v0.5.md | 2 +- test/3nodetest/bin/save_profiling_data.sh | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/core/commands/name/publish.go b/core/commands/name/publish.go index 9c8d837cb..168d7fb44 100644 --- a/core/commands/name/publish.go +++ b/core/commands/name/publish.go @@ -79,7 +79,7 @@ Alternatively, publish an using a valid PeerID (as listed by cmds.StringOption(ttlOptionName, "Time duration hint, akin to --lifetime, indicating how long to cache this record before checking for updates.").WithDefault(ipns.DefaultRecordTTL.String()), cmds.BoolOption(quieterOptionName, "Q", "Write only final IPNS Name encoded as CIDv1 (for use in /ipns content paths)."), cmds.BoolOption(v1compatOptionName, "Produce a backward-compatible IPNS Record by including fields for both V1 and V2 signatures.").WithDefault(true), - cmds.BoolOption(allowOfflineOptionName, "When --offline, save the IPNS record to the the local datastore without broadcasting to the network (instead of failing)."), + cmds.BoolOption(allowOfflineOptionName, "When --offline, save the IPNS record to the local datastore without broadcasting to the network (instead of failing)."), ke.OptionIPNSBase, }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { diff --git a/core/commands/routing.go b/core/commands/routing.go index 2442570ac..3e503b014 100644 --- a/core/commands/routing.go +++ b/core/commands/routing.go @@ -426,7 +426,7 @@ identified by QmFoo. cmds.FileArg("value-file", true, false, "A path to a file containing the value to store.").EnableStdin(), }, Options: []cmds.Option{ - cmds.BoolOption(allowOfflineOptionName, "When offline, save the IPNS record to the the local datastore without broadcasting to the network instead of simply failing."), + cmds.BoolOption(allowOfflineOptionName, "When offline, save the IPNS record to the local datastore without broadcasting to the network instead of simply failing."), }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { api, err := cmdenv.GetApi(env, req) diff --git a/docs/changelogs/v0.4.md b/docs/changelogs/v0.4.md index 5abf5df67..bdc0f004b 100644 --- a/docs/changelogs/v0.4.md +++ b/docs/changelogs/v0.4.md @@ -335,7 +335,7 @@ browsers (see [#4143](https://github.com/ipfs/go-ipfs/issues/4143). #### Human Readable Numbers -The `ipfs bitswap stat` and and `ipfs object stat` commands now support a +The `ipfs bitswap stat` and `ipfs object stat` commands now support a `--humanize` flag that formats numbers with human-readable units (GiB, MiB, etc.). @@ -2114,7 +2114,7 @@ approach: a local IPFS node). To fix the security issue, we intend to switch IPFS gateway links -`https://ipfs.io/ipfs/CID` to to `https://CID.ipfs.dweb.link`. This way, the CID +`https://ipfs.io/ipfs/CID` to `https://CID.ipfs.dweb.link`. This way, the CID will be a part of the ["origin"](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Origin) so each IPFS website will get a separate security origin. diff --git a/docs/changelogs/v0.5.md b/docs/changelogs/v0.5.md index dd154a6b4..aa5f9c957 100644 --- a/docs/changelogs/v0.5.md +++ b/docs/changelogs/v0.5.md @@ -993,7 +993,7 @@ As usual, this release contains several Windows specific fixes and improvements: - fix(dagreader): remove a buggy workaround for a gateway issue ([ipfs/go-unixfs#80](https://github.com/ipfs/go-unixfs/pull/80)) - fix: correctly handle symlink file sizes ([ipfs/go-unixfs#78](https://github.com/ipfs/go-unixfs/pull/78)) - fix: return the correct error from RemoveChild ([ipfs/go-unixfs#76](https://github.com/ipfs/go-unixfs/pull/76)) - - update the the last go-merkledag ([ipfs/go-unixfs#75](https://github.com/ipfs/go-unixfs/pull/75)) + - update the last go-merkledag ([ipfs/go-unixfs#75](https://github.com/ipfs/go-unixfs/pull/75)) - fix: enumerate children ([ipfs/go-unixfs#74](https://github.com/ipfs/go-unixfs/pull/74)) - github.com/ipfs/interface-go-ipfs-core (v0.0.8 -> v0.2.7): - Add pin ls tests for indirect pin traversal and pin type precedence ([ipfs/interface-go-ipfs-core#47](https://github.com/ipfs/interface-go-ipfs-core/pull/47)) diff --git a/test/3nodetest/bin/save_profiling_data.sh b/test/3nodetest/bin/save_profiling_data.sh index 03c0cbabe..639b5d383 100644 --- a/test/3nodetest/bin/save_profiling_data.sh +++ b/test/3nodetest/bin/save_profiling_data.sh @@ -6,7 +6,7 @@ for container in 3nodetest_bootstrap_1 3nodetest_client_1 3nodetest_server_1; do done # since the nodes are executed with the --debug flag, profiling data is written -# to the the working dir. by default, the working dir is /go. +# to the working dir. by default, the working dir is /go. for container in 3nodetest_bootstrap_1 3nodetest_client_1 3nodetest_server_1; do docker cp $container:/go/ipfs.cpuprof build/profiling_data_$container From 8559985d0a5ca827c9170bc7490057020f2227c3 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Mon, 18 Mar 2024 18:39:02 +0100 Subject: [PATCH 1058/1212] chore: finish reframe removal Closes #9479 --- docs/delegated-routing.md | 135 ++------------ .../t0701-delegated-routing-reframe.sh | 171 ------------------ 2 files changed, 12 insertions(+), 294 deletions(-) delete mode 100755 test/sharness/t0701-delegated-routing-reframe.sh diff --git a/docs/delegated-routing.md b/docs/delegated-routing.md index f4207f409..6f15972ed 100644 --- a/docs/delegated-routing.md +++ b/docs/delegated-routing.md @@ -11,8 +11,8 @@ Previously we only used the Amino DHT for content routing and content providing. -Kubo 0.14 introduced experimental support for [delegated routing using Reframe protocol](https://github.com/ipfs/kubo/pull/8997). -Since then, Reframe got deprecated and superseded by [Routing V1 HTTP API](https://specs.ipfs.tech/routing/http-routing-v1/). +Kubo 0.14 introduced experimental support for [delegated routing](https://github.com/ipfs/kubo/pull/8997), +which then got changed and standardized as [Routing V1 HTTP API](https://specs.ipfs.tech/routing/http-routing-v1/). Kubo 0.23.0 release added support for [self-hosting Routing V1 HTTP API server](https://github.com/ipfs/kubo/blob/master/docs/changelogs/v0.23.md#self-hosting-routingv1-endpoint-for-delegated-routing-needs). @@ -42,15 +42,15 @@ The `Routing` configuration section will contain the following keys: #### Routers -`Routers` will be a key-value list of routers that will be available to use. The key is the router name and the value is all the needed configurations for that router. the `Type` will define the routing kind. The main router types will be `reframe` and `dht`, but we will implement two special routers used to execute a set of routers in parallel or sequentially: `parallel` router and `sequential` router. +`Routers` will be a key-value list of routers that will be available to use. The key is the router name and the value is all the needed configurations for that router. the `Type` will define the routing kind. The main router types will be `http` and `dht`, but we will implement two special routers used to execute a set of routers in parallel or sequentially: `parallel` router and `sequential` router. Depending on the routing type, it will use different parameters: -##### Reframe +##### HTTP Params: -- `"Endpoint"`: URL endpoint implementing Reframe protocol. +- `"Endpoint"`: URL of HTTP server with endpoints that implement [Delegated Routing V1 HTTP API](https://specs.ipfs.tech/routing/http-routing-v1/) protocol. ##### Amino DHT @@ -89,10 +89,10 @@ The value will contain: "Routing": { "Type": "custom", "Routers": { - "storetheindex": { - "Type": "reframe", + "http-delegated": { + "Type": "http", "Parameters": { - "Endpoint": "https://cid.contact/reframe" + "Endpoint": "https://delegated-ipfs.dev" // /routing/v1 (https://specs.ipfs.tech/routing/http-routing-v1/) } }, "dht-lan": { @@ -123,7 +123,7 @@ The value will contain: "RouterName": "dht-wan" }, { - "RouterName": "storetheindex" + "RouterName": "http-delegated" } ] } @@ -142,7 +142,7 @@ The value will contain: "Timeout": "100ms" }, { - "RouterName": "storetheindex", + "RouterName": "http-delegated", "ExecuteAfter": "100ms" } ] @@ -161,7 +161,7 @@ The value will contain: "Timeout": "300ms" }, { - "RouterName": "storetheindex", + "RouterName": "http-delegated", "Timeout": "300ms" } ] @@ -178,7 +178,7 @@ The value will contain: "RouterName": "dht-wan" }, { - "RouterName": "storetheindex" + "RouterName": "http-delegated" } ] } @@ -201,75 +201,6 @@ The value will contain: } ``` -Added YAML for clarity: - -```yaml ---- -Type: custom -Routers: - storetheindex: - Type: reframe - Parameters: - Endpoint: https://cid.contact/reframe - dht-lan: - Type: dht - Parameters: - Mode: server - PublicIPNetwork: false - AcceleratedDHTClient: false - dht-wan: - Type: dht - Parameters: - Mode: auto - PublicIPNetwork: true - AcceleratedDHTClient: false - find-providers-router: - Type: parallel - Parameters: - Routers: - - RouterName: dht-lan - IgnoreErrors: true - - RouterName: dht-wan - - RouterName: storetheindex - provide-router: - Type: parallel - Parameters: - Routers: - - RouterName: dht-lan - IgnoreErrors: true - - RouterName: dht-wan - ExecuteAfter: 100ms - Timeout: 100ms - - RouterName: storetheindex - ExecuteAfter: 100ms - get-ipns-router: - Type: sequential - Parameters: - Routers: - - RouterName: dht-lan - IgnoreErrors: true - - RouterName: dht-wan - Timeout: 300ms - - RouterName: storetheindex - Timeout: 300ms - put-ipns-router: - Type: parallel - Parameters: - Routers: - - RouterName: dht-lan - - RouterName: dht-wan - - RouterName: storetheindex -Methods: - find-providers: - RouterName: find-providers-router - provide: - RouterName: provide-router - get-ipns: - RouterName: get-ipns-router - put-ipns: - RouterName: put-ipns-router -``` - ### Error cases - If any of the routers fails, the output will be an error by default. - You can use `IgnoreErrors:true` to ignore errors for a specific router output @@ -402,48 +333,6 @@ As test fixtures we can add different use cases here and see how the configurati } } ``` -YAML representation for clarity: - -```yaml ---- -Type: custom -Routers: - dht-lan: - Type: dht - Parameters: - Mode: server - PublicIPNetwork: false - dht-wan: - Type: dht - Parameters: - Mode: auto - PublicIPNetwork: true - parallel-dht-strict: - Type: parallel - Parameters: - Routers: - - RouterName: dht-lan - - RouterName: dht-wan - parallel-dht: - Type: parallel - Parameters: - Routers: - - RouterName: dht-lan - IgnoreError: true - - RouterName: dht-wan -Methods: - provide: - RouterName: dht-wan - find-providers: - RouterName: parallel-dht-strict - find-peers: - RouterName: parallel-dht-strict - get-ipns: - RouterName: parallel-dht - put-ipns: - RouterName: parallel-dht - -``` ### Compatibility diff --git a/test/sharness/t0701-delegated-routing-reframe.sh b/test/sharness/t0701-delegated-routing-reframe.sh deleted file mode 100755 index 5070b4fff..000000000 --- a/test/sharness/t0701-delegated-routing-reframe.sh +++ /dev/null @@ -1,171 +0,0 @@ -#!/usr/bin/env bash - -test_description="Test delegated routing via reframe endpoint" - -. lib/test-lib.sh - -if ! test_have_prereq SOCAT; then - skip_all="skipping '$test_description': socat is not available" - test_done -fi - -# simple reframe server mock -# local endpoint responds with deterministic application/vnd.ipfs.rpc+dag-json; version=1 -REFRAME_PORT=5098 -function start_reframe_mock_endpoint() { - REMOTE_SERVER_LOG="reframe-server.log" - rm -f $REMOTE_SERVER_LOG - - touch response - socat tcp-listen:$REFRAME_PORT,fork,bind=127.0.0.1,reuseaddr 'SYSTEM:cat response'!!CREATE:$REMOTE_SERVER_LOG & - REMOTE_SERVER_PID=$! - - socat /dev/null tcp:127.0.0.1:$REFRAME_PORT,retry=10 - return $? -} -function serve_reframe_response() { - local body=$1 - local status_code=${2:-"200 OK"} - local length=$((1 + ${#body})) - echo -e "HTTP/1.1 $status_code\nContent-Type: application/vnd.ipfs.rpc+dag-json; version=1\nContent-Length: $length\n\n$body" > response -} -function stop_reframe_mock_endpoint() { - exec 7<&- - kill $REMOTE_SERVER_PID > /dev/null 2>&1 - wait $REMOTE_SERVER_PID || true -} - -# daemon running in online mode to ensure Pin.origins/PinStatus.delegates work -test_init_ipfs - -# based on static, synthetic reframe messages: -# t0701-delegated-routing-reframe/FindProvidersRequest -# t0701-delegated-routing-reframe/FindProvidersResponse -FINDPROV_CID="bafybeigvgzoolc3drupxhlevdp2ugqcrbcsqfmcek2zxiw5wctk3xjpjwy" -EXPECTED_PROV="QmQzqxhK82kAmKvARFZSkUVS6fo9sySaiogAnx5EnZ6ZmC" - -test_expect_success "default Routing config has no Routers defined" ' - echo null > expected && - ipfs config show | jq .Routing.Routers > actual && - test_cmp expected actual -' - -# turn off all implicit routers -ipfs config Routing.Type none || exit 1 -test_launch_ipfs_daemon -test_expect_success "disabling default router (dht) works" ' - ipfs config Routing.Type > actual && - echo none > expected && - test_cmp expected actual -' -test_expect_success "no routers means findprovs returns no results" ' - ipfs routing findprovs "$FINDPROV_CID" > actual && - echo -n > expected && - test_cmp expected actual -' - -test_kill_ipfs_daemon - -ipfs config Routing.Type --json '"custom"' || exit 1 -ipfs config Routing.Methods --json '{ - "find-peers": { - "RouterName": "TestDelegatedRouter" - }, - "find-providers": { - "RouterName": "TestDelegatedRouter" - }, - "get-ipns": { - "RouterName": "TestDelegatedRouter" - }, - "provide": { - "RouterName": "TestDelegatedRouter" - } - }' || exit 1 - -test_expect_success "missing method params makes daemon fails" ' - echo "Error: constructing the node (see log for full detail): method name \"put-ipns\" is missing from Routing.Methods config param" > expected_error && - GOLOG_LOG_LEVEL=fatal ipfs daemon 2> actual_error || exit 0 && - test_cmp expected_error actual_error -' - -ipfs config Routing.Methods --json '{ - "find-peers": { - "RouterName": "TestDelegatedRouter" - }, - "find-providers": { - "RouterName": "TestDelegatedRouter" - }, - "get-ipns": { - "RouterName": "TestDelegatedRouter" - }, - "provide": { - "RouterName": "TestDelegatedRouter" - }, - "put-ipns": { - "RouterName": "TestDelegatedRouter" - }, - "NOT_SUPPORTED": { - "RouterName": "TestDelegatedRouter" - } - }' || exit 1 - -test_expect_success "having wrong methods makes daemon fails" ' - echo "Error: constructing the node (see log for full detail): method name \"NOT_SUPPORTED\" is not a supported method on Routing.Methods config param" > expected_error && - GOLOG_LOG_LEVEL=fatal ipfs daemon 2> actual_error || exit 0 && - test_cmp expected_error actual_error -' - -# set Routing config to only use delegated routing via mocked reframe endpoint - -ipfs config Routing.Type --json '"custom"' || exit 1 -ipfs config Routing.Routers.TestDelegatedRouter --json '{ - "Type": "reframe", - "Parameters": { - "Endpoint": "http://127.0.0.1:5098/reframe" - } -}' || exit 1 -ipfs config Routing.Methods --json '{ - "find-peers": { - "RouterName": "TestDelegatedRouter" - }, - "find-providers": { - "RouterName": "TestDelegatedRouter" - }, - "get-ipns": { - "RouterName": "TestDelegatedRouter" - }, - "provide": { - "RouterName": "TestDelegatedRouter" - }, - "put-ipns": { - "RouterName": "TestDelegatedRouter" - } - }' || exit 1 - -test_expect_success "adding reframe endpoint to Routing.Routers config works" ' - echo "http://127.0.0.1:5098/reframe" > expected && - ipfs config Routing.Routers.TestDelegatedRouter.Parameters.Endpoint > actual && - test_cmp expected actual -' - -test_launch_ipfs_daemon - -test_expect_success "start_reframe_mock_endpoint" ' - start_reframe_mock_endpoint -' - -test_expect_success "'ipfs routing findprovs' returns result from delegated reframe router" ' - serve_reframe_response "$(<../t0701-delegated-routing-reframe/FindProvidersResponse)" && - echo "$EXPECTED_PROV" > expected && - ipfs routing findprovs "$FINDPROV_CID" > actual && - test_cmp expected actual -' - -test_expect_success "stop_reframe_mock_endpoint" ' - stop_reframe_mock_endpoint -' - - -test_kill_ipfs_daemon -test_done -# vim: ts=2 sw=2 sts=2 et: From 9a5f5e7352656644ccea11da5d0dccc3b4160e0f Mon Sep 17 00:00:00 2001 From: Marco Munizaga Date: Tue, 19 Mar 2024 04:26:20 -0700 Subject: [PATCH 1059/1212] chore: cleanup old workaround (#10369) --- cmd/ipfs/kubo/daemon.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/cmd/ipfs/kubo/daemon.go b/cmd/ipfs/kubo/daemon.go index b966a630e..0fcd0e556 100644 --- a/cmd/ipfs/kubo/daemon.go +++ b/cmd/ipfs/kubo/daemon.go @@ -930,10 +930,6 @@ func serveTrustlessGatewayOverLibp2p(cctx *oldcmds.Context) (<-chan error, error StreamHost: node.PeerHost, } - tmpProtocol := protocol.ID("/kubo/delete-me") - h.SetHTTPHandler(tmpProtocol, http.NotFoundHandler()) - h.WellKnownHandler.RemoveProtocolMeta(tmpProtocol) - h.WellKnownHandler.AddProtocolMeta(gatewayProtocolID, p2phttp.ProtocolMeta{Path: "/"}) h.ServeMux = http.NewServeMux() h.ServeMux.Handle("/", handler) From a3483e352e336cfa7cfa714ecdcd7e6a0a82ee03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Mur=C3=A9?= Date: Fri, 20 Oct 2023 16:24:39 +0200 Subject: [PATCH 1060/1212] coreapi/unixfs: don't create an additional IpfsNode for --only-hash --- core/coreapi/unixfs.go | 59 ++++++++++++------------------------------ core/node/builder.go | 16 +----------- core/node/groups.go | 2 +- core/node/storage.go | 11 +++----- 4 files changed, 22 insertions(+), 66 deletions(-) diff --git a/core/coreapi/unixfs.go b/core/coreapi/unixfs.go index 452e6017b..860574945 100644 --- a/core/coreapi/unixfs.go +++ b/core/coreapi/unixfs.go @@ -3,14 +3,6 @@ package coreapi import ( "context" "fmt" - "sync" - - "github.com/ipfs/kubo/core" - "github.com/ipfs/kubo/tracing" - "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/trace" - - "github.com/ipfs/kubo/core/coreunix" blockservice "github.com/ipfs/boxo/blockservice" bstore "github.com/ipfs/boxo/blockstore" @@ -21,41 +13,23 @@ import ( ft "github.com/ipfs/boxo/ipld/unixfs" unixfile "github.com/ipfs/boxo/ipld/unixfs/file" uio "github.com/ipfs/boxo/ipld/unixfs/io" - mfs "github.com/ipfs/boxo/mfs" + "github.com/ipfs/boxo/mfs" "github.com/ipfs/boxo/path" cid "github.com/ipfs/go-cid" cidutil "github.com/ipfs/go-cidutil" + ds "github.com/ipfs/go-datastore" + dssync "github.com/ipfs/go-datastore/sync" ipld "github.com/ipfs/go-ipld-format" coreiface "github.com/ipfs/kubo/core/coreiface" options "github.com/ipfs/kubo/core/coreiface/options" + "github.com/ipfs/kubo/core/coreunix" + "github.com/ipfs/kubo/tracing" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/trace" ) type UnixfsAPI CoreAPI -var ( - nilNode *core.IpfsNode - once sync.Once -) - -func getOrCreateNilNode() (*core.IpfsNode, error) { - once.Do(func() { - if nilNode != nil { - return - } - node, err := core.NewNode(context.Background(), &core.BuildCfg{ - // TODO: need this to be true or all files - // hashed will be stored in memory! - NilRepo: true, - }) - if err != nil { - panic(err) - } - nilNode = node - }) - - return nilNode, nil -} - // Add builds a merkledag node from a reader, adds it to the blockstore, // and returns the key representing that node. func (api *UnixfsAPI) Add(ctx context.Context, files files.Node, opts ...options.UnixfsAddOption) (path.ImmutablePath, error) { @@ -108,13 +82,12 @@ func (api *UnixfsAPI) Add(ctx context.Context, files files.Node, opts ...options pinning := api.pinning if settings.OnlyHash { - node, err := getOrCreateNilNode() - if err != nil { - return path.ImmutablePath{}, err - } - addblockstore = node.Blockstore - exch = node.Exchange - pinning = node.Pinning + // setup a /dev/null pipeline to simulate adding the data + dstore := dssync.MutexWrap(ds.NewNullDatastore()) + bs := bstore.NewBlockstore(dstore, bstore.WriteThrough()) + addblockstore = bstore.NewGCBlockstore(bs, nil) // gclocker will never be used + exch = nil // exchange will never be used + pinning = nil // pinner will never be used } bserv := blockservice.New(addblockstore, exch) // hash security 001 @@ -133,11 +106,11 @@ func (api *UnixfsAPI) Add(ctx context.Context, files files.Node, opts ...options syncDserv = &syncDagService{ DAGService: dserv, syncFn: func() error { - ds := api.repo.Datastore() - if err := ds.Sync(ctx, bstore.BlockPrefix); err != nil { + rds := api.repo.Datastore() + if err := rds.Sync(ctx, bstore.BlockPrefix); err != nil { return err } - return ds.Sync(ctx, filestore.FilestorePrefix) + return rds.Sync(ctx, filestore.FilestorePrefix) }, } } diff --git a/core/node/builder.go b/core/node/builder.go index 57fa20945..411e3228c 100644 --- a/core/node/builder.go +++ b/core/node/builder.go @@ -4,7 +4,6 @@ import ( "context" "crypto/rand" "encoding/base64" - "errors" "go.uber.org/fx" @@ -34,9 +33,6 @@ type BuildCfg struct { // DO NOT SET THIS UNLESS YOU'RE TESTING. DisableEncryptedConnections bool - // If NilRepo is set, a Repo backed by a nil datastore will be constructed - NilRepo bool - Routing libp2p.RoutingOption Host libp2p.HostOption Repo repo.Repo @@ -51,18 +47,8 @@ func (cfg *BuildCfg) getOpt(key string) bool { } func (cfg *BuildCfg) fillDefaults() error { - if cfg.Repo != nil && cfg.NilRepo { - return errors.New("cannot set a Repo and specify nilrepo at the same time") - } - if cfg.Repo == nil { - var d ds.Datastore - if cfg.NilRepo { - d = ds.NewNullDatastore() - } else { - d = ds.NewMapDatastore() - } - r, err := defaultRepo(dsync.MutexWrap(d)) + r, err := defaultRepo(dsync.MutexWrap(ds.NewMapDatastore())) if err != nil { return err } diff --git a/core/node/groups.go b/core/node/groups.go index 061087c27..c0270bbe1 100644 --- a/core/node/groups.go +++ b/core/node/groups.go @@ -178,7 +178,7 @@ func Storage(bcfg *BuildCfg, cfg *config.Config) fx.Option { return fx.Options( fx.Provide(RepoConfig), fx.Provide(Datastore), - fx.Provide(BaseBlockstoreCtor(cacheOpts, bcfg.NilRepo, cfg.Datastore.HashOnRead)), + fx.Provide(BaseBlockstoreCtor(cacheOpts, cfg.Datastore.HashOnRead)), finalBstore, ) } diff --git a/core/node/storage.go b/core/node/storage.go index 782ff58f0..a303ddc23 100644 --- a/core/node/storage.go +++ b/core/node/storage.go @@ -27,17 +27,14 @@ func Datastore(repo repo.Repo) datastore.Datastore { type BaseBlocks blockstore.Blockstore // BaseBlockstoreCtor creates cached blockstore backed by the provided datastore -func BaseBlockstoreCtor(cacheOpts blockstore.CacheOpts, nilRepo bool, hashOnRead bool) func(mctx helpers.MetricsCtx, repo repo.Repo, lc fx.Lifecycle) (bs BaseBlocks, err error) { +func BaseBlockstoreCtor(cacheOpts blockstore.CacheOpts, hashOnRead bool) func(mctx helpers.MetricsCtx, repo repo.Repo, lc fx.Lifecycle) (bs BaseBlocks, err error) { return func(mctx helpers.MetricsCtx, repo repo.Repo, lc fx.Lifecycle) (bs BaseBlocks, err error) { // hash security bs = blockstore.NewBlockstore(repo.Datastore()) bs = &verifbs.VerifBS{Blockstore: bs} - - if !nilRepo { - bs, err = blockstore.CachedBlockstore(helpers.LifecycleCtx(mctx, lc), bs, cacheOpts) - if err != nil { - return nil, err - } + bs, err = blockstore.CachedBlockstore(helpers.LifecycleCtx(mctx, lc), bs, cacheOpts) + if err != nil { + return nil, err } bs = blockstore.NewIdStore(bs) From 21728eb0002ae7f79b52af7a48142330b3da81a0 Mon Sep 17 00:00:00 2001 From: Daniel Norman <1992255+2color@users.noreply.github.com> Date: Tue, 19 Mar 2024 13:28:47 +0100 Subject: [PATCH 1061/1212] docs: update default ipns lifetime --- docs/config.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/config.md b/docs/config.md index ca24c2d0f..0fa5000ac 100644 --- a/docs/config.md +++ b/docs/config.md @@ -1130,7 +1130,7 @@ Type: `interval` or an empty string for the default. A time duration specifying the value to set on ipns records for their validity lifetime. -Default: 24 hours. +Default: 48 hours. Type: `interval` or an empty string for the default. From 9047fed8d5c3b6935c9a2358de2689451fcb7047 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Fri, 22 Mar 2024 09:32:30 +0100 Subject: [PATCH 1062/1212] core/commands!: remove deprecated object APIs (#10375) --- assets/assets.go | 24 +- bin/ipns-republish | 2 +- client/rpc/object.go | 172 ------ core/commands/commands_test.go | 5 + core/commands/dht.go | 18 +- core/commands/object/object.go | 540 +----------------- core/commands/object/patch.go | 116 +--- core/coreapi/object.go | 263 --------- core/coreiface/object.go | 49 -- core/coreiface/options/object.go | 90 --- core/coreiface/tests/object.go | 463 +++------------ core/coreiface/tests/unixfs.go | 20 +- docs/changelogs/v0.28.md | 5 + docs/implement-api-bindings.md | 5 +- test/cli/basic_commands_test.go | 3 - .../testPut.pb | 0 test/sharness/t0050-block.sh | 22 +- .../sharness/t0051-object-data/UTF-8-test.txt | Bin 20350 -> 0 bytes .../sharness/t0051-object-data/brokenPut.json | 5 - test/sharness/t0051-object-data/brokenPut.xml | 1 - .../t0051-object-data/expected_getOut | 1 - test/sharness/t0051-object-data/mixed.json | 5 - test/sharness/t0051-object-data/testPut.json | 3 - test/sharness/t0051-object-data/testPut.xml | 1 - test/sharness/t0051-object.sh | 363 +----------- test/sharness/t0081-repo-pinning.sh | 6 +- test/sharness/t0090-get.sh | 6 +- test/sharness/t0252-files-gc.sh | 4 +- 28 files changed, 161 insertions(+), 2031 deletions(-) rename test/sharness/{t0051-object-data => t0050-block-data}/testPut.pb (100%) delete mode 100644 test/sharness/t0051-object-data/UTF-8-test.txt delete mode 100644 test/sharness/t0051-object-data/brokenPut.json delete mode 100644 test/sharness/t0051-object-data/brokenPut.xml delete mode 100644 test/sharness/t0051-object-data/expected_getOut delete mode 100644 test/sharness/t0051-object-data/mixed.json delete mode 100644 test/sharness/t0051-object-data/testPut.json delete mode 100644 test/sharness/t0051-object-data/testPut.xml diff --git a/assets/assets.go b/assets/assets.go index 17bfa8941..6196ed22f 100644 --- a/assets/assets.go +++ b/assets/assets.go @@ -9,9 +9,7 @@ import ( "github.com/ipfs/kubo/core/coreapi" "github.com/ipfs/boxo/files" - "github.com/ipfs/boxo/path" cid "github.com/ipfs/go-cid" - options "github.com/ipfs/kubo/core/coreiface/options" ) //go:embed init-doc @@ -39,12 +37,7 @@ func addAssetList(nd *core.IpfsNode, l []string) (cid.Cid, error) { return cid.Cid{}, err } - dirb, err := api.Object().New(nd.Context(), options.Object.Type("unixfs-dir")) - if err != nil { - return cid.Cid{}, err - } - - basePath := path.FromCid(dirb.Cid()) + dirMap := map[string]files.Node{} for _, p := range l { d, err := Asset.ReadFile(p) @@ -52,17 +45,12 @@ func addAssetList(nd *core.IpfsNode, l []string) (cid.Cid, error) { return cid.Cid{}, fmt.Errorf("assets: could load Asset '%s': %s", p, err) } - fp, err := api.Unixfs().Add(nd.Context(), files.NewBytesFile(d)) - if err != nil { - return cid.Cid{}, err - } + dirMap[gopath.Base(p)] = files.NewBytesFile(d) + } - fname := gopath.Base(p) - - basePath, err = api.Object().AddLink(nd.Context(), basePath, fname, fp) - if err != nil { - return cid.Cid{}, err - } + basePath, err := api.Unixfs().Add(nd.Context(), files.NewMapDirectory(dirMap)) + if err != nil { + return cid.Cid{}, err } if err := api.Pin().Add(nd.Context(), basePath); err != nil { diff --git a/bin/ipns-republish b/bin/ipns-republish index f5535ee4c..5fc81cd57 100755 --- a/bin/ipns-republish +++ b/bin/ipns-republish @@ -19,7 +19,7 @@ if [ $? -ne 0 ]; then fi # check the object is there -ipfs object stat "$1" >/dev/null +ipfs dag stat "$1" >/dev/null if [ $? -ne 0 ]; then echo "error: ipfs cannot find $1" exit 1 diff --git a/client/rpc/object.go b/client/rpc/object.go index 9e00bfb77..5c9d323e8 100644 --- a/client/rpc/object.go +++ b/client/rpc/object.go @@ -1,16 +1,10 @@ package rpc import ( - "bytes" "context" - "fmt" - "io" - "github.com/ipfs/boxo/ipld/merkledag" - ft "github.com/ipfs/boxo/ipld/unixfs" "github.com/ipfs/boxo/path" "github.com/ipfs/go-cid" - ipld "github.com/ipfs/go-ipld-format" iface "github.com/ipfs/kubo/core/coreiface" caopts "github.com/ipfs/kubo/core/coreiface/options" ) @@ -21,138 +15,6 @@ type objectOut struct { Hash string } -func (api *ObjectAPI) New(ctx context.Context, opts ...caopts.ObjectNewOption) (ipld.Node, error) { - options, err := caopts.ObjectNewOptions(opts...) - if err != nil { - return nil, err - } - - var n ipld.Node - switch options.Type { - case "empty": - n = new(merkledag.ProtoNode) - case "unixfs-dir": - n = ft.EmptyDirNode() - default: - return nil, fmt.Errorf("unknown object type: %s", options.Type) - } - - return n, nil -} - -func (api *ObjectAPI) Put(ctx context.Context, r io.Reader, opts ...caopts.ObjectPutOption) (path.ImmutablePath, error) { - options, err := caopts.ObjectPutOptions(opts...) - if err != nil { - return path.ImmutablePath{}, err - } - - var out objectOut - err = api.core().Request("object/put"). - Option("inputenc", options.InputEnc). - Option("datafieldenc", options.DataType). - Option("pin", options.Pin). - FileBody(r). - Exec(ctx, &out) - if err != nil { - return path.ImmutablePath{}, err - } - - c, err := cid.Parse(out.Hash) - if err != nil { - return path.ImmutablePath{}, err - } - - return path.FromCid(c), nil -} - -func (api *ObjectAPI) Get(ctx context.Context, p path.Path) (ipld.Node, error) { - r, err := api.core().Block().Get(ctx, p) - if err != nil { - return nil, err - } - b, err := io.ReadAll(r) - if err != nil { - return nil, err - } - - return merkledag.DecodeProtobuf(b) -} - -func (api *ObjectAPI) Data(ctx context.Context, p path.Path) (io.Reader, error) { - resp, err := api.core().Request("object/data", p.String()).Send(ctx) - if err != nil { - return nil, err - } - if resp.Error != nil { - return nil, resp.Error - } - - // TODO: make Data return ReadCloser to avoid copying - defer resp.Close() - b := new(bytes.Buffer) - if _, err := io.Copy(b, resp.Output); err != nil { - return nil, err - } - - return b, nil -} - -func (api *ObjectAPI) Links(ctx context.Context, p path.Path) ([]*ipld.Link, error) { - var out struct { - Links []struct { - Name string - Hash string - Size uint64 - } - } - if err := api.core().Request("object/links", p.String()).Exec(ctx, &out); err != nil { - return nil, err - } - res := make([]*ipld.Link, len(out.Links)) - for i, l := range out.Links { - c, err := cid.Parse(l.Hash) - if err != nil { - return nil, err - } - - res[i] = &ipld.Link{ - Cid: c, - Name: l.Name, - Size: l.Size, - } - } - - return res, nil -} - -func (api *ObjectAPI) Stat(ctx context.Context, p path.Path) (*iface.ObjectStat, error) { - var out struct { - Hash string - NumLinks int - BlockSize int - LinksSize int - DataSize int - CumulativeSize int - } - if err := api.core().Request("object/stat", p.String()).Exec(ctx, &out); err != nil { - return nil, err - } - - c, err := cid.Parse(out.Hash) - if err != nil { - return nil, err - } - - return &iface.ObjectStat{ - Cid: c, - NumLinks: out.NumLinks, - BlockSize: out.BlockSize, - LinksSize: out.LinksSize, - DataSize: out.DataSize, - CumulativeSize: out.CumulativeSize, - }, nil -} - func (api *ObjectAPI) AddLink(ctx context.Context, base path.Path, name string, child path.Path, opts ...caopts.ObjectAddLinkOption) (path.ImmutablePath, error) { options, err := caopts.ObjectAddLinkOptions(opts...) if err != nil { @@ -191,40 +53,6 @@ func (api *ObjectAPI) RmLink(ctx context.Context, base path.Path, link string) ( return path.FromCid(c), nil } -func (api *ObjectAPI) AppendData(ctx context.Context, p path.Path, r io.Reader) (path.ImmutablePath, error) { - var out objectOut - err := api.core().Request("object/patch/append-data", p.String()). - FileBody(r). - Exec(ctx, &out) - if err != nil { - return path.ImmutablePath{}, err - } - - c, err := cid.Parse(out.Hash) - if err != nil { - return path.ImmutablePath{}, err - } - - return path.FromCid(c), nil -} - -func (api *ObjectAPI) SetData(ctx context.Context, p path.Path, r io.Reader) (path.ImmutablePath, error) { - var out objectOut - err := api.core().Request("object/patch/set-data", p.String()). - FileBody(r). - Exec(ctx, &out) - if err != nil { - return path.ImmutablePath{}, err - } - - c, err := cid.Parse(out.Hash) - if err != nil { - return path.ImmutablePath{}, err - } - - return path.FromCid(c), nil -} - type change struct { Type iface.ChangeType Path string diff --git a/core/commands/commands_test.go b/core/commands/commands_test.go index 9e4da274c..38172fd66 100644 --- a/core/commands/commands_test.go +++ b/core/commands/commands_test.go @@ -61,6 +61,11 @@ func TestCommands(t *testing.T) { "/dag/stat", "/dht", "/dht/query", + "/dht/findprovs", + "/dht/findpeer", + "/dht/get", + "/dht/provide", + "/dht/put", "/routing", "/routing/put", "/routing/get", diff --git a/core/commands/dht.go b/core/commands/dht.go index c86b6262f..1d4620181 100644 --- a/core/commands/dht.go +++ b/core/commands/dht.go @@ -15,13 +15,19 @@ import ( var ErrNotDHT = errors.New("routing service is not a DHT") var DhtCmd = &cmds.Command{ + Status: cmds.Deprecated, Helptext: cmds.HelpText{ Tagline: "Issue commands directly through the DHT.", ShortDescription: ``, }, Subcommands: map[string]*cmds.Command{ - "query": queryDhtCmd, + "query": queryDhtCmd, + "findprovs": RemovedDHTCmd, + "findpeer": RemovedDHTCmd, + "get": RemovedDHTCmd, + "put": RemovedDHTCmd, + "provide": RemovedDHTCmd, }, } @@ -32,6 +38,7 @@ type kademlia interface { } var queryDhtCmd = &cmds.Command{ + Status: cmds.Deprecated, Helptext: cmds.HelpText{ Tagline: "Find the closest Peer IDs to a given Peer ID by querying the DHT.", ShortDescription: "Outputs a list of newline-delimited Peer IDs.", @@ -114,3 +121,12 @@ var queryDhtCmd = &cmds.Command{ }, Type: routing.QueryEvent{}, } +var RemovedDHTCmd = &cmds.Command{ + Status: cmds.Removed, + Helptext: cmds.HelpText{ + Tagline: "Removed, use 'ipfs routing' instead.", + }, + Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { + return errors.New("removed, use 'ipfs routing' instead") + }, +} diff --git a/core/commands/object/object.go b/core/commands/object/object.go index 5a8577cf2..380ca2533 100644 --- a/core/commands/object/object.go +++ b/core/commands/object/object.go @@ -1,28 +1,11 @@ package objectcmd import ( - "encoding/base64" "errors" - "fmt" - "io" - "text/tabwriter" cmds "github.com/ipfs/go-ipfs-cmds" - "github.com/ipfs/kubo/core/commands/cmdenv" - "github.com/ipfs/kubo/core/commands/cmdutils" - - humanize "github.com/dustin/go-humanize" - dag "github.com/ipfs/boxo/ipld/merkledag" - "github.com/ipfs/go-cid" - ipld "github.com/ipfs/go-ipld-format" - "github.com/ipfs/kubo/core/coreiface/options" ) -type Node struct { - Links []Link - Data string -} - type Link struct { Name, Hash string Size uint64 @@ -35,16 +18,6 @@ type Object struct { var ErrDataEncoding = errors.New("unknown data field encoding") -const ( - headersOptionName = "headers" - encodingOptionName = "data-encoding" - inputencOptionName = "inputenc" - datafieldencOptionName = "datafieldenc" - pinOptionName = "pin" - quietOptionName = "quiet" - humanOptionName = "human" -) - var ObjectCmd = &cmds.Command{ Status: cmds.Deprecated, // https://github.com/ipfs/kubo/issues/7936 Helptext: cmds.HelpText{ @@ -55,516 +28,23 @@ directly. Deprecated, use more modern 'ipfs dag' and 'ipfs files' instead.`, }, Subcommands: map[string]*cmds.Command{ - "data": ObjectDataCmd, + "data": RemovedObjectCmd, "diff": ObjectDiffCmd, - "get": ObjectGetCmd, - "links": ObjectLinksCmd, - "new": ObjectNewCmd, + "get": RemovedObjectCmd, + "links": RemovedObjectCmd, + "new": RemovedObjectCmd, "patch": ObjectPatchCmd, - "put": ObjectPutCmd, - "stat": ObjectStatCmd, + "put": RemovedObjectCmd, + "stat": RemovedObjectCmd, }, } -// ObjectDataCmd object data command -var ObjectDataCmd = &cmds.Command{ - Status: cmds.Deprecated, // https://github.com/ipfs/kubo/issues/7936 +var RemovedObjectCmd = &cmds.Command{ + Status: cmds.Removed, Helptext: cmds.HelpText{ - Tagline: "Deprecated way to read the raw bytes of a dag-pb object: use 'dag get' instead.", - ShortDescription: ` -'ipfs object data' is a deprecated plumbing command for retrieving the raw -bytes stored in a dag-pb node. It outputs to stdout, and is a base58 -encoded multihash. Provided for legacy reasons. Use 'ipfs dag get' instead. -`, - LongDescription: ` -'ipfs object data' is a deprecated plumbing command for retrieving the raw -bytes stored in a dag-pb node. It outputs to stdout, and is a base58 -encoded multihash. Provided for legacy reasons. Use 'ipfs dag get' instead. - -Note that the "--encoding" option does not affect the output, since the output -is the raw data of the object. -`, - }, - - Arguments: []cmds.Argument{ - cmds.StringArg("key", true, false, "Key of the object to retrieve, in base58-encoded multihash format.").EnableStdin(), + Tagline: "Removed, use 'ipfs dag' or 'ipfs files' instead.", }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - api, err := cmdenv.GetApi(env, req) - if err != nil { - return err - } - - path, err := cmdutils.PathOrCidPath(req.Arguments[0]) - if err != nil { - return err - } - - data, err := api.Object().Data(req.Context, path) - if err != nil { - return err - } - - return res.Emit(data) + return errors.New("removed, use 'ipfs dag' or 'ipfs files' instead") }, } - -// ObjectLinksCmd object links command -var ObjectLinksCmd = &cmds.Command{ - Status: cmds.Deprecated, // https://github.com/ipfs/kubo/issues/7936 - Helptext: cmds.HelpText{ - Tagline: "Deprecated way to output links in the specified dag-pb object: use 'dag get' instead.", - ShortDescription: ` -'ipfs object links' is a plumbing command for retrieving the links from -a dag-pb node. It outputs to stdout, and is a base58 encoded -multihash. Provided for legacy reasons. Use 'ipfs dag get' instead. -`, - }, - - Arguments: []cmds.Argument{ - cmds.StringArg("key", true, false, "Key of the dag-pb object to retrieve, in base58-encoded multihash format.").EnableStdin(), - }, - Options: []cmds.Option{ - cmds.BoolOption(headersOptionName, "v", "Print table headers (Hash, Size, Name)."), - }, - Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - api, err := cmdenv.GetApi(env, req) - if err != nil { - return err - } - - enc, err := cmdenv.GetLowLevelCidEncoder(req) - if err != nil { - return err - } - - path, err := cmdutils.PathOrCidPath(req.Arguments[0]) - if err != nil { - return err - } - - rp, _, err := api.ResolvePath(req.Context, path) - if err != nil { - return err - } - - links, err := api.Object().Links(req.Context, rp) - if err != nil { - return err - } - - outLinks := make([]Link, len(links)) - for i, link := range links { - outLinks[i] = Link{ - Hash: enc.Encode(link.Cid), - Name: link.Name, - Size: link.Size, - } - } - - out := &Object{ - Hash: enc.Encode(rp.RootCid()), - Links: outLinks, - } - - return cmds.EmitOnce(res, out) - }, - Encoders: cmds.EncoderMap{ - cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *Object) error { - tw := tabwriter.NewWriter(w, 1, 2, 1, ' ', 0) - headers, _ := req.Options[headersOptionName].(bool) - if headers { - fmt.Fprintln(tw, "Hash\tSize\tName") - } - for _, link := range out.Links { - fmt.Fprintf(tw, "%s\t%v\t%s\n", link.Hash, link.Size, cmdenv.EscNonPrint(link.Name)) - } - tw.Flush() - - return nil - }), - }, - Type: &Object{}, -} - -// ObjectGetCmd object get command -var ObjectGetCmd = &cmds.Command{ - Status: cmds.Deprecated, // https://github.com/ipfs/kubo/issues/7936 - Helptext: cmds.HelpText{ - Tagline: "Deprecated way to get and serialize the dag-pb node. Use 'dag get' instead", - ShortDescription: ` -'ipfs object get' is a plumbing command for retrieving dag-pb nodes. -It serializes the DAG node to the format specified by the "--encoding" -flag. It outputs to stdout, and is a base58 encoded multihash. - -DEPRECATED and provided for legacy reasons. Use 'ipfs dag get' instead. -`, - }, - - Arguments: []cmds.Argument{ - cmds.StringArg("key", true, false, "Key of the dag-pb object to retrieve, in base58-encoded multihash format.").EnableStdin(), - }, - Options: []cmds.Option{ - cmds.StringOption(encodingOptionName, "Encoding type of the data field, either \"text\" or \"base64\".").WithDefault("text"), - }, - Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - api, err := cmdenv.GetApi(env, req) - if err != nil { - return err - } - - enc, err := cmdenv.GetLowLevelCidEncoder(req) - if err != nil { - return err - } - - path, err := cmdutils.PathOrCidPath(req.Arguments[0]) - if err != nil { - return err - } - - datafieldenc, _ := req.Options[encodingOptionName].(string) - if err != nil { - return err - } - - nd, err := api.Object().Get(req.Context, path) - if err != nil { - return err - } - - r, err := api.Object().Data(req.Context, path) - if err != nil { - return err - } - - data, err := io.ReadAll(r) - if err != nil { - return err - } - - out, err := encodeData(data, datafieldenc) - if err != nil { - return err - } - - node := &Node{ - Links: make([]Link, len(nd.Links())), - Data: out, - } - - for i, link := range nd.Links() { - node.Links[i] = Link{ - Hash: enc.Encode(link.Cid), - Name: link.Name, - Size: link.Size, - } - } - - return cmds.EmitOnce(res, node) - }, - Type: Node{}, - Encoders: cmds.EncoderMap{ - cmds.Protobuf: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *Node) error { - // deserialize the Data field as text as this was the standard behaviour - object, err := deserializeNode(out, "text") - if err != nil { - return nil - } - - marshaled, err := object.Marshal() - if err != nil { - return err - } - _, err = w.Write(marshaled) - return err - }), - }, -} - -// ObjectStatCmd object stat command -var ObjectStatCmd = &cmds.Command{ - Status: cmds.Deprecated, // https://github.com/ipfs/kubo/issues/7936 - Helptext: cmds.HelpText{ - Tagline: "Deprecated way to read stats for the dag-pb node. Use 'files stat' instead.", - ShortDescription: ` -'ipfs object stat' is a plumbing command to print dag-pb node statistics. - is a base58 encoded multihash. - -DEPRECATED: modern replacements are 'files stat' and 'dag stat' -`, - LongDescription: ` -'ipfs object stat' is a plumbing command to print dag-pb node statistics. - is a base58 encoded multihash. It outputs to stdout: - - NumLinks int number of links in link table - BlockSize int size of the raw, encoded data - LinksSize int size of the links segment - DataSize int size of the data segment - CumulativeSize int cumulative size of object and its references - -DEPRECATED: Provided for legacy reasons. Modern replacements: - - For unixfs, 'ipfs files stat' can be used: - - $ ipfs files stat --with-local /ipfs/QmWfVY9y3xjsixTgbd9AorQxH7VtMpzfx2HaWtsoUYecaX - QmWfVY9y3xjsixTgbd9AorQxH7VtMpzfx2HaWtsoUYecaX - Size: 5 - CumulativeSize: 13 - ChildBlocks: 0 - Type: file - Local: 13 B of 13 B (100.00%) - - Reported sizes are based on metadata present in root block, and should not be - trusted. A slower, but more secure alternative is 'ipfs dag stat', which - will work for every DAG type. It comes with a benefit of calculating the - size by walking the DAG: - - $ ipfs dag stat /ipfs/QmWfVY9y3xjsixTgbd9AorQxH7VtMpzfx2HaWtsoUYecaX - Size: 13, NumBlocks: 1 -`, - }, - - Arguments: []cmds.Argument{ - cmds.StringArg("key", true, false, "Key of the object to retrieve, in base58-encoded multihash format.").EnableStdin(), - }, - Options: []cmds.Option{ - cmds.BoolOption(humanOptionName, "Print sizes in human readable format (e.g., 1K 234M 2G)"), - }, - Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - api, err := cmdenv.GetApi(env, req) - if err != nil { - return err - } - - enc, err := cmdenv.GetLowLevelCidEncoder(req) - if err != nil { - return err - } - - p, err := cmdutils.PathOrCidPath(req.Arguments[0]) - if err != nil { - return err - } - - ns, err := api.Object().Stat(req.Context, p) - if err != nil { - return err - } - - oldStat := &ipld.NodeStat{ - Hash: enc.Encode(ns.Cid), - NumLinks: ns.NumLinks, - BlockSize: ns.BlockSize, - LinksSize: ns.LinksSize, - DataSize: ns.DataSize, - CumulativeSize: ns.CumulativeSize, - } - - return cmds.EmitOnce(res, oldStat) - }, - Type: ipld.NodeStat{}, - Encoders: cmds.EncoderMap{ - cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *ipld.NodeStat) error { - wtr := tabwriter.NewWriter(w, 0, 0, 1, ' ', 0) - defer wtr.Flush() - fw := func(s string, n int) { - fmt.Fprintf(wtr, "%s:\t%d\n", s, n) - } - human, _ := req.Options[humanOptionName].(bool) - fw("NumLinks", out.NumLinks) - fw("BlockSize", out.BlockSize) - fw("LinksSize", out.LinksSize) - fw("DataSize", out.DataSize) - if human { - fmt.Fprintf(wtr, "%s:\t%s\n", "CumulativeSize", humanize.Bytes(uint64(out.CumulativeSize))) - } else { - fw("CumulativeSize", out.CumulativeSize) - } - - return nil - }), - }, -} - -// ObjectPutCmd object put command -var ObjectPutCmd = &cmds.Command{ - Status: cmds.Deprecated, // https://github.com/ipfs/kubo/issues/7936 - Helptext: cmds.HelpText{ - Tagline: "Deprecated way to store input as a DAG object. Use 'dag put' instead.", - ShortDescription: ` -'ipfs object put' is a plumbing command for storing dag-pb nodes. -It reads from stdin, and the output is a base58 encoded multihash. - -DEPRECATED and provided for legacy reasons. Use 'ipfs dag put' instead. -`, - }, - - Arguments: []cmds.Argument{ - cmds.FileArg("data", true, false, "Data to be stored as a dag-pb object.").EnableStdin(), - }, - Options: []cmds.Option{ - cmds.StringOption(inputencOptionName, "Encoding type of input data. One of: {\"protobuf\", \"json\"}.").WithDefault("json"), - cmds.StringOption(datafieldencOptionName, "Encoding type of the data field, either \"text\" or \"base64\".").WithDefault("text"), - cmds.BoolOption(pinOptionName, "Pin this object when adding."), - cmds.BoolOption(quietOptionName, "q", "Write minimal output."), - }, - Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - api, err := cmdenv.GetApi(env, req) - if err != nil { - return err - } - - enc, err := cmdenv.GetLowLevelCidEncoder(req) - if err != nil { - return err - } - - file, err := cmdenv.GetFileArg(req.Files.Entries()) - if err != nil { - return err - } - - inputenc, _ := req.Options[inputencOptionName].(string) - if err != nil { - return err - } - - datafieldenc, _ := req.Options[datafieldencOptionName].(string) - if err != nil { - return err - } - - dopin, _ := req.Options[pinOptionName].(bool) - if err != nil { - return err - } - - p, err := api.Object().Put(req.Context, file, - options.Object.DataType(datafieldenc), - options.Object.InputEnc(inputenc), - options.Object.Pin(dopin)) - if err != nil { - return err - } - - return cmds.EmitOnce(res, &Object{Hash: enc.Encode(p.RootCid())}) - }, - Encoders: cmds.EncoderMap{ - cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *Object) error { - quiet, _ := req.Options[quietOptionName].(bool) - - o := out.Hash - if !quiet { - o = "added " + o - } - - fmt.Fprintln(w, o) - - return nil - }), - }, - Type: Object{}, -} - -// ObjectNewCmd object new command -var ObjectNewCmd = &cmds.Command{ - Status: cmds.Deprecated, // https://github.com/ipfs/kubo/issues/7936 - Helptext: cmds.HelpText{ - Tagline: "Deprecated way to create a new dag-pb object from a template.", - ShortDescription: ` -'ipfs object new' is a plumbing command for creating new dag-pb nodes. -DEPRECATED and provided for legacy reasons. Use 'dag put' and 'files' instead. -`, - LongDescription: ` -'ipfs object new' is a plumbing command for creating new dag-pb nodes. -By default it creates and returns a new empty merkledag node, but -you may pass an optional template argument to create a preformatted -node. - -Available templates: - * unixfs-dir - -DEPRECATED and provided for legacy reasons. Use 'dag put' and 'files' instead. -`, - }, - Arguments: []cmds.Argument{ - cmds.StringArg("template", false, false, "Template to use. Optional."), - }, - Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - api, err := cmdenv.GetApi(env, req) - if err != nil { - return err - } - - enc, err := cmdenv.GetLowLevelCidEncoder(req) - if err != nil { - return err - } - - template := "empty" - if len(req.Arguments) == 1 { - template = req.Arguments[0] - } - - nd, err := api.Object().New(req.Context, options.Object.Type(template)) - if err != nil && err != io.EOF { - return err - } - - return cmds.EmitOnce(res, &Object{Hash: enc.Encode(nd.Cid())}) - }, - Encoders: cmds.EncoderMap{ - cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *Object) error { - fmt.Fprintln(w, out.Hash) - return nil - }), - }, - Type: Object{}, -} - -// converts the Node object into a real dag.ProtoNode -func deserializeNode(nd *Node, dataFieldEncoding string) (*dag.ProtoNode, error) { - dagnode := new(dag.ProtoNode) - switch dataFieldEncoding { - case "text": - dagnode.SetData([]byte(nd.Data)) - case "base64": - data, err := base64.StdEncoding.DecodeString(nd.Data) - if err != nil { - return nil, err - } - dagnode.SetData(data) - default: - return nil, ErrDataEncoding - } - - links := make([]*ipld.Link, len(nd.Links)) - for i, link := range nd.Links { - c, err := cid.Decode(link.Hash) - if err != nil { - return nil, err - } - links[i] = &ipld.Link{ - Name: link.Name, - Size: link.Size, - Cid: c, - } - } - if err := dagnode.SetLinks(links); err != nil { - return nil, err - } - - return dagnode, nil -} - -func encodeData(data []byte, encoding string) (string, error) { - switch encoding { - case "text": - return string(data), nil - case "base64": - return base64.StdEncoding.EncodeToString(data), nil - } - - return "", ErrDataEncoding -} diff --git a/core/commands/object/patch.go b/core/commands/object/patch.go index 7c35151fb..5a82dfe0b 100644 --- a/core/commands/object/patch.go +++ b/core/commands/object/patch.go @@ -37,128 +37,16 @@ For modern use cases, use MFS with 'files' commands: 'ipfs files --help'. }, Arguments: []cmds.Argument{}, Subcommands: map[string]*cmds.Command{ - "append-data": patchAppendDataCmd, + "append-data": RemovedObjectCmd, "add-link": patchAddLinkCmd, "rm-link": patchRmLinkCmd, - "set-data": patchSetDataCmd, + "set-data": RemovedObjectCmd, }, Options: []cmds.Option{ cmdutils.AllowBigBlockOption, }, } -var patchAppendDataCmd = &cmds.Command{ - Status: cmds.Deprecated, // https://github.com/ipfs/kubo/issues/7936 - Helptext: cmds.HelpText{ - Tagline: "Deprecated way to append data to the data segment of a DAG node.", - ShortDescription: ` -Append data to what already exists in the data segment in the given object. - -Example: - - $ echo "hello" | ipfs object patch $HASH append-data - -NOTE: This does not append data to a file - it modifies the actual raw -data within a dag-pb object. Blocks have a max size of 1MiB and objects larger than -the limit will not be respected by the network. - -DEPRECATED and provided for legacy reasons. Use 'ipfs add' or 'ipfs files' instead. -`, - }, - Arguments: []cmds.Argument{ - cmds.StringArg("root", true, false, "The hash of the node to modify."), - cmds.FileArg("data", true, false, "Data to append.").EnableStdin(), - }, - Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - api, err := cmdenv.GetApi(env, req) - if err != nil { - return err - } - - root, err := cmdutils.PathOrCidPath(req.Arguments[0]) - if err != nil { - return err - } - - file, err := cmdenv.GetFileArg(req.Files.Entries()) - if err != nil { - return err - } - - p, err := api.Object().AppendData(req.Context, root, file) - if err != nil { - return err - } - - if err := cmdutils.CheckCIDSize(req, p.RootCid(), api.Dag()); err != nil { - return err - } - - return cmds.EmitOnce(res, &Object{Hash: p.RootCid().String()}) - }, - Type: &Object{}, - Encoders: cmds.EncoderMap{ - cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, obj *Object) error { - _, err := fmt.Fprintln(w, obj.Hash) - return err - }), - }, -} - -var patchSetDataCmd = &cmds.Command{ - Status: cmds.Deprecated, // https://github.com/ipfs/kubo/issues/7936 - Helptext: cmds.HelpText{ - Tagline: "Deprecated way to set the data field of dag-pb object.", - ShortDescription: ` -Set the data of an IPFS object from stdin or with the contents of a file. - -Example: - - $ echo "my data" | ipfs object patch $MYHASH set-data - -DEPRECATED and provided for legacy reasons. Use 'files cp' and 'dag put' instead. -`, - }, - Arguments: []cmds.Argument{ - cmds.StringArg("root", true, false, "The hash of the node to modify."), - cmds.FileArg("data", true, false, "The data to set the object to.").EnableStdin(), - }, - Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - api, err := cmdenv.GetApi(env, req) - if err != nil { - return err - } - - root, err := cmdutils.PathOrCidPath(req.Arguments[0]) - if err != nil { - return err - } - - file, err := cmdenv.GetFileArg(req.Files.Entries()) - if err != nil { - return err - } - - p, err := api.Object().SetData(req.Context, root, file) - if err != nil { - return err - } - - if err := cmdutils.CheckCIDSize(req, p.RootCid(), api.Dag()); err != nil { - return err - } - - return cmds.EmitOnce(res, &Object{Hash: p.RootCid().String()}) - }, - Type: Object{}, - Encoders: cmds.EncoderMap{ - cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *Object) error { - fmt.Fprintln(w, out.Hash) - return nil - }), - }, -} - var patchRmLinkCmd = &cmds.Command{ Status: cmds.Deprecated, // https://github.com/ipfs/kubo/issues/7936 Helptext: cmds.HelpText{ diff --git a/core/coreapi/object.go b/core/coreapi/object.go index fca98bc5f..0f6c2747a 100644 --- a/core/coreapi/object.go +++ b/core/coreapi/object.go @@ -1,22 +1,12 @@ package coreapi import ( - "bytes" "context" - "encoding/base64" - "encoding/json" - "encoding/xml" - "errors" - "fmt" - "io" dag "github.com/ipfs/boxo/ipld/merkledag" "github.com/ipfs/boxo/ipld/merkledag/dagutils" ft "github.com/ipfs/boxo/ipld/unixfs" "github.com/ipfs/boxo/path" - pin "github.com/ipfs/boxo/pinning/pinner" - cid "github.com/ipfs/go-cid" - ipld "github.com/ipfs/go-ipld-format" coreiface "github.com/ipfs/kubo/core/coreiface" caopts "github.com/ipfs/kubo/core/coreiface/options" "go.opentelemetry.io/otel/attribute" @@ -25,8 +15,6 @@ import ( "github.com/ipfs/kubo/tracing" ) -const inputLimit = 2 << 20 - type ObjectAPI CoreAPI type Link struct { @@ -39,180 +27,6 @@ type Node struct { Data string } -func (api *ObjectAPI) New(ctx context.Context, opts ...caopts.ObjectNewOption) (ipld.Node, error) { - ctx, span := tracing.Span(ctx, "CoreAPI.ObjectAPI", "New") - defer span.End() - - options, err := caopts.ObjectNewOptions(opts...) - if err != nil { - return nil, err - } - - var n ipld.Node - switch options.Type { - case "empty": - n = new(dag.ProtoNode) - case "unixfs-dir": - n = ft.EmptyDirNode() - default: - return nil, fmt.Errorf("unknown node type: %s", options.Type) - } - - err = api.dag.Add(ctx, n) - if err != nil { - return nil, err - } - return n, nil -} - -func (api *ObjectAPI) Put(ctx context.Context, src io.Reader, opts ...caopts.ObjectPutOption) (path.ImmutablePath, error) { - ctx, span := tracing.Span(ctx, "CoreAPI.ObjectAPI", "Put") - defer span.End() - - options, err := caopts.ObjectPutOptions(opts...) - if err != nil { - return path.ImmutablePath{}, err - } - span.SetAttributes( - attribute.Bool("pin", options.Pin), - attribute.String("datatype", options.DataType), - attribute.String("inputenc", options.InputEnc), - ) - - data, err := io.ReadAll(io.LimitReader(src, inputLimit+10)) - if err != nil { - return path.ImmutablePath{}, err - } - - var dagnode *dag.ProtoNode - switch options.InputEnc { - case "json": - node := new(Node) - decoder := json.NewDecoder(bytes.NewReader(data)) - decoder.DisallowUnknownFields() - err = decoder.Decode(node) - if err != nil { - return path.ImmutablePath{}, err - } - - dagnode, err = deserializeNode(node, options.DataType) - if err != nil { - return path.ImmutablePath{}, err - } - - case "protobuf": - dagnode, err = dag.DecodeProtobuf(data) - - case "xml": - node := new(Node) - err = xml.Unmarshal(data, node) - if err != nil { - return path.ImmutablePath{}, err - } - - dagnode, err = deserializeNode(node, options.DataType) - if err != nil { - return path.ImmutablePath{}, err - } - - default: - return path.ImmutablePath{}, errors.New("unknown object encoding") - } - - if err != nil { - return path.ImmutablePath{}, err - } - - if options.Pin { - defer api.blockstore.PinLock(ctx).Unlock(ctx) - } - - err = api.dag.Add(ctx, dagnode) - if err != nil { - return path.ImmutablePath{}, err - } - - if options.Pin { - if err := api.pinning.PinWithMode(ctx, dagnode.Cid(), pin.Recursive, ""); err != nil { - return path.ImmutablePath{}, err - } - - err = api.pinning.Flush(ctx) - if err != nil { - return path.ImmutablePath{}, err - } - } - - return path.FromCid(dagnode.Cid()), nil -} - -func (api *ObjectAPI) Get(ctx context.Context, path path.Path) (ipld.Node, error) { - ctx, span := tracing.Span(ctx, "CoreAPI.ObjectAPI", "Get", trace.WithAttributes(attribute.String("path", path.String()))) - defer span.End() - return api.core().ResolveNode(ctx, path) -} - -func (api *ObjectAPI) Data(ctx context.Context, path path.Path) (io.Reader, error) { - ctx, span := tracing.Span(ctx, "CoreAPI.ObjectAPI", "Data", trace.WithAttributes(attribute.String("path", path.String()))) - defer span.End() - - nd, err := api.core().ResolveNode(ctx, path) - if err != nil { - return nil, err - } - - pbnd, ok := nd.(*dag.ProtoNode) - if !ok { - return nil, dag.ErrNotProtobuf - } - - return bytes.NewReader(pbnd.Data()), nil -} - -func (api *ObjectAPI) Links(ctx context.Context, path path.Path) ([]*ipld.Link, error) { - ctx, span := tracing.Span(ctx, "CoreAPI.ObjectAPI", "Links", trace.WithAttributes(attribute.String("path", path.String()))) - defer span.End() - - nd, err := api.core().ResolveNode(ctx, path) - if err != nil { - return nil, err - } - - links := nd.Links() - out := make([]*ipld.Link, len(links)) - for n, l := range links { - out[n] = (*ipld.Link)(l) - } - - return out, nil -} - -func (api *ObjectAPI) Stat(ctx context.Context, path path.Path) (*coreiface.ObjectStat, error) { - ctx, span := tracing.Span(ctx, "CoreAPI.ObjectAPI", "Stat", trace.WithAttributes(attribute.String("path", path.String()))) - defer span.End() - - nd, err := api.core().ResolveNode(ctx, path) - if err != nil { - return nil, err - } - - stat, err := nd.Stat() - if err != nil { - return nil, err - } - - out := &coreiface.ObjectStat{ - Cid: nd.Cid(), - NumLinks: stat.NumLinks, - BlockSize: stat.BlockSize, - LinksSize: stat.LinksSize, - DataSize: stat.DataSize, - CumulativeSize: stat.CumulativeSize, - } - - return out, nil -} - func (api *ObjectAPI) AddLink(ctx context.Context, base path.Path, name string, child path.Path, opts ...caopts.ObjectAddLinkOption) (path.ImmutablePath, error) { ctx, span := tracing.Span(ctx, "CoreAPI.ObjectAPI", "AddLink", trace.WithAttributes( attribute.String("base", base.String()), @@ -294,49 +108,6 @@ func (api *ObjectAPI) RmLink(ctx context.Context, base path.Path, link string) ( return path.FromCid(nnode.Cid()), nil } -func (api *ObjectAPI) AppendData(ctx context.Context, path path.Path, r io.Reader) (path.ImmutablePath, error) { - ctx, span := tracing.Span(ctx, "CoreAPI.ObjectAPI", "AppendData", trace.WithAttributes(attribute.String("path", path.String()))) - defer span.End() - - return api.patchData(ctx, path, r, true) -} - -func (api *ObjectAPI) SetData(ctx context.Context, path path.Path, r io.Reader) (path.ImmutablePath, error) { - ctx, span := tracing.Span(ctx, "CoreAPI.ObjectAPI", "SetData", trace.WithAttributes(attribute.String("path", path.String()))) - defer span.End() - - return api.patchData(ctx, path, r, false) -} - -func (api *ObjectAPI) patchData(ctx context.Context, p path.Path, r io.Reader, appendData bool) (path.ImmutablePath, error) { - nd, err := api.core().ResolveNode(ctx, p) - if err != nil { - return path.ImmutablePath{}, err - } - - pbnd, ok := nd.(*dag.ProtoNode) - if !ok { - return path.ImmutablePath{}, dag.ErrNotProtobuf - } - - data, err := io.ReadAll(r) - if err != nil { - return path.ImmutablePath{}, err - } - - if appendData { - data = append(pbnd.Data(), data...) - } - pbnd.SetData(data) - - err = api.dag.Add(ctx, pbnd) - if err != nil { - return path.ImmutablePath{}, err - } - - return path.FromCid(pbnd.Cid()), nil -} - func (api *ObjectAPI) Diff(ctx context.Context, before path.Path, after path.Path) ([]coreiface.ObjectChange, error) { ctx, span := tracing.Span(ctx, "CoreAPI.ObjectAPI", "Diff", trace.WithAttributes( attribute.String("before", before.String()), @@ -381,37 +152,3 @@ func (api *ObjectAPI) Diff(ctx context.Context, before path.Path, after path.Pat func (api *ObjectAPI) core() coreiface.CoreAPI { return (*CoreAPI)(api) } - -func deserializeNode(nd *Node, dataFieldEncoding string) (*dag.ProtoNode, error) { - dagnode := new(dag.ProtoNode) - switch dataFieldEncoding { - case "text": - dagnode.SetData([]byte(nd.Data)) - case "base64": - data, err := base64.StdEncoding.DecodeString(nd.Data) - if err != nil { - return nil, err - } - dagnode.SetData(data) - default: - return nil, fmt.Errorf("unknown data field encoding") - } - - links := make([]*ipld.Link, len(nd.Links)) - for i, link := range nd.Links { - c, err := cid.Decode(link.Hash) - if err != nil { - return nil, err - } - links[i] = &ipld.Link{ - Name: link.Name, - Size: link.Size, - Cid: c, - } - } - if err := dagnode.SetLinks(links); err != nil { - return nil, err - } - - return dagnode, nil -} diff --git a/core/coreiface/object.go b/core/coreiface/object.go index fa378ac6c..27bb88935 100644 --- a/core/coreiface/object.go +++ b/core/coreiface/object.go @@ -2,36 +2,11 @@ package iface import ( "context" - "io" "github.com/ipfs/boxo/path" "github.com/ipfs/kubo/core/coreiface/options" - - "github.com/ipfs/go-cid" - ipld "github.com/ipfs/go-ipld-format" ) -// ObjectStat provides information about dag nodes -type ObjectStat struct { - // Cid is the CID of the node - Cid cid.Cid - - // NumLinks is number of links the node contains - NumLinks int - - // BlockSize is size of the raw serialized node - BlockSize int - - // LinksSize is size of the links block section - LinksSize int - - // DataSize is the size of data block section - DataSize int - - // CumulativeSize is size of the tree (BlockSize + link sizes) - CumulativeSize int -} - // ChangeType denotes type of change in ObjectChange type ChangeType int @@ -69,24 +44,6 @@ type ObjectChange struct { // ObjectAPI specifies the interface to MerkleDAG and contains useful utilities // for manipulating MerkleDAG data structures. type ObjectAPI interface { - // New creates new, empty (by default) dag-node. - New(context.Context, ...options.ObjectNewOption) (ipld.Node, error) - - // Put imports the data into merkledag - Put(context.Context, io.Reader, ...options.ObjectPutOption) (path.ImmutablePath, error) - - // Get returns the node for the path - Get(context.Context, path.Path) (ipld.Node, error) - - // Data returns reader for data of the node - Data(context.Context, path.Path) (io.Reader, error) - - // Links returns lint or links the node contains - Links(context.Context, path.Path) ([]*ipld.Link, error) - - // Stat returns information about the node - Stat(context.Context, path.Path) (*ObjectStat, error) - // AddLink adds a link under the specified path. child path can point to a // subdirectory within the patent which must be present (can be overridden // with WithCreate option). @@ -95,12 +52,6 @@ type ObjectAPI interface { // RmLink removes a link from the node RmLink(ctx context.Context, base path.Path, link string) (path.ImmutablePath, error) - // AppendData appends data to the node - AppendData(context.Context, path.Path, io.Reader) (path.ImmutablePath, error) - - // SetData sets the data contained in the node - SetData(context.Context, path.Path, io.Reader) (path.ImmutablePath, error) - // Diff returns a set of changes needed to transform the first object into the // second. Diff(context.Context, path.Path, path.Path) ([]ObjectChange, error) diff --git a/core/coreiface/options/object.go b/core/coreiface/options/object.go index b5625a1d6..ab780ebd9 100644 --- a/core/coreiface/options/object.go +++ b/core/coreiface/options/object.go @@ -1,55 +1,13 @@ package options -type ObjectNewSettings struct { - Type string -} - -type ObjectPutSettings struct { - InputEnc string - DataType string - Pin bool -} - type ObjectAddLinkSettings struct { Create bool } type ( - ObjectNewOption func(*ObjectNewSettings) error - ObjectPutOption func(*ObjectPutSettings) error ObjectAddLinkOption func(*ObjectAddLinkSettings) error ) -func ObjectNewOptions(opts ...ObjectNewOption) (*ObjectNewSettings, error) { - options := &ObjectNewSettings{ - Type: "empty", - } - - for _, opt := range opts { - err := opt(options) - if err != nil { - return nil, err - } - } - return options, nil -} - -func ObjectPutOptions(opts ...ObjectPutOption) (*ObjectPutSettings, error) { - options := &ObjectPutSettings{ - InputEnc: "json", - DataType: "text", - Pin: false, - } - - for _, opt := range opts { - err := opt(options) - if err != nil { - return nil, err - } - } - return options, nil -} - func ObjectAddLinkOptions(opts ...ObjectAddLinkOption) (*ObjectAddLinkSettings, error) { options := &ObjectAddLinkSettings{ Create: false, @@ -68,54 +26,6 @@ type objectOpts struct{} var Object objectOpts -// Type is an option for Object.New which allows to change the type of created -// dag node. -// -// Supported types: -// * 'empty' - Empty node -// * 'unixfs-dir' - Empty UnixFS directory -func (objectOpts) Type(t string) ObjectNewOption { - return func(settings *ObjectNewSettings) error { - settings.Type = t - return nil - } -} - -// InputEnc is an option for Object.Put which specifies the input encoding of the -// data. Default is "json". -// -// Supported encodings: -// * "protobuf" -// * "json" -func (objectOpts) InputEnc(e string) ObjectPutOption { - return func(settings *ObjectPutSettings) error { - settings.InputEnc = e - return nil - } -} - -// DataType is an option for Object.Put which specifies the encoding of data -// field when using Json or XML input encoding. -// -// Supported types: -// * "text" (default) -// * "base64" -func (objectOpts) DataType(t string) ObjectPutOption { - return func(settings *ObjectPutSettings) error { - settings.DataType = t - return nil - } -} - -// Pin is an option for Object.Put which specifies whether to pin the added -// objects, default is false -func (objectOpts) Pin(pin bool) ObjectPutOption { - return func(settings *ObjectPutSettings) error { - settings.Pin = pin - return nil - } -} - // Create is an option for Object.AddLink which specifies whether create required // directories for the child func (objectOpts) Create(create bool) ObjectAddLinkOption { diff --git a/core/coreiface/tests/object.go b/core/coreiface/tests/object.go index 9e0463ab6..239b022e1 100644 --- a/core/coreiface/tests/object.go +++ b/core/coreiface/tests/object.go @@ -1,15 +1,15 @@ package tests import ( - "bytes" "context" - "encoding/hex" - "io" - "strings" "testing" + dag "github.com/ipfs/boxo/ipld/merkledag" + "github.com/ipfs/boxo/path" + ipld "github.com/ipfs/go-ipld-format" iface "github.com/ipfs/kubo/core/coreiface" opt "github.com/ipfs/kubo/core/coreiface/options" + "github.com/stretchr/testify/require" ) func (tp *TestSuite) TestObject(t *testing.T) { @@ -20,448 +20,125 @@ func (tp *TestSuite) TestObject(t *testing.T) { return nil }) - t.Run("TestNew", tp.TestNew) - t.Run("TestObjectPut", tp.TestObjectPut) - t.Run("TestObjectGet", tp.TestObjectGet) - t.Run("TestObjectData", tp.TestObjectData) - t.Run("TestObjectLinks", tp.TestObjectLinks) - t.Run("TestObjectStat", tp.TestObjectStat) t.Run("TestObjectAddLink", tp.TestObjectAddLink) t.Run("TestObjectAddLinkCreate", tp.TestObjectAddLinkCreate) t.Run("TestObjectRmLink", tp.TestObjectRmLink) - t.Run("TestObjectAddData", tp.TestObjectAddData) - t.Run("TestObjectSetData", tp.TestObjectSetData) t.Run("TestDiffTest", tp.TestDiffTest) } -func (tp *TestSuite) TestNew(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - api, err := tp.makeAPI(t, ctx) - if err != nil { - t.Fatal(err) +func putDagPbNode(t *testing.T, ctx context.Context, api iface.CoreAPI, data string, links []*ipld.Link) path.ImmutablePath { + dagnode := new(dag.ProtoNode) + + if data != "" { + dagnode.SetData([]byte(data)) } - emptyNode, err := api.Object().New(ctx) - if err != nil { - t.Fatal(err) + if links != nil { + err := dagnode.SetLinks(links) + require.NoError(t, err) } - dirNode, err := api.Object().New(ctx, opt.Object.Type("unixfs-dir")) - if err != nil { - t.Fatal(err) - } + err := api.Dag().Add(ctx, dagnode) + require.NoError(t, err) - if emptyNode.String() != "QmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zR1n" { - t.Errorf("Unexpected emptyNode path: %s", emptyNode.String()) - } - - if dirNode.String() != "QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn" { - t.Errorf("Unexpected dirNode path: %s", dirNode.String()) - } -} - -func (tp *TestSuite) TestObjectPut(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - api, err := tp.makeAPI(t, ctx) - if err != nil { - t.Fatal(err) - } - - p1, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"foo"}`)) - if err != nil { - t.Fatal(err) - } - - p2, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"YmFy"}`), opt.Object.DataType("base64")) // bar - if err != nil { - t.Fatal(err) - } - - pbBytes, err := hex.DecodeString("0a0362617a") - if err != nil { - t.Fatal(err) - } - - p3, err := api.Object().Put(ctx, bytes.NewReader(pbBytes), opt.Object.InputEnc("protobuf")) - if err != nil { - t.Fatal(err) - } - - if p1.String() != "/ipfs/QmQeGyS87nyijii7kFt1zbe4n2PsXTFimzsdxyE9qh9TST" { - t.Errorf("unexpected path: %s", p1.String()) - } - - if p2.String() != "/ipfs/QmNeYRbCibmaMMK6Du6ChfServcLqFvLJF76PzzF76SPrZ" { - t.Errorf("unexpected path: %s", p2.String()) - } - - if p3.String() != "/ipfs/QmZreR7M2t7bFXAdb1V5FtQhjk4t36GnrvueLJowJbQM9m" { - t.Errorf("unexpected path: %s", p3.String()) - } -} - -func (tp *TestSuite) TestObjectGet(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - api, err := tp.makeAPI(t, ctx) - if err != nil { - t.Fatal(err) - } - - p1, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"foo"}`)) - if err != nil { - t.Fatal(err) - } - - nd, err := api.Object().Get(ctx, p1) - if err != nil { - t.Fatal(err) - } - - if string(nd.RawData()[len(nd.RawData())-3:]) != "foo" { - t.Fatal("got non-matching data") - } -} - -func (tp *TestSuite) TestObjectData(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - api, err := tp.makeAPI(t, ctx) - if err != nil { - t.Fatal(err) - } - - p1, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"foo"}`)) - if err != nil { - t.Fatal(err) - } - - r, err := api.Object().Data(ctx, p1) - if err != nil { - t.Fatal(err) - } - - data, err := io.ReadAll(r) - if err != nil { - t.Fatal(err) - } - - if string(data) != "foo" { - t.Fatal("got non-matching data") - } -} - -func (tp *TestSuite) TestObjectLinks(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - api, err := tp.makeAPI(t, ctx) - if err != nil { - t.Fatal(err) - } - - p1, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"foo"}`)) - if err != nil { - t.Fatal(err) - } - - p2, err := api.Object().Put(ctx, strings.NewReader(`{"Links":[{"Name":"bar", "Hash":"`+p1.RootCid().String()+`"}]}`)) - if err != nil { - t.Fatal(err) - } - - links, err := api.Object().Links(ctx, p2) - if err != nil { - t.Fatal(err) - } - - if len(links) != 1 { - t.Errorf("unexpected number of links: %d", len(links)) - } - - if links[0].Cid.String() != p1.RootCid().String() { - t.Fatal("cids didn't batch") - } - - if links[0].Name != "bar" { - t.Fatal("unexpected link name") - } -} - -func (tp *TestSuite) TestObjectStat(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - api, err := tp.makeAPI(t, ctx) - if err != nil { - t.Fatal(err) - } - - p1, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"foo"}`)) - if err != nil { - t.Fatal(err) - } - - p2, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"bazz", "Links":[{"Name":"bar", "Hash":"`+p1.RootCid().String()+`", "Size":3}]}`)) - if err != nil { - t.Fatal(err) - } - - stat, err := api.Object().Stat(ctx, p2) - if err != nil { - t.Fatal(err) - } - - if stat.Cid.String() != p2.RootCid().String() { - t.Error("unexpected stat.Cid") - } - - if stat.NumLinks != 1 { - t.Errorf("unexpected stat.NumLinks") - } - - if stat.BlockSize != 51 { - t.Error("unexpected stat.BlockSize") - } - - if stat.LinksSize != 47 { - t.Errorf("unexpected stat.LinksSize: %d", stat.LinksSize) - } - - if stat.DataSize != 4 { - t.Error("unexpected stat.DataSize") - } - - if stat.CumulativeSize != 54 { - t.Error("unexpected stat.DataSize") - } + return path.FromCid(dagnode.Cid()) } func (tp *TestSuite) TestObjectAddLink(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() api, err := tp.makeAPI(t, ctx) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - p1, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"foo"}`)) - if err != nil { - t.Fatal(err) - } - - p2, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"bazz", "Links":[{"Name":"bar", "Hash":"`+p1.RootCid().String()+`", "Size":3}]}`)) - if err != nil { - t.Fatal(err) - } + p1 := putDagPbNode(t, ctx, api, "foo", nil) + p2 := putDagPbNode(t, ctx, api, "bazz", []*ipld.Link{ + { + Name: "bar", + Cid: p1.RootCid(), + Size: 3, + }, + }) p3, err := api.Object().AddLink(ctx, p2, "abc", p2) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - links, err := api.Object().Links(ctx, p3) - if err != nil { - t.Fatal(err) - } + nd, err := api.Dag().Get(ctx, p3.RootCid()) + require.NoError(t, err) - if len(links) != 2 { - t.Errorf("unexpected number of links: %d", len(links)) - } - - if links[0].Name != "abc" { - t.Errorf("unexpected link 0 name: %s", links[0].Name) - } - - if links[1].Name != "bar" { - t.Errorf("unexpected link 1 name: %s", links[1].Name) - } + links := nd.Links() + require.Len(t, links, 2) + require.Equal(t, "abc", links[0].Name) + require.Equal(t, "bar", links[1].Name) } func (tp *TestSuite) TestObjectAddLinkCreate(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() api, err := tp.makeAPI(t, ctx) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - p1, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"foo"}`)) - if err != nil { - t.Fatal(err) - } - - p2, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"bazz", "Links":[{"Name":"bar", "Hash":"`+p1.RootCid().String()+`", "Size":3}]}`)) - if err != nil { - t.Fatal(err) - } + p1 := putDagPbNode(t, ctx, api, "foo", nil) + p2 := putDagPbNode(t, ctx, api, "bazz", []*ipld.Link{ + { + Name: "bar", + Cid: p1.RootCid(), + Size: 3, + }, + }) _, err = api.Object().AddLink(ctx, p2, "abc/d", p2) - if err == nil { - t.Fatal("expected an error") - } - if !strings.Contains(err.Error(), "no link by that name") { - t.Fatalf("unexpected error: %s", err.Error()) - } + require.ErrorContains(t, err, "no link by that name") p3, err := api.Object().AddLink(ctx, p2, "abc/d", p2, opt.Object.Create(true)) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - links, err := api.Object().Links(ctx, p3) - if err != nil { - t.Fatal(err) - } + nd, err := api.Dag().Get(ctx, p3.RootCid()) + require.NoError(t, err) - if len(links) != 2 { - t.Errorf("unexpected number of links: %d", len(links)) - } - - if links[0].Name != "abc" { - t.Errorf("unexpected link 0 name: %s", links[0].Name) - } - - if links[1].Name != "bar" { - t.Errorf("unexpected link 1 name: %s", links[1].Name) - } + links := nd.Links() + require.Len(t, links, 2) + require.Equal(t, "abc", links[0].Name) + require.Equal(t, "bar", links[1].Name) } func (tp *TestSuite) TestObjectRmLink(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() api, err := tp.makeAPI(t, ctx) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - p1, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"foo"}`)) - if err != nil { - t.Fatal(err) - } - - p2, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"bazz", "Links":[{"Name":"bar", "Hash":"`+p1.RootCid().String()+`", "Size":3}]}`)) - if err != nil { - t.Fatal(err) - } + p1 := putDagPbNode(t, ctx, api, "foo", nil) + p2 := putDagPbNode(t, ctx, api, "bazz", []*ipld.Link{ + { + Name: "bar", + Cid: p1.RootCid(), + Size: 3, + }, + }) p3, err := api.Object().RmLink(ctx, p2, "bar") - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - links, err := api.Object().Links(ctx, p3) - if err != nil { - t.Fatal(err) - } + nd, err := api.Dag().Get(ctx, p3.RootCid()) + require.NoError(t, err) - if len(links) != 0 { - t.Errorf("unexpected number of links: %d", len(links)) - } -} - -func (tp *TestSuite) TestObjectAddData(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - api, err := tp.makeAPI(t, ctx) - if err != nil { - t.Fatal(err) - } - - p1, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"foo"}`)) - if err != nil { - t.Fatal(err) - } - - p2, err := api.Object().AppendData(ctx, p1, strings.NewReader("bar")) - if err != nil { - t.Fatal(err) - } - - r, err := api.Object().Data(ctx, p2) - if err != nil { - t.Fatal(err) - } - - data, err := io.ReadAll(r) - if err != nil { - t.Fatal(err) - } - - if string(data) != "foobar" { - t.Error("unexpected data") - } -} - -func (tp *TestSuite) TestObjectSetData(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - api, err := tp.makeAPI(t, ctx) - if err != nil { - t.Fatal(err) - } - - p1, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"foo"}`)) - if err != nil { - t.Fatal(err) - } - - p2, err := api.Object().SetData(ctx, p1, strings.NewReader("bar")) - if err != nil { - t.Fatal(err) - } - - r, err := api.Object().Data(ctx, p2) - if err != nil { - t.Fatal(err) - } - - data, err := io.ReadAll(r) - if err != nil { - t.Fatal(err) - } - - if string(data) != "bar" { - t.Error("unexpected data") - } + links := nd.Links() + require.Len(t, links, 0) } func (tp *TestSuite) TestDiffTest(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() api, err := tp.makeAPI(t, ctx) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - p1, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"foo"}`)) - if err != nil { - t.Fatal(err) - } - - p2, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"bar"}`)) - if err != nil { - t.Fatal(err) - } + p1 := putDagPbNode(t, ctx, api, "foo", nil) + p2 := putDagPbNode(t, ctx, api, "bar", nil) changes, err := api.Object().Diff(ctx, p1, p2) - if err != nil { - t.Fatal(err) - } - - if len(changes) != 1 { - t.Fatal("unexpected changes len") - } - - if changes[0].Type != iface.DiffMod { - t.Fatal("unexpected change type") - } - - if changes[0].Before.String() != p1.String() { - t.Fatal("unexpected before path") - } - - if changes[0].After.String() != p2.String() { - t.Fatal("unexpected before path") - } + require.NoError(t, err) + require.Len(t, changes, 1) + require.Equal(t, iface.DiffMod, changes[0].Type) + require.Equal(t, p1.String(), changes[0].Before.String()) + require.Equal(t, p2.String(), changes[0].After.String()) } diff --git a/core/coreiface/tests/unixfs.go b/core/coreiface/tests/unixfs.go index 538f4d8ed..0dca0218b 100644 --- a/core/coreiface/tests/unixfs.go +++ b/core/coreiface/tests/unixfs.go @@ -630,16 +630,11 @@ func (tp *TestSuite) TestGetDir(t *testing.T) { } p := path.FromCid(edir.Cid()) - emptyDir, err := api.Object().New(ctx, options.Object.Type("unixfs-dir")) - if err != nil { - t.Fatal(err) + if p.String() != path.FromCid(edir.Cid()).String() { + t.Fatalf("expected path %s, got: %s", edir.Cid(), p.String()) } - if p.String() != path.FromCid(emptyDir.Cid()).String() { - t.Fatalf("expected path %s, got: %s", emptyDir.Cid(), p.String()) - } - - r, err := api.Unixfs().Get(ctx, path.FromCid(emptyDir.Cid())) + r, err := api.Unixfs().Get(ctx, path.FromCid(edir.Cid())) if err != nil { t.Fatal(err) } @@ -779,17 +774,12 @@ func (tp *TestSuite) TestLsEmptyDir(t *testing.T) { t.Fatal(err) } - _, err = api.Unixfs().Add(ctx, files.NewSliceDirectory([]files.DirEntry{})) + p, err := api.Unixfs().Add(ctx, files.NewSliceDirectory([]files.DirEntry{})) if err != nil { t.Fatal(err) } - emptyDir, err := api.Object().New(ctx, options.Object.Type("unixfs-dir")) - if err != nil { - t.Fatal(err) - } - - links, err := api.Unixfs().Ls(ctx, path.FromCid(emptyDir.Cid())) + links, err := api.Unixfs().Ls(ctx, p) if err != nil { t.Fatal(err) } diff --git a/docs/changelogs/v0.28.md b/docs/changelogs/v0.28.md index ffc816737..0d399c6ec 100644 --- a/docs/changelogs/v0.28.md +++ b/docs/changelogs/v0.28.md @@ -8,6 +8,7 @@ - [🔦 Highlights](#-highlights) - [RPC client: removed deprecated DHT API](#rpc-client-removed-deprecated-dht-api) - [Gateway: `/api/v0` is removed](#gateway-apiv0-is-removed) + - [Removed deprecated Object API commands](#removed-deprecated-object-api-commands) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -23,6 +24,10 @@ The legacy subset of the Kubo RPC that was available via the Gateway port and wa If you have a legacy software that relies on this behavior, and want to expose parts of `/api/v0` next to `/ipfs`, use reverse-proxy in front of Kubo to mount both Gateway and RPC on the same port. NOTE: exposing RPC to the internet comes with security risk: make sure to specify access control via [API.Authorizations](https://github.com/ipfs/kubo/blob/master/docs/config.md#apiauthorizations). +#### Removed deprecated Object API commands + +The Object API commands deprecated back in [2021](https://github.com/ipfs/kubo/issues/7936) have been removed, except for `object diff`, `object patch add-link` and `object patch rm-link`, whose alternatives have not yet been built (see issues [4801](https://github.com/ipfs/kubo/issues/4801) and [4782](https://github.com/ipfs/kubo/issues/4782)). + ### 📝 Changelog ### 👨‍👩‍👧‍👦 Contributors diff --git a/docs/implement-api-bindings.md b/docs/implement-api-bindings.md index 996a6b8ac..3587ac21f 100644 --- a/docs/implement-api-bindings.md +++ b/docs/implement-api-bindings.md @@ -39,10 +39,9 @@ function calls. For example: #### CLI API Transport In the commandline, IPFS uses a traditional flag and arg-based mapping, where: -- the first arguments selects the command, as in git - e.g. `ipfs object get` +- the first arguments selects the command, as in git - e.g. `ipfs dag get` - the flags specify options - e.g. `--enc=protobuf -q` -- the rest are positional arguments - e.g. - `ipfs object patch add-linkfoo ` +- the rest are positional arguments - e.g. `ipfs key rename ` - files are specified by filename, or through stdin (NOTE: When kubo runs the daemon, the CLI API is actually converted to HTTP diff --git a/test/cli/basic_commands_test.go b/test/cli/basic_commands_test.go index 69b0cc63b..603a03d9d 100644 --- a/test/cli/basic_commands_test.go +++ b/test/cli/basic_commands_test.go @@ -147,7 +147,6 @@ func TestCommandDocsWidth(t *testing.T) { "ipfs swarm addrs listen": true, "ipfs dag resolve": true, "ipfs dag get": true, - "ipfs object stat": true, "ipfs pin remote add": true, "ipfs config show": true, "ipfs config edit": true, @@ -164,8 +163,6 @@ func TestCommandDocsWidth(t *testing.T) { "ipfs object diff": true, "ipfs object patch add-link": true, "ipfs name": true, - "ipfs object patch append-data": true, - "ipfs object patch set-data": true, "ipfs diag profile": true, "ipfs diag cmds": true, "ipfs swarm addrs local": true, diff --git a/test/sharness/t0051-object-data/testPut.pb b/test/sharness/t0050-block-data/testPut.pb similarity index 100% rename from test/sharness/t0051-object-data/testPut.pb rename to test/sharness/t0050-block-data/testPut.pb diff --git a/test/sharness/t0050-block.sh b/test/sharness/t0050-block.sh index 9ecf20875..05502adaf 100755 --- a/test/sharness/t0050-block.sh +++ b/test/sharness/t0050-block.sh @@ -42,12 +42,12 @@ test_expect_success "'ipfs block put' output looks good" ' ' test_expect_success "can set cid codec on block put" ' - CODEC_HASH=$(ipfs block put --cid-codec=dag-pb ../t0051-object-data/testPut.pb) + CODEC_HASH=$(ipfs block put --cid-codec=dag-pb ../t0050-block-data/testPut.pb) ' test_expect_success "block get output looks right" ' ipfs block get $CODEC_HASH > pb_block_out && - test_cmp pb_block_out ../t0051-object-data/testPut.pb + test_cmp pb_block_out ../t0050-block-data/testPut.pb ' # @@ -210,33 +210,33 @@ test_expect_success "multi-block 'ipfs block rm -q' produces no output" ' # --format used 'protobuf' for 'dag-pb' which was invalid, but we keep # for backward-compatibility test_expect_success "can set deprecated --format=protobuf on block put" ' - HASH=$(ipfs block put --format=protobuf ../t0051-object-data/testPut.pb) + HASH=$(ipfs block put --format=protobuf ../t0050-block-data/testPut.pb) ' test_expect_success "created an object correctly!" ' - ipfs object get $HASH > obj_out && - echo "{\"Links\":[],\"Data\":\"test json for sharness test\"}" > obj_exp && + ipfs dag get $HASH > obj_out && + echo -n "{\"Data\":{\"/\":{\"bytes\":\"dGVzdCBqc29uIGZvciBzaGFybmVzcyB0ZXN0\"}},\"Links\":[]}" > obj_exp && test_cmp obj_out obj_exp ' test_expect_success "block get output looks right" ' ipfs block get $HASH > pb_block_out && - test_cmp pb_block_out ../t0051-object-data/testPut.pb + test_cmp pb_block_out ../t0050-block-data/testPut.pb ' test_expect_success "can set --cid-codec=dag-pb on block put" ' - HASH=$(ipfs block put --cid-codec=dag-pb ../t0051-object-data/testPut.pb) + HASH=$(ipfs block put --cid-codec=dag-pb ../t0050-block-data/testPut.pb) ' test_expect_success "created an object correctly!" ' - ipfs object get $HASH > obj_out && - echo "{\"Links\":[],\"Data\":\"test json for sharness test\"}" > obj_exp && + ipfs dag get $HASH > obj_out && + echo -n "{\"Data\":{\"/\":{\"bytes\":\"dGVzdCBqc29uIGZvciBzaGFybmVzcyB0ZXN0\"}},\"Links\":[]}" > obj_exp && test_cmp obj_out obj_exp ' test_expect_success "block get output looks right" ' ipfs block get $HASH > pb_block_out && - test_cmp pb_block_out ../t0051-object-data/testPut.pb + test_cmp pb_block_out ../t0050-block-data/testPut.pb ' test_expect_success "can set multihash type and length on block put with --format=raw (deprecated)" ' @@ -248,7 +248,7 @@ test_expect_success "output looks good" ' ' test_expect_success "can't use both legacy format and custom cid-codec at the same time" ' - test_expect_code 1 ipfs block put --format=dag-cbor --cid-codec=dag-json < ../t0051-object-data/testPut.pb 2> output && + test_expect_code 1 ipfs block put --format=dag-cbor --cid-codec=dag-json < ../t0050-block-data/testPut.pb 2> output && test_should_contain "unable to use \"format\" (deprecated) and a custom \"cid-codec\" at the same time" output ' diff --git a/test/sharness/t0051-object-data/UTF-8-test.txt b/test/sharness/t0051-object-data/UTF-8-test.txt deleted file mode 100644 index 56213a84a9843f0f8fa6f10a1a67dcdb9de982c2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20350 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 is not a valid dag object fail diff --git a/test/sharness/t0051-object-data/expected_getOut b/test/sharness/t0051-object-data/expected_getOut deleted file mode 100644 index 27b23f9d3..000000000 --- a/test/sharness/t0051-object-data/expected_getOut +++ /dev/null @@ -1 +0,0 @@ -{"Links":[],"Data":"\b\u0002\u0012\nHello Mars\u0018\n"} diff --git a/test/sharness/t0051-object-data/mixed.json b/test/sharness/t0051-object-data/mixed.json deleted file mode 100644 index b8de2b8d8..000000000 --- a/test/sharness/t0051-object-data/mixed.json +++ /dev/null @@ -1,5 +0,0 @@ -{"Data": "another", - "Links": [ - {"Name": "some link", "Hash": "QmXg9Pp2ytZ14xgmQjYEiHjVjMFXzCVVEcRTWJBmLgR39V", "Size": 8}, - {"Name": "inlined", "Hash": "z4CrgyEyhm4tAw1pgzQtNNuP7", "Size": 14} -]} diff --git a/test/sharness/t0051-object-data/testPut.json b/test/sharness/t0051-object-data/testPut.json deleted file mode 100644 index c97f4ec0b..000000000 --- a/test/sharness/t0051-object-data/testPut.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "Data": "test json for sharness test" -} diff --git a/test/sharness/t0051-object-data/testPut.xml b/test/sharness/t0051-object-data/testPut.xml deleted file mode 100644 index 5cc290b27..000000000 --- a/test/sharness/t0051-object-data/testPut.xml +++ /dev/null @@ -1 +0,0 @@ -Test xml for sharness test diff --git a/test/sharness/t0051-object.sh b/test/sharness/t0051-object.sh index 316c220ab..4bac61374 100755 --- a/test/sharness/t0051-object.sh +++ b/test/sharness/t0051-object.sh @@ -27,204 +27,21 @@ test_patch_create_path() { } test_object_cmd() { - - test_expect_success "'ipfs add testData' succeeds" ' - printf "Hello Mars" >expected_in && - ipfs add expected_in >actual_Addout - ' - - test_expect_success "'ipfs add testData' output looks good" ' - HASH="QmWkHFpYBZ9mpPRreRbMhhYWXfUhBAue3JkbbpFqwowSRb" && - echo "added $HASH expected_in" >expected_Addout && - test_cmp expected_Addout actual_Addout - ' - - test_expect_success "'ipfs object get' succeeds" ' - ipfs object get $HASH >actual_getOut - ' - - test_expect_success "'ipfs object get' output looks good" ' - test_cmp ../t0051-object-data/expected_getOut actual_getOut - ' - - test_expect_success "'ipfs object get' can specify data encoding as base64" ' - ipfs object get --data-encoding base64 $HASH > obj_out && - echo "{\"Links\":[],\"Data\":\"CAISCkhlbGxvIE1hcnMYCg==\"}" > obj_exp && - test_cmp obj_out obj_exp - ' - - test_expect_success "'ipfs object get' can specify data encoding as text" ' - echo "{\"Links\":[],\"Data\":\"Hello Mars\"}" | ipfs object put && - ipfs object get --data-encoding text QmS3hVY6eYrMQ6L22agwrx3YHBEsc3LJxVXCtyQHqRBukH > obj_out && - echo "{\"Links\":[],\"Data\":\"Hello Mars\"}" > obj_exp && - test_cmp obj_out obj_exp - ' - - test_expect_failure "'ipfs object get' requires known data encoding" ' - ipfs object get --data-encoding nonsensical-encoding $HASH - ' - - test_expect_success "'ipfs object stat' succeeds" ' - ipfs object stat $HASH >actual_stat - ' - - test_expect_success "'ipfs object get' output looks good" ' - echo "NumLinks: 0" > expected_stat && - echo "BlockSize: 18" >> expected_stat && - echo "LinksSize: 2" >> expected_stat && - echo "DataSize: 16" >> expected_stat && - echo "CumulativeSize: 18" >> expected_stat && - test_cmp expected_stat actual_stat - ' - - test_expect_success "'ipfs object put file.json' succeeds" ' - ipfs object put ../t0051-object-data/testPut.json > actual_putOut - ' - - test_expect_success "'ipfs object put file.json' output looks good" ' - HASH="QmUTSAdDi2xsNkDtLqjFgQDMEn5di3Ab9eqbrt4gaiNbUD" && - printf "added $HASH\n" > expected_putOut && - test_cmp expected_putOut actual_putOut - ' - - test_expect_success "'ipfs object put --quiet file.json' succeeds" ' - ipfs object put --quiet ../t0051-object-data/testPut.json > actual_putOut - ' - - test_expect_success "'ipfs object put --quiet file.json' output looks good" ' - HASH="QmUTSAdDi2xsNkDtLqjFgQDMEn5di3Ab9eqbrt4gaiNbUD" && - printf "$HASH\n" > expected_putOut && - test_cmp expected_putOut actual_putOut - ' - - test_expect_success "'ipfs object put file.xml' succeeds" ' - ipfs object put ../t0051-object-data/testPut.xml --inputenc=xml > actual_putOut - ' - - test_expect_success "'ipfs object put file.xml' output looks good" ' - HASH="QmQzNKUHy4HyEUGkqKe3q3t796ffPLQXYCkHCcXUNT5JNK" && - printf "added $HASH\n" > expected_putOut && - test_cmp expected_putOut actual_putOut - ' - - test_expect_success "'ipfs object put' from stdin succeeds" ' - cat ../t0051-object-data/testPut.xml | ipfs object put --inputenc=xml > actual_putStdinOut - ' - - test_expect_failure "'ipfs object put broken.xml' should fail" ' - test_expect_code 1 ipfs object put ../t0051-object-data/brokenPut.xml --inputenc=xml 2>actual_putBrokenErr >actual_putBroken - ' - - test_expect_failure "'ipfs object put broken.hxml' output looks good" ' - touch expected_putBroken && - printf "Error: no data or links in this node\n" > expected_putBrokenErr && - test_cmp expected_putBroken actual_putBroken && - test_cmp expected_putBrokenErr actual_putBrokenErr - ' - test_expect_success "'ipfs object get --enc=xml' succeeds" ' - ipfs object get --enc=xml $HASH >utf8_xml - ' - - test_expect_success "'ipfs object put --inputenc=xml' succeeds" ' - ipfs object put --inputenc=xml actual - ' - - test_expect_failure "'ipfs object put --inputenc=xml' output looks good" ' - echo "added $HASH\n" >expected && - test_cmp expected actual - ' - - test_expect_success "'ipfs object put file.pb' succeeds" ' - ipfs object put --inputenc=protobuf ../t0051-object-data/testPut.pb > actual_putOut - ' - - test_expect_success "'ipfs object put file.pb' output looks good" ' - HASH="QmUTSAdDi2xsNkDtLqjFgQDMEn5di3Ab9eqbrt4gaiNbUD" && - printf "added $HASH\n" > expected_putOut && - test_cmp expected_putOut actual_putOut - ' - - test_expect_success "'ipfs object put' from stdin succeeds" ' - cat ../t0051-object-data/testPut.json | ipfs object put > actual_putStdinOut - ' - - test_expect_success "'ipfs object put' from stdin output looks good" ' - HASH="QmUTSAdDi2xsNkDtLqjFgQDMEn5di3Ab9eqbrt4gaiNbUD" && - printf "added $HASH\n" > expected_putStdinOut && - test_cmp expected_putStdinOut actual_putStdinOut - ' - - test_expect_success "'ipfs object put' from stdin (pb) succeeds" ' - cat ../t0051-object-data/testPut.pb | ipfs object put --inputenc=protobuf > actual_putPbStdinOut - ' - - test_expect_success "'ipfs object put' from stdin (pb) output looks good" ' - HASH="QmUTSAdDi2xsNkDtLqjFgQDMEn5di3Ab9eqbrt4gaiNbUD" && - printf "added $HASH\n" > expected_putStdinOut && - test_cmp expected_putStdinOut actual_putPbStdinOut - ' - - test_expect_success "'ipfs object put broken.json' should fail" ' - test_expect_code 1 ipfs object put ../t0051-object-data/brokenPut.json 2>actual_putBrokenErr >actual_putBroken - ' - - test_expect_success "'ipfs object put broken.hjson' output looks good" ' - touch expected_putBroken && - printf "Error: json: unknown field \"this\"\n" > expected_putBrokenErr && - test_cmp expected_putBroken actual_putBroken && - test_cmp expected_putBrokenErr actual_putBrokenErr - ' - - test_expect_success "setup: add UTF-8 test file" ' - HASH="QmNY5sQeH9ttVCg24sizH71dNbcZTpGd7Yb3YwsKZ4jiFP" && - ipfs add ../t0051-object-data/UTF-8-test.txt >actual && - echo "added $HASH UTF-8-test.txt" >expected && - test_cmp expected actual - ' - - test_expect_success "'ipfs object get --enc=json' succeeds" ' - ipfs object get --enc=json $HASH >utf8_json - ' - - test_expect_success "'ipfs object put --inputenc=json' succeeds" ' - ipfs object put --inputenc=json actual - ' - - test_expect_failure "'ipfs object put --inputenc=json' output looks good" ' - echo "added $HASH" >expected && - test_cmp expected actual - ' - - test_expect_success "'ipfs object put --pin' succeeds" ' - HASH="QmXg9Pp2ytZ14xgmQjYEiHjVjMFXzCVVEcRTWJBmLgR39V" && - echo "added $HASH" >expected && - echo "{ \"Data\": \"abc\" }" | ipfs object put --pin >actual - ' - - test_expect_success "'ipfs object put --pin' output looks good" ' - echo "added $HASH" >expected && - test_cmp expected actual - ' - - test_expect_success "after gc, objects still accessible" ' - ipfs repo gc > /dev/null && - ipfs refs -r --timeout=2s $HASH > /dev/null - ' + EMPTY_DIR=$(echo '{"Links":[]}' | ipfs dag put --store-codec dag-pb) + EMPTY_UNIXFS_DIR=$(echo '{"Data":{"/":{"bytes":"CAE"}},"Links":[]}' | ipfs dag put --store-codec dag-pb) test_expect_success "'ipfs object patch' should work (no unixfs-dir)" ' - EMPTY_DIR=$(ipfs object new) && OUTPUT=$(ipfs object patch $EMPTY_DIR add-link foo $EMPTY_DIR) && - ipfs object stat $OUTPUT + ipfs dag stat $OUTPUT ' test_expect_success "'ipfs object patch' should work" ' - EMPTY_DIR=$(ipfs object new unixfs-dir) && - OUTPUT=$(ipfs object patch $EMPTY_DIR add-link foo $EMPTY_DIR) && - ipfs object stat $OUTPUT + OUTPUT=$(ipfs object patch $EMPTY_UNIXFS_DIR add-link foo $EMPTY_UNIXFS_DIR) && + ipfs dag stat $OUTPUT ' test_expect_success "'ipfs object patch' check output block size" ' - DIR=$(ipfs object new unixfs-dir) + DIR=$EMPTY_UNIXFS_DIR for i in {1..13} do DIR=$(ipfs object patch "$DIR" add-link "$DIR.jpg" "$DIR") @@ -241,32 +58,20 @@ test_object_cmd() { test_expect_code 0 ipfs object patch --allow-big-block=true "$DIR" add-link "$DIR.jpg" "$DIR" ' - test_expect_success "'ipfs object new foo' shouldn't crash" ' - test_expect_code 1 ipfs object new foo - ' - - test_expect_success "'ipfs object links' gives the correct results" ' - echo "$EMPTY_DIR" 4 foo > expected && - ipfs object links "$OUTPUT" > actual && - test_cmp expected actual - ' - test_expect_success "'ipfs object patch add-link' should work with paths" ' - EMPTY_DIR=$(ipfs object new unixfs-dir) && - N1=$(ipfs object patch $EMPTY_DIR add-link baz $EMPTY_DIR) && - N2=$(ipfs object patch $EMPTY_DIR add-link bar $N1) && - N3=$(ipfs object patch $EMPTY_DIR add-link foo /ipfs/$N2/bar) && - ipfs object stat /ipfs/$N3 > /dev/null && - ipfs object stat $N3/foo > /dev/null && - ipfs object stat /ipfs/$N3/foo/baz > /dev/null + N1=$(ipfs object patch $EMPTY_UNIXFS_DIR add-link baz $EMPTY_UNIXFS_DIR) && + N2=$(ipfs object patch $EMPTY_UNIXFS_DIR add-link bar $N1) && + N3=$(ipfs object patch $EMPTY_UNIXFS_DIR add-link foo /ipfs/$N2/bar) && + ipfs dag stat /ipfs/$N3 > /dev/null && + ipfs dag stat $N3/foo > /dev/null && + ipfs dag stat /ipfs/$N3/foo/baz > /dev/null ' test_expect_success "'ipfs object patch add-link' allow linking IPLD objects" ' - EMPTY_DIR=$(ipfs object new unixfs-dir) && OBJ=$(echo "123" | ipfs dag put) && - N1=$(ipfs object patch $EMPTY_DIR add-link foo $OBJ) && + N1=$(ipfs object patch $EMPTY_UNIXFS_DIR add-link foo $OBJ) && - ipfs object stat /ipfs/$N1 > /dev/null && + ipfs dag stat /ipfs/$N1 > /dev/null && ipfs resolve /ipfs/$N1/foo > actual && echo /ipfs/$OBJ > expected && @@ -274,7 +79,7 @@ test_object_cmd() { ' test_expect_success "object patch creation looks right" ' - echo "QmPc73aWK9dgFBXe86P4PvQizHo9e5Qt7n7DAMXWuigFuG" > hash_exp && + echo "bafybeiakusqwohnt7bs75kx6jhmt4oi47l634bmudxfv4qxhpco6xuvgna" > hash_exp && echo $N3 > hash_actual && test_cmp hash_exp hash_actual ' @@ -282,7 +87,7 @@ test_object_cmd() { test_expect_success "multilayer ipfs patch works" ' echo "hello world" > hwfile && FILE=$(ipfs add -q hwfile) && - EMPTY=$(ipfs object new unixfs-dir) && + EMPTY=$EMPTY_UNIXFS_DIR && ONE=$(ipfs object patch $EMPTY add-link b $EMPTY) && TWO=$(ipfs object patch $EMPTY add-link a $ONE) && ipfs object patch $TWO add-link a/b/c $FILE > multi_patch @@ -293,49 +98,12 @@ test_object_cmd() { test_cmp hwfile hwfile_out ' - test_expect_success "ipfs object stat path succeeds" ' - ipfs object stat $(cat multi_patch)/a > obj_stat_out - ' - - test_expect_success "ipfs object stat output looks good" ' - echo "NumLinks: 1" > obj_stat_exp && - echo "BlockSize: 47" >> obj_stat_exp && - echo "LinksSize: 45" >> obj_stat_exp && - echo "DataSize: 2" >> obj_stat_exp && - echo "CumulativeSize: 114" >> obj_stat_exp && - - test_cmp obj_stat_exp obj_stat_out - ' - - test_expect_success "'ipfs object stat --human' succeeds" ' - ipfs object stat $(cat multi_patch)/a --human > obj_stat_human_out - ' - - test_expect_success "ipfs object stat --human output looks good" ' - echo "NumLinks: 1" > obj_stat_human_exp && - echo "BlockSize: 47" >> obj_stat_human_exp && - echo "LinksSize: 45" >> obj_stat_human_exp && - echo "DataSize: 2" >> obj_stat_human_exp && - echo "CumulativeSize: 114 B" >> obj_stat_human_exp && - - test_cmp obj_stat_human_exp obj_stat_human_out - ' - - test_expect_success "should have created dir within a dir" ' - ipfs ls $OUTPUT > patched_output - ' - - test_expect_success "output looks good" ' - echo "QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn - foo/" > patched_exp && - test_cmp patched_exp patched_output - ' - test_expect_success "can remove the directory" ' ipfs object patch $OUTPUT rm-link foo > rmlink_output ' test_expect_success "output should be empty" ' - echo QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn > rmlink_exp && + echo bafybeiczsscdsbs7ffqz55asqdf3smv6klcw3gofszvwlyarci47bgf354 > rmlink_exp && test_cmp rmlink_exp rmlink_output ' @@ -344,7 +112,7 @@ test_object_cmd() { ' test_expect_success "output looks good" ' - echo "QmZD3r9cZjzU8huNY2JS9TC6n8daDfT8TmE8zBSqG31Wvq" > multi_link_rm_exp && + echo "bafybeicourxysmtbe5hacxqico4d5hyvh7gqkrwlmqa4ew7zufn3pj3juu" > multi_link_rm_exp && test_cmp multi_link_rm_exp multi_link_rm_out ' @@ -355,7 +123,7 @@ test_object_cmd() { test_patch_create_path $EMPTY a/b/b/b/b $FILE test_expect_success "can create blank object" ' - BLANK=$(ipfs object new) + BLANK=$EMPTY_DIR ' test_patch_create_path $BLANK a $FILE @@ -363,98 +131,6 @@ test_object_cmd() { test_expect_success "create bad path fails" ' test_must_fail ipfs object patch $EMPTY add-link --create / $FILE ' - - test_expect_success "patch set-data works" ' - EMPTY=$(ipfs object new) && - HASH=$(printf "foo" | ipfs object patch $EMPTY set-data) - ' - - test_expect_success "output looks good" ' - echo "{\"Links\":[],\"Data\":\"foo\"}" > exp_data_set && - ipfs object get $HASH > actual_data_set && - test_cmp exp_data_set actual_data_set - ' - - test_expect_success "patch append-data works" ' - HASH=$(printf "bar" | ipfs object patch $HASH append-data) - ' - - test_expect_success "output looks good" ' - echo "{\"Links\":[],\"Data\":\"foobar\"}" > exp_data_append && - ipfs object get $HASH > actual_data_append && - test_cmp exp_data_append actual_data_append - ' - - # - # CidBase Tests - # - - test_expect_success "'ipfs object put file.json --cid-base=base32' succeeds" ' - ipfs object put --cid-base=base32 ../t0051-object-data/testPut.json > actual_putOut - ' - - test_expect_success "'ipfs object put file.json --cid-base=base32' output looks good" ' - HASH="QmUTSAdDi2xsNkDtLqjFgQDMEn5di3Ab9eqbrt4gaiNbUD" && - printf "added $HASH\n" > expected_putOut && - test_cmp expected_putOut actual_putOut - ' - - test_expect_success "'ipfs object put file.json --cid-base=base32 --upgrade-cidv0-in-output=true' succeeds" ' - ipfs object put --cid-base=base32 --upgrade-cidv0-in-output=true ../t0051-object-data/testPut.json > actual_putOut - ' - - test_expect_success "'ipfs object put file.json --cid-base=base32 --upgrade-cidv0-in-output=true' output looks good" ' - HASH=$(ipfs cid base32 "QmUTSAdDi2xsNkDtLqjFgQDMEn5di3Ab9eqbrt4gaiNbUD") && - printf "added $HASH\n" > expected_putOut && - test_cmp expected_putOut actual_putOut - ' - - test_expect_success "'insert json dag with both CidV0 and CidV1 links'" ' - MIXED=$(ipfs object put ../t0051-object-data/mixed.json -q) && - echo $MIXED - ' - - test_expect_success "ipfs object get then put creates identical object with --cid-base=base32" ' - ipfs object get --cid-base=base32 $MIXED > mixedv2.json && - MIXED2=$(ipfs object put -q mixedv2.json) && - echo "$MIXED =? $MIXED2" && - test "$MIXED" = "$MIXED2" - ' - - HASHv0=QmXg9Pp2ytZ14xgmQjYEiHjVjMFXzCVVEcRTWJBmLgR39V - HASHv1=bafkqadsimvwgy3zajb2w2yloeefau - - test_expect_success "ipfs object get with --cid-base=base32 uses base32 for CidV1 link only" ' - ipfs object get --cid-base=base32 $MIXED > mixed.actual && - grep -q $HASHv0 mixed.actual && - grep -q $(ipfs cid base32 $HASHv1) mixed.actual - ' - - test_expect_success "ipfs object links --cid-base=base32 --upgrade-cidv0-in-output=true converts both links" ' - ipfs object links --cid-base=base32 --upgrade-cidv0-in-output=true $MIXED | awk "{print \$1}" | sort > links.actual && - echo $(ipfs cid base32 $HASHv1) > links.expected - echo $(ipfs cid base32 $HASHv0) >> links.expected - test_cmp links.actual links.expected - ' -} - -test_object_content_type() { - - test_expect_success "'ipfs object get --encoding=protobuf' returns the correct content type" ' - curl -X POST -sI "http://$API_ADDR/api/v0/object/get?arg=$HASH&encoding=protobuf" | grep -q "^Content-Type: application/protobuf" - ' - - test_expect_success "'ipfs object get --encoding=json' returns the correct content type" ' - curl -X POST -sI "http://$API_ADDR/api/v0/object/get?arg=$HASH&encoding=json" | grep -q "^Content-Type: application/json" - ' - - test_expect_success "'ipfs object get --encoding=text' returns the correct content type" ' - curl -X POST -sI "http://$API_ADDR/api/v0/object/get?arg=$HASH&encoding=text" | grep -q "^Content-Type: text/plain" - ' - - test_expect_success "'ipfs object get --encoding=xml' returns the correct content type" ' - curl -X POST -sI "http://$API_ADDR/api/v0/object/get?arg=$HASH&encoding=xml" | grep -q "^Content-Type: application/xml" - ' } # should work offline @@ -463,7 +139,6 @@ test_object_cmd # should work online test_launch_ipfs_daemon test_object_cmd -test_object_content_type test_kill_ipfs_daemon test_done diff --git a/test/sharness/t0081-repo-pinning.sh b/test/sharness/t0081-repo-pinning.sh index 030f3fa3d..92cb71c38 100755 --- a/test/sharness/t0081-repo-pinning.sh +++ b/test/sharness/t0081-repo-pinning.sh @@ -114,8 +114,8 @@ test_expect_success "objects are there" ' ' # saving this output for later -test_expect_success "ipfs object links $HASH_DIR1 works" ' - ipfs object links $HASH_DIR1 > DIR1_objlink +test_expect_success "ipfs dag get $HASH_DIR1 works" ' + ipfs dag get $HASH_DIR1 | jq -r ".Links[] | .Hash | .[\"/\"]" > DIR1_objlink ' @@ -224,7 +224,7 @@ test_expect_success "some objects are still there" ' ipfs cat "$HASH_FILE1" >>actual8 && ipfs ls "$HASH_DIR4" >>actual8 && ipfs ls "$HASH_DIR2" >>actual8 && - ipfs object links "$HASH_DIR1" >>actual8 && + ipfs dag get "$HASH_DIR1" | jq -r ".Links[] | .Hash | .[\"/\"]" >>actual8 && test_cmp expected8 actual8 ' diff --git a/test/sharness/t0090-get.sh b/test/sharness/t0090-get.sh index 67fee8909..6a803080e 100755 --- a/test/sharness/t0090-get.sh +++ b/test/sharness/t0090-get.sh @@ -157,13 +157,13 @@ test_get_cmd() { test_get_fail() { test_expect_success "create an object that has unresolvable links" ' cat <<-\EOF >bad_object && -{ "Links": [ { "Name": "foo", "Hash": "QmZzaC6ydNXiR65W8VjGA73ET9MZ6VFAqUT1ngYMXcpihn", "Size": 1897 }, { "Name": "bar", "Hash": "Qmd4mG6pDFDmDTn6p3hX1srP8qTbkyXKj5yjpEsiHDX3u8", "Size": 56 }, { "Name": "baz", "Hash": "QmUTjwRnG28dSrFFVTYgbr6LiDLsBmRr2SaUSTGheK2YqG", "Size": 24266 } ], "Data": "\b\u0001" } +{"Data":{"/":{"bytes":"CAE"}},"Links":[{"Hash":{"/":"Qmd4mG6pDFDmDTn6p3hX1srP8qTbkyXKj5yjpEsiHDX3u8"},"Name":"bar","Tsize":56},{"Hash":{"/":"QmUTjwRnG28dSrFFVTYgbr6LiDLsBmRr2SaUSTGheK2YqG"},"Name":"baz","Tsize":24266},{"Hash":{"/":"QmZzaC6ydNXiR65W8VjGA73ET9MZ6VFAqUT1ngYMXcpihn"},"Name":"foo","Tsize":1897}]} EOF - cat bad_object | ipfs object put > put_out + cat bad_object | ipfs dag put --store-codec dag-pb > put_out ' test_expect_success "output looks good" ' - echo "added QmaGidyrnX8FMbWJoxp8HVwZ1uRKwCyxBJzABnR1S2FVUr" > put_exp && + echo "bafybeifrjjol3gixedca6etdwccnvwfvhurc4wb3i5mnk2rvwvyfcgwxd4" > put_exp && test_cmp put_exp put_out ' diff --git a/test/sharness/t0252-files-gc.sh b/test/sharness/t0252-files-gc.sh index 7267985d4..f2eb25b4f 100755 --- a/test/sharness/t0252-files-gc.sh +++ b/test/sharness/t0252-files-gc.sh @@ -38,9 +38,9 @@ test_expect_success "gc okay after adding incomplete node -- prep" ' ' test_expect_success "gc okay after adding incomplete node" ' - ipfs object stat $ADIR_HASH && + ipfs dag get $ADIR_HASH && ipfs repo gc && - ipfs object stat $ADIR_HASH + ipfs dag get $ADIR_HASH ' test_expect_success "add directory with direct pin" ' From 62eb1439157ea8de385671cb513e8ece10e43baf Mon Sep 17 00:00:00 2001 From: occupyhabit <164632559+occupyhabit@users.noreply.github.com> Date: Mon, 25 Mar 2024 16:59:47 +0800 Subject: [PATCH 1063/1212] docs: fix some typos (#10377) --- client/rpc/errors.go | 2 +- test/cli/dag_test.go | 2 +- test/sharness/t0119-prometheus.sh | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/client/rpc/errors.go b/client/rpc/errors.go index 84340b550..6c136ebef 100644 --- a/client/rpc/errors.go +++ b/client/rpc/errors.go @@ -138,7 +138,7 @@ func parseIPLDErrNotFound(msg string) (error, bool) { // This is a simple error type that just return msg as Error(). // But that also match ipld.ErrNotFound when called with Is(err). -// That is needed to keep compatiblity with code that use string.Contains(err.Error(), "blockstore: block not found") +// That is needed to keep compatibility with code that use string.Contains(err.Error(), "blockstore: block not found") // and code using ipld.ErrNotFound. type blockstoreNotFoundMatchingIPLDErrNotFound struct { msg string diff --git a/test/cli/dag_test.go b/test/cli/dag_test.go index d17b71cfb..1a3defc3c 100644 --- a/test/cli/dag_test.go +++ b/test/cli/dag_test.go @@ -36,7 +36,7 @@ type Data struct { // The Fixture file represents a dag where 2 nodes of size = 46B each, have a common child of 7B // when traversing the DAG from the root's children (node1 and node2) we count (46 + 7)x2 bytes (counting redundant bytes) = 106 // since both nodes share a common child of 7 bytes we actually had to read (46)x2 + 7 = 99 bytes -// we should get a dedup ratio of 106/99 that results in approximatelly 1.0707071 +// we should get a dedup ratio of 106/99 that results in approximately 1.0707071 func TestDag(t *testing.T) { t.Parallel() diff --git a/test/sharness/t0119-prometheus.sh b/test/sharness/t0119-prometheus.sh index 0e00f088a..fef204e23 100755 --- a/test/sharness/t0119-prometheus.sh +++ b/test/sharness/t0119-prometheus.sh @@ -33,7 +33,7 @@ test_expect_success "make sure metrics haven't changed" ' # Check what was added by enabling ResourceMgr.Enabled # # NOTE: we won't see all the dynamic ones, but that is ok: the point of the -# test here is to detect regression when rcmgr metrics dissapear due to +# test here is to detect regression when rcmgr metrics disappear due to # refactor/human error. test_expect_success "enable ResourceMgr in the config" ' From b7b6137170ce7537cf70cb1272ddbce84440981d Mon Sep 17 00:00:00 2001 From: hayden Date: Wed, 3 Apr 2024 01:38:56 -0400 Subject: [PATCH 1064/1212] chore: upgrade go-libp2p v0.33.2 (#10381) Signed-off-by: hfuss Co-authored-by: Henrique Dias --- docs/examples/kubo-as-a-library/go.mod | 6 +++--- docs/examples/kubo-as-a-library/go.sum | 14 ++++++++------ go.mod | 6 +++--- go.sum | 14 ++++++++------ test/dependencies/go.mod | 4 ++-- test/dependencies/go.sum | 12 ++++++------ 6 files changed, 30 insertions(+), 26 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 3ed4e2cb5..d08b0e03b 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -11,8 +11,8 @@ replace github.com/ipfs/kubo => ./../../.. require ( github.com/ipfs/boxo v0.18.0 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 - github.com/libp2p/go-libp2p v0.33.0 - github.com/multiformats/go-multiaddr v0.12.2 + github.com/libp2p/go-libp2p v0.33.2 + github.com/multiformats/go-multiaddr v0.12.3 ) require ( @@ -163,7 +163,7 @@ require ( github.com/prometheus/common v0.49.0 // indirect github.com/prometheus/procfs v0.12.0 // indirect github.com/quic-go/qpack v0.4.0 // indirect - github.com/quic-go/quic-go v0.41.0 // indirect + github.com/quic-go/quic-go v0.42.0 // indirect github.com/quic-go/webtransport-go v0.6.0 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/samber/lo v1.39.0 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 45c82eb47..776b61490 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -422,8 +422,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.33.0 h1:yTPSr8sJRbfeEYXyeN8VPVSlTlFjtMUwGDRniwaf/xQ= -github.com/libp2p/go-libp2p v0.33.0/go.mod h1:RIJFRQVUBKy82dnW7J5f1homqqv6NcsDJAl3e7CRGfE= +github.com/libp2p/go-libp2p v0.33.2 h1:vCdwnFxoGOXMKmaGHlDSnL4bM3fQeW8pgIa9DECnb40= +github.com/libp2p/go-libp2p v0.33.2/go.mod h1:zTeppLuCvUIkT118pFVzA8xzP/p2dJYOMApCkFh0Yww= github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94= github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= @@ -514,8 +514,8 @@ github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a github.com/multiformats/go-multiaddr v0.1.0/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo= github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4= -github.com/multiformats/go-multiaddr v0.12.2 h1:9G9sTY/wCYajKa9lyfWPmpZAwe6oV+Wb1zcmMS1HG24= -github.com/multiformats/go-multiaddr v0.12.2/go.mod h1:GKyaTYjZRdcUhyOetrxTk9z0cW+jA/YrnqTOvKgi44M= +github.com/multiformats/go-multiaddr v0.12.3 h1:hVBXvPRcKG0w80VinQ23P5t7czWgg65BmIvQKjDydU8= +github.com/multiformats/go-multiaddr v0.12.3/go.mod h1:sBXrNzucqkFJhvKOiwwLyqamGa/P5EIXNPLovyhQCII= github.com/multiformats/go-multiaddr-dns v0.3.0/go.mod h1:mNzQ4eTGDg0ll1N9jKPOUogZPoJ30W8a7zk66FQPpdQ= github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A= github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk= @@ -650,8 +650,8 @@ github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= -github.com/quic-go/quic-go v0.41.0 h1:aD8MmHfgqTURWNJy48IYFg2OnxwHT3JL7ahGs73lb4k= -github.com/quic-go/quic-go v0.41.0/go.mod h1:qCkNjqczPEvgsOnxZ0eCD14lv+B2LHlFAB++CNOh9hA= +github.com/quic-go/quic-go v0.42.0 h1:uSfdap0eveIl8KXnipv9K7nlwZ5IqLlYOpJ58u5utpM= +github.com/quic-go/quic-go v0.42.0/go.mod h1:132kz4kL3F9vxhW3CtQJLDVwcFe5wdWeJXXijhsO57M= github.com/quic-go/webtransport-go v0.6.0 h1:CvNsKqc4W2HljHJnoT+rMmbRJybShZ0YPFDD3NxaZLY= github.com/quic-go/webtransport-go v0.6.0/go.mod h1:9KjU4AEBqEQidGHNDkZrb8CAa1abRaosM2yGOyiikEc= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= @@ -1038,6 +1038,8 @@ golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= +golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/go.mod b/go.mod index d07b3ee8e..736901ae5 100644 --- a/go.mod +++ b/go.mod @@ -47,7 +47,7 @@ require ( github.com/jbenet/goprocess v0.1.4 github.com/julienschmidt/httprouter v1.3.0 github.com/libp2p/go-doh-resolver v0.4.0 - github.com/libp2p/go-libp2p v0.33.0 + github.com/libp2p/go-libp2p v0.33.2 github.com/libp2p/go-libp2p-http v0.5.0 github.com/libp2p/go-libp2p-kad-dht v0.24.4 github.com/libp2p/go-libp2p-kbucket v0.6.3 @@ -58,7 +58,7 @@ require ( github.com/libp2p/go-libp2p-testing v0.12.0 github.com/libp2p/go-socket-activation v0.1.0 github.com/mitchellh/go-homedir v1.1.0 - github.com/multiformats/go-multiaddr v0.12.2 + github.com/multiformats/go-multiaddr v0.12.3 github.com/multiformats/go-multiaddr-dns v0.3.1 github.com/multiformats/go-multibase v0.2.0 github.com/multiformats/go-multicodec v0.9.0 @@ -204,7 +204,7 @@ require ( github.com/prometheus/procfs v0.12.0 // indirect github.com/prometheus/statsd_exporter v0.22.7 // indirect github.com/quic-go/qpack v0.4.0 // indirect - github.com/quic-go/quic-go v0.41.0 // indirect + github.com/quic-go/quic-go v0.42.0 // indirect github.com/quic-go/webtransport-go v0.6.0 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/rs/cors v1.7.0 // indirect diff --git a/go.sum b/go.sum index fc2a4142c..17e57d561 100644 --- a/go.sum +++ b/go.sum @@ -508,8 +508,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.33.0 h1:yTPSr8sJRbfeEYXyeN8VPVSlTlFjtMUwGDRniwaf/xQ= -github.com/libp2p/go-libp2p v0.33.0/go.mod h1:RIJFRQVUBKy82dnW7J5f1homqqv6NcsDJAl3e7CRGfE= +github.com/libp2p/go-libp2p v0.33.2 h1:vCdwnFxoGOXMKmaGHlDSnL4bM3fQeW8pgIa9DECnb40= +github.com/libp2p/go-libp2p v0.33.2/go.mod h1:zTeppLuCvUIkT118pFVzA8xzP/p2dJYOMApCkFh0Yww= github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94= github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= @@ -619,8 +619,8 @@ github.com/multiformats/go-multiaddr v0.1.0/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lg github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo= github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4= github.com/multiformats/go-multiaddr v0.4.0/go.mod h1:YcpyLH8ZPudLxQlemYBPhSm0/oCXAT8Z4mzFpyoPyRc= -github.com/multiformats/go-multiaddr v0.12.2 h1:9G9sTY/wCYajKa9lyfWPmpZAwe6oV+Wb1zcmMS1HG24= -github.com/multiformats/go-multiaddr v0.12.2/go.mod h1:GKyaTYjZRdcUhyOetrxTk9z0cW+jA/YrnqTOvKgi44M= +github.com/multiformats/go-multiaddr v0.12.3 h1:hVBXvPRcKG0w80VinQ23P5t7czWgg65BmIvQKjDydU8= +github.com/multiformats/go-multiaddr v0.12.3/go.mod h1:sBXrNzucqkFJhvKOiwwLyqamGa/P5EIXNPLovyhQCII= github.com/multiformats/go-multiaddr-dns v0.3.0/go.mod h1:mNzQ4eTGDg0ll1N9jKPOUogZPoJ30W8a7zk66FQPpdQ= github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A= github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk= @@ -784,8 +784,8 @@ github.com/prometheus/statsd_exporter v0.22.7 h1:7Pji/i2GuhK6Lu7DHrtTkFmNBCudCPT github.com/prometheus/statsd_exporter v0.22.7/go.mod h1:N/TevpjkIh9ccs6nuzY3jQn9dFqnUakOjnEuMPJJJnI= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= -github.com/quic-go/quic-go v0.41.0 h1:aD8MmHfgqTURWNJy48IYFg2OnxwHT3JL7ahGs73lb4k= -github.com/quic-go/quic-go v0.41.0/go.mod h1:qCkNjqczPEvgsOnxZ0eCD14lv+B2LHlFAB++CNOh9hA= +github.com/quic-go/quic-go v0.42.0 h1:uSfdap0eveIl8KXnipv9K7nlwZ5IqLlYOpJ58u5utpM= +github.com/quic-go/quic-go v0.42.0/go.mod h1:132kz4kL3F9vxhW3CtQJLDVwcFe5wdWeJXXijhsO57M= github.com/quic-go/webtransport-go v0.6.0 h1:CvNsKqc4W2HljHJnoT+rMmbRJybShZ0YPFDD3NxaZLY= github.com/quic-go/webtransport-go v0.6.0/go.mod h1:9KjU4AEBqEQidGHNDkZrb8CAa1abRaosM2yGOyiikEc= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= @@ -1259,6 +1259,8 @@ golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= +golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 6fc84587f..a5a69e9c5 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -16,7 +16,7 @@ require ( github.com/ipfs/iptb-plugins v0.5.0 github.com/jbenet/go-random v0.0.0-20190219211222-123a90aedc0c github.com/jbenet/go-random-files v0.0.0-20190219210431-31b3f20ebded - github.com/multiformats/go-multiaddr v0.12.2 + github.com/multiformats/go-multiaddr v0.12.3 github.com/multiformats/go-multihash v0.2.3 gotest.tools/gotestsum v0.4.2 ) @@ -135,7 +135,7 @@ require ( github.com/leonklingele/grouper v1.1.1 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/libp2p/go-cidranger v1.1.0 // indirect - github.com/libp2p/go-libp2p v0.33.0 // indirect + github.com/libp2p/go-libp2p v0.33.2 // indirect github.com/libp2p/go-libp2p-asn-util v0.4.1 // indirect github.com/libp2p/go-libp2p-kad-dht v0.25.2 // indirect github.com/libp2p/go-libp2p-kbucket v0.6.3 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 3c422c295..eda0c9b8f 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -480,8 +480,8 @@ github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38y github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.33.0 h1:yTPSr8sJRbfeEYXyeN8VPVSlTlFjtMUwGDRniwaf/xQ= -github.com/libp2p/go-libp2p v0.33.0/go.mod h1:RIJFRQVUBKy82dnW7J5f1homqqv6NcsDJAl3e7CRGfE= +github.com/libp2p/go-libp2p v0.33.2 h1:vCdwnFxoGOXMKmaGHlDSnL4bM3fQeW8pgIa9DECnb40= +github.com/libp2p/go-libp2p v0.33.2/go.mod h1:zTeppLuCvUIkT118pFVzA8xzP/p2dJYOMApCkFh0Yww= github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94= github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= github.com/libp2p/go-libp2p-kad-dht v0.25.2 h1:FOIk9gHoe4YRWXTu8SY9Z1d0RILol0TrtApsMDPjAVQ= @@ -563,8 +563,8 @@ github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYg github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0= github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4= github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4= -github.com/multiformats/go-multiaddr v0.12.2 h1:9G9sTY/wCYajKa9lyfWPmpZAwe6oV+Wb1zcmMS1HG24= -github.com/multiformats/go-multiaddr v0.12.2/go.mod h1:GKyaTYjZRdcUhyOetrxTk9z0cW+jA/YrnqTOvKgi44M= +github.com/multiformats/go-multiaddr v0.12.3 h1:hVBXvPRcKG0w80VinQ23P5t7czWgg65BmIvQKjDydU8= +github.com/multiformats/go-multiaddr v0.12.3/go.mod h1:sBXrNzucqkFJhvKOiwwLyqamGa/P5EIXNPLovyhQCII= github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A= github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk= github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E= @@ -666,8 +666,8 @@ github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 h1:M8mH9eK4OUR4l github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567/go.mod h1:DWNGW8A4Y+GyBgPuaQJuWiy0XYftx4Xm/y5Jqk9I6VQ= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= -github.com/quic-go/quic-go v0.41.0 h1:aD8MmHfgqTURWNJy48IYFg2OnxwHT3JL7ahGs73lb4k= -github.com/quic-go/quic-go v0.41.0/go.mod h1:qCkNjqczPEvgsOnxZ0eCD14lv+B2LHlFAB++CNOh9hA= +github.com/quic-go/quic-go v0.42.0 h1:uSfdap0eveIl8KXnipv9K7nlwZ5IqLlYOpJ58u5utpM= +github.com/quic-go/quic-go v0.42.0/go.mod h1:132kz4kL3F9vxhW3CtQJLDVwcFe5wdWeJXXijhsO57M= github.com/quic-go/webtransport-go v0.6.0 h1:CvNsKqc4W2HljHJnoT+rMmbRJybShZ0YPFDD3NxaZLY= github.com/quic-go/webtransport-go v0.6.0/go.mod h1:9KjU4AEBqEQidGHNDkZrb8CAa1abRaosM2yGOyiikEc= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= From efceaec7da0a30f8b0fcf690f1d1272d3e41d71f Mon Sep 17 00:00:00 2001 From: crazehang <165746307+crazehang@users.noreply.github.com> Date: Wed, 3 Apr 2024 19:29:32 +0800 Subject: [PATCH 1065/1212] core: fix some typos (#10382) Signed-off-by: crazehang --- core/coreiface/tests/unixfs.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/coreiface/tests/unixfs.go b/core/coreiface/tests/unixfs.go index 0dca0218b..9d3362b9a 100644 --- a/core/coreiface/tests/unixfs.go +++ b/core/coreiface/tests/unixfs.go @@ -571,7 +571,7 @@ func (tp *TestSuite) TestAddHashOnly(t *testing.T) { } if p.String() != hello { - t.Errorf("unxepected path: %s", p.String()) + t.Errorf("unexpected path: %s", p.String()) } _, err = api.Block().Get(ctx, p) @@ -579,7 +579,7 @@ func (tp *TestSuite) TestAddHashOnly(t *testing.T) { t.Fatal("expected an error") } if !ipld.IsNotFound(err) { - t.Errorf("unxepected error: %s", err.Error()) + t.Errorf("unexpected error: %s", err.Error()) } } From c1ade2e86cf079c83771d1dbb861c6c5e0801364 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 3 Apr 2024 15:55:25 +0200 Subject: [PATCH 1066/1212] chore(deps): bump codecov/codecov-action from 4.0.1 to 4.1.1 (#10379) --- .github/workflows/gotest.yml | 2 +- .github/workflows/sharness.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/gotest.yml b/.github/workflows/gotest.yml index 1d8c75e5e..35865c14e 100644 --- a/.github/workflows/gotest.yml +++ b/.github/workflows/gotest.yml @@ -45,7 +45,7 @@ jobs: make -j "$PARALLEL" test/unit/gotest.junit.xml && [[ ! $(jq -s -c 'map(select(.Action == "fail")) | .[]' test/unit/gotest.json) ]] - name: Upload coverage to Codecov - uses: codecov/codecov-action@e0b68c6749509c5f83f984dd99a76a1c1a231044 # v4.0.1 + uses: codecov/codecov-action@c16abc29c95fcf9174b58eb7e1abf4c866893bc8 # v4.1.1 if: failure() || success() with: name: unittests diff --git a/.github/workflows/sharness.yml b/.github/workflows/sharness.yml index 9e6c33e7f..5a3a16066 100644 --- a/.github/workflows/sharness.yml +++ b/.github/workflows/sharness.yml @@ -55,7 +55,7 @@ jobs: # increasing parallelism beyond 10 doesn't speed up the tests much PARALLEL: ${{ github.repository == 'ipfs/kubo' && 10 || 3 }} - name: Upload coverage report - uses: codecov/codecov-action@e0b68c6749509c5f83f984dd99a76a1c1a231044 # v4.0.1 + uses: codecov/codecov-action@c16abc29c95fcf9174b58eb7e1abf4c866893bc8 # v4.1.1 if: failure() || success() with: name: sharness From 78a96e3faf477a6f0d35e531343813d60189e070 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 3 Apr 2024 15:55:37 +0200 Subject: [PATCH 1067/1212] chore(deps): bump docker/login-action from 3.0.0 to 3.1.0 (#10373) --- .github/workflows/docker-image.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index 33c5bb549..9c2f6d4ea 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -63,7 +63,7 @@ jobs: shell: bash - name: Log in to Docker Hub - uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d + uses: docker/login-action@e92390c5fb421da1463c202d546fed0ec5c39f20 with: username: ${{ vars.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} From 6d535072dcacfb444f10ed477f82d177800b7aca Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Wed, 3 Apr 2024 20:09:06 +0200 Subject: [PATCH 1068/1212] fix: switch lowpower profile to autoclient We missed this in https://github.com/ipfs/kubo/pull/9708 --- config/profile.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/profile.go b/config/profile.go index 83d53359d..24bbe1533 100644 --- a/config/profile.go +++ b/config/profile.go @@ -174,7 +174,7 @@ functionality - performance of content discovery and data fetching may be degraded. `, Transform: func(c *Config) error { - c.Routing.Type = NewOptionalString("dhtclient") // TODO: https://github.com/ipfs/kubo/issues/9480 + c.Routing.Type = NewOptionalString("autoclient") c.AutoNAT.ServiceMode = AutoNATServiceDisabled c.Reprovider.Interval = NewOptionalDuration(0) From cd78f2eae3bdd04f9265a71dac91984ae457a86d Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Thu, 4 Apr 2024 13:59:31 +0200 Subject: [PATCH 1069/1212] chore(config): make Routing.AcceleratedDHTClient a Flag (#10384) --- cmd/ipfs/kubo/daemon.go | 2 +- config/routing.go | 6 +++++- core/node/groups.go | 2 +- core/node/libp2p/routing.go | 2 +- docs/config.md | 2 +- 5 files changed, 9 insertions(+), 5 deletions(-) diff --git a/cmd/ipfs/kubo/daemon.go b/cmd/ipfs/kubo/daemon.go index 0fcd0e556..ab034b20a 100644 --- a/cmd/ipfs/kubo/daemon.go +++ b/cmd/ipfs/kubo/daemon.go @@ -424,7 +424,7 @@ func daemonFunc(req *cmds.Request, re cmds.ResponseEmitter, env cmds.Environment case routingOptionNoneKwd: ncfg.Routing = libp2p.NilRouterOption case routingOptionCustomKwd: - if cfg.Routing.AcceleratedDHTClient { + if cfg.Routing.AcceleratedDHTClient.WithDefault(config.DefaultAcceleratedDHTClient) { return fmt.Errorf("Routing.AcceleratedDHTClient option is set even tho Routing.Type is custom, using custom .AcceleratedDHTClient needs to be set on DHT routers individually") } ncfg.Routing = libp2p.ConstructDelegatedRouting( diff --git a/config/routing.go b/config/routing.go index 60faa605c..f8941f848 100644 --- a/config/routing.go +++ b/config/routing.go @@ -6,6 +6,10 @@ import ( "runtime" ) +var ( + DefaultAcceleratedDHTClient = false +) + // Routing defines configuration options for libp2p routing. type Routing struct { // Type sets default daemon routing mode. @@ -15,7 +19,7 @@ type Routing struct { // When "custom" is set, user-provided Routing.Routers is used. Type *OptionalString `json:",omitempty"` - AcceleratedDHTClient bool + AcceleratedDHTClient Flag `json:",omitempty"` Routers Routers diff --git a/core/node/groups.go b/core/node/groups.go index c0270bbe1..3df945fd2 100644 --- a/core/node/groups.go +++ b/core/node/groups.go @@ -286,7 +286,7 @@ func Online(bcfg *BuildCfg, cfg *config.Config, userResourceOverrides rcmgr.Part cfg.Experimental.StrategicProviding, cfg.Reprovider.Strategy.WithDefault(config.DefaultReproviderStrategy), cfg.Reprovider.Interval.WithDefault(config.DefaultReproviderInterval), - cfg.Routing.AcceleratedDHTClient, + cfg.Routing.AcceleratedDHTClient.WithDefault(config.DefaultAcceleratedDHTClient), ), ) } diff --git a/core/node/libp2p/routing.go b/core/node/libp2p/routing.go index 98234f5ce..697bf0f2e 100644 --- a/core/node/libp2p/routing.go +++ b/core/node/libp2p/routing.go @@ -90,7 +90,7 @@ func BaseRouting(cfg *config.Config) interface{} { } } - if dualDHT != nil && cfg.Routing.AcceleratedDHTClient { + if dualDHT != nil && cfg.Routing.AcceleratedDHTClient.WithDefault(config.DefaultAcceleratedDHTClient) { cfg, err := in.Repo.Config() if err != nil { return out, err diff --git a/docs/config.md b/docs/config.md index 0fa5000ac..d9addc713 100644 --- a/docs/config.md +++ b/docs/config.md @@ -1610,7 +1610,7 @@ them Default: `false` -Type: `bool` (missing means `false`) +Type: `flag` ### `Routing.Routers` From 11183bb2f530234007eed4a3ae3e924880b3df33 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Thu, 4 Apr 2024 14:56:19 +0200 Subject: [PATCH 1070/1212] chore: upgrade go-libp2p-kad-dht (#10378) * chore: upgrade go-libp2p-kad-dht * config: make LoopbackAddressesOnLanDHT a Flag * config: add DefaultLoopbackAddressesOnLanDHT * docs(config): Routing.LoopbackAddressesOnLanDHT --------- Co-authored-by: Marcin Rataj --- client/rpc/api_test.go | 1 - config/profile.go | 1 + config/routing.go | 5 ++++- core/node/libp2p/host.go | 2 ++ core/node/libp2p/routingopt.go | 11 ++++++++++- docs/changelogs/v0.28.md | 7 +++++++ docs/config.md | 13 +++++++++++++ go.mod | 2 +- go.sum | 4 ++-- test/cli/harness/node.go | 1 + test/sharness/lib/iptb-lib.sh | 4 ++++ test/sharness/t0131-multinode-client-routing.sh | 3 ++- test/sharness/t0142-testfilter.sh | 3 ++- test/sharness/t0181-private-network.sh | 1 + test/sharness/t0182-circuit-relay.sh | 3 ++- test/sharness/t0184-http-proxy-over-p2p.sh | 1 + test/sharness/t0276-cidv0v1.sh | 3 ++- 17 files changed, 55 insertions(+), 10 deletions(-) diff --git a/client/rpc/api_test.go b/client/rpc/api_test.go index 25bd26cee..c0da3d7b0 100644 --- a/client/rpc/api_test.go +++ b/client/rpc/api_test.go @@ -46,7 +46,6 @@ func (np NodeProvider) MakeAPISwarm(t *testing.T, ctx context.Context, fullIdent c := n.ReadConfig() c.Experimental.FilestoreEnabled = true n.WriteConfig(c) - n.StartDaemon("--enable-pubsub-experiment", "--offline="+strconv.FormatBool(!online)) if online { diff --git a/config/profile.go b/config/profile.go index 24bbe1533..068498715 100644 --- a/config/profile.go +++ b/config/profile.go @@ -82,6 +82,7 @@ is useful when using the daemon in test environments.`, } c.Swarm.DisableNatPortMap = true + c.Routing.LoopbackAddressesOnLanDHT = True c.Bootstrap = []string{} c.Discovery.MDNS.Enabled = false diff --git a/config/routing.go b/config/routing.go index f8941f848..231cbca73 100644 --- a/config/routing.go +++ b/config/routing.go @@ -7,7 +7,8 @@ import ( ) var ( - DefaultAcceleratedDHTClient = false + DefaultAcceleratedDHTClient = false + DefaultLoopbackAddressesOnLanDHT = false ) // Routing defines configuration options for libp2p routing. @@ -21,6 +22,8 @@ type Routing struct { AcceleratedDHTClient Flag `json:",omitempty"` + LoopbackAddressesOnLanDHT Flag `json:",omitempty"` + Routers Routers Methods Methods diff --git a/core/node/libp2p/host.go b/core/node/libp2p/host.go index afbd2080c..7950f3dc6 100644 --- a/core/node/libp2p/host.go +++ b/core/node/libp2p/host.go @@ -11,6 +11,7 @@ import ( "github.com/libp2p/go-libp2p/core/routing" routedhost "github.com/libp2p/go-libp2p/p2p/host/routed" + "github.com/ipfs/kubo/config" "github.com/ipfs/kubo/core/node/helpers" "github.com/ipfs/kubo/repo" @@ -60,6 +61,7 @@ func Host(mctx helpers.MetricsCtx, lc fx.Lifecycle, params P2PHostIn) (out P2PHo BootstrapPeers: bootstrappers, OptimisticProvide: cfg.Experimental.OptimisticProvide, OptimisticProvideJobsPoolSize: cfg.Experimental.OptimisticProvideJobsPoolSize, + LoopbackAddressesOnLanDHT: cfg.Routing.LoopbackAddressesOnLanDHT.WithDefault(config.DefaultLoopbackAddressesOnLanDHT), } opts = append(opts, libp2p.Routing(func(h host.Host) (routing.PeerRouting, error) { args := routingOptArgs diff --git a/core/node/libp2p/routingopt.go b/core/node/libp2p/routingopt.go index a58a8c498..869b7ef06 100644 --- a/core/node/libp2p/routingopt.go +++ b/core/node/libp2p/routingopt.go @@ -26,6 +26,7 @@ type RoutingOptionArgs struct { BootstrapPeers []peer.AddrInfo OptimisticProvide bool OptimisticProvideJobsPoolSize int + LoopbackAddressesOnLanDHT bool } type RoutingOption func(args RoutingOptionArgs) (routing.Routing, error) @@ -116,10 +117,18 @@ func constructDHTRouting(mode dht.ModeOpt) RoutingOption { if args.OptimisticProvideJobsPoolSize != 0 { dhtOpts = append(dhtOpts, dht.OptimisticProvideJobsPoolSize(args.OptimisticProvideJobsPoolSize)) } + wanOptions := []dht.Option{ + dht.BootstrapPeers(args.BootstrapPeers...), + } + lanOptions := []dht.Option{} + if args.LoopbackAddressesOnLanDHT { + lanOptions = append(lanOptions, dht.AddressFilter(nil)) + } return dual.New( args.Ctx, args.Host, dual.DHTOption(dhtOpts...), - dual.WanDHTOption(dht.BootstrapPeers(args.BootstrapPeers...)), + dual.WanDHTOption(wanOptions...), + dual.LanDHTOption(lanOptions...), ) } } diff --git a/docs/changelogs/v0.28.md b/docs/changelogs/v0.28.md index 0d399c6ec..7e5361eb5 100644 --- a/docs/changelogs/v0.28.md +++ b/docs/changelogs/v0.28.md @@ -9,6 +9,7 @@ - [RPC client: removed deprecated DHT API](#rpc-client-removed-deprecated-dht-api) - [Gateway: `/api/v0` is removed](#gateway-apiv0-is-removed) - [Removed deprecated Object API commands](#removed-deprecated-object-api-commands) + - [No longer publishes loopback and private addresses on DHT](#no-longer-publishes-loopback-and-private-addresses-on-dht) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -28,6 +29,12 @@ If you have a legacy software that relies on this behavior, and want to expose p The Object API commands deprecated back in [2021](https://github.com/ipfs/kubo/issues/7936) have been removed, except for `object diff`, `object patch add-link` and `object patch rm-link`, whose alternatives have not yet been built (see issues [4801](https://github.com/ipfs/kubo/issues/4801) and [4782](https://github.com/ipfs/kubo/issues/4782)). +##### Kubo ignores loopback addresses on LAN DHT and private addresses on WAN DHT + +Kubo no longer keeps track of loopback and private addresses on the LAN and WAN DHTs, respectively. This means that other nodes will not try to dial likely undialable addresses. + +To support testing scenarios where multiple Kubo instances run on the same machine, [`Routing.LoopbackAddressesOnLanDHT`](https://github.com/ipfs/kubo/blob/master/docs/config.md#routingloopbackaddressesonlandht) is set to `true` when the `test` profile is applied. + ### 📝 Changelog ### 👨‍👩‍👧‍👦 Contributors diff --git a/docs/config.md b/docs/config.md index d9addc713..ad308b18c 100644 --- a/docs/config.md +++ b/docs/config.md @@ -117,6 +117,7 @@ config file at runtime. - [`Routing`](#routing) - [`Routing.Type`](#routingtype) - [`Routing.AcceleratedDHTClient`](#routingaccelerateddhtclient) + - [`Routing.LoopbackAddressesOnLanDHT`](#routingloopbackaddressesonlandht) - [`Routing.Routers`](#routingrouters) - [`Routing.Routers: Type`](#routingrouters-type) - [`Routing.Routers: Parameters`](#routingrouters-parameters) @@ -1612,6 +1613,18 @@ Default: `false` Type: `flag` +### `Routing.LoopbackAddressesOnLanDHT` + +**EXPERIMENTAL: `Routing.LoopbackAddressesOnLanDHT` configuration may change in future release** + +Whether loopback addresses (e.g. 127.0.0.1) should not be ignored on the local LAN DHT. + +Most users do not need this setting. It can be useful during testing, when multiple Kubo nodes run on the same machine but some of them do not have `Discovery.MDNS.Enabled`. + +Default: `false` + +Type: `bool` (missing means `false`) + ### `Routing.Routers` **EXPERIMENTAL: `Routing.Routers` configuration may change in future release** diff --git a/go.mod b/go.mod index 736901ae5..d02a8d8bc 100644 --- a/go.mod +++ b/go.mod @@ -49,7 +49,7 @@ require ( github.com/libp2p/go-doh-resolver v0.4.0 github.com/libp2p/go-libp2p v0.33.2 github.com/libp2p/go-libp2p-http v0.5.0 - github.com/libp2p/go-libp2p-kad-dht v0.24.4 + github.com/libp2p/go-libp2p-kad-dht v0.25.2 github.com/libp2p/go-libp2p-kbucket v0.6.3 github.com/libp2p/go-libp2p-pubsub v0.10.0 github.com/libp2p/go-libp2p-pubsub-router v0.6.0 diff --git a/go.sum b/go.sum index 17e57d561..dc33871f7 100644 --- a/go.sum +++ b/go.sum @@ -518,8 +518,8 @@ github.com/libp2p/go-libp2p-gostream v0.6.0 h1:QfAiWeQRce6pqnYfmIVWJFXNdDyfiR/qk github.com/libp2p/go-libp2p-gostream v0.6.0/go.mod h1:Nywu0gYZwfj7Jc91PQvbGU8dIpqbQQkjWgDuOrFaRdA= github.com/libp2p/go-libp2p-http v0.5.0 h1:+x0AbLaUuLBArHubbbNRTsgWz0RjNTy6DJLOxQ3/QBc= github.com/libp2p/go-libp2p-http v0.5.0/go.mod h1:glh87nZ35XCQyFsdzZps6+F4HYI6DctVFY5u1fehwSg= -github.com/libp2p/go-libp2p-kad-dht v0.24.4 h1:ktNiJe7ffsJ1wX3ULpMCwXts99mPqGFSE/Qn1i8pErQ= -github.com/libp2p/go-libp2p-kad-dht v0.24.4/go.mod h1:ybWBJ5Fbvz9sSLkNtXt+2+bK0JB8+tRPvhBbRGHegRU= +github.com/libp2p/go-libp2p-kad-dht v0.25.2 h1:FOIk9gHoe4YRWXTu8SY9Z1d0RILol0TrtApsMDPjAVQ= +github.com/libp2p/go-libp2p-kad-dht v0.25.2/go.mod h1:6za56ncRHYXX4Nc2vn8z7CZK0P4QiMcrn77acKLM2Oo= github.com/libp2p/go-libp2p-kbucket v0.3.1/go.mod h1:oyjT5O7tS9CQurok++ERgc46YLwEpuGoFq9ubvoUOio= github.com/libp2p/go-libp2p-kbucket v0.6.3 h1:p507271wWzpy2f1XxPzCQG9NiN6R6lHL9GiSErbQQo0= github.com/libp2p/go-libp2p-kbucket v0.6.3/go.mod h1:RCseT7AH6eJWxxk2ol03xtP9pEHetYSPXOaJnOiD8i0= diff --git a/test/cli/harness/node.go b/test/cli/harness/node.go index d030c7c94..ad8ac263b 100644 --- a/test/cli/harness/node.go +++ b/test/cli/harness/node.go @@ -208,6 +208,7 @@ func (n *Node) Init(ipfsArgs ...string) *Node { cfg.Addresses.Gateway = []string{n.GatewayListenAddr.String()} cfg.Swarm.DisableNatPortMap = true cfg.Discovery.MDNS.Enabled = n.EnableMDNS + cfg.Routing.LoopbackAddressesOnLanDHT = config.True }) return n } diff --git a/test/sharness/lib/iptb-lib.sh b/test/sharness/lib/iptb-lib.sh index 3d2e95a49..8b2d956c2 100644 --- a/test/sharness/lib/iptb-lib.sh +++ b/test/sharness/lib/iptb-lib.sh @@ -34,6 +34,10 @@ startup_cluster() { other_args="$@" bound=$(expr "$num_nodes" - 1) + test_expect_success "set Routing.LoopbackAddressesOnLanDHT to true" ' + iptb run [0-$bound] -- ipfs config --json "Routing.LoopbackAddressesOnLanDHT" true + ' + if test -n "$other_args"; then test_expect_success "start up nodes with additional args" " iptb start -wait [0-$bound] -- ${other_args[@]} diff --git a/test/sharness/t0131-multinode-client-routing.sh b/test/sharness/t0131-multinode-client-routing.sh index b62c9790b..8949a1bdf 100755 --- a/test/sharness/t0131-multinode-client-routing.sh +++ b/test/sharness/t0131-multinode-client-routing.sh @@ -43,7 +43,8 @@ run_single_file_test() { NNODES=10 test_expect_success "set up testbed" ' - iptb testbed create -type localipfs -count $NNODES -force -init + iptb testbed create -type localipfs -count $NNODES -force -init && + iptb run -- ipfs config --json "Routing.LoopbackAddressesOnLanDHT" true ' test_expect_success "start up nodes" ' diff --git a/test/sharness/t0142-testfilter.sh b/test/sharness/t0142-testfilter.sh index 971aa6839..bdd7e4f76 100755 --- a/test/sharness/t0142-testfilter.sh +++ b/test/sharness/t0142-testfilter.sh @@ -13,7 +13,8 @@ AF="/ip4/127.0.0.0/ipcidr/24" NUM_NODES=3 test_expect_success "set up testbed" ' - iptb testbed create -type localipfs -count $NUM_NODES -force -init + iptb testbed create -type localipfs -count $NUM_NODES -force -init && + iptb run -- ipfs config --json "Routing.LoopbackAddressesOnLanDHT" true ' test_expect_success 'filter 127.0.0.0/24 on node 1' ' diff --git a/test/sharness/t0181-private-network.sh b/test/sharness/t0181-private-network.sh index 86c6151d3..46dc45cdf 100755 --- a/test/sharness/t0181-private-network.sh +++ b/test/sharness/t0181-private-network.sh @@ -35,6 +35,7 @@ LIBP2P_FORCE_PNET=1 test_launch_ipfs_daemon test_expect_success "set up iptb testbed" ' iptb testbed create -type localipfs -count 5 -force -init && + iptb run -- ipfs config --json "Routing.LoopbackAddressesOnLanDHT" true && iptb run -- ipfs config --json Addresses.Swarm '"'"'["/ip4/127.0.0.1/tcp/0"]'"'"' ' diff --git a/test/sharness/t0182-circuit-relay.sh b/test/sharness/t0182-circuit-relay.sh index d6e439ae3..c79edfc8e 100755 --- a/test/sharness/t0182-circuit-relay.sh +++ b/test/sharness/t0182-circuit-relay.sh @@ -7,7 +7,8 @@ test_description="Test circuit relay" # start iptb + wait for peering NUM_NODES=3 test_expect_success 'init iptb' ' - iptb testbed create -type localipfs -count $NUM_NODES -init + iptb testbed create -type localipfs -count $NUM_NODES -init && + iptb run -- ipfs config --json "Routing.LoopbackAddressesOnLanDHT" true ' # Network toplogy: A <-> Relay <-> B diff --git a/test/sharness/t0184-http-proxy-over-p2p.sh b/test/sharness/t0184-http-proxy-over-p2p.sh index 9c5308277..98e2f3ab2 100755 --- a/test/sharness/t0184-http-proxy-over-p2p.sh +++ b/test/sharness/t0184-http-proxy-over-p2p.sh @@ -142,6 +142,7 @@ function curl_send_multipart_form_request() { test_expect_success 'configure nodes' ' iptb testbed create -type localipfs -count 2 -force -init && + iptb run -- ipfs config --json "Routing.LoopbackAddressesOnLanDHT" true && ipfsi 0 config --json Experimental.Libp2pStreamMounting true && ipfsi 1 config --json Experimental.Libp2pStreamMounting true && ipfsi 0 config --json Experimental.P2pHttpProxy true && diff --git a/test/sharness/t0276-cidv0v1.sh b/test/sharness/t0276-cidv0v1.sh index 2058a9d54..c810f4544 100755 --- a/test/sharness/t0276-cidv0v1.sh +++ b/test/sharness/t0276-cidv0v1.sh @@ -95,7 +95,8 @@ test_expect_success "check that we can access the file when converted to CIDv1" # test_expect_success "set up iptb testbed" ' - iptb testbed create -type localipfs -count 2 -init + iptb testbed create -type localipfs -count 2 -init && + iptb run -- ipfs config --json "Routing.LoopbackAddressesOnLanDHT" true ' test_expect_success "start nodes" ' From 413de0f83137df2347ab2826149fb68b77b74468 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Fri, 5 Apr 2024 23:53:40 +0200 Subject: [PATCH 1071/1212] docs(config): clarify RPC vs Gateway --- docs/config.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/docs/config.md b/docs/config.md index ad308b18c..41c8429b4 100644 --- a/docs/config.md +++ b/docs/config.md @@ -345,8 +345,8 @@ Contains information about various listener addresses to be used by this node. ### `Addresses.API` -Multiaddr or array of multiaddrs describing the address to serve the local HTTP -API on. +Multiaddr or array of multiaddrs describing the address to serve +the local [Kubo RPC API](https://docs.ipfs.tech/reference/kubo/rpc/) (`/api/v0`). Supported Transports: @@ -359,8 +359,8 @@ Type: `strings` (multiaddrs) ### `Addresses.Gateway` -Multiaddr or array of multiaddrs describing the address to serve the local -gateway on. +Multiaddr or array of multiaddrs describing the address to serve +the local [HTTP gateway](https://specs.ipfs.tech/http-gateways/) (`/ipfs`, `/ipns`) on. Supported Transports: @@ -427,10 +427,12 @@ Default: `[]` Type: `array[string]` (multiaddrs) ## `API` -Contains information used by the API gateway. + +Contains information used by the [Kubo RPC API](https://docs.ipfs.tech/reference/kubo/rpc/). ### `API.HTTPHeaders` -Map of HTTP headers to set on responses from the API HTTP server. + +Map of HTTP headers to set on responses from the RPC (`/api/v0`) HTTP server. Example: ```json From 513bc3c0c800517c33c8d72976648c6c151c64ef Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Tue, 9 Apr 2024 08:08:06 +0200 Subject: [PATCH 1072/1212] chore: webui v4.2.1 (#10391) patch release that removes unnecessary requests to countly.ipfs.io which is no longer online https://github.com/ipfs/ipfs-webui/releases/tag/v4.2.1 --- core/corehttp/webui.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/core/corehttp/webui.go b/core/corehttp/webui.go index 5ec6edf15..2e31b2214 100644 --- a/core/corehttp/webui.go +++ b/core/corehttp/webui.go @@ -1,11 +1,12 @@ package corehttp -// TODO: move to IPNS -const WebUIPath = "/ipfs/bafybeidf7cpkwsjkq6xs3r6fbbxghbugilx3jtezbza7gua3k5wjixpmba" // v4.2.0 +// WebUI version confirmed to work with this Kubo version +const WebUIPath = "/ipfs/bafybeigggyffcf6yfhx5irtwzx3cgnk6n3dwylkvcpckzhqqrigsxowjwe" // v4.2.1 // WebUIPaths is a list of all past webUI paths. var WebUIPaths = []string{ WebUIPath, + "/ipfs/bafybeidf7cpkwsjkq6xs3r6fbbxghbugilx3jtezbza7gua3k5wjixpmba", "/ipfs/bafybeiamycmd52xvg6k3nzr6z3n33de6a2teyhquhj4kspdtnvetnkrfim", "/ipfs/bafybeieqdeoqkf7xf4aozd524qncgiloh33qgr25lyzrkusbcre4c3fxay", "/ipfs/bafybeicyp7ssbnj3hdzehcibmapmpuc3atrsc4ch3q6acldfh4ojjdbcxe", From 24031b9b69b92d1e0c5867e72e8d4d30939a56ae Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Apr 2024 21:53:17 +0000 Subject: [PATCH 1073/1212] chore(deps): bump codecov/codecov-action from 4.1.1 to 4.2.0 Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 4.1.1 to 4.2.0. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/c16abc29c95fcf9174b58eb7e1abf4c866893bc8...7afa10ed9b269c561c2336fd862446844e0cbf71) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/gotest.yml | 2 +- .github/workflows/sharness.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/gotest.yml b/.github/workflows/gotest.yml index 35865c14e..2e34922d6 100644 --- a/.github/workflows/gotest.yml +++ b/.github/workflows/gotest.yml @@ -45,7 +45,7 @@ jobs: make -j "$PARALLEL" test/unit/gotest.junit.xml && [[ ! $(jq -s -c 'map(select(.Action == "fail")) | .[]' test/unit/gotest.json) ]] - name: Upload coverage to Codecov - uses: codecov/codecov-action@c16abc29c95fcf9174b58eb7e1abf4c866893bc8 # v4.1.1 + uses: codecov/codecov-action@7afa10ed9b269c561c2336fd862446844e0cbf71 # v4.2.0 if: failure() || success() with: name: unittests diff --git a/.github/workflows/sharness.yml b/.github/workflows/sharness.yml index 5a3a16066..03c04f922 100644 --- a/.github/workflows/sharness.yml +++ b/.github/workflows/sharness.yml @@ -55,7 +55,7 @@ jobs: # increasing parallelism beyond 10 doesn't speed up the tests much PARALLEL: ${{ github.repository == 'ipfs/kubo' && 10 || 3 }} - name: Upload coverage report - uses: codecov/codecov-action@c16abc29c95fcf9174b58eb7e1abf4c866893bc8 # v4.1.1 + uses: codecov/codecov-action@7afa10ed9b269c561c2336fd862446844e0cbf71 # v4.2.0 if: failure() || success() with: name: sharness From 6f2a61e1dfb268db5e534805afd6c2204bc82d71 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Tue, 9 Apr 2024 08:37:23 +0200 Subject: [PATCH 1074/1212] core/node: prioritize announcing pin roots, and flat strategy (#10376) Co-authored-by: Marcin Rataj --- core/node/provider.go | 24 +++- docs/changelogs/v0.28.md | 5 + docs/config.md | 3 + docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 +- go.mod | 2 +- go.sum | 4 +- test/cli/provider_test.go | 165 ++++++++++++++++++++++ test/dependencies/go.mod | 2 +- test/dependencies/go.sum | 4 +- test/sharness/t0175-provider.sh | 34 ----- test/sharness/t0175-reprovider.sh | 140 ------------------ test/sharness/t0175-strategic-provider.sh | 34 ----- 13 files changed, 201 insertions(+), 222 deletions(-) create mode 100644 test/cli/provider_test.go delete mode 100755 test/sharness/t0175-provider.sh delete mode 100755 test/sharness/t0175-reprovider.sh delete mode 100755 test/sharness/t0175-strategic-provider.sh diff --git a/core/node/provider.go b/core/node/provider.go index c1c99e600..b274584ef 100644 --- a/core/node/provider.go +++ b/core/node/provider.go @@ -129,11 +129,13 @@ func OnlineProviders(useStrategicProviding bool, reprovideStrategy string, repro var keyProvider fx.Option switch reprovideStrategy { case "all", "": - keyProvider = fx.Provide(provider.NewBlockstoreProvider) + keyProvider = fx.Provide(newProvidingStrategy(false, false)) case "roots": - keyProvider = fx.Provide(pinnedProviderStrategy(true)) + keyProvider = fx.Provide(newProvidingStrategy(true, true)) case "pinned": - keyProvider = fx.Provide(pinnedProviderStrategy(false)) + keyProvider = fx.Provide(newProvidingStrategy(true, false)) + case "flat": + keyProvider = fx.Provide(provider.NewBlockstoreProvider) default: return fx.Error(fmt.Errorf("unknown reprovider strategy %q", reprovideStrategy)) } @@ -149,13 +151,25 @@ func OfflineProviders() fx.Option { return fx.Provide(provider.NewNoopProvider) } -func pinnedProviderStrategy(onlyRoots bool) interface{} { +func newProvidingStrategy(onlyPinned, onlyRoots bool) interface{} { type input struct { fx.In Pinner pin.Pinner + Blockstore blockstore.Blockstore IPLDFetcher fetcher.Factory `name:"ipldFetcher"` } return func(in input) provider.KeyChanFunc { - return provider.NewPinnedProvider(onlyRoots, in.Pinner, in.IPLDFetcher) + if onlyRoots { + return provider.NewPinnedProvider(true, in.Pinner, in.IPLDFetcher) + } + + if onlyPinned { + return provider.NewPinnedProvider(false, in.Pinner, in.IPLDFetcher) + } + + return provider.NewPrioritizedProvider( + provider.NewPinnedProvider(true, in.Pinner, in.IPLDFetcher), + provider.NewBlockstoreProvider(in.Blockstore), + ) } } diff --git a/docs/changelogs/v0.28.md b/docs/changelogs/v0.28.md index 7e5361eb5..1948509cf 100644 --- a/docs/changelogs/v0.28.md +++ b/docs/changelogs/v0.28.md @@ -10,6 +10,7 @@ - [Gateway: `/api/v0` is removed](#gateway-apiv0-is-removed) - [Removed deprecated Object API commands](#removed-deprecated-object-api-commands) - [No longer publishes loopback and private addresses on DHT](#no-longer-publishes-loopback-and-private-addresses-on-dht) + - [Pin roots are now prioritized when announcing](#pin-roots-are-now-prioritized-when-announcing) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -35,6 +36,10 @@ Kubo no longer keeps track of loopback and private addresses on the LAN and WAN To support testing scenarios where multiple Kubo instances run on the same machine, [`Routing.LoopbackAddressesOnLanDHT`](https://github.com/ipfs/kubo/blob/master/docs/config.md#routingloopbackaddressesonlandht) is set to `true` when the `test` profile is applied. +#### Pin roots are now prioritized when announcing + +The root CIDs of pinned content are now prioritized when announcing to the Amino DHT with [`Reprovider.Strategy`](https://github.com/ipfs/kubo/blob/master/docs/config.md#reproviderstrategy) set to `all` (default) or `pinned`, making the important CIDs accessible faster. + ### 📝 Changelog ### 👨‍👩‍👧‍👦 Contributors diff --git a/docs/config.md b/docs/config.md index 41c8429b4..e36ffebb7 100644 --- a/docs/config.md +++ b/docs/config.md @@ -1503,7 +1503,9 @@ Type: `optionalDuration` (unset for the default) Tells reprovider what should be announced. Valid strategies are: - `"all"` - announce all CIDs of stored blocks + - Order: root blocks of direct and recursive pins are announced first, then the rest of blockstore - `"pinned"` - only announce pinned CIDs recursively (both roots and child blocks) + - Order: root blocks of direct and recursive pins are announced first, then the child blocks of recursive pins - `"roots"` - only announce the root block of explicitly pinned CIDs - **⚠️ BE CAREFUL:** node with `roots` strategy will not announce child blocks. It makes sense only for use cases where the entire DAG is fetched in full, @@ -1512,6 +1514,7 @@ Tells reprovider what should be announced. Valid strategies are: providers for the missing block in the middle of a file, unless the peer happens to already be connected to a provider and ask for child CID over bitswap. +- `"flat"` - same as `all`, announce all CIDs of stored blocks, but without prioritizing anything Default: `"all"` diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index d08b0e03b..4824e9f1a 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -9,7 +9,7 @@ toolchain go1.22.0 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.18.0 + github.com/ipfs/boxo v0.18.1-0.20240409062800-ec207931045d github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.33.2 github.com/multiformats/go-multiaddr v0.12.3 diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 776b61490..6af5e4afb 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -266,8 +266,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.18.0 h1:MOL9/AgoV3e7jlVMInicaSdbgralfqSsbkc31dZ9tmw= -github.com/ipfs/boxo v0.18.0/go.mod h1:pIZgTWdm3k3pLF9Uq6MB8JEcW07UDwNJjlXW1HELW80= +github.com/ipfs/boxo v0.18.1-0.20240409062800-ec207931045d h1:4y8xHp4ZDUgnwXK3a146K/sEYq6BSO/nA46DOLMVp5k= +github.com/ipfs/boxo v0.18.1-0.20240409062800-ec207931045d/go.mod h1:V5gJzbIMwKEXrg3IdvAxIdF7UPgU4RsXmNGS8MQ/0D4= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.3/go.mod h1:4LmD4ZUw0mhO+JSKdpWwrzATiEfM7WWgQ8H5l6P8MVk= diff --git a/go.mod b/go.mod index d02a8d8bc..994645c0c 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,7 @@ require ( github.com/hashicorp/go-multierror v1.1.1 github.com/ipfs-shipyard/nopfs v0.0.12 github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c - github.com/ipfs/boxo v0.18.0 + github.com/ipfs/boxo v0.18.1-0.20240409062800-ec207931045d github.com/ipfs/go-block-format v0.2.0 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 diff --git a/go.sum b/go.sum index dc33871f7..43fe827bd 100644 --- a/go.sum +++ b/go.sum @@ -329,8 +329,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.18.0 h1:MOL9/AgoV3e7jlVMInicaSdbgralfqSsbkc31dZ9tmw= -github.com/ipfs/boxo v0.18.0/go.mod h1:pIZgTWdm3k3pLF9Uq6MB8JEcW07UDwNJjlXW1HELW80= +github.com/ipfs/boxo v0.18.1-0.20240409062800-ec207931045d h1:4y8xHp4ZDUgnwXK3a146K/sEYq6BSO/nA46DOLMVp5k= +github.com/ipfs/boxo v0.18.1-0.20240409062800-ec207931045d/go.mod h1:V5gJzbIMwKEXrg3IdvAxIdF7UPgU4RsXmNGS8MQ/0D4= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= diff --git a/test/cli/provider_test.go b/test/cli/provider_test.go new file mode 100644 index 000000000..5ecf8f3ca --- /dev/null +++ b/test/cli/provider_test.go @@ -0,0 +1,165 @@ +package cli + +import ( + "bytes" + "testing" + "time" + + "github.com/ipfs/kubo/test/cli/harness" + "github.com/ipfs/kubo/test/cli/testutils" + "github.com/stretchr/testify/require" +) + +func TestProvider(t *testing.T) { + t.Parallel() + + initNodes := func(t *testing.T, n int, fn func(n *harness.Node)) harness.Nodes { + nodes := harness.NewT(t).NewNodes(n).Init() + nodes.ForEachPar(fn) + return nodes.StartDaemons().Connect() + } + + expectNoProviders := func(t *testing.T, cid string, nodes ...*harness.Node) { + for _, node := range nodes { + res := node.IPFS("routing", "findprovs", "-n=1", cid) + require.Empty(t, res.Stdout.String()) + } + } + + expectProviders := func(t *testing.T, cid, expectedProvider string, nodes ...*harness.Node) { + for _, node := range nodes { + res := node.IPFS("routing", "findprovs", "-n=1", cid) + require.Equal(t, expectedProvider, res.Stdout.Trimmed()) + } + } + + t.Run("Basic Providing", func(t *testing.T) { + t.Parallel() + + nodes := initNodes(t, 2, func(n *harness.Node) { + n.SetIPFSConfig("Experimental.StrategicProviding", false) + }) + defer nodes.StopDaemons() + + cid := nodes[0].IPFSAddStr(time.Now().String()) + expectProviders(t, cid, nodes[0].PeerID().String(), nodes[1:]...) + }) + + t.Run("Basic Strategic Providing", func(t *testing.T) { + t.Parallel() + + nodes := initNodes(t, 2, func(n *harness.Node) { + n.SetIPFSConfig("Experimental.StrategicProviding", true) + }) + defer nodes.StopDaemons() + + cid := nodes[0].IPFSAddStr(time.Now().String()) + expectNoProviders(t, cid, nodes[1:]...) + }) + + t.Run("Reprovides with 'all' strategy", func(t *testing.T) { + t.Parallel() + + nodes := initNodes(t, 2, func(n *harness.Node) { + n.SetIPFSConfig("Reprovider.Strategy", "all") + }) + defer nodes.StopDaemons() + + cid := nodes[0].IPFSAddStr(time.Now().String(), "--local") + + expectNoProviders(t, cid, nodes[1:]...) + + nodes[0].IPFS("bitswap", "reprovide") + + expectProviders(t, cid, nodes[0].PeerID().String(), nodes[1:]...) + }) + + t.Run("Reprovides with 'flat' strategy", func(t *testing.T) { + t.Parallel() + + nodes := initNodes(t, 2, func(n *harness.Node) { + n.SetIPFSConfig("Reprovider.Strategy", "flat") + }) + defer nodes.StopDaemons() + + cid := nodes[0].IPFSAddStr(time.Now().String(), "--local") + + expectNoProviders(t, cid, nodes[1:]...) + + nodes[0].IPFS("bitswap", "reprovide") + + expectProviders(t, cid, nodes[0].PeerID().String(), nodes[1:]...) + }) + + t.Run("Reprovides with 'pinned' strategy", func(t *testing.T) { + t.Parallel() + + foo := testutils.RandomBytes(1000) + bar := testutils.RandomBytes(1000) + + nodes := initNodes(t, 2, func(n *harness.Node) { + n.SetIPFSConfig("Reprovider.Strategy", "pinned") + }) + defer nodes.StopDaemons() + + cidFoo := nodes[0].IPFSAdd(bytes.NewReader(foo), "--offline", "--pin=false") + cidBar := nodes[0].IPFSAdd(bytes.NewReader(bar), "--offline", "--pin=false") + cidBarDir := nodes[0].IPFSAdd(bytes.NewReader(bar), "-Q", "--offline", "-w") + + expectNoProviders(t, cidFoo, nodes[1:]...) + expectNoProviders(t, cidBar, nodes[1:]...) + expectNoProviders(t, cidBarDir, nodes[1:]...) + + nodes[0].IPFS("bitswap", "reprovide") + + expectNoProviders(t, cidFoo, nodes[1:]...) + expectProviders(t, cidBar, nodes[0].PeerID().String(), nodes[1:]...) + expectProviders(t, cidBarDir, nodes[0].PeerID().String(), nodes[1:]...) + }) + + t.Run("Reprovides with 'roots' strategy", func(t *testing.T) { + t.Parallel() + + foo := testutils.RandomBytes(1000) + bar := testutils.RandomBytes(1000) + baz := testutils.RandomBytes(1000) + + nodes := initNodes(t, 2, func(n *harness.Node) { + n.SetIPFSConfig("Reprovider.Strategy", "roots") + }) + defer nodes.StopDaemons() + + cidFoo := nodes[0].IPFSAdd(bytes.NewReader(foo), "--offline", "--pin=false") + cidBar := nodes[0].IPFSAdd(bytes.NewReader(bar), "--offline", "--pin=false") + cidBaz := nodes[0].IPFSAdd(bytes.NewReader(baz), "--offline") + cidBarDir := nodes[0].IPFSAdd(bytes.NewReader(bar), "-Q", "--offline", "-w") + + expectNoProviders(t, cidFoo, nodes[1:]...) + expectNoProviders(t, cidBar, nodes[1:]...) + expectNoProviders(t, cidBarDir, nodes[1:]...) + + nodes[0].IPFS("bitswap", "reprovide") + + expectNoProviders(t, cidFoo, nodes[1:]...) + expectNoProviders(t, cidBar, nodes[1:]...) + expectProviders(t, cidBaz, nodes[0].PeerID().String(), nodes[1:]...) + expectProviders(t, cidBarDir, nodes[0].PeerID().String(), nodes[1:]...) + }) + + t.Run("Providing works without ticking", func(t *testing.T) { + t.Parallel() + + nodes := initNodes(t, 2, func(n *harness.Node) { + n.SetIPFSConfig("Reprovider.Interval", "0") + }) + defer nodes.StopDaemons() + + cid := nodes[0].IPFSAddStr(time.Now().String(), "--offline") + + expectNoProviders(t, cid, nodes[1:]...) + + nodes[0].IPFS("bitswap", "reprovide") + + expectProviders(t, cid, nodes[0].PeerID().String(), nodes[1:]...) + }) +} diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index a5a69e9c5..203667205 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -105,7 +105,7 @@ require ( github.com/hexops/gotextdiff v1.0.3 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/ipfs/bbloom v0.0.4 // indirect - github.com/ipfs/boxo v0.18.0 // indirect + github.com/ipfs/boxo v0.18.1-0.20240409062800-ec207931045d // indirect github.com/ipfs/go-block-format v0.2.0 // indirect github.com/ipfs/go-cid v0.4.1 // indirect github.com/ipfs/go-datastore v0.6.0 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index eda0c9b8f..d7dac1ad2 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -362,8 +362,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.18.0 h1:MOL9/AgoV3e7jlVMInicaSdbgralfqSsbkc31dZ9tmw= -github.com/ipfs/boxo v0.18.0/go.mod h1:pIZgTWdm3k3pLF9Uq6MB8JEcW07UDwNJjlXW1HELW80= +github.com/ipfs/boxo v0.18.1-0.20240409062800-ec207931045d h1:4y8xHp4ZDUgnwXK3a146K/sEYq6BSO/nA46DOLMVp5k= +github.com/ipfs/boxo v0.18.1-0.20240409062800-ec207931045d/go.mod h1:V5gJzbIMwKEXrg3IdvAxIdF7UPgU4RsXmNGS8MQ/0D4= github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs= github.com/ipfs/go-block-format v0.2.0/go.mod h1:+jpL11nFx5A/SPpsoBn6Bzkra/zaArfSmsknbPMYgzM= github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= diff --git a/test/sharness/t0175-provider.sh b/test/sharness/t0175-provider.sh deleted file mode 100755 index cca110fe1..000000000 --- a/test/sharness/t0175-provider.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/env bash - -test_description="Test reprovider" - -. lib/test-lib.sh - -NUM_NODES=2 - -test_expect_success 'init iptb' ' - iptb testbed create -type localipfs -force -count $NUM_NODES -init -' - -test_expect_success 'peer ids' ' - PEERID_0=$(iptb attr get 0 id) && - PEERID_1=$(iptb attr get 1 id) -' - -test_expect_success 'use strategic providing' ' - iptb run -- ipfs config --json Experimental.StrategicProviding false -' - -startup_cluster ${NUM_NODES} - -test_expect_success 'add test object' ' - HASH_0=$(date +"%FT%T.%N%z" | ipfsi 0 add -q) -' - -findprovs_expect '$HASH_0' '$PEERID_0' - -test_expect_success 'stop node 1' ' - iptb stop -' - -test_done diff --git a/test/sharness/t0175-reprovider.sh b/test/sharness/t0175-reprovider.sh deleted file mode 100755 index 09535ecc4..000000000 --- a/test/sharness/t0175-reprovider.sh +++ /dev/null @@ -1,140 +0,0 @@ -#!/usr/bin/env bash - -test_description="Test reprovider" - -. lib/test-lib.sh - -NUM_NODES=6 - -init_strategy() { - test_expect_success 'init iptb' ' - iptb testbed create -type localipfs -force -count $NUM_NODES -init - ' - - test_expect_success 'peer ids' ' - PEERID_0=$(iptb attr get 0 id) && - PEERID_1=$(iptb attr get 1 id) - ' - - test_expect_success 'use pinning strategy for reprovider' ' - ipfsi 0 config Reprovider.Strategy '$1' - ' - - startup_cluster ${NUM_NODES} -} - -reprovide() { - test_expect_success 'reprovide' ' - # TODO: this hangs, though only after reprovision was done - ipfsi 0 bitswap reprovide - ' -} - -# Test 'all' strategy -init_strategy 'all' - -test_expect_success 'add test object' ' - HASH_0=$(date +"%FT%T.%N%z" | ipfsi 0 add -q --local) -' - -findprovs_empty '$HASH_0' -reprovide -findprovs_expect '$HASH_0' '$PEERID_0' - -test_expect_success 'Stop iptb' ' - iptb stop -' - -# Test 'pinned' strategy -init_strategy 'pinned' - -test_expect_success 'prepare test files' ' - date +"%FT%T.%N%z" > f1 && - date +"%FT%T.%N%z" > f2 -' - -test_expect_success 'add test objects' ' - HASH_FOO=$(ipfsi 0 add -q --offline --pin=false f1) && - HASH_BAR=$(ipfsi 0 add -q --offline --pin=false f2) && - HASH_BAR_DIR=$(ipfsi 0 add -q --offline -w f2) -' - -findprovs_empty '$HASH_FOO' -findprovs_empty '$HASH_BAR' -findprovs_empty '$HASH_BAR_DIR' - -reprovide - -findprovs_empty '$HASH_FOO' -findprovs_expect '$HASH_BAR' '$PEERID_0' -findprovs_expect '$HASH_BAR_DIR' '$PEERID_0' - -test_expect_success 'Stop iptb' ' - iptb stop -' - -# Test 'roots' strategy -init_strategy 'roots' - -test_expect_success 'prepare test files' ' - date +"%FT%T.%N%z" > f1 && - date +"%FT%T.%N%z" > f2 && - date +"%FT%T.%N%z" > f3 -' - -test_expect_success 'add test objects' ' - HASH_FOO=$(ipfsi 0 add -q --offline --pin=false f1) && - HASH_BAR=$(ipfsi 0 add -q --offline --pin=false f2) && - HASH_BAZ=$(ipfsi 0 add -q --offline f3) && - HASH_BAR_DIR=$(ipfsi 0 add -Q --offline -w f2) -' - -findprovs_empty '$HASH_FOO' -findprovs_empty '$HASH_BAR' -findprovs_empty '$HASH_BAR_DIR' - -reprovide - -findprovs_empty '$HASH_FOO' -findprovs_empty '$HASH_BAR' -findprovs_expect '$HASH_BAZ' '$PEERID_0' -findprovs_expect '$HASH_BAR_DIR' '$PEERID_0' - -test_expect_success 'Stop iptb' ' - iptb stop -' - -# Test reprovider working with ticking disabled -test_expect_success 'init iptb' ' - iptb testbed create -type localipfs -force -count $NUM_NODES -init -' - -test_expect_success 'peer ids' ' - PEERID_0=$(iptb attr get 0 id) && - PEERID_1=$(iptb attr get 1 id) -' - -test_expect_success 'Disable reprovider ticking' ' - ipfsi 0 config Reprovider.Interval 0 -' - -startup_cluster ${NUM_NODES} - -test_expect_success 'add test object' ' - HASH_0=$(date +"%FT%T.%N%z" | ipfsi 0 add -q --offline) -' - -findprovs_empty '$HASH_0' -reprovide -findprovs_expect '$HASH_0' '$PEERID_0' - -test_expect_success 'resolve object $HASH_0' ' - HASH_WITH_PREFIX=$(ipfsi 1 resolve $HASH_0) -' -findprovs_expect '$HASH_WITH_PREFIX' '$PEERID_0' - -test_expect_success 'Stop iptb' ' - iptb stop -' - -test_done diff --git a/test/sharness/t0175-strategic-provider.sh b/test/sharness/t0175-strategic-provider.sh deleted file mode 100755 index fafd6e538..000000000 --- a/test/sharness/t0175-strategic-provider.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/env bash - -test_description="Test reprovider" - -. lib/test-lib.sh - -NUM_NODES=2 - -test_expect_success 'init iptb' ' - iptb testbed create -type localipfs -force -count $NUM_NODES -init -' - -test_expect_success 'peer ids' ' - PEERID_0=$(iptb attr get 0 id) && - PEERID_1=$(iptb attr get 1 id) -' - -test_expect_success 'use strategic providing' ' - iptb run -- ipfs config --json Experimental.StrategicProviding true -' - -startup_cluster ${NUM_NODES} - -test_expect_success 'add test object' ' - HASH_0=$(date +"%FT%T.%N%z" | ipfsi 0 add -q) -' - -findprovs_empty '$HASH_0' - -test_expect_success 'stop node 1' ' - iptb stop -' - -test_done From eae612e884c87c3a9cffa4370c173491ec4aec00 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Tue, 9 Apr 2024 12:08:01 +0200 Subject: [PATCH 1075/1212] chore: boxo v0.19.0 --- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- test/dependencies/go.mod | 2 +- test/dependencies/go.sum | 4 ++-- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 4824e9f1a..5bfa4b7be 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -9,7 +9,7 @@ toolchain go1.22.0 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.18.1-0.20240409062800-ec207931045d + github.com/ipfs/boxo v0.19.0 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.33.2 github.com/multiformats/go-multiaddr v0.12.3 diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 6af5e4afb..4ee081aa8 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -266,8 +266,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.18.1-0.20240409062800-ec207931045d h1:4y8xHp4ZDUgnwXK3a146K/sEYq6BSO/nA46DOLMVp5k= -github.com/ipfs/boxo v0.18.1-0.20240409062800-ec207931045d/go.mod h1:V5gJzbIMwKEXrg3IdvAxIdF7UPgU4RsXmNGS8MQ/0D4= +github.com/ipfs/boxo v0.19.0 h1:UbX9FBJQF19ACLqRZOgdEla6jR/sC4H1O+iGE0NToXA= +github.com/ipfs/boxo v0.19.0/go.mod h1:V5gJzbIMwKEXrg3IdvAxIdF7UPgU4RsXmNGS8MQ/0D4= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.3/go.mod h1:4LmD4ZUw0mhO+JSKdpWwrzATiEfM7WWgQ8H5l6P8MVk= diff --git a/go.mod b/go.mod index 994645c0c..04971b569 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,7 @@ require ( github.com/hashicorp/go-multierror v1.1.1 github.com/ipfs-shipyard/nopfs v0.0.12 github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c - github.com/ipfs/boxo v0.18.1-0.20240409062800-ec207931045d + github.com/ipfs/boxo v0.19.0 github.com/ipfs/go-block-format v0.2.0 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 diff --git a/go.sum b/go.sum index 43fe827bd..fcd51a181 100644 --- a/go.sum +++ b/go.sum @@ -329,8 +329,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.18.1-0.20240409062800-ec207931045d h1:4y8xHp4ZDUgnwXK3a146K/sEYq6BSO/nA46DOLMVp5k= -github.com/ipfs/boxo v0.18.1-0.20240409062800-ec207931045d/go.mod h1:V5gJzbIMwKEXrg3IdvAxIdF7UPgU4RsXmNGS8MQ/0D4= +github.com/ipfs/boxo v0.19.0 h1:UbX9FBJQF19ACLqRZOgdEla6jR/sC4H1O+iGE0NToXA= +github.com/ipfs/boxo v0.19.0/go.mod h1:V5gJzbIMwKEXrg3IdvAxIdF7UPgU4RsXmNGS8MQ/0D4= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 203667205..6b6ecea99 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -105,7 +105,7 @@ require ( github.com/hexops/gotextdiff v1.0.3 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/ipfs/bbloom v0.0.4 // indirect - github.com/ipfs/boxo v0.18.1-0.20240409062800-ec207931045d // indirect + github.com/ipfs/boxo v0.19.0 // indirect github.com/ipfs/go-block-format v0.2.0 // indirect github.com/ipfs/go-cid v0.4.1 // indirect github.com/ipfs/go-datastore v0.6.0 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index d7dac1ad2..18d82929d 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -362,8 +362,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.18.1-0.20240409062800-ec207931045d h1:4y8xHp4ZDUgnwXK3a146K/sEYq6BSO/nA46DOLMVp5k= -github.com/ipfs/boxo v0.18.1-0.20240409062800-ec207931045d/go.mod h1:V5gJzbIMwKEXrg3IdvAxIdF7UPgU4RsXmNGS8MQ/0D4= +github.com/ipfs/boxo v0.19.0 h1:UbX9FBJQF19ACLqRZOgdEla6jR/sC4H1O+iGE0NToXA= +github.com/ipfs/boxo v0.19.0/go.mod h1:V5gJzbIMwKEXrg3IdvAxIdF7UPgU4RsXmNGS8MQ/0D4= github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs= github.com/ipfs/go-block-format v0.2.0/go.mod h1:+jpL11nFx5A/SPpsoBn6Bzkra/zaArfSmsknbPMYgzM= github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= From a91640f8b6963adbb1c71376f88e6f97c3132af0 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Tue, 9 Apr 2024 10:24:26 +0000 Subject: [PATCH 1076/1212] chore: update version --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index a88bf87d2..30ea7eb2e 100644 --- a/version.go +++ b/version.go @@ -11,7 +11,7 @@ import ( var CurrentCommit string // CurrentVersionNumber is the current application's version literal. -const CurrentVersionNumber = "0.28.0-dev" +const CurrentVersionNumber = "0.28.0-rc1" const ApiVersion = "/kubo/" + CurrentVersionNumber + "/" //nolint From 4ae097efe70809b7d942153ed8203345ef5845da Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Tue, 9 Apr 2024 10:24:45 +0000 Subject: [PATCH 1077/1212] chore: update version --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index a88bf87d2..bd6f8183a 100644 --- a/version.go +++ b/version.go @@ -11,7 +11,7 @@ import ( var CurrentCommit string // CurrentVersionNumber is the current application's version literal. -const CurrentVersionNumber = "0.28.0-dev" +const CurrentVersionNumber = "0.29.0-dev" const ApiVersion = "/kubo/" + CurrentVersionNumber + "/" //nolint From 3b8e2eedf76089bc074d26aee9703ea596dca907 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Mon, 15 Apr 2024 06:58:12 +0000 Subject: [PATCH 1078/1212] chore: update version --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index 30ea7eb2e..29bb0c30e 100644 --- a/version.go +++ b/version.go @@ -11,7 +11,7 @@ import ( var CurrentCommit string // CurrentVersionNumber is the current application's version literal. -const CurrentVersionNumber = "0.28.0-rc1" +const CurrentVersionNumber = "0.28.0" const ApiVersion = "/kubo/" + CurrentVersionNumber + "/" //nolint From 7374880fbe7a081929001b3d7b7438d998f0f1be Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Mon, 15 Apr 2024 07:15:38 +0000 Subject: [PATCH 1079/1212] chore: update changelog for v0.28 --- docs/changelogs/v0.28.md | 85 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/docs/changelogs/v0.28.md b/docs/changelogs/v0.28.md index 1948509cf..6dfd33386 100644 --- a/docs/changelogs/v0.28.md +++ b/docs/changelogs/v0.28.md @@ -42,4 +42,89 @@ The root CIDs of pinned content are now prioritized when announcing to the Amino ### 📝 Changelog +
Full Changelog + +- github.com/ipfs/kubo: + - chore: update version + - chore: update version + - core/node: prioritize announcing pin roots, and flat strategy (#10376) ([ipfs/kubo#10376](https://github.com/ipfs/kubo/pull/10376)) + - chore: webui v4.2.1 (#10391) ([ipfs/kubo#10391](https://github.com/ipfs/kubo/pull/10391)) + - docs(config): clarify RPC vs Gateway + - chore: upgrade go-libp2p-kad-dht (#10378) ([ipfs/kubo#10378](https://github.com/ipfs/kubo/pull/10378)) + - chore(config): make Routing.AcceleratedDHTClient a Flag (#10384) ([ipfs/kubo#10384](https://github.com/ipfs/kubo/pull/10384)) + - fix: switch lowpower profile to autoclient + - core: fix some typos (#10382) ([ipfs/kubo#10382](https://github.com/ipfs/kubo/pull/10382)) + - docs: fix some typos (#10377) ([ipfs/kubo#10377](https://github.com/ipfs/kubo/pull/10377)) + - core/commands!: remove deprecated object APIs (#10375) ([ipfs/kubo#10375](https://github.com/ipfs/kubo/pull/10375)) + - docs: update default ipns lifetime + - coreapi/unixfs: don't create an additional IpfsNode for --only-hash + - chore: cleanup old workaround (#10369) ([ipfs/kubo#10369](https://github.com/ipfs/kubo/pull/10369)) + - chore: finish reframe removal + - docs: remove repetitive words (#10370) ([ipfs/kubo#10370](https://github.com/ipfs/kubo/pull/10370)) + - docs: updated links and refs to external resources (#10368) ([ipfs/kubo#10368](https://github.com/ipfs/kubo/pull/10368)) + - core/corehttp!: remove /api/v0 from gateway port + - client/rpc!: remove deprecated DHT commands + - ci: upgrade to go 1.22 (#10355) ([ipfs/kubo#10355](https://github.com/ipfs/kubo/pull/10355)) + - chore: create next changelog + - Merge Release: v0.27.0 [skip changelog] ([ipfs/kubo#10362](https://github.com/ipfs/kubo/pull/10362)) + - test: cleanup content blocking tests (#10360) ([ipfs/kubo#10360](https://github.com/ipfs/kubo/pull/10360)) + - docs: improve release issue template + - chore: update version +- github.com/ipfs/boxo (v0.18.0 -> v0.19.0): + - Release v0.19.0 ([ipfs/boxo#598](https://github.com/ipfs/boxo/pull/598)) +- github.com/libp2p/go-libp2p (v0.33.0 -> v0.33.2): + - chore: release v0.33.2 (#2755) ([libp2p/go-libp2p#2755](https://github.com/libp2p/go-libp2p/pull/2755)) + - Update quic-go to v0.42.0. Release v0.33.1 (#2741) ([libp2p/go-libp2p#2741](https://github.com/libp2p/go-libp2p/pull/2741)) +- github.com/libp2p/go-libp2p-kad-dht (v0.24.4 -> v0.25.2): + - chore: release v0.25.2 ([libp2p/go-libp2p-kad-dht#961](https://github.com/libp2p/go-libp2p-kad-dht/pull/961)) + - add ctx canceled err check ([libp2p/go-libp2p-kad-dht#960](https://github.com/libp2p/go-libp2p-kad-dht/pull/960)) + - chore: release v0.25.1 + - perf: don't buffer the output of FindProvidersAsync + - chore: use go-libp2p-routing-helpers for tracing needs + - fix: properly iterate in tracing for protocol messenger + - fix: apply addrFilters in the dht (#872) ([libp2p/go-libp2p-kad-dht#872](https://github.com/libp2p/go-libp2p-kad-dht/pull/872)) + - Add provider record addresses to peerstore ([libp2p/go-libp2p-kad-dht#870](https://github.com/libp2p/go-libp2p-kad-dht/pull/870)) + - chore: release v0.25.0 + - tracing: add protocol messages client tracing + - Enhance handleNewMessage Server Mode Logging: Convert Error Logs to Debug Level ([libp2p/go-libp2p-kad-dht#860](https://github.com/libp2p/go-libp2p-kad-dht/pull/860)) + - tracing: fix DHT keys as string attribute not being valid utf-8 ([libp2p/go-libp2p-kad-dht#859](https://github.com/libp2p/go-libp2p-kad-dht/pull/859)) + - merge: fix: issues discovered in kubo v0.21.0-rc2 (#853) ([libp2p/go-libp2p-kad-dht#853](https://github.com/libp2p/go-libp2p-kad-dht/pull/853)) + - merge: fix: issues discovered in kubo v0.21.0-rc1 (#851) ([libp2p/go-libp2p-kad-dht#851](https://github.com/libp2p/go-libp2p-kad-dht/pull/851)) + - Release v0.24.0 ([libp2p/go-libp2p-kad-dht#844](https://github.com/libp2p/go-libp2p-kad-dht/pull/844)) + - fix: don't add unresponsive DHT servers to the Routing Table (#820) ([libp2p/go-libp2p-kad-dht#820](https://github.com/libp2p/go-libp2p-kad-dht/pull/820)) + - filter local addresses (for WAN) and localhost addresses (for LAN) ([libp2p/go-libp2p-kad-dht#839](https://github.com/libp2p/go-libp2p-kad-dht/pull/839)) +- github.com/multiformats/go-multiaddr (v0.12.2 -> v0.12.3): + - chore: release v0.12.3 ([multiformats/go-multiaddr#240](https://github.com/multiformats/go-multiaddr/pull/240)) + - chore: Expand comment ForEach ([multiformats/go-multiaddr#238](https://github.com/multiformats/go-multiaddr/pull/238)) + - .Decapsulate by Components ([multiformats/go-multiaddr#239](https://github.com/multiformats/go-multiaddr/pull/239)) +- github.com/whyrusleeping/cbor-gen (v0.0.0-20240109153615-66e95c3e8a87 -> v0.1.0): + - Nullable ints (#93) ([whyrusleeping/cbor-gen#93](https://github.com/whyrusleeping/cbor-gen/pull/93)) + - Introduce Gen{} struct for configurability ([whyrusleeping/cbor-gen#94](https://github.com/whyrusleeping/cbor-gen/pull/94)) + - Transparent encoding ([whyrusleeping/cbor-gen#91](https://github.com/whyrusleeping/cbor-gen/pull/91)) + - turn max length consts into global vars ([whyrusleeping/cbor-gen#92](https://github.com/whyrusleeping/cbor-gen/pull/92)) + +
+ ### 👨‍👩‍👧‍👦 Contributors + +| Contributor | Commits | Lines ± | Files Changed | +|-------------|---------|---------|---------------| +| Henrique Dias | 19 | +867/-2806 | 96 | +| Rod Vagg | 7 | +921/-475 | 25 | +| Marcin Rataj | 8 | +358/-344 | 18 | +| Guillaume Michel - guissou | 1 | +145/-485 | 13 | +| Jorropo | 8 | +429/-136 | 22 | +| Łukasz Magiera | 4 | +284/-48 | 11 | +| whyrusleeping | 1 | +90/-90 | 2 | +| Michael Muré | 2 | +48/-73 | 9 | +| Marco Munizaga | 6 | +86/-29 | 10 | +| guillaumemichel | 3 | +93/-1 | 3 | +| Marten Seemann | 1 | +31/-4 | 4 | +| godeamon | 3 | +11/-8 | 3 | +| shuangcui | 1 | +6/-6 | 5 | +| occupyhabit | 1 | +3/-3 | 3 | +| crazehang | 1 | +2/-2 | 1 | +| Dennis Trautwein | 1 | +1/-2 | 1 | +| “GheisMohammadi” | 1 | +1/-1 | 1 | +| web3-bot | 1 | +2/-0 | 1 | +| Daniel Norman | 1 | +1/-1 | 1 | From d62cc49a0f7bad2d205314715b1c41679edacc3e Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Mon, 15 Apr 2024 11:12:29 +0200 Subject: [PATCH 1080/1212] docs: update release checklist (#10401) - change thunderdome to after the dockers and binaries are released - simplify the tag command for final releases - add link to IPFS Companion issue about E2E tests --- docs/RELEASE_CHECKLIST.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/RELEASE_CHECKLIST.md b/docs/RELEASE_CHECKLIST.md index 767709db5..727700eeb 100644 --- a/docs/RELEASE_CHECKLIST.md +++ b/docs/RELEASE_CHECKLIST.md @@ -69,12 +69,10 @@ This section covers tasks to be done during each release. - do **NOT** use `Squash and merge` nor `Rebase and merge` because we need to be able to sign the merge commit - do **NOT** delete the `release-vX.Y` branch
-- [ ] Run Thunderdome testing, see the [Thunderdome release docs](./releases_thunderdome.md) for details - - [ ] create a PR and merge the experiment config into Thunderdome - [ ] Create the release tag
using `./kuboreleaser release --version vX.Y.Z(-rcN) tag` or ... - This is a dangerous operation! Go and Docker publishing are difficult to reverse! Have the release reviewer verify all the commands marked with ⚠️! - [ ] ⚠️ ![](https://img.shields.io/badge/only-RC-blue?style=flat-square) tag the HEAD commit using `git tag -s vX.Y.Z(-RCN) -m 'Prerelease X.Y.Z(-RCN)'` - - [ ] ⚠️ ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) tag the HEAD commit of the `release` branch using `git tag -s vX.Y.Z(-RCN) -m 'Release X.Y.Z(-RCN)'` + - [ ] ⚠️ ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) tag the HEAD commit of the `release` branch using `git tag -s vX.Y.Z -m 'Release X.Y.Z'` - [ ] ⚠️ verify the tag is signed and tied to the correct commit using `git show vX.Y.Z(-RCN)` - [ ] ⚠️ push the tag to GitHub using `git push origin vX.Y.Z(-RCN)` - do **NOT** use `git push --tags` because it pushes all your local tags @@ -111,6 +109,8 @@ This section covers tasks to be done during each release. - [ ] wait for the [sync-release-assets](https://github.com/ipfs/kubo/actions/workflows/sync-release-assets.yml) workflow run to finish - [ ] verify the release assets are present in the [GitHub release](https://github.com/ipfs/kubo/releases/tag/vX.Y.Z(-RCN))
+- [ ] Run Thunderdome testing, see the [Thunderdome release docs](./releases_thunderdome.md) for details + - [ ] create a PR and merge the experiment config into Thunderdome - [ ] Promote the release
using `./kuboreleaser release --version vX.Y.Z(-rcN) promote` or ... - [ ] create an [IPFS Discourse](https://discuss.ipfs.tech) topic - [prerelease example](https://discuss.ipfs.tech/t/kubo-v0-16-0-rc1-release-candidate-is-out/15248) @@ -136,7 +136,7 @@ This section covers tasks to be done during each release. - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) post the link to the [GitHub Release](https://github.com/ipfs/kubo/releases/tag/vX.Y.Z(-RCN)) to [Reddit](https://reddit.com/r/ipfs) - [example](https://www.reddit.com/r/ipfs/comments/9x0q0k/kubo_v0160_release_is_out/)
-- [ ] Test the new version with `ipfs-companion`
using `./kuboreleaser release --version vX.Y.Z(-rcN) test-ipfs-companion` or ... +- [ ] ~~Test the new version with `ipfs-companion`~~ ([currently skipped](https://github.com/ipfs/ipfs-companion/issues/1300))
using `./kuboreleaser release --version vX.Y.Z(-rcN) test-ipfs-companion` or ... - [ ] run the [e2e](https://github.com/ipfs/ipfs-companion/actions/workflows/e2e.yml) - use `vX.Y.Z(-RCN)` as the Kubo image version - [ ] wait for the [e2e](https://github.com/ipfs/ipfs-companion/actions/workflows/e2e.yml) workflow run to finish From f0cc65bf1a40eff9b1767e25c5bda01ad4d63138 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Mon, 15 Apr 2024 11:15:51 +0200 Subject: [PATCH 1081/1212] chore: create next changelog --- CHANGELOG.md | 1 + docs/changelogs/v0.29.md | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 docs/changelogs/v0.29.md diff --git a/CHANGELOG.md b/CHANGELOG.md index cd0dc69b9..5b68d6152 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ # Kubo Changelogs +- [v0.29](docs/changelogs/v0.29.md) - [v0.28](docs/changelogs/v0.28.md) - [v0.27](docs/changelogs/v0.27.md) - [v0.26](docs/changelogs/v0.26.md) diff --git a/docs/changelogs/v0.29.md b/docs/changelogs/v0.29.md new file mode 100644 index 000000000..e51d34b5e --- /dev/null +++ b/docs/changelogs/v0.29.md @@ -0,0 +1,18 @@ +# Kubo changelog v0.29 + +- [v0.29.0](#v0290) + +## v0.29.0 + +- [Overview](#overview) +- [🔦 Highlights](#-highlights) +- [📝 Changelog](#-changelog) +- [👨‍👩‍👧‍👦 Contributors](#-contributors) + +### Overview + +### 🔦 Highlights + +### 📝 Changelog + +### 👨‍👩‍👧‍👦 Contributors From ba3f7f39bdac3f0ebc2ce2741608af4036abdb3f Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Mon, 15 Apr 2024 12:49:33 +0200 Subject: [PATCH 1082/1212] chore: update dependencies (#10404) --- docs/examples/kubo-as-a-library/go.mod | 85 ++++++----- docs/examples/kubo-as-a-library/go.sum | 183 ++++++++++++----------- go.mod | 93 ++++++------ go.sum | 192 ++++++++++++------------- test/dependencies/go.mod | 44 +++--- test/dependencies/go.sum | 103 ++++++------- 6 files changed, 357 insertions(+), 343 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 5bfa4b7be..7f43fcd56 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -9,7 +9,7 @@ toolchain go1.22.0 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.19.0 + github.com/ipfs/boxo v0.19.1-0.20240415103851-7f9506844904 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.33.2 github.com/multiformats/go-multiaddr v0.12.3 @@ -24,23 +24,24 @@ require ( github.com/benbjohnson/clock v1.3.5 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver/v4 v4.0.0 // indirect - github.com/cenkalti/backoff/v4 v4.2.1 // indirect + github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/ceramicnetwork/go-dag-jose v0.1.0 // indirect github.com/cespare/xxhash v1.1.0 // indirect - github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/containerd/cgroups v1.1.0 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect github.com/crackcomm/go-gitignore v0.0.0-20231225121904-e25f5bc08668 // indirect github.com/cskr/pubsub v1.0.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect - github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect github.com/dgraph-io/badger v1.6.2 // indirect github.com/dgraph-io/ristretto v0.0.2 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/elastic/gosigar v0.14.2 // indirect github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5 // indirect + github.com/felixge/httpsnoop v1.0.4 // indirect github.com/flynn/noise v1.1.0 // indirect github.com/francoispqt/gojay v1.2.13 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect @@ -50,13 +51,13 @@ require ( github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/godbus/dbus/v5 v5.1.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang/protobuf v1.5.3 // indirect + github.com/golang/protobuf v1.5.4 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/gopacket v1.1.19 // indirect - github.com/google/pprof v0.0.0-20240207164012-fb44976bdcd5 // indirect + github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd // indirect github.com/google/uuid v1.6.0 // indirect github.com/gorilla/websocket v1.5.1 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/golang-lru v1.0.2 // indirect @@ -67,6 +68,7 @@ require ( github.com/ipfs/bbloom v0.0.4 // indirect github.com/ipfs/go-bitfield v1.1.0 // indirect github.com/ipfs/go-block-format v0.2.0 // indirect + github.com/ipfs/go-blockservice v0.5.2 // indirect github.com/ipfs/go-cid v0.4.1 // indirect github.com/ipfs/go-cidutil v0.1.0 // indirect github.com/ipfs/go-datastore v0.6.0 // indirect @@ -75,8 +77,10 @@ require ( github.com/ipfs/go-ds-leveldb v0.5.0 // indirect github.com/ipfs/go-ds-measure v0.2.0 // indirect github.com/ipfs/go-fs-lock v0.0.7 // indirect + github.com/ipfs/go-ipfs-blockstore v1.3.1 // indirect github.com/ipfs/go-ipfs-delay v0.0.1 // indirect - github.com/ipfs/go-ipfs-ds-help v1.1.0 // indirect + github.com/ipfs/go-ipfs-ds-help v1.1.1 // indirect + github.com/ipfs/go-ipfs-exchange-interface v0.2.1 // indirect github.com/ipfs/go-ipfs-pq v0.0.3 // indirect github.com/ipfs/go-ipfs-redirects-file v0.1.1 // indirect github.com/ipfs/go-ipfs-util v0.0.3 // indirect @@ -86,16 +90,19 @@ require ( github.com/ipfs/go-ipld-legacy v0.2.1 // indirect github.com/ipfs/go-log v1.0.5 // indirect github.com/ipfs/go-log/v2 v2.5.1 // indirect + github.com/ipfs/go-merkledag v0.11.0 // indirect github.com/ipfs/go-metrics-interface v0.0.1 // indirect github.com/ipfs/go-peertaskqueue v0.8.1 // indirect github.com/ipfs/go-unixfsnode v1.9.0 // indirect + github.com/ipfs/go-verifcid v0.0.3 // indirect + github.com/ipld/go-car v0.6.2 // indirect github.com/ipld/go-car/v2 v2.13.1 // indirect github.com/ipld/go-codec-dagpb v1.6.0 // indirect github.com/ipld/go-ipld-prime v0.21.0 // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect github.com/jbenet/goprocess v0.1.4 // indirect - github.com/klauspost/compress v1.17.6 // indirect + github.com/klauspost/compress v1.17.8 // indirect github.com/klauspost/cpuid/v2 v2.2.7 // indirect github.com/koron/go-ssdp v0.0.4 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect @@ -133,7 +140,7 @@ require ( github.com/multiformats/go-multihash v0.2.3 // indirect github.com/multiformats/go-multistream v0.5.0 // indirect github.com/multiformats/go-varint v0.0.7 // indirect - github.com/onsi/ginkgo/v2 v2.15.0 // indirect + github.com/onsi/ginkgo/v2 v2.17.1 // indirect github.com/opencontainers/runtime-spec v1.2.0 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/openzipkin/zipkin-go v0.4.2 // indirect @@ -159,16 +166,16 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect github.com/polydawn/refmt v0.89.0 // indirect github.com/prometheus/client_golang v1.19.0 // indirect - github.com/prometheus/client_model v0.6.0 // indirect - github.com/prometheus/common v0.49.0 // indirect - github.com/prometheus/procfs v0.12.0 // indirect + github.com/prometheus/client_model v0.6.1 // indirect + github.com/prometheus/common v0.52.3 // indirect + github.com/prometheus/procfs v0.13.0 // indirect github.com/quic-go/qpack v0.4.0 // indirect github.com/quic-go/quic-go v0.42.0 // indirect - github.com/quic-go/webtransport-go v0.6.0 // indirect + github.com/quic-go/webtransport-go v0.7.0 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/samber/lo v1.39.0 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect - github.com/stretchr/testify v1.8.4 // indirect + github.com/stretchr/testify v1.9.0 // indirect github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect github.com/ucarion/urlpath v0.0.0-20200424170820-7ccc79b76bbb // indirect github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc // indirect @@ -178,37 +185,39 @@ require ( github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 // indirect go.opencensus.io v0.24.0 // indirect - go.opentelemetry.io/otel v1.24.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.21.0 // indirect - go.opentelemetry.io/otel/exporters/zipkin v1.21.0 // indirect - go.opentelemetry.io/otel/metric v1.24.0 // indirect - go.opentelemetry.io/otel/sdk v1.21.0 // indirect - go.opentelemetry.io/otel/trace v1.24.0 // indirect - go.opentelemetry.io/proto/otlp v1.0.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.50.0 // indirect + go.opentelemetry.io/otel v1.25.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.25.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.25.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.25.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.25.0 // indirect + go.opentelemetry.io/otel/exporters/zipkin v1.25.0 // indirect + go.opentelemetry.io/otel/metric v1.25.0 // indirect + go.opentelemetry.io/otel/sdk v1.25.0 // indirect + go.opentelemetry.io/otel/trace v1.25.0 // indirect + go.opentelemetry.io/proto/otlp v1.2.0 // indirect + go.uber.org/atomic v1.11.0 // indirect go.uber.org/dig v1.17.1 // indirect go.uber.org/fx v1.20.1 // indirect go.uber.org/mock v0.4.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect go4.org v0.0.0-20230225012048-214862532bf5 // indirect - golang.org/x/crypto v0.20.0 // indirect - golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 // indirect - golang.org/x/mod v0.15.0 // indirect - golang.org/x/net v0.21.0 // indirect - golang.org/x/sync v0.6.0 // indirect - golang.org/x/sys v0.17.0 // indirect + golang.org/x/crypto v0.22.0 // indirect + golang.org/x/exp v0.0.0-20240409090435-93d18d7e34b8 // indirect + golang.org/x/mod v0.17.0 // indirect + golang.org/x/net v0.24.0 // indirect + golang.org/x/sync v0.7.0 // indirect + golang.org/x/sys v0.19.0 // indirect golang.org/x/text v0.14.0 // indirect - golang.org/x/tools v0.18.0 // indirect + golang.org/x/tools v0.20.0 // indirect golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect - gonum.org/v1/gonum v0.14.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240108191215-35c7eff3a6b1 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240108191215-35c7eff3a6b1 // indirect - google.golang.org/grpc v1.60.1 // indirect - google.golang.org/protobuf v1.32.0 // indirect + gonum.org/v1/gonum v0.15.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240412170617-26222e5d3d56 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240412170617-26222e5d3d56 // indirect + google.golang.org/grpc v1.63.2 // indirect + google.golang.org/protobuf v1.33.0 // indirect gopkg.in/square/go-jose.v2 v2.5.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - lukechampine.com/blake3 v1.2.1 // indirect + lukechampine.com/blake3 v1.2.2 // indirect ) diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 4ee081aa8..f3644a0f5 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -60,15 +60,15 @@ github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= -github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= -github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= +github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/ceramicnetwork/go-dag-jose v0.1.0 h1:yJ/HVlfKpnD3LdYP03AHyTvbm3BpPiz2oZiOeReJRdU= github.com/ceramicnetwork/go-dag-jose v0.1.0/go.mod h1:qYA1nYt0X8u4XoMAVoOV3upUVKtrxy/I670Dg5F0wjI= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= -github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= -github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= 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= @@ -102,8 +102,8 @@ github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c h1:pFUpOrbxDR github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c/go.mod h1:6UhI8N9EjYm1c2odKpFpAYeR8dsBeM7PtzQhRgxRr9U= github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y= github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= github.com/dgraph-io/badger v1.6.2 h1:mNw0qs90GVgGGWylh0umH5iag1j6n/PeJtNvL6KY/x8= github.com/dgraph-io/badger v1.6.2/go.mod h1:JW2yswe3V058sS0kZ2h/AXeDSqFjxnZcRrVH//y2UQE= @@ -126,6 +126,8 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5 h1:BBso6MBKW8ncyZLv37o+KNyy0HrrHgfnOaGQC2qvN+A= github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5/go.mod h1:JpoxHjuQauoxiFMl1ie8Xc/7TfLuMZ5eOCONd1sUBHg= +github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= +github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/flynn/noise v1.1.0 h1:KjPQoQCEFdZDiP03phOvGi11+SVVhBG2wOWAorLsstg= github.com/flynn/noise v1.1.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag= @@ -191,8 +193,8 @@ github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= @@ -218,8 +220,8 @@ github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXi github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20240207164012-fb44976bdcd5 h1:E/LAvt58di64hlYjx7AsNS6C/ysHWYo+2qPCZKTQhRo= -github.com/google/pprof v0.0.0-20240207164012-fb44976bdcd5/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= +github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd h1:gbpYu9NMq8jhDVbvlGkMFWCjLFlqqEZjEmObmhUy6Vo= +github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -239,8 +241,8 @@ github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/ github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0 h1:Wqo399gCIufwto+VfwCSvsnfGpF/w5E9CNxSwbpD6No= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0/go.mod h1:qmOFXW2epJhM0qSnUUYpldc7gVz2KMQwJ/QYCDIa7XU= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1 h1:/c3QmbOGMGTOumP2iT/rCwB7b0QDGLKzqOmktBjT+Is= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1/go.mod h1:5SN9VR2LTsRFsrEC6FHgRbTWrTHu6tqPeKxEQv15giM= github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -266,18 +268,19 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.19.0 h1:UbX9FBJQF19ACLqRZOgdEla6jR/sC4H1O+iGE0NToXA= -github.com/ipfs/boxo v0.19.0/go.mod h1:V5gJzbIMwKEXrg3IdvAxIdF7UPgU4RsXmNGS8MQ/0D4= +github.com/ipfs/boxo v0.19.1-0.20240415103851-7f9506844904 h1:HqjqN6oADXh1UNw8xKnBP50B3ZQDC/RStiBFPp6W+9Y= +github.com/ipfs/boxo v0.19.1-0.20240415103851-7f9506844904/go.mod h1:hA9Ou/YnfMZOG2nQhngsbBiYt6fiJ1EhWSmccZfV+M0= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= +github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= +github.com/ipfs/go-bitswap v0.11.0/go.mod h1:05aE8H3XOU+LXpTedeAS0OZpcO1WFsj5niYQH9a1Tmk= github.com/ipfs/go-block-format v0.0.3/go.mod h1:4LmD4ZUw0mhO+JSKdpWwrzATiEfM7WWgQ8H5l6P8MVk= github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs= github.com/ipfs/go-block-format v0.2.0/go.mod h1:+jpL11nFx5A/SPpsoBn6Bzkra/zaArfSmsknbPMYgzM= -github.com/ipfs/go-blockservice v0.5.0 h1:B2mwhhhVQl2ntW2EIpaWPwSCxSuqr5fFA93Ms4bYLEY= -github.com/ipfs/go-blockservice v0.5.0/go.mod h1:W6brZ5k20AehbmERplmERn8o2Ni3ZZubvAxaIUeaT6w= +github.com/ipfs/go-blockservice v0.5.2 h1:in9Bc+QcXwd1apOVM7Un9t8tixPKdaHQFdLSUM1Xgk8= +github.com/ipfs/go-blockservice v0.5.2/go.mod h1:VpMblFEqG67A/H2sHKAemeH9vlURVavlysbdUI632yk= github.com/ipfs/go-cid v0.0.3/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.4/go.mod h1:4LLaPOQwmk5z9LBgQnpkivrx8BJjUyGwTXCd5Xfj6+M= -github.com/ipfs/go-cid v0.0.5/go.mod h1:plgt+Y5MnOey4vO4UlUazGqdbEXuFYitED67FexhXog= github.com/ipfs/go-cid v0.0.7/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I= github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= github.com/ipfs/go-cid v0.4.1/go.mod h1:uQHwDeX4c6CtyrFwdqyhpNcxVewur1M7l7fNU7LKwZk= @@ -302,8 +305,8 @@ github.com/ipfs/go-ds-measure v0.2.0 h1:sG4goQe0KDTccHMyT45CY1XyUbxe5VwTKpg2LjAp github.com/ipfs/go-ds-measure v0.2.0/go.mod h1:SEUD/rE2PwRa4IQEC5FuNAmjJCyYObZr9UvVh8V3JxE= github.com/ipfs/go-fs-lock v0.0.7 h1:6BR3dajORFrFTkb5EpCUFIAypsoxpGpDSVUdFwzgL9U= github.com/ipfs/go-fs-lock v0.0.7/go.mod h1:Js8ka+FNYmgQRLrRXzU3CB/+Csr1BwrRilEcvYrHhhc= -github.com/ipfs/go-ipfs-blockstore v1.3.0 h1:m2EXaWgwTzAfsmt5UdJ7Is6l4gJcaM/A12XwJyvYvMM= -github.com/ipfs/go-ipfs-blockstore v1.3.0/go.mod h1:KgtZyc9fq+P2xJUiCAzbRdhhqJHvsw8u2Dlqy2MyRTE= +github.com/ipfs/go-ipfs-blockstore v1.3.1 h1:cEI9ci7V0sRNivqaOr0elDsamxXFxJMMMy7PTTDQNsQ= +github.com/ipfs/go-ipfs-blockstore v1.3.1/go.mod h1:KgtZyc9fq+P2xJUiCAzbRdhhqJHvsw8u2Dlqy2MyRTE= github.com/ipfs/go-ipfs-blocksutil v0.0.1 h1:Eh/H4pc1hsvhzsQoMEP3Bke/aW5P5rVM1IWFJMcGIPQ= github.com/ipfs/go-ipfs-blocksutil v0.0.1/go.mod h1:Yq4M86uIOmxmGPUHv/uI7uKqZNtLb449gwKqXjIsnRk= github.com/ipfs/go-ipfs-chunker v0.0.5 h1:ojCf7HV/m+uS2vhUGWcogIIxiO5ubl5O57Q7NapWLY8= @@ -311,16 +314,18 @@ github.com/ipfs/go-ipfs-chunker v0.0.5/go.mod h1:jhgdF8vxRHycr00k13FM8Y0E+6BoalY github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= github.com/ipfs/go-ipfs-delay v0.0.1 h1:r/UXYyRcddO6thwOnhiznIAiSvxMECGgtv35Xs1IeRQ= github.com/ipfs/go-ipfs-delay v0.0.1/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= -github.com/ipfs/go-ipfs-ds-help v1.1.0 h1:yLE2w9RAsl31LtfMt91tRZcrx+e61O5mDxFRR994w4Q= -github.com/ipfs/go-ipfs-ds-help v1.1.0/go.mod h1:YR5+6EaebOhfcqVCyqemItCLthrpVNot+rsOU/5IatU= -github.com/ipfs/go-ipfs-exchange-interface v0.2.0 h1:8lMSJmKogZYNo2jjhUs0izT+dck05pqUw4mWNW9Pw6Y= -github.com/ipfs/go-ipfs-exchange-interface v0.2.0/go.mod h1:z6+RhJuDQbqKguVyslSOuVDhqF9JtTrO3eptSAiW2/Y= +github.com/ipfs/go-ipfs-ds-help v1.1.1 h1:B5UJOH52IbcfS56+Ul+sv8jnIV10lbjLF5eOO0C66Nw= +github.com/ipfs/go-ipfs-ds-help v1.1.1/go.mod h1:75vrVCkSdSFidJscs8n4W+77AtTpCIAdDGAwjitJMIo= +github.com/ipfs/go-ipfs-exchange-interface v0.2.1 h1:jMzo2VhLKSHbVe+mHNzYgs95n0+t0Q69GQ5WhRDZV/s= +github.com/ipfs/go-ipfs-exchange-interface v0.2.1/go.mod h1:MUsYn6rKbG6CTtsDp+lKJPmVt3ZrCViNyH3rfPGsZ2E= github.com/ipfs/go-ipfs-exchange-offline v0.3.0 h1:c/Dg8GDPzixGd0MC8Jh6mjOwU57uYokgWRFidfvEkuA= github.com/ipfs/go-ipfs-exchange-offline v0.3.0/go.mod h1:MOdJ9DChbb5u37M1IcbrRB02e++Z7521fMxqCNRrz9s= github.com/ipfs/go-ipfs-pq v0.0.3 h1:YpoHVJB+jzK15mr/xsWC574tyDLkezVrDNeaalQBsTE= github.com/ipfs/go-ipfs-pq v0.0.3/go.mod h1:btNw5hsHBpRcSSgZtiNm/SLj5gYIZ18AKtv3kERkRb4= github.com/ipfs/go-ipfs-redirects-file v0.1.1 h1:Io++k0Vf/wK+tfnhEh63Yte1oQK5VGT2hIEYpD0Rzx8= github.com/ipfs/go-ipfs-redirects-file v0.1.1/go.mod h1:tAwRjCV0RjLTjH8DR/AU7VYvfQECg+lpUy2Mdzv7gyk= +github.com/ipfs/go-ipfs-routing v0.3.0 h1:9W/W3N+g+y4ZDeffSgqhgo7BsBSJwPMcyssET9OWevc= +github.com/ipfs/go-ipfs-routing v0.3.0/go.mod h1:dKqtTFIql7e1zYsEuWLyuOU+E0WJWW8JjbTPLParDWo= github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyBCNzQxlJBc= github.com/ipfs/go-ipfs-util v0.0.2/go.mod h1:CbPtkWJzjLdEcezDns2XYaehFVNXG9zrdrtMecczcsQ= github.com/ipfs/go-ipfs-util v0.0.3 h1:2RFdGez6bu2ZlZdI+rWfIdbQb1KudQp3VGwPtdNCmE0= @@ -353,8 +358,10 @@ github.com/ipfs/go-unixfs v0.4.5 h1:wj8JhxvV1G6CD7swACwSKYa+NgtdWC1RUit+gFnymDU= github.com/ipfs/go-unixfs v0.4.5/go.mod h1:BIznJNvt/gEx/ooRMI4Us9K8+qeGO7vx1ohnbk8gjFg= github.com/ipfs/go-unixfsnode v1.9.0 h1:ubEhQhr22sPAKO2DNsyVBW7YB/zA8Zkif25aBvz8rc8= github.com/ipfs/go-unixfsnode v1.9.0/go.mod h1:HxRu9HYHOjK6HUqFBAi++7DVoWAHn0o4v/nZ/VA+0g8= -github.com/ipfs/go-verifcid v0.0.2 h1:XPnUv0XmdH+ZIhLGKg6U2vaPaRDXb9urMyNVCE7uvTs= -github.com/ipfs/go-verifcid v0.0.2/go.mod h1:40cD9x1y4OWnFXbLNJYRe7MpNvWlMn3LZAG5Wb4xnPU= +github.com/ipfs/go-verifcid v0.0.3 h1:gmRKccqhWDocCRkC+a59g5QW7uJw5bpX9HWBevXa0zs= +github.com/ipfs/go-verifcid v0.0.3/go.mod h1:gcCtGniVzelKrbk9ooUSX/pM3xlH73fZZJDzQJRvOUw= +github.com/ipld/go-car v0.6.2 h1:Hlnl3Awgnq8icK+ze3iRghk805lu8YNq3wlREDTF2qc= +github.com/ipld/go-car v0.6.2/go.mod h1:oEGXdwp6bmxJCZ+rARSkDliTeYnVzv3++eXajZ+Bmr8= github.com/ipld/go-car/v2 v2.13.1 h1:KnlrKvEPEzr5IZHKTXLAEub+tPrzeAFQVRlSQvuxBO4= github.com/ipld/go-car/v2 v2.13.1/go.mod h1:QkdjjFNGit2GIkpQ953KBwowuoukoM75nP/JI1iDJdo= github.com/ipld/go-codec-dagpb v1.6.0 h1:9nYazfyu9B1p3NAgfVdpRco3Fs2nFC72DqVsMj6rOcc= @@ -390,8 +397,8 @@ github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQL 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.17.6 h1:60eq2E/jlfwQXtvZEeBUYADs+BwKBWURIY+Gj2eRGjI= -github.com/klauspost/compress v1.17.6/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= +github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU= +github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= @@ -557,8 +564,8 @@ github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9k github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.15.0 h1:79HwNRBAZHOEwrczrgSOPy+eFTTlIGELKy5as+ClttY= -github.com/onsi/ginkgo/v2 v2.15.0/go.mod h1:HlxMHtYF57y6Dpf+mc5529KKmSq9h2FpCF+/ZkwUxKM= +github.com/onsi/ginkgo/v2 v2.17.1 h1:V++EzdbhI4ZV4ev0UTIj0PzhzOcReJFyJaLjtSF55M8= +github.com/onsi/ginkgo/v2 v2.17.1/go.mod h1:llBI3WDLL9Z6taip6f33H76YcWtJv+7R3HigUjbIBOs= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= @@ -640,20 +647,20 @@ github.com/prometheus/client_golang v1.19.0 h1:ygXvpU1AoN1MhdzckN+PyD9QJOSD4x7km github.com/prometheus/client_golang v1.19.0/go.mod h1:ZRM9uEAypZakd+q/x7+gmsvXdURP+DABIEIjnmDdp+k= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.6.0 h1:k1v3CzpSRUTrKMppY35TLwPvxHqBu0bYgxZzqGIgaos= -github.com/prometheus/client_model v0.6.0/go.mod h1:NTQHnmxFpouOD0DpvP4XujX3CdOAGQPoaGhyTchlyt8= +github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= +github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.49.0 h1:ToNTdK4zSnPVJmh698mGFkDor9wBI/iGaJy5dbH1EgI= -github.com/prometheus/common v0.49.0/go.mod h1:Kxm+EULxRbUkjGU6WFsQqo3ORzB4tyKvlWFOE9mB2sE= +github.com/prometheus/common v0.52.3 h1:5f8uj6ZwHSscOGNdIQg6OiZv/ybiK2CO2q2drVZAQSA= +github.com/prometheus/common v0.52.3/go.mod h1:BrxBKv3FWBIGXw89Mg1AeBq7FSyRzXWI3l3e7W3RN5U= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= -github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= +github.com/prometheus/procfs v0.13.0 h1:GqzLlQyfsPbaEHaQkO7tbDlriv/4o5Hudv6OXHGKX7o= +github.com/prometheus/procfs v0.13.0/go.mod h1:cd4PFCR54QLnGKPaKGA6l+cfuNXtht43ZKY6tow0Y1g= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= github.com/quic-go/quic-go v0.42.0 h1:uSfdap0eveIl8KXnipv9K7nlwZ5IqLlYOpJ58u5utpM= github.com/quic-go/quic-go v0.42.0/go.mod h1:132kz4kL3F9vxhW3CtQJLDVwcFe5wdWeJXXijhsO57M= -github.com/quic-go/webtransport-go v0.6.0 h1:CvNsKqc4W2HljHJnoT+rMmbRJybShZ0YPFDD3NxaZLY= -github.com/quic-go/webtransport-go v0.6.0/go.mod h1:9KjU4AEBqEQidGHNDkZrb8CAa1abRaosM2yGOyiikEc= +github.com/quic-go/webtransport-go v0.7.0 h1:dv9wDD9Rd0cuSRLRHPrOX9fSY8QBpdXW4Ls85WXMKqE= +github.com/quic-go/webtransport-go v0.7.0/go.mod h1:MX3nFXrcXkdzblIfOXFZ5lVCZhn+VbMMspOweP1HoXE= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= @@ -715,8 +722,9 @@ github.com/src-d/envconfig v1.0.0/go.mod h1:Q9YQZ7BKITldTBnoxsE5gOeB5y66RyPXeue/ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -727,8 +735,9 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= @@ -779,26 +788,28 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo= -go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 h1:cl5P5/GIfFh4t6xyruOgJP5QiA1pw4fYYdv6nc6CBWw= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0/go.mod h1:zgBdWWAu7oEEMC06MMKc5NLbA/1YDXV1sMpSqEeLQLg= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0 h1:tIqheXEFWAZ7O8A7m+J0aPTmpJN3YQ7qetUAdkkkKpk= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0/go.mod h1:nUeKExfxAQVbiVFn32YXpXZZHZ61Cc3s3Rn1pDBGAb0= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0 h1:digkEZCJWobwBqMwC0cwCq8/wkkRy/OowZg5OArWZrM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0/go.mod h1:/OpE/y70qVkndM0TrxT4KBoN3RsFZP0QaofcfYrj76I= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.21.0 h1:VhlEQAPp9R1ktYfrPk5SOryw1e9LDDTZCbIPFrho0ec= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.21.0/go.mod h1:kB3ufRbfU+CQ4MlUcqtW8Z7YEOBeK2DJ6CmR5rYYF3E= -go.opentelemetry.io/otel/exporters/zipkin v1.21.0 h1:D+Gv6lSfrFBWmQYyxKjDd0Zuld9SRXpIrEsKZvE4DO4= -go.opentelemetry.io/otel/exporters/zipkin v1.21.0/go.mod h1:83oMKR6DzmHisFOW3I+yIMGZUTjxiWaiBI8M8+TU5zE= -go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI= -go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco= -go.opentelemetry.io/otel/sdk v1.21.0 h1:FTt8qirL1EysG6sTQRZ5TokkU8d0ugCj8htOgThZXQ8= -go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E= -go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI= -go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU= -go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I= -go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.50.0 h1:cEPbyTSEHlQR89XVlyo78gqluF8Y3oMeBkXGWzQsfXY= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.50.0/go.mod h1:DKdbWcT4GH1D0Y3Sqt/PFXt2naRKDWtU+eE6oLdFNA8= +go.opentelemetry.io/otel v1.25.0 h1:gldB5FfhRl7OJQbUHt/8s0a7cE8fbsPAtdpRaApKy4k= +go.opentelemetry.io/otel v1.25.0/go.mod h1:Wa2ds5NOXEMkCmUou1WA7ZBfLTHWIsp034OVD7AO+Vg= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.25.0 h1:dT33yIHtmsqpixFsSQPwNeY5drM9wTcoL8h0FWF4oGM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.25.0/go.mod h1:h95q0LBGh7hlAC08X2DhSeyIG02YQ0UyioTCVAqRPmc= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.25.0 h1:vOL89uRfOCCNIjkisd0r7SEdJF3ZJFyCNY34fdZs8eU= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.25.0/go.mod h1:8GlBGcDk8KKi7n+2S4BT/CPZQYH3erLu0/k64r1MYgo= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.25.0 h1:Mbi5PKN7u322woPa85d7ebZ+SOvEoPvoiBu+ryHWgfA= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.25.0/go.mod h1:e7ciERRhZaOZXVjx5MiL8TK5+Xv7G5Gv5PA2ZDEJdL8= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.25.0 h1:0vZZdECYzhTt9MKQZ5qQ0V+J3MFu4MQaQ3COfugF+FQ= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.25.0/go.mod h1:e7iXx3HjaSSBXfy9ykVUlupS2Vp7LBIBuT21ousM2Hk= +go.opentelemetry.io/otel/exporters/zipkin v1.25.0 h1:iLzdsOsstvim/54ymA2BhEN4+1NbsvwGvOhSkQy2TaY= +go.opentelemetry.io/otel/exporters/zipkin v1.25.0/go.mod h1:3QXxNo6ace1QZX6pSHEzGKKESVdjQxXR03FcIH7dNGs= +go.opentelemetry.io/otel/metric v1.25.0 h1:LUKbS7ArpFL/I2jJHdJcqMGxkRdxpPHE0VU/D4NuEwA= +go.opentelemetry.io/otel/metric v1.25.0/go.mod h1:rkDLUSd2lC5lq2dFNrX9LGAbINP5B7WBkC78RXCpH5s= +go.opentelemetry.io/otel/sdk v1.25.0 h1:PDryEJPC8YJZQSyLY5eqLeafHtG+X7FWnf3aXMtxbqo= +go.opentelemetry.io/otel/sdk v1.25.0/go.mod h1:oFgzCM2zdsxKzz6zwpTZYLLQsFwc+K0daArPdIhuxkw= +go.opentelemetry.io/otel/trace v1.25.0 h1:tqukZGLwQYRIFtSQM2u2+yfMVTgGVeqRLPUYx1Dq6RM= +go.opentelemetry.io/otel/trace v1.25.0/go.mod h1:hCCs70XM/ljO+BeQkyFnbK28SBIJ/Emuha+ccrCRT7I= +go.opentelemetry.io/proto/otlp v1.2.0 h1:pVeZGk7nXDC9O2hncA6nHldxEjm6LByfA2aN8IOkz94= +go.opentelemetry.io/proto/otlp v1.2.0/go.mod h1:gGpR8txAl5M03pDhMC79G6SdqNV26naRm/KDsgaHD8A= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= @@ -851,8 +862,8 @@ golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45 golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= -golang.org/x/crypto v0.20.0 h1:jmAMJJZXr5KiCw05dfYK9QnqaqKLYXijU23lsEdcQqg= -golang.org/x/crypto v0.20.0/go.mod h1:Xwo95rrVNIoSMx9wa1JroENMToLWn3RNVrTBpLHgZPQ= +golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= +golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -861,8 +872,8 @@ golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 h1:LfspQV/FYTatPTr/3HzIcmiUFH7PGP+OQ6mgDYo3yuQ= -golang.org/x/exp v0.0.0-20240222234643-814bf88cf225/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc= +golang.org/x/exp v0.0.0-20240409090435-93d18d7e34b8 h1:ESSUROHIBHg7USnszlcdmjBEwdMj9VUvU+OPk4yl2mc= +golang.org/x/exp v0.0.0-20240409090435-93d18d7e34b8/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -886,8 +897,8 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8= -golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= +golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -927,8 +938,8 @@ golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ= golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= -golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= -golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= +golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -947,8 +958,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= -golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/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= @@ -1006,8 +1017,8 @@ golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= -golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= +golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -1078,16 +1089,16 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.18.0 h1:k8NLag8AGHnn+PHbl7g43CtqZAwG60vZkLqgyZgIHgQ= -golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg= +golang.org/x/tools v0.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY= +golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU= golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= -gonum.org/v1/gonum v0.14.0 h1:2NiG67LD1tEH0D7kM+ps2V+fXmsAnpUeec7n8tcr4S0= -gonum.org/v1/gonum v0.14.0/go.mod h1:AoWeoz0becf9QMWtE8iWXNXc27fK4fNeHNf/oMejGfU= +gonum.org/v1/gonum v0.15.0 h1:2lYxjRbTYyxkJxlhC+LvJIx3SsANPdRybu1tGj9/OrQ= +gonum.org/v1/gonum v0.15.0/go.mod h1:xzZVBJBtS+Mz4q0Yl2LJTk+OxOg4jiXZ7qBoM0uISGo= google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y= @@ -1124,12 +1135,10 @@ google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvx google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20240102182953-50ed04b92917 h1:nz5NESFLZbJGPFxDT/HCn+V1mZ8JGNoY4nUpmW/Y2eg= -google.golang.org/genproto v0.0.0-20240102182953-50ed04b92917/go.mod h1:pZqR+glSb11aJ+JQcczCvgf47+duRuzNSKqE8YAQnV0= -google.golang.org/genproto/googleapis/api v0.0.0-20240108191215-35c7eff3a6b1 h1:OPXtXn7fNMaXwO3JvOmF1QyTc00jsSFFz1vXXBOdCDo= -google.golang.org/genproto/googleapis/api v0.0.0-20240108191215-35c7eff3a6b1/go.mod h1:B5xPO//w8qmBDjGReYLpR6UJPnkldGkCSMoH/2vxJeg= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240108191215-35c7eff3a6b1 h1:gphdwh0npgs8elJ4T6J+DQJHPVF7RsuJHCfwztUb4J4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240108191215-35c7eff3a6b1/go.mod h1:daQN87bsDqDoe316QbbvX60nMoJQa4r6Ds0ZuoAe5yA= +google.golang.org/genproto/googleapis/api v0.0.0-20240412170617-26222e5d3d56 h1:KuFzeG+qPmpT8KpJXcrKAyeHhn64dgEICWlccP9qp0U= +google.golang.org/genproto/googleapis/api v0.0.0-20240412170617-26222e5d3d56/go.mod h1:wTHjrkbcS8AoQbb/0v9bFIPItZQPAsyVfgG9YPUhjAM= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240412170617-26222e5d3d56 h1:zviK8GX4VlMstrK3JkexM5UHjH1VOkRebH9y3jhSBGk= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240412170617-26222e5d3d56/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= @@ -1142,8 +1151,8 @@ google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8 google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.60.1 h1:26+wFr+cNqSGFcOXcabYC0lUVJVRa2Sb2ortSK7VrEU= -google.golang.org/grpc v1.60.1/go.mod h1:OlCHIeLYqSSsLi6i49B5QGdzaMZK9+M7LXN2FKz4eGM= +google.golang.org/grpc v1.63.2 h1:MUeiw1B2maTVZthpU5xvASfTh3LDbxHd6IJ6QQVU+xM= +google.golang.org/grpc v1.63.2/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -1155,8 +1164,8 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= -google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= +google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -1190,8 +1199,8 @@ honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= lukechampine.com/blake3 v1.1.6/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= -lukechampine.com/blake3 v1.2.1 h1:YuqqRuaqsGV71BV/nm9xlI0MKUv4QC54jQnBChWbGnI= -lukechampine.com/blake3 v1.2.1/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= +lukechampine.com/blake3 v1.2.2 h1:wEAbSg0IVU4ih44CVlpMqMZMpzr5hf/6aqodLlevd/w= +lukechampine.com/blake3 v1.2.2/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= pgregory.net/rapid v0.4.7 h1:MTNRktPuv5FNqOO151TM9mDTa+XHcX6ypYeISDVD14g= pgregory.net/rapid v0.4.7/go.mod h1:UYpPVyjFHzYBGHIxLFoupi8vwk6rXNzRY9OMvVxFIOU= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= diff --git a/go.mod b/go.mod index 04971b569..26fe667dc 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ require ( contrib.go.opencensus.io/exporter/prometheus v0.4.2 github.com/benbjohnson/clock v1.3.5 github.com/blang/semver/v4 v4.0.0 - github.com/cenkalti/backoff/v4 v4.2.1 + github.com/cenkalti/backoff/v4 v4.3.0 github.com/ceramicnetwork/go-dag-jose v0.1.0 github.com/cheggaaa/pb v1.0.29 github.com/coreos/go-systemd/v22 v22.5.0 @@ -17,7 +17,7 @@ require ( github.com/hashicorp/go-multierror v1.1.1 github.com/ipfs-shipyard/nopfs v0.0.12 github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c - github.com/ipfs/boxo v0.19.0 + github.com/ipfs/boxo v0.19.1-0.20240415103851-7f9506844904 github.com/ipfs/go-block-format v0.2.0 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 @@ -38,7 +38,7 @@ require ( github.com/ipfs/go-metrics-interface v0.0.1 github.com/ipfs/go-metrics-prometheus v0.0.2 github.com/ipfs/go-unixfsnode v1.9.0 - github.com/ipld/go-car v0.5.0 + github.com/ipld/go-car v0.6.2 github.com/ipld/go-car/v2 v2.13.1 github.com/ipld/go-codec-dagpb v1.6.0 github.com/ipld/go-ipld-prime v0.21.0 @@ -67,28 +67,28 @@ require ( github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.19.0 - github.com/stretchr/testify v1.8.4 + github.com/stretchr/testify v1.9.0 github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 github.com/tidwall/gjson v1.14.4 github.com/tidwall/sjson v1.2.5 github.com/whyrusleeping/go-sysinfo v0.0.0-20190219211824-4a357d4b90b1 github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 go.opencensus.io v0.24.0 - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.50.0 go.opentelemetry.io/contrib/propagators/autoprop v0.46.1 - go.opentelemetry.io/otel v1.24.0 - go.opentelemetry.io/otel/sdk v1.21.0 - go.opentelemetry.io/otel/trace v1.24.0 + go.opentelemetry.io/otel v1.25.0 + go.opentelemetry.io/otel/sdk v1.25.0 + go.opentelemetry.io/otel/trace v1.25.0 go.uber.org/dig v1.17.1 go.uber.org/fx v1.20.1 go.uber.org/multierr v1.11.0 go.uber.org/zap v1.27.0 - golang.org/x/crypto v0.20.0 - golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 - golang.org/x/mod v0.15.0 - golang.org/x/sync v0.6.0 - golang.org/x/sys v0.17.0 - google.golang.org/protobuf v1.32.0 + golang.org/x/crypto v0.22.0 + golang.org/x/exp v0.0.0-20240409090435-93d18d7e34b8 + golang.org/x/mod v0.17.0 + golang.org/x/sync v0.7.0 + golang.org/x/sys v0.19.0 + google.golang.org/protobuf v1.33.0 ) require ( @@ -98,13 +98,13 @@ require ( github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash v1.1.0 // indirect - github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/containerd/cgroups v1.1.0 // indirect github.com/crackcomm/go-gitignore v0.0.0-20231225121904-e25f5bc08668 // indirect github.com/cskr/pubsub v1.0.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect - github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect github.com/dgraph-io/badger v1.6.2 // indirect github.com/dgraph-io/ristretto v0.0.2 // indirect github.com/docker/go-units v0.5.0 // indirect @@ -121,33 +121,33 @@ require ( github.com/godbus/dbus/v5 v5.1.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/golang/protobuf v1.5.3 // indirect + github.com/golang/protobuf v1.5.4 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/gopacket v1.1.19 // indirect - github.com/google/pprof v0.0.0-20240207164012-fb44976bdcd5 // indirect + github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd // indirect github.com/gorilla/mux v1.8.1 // indirect github.com/gorilla/websocket v1.5.1 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/golang-lru v1.0.2 // indirect github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/huin/goupnp v1.3.0 // indirect github.com/ipfs/bbloom v0.0.4 // indirect github.com/ipfs/go-bitfield v1.1.0 // indirect - github.com/ipfs/go-blockservice v0.5.0 // indirect - github.com/ipfs/go-ipfs-blockstore v1.3.0 // indirect + github.com/ipfs/go-blockservice v0.5.2 // indirect + github.com/ipfs/go-ipfs-blockstore v1.3.1 // indirect github.com/ipfs/go-ipfs-chunker v0.0.5 // indirect github.com/ipfs/go-ipfs-delay v0.0.1 // indirect - github.com/ipfs/go-ipfs-ds-help v1.1.0 // indirect - github.com/ipfs/go-ipfs-exchange-interface v0.2.0 // indirect + github.com/ipfs/go-ipfs-ds-help v1.1.1 // indirect + github.com/ipfs/go-ipfs-exchange-interface v0.2.1 // indirect github.com/ipfs/go-ipfs-pq v0.0.3 // indirect github.com/ipfs/go-ipfs-redirects-file v0.1.1 // indirect github.com/ipfs/go-ipfs-util v0.0.3 // indirect github.com/ipfs/go-merkledag v0.11.0 // indirect github.com/ipfs/go-peertaskqueue v0.8.1 // indirect - github.com/ipfs/go-verifcid v0.0.2 // indirect + github.com/ipfs/go-verifcid v0.0.3 // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect - github.com/klauspost/compress v1.17.6 // indirect + github.com/klauspost/compress v1.17.8 // indirect github.com/klauspost/cpuid/v2 v2.2.7 // indirect github.com/koron/go-ssdp v0.0.4 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect @@ -177,7 +177,7 @@ require ( github.com/multiformats/go-multiaddr-fmt v0.1.0 // indirect github.com/multiformats/go-multistream v0.5.0 // indirect github.com/multiformats/go-varint v0.0.7 // indirect - github.com/onsi/ginkgo/v2 v2.15.0 // indirect + github.com/onsi/ginkgo/v2 v2.17.1 // indirect github.com/opencontainers/runtime-spec v1.2.0 // indirect github.com/openzipkin/zipkin-go v0.4.2 // indirect github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 // indirect @@ -199,13 +199,13 @@ require ( github.com/pion/webrtc/v3 v3.2.23 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/polydawn/refmt v0.89.0 // indirect - github.com/prometheus/client_model v0.6.0 // indirect - github.com/prometheus/common v0.49.0 // indirect - github.com/prometheus/procfs v0.12.0 // indirect + github.com/prometheus/client_model v0.6.1 // indirect + github.com/prometheus/common v0.52.3 // indirect + github.com/prometheus/procfs v0.13.0 // indirect github.com/prometheus/statsd_exporter v0.22.7 // indirect github.com/quic-go/qpack v0.4.0 // indirect github.com/quic-go/quic-go v0.42.0 // indirect - github.com/quic-go/webtransport-go v0.6.0 // indirect + github.com/quic-go/webtransport-go v0.7.0 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/rs/cors v1.7.0 // indirect github.com/samber/lo v1.39.0 // indirect @@ -223,31 +223,30 @@ require ( go.opentelemetry.io/contrib/propagators/b3 v1.21.1 // indirect go.opentelemetry.io/contrib/propagators/jaeger v1.21.1 // indirect go.opentelemetry.io/contrib/propagators/ot v1.21.1 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.21.0 // indirect - go.opentelemetry.io/otel/exporters/zipkin v1.21.0 // indirect - go.opentelemetry.io/otel/metric v1.24.0 // indirect - go.opentelemetry.io/proto/otlp v1.0.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.25.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.25.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.25.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.25.0 // indirect + go.opentelemetry.io/otel/exporters/zipkin v1.25.0 // indirect + go.opentelemetry.io/otel/metric v1.25.0 // indirect + go.opentelemetry.io/proto/otlp v1.2.0 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/mock v0.4.0 // indirect go4.org v0.0.0-20230225012048-214862532bf5 // indirect - golang.org/x/net v0.21.0 // indirect - golang.org/x/oauth2 v0.17.0 // indirect - golang.org/x/term v0.17.0 // indirect + golang.org/x/net v0.24.0 // indirect + golang.org/x/oauth2 v0.19.0 // indirect + golang.org/x/term v0.19.0 // indirect golang.org/x/text v0.14.0 // indirect - golang.org/x/tools v0.18.0 // indirect + golang.org/x/tools v0.20.0 // indirect golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect - gonum.org/v1/gonum v0.14.0 // indirect - google.golang.org/appengine v1.6.8 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240108191215-35c7eff3a6b1 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240108191215-35c7eff3a6b1 // indirect - google.golang.org/grpc v1.60.1 // indirect + gonum.org/v1/gonum v0.15.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240412170617-26222e5d3d56 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240412170617-26222e5d3d56 // indirect + google.golang.org/grpc v1.63.2 // indirect gopkg.in/square/go-jose.v2 v2.5.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - lukechampine.com/blake3 v1.2.1 // indirect + lukechampine.com/blake3 v1.2.2 // indirect ) go 1.22 diff --git a/go.sum b/go.sum index fcd51a181..5b58d28c2 100644 --- a/go.sum +++ b/go.sum @@ -85,8 +85,8 @@ github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= -github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= -github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= +github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/ceramicnetwork/go-dag-jose v0.1.0 h1:yJ/HVlfKpnD3LdYP03AHyTvbm3BpPiz2oZiOeReJRdU= github.com/ceramicnetwork/go-dag-jose v0.1.0/go.mod h1:qYA1nYt0X8u4XoMAVoOV3upUVKtrxy/I670Dg5F0wjI= @@ -94,8 +94,8 @@ github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= -github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cheggaaa/pb v1.0.29 h1:FckUN5ngEk2LpvuG0fw1GEFx6LtyY2pWI/Z2QgCnEYo= github.com/cheggaaa/pb v1.0.29/go.mod h1:W40334L7FMC5JKWldsTWbdGjLo0RxUKK73K+TuPxX30= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= @@ -132,8 +132,8 @@ github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c h1:pFUpOrbxDR github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c/go.mod h1:6UhI8N9EjYm1c2odKpFpAYeR8dsBeM7PtzQhRgxRr9U= github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y= github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= github.com/dgraph-io/badger v1.6.2 h1:mNw0qs90GVgGGWylh0umH5iag1j6n/PeJtNvL6KY/x8= github.com/dgraph-io/badger v1.6.2/go.mod h1:JW2yswe3V058sS0kZ2h/AXeDSqFjxnZcRrVH//y2UQE= @@ -245,8 +245,8 @@ github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= @@ -281,8 +281,8 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20240207164012-fb44976bdcd5 h1:E/LAvt58di64hlYjx7AsNS6C/ysHWYo+2qPCZKTQhRo= -github.com/google/pprof v0.0.0-20240207164012-fb44976bdcd5/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= +github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd h1:gbpYu9NMq8jhDVbvlGkMFWCjLFlqqEZjEmObmhUy6Vo= +github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -302,8 +302,8 @@ github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/ github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0 h1:Wqo399gCIufwto+VfwCSvsnfGpF/w5E9CNxSwbpD6No= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0/go.mod h1:qmOFXW2epJhM0qSnUUYpldc7gVz2KMQwJ/QYCDIa7XU= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1 h1:/c3QmbOGMGTOumP2iT/rCwB7b0QDGLKzqOmktBjT+Is= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1/go.mod h1:5SN9VR2LTsRFsrEC6FHgRbTWrTHu6tqPeKxEQv15giM= github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -329,8 +329,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.19.0 h1:UbX9FBJQF19ACLqRZOgdEla6jR/sC4H1O+iGE0NToXA= -github.com/ipfs/boxo v0.19.0/go.mod h1:V5gJzbIMwKEXrg3IdvAxIdF7UPgU4RsXmNGS8MQ/0D4= +github.com/ipfs/boxo v0.19.1-0.20240415103851-7f9506844904 h1:HqjqN6oADXh1UNw8xKnBP50B3ZQDC/RStiBFPp6W+9Y= +github.com/ipfs/boxo v0.19.1-0.20240415103851-7f9506844904/go.mod h1:hA9Ou/YnfMZOG2nQhngsbBiYt6fiJ1EhWSmccZfV+M0= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= @@ -339,12 +339,11 @@ github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJ github.com/ipfs/go-block-format v0.0.3/go.mod h1:4LmD4ZUw0mhO+JSKdpWwrzATiEfM7WWgQ8H5l6P8MVk= github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs= github.com/ipfs/go-block-format v0.2.0/go.mod h1:+jpL11nFx5A/SPpsoBn6Bzkra/zaArfSmsknbPMYgzM= -github.com/ipfs/go-blockservice v0.5.0 h1:B2mwhhhVQl2ntW2EIpaWPwSCxSuqr5fFA93Ms4bYLEY= -github.com/ipfs/go-blockservice v0.5.0/go.mod h1:W6brZ5k20AehbmERplmERn8o2Ni3ZZubvAxaIUeaT6w= +github.com/ipfs/go-blockservice v0.5.2 h1:in9Bc+QcXwd1apOVM7Un9t8tixPKdaHQFdLSUM1Xgk8= +github.com/ipfs/go-blockservice v0.5.2/go.mod h1:VpMblFEqG67A/H2sHKAemeH9vlURVavlysbdUI632yk= github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.3/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.4/go.mod h1:4LLaPOQwmk5z9LBgQnpkivrx8BJjUyGwTXCd5Xfj6+M= -github.com/ipfs/go-cid v0.0.5/go.mod h1:plgt+Y5MnOey4vO4UlUazGqdbEXuFYitED67FexhXog= github.com/ipfs/go-cid v0.0.7/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I= github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= github.com/ipfs/go-cid v0.4.1/go.mod h1:uQHwDeX4c6CtyrFwdqyhpNcxVewur1M7l7fNU7LKwZk= @@ -369,8 +368,8 @@ github.com/ipfs/go-ds-measure v0.2.0 h1:sG4goQe0KDTccHMyT45CY1XyUbxe5VwTKpg2LjAp github.com/ipfs/go-ds-measure v0.2.0/go.mod h1:SEUD/rE2PwRa4IQEC5FuNAmjJCyYObZr9UvVh8V3JxE= github.com/ipfs/go-fs-lock v0.0.7 h1:6BR3dajORFrFTkb5EpCUFIAypsoxpGpDSVUdFwzgL9U= github.com/ipfs/go-fs-lock v0.0.7/go.mod h1:Js8ka+FNYmgQRLrRXzU3CB/+Csr1BwrRilEcvYrHhhc= -github.com/ipfs/go-ipfs-blockstore v1.3.0 h1:m2EXaWgwTzAfsmt5UdJ7Is6l4gJcaM/A12XwJyvYvMM= -github.com/ipfs/go-ipfs-blockstore v1.3.0/go.mod h1:KgtZyc9fq+P2xJUiCAzbRdhhqJHvsw8u2Dlqy2MyRTE= +github.com/ipfs/go-ipfs-blockstore v1.3.1 h1:cEI9ci7V0sRNivqaOr0elDsamxXFxJMMMy7PTTDQNsQ= +github.com/ipfs/go-ipfs-blockstore v1.3.1/go.mod h1:KgtZyc9fq+P2xJUiCAzbRdhhqJHvsw8u2Dlqy2MyRTE= github.com/ipfs/go-ipfs-blocksutil v0.0.1 h1:Eh/H4pc1hsvhzsQoMEP3Bke/aW5P5rVM1IWFJMcGIPQ= github.com/ipfs/go-ipfs-blocksutil v0.0.1/go.mod h1:Yq4M86uIOmxmGPUHv/uI7uKqZNtLb449gwKqXjIsnRk= github.com/ipfs/go-ipfs-chunker v0.0.5 h1:ojCf7HV/m+uS2vhUGWcogIIxiO5ubl5O57Q7NapWLY8= @@ -380,10 +379,10 @@ github.com/ipfs/go-ipfs-cmds v0.10.0/go.mod h1:sX5d7jkCft9XLPnkgEfXY0z2UBOB5g6fh github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= github.com/ipfs/go-ipfs-delay v0.0.1 h1:r/UXYyRcddO6thwOnhiznIAiSvxMECGgtv35Xs1IeRQ= github.com/ipfs/go-ipfs-delay v0.0.1/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= -github.com/ipfs/go-ipfs-ds-help v1.1.0 h1:yLE2w9RAsl31LtfMt91tRZcrx+e61O5mDxFRR994w4Q= -github.com/ipfs/go-ipfs-ds-help v1.1.0/go.mod h1:YR5+6EaebOhfcqVCyqemItCLthrpVNot+rsOU/5IatU= -github.com/ipfs/go-ipfs-exchange-interface v0.2.0 h1:8lMSJmKogZYNo2jjhUs0izT+dck05pqUw4mWNW9Pw6Y= -github.com/ipfs/go-ipfs-exchange-interface v0.2.0/go.mod h1:z6+RhJuDQbqKguVyslSOuVDhqF9JtTrO3eptSAiW2/Y= +github.com/ipfs/go-ipfs-ds-help v1.1.1 h1:B5UJOH52IbcfS56+Ul+sv8jnIV10lbjLF5eOO0C66Nw= +github.com/ipfs/go-ipfs-ds-help v1.1.1/go.mod h1:75vrVCkSdSFidJscs8n4W+77AtTpCIAdDGAwjitJMIo= +github.com/ipfs/go-ipfs-exchange-interface v0.2.1 h1:jMzo2VhLKSHbVe+mHNzYgs95n0+t0Q69GQ5WhRDZV/s= +github.com/ipfs/go-ipfs-exchange-interface v0.2.1/go.mod h1:MUsYn6rKbG6CTtsDp+lKJPmVt3ZrCViNyH3rfPGsZ2E= github.com/ipfs/go-ipfs-exchange-offline v0.3.0 h1:c/Dg8GDPzixGd0MC8Jh6mjOwU57uYokgWRFidfvEkuA= github.com/ipfs/go-ipfs-exchange-offline v0.3.0/go.mod h1:MOdJ9DChbb5u37M1IcbrRB02e++Z7521fMxqCNRrz9s= github.com/ipfs/go-ipfs-pq v0.0.3 h1:YpoHVJB+jzK15mr/xsWC574tyDLkezVrDNeaalQBsTE= @@ -426,10 +425,10 @@ github.com/ipfs/go-unixfs v0.4.5 h1:wj8JhxvV1G6CD7swACwSKYa+NgtdWC1RUit+gFnymDU= github.com/ipfs/go-unixfs v0.4.5/go.mod h1:BIznJNvt/gEx/ooRMI4Us9K8+qeGO7vx1ohnbk8gjFg= github.com/ipfs/go-unixfsnode v1.9.0 h1:ubEhQhr22sPAKO2DNsyVBW7YB/zA8Zkif25aBvz8rc8= github.com/ipfs/go-unixfsnode v1.9.0/go.mod h1:HxRu9HYHOjK6HUqFBAi++7DVoWAHn0o4v/nZ/VA+0g8= -github.com/ipfs/go-verifcid v0.0.2 h1:XPnUv0XmdH+ZIhLGKg6U2vaPaRDXb9urMyNVCE7uvTs= -github.com/ipfs/go-verifcid v0.0.2/go.mod h1:40cD9x1y4OWnFXbLNJYRe7MpNvWlMn3LZAG5Wb4xnPU= -github.com/ipld/go-car v0.5.0 h1:kcCEa3CvYMs0iE5BzD5sV7O2EwMiCIp3uF8tA6APQT8= -github.com/ipld/go-car v0.5.0/go.mod h1:ppiN5GWpjOZU9PgpAZ9HbZd9ZgSpwPMr48fGRJOWmvE= +github.com/ipfs/go-verifcid v0.0.3 h1:gmRKccqhWDocCRkC+a59g5QW7uJw5bpX9HWBevXa0zs= +github.com/ipfs/go-verifcid v0.0.3/go.mod h1:gcCtGniVzelKrbk9ooUSX/pM3xlH73fZZJDzQJRvOUw= +github.com/ipld/go-car v0.6.2 h1:Hlnl3Awgnq8icK+ze3iRghk805lu8YNq3wlREDTF2qc= +github.com/ipld/go-car v0.6.2/go.mod h1:oEGXdwp6bmxJCZ+rARSkDliTeYnVzv3++eXajZ+Bmr8= github.com/ipld/go-car/v2 v2.13.1 h1:KnlrKvEPEzr5IZHKTXLAEub+tPrzeAFQVRlSQvuxBO4= github.com/ipld/go-car/v2 v2.13.1/go.mod h1:QkdjjFNGit2GIkpQ953KBwowuoukoM75nP/JI1iDJdo= github.com/ipld/go-codec-dagpb v1.6.0 h1:9nYazfyu9B1p3NAgfVdpRco3Fs2nFC72DqVsMj6rOcc= @@ -474,8 +473,8 @@ github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQL 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.17.6 h1:60eq2E/jlfwQXtvZEeBUYADs+BwKBWURIY+Gj2eRGjI= -github.com/klauspost/compress v1.17.6/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= +github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU= +github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= @@ -664,8 +663,8 @@ github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9k github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.15.0 h1:79HwNRBAZHOEwrczrgSOPy+eFTTlIGELKy5as+ClttY= -github.com/onsi/ginkgo/v2 v2.15.0/go.mod h1:HlxMHtYF57y6Dpf+mc5529KKmSq9h2FpCF+/ZkwUxKM= +github.com/onsi/ginkgo/v2 v2.17.1 h1:V++EzdbhI4ZV4ev0UTIj0PzhzOcReJFyJaLjtSF55M8= +github.com/onsi/ginkgo/v2 v2.17.1/go.mod h1:llBI3WDLL9Z6taip6f33H76YcWtJv+7R3HigUjbIBOs= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= @@ -758,8 +757,8 @@ github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1: github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.6.0 h1:k1v3CzpSRUTrKMppY35TLwPvxHqBu0bYgxZzqGIgaos= -github.com/prometheus/client_model v0.6.0/go.mod h1:NTQHnmxFpouOD0DpvP4XujX3CdOAGQPoaGhyTchlyt8= +github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= +github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= @@ -768,8 +767,8 @@ github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9 github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/common v0.35.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= -github.com/prometheus/common v0.49.0 h1:ToNTdK4zSnPVJmh698mGFkDor9wBI/iGaJy5dbH1EgI= -github.com/prometheus/common v0.49.0/go.mod h1:Kxm+EULxRbUkjGU6WFsQqo3ORzB4tyKvlWFOE9mB2sE= +github.com/prometheus/common v0.52.3 h1:5f8uj6ZwHSscOGNdIQg6OiZv/ybiK2CO2q2drVZAQSA= +github.com/prometheus/common v0.52.3/go.mod h1:BrxBKv3FWBIGXw89Mg1AeBq7FSyRzXWI3l3e7W3RN5U= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= @@ -778,16 +777,16 @@ github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4O github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= -github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= -github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= +github.com/prometheus/procfs v0.13.0 h1:GqzLlQyfsPbaEHaQkO7tbDlriv/4o5Hudv6OXHGKX7o= +github.com/prometheus/procfs v0.13.0/go.mod h1:cd4PFCR54QLnGKPaKGA6l+cfuNXtht43ZKY6tow0Y1g= github.com/prometheus/statsd_exporter v0.22.7 h1:7Pji/i2GuhK6Lu7DHrtTkFmNBCudCPT1pX2CziuyQR0= github.com/prometheus/statsd_exporter v0.22.7/go.mod h1:N/TevpjkIh9ccs6nuzY3jQn9dFqnUakOjnEuMPJJJnI= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= github.com/quic-go/quic-go v0.42.0 h1:uSfdap0eveIl8KXnipv9K7nlwZ5IqLlYOpJ58u5utpM= github.com/quic-go/quic-go v0.42.0/go.mod h1:132kz4kL3F9vxhW3CtQJLDVwcFe5wdWeJXXijhsO57M= -github.com/quic-go/webtransport-go v0.6.0 h1:CvNsKqc4W2HljHJnoT+rMmbRJybShZ0YPFDD3NxaZLY= -github.com/quic-go/webtransport-go v0.6.0/go.mod h1:9KjU4AEBqEQidGHNDkZrb8CAa1abRaosM2yGOyiikEc= +github.com/quic-go/webtransport-go v0.7.0 h1:dv9wDD9Rd0cuSRLRHPrOX9fSY8QBpdXW4Ls85WXMKqE= +github.com/quic-go/webtransport-go v0.7.0/go.mod h1:MX3nFXrcXkdzblIfOXFZ5lVCZhn+VbMMspOweP1HoXE= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= @@ -853,8 +852,9 @@ github.com/src-d/envconfig v1.0.0/go.mod h1:Q9YQZ7BKITldTBnoxsE5gOeB5y66RyPXeue/ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -865,8 +865,9 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/stvp/go-udp-testing v0.0.0-20201019212854-469649b16807/go.mod h1:7jxmlfBCDBXRzr0eAQJ48XC1hBu1np4CS5+cHEYfwpc= github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= @@ -935,8 +936,8 @@ go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 h1:aFJWCqJMNjENlcleuuOkGAPH82y0yULBScfXcIEdS24= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1/go.mod h1:sEGXWArGqc3tVa+ekntsN65DmVbVeW+7lTKTjZF3/Fo= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.50.0 h1:cEPbyTSEHlQR89XVlyo78gqluF8Y3oMeBkXGWzQsfXY= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.50.0/go.mod h1:DKdbWcT4GH1D0Y3Sqt/PFXt2naRKDWtU+eE6oLdFNA8= go.opentelemetry.io/contrib/propagators/autoprop v0.46.1 h1:cXTYcMjY0dsYokAuo8LbNBQxpF8VgTHdiHJJ1zlIXl4= go.opentelemetry.io/contrib/propagators/autoprop v0.46.1/go.mod h1:WZxgny1/6+j67B1s72PLJ4bGjidoWFzSmLNfJKVt2bo= go.opentelemetry.io/contrib/propagators/aws v1.21.1 h1:uQIQIDWb0gzyvon2ICnghpLAf9w7ADOCUiIiwCQgR2o= @@ -947,26 +948,26 @@ go.opentelemetry.io/contrib/propagators/jaeger v1.21.1 h1:f4beMGDKiVzg9IcX7/VuWV go.opentelemetry.io/contrib/propagators/jaeger v1.21.1/go.mod h1:U9jhkEl8d1LL+QXY7q3kneJWJugiN3kZJV2OWz3hkBY= go.opentelemetry.io/contrib/propagators/ot v1.21.1 h1:3TN5vkXjKYWp0YdMcnUEC/A+pBPvqz9V3nCS2xmcurk= go.opentelemetry.io/contrib/propagators/ot v1.21.1/go.mod h1:oy0MYCbS/b3cqUDW37wBWtlwBIsutngS++Lklpgh+fc= -go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo= -go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 h1:cl5P5/GIfFh4t6xyruOgJP5QiA1pw4fYYdv6nc6CBWw= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0/go.mod h1:zgBdWWAu7oEEMC06MMKc5NLbA/1YDXV1sMpSqEeLQLg= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0 h1:tIqheXEFWAZ7O8A7m+J0aPTmpJN3YQ7qetUAdkkkKpk= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0/go.mod h1:nUeKExfxAQVbiVFn32YXpXZZHZ61Cc3s3Rn1pDBGAb0= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0 h1:digkEZCJWobwBqMwC0cwCq8/wkkRy/OowZg5OArWZrM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0/go.mod h1:/OpE/y70qVkndM0TrxT4KBoN3RsFZP0QaofcfYrj76I= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.21.0 h1:VhlEQAPp9R1ktYfrPk5SOryw1e9LDDTZCbIPFrho0ec= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.21.0/go.mod h1:kB3ufRbfU+CQ4MlUcqtW8Z7YEOBeK2DJ6CmR5rYYF3E= -go.opentelemetry.io/otel/exporters/zipkin v1.21.0 h1:D+Gv6lSfrFBWmQYyxKjDd0Zuld9SRXpIrEsKZvE4DO4= -go.opentelemetry.io/otel/exporters/zipkin v1.21.0/go.mod h1:83oMKR6DzmHisFOW3I+yIMGZUTjxiWaiBI8M8+TU5zE= -go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI= -go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco= -go.opentelemetry.io/otel/sdk v1.21.0 h1:FTt8qirL1EysG6sTQRZ5TokkU8d0ugCj8htOgThZXQ8= -go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E= -go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI= -go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU= -go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I= -go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM= +go.opentelemetry.io/otel v1.25.0 h1:gldB5FfhRl7OJQbUHt/8s0a7cE8fbsPAtdpRaApKy4k= +go.opentelemetry.io/otel v1.25.0/go.mod h1:Wa2ds5NOXEMkCmUou1WA7ZBfLTHWIsp034OVD7AO+Vg= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.25.0 h1:dT33yIHtmsqpixFsSQPwNeY5drM9wTcoL8h0FWF4oGM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.25.0/go.mod h1:h95q0LBGh7hlAC08X2DhSeyIG02YQ0UyioTCVAqRPmc= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.25.0 h1:vOL89uRfOCCNIjkisd0r7SEdJF3ZJFyCNY34fdZs8eU= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.25.0/go.mod h1:8GlBGcDk8KKi7n+2S4BT/CPZQYH3erLu0/k64r1MYgo= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.25.0 h1:Mbi5PKN7u322woPa85d7ebZ+SOvEoPvoiBu+ryHWgfA= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.25.0/go.mod h1:e7ciERRhZaOZXVjx5MiL8TK5+Xv7G5Gv5PA2ZDEJdL8= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.25.0 h1:0vZZdECYzhTt9MKQZ5qQ0V+J3MFu4MQaQ3COfugF+FQ= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.25.0/go.mod h1:e7iXx3HjaSSBXfy9ykVUlupS2Vp7LBIBuT21ousM2Hk= +go.opentelemetry.io/otel/exporters/zipkin v1.25.0 h1:iLzdsOsstvim/54ymA2BhEN4+1NbsvwGvOhSkQy2TaY= +go.opentelemetry.io/otel/exporters/zipkin v1.25.0/go.mod h1:3QXxNo6ace1QZX6pSHEzGKKESVdjQxXR03FcIH7dNGs= +go.opentelemetry.io/otel/metric v1.25.0 h1:LUKbS7ArpFL/I2jJHdJcqMGxkRdxpPHE0VU/D4NuEwA= +go.opentelemetry.io/otel/metric v1.25.0/go.mod h1:rkDLUSd2lC5lq2dFNrX9LGAbINP5B7WBkC78RXCpH5s= +go.opentelemetry.io/otel/sdk v1.25.0 h1:PDryEJPC8YJZQSyLY5eqLeafHtG+X7FWnf3aXMtxbqo= +go.opentelemetry.io/otel/sdk v1.25.0/go.mod h1:oFgzCM2zdsxKzz6zwpTZYLLQsFwc+K0daArPdIhuxkw= +go.opentelemetry.io/otel/trace v1.25.0 h1:tqukZGLwQYRIFtSQM2u2+yfMVTgGVeqRLPUYx1Dq6RM= +go.opentelemetry.io/otel/trace v1.25.0/go.mod h1:hCCs70XM/ljO+BeQkyFnbK28SBIJ/Emuha+ccrCRT7I= +go.opentelemetry.io/proto/otlp v1.2.0 h1:pVeZGk7nXDC9O2hncA6nHldxEjm6LByfA2aN8IOkz94= +go.opentelemetry.io/proto/otlp v1.2.0/go.mod h1:gGpR8txAl5M03pDhMC79G6SdqNV26naRm/KDsgaHD8A= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= @@ -1019,8 +1020,8 @@ golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45 golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= -golang.org/x/crypto v0.20.0 h1:jmAMJJZXr5KiCw05dfYK9QnqaqKLYXijU23lsEdcQqg= -golang.org/x/crypto v0.20.0/go.mod h1:Xwo95rrVNIoSMx9wa1JroENMToLWn3RNVrTBpLHgZPQ= +golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= +golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1031,8 +1032,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 h1:LfspQV/FYTatPTr/3HzIcmiUFH7PGP+OQ6mgDYo3yuQ= -golang.org/x/exp v0.0.0-20240222234643-814bf88cf225/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc= +golang.org/x/exp v0.0.0-20240409090435-93d18d7e34b8 h1:ESSUROHIBHg7USnszlcdmjBEwdMj9VUvU+OPk4yl2mc= +golang.org/x/exp v0.0.0-20240409090435-93d18d7e34b8/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1057,8 +1058,8 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8= -golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= +golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1115,8 +1116,8 @@ golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ= golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= -golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= -golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= +golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1126,8 +1127,8 @@ golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4Iltr golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.17.0 h1:6m3ZPmLEFdVxKKWnKq4VqZ60gutO35zm+zrAHVmHyDQ= -golang.org/x/oauth2 v0.17.0/go.mod h1:OzPDGQiuQMguemayvdylqddI7qcD9lnSDb+1FiwQ5HA= +golang.org/x/oauth2 v0.19.0 h1:9+E/EZBCbTLNrbN35fHv/a/d/mOBatymz1zbtQrXpIg= +golang.org/x/oauth2 v0.19.0/go.mod h1:vYi7skDa1x015PmRRYZ7+s1cWyPgrPiSYRe4rnsexc8= golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1143,8 +1144,8 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= -golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/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= @@ -1223,8 +1224,8 @@ golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= -golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= +golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -1236,8 +1237,8 @@ golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo= golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= -golang.org/x/term v0.17.0 h1:mkTF7LCd6WGJNL3K1Ad7kwxNfYAW6a8a8QqtMblp/4U= -golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= +golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q= +golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1245,7 +1246,6 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= @@ -1315,16 +1315,16 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.18.0 h1:k8NLag8AGHnn+PHbl7g43CtqZAwG60vZkLqgyZgIHgQ= -golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg= +golang.org/x/tools v0.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY= +golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU= golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= -gonum.org/v1/gonum v0.14.0 h1:2NiG67LD1tEH0D7kM+ps2V+fXmsAnpUeec7n8tcr4S0= -gonum.org/v1/gonum v0.14.0/go.mod h1:AoWeoz0becf9QMWtE8iWXNXc27fK4fNeHNf/oMejGfU= +gonum.org/v1/gonum v0.15.0 h1:2lYxjRbTYyxkJxlhC+LvJIx3SsANPdRybu1tGj9/OrQ= +gonum.org/v1/gonum v0.15.0/go.mod h1:xzZVBJBtS+Mz4q0Yl2LJTk+OxOg4jiXZ7qBoM0uISGo= google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y= @@ -1352,8 +1352,6 @@ google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7 google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= -google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= @@ -1387,12 +1385,10 @@ google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7Fc google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20240102182953-50ed04b92917 h1:nz5NESFLZbJGPFxDT/HCn+V1mZ8JGNoY4nUpmW/Y2eg= -google.golang.org/genproto v0.0.0-20240102182953-50ed04b92917/go.mod h1:pZqR+glSb11aJ+JQcczCvgf47+duRuzNSKqE8YAQnV0= -google.golang.org/genproto/googleapis/api v0.0.0-20240108191215-35c7eff3a6b1 h1:OPXtXn7fNMaXwO3JvOmF1QyTc00jsSFFz1vXXBOdCDo= -google.golang.org/genproto/googleapis/api v0.0.0-20240108191215-35c7eff3a6b1/go.mod h1:B5xPO//w8qmBDjGReYLpR6UJPnkldGkCSMoH/2vxJeg= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240108191215-35c7eff3a6b1 h1:gphdwh0npgs8elJ4T6J+DQJHPVF7RsuJHCfwztUb4J4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240108191215-35c7eff3a6b1/go.mod h1:daQN87bsDqDoe316QbbvX60nMoJQa4r6Ds0ZuoAe5yA= +google.golang.org/genproto/googleapis/api v0.0.0-20240412170617-26222e5d3d56 h1:KuFzeG+qPmpT8KpJXcrKAyeHhn64dgEICWlccP9qp0U= +google.golang.org/genproto/googleapis/api v0.0.0-20240412170617-26222e5d3d56/go.mod h1:wTHjrkbcS8AoQbb/0v9bFIPItZQPAsyVfgG9YPUhjAM= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240412170617-26222e5d3d56 h1:zviK8GX4VlMstrK3JkexM5UHjH1VOkRebH9y3jhSBGk= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240412170617-26222e5d3d56/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= @@ -1409,8 +1405,8 @@ google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3Iji google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.60.1 h1:26+wFr+cNqSGFcOXcabYC0lUVJVRa2Sb2ortSK7VrEU= -google.golang.org/grpc v1.60.1/go.mod h1:OlCHIeLYqSSsLi6i49B5QGdzaMZK9+M7LXN2FKz4eGM= +google.golang.org/grpc v1.63.2 h1:MUeiw1B2maTVZthpU5xvASfTh3LDbxHd6IJ6QQVU+xM= +google.golang.org/grpc v1.63.2/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -1425,8 +1421,8 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= -google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= +google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -1464,8 +1460,8 @@ honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= lukechampine.com/blake3 v1.1.6/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= -lukechampine.com/blake3 v1.2.1 h1:YuqqRuaqsGV71BV/nm9xlI0MKUv4QC54jQnBChWbGnI= -lukechampine.com/blake3 v1.2.1/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= +lukechampine.com/blake3 v1.2.2 h1:wEAbSg0IVU4ih44CVlpMqMZMpzr5hf/6aqodLlevd/w= +lukechampine.com/blake3 v1.2.2/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= pgregory.net/rapid v0.4.7 h1:MTNRktPuv5FNqOO151TM9mDTa+XHcX6ypYeISDVD14g= pgregory.net/rapid v0.4.7/go.mod h1:UYpPVyjFHzYBGHIxLFoupi8vwk6rXNzRY9OMvVxFIOU= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 6b6ecea99..86f0b7336 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -46,14 +46,14 @@ require ( github.com/breml/errchkjson v0.3.1 // indirect github.com/butuzov/ireturn v0.2.0 // indirect github.com/butuzov/mirror v1.1.0 // indirect - github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/charithe/durationcheck v0.0.10 // indirect github.com/chavacava/garif v0.0.0-20230227094218-b8c73b2037b8 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/curioswitch/go-reassign v0.2.0 // indirect github.com/daixiang0/gci v0.11.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect github.com/denis-tingaikin/go-header v0.4.3 // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/esimonov/ifshort v1.0.4 // indirect @@ -105,7 +105,7 @@ require ( github.com/hexops/gotextdiff v1.0.3 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/ipfs/bbloom v0.0.4 // indirect - github.com/ipfs/boxo v0.19.0 // indirect + github.com/ipfs/boxo v0.19.1-0.20240415103851-7f9506844904 // indirect github.com/ipfs/go-block-format v0.2.0 // indirect github.com/ipfs/go-cid v0.4.1 // indirect github.com/ipfs/go-datastore v0.6.0 // indirect @@ -181,9 +181,9 @@ require ( github.com/polydawn/refmt v0.89.0 // indirect github.com/polyfloyd/go-errorlint v1.4.3 // indirect github.com/prometheus/client_golang v1.19.0 // indirect - github.com/prometheus/client_model v0.6.0 // indirect - github.com/prometheus/common v0.49.0 // indirect - github.com/prometheus/procfs v0.12.0 // indirect + github.com/prometheus/client_model v0.6.1 // indirect + github.com/prometheus/common v0.52.3 // indirect + github.com/prometheus/procfs v0.13.0 // indirect github.com/quasilyte/go-ruleguard v0.4.0 // indirect github.com/quasilyte/gogrep v0.5.0 // indirect github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727 // indirect @@ -212,8 +212,8 @@ require ( github.com/spf13/viper v1.12.0 // indirect github.com/ssgreg/nlreturn/v2 v2.2.1 // indirect github.com/stbenjam/no-sprintf-host-port v0.1.1 // indirect - github.com/stretchr/objx v0.5.0 // indirect - github.com/stretchr/testify v1.8.4 // indirect + github.com/stretchr/objx v0.5.2 // indirect + github.com/stretchr/testify v1.9.0 // indirect github.com/subosito/gotenv v1.4.1 // indirect github.com/t-yuki/gocover-cobertura v0.0.0-20180217150009-aaee18c8195c // indirect github.com/tdakkota/asciicheck v0.2.0 // indirect @@ -234,29 +234,29 @@ require ( github.com/ykadowak/zerologlint v0.1.3 // indirect gitlab.com/bosi/decorder v0.4.0 // indirect go.opencensus.io v0.24.0 // indirect - go.opentelemetry.io/otel v1.24.0 // indirect - go.opentelemetry.io/otel/metric v1.24.0 // indirect - go.opentelemetry.io/otel/trace v1.24.0 // indirect + go.opentelemetry.io/otel v1.25.0 // indirect + go.opentelemetry.io/otel/metric v1.25.0 // indirect + go.opentelemetry.io/otel/trace v1.25.0 // indirect go.tmz.dev/musttag v0.7.1 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect - golang.org/x/crypto v0.20.0 // indirect - golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 // indirect + golang.org/x/crypto v0.22.0 // indirect + golang.org/x/exp v0.0.0-20240409090435-93d18d7e34b8 // indirect golang.org/x/exp/typeparams v0.0.0-20230307190834-24139beb5833 // indirect - golang.org/x/mod v0.15.0 // indirect - golang.org/x/net v0.21.0 // indirect - golang.org/x/sync v0.6.0 // indirect - golang.org/x/sys v0.17.0 // indirect - golang.org/x/term v0.17.0 // indirect + golang.org/x/mod v0.17.0 // indirect + golang.org/x/net v0.24.0 // indirect + golang.org/x/sync v0.7.0 // indirect + golang.org/x/sys v0.19.0 // indirect + golang.org/x/term v0.19.0 // indirect golang.org/x/text v0.14.0 // indirect - golang.org/x/tools v0.18.0 // indirect - gonum.org/v1/gonum v0.14.0 // indirect - google.golang.org/protobuf v1.32.0 // indirect + golang.org/x/tools v0.20.0 // indirect + gonum.org/v1/gonum v0.15.0 // indirect + google.golang.org/protobuf v1.33.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect honnef.co/go/tools v0.4.3 // indirect - lukechampine.com/blake3 v1.2.1 // indirect + lukechampine.com/blake3 v1.2.2 // indirect mvdan.cc/gofumpt v0.5.0 // indirect mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed // indirect mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 18d82929d..14bb2aa25 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -101,8 +101,8 @@ github.com/butuzov/mirror v1.1.0/go.mod h1:8Q0BdQU6rC6WILDiBM60DBfvV78OLJmMmixe7 github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= -github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/charithe/durationcheck v0.0.10 h1:wgw73BiocdBDQPik+zcEoBG/ob8uyBHf2iyoHGPf5w4= github.com/charithe/durationcheck v0.0.10/go.mod h1:bCWXb7gYRysD1CU3C+u4ceO49LoGOY1C1L6uouGNreQ= github.com/chavacava/garif v0.0.0-20230227094218-b8c73b2037b8 h1:W9o46d2kbNL06lq7UNDPV0zYLzkrde/bjIqO02eoll0= @@ -134,8 +134,8 @@ github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c h1:pFUpOrbxDR github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c/go.mod h1:6UhI8N9EjYm1c2odKpFpAYeR8dsBeM7PtzQhRgxRr9U= github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y= github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= github.com/denis-tingaikin/go-header v0.4.3 h1:tEaZKAlqql6SKCY++utLmkPLd6K8IBM20Ha7UVm+mtU= github.com/denis-tingaikin/go-header v0.4.3/go.mod h1:0wOCWuN71D5qIgE2nz9KrKmuYBAC2Mra5RassOIQ2/c= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= @@ -305,8 +305,8 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20240207164012-fb44976bdcd5 h1:E/LAvt58di64hlYjx7AsNS6C/ysHWYo+2qPCZKTQhRo= -github.com/google/pprof v0.0.0-20240207164012-fb44976bdcd5/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= +github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd h1:gbpYu9NMq8jhDVbvlGkMFWCjLFlqqEZjEmObmhUy6Vo= +github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= @@ -362,8 +362,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.19.0 h1:UbX9FBJQF19ACLqRZOgdEla6jR/sC4H1O+iGE0NToXA= -github.com/ipfs/boxo v0.19.0/go.mod h1:V5gJzbIMwKEXrg3IdvAxIdF7UPgU4RsXmNGS8MQ/0D4= +github.com/ipfs/boxo v0.19.1-0.20240415103851-7f9506844904 h1:HqjqN6oADXh1UNw8xKnBP50B3ZQDC/RStiBFPp6W+9Y= +github.com/ipfs/boxo v0.19.1-0.20240415103851-7f9506844904/go.mod h1:hA9Ou/YnfMZOG2nQhngsbBiYt6fiJ1EhWSmccZfV+M0= github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs= github.com/ipfs/go-block-format v0.2.0/go.mod h1:+jpL11nFx5A/SPpsoBn6Bzkra/zaArfSmsknbPMYgzM= github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= @@ -445,8 +445,8 @@ github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kkHAIKE/contextcheck v1.1.4 h1:B6zAaLhOEEcjvUgIYEqystmnFk1Oemn8bvJhbt0GMb8= github.com/kkHAIKE/contextcheck v1.1.4/go.mod h1:1+i/gWqokIa+dm31mqGLZhZJ7Uh44DJGZVmr6QRBNJg= -github.com/klauspost/compress v1.17.6 h1:60eq2E/jlfwQXtvZEeBUYADs+BwKBWURIY+Gj2eRGjI= -github.com/klauspost/compress v1.17.6/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= +github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU= +github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -598,8 +598,8 @@ github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6 github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w= github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo/v2 v2.15.0 h1:79HwNRBAZHOEwrczrgSOPy+eFTTlIGELKy5as+ClttY= -github.com/onsi/ginkgo/v2 v2.15.0/go.mod h1:HlxMHtYF57y6Dpf+mc5529KKmSq9h2FpCF+/ZkwUxKM= +github.com/onsi/ginkgo/v2 v2.17.1 h1:V++EzdbhI4ZV4ev0UTIj0PzhzOcReJFyJaLjtSF55M8= +github.com/onsi/ginkgo/v2 v2.17.1/go.mod h1:llBI3WDLL9Z6taip6f33H76YcWtJv+7R3HigUjbIBOs= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= @@ -641,21 +641,21 @@ github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1: github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.6.0 h1:k1v3CzpSRUTrKMppY35TLwPvxHqBu0bYgxZzqGIgaos= -github.com/prometheus/client_model v0.6.0/go.mod h1:NTQHnmxFpouOD0DpvP4XujX3CdOAGQPoaGhyTchlyt8= +github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= +github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= -github.com/prometheus/common v0.49.0 h1:ToNTdK4zSnPVJmh698mGFkDor9wBI/iGaJy5dbH1EgI= -github.com/prometheus/common v0.49.0/go.mod h1:Kxm+EULxRbUkjGU6WFsQqo3ORzB4tyKvlWFOE9mB2sE= +github.com/prometheus/common v0.52.3 h1:5f8uj6ZwHSscOGNdIQg6OiZv/ybiK2CO2q2drVZAQSA= +github.com/prometheus/common v0.52.3/go.mod h1:BrxBKv3FWBIGXw89Mg1AeBq7FSyRzXWI3l3e7W3RN5U= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= -github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= +github.com/prometheus/procfs v0.13.0 h1:GqzLlQyfsPbaEHaQkO7tbDlriv/4o5Hudv6OXHGKX7o= +github.com/prometheus/procfs v0.13.0/go.mod h1:cd4PFCR54QLnGKPaKGA6l+cfuNXtht43ZKY6tow0Y1g= github.com/quasilyte/go-ruleguard v0.4.0 h1:DyM6r+TKL+xbKB4Nm7Afd1IQh9kEUKQs2pboWGKtvQo= github.com/quasilyte/go-ruleguard v0.4.0/go.mod h1:Eu76Z/R8IXtViWUIHkE3p8gdH3/PKk1eh3YGfaEof10= github.com/quasilyte/gogrep v0.5.0 h1:eTKODPXbI8ffJMN+W2aE0+oL0z/nh8/5eNdiO34SOAo= @@ -668,8 +668,8 @@ github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= github.com/quic-go/quic-go v0.42.0 h1:uSfdap0eveIl8KXnipv9K7nlwZ5IqLlYOpJ58u5utpM= github.com/quic-go/quic-go v0.42.0/go.mod h1:132kz4kL3F9vxhW3CtQJLDVwcFe5wdWeJXXijhsO57M= -github.com/quic-go/webtransport-go v0.6.0 h1:CvNsKqc4W2HljHJnoT+rMmbRJybShZ0YPFDD3NxaZLY= -github.com/quic-go/webtransport-go v0.6.0/go.mod h1:9KjU4AEBqEQidGHNDkZrb8CAa1abRaosM2yGOyiikEc= +github.com/quic-go/webtransport-go v0.7.0 h1:dv9wDD9Rd0cuSRLRHPrOX9fSY8QBpdXW4Ls85WXMKqE= +github.com/quic-go/webtransport-go v0.7.0/go.mod h1:MX3nFXrcXkdzblIfOXFZ5lVCZhn+VbMMspOweP1HoXE= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= @@ -739,8 +739,9 @@ github.com/stbenjam/no-sprintf-host-port v0.1.1/go.mod h1:TLhvtIvONRzdmkFiio4O8L github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.1.4/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= @@ -751,8 +752,8 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.4.1 h1:jyEFiXpy21Wm81FBN71l9VoMMV8H8jG+qIK3GCpY6Qs= github.com/subosito/gotenv v1.4.1/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= github.com/t-yuki/gocover-cobertura v0.0.0-20180217150009-aaee18c8195c h1:+aPplBwWcHBo6q9xrfWdMrT9o4kltkmmvpemgIjep/8= @@ -817,12 +818,12 @@ go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo= -go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo= -go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI= -go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco= -go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI= -go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU= +go.opentelemetry.io/otel v1.25.0 h1:gldB5FfhRl7OJQbUHt/8s0a7cE8fbsPAtdpRaApKy4k= +go.opentelemetry.io/otel v1.25.0/go.mod h1:Wa2ds5NOXEMkCmUou1WA7ZBfLTHWIsp034OVD7AO+Vg= +go.opentelemetry.io/otel/metric v1.25.0 h1:LUKbS7ArpFL/I2jJHdJcqMGxkRdxpPHE0VU/D4NuEwA= +go.opentelemetry.io/otel/metric v1.25.0/go.mod h1:rkDLUSd2lC5lq2dFNrX9LGAbINP5B7WBkC78RXCpH5s= +go.opentelemetry.io/otel/trace v1.25.0 h1:tqukZGLwQYRIFtSQM2u2+yfMVTgGVeqRLPUYx1Dq6RM= +go.opentelemetry.io/otel/trace v1.25.0/go.mod h1:hCCs70XM/ljO+BeQkyFnbK28SBIJ/Emuha+ccrCRT7I= go.tmz.dev/musttag v0.7.1 h1:9lFmeSFnFfPuMq4IksHGomItE6NgKMNW2Nt2FPOhCfU= go.tmz.dev/musttag v0.7.1/go.mod h1:oJLkpR56EsIryktZJk/B0IroSMi37YWver47fibGh5U= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= @@ -856,8 +857,8 @@ golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= -golang.org/x/crypto v0.20.0 h1:jmAMJJZXr5KiCw05dfYK9QnqaqKLYXijU23lsEdcQqg= -golang.org/x/crypto v0.20.0/go.mod h1:Xwo95rrVNIoSMx9wa1JroENMToLWn3RNVrTBpLHgZPQ= +golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= +golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -868,8 +869,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 h1:LfspQV/FYTatPTr/3HzIcmiUFH7PGP+OQ6mgDYo3yuQ= -golang.org/x/exp v0.0.0-20240222234643-814bf88cf225/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc= +golang.org/x/exp v0.0.0-20240409090435-93d18d7e34b8 h1:ESSUROHIBHg7USnszlcdmjBEwdMj9VUvU+OPk4yl2mc= +golang.org/x/exp v0.0.0-20240409090435-93d18d7e34b8/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI= golang.org/x/exp/typeparams v0.0.0-20220428152302-39d4317da171/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/exp/typeparams v0.0.0-20230203172020-98cc5a0785f9/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/exp/typeparams v0.0.0-20230307190834-24139beb5833 h1:jWGQJV4niP+CCmFW9ekjA9Zx8vYORzOUH2/Nl5WPuLQ= @@ -904,8 +905,8 @@ golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91 golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8= -golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= +golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -949,8 +950,8 @@ golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= -golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= +golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -974,8 +975,8 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= -golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= 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= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1038,16 +1039,16 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= -golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= +golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.17.0 h1:mkTF7LCd6WGJNL3K1Ad7kwxNfYAW6a8a8QqtMblp/4U= -golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= +golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q= +golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1138,14 +1139,14 @@ golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= golang.org/x/tools v0.5.0/go.mod h1:N+Kgy78s5I24c24dU8OfWNEotWjutIs8SnJvn5IDq+k= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.18.0 h1:k8NLag8AGHnn+PHbl7g43CtqZAwG60vZkLqgyZgIHgQ= -golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg= +golang.org/x/tools v0.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY= +golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gonum.org/v1/gonum v0.14.0 h1:2NiG67LD1tEH0D7kM+ps2V+fXmsAnpUeec7n8tcr4S0= -gonum.org/v1/gonum v0.14.0/go.mod h1:AoWeoz0becf9QMWtE8iWXNXc27fK4fNeHNf/oMejGfU= +gonum.org/v1/gonum v0.15.0 h1:2lYxjRbTYyxkJxlhC+LvJIx3SsANPdRybu1tGj9/OrQ= +gonum.org/v1/gonum v0.15.0/go.mod h1:xzZVBJBtS+Mz4q0Yl2LJTk+OxOg4jiXZ7qBoM0uISGo= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= @@ -1236,8 +1237,8 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= -google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= +google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -1276,8 +1277,8 @@ honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9 honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.4.3 h1:o/n5/K5gXqk8Gozvs2cnL0F2S1/g1vcGCAx2vETjITw= honnef.co/go/tools v0.4.3/go.mod h1:36ZgoUOrqOk1GxwHhyryEkq8FQWkUO2xGuSMhUCcdvA= -lukechampine.com/blake3 v1.2.1 h1:YuqqRuaqsGV71BV/nm9xlI0MKUv4QC54jQnBChWbGnI= -lukechampine.com/blake3 v1.2.1/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= +lukechampine.com/blake3 v1.2.2 h1:wEAbSg0IVU4ih44CVlpMqMZMpzr5hf/6aqodLlevd/w= +lukechampine.com/blake3 v1.2.2/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= mvdan.cc/gofumpt v0.5.0 h1:0EQ+Z56k8tXjj/6TQD25BFNKQXpCvT0rnansIc7Ug5E= mvdan.cc/gofumpt v0.5.0/go.mod h1:HBeVDtMKRZpXyxFciAirzdKklDlGu8aAy1wEbH5Y9js= mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed h1:WX1yoOaKQfddO/mLzdV4wptyWgoH/6hwLs7QHTixo0I= From eb97cf9e57ed95a0b4c1d6e0d6d60c8dc6b01e67 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Wed, 17 Apr 2024 07:47:39 +0200 Subject: [PATCH 1083/1212] chore: bump to go-ipfs-cmds @ v0.11 --- core/corehttp/commands.go | 5 +++-- go.mod | 6 +++--- go.sum | 12 ++++++------ test/sharness/t0150-clisuggest.sh | 4 ++-- 4 files changed, 14 insertions(+), 13 deletions(-) diff --git a/core/corehttp/commands.go b/core/corehttp/commands.go index 8e1f84422..14de87d08 100644 --- a/core/corehttp/commands.go +++ b/core/corehttp/commands.go @@ -124,9 +124,10 @@ func patchCORSVars(c *cmdsHttp.ServerConfig, addr net.Addr) { func commandsOption(cctx oldcmds.Context, command *cmds.Command) ServeOption { return func(n *core.IpfsNode, l net.Listener, mux *http.ServeMux) (*http.ServeMux, error) { cfg := cmdsHttp.NewServerConfig() - corsAllowedMethods := []string{http.MethodPost} - cfg.SetAllowedMethods(corsAllowedMethods...) + cfg.AddAllowedHeaders("Origin", "Accept", "Content-Type", "X-Requested-With") + cfg.SetAllowedMethods(http.MethodPost) + cfg.APIPath = APIPath rcfg, err := n.Repo.Config() if err != nil { diff --git a/go.mod b/go.mod index 26fe667dc..18548e25c 100644 --- a/go.mod +++ b/go.mod @@ -28,7 +28,7 @@ require ( github.com/ipfs/go-ds-leveldb v0.5.0 github.com/ipfs/go-ds-measure v0.2.0 github.com/ipfs/go-fs-lock v0.0.7 - github.com/ipfs/go-ipfs-cmds v0.10.0 + github.com/ipfs/go-ipfs-cmds v0.11.0 github.com/ipfs/go-ipld-cbor v0.1.0 github.com/ipfs/go-ipld-format v0.6.0 github.com/ipfs/go-ipld-git v0.1.1 @@ -207,10 +207,10 @@ require ( github.com/quic-go/quic-go v0.42.0 // indirect github.com/quic-go/webtransport-go v0.7.0 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect - github.com/rs/cors v1.7.0 // indirect + github.com/rs/cors v1.10.1 // indirect github.com/samber/lo v1.39.0 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect - github.com/texttheater/golang-levenshtein v0.0.0-20180516184445-d188e65d659e // indirect + github.com/texttheater/golang-levenshtein v1.0.1 // indirect github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.0 // indirect github.com/ucarion/urlpath v0.0.0-20200424170820-7ccc79b76bbb // indirect diff --git a/go.sum b/go.sum index 5b58d28c2..5e2d0d86a 100644 --- a/go.sum +++ b/go.sum @@ -374,8 +374,8 @@ github.com/ipfs/go-ipfs-blocksutil v0.0.1 h1:Eh/H4pc1hsvhzsQoMEP3Bke/aW5P5rVM1IW github.com/ipfs/go-ipfs-blocksutil v0.0.1/go.mod h1:Yq4M86uIOmxmGPUHv/uI7uKqZNtLb449gwKqXjIsnRk= github.com/ipfs/go-ipfs-chunker v0.0.5 h1:ojCf7HV/m+uS2vhUGWcogIIxiO5ubl5O57Q7NapWLY8= github.com/ipfs/go-ipfs-chunker v0.0.5/go.mod h1:jhgdF8vxRHycr00k13FM8Y0E+6BoalYeobXmUyTreP8= -github.com/ipfs/go-ipfs-cmds v0.10.0 h1:ZB4+RgYaH4UARfJY0uLKl5UXgApqnRjKbuCiJVcErYk= -github.com/ipfs/go-ipfs-cmds v0.10.0/go.mod h1:sX5d7jkCft9XLPnkgEfXY0z2UBOB5g6fh/obBS0enJE= +github.com/ipfs/go-ipfs-cmds v0.11.0 h1:6AsTKwbVxwzrOkq2x89e6jYMGxzYqjt/WbAam69HZQE= +github.com/ipfs/go-ipfs-cmds v0.11.0/go.mod h1:DHp7YfJlOK+2IS07nk+hFmbKHK52tc29W38CaAgWHpk= github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= github.com/ipfs/go-ipfs-delay v0.0.1 h1:r/UXYyRcddO6thwOnhiznIAiSvxMECGgtv35Xs1IeRQ= github.com/ipfs/go-ipfs-delay v0.0.1/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= @@ -793,8 +793,8 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= -github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= -github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= +github.com/rs/cors v1.10.1 h1:L0uuZVXIKlI1SShY2nhFfo44TYvDPQ1w4oFkUJNfhyo= +github.com/rs/cors v1.10.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd/go.mod h1:hPqNNc0+uJM6H+SuU8sEs5K5IQeKccPqeSjfgcKGgPk= @@ -873,8 +873,8 @@ github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpP github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= -github.com/texttheater/golang-levenshtein v0.0.0-20180516184445-d188e65d659e h1:T5PdfK/M1xyrHwynxMIVMWLS7f/qHwfslZphxtGnw7s= -github.com/texttheater/golang-levenshtein v0.0.0-20180516184445-d188e65d659e/go.mod h1:XDKHRm5ThF8YJjx001LtgelzsoaEcvnA7lVWz9EeX3g= +github.com/texttheater/golang-levenshtein v1.0.1 h1:+cRNoVrfiwufQPhoMzB6N0Yf/Mqajr6t1lOv8GyGE2U= +github.com/texttheater/golang-levenshtein v1.0.1/go.mod h1:PYAKrbF5sAiq9wd+H82hs7gNaen0CplQ9uvm6+enD/8= github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/gjson v1.14.4 h1:uo0p8EbA09J7RQaflQ1aBRffTR7xedD2bcIVSYxLnkM= github.com/tidwall/gjson v1.14.4/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= diff --git a/test/sharness/t0150-clisuggest.sh b/test/sharness/t0150-clisuggest.sh index a504b38dd..30ae6acd2 100755 --- a/test/sharness/t0150-clisuggest.sh +++ b/test/sharness/t0150-clisuggest.sh @@ -18,13 +18,13 @@ test_suggest() { ' test_expect_success "test command fails" ' - test_must_fail ipfs lis 2>actual + test_must_fail ipfs li 2>actual ' test_expect_success "test multiple commands are suggested" ' grep "Did you mean any of these?" actual && grep "ls" actual && - grep "id" actual || + grep "log" actual || test_fsh cat actual ' From 8ee50990027e7408c04187927d1e7b2a40ee8d56 Mon Sep 17 00:00:00 2001 From: dbeal Date: Thu, 25 Apr 2024 20:53:51 +0900 Subject: [PATCH 1084/1212] fix divide by zero error for reprovide error --- core/node/provider.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/core/node/provider.go b/core/node/provider.go index b274584ef..da5dc98d9 100644 --- a/core/node/provider.go +++ b/core/node/provider.go @@ -83,7 +83,11 @@ https://github.com/ipfs/kubo/blob/master/docs/config.md#routingaccelerateddhtcli } // How long per block that lasts us. - expectedProvideSpeed := reprovideInterval / time.Duration(count) + expectedProvideSpeed := reprovideInterval + if count > 0 { + expectedProvideSpeed = reprovideInterval / time.Duration(count) + } + if avgProvideSpeed > expectedProvideSpeed { logger.Errorf(` 🔔🔔🔔 YOU ARE FALLING BEHIND DHT REPROVIDES! 🔔🔔🔔 From ca1dc3a020543a1a39d1a09e632771c041eae27d Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Mon, 6 May 2024 09:06:45 +0200 Subject: [PATCH 1085/1212] gofmt --- core/node/provider.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/node/provider.go b/core/node/provider.go index da5dc98d9..7f37cd8b1 100644 --- a/core/node/provider.go +++ b/core/node/provider.go @@ -87,7 +87,7 @@ https://github.com/ipfs/kubo/blob/master/docs/config.md#routingaccelerateddhtcli if count > 0 { expectedProvideSpeed = reprovideInterval / time.Duration(count) } - + if avgProvideSpeed > expectedProvideSpeed { logger.Errorf(` 🔔🔔🔔 YOU ARE FALLING BEHIND DHT REPROVIDES! 🔔🔔🔔 From 2841ec0fcd83bc956afec9c8d9a0e8f443e2cf46 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Mon, 6 May 2024 23:19:43 +0200 Subject: [PATCH 1086/1212] fix(fuse): ipfs path parsing (#10243) --- fuse/readonly/readonly_unix.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fuse/readonly/readonly_unix.go b/fuse/readonly/readonly_unix.go index 9dca9c1a9..32be8b123 100644 --- a/fuse/readonly/readonly_unix.go +++ b/fuse/readonly/readonly_unix.go @@ -62,7 +62,7 @@ func (s *Root) Lookup(ctx context.Context, name string) (fs.Node, error) { return nil, syscall.Errno(syscall.ENOENT) } - p, err := path.NewPath(name) + p, err := path.NewPath("/ipfs/" + name) if err != nil { log.Debugf("fuse failed to parse path: %q: %s", name, err) return nil, syscall.Errno(syscall.ENOENT) From ae05085644b5f5c9f2bdae30bd332d2e28de3a7a Mon Sep 17 00:00:00 2001 From: IGP <84940636+gystemd@users.noreply.github.com> Date: Tue, 14 May 2024 13:05:35 +0200 Subject: [PATCH 1087/1212] feat: enables searching pins by name (#10412) Co-authored-by: Henrique Dias --- core/commands/pin/pin.go | 8 +++++--- core/coreapi/pin.go | 11 ++++++----- core/coreiface/options/pin.go | 8 ++++++++ docs/changelogs/v0.29.md | 5 +++++ test/cli/pins_test.go | 35 +++++++++++++++++++++++++++++++++++ 5 files changed, 59 insertions(+), 8 deletions(-) diff --git a/core/commands/pin/pin.go b/core/commands/pin/pin.go index ca3c932bf..d5620bc7a 100644 --- a/core/commands/pin/pin.go +++ b/core/commands/pin/pin.go @@ -362,6 +362,7 @@ Example: cmds.BoolOption(pinQuietOptionName, "q", "Write just hashes of objects."), cmds.BoolOption(pinStreamOptionName, "s", "Enable streaming of pins as they are discovered."), cmds.BoolOption(pinNamesOptionName, "n", "Enable displaying pin names (slower)."), + cmds.StringOption(pinNameOptionName, "Display pins with names that contain the value provided (case-sensitive, exact match)."), }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { api, err := cmdenv.GetApi(env, req) @@ -372,6 +373,7 @@ Example: typeStr, _ := req.Options[pinTypeOptionName].(string) stream, _ := req.Options[pinStreamOptionName].(bool) displayNames, _ := req.Options[pinNamesOptionName].(bool) + name, _ := req.Options[pinNameOptionName].(string) switch typeStr { case "all", "direct", "indirect", "recursive": @@ -397,7 +399,7 @@ Example: if len(req.Arguments) > 0 { err = pinLsKeys(req, typeStr, api, emit) } else { - err = pinLsAll(req, typeStr, displayNames, api, emit) + err = pinLsAll(req, typeStr, displayNames || name != "", name, api, emit) } if err != nil { return err @@ -537,7 +539,7 @@ func pinLsKeys(req *cmds.Request, typeStr string, api coreiface.CoreAPI, emit fu return nil } -func pinLsAll(req *cmds.Request, typeStr string, detailed bool, api coreiface.CoreAPI, emit func(value PinLsOutputWrapper) error) error { +func pinLsAll(req *cmds.Request, typeStr string, detailed bool, name string, api coreiface.CoreAPI, emit func(value PinLsOutputWrapper) error) error { enc, err := cmdenv.GetCidEncoder(req) if err != nil { return err @@ -555,7 +557,7 @@ func pinLsAll(req *cmds.Request, typeStr string, detailed bool, api coreiface.Co panic("unhandled pin type") } - pins, err := api.Pin().Ls(req.Context, opt, options.Pin.Ls.Detailed(detailed)) + pins, err := api.Pin().Ls(req.Context, opt, options.Pin.Ls.Detailed(detailed), options.Pin.Ls.Name(name)) if err != nil { return err } diff --git a/core/coreapi/pin.go b/core/coreapi/pin.go index 8db582a4f..22b3aa25c 100644 --- a/core/coreapi/pin.go +++ b/core/coreapi/pin.go @@ -3,6 +3,7 @@ package coreapi import ( "context" "fmt" + "strings" bserv "github.com/ipfs/boxo/blockservice" offline "github.com/ipfs/boxo/exchange/offline" @@ -67,7 +68,7 @@ func (api *PinAPI) Ls(ctx context.Context, opts ...caopts.PinLsOption) (<-chan c return nil, fmt.Errorf("invalid type '%s', must be one of {direct, indirect, recursive, all}", settings.Type) } - return api.pinLsAll(ctx, settings.Type, settings.Detailed), nil + return api.pinLsAll(ctx, settings.Type, settings.Detailed, settings.Name), nil } func (api *PinAPI) IsPinned(ctx context.Context, p path.Path, opts ...caopts.PinIsPinnedOption) (string, bool, error) { @@ -276,17 +277,17 @@ func (p *pinInfo) Err() error { // // The caller must keep reading results until the channel is closed to prevent // leaking the goroutine that is fetching pins. -func (api *PinAPI) pinLsAll(ctx context.Context, typeStr string, detailed bool) <-chan coreiface.Pin { +func (api *PinAPI) pinLsAll(ctx context.Context, typeStr string, detailed bool, name string) <-chan coreiface.Pin { out := make(chan coreiface.Pin, 1) emittedSet := cid.NewSet() - AddToResultKeys := func(c cid.Cid, name, typeStr string) error { - if emittedSet.Visit(c) { + AddToResultKeys := func(c cid.Cid, pinName, typeStr string) error { + if emittedSet.Visit(c) && (name == "" || strings.Contains(pinName, name)) { select { case out <- &pinInfo{ pinType: typeStr, - name: name, + name: pinName, path: path.FromCid(c), }: case <-ctx.Done(): diff --git a/core/coreiface/options/pin.go b/core/coreiface/options/pin.go index 0efd853ef..5b4cc9de7 100644 --- a/core/coreiface/options/pin.go +++ b/core/coreiface/options/pin.go @@ -12,6 +12,7 @@ type PinAddSettings struct { type PinLsSettings struct { Type string Detailed bool + Name string } // PinIsPinnedSettings represent the settings for PinAPI.IsPinned @@ -205,6 +206,13 @@ func (pinLsOpts) Detailed(detailed bool) PinLsOption { } } +func (pinLsOpts) Name(name string) PinLsOption { + return func(settings *PinLsSettings) error { + settings.Name = name + return nil + } +} + type pinIsPinnedOpts struct{} // All is an option for Pin.IsPinned which will make it search in all type of pins. diff --git a/docs/changelogs/v0.29.md b/docs/changelogs/v0.29.md index e51d34b5e..386e93ead 100644 --- a/docs/changelogs/v0.29.md +++ b/docs/changelogs/v0.29.md @@ -6,6 +6,7 @@ - [Overview](#overview) - [🔦 Highlights](#-highlights) + - [Add search functionality for pin names](#add-search-functionality-for-pin-names) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -13,6 +14,10 @@ ### 🔦 Highlights +#### Add search functionality for pin names + +It is now possible to search for pins by name. To do so, use `ipfs pin ls --name "SomeName"`. The search is case-sensitive and will return all pins having a name which contains the exact word provided. + ### 📝 Changelog ### 👨‍👩‍👧‍👦 Contributors diff --git a/test/cli/pins_test.go b/test/cli/pins_test.go index 415da8d3b..88da250b1 100644 --- a/test/cli/pins_test.go +++ b/test/cli/pins_test.go @@ -242,6 +242,41 @@ func TestPins(t *testing.T) { require.NotContains(t, lsOut, outADetailed) }) + t.Run("test listing pins which contains specific name", func(t *testing.T) { + t.Parallel() + + node := harness.NewT(t).NewNode().Init() + cidAStr := node.IPFSAddStr(RandomStr(1000), "--pin=false") + cidBStr := node.IPFSAddStr(RandomStr(1000), "--pin=false") + cidCStr := node.IPFSAddStr(RandomStr(1000), "--pin=false") + + outA := cidAStr + " recursive testPin" + outB := cidBStr + " recursive testPin" + outC := cidCStr + " recursive randPin" + + _ = node.IPFS("pin", "add", "--name", "testPin", cidAStr) + lsOut := pinLs(node, "-t=recursive", "--name=test") + require.Contains(t, lsOut, outA) + lsOut = pinLs(node, "-t=recursive", "--name=randomLabel") + require.NotContains(t, lsOut, outA) + + _ = node.IPFS("pin", "add", "--name", "testPin", cidBStr) + lsOut = pinLs(node, "-t=recursive", "--name=test") + require.Contains(t, lsOut, outA) + require.Contains(t, lsOut, outB) + + _ = node.IPFS("pin", "add", "--name", "randPin", cidCStr) + lsOut = pinLs(node, "-t=recursive", "--name=rand") + require.NotContains(t, lsOut, outA) + require.NotContains(t, lsOut, outB) + require.Contains(t, lsOut, outC) + + lsOut = pinLs(node, "-t=recursive", "--name=testPin") + require.Contains(t, lsOut, outA) + require.Contains(t, lsOut, outB) + require.NotContains(t, lsOut, outC) + }) + t.Run("test overwriting pin with name", func(t *testing.T) { t.Parallel() From 8022e13a6b28d58a209e3d4eaefeb102b9e840e0 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Tue, 14 May 2024 16:17:04 +0200 Subject: [PATCH 1088/1212] config: introduce Import section (#10421) Co-authored-by: Marcin Rataj --- config/config.go | 1 + config/import.go | 17 ++++++ config/profile.go | 22 ++++++++ core/commands/add.go | 33 ++++++++++- core/commands/block.go | 17 +++++- core/commands/dag/dag.go | 2 +- core/commands/dag/put.go | 15 +++++ core/commands/files.go | 19 +++++-- docs/changelogs/v0.29.md | 11 ++++ docs/config.md | 58 +++++++++++++++++++ test/cli/add_test.go | 118 +++++++++++++++++++++++++++++++++++++++ 11 files changed, 305 insertions(+), 8 deletions(-) create mode 100644 config/import.go create mode 100644 test/cli/add_test.go diff --git a/config/config.go b/config/config.go index 1951784dd..046c930be 100644 --- a/config/config.go +++ b/config/config.go @@ -36,6 +36,7 @@ type Config struct { Experimental Experiments Plugins Plugins Pinning Pinning + Import Import Internal Internal // experimental/unstable options } diff --git a/config/import.go b/config/import.go new file mode 100644 index 000000000..10af4edfa --- /dev/null +++ b/config/import.go @@ -0,0 +1,17 @@ +package config + +const ( + DefaultCidVersion = 0 + DefaultUnixFSRawLeaves = false + DefaultUnixFSChunker = "size-262144" + DefaultHashFunction = "sha2-256" +) + +// Import configures the default options for ingesting data. This affects commands +// that ingest data, such as 'ipfs add', 'ipfs dag put, 'ipfs block put', 'ipfs files write'. +type Import struct { + CidVersion OptionalInteger + UnixFSRawLeaves Flag + UnixFSChunker OptionalString + HashFunction OptionalString +} diff --git a/config/profile.go b/config/profile.go index 068498715..c73b05af2 100644 --- a/config/profile.go +++ b/config/profile.go @@ -204,6 +204,28 @@ fetching may be degraded. return nil }, }, + "legacy-cid-v0": { + Description: `Makes UnixFS import produce legacy CIDv0 with no raw leaves, sha2-256 and 256 KiB chunks.`, + + Transform: func(c *Config) error { + c.Import.CidVersion = *NewOptionalInteger(0) + c.Import.UnixFSRawLeaves = False + c.Import.UnixFSChunker = *NewOptionalString("size-262144") + c.Import.HashFunction = *NewOptionalString("sha2-256") + return nil + }, + }, + "test-cid-v1": { + Description: `Makes UnixFS import produce modern CIDv1 with raw leaves, sha2-256 and 1 MiB chunks.`, + + Transform: func(c *Config) error { + c.Import.CidVersion = *NewOptionalInteger(1) + c.Import.UnixFSRawLeaves = True + c.Import.UnixFSChunker = *NewOptionalString("size-1048576") + c.Import.HashFunction = *NewOptionalString("sha2-256") + return nil + }, + }, } func getAvailablePort() (port int, err error) { diff --git a/core/commands/add.go b/core/commands/add.go index 4e59cc867..94a5a0f51 100644 --- a/core/commands/add.go +++ b/core/commands/add.go @@ -8,6 +8,7 @@ import ( gopath "path" "strings" + "github.com/ipfs/kubo/config" "github.com/ipfs/kubo/core/commands/cmdenv" "github.com/cheggaaa/pb" @@ -155,12 +156,12 @@ See 'dag export' and 'dag import' for more information. cmds.BoolOption(trickleOptionName, "t", "Use trickle-dag format for dag generation."), cmds.BoolOption(onlyHashOptionName, "n", "Only chunk and hash - do not write to disk."), cmds.BoolOption(wrapOptionName, "w", "Wrap files with a directory object."), - cmds.StringOption(chunkerOptionName, "s", "Chunking algorithm, size-[bytes], rabin-[min]-[avg]-[max] or buzhash").WithDefault("size-262144"), + cmds.StringOption(chunkerOptionName, "s", "Chunking algorithm, size-[bytes], rabin-[min]-[avg]-[max] or buzhash"), cmds.BoolOption(rawLeavesOptionName, "Use raw blocks for leaf nodes."), cmds.BoolOption(noCopyOptionName, "Add the file using filestore. Implies raw-leaves. (experimental)"), cmds.BoolOption(fstoreCacheOptionName, "Check the filestore for pre-existing blocks. (experimental)"), cmds.IntOption(cidVersionOptionName, "CID version. Defaults to 0 unless an option that depends on CIDv1 is passed. Passing version 1 will cause the raw-leaves option to default to true."), - cmds.StringOption(hashOptionName, "Hash function to use. Implies CIDv1 if not sha2-256. (experimental)").WithDefault("sha2-256"), + cmds.StringOption(hashOptionName, "Hash function to use. Implies CIDv1 if not sha2-256. (experimental)"), cmds.BoolOption(inlineOptionName, "Inline small blocks into CIDs. (experimental)"), cmds.IntOption(inlineLimitOptionName, "Maximum block size to inline. (experimental)").WithDefault(32), cmds.BoolOption(pinOptionName, "Pin locally to protect added files from garbage collection.").WithDefault(true), @@ -191,6 +192,16 @@ See 'dag export' and 'dag import' for more information. return err } + nd, err := cmdenv.GetNode(env) + if err != nil { + return err + } + + cfg, err := nd.Repo.Config() + if err != nil { + return err + } + progress, _ := req.Options[progressOptionName].(bool) trickle, _ := req.Options[trickleOptionName].(bool) wrap, _ := req.Options[wrapOptionName].(bool) @@ -207,6 +218,24 @@ See 'dag export' and 'dag import' for more information. inlineLimit, _ := req.Options[inlineLimitOptionName].(int) toFilesStr, toFilesSet := req.Options[toFilesOptionName].(string) + if chunker == "" { + chunker = cfg.Import.UnixFSChunker.WithDefault(config.DefaultUnixFSChunker) + } + + if hashFunStr == "" { + hashFunStr = cfg.Import.HashFunction.WithDefault(config.DefaultHashFunction) + } + + if !cidVerSet && !cfg.Import.CidVersion.IsDefault() { + cidVerSet = true + cidVer = int(cfg.Import.CidVersion.WithDefault(config.DefaultCidVersion)) + } + + if !rbset && cfg.Import.UnixFSRawLeaves != config.Default { + rbset = true + rawblks = cfg.Import.UnixFSRawLeaves.WithDefault(config.DefaultUnixFSRawLeaves) + } + if onlyHash && toFilesSet { return fmt.Errorf("%s and %s options are not compatible", onlyHashOptionName, toFilesOptionName) } diff --git a/core/commands/block.go b/core/commands/block.go index 6ceb258f6..b4b0fd204 100644 --- a/core/commands/block.go +++ b/core/commands/block.go @@ -8,6 +8,7 @@ import ( "github.com/ipfs/boxo/files" + "github.com/ipfs/kubo/config" cmdenv "github.com/ipfs/kubo/core/commands/cmdenv" "github.com/ipfs/kubo/core/commands/cmdutils" @@ -153,7 +154,7 @@ only for backward compatibility when a legacy CIDv0 is required (--format=v0). }, Options: []cmds.Option{ cmds.StringOption(blockCidCodecOptionName, "Multicodec to use in returned CID").WithDefault("raw"), - cmds.StringOption(mhtypeOptionName, "Multihash hash function").WithDefault("sha2-256"), + cmds.StringOption(mhtypeOptionName, "Multihash hash function"), cmds.IntOption(mhlenOptionName, "Multihash hash length").WithDefault(-1), cmds.BoolOption(pinOptionName, "Pin added blocks recursively").WithDefault(false), cmdutils.AllowBigBlockOption, @@ -165,7 +166,21 @@ only for backward compatibility when a legacy CIDv0 is required (--format=v0). return err } + nd, err := cmdenv.GetNode(env) + if err != nil { + return err + } + + cfg, err := nd.Repo.Config() + if err != nil { + return err + } + mhtype, _ := req.Options[mhtypeOptionName].(string) + if mhtype == "" { + mhtype = cfg.Import.HashFunction.WithDefault(config.DefaultHashFunction) + } + mhtval, ok := mh.Names[mhtype] if !ok { return fmt.Errorf("unrecognized multihash function: %s", mhtype) diff --git a/core/commands/dag/dag.go b/core/commands/dag/dag.go index 56aae4105..ce5edb641 100644 --- a/core/commands/dag/dag.go +++ b/core/commands/dag/dag.go @@ -87,7 +87,7 @@ into an object of the specified format. cmds.StringOption("store-codec", "Codec that the stored object will be encoded with").WithDefault("dag-cbor"), cmds.StringOption("input-codec", "Codec that the input object is encoded in").WithDefault("dag-json"), cmds.BoolOption("pin", "Pin this object when adding."), - cmds.StringOption("hash", "Hash function to use").WithDefault("sha2-256"), + cmds.StringOption("hash", "Hash function to use"), cmdutils.AllowBigBlockOption, }, Run: dagPut, diff --git a/core/commands/dag/put.go b/core/commands/dag/put.go index c9c0b455b..fb719916c 100644 --- a/core/commands/dag/put.go +++ b/core/commands/dag/put.go @@ -7,6 +7,7 @@ import ( blocks "github.com/ipfs/go-block-format" "github.com/ipfs/go-cid" ipldlegacy "github.com/ipfs/go-ipld-legacy" + "github.com/ipfs/kubo/config" "github.com/ipfs/kubo/core/commands/cmdenv" "github.com/ipfs/kubo/core/commands/cmdutils" "github.com/ipld/go-ipld-prime/multicodec" @@ -32,11 +33,25 @@ func dagPut(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) e return err } + nd, err := cmdenv.GetNode(env) + if err != nil { + return err + } + + cfg, err := nd.Repo.Config() + if err != nil { + return err + } + inputCodec, _ := req.Options["input-codec"].(string) storeCodec, _ := req.Options["store-codec"].(string) hash, _ := req.Options["hash"].(string) dopin, _ := req.Options["pin"].(bool) + if hash == "" { + hash = cfg.Import.HashFunction.WithDefault(config.DefaultHashFunction) + } + var icodec mc.Code if err := icodec.Set(inputCodec); err != nil { return err diff --git a/core/commands/files.go b/core/commands/files.go index 9a7ee639a..12891a730 100644 --- a/core/commands/files.go +++ b/core/commands/files.go @@ -11,6 +11,7 @@ import ( "strings" humanize "github.com/dustin/go-humanize" + "github.com/ipfs/kubo/config" "github.com/ipfs/kubo/core" "github.com/ipfs/kubo/core/commands/cmdenv" @@ -802,18 +803,28 @@ See '--to-files' in 'ipfs add --help' for more information. return err } + nd, err := cmdenv.GetNode(env) + if err != nil { + return err + } + + cfg, err := nd.Repo.Config() + if err != nil { + return err + } + create, _ := req.Options[filesCreateOptionName].(bool) mkParents, _ := req.Options[filesParentsOptionName].(bool) trunc, _ := req.Options[filesTruncateOptionName].(bool) flush, _ := req.Options[filesFlushOptionName].(bool) rawLeaves, rawLeavesDef := req.Options[filesRawLeavesOptionName].(bool) - prefix, err := getPrefixNew(req) - if err != nil { - return err + if !rawLeavesDef && cfg.Import.UnixFSRawLeaves != config.Default { + rawLeavesDef = true + rawLeaves = cfg.Import.UnixFSRawLeaves.WithDefault(config.DefaultUnixFSRawLeaves) } - nd, err := cmdenv.GetNode(env) + prefix, err := getPrefixNew(req) if err != nil { return err } diff --git a/docs/changelogs/v0.29.md b/docs/changelogs/v0.29.md index 386e93ead..632c47b15 100644 --- a/docs/changelogs/v0.29.md +++ b/docs/changelogs/v0.29.md @@ -7,6 +7,7 @@ - [Overview](#overview) - [🔦 Highlights](#-highlights) - [Add search functionality for pin names](#add-search-functionality-for-pin-names) + - [Customizing `ipfs add` defaults](#customizing-ipfs-add-defaults) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -18,6 +19,16 @@ It is now possible to search for pins by name. To do so, use `ipfs pin ls --name "SomeName"`. The search is case-sensitive and will return all pins having a name which contains the exact word provided. +#### Customizing `ipfs add` defaults + +This release supports overriding global data ingestion defaults used by commands like `ipfs add` via user-defined [`Import.*` configuration options](../config.md#import). +The hash function, CID version, or UnixFS raw leaves and chunker behaviors can be set once, and used as the new implicit default for `ipfs add`. + +> [!TIP] +> As a convenience, two CID [profiles](../config.md#profile) are provided: `legacy-cid-v0` and `test-cid-v1`. +> A test profile that defaults to modern CIDv1 can be applied via `ipfs config profile apply test-cid-v1`. +> We encourage users to try it and report any issues. + ### 📝 Changelog ### 👨‍👩‍👧‍👦 Contributors diff --git a/docs/config.md b/docs/config.md index e36ffebb7..130f724d5 100644 --- a/docs/config.md +++ b/docs/config.md @@ -175,6 +175,11 @@ config file at runtime. - [`DNS`](#dns) - [`DNS.Resolvers`](#dnsresolvers) - [`DNS.MaxCacheTTL`](#dnsmaxcachettl) + - [`Import`](#import) + - [`Import.CidVersion`](#importcidversion) + - [`Import.UnixFSRawLeaves`](#importunixfsrawleaves) + - [`Import.UnixFSChunker`](#importunixfschunker) + - [`Import.HashFunction`](#importhashfunction) ## Profiles @@ -265,6 +270,21 @@ documented in `ipfs config profile --help`. Use this profile with caution. +- `legacy-cid-v0` + + Makes UnixFS import (`ipfs add`) produce legacy CIDv0 with no raw leaves, sha2-256 and 256 KiB chunks. + + > [!WARNING] + > This profile is provided for legacy users and should not be used for new projects. + +- `test-cid-v1` + + Makes UnixFS import (`ipfs add`) produce modern CIDv1 with raw leaves, sha2-256 and 1 MiB chunks. + + > [!NOTE] + > This profile will become the new implicit default, provided for testing purposes. + > Follow [kubo#4143](https://github.com/ipfs/kubo/issues/4143) for more details. + ## Types This document refers to the standard JSON types (e.g., `null`, `string`, @@ -2377,3 +2397,41 @@ Note: this does NOT work with Go's default DNS resolver. To make this a global s Default: Respect DNS Response TTL Type: `optionalDuration` + +## `Import` + +Options to configure the default options used for ingesting data, in commands such as `ipfs add` or `ipfs block put`. All affected commands are detailed per option. + +Note that using flags will override the options defined here. + +### `Import.CidVersion` + +The default CID version. Commands affected: `ipfs add`. + +Default: `0` + +Type: `optionalInteger` + +### `Import.UnixFSRawLeaves` + +The default UnixFS raw leaves option. Commands affected: `ipfs add`, `ipfs files write`. + +Default: `false` if `CidVersion=0`; `true` if `CidVersion=1` + +Type: `flag` + +### `Import.UnixFSChunker` + +The default UnixFS chunker. Commands affected: `ipfs add`. + +Default: `size-262144` + +Type: `optionalString` + +### `Import.HashFunction` + +The default hash function. Commands affected: `ipfs add`, `ipfs block put`, `ipfs dag put`. + +Default: `sha2-256` + +Type: `optionalString` diff --git a/test/cli/add_test.go b/test/cli/add_test.go new file mode 100644 index 000000000..ae652989a --- /dev/null +++ b/test/cli/add_test.go @@ -0,0 +1,118 @@ +package cli + +import ( + "testing" + + "github.com/ipfs/kubo/config" + "github.com/ipfs/kubo/test/cli/harness" + "github.com/stretchr/testify/require" +) + +func TestAdd(t *testing.T) { + t.Parallel() + + var ( + shortString = "hello world" + shortStringCidV0 = "Qmf412jQZiuVUtdgnB36FXFX7xg5V6KEbSJ4dpQuhkLyfD" // cidv0 - dag-pb - sha2-256 + shortStringCidV1 = "bafkreifzjut3te2nhyekklss27nh3k72ysco7y32koao5eei66wof36n5e" // cidv1 - raw - sha2-256 + shortStringCidV1NoRawLeaves = "bafybeihykld7uyxzogax6vgyvag42y7464eywpf55gxi5qpoisibh3c5wa" // cidv1 - dag-pb - sha2-256 + shortStringCidV1Sha512 = "bafkrgqbqt3gerhas23vuzrapkdeqf4vu2dwxp3srdj6hvg6nhsug2tgyn6mj3u23yx7utftq3i2ckw2fwdh5qmhid5qf3t35yvkc5e5ottlw6" + ) + + t.Run("produced cid version: implicit default (CIDv0)", func(t *testing.T) { + t.Parallel() + node := harness.NewT(t).NewNode().Init().StartDaemon() + defer node.StopDaemon() + + cidStr := node.IPFSAddStr(shortString) + require.Equal(t, shortStringCidV0, cidStr) + }) + + t.Run("produced cid version: follows user-set configuration Import.CidVersion=0", func(t *testing.T) { + t.Parallel() + node := harness.NewT(t).NewNode().Init() + node.UpdateConfig(func(cfg *config.Config) { + cfg.Import.CidVersion = *config.NewOptionalInteger(0) + }) + node.StartDaemon() + defer node.StopDaemon() + + cidStr := node.IPFSAddStr(shortString) + require.Equal(t, shortStringCidV0, cidStr) + }) + + t.Run("produced cid multihash: follows user-set configuration in Import.HashFunction", func(t *testing.T) { + t.Parallel() + node := harness.NewT(t).NewNode().Init() + node.UpdateConfig(func(cfg *config.Config) { + cfg.Import.HashFunction = *config.NewOptionalString("sha2-512") + }) + node.StartDaemon() + defer node.StopDaemon() + + cidStr := node.IPFSAddStr(shortString) + require.Equal(t, shortStringCidV1Sha512, cidStr) + }) + + t.Run("produced cid version: follows user-set configuration Import.CidVersion=1", func(t *testing.T) { + t.Parallel() + node := harness.NewT(t).NewNode().Init() + node.UpdateConfig(func(cfg *config.Config) { + cfg.Import.CidVersion = *config.NewOptionalInteger(1) + }) + node.StartDaemon() + defer node.StopDaemon() + + cidStr := node.IPFSAddStr(shortString) + require.Equal(t, shortStringCidV1, cidStr) + }) + + t.Run("produced cid version: command flag overrides configuration in Import.CidVersion", func(t *testing.T) { + t.Parallel() + node := harness.NewT(t).NewNode().Init() + node.UpdateConfig(func(cfg *config.Config) { + cfg.Import.CidVersion = *config.NewOptionalInteger(1) + }) + node.StartDaemon() + defer node.StopDaemon() + + cidStr := node.IPFSAddStr(shortString, "--cid-version", "0") + require.Equal(t, shortStringCidV0, cidStr) + }) + + t.Run("produced unixfs raw leaves: follows user-set configuration Import.UnixFSRawLeaves", func(t *testing.T) { + t.Parallel() + node := harness.NewT(t).NewNode().Init() + node.UpdateConfig(func(cfg *config.Config) { + // CIDv1 defaults to raw-leaves=true + cfg.Import.CidVersion = *config.NewOptionalInteger(1) + // disable manually + cfg.Import.UnixFSRawLeaves = config.False + }) + node.StartDaemon() + defer node.StopDaemon() + + cidStr := node.IPFSAddStr(shortString) + require.Equal(t, shortStringCidV1NoRawLeaves, cidStr) + }) + + t.Run("ipfs init --profile=legacy-cid-v0 sets config that produces legacy CIDv0", func(t *testing.T) { + t.Parallel() + node := harness.NewT(t).NewNode().Init("--profile=legacy-cid-v0") + node.StartDaemon() + defer node.StopDaemon() + + cidStr := node.IPFSAddStr(shortString) + require.Equal(t, shortStringCidV0, cidStr) + }) + + t.Run("ipfs init --profile=test-cid-v1 produces modern CIDv1", func(t *testing.T) { + t.Parallel() + node := harness.NewT(t).NewNode().Init("--profile=test-cid-v1") + node.StartDaemon() + defer node.StopDaemon() + + cidStr := node.IPFSAddStr(shortString) + require.Equal(t, shortStringCidV1, cidStr) + }) +} From bde3a42940fde958671e9067e5ee2c88ffe96afd Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Tue, 14 May 2024 16:20:00 +0200 Subject: [PATCH 1089/1212] chore: fix --help text https://github.com/ipfs/kubo/pull/10412 changed to be partial match but we forgot to update --help text --- core/commands/pin/pin.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/commands/pin/pin.go b/core/commands/pin/pin.go index d5620bc7a..b27b1e2bf 100644 --- a/core/commands/pin/pin.go +++ b/core/commands/pin/pin.go @@ -362,7 +362,7 @@ Example: cmds.BoolOption(pinQuietOptionName, "q", "Write just hashes of objects."), cmds.BoolOption(pinStreamOptionName, "s", "Enable streaming of pins as they are discovered."), cmds.BoolOption(pinNamesOptionName, "n", "Enable displaying pin names (slower)."), - cmds.StringOption(pinNameOptionName, "Display pins with names that contain the value provided (case-sensitive, exact match)."), + cmds.StringOption(pinNameOptionName, "Display pins with names that contain the value provided (case-sensitive, partial match)."), }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { api, err := cmdenv.GetApi(env, req) From 869f50632798ffa0fb9ba81ed2ce4001ddc4ff70 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Thu, 16 May 2024 11:10:05 +0200 Subject: [PATCH 1090/1212] chore: update dependencies (#10423) --- docs/examples/kubo-as-a-library/go.mod | 64 +++++------ docs/examples/kubo-as-a-library/go.sum | 133 ++++++++++++----------- go.mod | 68 ++++++------ go.sum | 140 ++++++++++++------------- test/dependencies/go.mod | 34 +++--- test/dependencies/go.sum | 79 +++++++------- 6 files changed, 259 insertions(+), 259 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 7f43fcd56..0d60a029a 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -9,7 +9,7 @@ toolchain go1.22.0 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.19.1-0.20240415103851-7f9506844904 + github.com/ipfs/boxo v0.19.1-0.20240516085407-f4fe8997dcbe github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.33.2 github.com/multiformats/go-multiaddr v0.12.3 @@ -48,16 +48,16 @@ require ( github.com/gabriel-vasile/mimetype v1.4.3 // indirect github.com/go-logr/logr v1.4.1 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect + github.com/go-task/slim-sprig/v3 v3.0.0 // indirect github.com/godbus/dbus/v5 v5.1.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/gopacket v1.1.19 // indirect - github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd // indirect + github.com/google/pprof v0.0.0-20240509144519-723abb6459b7 // indirect github.com/google/uuid v1.6.0 // indirect github.com/gorilla/websocket v1.5.1 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/golang-lru v1.0.2 // indirect @@ -125,7 +125,7 @@ require ( github.com/libp2p/zeroconf/v2 v2.2.0 // indirect github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/miekg/dns v1.1.58 // indirect + github.com/miekg/dns v1.1.59 // indirect github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect github.com/minio/sha256-simd v1.0.1 // indirect @@ -140,10 +140,10 @@ require ( github.com/multiformats/go-multihash v0.2.3 // indirect github.com/multiformats/go-multistream v0.5.0 // indirect github.com/multiformats/go-varint v0.0.7 // indirect - github.com/onsi/ginkgo/v2 v2.17.1 // indirect + github.com/onsi/ginkgo/v2 v2.17.3 // indirect github.com/opencontainers/runtime-spec v1.2.0 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect - github.com/openzipkin/zipkin-go v0.4.2 // indirect + github.com/openzipkin/zipkin-go v0.4.3 // indirect github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 // indirect github.com/pion/datachannel v1.5.5 // indirect @@ -165,10 +165,10 @@ require ( github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/polydawn/refmt v0.89.0 // indirect - github.com/prometheus/client_golang v1.19.0 // indirect + github.com/prometheus/client_golang v1.19.1 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.52.3 // indirect - github.com/prometheus/procfs v0.13.0 // indirect + github.com/prometheus/common v0.53.0 // indirect + github.com/prometheus/procfs v0.15.0 // indirect github.com/quic-go/qpack v0.4.0 // indirect github.com/quic-go/quic-go v0.42.0 // indirect github.com/quic-go/webtransport-go v0.7.0 // indirect @@ -180,21 +180,21 @@ require ( github.com/ucarion/urlpath v0.0.0-20200424170820-7ccc79b76bbb // indirect github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc // indirect github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11 // indirect - github.com/whyrusleeping/cbor-gen v0.1.0 // indirect + github.com/whyrusleeping/cbor-gen v0.1.1 // indirect github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f // indirect github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 // indirect go.opencensus.io v0.24.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.50.0 // indirect - go.opentelemetry.io/otel v1.25.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.25.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.25.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.25.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.25.0 // indirect - go.opentelemetry.io/otel/exporters/zipkin v1.25.0 // indirect - go.opentelemetry.io/otel/metric v1.25.0 // indirect - go.opentelemetry.io/otel/sdk v1.25.0 // indirect - go.opentelemetry.io/otel/trace v1.25.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.51.0 // indirect + go.opentelemetry.io/otel v1.26.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.26.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.26.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.26.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.26.0 // indirect + go.opentelemetry.io/otel/exporters/zipkin v1.26.0 // indirect + go.opentelemetry.io/otel/metric v1.26.0 // indirect + go.opentelemetry.io/otel/sdk v1.26.0 // indirect + go.opentelemetry.io/otel/trace v1.26.0 // indirect go.opentelemetry.io/proto/otlp v1.2.0 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/dig v1.17.1 // indirect @@ -203,21 +203,21 @@ require ( go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect go4.org v0.0.0-20230225012048-214862532bf5 // indirect - golang.org/x/crypto v0.22.0 // indirect - golang.org/x/exp v0.0.0-20240409090435-93d18d7e34b8 // indirect + golang.org/x/crypto v0.23.0 // indirect + golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect golang.org/x/mod v0.17.0 // indirect - golang.org/x/net v0.24.0 // indirect + golang.org/x/net v0.25.0 // indirect golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.19.0 // indirect - golang.org/x/text v0.14.0 // indirect - golang.org/x/tools v0.20.0 // indirect + golang.org/x/sys v0.20.0 // indirect + golang.org/x/text v0.15.0 // indirect + golang.org/x/tools v0.21.0 // indirect golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect gonum.org/v1/gonum v0.15.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240412170617-26222e5d3d56 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240412170617-26222e5d3d56 // indirect - google.golang.org/grpc v1.63.2 // indirect - google.golang.org/protobuf v1.33.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240515191416-fc5f0ca64291 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240515191416-fc5f0ca64291 // indirect + google.golang.org/grpc v1.64.0 // indirect + google.golang.org/protobuf v1.34.1 // indirect gopkg.in/square/go-jose.v2 v2.5.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - lukechampine.com/blake3 v1.2.2 // indirect + lukechampine.com/blake3 v1.3.0 // indirect ) diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index f3644a0f5..116f7fc51 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -155,8 +155,8 @@ github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ4 github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= -github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= -github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= +github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= +github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0= github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= @@ -220,8 +220,8 @@ github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXi github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd h1:gbpYu9NMq8jhDVbvlGkMFWCjLFlqqEZjEmObmhUy6Vo= -github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= +github.com/google/pprof v0.0.0-20240509144519-723abb6459b7 h1:velgFPYr1X9TDwLIfkV7fWqsFlf7TeP11M/7kPd/dVI= +github.com/google/pprof v0.0.0-20240509144519-723abb6459b7/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -241,8 +241,8 @@ github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/ github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1 h1:/c3QmbOGMGTOumP2iT/rCwB7b0QDGLKzqOmktBjT+Is= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1/go.mod h1:5SN9VR2LTsRFsrEC6FHgRbTWrTHu6tqPeKxEQv15giM= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k= github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -268,8 +268,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.19.1-0.20240415103851-7f9506844904 h1:HqjqN6oADXh1UNw8xKnBP50B3ZQDC/RStiBFPp6W+9Y= -github.com/ipfs/boxo v0.19.1-0.20240415103851-7f9506844904/go.mod h1:hA9Ou/YnfMZOG2nQhngsbBiYt6fiJ1EhWSmccZfV+M0= +github.com/ipfs/boxo v0.19.1-0.20240516085407-f4fe8997dcbe h1:GoWqF8evx/xOnjVQEFT6FgMKVZBcqPCGeqY3h2m9r7A= +github.com/ipfs/boxo v0.19.1-0.20240516085407-f4fe8997dcbe/go.mod h1:7pXWoypZuknFVLqeLy7UraFV4NYBA0ufGBzVHcTZ188= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= @@ -487,8 +487,8 @@ github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyex github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= -github.com/miekg/dns v1.1.58 h1:ca2Hdkz+cDg/7eNF6V56jjzuZ4aCAE+DbVkILdQWG/4= -github.com/miekg/dns v1.1.58/go.mod h1:Ypv+3b/KadlvW9vJfXOTf300O4UqaHFzFCuHz+rPkBY= +github.com/miekg/dns v1.1.59 h1:C9EXc/UToRwKLhK5wKU/I4QVsBUc8kE6MkHBkeypWZs= +github.com/miekg/dns v1.1.59/go.mod h1:nZpewl5p6IvctfgrckopVx2OlSEHPRO/U4SYkRklrEk= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c h1:bzE/A84HN25pxAuk9Eej1Kz9OUelF97nAc82bDquQI8= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c/go.mod h1:0SQS9kMwD2VsyFEB++InYyBJroV/FRmBgcydeSUcJms= github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= @@ -564,14 +564,14 @@ github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9k github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.17.1 h1:V++EzdbhI4ZV4ev0UTIj0PzhzOcReJFyJaLjtSF55M8= -github.com/onsi/ginkgo/v2 v2.17.1/go.mod h1:llBI3WDLL9Z6taip6f33H76YcWtJv+7R3HigUjbIBOs= +github.com/onsi/ginkgo/v2 v2.17.3 h1:oJcvKpIb7/8uLpDDtnQuf18xVnwKp8DTD7DQ6gTd/MU= +github.com/onsi/ginkgo/v2 v2.17.3/go.mod h1:nP2DPOQoNsQmsVyv5rDA8JkXQoCs6goXIvr/PRJ1eCc= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= -github.com/onsi/gomega v1.30.0 h1:hvMK7xYz4D3HapigLTeGdId/NcfQx1VHMJc60ew99+8= -github.com/onsi/gomega v1.30.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= +github.com/onsi/gomega v1.33.0 h1:snPCflnZrpMsy94p4lXVEkHo12lmPnc3vY5XBbreexE= +github.com/onsi/gomega v1.33.0/go.mod h1:+925n5YtiFsLzzafLUHzVMBpvvRAzrydIBiSIxjX3wY= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.2.0 h1:z97+pHb3uELt/yiAWD691HNHQIF07bE7dzrbT927iTk= github.com/opencontainers/runtime-spec v1.2.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= @@ -580,8 +580,8 @@ github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFSt github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= -github.com/openzipkin/zipkin-go v0.4.2 h1:zjqfqHjUpPmB3c1GlCvvgsM1G4LkvqQbBDueDOCg/jA= -github.com/openzipkin/zipkin-go v0.4.2/go.mod h1:ZeVkFjuuBiSy13y8vpSDCjMi9GoI3hPpCJSBx/EYFhY= +github.com/openzipkin/zipkin-go v0.4.3 h1:9EGwpqkgnwdEIJ+Od7QVSEIH+ocmm5nPat0G7sjsSdg= +github.com/openzipkin/zipkin-go v0.4.3/go.mod h1:M9wCJZFWCo2RiY+o1eBCEMe0Dp2S5LDHcMZmk3RmK7c= 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/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= @@ -643,18 +643,18 @@ github.com/polydawn/refmt v0.0.0-20201211092308-30ac6d18308e/go.mod h1:uIp+gprXx github.com/polydawn/refmt v0.89.0 h1:ADJTApkvkeBZsN0tBTx8QjpD9JkmxbKp0cxfr9qszm4= github.com/polydawn/refmt v0.89.0/go.mod h1:/zvteZs/GwLtCgZ4BL6CBsk9IKIlexP43ObX9AxTqTw= github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v1.19.0 h1:ygXvpU1AoN1MhdzckN+PyD9QJOSD4x7kmXYlnfbA6JU= -github.com/prometheus/client_golang v1.19.0/go.mod h1:ZRM9uEAypZakd+q/x7+gmsvXdURP+DABIEIjnmDdp+k= +github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE= +github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.52.3 h1:5f8uj6ZwHSscOGNdIQg6OiZv/ybiK2CO2q2drVZAQSA= -github.com/prometheus/common v0.52.3/go.mod h1:BrxBKv3FWBIGXw89Mg1AeBq7FSyRzXWI3l3e7W3RN5U= +github.com/prometheus/common v0.53.0 h1:U2pL9w9nmJwJDa4qqLQ3ZaePJ6ZTwt7cMD3AG3+aLCE= +github.com/prometheus/common v0.53.0/go.mod h1:BrxBKv3FWBIGXw89Mg1AeBq7FSyRzXWI3l3e7W3RN5U= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.13.0 h1:GqzLlQyfsPbaEHaQkO7tbDlriv/4o5Hudv6OXHGKX7o= -github.com/prometheus/procfs v0.13.0/go.mod h1:cd4PFCR54QLnGKPaKGA6l+cfuNXtht43ZKY6tow0Y1g= +github.com/prometheus/procfs v0.15.0 h1:A82kmvXJq2jTu5YUhSGNlYoxh85zLnKgPz4bMZgI5Ek= +github.com/prometheus/procfs v0.15.0/go.mod h1:Y0RJ/Y5g5wJpkTisOtqwDSo4HwhGmLB4VQSw2sQJLHk= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= github.com/quic-go/quic-go v0.42.0 h1:uSfdap0eveIl8KXnipv9K7nlwZ5IqLlYOpJ58u5utpM= @@ -729,7 +729,6 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= @@ -765,8 +764,8 @@ github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc h1:BCPnHtcboa github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc/go.mod h1:r45hJU7yEoA81k6MWNhpMj/kms0n14dkzkxYHoB96UM= github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11 h1:5HZfQkwe0mIfyDmc1Em5GqlNRzcdtlv4HTNmdpt7XH0= github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11/go.mod h1:Wlo/SzPmxVp6vXpGt/zaXhHH0fn4IxgqZc82aKg6bpQ= -github.com/whyrusleeping/cbor-gen v0.1.0 h1:Jneeq3V5enErVcuL0NKEbD1Gi+iOvEeFhXOV1S1Fc6g= -github.com/whyrusleeping/cbor-gen v0.1.0/go.mod h1:pM99HXyEbSQHcosHc0iW7YFmwnscr+t9Te4ibko05so= +github.com/whyrusleeping/cbor-gen v0.1.1 h1:eKfcJIoxivjMtwfCfmJAqSF56MHcWqyIScXwaC1VBgw= +github.com/whyrusleeping/cbor-gen v0.1.1/go.mod h1:pM99HXyEbSQHcosHc0iW7YFmwnscr+t9Te4ibko05so= github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f h1:jQa4QT2UP9WYv2nzyawpKMOCl+Z/jW7djv2/J50lj9E= github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f/go.mod h1:p9UJB6dDgdPgMJZs7UjUOdulKyRr9fqkS+6JKAInPy8= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 h1:EKhdznlJHPMoKr0XTrX+IlJs1LH3lyx2nfr1dOlZ79k= @@ -788,26 +787,26 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.50.0 h1:cEPbyTSEHlQR89XVlyo78gqluF8Y3oMeBkXGWzQsfXY= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.50.0/go.mod h1:DKdbWcT4GH1D0Y3Sqt/PFXt2naRKDWtU+eE6oLdFNA8= -go.opentelemetry.io/otel v1.25.0 h1:gldB5FfhRl7OJQbUHt/8s0a7cE8fbsPAtdpRaApKy4k= -go.opentelemetry.io/otel v1.25.0/go.mod h1:Wa2ds5NOXEMkCmUou1WA7ZBfLTHWIsp034OVD7AO+Vg= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.25.0 h1:dT33yIHtmsqpixFsSQPwNeY5drM9wTcoL8h0FWF4oGM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.25.0/go.mod h1:h95q0LBGh7hlAC08X2DhSeyIG02YQ0UyioTCVAqRPmc= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.25.0 h1:vOL89uRfOCCNIjkisd0r7SEdJF3ZJFyCNY34fdZs8eU= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.25.0/go.mod h1:8GlBGcDk8KKi7n+2S4BT/CPZQYH3erLu0/k64r1MYgo= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.25.0 h1:Mbi5PKN7u322woPa85d7ebZ+SOvEoPvoiBu+ryHWgfA= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.25.0/go.mod h1:e7ciERRhZaOZXVjx5MiL8TK5+Xv7G5Gv5PA2ZDEJdL8= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.25.0 h1:0vZZdECYzhTt9MKQZ5qQ0V+J3MFu4MQaQ3COfugF+FQ= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.25.0/go.mod h1:e7iXx3HjaSSBXfy9ykVUlupS2Vp7LBIBuT21ousM2Hk= -go.opentelemetry.io/otel/exporters/zipkin v1.25.0 h1:iLzdsOsstvim/54ymA2BhEN4+1NbsvwGvOhSkQy2TaY= -go.opentelemetry.io/otel/exporters/zipkin v1.25.0/go.mod h1:3QXxNo6ace1QZX6pSHEzGKKESVdjQxXR03FcIH7dNGs= -go.opentelemetry.io/otel/metric v1.25.0 h1:LUKbS7ArpFL/I2jJHdJcqMGxkRdxpPHE0VU/D4NuEwA= -go.opentelemetry.io/otel/metric v1.25.0/go.mod h1:rkDLUSd2lC5lq2dFNrX9LGAbINP5B7WBkC78RXCpH5s= -go.opentelemetry.io/otel/sdk v1.25.0 h1:PDryEJPC8YJZQSyLY5eqLeafHtG+X7FWnf3aXMtxbqo= -go.opentelemetry.io/otel/sdk v1.25.0/go.mod h1:oFgzCM2zdsxKzz6zwpTZYLLQsFwc+K0daArPdIhuxkw= -go.opentelemetry.io/otel/trace v1.25.0 h1:tqukZGLwQYRIFtSQM2u2+yfMVTgGVeqRLPUYx1Dq6RM= -go.opentelemetry.io/otel/trace v1.25.0/go.mod h1:hCCs70XM/ljO+BeQkyFnbK28SBIJ/Emuha+ccrCRT7I= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.51.0 h1:Xs2Ncz0gNihqu9iosIZ5SkBbWo5T8JhhLJFMQL1qmLI= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.51.0/go.mod h1:vy+2G/6NvVMpwGX/NyLqcC41fxepnuKHk16E6IZUcJc= +go.opentelemetry.io/otel v1.26.0 h1:LQwgL5s/1W7YiiRwxf03QGnWLb2HW4pLiAhaA5cZXBs= +go.opentelemetry.io/otel v1.26.0/go.mod h1:UmLkJHUAidDval2EICqBMbnAd0/m2vmpf/dAM+fvFs4= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.26.0 h1:1u/AyyOqAWzy+SkPxDpahCNZParHV8Vid1RnI2clyDE= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.26.0/go.mod h1:z46paqbJ9l7c9fIPCXTqTGwhQZ5XoTIsfeFYWboizjs= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.26.0 h1:Waw9Wfpo/IXzOI8bCB7DIk+0JZcqqsyn1JFnAc+iam8= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.26.0/go.mod h1:wnJIG4fOqyynOnnQF/eQb4/16VlX2EJAHhHgqIqWfAo= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.26.0 h1:1wp/gyxsuYtuE/JFxsQRtcCDtMrO2qMvlfXALU5wkzI= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.26.0/go.mod h1:gbTHmghkGgqxMomVQQMur1Nba4M0MQ8AYThXDUjsJ38= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.26.0 h1:0W5o9SzoR15ocYHEQfvfipzcNog1lBxOLfnex91Hk6s= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.26.0/go.mod h1:zVZ8nz+VSggWmnh6tTsJqXQ7rU4xLwRtna1M4x5jq58= +go.opentelemetry.io/otel/exporters/zipkin v1.26.0 h1:sBk6A62GgcQRwcxcBwRMPkqeuSizcpHkXyZNyP281Fw= +go.opentelemetry.io/otel/exporters/zipkin v1.26.0/go.mod h1:fLzYtPUxPFzu7rSqhYsCxYheT2dNoPjtKovCLzLm07w= +go.opentelemetry.io/otel/metric v1.26.0 h1:7S39CLuY5Jgg9CrnA9HHiEjGMF/X2VHvoXGgSllRz30= +go.opentelemetry.io/otel/metric v1.26.0/go.mod h1:SY+rHOI4cEawI9a7N1A4nIg/nTQXe1ccCNWYOJUrpX4= +go.opentelemetry.io/otel/sdk v1.26.0 h1:Y7bumHf5tAiDlRYFmGqetNcLaVUZmh4iYfmGxtmz7F8= +go.opentelemetry.io/otel/sdk v1.26.0/go.mod h1:0p8MXpqLeJ0pzcszQQN4F0S5FVjBLgypeGSngLsmirs= +go.opentelemetry.io/otel/trace v1.26.0 h1:1ieeAUb4y0TE26jUFrCIXKpTuVK7uJGN9/Z/2LP5sQA= +go.opentelemetry.io/otel/trace v1.26.0/go.mod h1:4iDxvGDQuUkHve82hJJ8UqrwswHYsZuWCBllGV2U2y0= go.opentelemetry.io/proto/otlp v1.2.0 h1:pVeZGk7nXDC9O2hncA6nHldxEjm6LByfA2aN8IOkz94= go.opentelemetry.io/proto/otlp v1.2.0/go.mod h1:gGpR8txAl5M03pDhMC79G6SdqNV26naRm/KDsgaHD8A= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= @@ -862,8 +861,8 @@ golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45 golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= -golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= -golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= +golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= +golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -872,8 +871,8 @@ golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20240409090435-93d18d7e34b8 h1:ESSUROHIBHg7USnszlcdmjBEwdMj9VUvU+OPk4yl2mc= -golang.org/x/exp v0.0.0-20240409090435-93d18d7e34b8/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI= +golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM= +golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -938,8 +937,8 @@ golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ= golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= -golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= -golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= +golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= +golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1017,8 +1016,8 @@ golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= -golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -1044,8 +1043,8 @@ golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= +golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1089,8 +1088,8 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY= -golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg= +golang.org/x/tools v0.21.0 h1:qc0xYgIbsSDt9EyWz05J5wfa7LOVW0YTLOXrqdLAWIw= +golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1135,10 +1134,10 @@ google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvx google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto/googleapis/api v0.0.0-20240412170617-26222e5d3d56 h1:KuFzeG+qPmpT8KpJXcrKAyeHhn64dgEICWlccP9qp0U= -google.golang.org/genproto/googleapis/api v0.0.0-20240412170617-26222e5d3d56/go.mod h1:wTHjrkbcS8AoQbb/0v9bFIPItZQPAsyVfgG9YPUhjAM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240412170617-26222e5d3d56 h1:zviK8GX4VlMstrK3JkexM5UHjH1VOkRebH9y3jhSBGk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240412170617-26222e5d3d56/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= +google.golang.org/genproto/googleapis/api v0.0.0-20240515191416-fc5f0ca64291 h1:4HZJ3Xv1cmrJ+0aFo304Zn79ur1HMxptAE7aCPNLSqc= +google.golang.org/genproto/googleapis/api v0.0.0-20240515191416-fc5f0ca64291/go.mod h1:RGnPtTG7r4i8sPlNyDeikXF99hMM+hN6QMm4ooG9g2g= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240515191416-fc5f0ca64291 h1:AgADTJarZTBqgjiUzRgfaBchgYB3/WFTC80GPwsMcRI= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240515191416-fc5f0ca64291/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= @@ -1151,8 +1150,8 @@ google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8 google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.63.2 h1:MUeiw1B2maTVZthpU5xvASfTh3LDbxHd6IJ6QQVU+xM= -google.golang.org/grpc v1.63.2/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA= +google.golang.org/grpc v1.64.0 h1:KH3VH9y/MgNQg1dE7b3XfVK0GsPSIzJwdF617gUSbvY= +google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -1164,8 +1163,8 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= -google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= +google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -1199,8 +1198,8 @@ honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= lukechampine.com/blake3 v1.1.6/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= -lukechampine.com/blake3 v1.2.2 h1:wEAbSg0IVU4ih44CVlpMqMZMpzr5hf/6aqodLlevd/w= -lukechampine.com/blake3 v1.2.2/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= +lukechampine.com/blake3 v1.3.0 h1:sJ3XhFINmHSrYCgl958hscfIa3bw8x4DqMP3u1YvoYE= +lukechampine.com/blake3 v1.3.0/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= pgregory.net/rapid v0.4.7 h1:MTNRktPuv5FNqOO151TM9mDTa+XHcX6ypYeISDVD14g= pgregory.net/rapid v0.4.7/go.mod h1:UYpPVyjFHzYBGHIxLFoupi8vwk6rXNzRY9OMvVxFIOU= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= diff --git a/go.mod b/go.mod index 18548e25c..436af2ef0 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,7 @@ require ( github.com/hashicorp/go-multierror v1.1.1 github.com/ipfs-shipyard/nopfs v0.0.12 github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c - github.com/ipfs/boxo v0.19.1-0.20240415103851-7f9506844904 + github.com/ipfs/boxo v0.19.1-0.20240516085407-f4fe8997dcbe github.com/ipfs/go-block-format v0.2.0 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 @@ -66,7 +66,7 @@ require ( github.com/opentracing/opentracing-go v1.2.0 github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 github.com/pkg/errors v0.9.1 - github.com/prometheus/client_golang v1.19.0 + github.com/prometheus/client_golang v1.19.1 github.com/stretchr/testify v1.9.0 github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 github.com/tidwall/gjson v1.14.4 @@ -74,21 +74,21 @@ 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.24.0 - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.50.0 + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.51.0 go.opentelemetry.io/contrib/propagators/autoprop v0.46.1 - go.opentelemetry.io/otel v1.25.0 - go.opentelemetry.io/otel/sdk v1.25.0 - go.opentelemetry.io/otel/trace v1.25.0 + go.opentelemetry.io/otel v1.26.0 + go.opentelemetry.io/otel/sdk v1.26.0 + go.opentelemetry.io/otel/trace v1.26.0 go.uber.org/dig v1.17.1 go.uber.org/fx v1.20.1 go.uber.org/multierr v1.11.0 go.uber.org/zap v1.27.0 - golang.org/x/crypto v0.22.0 - golang.org/x/exp v0.0.0-20240409090435-93d18d7e34b8 + golang.org/x/crypto v0.23.0 + golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 golang.org/x/mod v0.17.0 golang.org/x/sync v0.7.0 - golang.org/x/sys v0.19.0 - google.golang.org/protobuf v1.33.0 + golang.org/x/sys v0.20.0 + google.golang.org/protobuf v1.34.1 ) require ( @@ -117,17 +117,17 @@ require ( github.com/go-logfmt/logfmt v0.5.1 // indirect github.com/go-logr/logr v1.4.1 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect + github.com/go-task/slim-sprig/v3 v3.0.0 // indirect github.com/godbus/dbus/v5 v5.1.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/gopacket v1.1.19 // indirect - github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd // indirect + github.com/google/pprof v0.0.0-20240509144519-723abb6459b7 // indirect github.com/gorilla/mux v1.8.1 // indirect github.com/gorilla/websocket v1.5.1 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/golang-lru v1.0.2 // indirect github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect @@ -167,7 +167,7 @@ require ( github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-runewidth v0.0.4 // indirect github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect - github.com/miekg/dns v1.1.58 // indirect + github.com/miekg/dns v1.1.59 // indirect github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect github.com/minio/sha256-simd v1.0.1 // indirect @@ -177,9 +177,9 @@ require ( github.com/multiformats/go-multiaddr-fmt v0.1.0 // indirect github.com/multiformats/go-multistream v0.5.0 // indirect github.com/multiformats/go-varint v0.0.7 // indirect - github.com/onsi/ginkgo/v2 v2.17.1 // indirect + github.com/onsi/ginkgo/v2 v2.17.3 // indirect github.com/opencontainers/runtime-spec v1.2.0 // indirect - github.com/openzipkin/zipkin-go v0.4.2 // indirect + github.com/openzipkin/zipkin-go v0.4.3 // indirect github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 // indirect github.com/pion/datachannel v1.5.5 // indirect github.com/pion/dtls/v2 v2.2.8 // indirect @@ -200,8 +200,8 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect github.com/polydawn/refmt v0.89.0 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.52.3 // indirect - github.com/prometheus/procfs v0.13.0 // indirect + github.com/prometheus/common v0.53.0 // indirect + github.com/prometheus/procfs v0.15.0 // indirect github.com/prometheus/statsd_exporter v0.22.7 // indirect github.com/quic-go/qpack v0.4.0 // indirect github.com/quic-go/quic-go v0.42.0 // indirect @@ -216,37 +216,37 @@ require ( github.com/ucarion/urlpath v0.0.0-20200424170820-7ccc79b76bbb // indirect github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc // indirect github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11 // indirect - github.com/whyrusleeping/cbor-gen v0.1.0 // indirect + github.com/whyrusleeping/cbor-gen v0.1.1 // indirect github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f // indirect github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect go.opentelemetry.io/contrib/propagators/aws v1.21.1 // indirect go.opentelemetry.io/contrib/propagators/b3 v1.21.1 // indirect go.opentelemetry.io/contrib/propagators/jaeger v1.21.1 // indirect go.opentelemetry.io/contrib/propagators/ot v1.21.1 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.25.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.25.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.25.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.25.0 // indirect - go.opentelemetry.io/otel/exporters/zipkin v1.25.0 // indirect - go.opentelemetry.io/otel/metric v1.25.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.26.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.26.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.26.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.26.0 // indirect + go.opentelemetry.io/otel/exporters/zipkin v1.26.0 // indirect + go.opentelemetry.io/otel/metric v1.26.0 // indirect go.opentelemetry.io/proto/otlp v1.2.0 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/mock v0.4.0 // indirect go4.org v0.0.0-20230225012048-214862532bf5 // indirect - golang.org/x/net v0.24.0 // indirect - golang.org/x/oauth2 v0.19.0 // indirect - golang.org/x/term v0.19.0 // indirect - golang.org/x/text v0.14.0 // indirect - golang.org/x/tools v0.20.0 // indirect + golang.org/x/net v0.25.0 // indirect + golang.org/x/oauth2 v0.20.0 // indirect + golang.org/x/term v0.20.0 // indirect + golang.org/x/text v0.15.0 // indirect + golang.org/x/tools v0.21.0 // indirect golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect gonum.org/v1/gonum v0.15.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240412170617-26222e5d3d56 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240412170617-26222e5d3d56 // indirect - google.golang.org/grpc v1.63.2 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240515191416-fc5f0ca64291 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240515191416-fc5f0ca64291 // indirect + google.golang.org/grpc v1.64.0 // indirect gopkg.in/square/go-jose.v2 v2.5.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - lukechampine.com/blake3 v1.2.2 // indirect + lukechampine.com/blake3 v1.3.0 // indirect ) go 1.22 diff --git a/go.sum b/go.sum index 5e2d0d86a..570a63772 100644 --- a/go.sum +++ b/go.sum @@ -202,8 +202,8 @@ github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= -github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= -github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= +github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= +github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0= github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= @@ -281,8 +281,8 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd h1:gbpYu9NMq8jhDVbvlGkMFWCjLFlqqEZjEmObmhUy6Vo= -github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= +github.com/google/pprof v0.0.0-20240509144519-723abb6459b7 h1:velgFPYr1X9TDwLIfkV7fWqsFlf7TeP11M/7kPd/dVI= +github.com/google/pprof v0.0.0-20240509144519-723abb6459b7/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -302,8 +302,8 @@ github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/ github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1 h1:/c3QmbOGMGTOumP2iT/rCwB7b0QDGLKzqOmktBjT+Is= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1/go.mod h1:5SN9VR2LTsRFsrEC6FHgRbTWrTHu6tqPeKxEQv15giM= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k= github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -329,8 +329,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.19.1-0.20240415103851-7f9506844904 h1:HqjqN6oADXh1UNw8xKnBP50B3ZQDC/RStiBFPp6W+9Y= -github.com/ipfs/boxo v0.19.1-0.20240415103851-7f9506844904/go.mod h1:hA9Ou/YnfMZOG2nQhngsbBiYt6fiJ1EhWSmccZfV+M0= +github.com/ipfs/boxo v0.19.1-0.20240516085407-f4fe8997dcbe h1:GoWqF8evx/xOnjVQEFT6FgMKVZBcqPCGeqY3h2m9r7A= +github.com/ipfs/boxo v0.19.1-0.20240516085407-f4fe8997dcbe/go.mod h1:7pXWoypZuknFVLqeLy7UraFV4NYBA0ufGBzVHcTZ188= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= @@ -580,8 +580,8 @@ github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyex github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= -github.com/miekg/dns v1.1.58 h1:ca2Hdkz+cDg/7eNF6V56jjzuZ4aCAE+DbVkILdQWG/4= -github.com/miekg/dns v1.1.58/go.mod h1:Ypv+3b/KadlvW9vJfXOTf300O4UqaHFzFCuHz+rPkBY= +github.com/miekg/dns v1.1.59 h1:C9EXc/UToRwKLhK5wKU/I4QVsBUc8kE6MkHBkeypWZs= +github.com/miekg/dns v1.1.59/go.mod h1:nZpewl5p6IvctfgrckopVx2OlSEHPRO/U4SYkRklrEk= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c h1:bzE/A84HN25pxAuk9Eej1Kz9OUelF97nAc82bDquQI8= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c/go.mod h1:0SQS9kMwD2VsyFEB++InYyBJroV/FRmBgcydeSUcJms= github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= @@ -663,14 +663,14 @@ github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9k github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.17.1 h1:V++EzdbhI4ZV4ev0UTIj0PzhzOcReJFyJaLjtSF55M8= -github.com/onsi/ginkgo/v2 v2.17.1/go.mod h1:llBI3WDLL9Z6taip6f33H76YcWtJv+7R3HigUjbIBOs= +github.com/onsi/ginkgo/v2 v2.17.3 h1:oJcvKpIb7/8uLpDDtnQuf18xVnwKp8DTD7DQ6gTd/MU= +github.com/onsi/ginkgo/v2 v2.17.3/go.mod h1:nP2DPOQoNsQmsVyv5rDA8JkXQoCs6goXIvr/PRJ1eCc= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= -github.com/onsi/gomega v1.30.0 h1:hvMK7xYz4D3HapigLTeGdId/NcfQx1VHMJc60ew99+8= -github.com/onsi/gomega v1.30.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= +github.com/onsi/gomega v1.33.0 h1:snPCflnZrpMsy94p4lXVEkHo12lmPnc3vY5XBbreexE= +github.com/onsi/gomega v1.33.0/go.mod h1:+925n5YtiFsLzzafLUHzVMBpvvRAzrydIBiSIxjX3wY= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.2.0 h1:z97+pHb3uELt/yiAWD691HNHQIF07bE7dzrbT927iTk= github.com/opencontainers/runtime-spec v1.2.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= @@ -679,8 +679,8 @@ github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFSt github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= -github.com/openzipkin/zipkin-go v0.4.2 h1:zjqfqHjUpPmB3c1GlCvvgsM1G4LkvqQbBDueDOCg/jA= -github.com/openzipkin/zipkin-go v0.4.2/go.mod h1:ZeVkFjuuBiSy13y8vpSDCjMi9GoI3hPpCJSBx/EYFhY= +github.com/openzipkin/zipkin-go v0.4.3 h1:9EGwpqkgnwdEIJ+Od7QVSEIH+ocmm5nPat0G7sjsSdg= +github.com/openzipkin/zipkin-go v0.4.3/go.mod h1:M9wCJZFWCo2RiY+o1eBCEMe0Dp2S5LDHcMZmk3RmK7c= 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/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= @@ -751,8 +751,8 @@ github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqr github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_golang v1.12.2/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_golang v1.13.0/go.mod h1:vTeo+zgvILHsnnj/39Ou/1fPN5nJFOEMgftOUOmlvYQ= -github.com/prometheus/client_golang v1.19.0 h1:ygXvpU1AoN1MhdzckN+PyD9QJOSD4x7kmXYlnfbA6JU= -github.com/prometheus/client_golang v1.19.0/go.mod h1:ZRM9uEAypZakd+q/x7+gmsvXdURP+DABIEIjnmDdp+k= +github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE= +github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -767,8 +767,8 @@ github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9 github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/common v0.35.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= -github.com/prometheus/common v0.52.3 h1:5f8uj6ZwHSscOGNdIQg6OiZv/ybiK2CO2q2drVZAQSA= -github.com/prometheus/common v0.52.3/go.mod h1:BrxBKv3FWBIGXw89Mg1AeBq7FSyRzXWI3l3e7W3RN5U= +github.com/prometheus/common v0.53.0 h1:U2pL9w9nmJwJDa4qqLQ3ZaePJ6ZTwt7cMD3AG3+aLCE= +github.com/prometheus/common v0.53.0/go.mod h1:BrxBKv3FWBIGXw89Mg1AeBq7FSyRzXWI3l3e7W3RN5U= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= @@ -777,8 +777,8 @@ github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4O github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= -github.com/prometheus/procfs v0.13.0 h1:GqzLlQyfsPbaEHaQkO7tbDlriv/4o5Hudv6OXHGKX7o= -github.com/prometheus/procfs v0.13.0/go.mod h1:cd4PFCR54QLnGKPaKGA6l+cfuNXtht43ZKY6tow0Y1g= +github.com/prometheus/procfs v0.15.0 h1:A82kmvXJq2jTu5YUhSGNlYoxh85zLnKgPz4bMZgI5Ek= +github.com/prometheus/procfs v0.15.0/go.mod h1:Y0RJ/Y5g5wJpkTisOtqwDSo4HwhGmLB4VQSw2sQJLHk= github.com/prometheus/statsd_exporter v0.22.7 h1:7Pji/i2GuhK6Lu7DHrtTkFmNBCudCPT1pX2CziuyQR0= github.com/prometheus/statsd_exporter v0.22.7/go.mod h1:N/TevpjkIh9ccs6nuzY3jQn9dFqnUakOjnEuMPJJJnI= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= @@ -907,8 +907,8 @@ github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc h1:BCPnHtcboa github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc/go.mod h1:r45hJU7yEoA81k6MWNhpMj/kms0n14dkzkxYHoB96UM= github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11 h1:5HZfQkwe0mIfyDmc1Em5GqlNRzcdtlv4HTNmdpt7XH0= github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11/go.mod h1:Wlo/SzPmxVp6vXpGt/zaXhHH0fn4IxgqZc82aKg6bpQ= -github.com/whyrusleeping/cbor-gen v0.1.0 h1:Jneeq3V5enErVcuL0NKEbD1Gi+iOvEeFhXOV1S1Fc6g= -github.com/whyrusleeping/cbor-gen v0.1.0/go.mod h1:pM99HXyEbSQHcosHc0iW7YFmwnscr+t9Te4ibko05so= +github.com/whyrusleeping/cbor-gen v0.1.1 h1:eKfcJIoxivjMtwfCfmJAqSF56MHcWqyIScXwaC1VBgw= +github.com/whyrusleeping/cbor-gen v0.1.1/go.mod h1:pM99HXyEbSQHcosHc0iW7YFmwnscr+t9Te4ibko05so= github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f h1:jQa4QT2UP9WYv2nzyawpKMOCl+Z/jW7djv2/J50lj9E= github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f/go.mod h1:p9UJB6dDgdPgMJZs7UjUOdulKyRr9fqkS+6JKAInPy8= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 h1:EKhdznlJHPMoKr0XTrX+IlJs1LH3lyx2nfr1dOlZ79k= @@ -936,8 +936,8 @@ go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.50.0 h1:cEPbyTSEHlQR89XVlyo78gqluF8Y3oMeBkXGWzQsfXY= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.50.0/go.mod h1:DKdbWcT4GH1D0Y3Sqt/PFXt2naRKDWtU+eE6oLdFNA8= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.51.0 h1:Xs2Ncz0gNihqu9iosIZ5SkBbWo5T8JhhLJFMQL1qmLI= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.51.0/go.mod h1:vy+2G/6NvVMpwGX/NyLqcC41fxepnuKHk16E6IZUcJc= go.opentelemetry.io/contrib/propagators/autoprop v0.46.1 h1:cXTYcMjY0dsYokAuo8LbNBQxpF8VgTHdiHJJ1zlIXl4= go.opentelemetry.io/contrib/propagators/autoprop v0.46.1/go.mod h1:WZxgny1/6+j67B1s72PLJ4bGjidoWFzSmLNfJKVt2bo= go.opentelemetry.io/contrib/propagators/aws v1.21.1 h1:uQIQIDWb0gzyvon2ICnghpLAf9w7ADOCUiIiwCQgR2o= @@ -948,24 +948,24 @@ go.opentelemetry.io/contrib/propagators/jaeger v1.21.1 h1:f4beMGDKiVzg9IcX7/VuWV go.opentelemetry.io/contrib/propagators/jaeger v1.21.1/go.mod h1:U9jhkEl8d1LL+QXY7q3kneJWJugiN3kZJV2OWz3hkBY= go.opentelemetry.io/contrib/propagators/ot v1.21.1 h1:3TN5vkXjKYWp0YdMcnUEC/A+pBPvqz9V3nCS2xmcurk= go.opentelemetry.io/contrib/propagators/ot v1.21.1/go.mod h1:oy0MYCbS/b3cqUDW37wBWtlwBIsutngS++Lklpgh+fc= -go.opentelemetry.io/otel v1.25.0 h1:gldB5FfhRl7OJQbUHt/8s0a7cE8fbsPAtdpRaApKy4k= -go.opentelemetry.io/otel v1.25.0/go.mod h1:Wa2ds5NOXEMkCmUou1WA7ZBfLTHWIsp034OVD7AO+Vg= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.25.0 h1:dT33yIHtmsqpixFsSQPwNeY5drM9wTcoL8h0FWF4oGM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.25.0/go.mod h1:h95q0LBGh7hlAC08X2DhSeyIG02YQ0UyioTCVAqRPmc= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.25.0 h1:vOL89uRfOCCNIjkisd0r7SEdJF3ZJFyCNY34fdZs8eU= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.25.0/go.mod h1:8GlBGcDk8KKi7n+2S4BT/CPZQYH3erLu0/k64r1MYgo= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.25.0 h1:Mbi5PKN7u322woPa85d7ebZ+SOvEoPvoiBu+ryHWgfA= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.25.0/go.mod h1:e7ciERRhZaOZXVjx5MiL8TK5+Xv7G5Gv5PA2ZDEJdL8= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.25.0 h1:0vZZdECYzhTt9MKQZ5qQ0V+J3MFu4MQaQ3COfugF+FQ= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.25.0/go.mod h1:e7iXx3HjaSSBXfy9ykVUlupS2Vp7LBIBuT21ousM2Hk= -go.opentelemetry.io/otel/exporters/zipkin v1.25.0 h1:iLzdsOsstvim/54ymA2BhEN4+1NbsvwGvOhSkQy2TaY= -go.opentelemetry.io/otel/exporters/zipkin v1.25.0/go.mod h1:3QXxNo6ace1QZX6pSHEzGKKESVdjQxXR03FcIH7dNGs= -go.opentelemetry.io/otel/metric v1.25.0 h1:LUKbS7ArpFL/I2jJHdJcqMGxkRdxpPHE0VU/D4NuEwA= -go.opentelemetry.io/otel/metric v1.25.0/go.mod h1:rkDLUSd2lC5lq2dFNrX9LGAbINP5B7WBkC78RXCpH5s= -go.opentelemetry.io/otel/sdk v1.25.0 h1:PDryEJPC8YJZQSyLY5eqLeafHtG+X7FWnf3aXMtxbqo= -go.opentelemetry.io/otel/sdk v1.25.0/go.mod h1:oFgzCM2zdsxKzz6zwpTZYLLQsFwc+K0daArPdIhuxkw= -go.opentelemetry.io/otel/trace v1.25.0 h1:tqukZGLwQYRIFtSQM2u2+yfMVTgGVeqRLPUYx1Dq6RM= -go.opentelemetry.io/otel/trace v1.25.0/go.mod h1:hCCs70XM/ljO+BeQkyFnbK28SBIJ/Emuha+ccrCRT7I= +go.opentelemetry.io/otel v1.26.0 h1:LQwgL5s/1W7YiiRwxf03QGnWLb2HW4pLiAhaA5cZXBs= +go.opentelemetry.io/otel v1.26.0/go.mod h1:UmLkJHUAidDval2EICqBMbnAd0/m2vmpf/dAM+fvFs4= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.26.0 h1:1u/AyyOqAWzy+SkPxDpahCNZParHV8Vid1RnI2clyDE= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.26.0/go.mod h1:z46paqbJ9l7c9fIPCXTqTGwhQZ5XoTIsfeFYWboizjs= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.26.0 h1:Waw9Wfpo/IXzOI8bCB7DIk+0JZcqqsyn1JFnAc+iam8= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.26.0/go.mod h1:wnJIG4fOqyynOnnQF/eQb4/16VlX2EJAHhHgqIqWfAo= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.26.0 h1:1wp/gyxsuYtuE/JFxsQRtcCDtMrO2qMvlfXALU5wkzI= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.26.0/go.mod h1:gbTHmghkGgqxMomVQQMur1Nba4M0MQ8AYThXDUjsJ38= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.26.0 h1:0W5o9SzoR15ocYHEQfvfipzcNog1lBxOLfnex91Hk6s= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.26.0/go.mod h1:zVZ8nz+VSggWmnh6tTsJqXQ7rU4xLwRtna1M4x5jq58= +go.opentelemetry.io/otel/exporters/zipkin v1.26.0 h1:sBk6A62GgcQRwcxcBwRMPkqeuSizcpHkXyZNyP281Fw= +go.opentelemetry.io/otel/exporters/zipkin v1.26.0/go.mod h1:fLzYtPUxPFzu7rSqhYsCxYheT2dNoPjtKovCLzLm07w= +go.opentelemetry.io/otel/metric v1.26.0 h1:7S39CLuY5Jgg9CrnA9HHiEjGMF/X2VHvoXGgSllRz30= +go.opentelemetry.io/otel/metric v1.26.0/go.mod h1:SY+rHOI4cEawI9a7N1A4nIg/nTQXe1ccCNWYOJUrpX4= +go.opentelemetry.io/otel/sdk v1.26.0 h1:Y7bumHf5tAiDlRYFmGqetNcLaVUZmh4iYfmGxtmz7F8= +go.opentelemetry.io/otel/sdk v1.26.0/go.mod h1:0p8MXpqLeJ0pzcszQQN4F0S5FVjBLgypeGSngLsmirs= +go.opentelemetry.io/otel/trace v1.26.0 h1:1ieeAUb4y0TE26jUFrCIXKpTuVK7uJGN9/Z/2LP5sQA= +go.opentelemetry.io/otel/trace v1.26.0/go.mod h1:4iDxvGDQuUkHve82hJJ8UqrwswHYsZuWCBllGV2U2y0= go.opentelemetry.io/proto/otlp v1.2.0 h1:pVeZGk7nXDC9O2hncA6nHldxEjm6LByfA2aN8IOkz94= go.opentelemetry.io/proto/otlp v1.2.0/go.mod h1:gGpR8txAl5M03pDhMC79G6SdqNV26naRm/KDsgaHD8A= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= @@ -1020,8 +1020,8 @@ golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45 golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= -golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= -golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= +golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= +golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1032,8 +1032,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20240409090435-93d18d7e34b8 h1:ESSUROHIBHg7USnszlcdmjBEwdMj9VUvU+OPk4yl2mc= -golang.org/x/exp v0.0.0-20240409090435-93d18d7e34b8/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI= +golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM= +golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1116,8 +1116,8 @@ golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ= golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= -golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= -golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= +golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= +golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1127,8 +1127,8 @@ golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4Iltr golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.19.0 h1:9+E/EZBCbTLNrbN35fHv/a/d/mOBatymz1zbtQrXpIg= -golang.org/x/oauth2 v0.19.0/go.mod h1:vYi7skDa1x015PmRRYZ7+s1cWyPgrPiSYRe4rnsexc8= +golang.org/x/oauth2 v0.20.0 h1:4mQdhULixXKP1rwYBW0vAijoXnkTG0BLCDRzfe1idMo= +golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1224,8 +1224,8 @@ golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= -golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -1237,8 +1237,8 @@ golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo= golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= -golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q= -golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= +golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw= +golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1253,8 +1253,8 @@ golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= +golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1315,8 +1315,8 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY= -golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg= +golang.org/x/tools v0.21.0 h1:qc0xYgIbsSDt9EyWz05J5wfa7LOVW0YTLOXrqdLAWIw= +golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1385,10 +1385,10 @@ google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7Fc google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto/googleapis/api v0.0.0-20240412170617-26222e5d3d56 h1:KuFzeG+qPmpT8KpJXcrKAyeHhn64dgEICWlccP9qp0U= -google.golang.org/genproto/googleapis/api v0.0.0-20240412170617-26222e5d3d56/go.mod h1:wTHjrkbcS8AoQbb/0v9bFIPItZQPAsyVfgG9YPUhjAM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240412170617-26222e5d3d56 h1:zviK8GX4VlMstrK3JkexM5UHjH1VOkRebH9y3jhSBGk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240412170617-26222e5d3d56/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= +google.golang.org/genproto/googleapis/api v0.0.0-20240515191416-fc5f0ca64291 h1:4HZJ3Xv1cmrJ+0aFo304Zn79ur1HMxptAE7aCPNLSqc= +google.golang.org/genproto/googleapis/api v0.0.0-20240515191416-fc5f0ca64291/go.mod h1:RGnPtTG7r4i8sPlNyDeikXF99hMM+hN6QMm4ooG9g2g= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240515191416-fc5f0ca64291 h1:AgADTJarZTBqgjiUzRgfaBchgYB3/WFTC80GPwsMcRI= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240515191416-fc5f0ca64291/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= @@ -1405,8 +1405,8 @@ google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3Iji google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.63.2 h1:MUeiw1B2maTVZthpU5xvASfTh3LDbxHd6IJ6QQVU+xM= -google.golang.org/grpc v1.63.2/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA= +google.golang.org/grpc v1.64.0 h1:KH3VH9y/MgNQg1dE7b3XfVK0GsPSIzJwdF617gUSbvY= +google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -1421,8 +1421,8 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= -google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= +google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -1460,8 +1460,8 @@ honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= lukechampine.com/blake3 v1.1.6/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= -lukechampine.com/blake3 v1.2.2 h1:wEAbSg0IVU4ih44CVlpMqMZMpzr5hf/6aqodLlevd/w= -lukechampine.com/blake3 v1.2.2/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= +lukechampine.com/blake3 v1.3.0 h1:sJ3XhFINmHSrYCgl958hscfIa3bw8x4DqMP3u1YvoYE= +lukechampine.com/blake3 v1.3.0/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= pgregory.net/rapid v0.4.7 h1:MTNRktPuv5FNqOO151TM9mDTa+XHcX6ypYeISDVD14g= pgregory.net/rapid v0.4.7/go.mod h1:UYpPVyjFHzYBGHIxLFoupi8vwk6rXNzRY9OMvVxFIOU= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 86f0b7336..436b013f4 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -105,7 +105,7 @@ require ( github.com/hexops/gotextdiff v1.0.3 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/ipfs/bbloom v0.0.4 // indirect - github.com/ipfs/boxo v0.19.1-0.20240415103851-7f9506844904 // indirect + github.com/ipfs/boxo v0.19.1-0.20240516085407-f4fe8997dcbe // indirect github.com/ipfs/go-block-format v0.2.0 // indirect github.com/ipfs/go-cid v0.4.1 // indirect github.com/ipfs/go-datastore v0.6.0 // indirect @@ -153,7 +153,7 @@ require ( github.com/mattn/go-runewidth v0.0.9 // indirect github.com/mbilski/exhaustivestruct v1.2.0 // indirect github.com/mgechev/revive v1.3.2 // indirect - github.com/miekg/dns v1.1.58 // indirect + github.com/miekg/dns v1.1.59 // indirect github.com/minio/sha256-simd v1.0.1 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect @@ -180,10 +180,10 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect github.com/polydawn/refmt v0.89.0 // indirect github.com/polyfloyd/go-errorlint v1.4.3 // indirect - github.com/prometheus/client_golang v1.19.0 // indirect + github.com/prometheus/client_golang v1.19.1 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.52.3 // indirect - github.com/prometheus/procfs v0.13.0 // indirect + github.com/prometheus/common v0.53.0 // indirect + github.com/prometheus/procfs v0.15.0 // indirect github.com/quasilyte/go-ruleguard v0.4.0 // indirect github.com/quasilyte/gogrep v0.5.0 // indirect github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727 // indirect @@ -234,29 +234,29 @@ require ( github.com/ykadowak/zerologlint v0.1.3 // indirect gitlab.com/bosi/decorder v0.4.0 // indirect go.opencensus.io v0.24.0 // indirect - go.opentelemetry.io/otel v1.25.0 // indirect - go.opentelemetry.io/otel/metric v1.25.0 // indirect - go.opentelemetry.io/otel/trace v1.25.0 // indirect + go.opentelemetry.io/otel v1.26.0 // indirect + go.opentelemetry.io/otel/metric v1.26.0 // indirect + go.opentelemetry.io/otel/trace v1.26.0 // indirect go.tmz.dev/musttag v0.7.1 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect - golang.org/x/crypto v0.22.0 // indirect - golang.org/x/exp v0.0.0-20240409090435-93d18d7e34b8 // indirect + golang.org/x/crypto v0.23.0 // indirect + golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect golang.org/x/exp/typeparams v0.0.0-20230307190834-24139beb5833 // indirect golang.org/x/mod v0.17.0 // indirect - golang.org/x/net v0.24.0 // indirect + golang.org/x/net v0.25.0 // indirect golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.19.0 // indirect - golang.org/x/term v0.19.0 // indirect - golang.org/x/text v0.14.0 // indirect - golang.org/x/tools v0.20.0 // indirect + golang.org/x/sys v0.20.0 // indirect + golang.org/x/term v0.20.0 // indirect + golang.org/x/text v0.15.0 // indirect + golang.org/x/tools v0.21.0 // indirect gonum.org/v1/gonum v0.15.0 // indirect - google.golang.org/protobuf v1.33.0 // indirect + google.golang.org/protobuf v1.34.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect honnef.co/go/tools v0.4.3 // indirect - lukechampine.com/blake3 v1.2.2 // indirect + lukechampine.com/blake3 v1.3.0 // indirect mvdan.cc/gofumpt v0.5.0 // indirect mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed // indirect mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 14bb2aa25..915c834f8 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -192,7 +192,8 @@ github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= -github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= +github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= +github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/go-toolsmith/astcast v1.1.0 h1:+JN9xZV1A+Re+95pgnMgDboWNVnIMMQXwfBwLRPgSC8= github.com/go-toolsmith/astcast v1.1.0/go.mod h1:qdcuFWeGGS2xX5bLM/c3U9lewg7+Zu4mr+xPwZIB4ZU= github.com/go-toolsmith/astcopy v1.1.0 h1:YGwBN0WM+ekI/6SS6+52zLDEf8Yvp3n2seZITCUBt5s= @@ -305,8 +306,8 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd h1:gbpYu9NMq8jhDVbvlGkMFWCjLFlqqEZjEmObmhUy6Vo= -github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= +github.com/google/pprof v0.0.0-20240509144519-723abb6459b7 h1:velgFPYr1X9TDwLIfkV7fWqsFlf7TeP11M/7kPd/dVI= +github.com/google/pprof v0.0.0-20240509144519-723abb6459b7/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= @@ -362,8 +363,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.19.1-0.20240415103851-7f9506844904 h1:HqjqN6oADXh1UNw8xKnBP50B3ZQDC/RStiBFPp6W+9Y= -github.com/ipfs/boxo v0.19.1-0.20240415103851-7f9506844904/go.mod h1:hA9Ou/YnfMZOG2nQhngsbBiYt6fiJ1EhWSmccZfV+M0= +github.com/ipfs/boxo v0.19.1-0.20240516085407-f4fe8997dcbe h1:GoWqF8evx/xOnjVQEFT6FgMKVZBcqPCGeqY3h2m9r7A= +github.com/ipfs/boxo v0.19.1-0.20240516085407-f4fe8997dcbe/go.mod h1:7pXWoypZuknFVLqeLy7UraFV4NYBA0ufGBzVHcTZ188= github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs= github.com/ipfs/go-block-format v0.2.0/go.mod h1:+jpL11nFx5A/SPpsoBn6Bzkra/zaArfSmsknbPMYgzM= github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= @@ -534,8 +535,8 @@ github.com/mbilski/exhaustivestruct v1.2.0/go.mod h1:OeTBVxQWoEmB2J2JCHmXWPJ0aks github.com/mgechev/revive v1.3.2 h1:Wb8NQKBaALBJ3xrrj4zpwJwqwNA6nDpyJSEQWcCka6U= github.com/mgechev/revive v1.3.2/go.mod h1:UCLtc7o5vg5aXCwdUTU1kEBQ1v+YXPAkYDIDXbrs5I0= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= -github.com/miekg/dns v1.1.58 h1:ca2Hdkz+cDg/7eNF6V56jjzuZ4aCAE+DbVkILdQWG/4= -github.com/miekg/dns v1.1.58/go.mod h1:Ypv+3b/KadlvW9vJfXOTf300O4UqaHFzFCuHz+rPkBY= +github.com/miekg/dns v1.1.59 h1:C9EXc/UToRwKLhK5wKU/I4QVsBUc8kE6MkHBkeypWZs= +github.com/miekg/dns v1.1.59/go.mod h1:nZpewl5p6IvctfgrckopVx2OlSEHPRO/U4SYkRklrEk= github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b/go.mod h1:lxPUiZwKoFL8DUUmalo2yJJUCxbPKtm8OKfqr2/FTNU= github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc h1:PTfri+PuQmWDqERdnNMiD9ZejrlswWrCpBEZgWOiTrc= @@ -598,8 +599,8 @@ github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6 github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w= github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo/v2 v2.17.1 h1:V++EzdbhI4ZV4ev0UTIj0PzhzOcReJFyJaLjtSF55M8= -github.com/onsi/ginkgo/v2 v2.17.1/go.mod h1:llBI3WDLL9Z6taip6f33H76YcWtJv+7R3HigUjbIBOs= +github.com/onsi/ginkgo/v2 v2.17.3 h1:oJcvKpIb7/8uLpDDtnQuf18xVnwKp8DTD7DQ6gTd/MU= +github.com/onsi/ginkgo/v2 v2.17.3/go.mod h1:nP2DPOQoNsQmsVyv5rDA8JkXQoCs6goXIvr/PRJ1eCc= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= @@ -635,8 +636,8 @@ github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5Fsn github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= -github.com/prometheus/client_golang v1.19.0 h1:ygXvpU1AoN1MhdzckN+PyD9QJOSD4x7kmXYlnfbA6JU= -github.com/prometheus/client_golang v1.19.0/go.mod h1:ZRM9uEAypZakd+q/x7+gmsvXdURP+DABIEIjnmDdp+k= +github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE= +github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -647,15 +648,15 @@ github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8 github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= -github.com/prometheus/common v0.52.3 h1:5f8uj6ZwHSscOGNdIQg6OiZv/ybiK2CO2q2drVZAQSA= -github.com/prometheus/common v0.52.3/go.mod h1:BrxBKv3FWBIGXw89Mg1AeBq7FSyRzXWI3l3e7W3RN5U= +github.com/prometheus/common v0.53.0 h1:U2pL9w9nmJwJDa4qqLQ3ZaePJ6ZTwt7cMD3AG3+aLCE= +github.com/prometheus/common v0.53.0/go.mod h1:BrxBKv3FWBIGXw89Mg1AeBq7FSyRzXWI3l3e7W3RN5U= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.13.0 h1:GqzLlQyfsPbaEHaQkO7tbDlriv/4o5Hudv6OXHGKX7o= -github.com/prometheus/procfs v0.13.0/go.mod h1:cd4PFCR54QLnGKPaKGA6l+cfuNXtht43ZKY6tow0Y1g= +github.com/prometheus/procfs v0.15.0 h1:A82kmvXJq2jTu5YUhSGNlYoxh85zLnKgPz4bMZgI5Ek= +github.com/prometheus/procfs v0.15.0/go.mod h1:Y0RJ/Y5g5wJpkTisOtqwDSo4HwhGmLB4VQSw2sQJLHk= github.com/quasilyte/go-ruleguard v0.4.0 h1:DyM6r+TKL+xbKB4Nm7Afd1IQh9kEUKQs2pboWGKtvQo= github.com/quasilyte/go-ruleguard v0.4.0/go.mod h1:Eu76Z/R8IXtViWUIHkE3p8gdH3/PKk1eh3YGfaEof10= github.com/quasilyte/gogrep v0.5.0 h1:eTKODPXbI8ffJMN+W2aE0+oL0z/nh8/5eNdiO34SOAo= @@ -818,12 +819,12 @@ go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/otel v1.25.0 h1:gldB5FfhRl7OJQbUHt/8s0a7cE8fbsPAtdpRaApKy4k= -go.opentelemetry.io/otel v1.25.0/go.mod h1:Wa2ds5NOXEMkCmUou1WA7ZBfLTHWIsp034OVD7AO+Vg= -go.opentelemetry.io/otel/metric v1.25.0 h1:LUKbS7ArpFL/I2jJHdJcqMGxkRdxpPHE0VU/D4NuEwA= -go.opentelemetry.io/otel/metric v1.25.0/go.mod h1:rkDLUSd2lC5lq2dFNrX9LGAbINP5B7WBkC78RXCpH5s= -go.opentelemetry.io/otel/trace v1.25.0 h1:tqukZGLwQYRIFtSQM2u2+yfMVTgGVeqRLPUYx1Dq6RM= -go.opentelemetry.io/otel/trace v1.25.0/go.mod h1:hCCs70XM/ljO+BeQkyFnbK28SBIJ/Emuha+ccrCRT7I= +go.opentelemetry.io/otel v1.26.0 h1:LQwgL5s/1W7YiiRwxf03QGnWLb2HW4pLiAhaA5cZXBs= +go.opentelemetry.io/otel v1.26.0/go.mod h1:UmLkJHUAidDval2EICqBMbnAd0/m2vmpf/dAM+fvFs4= +go.opentelemetry.io/otel/metric v1.26.0 h1:7S39CLuY5Jgg9CrnA9HHiEjGMF/X2VHvoXGgSllRz30= +go.opentelemetry.io/otel/metric v1.26.0/go.mod h1:SY+rHOI4cEawI9a7N1A4nIg/nTQXe1ccCNWYOJUrpX4= +go.opentelemetry.io/otel/trace v1.26.0 h1:1ieeAUb4y0TE26jUFrCIXKpTuVK7uJGN9/Z/2LP5sQA= +go.opentelemetry.io/otel/trace v1.26.0/go.mod h1:4iDxvGDQuUkHve82hJJ8UqrwswHYsZuWCBllGV2U2y0= go.tmz.dev/musttag v0.7.1 h1:9lFmeSFnFfPuMq4IksHGomItE6NgKMNW2Nt2FPOhCfU= go.tmz.dev/musttag v0.7.1/go.mod h1:oJLkpR56EsIryktZJk/B0IroSMi37YWver47fibGh5U= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= @@ -857,8 +858,8 @@ golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= -golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= -golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= +golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= +golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -869,8 +870,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20240409090435-93d18d7e34b8 h1:ESSUROHIBHg7USnszlcdmjBEwdMj9VUvU+OPk4yl2mc= -golang.org/x/exp v0.0.0-20240409090435-93d18d7e34b8/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI= +golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM= +golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc= golang.org/x/exp/typeparams v0.0.0-20220428152302-39d4317da171/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/exp/typeparams v0.0.0-20230203172020-98cc5a0785f9/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/exp/typeparams v0.0.0-20230307190834-24139beb5833 h1:jWGQJV4niP+CCmFW9ekjA9Zx8vYORzOUH2/Nl5WPuLQ= @@ -950,8 +951,8 @@ golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= -golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= +golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= +golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1039,16 +1040,16 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= -golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q= -golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= +golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw= +golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1060,8 +1061,8 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= +golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1139,8 +1140,8 @@ golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= golang.org/x/tools v0.5.0/go.mod h1:N+Kgy78s5I24c24dU8OfWNEotWjutIs8SnJvn5IDq+k= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY= -golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg= +golang.org/x/tools v0.21.0 h1:qc0xYgIbsSDt9EyWz05J5wfa7LOVW0YTLOXrqdLAWIw= +golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1237,8 +1238,8 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= -google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= +google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -1277,8 +1278,8 @@ honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9 honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.4.3 h1:o/n5/K5gXqk8Gozvs2cnL0F2S1/g1vcGCAx2vETjITw= honnef.co/go/tools v0.4.3/go.mod h1:36ZgoUOrqOk1GxwHhyryEkq8FQWkUO2xGuSMhUCcdvA= -lukechampine.com/blake3 v1.2.2 h1:wEAbSg0IVU4ih44CVlpMqMZMpzr5hf/6aqodLlevd/w= -lukechampine.com/blake3 v1.2.2/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= +lukechampine.com/blake3 v1.3.0 h1:sJ3XhFINmHSrYCgl958hscfIa3bw8x4DqMP3u1YvoYE= +lukechampine.com/blake3 v1.3.0/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= mvdan.cc/gofumpt v0.5.0 h1:0EQ+Z56k8tXjj/6TQD25BFNKQXpCvT0rnansIc7Ug5E= mvdan.cc/gofumpt v0.5.0/go.mod h1:HBeVDtMKRZpXyxFciAirzdKklDlGu8aAy1wEbH5Y9js= mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed h1:WX1yoOaKQfddO/mLzdV4wptyWgoH/6hwLs7QHTixo0I= From 4f94f368845ab811579af42b7ea9e53941553721 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 May 2024 21:05:48 +0000 Subject: [PATCH 1091/1212] chore(deps): bump codecov/codecov-action from 4.2.0 to 4.3.1 Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 4.2.0 to 4.3.1. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/7afa10ed9b269c561c2336fd862446844e0cbf71...5ecb98a3c6b747ed38dc09f787459979aebb39be) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/gotest.yml | 2 +- .github/workflows/sharness.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/gotest.yml b/.github/workflows/gotest.yml index 2e34922d6..a5df5d9f3 100644 --- a/.github/workflows/gotest.yml +++ b/.github/workflows/gotest.yml @@ -45,7 +45,7 @@ jobs: make -j "$PARALLEL" test/unit/gotest.junit.xml && [[ ! $(jq -s -c 'map(select(.Action == "fail")) | .[]' test/unit/gotest.json) ]] - name: Upload coverage to Codecov - uses: codecov/codecov-action@7afa10ed9b269c561c2336fd862446844e0cbf71 # v4.2.0 + uses: codecov/codecov-action@5ecb98a3c6b747ed38dc09f787459979aebb39be # v4.3.1 if: failure() || success() with: name: unittests diff --git a/.github/workflows/sharness.yml b/.github/workflows/sharness.yml index 03c04f922..48daa3114 100644 --- a/.github/workflows/sharness.yml +++ b/.github/workflows/sharness.yml @@ -55,7 +55,7 @@ jobs: # increasing parallelism beyond 10 doesn't speed up the tests much PARALLEL: ${{ github.repository == 'ipfs/kubo' && 10 || 3 }} - name: Upload coverage report - uses: codecov/codecov-action@7afa10ed9b269c561c2336fd862446844e0cbf71 # v4.2.0 + uses: codecov/codecov-action@5ecb98a3c6b747ed38dc09f787459979aebb39be # v4.3.1 if: failure() || success() with: name: sharness From 5de5b77168be347186dbc9f1586c2deb485ca2ef Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 16 May 2024 09:26:51 +0000 Subject: [PATCH 1092/1212] chore(deps): bump codecov/codecov-action from 4.2.0 to 4.4.0 Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 4.2.0 to 4.4.0. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/7afa10ed9b269c561c2336fd862446844e0cbf71...6d798873df2b1b8e5846dba6fb86631229fbcb17) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/gotest.yml | 2 +- .github/workflows/sharness.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/gotest.yml b/.github/workflows/gotest.yml index a5df5d9f3..609791aba 100644 --- a/.github/workflows/gotest.yml +++ b/.github/workflows/gotest.yml @@ -45,7 +45,7 @@ jobs: make -j "$PARALLEL" test/unit/gotest.junit.xml && [[ ! $(jq -s -c 'map(select(.Action == "fail")) | .[]' test/unit/gotest.json) ]] - name: Upload coverage to Codecov - uses: codecov/codecov-action@5ecb98a3c6b747ed38dc09f787459979aebb39be # v4.3.1 + uses: codecov/codecov-action@6d798873df2b1b8e5846dba6fb86631229fbcb17 # v4.4.0 if: failure() || success() with: name: unittests diff --git a/.github/workflows/sharness.yml b/.github/workflows/sharness.yml index 48daa3114..6432745bf 100644 --- a/.github/workflows/sharness.yml +++ b/.github/workflows/sharness.yml @@ -55,7 +55,7 @@ jobs: # increasing parallelism beyond 10 doesn't speed up the tests much PARALLEL: ${{ github.repository == 'ipfs/kubo' && 10 || 3 }} - name: Upload coverage report - uses: codecov/codecov-action@5ecb98a3c6b747ed38dc09f787459979aebb39be # v4.3.1 + uses: codecov/codecov-action@6d798873df2b1b8e5846dba6fb86631229fbcb17 # v4.4.0 if: failure() || success() with: name: sharness From 75df4e8173608dcc3fceba1868e7df97b2612ce7 Mon Sep 17 00:00:00 2001 From: Oleg Kovalov Date: Sun, 26 May 2024 13:04:40 +0200 Subject: [PATCH 1093/1212] refactor: stop using github.com/pkg/errors (#10431) --- client/rpc/pin.go | 2 +- core/commands/pubsub.go | 4 ++-- core/node/helpers.go | 2 +- go.mod | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/client/rpc/pin.go b/client/rpc/pin.go index a0469861c..6e8e942ac 100644 --- a/client/rpc/pin.go +++ b/client/rpc/pin.go @@ -3,6 +3,7 @@ package rpc import ( "context" "encoding/json" + "errors" "io" "strings" @@ -10,7 +11,6 @@ import ( "github.com/ipfs/go-cid" iface "github.com/ipfs/kubo/core/coreiface" caopts "github.com/ipfs/kubo/core/coreiface/options" - "github.com/pkg/errors" ) type PinAPI HttpApi diff --git a/core/commands/pubsub.go b/core/commands/pubsub.go index 8f52881a3..d50e651b2 100644 --- a/core/commands/pubsub.go +++ b/core/commands/pubsub.go @@ -2,6 +2,7 @@ package commands import ( "context" + "errors" "fmt" "io" "net/http" @@ -9,7 +10,6 @@ import ( cmdenv "github.com/ipfs/kubo/core/commands/cmdenv" mbase "github.com/multiformats/go-multibase" - "github.com/pkg/errors" cmds "github.com/ipfs/go-ipfs-cmds" options "github.com/ipfs/kubo/core/coreiface/options" @@ -351,7 +351,7 @@ func urlArgsDecoder(req *cmds.Request, env cmds.Environment) error { for n, arg := range req.Arguments { encoding, data, err := mbase.Decode(arg) if err != nil { - return errors.Wrap(err, "URL arg must be multibase encoded") + return fmt.Errorf("URL arg must be multibase encoded: %w", err) } // Enforce URL-safe encoding is used for data passed via URL arguments diff --git a/core/node/helpers.go b/core/node/helpers.go index 6e6cb2920..63e76ead7 100644 --- a/core/node/helpers.go +++ b/core/node/helpers.go @@ -2,9 +2,9 @@ package node import ( "context" + "errors" "github.com/jbenet/goprocess" - "github.com/pkg/errors" "go.uber.org/fx" ) diff --git a/go.mod b/go.mod index 436af2ef0..88b0653b1 100644 --- a/go.mod +++ b/go.mod @@ -65,7 +65,6 @@ require ( github.com/multiformats/go-multihash v0.2.3 github.com/opentracing/opentracing-go v1.2.0 github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 - github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.19.1 github.com/stretchr/testify v1.9.0 github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 @@ -197,6 +196,7 @@ require ( github.com/pion/transport/v2 v2.2.4 // indirect github.com/pion/turn/v2 v2.1.4 // indirect github.com/pion/webrtc/v3 v3.2.23 // indirect + github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/polydawn/refmt v0.89.0 // indirect github.com/prometheus/client_model v0.6.1 // indirect From b79cedec73012144f42a75eacfb957370c96325e Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Mon, 27 May 2024 10:16:13 +0200 Subject: [PATCH 1094/1212] chore: libp2p 0.34.1 (#10429) --- core/node/libp2p/rcmgr.go | 22 ++++- docs/examples/kubo-as-a-library/go.mod | 38 ++++---- docs/examples/kubo-as-a-library/go.sum | 129 +++++++++++-------------- go.mod | 38 ++++---- go.sum | 124 +++++++++++------------- test/dependencies/go.mod | 6 +- test/dependencies/go.sum | 56 ++++++++--- 7 files changed, 218 insertions(+), 195 deletions(-) diff --git a/core/node/libp2p/rcmgr.go b/core/node/libp2p/rcmgr.go index 8ec83601b..2a7d67575 100644 --- a/core/node/libp2p/rcmgr.go +++ b/core/node/libp2p/rcmgr.go @@ -74,7 +74,27 @@ filled in with autocomputed defaults.`) return nil, opts, err } - ropts := []rcmgr.Option{rcmgr.WithMetrics(createRcmgrMetrics()), rcmgr.WithTraceReporter(str)} + ropts := []rcmgr.Option{ + rcmgr.WithMetrics(createRcmgrMetrics()), + rcmgr.WithTraceReporter(str), + rcmgr.WithLimitPeersPerCIDR( + []rcmgr.ConnLimitPerCIDR{ + { + ConnCount: 16, + BitMask: 32, + }, + }, + []rcmgr.ConnLimitPerCIDR{ + { + ConnCount: 16, + BitMask: 56, + }, + { + ConnCount: 8 * 16, + BitMask: 48, + }, + }), + } if len(cfg.ResourceMgr.Allowlist) > 0 { var mas []multiaddr.Multiaddr diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 0d60a029a..2ecefe11d 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -9,10 +9,10 @@ toolchain go1.22.0 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.19.1-0.20240516085407-f4fe8997dcbe + github.com/ipfs/boxo v0.19.1-0.20240523201107-09b0013e1c3e github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 - github.com/libp2p/go-libp2p v0.33.2 - github.com/multiformats/go-multiaddr v0.12.3 + github.com/libp2p/go-libp2p v0.34.1 + github.com/multiformats/go-multiaddr v0.12.4 ) require ( @@ -112,7 +112,7 @@ require ( github.com/libp2p/go-libp2p-asn-util v0.4.1 // indirect github.com/libp2p/go-libp2p-kad-dht v0.25.2 // indirect github.com/libp2p/go-libp2p-kbucket v0.6.3 // indirect - github.com/libp2p/go-libp2p-pubsub v0.10.0 // indirect + github.com/libp2p/go-libp2p-pubsub v0.11.0 // indirect github.com/libp2p/go-libp2p-pubsub-router v0.6.0 // indirect github.com/libp2p/go-libp2p-record v0.2.0 // indirect github.com/libp2p/go-libp2p-routing-helpers v0.7.3 // indirect @@ -146,22 +146,22 @@ require ( github.com/openzipkin/zipkin-go v0.4.3 // indirect github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 // indirect - github.com/pion/datachannel v1.5.5 // indirect - github.com/pion/dtls/v2 v2.2.8 // indirect - github.com/pion/ice/v2 v2.3.11 // indirect - github.com/pion/interceptor v0.1.25 // indirect + github.com/pion/datachannel v1.5.6 // indirect + github.com/pion/dtls/v2 v2.2.11 // indirect + github.com/pion/ice/v2 v2.3.24 // indirect + github.com/pion/interceptor v0.1.29 // indirect github.com/pion/logging v0.2.2 // indirect - github.com/pion/mdns v0.0.9 // indirect + github.com/pion/mdns v0.0.12 // indirect github.com/pion/randutil v0.1.0 // indirect - github.com/pion/rtcp v1.2.13 // indirect - github.com/pion/rtp v1.8.3 // indirect - github.com/pion/sctp v1.8.9 // indirect - github.com/pion/sdp/v3 v3.0.6 // indirect + github.com/pion/rtcp v1.2.14 // indirect + github.com/pion/rtp v1.8.6 // indirect + github.com/pion/sctp v1.8.16 // indirect + github.com/pion/sdp/v3 v3.0.9 // indirect github.com/pion/srtp/v2 v2.0.18 // indirect github.com/pion/stun v0.6.1 // indirect - github.com/pion/transport/v2 v2.2.4 // indirect - github.com/pion/turn/v2 v2.1.4 // indirect - github.com/pion/webrtc/v3 v3.2.23 // indirect + github.com/pion/transport/v2 v2.2.5 // indirect + github.com/pion/turn/v2 v2.1.6 // indirect + github.com/pion/webrtc/v3 v3.2.40 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/polydawn/refmt v0.89.0 // indirect @@ -170,8 +170,8 @@ require ( github.com/prometheus/common v0.53.0 // indirect github.com/prometheus/procfs v0.15.0 // indirect github.com/quic-go/qpack v0.4.0 // indirect - github.com/quic-go/quic-go v0.42.0 // indirect - github.com/quic-go/webtransport-go v0.7.0 // indirect + github.com/quic-go/quic-go v0.44.0 // indirect + github.com/quic-go/webtransport-go v0.8.0 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/samber/lo v1.39.0 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect @@ -198,7 +198,7 @@ require ( go.opentelemetry.io/proto/otlp v1.2.0 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/dig v1.17.1 // indirect - go.uber.org/fx v1.20.1 // indirect + go.uber.org/fx v1.21.1 // indirect go.uber.org/mock v0.4.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 116f7fc51..21a93f6ad 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -154,7 +154,6 @@ github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0= @@ -191,8 +190,6 @@ github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvq github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= @@ -208,7 +205,6 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ 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= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= @@ -268,8 +264,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.19.1-0.20240516085407-f4fe8997dcbe h1:GoWqF8evx/xOnjVQEFT6FgMKVZBcqPCGeqY3h2m9r7A= -github.com/ipfs/boxo v0.19.1-0.20240516085407-f4fe8997dcbe/go.mod h1:7pXWoypZuknFVLqeLy7UraFV4NYBA0ufGBzVHcTZ188= +github.com/ipfs/boxo v0.19.1-0.20240523201107-09b0013e1c3e h1:ehlWR5Qj4AWORjKq4Cyl9mBkUTel6ulQ/WIf1t32q1s= +github.com/ipfs/boxo v0.19.1-0.20240523201107-09b0013e1c3e/go.mod h1:mwttn53Eibgska2DhVIj7ln3UViq7MVHRxOMb+ehSDM= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= @@ -429,8 +425,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.33.2 h1:vCdwnFxoGOXMKmaGHlDSnL4bM3fQeW8pgIa9DECnb40= -github.com/libp2p/go-libp2p v0.33.2/go.mod h1:zTeppLuCvUIkT118pFVzA8xzP/p2dJYOMApCkFh0Yww= +github.com/libp2p/go-libp2p v0.34.1 h1:fxn9vyLo7vJcXQRNvdRbyPjbzuQgi2UiqC8hEbn8a18= +github.com/libp2p/go-libp2p v0.34.1/go.mod h1:snyJQix4ET6Tj+LeI0VPjjxTtdWpeOhYt5lEY0KirkQ= github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94= github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= @@ -441,8 +437,8 @@ github.com/libp2p/go-libp2p-kbucket v0.3.1/go.mod h1:oyjT5O7tS9CQurok++ERgc46YLw github.com/libp2p/go-libp2p-kbucket v0.6.3 h1:p507271wWzpy2f1XxPzCQG9NiN6R6lHL9GiSErbQQo0= github.com/libp2p/go-libp2p-kbucket v0.6.3/go.mod h1:RCseT7AH6eJWxxk2ol03xtP9pEHetYSPXOaJnOiD8i0= github.com/libp2p/go-libp2p-peerstore v0.1.4/go.mod h1:+4BDbDiiKf4PzpANZDAT+knVdLxvqh7hXOujessqdzs= -github.com/libp2p/go-libp2p-pubsub v0.10.0 h1:wS0S5FlISavMaAbxyQn3dxMOe2eegMfswM471RuHJwA= -github.com/libp2p/go-libp2p-pubsub v0.10.0/go.mod h1:1OxbaT/pFRO5h+Dpze8hdHQ63R0ke55XTs6b6NwLLkw= +github.com/libp2p/go-libp2p-pubsub v0.11.0 h1:+JvS8Kty0OiyUiN0i8H5JbaCgjnJTRnTHe4rU88dLFc= +github.com/libp2p/go-libp2p-pubsub v0.11.0/go.mod h1:QEb+hEV9WL9wCiUAnpY29FZR6W3zK8qYlaml8R4q6gQ= github.com/libp2p/go-libp2p-pubsub-router v0.6.0 h1:D30iKdlqDt5ZmLEYhHELCMRj8b4sFAqrUcshIUvVP/s= github.com/libp2p/go-libp2p-pubsub-router v0.6.0/go.mod h1:FY/q0/RBTKsLA7l4vqC2cbRbOvyDotg8PJQ7j8FDudE= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= @@ -521,8 +517,8 @@ github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a github.com/multiformats/go-multiaddr v0.1.0/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo= github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4= -github.com/multiformats/go-multiaddr v0.12.3 h1:hVBXvPRcKG0w80VinQ23P5t7czWgg65BmIvQKjDydU8= -github.com/multiformats/go-multiaddr v0.12.3/go.mod h1:sBXrNzucqkFJhvKOiwwLyqamGa/P5EIXNPLovyhQCII= +github.com/multiformats/go-multiaddr v0.12.4 h1:rrKqpY9h+n80EwhhC/kkcunCZZ7URIF8yN1WEUt2Hvc= +github.com/multiformats/go-multiaddr v0.12.4/go.mod h1:sBXrNzucqkFJhvKOiwwLyqamGa/P5EIXNPLovyhQCII= github.com/multiformats/go-multiaddr-dns v0.3.0/go.mod h1:mNzQ4eTGDg0ll1N9jKPOUogZPoJ30W8a7zk66FQPpdQ= github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A= github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk= @@ -555,13 +551,12 @@ github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOEL github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= -github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= -github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY= +github.com/nxadm/tail v1.4.11/go.mod h1:OTaG3NK980DZzxbRq6lEuzgU+mug70nY11sMd4JXXHc= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= -github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/ginkgo/v2 v2.17.3 h1:oJcvKpIb7/8uLpDDtnQuf18xVnwKp8DTD7DQ6gTd/MU= @@ -569,7 +564,6 @@ github.com/onsi/ginkgo/v2 v2.17.3/go.mod h1:nP2DPOQoNsQmsVyv5rDA8JkXQoCs6goXIvr/ github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.33.0 h1:snPCflnZrpMsy94p4lXVEkHo12lmPnc3vY5XBbreexE= github.com/onsi/gomega v1.33.0/go.mod h1:+925n5YtiFsLzzafLUHzVMBpvvRAzrydIBiSIxjX3wY= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= @@ -587,53 +581,50 @@ github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhM github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 h1:1/WtZae0yGtPq+TI6+Tv1WTxkukpXeMlviSxvL7SRgk= github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9/go.mod h1:x3N5drFsm2uilKKuuYo6LdyD8vZAW55sH/9w+pbo1sw= -github.com/pion/datachannel v1.5.5 h1:10ef4kwdjije+M9d7Xm9im2Y3O6A6ccQb0zcqZcJew8= -github.com/pion/datachannel v1.5.5/go.mod h1:iMz+lECmfdCMqFRhXhcA/219B0SQlbpoR2V118yimL0= +github.com/pion/datachannel v1.5.6 h1:1IxKJntfSlYkpUj8LlYRSWpYiTTC02nUrOE8T3DqGeg= +github.com/pion/datachannel v1.5.6/go.mod h1:1eKT6Q85pRnr2mHiWHxJwO50SfZRtWHTsNIVb/NfGW4= github.com/pion/dtls/v2 v2.2.7/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s= -github.com/pion/dtls/v2 v2.2.8 h1:BUroldfiIbV9jSnC6cKOMnyiORRWrWWpV11JUyEu5OA= -github.com/pion/dtls/v2 v2.2.8/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s= -github.com/pion/ice/v2 v2.3.11 h1:rZjVmUwyT55cmN8ySMpL7rsS8KYsJERsrxJLLxpKhdw= -github.com/pion/ice/v2 v2.3.11/go.mod h1:hPcLC3kxMa+JGRzMHqQzjoSj3xtE9F+eoncmXLlCL4E= -github.com/pion/interceptor v0.1.25 h1:pwY9r7P6ToQ3+IF0bajN0xmk/fNw/suTgaTdlwTDmhc= -github.com/pion/interceptor v0.1.25/go.mod h1:wkbPYAak5zKsfpVDYMtEfWEy8D4zL+rpxCxPImLOg3Y= +github.com/pion/dtls/v2 v2.2.11 h1:9U/dpCYl1ySttROPWJgqWKEylUdT0fXp/xst6JwY5Ks= +github.com/pion/dtls/v2 v2.2.11/go.mod h1:d9SYc9fch0CqK90mRk1dC7AkzzpwJj6u2GU3u+9pqFE= +github.com/pion/ice/v2 v2.3.24 h1:RYgzhH/u5lH0XO+ABatVKCtRd+4U1GEaCXSMjNr13tI= +github.com/pion/ice/v2 v2.3.24/go.mod h1:KXJJcZK7E8WzrBEYnV4UtqEZsGeWfHxsNqhVcVvgjxw= +github.com/pion/interceptor v0.1.29 h1:39fsnlP1U8gw2JzOFWdfCU82vHvhW9o0rZnZF56wF+M= +github.com/pion/interceptor v0.1.29/go.mod h1:ri+LGNjRUc5xUNtDEPzfdkmSqISixVTBF/z/Zms/6T4= github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY= github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms= -github.com/pion/mdns v0.0.8/go.mod h1:hYE72WX8WDveIhg7fmXgMKivD3Puklk0Ymzog0lSyaI= -github.com/pion/mdns v0.0.9 h1:7Ue5KZsqq8EuqStnpPWV33vYYEH0+skdDN5L7EiEsI4= -github.com/pion/mdns v0.0.9/go.mod h1:2JA5exfxwzXiCihmxpTKgFUpiQws2MnipoPK09vecIc= +github.com/pion/mdns v0.0.12 h1:CiMYlY+O0azojWDmxdNr7ADGrnZ+V6Ilfner+6mSVK8= +github.com/pion/mdns v0.0.12/go.mod h1:VExJjv8to/6Wqm1FXK+Ii/Z9tsVk/F5sD/N70cnYFbk= github.com/pion/randutil v0.1.0 h1:CFG1UdESneORglEsnimhUjf33Rwjubwj6xfiOXBa3mA= github.com/pion/randutil v0.1.0/go.mod h1:XcJrSMMbbMRhASFVOlj/5hQial/Y8oH/HVo7TBZq+j8= -github.com/pion/rtcp v1.2.10/go.mod h1:ztfEwXZNLGyF1oQDttz/ZKIBaeeg/oWbRYqzBM9TL1I= github.com/pion/rtcp v1.2.12/go.mod h1:sn6qjxvnwyAkkPzPULIbVqSKI5Dv54Rv7VG0kNxh9L4= -github.com/pion/rtcp v1.2.13 h1:+EQijuisKwm/8VBs8nWllr0bIndR7Lf7cZG200mpbNo= -github.com/pion/rtcp v1.2.13/go.mod h1:sn6qjxvnwyAkkPzPULIbVqSKI5Dv54Rv7VG0kNxh9L4= -github.com/pion/rtp v1.8.2/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU= -github.com/pion/rtp v1.8.3 h1:VEHxqzSVQxCkKDSHro5/4IUUG1ea+MFdqR2R3xSpNU8= +github.com/pion/rtcp v1.2.14 h1:KCkGV3vJ+4DAJmvP0vaQShsb0xkRfWkO540Gy102KyE= +github.com/pion/rtcp v1.2.14/go.mod h1:sn6qjxvnwyAkkPzPULIbVqSKI5Dv54Rv7VG0kNxh9L4= github.com/pion/rtp v1.8.3/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU= -github.com/pion/sctp v1.8.5/go.mod h1:SUFFfDpViyKejTAdwD1d/HQsCu+V/40cCs2nZIvC3s0= -github.com/pion/sctp v1.8.8/go.mod h1:igF9nZBrjh5AtmKc7U30jXltsFHicFCXSmWA2GWRaWs= -github.com/pion/sctp v1.8.9 h1:TP5ZVxV5J7rz7uZmbyvnUvsn7EJ2x/5q9uhsTtXbI3g= -github.com/pion/sctp v1.8.9/go.mod h1:cMLT45jqw3+jiJCrtHVwfQLnfR0MGZ4rgOJwUOIqLkI= -github.com/pion/sdp/v3 v3.0.6 h1:WuDLhtuFUUVpTfus9ILC4HRyHsW6TdugjEX/QY9OiUw= -github.com/pion/sdp/v3 v3.0.6/go.mod h1:iiFWFpQO8Fy3S5ldclBkpXqmWy02ns78NOKoLLL0YQw= +github.com/pion/rtp v1.8.6 h1:MTmn/b0aWWsAzux2AmP8WGllusBVw4NPYPVFFd7jUPw= +github.com/pion/rtp v1.8.6/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU= +github.com/pion/sctp v1.8.13/go.mod h1:YKSgO/bO/6aOMP9LCie1DuD7m+GamiK2yIiPM6vH+GA= +github.com/pion/sctp v1.8.16 h1:PKrMs+o9EMLRvFfXq59WFsC+V8mN1wnKzqrv+3D/gYY= +github.com/pion/sctp v1.8.16/go.mod h1:P6PbDVA++OJMrVNg2AL3XtYHV4uD6dvfyOovCgMs0PE= +github.com/pion/sdp/v3 v3.0.9 h1:pX++dCHoHUwq43kuwf3PyJfHlwIj4hXA7Vrifiq0IJY= +github.com/pion/sdp/v3 v3.0.9/go.mod h1:B5xmvENq5IXJimIO4zfp6LAe1fD9N+kFv+V/1lOdz8M= github.com/pion/srtp/v2 v2.0.18 h1:vKpAXfawO9RtTRKZJbG4y0v1b11NZxQnxRl85kGuUlo= github.com/pion/srtp/v2 v2.0.18/go.mod h1:0KJQjA99A6/a0DOVTu1PhDSw0CXF2jTkqOoMg3ODqdA= github.com/pion/stun v0.6.1 h1:8lp6YejULeHBF8NmV8e2787BogQhduZugh5PdhDyyN4= github.com/pion/stun v0.6.1/go.mod h1:/hO7APkX4hZKu/D0f2lHzNyvdkTGtIy3NDmLR7kSz/8= -github.com/pion/transport v0.14.1 h1:XSM6olwW+o8J4SCmOBb/BpwZypkHeyM0PGFCxNQBr40= -github.com/pion/transport v0.14.1/go.mod h1:4tGmbk00NeYA3rUa9+n+dzCCoKkcy3YlYb99Jn2fNnI= github.com/pion/transport/v2 v2.2.1/go.mod h1:cXXWavvCnFF6McHTft3DWS9iic2Mftcz1Aq29pGcU5g= github.com/pion/transport/v2 v2.2.2/go.mod h1:OJg3ojoBJopjEeECq2yJdXH9YVrUJ1uQ++NjXLOUorc= github.com/pion/transport/v2 v2.2.3/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0= -github.com/pion/transport/v2 v2.2.4 h1:41JJK6DZQYSeVLxILA2+F4ZkKb4Xd/tFJZRFZQ9QAlo= github.com/pion/transport/v2 v2.2.4/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0= -github.com/pion/transport/v3 v3.0.1 h1:gDTlPJwROfSfz6QfSi0ZmeCSkFcnWWiiR9ES0ouANiM= +github.com/pion/transport/v2 v2.2.5 h1:iyi25i/21gQck4hfRhomF6SktmUQjRsRW4WJdhfc3Kc= +github.com/pion/transport/v2 v2.2.5/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0= github.com/pion/transport/v3 v3.0.1/go.mod h1:UY7kiITrlMv7/IKgd5eTUcaahZx5oUN3l9SzK5f5xE0= +github.com/pion/transport/v3 v3.0.2 h1:r+40RJR25S9w3jbA6/5uEPTzcdn7ncyU44RWCbHkLg4= +github.com/pion/transport/v3 v3.0.2/go.mod h1:nIToODoOlb5If2jF9y2Igfx3PFYWfuXi37m0IlWa/D0= github.com/pion/turn/v2 v2.1.3/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY= -github.com/pion/turn/v2 v2.1.4 h1:2xn8rduI5W6sCZQkEnIUDAkrBQNl2eYIBCHMZ3QMmP8= -github.com/pion/turn/v2 v2.1.4/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY= -github.com/pion/webrtc/v3 v3.2.23 h1:GbqEuxBbVLFhXk0GwxKAoaIJYiEa9TyoZPEZC+2HZxM= -github.com/pion/webrtc/v3 v3.2.23/go.mod h1:1CaT2fcZzZ6VZA+O1i9yK2DU4EOcXVvSbWG9pr5jefs= +github.com/pion/turn/v2 v2.1.6 h1:Xr2niVsiPTB0FPtt+yAWKFUkU1eotQbGgpTIld4x1Gc= +github.com/pion/turn/v2 v2.1.6/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY= +github.com/pion/webrtc/v3 v3.2.40 h1:Wtfi6AZMQg+624cvCXUuSmrKWepSB7zfgYDOYqsSOVU= +github.com/pion/webrtc/v3 v3.2.40/go.mod h1:M1RAe3TNTD1tzyvqHrbVODfwdPGSXOUo/OgpoGGJqFY= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -657,10 +648,10 @@ github.com/prometheus/procfs v0.15.0 h1:A82kmvXJq2jTu5YUhSGNlYoxh85zLnKgPz4bMZgI github.com/prometheus/procfs v0.15.0/go.mod h1:Y0RJ/Y5g5wJpkTisOtqwDSo4HwhGmLB4VQSw2sQJLHk= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= -github.com/quic-go/quic-go v0.42.0 h1:uSfdap0eveIl8KXnipv9K7nlwZ5IqLlYOpJ58u5utpM= -github.com/quic-go/quic-go v0.42.0/go.mod h1:132kz4kL3F9vxhW3CtQJLDVwcFe5wdWeJXXijhsO57M= -github.com/quic-go/webtransport-go v0.7.0 h1:dv9wDD9Rd0cuSRLRHPrOX9fSY8QBpdXW4Ls85WXMKqE= -github.com/quic-go/webtransport-go v0.7.0/go.mod h1:MX3nFXrcXkdzblIfOXFZ5lVCZhn+VbMMspOweP1HoXE= +github.com/quic-go/quic-go v0.44.0 h1:So5wOr7jyO4vzL2sd8/pD9Kesciv91zSk8BoFngItQ0= +github.com/quic-go/quic-go v0.44.0/go.mod h1:z4cx/9Ny9UtGITIPzmPTXh1ULfOyWh4qGQlpnPcWmek= +github.com/quic-go/webtransport-go v0.8.0 h1:HxSrwun11U+LlmwpgM1kEqIqH90IT4N8auv/cD7QFJg= +github.com/quic-go/webtransport-go v0.8.0/go.mod h1:N99tjprW432Ut5ONql/aUhSLT0YVSlwHohQsuac9WaM= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= @@ -672,7 +663,6 @@ github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd/go.mod h1:hPqNNc0+uJM6H+SuU8sEs5K5IQeKccPqeSjfgcKGgPk= github.com/samber/lo v1.39.0 h1:4gTz1wUhNYLhFSKl6O+8peW0v2F4BCY034GRpU9WnuA= github.com/samber/lo v1.39.0/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA= -github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY= github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM= @@ -728,7 +718,6 @@ github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= @@ -816,8 +805,8 @@ go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= -go.uber.org/fx v1.20.1 h1:zVwVQGS8zYvhh9Xxcu4w1M6ESyeMzebzj2NbSayZ4Mk= -go.uber.org/fx v1.20.1/go.mod h1:iSYNbHf2y55acNCwCXKx7LbWb5WG1Bnue5RDXz1OREg= +go.uber.org/fx v1.21.1 h1:RqBh3cYdzZS0uqwVeEjOX2p73dddLpym315myy/Bpb0= +go.uber.org/fx v1.21.1/go.mod h1:HT2M7d7RHo+ebKGh9NRcrsrHHfpZ60nW3QRubMRfv48= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= @@ -857,10 +846,11 @@ golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWP golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= -golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= -golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= +golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= +golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -926,17 +916,16 @@ golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210423184538-5f58ad60dda6/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ= golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= -golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= +golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -994,7 +983,6 @@ golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1006,8 +994,6 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1015,20 +1001,22 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= -golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo= golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= -golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= +golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= +golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= +golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1036,13 +1024,11 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1083,7 +1069,6 @@ golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapK golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= @@ -1161,8 +1146,6 @@ google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/go.mod b/go.mod index 88b0653b1..f27c91f25 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,7 @@ require ( github.com/hashicorp/go-multierror v1.1.1 github.com/ipfs-shipyard/nopfs v0.0.12 github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c - github.com/ipfs/boxo v0.19.1-0.20240516085407-f4fe8997dcbe + github.com/ipfs/boxo v0.19.1-0.20240523201107-09b0013e1c3e github.com/ipfs/go-block-format v0.2.0 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 @@ -47,18 +47,18 @@ require ( github.com/jbenet/goprocess v0.1.4 github.com/julienschmidt/httprouter v1.3.0 github.com/libp2p/go-doh-resolver v0.4.0 - github.com/libp2p/go-libp2p v0.33.2 + github.com/libp2p/go-libp2p v0.34.1 github.com/libp2p/go-libp2p-http v0.5.0 github.com/libp2p/go-libp2p-kad-dht v0.25.2 github.com/libp2p/go-libp2p-kbucket v0.6.3 - github.com/libp2p/go-libp2p-pubsub v0.10.0 + github.com/libp2p/go-libp2p-pubsub v0.11.0 github.com/libp2p/go-libp2p-pubsub-router v0.6.0 github.com/libp2p/go-libp2p-record v0.2.0 github.com/libp2p/go-libp2p-routing-helpers v0.7.3 github.com/libp2p/go-libp2p-testing v0.12.0 github.com/libp2p/go-socket-activation v0.1.0 github.com/mitchellh/go-homedir v1.1.0 - github.com/multiformats/go-multiaddr v0.12.3 + github.com/multiformats/go-multiaddr v0.12.4 github.com/multiformats/go-multiaddr-dns v0.3.1 github.com/multiformats/go-multibase v0.2.0 github.com/multiformats/go-multicodec v0.9.0 @@ -79,7 +79,7 @@ require ( go.opentelemetry.io/otel/sdk v1.26.0 go.opentelemetry.io/otel/trace v1.26.0 go.uber.org/dig v1.17.1 - go.uber.org/fx v1.20.1 + go.uber.org/fx v1.21.1 go.uber.org/multierr v1.11.0 go.uber.org/zap v1.27.0 golang.org/x/crypto v0.23.0 @@ -180,22 +180,22 @@ require ( github.com/opencontainers/runtime-spec v1.2.0 // indirect github.com/openzipkin/zipkin-go v0.4.3 // indirect github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 // indirect - github.com/pion/datachannel v1.5.5 // indirect - github.com/pion/dtls/v2 v2.2.8 // indirect - github.com/pion/ice/v2 v2.3.11 // indirect - github.com/pion/interceptor v0.1.25 // indirect + github.com/pion/datachannel v1.5.6 // indirect + github.com/pion/dtls/v2 v2.2.11 // indirect + github.com/pion/ice/v2 v2.3.24 // indirect + github.com/pion/interceptor v0.1.29 // indirect github.com/pion/logging v0.2.2 // indirect - github.com/pion/mdns v0.0.9 // indirect + github.com/pion/mdns v0.0.12 // indirect github.com/pion/randutil v0.1.0 // indirect - github.com/pion/rtcp v1.2.13 // indirect - github.com/pion/rtp v1.8.3 // indirect - github.com/pion/sctp v1.8.9 // indirect - github.com/pion/sdp/v3 v3.0.6 // indirect + github.com/pion/rtcp v1.2.14 // indirect + github.com/pion/rtp v1.8.6 // indirect + github.com/pion/sctp v1.8.16 // indirect + github.com/pion/sdp/v3 v3.0.9 // indirect github.com/pion/srtp/v2 v2.0.18 // indirect github.com/pion/stun v0.6.1 // indirect - github.com/pion/transport/v2 v2.2.4 // indirect - github.com/pion/turn/v2 v2.1.4 // indirect - github.com/pion/webrtc/v3 v3.2.23 // indirect + github.com/pion/transport/v2 v2.2.5 // indirect + github.com/pion/turn/v2 v2.1.6 // indirect + github.com/pion/webrtc/v3 v3.2.40 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/polydawn/refmt v0.89.0 // indirect @@ -204,8 +204,8 @@ require ( github.com/prometheus/procfs v0.15.0 // indirect github.com/prometheus/statsd_exporter v0.22.7 // indirect github.com/quic-go/qpack v0.4.0 // indirect - github.com/quic-go/quic-go v0.42.0 // indirect - github.com/quic-go/webtransport-go v0.7.0 // indirect + github.com/quic-go/quic-go v0.44.0 // indirect + github.com/quic-go/webtransport-go v0.8.0 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/rs/cors v1.10.1 // indirect github.com/samber/lo v1.39.0 // indirect diff --git a/go.sum b/go.sum index 570a63772..53216bf8b 100644 --- a/go.sum +++ b/go.sum @@ -201,7 +201,6 @@ github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ4 github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0= @@ -329,8 +328,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.19.1-0.20240516085407-f4fe8997dcbe h1:GoWqF8evx/xOnjVQEFT6FgMKVZBcqPCGeqY3h2m9r7A= -github.com/ipfs/boxo v0.19.1-0.20240516085407-f4fe8997dcbe/go.mod h1:7pXWoypZuknFVLqeLy7UraFV4NYBA0ufGBzVHcTZ188= +github.com/ipfs/boxo v0.19.1-0.20240523201107-09b0013e1c3e h1:ehlWR5Qj4AWORjKq4Cyl9mBkUTel6ulQ/WIf1t32q1s= +github.com/ipfs/boxo v0.19.1-0.20240523201107-09b0013e1c3e/go.mod h1:mwttn53Eibgska2DhVIj7ln3UViq7MVHRxOMb+ehSDM= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= @@ -507,8 +506,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.33.2 h1:vCdwnFxoGOXMKmaGHlDSnL4bM3fQeW8pgIa9DECnb40= -github.com/libp2p/go-libp2p v0.33.2/go.mod h1:zTeppLuCvUIkT118pFVzA8xzP/p2dJYOMApCkFh0Yww= +github.com/libp2p/go-libp2p v0.34.1 h1:fxn9vyLo7vJcXQRNvdRbyPjbzuQgi2UiqC8hEbn8a18= +github.com/libp2p/go-libp2p v0.34.1/go.mod h1:snyJQix4ET6Tj+LeI0VPjjxTtdWpeOhYt5lEY0KirkQ= github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94= github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= @@ -523,8 +522,8 @@ github.com/libp2p/go-libp2p-kbucket v0.3.1/go.mod h1:oyjT5O7tS9CQurok++ERgc46YLw github.com/libp2p/go-libp2p-kbucket v0.6.3 h1:p507271wWzpy2f1XxPzCQG9NiN6R6lHL9GiSErbQQo0= github.com/libp2p/go-libp2p-kbucket v0.6.3/go.mod h1:RCseT7AH6eJWxxk2ol03xtP9pEHetYSPXOaJnOiD8i0= github.com/libp2p/go-libp2p-peerstore v0.1.4/go.mod h1:+4BDbDiiKf4PzpANZDAT+knVdLxvqh7hXOujessqdzs= -github.com/libp2p/go-libp2p-pubsub v0.10.0 h1:wS0S5FlISavMaAbxyQn3dxMOe2eegMfswM471RuHJwA= -github.com/libp2p/go-libp2p-pubsub v0.10.0/go.mod h1:1OxbaT/pFRO5h+Dpze8hdHQ63R0ke55XTs6b6NwLLkw= +github.com/libp2p/go-libp2p-pubsub v0.11.0 h1:+JvS8Kty0OiyUiN0i8H5JbaCgjnJTRnTHe4rU88dLFc= +github.com/libp2p/go-libp2p-pubsub v0.11.0/go.mod h1:QEb+hEV9WL9wCiUAnpY29FZR6W3zK8qYlaml8R4q6gQ= github.com/libp2p/go-libp2p-pubsub-router v0.6.0 h1:D30iKdlqDt5ZmLEYhHELCMRj8b4sFAqrUcshIUvVP/s= github.com/libp2p/go-libp2p-pubsub-router v0.6.0/go.mod h1:FY/q0/RBTKsLA7l4vqC2cbRbOvyDotg8PJQ7j8FDudE= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= @@ -618,8 +617,8 @@ github.com/multiformats/go-multiaddr v0.1.0/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lg github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo= github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4= github.com/multiformats/go-multiaddr v0.4.0/go.mod h1:YcpyLH8ZPudLxQlemYBPhSm0/oCXAT8Z4mzFpyoPyRc= -github.com/multiformats/go-multiaddr v0.12.3 h1:hVBXvPRcKG0w80VinQ23P5t7czWgg65BmIvQKjDydU8= -github.com/multiformats/go-multiaddr v0.12.3/go.mod h1:sBXrNzucqkFJhvKOiwwLyqamGa/P5EIXNPLovyhQCII= +github.com/multiformats/go-multiaddr v0.12.4 h1:rrKqpY9h+n80EwhhC/kkcunCZZ7URIF8yN1WEUt2Hvc= +github.com/multiformats/go-multiaddr v0.12.4/go.mod h1:sBXrNzucqkFJhvKOiwwLyqamGa/P5EIXNPLovyhQCII= github.com/multiformats/go-multiaddr-dns v0.3.0/go.mod h1:mNzQ4eTGDg0ll1N9jKPOUogZPoJ30W8a7zk66FQPpdQ= github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A= github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk= @@ -654,13 +653,12 @@ github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRW github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= -github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= -github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY= +github.com/nxadm/tail v1.4.11/go.mod h1:OTaG3NK980DZzxbRq6lEuzgU+mug70nY11sMd4JXXHc= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= -github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/ginkgo/v2 v2.17.3 h1:oJcvKpIb7/8uLpDDtnQuf18xVnwKp8DTD7DQ6gTd/MU= @@ -668,7 +666,6 @@ github.com/onsi/ginkgo/v2 v2.17.3/go.mod h1:nP2DPOQoNsQmsVyv5rDA8JkXQoCs6goXIvr/ github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.33.0 h1:snPCflnZrpMsy94p4lXVEkHo12lmPnc3vY5XBbreexE= github.com/onsi/gomega v1.33.0/go.mod h1:+925n5YtiFsLzzafLUHzVMBpvvRAzrydIBiSIxjX3wY= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= @@ -686,53 +683,50 @@ github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhM github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 h1:1/WtZae0yGtPq+TI6+Tv1WTxkukpXeMlviSxvL7SRgk= github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9/go.mod h1:x3N5drFsm2uilKKuuYo6LdyD8vZAW55sH/9w+pbo1sw= -github.com/pion/datachannel v1.5.5 h1:10ef4kwdjije+M9d7Xm9im2Y3O6A6ccQb0zcqZcJew8= -github.com/pion/datachannel v1.5.5/go.mod h1:iMz+lECmfdCMqFRhXhcA/219B0SQlbpoR2V118yimL0= +github.com/pion/datachannel v1.5.6 h1:1IxKJntfSlYkpUj8LlYRSWpYiTTC02nUrOE8T3DqGeg= +github.com/pion/datachannel v1.5.6/go.mod h1:1eKT6Q85pRnr2mHiWHxJwO50SfZRtWHTsNIVb/NfGW4= github.com/pion/dtls/v2 v2.2.7/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s= -github.com/pion/dtls/v2 v2.2.8 h1:BUroldfiIbV9jSnC6cKOMnyiORRWrWWpV11JUyEu5OA= -github.com/pion/dtls/v2 v2.2.8/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s= -github.com/pion/ice/v2 v2.3.11 h1:rZjVmUwyT55cmN8ySMpL7rsS8KYsJERsrxJLLxpKhdw= -github.com/pion/ice/v2 v2.3.11/go.mod h1:hPcLC3kxMa+JGRzMHqQzjoSj3xtE9F+eoncmXLlCL4E= -github.com/pion/interceptor v0.1.25 h1:pwY9r7P6ToQ3+IF0bajN0xmk/fNw/suTgaTdlwTDmhc= -github.com/pion/interceptor v0.1.25/go.mod h1:wkbPYAak5zKsfpVDYMtEfWEy8D4zL+rpxCxPImLOg3Y= +github.com/pion/dtls/v2 v2.2.11 h1:9U/dpCYl1ySttROPWJgqWKEylUdT0fXp/xst6JwY5Ks= +github.com/pion/dtls/v2 v2.2.11/go.mod h1:d9SYc9fch0CqK90mRk1dC7AkzzpwJj6u2GU3u+9pqFE= +github.com/pion/ice/v2 v2.3.24 h1:RYgzhH/u5lH0XO+ABatVKCtRd+4U1GEaCXSMjNr13tI= +github.com/pion/ice/v2 v2.3.24/go.mod h1:KXJJcZK7E8WzrBEYnV4UtqEZsGeWfHxsNqhVcVvgjxw= +github.com/pion/interceptor v0.1.29 h1:39fsnlP1U8gw2JzOFWdfCU82vHvhW9o0rZnZF56wF+M= +github.com/pion/interceptor v0.1.29/go.mod h1:ri+LGNjRUc5xUNtDEPzfdkmSqISixVTBF/z/Zms/6T4= github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY= github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms= -github.com/pion/mdns v0.0.8/go.mod h1:hYE72WX8WDveIhg7fmXgMKivD3Puklk0Ymzog0lSyaI= -github.com/pion/mdns v0.0.9 h1:7Ue5KZsqq8EuqStnpPWV33vYYEH0+skdDN5L7EiEsI4= -github.com/pion/mdns v0.0.9/go.mod h1:2JA5exfxwzXiCihmxpTKgFUpiQws2MnipoPK09vecIc= +github.com/pion/mdns v0.0.12 h1:CiMYlY+O0azojWDmxdNr7ADGrnZ+V6Ilfner+6mSVK8= +github.com/pion/mdns v0.0.12/go.mod h1:VExJjv8to/6Wqm1FXK+Ii/Z9tsVk/F5sD/N70cnYFbk= github.com/pion/randutil v0.1.0 h1:CFG1UdESneORglEsnimhUjf33Rwjubwj6xfiOXBa3mA= github.com/pion/randutil v0.1.0/go.mod h1:XcJrSMMbbMRhASFVOlj/5hQial/Y8oH/HVo7TBZq+j8= -github.com/pion/rtcp v1.2.10/go.mod h1:ztfEwXZNLGyF1oQDttz/ZKIBaeeg/oWbRYqzBM9TL1I= github.com/pion/rtcp v1.2.12/go.mod h1:sn6qjxvnwyAkkPzPULIbVqSKI5Dv54Rv7VG0kNxh9L4= -github.com/pion/rtcp v1.2.13 h1:+EQijuisKwm/8VBs8nWllr0bIndR7Lf7cZG200mpbNo= -github.com/pion/rtcp v1.2.13/go.mod h1:sn6qjxvnwyAkkPzPULIbVqSKI5Dv54Rv7VG0kNxh9L4= -github.com/pion/rtp v1.8.2/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU= -github.com/pion/rtp v1.8.3 h1:VEHxqzSVQxCkKDSHro5/4IUUG1ea+MFdqR2R3xSpNU8= +github.com/pion/rtcp v1.2.14 h1:KCkGV3vJ+4DAJmvP0vaQShsb0xkRfWkO540Gy102KyE= +github.com/pion/rtcp v1.2.14/go.mod h1:sn6qjxvnwyAkkPzPULIbVqSKI5Dv54Rv7VG0kNxh9L4= github.com/pion/rtp v1.8.3/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU= -github.com/pion/sctp v1.8.5/go.mod h1:SUFFfDpViyKejTAdwD1d/HQsCu+V/40cCs2nZIvC3s0= -github.com/pion/sctp v1.8.8/go.mod h1:igF9nZBrjh5AtmKc7U30jXltsFHicFCXSmWA2GWRaWs= -github.com/pion/sctp v1.8.9 h1:TP5ZVxV5J7rz7uZmbyvnUvsn7EJ2x/5q9uhsTtXbI3g= -github.com/pion/sctp v1.8.9/go.mod h1:cMLT45jqw3+jiJCrtHVwfQLnfR0MGZ4rgOJwUOIqLkI= -github.com/pion/sdp/v3 v3.0.6 h1:WuDLhtuFUUVpTfus9ILC4HRyHsW6TdugjEX/QY9OiUw= -github.com/pion/sdp/v3 v3.0.6/go.mod h1:iiFWFpQO8Fy3S5ldclBkpXqmWy02ns78NOKoLLL0YQw= +github.com/pion/rtp v1.8.6 h1:MTmn/b0aWWsAzux2AmP8WGllusBVw4NPYPVFFd7jUPw= +github.com/pion/rtp v1.8.6/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU= +github.com/pion/sctp v1.8.13/go.mod h1:YKSgO/bO/6aOMP9LCie1DuD7m+GamiK2yIiPM6vH+GA= +github.com/pion/sctp v1.8.16 h1:PKrMs+o9EMLRvFfXq59WFsC+V8mN1wnKzqrv+3D/gYY= +github.com/pion/sctp v1.8.16/go.mod h1:P6PbDVA++OJMrVNg2AL3XtYHV4uD6dvfyOovCgMs0PE= +github.com/pion/sdp/v3 v3.0.9 h1:pX++dCHoHUwq43kuwf3PyJfHlwIj4hXA7Vrifiq0IJY= +github.com/pion/sdp/v3 v3.0.9/go.mod h1:B5xmvENq5IXJimIO4zfp6LAe1fD9N+kFv+V/1lOdz8M= github.com/pion/srtp/v2 v2.0.18 h1:vKpAXfawO9RtTRKZJbG4y0v1b11NZxQnxRl85kGuUlo= github.com/pion/srtp/v2 v2.0.18/go.mod h1:0KJQjA99A6/a0DOVTu1PhDSw0CXF2jTkqOoMg3ODqdA= github.com/pion/stun v0.6.1 h1:8lp6YejULeHBF8NmV8e2787BogQhduZugh5PdhDyyN4= github.com/pion/stun v0.6.1/go.mod h1:/hO7APkX4hZKu/D0f2lHzNyvdkTGtIy3NDmLR7kSz/8= -github.com/pion/transport v0.14.1 h1:XSM6olwW+o8J4SCmOBb/BpwZypkHeyM0PGFCxNQBr40= -github.com/pion/transport v0.14.1/go.mod h1:4tGmbk00NeYA3rUa9+n+dzCCoKkcy3YlYb99Jn2fNnI= github.com/pion/transport/v2 v2.2.1/go.mod h1:cXXWavvCnFF6McHTft3DWS9iic2Mftcz1Aq29pGcU5g= github.com/pion/transport/v2 v2.2.2/go.mod h1:OJg3ojoBJopjEeECq2yJdXH9YVrUJ1uQ++NjXLOUorc= github.com/pion/transport/v2 v2.2.3/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0= -github.com/pion/transport/v2 v2.2.4 h1:41JJK6DZQYSeVLxILA2+F4ZkKb4Xd/tFJZRFZQ9QAlo= github.com/pion/transport/v2 v2.2.4/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0= -github.com/pion/transport/v3 v3.0.1 h1:gDTlPJwROfSfz6QfSi0ZmeCSkFcnWWiiR9ES0ouANiM= +github.com/pion/transport/v2 v2.2.5 h1:iyi25i/21gQck4hfRhomF6SktmUQjRsRW4WJdhfc3Kc= +github.com/pion/transport/v2 v2.2.5/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0= github.com/pion/transport/v3 v3.0.1/go.mod h1:UY7kiITrlMv7/IKgd5eTUcaahZx5oUN3l9SzK5f5xE0= +github.com/pion/transport/v3 v3.0.2 h1:r+40RJR25S9w3jbA6/5uEPTzcdn7ncyU44RWCbHkLg4= +github.com/pion/transport/v3 v3.0.2/go.mod h1:nIToODoOlb5If2jF9y2Igfx3PFYWfuXi37m0IlWa/D0= github.com/pion/turn/v2 v2.1.3/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY= -github.com/pion/turn/v2 v2.1.4 h1:2xn8rduI5W6sCZQkEnIUDAkrBQNl2eYIBCHMZ3QMmP8= -github.com/pion/turn/v2 v2.1.4/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY= -github.com/pion/webrtc/v3 v3.2.23 h1:GbqEuxBbVLFhXk0GwxKAoaIJYiEa9TyoZPEZC+2HZxM= -github.com/pion/webrtc/v3 v3.2.23/go.mod h1:1CaT2fcZzZ6VZA+O1i9yK2DU4EOcXVvSbWG9pr5jefs= +github.com/pion/turn/v2 v2.1.6 h1:Xr2niVsiPTB0FPtt+yAWKFUkU1eotQbGgpTIld4x1Gc= +github.com/pion/turn/v2 v2.1.6/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY= +github.com/pion/webrtc/v3 v3.2.40 h1:Wtfi6AZMQg+624cvCXUuSmrKWepSB7zfgYDOYqsSOVU= +github.com/pion/webrtc/v3 v3.2.40/go.mod h1:M1RAe3TNTD1tzyvqHrbVODfwdPGSXOUo/OgpoGGJqFY= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -783,10 +777,10 @@ github.com/prometheus/statsd_exporter v0.22.7 h1:7Pji/i2GuhK6Lu7DHrtTkFmNBCudCPT github.com/prometheus/statsd_exporter v0.22.7/go.mod h1:N/TevpjkIh9ccs6nuzY3jQn9dFqnUakOjnEuMPJJJnI= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= -github.com/quic-go/quic-go v0.42.0 h1:uSfdap0eveIl8KXnipv9K7nlwZ5IqLlYOpJ58u5utpM= -github.com/quic-go/quic-go v0.42.0/go.mod h1:132kz4kL3F9vxhW3CtQJLDVwcFe5wdWeJXXijhsO57M= -github.com/quic-go/webtransport-go v0.7.0 h1:dv9wDD9Rd0cuSRLRHPrOX9fSY8QBpdXW4Ls85WXMKqE= -github.com/quic-go/webtransport-go v0.7.0/go.mod h1:MX3nFXrcXkdzblIfOXFZ5lVCZhn+VbMMspOweP1HoXE= +github.com/quic-go/quic-go v0.44.0 h1:So5wOr7jyO4vzL2sd8/pD9Kesciv91zSk8BoFngItQ0= +github.com/quic-go/quic-go v0.44.0/go.mod h1:z4cx/9Ny9UtGITIPzmPTXh1ULfOyWh4qGQlpnPcWmek= +github.com/quic-go/webtransport-go v0.8.0 h1:HxSrwun11U+LlmwpgM1kEqIqH90IT4N8auv/cD7QFJg= +github.com/quic-go/webtransport-go v0.8.0/go.mod h1:N99tjprW432Ut5ONql/aUhSLT0YVSlwHohQsuac9WaM= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= @@ -800,7 +794,6 @@ github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd/go.mod h1:hPqNNc0+uJM6H+SuU8sEs5K5IQeKccPqeSjfgcKGgPk= github.com/samber/lo v1.39.0 h1:4gTz1wUhNYLhFSKl6O+8peW0v2F4BCY034GRpU9WnuA= github.com/samber/lo v1.39.0/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA= -github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY= github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM= @@ -858,7 +851,6 @@ github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= @@ -975,8 +967,8 @@ go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= -go.uber.org/fx v1.20.1 h1:zVwVQGS8zYvhh9Xxcu4w1M6ESyeMzebzj2NbSayZ4Mk= -go.uber.org/fx v1.20.1/go.mod h1:iSYNbHf2y55acNCwCXKx7LbWb5WG1Bnue5RDXz1OREg= +go.uber.org/fx v1.21.1 h1:RqBh3cYdzZS0uqwVeEjOX2p73dddLpym315myy/Bpb0= +go.uber.org/fx v1.21.1/go.mod h1:HT2M7d7RHo+ebKGh9NRcrsrHHfpZ60nW3QRubMRfv48= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= @@ -1016,10 +1008,11 @@ golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWP golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= -golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= -golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= +golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= +golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1102,20 +1095,19 @@ golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210423184538-5f58ad60dda6/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ= golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= -golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= +golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1197,7 +1189,6 @@ golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1214,8 +1205,6 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220708085239-5a0f0661e09d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1223,20 +1212,22 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= -golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo= golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= -golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= +golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= +golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= +golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw= golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1246,13 +1237,11 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1310,7 +1299,6 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 436b013f4..b8ce2fc5a 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -16,7 +16,7 @@ require ( github.com/ipfs/iptb-plugins v0.5.0 github.com/jbenet/go-random v0.0.0-20190219211222-123a90aedc0c github.com/jbenet/go-random-files v0.0.0-20190219210431-31b3f20ebded - github.com/multiformats/go-multiaddr v0.12.3 + github.com/multiformats/go-multiaddr v0.12.4 github.com/multiformats/go-multihash v0.2.3 gotest.tools/gotestsum v0.4.2 ) @@ -105,7 +105,7 @@ require ( github.com/hexops/gotextdiff v1.0.3 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/ipfs/bbloom v0.0.4 // indirect - github.com/ipfs/boxo v0.19.1-0.20240516085407-f4fe8997dcbe // indirect + github.com/ipfs/boxo v0.19.1-0.20240523201107-09b0013e1c3e // indirect github.com/ipfs/go-block-format v0.2.0 // indirect github.com/ipfs/go-cid v0.4.1 // indirect github.com/ipfs/go-datastore v0.6.0 // indirect @@ -135,7 +135,7 @@ require ( github.com/leonklingele/grouper v1.1.1 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/libp2p/go-cidranger v1.1.0 // indirect - github.com/libp2p/go-libp2p v0.33.2 // indirect + github.com/libp2p/go-libp2p v0.34.1 // indirect github.com/libp2p/go-libp2p-asn-util v0.4.1 // indirect github.com/libp2p/go-libp2p-kad-dht v0.25.2 // indirect github.com/libp2p/go-libp2p-kbucket v0.6.3 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 915c834f8..b918942f9 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -363,8 +363,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.19.1-0.20240516085407-f4fe8997dcbe h1:GoWqF8evx/xOnjVQEFT6FgMKVZBcqPCGeqY3h2m9r7A= -github.com/ipfs/boxo v0.19.1-0.20240516085407-f4fe8997dcbe/go.mod h1:7pXWoypZuknFVLqeLy7UraFV4NYBA0ufGBzVHcTZ188= +github.com/ipfs/boxo v0.19.1-0.20240523201107-09b0013e1c3e h1:ehlWR5Qj4AWORjKq4Cyl9mBkUTel6ulQ/WIf1t32q1s= +github.com/ipfs/boxo v0.19.1-0.20240523201107-09b0013e1c3e/go.mod h1:mwttn53Eibgska2DhVIj7ln3UViq7MVHRxOMb+ehSDM= github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs= github.com/ipfs/go-block-format v0.2.0/go.mod h1:+jpL11nFx5A/SPpsoBn6Bzkra/zaArfSmsknbPMYgzM= github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= @@ -481,8 +481,8 @@ github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38y github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.33.2 h1:vCdwnFxoGOXMKmaGHlDSnL4bM3fQeW8pgIa9DECnb40= -github.com/libp2p/go-libp2p v0.33.2/go.mod h1:zTeppLuCvUIkT118pFVzA8xzP/p2dJYOMApCkFh0Yww= +github.com/libp2p/go-libp2p v0.34.1 h1:fxn9vyLo7vJcXQRNvdRbyPjbzuQgi2UiqC8hEbn8a18= +github.com/libp2p/go-libp2p v0.34.1/go.mod h1:snyJQix4ET6Tj+LeI0VPjjxTtdWpeOhYt5lEY0KirkQ= github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94= github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= github.com/libp2p/go-libp2p-kad-dht v0.25.2 h1:FOIk9gHoe4YRWXTu8SY9Z1d0RILol0TrtApsMDPjAVQ= @@ -564,8 +564,8 @@ github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYg github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0= github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4= github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4= -github.com/multiformats/go-multiaddr v0.12.3 h1:hVBXvPRcKG0w80VinQ23P5t7czWgg65BmIvQKjDydU8= -github.com/multiformats/go-multiaddr v0.12.3/go.mod h1:sBXrNzucqkFJhvKOiwwLyqamGa/P5EIXNPLovyhQCII= +github.com/multiformats/go-multiaddr v0.12.4 h1:rrKqpY9h+n80EwhhC/kkcunCZZ7URIF8yN1WEUt2Hvc= +github.com/multiformats/go-multiaddr v0.12.4/go.mod h1:sBXrNzucqkFJhvKOiwwLyqamGa/P5EIXNPLovyhQCII= github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A= github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk= github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E= @@ -620,6 +620,38 @@ github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3v github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pelletier/go-toml/v2 v2.0.5 h1:ipoSadvV8oGUjnUbMub59IDPPwfxF694nG/jwbMiyQg= github.com/pelletier/go-toml/v2 v2.0.5/go.mod h1:OMHamSCAODeSsVrwwvcJOaoN0LIUIaFVNZzmWyNfXas= +github.com/pion/datachannel v1.5.6 h1:1IxKJntfSlYkpUj8LlYRSWpYiTTC02nUrOE8T3DqGeg= +github.com/pion/datachannel v1.5.6/go.mod h1:1eKT6Q85pRnr2mHiWHxJwO50SfZRtWHTsNIVb/NfGW4= +github.com/pion/dtls/v2 v2.2.11 h1:9U/dpCYl1ySttROPWJgqWKEylUdT0fXp/xst6JwY5Ks= +github.com/pion/dtls/v2 v2.2.11/go.mod h1:d9SYc9fch0CqK90mRk1dC7AkzzpwJj6u2GU3u+9pqFE= +github.com/pion/ice/v2 v2.3.24 h1:RYgzhH/u5lH0XO+ABatVKCtRd+4U1GEaCXSMjNr13tI= +github.com/pion/ice/v2 v2.3.24/go.mod h1:KXJJcZK7E8WzrBEYnV4UtqEZsGeWfHxsNqhVcVvgjxw= +github.com/pion/interceptor v0.1.29 h1:39fsnlP1U8gw2JzOFWdfCU82vHvhW9o0rZnZF56wF+M= +github.com/pion/interceptor v0.1.29/go.mod h1:ri+LGNjRUc5xUNtDEPzfdkmSqISixVTBF/z/Zms/6T4= +github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY= +github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms= +github.com/pion/mdns v0.0.12 h1:CiMYlY+O0azojWDmxdNr7ADGrnZ+V6Ilfner+6mSVK8= +github.com/pion/mdns v0.0.12/go.mod h1:VExJjv8to/6Wqm1FXK+Ii/Z9tsVk/F5sD/N70cnYFbk= +github.com/pion/randutil v0.1.0 h1:CFG1UdESneORglEsnimhUjf33Rwjubwj6xfiOXBa3mA= +github.com/pion/randutil v0.1.0/go.mod h1:XcJrSMMbbMRhASFVOlj/5hQial/Y8oH/HVo7TBZq+j8= +github.com/pion/rtcp v1.2.14 h1:KCkGV3vJ+4DAJmvP0vaQShsb0xkRfWkO540Gy102KyE= +github.com/pion/rtcp v1.2.14/go.mod h1:sn6qjxvnwyAkkPzPULIbVqSKI5Dv54Rv7VG0kNxh9L4= +github.com/pion/rtp v1.8.6 h1:MTmn/b0aWWsAzux2AmP8WGllusBVw4NPYPVFFd7jUPw= +github.com/pion/rtp v1.8.6/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU= +github.com/pion/sctp v1.8.16 h1:PKrMs+o9EMLRvFfXq59WFsC+V8mN1wnKzqrv+3D/gYY= +github.com/pion/sctp v1.8.16/go.mod h1:P6PbDVA++OJMrVNg2AL3XtYHV4uD6dvfyOovCgMs0PE= +github.com/pion/sdp/v3 v3.0.9 h1:pX++dCHoHUwq43kuwf3PyJfHlwIj4hXA7Vrifiq0IJY= +github.com/pion/sdp/v3 v3.0.9/go.mod h1:B5xmvENq5IXJimIO4zfp6LAe1fD9N+kFv+V/1lOdz8M= +github.com/pion/srtp/v2 v2.0.18 h1:vKpAXfawO9RtTRKZJbG4y0v1b11NZxQnxRl85kGuUlo= +github.com/pion/srtp/v2 v2.0.18/go.mod h1:0KJQjA99A6/a0DOVTu1PhDSw0CXF2jTkqOoMg3ODqdA= +github.com/pion/stun v0.6.1 h1:8lp6YejULeHBF8NmV8e2787BogQhduZugh5PdhDyyN4= +github.com/pion/stun v0.6.1/go.mod h1:/hO7APkX4hZKu/D0f2lHzNyvdkTGtIy3NDmLR7kSz/8= +github.com/pion/transport/v2 v2.2.5 h1:iyi25i/21gQck4hfRhomF6SktmUQjRsRW4WJdhfc3Kc= +github.com/pion/transport/v2 v2.2.5/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0= +github.com/pion/turn/v2 v2.1.6 h1:Xr2niVsiPTB0FPtt+yAWKFUkU1eotQbGgpTIld4x1Gc= +github.com/pion/turn/v2 v2.1.6/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY= +github.com/pion/webrtc/v3 v3.2.40 h1:Wtfi6AZMQg+624cvCXUuSmrKWepSB7zfgYDOYqsSOVU= +github.com/pion/webrtc/v3 v3.2.40/go.mod h1:M1RAe3TNTD1tzyvqHrbVODfwdPGSXOUo/OgpoGGJqFY= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -667,10 +699,10 @@ github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 h1:M8mH9eK4OUR4l github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567/go.mod h1:DWNGW8A4Y+GyBgPuaQJuWiy0XYftx4Xm/y5Jqk9I6VQ= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= -github.com/quic-go/quic-go v0.42.0 h1:uSfdap0eveIl8KXnipv9K7nlwZ5IqLlYOpJ58u5utpM= -github.com/quic-go/quic-go v0.42.0/go.mod h1:132kz4kL3F9vxhW3CtQJLDVwcFe5wdWeJXXijhsO57M= -github.com/quic-go/webtransport-go v0.7.0 h1:dv9wDD9Rd0cuSRLRHPrOX9fSY8QBpdXW4Ls85WXMKqE= -github.com/quic-go/webtransport-go v0.7.0/go.mod h1:MX3nFXrcXkdzblIfOXFZ5lVCZhn+VbMMspOweP1HoXE= +github.com/quic-go/quic-go v0.44.0 h1:So5wOr7jyO4vzL2sd8/pD9Kesciv91zSk8BoFngItQ0= +github.com/quic-go/quic-go v0.44.0/go.mod h1:z4cx/9Ny9UtGITIPzmPTXh1ULfOyWh4qGQlpnPcWmek= +github.com/quic-go/webtransport-go v0.8.0 h1:HxSrwun11U+LlmwpgM1kEqIqH90IT4N8auv/cD7QFJg= +github.com/quic-go/webtransport-go v0.8.0/go.mod h1:N99tjprW432Ut5ONql/aUhSLT0YVSlwHohQsuac9WaM= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= @@ -831,8 +863,8 @@ go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= -go.uber.org/fx v1.20.1 h1:zVwVQGS8zYvhh9Xxcu4w1M6ESyeMzebzj2NbSayZ4Mk= -go.uber.org/fx v1.20.1/go.mod h1:iSYNbHf2y55acNCwCXKx7LbWb5WG1Bnue5RDXz1OREg= +go.uber.org/fx v1.21.1 h1:RqBh3cYdzZS0uqwVeEjOX2p73dddLpym315myy/Bpb0= +go.uber.org/fx v1.21.1/go.mod h1:HT2M7d7RHo+ebKGh9NRcrsrHHfpZ60nW3QRubMRfv48= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= From 70d976267a95520266d7ed9dd0b3accdf41d84c2 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Mon, 27 May 2024 12:40:37 +0200 Subject: [PATCH 1095/1212] chore: boxo 0.20.0 (#10432) --- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- test/dependencies/go.mod | 2 +- test/dependencies/go.sum | 4 ++-- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 2ecefe11d..6914d8888 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -9,7 +9,7 @@ toolchain go1.22.0 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.19.1-0.20240523201107-09b0013e1c3e + github.com/ipfs/boxo v0.20.0 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.34.1 github.com/multiformats/go-multiaddr v0.12.4 diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 21a93f6ad..8361e8757 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -264,8 +264,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.19.1-0.20240523201107-09b0013e1c3e h1:ehlWR5Qj4AWORjKq4Cyl9mBkUTel6ulQ/WIf1t32q1s= -github.com/ipfs/boxo v0.19.1-0.20240523201107-09b0013e1c3e/go.mod h1:mwttn53Eibgska2DhVIj7ln3UViq7MVHRxOMb+ehSDM= +github.com/ipfs/boxo v0.20.0 h1:umUl7q1v5g5AX8FPLTnZBvvagLmT+V0Tt61EigP81ec= +github.com/ipfs/boxo v0.20.0/go.mod h1:mwttn53Eibgska2DhVIj7ln3UViq7MVHRxOMb+ehSDM= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= diff --git a/go.mod b/go.mod index f27c91f25..062c44d2c 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,7 @@ require ( github.com/hashicorp/go-multierror v1.1.1 github.com/ipfs-shipyard/nopfs v0.0.12 github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c - github.com/ipfs/boxo v0.19.1-0.20240523201107-09b0013e1c3e + github.com/ipfs/boxo v0.20.0 github.com/ipfs/go-block-format v0.2.0 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 diff --git a/go.sum b/go.sum index 53216bf8b..b5e133f92 100644 --- a/go.sum +++ b/go.sum @@ -328,8 +328,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.19.1-0.20240523201107-09b0013e1c3e h1:ehlWR5Qj4AWORjKq4Cyl9mBkUTel6ulQ/WIf1t32q1s= -github.com/ipfs/boxo v0.19.1-0.20240523201107-09b0013e1c3e/go.mod h1:mwttn53Eibgska2DhVIj7ln3UViq7MVHRxOMb+ehSDM= +github.com/ipfs/boxo v0.20.0 h1:umUl7q1v5g5AX8FPLTnZBvvagLmT+V0Tt61EigP81ec= +github.com/ipfs/boxo v0.20.0/go.mod h1:mwttn53Eibgska2DhVIj7ln3UViq7MVHRxOMb+ehSDM= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index b8ce2fc5a..f78ed4bfe 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -105,7 +105,7 @@ require ( github.com/hexops/gotextdiff v1.0.3 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/ipfs/bbloom v0.0.4 // indirect - github.com/ipfs/boxo v0.19.1-0.20240523201107-09b0013e1c3e // indirect + github.com/ipfs/boxo v0.20.0 // indirect github.com/ipfs/go-block-format v0.2.0 // indirect github.com/ipfs/go-cid v0.4.1 // indirect github.com/ipfs/go-datastore v0.6.0 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index b918942f9..e221fd652 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -363,8 +363,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.19.1-0.20240523201107-09b0013e1c3e h1:ehlWR5Qj4AWORjKq4Cyl9mBkUTel6ulQ/WIf1t32q1s= -github.com/ipfs/boxo v0.19.1-0.20240523201107-09b0013e1c3e/go.mod h1:mwttn53Eibgska2DhVIj7ln3UViq7MVHRxOMb+ehSDM= +github.com/ipfs/boxo v0.20.0 h1:umUl7q1v5g5AX8FPLTnZBvvagLmT+V0Tt61EigP81ec= +github.com/ipfs/boxo v0.20.0/go.mod h1:mwttn53Eibgska2DhVIj7ln3UViq7MVHRxOMb+ehSDM= github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs= github.com/ipfs/go-block-format v0.2.0/go.mod h1:+jpL11nFx5A/SPpsoBn6Bzkra/zaArfSmsknbPMYgzM= github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= From 3a78f7b8228ca18b961b2995a0272eccb9d990ef Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Mon, 27 May 2024 10:42:39 +0000 Subject: [PATCH 1096/1212] chore: update version --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index bd6f8183a..ecc82a058 100644 --- a/version.go +++ b/version.go @@ -11,7 +11,7 @@ import ( var CurrentCommit string // CurrentVersionNumber is the current application's version literal. -const CurrentVersionNumber = "0.29.0-dev" +const CurrentVersionNumber = "0.29.0-rc1" const ApiVersion = "/kubo/" + CurrentVersionNumber + "/" //nolint From 97e5e6b543f42ec7fd54cfcbc0aeec36d3f7595c Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Mon, 27 May 2024 10:43:29 +0000 Subject: [PATCH 1097/1212] chore: update version --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index bd6f8183a..ee76d8ed1 100644 --- a/version.go +++ b/version.go @@ -11,7 +11,7 @@ import ( var CurrentCommit string // CurrentVersionNumber is the current application's version literal. -const CurrentVersionNumber = "0.29.0-dev" +const CurrentVersionNumber = "0.30.0-dev" const ApiVersion = "/kubo/" + CurrentVersionNumber + "/" //nolint From 2fdb997bc5f5ce0be1d7e3d2109f081ed5e3b863 Mon Sep 17 00:00:00 2001 From: looklose <166388131+looklose@users.noreply.github.com> Date: Mon, 3 Jun 2024 23:17:58 +0800 Subject: [PATCH 1098/1212] chore: fix some typos (#10396) Signed-off-by: looklose --- Rules.mk | 2 +- client/rpc/errors.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Rules.mk b/Rules.mk index c3e662aa0..ef88bee0f 100644 --- a/Rules.mk +++ b/Rules.mk @@ -123,7 +123,7 @@ help: @echo ' build - Build binary at ./cmd/ipfs/ipfs' @echo ' nofuse - Build binary with no fuse support' @echo ' install - Build binary and install into $$GOBIN' - @echo ' mod_tidy - Remove unused dependencis from go.mod files' + @echo ' mod_tidy - Remove unused dependencies from go.mod files' # @echo ' dist_install - TODO: c.f. ./cmd/ipfs/dist/README.md' @echo '' @echo 'CLEANING TARGETS:' diff --git a/client/rpc/errors.go b/client/rpc/errors.go index 6c136ebef..29f5487d4 100644 --- a/client/rpc/errors.go +++ b/client/rpc/errors.go @@ -68,11 +68,11 @@ func parseErrNotFound(msg string) (error, bool) { // Assume CIDs break on: // - Whitespaces: " \t\n\r\v\f" // - Semicolon: ";" this is to parse ipld.ErrNotFound wrapped in multierr -// - Double Quotes: "\"" this is for parsing %q and %#v formating. +// - Double Quotes: "\"" this is for parsing %q and %#v formatting. const cidBreakSet = " \t\n\r\v\f;\"" func parseIPLDErrNotFound(msg string) (error, bool) { - // The patern we search for is: + // The pattern we search for is: const ipldErrNotFoundKey = "ipld: could not find " /*CID*/ // We try to parse the CID, if it's invalid we give up and return a simple text error. // We also accept "node" in place of the CID because that means it's an Undefined CID. From 40cf630874a3fc0c6ad9e1dc3045f67319dae402 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Luk=C3=A1=C4=8D?= Date: Mon, 3 Jun 2024 21:13:30 +0200 Subject: [PATCH 1099/1212] fix(libp2p): streams config validation in resource manager (#10435) --- core/node/libp2p/rcmgr.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/node/libp2p/rcmgr.go b/core/node/libp2p/rcmgr.go index 2a7d67575..ab6e72940 100644 --- a/core/node/libp2p/rcmgr.go +++ b/core/node/libp2p/rcmgr.go @@ -491,7 +491,7 @@ resource manager System.ConnsInbound (%d) must be bigger than ConnMgr.HighWater See: https://github.com/ipfs/kubo/blob/master/docs/libp2p-resource-management.md#how-does-the-resource-manager-resourcemgr-relate-to-the-connection-manager-connmgr `, rcm.System.ConnsInbound, highWater) } - if rcm.System.Streams > rcmgr.DefaultLimit || rcm.System.Streams == rcmgr.BlockAllLimit && int64(rcm.System.Streams) <= highWater { + if (rcm.System.Streams > rcmgr.DefaultLimit || rcm.System.Streams == rcmgr.BlockAllLimit) && int64(rcm.System.Streams) <= highWater { // nolint return fmt.Errorf(` Unable to initialize libp2p due to conflicting resource manager limit configuration. From 9c9c89f5942c511ddc5340668453a93a0639213c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Luk=C3=A1=C4=8D?= Date: Mon, 3 Jun 2024 21:13:30 +0200 Subject: [PATCH 1100/1212] fix(libp2p): streams config validation in resource manager (#10435) (cherry picked from commit 40cf630874a3fc0c6ad9e1dc3045f67319dae402) --- core/node/libp2p/rcmgr.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/node/libp2p/rcmgr.go b/core/node/libp2p/rcmgr.go index 2a7d67575..ab6e72940 100644 --- a/core/node/libp2p/rcmgr.go +++ b/core/node/libp2p/rcmgr.go @@ -491,7 +491,7 @@ resource manager System.ConnsInbound (%d) must be bigger than ConnMgr.HighWater See: https://github.com/ipfs/kubo/blob/master/docs/libp2p-resource-management.md#how-does-the-resource-manager-resourcemgr-relate-to-the-connection-manager-connmgr `, rcm.System.ConnsInbound, highWater) } - if rcm.System.Streams > rcmgr.DefaultLimit || rcm.System.Streams == rcmgr.BlockAllLimit && int64(rcm.System.Streams) <= highWater { + if (rcm.System.Streams > rcmgr.DefaultLimit || rcm.System.Streams == rcmgr.BlockAllLimit) && int64(rcm.System.Streams) <= highWater { // nolint return fmt.Errorf(` Unable to initialize libp2p due to conflicting resource manager limit configuration. From c526f29b41565422a4234156d7e053cc49bcabad Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Mon, 3 Jun 2024 21:23:19 +0200 Subject: [PATCH 1101/1212] chore: set version to 0.29.0-rc2 --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index ecc82a058..51c65aca3 100644 --- a/version.go +++ b/version.go @@ -11,7 +11,7 @@ import ( var CurrentCommit string // CurrentVersionNumber is the current application's version literal. -const CurrentVersionNumber = "0.29.0-rc1" +const CurrentVersionNumber = "0.29.0-rc2" const ApiVersion = "/kubo/" + CurrentVersionNumber + "/" //nolint From a07852a3f0294974b802923fb136885ad077384e Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Thu, 6 Jun 2024 22:19:23 +0200 Subject: [PATCH 1102/1212] fix(cli): unify --name param in ls and add (#10439) This is a cosmetic fix for bug found during testing 0.29.0-rc2. pin add --name had shorthand -n pin ls --name had no shorthand, and --names had -n This unifies -n making it a shorthand for the same parameter in both `pin ls` and `pin add`. --- core/commands/pin/pin.go | 6 +++--- docs/changelogs/v0.29.md | 9 +++++++-- test/cli/pins_test.go | 41 +++++++++++++++++++++------------------- 3 files changed, 32 insertions(+), 24 deletions(-) diff --git a/core/commands/pin/pin.go b/core/commands/pin/pin.go index b27b1e2bf..b87760aaf 100644 --- a/core/commands/pin/pin.go +++ b/core/commands/pin/pin.go @@ -359,10 +359,10 @@ Example: }, Options: []cmds.Option{ cmds.StringOption(pinTypeOptionName, "t", "The type of pinned keys to list. Can be \"direct\", \"indirect\", \"recursive\", or \"all\".").WithDefault("all"), - cmds.BoolOption(pinQuietOptionName, "q", "Write just hashes of objects."), + cmds.BoolOption(pinQuietOptionName, "q", "Output only the CIDs of pins."), + cmds.StringOption(pinNameOptionName, "n", "Limit returned pins to ones with names that contain the value provided (case-sensitive, partial match). Implies --names=true."), cmds.BoolOption(pinStreamOptionName, "s", "Enable streaming of pins as they are discovered."), - cmds.BoolOption(pinNamesOptionName, "n", "Enable displaying pin names (slower)."), - cmds.StringOption(pinNameOptionName, "Display pins with names that contain the value provided (case-sensitive, partial match)."), + cmds.BoolOption(pinNamesOptionName, "Include pin names in the output (slower, disabled by default)."), }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { api, err := cmdenv.GetApi(env, req) diff --git a/docs/changelogs/v0.29.md b/docs/changelogs/v0.29.md index 632c47b15..a7c6f2608 100644 --- a/docs/changelogs/v0.29.md +++ b/docs/changelogs/v0.29.md @@ -17,7 +17,12 @@ #### Add search functionality for pin names -It is now possible to search for pins by name. To do so, use `ipfs pin ls --name "SomeName"`. The search is case-sensitive and will return all pins having a name which contains the exact word provided. +It is now possible to search for pins by name via `ipfs pin ls --name "SomeName"`. +The search is case-sensitive and will return all pins that contain the specified substring in their name. + +> [!TIP] +> The `ipfs pin ls -n` is now a shorthand for `ipfs pin ls --name`, mirroring the behavior of `ipfs pin add`. +> See `ipfs pin ls --help` for more information. #### Customizing `ipfs add` defaults @@ -27,7 +32,7 @@ The hash function, CID version, or UnixFS raw leaves and chunker behaviors can b > [!TIP] > As a convenience, two CID [profiles](../config.md#profile) are provided: `legacy-cid-v0` and `test-cid-v1`. > A test profile that defaults to modern CIDv1 can be applied via `ipfs config profile apply test-cid-v1`. -> We encourage users to try it and report any issues. +> We encourage users to try it and report any issues in [kubo#4143](https://github.com/ipfs/kubo/issues/4143). ### 📝 Changelog diff --git a/test/cli/pins_test.go b/test/cli/pins_test.go index 88da250b1..3e3325a01 100644 --- a/test/cli/pins_test.go +++ b/test/cli/pins_test.go @@ -242,7 +242,7 @@ func TestPins(t *testing.T) { require.NotContains(t, lsOut, outADetailed) }) - t.Run("test listing pins which contains specific name", func(t *testing.T) { + t.Run("test listing pins with names that contain specific string", func(t *testing.T) { t.Parallel() node := harness.NewT(t).NewNode().Init() @@ -254,27 +254,30 @@ func TestPins(t *testing.T) { outB := cidBStr + " recursive testPin" outC := cidCStr + " recursive randPin" - _ = node.IPFS("pin", "add", "--name", "testPin", cidAStr) - lsOut := pinLs(node, "-t=recursive", "--name=test") - require.Contains(t, lsOut, outA) - lsOut = pinLs(node, "-t=recursive", "--name=randomLabel") - require.NotContains(t, lsOut, outA) + // make sure both -n and --name work + for _, nameParam := range []string{"--name", "-n"} { + _ = node.IPFS("pin", "add", "--name", "testPin", cidAStr) + lsOut := pinLs(node, "-t=recursive", nameParam+"=test") + require.Contains(t, lsOut, outA) + lsOut = pinLs(node, "-t=recursive", nameParam+"=randomLabel") + require.NotContains(t, lsOut, outA) - _ = node.IPFS("pin", "add", "--name", "testPin", cidBStr) - lsOut = pinLs(node, "-t=recursive", "--name=test") - require.Contains(t, lsOut, outA) - require.Contains(t, lsOut, outB) + _ = node.IPFS("pin", "add", "--name", "testPin", cidBStr) + lsOut = pinLs(node, "-t=recursive", nameParam+"=test") + require.Contains(t, lsOut, outA) + require.Contains(t, lsOut, outB) - _ = node.IPFS("pin", "add", "--name", "randPin", cidCStr) - lsOut = pinLs(node, "-t=recursive", "--name=rand") - require.NotContains(t, lsOut, outA) - require.NotContains(t, lsOut, outB) - require.Contains(t, lsOut, outC) + _ = node.IPFS("pin", "add", "--name", "randPin", cidCStr) + lsOut = pinLs(node, "-t=recursive", nameParam+"=rand") + require.NotContains(t, lsOut, outA) + require.NotContains(t, lsOut, outB) + require.Contains(t, lsOut, outC) - lsOut = pinLs(node, "-t=recursive", "--name=testPin") - require.Contains(t, lsOut, outA) - require.Contains(t, lsOut, outB) - require.NotContains(t, lsOut, outC) + lsOut = pinLs(node, "-t=recursive", nameParam+"=testPin") + require.Contains(t, lsOut, outA) + require.Contains(t, lsOut, outB) + require.NotContains(t, lsOut, outC) + } }) t.Run("test overwriting pin with name", func(t *testing.T) { From 5a7029e8ccdf388a8b8407920cd801e7340a0ba4 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Thu, 6 Jun 2024 22:19:23 +0200 Subject: [PATCH 1103/1212] fix(cli): unify --name param in ls and add (#10439) This is a cosmetic fix for bug found during testing 0.29.0-rc2. pin add --name had shorthand -n pin ls --name had no shorthand, and --names had -n This unifies -n making it a shorthand for the same parameter in both `pin ls` and `pin add`. (cherry picked from commit a07852a3f0294974b802923fb136885ad077384e) --- core/commands/pin/pin.go | 6 +++--- docs/changelogs/v0.29.md | 9 +++++++-- test/cli/pins_test.go | 41 +++++++++++++++++++++------------------- 3 files changed, 32 insertions(+), 24 deletions(-) diff --git a/core/commands/pin/pin.go b/core/commands/pin/pin.go index b27b1e2bf..b87760aaf 100644 --- a/core/commands/pin/pin.go +++ b/core/commands/pin/pin.go @@ -359,10 +359,10 @@ Example: }, Options: []cmds.Option{ cmds.StringOption(pinTypeOptionName, "t", "The type of pinned keys to list. Can be \"direct\", \"indirect\", \"recursive\", or \"all\".").WithDefault("all"), - cmds.BoolOption(pinQuietOptionName, "q", "Write just hashes of objects."), + cmds.BoolOption(pinQuietOptionName, "q", "Output only the CIDs of pins."), + cmds.StringOption(pinNameOptionName, "n", "Limit returned pins to ones with names that contain the value provided (case-sensitive, partial match). Implies --names=true."), cmds.BoolOption(pinStreamOptionName, "s", "Enable streaming of pins as they are discovered."), - cmds.BoolOption(pinNamesOptionName, "n", "Enable displaying pin names (slower)."), - cmds.StringOption(pinNameOptionName, "Display pins with names that contain the value provided (case-sensitive, partial match)."), + cmds.BoolOption(pinNamesOptionName, "Include pin names in the output (slower, disabled by default)."), }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { api, err := cmdenv.GetApi(env, req) diff --git a/docs/changelogs/v0.29.md b/docs/changelogs/v0.29.md index 632c47b15..a7c6f2608 100644 --- a/docs/changelogs/v0.29.md +++ b/docs/changelogs/v0.29.md @@ -17,7 +17,12 @@ #### Add search functionality for pin names -It is now possible to search for pins by name. To do so, use `ipfs pin ls --name "SomeName"`. The search is case-sensitive and will return all pins having a name which contains the exact word provided. +It is now possible to search for pins by name via `ipfs pin ls --name "SomeName"`. +The search is case-sensitive and will return all pins that contain the specified substring in their name. + +> [!TIP] +> The `ipfs pin ls -n` is now a shorthand for `ipfs pin ls --name`, mirroring the behavior of `ipfs pin add`. +> See `ipfs pin ls --help` for more information. #### Customizing `ipfs add` defaults @@ -27,7 +32,7 @@ The hash function, CID version, or UnixFS raw leaves and chunker behaviors can b > [!TIP] > As a convenience, two CID [profiles](../config.md#profile) are provided: `legacy-cid-v0` and `test-cid-v1`. > A test profile that defaults to modern CIDv1 can be applied via `ipfs config profile apply test-cid-v1`. -> We encourage users to try it and report any issues. +> We encourage users to try it and report any issues in [kubo#4143](https://github.com/ipfs/kubo/issues/4143). ### 📝 Changelog diff --git a/test/cli/pins_test.go b/test/cli/pins_test.go index 88da250b1..3e3325a01 100644 --- a/test/cli/pins_test.go +++ b/test/cli/pins_test.go @@ -242,7 +242,7 @@ func TestPins(t *testing.T) { require.NotContains(t, lsOut, outADetailed) }) - t.Run("test listing pins which contains specific name", func(t *testing.T) { + t.Run("test listing pins with names that contain specific string", func(t *testing.T) { t.Parallel() node := harness.NewT(t).NewNode().Init() @@ -254,27 +254,30 @@ func TestPins(t *testing.T) { outB := cidBStr + " recursive testPin" outC := cidCStr + " recursive randPin" - _ = node.IPFS("pin", "add", "--name", "testPin", cidAStr) - lsOut := pinLs(node, "-t=recursive", "--name=test") - require.Contains(t, lsOut, outA) - lsOut = pinLs(node, "-t=recursive", "--name=randomLabel") - require.NotContains(t, lsOut, outA) + // make sure both -n and --name work + for _, nameParam := range []string{"--name", "-n"} { + _ = node.IPFS("pin", "add", "--name", "testPin", cidAStr) + lsOut := pinLs(node, "-t=recursive", nameParam+"=test") + require.Contains(t, lsOut, outA) + lsOut = pinLs(node, "-t=recursive", nameParam+"=randomLabel") + require.NotContains(t, lsOut, outA) - _ = node.IPFS("pin", "add", "--name", "testPin", cidBStr) - lsOut = pinLs(node, "-t=recursive", "--name=test") - require.Contains(t, lsOut, outA) - require.Contains(t, lsOut, outB) + _ = node.IPFS("pin", "add", "--name", "testPin", cidBStr) + lsOut = pinLs(node, "-t=recursive", nameParam+"=test") + require.Contains(t, lsOut, outA) + require.Contains(t, lsOut, outB) - _ = node.IPFS("pin", "add", "--name", "randPin", cidCStr) - lsOut = pinLs(node, "-t=recursive", "--name=rand") - require.NotContains(t, lsOut, outA) - require.NotContains(t, lsOut, outB) - require.Contains(t, lsOut, outC) + _ = node.IPFS("pin", "add", "--name", "randPin", cidCStr) + lsOut = pinLs(node, "-t=recursive", nameParam+"=rand") + require.NotContains(t, lsOut, outA) + require.NotContains(t, lsOut, outB) + require.Contains(t, lsOut, outC) - lsOut = pinLs(node, "-t=recursive", "--name=testPin") - require.Contains(t, lsOut, outA) - require.Contains(t, lsOut, outB) - require.NotContains(t, lsOut, outC) + lsOut = pinLs(node, "-t=recursive", nameParam+"=testPin") + require.Contains(t, lsOut, outA) + require.Contains(t, lsOut, outB) + require.NotContains(t, lsOut, outC) + } }) t.Run("test overwriting pin with name", func(t *testing.T) { From b35cd6243011847b013ee169a0f0c57601d82ac9 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Mon, 10 Jun 2024 15:10:57 +0200 Subject: [PATCH 1104/1212] docs(changelog): v0.29.0 --- docs/changelogs/v0.29.md | 202 +++++++++++++++++++++++++++++++++++++++ version.go | 2 +- 2 files changed, 203 insertions(+), 1 deletion(-) diff --git a/docs/changelogs/v0.29.md b/docs/changelogs/v0.29.md index a7c6f2608..8c45bbfca 100644 --- a/docs/changelogs/v0.29.md +++ b/docs/changelogs/v0.29.md @@ -36,4 +36,206 @@ The hash function, CID version, or UnixFS raw leaves and chunker behaviors can b ### 📝 Changelog +
Full Changelog + +- github.com/ipfs/kubo: + - fix(cli): unify --name param in ls and add (#10439) ([ipfs/kubo#10439](https://github.com/ipfs/kubo/pull/10439)) + - chore: set version to 0.29.0-rc2 + - fix(libp2p): streams config validation in resource manager (#10435) ([ipfs/kubo#10435](https://github.com/ipfs/kubo/pull/10435)) + - chore: update version + - chore: libp2p 0.34.1 (#10429) ([ipfs/kubo#10429](https://github.com/ipfs/kubo/pull/10429)) + - refactor: stop using github.com/pkg/errors (#10431) ([ipfs/kubo#10431](https://github.com/ipfs/kubo/pull/10431)) + - chore: fix --help text + - config: introduce Import section (#10421) ([ipfs/kubo#10421](https://github.com/ipfs/kubo/pull/10421)) + - feat: enables searching pins by name (#10412) ([ipfs/kubo#10412](https://github.com/ipfs/kubo/pull/10412)) + - fix(fuse): ipfs path parsing (#10243) ([ipfs/kubo#10243](https://github.com/ipfs/kubo/pull/10243)) + - core/node: fix divide by zero fatal crash for reprovide rate check (#10411) ([ipfs/kubo#10411](https://github.com/ipfs/kubo/pull/10411)) + - chore: bump to go-ipfs-cmds @ v0.11 + - chore: create next changelog + - Merge Release: v0.28.0 [skip changelog] ([ipfs/kubo#10402](https://github.com/ipfs/kubo/pull/10402)) + - docs: update release checklist (#10401) ([ipfs/kubo#10401](https://github.com/ipfs/kubo/pull/10401)) + - chore: update version +- github.com/ipfs/boxo (v0.19.0 -> v0.20.0): + - Release v0.20.0 ([ipfs/boxo#613](https://github.com/ipfs/boxo/pull/613)) +- github.com/ipfs/go-blockservice (v0.5.0 -> v0.5.2): + - docs: remove contribution section + - chore: bump version + - chore: deprecate types and readme + - chore: release v0.5.1 + - fix: remove busyloop in getBlocks by removing batching +- github.com/ipfs/go-ipfs-blockstore (v1.3.0 -> v1.3.1): + - docs: remove contribution section + - chore: bump version + - chore: deprecate types and readme +- github.com/ipfs/go-ipfs-cmds (v0.10.0 -> v0.11.0): + - chore: release v0.11.0 (#253) ([ipfs/go-ipfs-cmds#253](https://github.com/ipfs/go-ipfs-cmds/pull/253)) + - chore: update deps (#252) ([ipfs/go-ipfs-cmds#252](https://github.com/ipfs/go-ipfs-cmds/pull/252)) + - chore: release 0.10.2 (#251) ([ipfs/go-ipfs-cmds#251](https://github.com/ipfs/go-ipfs-cmds/pull/251)) + - fix(http): return error in case of panic (#250) ([ipfs/go-ipfs-cmds#250](https://github.com/ipfs/go-ipfs-cmds/pull/250)) + - chore: release v0.10.1 +- github.com/ipfs/go-ipfs-ds-help (v1.1.0 -> v1.1.1): + - docs: remove contribution section + - chore: bump version + - chore: deprecate types and readme +- github.com/ipfs/go-ipfs-exchange-interface (v0.2.0 -> v0.2.1): + - chore: bump version + - Deprecate types and readme (#29) ([ipfs/go-ipfs-exchange-interface#29](https://github.com/ipfs/go-ipfs-exchange-interface/pull/29)) + - docs: Add proper documenation to the interface. +- github.com/ipfs/go-verifcid (v0.0.2 -> v0.0.3): + - chore: bump version + - chore: deprecate types and readme + - Make poseidon hashes good hashes ([ipfs/go-verifcid#19](https://github.com/ipfs/go-verifcid/pull/19)) + - sync: update CI config files (#18) ([ipfs/go-verifcid#18](https://github.com/ipfs/go-verifcid/pull/18)) +- github.com/ipld/go-car (v0.5.0 -> v0.6.2): + - v0.6.2 ([ipld/go-car#464](https://github.com/ipld/go-car/pull/464)) + - fix: opt-in way to allow empty list of roots in CAR headers ([ipld/go-car#461](https://github.com/ipld/go-car/pull/461)) + - feat: add inverse and version to filter cmd ([ipld/go-car#457](https://github.com/ipld/go-car/pull/457)) + - v0.6.1 bump + - chore: update usage of merkledag by go-car (#437) ([ipld/go-car#437](https://github.com/ipld/go-car/pull/437)) + - feat(cmd/car): add '--no-wrap' option to 'create' command ([ipld/go-car#432](https://github.com/ipld/go-car/pull/432)) + - fix: remove github.com/ipfs/go-ipfs-blockstore dependency + - feat: expose index for StorageCar + - perf: reduce NewCarReader allocations + - fix(deps): update deps for cmd (use master go-car and go-car/v2 for now) + - fix: new error strings from go-cid + - fix: tests should match stderr for verbose output + - fix: reading from stdin should broadcast EOF to block loaders + - refactor insertion index to be publicly accessible ([ipld/go-car#408](https://github.com/ipld/go-car/pull/408)) + - chore: unmigrate from go-libipfs + - Create CODEOWNERS + - blockstore: give a direct access to the index for read operations + - blockstore: only close the file on error in OpenReadWrite, not OpenReadWriteFile + - fix: handle (and test) WholeCID vs not; fast Has() path for storage + - ReadWrite: faster Has() by using the in-memory index instead of reading on disk + - fix: let `extract` skip missing unixfs shard links + - fix: error when no files extracted + - fix: make -f optional, read from stdin if omitted + - fix: update cmd/car/README with latest description + - chore: add test cases for extract modes + - feat: extract accepts '-' as an output path for stdout + - feat: extract specific path, accept stdin as streaming input + - fix: if we don't read the full block data, don't error on !EOF + - blockstore: try to close during Finalize(), even in case of previous error + - ReadWrite: add an alternative FinalizeReadOnly+Close flow + - feat: add WithTrustedCar() reader option (#381) ([ipld/go-car#381](https://github.com/ipld/go-car/pull/381)) + - blockstore: fast path for AllKeysChan using the index + - fix: switch to crypto/rand.Read + - stop using the deprecated io/ioutil package + - fix(doc): fix storage package doc formatting + - fix: return errors for unsupported operations + - chore: move insertionindex into store pkg + - chore: add experimental note + - fix: minor lint & windows fd test problems + - feat: docs for StorageCar interfaces + - feat: ReadableWritable; dedupe shared code + - feat: add Writable functionality to StorageCar + - feat: StorageCar as a Readable storage, separate from blockstore + - feat(blockstore): implement a streaming read only storage + - feat(cmd): add index create subcommand to create an external carv2 index ([ipld/go-car#350](https://github.com/ipld/go-car/pull/350)) + - chore: bump version to 0.6.0 + - fix: use goreleaser instead + - Allow using WalkOption in WriteCar function ([ipld/go-car#357](https://github.com/ipld/go-car/pull/357)) + - fix: update go-block-format to the version that includes the stubs + - feat: upgrade from go-block-format to go-libipfs/blocks + - cleanup readme a bit to make the cli more discoverable (#353) ([ipld/go-car#353](https://github.com/ipld/go-car/pull/353)) + - Update install instructions in README.md + - Add a debugging form for car files. (#341) ([ipld/go-car#341](https://github.com/ipld/go-car/pull/341)) + - ([ipld/go-car#340](https://github.com/ipld/go-car/pull/340)) + - add a `SkipNext` method on block reader (#338) ([ipld/go-car#338](https://github.com/ipld/go-car/pull/338)) + - feat: Has() and Get() will respect StoreIdentityCIDs option +- github.com/libp2p/go-libp2p (v0.33.2 -> v0.34.1): + - release v0.34.1 (#2811) ([libp2p/go-libp2p#2811](https://github.com/libp2p/go-libp2p/pull/2811)) + - config: fix Insecure security constructor (#2810) ([libp2p/go-libp2p#2810](https://github.com/libp2p/go-libp2p/pull/2810)) + - rcmgr: Backwards compatibility if you wrap default impl (#2805) ([libp2p/go-libp2p#2805](https://github.com/libp2p/go-libp2p/pull/2805)) + - v0.34.0 (#2795) ([libp2p/go-libp2p#2795](https://github.com/libp2p/go-libp2p/pull/2795)) + - swarm: fix addr for TestBlackHoledAddrBlocked (#2803) ([libp2p/go-libp2p#2803](https://github.com/libp2p/go-libp2p/pull/2803)) + - Add backwards compatibility with old well-known resource (#2798) ([libp2p/go-libp2p#2798](https://github.com/libp2p/go-libp2p/pull/2798)) + - rcmgr: remove a connection only once from the limiter (#2800) ([libp2p/go-libp2p#2800](https://github.com/libp2p/go-libp2p/pull/2800)) + - Adhere to request.Context when roundtripping on a stream (#2796) ([libp2p/go-libp2p#2796](https://github.com/libp2p/go-libp2p/pull/2796)) + - fix: Set missing deadlines (#2794) ([libp2p/go-libp2p#2794](https://github.com/libp2p/go-libp2p/pull/2794)) + - rcmgr: Add conn_limiter to limit number of conns per ip cidr (#2788) ([libp2p/go-libp2p#2788](https://github.com/libp2p/go-libp2p/pull/2788)) + - identify: refactor observed address manager to do address mapping at thin waist(IP+TCP/UDP) layer (#2793) ([libp2p/go-libp2p#2793](https://github.com/libp2p/go-libp2p/pull/2793)) + - fix: DNS protocol address is not reserved (#2792) ([libp2p/go-libp2p#2792](https://github.com/libp2p/go-libp2p/pull/2792)) + - Update github.com/quic-go/quic-go dependency (#2780) ([libp2p/go-libp2p#2780](https://github.com/libp2p/go-libp2p/pull/2780)) + - webrtc: add webrtc addresses to host normalizer (#2784) ([libp2p/go-libp2p#2784](https://github.com/libp2p/go-libp2p/pull/2784)) + - Add a "Limited" network connectivity state (#2696) ([libp2p/go-libp2p#2696](https://github.com/libp2p/go-libp2p/pull/2696)) + - basichost: append certhash for webrtc addresses provided via address factory (#2774) ([libp2p/go-libp2p#2774](https://github.com/libp2p/go-libp2p/pull/2774)) + - Fix comment (#2775) ([libp2p/go-libp2p#2775](https://github.com/libp2p/go-libp2p/pull/2775)) + - Update: update incomplete readmes (#2767) ([libp2p/go-libp2p#2767](https://github.com/libp2p/go-libp2p/pull/2767)) + - libp2phttp: Return connection: close when doing http over streams (#2756) ([libp2p/go-libp2p#2756](https://github.com/libp2p/go-libp2p/pull/2756)) + - Identify: emit useful events after identification (#2759) ([libp2p/go-libp2p#2759](https://github.com/libp2p/go-libp2p/pull/2759)) + - Update chat with rendezvous example (#2769) ([libp2p/go-libp2p#2769](https://github.com/libp2p/go-libp2p/pull/2769)) + - Rename well-known resource (#2757) ([libp2p/go-libp2p#2757](https://github.com/libp2p/go-libp2p/pull/2757)) + - quic: make server cmd use RFC 9000 instead of draft-29 (#2753) ([libp2p/go-libp2p#2753](https://github.com/libp2p/go-libp2p/pull/2753)) + - autonat: Clean up after close (#2749) ([libp2p/go-libp2p#2749](https://github.com/libp2p/go-libp2p/pull/2749)) + - webrtc: run onDone callback immediately on close (#2729) ([libp2p/go-libp2p#2729](https://github.com/libp2p/go-libp2p/pull/2729)) + - fix: add NullResourceManager to webrtc, fixes panic (#2752) ([libp2p/go-libp2p#2752](https://github.com/libp2p/go-libp2p/pull/2752)) + - feat: add tls KeyLogWriter option (#2750) ([libp2p/go-libp2p#2750](https://github.com/libp2p/go-libp2p/pull/2750)) + - Use any port, not a specific one for examples (#2748) ([libp2p/go-libp2p#2748](https://github.com/libp2p/go-libp2p/pull/2748)) + - quicreuse: remove workaround for quic-go listener close deadlock (#2746) ([libp2p/go-libp2p#2746](https://github.com/libp2p/go-libp2p/pull/2746)) + - use Fx to start and stop the host, swarm, autorelay and quicreuse (#2118) ([libp2p/go-libp2p#2118](https://github.com/libp2p/go-libp2p/pull/2118)) + - webrtc: set sctp receive buffer size to 100kB (#2745) ([libp2p/go-libp2p#2745](https://github.com/libp2p/go-libp2p/pull/2745)) + - basichost: log more info when protocol selection fails (#2734) ([libp2p/go-libp2p#2734](https://github.com/libp2p/go-libp2p/pull/2734)) + - chore: bump quic-go (#2742) ([libp2p/go-libp2p#2742](https://github.com/libp2p/go-libp2p/pull/2742)) + - security: remove unnecessary noise code (#2738) ([libp2p/go-libp2p#2738](https://github.com/libp2p/go-libp2p/pull/2738)) + - webrtc: increase receive buffer size on listener (#2730) ([libp2p/go-libp2p#2730](https://github.com/libp2p/go-libp2p/pull/2730)) + - webrtc: fix bug with logger wrapper (#2727) ([libp2p/go-libp2p#2727](https://github.com/libp2p/go-libp2p/pull/2727)) + - dcutr: fix log format to actually print error (#2725) ([libp2p/go-libp2p#2725](https://github.com/libp2p/go-libp2p/pull/2725)) + - webrtc: use a common logger for all pion logging (#2718) ([libp2p/go-libp2p#2718](https://github.com/libp2p/go-libp2p/pull/2718)) + - chore: remove unreadable code, move a test function to test code, better locking in webrtc control reader + - ping: use context.Afterfunc to avoid a lingering goroutine (#2723) ([libp2p/go-libp2p#2723](https://github.com/libp2p/go-libp2p/pull/2723)) + - webrtc: close mux when closing listener (#2717) ([libp2p/go-libp2p#2717](https://github.com/libp2p/go-libp2p/pull/2717)) + - webrtc: setup datachannel handlers before connecting to a peer (#2716) ([libp2p/go-libp2p#2716](https://github.com/libp2p/go-libp2p/pull/2716)) +- github.com/libp2p/go-libp2p-pubsub (v0.10.0 -> v0.11.0): + - Fix: Own our CertifiedAddrBook (#555) ([libp2p/go-libp2p-pubsub#555](https://github.com/libp2p/go-libp2p-pubsub/pull/555)) + - chores: bump go-libp2p (#558) ([libp2p/go-libp2p-pubsub#558](https://github.com/libp2p/go-libp2p-pubsub/pull/558)) + - fix: Don't bother parsing an empty slice (#556) ([libp2p/go-libp2p-pubsub#556](https://github.com/libp2p/go-libp2p-pubsub/pull/556)) + - Replace fragmentRPC with appendOrMergeRPC (#557) ([libp2p/go-libp2p-pubsub#557](https://github.com/libp2p/go-libp2p-pubsub/pull/557)) +- github.com/multiformats/go-multiaddr (v0.12.3 -> v0.12.4): + - Release v0.12.4 ([multiformats/go-multiaddr#245](https://github.com/multiformats/go-multiaddr/pull/245)) + - net: restrict unicast ip6 public address space (#235) ([multiformats/go-multiaddr#235](https://github.com/multiformats/go-multiaddr/pull/235)) +- github.com/whyrusleeping/cbor-gen (v0.1.0 -> v0.1.1): + - fix: reduce memory held by deferred objects (#96) ([whyrusleeping/cbor-gen#96](https://github.com/whyrusleeping/cbor-gen/pull/96)) + +
+ ### 👨‍👩‍👧‍👦 Contributors + +| Contributor | Commits | Lines ± | Files Changed | +|-------------|---------|---------|---------------| +| Henrique Dias | 33 | +4994/-579 | 115 | +| Rod Vagg | 29 | +3781/-1367 | 90 | +| sukun | 12 | +2026/-1215 | 39 | +| Marco Munizaga | 18 | +1482/-382 | 47 | +| Will | 5 | +769/-213 | 17 | +| Steven Allen | 5 | +540/-115 | 24 | +| Sukun | 4 | +274/-194 | 11 | +| Michael Muré | 7 | +372/-55 | 16 | +| Marten Seemann | 1 | +243/-141 | 10 | +| Marcin Rataj | 7 | +244/-134 | 13 | +| hannahhoward | 1 | +277/-0 | 2 | +| Will Scott | 5 | +54/-38 | 9 | +| Hector Sanjuan | 3 | +68/-20 | 5 | +| Jorropo | 5 | +34/-47 | 15 | +| Andrew Gillis | 2 | +67/-7 | 3 | +| IGP | 1 | +59/-8 | 5 | +| Adin Schmahmann | 2 | +50/-0 | 3 | +| Laurent Senta | 1 | +40/-4 | 2 | +| Brad Fitzpatrick | 1 | +42/-2 | 2 | +| Fabio Bozzo | 1 | +36/-1 | 3 | +| Yolan Romailler | 1 | +15/-19 | 4 | +| Hlib Kanunnikov | 2 | +14/-14 | 6 | +| Andreas Penzkofer | 1 | +22/-2 | 3 | +| Matthias Fasching | 1 | +8/-10 | 1 | +| gopherfarm | 2 | +16/-1 | 2 | +| Dreamacro | 1 | +1/-10 | 1 | +| web3-bot | 2 | +7/-3 | 4 | +| Rafał Leszko | 1 | +4/-4 | 1 | +| Oleg Kovalov | 1 | +4/-4 | 3 | +| dbeal | 1 | +5/-1 | 1 | +| Antonio Navarro Perez | 1 | +4/-1 | 1 | +| dozyio | 1 | +3/-0 | 1 | +| zhiqiangxu | 1 | +1/-1 | 1 | +| the harder the luckier | 1 | +1/-1 | 1 | +| Lukáš Lukáč | 1 | +1/-1 | 1 | +| Steve Loeppky | 1 | +1/-0 | 1 | diff --git a/version.go b/version.go index 51c65aca3..91c690009 100644 --- a/version.go +++ b/version.go @@ -11,7 +11,7 @@ import ( var CurrentCommit string // CurrentVersionNumber is the current application's version literal. -const CurrentVersionNumber = "0.29.0-rc2" +const CurrentVersionNumber = "0.29.0" const ApiVersion = "/kubo/" + CurrentVersionNumber + "/" //nolint From c9bab01a50ca2b0de74c28b3eb7ce1cf84f0a854 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Mon, 10 Jun 2024 22:56:11 +0200 Subject: [PATCH 1105/1212] chore: create next changelog (#10443) --- CHANGELOG.md | 1 + docs/changelogs/v0.30.md | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 docs/changelogs/v0.30.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 5b68d6152..93901ba1e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ # Kubo Changelogs +- [v0.30](docs/changelogs/v0.30.md) - [v0.29](docs/changelogs/v0.29.md) - [v0.28](docs/changelogs/v0.28.md) - [v0.27](docs/changelogs/v0.27.md) diff --git a/docs/changelogs/v0.30.md b/docs/changelogs/v0.30.md new file mode 100644 index 000000000..e561566d9 --- /dev/null +++ b/docs/changelogs/v0.30.md @@ -0,0 +1,18 @@ +# Kubo changelog v0.30 + +- [v0.30.0](#v0300) + +## v0.30.0 + +- [Overview](#overview) +- [🔦 Highlights](#-highlights) +- [📝 Changelog](#-changelog) +- [👨‍👩‍👧‍👦 Contributors](#-contributors) + +### Overview + +### 🔦 Highlights + +### 📝 Changelog + +### 👨‍👩‍👧‍👦 Contributors From 144e97cf69909b76c659f86528b06ea52bbe9f0b Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Mon, 10 Jun 2024 23:06:02 +0200 Subject: [PATCH 1106/1212] docsa: update RELEASE_CHECKLIST.md --- docs/RELEASE_CHECKLIST.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/RELEASE_CHECKLIST.md b/docs/RELEASE_CHECKLIST.md index 727700eeb..655329e1a 100644 --- a/docs/RELEASE_CHECKLIST.md +++ b/docs/RELEASE_CHECKLIST.md @@ -173,8 +173,7 @@ This section covers tasks to be done during each release. - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) Create a dependency update PR - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) check out [ipfs/kubo](https://github.com/ipfs/kubo) - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) run `go get -u` in root directory - - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) run `go mod tidy` in root directory - - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) run `go mod tidy` in `docs/examples/kubo-as-a-library` directory + - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) run `make mod_tidy` - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) create a PR which updates `go.mod` and `go.sum` - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) add the PR to the next release milestone - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Close the release issue From 121c6023c3b1f9b2898311350883e6c35be39d26 Mon Sep 17 00:00:00 2001 From: Marco Munizaga Date: Fri, 14 Jun 2024 12:33:00 -0700 Subject: [PATCH 1107/1212] chore: go-libp2p 0.35.1 (#10430) https://github.com/libp2p/go-libp2p/releases/tag/v0.35.1 Co-authored-by: Marcin Rataj --- core/node/libp2p/rcmgr.go | 19 +++---- docs/examples/kubo-as-a-library/go.mod | 34 ++++++------ docs/examples/kubo-as-a-library/go.sum | 68 ++++++++++++------------ go.mod | 36 ++++++------- go.sum | 72 +++++++++++++------------- test/dependencies/go.mod | 32 ++++++------ test/dependencies/go.sum | 68 ++++++++++++------------ 7 files changed, 162 insertions(+), 167 deletions(-) diff --git a/core/node/libp2p/rcmgr.go b/core/node/libp2p/rcmgr.go index ab6e72940..8b6d55a2c 100644 --- a/core/node/libp2p/rcmgr.go +++ b/core/node/libp2p/rcmgr.go @@ -77,21 +77,16 @@ filled in with autocomputed defaults.`) ropts := []rcmgr.Option{ rcmgr.WithMetrics(createRcmgrMetrics()), rcmgr.WithTraceReporter(str), - rcmgr.WithLimitPeersPerCIDR( - []rcmgr.ConnLimitPerCIDR{ + rcmgr.WithLimitPerSubnet( + nil, + []rcmgr.ConnLimitPerSubnet{ { - ConnCount: 16, - BitMask: 32, - }, - }, - []rcmgr.ConnLimitPerCIDR{ - { - ConnCount: 16, - BitMask: 56, + ConnCount: 16, + PrefixLength: 56, }, { - ConnCount: 8 * 16, - BitMask: 48, + ConnCount: 8 * 16, + PrefixLength: 48, }, }), } diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 6914d8888..7f12b7936 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -11,7 +11,7 @@ replace github.com/ipfs/kubo => ./../../.. require ( github.com/ipfs/boxo v0.20.0 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 - github.com/libp2p/go-libp2p v0.34.1 + github.com/libp2p/go-libp2p v0.35.1 github.com/multiformats/go-multiaddr v0.12.4 ) @@ -46,7 +46,7 @@ require ( github.com/francoispqt/gojay v1.2.13 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/gabriel-vasile/mimetype v1.4.3 // indirect - github.com/go-logr/logr v1.4.1 // indirect + github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-task/slim-sprig/v3 v3.0.0 // indirect github.com/godbus/dbus/v5 v5.1.0 // indirect @@ -103,7 +103,7 @@ require ( github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect github.com/jbenet/goprocess v0.1.4 // indirect github.com/klauspost/compress v1.17.8 // indirect - github.com/klauspost/cpuid/v2 v2.2.7 // indirect + github.com/klauspost/cpuid/v2 v2.2.8 // indirect github.com/koron/go-ssdp v0.0.4 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/libp2p/go-cidranger v1.1.0 // indirect @@ -148,7 +148,7 @@ require ( github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 // indirect github.com/pion/datachannel v1.5.6 // indirect github.com/pion/dtls/v2 v2.2.11 // indirect - github.com/pion/ice/v2 v2.3.24 // indirect + github.com/pion/ice/v2 v2.3.25 // indirect github.com/pion/interceptor v0.1.29 // indirect github.com/pion/logging v0.2.2 // indirect github.com/pion/mdns v0.0.12 // indirect @@ -167,8 +167,8 @@ require ( github.com/polydawn/refmt v0.89.0 // indirect github.com/prometheus/client_golang v1.19.1 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.53.0 // indirect - github.com/prometheus/procfs v0.15.0 // indirect + github.com/prometheus/common v0.54.0 // indirect + github.com/prometheus/procfs v0.15.1 // indirect github.com/quic-go/qpack v0.4.0 // indirect github.com/quic-go/quic-go v0.44.0 // indirect github.com/quic-go/webtransport-go v0.8.0 // indirect @@ -180,21 +180,21 @@ require ( github.com/ucarion/urlpath v0.0.0-20200424170820-7ccc79b76bbb // indirect github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc // indirect github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11 // indirect - github.com/whyrusleeping/cbor-gen v0.1.1 // indirect + github.com/whyrusleeping/cbor-gen v0.1.2 // indirect github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f // indirect github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.51.0 // indirect - go.opentelemetry.io/otel v1.26.0 // indirect + go.opentelemetry.io/otel v1.27.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.26.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.26.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.26.0 // indirect go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.26.0 // indirect go.opentelemetry.io/otel/exporters/zipkin v1.26.0 // indirect - go.opentelemetry.io/otel/metric v1.26.0 // indirect + go.opentelemetry.io/otel/metric v1.27.0 // indirect go.opentelemetry.io/otel/sdk v1.26.0 // indirect - go.opentelemetry.io/otel/trace v1.26.0 // indirect + go.opentelemetry.io/otel/trace v1.27.0 // indirect go.opentelemetry.io/proto/otlp v1.2.0 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/dig v1.17.1 // indirect @@ -203,14 +203,14 @@ require ( go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect go4.org v0.0.0-20230225012048-214862532bf5 // indirect - golang.org/x/crypto v0.23.0 // indirect - golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect - golang.org/x/mod v0.17.0 // indirect - golang.org/x/net v0.25.0 // indirect + golang.org/x/crypto v0.24.0 // indirect + golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8 // indirect + golang.org/x/mod v0.18.0 // indirect + golang.org/x/net v0.26.0 // indirect golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.20.0 // indirect - golang.org/x/text v0.15.0 // indirect - golang.org/x/tools v0.21.0 // indirect + golang.org/x/sys v0.21.0 // indirect + golang.org/x/text v0.16.0 // indirect + golang.org/x/tools v0.22.0 // indirect golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect gonum.org/v1/gonum v0.15.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240515191416-fc5f0ca64291 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 8361e8757..183aad046 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -150,8 +150,8 @@ github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= -github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= @@ -397,8 +397,8 @@ github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0N github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= -github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM= +github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/koron/go-ssdp v0.0.4 h1:1IDwrghSKYM7yLf7XCzbByg2sJ/JcNOZRXS2jczTwz0= github.com/koron/go-ssdp v0.0.4/go.mod h1:oDXq+E5IL5q0U8uSBcoAXzTzInwy5lEgC91HoKtbmZk= @@ -425,8 +425,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.34.1 h1:fxn9vyLo7vJcXQRNvdRbyPjbzuQgi2UiqC8hEbn8a18= -github.com/libp2p/go-libp2p v0.34.1/go.mod h1:snyJQix4ET6Tj+LeI0VPjjxTtdWpeOhYt5lEY0KirkQ= +github.com/libp2p/go-libp2p v0.35.1 h1:Hm7Ub2BF+GCb14ojcsEK6WAy5it5smPDK02iXSZLl50= +github.com/libp2p/go-libp2p v0.35.1/go.mod h1:Dnkgba5hsfSv5dvvXC8nfqk44hH0gIKKno+HOMU0fdc= github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94= github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= @@ -586,8 +586,8 @@ github.com/pion/datachannel v1.5.6/go.mod h1:1eKT6Q85pRnr2mHiWHxJwO50SfZRtWHTsNI github.com/pion/dtls/v2 v2.2.7/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s= github.com/pion/dtls/v2 v2.2.11 h1:9U/dpCYl1ySttROPWJgqWKEylUdT0fXp/xst6JwY5Ks= github.com/pion/dtls/v2 v2.2.11/go.mod h1:d9SYc9fch0CqK90mRk1dC7AkzzpwJj6u2GU3u+9pqFE= -github.com/pion/ice/v2 v2.3.24 h1:RYgzhH/u5lH0XO+ABatVKCtRd+4U1GEaCXSMjNr13tI= -github.com/pion/ice/v2 v2.3.24/go.mod h1:KXJJcZK7E8WzrBEYnV4UtqEZsGeWfHxsNqhVcVvgjxw= +github.com/pion/ice/v2 v2.3.25 h1:M5rJA07dqhi3nobJIg+uPtcVjFECTrhcR3n0ns8kDZs= +github.com/pion/ice/v2 v2.3.25/go.mod h1:KXJJcZK7E8WzrBEYnV4UtqEZsGeWfHxsNqhVcVvgjxw= github.com/pion/interceptor v0.1.29 h1:39fsnlP1U8gw2JzOFWdfCU82vHvhW9o0rZnZF56wF+M= github.com/pion/interceptor v0.1.29/go.mod h1:ri+LGNjRUc5xUNtDEPzfdkmSqISixVTBF/z/Zms/6T4= github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY= @@ -641,11 +641,11 @@ github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1: github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.53.0 h1:U2pL9w9nmJwJDa4qqLQ3ZaePJ6ZTwt7cMD3AG3+aLCE= -github.com/prometheus/common v0.53.0/go.mod h1:BrxBKv3FWBIGXw89Mg1AeBq7FSyRzXWI3l3e7W3RN5U= +github.com/prometheus/common v0.54.0 h1:ZlZy0BgJhTwVZUn7dLOkwCZHUkrAqd3WYtcFCWnM1D8= +github.com/prometheus/common v0.54.0/go.mod h1:/TQgMJP5CuVYveyT7n/0Ix8yLNNXy9yRSkhnLTHPDIQ= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.15.0 h1:A82kmvXJq2jTu5YUhSGNlYoxh85zLnKgPz4bMZgI5Ek= -github.com/prometheus/procfs v0.15.0/go.mod h1:Y0RJ/Y5g5wJpkTisOtqwDSo4HwhGmLB4VQSw2sQJLHk= +github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= +github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= github.com/quic-go/quic-go v0.44.0 h1:So5wOr7jyO4vzL2sd8/pD9Kesciv91zSk8BoFngItQ0= @@ -753,8 +753,8 @@ github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc h1:BCPnHtcboa github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc/go.mod h1:r45hJU7yEoA81k6MWNhpMj/kms0n14dkzkxYHoB96UM= github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11 h1:5HZfQkwe0mIfyDmc1Em5GqlNRzcdtlv4HTNmdpt7XH0= github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11/go.mod h1:Wlo/SzPmxVp6vXpGt/zaXhHH0fn4IxgqZc82aKg6bpQ= -github.com/whyrusleeping/cbor-gen v0.1.1 h1:eKfcJIoxivjMtwfCfmJAqSF56MHcWqyIScXwaC1VBgw= -github.com/whyrusleeping/cbor-gen v0.1.1/go.mod h1:pM99HXyEbSQHcosHc0iW7YFmwnscr+t9Te4ibko05so= +github.com/whyrusleeping/cbor-gen v0.1.2 h1:WQFlrPhpcQl+M2/3dP5cvlTLWPVsL6LGBb9jJt6l/cA= +github.com/whyrusleeping/cbor-gen v0.1.2/go.mod h1:pM99HXyEbSQHcosHc0iW7YFmwnscr+t9Te4ibko05so= github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f h1:jQa4QT2UP9WYv2nzyawpKMOCl+Z/jW7djv2/J50lj9E= github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f/go.mod h1:p9UJB6dDgdPgMJZs7UjUOdulKyRr9fqkS+6JKAInPy8= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 h1:EKhdznlJHPMoKr0XTrX+IlJs1LH3lyx2nfr1dOlZ79k= @@ -778,8 +778,8 @@ go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.51.0 h1:Xs2Ncz0gNihqu9iosIZ5SkBbWo5T8JhhLJFMQL1qmLI= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.51.0/go.mod h1:vy+2G/6NvVMpwGX/NyLqcC41fxepnuKHk16E6IZUcJc= -go.opentelemetry.io/otel v1.26.0 h1:LQwgL5s/1W7YiiRwxf03QGnWLb2HW4pLiAhaA5cZXBs= -go.opentelemetry.io/otel v1.26.0/go.mod h1:UmLkJHUAidDval2EICqBMbnAd0/m2vmpf/dAM+fvFs4= +go.opentelemetry.io/otel v1.27.0 h1:9BZoF3yMK/O1AafMiQTVu0YDj5Ea4hPhxCs7sGva+cg= +go.opentelemetry.io/otel v1.27.0/go.mod h1:DMpAK8fzYRzs+bi3rS5REupisuqTheUlSZJ1WnZaPAQ= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.26.0 h1:1u/AyyOqAWzy+SkPxDpahCNZParHV8Vid1RnI2clyDE= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.26.0/go.mod h1:z46paqbJ9l7c9fIPCXTqTGwhQZ5XoTIsfeFYWboizjs= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.26.0 h1:Waw9Wfpo/IXzOI8bCB7DIk+0JZcqqsyn1JFnAc+iam8= @@ -790,12 +790,12 @@ go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.26.0 h1:0W5o9SzoR15ocYH go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.26.0/go.mod h1:zVZ8nz+VSggWmnh6tTsJqXQ7rU4xLwRtna1M4x5jq58= go.opentelemetry.io/otel/exporters/zipkin v1.26.0 h1:sBk6A62GgcQRwcxcBwRMPkqeuSizcpHkXyZNyP281Fw= go.opentelemetry.io/otel/exporters/zipkin v1.26.0/go.mod h1:fLzYtPUxPFzu7rSqhYsCxYheT2dNoPjtKovCLzLm07w= -go.opentelemetry.io/otel/metric v1.26.0 h1:7S39CLuY5Jgg9CrnA9HHiEjGMF/X2VHvoXGgSllRz30= -go.opentelemetry.io/otel/metric v1.26.0/go.mod h1:SY+rHOI4cEawI9a7N1A4nIg/nTQXe1ccCNWYOJUrpX4= +go.opentelemetry.io/otel/metric v1.27.0 h1:hvj3vdEKyeCi4YaYfNjv2NUje8FqKqUY8IlF0FxV/ik= +go.opentelemetry.io/otel/metric v1.27.0/go.mod h1:mVFgmRlhljgBiuk/MP/oKylr4hs85GZAylncepAX/ak= go.opentelemetry.io/otel/sdk v1.26.0 h1:Y7bumHf5tAiDlRYFmGqetNcLaVUZmh4iYfmGxtmz7F8= go.opentelemetry.io/otel/sdk v1.26.0/go.mod h1:0p8MXpqLeJ0pzcszQQN4F0S5FVjBLgypeGSngLsmirs= -go.opentelemetry.io/otel/trace v1.26.0 h1:1ieeAUb4y0TE26jUFrCIXKpTuVK7uJGN9/Z/2LP5sQA= -go.opentelemetry.io/otel/trace v1.26.0/go.mod h1:4iDxvGDQuUkHve82hJJ8UqrwswHYsZuWCBllGV2U2y0= +go.opentelemetry.io/otel/trace v1.27.0 h1:IqYb813p7cmbHk0a5y6pD5JPakbVfftRXABGt5/Rscw= +go.opentelemetry.io/otel/trace v1.27.0/go.mod h1:6RiD1hkAprV4/q+yd2ln1HG9GoPx39SuvvstaLBl+l4= go.opentelemetry.io/proto/otlp v1.2.0 h1:pVeZGk7nXDC9O2hncA6nHldxEjm6LByfA2aN8IOkz94= go.opentelemetry.io/proto/otlp v1.2.0/go.mod h1:gGpR8txAl5M03pDhMC79G6SdqNV26naRm/KDsgaHD8A= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= @@ -851,8 +851,8 @@ golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98y golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= -golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= -golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= +golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= +golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -861,8 +861,8 @@ golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM= -golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc= +golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8 h1:LoYXNGAShUG3m/ehNk4iFctuhGX/+R1ZpfJ4/ia80JM= +golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -886,8 +886,8 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= -golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0= +golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -926,8 +926,8 @@ golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= -golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= -golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= +golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= +golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1004,8 +1004,8 @@ golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= -golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= +golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -1029,8 +1029,8 @@ golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= -golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1073,8 +1073,8 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.21.0 h1:qc0xYgIbsSDt9EyWz05J5wfa7LOVW0YTLOXrqdLAWIw= -golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= +golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA= +golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/go.mod b/go.mod index 062c44d2c..2abdfacae 100644 --- a/go.mod +++ b/go.mod @@ -47,7 +47,7 @@ require ( github.com/jbenet/goprocess v0.1.4 github.com/julienschmidt/httprouter v1.3.0 github.com/libp2p/go-doh-resolver v0.4.0 - github.com/libp2p/go-libp2p v0.34.1 + github.com/libp2p/go-libp2p v0.35.1 github.com/libp2p/go-libp2p-http v0.5.0 github.com/libp2p/go-libp2p-kad-dht v0.25.2 github.com/libp2p/go-libp2p-kbucket v0.6.3 @@ -75,18 +75,18 @@ require ( go.opencensus.io v0.24.0 go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.51.0 go.opentelemetry.io/contrib/propagators/autoprop v0.46.1 - go.opentelemetry.io/otel v1.26.0 + go.opentelemetry.io/otel v1.27.0 go.opentelemetry.io/otel/sdk v1.26.0 - go.opentelemetry.io/otel/trace v1.26.0 + go.opentelemetry.io/otel/trace v1.27.0 go.uber.org/dig v1.17.1 go.uber.org/fx v1.21.1 go.uber.org/multierr v1.11.0 go.uber.org/zap v1.27.0 - golang.org/x/crypto v0.23.0 - golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 - golang.org/x/mod v0.17.0 + golang.org/x/crypto v0.24.0 + golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8 + golang.org/x/mod v0.18.0 golang.org/x/sync v0.7.0 - golang.org/x/sys v0.20.0 + golang.org/x/sys v0.21.0 google.golang.org/protobuf v1.34.1 ) @@ -114,7 +114,7 @@ require ( github.com/gabriel-vasile/mimetype v1.4.3 // indirect github.com/go-kit/log v0.2.1 // indirect github.com/go-logfmt/logfmt v0.5.1 // indirect - github.com/go-logr/logr v1.4.1 // indirect + github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-task/slim-sprig/v3 v3.0.0 // indirect github.com/godbus/dbus/v5 v5.1.0 // indirect @@ -147,7 +147,7 @@ require ( github.com/ipfs/go-verifcid v0.0.3 // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/klauspost/compress v1.17.8 // indirect - github.com/klauspost/cpuid/v2 v2.2.7 // indirect + github.com/klauspost/cpuid/v2 v2.2.8 // indirect github.com/koron/go-ssdp v0.0.4 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/libp2p/go-cidranger v1.1.0 // indirect @@ -182,7 +182,7 @@ require ( github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 // indirect github.com/pion/datachannel v1.5.6 // indirect github.com/pion/dtls/v2 v2.2.11 // indirect - github.com/pion/ice/v2 v2.3.24 // indirect + github.com/pion/ice/v2 v2.3.25 // indirect github.com/pion/interceptor v0.1.29 // indirect github.com/pion/logging v0.2.2 // indirect github.com/pion/mdns v0.0.12 // indirect @@ -200,8 +200,8 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect github.com/polydawn/refmt v0.89.0 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.53.0 // indirect - github.com/prometheus/procfs v0.15.0 // indirect + github.com/prometheus/common v0.54.0 // indirect + github.com/prometheus/procfs v0.15.1 // indirect github.com/prometheus/statsd_exporter v0.22.7 // indirect github.com/quic-go/qpack v0.4.0 // indirect github.com/quic-go/quic-go v0.44.0 // indirect @@ -216,7 +216,7 @@ require ( github.com/ucarion/urlpath v0.0.0-20200424170820-7ccc79b76bbb // indirect github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc // indirect github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11 // indirect - github.com/whyrusleeping/cbor-gen v0.1.1 // indirect + github.com/whyrusleeping/cbor-gen v0.1.2 // indirect github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f // indirect github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect go.opentelemetry.io/contrib/propagators/aws v1.21.1 // indirect @@ -228,16 +228,16 @@ require ( go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.26.0 // indirect go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.26.0 // indirect go.opentelemetry.io/otel/exporters/zipkin v1.26.0 // indirect - go.opentelemetry.io/otel/metric v1.26.0 // indirect + go.opentelemetry.io/otel/metric v1.27.0 // indirect go.opentelemetry.io/proto/otlp v1.2.0 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/mock v0.4.0 // indirect go4.org v0.0.0-20230225012048-214862532bf5 // indirect - golang.org/x/net v0.25.0 // indirect + golang.org/x/net v0.26.0 // indirect golang.org/x/oauth2 v0.20.0 // indirect - golang.org/x/term v0.20.0 // indirect - golang.org/x/text v0.15.0 // indirect - golang.org/x/tools v0.21.0 // indirect + golang.org/x/term v0.21.0 // indirect + golang.org/x/text v0.16.0 // indirect + golang.org/x/tools v0.22.0 // indirect golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect gonum.org/v1/gonum v0.15.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240515191416-fc5f0ca64291 // indirect diff --git a/go.sum b/go.sum index b5e133f92..b02bced7a 100644 --- a/go.sum +++ b/go.sum @@ -196,8 +196,8 @@ github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA= github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= -github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= @@ -476,8 +476,8 @@ github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0N github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= -github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM= +github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/koron/go-ssdp v0.0.4 h1:1IDwrghSKYM7yLf7XCzbByg2sJ/JcNOZRXS2jczTwz0= @@ -506,8 +506,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.34.1 h1:fxn9vyLo7vJcXQRNvdRbyPjbzuQgi2UiqC8hEbn8a18= -github.com/libp2p/go-libp2p v0.34.1/go.mod h1:snyJQix4ET6Tj+LeI0VPjjxTtdWpeOhYt5lEY0KirkQ= +github.com/libp2p/go-libp2p v0.35.1 h1:Hm7Ub2BF+GCb14ojcsEK6WAy5it5smPDK02iXSZLl50= +github.com/libp2p/go-libp2p v0.35.1/go.mod h1:Dnkgba5hsfSv5dvvXC8nfqk44hH0gIKKno+HOMU0fdc= github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94= github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= @@ -688,8 +688,8 @@ github.com/pion/datachannel v1.5.6/go.mod h1:1eKT6Q85pRnr2mHiWHxJwO50SfZRtWHTsNI github.com/pion/dtls/v2 v2.2.7/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s= github.com/pion/dtls/v2 v2.2.11 h1:9U/dpCYl1ySttROPWJgqWKEylUdT0fXp/xst6JwY5Ks= github.com/pion/dtls/v2 v2.2.11/go.mod h1:d9SYc9fch0CqK90mRk1dC7AkzzpwJj6u2GU3u+9pqFE= -github.com/pion/ice/v2 v2.3.24 h1:RYgzhH/u5lH0XO+ABatVKCtRd+4U1GEaCXSMjNr13tI= -github.com/pion/ice/v2 v2.3.24/go.mod h1:KXJJcZK7E8WzrBEYnV4UtqEZsGeWfHxsNqhVcVvgjxw= +github.com/pion/ice/v2 v2.3.25 h1:M5rJA07dqhi3nobJIg+uPtcVjFECTrhcR3n0ns8kDZs= +github.com/pion/ice/v2 v2.3.25/go.mod h1:KXJJcZK7E8WzrBEYnV4UtqEZsGeWfHxsNqhVcVvgjxw= github.com/pion/interceptor v0.1.29 h1:39fsnlP1U8gw2JzOFWdfCU82vHvhW9o0rZnZF56wF+M= github.com/pion/interceptor v0.1.29/go.mod h1:ri+LGNjRUc5xUNtDEPzfdkmSqISixVTBF/z/Zms/6T4= github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY= @@ -761,8 +761,8 @@ github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9 github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/common v0.35.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= -github.com/prometheus/common v0.53.0 h1:U2pL9w9nmJwJDa4qqLQ3ZaePJ6ZTwt7cMD3AG3+aLCE= -github.com/prometheus/common v0.53.0/go.mod h1:BrxBKv3FWBIGXw89Mg1AeBq7FSyRzXWI3l3e7W3RN5U= +github.com/prometheus/common v0.54.0 h1:ZlZy0BgJhTwVZUn7dLOkwCZHUkrAqd3WYtcFCWnM1D8= +github.com/prometheus/common v0.54.0/go.mod h1:/TQgMJP5CuVYveyT7n/0Ix8yLNNXy9yRSkhnLTHPDIQ= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= @@ -771,8 +771,8 @@ github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4O github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= -github.com/prometheus/procfs v0.15.0 h1:A82kmvXJq2jTu5YUhSGNlYoxh85zLnKgPz4bMZgI5Ek= -github.com/prometheus/procfs v0.15.0/go.mod h1:Y0RJ/Y5g5wJpkTisOtqwDSo4HwhGmLB4VQSw2sQJLHk= +github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= +github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/prometheus/statsd_exporter v0.22.7 h1:7Pji/i2GuhK6Lu7DHrtTkFmNBCudCPT1pX2CziuyQR0= github.com/prometheus/statsd_exporter v0.22.7/go.mod h1:N/TevpjkIh9ccs6nuzY3jQn9dFqnUakOjnEuMPJJJnI= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= @@ -899,8 +899,8 @@ github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc h1:BCPnHtcboa github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc/go.mod h1:r45hJU7yEoA81k6MWNhpMj/kms0n14dkzkxYHoB96UM= github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11 h1:5HZfQkwe0mIfyDmc1Em5GqlNRzcdtlv4HTNmdpt7XH0= github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11/go.mod h1:Wlo/SzPmxVp6vXpGt/zaXhHH0fn4IxgqZc82aKg6bpQ= -github.com/whyrusleeping/cbor-gen v0.1.1 h1:eKfcJIoxivjMtwfCfmJAqSF56MHcWqyIScXwaC1VBgw= -github.com/whyrusleeping/cbor-gen v0.1.1/go.mod h1:pM99HXyEbSQHcosHc0iW7YFmwnscr+t9Te4ibko05so= +github.com/whyrusleeping/cbor-gen v0.1.2 h1:WQFlrPhpcQl+M2/3dP5cvlTLWPVsL6LGBb9jJt6l/cA= +github.com/whyrusleeping/cbor-gen v0.1.2/go.mod h1:pM99HXyEbSQHcosHc0iW7YFmwnscr+t9Te4ibko05so= github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f h1:jQa4QT2UP9WYv2nzyawpKMOCl+Z/jW7djv2/J50lj9E= github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f/go.mod h1:p9UJB6dDgdPgMJZs7UjUOdulKyRr9fqkS+6JKAInPy8= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 h1:EKhdznlJHPMoKr0XTrX+IlJs1LH3lyx2nfr1dOlZ79k= @@ -940,8 +940,8 @@ go.opentelemetry.io/contrib/propagators/jaeger v1.21.1 h1:f4beMGDKiVzg9IcX7/VuWV go.opentelemetry.io/contrib/propagators/jaeger v1.21.1/go.mod h1:U9jhkEl8d1LL+QXY7q3kneJWJugiN3kZJV2OWz3hkBY= go.opentelemetry.io/contrib/propagators/ot v1.21.1 h1:3TN5vkXjKYWp0YdMcnUEC/A+pBPvqz9V3nCS2xmcurk= go.opentelemetry.io/contrib/propagators/ot v1.21.1/go.mod h1:oy0MYCbS/b3cqUDW37wBWtlwBIsutngS++Lklpgh+fc= -go.opentelemetry.io/otel v1.26.0 h1:LQwgL5s/1W7YiiRwxf03QGnWLb2HW4pLiAhaA5cZXBs= -go.opentelemetry.io/otel v1.26.0/go.mod h1:UmLkJHUAidDval2EICqBMbnAd0/m2vmpf/dAM+fvFs4= +go.opentelemetry.io/otel v1.27.0 h1:9BZoF3yMK/O1AafMiQTVu0YDj5Ea4hPhxCs7sGva+cg= +go.opentelemetry.io/otel v1.27.0/go.mod h1:DMpAK8fzYRzs+bi3rS5REupisuqTheUlSZJ1WnZaPAQ= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.26.0 h1:1u/AyyOqAWzy+SkPxDpahCNZParHV8Vid1RnI2clyDE= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.26.0/go.mod h1:z46paqbJ9l7c9fIPCXTqTGwhQZ5XoTIsfeFYWboizjs= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.26.0 h1:Waw9Wfpo/IXzOI8bCB7DIk+0JZcqqsyn1JFnAc+iam8= @@ -952,12 +952,12 @@ go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.26.0 h1:0W5o9SzoR15ocYH go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.26.0/go.mod h1:zVZ8nz+VSggWmnh6tTsJqXQ7rU4xLwRtna1M4x5jq58= go.opentelemetry.io/otel/exporters/zipkin v1.26.0 h1:sBk6A62GgcQRwcxcBwRMPkqeuSizcpHkXyZNyP281Fw= go.opentelemetry.io/otel/exporters/zipkin v1.26.0/go.mod h1:fLzYtPUxPFzu7rSqhYsCxYheT2dNoPjtKovCLzLm07w= -go.opentelemetry.io/otel/metric v1.26.0 h1:7S39CLuY5Jgg9CrnA9HHiEjGMF/X2VHvoXGgSllRz30= -go.opentelemetry.io/otel/metric v1.26.0/go.mod h1:SY+rHOI4cEawI9a7N1A4nIg/nTQXe1ccCNWYOJUrpX4= +go.opentelemetry.io/otel/metric v1.27.0 h1:hvj3vdEKyeCi4YaYfNjv2NUje8FqKqUY8IlF0FxV/ik= +go.opentelemetry.io/otel/metric v1.27.0/go.mod h1:mVFgmRlhljgBiuk/MP/oKylr4hs85GZAylncepAX/ak= go.opentelemetry.io/otel/sdk v1.26.0 h1:Y7bumHf5tAiDlRYFmGqetNcLaVUZmh4iYfmGxtmz7F8= go.opentelemetry.io/otel/sdk v1.26.0/go.mod h1:0p8MXpqLeJ0pzcszQQN4F0S5FVjBLgypeGSngLsmirs= -go.opentelemetry.io/otel/trace v1.26.0 h1:1ieeAUb4y0TE26jUFrCIXKpTuVK7uJGN9/Z/2LP5sQA= -go.opentelemetry.io/otel/trace v1.26.0/go.mod h1:4iDxvGDQuUkHve82hJJ8UqrwswHYsZuWCBllGV2U2y0= +go.opentelemetry.io/otel/trace v1.27.0 h1:IqYb813p7cmbHk0a5y6pD5JPakbVfftRXABGt5/Rscw= +go.opentelemetry.io/otel/trace v1.27.0/go.mod h1:6RiD1hkAprV4/q+yd2ln1HG9GoPx39SuvvstaLBl+l4= go.opentelemetry.io/proto/otlp v1.2.0 h1:pVeZGk7nXDC9O2hncA6nHldxEjm6LByfA2aN8IOkz94= go.opentelemetry.io/proto/otlp v1.2.0/go.mod h1:gGpR8txAl5M03pDhMC79G6SdqNV26naRm/KDsgaHD8A= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= @@ -1013,8 +1013,8 @@ golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98y golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= -golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= -golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= +golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= +golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1025,8 +1025,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM= -golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc= +golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8 h1:LoYXNGAShUG3m/ehNk4iFctuhGX/+R1ZpfJ4/ia80JM= +golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1051,8 +1051,8 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= -golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0= +golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1108,8 +1108,8 @@ golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= -golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= -golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= +golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= +golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1215,8 +1215,8 @@ golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= -golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= +golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -1228,8 +1228,8 @@ golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= -golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw= -golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= +golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA= +golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1242,8 +1242,8 @@ golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= -golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1303,8 +1303,8 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.21.0 h1:qc0xYgIbsSDt9EyWz05J5wfa7LOVW0YTLOXrqdLAWIw= -golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= +golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA= +golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index f78ed4bfe..18ef713ae 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -65,7 +65,7 @@ require ( github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/fzipp/gocyclo v0.6.0 // indirect github.com/go-critic/go-critic v0.9.0 // indirect - github.com/go-logr/logr v1.4.1 // indirect + github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-toolsmith/astcast v1.1.0 // indirect github.com/go-toolsmith/astcopy v1.1.0 // indirect @@ -126,7 +126,7 @@ require ( github.com/kisielk/errcheck v1.6.3 // indirect github.com/kisielk/gotool v1.0.0 // indirect github.com/kkHAIKE/contextcheck v1.1.4 // indirect - github.com/klauspost/cpuid/v2 v2.2.7 // indirect + github.com/klauspost/cpuid/v2 v2.2.8 // indirect github.com/kulti/thelper v0.6.3 // indirect github.com/kunwardeep/paralleltest v1.0.8 // indirect github.com/kyoh86/exportloopref v0.1.11 // indirect @@ -135,7 +135,7 @@ require ( github.com/leonklingele/grouper v1.1.1 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/libp2p/go-cidranger v1.1.0 // indirect - github.com/libp2p/go-libp2p v0.34.1 // indirect + github.com/libp2p/go-libp2p v0.35.1 // indirect github.com/libp2p/go-libp2p-asn-util v0.4.1 // indirect github.com/libp2p/go-libp2p-kad-dht v0.25.2 // indirect github.com/libp2p/go-libp2p-kbucket v0.6.3 // indirect @@ -182,8 +182,8 @@ require ( github.com/polyfloyd/go-errorlint v1.4.3 // indirect github.com/prometheus/client_golang v1.19.1 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.53.0 // indirect - github.com/prometheus/procfs v0.15.0 // indirect + github.com/prometheus/common v0.54.0 // indirect + github.com/prometheus/procfs v0.15.1 // indirect github.com/quasilyte/go-ruleguard v0.4.0 // indirect github.com/quasilyte/gogrep v0.5.0 // indirect github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727 // indirect @@ -234,22 +234,22 @@ require ( github.com/ykadowak/zerologlint v0.1.3 // indirect gitlab.com/bosi/decorder v0.4.0 // indirect go.opencensus.io v0.24.0 // indirect - go.opentelemetry.io/otel v1.26.0 // indirect - go.opentelemetry.io/otel/metric v1.26.0 // indirect - go.opentelemetry.io/otel/trace v1.26.0 // indirect + go.opentelemetry.io/otel v1.27.0 // indirect + go.opentelemetry.io/otel/metric v1.27.0 // indirect + go.opentelemetry.io/otel/trace v1.27.0 // indirect go.tmz.dev/musttag v0.7.1 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect - golang.org/x/crypto v0.23.0 // indirect - golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect + golang.org/x/crypto v0.24.0 // indirect + golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8 // indirect golang.org/x/exp/typeparams v0.0.0-20230307190834-24139beb5833 // indirect - golang.org/x/mod v0.17.0 // indirect - golang.org/x/net v0.25.0 // indirect + golang.org/x/mod v0.18.0 // indirect + golang.org/x/net v0.26.0 // indirect golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.20.0 // indirect - golang.org/x/term v0.20.0 // indirect - golang.org/x/text v0.15.0 // indirect - golang.org/x/tools v0.21.0 // indirect + golang.org/x/sys v0.21.0 // indirect + golang.org/x/term v0.21.0 // indirect + golang.org/x/text v0.16.0 // indirect + golang.org/x/tools v0.22.0 // indirect gonum.org/v1/gonum v0.15.0 // indirect google.golang.org/protobuf v1.34.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index e221fd652..4b3048257 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -186,8 +186,8 @@ github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9 github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= -github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= @@ -448,8 +448,8 @@ github.com/kkHAIKE/contextcheck v1.1.4 h1:B6zAaLhOEEcjvUgIYEqystmnFk1Oemn8bvJhbt github.com/kkHAIKE/contextcheck v1.1.4/go.mod h1:1+i/gWqokIa+dm31mqGLZhZJ7Uh44DJGZVmr6QRBNJg= github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU= github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= -github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= -github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM= +github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/koron/go-ssdp v0.0.4 h1:1IDwrghSKYM7yLf7XCzbByg2sJ/JcNOZRXS2jczTwz0= @@ -481,8 +481,8 @@ github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38y github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.34.1 h1:fxn9vyLo7vJcXQRNvdRbyPjbzuQgi2UiqC8hEbn8a18= -github.com/libp2p/go-libp2p v0.34.1/go.mod h1:snyJQix4ET6Tj+LeI0VPjjxTtdWpeOhYt5lEY0KirkQ= +github.com/libp2p/go-libp2p v0.35.1 h1:Hm7Ub2BF+GCb14ojcsEK6WAy5it5smPDK02iXSZLl50= +github.com/libp2p/go-libp2p v0.35.1/go.mod h1:Dnkgba5hsfSv5dvvXC8nfqk44hH0gIKKno+HOMU0fdc= github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94= github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= github.com/libp2p/go-libp2p-kad-dht v0.25.2 h1:FOIk9gHoe4YRWXTu8SY9Z1d0RILol0TrtApsMDPjAVQ= @@ -624,8 +624,8 @@ github.com/pion/datachannel v1.5.6 h1:1IxKJntfSlYkpUj8LlYRSWpYiTTC02nUrOE8T3DqGe github.com/pion/datachannel v1.5.6/go.mod h1:1eKT6Q85pRnr2mHiWHxJwO50SfZRtWHTsNIVb/NfGW4= github.com/pion/dtls/v2 v2.2.11 h1:9U/dpCYl1ySttROPWJgqWKEylUdT0fXp/xst6JwY5Ks= github.com/pion/dtls/v2 v2.2.11/go.mod h1:d9SYc9fch0CqK90mRk1dC7AkzzpwJj6u2GU3u+9pqFE= -github.com/pion/ice/v2 v2.3.24 h1:RYgzhH/u5lH0XO+ABatVKCtRd+4U1GEaCXSMjNr13tI= -github.com/pion/ice/v2 v2.3.24/go.mod h1:KXJJcZK7E8WzrBEYnV4UtqEZsGeWfHxsNqhVcVvgjxw= +github.com/pion/ice/v2 v2.3.25 h1:M5rJA07dqhi3nobJIg+uPtcVjFECTrhcR3n0ns8kDZs= +github.com/pion/ice/v2 v2.3.25/go.mod h1:KXJJcZK7E8WzrBEYnV4UtqEZsGeWfHxsNqhVcVvgjxw= github.com/pion/interceptor v0.1.29 h1:39fsnlP1U8gw2JzOFWdfCU82vHvhW9o0rZnZF56wF+M= github.com/pion/interceptor v0.1.29/go.mod h1:ri+LGNjRUc5xUNtDEPzfdkmSqISixVTBF/z/Zms/6T4= github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY= @@ -680,15 +680,15 @@ github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8 github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= -github.com/prometheus/common v0.53.0 h1:U2pL9w9nmJwJDa4qqLQ3ZaePJ6ZTwt7cMD3AG3+aLCE= -github.com/prometheus/common v0.53.0/go.mod h1:BrxBKv3FWBIGXw89Mg1AeBq7FSyRzXWI3l3e7W3RN5U= +github.com/prometheus/common v0.54.0 h1:ZlZy0BgJhTwVZUn7dLOkwCZHUkrAqd3WYtcFCWnM1D8= +github.com/prometheus/common v0.54.0/go.mod h1:/TQgMJP5CuVYveyT7n/0Ix8yLNNXy9yRSkhnLTHPDIQ= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.15.0 h1:A82kmvXJq2jTu5YUhSGNlYoxh85zLnKgPz4bMZgI5Ek= -github.com/prometheus/procfs v0.15.0/go.mod h1:Y0RJ/Y5g5wJpkTisOtqwDSo4HwhGmLB4VQSw2sQJLHk= +github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= +github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/quasilyte/go-ruleguard v0.4.0 h1:DyM6r+TKL+xbKB4Nm7Afd1IQh9kEUKQs2pboWGKtvQo= github.com/quasilyte/go-ruleguard v0.4.0/go.mod h1:Eu76Z/R8IXtViWUIHkE3p8gdH3/PKk1eh3YGfaEof10= github.com/quasilyte/gogrep v0.5.0 h1:eTKODPXbI8ffJMN+W2aE0+oL0z/nh8/5eNdiO34SOAo= @@ -851,12 +851,12 @@ go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/otel v1.26.0 h1:LQwgL5s/1W7YiiRwxf03QGnWLb2HW4pLiAhaA5cZXBs= -go.opentelemetry.io/otel v1.26.0/go.mod h1:UmLkJHUAidDval2EICqBMbnAd0/m2vmpf/dAM+fvFs4= -go.opentelemetry.io/otel/metric v1.26.0 h1:7S39CLuY5Jgg9CrnA9HHiEjGMF/X2VHvoXGgSllRz30= -go.opentelemetry.io/otel/metric v1.26.0/go.mod h1:SY+rHOI4cEawI9a7N1A4nIg/nTQXe1ccCNWYOJUrpX4= -go.opentelemetry.io/otel/trace v1.26.0 h1:1ieeAUb4y0TE26jUFrCIXKpTuVK7uJGN9/Z/2LP5sQA= -go.opentelemetry.io/otel/trace v1.26.0/go.mod h1:4iDxvGDQuUkHve82hJJ8UqrwswHYsZuWCBllGV2U2y0= +go.opentelemetry.io/otel v1.27.0 h1:9BZoF3yMK/O1AafMiQTVu0YDj5Ea4hPhxCs7sGva+cg= +go.opentelemetry.io/otel v1.27.0/go.mod h1:DMpAK8fzYRzs+bi3rS5REupisuqTheUlSZJ1WnZaPAQ= +go.opentelemetry.io/otel/metric v1.27.0 h1:hvj3vdEKyeCi4YaYfNjv2NUje8FqKqUY8IlF0FxV/ik= +go.opentelemetry.io/otel/metric v1.27.0/go.mod h1:mVFgmRlhljgBiuk/MP/oKylr4hs85GZAylncepAX/ak= +go.opentelemetry.io/otel/trace v1.27.0 h1:IqYb813p7cmbHk0a5y6pD5JPakbVfftRXABGt5/Rscw= +go.opentelemetry.io/otel/trace v1.27.0/go.mod h1:6RiD1hkAprV4/q+yd2ln1HG9GoPx39SuvvstaLBl+l4= go.tmz.dev/musttag v0.7.1 h1:9lFmeSFnFfPuMq4IksHGomItE6NgKMNW2Nt2FPOhCfU= go.tmz.dev/musttag v0.7.1/go.mod h1:oJLkpR56EsIryktZJk/B0IroSMi37YWver47fibGh5U= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= @@ -890,8 +890,8 @@ golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= -golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= -golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= +golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= +golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -902,8 +902,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM= -golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc= +golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8 h1:LoYXNGAShUG3m/ehNk4iFctuhGX/+R1ZpfJ4/ia80JM= +golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI= golang.org/x/exp/typeparams v0.0.0-20220428152302-39d4317da171/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/exp/typeparams v0.0.0-20230203172020-98cc5a0785f9/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/exp/typeparams v0.0.0-20230307190834-24139beb5833 h1:jWGQJV4niP+CCmFW9ekjA9Zx8vYORzOUH2/Nl5WPuLQ= @@ -938,8 +938,8 @@ golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91 golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= -golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0= +golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -983,8 +983,8 @@ golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= -golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= +golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= +golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1072,16 +1072,16 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= -golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= +golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw= -golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= +golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA= +golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1093,8 +1093,8 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= -golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1172,8 +1172,8 @@ golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= golang.org/x/tools v0.5.0/go.mod h1:N+Kgy78s5I24c24dU8OfWNEotWjutIs8SnJvn5IDq+k= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.21.0 h1:qc0xYgIbsSDt9EyWz05J5wfa7LOVW0YTLOXrqdLAWIw= -golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= +golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA= +golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From e9fbc287ab0dc77729279ea07955c8529466dda3 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Tue, 18 Jun 2024 21:06:23 +0200 Subject: [PATCH 1108/1212] chore: gateway-conformance v6 (#10441) https://github.com/ipfs/gateway-conformance/releases/tag/v0.6.0 --- .github/workflows/gateway-conformance.yml | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/.github/workflows/gateway-conformance.yml b/.github/workflows/gateway-conformance.yml index 0f3698641..b1791868c 100644 --- a/.github/workflows/gateway-conformance.yml +++ b/.github/workflows/gateway-conformance.yml @@ -41,7 +41,7 @@ jobs: steps: # 1. Download the gateway-conformance fixtures - name: Download gateway-conformance fixtures - uses: ipfs/gateway-conformance/.github/actions/extract-fixtures@v0.5 + uses: ipfs/gateway-conformance/.github/actions/extract-fixtures@v0.6 with: output: fixtures @@ -84,9 +84,7 @@ jobs: # Import dnslink records # the IPFS_NS_MAP env will be used by the daemon - export IPFS_NS_MAP=$(cat "./fixtures/dnslinks.json" | jq -r '.subdomains | to_entries | map("\(.key).example.com:\(.value)") | join(",")') - export IPFS_NS_MAP="$(cat "./fixtures/dnslinks.json" | jq -r '.domains | to_entries | map("\(.key):\(.value)") | join(",")'),${IPFS_NS_MAP}" - echo "IPFS_NS_MAP=${IPFS_NS_MAP}" >> $GITHUB_ENV + echo "IPFS_NS_MAP=$(cat ./fixtures/dnslinks.IPFS_NS_MAP)" >> $GITHUB_ENV # 5. Start the kubo-gateway - name: Start kubo-gateway @@ -96,14 +94,15 @@ jobs: # 6. Run the gateway-conformance tests - name: Run gateway-conformance tests - uses: ipfs/gateway-conformance/.github/actions/test@v0.5 + uses: ipfs/gateway-conformance/.github/actions/test@v0.6 with: gateway-url: http://127.0.0.1:8080 + subdomain-url: http://localhost:8080 + args: -skip 'TestGatewayCar/GET_response_for_application/vnd.ipld.car/Header_Content-Length' json: output.json xml: output.xml html: output.html markdown: output.md - args: -skip 'TestGatewayCar/GET_response_for_application/vnd.ipld.car/Header_Content-Length' # 7. Upload the results - name: Upload MD summary @@ -129,7 +128,7 @@ jobs: steps: # 1. Download the gateway-conformance fixtures - name: Download gateway-conformance fixtures - uses: ipfs/gateway-conformance/.github/actions/extract-fixtures@v0.5 + uses: ipfs/gateway-conformance/.github/actions/extract-fixtures@v0.6 with: output: fixtures @@ -202,14 +201,14 @@ jobs: # 9. Run the gateway-conformance tests over libp2p - name: Run gateway-conformance tests over libp2p - uses: ipfs/gateway-conformance/.github/actions/test@v0.5 + uses: ipfs/gateway-conformance/.github/actions/test@v0.6 with: gateway-url: http://127.0.0.1:8092 + args: --specs "trustless-gateway,-trustless-ipns-gateway" -skip 'TestGatewayCar/GET_response_for_application/vnd.ipld.car/Header_Content-Length' json: output.json xml: output.xml html: output.html markdown: output.md - args: --specs "trustless-gateway,-trustless-ipns-gateway" -skip 'TestGatewayCar/GET_response_for_application/vnd.ipld.car/Header_Content-Length' # 10. Upload the results - name: Upload MD summary From f08d585a5aa464a0655fc0e5f26d8f7c0c86cbd6 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Fri, 21 Jun 2024 02:57:36 +0200 Subject: [PATCH 1109/1212] chore: update deps incl. boxo v0.21.0 (#10444) * chore: update dependencies * refactor: go lint * chore: boxo v0.21.0 https://github.com/ipfs/boxo/releases/tag/v0.21.0 --- cmd/ipfs/kubo/daemon.go | 6 +- docs/examples/kubo-as-a-library/go.mod | 54 +- docs/examples/kubo-as-a-library/go.sum | 117 ++-- go.mod | 48 +- go.sum | 104 +-- test/dependencies/go.mod | 194 +++--- test/dependencies/go.sum | 890 ++++++++----------------- 7 files changed, 554 insertions(+), 859 deletions(-) diff --git a/cmd/ipfs/kubo/daemon.go b/cmd/ipfs/kubo/daemon.go index ab034b20a..1d6ff5035 100644 --- a/cmd/ipfs/kubo/daemon.go +++ b/cmd/ipfs/kubo/daemon.go @@ -1027,7 +1027,11 @@ func YesNoPrompt(prompt string) bool { var s string for i := 0; i < 3; i++ { fmt.Printf("%s ", prompt) - fmt.Scanf("%s", &s) + _, err := fmt.Scanf("%s", &s) + if err != nil { + fmt.Printf("Invalid input: %v. Please try again.\n", err) + continue + } switch s { case "y", "Y": return true diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 7f12b7936..a8fc209d2 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -9,7 +9,7 @@ toolchain go1.22.0 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.20.0 + github.com/ipfs/boxo v0.21.0 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.35.1 github.com/multiformats/go-multiaddr v0.12.4 @@ -26,7 +26,6 @@ require ( github.com/blang/semver/v4 v4.0.0 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/ceramicnetwork/go-dag-jose v0.1.0 // indirect - github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/containerd/cgroups v1.1.0 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect @@ -36,27 +35,28 @@ require ( github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect github.com/dgraph-io/badger v1.6.2 // indirect - github.com/dgraph-io/ristretto v0.0.2 // indirect + github.com/dgraph-io/ristretto v0.1.1 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/dustin/go-humanize v1.0.1 // indirect - github.com/elastic/gosigar v0.14.2 // indirect + github.com/elastic/gosigar v0.14.3 // indirect github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/flynn/noise v1.1.0 // indirect github.com/francoispqt/gojay v1.2.13 // indirect - github.com/fsnotify/fsnotify v1.6.0 // indirect - github.com/gabriel-vasile/mimetype v1.4.3 // indirect + github.com/fsnotify/fsnotify v1.7.0 // indirect + github.com/gabriel-vasile/mimetype v1.4.4 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-task/slim-sprig/v3 v3.0.0 // indirect github.com/godbus/dbus/v5 v5.1.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/glog v1.2.1 // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/gopacket v1.1.19 // indirect - github.com/google/pprof v0.0.0-20240509144519-723abb6459b7 // indirect + github.com/google/pprof v0.0.0-20240618054019-d3b898a103f8 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/gorilla/websocket v1.5.1 // indirect + github.com/gorilla/websocket v1.5.3 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect @@ -102,7 +102,7 @@ require ( github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect github.com/jbenet/goprocess v0.1.4 // indirect - github.com/klauspost/compress v1.17.8 // indirect + github.com/klauspost/compress v1.17.9 // indirect github.com/klauspost/cpuid/v2 v2.2.8 // indirect github.com/koron/go-ssdp v0.0.4 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect @@ -125,7 +125,7 @@ require ( github.com/libp2p/zeroconf/v2 v2.2.0 // indirect github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/miekg/dns v1.1.59 // indirect + github.com/miekg/dns v1.1.61 // indirect github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect github.com/minio/sha256-simd v1.0.1 // indirect @@ -140,7 +140,7 @@ require ( github.com/multiformats/go-multihash v0.2.3 // indirect github.com/multiformats/go-multistream v0.5.0 // indirect github.com/multiformats/go-varint v0.0.7 // indirect - github.com/onsi/ginkgo/v2 v2.17.3 // indirect + github.com/onsi/ginkgo/v2 v2.19.0 // indirect github.com/opencontainers/runtime-spec v1.2.0 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/openzipkin/zipkin-go v0.4.3 // indirect @@ -161,7 +161,7 @@ require ( github.com/pion/stun v0.6.1 // indirect github.com/pion/transport/v2 v2.2.5 // indirect github.com/pion/turn/v2 v2.1.6 // indirect - github.com/pion/webrtc/v3 v3.2.40 // indirect + github.com/pion/webrtc/v3 v3.2.42 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/polydawn/refmt v0.89.0 // indirect @@ -170,7 +170,7 @@ require ( github.com/prometheus/common v0.54.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/quic-go/qpack v0.4.0 // indirect - github.com/quic-go/quic-go v0.44.0 // indirect + github.com/quic-go/quic-go v0.45.0 // indirect github.com/quic-go/webtransport-go v0.8.0 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/samber/lo v1.39.0 // indirect @@ -185,26 +185,26 @@ require ( github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 // indirect go.opencensus.io v0.24.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.51.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.52.0 // indirect go.opentelemetry.io/otel v1.27.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.26.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.26.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.26.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.26.0 // indirect - go.opentelemetry.io/otel/exporters/zipkin v1.26.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.27.0 // indirect + go.opentelemetry.io/otel/exporters/zipkin v1.27.0 // indirect go.opentelemetry.io/otel/metric v1.27.0 // indirect - go.opentelemetry.io/otel/sdk v1.26.0 // indirect + go.opentelemetry.io/otel/sdk v1.27.0 // indirect go.opentelemetry.io/otel/trace v1.27.0 // indirect - go.opentelemetry.io/proto/otlp v1.2.0 // indirect + go.opentelemetry.io/proto/otlp v1.3.1 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/dig v1.17.1 // indirect - go.uber.org/fx v1.21.1 // indirect + go.uber.org/fx v1.22.0 // indirect go.uber.org/mock v0.4.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect go4.org v0.0.0-20230225012048-214862532bf5 // indirect golang.org/x/crypto v0.24.0 // indirect - golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8 // indirect + golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 // indirect golang.org/x/mod v0.18.0 // indirect golang.org/x/net v0.26.0 // indirect golang.org/x/sync v0.7.0 // indirect @@ -213,11 +213,11 @@ require ( golang.org/x/tools v0.22.0 // indirect golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect gonum.org/v1/gonum v0.15.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240515191416-fc5f0ca64291 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240515191416-fc5f0ca64291 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240617180043-68d350f18fd4 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240617180043-68d350f18fd4 // indirect google.golang.org/grpc v1.64.0 // indirect - google.golang.org/protobuf v1.34.1 // indirect - gopkg.in/square/go-jose.v2 v2.5.1 // indirect + google.golang.org/protobuf v1.34.2 // indirect + gopkg.in/square/go-jose.v2 v2.6.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect lukechampine.com/blake3 v1.3.0 // indirect ) diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 183aad046..7ab48b7f6 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -31,7 +31,6 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/Jorropo/jsync v1.0.1 h1:6HgRolFZnsdfzRUj+ImB9og1JYOxQoReSywkHOGSaUU= github.com/Jorropo/jsync v1.0.1/go.mod h1:jCOZj3vrBCri3bSU3ErUYvevKlnbssrXeCivybS5ABQ= -github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= github.com/alecthomas/units v0.0.0-20231202071711-9a357b53e9c9 h1:ez/4by2iGztzR4L0zgAOR8lTQK9VlyBVVd7G4omaOQs= @@ -65,8 +64,8 @@ github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyY github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/ceramicnetwork/go-dag-jose v0.1.0 h1:yJ/HVlfKpnD3LdYP03AHyTvbm3BpPiz2oZiOeReJRdU= github.com/ceramicnetwork/go-dag-jose v0.1.0/go.mod h1:qYA1nYt0X8u4XoMAVoOV3upUVKtrxy/I670Dg5F0wjI= -github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= @@ -107,8 +106,9 @@ github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3 github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= github.com/dgraph-io/badger v1.6.2 h1:mNw0qs90GVgGGWylh0umH5iag1j6n/PeJtNvL6KY/x8= github.com/dgraph-io/badger v1.6.2/go.mod h1:JW2yswe3V058sS0kZ2h/AXeDSqFjxnZcRrVH//y2UQE= -github.com/dgraph-io/ristretto v0.0.2 h1:a5WaUrDa0qm0YrAAS1tUykT5El3kt62KNZZeMxQn3po= github.com/dgraph-io/ristretto v0.0.2/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= +github.com/dgraph-io/ristretto v0.1.1 h1:6CWw5tJNgpegArSHpNHJKldNeq03FQCwYvfMVWajOK8= +github.com/dgraph-io/ristretto v0.1.1/go.mod h1:S1GPSBCYCIhmVNfcth17y2zZtQT6wzkzgwUve0VDWWA= 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/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= @@ -118,8 +118,8 @@ github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25Kn github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/elastic/gosigar v0.12.0/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= -github.com/elastic/gosigar v0.14.2 h1:Dg80n8cr90OZ7x+bAax/QjoW/XqTI11RmA79ZwIm9/4= -github.com/elastic/gosigar v0.14.2/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= +github.com/elastic/gosigar v0.14.3 h1:xwkKwPia+hSfg9GqrCUKYdId102m9qTJIIr7egmK/uo= +github.com/elastic/gosigar v0.14.3/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -139,10 +139,10 @@ github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHk github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= -github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= -github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= -github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= +github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= +github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= +github.com/gabriel-vasile/mimetype v1.4.4 h1:QjV6pZ7/XZ7ryI2KuyeEDE8wnh7fHP9YnQy+R0LnH8I= +github.com/gabriel-vasile/mimetype v1.4.4/go.mod h1:JwLei5XPtWdGiMFB5Pjle1oEeoSeEuJfJE+TtfvdB/s= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= @@ -168,6 +168,8 @@ github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXP github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/glog v1.2.1 h1:OptwRhECazUx5ix5TTWC3EZhsZEHWcYWY4FQHTIubm4= +github.com/golang/glog v1.2.1/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -216,8 +218,8 @@ github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXi github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20240509144519-723abb6459b7 h1:velgFPYr1X9TDwLIfkV7fWqsFlf7TeP11M/7kPd/dVI= -github.com/google/pprof v0.0.0-20240509144519-723abb6459b7/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= +github.com/google/pprof v0.0.0-20240618054019-d3b898a103f8 h1:ASJ/LAqdCHOyMYI+dwNxn7Rd8FscNkMyTr1KZU1JI/M= +github.com/google/pprof v0.0.0-20240618054019-d3b898a103f8/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -233,8 +235,8 @@ github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c h1:7lF+Vz0LqiRid github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= -github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= -github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= +github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= +github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0= @@ -264,8 +266,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.20.0 h1:umUl7q1v5g5AX8FPLTnZBvvagLmT+V0Tt61EigP81ec= -github.com/ipfs/boxo v0.20.0/go.mod h1:mwttn53Eibgska2DhVIj7ln3UViq7MVHRxOMb+ehSDM= +github.com/ipfs/boxo v0.21.0 h1:XpGXb+TQQ0IUdYaeAxGzWjSs6ow/Lce148A/2IbRDVE= +github.com/ipfs/boxo v0.21.0/go.mod h1:NmweAYeY1USOaJJxouy7DLr/Y5M8UBSsCI2KRivO+TY= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= @@ -393,8 +395,8 @@ github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQL 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.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU= -github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= +github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM= @@ -483,8 +485,8 @@ github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyex github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= -github.com/miekg/dns v1.1.59 h1:C9EXc/UToRwKLhK5wKU/I4QVsBUc8kE6MkHBkeypWZs= -github.com/miekg/dns v1.1.59/go.mod h1:nZpewl5p6IvctfgrckopVx2OlSEHPRO/U4SYkRklrEk= +github.com/miekg/dns v1.1.61 h1:nLxbwF3XxhwVSm8g9Dghm9MHPaUZuqhPiGL+675ZmEs= +github.com/miekg/dns v1.1.61/go.mod h1:mnAarhS3nWaW+NVP2wTkYVIZyHNJ098SJZUki3eykwQ= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c h1:bzE/A84HN25pxAuk9Eej1Kz9OUelF97nAc82bDquQI8= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c/go.mod h1:0SQS9kMwD2VsyFEB++InYyBJroV/FRmBgcydeSUcJms= github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= @@ -559,13 +561,13 @@ github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108 github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.17.3 h1:oJcvKpIb7/8uLpDDtnQuf18xVnwKp8DTD7DQ6gTd/MU= -github.com/onsi/ginkgo/v2 v2.17.3/go.mod h1:nP2DPOQoNsQmsVyv5rDA8JkXQoCs6goXIvr/PRJ1eCc= +github.com/onsi/ginkgo/v2 v2.19.0 h1:9Cnnf7UHo57Hy3k6/m5k3dRfGTMXGvxhHFvkDTCTpvA= +github.com/onsi/ginkgo/v2 v2.19.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.33.0 h1:snPCflnZrpMsy94p4lXVEkHo12lmPnc3vY5XBbreexE= -github.com/onsi/gomega v1.33.0/go.mod h1:+925n5YtiFsLzzafLUHzVMBpvvRAzrydIBiSIxjX3wY= +github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk= +github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.2.0 h1:z97+pHb3uELt/yiAWD691HNHQIF07bE7dzrbT927iTk= github.com/opencontainers/runtime-spec v1.2.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= @@ -623,8 +625,8 @@ github.com/pion/transport/v3 v3.0.2/go.mod h1:nIToODoOlb5If2jF9y2Igfx3PFYWfuXi37 github.com/pion/turn/v2 v2.1.3/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY= github.com/pion/turn/v2 v2.1.6 h1:Xr2niVsiPTB0FPtt+yAWKFUkU1eotQbGgpTIld4x1Gc= github.com/pion/turn/v2 v2.1.6/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY= -github.com/pion/webrtc/v3 v3.2.40 h1:Wtfi6AZMQg+624cvCXUuSmrKWepSB7zfgYDOYqsSOVU= -github.com/pion/webrtc/v3 v3.2.40/go.mod h1:M1RAe3TNTD1tzyvqHrbVODfwdPGSXOUo/OgpoGGJqFY= +github.com/pion/webrtc/v3 v3.2.42 h1:WN/ZuMjtpQOoGRCZUg/zFG+JHEvYLVyDKOxU6H1qWlE= +github.com/pion/webrtc/v3 v3.2.42/go.mod h1:M1RAe3TNTD1tzyvqHrbVODfwdPGSXOUo/OgpoGGJqFY= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -648,16 +650,16 @@ github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0leargg github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= -github.com/quic-go/quic-go v0.44.0 h1:So5wOr7jyO4vzL2sd8/pD9Kesciv91zSk8BoFngItQ0= -github.com/quic-go/quic-go v0.44.0/go.mod h1:z4cx/9Ny9UtGITIPzmPTXh1ULfOyWh4qGQlpnPcWmek= +github.com/quic-go/quic-go v0.45.0 h1:OHmkQGM37luZITyTSu6ff03HP/2IrwDX1ZFiNEhSFUE= +github.com/quic-go/quic-go v0.45.0/go.mod h1:1dLehS7TIR64+vxGR70GDcatWTOtMX2PUtnKsjbTurI= github.com/quic-go/webtransport-go v0.8.0 h1:HxSrwun11U+LlmwpgM1kEqIqH90IT4N8auv/cD7QFJg= github.com/quic-go/webtransport-go v0.8.0/go.mod h1:N99tjprW432Ut5ONql/aUhSLT0YVSlwHohQsuac9WaM= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= -github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= -github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= +github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd/go.mod h1:hPqNNc0+uJM6H+SuU8sEs5K5IQeKccPqeSjfgcKGgPk= @@ -776,28 +778,28 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.51.0 h1:Xs2Ncz0gNihqu9iosIZ5SkBbWo5T8JhhLJFMQL1qmLI= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.51.0/go.mod h1:vy+2G/6NvVMpwGX/NyLqcC41fxepnuKHk16E6IZUcJc= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.52.0 h1:9l89oX4ba9kHbBol3Xin3leYJ+252h0zszDtBwyKe2A= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.52.0/go.mod h1:XLZfZboOJWHNKUv7eH0inh0E9VV6eWDFB/9yJyTLPp0= go.opentelemetry.io/otel v1.27.0 h1:9BZoF3yMK/O1AafMiQTVu0YDj5Ea4hPhxCs7sGva+cg= go.opentelemetry.io/otel v1.27.0/go.mod h1:DMpAK8fzYRzs+bi3rS5REupisuqTheUlSZJ1WnZaPAQ= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.26.0 h1:1u/AyyOqAWzy+SkPxDpahCNZParHV8Vid1RnI2clyDE= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.26.0/go.mod h1:z46paqbJ9l7c9fIPCXTqTGwhQZ5XoTIsfeFYWboizjs= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.26.0 h1:Waw9Wfpo/IXzOI8bCB7DIk+0JZcqqsyn1JFnAc+iam8= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.26.0/go.mod h1:wnJIG4fOqyynOnnQF/eQb4/16VlX2EJAHhHgqIqWfAo= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.26.0 h1:1wp/gyxsuYtuE/JFxsQRtcCDtMrO2qMvlfXALU5wkzI= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.26.0/go.mod h1:gbTHmghkGgqxMomVQQMur1Nba4M0MQ8AYThXDUjsJ38= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.26.0 h1:0W5o9SzoR15ocYHEQfvfipzcNog1lBxOLfnex91Hk6s= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.26.0/go.mod h1:zVZ8nz+VSggWmnh6tTsJqXQ7rU4xLwRtna1M4x5jq58= -go.opentelemetry.io/otel/exporters/zipkin v1.26.0 h1:sBk6A62GgcQRwcxcBwRMPkqeuSizcpHkXyZNyP281Fw= -go.opentelemetry.io/otel/exporters/zipkin v1.26.0/go.mod h1:fLzYtPUxPFzu7rSqhYsCxYheT2dNoPjtKovCLzLm07w= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 h1:R9DE4kQ4k+YtfLI2ULwX82VtNQ2J8yZmA7ZIF/D+7Mc= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0/go.mod h1:OQFyQVrDlbe+R7xrEyDr/2Wr67Ol0hRUgsfA+V5A95s= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 h1:qFffATk0X+HD+f1Z8lswGiOQYKHRlzfmdJm0wEaVrFA= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0/go.mod h1:MOiCmryaYtc+V0Ei+Tx9o5S1ZjA7kzLucuVuyzBZloQ= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.0 h1:QY7/0NeRPKlzusf40ZE4t1VlMKbqSNT7cJRYzWuja0s= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.0/go.mod h1:HVkSiDhTM9BoUJU8qE6j2eSWLLXvi1USXjyd2BXT8PY= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.27.0 h1:/0YaXu3755A/cFbtXp+21lkXgI0QE5avTWA2HjU9/WE= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.27.0/go.mod h1:m7SFxp0/7IxmJPLIY3JhOcU9CoFzDaCPL6xxQIxhA+o= +go.opentelemetry.io/otel/exporters/zipkin v1.27.0 h1:aXcxb7F6ZDC1o2Z52LDfS2g6M2FB5CrxdR2gzY4QRNs= +go.opentelemetry.io/otel/exporters/zipkin v1.27.0/go.mod h1:+WMURoi4KmVB7ypbFPx3xtZTWen2Ca3lRK9u6DVTO5M= go.opentelemetry.io/otel/metric v1.27.0 h1:hvj3vdEKyeCi4YaYfNjv2NUje8FqKqUY8IlF0FxV/ik= go.opentelemetry.io/otel/metric v1.27.0/go.mod h1:mVFgmRlhljgBiuk/MP/oKylr4hs85GZAylncepAX/ak= -go.opentelemetry.io/otel/sdk v1.26.0 h1:Y7bumHf5tAiDlRYFmGqetNcLaVUZmh4iYfmGxtmz7F8= -go.opentelemetry.io/otel/sdk v1.26.0/go.mod h1:0p8MXpqLeJ0pzcszQQN4F0S5FVjBLgypeGSngLsmirs= +go.opentelemetry.io/otel/sdk v1.27.0 h1:mlk+/Y1gLPLn84U4tI8d3GNJmGT/eXe3ZuOXN9kTWmI= +go.opentelemetry.io/otel/sdk v1.27.0/go.mod h1:Ha9vbLwJE6W86YstIywK2xFfPjbWlCuwPtMkKdz/Y4A= go.opentelemetry.io/otel/trace v1.27.0 h1:IqYb813p7cmbHk0a5y6pD5JPakbVfftRXABGt5/Rscw= go.opentelemetry.io/otel/trace v1.27.0/go.mod h1:6RiD1hkAprV4/q+yd2ln1HG9GoPx39SuvvstaLBl+l4= -go.opentelemetry.io/proto/otlp v1.2.0 h1:pVeZGk7nXDC9O2hncA6nHldxEjm6LByfA2aN8IOkz94= -go.opentelemetry.io/proto/otlp v1.2.0/go.mod h1:gGpR8txAl5M03pDhMC79G6SdqNV26naRm/KDsgaHD8A= +go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= +go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= @@ -805,8 +807,8 @@ go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= -go.uber.org/fx v1.21.1 h1:RqBh3cYdzZS0uqwVeEjOX2p73dddLpym315myy/Bpb0= -go.uber.org/fx v1.21.1/go.mod h1:HT2M7d7RHo+ebKGh9NRcrsrHHfpZ60nW3QRubMRfv48= +go.uber.org/fx v1.22.0 h1:pApUK7yL0OUHMd8vkunWSlLxZVFFk70jR2nKde8X2NM= +go.uber.org/fx v1.22.0/go.mod h1:HT2M7d7RHo+ebKGh9NRcrsrHHfpZ60nW3QRubMRfv48= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= @@ -861,8 +863,8 @@ golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8 h1:LoYXNGAShUG3m/ehNk4iFctuhGX/+R1ZpfJ4/ia80JM= -golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI= +golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 h1:yixxcjnhBmY0nkL253HFVIm0JsFHwrHdT3Yh6szTnfY= +golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -993,7 +995,7 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1119,10 +1121,10 @@ google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvx google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto/googleapis/api v0.0.0-20240515191416-fc5f0ca64291 h1:4HZJ3Xv1cmrJ+0aFo304Zn79ur1HMxptAE7aCPNLSqc= -google.golang.org/genproto/googleapis/api v0.0.0-20240515191416-fc5f0ca64291/go.mod h1:RGnPtTG7r4i8sPlNyDeikXF99hMM+hN6QMm4ooG9g2g= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240515191416-fc5f0ca64291 h1:AgADTJarZTBqgjiUzRgfaBchgYB3/WFTC80GPwsMcRI= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240515191416-fc5f0ca64291/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0= +google.golang.org/genproto/googleapis/api v0.0.0-20240617180043-68d350f18fd4 h1:MuYw1wJzT+ZkybKfaOXKp5hJiZDn2iHaXRw0mRYdHSc= +google.golang.org/genproto/googleapis/api v0.0.0-20240617180043-68d350f18fd4/go.mod h1:px9SlOOZBg1wM1zdnr8jEL4CNGUBZ+ZKYtNPApNQc4c= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240617180043-68d350f18fd4 h1:Di6ANFilr+S60a4S61ZM00vLdw0IrQOSMS2/6mrnOU0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240617180043-68d350f18fd4/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= @@ -1146,8 +1148,8 @@ google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= -google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -1156,8 +1158,9 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EV gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/square/go-jose.v2 v2.5.1 h1:7odma5RETjNHWJnR32wx8t+Io4djHE1PqxCFx3iiZ2w= gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= +gopkg.in/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI= +gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/src-d/go-cli.v0 v0.0.0-20181105080154-d492247bbc0d/go.mod h1:z+K8VcOYVYcSwSjGebuDL6176A1XskgbtNl64NSg+n8= gopkg.in/src-d/go-log.v1 v1.0.1/go.mod h1:GN34hKP0g305ysm2/hctJ0Y8nWP3zxXXJ8GFabTyABE= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= diff --git a/go.mod b/go.mod index 2abdfacae..866a1ecc6 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,7 @@ require ( github.com/hashicorp/go-multierror v1.1.1 github.com/ipfs-shipyard/nopfs v0.0.12 github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c - github.com/ipfs/boxo v0.20.0 + github.com/ipfs/boxo v0.21.0 github.com/ipfs/go-block-format v0.2.0 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 @@ -73,21 +73,21 @@ 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.24.0 - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.51.0 + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.52.0 go.opentelemetry.io/contrib/propagators/autoprop v0.46.1 go.opentelemetry.io/otel v1.27.0 - go.opentelemetry.io/otel/sdk v1.26.0 + go.opentelemetry.io/otel/sdk v1.27.0 go.opentelemetry.io/otel/trace v1.27.0 go.uber.org/dig v1.17.1 - go.uber.org/fx v1.21.1 + go.uber.org/fx v1.22.0 go.uber.org/multierr v1.11.0 go.uber.org/zap v1.27.0 golang.org/x/crypto v0.24.0 - golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8 + golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 golang.org/x/mod v0.18.0 golang.org/x/sync v0.7.0 golang.org/x/sys v0.21.0 - google.golang.org/protobuf v1.34.1 + google.golang.org/protobuf v1.34.2 ) require ( @@ -107,11 +107,11 @@ require ( github.com/dgraph-io/badger v1.6.2 // indirect github.com/dgraph-io/ristretto v0.0.2 // indirect github.com/docker/go-units v0.5.0 // indirect - github.com/elastic/gosigar v0.14.2 // indirect + github.com/elastic/gosigar v0.14.3 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/flynn/noise v1.1.0 // indirect github.com/francoispqt/gojay v1.2.13 // indirect - github.com/gabriel-vasile/mimetype v1.4.3 // indirect + github.com/gabriel-vasile/mimetype v1.4.4 // indirect github.com/go-kit/log v0.2.1 // indirect github.com/go-logfmt/logfmt v0.5.1 // indirect github.com/go-logr/logr v1.4.2 // indirect @@ -123,9 +123,9 @@ require ( github.com/golang/protobuf v1.5.4 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/gopacket v1.1.19 // indirect - github.com/google/pprof v0.0.0-20240509144519-723abb6459b7 // indirect + github.com/google/pprof v0.0.0-20240618054019-d3b898a103f8 // indirect github.com/gorilla/mux v1.8.1 // indirect - github.com/gorilla/websocket v1.5.1 // indirect + github.com/gorilla/websocket v1.5.3 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/golang-lru v1.0.2 // indirect @@ -146,7 +146,7 @@ require ( github.com/ipfs/go-peertaskqueue v0.8.1 // indirect github.com/ipfs/go-verifcid v0.0.3 // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect - github.com/klauspost/compress v1.17.8 // indirect + github.com/klauspost/compress v1.17.9 // indirect github.com/klauspost/cpuid/v2 v2.2.8 // indirect github.com/koron/go-ssdp v0.0.4 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect @@ -166,7 +166,7 @@ require ( github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-runewidth v0.0.4 // indirect github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect - github.com/miekg/dns v1.1.59 // indirect + github.com/miekg/dns v1.1.61 // indirect github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect github.com/minio/sha256-simd v1.0.1 // indirect @@ -176,7 +176,7 @@ require ( github.com/multiformats/go-multiaddr-fmt v0.1.0 // indirect github.com/multiformats/go-multistream v0.5.0 // indirect github.com/multiformats/go-varint v0.0.7 // indirect - github.com/onsi/ginkgo/v2 v2.17.3 // indirect + github.com/onsi/ginkgo/v2 v2.19.0 // indirect github.com/opencontainers/runtime-spec v1.2.0 // indirect github.com/openzipkin/zipkin-go v0.4.3 // indirect github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 // indirect @@ -195,7 +195,7 @@ require ( github.com/pion/stun v0.6.1 // indirect github.com/pion/transport/v2 v2.2.5 // indirect github.com/pion/turn/v2 v2.1.6 // indirect - github.com/pion/webrtc/v3 v3.2.40 // indirect + github.com/pion/webrtc/v3 v3.2.42 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/polydawn/refmt v0.89.0 // indirect @@ -204,7 +204,7 @@ require ( github.com/prometheus/procfs v0.15.1 // indirect github.com/prometheus/statsd_exporter v0.22.7 // indirect github.com/quic-go/qpack v0.4.0 // indirect - github.com/quic-go/quic-go v0.44.0 // indirect + github.com/quic-go/quic-go v0.45.0 // indirect github.com/quic-go/webtransport-go v0.8.0 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/rs/cors v1.10.1 // indirect @@ -223,25 +223,25 @@ require ( go.opentelemetry.io/contrib/propagators/b3 v1.21.1 // indirect go.opentelemetry.io/contrib/propagators/jaeger v1.21.1 // indirect go.opentelemetry.io/contrib/propagators/ot v1.21.1 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.26.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.26.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.26.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.26.0 // indirect - go.opentelemetry.io/otel/exporters/zipkin v1.26.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.27.0 // indirect + go.opentelemetry.io/otel/exporters/zipkin v1.27.0 // indirect go.opentelemetry.io/otel/metric v1.27.0 // indirect - go.opentelemetry.io/proto/otlp v1.2.0 // indirect + go.opentelemetry.io/proto/otlp v1.3.1 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/mock v0.4.0 // indirect go4.org v0.0.0-20230225012048-214862532bf5 // indirect golang.org/x/net v0.26.0 // indirect - golang.org/x/oauth2 v0.20.0 // indirect + golang.org/x/oauth2 v0.21.0 // indirect golang.org/x/term v0.21.0 // indirect golang.org/x/text v0.16.0 // indirect golang.org/x/tools v0.22.0 // indirect golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect gonum.org/v1/gonum v0.15.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240515191416-fc5f0ca64291 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240515191416-fc5f0ca64291 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240617180043-68d350f18fd4 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240617180043-68d350f18fd4 // indirect google.golang.org/grpc v1.64.0 // indirect gopkg.in/square/go-jose.v2 v2.5.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/go.sum b/go.sum index b02bced7a..52e889275 100644 --- a/go.sum +++ b/go.sum @@ -148,8 +148,8 @@ github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25Kn github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/elastic/gosigar v0.12.0/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= -github.com/elastic/gosigar v0.14.2 h1:Dg80n8cr90OZ7x+bAax/QjoW/XqTI11RmA79ZwIm9/4= -github.com/elastic/gosigar v0.14.2/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= +github.com/elastic/gosigar v0.14.3 h1:xwkKwPia+hSfg9GqrCUKYdId102m9qTJIIr7egmK/uo= +github.com/elastic/gosigar v0.14.3/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.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -175,8 +175,8 @@ github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMo github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= -github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= -github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= +github.com/gabriel-vasile/mimetype v1.4.4 h1:QjV6pZ7/XZ7ryI2KuyeEDE8wnh7fHP9YnQy+R0LnH8I= +github.com/gabriel-vasile/mimetype v1.4.4/go.mod h1:JwLei5XPtWdGiMFB5Pjle1oEeoSeEuJfJE+TtfvdB/s= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= @@ -280,8 +280,8 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20240509144519-723abb6459b7 h1:velgFPYr1X9TDwLIfkV7fWqsFlf7TeP11M/7kPd/dVI= -github.com/google/pprof v0.0.0-20240509144519-723abb6459b7/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= +github.com/google/pprof v0.0.0-20240618054019-d3b898a103f8 h1:ASJ/LAqdCHOyMYI+dwNxn7Rd8FscNkMyTr1KZU1JI/M= +github.com/google/pprof v0.0.0-20240618054019-d3b898a103f8/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -297,8 +297,8 @@ github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c h1:7lF+Vz0LqiRid github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= -github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= -github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= +github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= +github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0= @@ -328,8 +328,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.20.0 h1:umUl7q1v5g5AX8FPLTnZBvvagLmT+V0Tt61EigP81ec= -github.com/ipfs/boxo v0.20.0/go.mod h1:mwttn53Eibgska2DhVIj7ln3UViq7MVHRxOMb+ehSDM= +github.com/ipfs/boxo v0.21.0 h1:XpGXb+TQQ0IUdYaeAxGzWjSs6ow/Lce148A/2IbRDVE= +github.com/ipfs/boxo v0.21.0/go.mod h1:NmweAYeY1USOaJJxouy7DLr/Y5M8UBSsCI2KRivO+TY= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= @@ -472,8 +472,8 @@ github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQL 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.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU= -github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= +github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM= @@ -579,8 +579,8 @@ github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyex github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= -github.com/miekg/dns v1.1.59 h1:C9EXc/UToRwKLhK5wKU/I4QVsBUc8kE6MkHBkeypWZs= -github.com/miekg/dns v1.1.59/go.mod h1:nZpewl5p6IvctfgrckopVx2OlSEHPRO/U4SYkRklrEk= +github.com/miekg/dns v1.1.61 h1:nLxbwF3XxhwVSm8g9Dghm9MHPaUZuqhPiGL+675ZmEs= +github.com/miekg/dns v1.1.61/go.mod h1:mnAarhS3nWaW+NVP2wTkYVIZyHNJ098SJZUki3eykwQ= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c h1:bzE/A84HN25pxAuk9Eej1Kz9OUelF97nAc82bDquQI8= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c/go.mod h1:0SQS9kMwD2VsyFEB++InYyBJroV/FRmBgcydeSUcJms= github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= @@ -661,13 +661,13 @@ github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108 github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.17.3 h1:oJcvKpIb7/8uLpDDtnQuf18xVnwKp8DTD7DQ6gTd/MU= -github.com/onsi/ginkgo/v2 v2.17.3/go.mod h1:nP2DPOQoNsQmsVyv5rDA8JkXQoCs6goXIvr/PRJ1eCc= +github.com/onsi/ginkgo/v2 v2.19.0 h1:9Cnnf7UHo57Hy3k6/m5k3dRfGTMXGvxhHFvkDTCTpvA= +github.com/onsi/ginkgo/v2 v2.19.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.33.0 h1:snPCflnZrpMsy94p4lXVEkHo12lmPnc3vY5XBbreexE= -github.com/onsi/gomega v1.33.0/go.mod h1:+925n5YtiFsLzzafLUHzVMBpvvRAzrydIBiSIxjX3wY= +github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk= +github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.2.0 h1:z97+pHb3uELt/yiAWD691HNHQIF07bE7dzrbT927iTk= github.com/opencontainers/runtime-spec v1.2.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= @@ -725,8 +725,8 @@ github.com/pion/transport/v3 v3.0.2/go.mod h1:nIToODoOlb5If2jF9y2Igfx3PFYWfuXi37 github.com/pion/turn/v2 v2.1.3/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY= github.com/pion/turn/v2 v2.1.6 h1:Xr2niVsiPTB0FPtt+yAWKFUkU1eotQbGgpTIld4x1Gc= github.com/pion/turn/v2 v2.1.6/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY= -github.com/pion/webrtc/v3 v3.2.40 h1:Wtfi6AZMQg+624cvCXUuSmrKWepSB7zfgYDOYqsSOVU= -github.com/pion/webrtc/v3 v3.2.40/go.mod h1:M1RAe3TNTD1tzyvqHrbVODfwdPGSXOUo/OgpoGGJqFY= +github.com/pion/webrtc/v3 v3.2.42 h1:WN/ZuMjtpQOoGRCZUg/zFG+JHEvYLVyDKOxU6H1qWlE= +github.com/pion/webrtc/v3 v3.2.42/go.mod h1:M1RAe3TNTD1tzyvqHrbVODfwdPGSXOUo/OgpoGGJqFY= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -777,16 +777,16 @@ github.com/prometheus/statsd_exporter v0.22.7 h1:7Pji/i2GuhK6Lu7DHrtTkFmNBCudCPT github.com/prometheus/statsd_exporter v0.22.7/go.mod h1:N/TevpjkIh9ccs6nuzY3jQn9dFqnUakOjnEuMPJJJnI= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= -github.com/quic-go/quic-go v0.44.0 h1:So5wOr7jyO4vzL2sd8/pD9Kesciv91zSk8BoFngItQ0= -github.com/quic-go/quic-go v0.44.0/go.mod h1:z4cx/9Ny9UtGITIPzmPTXh1ULfOyWh4qGQlpnPcWmek= +github.com/quic-go/quic-go v0.45.0 h1:OHmkQGM37luZITyTSu6ff03HP/2IrwDX1ZFiNEhSFUE= +github.com/quic-go/quic-go v0.45.0/go.mod h1:1dLehS7TIR64+vxGR70GDcatWTOtMX2PUtnKsjbTurI= github.com/quic-go/webtransport-go v0.8.0 h1:HxSrwun11U+LlmwpgM1kEqIqH90IT4N8auv/cD7QFJg= github.com/quic-go/webtransport-go v0.8.0/go.mod h1:N99tjprW432Ut5ONql/aUhSLT0YVSlwHohQsuac9WaM= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= -github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= -github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= +github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/rs/cors v1.10.1 h1:L0uuZVXIKlI1SShY2nhFfo44TYvDPQ1w4oFkUJNfhyo= github.com/rs/cors v1.10.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= @@ -928,8 +928,8 @@ go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.51.0 h1:Xs2Ncz0gNihqu9iosIZ5SkBbWo5T8JhhLJFMQL1qmLI= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.51.0/go.mod h1:vy+2G/6NvVMpwGX/NyLqcC41fxepnuKHk16E6IZUcJc= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.52.0 h1:9l89oX4ba9kHbBol3Xin3leYJ+252h0zszDtBwyKe2A= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.52.0/go.mod h1:XLZfZboOJWHNKUv7eH0inh0E9VV6eWDFB/9yJyTLPp0= go.opentelemetry.io/contrib/propagators/autoprop v0.46.1 h1:cXTYcMjY0dsYokAuo8LbNBQxpF8VgTHdiHJJ1zlIXl4= go.opentelemetry.io/contrib/propagators/autoprop v0.46.1/go.mod h1:WZxgny1/6+j67B1s72PLJ4bGjidoWFzSmLNfJKVt2bo= go.opentelemetry.io/contrib/propagators/aws v1.21.1 h1:uQIQIDWb0gzyvon2ICnghpLAf9w7ADOCUiIiwCQgR2o= @@ -942,24 +942,24 @@ go.opentelemetry.io/contrib/propagators/ot v1.21.1 h1:3TN5vkXjKYWp0YdMcnUEC/A+pB go.opentelemetry.io/contrib/propagators/ot v1.21.1/go.mod h1:oy0MYCbS/b3cqUDW37wBWtlwBIsutngS++Lklpgh+fc= go.opentelemetry.io/otel v1.27.0 h1:9BZoF3yMK/O1AafMiQTVu0YDj5Ea4hPhxCs7sGva+cg= go.opentelemetry.io/otel v1.27.0/go.mod h1:DMpAK8fzYRzs+bi3rS5REupisuqTheUlSZJ1WnZaPAQ= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.26.0 h1:1u/AyyOqAWzy+SkPxDpahCNZParHV8Vid1RnI2clyDE= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.26.0/go.mod h1:z46paqbJ9l7c9fIPCXTqTGwhQZ5XoTIsfeFYWboizjs= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.26.0 h1:Waw9Wfpo/IXzOI8bCB7DIk+0JZcqqsyn1JFnAc+iam8= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.26.0/go.mod h1:wnJIG4fOqyynOnnQF/eQb4/16VlX2EJAHhHgqIqWfAo= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.26.0 h1:1wp/gyxsuYtuE/JFxsQRtcCDtMrO2qMvlfXALU5wkzI= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.26.0/go.mod h1:gbTHmghkGgqxMomVQQMur1Nba4M0MQ8AYThXDUjsJ38= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.26.0 h1:0W5o9SzoR15ocYHEQfvfipzcNog1lBxOLfnex91Hk6s= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.26.0/go.mod h1:zVZ8nz+VSggWmnh6tTsJqXQ7rU4xLwRtna1M4x5jq58= -go.opentelemetry.io/otel/exporters/zipkin v1.26.0 h1:sBk6A62GgcQRwcxcBwRMPkqeuSizcpHkXyZNyP281Fw= -go.opentelemetry.io/otel/exporters/zipkin v1.26.0/go.mod h1:fLzYtPUxPFzu7rSqhYsCxYheT2dNoPjtKovCLzLm07w= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 h1:R9DE4kQ4k+YtfLI2ULwX82VtNQ2J8yZmA7ZIF/D+7Mc= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0/go.mod h1:OQFyQVrDlbe+R7xrEyDr/2Wr67Ol0hRUgsfA+V5A95s= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 h1:qFffATk0X+HD+f1Z8lswGiOQYKHRlzfmdJm0wEaVrFA= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0/go.mod h1:MOiCmryaYtc+V0Ei+Tx9o5S1ZjA7kzLucuVuyzBZloQ= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.0 h1:QY7/0NeRPKlzusf40ZE4t1VlMKbqSNT7cJRYzWuja0s= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.0/go.mod h1:HVkSiDhTM9BoUJU8qE6j2eSWLLXvi1USXjyd2BXT8PY= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.27.0 h1:/0YaXu3755A/cFbtXp+21lkXgI0QE5avTWA2HjU9/WE= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.27.0/go.mod h1:m7SFxp0/7IxmJPLIY3JhOcU9CoFzDaCPL6xxQIxhA+o= +go.opentelemetry.io/otel/exporters/zipkin v1.27.0 h1:aXcxb7F6ZDC1o2Z52LDfS2g6M2FB5CrxdR2gzY4QRNs= +go.opentelemetry.io/otel/exporters/zipkin v1.27.0/go.mod h1:+WMURoi4KmVB7ypbFPx3xtZTWen2Ca3lRK9u6DVTO5M= go.opentelemetry.io/otel/metric v1.27.0 h1:hvj3vdEKyeCi4YaYfNjv2NUje8FqKqUY8IlF0FxV/ik= go.opentelemetry.io/otel/metric v1.27.0/go.mod h1:mVFgmRlhljgBiuk/MP/oKylr4hs85GZAylncepAX/ak= -go.opentelemetry.io/otel/sdk v1.26.0 h1:Y7bumHf5tAiDlRYFmGqetNcLaVUZmh4iYfmGxtmz7F8= -go.opentelemetry.io/otel/sdk v1.26.0/go.mod h1:0p8MXpqLeJ0pzcszQQN4F0S5FVjBLgypeGSngLsmirs= +go.opentelemetry.io/otel/sdk v1.27.0 h1:mlk+/Y1gLPLn84U4tI8d3GNJmGT/eXe3ZuOXN9kTWmI= +go.opentelemetry.io/otel/sdk v1.27.0/go.mod h1:Ha9vbLwJE6W86YstIywK2xFfPjbWlCuwPtMkKdz/Y4A= go.opentelemetry.io/otel/trace v1.27.0 h1:IqYb813p7cmbHk0a5y6pD5JPakbVfftRXABGt5/Rscw= go.opentelemetry.io/otel/trace v1.27.0/go.mod h1:6RiD1hkAprV4/q+yd2ln1HG9GoPx39SuvvstaLBl+l4= -go.opentelemetry.io/proto/otlp v1.2.0 h1:pVeZGk7nXDC9O2hncA6nHldxEjm6LByfA2aN8IOkz94= -go.opentelemetry.io/proto/otlp v1.2.0/go.mod h1:gGpR8txAl5M03pDhMC79G6SdqNV26naRm/KDsgaHD8A= +go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= +go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= @@ -967,8 +967,8 @@ go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= -go.uber.org/fx v1.21.1 h1:RqBh3cYdzZS0uqwVeEjOX2p73dddLpym315myy/Bpb0= -go.uber.org/fx v1.21.1/go.mod h1:HT2M7d7RHo+ebKGh9NRcrsrHHfpZ60nW3QRubMRfv48= +go.uber.org/fx v1.22.0 h1:pApUK7yL0OUHMd8vkunWSlLxZVFFk70jR2nKde8X2NM= +go.uber.org/fx v1.22.0/go.mod h1:HT2M7d7RHo+ebKGh9NRcrsrHHfpZ60nW3QRubMRfv48= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= @@ -1025,8 +1025,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8 h1:LoYXNGAShUG3m/ehNk4iFctuhGX/+R1ZpfJ4/ia80JM= -golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI= +golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 h1:yixxcjnhBmY0nkL253HFVIm0JsFHwrHdT3Yh6szTnfY= +golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1119,8 +1119,8 @@ golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4Iltr golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.20.0 h1:4mQdhULixXKP1rwYBW0vAijoXnkTG0BLCDRzfe1idMo= -golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs= +golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1373,10 +1373,10 @@ google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7Fc google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto/googleapis/api v0.0.0-20240515191416-fc5f0ca64291 h1:4HZJ3Xv1cmrJ+0aFo304Zn79ur1HMxptAE7aCPNLSqc= -google.golang.org/genproto/googleapis/api v0.0.0-20240515191416-fc5f0ca64291/go.mod h1:RGnPtTG7r4i8sPlNyDeikXF99hMM+hN6QMm4ooG9g2g= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240515191416-fc5f0ca64291 h1:AgADTJarZTBqgjiUzRgfaBchgYB3/WFTC80GPwsMcRI= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240515191416-fc5f0ca64291/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0= +google.golang.org/genproto/googleapis/api v0.0.0-20240617180043-68d350f18fd4 h1:MuYw1wJzT+ZkybKfaOXKp5hJiZDn2iHaXRw0mRYdHSc= +google.golang.org/genproto/googleapis/api v0.0.0-20240617180043-68d350f18fd4/go.mod h1:px9SlOOZBg1wM1zdnr8jEL4CNGUBZ+ZKYtNPApNQc4c= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240617180043-68d350f18fd4 h1:Di6ANFilr+S60a4S61ZM00vLdw0IrQOSMS2/6mrnOU0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240617180043-68d350f18fd4/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= @@ -1409,8 +1409,8 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= -google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 18ef713ae..bc334d33f 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -8,7 +8,7 @@ replace github.com/ipfs/kubo => ../../ require ( github.com/Kubuxu/gocovmerge v0.0.0-20161216165753-7ecaa51963cd - github.com/golangci/golangci-lint v1.54.1 + github.com/golangci/golangci-lint v1.59.1 github.com/ipfs/go-cidutil v0.1.0 github.com/ipfs/go-log v1.0.5 github.com/ipfs/hang-fds v0.1.0 @@ -18,79 +18,87 @@ require ( github.com/jbenet/go-random-files v0.0.0-20190219210431-31b3f20ebded github.com/multiformats/go-multiaddr v0.12.4 github.com/multiformats/go-multihash v0.2.3 - gotest.tools/gotestsum v0.4.2 + gotest.tools/gotestsum v1.12.0 ) require ( 4d63.com/gocheckcompilerdirectives v1.2.1 // indirect 4d63.com/gochecknoglobals v0.2.1 // indirect - github.com/4meepo/tagalign v1.3.2 // indirect - github.com/Abirdcfly/dupword v0.0.12 // indirect - github.com/Antonboom/errname v0.1.10 // indirect - github.com/Antonboom/nilnil v0.1.5 // indirect - github.com/BurntSushi/toml v1.3.2 // indirect + github.com/4meepo/tagalign v1.3.4 // indirect + github.com/Abirdcfly/dupword v0.0.14 // indirect + github.com/Antonboom/errname v0.1.13 // indirect + github.com/Antonboom/nilnil v0.1.9 // indirect + github.com/Antonboom/testifylint v1.4.1 // indirect + github.com/BurntSushi/toml v1.4.0 // indirect + github.com/Crocmagnon/fatcontext v0.3.0 // indirect github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 // indirect - github.com/GaijinEntertainment/go-exhaustruct/v3 v3.1.0 // indirect - github.com/Masterminds/semver v1.5.0 // indirect - github.com/OpenPeeDeeP/depguard/v2 v2.1.0 // indirect - github.com/alexkohler/nakedret/v2 v2.0.2 // indirect + github.com/GaijinEntertainment/go-exhaustruct/v3 v3.3.0 // indirect + github.com/Masterminds/semver/v3 v3.2.1 // indirect + github.com/OpenPeeDeeP/depguard/v2 v2.2.0 // indirect + github.com/alecthomas/go-check-sumtype v0.1.4 // indirect + github.com/alexkohler/nakedret/v2 v2.0.4 // indirect github.com/alexkohler/prealloc v1.0.0 // indirect github.com/alingse/asasalint v0.0.11 // indirect github.com/ashanbrown/forbidigo v1.6.0 // indirect github.com/ashanbrown/makezero v1.1.1 // indirect github.com/beorn7/perks v1.0.1 // indirect + github.com/bitfield/gotestdox v0.2.2 // indirect github.com/bkielbasa/cyclop v1.2.1 // indirect github.com/blizzy78/varnamelen v0.8.0 // indirect - github.com/bombsimon/wsl/v3 v3.4.0 // indirect - github.com/breml/bidichk v0.2.4 // indirect - github.com/breml/errchkjson v0.3.1 // indirect - github.com/butuzov/ireturn v0.2.0 // indirect - github.com/butuzov/mirror v1.1.0 // indirect + github.com/bombsimon/wsl/v4 v4.4.0 // indirect + github.com/breml/bidichk v0.2.7 // indirect + github.com/breml/errchkjson v0.3.6 // indirect + github.com/butuzov/ireturn v0.3.0 // indirect + github.com/butuzov/mirror v1.2.0 // indirect + github.com/catenacyber/perfsprint v0.7.1 // indirect + github.com/ccojocar/zxcvbn-go v1.0.2 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/charithe/durationcheck v0.0.10 // indirect - github.com/chavacava/garif v0.0.0-20230227094218-b8c73b2037b8 // indirect - github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect + github.com/chavacava/garif v0.1.0 // indirect + github.com/ckaznocha/intrange v0.1.2 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect github.com/curioswitch/go-reassign v0.2.0 // indirect - github.com/daixiang0/gci v0.11.0 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect + github.com/daixiang0/gci v0.13.4 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect - github.com/denis-tingaikin/go-header v0.4.3 // indirect + github.com/denis-tingaikin/go-header v0.5.0 // indirect + github.com/dnephin/pflag v1.0.7 // indirect github.com/dustin/go-humanize v1.0.1 // indirect - github.com/esimonov/ifshort v1.0.4 // indirect - github.com/ettle/strcase v0.1.1 // indirect + github.com/ettle/strcase v0.2.0 // indirect github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5 // indirect - github.com/fatih/color v1.15.0 // indirect + github.com/fatih/color v1.17.0 // indirect github.com/fatih/structtag v1.2.0 // indirect - github.com/firefart/nonamedreturns v1.0.4 // indirect - github.com/fsnotify/fsnotify v1.6.0 // indirect + github.com/firefart/nonamedreturns v1.0.5 // indirect + github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/fzipp/gocyclo v0.6.0 // indirect - github.com/go-critic/go-critic v0.9.0 // indirect + github.com/ghostiam/protogetter v0.3.6 // indirect + github.com/go-critic/go-critic v0.11.4 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-toolsmith/astcast v1.1.0 // indirect github.com/go-toolsmith/astcopy v1.1.0 // indirect - github.com/go-toolsmith/astequal v1.1.0 // indirect + github.com/go-toolsmith/astequal v1.2.0 // indirect github.com/go-toolsmith/astfmt v1.1.0 // indirect github.com/go-toolsmith/astp v1.1.0 // indirect github.com/go-toolsmith/strparse v1.1.0 // indirect github.com/go-toolsmith/typep v1.1.0 // indirect + github.com/go-viper/mapstructure/v2 v2.0.0 // indirect github.com/go-xmlfmt/xmlfmt v1.1.2 // indirect github.com/gobwas/glob v0.2.3 // indirect github.com/gofrs/flock v0.8.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2 // indirect github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a // indirect - github.com/golangci/go-misc v0.0.0-20220329215616-d24fe342adfe // indirect - github.com/golangci/gofmt v0.0.0-20220901101216-f2edd75033f2 // indirect - github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0 // indirect - github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca // indirect - github.com/golangci/misspell v0.4.1 // indirect - github.com/golangci/revgrep v0.0.0-20220804021717-745bb2f7c2e6 // indirect - github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4 // indirect + github.com/golangci/gofmt v0.0.0-20231019111953-be8c47862aaa // indirect + github.com/golangci/misspell v0.6.0 // indirect + github.com/golangci/modinfo v0.3.4 // indirect + github.com/golangci/plugin-module-register v0.1.1 // indirect + github.com/golangci/revgrep v0.5.3 // indirect + github.com/golangci/unconvert v0.0.0-20240309020433-c5143eacb3ed // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/gopacket v1.1.19 // indirect + github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/gordonklaus/ineffassign v0.0.0-20230610083614-0e73809eb601 // indirect + github.com/gordonklaus/ineffassign v0.1.0 // indirect github.com/gostaticanalysis/analysisutil v0.7.1 // indirect github.com/gostaticanalysis/comment v1.4.2 // indirect github.com/gostaticanalysis/forcetypeassert v0.1.0 // indirect @@ -98,14 +106,14 @@ require ( github.com/gxed/go-shellwords v1.0.3 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect - github.com/hashicorp/go-version v1.6.0 // indirect + github.com/hashicorp/go-version v1.7.0 // indirect github.com/hashicorp/golang-lru v1.0.2 // indirect github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/hexops/gotextdiff v1.0.3 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/ipfs/bbloom v0.0.4 // indirect - github.com/ipfs/boxo v0.20.0 // indirect + github.com/ipfs/boxo v0.21.0 // indirect github.com/ipfs/go-block-format v0.2.0 // indirect github.com/ipfs/go-cid v0.4.1 // indirect github.com/ipfs/go-datastore v0.6.0 // indirect @@ -118,21 +126,22 @@ require ( github.com/ipld/go-codec-dagpb v1.6.0 // indirect github.com/ipld/go-ipld-prime v0.21.0 // indirect github.com/jbenet/goprocess v0.1.4 // indirect - github.com/jgautheron/goconst v1.5.1 // indirect + github.com/jgautheron/goconst v1.7.1 // indirect github.com/jingyugao/rowserrcheck v1.1.1 // indirect github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af // indirect - github.com/jonboulle/clockwork v0.2.0 // indirect + github.com/jjti/go-spancheck v0.6.1 // indirect github.com/julz/importas v0.1.0 // indirect - github.com/kisielk/errcheck v1.6.3 // indirect - github.com/kisielk/gotool v1.0.0 // indirect - github.com/kkHAIKE/contextcheck v1.1.4 // indirect + github.com/karamaru-alpha/copyloopvar v1.1.0 // indirect + github.com/kisielk/errcheck v1.7.0 // indirect + github.com/kkHAIKE/contextcheck v1.1.5 // indirect github.com/klauspost/cpuid/v2 v2.2.8 // indirect github.com/kulti/thelper v0.6.3 // indirect - github.com/kunwardeep/paralleltest v1.0.8 // indirect + github.com/kunwardeep/paralleltest v1.0.10 // indirect github.com/kyoh86/exportloopref v0.1.11 // indirect - github.com/ldez/gomoddirectives v0.2.3 // indirect + github.com/lasiar/canonicalheader v1.1.1 // indirect + github.com/ldez/gomoddirectives v0.2.4 // indirect github.com/ldez/tagliatelle v0.5.0 // indirect - github.com/leonklingele/grouper v1.1.1 // indirect + github.com/leonklingele/grouper v1.1.2 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/libp2p/go-cidranger v1.1.0 // indirect github.com/libp2p/go-libp2p v0.35.1 // indirect @@ -144,16 +153,16 @@ require ( github.com/libp2p/go-msgio v0.3.0 // indirect github.com/libp2p/go-netroute v0.2.1 // indirect github.com/lufeee/execinquery v1.2.1 // indirect - github.com/magiconair/properties v1.8.6 // indirect + github.com/macabu/inamedparam v0.1.3 // indirect + github.com/magiconair/properties v1.8.7 // indirect github.com/maratori/testableexamples v1.0.0 // indirect github.com/maratori/testpackage v1.1.1 // indirect - github.com/matoous/godox v0.0.0-20230222163458-006bad1f9d26 // indirect + github.com/matoous/godox v0.0.0-20240105082147-c5b5e0e7c0c0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mattn/go-runewidth v0.0.9 // indirect - github.com/mbilski/exhaustivestruct v1.2.0 // indirect - github.com/mgechev/revive v1.3.2 // indirect - github.com/miekg/dns v1.1.59 // indirect + github.com/mattn/go-runewidth v0.0.15 // indirect + github.com/mgechev/revive v1.3.7 // indirect + github.com/miekg/dns v1.1.61 // indirect github.com/minio/sha256-simd v1.0.1 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect @@ -167,82 +176,85 @@ require ( github.com/multiformats/go-multistream v0.5.0 // indirect github.com/multiformats/go-varint v0.0.7 // indirect github.com/nakabonne/nestif v0.3.1 // indirect - github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354 // indirect - github.com/nishanths/exhaustive v0.11.0 // indirect + github.com/nishanths/exhaustive v0.12.0 // indirect github.com/nishanths/predeclared v0.2.2 // indirect - github.com/nunnatsa/ginkgolinter v0.13.3 // indirect + github.com/nunnatsa/ginkgolinter v0.16.2 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect - github.com/onsi/gomega v1.27.10 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect - github.com/pelletier/go-toml v1.9.5 // indirect - github.com/pelletier/go-toml/v2 v2.0.5 // indirect + github.com/pelletier/go-toml/v2 v2.2.2 // indirect github.com/pkg/errors v0.9.1 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/polydawn/refmt v0.89.0 // indirect - github.com/polyfloyd/go-errorlint v1.4.3 // indirect + github.com/polyfloyd/go-errorlint v1.5.2 // indirect github.com/prometheus/client_golang v1.19.1 // indirect github.com/prometheus/client_model v0.6.1 // indirect github.com/prometheus/common v0.54.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect - github.com/quasilyte/go-ruleguard v0.4.0 // indirect + github.com/quasilyte/go-ruleguard v0.4.2 // indirect + github.com/quasilyte/go-ruleguard/dsl v0.3.22 // indirect github.com/quasilyte/gogrep v0.5.0 // indirect github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727 // indirect github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 // indirect + github.com/rivo/uniseg v0.4.7 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect - github.com/ryancurrah/gomodguard v1.3.0 // indirect - github.com/ryanrolds/sqlclosecheck v0.4.0 // indirect + github.com/ryancurrah/gomodguard v1.3.2 // indirect + github.com/ryanrolds/sqlclosecheck v0.5.1 // indirect + github.com/sagikazarmark/locafero v0.6.0 // indirect + github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/samber/lo v1.39.0 // indirect github.com/sanposhiho/wastedassign/v2 v2.0.7 // indirect + github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 // indirect github.com/sashamelentyev/interfacebloat v1.1.0 // indirect - github.com/sashamelentyev/usestdlibvars v1.23.0 // indirect - github.com/securego/gosec/v2 v2.16.0 // indirect + github.com/sashamelentyev/usestdlibvars v1.27.0 // indirect + github.com/securego/gosec/v2 v2.20.1-0.20240525090044-5f0084eb01a9 // indirect github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/sivchari/containedctx v1.0.3 // indirect - github.com/sivchari/nosnakecase v1.7.0 // indirect - github.com/sivchari/tenv v1.7.1 // indirect + github.com/sivchari/tenv v1.10.0 // indirect github.com/sonatard/noctx v0.0.2 // indirect + github.com/sourcegraph/conc v0.3.0 // indirect github.com/sourcegraph/go-diff v0.7.0 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect - github.com/spf13/afero v1.8.2 // indirect - github.com/spf13/cast v1.5.0 // indirect - github.com/spf13/cobra v1.7.0 // indirect - github.com/spf13/jwalterweatherman v1.1.0 // indirect + github.com/spf13/afero v1.11.0 // indirect + github.com/spf13/cast v1.6.0 // indirect + github.com/spf13/cobra v1.8.0 // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/spf13/viper v1.12.0 // indirect + github.com/spf13/viper v1.19.0 // indirect github.com/ssgreg/nlreturn/v2 v2.2.1 // indirect github.com/stbenjam/no-sprintf-host-port v0.1.1 // indirect github.com/stretchr/objx v0.5.2 // indirect github.com/stretchr/testify v1.9.0 // indirect - github.com/subosito/gotenv v1.4.1 // indirect + github.com/subosito/gotenv v1.6.0 // indirect github.com/t-yuki/gocover-cobertura v0.0.0-20180217150009-aaee18c8195c // indirect github.com/tdakkota/asciicheck v0.2.0 // indirect - github.com/tetafro/godot v1.4.11 // indirect - github.com/timakin/bodyclose v0.0.0-20230421092635-574207250966 // indirect + github.com/tetafro/godot v1.4.16 // indirect + github.com/timakin/bodyclose v0.0.0-20240125160201-f835fa56326a // indirect github.com/timonwong/loggercheck v0.9.4 // indirect - github.com/tomarrell/wrapcheck/v2 v2.8.1 // indirect + github.com/tomarrell/wrapcheck/v2 v2.8.3 // indirect github.com/tommy-muehle/go-mnd/v2 v2.5.1 // indirect github.com/ultraware/funlen v0.1.0 // indirect - github.com/ultraware/whitespace v0.0.5 // indirect + github.com/ultraware/whitespace v0.1.1 // indirect github.com/urfave/cli v1.22.10 // indirect - github.com/uudashr/gocognit v1.0.7 // indirect + github.com/uudashr/gocognit v1.1.2 // indirect github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc // indirect github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect - github.com/xen0n/gosmopolitan v1.2.1 // indirect + github.com/xen0n/gosmopolitan v1.2.2 // indirect github.com/yagipy/maintidx v1.0.0 // indirect - github.com/yeya24/promlinter v0.2.0 // indirect - github.com/ykadowak/zerologlint v0.1.3 // indirect - gitlab.com/bosi/decorder v0.4.0 // indirect + github.com/yeya24/promlinter v0.3.0 // indirect + github.com/ykadowak/zerologlint v0.1.5 // indirect + gitlab.com/bosi/decorder v0.4.2 // indirect + go-simpler.org/musttag v0.12.2 // indirect + go-simpler.org/sloglint v0.7.1 // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/otel v1.27.0 // indirect go.opentelemetry.io/otel/metric v1.27.0 // indirect go.opentelemetry.io/otel/trace v1.27.0 // indirect - go.tmz.dev/musttag v0.7.1 // indirect + go.uber.org/automaxprocs v1.5.3 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect golang.org/x/crypto v0.24.0 // indirect - golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8 // indirect - golang.org/x/exp/typeparams v0.0.0-20230307190834-24139beb5833 // indirect + golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 // indirect + golang.org/x/exp/typeparams v0.0.0-20240613232115-7f521ea00fb8 // indirect golang.org/x/mod v0.18.0 // indirect golang.org/x/net v0.26.0 // indirect golang.org/x/sync v0.7.0 // indirect @@ -251,14 +263,12 @@ require ( golang.org/x/text v0.16.0 // indirect golang.org/x/tools v0.22.0 // indirect gonum.org/v1/gonum v0.15.0 // indirect - google.golang.org/protobuf v1.34.1 // indirect + google.golang.org/protobuf v1.34.2 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - honnef.co/go/tools v0.4.3 // indirect + honnef.co/go/tools v0.4.7 // indirect lukechampine.com/blake3 v1.3.0 // indirect - mvdan.cc/gofumpt v0.5.0 // indirect - mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed // indirect - mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b // indirect - mvdan.cc/unparam v0.0.0-20221223090309-7455f1af531d // indirect + mvdan.cc/gofumpt v0.6.0 // indirect + mvdan.cc/unparam v0.0.0-20240528143540-8a5130ca722f // indirect ) diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 4b3048257..e5c9a5307 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -3,72 +3,39 @@ 4d63.com/gochecknoglobals v0.2.1 h1:1eiorGsgHOFOuoOiJDy2psSrQbRdIHrlge0IJIkUgDc= 4d63.com/gochecknoglobals v0.2.1/go.mod h1:KRE8wtJB3CXCsb1xy421JfTHIIbmT3U5ruxw2Qu8fSU= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= -cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= -cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= -cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= -cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= -cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= -cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= -cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= -cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= -cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= -cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= -cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= -cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= -cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= -cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= -cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= -cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= -cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= -cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= -cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= -cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= -cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= -cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= -cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= -cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= -cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= -cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= -cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= -cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= -cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= -cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= -dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/4meepo/tagalign v1.3.2 h1:1idD3yxlRGV18VjqtDbqYvQ5pXqQS0wO2dn6M3XstvI= -github.com/4meepo/tagalign v1.3.2/go.mod h1:Q9c1rYMZJc9dPRkbQPpcBNCLEmY2njbAsXhQOZFE2dE= -github.com/Abirdcfly/dupword v0.0.12 h1:56NnOyrXzChj07BDFjeRA+IUzSz01jmzEq+G4kEgFhc= -github.com/Abirdcfly/dupword v0.0.12/go.mod h1:+us/TGct/nI9Ndcbcp3rgNcQzctTj68pq7TcgNpLfdI= -github.com/Antonboom/errname v0.1.10 h1:RZ7cYo/GuZqjr1nuJLNe8ZH+a+Jd9DaZzttWzak9Bls= -github.com/Antonboom/errname v0.1.10/go.mod h1:xLeiCIrvVNpUtsN0wxAh05bNIZpqE22/qDMnTBTttiA= -github.com/Antonboom/nilnil v0.1.5 h1:X2JAdEVcbPaOom2TUa1FxZ3uyuUlex0XMLGYMemu6l0= -github.com/Antonboom/nilnil v0.1.5/go.mod h1:I24toVuBKhfP5teihGWctrRiPbRKHwZIFOvc6v3HZXk= +github.com/4meepo/tagalign v1.3.4 h1:P51VcvBnf04YkHzjfclN6BbsopfJR5rxs1n+5zHt+w8= +github.com/4meepo/tagalign v1.3.4/go.mod h1:M+pnkHH2vG8+qhE5bVc/zeP7HS/j910Fwa9TUSyZVI0= +github.com/Abirdcfly/dupword v0.0.14 h1:3U4ulkc8EUo+CaT105/GJ1BQwtgyj6+VaBVbAX11Ba8= +github.com/Abirdcfly/dupword v0.0.14/go.mod h1:VKDAbxdY8YbKUByLGg8EETzYSuC4crm9WwI6Y3S0cLI= +github.com/Antonboom/errname v0.1.13 h1:JHICqsewj/fNckzrfVSe+T33svwQxmjC+1ntDsHOVvM= +github.com/Antonboom/errname v0.1.13/go.mod h1:uWyefRYRN54lBg6HseYCFhs6Qjcy41Y3Jl/dVhA87Ns= +github.com/Antonboom/nilnil v0.1.9 h1:eKFMejSxPSA9eLSensFmjW2XTgTwJMjZ8hUHtV4s/SQ= +github.com/Antonboom/nilnil v0.1.9/go.mod h1:iGe2rYwCq5/Me1khrysB4nwI7swQvjclR8/YRPl5ihQ= +github.com/Antonboom/testifylint v1.4.1 h1:LeBVoSeqCgJoHqwu46yzm7Zgcm6T7QhDYfT9VtFIRpg= +github.com/Antonboom/testifylint v1.4.1/go.mod h1:+8Q9+AOLsz5ZiQiiYujJKs9mNz398+M6UgslP4qgJLA= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= -github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= -github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0= +github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= +github.com/Crocmagnon/fatcontext v0.3.0 h1:S6gNUYNSN9V76Tu017OFgoaOpybmMhwe6Ewh1cYd0jg= +github.com/Crocmagnon/fatcontext v0.3.0/go.mod h1:x3F9YW5CFE7vo+FGA5GzBD1SBXU4FQI0+y1ReG4Q+pY= github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 h1:sHglBQTwgx+rWPdisA5ynNEsoARbiCBOyGcJM4/OzsM= github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs= -github.com/GaijinEntertainment/go-exhaustruct/v3 v3.1.0 h1:3ZBs7LAezy8gh0uECsA6CGU43FF3zsx5f4eah5FxTMA= -github.com/GaijinEntertainment/go-exhaustruct/v3 v3.1.0/go.mod h1:rZLTje5A9kFBe0pzhpe2TdhRniBF++PRHQuRpR8esVc= +github.com/GaijinEntertainment/go-exhaustruct/v3 v3.3.0 h1:/fTUt5vmbkAcMBt4YQiuC23cV0kEsN1MVMNqeOW43cU= +github.com/GaijinEntertainment/go-exhaustruct/v3 v3.3.0/go.mod h1:ONJg5sxcbsdQQ4pOW8TGdTidT2TMAUy/2Xhr8mrYaao= github.com/Kubuxu/gocovmerge v0.0.0-20161216165753-7ecaa51963cd h1:HNhzThEtZW714v8Eda8sWWRcu9WSzJC+oCyjRjvZgRA= github.com/Kubuxu/gocovmerge v0.0.0-20161216165753-7ecaa51963cd/go.mod h1:bqoB8kInrTeEtYAwaIXoSRqdwnjQmFhsfusnzyui6yY= -github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= -github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= -github.com/OpenPeeDeeP/depguard/v2 v2.1.0 h1:aQl70G173h/GZYhWf36aE5H0KaujXfVMnn/f1kSDVYY= -github.com/OpenPeeDeeP/depguard/v2 v2.1.0/go.mod h1:PUBgk35fX4i7JDmwzlJwJ+GMe6NfO1723wmJMgPThNQ= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= -github.com/alexkohler/nakedret/v2 v2.0.2 h1:qnXuZNvv3/AxkAb22q/sEsEpcA99YxLFACDtEw9TPxE= -github.com/alexkohler/nakedret/v2 v2.0.2/go.mod h1:2b8Gkk0GsOrqQv/gPWjNLDSKwG8I5moSXG1K4VIBcTQ= +github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= +github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= +github.com/OpenPeeDeeP/depguard/v2 v2.2.0 h1:vDfG60vDtIuf0MEOhmLlLLSzqaRM8EMcgJPdp74zmpA= +github.com/OpenPeeDeeP/depguard/v2 v2.2.0/go.mod h1:CIzddKRvLBC4Au5aYP/i3nyaWQ+ClszLIuVocRiCYFQ= +github.com/alecthomas/assert/v2 v2.2.2 h1:Z/iVC0xZfWTaFNE6bA3z07T86hd45Xe2eLt6WVy2bbk= +github.com/alecthomas/assert/v2 v2.2.2/go.mod h1:pXcQ2Asjp247dahGEmsZ6ru0UVwnkhktn7S0bBDLxvQ= +github.com/alecthomas/go-check-sumtype v0.1.4 h1:WCvlB3l5Vq5dZQTFmodqL2g68uHiSwwlWcT5a2FGK0c= +github.com/alecthomas/go-check-sumtype v0.1.4/go.mod h1:WyYPfhfkdhyrdaligV6svFopZV8Lqdzn5pyVBaV6jhQ= +github.com/alecthomas/repr v0.2.0 h1:HAzS41CIzNW5syS8Mf9UwXhNH1J9aix/BvDRf1Ml2Yk= +github.com/alecthomas/repr v0.2.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= +github.com/alexkohler/nakedret/v2 v2.0.4 h1:yZuKmjqGi0pSmjGpOC016LtPJysIL0WEUiaXW5SUnNg= +github.com/alexkohler/nakedret/v2 v2.0.4/go.mod h1:bF5i0zF2Wo2o4X4USt9ntUWve6JbFv02Ff4vlkmS/VU= github.com/alexkohler/prealloc v1.0.0 h1:Hbq0/3fJPQhNkN0dR95AVrr6R7tou91y0uHG5pOcUuw= github.com/alexkohler/prealloc v1.0.0/go.mod h1:VetnK3dIgFBBKmg0YnD9F9x6Icjd+9cvfHR56wJVlKE= github.com/alingse/asasalint v0.0.11 h1:SFwnQXJ49Kx/1GghOFz1XGqHYKp21Kq1nHad/0WQRnw= @@ -80,117 +47,107 @@ github.com/ashanbrown/makezero v1.1.1/go.mod h1:i1bJLCRSCHOcOa9Y6MyF2FTfMZMFdHvx github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o= github.com/benbjohnson/clock v1.3.5/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= -github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= -github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bitfield/gotestdox v0.2.2 h1:x6RcPAbBbErKLnapz1QeAlf3ospg8efBsedU93CDsnE= +github.com/bitfield/gotestdox v0.2.2/go.mod h1:D+gwtS0urjBrzguAkTM2wodsTQYFHdpx8eqRJ3N+9pY= github.com/bkielbasa/cyclop v1.2.1 h1:AeF71HZDob1P2/pRm1so9cd1alZnrpyc4q2uP2l0gJY= github.com/bkielbasa/cyclop v1.2.1/go.mod h1:K/dT/M0FPAiYjBgQGau7tz+3TMh4FWAEqlMhzFWCrgM= github.com/blizzy78/varnamelen v0.8.0 h1:oqSblyuQvFsW1hbBHh1zfwrKe3kcSj0rnXkKzsQ089M= github.com/blizzy78/varnamelen v0.8.0/go.mod h1:V9TzQZ4fLJ1DSrjVDfl89H7aMnTvKkApdHeyESmyR7k= -github.com/bombsimon/wsl/v3 v3.4.0 h1:RkSxjT3tmlptwfgEgTgU+KYKLI35p/tviNXNXiL2aNU= -github.com/bombsimon/wsl/v3 v3.4.0/go.mod h1:KkIB+TXkqy6MvK9BDZVbZxKNYsE1/oLRJbIFtf14qqo= -github.com/breml/bidichk v0.2.4 h1:i3yedFWWQ7YzjdZJHnPo9d/xURinSq3OM+gyM43K4/8= -github.com/breml/bidichk v0.2.4/go.mod h1:7Zk0kRFt1LIZxtQdl9W9JwGAcLTTkOs+tN7wuEYGJ3s= -github.com/breml/errchkjson v0.3.1 h1:hlIeXuspTyt8Y/UmP5qy1JocGNR00KQHgfaNtRAjoxQ= -github.com/breml/errchkjson v0.3.1/go.mod h1:XroxrzKjdiutFyW3nWhw34VGg7kiMsDQox73yWCGI2U= -github.com/butuzov/ireturn v0.2.0 h1:kCHi+YzC150GE98WFuZQu9yrTn6GEydO2AuPLbTgnO4= -github.com/butuzov/ireturn v0.2.0/go.mod h1:Wh6Zl3IMtTpaIKbmwzqi6olnM9ptYQxxVacMsOEFPoc= -github.com/butuzov/mirror v1.1.0 h1:ZqX54gBVMXu78QLoiqdwpl2mgmoOJTk7s4p4o+0avZI= -github.com/butuzov/mirror v1.1.0/go.mod h1:8Q0BdQU6rC6WILDiBM60DBfvV78OLJmMmixe7GF45AE= +github.com/bombsimon/wsl/v4 v4.4.0 h1:1FHD09Li8Okn1/iERsSOo+0pXZZpVuw0XUz5/a+4+UQ= +github.com/bombsimon/wsl/v4 v4.4.0/go.mod h1:Xu/kDxGZTofQcDGCtQe9KCzhHphIe0fDuyWTxER9Feo= +github.com/breml/bidichk v0.2.7 h1:dAkKQPLl/Qrk7hnP6P+E0xOodrq8Us7+U0o4UBOAlQY= +github.com/breml/bidichk v0.2.7/go.mod h1:YodjipAGI9fGcYM7II6wFvGhdMYsC5pHDlGzqvEW3tQ= +github.com/breml/errchkjson v0.3.6 h1:VLhVkqSBH96AvXEyclMR37rZslRrY2kcyq+31HCsVrA= +github.com/breml/errchkjson v0.3.6/go.mod h1:jhSDoFheAF2RSDOlCfhHO9KqhZgAYLyvHe7bRCX8f/U= +github.com/butuzov/ireturn v0.3.0 h1:hTjMqWw3y5JC3kpnC5vXmFJAWI/m31jaCYQqzkS6PL0= +github.com/butuzov/ireturn v0.3.0/go.mod h1:A09nIiwiqzN/IoVo9ogpa0Hzi9fex1kd9PSD6edP5ZA= +github.com/butuzov/mirror v1.2.0 h1:9YVK1qIjNspaqWutSv8gsge2e/Xpq1eqEkslEUHy5cs= +github.com/butuzov/mirror v1.2.0/go.mod h1:DqZZDtzm42wIAIyHXeN8W/qb1EPlb9Qn/if9icBOpdQ= +github.com/catenacyber/perfsprint v0.7.1 h1:PGW5G/Kxn+YrN04cRAZKC+ZuvlVwolYMrIyyTJ/rMmc= +github.com/catenacyber/perfsprint v0.7.1/go.mod h1:/wclWYompEyjUD2FuIIDVKNkqz7IgBIWXIH3V0Zol50= +github.com/ccojocar/zxcvbn-go v1.0.2 h1:na/czXU8RrhXO4EZme6eQJLR4PzcGsahsBOAwU6I3Vg= +github.com/ccojocar/zxcvbn-go v1.0.2/go.mod h1:g1qkXtUSvHP8lhHp5GrSmTz6uWALGRMQdw6Qnz/hi60= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/charithe/durationcheck v0.0.10 h1:wgw73BiocdBDQPik+zcEoBG/ob8uyBHf2iyoHGPf5w4= github.com/charithe/durationcheck v0.0.10/go.mod h1:bCWXb7gYRysD1CU3C+u4ceO49LoGOY1C1L6uouGNreQ= -github.com/chavacava/garif v0.0.0-20230227094218-b8c73b2037b8 h1:W9o46d2kbNL06lq7UNDPV0zYLzkrde/bjIqO02eoll0= -github.com/chavacava/garif v0.0.0-20230227094218-b8c73b2037b8/go.mod h1:gakxgyXaaPkxvLw1XQxNGK4I37ys9iBRzNUx/B7pUCo= -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/chavacava/garif v0.1.0 h1:2JHa3hbYf5D9dsgseMKAmc/MZ109otzgNFk5s87H9Pc= +github.com/chavacava/garif v0.1.0/go.mod h1:XMyYCkEL58DF0oyW4qDjjnPWONs2HBqYKI+UIPD+Gww= +github.com/ckaznocha/intrange v0.1.2 h1:3Y4JAxcMntgb/wABQ6e8Q8leMd26JbX2790lIss9MTI= +github.com/ckaznocha/intrange v0.1.2/go.mod h1:RWffCw/vKBwHeOEwWdCikAtY0q4gGt8VhJZEEA5n+RE= 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= -github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM= github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw= github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= 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.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= -github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.3 h1:qMCsGGgs+MAzDFyp9LpAe1Lqy/fY/qCovCm0qnXZOBM= +github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/cskr/pubsub v1.0.2 h1:vlOzMhl6PFn60gRlTQQsIfVwaPB/B/8MziK8FhEPt/0= github.com/cskr/pubsub v1.0.2/go.mod h1:/8MzYXk/NJAz782G8RPkFzXTZVu63VotefPnR9TIRis= github.com/curioswitch/go-reassign v0.2.0 h1:G9UZyOcpk/d7Gd6mqYgd8XYWFMw/znxwGDUstnC9DIo= github.com/curioswitch/go-reassign v0.2.0/go.mod h1:x6OpXuWvgfQaMGks2BZybTngWjT84hqJfKoO8Tt/Roc= -github.com/daixiang0/gci v0.11.0 h1:XeQbFKkCRxvVyn06EOuNY6LPGBLVuB/W130c8FrnX6A= -github.com/daixiang0/gci v0.11.0/go.mod h1:xtHP9N7AHdNvtRNfcx9gwTDfw7FRJx4bZUsiEfiNNAI= +github.com/daixiang0/gci v0.13.4 h1:61UGkmpoAcxHM2hhNkZEf5SzwQtWJXTSws7jaPyqwlw= +github.com/daixiang0/gci v0.13.4/go.mod h1:12etP2OniiIdP4q+kjUGrC/rUagga7ODbqsom5Eo5Yk= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c h1:pFUpOrbxDR6AkioZ1ySsx5yxlDQZ8stG2b88gTPxgJU= github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c/go.mod h1:6UhI8N9EjYm1c2odKpFpAYeR8dsBeM7PtzQhRgxRr9U= github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y= github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= -github.com/denis-tingaikin/go-header v0.4.3 h1:tEaZKAlqql6SKCY++utLmkPLd6K8IBM20Ha7UVm+mtU= -github.com/denis-tingaikin/go-header v0.4.3/go.mod h1:0wOCWuN71D5qIgE2nz9KrKmuYBAC2Mra5RassOIQ2/c= +github.com/denis-tingaikin/go-header v0.5.0 h1:SRdnP5ZKvcO9KKRP1KJrhFR3RrlGuD+42t4429eC9k8= +github.com/denis-tingaikin/go-header v0.5.0/go.mod h1:mMenU5bWrok6Wl2UsZjy+1okegmwQ3UgWl4V1D8gjlY= +github.com/dnephin/pflag v1.0.7 h1:oxONGlWxhmUct0YzKTgrpQv9AUA1wtPBn7zuSjJqptk= +github.com/dnephin/pflag v1.0.7/go.mod h1:uxE91IoWURlOiTUIA8Mq5ZZkAv3dPUfZNaT80Zm7OQE= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= -github.com/elastic/gosigar v0.14.2 h1:Dg80n8cr90OZ7x+bAax/QjoW/XqTI11RmA79ZwIm9/4= -github.com/elastic/gosigar v0.14.2/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= +github.com/elastic/gosigar v0.14.3 h1:xwkKwPia+hSfg9GqrCUKYdId102m9qTJIIr7egmK/uo= +github.com/elastic/gosigar v0.14.3/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= -github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/esimonov/ifshort v1.0.4 h1:6SID4yGWfRae/M7hkVDVVyppy8q/v9OuxNdmjLQStBA= -github.com/esimonov/ifshort v1.0.4/go.mod h1:Pe8zjlRrJ80+q2CxHLfEOfTwxCZ4O+MuhcHcfgNWTk0= -github.com/ettle/strcase v0.1.1 h1:htFueZyVeE1XNnMEfbqp5r67qAN/4r6ya1ysq8Q+Zcw= -github.com/ettle/strcase v0.1.1/go.mod h1:hzDLsPC7/lwKyBOywSHEP89nt2pDgdy+No1NBA9o9VY= +github.com/ettle/strcase v0.2.0 h1:fGNiVF21fHXpX1niBgk0aROov1LagYsOwV/xqKDKR/Q= +github.com/ettle/strcase v0.2.0/go.mod h1:DajmHElDSaX76ITe3/VHVyMin4LWSJN5Z909Wp+ED1A= github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5 h1:BBso6MBKW8ncyZLv37o+KNyy0HrrHgfnOaGQC2qvN+A= github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5/go.mod h1:JpoxHjuQauoxiFMl1ie8Xc/7TfLuMZ5eOCONd1sUBHg= -github.com/fatih/color v1.6.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= +github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= +github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4= +github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI= github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4= github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94= -github.com/firefart/nonamedreturns v1.0.4 h1:abzI1p7mAEPYuR4A+VLKn4eNDOycjYo2phmY9sfv40Y= -github.com/firefart/nonamedreturns v1.0.4/go.mod h1:TDhe/tjI1BXo48CmYbUduTV7BdIga8MAO/xbKdcVsGI= +github.com/firefart/nonamedreturns v1.0.5 h1:tM+Me2ZaXs8tfdDw3X6DOX++wMCOqzYUho6tUTYIdRA= +github.com/firefart/nonamedreturns v1.0.5/go.mod h1:gHJjDqhGM4WyPt639SOZs+G89Ko7QKH5R5BhnO6xJhw= github.com/flynn/noise v1.1.0 h1:KjPQoQCEFdZDiP03phOvGi11+SVVhBG2wOWAorLsstg= github.com/flynn/noise v1.1.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag= github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk= github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= -github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= +github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/fzipp/gocyclo v0.6.0 h1:lsblElZG7d3ALtGMx9fmxeTKZaLLpU8mET09yN4BBLo= github.com/fzipp/gocyclo v0.6.0/go.mod h1:rXPyn8fnlpa0R2csP/31uerbiVBugk5whMdlyaLkLoA= -github.com/go-critic/go-critic v0.9.0 h1:Pmys9qvU3pSML/3GEQ2Xd9RZ/ip+aXHKILuxczKGV/U= -github.com/go-critic/go-critic v0.9.0/go.mod h1:5P8tdXL7m/6qnyG6oRAlYLORvoXH0WDypYgAEmagT40= -github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= -github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/ghostiam/protogetter v0.3.6 h1:R7qEWaSgFCsy20yYHNIJsU9ZOb8TziSRRxuAOTVKeOk= +github.com/ghostiam/protogetter v0.3.6/go.mod h1:7lpeDnEJ1ZjL/YtyoN99ljO4z0pd3H0d18/t2dPBxHw= +github.com/go-critic/go-critic v0.11.4 h1:O7kGOCx0NDIni4czrkRIXTnit0mkyKOCePh3My6OyEU= +github.com/go-critic/go-critic v0.11.4/go.mod h1:2QAdo4iuLik5S9YG0rT4wcZ8QxwHYkrr6/2MWAiv/vc= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= @@ -199,8 +156,9 @@ github.com/go-toolsmith/astcast v1.1.0/go.mod h1:qdcuFWeGGS2xX5bLM/c3U9lewg7+Zu4 github.com/go-toolsmith/astcopy v1.1.0 h1:YGwBN0WM+ekI/6SS6+52zLDEf8Yvp3n2seZITCUBt5s= github.com/go-toolsmith/astcopy v1.1.0/go.mod h1:hXM6gan18VA1T/daUEHCFcYiW8Ai1tIwIzHY6srfEAw= github.com/go-toolsmith/astequal v1.0.3/go.mod h1:9Ai4UglvtR+4up+bAD4+hCj7iTo4m/OXVTSLnCyTAx4= -github.com/go-toolsmith/astequal v1.1.0 h1:kHKm1AWqClYn15R0K1KKE4RG614D46n+nqUQ06E1dTw= github.com/go-toolsmith/astequal v1.1.0/go.mod h1:sedf7VIdCL22LD8qIvv7Nn9MuWJruQA/ysswh64lffQ= +github.com/go-toolsmith/astequal v1.2.0 h1:3Fs3CYZ1k9Vo4FzFhwwewC3CHISHDnVUPC4x0bI2+Cw= +github.com/go-toolsmith/astequal v1.2.0/go.mod h1:c8NZ3+kSFtFY/8lPso4v8LuJjdJiUFVnSuU3s0qrrDY= github.com/go-toolsmith/astfmt v1.1.0 h1:iJVPDPp6/7AaeLJEruMsBUlOYCmvg0MoCfJprsOmcco= github.com/go-toolsmith/astfmt v1.1.0/go.mod h1:OrcLlRwu0CuiIBp/8b5PYF9ktGVZUjlNMV634mhwuQ4= github.com/go-toolsmith/astp v1.1.0 h1:dXPuCl6u2llURjdPLLDxJeZInAeZ0/eZwFJmqZMnpQA= @@ -212,6 +170,8 @@ github.com/go-toolsmith/strparse v1.1.0 h1:GAioeZUK9TGxnLS+qfdqNbA4z0SSm5zVNtCQi github.com/go-toolsmith/strparse v1.1.0/go.mod h1:7ksGy58fsaQkGQlY8WVoBFNyEPMGuJin1rfoPS4lBSQ= github.com/go-toolsmith/typep v1.1.0 h1:fIRYDyF+JywLfqzyhdiHzRop/GQDxxNhLGQ6gFUNHus= github.com/go-toolsmith/typep v1.1.0/go.mod h1:fVIw+7zjdsMxDA3ITWnH1yOiw1rnTQKCsF/sk2H/qig= +github.com/go-viper/mapstructure/v2 v2.0.0 h1:dhn8MZ1gZ0mzeodTG3jt5Vj/o87xZKuNAprG2mQfMfc= +github.com/go-viper/mapstructure/v2 v2.0.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/go-xmlfmt/xmlfmt v1.1.2 h1:Nea7b4icn8s57fTx1M5AI4qQT5HEM3rVUO8MuE6g80U= github.com/go-xmlfmt/xmlfmt v1.1.2/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM= github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0= @@ -221,107 +181,69 @@ github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= -github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= -github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2 h1:23T5iq8rbUYlhpt5DB4XJkc6BU31uODLD1o1gKvZmD0= -github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2/go.mod h1:k9Qvh+8juN+UKMCS/3jFtGICgW8O96FVaZsaxdzDkR4= github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a h1:w8hkcTqaFpzKqonE9uMCefW1WDie15eSP/4MssdenaM= github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a/go.mod h1:ryS0uhF+x9jgbj/N71xsEqODy9BN81/GonCZiOzirOk= -github.com/golangci/go-misc v0.0.0-20220329215616-d24fe342adfe h1:6RGUuS7EGotKx6J5HIP8ZtyMdiDscjMLfRBSPuzVVeo= -github.com/golangci/go-misc v0.0.0-20220329215616-d24fe342adfe/go.mod h1:gjqyPShc/m8pEMpk0a3SeagVb0kaqvhscv+i9jI5ZhQ= -github.com/golangci/gofmt v0.0.0-20220901101216-f2edd75033f2 h1:amWTbTGqOZ71ruzrdA+Nx5WA3tV1N0goTspwmKCQvBY= -github.com/golangci/gofmt v0.0.0-20220901101216-f2edd75033f2/go.mod h1:9wOXstvyDRshQ9LggQuzBCGysxs3b6Uo/1MvYCR2NMs= -github.com/golangci/golangci-lint v1.54.1 h1:0qMrH1gkeIBqCZaaAm5Fwq4xys9rO/lJofHfZURIFFk= -github.com/golangci/golangci-lint v1.54.1/go.mod h1:JK47+qksV/t2mAz9YvndwT0ZLW4A1rvDljOs3g9jblo= -github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0 h1:MfyDlzVjl1hoaPzPD4Gpb/QgoRfSBR0jdhwGyAWwMSA= -github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0/go.mod h1:66R6K6P6VWk9I95jvqGxkqJxVWGFy9XlDwLwVz1RCFg= -github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca h1:kNY3/svz5T29MYHubXix4aDDuE3RWHkPvopM/EDv/MA= -github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca/go.mod h1:tvlJhZqDe4LMs4ZHD0oMUlt9G2LWuDGoisJTBzLMV9o= -github.com/golangci/misspell v0.4.1 h1:+y73iSicVy2PqyX7kmUefHusENlrP9YwuHZHPLGQj/g= -github.com/golangci/misspell v0.4.1/go.mod h1:9mAN1quEo3DlpbaIKKyEvRxK1pwqR9s/Sea1bJCtlNI= -github.com/golangci/revgrep v0.0.0-20220804021717-745bb2f7c2e6 h1:DIPQnGy2Gv2FSA4B/hh8Q7xx3B7AIDk3DAMeHclH1vQ= -github.com/golangci/revgrep v0.0.0-20220804021717-745bb2f7c2e6/go.mod h1:0AKcRCkMoKvUvlf89F6O7H2LYdhr1zBh736mBItOdRs= -github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4 h1:zwtduBRr5SSWhqsYNgcuWO2kFlpdOZbP0+yRjmvPGys= -github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4/go.mod h1:Izgrg8RkN3rCIMLGE9CyYmU9pY2Jer6DgANEnZ/L/cQ= -github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/golangci/gofmt v0.0.0-20231019111953-be8c47862aaa h1:L0Zq43Px2HrLroRKEgfCsQLMJUkjskJBB1kd1Zjcvvc= +github.com/golangci/gofmt v0.0.0-20231019111953-be8c47862aaa/go.mod h1:Pm5KhLPA8gSnQwrQ6ukebRcapGb/BG9iUkdaiCcGHJM= +github.com/golangci/golangci-lint v1.59.1 h1:CRRLu1JbhK5avLABFJ/OHVSQ0Ie5c4ulsOId1h3TTks= +github.com/golangci/golangci-lint v1.59.1/go.mod h1:jX5Oif4C7P0j9++YB2MMJmoNrb01NJ8ITqKWNLewThg= +github.com/golangci/misspell v0.6.0 h1:JCle2HUTNWirNlDIAUO44hUsKhOFqGPoC4LZxlaSXDs= +github.com/golangci/misspell v0.6.0/go.mod h1:keMNyY6R9isGaSAu+4Q8NMBwMPkh15Gtc8UCVoDtAWo= +github.com/golangci/modinfo v0.3.4 h1:oU5huX3fbxqQXdfspamej74DFX0kyGLkw1ppvXoJ8GA= +github.com/golangci/modinfo v0.3.4/go.mod h1:wytF1M5xl9u0ij8YSvhkEVPP3M5Mc7XLl1pxH3B2aUM= +github.com/golangci/plugin-module-register v0.1.1 h1:TCmesur25LnyJkpsVrupv1Cdzo+2f7zX0H6Jkw1Ol6c= +github.com/golangci/plugin-module-register v0.1.1/go.mod h1:TTpqoB6KkwOJMV8u7+NyXMrkwwESJLOkfl9TxR1DGFc= +github.com/golangci/revgrep v0.5.3 h1:3tL7c1XBMtWHHqVpS5ChmiAAoe4PF/d5+ULzV9sLAzs= +github.com/golangci/revgrep v0.5.3/go.mod h1:U4R/s9dlXZsg8uJmaR1GrloUr14D7qDl8gi2iPXJH8k= +github.com/golangci/unconvert v0.0.0-20240309020433-c5143eacb3ed h1:IURFTjxeTfNFP0hTEi1YKjB/ub8zkpaOqFFMApi2EAs= +github.com/golangci/unconvert v0.0.0-20240309020433-c5143eacb3ed/go.mod h1:XLXN8bNw4CGRPaqgl3bv/lhz7bsGPh4/xSaMTbo2vkQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -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= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= -github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20240509144519-723abb6459b7 h1:velgFPYr1X9TDwLIfkV7fWqsFlf7TeP11M/7kPd/dVI= -github.com/google/pprof v0.0.0-20240509144519-723abb6459b7/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= +github.com/google/pprof v0.0.0-20240618054019-d3b898a103f8 h1:ASJ/LAqdCHOyMYI+dwNxn7Rd8FscNkMyTr1KZU1JI/M= +github.com/google/pprof v0.0.0-20240618054019-d3b898a103f8/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= +github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c h1:7lF+Vz0LqiRidnzC1Oq86fpX1q/iEv2KJdrCtttYjT4= github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gordonklaus/ineffassign v0.0.0-20230610083614-0e73809eb601 h1:mrEEilTAUmaAORhssPPkxj84TsHrPMLBGW2Z4SoTxm8= -github.com/gordonklaus/ineffassign v0.0.0-20230610083614-0e73809eb601/go.mod h1:Qcp2HIAYhR7mNUVSIxZww3Guk4it82ghYcEXIAk+QT0= -github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= -github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= +github.com/gordonklaus/ineffassign v0.1.0 h1:y2Gd/9I7MdY1oEIt+n+rowjBNDcLQq3RsH5hwJd0f9s= +github.com/gordonklaus/ineffassign v0.1.0/go.mod h1:Qcp2HIAYhR7mNUVSIxZww3Guk4it82ghYcEXIAk+QT0= +github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= +github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gostaticanalysis/analysisutil v0.7.1 h1:ZMCjoue3DtDWQ5WyU16YbjbQEQ3VuzwxALrpYd+HeKk= github.com/gostaticanalysis/analysisutil v0.7.1/go.mod h1:v21E3hY37WKMGSnbsw2S/ojApNWb6C1//mXO48CXbVc= github.com/gostaticanalysis/comment v1.4.1/go.mod h1:ih6ZxzTHLdadaiSnF5WY3dxUoXfXAlTaRzuaNDlSado= @@ -342,10 +264,8 @@ github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brv github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= -github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= +github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c= github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= @@ -354,17 +274,14 @@ github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= -github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.20.0 h1:umUl7q1v5g5AX8FPLTnZBvvagLmT+V0Tt61EigP81ec= -github.com/ipfs/boxo v0.20.0/go.mod h1:mwttn53Eibgska2DhVIj7ln3UViq7MVHRxOMb+ehSDM= +github.com/ipfs/boxo v0.21.0 h1:XpGXb+TQQ0IUdYaeAxGzWjSs6ow/Lce148A/2IbRDVE= +github.com/ipfs/boxo v0.21.0/go.mod h1:NmweAYeY1USOaJJxouy7DLr/Y5M8UBSsCI2KRivO+TY= github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs= github.com/ipfs/go-block-format v0.2.0/go.mod h1:+jpL11nFx5A/SPpsoBn6Bzkra/zaArfSmsknbPMYgzM= github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= @@ -417,45 +334,32 @@ github.com/jbenet/go-temp-err-catcher v0.1.0 h1:zpb3ZH6wIE8Shj2sKS+khgRvf7T7RABo github.com/jbenet/go-temp-err-catcher v0.1.0/go.mod h1:0kJRvmDZXNMIiJirNPEYfhpPwbGVtZVWC34vc5WLsDk= github.com/jbenet/goprocess v0.1.4 h1:DRGOFReOMqqDNXwW70QkacFW0YN9QnwLV0Vqk+3oU0o= github.com/jbenet/goprocess v0.1.4/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= -github.com/jgautheron/goconst v1.5.1 h1:HxVbL1MhydKs8R8n/HE5NPvzfaYmQJA3o879lE4+WcM= -github.com/jgautheron/goconst v1.5.1/go.mod h1:aAosetZ5zaeC/2EfMeRswtxUFBpe2Hr7HzkgX4fanO4= +github.com/jgautheron/goconst v1.7.1 h1:VpdAG7Ca7yvvJk5n8dMwQhfEZJh95kl/Hl9S1OI5Jkk= +github.com/jgautheron/goconst v1.7.1/go.mod h1:aAosetZ5zaeC/2EfMeRswtxUFBpe2Hr7HzkgX4fanO4= github.com/jingyugao/rowserrcheck v1.1.1 h1:zibz55j/MJtLsjP1OF4bSdgXxwL1b+Vn7Tjzq7gFzUs= github.com/jingyugao/rowserrcheck v1.1.1/go.mod h1:4yvlZSDb3IyDTUZJUmpZfm2Hwok+Dtp+nu2qOq+er9c= github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af h1:KA9BjwUk7KlCh6S9EAGWBt1oExIUv9WyNCiRz5amv48= github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af/go.mod h1:HEWGJkRDzjJY2sqdDwxccsGicWEf9BQOZsq2tV+xzM0= -github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= -github.com/jonboulle/clockwork v0.2.0 h1:J2SLSdy7HgElq8ekSl2Mxh6vrRNFxqbXGenYH2I02Vs= -github.com/jonboulle/clockwork v0.2.0/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= -github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= -github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/jjti/go-spancheck v0.6.1 h1:ZK/wE5Kyi1VX3PJpUO2oEgeoI4FWOUm7Shb2Gbv5obI= +github.com/jjti/go-spancheck v0.6.1/go.mod h1:vF1QkOO159prdo6mHRxak2CpzDpHAfKiPUDP/NeRnX8= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/julz/importas v0.1.0 h1:F78HnrsjY3cR7j0etXy5+TU1Zuy7Xt08X/1aJnH5xXY= github.com/julz/importas v0.1.0/go.mod h1:oSFU2R4XK/P7kNBrnL/FEQlDGN1/6WoxXEjSSXO0DV0= +github.com/karamaru-alpha/copyloopvar v1.1.0 h1:x7gNyKcC2vRBO1H2Mks5u1VxQtYvFiym7fCjIP8RPos= +github.com/karamaru-alpha/copyloopvar v1.1.0/go.mod h1:u7CIfztblY0jZLOQZgH3oYsJzpC2A7S6u/lfgSXHy0k= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= -github.com/kisielk/errcheck v1.6.3 h1:dEKh+GLHcWm2oN34nMvDzn1sqI0i0WxPvrgiJA5JuM8= -github.com/kisielk/errcheck v1.6.3/go.mod h1:nXw/i/MfnvRHqXa7XXmQMUB0oNFGuBrNI8d8NLy0LPw= -github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= +github.com/kisielk/errcheck v1.7.0 h1:+SbscKmWJ5mOK/bO1zS60F5I9WwZDWOfRsC4RwfwRV0= +github.com/kisielk/errcheck v1.7.0/go.mod h1:1kLL+jV4e+CFfueBmI1dSK2ADDyQnlrnrY/FqKluHJQ= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/kkHAIKE/contextcheck v1.1.4 h1:B6zAaLhOEEcjvUgIYEqystmnFk1Oemn8bvJhbt0GMb8= -github.com/kkHAIKE/contextcheck v1.1.4/go.mod h1:1+i/gWqokIa+dm31mqGLZhZJ7Uh44DJGZVmr6QRBNJg= -github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU= -github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/kkHAIKE/contextcheck v1.1.5 h1:CdnJh63tcDe53vG+RebdpdXJTc9atMgGqdx8LXxiilg= +github.com/kkHAIKE/contextcheck v1.1.5/go.mod h1:O930cpht4xb1YQpK+1+AgoM3mFsvxr7uyFptcnWTYUA= +github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= +github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM= github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/koron/go-ssdp v0.0.4 h1:1IDwrghSKYM7yLf7XCzbByg2sJ/JcNOZRXS2jczTwz0= github.com/koron/go-ssdp v0.0.4/go.mod h1:oDXq+E5IL5q0U8uSBcoAXzTzInwy5lEgC91HoKtbmZk= -github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= @@ -465,16 +369,18 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kulti/thelper v0.6.3 h1:ElhKf+AlItIu+xGnI990no4cE2+XaSu1ULymV2Yulxs= github.com/kulti/thelper v0.6.3/go.mod h1:DsqKShOvP40epevkFrvIwkCMNYxMeTNjdWL4dqWHZ6I= -github.com/kunwardeep/paralleltest v1.0.8 h1:Ul2KsqtzFxTlSU7IP0JusWlLiNqQaloB9vguyjbE558= -github.com/kunwardeep/paralleltest v1.0.8/go.mod h1:2C7s65hONVqY7Q5Efj5aLzRCNLjw2h4eMc9EcypGjcY= +github.com/kunwardeep/paralleltest v1.0.10 h1:wrodoaKYzS2mdNVnc4/w31YaXFtsc21PCTdvWJ/lDDs= +github.com/kunwardeep/paralleltest v1.0.10/go.mod h1:2C7s65hONVqY7Q5Efj5aLzRCNLjw2h4eMc9EcypGjcY= github.com/kyoh86/exportloopref v0.1.11 h1:1Z0bcmTypkL3Q4k+IDHMWTcnCliEZcaPiIe0/ymEyhQ= github.com/kyoh86/exportloopref v0.1.11/go.mod h1:qkV4UF1zGl6EkF1ox8L5t9SwyeBAZ3qLMd6up458uqA= -github.com/ldez/gomoddirectives v0.2.3 h1:y7MBaisZVDYmKvt9/l1mjNCiSA1BVn34U0ObUcJwlhA= -github.com/ldez/gomoddirectives v0.2.3/go.mod h1:cpgBogWITnCfRq2qGoDkKMEVSaarhdBr6g8G04uz6d0= +github.com/lasiar/canonicalheader v1.1.1 h1:wC+dY9ZfiqiPwAexUApFush/csSPXeIi4QqyxXmng8I= +github.com/lasiar/canonicalheader v1.1.1/go.mod h1:cXkb3Dlk6XXy+8MVQnF23CYKWlyA7kfQhSw2CcZtZb0= +github.com/ldez/gomoddirectives v0.2.4 h1:j3YjBIjEBbqZ0NKtBNzr8rtMHTOrLPeiwTkfUJZ3alg= +github.com/ldez/gomoddirectives v0.2.4/go.mod h1:oWu9i62VcQDYp9EQ0ONTfqLNh+mDLWWDO+SO0qSQw5g= github.com/ldez/tagliatelle v0.5.0 h1:epgfuYt9v0CG3fms0pEgIMNPuFf/LpPIfjk4kyqSioo= github.com/ldez/tagliatelle v0.5.0/go.mod h1:rj1HmWiL1MiKQuOONhd09iySTEkUuE/8+5jtPYz9xa4= -github.com/leonklingele/grouper v1.1.1 h1:suWXRU57D4/Enn6pXR0QVqqWWrnJ9Osrz+5rjt8ivzU= -github.com/leonklingele/grouper v1.1.1/go.mod h1:uk3I3uDfi9B6PeUjsCKi6ndcf63Uy7snXgR4yDYQVDY= +github.com/leonklingele/grouper v1.1.2 h1:o1ARBDLOmmasUaNDesWqWCIFH3u7hoFlM84YrjT3mIY= +github.com/leonklingele/grouper v1.1.2/go.mod h1:6D0M/HVkhs2yRKRFZUoGjeDy7EZTfFBE9gl4kjmIGkA= github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38yPW7c= @@ -507,36 +413,36 @@ github.com/libp2p/go-yamux/v4 v4.0.1 h1:FfDR4S1wj6Bw2Pqbc8Uz7pCxeRBPbwsBbEdfwiCy github.com/libp2p/go-yamux/v4 v4.0.1/go.mod h1:NWjl8ZTLOGlozrXSOZ/HlfG++39iKNnM5wwmtQP1YB4= github.com/lufeee/execinquery v1.2.1 h1:hf0Ems4SHcUGBxpGN7Jz78z1ppVkP/837ZlETPCEtOM= github.com/lufeee/execinquery v1.2.1/go.mod h1:EC7DrEKView09ocscGHC+apXMIaorh4xqSxS/dy8SbM= -github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo= -github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= +github.com/macabu/inamedparam v0.1.3 h1:2tk/phHkMlEL/1GNe/Yf6kkR/hkcUdAEY3L0hjYV1Mk= +github.com/macabu/inamedparam v0.1.3/go.mod h1:93FLICAIk/quk7eaPPQvbzihUdn/QkGDwIZEoLtpH6I= +github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= +github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/maratori/testableexamples v1.0.0 h1:dU5alXRrD8WKSjOUnmJZuzdxWOEQ57+7s93SLMxb2vI= github.com/maratori/testableexamples v1.0.0/go.mod h1:4rhjL1n20TUTT4vdh3RDqSizKLyXp7K2u6HgraZCGzE= github.com/maratori/testpackage v1.1.1 h1:S58XVV5AD7HADMmD0fNnziNHqKvSdDuEKdPD1rNTU04= github.com/maratori/testpackage v1.1.1/go.mod h1:s4gRK/ym6AMrqpOa/kEbQTV4Q4jb7WeLZzVhVVVOQMc= 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/matoous/godox v0.0.0-20230222163458-006bad1f9d26 h1:gWg6ZQ4JhDfJPqlo2srm/LN17lpybq15AryXIRcWYLE= -github.com/matoous/godox v0.0.0-20230222163458-006bad1f9d26/go.mod h1:1BELzlh859Sh1c6+90blK8lbYy0kwQf1bYlBhBysy1s= +github.com/matoous/godox v0.0.0-20240105082147-c5b5e0e7c0c0 h1:Ny7cm4KSWceJLYyI1sm+aFIVDWSGXLcOJ0O0UaS5wdU= +github.com/matoous/godox v0.0.0-20240105082147-c5b5e0e7c0c0/go.mod h1:jgE/3fUXiTurkdHOLT5WEkThTSuE7yxHv5iWPa80afs= github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE= github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU= -github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= -github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/mbilski/exhaustivestruct v1.2.0 h1:wCBmUnSYufAHO6J4AVWY6ff+oxWxsVFrwgOdMUQePUo= -github.com/mbilski/exhaustivestruct v1.2.0/go.mod h1:OeTBVxQWoEmB2J2JCHmXWPJ0aksxSUOUy+nvtVEfzXc= -github.com/mgechev/revive v1.3.2 h1:Wb8NQKBaALBJ3xrrj4zpwJwqwNA6nDpyJSEQWcCka6U= -github.com/mgechev/revive v1.3.2/go.mod h1:UCLtc7o5vg5aXCwdUTU1kEBQ1v+YXPAkYDIDXbrs5I0= +github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= +github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mgechev/revive v1.3.7 h1:502QY0vQGe9KtYJ9FpxMz9rL+Fc/P13CI5POL4uHCcE= +github.com/mgechev/revive v1.3.7/go.mod h1:RJ16jUbF0OWC3co/+XTxmFNgEpUPwnnA0BRllX2aDNA= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= -github.com/miekg/dns v1.1.59 h1:C9EXc/UToRwKLhK5wKU/I4QVsBUc8kE6MkHBkeypWZs= -github.com/miekg/dns v1.1.59/go.mod h1:nZpewl5p6IvctfgrckopVx2OlSEHPRO/U4SYkRklrEk= +github.com/miekg/dns v1.1.61 h1:nLxbwF3XxhwVSm8g9Dghm9MHPaUZuqhPiGL+675ZmEs= +github.com/miekg/dns v1.1.61/go.mod h1:mnAarhS3nWaW+NVP2wTkYVIZyHNJ098SJZUki3eykwQ= github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b/go.mod h1:lxPUiZwKoFL8DUUmalo2yJJUCxbPKtm8OKfqr2/FTNU= github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc h1:PTfri+PuQmWDqERdnNMiD9ZejrlswWrCpBEZgWOiTrc= @@ -549,11 +455,6 @@ github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/moricho/tparallel v0.3.1 h1:fQKD4U1wRMAYNngDonW5XupoB/ZGJHdpzrWqgyg9krA= github.com/moricho/tparallel v0.3.1/go.mod h1:leENX2cUv7Sv2qDgdi0D0fCftN8fRC67Bcn8pqzeYNI= github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= @@ -582,44 +483,35 @@ github.com/multiformats/go-multistream v0.5.0/go.mod h1:n6tMZiwiP2wUsR8DgfDWw1dy github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8= github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU= -github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/nakabonne/nestif v0.3.1 h1:wm28nZjhQY5HyYPx+weN3Q65k6ilSBxDb8v5S81B81U= github.com/nakabonne/nestif v0.3.1/go.mod h1:9EtoZochLn5iUprVDmDjqGKPofoUEBL8U4Ngq6aY7OE= -github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354 h1:4kuARK6Y6FxaNu/BnU2OAaLF86eTVhP2hjTB6iMvItA= -github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354/go.mod h1:KSVJerMDfblTH7p5MZaTt+8zaT2iEk3AkVb9PQdZuE8= -github.com/nishanths/exhaustive v0.11.0 h1:T3I8nUGhl/Cwu5Z2hfc92l0e04D2GEW6e0l8pzda2l0= -github.com/nishanths/exhaustive v0.11.0/go.mod h1:RqwDsZ1xY0dNdqHho2z6X+bgzizwbLYOWnZbbl2wLB4= +github.com/nishanths/exhaustive v0.12.0 h1:vIY9sALmw6T/yxiASewa4TQcFsVYZQQRUQJhKRf3Swg= +github.com/nishanths/exhaustive v0.12.0/go.mod h1:mEZ95wPIZW+x8kC4TgC+9YCUgiST7ecevsVDTgc2obs= github.com/nishanths/predeclared v0.2.2 h1:V2EPdZPliZymNAn79T8RkNApBjMmVKh5XRpLm/w98Vk= github.com/nishanths/predeclared v0.2.2/go.mod h1:RROzoN6TnGQupbC+lqggsOlcgysk3LMK/HI84Mp280c= -github.com/nunnatsa/ginkgolinter v0.13.3 h1:wEvjrzSMfDdnoWkctignX9QTf4rT9f4GkQ3uVoXBmiU= -github.com/nunnatsa/ginkgolinter v0.13.3/go.mod h1:aTKXo8WddENYxNEFT+4ZxEgWXqlD9uMD3w9Bfw/ABEc= +github.com/nunnatsa/ginkgolinter v0.16.2 h1:8iLqHIZvN4fTLDC0Ke9tbSZVcyVHoBs0HIbnVSxfHJk= +github.com/nunnatsa/ginkgolinter v0.16.2/go.mod h1:4tWRinDN1FeJgU+iJANW/kz7xKN5nYRAOfJDQUS9dOQ= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w= -github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo/v2 v2.17.3 h1:oJcvKpIb7/8uLpDDtnQuf18xVnwKp8DTD7DQ6gTd/MU= -github.com/onsi/ginkgo/v2 v2.17.3/go.mod h1:nP2DPOQoNsQmsVyv5rDA8JkXQoCs6goXIvr/PRJ1eCc= -github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= -github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= +github.com/onsi/ginkgo/v2 v2.19.0 h1:9Cnnf7UHo57Hy3k6/m5k3dRfGTMXGvxhHFvkDTCTpvA= +github.com/onsi/ginkgo/v2 v2.19.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To= +github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk= +github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0= github.com/opencontainers/runtime-spec v1.2.0 h1:z97+pHb3uELt/yiAWD691HNHQIF07bE7dzrbT927iTk= github.com/opencontainers/runtime-spec v1.2.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= -github.com/otiai10/copy v1.2.0 h1:HvG945u96iNadPoG2/Ja2+AUJeW5YuFQMixq9yirC+k= github.com/otiai10/copy v1.2.0/go.mod h1:rrF5dJ5F0t/EWSYODDu4j9/vEeYHMkc8jt0zJChqQWw= +github.com/otiai10/copy v1.14.0 h1:dCI/t1iTdYGtkvCuBG2BgR6KZa83PTclw4U5n2wAllU= +github.com/otiai10/copy v1.14.0/go.mod h1:ECfuL02W+/FkTWZWgQqXPWZgW9oeKCSQ5qVfSc4qc4w= github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs= github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo= github.com/otiai10/mint v1.3.1/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc= 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/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= -github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= -github.com/pelletier/go-toml/v2 v2.0.5 h1:ipoSadvV8oGUjnUbMub59IDPPwfxF694nG/jwbMiyQg= -github.com/pelletier/go-toml/v2 v2.0.5/go.mod h1:OMHamSCAODeSsVrwwvcJOaoN0LIUIaFVNZzmWyNfXas= +github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= +github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= github.com/pion/datachannel v1.5.6 h1:1IxKJntfSlYkpUj8LlYRSWpYiTTC02nUrOE8T3DqGeg= github.com/pion/datachannel v1.5.6/go.mod h1:1eKT6Q85pRnr2mHiWHxJwO50SfZRtWHTsNIVb/NfGW4= github.com/pion/dtls/v2 v2.2.11 h1:9U/dpCYl1ySttROPWJgqWKEylUdT0fXp/xst6JwY5Ks= @@ -650,47 +542,33 @@ github.com/pion/transport/v2 v2.2.5 h1:iyi25i/21gQck4hfRhomF6SktmUQjRsRW4WJdhfc3 github.com/pion/transport/v2 v2.2.5/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0= github.com/pion/turn/v2 v2.1.6 h1:Xr2niVsiPTB0FPtt+yAWKFUkU1eotQbGgpTIld4x1Gc= github.com/pion/turn/v2 v2.1.6/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY= -github.com/pion/webrtc/v3 v3.2.40 h1:Wtfi6AZMQg+624cvCXUuSmrKWepSB7zfgYDOYqsSOVU= -github.com/pion/webrtc/v3 v3.2.40/go.mod h1:M1RAe3TNTD1tzyvqHrbVODfwdPGSXOUo/OgpoGGJqFY= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pion/webrtc/v3 v3.2.42 h1:WN/ZuMjtpQOoGRCZUg/zFG+JHEvYLVyDKOxU6H1qWlE= +github.com/pion/webrtc/v3 v3.2.42/go.mod h1:M1RAe3TNTD1tzyvqHrbVODfwdPGSXOUo/OgpoGGJqFY= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/polydawn/refmt v0.89.0 h1:ADJTApkvkeBZsN0tBTx8QjpD9JkmxbKp0cxfr9qszm4= github.com/polydawn/refmt v0.89.0/go.mod h1:/zvteZs/GwLtCgZ4BL6CBsk9IKIlexP43ObX9AxTqTw= -github.com/polyfloyd/go-errorlint v1.4.3 h1:P6NALOLV8BrWhm6PsqOraUK05E5h8IZnpXYJ+CIg+0U= -github.com/polyfloyd/go-errorlint v1.4.3/go.mod h1:VPlWPh6hB/wruVG803SuNpLuTGNjLHYlvcdSy4RhdPA= -github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= +github.com/polyfloyd/go-errorlint v1.5.2 h1:SJhVik3Umsjh7mte1vE0fVZ5T1gznasQG3PV7U5xFdA= +github.com/polyfloyd/go-errorlint v1.5.2/go.mod h1:sH1QC1pxxi0fFecsVIzBmxtrgd9IF/SkJpA6wqyKAJs= +github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g= +github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U= github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE= github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho= -github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= -github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= -github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= -github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/common v0.54.0 h1:ZlZy0BgJhTwVZUn7dLOkwCZHUkrAqd3WYtcFCWnM1D8= github.com/prometheus/common v0.54.0/go.mod h1:/TQgMJP5CuVYveyT7n/0Ix8yLNNXy9yRSkhnLTHPDIQ= -github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= -github.com/quasilyte/go-ruleguard v0.4.0 h1:DyM6r+TKL+xbKB4Nm7Afd1IQh9kEUKQs2pboWGKtvQo= -github.com/quasilyte/go-ruleguard v0.4.0/go.mod h1:Eu76Z/R8IXtViWUIHkE3p8gdH3/PKk1eh3YGfaEof10= +github.com/quasilyte/go-ruleguard v0.4.2 h1:htXcXDK6/rO12kiTHKfHuqR4kr3Y4M0J0rOL6CH/BYs= +github.com/quasilyte/go-ruleguard v0.4.2/go.mod h1:GJLgqsLeo4qgavUoL8JeGFNS7qcisx3awV/w9eWTmNI= +github.com/quasilyte/go-ruleguard/dsl v0.3.22 h1:wd8zkOhSNr+I+8Qeciml08ivDt1pSXe60+5DqOpCjPE= +github.com/quasilyte/go-ruleguard/dsl v0.3.22/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU= github.com/quasilyte/gogrep v0.5.0 h1:eTKODPXbI8ffJMN+W2aE0+oL0z/nh8/5eNdiO34SOAo= github.com/quasilyte/gogrep v0.5.0/go.mod h1:Cm9lpz9NZjEoL1tgZ2OgeUKPIxL1meE7eo60Z6Sk+Ng= github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727 h1:TCg2WBOl980XxGFEZSS6KlBGIV0diGdySzxATTWoqaU= @@ -699,84 +577,84 @@ github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 h1:M8mH9eK4OUR4l github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567/go.mod h1:DWNGW8A4Y+GyBgPuaQJuWiy0XYftx4Xm/y5Jqk9I6VQ= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= -github.com/quic-go/quic-go v0.44.0 h1:So5wOr7jyO4vzL2sd8/pD9Kesciv91zSk8BoFngItQ0= -github.com/quic-go/quic-go v0.44.0/go.mod h1:z4cx/9Ny9UtGITIPzmPTXh1ULfOyWh4qGQlpnPcWmek= +github.com/quic-go/quic-go v0.45.0 h1:OHmkQGM37luZITyTSu6ff03HP/2IrwDX1ZFiNEhSFUE= +github.com/quic-go/quic-go v0.45.0/go.mod h1:1dLehS7TIR64+vxGR70GDcatWTOtMX2PUtnKsjbTurI= github.com/quic-go/webtransport-go v0.8.0 h1:HxSrwun11U+LlmwpgM1kEqIqH90IT4N8auv/cD7QFJg= github.com/quic-go/webtransport-go v0.8.0/go.mod h1:N99tjprW432Ut5ONql/aUhSLT0YVSlwHohQsuac9WaM= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= +github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= -github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= +github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= +github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/ryancurrah/gomodguard v1.3.0 h1:q15RT/pd6UggBXVBuLps8BXRvl5GPBcwVA7BJHMLuTw= -github.com/ryancurrah/gomodguard v1.3.0/go.mod h1:ggBxb3luypPEzqVtq33ee7YSN35V28XeGnid8dnni50= -github.com/ryanrolds/sqlclosecheck v0.4.0 h1:i8SX60Rppc1wRuyQjMciLqIzV3xnoHB7/tXbr6RGYNI= -github.com/ryanrolds/sqlclosecheck v0.4.0/go.mod h1:TBRRjzL31JONc9i4XMinicuo+s+E8yKZ5FN8X3G6CKQ= +github.com/ryancurrah/gomodguard v1.3.2 h1:CuG27ulzEB1Gu5Dk5gP8PFxSOZ3ptSdP5iI/3IXxM18= +github.com/ryancurrah/gomodguard v1.3.2/go.mod h1:LqdemiFomEjcxOqirbQCb3JFvSxH2JUYMerTFd3sF2o= +github.com/ryanrolds/sqlclosecheck v0.5.1 h1:dibWW826u0P8jNLsLN+En7+RqWWTYrjCB9fJfSfdyCU= +github.com/ryanrolds/sqlclosecheck v0.5.1/go.mod h1:2g3dUjoS6AL4huFdv6wn55WpLIDjY7ZgUR4J8HOO/XQ= +github.com/sagikazarmark/locafero v0.6.0 h1:ON7AQg37yzcRPU69mt7gwhFEBwxI6P9T4Qu3N51bwOk= +github.com/sagikazarmark/locafero v0.6.0/go.mod h1:77OmuIc6VTraTXKXIs/uvUxKGUXjE1GbemJYHqdNjX0= +github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= +github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= github.com/samber/lo v1.39.0 h1:4gTz1wUhNYLhFSKl6O+8peW0v2F4BCY034GRpU9WnuA= github.com/samber/lo v1.39.0/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA= github.com/sanposhiho/wastedassign/v2 v2.0.7 h1:J+6nrY4VW+gC9xFzUc+XjPD3g3wF3je/NsJFwFK7Uxc= github.com/sanposhiho/wastedassign/v2 v2.0.7/go.mod h1:KyZ0MWTwxxBmfwn33zh3k1dmsbF2ud9pAAGfoLfjhtI= +github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6NgVqpn3+iol9aGu4= +github.com/santhosh-tekuri/jsonschema/v5 v5.3.1/go.mod h1:uToXkOrWAZ6/Oc07xWQrPOhJotwFIyu2bBVN41fcDUY= github.com/sashamelentyev/interfacebloat v1.1.0 h1:xdRdJp0irL086OyW1H/RTZTr1h/tMEOsumirXcOJqAw= github.com/sashamelentyev/interfacebloat v1.1.0/go.mod h1:+Y9yU5YdTkrNvoX0xHc84dxiN1iBi9+G8zZIhPVoNjQ= -github.com/sashamelentyev/usestdlibvars v1.23.0 h1:01h+/2Kd+NblNItNeux0veSL5cBF1jbEOPrEhDzGYq0= -github.com/sashamelentyev/usestdlibvars v1.23.0/go.mod h1:YPwr/Y1LATzHI93CqoPUN/2BzGQ/6N/cl/KwgR0B/aU= -github.com/securego/gosec/v2 v2.16.0 h1:Pi0JKoasQQ3NnoRao/ww/N/XdynIB9NRYYZT5CyOs5U= -github.com/securego/gosec/v2 v2.16.0/go.mod h1:xvLcVZqUfo4aAQu56TNv7/Ltz6emAOQAEsrZrt7uGlI= +github.com/sashamelentyev/usestdlibvars v1.27.0 h1:t/3jZpSXtRPRf2xr0m63i32ZrusyurIGT9E5wAvXQnI= +github.com/sashamelentyev/usestdlibvars v1.27.0/go.mod h1:9nl0jgOfHKWNFS43Ojw0i7aRoS4j6EBye3YBhmAIRF8= +github.com/securego/gosec/v2 v2.20.1-0.20240525090044-5f0084eb01a9 h1:rnO6Zp1YMQwv8AyxzuwsVohljJgp4L0ZqiCgtACsPsc= +github.com/securego/gosec/v2 v2.20.1-0.20240525090044-5f0084eb01a9/go.mod h1:dg7lPlu/xK/Ut9SedURCoZbVCR4yC7fM65DtH9/CDHs= github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c h1:W65qqJCIOVP4jpqPQ0YvHYKwcMEMVWIzWC5iNQQfBTU= github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c/go.mod h1:/PevMnwAxekIXwN8qQyfc5gl2NlkB3CQlkizAbOkeBs= github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/sirupsen/logrus v1.0.5/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= -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.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/sivchari/containedctx v1.0.3 h1:x+etemjbsh2fB5ewm5FeLNi5bUjK0V8n0RB+Wwfd0XE= github.com/sivchari/containedctx v1.0.3/go.mod h1:c1RDvCbnJLtH4lLcYD/GqwiBSSf4F5Qk0xld2rBqzJ4= -github.com/sivchari/nosnakecase v1.7.0 h1:7QkpWIRMe8x25gckkFd2A5Pi6Ymo0qgr4JrhGt95do8= -github.com/sivchari/nosnakecase v1.7.0/go.mod h1:CwDzrzPea40/GB6uynrNLiorAlgFRvRbFSgJx2Gs+QY= -github.com/sivchari/tenv v1.7.1 h1:PSpuD4bu6fSmtWMxSGWcvqUUgIn7k3yOJhOIzVWn8Ak= -github.com/sivchari/tenv v1.7.1/go.mod h1:64yStXKSOxDfX47NlhVwND4dHwfZDdbp2Lyl018Icvg= +github.com/sivchari/tenv v1.10.0 h1:g/hzMA+dBCKqGXgW8AV/1xIWhAvDrx0zFKNR48NFMg0= +github.com/sivchari/tenv v1.10.0/go.mod h1:tdY24masnVoZFxYrHv/nD6Tc8FbkEtAQEEziXpyMgqY= github.com/smartystreets/assertions v1.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N3yZFZkDFs= github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo= github.com/smartystreets/goconvey v1.7.2 h1:9RBaZCeXEQ3UselpuwUQHltGVXvdwm6cv1hgR6gDIPg= github.com/smartystreets/goconvey v1.7.2/go.mod h1:Vw0tHAZW6lzCRk3xgdin6fKYcG+G3Pg9vgXWeJpQFMM= github.com/sonatard/noctx v0.0.2 h1:L7Dz4De2zDQhW8S0t+KUjY0MAQJd6SgVwhzNIc4ok00= github.com/sonatard/noctx v0.0.2/go.mod h1:kzFz+CzWSjQ2OzIm46uJZoXuBpa2+0y3T36U18dWqIo= +github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= +github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= github.com/sourcegraph/go-diff v0.7.0 h1:9uLlrd5T46OXs5qpp8L/MTltk0zikUGi0sNNyCpA8G0= github.com/sourcegraph/go-diff v0.7.0/go.mod h1:iBszgVvyxdc8SFZ7gm69go2KDdt3ag071iBaWPF6cjs= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spf13/afero v1.8.2 h1:xehSyVa0YnHWsJ49JFljMpg1HX19V6NDZ1fkm1Xznbo= -github.com/spf13/afero v1.8.2/go.mod h1:CtAatgMJh6bJEIs48Ay/FOnkljP3WeGUG0MC1RfAqwo= -github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= -github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= -github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= -github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= -github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= -github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= -github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= +github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= +github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= +github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= +github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= +github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/viper v1.12.0 h1:CZ7eSOd3kZoaYDLbXnmzgQI5RlciuXBMA+18HwHRfZQ= -github.com/spf13/viper v1.12.0/go.mod h1:b6COn30jlNxbm/V2IqWiNWkJ+vZNiMNksliPCiuKtSI= +github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI= +github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg= github.com/ssgreg/nlreturn/v2 v2.2.1 h1:X4XDI7jstt3ySqGU86YGAURbxw3oTDPK9sPEi6YEwQ0= github.com/ssgreg/nlreturn/v2 v2.2.1/go.mod h1:E/iiPB78hV7Szg2YfRgyIrk1AD6JVMTRkkxBiELzh2I= github.com/stbenjam/no-sprintf-host-port v0.1.1 h1:tYugd/yrm1O0dV+ThCbaKZh195Dfm07ysF0U6JQXczc= github.com/stbenjam/no-sprintf-host-port v0.1.1/go.mod h1:TLhvtIvONRzdmkFiio4O8LHsN9N74I+PhRquPsxpL0I= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= -github.com/stretchr/testify v1.1.4/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= @@ -784,11 +662,11 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/subosito/gotenv v1.4.1 h1:jyEFiXpy21Wm81FBN71l9VoMMV8H8jG+qIK3GCpY6Qs= -github.com/subosito/gotenv v1.4.1/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= +github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= +github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= github.com/t-yuki/gocover-cobertura v0.0.0-20180217150009-aaee18c8195c h1:+aPplBwWcHBo6q9xrfWdMrT9o4kltkmmvpemgIjep/8= github.com/t-yuki/gocover-cobertura v0.0.0-20180217150009-aaee18c8195c/go.mod h1:SbErYREK7xXdsRiigaQiQkI9McGRzYMvlKYaP3Nimdk= github.com/tdakkota/asciicheck v0.2.0 h1:o8jvnUANo0qXtnslk2d3nMKTFNlOnJjRrNcj0j9qkHM= @@ -797,25 +675,25 @@ github.com/tenntenn/modver v1.0.1 h1:2klLppGhDgzJrScMpkj9Ujy3rXPUspSjAcev9tSEBgA github.com/tenntenn/modver v1.0.1/go.mod h1:bePIyQPb7UeioSRkw3Q0XeMhYZSMx9B8ePqg6SAMGH0= github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3 h1:f+jULpRQGxTSkNYKJ51yaw6ChIqO+Je8UqsTKN/cDag= github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3/go.mod h1:ON8b8w4BN/kE1EOhwT0o+d62W65a6aPw1nouo9LMgyY= -github.com/tetafro/godot v1.4.11 h1:BVoBIqAf/2QdbFmSwAWnaIqDivZdOV0ZRwEm6jivLKw= -github.com/tetafro/godot v1.4.11/go.mod h1:LR3CJpxDVGlYOWn3ZZg1PgNZdTUvzsZWu8xaEohUpn8= -github.com/timakin/bodyclose v0.0.0-20230421092635-574207250966 h1:quvGphlmUVU+nhpFa4gg4yJyTRJ13reZMDHrKwYw53M= -github.com/timakin/bodyclose v0.0.0-20230421092635-574207250966/go.mod h1:27bSVNWSBOHm+qRp1T9qzaIpsWEP6TbUnei/43HK+PQ= +github.com/tetafro/godot v1.4.16 h1:4ChfhveiNLk4NveAZ9Pu2AN8QZ2nkUGFuadM9lrr5D0= +github.com/tetafro/godot v1.4.16/go.mod h1:2oVxTBSftRTh4+MVfUaUXR6bn2GDXCaMcOG4Dk3rfio= +github.com/timakin/bodyclose v0.0.0-20240125160201-f835fa56326a h1:A6uKudFIfAEpoPdaal3aSqGxBzLyU8TqyXImLwo6dIo= +github.com/timakin/bodyclose v0.0.0-20240125160201-f835fa56326a/go.mod h1:mkjARE7Yr8qU23YcGMSALbIxTQ9r9QBVahQOBRfU460= github.com/timonwong/loggercheck v0.9.4 h1:HKKhqrjcVj8sxL7K77beXh0adEm6DLjV/QOGeMXEVi4= github.com/timonwong/loggercheck v0.9.4/go.mod h1:caz4zlPcgvpEkXgVnAJGowHAMW2NwHaNlpS8xDbVhTg= -github.com/tomarrell/wrapcheck/v2 v2.8.1 h1:HxSqDSN0sAt0yJYsrcYVoEeyM4aI9yAm3KQpIXDJRhQ= -github.com/tomarrell/wrapcheck/v2 v2.8.1/go.mod h1:/n2Q3NZ4XFT50ho6Hbxg+RV1uyo2Uow/Vdm9NQcl5SE= +github.com/tomarrell/wrapcheck/v2 v2.8.3 h1:5ov+Cbhlgi7s/a42BprYoxsr73CbdMUTzE3bRDFASUs= +github.com/tomarrell/wrapcheck/v2 v2.8.3/go.mod h1:g9vNIyhb5/9TQgumxQyOEqDHsmGYcGsVMOx/xGkqdMo= github.com/tommy-muehle/go-mnd/v2 v2.5.1 h1:NowYhSdyE/1zwK9QCLeRb6USWdoif80Ie+v+yU8u1Zw= github.com/tommy-muehle/go-mnd/v2 v2.5.1/go.mod h1:WsUAkMJMYww6l/ufffCD3m+P7LEvr8TnZn9lwVDlgzw= github.com/ultraware/funlen v0.1.0 h1:BuqclbkY6pO+cvxoq7OsktIXZpgBSkYTQtmwhAK81vI= github.com/ultraware/funlen v0.1.0/go.mod h1:XJqmOQja6DpxarLj6Jj1U7JuoS8PvL4nEqDaQhy22p4= -github.com/ultraware/whitespace v0.0.5 h1:hh+/cpIcopyMYbZNVov9iSxvJU3OYQg78Sfaqzi/CzI= -github.com/ultraware/whitespace v0.0.5/go.mod h1:aVMh/gQve5Maj9hQ/hg+F75lr/X5A89uZnzAmWSineA= +github.com/ultraware/whitespace v0.1.1 h1:bTPOGejYFulW3PkcrqkeQwOd6NKOOXvmGD9bo/Gk8VQ= +github.com/ultraware/whitespace v0.1.1/go.mod h1:XcP1RLD81eV4BW8UhQlpaR+SDc2givTvyI8a586WjW8= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.10 h1:p8Fspmz3iTctJstry1PYS3HVdllxnEzTEsgIgtxTrCk= github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/uudashr/gocognit v1.0.7 h1:e9aFXgKgUJrQ5+bs61zBigmj7bFJ/5cC6HmMahVzuDo= -github.com/uudashr/gocognit v1.0.7/go.mod h1:nAIUuVBnYU7pcninia3BHOvQkpQCeO76Uscky5BOwcY= +github.com/uudashr/gocognit v1.1.2 h1:l6BAEKJqQH2UpKAPKdMfZf5kE4W/2xk8pfU1OVLvniI= +github.com/uudashr/gocognit v1.1.2/go.mod h1:aAVdLURqcanke8h3vg35BC++eseDm66Z7KmchI5et4k= github.com/warpfork/go-testmark v0.12.1 h1:rMgCpJfwy1sJ50x0M0NgyphxYYPMOODIJHhsXyEHU0s= github.com/warpfork/go-testmark v0.12.1/go.mod h1:kHwy7wfvGSPh1rQJYKayD4AbtNaeyZdcGi9tNJTaa5Y= github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0 h1:GDDkbFiaK8jsSDJfjId/PEGEShv6ugrt4kYsC5UIDaQ= @@ -824,14 +702,14 @@ github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc h1:BCPnHtcboa github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc/go.mod h1:r45hJU7yEoA81k6MWNhpMj/kms0n14dkzkxYHoB96UM= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 h1:EKhdznlJHPMoKr0XTrX+IlJs1LH3lyx2nfr1dOlZ79k= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc= -github.com/xen0n/gosmopolitan v1.2.1 h1:3pttnTuFumELBRSh+KQs1zcz4fN6Zy7aB0xlnQSn1Iw= -github.com/xen0n/gosmopolitan v1.2.1/go.mod h1:JsHq/Brs1o050OOdmzHeOr0N7OtlnKRAGAsElF8xBQA= +github.com/xen0n/gosmopolitan v1.2.2 h1:/p2KTnMzwRexIW8GlKawsTWOxn7UHA+jCMF/V8HHtvU= +github.com/xen0n/gosmopolitan v1.2.2/go.mod h1:7XX7Mj61uLYrj0qmeN0zi7XDon9JRAEhYQqAPLVNTeg= github.com/yagipy/maintidx v1.0.0 h1:h5NvIsCz+nRDapQ0exNv4aJ0yXSI0420omVANTv3GJM= github.com/yagipy/maintidx v1.0.0/go.mod h1:0qNf/I/CCZXSMhsRsrEPDZ+DkekpKLXAJfsTACwgXLk= -github.com/yeya24/promlinter v0.2.0 h1:xFKDQ82orCU5jQujdaD8stOHiv8UN68BSdn2a8u8Y3o= -github.com/yeya24/promlinter v0.2.0/go.mod h1:u54lkmBOZrpEbQQ6gox2zWKKLKu2SGe+2KOiextY+IA= -github.com/ykadowak/zerologlint v0.1.3 h1:TLy1dTW3Nuc+YE3bYRPToG1Q9Ej78b5UUN6bjbGdxPE= -github.com/ykadowak/zerologlint v0.1.3/go.mod h1:KaUskqF3e/v59oPmdq1U1DnKcuHokl2/K1U4pmIELKg= +github.com/yeya24/promlinter v0.3.0 h1:JVDbMp08lVCP7Y6NP3qHroGAO6z2yGKQtS5JsjqtoFs= +github.com/yeya24/promlinter v0.3.0/go.mod h1:cDfJQQYv9uYciW60QT0eeHlFodotkYZlL+YcPQN+mW4= +github.com/ykadowak/zerologlint v0.1.5 h1:Gy/fMz1dFQN9JZTPjv1hxEk+sRWm05row04Yoolgdiw= +github.com/ykadowak/zerologlint v0.1.5/go.mod h1:KaUskqF3e/v59oPmdq1U1DnKcuHokl2/K1U4pmIELKg= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -839,16 +717,14 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -gitlab.com/bosi/decorder v0.4.0 h1:HWuxAhSxIvsITcXeP+iIRg9d1cVfvVkmlF7M68GaoDY= -gitlab.com/bosi/decorder v0.4.0/go.mod h1:xarnteyUoJiOTEldDysquWKTVDCKo2TOIOIibSuWqOg= -go-simpler.org/assert v0.5.0 h1:+5L/lajuQtzmbtEfh69sr5cRf2/xZzyJhFjoOz/PPqs= -go-simpler.org/assert v0.5.0/go.mod h1:74Eqh5eI6vCK6Y5l3PI8ZYFXG4Sa+tkr70OIPJAUr28= -go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= -go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +gitlab.com/bosi/decorder v0.4.2 h1:qbQaV3zgwnBZ4zPMhGLW4KZe7A7NwxEhJx39R3shffo= +gitlab.com/bosi/decorder v0.4.2/go.mod h1:muuhHoaJkA9QLcYHq4Mj8FJUwDZ+EirSHRiaTcTf6T8= +go-simpler.org/assert v0.9.0 h1:PfpmcSvL7yAnWyChSjOz6Sp6m9j5lyK8Ok9pEL31YkQ= +go-simpler.org/assert v0.9.0/go.mod h1:74Eqh5eI6vCK6Y5l3PI8ZYFXG4Sa+tkr70OIPJAUr28= +go-simpler.org/musttag v0.12.2 h1:J7lRc2ysXOq7eM8rwaTYnNrHd5JwjppzB6mScysB2Cs= +go-simpler.org/musttag v0.12.2/go.mod h1:uN1DVIasMTQKk6XSik7yrJoEysGtR2GRqvWnI9S7TYM= +go-simpler.org/sloglint v0.7.1 h1:qlGLiqHbN5islOxjeLXoPtUdZXb669RW+BDQ+xOSNoU= +go-simpler.org/sloglint v0.7.1/go.mod h1:OlaVDRh/FKKd4X4sIMbsz8st97vomydceL146Fthh/c= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/otel v1.27.0 h1:9BZoF3yMK/O1AafMiQTVu0YDj5Ea4hPhxCs7sGva+cg= @@ -857,14 +733,14 @@ go.opentelemetry.io/otel/metric v1.27.0 h1:hvj3vdEKyeCi4YaYfNjv2NUje8FqKqUY8IlF0 go.opentelemetry.io/otel/metric v1.27.0/go.mod h1:mVFgmRlhljgBiuk/MP/oKylr4hs85GZAylncepAX/ak= go.opentelemetry.io/otel/trace v1.27.0 h1:IqYb813p7cmbHk0a5y6pD5JPakbVfftRXABGt5/Rscw= go.opentelemetry.io/otel/trace v1.27.0/go.mod h1:6RiD1hkAprV4/q+yd2ln1HG9GoPx39SuvvstaLBl+l4= -go.tmz.dev/musttag v0.7.1 h1:9lFmeSFnFfPuMq4IksHGomItE6NgKMNW2Nt2FPOhCfU= -go.tmz.dev/musttag v0.7.1/go.mod h1:oJLkpR56EsIryktZJk/B0IroSMi37YWver47fibGh5U= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/automaxprocs v1.5.3 h1:kWazyxZUrS3Gs4qUpbwo5kEIMGe/DAvi5Z4tl2NW4j8= +go.uber.org/automaxprocs v1.5.3/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0= go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= -go.uber.org/fx v1.21.1 h1:RqBh3cYdzZS0uqwVeEjOX2p73dddLpym315myy/Bpb0= -go.uber.org/fx v1.21.1/go.mod h1:HT2M7d7RHo+ebKGh9NRcrsrHHfpZ60nW3QRubMRfv48= +go.uber.org/fx v1.22.0 h1:pApUK7yL0OUHMd8vkunWSlLxZVFFk70jR2nKde8X2NM= +go.uber.org/fx v1.22.0/go.mod h1:HT2M7d7RHo+ebKGh9NRcrsrHHfpZ60nW3QRubMRfv48= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= @@ -879,57 +755,36 @@ go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= +golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= +golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= +golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= +golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= -golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= -golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8 h1:LoYXNGAShUG3m/ehNk4iFctuhGX/+R1ZpfJ4/ia80JM= -golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI= +golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 h1:yixxcjnhBmY0nkL253HFVIm0JsFHwrHdT3Yh6szTnfY= +golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI= golang.org/x/exp/typeparams v0.0.0-20220428152302-39d4317da171/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/exp/typeparams v0.0.0-20230203172020-98cc5a0785f9/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= -golang.org/x/exp/typeparams v0.0.0-20230307190834-24139beb5833 h1:jWGQJV4niP+CCmFW9ekjA9Zx8vYORzOUH2/Nl5WPuLQ= -golang.org/x/exp/typeparams v0.0.0-20230307190834-24139beb5833/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= -golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/exp/typeparams v0.0.0-20240613232115-7f521ea00fb8 h1:+ZJmEdDFzH5H0CnzOrwgbH3elHctfTecW9X0k2tkn5M= +golang.org/x/exp/typeparams v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= -golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= -golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= -golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= @@ -938,227 +793,138 @@ golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91 golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.16.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0= golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= +golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= +golang.org/x/net v0.16.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= 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= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/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= -golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211105183446-c75c47738b0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220702020025-31831981b65f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= +golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= +golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= +golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= +golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA= golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= -golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= -golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190321232350-e250d351ecad/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190910044552-dd2b5c81c578/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= golang.org/x/tools v0.0.0-20200324003944-a576cf524670/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= golang.org/x/tools v0.0.0-20200329025819-fd4102a86c65/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= -golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= -golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200724022722-7017fd6b1305/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200820010801-b793a1359eac/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= -golang.org/x/tools v0.0.0-20201001104356-43ebab892c4c/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= golang.org/x/tools v0.0.0-20201023174141-c8cfbd0f21e6/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.1-0.20210205202024-ef80cdb6ec6d/go.mod h1:9bzcO0MWcOuT0tm1iBGzDVPshzfwoVvREIui8C+MHqU= golang.org/x/tools v0.1.1-0.20210302220138-2ac05c832e1a/go.mod h1:9bzcO0MWcOuT0tm1iBGzDVPshzfwoVvREIui8C+MHqU= @@ -1172,6 +938,10 @@ golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= golang.org/x/tools v0.5.0/go.mod h1:N+Kgy78s5I24c24dU8OfWNEotWjutIs8SnJvn5IDq+k= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.11.0/go.mod h1:anzJrxPjNtfgiYQYirP2CPGzGLxrH2u2QBhn6Bf3qY8= +golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= +golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= +golang.org/x/tools v0.19.0/go.mod h1:qoJWxmGSIBmAeriMx19ogtrEPrGtDbPK634QFIcLAhc= golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA= golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1180,84 +950,16 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gonum.org/v1/gonum v0.15.0 h1:2lYxjRbTYyxkJxlhC+LvJIx3SsANPdRybu1tGj9/OrQ= gonum.org/v1/gonum v0.15.0/go.mod h1:xzZVBJBtS+Mz4q0Yl2LJTk+OxOg4jiXZ7qBoM0uISGo= -google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= -google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= -google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= -google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= -google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= -google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= -google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= -google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= -google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= -google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= -google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -1266,60 +968,36 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= -google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= -gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= -gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools/gotestsum v0.4.2 h1:QOdtb6bnnPUuHKkR9+/QQa8e6qjpTTP7cDi7G9/10C4= -gotest.tools/gotestsum v0.4.2/go.mod h1:a32lmn/7xfm0+QHj8K5NyQY1NNNNhZoAp+/OHkLs77Y= -gotest.tools/v3 v3.0.2 h1:kG1BFyqVHuQoVQiR1bWGnfz/fmHvvuiSPIV7rvl360E= -gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= +gotest.tools/gotestsum v1.12.0 h1:CmwtaGDkHxrZm4Ib0Vob89MTfpc3GrEFMJKovliPwGk= +gotest.tools/gotestsum v1.12.0/go.mod h1:fAvqkSptospfSbQw26CTYzNwnsE/ztqLeyhP0h67ARY= +gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU= +gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.4.3 h1:o/n5/K5gXqk8Gozvs2cnL0F2S1/g1vcGCAx2vETjITw= -honnef.co/go/tools v0.4.3/go.mod h1:36ZgoUOrqOk1GxwHhyryEkq8FQWkUO2xGuSMhUCcdvA= +honnef.co/go/tools v0.4.7 h1:9MDAWxMoSnB6QoSqiVr7P5mtkT9pOc1kSxchzPCnqJs= +honnef.co/go/tools v0.4.7/go.mod h1:+rnGS1THNh8zMwnd2oVOTL9QF6vmfyG6ZXBULae2uc0= lukechampine.com/blake3 v1.3.0 h1:sJ3XhFINmHSrYCgl958hscfIa3bw8x4DqMP3u1YvoYE= lukechampine.com/blake3 v1.3.0/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= -mvdan.cc/gofumpt v0.5.0 h1:0EQ+Z56k8tXjj/6TQD25BFNKQXpCvT0rnansIc7Ug5E= -mvdan.cc/gofumpt v0.5.0/go.mod h1:HBeVDtMKRZpXyxFciAirzdKklDlGu8aAy1wEbH5Y9js= -mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed h1:WX1yoOaKQfddO/mLzdV4wptyWgoH/6hwLs7QHTixo0I= -mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc= -mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b h1:DxJ5nJdkhDlLok9K6qO+5290kphDJbHOQO1DFFFTeBo= -mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4= -mvdan.cc/unparam v0.0.0-20221223090309-7455f1af531d h1:3rvTIIM22r9pvXk+q3swxUQAQOxksVMGK7sml4nG57w= -mvdan.cc/unparam v0.0.0-20221223090309-7455f1af531d/go.mod h1:IeHQjmn6TOD+e4Z3RFiZMMsLVL+A96Nvptar8Fj71is= -rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= -rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= -rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +mvdan.cc/gofumpt v0.6.0 h1:G3QvahNDmpD+Aek/bNOLrFR2XC6ZAdo62dZu65gmwGo= +mvdan.cc/gofumpt v0.6.0/go.mod h1:4L0wf+kgIPZtcCWXynNS2e6bhmj73umwnuXSZarixzA= +mvdan.cc/unparam v0.0.0-20240528143540-8a5130ca722f h1:lMpcwN6GxNbWtbpI1+xzFLSW8XzX0u72NttUGVFjO3U= +mvdan.cc/unparam v0.0.0-20240528143540-8a5130ca722f/go.mod h1:RSLa7mKKCNeTTMHBw5Hsy2rfJmd6O2ivt9Dw9ZqCQpQ= From de87573c2e01748ad6dac2ca4a5147a11f986e09 Mon Sep 17 00:00:00 2001 From: Gabe Date: Fri, 21 Jun 2024 08:54:11 -0600 Subject: [PATCH 1110/1212] docs: update ipfs-swarm-key-gen example (#10453) --- docs/experimental-features.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/experimental-features.md b/docs/experimental-features.md index 09640274e..9798c746b 100644 --- a/docs/experimental-features.md +++ b/docs/experimental-features.md @@ -126,7 +126,7 @@ Stable but not quite ready for prime-time. Generate a pre-shared-key using [ipfs-swarm-key-gen](https://github.com/Kubuxu/go-ipfs-swarm-key-gen)): ``` -go get github.com/Kubuxu/go-ipfs-swarm-key-gen/ipfs-swarm-key-gen +go install github.com/Kubuxu/go-ipfs-swarm-key-gen/ipfs-swarm-key-gen@latest ipfs-swarm-key-gen > ~/.ipfs/swarm.key ``` From 11bfb3c93b9a69031cb536b07916d562e680d5e8 Mon Sep 17 00:00:00 2001 From: swedneck <40505480+swedneck@users.noreply.github.com> Date: Fri, 21 Jun 2024 16:56:58 +0200 Subject: [PATCH 1111/1212] docs: "error mounting: could not resolve name" (#10449) based on https://github.com/ipfs/kubo/issues/2383#issuecomment-187867923 and https://github.com/ipfs/kubo/issues/2383#issuecomment-1436069101 --- docs/fuse.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/fuse.md b/docs/fuse.md index 2b64a7856..7744a0d45 100644 --- a/docs/fuse.md +++ b/docs/fuse.md @@ -147,5 +147,15 @@ sudo umount /ipfs sudo umount /ipns ``` +#### Mounting fails with "error mounting: could not resolve name" + +Make sure your node's IPNS address has a directory published: +``` +$ mkdir hello/; echo 'hello' > hello/hello.txt; ipfs add -rQ ./hello/ +QmU5PLEGqjetW4RAmXgHpEFL7nVCL3vFnEyrCKUfRk4MSq + +$ ipfs name publish QmU5PLEGqjetW4RAmXgHpEFL7nVCL3vFnEyrCKUfRk4MSq +``` + If you manage to mount on other systems (or followed an alternative path to one above), please contribute to these docs :D From ddfd776a99eb585538fcf5de152a9636c1ccb5bd Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Mon, 24 Jun 2024 22:19:20 +0200 Subject: [PATCH 1112/1212] docs: clarify pnet limitations --- docs/experimental-features.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/docs/experimental-features.md b/docs/experimental-features.md index 9798c746b..eb4f2ff14 100644 --- a/docs/experimental-features.md +++ b/docs/experimental-features.md @@ -118,6 +118,9 @@ It allows ipfs to only connect to other peers who have a shared secret key. Stable but not quite ready for prime-time. +> [!WARNING] +> Limited to TCP transport, comes with overhead of double-encryption. See details below. + ### In Version 0.4.7 @@ -164,7 +167,12 @@ configured, the daemon will fail to start. - [x] Needs more people to use and report on how well it works - [ ] More documentation -- [ ] Needs better tooling/UX. +- [ ] Improve / future proof libp2p support (see [libp2p/specs#489](https://github.com/libp2p/specs/issues/489)) + - [ ] Currently limited to TCP-only, and double-encrypts all data sent on TCP. This is slow. + - [ ] Does not work with QUIC: [go-libp2p#1432](https://github.com/libp2p/go-libp2p/issues/1432) +- [ ] Needs better tooling/UX + - [ ] Detect lack of peers when swarm key is present and prompt user to set up bootstrappers/peering + - [ ] ipfs-webui will not load unless blocks are present in private swarm. Detect it and prompt user to import CAR with webui. ## ipfs p2p From 225dbe6c0340527071a162913e4b64a64df9be32 Mon Sep 17 00:00:00 2001 From: Patryk Date: Wed, 24 Jul 2024 23:42:19 +0200 Subject: [PATCH 1113/1212] feat: periodic version check and json config (#10438) Co-authored-by: Lucas Molas Co-authored-by: Marcin Rataj --- cmd/ipfs/kubo/daemon.go | 57 ++++++++++- config/config.go | 1 + config/version.go | 14 +++ core/commands/commands_test.go | 1 + core/commands/version.go | 181 +++++++++++++++++++++++++++++++-- docs/changelogs/v0.30.md | 17 ++++ docs/config.md | 40 ++++++++ go.mod | 1 + go.sum | 2 + test/sharness/t0026-id.sh | 11 ++ 10 files changed, 315 insertions(+), 10 deletions(-) create mode 100644 config/version.go diff --git a/cmd/ipfs/kubo/daemon.go b/cmd/ipfs/kubo/daemon.go index 1d6ff5035..5dec799dd 100644 --- a/cmd/ipfs/kubo/daemon.go +++ b/cmd/ipfs/kubo/daemon.go @@ -1,9 +1,11 @@ package kubo import ( + "context" "errors" _ "expvar" "fmt" + "math" "net" "net/http" _ "net/http/pprof" @@ -438,9 +440,11 @@ func daemonFunc(req *cmds.Request, re cmds.ResponseEmitter, env cmds.Environment return fmt.Errorf("unrecognized routing option: %s", routingOption) } - agentVersionSuffixString, _ := req.Options[agentVersionSuffix].(string) - if agentVersionSuffixString != "" { - version.SetUserAgentSuffix(agentVersionSuffixString) + // Set optional agent version suffix + versionSuffixFromCli, _ := req.Options[agentVersionSuffix].(string) + versionSuffix := cfg.Version.AgentSuffix.WithDefault(versionSuffixFromCli) + if versionSuffix != "" { + version.SetUserAgentSuffix(versionSuffix) } node, err := core.NewNode(req.Context, ncfg) @@ -610,6 +614,15 @@ take effect. } if len(peers) == 0 { log.Error("failed to bootstrap (no peers found): consider updating Bootstrap or Peering section of your config") + } else { + // After 1 minute we should have enough peers + // to run informed version check + startVersionChecker( + cctx.Context(), + node, + cfg.Version.SwarmCheckEnabled.WithDefault(true), + cfg.Version.SwarmCheckPercentThreshold.WithDefault(config.DefaultSwarmCheckPercentThreshold), + ) } }) } @@ -1056,3 +1069,41 @@ func printVersion() { fmt.Printf("System version: %s\n", runtime.GOARCH+"/"+runtime.GOOS) fmt.Printf("Golang version: %s\n", runtime.Version()) } + +func startVersionChecker(ctx context.Context, nd *core.IpfsNode, enabled bool, percentThreshold int64) { + if !enabled { + return + } + ticker := time.NewTicker(time.Hour) + defer ticker.Stop() + go func() { + for { + o, err := commands.DetectNewKuboVersion(nd, percentThreshold) + if err != nil { + // The version check is best-effort, and may fail in custom + // configurations that do not run standard WAN DHT. If it + // errors here, no point in spamming logs: og once and exit. + log.Errorw("initial version check failed, will not be run again", "error", err) + return + } + if o.UpdateAvailable { + newerPercent := fmt.Sprintf("%.0f%%", math.Round(float64(o.WithGreaterVersion)/float64(o.PeersSampled)*100)) + log.Errorf(` +⚠️ A NEW VERSION OF KUBO DETECTED + +This Kubo node is running an outdated version (%s). +%s of the sampled Kubo peers are running a higher version. +Visit https://github.com/ipfs/kubo/releases or https://dist.ipfs.tech/#kubo and update to version %s or later.`, + o.RunningVersion, newerPercent, o.GreatestVersion) + } + select { + case <-ctx.Done(): + return + case <-nd.Process.Closing(): + return + case <-ticker.C: + continue + } + } + }() +} diff --git a/config/config.go b/config/config.go index 046c930be..71365eb0b 100644 --- a/config/config.go +++ b/config/config.go @@ -37,6 +37,7 @@ type Config struct { Plugins Plugins Pinning Pinning Import Import + Version Version Internal Internal // experimental/unstable options } diff --git a/config/version.go b/config/version.go new file mode 100644 index 000000000..8096107bb --- /dev/null +++ b/config/version.go @@ -0,0 +1,14 @@ +package config + +const DefaultSwarmCheckPercentThreshold = 5 + +// Version allows controling things like custom user agent and update checks. +type Version struct { + // Optional suffix to the AgentVersion presented by `ipfs id` and exposed + // via libp2p identify protocol. + AgentSuffix *OptionalString `json:",omitempty"` + + // Detect when to warn about new version when observed via libp2p identify + SwarmCheckEnabled Flag `json:",omitempty"` + SwarmCheckPercentThreshold *OptionalInteger `json:",omitempty"` +} diff --git a/core/commands/commands_test.go b/core/commands/commands_test.go index 38172fd66..018b6734e 100644 --- a/core/commands/commands_test.go +++ b/core/commands/commands_test.go @@ -199,6 +199,7 @@ func TestCommands(t *testing.T) { "/swarm/resources", "/update", "/version", + "/version/check", "/version/deps", } diff --git a/core/commands/version.go b/core/commands/version.go index e404074fe..221726881 100644 --- a/core/commands/version.go +++ b/core/commands/version.go @@ -5,17 +5,25 @@ import ( "fmt" "io" "runtime/debug" + "strings" - version "github.com/ipfs/kubo" - + versioncmp "github.com/hashicorp/go-version" cmds "github.com/ipfs/go-ipfs-cmds" + version "github.com/ipfs/kubo" + "github.com/ipfs/kubo/config" + "github.com/ipfs/kubo/core" + "github.com/ipfs/kubo/core/commands/cmdenv" + "github.com/libp2p/go-libp2p-kad-dht/fullrt" + peer "github.com/libp2p/go-libp2p/core/peer" + pstore "github.com/libp2p/go-libp2p/core/peerstore" ) const ( - versionNumberOptionName = "number" - versionCommitOptionName = "commit" - versionRepoOptionName = "repo" - versionAllOptionName = "all" + versionNumberOptionName = "number" + versionCommitOptionName = "commit" + versionRepoOptionName = "repo" + versionAllOptionName = "all" + versionCheckThresholdOptionName = "min-percent" ) var VersionCmd = &cmds.Command{ @@ -24,7 +32,8 @@ var VersionCmd = &cmds.Command{ ShortDescription: "Returns the current version of IPFS and exits.", }, Subcommands: map[string]*cmds.Command{ - "deps": depsVersionCommand, + "deps": depsVersionCommand, + "check": checkVersionCommand, }, Options: []cmds.Option{ @@ -130,3 +139,161 @@ Print out all dependencies and their versions.`, }), }, } + +const DefaultMinimalVersionFraction = 0.05 // 5% + +type VersionCheckOutput struct { + UpdateAvailable bool + RunningVersion string + GreatestVersion string + PeersSampled int + WithGreaterVersion int +} + +var checkVersionCommand = &cmds.Command{ + Helptext: cmds.HelpText{ + Tagline: "Checks Kubo version against connected peers.", + ShortDescription: ` +This command uses the libp2p identify protocol to check the 'AgentVersion' +of connected peers and see if the Kubo version we're running is outdated. + +Peers with an AgentVersion that doesn't start with 'kubo/' are ignored. +'UpdateAvailable' is set to true only if the 'min-fraction' criteria are met. + +The 'ipfs daemon' does the same check regularly and logs when a new version +is available. You can stop these regular checks by setting +Version.SwarmCheckEnabled:false in the config. +`, + }, + Options: []cmds.Option{ + cmds.IntOption(versionCheckThresholdOptionName, "t", "Percentage (1-100) of sampled peers with the new Kubo version needed to trigger an update warning.").WithDefault(config.DefaultSwarmCheckPercentThreshold), + }, + Type: VersionCheckOutput{}, + + Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { + nd, err := cmdenv.GetNode(env) + if err != nil { + return err + } + + if !nd.IsOnline { + return ErrNotOnline + } + + minPercent, _ := req.Options[versionCheckThresholdOptionName].(int64) + output, err := DetectNewKuboVersion(nd, minPercent) + if err != nil { + return err + } + + if err := cmds.EmitOnce(res, output); err != nil { + return err + } + return nil + }, +} + +// DetectNewKuboVersion observers kubo version reported by other peers via +// libp2p identify protocol and notifies when threshold fraction of seen swarm +// is running updated Kubo. It is used by RPC and CLI at 'ipfs version check' +// and also periodically when 'ipfs daemon' is running. +func DetectNewKuboVersion(nd *core.IpfsNode, minPercent int64) (VersionCheckOutput, error) { + ourVersion, err := versioncmp.NewVersion(version.CurrentVersionNumber) + if err != nil { + return VersionCheckOutput{}, fmt.Errorf("could not parse our own version %q: %w", + version.CurrentVersionNumber, err) + } + // MAJOR.MINOR.PATCH without any suffix + ourVersion = ourVersion.Core() + + greatestVersionSeen := ourVersion + totalPeersSampled := 1 // Us (and to avoid division-by-zero edge case) + withGreaterVersion := 0 + + recordPeerVersion := func(agentVersion string) { + // We process the version as is it assembled in GetUserAgentVersion + segments := strings.Split(agentVersion, "/") + if len(segments) < 2 { + return + } + if segments[0] != "kubo" { + return + } + versionNumber := segments[1] // As in our CurrentVersionNumber + + peerVersion, err := versioncmp.NewVersion(versionNumber) + if err != nil { + // Do not error on invalid remote versions, just ignore + return + } + + // Ignore prerelases and development releases (-dev, -rcX) + if peerVersion.Metadata() != "" || peerVersion.Prerelease() != "" { + return + } + + // MAJOR.MINOR.PATCH without any suffix + peerVersion = peerVersion.Core() + + // Valid peer version number + totalPeersSampled += 1 + if ourVersion.LessThan(peerVersion) { + withGreaterVersion += 1 + } + if peerVersion.GreaterThan(greatestVersionSeen) { + greatestVersionSeen = peerVersion + } + } + + processPeerstoreEntry := func(id peer.ID) { + if v, err := nd.Peerstore.Get(id, "AgentVersion"); err == nil { + recordPeerVersion(v.(string)) + } else if errors.Is(err, pstore.ErrNotFound) { // ignore noop + } else { // a bug, usually. + log.Errorw("failed to get agent version from peerstore", "error", err) + } + } + + // Amino DHT client keeps information about previously seen peers + if nd.DHTClient != nd.DHT && nd.DHTClient != nil { + client, ok := nd.DHTClient.(*fullrt.FullRT) + if !ok { + return VersionCheckOutput{}, errors.New("could not perform version check due to missing or incompatible DHT configuration") + } + for _, p := range client.Stat() { + processPeerstoreEntry(p) + } + } else if nd.DHT != nil && nd.DHT.WAN != nil { + for _, pi := range nd.DHT.WAN.RoutingTable().GetPeerInfos() { + processPeerstoreEntry(pi.Id) + } + } else if nd.DHT != nil && nd.DHT.LAN != nil { + for _, pi := range nd.DHT.LAN.RoutingTable().GetPeerInfos() { + processPeerstoreEntry(pi.Id) + } + } else { + return VersionCheckOutput{}, errors.New("could not perform version check due to missing or incompatible DHT configuration") + } + + if minPercent < 1 || minPercent > 100 { + if minPercent == 0 { + minPercent = config.DefaultSwarmCheckPercentThreshold + } else { + return VersionCheckOutput{}, errors.New("Version.SwarmCheckPercentThreshold must be between 1 and 100") + } + } + + minFraction := float64(minPercent) / 100.0 + + // UpdateAvailable flag is set only if minFraction was reached + greaterFraction := float64(withGreaterVersion) / float64(totalPeersSampled) + + // Gathered metric are returned every time + return VersionCheckOutput{ + UpdateAvailable: (greaterFraction >= minFraction), + RunningVersion: ourVersion.String(), + GreatestVersion: greatestVersionSeen.String(), + PeersSampled: totalPeersSampled, + WithGreaterVersion: withGreaterVersion, + }, nil +} diff --git a/docs/changelogs/v0.30.md b/docs/changelogs/v0.30.md index e561566d9..8457662bf 100644 --- a/docs/changelogs/v0.30.md +++ b/docs/changelogs/v0.30.md @@ -6,6 +6,8 @@ - [Overview](#overview) - [🔦 Highlights](#-highlights) + - [Automated `ipfs version check`](#automated-ipfs-version-check) + - [Version Suffix Configuration](#version-suffix-configuration) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -13,6 +15,21 @@ ### 🔦 Highlights +#### Automated `ipfs version check` + +Kubo now performs privacy-preserving version checks using the [libp2p identify protocol](https://github.com/libp2p/specs/blob/master/identify/README.md) on peers detected by the Amino DHT client. +If more than 5% of Kubo peers seen by your node are running a newer version, you will receive a log message notification. + +- For manual checks, refer to `ipfs version check --help` for details. +- To disable automated checks, set [`Version.SwarmCheckEnabled`](https://github.com/ipfs/kubo/blob/master/docs/config.md#versionswarmcheckenabled) to `false`. + +#### Version Suffix Configuration + +Defining the optional agent version suffix is now simpler. The [`Version.AgentSuffix`](https://github.com/ipfs/kubo/blob/master/docs/config.md#agentsuffix) value from the Kubo config takes precedence over any value provided via `ipfs daemon --agent-version-suffix` (which is still supported). + +> [!NOTE] +> Setting a custom version suffix helps with ecosystem analysis, such as Amino DHT reports published at https://stats.ipfs.network + ### 📝 Changelog ### 👨‍👩‍👧‍👦 Contributors diff --git a/docs/config.md b/docs/config.md index 130f724d5..c7355072d 100644 --- a/docs/config.md +++ b/docs/config.md @@ -180,6 +180,10 @@ config file at runtime. - [`Import.UnixFSRawLeaves`](#importunixfsrawleaves) - [`Import.UnixFSChunker`](#importunixfschunker) - [`Import.HashFunction`](#importhashfunction) + - [`Version`](#version) + - [`Version.AgentSuffix`](#versionagentsuffix) + - [`Version.SwarmCheckEnabled`](#versionswarmcheckenabled) + - [`Version.SwarmCheckPercentThreshold`](#versionswarmcheckpercentthreshold) ## Profiles @@ -2435,3 +2439,39 @@ The default hash function. Commands affected: `ipfs add`, `ipfs block put`, `ipf Default: `sha2-256` Type: `optionalString` + +## `Version` + +Options to configure agent version announced to the swarm, and leveraging +other peers version for detecting when there is time to update. + +### `Version.AgentSuffix` + +Optional suffix to the AgentVersion presented by `ipfs id` and exposed via [libp2p identify protocol](https://github.com/libp2p/specs/blob/master/identify/README.md#agentversion). + +The value from config takes precedence over value passed via `ipfs daemon --agent-version-suffix`. + +> [!NOTE] +> Setting a custom version suffix helps with ecosystem analysis, such as Amino DHT reports published at https://stats.ipfs.network + +Default: `""` (no suffix, or value from `ipfs daemon --agent-version-suffix=`) + +Type: `optionalString` + +### `Version.SwarmCheckEnabled` + +Observe the AgentVersion of swarm peers and log warning when +`SwarmCheckPercentThreshold` of peers runs version higher than this node. + +Default: `true` + +Type: `flag` + +### `Version.SwarmCheckPercentThreshold` + +Control the percentage of `kubo/` peers running new version required to +trigger update warning. + +Default: `5` + +Type: `optionalInteger` (1-100) diff --git a/go.mod b/go.mod index 866a1ecc6..b466bc1f9 100644 --- a/go.mod +++ b/go.mod @@ -15,6 +15,7 @@ require ( github.com/fsnotify/fsnotify v1.6.0 github.com/google/uuid v1.6.0 github.com/hashicorp/go-multierror v1.1.1 + github.com/hashicorp/go-version v1.6.0 github.com/ipfs-shipyard/nopfs v0.0.12 github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c github.com/ipfs/boxo v0.21.0 diff --git a/go.sum b/go.sum index 52e889275..a42aaa22c 100644 --- a/go.sum +++ b/go.sum @@ -310,6 +310,8 @@ github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= +github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= +github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c= diff --git a/test/sharness/t0026-id.sh b/test/sharness/t0026-id.sh index d4248c562..992892a39 100755 --- a/test/sharness/t0026-id.sh +++ b/test/sharness/t0026-id.sh @@ -65,5 +65,16 @@ iptb stop test_kill_ipfs_daemon +# Version.AgentSuffix overrides --agent-version-suffix (local, offline) +test_expect_success "setting Version.AgentSuffix in config" ' + ipfs config Version.AgentSuffix json-config-suffix +' +test_launch_ipfs_daemon --agent-version-suffix=ignored-cli-suffix +test_expect_success "checking AgentVersion with suffix set via JSON config" ' + test_id_compute_agent json-config-suffix > expected-agent-version && + ipfs id -f "\n" > actual-agent-version && + test_cmp expected-agent-version actual-agent-version +' +test_kill_ipfs_daemon test_done From 749a61bae21e4229ae5170a0713cc19a4124c4b9 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Tue, 30 Jul 2024 16:42:18 +0200 Subject: [PATCH 1114/1212] chore: update dependencies (#10462)(#10466) * chore: go get -u * fix(gateway): return 404 in no-fetch contexts (#10466) applies and tests fix from https://github.com/ipfs/boxo/pull/630 --- docs/examples/kubo-as-a-library/go.mod | 37 +++++------ docs/examples/kubo-as-a-library/go.sum | 74 ++++++++++----------- go.mod | 39 ++++++------ go.sum | 78 ++++++++++++----------- test/cli/gateway_test.go | 10 +-- test/cli/http_gateway_over_libp2p_test.go | 2 +- test/dependencies/go.mod | 33 +++++----- test/dependencies/go.sum | 70 ++++++++++---------- 8 files changed, 176 insertions(+), 167 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index a8fc209d2..bdeee3bf8 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -9,17 +9,17 @@ toolchain go1.22.0 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.21.0 + github.com/ipfs/boxo v0.21.1-0.20240730141506-8e51658f8a1b github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 - github.com/libp2p/go-libp2p v0.35.1 - github.com/multiformats/go-multiaddr v0.12.4 + github.com/libp2p/go-libp2p v0.35.4 + github.com/multiformats/go-multiaddr v0.13.0 ) require ( bazil.org/fuse v0.0.0-20200117225306-7b5117fecadc // indirect github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 // indirect github.com/Jorropo/jsync v1.0.1 // indirect - github.com/alecthomas/units v0.0.0-20231202071711-9a357b53e9c9 // indirect + github.com/alecthomas/units v0.0.0-20240626203959-61d1e3462e30 // indirect github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5 // indirect github.com/benbjohnson/clock v1.3.5 // indirect github.com/beorn7/perks v1.0.1 // indirect @@ -115,7 +115,7 @@ require ( github.com/libp2p/go-libp2p-pubsub v0.11.0 // indirect github.com/libp2p/go-libp2p-pubsub-router v0.6.0 // indirect github.com/libp2p/go-libp2p-record v0.2.0 // indirect - github.com/libp2p/go-libp2p-routing-helpers v0.7.3 // indirect + github.com/libp2p/go-libp2p-routing-helpers v0.7.4 // indirect github.com/libp2p/go-libp2p-xor v0.1.0 // indirect github.com/libp2p/go-msgio v0.3.0 // indirect github.com/libp2p/go-nat v0.2.0 // indirect @@ -140,6 +140,7 @@ require ( github.com/multiformats/go-multihash v0.2.3 // indirect github.com/multiformats/go-multistream v0.5.0 // indirect github.com/multiformats/go-varint v0.0.7 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/onsi/ginkgo/v2 v2.19.0 // indirect github.com/opencontainers/runtime-spec v1.2.0 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect @@ -167,13 +168,13 @@ require ( github.com/polydawn/refmt v0.89.0 // indirect github.com/prometheus/client_golang v1.19.1 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.54.0 // indirect + github.com/prometheus/common v0.55.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/quic-go/qpack v0.4.0 // indirect github.com/quic-go/quic-go v0.45.0 // indirect github.com/quic-go/webtransport-go v0.8.0 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect - github.com/samber/lo v1.39.0 // indirect + github.com/samber/lo v1.46.0 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/stretchr/testify v1.9.0 // indirect github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect @@ -186,32 +187,32 @@ require ( github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.52.0 // indirect - go.opentelemetry.io/otel v1.27.0 // indirect + go.opentelemetry.io/otel v1.28.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.0 // indirect go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.27.0 // indirect go.opentelemetry.io/otel/exporters/zipkin v1.27.0 // indirect - go.opentelemetry.io/otel/metric v1.27.0 // indirect + go.opentelemetry.io/otel/metric v1.28.0 // indirect go.opentelemetry.io/otel/sdk v1.27.0 // indirect - go.opentelemetry.io/otel/trace v1.27.0 // indirect + go.opentelemetry.io/otel/trace v1.28.0 // indirect go.opentelemetry.io/proto/otlp v1.3.1 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/dig v1.17.1 // indirect - go.uber.org/fx v1.22.0 // indirect + go.uber.org/fx v1.22.1 // indirect go.uber.org/mock v0.4.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect go4.org v0.0.0-20230225012048-214862532bf5 // indirect - golang.org/x/crypto v0.24.0 // indirect - golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 // indirect - golang.org/x/mod v0.18.0 // indirect - golang.org/x/net v0.26.0 // indirect + golang.org/x/crypto v0.25.0 // indirect + golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect + golang.org/x/mod v0.19.0 // indirect + golang.org/x/net v0.27.0 // indirect golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.21.0 // indirect + golang.org/x/sys v0.22.0 // indirect golang.org/x/text v0.16.0 // indirect - golang.org/x/tools v0.22.0 // indirect - golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect + golang.org/x/tools v0.23.0 // indirect + golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9 // indirect gonum.org/v1/gonum v0.15.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240617180043-68d350f18fd4 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240617180043-68d350f18fd4 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 7ab48b7f6..c2813c4dc 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -33,8 +33,8 @@ github.com/Jorropo/jsync v1.0.1 h1:6HgRolFZnsdfzRUj+ImB9og1JYOxQoReSywkHOGSaUU= github.com/Jorropo/jsync v1.0.1/go.mod h1:jCOZj3vrBCri3bSU3ErUYvevKlnbssrXeCivybS5ABQ= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= -github.com/alecthomas/units v0.0.0-20231202071711-9a357b53e9c9 h1:ez/4by2iGztzR4L0zgAOR8lTQK9VlyBVVd7G4omaOQs= -github.com/alecthomas/units v0.0.0-20231202071711-9a357b53e9c9/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= +github.com/alecthomas/units v0.0.0-20240626203959-61d1e3462e30 h1:t3eaIm0rUkzbrIewtiFmMK5RXHej2XnoXNhxVsAYUfg= +github.com/alecthomas/units v0.0.0-20240626203959-61d1e3462e30/go.mod h1:fvzegU4vN3H1qMT+8wDmzjAcDONcgo2/SZ/TyfdUOFs= github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5 h1:iW0a5ljuFxkLGPNem5Ui+KBjFJzKg4Fv2fnxe4dvzpM= github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5/go.mod h1:Y2QMoi1vgtOIfc+6DhrMOGkLoGzqSV2rKp4Sm+opsyA= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= @@ -266,8 +266,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.21.0 h1:XpGXb+TQQ0IUdYaeAxGzWjSs6ow/Lce148A/2IbRDVE= -github.com/ipfs/boxo v0.21.0/go.mod h1:NmweAYeY1USOaJJxouy7DLr/Y5M8UBSsCI2KRivO+TY= +github.com/ipfs/boxo v0.21.1-0.20240730141506-8e51658f8a1b h1:vH+ly+ghScnm4fDTsFnRkWIqZ0Vux6U3aOzPc3bQsOM= +github.com/ipfs/boxo v0.21.1-0.20240730141506-8e51658f8a1b/go.mod h1:NmweAYeY1USOaJJxouy7DLr/Y5M8UBSsCI2KRivO+TY= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= @@ -427,8 +427,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.35.1 h1:Hm7Ub2BF+GCb14ojcsEK6WAy5it5smPDK02iXSZLl50= -github.com/libp2p/go-libp2p v0.35.1/go.mod h1:Dnkgba5hsfSv5dvvXC8nfqk44hH0gIKKno+HOMU0fdc= +github.com/libp2p/go-libp2p v0.35.4 h1:FDiBUYLkueFwsuNJUZaxKRdpKvBOWU64qQPL768bSeg= +github.com/libp2p/go-libp2p v0.35.4/go.mod h1:RKCDNt30IkFipGL0tl8wQW/3zVWEGFUZo8g2gAKxwjU= github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94= github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= @@ -445,8 +445,8 @@ github.com/libp2p/go-libp2p-pubsub-router v0.6.0 h1:D30iKdlqDt5ZmLEYhHELCMRj8b4s github.com/libp2p/go-libp2p-pubsub-router v0.6.0/go.mod h1:FY/q0/RBTKsLA7l4vqC2cbRbOvyDotg8PJQ7j8FDudE= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= github.com/libp2p/go-libp2p-record v0.2.0/go.mod h1:I+3zMkvvg5m2OcSdoL0KPljyJyvNDFGKX7QdlpYUcwk= -github.com/libp2p/go-libp2p-routing-helpers v0.7.3 h1:u1LGzAMVRK9Nqq5aYDVOiq/HaB93U9WWczBzGyAC5ZY= -github.com/libp2p/go-libp2p-routing-helpers v0.7.3/go.mod h1:cN4mJAD/7zfPKXBcs9ze31JGYAZgzdABEm+q/hkswb8= +github.com/libp2p/go-libp2p-routing-helpers v0.7.4 h1:6LqS1Bzn5CfDJ4tzvP9uwh42IB7TJLNFJA6dEeGBv84= +github.com/libp2p/go-libp2p-routing-helpers v0.7.4/go.mod h1:we5WDj9tbolBXOuF1hGOkR+r7Uh1408tQbAKaT5n1LE= github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA= github.com/libp2p/go-libp2p-testing v0.12.0/go.mod h1:KcGDRXyN7sQCllucn1cOOS+Dmm7ujhfEyXQL5lvkcPg= github.com/libp2p/go-libp2p-xor v0.1.0 h1:hhQwT4uGrBcuAkUGXADuPltalOdpf9aag9kaYNT2tLA= @@ -519,8 +519,8 @@ github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a github.com/multiformats/go-multiaddr v0.1.0/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo= github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4= -github.com/multiformats/go-multiaddr v0.12.4 h1:rrKqpY9h+n80EwhhC/kkcunCZZ7URIF8yN1WEUt2Hvc= -github.com/multiformats/go-multiaddr v0.12.4/go.mod h1:sBXrNzucqkFJhvKOiwwLyqamGa/P5EIXNPLovyhQCII= +github.com/multiformats/go-multiaddr v0.13.0 h1:BCBzs61E3AGHcYYTv8dqRH43ZfyrqM8RXVPT8t13tLQ= +github.com/multiformats/go-multiaddr v0.13.0/go.mod h1:sBXrNzucqkFJhvKOiwwLyqamGa/P5EIXNPLovyhQCII= github.com/multiformats/go-multiaddr-dns v0.3.0/go.mod h1:mNzQ4eTGDg0ll1N9jKPOUogZPoJ30W8a7zk66FQPpdQ= github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A= github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk= @@ -550,6 +550,8 @@ github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXS github.com/multiformats/go-varint v0.0.6/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8= github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= @@ -643,8 +645,8 @@ github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1: github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.54.0 h1:ZlZy0BgJhTwVZUn7dLOkwCZHUkrAqd3WYtcFCWnM1D8= -github.com/prometheus/common v0.54.0/go.mod h1:/TQgMJP5CuVYveyT7n/0Ix8yLNNXy9yRSkhnLTHPDIQ= +github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc= +github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= @@ -663,8 +665,8 @@ github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99 github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd/go.mod h1:hPqNNc0+uJM6H+SuU8sEs5K5IQeKccPqeSjfgcKGgPk= -github.com/samber/lo v1.39.0 h1:4gTz1wUhNYLhFSKl6O+8peW0v2F4BCY034GRpU9WnuA= -github.com/samber/lo v1.39.0/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA= +github.com/samber/lo v1.46.0 h1:w8G+oaCPgz1PoCJztqymCFaKwXt+5cCXn51uPxExFfQ= +github.com/samber/lo v1.46.0/go.mod h1:RmDH9Ct32Qy3gduHQuKJ3gW1fMHAnE/fAzQuf6He5cU= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY= github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM= @@ -780,8 +782,8 @@ go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.52.0 h1:9l89oX4ba9kHbBol3Xin3leYJ+252h0zszDtBwyKe2A= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.52.0/go.mod h1:XLZfZboOJWHNKUv7eH0inh0E9VV6eWDFB/9yJyTLPp0= -go.opentelemetry.io/otel v1.27.0 h1:9BZoF3yMK/O1AafMiQTVu0YDj5Ea4hPhxCs7sGva+cg= -go.opentelemetry.io/otel v1.27.0/go.mod h1:DMpAK8fzYRzs+bi3rS5REupisuqTheUlSZJ1WnZaPAQ= +go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= +go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 h1:R9DE4kQ4k+YtfLI2ULwX82VtNQ2J8yZmA7ZIF/D+7Mc= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0/go.mod h1:OQFyQVrDlbe+R7xrEyDr/2Wr67Ol0hRUgsfA+V5A95s= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 h1:qFffATk0X+HD+f1Z8lswGiOQYKHRlzfmdJm0wEaVrFA= @@ -792,12 +794,12 @@ go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.27.0 h1:/0YaXu3755A/cFb go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.27.0/go.mod h1:m7SFxp0/7IxmJPLIY3JhOcU9CoFzDaCPL6xxQIxhA+o= go.opentelemetry.io/otel/exporters/zipkin v1.27.0 h1:aXcxb7F6ZDC1o2Z52LDfS2g6M2FB5CrxdR2gzY4QRNs= go.opentelemetry.io/otel/exporters/zipkin v1.27.0/go.mod h1:+WMURoi4KmVB7ypbFPx3xtZTWen2Ca3lRK9u6DVTO5M= -go.opentelemetry.io/otel/metric v1.27.0 h1:hvj3vdEKyeCi4YaYfNjv2NUje8FqKqUY8IlF0FxV/ik= -go.opentelemetry.io/otel/metric v1.27.0/go.mod h1:mVFgmRlhljgBiuk/MP/oKylr4hs85GZAylncepAX/ak= +go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q= +go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s= go.opentelemetry.io/otel/sdk v1.27.0 h1:mlk+/Y1gLPLn84U4tI8d3GNJmGT/eXe3ZuOXN9kTWmI= go.opentelemetry.io/otel/sdk v1.27.0/go.mod h1:Ha9vbLwJE6W86YstIywK2xFfPjbWlCuwPtMkKdz/Y4A= -go.opentelemetry.io/otel/trace v1.27.0 h1:IqYb813p7cmbHk0a5y6pD5JPakbVfftRXABGt5/Rscw= -go.opentelemetry.io/otel/trace v1.27.0/go.mod h1:6RiD1hkAprV4/q+yd2ln1HG9GoPx39SuvvstaLBl+l4= +go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= +go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= @@ -807,8 +809,8 @@ go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= -go.uber.org/fx v1.22.0 h1:pApUK7yL0OUHMd8vkunWSlLxZVFFk70jR2nKde8X2NM= -go.uber.org/fx v1.22.0/go.mod h1:HT2M7d7RHo+ebKGh9NRcrsrHHfpZ60nW3QRubMRfv48= +go.uber.org/fx v1.22.1 h1:nvvln7mwyT5s1q201YE29V/BFrGor6vMiDNpU/78Mys= +go.uber.org/fx v1.22.1/go.mod h1:HT2M7d7RHo+ebKGh9NRcrsrHHfpZ60nW3QRubMRfv48= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= @@ -853,8 +855,8 @@ golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98y golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= -golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= -golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= +golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= +golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -863,8 +865,8 @@ golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 h1:yixxcjnhBmY0nkL253HFVIm0JsFHwrHdT3Yh6szTnfY= -golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -888,8 +890,8 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0= -golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= +golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -928,8 +930,8 @@ golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= -golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= -golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= +golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= +golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1006,8 +1008,8 @@ golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= -golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= +golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -1075,14 +1077,14 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA= -golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c= +golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= +golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU= -golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= +golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9 h1:LLhsEBxRTBLuKlQxFBYUOU8xyFgXv6cOTp2HASDlsDk= +golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= gonum.org/v1/gonum v0.15.0 h1:2lYxjRbTYyxkJxlhC+LvJIx3SsANPdRybu1tGj9/OrQ= gonum.org/v1/gonum v0.15.0/go.mod h1:xzZVBJBtS+Mz4q0Yl2LJTk+OxOg4jiXZ7qBoM0uISGo= google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= diff --git a/go.mod b/go.mod index b466bc1f9..1492b46eb 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( github.com/hashicorp/go-version v1.6.0 github.com/ipfs-shipyard/nopfs v0.0.12 github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c - github.com/ipfs/boxo v0.21.0 + github.com/ipfs/boxo v0.21.1-0.20240730141506-8e51658f8a1b github.com/ipfs/go-block-format v0.2.0 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 @@ -48,18 +48,18 @@ require ( github.com/jbenet/goprocess v0.1.4 github.com/julienschmidt/httprouter v1.3.0 github.com/libp2p/go-doh-resolver v0.4.0 - github.com/libp2p/go-libp2p v0.35.1 + github.com/libp2p/go-libp2p v0.35.4 github.com/libp2p/go-libp2p-http v0.5.0 github.com/libp2p/go-libp2p-kad-dht v0.25.2 github.com/libp2p/go-libp2p-kbucket v0.6.3 github.com/libp2p/go-libp2p-pubsub v0.11.0 github.com/libp2p/go-libp2p-pubsub-router v0.6.0 github.com/libp2p/go-libp2p-record v0.2.0 - github.com/libp2p/go-libp2p-routing-helpers v0.7.3 + github.com/libp2p/go-libp2p-routing-helpers v0.7.4 github.com/libp2p/go-libp2p-testing v0.12.0 github.com/libp2p/go-socket-activation v0.1.0 github.com/mitchellh/go-homedir v1.1.0 - github.com/multiformats/go-multiaddr v0.12.4 + github.com/multiformats/go-multiaddr v0.13.0 github.com/multiformats/go-multiaddr-dns v0.3.1 github.com/multiformats/go-multibase v0.2.0 github.com/multiformats/go-multicodec v0.9.0 @@ -76,25 +76,25 @@ require ( go.opencensus.io v0.24.0 go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.52.0 go.opentelemetry.io/contrib/propagators/autoprop v0.46.1 - go.opentelemetry.io/otel v1.27.0 + go.opentelemetry.io/otel v1.28.0 go.opentelemetry.io/otel/sdk v1.27.0 - go.opentelemetry.io/otel/trace v1.27.0 + go.opentelemetry.io/otel/trace v1.28.0 go.uber.org/dig v1.17.1 - go.uber.org/fx v1.22.0 + go.uber.org/fx v1.22.1 go.uber.org/multierr v1.11.0 go.uber.org/zap v1.27.0 - golang.org/x/crypto v0.24.0 - golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 - golang.org/x/mod v0.18.0 + golang.org/x/crypto v0.25.0 + golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 + golang.org/x/mod v0.19.0 golang.org/x/sync v0.7.0 - golang.org/x/sys v0.21.0 + golang.org/x/sys v0.22.0 google.golang.org/protobuf v1.34.2 ) require ( github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 // indirect github.com/Jorropo/jsync v1.0.1 // indirect - github.com/alecthomas/units v0.0.0-20231202071711-9a357b53e9c9 // indirect + github.com/alecthomas/units v0.0.0-20240626203959-61d1e3462e30 // indirect github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash v1.1.0 // indirect @@ -177,6 +177,7 @@ require ( github.com/multiformats/go-multiaddr-fmt v0.1.0 // indirect github.com/multiformats/go-multistream v0.5.0 // indirect github.com/multiformats/go-varint v0.0.7 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/onsi/ginkgo/v2 v2.19.0 // indirect github.com/opencontainers/runtime-spec v1.2.0 // indirect github.com/openzipkin/zipkin-go v0.4.3 // indirect @@ -201,7 +202,7 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect github.com/polydawn/refmt v0.89.0 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.54.0 // indirect + github.com/prometheus/common v0.55.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/prometheus/statsd_exporter v0.22.7 // indirect github.com/quic-go/qpack v0.4.0 // indirect @@ -209,7 +210,7 @@ require ( github.com/quic-go/webtransport-go v0.8.0 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/rs/cors v1.10.1 // indirect - github.com/samber/lo v1.39.0 // indirect + github.com/samber/lo v1.46.0 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/texttheater/golang-levenshtein v1.0.1 // indirect github.com/tidwall/match v1.1.1 // indirect @@ -229,17 +230,17 @@ require ( go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.0 // indirect go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.27.0 // indirect go.opentelemetry.io/otel/exporters/zipkin v1.27.0 // indirect - go.opentelemetry.io/otel/metric v1.27.0 // indirect + go.opentelemetry.io/otel/metric v1.28.0 // indirect go.opentelemetry.io/proto/otlp v1.3.1 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/mock v0.4.0 // indirect go4.org v0.0.0-20230225012048-214862532bf5 // indirect - golang.org/x/net v0.26.0 // indirect + golang.org/x/net v0.27.0 // indirect golang.org/x/oauth2 v0.21.0 // indirect - golang.org/x/term v0.21.0 // indirect + golang.org/x/term v0.22.0 // indirect golang.org/x/text v0.16.0 // indirect - golang.org/x/tools v0.22.0 // indirect - golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect + golang.org/x/tools v0.23.0 // indirect + golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9 // indirect gonum.org/v1/gonum v0.15.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240617180043-68d350f18fd4 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240617180043-68d350f18fd4 // indirect diff --git a/go.sum b/go.sum index a42aaa22c..8f76df20a 100644 --- a/go.sum +++ b/go.sum @@ -58,8 +58,8 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= -github.com/alecthomas/units v0.0.0-20231202071711-9a357b53e9c9 h1:ez/4by2iGztzR4L0zgAOR8lTQK9VlyBVVd7G4omaOQs= -github.com/alecthomas/units v0.0.0-20231202071711-9a357b53e9c9/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= +github.com/alecthomas/units v0.0.0-20240626203959-61d1e3462e30 h1:t3eaIm0rUkzbrIewtiFmMK5RXHej2XnoXNhxVsAYUfg= +github.com/alecthomas/units v0.0.0-20240626203959-61d1e3462e30/go.mod h1:fvzegU4vN3H1qMT+8wDmzjAcDONcgo2/SZ/TyfdUOFs= github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5 h1:iW0a5ljuFxkLGPNem5Ui+KBjFJzKg4Fv2fnxe4dvzpM= github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5/go.mod h1:Y2QMoi1vgtOIfc+6DhrMOGkLoGzqSV2rKp4Sm+opsyA= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= @@ -330,8 +330,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.21.0 h1:XpGXb+TQQ0IUdYaeAxGzWjSs6ow/Lce148A/2IbRDVE= -github.com/ipfs/boxo v0.21.0/go.mod h1:NmweAYeY1USOaJJxouy7DLr/Y5M8UBSsCI2KRivO+TY= +github.com/ipfs/boxo v0.21.1-0.20240730141506-8e51658f8a1b h1:vH+ly+ghScnm4fDTsFnRkWIqZ0Vux6U3aOzPc3bQsOM= +github.com/ipfs/boxo v0.21.1-0.20240730141506-8e51658f8a1b/go.mod h1:NmweAYeY1USOaJJxouy7DLr/Y5M8UBSsCI2KRivO+TY= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= @@ -508,8 +508,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.35.1 h1:Hm7Ub2BF+GCb14ojcsEK6WAy5it5smPDK02iXSZLl50= -github.com/libp2p/go-libp2p v0.35.1/go.mod h1:Dnkgba5hsfSv5dvvXC8nfqk44hH0gIKKno+HOMU0fdc= +github.com/libp2p/go-libp2p v0.35.4 h1:FDiBUYLkueFwsuNJUZaxKRdpKvBOWU64qQPL768bSeg= +github.com/libp2p/go-libp2p v0.35.4/go.mod h1:RKCDNt30IkFipGL0tl8wQW/3zVWEGFUZo8g2gAKxwjU= github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94= github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= @@ -530,8 +530,8 @@ github.com/libp2p/go-libp2p-pubsub-router v0.6.0 h1:D30iKdlqDt5ZmLEYhHELCMRj8b4s github.com/libp2p/go-libp2p-pubsub-router v0.6.0/go.mod h1:FY/q0/RBTKsLA7l4vqC2cbRbOvyDotg8PJQ7j8FDudE= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= github.com/libp2p/go-libp2p-record v0.2.0/go.mod h1:I+3zMkvvg5m2OcSdoL0KPljyJyvNDFGKX7QdlpYUcwk= -github.com/libp2p/go-libp2p-routing-helpers v0.7.3 h1:u1LGzAMVRK9Nqq5aYDVOiq/HaB93U9WWczBzGyAC5ZY= -github.com/libp2p/go-libp2p-routing-helpers v0.7.3/go.mod h1:cN4mJAD/7zfPKXBcs9ze31JGYAZgzdABEm+q/hkswb8= +github.com/libp2p/go-libp2p-routing-helpers v0.7.4 h1:6LqS1Bzn5CfDJ4tzvP9uwh42IB7TJLNFJA6dEeGBv84= +github.com/libp2p/go-libp2p-routing-helpers v0.7.4/go.mod h1:we5WDj9tbolBXOuF1hGOkR+r7Uh1408tQbAKaT5n1LE= github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA= github.com/libp2p/go-libp2p-testing v0.12.0/go.mod h1:KcGDRXyN7sQCllucn1cOOS+Dmm7ujhfEyXQL5lvkcPg= github.com/libp2p/go-libp2p-xor v0.1.0 h1:hhQwT4uGrBcuAkUGXADuPltalOdpf9aag9kaYNT2tLA= @@ -619,8 +619,8 @@ github.com/multiformats/go-multiaddr v0.1.0/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lg github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo= github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4= github.com/multiformats/go-multiaddr v0.4.0/go.mod h1:YcpyLH8ZPudLxQlemYBPhSm0/oCXAT8Z4mzFpyoPyRc= -github.com/multiformats/go-multiaddr v0.12.4 h1:rrKqpY9h+n80EwhhC/kkcunCZZ7URIF8yN1WEUt2Hvc= -github.com/multiformats/go-multiaddr v0.12.4/go.mod h1:sBXrNzucqkFJhvKOiwwLyqamGa/P5EIXNPLovyhQCII= +github.com/multiformats/go-multiaddr v0.13.0 h1:BCBzs61E3AGHcYYTv8dqRH43ZfyrqM8RXVPT8t13tLQ= +github.com/multiformats/go-multiaddr v0.13.0/go.mod h1:sBXrNzucqkFJhvKOiwwLyqamGa/P5EIXNPLovyhQCII= github.com/multiformats/go-multiaddr-dns v0.3.0/go.mod h1:mNzQ4eTGDg0ll1N9jKPOUogZPoJ30W8a7zk66FQPpdQ= github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A= github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk= @@ -650,6 +650,8 @@ github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXS github.com/multiformats/go-varint v0.0.6/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8= github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= @@ -763,8 +765,8 @@ github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9 github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/common v0.35.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= -github.com/prometheus/common v0.54.0 h1:ZlZy0BgJhTwVZUn7dLOkwCZHUkrAqd3WYtcFCWnM1D8= -github.com/prometheus/common v0.54.0/go.mod h1:/TQgMJP5CuVYveyT7n/0Ix8yLNNXy9yRSkhnLTHPDIQ= +github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc= +github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= @@ -794,8 +796,8 @@ github.com/rs/cors v1.10.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd/go.mod h1:hPqNNc0+uJM6H+SuU8sEs5K5IQeKccPqeSjfgcKGgPk= -github.com/samber/lo v1.39.0 h1:4gTz1wUhNYLhFSKl6O+8peW0v2F4BCY034GRpU9WnuA= -github.com/samber/lo v1.39.0/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA= +github.com/samber/lo v1.46.0 h1:w8G+oaCPgz1PoCJztqymCFaKwXt+5cCXn51uPxExFfQ= +github.com/samber/lo v1.46.0/go.mod h1:RmDH9Ct32Qy3gduHQuKJ3gW1fMHAnE/fAzQuf6He5cU= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY= github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM= @@ -942,8 +944,8 @@ go.opentelemetry.io/contrib/propagators/jaeger v1.21.1 h1:f4beMGDKiVzg9IcX7/VuWV go.opentelemetry.io/contrib/propagators/jaeger v1.21.1/go.mod h1:U9jhkEl8d1LL+QXY7q3kneJWJugiN3kZJV2OWz3hkBY= go.opentelemetry.io/contrib/propagators/ot v1.21.1 h1:3TN5vkXjKYWp0YdMcnUEC/A+pBPvqz9V3nCS2xmcurk= go.opentelemetry.io/contrib/propagators/ot v1.21.1/go.mod h1:oy0MYCbS/b3cqUDW37wBWtlwBIsutngS++Lklpgh+fc= -go.opentelemetry.io/otel v1.27.0 h1:9BZoF3yMK/O1AafMiQTVu0YDj5Ea4hPhxCs7sGva+cg= -go.opentelemetry.io/otel v1.27.0/go.mod h1:DMpAK8fzYRzs+bi3rS5REupisuqTheUlSZJ1WnZaPAQ= +go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= +go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 h1:R9DE4kQ4k+YtfLI2ULwX82VtNQ2J8yZmA7ZIF/D+7Mc= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0/go.mod h1:OQFyQVrDlbe+R7xrEyDr/2Wr67Ol0hRUgsfA+V5A95s= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 h1:qFffATk0X+HD+f1Z8lswGiOQYKHRlzfmdJm0wEaVrFA= @@ -954,12 +956,12 @@ go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.27.0 h1:/0YaXu3755A/cFb go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.27.0/go.mod h1:m7SFxp0/7IxmJPLIY3JhOcU9CoFzDaCPL6xxQIxhA+o= go.opentelemetry.io/otel/exporters/zipkin v1.27.0 h1:aXcxb7F6ZDC1o2Z52LDfS2g6M2FB5CrxdR2gzY4QRNs= go.opentelemetry.io/otel/exporters/zipkin v1.27.0/go.mod h1:+WMURoi4KmVB7ypbFPx3xtZTWen2Ca3lRK9u6DVTO5M= -go.opentelemetry.io/otel/metric v1.27.0 h1:hvj3vdEKyeCi4YaYfNjv2NUje8FqKqUY8IlF0FxV/ik= -go.opentelemetry.io/otel/metric v1.27.0/go.mod h1:mVFgmRlhljgBiuk/MP/oKylr4hs85GZAylncepAX/ak= +go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q= +go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s= go.opentelemetry.io/otel/sdk v1.27.0 h1:mlk+/Y1gLPLn84U4tI8d3GNJmGT/eXe3ZuOXN9kTWmI= go.opentelemetry.io/otel/sdk v1.27.0/go.mod h1:Ha9vbLwJE6W86YstIywK2xFfPjbWlCuwPtMkKdz/Y4A= -go.opentelemetry.io/otel/trace v1.27.0 h1:IqYb813p7cmbHk0a5y6pD5JPakbVfftRXABGt5/Rscw= -go.opentelemetry.io/otel/trace v1.27.0/go.mod h1:6RiD1hkAprV4/q+yd2ln1HG9GoPx39SuvvstaLBl+l4= +go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= +go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= @@ -969,8 +971,8 @@ go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= -go.uber.org/fx v1.22.0 h1:pApUK7yL0OUHMd8vkunWSlLxZVFFk70jR2nKde8X2NM= -go.uber.org/fx v1.22.0/go.mod h1:HT2M7d7RHo+ebKGh9NRcrsrHHfpZ60nW3QRubMRfv48= +go.uber.org/fx v1.22.1 h1:nvvln7mwyT5s1q201YE29V/BFrGor6vMiDNpU/78Mys= +go.uber.org/fx v1.22.1/go.mod h1:HT2M7d7RHo+ebKGh9NRcrsrHHfpZ60nW3QRubMRfv48= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= @@ -1015,8 +1017,8 @@ golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98y golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= -golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= -golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= +golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= +golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1027,8 +1029,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 h1:yixxcjnhBmY0nkL253HFVIm0JsFHwrHdT3Yh6szTnfY= -golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1053,8 +1055,8 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0= -golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= +golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1110,8 +1112,8 @@ golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= -golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= -golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= +golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= +golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1217,8 +1219,8 @@ golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= -golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= +golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -1230,8 +1232,8 @@ golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= -golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA= -golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= +golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= +golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1305,14 +1307,14 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA= -golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c= +golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= +golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU= -golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= +golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9 h1:LLhsEBxRTBLuKlQxFBYUOU8xyFgXv6cOTp2HASDlsDk= +golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= gonum.org/v1/gonum v0.15.0 h1:2lYxjRbTYyxkJxlhC+LvJIx3SsANPdRybu1tGj9/OrQ= gonum.org/v1/gonum v0.15.0/go.mod h1:xzZVBJBtS+Mz4q0Yl2LJTk+OxOg4jiXZ7qBoM0uISGo= google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= diff --git a/test/cli/gateway_test.go b/test/cli/gateway_test.go index 33212a90f..0a10782f9 100644 --- a/test/cli/gateway_test.go +++ b/test/cli/gateway_test.go @@ -414,12 +414,12 @@ func TestGateway(t *testing.T) { t.Run("not present", func(t *testing.T) { cidFoo := node2.IPFSAddStr("foo") - t.Run("not present key from node 1", func(t *testing.T) { + t.Run("not present CID from node 1", func(t *testing.T) { t.Parallel() - assert.Equal(t, 500, node1.GatewayClient().Get("/ipfs/"+cidFoo).StatusCode) + assert.Equal(t, 404, node1.GatewayClient().Get("/ipfs/"+cidFoo).StatusCode) }) - t.Run("not present IPNS key from node 1", func(t *testing.T) { + t.Run("not present IPNS Record from node 1", func(t *testing.T) { t.Parallel() assert.Equal(t, 500, node1.GatewayClient().Get("/ipns/"+node2PeerID).StatusCode) }) @@ -428,12 +428,12 @@ func TestGateway(t *testing.T) { t.Run("present", func(t *testing.T) { cidBar := node1.IPFSAddStr("bar") - t.Run("present key from node 1", func(t *testing.T) { + t.Run("present CID from node 1", func(t *testing.T) { t.Parallel() assert.Equal(t, 200, node1.GatewayClient().Get("/ipfs/"+cidBar).StatusCode) }) - t.Run("present IPNS key from node 1", func(t *testing.T) { + t.Run("present IPNS Record from node 1", func(t *testing.T) { t.Parallel() node2.IPFS("name", "publish", "/ipfs/"+cidBar) assert.Equal(t, 200, node1.GatewayClient().Get("/ipns/"+node2PeerID).StatusCode) diff --git a/test/cli/http_gateway_over_libp2p_test.go b/test/cli/http_gateway_over_libp2p_test.go index ee5717571..f8cfe0071 100644 --- a/test/cli/http_gateway_over_libp2p_test.go +++ b/test/cli/http_gateway_over_libp2p_test.go @@ -71,7 +71,7 @@ func TestGatewayOverLibp2p(t *testing.T) { t.Run("WillNotServeRemoteContent", func(t *testing.T) { resp, err := http.Get(fmt.Sprintf("http://%s/ipfs/%s?format=raw", p2pProxyNodeHTTPListenAddr, cidDataNotOnGatewayNode)) require.NoError(t, err) - require.Equal(t, 500, resp.StatusCode) + require.Equal(t, http.StatusNotFound, resp.StatusCode) }) t.Run("WillNotServeDeserializedResponses", func(t *testing.T) { diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index bc334d33f..108ffeaab 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -16,7 +16,7 @@ require ( github.com/ipfs/iptb-plugins v0.5.0 github.com/jbenet/go-random v0.0.0-20190219211222-123a90aedc0c github.com/jbenet/go-random-files v0.0.0-20190219210431-31b3f20ebded - github.com/multiformats/go-multiaddr v0.12.4 + github.com/multiformats/go-multiaddr v0.13.0 github.com/multiformats/go-multihash v0.2.3 gotest.tools/gotestsum v1.12.0 ) @@ -113,7 +113,7 @@ require ( github.com/hexops/gotextdiff v1.0.3 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/ipfs/bbloom v0.0.4 // indirect - github.com/ipfs/boxo v0.21.0 // indirect + github.com/ipfs/boxo v0.21.1-0.20240730141506-8e51658f8a1b // indirect github.com/ipfs/go-block-format v0.2.0 // indirect github.com/ipfs/go-cid v0.4.1 // indirect github.com/ipfs/go-datastore v0.6.0 // indirect @@ -144,12 +144,12 @@ require ( github.com/leonklingele/grouper v1.1.2 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/libp2p/go-cidranger v1.1.0 // indirect - github.com/libp2p/go-libp2p v0.35.1 // indirect + github.com/libp2p/go-libp2p v0.35.4 // indirect github.com/libp2p/go-libp2p-asn-util v0.4.1 // indirect github.com/libp2p/go-libp2p-kad-dht v0.25.2 // indirect github.com/libp2p/go-libp2p-kbucket v0.6.3 // indirect github.com/libp2p/go-libp2p-record v0.2.0 // indirect - github.com/libp2p/go-libp2p-routing-helpers v0.7.3 // indirect + github.com/libp2p/go-libp2p-routing-helpers v0.7.4 // indirect github.com/libp2p/go-msgio v0.3.0 // indirect github.com/libp2p/go-netroute v0.2.1 // indirect github.com/lufeee/execinquery v1.2.1 // indirect @@ -175,6 +175,7 @@ require ( github.com/multiformats/go-multicodec v0.9.0 // indirect github.com/multiformats/go-multistream v0.5.0 // indirect github.com/multiformats/go-varint v0.0.7 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/nakabonne/nestif v0.3.1 // indirect github.com/nishanths/exhaustive v0.12.0 // indirect github.com/nishanths/predeclared v0.2.2 // indirect @@ -188,7 +189,7 @@ require ( github.com/polyfloyd/go-errorlint v1.5.2 // indirect github.com/prometheus/client_golang v1.19.1 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.54.0 // indirect + github.com/prometheus/common v0.55.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/quasilyte/go-ruleguard v0.4.2 // indirect github.com/quasilyte/go-ruleguard/dsl v0.3.22 // indirect @@ -201,7 +202,7 @@ require ( github.com/ryanrolds/sqlclosecheck v0.5.1 // indirect github.com/sagikazarmark/locafero v0.6.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect - github.com/samber/lo v1.39.0 // indirect + github.com/samber/lo v1.46.0 // indirect github.com/sanposhiho/wastedassign/v2 v2.0.7 // indirect github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 // indirect github.com/sashamelentyev/interfacebloat v1.1.0 // indirect @@ -246,22 +247,22 @@ require ( go-simpler.org/musttag v0.12.2 // indirect go-simpler.org/sloglint v0.7.1 // indirect go.opencensus.io v0.24.0 // indirect - go.opentelemetry.io/otel v1.27.0 // indirect - go.opentelemetry.io/otel/metric v1.27.0 // indirect - go.opentelemetry.io/otel/trace v1.27.0 // indirect + go.opentelemetry.io/otel v1.28.0 // indirect + go.opentelemetry.io/otel/metric v1.28.0 // indirect + go.opentelemetry.io/otel/trace v1.28.0 // indirect go.uber.org/automaxprocs v1.5.3 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect - golang.org/x/crypto v0.24.0 // indirect - golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 // indirect + golang.org/x/crypto v0.25.0 // indirect + golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect golang.org/x/exp/typeparams v0.0.0-20240613232115-7f521ea00fb8 // indirect - golang.org/x/mod v0.18.0 // indirect - golang.org/x/net v0.26.0 // indirect + golang.org/x/mod v0.19.0 // indirect + golang.org/x/net v0.27.0 // indirect golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.21.0 // indirect - golang.org/x/term v0.21.0 // indirect + golang.org/x/sys v0.22.0 // indirect + golang.org/x/term v0.22.0 // indirect golang.org/x/text v0.16.0 // indirect - golang.org/x/tools v0.22.0 // indirect + golang.org/x/tools v0.23.0 // indirect gonum.org/v1/gonum v0.15.0 // indirect google.golang.org/protobuf v1.34.2 // indirect gopkg.in/ini.v1 v1.67.0 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index e5c9a5307..28f533eac 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -280,8 +280,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.21.0 h1:XpGXb+TQQ0IUdYaeAxGzWjSs6ow/Lce148A/2IbRDVE= -github.com/ipfs/boxo v0.21.0/go.mod h1:NmweAYeY1USOaJJxouy7DLr/Y5M8UBSsCI2KRivO+TY= +github.com/ipfs/boxo v0.21.1-0.20240730141506-8e51658f8a1b h1:vH+ly+ghScnm4fDTsFnRkWIqZ0Vux6U3aOzPc3bQsOM= +github.com/ipfs/boxo v0.21.1-0.20240730141506-8e51658f8a1b/go.mod h1:NmweAYeY1USOaJJxouy7DLr/Y5M8UBSsCI2KRivO+TY= github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs= github.com/ipfs/go-block-format v0.2.0/go.mod h1:+jpL11nFx5A/SPpsoBn6Bzkra/zaArfSmsknbPMYgzM= github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= @@ -387,8 +387,8 @@ github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38y github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.35.1 h1:Hm7Ub2BF+GCb14ojcsEK6WAy5it5smPDK02iXSZLl50= -github.com/libp2p/go-libp2p v0.35.1/go.mod h1:Dnkgba5hsfSv5dvvXC8nfqk44hH0gIKKno+HOMU0fdc= +github.com/libp2p/go-libp2p v0.35.4 h1:FDiBUYLkueFwsuNJUZaxKRdpKvBOWU64qQPL768bSeg= +github.com/libp2p/go-libp2p v0.35.4/go.mod h1:RKCDNt30IkFipGL0tl8wQW/3zVWEGFUZo8g2gAKxwjU= github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94= github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= github.com/libp2p/go-libp2p-kad-dht v0.25.2 h1:FOIk9gHoe4YRWXTu8SY9Z1d0RILol0TrtApsMDPjAVQ= @@ -397,8 +397,8 @@ github.com/libp2p/go-libp2p-kbucket v0.6.3 h1:p507271wWzpy2f1XxPzCQG9NiN6R6lHL9G github.com/libp2p/go-libp2p-kbucket v0.6.3/go.mod h1:RCseT7AH6eJWxxk2ol03xtP9pEHetYSPXOaJnOiD8i0= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= github.com/libp2p/go-libp2p-record v0.2.0/go.mod h1:I+3zMkvvg5m2OcSdoL0KPljyJyvNDFGKX7QdlpYUcwk= -github.com/libp2p/go-libp2p-routing-helpers v0.7.3 h1:u1LGzAMVRK9Nqq5aYDVOiq/HaB93U9WWczBzGyAC5ZY= -github.com/libp2p/go-libp2p-routing-helpers v0.7.3/go.mod h1:cN4mJAD/7zfPKXBcs9ze31JGYAZgzdABEm+q/hkswb8= +github.com/libp2p/go-libp2p-routing-helpers v0.7.4 h1:6LqS1Bzn5CfDJ4tzvP9uwh42IB7TJLNFJA6dEeGBv84= +github.com/libp2p/go-libp2p-routing-helpers v0.7.4/go.mod h1:we5WDj9tbolBXOuF1hGOkR+r7Uh1408tQbAKaT5n1LE= github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA= github.com/libp2p/go-libp2p-testing v0.12.0/go.mod h1:KcGDRXyN7sQCllucn1cOOS+Dmm7ujhfEyXQL5lvkcPg= github.com/libp2p/go-msgio v0.3.0 h1:mf3Z8B1xcFN314sWX+2vOTShIE0Mmn2TXn3YCUQGNj0= @@ -465,8 +465,8 @@ github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYg github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0= github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4= github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4= -github.com/multiformats/go-multiaddr v0.12.4 h1:rrKqpY9h+n80EwhhC/kkcunCZZ7URIF8yN1WEUt2Hvc= -github.com/multiformats/go-multiaddr v0.12.4/go.mod h1:sBXrNzucqkFJhvKOiwwLyqamGa/P5EIXNPLovyhQCII= +github.com/multiformats/go-multiaddr v0.13.0 h1:BCBzs61E3AGHcYYTv8dqRH43ZfyrqM8RXVPT8t13tLQ= +github.com/multiformats/go-multiaddr v0.13.0/go.mod h1:sBXrNzucqkFJhvKOiwwLyqamGa/P5EIXNPLovyhQCII= github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A= github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk= github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E= @@ -483,6 +483,8 @@ github.com/multiformats/go-multistream v0.5.0/go.mod h1:n6tMZiwiP2wUsR8DgfDWw1dy github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8= github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/nakabonne/nestif v0.3.1 h1:wm28nZjhQY5HyYPx+weN3Q65k6ilSBxDb8v5S81B81U= github.com/nakabonne/nestif v0.3.1/go.mod h1:9EtoZochLn5iUprVDmDjqGKPofoUEBL8U4Ngq6aY7OE= github.com/nishanths/exhaustive v0.12.0 h1:vIY9sALmw6T/yxiASewa4TQcFsVYZQQRUQJhKRf3Swg= @@ -561,8 +563,8 @@ github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJL github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= -github.com/prometheus/common v0.54.0 h1:ZlZy0BgJhTwVZUn7dLOkwCZHUkrAqd3WYtcFCWnM1D8= -github.com/prometheus/common v0.54.0/go.mod h1:/TQgMJP5CuVYveyT7n/0Ix8yLNNXy9yRSkhnLTHPDIQ= +github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc= +github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8= github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/quasilyte/go-ruleguard v0.4.2 h1:htXcXDK6/rO12kiTHKfHuqR4kr3Y4M0J0rOL6CH/BYs= @@ -601,8 +603,8 @@ github.com/sagikazarmark/locafero v0.6.0 h1:ON7AQg37yzcRPU69mt7gwhFEBwxI6P9T4Qu3 github.com/sagikazarmark/locafero v0.6.0/go.mod h1:77OmuIc6VTraTXKXIs/uvUxKGUXjE1GbemJYHqdNjX0= github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= -github.com/samber/lo v1.39.0 h1:4gTz1wUhNYLhFSKl6O+8peW0v2F4BCY034GRpU9WnuA= -github.com/samber/lo v1.39.0/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA= +github.com/samber/lo v1.46.0 h1:w8G+oaCPgz1PoCJztqymCFaKwXt+5cCXn51uPxExFfQ= +github.com/samber/lo v1.46.0/go.mod h1:RmDH9Ct32Qy3gduHQuKJ3gW1fMHAnE/fAzQuf6He5cU= github.com/sanposhiho/wastedassign/v2 v2.0.7 h1:J+6nrY4VW+gC9xFzUc+XjPD3g3wF3je/NsJFwFK7Uxc= github.com/sanposhiho/wastedassign/v2 v2.0.7/go.mod h1:KyZ0MWTwxxBmfwn33zh3k1dmsbF2ud9pAAGfoLfjhtI= github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6NgVqpn3+iol9aGu4= @@ -727,20 +729,20 @@ go-simpler.org/sloglint v0.7.1 h1:qlGLiqHbN5islOxjeLXoPtUdZXb669RW+BDQ+xOSNoU= go-simpler.org/sloglint v0.7.1/go.mod h1:OlaVDRh/FKKd4X4sIMbsz8st97vomydceL146Fthh/c= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/otel v1.27.0 h1:9BZoF3yMK/O1AafMiQTVu0YDj5Ea4hPhxCs7sGva+cg= -go.opentelemetry.io/otel v1.27.0/go.mod h1:DMpAK8fzYRzs+bi3rS5REupisuqTheUlSZJ1WnZaPAQ= -go.opentelemetry.io/otel/metric v1.27.0 h1:hvj3vdEKyeCi4YaYfNjv2NUje8FqKqUY8IlF0FxV/ik= -go.opentelemetry.io/otel/metric v1.27.0/go.mod h1:mVFgmRlhljgBiuk/MP/oKylr4hs85GZAylncepAX/ak= -go.opentelemetry.io/otel/trace v1.27.0 h1:IqYb813p7cmbHk0a5y6pD5JPakbVfftRXABGt5/Rscw= -go.opentelemetry.io/otel/trace v1.27.0/go.mod h1:6RiD1hkAprV4/q+yd2ln1HG9GoPx39SuvvstaLBl+l4= +go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= +go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= +go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q= +go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s= +go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= +go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/automaxprocs v1.5.3 h1:kWazyxZUrS3Gs4qUpbwo5kEIMGe/DAvi5Z4tl2NW4j8= go.uber.org/automaxprocs v1.5.3/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0= go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= -go.uber.org/fx v1.22.0 h1:pApUK7yL0OUHMd8vkunWSlLxZVFFk70jR2nKde8X2NM= -go.uber.org/fx v1.22.0/go.mod h1:HT2M7d7RHo+ebKGh9NRcrsrHHfpZ60nW3QRubMRfv48= +go.uber.org/fx v1.22.1 h1:nvvln7mwyT5s1q201YE29V/BFrGor6vMiDNpU/78Mys= +go.uber.org/fx v1.22.1/go.mod h1:HT2M7d7RHo+ebKGh9NRcrsrHHfpZ60nW3QRubMRfv48= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= @@ -767,11 +769,11 @@ golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliY golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= -golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= -golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= +golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= +golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 h1:yixxcjnhBmY0nkL253HFVIm0JsFHwrHdT3Yh6szTnfY= -golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= golang.org/x/exp/typeparams v0.0.0-20220428152302-39d4317da171/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/exp/typeparams v0.0.0-20230203172020-98cc5a0785f9/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/exp/typeparams v0.0.0-20240613232115-7f521ea00fb8 h1:+ZJmEdDFzH5H0CnzOrwgbH3elHctfTecW9X0k2tkn5M= @@ -798,8 +800,8 @@ golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.16.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0= -golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= +golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -824,8 +826,8 @@ golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/net v0.16.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= -golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= -golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= +golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= +golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -874,8 +876,8 @@ golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= -golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= +golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -889,8 +891,8 @@ golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= -golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA= -golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= +golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= +golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -942,8 +944,8 @@ golang.org/x/tools v0.11.0/go.mod h1:anzJrxPjNtfgiYQYirP2CPGzGLxrH2u2QBhn6Bf3qY8 golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= golang.org/x/tools v0.19.0/go.mod h1:qoJWxmGSIBmAeriMx19ogtrEPrGtDbPK634QFIcLAhc= -golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA= -golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c= +golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= +golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From c2bdd619976ab40b647535dbaa0f6ec8242bd627 Mon Sep 17 00:00:00 2001 From: Andrei Vukolov Date: Fri, 2 Aug 2024 12:30:29 +0200 Subject: [PATCH 1115/1212] Documented unofficial Ubuntu PPA Documented unofficial installation package located in Ubuntu PPA maintained by @twdragon --- README.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/README.md b/README.md index d2ff46a93..726ab99a5 100644 --- a/README.md +++ b/README.md @@ -78,6 +78,7 @@ Before opening an issue, consider using one of the following locations to ensure - [openSUSE](#opensuse) - [Guix](#guix) - [Snap](#snap) + - [Ubuntu PPA](#ubuntu-ppa) - [Unofficial Windows packages](#unofficial-windows-packages) - [Chocolatey](#chocolatey) - [Scoop](#scoop) @@ -203,6 +204,7 @@ $ ipfs get /ipns/dist.ipfs.tech/kubo/$VERSION/kubo_$VERSION_windows-amd64.zip - [openSUSE](#opensuse) - [Guix](#guix) - [Snap](#snap) +- [Ubuntu PPA](#ubuntu-ppa) #### Arch Linux @@ -246,6 +248,31 @@ You can also install it through the Solus software center. No longer supported, see rationale in [kubo#8688](https://github.com/ipfs/kubo/issues/8688). +#### Ubuntu PPA + +[PPA homepage](https://launchpad.net/~twdragon/+archive/ubuntu/ipfs) on Launchpad. + +##### Latest Ubuntu (>= 20.04 LTS) +```sh +sudo add-apt-repository ppa:twdragon/ipfs +sudo apt update +sudo apt install ipfs-kubo +``` + +##### Any Ubuntu version + +```sh +sudo su +echo 'deb https://ppa.launchpadcontent.net/twdragon/ipfs/ubuntu <> main' >> /etc/apt/sources.list.d/ipfs +echo 'deb-src https://ppa.launchpadcontent.net/twdragon/ipfs/ubuntu <> main' >> /etc/apt/sources.list.d/ipfs +exit +sudo apt update +sudo apt install ipfs-kubo +``` +where `<>` is the codename of your Ubuntu distribution (for example, `jammy` for 22.04 LTS). During the first installation the package maintenance script may automatically ask you about which networking profile, CPU accounting model, and/or existing node configuration file you want to use. + +**NOTE**: this method also may work with any compatible Debian-based distro which has `libc6` inside, and APT as a package manager. + ### Unofficial Windows packages - [Chocolatey](#chocolatey) From feef0851bd2e32bc2dd5e6b2f9749ae0bb562302 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Tue, 6 Aug 2024 21:25:27 +0200 Subject: [PATCH 1116/1212] feat: go-libp2p 0.36 and /webrtc-direct listener (#10463) Co-authored-by: Marco Munizaga --- config/init.go | 2 + core/coreunix/metadata_test.go | 4 +- core/node/libp2p/transport.go | 2 +- docs/changelogs/v0.30.md | 12 ++++ docs/config.md | 39 +++++++------ docs/examples/kubo-as-a-library/go.mod | 27 ++++----- docs/examples/kubo-as-a-library/go.sum | 80 +++++++++++--------------- fuse/ipns/ipns_test.go | 4 +- fuse/readonly/ipfs_test.go | 4 +- go.mod | 28 ++++----- go.sum | 80 +++++++++++--------------- repo/fsrepo/fsrepo.go | 2 +- repo/fsrepo/migrations/fetcher.go | 2 +- test/cli/transports_test.go | 8 ++- test/dependencies/go.mod | 4 +- test/dependencies/go.sum | 56 +++++++++--------- 16 files changed, 183 insertions(+), 171 deletions(-) diff --git a/config/init.go b/config/init.go index e3d0af30d..4a86aa518 100644 --- a/config/init.go +++ b/config/init.go @@ -112,8 +112,10 @@ func addressesConfig() Addresses { Swarm: []string{ "/ip4/0.0.0.0/tcp/4001", "/ip6/::/tcp/4001", + "/ip4/0.0.0.0/udp/4001/webrtc-direct", "/ip4/0.0.0.0/udp/4001/quic-v1", "/ip4/0.0.0.0/udp/4001/quic-v1/webtransport", + "/ip6/::/udp/4001/webrtc-direct", "/ip6/::/udp/4001/quic-v1", "/ip6/::/udp/4001/quic-v1/webtransport", }, diff --git a/core/coreunix/metadata_test.go b/core/coreunix/metadata_test.go index b40f010db..c7d1b94db 100644 --- a/core/coreunix/metadata_test.go +++ b/core/coreunix/metadata_test.go @@ -16,11 +16,11 @@ import ( bstore "github.com/ipfs/boxo/blockstore" chunker "github.com/ipfs/boxo/chunker" offline "github.com/ipfs/boxo/exchange/offline" - u "github.com/ipfs/boxo/util" cid "github.com/ipfs/go-cid" ds "github.com/ipfs/go-datastore" dssync "github.com/ipfs/go-datastore/sync" ipld "github.com/ipfs/go-ipld-format" + "github.com/ipfs/go-test/random" ) func getDagserv(t *testing.T) ipld.DAGService { @@ -35,7 +35,7 @@ func TestMetadata(t *testing.T) { // Make some random node ds := getDagserv(t) data := make([]byte, 1000) - _, err := io.ReadFull(u.NewTimeSeededRand(), data) + _, err := io.ReadFull(random.NewRand(), data) if err != nil { t.Fatal(err) } diff --git a/core/node/libp2p/transport.go b/core/node/libp2p/transport.go index 797917b72..6628adc32 100644 --- a/core/node/libp2p/transport.go +++ b/core/node/libp2p/transport.go @@ -50,7 +50,7 @@ func Transports(tptConfig config.Transports) interface{} { opts.Opts = append(opts.Opts, libp2p.Transport(webtransport.New)) } - if tptConfig.Network.WebRTCDirect.WithDefault(false) { + if tptConfig.Network.WebRTCDirect.WithDefault(!privateNetworkEnabled) { if privateNetworkEnabled { return opts, fmt.Errorf( "WebRTC Direct transport does not support private networks, please disable Swarm.Transports.Network.WebRTCDirect", diff --git a/docs/changelogs/v0.30.md b/docs/changelogs/v0.30.md index 8457662bf..aa870c0ad 100644 --- a/docs/changelogs/v0.30.md +++ b/docs/changelogs/v0.30.md @@ -6,6 +6,7 @@ - [Overview](#overview) - [🔦 Highlights](#-highlights) + - [WebRTC-Direct Transport enabled by default](#webrtc-direct-transport-enabled-by-default) - [Automated `ipfs version check`](#automated-ipfs-version-check) - [Version Suffix Configuration](#version-suffix-configuration) - [📝 Changelog](#-changelog) @@ -15,6 +16,17 @@ ### 🔦 Highlights +#### WebRTC-Direct Transport enabled by default + +Kubo now ships with `/udp/4001/webrtc-direct` listener enabled by default. + +WebRTC Direct complements existing `/wss` (Secure WebSockets) and `/webtransport` transports. Unlike `/wss`, which requires a domain name and a CA-issued TLS certificate, WebRTC Direct works with IPs and can be enabled by default on all Kubo nodes. + +Learn more: [`Swarm.Transports.Network.WebRTCDirect`](https://github.com/ipfs/kubo/blob/master/docs/config.md#swarmtransportsnetworkwebrtcdirect) + +> [!NOTE] +> Kubo 0.30 includes a migration for existing users that adds `/webrtc-direct` listener on the same UDP port as `/udp/{port}/quic-v1`. This supports the WebRTC-Direct rollout by reusing preexisting UDP firewall settings and port mappings created for QUIC. + #### Automated `ipfs version check` Kubo now performs privacy-preserving version checks using the [libp2p identify protocol](https://github.com/libp2p/specs/blob/master/identify/README.md) on peers detected by the Amino DHT client. diff --git a/docs/config.md b/docs/config.md index c7355072d..8a09b7fe0 100644 --- a/docs/config.md +++ b/docs/config.md @@ -2144,7 +2144,7 @@ Configuration section for libp2p _network_ transports. Transports enabled in this section will be used for dialing. However, to receive connections on these transports, multiaddrs for these transports must be added to `Addresses.Swarm`. -Supported transports are: QUIC, TCP, WS, Relay and WebTransport. +Supported transports are: QUIC, TCP, WS, Relay, WebTransport and WebRTCDirect. Each field in this section is a `flag`. @@ -2195,8 +2195,8 @@ Default: Enabled Type: `flag` Listen Addresses: -* /ip4/0.0.0.0/udp/4001/quic-v1 (default) -* /ip6/::/udp/4001/quic-v1 (default) +- `/ip4/0.0.0.0/udp/4001/quic-v1` (default) +- `/ip6/::/udp/4001/quic-v1` (default) #### `Swarm.Transports.Network.Relay` @@ -2243,33 +2243,40 @@ Default: Enabled Type: `flag` -#### `Swarm.Transports.Network.WebRTCDirect` +Listen Addresses: +- `/ip4/0.0.0.0/udp/4001/quic-v1/webtransport` (default) +- `/ip6/::/udp/4001/quic-v1/webtransport` (default) -**Experimental:** the support for WebRTC Direct is currently experimental. -This feature was introduced in [`go-libp2p@v0.32.0`](https://github.com/libp2p/go-libp2p/releases/tag/v0.32.0). +#### `Swarm.Transports.Network.WebRTCDirect` [WebRTC Direct](https://github.com/libp2p/specs/blob/master/webrtc/webrtc-direct.md) is a transport protocol that provides another way for browsers to connect to the rest of the libp2p network. WebRTC Direct allows for browser nodes to connect to other nodes without special configuration, such as TLS certificates. This can be useful for browser nodes that do not yet support -[WebTransport](https://blog.libp2p.io/2022-12-19-libp2p-webtransport/). +[WebTransport](https://blog.libp2p.io/2022-12-19-libp2p-webtransport/), +which is still relatively new and has [known issues](https://github.com/libp2p/js-libp2p/issues/2572). -Enabling this transport allows Kubo node to act on `/udp/4002/webrtc-direct` +Enabling this transport allows Kubo node to act on `/udp/4001/webrtc-direct` listeners defined in `Addresses.Swarm`, `Addresses.Announce` or -`Addresses.AppendAnnounce`. At the moment, WebRTC Direct doesn't support listening on the same port as a QUIC or WebTransport listener +`Addresses.AppendAnnounce`. -**NOTE:** at the moment, WebRTC Direct cannot be used to connect to a browser -node to a node that is behind a NAT or firewall. -This requires using normal -[WebRTC](https://github.com/libp2p/specs/blob/master/webrtc/webrtc.md), -which is currently being worked on in -[go-libp2p#2009](https://github.com/libp2p/go-libp2p/issues/2009). +> [!NOTE] +> WebRTC Direct is browser-to-node. It cannot be used to connect a browser +> node to a node that is behind a NAT or firewall (without UPnP port mapping). +> The browser-to-private requires using normal +> [WebRTC](https://github.com/libp2p/specs/blob/master/webrtc/webrtc.md), +> which is currently being worked on in +> [go-libp2p#2009](https://github.com/libp2p/go-libp2p/issues/2009). -Default: Disabled +Default: Enabled Type: `flag` +Listen Addresses: +- `/ip4/0.0.0.0/udp/4001/webrtc-direct` (default) +- `/ip6/::/udp/4001/webrtc-direct` (default) + ### `Swarm.Transports.Security` Configuration section for libp2p _security_ transports. Transports enabled in diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index bdeee3bf8..a4f79ae44 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -9,9 +9,9 @@ toolchain go1.22.0 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.21.1-0.20240730141506-8e51658f8a1b + github.com/ipfs/boxo v0.21.1-0.20240806135911-08d5663d293c github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 - github.com/libp2p/go-libp2p v0.35.4 + github.com/libp2p/go-libp2p v0.36.1 github.com/multiformats/go-multiaddr v0.13.0 ) @@ -54,7 +54,7 @@ require ( github.com/golang/protobuf v1.5.4 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/gopacket v1.1.19 // indirect - github.com/google/pprof v0.0.0-20240618054019-d3b898a103f8 // indirect + github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 // indirect github.com/google/uuid v1.6.0 // indirect github.com/gorilla/websocket v1.5.3 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect @@ -141,28 +141,28 @@ require ( github.com/multiformats/go-multistream v0.5.0 // indirect github.com/multiformats/go-varint v0.0.7 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/onsi/ginkgo/v2 v2.19.0 // indirect + github.com/onsi/ginkgo/v2 v2.19.1 // indirect github.com/opencontainers/runtime-spec v1.2.0 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/openzipkin/zipkin-go v0.4.3 // indirect github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 // indirect - github.com/pion/datachannel v1.5.6 // indirect - github.com/pion/dtls/v2 v2.2.11 // indirect - github.com/pion/ice/v2 v2.3.25 // indirect + github.com/pion/datachannel v1.5.8 // indirect + github.com/pion/dtls/v2 v2.2.12 // indirect + github.com/pion/ice/v2 v2.3.32 // indirect github.com/pion/interceptor v0.1.29 // indirect github.com/pion/logging v0.2.2 // indirect github.com/pion/mdns v0.0.12 // indirect github.com/pion/randutil v0.1.0 // indirect github.com/pion/rtcp v1.2.14 // indirect - github.com/pion/rtp v1.8.6 // indirect - github.com/pion/sctp v1.8.16 // indirect + github.com/pion/rtp v1.8.8 // indirect + github.com/pion/sctp v1.8.20 // indirect github.com/pion/sdp/v3 v3.0.9 // indirect - github.com/pion/srtp/v2 v2.0.18 // indirect + github.com/pion/srtp/v2 v2.0.20 // indirect github.com/pion/stun v0.6.1 // indirect - github.com/pion/transport/v2 v2.2.5 // indirect + github.com/pion/transport/v2 v2.2.9 // indirect github.com/pion/turn/v2 v2.1.6 // indirect - github.com/pion/webrtc/v3 v3.2.42 // indirect + github.com/pion/webrtc/v3 v3.2.50 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/polydawn/refmt v0.89.0 // indirect @@ -171,7 +171,7 @@ require ( github.com/prometheus/common v0.55.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/quic-go/qpack v0.4.0 // indirect - github.com/quic-go/quic-go v0.45.0 // indirect + github.com/quic-go/quic-go v0.45.2 // indirect github.com/quic-go/webtransport-go v0.8.0 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/samber/lo v1.46.0 // indirect @@ -185,6 +185,7 @@ require ( github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f // indirect github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 // indirect + github.com/wlynxg/anet v0.0.3 // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.52.0 // indirect go.opentelemetry.io/otel v1.28.0 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index c2813c4dc..49c78ffd9 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -218,8 +218,8 @@ github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXi github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20240618054019-d3b898a103f8 h1:ASJ/LAqdCHOyMYI+dwNxn7Rd8FscNkMyTr1KZU1JI/M= -github.com/google/pprof v0.0.0-20240618054019-d3b898a103f8/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= +github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 h1:FKHo8hFI3A+7w0aUQuYXQ+6EN5stWmeY/AZqtM8xk9k= +github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -266,8 +266,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.21.1-0.20240730141506-8e51658f8a1b h1:vH+ly+ghScnm4fDTsFnRkWIqZ0Vux6U3aOzPc3bQsOM= -github.com/ipfs/boxo v0.21.1-0.20240730141506-8e51658f8a1b/go.mod h1:NmweAYeY1USOaJJxouy7DLr/Y5M8UBSsCI2KRivO+TY= +github.com/ipfs/boxo v0.21.1-0.20240806135911-08d5663d293c h1:HUYj1w1hVsiceE0FLcMlkQfo4+Ioz7G/X0WXPzzZWHs= +github.com/ipfs/boxo v0.21.1-0.20240806135911-08d5663d293c/go.mod h1:yp1loimX0BDYOR0cyjtcXHv15muEh5V1FqO2QLlzykw= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= @@ -352,6 +352,8 @@ github.com/ipfs/go-metrics-interface v0.0.1 h1:j+cpbjYvu4R8zbleSs36gvB7jR+wsL2fG github.com/ipfs/go-metrics-interface v0.0.1/go.mod h1:6s6euYU4zowdslK0GKHmqaIZ3j/b/tL7HTWtJ4VPgWY= github.com/ipfs/go-peertaskqueue v0.8.1 h1:YhxAs1+wxb5jk7RvS0LHdyiILpNmRIRnZVztekOF0pg= github.com/ipfs/go-peertaskqueue v0.8.1/go.mod h1:Oxxd3eaK279FxeydSPPVGHzbwVeHjatZ2GA8XD+KbPU= +github.com/ipfs/go-test v0.0.4 h1:DKT66T6GBB6PsDFLoO56QZPrOmzJkqU1FZH5C9ySkew= +github.com/ipfs/go-test v0.0.4/go.mod h1:qhIM1EluEfElKKM6fnWxGn822/z9knUGM1+I/OAQNKI= github.com/ipfs/go-unixfs v0.4.5 h1:wj8JhxvV1G6CD7swACwSKYa+NgtdWC1RUit+gFnymDU= github.com/ipfs/go-unixfs v0.4.5/go.mod h1:BIznJNvt/gEx/ooRMI4Us9K8+qeGO7vx1ohnbk8gjFg= github.com/ipfs/go-unixfsnode v1.9.0 h1:ubEhQhr22sPAKO2DNsyVBW7YB/zA8Zkif25aBvz8rc8= @@ -427,8 +429,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.35.4 h1:FDiBUYLkueFwsuNJUZaxKRdpKvBOWU64qQPL768bSeg= -github.com/libp2p/go-libp2p v0.35.4/go.mod h1:RKCDNt30IkFipGL0tl8wQW/3zVWEGFUZo8g2gAKxwjU= +github.com/libp2p/go-libp2p v0.36.1 h1:piAHesy0/8ifBEBUS8HF2m7ywR5vnktUFv00dTsVKcs= +github.com/libp2p/go-libp2p v0.36.1/go.mod h1:vHzel3CpRB+vS11fIjZSJAU4ALvieKV9VZHC9VerHj8= github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94= github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= @@ -563,13 +565,13 @@ github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108 github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.19.0 h1:9Cnnf7UHo57Hy3k6/m5k3dRfGTMXGvxhHFvkDTCTpvA= -github.com/onsi/ginkgo/v2 v2.19.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To= +github.com/onsi/ginkgo/v2 v2.19.1 h1:QXgq3Z8Crl5EL1WBAC98A5sEBHARrAJNzAmMxzLcRF0= +github.com/onsi/ginkgo/v2 v2.19.1/go.mod h1:O3DtEWQkPa/F7fBMgmZQKKsluAy8pd3rEQdrjkPb9zA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk= -github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0= +github.com/onsi/gomega v1.34.0 h1:eSSPsPNp6ZpsG8X1OVmOTxig+CblTc4AxpPBykhe2Os= +github.com/onsi/gomega v1.34.0/go.mod h1:MIKI8c+f+QLWk+hxbePD4i0LMJSExPaZOVfkoex4cAo= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.2.0 h1:z97+pHb3uELt/yiAWD691HNHQIF07bE7dzrbT927iTk= github.com/opencontainers/runtime-spec v1.2.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= @@ -585,13 +587,13 @@ github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhM github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 h1:1/WtZae0yGtPq+TI6+Tv1WTxkukpXeMlviSxvL7SRgk= github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9/go.mod h1:x3N5drFsm2uilKKuuYo6LdyD8vZAW55sH/9w+pbo1sw= -github.com/pion/datachannel v1.5.6 h1:1IxKJntfSlYkpUj8LlYRSWpYiTTC02nUrOE8T3DqGeg= -github.com/pion/datachannel v1.5.6/go.mod h1:1eKT6Q85pRnr2mHiWHxJwO50SfZRtWHTsNIVb/NfGW4= +github.com/pion/datachannel v1.5.8 h1:ph1P1NsGkazkjrvyMfhRBUAWMxugJjq2HfQifaOoSNo= +github.com/pion/datachannel v1.5.8/go.mod h1:PgmdpoaNBLX9HNzNClmdki4DYW5JtI7Yibu8QzbL3tI= github.com/pion/dtls/v2 v2.2.7/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s= -github.com/pion/dtls/v2 v2.2.11 h1:9U/dpCYl1ySttROPWJgqWKEylUdT0fXp/xst6JwY5Ks= -github.com/pion/dtls/v2 v2.2.11/go.mod h1:d9SYc9fch0CqK90mRk1dC7AkzzpwJj6u2GU3u+9pqFE= -github.com/pion/ice/v2 v2.3.25 h1:M5rJA07dqhi3nobJIg+uPtcVjFECTrhcR3n0ns8kDZs= -github.com/pion/ice/v2 v2.3.25/go.mod h1:KXJJcZK7E8WzrBEYnV4UtqEZsGeWfHxsNqhVcVvgjxw= +github.com/pion/dtls/v2 v2.2.12 h1:KP7H5/c1EiVAAKUmXyCzPiQe5+bCJrpOeKg/L05dunk= +github.com/pion/dtls/v2 v2.2.12/go.mod h1:d9SYc9fch0CqK90mRk1dC7AkzzpwJj6u2GU3u+9pqFE= +github.com/pion/ice/v2 v2.3.32 h1:VwE/uEeqiMm0zUWpdt1DJtnqEkj3UjEbhX92/CurtWI= +github.com/pion/ice/v2 v2.3.32/go.mod h1:8fac0+qftclGy1tYd/nfwfHC729BLaxtVqMdMVCAVPU= github.com/pion/interceptor v0.1.29 h1:39fsnlP1U8gw2JzOFWdfCU82vHvhW9o0rZnZF56wF+M= github.com/pion/interceptor v0.1.29/go.mod h1:ri+LGNjRUc5xUNtDEPzfdkmSqISixVTBF/z/Zms/6T4= github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY= @@ -604,31 +606,30 @@ github.com/pion/rtcp v1.2.12/go.mod h1:sn6qjxvnwyAkkPzPULIbVqSKI5Dv54Rv7VG0kNxh9 github.com/pion/rtcp v1.2.14 h1:KCkGV3vJ+4DAJmvP0vaQShsb0xkRfWkO540Gy102KyE= github.com/pion/rtcp v1.2.14/go.mod h1:sn6qjxvnwyAkkPzPULIbVqSKI5Dv54Rv7VG0kNxh9L4= github.com/pion/rtp v1.8.3/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU= -github.com/pion/rtp v1.8.6 h1:MTmn/b0aWWsAzux2AmP8WGllusBVw4NPYPVFFd7jUPw= -github.com/pion/rtp v1.8.6/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU= -github.com/pion/sctp v1.8.13/go.mod h1:YKSgO/bO/6aOMP9LCie1DuD7m+GamiK2yIiPM6vH+GA= -github.com/pion/sctp v1.8.16 h1:PKrMs+o9EMLRvFfXq59WFsC+V8mN1wnKzqrv+3D/gYY= -github.com/pion/sctp v1.8.16/go.mod h1:P6PbDVA++OJMrVNg2AL3XtYHV4uD6dvfyOovCgMs0PE= +github.com/pion/rtp v1.8.8 h1:EtYFHI0rpUEjT/RMnGfb1vdJhbYmPG77szD72uUnSxs= +github.com/pion/rtp v1.8.8/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU= +github.com/pion/sctp v1.8.20 h1:sOc3lkV/tQaP57ZUEXIMdM2V92IIB2ia5v/ygnBxaEg= +github.com/pion/sctp v1.8.20/go.mod h1:oTxw8i5m+WbDHZJL/xUpe6CPIn1Y0GIKKwTLF4h53H8= github.com/pion/sdp/v3 v3.0.9 h1:pX++dCHoHUwq43kuwf3PyJfHlwIj4hXA7Vrifiq0IJY= github.com/pion/sdp/v3 v3.0.9/go.mod h1:B5xmvENq5IXJimIO4zfp6LAe1fD9N+kFv+V/1lOdz8M= -github.com/pion/srtp/v2 v2.0.18 h1:vKpAXfawO9RtTRKZJbG4y0v1b11NZxQnxRl85kGuUlo= -github.com/pion/srtp/v2 v2.0.18/go.mod h1:0KJQjA99A6/a0DOVTu1PhDSw0CXF2jTkqOoMg3ODqdA= +github.com/pion/srtp/v2 v2.0.20 h1:HNNny4s+OUmG280ETrCdgFndp4ufx3/uy85EawYEhTk= +github.com/pion/srtp/v2 v2.0.20/go.mod h1:0KJQjA99A6/a0DOVTu1PhDSw0CXF2jTkqOoMg3ODqdA= github.com/pion/stun v0.6.1 h1:8lp6YejULeHBF8NmV8e2787BogQhduZugh5PdhDyyN4= github.com/pion/stun v0.6.1/go.mod h1:/hO7APkX4hZKu/D0f2lHzNyvdkTGtIy3NDmLR7kSz/8= github.com/pion/transport/v2 v2.2.1/go.mod h1:cXXWavvCnFF6McHTft3DWS9iic2Mftcz1Aq29pGcU5g= -github.com/pion/transport/v2 v2.2.2/go.mod h1:OJg3ojoBJopjEeECq2yJdXH9YVrUJ1uQ++NjXLOUorc= github.com/pion/transport/v2 v2.2.3/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0= github.com/pion/transport/v2 v2.2.4/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0= -github.com/pion/transport/v2 v2.2.5 h1:iyi25i/21gQck4hfRhomF6SktmUQjRsRW4WJdhfc3Kc= -github.com/pion/transport/v2 v2.2.5/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0= +github.com/pion/transport/v2 v2.2.8/go.mod h1:sq1kSLWs+cHW9E+2fJP95QudkzbK7wscs8yYgQToO5E= +github.com/pion/transport/v2 v2.2.9 h1:WEDygVovkJlV2CCunM9KS2kds+kcl7zdIefQA5y/nkE= +github.com/pion/transport/v2 v2.2.9/go.mod h1:sq1kSLWs+cHW9E+2fJP95QudkzbK7wscs8yYgQToO5E= github.com/pion/transport/v3 v3.0.1/go.mod h1:UY7kiITrlMv7/IKgd5eTUcaahZx5oUN3l9SzK5f5xE0= -github.com/pion/transport/v3 v3.0.2 h1:r+40RJR25S9w3jbA6/5uEPTzcdn7ncyU44RWCbHkLg4= -github.com/pion/transport/v3 v3.0.2/go.mod h1:nIToODoOlb5If2jF9y2Igfx3PFYWfuXi37m0IlWa/D0= +github.com/pion/transport/v3 v3.0.6 h1:k1mQU06bmmX143qSWgXFqSH1KUJceQvIUuVH/K5ELWw= +github.com/pion/transport/v3 v3.0.6/go.mod h1:HvJr2N/JwNJAfipsRleqwFoR3t/pWyHeZUs89v3+t5s= github.com/pion/turn/v2 v2.1.3/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY= github.com/pion/turn/v2 v2.1.6 h1:Xr2niVsiPTB0FPtt+yAWKFUkU1eotQbGgpTIld4x1Gc= github.com/pion/turn/v2 v2.1.6/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY= -github.com/pion/webrtc/v3 v3.2.42 h1:WN/ZuMjtpQOoGRCZUg/zFG+JHEvYLVyDKOxU6H1qWlE= -github.com/pion/webrtc/v3 v3.2.42/go.mod h1:M1RAe3TNTD1tzyvqHrbVODfwdPGSXOUo/OgpoGGJqFY= +github.com/pion/webrtc/v3 v3.2.50 h1:C/rwL2mBfCxHv6tlLzDAO3krJpQXfVx8A8WHnGJ2j34= +github.com/pion/webrtc/v3 v3.2.50/go.mod h1:dytYYoSBy7ZUWhJMbndx9UckgYvzNAfL7xgVnrIKxqo= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -652,8 +653,8 @@ github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0leargg github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= -github.com/quic-go/quic-go v0.45.0 h1:OHmkQGM37luZITyTSu6ff03HP/2IrwDX1ZFiNEhSFUE= -github.com/quic-go/quic-go v0.45.0/go.mod h1:1dLehS7TIR64+vxGR70GDcatWTOtMX2PUtnKsjbTurI= +github.com/quic-go/quic-go v0.45.2 h1:DfqBmqjb4ExSdxRIb/+qXhPC+7k6+DUNZha4oeiC9fY= +github.com/quic-go/quic-go v0.45.2/go.mod h1:1dLehS7TIR64+vxGR70GDcatWTOtMX2PUtnKsjbTurI= github.com/quic-go/webtransport-go v0.8.0 h1:HxSrwun11U+LlmwpgM1kEqIqH90IT4N8auv/cD7QFJg= github.com/quic-go/webtransport-go v0.8.0/go.mod h1:N99tjprW432Ut5ONql/aUhSLT0YVSlwHohQsuac9WaM= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= @@ -766,6 +767,8 @@ github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 h1:E9S12nwJwEOXe2d6gT6qxdvqMnNq+VnSsKPgm2ZZNds= github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7/go.mod h1:X2c0RVCI1eSUFI8eLcY3c0423ykwiUdxLJtkDvruhjI= +github.com/wlynxg/anet v0.0.3 h1:PvR53psxFXstc12jelG6f1Lv4MWqE0tI76/hHGjh9rg= +github.com/wlynxg/anet v0.0.3/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA= github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -850,11 +853,8 @@ golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWP golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= -golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= -golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= -golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -925,11 +925,8 @@ golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= -golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= -golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1003,11 +1000,8 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= @@ -1016,11 +1010,8 @@ golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuX golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= -golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= -golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= -golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1030,7 +1021,6 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= diff --git a/fuse/ipns/ipns_test.go b/fuse/ipns/ipns_test.go index d26e78c4d..ece386bf7 100644 --- a/fuse/ipns/ipns_test.go +++ b/fuse/ipns/ipns_test.go @@ -19,8 +19,8 @@ import ( coreapi "github.com/ipfs/kubo/core/coreapi" fstest "bazil.org/fuse/fs/fstestutil" - u "github.com/ipfs/boxo/util" racedet "github.com/ipfs/go-detect-race" + "github.com/ipfs/go-test/random" ci "github.com/libp2p/go-libp2p-testing/ci" ) @@ -32,7 +32,7 @@ func maybeSkipFuseTests(t *testing.T) { func randBytes(size int) []byte { b := make([]byte, size) - _, err := io.ReadFull(u.NewTimeSeededRand(), b) + _, err := io.ReadFull(random.NewRand(), b) if err != nil { panic(err) } diff --git a/fuse/readonly/ipfs_test.go b/fuse/readonly/ipfs_test.go index 385ae1272..6d667843c 100644 --- a/fuse/readonly/ipfs_test.go +++ b/fuse/readonly/ipfs_test.go @@ -29,8 +29,8 @@ import ( importer "github.com/ipfs/boxo/ipld/unixfs/importer" uio "github.com/ipfs/boxo/ipld/unixfs/io" "github.com/ipfs/boxo/path" - u "github.com/ipfs/boxo/util" ipld "github.com/ipfs/go-ipld-format" + "github.com/ipfs/go-test/random" ci "github.com/libp2p/go-libp2p-testing/ci" ) @@ -42,7 +42,7 @@ func maybeSkipFuseTests(t *testing.T) { func randObj(t *testing.T, nd *core.IpfsNode, size int64) (ipld.Node, []byte) { buf := make([]byte, size) - _, err := io.ReadFull(u.NewTimeSeededRand(), buf) + _, err := io.ReadFull(random.NewRand(), buf) if err != nil { t.Fatal(err) } diff --git a/go.mod b/go.mod index 1492b46eb..a68916313 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( github.com/hashicorp/go-version v1.6.0 github.com/ipfs-shipyard/nopfs v0.0.12 github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c - github.com/ipfs/boxo v0.21.1-0.20240730141506-8e51658f8a1b + github.com/ipfs/boxo v0.21.1-0.20240806135911-08d5663d293c github.com/ipfs/go-block-format v0.2.0 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 @@ -38,6 +38,7 @@ require ( github.com/ipfs/go-log/v2 v2.5.1 github.com/ipfs/go-metrics-interface v0.0.1 github.com/ipfs/go-metrics-prometheus v0.0.2 + github.com/ipfs/go-test v0.0.4 github.com/ipfs/go-unixfsnode v1.9.0 github.com/ipld/go-car v0.6.2 github.com/ipld/go-car/v2 v2.13.1 @@ -48,7 +49,7 @@ require ( github.com/jbenet/goprocess v0.1.4 github.com/julienschmidt/httprouter v1.3.0 github.com/libp2p/go-doh-resolver v0.4.0 - github.com/libp2p/go-libp2p v0.35.4 + github.com/libp2p/go-libp2p v0.36.1 github.com/libp2p/go-libp2p-http v0.5.0 github.com/libp2p/go-libp2p-kad-dht v0.25.2 github.com/libp2p/go-libp2p-kbucket v0.6.3 @@ -124,7 +125,7 @@ require ( github.com/golang/protobuf v1.5.4 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/gopacket v1.1.19 // indirect - github.com/google/pprof v0.0.0-20240618054019-d3b898a103f8 // indirect + github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 // indirect github.com/gorilla/mux v1.8.1 // indirect github.com/gorilla/websocket v1.5.3 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect @@ -178,26 +179,26 @@ require ( github.com/multiformats/go-multistream v0.5.0 // indirect github.com/multiformats/go-varint v0.0.7 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/onsi/ginkgo/v2 v2.19.0 // indirect + github.com/onsi/ginkgo/v2 v2.19.1 // indirect github.com/opencontainers/runtime-spec v1.2.0 // indirect github.com/openzipkin/zipkin-go v0.4.3 // indirect github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 // indirect - github.com/pion/datachannel v1.5.6 // indirect - github.com/pion/dtls/v2 v2.2.11 // indirect - github.com/pion/ice/v2 v2.3.25 // indirect + github.com/pion/datachannel v1.5.8 // indirect + github.com/pion/dtls/v2 v2.2.12 // indirect + github.com/pion/ice/v2 v2.3.32 // indirect github.com/pion/interceptor v0.1.29 // indirect github.com/pion/logging v0.2.2 // indirect github.com/pion/mdns v0.0.12 // indirect github.com/pion/randutil v0.1.0 // indirect github.com/pion/rtcp v1.2.14 // indirect - github.com/pion/rtp v1.8.6 // indirect - github.com/pion/sctp v1.8.16 // indirect + github.com/pion/rtp v1.8.8 // indirect + github.com/pion/sctp v1.8.20 // indirect github.com/pion/sdp/v3 v3.0.9 // indirect - github.com/pion/srtp/v2 v2.0.18 // indirect + github.com/pion/srtp/v2 v2.0.20 // indirect github.com/pion/stun v0.6.1 // indirect - github.com/pion/transport/v2 v2.2.5 // indirect + github.com/pion/transport/v2 v2.2.9 // indirect github.com/pion/turn/v2 v2.1.6 // indirect - github.com/pion/webrtc/v3 v3.2.42 // indirect + github.com/pion/webrtc/v3 v3.2.50 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/polydawn/refmt v0.89.0 // indirect @@ -206,7 +207,7 @@ require ( github.com/prometheus/procfs v0.15.1 // indirect github.com/prometheus/statsd_exporter v0.22.7 // indirect github.com/quic-go/qpack v0.4.0 // indirect - github.com/quic-go/quic-go v0.45.0 // indirect + github.com/quic-go/quic-go v0.45.2 // indirect github.com/quic-go/webtransport-go v0.8.0 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/rs/cors v1.10.1 // indirect @@ -221,6 +222,7 @@ require ( github.com/whyrusleeping/cbor-gen v0.1.2 // indirect github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f // indirect github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect + github.com/wlynxg/anet v0.0.3 // indirect go.opentelemetry.io/contrib/propagators/aws v1.21.1 // indirect go.opentelemetry.io/contrib/propagators/b3 v1.21.1 // indirect go.opentelemetry.io/contrib/propagators/jaeger v1.21.1 // indirect diff --git a/go.sum b/go.sum index 8f76df20a..8f59f5102 100644 --- a/go.sum +++ b/go.sum @@ -280,8 +280,8 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20240618054019-d3b898a103f8 h1:ASJ/LAqdCHOyMYI+dwNxn7Rd8FscNkMyTr1KZU1JI/M= -github.com/google/pprof v0.0.0-20240618054019-d3b898a103f8/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= +github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 h1:FKHo8hFI3A+7w0aUQuYXQ+6EN5stWmeY/AZqtM8xk9k= +github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -330,8 +330,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.21.1-0.20240730141506-8e51658f8a1b h1:vH+ly+ghScnm4fDTsFnRkWIqZ0Vux6U3aOzPc3bQsOM= -github.com/ipfs/boxo v0.21.1-0.20240730141506-8e51658f8a1b/go.mod h1:NmweAYeY1USOaJJxouy7DLr/Y5M8UBSsCI2KRivO+TY= +github.com/ipfs/boxo v0.21.1-0.20240806135911-08d5663d293c h1:HUYj1w1hVsiceE0FLcMlkQfo4+Ioz7G/X0WXPzzZWHs= +github.com/ipfs/boxo v0.21.1-0.20240806135911-08d5663d293c/go.mod h1:yp1loimX0BDYOR0cyjtcXHv15muEh5V1FqO2QLlzykw= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= @@ -422,6 +422,8 @@ github.com/ipfs/go-metrics-prometheus v0.0.2 h1:9i2iljLg12S78OhC6UAiXi176xvQGiZa github.com/ipfs/go-metrics-prometheus v0.0.2/go.mod h1:ELLU99AQQNi+zX6GCGm2lAgnzdSH3u5UVlCdqSXnEks= github.com/ipfs/go-peertaskqueue v0.8.1 h1:YhxAs1+wxb5jk7RvS0LHdyiILpNmRIRnZVztekOF0pg= github.com/ipfs/go-peertaskqueue v0.8.1/go.mod h1:Oxxd3eaK279FxeydSPPVGHzbwVeHjatZ2GA8XD+KbPU= +github.com/ipfs/go-test v0.0.4 h1:DKT66T6GBB6PsDFLoO56QZPrOmzJkqU1FZH5C9ySkew= +github.com/ipfs/go-test v0.0.4/go.mod h1:qhIM1EluEfElKKM6fnWxGn822/z9knUGM1+I/OAQNKI= github.com/ipfs/go-unixfs v0.4.5 h1:wj8JhxvV1G6CD7swACwSKYa+NgtdWC1RUit+gFnymDU= github.com/ipfs/go-unixfs v0.4.5/go.mod h1:BIznJNvt/gEx/ooRMI4Us9K8+qeGO7vx1ohnbk8gjFg= github.com/ipfs/go-unixfsnode v1.9.0 h1:ubEhQhr22sPAKO2DNsyVBW7YB/zA8Zkif25aBvz8rc8= @@ -508,8 +510,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.35.4 h1:FDiBUYLkueFwsuNJUZaxKRdpKvBOWU64qQPL768bSeg= -github.com/libp2p/go-libp2p v0.35.4/go.mod h1:RKCDNt30IkFipGL0tl8wQW/3zVWEGFUZo8g2gAKxwjU= +github.com/libp2p/go-libp2p v0.36.1 h1:piAHesy0/8ifBEBUS8HF2m7ywR5vnktUFv00dTsVKcs= +github.com/libp2p/go-libp2p v0.36.1/go.mod h1:vHzel3CpRB+vS11fIjZSJAU4ALvieKV9VZHC9VerHj8= github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94= github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= @@ -665,13 +667,13 @@ github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108 github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.19.0 h1:9Cnnf7UHo57Hy3k6/m5k3dRfGTMXGvxhHFvkDTCTpvA= -github.com/onsi/ginkgo/v2 v2.19.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To= +github.com/onsi/ginkgo/v2 v2.19.1 h1:QXgq3Z8Crl5EL1WBAC98A5sEBHARrAJNzAmMxzLcRF0= +github.com/onsi/ginkgo/v2 v2.19.1/go.mod h1:O3DtEWQkPa/F7fBMgmZQKKsluAy8pd3rEQdrjkPb9zA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk= -github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0= +github.com/onsi/gomega v1.34.0 h1:eSSPsPNp6ZpsG8X1OVmOTxig+CblTc4AxpPBykhe2Os= +github.com/onsi/gomega v1.34.0/go.mod h1:MIKI8c+f+QLWk+hxbePD4i0LMJSExPaZOVfkoex4cAo= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.2.0 h1:z97+pHb3uELt/yiAWD691HNHQIF07bE7dzrbT927iTk= github.com/opencontainers/runtime-spec v1.2.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= @@ -687,13 +689,13 @@ github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhM github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 h1:1/WtZae0yGtPq+TI6+Tv1WTxkukpXeMlviSxvL7SRgk= github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9/go.mod h1:x3N5drFsm2uilKKuuYo6LdyD8vZAW55sH/9w+pbo1sw= -github.com/pion/datachannel v1.5.6 h1:1IxKJntfSlYkpUj8LlYRSWpYiTTC02nUrOE8T3DqGeg= -github.com/pion/datachannel v1.5.6/go.mod h1:1eKT6Q85pRnr2mHiWHxJwO50SfZRtWHTsNIVb/NfGW4= +github.com/pion/datachannel v1.5.8 h1:ph1P1NsGkazkjrvyMfhRBUAWMxugJjq2HfQifaOoSNo= +github.com/pion/datachannel v1.5.8/go.mod h1:PgmdpoaNBLX9HNzNClmdki4DYW5JtI7Yibu8QzbL3tI= github.com/pion/dtls/v2 v2.2.7/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s= -github.com/pion/dtls/v2 v2.2.11 h1:9U/dpCYl1ySttROPWJgqWKEylUdT0fXp/xst6JwY5Ks= -github.com/pion/dtls/v2 v2.2.11/go.mod h1:d9SYc9fch0CqK90mRk1dC7AkzzpwJj6u2GU3u+9pqFE= -github.com/pion/ice/v2 v2.3.25 h1:M5rJA07dqhi3nobJIg+uPtcVjFECTrhcR3n0ns8kDZs= -github.com/pion/ice/v2 v2.3.25/go.mod h1:KXJJcZK7E8WzrBEYnV4UtqEZsGeWfHxsNqhVcVvgjxw= +github.com/pion/dtls/v2 v2.2.12 h1:KP7H5/c1EiVAAKUmXyCzPiQe5+bCJrpOeKg/L05dunk= +github.com/pion/dtls/v2 v2.2.12/go.mod h1:d9SYc9fch0CqK90mRk1dC7AkzzpwJj6u2GU3u+9pqFE= +github.com/pion/ice/v2 v2.3.32 h1:VwE/uEeqiMm0zUWpdt1DJtnqEkj3UjEbhX92/CurtWI= +github.com/pion/ice/v2 v2.3.32/go.mod h1:8fac0+qftclGy1tYd/nfwfHC729BLaxtVqMdMVCAVPU= github.com/pion/interceptor v0.1.29 h1:39fsnlP1U8gw2JzOFWdfCU82vHvhW9o0rZnZF56wF+M= github.com/pion/interceptor v0.1.29/go.mod h1:ri+LGNjRUc5xUNtDEPzfdkmSqISixVTBF/z/Zms/6T4= github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY= @@ -706,31 +708,30 @@ github.com/pion/rtcp v1.2.12/go.mod h1:sn6qjxvnwyAkkPzPULIbVqSKI5Dv54Rv7VG0kNxh9 github.com/pion/rtcp v1.2.14 h1:KCkGV3vJ+4DAJmvP0vaQShsb0xkRfWkO540Gy102KyE= github.com/pion/rtcp v1.2.14/go.mod h1:sn6qjxvnwyAkkPzPULIbVqSKI5Dv54Rv7VG0kNxh9L4= github.com/pion/rtp v1.8.3/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU= -github.com/pion/rtp v1.8.6 h1:MTmn/b0aWWsAzux2AmP8WGllusBVw4NPYPVFFd7jUPw= -github.com/pion/rtp v1.8.6/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU= -github.com/pion/sctp v1.8.13/go.mod h1:YKSgO/bO/6aOMP9LCie1DuD7m+GamiK2yIiPM6vH+GA= -github.com/pion/sctp v1.8.16 h1:PKrMs+o9EMLRvFfXq59WFsC+V8mN1wnKzqrv+3D/gYY= -github.com/pion/sctp v1.8.16/go.mod h1:P6PbDVA++OJMrVNg2AL3XtYHV4uD6dvfyOovCgMs0PE= +github.com/pion/rtp v1.8.8 h1:EtYFHI0rpUEjT/RMnGfb1vdJhbYmPG77szD72uUnSxs= +github.com/pion/rtp v1.8.8/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU= +github.com/pion/sctp v1.8.20 h1:sOc3lkV/tQaP57ZUEXIMdM2V92IIB2ia5v/ygnBxaEg= +github.com/pion/sctp v1.8.20/go.mod h1:oTxw8i5m+WbDHZJL/xUpe6CPIn1Y0GIKKwTLF4h53H8= github.com/pion/sdp/v3 v3.0.9 h1:pX++dCHoHUwq43kuwf3PyJfHlwIj4hXA7Vrifiq0IJY= github.com/pion/sdp/v3 v3.0.9/go.mod h1:B5xmvENq5IXJimIO4zfp6LAe1fD9N+kFv+V/1lOdz8M= -github.com/pion/srtp/v2 v2.0.18 h1:vKpAXfawO9RtTRKZJbG4y0v1b11NZxQnxRl85kGuUlo= -github.com/pion/srtp/v2 v2.0.18/go.mod h1:0KJQjA99A6/a0DOVTu1PhDSw0CXF2jTkqOoMg3ODqdA= +github.com/pion/srtp/v2 v2.0.20 h1:HNNny4s+OUmG280ETrCdgFndp4ufx3/uy85EawYEhTk= +github.com/pion/srtp/v2 v2.0.20/go.mod h1:0KJQjA99A6/a0DOVTu1PhDSw0CXF2jTkqOoMg3ODqdA= github.com/pion/stun v0.6.1 h1:8lp6YejULeHBF8NmV8e2787BogQhduZugh5PdhDyyN4= github.com/pion/stun v0.6.1/go.mod h1:/hO7APkX4hZKu/D0f2lHzNyvdkTGtIy3NDmLR7kSz/8= github.com/pion/transport/v2 v2.2.1/go.mod h1:cXXWavvCnFF6McHTft3DWS9iic2Mftcz1Aq29pGcU5g= -github.com/pion/transport/v2 v2.2.2/go.mod h1:OJg3ojoBJopjEeECq2yJdXH9YVrUJ1uQ++NjXLOUorc= github.com/pion/transport/v2 v2.2.3/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0= github.com/pion/transport/v2 v2.2.4/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0= -github.com/pion/transport/v2 v2.2.5 h1:iyi25i/21gQck4hfRhomF6SktmUQjRsRW4WJdhfc3Kc= -github.com/pion/transport/v2 v2.2.5/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0= +github.com/pion/transport/v2 v2.2.8/go.mod h1:sq1kSLWs+cHW9E+2fJP95QudkzbK7wscs8yYgQToO5E= +github.com/pion/transport/v2 v2.2.9 h1:WEDygVovkJlV2CCunM9KS2kds+kcl7zdIefQA5y/nkE= +github.com/pion/transport/v2 v2.2.9/go.mod h1:sq1kSLWs+cHW9E+2fJP95QudkzbK7wscs8yYgQToO5E= github.com/pion/transport/v3 v3.0.1/go.mod h1:UY7kiITrlMv7/IKgd5eTUcaahZx5oUN3l9SzK5f5xE0= -github.com/pion/transport/v3 v3.0.2 h1:r+40RJR25S9w3jbA6/5uEPTzcdn7ncyU44RWCbHkLg4= -github.com/pion/transport/v3 v3.0.2/go.mod h1:nIToODoOlb5If2jF9y2Igfx3PFYWfuXi37m0IlWa/D0= +github.com/pion/transport/v3 v3.0.6 h1:k1mQU06bmmX143qSWgXFqSH1KUJceQvIUuVH/K5ELWw= +github.com/pion/transport/v3 v3.0.6/go.mod h1:HvJr2N/JwNJAfipsRleqwFoR3t/pWyHeZUs89v3+t5s= github.com/pion/turn/v2 v2.1.3/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY= github.com/pion/turn/v2 v2.1.6 h1:Xr2niVsiPTB0FPtt+yAWKFUkU1eotQbGgpTIld4x1Gc= github.com/pion/turn/v2 v2.1.6/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY= -github.com/pion/webrtc/v3 v3.2.42 h1:WN/ZuMjtpQOoGRCZUg/zFG+JHEvYLVyDKOxU6H1qWlE= -github.com/pion/webrtc/v3 v3.2.42/go.mod h1:M1RAe3TNTD1tzyvqHrbVODfwdPGSXOUo/OgpoGGJqFY= +github.com/pion/webrtc/v3 v3.2.50 h1:C/rwL2mBfCxHv6tlLzDAO3krJpQXfVx8A8WHnGJ2j34= +github.com/pion/webrtc/v3 v3.2.50/go.mod h1:dytYYoSBy7ZUWhJMbndx9UckgYvzNAfL7xgVnrIKxqo= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -781,8 +782,8 @@ github.com/prometheus/statsd_exporter v0.22.7 h1:7Pji/i2GuhK6Lu7DHrtTkFmNBCudCPT github.com/prometheus/statsd_exporter v0.22.7/go.mod h1:N/TevpjkIh9ccs6nuzY3jQn9dFqnUakOjnEuMPJJJnI= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= -github.com/quic-go/quic-go v0.45.0 h1:OHmkQGM37luZITyTSu6ff03HP/2IrwDX1ZFiNEhSFUE= -github.com/quic-go/quic-go v0.45.0/go.mod h1:1dLehS7TIR64+vxGR70GDcatWTOtMX2PUtnKsjbTurI= +github.com/quic-go/quic-go v0.45.2 h1:DfqBmqjb4ExSdxRIb/+qXhPC+7k6+DUNZha4oeiC9fY= +github.com/quic-go/quic-go v0.45.2/go.mod h1:1dLehS7TIR64+vxGR70GDcatWTOtMX2PUtnKsjbTurI= github.com/quic-go/webtransport-go v0.8.0 h1:HxSrwun11U+LlmwpgM1kEqIqH90IT4N8auv/cD7QFJg= github.com/quic-go/webtransport-go v0.8.0/go.mod h1:N99tjprW432Ut5ONql/aUhSLT0YVSlwHohQsuac9WaM= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= @@ -914,6 +915,8 @@ github.com/whyrusleeping/go-sysinfo v0.0.0-20190219211824-4a357d4b90b1 h1:ctS9An github.com/whyrusleeping/go-sysinfo v0.0.0-20190219211824-4a357d4b90b1/go.mod h1:tKH72zYNt/exx6/5IQO6L9LoQ0rEjd5SbbWaDTs9Zso= github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 h1:E9S12nwJwEOXe2d6gT6qxdvqMnNq+VnSsKPgm2ZZNds= github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7/go.mod h1:X2c0RVCI1eSUFI8eLcY3c0423ykwiUdxLJtkDvruhjI= +github.com/wlynxg/anet v0.0.3 h1:PvR53psxFXstc12jelG6f1Lv4MWqE0tI76/hHGjh9rg= +github.com/wlynxg/anet v0.0.3/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA= github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -1012,11 +1015,8 @@ golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWP golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= -golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= -golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= -golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1107,11 +1107,8 @@ golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= -golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= -golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1214,11 +1211,8 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= @@ -1227,11 +1221,8 @@ golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuX golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= -golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= -golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= -golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1243,7 +1234,6 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= diff --git a/repo/fsrepo/fsrepo.go b/repo/fsrepo/fsrepo.go index 591d25aee..6e9e01dab 100644 --- a/repo/fsrepo/fsrepo.go +++ b/repo/fsrepo/fsrepo.go @@ -37,7 +37,7 @@ const LockFile = "repo.lock" var log = logging.Logger("fsrepo") // RepoVersion is the version number that we are currently expecting to see. -var RepoVersion = 15 +var RepoVersion = 16 var migrationInstructions = `See https://github.com/ipfs/fs-repo-migrations/blob/master/run.md Sorry for the inconvenience. In the future, these will run automatically.` diff --git a/repo/fsrepo/migrations/fetcher.go b/repo/fsrepo/migrations/fetcher.go index 880492b92..db7a5c0c1 100644 --- a/repo/fsrepo/migrations/fetcher.go +++ b/repo/fsrepo/migrations/fetcher.go @@ -11,7 +11,7 @@ import ( const ( // Current distribution to fetch migrations from. - CurrentIpfsDist = "/ipfs/QmZPedUiZNe6Gq9oDvoizuuCMVoeb7shwq9xKhysq7exMo" // fs-repo-14-to-15 v1.0.1 + CurrentIpfsDist = "/ipfs/QmRzRGJEjYDfbHHaALnHBuhzzrkXGdwcPMrgd5fgM7hqbe" // fs-repo-15-to-16 v1.0.1 // Latest distribution path. Default for fetchers. LatestIpfsDist = "/ipns/dist.ipfs.tech" diff --git a/test/cli/transports_test.go b/test/cli/transports_test.go index a52335181..cbef5c57d 100644 --- a/test/cli/transports_test.go +++ b/test/cli/transports_test.go @@ -90,8 +90,10 @@ func TestTransports(t *testing.T) { nodes.ForEachPar(func(n *harness.Node) { n.UpdateConfig(func(cfg *config.Config) { cfg.Addresses.Swarm = []string{"/ip4/127.0.0.1/udp/0/quic-v1"} - cfg.Swarm.Transports.Network.QUIC = config.True cfg.Swarm.Transports.Network.TCP = config.False + cfg.Swarm.Transports.Network.QUIC = config.True + cfg.Swarm.Transports.Network.WebTransport = config.False + cfg.Swarm.Transports.Network.WebRTCDirect = config.False }) }) disableRouting(nodes) @@ -99,14 +101,16 @@ func TestTransports(t *testing.T) { runTests(nodes) }) - t.Run("QUIC", func(t *testing.T) { + t.Run("QUIC+Webtransport", func(t *testing.T) { t.Parallel() nodes := harness.NewT(t).NewNodes(5).Init() nodes.ForEachPar(func(n *harness.Node) { n.UpdateConfig(func(cfg *config.Config) { cfg.Addresses.Swarm = []string{"/ip4/127.0.0.1/udp/0/quic-v1/webtransport"} + cfg.Swarm.Transports.Network.TCP = config.False cfg.Swarm.Transports.Network.QUIC = config.True cfg.Swarm.Transports.Network.WebTransport = config.True + cfg.Swarm.Transports.Network.WebRTCDirect = config.False }) }) disableRouting(nodes) diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 108ffeaab..cea2c1c92 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -113,7 +113,7 @@ require ( github.com/hexops/gotextdiff v1.0.3 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/ipfs/bbloom v0.0.4 // indirect - github.com/ipfs/boxo v0.21.1-0.20240730141506-8e51658f8a1b // indirect + github.com/ipfs/boxo v0.21.1-0.20240806135911-08d5663d293c // indirect github.com/ipfs/go-block-format v0.2.0 // indirect github.com/ipfs/go-cid v0.4.1 // indirect github.com/ipfs/go-datastore v0.6.0 // indirect @@ -144,7 +144,7 @@ require ( github.com/leonklingele/grouper v1.1.2 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/libp2p/go-cidranger v1.1.0 // indirect - github.com/libp2p/go-libp2p v0.35.4 // indirect + github.com/libp2p/go-libp2p v0.36.1 // indirect github.com/libp2p/go-libp2p-asn-util v0.4.1 // indirect github.com/libp2p/go-libp2p-kad-dht v0.25.2 // indirect github.com/libp2p/go-libp2p-kbucket v0.6.3 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 28f533eac..10ab482fd 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -229,8 +229,8 @@ github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= -github.com/google/pprof v0.0.0-20240618054019-d3b898a103f8 h1:ASJ/LAqdCHOyMYI+dwNxn7Rd8FscNkMyTr1KZU1JI/M= -github.com/google/pprof v0.0.0-20240618054019-d3b898a103f8/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= +github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 h1:FKHo8hFI3A+7w0aUQuYXQ+6EN5stWmeY/AZqtM8xk9k= +github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= @@ -280,8 +280,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.21.1-0.20240730141506-8e51658f8a1b h1:vH+ly+ghScnm4fDTsFnRkWIqZ0Vux6U3aOzPc3bQsOM= -github.com/ipfs/boxo v0.21.1-0.20240730141506-8e51658f8a1b/go.mod h1:NmweAYeY1USOaJJxouy7DLr/Y5M8UBSsCI2KRivO+TY= +github.com/ipfs/boxo v0.21.1-0.20240806135911-08d5663d293c h1:HUYj1w1hVsiceE0FLcMlkQfo4+Ioz7G/X0WXPzzZWHs= +github.com/ipfs/boxo v0.21.1-0.20240806135911-08d5663d293c/go.mod h1:yp1loimX0BDYOR0cyjtcXHv15muEh5V1FqO2QLlzykw= github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs= github.com/ipfs/go-block-format v0.2.0/go.mod h1:+jpL11nFx5A/SPpsoBn6Bzkra/zaArfSmsknbPMYgzM= github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= @@ -313,6 +313,8 @@ github.com/ipfs/go-metrics-interface v0.0.1 h1:j+cpbjYvu4R8zbleSs36gvB7jR+wsL2fG github.com/ipfs/go-metrics-interface v0.0.1/go.mod h1:6s6euYU4zowdslK0GKHmqaIZ3j/b/tL7HTWtJ4VPgWY= github.com/ipfs/go-peertaskqueue v0.8.1 h1:YhxAs1+wxb5jk7RvS0LHdyiILpNmRIRnZVztekOF0pg= github.com/ipfs/go-peertaskqueue v0.8.1/go.mod h1:Oxxd3eaK279FxeydSPPVGHzbwVeHjatZ2GA8XD+KbPU= +github.com/ipfs/go-test v0.0.4 h1:DKT66T6GBB6PsDFLoO56QZPrOmzJkqU1FZH5C9ySkew= +github.com/ipfs/go-test v0.0.4/go.mod h1:qhIM1EluEfElKKM6fnWxGn822/z9knUGM1+I/OAQNKI= github.com/ipfs/hang-fds v0.1.0 h1:deBiFlWHsVGzJ0ZMaqscEqRM1r2O1rFZ59UiQXb1Xko= github.com/ipfs/hang-fds v0.1.0/go.mod h1:29VLWOn3ftAgNNgXg/al7b11UzuQ+w7AwtCGcTaWkbM= github.com/ipfs/iptb v1.4.0 h1:YFYTrCkLMRwk/35IMyC6+yjoQSHTEcNcefBStLJzgvo= @@ -387,8 +389,8 @@ github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38y github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.35.4 h1:FDiBUYLkueFwsuNJUZaxKRdpKvBOWU64qQPL768bSeg= -github.com/libp2p/go-libp2p v0.35.4/go.mod h1:RKCDNt30IkFipGL0tl8wQW/3zVWEGFUZo8g2gAKxwjU= +github.com/libp2p/go-libp2p v0.36.1 h1:piAHesy0/8ifBEBUS8HF2m7ywR5vnktUFv00dTsVKcs= +github.com/libp2p/go-libp2p v0.36.1/go.mod h1:vHzel3CpRB+vS11fIjZSJAU4ALvieKV9VZHC9VerHj8= github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94= github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= github.com/libp2p/go-libp2p-kad-dht v0.25.2 h1:FOIk9gHoe4YRWXTu8SY9Z1d0RILol0TrtApsMDPjAVQ= @@ -495,8 +497,8 @@ github.com/nunnatsa/ginkgolinter v0.16.2 h1:8iLqHIZvN4fTLDC0Ke9tbSZVcyVHoBs0HIbn github.com/nunnatsa/ginkgolinter v0.16.2/go.mod h1:4tWRinDN1FeJgU+iJANW/kz7xKN5nYRAOfJDQUS9dOQ= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= -github.com/onsi/ginkgo/v2 v2.19.0 h1:9Cnnf7UHo57Hy3k6/m5k3dRfGTMXGvxhHFvkDTCTpvA= -github.com/onsi/ginkgo/v2 v2.19.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To= +github.com/onsi/ginkgo/v2 v2.19.1 h1:QXgq3Z8Crl5EL1WBAC98A5sEBHARrAJNzAmMxzLcRF0= +github.com/onsi/ginkgo/v2 v2.19.1/go.mod h1:O3DtEWQkPa/F7fBMgmZQKKsluAy8pd3rEQdrjkPb9zA= github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk= github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0= github.com/opencontainers/runtime-spec v1.2.0 h1:z97+pHb3uELt/yiAWD691HNHQIF07bE7dzrbT927iTk= @@ -514,12 +516,12 @@ github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2D github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y= github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= -github.com/pion/datachannel v1.5.6 h1:1IxKJntfSlYkpUj8LlYRSWpYiTTC02nUrOE8T3DqGeg= -github.com/pion/datachannel v1.5.6/go.mod h1:1eKT6Q85pRnr2mHiWHxJwO50SfZRtWHTsNIVb/NfGW4= -github.com/pion/dtls/v2 v2.2.11 h1:9U/dpCYl1ySttROPWJgqWKEylUdT0fXp/xst6JwY5Ks= -github.com/pion/dtls/v2 v2.2.11/go.mod h1:d9SYc9fch0CqK90mRk1dC7AkzzpwJj6u2GU3u+9pqFE= -github.com/pion/ice/v2 v2.3.25 h1:M5rJA07dqhi3nobJIg+uPtcVjFECTrhcR3n0ns8kDZs= -github.com/pion/ice/v2 v2.3.25/go.mod h1:KXJJcZK7E8WzrBEYnV4UtqEZsGeWfHxsNqhVcVvgjxw= +github.com/pion/datachannel v1.5.8 h1:ph1P1NsGkazkjrvyMfhRBUAWMxugJjq2HfQifaOoSNo= +github.com/pion/datachannel v1.5.8/go.mod h1:PgmdpoaNBLX9HNzNClmdki4DYW5JtI7Yibu8QzbL3tI= +github.com/pion/dtls/v2 v2.2.12 h1:KP7H5/c1EiVAAKUmXyCzPiQe5+bCJrpOeKg/L05dunk= +github.com/pion/dtls/v2 v2.2.12/go.mod h1:d9SYc9fch0CqK90mRk1dC7AkzzpwJj6u2GU3u+9pqFE= +github.com/pion/ice/v2 v2.3.32 h1:VwE/uEeqiMm0zUWpdt1DJtnqEkj3UjEbhX92/CurtWI= +github.com/pion/ice/v2 v2.3.32/go.mod h1:8fac0+qftclGy1tYd/nfwfHC729BLaxtVqMdMVCAVPU= github.com/pion/interceptor v0.1.29 h1:39fsnlP1U8gw2JzOFWdfCU82vHvhW9o0rZnZF56wF+M= github.com/pion/interceptor v0.1.29/go.mod h1:ri+LGNjRUc5xUNtDEPzfdkmSqISixVTBF/z/Zms/6T4= github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY= @@ -530,22 +532,22 @@ github.com/pion/randutil v0.1.0 h1:CFG1UdESneORglEsnimhUjf33Rwjubwj6xfiOXBa3mA= github.com/pion/randutil v0.1.0/go.mod h1:XcJrSMMbbMRhASFVOlj/5hQial/Y8oH/HVo7TBZq+j8= github.com/pion/rtcp v1.2.14 h1:KCkGV3vJ+4DAJmvP0vaQShsb0xkRfWkO540Gy102KyE= github.com/pion/rtcp v1.2.14/go.mod h1:sn6qjxvnwyAkkPzPULIbVqSKI5Dv54Rv7VG0kNxh9L4= -github.com/pion/rtp v1.8.6 h1:MTmn/b0aWWsAzux2AmP8WGllusBVw4NPYPVFFd7jUPw= -github.com/pion/rtp v1.8.6/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU= -github.com/pion/sctp v1.8.16 h1:PKrMs+o9EMLRvFfXq59WFsC+V8mN1wnKzqrv+3D/gYY= -github.com/pion/sctp v1.8.16/go.mod h1:P6PbDVA++OJMrVNg2AL3XtYHV4uD6dvfyOovCgMs0PE= +github.com/pion/rtp v1.8.8 h1:EtYFHI0rpUEjT/RMnGfb1vdJhbYmPG77szD72uUnSxs= +github.com/pion/rtp v1.8.8/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU= +github.com/pion/sctp v1.8.20 h1:sOc3lkV/tQaP57ZUEXIMdM2V92IIB2ia5v/ygnBxaEg= +github.com/pion/sctp v1.8.20/go.mod h1:oTxw8i5m+WbDHZJL/xUpe6CPIn1Y0GIKKwTLF4h53H8= github.com/pion/sdp/v3 v3.0.9 h1:pX++dCHoHUwq43kuwf3PyJfHlwIj4hXA7Vrifiq0IJY= github.com/pion/sdp/v3 v3.0.9/go.mod h1:B5xmvENq5IXJimIO4zfp6LAe1fD9N+kFv+V/1lOdz8M= -github.com/pion/srtp/v2 v2.0.18 h1:vKpAXfawO9RtTRKZJbG4y0v1b11NZxQnxRl85kGuUlo= -github.com/pion/srtp/v2 v2.0.18/go.mod h1:0KJQjA99A6/a0DOVTu1PhDSw0CXF2jTkqOoMg3ODqdA= +github.com/pion/srtp/v2 v2.0.20 h1:HNNny4s+OUmG280ETrCdgFndp4ufx3/uy85EawYEhTk= +github.com/pion/srtp/v2 v2.0.20/go.mod h1:0KJQjA99A6/a0DOVTu1PhDSw0CXF2jTkqOoMg3ODqdA= github.com/pion/stun v0.6.1 h1:8lp6YejULeHBF8NmV8e2787BogQhduZugh5PdhDyyN4= github.com/pion/stun v0.6.1/go.mod h1:/hO7APkX4hZKu/D0f2lHzNyvdkTGtIy3NDmLR7kSz/8= -github.com/pion/transport/v2 v2.2.5 h1:iyi25i/21gQck4hfRhomF6SktmUQjRsRW4WJdhfc3Kc= -github.com/pion/transport/v2 v2.2.5/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0= +github.com/pion/transport/v2 v2.2.9 h1:WEDygVovkJlV2CCunM9KS2kds+kcl7zdIefQA5y/nkE= +github.com/pion/transport/v2 v2.2.9/go.mod h1:sq1kSLWs+cHW9E+2fJP95QudkzbK7wscs8yYgQToO5E= github.com/pion/turn/v2 v2.1.6 h1:Xr2niVsiPTB0FPtt+yAWKFUkU1eotQbGgpTIld4x1Gc= github.com/pion/turn/v2 v2.1.6/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY= -github.com/pion/webrtc/v3 v3.2.42 h1:WN/ZuMjtpQOoGRCZUg/zFG+JHEvYLVyDKOxU6H1qWlE= -github.com/pion/webrtc/v3 v3.2.42/go.mod h1:M1RAe3TNTD1tzyvqHrbVODfwdPGSXOUo/OgpoGGJqFY= +github.com/pion/webrtc/v3 v3.2.50 h1:C/rwL2mBfCxHv6tlLzDAO3krJpQXfVx8A8WHnGJ2j34= +github.com/pion/webrtc/v3 v3.2.50/go.mod h1:dytYYoSBy7ZUWhJMbndx9UckgYvzNAfL7xgVnrIKxqo= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -579,8 +581,8 @@ github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 h1:M8mH9eK4OUR4l github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567/go.mod h1:DWNGW8A4Y+GyBgPuaQJuWiy0XYftx4Xm/y5Jqk9I6VQ= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= -github.com/quic-go/quic-go v0.45.0 h1:OHmkQGM37luZITyTSu6ff03HP/2IrwDX1ZFiNEhSFUE= -github.com/quic-go/quic-go v0.45.0/go.mod h1:1dLehS7TIR64+vxGR70GDcatWTOtMX2PUtnKsjbTurI= +github.com/quic-go/quic-go v0.45.2 h1:DfqBmqjb4ExSdxRIb/+qXhPC+7k6+DUNZha4oeiC9fY= +github.com/quic-go/quic-go v0.45.2/go.mod h1:1dLehS7TIR64+vxGR70GDcatWTOtMX2PUtnKsjbTurI= github.com/quic-go/webtransport-go v0.8.0 h1:HxSrwun11U+LlmwpgM1kEqIqH90IT4N8auv/cD7QFJg= github.com/quic-go/webtransport-go v0.8.0/go.mod h1:N99tjprW432Ut5ONql/aUhSLT0YVSlwHohQsuac9WaM= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= @@ -704,6 +706,8 @@ github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc h1:BCPnHtcboa github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc/go.mod h1:r45hJU7yEoA81k6MWNhpMj/kms0n14dkzkxYHoB96UM= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 h1:EKhdznlJHPMoKr0XTrX+IlJs1LH3lyx2nfr1dOlZ79k= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc= +github.com/wlynxg/anet v0.0.3 h1:PvR53psxFXstc12jelG6f1Lv4MWqE0tI76/hHGjh9rg= +github.com/wlynxg/anet v0.0.3/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA= github.com/xen0n/gosmopolitan v1.2.2 h1:/p2KTnMzwRexIW8GlKawsTWOxn7UHA+jCMF/V8HHtvU= github.com/xen0n/gosmopolitan v1.2.2/go.mod h1:7XX7Mj61uLYrj0qmeN0zi7XDon9JRAEhYQqAPLVNTeg= github.com/yagipy/maintidx v1.0.0 h1:h5NvIsCz+nRDapQ0exNv4aJ0yXSI0420omVANTv3GJM= From ffab7b271a9b7fcdc9d4b758d19aae5ecd412312 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Tue, 6 Aug 2024 21:51:45 +0200 Subject: [PATCH 1117/1212] feat: run AutoNAT V2 service in addition to V1 (#10468) * feat: libp2p.EnableAutoNATv2 Part of https://github.com/ipfs/kubo/issues/10091 We include a flag that allows shutting down V2 in case there are issues with it. * docs: EnableAutoNATv2 --- config/autonat.go | 7 +++++++ core/node/groups.go | 4 +++- core/node/libp2p/nat.go | 9 ++++++++- docs/changelogs/v0.30.md | 7 +++++++ docs/config.md | 19 ++++++++++++++----- 5 files changed, 39 insertions(+), 7 deletions(-) diff --git a/config/autonat.go b/config/autonat.go index eb87b48e6..e8940d14e 100644 --- a/config/autonat.go +++ b/config/autonat.go @@ -20,6 +20,9 @@ const ( // AutoNATServiceDisabled indicates that the user has disabled the // AutoNATService. AutoNATServiceDisabled + // AutoNATServiceEnabledV1Only forces use of V1 and disables V2 + // (used for testing) + AutoNATServiceEnabledV1Only ) func (m *AutoNATServiceMode) UnmarshalText(text []byte) error { @@ -30,6 +33,8 @@ func (m *AutoNATServiceMode) UnmarshalText(text []byte) error { *m = AutoNATServiceEnabled case "disabled": *m = AutoNATServiceDisabled + case "legacy-v1": + *m = AutoNATServiceEnabledV1Only default: return fmt.Errorf("unknown autonat mode: %s", string(text)) } @@ -44,6 +49,8 @@ func (m AutoNATServiceMode) MarshalText() ([]byte, error) { return []byte("enabled"), nil case AutoNATServiceDisabled: return []byte("disabled"), nil + case AutoNATServiceEnabledV1Only: + return []byte("legacy-v1"), nil default: return nil, fmt.Errorf("unknown autonat mode: %d", m) } diff --git a/core/node/groups.go b/core/node/groups.go index 3df945fd2..a12cc7b7f 100644 --- a/core/node/groups.go +++ b/core/node/groups.go @@ -105,7 +105,9 @@ func LibP2P(bcfg *BuildCfg, cfg *config.Config, userResourceOverrides rcmgr.Part // to dhtclient. fallthrough case config.AutoNATServiceEnabled: - autonat = fx.Provide(libp2p.AutoNATService(cfg.AutoNAT.Throttle)) + autonat = fx.Provide(libp2p.AutoNATService(cfg.AutoNAT.Throttle, false)) + case config.AutoNATServiceEnabledV1Only: + autonat = fx.Provide(libp2p.AutoNATService(cfg.AutoNAT.Throttle, true)) } enableRelayTransport := cfg.Swarm.Transports.Network.Relay.WithDefault(true) // nolint diff --git a/core/node/libp2p/nat.go b/core/node/libp2p/nat.go index fc72d7fb3..6d3cd09c3 100644 --- a/core/node/libp2p/nat.go +++ b/core/node/libp2p/nat.go @@ -9,7 +9,7 @@ import ( var NatPortMap = simpleOpt(libp2p.NATPortMap()) -func AutoNATService(throttle *config.AutoNATThrottleConfig) func() Libp2pOpts { +func AutoNATService(throttle *config.AutoNATThrottleConfig, v1only bool) func() Libp2pOpts { return func() (opts Libp2pOpts) { opts.Opts = append(opts.Opts, libp2p.EnableNATService()) if throttle != nil { @@ -21,6 +21,13 @@ func AutoNATService(throttle *config.AutoNATThrottleConfig) func() Libp2pOpts { ), ) } + + // While V1 still exists and V2 rollout is in progress + // (https://github.com/ipfs/kubo/issues/10091) we check a flag that + // allows users to disable V2 and run V1-only mode + if !v1only { + opts.Opts = append(opts.Opts, libp2p.EnableAutoNATv2()) + } return opts } } diff --git a/docs/changelogs/v0.30.md b/docs/changelogs/v0.30.md index aa870c0ad..dde03cd25 100644 --- a/docs/changelogs/v0.30.md +++ b/docs/changelogs/v0.30.md @@ -7,6 +7,7 @@ - [Overview](#overview) - [🔦 Highlights](#-highlights) - [WebRTC-Direct Transport enabled by default](#webrtc-direct-transport-enabled-by-default) + - [AutoNAT V2 Service Introduced Alongside V1](#autonat-v2-service-introduced-alongside-v1) - [Automated `ipfs version check`](#automated-ipfs-version-check) - [Version Suffix Configuration](#version-suffix-configuration) - [📝 Changelog](#-changelog) @@ -27,6 +28,12 @@ Learn more: [`Swarm.Transports.Network.WebRTCDirect`](https://github.com/ipfs/ku > [!NOTE] > Kubo 0.30 includes a migration for existing users that adds `/webrtc-direct` listener on the same UDP port as `/udp/{port}/quic-v1`. This supports the WebRTC-Direct rollout by reusing preexisting UDP firewall settings and port mappings created for QUIC. +#### AutoNAT V2 Service Introduced Alongside V1 + +The AutoNAT service enables nodes to determine their public reachability on the internet. AutoNAT V2 enhances this protocol with improved features. In this release, Kubo will offer both V1 and V2 services to other peers, although it will continue to use only V1 when acting as a client. Future releases will phase out V1, transitioning clients to utilize V2 exclusively. + +For more details, see the [Deployment Plan for AutoNAT V2](https://github.com/ipfs/kubo/issues/10091) and [`AutoNAT`](https://github.com/ipfs/kubo/blob/master/docs/config.md#autonat) configuration options. + #### Automated `ipfs version check` Kubo now performs privacy-preserving version checks using the [libp2p identify protocol](https://github.com/libp2p/specs/blob/master/identify/README.md) on peers detected by the Amino DHT client. diff --git a/docs/config.md b/docs/config.md index 8a09b7fe0..e5f02dc1d 100644 --- a/docs/config.md +++ b/docs/config.md @@ -552,7 +552,7 @@ Type: `array[string]` ## `AutoNAT` -Contains the configuration options for the AutoNAT service. The AutoNAT service +Contains the configuration options for the libp2p's [AutoNAT](https://github.com/libp2p/specs/tree/master/autonat) service. The AutoNAT service helps other nodes on the network determine if they're publicly reachable from the rest of the internet. @@ -561,13 +561,22 @@ the rest of the internet. When unset (default), the AutoNAT service defaults to _enabled_. Otherwise, this field can take one of two values: -* "enabled" - Enable the service (unless the node determines that it, itself, - isn't reachable by the public internet). -* "disabled" - Disable the service. +* `enabled` - Enable the V1+V2 service (unless the node determines that it, + itself, isn't reachable by the public internet). +* `legacy-v1` - Same as `enabled` but only V1 service is enabled. Used for testing + during as few releases as we [transition to V2](https://github.com/ipfs/kubo/issues/10091), will be removed in the future. +* `disabled` - Disable the service. Additional modes may be added in the future. -Type: `string` (one of `"enabled"` or `"disabled"`) +> [!IMPORTANT] +> We are in the progress of [rolling out AutoNAT V2](https://github.com/ipfs/kubo/issues/10091). +> Right now, by default, a publicly diallable Kubo provides both V1 and V2 service to other peers, +> but only V1 is used by Kubo as a client. In a future release we will remove V1 and switch client to use V2. + +Default: `enabled` + +Type: `optionalString` ### `AutoNAT.Throttle` From fc31f9c211b9cca231ca8e298609e829dedd82ad Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Wed, 7 Aug 2024 01:14:26 +0200 Subject: [PATCH 1118/1212] chore: boxo v0.22.0 (#10469) --- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- test/dependencies/go.mod | 2 +- test/dependencies/go.sum | 4 ++-- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index a4f79ae44..e83370805 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -9,7 +9,7 @@ toolchain go1.22.0 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.21.1-0.20240806135911-08d5663d293c + github.com/ipfs/boxo v0.22.0 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.36.1 github.com/multiformats/go-multiaddr v0.13.0 diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 49c78ffd9..acb82700c 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -266,8 +266,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.21.1-0.20240806135911-08d5663d293c h1:HUYj1w1hVsiceE0FLcMlkQfo4+Ioz7G/X0WXPzzZWHs= -github.com/ipfs/boxo v0.21.1-0.20240806135911-08d5663d293c/go.mod h1:yp1loimX0BDYOR0cyjtcXHv15muEh5V1FqO2QLlzykw= +github.com/ipfs/boxo v0.22.0 h1:QTC+P5uhsBNq6HzX728nsLyFW6rYDeR/5hggf9YZX78= +github.com/ipfs/boxo v0.22.0/go.mod h1:yp1loimX0BDYOR0cyjtcXHv15muEh5V1FqO2QLlzykw= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= diff --git a/go.mod b/go.mod index a68916313..233bf5976 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( github.com/hashicorp/go-version v1.6.0 github.com/ipfs-shipyard/nopfs v0.0.12 github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c - github.com/ipfs/boxo v0.21.1-0.20240806135911-08d5663d293c + github.com/ipfs/boxo v0.22.0 github.com/ipfs/go-block-format v0.2.0 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 diff --git a/go.sum b/go.sum index 8f59f5102..d3296bd39 100644 --- a/go.sum +++ b/go.sum @@ -330,8 +330,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.21.1-0.20240806135911-08d5663d293c h1:HUYj1w1hVsiceE0FLcMlkQfo4+Ioz7G/X0WXPzzZWHs= -github.com/ipfs/boxo v0.21.1-0.20240806135911-08d5663d293c/go.mod h1:yp1loimX0BDYOR0cyjtcXHv15muEh5V1FqO2QLlzykw= +github.com/ipfs/boxo v0.22.0 h1:QTC+P5uhsBNq6HzX728nsLyFW6rYDeR/5hggf9YZX78= +github.com/ipfs/boxo v0.22.0/go.mod h1:yp1loimX0BDYOR0cyjtcXHv15muEh5V1FqO2QLlzykw= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index cea2c1c92..dd32ac5e8 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -113,7 +113,7 @@ require ( github.com/hexops/gotextdiff v1.0.3 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/ipfs/bbloom v0.0.4 // indirect - github.com/ipfs/boxo v0.21.1-0.20240806135911-08d5663d293c // indirect + github.com/ipfs/boxo v0.22.0 // indirect github.com/ipfs/go-block-format v0.2.0 // indirect github.com/ipfs/go-cid v0.4.1 // indirect github.com/ipfs/go-datastore v0.6.0 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 10ab482fd..d4730e09e 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -280,8 +280,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.21.1-0.20240806135911-08d5663d293c h1:HUYj1w1hVsiceE0FLcMlkQfo4+Ioz7G/X0WXPzzZWHs= -github.com/ipfs/boxo v0.21.1-0.20240806135911-08d5663d293c/go.mod h1:yp1loimX0BDYOR0cyjtcXHv15muEh5V1FqO2QLlzykw= +github.com/ipfs/boxo v0.22.0 h1:QTC+P5uhsBNq6HzX728nsLyFW6rYDeR/5hggf9YZX78= +github.com/ipfs/boxo v0.22.0/go.mod h1:yp1loimX0BDYOR0cyjtcXHv15muEh5V1FqO2QLlzykw= github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs= github.com/ipfs/go-block-format v0.2.0/go.mod h1:+jpL11nFx5A/SPpsoBn6Bzkra/zaArfSmsknbPMYgzM= github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= From 9cc64ef06f6c26c4de99ff1a25817feca9305cbf Mon Sep 17 00:00:00 2001 From: gammazero Date: Tue, 6 Aug 2024 20:21:20 -0700 Subject: [PATCH 1119/1212] Update comment --- docs/config.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/config.md b/docs/config.md index c65bae2d2..9119610dc 100644 --- a/docs/config.md +++ b/docs/config.md @@ -2303,7 +2303,7 @@ transports. Supported transports are: TLS (priority 100) and Noise (priority 200). -No default priority will ever be less than 100. +No default priority will ever be less than 100. Lower values have precedence. #### `Swarm.Transports.Security.TLS` From 7500922f5ae9274748bb13f40ae173860a0fa9ae Mon Sep 17 00:00:00 2001 From: Vitaly Zdanevich Date: Mon, 12 Aug 2024 16:17:07 +0400 Subject: [PATCH 1120/1212] docs(readme): add Gentoo Linux (#10474) --- README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/README.md b/README.md index 726ab99a5..b80fa2e60 100644 --- a/README.md +++ b/README.md @@ -73,6 +73,7 @@ Before opening an issue, consider using one of the following locations to ensure - [Downloading builds using IPFS](#downloading-builds-using-ipfs) - [Unofficial Linux packages](#unofficial-linux-packages) - [ArchLinux](#arch-linux) + - [Gentoo Linux](#gentoo-linux) - [Nix](#nix) - [Solus](#solus) - [openSUSE](#opensuse) @@ -199,6 +200,7 @@ $ ipfs get /ipns/dist.ipfs.tech/kubo/$VERSION/kubo_$VERSION_windows-amd64.zip - [ArchLinux](#arch-linux) +- [Gentoo Linux](#gentoo-linux) - [Nix](#nix-linux) - [Solus](#solus) - [openSUSE](#opensuse) @@ -216,6 +218,16 @@ $ ipfs get /ipns/dist.ipfs.tech/kubo/$VERSION/kubo_$VERSION_windows-amd64.zip [![kubo-git via AUR](https://img.shields.io/static/v1?label=kubo-git&message=latest%40master&color=1793d1&logo=arch-linux&style=flat-square&cacheSeconds=3600)](https://aur.archlinux.org/packages/kubo/) +#### Gentoo Linux + +https://wiki.gentoo.org/wiki/Kubo + +```bash +# emerge -a net-p2p/kubo +``` + +https://packages.gentoo.org/packages/net-p2p/kubo + #### Nix With the purely functional package manager [Nix](https://nixos.org/nix/) you can install kubo (go-ipfs) like this: From 91ae982494325388f846da8d652bb6db3d78f6ee Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Mon, 12 Aug 2024 22:36:59 +0200 Subject: [PATCH 1121/1212] feat: webui v4.3.0 (#10477) https://github.com/ipfs/ipfs-webui/releases/tag/v4.3.0 --- core/corehttp/webui.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/corehttp/webui.go b/core/corehttp/webui.go index 2e31b2214..82520e30d 100644 --- a/core/corehttp/webui.go +++ b/core/corehttp/webui.go @@ -1,11 +1,12 @@ package corehttp // WebUI version confirmed to work with this Kubo version -const WebUIPath = "/ipfs/bafybeigggyffcf6yfhx5irtwzx3cgnk6n3dwylkvcpckzhqqrigsxowjwe" // v4.2.1 +const WebUIPath = "/ipfs/bafybeihatzsgposbr3hrngo42yckdyqcc56yean2rynnwpzxstvdlphxf4" // v4.3.0 // WebUIPaths is a list of all past webUI paths. var WebUIPaths = []string{ WebUIPath, + "/ipfs/bafybeigggyffcf6yfhx5irtwzx3cgnk6n3dwylkvcpckzhqqrigsxowjwe", "/ipfs/bafybeidf7cpkwsjkq6xs3r6fbbxghbugilx3jtezbza7gua3k5wjixpmba", "/ipfs/bafybeiamycmd52xvg6k3nzr6z3n33de6a2teyhquhj4kspdtnvetnkrfim", "/ipfs/bafybeieqdeoqkf7xf4aozd524qncgiloh33qgr25lyzrkusbcre4c3fxay", From a339e6e807fa5bde786e5a539b2958a15ea22125 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Mon, 12 Aug 2024 23:00:56 +0200 Subject: [PATCH 1122/1212] fix(daemon): panic in kubo/daemon.go:595 (#10473) --- cmd/ipfs/kubo/daemon.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cmd/ipfs/kubo/daemon.go b/cmd/ipfs/kubo/daemon.go index 5dec799dd..e683f0cb1 100644 --- a/cmd/ipfs/kubo/daemon.go +++ b/cmd/ipfs/kubo/daemon.go @@ -597,6 +597,7 @@ take effect. cfg, err := cctx.GetConfig() if err != nil { log.Errorf("failed to access config: %s", err) + return } if len(cfg.Bootstrap) == 0 && len(cfg.Peering.Peers) == 0 { // Skip peer check if Bootstrap and Peering lists are empty @@ -607,10 +608,12 @@ take effect. ipfs, err := coreapi.NewCoreAPI(node) if err != nil { log.Errorf("failed to access CoreAPI: %v", err) + return } peers, err := ipfs.Swarm().Peers(cctx.Context()) if err != nil { log.Errorf("failed to read swarm peers: %v", err) + return } if len(peers) == 0 { log.Error("failed to bootstrap (no peers found): consider updating Bootstrap or Peering section of your config") From 0d428310b28c663c473d684011780929b145d4f2 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Wed, 14 Aug 2024 16:42:24 +0200 Subject: [PATCH 1123/1212] feat(daemon): improve stdout on startup (#10472) --- cmd/ipfs/kubo/daemon.go | 73 ++++++++++++++++++++++------------- docs/changelogs/v0.30.md | 29 ++++++++++++++ test/sharness/t0060-daemon.sh | 21 +++++----- 3 files changed, 85 insertions(+), 38 deletions(-) diff --git a/cmd/ipfs/kubo/daemon.go b/cmd/ipfs/kubo/daemon.go index e683f0cb1..1999605dc 100644 --- a/cmd/ipfs/kubo/daemon.go +++ b/cmd/ipfs/kubo/daemon.go @@ -10,8 +10,10 @@ import ( "net/http" _ "net/http/pprof" "os" + "regexp" "runtime" "sort" + "strings" "sync" "time" @@ -89,7 +91,7 @@ running, calls to 'ipfs' commands will be sent over the network to the daemon. `, LongDescription: ` -The daemon will start listening on ports on the network, which are +The Kubo daemon will start listening on ports on the network, which are documented in (and can be modified through) 'ipfs config Addresses'. For example, to change the 'Gateway' port: @@ -109,11 +111,11 @@ other computers in the network, use 0.0.0.0 as the ip address: Be careful if you expose the RPC API. It is a security risk, as anyone could control your node remotely. If you need to control the node remotely, make sure to protect the port as you would other services or database -(firewall, authenticated proxy, etc). +(firewall, authenticated proxy, etc), or at least set API.Authorizations. HTTP Headers -ipfs supports passing arbitrary headers to the RPC API and Gateway. You can +Kubo supports passing arbitrary headers to the RPC API and Gateway. You can do this by setting headers on the API.HTTPHeaders and Gateway.HTTPHeaders keys: @@ -124,7 +126,7 @@ Note that the value of the keys is an _array_ of strings. This is because headers can have more than one value, and it is convenient to pass through to other libraries. -CORS Headers (for API) +CORS Headers (for RPC API) You can setup CORS headers the same way: @@ -141,7 +143,7 @@ second signal. IPFS_PATH environment variable -ipfs uses a repository in the local file system. By default, the repo is +Kubo uses a repository in the local file system. By default, the repo is located at ~/.ipfs. To change the repo location, set the $IPFS_PATH environment variable: @@ -149,7 +151,7 @@ environment variable: DEPRECATION NOTICE -Previously, ipfs used an environment variable as seen below: +Previously, Kubo used an environment variable as seen below: export API_ORIGIN="http://localhost:8888/" @@ -160,14 +162,14 @@ Headers. }, Options: []cmds.Option{ - cmds.BoolOption(initOptionKwd, "Initialize ipfs with default settings if not already initialized"), + cmds.BoolOption(initOptionKwd, "Initialize Kubo with default settings if not already initialized"), cmds.StringOption(initConfigOptionKwd, "Path to existing configuration file to be loaded during --init"), cmds.StringOption(initProfileOptionKwd, "Configuration profiles to apply for --init. See ipfs init --help for more"), cmds.StringOption(routingOptionKwd, "Overrides the routing option").WithDefault(routingOptionDefaultKwd), cmds.BoolOption(mountKwd, "Mounts IPFS to the filesystem using FUSE (experimental)"), cmds.StringOption(ipfsMountKwd, "Path to the mountpoint for IPFS (if using --mount). Defaults to config setting."), cmds.StringOption(ipnsMountKwd, "Path to the mountpoint for IPNS (if using --mount). Defaults to config setting."), - cmds.BoolOption(unrestrictedAPIAccessKwd, "Allow API access to unlisted hashes"), + cmds.BoolOption(unrestrictedAPIAccessKwd, "Allow RPC API access to unlisted hashes"), cmds.BoolOption(unencryptTransportKwd, "Disable transport encryption (for debugging protocols)"), cmds.BoolOption(enableGCKwd, "Enable automatic periodic repo garbage collection"), cmds.BoolOption(adjustFDLimitKwd, "Check and raise file descriptor limits if needed").WithDefault(true), @@ -373,6 +375,8 @@ func daemonFunc(req *cmds.Request, re cmds.ResponseEmitter, env cmds.Environment return err } + fmt.Printf("PeerID: %s\n", cfg.Identity.PeerID) + if !psSet { pubsub = cfg.Pubsub.Enabled.WithDefault(false) } @@ -463,7 +467,7 @@ func daemonFunc(req *cmds.Request, re cmds.ResponseEmitter, env cmds.Environment log.Fatal("Private network does not work with Routing.Type=auto. Update your config to Routing.Type=dht (or none, and do manual peering)") } - printSwarmAddrs(node) + printLibp2pPorts(node) if node.PrivateKey.Type() == p2pcrypto.RSA { fmt.Print(` @@ -563,7 +567,7 @@ take effect. // Add ipfs version info to prometheus metrics ipfsInfoMetric := promauto.NewGaugeVec(prometheus.GaugeOpts{ Name: "ipfs_info", - Help: "IPFS version information.", + Help: "Kubo IPFS version information.", }, []string{"version", "commit"}) // Setting to 1 lets us multiply it with other stats to add the version labels @@ -779,8 +783,8 @@ func rewriteMaddrToUseLocalhostIfItsAny(maddr ma.Multiaddr) ma.Multiaddr { } } -// printSwarmAddrs prints the addresses of the host. -func printSwarmAddrs(node *core.IpfsNode) { +// printLibp2pPorts prints which ports are opened to facilitate swarm connectivity. +func printLibp2pPorts(node *core.IpfsNode) { if !node.IsOnline { fmt.Println("Swarm not listening, running in offline mode.") return @@ -790,24 +794,39 @@ func printSwarmAddrs(node *core.IpfsNode) { if err != nil { log.Errorf("failed to read listening addresses: %s", err) } - lisAddrs := make([]string, len(ifaceAddrs)) - for i, addr := range ifaceAddrs { - lisAddrs[i] = addr.String() - } - sort.Strings(lisAddrs) - for _, addr := range lisAddrs { - fmt.Printf("Swarm listening on %s\n", addr) - } - nodePhostAddrs := node.PeerHost.Addrs() - addrs := make([]string, len(nodePhostAddrs)) - for i, addr := range nodePhostAddrs { - addrs[i] = addr.String() + // Multiple libp2p transports can use same port. + // Deduplicate all listeners and collect unique IP:port (udp|tcp) combinations + // which is useful information for operator deploying Kubo in TCP/IP infra. + addrMap := make(map[string]map[string]struct{}) + re := regexp.MustCompile(`^/(?:ip[46]|dns(?:[46])?)/([^/]+)/(tcp|udp)/(\d+)(/.*)?$`) + for _, addr := range ifaceAddrs { + matches := re.FindStringSubmatch(addr.String()) + if matches != nil { + hostname := matches[1] + protocol := strings.ToUpper(matches[2]) + port := matches[3] + var host string + if matches[0][:4] == "/ip6" { + host = fmt.Sprintf("[%s]:%s", hostname, port) + } else { + host = fmt.Sprintf("%s:%s", hostname, port) + } + if _, ok := addrMap[host]; !ok { + addrMap[host] = make(map[string]struct{}) + } + addrMap[host][protocol] = struct{}{} + } } - sort.Strings(addrs) - for _, addr := range addrs { - fmt.Printf("Swarm announcing %s\n", addr) + for host, protocolsSet := range addrMap { + protocols := make([]string, 0, len(protocolsSet)) + for protocol := range protocolsSet { + protocols = append(protocols, protocol) + } + sort.Strings(protocols) + fmt.Printf("Swarm listening on %s (%s)\n", host, strings.Join(protocols, "+")) } + fmt.Printf("Run 'ipfs id' to inspect announced and discovered multiaddrs of this node.\n") } // serveHTTPGateway collects options, creates listener, prints status message and starts serving requests. diff --git a/docs/changelogs/v0.30.md b/docs/changelogs/v0.30.md index dde03cd25..314e5a2e0 100644 --- a/docs/changelogs/v0.30.md +++ b/docs/changelogs/v0.30.md @@ -10,6 +10,7 @@ - [AutoNAT V2 Service Introduced Alongside V1](#autonat-v2-service-introduced-alongside-v1) - [Automated `ipfs version check`](#automated-ipfs-version-check) - [Version Suffix Configuration](#version-suffix-configuration) + - [Cleaned Up `ipfs daemon` Startup Log](#cleaned-up-ipfs-daemon-startup-log) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -48,6 +49,34 @@ Defining the optional agent version suffix is now simpler. The [`Version.AgentSu > [!NOTE] > Setting a custom version suffix helps with ecosystem analysis, such as Amino DHT reports published at https://stats.ipfs.network +> + +#### Cleaned Up `ipfs daemon` Startup Log + +The `ipfs daemon` startup output has been streamlined to enhance clarity and usability: + +```console +$ ipfs daemon +Initializing daemon... +Kubo version: 0.30.0 +Repo version: 16 +System version: amd64/linux +Golang version: go1.22.5 +PeerID: 12D3KooWQ73s1CQsm4jWwQvdCAtc5w8LatyQt7QLQARk5xdhK9CE +Swarm listening on 127.0.0.1:4001 (TCP+UDP) +Swarm listening on 192.0.2.10:4001 (TCP+UDP) +Swarm listening on [::1]:4001 (TCP+UDP) +Swarm listening on [2001:0db8::10]:4001 (TCP+UDP) +Run 'ipfs id' to inspect announced and discovered multiaddrs of this node. +RPC API server listening on /ip4/127.0.0.1/tcp/5001 +WebUI: http://127.0.0.1:5001/webui +Gateway server listening on /ip4/127.0.0.1/tcp/8080 +Daemon is ready +``` + +The previous lengthy listing of all listener and announced multiaddrs has been removed due to its complexity, especially with modern libp2p nodes sharing multiple transports and long lists of `/webtransport` and `/webrtc-direct` certhashes. +The output now features a simplified list of swarm listeners, displayed in the format `host:port (TCP+UDP)`, which provides essential information for debugging connectivity issues, particularly related to port forwarding. +Announced libp2p addresses are no longer printed on startup, because libp2p may change or augument them based on AutoNAT, relay, and UPnP state. Instead, users are prompted to run `ipfs id` to obtain up-to-date list of listeners and announced multiaddrs in libp2p format. ### 📝 Changelog diff --git a/test/sharness/t0060-daemon.sh b/test/sharness/t0060-daemon.sh index 29474c7ff..431ff245c 100755 --- a/test/sharness/t0060-daemon.sh +++ b/test/sharness/t0060-daemon.sh @@ -76,17 +76,16 @@ test_expect_success "ipfs gateway works with the correct allowed origin port" ' curl -s -X POST -H "Origin:http://localhost:$GWAY_PORT" -I "http://$GWAY_ADDR/api/v0/version" ' -test_expect_success "ipfs daemon output looks good" ' - STARTFILE="ipfs cat /ipfs/$HASH_WELCOME_DOCS/readme" && - echo "Initializing daemon..." >expected_daemon && - ipfs version --all >> expected_daemon && - sed "s/^/Swarm listening on /" listen_addrs >>expected_daemon && - sed "s/^/Swarm announcing /" local_addrs >>expected_daemon && - echo "RPC API server listening on '$API_MADDR'" >>expected_daemon && - echo "WebUI: http://'$API_ADDR'/webui" >>expected_daemon && - echo "Gateway server listening on '$GWAY_MADDR'" >>expected_daemon && - echo "Daemon is ready" >>expected_daemon && - test_cmp expected_daemon actual_daemon +test_expect_success "ipfs daemon output includes looks good" ' + test_should_contain "Initializing daemon..." actual_daemon && + test_should_contain "$(ipfs version --all)" actual_daemon && + test_should_contain "PeerID: $(ipfs config Identity.PeerID)" actual_daemon && + test_should_contain "Swarm listening on 127.0.0.1:" actual_daemon && + test_should_contain "RPC API server listening on '$API_MADDR'" actual_daemon && + test_should_contain "WebUI: http://'$API_ADDR'/webui" actual_daemon && + test_should_contain "Gateway server listening on '$GWAY_MADDR'" actual_daemon && + test_should_contain "Daemon is ready" actual_daemon && + cat actual_daemon ' test_expect_success ".ipfs/ has been created" ' From 34008b6ffa1295a6dfd8f5bb8fd488975b212f60 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Mon, 19 Aug 2024 14:23:14 +0200 Subject: [PATCH 1124/1212] chore(daemon): sort listeners (#10480) --- cmd/ipfs/kubo/daemon.go | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/cmd/ipfs/kubo/daemon.go b/cmd/ipfs/kubo/daemon.go index 1999605dc..b66e61374 100644 --- a/cmd/ipfs/kubo/daemon.go +++ b/cmd/ipfs/kubo/daemon.go @@ -818,7 +818,17 @@ func printLibp2pPorts(node *core.IpfsNode) { addrMap[host][protocol] = struct{}{} } } - for host, protocolsSet := range addrMap { + + // Produce a sorted host:port list + hosts := make([]string, 0, len(addrMap)) + for host := range addrMap { + hosts = append(hosts, host) + } + sort.Strings(hosts) + + // Print listeners + for _, host := range hosts { + protocolsSet := addrMap[host] protocols := make([]string, 0, len(protocolsSet)) for protocol := range protocolsSet { protocols = append(protocols, protocol) From c8007dd242987b2ea9c1733d95823a019fd55ccc Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Mon, 19 Aug 2024 14:43:49 +0200 Subject: [PATCH 1125/1212] fix: go-libp2p v0.36.2 (#10483) https://github.com/libp2p/go-libp2p/releases/tag/v0.36.2 --- docs/examples/kubo-as-a-library/go.mod | 8 ++++---- docs/examples/kubo-as-a-library/go.sum | 17 ++++++++--------- go.mod | 8 ++++---- go.sum | 17 ++++++++--------- test/dependencies/go.mod | 2 +- test/dependencies/go.sum | 16 ++++++++-------- 6 files changed, 33 insertions(+), 35 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index e83370805..c51eb189d 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -11,7 +11,7 @@ replace github.com/ipfs/kubo => ./../../.. require ( github.com/ipfs/boxo v0.22.0 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 - github.com/libp2p/go-libp2p v0.36.1 + github.com/libp2p/go-libp2p v0.36.2 github.com/multiformats/go-multiaddr v0.13.0 ) @@ -149,7 +149,7 @@ require ( github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 // indirect github.com/pion/datachannel v1.5.8 // indirect github.com/pion/dtls/v2 v2.2.12 // indirect - github.com/pion/ice/v2 v2.3.32 // indirect + github.com/pion/ice/v2 v2.3.34 // indirect github.com/pion/interceptor v0.1.29 // indirect github.com/pion/logging v0.2.2 // indirect github.com/pion/mdns v0.0.12 // indirect @@ -160,9 +160,9 @@ require ( github.com/pion/sdp/v3 v3.0.9 // indirect github.com/pion/srtp/v2 v2.0.20 // indirect github.com/pion/stun v0.6.1 // indirect - github.com/pion/transport/v2 v2.2.9 // indirect + github.com/pion/transport/v2 v2.2.10 // indirect github.com/pion/turn/v2 v2.1.6 // indirect - github.com/pion/webrtc/v3 v3.2.50 // indirect + github.com/pion/webrtc/v3 v3.3.0 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/polydawn/refmt v0.89.0 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index acb82700c..71d5bd54a 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -429,8 +429,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.36.1 h1:piAHesy0/8ifBEBUS8HF2m7ywR5vnktUFv00dTsVKcs= -github.com/libp2p/go-libp2p v0.36.1/go.mod h1:vHzel3CpRB+vS11fIjZSJAU4ALvieKV9VZHC9VerHj8= +github.com/libp2p/go-libp2p v0.36.2 h1:BbqRkDaGC3/5xfaJakLV/BrpjlAuYqSB0lRvtzL3B/U= +github.com/libp2p/go-libp2p v0.36.2/go.mod h1:XO3joasRE4Eup8yCTTP/+kX+g92mOgRaadk46LmPhHY= github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94= github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= @@ -592,8 +592,8 @@ github.com/pion/datachannel v1.5.8/go.mod h1:PgmdpoaNBLX9HNzNClmdki4DYW5JtI7Yibu github.com/pion/dtls/v2 v2.2.7/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s= github.com/pion/dtls/v2 v2.2.12 h1:KP7H5/c1EiVAAKUmXyCzPiQe5+bCJrpOeKg/L05dunk= github.com/pion/dtls/v2 v2.2.12/go.mod h1:d9SYc9fch0CqK90mRk1dC7AkzzpwJj6u2GU3u+9pqFE= -github.com/pion/ice/v2 v2.3.32 h1:VwE/uEeqiMm0zUWpdt1DJtnqEkj3UjEbhX92/CurtWI= -github.com/pion/ice/v2 v2.3.32/go.mod h1:8fac0+qftclGy1tYd/nfwfHC729BLaxtVqMdMVCAVPU= +github.com/pion/ice/v2 v2.3.34 h1:Ic1ppYCj4tUOcPAp76U6F3fVrlSw8A9JtRXLqw6BbUM= +github.com/pion/ice/v2 v2.3.34/go.mod h1:mBF7lnigdqgtB+YHkaY/Y6s6tsyRyo4u4rPGRuOjUBQ= github.com/pion/interceptor v0.1.29 h1:39fsnlP1U8gw2JzOFWdfCU82vHvhW9o0rZnZF56wF+M= github.com/pion/interceptor v0.1.29/go.mod h1:ri+LGNjRUc5xUNtDEPzfdkmSqISixVTBF/z/Zms/6T4= github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY= @@ -619,17 +619,16 @@ github.com/pion/stun v0.6.1/go.mod h1:/hO7APkX4hZKu/D0f2lHzNyvdkTGtIy3NDmLR7kSz/ github.com/pion/transport/v2 v2.2.1/go.mod h1:cXXWavvCnFF6McHTft3DWS9iic2Mftcz1Aq29pGcU5g= github.com/pion/transport/v2 v2.2.3/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0= github.com/pion/transport/v2 v2.2.4/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0= -github.com/pion/transport/v2 v2.2.8/go.mod h1:sq1kSLWs+cHW9E+2fJP95QudkzbK7wscs8yYgQToO5E= -github.com/pion/transport/v2 v2.2.9 h1:WEDygVovkJlV2CCunM9KS2kds+kcl7zdIefQA5y/nkE= -github.com/pion/transport/v2 v2.2.9/go.mod h1:sq1kSLWs+cHW9E+2fJP95QudkzbK7wscs8yYgQToO5E= +github.com/pion/transport/v2 v2.2.10 h1:ucLBLE8nuxiHfvkFKnkDQRYWYfp8ejf4YBOPfaQpw6Q= +github.com/pion/transport/v2 v2.2.10/go.mod h1:sq1kSLWs+cHW9E+2fJP95QudkzbK7wscs8yYgQToO5E= github.com/pion/transport/v3 v3.0.1/go.mod h1:UY7kiITrlMv7/IKgd5eTUcaahZx5oUN3l9SzK5f5xE0= github.com/pion/transport/v3 v3.0.6 h1:k1mQU06bmmX143qSWgXFqSH1KUJceQvIUuVH/K5ELWw= github.com/pion/transport/v3 v3.0.6/go.mod h1:HvJr2N/JwNJAfipsRleqwFoR3t/pWyHeZUs89v3+t5s= github.com/pion/turn/v2 v2.1.3/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY= github.com/pion/turn/v2 v2.1.6 h1:Xr2niVsiPTB0FPtt+yAWKFUkU1eotQbGgpTIld4x1Gc= github.com/pion/turn/v2 v2.1.6/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY= -github.com/pion/webrtc/v3 v3.2.50 h1:C/rwL2mBfCxHv6tlLzDAO3krJpQXfVx8A8WHnGJ2j34= -github.com/pion/webrtc/v3 v3.2.50/go.mod h1:dytYYoSBy7ZUWhJMbndx9UckgYvzNAfL7xgVnrIKxqo= +github.com/pion/webrtc/v3 v3.3.0 h1:Rf4u6n6U5t5sUxhYPQk/samzU/oDv7jk6BA5hyO2F9I= +github.com/pion/webrtc/v3 v3.3.0/go.mod h1:hVmrDJvwhEertRWObeb1xzulzHGeVUoPlWvxdGzcfU0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= diff --git a/go.mod b/go.mod index 233bf5976..ee336089e 100644 --- a/go.mod +++ b/go.mod @@ -49,7 +49,7 @@ require ( github.com/jbenet/goprocess v0.1.4 github.com/julienschmidt/httprouter v1.3.0 github.com/libp2p/go-doh-resolver v0.4.0 - github.com/libp2p/go-libp2p v0.36.1 + github.com/libp2p/go-libp2p v0.36.2 github.com/libp2p/go-libp2p-http v0.5.0 github.com/libp2p/go-libp2p-kad-dht v0.25.2 github.com/libp2p/go-libp2p-kbucket v0.6.3 @@ -185,7 +185,7 @@ require ( github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 // indirect github.com/pion/datachannel v1.5.8 // indirect github.com/pion/dtls/v2 v2.2.12 // indirect - github.com/pion/ice/v2 v2.3.32 // indirect + github.com/pion/ice/v2 v2.3.34 // indirect github.com/pion/interceptor v0.1.29 // indirect github.com/pion/logging v0.2.2 // indirect github.com/pion/mdns v0.0.12 // indirect @@ -196,9 +196,9 @@ require ( github.com/pion/sdp/v3 v3.0.9 // indirect github.com/pion/srtp/v2 v2.0.20 // indirect github.com/pion/stun v0.6.1 // indirect - github.com/pion/transport/v2 v2.2.9 // indirect + github.com/pion/transport/v2 v2.2.10 // indirect github.com/pion/turn/v2 v2.1.6 // indirect - github.com/pion/webrtc/v3 v3.2.50 // indirect + github.com/pion/webrtc/v3 v3.3.0 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/polydawn/refmt v0.89.0 // indirect diff --git a/go.sum b/go.sum index d3296bd39..05be97779 100644 --- a/go.sum +++ b/go.sum @@ -510,8 +510,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.36.1 h1:piAHesy0/8ifBEBUS8HF2m7ywR5vnktUFv00dTsVKcs= -github.com/libp2p/go-libp2p v0.36.1/go.mod h1:vHzel3CpRB+vS11fIjZSJAU4ALvieKV9VZHC9VerHj8= +github.com/libp2p/go-libp2p v0.36.2 h1:BbqRkDaGC3/5xfaJakLV/BrpjlAuYqSB0lRvtzL3B/U= +github.com/libp2p/go-libp2p v0.36.2/go.mod h1:XO3joasRE4Eup8yCTTP/+kX+g92mOgRaadk46LmPhHY= github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94= github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= @@ -694,8 +694,8 @@ github.com/pion/datachannel v1.5.8/go.mod h1:PgmdpoaNBLX9HNzNClmdki4DYW5JtI7Yibu github.com/pion/dtls/v2 v2.2.7/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s= github.com/pion/dtls/v2 v2.2.12 h1:KP7H5/c1EiVAAKUmXyCzPiQe5+bCJrpOeKg/L05dunk= github.com/pion/dtls/v2 v2.2.12/go.mod h1:d9SYc9fch0CqK90mRk1dC7AkzzpwJj6u2GU3u+9pqFE= -github.com/pion/ice/v2 v2.3.32 h1:VwE/uEeqiMm0zUWpdt1DJtnqEkj3UjEbhX92/CurtWI= -github.com/pion/ice/v2 v2.3.32/go.mod h1:8fac0+qftclGy1tYd/nfwfHC729BLaxtVqMdMVCAVPU= +github.com/pion/ice/v2 v2.3.34 h1:Ic1ppYCj4tUOcPAp76U6F3fVrlSw8A9JtRXLqw6BbUM= +github.com/pion/ice/v2 v2.3.34/go.mod h1:mBF7lnigdqgtB+YHkaY/Y6s6tsyRyo4u4rPGRuOjUBQ= github.com/pion/interceptor v0.1.29 h1:39fsnlP1U8gw2JzOFWdfCU82vHvhW9o0rZnZF56wF+M= github.com/pion/interceptor v0.1.29/go.mod h1:ri+LGNjRUc5xUNtDEPzfdkmSqISixVTBF/z/Zms/6T4= github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY= @@ -721,17 +721,16 @@ github.com/pion/stun v0.6.1/go.mod h1:/hO7APkX4hZKu/D0f2lHzNyvdkTGtIy3NDmLR7kSz/ github.com/pion/transport/v2 v2.2.1/go.mod h1:cXXWavvCnFF6McHTft3DWS9iic2Mftcz1Aq29pGcU5g= github.com/pion/transport/v2 v2.2.3/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0= github.com/pion/transport/v2 v2.2.4/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0= -github.com/pion/transport/v2 v2.2.8/go.mod h1:sq1kSLWs+cHW9E+2fJP95QudkzbK7wscs8yYgQToO5E= -github.com/pion/transport/v2 v2.2.9 h1:WEDygVovkJlV2CCunM9KS2kds+kcl7zdIefQA5y/nkE= -github.com/pion/transport/v2 v2.2.9/go.mod h1:sq1kSLWs+cHW9E+2fJP95QudkzbK7wscs8yYgQToO5E= +github.com/pion/transport/v2 v2.2.10 h1:ucLBLE8nuxiHfvkFKnkDQRYWYfp8ejf4YBOPfaQpw6Q= +github.com/pion/transport/v2 v2.2.10/go.mod h1:sq1kSLWs+cHW9E+2fJP95QudkzbK7wscs8yYgQToO5E= github.com/pion/transport/v3 v3.0.1/go.mod h1:UY7kiITrlMv7/IKgd5eTUcaahZx5oUN3l9SzK5f5xE0= github.com/pion/transport/v3 v3.0.6 h1:k1mQU06bmmX143qSWgXFqSH1KUJceQvIUuVH/K5ELWw= github.com/pion/transport/v3 v3.0.6/go.mod h1:HvJr2N/JwNJAfipsRleqwFoR3t/pWyHeZUs89v3+t5s= github.com/pion/turn/v2 v2.1.3/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY= github.com/pion/turn/v2 v2.1.6 h1:Xr2niVsiPTB0FPtt+yAWKFUkU1eotQbGgpTIld4x1Gc= github.com/pion/turn/v2 v2.1.6/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY= -github.com/pion/webrtc/v3 v3.2.50 h1:C/rwL2mBfCxHv6tlLzDAO3krJpQXfVx8A8WHnGJ2j34= -github.com/pion/webrtc/v3 v3.2.50/go.mod h1:dytYYoSBy7ZUWhJMbndx9UckgYvzNAfL7xgVnrIKxqo= +github.com/pion/webrtc/v3 v3.3.0 h1:Rf4u6n6U5t5sUxhYPQk/samzU/oDv7jk6BA5hyO2F9I= +github.com/pion/webrtc/v3 v3.3.0/go.mod h1:hVmrDJvwhEertRWObeb1xzulzHGeVUoPlWvxdGzcfU0= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index dd32ac5e8..277b31541 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -144,7 +144,7 @@ require ( github.com/leonklingele/grouper v1.1.2 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/libp2p/go-cidranger v1.1.0 // indirect - github.com/libp2p/go-libp2p v0.36.1 // indirect + github.com/libp2p/go-libp2p v0.36.2 // indirect github.com/libp2p/go-libp2p-asn-util v0.4.1 // indirect github.com/libp2p/go-libp2p-kad-dht v0.25.2 // indirect github.com/libp2p/go-libp2p-kbucket v0.6.3 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index d4730e09e..8553ddb6e 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -389,8 +389,8 @@ github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38y github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.36.1 h1:piAHesy0/8ifBEBUS8HF2m7ywR5vnktUFv00dTsVKcs= -github.com/libp2p/go-libp2p v0.36.1/go.mod h1:vHzel3CpRB+vS11fIjZSJAU4ALvieKV9VZHC9VerHj8= +github.com/libp2p/go-libp2p v0.36.2 h1:BbqRkDaGC3/5xfaJakLV/BrpjlAuYqSB0lRvtzL3B/U= +github.com/libp2p/go-libp2p v0.36.2/go.mod h1:XO3joasRE4Eup8yCTTP/+kX+g92mOgRaadk46LmPhHY= github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94= github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= github.com/libp2p/go-libp2p-kad-dht v0.25.2 h1:FOIk9gHoe4YRWXTu8SY9Z1d0RILol0TrtApsMDPjAVQ= @@ -520,8 +520,8 @@ github.com/pion/datachannel v1.5.8 h1:ph1P1NsGkazkjrvyMfhRBUAWMxugJjq2HfQifaOoSN github.com/pion/datachannel v1.5.8/go.mod h1:PgmdpoaNBLX9HNzNClmdki4DYW5JtI7Yibu8QzbL3tI= github.com/pion/dtls/v2 v2.2.12 h1:KP7H5/c1EiVAAKUmXyCzPiQe5+bCJrpOeKg/L05dunk= github.com/pion/dtls/v2 v2.2.12/go.mod h1:d9SYc9fch0CqK90mRk1dC7AkzzpwJj6u2GU3u+9pqFE= -github.com/pion/ice/v2 v2.3.32 h1:VwE/uEeqiMm0zUWpdt1DJtnqEkj3UjEbhX92/CurtWI= -github.com/pion/ice/v2 v2.3.32/go.mod h1:8fac0+qftclGy1tYd/nfwfHC729BLaxtVqMdMVCAVPU= +github.com/pion/ice/v2 v2.3.34 h1:Ic1ppYCj4tUOcPAp76U6F3fVrlSw8A9JtRXLqw6BbUM= +github.com/pion/ice/v2 v2.3.34/go.mod h1:mBF7lnigdqgtB+YHkaY/Y6s6tsyRyo4u4rPGRuOjUBQ= github.com/pion/interceptor v0.1.29 h1:39fsnlP1U8gw2JzOFWdfCU82vHvhW9o0rZnZF56wF+M= github.com/pion/interceptor v0.1.29/go.mod h1:ri+LGNjRUc5xUNtDEPzfdkmSqISixVTBF/z/Zms/6T4= github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY= @@ -542,12 +542,12 @@ github.com/pion/srtp/v2 v2.0.20 h1:HNNny4s+OUmG280ETrCdgFndp4ufx3/uy85EawYEhTk= github.com/pion/srtp/v2 v2.0.20/go.mod h1:0KJQjA99A6/a0DOVTu1PhDSw0CXF2jTkqOoMg3ODqdA= github.com/pion/stun v0.6.1 h1:8lp6YejULeHBF8NmV8e2787BogQhduZugh5PdhDyyN4= github.com/pion/stun v0.6.1/go.mod h1:/hO7APkX4hZKu/D0f2lHzNyvdkTGtIy3NDmLR7kSz/8= -github.com/pion/transport/v2 v2.2.9 h1:WEDygVovkJlV2CCunM9KS2kds+kcl7zdIefQA5y/nkE= -github.com/pion/transport/v2 v2.2.9/go.mod h1:sq1kSLWs+cHW9E+2fJP95QudkzbK7wscs8yYgQToO5E= +github.com/pion/transport/v2 v2.2.10 h1:ucLBLE8nuxiHfvkFKnkDQRYWYfp8ejf4YBOPfaQpw6Q= +github.com/pion/transport/v2 v2.2.10/go.mod h1:sq1kSLWs+cHW9E+2fJP95QudkzbK7wscs8yYgQToO5E= github.com/pion/turn/v2 v2.1.6 h1:Xr2niVsiPTB0FPtt+yAWKFUkU1eotQbGgpTIld4x1Gc= github.com/pion/turn/v2 v2.1.6/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY= -github.com/pion/webrtc/v3 v3.2.50 h1:C/rwL2mBfCxHv6tlLzDAO3krJpQXfVx8A8WHnGJ2j34= -github.com/pion/webrtc/v3 v3.2.50/go.mod h1:dytYYoSBy7ZUWhJMbndx9UckgYvzNAfL7xgVnrIKxqo= +github.com/pion/webrtc/v3 v3.3.0 h1:Rf4u6n6U5t5sUxhYPQk/samzU/oDv7jk6BA5hyO2F9I= +github.com/pion/webrtc/v3 v3.3.0/go.mod h1:hVmrDJvwhEertRWObeb1xzulzHGeVUoPlWvxdGzcfU0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= From 893a94864a280653beb8698ca7b0bc7a1f917da8 Mon Sep 17 00:00:00 2001 From: gammazero <11790789+gammazero@users.noreply.github.com> Date: Mon, 19 Aug 2024 19:00:46 -0700 Subject: [PATCH 1126/1212] Add unit test for rpc over unix socket --- test/cli/harness/node.go | 11 +++++++ test/cli/rpc_unixsocket_test.go | 55 +++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 test/cli/rpc_unixsocket_test.go diff --git a/test/cli/harness/node.go b/test/cli/harness/node.go index d030c7c94..dfef4678e 100644 --- a/test/cli/harness/node.go +++ b/test/cli/harness/node.go @@ -349,6 +349,17 @@ func (n *Node) checkAPI(authorization string) bool { log.Debugf("node %d API addr not available yet: %s", n.ID, err.Error()) return false } + + if unixAddr, err := apiAddr.ValueForProtocol(multiaddr.P_UNIX); err == nil { + parts := strings.SplitN(unixAddr, "/", 2) + if len(parts) < 1 { + panic("malformed unix socket address") + } + fileName := "/" + parts[1] + _, err := os.Stat(fileName) + return !errors.Is(err, fs.ErrNotExist) + } + ip, err := apiAddr.ValueForProtocol(multiaddr.P_IP4) if err != nil { panic(err) diff --git a/test/cli/rpc_unixsocket_test.go b/test/cli/rpc_unixsocket_test.go new file mode 100644 index 000000000..902ca71fb --- /dev/null +++ b/test/cli/rpc_unixsocket_test.go @@ -0,0 +1,55 @@ +package cli + +import ( + "context" + //"net" + //"net/http" + "path" + "testing" + + rpcapi "github.com/ipfs/kubo/client/rpc" + ///"github.com/ipfs/kubo/client/rpc/auth" + "github.com/ipfs/kubo/config" + "github.com/ipfs/kubo/test/cli/harness" + "github.com/multiformats/go-multiaddr" + //manet "github.com/multiformats/go-multiaddr/net" + "github.com/stretchr/testify/require" +) + +func TestRPCUnixSocket(t *testing.T) { + node := harness.NewT(t).NewNode().Init() + + sockDir := node.Dir + sockAddr := path.Join("/unix", sockDir, "sock") + + node.UpdateConfig(func(cfg *config.Config) { + //cfg.Addresses.API = append(cfg.Addresses.API, sockPath) + cfg.Addresses.API = []string{sockAddr} + }) + t.Log("Starting daemon with unix socket:", sockAddr) + node.StartDaemon() + + unixMaddr, err := multiaddr.NewMultiaddr(sockAddr) + require.NoError(t, err) + + apiClient, err := rpcapi.NewApi(unixMaddr) + require.NoError(t, err) + + var ver struct { + Version string + } + err = apiClient.Request("version").Exec(context.Background(), &ver) + require.NoError(t, err) + require.NotEmpty(t, ver) + t.Log("Got version:", ver.Version) + + var res struct { + ID string + } + err = apiClient.Request("id").Exec(context.Background(), &res) + require.NoError(t, err) + require.NotEmpty(t, res) + t.Log("Got ID:", res.ID) + + node.StopDaemon() +} From a5f4d0be0241a2c71a2cf395b6b32d3bf502725d Mon Sep 17 00:00:00 2001 From: gammazero <11790789+gammazero@users.noreply.github.com> Date: Mon, 19 Aug 2024 19:55:11 -0700 Subject: [PATCH 1127/1212] Cleanup commented imports --- test/cli/rpc_unixsocket_test.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/test/cli/rpc_unixsocket_test.go b/test/cli/rpc_unixsocket_test.go index 902ca71fb..8cead7388 100644 --- a/test/cli/rpc_unixsocket_test.go +++ b/test/cli/rpc_unixsocket_test.go @@ -2,17 +2,13 @@ package cli import ( "context" - //"net" - //"net/http" "path" "testing" rpcapi "github.com/ipfs/kubo/client/rpc" - ///"github.com/ipfs/kubo/client/rpc/auth" "github.com/ipfs/kubo/config" "github.com/ipfs/kubo/test/cli/harness" "github.com/multiformats/go-multiaddr" - //manet "github.com/multiformats/go-multiaddr/net" "github.com/stretchr/testify/require" ) From fdfd2bc4a16782cce96f7d057f79ba055018d893 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Tue, 20 Aug 2024 17:01:23 +0200 Subject: [PATCH 1128/1212] docs: document rpc over unix socket --- cmd/ipfs/kubo/daemon.go | 5 +++++ docs/changelogs/v0.30.md | 20 +++++++++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/cmd/ipfs/kubo/daemon.go b/cmd/ipfs/kubo/daemon.go index b66e61374..eb9fff8e4 100644 --- a/cmd/ipfs/kubo/daemon.go +++ b/cmd/ipfs/kubo/daemon.go @@ -113,6 +113,11 @@ control your node remotely. If you need to control the node remotely, make sure to protect the port as you would other services or database (firewall, authenticated proxy, etc), or at least set API.Authorizations. +If you do not want to open any ports for RPC, and only want to use +kubo CLI client, it is possible to expose the RPC over Unix socket: + + ipfs config Addresses.API /unix/var/run/kubo.socket + HTTP Headers Kubo supports passing arbitrary headers to the RPC API and Gateway. You can diff --git a/docs/changelogs/v0.30.md b/docs/changelogs/v0.30.md index 314e5a2e0..558511263 100644 --- a/docs/changelogs/v0.30.md +++ b/docs/changelogs/v0.30.md @@ -10,6 +10,7 @@ - [AutoNAT V2 Service Introduced Alongside V1](#autonat-v2-service-introduced-alongside-v1) - [Automated `ipfs version check`](#automated-ipfs-version-check) - [Version Suffix Configuration](#version-suffix-configuration) + - [`/unix/` socket support in `Addresses.API`](#unix-socket-support-in-addressesapi) - [Cleaned Up `ipfs daemon` Startup Log](#cleaned-up-ipfs-daemon-startup-log) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -49,7 +50,24 @@ Defining the optional agent version suffix is now simpler. The [`Version.AgentSu > [!NOTE] > Setting a custom version suffix helps with ecosystem analysis, such as Amino DHT reports published at https://stats.ipfs.network -> + +#### `/unix/` socket support in `Addresses.API` + +This release fixes a bug which blocked users from disabling local HTTP port for [Kubo RPC](https://docs.ipfs.tech/reference/kubo/rpc/), and using a Unix socket instead. + +```console +$ ipfs config Addresses.API "/unix/tmp/kubo.socket" +$ ipfs daemon # start with rpc socket +... +RPC API server listening on /unix/tmp/kubo.socket + +$ # cli client, in different terminal can find socket via /api file +$ cat $IPFS_PATH/api +/unix/tmp/kubo.socket + +$ # or have it pased via --api +$ ipfs --api=/unix/tmp/kubo.socket id +``` #### Cleaned Up `ipfs daemon` Startup Log From 85ab35d60f07e3573cd61526201cffa80c22e17f Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Tue, 20 Aug 2024 17:39:24 +0200 Subject: [PATCH 1129/1212] docs: improve style Co-authored-by: djdv --- docs/changelogs/v0.30.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/changelogs/v0.30.md b/docs/changelogs/v0.30.md index 558511263..7fe13e19e 100644 --- a/docs/changelogs/v0.30.md +++ b/docs/changelogs/v0.30.md @@ -53,7 +53,7 @@ Defining the optional agent version suffix is now simpler. The [`Version.AgentSu #### `/unix/` socket support in `Addresses.API` -This release fixes a bug which blocked users from disabling local HTTP port for [Kubo RPC](https://docs.ipfs.tech/reference/kubo/rpc/), and using a Unix socket instead. +This release fixes a bug which blocked users from using Unix domain sockets for [Kubo's RPC](https://docs.ipfs.tech/reference/kubo/rpc/) (instead of a local HTTP port). ```console $ ipfs config Addresses.API "/unix/tmp/kubo.socket" From 263edb251eecfb375110bcacf170b193ddfea179 Mon Sep 17 00:00:00 2001 From: Andrew Gillis <11790789+gammazero@users.noreply.github.com> Date: Tue, 20 Aug 2024 17:02:46 -0700 Subject: [PATCH 1130/1212] feat: Support storing UnixFS 1.5 Mode and ModTime (#10478) Co-authored-by: Marcin Rataj --- client/rpc/apifile.go | 123 +++++- client/rpc/unixfs.go | 19 +- core/commands/add.go | 120 +++++- core/commands/commands_test.go | 2 + core/commands/files.go | 213 ++++++++-- core/commands/get.go | 9 +- core/commands/ls.go | 7 + core/coreapi/unixfs.go | 6 + core/coreiface/options/unixfs.go | 55 +++ core/coreiface/unixfs.go | 16 +- core/coreunix/add.go | 55 ++- core/node/storage.go | 2 +- docs/changelogs/v0.30.md | 32 ++ docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 +- go.mod | 2 +- go.sum | 4 +- test/dependencies/go.mod | 2 +- test/dependencies/go.sum | 6 +- test/sharness/t0047-add-mode-mtime.sh | 513 +++++++++++++++++++++++++ test/sharness/t0250-files-api.sh | 4 + 21 files changed, 1105 insertions(+), 91 deletions(-) create mode 100755 test/sharness/t0047-add-mode-mtime.sh diff --git a/client/rpc/apifile.go b/client/rpc/apifile.go index 7a54995b1..57d82c5f7 100644 --- a/client/rpc/apifile.go +++ b/client/rpc/apifile.go @@ -1,10 +1,14 @@ package rpc import ( + "bytes" "context" "encoding/json" "fmt" "io" + "os" + "strconv" + "time" "github.com/ipfs/boxo/files" unixfs "github.com/ipfs/boxo/ipld/unixfs" @@ -24,20 +28,35 @@ func (api *UnixfsAPI) Get(ctx context.Context, p path.Path) (files.Node, error) } var stat struct { - Hash string - Type string - Size int64 // unixfs size + Hash string + Type string + Size int64 // unixfs size + Mode string + Mtime int64 + MtimeNsecs int } err := api.core().Request("files/stat", p.String()).Exec(ctx, &stat) if err != nil { return nil, err } + mode, err := stringToFileMode(stat.Mode) + if err != nil { + return nil, err + } + + var modTime time.Time + if stat.Mtime != 0 { + modTime = time.Unix(stat.Mtime, int64(stat.MtimeNsecs)).UTC() + } + switch stat.Type { case "file": - return api.getFile(ctx, p, stat.Size) + return api.getFile(ctx, p, stat.Size, mode, modTime) case "directory": - return api.getDir(ctx, p, stat.Size) + return api.getDir(ctx, p, stat.Size, mode, modTime) + case "symlink": + return api.getSymlink(ctx, p, modTime) default: return nil, fmt.Errorf("unsupported file type '%s'", stat.Type) } @@ -49,6 +68,9 @@ type apiFile struct { size int64 path path.Path + mode os.FileMode + mtime time.Time + r *Response at int64 } @@ -128,16 +150,37 @@ func (f *apiFile) Close() error { return nil } +func (f *apiFile) Mode() os.FileMode { + return f.mode +} + +func (f *apiFile) ModTime() time.Time { + return f.mtime +} + func (f *apiFile) Size() (int64, error) { return f.size, nil } -func (api *UnixfsAPI) getFile(ctx context.Context, p path.Path, size int64) (files.Node, error) { +func stringToFileMode(mode string) (os.FileMode, error) { + if mode == "" { + return 0, nil + } + mode64, err := strconv.ParseUint(mode, 8, 32) + if err != nil { + return 0, fmt.Errorf("cannot parse mode %s: %s", mode, err) + } + return os.FileMode(uint32(mode64)), nil +} + +func (api *UnixfsAPI) getFile(ctx context.Context, p path.Path, size int64, mode os.FileMode, mtime time.Time) (files.Node, error) { f := &apiFile{ - ctx: ctx, - core: api.core(), - size: size, - path: p, + ctx: ctx, + core: api.core(), + size: size, + path: p, + mode: mode, + mtime: mtime, } return f, f.reset() @@ -195,13 +238,19 @@ func (it *apiIter) Next() bool { switch it.cur.Type { case unixfs.THAMTShard, unixfs.TMetadata, unixfs.TDirectory: - it.curFile, err = it.core.getDir(it.ctx, path.FromCid(c), int64(it.cur.Size)) + it.curFile, err = it.core.getDir(it.ctx, path.FromCid(c), int64(it.cur.Size), it.cur.Mode, it.cur.ModTime) if err != nil { it.err = err return false } case unixfs.TFile: - it.curFile, err = it.core.getFile(it.ctx, path.FromCid(c), int64(it.cur.Size)) + it.curFile, err = it.core.getFile(it.ctx, path.FromCid(c), int64(it.cur.Size), it.cur.Mode, it.cur.ModTime) + if err != nil { + it.err = err + return false + } + case unixfs.TSymlink: + it.curFile, err = it.core.getSymlink(it.ctx, path.FromCid(c), it.cur.ModTime) if err != nil { it.err = err return false @@ -223,6 +272,9 @@ type apiDir struct { size int64 path path.Path + mode os.FileMode + mtime time.Time + dec *json.Decoder } @@ -230,6 +282,14 @@ func (d *apiDir) Close() error { return nil } +func (d *apiDir) Mode() os.FileMode { + return d.mode +} + +func (d *apiDir) ModTime() time.Time { + return d.mtime +} + func (d *apiDir) Size() (int64, error) { return d.size, nil } @@ -242,7 +302,7 @@ func (d *apiDir) Entries() files.DirIterator { } } -func (api *UnixfsAPI) getDir(ctx context.Context, p path.Path, size int64) (files.Node, error) { +func (api *UnixfsAPI) getDir(ctx context.Context, p path.Path, size int64, mode os.FileMode, modTime time.Time) (files.Node, error) { resp, err := api.core().Request("ls", p.String()). Option("resolve-size", true). Option("stream", true).Send(ctx) @@ -253,18 +313,43 @@ func (api *UnixfsAPI) getDir(ctx context.Context, p path.Path, size int64) (file return nil, resp.Error } - d := &apiDir{ - ctx: ctx, - core: api, - size: size, - path: p, + data, _ := io.ReadAll(resp.Output) + rdr := bytes.NewReader(data) - dec: json.NewDecoder(resp.Output), + d := &apiDir{ + ctx: ctx, + core: api, + size: size, + path: p, + mode: mode, + mtime: modTime, + + //dec: json.NewDecoder(resp.Output), + dec: json.NewDecoder(rdr), } return d, nil } +func (api *UnixfsAPI) getSymlink(ctx context.Context, p path.Path, modTime time.Time) (files.Node, error) { + resp, err := api.core().Request("cat", p.String()). + Option("resolve-size", true). + Option("stream", true).Send(ctx) + if err != nil { + return nil, err + } + if resp.Error != nil { + return nil, resp.Error + } + + target, err := io.ReadAll(resp.Output) + if err != nil { + return nil, err + } + + return files.NewSymlinkFile(string(target), modTime), nil +} + var ( _ files.File = &apiFile{} _ files.Directory = &apiDir{} diff --git a/client/rpc/unixfs.go b/client/rpc/unixfs.go index 501e8d025..3ba2c1c15 100644 --- a/client/rpc/unixfs.go +++ b/client/rpc/unixfs.go @@ -6,6 +6,8 @@ import ( "errors" "fmt" "io" + "os" + "time" "github.com/ipfs/boxo/files" unixfs "github.com/ipfs/boxo/ipld/unixfs" @@ -80,14 +82,13 @@ func (api *UnixfsAPI) Add(ctx context.Context, f files.Node, opts ...caopts.Unix } defer resp.Output.Close() dec := json.NewDecoder(resp.Output) -loop: + for { var evt addEvent - switch err := dec.Decode(&evt); err { - case nil: - case io.EOF: - break loop - default: + if err := dec.Decode(&evt); err != nil { + if errors.Is(err, io.EOF) { + break + } return path.ImmutablePath{}, err } out = evt @@ -129,6 +130,9 @@ type lsLink struct { Size uint64 Type unixfs_pb.Data_DataType Target string + + Mode os.FileMode + ModTime time.Time } type lsObject struct { @@ -222,6 +226,9 @@ func (api *UnixfsAPI) Ls(ctx context.Context, p path.Path, opts ...caopts.Unixfs Size: l0.Size, Type: ftype, Target: l0.Target, + + Mode: l0.Mode, + ModTime: l0.ModTime, }: case <-ctx.Done(): } diff --git a/core/commands/add.go b/core/commands/add.go index 94a5a0f51..908613025 100644 --- a/core/commands/add.go +++ b/core/commands/add.go @@ -6,7 +6,9 @@ import ( "io" "os" gopath "path" + "strconv" "strings" + "time" "github.com/ipfs/kubo/config" "github.com/ipfs/kubo/core/commands/cmdenv" @@ -25,11 +27,31 @@ import ( // ErrDepthLimitExceeded indicates that the max depth has been exceeded. var ErrDepthLimitExceeded = fmt.Errorf("depth limit exceeded") +type TimeParts struct { + t *time.Time +} + +func (t TimeParts) MarshalJSON() ([]byte, error) { + return t.t.MarshalJSON() +} + +// UnmarshalJSON implements the json.Unmarshaler interface. +// The time is expected to be a quoted string in RFC 3339 format. +func (t *TimeParts) UnmarshalJSON(data []byte) (err error) { + // Fractional seconds are handled implicitly by Parse. + tt, err := time.Parse("\"2006-01-02T15:04:05Z\"", string(data)) + *t = TimeParts{&tt} + return +} + type AddEvent struct { - Name string - Hash string `json:",omitempty"` - Bytes int64 `json:",omitempty"` - Size string `json:",omitempty"` + Name string + Hash string `json:",omitempty"` + Bytes int64 `json:",omitempty"` + Size string `json:",omitempty"` + Mode string `json:",omitempty"` + Mtime int64 `json:",omitempty"` + MtimeNsecs int `json:",omitempty"` } const ( @@ -50,6 +72,12 @@ const ( inlineOptionName = "inline" inlineLimitOptionName = "inline-limit" toFilesOptionName = "to-files" + + preserveModeOptionName = "preserve-mode" + preserveMtimeOptionName = "preserve-mtime" + modeOptionName = "mode" + mtimeOptionName = "mtime" + mtimeNsecsOptionName = "mtime-nsecs" ) const adderOutChanSize = 8 @@ -166,22 +194,24 @@ See 'dag export' and 'dag import' for more information. cmds.IntOption(inlineLimitOptionName, "Maximum block size to inline. (experimental)").WithDefault(32), cmds.BoolOption(pinOptionName, "Pin locally to protect added files from garbage collection.").WithDefault(true), cmds.StringOption(toFilesOptionName, "Add reference to Files API (MFS) at the provided path."), + cmds.BoolOption(preserveModeOptionName, "Apply existing POSIX permissions to created UnixFS entries. Disables raw-leaves. (experimental)"), + cmds.BoolOption(preserveMtimeOptionName, "Apply existing POSIX modification time to created UnixFS entries. Disables raw-leaves. (experimental)"), + cmds.UintOption(modeOptionName, "Custom POSIX file mode to store in created UnixFS entries. Disables raw-leaves. (experimental)"), + cmds.Int64Option(mtimeOptionName, "Custom POSIX modification time to store in created UnixFS entries (seconds before or after the Unix Epoch). Disables raw-leaves. (experimental)"), + cmds.UintOption(mtimeNsecsOptionName, "Custom POSIX modification time (optional time fraction in nanoseconds)"), }, PreRun: func(req *cmds.Request, env cmds.Environment) error { quiet, _ := req.Options[quietOptionName].(bool) quieter, _ := req.Options[quieterOptionName].(bool) quiet = quiet || quieter - silent, _ := req.Options[silentOptionName].(bool) - if quiet || silent { - return nil - } - - // ipfs cli progress bar defaults to true unless quiet or silent is used - _, found := req.Options[progressOptionName].(bool) - if !found { - req.Options[progressOptionName] = true + if !quiet && !silent { + // ipfs cli progress bar defaults to true unless quiet or silent is used + _, found := req.Options[progressOptionName].(bool) + if !found { + req.Options[progressOptionName] = true + } } return nil @@ -217,6 +247,11 @@ See 'dag export' and 'dag import' for more information. inline, _ := req.Options[inlineOptionName].(bool) inlineLimit, _ := req.Options[inlineLimitOptionName].(int) toFilesStr, toFilesSet := req.Options[toFilesOptionName].(string) + preserveMode, _ := req.Options[preserveModeOptionName].(bool) + preserveMtime, _ := req.Options[preserveMtimeOptionName].(bool) + mode, _ := req.Options[modeOptionName].(uint) + mtime, _ := req.Options[mtimeOptionName].(int64) + mtimeNsecs, _ := req.Options[mtimeNsecsOptionName].(uint) if chunker == "" { chunker = cfg.Import.UnixFSChunker.WithDefault(config.DefaultUnixFSChunker) @@ -236,6 +271,19 @@ See 'dag export' and 'dag import' for more information. rawblks = cfg.Import.UnixFSRawLeaves.WithDefault(config.DefaultUnixFSRawLeaves) } + // Storing optional mode or mtime (UnixFS 1.5) requires root block + // to always be 'dag-pb' and not 'raw'. Below adjusts raw-leaves setting, if possible. + if preserveMode || preserveMtime || mode != 0 || mtime != 0 { + // Error if --raw-leaves flag was explicitly passed by the user. + // (let user make a decision to manually disable it and retry) + if rbset && rawblks { + return fmt.Errorf("%s can't be used with UnixFS metadata like mode or modification time", rawLeavesOptionName) + } + // No explicit preference from user, disable raw-leaves and continue + rbset = true + rawblks = false + } + if onlyHash && toFilesSet { return fmt.Errorf("%s and %s options are not compatible", onlyHashOptionName, toFilesOptionName) } @@ -272,6 +320,19 @@ See 'dag export' and 'dag import' for more information. options.Unixfs.Progress(progress), options.Unixfs.Silent(silent), + + options.Unixfs.PreserveMode(preserveMode), + options.Unixfs.PreserveMtime(preserveMtime), + } + + if mode != 0 { + opts = append(opts, options.Unixfs.Mode(os.FileMode(mode))) + } + + if mtime != 0 { + opts = append(opts, options.Unixfs.Mtime(mtime, uint32(mtimeNsecs))) + } else if mtimeNsecs != 0 { + return fmt.Errorf("option %q requires %q to be provided as well", mtimeNsecsOptionName, mtimeOptionName) } if cidVerSet { @@ -383,12 +444,33 @@ See 'dag export' and 'dag import' for more information. output.Name = gopath.Join(addit.Name(), output.Name) } - if err := res.Emit(&AddEvent{ - Name: output.Name, - Hash: h, - Bytes: output.Bytes, - Size: output.Size, - }); err != nil { + output.Mode = addit.Node().Mode() + if ts := addit.Node().ModTime(); !ts.IsZero() { + output.Mtime = addit.Node().ModTime().Unix() + output.MtimeNsecs = addit.Node().ModTime().Nanosecond() + } + + addEvent := AddEvent{ + Name: output.Name, + Hash: h, + Bytes: output.Bytes, + Size: output.Size, + Mtime: output.Mtime, + MtimeNsecs: output.MtimeNsecs, + } + + if output.Mode != 0 { + addEvent.Mode = "0" + strconv.FormatUint(uint64(output.Mode), 8) + } + + if output.Mtime > 0 { + addEvent.Mtime = output.Mtime + if output.MtimeNsecs > 0 { + addEvent.MtimeNsecs = output.MtimeNsecs + } + } + + if err := res.Emit(&addEvent); err != nil { return err } } diff --git a/core/commands/commands_test.go b/core/commands/commands_test.go index 018b6734e..b04a5459b 100644 --- a/core/commands/commands_test.go +++ b/core/commands/commands_test.go @@ -89,6 +89,8 @@ func TestCommands(t *testing.T) { "/files/rm", "/files/stat", "/files/write", + "/files/chmod", + "/files/touch", "/filestore", "/filestore/dups", "/filestore/ls", diff --git a/core/commands/files.go b/core/commands/files.go index 12891a730..6add671ce 100644 --- a/core/commands/files.go +++ b/core/commands/files.go @@ -2,13 +2,16 @@ package commands import ( "context" + "encoding/json" "errors" "fmt" "io" "os" gopath "path" "sort" + "strconv" "strings" + "time" humanize "github.com/dustin/go-humanize" "github.com/ipfs/kubo/config" @@ -81,6 +84,8 @@ operations. "rm": filesRmCmd, "flush": filesFlushCmd, "chcid": filesChcidCmd, + "chmod": filesChmodCmd, + "touch": filesTouchCmd, }, } @@ -105,6 +110,43 @@ type statOutput struct { WithLocality bool `json:",omitempty"` Local bool `json:",omitempty"` SizeLocal uint64 `json:",omitempty"` + Mode uint32 `json:",omitempty"` + Mtime int64 `json:",omitempty"` + MtimeNsecs int `json:",omitempty"` +} + +func (s *statOutput) MarshalJSON() ([]byte, error) { + type so statOutput + out := &struct { + *so + Mode string `json:",omitempty"` + }{so: (*so)(s)} + + if s.Mode != 0 { + out.Mode = fmt.Sprintf("%04o", s.Mode) + } + return json.Marshal(out) +} + +func (s *statOutput) UnmarshalJSON(data []byte) error { + var err error + type so statOutput + tmp := &struct { + *so + Mode string `json:",omitempty"` + }{so: (*so)(s)} + + if err := json.Unmarshal(data, &tmp); err != nil { + return err + } + + if tmp.Mode != "" { + mode, err := strconv.ParseUint(tmp.Mode, 8, 32) + if err == nil { + s.Mode = uint32(mode) + } + } + return err } const ( @@ -112,10 +154,13 @@ const ( Size: CumulativeSize: ChildBlocks: -Type: ` +Type: +Mode: () +Mtime: ` filesFormatOptionName = "format" filesSizeOptionName = "size" filesWithLocalOptionName = "with-local" + filesStatUnspecified = "not set" ) var filesStatCmd = &cmds.Command{ @@ -128,7 +173,8 @@ var filesStatCmd = &cmds.Command{ }, Options: []cmds.Option{ cmds.StringOption(filesFormatOptionName, "Print statistics in given format. Allowed tokens: "+ - " . Conflicts with other format options.").WithDefault(defaultStatFormat), + " and optional ."+ + "Conflicts with other format options.").WithDefault(defaultStatFormat), cmds.BoolOption(filesHashOptionName, "Print only hash. Implies '--format='. Conflicts with other format options."), cmds.BoolOption(filesSizeOptionName, "Print only size. Implies '--format='. Conflicts with other format options."), cmds.BoolOption(filesWithLocalOptionName, "Compute the amount of the dag that is local, and if possible the total size"), @@ -199,12 +245,29 @@ var filesStatCmd = &cmds.Command{ }, Encoders: cmds.EncoderMap{ cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *statOutput) error { + mode, modeo := filesStatUnspecified, filesStatUnspecified + if out.Mode != 0 { + mode = strings.ToLower(os.FileMode(out.Mode).String()) + modeo = "0" + strconv.FormatInt(int64(out.Mode&0x1FF), 8) + } + mtime, mtimes, mtimens := filesStatUnspecified, filesStatUnspecified, filesStatUnspecified + if out.Mtime > 0 { + mtime = time.Unix(out.Mtime, int64(out.MtimeNsecs)).UTC().Format("2 Jan 2006, 15:04:05 MST") + mtimes = strconv.FormatInt(out.Mtime, 10) + mtimens = strconv.Itoa(out.MtimeNsecs) + } + s, _ := statGetFormatOptions(req) s = strings.Replace(s, "", out.Hash, -1) s = strings.Replace(s, "", fmt.Sprintf("%d", out.Size), -1) s = strings.Replace(s, "", fmt.Sprintf("%d", out.CumulativeSize), -1) s = strings.Replace(s, "", fmt.Sprintf("%d", out.Blocks), -1) s = strings.Replace(s, "", out.Type, -1) + s = strings.Replace(s, "", mode, -1) + s = strings.Replace(s, "", modeo, -1) + s = strings.Replace(s, "", mtime, -1) + s = strings.Replace(s, "", mtimes, -1) + s = strings.Replace(s, "", mtimens, -1) fmt.Fprintln(w, s) @@ -254,28 +317,7 @@ func statNode(nd ipld.Node, enc cidenc.Encoder) (*statOutput, error) { switch n := nd.(type) { case *dag.ProtoNode: - d, err := ft.FSNodeFromBytes(n.Data()) - if err != nil { - return nil, err - } - - var ndtype string - switch d.Type() { - case ft.TDirectory, ft.THAMTShard: - ndtype = "directory" - case ft.TFile, ft.TMetadata, ft.TRaw: - ndtype = "file" - default: - return nil, fmt.Errorf("unrecognized node type: %s", d.Type()) - } - - return &statOutput{ - Hash: enc.Encode(c), - Blocks: len(nd.Links()), - Size: d.FileSize(), - CumulativeSize: cumulsize, - Type: ndtype, - }, nil + return statProtoNode(n, enc, c, cumulsize) case *dag.RawNode: return &statOutput{ Hash: enc.Encode(c), @@ -289,6 +331,44 @@ func statNode(nd ipld.Node, enc cidenc.Encoder) (*statOutput, error) { } } +func statProtoNode(n *dag.ProtoNode, enc cidenc.Encoder, cid cid.Cid, cumulsize uint64) (*statOutput, error) { + d, err := ft.FSNodeFromBytes(n.Data()) + if err != nil { + return nil, err + } + + stat := statOutput{ + Hash: enc.Encode(cid), + Blocks: len(n.Links()), + Size: d.FileSize(), + CumulativeSize: cumulsize, + } + + switch d.Type() { + case ft.TDirectory, ft.THAMTShard: + stat.Type = "directory" + case ft.TFile, ft.TSymlink, ft.TMetadata, ft.TRaw: + stat.Type = "file" + default: + return nil, fmt.Errorf("unrecognized node type: %s", d.Type()) + } + + if mode := d.Mode(); mode != 0 { + stat.Mode = uint32(mode) + } else if d.Type() == ft.TSymlink { + stat.Mode = uint32(os.ModeSymlink | 0x1FF) + } + + if mt := d.ModTime(); !mt.IsZero() { + stat.Mtime = mt.Unix() + if ns := mt.Nanosecond(); ns > 0 { + stat.MtimeNsecs = ns + } + } + + return &stat, nil +} + func walkBlock(ctx context.Context, dagserv ipld.DAGService, nd ipld.Node) (bool, uint64, error) { // Start with the block data size sizeLocal := uint64(len(nd.RawData())) @@ -341,7 +421,7 @@ $ ipfs add --quieter --pin=false $ ipfs files cp /ipfs/ /your/desired/mfs/path If you wish to fully copy content from a different IPFS peer into MFS, do not -forget to force IPFS to fetch to full DAG after doing the "cp" operation. i.e: +forget to force IPFS to fetch the full DAG after doing a "cp" operation. i.e: $ ipfs files cp /ipfs/ /your/desired/mfs/path $ ipfs pin add @@ -1313,3 +1393,86 @@ func getParentDir(root *mfs.Root, dir string) (*mfs.Directory, error) { } return pdir, nil } + +var filesChmodCmd = &cmds.Command{ + Status: cmds.Experimental, + Helptext: cmds.HelpText{ + Tagline: "Change optional POSIX mode permissions", + ShortDescription: ` +The mode argument must be specified in Unix numeric notation. + + $ ipfs files chmod 0644 /foo + $ ipfs files stat /foo + ... + Type: file + Mode: -rw-r--r-- (0644) + ... +`, + }, + Arguments: []cmds.Argument{ + cmds.StringArg("mode", true, false, "Mode to apply to node (numeric notation)"), + cmds.StringArg("path", true, false, "Path to apply mode"), + }, + Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { + nd, err := cmdenv.GetNode(env) + if err != nil { + return err + } + + path, err := checkPath(req.Arguments[1]) + if err != nil { + return err + } + + mode, err := strconv.ParseInt(req.Arguments[0], 8, 32) + if err != nil { + return err + } + + return mfs.Chmod(nd.FilesRoot, path, os.FileMode(mode)) + }, +} + +var filesTouchCmd = &cmds.Command{ + Status: cmds.Experimental, + Helptext: cmds.HelpText{ + Tagline: "Set or change optional POSIX modification times.", + ShortDescription: ` +Examples: + # set modification time to now. + $ ipfs files touch /foo + # set a custom modification time. + $ ipfs files touch --mtime=1630937926 /foo +`, + }, + Arguments: []cmds.Argument{ + cmds.StringArg("path", true, false, "Path of target to update."), + }, + Options: []cmds.Option{ + cmds.Int64Option(mtimeOptionName, "Modification time in seconds before or since the Unix Epoch to apply to created UnixFS entries."), + cmds.UintOption(mtimeNsecsOptionName, "Modification time fraction in nanoseconds"), + }, + Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { + nd, err := cmdenv.GetNode(env) + if err != nil { + return err + } + + path, err := checkPath(req.Arguments[0]) + if err != nil { + return err + } + + mtime, _ := req.Options[mtimeOptionName].(int64) + nsecs, _ := req.Options[mtimeNsecsOptionName].(uint) + + var ts time.Time + if mtime != 0 { + ts = time.Unix(mtime, int64(nsecs)).UTC() + } else { + ts = time.Now().UTC() + } + + return mfs.Touch(nd.FilesRoot, path, ts) + }, +} diff --git a/core/commands/get.go b/core/commands/get.go index 5b64c281b..12a3ea8ca 100644 --- a/core/commands/get.go +++ b/core/commands/get.go @@ -1,6 +1,7 @@ package commands import ( + gotar "archive/tar" "bufio" "compress/gzip" "errors" @@ -331,7 +332,8 @@ func fileArchive(f files.Node, name string, archive bool, compression int) (io.R closeGzwAndPipe() // everything seems to be ok }() } else { - // the case for 1. archive, and 2. not archived and not compressed, in which tar is used anyway as a transport format + // the case for 1. archive, and 2. not archived and not compressed, in + // which tar is used anyway as a transport format // construct the tar writer w, err := files.NewTarWriter(maybeGzw) @@ -339,6 +341,11 @@ func fileArchive(f files.Node, name string, archive bool, compression int) (io.R return nil, err } + // if not creating an archive set the format to PAX in order to preserve nanoseconds + if !archive { + w.SetFormat(gotar.FormatPAX) + } + go func() { // write all the nodes recursively if err := w.WriteFile(f, filename); checkErrAndClosePipe(err) { diff --git a/core/commands/ls.go b/core/commands/ls.go index 6fd535282..ab914bb0e 100644 --- a/core/commands/ls.go +++ b/core/commands/ls.go @@ -6,6 +6,7 @@ import ( "os" "sort" "text/tabwriter" + "time" cmdenv "github.com/ipfs/kubo/core/commands/cmdenv" "github.com/ipfs/kubo/core/commands/cmdutils" @@ -23,6 +24,8 @@ type LsLink struct { Size uint64 Type unixfs_pb.Data_DataType Target string + Mode os.FileMode + ModTime time.Time } // LsObject is an element of LsOutput @@ -163,6 +166,9 @@ The JSON output contains type information. Size: link.Size, Type: ftype, Target: link.Target, + + Mode: link.Mode, + ModTime: link.ModTime, } if err := processLink(paths[i], lsLink); err != nil { return err @@ -256,6 +262,7 @@ func tabularOutput(req *cmds.Request, w io.Writer, out *LsOutput, lastObjectHash } } + // TODO: Print link.Mode and link.ModTime? fmt.Fprintf(tw, s, link.Hash, link.Size, cmdenv.EscNonPrint(link.Name)) } } diff --git a/core/coreapi/unixfs.go b/core/coreapi/unixfs.go index 860574945..e175488f3 100644 --- a/core/coreapi/unixfs.go +++ b/core/coreapi/unixfs.go @@ -130,6 +130,10 @@ func (api *UnixfsAPI) Add(ctx context.Context, files files.Node, opts ...options fileAdder.RawLeaves = settings.RawLeaves fileAdder.NoCopy = settings.NoCopy fileAdder.CidBuilder = prefix + fileAdder.PreserveMode = settings.PreserveMode + fileAdder.PreserveMtime = settings.PreserveMtime + fileAdder.FileMode = settings.Mode + fileAdder.FileMtime = settings.Mtime switch settings.Layout { case options.BalancedLayout: @@ -270,6 +274,8 @@ func (api *UnixfsAPI) processLink(ctx context.Context, linkres ft.LinkResult, se if !settings.UseCumulativeSize { lnk.Size = d.FileSize() } + lnk.Mode = d.Mode() + lnk.ModTime = d.ModTime() } } diff --git a/core/coreiface/options/unixfs.go b/core/coreiface/options/unixfs.go index f00fffb87..c837ec1b2 100644 --- a/core/coreiface/options/unixfs.go +++ b/core/coreiface/options/unixfs.go @@ -3,6 +3,8 @@ package options import ( "errors" "fmt" + "os" + "time" dag "github.com/ipfs/boxo/ipld/merkledag" cid "github.com/ipfs/go-cid" @@ -36,6 +38,11 @@ type UnixfsAddSettings struct { Events chan<- interface{} Silent bool Progress bool + + PreserveMode bool + PreserveMtime bool + Mode os.FileMode + Mtime time.Time } type UnixfsLsSettings struct { @@ -69,6 +76,11 @@ func UnixfsAddOptions(opts ...UnixfsAddOption) (*UnixfsAddSettings, cid.Prefix, Events: nil, Silent: false, Progress: false, + + PreserveMode: false, + PreserveMtime: false, + Mode: 0, + Mtime: time.Time{}, } for _, opt := range opts { @@ -106,6 +118,14 @@ func UnixfsAddOptions(opts ...UnixfsAddOption) (*UnixfsAddSettings, cid.Prefix, } } + if !options.Mtime.IsZero() && options.PreserveMtime { + options.PreserveMtime = false + } + + if options.Mode != 0 && options.PreserveMode { + options.PreserveMode = false + } + // cidV1 -> raw blocks (by default) if options.CidVersion > 0 && !options.RawLeavesSet { options.RawLeaves = true @@ -293,3 +313,38 @@ func (unixfsOpts) UseCumulativeSize(use bool) UnixfsLsOption { return nil } } + +// PreserveMode tells the adder to store the file permissions +func (unixfsOpts) PreserveMode(enable bool) UnixfsAddOption { + return func(settings *UnixfsAddSettings) error { + settings.PreserveMode = enable + return nil + } +} + +// PreserveMtime tells the adder to store the file modification time +func (unixfsOpts) PreserveMtime(enable bool) UnixfsAddOption { + return func(settings *UnixfsAddSettings) error { + settings.PreserveMtime = enable + return nil + } +} + +// Mode represents a unix file mode +func (unixfsOpts) Mode(mode os.FileMode) UnixfsAddOption { + return func(settings *UnixfsAddSettings) error { + settings.Mode = mode + return nil + } +} + +// Mtime represents a unix file mtime +func (unixfsOpts) Mtime(seconds int64, nsecs uint32) UnixfsAddOption { + return func(settings *UnixfsAddSettings) error { + if nsecs > 999999999 { + return errors.New("mtime nanoseconds must be in range [1, 999999999]") + } + settings.Mtime = time.Unix(seconds, int64(nsecs)) + return nil + } +} diff --git a/core/coreiface/unixfs.go b/core/coreiface/unixfs.go index d0dc4d8ce..c0150bd12 100644 --- a/core/coreiface/unixfs.go +++ b/core/coreiface/unixfs.go @@ -2,6 +2,8 @@ package iface import ( "context" + "os" + "time" "github.com/ipfs/boxo/files" "github.com/ipfs/boxo/path" @@ -10,10 +12,13 @@ import ( ) type AddEvent struct { - Name string - Path path.ImmutablePath `json:",omitempty"` - Bytes int64 `json:",omitempty"` - Size string `json:",omitempty"` + Name string + Path path.ImmutablePath `json:",omitempty"` + Bytes int64 `json:",omitempty"` + Size string `json:",omitempty"` + Mode os.FileMode `json:",omitempty"` + Mtime int64 `json:",omitempty"` + MtimeNsecs int `json:",omitempty"` } // FileType is an enum of possible UnixFS file types. @@ -56,6 +61,9 @@ type DirEntry struct { Type FileType // The type of the file. Target string // The symlink target (if a symlink). + Mode os.FileMode + ModTime time.Time + Err error } diff --git a/core/coreunix/add.go b/core/coreunix/add.go index a8d7e5982..5f7cbb610 100644 --- a/core/coreunix/add.go +++ b/core/coreunix/add.go @@ -5,8 +5,10 @@ import ( "errors" "fmt" "io" + "os" gopath "path" "strconv" + "time" bstore "github.com/ipfs/boxo/blockstore" chunker "github.com/ipfs/boxo/chunker" @@ -81,6 +83,11 @@ type Adder struct { tempRoot cid.Cid CidBuilder cid.Builder liveNodes uint64 + + PreserveMode bool + PreserveMtime bool + FileMode os.FileMode + FileMtime time.Time } func (adder *Adder) mfsRoot() (*mfs.Root, error) { @@ -113,11 +120,13 @@ func (adder *Adder) add(reader io.Reader) (ipld.Node, error) { } params := ihelper.DagBuilderParams{ - Dagserv: adder.bufferedDS, - RawLeaves: adder.RawLeaves, - Maxlinks: ihelper.DefaultLinksPerBlock, - NoCopy: adder.NoCopy, - CidBuilder: adder.CidBuilder, + Dagserv: adder.bufferedDS, + RawLeaves: adder.RawLeaves, + Maxlinks: ihelper.DefaultLinksPerBlock, + NoCopy: adder.NoCopy, + CidBuilder: adder.CidBuilder, + FileMode: adder.FileMode, + FileModTime: adder.FileMtime, } db, err := params.New(chnk) @@ -359,6 +368,14 @@ func (adder *Adder) addFileNode(ctx context.Context, path string, file files.Nod return err } + if adder.PreserveMtime { + adder.FileMtime = file.ModTime() + } + + if adder.PreserveMode { + adder.FileMode = file.Mode() + } + if adder.liveNodes >= liveCacheSize { // TODO: A smarter cache that uses some sort of lru cache with an eviction handler mr, err := adder.mfsRoot() @@ -391,6 +408,18 @@ func (adder *Adder) addSymlink(path string, l *files.Symlink) error { return err } + if !adder.FileMtime.IsZero() { + fsn, err := unixfs.FSNodeFromBytes(sdata) + if err != nil { + return err + } + + fsn.SetModTime(adder.FileMtime) + if sdata, err = fsn.GetBytes(); err != nil { + return err + } + } + dagnode := dag.NodeWithData(sdata) err = dagnode.SetCidBuilder(adder.CidBuilder) if err != nil { @@ -429,6 +458,20 @@ func (adder *Adder) addFile(path string, file files.File) error { func (adder *Adder) addDir(ctx context.Context, path string, dir files.Directory, toplevel bool) error { log.Infof("adding directory: %s", path) + // if we need to store mode or modification time then create a new root which includes that data + if toplevel && (adder.FileMode != 0 || !adder.FileMtime.IsZero()) { + nd := unixfs.EmptyDirNodeWithStat(adder.FileMode, adder.FileMtime) + err := nd.SetCidBuilder(adder.CidBuilder) + if err != nil { + return err + } + mr, err := mfs.NewRoot(ctx, adder.dagService, nd, nil) + if err != nil { + return err + } + adder.SetMfsRoot(mr) + } + if !(toplevel && path == "") { mr, err := adder.mfsRoot() if err != nil { @@ -438,6 +481,8 @@ func (adder *Adder) addDir(ctx context.Context, path string, dir files.Directory Mkparents: true, Flush: false, CidBuilder: adder.CidBuilder, + Mode: adder.FileMode, + ModTime: adder.FileMtime, }) if err != nil { return err diff --git a/core/node/storage.go b/core/node/storage.go index a303ddc23..aedf0ee6a 100644 --- a/core/node/storage.go +++ b/core/node/storage.go @@ -56,7 +56,7 @@ func GcBlockstoreCtor(bb BaseBlocks) (gclocker blockstore.GCLocker, gcbs blockst return } -// GcBlockstoreCtor wraps GcBlockstore and adds Filestore support +// FilestoreBlockstoreCtor wraps GcBlockstore and adds Filestore support func FilestoreBlockstoreCtor(repo repo.Repo, bb BaseBlocks) (gclocker blockstore.GCLocker, gcbs blockstore.GCBlockstore, bs blockstore.Blockstore, fstore *filestore.Filestore) { gclocker = blockstore.NewGCLocker() diff --git a/docs/changelogs/v0.30.md b/docs/changelogs/v0.30.md index 7fe13e19e..6cc212f7a 100644 --- a/docs/changelogs/v0.30.md +++ b/docs/changelogs/v0.30.md @@ -12,6 +12,7 @@ - [Version Suffix Configuration](#version-suffix-configuration) - [`/unix/` socket support in `Addresses.API`](#unix-socket-support-in-addressesapi) - [Cleaned Up `ipfs daemon` Startup Log](#cleaned-up-ipfs-daemon-startup-log) + - [UnixFS 1.5: Mode and Modification Time Support](#unixfs-15-mode-and-modification-time-support) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -96,6 +97,37 @@ The previous lengthy listing of all listener and announced multiaddrs has been r The output now features a simplified list of swarm listeners, displayed in the format `host:port (TCP+UDP)`, which provides essential information for debugging connectivity issues, particularly related to port forwarding. Announced libp2p addresses are no longer printed on startup, because libp2p may change or augument them based on AutoNAT, relay, and UPnP state. Instead, users are prompted to run `ipfs id` to obtain up-to-date list of listeners and announced multiaddrs in libp2p format. +#### UnixFS 1.5: Mode and Modification Time Support + +Kubo now allows users to opt-in to store mode and modification time for files, directories, and symbolic links. +By default, if you do not opt-in, the old behavior remains unchanged, and the same CIDs will be generated as before. + +The `ipfs add` CLI options `--preserve-mode` and `--preserve-mtime` can be used to store the original mode and last modified time of the file being added, and `ipfs files stat /ipfs/CID` can be used for inspecting these optional attributes: + +```console +$ touch ./file +$ chmod 654 ./file +$ ipfs add --preserve-mode --preserve-mtime -Q ./file +QmczQr4XS1rRnWVopyg5Chr9EQ7JKpbhgnrjpb5kTQ1DKQ + +$ ipfs files stat /ipfs/QmczQr4XS1rRnWVopyg5Chr9EQ7JKpbhgnrjpb5kTQ1DKQ +QmczQr4XS1rRnWVopyg5Chr9EQ7JKpbhgnrjpb5kTQ1DKQ +Size: 0 +CumulativeSize: 22 +ChildBlocks: 0 +Type: file +Mode: -rw-r-xr-- (0654) +Mtime: 13 Aug 2024, 21:15:31 UTC +``` + +The CLI and HTTP RPC options `--mode`, `--mtime` and `--mtime-nsecs` can be used to set them to arbitrary values. + +Opt-in support for `mode` and `mtime` was also added to MFS (`ipfs files --help`). For more information see `--help` text of `ipfs files touch|stat|chmod` commands. + + +> [!NOTE] +> Storing `mode` and `mtime` requires root block to be `dag-pb` and disabled `raw-leaves` setting to create envelope for storing the metadata. + ### 📝 Changelog ### 👨‍👩‍👧‍👦 Contributors diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index c51eb189d..79d8d4600 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -9,7 +9,7 @@ toolchain go1.22.0 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.22.0 + github.com/ipfs/boxo v0.22.1-0.20240820234446-aa27cd2f8053 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.36.2 github.com/multiformats/go-multiaddr v0.13.0 diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 71d5bd54a..2d2f68eb7 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -266,8 +266,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.22.0 h1:QTC+P5uhsBNq6HzX728nsLyFW6rYDeR/5hggf9YZX78= -github.com/ipfs/boxo v0.22.0/go.mod h1:yp1loimX0BDYOR0cyjtcXHv15muEh5V1FqO2QLlzykw= +github.com/ipfs/boxo v0.22.1-0.20240820234446-aa27cd2f8053 h1:rW0xGaZW9+74cc8etCm6DwrHhIEtNxklFn8YrUaWjx4= +github.com/ipfs/boxo v0.22.1-0.20240820234446-aa27cd2f8053/go.mod h1:bMB1tnSTr+6/CS5p3jkS4rtifpl+ul6P4ZgeTZn8Ty0= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= diff --git a/go.mod b/go.mod index ee336089e..65e2ac295 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( github.com/hashicorp/go-version v1.6.0 github.com/ipfs-shipyard/nopfs v0.0.12 github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c - github.com/ipfs/boxo v0.22.0 + github.com/ipfs/boxo v0.22.1-0.20240820234446-aa27cd2f8053 github.com/ipfs/go-block-format v0.2.0 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 diff --git a/go.sum b/go.sum index 05be97779..f5a27bc2e 100644 --- a/go.sum +++ b/go.sum @@ -330,8 +330,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.22.0 h1:QTC+P5uhsBNq6HzX728nsLyFW6rYDeR/5hggf9YZX78= -github.com/ipfs/boxo v0.22.0/go.mod h1:yp1loimX0BDYOR0cyjtcXHv15muEh5V1FqO2QLlzykw= +github.com/ipfs/boxo v0.22.1-0.20240820234446-aa27cd2f8053 h1:rW0xGaZW9+74cc8etCm6DwrHhIEtNxklFn8YrUaWjx4= +github.com/ipfs/boxo v0.22.1-0.20240820234446-aa27cd2f8053/go.mod h1:bMB1tnSTr+6/CS5p3jkS4rtifpl+ul6P4ZgeTZn8Ty0= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 277b31541..a263e3d98 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -113,7 +113,7 @@ require ( github.com/hexops/gotextdiff v1.0.3 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/ipfs/bbloom v0.0.4 // indirect - github.com/ipfs/boxo v0.22.0 // indirect + github.com/ipfs/boxo v0.22.1-0.20240820234446-aa27cd2f8053 // indirect github.com/ipfs/go-block-format v0.2.0 // indirect github.com/ipfs/go-cid v0.4.1 // indirect github.com/ipfs/go-datastore v0.6.0 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 8553ddb6e..27876d29f 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -280,8 +280,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.22.0 h1:QTC+P5uhsBNq6HzX728nsLyFW6rYDeR/5hggf9YZX78= -github.com/ipfs/boxo v0.22.0/go.mod h1:yp1loimX0BDYOR0cyjtcXHv15muEh5V1FqO2QLlzykw= +github.com/ipfs/boxo v0.22.1-0.20240820234446-aa27cd2f8053 h1:rW0xGaZW9+74cc8etCm6DwrHhIEtNxklFn8YrUaWjx4= +github.com/ipfs/boxo v0.22.1-0.20240820234446-aa27cd2f8053/go.mod h1:bMB1tnSTr+6/CS5p3jkS4rtifpl+ul6P4ZgeTZn8Ty0= github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs= github.com/ipfs/go-block-format v0.2.0/go.mod h1:+jpL11nFx5A/SPpsoBn6Bzkra/zaArfSmsknbPMYgzM= github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= @@ -292,8 +292,6 @@ github.com/ipfs/go-datastore v0.6.0 h1:JKyz+Gvz1QEZw0LsX1IBn+JFCJQH4SJVFtM4uWU0M github.com/ipfs/go-datastore v0.6.0/go.mod h1:rt5M3nNbSO/8q1t4LNkLyUwRs8HupMeN/8O4Vn9YAT8= github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk= github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps= -github.com/ipfs/go-ipfs-blocksutil v0.0.1 h1:Eh/H4pc1hsvhzsQoMEP3Bke/aW5P5rVM1IWFJMcGIPQ= -github.com/ipfs/go-ipfs-blocksutil v0.0.1/go.mod h1:Yq4M86uIOmxmGPUHv/uI7uKqZNtLb449gwKqXjIsnRk= github.com/ipfs/go-ipfs-delay v0.0.1 h1:r/UXYyRcddO6thwOnhiznIAiSvxMECGgtv35Xs1IeRQ= github.com/ipfs/go-ipfs-delay v0.0.1/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= github.com/ipfs/go-ipfs-pq v0.0.3 h1:YpoHVJB+jzK15mr/xsWC574tyDLkezVrDNeaalQBsTE= diff --git a/test/sharness/t0047-add-mode-mtime.sh b/test/sharness/t0047-add-mode-mtime.sh new file mode 100755 index 000000000..520c692f3 --- /dev/null +++ b/test/sharness/t0047-add-mode-mtime.sh @@ -0,0 +1,513 @@ +#!/usr/bin/env bash + +test_description="Test storing and retrieving mode and mtime" + +. lib/test-lib.sh + +test_init_ipfs + +test_expect_success "set Import defaults to ensure deterministic cids for mod and mtime tests" ' + ipfs config --json Import.CidVersion 0 && + ipfs config Import.HashFunction sha2-256 && + ipfs config Import.UnixFSChunker size-262144 +' + +HASH_NO_PRESERVE=QmbFMke1KXqnYyBBWxB74N4c5SBnJMVAiMNRcGu6x1AwQH + +PRESERVE_MTIME=1604320482 +PRESERVE_MODE="0640" +HASH_PRESERVE_MODE=QmQLgxypSNGNFTuUPGCecq6dDEjb6hNB5xSyVmP3cEuNtq +HASH_PRESERVE_MTIME=QmQ6kErEW8kztQFV8vbwNU8E4dmtGsYpRiboiLxUEwibvj +HASH_PRESERVE_LINK_MTIME=QmbJwotgtr84JxcnjpwJ86uZiyMoxbZuNH4YrdJMypkYaB +HASH_PRESERVE_MODE_AND_MTIME=QmYkvboLsvLFcSYmqVJRxvBdYRQLroLv9kELf3LRiCqBri + +CUSTOM_MTIME=1603539720 +CUSTOM_MTIME_NSECS=54321 +CUSTOM_MODE="0764" +HASH_CUSTOM_MODE=QmchD3BN8TQ3RW6jPLxSaNkqvfuj7syKhzTRmL4EpyY1Nz +HASH_CUSTOM_MTIME=QmT3aY4avDcYXCWpU8CJzqUkW7YEuEsx36S8cTNoLcuK1B +HASH_CUSTOM_MTIME_NSECS=QmaKH8H5rXBUBCX4vdxi7ktGQEL7wejV7L9rX2qpZjwncz +HASH_CUSTOM_MODE_AND_MTIME=QmUkxrtBA8tPjwCYz1HrsoRfDz6NgKut3asVeHVQNH4C8L +HASH_CUSTOM_LINK_MTIME=QmV1Uot2gy4bhY9yvYiZxhhchhyYC6MKKoGV1XtWNmpCLe +HASH_CUSTOM_LINK_MTIME_NSECS=QmPHYCxYvvHj6VxiPNJ3kXxcPsnJLDYUJqsDJWjvytmrmY + +mk_name() { + tr -dc '[:alnum:]'> file1stat_expect && echo "ChildBlocks: 0" >> file1stat_expect && echo "Type: file" >> file1stat_expect && + echo "Mode: not set (not set)" >> file1stat_expect && + echo "Mtime: not set" >> file1stat_expect && test_cmp file1stat_expect file1stat_actual ' @@ -243,6 +245,8 @@ test_files_api() { echo "Size: 4" >> file1stat_expect && echo "ChildBlocks: 0" >> file1stat_expect && echo "Type: file" >> file1stat_expect && + echo "Mode: not set (not set)" >> file1stat_expect && + echo "Mtime: not set" >> file1stat_expect && test_cmp file1stat_expect file1stat_actual ' From d3c20b021049c8f14be8ab4e9eb6b2b386e27bc0 Mon Sep 17 00:00:00 2001 From: shenpengfeng Date: Wed, 21 Aug 2024 22:00:45 +0800 Subject: [PATCH 1131/1212] chore: fix function name (#10481) Signed-off-by: shenpengfeng --- fuse/mount/fuse.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fuse/mount/fuse.go b/fuse/mount/fuse.go index 2dcb8ccae..02d733b89 100644 --- a/fuse/mount/fuse.go +++ b/fuse/mount/fuse.go @@ -102,7 +102,7 @@ func (m *mount) mount() error { return nil } -// umount is called exactly once to unmount this service. +// unmount is called exactly once to unmount this service. // note that closing the connection will not always unmount // properly. If that happens, we bring out the big guns // (mount.ForceUnmountManyTimes, exec unmount). From afe3ae0dac1dcc6f902e0baae3dbb997ebfc372c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 21 Aug 2024 16:07:15 +0200 Subject: [PATCH 1132/1212] chore(deps): bump docker/build-push-action from 5 to 6 (#10451) Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 5 to 6. - [Release notes](https://github.com/docker/build-push-action/releases) - [Commits](https://github.com/docker/build-push-action/compare/v5...v6) --- updated-dependencies: - dependency-name: docker/build-push-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/docker-image.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index 9c2f6d4ea..e52e522ea 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -72,7 +72,7 @@ jobs: # builds, only one platform is being loaded into the cache. This would # prevent us from testing the other platforms. - name: Build Docker image (linux/amd64) - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6 with: platforms: linux/amd64 context: . @@ -84,7 +84,7 @@ jobs: cache-to: type=local,dest=/tmp/.buildx-cache-new - name: Build Docker image (linux/arm/v7) - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6 with: platforms: linux/arm/v7 context: . @@ -96,7 +96,7 @@ jobs: cache-to: type=local,dest=/tmp/.buildx-cache-new - name: Build Docker image (linux/arm64/v8) - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6 with: platforms: linux/arm64/v8 context: . @@ -116,7 +116,7 @@ jobs: # This will only push the previously built images. - if: github.event_name != 'workflow_dispatch' || github.event.inputs.push == 'true' name: Publish to Docker Hub - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6 with: platforms: linux/amd64,linux/arm/v7,linux/arm64/v8 context: . From 330818582dcfb5dd71e66c33ffa5332883fa1c71 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Wed, 21 Aug 2024 18:10:41 +0200 Subject: [PATCH 1133/1212] chore: update go-ipfs-cmds and boxo (#10485) * chore: go-ipfs-cmds v0.12.0 https://github.com/ipfs/go-ipfs-cmds/releases/tag/v0.12.0 * chore: boxo main with boxo#649 https://github.com/ipfs/boxo/pull/649 --- docs/examples/kubo-as-a-library/go.mod | 4 ++-- docs/examples/kubo-as-a-library/go.sum | 8 ++++---- go.mod | 8 ++++---- go.sum | 16 ++++++++-------- test/dependencies/go.mod | 6 +++--- test/dependencies/go.sum | 12 ++++++------ 6 files changed, 27 insertions(+), 27 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 79d8d4600..19d2dcf96 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -9,7 +9,7 @@ toolchain go1.22.0 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.22.1-0.20240820234446-aa27cd2f8053 + github.com/ipfs/boxo v0.22.1-0.20240821001902-3cd3857b046c github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.36.2 github.com/multiformats/go-multiaddr v0.13.0 @@ -210,7 +210,7 @@ require ( golang.org/x/mod v0.19.0 // indirect golang.org/x/net v0.27.0 // indirect golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.22.0 // indirect + golang.org/x/sys v0.24.0 // indirect golang.org/x/text v0.16.0 // indirect golang.org/x/tools v0.23.0 // indirect golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 2d2f68eb7..c7225adff 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -266,8 +266,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.22.1-0.20240820234446-aa27cd2f8053 h1:rW0xGaZW9+74cc8etCm6DwrHhIEtNxklFn8YrUaWjx4= -github.com/ipfs/boxo v0.22.1-0.20240820234446-aa27cd2f8053/go.mod h1:bMB1tnSTr+6/CS5p3jkS4rtifpl+ul6P4ZgeTZn8Ty0= +github.com/ipfs/boxo v0.22.1-0.20240821001902-3cd3857b046c h1:vJb5RbEzIvTFnrxN1+AdQZLu1+ky4oWyx6ARnmtWYXU= +github.com/ipfs/boxo v0.22.1-0.20240821001902-3cd3857b046c/go.mod h1:bMB1tnSTr+6/CS5p3jkS4rtifpl+ul6P4ZgeTZn8Ty0= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= @@ -1001,8 +1001,8 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= diff --git a/go.mod b/go.mod index 65e2ac295..9f0b099be 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( github.com/hashicorp/go-version v1.6.0 github.com/ipfs-shipyard/nopfs v0.0.12 github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c - github.com/ipfs/boxo v0.22.1-0.20240820234446-aa27cd2f8053 + github.com/ipfs/boxo v0.22.1-0.20240821001902-3cd3857b046c github.com/ipfs/go-block-format v0.2.0 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 @@ -29,7 +29,7 @@ require ( github.com/ipfs/go-ds-leveldb v0.5.0 github.com/ipfs/go-ds-measure v0.2.0 github.com/ipfs/go-fs-lock v0.0.7 - github.com/ipfs/go-ipfs-cmds v0.11.0 + github.com/ipfs/go-ipfs-cmds v0.12.0 github.com/ipfs/go-ipld-cbor v0.1.0 github.com/ipfs/go-ipld-format v0.6.0 github.com/ipfs/go-ipld-git v0.1.1 @@ -88,7 +88,7 @@ require ( golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 golang.org/x/mod v0.19.0 golang.org/x/sync v0.7.0 - golang.org/x/sys v0.22.0 + golang.org/x/sys v0.24.0 google.golang.org/protobuf v1.34.2 ) @@ -239,7 +239,7 @@ require ( go4.org v0.0.0-20230225012048-214862532bf5 // indirect golang.org/x/net v0.27.0 // indirect golang.org/x/oauth2 v0.21.0 // indirect - golang.org/x/term v0.22.0 // indirect + golang.org/x/term v0.23.0 // indirect golang.org/x/text v0.16.0 // indirect golang.org/x/tools v0.23.0 // indirect golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9 // indirect diff --git a/go.sum b/go.sum index f5a27bc2e..64034f037 100644 --- a/go.sum +++ b/go.sum @@ -330,8 +330,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.22.1-0.20240820234446-aa27cd2f8053 h1:rW0xGaZW9+74cc8etCm6DwrHhIEtNxklFn8YrUaWjx4= -github.com/ipfs/boxo v0.22.1-0.20240820234446-aa27cd2f8053/go.mod h1:bMB1tnSTr+6/CS5p3jkS4rtifpl+ul6P4ZgeTZn8Ty0= +github.com/ipfs/boxo v0.22.1-0.20240821001902-3cd3857b046c h1:vJb5RbEzIvTFnrxN1+AdQZLu1+ky4oWyx6ARnmtWYXU= +github.com/ipfs/boxo v0.22.1-0.20240821001902-3cd3857b046c/go.mod h1:bMB1tnSTr+6/CS5p3jkS4rtifpl+ul6P4ZgeTZn8Ty0= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= @@ -375,8 +375,8 @@ github.com/ipfs/go-ipfs-blocksutil v0.0.1 h1:Eh/H4pc1hsvhzsQoMEP3Bke/aW5P5rVM1IW github.com/ipfs/go-ipfs-blocksutil v0.0.1/go.mod h1:Yq4M86uIOmxmGPUHv/uI7uKqZNtLb449gwKqXjIsnRk= github.com/ipfs/go-ipfs-chunker v0.0.5 h1:ojCf7HV/m+uS2vhUGWcogIIxiO5ubl5O57Q7NapWLY8= github.com/ipfs/go-ipfs-chunker v0.0.5/go.mod h1:jhgdF8vxRHycr00k13FM8Y0E+6BoalYeobXmUyTreP8= -github.com/ipfs/go-ipfs-cmds v0.11.0 h1:6AsTKwbVxwzrOkq2x89e6jYMGxzYqjt/WbAam69HZQE= -github.com/ipfs/go-ipfs-cmds v0.11.0/go.mod h1:DHp7YfJlOK+2IS07nk+hFmbKHK52tc29W38CaAgWHpk= +github.com/ipfs/go-ipfs-cmds v0.12.0 h1:sx3toXYNbpTSfVvGjom7cuXPSynLMFIqX2h6JCebOP4= +github.com/ipfs/go-ipfs-cmds v0.12.0/go.mod h1:vZ4xu9Fi8ruWSbZfonlJYclH4371T7hWRpwqk0FE9SQ= github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= github.com/ipfs/go-ipfs-delay v0.0.1 h1:r/UXYyRcddO6thwOnhiznIAiSvxMECGgtv35Xs1IeRQ= github.com/ipfs/go-ipfs-delay v0.0.1/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= @@ -1212,8 +1212,8 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -1222,8 +1222,8 @@ golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= -golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= -golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= +golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= +golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index a263e3d98..3bbc96881 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -113,7 +113,7 @@ require ( github.com/hexops/gotextdiff v1.0.3 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/ipfs/bbloom v0.0.4 // indirect - github.com/ipfs/boxo v0.22.1-0.20240820234446-aa27cd2f8053 // indirect + github.com/ipfs/boxo v0.22.1-0.20240821001902-3cd3857b046c // indirect github.com/ipfs/go-block-format v0.2.0 // indirect github.com/ipfs/go-cid v0.4.1 // indirect github.com/ipfs/go-datastore v0.6.0 // indirect @@ -259,8 +259,8 @@ require ( golang.org/x/mod v0.19.0 // indirect golang.org/x/net v0.27.0 // indirect golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/term v0.22.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/term v0.23.0 // indirect golang.org/x/text v0.16.0 // indirect golang.org/x/tools v0.23.0 // indirect gonum.org/v1/gonum v0.15.0 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 27876d29f..685a12c41 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -280,8 +280,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.22.1-0.20240820234446-aa27cd2f8053 h1:rW0xGaZW9+74cc8etCm6DwrHhIEtNxklFn8YrUaWjx4= -github.com/ipfs/boxo v0.22.1-0.20240820234446-aa27cd2f8053/go.mod h1:bMB1tnSTr+6/CS5p3jkS4rtifpl+ul6P4ZgeTZn8Ty0= +github.com/ipfs/boxo v0.22.1-0.20240821001902-3cd3857b046c h1:vJb5RbEzIvTFnrxN1+AdQZLu1+ky4oWyx6ARnmtWYXU= +github.com/ipfs/boxo v0.22.1-0.20240821001902-3cd3857b046c/go.mod h1:bMB1tnSTr+6/CS5p3jkS4rtifpl+ul6P4ZgeTZn8Ty0= github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs= github.com/ipfs/go-block-format v0.2.0/go.mod h1:+jpL11nFx5A/SPpsoBn6Bzkra/zaArfSmsknbPMYgzM= github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= @@ -878,8 +878,8 @@ golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -893,8 +893,8 @@ golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= -golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= -golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= +golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= +golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= From ca95b637ab498fe864c8ab23357246711426dfa4 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Wed, 21 Aug 2024 23:56:55 +0200 Subject: [PATCH 1134/1212] chore: go-libp2p-kad-dht v0.26.1 (#10488) * chore: go-libp2p-kad-dht v0.26.1 https://github.com/libp2p/go-libp2p-kad-dht/releases/tag/v0.26.1 * fix(ci): helia-interop from pr fix https://github.com/ipfs/helia/pull/584 --- .github/workflows/{build.yml => interop.yml} | 20 +++++++++++++++++++- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- test/dependencies/go.mod | 2 +- test/dependencies/go.sum | 5 ++--- 7 files changed, 28 insertions(+), 11 deletions(-) rename .github/workflows/{build.yml => interop.yml} (84%) diff --git a/.github/workflows/build.yml b/.github/workflows/interop.yml similarity index 84% rename from .github/workflows/build.yml rename to .github/workflows/interop.yml index 2967c9997..73ee25555 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/interop.yml @@ -70,9 +70,27 @@ jobs: restore-keys: ${{ runner.os }}-${{ github.job }}-helia- - run: sudo apt update - run: sudo apt install -y libxkbcommon0 libxdamage1 libgbm1 libpango-1.0-0 libcairo2 # dependencies for playwright - - run: npx --package @helia/interop helia-interop + + # TODO: for now run against version from https://github.com/ipfs/helia/pull/584 + - name: Checkout helia-interop with provisional fix + uses: actions/checkout@v4 + with: + repository: ipfs/helia + ref: ab6b385787075ad9932f24362293b3bb82ff1d96 + path: helia + - name: Run provisional build of helia + run: npm i && npm run build + working-directory: helia + - name: Run provisional build of helia-interop + run: npm i && npm run build && npx . + working-directory: helia/packages/interop env: KUBO_BINARY: ${{ github.workspace }}/cmd/ipfs/ipfs + + # TODO: switch back to release once https://github.com/ipfs/helia/pull/584 ships + #- run: npx --package @helia/interop helia-interop + # env: + # KUBO_BINARY: ${{ github.workspace }}/cmd/ipfs/ipfs ipfs-webui: needs: [interop-prep] runs-on: ${{ fromJSON(github.repository == 'ipfs/kubo' && '["self-hosted", "linux", "x64", "2xlarge"]' || '"ubuntu-latest"') }} diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 19d2dcf96..7dde64b20 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -110,7 +110,7 @@ require ( github.com/libp2p/go-doh-resolver v0.4.0 // indirect github.com/libp2p/go-flow-metrics v0.1.0 // indirect github.com/libp2p/go-libp2p-asn-util v0.4.1 // indirect - github.com/libp2p/go-libp2p-kad-dht v0.25.2 // indirect + github.com/libp2p/go-libp2p-kad-dht v0.26.1 // indirect github.com/libp2p/go-libp2p-kbucket v0.6.3 // indirect github.com/libp2p/go-libp2p-pubsub v0.11.0 // indirect github.com/libp2p/go-libp2p-pubsub-router v0.6.0 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index c7225adff..0b736aaf4 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -435,8 +435,8 @@ github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl9 github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= github.com/libp2p/go-libp2p-core v0.3.0/go.mod h1:ACp3DmS3/N64c2jDzcV429ukDpicbL6+TrrxANBjPGw= -github.com/libp2p/go-libp2p-kad-dht v0.25.2 h1:FOIk9gHoe4YRWXTu8SY9Z1d0RILol0TrtApsMDPjAVQ= -github.com/libp2p/go-libp2p-kad-dht v0.25.2/go.mod h1:6za56ncRHYXX4Nc2vn8z7CZK0P4QiMcrn77acKLM2Oo= +github.com/libp2p/go-libp2p-kad-dht v0.26.1 h1:AazV3LCImYVkDUGAHx5lIEgZ9iUI2QQKH5GMRQU8uEA= +github.com/libp2p/go-libp2p-kad-dht v0.26.1/go.mod h1:mqRUGJ/+7ziQ3XknU2kKHfsbbgb9xL65DXjPOJwmZF8= github.com/libp2p/go-libp2p-kbucket v0.3.1/go.mod h1:oyjT5O7tS9CQurok++ERgc46YLwEpuGoFq9ubvoUOio= github.com/libp2p/go-libp2p-kbucket v0.6.3 h1:p507271wWzpy2f1XxPzCQG9NiN6R6lHL9GiSErbQQo0= github.com/libp2p/go-libp2p-kbucket v0.6.3/go.mod h1:RCseT7AH6eJWxxk2ol03xtP9pEHetYSPXOaJnOiD8i0= diff --git a/go.mod b/go.mod index 9f0b099be..3953ce881 100644 --- a/go.mod +++ b/go.mod @@ -51,7 +51,7 @@ require ( github.com/libp2p/go-doh-resolver v0.4.0 github.com/libp2p/go-libp2p v0.36.2 github.com/libp2p/go-libp2p-http v0.5.0 - github.com/libp2p/go-libp2p-kad-dht v0.25.2 + github.com/libp2p/go-libp2p-kad-dht v0.26.1 github.com/libp2p/go-libp2p-kbucket v0.6.3 github.com/libp2p/go-libp2p-pubsub v0.11.0 github.com/libp2p/go-libp2p-pubsub-router v0.6.0 diff --git a/go.sum b/go.sum index 64034f037..953bf5b5f 100644 --- a/go.sum +++ b/go.sum @@ -520,8 +520,8 @@ github.com/libp2p/go-libp2p-gostream v0.6.0 h1:QfAiWeQRce6pqnYfmIVWJFXNdDyfiR/qk github.com/libp2p/go-libp2p-gostream v0.6.0/go.mod h1:Nywu0gYZwfj7Jc91PQvbGU8dIpqbQQkjWgDuOrFaRdA= github.com/libp2p/go-libp2p-http v0.5.0 h1:+x0AbLaUuLBArHubbbNRTsgWz0RjNTy6DJLOxQ3/QBc= github.com/libp2p/go-libp2p-http v0.5.0/go.mod h1:glh87nZ35XCQyFsdzZps6+F4HYI6DctVFY5u1fehwSg= -github.com/libp2p/go-libp2p-kad-dht v0.25.2 h1:FOIk9gHoe4YRWXTu8SY9Z1d0RILol0TrtApsMDPjAVQ= -github.com/libp2p/go-libp2p-kad-dht v0.25.2/go.mod h1:6za56ncRHYXX4Nc2vn8z7CZK0P4QiMcrn77acKLM2Oo= +github.com/libp2p/go-libp2p-kad-dht v0.26.1 h1:AazV3LCImYVkDUGAHx5lIEgZ9iUI2QQKH5GMRQU8uEA= +github.com/libp2p/go-libp2p-kad-dht v0.26.1/go.mod h1:mqRUGJ/+7ziQ3XknU2kKHfsbbgb9xL65DXjPOJwmZF8= github.com/libp2p/go-libp2p-kbucket v0.3.1/go.mod h1:oyjT5O7tS9CQurok++ERgc46YLwEpuGoFq9ubvoUOio= github.com/libp2p/go-libp2p-kbucket v0.6.3 h1:p507271wWzpy2f1XxPzCQG9NiN6R6lHL9GiSErbQQo0= github.com/libp2p/go-libp2p-kbucket v0.6.3/go.mod h1:RCseT7AH6eJWxxk2ol03xtP9pEHetYSPXOaJnOiD8i0= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 3bbc96881..21d77ede2 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -146,7 +146,7 @@ require ( github.com/libp2p/go-cidranger v1.1.0 // indirect github.com/libp2p/go-libp2p v0.36.2 // indirect github.com/libp2p/go-libp2p-asn-util v0.4.1 // indirect - github.com/libp2p/go-libp2p-kad-dht v0.25.2 // indirect + github.com/libp2p/go-libp2p-kad-dht v0.26.1 // indirect github.com/libp2p/go-libp2p-kbucket v0.6.3 // indirect github.com/libp2p/go-libp2p-record v0.2.0 // indirect github.com/libp2p/go-libp2p-routing-helpers v0.7.4 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 685a12c41..79c1f73e8 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -148,7 +148,6 @@ github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/go-toolsmith/astcast v1.1.0 h1:+JN9xZV1A+Re+95pgnMgDboWNVnIMMQXwfBwLRPgSC8= @@ -391,8 +390,8 @@ github.com/libp2p/go-libp2p v0.36.2 h1:BbqRkDaGC3/5xfaJakLV/BrpjlAuYqSB0lRvtzL3B github.com/libp2p/go-libp2p v0.36.2/go.mod h1:XO3joasRE4Eup8yCTTP/+kX+g92mOgRaadk46LmPhHY= github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94= github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= -github.com/libp2p/go-libp2p-kad-dht v0.25.2 h1:FOIk9gHoe4YRWXTu8SY9Z1d0RILol0TrtApsMDPjAVQ= -github.com/libp2p/go-libp2p-kad-dht v0.25.2/go.mod h1:6za56ncRHYXX4Nc2vn8z7CZK0P4QiMcrn77acKLM2Oo= +github.com/libp2p/go-libp2p-kad-dht v0.26.1 h1:AazV3LCImYVkDUGAHx5lIEgZ9iUI2QQKH5GMRQU8uEA= +github.com/libp2p/go-libp2p-kad-dht v0.26.1/go.mod h1:mqRUGJ/+7ziQ3XknU2kKHfsbbgb9xL65DXjPOJwmZF8= github.com/libp2p/go-libp2p-kbucket v0.6.3 h1:p507271wWzpy2f1XxPzCQG9NiN6R6lHL9GiSErbQQo0= github.com/libp2p/go-libp2p-kbucket v0.6.3/go.mod h1:RCseT7AH6eJWxxk2ol03xtP9pEHetYSPXOaJnOiD8i0= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= From 49f9cc92d12d5e78f83b88b031be82b3b9c3e74f Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Wed, 21 Aug 2024 23:15:55 +0000 Subject: [PATCH 1135/1212] chore: update version --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index ee76d8ed1..316ca6daf 100644 --- a/version.go +++ b/version.go @@ -11,7 +11,7 @@ import ( var CurrentCommit string // CurrentVersionNumber is the current application's version literal. -const CurrentVersionNumber = "0.30.0-dev" +const CurrentVersionNumber = "0.30.0-rc1" const ApiVersion = "/kubo/" + CurrentVersionNumber + "/" //nolint From f6fb36cf43581055a9d822caf3e0ccc89b8334bd Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Thu, 22 Aug 2024 01:48:59 +0200 Subject: [PATCH 1136/1212] chore: update version (#10491) --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index ee76d8ed1..c8b24bd3c 100644 --- a/version.go +++ b/version.go @@ -11,7 +11,7 @@ import ( var CurrentCommit string // CurrentVersionNumber is the current application's version literal. -const CurrentVersionNumber = "0.30.0-dev" +const CurrentVersionNumber = "0.31.0-dev" const ApiVersion = "/kubo/" + CurrentVersionNumber + "/" //nolint From 91144f7bfc81f171c40161c17d8ae1fe779817ec Mon Sep 17 00:00:00 2001 From: Elias Rad <146735585+nnsW3@users.noreply.github.com> Date: Mon, 26 Aug 2024 21:32:07 +0300 Subject: [PATCH 1137/1212] Docs fix spelling issues (#10493) * fix keystore.md * fix config.md * fix datastores.md * fix libp2p-resource-management.md --- docs/config.md | 6 +++--- docs/datastores.md | 2 +- docs/libp2p-resource-management.md | 4 ++-- docs/specifications/keystore.md | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/config.md b/docs/config.md index 9119610dc..107050927 100644 --- a/docs/config.md +++ b/docs/config.md @@ -571,7 +571,7 @@ Additional modes may be added in the future. > [!IMPORTANT] > We are in the progress of [rolling out AutoNAT V2](https://github.com/ipfs/kubo/issues/10091). -> Right now, by default, a publicly diallable Kubo provides both V1 and V2 service to other peers, +> Right now, by default, a publicly dialable Kubo provides both V1 and V2 service to other peers, > but only V1 is used by Kubo as a client. In a future release we will remove V1 and switch client to use V2. Default: `enabled` @@ -1615,7 +1615,7 @@ is able to find the 20 final nodes by looking up the in-memory recorded network This means sustained higher memory to store the routing table and extra CPU and network bandwidth for each network scan. However the latency of individual read/write operations should be ~10x faster -and the provide throughput up to 6 million times faster on larger datasets! +and provide throughput up to 6 million times faster on larger datasets! This is not compatible with `Routing.Type` `custom`. If you are using composable routers you can configure this individually on each router. @@ -1918,7 +1918,7 @@ Type: `flag` #### `Swarm.RelayService.Limit` -Limits applied to every relayed connection. +Limits are applied to every relayed connection. Default: `{}` diff --git a/docs/datastores.md b/docs/datastores.md index db729bf97..ccedce4c7 100644 --- a/docs/datastores.md +++ b/docs/datastores.md @@ -40,7 +40,7 @@ Uses a leveldb database to store key value pairs. Uses [badger](https://github.com/dgraph-io/badger) as a key value store. * `syncWrites`: Flush every write to disk before continuing. Setting this to false is safe as kubo will automatically flush writes to disk before and after performing critical operations like pinning. However, you can set this to true to be extra-safe (at the cost of a 2-3x slowdown when adding files). -* `truncate`: Truncate the DB if a partially written sector is found (defaults to true). There is no good reason to set this to false unless you want to manually recover partially written (and unpinned) blocks if kubo crashes half-way through a adding a file. +* `truncate`: Truncate the DB if a partially written sector is found (defaults to true). There is no good reason to set this to false unless you want to manually recover partially written (and unpinned) blocks if kubo crashes half-way through adding a file. ```json { diff --git a/docs/libp2p-resource-management.md b/docs/libp2p-resource-management.md index 410982dab..a778f680d 100644 --- a/docs/libp2p-resource-management.md +++ b/docs/libp2p-resource-management.md @@ -91,7 +91,7 @@ These values trump anything else and are parsed directly by go-libp2p. ## FAQ ### What do these "Protected from exceeding resource limits" log messages mean? -"Protected from exceeding resource limits" log messages denote that the resource manager is working and that it prevented additional resources being used beyond the set limits. Per [libp2p code](https://github.com/libp2p/go-libp2p/blob/master/p2p/host/resource-manager/scope.go), these messages take the form of "$scope: cannot reserve $limitKey". +"Protected from exceeding resource limits" log messages denote that the resource manager is working and that it prevented additional resources from being used beyond the set limits. Per [libp2p code](https://github.com/libp2p/go-libp2p/blob/master/p2p/host/resource-manager/scope.go), these messages take the form of "$scope: cannot reserve $limitKey". As an example: @@ -133,7 +133,7 @@ Kubo performs sanity checks to ensure that some of the hard limits of the Resour The soft limit of `Swarm.ConnMgr.HighWater` needs to be less than the resource manager hard limit `System.ConnsInbound` for the configuration to make sense. This ensures the ConnMgr cleans up connections based on connection priorities before the hard limits of the ResourceMgr are applied. If `Swarm.ConnMgr.HighWater` is greater than resource manager's `System.ConnsInbound`, -existing low priority idle connections can prevent new high priority connections from being established. +existing low-priority idle connections can prevent new high-priority connections from being established. The ResourceMgr doesn't know that the new connection is high priority and simply blocks it because of the limit its enforcing. To ensure the ConnMgr and ResourceMgr are congruent, the ResourceMgr [computed default limits](#computed-default-limits) are adjusted such that: diff --git a/docs/specifications/keystore.md b/docs/specifications/keystore.md index 7e588ca98..9609b83c2 100644 --- a/docs/specifications/keystore.md +++ b/docs/specifications/keystore.md @@ -175,7 +175,7 @@ OPTIONS: DESCRIPTION: - 'ipfs crypt encrypt' is a command used to encypt data so that only holders of a certain + 'ipfs crypt encrypt' is a command used to encrypt data so that only holders of a certain key can read it. ``` From add45cf34c0f38d56570b4446ab33b7dddfec72e Mon Sep 17 00:00:00 2001 From: Andrew Gillis <11790789+gammazero@users.noreply.github.com> Date: Tue, 27 Aug 2024 17:41:45 -0700 Subject: [PATCH 1138/1212] chore: update go-unixfsnode, cmds, and boxo (#10494) * Update go-unixfsnode dependency * Update go-ipfs-cmds * chore: boxo@main with boxo#659 --------- Co-authored-by: Marcin Rataj --- docs/changelogs/v0.30.md | 1 + docs/examples/kubo-as-a-library/go.mod | 4 ++-- docs/examples/kubo-as-a-library/go.sum | 10 ++++------ go.mod | 7 +++---- go.sum | 16 ++++++---------- test/dependencies/go.mod | 2 +- test/dependencies/go.sum | 4 ++-- 7 files changed, 19 insertions(+), 25 deletions(-) diff --git a/docs/changelogs/v0.30.md b/docs/changelogs/v0.30.md index 6cc212f7a..e7f5d8b3f 100644 --- a/docs/changelogs/v0.30.md +++ b/docs/changelogs/v0.30.md @@ -124,6 +124,7 @@ The CLI and HTTP RPC options `--mode`, `--mtime` and `--mtime-nsecs` can be used Opt-in support for `mode` and `mtime` was also added to MFS (`ipfs files --help`). For more information see `--help` text of `ipfs files touch|stat|chmod` commands. +Modification time support was also added to the Gateway. If present, value from file's dag-pb is returned in `Last-Modified` HTTP header and requests made with `If-Modified-Since` can produce HTTP 304 not modified response. > [!NOTE] > Storing `mode` and `mtime` requires root block to be `dag-pb` and disabled `raw-leaves` setting to create envelope for storing the metadata. diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 7dde64b20..734376538 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -9,7 +9,7 @@ toolchain go1.22.0 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.22.1-0.20240821001902-3cd3857b046c + github.com/ipfs/boxo v0.22.1-0.20240828000743-08f200aa8eef github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.36.2 github.com/multiformats/go-multiaddr v0.13.0 @@ -93,7 +93,7 @@ require ( github.com/ipfs/go-merkledag v0.11.0 // indirect github.com/ipfs/go-metrics-interface v0.0.1 // indirect github.com/ipfs/go-peertaskqueue v0.8.1 // indirect - github.com/ipfs/go-unixfsnode v1.9.0 // indirect + github.com/ipfs/go-unixfsnode v1.9.1 // indirect github.com/ipfs/go-verifcid v0.0.3 // indirect github.com/ipld/go-car v0.6.2 // indirect github.com/ipld/go-car/v2 v2.13.1 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 0b736aaf4..05e7f6903 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -266,8 +266,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.22.1-0.20240821001902-3cd3857b046c h1:vJb5RbEzIvTFnrxN1+AdQZLu1+ky4oWyx6ARnmtWYXU= -github.com/ipfs/boxo v0.22.1-0.20240821001902-3cd3857b046c/go.mod h1:bMB1tnSTr+6/CS5p3jkS4rtifpl+ul6P4ZgeTZn8Ty0= +github.com/ipfs/boxo v0.22.1-0.20240828000743-08f200aa8eef h1:ozMkCGYQmIkMnZwo4zPgrkkVFJvhBPnb3HhEswJoiG8= +github.com/ipfs/boxo v0.22.1-0.20240828000743-08f200aa8eef/go.mod h1:bMB1tnSTr+6/CS5p3jkS4rtifpl+ul6P4ZgeTZn8Ty0= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= @@ -307,8 +307,6 @@ github.com/ipfs/go-ipfs-blockstore v1.3.1 h1:cEI9ci7V0sRNivqaOr0elDsamxXFxJMMMy7 github.com/ipfs/go-ipfs-blockstore v1.3.1/go.mod h1:KgtZyc9fq+P2xJUiCAzbRdhhqJHvsw8u2Dlqy2MyRTE= github.com/ipfs/go-ipfs-blocksutil v0.0.1 h1:Eh/H4pc1hsvhzsQoMEP3Bke/aW5P5rVM1IWFJMcGIPQ= github.com/ipfs/go-ipfs-blocksutil v0.0.1/go.mod h1:Yq4M86uIOmxmGPUHv/uI7uKqZNtLb449gwKqXjIsnRk= -github.com/ipfs/go-ipfs-chunker v0.0.5 h1:ojCf7HV/m+uS2vhUGWcogIIxiO5ubl5O57Q7NapWLY8= -github.com/ipfs/go-ipfs-chunker v0.0.5/go.mod h1:jhgdF8vxRHycr00k13FM8Y0E+6BoalYeobXmUyTreP8= github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= github.com/ipfs/go-ipfs-delay v0.0.1 h1:r/UXYyRcddO6thwOnhiznIAiSvxMECGgtv35Xs1IeRQ= github.com/ipfs/go-ipfs-delay v0.0.1/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= @@ -356,8 +354,8 @@ github.com/ipfs/go-test v0.0.4 h1:DKT66T6GBB6PsDFLoO56QZPrOmzJkqU1FZH5C9ySkew= github.com/ipfs/go-test v0.0.4/go.mod h1:qhIM1EluEfElKKM6fnWxGn822/z9knUGM1+I/OAQNKI= github.com/ipfs/go-unixfs v0.4.5 h1:wj8JhxvV1G6CD7swACwSKYa+NgtdWC1RUit+gFnymDU= github.com/ipfs/go-unixfs v0.4.5/go.mod h1:BIznJNvt/gEx/ooRMI4Us9K8+qeGO7vx1ohnbk8gjFg= -github.com/ipfs/go-unixfsnode v1.9.0 h1:ubEhQhr22sPAKO2DNsyVBW7YB/zA8Zkif25aBvz8rc8= -github.com/ipfs/go-unixfsnode v1.9.0/go.mod h1:HxRu9HYHOjK6HUqFBAi++7DVoWAHn0o4v/nZ/VA+0g8= +github.com/ipfs/go-unixfsnode v1.9.1 h1:2cdSIDQCt7emNhlyUqUFQnKo2XvecARoIcurIKFjPD8= +github.com/ipfs/go-unixfsnode v1.9.1/go.mod h1:u8WxhmXzyrq3xfSYkhfx+uI+n91O+0L7KFjq3TS7d6g= github.com/ipfs/go-verifcid v0.0.3 h1:gmRKccqhWDocCRkC+a59g5QW7uJw5bpX9HWBevXa0zs= github.com/ipfs/go-verifcid v0.0.3/go.mod h1:gcCtGniVzelKrbk9ooUSX/pM3xlH73fZZJDzQJRvOUw= github.com/ipld/go-car v0.6.2 h1:Hlnl3Awgnq8icK+ze3iRghk805lu8YNq3wlREDTF2qc= diff --git a/go.mod b/go.mod index 3953ce881..fd2f2459e 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( github.com/hashicorp/go-version v1.6.0 github.com/ipfs-shipyard/nopfs v0.0.12 github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c - github.com/ipfs/boxo v0.22.1-0.20240821001902-3cd3857b046c + github.com/ipfs/boxo v0.22.1-0.20240828000743-08f200aa8eef github.com/ipfs/go-block-format v0.2.0 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 @@ -29,7 +29,7 @@ require ( github.com/ipfs/go-ds-leveldb v0.5.0 github.com/ipfs/go-ds-measure v0.2.0 github.com/ipfs/go-fs-lock v0.0.7 - github.com/ipfs/go-ipfs-cmds v0.12.0 + github.com/ipfs/go-ipfs-cmds v0.13.0 github.com/ipfs/go-ipld-cbor v0.1.0 github.com/ipfs/go-ipld-format v0.6.0 github.com/ipfs/go-ipld-git v0.1.1 @@ -39,7 +39,7 @@ require ( github.com/ipfs/go-metrics-interface v0.0.1 github.com/ipfs/go-metrics-prometheus v0.0.2 github.com/ipfs/go-test v0.0.4 - github.com/ipfs/go-unixfsnode v1.9.0 + github.com/ipfs/go-unixfsnode v1.9.1 github.com/ipld/go-car v0.6.2 github.com/ipld/go-car/v2 v2.13.1 github.com/ipld/go-codec-dagpb v1.6.0 @@ -137,7 +137,6 @@ require ( github.com/ipfs/go-bitfield v1.1.0 // indirect github.com/ipfs/go-blockservice v0.5.2 // indirect github.com/ipfs/go-ipfs-blockstore v1.3.1 // indirect - github.com/ipfs/go-ipfs-chunker v0.0.5 // indirect github.com/ipfs/go-ipfs-delay v0.0.1 // indirect github.com/ipfs/go-ipfs-ds-help v1.1.1 // indirect github.com/ipfs/go-ipfs-exchange-interface v0.2.1 // indirect diff --git a/go.sum b/go.sum index 953bf5b5f..789e83b1c 100644 --- a/go.sum +++ b/go.sum @@ -330,19 +330,17 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.22.1-0.20240821001902-3cd3857b046c h1:vJb5RbEzIvTFnrxN1+AdQZLu1+ky4oWyx6ARnmtWYXU= -github.com/ipfs/boxo v0.22.1-0.20240821001902-3cd3857b046c/go.mod h1:bMB1tnSTr+6/CS5p3jkS4rtifpl+ul6P4ZgeTZn8Ty0= +github.com/ipfs/boxo v0.22.1-0.20240828000743-08f200aa8eef h1:ozMkCGYQmIkMnZwo4zPgrkkVFJvhBPnb3HhEswJoiG8= +github.com/ipfs/boxo v0.22.1-0.20240828000743-08f200aa8eef/go.mod h1:bMB1tnSTr+6/CS5p3jkS4rtifpl+ul6P4ZgeTZn8Ty0= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= github.com/ipfs/go-bitswap v0.11.0/go.mod h1:05aE8H3XOU+LXpTedeAS0OZpcO1WFsj5niYQH9a1Tmk= -github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= github.com/ipfs/go-block-format v0.0.3/go.mod h1:4LmD4ZUw0mhO+JSKdpWwrzATiEfM7WWgQ8H5l6P8MVk= github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs= github.com/ipfs/go-block-format v0.2.0/go.mod h1:+jpL11nFx5A/SPpsoBn6Bzkra/zaArfSmsknbPMYgzM= github.com/ipfs/go-blockservice v0.5.2 h1:in9Bc+QcXwd1apOVM7Un9t8tixPKdaHQFdLSUM1Xgk8= github.com/ipfs/go-blockservice v0.5.2/go.mod h1:VpMblFEqG67A/H2sHKAemeH9vlURVavlysbdUI632yk= -github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.3/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.4/go.mod h1:4LLaPOQwmk5z9LBgQnpkivrx8BJjUyGwTXCd5Xfj6+M= github.com/ipfs/go-cid v0.0.7/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I= @@ -373,10 +371,8 @@ github.com/ipfs/go-ipfs-blockstore v1.3.1 h1:cEI9ci7V0sRNivqaOr0elDsamxXFxJMMMy7 github.com/ipfs/go-ipfs-blockstore v1.3.1/go.mod h1:KgtZyc9fq+P2xJUiCAzbRdhhqJHvsw8u2Dlqy2MyRTE= github.com/ipfs/go-ipfs-blocksutil v0.0.1 h1:Eh/H4pc1hsvhzsQoMEP3Bke/aW5P5rVM1IWFJMcGIPQ= github.com/ipfs/go-ipfs-blocksutil v0.0.1/go.mod h1:Yq4M86uIOmxmGPUHv/uI7uKqZNtLb449gwKqXjIsnRk= -github.com/ipfs/go-ipfs-chunker v0.0.5 h1:ojCf7HV/m+uS2vhUGWcogIIxiO5ubl5O57Q7NapWLY8= -github.com/ipfs/go-ipfs-chunker v0.0.5/go.mod h1:jhgdF8vxRHycr00k13FM8Y0E+6BoalYeobXmUyTreP8= -github.com/ipfs/go-ipfs-cmds v0.12.0 h1:sx3toXYNbpTSfVvGjom7cuXPSynLMFIqX2h6JCebOP4= -github.com/ipfs/go-ipfs-cmds v0.12.0/go.mod h1:vZ4xu9Fi8ruWSbZfonlJYclH4371T7hWRpwqk0FE9SQ= +github.com/ipfs/go-ipfs-cmds v0.13.0 h1:+WVHZMrQNkPqwAQdrSFGbJgHpOc8H2G8eszNxnvoCQA= +github.com/ipfs/go-ipfs-cmds v0.13.0/go.mod h1:GYqjGSt6u9k9tyxIDT7M0ROWeB2raPGH94uuVnpWgY0= github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= github.com/ipfs/go-ipfs-delay v0.0.1 h1:r/UXYyRcddO6thwOnhiznIAiSvxMECGgtv35Xs1IeRQ= github.com/ipfs/go-ipfs-delay v0.0.1/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= @@ -426,8 +422,8 @@ github.com/ipfs/go-test v0.0.4 h1:DKT66T6GBB6PsDFLoO56QZPrOmzJkqU1FZH5C9ySkew= github.com/ipfs/go-test v0.0.4/go.mod h1:qhIM1EluEfElKKM6fnWxGn822/z9knUGM1+I/OAQNKI= github.com/ipfs/go-unixfs v0.4.5 h1:wj8JhxvV1G6CD7swACwSKYa+NgtdWC1RUit+gFnymDU= github.com/ipfs/go-unixfs v0.4.5/go.mod h1:BIznJNvt/gEx/ooRMI4Us9K8+qeGO7vx1ohnbk8gjFg= -github.com/ipfs/go-unixfsnode v1.9.0 h1:ubEhQhr22sPAKO2DNsyVBW7YB/zA8Zkif25aBvz8rc8= -github.com/ipfs/go-unixfsnode v1.9.0/go.mod h1:HxRu9HYHOjK6HUqFBAi++7DVoWAHn0o4v/nZ/VA+0g8= +github.com/ipfs/go-unixfsnode v1.9.1 h1:2cdSIDQCt7emNhlyUqUFQnKo2XvecARoIcurIKFjPD8= +github.com/ipfs/go-unixfsnode v1.9.1/go.mod h1:u8WxhmXzyrq3xfSYkhfx+uI+n91O+0L7KFjq3TS7d6g= github.com/ipfs/go-verifcid v0.0.3 h1:gmRKccqhWDocCRkC+a59g5QW7uJw5bpX9HWBevXa0zs= github.com/ipfs/go-verifcid v0.0.3/go.mod h1:gcCtGniVzelKrbk9ooUSX/pM3xlH73fZZJDzQJRvOUw= github.com/ipld/go-car v0.6.2 h1:Hlnl3Awgnq8icK+ze3iRghk805lu8YNq3wlREDTF2qc= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 21d77ede2..32941dd14 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -113,7 +113,7 @@ require ( github.com/hexops/gotextdiff v1.0.3 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/ipfs/bbloom v0.0.4 // indirect - github.com/ipfs/boxo v0.22.1-0.20240821001902-3cd3857b046c // indirect + github.com/ipfs/boxo v0.22.1-0.20240828000743-08f200aa8eef // indirect github.com/ipfs/go-block-format v0.2.0 // indirect github.com/ipfs/go-cid v0.4.1 // indirect github.com/ipfs/go-datastore v0.6.0 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 79c1f73e8..2d055f038 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -279,8 +279,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.22.1-0.20240821001902-3cd3857b046c h1:vJb5RbEzIvTFnrxN1+AdQZLu1+ky4oWyx6ARnmtWYXU= -github.com/ipfs/boxo v0.22.1-0.20240821001902-3cd3857b046c/go.mod h1:bMB1tnSTr+6/CS5p3jkS4rtifpl+ul6P4ZgeTZn8Ty0= +github.com/ipfs/boxo v0.22.1-0.20240828000743-08f200aa8eef h1:ozMkCGYQmIkMnZwo4zPgrkkVFJvhBPnb3HhEswJoiG8= +github.com/ipfs/boxo v0.22.1-0.20240828000743-08f200aa8eef/go.mod h1:bMB1tnSTr+6/CS5p3jkS4rtifpl+ul6P4ZgeTZn8Ty0= github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs= github.com/ipfs/go-block-format v0.2.0/go.mod h1:+jpL11nFx5A/SPpsoBn6Bzkra/zaArfSmsknbPMYgzM= github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= From 175aabdd85d2235e46bc163706dd7beb2c47ce05 Mon Sep 17 00:00:00 2001 From: Andrew Gillis <11790789+gammazero@users.noreply.github.com> Date: Wed, 28 Aug 2024 09:21:16 -0700 Subject: [PATCH 1139/1212] fix: error during config when running benchmarks (#10495) - Benchmarks were failing with error setting number of bits for ed25519 keys, which are the default now. - Update the random data generation package to remove a dependency. --- go.mod | 1 - go.sum | 2 -- test/bench/bench_cli_ipfs_add/main.go | 11 ++++++++--- test/bench/offline_add/main.go | 11 ++++++++--- test/integration/addcat_test.go | 10 +++------- 5 files changed, 19 insertions(+), 16 deletions(-) diff --git a/go.mod b/go.mod index fd2f2459e..3f86b7f54 100644 --- a/go.mod +++ b/go.mod @@ -44,7 +44,6 @@ require ( github.com/ipld/go-car/v2 v2.13.1 github.com/ipld/go-codec-dagpb v1.6.0 github.com/ipld/go-ipld-prime v0.21.0 - 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/julienschmidt/httprouter v1.3.0 diff --git a/go.sum b/go.sum index 789e83b1c..553591794 100644 --- a/go.sum +++ b/go.sum @@ -442,8 +442,6 @@ github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7Bd github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/jbenet/go-cienv v0.1.0 h1:Vc/s0QbQtoxX8MwwSLWWh+xNNZvM3Lw7NsTcHrvvhMc= github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA= -github.com/jbenet/go-random v0.0.0-20190219211222-123a90aedc0c h1:uUx61FiAa1GI6ZmVd2wf2vULeQZIKG66eybjNXKYCz4= -github.com/jbenet/go-random v0.0.0-20190219211222-123a90aedc0c/go.mod h1:sdx1xVM9UuLw1tXnhJWN3piypTUO3vCIHYmG15KE/dU= github.com/jbenet/go-temp-err-catcher v0.1.0 h1:zpb3ZH6wIE8Shj2sKS+khgRvf7T7RABoLk/+KKHggpk= github.com/jbenet/go-temp-err-catcher v0.1.0/go.mod h1:0kJRvmDZXNMIiJirNPEYfhpPwbGVtZVWC34vc5WLsDk= github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY= diff --git a/test/bench/bench_cli_ipfs_add/main.go b/test/bench/bench_cli_ipfs_add/main.go index e7fe90e04..2c39ba636 100644 --- a/test/bench/bench_cli_ipfs_add/main.go +++ b/test/bench/bench_cli_ipfs_add/main.go @@ -3,6 +3,7 @@ package main import ( "flag" "fmt" + "io" "log" "os" "os/exec" @@ -11,8 +12,8 @@ import ( "github.com/ipfs/kubo/thirdparty/unit" + random "github.com/ipfs/go-test/random" config "github.com/ipfs/kubo/config" - random "github.com/jbenet/go-random" ) var ( @@ -59,7 +60,7 @@ func benchmarkAdd(amount int64) (*testing.BenchmarkResult, error) { } } - initCmd := exec.Command("ipfs", "init", "-b=2048") + initCmd := exec.Command("ipfs", "init") setupCmd(initCmd) if err := initCmd.Run(); err != nil { benchmarkError = err @@ -74,7 +75,11 @@ func benchmarkAdd(amount int64) (*testing.BenchmarkResult, error) { } defer os.Remove(f.Name()) - if err := random.WritePseudoRandomBytes(amount, f, seed); err != nil { + randReader := &io.LimitedReader{ + R: random.NewSeededRand(seed), + N: amount, + } + if _, err := io.Copy(f, randReader); err != nil { benchmarkError = err b.Fatal(err) } diff --git a/test/bench/offline_add/main.go b/test/bench/offline_add/main.go index 338a5f6ac..7c00d30f4 100644 --- a/test/bench/offline_add/main.go +++ b/test/bench/offline_add/main.go @@ -2,6 +2,7 @@ package main import ( "fmt" + "io" "log" "os" "os/exec" @@ -10,8 +11,8 @@ import ( "github.com/ipfs/kubo/thirdparty/unit" + random "github.com/ipfs/go-test/random" config "github.com/ipfs/kubo/config" - random "github.com/jbenet/go-random" ) func main() { @@ -44,7 +45,7 @@ func benchmarkAdd(amount int64) (*testing.BenchmarkResult, error) { cmd.Env = env } - cmd := exec.Command("ipfs", "init", "-b=2048") + cmd := exec.Command("ipfs", "init") setupCmd(cmd) if err := cmd.Run(); err != nil { b.Fatal(err) @@ -57,7 +58,11 @@ func benchmarkAdd(amount int64) (*testing.BenchmarkResult, error) { } defer os.Remove(f.Name()) - err = random.WritePseudoRandomBytes(amount, f, seed) + randReader := &io.LimitedReader{ + R: random.NewSeededRand(seed), + N: amount, + } + _, err = io.Copy(f, randReader) if err != nil { b.Fatal(err) } diff --git a/test/integration/addcat_test.go b/test/integration/addcat_test.go index 222326de2..936b28c6d 100644 --- a/test/integration/addcat_test.go +++ b/test/integration/addcat_test.go @@ -14,11 +14,11 @@ import ( "github.com/ipfs/boxo/bootstrap" "github.com/ipfs/boxo/files" logging "github.com/ipfs/go-log" + "github.com/ipfs/go-test/random" "github.com/ipfs/kubo/core" "github.com/ipfs/kubo/core/coreapi" mock "github.com/ipfs/kubo/core/mock" "github.com/ipfs/kubo/thirdparty/unit" - "github.com/jbenet/go-random" testutil "github.com/libp2p/go-libp2p-testing/net" "github.com/libp2p/go-libp2p/core/peer" mocknet "github.com/libp2p/go-libp2p/p2p/net/mock" @@ -84,12 +84,8 @@ func AddCatPowers(conf testutil.LatencyConfig, megabytesMax int64) error { } func RandomBytes(n int64) []byte { - var data bytes.Buffer - err := random.WritePseudoRandomBytes(n, &data, kSeed) - if err != nil { - panic(err) - } - return data.Bytes() + random.SetSeed(kSeed) + return random.Bytes(int(n)) } func DirectAddCat(data []byte, conf testutil.LatencyConfig) error { From 483e9c383bc59571c0ee1466024211b2f07cd0dd Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Wed, 28 Aug 2024 18:54:50 +0200 Subject: [PATCH 1140/1212] chore: update version to rc-2 --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index 316ca6daf..e394ce0f9 100644 --- a/version.go +++ b/version.go @@ -11,7 +11,7 @@ import ( var CurrentCommit string // CurrentVersionNumber is the current application's version literal. -const CurrentVersionNumber = "0.30.0-rc1" +const CurrentVersionNumber = "0.30.0-rc2" const ApiVersion = "/kubo/" + CurrentVersionNumber + "/" //nolint From 2260e35df2a17b5483e3fef55b4ddc0f81fb31a3 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Wed, 28 Aug 2024 18:56:45 +0200 Subject: [PATCH 1141/1212] chore: upgrade to go 1.23 (#10486) * chore: upgrade to go 1.23 https://tip.golang.org/doc/go1.23 * refactor: golangci-lint v1.60.2 --- .github/workflows/codeql-analysis.yml | 2 +- .github/workflows/docker-build.yml | 2 +- .github/workflows/gateway-conformance.yml | 4 +- .github/workflows/gobuild.yml | 2 +- .github/workflows/golang-analysis.yml | 2 +- .github/workflows/golint.yml | 2 +- .github/workflows/gotest.yml | 2 +- .github/workflows/interop.yml | 2 +- .github/workflows/sharness.yml | 2 +- Dockerfile | 2 +- core/commands/bitswap.go | 2 +- core/commands/files.go | 2 +- core/commands/name/ipnsps.go | 2 +- core/commands/name/name.go | 3 +- core/commands/refs.go | 2 +- core/commands/stat.go | 2 +- core/commands/swarm.go | 2 +- docs/examples/kubo-as-a-library/go.mod | 4 +- go.mod | 2 +- plugin/loader/loader.go | 3 +- test/dependencies/go.mod | 57 +++++------ test/dependencies/go.sum | 118 +++++++++++----------- 22 files changed, 107 insertions(+), 114 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index d0e082d65..8ed324854 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -34,7 +34,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: 1.22.x + go-version: 1.23.x # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml index 433240f42..e13a3f882 100644 --- a/.github/workflows/docker-build.yml +++ b/.github/workflows/docker-build.yml @@ -28,7 +28,7 @@ jobs: steps: - uses: actions/setup-go@v5 with: - go-version: 1.22.x + go-version: 1.23.x - uses: actions/checkout@v4 - run: docker build -t $IMAGE_NAME:$WIP_IMAGE_TAG . - run: docker run --rm $IMAGE_NAME:$WIP_IMAGE_TAG --version diff --git a/.github/workflows/gateway-conformance.yml b/.github/workflows/gateway-conformance.yml index b1791868c..d2f015900 100644 --- a/.github/workflows/gateway-conformance.yml +++ b/.github/workflows/gateway-conformance.yml @@ -49,7 +49,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: 1.22.x + go-version: 1.23.x - uses: protocol/cache-go-action@v1 with: name: ${{ github.job }} @@ -136,7 +136,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: 1.22.x + go-version: 1.23.x - uses: protocol/cache-go-action@v1 with: name: ${{ github.job }} diff --git a/.github/workflows/gobuild.yml b/.github/workflows/gobuild.yml index 93159eadd..5aebfd938 100644 --- a/.github/workflows/gobuild.yml +++ b/.github/workflows/gobuild.yml @@ -30,7 +30,7 @@ jobs: steps: - uses: actions/setup-go@v5 with: - go-version: 1.22.x + go-version: 1.23.x - uses: actions/checkout@v4 - run: make cmd/ipfs-try-build env: diff --git a/.github/workflows/golang-analysis.yml b/.github/workflows/golang-analysis.yml index e89034a92..36a5bba01 100644 --- a/.github/workflows/golang-analysis.yml +++ b/.github/workflows/golang-analysis.yml @@ -27,7 +27,7 @@ jobs: submodules: recursive - uses: actions/setup-go@v5 with: - go-version: "1.22.x" + go-version: "1.23.x" - name: Check that go.mod is tidy uses: protocol/multiple-go-modules@v1.4 with: diff --git a/.github/workflows/golint.yml b/.github/workflows/golint.yml index aa8b21b53..57b5d46dd 100644 --- a/.github/workflows/golint.yml +++ b/.github/workflows/golint.yml @@ -31,6 +31,6 @@ jobs: steps: - uses: actions/setup-go@v5 with: - go-version: 1.22.x + go-version: 1.23.x - uses: actions/checkout@v4 - run: make -O test_go_lint diff --git a/.github/workflows/gotest.yml b/.github/workflows/gotest.yml index 609791aba..f5225e8a3 100644 --- a/.github/workflows/gotest.yml +++ b/.github/workflows/gotest.yml @@ -32,7 +32,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v5 with: - go-version: 1.22.x + go-version: 1.23.x - name: Check out Kubo uses: actions/checkout@v4 - name: Install missing tools diff --git a/.github/workflows/interop.yml b/.github/workflows/interop.yml index 73ee25555..2e280a779 100644 --- a/.github/workflows/interop.yml +++ b/.github/workflows/interop.yml @@ -10,7 +10,7 @@ on: - 'master' env: - GO_VERSION: 1.22.x + GO_VERSION: 1.23.x concurrency: group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.event_name == 'push' && github.sha || github.ref }} diff --git a/.github/workflows/sharness.yml b/.github/workflows/sharness.yml index 6432745bf..af7fa896c 100644 --- a/.github/workflows/sharness.yml +++ b/.github/workflows/sharness.yml @@ -25,7 +25,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: 1.22.x + go-version: 1.23.x - name: Checkout Kubo uses: actions/checkout@v4 with: diff --git a/Dockerfile b/Dockerfile index 4ed07d3d4..e04b3c666 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM --platform=${BUILDPLATFORM:-linux/amd64} golang:1.22 AS builder +FROM --platform=${BUILDPLATFORM:-linux/amd64} golang:1.23 AS builder ARG TARGETOS TARGETARCH diff --git a/core/commands/bitswap.go b/core/commands/bitswap.go index 6502876d1..07f91fb0f 100644 --- a/core/commands/bitswap.go +++ b/core/commands/bitswap.go @@ -109,7 +109,7 @@ var bitswapStatCmd = &cmds.Command{ } if !nd.IsOnline { - return cmds.Errorf(cmds.ErrClient, ErrNotOnline.Error()) + return cmds.Errorf(cmds.ErrClient, "unable to run offline: %s", ErrNotOnline) } bs, ok := nd.Exchange.(*bitswap.Bitswap) diff --git a/core/commands/files.go b/core/commands/files.go index 6add671ce..d1a52cbfb 100644 --- a/core/commands/files.go +++ b/core/commands/files.go @@ -182,7 +182,7 @@ var filesStatCmd = &cmds.Command{ Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { _, err := statGetFormatOptions(req) if err != nil { - return cmds.Errorf(cmds.ErrClient, err.Error()) + return cmds.Errorf(cmds.ErrClient, "invalid parameters: %s", err) } node, err := cmdenv.GetNode(env) diff --git a/core/commands/name/ipnsps.go b/core/commands/name/ipnsps.go index f57173eea..e465549e0 100644 --- a/core/commands/name/ipnsps.go +++ b/core/commands/name/ipnsps.go @@ -135,7 +135,7 @@ var ipnspsCancelCmd = &cmds.Command{ name = strings.TrimPrefix(name, "/ipns/") pid, err := peer.Decode(name) if err != nil { - return cmds.Errorf(cmds.ErrClient, err.Error()) + return cmds.Errorf(cmds.ErrClient, "not a valid IPNS name: %s", err) } ok, err := n.PSRouter.Cancel("/ipns/" + string(pid)) diff --git a/core/commands/name/name.go b/core/commands/name/name.go index 9445fc362..912629d68 100644 --- a/core/commands/name/name.go +++ b/core/commands/name/name.go @@ -260,8 +260,7 @@ Passing --verify will verify signature against provided public key. if out.HexDump != "" { tw.Flush() - fmt.Fprintf(w, "\nHex Dump:\n") - fmt.Fprintf(w, out.HexDump) + fmt.Fprintf(w, "\nHex Dump:\n%s", out.HexDump) } return nil diff --git a/core/commands/refs.go b/core/commands/refs.go index cefd8af90..53c92c3df 100644 --- a/core/commands/refs.go +++ b/core/commands/refs.go @@ -21,7 +21,7 @@ import ( var refsEncoderMap = cmds.EncoderMap{ cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *RefWrapper) error { if out.Err != "" { - return fmt.Errorf(out.Err) + return errors.New(out.Err) } fmt.Fprintln(w, out.Ref) diff --git a/core/commands/stat.go b/core/commands/stat.go index a09c70ea1..4ceb95f13 100644 --- a/core/commands/stat.go +++ b/core/commands/stat.go @@ -96,7 +96,7 @@ Example: // Must be online! if !nd.IsOnline { - return cmds.Errorf(cmds.ErrClient, ErrNotOnline.Error()) + return cmds.Errorf(cmds.ErrClient, "unable to run offline: %s", ErrNotOnline) } if nd.Reporter == nil { diff --git a/core/commands/swarm.go b/core/commands/swarm.go index 4fe535ffc..252c48d33 100644 --- a/core/commands/swarm.go +++ b/core/commands/swarm.go @@ -557,7 +557,7 @@ var swarmAddrsCmd = &cmds.Command{ paddrs := am.Addrs[p] fmt.Fprintf(w, "%s (%d)\n", p, len(paddrs)) for _, addr := range paddrs { - fmt.Fprintf(w, "\t"+addr+"\n") + fmt.Fprintf(w, "\t%s\n", addr) } } diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 734376538..49010af31 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -1,8 +1,6 @@ module github.com/ipfs/kubo/examples/kubo-as-a-library -go 1.22 - -toolchain go1.22.0 +go 1.23 // Used to keep this in sync with the current version of kubo. You should remove // this if you copy this example. diff --git a/go.mod b/go.mod index 3f86b7f54..257733cca 100644 --- a/go.mod +++ b/go.mod @@ -251,4 +251,4 @@ require ( lukechampine.com/blake3 v1.3.0 // indirect ) -go 1.22 +go 1.23 diff --git a/plugin/loader/loader.go b/plugin/loader/loader.go index 80cc9a1b6..4ea3ac226 100644 --- a/plugin/loader/loader.go +++ b/plugin/loader/loader.go @@ -2,6 +2,7 @@ package loader import ( "encoding/json" + "errors" "fmt" "io" "os" @@ -361,7 +362,7 @@ func (loader *PluginLoader) Close() error { } if errs != nil { loader.state = loaderFailed - return fmt.Errorf(strings.Join(errs, "\n")) + return errors.New(strings.Join(errs, "\n")) } loader.state = loaderClosed return nil diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 32941dd14..4df60a3d7 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -1,14 +1,12 @@ module github.com/ipfs/kubo/test/dependencies -go 1.22 - -toolchain go1.22.0 +go 1.23 replace github.com/ipfs/kubo => ../../ require ( github.com/Kubuxu/gocovmerge v0.0.0-20161216165753-7ecaa51963cd - github.com/golangci/golangci-lint v1.59.1 + github.com/golangci/golangci-lint v1.60.2 github.com/ipfs/go-cidutil v0.1.0 github.com/ipfs/go-log v1.0.5 github.com/ipfs/hang-fds v0.1.0 @@ -28,9 +26,9 @@ require ( github.com/Abirdcfly/dupword v0.0.14 // indirect github.com/Antonboom/errname v0.1.13 // indirect github.com/Antonboom/nilnil v0.1.9 // indirect - github.com/Antonboom/testifylint v1.4.1 // indirect - github.com/BurntSushi/toml v1.4.0 // indirect - github.com/Crocmagnon/fatcontext v0.3.0 // indirect + github.com/Antonboom/testifylint v1.4.3 // indirect + github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c // indirect + github.com/Crocmagnon/fatcontext v0.4.0 // indirect github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 // indirect github.com/GaijinEntertainment/go-exhaustruct/v3 v3.3.0 // indirect github.com/Masterminds/semver/v3 v3.2.1 // indirect @@ -45,7 +43,7 @@ require ( github.com/bitfield/gotestdox v0.2.2 // indirect github.com/bkielbasa/cyclop v1.2.1 // indirect github.com/blizzy78/varnamelen v0.8.0 // indirect - github.com/bombsimon/wsl/v4 v4.4.0 // indirect + github.com/bombsimon/wsl/v4 v4.4.1 // indirect github.com/breml/bidichk v0.2.7 // indirect github.com/breml/errchkjson v0.3.6 // indirect github.com/butuzov/ireturn v0.3.0 // indirect @@ -56,7 +54,7 @@ require ( github.com/charithe/durationcheck v0.0.10 // indirect github.com/chavacava/garif v0.1.0 // indirect github.com/ckaznocha/intrange v0.1.2 // indirect - github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect github.com/curioswitch/go-reassign v0.2.0 // indirect github.com/daixiang0/gci v0.13.4 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect @@ -85,10 +83,10 @@ require ( github.com/go-viper/mapstructure/v2 v2.0.0 // indirect github.com/go-xmlfmt/xmlfmt v1.1.2 // indirect github.com/gobwas/glob v0.2.3 // indirect - github.com/gofrs/flock v0.8.1 // indirect + github.com/gofrs/flock v0.12.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a // indirect - github.com/golangci/gofmt v0.0.0-20231019111953-be8c47862aaa // indirect + github.com/golangci/gofmt v0.0.0-20240816233607-d8596aa466a9 // indirect github.com/golangci/misspell v0.6.0 // indirect github.com/golangci/modinfo v0.3.4 // indirect github.com/golangci/plugin-module-register v0.1.1 // indirect @@ -129,7 +127,7 @@ require ( github.com/jgautheron/goconst v1.7.1 // indirect github.com/jingyugao/rowserrcheck v1.1.1 // indirect github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af // indirect - github.com/jjti/go-spancheck v0.6.1 // indirect + github.com/jjti/go-spancheck v0.6.2 // indirect github.com/julz/importas v0.1.0 // indirect github.com/karamaru-alpha/copyloopvar v1.1.0 // indirect github.com/kisielk/errcheck v1.7.0 // indirect @@ -161,12 +159,12 @@ require ( github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-runewidth v0.0.15 // indirect - github.com/mgechev/revive v1.3.7 // indirect + github.com/mgechev/revive v1.3.9 // indirect github.com/miekg/dns v1.1.61 // indirect github.com/minio/sha256-simd v1.0.1 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect - github.com/moricho/tparallel v0.3.1 // indirect + github.com/moricho/tparallel v0.3.2 // indirect github.com/mr-tron/base58 v1.2.0 // indirect github.com/multiformats/go-base32 v0.1.0 // indirect github.com/multiformats/go-base36 v0.2.0 // indirect @@ -186,7 +184,7 @@ require ( github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/polydawn/refmt v0.89.0 // indirect - github.com/polyfloyd/go-errorlint v1.5.2 // indirect + github.com/polyfloyd/go-errorlint v1.6.0 // indirect github.com/prometheus/client_golang v1.19.1 // indirect github.com/prometheus/client_model v0.6.1 // indirect github.com/prometheus/common v0.55.0 // indirect @@ -198,7 +196,7 @@ require ( github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 // indirect github.com/rivo/uniseg v0.4.7 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect - github.com/ryancurrah/gomodguard v1.3.2 // indirect + github.com/ryancurrah/gomodguard v1.3.3 // indirect github.com/ryanrolds/sqlclosecheck v0.5.1 // indirect github.com/sagikazarmark/locafero v0.6.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect @@ -207,7 +205,7 @@ require ( github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 // indirect github.com/sashamelentyev/interfacebloat v1.1.0 // indirect github.com/sashamelentyev/usestdlibvars v1.27.0 // indirect - github.com/securego/gosec/v2 v2.20.1-0.20240525090044-5f0084eb01a9 // indirect + github.com/securego/gosec/v2 v2.20.1-0.20240820084340-81cda2f91fbe // indirect github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/sivchari/containedctx v1.0.3 // indirect @@ -218,7 +216,7 @@ require ( github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/spf13/afero v1.11.0 // indirect github.com/spf13/cast v1.6.0 // indirect - github.com/spf13/cobra v1.8.0 // indirect + github.com/spf13/cobra v1.8.1 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/spf13/viper v1.19.0 // indirect github.com/ssgreg/nlreturn/v2 v2.2.1 // indirect @@ -226,17 +224,16 @@ require ( github.com/stretchr/objx v0.5.2 // indirect github.com/stretchr/testify v1.9.0 // indirect github.com/subosito/gotenv v1.6.0 // indirect - github.com/t-yuki/gocover-cobertura v0.0.0-20180217150009-aaee18c8195c // indirect github.com/tdakkota/asciicheck v0.2.0 // indirect github.com/tetafro/godot v1.4.16 // indirect github.com/timakin/bodyclose v0.0.0-20240125160201-f835fa56326a // indirect github.com/timonwong/loggercheck v0.9.4 // indirect - github.com/tomarrell/wrapcheck/v2 v2.8.3 // indirect + github.com/tomarrell/wrapcheck/v2 v2.9.0 // indirect github.com/tommy-muehle/go-mnd/v2 v2.5.1 // indirect github.com/ultraware/funlen v0.1.0 // indirect github.com/ultraware/whitespace v0.1.1 // indirect github.com/urfave/cli v1.22.10 // indirect - github.com/uudashr/gocognit v1.1.2 // indirect + github.com/uudashr/gocognit v1.1.3 // indirect github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc // indirect github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect github.com/xen0n/gosmopolitan v1.2.2 // indirect @@ -245,7 +242,7 @@ require ( github.com/ykadowak/zerologlint v0.1.5 // indirect gitlab.com/bosi/decorder v0.4.2 // indirect go-simpler.org/musttag v0.12.2 // indirect - go-simpler.org/sloglint v0.7.1 // indirect + go-simpler.org/sloglint v0.7.2 // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/otel v1.28.0 // indirect go.opentelemetry.io/otel/metric v1.28.0 // indirect @@ -253,23 +250,23 @@ require ( go.uber.org/automaxprocs v1.5.3 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect - golang.org/x/crypto v0.25.0 // indirect + golang.org/x/crypto v0.26.0 // indirect golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect golang.org/x/exp/typeparams v0.0.0-20240613232115-7f521ea00fb8 // indirect - golang.org/x/mod v0.19.0 // indirect - golang.org/x/net v0.27.0 // indirect - golang.org/x/sync v0.7.0 // indirect + golang.org/x/mod v0.20.0 // indirect + golang.org/x/net v0.28.0 // indirect + golang.org/x/sync v0.8.0 // indirect golang.org/x/sys v0.24.0 // indirect golang.org/x/term v0.23.0 // indirect - golang.org/x/text v0.16.0 // indirect - golang.org/x/tools v0.23.0 // indirect + golang.org/x/text v0.17.0 // indirect + golang.org/x/tools v0.24.0 // indirect gonum.org/v1/gonum v0.15.0 // indirect google.golang.org/protobuf v1.34.2 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - honnef.co/go/tools v0.4.7 // indirect + honnef.co/go/tools v0.5.1 // indirect lukechampine.com/blake3 v1.3.0 // indirect - mvdan.cc/gofumpt v0.6.0 // indirect + mvdan.cc/gofumpt v0.7.0 // indirect mvdan.cc/unparam v0.0.0-20240528143540-8a5130ca722f // indirect ) diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 2d055f038..72798a87f 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -11,13 +11,13 @@ github.com/Antonboom/errname v0.1.13 h1:JHICqsewj/fNckzrfVSe+T33svwQxmjC+1ntDsHO github.com/Antonboom/errname v0.1.13/go.mod h1:uWyefRYRN54lBg6HseYCFhs6Qjcy41Y3Jl/dVhA87Ns= github.com/Antonboom/nilnil v0.1.9 h1:eKFMejSxPSA9eLSensFmjW2XTgTwJMjZ8hUHtV4s/SQ= github.com/Antonboom/nilnil v0.1.9/go.mod h1:iGe2rYwCq5/Me1khrysB4nwI7swQvjclR8/YRPl5ihQ= -github.com/Antonboom/testifylint v1.4.1 h1:LeBVoSeqCgJoHqwu46yzm7Zgcm6T7QhDYfT9VtFIRpg= -github.com/Antonboom/testifylint v1.4.1/go.mod h1:+8Q9+AOLsz5ZiQiiYujJKs9mNz398+M6UgslP4qgJLA= +github.com/Antonboom/testifylint v1.4.3 h1:ohMt6AHuHgttaQ1xb6SSnxCeK4/rnK7KKzbvs7DmEck= +github.com/Antonboom/testifylint v1.4.3/go.mod h1:+8Q9+AOLsz5ZiQiiYujJKs9mNz398+M6UgslP4qgJLA= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0= -github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= -github.com/Crocmagnon/fatcontext v0.3.0 h1:S6gNUYNSN9V76Tu017OFgoaOpybmMhwe6Ewh1cYd0jg= -github.com/Crocmagnon/fatcontext v0.3.0/go.mod h1:x3F9YW5CFE7vo+FGA5GzBD1SBXU4FQI0+y1ReG4Q+pY= +github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c h1:pxW6RcqyfI9/kWtOwnv/G+AzdKuy2ZrqINhenH4HyNs= +github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= +github.com/Crocmagnon/fatcontext v0.4.0 h1:4ykozu23YHA0JB6+thiuEv7iT6xq995qS1vcuWZq0tg= +github.com/Crocmagnon/fatcontext v0.4.0/go.mod h1:ZtWrXkgyfsYPzS6K3O88va6t2GEglG93vnII/F94WC0= github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 h1:sHglBQTwgx+rWPdisA5ynNEsoARbiCBOyGcJM4/OzsM= github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs= github.com/GaijinEntertainment/go-exhaustruct/v3 v3.3.0 h1:/fTUt5vmbkAcMBt4YQiuC23cV0kEsN1MVMNqeOW43cU= @@ -55,8 +55,8 @@ github.com/bkielbasa/cyclop v1.2.1 h1:AeF71HZDob1P2/pRm1so9cd1alZnrpyc4q2uP2l0gJ github.com/bkielbasa/cyclop v1.2.1/go.mod h1:K/dT/M0FPAiYjBgQGau7tz+3TMh4FWAEqlMhzFWCrgM= github.com/blizzy78/varnamelen v0.8.0 h1:oqSblyuQvFsW1hbBHh1zfwrKe3kcSj0rnXkKzsQ089M= github.com/blizzy78/varnamelen v0.8.0/go.mod h1:V9TzQZ4fLJ1DSrjVDfl89H7aMnTvKkApdHeyESmyR7k= -github.com/bombsimon/wsl/v4 v4.4.0 h1:1FHD09Li8Okn1/iERsSOo+0pXZZpVuw0XUz5/a+4+UQ= -github.com/bombsimon/wsl/v4 v4.4.0/go.mod h1:Xu/kDxGZTofQcDGCtQe9KCzhHphIe0fDuyWTxER9Feo= +github.com/bombsimon/wsl/v4 v4.4.1 h1:jfUaCkN+aUpobrMO24zwyAMwMAV5eSziCkOKEauOLdw= +github.com/bombsimon/wsl/v4 v4.4.1/go.mod h1:Xu/kDxGZTofQcDGCtQe9KCzhHphIe0fDuyWTxER9Feo= github.com/breml/bidichk v0.2.7 h1:dAkKQPLl/Qrk7hnP6P+E0xOodrq8Us7+U0o4UBOAlQY= github.com/breml/bidichk v0.2.7/go.mod h1:YodjipAGI9fGcYM7II6wFvGhdMYsC5pHDlGzqvEW3tQ= github.com/breml/errchkjson v0.3.6 h1:VLhVkqSBH96AvXEyclMR37rZslRrY2kcyq+31HCsVrA= @@ -85,8 +85,8 @@ github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHq github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= 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.3 h1:qMCsGGgs+MAzDFyp9LpAe1Lqy/fY/qCovCm0qnXZOBM= -github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4= +github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/cskr/pubsub v1.0.2 h1:vlOzMhl6PFn60gRlTQQsIfVwaPB/B/8MziK8FhEPt/0= github.com/cskr/pubsub v1.0.2/go.mod h1:/8MzYXk/NJAz782G8RPkFzXTZVu63VotefPnR9TIRis= github.com/curioswitch/go-reassign v0.2.0 h1:G9UZyOcpk/d7Gd6mqYgd8XYWFMw/znxwGDUstnC9DIo= @@ -148,6 +148,8 @@ github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-quicktest/qt v1.101.0 h1:O1K29Txy5P2OK0dGo59b7b0LR6wKfIhttaAhHUyn7eI= +github.com/go-quicktest/qt v1.101.0/go.mod h1:14Bz/f7NwaXPtdYEgzsx46kqSxVwTbzVZsDC26tQJow= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/go-toolsmith/astcast v1.1.0 h1:+JN9xZV1A+Re+95pgnMgDboWNVnIMMQXwfBwLRPgSC8= @@ -178,8 +180,8 @@ github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= -github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= +github.com/gofrs/flock v0.12.1 h1:MTLVXXHf8ekldpJk3AKicLij9MdwOWkZ+a/jHHZby9E= +github.com/gofrs/flock v0.12.1/go.mod h1:9zxTsyu5xtJ9DK+1tFZyibEV7y3uwDxPPfbxeeHCoD0= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= @@ -198,10 +200,10 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a h1:w8hkcTqaFpzKqonE9uMCefW1WDie15eSP/4MssdenaM= github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a/go.mod h1:ryS0uhF+x9jgbj/N71xsEqODy9BN81/GonCZiOzirOk= -github.com/golangci/gofmt v0.0.0-20231019111953-be8c47862aaa h1:L0Zq43Px2HrLroRKEgfCsQLMJUkjskJBB1kd1Zjcvvc= -github.com/golangci/gofmt v0.0.0-20231019111953-be8c47862aaa/go.mod h1:Pm5KhLPA8gSnQwrQ6ukebRcapGb/BG9iUkdaiCcGHJM= -github.com/golangci/golangci-lint v1.59.1 h1:CRRLu1JbhK5avLABFJ/OHVSQ0Ie5c4ulsOId1h3TTks= -github.com/golangci/golangci-lint v1.59.1/go.mod h1:jX5Oif4C7P0j9++YB2MMJmoNrb01NJ8ITqKWNLewThg= +github.com/golangci/gofmt v0.0.0-20240816233607-d8596aa466a9 h1:/1322Qns6BtQxUZDTAT4SdcoxknUki7IAoK4SAXr8ME= +github.com/golangci/gofmt v0.0.0-20240816233607-d8596aa466a9/go.mod h1:Oesb/0uFAyWoaw1U1qS5zyjCg5NP9C9iwjnI4tIsXEE= +github.com/golangci/golangci-lint v1.60.2 h1:Y8aWnZCMOLY5T7Ga5hcoemyKsZZJCUmIIK3xTD3jIhc= +github.com/golangci/golangci-lint v1.60.2/go.mod h1:4UvjLpOJoQSvmyWkmO1urDR3txhL9R9sn4oM/evJ95g= github.com/golangci/misspell v0.6.0 h1:JCle2HUTNWirNlDIAUO44hUsKhOFqGPoC4LZxlaSXDs= github.com/golangci/misspell v0.6.0/go.mod h1:keMNyY6R9isGaSAu+4Q8NMBwMPkh15Gtc8UCVoDtAWo= github.com/golangci/modinfo v0.3.4 h1:oU5huX3fbxqQXdfspamej74DFX0kyGLkw1ppvXoJ8GA= @@ -339,8 +341,8 @@ github.com/jingyugao/rowserrcheck v1.1.1 h1:zibz55j/MJtLsjP1OF4bSdgXxwL1b+Vn7Tjz github.com/jingyugao/rowserrcheck v1.1.1/go.mod h1:4yvlZSDb3IyDTUZJUmpZfm2Hwok+Dtp+nu2qOq+er9c= github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af h1:KA9BjwUk7KlCh6S9EAGWBt1oExIUv9WyNCiRz5amv48= github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af/go.mod h1:HEWGJkRDzjJY2sqdDwxccsGicWEf9BQOZsq2tV+xzM0= -github.com/jjti/go-spancheck v0.6.1 h1:ZK/wE5Kyi1VX3PJpUO2oEgeoI4FWOUm7Shb2Gbv5obI= -github.com/jjti/go-spancheck v0.6.1/go.mod h1:vF1QkOO159prdo6mHRxak2CpzDpHAfKiPUDP/NeRnX8= +github.com/jjti/go-spancheck v0.6.2 h1:iYtoxqPMzHUPp7St+5yA8+cONdyXD3ug6KK15n7Pklk= +github.com/jjti/go-spancheck v0.6.2/go.mod h1:+X7lvIrR5ZdUTkxFYqzJ0abr8Sb5LOo80uOhWNqIrYA= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julz/importas v0.1.0 h1:F78HnrsjY3cR7j0etXy5+TU1Zuy7Xt08X/1aJnH5xXY= @@ -437,8 +439,8 @@ github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/mgechev/revive v1.3.7 h1:502QY0vQGe9KtYJ9FpxMz9rL+Fc/P13CI5POL4uHCcE= -github.com/mgechev/revive v1.3.7/go.mod h1:RJ16jUbF0OWC3co/+XTxmFNgEpUPwnnA0BRllX2aDNA= +github.com/mgechev/revive v1.3.9 h1:18Y3R4a2USSBF+QZKFQwVkBROUda7uoBlkEuBD+YD1A= +github.com/mgechev/revive v1.3.9/go.mod h1:+uxEIr5UH0TjXWHTno3xh4u7eg6jDpXKzQccA9UGhHU= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= github.com/miekg/dns v1.1.61 h1:nLxbwF3XxhwVSm8g9Dghm9MHPaUZuqhPiGL+675ZmEs= github.com/miekg/dns v1.1.61/go.mod h1:mnAarhS3nWaW+NVP2wTkYVIZyHNJ098SJZUki3eykwQ= @@ -454,8 +456,8 @@ github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/moricho/tparallel v0.3.1 h1:fQKD4U1wRMAYNngDonW5XupoB/ZGJHdpzrWqgyg9krA= -github.com/moricho/tparallel v0.3.1/go.mod h1:leENX2cUv7Sv2qDgdi0D0fCftN8fRC67Bcn8pqzeYNI= +github.com/moricho/tparallel v0.3.2 h1:odr8aZVFA3NZrNybggMkYO3rgPRcqjeQUlBBFVxKHTI= +github.com/moricho/tparallel v0.3.2/go.mod h1:OQ+K3b4Ln3l2TZveGCywybl68glfLEwFGqvnjok8b+U= github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= @@ -494,10 +496,10 @@ github.com/nunnatsa/ginkgolinter v0.16.2 h1:8iLqHIZvN4fTLDC0Ke9tbSZVcyVHoBs0HIbn github.com/nunnatsa/ginkgolinter v0.16.2/go.mod h1:4tWRinDN1FeJgU+iJANW/kz7xKN5nYRAOfJDQUS9dOQ= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= -github.com/onsi/ginkgo/v2 v2.19.1 h1:QXgq3Z8Crl5EL1WBAC98A5sEBHARrAJNzAmMxzLcRF0= -github.com/onsi/ginkgo/v2 v2.19.1/go.mod h1:O3DtEWQkPa/F7fBMgmZQKKsluAy8pd3rEQdrjkPb9zA= -github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk= -github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0= +github.com/onsi/ginkgo/v2 v2.20.0 h1:PE84V2mHqoT1sglvHc8ZdQtPcwmvvt29WLEEO3xmdZw= +github.com/onsi/ginkgo/v2 v2.20.0/go.mod h1:lG9ey2Z29hR41WMVthyJBGUBcBhGOtoPF2VFMvBXFCI= +github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k= +github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY= github.com/opencontainers/runtime-spec v1.2.0 h1:z97+pHb3uELt/yiAWD691HNHQIF07bE7dzrbT927iTk= github.com/opencontainers/runtime-spec v1.2.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= @@ -553,8 +555,8 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/polydawn/refmt v0.89.0 h1:ADJTApkvkeBZsN0tBTx8QjpD9JkmxbKp0cxfr9qszm4= github.com/polydawn/refmt v0.89.0/go.mod h1:/zvteZs/GwLtCgZ4BL6CBsk9IKIlexP43ObX9AxTqTw= -github.com/polyfloyd/go-errorlint v1.5.2 h1:SJhVik3Umsjh7mte1vE0fVZ5T1gznasQG3PV7U5xFdA= -github.com/polyfloyd/go-errorlint v1.5.2/go.mod h1:sH1QC1pxxi0fFecsVIzBmxtrgd9IF/SkJpA6wqyKAJs= +github.com/polyfloyd/go-errorlint v1.6.0 h1:tftWV9DE7txiFzPpztTAwyoRLKNj9gpVm2cg8/OwcYY= +github.com/polyfloyd/go-errorlint v1.6.0/go.mod h1:HR7u8wuP1kb1NeN1zqTd1ZMlqUKPPHF+Id4vIPvDqVw= github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g= github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U= github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE= @@ -594,8 +596,8 @@ github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99 github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/ryancurrah/gomodguard v1.3.2 h1:CuG27ulzEB1Gu5Dk5gP8PFxSOZ3ptSdP5iI/3IXxM18= -github.com/ryancurrah/gomodguard v1.3.2/go.mod h1:LqdemiFomEjcxOqirbQCb3JFvSxH2JUYMerTFd3sF2o= +github.com/ryancurrah/gomodguard v1.3.3 h1:eiSQdJVNr9KTNxY2Niij8UReSwR8Xrte3exBrAZfqpg= +github.com/ryancurrah/gomodguard v1.3.3/go.mod h1:rsKQjj4l3LXe8N344Ow7agAy5p9yjsWOtRzUMYmA0QY= github.com/ryanrolds/sqlclosecheck v0.5.1 h1:dibWW826u0P8jNLsLN+En7+RqWWTYrjCB9fJfSfdyCU= github.com/ryanrolds/sqlclosecheck v0.5.1/go.mod h1:2g3dUjoS6AL4huFdv6wn55WpLIDjY7ZgUR4J8HOO/XQ= github.com/sagikazarmark/locafero v0.6.0 h1:ON7AQg37yzcRPU69mt7gwhFEBwxI6P9T4Qu3N51bwOk= @@ -612,8 +614,8 @@ github.com/sashamelentyev/interfacebloat v1.1.0 h1:xdRdJp0irL086OyW1H/RTZTr1h/tM github.com/sashamelentyev/interfacebloat v1.1.0/go.mod h1:+Y9yU5YdTkrNvoX0xHc84dxiN1iBi9+G8zZIhPVoNjQ= github.com/sashamelentyev/usestdlibvars v1.27.0 h1:t/3jZpSXtRPRf2xr0m63i32ZrusyurIGT9E5wAvXQnI= github.com/sashamelentyev/usestdlibvars v1.27.0/go.mod h1:9nl0jgOfHKWNFS43Ojw0i7aRoS4j6EBye3YBhmAIRF8= -github.com/securego/gosec/v2 v2.20.1-0.20240525090044-5f0084eb01a9 h1:rnO6Zp1YMQwv8AyxzuwsVohljJgp4L0ZqiCgtACsPsc= -github.com/securego/gosec/v2 v2.20.1-0.20240525090044-5f0084eb01a9/go.mod h1:dg7lPlu/xK/Ut9SedURCoZbVCR4yC7fM65DtH9/CDHs= +github.com/securego/gosec/v2 v2.20.1-0.20240820084340-81cda2f91fbe h1:exdneYmXwZ4+VaIWv9mQ47uIHkTQSN50DYdCjXJ1cdQ= +github.com/securego/gosec/v2 v2.20.1-0.20240820084340-81cda2f91fbe/go.mod h1:iyeMMRw8QEmueUSZ2VqmkQMiDyDcobfPnG00CV/NWdE= github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c h1:W65qqJCIOVP4jpqPQ0YvHYKwcMEMVWIzWC5iNQQfBTU= github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c/go.mod h1:/PevMnwAxekIXwN8qQyfc5gl2NlkB3CQlkizAbOkeBs= github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= @@ -641,8 +643,8 @@ github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= -github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= -github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= +github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= +github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI= @@ -668,8 +670,6 @@ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsT github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= -github.com/t-yuki/gocover-cobertura v0.0.0-20180217150009-aaee18c8195c h1:+aPplBwWcHBo6q9xrfWdMrT9o4kltkmmvpemgIjep/8= -github.com/t-yuki/gocover-cobertura v0.0.0-20180217150009-aaee18c8195c/go.mod h1:SbErYREK7xXdsRiigaQiQkI9McGRzYMvlKYaP3Nimdk= github.com/tdakkota/asciicheck v0.2.0 h1:o8jvnUANo0qXtnslk2d3nMKTFNlOnJjRrNcj0j9qkHM= github.com/tdakkota/asciicheck v0.2.0/go.mod h1:Qb7Y9EgjCLJGup51gDHFzbI08/gbGhL/UVhYIPWG2rg= github.com/tenntenn/modver v1.0.1 h1:2klLppGhDgzJrScMpkj9Ujy3rXPUspSjAcev9tSEBgA= @@ -682,8 +682,8 @@ github.com/timakin/bodyclose v0.0.0-20240125160201-f835fa56326a h1:A6uKudFIfAEpo github.com/timakin/bodyclose v0.0.0-20240125160201-f835fa56326a/go.mod h1:mkjARE7Yr8qU23YcGMSALbIxTQ9r9QBVahQOBRfU460= github.com/timonwong/loggercheck v0.9.4 h1:HKKhqrjcVj8sxL7K77beXh0adEm6DLjV/QOGeMXEVi4= github.com/timonwong/loggercheck v0.9.4/go.mod h1:caz4zlPcgvpEkXgVnAJGowHAMW2NwHaNlpS8xDbVhTg= -github.com/tomarrell/wrapcheck/v2 v2.8.3 h1:5ov+Cbhlgi7s/a42BprYoxsr73CbdMUTzE3bRDFASUs= -github.com/tomarrell/wrapcheck/v2 v2.8.3/go.mod h1:g9vNIyhb5/9TQgumxQyOEqDHsmGYcGsVMOx/xGkqdMo= +github.com/tomarrell/wrapcheck/v2 v2.9.0 h1:801U2YCAjLhdN8zhZ/7tdjB3EnAoRlJHt/s+9hijLQ4= +github.com/tomarrell/wrapcheck/v2 v2.9.0/go.mod h1:g9vNIyhb5/9TQgumxQyOEqDHsmGYcGsVMOx/xGkqdMo= github.com/tommy-muehle/go-mnd/v2 v2.5.1 h1:NowYhSdyE/1zwK9QCLeRb6USWdoif80Ie+v+yU8u1Zw= github.com/tommy-muehle/go-mnd/v2 v2.5.1/go.mod h1:WsUAkMJMYww6l/ufffCD3m+P7LEvr8TnZn9lwVDlgzw= github.com/ultraware/funlen v0.1.0 h1:BuqclbkY6pO+cvxoq7OsktIXZpgBSkYTQtmwhAK81vI= @@ -693,8 +693,8 @@ github.com/ultraware/whitespace v0.1.1/go.mod h1:XcP1RLD81eV4BW8UhQlpaR+SDc2givT github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.10 h1:p8Fspmz3iTctJstry1PYS3HVdllxnEzTEsgIgtxTrCk= github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/uudashr/gocognit v1.1.2 h1:l6BAEKJqQH2UpKAPKdMfZf5kE4W/2xk8pfU1OVLvniI= -github.com/uudashr/gocognit v1.1.2/go.mod h1:aAVdLURqcanke8h3vg35BC++eseDm66Z7KmchI5et4k= +github.com/uudashr/gocognit v1.1.3 h1:l+a111VcDbKfynh+airAy/DJQKaXh2m9vkoysMPSZyM= +github.com/uudashr/gocognit v1.1.3/go.mod h1:aKH8/e8xbTRBwjbCkwZ8qt4l2EpKXl31KMHgSS+lZ2U= github.com/warpfork/go-testmark v0.12.1 h1:rMgCpJfwy1sJ50x0M0NgyphxYYPMOODIJHhsXyEHU0s= github.com/warpfork/go-testmark v0.12.1/go.mod h1:kHwy7wfvGSPh1rQJYKayD4AbtNaeyZdcGi9tNJTaa5Y= github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0 h1:GDDkbFiaK8jsSDJfjId/PEGEShv6ugrt4kYsC5UIDaQ= @@ -726,8 +726,8 @@ go-simpler.org/assert v0.9.0 h1:PfpmcSvL7yAnWyChSjOz6Sp6m9j5lyK8Ok9pEL31YkQ= go-simpler.org/assert v0.9.0/go.mod h1:74Eqh5eI6vCK6Y5l3PI8ZYFXG4Sa+tkr70OIPJAUr28= go-simpler.org/musttag v0.12.2 h1:J7lRc2ysXOq7eM8rwaTYnNrHd5JwjppzB6mScysB2Cs= go-simpler.org/musttag v0.12.2/go.mod h1:uN1DVIasMTQKk6XSik7yrJoEysGtR2GRqvWnI9S7TYM= -go-simpler.org/sloglint v0.7.1 h1:qlGLiqHbN5islOxjeLXoPtUdZXb669RW+BDQ+xOSNoU= -go-simpler.org/sloglint v0.7.1/go.mod h1:OlaVDRh/FKKd4X4sIMbsz8st97vomydceL146Fthh/c= +go-simpler.org/sloglint v0.7.2 h1:Wc9Em/Zeuu7JYpl+oKoYOsQSy2X560aVueCW/m6IijY= +go-simpler.org/sloglint v0.7.2/go.mod h1:US+9C80ppl7VsThQclkM7BkCHQAzuz8kHLsW3ppuluo= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= @@ -770,8 +770,8 @@ golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliY golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= @@ -801,8 +801,8 @@ golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.16.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= -golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -827,8 +827,8 @@ golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/net v0.16.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -842,8 +842,8 @@ golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -861,7 +861,6 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211105183446-c75c47738b0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220702020025-31831981b65f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -906,8 +905,8 @@ golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= @@ -935,7 +934,6 @@ golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= -golang.org/x/tools v0.1.11/go.mod h1:SgwaegtQh8clINPpECJMqnxLv9I09HLqnW3RMqW0CA4= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= @@ -945,8 +943,8 @@ golang.org/x/tools v0.11.0/go.mod h1:anzJrxPjNtfgiYQYirP2CPGzGLxrH2u2QBhn6Bf3qY8 golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= golang.org/x/tools v0.19.0/go.mod h1:qoJWxmGSIBmAeriMx19ogtrEPrGtDbPK634QFIcLAhc= -golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= -golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -996,11 +994,11 @@ gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -honnef.co/go/tools v0.4.7 h1:9MDAWxMoSnB6QoSqiVr7P5mtkT9pOc1kSxchzPCnqJs= -honnef.co/go/tools v0.4.7/go.mod h1:+rnGS1THNh8zMwnd2oVOTL9QF6vmfyG6ZXBULae2uc0= +honnef.co/go/tools v0.5.1 h1:4bH5o3b5ZULQ4UrBmP+63W9r7qIkqJClEA9ko5YKx+I= +honnef.co/go/tools v0.5.1/go.mod h1:e9irvo83WDG9/irijV44wr3tbhcFeRnfpVlRqVwpzMs= lukechampine.com/blake3 v1.3.0 h1:sJ3XhFINmHSrYCgl958hscfIa3bw8x4DqMP3u1YvoYE= lukechampine.com/blake3 v1.3.0/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= -mvdan.cc/gofumpt v0.6.0 h1:G3QvahNDmpD+Aek/bNOLrFR2XC6ZAdo62dZu65gmwGo= -mvdan.cc/gofumpt v0.6.0/go.mod h1:4L0wf+kgIPZtcCWXynNS2e6bhmj73umwnuXSZarixzA= +mvdan.cc/gofumpt v0.7.0 h1:bg91ttqXmi9y2xawvkuMXyvAA/1ZGJqYAEGjXuP0JXU= +mvdan.cc/gofumpt v0.7.0/go.mod h1:txVFJy/Sc/mvaycET54pV8SW8gWxTlUuGHVEcncmNUo= mvdan.cc/unparam v0.0.0-20240528143540-8a5130ca722f h1:lMpcwN6GxNbWtbpI1+xzFLSW8XzX0u72NttUGVFjO3U= mvdan.cc/unparam v0.0.0-20240528143540-8a5130ca722f/go.mod h1:RSLa7mKKCNeTTMHBw5Hsy2rfJmd6O2ivt9Dw9ZqCQpQ= From 5fe960474c4af2c7935839f5e3130dce45af8b63 Mon Sep 17 00:00:00 2001 From: Andrew Gillis <11790789+gammazero@users.noreply.github.com> Date: Wed, 28 Aug 2024 10:03:26 -0700 Subject: [PATCH 1142/1212] fix(cli): preserve hostname specified with --api in http request headers (#10497) Preserve hostname specified with --api in http request headers - Replaces PR #10233 - Add test to check for hostname in HTTP header - Update docs/changelogs/v0.30.md --- cmd/ipfs/kubo/start.go | 5 ++++- docs/changelogs/v0.30.md | 5 +++++ test/sharness/t0235-cli-request.sh | 6 +++++- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/cmd/ipfs/kubo/start.go b/cmd/ipfs/kubo/start.go index cae1e2c1b..474045e71 100644 --- a/cmd/ipfs/kubo/start.go +++ b/cmd/ipfs/kubo/start.go @@ -303,7 +303,10 @@ func makeExecutor(req *cmds.Request, env interface{}) (cmds.Executor, error) { } // Resolve the API addr. - apiAddr, err = resolveAddr(req.Context, apiAddr) + // + // Do not replace apiAddr with the resolved addr so that the requested + // hostname is kept for use in the request's HTTP header. + _, err = resolveAddr(req.Context, apiAddr) if err != nil { return nil, err } diff --git a/docs/changelogs/v0.30.md b/docs/changelogs/v0.30.md index e7f5d8b3f..4c22e40ba 100644 --- a/docs/changelogs/v0.30.md +++ b/docs/changelogs/v0.30.md @@ -13,6 +13,7 @@ - [`/unix/` socket support in `Addresses.API`](#unix-socket-support-in-addressesapi) - [Cleaned Up `ipfs daemon` Startup Log](#cleaned-up-ipfs-daemon-startup-log) - [UnixFS 1.5: Mode and Modification Time Support](#unixfs-15-mode-and-modification-time-support) + - [Commands Preserve Specified Hostname](#commands-preserve-specified-hostname) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -129,6 +130,10 @@ Modification time support was also added to the Gateway. If present, value from > [!NOTE] > Storing `mode` and `mtime` requires root block to be `dag-pb` and disabled `raw-leaves` setting to create envelope for storing the metadata. +#### Commands Preserve Specified Hostname + +When executing a [CLI command](https://docs.ipfs.tech/reference/kubo/cli/) over [Kubo RPC API](https://docs.ipfs.tech/reference/kubo/rpc/), if a hostname is specified by `--api=/dns4//` the resulting HTTP request now contains the hostname, instead of the the IP address that the hostname resolved to, as was the previous behavior. This makes it easier for those trying to run Kubo behind a reverse proxy using hostname-based rules. + ### 📝 Changelog ### 👨‍👩‍👧‍👦 Contributors diff --git a/test/sharness/t0235-cli-request.sh b/test/sharness/t0235-cli-request.sh index 3b2281894..02ef514de 100755 --- a/test/sharness/t0235-cli-request.sh +++ b/test/sharness/t0235-cli-request.sh @@ -28,7 +28,7 @@ test_expect_success "start nc" ' ' test_expect_success "can make http request against nc server" ' - ipfs cat /ipfs/Qmabcdef --api /ip4/127.0.0.1/tcp/5005 & + ipfs cat /ipfs/Qmabcdef --api /dns4/localhost/tcp/5005 & IPFSPID=$! # handle request for /api/v0/version @@ -80,4 +80,8 @@ test_expect_success "api flag does not appear in request" ' test_expect_code 1 grep "api=/ip4" nc_out ' +test_expect_success "host has dns name not ip address" ' + grep "Host: localhost:5005" nc_out +' + test_done From f0d2c99d372f35bbbdf9ae344d697695b6e1a29b Mon Sep 17 00:00:00 2001 From: Andrew Gillis <11790789+gammazero@users.noreply.github.com> Date: Wed, 28 Aug 2024 09:21:16 -0700 Subject: [PATCH 1143/1212] fix: error during config when running benchmarks (#10495) - Benchmarks were failing with error setting number of bits for ed25519 keys, which are the default now. - Update the random data generation package to remove a dependency. (cherry picked from commit 175aabdd85d2235e46bc163706dd7beb2c47ce05) --- go.mod | 1 - go.sum | 2 -- test/bench/bench_cli_ipfs_add/main.go | 11 ++++++++--- test/bench/offline_add/main.go | 11 ++++++++--- test/integration/addcat_test.go | 10 +++------- 5 files changed, 19 insertions(+), 16 deletions(-) diff --git a/go.mod b/go.mod index 3953ce881..f07715502 100644 --- a/go.mod +++ b/go.mod @@ -44,7 +44,6 @@ require ( github.com/ipld/go-car/v2 v2.13.1 github.com/ipld/go-codec-dagpb v1.6.0 github.com/ipld/go-ipld-prime v0.21.0 - 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/julienschmidt/httprouter v1.3.0 diff --git a/go.sum b/go.sum index 953bf5b5f..4c0c4fb61 100644 --- a/go.sum +++ b/go.sum @@ -446,8 +446,6 @@ github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7Bd github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/jbenet/go-cienv v0.1.0 h1:Vc/s0QbQtoxX8MwwSLWWh+xNNZvM3Lw7NsTcHrvvhMc= github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA= -github.com/jbenet/go-random v0.0.0-20190219211222-123a90aedc0c h1:uUx61FiAa1GI6ZmVd2wf2vULeQZIKG66eybjNXKYCz4= -github.com/jbenet/go-random v0.0.0-20190219211222-123a90aedc0c/go.mod h1:sdx1xVM9UuLw1tXnhJWN3piypTUO3vCIHYmG15KE/dU= github.com/jbenet/go-temp-err-catcher v0.1.0 h1:zpb3ZH6wIE8Shj2sKS+khgRvf7T7RABoLk/+KKHggpk= github.com/jbenet/go-temp-err-catcher v0.1.0/go.mod h1:0kJRvmDZXNMIiJirNPEYfhpPwbGVtZVWC34vc5WLsDk= github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY= diff --git a/test/bench/bench_cli_ipfs_add/main.go b/test/bench/bench_cli_ipfs_add/main.go index e7fe90e04..2c39ba636 100644 --- a/test/bench/bench_cli_ipfs_add/main.go +++ b/test/bench/bench_cli_ipfs_add/main.go @@ -3,6 +3,7 @@ package main import ( "flag" "fmt" + "io" "log" "os" "os/exec" @@ -11,8 +12,8 @@ import ( "github.com/ipfs/kubo/thirdparty/unit" + random "github.com/ipfs/go-test/random" config "github.com/ipfs/kubo/config" - random "github.com/jbenet/go-random" ) var ( @@ -59,7 +60,7 @@ func benchmarkAdd(amount int64) (*testing.BenchmarkResult, error) { } } - initCmd := exec.Command("ipfs", "init", "-b=2048") + initCmd := exec.Command("ipfs", "init") setupCmd(initCmd) if err := initCmd.Run(); err != nil { benchmarkError = err @@ -74,7 +75,11 @@ func benchmarkAdd(amount int64) (*testing.BenchmarkResult, error) { } defer os.Remove(f.Name()) - if err := random.WritePseudoRandomBytes(amount, f, seed); err != nil { + randReader := &io.LimitedReader{ + R: random.NewSeededRand(seed), + N: amount, + } + if _, err := io.Copy(f, randReader); err != nil { benchmarkError = err b.Fatal(err) } diff --git a/test/bench/offline_add/main.go b/test/bench/offline_add/main.go index 338a5f6ac..7c00d30f4 100644 --- a/test/bench/offline_add/main.go +++ b/test/bench/offline_add/main.go @@ -2,6 +2,7 @@ package main import ( "fmt" + "io" "log" "os" "os/exec" @@ -10,8 +11,8 @@ import ( "github.com/ipfs/kubo/thirdparty/unit" + random "github.com/ipfs/go-test/random" config "github.com/ipfs/kubo/config" - random "github.com/jbenet/go-random" ) func main() { @@ -44,7 +45,7 @@ func benchmarkAdd(amount int64) (*testing.BenchmarkResult, error) { cmd.Env = env } - cmd := exec.Command("ipfs", "init", "-b=2048") + cmd := exec.Command("ipfs", "init") setupCmd(cmd) if err := cmd.Run(); err != nil { b.Fatal(err) @@ -57,7 +58,11 @@ func benchmarkAdd(amount int64) (*testing.BenchmarkResult, error) { } defer os.Remove(f.Name()) - err = random.WritePseudoRandomBytes(amount, f, seed) + randReader := &io.LimitedReader{ + R: random.NewSeededRand(seed), + N: amount, + } + _, err = io.Copy(f, randReader) if err != nil { b.Fatal(err) } diff --git a/test/integration/addcat_test.go b/test/integration/addcat_test.go index 222326de2..936b28c6d 100644 --- a/test/integration/addcat_test.go +++ b/test/integration/addcat_test.go @@ -14,11 +14,11 @@ import ( "github.com/ipfs/boxo/bootstrap" "github.com/ipfs/boxo/files" logging "github.com/ipfs/go-log" + "github.com/ipfs/go-test/random" "github.com/ipfs/kubo/core" "github.com/ipfs/kubo/core/coreapi" mock "github.com/ipfs/kubo/core/mock" "github.com/ipfs/kubo/thirdparty/unit" - "github.com/jbenet/go-random" testutil "github.com/libp2p/go-libp2p-testing/net" "github.com/libp2p/go-libp2p/core/peer" mocknet "github.com/libp2p/go-libp2p/p2p/net/mock" @@ -84,12 +84,8 @@ func AddCatPowers(conf testutil.LatencyConfig, megabytesMax int64) error { } func RandomBytes(n int64) []byte { - var data bytes.Buffer - err := random.WritePseudoRandomBytes(n, &data, kSeed) - if err != nil { - panic(err) - } - return data.Bytes() + random.SetSeed(kSeed) + return random.Bytes(int(n)) } func DirectAddCat(data []byte, conf testutil.LatencyConfig) error { From 2b245e0275b8c7894811b3d4b404011f53314d7c Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Wed, 28 Aug 2024 18:56:45 +0200 Subject: [PATCH 1144/1212] chore: upgrade to go 1.23 (#10486) * chore: upgrade to go 1.23 https://tip.golang.org/doc/go1.23 * refactor: golangci-lint v1.60.2 (cherry picked from commit 2260e35df2a17b5483e3fef55b4ddc0f81fb31a3) --- .github/workflows/codeql-analysis.yml | 2 +- .github/workflows/docker-build.yml | 2 +- .github/workflows/gateway-conformance.yml | 4 +- .github/workflows/gobuild.yml | 2 +- .github/workflows/golang-analysis.yml | 2 +- .github/workflows/golint.yml | 2 +- .github/workflows/gotest.yml | 2 +- .github/workflows/interop.yml | 2 +- .github/workflows/sharness.yml | 2 +- Dockerfile | 2 +- core/commands/bitswap.go | 2 +- core/commands/files.go | 2 +- core/commands/name/ipnsps.go | 2 +- core/commands/name/name.go | 3 +- core/commands/refs.go | 2 +- core/commands/stat.go | 2 +- core/commands/swarm.go | 2 +- docs/examples/kubo-as-a-library/go.mod | 4 +- go.mod | 2 +- plugin/loader/loader.go | 3 +- test/dependencies/go.mod | 57 +++++------ test/dependencies/go.sum | 118 +++++++++++----------- 22 files changed, 107 insertions(+), 114 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index d0e082d65..8ed324854 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -34,7 +34,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: 1.22.x + go-version: 1.23.x # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml index 433240f42..e13a3f882 100644 --- a/.github/workflows/docker-build.yml +++ b/.github/workflows/docker-build.yml @@ -28,7 +28,7 @@ jobs: steps: - uses: actions/setup-go@v5 with: - go-version: 1.22.x + go-version: 1.23.x - uses: actions/checkout@v4 - run: docker build -t $IMAGE_NAME:$WIP_IMAGE_TAG . - run: docker run --rm $IMAGE_NAME:$WIP_IMAGE_TAG --version diff --git a/.github/workflows/gateway-conformance.yml b/.github/workflows/gateway-conformance.yml index b1791868c..d2f015900 100644 --- a/.github/workflows/gateway-conformance.yml +++ b/.github/workflows/gateway-conformance.yml @@ -49,7 +49,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: 1.22.x + go-version: 1.23.x - uses: protocol/cache-go-action@v1 with: name: ${{ github.job }} @@ -136,7 +136,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: 1.22.x + go-version: 1.23.x - uses: protocol/cache-go-action@v1 with: name: ${{ github.job }} diff --git a/.github/workflows/gobuild.yml b/.github/workflows/gobuild.yml index 93159eadd..5aebfd938 100644 --- a/.github/workflows/gobuild.yml +++ b/.github/workflows/gobuild.yml @@ -30,7 +30,7 @@ jobs: steps: - uses: actions/setup-go@v5 with: - go-version: 1.22.x + go-version: 1.23.x - uses: actions/checkout@v4 - run: make cmd/ipfs-try-build env: diff --git a/.github/workflows/golang-analysis.yml b/.github/workflows/golang-analysis.yml index e89034a92..36a5bba01 100644 --- a/.github/workflows/golang-analysis.yml +++ b/.github/workflows/golang-analysis.yml @@ -27,7 +27,7 @@ jobs: submodules: recursive - uses: actions/setup-go@v5 with: - go-version: "1.22.x" + go-version: "1.23.x" - name: Check that go.mod is tidy uses: protocol/multiple-go-modules@v1.4 with: diff --git a/.github/workflows/golint.yml b/.github/workflows/golint.yml index aa8b21b53..57b5d46dd 100644 --- a/.github/workflows/golint.yml +++ b/.github/workflows/golint.yml @@ -31,6 +31,6 @@ jobs: steps: - uses: actions/setup-go@v5 with: - go-version: 1.22.x + go-version: 1.23.x - uses: actions/checkout@v4 - run: make -O test_go_lint diff --git a/.github/workflows/gotest.yml b/.github/workflows/gotest.yml index 609791aba..f5225e8a3 100644 --- a/.github/workflows/gotest.yml +++ b/.github/workflows/gotest.yml @@ -32,7 +32,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v5 with: - go-version: 1.22.x + go-version: 1.23.x - name: Check out Kubo uses: actions/checkout@v4 - name: Install missing tools diff --git a/.github/workflows/interop.yml b/.github/workflows/interop.yml index 73ee25555..2e280a779 100644 --- a/.github/workflows/interop.yml +++ b/.github/workflows/interop.yml @@ -10,7 +10,7 @@ on: - 'master' env: - GO_VERSION: 1.22.x + GO_VERSION: 1.23.x concurrency: group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.event_name == 'push' && github.sha || github.ref }} diff --git a/.github/workflows/sharness.yml b/.github/workflows/sharness.yml index 6432745bf..af7fa896c 100644 --- a/.github/workflows/sharness.yml +++ b/.github/workflows/sharness.yml @@ -25,7 +25,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: 1.22.x + go-version: 1.23.x - name: Checkout Kubo uses: actions/checkout@v4 with: diff --git a/Dockerfile b/Dockerfile index 4ed07d3d4..e04b3c666 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM --platform=${BUILDPLATFORM:-linux/amd64} golang:1.22 AS builder +FROM --platform=${BUILDPLATFORM:-linux/amd64} golang:1.23 AS builder ARG TARGETOS TARGETARCH diff --git a/core/commands/bitswap.go b/core/commands/bitswap.go index 6502876d1..07f91fb0f 100644 --- a/core/commands/bitswap.go +++ b/core/commands/bitswap.go @@ -109,7 +109,7 @@ var bitswapStatCmd = &cmds.Command{ } if !nd.IsOnline { - return cmds.Errorf(cmds.ErrClient, ErrNotOnline.Error()) + return cmds.Errorf(cmds.ErrClient, "unable to run offline: %s", ErrNotOnline) } bs, ok := nd.Exchange.(*bitswap.Bitswap) diff --git a/core/commands/files.go b/core/commands/files.go index 6add671ce..d1a52cbfb 100644 --- a/core/commands/files.go +++ b/core/commands/files.go @@ -182,7 +182,7 @@ var filesStatCmd = &cmds.Command{ Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { _, err := statGetFormatOptions(req) if err != nil { - return cmds.Errorf(cmds.ErrClient, err.Error()) + return cmds.Errorf(cmds.ErrClient, "invalid parameters: %s", err) } node, err := cmdenv.GetNode(env) diff --git a/core/commands/name/ipnsps.go b/core/commands/name/ipnsps.go index f57173eea..e465549e0 100644 --- a/core/commands/name/ipnsps.go +++ b/core/commands/name/ipnsps.go @@ -135,7 +135,7 @@ var ipnspsCancelCmd = &cmds.Command{ name = strings.TrimPrefix(name, "/ipns/") pid, err := peer.Decode(name) if err != nil { - return cmds.Errorf(cmds.ErrClient, err.Error()) + return cmds.Errorf(cmds.ErrClient, "not a valid IPNS name: %s", err) } ok, err := n.PSRouter.Cancel("/ipns/" + string(pid)) diff --git a/core/commands/name/name.go b/core/commands/name/name.go index 9445fc362..912629d68 100644 --- a/core/commands/name/name.go +++ b/core/commands/name/name.go @@ -260,8 +260,7 @@ Passing --verify will verify signature against provided public key. if out.HexDump != "" { tw.Flush() - fmt.Fprintf(w, "\nHex Dump:\n") - fmt.Fprintf(w, out.HexDump) + fmt.Fprintf(w, "\nHex Dump:\n%s", out.HexDump) } return nil diff --git a/core/commands/refs.go b/core/commands/refs.go index cefd8af90..53c92c3df 100644 --- a/core/commands/refs.go +++ b/core/commands/refs.go @@ -21,7 +21,7 @@ import ( var refsEncoderMap = cmds.EncoderMap{ cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *RefWrapper) error { if out.Err != "" { - return fmt.Errorf(out.Err) + return errors.New(out.Err) } fmt.Fprintln(w, out.Ref) diff --git a/core/commands/stat.go b/core/commands/stat.go index a09c70ea1..4ceb95f13 100644 --- a/core/commands/stat.go +++ b/core/commands/stat.go @@ -96,7 +96,7 @@ Example: // Must be online! if !nd.IsOnline { - return cmds.Errorf(cmds.ErrClient, ErrNotOnline.Error()) + return cmds.Errorf(cmds.ErrClient, "unable to run offline: %s", ErrNotOnline) } if nd.Reporter == nil { diff --git a/core/commands/swarm.go b/core/commands/swarm.go index 4fe535ffc..252c48d33 100644 --- a/core/commands/swarm.go +++ b/core/commands/swarm.go @@ -557,7 +557,7 @@ var swarmAddrsCmd = &cmds.Command{ paddrs := am.Addrs[p] fmt.Fprintf(w, "%s (%d)\n", p, len(paddrs)) for _, addr := range paddrs { - fmt.Fprintf(w, "\t"+addr+"\n") + fmt.Fprintf(w, "\t%s\n", addr) } } diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 7dde64b20..e78e34d7d 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -1,8 +1,6 @@ module github.com/ipfs/kubo/examples/kubo-as-a-library -go 1.22 - -toolchain go1.22.0 +go 1.23 // Used to keep this in sync with the current version of kubo. You should remove // this if you copy this example. diff --git a/go.mod b/go.mod index f07715502..9031c1840 100644 --- a/go.mod +++ b/go.mod @@ -252,4 +252,4 @@ require ( lukechampine.com/blake3 v1.3.0 // indirect ) -go 1.22 +go 1.23 diff --git a/plugin/loader/loader.go b/plugin/loader/loader.go index 80cc9a1b6..4ea3ac226 100644 --- a/plugin/loader/loader.go +++ b/plugin/loader/loader.go @@ -2,6 +2,7 @@ package loader import ( "encoding/json" + "errors" "fmt" "io" "os" @@ -361,7 +362,7 @@ func (loader *PluginLoader) Close() error { } if errs != nil { loader.state = loaderFailed - return fmt.Errorf(strings.Join(errs, "\n")) + return errors.New(strings.Join(errs, "\n")) } loader.state = loaderClosed return nil diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 21d77ede2..8a9a4036a 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -1,14 +1,12 @@ module github.com/ipfs/kubo/test/dependencies -go 1.22 - -toolchain go1.22.0 +go 1.23 replace github.com/ipfs/kubo => ../../ require ( github.com/Kubuxu/gocovmerge v0.0.0-20161216165753-7ecaa51963cd - github.com/golangci/golangci-lint v1.59.1 + github.com/golangci/golangci-lint v1.60.2 github.com/ipfs/go-cidutil v0.1.0 github.com/ipfs/go-log v1.0.5 github.com/ipfs/hang-fds v0.1.0 @@ -28,9 +26,9 @@ require ( github.com/Abirdcfly/dupword v0.0.14 // indirect github.com/Antonboom/errname v0.1.13 // indirect github.com/Antonboom/nilnil v0.1.9 // indirect - github.com/Antonboom/testifylint v1.4.1 // indirect - github.com/BurntSushi/toml v1.4.0 // indirect - github.com/Crocmagnon/fatcontext v0.3.0 // indirect + github.com/Antonboom/testifylint v1.4.3 // indirect + github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c // indirect + github.com/Crocmagnon/fatcontext v0.4.0 // indirect github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 // indirect github.com/GaijinEntertainment/go-exhaustruct/v3 v3.3.0 // indirect github.com/Masterminds/semver/v3 v3.2.1 // indirect @@ -45,7 +43,7 @@ require ( github.com/bitfield/gotestdox v0.2.2 // indirect github.com/bkielbasa/cyclop v1.2.1 // indirect github.com/blizzy78/varnamelen v0.8.0 // indirect - github.com/bombsimon/wsl/v4 v4.4.0 // indirect + github.com/bombsimon/wsl/v4 v4.4.1 // indirect github.com/breml/bidichk v0.2.7 // indirect github.com/breml/errchkjson v0.3.6 // indirect github.com/butuzov/ireturn v0.3.0 // indirect @@ -56,7 +54,7 @@ require ( github.com/charithe/durationcheck v0.0.10 // indirect github.com/chavacava/garif v0.1.0 // indirect github.com/ckaznocha/intrange v0.1.2 // indirect - github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect github.com/curioswitch/go-reassign v0.2.0 // indirect github.com/daixiang0/gci v0.13.4 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect @@ -85,10 +83,10 @@ require ( github.com/go-viper/mapstructure/v2 v2.0.0 // indirect github.com/go-xmlfmt/xmlfmt v1.1.2 // indirect github.com/gobwas/glob v0.2.3 // indirect - github.com/gofrs/flock v0.8.1 // indirect + github.com/gofrs/flock v0.12.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a // indirect - github.com/golangci/gofmt v0.0.0-20231019111953-be8c47862aaa // indirect + github.com/golangci/gofmt v0.0.0-20240816233607-d8596aa466a9 // indirect github.com/golangci/misspell v0.6.0 // indirect github.com/golangci/modinfo v0.3.4 // indirect github.com/golangci/plugin-module-register v0.1.1 // indirect @@ -129,7 +127,7 @@ require ( github.com/jgautheron/goconst v1.7.1 // indirect github.com/jingyugao/rowserrcheck v1.1.1 // indirect github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af // indirect - github.com/jjti/go-spancheck v0.6.1 // indirect + github.com/jjti/go-spancheck v0.6.2 // indirect github.com/julz/importas v0.1.0 // indirect github.com/karamaru-alpha/copyloopvar v1.1.0 // indirect github.com/kisielk/errcheck v1.7.0 // indirect @@ -161,12 +159,12 @@ require ( github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-runewidth v0.0.15 // indirect - github.com/mgechev/revive v1.3.7 // indirect + github.com/mgechev/revive v1.3.9 // indirect github.com/miekg/dns v1.1.61 // indirect github.com/minio/sha256-simd v1.0.1 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect - github.com/moricho/tparallel v0.3.1 // indirect + github.com/moricho/tparallel v0.3.2 // indirect github.com/mr-tron/base58 v1.2.0 // indirect github.com/multiformats/go-base32 v0.1.0 // indirect github.com/multiformats/go-base36 v0.2.0 // indirect @@ -186,7 +184,7 @@ require ( github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/polydawn/refmt v0.89.0 // indirect - github.com/polyfloyd/go-errorlint v1.5.2 // indirect + github.com/polyfloyd/go-errorlint v1.6.0 // indirect github.com/prometheus/client_golang v1.19.1 // indirect github.com/prometheus/client_model v0.6.1 // indirect github.com/prometheus/common v0.55.0 // indirect @@ -198,7 +196,7 @@ require ( github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 // indirect github.com/rivo/uniseg v0.4.7 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect - github.com/ryancurrah/gomodguard v1.3.2 // indirect + github.com/ryancurrah/gomodguard v1.3.3 // indirect github.com/ryanrolds/sqlclosecheck v0.5.1 // indirect github.com/sagikazarmark/locafero v0.6.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect @@ -207,7 +205,7 @@ require ( github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 // indirect github.com/sashamelentyev/interfacebloat v1.1.0 // indirect github.com/sashamelentyev/usestdlibvars v1.27.0 // indirect - github.com/securego/gosec/v2 v2.20.1-0.20240525090044-5f0084eb01a9 // indirect + github.com/securego/gosec/v2 v2.20.1-0.20240820084340-81cda2f91fbe // indirect github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/sivchari/containedctx v1.0.3 // indirect @@ -218,7 +216,7 @@ require ( github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/spf13/afero v1.11.0 // indirect github.com/spf13/cast v1.6.0 // indirect - github.com/spf13/cobra v1.8.0 // indirect + github.com/spf13/cobra v1.8.1 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/spf13/viper v1.19.0 // indirect github.com/ssgreg/nlreturn/v2 v2.2.1 // indirect @@ -226,17 +224,16 @@ require ( github.com/stretchr/objx v0.5.2 // indirect github.com/stretchr/testify v1.9.0 // indirect github.com/subosito/gotenv v1.6.0 // indirect - github.com/t-yuki/gocover-cobertura v0.0.0-20180217150009-aaee18c8195c // indirect github.com/tdakkota/asciicheck v0.2.0 // indirect github.com/tetafro/godot v1.4.16 // indirect github.com/timakin/bodyclose v0.0.0-20240125160201-f835fa56326a // indirect github.com/timonwong/loggercheck v0.9.4 // indirect - github.com/tomarrell/wrapcheck/v2 v2.8.3 // indirect + github.com/tomarrell/wrapcheck/v2 v2.9.0 // indirect github.com/tommy-muehle/go-mnd/v2 v2.5.1 // indirect github.com/ultraware/funlen v0.1.0 // indirect github.com/ultraware/whitespace v0.1.1 // indirect github.com/urfave/cli v1.22.10 // indirect - github.com/uudashr/gocognit v1.1.2 // indirect + github.com/uudashr/gocognit v1.1.3 // indirect github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc // indirect github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect github.com/xen0n/gosmopolitan v1.2.2 // indirect @@ -245,7 +242,7 @@ require ( github.com/ykadowak/zerologlint v0.1.5 // indirect gitlab.com/bosi/decorder v0.4.2 // indirect go-simpler.org/musttag v0.12.2 // indirect - go-simpler.org/sloglint v0.7.1 // indirect + go-simpler.org/sloglint v0.7.2 // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/otel v1.28.0 // indirect go.opentelemetry.io/otel/metric v1.28.0 // indirect @@ -253,23 +250,23 @@ require ( go.uber.org/automaxprocs v1.5.3 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect - golang.org/x/crypto v0.25.0 // indirect + golang.org/x/crypto v0.26.0 // indirect golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect golang.org/x/exp/typeparams v0.0.0-20240613232115-7f521ea00fb8 // indirect - golang.org/x/mod v0.19.0 // indirect - golang.org/x/net v0.27.0 // indirect - golang.org/x/sync v0.7.0 // indirect + golang.org/x/mod v0.20.0 // indirect + golang.org/x/net v0.28.0 // indirect + golang.org/x/sync v0.8.0 // indirect golang.org/x/sys v0.24.0 // indirect golang.org/x/term v0.23.0 // indirect - golang.org/x/text v0.16.0 // indirect - golang.org/x/tools v0.23.0 // indirect + golang.org/x/text v0.17.0 // indirect + golang.org/x/tools v0.24.0 // indirect gonum.org/v1/gonum v0.15.0 // indirect google.golang.org/protobuf v1.34.2 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - honnef.co/go/tools v0.4.7 // indirect + honnef.co/go/tools v0.5.1 // indirect lukechampine.com/blake3 v1.3.0 // indirect - mvdan.cc/gofumpt v0.6.0 // indirect + mvdan.cc/gofumpt v0.7.0 // indirect mvdan.cc/unparam v0.0.0-20240528143540-8a5130ca722f // indirect ) diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 79c1f73e8..67dffd1ed 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -11,13 +11,13 @@ github.com/Antonboom/errname v0.1.13 h1:JHICqsewj/fNckzrfVSe+T33svwQxmjC+1ntDsHO github.com/Antonboom/errname v0.1.13/go.mod h1:uWyefRYRN54lBg6HseYCFhs6Qjcy41Y3Jl/dVhA87Ns= github.com/Antonboom/nilnil v0.1.9 h1:eKFMejSxPSA9eLSensFmjW2XTgTwJMjZ8hUHtV4s/SQ= github.com/Antonboom/nilnil v0.1.9/go.mod h1:iGe2rYwCq5/Me1khrysB4nwI7swQvjclR8/YRPl5ihQ= -github.com/Antonboom/testifylint v1.4.1 h1:LeBVoSeqCgJoHqwu46yzm7Zgcm6T7QhDYfT9VtFIRpg= -github.com/Antonboom/testifylint v1.4.1/go.mod h1:+8Q9+AOLsz5ZiQiiYujJKs9mNz398+M6UgslP4qgJLA= +github.com/Antonboom/testifylint v1.4.3 h1:ohMt6AHuHgttaQ1xb6SSnxCeK4/rnK7KKzbvs7DmEck= +github.com/Antonboom/testifylint v1.4.3/go.mod h1:+8Q9+AOLsz5ZiQiiYujJKs9mNz398+M6UgslP4qgJLA= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0= -github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= -github.com/Crocmagnon/fatcontext v0.3.0 h1:S6gNUYNSN9V76Tu017OFgoaOpybmMhwe6Ewh1cYd0jg= -github.com/Crocmagnon/fatcontext v0.3.0/go.mod h1:x3F9YW5CFE7vo+FGA5GzBD1SBXU4FQI0+y1ReG4Q+pY= +github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c h1:pxW6RcqyfI9/kWtOwnv/G+AzdKuy2ZrqINhenH4HyNs= +github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= +github.com/Crocmagnon/fatcontext v0.4.0 h1:4ykozu23YHA0JB6+thiuEv7iT6xq995qS1vcuWZq0tg= +github.com/Crocmagnon/fatcontext v0.4.0/go.mod h1:ZtWrXkgyfsYPzS6K3O88va6t2GEglG93vnII/F94WC0= github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 h1:sHglBQTwgx+rWPdisA5ynNEsoARbiCBOyGcJM4/OzsM= github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs= github.com/GaijinEntertainment/go-exhaustruct/v3 v3.3.0 h1:/fTUt5vmbkAcMBt4YQiuC23cV0kEsN1MVMNqeOW43cU= @@ -55,8 +55,8 @@ github.com/bkielbasa/cyclop v1.2.1 h1:AeF71HZDob1P2/pRm1so9cd1alZnrpyc4q2uP2l0gJ github.com/bkielbasa/cyclop v1.2.1/go.mod h1:K/dT/M0FPAiYjBgQGau7tz+3TMh4FWAEqlMhzFWCrgM= github.com/blizzy78/varnamelen v0.8.0 h1:oqSblyuQvFsW1hbBHh1zfwrKe3kcSj0rnXkKzsQ089M= github.com/blizzy78/varnamelen v0.8.0/go.mod h1:V9TzQZ4fLJ1DSrjVDfl89H7aMnTvKkApdHeyESmyR7k= -github.com/bombsimon/wsl/v4 v4.4.0 h1:1FHD09Li8Okn1/iERsSOo+0pXZZpVuw0XUz5/a+4+UQ= -github.com/bombsimon/wsl/v4 v4.4.0/go.mod h1:Xu/kDxGZTofQcDGCtQe9KCzhHphIe0fDuyWTxER9Feo= +github.com/bombsimon/wsl/v4 v4.4.1 h1:jfUaCkN+aUpobrMO24zwyAMwMAV5eSziCkOKEauOLdw= +github.com/bombsimon/wsl/v4 v4.4.1/go.mod h1:Xu/kDxGZTofQcDGCtQe9KCzhHphIe0fDuyWTxER9Feo= github.com/breml/bidichk v0.2.7 h1:dAkKQPLl/Qrk7hnP6P+E0xOodrq8Us7+U0o4UBOAlQY= github.com/breml/bidichk v0.2.7/go.mod h1:YodjipAGI9fGcYM7II6wFvGhdMYsC5pHDlGzqvEW3tQ= github.com/breml/errchkjson v0.3.6 h1:VLhVkqSBH96AvXEyclMR37rZslRrY2kcyq+31HCsVrA= @@ -85,8 +85,8 @@ github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHq github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= 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.3 h1:qMCsGGgs+MAzDFyp9LpAe1Lqy/fY/qCovCm0qnXZOBM= -github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4= +github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/cskr/pubsub v1.0.2 h1:vlOzMhl6PFn60gRlTQQsIfVwaPB/B/8MziK8FhEPt/0= github.com/cskr/pubsub v1.0.2/go.mod h1:/8MzYXk/NJAz782G8RPkFzXTZVu63VotefPnR9TIRis= github.com/curioswitch/go-reassign v0.2.0 h1:G9UZyOcpk/d7Gd6mqYgd8XYWFMw/znxwGDUstnC9DIo= @@ -148,6 +148,8 @@ github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-quicktest/qt v1.101.0 h1:O1K29Txy5P2OK0dGo59b7b0LR6wKfIhttaAhHUyn7eI= +github.com/go-quicktest/qt v1.101.0/go.mod h1:14Bz/f7NwaXPtdYEgzsx46kqSxVwTbzVZsDC26tQJow= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/go-toolsmith/astcast v1.1.0 h1:+JN9xZV1A+Re+95pgnMgDboWNVnIMMQXwfBwLRPgSC8= @@ -178,8 +180,8 @@ github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= -github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= +github.com/gofrs/flock v0.12.1 h1:MTLVXXHf8ekldpJk3AKicLij9MdwOWkZ+a/jHHZby9E= +github.com/gofrs/flock v0.12.1/go.mod h1:9zxTsyu5xtJ9DK+1tFZyibEV7y3uwDxPPfbxeeHCoD0= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= @@ -198,10 +200,10 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a h1:w8hkcTqaFpzKqonE9uMCefW1WDie15eSP/4MssdenaM= github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a/go.mod h1:ryS0uhF+x9jgbj/N71xsEqODy9BN81/GonCZiOzirOk= -github.com/golangci/gofmt v0.0.0-20231019111953-be8c47862aaa h1:L0Zq43Px2HrLroRKEgfCsQLMJUkjskJBB1kd1Zjcvvc= -github.com/golangci/gofmt v0.0.0-20231019111953-be8c47862aaa/go.mod h1:Pm5KhLPA8gSnQwrQ6ukebRcapGb/BG9iUkdaiCcGHJM= -github.com/golangci/golangci-lint v1.59.1 h1:CRRLu1JbhK5avLABFJ/OHVSQ0Ie5c4ulsOId1h3TTks= -github.com/golangci/golangci-lint v1.59.1/go.mod h1:jX5Oif4C7P0j9++YB2MMJmoNrb01NJ8ITqKWNLewThg= +github.com/golangci/gofmt v0.0.0-20240816233607-d8596aa466a9 h1:/1322Qns6BtQxUZDTAT4SdcoxknUki7IAoK4SAXr8ME= +github.com/golangci/gofmt v0.0.0-20240816233607-d8596aa466a9/go.mod h1:Oesb/0uFAyWoaw1U1qS5zyjCg5NP9C9iwjnI4tIsXEE= +github.com/golangci/golangci-lint v1.60.2 h1:Y8aWnZCMOLY5T7Ga5hcoemyKsZZJCUmIIK3xTD3jIhc= +github.com/golangci/golangci-lint v1.60.2/go.mod h1:4UvjLpOJoQSvmyWkmO1urDR3txhL9R9sn4oM/evJ95g= github.com/golangci/misspell v0.6.0 h1:JCle2HUTNWirNlDIAUO44hUsKhOFqGPoC4LZxlaSXDs= github.com/golangci/misspell v0.6.0/go.mod h1:keMNyY6R9isGaSAu+4Q8NMBwMPkh15Gtc8UCVoDtAWo= github.com/golangci/modinfo v0.3.4 h1:oU5huX3fbxqQXdfspamej74DFX0kyGLkw1ppvXoJ8GA= @@ -339,8 +341,8 @@ github.com/jingyugao/rowserrcheck v1.1.1 h1:zibz55j/MJtLsjP1OF4bSdgXxwL1b+Vn7Tjz github.com/jingyugao/rowserrcheck v1.1.1/go.mod h1:4yvlZSDb3IyDTUZJUmpZfm2Hwok+Dtp+nu2qOq+er9c= github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af h1:KA9BjwUk7KlCh6S9EAGWBt1oExIUv9WyNCiRz5amv48= github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af/go.mod h1:HEWGJkRDzjJY2sqdDwxccsGicWEf9BQOZsq2tV+xzM0= -github.com/jjti/go-spancheck v0.6.1 h1:ZK/wE5Kyi1VX3PJpUO2oEgeoI4FWOUm7Shb2Gbv5obI= -github.com/jjti/go-spancheck v0.6.1/go.mod h1:vF1QkOO159prdo6mHRxak2CpzDpHAfKiPUDP/NeRnX8= +github.com/jjti/go-spancheck v0.6.2 h1:iYtoxqPMzHUPp7St+5yA8+cONdyXD3ug6KK15n7Pklk= +github.com/jjti/go-spancheck v0.6.2/go.mod h1:+X7lvIrR5ZdUTkxFYqzJ0abr8Sb5LOo80uOhWNqIrYA= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julz/importas v0.1.0 h1:F78HnrsjY3cR7j0etXy5+TU1Zuy7Xt08X/1aJnH5xXY= @@ -437,8 +439,8 @@ github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/mgechev/revive v1.3.7 h1:502QY0vQGe9KtYJ9FpxMz9rL+Fc/P13CI5POL4uHCcE= -github.com/mgechev/revive v1.3.7/go.mod h1:RJ16jUbF0OWC3co/+XTxmFNgEpUPwnnA0BRllX2aDNA= +github.com/mgechev/revive v1.3.9 h1:18Y3R4a2USSBF+QZKFQwVkBROUda7uoBlkEuBD+YD1A= +github.com/mgechev/revive v1.3.9/go.mod h1:+uxEIr5UH0TjXWHTno3xh4u7eg6jDpXKzQccA9UGhHU= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= github.com/miekg/dns v1.1.61 h1:nLxbwF3XxhwVSm8g9Dghm9MHPaUZuqhPiGL+675ZmEs= github.com/miekg/dns v1.1.61/go.mod h1:mnAarhS3nWaW+NVP2wTkYVIZyHNJ098SJZUki3eykwQ= @@ -454,8 +456,8 @@ github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/moricho/tparallel v0.3.1 h1:fQKD4U1wRMAYNngDonW5XupoB/ZGJHdpzrWqgyg9krA= -github.com/moricho/tparallel v0.3.1/go.mod h1:leENX2cUv7Sv2qDgdi0D0fCftN8fRC67Bcn8pqzeYNI= +github.com/moricho/tparallel v0.3.2 h1:odr8aZVFA3NZrNybggMkYO3rgPRcqjeQUlBBFVxKHTI= +github.com/moricho/tparallel v0.3.2/go.mod h1:OQ+K3b4Ln3l2TZveGCywybl68glfLEwFGqvnjok8b+U= github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= @@ -494,10 +496,10 @@ github.com/nunnatsa/ginkgolinter v0.16.2 h1:8iLqHIZvN4fTLDC0Ke9tbSZVcyVHoBs0HIbn github.com/nunnatsa/ginkgolinter v0.16.2/go.mod h1:4tWRinDN1FeJgU+iJANW/kz7xKN5nYRAOfJDQUS9dOQ= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= -github.com/onsi/ginkgo/v2 v2.19.1 h1:QXgq3Z8Crl5EL1WBAC98A5sEBHARrAJNzAmMxzLcRF0= -github.com/onsi/ginkgo/v2 v2.19.1/go.mod h1:O3DtEWQkPa/F7fBMgmZQKKsluAy8pd3rEQdrjkPb9zA= -github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk= -github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0= +github.com/onsi/ginkgo/v2 v2.20.0 h1:PE84V2mHqoT1sglvHc8ZdQtPcwmvvt29WLEEO3xmdZw= +github.com/onsi/ginkgo/v2 v2.20.0/go.mod h1:lG9ey2Z29hR41WMVthyJBGUBcBhGOtoPF2VFMvBXFCI= +github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k= +github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY= github.com/opencontainers/runtime-spec v1.2.0 h1:z97+pHb3uELt/yiAWD691HNHQIF07bE7dzrbT927iTk= github.com/opencontainers/runtime-spec v1.2.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= @@ -553,8 +555,8 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/polydawn/refmt v0.89.0 h1:ADJTApkvkeBZsN0tBTx8QjpD9JkmxbKp0cxfr9qszm4= github.com/polydawn/refmt v0.89.0/go.mod h1:/zvteZs/GwLtCgZ4BL6CBsk9IKIlexP43ObX9AxTqTw= -github.com/polyfloyd/go-errorlint v1.5.2 h1:SJhVik3Umsjh7mte1vE0fVZ5T1gznasQG3PV7U5xFdA= -github.com/polyfloyd/go-errorlint v1.5.2/go.mod h1:sH1QC1pxxi0fFecsVIzBmxtrgd9IF/SkJpA6wqyKAJs= +github.com/polyfloyd/go-errorlint v1.6.0 h1:tftWV9DE7txiFzPpztTAwyoRLKNj9gpVm2cg8/OwcYY= +github.com/polyfloyd/go-errorlint v1.6.0/go.mod h1:HR7u8wuP1kb1NeN1zqTd1ZMlqUKPPHF+Id4vIPvDqVw= github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g= github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U= github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE= @@ -594,8 +596,8 @@ github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99 github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/ryancurrah/gomodguard v1.3.2 h1:CuG27ulzEB1Gu5Dk5gP8PFxSOZ3ptSdP5iI/3IXxM18= -github.com/ryancurrah/gomodguard v1.3.2/go.mod h1:LqdemiFomEjcxOqirbQCb3JFvSxH2JUYMerTFd3sF2o= +github.com/ryancurrah/gomodguard v1.3.3 h1:eiSQdJVNr9KTNxY2Niij8UReSwR8Xrte3exBrAZfqpg= +github.com/ryancurrah/gomodguard v1.3.3/go.mod h1:rsKQjj4l3LXe8N344Ow7agAy5p9yjsWOtRzUMYmA0QY= github.com/ryanrolds/sqlclosecheck v0.5.1 h1:dibWW826u0P8jNLsLN+En7+RqWWTYrjCB9fJfSfdyCU= github.com/ryanrolds/sqlclosecheck v0.5.1/go.mod h1:2g3dUjoS6AL4huFdv6wn55WpLIDjY7ZgUR4J8HOO/XQ= github.com/sagikazarmark/locafero v0.6.0 h1:ON7AQg37yzcRPU69mt7gwhFEBwxI6P9T4Qu3N51bwOk= @@ -612,8 +614,8 @@ github.com/sashamelentyev/interfacebloat v1.1.0 h1:xdRdJp0irL086OyW1H/RTZTr1h/tM github.com/sashamelentyev/interfacebloat v1.1.0/go.mod h1:+Y9yU5YdTkrNvoX0xHc84dxiN1iBi9+G8zZIhPVoNjQ= github.com/sashamelentyev/usestdlibvars v1.27.0 h1:t/3jZpSXtRPRf2xr0m63i32ZrusyurIGT9E5wAvXQnI= github.com/sashamelentyev/usestdlibvars v1.27.0/go.mod h1:9nl0jgOfHKWNFS43Ojw0i7aRoS4j6EBye3YBhmAIRF8= -github.com/securego/gosec/v2 v2.20.1-0.20240525090044-5f0084eb01a9 h1:rnO6Zp1YMQwv8AyxzuwsVohljJgp4L0ZqiCgtACsPsc= -github.com/securego/gosec/v2 v2.20.1-0.20240525090044-5f0084eb01a9/go.mod h1:dg7lPlu/xK/Ut9SedURCoZbVCR4yC7fM65DtH9/CDHs= +github.com/securego/gosec/v2 v2.20.1-0.20240820084340-81cda2f91fbe h1:exdneYmXwZ4+VaIWv9mQ47uIHkTQSN50DYdCjXJ1cdQ= +github.com/securego/gosec/v2 v2.20.1-0.20240820084340-81cda2f91fbe/go.mod h1:iyeMMRw8QEmueUSZ2VqmkQMiDyDcobfPnG00CV/NWdE= github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c h1:W65qqJCIOVP4jpqPQ0YvHYKwcMEMVWIzWC5iNQQfBTU= github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c/go.mod h1:/PevMnwAxekIXwN8qQyfc5gl2NlkB3CQlkizAbOkeBs= github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= @@ -641,8 +643,8 @@ github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= -github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= -github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= +github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= +github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI= @@ -668,8 +670,6 @@ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsT github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= -github.com/t-yuki/gocover-cobertura v0.0.0-20180217150009-aaee18c8195c h1:+aPplBwWcHBo6q9xrfWdMrT9o4kltkmmvpemgIjep/8= -github.com/t-yuki/gocover-cobertura v0.0.0-20180217150009-aaee18c8195c/go.mod h1:SbErYREK7xXdsRiigaQiQkI9McGRzYMvlKYaP3Nimdk= github.com/tdakkota/asciicheck v0.2.0 h1:o8jvnUANo0qXtnslk2d3nMKTFNlOnJjRrNcj0j9qkHM= github.com/tdakkota/asciicheck v0.2.0/go.mod h1:Qb7Y9EgjCLJGup51gDHFzbI08/gbGhL/UVhYIPWG2rg= github.com/tenntenn/modver v1.0.1 h1:2klLppGhDgzJrScMpkj9Ujy3rXPUspSjAcev9tSEBgA= @@ -682,8 +682,8 @@ github.com/timakin/bodyclose v0.0.0-20240125160201-f835fa56326a h1:A6uKudFIfAEpo github.com/timakin/bodyclose v0.0.0-20240125160201-f835fa56326a/go.mod h1:mkjARE7Yr8qU23YcGMSALbIxTQ9r9QBVahQOBRfU460= github.com/timonwong/loggercheck v0.9.4 h1:HKKhqrjcVj8sxL7K77beXh0adEm6DLjV/QOGeMXEVi4= github.com/timonwong/loggercheck v0.9.4/go.mod h1:caz4zlPcgvpEkXgVnAJGowHAMW2NwHaNlpS8xDbVhTg= -github.com/tomarrell/wrapcheck/v2 v2.8.3 h1:5ov+Cbhlgi7s/a42BprYoxsr73CbdMUTzE3bRDFASUs= -github.com/tomarrell/wrapcheck/v2 v2.8.3/go.mod h1:g9vNIyhb5/9TQgumxQyOEqDHsmGYcGsVMOx/xGkqdMo= +github.com/tomarrell/wrapcheck/v2 v2.9.0 h1:801U2YCAjLhdN8zhZ/7tdjB3EnAoRlJHt/s+9hijLQ4= +github.com/tomarrell/wrapcheck/v2 v2.9.0/go.mod h1:g9vNIyhb5/9TQgumxQyOEqDHsmGYcGsVMOx/xGkqdMo= github.com/tommy-muehle/go-mnd/v2 v2.5.1 h1:NowYhSdyE/1zwK9QCLeRb6USWdoif80Ie+v+yU8u1Zw= github.com/tommy-muehle/go-mnd/v2 v2.5.1/go.mod h1:WsUAkMJMYww6l/ufffCD3m+P7LEvr8TnZn9lwVDlgzw= github.com/ultraware/funlen v0.1.0 h1:BuqclbkY6pO+cvxoq7OsktIXZpgBSkYTQtmwhAK81vI= @@ -693,8 +693,8 @@ github.com/ultraware/whitespace v0.1.1/go.mod h1:XcP1RLD81eV4BW8UhQlpaR+SDc2givT github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.10 h1:p8Fspmz3iTctJstry1PYS3HVdllxnEzTEsgIgtxTrCk= github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/uudashr/gocognit v1.1.2 h1:l6BAEKJqQH2UpKAPKdMfZf5kE4W/2xk8pfU1OVLvniI= -github.com/uudashr/gocognit v1.1.2/go.mod h1:aAVdLURqcanke8h3vg35BC++eseDm66Z7KmchI5et4k= +github.com/uudashr/gocognit v1.1.3 h1:l+a111VcDbKfynh+airAy/DJQKaXh2m9vkoysMPSZyM= +github.com/uudashr/gocognit v1.1.3/go.mod h1:aKH8/e8xbTRBwjbCkwZ8qt4l2EpKXl31KMHgSS+lZ2U= github.com/warpfork/go-testmark v0.12.1 h1:rMgCpJfwy1sJ50x0M0NgyphxYYPMOODIJHhsXyEHU0s= github.com/warpfork/go-testmark v0.12.1/go.mod h1:kHwy7wfvGSPh1rQJYKayD4AbtNaeyZdcGi9tNJTaa5Y= github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0 h1:GDDkbFiaK8jsSDJfjId/PEGEShv6ugrt4kYsC5UIDaQ= @@ -726,8 +726,8 @@ go-simpler.org/assert v0.9.0 h1:PfpmcSvL7yAnWyChSjOz6Sp6m9j5lyK8Ok9pEL31YkQ= go-simpler.org/assert v0.9.0/go.mod h1:74Eqh5eI6vCK6Y5l3PI8ZYFXG4Sa+tkr70OIPJAUr28= go-simpler.org/musttag v0.12.2 h1:J7lRc2ysXOq7eM8rwaTYnNrHd5JwjppzB6mScysB2Cs= go-simpler.org/musttag v0.12.2/go.mod h1:uN1DVIasMTQKk6XSik7yrJoEysGtR2GRqvWnI9S7TYM= -go-simpler.org/sloglint v0.7.1 h1:qlGLiqHbN5islOxjeLXoPtUdZXb669RW+BDQ+xOSNoU= -go-simpler.org/sloglint v0.7.1/go.mod h1:OlaVDRh/FKKd4X4sIMbsz8st97vomydceL146Fthh/c= +go-simpler.org/sloglint v0.7.2 h1:Wc9Em/Zeuu7JYpl+oKoYOsQSy2X560aVueCW/m6IijY= +go-simpler.org/sloglint v0.7.2/go.mod h1:US+9C80ppl7VsThQclkM7BkCHQAzuz8kHLsW3ppuluo= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= @@ -770,8 +770,8 @@ golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliY golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= @@ -801,8 +801,8 @@ golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.16.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= -golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -827,8 +827,8 @@ golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/net v0.16.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -842,8 +842,8 @@ golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -861,7 +861,6 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211105183446-c75c47738b0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220702020025-31831981b65f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -906,8 +905,8 @@ golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= @@ -935,7 +934,6 @@ golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= -golang.org/x/tools v0.1.11/go.mod h1:SgwaegtQh8clINPpECJMqnxLv9I09HLqnW3RMqW0CA4= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= @@ -945,8 +943,8 @@ golang.org/x/tools v0.11.0/go.mod h1:anzJrxPjNtfgiYQYirP2CPGzGLxrH2u2QBhn6Bf3qY8 golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= golang.org/x/tools v0.19.0/go.mod h1:qoJWxmGSIBmAeriMx19ogtrEPrGtDbPK634QFIcLAhc= -golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= -golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -996,11 +994,11 @@ gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -honnef.co/go/tools v0.4.7 h1:9MDAWxMoSnB6QoSqiVr7P5mtkT9pOc1kSxchzPCnqJs= -honnef.co/go/tools v0.4.7/go.mod h1:+rnGS1THNh8zMwnd2oVOTL9QF6vmfyG6ZXBULae2uc0= +honnef.co/go/tools v0.5.1 h1:4bH5o3b5ZULQ4UrBmP+63W9r7qIkqJClEA9ko5YKx+I= +honnef.co/go/tools v0.5.1/go.mod h1:e9irvo83WDG9/irijV44wr3tbhcFeRnfpVlRqVwpzMs= lukechampine.com/blake3 v1.3.0 h1:sJ3XhFINmHSrYCgl958hscfIa3bw8x4DqMP3u1YvoYE= lukechampine.com/blake3 v1.3.0/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= -mvdan.cc/gofumpt v0.6.0 h1:G3QvahNDmpD+Aek/bNOLrFR2XC6ZAdo62dZu65gmwGo= -mvdan.cc/gofumpt v0.6.0/go.mod h1:4L0wf+kgIPZtcCWXynNS2e6bhmj73umwnuXSZarixzA= +mvdan.cc/gofumpt v0.7.0 h1:bg91ttqXmi9y2xawvkuMXyvAA/1ZGJqYAEGjXuP0JXU= +mvdan.cc/gofumpt v0.7.0/go.mod h1:txVFJy/Sc/mvaycET54pV8SW8gWxTlUuGHVEcncmNUo= mvdan.cc/unparam v0.0.0-20240528143540-8a5130ca722f h1:lMpcwN6GxNbWtbpI1+xzFLSW8XzX0u72NttUGVFjO3U= mvdan.cc/unparam v0.0.0-20240528143540-8a5130ca722f/go.mod h1:RSLa7mKKCNeTTMHBw5Hsy2rfJmd6O2ivt9Dw9ZqCQpQ= From 3bb09f89a10785825e3a78c7fcd19da4261de8d0 Mon Sep 17 00:00:00 2001 From: Andrew Gillis <11790789+gammazero@users.noreply.github.com> Date: Wed, 28 Aug 2024 10:03:26 -0700 Subject: [PATCH 1145/1212] fix(cli): preserve hostname specified with --api in http request headers (#10497) Preserve hostname specified with --api in http request headers - Replaces PR #10233 - Add test to check for hostname in HTTP header - Update docs/changelogs/v0.30.md (cherry picked from commit 5fe960474c4af2c7935839f5e3130dce45af8b63) --- cmd/ipfs/kubo/start.go | 5 ++++- docs/changelogs/v0.30.md | 5 +++++ test/sharness/t0235-cli-request.sh | 6 +++++- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/cmd/ipfs/kubo/start.go b/cmd/ipfs/kubo/start.go index cae1e2c1b..474045e71 100644 --- a/cmd/ipfs/kubo/start.go +++ b/cmd/ipfs/kubo/start.go @@ -303,7 +303,10 @@ func makeExecutor(req *cmds.Request, env interface{}) (cmds.Executor, error) { } // Resolve the API addr. - apiAddr, err = resolveAddr(req.Context, apiAddr) + // + // Do not replace apiAddr with the resolved addr so that the requested + // hostname is kept for use in the request's HTTP header. + _, err = resolveAddr(req.Context, apiAddr) if err != nil { return nil, err } diff --git a/docs/changelogs/v0.30.md b/docs/changelogs/v0.30.md index 6cc212f7a..d73860971 100644 --- a/docs/changelogs/v0.30.md +++ b/docs/changelogs/v0.30.md @@ -13,6 +13,7 @@ - [`/unix/` socket support in `Addresses.API`](#unix-socket-support-in-addressesapi) - [Cleaned Up `ipfs daemon` Startup Log](#cleaned-up-ipfs-daemon-startup-log) - [UnixFS 1.5: Mode and Modification Time Support](#unixfs-15-mode-and-modification-time-support) + - [Commands Preserve Specified Hostname](#commands-preserve-specified-hostname) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -128,6 +129,10 @@ Opt-in support for `mode` and `mtime` was also added to MFS (`ipfs files --help` > [!NOTE] > Storing `mode` and `mtime` requires root block to be `dag-pb` and disabled `raw-leaves` setting to create envelope for storing the metadata. +#### Commands Preserve Specified Hostname + +When executing a [CLI command](https://docs.ipfs.tech/reference/kubo/cli/) over [Kubo RPC API](https://docs.ipfs.tech/reference/kubo/rpc/), if a hostname is specified by `--api=/dns4//` the resulting HTTP request now contains the hostname, instead of the the IP address that the hostname resolved to, as was the previous behavior. This makes it easier for those trying to run Kubo behind a reverse proxy using hostname-based rules. + ### 📝 Changelog ### 👨‍👩‍👧‍👦 Contributors diff --git a/test/sharness/t0235-cli-request.sh b/test/sharness/t0235-cli-request.sh index 3b2281894..02ef514de 100755 --- a/test/sharness/t0235-cli-request.sh +++ b/test/sharness/t0235-cli-request.sh @@ -28,7 +28,7 @@ test_expect_success "start nc" ' ' test_expect_success "can make http request against nc server" ' - ipfs cat /ipfs/Qmabcdef --api /ip4/127.0.0.1/tcp/5005 & + ipfs cat /ipfs/Qmabcdef --api /dns4/localhost/tcp/5005 & IPFSPID=$! # handle request for /api/v0/version @@ -80,4 +80,8 @@ test_expect_success "api flag does not appear in request" ' test_expect_code 1 grep "api=/ip4" nc_out ' +test_expect_success "host has dns name not ip address" ' + grep "Host: localhost:5005" nc_out +' + test_done From 467fc69e91f24d19a99f42894ae3756ca954fa8a Mon Sep 17 00:00:00 2001 From: Andrew Gillis <11790789+gammazero@users.noreply.github.com> Date: Tue, 27 Aug 2024 17:41:45 -0700 Subject: [PATCH 1146/1212] chore: update go-unixfsnode, cmds, and boxo (#10494) * Update go-unixfsnode dependency * Update go-ipfs-cmds * chore: boxo@main with boxo#659 --------- Co-authored-by: Marcin Rataj (cherry picked from commit add45cf34c0f38d56570b4446ab33b7dddfec72e) --- docs/changelogs/v0.30.md | 1 + docs/examples/kubo-as-a-library/go.mod | 4 ++-- docs/examples/kubo-as-a-library/go.sum | 10 ++++------ go.mod | 7 +++---- go.sum | 16 ++++++---------- test/dependencies/go.mod | 2 +- test/dependencies/go.sum | 4 ++-- 7 files changed, 19 insertions(+), 25 deletions(-) diff --git a/docs/changelogs/v0.30.md b/docs/changelogs/v0.30.md index d73860971..4c22e40ba 100644 --- a/docs/changelogs/v0.30.md +++ b/docs/changelogs/v0.30.md @@ -125,6 +125,7 @@ The CLI and HTTP RPC options `--mode`, `--mtime` and `--mtime-nsecs` can be used Opt-in support for `mode` and `mtime` was also added to MFS (`ipfs files --help`). For more information see `--help` text of `ipfs files touch|stat|chmod` commands. +Modification time support was also added to the Gateway. If present, value from file's dag-pb is returned in `Last-Modified` HTTP header and requests made with `If-Modified-Since` can produce HTTP 304 not modified response. > [!NOTE] > Storing `mode` and `mtime` requires root block to be `dag-pb` and disabled `raw-leaves` setting to create envelope for storing the metadata. diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index e78e34d7d..49010af31 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.23 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.22.1-0.20240821001902-3cd3857b046c + github.com/ipfs/boxo v0.22.1-0.20240828000743-08f200aa8eef github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.36.2 github.com/multiformats/go-multiaddr v0.13.0 @@ -91,7 +91,7 @@ require ( github.com/ipfs/go-merkledag v0.11.0 // indirect github.com/ipfs/go-metrics-interface v0.0.1 // indirect github.com/ipfs/go-peertaskqueue v0.8.1 // indirect - github.com/ipfs/go-unixfsnode v1.9.0 // indirect + github.com/ipfs/go-unixfsnode v1.9.1 // indirect github.com/ipfs/go-verifcid v0.0.3 // indirect github.com/ipld/go-car v0.6.2 // indirect github.com/ipld/go-car/v2 v2.13.1 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 0b736aaf4..05e7f6903 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -266,8 +266,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.22.1-0.20240821001902-3cd3857b046c h1:vJb5RbEzIvTFnrxN1+AdQZLu1+ky4oWyx6ARnmtWYXU= -github.com/ipfs/boxo v0.22.1-0.20240821001902-3cd3857b046c/go.mod h1:bMB1tnSTr+6/CS5p3jkS4rtifpl+ul6P4ZgeTZn8Ty0= +github.com/ipfs/boxo v0.22.1-0.20240828000743-08f200aa8eef h1:ozMkCGYQmIkMnZwo4zPgrkkVFJvhBPnb3HhEswJoiG8= +github.com/ipfs/boxo v0.22.1-0.20240828000743-08f200aa8eef/go.mod h1:bMB1tnSTr+6/CS5p3jkS4rtifpl+ul6P4ZgeTZn8Ty0= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= @@ -307,8 +307,6 @@ github.com/ipfs/go-ipfs-blockstore v1.3.1 h1:cEI9ci7V0sRNivqaOr0elDsamxXFxJMMMy7 github.com/ipfs/go-ipfs-blockstore v1.3.1/go.mod h1:KgtZyc9fq+P2xJUiCAzbRdhhqJHvsw8u2Dlqy2MyRTE= github.com/ipfs/go-ipfs-blocksutil v0.0.1 h1:Eh/H4pc1hsvhzsQoMEP3Bke/aW5P5rVM1IWFJMcGIPQ= github.com/ipfs/go-ipfs-blocksutil v0.0.1/go.mod h1:Yq4M86uIOmxmGPUHv/uI7uKqZNtLb449gwKqXjIsnRk= -github.com/ipfs/go-ipfs-chunker v0.0.5 h1:ojCf7HV/m+uS2vhUGWcogIIxiO5ubl5O57Q7NapWLY8= -github.com/ipfs/go-ipfs-chunker v0.0.5/go.mod h1:jhgdF8vxRHycr00k13FM8Y0E+6BoalYeobXmUyTreP8= github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= github.com/ipfs/go-ipfs-delay v0.0.1 h1:r/UXYyRcddO6thwOnhiznIAiSvxMECGgtv35Xs1IeRQ= github.com/ipfs/go-ipfs-delay v0.0.1/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= @@ -356,8 +354,8 @@ github.com/ipfs/go-test v0.0.4 h1:DKT66T6GBB6PsDFLoO56QZPrOmzJkqU1FZH5C9ySkew= github.com/ipfs/go-test v0.0.4/go.mod h1:qhIM1EluEfElKKM6fnWxGn822/z9knUGM1+I/OAQNKI= github.com/ipfs/go-unixfs v0.4.5 h1:wj8JhxvV1G6CD7swACwSKYa+NgtdWC1RUit+gFnymDU= github.com/ipfs/go-unixfs v0.4.5/go.mod h1:BIznJNvt/gEx/ooRMI4Us9K8+qeGO7vx1ohnbk8gjFg= -github.com/ipfs/go-unixfsnode v1.9.0 h1:ubEhQhr22sPAKO2DNsyVBW7YB/zA8Zkif25aBvz8rc8= -github.com/ipfs/go-unixfsnode v1.9.0/go.mod h1:HxRu9HYHOjK6HUqFBAi++7DVoWAHn0o4v/nZ/VA+0g8= +github.com/ipfs/go-unixfsnode v1.9.1 h1:2cdSIDQCt7emNhlyUqUFQnKo2XvecARoIcurIKFjPD8= +github.com/ipfs/go-unixfsnode v1.9.1/go.mod h1:u8WxhmXzyrq3xfSYkhfx+uI+n91O+0L7KFjq3TS7d6g= github.com/ipfs/go-verifcid v0.0.3 h1:gmRKccqhWDocCRkC+a59g5QW7uJw5bpX9HWBevXa0zs= github.com/ipfs/go-verifcid v0.0.3/go.mod h1:gcCtGniVzelKrbk9ooUSX/pM3xlH73fZZJDzQJRvOUw= github.com/ipld/go-car v0.6.2 h1:Hlnl3Awgnq8icK+ze3iRghk805lu8YNq3wlREDTF2qc= diff --git a/go.mod b/go.mod index 9031c1840..257733cca 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( github.com/hashicorp/go-version v1.6.0 github.com/ipfs-shipyard/nopfs v0.0.12 github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c - github.com/ipfs/boxo v0.22.1-0.20240821001902-3cd3857b046c + github.com/ipfs/boxo v0.22.1-0.20240828000743-08f200aa8eef github.com/ipfs/go-block-format v0.2.0 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 @@ -29,7 +29,7 @@ require ( github.com/ipfs/go-ds-leveldb v0.5.0 github.com/ipfs/go-ds-measure v0.2.0 github.com/ipfs/go-fs-lock v0.0.7 - github.com/ipfs/go-ipfs-cmds v0.12.0 + github.com/ipfs/go-ipfs-cmds v0.13.0 github.com/ipfs/go-ipld-cbor v0.1.0 github.com/ipfs/go-ipld-format v0.6.0 github.com/ipfs/go-ipld-git v0.1.1 @@ -39,7 +39,7 @@ require ( github.com/ipfs/go-metrics-interface v0.0.1 github.com/ipfs/go-metrics-prometheus v0.0.2 github.com/ipfs/go-test v0.0.4 - github.com/ipfs/go-unixfsnode v1.9.0 + github.com/ipfs/go-unixfsnode v1.9.1 github.com/ipld/go-car v0.6.2 github.com/ipld/go-car/v2 v2.13.1 github.com/ipld/go-codec-dagpb v1.6.0 @@ -136,7 +136,6 @@ require ( github.com/ipfs/go-bitfield v1.1.0 // indirect github.com/ipfs/go-blockservice v0.5.2 // indirect github.com/ipfs/go-ipfs-blockstore v1.3.1 // indirect - github.com/ipfs/go-ipfs-chunker v0.0.5 // indirect github.com/ipfs/go-ipfs-delay v0.0.1 // indirect github.com/ipfs/go-ipfs-ds-help v1.1.1 // indirect github.com/ipfs/go-ipfs-exchange-interface v0.2.1 // indirect diff --git a/go.sum b/go.sum index 4c0c4fb61..553591794 100644 --- a/go.sum +++ b/go.sum @@ -330,19 +330,17 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.22.1-0.20240821001902-3cd3857b046c h1:vJb5RbEzIvTFnrxN1+AdQZLu1+ky4oWyx6ARnmtWYXU= -github.com/ipfs/boxo v0.22.1-0.20240821001902-3cd3857b046c/go.mod h1:bMB1tnSTr+6/CS5p3jkS4rtifpl+ul6P4ZgeTZn8Ty0= +github.com/ipfs/boxo v0.22.1-0.20240828000743-08f200aa8eef h1:ozMkCGYQmIkMnZwo4zPgrkkVFJvhBPnb3HhEswJoiG8= +github.com/ipfs/boxo v0.22.1-0.20240828000743-08f200aa8eef/go.mod h1:bMB1tnSTr+6/CS5p3jkS4rtifpl+ul6P4ZgeTZn8Ty0= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= github.com/ipfs/go-bitswap v0.11.0/go.mod h1:05aE8H3XOU+LXpTedeAS0OZpcO1WFsj5niYQH9a1Tmk= -github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= github.com/ipfs/go-block-format v0.0.3/go.mod h1:4LmD4ZUw0mhO+JSKdpWwrzATiEfM7WWgQ8H5l6P8MVk= github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs= github.com/ipfs/go-block-format v0.2.0/go.mod h1:+jpL11nFx5A/SPpsoBn6Bzkra/zaArfSmsknbPMYgzM= github.com/ipfs/go-blockservice v0.5.2 h1:in9Bc+QcXwd1apOVM7Un9t8tixPKdaHQFdLSUM1Xgk8= github.com/ipfs/go-blockservice v0.5.2/go.mod h1:VpMblFEqG67A/H2sHKAemeH9vlURVavlysbdUI632yk= -github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.3/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.4/go.mod h1:4LLaPOQwmk5z9LBgQnpkivrx8BJjUyGwTXCd5Xfj6+M= github.com/ipfs/go-cid v0.0.7/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I= @@ -373,10 +371,8 @@ github.com/ipfs/go-ipfs-blockstore v1.3.1 h1:cEI9ci7V0sRNivqaOr0elDsamxXFxJMMMy7 github.com/ipfs/go-ipfs-blockstore v1.3.1/go.mod h1:KgtZyc9fq+P2xJUiCAzbRdhhqJHvsw8u2Dlqy2MyRTE= github.com/ipfs/go-ipfs-blocksutil v0.0.1 h1:Eh/H4pc1hsvhzsQoMEP3Bke/aW5P5rVM1IWFJMcGIPQ= github.com/ipfs/go-ipfs-blocksutil v0.0.1/go.mod h1:Yq4M86uIOmxmGPUHv/uI7uKqZNtLb449gwKqXjIsnRk= -github.com/ipfs/go-ipfs-chunker v0.0.5 h1:ojCf7HV/m+uS2vhUGWcogIIxiO5ubl5O57Q7NapWLY8= -github.com/ipfs/go-ipfs-chunker v0.0.5/go.mod h1:jhgdF8vxRHycr00k13FM8Y0E+6BoalYeobXmUyTreP8= -github.com/ipfs/go-ipfs-cmds v0.12.0 h1:sx3toXYNbpTSfVvGjom7cuXPSynLMFIqX2h6JCebOP4= -github.com/ipfs/go-ipfs-cmds v0.12.0/go.mod h1:vZ4xu9Fi8ruWSbZfonlJYclH4371T7hWRpwqk0FE9SQ= +github.com/ipfs/go-ipfs-cmds v0.13.0 h1:+WVHZMrQNkPqwAQdrSFGbJgHpOc8H2G8eszNxnvoCQA= +github.com/ipfs/go-ipfs-cmds v0.13.0/go.mod h1:GYqjGSt6u9k9tyxIDT7M0ROWeB2raPGH94uuVnpWgY0= github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= github.com/ipfs/go-ipfs-delay v0.0.1 h1:r/UXYyRcddO6thwOnhiznIAiSvxMECGgtv35Xs1IeRQ= github.com/ipfs/go-ipfs-delay v0.0.1/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= @@ -426,8 +422,8 @@ github.com/ipfs/go-test v0.0.4 h1:DKT66T6GBB6PsDFLoO56QZPrOmzJkqU1FZH5C9ySkew= github.com/ipfs/go-test v0.0.4/go.mod h1:qhIM1EluEfElKKM6fnWxGn822/z9knUGM1+I/OAQNKI= github.com/ipfs/go-unixfs v0.4.5 h1:wj8JhxvV1G6CD7swACwSKYa+NgtdWC1RUit+gFnymDU= github.com/ipfs/go-unixfs v0.4.5/go.mod h1:BIznJNvt/gEx/ooRMI4Us9K8+qeGO7vx1ohnbk8gjFg= -github.com/ipfs/go-unixfsnode v1.9.0 h1:ubEhQhr22sPAKO2DNsyVBW7YB/zA8Zkif25aBvz8rc8= -github.com/ipfs/go-unixfsnode v1.9.0/go.mod h1:HxRu9HYHOjK6HUqFBAi++7DVoWAHn0o4v/nZ/VA+0g8= +github.com/ipfs/go-unixfsnode v1.9.1 h1:2cdSIDQCt7emNhlyUqUFQnKo2XvecARoIcurIKFjPD8= +github.com/ipfs/go-unixfsnode v1.9.1/go.mod h1:u8WxhmXzyrq3xfSYkhfx+uI+n91O+0L7KFjq3TS7d6g= github.com/ipfs/go-verifcid v0.0.3 h1:gmRKccqhWDocCRkC+a59g5QW7uJw5bpX9HWBevXa0zs= github.com/ipfs/go-verifcid v0.0.3/go.mod h1:gcCtGniVzelKrbk9ooUSX/pM3xlH73fZZJDzQJRvOUw= github.com/ipld/go-car v0.6.2 h1:Hlnl3Awgnq8icK+ze3iRghk805lu8YNq3wlREDTF2qc= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 8a9a4036a..4df60a3d7 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -111,7 +111,7 @@ require ( github.com/hexops/gotextdiff v1.0.3 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/ipfs/bbloom v0.0.4 // indirect - github.com/ipfs/boxo v0.22.1-0.20240821001902-3cd3857b046c // indirect + github.com/ipfs/boxo v0.22.1-0.20240828000743-08f200aa8eef // indirect github.com/ipfs/go-block-format v0.2.0 // indirect github.com/ipfs/go-cid v0.4.1 // indirect github.com/ipfs/go-datastore v0.6.0 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 67dffd1ed..72798a87f 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -281,8 +281,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.22.1-0.20240821001902-3cd3857b046c h1:vJb5RbEzIvTFnrxN1+AdQZLu1+ky4oWyx6ARnmtWYXU= -github.com/ipfs/boxo v0.22.1-0.20240821001902-3cd3857b046c/go.mod h1:bMB1tnSTr+6/CS5p3jkS4rtifpl+ul6P4ZgeTZn8Ty0= +github.com/ipfs/boxo v0.22.1-0.20240828000743-08f200aa8eef h1:ozMkCGYQmIkMnZwo4zPgrkkVFJvhBPnb3HhEswJoiG8= +github.com/ipfs/boxo v0.22.1-0.20240828000743-08f200aa8eef/go.mod h1:bMB1tnSTr+6/CS5p3jkS4rtifpl+ul6P4ZgeTZn8Ty0= github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs= github.com/ipfs/go-block-format v0.2.0/go.mod h1:+jpL11nFx5A/SPpsoBn6Bzkra/zaArfSmsknbPMYgzM= github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= From 23ca1ddab1cbaedbc21409ccf0337d2255e9ce0e Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Mon, 2 Sep 2024 23:39:16 +0200 Subject: [PATCH 1147/1212] fix: switch back to go 1.22 (#10502) Switching back until https://github.com/ipfs/kubo/issues/10501 is resolved. --- .github/workflows/codeql-analysis.yml | 2 +- .github/workflows/docker-build.yml | 2 +- .github/workflows/gateway-conformance.yml | 4 ++-- .github/workflows/gobuild.yml | 2 +- .github/workflows/golang-analysis.yml | 2 +- .github/workflows/golint.yml | 2 +- .github/workflows/gotest.yml | 2 +- .github/workflows/interop.yml | 2 +- .github/workflows/sharness.yml | 2 +- Dockerfile | 2 +- docs/examples/kubo-as-a-library/go.mod | 2 +- go.mod | 2 +- 12 files changed, 13 insertions(+), 13 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 8ed324854..d0e082d65 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -34,7 +34,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: 1.23.x + go-version: 1.22.x # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml index e13a3f882..433240f42 100644 --- a/.github/workflows/docker-build.yml +++ b/.github/workflows/docker-build.yml @@ -28,7 +28,7 @@ jobs: steps: - uses: actions/setup-go@v5 with: - go-version: 1.23.x + go-version: 1.22.x - uses: actions/checkout@v4 - run: docker build -t $IMAGE_NAME:$WIP_IMAGE_TAG . - run: docker run --rm $IMAGE_NAME:$WIP_IMAGE_TAG --version diff --git a/.github/workflows/gateway-conformance.yml b/.github/workflows/gateway-conformance.yml index d2f015900..b1791868c 100644 --- a/.github/workflows/gateway-conformance.yml +++ b/.github/workflows/gateway-conformance.yml @@ -49,7 +49,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: 1.23.x + go-version: 1.22.x - uses: protocol/cache-go-action@v1 with: name: ${{ github.job }} @@ -136,7 +136,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: 1.23.x + go-version: 1.22.x - uses: protocol/cache-go-action@v1 with: name: ${{ github.job }} diff --git a/.github/workflows/gobuild.yml b/.github/workflows/gobuild.yml index 5aebfd938..93159eadd 100644 --- a/.github/workflows/gobuild.yml +++ b/.github/workflows/gobuild.yml @@ -30,7 +30,7 @@ jobs: steps: - uses: actions/setup-go@v5 with: - go-version: 1.23.x + go-version: 1.22.x - uses: actions/checkout@v4 - run: make cmd/ipfs-try-build env: diff --git a/.github/workflows/golang-analysis.yml b/.github/workflows/golang-analysis.yml index 36a5bba01..e89034a92 100644 --- a/.github/workflows/golang-analysis.yml +++ b/.github/workflows/golang-analysis.yml @@ -27,7 +27,7 @@ jobs: submodules: recursive - uses: actions/setup-go@v5 with: - go-version: "1.23.x" + go-version: "1.22.x" - name: Check that go.mod is tidy uses: protocol/multiple-go-modules@v1.4 with: diff --git a/.github/workflows/golint.yml b/.github/workflows/golint.yml index 57b5d46dd..aa8b21b53 100644 --- a/.github/workflows/golint.yml +++ b/.github/workflows/golint.yml @@ -31,6 +31,6 @@ jobs: steps: - uses: actions/setup-go@v5 with: - go-version: 1.23.x + go-version: 1.22.x - uses: actions/checkout@v4 - run: make -O test_go_lint diff --git a/.github/workflows/gotest.yml b/.github/workflows/gotest.yml index f5225e8a3..609791aba 100644 --- a/.github/workflows/gotest.yml +++ b/.github/workflows/gotest.yml @@ -32,7 +32,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v5 with: - go-version: 1.23.x + go-version: 1.22.x - name: Check out Kubo uses: actions/checkout@v4 - name: Install missing tools diff --git a/.github/workflows/interop.yml b/.github/workflows/interop.yml index 2e280a779..73ee25555 100644 --- a/.github/workflows/interop.yml +++ b/.github/workflows/interop.yml @@ -10,7 +10,7 @@ on: - 'master' env: - GO_VERSION: 1.23.x + GO_VERSION: 1.22.x concurrency: group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.event_name == 'push' && github.sha || github.ref }} diff --git a/.github/workflows/sharness.yml b/.github/workflows/sharness.yml index af7fa896c..6432745bf 100644 --- a/.github/workflows/sharness.yml +++ b/.github/workflows/sharness.yml @@ -25,7 +25,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: 1.23.x + go-version: 1.22.x - name: Checkout Kubo uses: actions/checkout@v4 with: diff --git a/Dockerfile b/Dockerfile index e04b3c666..4ed07d3d4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM --platform=${BUILDPLATFORM:-linux/amd64} golang:1.23 AS builder +FROM --platform=${BUILDPLATFORM:-linux/amd64} golang:1.22 AS builder ARG TARGETOS TARGETARCH diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 49010af31..d84121e32 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -1,6 +1,6 @@ module github.com/ipfs/kubo/examples/kubo-as-a-library -go 1.23 +go 1.22 // Used to keep this in sync with the current version of kubo. You should remove // this if you copy this example. diff --git a/go.mod b/go.mod index 257733cca..3f86b7f54 100644 --- a/go.mod +++ b/go.mod @@ -251,4 +251,4 @@ require ( lukechampine.com/blake3 v1.3.0 // indirect ) -go 1.23 +go 1.22 From b50e029676a7a3f09350594ae8d5560b3b55e039 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Mon, 2 Sep 2024 23:39:16 +0200 Subject: [PATCH 1148/1212] fix: switch back to go 1.22 (#10502) Switching back until https://github.com/ipfs/kubo/issues/10501 is resolved. (cherry picked from commit 23ca1ddab1cbaedbc21409ccf0337d2255e9ce0e) --- .github/workflows/codeql-analysis.yml | 2 +- .github/workflows/docker-build.yml | 2 +- .github/workflows/gateway-conformance.yml | 4 ++-- .github/workflows/gobuild.yml | 2 +- .github/workflows/golang-analysis.yml | 2 +- .github/workflows/golint.yml | 2 +- .github/workflows/gotest.yml | 2 +- .github/workflows/interop.yml | 2 +- .github/workflows/sharness.yml | 2 +- Dockerfile | 2 +- docs/examples/kubo-as-a-library/go.mod | 2 +- go.mod | 2 +- 12 files changed, 13 insertions(+), 13 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 8ed324854..d0e082d65 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -34,7 +34,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: 1.23.x + go-version: 1.22.x # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml index e13a3f882..433240f42 100644 --- a/.github/workflows/docker-build.yml +++ b/.github/workflows/docker-build.yml @@ -28,7 +28,7 @@ jobs: steps: - uses: actions/setup-go@v5 with: - go-version: 1.23.x + go-version: 1.22.x - uses: actions/checkout@v4 - run: docker build -t $IMAGE_NAME:$WIP_IMAGE_TAG . - run: docker run --rm $IMAGE_NAME:$WIP_IMAGE_TAG --version diff --git a/.github/workflows/gateway-conformance.yml b/.github/workflows/gateway-conformance.yml index d2f015900..b1791868c 100644 --- a/.github/workflows/gateway-conformance.yml +++ b/.github/workflows/gateway-conformance.yml @@ -49,7 +49,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: 1.23.x + go-version: 1.22.x - uses: protocol/cache-go-action@v1 with: name: ${{ github.job }} @@ -136,7 +136,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: 1.23.x + go-version: 1.22.x - uses: protocol/cache-go-action@v1 with: name: ${{ github.job }} diff --git a/.github/workflows/gobuild.yml b/.github/workflows/gobuild.yml index 5aebfd938..93159eadd 100644 --- a/.github/workflows/gobuild.yml +++ b/.github/workflows/gobuild.yml @@ -30,7 +30,7 @@ jobs: steps: - uses: actions/setup-go@v5 with: - go-version: 1.23.x + go-version: 1.22.x - uses: actions/checkout@v4 - run: make cmd/ipfs-try-build env: diff --git a/.github/workflows/golang-analysis.yml b/.github/workflows/golang-analysis.yml index 36a5bba01..e89034a92 100644 --- a/.github/workflows/golang-analysis.yml +++ b/.github/workflows/golang-analysis.yml @@ -27,7 +27,7 @@ jobs: submodules: recursive - uses: actions/setup-go@v5 with: - go-version: "1.23.x" + go-version: "1.22.x" - name: Check that go.mod is tidy uses: protocol/multiple-go-modules@v1.4 with: diff --git a/.github/workflows/golint.yml b/.github/workflows/golint.yml index 57b5d46dd..aa8b21b53 100644 --- a/.github/workflows/golint.yml +++ b/.github/workflows/golint.yml @@ -31,6 +31,6 @@ jobs: steps: - uses: actions/setup-go@v5 with: - go-version: 1.23.x + go-version: 1.22.x - uses: actions/checkout@v4 - run: make -O test_go_lint diff --git a/.github/workflows/gotest.yml b/.github/workflows/gotest.yml index f5225e8a3..609791aba 100644 --- a/.github/workflows/gotest.yml +++ b/.github/workflows/gotest.yml @@ -32,7 +32,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v5 with: - go-version: 1.23.x + go-version: 1.22.x - name: Check out Kubo uses: actions/checkout@v4 - name: Install missing tools diff --git a/.github/workflows/interop.yml b/.github/workflows/interop.yml index 2e280a779..73ee25555 100644 --- a/.github/workflows/interop.yml +++ b/.github/workflows/interop.yml @@ -10,7 +10,7 @@ on: - 'master' env: - GO_VERSION: 1.23.x + GO_VERSION: 1.22.x concurrency: group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.event_name == 'push' && github.sha || github.ref }} diff --git a/.github/workflows/sharness.yml b/.github/workflows/sharness.yml index af7fa896c..6432745bf 100644 --- a/.github/workflows/sharness.yml +++ b/.github/workflows/sharness.yml @@ -25,7 +25,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: 1.23.x + go-version: 1.22.x - name: Checkout Kubo uses: actions/checkout@v4 with: diff --git a/Dockerfile b/Dockerfile index e04b3c666..4ed07d3d4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM --platform=${BUILDPLATFORM:-linux/amd64} golang:1.23 AS builder +FROM --platform=${BUILDPLATFORM:-linux/amd64} golang:1.22 AS builder ARG TARGETOS TARGETARCH diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 49010af31..d84121e32 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -1,6 +1,6 @@ module github.com/ipfs/kubo/examples/kubo-as-a-library -go 1.23 +go 1.22 // Used to keep this in sync with the current version of kubo. You should remove // this if you copy this example. diff --git a/go.mod b/go.mod index 257733cca..3f86b7f54 100644 --- a/go.mod +++ b/go.mod @@ -251,4 +251,4 @@ require ( lukechampine.com/blake3 v1.3.0 // indirect ) -go 1.23 +go 1.22 From cc2402c256f710620b6f2d9745098ea71b982f1a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 5 Sep 2024 17:34:57 +0200 Subject: [PATCH 1149/1212] chore(deps): bump docker/login-action from 3.1.0 to 3.3.0 (#10460) * chore(deps): bump docker/login-action from 3.1.0 to 3.3.0 Bumps [docker/login-action](https://github.com/docker/login-action) from 3.1.0 to 3.3.0. - [Release notes](https://github.com/docker/login-action/releases) - [Commits](https://github.com/docker/login-action/compare/e92390c5fb421da1463c202d546fed0ec5c39f20...9780b0c442fbb1117ed29e0efdff1e18412f7567) --- updated-dependencies: - dependency-name: docker/login-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Update .github/workflows/docker-image.yml * Update .github/workflows/docker-image.yml --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Marcin Rataj --- .github/workflows/docker-image.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index e52e522ea..f5642fe6d 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -63,7 +63,7 @@ jobs: shell: bash - name: Log in to Docker Hub - uses: docker/login-action@e92390c5fb421da1463c202d546fed0ec5c39f20 + uses: docker/login-action@v3 with: username: ${{ vars.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} From 680d420f9f878cbf7a56277006d052e276029048 Mon Sep 17 00:00:00 2001 From: Andrew Gillis <11790789+gammazero@users.noreply.github.com> Date: Thu, 5 Sep 2024 14:20:08 -0700 Subject: [PATCH 1150/1212] docs: replace outdated package paths described in rpc README (#10505) Closes #10498 --- client/rpc/README.md | 46 ++++++++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/client/rpc/README.md b/client/rpc/README.md index a020aa9da..d9744e5b6 100644 --- a/client/rpc/README.md +++ b/client/rpc/README.md @@ -2,7 +2,7 @@ > IPFS CoreAPI implementation using HTTP API -This packages implements [`coreiface.CoreAPI`](https://pkg.go.dev/github.com/ipfs/boxo/coreiface#CoreAPI) over the HTTP API. +This package implements [`coreiface.CoreAPI`](https://pkg.go.dev/github.com/ipfs/kubo/core/coreiface#CoreAPI) over the HTTP API. ## Documentation @@ -16,29 +16,33 @@ Pin file on your local IPFS node based on its CID: package main import ( - "context" - "fmt" + "context" + "fmt" - "github.com/ipfs/kubo/client/rpc" - path "github.com/ipfs/boxo/coreiface/path" + "github.com/ipfs/boxo/path" + "github.com/ipfs/go-cid" + "github.com/ipfs/kubo/client/rpc" ) func main() { - // "Connect" to local node - node, err := rpc.NewLocalApi() - if err != nil { - fmt.Printf(err) - return - } - // Pin a given file by its CID - ctx := context.Background() - cid := "bafkreidtuosuw37f5xmn65b3ksdiikajy7pwjjslzj2lxxz2vc4wdy3zku" - p := path.New(cid) - err = node.Pin().Add(ctx, p) - if err != nil { - fmt.Printf(err) - return - } - return + // "Connect" to local node + node, err := rpc.NewLocalApi() + if err != nil { + fmt.Println(err) + return + } + // Pin a given file by its CID + ctx := context.Background() + c, err := cid.Decode("bafkreidtuosuw37f5xmn65b3ksdiikajy7pwjjslzj2lxxz2vc4wdy3zku") + if err != nil { + fmt.Println(err) + return + } + p := path.FromCid(c) + err = node.Pin().Add(ctx, p) + if err != nil { + fmt.Println(err) + return + } } ``` From 6454bdb4ea9d37446d1ed4be4418dafc70618a42 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Thu, 5 Sep 2024 23:52:19 +0200 Subject: [PATCH 1151/1212] chore: boxo v0.23.0 and go-libp2p v0.36.3 (#10507) https://github.com/libp2p/go-libp2p/releases/tag/v0.36.3 https://github.com/ipfs/boxo/releases/tag/v0.23.0 --- README.md | 8 +++++--- docs/changelogs/v0.30.md | 22 ++++++++++++++++++++++ docs/examples/kubo-as-a-library/go.mod | 4 ++-- docs/examples/kubo-as-a-library/go.sum | 8 ++++---- go.mod | 4 ++-- go.sum | 8 ++++---- test/dependencies/go.mod | 4 ++-- test/dependencies/go.sum | 8 ++++---- test/sharness/lib/install-sharness.sh | 2 +- 9 files changed, 46 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index b80fa2e60..30a884e96 100644 --- a/README.md +++ b/README.md @@ -471,9 +471,11 @@ If you make changes to the protocol buffers, you will need to install the [proto Find more documentation for developers on [docs](./docs) ## Maintainer Info -* [Project Board for active and upcoming work](https://pl-strflt.notion.site/Kubo-GitHub-Project-Board-c68f9192e48e4e9eba185fa697bf0570) -* [Release Process](https://pl-strflt.notion.site/Kubo-Release-Process-5a5d066264704009a28a79cff93062c4) -* [Additional PL EngRes Kubo maintainer info](https://pl-strflt.notion.site/Kubo-go-ipfs-4a484aeeaa974dcf918027c300426c05) + +Kubo is maintained by [Shipyard](https://ipshipyard.com/). + +* This repository is part of [Shipyard's GO Triage triage](https://ipshipyard.notion.site/IPFS-Go-Triage-Boxo-Kubo-Rainbow-0ddee6b7f28d412da7dabe4f9107c29a). +* [Release Process](https://ipshipyard.notion.site/Kubo-Release-Process-6dba4f5755c9458ab5685eeb28173778) ## Contributing diff --git a/docs/changelogs/v0.30.md b/docs/changelogs/v0.30.md index 4c22e40ba..c5073049c 100644 --- a/docs/changelogs/v0.30.md +++ b/docs/changelogs/v0.30.md @@ -6,6 +6,8 @@ - [Overview](#overview) - [🔦 Highlights](#-highlights) + - [Improved P2P connectivity](#improved-p2p-connectivity) + - [Refactored Bitswap and dag-pb chunker](#refactored-bitswap-and-dag-pb-chunker) - [WebRTC-Direct Transport enabled by default](#webrtc-direct-transport-enabled-by-default) - [AutoNAT V2 Service Introduced Alongside V1](#autonat-v2-service-introduced-alongside-v1) - [Automated `ipfs version check`](#automated-ipfs-version-check) @@ -21,6 +23,26 @@ ### 🔦 Highlights +This release took longer and is more packed with fixes and features than usual. + +> [!IMPORTANT] +> TLDR: update, it contains many, many fixes. + +#### Improved P2P connectivity + +This release comes with significant go-libp2p update from v0.34.1 to v0.36.3 ([release notes](https://github.com/ipfs/boxo/releases/)). + +It includes multiple fixes to key protocols: QUIC/Webtransport/WebRTC, Connection Upgrades through Relay ([DCUtR](https://github.com/libp2p/specs/blob/master/relay/DCUtR.md)), and Secure WebSockets. + +Also, peers that are behind certain types of NAT will now be more reachable. For this alone, Kubo users are highly encouraged to upgrade. + +#### Refactored Bitswap and dag-pb chunker + +Some workloads may experience improved memory profile thanks to optimizations from Boxo SDK [v0.23.0](https://github.com/ipfs/boxo/releases/tag/v0.23.0). + +> [!IMPORTANT] +> Storage providers should upgrade to take advantage of the Bitswap server fix, which resolves the issue of greedy peers depleting available wantlist slots for their PeerID, resulting in stalled downloads. + #### WebRTC-Direct Transport enabled by default Kubo now ships with `/udp/4001/webrtc-direct` listener enabled by default. diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index d84121e32..033282a0f 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,9 +7,9 @@ go 1.22 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.22.1-0.20240828000743-08f200aa8eef + github.com/ipfs/boxo v0.23.0 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 - github.com/libp2p/go-libp2p v0.36.2 + github.com/libp2p/go-libp2p v0.36.3 github.com/multiformats/go-multiaddr v0.13.0 ) diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 05e7f6903..53a4e6750 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -266,8 +266,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.22.1-0.20240828000743-08f200aa8eef h1:ozMkCGYQmIkMnZwo4zPgrkkVFJvhBPnb3HhEswJoiG8= -github.com/ipfs/boxo v0.22.1-0.20240828000743-08f200aa8eef/go.mod h1:bMB1tnSTr+6/CS5p3jkS4rtifpl+ul6P4ZgeTZn8Ty0= +github.com/ipfs/boxo v0.23.0 h1:dY1PpcvPJ//VuUQ1TUd5TZvmaGuzxJ8dOP6mXaw+ke8= +github.com/ipfs/boxo v0.23.0/go.mod h1:ulu5I6avTmgGmvjuCaBRKwsaOOKjBfQw1EiOOQp8M6E= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= @@ -427,8 +427,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.36.2 h1:BbqRkDaGC3/5xfaJakLV/BrpjlAuYqSB0lRvtzL3B/U= -github.com/libp2p/go-libp2p v0.36.2/go.mod h1:XO3joasRE4Eup8yCTTP/+kX+g92mOgRaadk46LmPhHY= +github.com/libp2p/go-libp2p v0.36.3 h1:NHz30+G7D8Y8YmznrVZZla0ofVANrvBl2c+oARfMeDQ= +github.com/libp2p/go-libp2p v0.36.3/go.mod h1:4Y5vFyCUiJuluEPmpnKYf6WFx5ViKPUYs/ixe9ANFZ8= github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94= github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= diff --git a/go.mod b/go.mod index 3f86b7f54..32b762790 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( github.com/hashicorp/go-version v1.6.0 github.com/ipfs-shipyard/nopfs v0.0.12 github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c - github.com/ipfs/boxo v0.22.1-0.20240828000743-08f200aa8eef + github.com/ipfs/boxo v0.23.0 github.com/ipfs/go-block-format v0.2.0 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 @@ -48,7 +48,7 @@ require ( github.com/jbenet/goprocess v0.1.4 github.com/julienschmidt/httprouter v1.3.0 github.com/libp2p/go-doh-resolver v0.4.0 - github.com/libp2p/go-libp2p v0.36.2 + github.com/libp2p/go-libp2p v0.36.3 github.com/libp2p/go-libp2p-http v0.5.0 github.com/libp2p/go-libp2p-kad-dht v0.26.1 github.com/libp2p/go-libp2p-kbucket v0.6.3 diff --git a/go.sum b/go.sum index 553591794..40d55934a 100644 --- a/go.sum +++ b/go.sum @@ -330,8 +330,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.22.1-0.20240828000743-08f200aa8eef h1:ozMkCGYQmIkMnZwo4zPgrkkVFJvhBPnb3HhEswJoiG8= -github.com/ipfs/boxo v0.22.1-0.20240828000743-08f200aa8eef/go.mod h1:bMB1tnSTr+6/CS5p3jkS4rtifpl+ul6P4ZgeTZn8Ty0= +github.com/ipfs/boxo v0.23.0 h1:dY1PpcvPJ//VuUQ1TUd5TZvmaGuzxJ8dOP6mXaw+ke8= +github.com/ipfs/boxo v0.23.0/go.mod h1:ulu5I6avTmgGmvjuCaBRKwsaOOKjBfQw1EiOOQp8M6E= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= @@ -504,8 +504,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.36.2 h1:BbqRkDaGC3/5xfaJakLV/BrpjlAuYqSB0lRvtzL3B/U= -github.com/libp2p/go-libp2p v0.36.2/go.mod h1:XO3joasRE4Eup8yCTTP/+kX+g92mOgRaadk46LmPhHY= +github.com/libp2p/go-libp2p v0.36.3 h1:NHz30+G7D8Y8YmznrVZZla0ofVANrvBl2c+oARfMeDQ= +github.com/libp2p/go-libp2p v0.36.3/go.mod h1:4Y5vFyCUiJuluEPmpnKYf6WFx5ViKPUYs/ixe9ANFZ8= github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94= github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 4df60a3d7..40fde600c 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -111,7 +111,7 @@ require ( github.com/hexops/gotextdiff v1.0.3 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/ipfs/bbloom v0.0.4 // indirect - github.com/ipfs/boxo v0.22.1-0.20240828000743-08f200aa8eef // indirect + github.com/ipfs/boxo v0.23.0 // indirect github.com/ipfs/go-block-format v0.2.0 // indirect github.com/ipfs/go-cid v0.4.1 // indirect github.com/ipfs/go-datastore v0.6.0 // indirect @@ -142,7 +142,7 @@ require ( github.com/leonklingele/grouper v1.1.2 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/libp2p/go-cidranger v1.1.0 // indirect - github.com/libp2p/go-libp2p v0.36.2 // indirect + github.com/libp2p/go-libp2p v0.36.3 // indirect github.com/libp2p/go-libp2p-asn-util v0.4.1 // indirect github.com/libp2p/go-libp2p-kad-dht v0.26.1 // indirect github.com/libp2p/go-libp2p-kbucket v0.6.3 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 72798a87f..81ca714e2 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -281,8 +281,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.22.1-0.20240828000743-08f200aa8eef h1:ozMkCGYQmIkMnZwo4zPgrkkVFJvhBPnb3HhEswJoiG8= -github.com/ipfs/boxo v0.22.1-0.20240828000743-08f200aa8eef/go.mod h1:bMB1tnSTr+6/CS5p3jkS4rtifpl+ul6P4ZgeTZn8Ty0= +github.com/ipfs/boxo v0.23.0 h1:dY1PpcvPJ//VuUQ1TUd5TZvmaGuzxJ8dOP6mXaw+ke8= +github.com/ipfs/boxo v0.23.0/go.mod h1:ulu5I6avTmgGmvjuCaBRKwsaOOKjBfQw1EiOOQp8M6E= github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs= github.com/ipfs/go-block-format v0.2.0/go.mod h1:+jpL11nFx5A/SPpsoBn6Bzkra/zaArfSmsknbPMYgzM= github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= @@ -388,8 +388,8 @@ github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38y github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.36.2 h1:BbqRkDaGC3/5xfaJakLV/BrpjlAuYqSB0lRvtzL3B/U= -github.com/libp2p/go-libp2p v0.36.2/go.mod h1:XO3joasRE4Eup8yCTTP/+kX+g92mOgRaadk46LmPhHY= +github.com/libp2p/go-libp2p v0.36.3 h1:NHz30+G7D8Y8YmznrVZZla0ofVANrvBl2c+oARfMeDQ= +github.com/libp2p/go-libp2p v0.36.3/go.mod h1:4Y5vFyCUiJuluEPmpnKYf6WFx5ViKPUYs/ixe9ANFZ8= github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94= github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= github.com/libp2p/go-libp2p-kad-dht v0.26.1 h1:AazV3LCImYVkDUGAHx5lIEgZ9iUI2QQKH5GMRQU8uEA= diff --git a/test/sharness/lib/install-sharness.sh b/test/sharness/lib/install-sharness.sh index 41b27188c..c695a3419 100755 --- a/test/sharness/lib/install-sharness.sh +++ b/test/sharness/lib/install-sharness.sh @@ -5,7 +5,7 @@ # MIT Licensed; see the LICENSE file in this repository. # -gitrepo=pl-strflt/sharness +gitrepo=ipfs/sharness githash=803df39d3cba16bb7d493dd6cd8bc5e29826da61 if test ! -n "$clonedir" ; then From c228935ba5c41391610109aebabeb1edba750a62 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Thu, 5 Sep 2024 23:52:19 +0200 Subject: [PATCH 1152/1212] chore: boxo v0.23.0 and go-libp2p v0.36.3 (#10507) https://github.com/libp2p/go-libp2p/releases/tag/v0.36.3 https://github.com/ipfs/boxo/releases/tag/v0.23.0 (cherry picked from commit 6454bdb4ea9d37446d1ed4be4418dafc70618a42) --- README.md | 8 +++++--- docs/changelogs/v0.30.md | 22 ++++++++++++++++++++++ docs/examples/kubo-as-a-library/go.mod | 4 ++-- docs/examples/kubo-as-a-library/go.sum | 8 ++++---- go.mod | 4 ++-- go.sum | 8 ++++---- test/dependencies/go.mod | 4 ++-- test/dependencies/go.sum | 8 ++++---- test/sharness/lib/install-sharness.sh | 2 +- 9 files changed, 46 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index b80fa2e60..30a884e96 100644 --- a/README.md +++ b/README.md @@ -471,9 +471,11 @@ If you make changes to the protocol buffers, you will need to install the [proto Find more documentation for developers on [docs](./docs) ## Maintainer Info -* [Project Board for active and upcoming work](https://pl-strflt.notion.site/Kubo-GitHub-Project-Board-c68f9192e48e4e9eba185fa697bf0570) -* [Release Process](https://pl-strflt.notion.site/Kubo-Release-Process-5a5d066264704009a28a79cff93062c4) -* [Additional PL EngRes Kubo maintainer info](https://pl-strflt.notion.site/Kubo-go-ipfs-4a484aeeaa974dcf918027c300426c05) + +Kubo is maintained by [Shipyard](https://ipshipyard.com/). + +* This repository is part of [Shipyard's GO Triage triage](https://ipshipyard.notion.site/IPFS-Go-Triage-Boxo-Kubo-Rainbow-0ddee6b7f28d412da7dabe4f9107c29a). +* [Release Process](https://ipshipyard.notion.site/Kubo-Release-Process-6dba4f5755c9458ab5685eeb28173778) ## Contributing diff --git a/docs/changelogs/v0.30.md b/docs/changelogs/v0.30.md index 4c22e40ba..c5073049c 100644 --- a/docs/changelogs/v0.30.md +++ b/docs/changelogs/v0.30.md @@ -6,6 +6,8 @@ - [Overview](#overview) - [🔦 Highlights](#-highlights) + - [Improved P2P connectivity](#improved-p2p-connectivity) + - [Refactored Bitswap and dag-pb chunker](#refactored-bitswap-and-dag-pb-chunker) - [WebRTC-Direct Transport enabled by default](#webrtc-direct-transport-enabled-by-default) - [AutoNAT V2 Service Introduced Alongside V1](#autonat-v2-service-introduced-alongside-v1) - [Automated `ipfs version check`](#automated-ipfs-version-check) @@ -21,6 +23,26 @@ ### 🔦 Highlights +This release took longer and is more packed with fixes and features than usual. + +> [!IMPORTANT] +> TLDR: update, it contains many, many fixes. + +#### Improved P2P connectivity + +This release comes with significant go-libp2p update from v0.34.1 to v0.36.3 ([release notes](https://github.com/ipfs/boxo/releases/)). + +It includes multiple fixes to key protocols: QUIC/Webtransport/WebRTC, Connection Upgrades through Relay ([DCUtR](https://github.com/libp2p/specs/blob/master/relay/DCUtR.md)), and Secure WebSockets. + +Also, peers that are behind certain types of NAT will now be more reachable. For this alone, Kubo users are highly encouraged to upgrade. + +#### Refactored Bitswap and dag-pb chunker + +Some workloads may experience improved memory profile thanks to optimizations from Boxo SDK [v0.23.0](https://github.com/ipfs/boxo/releases/tag/v0.23.0). + +> [!IMPORTANT] +> Storage providers should upgrade to take advantage of the Bitswap server fix, which resolves the issue of greedy peers depleting available wantlist slots for their PeerID, resulting in stalled downloads. + #### WebRTC-Direct Transport enabled by default Kubo now ships with `/udp/4001/webrtc-direct` listener enabled by default. diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index d84121e32..033282a0f 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,9 +7,9 @@ go 1.22 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.22.1-0.20240828000743-08f200aa8eef + github.com/ipfs/boxo v0.23.0 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 - github.com/libp2p/go-libp2p v0.36.2 + github.com/libp2p/go-libp2p v0.36.3 github.com/multiformats/go-multiaddr v0.13.0 ) diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 05e7f6903..53a4e6750 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -266,8 +266,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.22.1-0.20240828000743-08f200aa8eef h1:ozMkCGYQmIkMnZwo4zPgrkkVFJvhBPnb3HhEswJoiG8= -github.com/ipfs/boxo v0.22.1-0.20240828000743-08f200aa8eef/go.mod h1:bMB1tnSTr+6/CS5p3jkS4rtifpl+ul6P4ZgeTZn8Ty0= +github.com/ipfs/boxo v0.23.0 h1:dY1PpcvPJ//VuUQ1TUd5TZvmaGuzxJ8dOP6mXaw+ke8= +github.com/ipfs/boxo v0.23.0/go.mod h1:ulu5I6avTmgGmvjuCaBRKwsaOOKjBfQw1EiOOQp8M6E= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= @@ -427,8 +427,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.36.2 h1:BbqRkDaGC3/5xfaJakLV/BrpjlAuYqSB0lRvtzL3B/U= -github.com/libp2p/go-libp2p v0.36.2/go.mod h1:XO3joasRE4Eup8yCTTP/+kX+g92mOgRaadk46LmPhHY= +github.com/libp2p/go-libp2p v0.36.3 h1:NHz30+G7D8Y8YmznrVZZla0ofVANrvBl2c+oARfMeDQ= +github.com/libp2p/go-libp2p v0.36.3/go.mod h1:4Y5vFyCUiJuluEPmpnKYf6WFx5ViKPUYs/ixe9ANFZ8= github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94= github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= diff --git a/go.mod b/go.mod index 3f86b7f54..32b762790 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( github.com/hashicorp/go-version v1.6.0 github.com/ipfs-shipyard/nopfs v0.0.12 github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c - github.com/ipfs/boxo v0.22.1-0.20240828000743-08f200aa8eef + github.com/ipfs/boxo v0.23.0 github.com/ipfs/go-block-format v0.2.0 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 @@ -48,7 +48,7 @@ require ( github.com/jbenet/goprocess v0.1.4 github.com/julienschmidt/httprouter v1.3.0 github.com/libp2p/go-doh-resolver v0.4.0 - github.com/libp2p/go-libp2p v0.36.2 + github.com/libp2p/go-libp2p v0.36.3 github.com/libp2p/go-libp2p-http v0.5.0 github.com/libp2p/go-libp2p-kad-dht v0.26.1 github.com/libp2p/go-libp2p-kbucket v0.6.3 diff --git a/go.sum b/go.sum index 553591794..40d55934a 100644 --- a/go.sum +++ b/go.sum @@ -330,8 +330,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.22.1-0.20240828000743-08f200aa8eef h1:ozMkCGYQmIkMnZwo4zPgrkkVFJvhBPnb3HhEswJoiG8= -github.com/ipfs/boxo v0.22.1-0.20240828000743-08f200aa8eef/go.mod h1:bMB1tnSTr+6/CS5p3jkS4rtifpl+ul6P4ZgeTZn8Ty0= +github.com/ipfs/boxo v0.23.0 h1:dY1PpcvPJ//VuUQ1TUd5TZvmaGuzxJ8dOP6mXaw+ke8= +github.com/ipfs/boxo v0.23.0/go.mod h1:ulu5I6avTmgGmvjuCaBRKwsaOOKjBfQw1EiOOQp8M6E= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= @@ -504,8 +504,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.36.2 h1:BbqRkDaGC3/5xfaJakLV/BrpjlAuYqSB0lRvtzL3B/U= -github.com/libp2p/go-libp2p v0.36.2/go.mod h1:XO3joasRE4Eup8yCTTP/+kX+g92mOgRaadk46LmPhHY= +github.com/libp2p/go-libp2p v0.36.3 h1:NHz30+G7D8Y8YmznrVZZla0ofVANrvBl2c+oARfMeDQ= +github.com/libp2p/go-libp2p v0.36.3/go.mod h1:4Y5vFyCUiJuluEPmpnKYf6WFx5ViKPUYs/ixe9ANFZ8= github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94= github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 4df60a3d7..40fde600c 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -111,7 +111,7 @@ require ( github.com/hexops/gotextdiff v1.0.3 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/ipfs/bbloom v0.0.4 // indirect - github.com/ipfs/boxo v0.22.1-0.20240828000743-08f200aa8eef // indirect + github.com/ipfs/boxo v0.23.0 // indirect github.com/ipfs/go-block-format v0.2.0 // indirect github.com/ipfs/go-cid v0.4.1 // indirect github.com/ipfs/go-datastore v0.6.0 // indirect @@ -142,7 +142,7 @@ require ( github.com/leonklingele/grouper v1.1.2 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/libp2p/go-cidranger v1.1.0 // indirect - github.com/libp2p/go-libp2p v0.36.2 // indirect + github.com/libp2p/go-libp2p v0.36.3 // indirect github.com/libp2p/go-libp2p-asn-util v0.4.1 // indirect github.com/libp2p/go-libp2p-kad-dht v0.26.1 // indirect github.com/libp2p/go-libp2p-kbucket v0.6.3 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 72798a87f..81ca714e2 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -281,8 +281,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.22.1-0.20240828000743-08f200aa8eef h1:ozMkCGYQmIkMnZwo4zPgrkkVFJvhBPnb3HhEswJoiG8= -github.com/ipfs/boxo v0.22.1-0.20240828000743-08f200aa8eef/go.mod h1:bMB1tnSTr+6/CS5p3jkS4rtifpl+ul6P4ZgeTZn8Ty0= +github.com/ipfs/boxo v0.23.0 h1:dY1PpcvPJ//VuUQ1TUd5TZvmaGuzxJ8dOP6mXaw+ke8= +github.com/ipfs/boxo v0.23.0/go.mod h1:ulu5I6avTmgGmvjuCaBRKwsaOOKjBfQw1EiOOQp8M6E= github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs= github.com/ipfs/go-block-format v0.2.0/go.mod h1:+jpL11nFx5A/SPpsoBn6Bzkra/zaArfSmsknbPMYgzM= github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= @@ -388,8 +388,8 @@ github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38y github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.36.2 h1:BbqRkDaGC3/5xfaJakLV/BrpjlAuYqSB0lRvtzL3B/U= -github.com/libp2p/go-libp2p v0.36.2/go.mod h1:XO3joasRE4Eup8yCTTP/+kX+g92mOgRaadk46LmPhHY= +github.com/libp2p/go-libp2p v0.36.3 h1:NHz30+G7D8Y8YmznrVZZla0ofVANrvBl2c+oARfMeDQ= +github.com/libp2p/go-libp2p v0.36.3/go.mod h1:4Y5vFyCUiJuluEPmpnKYf6WFx5ViKPUYs/ixe9ANFZ8= github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94= github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= github.com/libp2p/go-libp2p-kad-dht v0.26.1 h1:AazV3LCImYVkDUGAHx5lIEgZ9iUI2QQKH5GMRQU8uEA= diff --git a/test/sharness/lib/install-sharness.sh b/test/sharness/lib/install-sharness.sh index 41b27188c..c695a3419 100755 --- a/test/sharness/lib/install-sharness.sh +++ b/test/sharness/lib/install-sharness.sh @@ -5,7 +5,7 @@ # MIT Licensed; see the LICENSE file in this repository. # -gitrepo=pl-strflt/sharness +gitrepo=ipfs/sharness githash=803df39d3cba16bb7d493dd6cd8bc5e29826da61 if test ! -n "$clonedir" ; then From 2b1af8d958855dba025b79b822f9fece9bb3f95b Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Fri, 6 Sep 2024 00:14:03 +0200 Subject: [PATCH 1153/1212] chore: bump CurrentVersionNumber --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index e394ce0f9..30d2f72a3 100644 --- a/version.go +++ b/version.go @@ -11,7 +11,7 @@ import ( var CurrentCommit string // CurrentVersionNumber is the current application's version literal. -const CurrentVersionNumber = "0.30.0-rc2" +const CurrentVersionNumber = "0.30.0-rc3" const ApiVersion = "/kubo/" + CurrentVersionNumber + "/" //nolint From 89df952afa6069e34991c0b5e8eb4af66b90bce6 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Wed, 11 Sep 2024 15:48:46 +0200 Subject: [PATCH 1154/1212] chore: set version to 0.30.0 --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index 30d2f72a3..502bbc650 100644 --- a/version.go +++ b/version.go @@ -11,7 +11,7 @@ import ( var CurrentCommit string // CurrentVersionNumber is the current application's version literal. -const CurrentVersionNumber = "0.30.0-rc3" +const CurrentVersionNumber = "0.30.0" const ApiVersion = "/kubo/" + CurrentVersionNumber + "/" //nolint From b0812d82dd72532f6e684de973d8d369fa054702 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Wed, 11 Sep 2024 16:04:53 +0200 Subject: [PATCH 1155/1212] docs: changelog and contributors --- docs/changelogs/v0.30.md | 178 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 177 insertions(+), 1 deletion(-) diff --git a/docs/changelogs/v0.30.md b/docs/changelogs/v0.30.md index c5073049c..d13f2617e 100644 --- a/docs/changelogs/v0.30.md +++ b/docs/changelogs/v0.30.md @@ -155,7 +155,183 @@ Modification time support was also added to the Gateway. If present, value from #### Commands Preserve Specified Hostname When executing a [CLI command](https://docs.ipfs.tech/reference/kubo/cli/) over [Kubo RPC API](https://docs.ipfs.tech/reference/kubo/rpc/), if a hostname is specified by `--api=/dns4//` the resulting HTTP request now contains the hostname, instead of the the IP address that the hostname resolved to, as was the previous behavior. This makes it easier for those trying to run Kubo behind a reverse proxy using hostname-based rules. - + ### 📝 Changelog +
Full Changelog + +- github.com/ipfs/kubo: + - chore: set version to 0.30.0 + - chore: bump CurrentVersionNumber + - chore: boxo v0.23.0 and go-libp2p v0.36.3 (#10507) ([ipfs/kubo#10507](https://github.com/ipfs/kubo/pull/10507)) + - fix: switch back to go 1.22 (#10502) ([ipfs/kubo#10502](https://github.com/ipfs/kubo/pull/10502)) + - chore: update go-unixfsnode, cmds, and boxo (#10494) ([ipfs/kubo#10494](https://github.com/ipfs/kubo/pull/10494)) + - fix(cli): preserve hostname specified with --api in http request headers (#10497) ([ipfs/kubo#10497](https://github.com/ipfs/kubo/pull/10497)) + - chore: upgrade to go 1.23 (#10486) ([ipfs/kubo#10486](https://github.com/ipfs/kubo/pull/10486)) + - fix: error during config when running benchmarks (#10495) ([ipfs/kubo#10495](https://github.com/ipfs/kubo/pull/10495)) + - chore: update version to rc-2 + - chore: update version + - chore: fix function name (#10481) ([ipfs/kubo#10481](https://github.com/ipfs/kubo/pull/10481)) + - feat: Support storing UnixFS 1.5 Mode and ModTime (#10478) ([ipfs/kubo#10478](https://github.com/ipfs/kubo/pull/10478)) + - fix(rpc): cross-platform support for /unix/ socket maddrs in Addresses.API ([ipfs/kubo#10019](https://github.com/ipfs/kubo/pull/10019)) + - chore(daemon): sort listeners (#10480) ([ipfs/kubo#10480](https://github.com/ipfs/kubo/pull/10480)) + - feat(daemon): improve stdout on startup (#10472) ([ipfs/kubo#10472](https://github.com/ipfs/kubo/pull/10472)) + - fix(daemon): panic in kubo/daemon.go:595 (#10473) ([ipfs/kubo#10473](https://github.com/ipfs/kubo/pull/10473)) + - feat: webui v4.3.0 (#10477) ([ipfs/kubo#10477](https://github.com/ipfs/kubo/pull/10477)) + - docs(readme): add Gentoo Linux (#10474) ([ipfs/kubo#10474](https://github.com/ipfs/kubo/pull/10474)) + - libp2p: default to prefering TLS ([ipfs/kubo#10227](https://github.com/ipfs/kubo/pull/10227)) + - docs: document unofficial Ubuntu PPA ([ipfs/kubo#10467](https://github.com/ipfs/kubo/pull/10467)) + - feat: run AutoNAT V2 service in addition to V1 (#10468) ([ipfs/kubo#10468](https://github.com/ipfs/kubo/pull/10468)) + - feat: go-libp2p 0.36 and /webrtc-direct listener (#10463) ([ipfs/kubo#10463](https://github.com/ipfs/kubo/pull/10463)) + - chore: update dependencies (#10462)(#10466) ([ipfs/kubo#10466](https://github.com/ipfs/kubo/pull/10466)) + - feat: periodic version check and json config (#10438) ([ipfs/kubo#10438](https://github.com/ipfs/kubo/pull/10438)) + - docs: clarify pnet limitations + - docs: "error mounting: could not resolve name" (#10449) ([ipfs/kubo#10449](https://github.com/ipfs/kubo/pull/10449)) + - docs: update ipfs-swarm-key-gen example (#10453) ([ipfs/kubo#10453](https://github.com/ipfs/kubo/pull/10453)) + - chore: update deps incl. boxo v0.21.0 (#10444) ([ipfs/kubo#10444](https://github.com/ipfs/kubo/pull/10444)) + - chore: go-libp2p 0.35.1 (#10430) ([ipfs/kubo#10430](https://github.com/ipfs/kubo/pull/10430)) + - docsa: update RELEASE_CHECKLIST.md + - chore: create next changelog (#10443) ([ipfs/kubo#10443](https://github.com/ipfs/kubo/pull/10443)) + - Merge Release: v0.29.0 [skip changelog] ([ipfs/kubo#10442](https://github.com/ipfs/kubo/pull/10442)) + - fix(cli): unify --name param in ls and add (#10439) ([ipfs/kubo#10439](https://github.com/ipfs/kubo/pull/10439)) + - fix(libp2p): streams config validation in resource manager (#10435) ([ipfs/kubo#10435](https://github.com/ipfs/kubo/pull/10435)) + - chore: fix some typos (#10396) ([ipfs/kubo#10396](https://github.com/ipfs/kubo/pull/10396)) + - chore: update version +- github.com/ipfs/boxo (v0.20.0 -> v0.23.0): + - Release v0.23.0 ([ipfs/boxo#669](https://github.com/ipfs/boxo/pull/669)) + - docs(changelog): move entry to correct release + - Release v0.22.0 ([ipfs/boxo#654](https://github.com/ipfs/boxo/pull/654)) + - Release v0.21.0 ([ipfs/boxo#622](https://github.com/ipfs/boxo/pull/622)) +- github.com/ipfs/go-ipfs-cmds (v0.11.0 -> v0.13.0): + - chore: release v0.13.0 (#261) ([ipfs/go-ipfs-cmds#261](https://github.com/ipfs/go-ipfs-cmds/pull/261)) + - chore: release v0.12.0 (#259) ([ipfs/go-ipfs-cmds#259](https://github.com/ipfs/go-ipfs-cmds/pull/259)) +- github.com/ipfs/go-unixfsnode (v1.9.0 -> v1.9.1): + - Update release version ([ipfs/go-unixfsnode#76](https://github.com/ipfs/go-unixfsnode/pull/76)) + - chore: update dependencies ([ipfs/go-unixfsnode#75](https://github.com/ipfs/go-unixfsnode/pull/75)) +- github.com/libp2p/go-libp2p (v0.34.1 -> v0.36.3): + - Release v0.36.3 + - Fix: WebSocket: Clone TLS config before creating a new listener + - fix: enable dctur when interface address is public (#2931) ([libp2p/go-libp2p#2931](https://github.com/libp2p/go-libp2p/pull/2931)) + - fix: QUIC/Webtransport Transports now will prefer their owned listeners for dialing out (#2936) ([libp2p/go-libp2p#2936](https://github.com/libp2p/go-libp2p/pull/2936)) + - ci: uci/update-go (#2937) ([libp2p/go-libp2p#2937](https://github.com/libp2p/go-libp2p/pull/2937)) + - fix: slice append value (#2938) ([libp2p/go-libp2p#2938](https://github.com/libp2p/go-libp2p/pull/2938)) + - webrtc: wait for listener context before dropping connection (#2932) ([libp2p/go-libp2p#2932](https://github.com/libp2p/go-libp2p/pull/2932)) + - ci: use go1.23, drop go1.21 (#2933) ([libp2p/go-libp2p#2933](https://github.com/libp2p/go-libp2p/pull/2933)) + - Fail on any test timeout (#2929) ([libp2p/go-libp2p#2929](https://github.com/libp2p/go-libp2p/pull/2929)) + - test: Try to fix test timeout (#2930) ([libp2p/go-libp2p#2930](https://github.com/libp2p/go-libp2p/pull/2930)) + - ci: Out of the tarpit (#2923) ([libp2p/go-libp2p#2923](https://github.com/libp2p/go-libp2p/pull/2923)) + - Fix proto import paths (#2920) ([libp2p/go-libp2p#2920](https://github.com/libp2p/go-libp2p/pull/2920)) + - Release v0.36.2 + - webrtc: reduce loglevel for pion logs (#2915) ([libp2p/go-libp2p#2915](https://github.com/libp2p/go-libp2p/pull/2915)) + - webrtc: close connection when remote closes (#2914) ([libp2p/go-libp2p#2914](https://github.com/libp2p/go-libp2p/pull/2914)) + - basic_host: close swarm on Close (#2916) ([libp2p/go-libp2p#2916](https://github.com/libp2p/go-libp2p/pull/2916)) + - Revert "Create funding.json" (#2919) ([libp2p/go-libp2p#2919](https://github.com/libp2p/go-libp2p/pull/2919)) + - Create funding.json + - Release v0.36.1 + - Release v0.36.0 (#2905) ([libp2p/go-libp2p#2905](https://github.com/libp2p/go-libp2p/pull/2905)) + - swarm: add a default timeout to conn.NewStream (#2907) ([libp2p/go-libp2p#2907](https://github.com/libp2p/go-libp2p/pull/2907)) + - udpmux: Don't log an error if canceled because of shutdown (#2903) ([libp2p/go-libp2p#2903](https://github.com/libp2p/go-libp2p/pull/2903)) + - ObsAddrManager: Infer external addresses for transports that share the same listening address. (#2892) ([libp2p/go-libp2p#2892](https://github.com/libp2p/go-libp2p/pull/2892)) + - feat: WebRTC reuse QUIC conn (#2889) ([libp2p/go-libp2p#2889](https://github.com/libp2p/go-libp2p/pull/2889)) + - examples/chat-with-mdns: default to a random port (#2896) ([libp2p/go-libp2p#2896](https://github.com/libp2p/go-libp2p/pull/2896)) + - allow findpeers limit to be 0 (#2894) ([libp2p/go-libp2p#2894](https://github.com/libp2p/go-libp2p/pull/2894)) + - quic: add support for quic-go metrics (#2823) ([libp2p/go-libp2p#2823](https://github.com/libp2p/go-libp2p/pull/2823)) + - webrtc: remove experimental tag, enable by default (#2887) ([libp2p/go-libp2p#2887](https://github.com/libp2p/go-libp2p/pull/2887)) + - config: fix AddrFactory for AutoNAT (#2868) ([libp2p/go-libp2p#2868](https://github.com/libp2p/go-libp2p/pull/2868)) + - chore: /quic → /quic-v1 (#2888) ([libp2p/go-libp2p#2888](https://github.com/libp2p/go-libp2p/pull/2888)) + - basichost: reset stream if SetProtocol fails (#2875) ([libp2p/go-libp2p#2875](https://github.com/libp2p/go-libp2p/pull/2875)) + - feat: libp2phttp `/http-path` (#2850) ([libp2p/go-libp2p#2850](https://github.com/libp2p/go-libp2p/pull/2850)) + - readme: update per latest multiversx rename (#2874) ([libp2p/go-libp2p#2874](https://github.com/libp2p/go-libp2p/pull/2874)) + - websocket: don't return transport.ErrListenerClosed on closing listener (#2867) ([libp2p/go-libp2p#2867](https://github.com/libp2p/go-libp2p/pull/2867)) + - Added tau to README.md (#2870) ([libp2p/go-libp2p#2870](https://github.com/libp2p/go-libp2p/pull/2870)) + - basichost: reset new stream if rcmgr blocks (#2869) ([libp2p/go-libp2p#2869](https://github.com/libp2p/go-libp2p/pull/2869)) + - transport integration tests: test conn attempt is dropped when the rcmgr blocks for WebRTC (#2856) ([libp2p/go-libp2p#2856](https://github.com/libp2p/go-libp2p/pull/2856)) + - webtransport: close underlying h3 connection (#2862) ([libp2p/go-libp2p#2862](https://github.com/libp2p/go-libp2p/pull/2862)) + - peerstore: don't intern protocols (#2860) ([libp2p/go-libp2p#2860](https://github.com/libp2p/go-libp2p/pull/2860)) + - autonatv2: add server metrics for dial requests (#2848) ([libp2p/go-libp2p#2848](https://github.com/libp2p/go-libp2p/pull/2848)) + - PR Comments + - Add a transport level test to ensure we close conns after rejecting them by the rcmgr + - Close quic conns when wrapping conn fails + - libp2p: use rcmgr for autonat dials (#2842) ([libp2p/go-libp2p#2842](https://github.com/libp2p/go-libp2p/pull/2842)) + - metricshelper: improve checks for ip and transport (#2849) ([libp2p/go-libp2p#2849](https://github.com/libp2p/go-libp2p/pull/2849)) + - Don't reuse the URL, make a new one + - Use default transport to make using the Host cheaper + - cleanup + - Add future test + - HTTP Host implements RoundTripper + - swarm: improve dial worker performance for common case + - pstoremanager: fix connectedness check + - autonatv2: implement autonatv2 spec (#2469) ([libp2p/go-libp2p#2469](https://github.com/libp2p/go-libp2p/pull/2469)) + - webrtc: add a test for establishing many connections (#2801) ([libp2p/go-libp2p#2801](https://github.com/libp2p/go-libp2p/pull/2801)) + - webrtc: fix ufrag prefix for dialing (#2832) ([libp2p/go-libp2p#2832](https://github.com/libp2p/go-libp2p/pull/2832)) + - circuitv2: improve voucher validation (#2826) ([libp2p/go-libp2p#2826](https://github.com/libp2p/go-libp2p/pull/2826)) + - libp2phttp: workaround for ResponseWriter's CloseNotifier (#2821) ([libp2p/go-libp2p#2821](https://github.com/libp2p/go-libp2p/pull/2821)) + - Update README.md (#2830) ([libp2p/go-libp2p#2830](https://github.com/libp2p/go-libp2p/pull/2830)) + - identify: add test for observed address handling (#2828) ([libp2p/go-libp2p#2828](https://github.com/libp2p/go-libp2p/pull/2828)) + - identify: fix bug in observed address handling (#2825) ([libp2p/go-libp2p#2825](https://github.com/libp2p/go-libp2p/pull/2825)) + - identify: Don't filter addr if remote is neither public nor private (#2820) ([libp2p/go-libp2p#2820](https://github.com/libp2p/go-libp2p/pull/2820)) + - limit ping duration to 30s (#1358) ([libp2p/go-libp2p#1358](https://github.com/libp2p/go-libp2p/pull/1358)) + - Remove out-dated code in example readme (#2818) ([libp2p/go-libp2p#2818](https://github.com/libp2p/go-libp2p/pull/2818)) + - v0.35.0 (#2812) ([libp2p/go-libp2p#2812](https://github.com/libp2p/go-libp2p/pull/2812)) + - rcmgr: Support specific network prefix in conn limiter (#2807) ([libp2p/go-libp2p#2807](https://github.com/libp2p/go-libp2p/pull/2807)) +- github.com/libp2p/go-libp2p-kad-dht (v0.25.2 -> v0.26.1): + - Release v0.26.1 ([libp2p/go-libp2p-kad-dht#983](https://github.com/libp2p/go-libp2p-kad-dht/pull/983)) + - fix: Unexport hasValidConnectedness to make a patch release ([libp2p/go-libp2p-kad-dht#982](https://github.com/libp2p/go-libp2p-kad-dht/pull/982)) + - correctly merging fix from https://github.com/libp2p/go-libp2p-kad-dht/pull/976 ([libp2p/go-libp2p-kad-dht#980](https://github.com/libp2p/go-libp2p-kad-dht/pull/980)) + - Release v0.26.0 ([libp2p/go-libp2p-kad-dht#979](https://github.com/libp2p/go-libp2p-kad-dht/pull/979)) + - chore: update deps ([libp2p/go-libp2p-kad-dht#974](https://github.com/libp2p/go-libp2p-kad-dht/pull/974)) + - Upgrade to go-log v2.5.1 ([libp2p/go-libp2p-kad-dht#971](https://github.com/libp2p/go-libp2p-kad-dht/pull/971)) + - Fix: don't perform lookupCheck if not enough peers in routing table ([libp2p/go-libp2p-kad-dht#970](https://github.com/libp2p/go-libp2p-kad-dht/pull/970)) + - findnode(self) should return multiple peers ([libp2p/go-libp2p-kad-dht#968](https://github.com/libp2p/go-libp2p-kad-dht/pull/968)) +- github.com/libp2p/go-libp2p-routing-helpers (v0.7.3 -> v0.7.4): + - chore: release v0.7.4 (#85) ([libp2p/go-libp2p-routing-helpers#85](https://github.com/libp2p/go-libp2p-routing-helpers/pull/85)) + - fix: composable parallel router tracing by index (#84) ([libp2p/go-libp2p-routing-helpers#84](https://github.com/libp2p/go-libp2p-routing-helpers/pull/84)) +- github.com/multiformats/go-multiaddr (v0.12.4 -> v0.13.0): + - Release v0.13.0 ([multiformats/go-multiaddr#248](https://github.com/multiformats/go-multiaddr/pull/248)) + - Add support for http-path ([multiformats/go-multiaddr#246](https://github.com/multiformats/go-multiaddr/pull/246)) +- github.com/whyrusleeping/cbor-gen (v0.1.1 -> v0.1.2): + - properly extend strings (#95) ([whyrusleeping/cbor-gen#95](https://github.com/whyrusleeping/cbor-gen/pull/95)) + - ioutil to io (#98) ([whyrusleeping/cbor-gen#98](https://github.com/whyrusleeping/cbor-gen/pull/98)) + +
+ ### 👨‍👩‍👧‍👦 Contributors + +| Contributor | Commits | Lines ± | Files Changed | +|-------------|---------|---------|---------------| +| Andrew Gillis | 14 | +4920/-1714 | 145 | +| sukun | 26 | +4402/-448 | 79 | +| Marco Munizaga | 32 | +2287/-536 | 73 | +| Marcin Rataj | 41 | +685/-193 | 86 | +| Patryk | 1 | +312/-10 | 8 | +| guillaumemichel | 7 | +134/-105 | 14 | +| Adin Schmahmann | 5 | +145/-80 | 9 | +| Henrique Dias | 2 | +190/-1 | 6 | +| Josh Klopfenstein | 1 | +90/-35 | 27 | +| gammazero | 5 | +90/-28 | 11 | +| Jeromy Johnson | 1 | +116/-0 | 5 | +| Daniel N | 3 | +27/-25 | 9 | +| Daniel Norman | 2 | +28/-19 | 4 | +| Ivan Shvedunov | 2 | +25/-10 | 2 | +| Michael Muré | 2 | +22/-9 | 4 | +| Dominic Della Valle | 1 | +23/-4 | 1 | +| Andrei Vukolov | 1 | +27/-0 | 1 | +| chris erway | 1 | +9/-9 | 9 | +| Vitaly Zdanevich | 1 | +12/-0 | 1 | +| Guillaume Michel | 1 | +4/-7 | 1 | +| swedneck | 1 | +10/-0 | 1 | +| Jorropo | 2 | +5/-5 | 3 | +| omahs | 1 | +4/-4 | 4 | +| THAT ONE GUY | 1 | +3/-5 | 2 | +| vyzo | 1 | +5/-2 | 1 | +| looklose | 1 | +3/-3 | 2 | +| web3-bot | 2 | +2/-3 | 4 | +| Dave Huseby | 1 | +5/-0 | 1 | +| shenpengfeng | 1 | +1/-1 | 1 | +| bytetigers | 1 | +1/-1 | 1 | +| Sorin Stanculeanu | 1 | +1/-1 | 1 | +| Lukáš Lukáč | 1 | +1/-1 | 1 | +| Gabe | 1 | +1/-1 | 1 | +| Bryan Stenson | 1 | +1/-1 | 1 | +| Samy Fodil | 1 | +1/-0 | 1 | +| Lane Rettig | 1 | +1/-0 | 1 | From aa355da3382f4ca2ff1fc112bae89749c515a4d6 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Wed, 11 Sep 2024 16:14:50 +0200 Subject: [PATCH 1156/1212] docs: changelog cleanup --- docs/changelogs/v0.30.md | 74 ++++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/docs/changelogs/v0.30.md b/docs/changelogs/v0.30.md index d13f2617e..5fcfb693c 100644 --- a/docs/changelogs/v0.30.md +++ b/docs/changelogs/v0.30.md @@ -9,12 +9,12 @@ - [Improved P2P connectivity](#improved-p2p-connectivity) - [Refactored Bitswap and dag-pb chunker](#refactored-bitswap-and-dag-pb-chunker) - [WebRTC-Direct Transport enabled by default](#webrtc-direct-transport-enabled-by-default) + - [UnixFS 1.5: Mode and Modification Time Support](#unixfs-15-mode-and-modification-time-support) - [AutoNAT V2 Service Introduced Alongside V1](#autonat-v2-service-introduced-alongside-v1) - [Automated `ipfs version check`](#automated-ipfs-version-check) - [Version Suffix Configuration](#version-suffix-configuration) - [`/unix/` socket support in `Addresses.API`](#unix-socket-support-in-addressesapi) - [Cleaned Up `ipfs daemon` Startup Log](#cleaned-up-ipfs-daemon-startup-log) - - [UnixFS 1.5: Mode and Modification Time Support](#unixfs-15-mode-and-modification-time-support) - [Commands Preserve Specified Hostname](#commands-preserve-specified-hostname) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -30,9 +30,9 @@ This release took longer and is more packed with fixes and features than usual. #### Improved P2P connectivity -This release comes with significant go-libp2p update from v0.34.1 to v0.36.3 ([release notes](https://github.com/ipfs/boxo/releases/)). +This release comes with significant go-libp2p update from v0.34.1 to v0.36.3 ([release notes](https://github.com/libp2p/go-libp2p/releases/)). -It includes multiple fixes to key protocols: QUIC/Webtransport/WebRTC, Connection Upgrades through Relay ([DCUtR](https://github.com/libp2p/specs/blob/master/relay/DCUtR.md)), and Secure WebSockets. +It includes multiple fixes to key protocols: [QUIC](https://github.com/libp2p/specs/tree/master/quic)/[Webtransport](https://github.com/libp2p/specs/tree/master/webtransport)/[WebRTC](https://github.com/libp2p/specs/tree/master/webrtc), Connection Upgrades through Relay ([DCUtR](https://github.com/libp2p/specs/blob/master/relay/DCUtR.md)), and [Secure WebSockets](https://github.com/libp2p/specs/pull/624). Also, peers that are behind certain types of NAT will now be more reachable. For this alone, Kubo users are highly encouraged to upgrade. @@ -45,7 +45,7 @@ Some workloads may experience improved memory profile thanks to optimizations fr #### WebRTC-Direct Transport enabled by default -Kubo now ships with `/udp/4001/webrtc-direct` listener enabled by default. +Kubo now ships with [WebRTC Direct](https://github.com/libp2p/specs/blob/master/webrtc/webrtc-direct.md) listener enabled by default: `/udp/4001/webrtc-direct`. WebRTC Direct complements existing `/wss` (Secure WebSockets) and `/webtransport` transports. Unlike `/wss`, which requires a domain name and a CA-issued TLS certificate, WebRTC Direct works with IPs and can be enabled by default on all Kubo nodes. @@ -54,9 +54,41 @@ Learn more: [`Swarm.Transports.Network.WebRTCDirect`](https://github.com/ipfs/ku > [!NOTE] > Kubo 0.30 includes a migration for existing users that adds `/webrtc-direct` listener on the same UDP port as `/udp/{port}/quic-v1`. This supports the WebRTC-Direct rollout by reusing preexisting UDP firewall settings and port mappings created for QUIC. +#### UnixFS 1.5: Mode and Modification Time Support + +Kubo now allows users to opt-in to store mode and modification time for files, directories, and symbolic links. +By default, if you do not opt-in, the old behavior remains unchanged, and the same CIDs will be generated as before. + +The `ipfs add` CLI options `--preserve-mode` and `--preserve-mtime` can be used to store the original mode and last modified time of the file being added, and `ipfs files stat /ipfs/CID` can be used for inspecting these optional attributes: + +```console +$ touch ./file +$ chmod 654 ./file +$ ipfs add --preserve-mode --preserve-mtime -Q ./file +QmczQr4XS1rRnWVopyg5Chr9EQ7JKpbhgnrjpb5kTQ1DKQ + +$ ipfs files stat /ipfs/QmczQr4XS1rRnWVopyg5Chr9EQ7JKpbhgnrjpb5kTQ1DKQ +QmczQr4XS1rRnWVopyg5Chr9EQ7JKpbhgnrjpb5kTQ1DKQ +Size: 0 +CumulativeSize: 22 +ChildBlocks: 0 +Type: file +Mode: -rw-r-xr-- (0654) +Mtime: 13 Aug 2024, 21:15:31 UTC +``` + +The CLI and HTTP RPC options `--mode`, `--mtime` and `--mtime-nsecs` can be used to set them to arbitrary values. + +Opt-in support for `mode` and `mtime` was also added to MFS (`ipfs files --help`). For more information see `--help` text of `ipfs files touch|stat|chmod` commands. + +Modification time support was also added to the Gateway. If present, value from file's dag-pb is returned in `Last-Modified` HTTP header and requests made with `If-Modified-Since` can produce HTTP 304 not modified response. + +> [!NOTE] +> Storing `mode` and `mtime` requires root block to be `dag-pb` and disabled `raw-leaves` setting to create envelope for storing the metadata. + #### AutoNAT V2 Service Introduced Alongside V1 -The AutoNAT service enables nodes to determine their public reachability on the internet. AutoNAT V2 enhances this protocol with improved features. In this release, Kubo will offer both V1 and V2 services to other peers, although it will continue to use only V1 when acting as a client. Future releases will phase out V1, transitioning clients to utilize V2 exclusively. +The AutoNAT service enables nodes to determine their public reachability on the internet. [AutoNAT V2](https://github.com/libp2p/specs/pull/538) enhances this protocol with improved features. In this release, Kubo will offer both V1 and V2 services to other peers, although it will continue to use only V1 when acting as a client. Future releases will phase out V1, transitioning clients to utilize V2 exclusively. For more details, see the [Deployment Plan for AutoNAT V2](https://github.com/ipfs/kubo/issues/10091) and [`AutoNAT`](https://github.com/ipfs/kubo/blob/master/docs/config.md#autonat) configuration options. @@ -120,38 +152,6 @@ The previous lengthy listing of all listener and announced multiaddrs has been r The output now features a simplified list of swarm listeners, displayed in the format `host:port (TCP+UDP)`, which provides essential information for debugging connectivity issues, particularly related to port forwarding. Announced libp2p addresses are no longer printed on startup, because libp2p may change or augument them based on AutoNAT, relay, and UPnP state. Instead, users are prompted to run `ipfs id` to obtain up-to-date list of listeners and announced multiaddrs in libp2p format. -#### UnixFS 1.5: Mode and Modification Time Support - -Kubo now allows users to opt-in to store mode and modification time for files, directories, and symbolic links. -By default, if you do not opt-in, the old behavior remains unchanged, and the same CIDs will be generated as before. - -The `ipfs add` CLI options `--preserve-mode` and `--preserve-mtime` can be used to store the original mode and last modified time of the file being added, and `ipfs files stat /ipfs/CID` can be used for inspecting these optional attributes: - -```console -$ touch ./file -$ chmod 654 ./file -$ ipfs add --preserve-mode --preserve-mtime -Q ./file -QmczQr4XS1rRnWVopyg5Chr9EQ7JKpbhgnrjpb5kTQ1DKQ - -$ ipfs files stat /ipfs/QmczQr4XS1rRnWVopyg5Chr9EQ7JKpbhgnrjpb5kTQ1DKQ -QmczQr4XS1rRnWVopyg5Chr9EQ7JKpbhgnrjpb5kTQ1DKQ -Size: 0 -CumulativeSize: 22 -ChildBlocks: 0 -Type: file -Mode: -rw-r-xr-- (0654) -Mtime: 13 Aug 2024, 21:15:31 UTC -``` - -The CLI and HTTP RPC options `--mode`, `--mtime` and `--mtime-nsecs` can be used to set them to arbitrary values. - -Opt-in support for `mode` and `mtime` was also added to MFS (`ipfs files --help`). For more information see `--help` text of `ipfs files touch|stat|chmod` commands. - -Modification time support was also added to the Gateway. If present, value from file's dag-pb is returned in `Last-Modified` HTTP header and requests made with `If-Modified-Since` can produce HTTP 304 not modified response. - -> [!NOTE] -> Storing `mode` and `mtime` requires root block to be `dag-pb` and disabled `raw-leaves` setting to create envelope for storing the metadata. - #### Commands Preserve Specified Hostname When executing a [CLI command](https://docs.ipfs.tech/reference/kubo/cli/) over [Kubo RPC API](https://docs.ipfs.tech/reference/kubo/rpc/), if a hostname is specified by `--api=/dns4//` the resulting HTTP request now contains the hostname, instead of the the IP address that the hostname resolved to, as was the previous behavior. This makes it easier for those trying to run Kubo behind a reverse proxy using hostname-based rules. From 3799c32971527e20400a2cf3cbb5d441d678e2bd Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Wed, 11 Sep 2024 19:01:22 +0200 Subject: [PATCH 1157/1212] chore: create next changelog (#10510) --- CHANGELOG.md | 1 + docs/changelogs/v0.31.md | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 docs/changelogs/v0.31.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 93901ba1e..fa40e1625 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ # Kubo Changelogs +- [v0.31](docs/changelogs/v0.31.md) - [v0.30](docs/changelogs/v0.30.md) - [v0.29](docs/changelogs/v0.29.md) - [v0.28](docs/changelogs/v0.28.md) diff --git a/docs/changelogs/v0.31.md b/docs/changelogs/v0.31.md new file mode 100644 index 000000000..80823816c --- /dev/null +++ b/docs/changelogs/v0.31.md @@ -0,0 +1,18 @@ +# Kubo changelog v0.31 + +- [v0.31.0](#v0310) + +## v0.31.0 + +- [Overview](#overview) +- [🔦 Highlights](#-highlights) +- [📝 Changelog](#-changelog) +- [👨‍👩‍👧‍👦 Contributors](#-contributors) + +### Overview + +### 🔦 Highlights + +### 📝 Changelog + +### 👨‍👩‍👧‍👦 Contributors From 4842d6e547955958c1832bb81d5239a7bd728267 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Wed, 11 Sep 2024 19:06:54 +0200 Subject: [PATCH 1158/1212] docs: update RELEASE_CHECKLIST.md (#10496) --- docs/EARLY_TESTERS.md | 2 +- docs/RELEASE_CHECKLIST.md | 76 +++++++++++++++++----------------- docs/RELEASE_ISSUE_TEMPLATE.md | 3 +- docs/releases_thunderdome.md | 2 +- 4 files changed, 40 insertions(+), 43 deletions(-) diff --git a/docs/EARLY_TESTERS.md b/docs/EARLY_TESTERS.md index 6c5b09b15..e3280b0eb 100644 --- a/docs/EARLY_TESTERS.md +++ b/docs/EARLY_TESTERS.md @@ -27,7 +27,7 @@ We will ask early testers to participate at two points in the process: - [ ] Infura (@MichaelMure) - [ ] OrbitDB (@haydenyoung) - [ ] Pinata (@obo20) -- [ ] PL EngRes bifrost (@cewood ns4plabs) +- [ ] Shipyard (@cewood, @ns4plabs) - [ ] Siderus (@koalalorenzo) - [ ] Textile (@sanderpick) - [ ] @RubenKelevra diff --git a/docs/RELEASE_CHECKLIST.md b/docs/RELEASE_CHECKLIST.md index 655329e1a..2e8d0605a 100644 --- a/docs/RELEASE_CHECKLIST.md +++ b/docs/RELEASE_CHECKLIST.md @@ -1,4 +1,4 @@ - + # ✅ Release Checklist (vX.Y.Z[-rcN]) @@ -62,7 +62,7 @@ This section covers tasks to be done during each release. - [example](https://github.com/ipfs/kubo/pull/9306) - [ ] Cherry-pick commits from `master` to the `release-vX.Y.Z` using `git cherry-pick -x ` - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Add full changelog and contributors to the [changelog](docs/changelogs/vX.Y.md) - - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Replace the `Changelog` and `Contributors` sections of the [changelog](docs/changelogs/vX.Y.md) with the stdout of `./bin/mkreleaselog` + - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Replace the `Changelog` and `Contributors` sections of the [changelog](docs/changelogs/vX.Y.md) with the stdout of `./bin/mkreleaselog`. Note that the command expects your `$GOPATH/src/github.com/ipfs/kubo` to include latest commits from `release-vX.Y` - do **NOT** copy the stderr - [ ] verify all CI checks on the PR from `release-vX.Y` to `release` are passing - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Merge the PR from `release-vX.Y` to `release` using the `Create a merge commit` @@ -77,40 +77,42 @@ This section covers tasks to be done during each release. - [ ] ⚠️ push the tag to GitHub using `git push origin vX.Y.Z(-RCN)` - do **NOT** use `git push --tags` because it pushes all your local tags
-- [ ] Publish the release to [DockerHub](https://hub.docker.com/r/ipfs/kubo/)
using `./kuboreleaser --skip-check-before --skip-run release --version vX.Y.Z(-rcN) publish-to-dockerhub` or ... - - [ ] Wait for [Publish docker image](https://github.com/ipfs/kubo/actions/workflows/docker-image.yml) workflow run initiated by the tag push to finish - - [ ] verify the image is available on [Docker Hub](https://hub.docker.com/r/ipfs/kubo/tags) - [ ] Verify [ipfs/distributions](https://github.com/ipfs/distributions)'s `.tool-versions`'s `golang` entry is set to the [latest go release](https://go.dev/doc/devel/release) on the major go branch [Kubo is being tested on](https://github.com/ipfs/kubo/blob/master/.github/workflows/gotest.yml) (see `go-version:`). -- [ ] Publish the release to [dist.ipfs.tech](https://dist.ipfs.tech)
using `./kuboreleaser release --version vX.Y.Z(-rcN) publish-to-distributions` or ... - - [ ] check out [ipfs/distributions](https://github.com/ipfs/distributions) - - [ ] run `./dist.sh add-version kubo vX.Y.Z(-RCN)` to add the new version to the `versions` file - - [usage](https://github.com/ipfs/distributions#usage) - - [ ] create and merge the PR which updates `dists/kubo/versions` and `dists/go-ipfs/versions` (![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) and `dists/kubo/current_version` and `dists/go-ipfs/current_version`) - - [example](https://github.com/ipfs/distributions/pull/760) - - [ ] wait for the [CI](https://github.com/ipfs/distributions/actions/workflows/main.yml) workflow run initiated by the merge to master to finish - - [ ] verify the release is available on [dist.ipfs.tech](https://dist.ipfs.tech/#kubo) -
-- [ ] Publish the release to [NPM](https://www.npmjs.com/package/go-ipfs?activeTab=versions)
using `./kuboreleaser release --version vX.Y.Z(-rcN) publish-to-npm` (⚠️ you might need to run the command a couple of times because GHA might not be able to see the new distribution straight away due to caching) or ... - - [ ] run the [Release to npm](https://github.com/ipfs/npm-go-ipfs/actions/workflows/main.yml) workflow - - [ ] check [Release to npm](https://github.com/ipfs/npm-go-ipfs/actions/workflows/main.yml) workflow run logs to verify it discovered the new release - - [ ] verify the release is available on [NPM](https://www.npmjs.com/package/go-ipfs?activeTab=versions) -
-- [ ] Publish the release to [GitHub](https://github.com/ipfs/kubo/releases)
using `./kuboreleaser release --version vX.Y.Z(-rcN) publish-to-github` or ... - - [ ] create a new release on [GitHub](https://docs.github.com/en/repositories/releasing-projects-on-github/managing-releases-in-a-repository#creating-a-release) - - [RC example](https://github.com/ipfs/kubo/releases/tag/v0.17.0-rc1) - - [FINAL example](https://github.com/ipfs/kubo/releases/tag/v0.17.0) - - [ ] use the `vX.Y.Z(-RCN)` tag - - [ ] link to the release issue - - [ ] ![](https://img.shields.io/badge/only-RC-blue?style=flat-square) link to the changelog in the description - - [ ] ![](https://img.shields.io/badge/only-RC-blue?style=flat-square) check the `This is a pre-release` checkbox - - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) copy the changelog (without the header) in the description - - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) do **NOT** check the `This is a pre-release` checkbox - - [ ] run the [sync-release-assets](https://github.com/ipfs/kubo/actions/workflows/sync-release-assets.yml) workflow - - [ ] wait for the [sync-release-assets](https://github.com/ipfs/kubo/actions/workflows/sync-release-assets.yml) workflow run to finish - - [ ] verify the release assets are present in the [GitHub release](https://github.com/ipfs/kubo/releases/tag/vX.Y.Z(-RCN)) -
-- [ ] Run Thunderdome testing, see the [Thunderdome release docs](./releases_thunderdome.md) for details - - [ ] create a PR and merge the experiment config into Thunderdome +- [ ] Publish to Dockerhub, NPM, and dist.ipfs.tech and GitHub using `./kuboreleaser --skip-check-before --skip-run release --version vX.Y.Z(-rcN) publish-to-all` or follow each step below: + - [ ] Publish the release to [DockerHub](https://hub.docker.com/r/ipfs/kubo/)
using `./kuboreleaser --skip-check-before --skip-run release --version vX.Y.Z(-rcN) publish-to-dockerhub` or ... + - [ ] Wait for [Publish docker image](https://github.com/ipfs/kubo/actions/workflows/docker-image.yml) workflow run initiated by the tag push to finish + - [ ] verify the image is available on [Docker Hub](https://hub.docker.com/r/ipfs/kubo/tags) + - [ ] Publish the release to [dist.ipfs.tech](https://dist.ipfs.tech)
using `./kuboreleaser release --version vX.Y.Z(-rcN) publish-to-distributions` or ... + - [ ] check out [ipfs/distributions](https://github.com/ipfs/distributions) + - [ ] run `./dist.sh add-version kubo vX.Y.Z(-RCN)` to add the new version to the `versions` file + - [usage](https://github.com/ipfs/distributions#usage) + - [ ] create and merge the PR which updates `dists/kubo/versions` and `dists/go-ipfs/versions` (![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) and `dists/kubo/current_version` and `dists/go-ipfs/current_version`) + - [example](https://github.com/ipfs/distributions/pull/760) + - [ ] wait for the [CI](https://github.com/ipfs/distributions/actions/workflows/main.yml) workflow run initiated by the merge to master to finish + - [ ] verify the release is available on [dist.ipfs.tech](https://dist.ipfs.tech/#kubo) +
+ - [ ] Publish the release to [NPM](https://www.npmjs.com/package/go-ipfs?activeTab=versions)
using `./kuboreleaser release --version vX.Y.Z(-rcN) publish-to-npm` (⚠️ you might need to run the command a couple of times because GHA might not be able to see the new distribution straight away due to caching) or ... + - [ ] run the [Release to npm](https://github.com/ipfs/npm-go-ipfs/actions/workflows/main.yml) workflow + - [ ] check [Release to npm](https://github.com/ipfs/npm-go-ipfs/actions/workflows/main.yml) workflow run logs to verify it discovered the new release + - [ ] verify the release is available on [NPM](https://www.npmjs.com/package/go-ipfs?activeTab=versions) +
+ - [ ] Publish the release to [GitHub](https://github.com/ipfs/kubo/releases)
using `./kuboreleaser release --version vX.Y.Z(-rcN) publish-to-github` or ... + - [ ] create a new release on [GitHub](https://docs.github.com/en/repositories/releasing-projects-on-github/managing-releases-in-a-repository#creating-a-release) + - [RC example](https://github.com/ipfs/kubo/releases/tag/v0.17.0-rc1) + - [FINAL example](https://github.com/ipfs/kubo/releases/tag/v0.17.0) + - [ ] use the `vX.Y.Z(-RCN)` tag + - [ ] link to the release issue + - [ ] ![](https://img.shields.io/badge/only-RC-blue?style=flat-square) link to the changelog in the description + - [ ] ![](https://img.shields.io/badge/only-RC-blue?style=flat-square) check the `This is a pre-release` checkbox + - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) copy the changelog (without the header) in the description + - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) do **NOT** check the `This is a pre-release` checkbox + - [ ] run the [sync-release-assets](https://github.com/ipfs/kubo/actions/workflows/sync-release-assets.yml) workflow + - [ ] wait for the [sync-release-assets](https://github.com/ipfs/kubo/actions/workflows/sync-release-assets.yml) workflow run to finish + - [ ] verify the release assets are present in the [GitHub release](https://github.com/ipfs/kubo/releases/tag/vX.Y.Z(-RCN)) +
+- [ ] Update Kubo staging environment, see the [Running Kubo tests on staging](https://www.notion.so/Running-Kubo-tests-on-staging-488578bb46154f9bad982e4205621af8) for details. + - [ ] ![](https://img.shields.io/badge/only-RC-blue?style=flat-square) Test last release against the current RC + - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Test last release against the current one - [ ] Promote the release
using `./kuboreleaser release --version vX.Y.Z(-rcN) promote` or ... - [ ] create an [IPFS Discourse](https://discuss.ipfs.tech) topic - [prerelease example](https://discuss.ipfs.tech/t/kubo-v0-16-0-rc1-release-candidate-is-out/15248) @@ -151,10 +153,6 @@ This section covers tasks to be done during each release. - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) run the [update-on-new-ipfs-tag.yml](https://github.com/ipfs/ipfs-docs/actions/workflows/update-on-new-ipfs-tag.yml) workflow - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) merge the PR created by the [update-on-new-ipfs-tag.yml](https://github.com/ipfs/ipfs-docs/actions/workflows/update-on-new-ipfs-tag.yml) workflow run
-- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Ask Brave to update Kubo in Brave Desktop - - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) use [this link](https://github.com/brave/brave-browser/issues/new?assignees=&labels=OS%2FDesktop&projects=&template=desktop.md&title=) to create an issue for the new Kubo version - - [basic example](https://github.com/brave/brave-browser/issues/31453), [example with additional notes](https://github.com/brave/brave-browser/issues/27965) - - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) post link to the issue in `#shared-pl-brave` for visibility - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) Create a blog entry on [blog.ipfs.tech](https://blog.ipfs.tech)
using `./kuboreleaser release --version vX.Y.Z(-rcN) update-ipfs-blog --date YYYY-MM-DD` or ... - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) create a PR which adds a release note for the new Kubo version - [example](https://github.com/ipfs/ipfs-blog/pull/529) diff --git a/docs/RELEASE_ISSUE_TEMPLATE.md b/docs/RELEASE_ISSUE_TEMPLATE.md index cfa975943..321026ea6 100644 --- a/docs/RELEASE_ISSUE_TEMPLATE.md +++ b/docs/RELEASE_ISSUE_TEMPLATE.md @@ -1,4 +1,4 @@ - + # Items to do upon creating the release issue @@ -22,7 +22,6 @@ * Expected RC date: week of YYYY-MM-DD * 🚢 Expected final release date: YYYY-MM-DD * Release PR: -* Thunderdome PR: * Accompanying PR for improving the release process: ([example](https://github.com/ipfs/kubo/pull/9391)) * Changelog: https://github.com/ipfs/kubo/blob/master/docs/changelogs/vX.Y.md diff --git a/docs/releases_thunderdome.md b/docs/releases_thunderdome.md index 11057e26a..53034b3bb 100644 --- a/docs/releases_thunderdome.md +++ b/docs/releases_thunderdome.md @@ -50,7 +50,7 @@ This will build the Docker images, upload them to ECR, and then launch the exper ## Analyze Results -Add a log entry in https://www.notion.so/pl-strflt/ce2d1bd56f3541028d960d3711465659 and link to it from the release issue, so that experiment results are publicly visible. +Add a log entry in https://www.notion.so/ceb2047e79f2498494077a2739a6c493 and link to it from the release issue, so that experiment results are publicly visible. The `deploy` command will output a link to the Grafana dashboard for the experiment. We don't currently have rigorous acceptance criteria, so you should look for anomalies or changes in the metrics and make sure they are tolerable and explainable. Unexplainable anomalies should be noted in the log with a screenshot, and then root caused. From b71cf0d15904bdef21fe2eee5f1118a274309a4d Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Tue, 17 Sep 2024 14:56:35 +0200 Subject: [PATCH 1159/1212] chore: switch back to release @helia/interop (#10516) Context: https://github.com/ipfs/helia/pull/584#issuecomment-2343839607 --- .github/workflows/interop.yml | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/.github/workflows/interop.yml b/.github/workflows/interop.yml index 73ee25555..2967c9997 100644 --- a/.github/workflows/interop.yml +++ b/.github/workflows/interop.yml @@ -70,27 +70,9 @@ jobs: restore-keys: ${{ runner.os }}-${{ github.job }}-helia- - run: sudo apt update - run: sudo apt install -y libxkbcommon0 libxdamage1 libgbm1 libpango-1.0-0 libcairo2 # dependencies for playwright - - # TODO: for now run against version from https://github.com/ipfs/helia/pull/584 - - name: Checkout helia-interop with provisional fix - uses: actions/checkout@v4 - with: - repository: ipfs/helia - ref: ab6b385787075ad9932f24362293b3bb82ff1d96 - path: helia - - name: Run provisional build of helia - run: npm i && npm run build - working-directory: helia - - name: Run provisional build of helia-interop - run: npm i && npm run build && npx . - working-directory: helia/packages/interop + - run: npx --package @helia/interop helia-interop env: KUBO_BINARY: ${{ github.workspace }}/cmd/ipfs/ipfs - - # TODO: switch back to release once https://github.com/ipfs/helia/pull/584 ships - #- run: npx --package @helia/interop helia-interop - # env: - # KUBO_BINARY: ${{ github.workspace }}/cmd/ipfs/ipfs ipfs-webui: needs: [interop-prep] runs-on: ${{ fromJSON(github.repository == 'ipfs/kubo' && '["self-hosted", "linux", "x64", "2xlarge"]' || '"ubuntu-latest"') }} From 60588afc9eaae23d9e8da3996f2fe7e101b5721d Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Fri, 20 Sep 2024 15:40:45 +0200 Subject: [PATCH 1160/1212] docs(config): improve profile descriptions (#10517) * docs(config): improve profile descriptions * chore: move profiles and types to the end --- config/profile.go | 15 +- docs/config.md | 399 ++++++++++++++++++++++++--------------------- docs/datastores.md | 6 + 3 files changed, 224 insertions(+), 196 deletions(-) diff --git a/config/profile.go b/config/profile.go index c73b05af2..63e76d8ec 100644 --- a/config/profile.go +++ b/config/profile.go @@ -124,7 +124,7 @@ This profile may only be applied when first initializing the node. "flatfs": { Description: `Configures the node to use the flatfs datastore. -This is the most battle-tested and reliable datastore. +This is the most battle-tested and reliable datastore. You should use this datastore if: * You need a very simple and very reliable datastore, and you trust your @@ -145,21 +145,20 @@ This profile may only be applied when first initializing the node. }, }, "badgerds": { - Description: `Configures the node to use the experimental badger datastore. + Description: `Configures the node to use the legacy badgerv1 datastore. -Use this datastore if some aspects of performance, -especially the speed of adding many gigabytes of files, are critical. -However, be aware that: +NOTE: this is badger 1.x, which has known bugs and is no longer supported by the upstream team. +It is provided here only for pre-existing users, allowing them to migrate away to more modern datastore. + +Other caveats: * This datastore will not properly reclaim space when your datastore is smaller than several gigabytes. If you run IPFS with --enable-gc, you plan on storing very little data in your IPFS node, and disk usage is more critical than performance, consider using flatfs. -* This datastore uses up to several gigabytes of memory. +* This datastore uses up to several gigabytes of memory. * Good for medium-size datastores, but may run into performance issues if your dataset is bigger than a terabyte. -* The current implementation is based on old badger 1.x - which is no longer supported by the upstream team. This profile may only be applied when first initializing the node.`, diff --git a/docs/config.md b/docs/config.md index 107050927..26f712d3a 100644 --- a/docs/config.md +++ b/docs/config.md @@ -9,16 +9,6 @@ config file at runtime. - [The Kubo config file](#the-kubo-config-file) - [Table of Contents](#table-of-contents) - - [Profiles](#profiles) - - [Types](#types) - - [`flag`](#flag) - - [`priority`](#priority) - - [`strings`](#strings) - - [`duration`](#duration) - - [`optionalInteger`](#optionalinteger) - - [`optionalBytes`](#optionalbytes) - - [`optionalString`](#optionalstring) - - [`optionalDuration`](#optionalduration) - [`Addresses`](#addresses) - [`Addresses.API`](#addressesapi) - [`Addresses.Gateway`](#addressesgateway) @@ -184,184 +174,26 @@ config file at runtime. - [`Version.AgentSuffix`](#versionagentsuffix) - [`Version.SwarmCheckEnabled`](#versionswarmcheckenabled) - [`Version.SwarmCheckPercentThreshold`](#versionswarmcheckpercentthreshold) - -## Profiles - -Configuration profiles allow to tweak configuration quickly. Profiles can be -applied with the `--profile` flag to `ipfs init` or with the `ipfs config profile -apply` command. When a profile is applied a backup of the configuration file -will be created in `$IPFS_PATH`. - -The available configuration profiles are listed below. You can also find them -documented in `ipfs config profile --help`. - -- `server` - - Disables local host discovery, recommended when - running IPFS on machines with public IPv4 addresses. - -- `randomports` - - Use a random port number for the incoming swarm connections. - -- `default-datastore` - - Configures the node to use the default datastore (flatfs). - - Read the "flatfs" profile description for more information on this datastore. - - This profile may only be applied when first initializing the node. - -- `local-discovery` - - Enables local discovery (enabled by default). Useful to re-enable local discovery after it's - disabled by another profile (e.g., the server profile). - -- `test` - - Reduces external interference of IPFS daemon, this - is useful when using the daemon in test environments. - -- `default-networking` - - Restores default network settings. - Inverse profile of the test profile. - -- `flatfs` - - Configures the node to use the flatfs datastore. Flatfs is the default datastore. - - This is the most battle-tested and reliable datastore. - You should use this datastore if: - - - You need a very simple and very reliable datastore, and you trust your - filesystem. This datastore stores each block as a separate file in the - underlying filesystem so it's unlikely to lose data unless there's an issue - with the underlying file system. - - You need to run garbage collection in a way that reclaims free space as soon as possible. - - You want to minimize memory usage. - - You are ok with the default speed of data import, or prefer to use `--nocopy`. - - This profile may only be applied when first initializing the node. - - -- `badgerds` - - Configures the node to use the experimental badger datastore. Keep in mind that this **uses an outdated badger 1.x**. - - Use this datastore if some aspects of performance, - especially the speed of adding many gigabytes of files, are critical. However, be aware that: - - - This datastore will not properly reclaim space when your datastore is - smaller than several gigabytes. If you run IPFS with `--enable-gc`, you plan on storing very little data in - your IPFS node, and disk usage is more critical than performance, consider using - `flatfs`. - - This datastore uses up to several gigabytes of memory. - - Good for medium-size datastores, but may run into performance issues if your dataset is bigger than a terabyte. - - The current implementation is based on old badger 1.x which is no longer supported by the upstream team. - - This profile may only be applied when first initializing the node. - -- `lowpower` - - Reduces daemon overhead on the system. Affects node - functionality - performance of content discovery and data - fetching may be degraded. Local data won't be announced on routing systems like Amino DHT. - - - `Swarm.ConnMgr` set to maintain minimum number of p2p connections at a time. - - Disables [`Reprovider`](#reprovider) service → no CID will be announced on Amino DHT and other routing systems(!) - - Disables AutoNAT. - - Use this profile with caution. - -- `legacy-cid-v0` - - Makes UnixFS import (`ipfs add`) produce legacy CIDv0 with no raw leaves, sha2-256 and 256 KiB chunks. - - > [!WARNING] - > This profile is provided for legacy users and should not be used for new projects. - -- `test-cid-v1` - - Makes UnixFS import (`ipfs add`) produce modern CIDv1 with raw leaves, sha2-256 and 1 MiB chunks. - - > [!NOTE] - > This profile will become the new implicit default, provided for testing purposes. - > Follow [kubo#4143](https://github.com/ipfs/kubo/issues/4143) for more details. - -## Types - -This document refers to the standard JSON types (e.g., `null`, `string`, -`number`, etc.), as well as a few custom types, described below. - -### `flag` - -Flags allow enabling and disabling features. However, unlike simple booleans, -they can also be `null` (or omitted) to indicate that the default value should -be chosen. This makes it easier for Kubo to change the defaults in the -future unless the user _explicitly_ sets the flag to either `true` (enabled) or -`false` (disabled). Flags have three possible states: - -- `null` or missing (apply the default value). -- `true` (enabled) -- `false` (disabled) - -### `priority` - -Priorities allow specifying the priority of a feature/protocol and disabling the -feature/protocol. Priorities can take one of the following values: - -- `null`/missing (apply the default priority, same as with flags) -- `false` (disabled) -- `1 - 2^63` (priority, lower is preferred) - -### `strings` - -Strings is a special type for conveniently specifying a single string, an array -of strings, or null: - -- `null` -- `"a single string"` -- `["an", "array", "of", "strings"]` - -### `duration` - -Duration is a type for describing lengths of time, using the same format go -does (e.g, `"1d2h4m40.01s"`). - -### `optionalInteger` - -Optional integers allow specifying some numerical value which has -an implicit default when missing from the config file: - -- `null`/missing will apply the default value defined in Kubo sources (`.WithDefault(value)`) -- an integer between `-2^63` and `2^63-1` (i.e. `-9223372036854775808` to `9223372036854775807`) - -### `optionalBytes` - -Optional Bytes allow specifying some number of bytes which has -an implicit default when missing from the config file: - -- `null`/missing (apply the default value defined in Kubo sources) -- a string value indicating the number of bytes, including human readable representations: - - [SI sizes](https://en.wikipedia.org/wiki/Metric_prefix#List_of_SI_prefixes) (metric units, powers of 1000), e.g. `1B`, `2kB`, `3MB`, `4GB`, `5TB`, …) - - [IEC sizes](https://en.wikipedia.org/wiki/Binary_prefix#IEC_prefixes) (binary units, powers of 1024), e.g. `1B`, `2KiB`, `3MiB`, `4GiB`, `5TiB`, …) - -### `optionalString` - -Optional strings allow specifying some string value which has -an implicit default when missing from the config file: - -- `null`/missing will apply the default value defined in Kubo sources (`.WithDefault("value")`) -- a string - -### `optionalDuration` - -Optional durations allow specifying some duration value which has -an implicit default when missing from the config file: - -- `null`/missing will apply the default value defined in Kubo sources (`.WithDefault("1h2m3s")`) -- a string with a valid [go duration](#duration) (e.g, `"1d2h4m40.01s"`). + - [Profiles](#profiles) + - [`server` profile](#server-profile) + - [`randomports` profile](#randomports-profile) + - [`default-datastore` profile](#default-datastore-profile) + - [`local-discovery` profile](#local-discovery-profile) + - [`default-networking` profile](#default-networking-profile) + - [`flatfs` profile](#flatfs-profile) + - [`badgerds` profile](#badgerds-profile) + - [`lowpower` profile](#lowpower-profile) + - [`legacy-cid-v0` profile](#legacy-cid-v0-profile) + - [`test-cid-v1` profile](#test-cid-v1-profile) + - [Types](#types) + - [`flag`](#flag) + - [`priority`](#priority) + - [`strings`](#strings) + - [`duration`](#duration) + - [`optionalInteger`](#optionalinteger) + - [`optionalBytes`](#optionalbytes) + - [`optionalString`](#optionalstring) + - [`optionalDuration`](#optionalduration) ## `Addresses` @@ -2491,3 +2323,194 @@ trigger update warning. Default: `5` Type: `optionalInteger` (1-100) + +## Profiles + +Configuration profiles allow to tweak configuration quickly. Profiles can be +applied with the `--profile` flag to `ipfs init` or with the `ipfs config profile +apply` command. When a profile is applied a backup of the configuration file +will be created in `$IPFS_PATH`. + +Configuration profiles can be applied additively. For example, both the `test-cid-v1` and `lowpower` profiles can be applied one after the other. +The available configuration profiles are listed below. You can also find them +documented in `ipfs config profile --help`. + +### `server` profile + +Disables local [`Discovery.MDNS`](#discoverymdns) and blocks connections to +IPv4 and IPv6 prefixes that are [private, local only, or unrouteable](https://github.com/ipfs/kubo/blob/b71cf0d15904bdef21fe2eee5f1118a274309a4d/config/profile.go#L24-L43). + +Recommended when running IPFS on machines with public IPv4 addresses +at providers that interpret local IPFS discovery and traffic as netscan abuse ([example](https://github.com/ipfs/kubo/issues/10327)). + +### `randomports` profile + +Use a random port number for the incoming swarm connections. +Used for testing. + +### `default-datastore` profile + +Configures the node to use the default datastore (flatfs). + +Read the "flatfs" profile description for more information on this datastore. + +This profile may only be applied when first initializing the node. + +### `local-discovery` profile + +Enables local [`Discovery.MDNS`](#discoverymdns) (enabled by default). + +Useful to re-enable local discovery after it's disabled by another profile +(e.g., the server profile). + +`test` profile + +Reduces external interference of IPFS daemon, this +is useful when using the daemon in test environments. + +### `default-networking` profile + +Restores default network settings. +Inverse profile of the test profile. + +### `flatfs` profile + +Configures the node to use the flatfs datastore. Flatfs is the default datastore. + +This is the most battle-tested and reliable datastore. +You should use this datastore if: + +- You need a very simple and very reliable datastore, and you trust your + filesystem. This datastore stores each block as a separate file in the + underlying filesystem so it's unlikely to lose data unless there's an issue + with the underlying file system. +- You need to run garbage collection in a way that reclaims free space as soon as possible. +- You want to minimize memory usage. +- You are ok with the default speed of data import, or prefer to use `--nocopy`. + +This profile may only be applied when first initializing the node. + +### `badgerds` profile + +Configures the node to use the legacy badgerv1 datastore. + +> [!CAUTION] +> This is based on very old badger 1.x, which has known bugs and is no longer supported by the upstream team. +> It is provided here only for pre-existing users, allowing them to migrate away to more modern datastore. +> Do not use it for new deployments, unless you really, really know what you are doing. + +Also, be aware that: + +- This datastore will not properly reclaim space when your datastore is + smaller than several gigabytes. If you run IPFS with `--enable-gc`, you plan on storing very little data in + your IPFS node, and disk usage is more critical than performance, consider using + `flatfs`. +- This datastore uses up to several gigabytes of memory. +- Good for medium-size datastores, but may run into performance issues if your dataset is bigger than a terabyte. +- The current implementation is based on old badger 1.x which is no longer supported by the upstream team. + +This profile may only be applied when first initializing the node. + +### `lowpower` profile + +Reduces daemon overhead on the system. Affects node +functionality - performance of content discovery and data +fetching may be degraded. + +> [!CAUTION] +> Local data won't be announced on routing systems like Amino DHT. + +- `Swarm.ConnMgr` set to maintain minimum number of p2p connections at a time. +- Disables [`Reprovider`](#reprovider) service → no CID will be announced on Amino DHT and other routing systems(!) +- Disables [`AutoNAT`](#autonat). + +Use this profile with caution. + +### `legacy-cid-v0` profile + +Makes UnixFS import (`ipfs add`) produce legacy CIDv0 with no raw leaves, sha2-256 and 256 KiB chunks. + +> [!NOTE] +> This profile is provided for legacy users and should not be used for new projects. + +### `test-cid-v1` profile + +Makes UnixFS import (`ipfs add`) produce modern CIDv1 with raw leaves, sha2-256 and 1 MiB chunks. + +> [!NOTE] +> This profile will become the new implicit default, provided for testing purposes. +> Follow [kubo#4143](https://github.com/ipfs/kubo/issues/4143) for more details. + +## Types + +This document refers to the standard JSON types (e.g., `null`, `string`, +`number`, etc.), as well as a few custom types, described below. + +### `flag` + +Flags allow enabling and disabling features. However, unlike simple booleans, +they can also be `null` (or omitted) to indicate that the default value should +be chosen. This makes it easier for Kubo to change the defaults in the +future unless the user _explicitly_ sets the flag to either `true` (enabled) or +`false` (disabled). Flags have three possible states: + +- `null` or missing (apply the default value). +- `true` (enabled) +- `false` (disabled) + +### `priority` + +Priorities allow specifying the priority of a feature/protocol and disabling the +feature/protocol. Priorities can take one of the following values: + +- `null`/missing (apply the default priority, same as with flags) +- `false` (disabled) +- `1 - 2^63` (priority, lower is preferred) + +### `strings` + +Strings is a special type for conveniently specifying a single string, an array +of strings, or null: + +- `null` +- `"a single string"` +- `["an", "array", "of", "strings"]` + +### `duration` + +Duration is a type for describing lengths of time, using the same format go +does (e.g, `"1d2h4m40.01s"`). + +### `optionalInteger` + +Optional integers allow specifying some numerical value which has +an implicit default when missing from the config file: + +- `null`/missing will apply the default value defined in Kubo sources (`.WithDefault(value)`) +- an integer between `-2^63` and `2^63-1` (i.e. `-9223372036854775808` to `9223372036854775807`) + +### `optionalBytes` + +Optional Bytes allow specifying some number of bytes which has +an implicit default when missing from the config file: + +- `null`/missing (apply the default value defined in Kubo sources) +- a string value indicating the number of bytes, including human readable representations: + - [SI sizes](https://en.wikipedia.org/wiki/Metric_prefix#List_of_SI_prefixes) (metric units, powers of 1000), e.g. `1B`, `2kB`, `3MB`, `4GB`, `5TB`, …) + - [IEC sizes](https://en.wikipedia.org/wiki/Binary_prefix#IEC_prefixes) (binary units, powers of 1024), e.g. `1B`, `2KiB`, `3MiB`, `4GiB`, `5TiB`, …) + +### `optionalString` + +Optional strings allow specifying some string value which has +an implicit default when missing from the config file: + +- `null`/missing will apply the default value defined in Kubo sources (`.WithDefault("value")`) +- a string + +### `optionalDuration` + +Optional durations allow specifying some duration value which has +an implicit default when missing from the config file: + +- `null`/missing will apply the default value defined in Kubo sources (`.WithDefault("1h2m3s")`) +- a string with a valid [go duration](#duration) (e.g, `"1d2h4m40.01s"`). diff --git a/docs/datastores.md b/docs/datastores.md index ccedce4c7..c18ecb0c7 100644 --- a/docs/datastores.md +++ b/docs/datastores.md @@ -39,6 +39,12 @@ Uses a leveldb database to store key value pairs. Uses [badger](https://github.com/dgraph-io/badger) as a key value store. +> [!CAUTION] +> This is based on very old badger 1.x, which has known bugs and is no longer supported by the upstream team. +> It is provided here only for pre-existing users, allowing them to migrate away to more modern datastore. +> Do not use it for new deployments, unless you really, really know what you are doing. + + * `syncWrites`: Flush every write to disk before continuing. Setting this to false is safe as kubo will automatically flush writes to disk before and after performing critical operations like pinning. However, you can set this to true to be extra-safe (at the cost of a 2-3x slowdown when adding files). * `truncate`: Truncate the DB if a partially written sector is found (defaults to true). There is no good reason to set this to false unless you want to manually recover partially written (and unpinned) blocks if kubo crashes half-way through adding a file. From 58434ecbd15a34fcac0a1ddfa2e43a02df7eb2b8 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Fri, 20 Sep 2024 15:54:41 +0200 Subject: [PATCH 1161/1212] docs(config): add useful references --- docs/config.md | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/docs/config.md b/docs/config.md index 26f712d3a..adbbb0bdc 100644 --- a/docs/config.md +++ b/docs/config.md @@ -278,6 +278,12 @@ Type: `array[string]` (multiaddrs) An array of swarm addresses not to announce to the network. Takes precedence over `Addresses.Announce` and `Addresses.AppendAnnounce`. +> [!TIP] +> The [`server` configuration profile](#server-profile) fills up this list with sensible defaults, +> preventing announcement of non-routable IP addresses (e.g., `/ip4/192.168.0.0/ipcidr/16`, +> which is the multiaddress representation of `192.168.0.0/16`) but you should always +> check settings against your own network and/or hosting provider. + Default: `[]` Type: `array[string]` (multiaddrs) @@ -1645,10 +1651,11 @@ node will try to connect to one or more private IP addresses whenever dialing another node, even if this other node is on a different network. This may trigger netscan alerts on some hosting providers or cause strain in some setups. -The `server` configuration profile fills up this list with sensible defaults, -preventing dials to all non-routable IP addresses (e.g., `/ip4/192.168.0.0/ipcidr/16`, -which is the multiaddress representation of `192.168.0.0/16`) but you should always -check settings against your own network and/or hosting provider. +> [!TIP] +> The [`server` configuration profile](#server-profile) fills up this list with sensible defaults, +> preventing dials to all non-routable IP addresses (e.g., `/ip4/192.168.0.0/ipcidr/16`, +> which is the multiaddress representation of `192.168.0.0/16`) but you should always +> check settings against your own network and/or hosting provider. Default: `[]` @@ -1666,7 +1673,7 @@ Type: `bool` ### `Swarm.DisableNatPortMap` -Disable automatic NAT port forwarding. +Disable automatic NAT port forwarding (turn off [UPnP](https://en.wikipedia.org/wiki/Universal_Plug_and_Play)). When not disabled (default), Kubo asks NAT devices (e.g., routers), to open up an external port and forward it to the port Kubo is running on. When this @@ -2337,10 +2344,10 @@ documented in `ipfs config profile --help`. ### `server` profile -Disables local [`Discovery.MDNS`](#discoverymdns) and blocks connections to +Disables local [`Discovery.MDNS`](#discoverymdns), [turns off uPnP NAT port mapping](#swarmdisablenatportmap), and blocks connections to IPv4 and IPv6 prefixes that are [private, local only, or unrouteable](https://github.com/ipfs/kubo/blob/b71cf0d15904bdef21fe2eee5f1118a274309a4d/config/profile.go#L24-L43). -Recommended when running IPFS on machines with public IPv4 addresses +Recommended when running IPFS on machines with public IPv4 addresses (no NAT, no uPnP) at providers that interpret local IPFS discovery and traffic as netscan abuse ([example](https://github.com/ipfs/kubo/issues/10327)). ### `randomports` profile From ce23fc7cccf1bea7ba0e93900b3654d2b879cad9 Mon Sep 17 00:00:00 2001 From: Russell Dempsey <1173416+SgtPooki@users.noreply.github.com> Date: Tue, 24 Sep 2024 23:26:51 +0200 Subject: [PATCH 1162/1212] feat: ipfs-webui v4.3.2 (#10523) https://github.com/ipfs/ipfs-webui/releases/tag/v4.3.1 https://github.com/ipfs/ipfs-webui/releases/tag/v4.3.2 --------- Co-authored-by: Marcin Rataj --- core/corehttp/webui.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/corehttp/webui.go b/core/corehttp/webui.go index 82520e30d..2117d78af 100644 --- a/core/corehttp/webui.go +++ b/core/corehttp/webui.go @@ -1,11 +1,12 @@ package corehttp // WebUI version confirmed to work with this Kubo version -const WebUIPath = "/ipfs/bafybeihatzsgposbr3hrngo42yckdyqcc56yean2rynnwpzxstvdlphxf4" // v4.3.0 +const WebUIPath = "/ipfs/bafybeif6abowqcavbkz243biyh7pde7ick5kkwwytrh7pd2hkbtuqysjxy" // v4.3.2 // WebUIPaths is a list of all past webUI paths. var WebUIPaths = []string{ WebUIPath, + "/ipfs/bafybeihatzsgposbr3hrngo42yckdyqcc56yean2rynnwpzxstvdlphxf4", "/ipfs/bafybeigggyffcf6yfhx5irtwzx3cgnk6n3dwylkvcpckzhqqrigsxowjwe", "/ipfs/bafybeidf7cpkwsjkq6xs3r6fbbxghbugilx3jtezbza7gua3k5wjixpmba", "/ipfs/bafybeiamycmd52xvg6k3nzr6z3n33de6a2teyhquhj4kspdtnvetnkrfim", From 43ba17bca25b1f792eed37f05bd0ebb272025168 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Thu, 26 Sep 2024 19:01:05 +0200 Subject: [PATCH 1163/1212] chore: clarify dep update in RELEASE_CHECKLIST.md (#10518) Co-authored-by: Andrew Gillis <11790789+gammazero@users.noreply.github.com> --- docs/RELEASE_CHECKLIST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/RELEASE_CHECKLIST.md b/docs/RELEASE_CHECKLIST.md index 2e8d0605a..476c77b15 100644 --- a/docs/RELEASE_CHECKLIST.md +++ b/docs/RELEASE_CHECKLIST.md @@ -170,7 +170,7 @@ This section covers tasks to be done during each release.
- [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) Create a dependency update PR - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) check out [ipfs/kubo](https://github.com/ipfs/kubo) - - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) run `go get -u` in root directory + - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) go over direct dependencies from `go.mod` in the root directory (NOTE: do not run `go get -u` as it will upgrade indirect dependencies which may cause problems) - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) run `make mod_tidy` - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) create a PR which updates `go.mod` and `go.sum` - [ ] ![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) ![](https://img.shields.io/badge/not-PATCH-yellow?style=flat-square) add the PR to the next release milestone From 836d51650dac34a2b1f6447c3f195fbc5e9920bf Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Thu, 26 Sep 2024 19:31:36 +0200 Subject: [PATCH 1164/1212] docs: clarify Gateway.PublicGateways (#10525) * docs: clarify Gateway.PublicGateways * docs: caution about reusing domains --- docs/config.md | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/docs/config.md b/docs/config.md index adbbb0bdc..5500128ab 100644 --- a/docs/config.md +++ b/docs/config.md @@ -682,7 +682,18 @@ We are working on developing a modern replacement. To support our efforts, pleas ### `Gateway.PublicGateways` -`PublicGateways` is a dictionary for defining gateway behavior on specified hostnames. +> [!IMPORTANT] +> This configuration is **NOT** for HTTP Client, it is for HTTP Server – use this ONLY if you want to run your own IPFS gateway. + +`PublicGateways` is a configuration map used for dictionary for customizing gateway behavior +on specified hostnames that point at your Kubo instance. + +It is useful when you want to run [Path gateway](https://specs.ipfs.tech/http-gateways/path-gateway/) on `example.com/ipfs/cid`, +and [Subdomain gateway](https://specs.ipfs.tech/http-gateways/subdomain-gateway/) on `cid.ipfs.example.org`, +or limit `verifiable.example.net` to response types defined in [Trustless Gateway](https://specs.ipfs.tech/http-gateways/trustless-gateway/) specification. + +> [!CAUTION] +> Keys (Hostnames) MUST be unique. Do not use the same parent domain for multiple gateway types, it will break origin isolation. Hostnames can optionally be defined with one or more wildcards. @@ -715,7 +726,9 @@ Type: `array[string]` #### `Gateway.PublicGateways: UseSubdomains` -A boolean to configure whether the gateway at the hostname provides [Origin isolation](https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy) +A boolean to configure whether the gateway at the hostname should be +a [Subdomain Gateway](https://specs.ipfs.tech/http-gateways/subdomain-gateway/) +and provide [Origin isolation](https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy) between content roots. - `true` - enables [subdomain gateway](https://docs.ipfs.tech/how-to/address-ipfs-on-web/#subdomain-gateway) at `http://*.{hostname}/` @@ -764,7 +777,7 @@ Type: `bool` An optional flag to explicitly configure whether subdomain gateway's redirects (enabled by `UseSubdomains: true`) should always inline a DNSLink name (FQDN) -into a single DNS label: +into a single DNS label ([specification](https://specs.ipfs.tech/http-gateways/subdomain-gateway/#host-request-header)): ``` //example.com/ipns/example.net → HTTP 301 → //example-net.ipns.example.com @@ -783,8 +796,14 @@ Type: `flag` #### `Gateway.PublicGateways: DeserializedResponses` An optional flag to explicitly configure whether this gateway responds to deserialized -requests, or not. By default, it is enabled. When disabling this option, the gateway -operates as a Trustless Gateway only: https://specs.ipfs.tech/http-gateways/trustless-gateway/. +requests, or not. By default, it is enabled. + +When disabled, the gateway operates strictly as a [Trustless Gateway](https://specs.ipfs.tech/http-gateways/trustless-gateway/). + +> [!TIP] +> Disabling deserialized responses will protect you from acting as a free web hosting, +> while still allowing trustless clients like [@helia/verified-fetch](https://www.npmjs.com/package/@helia/verified-fetch) +> to utilize it for [trustless, verifiable data retrieval](https://docs.ipfs.tech/reference/http/gateway/#trustless-verifiable-retrieval). Default: same as global `Gateway.DeserializedResponses` From ca4f486781a6ddc3c3aa98ae78314d06b11a1bb0 Mon Sep 17 00:00:00 2001 From: Andrew Gillis <11790789+gammazero@users.noreply.github.com> Date: Fri, 27 Sep 2024 06:37:47 -0700 Subject: [PATCH 1165/1212] refactor: simplify logic for MFS pinning (#10506) --- cmd/ipfs/kubo/daemon.go | 2 +- cmd/ipfs/kubo/pinmfs.go | 167 +++++++++++++-------------------- cmd/ipfs/kubo/pinmfs_test.go | 90 +++++++++++++----- core/commands/pin/remotepin.go | 11 ++- 4 files changed, 141 insertions(+), 129 deletions(-) diff --git a/cmd/ipfs/kubo/daemon.go b/cmd/ipfs/kubo/daemon.go index eb9fff8e4..0e5637cdb 100644 --- a/cmd/ipfs/kubo/daemon.go +++ b/cmd/ipfs/kubo/daemon.go @@ -586,7 +586,7 @@ take effect. prometheus.MustRegister(&corehttp.IpfsNodeCollector{Node: node}) // start MFS pinning thread - startPinMFS(daemonConfigPollInterval, cctx, &ipfsPinMFSNode{node}) + startPinMFS(cctx, daemonConfigPollInterval, &ipfsPinMFSNode{node}) // The daemon is *finally* ready. fmt.Printf("Daemon is ready\n") diff --git a/cmd/ipfs/kubo/pinmfs.go b/cmd/ipfs/kubo/pinmfs.go index 846ee8a77..c9187145c 100644 --- a/cmd/ipfs/kubo/pinmfs.go +++ b/cmd/ipfs/kubo/pinmfs.go @@ -12,7 +12,7 @@ import ( pinclient "github.com/ipfs/boxo/pinning/remote/client" cid "github.com/ipfs/go-cid" ipld "github.com/ipfs/go-ipld-format" - logging "github.com/ipfs/go-log" + logging "github.com/ipfs/go-log/v2" config "github.com/ipfs/kubo/config" "github.com/ipfs/kubo/core" @@ -40,6 +40,7 @@ func init() { d, err := time.ParseDuration(pollDurStr) if err != nil { mfslog.Error("error parsing MFS_PIN_POLL_INTERVAL, using default:", err) + return } daemonConfigPollInterval = d } @@ -74,56 +75,28 @@ func (x *ipfsPinMFSNode) PeerHost() host.Host { return x.node.PeerHost } -func startPinMFS(configPollInterval time.Duration, cctx pinMFSContext, node pinMFSNode) { - errCh := make(chan error) - go pinMFSOnChange(configPollInterval, cctx, node, errCh) - go func() { - for { - select { - case err, isOpen := <-errCh: - if !isOpen { - return - } - mfslog.Errorf("%v", err) - case <-cctx.Context().Done(): - return - } - } - }() +func startPinMFS(cctx pinMFSContext, configPollInterval time.Duration, node pinMFSNode) { + go pinMFSOnChange(cctx, configPollInterval, node) } -func pinMFSOnChange(configPollInterval time.Duration, cctx pinMFSContext, node pinMFSNode, errCh chan<- error) { - defer close(errCh) - - var tmo *time.Timer - defer func() { - if tmo != nil { - tmo.Stop() - } - }() +func pinMFSOnChange(cctx pinMFSContext, configPollInterval time.Duration, node pinMFSNode) { + tmo := time.NewTimer(configPollInterval) + defer tmo.Stop() lastPins := map[string]lastPin{} for { // polling sleep - if tmo == nil { - tmo = time.NewTimer(configPollInterval) - } else { - tmo.Reset(configPollInterval) - } select { case <-cctx.Context().Done(): return case <-tmo.C: + tmo.Reset(configPollInterval) } // reread the config, which may have changed in the meantime cfg, err := cctx.GetConfig() if err != nil { - select { - case errCh <- fmt.Errorf("pinning reading config (%v)", err): - case <-cctx.Context().Done(): - return - } + mfslog.Errorf("pinning reading config (%v)", err) continue } mfslog.Debugf("pinning loop is awake, %d remote services", len(cfg.Pinning.RemoteServices)) @@ -131,30 +104,29 @@ func pinMFSOnChange(configPollInterval time.Duration, cctx pinMFSContext, node p // get the most recent MFS root cid rootNode, err := node.RootNode() if err != nil { - select { - case errCh <- fmt.Errorf("pinning reading MFS root (%v)", err): - case <-cctx.Context().Done(): - return - } + mfslog.Errorf("pinning reading MFS root (%v)", err) continue } - rootCid := rootNode.Cid() // pin to all remote services in parallel - pinAllMFS(cctx.Context(), node, cfg, rootCid, lastPins, errCh) + pinAllMFS(cctx.Context(), node, cfg, rootNode.Cid(), lastPins) } } // pinAllMFS pins on all remote services in parallel to overcome DoS attacks. -func pinAllMFS(ctx context.Context, node pinMFSNode, cfg *config.Config, rootCid cid.Cid, lastPins map[string]lastPin, errCh chan<- error) { - ch := make(chan lastPin, len(cfg.Pinning.RemoteServices)) - for svcName_, svcConfig_ := range cfg.Pinning.RemoteServices { +func pinAllMFS(ctx context.Context, node pinMFSNode, cfg *config.Config, rootCid cid.Cid, lastPins map[string]lastPin) { + ch := make(chan lastPin) + var started int + + for svcName, svcConfig := range cfg.Pinning.RemoteServices { + if ctx.Err() != nil { + break + } + // skip services where MFS is not enabled - svcName, svcConfig := svcName_, svcConfig_ mfslog.Debugf("pinning MFS root considering service %q", svcName) if !svcConfig.Policies.MFS.Enable { mfslog.Debugf("pinning service %q is not enabled", svcName) - ch <- lastPin{} continue } // read mfs pin interval for this service @@ -165,11 +137,7 @@ func pinAllMFS(ctx context.Context, node pinMFSNode, cfg *config.Config, rootCid var err error repinInterval, err = time.ParseDuration(svcConfig.Policies.MFS.RepinInterval) if err != nil { - select { - case errCh <- fmt.Errorf("remote pinning service %q has invalid MFS.RepinInterval (%v)", svcName, err): - case <-ctx.Done(): - } - ch <- lastPin{} + mfslog.Errorf("remote pinning service %q has invalid MFS.RepinInterval (%v)", svcName, err) continue } } @@ -182,38 +150,30 @@ func pinAllMFS(ctx context.Context, node pinMFSNode, cfg *config.Config, rootCid } else { mfslog.Debugf("pinning MFS root to %q: skipped due to MFS.RepinInterval=%s (remaining: %s)", svcName, repinInterval.String(), (repinInterval - time.Since(last.Time)).String()) } - ch <- lastPin{} continue } } mfslog.Debugf("pinning MFS root %q to %q", rootCid, svcName) - go func() { - if r, err := pinMFS(ctx, node, rootCid, svcName, svcConfig); err != nil { - select { - case errCh <- fmt.Errorf("pinning MFS root %q to %q (%v)", rootCid, svcName, err): - case <-ctx.Done(): - } - ch <- lastPin{} - } else { - ch <- r + go func(svcName string, svcConfig config.RemotePinningService) { + r, err := pinMFS(ctx, node, rootCid, svcName, svcConfig) + if err != nil { + mfslog.Errorf("pinning MFS root %q to %q (%v)", rootCid, svcName, err) } - }() + ch <- r + }(svcName, svcConfig) + started++ } - for i := 0; i < len(cfg.Pinning.RemoteServices); i++ { + + // Collect results from all started goroutines. + for i := 0; i < started; i++ { if x := <-ch; x.IsValid() { lastPins[x.ServiceName] = x } } } -func pinMFS( - ctx context.Context, - node pinMFSNode, - cid cid.Cid, - svcName string, - svcConfig config.RemotePinningService, -) (lastPin, error) { +func pinMFS(ctx context.Context, node pinMFSNode, cid cid.Cid, svcName string, svcConfig config.RemotePinningService) (lastPin, error) { c := pinclient.NewClient(svcConfig.API.Endpoint, svcConfig.API.Key) pinName := svcConfig.Policies.MFS.PinName @@ -243,43 +203,46 @@ func pinMFS( } for range lsPinCh { // in case the prior loop exits early } - if err := <-lsErrCh; err != nil { + err := <-lsErrCh + if err != nil { return lastPin{}, fmt.Errorf("error while listing remote pins: %v", err) } - // CID of the current MFS root is already being pinned, nothing to do - if pinning { - mfslog.Debugf("pinning MFS to %q: pin for %q exists since %s, skipping", svcName, cid, pinTime.String()) - return lastPin{Time: pinTime, ServiceName: svcName, ServiceConfig: svcConfig, CID: cid}, nil - } + if !pinning { + // Prepare Pin.name + addOpts := []pinclient.AddOption{pinclient.PinOpts.WithName(pinName)} - // Prepare Pin.name - addOpts := []pinclient.AddOption{pinclient.PinOpts.WithName(pinName)} - - // Prepare Pin.origins - // Add own multiaddrs to the 'origins' array, so Pinning Service can - // use that as a hint and connect back to us (if possible) - if node.PeerHost() != nil { - addrs, err := peer.AddrInfoToP2pAddrs(host.InfoFromHost(node.PeerHost())) - if err != nil { - return lastPin{}, err + // Prepare Pin.origins + // Add own multiaddrs to the 'origins' array, so Pinning Service can + // use that as a hint and connect back to us (if possible) + if node.PeerHost() != nil { + addrs, err := peer.AddrInfoToP2pAddrs(host.InfoFromHost(node.PeerHost())) + if err != nil { + return lastPin{}, err + } + addOpts = append(addOpts, pinclient.PinOpts.WithOrigins(addrs...)) } - addOpts = append(addOpts, pinclient.PinOpts.WithOrigins(addrs...)) - } - // Create or replace pin for MFS root - if existingRequestID != "" { - mfslog.Debugf("pinning to %q: replacing existing MFS root pin with %q", svcName, cid) - _, err := c.Replace(ctx, existingRequestID, cid, addOpts...) - if err != nil { - return lastPin{}, err + // Create or replace pin for MFS root + if existingRequestID != "" { + mfslog.Debugf("pinning to %q: replacing existing MFS root pin with %q", svcName, cid) + if _, err = c.Replace(ctx, existingRequestID, cid, addOpts...); err != nil { + return lastPin{}, err + } + } else { + mfslog.Debugf("pinning to %q: creating a new MFS root pin for %q", svcName, cid) + if _, err = c.Add(ctx, cid, addOpts...); err != nil { + return lastPin{}, err + } } } else { - mfslog.Debugf("pinning to %q: creating a new MFS root pin for %q", svcName, cid) - _, err := c.Add(ctx, cid, addOpts...) - if err != nil { - return lastPin{}, err - } + mfslog.Debugf("pinning MFS to %q: pin for %q exists since %s, skipping", svcName, cid, pinTime.String()) } - return lastPin{Time: pinTime, ServiceName: svcName, ServiceConfig: svcConfig, CID: cid}, nil + + return lastPin{ + Time: pinTime, + ServiceName: svcName, + ServiceConfig: svcConfig, + CID: cid, + }, nil } diff --git a/cmd/ipfs/kubo/pinmfs_test.go b/cmd/ipfs/kubo/pinmfs_test.go index da71d362c..750be9c98 100644 --- a/cmd/ipfs/kubo/pinmfs_test.go +++ b/cmd/ipfs/kubo/pinmfs_test.go @@ -1,14 +1,19 @@ package kubo import ( + "bufio" "context" + "encoding/json" + "errors" "fmt" + "io" "strings" "testing" "time" merkledag "github.com/ipfs/boxo/ipld/merkledag" ipld "github.com/ipfs/go-ipld-format" + logging "github.com/ipfs/go-log/v2" config "github.com/ipfs/kubo/config" "github.com/libp2p/go-libp2p/core/host" peer "github.com/libp2p/go-libp2p/core/peer" @@ -60,25 +65,37 @@ func isErrorSimilar(e1, e2 error) bool { } func TestPinMFSConfigError(t *testing.T) { - ctx := &testPinMFSContext{ - ctx: context.Background(), + ctx, cancel := context.WithTimeout(context.Background(), 2*testConfigPollInterval) + defer cancel() + + cctx := &testPinMFSContext{ + ctx: ctx, cfg: nil, err: fmt.Errorf("couldn't read config"), } node := &testPinMFSNode{} - errCh := make(chan error) - go pinMFSOnChange(testConfigPollInterval, ctx, node, errCh) - if !isErrorSimilar(<-errCh, ctx.err) { - t.Errorf("error did not propagate") + + logReader := logging.NewPipeReader() + go func() { + pinMFSOnChange(cctx, testConfigPollInterval, node) + logReader.Close() + }() + + level, msg := readLogLine(t, logReader) + if level != "error" { + t.Error("expected error to be logged") } - if !isErrorSimilar(<-errCh, ctx.err) { + if !isErrorSimilar(errors.New(msg), cctx.err) { t.Errorf("error did not propagate") } } func TestPinMFSRootNodeError(t *testing.T) { - ctx := &testPinMFSContext{ - ctx: context.Background(), + ctx, cancel := context.WithTimeout(context.Background(), 2*testConfigPollInterval) + defer cancel() + + cctx := &testPinMFSContext{ + ctx: ctx, cfg: &config.Config{ Pinning: config.Pinning{}, }, @@ -87,12 +104,16 @@ func TestPinMFSRootNodeError(t *testing.T) { node := &testPinMFSNode{ err: fmt.Errorf("cannot create root node"), } - errCh := make(chan error) - go pinMFSOnChange(testConfigPollInterval, ctx, node, errCh) - if !isErrorSimilar(<-errCh, node.err) { - t.Errorf("error did not propagate") + logReader := logging.NewPipeReader() + go func() { + pinMFSOnChange(cctx, testConfigPollInterval, node) + logReader.Close() + }() + level, msg := readLogLine(t, logReader) + if level != "error" { + t.Error("expected error to be logged") } - if !isErrorSimilar(<-errCh, node.err) { + if !isErrorSimilar(errors.New(msg), node.err) { t.Errorf("error did not propagate") } } @@ -155,7 +176,8 @@ func TestPinMFSService(t *testing.T) { } func testPinMFSServiceWithError(t *testing.T, cfg *config.Config, expectedErrorPrefix string) { - goctx, cancel := context.WithCancel(context.Background()) + goctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() ctx := &testPinMFSContext{ ctx: goctx, cfg: cfg, @@ -164,16 +186,36 @@ func testPinMFSServiceWithError(t *testing.T, cfg *config.Config, expectedErrorP node := &testPinMFSNode{ err: nil, } - errCh := make(chan error) - go pinMFSOnChange(testConfigPollInterval, ctx, node, errCh) - defer cancel() - // first pass through the pinning loop - err := <-errCh - if !strings.Contains((err).Error(), expectedErrorPrefix) { - t.Errorf("expecting error containing %q", expectedErrorPrefix) + logReader := logging.NewPipeReader() + go func() { + pinMFSOnChange(ctx, testConfigPollInterval, node) + logReader.Close() + }() + level, msg := readLogLine(t, logReader) + if level != "error" { + t.Error("expected error to be logged") } - // second pass through the pinning loop - if !strings.Contains((err).Error(), expectedErrorPrefix) { + if !strings.Contains(msg, expectedErrorPrefix) { t.Errorf("expecting error containing %q", expectedErrorPrefix) } } + +func readLogLine(t *testing.T, logReader io.Reader) (string, string) { + t.Helper() + + r := bufio.NewReader(logReader) + data, err := r.ReadBytes('\n') + if err != nil { + t.Fatal(err) + } + + logInfo := struct { + Level string `json:"level"` + Msg string `json:"msg"` + }{} + err = json.Unmarshal(data, &logInfo) + if err != nil { + t.Fatal(err) + } + return logInfo.Level, logInfo.Msg +} diff --git a/core/commands/pin/remotepin.go b/core/commands/pin/remotepin.go index 132532554..3721913e7 100644 --- a/core/commands/pin/remotepin.go +++ b/core/commands/pin/remotepin.go @@ -221,6 +221,8 @@ NOTE: a comma-separated notation is supported in CLI for convenience: // Block unless --background=true is passed if !req.Options[pinBackgroundOptionName].(bool) { + const pinWaitTime = 500 * time.Millisecond + var timer *time.Timer requestID := ps.GetRequestId() for { ps, err = c.GetStatusByID(ctx, requestID) @@ -237,10 +239,15 @@ NOTE: a comma-separated notation is supported in CLI for convenience: if s == pinclient.StatusFailed { return fmt.Errorf("remote service failed to pin requestid=%q", requestID) } - tmr := time.NewTimer(time.Second / 2) + if timer == nil { + timer = time.NewTimer(pinWaitTime) + } else { + timer.Reset(pinWaitTime) + } select { - case <-tmr.C: + case <-timer.C: case <-ctx.Done(): + timer.Stop() return fmt.Errorf("waiting for pin interrupted, requestid=%q remains on remote service", requestID) } } From 95775273293d5c92d8d1252e974672bf12e88756 Mon Sep 17 00:00:00 2001 From: Andrew Gillis <11790789+gammazero@users.noreply.github.com> Date: Fri, 27 Sep 2024 20:37:41 -0700 Subject: [PATCH 1166/1212] feat(bitswap): allow configuring WithWantHaveReplaceSize (#10512) Allow configuration of the bitswap server's replace WantHave with WantBlock maximum block size using the Internal.Bitswap.WantHaveReplaceSize config item. This sets the maximum size of a block in bytes up to which we will replace a want-have with a want-block. Setting a size of 0 disables this replacement and means that block sizes are not read for WantHave requests. See ipfs/boxo#672 for more details Updated boxo to version with PR 672 --------- Co-authored-by: Marcin Rataj --- config/internal.go | 1 + core/node/bitswap.go | 2 ++ docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- test/dependencies/go.mod | 2 +- test/dependencies/go.sum | 4 ++-- 8 files changed, 12 insertions(+), 9 deletions(-) diff --git a/config/internal.go b/config/internal.go index 40070b11b..f43746534 100644 --- a/config/internal.go +++ b/config/internal.go @@ -14,4 +14,5 @@ type InternalBitswap struct { EngineTaskWorkerCount OptionalInteger MaxOutstandingBytesPerPeer OptionalInteger ProviderSearchDelay OptionalDuration + WantHaveReplaceSize OptionalInteger } diff --git a/core/node/bitswap.go b/core/node/bitswap.go index 1c4c1df21..4132d5a01 100644 --- a/core/node/bitswap.go +++ b/core/node/bitswap.go @@ -23,6 +23,7 @@ const ( DefaultEngineTaskWorkerCount = 8 DefaultMaxOutstandingBytesPerPeer = 1 << 20 DefaultProviderSearchDelay = 1000 * time.Millisecond + DefaultWantHaveReplaceSize = 1024 ) type bitswapOptionsOut struct { @@ -47,6 +48,7 @@ func BitswapOptions(cfg *config.Config, provide bool) interface{} { bitswap.TaskWorkerCount(int(internalBsCfg.TaskWorkerCount.WithDefault(DefaultTaskWorkerCount))), bitswap.EngineTaskWorkerCount(int(internalBsCfg.EngineTaskWorkerCount.WithDefault(DefaultEngineTaskWorkerCount))), bitswap.MaxOutstandingBytesPerPeer(int(internalBsCfg.MaxOutstandingBytesPerPeer.WithDefault(DefaultMaxOutstandingBytesPerPeer))), + bitswap.WithWantHaveReplaceSize(int(internalBsCfg.WantHaveReplaceSize.WithDefault(DefaultWantHaveReplaceSize))), } return bitswapOptionsOut{BitswapOpts: opts} diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 033282a0f..7478ae14d 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.22 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.23.0 + github.com/ipfs/boxo v0.23.1-0.20240927234853-19a402b7dc34 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.36.3 github.com/multiformats/go-multiaddr v0.13.0 diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 53a4e6750..fff159908 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -266,8 +266,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.23.0 h1:dY1PpcvPJ//VuUQ1TUd5TZvmaGuzxJ8dOP6mXaw+ke8= -github.com/ipfs/boxo v0.23.0/go.mod h1:ulu5I6avTmgGmvjuCaBRKwsaOOKjBfQw1EiOOQp8M6E= +github.com/ipfs/boxo v0.23.1-0.20240927234853-19a402b7dc34 h1:/Etgc4IR0OUF+nIoNdqwu12EYuaSMpd7/Nc5wRLd67U= +github.com/ipfs/boxo v0.23.1-0.20240927234853-19a402b7dc34/go.mod h1:ulu5I6avTmgGmvjuCaBRKwsaOOKjBfQw1EiOOQp8M6E= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= diff --git a/go.mod b/go.mod index 32b762790..e188c1968 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( github.com/hashicorp/go-version v1.6.0 github.com/ipfs-shipyard/nopfs v0.0.12 github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c - github.com/ipfs/boxo v0.23.0 + github.com/ipfs/boxo v0.23.1-0.20240927234853-19a402b7dc34 github.com/ipfs/go-block-format v0.2.0 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 diff --git a/go.sum b/go.sum index 40d55934a..246eef96b 100644 --- a/go.sum +++ b/go.sum @@ -330,8 +330,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.23.0 h1:dY1PpcvPJ//VuUQ1TUd5TZvmaGuzxJ8dOP6mXaw+ke8= -github.com/ipfs/boxo v0.23.0/go.mod h1:ulu5I6avTmgGmvjuCaBRKwsaOOKjBfQw1EiOOQp8M6E= +github.com/ipfs/boxo v0.23.1-0.20240927234853-19a402b7dc34 h1:/Etgc4IR0OUF+nIoNdqwu12EYuaSMpd7/Nc5wRLd67U= +github.com/ipfs/boxo v0.23.1-0.20240927234853-19a402b7dc34/go.mod h1:ulu5I6avTmgGmvjuCaBRKwsaOOKjBfQw1EiOOQp8M6E= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 40fde600c..24af83852 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -111,7 +111,7 @@ require ( github.com/hexops/gotextdiff v1.0.3 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/ipfs/bbloom v0.0.4 // indirect - github.com/ipfs/boxo v0.23.0 // indirect + github.com/ipfs/boxo v0.23.1-0.20240927234853-19a402b7dc34 // indirect github.com/ipfs/go-block-format v0.2.0 // indirect github.com/ipfs/go-cid v0.4.1 // indirect github.com/ipfs/go-datastore v0.6.0 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 81ca714e2..7d9722814 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -281,8 +281,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.23.0 h1:dY1PpcvPJ//VuUQ1TUd5TZvmaGuzxJ8dOP6mXaw+ke8= -github.com/ipfs/boxo v0.23.0/go.mod h1:ulu5I6avTmgGmvjuCaBRKwsaOOKjBfQw1EiOOQp8M6E= +github.com/ipfs/boxo v0.23.1-0.20240927234853-19a402b7dc34 h1:/Etgc4IR0OUF+nIoNdqwu12EYuaSMpd7/Nc5wRLd67U= +github.com/ipfs/boxo v0.23.1-0.20240927234853-19a402b7dc34/go.mod h1:ulu5I6avTmgGmvjuCaBRKwsaOOKjBfQw1EiOOQp8M6E= github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs= github.com/ipfs/go-block-format v0.2.0/go.mod h1:+jpL11nFx5A/SPpsoBn6Bzkra/zaArfSmsknbPMYgzM= github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= From a17830754ccb22ef1ae8a63f30643c41eb35f01d Mon Sep 17 00:00:00 2001 From: fengzie <526567244@qq.com> Date: Sun, 29 Sep 2024 11:58:24 +0800 Subject: [PATCH 1167/1212] Fix issue in ResourceManager and nopfsPlugin about repo path (#10492) --- core/node/groups.go | 2 +- core/node/libp2p/rcmgr.go | 7 +----- plugin/plugins/nopfs/nopfs.go | 43 ++++++++++++++++++----------------- repo/mock.go | 4 ++++ repo/repo.go | 3 +++ 5 files changed, 31 insertions(+), 28 deletions(-) diff --git a/core/node/groups.go b/core/node/groups.go index a12cc7b7f..d806e2ef6 100644 --- a/core/node/groups.go +++ b/core/node/groups.go @@ -132,7 +132,7 @@ func LibP2P(bcfg *BuildCfg, cfg *config.Config, userResourceOverrides rcmgr.Part fx.Provide(libp2p.UserAgent()), // Services (resource management) - fx.Provide(libp2p.ResourceManager(cfg.Swarm, userResourceOverrides)), + fx.Provide(libp2p.ResourceManager(bcfg.Repo.Path(), cfg.Swarm, userResourceOverrides)), 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 8b6d55a2c..80bfec34a 100644 --- a/core/node/libp2p/rcmgr.go +++ b/core/node/libp2p/rcmgr.go @@ -28,7 +28,7 @@ const NetLimitTraceFilename = "rcmgr.json.gz" var ErrNoResourceMgr = fmt.Errorf("missing ResourceMgr: make sure the daemon is running with Swarm.ResourceMgr.Enabled") -func ResourceManager(cfg config.SwarmConfig, userResourceOverrides rcmgr.PartialLimitConfig) interface{} { +func ResourceManager(repoPath string, cfg config.SwarmConfig, userResourceOverrides rcmgr.PartialLimitConfig) interface{} { return func(mctx helpers.MetricsCtx, lc fx.Lifecycle, repo repo.Repo) (network.ResourceManager, Libp2pOpts, error) { var manager network.ResourceManager var opts Libp2pOpts @@ -46,11 +46,6 @@ func ResourceManager(cfg config.SwarmConfig, userResourceOverrides rcmgr.Partial if enabled { log.Debug("libp2p resource manager is enabled") - repoPath, err := config.PathRoot() - if err != nil { - return nil, opts, fmt.Errorf("opening IPFS_PATH: %w", err) - } - limitConfig, msg, err := LimitConfig(cfg, userResourceOverrides) if err != nil { return nil, opts, fmt.Errorf("creating final Resource Manager config: %w", err) diff --git a/plugin/plugins/nopfs/nopfs.go b/plugin/plugins/nopfs/nopfs.go index 64350830f..c32d7533f 100644 --- a/plugin/plugins/nopfs/nopfs.go +++ b/plugin/plugins/nopfs/nopfs.go @@ -6,7 +6,6 @@ import ( "github.com/ipfs-shipyard/nopfs" "github.com/ipfs-shipyard/nopfs/ipfs" - "github.com/ipfs/kubo/config" "github.com/ipfs/kubo/core" "github.com/ipfs/kubo/core/node" "github.com/ipfs/kubo/plugin" @@ -20,7 +19,10 @@ var Plugins = []plugin.Plugin{ // fxtestPlugin is used for testing the fx plugin. // It merely adds an fx option that logs a debug statement, so we can verify that it works in tests. -type nopfsPlugin struct{} +type nopfsPlugin struct { + // Path to the IPFS repo. + repo string +} var _ plugin.PluginFx = (*nopfsPlugin)(nil) @@ -33,29 +35,28 @@ func (p *nopfsPlugin) Version() string { } func (p *nopfsPlugin) Init(env *plugin.Environment) error { + p.repo = env.Repo + return nil } // MakeBlocker is a factory for the blocker so that it can be provided with Fx. -func MakeBlocker() (*nopfs.Blocker, error) { - ipfsPath, err := config.PathRoot() - if err != nil { - return nil, err +func MakeBlocker(repoPath string) func() (*nopfs.Blocker, error) { + return func() (*nopfs.Blocker, error) { + defaultFiles, err := nopfs.GetDenylistFiles() + if err != nil { + return nil, err + } + + kuboFiles, err := nopfs.GetDenylistFilesInDir(filepath.Join(repoPath, "denylists")) + if err != nil { + return nil, err + } + + files := append(defaultFiles, kuboFiles...) + + return nopfs.NewBlocker(files) } - - defaultFiles, err := nopfs.GetDenylistFiles() - if err != nil { - return nil, err - } - - kuboFiles, err := nopfs.GetDenylistFilesInDir(filepath.Join(ipfsPath, "denylists")) - if err != nil { - return nil, err - } - - files := append(defaultFiles, kuboFiles...) - - return nopfs.NewBlocker(files) } // PathResolvers returns wrapped PathResolvers for Kubo. @@ -76,7 +77,7 @@ func (p *nopfsPlugin) Options(info core.FXNodeInfo) ([]fx.Option, error) { opts := append( info.FXOptions, - fx.Provide(MakeBlocker), + fx.Provide(MakeBlocker(p.repo)), fx.Decorate(ipfs.WrapBlockService), fx.Decorate(ipfs.WrapNameSystem), fx.Decorate(PathResolvers), diff --git a/repo/mock.go b/repo/mock.go index 46bb0cb42..2ac60615d 100644 --- a/repo/mock.go +++ b/repo/mock.go @@ -27,6 +27,10 @@ func (m *Mock) Config() (*config.Config, error) { return &m.C, nil // FIXME threadsafety } +func (m *Mock) Path() string { + return "" +} + func (m *Mock) UserResourceOverrides() (rcmgr.PartialLimitConfig, error) { return rcmgr.PartialLimitConfig{}, nil } diff --git a/repo/repo.go b/repo/repo.go index 9abdf867e..f345e89b4 100644 --- a/repo/repo.go +++ b/repo/repo.go @@ -23,6 +23,9 @@ type Repo interface { // to the returned config are not automatically persisted. Config() (*config.Config, error) + // Path is the repo file-system path + Path() string + // UserResourceOverrides returns optional user resource overrides for the // libp2p resource manager. UserResourceOverrides() (rcmgr.PartialLimitConfig, error) From 22aeb13124eb7a0f204c6af46135cb37823f76dd Mon Sep 17 00:00:00 2001 From: Lucas Molas Date: Thu, 3 Oct 2024 16:38:16 -0300 Subject: [PATCH 1168/1212] fix(core): look for MFS root in local repo only (#8661) Co-authored-by: Andrew Gillis <11790789+gammazero@users.noreply.github.com> --- core/node/core.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/core/node/core.go b/core/node/core.go index 9a2035a4c..ad259c962 100644 --- a/core/node/core.go +++ b/core/node/core.go @@ -146,7 +146,7 @@ func Dag(bs blockservice.BlockService) format.DAGService { } // Files loads persisted MFS root -func Files(mctx helpers.MetricsCtx, lc fx.Lifecycle, repo repo.Repo, dag format.DAGService) (*mfs.Root, error) { +func Files(mctx helpers.MetricsCtx, lc fx.Lifecycle, repo repo.Repo, dag format.DAGService, bs blockstore.Blockstore) (*mfs.Root, error) { dsk := datastore.NewKey("/local/filesroot") pf := func(ctx context.Context, c cid.Cid) error { rootDS := repo.Datastore() @@ -172,7 +172,7 @@ func Files(mctx helpers.MetricsCtx, lc fx.Lifecycle, repo repo.Repo, dag format. nd = unixfs.EmptyDirNode() err := dag.Add(ctx, nd) if err != nil { - return nil, fmt.Errorf("failure writing to dagstore: %s", err) + return nil, fmt.Errorf("failure writing filesroot to dagstore: %s", err) } case err == nil: c, err := cid.Cast(val) @@ -180,9 +180,10 @@ func Files(mctx helpers.MetricsCtx, lc fx.Lifecycle, repo repo.Repo, dag format. return nil, err } - rnd, err := dag.Get(ctx, c) + offineDag := merkledag.NewDAGService(blockservice.New(bs, offline.Exchange(bs))) + rnd, err := offineDag.Get(ctx, c) if err != nil { - return nil, fmt.Errorf("error loading filesroot from DAG: %s", err) + return nil, fmt.Errorf("error loading filesroot from dagservice: %s", err) } pbnd, ok := rnd.(*merkledag.ProtoNode) From a8ecf014a9ed15c15760c827e8909d99f176e4c4 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Thu, 3 Oct 2024 21:39:52 +0200 Subject: [PATCH 1169/1212] feat: explicit announce-on/off profiles (#10524) moving reprovide on/off to separate profile to avoid footgun where node no longer announces to DHT + ipfs daemon check that prints warning on start if reprovide system is disabled --- cmd/ipfs/kubo/daemon.go | 19 +++++++++- config/profile.go | 27 +++++++++++++- docs/changelogs/v0.31.md | 13 +++++++ docs/config.md | 76 ++++++++++++++++++++++++---------------- 4 files changed, 102 insertions(+), 33 deletions(-) diff --git a/cmd/ipfs/kubo/daemon.go b/cmd/ipfs/kubo/daemon.go index 0e5637cdb..aaa1f414f 100644 --- a/cmd/ipfs/kubo/daemon.go +++ b/cmd/ipfs/kubo/daemon.go @@ -600,8 +600,25 @@ take effect. fmt.Println("(Hit ctrl-c again to force-shutdown the daemon.)") }() - // Give the user heads up if daemon running in online mode has no peers after 1 minute if !offline { + // Warn users who were victims of 'lowprofile' footgun (https://github.com/ipfs/kubo/pull/10524) + if cfg.Experimental.StrategicProviding { + fmt.Print(` +⚠️ Reprovide system is disabled due to 'Experimental.StrategicProviding=true' +⚠️ Local CIDs will not be announced to Amino DHT, making them impossible to retrieve without manual peering +⚠️ If this is not intentional, call 'ipfs config profile apply announce-on' + +`) + } else if cfg.Reprovider.Interval.WithDefault(config.DefaultReproviderInterval) == 0 { + fmt.Print(` +⚠️ Reprovider system is disabled due to 'Reprovider.Interval=0' +⚠️ Local CIDs will not be announced to Amino DHT, making them impossible to retrieve without manual peering +⚠️ If this is not intentional, call 'ipfs config profile apply announce-on', or set 'Reprovider.Interval=22h' + +`) + } + + // Give the user heads up if daemon running in online mode has no peers after 1 minute time.AfterFunc(1*time.Minute, func() { cfg, err := cctx.GetConfig() if err != nil { diff --git a/config/profile.go b/config/profile.go index 63e76d8ec..0ee9225be 100644 --- a/config/profile.go +++ b/config/profile.go @@ -174,10 +174,12 @@ functionality - performance of content discovery and data fetching may be degraded. `, Transform: func(c *Config) error { + // Disable "server" services (dht, autonat, limited relay) c.Routing.Type = NewOptionalString("autoclient") c.AutoNAT.ServiceMode = AutoNATServiceDisabled - c.Reprovider.Interval = NewOptionalDuration(0) + c.Swarm.RelayService.Enabled = False + // Keep bare minimum connections around lowWater := int64(20) highWater := int64(40) gracePeriod := time.Minute @@ -188,6 +190,29 @@ fetching may be degraded. return nil }, }, + "announce-off": { + Description: `Disables Reprovide system (and announcing to Amino DHT). + + USE WITH CAUTION: + The main use case for this is setups with manual Peering.Peers config. + Data from this node will not be announced on the DHT. This will make + DHT-based routing an data retrieval impossible if this node is the only + one hosting it, and other peers are not already connected to it. +`, + Transform: func(c *Config) error { + c.Reprovider.Interval = NewOptionalDuration(0) // 0 disables periodic reprovide + c.Experimental.StrategicProviding = true // this is not a typo (the name is counter-intuitive) + return nil + }, + }, + "announce-on": { + Description: `Re-enables Reprovide system (reverts announce-off profile).`, + Transform: func(c *Config) error { + c.Reprovider.Interval = NewOptionalDuration(DefaultReproviderInterval) // have to apply explicit default because nil would be ignored + c.Experimental.StrategicProviding = false // this is not a typo (the name is counter-intuitive) + return nil + }, + }, "randomports": { Description: `Use a random port number for swarm.`, diff --git a/docs/changelogs/v0.31.md b/docs/changelogs/v0.31.md index 80823816c..ef1d4bb1b 100644 --- a/docs/changelogs/v0.31.md +++ b/docs/changelogs/v0.31.md @@ -6,6 +6,7 @@ - [Overview](#overview) - [🔦 Highlights](#-highlights) + - [`lowpower` profile no longer breaks DHT announcements](#lowpower-profile-no-longer-breaks-dht-announcements) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -13,6 +14,18 @@ ### 🔦 Highlights +#### `lowpower` profile no longer breaks DHT announcements + +We've notices users were applying `lowpower` profile, and then reporting content routing issues. This was because `lowpower` disabled reprovider system and locally hosted data was no longer announced on Amino DHT. + +This release changes [`lowpower` profile](https://github.com/ipfs/kubo/blob/master/docs/config.md#lowpower-profile) to not change reprovider settings, ensuring the new users are not sabotaging themselves. It also adds [`annouce-on`](https://github.com/ipfs/kubo/blob/master/docs/config.md#announce-on-profile) and [`announce-off`](https://github.com/ipfs/kubo/blob/master/docs/config.md#announce-off-profile) profiles for controlling announcement settings separately. + +> [!IMPORTANT] +> If you've ever applied the `lowpower` profile before, there is a high chance your node is not announcing to DHT anymore. +> If you have `Reprovider.Interval` set to `0` you may want to wet it to `22h` (or run `ipfs config profile apply announce-on`) to fix your system. +> +> As a convenience, `ipfs daemon` will warn if reprovide system is disabled, creating oportinity to fix configuration if it was not intentional. + ### 📝 Changelog ### 👨‍👩‍👧‍👦 Contributors diff --git a/docs/config.md b/docs/config.md index 5500128ab..2bcf4b0f2 100644 --- a/docs/config.md +++ b/docs/config.md @@ -183,6 +183,8 @@ config file at runtime. - [`flatfs` profile](#flatfs-profile) - [`badgerds` profile](#badgerds-profile) - [`lowpower` profile](#lowpower-profile) + - [`announce-off` profile](#announce-off-profile) + - [`announce-on` profile](#announce-on-profile) - [`legacy-cid-v0` profile](#legacy-cid-v0-profile) - [`test-cid-v1` profile](#test-cid-v1-profile) - [Types](#types) @@ -299,7 +301,7 @@ Map of HTTP headers to set on responses from the RPC (`/api/v0`) HTTP server. Example: ```json { - "Foo": ["bar"] + "Foo": ["bar"] } ``` @@ -534,27 +536,27 @@ Default: ``` { "mounts": [ - { - "child": { - "path": "blocks", - "shardFunc": "/repo/flatfs/shard/v1/next-to-last/2", - "sync": true, - "type": "flatfs" - }, - "mountpoint": "/blocks", - "prefix": "flatfs.datastore", - "type": "measure" - }, - { - "child": { - "compression": "none", - "path": "datastore", - "type": "levelds" - }, - "mountpoint": "/", - "prefix": "leveldb.datastore", - "type": "measure" - } + { + "child": { + "path": "blocks", + "shardFunc": "/repo/flatfs/shard/v1/next-to-last/2", + "sync": true, + "type": "flatfs" + }, + "mountpoint": "/blocks", + "prefix": "flatfs.datastore", + "type": "measure" + }, + { + "child": { + "compression": "none", + "path": "datastore", + "type": "levelds" + }, + "mountpoint": "/", + "prefix": "leveldb.datastore", + "type": "measure" + } ], "type": "mount" } @@ -1145,7 +1147,7 @@ Example: "API" : { "Endpoint" : "https://pinningservice.tld:1234/my/api/path", "Key" : "someOpaqueKey" - } + } } } } @@ -2439,18 +2441,30 @@ This profile may only be applied when first initializing the node. ### `lowpower` profile -Reduces daemon overhead on the system. Affects node -functionality - performance of content discovery and data -fetching may be degraded. +Reduces daemon overhead on the system by disabling optional swarm services. + +- [`Routing.Type`](#routingtype) set to `autoclient` (no DHT server, only client). +- `Swarm.ConnMgr` set to maintain minimum number of p2p connections at a time. +- Disables [`AutoNAT`](#autonat). +- Disables [`Swam.RelayService`](#swarmrelayservice). + +> [!NOTE] +> This profile is provided for legacy reasons. +> With modern Kubo setting the above should not be necessary. + +### `announce-off` profile + +Disables [Reprovider](#reprovider) system (and announcing to Amino DHT). > [!CAUTION] -> Local data won't be announced on routing systems like Amino DHT. +> The main use case for this is setups with manual Peering.Peers config. +> Data from this node will not be announced on the DHT. This will make +> DHT-based routing an data retrieval impossible if this node is the only +> one hosting it, and other peers are not already connected to it. -- `Swarm.ConnMgr` set to maintain minimum number of p2p connections at a time. -- Disables [`Reprovider`](#reprovider) service → no CID will be announced on Amino DHT and other routing systems(!) -- Disables [`AutoNAT`](#autonat). +### `announce-on` profile -Use this profile with caution. +(Re-)enables [Reprovider](#reprovider) system (reverts [`announce-off` profile](#annouce-off-profile). ### `legacy-cid-v0` profile From e1955a8a5a99f63f2e7721563085c15a4074de44 Mon Sep 17 00:00:00 2001 From: Andrew Gillis <11790789+gammazero@users.noreply.github.com> Date: Thu, 3 Oct 2024 12:50:34 -0700 Subject: [PATCH 1170/1212] chore: boxo v0.24.0 and go-libp2p v0.36.4 (#10531) * Upgrade to Boxo v0.24.0 * Update to boxo release v0.24.0 --- docs/examples/kubo-as-a-library/go.mod | 6 +++--- docs/examples/kubo-as-a-library/go.sum | 12 ++++++------ go.mod | 6 +++--- go.sum | 12 ++++++------ test/dependencies/go.mod | 6 +++--- test/dependencies/go.sum | 21 ++++++--------------- 6 files changed, 27 insertions(+), 36 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 7478ae14d..9cdd51319 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,9 +7,9 @@ go 1.22 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.23.1-0.20240927234853-19a402b7dc34 + github.com/ipfs/boxo v0.24.0 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 - github.com/libp2p/go-libp2p v0.36.3 + github.com/libp2p/go-libp2p v0.36.4 github.com/multiformats/go-multiaddr v0.13.0 ) @@ -131,7 +131,7 @@ require ( github.com/mr-tron/base58 v1.2.0 // indirect github.com/multiformats/go-base32 v0.1.0 // indirect github.com/multiformats/go-base36 v0.2.0 // indirect - github.com/multiformats/go-multiaddr-dns v0.3.1 // indirect + github.com/multiformats/go-multiaddr-dns v0.4.0 // indirect github.com/multiformats/go-multiaddr-fmt v0.1.0 // indirect github.com/multiformats/go-multibase v0.2.0 // indirect github.com/multiformats/go-multicodec v0.9.0 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index fff159908..387634d3a 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -266,8 +266,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.23.1-0.20240927234853-19a402b7dc34 h1:/Etgc4IR0OUF+nIoNdqwu12EYuaSMpd7/Nc5wRLd67U= -github.com/ipfs/boxo v0.23.1-0.20240927234853-19a402b7dc34/go.mod h1:ulu5I6avTmgGmvjuCaBRKwsaOOKjBfQw1EiOOQp8M6E= +github.com/ipfs/boxo v0.24.0 h1:D9gTU3QdxyjPMlJ6QfqhHTG3TIJPplKzjXLO2J30h9U= +github.com/ipfs/boxo v0.24.0/go.mod h1:iP7xUPpHq2QAmVAjwtQvsNBTxTwLpFuy6ZpiRFwmzDA= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= @@ -427,8 +427,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.36.3 h1:NHz30+G7D8Y8YmznrVZZla0ofVANrvBl2c+oARfMeDQ= -github.com/libp2p/go-libp2p v0.36.3/go.mod h1:4Y5vFyCUiJuluEPmpnKYf6WFx5ViKPUYs/ixe9ANFZ8= +github.com/libp2p/go-libp2p v0.36.4 h1:ZaKyKSHBFbzs6CnAYMhaMc5QgV1UoCN+9WXrg8SEwI4= +github.com/libp2p/go-libp2p v0.36.4/go.mod h1:4Y5vFyCUiJuluEPmpnKYf6WFx5ViKPUYs/ixe9ANFZ8= github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94= github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= @@ -522,8 +522,8 @@ github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y9 github.com/multiformats/go-multiaddr v0.13.0 h1:BCBzs61E3AGHcYYTv8dqRH43ZfyrqM8RXVPT8t13tLQ= github.com/multiformats/go-multiaddr v0.13.0/go.mod h1:sBXrNzucqkFJhvKOiwwLyqamGa/P5EIXNPLovyhQCII= github.com/multiformats/go-multiaddr-dns v0.3.0/go.mod h1:mNzQ4eTGDg0ll1N9jKPOUogZPoJ30W8a7zk66FQPpdQ= -github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A= -github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk= +github.com/multiformats/go-multiaddr-dns v0.4.0 h1:P76EJ3qzBXpUXZ3twdCDx/kvagMsNo0LMFXpyms/zgU= +github.com/multiformats/go-multiaddr-dns v0.4.0/go.mod h1:7hfthtB4E4pQwirrz+J0CcDUfbWzTqEzVyYKKIKpgkc= github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E= github.com/multiformats/go-multiaddr-fmt v0.1.0/go.mod h1:hGtDIW4PU4BqJ50gW2quDuPVjyWNZxToGUh/HwTZYJo= github.com/multiformats/go-multiaddr-net v0.1.1/go.mod h1:5JNbcfBOP4dnhoZOv10JJVkJO0pCCEf8mTnipAo2UZQ= diff --git a/go.mod b/go.mod index e188c1968..db6a05c0c 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( github.com/hashicorp/go-version v1.6.0 github.com/ipfs-shipyard/nopfs v0.0.12 github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c - github.com/ipfs/boxo v0.23.1-0.20240927234853-19a402b7dc34 + github.com/ipfs/boxo v0.24.0 github.com/ipfs/go-block-format v0.2.0 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 @@ -48,7 +48,7 @@ require ( github.com/jbenet/goprocess v0.1.4 github.com/julienschmidt/httprouter v1.3.0 github.com/libp2p/go-doh-resolver v0.4.0 - github.com/libp2p/go-libp2p v0.36.3 + github.com/libp2p/go-libp2p v0.36.4 github.com/libp2p/go-libp2p-http v0.5.0 github.com/libp2p/go-libp2p-kad-dht v0.26.1 github.com/libp2p/go-libp2p-kbucket v0.6.3 @@ -60,7 +60,7 @@ require ( github.com/libp2p/go-socket-activation v0.1.0 github.com/mitchellh/go-homedir v1.1.0 github.com/multiformats/go-multiaddr v0.13.0 - github.com/multiformats/go-multiaddr-dns v0.3.1 + github.com/multiformats/go-multiaddr-dns v0.4.0 github.com/multiformats/go-multibase v0.2.0 github.com/multiformats/go-multicodec v0.9.0 github.com/multiformats/go-multihash v0.2.3 diff --git a/go.sum b/go.sum index 246eef96b..4453c254d 100644 --- a/go.sum +++ b/go.sum @@ -330,8 +330,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.23.1-0.20240927234853-19a402b7dc34 h1:/Etgc4IR0OUF+nIoNdqwu12EYuaSMpd7/Nc5wRLd67U= -github.com/ipfs/boxo v0.23.1-0.20240927234853-19a402b7dc34/go.mod h1:ulu5I6avTmgGmvjuCaBRKwsaOOKjBfQw1EiOOQp8M6E= +github.com/ipfs/boxo v0.24.0 h1:D9gTU3QdxyjPMlJ6QfqhHTG3TIJPplKzjXLO2J30h9U= +github.com/ipfs/boxo v0.24.0/go.mod h1:iP7xUPpHq2QAmVAjwtQvsNBTxTwLpFuy6ZpiRFwmzDA= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= @@ -504,8 +504,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.36.3 h1:NHz30+G7D8Y8YmznrVZZla0ofVANrvBl2c+oARfMeDQ= -github.com/libp2p/go-libp2p v0.36.3/go.mod h1:4Y5vFyCUiJuluEPmpnKYf6WFx5ViKPUYs/ixe9ANFZ8= +github.com/libp2p/go-libp2p v0.36.4 h1:ZaKyKSHBFbzs6CnAYMhaMc5QgV1UoCN+9WXrg8SEwI4= +github.com/libp2p/go-libp2p v0.36.4/go.mod h1:4Y5vFyCUiJuluEPmpnKYf6WFx5ViKPUYs/ixe9ANFZ8= github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94= github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= @@ -618,8 +618,8 @@ github.com/multiformats/go-multiaddr v0.4.0/go.mod h1:YcpyLH8ZPudLxQlemYBPhSm0/o github.com/multiformats/go-multiaddr v0.13.0 h1:BCBzs61E3AGHcYYTv8dqRH43ZfyrqM8RXVPT8t13tLQ= github.com/multiformats/go-multiaddr v0.13.0/go.mod h1:sBXrNzucqkFJhvKOiwwLyqamGa/P5EIXNPLovyhQCII= github.com/multiformats/go-multiaddr-dns v0.3.0/go.mod h1:mNzQ4eTGDg0ll1N9jKPOUogZPoJ30W8a7zk66FQPpdQ= -github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A= -github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk= +github.com/multiformats/go-multiaddr-dns v0.4.0 h1:P76EJ3qzBXpUXZ3twdCDx/kvagMsNo0LMFXpyms/zgU= +github.com/multiformats/go-multiaddr-dns v0.4.0/go.mod h1:7hfthtB4E4pQwirrz+J0CcDUfbWzTqEzVyYKKIKpgkc= github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E= github.com/multiformats/go-multiaddr-fmt v0.1.0/go.mod h1:hGtDIW4PU4BqJ50gW2quDuPVjyWNZxToGUh/HwTZYJo= github.com/multiformats/go-multiaddr-net v0.1.1/go.mod h1:5JNbcfBOP4dnhoZOv10JJVkJO0pCCEf8mTnipAo2UZQ= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 24af83852..5f77201ee 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -111,7 +111,7 @@ require ( github.com/hexops/gotextdiff v1.0.3 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/ipfs/bbloom v0.0.4 // indirect - github.com/ipfs/boxo v0.23.1-0.20240927234853-19a402b7dc34 // indirect + github.com/ipfs/boxo v0.24.0 // indirect github.com/ipfs/go-block-format v0.2.0 // indirect github.com/ipfs/go-cid v0.4.1 // indirect github.com/ipfs/go-datastore v0.6.0 // indirect @@ -142,7 +142,7 @@ require ( github.com/leonklingele/grouper v1.1.2 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/libp2p/go-cidranger v1.1.0 // indirect - github.com/libp2p/go-libp2p v0.36.3 // indirect + github.com/libp2p/go-libp2p v0.36.4 // indirect github.com/libp2p/go-libp2p-asn-util v0.4.1 // indirect github.com/libp2p/go-libp2p-kad-dht v0.26.1 // indirect github.com/libp2p/go-libp2p-kbucket v0.6.3 // indirect @@ -168,7 +168,7 @@ require ( github.com/mr-tron/base58 v1.2.0 // indirect github.com/multiformats/go-base32 v0.1.0 // indirect github.com/multiformats/go-base36 v0.2.0 // indirect - github.com/multiformats/go-multiaddr-dns v0.3.1 // indirect + github.com/multiformats/go-multiaddr-dns v0.4.0 // indirect github.com/multiformats/go-multibase v0.2.0 // indirect github.com/multiformats/go-multicodec v0.9.0 // indirect github.com/multiformats/go-multistream v0.5.0 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 7d9722814..168d9abd8 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -281,8 +281,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.23.1-0.20240927234853-19a402b7dc34 h1:/Etgc4IR0OUF+nIoNdqwu12EYuaSMpd7/Nc5wRLd67U= -github.com/ipfs/boxo v0.23.1-0.20240927234853-19a402b7dc34/go.mod h1:ulu5I6avTmgGmvjuCaBRKwsaOOKjBfQw1EiOOQp8M6E= +github.com/ipfs/boxo v0.24.0 h1:D9gTU3QdxyjPMlJ6QfqhHTG3TIJPplKzjXLO2J30h9U= +github.com/ipfs/boxo v0.24.0/go.mod h1:iP7xUPpHq2QAmVAjwtQvsNBTxTwLpFuy6ZpiRFwmzDA= github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs= github.com/ipfs/go-block-format v0.2.0/go.mod h1:+jpL11nFx5A/SPpsoBn6Bzkra/zaArfSmsknbPMYgzM= github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= @@ -388,8 +388,8 @@ github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38y github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.36.3 h1:NHz30+G7D8Y8YmznrVZZla0ofVANrvBl2c+oARfMeDQ= -github.com/libp2p/go-libp2p v0.36.3/go.mod h1:4Y5vFyCUiJuluEPmpnKYf6WFx5ViKPUYs/ixe9ANFZ8= +github.com/libp2p/go-libp2p v0.36.4 h1:ZaKyKSHBFbzs6CnAYMhaMc5QgV1UoCN+9WXrg8SEwI4= +github.com/libp2p/go-libp2p v0.36.4/go.mod h1:4Y5vFyCUiJuluEPmpnKYf6WFx5ViKPUYs/ixe9ANFZ8= github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94= github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= github.com/libp2p/go-libp2p-kad-dht v0.26.1 h1:AazV3LCImYVkDUGAHx5lIEgZ9iUI2QQKH5GMRQU8uEA= @@ -441,15 +441,12 @@ github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZ github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mgechev/revive v1.3.9 h1:18Y3R4a2USSBF+QZKFQwVkBROUda7uoBlkEuBD+YD1A= github.com/mgechev/revive v1.3.9/go.mod h1:+uxEIr5UH0TjXWHTno3xh4u7eg6jDpXKzQccA9UGhHU= -github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= github.com/miekg/dns v1.1.61 h1:nLxbwF3XxhwVSm8g9Dghm9MHPaUZuqhPiGL+675ZmEs= github.com/miekg/dns v1.1.61/go.mod h1:mnAarhS3nWaW+NVP2wTkYVIZyHNJ098SJZUki3eykwQ= github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b/go.mod h1:lxPUiZwKoFL8DUUmalo2yJJUCxbPKtm8OKfqr2/FTNU= github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc h1:PTfri+PuQmWDqERdnNMiD9ZejrlswWrCpBEZgWOiTrc= github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc/go.mod h1:cGKTAVKx4SxOuR/czcZ/E2RSJ3sfHs8FpHhQ5CWMf9s= -github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= -github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM= github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= @@ -458,30 +455,26 @@ github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyua github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/moricho/tparallel v0.3.2 h1:odr8aZVFA3NZrNybggMkYO3rgPRcqjeQUlBBFVxKHTI= github.com/moricho/tparallel v0.3.2/go.mod h1:OQ+K3b4Ln3l2TZveGCywybl68glfLEwFGqvnjok8b+U= -github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/multiformats/go-base32 v0.1.0 h1:pVx9xoSPqEIQG8o+UbAe7DNi51oej1NtK+aGkbLYxPE= github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYgtWibDcT0rExnbI= github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0= github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4= -github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4= github.com/multiformats/go-multiaddr v0.13.0 h1:BCBzs61E3AGHcYYTv8dqRH43ZfyrqM8RXVPT8t13tLQ= github.com/multiformats/go-multiaddr v0.13.0/go.mod h1:sBXrNzucqkFJhvKOiwwLyqamGa/P5EIXNPLovyhQCII= -github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A= -github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk= +github.com/multiformats/go-multiaddr-dns v0.4.0 h1:P76EJ3qzBXpUXZ3twdCDx/kvagMsNo0LMFXpyms/zgU= +github.com/multiformats/go-multiaddr-dns v0.4.0/go.mod h1:7hfthtB4E4pQwirrz+J0CcDUfbWzTqEzVyYKKIKpgkc= github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E= github.com/multiformats/go-multiaddr-fmt v0.1.0/go.mod h1:hGtDIW4PU4BqJ50gW2quDuPVjyWNZxToGUh/HwTZYJo= github.com/multiformats/go-multibase v0.2.0 h1:isdYCVLvksgWlMW9OZRYJEa9pZETFivncJHmHnnd87g= github.com/multiformats/go-multibase v0.2.0/go.mod h1:bFBZX4lKCA/2lyOFSAoKH5SS6oPyjtnzK/XTFDPkNuk= github.com/multiformats/go-multicodec v0.9.0 h1:pb/dlPnzee/Sxv/j4PmkDRxCOi3hXTz3IbPKOXWJkmg= github.com/multiformats/go-multicodec v0.9.0/go.mod h1:L3QTQvMIaVBkXOXXtVmYE+LI16i14xuaojr/H7Ai54k= -github.com/multiformats/go-multihash v0.0.8/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= github.com/multiformats/go-multihash v0.2.3 h1:7Lyc8XfX/IY2jWb/gI7JP+o7JEq9hOa7BFvVU9RSh+U= github.com/multiformats/go-multihash v0.2.3/go.mod h1:dXgKXCXjBzdscBLk9JkjINiEsCKRVch90MdaGiKsvSM= github.com/multiformats/go-multistream v0.5.0 h1:5htLSLl7lvJk3xx3qT/8Zm9J4K8vEOf/QGkvOGQAyiE= github.com/multiformats/go-multistream v0.5.0/go.mod h1:n6tMZiwiP2wUsR8DgfDWw1dydlEqV3l6N3/GBsX6ILA= -github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8= github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= @@ -760,7 +753,6 @@ go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= @@ -852,7 +844,6 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= From 1bc773fd8b16393847b8d8df388095fa97fa520a Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Thu, 3 Oct 2024 22:03:58 +0200 Subject: [PATCH 1171/1212] chore: dependency updates for 0.31 (#10511) * chore: client_golang v1.20.4 * chore: go-libp2p-kbucket v0.6.4 * chore: go-libp2p v0.36.4 * chore: go-car/v2 v2.14 * chore: go-ipld-cbor v0.2.0 --- docs/changelogs/v0.31.md | 7 ++++ docs/examples/kubo-as-a-library/go.mod | 18 ++++---- docs/examples/kubo-as-a-library/go.sum | 36 ++++++++-------- go.mod | 24 +++++------ go.sum | 42 ++++++++++--------- test/dependencies/go.mod | 12 +++--- test/dependencies/go.sum | 24 +++++------ .../t0119-prometheus-data/prometheus_metrics | 6 ++- 8 files changed, 91 insertions(+), 78 deletions(-) diff --git a/docs/changelogs/v0.31.md b/docs/changelogs/v0.31.md index ef1d4bb1b..1d6501ec9 100644 --- a/docs/changelogs/v0.31.md +++ b/docs/changelogs/v0.31.md @@ -6,6 +6,7 @@ - [Overview](#overview) - [🔦 Highlights](#-highlights) + - [New metrics](#new-metrics) - [`lowpower` profile no longer breaks DHT announcements](#lowpower-profile-no-longer-breaks-dht-announcements) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -14,6 +15,12 @@ ### 🔦 Highlights +#### New metrics + +- Added 3 new go metrics: `go_gc_gogc_percent`, `go_gc_gomemlimit_bytes` and `go_sched_gomaxprocs_threads` as those are [recommended by the Go team](https://github.com/prometheus/client_golang/pull/1559) +- Added [network usage metrics](https://github.com/prometheus/client_golang/pull/1555): `process_network_receive_bytes_total` and `process_network_transmit_bytes_total` +- Removed `go_memstat_lookups_total` metric [which was always 0](https://github.com/prometheus/client_golang/pull/1577) + #### `lowpower` profile no longer breaks DHT announcements We've notices users were applying `lowpower` profile, and then reporting content routing issues. This was because `lowpower` disabled reprovider system and locally hosted data was no longer announced on Amino DHT. diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 9cdd51319..6c0600757 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -82,7 +82,7 @@ require ( github.com/ipfs/go-ipfs-pq v0.0.3 // indirect github.com/ipfs/go-ipfs-redirects-file v0.1.1 // indirect github.com/ipfs/go-ipfs-util v0.0.3 // indirect - github.com/ipfs/go-ipld-cbor v0.1.0 // indirect + github.com/ipfs/go-ipld-cbor v0.2.0 // indirect github.com/ipfs/go-ipld-format v0.6.0 // indirect github.com/ipfs/go-ipld-git v0.1.1 // indirect github.com/ipfs/go-ipld-legacy v0.2.1 // indirect @@ -94,7 +94,7 @@ require ( github.com/ipfs/go-unixfsnode v1.9.1 // indirect github.com/ipfs/go-verifcid v0.0.3 // indirect github.com/ipld/go-car v0.6.2 // indirect - github.com/ipld/go-car/v2 v2.13.1 // indirect + github.com/ipld/go-car/v2 v2.14.2 // indirect github.com/ipld/go-codec-dagpb v1.6.0 // indirect github.com/ipld/go-ipld-prime v0.21.0 // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect @@ -109,7 +109,7 @@ require ( github.com/libp2p/go-flow-metrics v0.1.0 // indirect github.com/libp2p/go-libp2p-asn-util v0.4.1 // indirect github.com/libp2p/go-libp2p-kad-dht v0.26.1 // indirect - github.com/libp2p/go-libp2p-kbucket v0.6.3 // indirect + github.com/libp2p/go-libp2p-kbucket v0.6.4 // indirect github.com/libp2p/go-libp2p-pubsub v0.11.0 // indirect github.com/libp2p/go-libp2p-pubsub-router v0.6.0 // indirect github.com/libp2p/go-libp2p-record v0.2.0 // indirect @@ -164,7 +164,7 @@ require ( github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/polydawn/refmt v0.89.0 // indirect - github.com/prometheus/client_golang v1.19.1 // indirect + github.com/prometheus/client_golang v1.20.4 // indirect github.com/prometheus/client_model v0.6.1 // indirect github.com/prometheus/common v0.55.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect @@ -203,15 +203,15 @@ require ( go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect go4.org v0.0.0-20230225012048-214862532bf5 // indirect - golang.org/x/crypto v0.25.0 // indirect + golang.org/x/crypto v0.27.0 // indirect golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect golang.org/x/mod v0.19.0 // indirect golang.org/x/net v0.27.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.24.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.25.0 // indirect + golang.org/x/text v0.18.0 // indirect golang.org/x/tools v0.23.0 // indirect - golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9 // indirect + golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect gonum.org/v1/gonum v0.15.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240617180043-68d350f18fd4 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240617180043-68d350f18fd4 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 387634d3a..2cd9a72e5 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -326,8 +326,8 @@ github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyB github.com/ipfs/go-ipfs-util v0.0.2/go.mod h1:CbPtkWJzjLdEcezDns2XYaehFVNXG9zrdrtMecczcsQ= github.com/ipfs/go-ipfs-util v0.0.3 h1:2RFdGez6bu2ZlZdI+rWfIdbQb1KudQp3VGwPtdNCmE0= github.com/ipfs/go-ipfs-util v0.0.3/go.mod h1:LHzG1a0Ig4G+iZ26UUOMjHd+lfM84LZCrn17xAKWBvs= -github.com/ipfs/go-ipld-cbor v0.1.0 h1:dx0nS0kILVivGhfWuB6dUpMa/LAwElHPw1yOGYopoYs= -github.com/ipfs/go-ipld-cbor v0.1.0/go.mod h1:U2aYlmVrJr2wsUBU67K4KgepApSZddGRDWBYR0H4sCk= +github.com/ipfs/go-ipld-cbor v0.2.0 h1:VHIW3HVIjcMd8m4ZLZbrYpwjzqlVUfjLM7oK4T5/YF0= +github.com/ipfs/go-ipld-cbor v0.2.0/go.mod h1:Cp8T7w1NKcu4AQJLqK0tWpd1nkgTxEVB5C6kVpLW6/0= github.com/ipfs/go-ipld-format v0.6.0 h1:VEJlA2kQ3LqFSIm5Vu6eIlSxD/Ze90xtc4Meten1F5U= github.com/ipfs/go-ipld-format v0.6.0/go.mod h1:g4QVMTn3marU3qXchwjpKPKgJv+zF+OlaKMyhJ4LHPg= github.com/ipfs/go-ipld-git v0.1.1 h1:TWGnZjS0htmEmlMFEkA3ogrNCqWjIxwr16x1OsdhG+Y= @@ -360,8 +360,8 @@ github.com/ipfs/go-verifcid v0.0.3 h1:gmRKccqhWDocCRkC+a59g5QW7uJw5bpX9HWBevXa0z github.com/ipfs/go-verifcid v0.0.3/go.mod h1:gcCtGniVzelKrbk9ooUSX/pM3xlH73fZZJDzQJRvOUw= github.com/ipld/go-car v0.6.2 h1:Hlnl3Awgnq8icK+ze3iRghk805lu8YNq3wlREDTF2qc= github.com/ipld/go-car v0.6.2/go.mod h1:oEGXdwp6bmxJCZ+rARSkDliTeYnVzv3++eXajZ+Bmr8= -github.com/ipld/go-car/v2 v2.13.1 h1:KnlrKvEPEzr5IZHKTXLAEub+tPrzeAFQVRlSQvuxBO4= -github.com/ipld/go-car/v2 v2.13.1/go.mod h1:QkdjjFNGit2GIkpQ953KBwowuoukoM75nP/JI1iDJdo= +github.com/ipld/go-car/v2 v2.14.2 h1:9ERr7KXpCC7If0rChZLhYDlyr6Bes6yRKPJnCO3hdHY= +github.com/ipld/go-car/v2 v2.14.2/go.mod h1:0iPB/825lTZLU2zPK5bVTk/R3V2612E1VI279OGSXWA= github.com/ipld/go-codec-dagpb v1.6.0 h1:9nYazfyu9B1p3NAgfVdpRco3Fs2nFC72DqVsMj6rOcc= github.com/ipld/go-codec-dagpb v1.6.0/go.mod h1:ANzFhfP2uMJxRBr8CE+WQWs5UsNa0pYtmKZ+agnUw9s= github.com/ipld/go-ipld-prime v0.11.0/go.mod h1:+WIAkokurHmZ/KwzDOMUuoeJgaRQktHtEaLglS3ZeV8= @@ -436,8 +436,8 @@ github.com/libp2p/go-libp2p-core v0.3.0/go.mod h1:ACp3DmS3/N64c2jDzcV429ukDpicbL github.com/libp2p/go-libp2p-kad-dht v0.26.1 h1:AazV3LCImYVkDUGAHx5lIEgZ9iUI2QQKH5GMRQU8uEA= github.com/libp2p/go-libp2p-kad-dht v0.26.1/go.mod h1:mqRUGJ/+7ziQ3XknU2kKHfsbbgb9xL65DXjPOJwmZF8= github.com/libp2p/go-libp2p-kbucket v0.3.1/go.mod h1:oyjT5O7tS9CQurok++ERgc46YLwEpuGoFq9ubvoUOio= -github.com/libp2p/go-libp2p-kbucket v0.6.3 h1:p507271wWzpy2f1XxPzCQG9NiN6R6lHL9GiSErbQQo0= -github.com/libp2p/go-libp2p-kbucket v0.6.3/go.mod h1:RCseT7AH6eJWxxk2ol03xtP9pEHetYSPXOaJnOiD8i0= +github.com/libp2p/go-libp2p-kbucket v0.6.4 h1:OjfiYxU42TKQSB8t8WYd8MKhYhMJeO2If+NiuKfb6iQ= +github.com/libp2p/go-libp2p-kbucket v0.6.4/go.mod h1:jp6w82sczYaBsAypt5ayACcRJi0lgsba7o4TzJKEfWA= github.com/libp2p/go-libp2p-peerstore v0.1.4/go.mod h1:+4BDbDiiKf4PzpANZDAT+knVdLxvqh7hXOujessqdzs= github.com/libp2p/go-libp2p-pubsub v0.11.0 h1:+JvS8Kty0OiyUiN0i8H5JbaCgjnJTRnTHe4rU88dLFc= github.com/libp2p/go-libp2p-pubsub v0.11.0/go.mod h1:QEb+hEV9WL9wCiUAnpY29FZR6W3zK8qYlaml8R4q6gQ= @@ -636,8 +636,8 @@ github.com/polydawn/refmt v0.0.0-20201211092308-30ac6d18308e/go.mod h1:uIp+gprXx github.com/polydawn/refmt v0.89.0 h1:ADJTApkvkeBZsN0tBTx8QjpD9JkmxbKp0cxfr9qszm4= github.com/polydawn/refmt v0.89.0/go.mod h1:/zvteZs/GwLtCgZ4BL6CBsk9IKIlexP43ObX9AxTqTw= github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE= -github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho= +github.com/prometheus/client_golang v1.20.4 h1:Tgh3Yr67PaOv/uTqloMsCEdeuFTatm5zIq5+qNN23vI= +github.com/prometheus/client_golang v1.20.4/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= @@ -852,8 +852,8 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= +golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -944,8 +944,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/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= @@ -999,8 +999,8 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= -golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= +golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -1020,8 +1020,8 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= +golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1070,8 +1070,8 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9 h1:LLhsEBxRTBLuKlQxFBYUOU8xyFgXv6cOTp2HASDlsDk= -golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= +golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da h1:noIWHXmPHxILtqtCOPIhSt0ABwskkZKjD3bXGnZGpNY= +golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= gonum.org/v1/gonum v0.15.0 h1:2lYxjRbTYyxkJxlhC+LvJIx3SsANPdRybu1tGj9/OrQ= gonum.org/v1/gonum v0.15.0/go.mod h1:xzZVBJBtS+Mz4q0Yl2LJTk+OxOg4jiXZ7qBoM0uISGo= google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= diff --git a/go.mod b/go.mod index db6a05c0c..5f27e27a8 100644 --- a/go.mod +++ b/go.mod @@ -1,5 +1,7 @@ module github.com/ipfs/kubo +go 1.22 + require ( bazil.org/fuse v0.0.0-20200117225306-7b5117fecadc contrib.go.opencensus.io/exporter/prometheus v0.4.2 @@ -30,7 +32,7 @@ require ( github.com/ipfs/go-ds-measure v0.2.0 github.com/ipfs/go-fs-lock v0.0.7 github.com/ipfs/go-ipfs-cmds v0.13.0 - github.com/ipfs/go-ipld-cbor v0.1.0 + github.com/ipfs/go-ipld-cbor v0.2.0 github.com/ipfs/go-ipld-format v0.6.0 github.com/ipfs/go-ipld-git v0.1.1 github.com/ipfs/go-ipld-legacy v0.2.1 @@ -41,7 +43,7 @@ require ( github.com/ipfs/go-test v0.0.4 github.com/ipfs/go-unixfsnode v1.9.1 github.com/ipld/go-car v0.6.2 - github.com/ipld/go-car/v2 v2.13.1 + github.com/ipld/go-car/v2 v2.14.2 github.com/ipld/go-codec-dagpb v1.6.0 github.com/ipld/go-ipld-prime v0.21.0 github.com/jbenet/go-temp-err-catcher v0.1.0 @@ -51,7 +53,7 @@ require ( github.com/libp2p/go-libp2p v0.36.4 github.com/libp2p/go-libp2p-http v0.5.0 github.com/libp2p/go-libp2p-kad-dht v0.26.1 - github.com/libp2p/go-libp2p-kbucket v0.6.3 + github.com/libp2p/go-libp2p-kbucket v0.6.4 github.com/libp2p/go-libp2p-pubsub v0.11.0 github.com/libp2p/go-libp2p-pubsub-router v0.6.0 github.com/libp2p/go-libp2p-record v0.2.0 @@ -66,7 +68,7 @@ require ( github.com/multiformats/go-multihash v0.2.3 github.com/opentracing/opentracing-go v1.2.0 github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 - github.com/prometheus/client_golang v1.19.1 + github.com/prometheus/client_golang v1.20.4 github.com/stretchr/testify v1.9.0 github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 github.com/tidwall/gjson v1.14.4 @@ -83,11 +85,11 @@ require ( go.uber.org/fx v1.22.1 go.uber.org/multierr v1.11.0 go.uber.org/zap v1.27.0 - golang.org/x/crypto v0.25.0 + golang.org/x/crypto v0.27.0 golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 golang.org/x/mod v0.19.0 - golang.org/x/sync v0.7.0 - golang.org/x/sys v0.24.0 + golang.org/x/sync v0.8.0 + golang.org/x/sys v0.25.0 google.golang.org/protobuf v1.34.2 ) @@ -237,10 +239,10 @@ require ( go4.org v0.0.0-20230225012048-214862532bf5 // indirect golang.org/x/net v0.27.0 // indirect golang.org/x/oauth2 v0.21.0 // indirect - golang.org/x/term v0.23.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/term v0.24.0 // indirect + golang.org/x/text v0.18.0 // indirect golang.org/x/tools v0.23.0 // indirect - golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9 // indirect + golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect gonum.org/v1/gonum v0.15.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240617180043-68d350f18fd4 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240617180043-68d350f18fd4 // indirect @@ -250,5 +252,3 @@ require ( gopkg.in/yaml.v3 v3.0.1 // indirect lukechampine.com/blake3 v1.3.0 // indirect ) - -go 1.22 diff --git a/go.sum b/go.sum index 4453c254d..0c5e5bbd6 100644 --- a/go.sum +++ b/go.sum @@ -392,8 +392,8 @@ github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyB github.com/ipfs/go-ipfs-util v0.0.2/go.mod h1:CbPtkWJzjLdEcezDns2XYaehFVNXG9zrdrtMecczcsQ= github.com/ipfs/go-ipfs-util v0.0.3 h1:2RFdGez6bu2ZlZdI+rWfIdbQb1KudQp3VGwPtdNCmE0= github.com/ipfs/go-ipfs-util v0.0.3/go.mod h1:LHzG1a0Ig4G+iZ26UUOMjHd+lfM84LZCrn17xAKWBvs= -github.com/ipfs/go-ipld-cbor v0.1.0 h1:dx0nS0kILVivGhfWuB6dUpMa/LAwElHPw1yOGYopoYs= -github.com/ipfs/go-ipld-cbor v0.1.0/go.mod h1:U2aYlmVrJr2wsUBU67K4KgepApSZddGRDWBYR0H4sCk= +github.com/ipfs/go-ipld-cbor v0.2.0 h1:VHIW3HVIjcMd8m4ZLZbrYpwjzqlVUfjLM7oK4T5/YF0= +github.com/ipfs/go-ipld-cbor v0.2.0/go.mod h1:Cp8T7w1NKcu4AQJLqK0tWpd1nkgTxEVB5C6kVpLW6/0= github.com/ipfs/go-ipld-format v0.6.0 h1:VEJlA2kQ3LqFSIm5Vu6eIlSxD/Ze90xtc4Meten1F5U= github.com/ipfs/go-ipld-format v0.6.0/go.mod h1:g4QVMTn3marU3qXchwjpKPKgJv+zF+OlaKMyhJ4LHPg= github.com/ipfs/go-ipld-git v0.1.1 h1:TWGnZjS0htmEmlMFEkA3ogrNCqWjIxwr16x1OsdhG+Y= @@ -428,8 +428,8 @@ github.com/ipfs/go-verifcid v0.0.3 h1:gmRKccqhWDocCRkC+a59g5QW7uJw5bpX9HWBevXa0z github.com/ipfs/go-verifcid v0.0.3/go.mod h1:gcCtGniVzelKrbk9ooUSX/pM3xlH73fZZJDzQJRvOUw= github.com/ipld/go-car v0.6.2 h1:Hlnl3Awgnq8icK+ze3iRghk805lu8YNq3wlREDTF2qc= github.com/ipld/go-car v0.6.2/go.mod h1:oEGXdwp6bmxJCZ+rARSkDliTeYnVzv3++eXajZ+Bmr8= -github.com/ipld/go-car/v2 v2.13.1 h1:KnlrKvEPEzr5IZHKTXLAEub+tPrzeAFQVRlSQvuxBO4= -github.com/ipld/go-car/v2 v2.13.1/go.mod h1:QkdjjFNGit2GIkpQ953KBwowuoukoM75nP/JI1iDJdo= +github.com/ipld/go-car/v2 v2.14.2 h1:9ERr7KXpCC7If0rChZLhYDlyr6Bes6yRKPJnCO3hdHY= +github.com/ipld/go-car/v2 v2.14.2/go.mod h1:0iPB/825lTZLU2zPK5bVTk/R3V2612E1VI279OGSXWA= github.com/ipld/go-codec-dagpb v1.6.0 h1:9nYazfyu9B1p3NAgfVdpRco3Fs2nFC72DqVsMj6rOcc= github.com/ipld/go-codec-dagpb v1.6.0/go.mod h1:ANzFhfP2uMJxRBr8CE+WQWs5UsNa0pYtmKZ+agnUw9s= github.com/ipld/go-ipld-prime v0.11.0/go.mod h1:+WIAkokurHmZ/KwzDOMUuoeJgaRQktHtEaLglS3ZeV8= @@ -492,6 +492,8 @@ github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/libp2p/go-buffer-pool v0.0.1/go.mod h1:xtyIz9PMobb13WaxR6Zo1Pd1zXJKYg0a8KiIvDp3TzQ= github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM= github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= @@ -517,8 +519,8 @@ github.com/libp2p/go-libp2p-http v0.5.0/go.mod h1:glh87nZ35XCQyFsdzZps6+F4HYI6Dc github.com/libp2p/go-libp2p-kad-dht v0.26.1 h1:AazV3LCImYVkDUGAHx5lIEgZ9iUI2QQKH5GMRQU8uEA= github.com/libp2p/go-libp2p-kad-dht v0.26.1/go.mod h1:mqRUGJ/+7ziQ3XknU2kKHfsbbgb9xL65DXjPOJwmZF8= github.com/libp2p/go-libp2p-kbucket v0.3.1/go.mod h1:oyjT5O7tS9CQurok++ERgc46YLwEpuGoFq9ubvoUOio= -github.com/libp2p/go-libp2p-kbucket v0.6.3 h1:p507271wWzpy2f1XxPzCQG9NiN6R6lHL9GiSErbQQo0= -github.com/libp2p/go-libp2p-kbucket v0.6.3/go.mod h1:RCseT7AH6eJWxxk2ol03xtP9pEHetYSPXOaJnOiD8i0= +github.com/libp2p/go-libp2p-kbucket v0.6.4 h1:OjfiYxU42TKQSB8t8WYd8MKhYhMJeO2If+NiuKfb6iQ= +github.com/libp2p/go-libp2p-kbucket v0.6.4/go.mod h1:jp6w82sczYaBsAypt5ayACcRJi0lgsba7o4TzJKEfWA= github.com/libp2p/go-libp2p-peerstore v0.1.4/go.mod h1:+4BDbDiiKf4PzpANZDAT+knVdLxvqh7hXOujessqdzs= github.com/libp2p/go-libp2p-pubsub v0.11.0 h1:+JvS8Kty0OiyUiN0i8H5JbaCgjnJTRnTHe4rU88dLFc= github.com/libp2p/go-libp2p-pubsub v0.11.0/go.mod h1:QEb+hEV9WL9wCiUAnpY29FZR6W3zK8qYlaml8R4q6gQ= @@ -743,8 +745,8 @@ github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqr github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_golang v1.12.2/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_golang v1.13.0/go.mod h1:vTeo+zgvILHsnnj/39Ou/1fPN5nJFOEMgftOUOmlvYQ= -github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE= -github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho= +github.com/prometheus/client_golang v1.20.4 h1:Tgh3Yr67PaOv/uTqloMsCEdeuFTatm5zIq5+qNN23vI= +github.com/prometheus/client_golang v1.20.4/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -1010,8 +1012,8 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= +golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1130,8 +1132,8 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/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= @@ -1206,8 +1208,8 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= -golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= +golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -1216,8 +1218,8 @@ golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= -golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= -golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= +golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM= +golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1229,8 +1231,8 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= +golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1296,8 +1298,8 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9 h1:LLhsEBxRTBLuKlQxFBYUOU8xyFgXv6cOTp2HASDlsDk= -golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= +golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da h1:noIWHXmPHxILtqtCOPIhSt0ABwskkZKjD3bXGnZGpNY= +golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= gonum.org/v1/gonum v0.15.0 h1:2lYxjRbTYyxkJxlhC+LvJIx3SsANPdRybu1tGj9/OrQ= gonum.org/v1/gonum v0.15.0/go.mod h1:xzZVBJBtS+Mz4q0Yl2LJTk+OxOg4jiXZ7qBoM0uISGo= google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 5f77201ee..29a0cf35a 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -145,7 +145,7 @@ require ( github.com/libp2p/go-libp2p v0.36.4 // indirect github.com/libp2p/go-libp2p-asn-util v0.4.1 // indirect github.com/libp2p/go-libp2p-kad-dht v0.26.1 // indirect - github.com/libp2p/go-libp2p-kbucket v0.6.3 // indirect + github.com/libp2p/go-libp2p-kbucket v0.6.4 // indirect github.com/libp2p/go-libp2p-record v0.2.0 // indirect github.com/libp2p/go-libp2p-routing-helpers v0.7.4 // indirect github.com/libp2p/go-msgio v0.3.0 // indirect @@ -185,7 +185,7 @@ require ( github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/polydawn/refmt v0.89.0 // indirect github.com/polyfloyd/go-errorlint v1.6.0 // indirect - github.com/prometheus/client_golang v1.19.1 // indirect + github.com/prometheus/client_golang v1.20.4 // indirect github.com/prometheus/client_model v0.6.1 // indirect github.com/prometheus/common v0.55.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect @@ -250,15 +250,15 @@ require ( go.uber.org/automaxprocs v1.5.3 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect - golang.org/x/crypto v0.26.0 // indirect + golang.org/x/crypto v0.27.0 // indirect golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect golang.org/x/exp/typeparams v0.0.0-20240613232115-7f521ea00fb8 // indirect golang.org/x/mod v0.20.0 // indirect golang.org/x/net v0.28.0 // indirect golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.24.0 // indirect - golang.org/x/term v0.23.0 // indirect - golang.org/x/text v0.17.0 // indirect + golang.org/x/sys v0.25.0 // indirect + golang.org/x/term v0.24.0 // indirect + golang.org/x/text v0.18.0 // indirect golang.org/x/tools v0.24.0 // indirect gonum.org/v1/gonum v0.15.0 // indirect google.golang.org/protobuf v1.34.2 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 168d9abd8..d930da41b 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -394,8 +394,8 @@ github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl9 github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= github.com/libp2p/go-libp2p-kad-dht v0.26.1 h1:AazV3LCImYVkDUGAHx5lIEgZ9iUI2QQKH5GMRQU8uEA= github.com/libp2p/go-libp2p-kad-dht v0.26.1/go.mod h1:mqRUGJ/+7ziQ3XknU2kKHfsbbgb9xL65DXjPOJwmZF8= -github.com/libp2p/go-libp2p-kbucket v0.6.3 h1:p507271wWzpy2f1XxPzCQG9NiN6R6lHL9GiSErbQQo0= -github.com/libp2p/go-libp2p-kbucket v0.6.3/go.mod h1:RCseT7AH6eJWxxk2ol03xtP9pEHetYSPXOaJnOiD8i0= +github.com/libp2p/go-libp2p-kbucket v0.6.4 h1:OjfiYxU42TKQSB8t8WYd8MKhYhMJeO2If+NiuKfb6iQ= +github.com/libp2p/go-libp2p-kbucket v0.6.4/go.mod h1:jp6w82sczYaBsAypt5ayACcRJi0lgsba7o4TzJKEfWA= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= github.com/libp2p/go-libp2p-record v0.2.0/go.mod h1:I+3zMkvvg5m2OcSdoL0KPljyJyvNDFGKX7QdlpYUcwk= github.com/libp2p/go-libp2p-routing-helpers v0.7.4 h1:6LqS1Bzn5CfDJ4tzvP9uwh42IB7TJLNFJA6dEeGBv84= @@ -552,8 +552,8 @@ github.com/polyfloyd/go-errorlint v1.6.0 h1:tftWV9DE7txiFzPpztTAwyoRLKNj9gpVm2cg github.com/polyfloyd/go-errorlint v1.6.0/go.mod h1:HR7u8wuP1kb1NeN1zqTd1ZMlqUKPPHF+Id4vIPvDqVw= github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g= github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U= -github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE= -github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho= +github.com/prometheus/client_golang v1.20.4 h1:Tgh3Yr67PaOv/uTqloMsCEdeuFTatm5zIq5+qNN23vI= +github.com/prometheus/client_golang v1.20.4/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= @@ -762,8 +762,8 @@ golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliY golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= -golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= -golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= +golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= +golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= @@ -867,8 +867,8 @@ golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= -golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= +golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -882,8 +882,8 @@ golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= -golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= -golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= +golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM= +golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -896,8 +896,8 @@ golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= -golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= +golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= diff --git a/test/sharness/t0119-prometheus-data/prometheus_metrics b/test/sharness/t0119-prometheus-data/prometheus_metrics index f3ba65c97..f575bf778 100644 --- a/test/sharness/t0119-prometheus-data/prometheus_metrics +++ b/test/sharness/t0119-prometheus-data/prometheus_metrics @@ -80,6 +80,8 @@ flatfs_datastore_sync_total go_gc_duration_seconds go_gc_duration_seconds_count go_gc_duration_seconds_sum +go_gc_gogc_percent +go_gc_gomemlimit_bytes go_goroutines go_info go_memstats_alloc_bytes @@ -94,7 +96,6 @@ go_memstats_heap_objects go_memstats_heap_released_bytes go_memstats_heap_sys_bytes go_memstats_last_gc_time_seconds -go_memstats_lookups_total go_memstats_mallocs_total go_memstats_mcache_inuse_bytes go_memstats_mcache_sys_bytes @@ -105,6 +106,7 @@ go_memstats_other_sys_bytes go_memstats_stack_inuse_bytes go_memstats_stack_sys_bytes go_memstats_sys_bytes +go_sched_gomaxprocs_threads go_threads ipfs_bitswap_active_block_tasks ipfs_bitswap_active_tasks @@ -359,6 +361,8 @@ libp2p_swarm_dial_ranking_delay_seconds_count libp2p_swarm_dial_ranking_delay_seconds_sum process_cpu_seconds_total process_max_fds +process_network_receive_bytes_total +process_network_transmit_bytes_total process_open_fds process_resident_memory_bytes process_start_time_seconds From 52b00624cde178e04e406560af2252c85376fab6 Mon Sep 17 00:00:00 2001 From: Andrew Gillis <11790789+gammazero@users.noreply.github.com> Date: Thu, 3 Oct 2024 13:58:14 -0700 Subject: [PATCH 1172/1212] feat: pebbleds profile and plugin (#10530) * include pebble as built-in plugin Pebble provides a high-performance alternative to leveldb as the datastore, and will serve as a replacement for badger1. There are a number of tuning parameters available for tuning pebble's performance to your specific needs. Default values are used for any that are not configured or are set to the parameter's zero-value. Requires https://github.com/ipfs/go-ds-pebble/pull/39 Closes #10347 * docs: remove mention of ipfs-ds-convert. Rationale: https://github.com/ipfs/ipfs-ds-convert/issues/50 * docs: pebbleds profile * test: meaningful t0025-datastores.sh * Update config/init.go * Update docs/config.md * Do not hard-code zero values into pebble config --- config/init.go | 11 ++ config/profile.go | 39 +++- docs/changelogs/v0.31.md | 10 + docs/config.md | 45 +++-- docs/datastores.md | 36 ++++ docs/examples/kubo-as-a-library/go.mod | 12 ++ docs/examples/kubo-as-a-library/go.sum | 26 +++ go.mod | 14 +- go.sum | 33 +++- plugin/loader/preload.go | 2 + plugin/loader/preload_list | 3 +- plugin/plugins/flatfs/flatfs.go | 2 +- plugin/plugins/levelds/levelds.go | 2 +- plugin/plugins/pebbleds/pebbleds.go | 246 +++++++++++++++++++++++++ test/sharness/t0021-config.sh | 2 +- test/sharness/t0025-datastores.sh | 21 ++- 16 files changed, 476 insertions(+), 28 deletions(-) create mode 100644 plugin/plugins/pebbleds/pebbleds.go diff --git a/config/init.go b/config/init.go index 4a86aa518..6099712f4 100644 --- a/config/init.go +++ b/config/init.go @@ -138,6 +138,17 @@ func DefaultDatastoreConfig() Datastore { } } +func pebbleSpec() map[string]interface{} { + return map[string]interface{}{ + "type": "measure", + "prefix": "pebble.datastore", + "child": map[string]interface{}{ + "type": "pebbleds", + "path": "pebbleds", + }, + } +} + func badgerSpec() map[string]interface{} { return map[string]interface{}{ "type": "measure", diff --git a/config/profile.go b/config/profile.go index 0ee9225be..3a4329639 100644 --- a/config/profile.go +++ b/config/profile.go @@ -135,7 +135,11 @@ You should use this datastore if: * You want to minimize memory usage. * You are ok with the default speed of data import, or prefer to use --nocopy. -This profile may only be applied when first initializing the node. +See configuration documentation at: +https://github.com/ipfs/kubo/blob/master/docs/datastores.md#flatfs + +NOTE: This profile may only be applied when first initializing node at IPFS_PATH + via 'ipfs init --profile flatfs' `, InitOnly: true, @@ -144,6 +148,32 @@ This profile may only be applied when first initializing the node. return nil }, }, + "pebbleds": { + Description: `Configures the node to use the pebble high-performance datastore. + +Pebble is a LevelDB/RocksDB inspired key-value store focused on performance +and internal usage by CockroachDB. +You should use this datastore if: + +- You need a datastore that is focused on performance. +- You need reliability by default, but may choose to disable WAL for maximum performance when reliability is not critical. +- This datastore is good for multi-terabyte data sets. +- May benefit from tuning depending on read/write patterns and throughput. +- Performance is helped significantly by running on a system with plenty of memory. + +See configuration documentation at: +https://github.com/ipfs/kubo/blob/master/docs/datastores.md#pebbleds + +NOTE: This profile may only be applied when first initializing node at IPFS_PATH + via 'ipfs init --profile pebbleds' +`, + + InitOnly: true, + Transform: func(c *Config) error { + c.Datastore.Spec = pebbleSpec() + return nil + }, + }, "badgerds": { Description: `Configures the node to use the legacy badgerv1 datastore. @@ -160,7 +190,12 @@ Other caveats: * Good for medium-size datastores, but may run into performance issues if your dataset is bigger than a terabyte. -This profile may only be applied when first initializing the node.`, +See configuration documentation at: +https://github.com/ipfs/kubo/blob/master/docs/datastores.md#badgerds + +NOTE: This profile may only be applied when first initializing node at IPFS_PATH + via 'ipfs init --profile badgerds' +`, InitOnly: true, Transform: func(c *Config) error { diff --git a/docs/changelogs/v0.31.md b/docs/changelogs/v0.31.md index 1d6501ec9..0b814ff65 100644 --- a/docs/changelogs/v0.31.md +++ b/docs/changelogs/v0.31.md @@ -6,6 +6,7 @@ - [Overview](#overview) - [🔦 Highlights](#-highlights) + - [Experimental Pebble Datastore](#experimental-pebble-datastore) - [New metrics](#new-metrics) - [`lowpower` profile no longer breaks DHT announcements](#lowpower-profile-no-longer-breaks-dht-announcements) - [📝 Changelog](#-changelog) @@ -15,6 +16,15 @@ ### 🔦 Highlights +#### Experimental Pebble Datastore + +[Pebble](https://github.com/ipfs/kubo/blob/master/docs/config.md#pebbleds-profile) provides a high-performance alternative to leveldb as the datastore, and provides a modern replacement for [legacy badgerv1](https://github.com/ipfs/kubo/blob/master/docs/config.md#badgerds-profile). + +A fresh Kubo node can be initialized with [`pebbleds` profile](https://github.com/ipfs/kubo/blob/master/docs/config.md#pebbleds-profile) via `ipfs init --profile pebbleds`. + +There are a number of parameters available for tuning pebble's performance to your specific needs. Default values are used for any parameters that are not configured or are set to their zero-value. +For a description of the available tuning parameters, see [kubo/docs/datastores.md#pebbleds](https://github.com/ipfs/kubo/blob/master/docs/datastores.md#pebbleds). + #### New metrics - Added 3 new go metrics: `go_gc_gogc_percent`, `go_gc_gomemlimit_bytes` and `go_sched_gomaxprocs_threads` as those are [recommended by the Go team](https://github.com/prometheus/client_golang/pull/1559) diff --git a/docs/config.md b/docs/config.md index 2bcf4b0f2..bbbb94bd8 100644 --- a/docs/config.md +++ b/docs/config.md @@ -181,6 +181,7 @@ config file at runtime. - [`local-discovery` profile](#local-discovery-profile) - [`default-networking` profile](#default-networking-profile) - [`flatfs` profile](#flatfs-profile) + - [`pebbleds` profile](#pebbleds-profile) - [`badgerds` profile](#badgerds-profile) - [`lowpower` profile](#lowpower-profile) - [`announce-off` profile](#announce-off-profile) @@ -524,13 +525,8 @@ Spec defines the structure of the ipfs datastore. It is a composable structure, where each datastore is represented by a json object. Datastores can wrap other datastores to provide extra functionality (eg metrics, logging, or caching). -This can be changed manually, however, if you make any changes that require a -different on-disk structure, you will need to run the [ipfs-ds-convert -tool](https://github.com/ipfs/ipfs-ds-convert) to migrate data into the new -structures. - -For more information on possible values for this configuration option, see -[docs/datastores.md](datastores.md) +> [!NOTE] +> For more information on possible values for this configuration option, see [`kubo/docs/datastores.md`](datastores.md) Default: ``` @@ -2403,9 +2399,9 @@ Inverse profile of the test profile. ### `flatfs` profile -Configures the node to use the flatfs datastore. Flatfs is the default datastore. +Configures the node to use the flatfs datastore. +Flatfs is the default, most battle-tested and reliable datastore. -This is the most battle-tested and reliable datastore. You should use this datastore if: - You need a very simple and very reliable datastore, and you trust your @@ -2416,7 +2412,30 @@ You should use this datastore if: - You want to minimize memory usage. - You are ok with the default speed of data import, or prefer to use `--nocopy`. -This profile may only be applied when first initializing the node. +> [!WARNING] +> This profile may only be applied when first initializing the node via `ipfs init --profile flatfs` + +> [!NOTE] +> See caveats and configuration options at [`datastores.md#flatfs`](datastores.md#flatfs) + +### `pebbleds` profile + +Configures the node to use the pebble high-performance datastore. + +Pebble is a LevelDB/RocksDB inspired key-value store focused on performance and internal usage by CockroachDB. +You should use this datastore if: + +- You need a datastore that is focused on performance. +- You need reliability by default, but may choose to disable WAL for maximum performance when reliability is not critical. +- This datastore is good for multi-terrabyte data sets. +- May benefit from tuning depending on read/write patterns and throughput. +- Performance is helped significantly by running on a system with plenty of memory. + +> [!WARNING] +> This profile may only be applied when first initializing the node via `ipfs init --profile pebbleds` + +> [!NOTE] +> See other caveats and configuration options at [`datastores.md#pebbleds`](datastores.md#pebbleds) ### `badgerds` profile @@ -2437,7 +2456,11 @@ Also, be aware that: - Good for medium-size datastores, but may run into performance issues if your dataset is bigger than a terabyte. - The current implementation is based on old badger 1.x which is no longer supported by the upstream team. -This profile may only be applied when first initializing the node. +> [!WARNING] +> This profile may only be applied when first initializing the node via `ipfs init --profile badgerds` + +> [!NOTE] +> See other caveats and configuration options at [`datastores.md#pebbleds`](datastores.md#pebbleds) ### `lowpower` profile diff --git a/docs/datastores.md b/docs/datastores.md index c18ecb0c7..f2051b601 100644 --- a/docs/datastores.md +++ b/docs/datastores.md @@ -3,6 +3,13 @@ This document describes the different possible values for the `Datastore.Spec` field in the ipfs configuration file. +- [flatfs](#flatfs) +- [levelds](#levelds) +- [pebbleds](#pebbleds) +- [badgerds](#badgerds) +- [mount](#mount) +- [measure](#measure) + ## flatfs Stores each key value pair as a file on the filesystem. @@ -35,6 +42,35 @@ Uses a leveldb database to store key value pairs. } ``` +## pebbleds + +Uses [pebble](https://github.com/cockroachdb/pebble) as a key value store. + +```json +{ + "type": "pebbleds", + "path": "", +} +``` + +The following options are availble for tuning pebble. +If they are not configured (or assigned their zero-valued), then default values are used. + +* `bytesPerSync`: int, Sync sstables periodically in order to smooth out writes to disk. (default: 512KB) +* `bisableWAL`: true|false, Disable the write-ahead log (WAL) at expense of prohibiting crash recovery. (default: false) +* `cacheSize`: Size of pebble's shared block cache. (default: 8MB) +* `l0CompactionThreshold`: int, Count of L0 files necessary to trigger an L0 compaction. +* `l0StopWritesThreshold`: int, Limit on L0 read-amplification, computed as the number of L0 sublevels. +* `lBaseMaxBytes`: int, Maximum number of bytes for LBase. The base level is the level which L0 is compacted into. +* `maxConcurrentCompactions`: int, Maximum number of concurrent compactions. (default: 1) +* `memTableSize`: int, Size of a MemTable in steady state. The actual MemTable size starts at min(256KB, MemTableSize) and doubles for each subsequent MemTable up to MemTableSize (default: 4MB) +* `memTableStopWritesThreshold`: int, Limit on the number of queued of MemTables. (default: 2) +* `walBytesPerSync`: int: Sets the number of bytes to write to a WAL before calling Sync on it in the background. (default: 0, no background syncing) +* `walMinSyncSeconds`: int: Sets the minimum duration between syncs of the WAL. (default: 0) + +> [!TIP] +> Start using pebble with only default values and configure tuning items are needed for your needs. For a more complete description of these values, see: `https://pkg.go.dev/github.com/cockroachdb/pebble@vA.B.C#Options` (where `A.B.C` is pebble version from Kubo's `go.mod`). + ## badgerds Uses [badger](https://github.com/dgraph-io/badger) as a key value store. diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 6c0600757..6b94d3802 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -16,6 +16,7 @@ require ( require ( bazil.org/fuse v0.0.0-20200117225306-7b5117fecadc // indirect github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 // indirect + github.com/DataDog/zstd v1.4.5 // indirect github.com/Jorropo/jsync v1.0.1 // indirect github.com/alecthomas/units v0.0.0-20240626203959-61d1e3462e30 // indirect github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5 // indirect @@ -25,6 +26,12 @@ require ( github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/ceramicnetwork/go-dag-jose v0.1.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/cockroachdb/errors v1.11.3 // indirect + github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce // indirect + github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect + github.com/cockroachdb/pebble v1.1.2 // indirect + github.com/cockroachdb/redact v1.1.5 // indirect + github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect github.com/containerd/cgroups v1.1.0 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect github.com/crackcomm/go-gitignore v0.0.0-20231225121904-e25f5bc08668 // indirect @@ -43,6 +50,7 @@ require ( github.com/francoispqt/gojay v1.2.13 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/gabriel-vasile/mimetype v1.4.4 // indirect + github.com/getsentry/sentry-go v0.27.0 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-task/slim-sprig/v3 v3.0.0 // indirect @@ -74,6 +82,7 @@ require ( github.com/ipfs/go-ds-flatfs v0.5.1 // indirect github.com/ipfs/go-ds-leveldb v0.5.0 // indirect github.com/ipfs/go-ds-measure v0.2.0 // indirect + github.com/ipfs/go-ds-pebble v0.4.0 // indirect github.com/ipfs/go-fs-lock v0.0.7 // indirect github.com/ipfs/go-ipfs-blockstore v1.3.1 // indirect github.com/ipfs/go-ipfs-delay v0.0.1 // indirect @@ -103,6 +112,8 @@ require ( github.com/klauspost/compress v1.17.9 // indirect github.com/klauspost/cpuid/v2 v2.2.8 // indirect github.com/koron/go-ssdp v0.0.4 // indirect + github.com/kr/pretty v0.3.1 // indirect + github.com/kr/text v0.2.0 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/libp2p/go-cidranger v1.1.0 // indirect github.com/libp2p/go-doh-resolver v0.4.0 // indirect @@ -172,6 +183,7 @@ require ( github.com/quic-go/quic-go v0.45.2 // indirect github.com/quic-go/webtransport-go v0.8.0 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect + github.com/rogpeppe/go-internal v1.12.0 // indirect github.com/samber/lo v1.46.0 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/stretchr/testify v1.9.0 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 2cd9a72e5..8b4c2ee8c 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -29,6 +29,8 @@ github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 h1:cTp8I5+VIo github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/DataDog/zstd v1.4.5 h1:EndNeuB0l9syBZhut0wns3gV1hL8zX8LIu6ZiVHWLIQ= +github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= github.com/Jorropo/jsync v1.0.1 h1:6HgRolFZnsdfzRUj+ImB9og1JYOxQoReSywkHOGSaUU= github.com/Jorropo/jsync v1.0.1/go.mod h1:jCOZj3vrBCri3bSU3ErUYvevKlnbssrXeCivybS5ABQ= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= @@ -74,6 +76,20 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMn github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs= 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= +github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f h1:otljaYPt5hWxV3MUfO5dFPFiOXg9CyG5/kCfayTqsJ4= +github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= +github.com/cockroachdb/errors v1.11.3 h1:5bA+k2Y6r+oz/6Z/RFlNeVCesGARKuC6YymtcDrbC/I= +github.com/cockroachdb/errors v1.11.3/go.mod h1:m4UIW4CDjx+R5cybPsNrRbreomiFqt8o1h1wUVazSd8= +github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce h1:giXvy4KSc/6g/esnpM7Geqxka4WSqI1SZc7sMJFd3y4= +github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce/go.mod h1:9/y3cnZ5GKakj/H4y9r9GTjCvAFta7KLgSHPJJYc52M= +github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE= +github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= +github.com/cockroachdb/pebble v1.1.2 h1:CUh2IPtR4swHlEj48Rhfzw6l/d0qA31fItcIszQVIsA= +github.com/cockroachdb/pebble v1.1.2/go.mod h1:4exszw1r40423ZsmkG/09AFEG83I0uDgfujJdbL6kYU= +github.com/cockroachdb/redact v1.1.5 h1:u1PMllDkdFfPWaNGMyLD1+so+aq3uUItthCFqzwPJ30= +github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= +github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo= +github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ= github.com/containerd/cgroups v0.0.0-20201119153540-4cbc285b3327/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE= github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM= github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw= @@ -143,10 +159,14 @@ github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nos github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/gabriel-vasile/mimetype v1.4.4 h1:QjV6pZ7/XZ7ryI2KuyeEDE8wnh7fHP9YnQy+R0LnH8I= github.com/gabriel-vasile/mimetype v1.4.4/go.mod h1:JwLei5XPtWdGiMFB5Pjle1oEeoSeEuJfJE+TtfvdB/s= +github.com/getsentry/sentry-go v0.27.0 h1:Pv98CIbtB3LkMWmXi4Joa5OOcwbmnX88sF5qbK3r3Ps= +github.com/getsentry/sentry-go v0.27.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= +github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= +github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= @@ -301,6 +321,8 @@ github.com/ipfs/go-ds-leveldb v0.5.0 h1:s++MEBbD3ZKc9/8/njrn4flZLnCuY9I79v94gBUN github.com/ipfs/go-ds-leveldb v0.5.0/go.mod h1:d3XG9RUDzQ6V4SHi8+Xgj9j1XuEk1z82lquxrVbml/Q= github.com/ipfs/go-ds-measure v0.2.0 h1:sG4goQe0KDTccHMyT45CY1XyUbxe5VwTKpg2LjApYyQ= github.com/ipfs/go-ds-measure v0.2.0/go.mod h1:SEUD/rE2PwRa4IQEC5FuNAmjJCyYObZr9UvVh8V3JxE= +github.com/ipfs/go-ds-pebble v0.4.0 h1:88lgFAs2ck8jCQ8lMYRBtksEg18r9BlvTxIMnNJkZaQ= +github.com/ipfs/go-ds-pebble v0.4.0/go.mod h1:ZyYU+weIni+4NG/Yjva+cPkU3ghlsU1HA2R/VLHJ9sM= github.com/ipfs/go-fs-lock v0.0.7 h1:6BR3dajORFrFTkb5EpCUFIAypsoxpGpDSVUdFwzgL9U= github.com/ipfs/go-fs-lock v0.0.7/go.mod h1:Js8ka+FNYmgQRLrRXzU3CB/+Csr1BwrRilEcvYrHhhc= github.com/ipfs/go-ipfs-blockstore v1.3.1 h1:cEI9ci7V0sRNivqaOr0elDsamxXFxJMMMy7PTTDQNsQ= @@ -585,6 +607,8 @@ github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhM github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 h1:1/WtZae0yGtPq+TI6+Tv1WTxkukpXeMlviSxvL7SRgk= github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9/go.mod h1:x3N5drFsm2uilKKuuYo6LdyD8vZAW55sH/9w+pbo1sw= +github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= +github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= github.com/pion/datachannel v1.5.8 h1:ph1P1NsGkazkjrvyMfhRBUAWMxugJjq2HfQifaOoSNo= github.com/pion/datachannel v1.5.8/go.mod h1:PgmdpoaNBLX9HNzNClmdki4DYW5JtI7Yibu8QzbL3tI= github.com/pion/dtls/v2 v2.2.7/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s= @@ -627,6 +651,7 @@ github.com/pion/turn/v2 v2.1.6 h1:Xr2niVsiPTB0FPtt+yAWKFUkU1eotQbGgpTIld4x1Gc= github.com/pion/turn/v2 v2.1.6/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY= github.com/pion/webrtc/v3 v3.3.0 h1:Rf4u6n6U5t5sUxhYPQk/samzU/oDv7jk6BA5hyO2F9I= github.com/pion/webrtc/v3 v3.3.0/go.mod h1:hVmrDJvwhEertRWObeb1xzulzHGeVUoPlWvxdGzcfU0= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -658,6 +683,7 @@ github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtB github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= diff --git a/go.mod b/go.mod index 5f27e27a8..3a33543f4 100644 --- a/go.mod +++ b/go.mod @@ -10,6 +10,7 @@ require ( github.com/cenkalti/backoff/v4 v4.3.0 github.com/ceramicnetwork/go-dag-jose v0.1.0 github.com/cheggaaa/pb v1.0.29 + github.com/cockroachdb/pebble v1.1.2 github.com/coreos/go-systemd/v22 v22.5.0 github.com/dustin/go-humanize v1.0.1 github.com/elgris/jsondiff v0.0.0-20160530203242-765b5c24c302 @@ -30,6 +31,7 @@ require ( github.com/ipfs/go-ds-flatfs v0.5.1 github.com/ipfs/go-ds-leveldb v0.5.0 github.com/ipfs/go-ds-measure v0.2.0 + github.com/ipfs/go-ds-pebble v0.4.0 github.com/ipfs/go-fs-lock v0.0.7 github.com/ipfs/go-ipfs-cmds v0.13.0 github.com/ipfs/go-ipld-cbor v0.2.0 @@ -95,12 +97,18 @@ require ( require ( github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 // indirect + github.com/DataDog/zstd v1.4.5 // indirect github.com/Jorropo/jsync v1.0.1 // indirect github.com/alecthomas/units v0.0.0-20240626203959-61d1e3462e30 // indirect github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/cockroachdb/errors v1.11.3 // indirect + github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce // indirect + github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect + github.com/cockroachdb/redact v1.1.5 // indirect + github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect github.com/containerd/cgroups v1.1.0 // indirect github.com/crackcomm/go-gitignore v0.0.0-20231225121904-e25f5bc08668 // indirect github.com/cskr/pubsub v1.0.2 // indirect @@ -115,6 +123,7 @@ require ( github.com/flynn/noise v1.1.0 // indirect github.com/francoispqt/gojay v1.2.13 // indirect github.com/gabriel-vasile/mimetype v1.4.4 // indirect + github.com/getsentry/sentry-go v0.27.0 // indirect github.com/go-kit/log v0.2.1 // indirect github.com/go-logfmt/logfmt v0.5.1 // indirect github.com/go-logr/logr v1.4.2 // indirect @@ -151,6 +160,8 @@ require ( github.com/klauspost/compress v1.17.9 // indirect github.com/klauspost/cpuid/v2 v2.2.8 // indirect github.com/koron/go-ssdp v0.0.4 // indirect + github.com/kr/pretty v0.3.1 // indirect + github.com/kr/text v0.2.0 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/libp2p/go-cidranger v1.1.0 // indirect github.com/libp2p/go-flow-metrics v0.1.0 // indirect @@ -164,7 +175,7 @@ require ( github.com/libp2p/go-yamux/v4 v4.0.1 // indirect github.com/libp2p/zeroconf/v2 v2.2.0 // indirect github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect - github.com/mattn/go-colorable v0.1.6 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-runewidth v0.0.4 // indirect github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect @@ -210,6 +221,7 @@ require ( github.com/quic-go/quic-go v0.45.2 // indirect github.com/quic-go/webtransport-go v0.8.0 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect + github.com/rogpeppe/go-internal v1.12.0 // indirect github.com/rs/cors v1.10.1 // indirect github.com/samber/lo v1.46.0 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect diff --git a/go.sum b/go.sum index 0c5e5bbd6..09a91f624 100644 --- a/go.sum +++ b/go.sum @@ -47,6 +47,8 @@ github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 h1:cTp8I5+VIo github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/DataDog/zstd v1.4.5 h1:EndNeuB0l9syBZhut0wns3gV1hL8zX8LIu6ZiVHWLIQ= +github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= github.com/Jorropo/jsync v1.0.1 h1:6HgRolFZnsdfzRUj+ImB9og1JYOxQoReSywkHOGSaUU= github.com/Jorropo/jsync v1.0.1/go.mod h1:jCOZj3vrBCri3bSU3ErUYvevKlnbssrXeCivybS5ABQ= github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= @@ -104,6 +106,20 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMn github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs= 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= +github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f h1:otljaYPt5hWxV3MUfO5dFPFiOXg9CyG5/kCfayTqsJ4= +github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= +github.com/cockroachdb/errors v1.11.3 h1:5bA+k2Y6r+oz/6Z/RFlNeVCesGARKuC6YymtcDrbC/I= +github.com/cockroachdb/errors v1.11.3/go.mod h1:m4UIW4CDjx+R5cybPsNrRbreomiFqt8o1h1wUVazSd8= +github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce h1:giXvy4KSc/6g/esnpM7Geqxka4WSqI1SZc7sMJFd3y4= +github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce/go.mod h1:9/y3cnZ5GKakj/H4y9r9GTjCvAFta7KLgSHPJJYc52M= +github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE= +github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= +github.com/cockroachdb/pebble v1.1.2 h1:CUh2IPtR4swHlEj48Rhfzw6l/d0qA31fItcIszQVIsA= +github.com/cockroachdb/pebble v1.1.2/go.mod h1:4exszw1r40423ZsmkG/09AFEG83I0uDgfujJdbL6kYU= +github.com/cockroachdb/redact v1.1.5 h1:u1PMllDkdFfPWaNGMyLD1+so+aq3uUItthCFqzwPJ30= +github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= +github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo= +github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ= github.com/containerd/cgroups v0.0.0-20201119153540-4cbc285b3327/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE= github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM= github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw= @@ -177,10 +193,14 @@ github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4 github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/gabriel-vasile/mimetype v1.4.4 h1:QjV6pZ7/XZ7ryI2KuyeEDE8wnh7fHP9YnQy+R0LnH8I= github.com/gabriel-vasile/mimetype v1.4.4/go.mod h1:JwLei5XPtWdGiMFB5Pjle1oEeoSeEuJfJE+TtfvdB/s= +github.com/getsentry/sentry-go v0.27.0 h1:Pv98CIbtB3LkMWmXi4Joa5OOcwbmnX88sF5qbK3r3Ps= +github.com/getsentry/sentry-go v0.27.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= +github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= +github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -365,6 +385,8 @@ github.com/ipfs/go-ds-leveldb v0.5.0 h1:s++MEBbD3ZKc9/8/njrn4flZLnCuY9I79v94gBUN github.com/ipfs/go-ds-leveldb v0.5.0/go.mod h1:d3XG9RUDzQ6V4SHi8+Xgj9j1XuEk1z82lquxrVbml/Q= github.com/ipfs/go-ds-measure v0.2.0 h1:sG4goQe0KDTccHMyT45CY1XyUbxe5VwTKpg2LjApYyQ= github.com/ipfs/go-ds-measure v0.2.0/go.mod h1:SEUD/rE2PwRa4IQEC5FuNAmjJCyYObZr9UvVh8V3JxE= +github.com/ipfs/go-ds-pebble v0.4.0 h1:88lgFAs2ck8jCQ8lMYRBtksEg18r9BlvTxIMnNJkZaQ= +github.com/ipfs/go-ds-pebble v0.4.0/go.mod h1:ZyYU+weIni+4NG/Yjva+cPkU3ghlsU1HA2R/VLHJ9sM= github.com/ipfs/go-fs-lock v0.0.7 h1:6BR3dajORFrFTkb5EpCUFIAypsoxpGpDSVUdFwzgL9U= github.com/ipfs/go-fs-lock v0.0.7/go.mod h1:Js8ka+FNYmgQRLrRXzU3CB/+Csr1BwrRilEcvYrHhhc= github.com/ipfs/go-ipfs-blockstore v1.3.1 h1:cEI9ci7V0sRNivqaOr0elDsamxXFxJMMMy7PTTDQNsQ= @@ -560,15 +582,15 @@ github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd/go.mod h1:QuCEs github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-colorable v0.1.6 h1:6Su7aK7lXmJ/U79bYtBjLNaha4Fs1Rg9plHpcH+vvnE= -github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= 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.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.4 h1:2BvfKmzob6Bmd4YsL0zygOqfdFnK7GR4QL06Do4/p7Y= @@ -685,6 +707,8 @@ github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhM github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 h1:1/WtZae0yGtPq+TI6+Tv1WTxkukpXeMlviSxvL7SRgk= github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9/go.mod h1:x3N5drFsm2uilKKuuYo6LdyD8vZAW55sH/9w+pbo1sw= +github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= +github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= github.com/pion/datachannel v1.5.8 h1:ph1P1NsGkazkjrvyMfhRBUAWMxugJjq2HfQifaOoSNo= github.com/pion/datachannel v1.5.8/go.mod h1:PgmdpoaNBLX9HNzNClmdki4DYW5JtI7Yibu8QzbL3tI= github.com/pion/dtls/v2 v2.2.7/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s= @@ -727,6 +751,7 @@ github.com/pion/turn/v2 v2.1.6 h1:Xr2niVsiPTB0FPtt+yAWKFUkU1eotQbGgpTIld4x1Gc= github.com/pion/turn/v2 v2.1.6/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY= github.com/pion/webrtc/v3 v3.3.0 h1:Rf4u6n6U5t5sUxhYPQk/samzU/oDv7jk6BA5hyO2F9I= github.com/pion/webrtc/v3 v3.3.0/go.mod h1:hVmrDJvwhEertRWObeb1xzulzHGeVUoPlWvxdGzcfU0= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -785,6 +810,7 @@ github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtB github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/rs/cors v1.10.1 h1:L0uuZVXIKlI1SShY2nhFfo44TYvDPQ1w4oFkUJNfhyo= @@ -1200,6 +1226,7 @@ golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220708085239-5a0f0661e09d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= diff --git a/plugin/loader/preload.go b/plugin/loader/preload.go index 2ad84e594..75e21270c 100644 --- a/plugin/loader/preload.go +++ b/plugin/loader/preload.go @@ -8,6 +8,7 @@ import ( pluginipldgit "github.com/ipfs/kubo/plugin/plugins/git" pluginlevelds "github.com/ipfs/kubo/plugin/plugins/levelds" pluginnopfs "github.com/ipfs/kubo/plugin/plugins/nopfs" + pluginpebbleds "github.com/ipfs/kubo/plugin/plugins/pebbleds" pluginpeerlog "github.com/ipfs/kubo/plugin/plugins/peerlog" ) @@ -21,6 +22,7 @@ func init() { Preload(pluginbadgerds.Plugins...) Preload(pluginflatfs.Plugins...) Preload(pluginlevelds.Plugins...) + Preload(pluginpebbleds.Plugins...) Preload(pluginpeerlog.Plugins...) Preload(pluginfxtest.Plugins...) Preload(pluginnopfs.Plugins...) diff --git a/plugin/loader/preload_list b/plugin/loader/preload_list index 462a3f393..190cc65d7 100644 --- a/plugin/loader/preload_list +++ b/plugin/loader/preload_list @@ -9,6 +9,7 @@ iplddagjose github.com/ipfs/kubo/plugin/plugins/dagjose * badgerds github.com/ipfs/kubo/plugin/plugins/badgerds * flatfs github.com/ipfs/kubo/plugin/plugins/flatfs * levelds github.com/ipfs/kubo/plugin/plugins/levelds * +pebbleds github.com/ipfs/kubo/plugin/plugins/pebbleds * peerlog github.com/ipfs/kubo/plugin/plugins/peerlog * fxtest github.com/ipfs/kubo/plugin/plugins/fxtest * -nopfs github.com/ipfs/kubo/plugin/plugins/nopfs * \ No newline at end of file +nopfs github.com/ipfs/kubo/plugin/plugins/nopfs * diff --git a/plugin/plugins/flatfs/flatfs.go b/plugin/plugins/flatfs/flatfs.go index 1a23dfcca..397c2656c 100644 --- a/plugin/plugins/flatfs/flatfs.go +++ b/plugin/plugins/flatfs/flatfs.go @@ -42,7 +42,7 @@ type datastoreConfig struct { syncField bool } -// BadgerdsDatastoreConfig returns a configuration stub for a badger datastore +// BadgerdsDatastoreConfig returns a configuration stub for a flatfs datastore // from the given parameters. func (*flatfsPlugin) DatastoreConfigParser() fsrepo.ConfigFromMap { return func(params map[string]interface{}) (fsrepo.DatastoreConfig, error) { diff --git a/plugin/plugins/levelds/levelds.go b/plugin/plugins/levelds/levelds.go index b08872de6..78331730e 100644 --- a/plugin/plugins/levelds/levelds.go +++ b/plugin/plugins/levelds/levelds.go @@ -42,7 +42,7 @@ type datastoreConfig struct { compression ldbopts.Compression } -// BadgerdsDatastoreConfig returns a configuration stub for a badger datastore +// DatastoreConfigParser returns a configuration stub for a badger datastore // from the given parameters. func (*leveldsPlugin) DatastoreConfigParser() fsrepo.ConfigFromMap { return func(params map[string]interface{}) (fsrepo.DatastoreConfig, error) { diff --git a/plugin/plugins/pebbleds/pebbleds.go b/plugin/plugins/pebbleds/pebbleds.go new file mode 100644 index 000000000..320fb3156 --- /dev/null +++ b/plugin/plugins/pebbleds/pebbleds.go @@ -0,0 +1,246 @@ +package pebbleds + +import ( + "errors" + "fmt" + "io/fs" + "os" + "path/filepath" + "time" + + "github.com/cockroachdb/pebble" + pebbleds "github.com/ipfs/go-ds-pebble" + "github.com/ipfs/kubo/plugin" + "github.com/ipfs/kubo/repo" + "github.com/ipfs/kubo/repo/fsrepo" +) + +// Plugins is exported list of plugins that will be loaded. +var Plugins = []plugin.Plugin{ + &pebbledsPlugin{}, +} + +type pebbledsPlugin struct{} + +var _ plugin.PluginDatastore = (*pebbledsPlugin)(nil) + +func (*pebbledsPlugin) Name() string { + return "ds-pebble" +} + +func (*pebbledsPlugin) Version() string { + return "0.1.0" +} + +func (*pebbledsPlugin) Init(_ *plugin.Environment) error { + return nil +} + +func (*pebbledsPlugin) DatastoreTypeName() string { + return "pebbleds" +} + +type datastoreConfig struct { + path string + cacheSize int64 + + // Documentation of these values: https://pkg.go.dev/github.com/cockroachdb/pebble@v1.1.2#Options + pebbleOpts *pebble.Options +} + +// PebbleDatastoreConfig returns a configuration stub for a pebble datastore +// from the given parameters. +func (*pebbledsPlugin) DatastoreConfigParser() fsrepo.ConfigFromMap { + return func(params map[string]any) (fsrepo.DatastoreConfig, error) { + var c datastoreConfig + var ok bool + + c.path, ok = params["path"].(string) + if !ok { + return nil, fmt.Errorf("'path' field is missing or not string") + } + + cacheSize, err := getConfigInt("cacheSize", params) + if err != nil { + return nil, err + } + c.cacheSize = int64(cacheSize) + + bytesPerSync, err := getConfigInt("bytesPerSync", params) + if err != nil { + return nil, err + } + disableWAL, err := getConfigBool("disableWAL", params) + if err != nil { + return nil, err + } + l0CompactionThreshold, err := getConfigInt("l0CompactionThreshold", params) + if err != nil { + return nil, err + } + l0StopWritesThreshold, err := getConfigInt("l0StopWritesThreshold", params) + if err != nil { + return nil, err + } + lBaseMaxBytes, err := getConfigInt("lBaseMaxBytes", params) + if err != nil { + return nil, err + } + maxConcurrentCompactions, err := getConfigInt("maxConcurrentCompactions", params) + if err != nil { + return nil, err + } + memTableSize, err := getConfigInt("memTableSize", params) + if err != nil { + return nil, err + } + memTableStopWritesThreshold, err := getConfigInt("memTableStopWritesThreshold", params) + if err != nil { + return nil, err + } + walBytesPerSync, err := getConfigInt("walBytesPerSync", params) + if err != nil { + return nil, err + } + walMinSyncSec, err := getConfigInt("walMinSyncIntervalSeconds", params) + if err != nil { + return nil, err + } + + if bytesPerSync != 0 || disableWAL || l0CompactionThreshold != 0 || l0StopWritesThreshold != 0 || lBaseMaxBytes != 0 || maxConcurrentCompactions != 0 || memTableSize != 0 || memTableStopWritesThreshold != 0 || walBytesPerSync != 0 || walMinSyncSec != 0 { + c.pebbleOpts = &pebble.Options{ + BytesPerSync: bytesPerSync, + DisableWAL: disableWAL, + L0CompactionThreshold: l0CompactionThreshold, + L0StopWritesThreshold: l0StopWritesThreshold, + LBaseMaxBytes: int64(lBaseMaxBytes), + MemTableSize: uint64(memTableSize), + MemTableStopWritesThreshold: memTableStopWritesThreshold, + WALBytesPerSync: walBytesPerSync, + } + if maxConcurrentCompactions != 0 { + c.pebbleOpts.MaxConcurrentCompactions = func() int { return maxConcurrentCompactions } + } + if walMinSyncSec != 0 { + c.pebbleOpts.WALMinSyncInterval = func() time.Duration { return time.Duration(walMinSyncSec) * time.Second } + } + } + + return &c, nil + } +} + +func getConfigBool(name string, params map[string]any) (bool, error) { + val, ok := params[name] + if ok { + bval, ok := val.(bool) + if !ok { + return false, fmt.Errorf("%q field was not a bool", name) + } + return bval, nil + } + return false, nil +} + +func getConfigInt(name string, params map[string]any) (int, error) { + val, ok := params[name] + if ok { + // TODO: see why val may be an int or a float64. + ival, ok := val.(int) + if !ok { + fval, ok := val.(float64) + if !ok { + return 0, fmt.Errorf("%q field was not an integer or a float64", name) + } + return int(fval), nil + } + return ival, nil + } + return 0, nil +} + +func (c *datastoreConfig) DiskSpec() fsrepo.DiskSpec { + return map[string]interface{}{ + "type": "pebbleds", + "path": c.path, + } +} + +func (c *datastoreConfig) Create(path string) (repo.Datastore, error) { + p := c.path + if !filepath.IsAbs(p) { + p = filepath.Join(path, p) + } + + if err := dirWritable(p); err != nil { + return nil, err + } + + return pebbleds.NewDatastore(p, pebbleds.WithCacheSize(c.cacheSize), pebbleds.WithPebbleOpts(c.pebbleOpts)) +} + +// dirWritable checks if a directory is writable. If the directory does +// not exist it is created with writable permission. +func dirWritable(dir string) error { + if dir == "" { + return errors.New("directory not specified") + } + var err error + dir, err = expandHome(dir) + if err != nil { + return err + } + + fi, err := os.Stat(dir) + if err != nil { + if errors.Is(err, fs.ErrNotExist) { + // Directory does not exist, so create it. + err = os.Mkdir(dir, 0775) + if err == nil { + return nil + } + } + if errors.Is(err, fs.ErrPermission) { + err = fs.ErrPermission + } + return fmt.Errorf("directory not writable: %s: %w", dir, err) + } + if !fi.IsDir() { + return fmt.Errorf("not a directory: %s", dir) + } + + // Directory exists, check that a file can be written. + file, err := os.CreateTemp(dir, "writetest") + if err != nil { + if errors.Is(err, fs.ErrPermission) { + err = fs.ErrPermission + } + return fmt.Errorf("directory not writable: %s: %w", dir, err) + } + file.Close() + return os.Remove(file.Name()) +} + +// expandHome expands the path to include the home directory if the path is +// prefixed with `~`. If it isn't prefixed with `~`, the path is returned +// as-is. +func expandHome(path string) (string, error) { + if path == "" { + return path, nil + } + + if path[0] != '~' { + return path, nil + } + + if len(path) > 1 && path[1] != '/' && path[1] != '\\' { + return "", errors.New("cannot expand user-specific home dir") + } + + dir, err := os.UserHomeDir() + if err != nil { + return "", err + } + + return filepath.Join(dir, path[1:]), nil +} diff --git a/test/sharness/t0021-config.sh b/test/sharness/t0021-config.sh index 5264908c7..95a8a7d87 100755 --- a/test/sharness/t0021-config.sh +++ b/test/sharness/t0021-config.sh @@ -281,7 +281,7 @@ test_config_cmd() { # won't work as it changes datastore definition, which makes ipfs not launch # without converting first - # test_profile_apply_revert badgerds + # test_profile_apply_revert pebbleds test_expect_success "cleanup config backups" ' find "$IPFS_PATH" -name "config-*" -exec rm {} \; diff --git a/test/sharness/t0025-datastores.sh b/test/sharness/t0025-datastores.sh index f0ddd4e2e..6be9eb3ed 100755 --- a/test/sharness/t0025-datastores.sh +++ b/test/sharness/t0025-datastores.sh @@ -4,13 +4,20 @@ test_description="Test non-standard datastores" . lib/test-lib.sh -test_expect_success "'ipfs init --empty-repo=false --profile=badgerds' succeeds" ' - BITS="2048" && - ipfs init --empty-repo=false --profile=badgerds -' +profiles=("flatfs" "pebbleds" "badgerds") +proot="$(mktemp -d "${TMPDIR:-/tmp}/t0025.XXXXXX")" -test_expect_success "'ipfs pin ls' works" ' - ipfs pin ls | wc -l | grep 9 -' +for profile in "${profiles[@]}"; do + test_expect_success "'ipfs init --empty-repo=false --profile=$profile' succeeds" ' + BITS="2048" && + IPFS_PATH="$proot/$profile" && + ipfs init --empty-repo=false --profile=$profile + ' + test_expect_success "'ipfs pin add' and 'pin ls' works with $profile" ' + export IPFS_PATH="$proot/$profile" && + echo -n "hello_$profile" | ipfs block put --pin=true > hello_cid && + ipfs pin ls -t recursive "$(cat hello_cid)" + ' +done test_done From 4566741b222a1dec8884080d7be3b3a9373f6956 Mon Sep 17 00:00:00 2001 From: Andrew Gillis <11790789+gammazero@users.noreply.github.com> Date: Thu, 3 Oct 2024 15:42:15 -0700 Subject: [PATCH 1173/1212] chore: update changelog and config doc with more info about pebble (#10533) * Update config doc with more info about Pebble Provide additional information about some key behaviors that may be useful for deciding what datastore to use. --- docs/config.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/config.md b/docs/config.md index bbbb94bd8..9a47d0061 100644 --- a/docs/config.md +++ b/docs/config.md @@ -2426,10 +2426,11 @@ Pebble is a LevelDB/RocksDB inspired key-value store focused on performance and You should use this datastore if: - You need a datastore that is focused on performance. +- You need a datastore that is good for multi-terrabyte data sets. - You need reliability by default, but may choose to disable WAL for maximum performance when reliability is not critical. -- This datastore is good for multi-terrabyte data sets. -- May benefit from tuning depending on read/write patterns and throughput. -- Performance is helped significantly by running on a system with plenty of memory. +- You want a datastore that does not need GC cycles and does not use more space than necessary +- You want a datastore that does not take several minutes to start with large repositories +- You want a datastore that performs well even with default settings, but can optimized by setting configuration to tune it for your specific needs. > [!WARNING] > This profile may only be applied when first initializing the node via `ipfs init --profile pebbleds` From 6305932b4ef5ca816d8a6f94fccc5b601f16701a Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Fri, 4 Oct 2024 00:51:45 +0200 Subject: [PATCH 1174/1212] fix(daemon): webui URL when rpc is catch-all (#10520) Closes #10515 --- cmd/ipfs/kubo/daemon.go | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/cmd/ipfs/kubo/daemon.go b/cmd/ipfs/kubo/daemon.go index aaa1f414f..956057fe6 100644 --- a/cmd/ipfs/kubo/daemon.go +++ b/cmd/ipfs/kubo/daemon.go @@ -723,10 +723,18 @@ func serveHTTPApi(req *cmds.Request, cctx *oldcmds.Context) (<-chan error, error for _, listener := range listeners { // we might have listened to /tcp/0 - let's see what we are listing on fmt.Printf("RPC API server listening on %s\n", listener.Multiaddr()) - // Browsers require TCP. + // Browsers require TCP with explicit host. switch listener.Addr().Network() { case "tcp", "tcp4", "tcp6": - fmt.Printf("WebUI: http://%s/webui\n", listener.Addr()) + rpc := listener.Addr().String() + // replace catch-all with explicit localhost URL that works in browsers + // https://github.com/ipfs/kubo/issues/10515 + if strings.Contains(rpc, "0.0.0.0:") { + rpc = strings.Replace(rpc, "0.0.0.0:", "127.0.0.1:", 1) + } else if strings.Contains(rpc, "[::]:") { + rpc = strings.Replace(rpc, "[::]:", "[::1]:", 1) + } + fmt.Printf("WebUI: http://%s/webui\n", rpc) } } From 52ca3707591cad8ae99fd0a03b7e278487192e71 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Fri, 4 Oct 2024 00:58:25 +0200 Subject: [PATCH 1175/1212] feat(routing/http): support IPIP-484 and streaming (#10534) --- config/routing.go | 31 +++++++++++++++++++++++++++++-- core/node/libp2p/routingopt.go | 17 +---------------- docs/environment-variables.md | 12 ++++++++++++ routing/delegated.go | 3 +++ 4 files changed, 45 insertions(+), 18 deletions(-) diff --git a/config/routing.go b/config/routing.go index 231cbca73..52d8b7296 100644 --- a/config/routing.go +++ b/config/routing.go @@ -3,12 +3,29 @@ package config import ( "encoding/json" "fmt" + "os" "runtime" + "strings" +) + +const ( + DefaultAcceleratedDHTClient = false + DefaultLoopbackAddressesOnLanDHT = false ) var ( - DefaultAcceleratedDHTClient = false - DefaultLoopbackAddressesOnLanDHT = false + // Default HTTP routers used in parallel to DHT when Routing.Type = "auto" + DefaultHTTPRouters = getEnvOrDefault("IPFS_HTTP_ROUTERS", []string{ + "https://cid.contact", // https://github.com/ipfs/kubo/issues/9422#issuecomment-1338142084 + }) + + // Default filter-protocols to pass along with delegated routing requests (as defined in IPIP-484) + // and also filter out locally + DefaultHTTPRoutersFilterProtocols = getEnvOrDefault("IPFS_HTTP_ROUTERS_FILTER_PROTOCOLS", []string{ + "unknown", // allow results without protocol list, we can do libp2p identify to test them + "transport-bitswap", + // TODO: add 'transport-ipfs-gateway-http' once https://github.com/ipfs/rainbow/issues/125 is addressed + }) ) // Routing defines configuration options for libp2p routing. @@ -180,3 +197,13 @@ type ConfigRouter struct { type Method struct { RouterName string } + +// getEnvOrDefault reads space or comma separated strings from env if present, +// and uses provided defaultValue as a fallback +func getEnvOrDefault(key string, defaultValue []string) []string { + if value, exists := os.LookupEnv(key); exists { + splitFunc := func(r rune) bool { return r == ',' || r == ' ' } + return strings.FieldsFunc(value, splitFunc) + } + return defaultValue +} diff --git a/core/node/libp2p/routingopt.go b/core/node/libp2p/routingopt.go index 869b7ef06..292f49fe4 100644 --- a/core/node/libp2p/routingopt.go +++ b/core/node/libp2p/routingopt.go @@ -2,8 +2,6 @@ package libp2p import ( "context" - "os" - "strings" "time" "github.com/ipfs/go-datastore" @@ -31,23 +29,10 @@ type RoutingOptionArgs struct { type RoutingOption func(args RoutingOptionArgs) (routing.Routing, error) -// Default HTTP routers used in parallel to DHT when Routing.Type = "auto" -var defaultHTTPRouters = []string{ - "https://cid.contact", // https://github.com/ipfs/kubo/issues/9422#issuecomment-1338142084 - // TODO: add an independent router from Cloudflare -} - -func init() { - // Override HTTP routers if custom ones were passed via env - if routers := os.Getenv("IPFS_HTTP_ROUTERS"); routers != "" { - defaultHTTPRouters = strings.Split(routers, " ") - } -} - func constructDefaultHTTPRouters(cfg *config.Config) ([]*routinghelpers.ParallelRouter, error) { var routers []*routinghelpers.ParallelRouter // Append HTTP routers for additional speed - for _, endpoint := range defaultHTTPRouters { + for _, endpoint := range config.DefaultHTTPRouters { httpRouter, err := irouting.ConstructHTTPRouter(endpoint, cfg.Identity.PeerID, httpAddrsFromConfig(cfg.Addresses), cfg.Identity.PrivKey) if err != nil { return nil, err diff --git a/docs/environment-variables.md b/docs/environment-variables.md index f0f6b3f18..b384e51ad 100644 --- a/docs/environment-variables.md +++ b/docs/environment-variables.md @@ -131,6 +131,18 @@ The above will replace implicit HTTP routers with single one, allowing for inspection/debug of HTTP requests sent by Kubo via `while true ; do nc -l 7423; done` or more advanced tools like [mitmproxy](https://docs.mitmproxy.org/stable/#mitmproxy). +Default: `config.DefaultHTTPRouters` + +## `IPFS_HTTP_ROUTERS_FILTER_PROTOCOLS` + +Overrides values passed with `filter-protocols` parameter defined in IPIP-484. +Value is space-separated. + +```console +$ IPFS_HTTP_ROUTERS_FILTER_PROTOCOLS="unknown transport-bitswap transport-foo" ipfs daemon +``` + +Default: `config.DefaultHTTPRoutersFilterProtocols` ## `IPFS_CONTENT_BLOCKING_DISABLE` diff --git a/routing/delegated.go b/routing/delegated.go index e830c1aa1..f5f98a03f 100644 --- a/routing/delegated.go +++ b/routing/delegated.go @@ -206,6 +206,9 @@ func httpRoutingFromConfig(conf config.Router, extraHTTP *ExtraHTTPParams) (rout drclient.WithIdentity(key), drclient.WithProviderInfo(addrInfo.ID, addrInfo.Addrs), drclient.WithUserAgent(version.GetUserAgentVersion()), + drclient.WithProtocolFilter(config.DefaultHTTPRoutersFilterProtocols), + drclient.WithStreamResultsRequired(), // https://specs.ipfs.tech/routing/http-routing-v1/#streaming + drclient.WithDisabledLocalFiltering(false), // force local filtering in case remote server does not support IPIP-484 ) if err != nil { return nil, err From 6e5df580a19c2d1e0b7b93a190353c90c746623f Mon Sep 17 00:00:00 2001 From: gammazero <11790789+gammazero@users.noreply.github.com> Date: Thu, 3 Oct 2024 16:22:04 -0700 Subject: [PATCH 1176/1212] chore: bump version to 0.32.0-dev --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index c8b24bd3c..46704e0be 100644 --- a/version.go +++ b/version.go @@ -11,7 +11,7 @@ import ( var CurrentCommit string // CurrentVersionNumber is the current application's version literal. -const CurrentVersionNumber = "0.31.0-dev" +const CurrentVersionNumber = "0.32.0-dev" const ApiVersion = "/kubo/" + CurrentVersionNumber + "/" //nolint From a55215c5c1c4284370751b830b1711ee26b5f789 Mon Sep 17 00:00:00 2001 From: gammazero <11790789+gammazero@users.noreply.github.com> Date: Thu, 3 Oct 2024 16:18:41 -0700 Subject: [PATCH 1177/1212] chore: bump version to v0.31.0-rc1 --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index c8b24bd3c..b0785b505 100644 --- a/version.go +++ b/version.go @@ -11,7 +11,7 @@ import ( var CurrentCommit string // CurrentVersionNumber is the current application's version literal. -const CurrentVersionNumber = "0.31.0-dev" +const CurrentVersionNumber = "0.31.0-rc1" const ApiVersion = "/kubo/" + CurrentVersionNumber + "/" //nolint From 00e1f812a24fe1683f9fd141f7ec6f2b49652c91 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Fri, 4 Oct 2024 16:32:21 +0200 Subject: [PATCH 1178/1212] chore: go-libp2p v0.36.5 (#10538) https://github.com/libp2p/go-libp2p/releases/tag/v0.36.5 --- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- test/dependencies/go.mod | 2 +- test/dependencies/go.sum | 4 ++-- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 6b94d3802..36c818068 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -9,7 +9,7 @@ replace github.com/ipfs/kubo => ./../../.. require ( github.com/ipfs/boxo v0.24.0 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 - github.com/libp2p/go-libp2p v0.36.4 + github.com/libp2p/go-libp2p v0.36.5 github.com/multiformats/go-multiaddr v0.13.0 ) diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 8b4c2ee8c..ae9498ade 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -449,8 +449,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.36.4 h1:ZaKyKSHBFbzs6CnAYMhaMc5QgV1UoCN+9WXrg8SEwI4= -github.com/libp2p/go-libp2p v0.36.4/go.mod h1:4Y5vFyCUiJuluEPmpnKYf6WFx5ViKPUYs/ixe9ANFZ8= +github.com/libp2p/go-libp2p v0.36.5 h1:DoABsaHO0VXwH6pwCs2F6XKAXWYjFMO4HFBoVxTnF9g= +github.com/libp2p/go-libp2p v0.36.5/go.mod h1:CpszAtXxHYOcyvB7K8rSHgnNlh21eKjYbEfLoMerbEI= github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94= github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= diff --git a/go.mod b/go.mod index 3a33543f4..f6da422ca 100644 --- a/go.mod +++ b/go.mod @@ -52,7 +52,7 @@ require ( github.com/jbenet/goprocess v0.1.4 github.com/julienschmidt/httprouter v1.3.0 github.com/libp2p/go-doh-resolver v0.4.0 - github.com/libp2p/go-libp2p v0.36.4 + github.com/libp2p/go-libp2p v0.36.5 github.com/libp2p/go-libp2p-http v0.5.0 github.com/libp2p/go-libp2p-kad-dht v0.26.1 github.com/libp2p/go-libp2p-kbucket v0.6.4 diff --git a/go.sum b/go.sum index 09a91f624..22b5807db 100644 --- a/go.sum +++ b/go.sum @@ -528,8 +528,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.36.4 h1:ZaKyKSHBFbzs6CnAYMhaMc5QgV1UoCN+9WXrg8SEwI4= -github.com/libp2p/go-libp2p v0.36.4/go.mod h1:4Y5vFyCUiJuluEPmpnKYf6WFx5ViKPUYs/ixe9ANFZ8= +github.com/libp2p/go-libp2p v0.36.5 h1:DoABsaHO0VXwH6pwCs2F6XKAXWYjFMO4HFBoVxTnF9g= +github.com/libp2p/go-libp2p v0.36.5/go.mod h1:CpszAtXxHYOcyvB7K8rSHgnNlh21eKjYbEfLoMerbEI= github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94= github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 29a0cf35a..6fbcd249d 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -142,7 +142,7 @@ require ( github.com/leonklingele/grouper v1.1.2 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/libp2p/go-cidranger v1.1.0 // indirect - github.com/libp2p/go-libp2p v0.36.4 // indirect + github.com/libp2p/go-libp2p v0.36.5 // indirect github.com/libp2p/go-libp2p-asn-util v0.4.1 // indirect github.com/libp2p/go-libp2p-kad-dht v0.26.1 // indirect github.com/libp2p/go-libp2p-kbucket v0.6.4 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index d930da41b..06443b67c 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -388,8 +388,8 @@ github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38y github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.36.4 h1:ZaKyKSHBFbzs6CnAYMhaMc5QgV1UoCN+9WXrg8SEwI4= -github.com/libp2p/go-libp2p v0.36.4/go.mod h1:4Y5vFyCUiJuluEPmpnKYf6WFx5ViKPUYs/ixe9ANFZ8= +github.com/libp2p/go-libp2p v0.36.5 h1:DoABsaHO0VXwH6pwCs2F6XKAXWYjFMO4HFBoVxTnF9g= +github.com/libp2p/go-libp2p v0.36.5/go.mod h1:CpszAtXxHYOcyvB7K8rSHgnNlh21eKjYbEfLoMerbEI= github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94= github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= github.com/libp2p/go-libp2p-kad-dht v0.26.1 h1:AazV3LCImYVkDUGAHx5lIEgZ9iUI2QQKH5GMRQU8uEA= From 38ae2e73b2cc70cc22a4a4e0adb699951bfe1762 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Fri, 4 Oct 2024 16:32:21 +0200 Subject: [PATCH 1179/1212] chore: go-libp2p v0.36.5 (#10538) https://github.com/libp2p/go-libp2p/releases/tag/v0.36.5 (cherry picked from commit 00e1f812a24fe1683f9fd141f7ec6f2b49652c91) --- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- test/dependencies/go.mod | 2 +- test/dependencies/go.sum | 4 ++-- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 6b94d3802..36c818068 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -9,7 +9,7 @@ replace github.com/ipfs/kubo => ./../../.. require ( github.com/ipfs/boxo v0.24.0 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 - github.com/libp2p/go-libp2p v0.36.4 + github.com/libp2p/go-libp2p v0.36.5 github.com/multiformats/go-multiaddr v0.13.0 ) diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 8b4c2ee8c..ae9498ade 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -449,8 +449,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.36.4 h1:ZaKyKSHBFbzs6CnAYMhaMc5QgV1UoCN+9WXrg8SEwI4= -github.com/libp2p/go-libp2p v0.36.4/go.mod h1:4Y5vFyCUiJuluEPmpnKYf6WFx5ViKPUYs/ixe9ANFZ8= +github.com/libp2p/go-libp2p v0.36.5 h1:DoABsaHO0VXwH6pwCs2F6XKAXWYjFMO4HFBoVxTnF9g= +github.com/libp2p/go-libp2p v0.36.5/go.mod h1:CpszAtXxHYOcyvB7K8rSHgnNlh21eKjYbEfLoMerbEI= github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94= github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= diff --git a/go.mod b/go.mod index 3a33543f4..f6da422ca 100644 --- a/go.mod +++ b/go.mod @@ -52,7 +52,7 @@ require ( github.com/jbenet/goprocess v0.1.4 github.com/julienschmidt/httprouter v1.3.0 github.com/libp2p/go-doh-resolver v0.4.0 - github.com/libp2p/go-libp2p v0.36.4 + github.com/libp2p/go-libp2p v0.36.5 github.com/libp2p/go-libp2p-http v0.5.0 github.com/libp2p/go-libp2p-kad-dht v0.26.1 github.com/libp2p/go-libp2p-kbucket v0.6.4 diff --git a/go.sum b/go.sum index 09a91f624..22b5807db 100644 --- a/go.sum +++ b/go.sum @@ -528,8 +528,8 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.36.4 h1:ZaKyKSHBFbzs6CnAYMhaMc5QgV1UoCN+9WXrg8SEwI4= -github.com/libp2p/go-libp2p v0.36.4/go.mod h1:4Y5vFyCUiJuluEPmpnKYf6WFx5ViKPUYs/ixe9ANFZ8= +github.com/libp2p/go-libp2p v0.36.5 h1:DoABsaHO0VXwH6pwCs2F6XKAXWYjFMO4HFBoVxTnF9g= +github.com/libp2p/go-libp2p v0.36.5/go.mod h1:CpszAtXxHYOcyvB7K8rSHgnNlh21eKjYbEfLoMerbEI= github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94= github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 29a0cf35a..6fbcd249d 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -142,7 +142,7 @@ require ( github.com/leonklingele/grouper v1.1.2 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/libp2p/go-cidranger v1.1.0 // indirect - github.com/libp2p/go-libp2p v0.36.4 // indirect + github.com/libp2p/go-libp2p v0.36.5 // indirect github.com/libp2p/go-libp2p-asn-util v0.4.1 // indirect github.com/libp2p/go-libp2p-kad-dht v0.26.1 // indirect github.com/libp2p/go-libp2p-kbucket v0.6.4 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index d930da41b..06443b67c 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -388,8 +388,8 @@ github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38y github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.36.4 h1:ZaKyKSHBFbzs6CnAYMhaMc5QgV1UoCN+9WXrg8SEwI4= -github.com/libp2p/go-libp2p v0.36.4/go.mod h1:4Y5vFyCUiJuluEPmpnKYf6WFx5ViKPUYs/ixe9ANFZ8= +github.com/libp2p/go-libp2p v0.36.5 h1:DoABsaHO0VXwH6pwCs2F6XKAXWYjFMO4HFBoVxTnF9g= +github.com/libp2p/go-libp2p v0.36.5/go.mod h1:CpszAtXxHYOcyvB7K8rSHgnNlh21eKjYbEfLoMerbEI= github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94= github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= github.com/libp2p/go-libp2p-kad-dht v0.26.1 h1:AazV3LCImYVkDUGAHx5lIEgZ9iUI2QQKH5GMRQU8uEA= From 6b3cd0d14f88f305e9f358443cc3ed1d6dc38826 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Mon, 7 Oct 2024 21:52:08 +0200 Subject: [PATCH 1180/1212] chore: typo --- docs/changelogs/v0.31.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/changelogs/v0.31.md b/docs/changelogs/v0.31.md index 0b814ff65..106266a99 100644 --- a/docs/changelogs/v0.31.md +++ b/docs/changelogs/v0.31.md @@ -39,7 +39,7 @@ This release changes [`lowpower` profile](https://github.com/ipfs/kubo/blob/mast > [!IMPORTANT] > If you've ever applied the `lowpower` profile before, there is a high chance your node is not announcing to DHT anymore. -> If you have `Reprovider.Interval` set to `0` you may want to wet it to `22h` (or run `ipfs config profile apply announce-on`) to fix your system. +> If you have `Reprovider.Interval` set to `0` you may want to set it to `22h` (or run `ipfs config profile apply announce-on`) to fix your system. > > As a convenience, `ipfs daemon` will warn if reprovide system is disabled, creating oportinity to fix configuration if it was not intentional. From 091bc083c3cb76ff408a9df2c020b0cbc49f141b Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Tue, 8 Oct 2024 17:16:02 +0200 Subject: [PATCH 1181/1212] fix: go 1.23(.2) (#10540) go1.23.2 includes potential fix for issue described in https://github.com/ipfs/kubo/issues/10501 --- .github/workflows/codeql-analysis.yml | 2 +- .github/workflows/docker-build.yml | 2 +- .github/workflows/gateway-conformance.yml | 4 ++-- .github/workflows/gobuild.yml | 2 +- .github/workflows/golang-analysis.yml | 2 +- .github/workflows/golint.yml | 2 +- .github/workflows/gotest.yml | 2 +- .github/workflows/interop.yml | 2 +- .github/workflows/sharness.yml | 2 +- Dockerfile | 2 +- docs/changelogs/v0.31.md | 5 +++++ docs/examples/kubo-as-a-library/go.mod | 4 +++- go.mod | 2 +- 13 files changed, 20 insertions(+), 13 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index d0e082d65..8ed324854 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -34,7 +34,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: 1.22.x + go-version: 1.23.x # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml index 433240f42..e13a3f882 100644 --- a/.github/workflows/docker-build.yml +++ b/.github/workflows/docker-build.yml @@ -28,7 +28,7 @@ jobs: steps: - uses: actions/setup-go@v5 with: - go-version: 1.22.x + go-version: 1.23.x - uses: actions/checkout@v4 - run: docker build -t $IMAGE_NAME:$WIP_IMAGE_TAG . - run: docker run --rm $IMAGE_NAME:$WIP_IMAGE_TAG --version diff --git a/.github/workflows/gateway-conformance.yml b/.github/workflows/gateway-conformance.yml index b1791868c..d2f015900 100644 --- a/.github/workflows/gateway-conformance.yml +++ b/.github/workflows/gateway-conformance.yml @@ -49,7 +49,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: 1.22.x + go-version: 1.23.x - uses: protocol/cache-go-action@v1 with: name: ${{ github.job }} @@ -136,7 +136,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: 1.22.x + go-version: 1.23.x - uses: protocol/cache-go-action@v1 with: name: ${{ github.job }} diff --git a/.github/workflows/gobuild.yml b/.github/workflows/gobuild.yml index 93159eadd..5aebfd938 100644 --- a/.github/workflows/gobuild.yml +++ b/.github/workflows/gobuild.yml @@ -30,7 +30,7 @@ jobs: steps: - uses: actions/setup-go@v5 with: - go-version: 1.22.x + go-version: 1.23.x - uses: actions/checkout@v4 - run: make cmd/ipfs-try-build env: diff --git a/.github/workflows/golang-analysis.yml b/.github/workflows/golang-analysis.yml index e89034a92..36a5bba01 100644 --- a/.github/workflows/golang-analysis.yml +++ b/.github/workflows/golang-analysis.yml @@ -27,7 +27,7 @@ jobs: submodules: recursive - uses: actions/setup-go@v5 with: - go-version: "1.22.x" + go-version: "1.23.x" - name: Check that go.mod is tidy uses: protocol/multiple-go-modules@v1.4 with: diff --git a/.github/workflows/golint.yml b/.github/workflows/golint.yml index aa8b21b53..57b5d46dd 100644 --- a/.github/workflows/golint.yml +++ b/.github/workflows/golint.yml @@ -31,6 +31,6 @@ jobs: steps: - uses: actions/setup-go@v5 with: - go-version: 1.22.x + go-version: 1.23.x - uses: actions/checkout@v4 - run: make -O test_go_lint diff --git a/.github/workflows/gotest.yml b/.github/workflows/gotest.yml index 609791aba..f5225e8a3 100644 --- a/.github/workflows/gotest.yml +++ b/.github/workflows/gotest.yml @@ -32,7 +32,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v5 with: - go-version: 1.22.x + go-version: 1.23.x - name: Check out Kubo uses: actions/checkout@v4 - name: Install missing tools diff --git a/.github/workflows/interop.yml b/.github/workflows/interop.yml index 2967c9997..bfa6523de 100644 --- a/.github/workflows/interop.yml +++ b/.github/workflows/interop.yml @@ -10,7 +10,7 @@ on: - 'master' env: - GO_VERSION: 1.22.x + GO_VERSION: 1.23.x concurrency: group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.event_name == 'push' && github.sha || github.ref }} diff --git a/.github/workflows/sharness.yml b/.github/workflows/sharness.yml index 6432745bf..af7fa896c 100644 --- a/.github/workflows/sharness.yml +++ b/.github/workflows/sharness.yml @@ -25,7 +25,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: 1.22.x + go-version: 1.23.x - name: Checkout Kubo uses: actions/checkout@v4 with: diff --git a/Dockerfile b/Dockerfile index 4ed07d3d4..e04b3c666 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM --platform=${BUILDPLATFORM:-linux/amd64} golang:1.22 AS builder +FROM --platform=${BUILDPLATFORM:-linux/amd64} golang:1.23 AS builder ARG TARGETOS TARGETARCH diff --git a/docs/changelogs/v0.31.md b/docs/changelogs/v0.31.md index 0b814ff65..22909b9a9 100644 --- a/docs/changelogs/v0.31.md +++ b/docs/changelogs/v0.31.md @@ -9,6 +9,7 @@ - [Experimental Pebble Datastore](#experimental-pebble-datastore) - [New metrics](#new-metrics) - [`lowpower` profile no longer breaks DHT announcements](#lowpower-profile-no-longer-breaks-dht-announcements) + - [go 1.23, boxo 0.24 and go-libp2p 0.36.5](#go-123-boxo-024-and-go-libp2p-0365) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -43,6 +44,10 @@ This release changes [`lowpower` profile](https://github.com/ipfs/kubo/blob/mast > > As a convenience, `ipfs daemon` will warn if reprovide system is disabled, creating oportinity to fix configuration if it was not intentional. +#### go 1.23, boxo 0.24 and go-libp2p 0.36.5 + +Various bugfixes. Please update. + ### 📝 Changelog ### 👨‍👩‍👧‍👦 Contributors diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 36c818068..0c3c73630 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -1,6 +1,8 @@ module github.com/ipfs/kubo/examples/kubo-as-a-library -go 1.22 +go 1.23 + +toolchain go1.23.2 // Used to keep this in sync with the current version of kubo. You should remove // this if you copy this example. diff --git a/go.mod b/go.mod index f6da422ca..5774817e9 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/ipfs/kubo -go 1.22 +go 1.23 require ( bazil.org/fuse v0.0.0-20200117225306-7b5117fecadc From 598545171cdc41aa2050617ef3a3b712682a8a99 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Tue, 8 Oct 2024 17:16:02 +0200 Subject: [PATCH 1182/1212] fix: go 1.23(.2) (#10540) go1.23.2 includes potential fix for issue described in https://github.com/ipfs/kubo/issues/10501 (cherry picked from commit 091bc083c3cb76ff408a9df2c020b0cbc49f141b) --- .github/workflows/codeql-analysis.yml | 2 +- .github/workflows/docker-build.yml | 2 +- .github/workflows/gateway-conformance.yml | 4 ++-- .github/workflows/gobuild.yml | 2 +- .github/workflows/golang-analysis.yml | 2 +- .github/workflows/golint.yml | 2 +- .github/workflows/gotest.yml | 2 +- .github/workflows/interop.yml | 2 +- .github/workflows/sharness.yml | 2 +- Dockerfile | 2 +- docs/changelogs/v0.31.md | 5 +++++ docs/examples/kubo-as-a-library/go.mod | 4 +++- go.mod | 2 +- 13 files changed, 20 insertions(+), 13 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index d0e082d65..8ed324854 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -34,7 +34,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: 1.22.x + go-version: 1.23.x # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml index 433240f42..e13a3f882 100644 --- a/.github/workflows/docker-build.yml +++ b/.github/workflows/docker-build.yml @@ -28,7 +28,7 @@ jobs: steps: - uses: actions/setup-go@v5 with: - go-version: 1.22.x + go-version: 1.23.x - uses: actions/checkout@v4 - run: docker build -t $IMAGE_NAME:$WIP_IMAGE_TAG . - run: docker run --rm $IMAGE_NAME:$WIP_IMAGE_TAG --version diff --git a/.github/workflows/gateway-conformance.yml b/.github/workflows/gateway-conformance.yml index b1791868c..d2f015900 100644 --- a/.github/workflows/gateway-conformance.yml +++ b/.github/workflows/gateway-conformance.yml @@ -49,7 +49,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: 1.22.x + go-version: 1.23.x - uses: protocol/cache-go-action@v1 with: name: ${{ github.job }} @@ -136,7 +136,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: 1.22.x + go-version: 1.23.x - uses: protocol/cache-go-action@v1 with: name: ${{ github.job }} diff --git a/.github/workflows/gobuild.yml b/.github/workflows/gobuild.yml index 93159eadd..5aebfd938 100644 --- a/.github/workflows/gobuild.yml +++ b/.github/workflows/gobuild.yml @@ -30,7 +30,7 @@ jobs: steps: - uses: actions/setup-go@v5 with: - go-version: 1.22.x + go-version: 1.23.x - uses: actions/checkout@v4 - run: make cmd/ipfs-try-build env: diff --git a/.github/workflows/golang-analysis.yml b/.github/workflows/golang-analysis.yml index e89034a92..36a5bba01 100644 --- a/.github/workflows/golang-analysis.yml +++ b/.github/workflows/golang-analysis.yml @@ -27,7 +27,7 @@ jobs: submodules: recursive - uses: actions/setup-go@v5 with: - go-version: "1.22.x" + go-version: "1.23.x" - name: Check that go.mod is tidy uses: protocol/multiple-go-modules@v1.4 with: diff --git a/.github/workflows/golint.yml b/.github/workflows/golint.yml index aa8b21b53..57b5d46dd 100644 --- a/.github/workflows/golint.yml +++ b/.github/workflows/golint.yml @@ -31,6 +31,6 @@ jobs: steps: - uses: actions/setup-go@v5 with: - go-version: 1.22.x + go-version: 1.23.x - uses: actions/checkout@v4 - run: make -O test_go_lint diff --git a/.github/workflows/gotest.yml b/.github/workflows/gotest.yml index 609791aba..f5225e8a3 100644 --- a/.github/workflows/gotest.yml +++ b/.github/workflows/gotest.yml @@ -32,7 +32,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v5 with: - go-version: 1.22.x + go-version: 1.23.x - name: Check out Kubo uses: actions/checkout@v4 - name: Install missing tools diff --git a/.github/workflows/interop.yml b/.github/workflows/interop.yml index 2967c9997..bfa6523de 100644 --- a/.github/workflows/interop.yml +++ b/.github/workflows/interop.yml @@ -10,7 +10,7 @@ on: - 'master' env: - GO_VERSION: 1.22.x + GO_VERSION: 1.23.x concurrency: group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.event_name == 'push' && github.sha || github.ref }} diff --git a/.github/workflows/sharness.yml b/.github/workflows/sharness.yml index 6432745bf..af7fa896c 100644 --- a/.github/workflows/sharness.yml +++ b/.github/workflows/sharness.yml @@ -25,7 +25,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: 1.22.x + go-version: 1.23.x - name: Checkout Kubo uses: actions/checkout@v4 with: diff --git a/Dockerfile b/Dockerfile index 4ed07d3d4..e04b3c666 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM --platform=${BUILDPLATFORM:-linux/amd64} golang:1.22 AS builder +FROM --platform=${BUILDPLATFORM:-linux/amd64} golang:1.23 AS builder ARG TARGETOS TARGETARCH diff --git a/docs/changelogs/v0.31.md b/docs/changelogs/v0.31.md index 106266a99..7d734209e 100644 --- a/docs/changelogs/v0.31.md +++ b/docs/changelogs/v0.31.md @@ -9,6 +9,7 @@ - [Experimental Pebble Datastore](#experimental-pebble-datastore) - [New metrics](#new-metrics) - [`lowpower` profile no longer breaks DHT announcements](#lowpower-profile-no-longer-breaks-dht-announcements) + - [go 1.23, boxo 0.24 and go-libp2p 0.36.5](#go-123-boxo-024-and-go-libp2p-0365) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -43,6 +44,10 @@ This release changes [`lowpower` profile](https://github.com/ipfs/kubo/blob/mast > > As a convenience, `ipfs daemon` will warn if reprovide system is disabled, creating oportinity to fix configuration if it was not intentional. +#### go 1.23, boxo 0.24 and go-libp2p 0.36.5 + +Various bugfixes. Please update. + ### 📝 Changelog ### 👨‍👩‍👧‍👦 Contributors diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 36c818068..0c3c73630 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -1,6 +1,8 @@ module github.com/ipfs/kubo/examples/kubo-as-a-library -go 1.22 +go 1.23 + +toolchain go1.23.2 // Used to keep this in sync with the current version of kubo. You should remove // this if you copy this example. diff --git a/go.mod b/go.mod index f6da422ca..5774817e9 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/ipfs/kubo -go 1.22 +go 1.23 require ( bazil.org/fuse v0.0.0-20200117225306-7b5117fecadc From bd9e1548183fcf295e17fe6c17034633b61f045d Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Tue, 8 Oct 2024 19:11:37 +0200 Subject: [PATCH 1183/1212] chore: 0.31.0-rc2 --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index b0785b505..ee75e8876 100644 --- a/version.go +++ b/version.go @@ -11,7 +11,7 @@ import ( var CurrentCommit string // CurrentVersionNumber is the current application's version literal. -const CurrentVersionNumber = "0.31.0-rc1" +const CurrentVersionNumber = "0.31.0-rc2" const ApiVersion = "/kubo/" + CurrentVersionNumber + "/" //nolint From 8135adc8538431b6b14408e34ccf9913d87a754d Mon Sep 17 00:00:00 2001 From: gammazero <11790789+gammazero@users.noreply.github.com> Date: Wed, 16 Oct 2024 04:49:53 -1000 Subject: [PATCH 1184/1212] update version for release --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index ee75e8876..cc6663db8 100644 --- a/version.go +++ b/version.go @@ -11,7 +11,7 @@ import ( var CurrentCommit string // CurrentVersionNumber is the current application's version literal. -const CurrentVersionNumber = "0.31.0-rc2" +const CurrentVersionNumber = "0.31.0" const ApiVersion = "/kubo/" + CurrentVersionNumber + "/" //nolint From 36f385cfdb5231a97ecc4a75e7dc44fe829b69a9 Mon Sep 17 00:00:00 2001 From: gammazero <11790789+gammazero@users.noreply.github.com> Date: Wed, 16 Oct 2024 05:37:42 -1000 Subject: [PATCH 1185/1212] Add full changelog to release changelog --- docs/changelogs/v0.31.md | 101 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) diff --git a/docs/changelogs/v0.31.md b/docs/changelogs/v0.31.md index 22909b9a9..55ddeaeb4 100644 --- a/docs/changelogs/v0.31.md +++ b/docs/changelogs/v0.31.md @@ -50,4 +50,105 @@ Various bugfixes. Please update. ### 📝 Changelog +
Full Changelog + +- github.com/ipfs/kubo: + - fix: go 1.23(.2) (#10540) ([ipfs/kubo#10540](https://github.com/ipfs/kubo/pull/10540)) + - chore: bump version to 0.32.0-dev + - feat(routing/http): support IPIP-484 and streaming (#10534) ([ipfs/kubo#10534](https://github.com/ipfs/kubo/pull/10534)) + - fix(daemon): webui URL when rpc is catch-all (#10520) ([ipfs/kubo#10520](https://github.com/ipfs/kubo/pull/10520)) + - chore: update changelog and config doc with more info about pebble (#10533) ([ipfs/kubo#10533](https://github.com/ipfs/kubo/pull/10533)) + - feat: pebbleds profile and plugin (#10530) ([ipfs/kubo#10530](https://github.com/ipfs/kubo/pull/10530)) + - chore: dependency updates for 0.31 (#10511) ([ipfs/kubo#10511](https://github.com/ipfs/kubo/pull/10511)) + - feat: explicit announce-on/off profiles (#10524) ([ipfs/kubo#10524](https://github.com/ipfs/kubo/pull/10524)) + - fix(core): look for MFS root in local repo only (#8661) ([ipfs/kubo#8661](https://github.com/ipfs/kubo/pull/8661)) + - Fix issue in ResourceManager and nopfsPlugin about repo path (#10492) ([ipfs/kubo#10492](https://github.com/ipfs/kubo/pull/10492)) + - feat(bitswap): allow configuring WithWantHaveReplaceSize (#10512) ([ipfs/kubo#10512](https://github.com/ipfs/kubo/pull/10512)) + - refactor: simplify logic for MFS pinning (#10506) ([ipfs/kubo#10506](https://github.com/ipfs/kubo/pull/10506)) + - docs: clarify Gateway.PublicGateways (#10525) ([ipfs/kubo#10525](https://github.com/ipfs/kubo/pull/10525)) + - chore: clarify dep update in RELEASE_CHECKLIST.md (#10518) ([ipfs/kubo#10518](https://github.com/ipfs/kubo/pull/10518)) + - feat: ipfs-webui v4.3.2 (#10523) ([ipfs/kubo#10523](https://github.com/ipfs/kubo/pull/10523)) + - docs(config): add useful references + - docs(config): improve profile descriptions (#10517) ([ipfs/kubo#10517](https://github.com/ipfs/kubo/pull/10517)) + - docs: update RELEASE_CHECKLIST.md (#10496) ([ipfs/kubo#10496](https://github.com/ipfs/kubo/pull/10496)) + - chore: create next changelog (#10510) ([ipfs/kubo#10510](https://github.com/ipfs/kubo/pull/10510)) + - Merge Release: v0.30.0 [skip changelog] ([ipfs/kubo#10508](https://github.com/ipfs/kubo/pull/10508)) + - chore: boxo v0.23.0 and go-libp2p v0.36.3 (#10507) ([ipfs/kubo#10507](https://github.com/ipfs/kubo/pull/10507)) + - docs: replace outdated package paths described in rpc README (#10505) ([ipfs/kubo#10505](https://github.com/ipfs/kubo/pull/10505)) + - fix: switch back to go 1.22 (#10502) ([ipfs/kubo#10502](https://github.com/ipfs/kubo/pull/10502)) + - fix(cli): preserve hostname specified with --api in http request headers (#10497) ([ipfs/kubo#10497](https://github.com/ipfs/kubo/pull/10497)) + - chore: upgrade to go 1.23 (#10486) ([ipfs/kubo#10486](https://github.com/ipfs/kubo/pull/10486)) + - fix: error during config when running benchmarks (#10495) ([ipfs/kubo#10495](https://github.com/ipfs/kubo/pull/10495)) + - chore: update go-unixfsnode, cmds, and boxo (#10494) ([ipfs/kubo#10494](https://github.com/ipfs/kubo/pull/10494)) + - Docs fix spelling issues (#10493) ([ipfs/kubo#10493](https://github.com/ipfs/kubo/pull/10493)) + - chore: update version (#10491) ([ipfs/kubo#10491](https://github.com/ipfs/kubo/pull/10491)) +- github.com/ipfs/boxo (v0.23.0 -> v0.24.0): + - Release v0.24.0 ([ipfs/boxo#683](https://github.com/ipfs/boxo/pull/683)) +- github.com/ipfs/go-ipld-cbor (v0.1.0 -> v0.2.0): + - v0.2.0 + - deprecate DumpObject() in favor of better named Encode() + - add an EncodeWriter method, using the pooled marshallers + - fix expCid vs actualCid guard +- github.com/ipld/go-car/v2 (v2.13.1 -> v2.14.2): + - v2.14.2 bump + - fix: goreleaser v2 compat, trigger release-binaries with workflow_run + - v2.14.1 bump + - chore: update fuzz to Go 1.22 + - v2.14.0 bump + - fix(cmd): properly pick up --inverse and --cid-file args ([ipld/go-car#531](https://github.com/ipld/go-car/pull/531)) + - Re-factor cmd functions to library ([ipld/go-car#524](https://github.com/ipld/go-car/pull/524)) + - ci: uci/copy-templates ([ipld/go-car#521](https://github.com/ipld/go-car/pull/521)) + - Add a `car ls --unixfs-blocks` to render two-column output ([ipld/go-car#514](https://github.com/ipld/go-car/pull/514)) +- github.com/libp2p/go-libp2p (v0.36.3 -> v0.36.5): + - chore: remove Roadmap file (#2954) ([libp2p/go-libp2p#2954](https://github.com/libp2p/go-libp2p/pull/2954)) + - fix: Release v0.36.5 + - autonatv2: recover from panics (#2992) ([libp2p/go-libp2p#2992](https://github.com/libp2p/go-libp2p/pull/2992)) + - basichost: ensure no duplicates in Addrs output (#2980) ([libp2p/go-libp2p#2980](https://github.com/libp2p/go-libp2p/pull/2980)) + - Release v0.36.4 + - peerstore: better GC in membacked peerstore (#2960) ([libp2p/go-libp2p#2960](https://github.com/libp2p/go-libp2p/pull/2960)) + - fix: use quic.Version instead of the deprecated quic.VersionNumber (#2955) ([libp2p/go-libp2p#2955](https://github.com/libp2p/go-libp2p/pull/2955)) + - tcp: fix metrics for multiple calls to Close (#2953) ([libp2p/go-libp2p#2953](https://github.com/libp2p/go-libp2p/pull/2953)) +- github.com/libp2p/go-libp2p-kbucket (v0.6.3 -> v0.6.4): + - release v0.6.4 ([libp2p/go-libp2p-kbucket#135](https://github.com/libp2p/go-libp2p-kbucket/pull/135)) + - feat: add log printing when peer added and removed table ([libp2p/go-libp2p-kbucket#134](https://github.com/libp2p/go-libp2p-kbucket/pull/134)) + - Upgrade to go-log v2.5.1 ([libp2p/go-libp2p-kbucket#132](https://github.com/libp2p/go-libp2p-kbucket/pull/132)) + - chore: update go-libp2p-asn-util +- github.com/multiformats/go-multiaddr-dns (v0.3.1 -> v0.4.0): + - Release v0.4.0 (#64) ([multiformats/go-multiaddr-dns#64](https://github.com/multiformats/go-multiaddr-dns/pull/64)) + - Limit total number of resolved addresses from DNS response (#63) ([multiformats/go-multiaddr-dns#63](https://github.com/multiformats/go-multiaddr-dns/pull/63)) + - fix!: Only resolve the first DNS-like component (#61) ([multiformats/go-multiaddr-dns#61](https://github.com/multiformats/go-multiaddr-dns/pull/61)) + - sync: update CI config files (#43) ([multiformats/go-multiaddr-dns#43](https://github.com/multiformats/go-multiaddr-dns/pull/43)) + - remove deprecated types ([multiformats/go-multiaddr-dns#37](https://github.com/multiformats/go-multiaddr-dns/pull/37)) + - remove Jenkinsfile ([multiformats/go-multiaddr-dns#40](https://github.com/multiformats/go-multiaddr-dns/pull/40)) + - sync: update CI config files (#29) ([multiformats/go-multiaddr-dns#29](https://github.com/multiformats/go-multiaddr-dns/pull/29)) + - use net.IP.Equal to compare IP addresses ([multiformats/go-multiaddr-dns#30](https://github.com/multiformats/go-multiaddr-dns/pull/30)) + +
+ ### 👨‍👩‍👧‍👦 Contributors + +| Contributor | Commits | Lines ± | Files Changed | +|-------------|---------|---------|---------------| +| Will Scott | 3 | +731/-581 | 14 | +| Daniel N | 17 | +1034/-191 | 33 | +| Marco Munizaga | 5 | +721/-404 | 12 | +| Andrew Gillis | 9 | +765/-266 | 35 | +| Marcin Rataj | 17 | +568/-323 | 41 | +| Daniel Norman | 3 | +232/-111 | 10 | +| sukun | 4 | +93/-8 | 8 | +| Jorropo | 2 | +48/-45 | 5 | +| Marten Seemann | 3 | +19/-47 | 5 | +| fengzie | 1 | +29/-26 | 5 | +| Rod Vagg | 7 | +27/-11 | 9 | +| gopherfarm | 1 | +14/-14 | 6 | +| web3-bot | 3 | +13/-10 | 3 | +| Michael Muré | 2 | +16/-5 | 4 | +| i-norden | 1 | +9/-9 | 1 | +| Elias Rad | 1 | +7/-7 | 4 | +| Prithvi Shahi | 1 | +0/-11 | 2 | +| Lucas Molas | 1 | +5/-4 | 1 | +| elecbug | 1 | +6/-2 | 1 | +| gammazero | 2 | +2/-2 | 2 | +| chris erway | 1 | +2/-2 | 2 | +| Russell Dempsey | 1 | +2/-1 | 1 | +| guillaumemichel | 1 | +1/-1 | 1 | From 4aebe7f27b578565c577541fa32bfc5a058a0bca Mon Sep 17 00:00:00 2001 From: gammazero <11790789+gammazero@users.noreply.github.com> Date: Wed, 16 Oct 2024 05:37:42 -1000 Subject: [PATCH 1186/1212] Add full changelog to release changelog (cherry picked from commit 36f385cfdb5231a97ecc4a75e7dc44fe829b69a9) --- docs/changelogs/v0.31.md | 101 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) diff --git a/docs/changelogs/v0.31.md b/docs/changelogs/v0.31.md index 7d734209e..b20b15862 100644 --- a/docs/changelogs/v0.31.md +++ b/docs/changelogs/v0.31.md @@ -50,4 +50,105 @@ Various bugfixes. Please update. ### 📝 Changelog +
Full Changelog + +- github.com/ipfs/kubo: + - fix: go 1.23(.2) (#10540) ([ipfs/kubo#10540](https://github.com/ipfs/kubo/pull/10540)) + - chore: bump version to 0.32.0-dev + - feat(routing/http): support IPIP-484 and streaming (#10534) ([ipfs/kubo#10534](https://github.com/ipfs/kubo/pull/10534)) + - fix(daemon): webui URL when rpc is catch-all (#10520) ([ipfs/kubo#10520](https://github.com/ipfs/kubo/pull/10520)) + - chore: update changelog and config doc with more info about pebble (#10533) ([ipfs/kubo#10533](https://github.com/ipfs/kubo/pull/10533)) + - feat: pebbleds profile and plugin (#10530) ([ipfs/kubo#10530](https://github.com/ipfs/kubo/pull/10530)) + - chore: dependency updates for 0.31 (#10511) ([ipfs/kubo#10511](https://github.com/ipfs/kubo/pull/10511)) + - feat: explicit announce-on/off profiles (#10524) ([ipfs/kubo#10524](https://github.com/ipfs/kubo/pull/10524)) + - fix(core): look for MFS root in local repo only (#8661) ([ipfs/kubo#8661](https://github.com/ipfs/kubo/pull/8661)) + - Fix issue in ResourceManager and nopfsPlugin about repo path (#10492) ([ipfs/kubo#10492](https://github.com/ipfs/kubo/pull/10492)) + - feat(bitswap): allow configuring WithWantHaveReplaceSize (#10512) ([ipfs/kubo#10512](https://github.com/ipfs/kubo/pull/10512)) + - refactor: simplify logic for MFS pinning (#10506) ([ipfs/kubo#10506](https://github.com/ipfs/kubo/pull/10506)) + - docs: clarify Gateway.PublicGateways (#10525) ([ipfs/kubo#10525](https://github.com/ipfs/kubo/pull/10525)) + - chore: clarify dep update in RELEASE_CHECKLIST.md (#10518) ([ipfs/kubo#10518](https://github.com/ipfs/kubo/pull/10518)) + - feat: ipfs-webui v4.3.2 (#10523) ([ipfs/kubo#10523](https://github.com/ipfs/kubo/pull/10523)) + - docs(config): add useful references + - docs(config): improve profile descriptions (#10517) ([ipfs/kubo#10517](https://github.com/ipfs/kubo/pull/10517)) + - docs: update RELEASE_CHECKLIST.md (#10496) ([ipfs/kubo#10496](https://github.com/ipfs/kubo/pull/10496)) + - chore: create next changelog (#10510) ([ipfs/kubo#10510](https://github.com/ipfs/kubo/pull/10510)) + - Merge Release: v0.30.0 [skip changelog] ([ipfs/kubo#10508](https://github.com/ipfs/kubo/pull/10508)) + - chore: boxo v0.23.0 and go-libp2p v0.36.3 (#10507) ([ipfs/kubo#10507](https://github.com/ipfs/kubo/pull/10507)) + - docs: replace outdated package paths described in rpc README (#10505) ([ipfs/kubo#10505](https://github.com/ipfs/kubo/pull/10505)) + - fix: switch back to go 1.22 (#10502) ([ipfs/kubo#10502](https://github.com/ipfs/kubo/pull/10502)) + - fix(cli): preserve hostname specified with --api in http request headers (#10497) ([ipfs/kubo#10497](https://github.com/ipfs/kubo/pull/10497)) + - chore: upgrade to go 1.23 (#10486) ([ipfs/kubo#10486](https://github.com/ipfs/kubo/pull/10486)) + - fix: error during config when running benchmarks (#10495) ([ipfs/kubo#10495](https://github.com/ipfs/kubo/pull/10495)) + - chore: update go-unixfsnode, cmds, and boxo (#10494) ([ipfs/kubo#10494](https://github.com/ipfs/kubo/pull/10494)) + - Docs fix spelling issues (#10493) ([ipfs/kubo#10493](https://github.com/ipfs/kubo/pull/10493)) + - chore: update version (#10491) ([ipfs/kubo#10491](https://github.com/ipfs/kubo/pull/10491)) +- github.com/ipfs/boxo (v0.23.0 -> v0.24.0): + - Release v0.24.0 ([ipfs/boxo#683](https://github.com/ipfs/boxo/pull/683)) +- github.com/ipfs/go-ipld-cbor (v0.1.0 -> v0.2.0): + - v0.2.0 + - deprecate DumpObject() in favor of better named Encode() + - add an EncodeWriter method, using the pooled marshallers + - fix expCid vs actualCid guard +- github.com/ipld/go-car/v2 (v2.13.1 -> v2.14.2): + - v2.14.2 bump + - fix: goreleaser v2 compat, trigger release-binaries with workflow_run + - v2.14.1 bump + - chore: update fuzz to Go 1.22 + - v2.14.0 bump + - fix(cmd): properly pick up --inverse and --cid-file args ([ipld/go-car#531](https://github.com/ipld/go-car/pull/531)) + - Re-factor cmd functions to library ([ipld/go-car#524](https://github.com/ipld/go-car/pull/524)) + - ci: uci/copy-templates ([ipld/go-car#521](https://github.com/ipld/go-car/pull/521)) + - Add a `car ls --unixfs-blocks` to render two-column output ([ipld/go-car#514](https://github.com/ipld/go-car/pull/514)) +- github.com/libp2p/go-libp2p (v0.36.3 -> v0.36.5): + - chore: remove Roadmap file (#2954) ([libp2p/go-libp2p#2954](https://github.com/libp2p/go-libp2p/pull/2954)) + - fix: Release v0.36.5 + - autonatv2: recover from panics (#2992) ([libp2p/go-libp2p#2992](https://github.com/libp2p/go-libp2p/pull/2992)) + - basichost: ensure no duplicates in Addrs output (#2980) ([libp2p/go-libp2p#2980](https://github.com/libp2p/go-libp2p/pull/2980)) + - Release v0.36.4 + - peerstore: better GC in membacked peerstore (#2960) ([libp2p/go-libp2p#2960](https://github.com/libp2p/go-libp2p/pull/2960)) + - fix: use quic.Version instead of the deprecated quic.VersionNumber (#2955) ([libp2p/go-libp2p#2955](https://github.com/libp2p/go-libp2p/pull/2955)) + - tcp: fix metrics for multiple calls to Close (#2953) ([libp2p/go-libp2p#2953](https://github.com/libp2p/go-libp2p/pull/2953)) +- github.com/libp2p/go-libp2p-kbucket (v0.6.3 -> v0.6.4): + - release v0.6.4 ([libp2p/go-libp2p-kbucket#135](https://github.com/libp2p/go-libp2p-kbucket/pull/135)) + - feat: add log printing when peer added and removed table ([libp2p/go-libp2p-kbucket#134](https://github.com/libp2p/go-libp2p-kbucket/pull/134)) + - Upgrade to go-log v2.5.1 ([libp2p/go-libp2p-kbucket#132](https://github.com/libp2p/go-libp2p-kbucket/pull/132)) + - chore: update go-libp2p-asn-util +- github.com/multiformats/go-multiaddr-dns (v0.3.1 -> v0.4.0): + - Release v0.4.0 (#64) ([multiformats/go-multiaddr-dns#64](https://github.com/multiformats/go-multiaddr-dns/pull/64)) + - Limit total number of resolved addresses from DNS response (#63) ([multiformats/go-multiaddr-dns#63](https://github.com/multiformats/go-multiaddr-dns/pull/63)) + - fix!: Only resolve the first DNS-like component (#61) ([multiformats/go-multiaddr-dns#61](https://github.com/multiformats/go-multiaddr-dns/pull/61)) + - sync: update CI config files (#43) ([multiformats/go-multiaddr-dns#43](https://github.com/multiformats/go-multiaddr-dns/pull/43)) + - remove deprecated types ([multiformats/go-multiaddr-dns#37](https://github.com/multiformats/go-multiaddr-dns/pull/37)) + - remove Jenkinsfile ([multiformats/go-multiaddr-dns#40](https://github.com/multiformats/go-multiaddr-dns/pull/40)) + - sync: update CI config files (#29) ([multiformats/go-multiaddr-dns#29](https://github.com/multiformats/go-multiaddr-dns/pull/29)) + - use net.IP.Equal to compare IP addresses ([multiformats/go-multiaddr-dns#30](https://github.com/multiformats/go-multiaddr-dns/pull/30)) + +
+ ### 👨‍👩‍👧‍👦 Contributors + +| Contributor | Commits | Lines ± | Files Changed | +|-------------|---------|---------|---------------| +| Will Scott | 3 | +731/-581 | 14 | +| Daniel N | 17 | +1034/-191 | 33 | +| Marco Munizaga | 5 | +721/-404 | 12 | +| Andrew Gillis | 9 | +765/-266 | 35 | +| Marcin Rataj | 17 | +568/-323 | 41 | +| Daniel Norman | 3 | +232/-111 | 10 | +| sukun | 4 | +93/-8 | 8 | +| Jorropo | 2 | +48/-45 | 5 | +| Marten Seemann | 3 | +19/-47 | 5 | +| fengzie | 1 | +29/-26 | 5 | +| Rod Vagg | 7 | +27/-11 | 9 | +| gopherfarm | 1 | +14/-14 | 6 | +| web3-bot | 3 | +13/-10 | 3 | +| Michael Muré | 2 | +16/-5 | 4 | +| i-norden | 1 | +9/-9 | 1 | +| Elias Rad | 1 | +7/-7 | 4 | +| Prithvi Shahi | 1 | +0/-11 | 2 | +| Lucas Molas | 1 | +5/-4 | 1 | +| elecbug | 1 | +6/-2 | 1 | +| gammazero | 2 | +2/-2 | 2 | +| chris erway | 1 | +2/-2 | 2 | +| Russell Dempsey | 1 | +2/-1 | 1 | +| guillaumemichel | 1 | +1/-1 | 1 | From c488864f93bc9a0a87ff89a31d7a0d5b005a1fc2 Mon Sep 17 00:00:00 2001 From: Andrew Gillis <11790789+gammazero@users.noreply.github.com> Date: Wed, 16 Oct 2024 08:03:37 -1000 Subject: [PATCH 1187/1212] chore: update RELEASE_CHECKLIST.md (#10542) Update distribution publishing procedure --- docs/RELEASE_CHECKLIST.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/RELEASE_CHECKLIST.md b/docs/RELEASE_CHECKLIST.md index 476c77b15..a256c5d8b 100644 --- a/docs/RELEASE_CHECKLIST.md +++ b/docs/RELEASE_CHECKLIST.md @@ -84,9 +84,10 @@ This section covers tasks to be done during each release. - [ ] verify the image is available on [Docker Hub](https://hub.docker.com/r/ipfs/kubo/tags) - [ ] Publish the release to [dist.ipfs.tech](https://dist.ipfs.tech)
using `./kuboreleaser release --version vX.Y.Z(-rcN) publish-to-distributions` or ... - [ ] check out [ipfs/distributions](https://github.com/ipfs/distributions) + - [ ] create new branch: run `git checkout -b release-kubo-X.Y.Z(-rcN)` - [ ] run `./dist.sh add-version kubo vX.Y.Z(-RCN)` to add the new version to the `versions` file - [usage](https://github.com/ipfs/distributions#usage) - - [ ] create and merge the PR which updates `dists/kubo/versions` and `dists/go-ipfs/versions` (![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) and `dists/kubo/current_version` and `dists/go-ipfs/current_version`) + - [ ] create and merge the PR which updates `dists/kubo/versions` and `dists/go-ipfs/versions` (![](https://img.shields.io/badge/only-FINAL-green?style=flat-square) and `dists/kubo/current` and `dists/go-ipfs/current`) - [example](https://github.com/ipfs/distributions/pull/760) - [ ] wait for the [CI](https://github.com/ipfs/distributions/actions/workflows/main.yml) workflow run initiated by the merge to master to finish - [ ] verify the release is available on [dist.ipfs.tech](https://dist.ipfs.tech/#kubo) From b3366025970acbf64d3f272a002f5fc175972943 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Wed, 16 Oct 2024 20:51:17 +0200 Subject: [PATCH 1188/1212] feat: ipfs-webui v4.3.3 (#10543) https://github.com/ipfs/ipfs-webui/releases/tag/v4.3.3 --- core/corehttp/webui.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/corehttp/webui.go b/core/corehttp/webui.go index 2117d78af..4014e69b3 100644 --- a/core/corehttp/webui.go +++ b/core/corehttp/webui.go @@ -1,11 +1,12 @@ package corehttp // WebUI version confirmed to work with this Kubo version -const WebUIPath = "/ipfs/bafybeif6abowqcavbkz243biyh7pde7ick5kkwwytrh7pd2hkbtuqysjxy" // v4.3.2 +const WebUIPath = "/ipfs/bafybeid4uxz7klxcu3ffsnmn64r7ihvysamlj4ohl5h2orjsffuegcpaeq" // v4.3.3 // WebUIPaths is a list of all past webUI paths. var WebUIPaths = []string{ WebUIPath, + "/ipfs/bafybeif6abowqcavbkz243biyh7pde7ick5kkwwytrh7pd2hkbtuqysjxy", "/ipfs/bafybeihatzsgposbr3hrngo42yckdyqcc56yean2rynnwpzxstvdlphxf4", "/ipfs/bafybeigggyffcf6yfhx5irtwzx3cgnk6n3dwylkvcpckzhqqrigsxowjwe", "/ipfs/bafybeidf7cpkwsjkq6xs3r6fbbxghbugilx3jtezbza7gua3k5wjixpmba", From 61bae0360e4b454229068837396b02c58e958fff Mon Sep 17 00:00:00 2001 From: Andrew Gillis <11790789+gammazero@users.noreply.github.com> Date: Wed, 16 Oct 2024 10:06:12 -1000 Subject: [PATCH 1189/1212] chore: update RELEASE_CHECKLIST.md (#10544) --- docs/RELEASE_CHECKLIST.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/RELEASE_CHECKLIST.md b/docs/RELEASE_CHECKLIST.md index a256c5d8b..9a9d7f113 100644 --- a/docs/RELEASE_CHECKLIST.md +++ b/docs/RELEASE_CHECKLIST.md @@ -92,10 +92,10 @@ This section covers tasks to be done during each release. - [ ] wait for the [CI](https://github.com/ipfs/distributions/actions/workflows/main.yml) workflow run initiated by the merge to master to finish - [ ] verify the release is available on [dist.ipfs.tech](https://dist.ipfs.tech/#kubo)
- - [ ] Publish the release to [NPM](https://www.npmjs.com/package/go-ipfs?activeTab=versions)
using `./kuboreleaser release --version vX.Y.Z(-rcN) publish-to-npm` (⚠️ you might need to run the command a couple of times because GHA might not be able to see the new distribution straight away due to caching) or ... + - [ ] Publish the release to [NPM](https://www.npmjs.com/package/kubo?activeTab=versions)
using `./kuboreleaser release --version vX.Y.Z(-rcN) publish-to-npm` (⚠️ you might need to run the command a couple of times because GHA might not be able to see the new distribution straight away due to caching) or ... - [ ] run the [Release to npm](https://github.com/ipfs/npm-go-ipfs/actions/workflows/main.yml) workflow - [ ] check [Release to npm](https://github.com/ipfs/npm-go-ipfs/actions/workflows/main.yml) workflow run logs to verify it discovered the new release - - [ ] verify the release is available on [NPM](https://www.npmjs.com/package/go-ipfs?activeTab=versions) + - [ ] verify the release is available on [NPM](https://www.npmjs.com/package/kubo?activeTab=versions)
- [ ] Publish the release to [GitHub](https://github.com/ipfs/kubo/releases)
using `./kuboreleaser release --version vX.Y.Z(-rcN) publish-to-github` or ... - [ ] create a new release on [GitHub](https://docs.github.com/en/repositories/releasing-projects-on-github/managing-releases-in-a-repository#creating-a-release) From 5cc979f15fbc3d431ce7962a14247b9f7354294e Mon Sep 17 00:00:00 2001 From: gammazero <11790789+gammazero@users.noreply.github.com> Date: Wed, 16 Oct 2024 22:03:21 -1000 Subject: [PATCH 1190/1212] Create Changelog: v0.32 This PR creates changelog: v0.32 --- CHANGELOG.md | 1 + docs/changelogs/v0.32.md | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 docs/changelogs/v0.32.md diff --git a/CHANGELOG.md b/CHANGELOG.md index fa40e1625..621e07d7f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ # Kubo Changelogs +- [v0.32](docs/changelogs/v0.32.md) - [v0.31](docs/changelogs/v0.31.md) - [v0.30](docs/changelogs/v0.30.md) - [v0.29](docs/changelogs/v0.29.md) diff --git a/docs/changelogs/v0.32.md b/docs/changelogs/v0.32.md new file mode 100644 index 000000000..0744bd628 --- /dev/null +++ b/docs/changelogs/v0.32.md @@ -0,0 +1,18 @@ +# Kubo changelog v0.32 + +- [v0.31.0](#v0320) + +## v0.32.0 + +- [Overview](#overview) +- [🔦 Highlights](#-highlights) +- [📝 Changelog](#-changelog) +- [👨‍👩‍👧‍👦 Contributors](#-contributors) + +### Overview + +### 🔦 Highlights + +### 📝 Changelog + +### 👨‍👩‍👧‍👦 Contributors From 550f4642634ccc8bfd5f07c63be87a1160e4d02c Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Mon, 21 Oct 2024 15:58:34 +0200 Subject: [PATCH 1191/1212] chore(ci): build docker images for staging branch --- .github/workflows/docker-image.yml | 1 + bin/get-docker-tags.sh | 8 ++++---- bin/push-docker-tags.sh | 10 ++++++---- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index f5642fe6d..ce927e5e5 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -19,6 +19,7 @@ on: push: branches: - 'master' + - 'staging' - 'bifrost-*' tags: - 'v*' diff --git a/bin/get-docker-tags.sh b/bin/get-docker-tags.sh index e54da6482..1c4e184f2 100755 --- a/bin/get-docker-tags.sh +++ b/bin/get-docker-tags.sh @@ -18,7 +18,7 @@ set -euo pipefail if [[ $# -lt 1 ]] ; then echo 'At least 1 arg required.' echo 'Usage:' - echo './push-docker-tags.sh [git commit sha1] [git branch name] [git tag name]' + echo './get-docker-tags.sh [git commit sha1] [git branch name] [git tag name]' exit 1 fi @@ -50,9 +50,9 @@ elif [[ $GIT_BRANCH =~ ^bifrost-.* ]]; then branch=$(echo "$GIT_BRANCH" | tr '/' '-' | tr --delete --complement '[:alnum:]-') echoImageName "${branch}-${BUILD_NUM}-${GIT_SHA1_SHORT}" -elif [ "$GIT_BRANCH" = "master" ]; then - echoImageName "master-${BUILD_NUM}-${GIT_SHA1_SHORT}" - echoImageName "master-latest" +elif [ "$GIT_BRANCH" = "master" ] || [ "$GIT_BRANCH" = "staging" ]; then + echoImageName "${GIT_BRANCH}-${BUILD_NUM}-${GIT_SHA1_SHORT}" + echoImageName "${GIT_BRANCH}-latest" else echo "Nothing to do. No docker tag defined for branch: $GIT_BRANCH, tag: $GIT_TAG" diff --git a/bin/push-docker-tags.sh b/bin/push-docker-tags.sh index af809b989..a33948307 100755 --- a/bin/push-docker-tags.sh +++ b/bin/push-docker-tags.sh @@ -1,5 +1,7 @@ #!/usr/bin/env bash - +# +# TODO: this script is legacy, use get-docker-tags.sh instead. +# # push-docker-tags.sh # # Run from ci to tag images based on the current branch or tag name. @@ -68,9 +70,9 @@ elif [[ $GIT_BRANCH =~ ^bifrost-.* ]]; then branch=$(echo "$GIT_BRANCH" | tr '/' '-' | tr --delete --complement '[:alnum:]-') pushTag "${branch}-${BUILD_NUM}-${GIT_SHA1_SHORT}" -elif [ "$GIT_BRANCH" = "master" ]; then - pushTag "master-${BUILD_NUM}-${GIT_SHA1_SHORT}" - pushTag "master-latest" +elif [ "$GIT_BRANCH" = "master" ] || [ "$GIT_BRANCH" = "staging" ]; then + pushTag "${GIT_BRANCH}-${BUILD_NUM}-${GIT_SHA1_SHORT}" + pushTag "${GIT_BRANCH}-latest" else echo "Nothing to do. No docker tag defined for branch: $GIT_BRANCH, tag: $GIT_TAG" From 1cb153757ceb51977651740afe6196f7ebc5a6b5 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Mon, 21 Oct 2024 19:23:29 +0200 Subject: [PATCH 1192/1212] chore(ci): verbose build of test/bin deps this aims to help with debugging CI failure in https://github.com/ipfs/boxo/pull/693 --- test/bin/Rules.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/bin/Rules.mk b/test/bin/Rules.mk index 4e264106a..35bc57f51 100644 --- a/test/bin/Rules.mk +++ b/test/bin/Rules.mk @@ -5,7 +5,7 @@ TGTS_$(d) := define go-build-testdep OUT="$(CURDIR)/$@" ; \ cd "test/dependencies" ; \ - $(GOCC) build $(go-flags-with-tags) -o "$${OUT}" "$<" + $(GOCC) build -v $(go-flags-with-tags) -o "$${OUT}" "$<" 2>&1 endef .PHONY: github.com/ipfs/kubo/test/dependencies/pollEndpoint From 551ac65b84d04bde63da30091d7f18c477dbaaf7 Mon Sep 17 00:00:00 2001 From: Andrew Gillis <11790789+gammazero@users.noreply.github.com> Date: Mon, 21 Oct 2024 08:05:32 -1000 Subject: [PATCH 1193/1212] chore: update go-unixfsnode (#10553) minor dependency update --- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 6 ++---- go.mod | 2 +- go.sum | 6 ++---- 4 files changed, 6 insertions(+), 10 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 0c3c73630..15028beda 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -102,7 +102,7 @@ require ( github.com/ipfs/go-merkledag v0.11.0 // indirect github.com/ipfs/go-metrics-interface v0.0.1 // indirect github.com/ipfs/go-peertaskqueue v0.8.1 // indirect - github.com/ipfs/go-unixfsnode v1.9.1 // indirect + github.com/ipfs/go-unixfsnode v1.9.2 // indirect github.com/ipfs/go-verifcid v0.0.3 // indirect github.com/ipld/go-car v0.6.2 // indirect github.com/ipld/go-car/v2 v2.14.2 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index ae9498ade..55d6838da 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -374,10 +374,8 @@ github.com/ipfs/go-peertaskqueue v0.8.1 h1:YhxAs1+wxb5jk7RvS0LHdyiILpNmRIRnZVzte github.com/ipfs/go-peertaskqueue v0.8.1/go.mod h1:Oxxd3eaK279FxeydSPPVGHzbwVeHjatZ2GA8XD+KbPU= github.com/ipfs/go-test v0.0.4 h1:DKT66T6GBB6PsDFLoO56QZPrOmzJkqU1FZH5C9ySkew= github.com/ipfs/go-test v0.0.4/go.mod h1:qhIM1EluEfElKKM6fnWxGn822/z9knUGM1+I/OAQNKI= -github.com/ipfs/go-unixfs v0.4.5 h1:wj8JhxvV1G6CD7swACwSKYa+NgtdWC1RUit+gFnymDU= -github.com/ipfs/go-unixfs v0.4.5/go.mod h1:BIznJNvt/gEx/ooRMI4Us9K8+qeGO7vx1ohnbk8gjFg= -github.com/ipfs/go-unixfsnode v1.9.1 h1:2cdSIDQCt7emNhlyUqUFQnKo2XvecARoIcurIKFjPD8= -github.com/ipfs/go-unixfsnode v1.9.1/go.mod h1:u8WxhmXzyrq3xfSYkhfx+uI+n91O+0L7KFjq3TS7d6g= +github.com/ipfs/go-unixfsnode v1.9.2 h1:0A12BYs4XOtDPJTMlwmNPlllDfqcc4yie4e919hcUXk= +github.com/ipfs/go-unixfsnode v1.9.2/go.mod h1:v1nuMFHf4QTIhFUdPMvg1nQu7AqDLvIdwyvJ531Ot1U= github.com/ipfs/go-verifcid v0.0.3 h1:gmRKccqhWDocCRkC+a59g5QW7uJw5bpX9HWBevXa0zs= github.com/ipfs/go-verifcid v0.0.3/go.mod h1:gcCtGniVzelKrbk9ooUSX/pM3xlH73fZZJDzQJRvOUw= github.com/ipld/go-car v0.6.2 h1:Hlnl3Awgnq8icK+ze3iRghk805lu8YNq3wlREDTF2qc= diff --git a/go.mod b/go.mod index 5774817e9..700e62d50 100644 --- a/go.mod +++ b/go.mod @@ -43,7 +43,7 @@ require ( github.com/ipfs/go-metrics-interface v0.0.1 github.com/ipfs/go-metrics-prometheus v0.0.2 github.com/ipfs/go-test v0.0.4 - github.com/ipfs/go-unixfsnode v1.9.1 + github.com/ipfs/go-unixfsnode v1.9.2 github.com/ipld/go-car v0.6.2 github.com/ipld/go-car/v2 v2.14.2 github.com/ipld/go-codec-dagpb v1.6.0 diff --git a/go.sum b/go.sum index 22b5807db..5031c5833 100644 --- a/go.sum +++ b/go.sum @@ -442,10 +442,8 @@ github.com/ipfs/go-peertaskqueue v0.8.1 h1:YhxAs1+wxb5jk7RvS0LHdyiILpNmRIRnZVzte github.com/ipfs/go-peertaskqueue v0.8.1/go.mod h1:Oxxd3eaK279FxeydSPPVGHzbwVeHjatZ2GA8XD+KbPU= github.com/ipfs/go-test v0.0.4 h1:DKT66T6GBB6PsDFLoO56QZPrOmzJkqU1FZH5C9ySkew= github.com/ipfs/go-test v0.0.4/go.mod h1:qhIM1EluEfElKKM6fnWxGn822/z9knUGM1+I/OAQNKI= -github.com/ipfs/go-unixfs v0.4.5 h1:wj8JhxvV1G6CD7swACwSKYa+NgtdWC1RUit+gFnymDU= -github.com/ipfs/go-unixfs v0.4.5/go.mod h1:BIznJNvt/gEx/ooRMI4Us9K8+qeGO7vx1ohnbk8gjFg= -github.com/ipfs/go-unixfsnode v1.9.1 h1:2cdSIDQCt7emNhlyUqUFQnKo2XvecARoIcurIKFjPD8= -github.com/ipfs/go-unixfsnode v1.9.1/go.mod h1:u8WxhmXzyrq3xfSYkhfx+uI+n91O+0L7KFjq3TS7d6g= +github.com/ipfs/go-unixfsnode v1.9.2 h1:0A12BYs4XOtDPJTMlwmNPlllDfqcc4yie4e919hcUXk= +github.com/ipfs/go-unixfsnode v1.9.2/go.mod h1:v1nuMFHf4QTIhFUdPMvg1nQu7AqDLvIdwyvJ531Ot1U= github.com/ipfs/go-verifcid v0.0.3 h1:gmRKccqhWDocCRkC+a59g5QW7uJw5bpX9HWBevXa0zs= github.com/ipfs/go-verifcid v0.0.3/go.mod h1:gcCtGniVzelKrbk9ooUSX/pM3xlH73fZZJDzQJRvOUw= github.com/ipld/go-car v0.6.2 h1:Hlnl3Awgnq8icK+ze3iRghk805lu8YNq3wlREDTF2qc= From 68b478d6b237109f0a745214ff1eaed13041b56e Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Mon, 21 Oct 2024 20:19:46 +0200 Subject: [PATCH 1194/1212] chore(ci): adjust verbosity --- test/bin/Rules.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/bin/Rules.mk b/test/bin/Rules.mk index 35bc57f51..3fd0bcd92 100644 --- a/test/bin/Rules.mk +++ b/test/bin/Rules.mk @@ -5,7 +5,7 @@ TGTS_$(d) := define go-build-testdep OUT="$(CURDIR)/$@" ; \ cd "test/dependencies" ; \ - $(GOCC) build -v $(go-flags-with-tags) -o "$${OUT}" "$<" 2>&1 + $(GOCC) build $(go-flags-with-tags) -o "$${OUT}" "$<" 2>&1 endef .PHONY: github.com/ipfs/kubo/test/dependencies/pollEndpoint From b5b35a4725fe7d48557a7e0b7ea30c0d91d849f1 Mon Sep 17 00:00:00 2001 From: Andrew Gillis <11790789+gammazero@users.noreply.github.com> Date: Mon, 21 Oct 2024 14:07:53 -1000 Subject: [PATCH 1195/1212] chore: update test dependencies (#10555) --- test/dependencies/go.mod | 17 +++++------- test/dependencies/go.sum | 38 ++++++++------------------ test/dependencies/pollEndpoint/main.go | 2 +- 3 files changed, 19 insertions(+), 38 deletions(-) diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 6fbcd249d..3d0c0b448 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -8,10 +8,10 @@ require ( github.com/Kubuxu/gocovmerge v0.0.0-20161216165753-7ecaa51963cd github.com/golangci/golangci-lint v1.60.2 github.com/ipfs/go-cidutil v0.1.0 - github.com/ipfs/go-log v1.0.5 + github.com/ipfs/go-log/v2 v2.5.1 github.com/ipfs/hang-fds v0.1.0 - github.com/ipfs/iptb v1.4.0 - github.com/ipfs/iptb-plugins v0.5.0 + github.com/ipfs/iptb v1.4.1 + github.com/ipfs/iptb-plugins v0.5.1 github.com/jbenet/go-random v0.0.0-20190219211222-123a90aedc0c github.com/jbenet/go-random-files v0.0.0-20190219210431-31b3f20ebded github.com/multiformats/go-multiaddr v0.13.0 @@ -54,7 +54,7 @@ require ( github.com/charithe/durationcheck v0.0.10 // indirect github.com/chavacava/garif v0.1.0 // indirect github.com/ckaznocha/intrange v0.1.2 // indirect - github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect github.com/curioswitch/go-reassign v0.2.0 // indirect github.com/daixiang0/gci v0.13.4 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect @@ -101,7 +101,6 @@ require ( github.com/gostaticanalysis/comment v1.4.2 // indirect github.com/gostaticanalysis/forcetypeassert v0.1.0 // indirect github.com/gostaticanalysis/nilerr v0.1.1 // indirect - github.com/gxed/go-shellwords v1.0.3 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-version v1.7.0 // indirect @@ -118,9 +117,8 @@ require ( github.com/ipfs/go-ipfs-util v0.0.3 // indirect github.com/ipfs/go-ipld-format v0.6.0 // indirect github.com/ipfs/go-ipld-legacy v0.2.1 // indirect - github.com/ipfs/go-log/v2 v2.5.1 // indirect github.com/ipfs/go-metrics-interface v0.0.1 // indirect - github.com/ipfs/kubo v0.16.0 // indirect + github.com/ipfs/kubo v0.31.0 // indirect github.com/ipld/go-codec-dagpb v1.6.0 // indirect github.com/ipld/go-ipld-prime v0.21.0 // indirect github.com/jbenet/goprocess v0.1.4 // indirect @@ -159,6 +157,7 @@ require ( github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-runewidth v0.0.15 // indirect + github.com/mattn/go-shellwords v1.0.12 // indirect github.com/mgechev/revive v1.3.9 // indirect github.com/miekg/dns v1.1.61 // indirect github.com/minio/sha256-simd v1.0.1 // indirect @@ -179,9 +178,7 @@ require ( github.com/nishanths/predeclared v0.2.2 // indirect github.com/nunnatsa/ginkgolinter v0.16.2 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect - github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/pelletier/go-toml/v2 v2.2.2 // indirect - github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/polydawn/refmt v0.89.0 // indirect github.com/polyfloyd/go-errorlint v1.6.0 // indirect @@ -232,7 +229,7 @@ require ( github.com/tommy-muehle/go-mnd/v2 v2.5.1 // indirect github.com/ultraware/funlen v0.1.0 // indirect github.com/ultraware/whitespace v0.1.1 // indirect - github.com/urfave/cli v1.22.10 // indirect + github.com/urfave/cli v1.22.16 // indirect github.com/uudashr/gocognit v1.1.3 // indirect github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc // indirect github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 06443b67c..4ddf403b5 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -14,6 +14,7 @@ github.com/Antonboom/nilnil v0.1.9/go.mod h1:iGe2rYwCq5/Me1khrysB4nwI7swQvjclR8/ github.com/Antonboom/testifylint v1.4.3 h1:ohMt6AHuHgttaQ1xb6SSnxCeK4/rnK7KKzbvs7DmEck= github.com/Antonboom/testifylint v1.4.3/go.mod h1:+8Q9+AOLsz5ZiQiiYujJKs9mNz398+M6UgslP4qgJLA= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c h1:pxW6RcqyfI9/kWtOwnv/G+AzdKuy2ZrqINhenH4HyNs= github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/Crocmagnon/fatcontext v0.4.0 h1:4ykozu23YHA0JB6+thiuEv7iT6xq995qS1vcuWZq0tg= @@ -85,8 +86,9 @@ github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHq github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= 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.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4= github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc= +github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/cskr/pubsub v1.0.2 h1:vlOzMhl6PFn60gRlTQQsIfVwaPB/B/8MziK8FhEPt/0= github.com/cskr/pubsub v1.0.2/go.mod h1:/8MzYXk/NJAz782G8RPkFzXTZVu63VotefPnR9TIRis= github.com/curioswitch/go-reassign v0.2.0 h1:G9UZyOcpk/d7Gd6mqYgd8XYWFMw/znxwGDUstnC9DIo= @@ -232,7 +234,6 @@ github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 h1:FKHo8hFI3A+7w0aUQuYXQ+6EN5stWmeY/AZqtM8xk9k= github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= -github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -257,8 +258,6 @@ github.com/gostaticanalysis/nilerr v0.1.1/go.mod h1:wZYb6YI5YAxxq0i1+VJbY0s2YONW github.com/gostaticanalysis/testutil v0.3.1-0.20210208050101-bfb5c8eec0e4/go.mod h1:D+FIZ+7OahH3ePw/izIEeH5I06eKs1IKI4Xr64/Am3M= github.com/gostaticanalysis/testutil v0.4.0 h1:nhdCmubdmDF6VEatUNjgUZBJKWRqugoISdUv3PPQgHY= github.com/gostaticanalysis/testutil v0.4.0/go.mod h1:bLIoPefWXrRi/ssLFWX1dx7Repi5x3CuviD3dgAZaBU= -github.com/gxed/go-shellwords v1.0.3 h1:2TP32H4TAklZUdz84oj95BJhVnIrRasyx2j1cqH5K38= -github.com/gxed/go-shellwords v1.0.3/go.mod h1:N7paucT91ByIjmVJHhvoarjoQnmsi3Jd3vH7VqgtMxQ= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -303,9 +302,6 @@ github.com/ipfs/go-ipld-format v0.6.0 h1:VEJlA2kQ3LqFSIm5Vu6eIlSxD/Ze90xtc4Meten github.com/ipfs/go-ipld-format v0.6.0/go.mod h1:g4QVMTn3marU3qXchwjpKPKgJv+zF+OlaKMyhJ4LHPg= github.com/ipfs/go-ipld-legacy v0.2.1 h1:mDFtrBpmU7b//LzLSypVrXsD8QxkEWxu5qVxN99/+tk= github.com/ipfs/go-ipld-legacy v0.2.1/go.mod h1:782MOUghNzMO2DER0FlBR94mllfdCJCkTtDtPM51otM= -github.com/ipfs/go-log v1.0.5 h1:2dOuUCB1Z7uoczMWgAyDck5JLb72zHzrMnGnCNNbvY8= -github.com/ipfs/go-log v1.0.5/go.mod h1:j0b8ZoR+7+R99LD9jZ6+AJsrzkPbSXbZfGakb5JPtIo= -github.com/ipfs/go-log/v2 v2.1.3/go.mod h1:/8d0SH3Su5Ooc31QlL1WysJhvyOTDCjcCZ9Axpmri6g= github.com/ipfs/go-log/v2 v2.5.1 h1:1XdUzF7048prq4aBjDQQ4SL5RxftpRGdXhNRwKSAlcY= github.com/ipfs/go-log/v2 v2.5.1/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOLU9U5UI= github.com/ipfs/go-metrics-interface v0.0.1 h1:j+cpbjYvu4R8zbleSs36gvB7jR+wsL2fGD6n0jO4kdg= @@ -316,10 +312,10 @@ github.com/ipfs/go-test v0.0.4 h1:DKT66T6GBB6PsDFLoO56QZPrOmzJkqU1FZH5C9ySkew= github.com/ipfs/go-test v0.0.4/go.mod h1:qhIM1EluEfElKKM6fnWxGn822/z9knUGM1+I/OAQNKI= github.com/ipfs/hang-fds v0.1.0 h1:deBiFlWHsVGzJ0ZMaqscEqRM1r2O1rFZ59UiQXb1Xko= github.com/ipfs/hang-fds v0.1.0/go.mod h1:29VLWOn3ftAgNNgXg/al7b11UzuQ+w7AwtCGcTaWkbM= -github.com/ipfs/iptb v1.4.0 h1:YFYTrCkLMRwk/35IMyC6+yjoQSHTEcNcefBStLJzgvo= -github.com/ipfs/iptb v1.4.0/go.mod h1:1rzHpCYtNp87/+hTxG5TfCVn/yMY3dKnLn8tBiMfdmg= -github.com/ipfs/iptb-plugins v0.5.0 h1:zEMLlWAb531mLpD36KFy/yc0egT6FkBEHQtdERexNao= -github.com/ipfs/iptb-plugins v0.5.0/go.mod h1:/6crDf3s58T70BhZ+m9SyyKpK7VvSDS2Ny4kafxXDp4= +github.com/ipfs/iptb v1.4.1 h1:faXd3TKGPswbHyZecqqg6UfbES7RDjTKQb+6VFPKDUo= +github.com/ipfs/iptb v1.4.1/go.mod h1:nTsBMtVYFEu0FjC5DgrErnABm3OG9ruXkFXGJoTV5OA= +github.com/ipfs/iptb-plugins v0.5.1 h1:11PNTNEt2+SFxjUcO5qpyCTXqDj6T8Tx9pU/G4ytCIQ= +github.com/ipfs/iptb-plugins v0.5.1/go.mod h1:mscJAjRnu4g16QK6oUBn9RGpcp8ueJmLfmPxIG/At78= github.com/ipld/go-codec-dagpb v1.6.0 h1:9nYazfyu9B1p3NAgfVdpRco3Fs2nFC72DqVsMj6rOcc= github.com/ipld/go-codec-dagpb v1.6.0/go.mod h1:ANzFhfP2uMJxRBr8CE+WQWs5UsNa0pYtmKZ+agnUw9s= github.com/ipld/go-ipld-prime v0.21.0 h1:n4JmcpOlPDIxBcY037SVfpd1G+Sj1nKZah0m6QH9C2E= @@ -439,6 +435,8 @@ github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-shellwords v1.0.12 h1:M2zGm7EW6UQJvDeQxo4T51eKPurbeFbe8WtebGE2xrk= +github.com/mattn/go-shellwords v1.0.12/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= github.com/mgechev/revive v1.3.9 h1:18Y3R4a2USSBF+QZKFQwVkBROUda7uoBlkEuBD+YD1A= github.com/mgechev/revive v1.3.9/go.mod h1:+uxEIr5UH0TjXWHTno3xh4u7eg6jDpXKzQccA9UGhHU= github.com/miekg/dns v1.1.61 h1:nLxbwF3XxhwVSm8g9Dghm9MHPaUZuqhPiGL+675ZmEs= @@ -495,8 +493,6 @@ github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k= github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY= github.com/opencontainers/runtime-spec v1.2.0 h1:z97+pHb3uELt/yiAWD691HNHQIF07bE7dzrbT927iTk= github.com/opencontainers/runtime-spec v1.2.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= -github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/otiai10/copy v1.2.0/go.mod h1:rrF5dJ5F0t/EWSYODDu4j9/vEeYHMkc8jt0zJChqQWw= github.com/otiai10/copy v1.14.0 h1:dCI/t1iTdYGtkvCuBG2BgR6KZa83PTclw4U5n2wAllU= github.com/otiai10/copy v1.14.0/go.mod h1:ECfuL02W+/FkTWZWgQqXPWZgW9oeKCSQ5qVfSc4qc4w= @@ -582,7 +578,6 @@ github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtD github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= -github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= @@ -683,9 +678,9 @@ github.com/ultraware/funlen v0.1.0 h1:BuqclbkY6pO+cvxoq7OsktIXZpgBSkYTQtmwhAK81v github.com/ultraware/funlen v0.1.0/go.mod h1:XJqmOQja6DpxarLj6Jj1U7JuoS8PvL4nEqDaQhy22p4= github.com/ultraware/whitespace v0.1.1 h1:bTPOGejYFulW3PkcrqkeQwOd6NKOOXvmGD9bo/Gk8VQ= github.com/ultraware/whitespace v0.1.1/go.mod h1:XcP1RLD81eV4BW8UhQlpaR+SDc2givTvyI8a586WjW8= -github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= -github.com/urfave/cli v1.22.10 h1:p8Fspmz3iTctJstry1PYS3HVdllxnEzTEsgIgtxTrCk= github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/urfave/cli v1.22.16 h1:MH0k6uJxdwdeWQTwhSO42Pwr4YLrNLwBtg1MRgTqPdQ= +github.com/urfave/cli v1.22.16/go.mod h1:EeJR6BKodywf4zciqrdw6hpCPk68JO9z5LazXZMn5Po= github.com/uudashr/gocognit v1.1.3 h1:l+a111VcDbKfynh+airAy/DJQKaXh2m9vkoysMPSZyM= github.com/uudashr/gocognit v1.1.3/go.mod h1:aKH8/e8xbTRBwjbCkwZ8qt4l2EpKXl31KMHgSS+lZ2U= github.com/warpfork/go-testmark v0.12.1 h1:rMgCpJfwy1sJ50x0M0NgyphxYYPMOODIJHhsXyEHU0s= @@ -729,7 +724,6 @@ go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6b go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s= go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= -go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/automaxprocs v1.5.3 h1:kWazyxZUrS3Gs4qUpbwo5kEIMGe/DAvi5Z4tl2NW4j8= go.uber.org/automaxprocs v1.5.3/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0= @@ -742,17 +736,13 @@ go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= -go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= -go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= @@ -776,7 +766,6 @@ golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvx golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= @@ -905,9 +894,6 @@ golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3 golang.org/x/tools v0.0.0-20190321232350-e250d351ecad/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= @@ -967,7 +953,6 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -984,7 +969,6 @@ gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU= gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.5.1 h1:4bH5o3b5ZULQ4UrBmP+63W9r7qIkqJClEA9ko5YKx+I= honnef.co/go/tools v0.5.1/go.mod h1:e9irvo83WDG9/irijV44wr3tbhcFeRnfpVlRqVwpzMs= lukechampine.com/blake3 v1.3.0 h1:sJ3XhFINmHSrYCgl958hscfIa3bw8x4DqMP3u1YvoYE= diff --git a/test/dependencies/pollEndpoint/main.go b/test/dependencies/pollEndpoint/main.go index 0c548d8c9..fbea6fd77 100644 --- a/test/dependencies/pollEndpoint/main.go +++ b/test/dependencies/pollEndpoint/main.go @@ -10,7 +10,7 @@ import ( "os" "time" - logging "github.com/ipfs/go-log" + logging "github.com/ipfs/go-log/v2" ma "github.com/multiformats/go-multiaddr" manet "github.com/multiformats/go-multiaddr/net" ) From 1fd5ab4c45f564fc28fe44b79e11e97c8bd5b629 Mon Sep 17 00:00:00 2001 From: Andrew Gillis <11790789+gammazero@users.noreply.github.com> Date: Tue, 22 Oct 2024 08:26:02 -1000 Subject: [PATCH 1196/1212] chore: update dependencies (#10548) update dependencies --- docs/changelogs/v0.32.md | 3 + docs/examples/kubo-as-a-library/go.mod | 30 ++++----- docs/examples/kubo-as-a-library/go.sum | 67 ++++++++++---------- go.mod | 36 +++++------ go.sum | 84 ++++++++++++-------------- test/dependencies/go.mod | 6 +- test/dependencies/go.sum | 40 ++++++------ 7 files changed, 133 insertions(+), 133 deletions(-) diff --git a/docs/changelogs/v0.32.md b/docs/changelogs/v0.32.md index 0744bd628..6ae7d1ad7 100644 --- a/docs/changelogs/v0.32.md +++ b/docs/changelogs/v0.32.md @@ -13,6 +13,9 @@ ### 🔦 Highlights + +- update `go-libp2p-kad-dht` to [v0.27.0](https://github.com/libp2p/go-libp2p-kad-dht/releases/tag/v0.27.0) +- update `go-libp2p-pubsub` to [v0.12.0](https://github.com/libp2p/go-libp2p-pubsub/releases/tag/v0.12.0) ### 📝 Changelog ### 👨‍👩‍👧‍👦 Contributors diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 15028beda..2c3054fc1 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -121,9 +121,9 @@ require ( github.com/libp2p/go-doh-resolver v0.4.0 // indirect github.com/libp2p/go-flow-metrics v0.1.0 // indirect github.com/libp2p/go-libp2p-asn-util v0.4.1 // indirect - github.com/libp2p/go-libp2p-kad-dht v0.26.1 // indirect + github.com/libp2p/go-libp2p-kad-dht v0.27.0 // indirect github.com/libp2p/go-libp2p-kbucket v0.6.4 // indirect - github.com/libp2p/go-libp2p-pubsub v0.11.0 // indirect + github.com/libp2p/go-libp2p-pubsub v0.12.0 // indirect github.com/libp2p/go-libp2p-pubsub-router v0.6.0 // indirect github.com/libp2p/go-libp2p-record v0.2.0 // indirect github.com/libp2p/go-libp2p-routing-helpers v0.7.4 // indirect @@ -136,7 +136,7 @@ require ( github.com/libp2p/zeroconf/v2 v2.2.0 // indirect github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/miekg/dns v1.1.61 // indirect + github.com/miekg/dns v1.1.62 // indirect github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect github.com/minio/sha256-simd v1.0.1 // indirect @@ -152,7 +152,7 @@ require ( github.com/multiformats/go-multistream v0.5.0 // indirect github.com/multiformats/go-varint v0.0.7 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/onsi/ginkgo/v2 v2.19.1 // indirect + github.com/onsi/ginkgo/v2 v2.20.0 // indirect github.com/opencontainers/runtime-spec v1.2.0 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/openzipkin/zipkin-go v0.4.3 // indirect @@ -161,13 +161,13 @@ require ( github.com/pion/datachannel v1.5.8 // indirect github.com/pion/dtls/v2 v2.2.12 // indirect github.com/pion/ice/v2 v2.3.34 // indirect - github.com/pion/interceptor v0.1.29 // indirect + github.com/pion/interceptor v0.1.30 // indirect github.com/pion/logging v0.2.2 // indirect github.com/pion/mdns v0.0.12 // indirect github.com/pion/randutil v0.1.0 // indirect github.com/pion/rtcp v1.2.14 // indirect - github.com/pion/rtp v1.8.8 // indirect - github.com/pion/sctp v1.8.20 // indirect + github.com/pion/rtp v1.8.9 // indirect + github.com/pion/sctp v1.8.33 // indirect github.com/pion/sdp/v3 v3.0.9 // indirect github.com/pion/srtp/v2 v2.0.20 // indirect github.com/pion/stun v0.6.1 // indirect @@ -182,7 +182,7 @@ require ( github.com/prometheus/common v0.55.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/quic-go/qpack v0.4.0 // indirect - github.com/quic-go/quic-go v0.45.2 // indirect + github.com/quic-go/quic-go v0.46.0 // indirect github.com/quic-go/webtransport-go v0.8.0 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect @@ -197,7 +197,7 @@ require ( github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f // indirect github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 // indirect - github.com/wlynxg/anet v0.0.3 // indirect + github.com/wlynxg/anet v0.0.4 // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.52.0 // indirect go.opentelemetry.io/otel v1.28.0 // indirect @@ -211,20 +211,20 @@ require ( go.opentelemetry.io/otel/trace v1.28.0 // indirect go.opentelemetry.io/proto/otlp v1.3.1 // indirect go.uber.org/atomic v1.11.0 // indirect - go.uber.org/dig v1.17.1 // indirect - go.uber.org/fx v1.22.1 // indirect + go.uber.org/dig v1.18.0 // indirect + go.uber.org/fx v1.22.2 // indirect go.uber.org/mock v0.4.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect go4.org v0.0.0-20230225012048-214862532bf5 // indirect golang.org/x/crypto v0.27.0 // indirect - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect - golang.org/x/mod v0.19.0 // indirect - golang.org/x/net v0.27.0 // indirect + golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect + golang.org/x/mod v0.20.0 // indirect + golang.org/x/net v0.28.0 // indirect golang.org/x/sync v0.8.0 // indirect golang.org/x/sys v0.25.0 // indirect golang.org/x/text v0.18.0 // indirect - golang.org/x/tools v0.23.0 // indirect + golang.org/x/tools v0.24.0 // indirect golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect gonum.org/v1/gonum v0.15.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240617180043-68d350f18fd4 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 55d6838da..291ab74d4 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -453,14 +453,14 @@ github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl9 github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= github.com/libp2p/go-libp2p-core v0.3.0/go.mod h1:ACp3DmS3/N64c2jDzcV429ukDpicbL6+TrrxANBjPGw= -github.com/libp2p/go-libp2p-kad-dht v0.26.1 h1:AazV3LCImYVkDUGAHx5lIEgZ9iUI2QQKH5GMRQU8uEA= -github.com/libp2p/go-libp2p-kad-dht v0.26.1/go.mod h1:mqRUGJ/+7ziQ3XknU2kKHfsbbgb9xL65DXjPOJwmZF8= +github.com/libp2p/go-libp2p-kad-dht v0.27.0 h1:1Ea32tVTPiAfaLpPMbaBWFJgbsi/JpMqC2YBuFdf32o= +github.com/libp2p/go-libp2p-kad-dht v0.27.0/go.mod h1:ixhjLuzaXSGtWsKsXTj7erySNuVC4UP7NO015cRrF14= github.com/libp2p/go-libp2p-kbucket v0.3.1/go.mod h1:oyjT5O7tS9CQurok++ERgc46YLwEpuGoFq9ubvoUOio= github.com/libp2p/go-libp2p-kbucket v0.6.4 h1:OjfiYxU42TKQSB8t8WYd8MKhYhMJeO2If+NiuKfb6iQ= github.com/libp2p/go-libp2p-kbucket v0.6.4/go.mod h1:jp6w82sczYaBsAypt5ayACcRJi0lgsba7o4TzJKEfWA= github.com/libp2p/go-libp2p-peerstore v0.1.4/go.mod h1:+4BDbDiiKf4PzpANZDAT+knVdLxvqh7hXOujessqdzs= -github.com/libp2p/go-libp2p-pubsub v0.11.0 h1:+JvS8Kty0OiyUiN0i8H5JbaCgjnJTRnTHe4rU88dLFc= -github.com/libp2p/go-libp2p-pubsub v0.11.0/go.mod h1:QEb+hEV9WL9wCiUAnpY29FZR6W3zK8qYlaml8R4q6gQ= +github.com/libp2p/go-libp2p-pubsub v0.12.0 h1:PENNZjSfk8KYxANRlpipdS7+BfLmOl3L2E/6vSNjbdI= +github.com/libp2p/go-libp2p-pubsub v0.12.0/go.mod h1:Oi0zw9aw8/Y5GC99zt+Ef2gYAl+0nZlwdJonDyOz/sE= github.com/libp2p/go-libp2p-pubsub-router v0.6.0 h1:D30iKdlqDt5ZmLEYhHELCMRj8b4sFAqrUcshIUvVP/s= github.com/libp2p/go-libp2p-pubsub-router v0.6.0/go.mod h1:FY/q0/RBTKsLA7l4vqC2cbRbOvyDotg8PJQ7j8FDudE= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= @@ -505,8 +505,8 @@ github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyex github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= -github.com/miekg/dns v1.1.61 h1:nLxbwF3XxhwVSm8g9Dghm9MHPaUZuqhPiGL+675ZmEs= -github.com/miekg/dns v1.1.61/go.mod h1:mnAarhS3nWaW+NVP2wTkYVIZyHNJ098SJZUki3eykwQ= +github.com/miekg/dns v1.1.62 h1:cN8OuEF1/x5Rq6Np+h1epln8OiyPWV+lROx9LxcGgIQ= +github.com/miekg/dns v1.1.62/go.mod h1:mvDlcItzm+br7MToIKqkglaGhlFMHJ9DTNNWONWXbNQ= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c h1:bzE/A84HN25pxAuk9Eej1Kz9OUelF97nAc82bDquQI8= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c/go.mod h1:0SQS9kMwD2VsyFEB++InYyBJroV/FRmBgcydeSUcJms= github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= @@ -583,13 +583,13 @@ github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108 github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.19.1 h1:QXgq3Z8Crl5EL1WBAC98A5sEBHARrAJNzAmMxzLcRF0= -github.com/onsi/ginkgo/v2 v2.19.1/go.mod h1:O3DtEWQkPa/F7fBMgmZQKKsluAy8pd3rEQdrjkPb9zA= +github.com/onsi/ginkgo/v2 v2.20.0 h1:PE84V2mHqoT1sglvHc8ZdQtPcwmvvt29WLEEO3xmdZw= +github.com/onsi/ginkgo/v2 v2.20.0/go.mod h1:lG9ey2Z29hR41WMVthyJBGUBcBhGOtoPF2VFMvBXFCI= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.34.0 h1:eSSPsPNp6ZpsG8X1OVmOTxig+CblTc4AxpPBykhe2Os= -github.com/onsi/gomega v1.34.0/go.mod h1:MIKI8c+f+QLWk+hxbePD4i0LMJSExPaZOVfkoex4cAo= +github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k= +github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.2.0 h1:z97+pHb3uELt/yiAWD691HNHQIF07bE7dzrbT927iTk= github.com/opencontainers/runtime-spec v1.2.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= @@ -614,8 +614,8 @@ github.com/pion/dtls/v2 v2.2.12 h1:KP7H5/c1EiVAAKUmXyCzPiQe5+bCJrpOeKg/L05dunk= github.com/pion/dtls/v2 v2.2.12/go.mod h1:d9SYc9fch0CqK90mRk1dC7AkzzpwJj6u2GU3u+9pqFE= github.com/pion/ice/v2 v2.3.34 h1:Ic1ppYCj4tUOcPAp76U6F3fVrlSw8A9JtRXLqw6BbUM= github.com/pion/ice/v2 v2.3.34/go.mod h1:mBF7lnigdqgtB+YHkaY/Y6s6tsyRyo4u4rPGRuOjUBQ= -github.com/pion/interceptor v0.1.29 h1:39fsnlP1U8gw2JzOFWdfCU82vHvhW9o0rZnZF56wF+M= -github.com/pion/interceptor v0.1.29/go.mod h1:ri+LGNjRUc5xUNtDEPzfdkmSqISixVTBF/z/Zms/6T4= +github.com/pion/interceptor v0.1.30 h1:au5rlVHsgmxNi+v/mjOPazbW1SHzfx7/hYOEYQnUcxA= +github.com/pion/interceptor v0.1.30/go.mod h1:RQuKT5HTdkP2Fi0cuOS5G5WNymTjzXaGF75J4k7z2nc= github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY= github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms= github.com/pion/mdns v0.0.12 h1:CiMYlY+O0azojWDmxdNr7ADGrnZ+V6Ilfner+6mSVK8= @@ -626,10 +626,10 @@ github.com/pion/rtcp v1.2.12/go.mod h1:sn6qjxvnwyAkkPzPULIbVqSKI5Dv54Rv7VG0kNxh9 github.com/pion/rtcp v1.2.14 h1:KCkGV3vJ+4DAJmvP0vaQShsb0xkRfWkO540Gy102KyE= github.com/pion/rtcp v1.2.14/go.mod h1:sn6qjxvnwyAkkPzPULIbVqSKI5Dv54Rv7VG0kNxh9L4= github.com/pion/rtp v1.8.3/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU= -github.com/pion/rtp v1.8.8 h1:EtYFHI0rpUEjT/RMnGfb1vdJhbYmPG77szD72uUnSxs= -github.com/pion/rtp v1.8.8/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU= -github.com/pion/sctp v1.8.20 h1:sOc3lkV/tQaP57ZUEXIMdM2V92IIB2ia5v/ygnBxaEg= -github.com/pion/sctp v1.8.20/go.mod h1:oTxw8i5m+WbDHZJL/xUpe6CPIn1Y0GIKKwTLF4h53H8= +github.com/pion/rtp v1.8.9 h1:E2HX740TZKaqdcPmf4pw6ZZuG8u5RlMMt+l3dxeu6Wk= +github.com/pion/rtp v1.8.9/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU= +github.com/pion/sctp v1.8.33 h1:dSE4wX6uTJBcNm8+YlMg7lw1wqyKHggsP5uKbdj+NZw= +github.com/pion/sctp v1.8.33/go.mod h1:beTnqSzewI53KWoG3nqB282oDMGrhNxBdb+JZnkCwRM= github.com/pion/sdp/v3 v3.0.9 h1:pX++dCHoHUwq43kuwf3PyJfHlwIj4hXA7Vrifiq0IJY= github.com/pion/sdp/v3 v3.0.9/go.mod h1:B5xmvENq5IXJimIO4zfp6LAe1fD9N+kFv+V/1lOdz8M= github.com/pion/srtp/v2 v2.0.20 h1:HNNny4s+OUmG280ETrCdgFndp4ufx3/uy85EawYEhTk= @@ -642,8 +642,8 @@ github.com/pion/transport/v2 v2.2.4/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLh github.com/pion/transport/v2 v2.2.10 h1:ucLBLE8nuxiHfvkFKnkDQRYWYfp8ejf4YBOPfaQpw6Q= github.com/pion/transport/v2 v2.2.10/go.mod h1:sq1kSLWs+cHW9E+2fJP95QudkzbK7wscs8yYgQToO5E= github.com/pion/transport/v3 v3.0.1/go.mod h1:UY7kiITrlMv7/IKgd5eTUcaahZx5oUN3l9SzK5f5xE0= -github.com/pion/transport/v3 v3.0.6 h1:k1mQU06bmmX143qSWgXFqSH1KUJceQvIUuVH/K5ELWw= -github.com/pion/transport/v3 v3.0.6/go.mod h1:HvJr2N/JwNJAfipsRleqwFoR3t/pWyHeZUs89v3+t5s= +github.com/pion/transport/v3 v3.0.7 h1:iRbMH05BzSNwhILHoBoAPxoB9xQgOaJk+591KC9P1o0= +github.com/pion/transport/v3 v3.0.7/go.mod h1:YleKiTZ4vqNxVwh77Z0zytYi7rXHl7j6uPLGhhz9rwo= github.com/pion/turn/v2 v2.1.3/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY= github.com/pion/turn/v2 v2.1.6 h1:Xr2niVsiPTB0FPtt+yAWKFUkU1eotQbGgpTIld4x1Gc= github.com/pion/turn/v2 v2.1.6/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY= @@ -673,8 +673,8 @@ github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0leargg github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= -github.com/quic-go/quic-go v0.45.2 h1:DfqBmqjb4ExSdxRIb/+qXhPC+7k6+DUNZha4oeiC9fY= -github.com/quic-go/quic-go v0.45.2/go.mod h1:1dLehS7TIR64+vxGR70GDcatWTOtMX2PUtnKsjbTurI= +github.com/quic-go/quic-go v0.46.0 h1:uuwLClEEyk1DNvchH8uCByQVjo3yKL9opKulExNDs7Y= +github.com/quic-go/quic-go v0.46.0/go.mod h1:1dLehS7TIR64+vxGR70GDcatWTOtMX2PUtnKsjbTurI= github.com/quic-go/webtransport-go v0.8.0 h1:HxSrwun11U+LlmwpgM1kEqIqH90IT4N8auv/cD7QFJg= github.com/quic-go/webtransport-go v0.8.0/go.mod h1:N99tjprW432Ut5ONql/aUhSLT0YVSlwHohQsuac9WaM= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= @@ -788,8 +788,9 @@ github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 h1:E9S12nwJwEOXe2d6gT6qxdvqMnNq+VnSsKPgm2ZZNds= github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7/go.mod h1:X2c0RVCI1eSUFI8eLcY3c0423ykwiUdxLJtkDvruhjI= -github.com/wlynxg/anet v0.0.3 h1:PvR53psxFXstc12jelG6f1Lv4MWqE0tI76/hHGjh9rg= github.com/wlynxg/anet v0.0.3/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA= +github.com/wlynxg/anet v0.0.4 h1:0de1OFQxnNqAu+x2FAKKCVIrnfGKQbs7FQz++tB0+Uw= +github.com/wlynxg/anet v0.0.4/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA= github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -831,10 +832,10 @@ go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= -go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= -go.uber.org/fx v1.22.1 h1:nvvln7mwyT5s1q201YE29V/BFrGor6vMiDNpU/78Mys= -go.uber.org/fx v1.22.1/go.mod h1:HT2M7d7RHo+ebKGh9NRcrsrHHfpZ60nW3QRubMRfv48= +go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw= +go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= +go.uber.org/fx v1.22.2 h1:iPW+OPxv0G8w75OemJ1RAnTUrF55zOJlXlo1TbJ0Buw= +go.uber.org/fx v1.22.2/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= @@ -886,8 +887,8 @@ golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa h1:ELnwvuAXPNtPk1TJRuGkI9fDTwym6AYBu0qzT8AcHdI= +golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -911,8 +912,8 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= -golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -948,8 +949,8 @@ golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1088,8 +1089,8 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= -golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/go.mod b/go.mod index 700e62d50..0231b8658 100644 --- a/go.mod +++ b/go.mod @@ -15,10 +15,10 @@ require ( github.com/dustin/go-humanize v1.0.1 github.com/elgris/jsondiff v0.0.0-20160530203242-765b5c24c302 github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5 - github.com/fsnotify/fsnotify v1.6.0 + github.com/fsnotify/fsnotify v1.7.0 github.com/google/uuid v1.6.0 github.com/hashicorp/go-multierror v1.1.1 - github.com/hashicorp/go-version v1.6.0 + github.com/hashicorp/go-version v1.7.0 github.com/ipfs-shipyard/nopfs v0.0.12 github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c github.com/ipfs/boxo v0.24.0 @@ -41,7 +41,7 @@ require ( github.com/ipfs/go-log v1.0.5 github.com/ipfs/go-log/v2 v2.5.1 github.com/ipfs/go-metrics-interface v0.0.1 - github.com/ipfs/go-metrics-prometheus v0.0.2 + github.com/ipfs/go-metrics-prometheus v0.0.3 github.com/ipfs/go-test v0.0.4 github.com/ipfs/go-unixfsnode v1.9.2 github.com/ipld/go-car v0.6.2 @@ -54,9 +54,9 @@ require ( github.com/libp2p/go-doh-resolver v0.4.0 github.com/libp2p/go-libp2p v0.36.5 github.com/libp2p/go-libp2p-http v0.5.0 - github.com/libp2p/go-libp2p-kad-dht v0.26.1 + github.com/libp2p/go-libp2p-kad-dht v0.27.0 github.com/libp2p/go-libp2p-kbucket v0.6.4 - github.com/libp2p/go-libp2p-pubsub v0.11.0 + github.com/libp2p/go-libp2p-pubsub v0.12.0 github.com/libp2p/go-libp2p-pubsub-router v0.6.0 github.com/libp2p/go-libp2p-record v0.2.0 github.com/libp2p/go-libp2p-routing-helpers v0.7.4 @@ -83,13 +83,13 @@ require ( go.opentelemetry.io/otel v1.28.0 go.opentelemetry.io/otel/sdk v1.27.0 go.opentelemetry.io/otel/trace v1.28.0 - go.uber.org/dig v1.17.1 - go.uber.org/fx v1.22.1 + go.uber.org/dig v1.18.0 + go.uber.org/fx v1.22.2 go.uber.org/multierr v1.11.0 go.uber.org/zap v1.27.0 golang.org/x/crypto v0.27.0 - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 - golang.org/x/mod v0.19.0 + golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa + golang.org/x/mod v0.20.0 golang.org/x/sync v0.8.0 golang.org/x/sys v0.25.0 google.golang.org/protobuf v1.34.2 @@ -179,7 +179,7 @@ require ( github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-runewidth v0.0.4 // indirect github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect - github.com/miekg/dns v1.1.61 // indirect + github.com/miekg/dns v1.1.62 // indirect github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect github.com/minio/sha256-simd v1.0.1 // indirect @@ -190,20 +190,20 @@ require ( github.com/multiformats/go-multistream v0.5.0 // indirect github.com/multiformats/go-varint v0.0.7 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/onsi/ginkgo/v2 v2.19.1 // indirect + github.com/onsi/ginkgo/v2 v2.20.0 // indirect github.com/opencontainers/runtime-spec v1.2.0 // indirect github.com/openzipkin/zipkin-go v0.4.3 // indirect github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 // indirect github.com/pion/datachannel v1.5.8 // indirect github.com/pion/dtls/v2 v2.2.12 // indirect github.com/pion/ice/v2 v2.3.34 // indirect - github.com/pion/interceptor v0.1.29 // indirect + github.com/pion/interceptor v0.1.30 // indirect github.com/pion/logging v0.2.2 // indirect github.com/pion/mdns v0.0.12 // indirect github.com/pion/randutil v0.1.0 // indirect github.com/pion/rtcp v1.2.14 // indirect - github.com/pion/rtp v1.8.8 // indirect - github.com/pion/sctp v1.8.20 // indirect + github.com/pion/rtp v1.8.9 // indirect + github.com/pion/sctp v1.8.33 // indirect github.com/pion/sdp/v3 v3.0.9 // indirect github.com/pion/srtp/v2 v2.0.20 // indirect github.com/pion/stun v0.6.1 // indirect @@ -218,7 +218,7 @@ require ( github.com/prometheus/procfs v0.15.1 // indirect github.com/prometheus/statsd_exporter v0.22.7 // indirect github.com/quic-go/qpack v0.4.0 // indirect - github.com/quic-go/quic-go v0.45.2 // indirect + github.com/quic-go/quic-go v0.46.0 // indirect github.com/quic-go/webtransport-go v0.8.0 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect @@ -234,7 +234,7 @@ require ( github.com/whyrusleeping/cbor-gen v0.1.2 // indirect github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f // indirect github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect - github.com/wlynxg/anet v0.0.3 // indirect + github.com/wlynxg/anet v0.0.4 // indirect go.opentelemetry.io/contrib/propagators/aws v1.21.1 // indirect go.opentelemetry.io/contrib/propagators/b3 v1.21.1 // indirect go.opentelemetry.io/contrib/propagators/jaeger v1.21.1 // indirect @@ -249,11 +249,11 @@ require ( go.uber.org/atomic v1.11.0 // indirect go.uber.org/mock v0.4.0 // indirect go4.org v0.0.0-20230225012048-214862532bf5 // indirect - golang.org/x/net v0.27.0 // indirect + golang.org/x/net v0.28.0 // indirect golang.org/x/oauth2 v0.21.0 // indirect golang.org/x/term v0.24.0 // indirect golang.org/x/text v0.18.0 // indirect - golang.org/x/tools v0.23.0 // indirect + golang.org/x/tools v0.24.0 // indirect golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect gonum.org/v1/gonum v0.15.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240617180043-68d350f18fd4 // indirect diff --git a/go.sum b/go.sum index 5031c5833..9087b8647 100644 --- a/go.sum +++ b/go.sum @@ -189,8 +189,8 @@ github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHk github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= -github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= +github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/gabriel-vasile/mimetype v1.4.4 h1:QjV6pZ7/XZ7ryI2KuyeEDE8wnh7fHP9YnQy+R0LnH8I= github.com/gabriel-vasile/mimetype v1.4.4/go.mod h1:JwLei5XPtWdGiMFB5Pjle1oEeoSeEuJfJE+TtfvdB/s= github.com/getsentry/sentry-go v0.27.0 h1:Pv98CIbtB3LkMWmXi4Joa5OOcwbmnX88sF5qbK3r3Ps= @@ -330,8 +330,8 @@ github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= -github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= -github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= +github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c= @@ -436,8 +436,8 @@ github.com/ipfs/go-merkledag v0.11.0 h1:DgzwK5hprESOzS4O1t/wi6JDpyVQdvm9Bs59N/jq github.com/ipfs/go-merkledag v0.11.0/go.mod h1:Q4f/1ezvBiJV0YCIXvt51W/9/kqJGH4I1LsA7+djsM4= github.com/ipfs/go-metrics-interface v0.0.1 h1:j+cpbjYvu4R8zbleSs36gvB7jR+wsL2fGD6n0jO4kdg= github.com/ipfs/go-metrics-interface v0.0.1/go.mod h1:6s6euYU4zowdslK0GKHmqaIZ3j/b/tL7HTWtJ4VPgWY= -github.com/ipfs/go-metrics-prometheus v0.0.2 h1:9i2iljLg12S78OhC6UAiXi176xvQGiZaGVF1CUVdE+s= -github.com/ipfs/go-metrics-prometheus v0.0.2/go.mod h1:ELLU99AQQNi+zX6GCGm2lAgnzdSH3u5UVlCdqSXnEks= +github.com/ipfs/go-metrics-prometheus v0.0.3 h1:MVgBw30nE9eKC598ZQg+LIIbgIcx46NG8KISWLCLkMo= +github.com/ipfs/go-metrics-prometheus v0.0.3/go.mod h1:qjWVLyK+ZJrQuiyTqfgoECgKfd4b4lEtpQemAWomWc8= github.com/ipfs/go-peertaskqueue v0.8.1 h1:YhxAs1+wxb5jk7RvS0LHdyiILpNmRIRnZVztekOF0pg= github.com/ipfs/go-peertaskqueue v0.8.1/go.mod h1:Oxxd3eaK279FxeydSPPVGHzbwVeHjatZ2GA8XD+KbPU= github.com/ipfs/go-test v0.0.4 h1:DKT66T6GBB6PsDFLoO56QZPrOmzJkqU1FZH5C9ySkew= @@ -536,14 +536,14 @@ github.com/libp2p/go-libp2p-gostream v0.6.0 h1:QfAiWeQRce6pqnYfmIVWJFXNdDyfiR/qk github.com/libp2p/go-libp2p-gostream v0.6.0/go.mod h1:Nywu0gYZwfj7Jc91PQvbGU8dIpqbQQkjWgDuOrFaRdA= github.com/libp2p/go-libp2p-http v0.5.0 h1:+x0AbLaUuLBArHubbbNRTsgWz0RjNTy6DJLOxQ3/QBc= github.com/libp2p/go-libp2p-http v0.5.0/go.mod h1:glh87nZ35XCQyFsdzZps6+F4HYI6DctVFY5u1fehwSg= -github.com/libp2p/go-libp2p-kad-dht v0.26.1 h1:AazV3LCImYVkDUGAHx5lIEgZ9iUI2QQKH5GMRQU8uEA= -github.com/libp2p/go-libp2p-kad-dht v0.26.1/go.mod h1:mqRUGJ/+7ziQ3XknU2kKHfsbbgb9xL65DXjPOJwmZF8= +github.com/libp2p/go-libp2p-kad-dht v0.27.0 h1:1Ea32tVTPiAfaLpPMbaBWFJgbsi/JpMqC2YBuFdf32o= +github.com/libp2p/go-libp2p-kad-dht v0.27.0/go.mod h1:ixhjLuzaXSGtWsKsXTj7erySNuVC4UP7NO015cRrF14= github.com/libp2p/go-libp2p-kbucket v0.3.1/go.mod h1:oyjT5O7tS9CQurok++ERgc46YLwEpuGoFq9ubvoUOio= github.com/libp2p/go-libp2p-kbucket v0.6.4 h1:OjfiYxU42TKQSB8t8WYd8MKhYhMJeO2If+NiuKfb6iQ= github.com/libp2p/go-libp2p-kbucket v0.6.4/go.mod h1:jp6w82sczYaBsAypt5ayACcRJi0lgsba7o4TzJKEfWA= github.com/libp2p/go-libp2p-peerstore v0.1.4/go.mod h1:+4BDbDiiKf4PzpANZDAT+knVdLxvqh7hXOujessqdzs= -github.com/libp2p/go-libp2p-pubsub v0.11.0 h1:+JvS8Kty0OiyUiN0i8H5JbaCgjnJTRnTHe4rU88dLFc= -github.com/libp2p/go-libp2p-pubsub v0.11.0/go.mod h1:QEb+hEV9WL9wCiUAnpY29FZR6W3zK8qYlaml8R4q6gQ= +github.com/libp2p/go-libp2p-pubsub v0.12.0 h1:PENNZjSfk8KYxANRlpipdS7+BfLmOl3L2E/6vSNjbdI= +github.com/libp2p/go-libp2p-pubsub v0.12.0/go.mod h1:Oi0zw9aw8/Y5GC99zt+Ef2gYAl+0nZlwdJonDyOz/sE= github.com/libp2p/go-libp2p-pubsub-router v0.6.0 h1:D30iKdlqDt5ZmLEYhHELCMRj8b4sFAqrUcshIUvVP/s= github.com/libp2p/go-libp2p-pubsub-router v0.6.0/go.mod h1:FY/q0/RBTKsLA7l4vqC2cbRbOvyDotg8PJQ7j8FDudE= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= @@ -599,8 +599,8 @@ github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyex github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= -github.com/miekg/dns v1.1.61 h1:nLxbwF3XxhwVSm8g9Dghm9MHPaUZuqhPiGL+675ZmEs= -github.com/miekg/dns v1.1.61/go.mod h1:mnAarhS3nWaW+NVP2wTkYVIZyHNJ098SJZUki3eykwQ= +github.com/miekg/dns v1.1.62 h1:cN8OuEF1/x5Rq6Np+h1epln8OiyPWV+lROx9LxcGgIQ= +github.com/miekg/dns v1.1.62/go.mod h1:mvDlcItzm+br7MToIKqkglaGhlFMHJ9DTNNWONWXbNQ= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c h1:bzE/A84HN25pxAuk9Eej1Kz9OUelF97nAc82bDquQI8= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c/go.mod h1:0SQS9kMwD2VsyFEB++InYyBJroV/FRmBgcydeSUcJms= github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= @@ -683,13 +683,13 @@ github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108 github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.19.1 h1:QXgq3Z8Crl5EL1WBAC98A5sEBHARrAJNzAmMxzLcRF0= -github.com/onsi/ginkgo/v2 v2.19.1/go.mod h1:O3DtEWQkPa/F7fBMgmZQKKsluAy8pd3rEQdrjkPb9zA= +github.com/onsi/ginkgo/v2 v2.20.0 h1:PE84V2mHqoT1sglvHc8ZdQtPcwmvvt29WLEEO3xmdZw= +github.com/onsi/ginkgo/v2 v2.20.0/go.mod h1:lG9ey2Z29hR41WMVthyJBGUBcBhGOtoPF2VFMvBXFCI= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.34.0 h1:eSSPsPNp6ZpsG8X1OVmOTxig+CblTc4AxpPBykhe2Os= -github.com/onsi/gomega v1.34.0/go.mod h1:MIKI8c+f+QLWk+hxbePD4i0LMJSExPaZOVfkoex4cAo= +github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k= +github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.2.0 h1:z97+pHb3uELt/yiAWD691HNHQIF07bE7dzrbT927iTk= github.com/opencontainers/runtime-spec v1.2.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= @@ -714,8 +714,8 @@ github.com/pion/dtls/v2 v2.2.12 h1:KP7H5/c1EiVAAKUmXyCzPiQe5+bCJrpOeKg/L05dunk= github.com/pion/dtls/v2 v2.2.12/go.mod h1:d9SYc9fch0CqK90mRk1dC7AkzzpwJj6u2GU3u+9pqFE= github.com/pion/ice/v2 v2.3.34 h1:Ic1ppYCj4tUOcPAp76U6F3fVrlSw8A9JtRXLqw6BbUM= github.com/pion/ice/v2 v2.3.34/go.mod h1:mBF7lnigdqgtB+YHkaY/Y6s6tsyRyo4u4rPGRuOjUBQ= -github.com/pion/interceptor v0.1.29 h1:39fsnlP1U8gw2JzOFWdfCU82vHvhW9o0rZnZF56wF+M= -github.com/pion/interceptor v0.1.29/go.mod h1:ri+LGNjRUc5xUNtDEPzfdkmSqISixVTBF/z/Zms/6T4= +github.com/pion/interceptor v0.1.30 h1:au5rlVHsgmxNi+v/mjOPazbW1SHzfx7/hYOEYQnUcxA= +github.com/pion/interceptor v0.1.30/go.mod h1:RQuKT5HTdkP2Fi0cuOS5G5WNymTjzXaGF75J4k7z2nc= github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY= github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms= github.com/pion/mdns v0.0.12 h1:CiMYlY+O0azojWDmxdNr7ADGrnZ+V6Ilfner+6mSVK8= @@ -726,10 +726,10 @@ github.com/pion/rtcp v1.2.12/go.mod h1:sn6qjxvnwyAkkPzPULIbVqSKI5Dv54Rv7VG0kNxh9 github.com/pion/rtcp v1.2.14 h1:KCkGV3vJ+4DAJmvP0vaQShsb0xkRfWkO540Gy102KyE= github.com/pion/rtcp v1.2.14/go.mod h1:sn6qjxvnwyAkkPzPULIbVqSKI5Dv54Rv7VG0kNxh9L4= github.com/pion/rtp v1.8.3/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU= -github.com/pion/rtp v1.8.8 h1:EtYFHI0rpUEjT/RMnGfb1vdJhbYmPG77szD72uUnSxs= -github.com/pion/rtp v1.8.8/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU= -github.com/pion/sctp v1.8.20 h1:sOc3lkV/tQaP57ZUEXIMdM2V92IIB2ia5v/ygnBxaEg= -github.com/pion/sctp v1.8.20/go.mod h1:oTxw8i5m+WbDHZJL/xUpe6CPIn1Y0GIKKwTLF4h53H8= +github.com/pion/rtp v1.8.9 h1:E2HX740TZKaqdcPmf4pw6ZZuG8u5RlMMt+l3dxeu6Wk= +github.com/pion/rtp v1.8.9/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU= +github.com/pion/sctp v1.8.33 h1:dSE4wX6uTJBcNm8+YlMg7lw1wqyKHggsP5uKbdj+NZw= +github.com/pion/sctp v1.8.33/go.mod h1:beTnqSzewI53KWoG3nqB282oDMGrhNxBdb+JZnkCwRM= github.com/pion/sdp/v3 v3.0.9 h1:pX++dCHoHUwq43kuwf3PyJfHlwIj4hXA7Vrifiq0IJY= github.com/pion/sdp/v3 v3.0.9/go.mod h1:B5xmvENq5IXJimIO4zfp6LAe1fD9N+kFv+V/1lOdz8M= github.com/pion/srtp/v2 v2.0.20 h1:HNNny4s+OUmG280ETrCdgFndp4ufx3/uy85EawYEhTk= @@ -742,8 +742,8 @@ github.com/pion/transport/v2 v2.2.4/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLh github.com/pion/transport/v2 v2.2.10 h1:ucLBLE8nuxiHfvkFKnkDQRYWYfp8ejf4YBOPfaQpw6Q= github.com/pion/transport/v2 v2.2.10/go.mod h1:sq1kSLWs+cHW9E+2fJP95QudkzbK7wscs8yYgQToO5E= github.com/pion/transport/v3 v3.0.1/go.mod h1:UY7kiITrlMv7/IKgd5eTUcaahZx5oUN3l9SzK5f5xE0= -github.com/pion/transport/v3 v3.0.6 h1:k1mQU06bmmX143qSWgXFqSH1KUJceQvIUuVH/K5ELWw= -github.com/pion/transport/v3 v3.0.6/go.mod h1:HvJr2N/JwNJAfipsRleqwFoR3t/pWyHeZUs89v3+t5s= +github.com/pion/transport/v3 v3.0.7 h1:iRbMH05BzSNwhILHoBoAPxoB9xQgOaJk+591KC9P1o0= +github.com/pion/transport/v3 v3.0.7/go.mod h1:YleKiTZ4vqNxVwh77Z0zytYi7rXHl7j6uPLGhhz9rwo= github.com/pion/turn/v2 v2.1.3/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY= github.com/pion/turn/v2 v2.1.6 h1:Xr2niVsiPTB0FPtt+yAWKFUkU1eotQbGgpTIld4x1Gc= github.com/pion/turn/v2 v2.1.6/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY= @@ -761,7 +761,6 @@ github.com/polydawn/refmt v0.89.0 h1:ADJTApkvkeBZsN0tBTx8QjpD9JkmxbKp0cxfr9qszm4 github.com/polydawn/refmt v0.89.0/go.mod h1:/zvteZs/GwLtCgZ4BL6CBsk9IKIlexP43ObX9AxTqTw= github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= @@ -777,7 +776,6 @@ github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6T github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= @@ -788,7 +786,6 @@ github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= @@ -800,8 +797,8 @@ github.com/prometheus/statsd_exporter v0.22.7 h1:7Pji/i2GuhK6Lu7DHrtTkFmNBCudCPT github.com/prometheus/statsd_exporter v0.22.7/go.mod h1:N/TevpjkIh9ccs6nuzY3jQn9dFqnUakOjnEuMPJJJnI= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= -github.com/quic-go/quic-go v0.45.2 h1:DfqBmqjb4ExSdxRIb/+qXhPC+7k6+DUNZha4oeiC9fY= -github.com/quic-go/quic-go v0.45.2/go.mod h1:1dLehS7TIR64+vxGR70GDcatWTOtMX2PUtnKsjbTurI= +github.com/quic-go/quic-go v0.46.0 h1:uuwLClEEyk1DNvchH8uCByQVjo3yKL9opKulExNDs7Y= +github.com/quic-go/quic-go v0.46.0/go.mod h1:1dLehS7TIR64+vxGR70GDcatWTOtMX2PUtnKsjbTurI= github.com/quic-go/webtransport-go v0.8.0 h1:HxSrwun11U+LlmwpgM1kEqIqH90IT4N8auv/cD7QFJg= github.com/quic-go/webtransport-go v0.8.0/go.mod h1:N99tjprW432Ut5ONql/aUhSLT0YVSlwHohQsuac9WaM= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= @@ -934,8 +931,9 @@ github.com/whyrusleeping/go-sysinfo v0.0.0-20190219211824-4a357d4b90b1 h1:ctS9An github.com/whyrusleeping/go-sysinfo v0.0.0-20190219211824-4a357d4b90b1/go.mod h1:tKH72zYNt/exx6/5IQO6L9LoQ0rEjd5SbbWaDTs9Zso= github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 h1:E9S12nwJwEOXe2d6gT6qxdvqMnNq+VnSsKPgm2ZZNds= github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7/go.mod h1:X2c0RVCI1eSUFI8eLcY3c0423ykwiUdxLJtkDvruhjI= -github.com/wlynxg/anet v0.0.3 h1:PvR53psxFXstc12jelG6f1Lv4MWqE0tI76/hHGjh9rg= github.com/wlynxg/anet v0.0.3/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA= +github.com/wlynxg/anet v0.0.4 h1:0de1OFQxnNqAu+x2FAKKCVIrnfGKQbs7FQz++tB0+Uw= +github.com/wlynxg/anet v0.0.4/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA= github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -991,10 +989,10 @@ go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= -go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= -go.uber.org/fx v1.22.1 h1:nvvln7mwyT5s1q201YE29V/BFrGor6vMiDNpU/78Mys= -go.uber.org/fx v1.22.1/go.mod h1:HT2M7d7RHo+ebKGh9NRcrsrHHfpZ60nW3QRubMRfv48= +go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw= +go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= +go.uber.org/fx v1.22.2 h1:iPW+OPxv0G8w75OemJ1RAnTUrF55zOJlXlo1TbJ0Buw= +go.uber.org/fx v1.22.2/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= @@ -1048,8 +1046,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa h1:ELnwvuAXPNtPk1TJRuGkI9fDTwym6AYBu0qzT8AcHdI= +golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1074,15 +1072,14 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= -golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1128,8 +1125,8 @@ golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1225,7 +1222,6 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220708085239-5a0f0661e09d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1317,8 +1313,8 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= -golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 3d0c0b448..902ac5234 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -142,7 +142,7 @@ require ( github.com/libp2p/go-cidranger v1.1.0 // indirect github.com/libp2p/go-libp2p v0.36.5 // indirect github.com/libp2p/go-libp2p-asn-util v0.4.1 // indirect - github.com/libp2p/go-libp2p-kad-dht v0.26.1 // indirect + github.com/libp2p/go-libp2p-kad-dht v0.27.0 // indirect github.com/libp2p/go-libp2p-kbucket v0.6.4 // indirect github.com/libp2p/go-libp2p-record v0.2.0 // indirect github.com/libp2p/go-libp2p-routing-helpers v0.7.4 // indirect @@ -159,7 +159,7 @@ require ( github.com/mattn/go-runewidth v0.0.15 // indirect github.com/mattn/go-shellwords v1.0.12 // indirect github.com/mgechev/revive v1.3.9 // indirect - github.com/miekg/dns v1.1.61 // indirect + github.com/miekg/dns v1.1.62 // indirect github.com/minio/sha256-simd v1.0.1 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect @@ -248,7 +248,7 @@ require ( go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect golang.org/x/crypto v0.27.0 // indirect - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect + golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect golang.org/x/exp/typeparams v0.0.0-20240613232115-7f521ea00fb8 // indirect golang.org/x/mod v0.20.0 // indirect golang.org/x/net v0.28.0 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 4ddf403b5..5645f0090 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -388,8 +388,8 @@ github.com/libp2p/go-libp2p v0.36.5 h1:DoABsaHO0VXwH6pwCs2F6XKAXWYjFMO4HFBoVxTnF github.com/libp2p/go-libp2p v0.36.5/go.mod h1:CpszAtXxHYOcyvB7K8rSHgnNlh21eKjYbEfLoMerbEI= github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94= github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= -github.com/libp2p/go-libp2p-kad-dht v0.26.1 h1:AazV3LCImYVkDUGAHx5lIEgZ9iUI2QQKH5GMRQU8uEA= -github.com/libp2p/go-libp2p-kad-dht v0.26.1/go.mod h1:mqRUGJ/+7ziQ3XknU2kKHfsbbgb9xL65DXjPOJwmZF8= +github.com/libp2p/go-libp2p-kad-dht v0.27.0 h1:1Ea32tVTPiAfaLpPMbaBWFJgbsi/JpMqC2YBuFdf32o= +github.com/libp2p/go-libp2p-kad-dht v0.27.0/go.mod h1:ixhjLuzaXSGtWsKsXTj7erySNuVC4UP7NO015cRrF14= github.com/libp2p/go-libp2p-kbucket v0.6.4 h1:OjfiYxU42TKQSB8t8WYd8MKhYhMJeO2If+NiuKfb6iQ= github.com/libp2p/go-libp2p-kbucket v0.6.4/go.mod h1:jp6w82sczYaBsAypt5ayACcRJi0lgsba7o4TzJKEfWA= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= @@ -439,8 +439,8 @@ github.com/mattn/go-shellwords v1.0.12 h1:M2zGm7EW6UQJvDeQxo4T51eKPurbeFbe8WtebG github.com/mattn/go-shellwords v1.0.12/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= github.com/mgechev/revive v1.3.9 h1:18Y3R4a2USSBF+QZKFQwVkBROUda7uoBlkEuBD+YD1A= github.com/mgechev/revive v1.3.9/go.mod h1:+uxEIr5UH0TjXWHTno3xh4u7eg6jDpXKzQccA9UGhHU= -github.com/miekg/dns v1.1.61 h1:nLxbwF3XxhwVSm8g9Dghm9MHPaUZuqhPiGL+675ZmEs= -github.com/miekg/dns v1.1.61/go.mod h1:mnAarhS3nWaW+NVP2wTkYVIZyHNJ098SJZUki3eykwQ= +github.com/miekg/dns v1.1.62 h1:cN8OuEF1/x5Rq6Np+h1epln8OiyPWV+lROx9LxcGgIQ= +github.com/miekg/dns v1.1.62/go.mod h1:mvDlcItzm+br7MToIKqkglaGhlFMHJ9DTNNWONWXbNQ= github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b/go.mod h1:lxPUiZwKoFL8DUUmalo2yJJUCxbPKtm8OKfqr2/FTNU= github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc h1:PTfri+PuQmWDqERdnNMiD9ZejrlswWrCpBEZgWOiTrc= @@ -510,8 +510,8 @@ github.com/pion/dtls/v2 v2.2.12 h1:KP7H5/c1EiVAAKUmXyCzPiQe5+bCJrpOeKg/L05dunk= github.com/pion/dtls/v2 v2.2.12/go.mod h1:d9SYc9fch0CqK90mRk1dC7AkzzpwJj6u2GU3u+9pqFE= github.com/pion/ice/v2 v2.3.34 h1:Ic1ppYCj4tUOcPAp76U6F3fVrlSw8A9JtRXLqw6BbUM= github.com/pion/ice/v2 v2.3.34/go.mod h1:mBF7lnigdqgtB+YHkaY/Y6s6tsyRyo4u4rPGRuOjUBQ= -github.com/pion/interceptor v0.1.29 h1:39fsnlP1U8gw2JzOFWdfCU82vHvhW9o0rZnZF56wF+M= -github.com/pion/interceptor v0.1.29/go.mod h1:ri+LGNjRUc5xUNtDEPzfdkmSqISixVTBF/z/Zms/6T4= +github.com/pion/interceptor v0.1.30 h1:au5rlVHsgmxNi+v/mjOPazbW1SHzfx7/hYOEYQnUcxA= +github.com/pion/interceptor v0.1.30/go.mod h1:RQuKT5HTdkP2Fi0cuOS5G5WNymTjzXaGF75J4k7z2nc= github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY= github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms= github.com/pion/mdns v0.0.12 h1:CiMYlY+O0azojWDmxdNr7ADGrnZ+V6Ilfner+6mSVK8= @@ -520,10 +520,10 @@ github.com/pion/randutil v0.1.0 h1:CFG1UdESneORglEsnimhUjf33Rwjubwj6xfiOXBa3mA= github.com/pion/randutil v0.1.0/go.mod h1:XcJrSMMbbMRhASFVOlj/5hQial/Y8oH/HVo7TBZq+j8= github.com/pion/rtcp v1.2.14 h1:KCkGV3vJ+4DAJmvP0vaQShsb0xkRfWkO540Gy102KyE= github.com/pion/rtcp v1.2.14/go.mod h1:sn6qjxvnwyAkkPzPULIbVqSKI5Dv54Rv7VG0kNxh9L4= -github.com/pion/rtp v1.8.8 h1:EtYFHI0rpUEjT/RMnGfb1vdJhbYmPG77szD72uUnSxs= -github.com/pion/rtp v1.8.8/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU= -github.com/pion/sctp v1.8.20 h1:sOc3lkV/tQaP57ZUEXIMdM2V92IIB2ia5v/ygnBxaEg= -github.com/pion/sctp v1.8.20/go.mod h1:oTxw8i5m+WbDHZJL/xUpe6CPIn1Y0GIKKwTLF4h53H8= +github.com/pion/rtp v1.8.9 h1:E2HX740TZKaqdcPmf4pw6ZZuG8u5RlMMt+l3dxeu6Wk= +github.com/pion/rtp v1.8.9/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU= +github.com/pion/sctp v1.8.33 h1:dSE4wX6uTJBcNm8+YlMg7lw1wqyKHggsP5uKbdj+NZw= +github.com/pion/sctp v1.8.33/go.mod h1:beTnqSzewI53KWoG3nqB282oDMGrhNxBdb+JZnkCwRM= github.com/pion/sdp/v3 v3.0.9 h1:pX++dCHoHUwq43kuwf3PyJfHlwIj4hXA7Vrifiq0IJY= github.com/pion/sdp/v3 v3.0.9/go.mod h1:B5xmvENq5IXJimIO4zfp6LAe1fD9N+kFv+V/1lOdz8M= github.com/pion/srtp/v2 v2.0.20 h1:HNNny4s+OUmG280ETrCdgFndp4ufx3/uy85EawYEhTk= @@ -569,8 +569,8 @@ github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 h1:M8mH9eK4OUR4l github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567/go.mod h1:DWNGW8A4Y+GyBgPuaQJuWiy0XYftx4Xm/y5Jqk9I6VQ= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= -github.com/quic-go/quic-go v0.45.2 h1:DfqBmqjb4ExSdxRIb/+qXhPC+7k6+DUNZha4oeiC9fY= -github.com/quic-go/quic-go v0.45.2/go.mod h1:1dLehS7TIR64+vxGR70GDcatWTOtMX2PUtnKsjbTurI= +github.com/quic-go/quic-go v0.46.0 h1:uuwLClEEyk1DNvchH8uCByQVjo3yKL9opKulExNDs7Y= +github.com/quic-go/quic-go v0.46.0/go.mod h1:1dLehS7TIR64+vxGR70GDcatWTOtMX2PUtnKsjbTurI= github.com/quic-go/webtransport-go v0.8.0 h1:HxSrwun11U+LlmwpgM1kEqIqH90IT4N8auv/cD7QFJg= github.com/quic-go/webtransport-go v0.8.0/go.mod h1:N99tjprW432Ut5ONql/aUhSLT0YVSlwHohQsuac9WaM= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= @@ -691,8 +691,8 @@ github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc h1:BCPnHtcboa github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc/go.mod h1:r45hJU7yEoA81k6MWNhpMj/kms0n14dkzkxYHoB96UM= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 h1:EKhdznlJHPMoKr0XTrX+IlJs1LH3lyx2nfr1dOlZ79k= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc= -github.com/wlynxg/anet v0.0.3 h1:PvR53psxFXstc12jelG6f1Lv4MWqE0tI76/hHGjh9rg= -github.com/wlynxg/anet v0.0.3/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA= +github.com/wlynxg/anet v0.0.4 h1:0de1OFQxnNqAu+x2FAKKCVIrnfGKQbs7FQz++tB0+Uw= +github.com/wlynxg/anet v0.0.4/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA= github.com/xen0n/gosmopolitan v1.2.2 h1:/p2KTnMzwRexIW8GlKawsTWOxn7UHA+jCMF/V8HHtvU= github.com/xen0n/gosmopolitan v1.2.2/go.mod h1:7XX7Mj61uLYrj0qmeN0zi7XDon9JRAEhYQqAPLVNTeg= github.com/yagipy/maintidx v1.0.0 h1:h5NvIsCz+nRDapQ0exNv4aJ0yXSI0420omVANTv3GJM= @@ -727,10 +727,10 @@ go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVf go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/automaxprocs v1.5.3 h1:kWazyxZUrS3Gs4qUpbwo5kEIMGe/DAvi5Z4tl2NW4j8= go.uber.org/automaxprocs v1.5.3/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0= -go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= -go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= -go.uber.org/fx v1.22.1 h1:nvvln7mwyT5s1q201YE29V/BFrGor6vMiDNpU/78Mys= -go.uber.org/fx v1.22.1/go.mod h1:HT2M7d7RHo+ebKGh9NRcrsrHHfpZ60nW3QRubMRfv48= +go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw= +go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= +go.uber.org/fx v1.22.2 h1:iPW+OPxv0G8w75OemJ1RAnTUrF55zOJlXlo1TbJ0Buw= +go.uber.org/fx v1.22.2/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= @@ -755,8 +755,8 @@ golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOM golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa h1:ELnwvuAXPNtPk1TJRuGkI9fDTwym6AYBu0qzT8AcHdI= +golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= golang.org/x/exp/typeparams v0.0.0-20220428152302-39d4317da171/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/exp/typeparams v0.0.0-20230203172020-98cc5a0785f9/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/exp/typeparams v0.0.0-20240613232115-7f521ea00fb8 h1:+ZJmEdDFzH5H0CnzOrwgbH3elHctfTecW9X0k2tkn5M= From 8913a1c1e599d144a8cf9ed102773a94ed3d259b Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Wed, 23 Oct 2024 00:08:12 +0200 Subject: [PATCH 1197/1212] docs(config): explain what multiaddr is --- docs/config.md | 38 +++++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/docs/config.md b/docs/config.md index 9a47d0061..b84711e81 100644 --- a/docs/config.md +++ b/docs/config.md @@ -204,7 +204,7 @@ Contains information about various listener addresses to be used by this node. ### `Addresses.API` -Multiaddr or array of multiaddrs describing the address to serve +[Multiaddr][multiaddr] or array of multiaddrs describing the address to serve the local [Kubo RPC API](https://docs.ipfs.tech/reference/kubo/rpc/) (`/api/v0`). Supported Transports: @@ -214,11 +214,11 @@ Supported Transports: Default: `/ip4/127.0.0.1/tcp/5001` -Type: `strings` (multiaddrs) +Type: `strings` ([multiaddrs][multiaddr]) ### `Addresses.Gateway` -Multiaddr or array of multiaddrs describing the address to serve +[Multiaddr][multiaddr] or array of multiaddrs describing the address to serve the local [HTTP gateway](https://specs.ipfs.tech/http-gateways/) (`/ipfs`, `/ipns`) on. Supported Transports: @@ -228,11 +228,11 @@ Supported Transports: Default: `/ip4/127.0.0.1/tcp/8080` -Type: `strings` (multiaddrs) +Type: `strings` ([multiaddrs][multiaddr]) ### `Addresses.Swarm` -An array of multiaddrs describing which addresses to listen on for p2p swarm +An array of [multiaddrs][multiaddr] describing which addresses to listen on for p2p swarm connections. Supported Transports: @@ -256,7 +256,7 @@ Default: ] ``` -Type: `array[string]` (multiaddrs) +Type: `array[string]` ([multiaddrs][multiaddr]) ### `Addresses.Announce` @@ -265,7 +265,7 @@ network. If empty, the daemon will announce inferred swarm addresses. Default: `[]` -Type: `array[string]` (multiaddrs) +Type: `array[string]` ([multiaddrs][multiaddr]) ### `Addresses.AppendAnnounce` @@ -274,7 +274,7 @@ override inferred swarm addresses if non-empty. Default: `[]` -Type: `array[string]` (multiaddrs) +Type: `array[string]` ([multiaddrs][multiaddr]) ### `Addresses.NoAnnounce` @@ -284,12 +284,12 @@ Takes precedence over `Addresses.Announce` and `Addresses.AppendAnnounce`. > [!TIP] > The [`server` configuration profile](#server-profile) fills up this list with sensible defaults, > preventing announcement of non-routable IP addresses (e.g., `/ip4/192.168.0.0/ipcidr/16`, -> which is the multiaddress representation of `192.168.0.0/16`) but you should always +> which is the [multiaddress][multiaddr] representation of `192.168.0.0/16`) but you should always > check settings against your own network and/or hosting provider. Default: `[]` -Type: `array[string]` (multiaddrs) +Type: `array[string]` ([multiaddrs][multiaddr]) ## `API` @@ -451,11 +451,11 @@ Type: `duration` (when `0`/unset, the default value is used) ## `Bootstrap` -Bootstrap is an array of multiaddrs of trusted nodes that your node connects to, to fetch other nodes of the network on startup. +Bootstrap is an array of [multiaddrs][multiaddr] of trusted nodes that your node connects to, to fetch other nodes of the network on startup. Default: The ipfs.io bootstrap nodes -Type: `array[string]` (multiaddrs) +Type: `array[string]` ([multiaddrs][multiaddr]) ## `Datastore` @@ -1671,7 +1671,7 @@ trigger netscan alerts on some hosting providers or cause strain in some setups. > [!TIP] > The [`server` configuration profile](#server-profile) fills up this list with sensible defaults, > preventing dials to all non-routable IP addresses (e.g., `/ip4/192.168.0.0/ipcidr/16`, -> which is the multiaddress representation of `192.168.0.0/16`) but you should always +> which is the [multiaddress][multiaddr] representation of `192.168.0.0/16`) but you should always > check settings against your own network and/or hosting provider. Default: `[]` @@ -1991,12 +1991,12 @@ Type: `optionalInteger` #### `Swarm.ResourceMgr.Allowlist` -A list of multiaddrs that can bypass normal system limits (but are still limited by the allowlist scope). +A list of [multiaddrs][libp2p-multiaddrs] that can bypass normal system limits (but are still limited by the allowlist scope). Convenience config around [go-libp2p-resource-manager#Allowlist.Add](https://pkg.go.dev/github.com/libp2p/go-libp2p/p2p/host/resource-manager#Allowlist.Add). Default: `[]` -Type: `array[string]` (multiaddrs) +Type: `array[string]` ([multiaddrs][multiaddr]) ### `Swarm.Transports` @@ -2068,7 +2068,7 @@ Listen Addresses: [Libp2p Relay](https://github.com/libp2p/specs/tree/master/relay) proxy transport that forms connections by hopping between multiple libp2p nodes. Allows IPFS node to connect to other peers using their `/p2p-circuit` -multiaddrs. This transport is primarily useful for bypassing firewalls and +[multiaddrs][libp2p-multiaddrs]. This transport is primarily useful for bypassing firewalls and NATs. See also: @@ -2218,7 +2218,7 @@ Please remove this option from your config. ## `DNS` -Options for configuring DNS resolution for [DNSLink](https://docs.ipfs.tech/concepts/dnslink/) and `/dns*` [Multiaddrs](https://github.com/multiformats/multiaddr/). +Options for configuring DNS resolution for [DNSLink](https://docs.ipfs.tech/concepts/dnslink/) and `/dns*` [Multiaddrs][libp2p-multiaddrs]. ### `DNS.Resolvers` @@ -2578,3 +2578,7 @@ an implicit default when missing from the config file: - `null`/missing will apply the default value defined in Kubo sources (`.WithDefault("1h2m3s")`) - a string with a valid [go duration](#duration) (e.g, `"1d2h4m40.01s"`). + +---- + +[multiaddr]: https://docs.ipfs.tech/concepts/glossary/#multiaddr From 5399757b9a5c182f7e40e963af082001062d98db Mon Sep 17 00:00:00 2001 From: Andrew Gillis <11790789+gammazero@users.noreply.github.com> Date: Tue, 22 Oct 2024 13:06:13 -1000 Subject: [PATCH 1198/1212] chore: upgrade to Boxo v0.24.1 (#10556) Upgrade to Boxo vX.Y.Z --- docs/examples/kubo-as-a-library/go.mod | 4 ++-- docs/examples/kubo-as-a-library/go.sum | 10 ++++------ go.mod | 4 ++-- go.sum | 10 ++++------ test/dependencies/go.mod | 2 +- test/dependencies/go.sum | 4 ++-- 6 files changed, 15 insertions(+), 19 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 2c3054fc1..87df70bba 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -9,7 +9,7 @@ toolchain go1.23.2 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.24.0 + github.com/ipfs/boxo v0.24.1 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.36.5 github.com/multiformats/go-multiaddr v0.13.0 @@ -91,7 +91,7 @@ require ( github.com/ipfs/go-ipfs-ds-help v1.1.1 // indirect github.com/ipfs/go-ipfs-exchange-interface v0.2.1 // indirect github.com/ipfs/go-ipfs-pq v0.0.3 // indirect - github.com/ipfs/go-ipfs-redirects-file v0.1.1 // indirect + github.com/ipfs/go-ipfs-redirects-file v0.1.2 // indirect github.com/ipfs/go-ipfs-util v0.0.3 // indirect github.com/ipfs/go-ipld-cbor v0.2.0 // indirect github.com/ipfs/go-ipld-format v0.6.0 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 291ab74d4..8194efa08 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -286,8 +286,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.24.0 h1:D9gTU3QdxyjPMlJ6QfqhHTG3TIJPplKzjXLO2J30h9U= -github.com/ipfs/boxo v0.24.0/go.mod h1:iP7xUPpHq2QAmVAjwtQvsNBTxTwLpFuy6ZpiRFwmzDA= +github.com/ipfs/boxo v0.24.1 h1:Y1n+8Q9lqeWLhEMZR2staJDnY80mtSWNR+hOhG3VtDo= +github.com/ipfs/boxo v0.24.1/go.mod h1:8mVcuQl2qqprmSOXHeqvvP4TezOobM92fKF3+ugpE58= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= @@ -340,8 +340,8 @@ github.com/ipfs/go-ipfs-exchange-offline v0.3.0 h1:c/Dg8GDPzixGd0MC8Jh6mjOwU57uY github.com/ipfs/go-ipfs-exchange-offline v0.3.0/go.mod h1:MOdJ9DChbb5u37M1IcbrRB02e++Z7521fMxqCNRrz9s= github.com/ipfs/go-ipfs-pq v0.0.3 h1:YpoHVJB+jzK15mr/xsWC574tyDLkezVrDNeaalQBsTE= github.com/ipfs/go-ipfs-pq v0.0.3/go.mod h1:btNw5hsHBpRcSSgZtiNm/SLj5gYIZ18AKtv3kERkRb4= -github.com/ipfs/go-ipfs-redirects-file v0.1.1 h1:Io++k0Vf/wK+tfnhEh63Yte1oQK5VGT2hIEYpD0Rzx8= -github.com/ipfs/go-ipfs-redirects-file v0.1.1/go.mod h1:tAwRjCV0RjLTjH8DR/AU7VYvfQECg+lpUy2Mdzv7gyk= +github.com/ipfs/go-ipfs-redirects-file v0.1.2 h1:QCK7VtL91FH17KROVVy5KrzDx2hu68QvB2FTWk08ZQk= +github.com/ipfs/go-ipfs-redirects-file v0.1.2/go.mod h1:yIiTlLcDEM/8lS6T3FlCEXZktPPqSOyuY6dEzVqw7Fw= github.com/ipfs/go-ipfs-routing v0.3.0 h1:9W/W3N+g+y4ZDeffSgqhgo7BsBSJwPMcyssET9OWevc= github.com/ipfs/go-ipfs-routing v0.3.0/go.mod h1:dKqtTFIql7e1zYsEuWLyuOU+E0WJWW8JjbTPLParDWo= github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyBCNzQxlJBc= @@ -756,8 +756,6 @@ github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpP github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= -github.com/tj/assert v0.0.3 h1:Df/BlaZ20mq6kuai7f5z2TvPFiwC3xaWJSDQNiIS3Rk= -github.com/tj/assert v0.0.3/go.mod h1:Ne6X72Q+TB1AteidzQncjw9PabbMp4PBMZ1k+vd1Pvk= github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c h1:u6SKchux2yDvFQnDHS3lPnIRmfVJ5Sxy3ao2SIdysLQ= github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM= github.com/ucarion/urlpath v0.0.0-20200424170820-7ccc79b76bbb h1:Ywfo8sUltxogBpFuMOFRrrSifO788kAFxmvVw31PtQQ= diff --git a/go.mod b/go.mod index 0231b8658..ede954021 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,7 @@ require ( github.com/hashicorp/go-version v1.7.0 github.com/ipfs-shipyard/nopfs v0.0.12 github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c - github.com/ipfs/boxo v0.24.0 + github.com/ipfs/boxo v0.24.1 github.com/ipfs/go-block-format v0.2.0 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 @@ -151,7 +151,7 @@ require ( github.com/ipfs/go-ipfs-ds-help v1.1.1 // indirect github.com/ipfs/go-ipfs-exchange-interface v0.2.1 // indirect github.com/ipfs/go-ipfs-pq v0.0.3 // indirect - github.com/ipfs/go-ipfs-redirects-file v0.1.1 // indirect + github.com/ipfs/go-ipfs-redirects-file v0.1.2 // indirect github.com/ipfs/go-ipfs-util v0.0.3 // indirect github.com/ipfs/go-merkledag v0.11.0 // indirect github.com/ipfs/go-peertaskqueue v0.8.1 // indirect diff --git a/go.sum b/go.sum index 9087b8647..ba427dd0f 100644 --- a/go.sum +++ b/go.sum @@ -350,8 +350,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.24.0 h1:D9gTU3QdxyjPMlJ6QfqhHTG3TIJPplKzjXLO2J30h9U= -github.com/ipfs/boxo v0.24.0/go.mod h1:iP7xUPpHq2QAmVAjwtQvsNBTxTwLpFuy6ZpiRFwmzDA= +github.com/ipfs/boxo v0.24.1 h1:Y1n+8Q9lqeWLhEMZR2staJDnY80mtSWNR+hOhG3VtDo= +github.com/ipfs/boxo v0.24.1/go.mod h1:8mVcuQl2qqprmSOXHeqvvP4TezOobM92fKF3+ugpE58= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= @@ -406,8 +406,8 @@ github.com/ipfs/go-ipfs-exchange-offline v0.3.0 h1:c/Dg8GDPzixGd0MC8Jh6mjOwU57uY github.com/ipfs/go-ipfs-exchange-offline v0.3.0/go.mod h1:MOdJ9DChbb5u37M1IcbrRB02e++Z7521fMxqCNRrz9s= github.com/ipfs/go-ipfs-pq v0.0.3 h1:YpoHVJB+jzK15mr/xsWC574tyDLkezVrDNeaalQBsTE= github.com/ipfs/go-ipfs-pq v0.0.3/go.mod h1:btNw5hsHBpRcSSgZtiNm/SLj5gYIZ18AKtv3kERkRb4= -github.com/ipfs/go-ipfs-redirects-file v0.1.1 h1:Io++k0Vf/wK+tfnhEh63Yte1oQK5VGT2hIEYpD0Rzx8= -github.com/ipfs/go-ipfs-redirects-file v0.1.1/go.mod h1:tAwRjCV0RjLTjH8DR/AU7VYvfQECg+lpUy2Mdzv7gyk= +github.com/ipfs/go-ipfs-redirects-file v0.1.2 h1:QCK7VtL91FH17KROVVy5KrzDx2hu68QvB2FTWk08ZQk= +github.com/ipfs/go-ipfs-redirects-file v0.1.2/go.mod h1:yIiTlLcDEM/8lS6T3FlCEXZktPPqSOyuY6dEzVqw7Fw= github.com/ipfs/go-ipfs-routing v0.3.0 h1:9W/W3N+g+y4ZDeffSgqhgo7BsBSJwPMcyssET9OWevc= github.com/ipfs/go-ipfs-routing v0.3.0/go.mod h1:dKqtTFIql7e1zYsEuWLyuOU+E0WJWW8JjbTPLParDWo= github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyBCNzQxlJBc= @@ -897,8 +897,6 @@ github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= -github.com/tj/assert v0.0.3 h1:Df/BlaZ20mq6kuai7f5z2TvPFiwC3xaWJSDQNiIS3Rk= -github.com/tj/assert v0.0.3/go.mod h1:Ne6X72Q+TB1AteidzQncjw9PabbMp4PBMZ1k+vd1Pvk= github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c h1:u6SKchux2yDvFQnDHS3lPnIRmfVJ5Sxy3ao2SIdysLQ= github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM= github.com/ucarion/urlpath v0.0.0-20200424170820-7ccc79b76bbb h1:Ywfo8sUltxogBpFuMOFRrrSifO788kAFxmvVw31PtQQ= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 902ac5234..9a14d2992 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -110,7 +110,7 @@ require ( github.com/hexops/gotextdiff v1.0.3 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/ipfs/bbloom v0.0.4 // indirect - github.com/ipfs/boxo v0.24.0 // indirect + github.com/ipfs/boxo v0.24.1 // indirect github.com/ipfs/go-block-format v0.2.0 // indirect github.com/ipfs/go-cid v0.4.1 // indirect github.com/ipfs/go-datastore v0.6.0 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 5645f0090..34ac28c54 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -280,8 +280,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.24.0 h1:D9gTU3QdxyjPMlJ6QfqhHTG3TIJPplKzjXLO2J30h9U= -github.com/ipfs/boxo v0.24.0/go.mod h1:iP7xUPpHq2QAmVAjwtQvsNBTxTwLpFuy6ZpiRFwmzDA= +github.com/ipfs/boxo v0.24.1 h1:Y1n+8Q9lqeWLhEMZR2staJDnY80mtSWNR+hOhG3VtDo= +github.com/ipfs/boxo v0.24.1/go.mod h1:8mVcuQl2qqprmSOXHeqvvP4TezOobM92fKF3+ugpE58= github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs= github.com/ipfs/go-block-format v0.2.0/go.mod h1:+jpL11nFx5A/SPpsoBn6Bzkra/zaArfSmsknbPMYgzM= github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= From 56c68a1657c833f637b6f47f17a5555788c72cbf Mon Sep 17 00:00:00 2001 From: Marco Munizaga Date: Tue, 22 Oct 2024 16:31:40 -0700 Subject: [PATCH 1199/1212] refactor: update to go-libp2p v0.37.0 (#10554) https://github.com/libp2p/go-libp2p/releases/tag/v0.37.0 Co-authored-by: Marcin Rataj --- config/swarm.go | 2 - core/node/libp2p/dns.go | 3 +- core/node/libp2p/relay.go | 13 ++- docs/changelogs/v0.32.md | 5 ++ docs/config.md | 7 +- docs/examples/kubo-as-a-library/go.mod | 52 ++++++------ docs/examples/kubo-as-a-library/go.sum | 100 +++++++++++------------ go.mod | 54 ++++++------- go.sum | 108 ++++++++++++------------- test/dependencies/go.mod | 24 +++--- test/dependencies/go.sum | 104 ++++++++++++------------ 11 files changed, 234 insertions(+), 238 deletions(-) diff --git a/config/swarm.go b/config/swarm.go index f15634b57..4a04a0054 100644 --- a/config/swarm.go +++ b/config/swarm.go @@ -65,8 +65,6 @@ type RelayService struct { // BufferSize is the size of the relayed connection buffers. BufferSize *OptionalInteger `json:",omitempty"` - // MaxReservationsPerPeer is the maximum number of reservations originating from the same peer. - MaxReservationsPerPeer *OptionalInteger `json:",omitempty"` // MaxReservationsPerIP is the maximum number of reservations originating from the same IP address. MaxReservationsPerIP *OptionalInteger `json:",omitempty"` // MaxReservationsPerASN is the maximum number of reservations origination from the same ASN. diff --git a/core/node/libp2p/dns.go b/core/node/libp2p/dns.go index 1c56a2c0a..2ee73b4c9 100644 --- a/core/node/libp2p/dns.go +++ b/core/node/libp2p/dns.go @@ -2,10 +2,11 @@ package libp2p import ( "github.com/libp2p/go-libp2p" + "github.com/libp2p/go-libp2p/p2p/net/swarm" madns "github.com/multiformats/go-multiaddr-dns" ) func MultiaddrResolver(rslv *madns.Resolver) (opts Libp2pOpts, err error) { - opts.Opts = append(opts.Opts, libp2p.MultiaddrResolver(rslv)) + opts.Opts = append(opts.Opts, libp2p.MultiaddrResolver(swarm.ResolverFromMaDNS{Resolver: rslv})) return opts, nil } diff --git a/core/node/libp2p/relay.go b/core/node/libp2p/relay.go index 89567e30d..dd56835fb 100644 --- a/core/node/libp2p/relay.go +++ b/core/node/libp2p/relay.go @@ -33,13 +33,12 @@ func RelayService(enable bool, relayOpts config.RelayService) func() (opts Libp2 Data: relayOpts.ConnectionDataLimit.WithDefault(def.Limit.Data), Duration: relayOpts.ConnectionDurationLimit.WithDefault(def.Limit.Duration), }, - MaxCircuits: int(relayOpts.MaxCircuits.WithDefault(int64(def.MaxCircuits))), - BufferSize: int(relayOpts.BufferSize.WithDefault(int64(def.BufferSize))), - ReservationTTL: relayOpts.ReservationTTL.WithDefault(def.ReservationTTL), - MaxReservations: int(relayOpts.MaxReservations.WithDefault(int64(def.MaxReservations))), - MaxReservationsPerIP: int(relayOpts.MaxReservationsPerIP.WithDefault(int64(def.MaxReservationsPerIP))), - MaxReservationsPerPeer: int(relayOpts.MaxReservationsPerPeer.WithDefault(int64(def.MaxReservationsPerPeer))), - MaxReservationsPerASN: int(relayOpts.MaxReservationsPerASN.WithDefault(int64(def.MaxReservationsPerASN))), + MaxCircuits: int(relayOpts.MaxCircuits.WithDefault(int64(def.MaxCircuits))), + BufferSize: int(relayOpts.BufferSize.WithDefault(int64(def.BufferSize))), + ReservationTTL: relayOpts.ReservationTTL.WithDefault(def.ReservationTTL), + MaxReservations: int(relayOpts.MaxReservations.WithDefault(int64(def.MaxReservations))), + MaxReservationsPerIP: int(relayOpts.MaxReservationsPerIP.WithDefault(int64(def.MaxReservationsPerIP))), + MaxReservationsPerASN: int(relayOpts.MaxReservationsPerASN.WithDefault(int64(def.MaxReservationsPerASN))), }))) } return diff --git a/docs/changelogs/v0.32.md b/docs/changelogs/v0.32.md index 6ae7d1ad7..edeef6c5e 100644 --- a/docs/changelogs/v0.32.md +++ b/docs/changelogs/v0.32.md @@ -14,8 +14,13 @@ ### 🔦 Highlights +#### go-libp2p updates + +- update `go-libp2p` to [v0.37.0](https://github.com/libp2p/go-libp2p/releases/tag/v0.37.0) + - This update required removal of `Swarm.RelayService.MaxReservationsPerPeer` configuration option from Kubo. If you had it set, remove it from your configuration file. - update `go-libp2p-kad-dht` to [v0.27.0](https://github.com/libp2p/go-libp2p-kad-dht/releases/tag/v0.27.0) - update `go-libp2p-pubsub` to [v0.12.0](https://github.com/libp2p/go-libp2p-pubsub/releases/tag/v0.12.0) + ### 📝 Changelog ### 👨‍👩‍👧‍👦 Contributors diff --git a/docs/config.md b/docs/config.md index b84711e81..47264a868 100644 --- a/docs/config.md +++ b/docs/config.md @@ -1835,12 +1835,7 @@ Type: `optionalInteger` #### `Swarm.RelayService.MaxReservationsPerPeer` -Maximum number of reservations originating from the same peer. - -Default: `4` - -Type: `optionalInteger` - +**REMOVED in kubo 0.32 due to removal from go-libp2p v0.37** #### `Swarm.RelayService.MaxReservationsPerIP` diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 87df70bba..17fefed06 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -2,8 +2,6 @@ module github.com/ipfs/kubo/examples/kubo-as-a-library go 1.23 -toolchain go1.23.2 - // Used to keep this in sync with the current version of kubo. You should remove // this if you copy this example. replace github.com/ipfs/kubo => ./../../.. @@ -11,7 +9,7 @@ replace github.com/ipfs/kubo => ./../../.. require ( github.com/ipfs/boxo v0.24.1 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 - github.com/libp2p/go-libp2p v0.36.5 + github.com/libp2p/go-libp2p v0.37.0 github.com/multiformats/go-multiaddr v0.13.0 ) @@ -62,7 +60,7 @@ require ( github.com/golang/protobuf v1.5.4 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/gopacket v1.1.19 // indirect - github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 // indirect + github.com/google/pprof v0.0.0-20241017200806-017d972448fc // indirect github.com/google/uuid v1.6.0 // indirect github.com/gorilla/websocket v1.5.3 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect @@ -111,7 +109,7 @@ require ( github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect github.com/jbenet/goprocess v0.1.4 // indirect - github.com/klauspost/compress v1.17.9 // indirect + github.com/klauspost/compress v1.17.11 // indirect github.com/klauspost/cpuid/v2 v2.2.8 // indirect github.com/koron/go-ssdp v0.0.4 // indirect github.com/kr/pretty v0.3.1 // indirect @@ -119,7 +117,7 @@ require ( github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/libp2p/go-cidranger v1.1.0 // indirect github.com/libp2p/go-doh-resolver v0.4.0 // indirect - github.com/libp2p/go-flow-metrics v0.1.0 // indirect + github.com/libp2p/go-flow-metrics v0.2.0 // indirect github.com/libp2p/go-libp2p-asn-util v0.4.1 // indirect github.com/libp2p/go-libp2p-kad-dht v0.27.0 // indirect github.com/libp2p/go-libp2p-kbucket v0.6.4 // indirect @@ -152,16 +150,16 @@ require ( github.com/multiformats/go-multistream v0.5.0 // indirect github.com/multiformats/go-varint v0.0.7 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/onsi/ginkgo/v2 v2.20.0 // indirect + github.com/onsi/ginkgo/v2 v2.20.2 // indirect github.com/opencontainers/runtime-spec v1.2.0 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/openzipkin/zipkin-go v0.4.3 // indirect github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 // indirect - github.com/pion/datachannel v1.5.8 // indirect + github.com/pion/datachannel v1.5.9 // indirect github.com/pion/dtls/v2 v2.2.12 // indirect - github.com/pion/ice/v2 v2.3.34 // indirect - github.com/pion/interceptor v0.1.30 // indirect + github.com/pion/ice/v2 v2.3.36 // indirect + github.com/pion/interceptor v0.1.37 // indirect github.com/pion/logging v0.2.2 // indirect github.com/pion/mdns v0.0.12 // indirect github.com/pion/randutil v0.1.0 // indirect @@ -173,17 +171,17 @@ require ( github.com/pion/stun v0.6.1 // indirect github.com/pion/transport/v2 v2.2.10 // indirect github.com/pion/turn/v2 v2.1.6 // indirect - github.com/pion/webrtc/v3 v3.3.0 // indirect + github.com/pion/webrtc/v3 v3.3.4 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/polydawn/refmt v0.89.0 // indirect - github.com/prometheus/client_golang v1.20.4 // indirect + github.com/prometheus/client_golang v1.20.5 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.55.0 // indirect + github.com/prometheus/common v0.60.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect - github.com/quic-go/qpack v0.4.0 // indirect - github.com/quic-go/quic-go v0.46.0 // indirect - github.com/quic-go/webtransport-go v0.8.0 // indirect + github.com/quic-go/qpack v0.5.1 // indirect + github.com/quic-go/quic-go v0.48.1 // indirect + github.com/quic-go/webtransport-go v0.8.1-0.20241018022711-4ac2c9250e66 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect github.com/samber/lo v1.46.0 // indirect @@ -197,7 +195,7 @@ require ( github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f // indirect github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 // indirect - github.com/wlynxg/anet v0.0.4 // indirect + github.com/wlynxg/anet v0.0.5 // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.52.0 // indirect go.opentelemetry.io/otel v1.28.0 // indirect @@ -212,25 +210,25 @@ require ( go.opentelemetry.io/proto/otlp v1.3.1 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/dig v1.18.0 // indirect - go.uber.org/fx v1.22.2 // indirect - go.uber.org/mock v0.4.0 // indirect + go.uber.org/fx v1.23.0 // indirect + go.uber.org/mock v0.5.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect go4.org v0.0.0-20230225012048-214862532bf5 // indirect - golang.org/x/crypto v0.27.0 // indirect - golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect - golang.org/x/mod v0.20.0 // indirect - golang.org/x/net v0.28.0 // indirect + golang.org/x/crypto v0.28.0 // indirect + golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c // indirect + golang.org/x/mod v0.21.0 // indirect + golang.org/x/net v0.30.0 // indirect golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.25.0 // indirect - golang.org/x/text v0.18.0 // indirect - golang.org/x/tools v0.24.0 // indirect + golang.org/x/sys v0.26.0 // indirect + golang.org/x/text v0.19.0 // indirect + golang.org/x/tools v0.26.0 // indirect golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect gonum.org/v1/gonum v0.15.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240617180043-68d350f18fd4 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240617180043-68d350f18fd4 // indirect google.golang.org/grpc v1.64.0 // indirect - google.golang.org/protobuf v1.34.2 // indirect + google.golang.org/protobuf v1.35.1 // indirect gopkg.in/square/go-jose.v2 v2.6.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect lukechampine.com/blake3 v1.3.0 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 8194efa08..f09415bdc 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -238,8 +238,8 @@ github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXi github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 h1:FKHo8hFI3A+7w0aUQuYXQ+6EN5stWmeY/AZqtM8xk9k= -github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= +github.com/google/pprof v0.0.0-20241017200806-017d972448fc h1:NGyrhhFhwvRAZg02jnYVg3GBQy0qGBKmFQJwaPmpmxs= +github.com/google/pprof v0.0.0-20241017200806-017d972448fc/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -415,8 +415,8 @@ github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQL 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.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= -github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= +github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM= @@ -445,10 +445,10 @@ github.com/libp2p/go-doh-resolver v0.4.0 h1:gUBa1f1XsPwtpE1du0O+nnZCUqtG7oYi7Bb+ github.com/libp2p/go-doh-resolver v0.4.0/go.mod h1:v1/jwsFusgsWIGX/c6vCRrnJ60x7bhTiq/fs2qt0cAg= github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8= github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= -github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= -github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.36.5 h1:DoABsaHO0VXwH6pwCs2F6XKAXWYjFMO4HFBoVxTnF9g= -github.com/libp2p/go-libp2p v0.36.5/go.mod h1:CpszAtXxHYOcyvB7K8rSHgnNlh21eKjYbEfLoMerbEI= +github.com/libp2p/go-flow-metrics v0.2.0 h1:EIZzjmeOE6c8Dav0sNv35vhZxATIXWZg6j/C08XmmDw= +github.com/libp2p/go-flow-metrics v0.2.0/go.mod h1:st3qqfu8+pMfh+9Mzqb2GTiwrAGjIPszEjZmtksN8Jc= +github.com/libp2p/go-libp2p v0.37.0 h1:8K3mcZgwTldydMCNOiNi/ZJrOB9BY+GlI3UxYzxBi9A= +github.com/libp2p/go-libp2p v0.37.0/go.mod h1:GOKmSN99scDuYGTwaTbQPR8Nt6dxrK3ue7OjW2NGDg4= github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94= github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= @@ -583,8 +583,8 @@ github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108 github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.20.0 h1:PE84V2mHqoT1sglvHc8ZdQtPcwmvvt29WLEEO3xmdZw= -github.com/onsi/ginkgo/v2 v2.20.0/go.mod h1:lG9ey2Z29hR41WMVthyJBGUBcBhGOtoPF2VFMvBXFCI= +github.com/onsi/ginkgo/v2 v2.20.2 h1:7NVCeyIWROIAheY21RLS+3j2bb52W0W82tkberYytp4= +github.com/onsi/ginkgo/v2 v2.20.2/go.mod h1:K9gyxPIlb+aIvnZ8bd9Ak+YP18w3APlR+5coaZoE2ag= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= @@ -607,15 +607,15 @@ github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 h1:1/WtZae0yGtPq+TI6+ github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9/go.mod h1:x3N5drFsm2uilKKuuYo6LdyD8vZAW55sH/9w+pbo1sw= github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= -github.com/pion/datachannel v1.5.8 h1:ph1P1NsGkazkjrvyMfhRBUAWMxugJjq2HfQifaOoSNo= -github.com/pion/datachannel v1.5.8/go.mod h1:PgmdpoaNBLX9HNzNClmdki4DYW5JtI7Yibu8QzbL3tI= +github.com/pion/datachannel v1.5.9 h1:LpIWAOYPyDrXtU+BW7X0Yt/vGtYxtXQ8ql7dFfYUVZA= +github.com/pion/datachannel v1.5.9/go.mod h1:kDUuk4CU4Uxp82NH4LQZbISULkX/HtzKa4P7ldf9izE= github.com/pion/dtls/v2 v2.2.7/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s= github.com/pion/dtls/v2 v2.2.12 h1:KP7H5/c1EiVAAKUmXyCzPiQe5+bCJrpOeKg/L05dunk= github.com/pion/dtls/v2 v2.2.12/go.mod h1:d9SYc9fch0CqK90mRk1dC7AkzzpwJj6u2GU3u+9pqFE= -github.com/pion/ice/v2 v2.3.34 h1:Ic1ppYCj4tUOcPAp76U6F3fVrlSw8A9JtRXLqw6BbUM= -github.com/pion/ice/v2 v2.3.34/go.mod h1:mBF7lnigdqgtB+YHkaY/Y6s6tsyRyo4u4rPGRuOjUBQ= -github.com/pion/interceptor v0.1.30 h1:au5rlVHsgmxNi+v/mjOPazbW1SHzfx7/hYOEYQnUcxA= -github.com/pion/interceptor v0.1.30/go.mod h1:RQuKT5HTdkP2Fi0cuOS5G5WNymTjzXaGF75J4k7z2nc= +github.com/pion/ice/v2 v2.3.36 h1:SopeXiVbbcooUg2EIR8sq4b13RQ8gzrkkldOVg+bBsc= +github.com/pion/ice/v2 v2.3.36/go.mod h1:mBF7lnigdqgtB+YHkaY/Y6s6tsyRyo4u4rPGRuOjUBQ= +github.com/pion/interceptor v0.1.37 h1:aRA8Zpab/wE7/c0O3fh1PqY0AJI3fCSEM5lRWJVorwI= +github.com/pion/interceptor v0.1.37/go.mod h1:JzxbJ4umVTlZAf+/utHzNesY8tmRkM2lVmkS82TTj8Y= github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY= github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms= github.com/pion/mdns v0.0.12 h1:CiMYlY+O0azojWDmxdNr7ADGrnZ+V6Ilfner+6mSVK8= @@ -647,8 +647,8 @@ github.com/pion/transport/v3 v3.0.7/go.mod h1:YleKiTZ4vqNxVwh77Z0zytYi7rXHl7j6uP github.com/pion/turn/v2 v2.1.3/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY= github.com/pion/turn/v2 v2.1.6 h1:Xr2niVsiPTB0FPtt+yAWKFUkU1eotQbGgpTIld4x1Gc= github.com/pion/turn/v2 v2.1.6/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY= -github.com/pion/webrtc/v3 v3.3.0 h1:Rf4u6n6U5t5sUxhYPQk/samzU/oDv7jk6BA5hyO2F9I= -github.com/pion/webrtc/v3 v3.3.0/go.mod h1:hVmrDJvwhEertRWObeb1xzulzHGeVUoPlWvxdGzcfU0= +github.com/pion/webrtc/v3 v3.3.4 h1:v2heQVnXTSqNRXcaFQVOhIOYkLMxOu1iJG8uy1djvkk= +github.com/pion/webrtc/v3 v3.3.4/go.mod h1:liNa+E1iwyzyXqNUwvoMRNQ10x8h8FOeJKL8RkIbamE= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -659,24 +659,24 @@ github.com/polydawn/refmt v0.0.0-20201211092308-30ac6d18308e/go.mod h1:uIp+gprXx github.com/polydawn/refmt v0.89.0 h1:ADJTApkvkeBZsN0tBTx8QjpD9JkmxbKp0cxfr9qszm4= github.com/polydawn/refmt v0.89.0/go.mod h1:/zvteZs/GwLtCgZ4BL6CBsk9IKIlexP43ObX9AxTqTw= github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v1.20.4 h1:Tgh3Yr67PaOv/uTqloMsCEdeuFTatm5zIq5+qNN23vI= -github.com/prometheus/client_golang v1.20.4/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= +github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y= +github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc= -github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8= +github.com/prometheus/common v0.60.0 h1:+V9PAREWNvJMAuJ1x1BaWl9dewMW4YrHZQbx0sJNllA= +github.com/prometheus/common v0.60.0/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= -github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= -github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= -github.com/quic-go/quic-go v0.46.0 h1:uuwLClEEyk1DNvchH8uCByQVjo3yKL9opKulExNDs7Y= -github.com/quic-go/quic-go v0.46.0/go.mod h1:1dLehS7TIR64+vxGR70GDcatWTOtMX2PUtnKsjbTurI= -github.com/quic-go/webtransport-go v0.8.0 h1:HxSrwun11U+LlmwpgM1kEqIqH90IT4N8auv/cD7QFJg= -github.com/quic-go/webtransport-go v0.8.0/go.mod h1:N99tjprW432Ut5ONql/aUhSLT0YVSlwHohQsuac9WaM= +github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI= +github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg= +github.com/quic-go/quic-go v0.48.1 h1:y/8xmfWI9qmGTc+lBr4jKRUWLGSlSigv847ULJ4hYXA= +github.com/quic-go/quic-go v0.48.1/go.mod h1:yBgs3rWBOADpga7F+jJsb6Ybg1LSYiQvwWlLX+/6HMs= +github.com/quic-go/webtransport-go v0.8.1-0.20241018022711-4ac2c9250e66 h1:4WFk6u3sOT6pLa1kQ50ZVdm8BQFgJNA117cepZxtLIg= +github.com/quic-go/webtransport-go v0.8.1-0.20241018022711-4ac2c9250e66/go.mod h1:Vp72IJajgeOL6ddqrAhmp7IM9zbTcgkQxD/YdxrVwMw= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= @@ -787,8 +787,8 @@ github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1 github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 h1:E9S12nwJwEOXe2d6gT6qxdvqMnNq+VnSsKPgm2ZZNds= github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7/go.mod h1:X2c0RVCI1eSUFI8eLcY3c0423ykwiUdxLJtkDvruhjI= github.com/wlynxg/anet v0.0.3/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA= -github.com/wlynxg/anet v0.0.4 h1:0de1OFQxnNqAu+x2FAKKCVIrnfGKQbs7FQz++tB0+Uw= -github.com/wlynxg/anet v0.0.4/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA= +github.com/wlynxg/anet v0.0.5 h1:J3VJGi1gvo0JwZ/P1/Yc/8p63SoW98B5dHkYDmpgvvU= +github.com/wlynxg/anet v0.0.5/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA= github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -832,13 +832,13 @@ go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw= go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= -go.uber.org/fx v1.22.2 h1:iPW+OPxv0G8w75OemJ1RAnTUrF55zOJlXlo1TbJ0Buw= -go.uber.org/fx v1.22.2/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU= +go.uber.org/fx v1.23.0 h1:lIr/gYWQGfTwGcSXWXu4vP5Ws6iqnNEIY+F/aFzCKTg= +go.uber.org/fx v1.23.0/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= -go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= -go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= +go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU= +go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= @@ -875,8 +875,8 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= -golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= -golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= +golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= +golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -885,8 +885,8 @@ golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa h1:ELnwvuAXPNtPk1TJRuGkI9fDTwym6AYBu0qzT8AcHdI= -golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= +golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c h1:7dEasQXItcW1xKJ2+gg5VOiBnqWrJc+rq0DPKyvvdbY= +golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c/go.mod h1:NQtJDoLvd6faHhE7m4T/1IY708gDefGGjR/iUW8yQQ8= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -910,8 +910,8 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= -golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= +golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -947,8 +947,8 @@ golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= -golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= -golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4= +golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1022,8 +1022,8 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= -golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= +golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -1043,8 +1043,8 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= -golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= +golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1087,8 +1087,8 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= -golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= +golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ= +golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1160,8 +1160,8 @@ google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= -google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= +google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/go.mod b/go.mod index ede954021..1c3e7914a 100644 --- a/go.mod +++ b/go.mod @@ -52,7 +52,7 @@ require ( github.com/jbenet/goprocess v0.1.4 github.com/julienschmidt/httprouter v1.3.0 github.com/libp2p/go-doh-resolver v0.4.0 - github.com/libp2p/go-libp2p v0.36.5 + github.com/libp2p/go-libp2p v0.37.0 github.com/libp2p/go-libp2p-http v0.5.0 github.com/libp2p/go-libp2p-kad-dht v0.27.0 github.com/libp2p/go-libp2p-kbucket v0.6.4 @@ -70,7 +70,7 @@ require ( github.com/multiformats/go-multihash v0.2.3 github.com/opentracing/opentracing-go v1.2.0 github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 - github.com/prometheus/client_golang v1.20.4 + github.com/prometheus/client_golang v1.20.5 github.com/stretchr/testify v1.9.0 github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 github.com/tidwall/gjson v1.14.4 @@ -84,15 +84,15 @@ require ( go.opentelemetry.io/otel/sdk v1.27.0 go.opentelemetry.io/otel/trace v1.28.0 go.uber.org/dig v1.18.0 - go.uber.org/fx v1.22.2 + go.uber.org/fx v1.23.0 go.uber.org/multierr v1.11.0 go.uber.org/zap v1.27.0 - golang.org/x/crypto v0.27.0 - golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa - golang.org/x/mod v0.20.0 + golang.org/x/crypto v0.28.0 + golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c + golang.org/x/mod v0.21.0 golang.org/x/sync v0.8.0 - golang.org/x/sys v0.25.0 - google.golang.org/protobuf v1.34.2 + golang.org/x/sys v0.26.0 + google.golang.org/protobuf v1.35.1 ) require ( @@ -135,7 +135,7 @@ require ( github.com/golang/protobuf v1.5.4 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/gopacket v1.1.19 // indirect - github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 // indirect + github.com/google/pprof v0.0.0-20241017200806-017d972448fc // indirect github.com/gorilla/mux v1.8.1 // indirect github.com/gorilla/websocket v1.5.3 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect @@ -157,14 +157,14 @@ require ( github.com/ipfs/go-peertaskqueue v0.8.1 // indirect github.com/ipfs/go-verifcid v0.0.3 // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect - github.com/klauspost/compress v1.17.9 // indirect + github.com/klauspost/compress v1.17.11 // indirect github.com/klauspost/cpuid/v2 v2.2.8 // indirect github.com/koron/go-ssdp v0.0.4 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/libp2p/go-cidranger v1.1.0 // indirect - github.com/libp2p/go-flow-metrics v0.1.0 // indirect + github.com/libp2p/go-flow-metrics v0.2.0 // indirect github.com/libp2p/go-libp2p-asn-util v0.4.1 // indirect github.com/libp2p/go-libp2p-gostream v0.6.0 // indirect github.com/libp2p/go-libp2p-xor v0.1.0 // indirect @@ -190,14 +190,14 @@ require ( github.com/multiformats/go-multistream v0.5.0 // indirect github.com/multiformats/go-varint v0.0.7 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/onsi/ginkgo/v2 v2.20.0 // indirect + github.com/onsi/ginkgo/v2 v2.20.2 // indirect github.com/opencontainers/runtime-spec v1.2.0 // indirect github.com/openzipkin/zipkin-go v0.4.3 // indirect github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 // indirect - github.com/pion/datachannel v1.5.8 // indirect + github.com/pion/datachannel v1.5.9 // indirect github.com/pion/dtls/v2 v2.2.12 // indirect - github.com/pion/ice/v2 v2.3.34 // indirect - github.com/pion/interceptor v0.1.30 // indirect + github.com/pion/ice/v2 v2.3.36 // indirect + github.com/pion/interceptor v0.1.37 // indirect github.com/pion/logging v0.2.2 // indirect github.com/pion/mdns v0.0.12 // indirect github.com/pion/randutil v0.1.0 // indirect @@ -209,17 +209,17 @@ require ( github.com/pion/stun v0.6.1 // indirect github.com/pion/transport/v2 v2.2.10 // indirect github.com/pion/turn/v2 v2.1.6 // indirect - github.com/pion/webrtc/v3 v3.3.0 // indirect + github.com/pion/webrtc/v3 v3.3.4 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/polydawn/refmt v0.89.0 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.55.0 // indirect + github.com/prometheus/common v0.60.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/prometheus/statsd_exporter v0.22.7 // indirect - github.com/quic-go/qpack v0.4.0 // indirect - github.com/quic-go/quic-go v0.46.0 // indirect - github.com/quic-go/webtransport-go v0.8.0 // indirect + github.com/quic-go/qpack v0.5.1 // indirect + github.com/quic-go/quic-go v0.48.1 // indirect + github.com/quic-go/webtransport-go v0.8.1-0.20241018022711-4ac2c9250e66 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect github.com/rs/cors v1.10.1 // indirect @@ -234,7 +234,7 @@ require ( github.com/whyrusleeping/cbor-gen v0.1.2 // indirect github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f // indirect github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect - github.com/wlynxg/anet v0.0.4 // indirect + github.com/wlynxg/anet v0.0.5 // indirect go.opentelemetry.io/contrib/propagators/aws v1.21.1 // indirect go.opentelemetry.io/contrib/propagators/b3 v1.21.1 // indirect go.opentelemetry.io/contrib/propagators/jaeger v1.21.1 // indirect @@ -247,13 +247,13 @@ require ( go.opentelemetry.io/otel/metric v1.28.0 // indirect go.opentelemetry.io/proto/otlp v1.3.1 // indirect go.uber.org/atomic v1.11.0 // indirect - go.uber.org/mock v0.4.0 // indirect + go.uber.org/mock v0.5.0 // indirect go4.org v0.0.0-20230225012048-214862532bf5 // indirect - golang.org/x/net v0.28.0 // indirect - golang.org/x/oauth2 v0.21.0 // indirect - golang.org/x/term v0.24.0 // indirect - golang.org/x/text v0.18.0 // indirect - golang.org/x/tools v0.24.0 // indirect + golang.org/x/net v0.30.0 // indirect + golang.org/x/oauth2 v0.23.0 // indirect + golang.org/x/term v0.25.0 // indirect + golang.org/x/text v0.19.0 // indirect + golang.org/x/tools v0.26.0 // indirect golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect gonum.org/v1/gonum v0.15.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240617180043-68d350f18fd4 // indirect diff --git a/go.sum b/go.sum index ba427dd0f..9416f06d5 100644 --- a/go.sum +++ b/go.sum @@ -300,8 +300,8 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 h1:FKHo8hFI3A+7w0aUQuYXQ+6EN5stWmeY/AZqtM8xk9k= -github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= +github.com/google/pprof v0.0.0-20241017200806-017d972448fc h1:NGyrhhFhwvRAZg02jnYVg3GBQy0qGBKmFQJwaPmpmxs= +github.com/google/pprof v0.0.0-20241017200806-017d972448fc/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -490,8 +490,8 @@ github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQL 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.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= -github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= +github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM= @@ -524,10 +524,10 @@ github.com/libp2p/go-doh-resolver v0.4.0 h1:gUBa1f1XsPwtpE1du0O+nnZCUqtG7oYi7Bb+ github.com/libp2p/go-doh-resolver v0.4.0/go.mod h1:v1/jwsFusgsWIGX/c6vCRrnJ60x7bhTiq/fs2qt0cAg= github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8= github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= -github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= -github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.36.5 h1:DoABsaHO0VXwH6pwCs2F6XKAXWYjFMO4HFBoVxTnF9g= -github.com/libp2p/go-libp2p v0.36.5/go.mod h1:CpszAtXxHYOcyvB7K8rSHgnNlh21eKjYbEfLoMerbEI= +github.com/libp2p/go-flow-metrics v0.2.0 h1:EIZzjmeOE6c8Dav0sNv35vhZxATIXWZg6j/C08XmmDw= +github.com/libp2p/go-flow-metrics v0.2.0/go.mod h1:st3qqfu8+pMfh+9Mzqb2GTiwrAGjIPszEjZmtksN8Jc= +github.com/libp2p/go-libp2p v0.37.0 h1:8K3mcZgwTldydMCNOiNi/ZJrOB9BY+GlI3UxYzxBi9A= +github.com/libp2p/go-libp2p v0.37.0/go.mod h1:GOKmSN99scDuYGTwaTbQPR8Nt6dxrK3ue7OjW2NGDg4= github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94= github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= @@ -683,8 +683,8 @@ github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108 github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.20.0 h1:PE84V2mHqoT1sglvHc8ZdQtPcwmvvt29WLEEO3xmdZw= -github.com/onsi/ginkgo/v2 v2.20.0/go.mod h1:lG9ey2Z29hR41WMVthyJBGUBcBhGOtoPF2VFMvBXFCI= +github.com/onsi/ginkgo/v2 v2.20.2 h1:7NVCeyIWROIAheY21RLS+3j2bb52W0W82tkberYytp4= +github.com/onsi/ginkgo/v2 v2.20.2/go.mod h1:K9gyxPIlb+aIvnZ8bd9Ak+YP18w3APlR+5coaZoE2ag= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= @@ -707,15 +707,15 @@ github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 h1:1/WtZae0yGtPq+TI6+ github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9/go.mod h1:x3N5drFsm2uilKKuuYo6LdyD8vZAW55sH/9w+pbo1sw= github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= -github.com/pion/datachannel v1.5.8 h1:ph1P1NsGkazkjrvyMfhRBUAWMxugJjq2HfQifaOoSNo= -github.com/pion/datachannel v1.5.8/go.mod h1:PgmdpoaNBLX9HNzNClmdki4DYW5JtI7Yibu8QzbL3tI= +github.com/pion/datachannel v1.5.9 h1:LpIWAOYPyDrXtU+BW7X0Yt/vGtYxtXQ8ql7dFfYUVZA= +github.com/pion/datachannel v1.5.9/go.mod h1:kDUuk4CU4Uxp82NH4LQZbISULkX/HtzKa4P7ldf9izE= github.com/pion/dtls/v2 v2.2.7/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s= github.com/pion/dtls/v2 v2.2.12 h1:KP7H5/c1EiVAAKUmXyCzPiQe5+bCJrpOeKg/L05dunk= github.com/pion/dtls/v2 v2.2.12/go.mod h1:d9SYc9fch0CqK90mRk1dC7AkzzpwJj6u2GU3u+9pqFE= -github.com/pion/ice/v2 v2.3.34 h1:Ic1ppYCj4tUOcPAp76U6F3fVrlSw8A9JtRXLqw6BbUM= -github.com/pion/ice/v2 v2.3.34/go.mod h1:mBF7lnigdqgtB+YHkaY/Y6s6tsyRyo4u4rPGRuOjUBQ= -github.com/pion/interceptor v0.1.30 h1:au5rlVHsgmxNi+v/mjOPazbW1SHzfx7/hYOEYQnUcxA= -github.com/pion/interceptor v0.1.30/go.mod h1:RQuKT5HTdkP2Fi0cuOS5G5WNymTjzXaGF75J4k7z2nc= +github.com/pion/ice/v2 v2.3.36 h1:SopeXiVbbcooUg2EIR8sq4b13RQ8gzrkkldOVg+bBsc= +github.com/pion/ice/v2 v2.3.36/go.mod h1:mBF7lnigdqgtB+YHkaY/Y6s6tsyRyo4u4rPGRuOjUBQ= +github.com/pion/interceptor v0.1.37 h1:aRA8Zpab/wE7/c0O3fh1PqY0AJI3fCSEM5lRWJVorwI= +github.com/pion/interceptor v0.1.37/go.mod h1:JzxbJ4umVTlZAf+/utHzNesY8tmRkM2lVmkS82TTj8Y= github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY= github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms= github.com/pion/mdns v0.0.12 h1:CiMYlY+O0azojWDmxdNr7ADGrnZ+V6Ilfner+6mSVK8= @@ -747,8 +747,8 @@ github.com/pion/transport/v3 v3.0.7/go.mod h1:YleKiTZ4vqNxVwh77Z0zytYi7rXHl7j6uP github.com/pion/turn/v2 v2.1.3/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY= github.com/pion/turn/v2 v2.1.6 h1:Xr2niVsiPTB0FPtt+yAWKFUkU1eotQbGgpTIld4x1Gc= github.com/pion/turn/v2 v2.1.6/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY= -github.com/pion/webrtc/v3 v3.3.0 h1:Rf4u6n6U5t5sUxhYPQk/samzU/oDv7jk6BA5hyO2F9I= -github.com/pion/webrtc/v3 v3.3.0/go.mod h1:hVmrDJvwhEertRWObeb1xzulzHGeVUoPlWvxdGzcfU0= +github.com/pion/webrtc/v3 v3.3.4 h1:v2heQVnXTSqNRXcaFQVOhIOYkLMxOu1iJG8uy1djvkk= +github.com/pion/webrtc/v3 v3.3.4/go.mod h1:liNa+E1iwyzyXqNUwvoMRNQ10x8h8FOeJKL8RkIbamE= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -767,8 +767,8 @@ github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqr github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_golang v1.12.2/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_golang v1.13.0/go.mod h1:vTeo+zgvILHsnnj/39Ou/1fPN5nJFOEMgftOUOmlvYQ= -github.com/prometheus/client_golang v1.20.4 h1:Tgh3Yr67PaOv/uTqloMsCEdeuFTatm5zIq5+qNN23vI= -github.com/prometheus/client_golang v1.20.4/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= +github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y= +github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -782,8 +782,8 @@ github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9 github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/common v0.35.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= -github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc= -github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8= +github.com/prometheus/common v0.60.0 h1:+V9PAREWNvJMAuJ1x1BaWl9dewMW4YrHZQbx0sJNllA= +github.com/prometheus/common v0.60.0/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= @@ -795,12 +795,12 @@ github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0leargg github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/prometheus/statsd_exporter v0.22.7 h1:7Pji/i2GuhK6Lu7DHrtTkFmNBCudCPT1pX2CziuyQR0= github.com/prometheus/statsd_exporter v0.22.7/go.mod h1:N/TevpjkIh9ccs6nuzY3jQn9dFqnUakOjnEuMPJJJnI= -github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= -github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= -github.com/quic-go/quic-go v0.46.0 h1:uuwLClEEyk1DNvchH8uCByQVjo3yKL9opKulExNDs7Y= -github.com/quic-go/quic-go v0.46.0/go.mod h1:1dLehS7TIR64+vxGR70GDcatWTOtMX2PUtnKsjbTurI= -github.com/quic-go/webtransport-go v0.8.0 h1:HxSrwun11U+LlmwpgM1kEqIqH90IT4N8auv/cD7QFJg= -github.com/quic-go/webtransport-go v0.8.0/go.mod h1:N99tjprW432Ut5ONql/aUhSLT0YVSlwHohQsuac9WaM= +github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI= +github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg= +github.com/quic-go/quic-go v0.48.1 h1:y/8xmfWI9qmGTc+lBr4jKRUWLGSlSigv847ULJ4hYXA= +github.com/quic-go/quic-go v0.48.1/go.mod h1:yBgs3rWBOADpga7F+jJsb6Ybg1LSYiQvwWlLX+/6HMs= +github.com/quic-go/webtransport-go v0.8.1-0.20241018022711-4ac2c9250e66 h1:4WFk6u3sOT6pLa1kQ50ZVdm8BQFgJNA117cepZxtLIg= +github.com/quic-go/webtransport-go v0.8.1-0.20241018022711-4ac2c9250e66/go.mod h1:Vp72IJajgeOL6ddqrAhmp7IM9zbTcgkQxD/YdxrVwMw= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= @@ -930,8 +930,8 @@ github.com/whyrusleeping/go-sysinfo v0.0.0-20190219211824-4a357d4b90b1/go.mod h1 github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 h1:E9S12nwJwEOXe2d6gT6qxdvqMnNq+VnSsKPgm2ZZNds= github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7/go.mod h1:X2c0RVCI1eSUFI8eLcY3c0423ykwiUdxLJtkDvruhjI= github.com/wlynxg/anet v0.0.3/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA= -github.com/wlynxg/anet v0.0.4 h1:0de1OFQxnNqAu+x2FAKKCVIrnfGKQbs7FQz++tB0+Uw= -github.com/wlynxg/anet v0.0.4/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA= +github.com/wlynxg/anet v0.0.5 h1:J3VJGi1gvo0JwZ/P1/Yc/8p63SoW98B5dHkYDmpgvvU= +github.com/wlynxg/anet v0.0.5/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA= github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -989,13 +989,13 @@ go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw= go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= -go.uber.org/fx v1.22.2 h1:iPW+OPxv0G8w75OemJ1RAnTUrF55zOJlXlo1TbJ0Buw= -go.uber.org/fx v1.22.2/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU= +go.uber.org/fx v1.23.0 h1:lIr/gYWQGfTwGcSXWXu4vP5Ws6iqnNEIY+F/aFzCKTg= +go.uber.org/fx v1.23.0/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= -go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= -go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= +go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU= +go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= @@ -1032,8 +1032,8 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= -golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= -golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= +golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= +golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1044,8 +1044,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa h1:ELnwvuAXPNtPk1TJRuGkI9fDTwym6AYBu0qzT8AcHdI= -golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= +golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c h1:7dEasQXItcW1xKJ2+gg5VOiBnqWrJc+rq0DPKyvvdbY= +golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c/go.mod h1:NQtJDoLvd6faHhE7m4T/1IY708gDefGGjR/iUW8yQQ8= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1070,8 +1070,8 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= -golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= +golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1123,8 +1123,8 @@ golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= -golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= -golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4= +golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1134,8 +1134,8 @@ golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4Iltr golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs= -golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs= +golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1227,8 +1227,8 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= -golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= +golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -1237,8 +1237,8 @@ golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= -golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM= -golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8= +golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24= +golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1250,8 +1250,8 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= -golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= +golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1311,8 +1311,8 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= -golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= +golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ= +golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1417,8 +1417,8 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= -google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= +google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 9a14d2992..6b116c524 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -140,7 +140,7 @@ require ( github.com/leonklingele/grouper v1.1.2 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/libp2p/go-cidranger v1.1.0 // indirect - github.com/libp2p/go-libp2p v0.36.5 // indirect + github.com/libp2p/go-libp2p v0.37.0 // indirect github.com/libp2p/go-libp2p-asn-util v0.4.1 // indirect github.com/libp2p/go-libp2p-kad-dht v0.27.0 // indirect github.com/libp2p/go-libp2p-kbucket v0.6.4 // indirect @@ -182,9 +182,9 @@ require ( github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/polydawn/refmt v0.89.0 // indirect github.com/polyfloyd/go-errorlint v1.6.0 // indirect - github.com/prometheus/client_golang v1.20.4 // indirect + github.com/prometheus/client_golang v1.20.5 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.55.0 // indirect + github.com/prometheus/common v0.60.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/quasilyte/go-ruleguard v0.4.2 // indirect github.com/quasilyte/go-ruleguard/dsl v0.3.22 // indirect @@ -247,18 +247,18 @@ require ( go.uber.org/automaxprocs v1.5.3 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect - golang.org/x/crypto v0.27.0 // indirect - golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect + golang.org/x/crypto v0.28.0 // indirect + golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c // indirect golang.org/x/exp/typeparams v0.0.0-20240613232115-7f521ea00fb8 // indirect - golang.org/x/mod v0.20.0 // indirect - golang.org/x/net v0.28.0 // indirect + golang.org/x/mod v0.21.0 // indirect + golang.org/x/net v0.30.0 // indirect golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.25.0 // indirect - golang.org/x/term v0.24.0 // indirect - golang.org/x/text v0.18.0 // indirect - golang.org/x/tools v0.24.0 // indirect + golang.org/x/sys v0.26.0 // indirect + golang.org/x/term v0.25.0 // indirect + golang.org/x/text v0.19.0 // indirect + golang.org/x/tools v0.26.0 // indirect gonum.org/v1/gonum v0.15.0 // indirect - google.golang.org/protobuf v1.34.2 // indirect + google.golang.org/protobuf v1.35.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 34ac28c54..155da7cf9 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -232,8 +232,8 @@ github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= -github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 h1:FKHo8hFI3A+7w0aUQuYXQ+6EN5stWmeY/AZqtM8xk9k= -github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= +github.com/google/pprof v0.0.0-20241017200806-017d972448fc h1:NGyrhhFhwvRAZg02jnYVg3GBQy0qGBKmFQJwaPmpmxs= +github.com/google/pprof v0.0.0-20241017200806-017d972448fc/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -351,8 +351,8 @@ github.com/kisielk/errcheck v1.7.0/go.mod h1:1kLL+jV4e+CFfueBmI1dSK2ADDyQnlrnrY/ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kkHAIKE/contextcheck v1.1.5 h1:CdnJh63tcDe53vG+RebdpdXJTc9atMgGqdx8LXxiilg= github.com/kkHAIKE/contextcheck v1.1.5/go.mod h1:O930cpht4xb1YQpK+1+AgoM3mFsvxr7uyFptcnWTYUA= -github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= -github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= +github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM= github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/koron/go-ssdp v0.0.4 h1:1IDwrghSKYM7yLf7XCzbByg2sJ/JcNOZRXS2jczTwz0= @@ -382,10 +382,10 @@ github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6 github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38yPW7c= github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic= -github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= -github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.36.5 h1:DoABsaHO0VXwH6pwCs2F6XKAXWYjFMO4HFBoVxTnF9g= -github.com/libp2p/go-libp2p v0.36.5/go.mod h1:CpszAtXxHYOcyvB7K8rSHgnNlh21eKjYbEfLoMerbEI= +github.com/libp2p/go-flow-metrics v0.2.0 h1:EIZzjmeOE6c8Dav0sNv35vhZxATIXWZg6j/C08XmmDw= +github.com/libp2p/go-flow-metrics v0.2.0/go.mod h1:st3qqfu8+pMfh+9Mzqb2GTiwrAGjIPszEjZmtksN8Jc= +github.com/libp2p/go-libp2p v0.37.0 h1:8K3mcZgwTldydMCNOiNi/ZJrOB9BY+GlI3UxYzxBi9A= +github.com/libp2p/go-libp2p v0.37.0/go.mod h1:GOKmSN99scDuYGTwaTbQPR8Nt6dxrK3ue7OjW2NGDg4= github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94= github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= github.com/libp2p/go-libp2p-kad-dht v0.27.0 h1:1Ea32tVTPiAfaLpPMbaBWFJgbsi/JpMqC2YBuFdf32o= @@ -487,8 +487,8 @@ github.com/nunnatsa/ginkgolinter v0.16.2 h1:8iLqHIZvN4fTLDC0Ke9tbSZVcyVHoBs0HIbn github.com/nunnatsa/ginkgolinter v0.16.2/go.mod h1:4tWRinDN1FeJgU+iJANW/kz7xKN5nYRAOfJDQUS9dOQ= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= -github.com/onsi/ginkgo/v2 v2.20.0 h1:PE84V2mHqoT1sglvHc8ZdQtPcwmvvt29WLEEO3xmdZw= -github.com/onsi/ginkgo/v2 v2.20.0/go.mod h1:lG9ey2Z29hR41WMVthyJBGUBcBhGOtoPF2VFMvBXFCI= +github.com/onsi/ginkgo/v2 v2.20.2 h1:7NVCeyIWROIAheY21RLS+3j2bb52W0W82tkberYytp4= +github.com/onsi/ginkgo/v2 v2.20.2/go.mod h1:K9gyxPIlb+aIvnZ8bd9Ak+YP18w3APlR+5coaZoE2ag= github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k= github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY= github.com/opencontainers/runtime-spec v1.2.0 h1:z97+pHb3uELt/yiAWD691HNHQIF07bE7dzrbT927iTk= @@ -504,14 +504,14 @@ github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2D github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y= github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= -github.com/pion/datachannel v1.5.8 h1:ph1P1NsGkazkjrvyMfhRBUAWMxugJjq2HfQifaOoSNo= -github.com/pion/datachannel v1.5.8/go.mod h1:PgmdpoaNBLX9HNzNClmdki4DYW5JtI7Yibu8QzbL3tI= +github.com/pion/datachannel v1.5.9 h1:LpIWAOYPyDrXtU+BW7X0Yt/vGtYxtXQ8ql7dFfYUVZA= +github.com/pion/datachannel v1.5.9/go.mod h1:kDUuk4CU4Uxp82NH4LQZbISULkX/HtzKa4P7ldf9izE= github.com/pion/dtls/v2 v2.2.12 h1:KP7H5/c1EiVAAKUmXyCzPiQe5+bCJrpOeKg/L05dunk= github.com/pion/dtls/v2 v2.2.12/go.mod h1:d9SYc9fch0CqK90mRk1dC7AkzzpwJj6u2GU3u+9pqFE= -github.com/pion/ice/v2 v2.3.34 h1:Ic1ppYCj4tUOcPAp76U6F3fVrlSw8A9JtRXLqw6BbUM= -github.com/pion/ice/v2 v2.3.34/go.mod h1:mBF7lnigdqgtB+YHkaY/Y6s6tsyRyo4u4rPGRuOjUBQ= -github.com/pion/interceptor v0.1.30 h1:au5rlVHsgmxNi+v/mjOPazbW1SHzfx7/hYOEYQnUcxA= -github.com/pion/interceptor v0.1.30/go.mod h1:RQuKT5HTdkP2Fi0cuOS5G5WNymTjzXaGF75J4k7z2nc= +github.com/pion/ice/v2 v2.3.36 h1:SopeXiVbbcooUg2EIR8sq4b13RQ8gzrkkldOVg+bBsc= +github.com/pion/ice/v2 v2.3.36/go.mod h1:mBF7lnigdqgtB+YHkaY/Y6s6tsyRyo4u4rPGRuOjUBQ= +github.com/pion/interceptor v0.1.37 h1:aRA8Zpab/wE7/c0O3fh1PqY0AJI3fCSEM5lRWJVorwI= +github.com/pion/interceptor v0.1.37/go.mod h1:JzxbJ4umVTlZAf+/utHzNesY8tmRkM2lVmkS82TTj8Y= github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY= github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms= github.com/pion/mdns v0.0.12 h1:CiMYlY+O0azojWDmxdNr7ADGrnZ+V6Ilfner+6mSVK8= @@ -534,8 +534,8 @@ github.com/pion/transport/v2 v2.2.10 h1:ucLBLE8nuxiHfvkFKnkDQRYWYfp8ejf4YBOPfaQp github.com/pion/transport/v2 v2.2.10/go.mod h1:sq1kSLWs+cHW9E+2fJP95QudkzbK7wscs8yYgQToO5E= github.com/pion/turn/v2 v2.1.6 h1:Xr2niVsiPTB0FPtt+yAWKFUkU1eotQbGgpTIld4x1Gc= github.com/pion/turn/v2 v2.1.6/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY= -github.com/pion/webrtc/v3 v3.3.0 h1:Rf4u6n6U5t5sUxhYPQk/samzU/oDv7jk6BA5hyO2F9I= -github.com/pion/webrtc/v3 v3.3.0/go.mod h1:hVmrDJvwhEertRWObeb1xzulzHGeVUoPlWvxdGzcfU0= +github.com/pion/webrtc/v3 v3.3.4 h1:v2heQVnXTSqNRXcaFQVOhIOYkLMxOu1iJG8uy1djvkk= +github.com/pion/webrtc/v3 v3.3.4/go.mod h1:liNa+E1iwyzyXqNUwvoMRNQ10x8h8FOeJKL8RkIbamE= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -548,13 +548,13 @@ github.com/polyfloyd/go-errorlint v1.6.0 h1:tftWV9DE7txiFzPpztTAwyoRLKNj9gpVm2cg github.com/polyfloyd/go-errorlint v1.6.0/go.mod h1:HR7u8wuP1kb1NeN1zqTd1ZMlqUKPPHF+Id4vIPvDqVw= github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g= github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U= -github.com/prometheus/client_golang v1.20.4 h1:Tgh3Yr67PaOv/uTqloMsCEdeuFTatm5zIq5+qNN23vI= -github.com/prometheus/client_golang v1.20.4/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= +github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y= +github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= -github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc= -github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8= +github.com/prometheus/common v0.60.0 h1:+V9PAREWNvJMAuJ1x1BaWl9dewMW4YrHZQbx0sJNllA= +github.com/prometheus/common v0.60.0/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw= github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/quasilyte/go-ruleguard v0.4.2 h1:htXcXDK6/rO12kiTHKfHuqR4kr3Y4M0J0rOL6CH/BYs= @@ -567,12 +567,12 @@ github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727 h1:TCg2WBOl github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727/go.mod h1:rlzQ04UMyJXu/aOvhd8qT+hvDrFpiwqp8MRXDY9szc0= github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 h1:M8mH9eK4OUR4lu7Gd+PU1fV2/qnDNfzT635KRSObncs= github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567/go.mod h1:DWNGW8A4Y+GyBgPuaQJuWiy0XYftx4Xm/y5Jqk9I6VQ= -github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= -github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= -github.com/quic-go/quic-go v0.46.0 h1:uuwLClEEyk1DNvchH8uCByQVjo3yKL9opKulExNDs7Y= -github.com/quic-go/quic-go v0.46.0/go.mod h1:1dLehS7TIR64+vxGR70GDcatWTOtMX2PUtnKsjbTurI= -github.com/quic-go/webtransport-go v0.8.0 h1:HxSrwun11U+LlmwpgM1kEqIqH90IT4N8auv/cD7QFJg= -github.com/quic-go/webtransport-go v0.8.0/go.mod h1:N99tjprW432Ut5ONql/aUhSLT0YVSlwHohQsuac9WaM= +github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI= +github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg= +github.com/quic-go/quic-go v0.48.1 h1:y/8xmfWI9qmGTc+lBr4jKRUWLGSlSigv847ULJ4hYXA= +github.com/quic-go/quic-go v0.48.1/go.mod h1:yBgs3rWBOADpga7F+jJsb6Ybg1LSYiQvwWlLX+/6HMs= +github.com/quic-go/webtransport-go v0.8.1-0.20241018022711-4ac2c9250e66 h1:4WFk6u3sOT6pLa1kQ50ZVdm8BQFgJNA117cepZxtLIg= +github.com/quic-go/webtransport-go v0.8.1-0.20241018022711-4ac2c9250e66/go.mod h1:Vp72IJajgeOL6ddqrAhmp7IM9zbTcgkQxD/YdxrVwMw= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= @@ -691,8 +691,8 @@ github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc h1:BCPnHtcboa github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc/go.mod h1:r45hJU7yEoA81k6MWNhpMj/kms0n14dkzkxYHoB96UM= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 h1:EKhdznlJHPMoKr0XTrX+IlJs1LH3lyx2nfr1dOlZ79k= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc= -github.com/wlynxg/anet v0.0.4 h1:0de1OFQxnNqAu+x2FAKKCVIrnfGKQbs7FQz++tB0+Uw= -github.com/wlynxg/anet v0.0.4/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA= +github.com/wlynxg/anet v0.0.5 h1:J3VJGi1gvo0JwZ/P1/Yc/8p63SoW98B5dHkYDmpgvvU= +github.com/wlynxg/anet v0.0.5/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA= github.com/xen0n/gosmopolitan v1.2.2 h1:/p2KTnMzwRexIW8GlKawsTWOxn7UHA+jCMF/V8HHtvU= github.com/xen0n/gosmopolitan v1.2.2/go.mod h1:7XX7Mj61uLYrj0qmeN0zi7XDon9JRAEhYQqAPLVNTeg= github.com/yagipy/maintidx v1.0.0 h1:h5NvIsCz+nRDapQ0exNv4aJ0yXSI0420omVANTv3GJM= @@ -729,13 +729,13 @@ go.uber.org/automaxprocs v1.5.3 h1:kWazyxZUrS3Gs4qUpbwo5kEIMGe/DAvi5Z4tl2NW4j8= go.uber.org/automaxprocs v1.5.3/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0= go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw= go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= -go.uber.org/fx v1.22.2 h1:iPW+OPxv0G8w75OemJ1RAnTUrF55zOJlXlo1TbJ0Buw= -go.uber.org/fx v1.22.2/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU= +go.uber.org/fx v1.23.0 h1:lIr/gYWQGfTwGcSXWXu4vP5Ws6iqnNEIY+F/aFzCKTg= +go.uber.org/fx v1.23.0/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= -go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= -go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= +go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU= +go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= @@ -752,11 +752,11 @@ golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliY golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= -golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= -golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= +golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= +golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa h1:ELnwvuAXPNtPk1TJRuGkI9fDTwym6AYBu0qzT8AcHdI= -golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= +golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c h1:7dEasQXItcW1xKJ2+gg5VOiBnqWrJc+rq0DPKyvvdbY= +golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c/go.mod h1:NQtJDoLvd6faHhE7m4T/1IY708gDefGGjR/iUW8yQQ8= golang.org/x/exp/typeparams v0.0.0-20220428152302-39d4317da171/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/exp/typeparams v0.0.0-20230203172020-98cc5a0785f9/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/exp/typeparams v0.0.0-20240613232115-7f521ea00fb8 h1:+ZJmEdDFzH5H0CnzOrwgbH3elHctfTecW9X0k2tkn5M= @@ -782,8 +782,8 @@ golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.16.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= -golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= +golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -808,8 +808,8 @@ golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/net v0.16.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= -golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= -golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4= +golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -856,8 +856,8 @@ golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= -golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= +golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -871,8 +871,8 @@ golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= -golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM= -golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8= +golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24= +golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -885,8 +885,8 @@ golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= -golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= +golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= @@ -920,8 +920,8 @@ golang.org/x/tools v0.11.0/go.mod h1:anzJrxPjNtfgiYQYirP2CPGzGLxrH2u2QBhn6Bf3qY8 golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= golang.org/x/tools v0.19.0/go.mod h1:qoJWxmGSIBmAeriMx19ogtrEPrGtDbPK634QFIcLAhc= -golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= -golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= +golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ= +golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -947,8 +947,8 @@ google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= -google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= +google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= From ecb81c92221c8c563d7d245df193dc96163a76d0 Mon Sep 17 00:00:00 2001 From: Andrew Gillis <11790789+gammazero@users.noreply.github.com> Date: Fri, 25 Oct 2024 08:59:26 -1000 Subject: [PATCH 1200/1212] chore: upgrade to boxo v0.24.2 (#10559) * use boxo v0.24.2 * update changelog --- docs/changelogs/v0.32.md | 6 ++++++ docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- test/dependencies/go.mod | 2 +- test/dependencies/go.sum | 4 ++-- 7 files changed, 15 insertions(+), 9 deletions(-) diff --git a/docs/changelogs/v0.32.md b/docs/changelogs/v0.32.md index edeef6c5e..d6631d2c8 100644 --- a/docs/changelogs/v0.32.md +++ b/docs/changelogs/v0.32.md @@ -6,6 +6,8 @@ - [Overview](#overview) - [🔦 Highlights](#-highlights) + - [go-libp2p updates](#go-libp2p-updated) + - [update boxo](#update-boxo) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -21,6 +23,10 @@ - update `go-libp2p-kad-dht` to [v0.27.0](https://github.com/libp2p/go-libp2p-kad-dht/releases/tag/v0.27.0) - update `go-libp2p-pubsub` to [v0.12.0](https://github.com/libp2p/go-libp2p-pubsub/releases/tag/v0.12.0) +#### Update Boxo + +Update boxo to [v0.24.2](https://github.com/ipfs/boxo/releases/tag/v0.24.2). This includes a number of fixes and bitswap improvements. + ### 📝 Changelog ### 👨‍👩‍👧‍👦 Contributors diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 17fefed06..633457f2d 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.23 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.24.1 + github.com/ipfs/boxo v0.24.2 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.37.0 github.com/multiformats/go-multiaddr v0.13.0 diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index f09415bdc..077a67e6c 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -286,8 +286,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.24.1 h1:Y1n+8Q9lqeWLhEMZR2staJDnY80mtSWNR+hOhG3VtDo= -github.com/ipfs/boxo v0.24.1/go.mod h1:8mVcuQl2qqprmSOXHeqvvP4TezOobM92fKF3+ugpE58= +github.com/ipfs/boxo v0.24.2 h1:feLM6DY6CNI0uSG3TvP/Hv4PdM/fsekjqSCqKtifF0E= +github.com/ipfs/boxo v0.24.2/go.mod h1:Dt3TJjMZtF2QksMv2LC8pQlG9VQUiSV2DsHQzvDiroo= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= diff --git a/go.mod b/go.mod index 1c3e7914a..1699a1e1b 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,7 @@ require ( github.com/hashicorp/go-version v1.7.0 github.com/ipfs-shipyard/nopfs v0.0.12 github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c - github.com/ipfs/boxo v0.24.1 + github.com/ipfs/boxo v0.24.2 github.com/ipfs/go-block-format v0.2.0 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 diff --git a/go.sum b/go.sum index 9416f06d5..5c426d6c7 100644 --- a/go.sum +++ b/go.sum @@ -350,8 +350,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.24.1 h1:Y1n+8Q9lqeWLhEMZR2staJDnY80mtSWNR+hOhG3VtDo= -github.com/ipfs/boxo v0.24.1/go.mod h1:8mVcuQl2qqprmSOXHeqvvP4TezOobM92fKF3+ugpE58= +github.com/ipfs/boxo v0.24.2 h1:feLM6DY6CNI0uSG3TvP/Hv4PdM/fsekjqSCqKtifF0E= +github.com/ipfs/boxo v0.24.2/go.mod h1:Dt3TJjMZtF2QksMv2LC8pQlG9VQUiSV2DsHQzvDiroo= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 6b116c524..56ce421ae 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -110,7 +110,7 @@ require ( github.com/hexops/gotextdiff v1.0.3 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/ipfs/bbloom v0.0.4 // indirect - github.com/ipfs/boxo v0.24.1 // indirect + github.com/ipfs/boxo v0.24.2 // indirect github.com/ipfs/go-block-format v0.2.0 // indirect github.com/ipfs/go-cid v0.4.1 // indirect github.com/ipfs/go-datastore v0.6.0 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 155da7cf9..df758ace8 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -280,8 +280,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.24.1 h1:Y1n+8Q9lqeWLhEMZR2staJDnY80mtSWNR+hOhG3VtDo= -github.com/ipfs/boxo v0.24.1/go.mod h1:8mVcuQl2qqprmSOXHeqvvP4TezOobM92fKF3+ugpE58= +github.com/ipfs/boxo v0.24.2 h1:feLM6DY6CNI0uSG3TvP/Hv4PdM/fsekjqSCqKtifF0E= +github.com/ipfs/boxo v0.24.2/go.mod h1:Dt3TJjMZtF2QksMv2LC8pQlG9VQUiSV2DsHQzvDiroo= github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs= github.com/ipfs/go-block-format v0.2.0/go.mod h1:+jpL11nFx5A/SPpsoBn6Bzkra/zaArfSmsknbPMYgzM= github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= From 3134fd246e426034e7f288c4efde85856a79f6c8 Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Tue, 29 Oct 2024 17:37:33 -0400 Subject: [PATCH 1201/1212] feat(AutoTLS): opt-in WSS certs from p2p-forge at libp2p.direct (#10521) Co-authored-by: Marcin Rataj --- config/autotls.go | 30 +++++ config/config.go | 1 + core/node/groups.go | 21 +++ core/node/libp2p/addrs.go | 69 +++++++++- core/node/libp2p/transport.go | 15 ++- docs/changelogs/v0.32.md | 19 +-- docs/config.md | 111 ++++++++++++++- docs/examples/kubo-as-a-library/go.mod | 12 +- docs/examples/kubo-as-a-library/go.sum | 54 ++++++-- go.mod | 24 ++-- go.sum | 71 +++++++--- test/dependencies/go.mod | 45 +++++++ test/dependencies/go.sum | 178 +++++++++++++++++++++++++ 13 files changed, 598 insertions(+), 52 deletions(-) create mode 100644 config/autotls.go diff --git a/config/autotls.go b/config/autotls.go new file mode 100644 index 000000000..67ada23ab --- /dev/null +++ b/config/autotls.go @@ -0,0 +1,30 @@ +package config + +import p2pforge "github.com/ipshipyard/p2p-forge/client" + +// AutoTLS includes optional configuration of p2p-forge client of service +// for obtaining a domain and TLS certificate to improve connectivity for web +// browser clients. More: https://github.com/ipshipyard/p2p-forge#readme +type AutoTLS struct { + // Enables the p2p-forge feature + Enabled Flag `json:",omitempty"` + + // Optional override of the parent domain that will be used + DomainSuffix *OptionalString `json:",omitempty"` + + // Optional override of HTTP API that acts as ACME DNS-01 Challenge broker + RegistrationEndpoint *OptionalString `json:",omitempty"` + + // Optional Authorization token, used with private/test instances of p2p-forge + RegistrationToken *OptionalString `json:",omitempty"` + + // Optional override of CA ACME API used by p2p-forge system + CAEndpoint *OptionalString `json:",omitempty"` +} + +const ( + DefaultAutoTLSEnabled = false // experimental, opt-in for now (https://github.com/ipfs/kubo/pull/10521) + DefaultDomainSuffix = p2pforge.DefaultForgeDomain + DefaultRegistrationEndpoint = p2pforge.DefaultForgeEndpoint + DefaultCAEndpoint = p2pforge.DefaultCAEndpoint +) diff --git a/config/config.go b/config/config.go index 71365eb0b..6d91ff0f4 100644 --- a/config/config.go +++ b/config/config.go @@ -26,6 +26,7 @@ type Config struct { API API // local node's API settings Swarm SwarmConfig AutoNAT AutoNATConfig + AutoTLS AutoTLS Pubsub PubsubConfig Peering Peering DNS DNS diff --git a/core/node/groups.go b/core/node/groups.go index d806e2ef6..37bb1d6db 100644 --- a/core/node/groups.go +++ b/core/node/groups.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "strings" "time" "github.com/dustin/go-humanize" @@ -113,6 +114,7 @@ func LibP2P(bcfg *BuildCfg, cfg *config.Config, userResourceOverrides rcmgr.Part enableRelayTransport := cfg.Swarm.Transports.Network.Relay.WithDefault(true) // nolint enableRelayService := cfg.Swarm.RelayService.Enabled.WithDefault(enableRelayTransport) enableRelayClient := cfg.Swarm.RelayClient.Enabled.WithDefault(enableRelayTransport) + enableAutoTLS := cfg.AutoTLS.Enabled.WithDefault(config.DefaultAutoTLSEnabled) // Log error when relay subsystem could not be initialized due to missing dependency if !enableRelayTransport { @@ -123,6 +125,23 @@ func LibP2P(bcfg *BuildCfg, cfg *config.Config, userResourceOverrides rcmgr.Part logger.Fatal("Failed to enable `Swarm.RelayClient`, it requires `Swarm.Transports.Network.Relay` to be true.") } } + if enableAutoTLS { + if !cfg.Swarm.Transports.Network.Websocket.WithDefault(true) { + logger.Fatal("Invalid configuration: AutoTLS.Enabled=true requires Swarm.Transports.Network.Websocket to be true as well.") + } + + wssWildcard := fmt.Sprintf("/tls/sni/*.%s/ws", cfg.AutoTLS.DomainSuffix.WithDefault(config.DefaultDomainSuffix)) + wssWildcardPresent := false + for _, listener := range cfg.Addresses.Swarm { + if strings.Contains(listener, wssWildcard) { + wssWildcardPresent = true + break + } + } + if !wssWildcardPresent { + logger.Fatal(fmt.Sprintf("Invalid configuration: AutoTLS.Enabled=true requires a catch-all Addresses.Swarm listener ending with %q to be present, see https://github.com/ipfs/kubo/blob/master/docs/config.md#autotls", wssWildcard)) + } + } // Gather all the options opts := fx.Options( @@ -133,6 +152,8 @@ func LibP2P(bcfg *BuildCfg, cfg *config.Config, userResourceOverrides rcmgr.Part // Services (resource management) fx.Provide(libp2p.ResourceManager(bcfg.Repo.Path(), cfg.Swarm, userResourceOverrides)), + maybeProvide(libp2p.P2PForgeCertMgr(cfg.AutoTLS), enableAutoTLS), + maybeInvoke(libp2p.StartP2PAutoTLS, enableAutoTLS), 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/addrs.go b/core/node/libp2p/addrs.go index b287c20ff..c4c8bbe09 100644 --- a/core/node/libp2p/addrs.go +++ b/core/node/libp2p/addrs.go @@ -1,12 +1,22 @@ package libp2p import ( + "context" "fmt" + "os" + logging "github.com/ipfs/go-log" + version "github.com/ipfs/kubo" + "github.com/ipfs/kubo/config" + p2pforge "github.com/ipshipyard/p2p-forge/client" "github.com/libp2p/go-libp2p" + "github.com/libp2p/go-libp2p/core/host" p2pbhost "github.com/libp2p/go-libp2p/p2p/host/basic" ma "github.com/multiformats/go-multiaddr" mamask "github.com/whyrusleeping/multiaddr-filter" + + "github.com/caddyserver/certmagic" + "go.uber.org/fx" ) func AddrFilters(filters []string) func() (*ma.Filters, Libp2pOpts, error) { @@ -87,12 +97,26 @@ func makeAddrsFactory(announce []string, appendAnnouce []string, noAnnounce []st }, nil } -func AddrsFactory(announce []string, appendAnnouce []string, noAnnounce []string) func() (opts Libp2pOpts, err error) { - return func() (opts Libp2pOpts, err error) { - addrsFactory, err := makeAddrsFactory(announce, appendAnnouce, noAnnounce) +func AddrsFactory(announce []string, appendAnnouce []string, noAnnounce []string) interface{} { + return func(params struct { + fx.In + ForgeMgr *p2pforge.P2PForgeCertMgr `optional:"true"` + }, + ) (opts Libp2pOpts, err error) { + var addrsFactory p2pbhost.AddrsFactory + announceAddrsFactory, err := makeAddrsFactory(announce, appendAnnouce, noAnnounce) if err != nil { return opts, err } + if params.ForgeMgr == nil { + addrsFactory = announceAddrsFactory + } else { + addrsFactory = func(multiaddrs []ma.Multiaddr) []ma.Multiaddr { + forgeProcessing := params.ForgeMgr.AddressFactory()(multiaddrs) + annouceProcessing := announceAddrsFactory(forgeProcessing) + return annouceProcessing + } + } opts.Opts = append(opts.Opts, libp2p.AddrsFactory(addrsFactory)) return } @@ -107,3 +131,42 @@ func ListenOn(addresses []string) interface{} { } } } + +func P2PForgeCertMgr(cfg config.AutoTLS) interface{} { + return func() (*p2pforge.P2PForgeCertMgr, error) { + storagePath, err := config.Path("", "p2p-forge-certs") + if err != nil { + return nil, err + } + + forgeLogger := logging.Logger("autotls").Desugar() + certStorage := &certmagic.FileStorage{Path: storagePath} + certMgr, err := p2pforge.NewP2PForgeCertMgr( + p2pforge.WithLogger(forgeLogger.Sugar()), + p2pforge.WithForgeDomain(cfg.DomainSuffix.WithDefault(config.DefaultDomainSuffix)), + p2pforge.WithForgeRegistrationEndpoint(cfg.RegistrationEndpoint.WithDefault(config.DefaultRegistrationEndpoint)), + p2pforge.WithCAEndpoint(cfg.CAEndpoint.WithDefault(config.DefaultCAEndpoint)), + p2pforge.WithForgeAuth(cfg.RegistrationToken.WithDefault(os.Getenv(p2pforge.ForgeAuthEnv))), + p2pforge.WithUserAgent(version.GetUserAgentVersion()), + p2pforge.WithCertificateStorage(certStorage), + ) + if err != nil { + return nil, err + } + + return certMgr, nil + } +} + +func StartP2PAutoTLS(lc fx.Lifecycle, certMgr *p2pforge.P2PForgeCertMgr, h host.Host) { + lc.Append(fx.Hook{ + OnStart: func(ctx context.Context) error { + certMgr.ProvideHost(h) + return certMgr.Start() + }, + OnStop: func(ctx context.Context) error { + certMgr.Stop() + return nil + }, + }) +} diff --git a/core/node/libp2p/transport.go b/core/node/libp2p/transport.go index 6628adc32..61412ff4f 100644 --- a/core/node/libp2p/transport.go +++ b/core/node/libp2p/transport.go @@ -2,8 +2,8 @@ package libp2p import ( "fmt" - "github.com/ipfs/kubo/config" + "github.com/ipshipyard/p2p-forge/client" "github.com/libp2p/go-libp2p" "github.com/libp2p/go-libp2p/core/metrics" quic "github.com/libp2p/go-libp2p/p2p/transport/quic" @@ -16,12 +16,13 @@ import ( ) func Transports(tptConfig config.Transports) interface{} { - return func(pnet struct { + return func(params struct { fx.In - Fprint PNetFingerprint `optional:"true"` + Fprint PNetFingerprint `optional:"true"` + ForgeMgr *client.P2PForgeCertMgr `optional:"true"` }, ) (opts Libp2pOpts, err error) { - privateNetworkEnabled := pnet.Fprint != nil + privateNetworkEnabled := params.Fprint != nil if tptConfig.Network.TCP.WithDefault(true) { // TODO(9290): Make WithMetrics configurable @@ -29,7 +30,11 @@ func Transports(tptConfig config.Transports) interface{} { } if tptConfig.Network.Websocket.WithDefault(true) { - opts.Opts = append(opts.Opts, libp2p.Transport(websocket.New)) + if params.ForgeMgr == nil { + opts.Opts = append(opts.Opts, libp2p.Transport(websocket.New)) + } else { + opts.Opts = append(opts.Opts, libp2p.Transport(websocket.New, websocket.WithTLSConfig(params.ForgeMgr.TLSConfig()))) + } } if tptConfig.Network.QUIC.WithDefault(!privateNetworkEnabled) { diff --git a/docs/changelogs/v0.32.md b/docs/changelogs/v0.32.md index d6631d2c8..a8deab9e6 100644 --- a/docs/changelogs/v0.32.md +++ b/docs/changelogs/v0.32.md @@ -1,13 +1,13 @@ # Kubo changelog v0.32 -- [v0.31.0](#v0320) +- [v0.32.0](#v0310) ## v0.32.0 - [Overview](#overview) - [🔦 Highlights](#-highlights) - - [go-libp2p updates](#go-libp2p-updated) - - [update boxo](#update-boxo) + - [🎯 AutoTLS: Automatic Certificates for libp2p WebSockets via `libp2p.direct`](#-autotls-automatic-certificates-for-libp2p-websockets-via-libp2pdirect) + - [📦️ Boxo and go-libp2p updates](#-boxo-and-go-libp2p-updates) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -15,18 +15,21 @@ ### 🔦 Highlights +#### 🎯 AutoTLS: Automatic Certificates for libp2p WebSockets via `libp2p.direct` -#### go-libp2p updates +This release introduces an experimental feature that significantly improves how browsers can connect to Kubo node. +Opt-in configuration allows Kubo nodes to obtain CA-signed TLS certificates for [libp2p Secure WebSocket (WSS)](https://github.com/libp2p/specs/blob/master/websockets/README.md) connections automatically. +See [`AutoTLS`](https://github.com/ipfs/kubo/blob/master/docs/config.md#autotls) configuration for details how to enable it. We appreciate you testing and providing an early feedback in [kubo#10560](https://github.com/ipfs/kubo/issues/10560). + +#### 📦️ Boxo and go-libp2p updates + +- update `boxo` to [v0.24.2](https://github.com/ipfs/boxo/releases/tag/v0.24.2). This includes a number of fixes and bitswap improvements. - update `go-libp2p` to [v0.37.0](https://github.com/libp2p/go-libp2p/releases/tag/v0.37.0) - This update required removal of `Swarm.RelayService.MaxReservationsPerPeer` configuration option from Kubo. If you had it set, remove it from your configuration file. - update `go-libp2p-kad-dht` to [v0.27.0](https://github.com/libp2p/go-libp2p-kad-dht/releases/tag/v0.27.0) - update `go-libp2p-pubsub` to [v0.12.0](https://github.com/libp2p/go-libp2p-pubsub/releases/tag/v0.12.0) -#### Update Boxo - -Update boxo to [v0.24.2](https://github.com/ipfs/boxo/releases/tag/v0.24.2). This includes a number of fixes and bitswap improvements. - ### 📝 Changelog ### 👨‍👩‍👧‍👦 Contributors diff --git a/docs/config.md b/docs/config.md index 47264a868..f1efc40bb 100644 --- a/docs/config.md +++ b/docs/config.md @@ -27,6 +27,12 @@ config file at runtime. - [`AutoNAT.Throttle.GlobalLimit`](#autonatthrottlegloballimit) - [`AutoNAT.Throttle.PeerLimit`](#autonatthrottlepeerlimit) - [`AutoNAT.Throttle.Interval`](#autonatthrottleinterval) + - [`AutoTLS`](#autotls) + - [`AutoTLS.Enabled`](#autotlsenabled) + - [`AutoTLS.DomainSuffix`](#autotlsdomainsuffix) + - [`AutoTLS.RegistrationEndpoint`](#autotlsregistrationendpoint) + - [`AutoTLS.RegistrationToken`](#autotlsregistrationtoken) + - [`AutoTLS.CAEndpoint`](#autotlscaendpoint) - [`Bootstrap`](#bootstrap) - [`Datastore`](#datastore) - [`Datastore.StorageMax`](#datastorestoragemax) @@ -449,6 +455,109 @@ Default: 1 Minute Type: `duration` (when `0`/unset, the default value is used) +## `AutoTLS` + +> [!CAUTION] +> This is an **EXPERIMENTAL** opt-in feature and should not be used in production yet. +> Feel free to enable it and [report issues](https://github.com/ipfs/kubo/issues/new/choose) if you want to help with testing. +> Track progress in [kubo#10560](https://github.com/ipfs/kubo/issues/10560). + +AutoTLS feature enables publicly reachable Kubo nodes (those dialable from the public +internet) to automatically obtain a wildcard TLS certificate for a DNS name +unique to their PeerID at `*.[PeerID].libp2p.direct`. This enables direct +libp2p connections and retrieval of IPFS content from browsers [Secure Context](https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts) +using transports such as [Secure WebSockets](https://github.com/libp2p/specs/blob/master/websockets/README.md), +without requiring user to do any manual domain registration and ceritficate configuration. + +Under the hood, [p2p-forge] client uses public utility service at `libp2p.direct` as an [ACME DNS-01 Challenge](https://letsencrypt.org/docs/challenge-types/#dns-01-challenge) +broker enabling peer to obtain a wildcard TLS certificate tied to public key of their [PeerID](https://docs.libp2p.io/concepts/fundamentals/peers/#peer-id). + +By default, the certificates are requested from Let's Encrypt. Origin and rationale for this project can be found in [community.letsencrypt.org discussion](https://community.letsencrypt.org/t/feedback-on-raising-certificates-per-registered-domain-to-enable-peer-to-peer-networking/223003). + +> [!NOTE] +> Public good DNS and [p2p-forge] infrastructure at `libp2p.direct` is run by the team at [Interplanetary Shipyard](https://ipshipyard.com). +> +> + +[p2p-forge]: https://github.com/ipshipyard/p2p-forge + +Default: `{}` + +Type: `object` + +### `AutoTLS.Enabled` + +> [!CAUTION] +> This is an **EXPERIMENTAL** opt-in feature and should not be used in production yet. +> Feel free to enable it and [report issues](https://github.com/ipfs/kubo/issues/new/choose) if you want to help with testing. +> Track progress in [kubo#10560](https://github.com/ipfs/kubo/issues/10560). + +Enables AutoTLS feature to get DNS+TLS for [libp2p Secure WebSocket](https://github.com/libp2p/specs/blob/master/websockets/README.md) listeners defined in [`Addresses.Swarm`](#addressesswarm), such as `/ip4/0.0.0.0/tcp/4002/tls/sni/*.libp2p.direct/ws` and `/ip6/::/tcp/4002/tls/sni/*.libp2p.direct/ws`. + +If `.../tls/sni/*.libp2p.direct/ws` [multiaddr] is present in [`Addresses.Swarm`](#addressesswarm) +with SNI segment ending with [`AutoTLS.DomainSuffix`](#autotlsdomainsuffix), +Kubo will obtain and set up a trusted PKI TLS certificate for it, making it diallable from web browser's [Secure Contexts](https://w3c.github.io/webappsec-secure-contexts/). + +> [!IMPORTANT] +> Caveats: +> - Requires your Kubo node to be publicly diallable. +> - If you want to test this with a node that is behind a NAT and uses manual port forwarding or UPnP (`Swarm.DisableNatPortMap=false`), +> add catch-all `/ip4/0.0.0.0/tcp/4002/tls/sni/*.libp2p.direct/ws` and `/ip6/::/tcp/4002/tls/sni/*.libp2p.direct/ws` to [`Addresses.Swarm`](#addressesswarm) +> and **wait 5-15 minutes** for libp2p node to set up and learn about own public addresses via [AutoNAT](#autonat). +> - If your node is fresh and just started, the [p2p-forge] client may produce and log ERRORs during this time, but once a publicly diallable addresses are set up, a subsequent retry should be successful. +> - Requires manually updating [`Addresses.Swarm`](#addressesswarm) and opening a new port +> - A separate port has to be used instead of `4001` because we wait for TCP port sharing ([go-libp2p#2984](https://github.com/libp2p/go-libp2p/issues/2684)) to be implemented. +> - If you use manual port forwarding, make sure incoming connections to this additional port are allowed the same way `4001` ones already are. +> - The TLS certificate is used only for [libp2p WebSocket](https://github.com/libp2p/specs/blob/master/websockets/README.md) connections. +> - Right now, this is NOT used for hosting a [Gateway](#gateway) over HTTPS (that use case still requires manual TLS setup on reverse proxy, and your own domain). + +> [!TIP] +> Debugging can be enabled by setting environment variable `GOLOG_LOG_LEVEL="error,autotls=debug,p2p-forge/client=debug"` + +Default: `false` + +Type: `flag` + +### `AutoTLS.DomainSuffix` + +Optional override of the parent domain suffix that will be used in DNS+TLS+WebSockets multiaddrs generated by [p2p-forge] client. +Do not change this unless you self-host [p2p-forge]. + +Default: `libp2p.direct` (public good run by [Interplanetary Shipyard](https://ipshipyard.com)) + +Type: `optionalString` + +### `AutoTLS.RegistrationEndpoint` + +Optional override of [p2p-forge] HTTP registration API. +Do not change this unless you self-host [p2p-forge]. + +> [!IMPORTANT] +> The default endpoint performs [libp2p Peer ID Authentication over HTTP](https://github.com/libp2p/specs/blob/master/http/peer-id-auth.md) +> (prooving ownership of PeerID), probes if your Kubo node can correctly answer to a [libp2p Identify](https://github.com/libp2p/specs/tree/master/identify) query. +> This ensures only a correctly configured, publicly diallable Kubo can initiate [ACME DNS-01 challenge](https://letsencrypt.org/docs/challenge-types/#dns-01-challenge) for `peerid.libp2p.direct`. + +Default: `https://registration.libp2p.direct` (public good run by [Interplanetary Shipyard](https://ipshipyard.com)) + +Type: `optionalString` + +### `AutoTLS.RegistrationToken` + +Optional value for `Forge-Authorization` token sent with request to `RegistrationEndpoint` +(useful for private/self-hosted/test instances of [p2p-forge], unset by default). + +Default: `""` + +Type: `optionalString` + +### `AutoTLS.CAEndpoint` + +Optional override of CA ACME API used by [p2p-forge] system. + +Default: [certmagic.LetsEncryptProductionCA](https://pkg.go.dev/github.com/caddyserver/certmagic#pkg-constants) (see [community.letsencrypt.org discussion](https://community.letsencrypt.org/t/feedback-on-raising-certificates-per-registered-domain-to-enable-peer-to-peer-networking/223003)) + +Type: `optionalString` + ## `Bootstrap` Bootstrap is an array of [multiaddrs][multiaddr] of trusted nodes that your node connects to, to fetch other nodes of the network on startup. @@ -1835,7 +1944,7 @@ Type: `optionalInteger` #### `Swarm.RelayService.MaxReservationsPerPeer` -**REMOVED in kubo 0.32 due to removal from go-libp2p v0.37** +**REMOVED in kubo 0.32 due to [go-libp2p#2974](https://github.com/libp2p/go-libp2p/pull/2974)** #### `Swarm.RelayService.MaxReservationsPerIP` diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 633457f2d..6fed80107 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -23,6 +23,8 @@ require ( github.com/benbjohnson/clock v1.3.5 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver/v4 v4.0.0 // indirect + github.com/caddyserver/certmagic v0.21.4 // indirect + github.com/caddyserver/zerossl v0.1.3 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/ceramicnetwork/go-dag-jose v0.1.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect @@ -36,7 +38,7 @@ require ( github.com/coreos/go-systemd/v22 v22.5.0 // indirect github.com/crackcomm/go-gitignore v0.0.0-20231225121904-e25f5bc08668 // indirect github.com/cskr/pubsub v1.0.2 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect github.com/dgraph-io/badger v1.6.2 // indirect @@ -106,6 +108,7 @@ require ( github.com/ipld/go-car/v2 v2.14.2 // indirect github.com/ipld/go-codec-dagpb v1.6.0 // indirect github.com/ipld/go-ipld-prime v0.21.0 // indirect + github.com/ipshipyard/p2p-forge v0.0.0-20241028231853-f599f4803109 // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect github.com/jbenet/goprocess v0.1.4 // indirect @@ -114,6 +117,7 @@ require ( github.com/koron/go-ssdp v0.0.4 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect + github.com/libdns/libdns v0.2.2 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/libp2p/go-cidranger v1.1.0 // indirect github.com/libp2p/go-doh-resolver v0.4.0 // indirect @@ -134,6 +138,7 @@ require ( github.com/libp2p/zeroconf/v2 v2.2.0 // indirect github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect github.com/mattn/go-isatty v0.0.20 // indirect + github.com/mholt/acmez/v2 v2.0.3 // indirect github.com/miekg/dns v1.1.62 // indirect github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect @@ -173,7 +178,7 @@ require ( github.com/pion/turn/v2 v2.1.6 // indirect github.com/pion/webrtc/v3 v3.3.4 // indirect github.com/pkg/errors v0.9.1 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/polydawn/refmt v0.89.0 // indirect github.com/prometheus/client_golang v1.20.5 // indirect github.com/prometheus/client_model v0.6.1 // indirect @@ -187,7 +192,7 @@ require ( github.com/samber/lo v1.46.0 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/stretchr/testify v1.9.0 // indirect - github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect + github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect github.com/ucarion/urlpath v0.0.0-20200424170820-7ccc79b76bbb // indirect github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc // indirect github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11 // indirect @@ -196,6 +201,7 @@ require ( github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 // indirect github.com/wlynxg/anet v0.0.5 // indirect + github.com/zeebo/blake3 v0.2.4 // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.52.0 // indirect go.opentelemetry.io/otel v1.28.0 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 077a67e6c..774aa59fe 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -61,6 +61,10 @@ github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= +github.com/caddyserver/certmagic v0.21.4 h1:e7VobB8rffHv8ZZpSiZtEwnLDHUwLVYLWzWSa1FfKI0= +github.com/caddyserver/certmagic v0.21.4/go.mod h1:swUXjQ1T9ZtMv95qj7/InJvWLXURU85r+CfG0T+ZbDE= +github.com/caddyserver/zerossl v0.1.3 h1:onS+pxp3M8HnHpN5MMbOMyNjmTheJyWRaZYwn+YTAyA= +github.com/caddyserver/zerossl v0.1.3/go.mod h1:CxA0acn7oEGO6//4rtrRjYgEoa4MFw/XofZnrYwGqG4= github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -111,8 +115,9 @@ github.com/cskr/pubsub v1.0.2 h1:vlOzMhl6PFn60gRlTQQsIfVwaPB/B/8MziK8FhEPt/0= github.com/cskr/pubsub v1.0.2/go.mod h1:/8MzYXk/NJAz782G8RPkFzXTZVu63VotefPnR9TIRis= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c h1:pFUpOrbxDR6AkioZ1ySsx5yxlDQZ8stG2b88gTPxgJU= github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c/go.mod h1:6UhI8N9EjYm1c2odKpFpAYeR8dsBeM7PtzQhRgxRr9U= github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y= @@ -155,6 +160,7 @@ github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHk github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/gabriel-vasile/mimetype v1.4.4 h1:QjV6pZ7/XZ7ryI2KuyeEDE8wnh7fHP9YnQy+R0LnH8I= @@ -174,6 +180,7 @@ github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0= @@ -212,6 +219,8 @@ github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvq github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= @@ -227,6 +236,7 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ 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= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= @@ -238,6 +248,7 @@ github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXi github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20241017200806-017d972448fc h1:NGyrhhFhwvRAZg02jnYVg3GBQy0qGBKmFQJwaPmpmxs= github.com/google/pprof v0.0.0-20241017200806-017d972448fc/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= @@ -279,6 +290,7 @@ github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpO github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs-shipyard/nopfs v0.0.12 h1:mvwaoefDF5VI9jyvgWCmaoTJIJFAfrbyQV5fJz35hlk= github.com/ipfs-shipyard/nopfs v0.0.12/go.mod h1:mQyd0BElYI2gB/kq/Oue97obP4B3os4eBmgfPZ+hnrE= @@ -390,6 +402,8 @@ github.com/ipld/go-ipld-prime v0.21.0 h1:n4JmcpOlPDIxBcY037SVfpd1G+Sj1nKZah0m6QH github.com/ipld/go-ipld-prime v0.21.0/go.mod h1:3RLqy//ERg/y5oShXXdx5YIp50cFGOanyMctpPjsvxQ= github.com/ipld/go-ipld-prime/storage/bsadapter v0.0.0-20230102063945-1a409dc236dd h1:gMlw/MhNr2Wtp5RwGdsW23cs+yCuj9k2ON7i9MiJlRo= github.com/ipld/go-ipld-prime/storage/bsadapter v0.0.0-20230102063945-1a409dc236dd/go.mod h1:wZ8hH8UxeryOs4kJEJaiui/s00hDSbE37OKsL47g+Sw= +github.com/ipshipyard/p2p-forge v0.0.0-20241028231853-f599f4803109 h1:Od9XhliY3EzRDCd/H6fMQ225+DSaS+CT0daHjEwbZTM= +github.com/ipshipyard/p2p-forge v0.0.0-20241028231853-f599f4803109/go.mod h1:taPeh3PDSO8Ual0/N2tIOAUXPV8gZoPF3uPXoUyiq14= github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/jbenet/go-cienv v0.1.0 h1:Vc/s0QbQtoxX8MwwSLWWh+xNNZvM3Lw7NsTcHrvvhMc= @@ -435,6 +449,8 @@ github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/libdns/libdns v0.2.2 h1:O6ws7bAfRPaBsgAYt8MDe2HcNBGC29hkZ9MX2eUSX3s= +github.com/libdns/libdns v0.2.2/go.mod h1:4Bj9+5CQiNMVGf87wjX4CY3HQJypUHRuLvlsfsZqLWQ= github.com/libp2p/go-buffer-pool v0.0.1/go.mod h1:xtyIz9PMobb13WaxR6Zo1Pd1zXJKYg0a8KiIvDp3TzQ= github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM= github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= @@ -502,6 +518,8 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= +github.com/mholt/acmez/v2 v2.0.3 h1:CgDBlEwg3QBp6s45tPQmFIBrkRIkBT4rW4orMM6p4sw= +github.com/mholt/acmez/v2 v2.0.3/go.mod h1:pQ1ysaDeGrIMvJ9dfJMk5kJNkn7L2sb3UhyrX6Q91cw= github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= @@ -575,19 +593,23 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8m github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY= github.com/nxadm/tail v1.4.11/go.mod h1:OTaG3NK980DZzxbRq6lEuzgU+mug70nY11sMd4JXXHc= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= +github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= +github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= github.com/onsi/ginkgo/v2 v2.20.2 h1:7NVCeyIWROIAheY21RLS+3j2bb52W0W82tkberYytp4= github.com/onsi/ginkgo/v2 v2.20.2/go.mod h1:K9gyxPIlb+aIvnZ8bd9Ak+YP18w3APlR+5coaZoE2ag= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k= github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= @@ -653,8 +675,9 @@ github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsK github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/polydawn/refmt v0.0.0-20201211092308-30ac6d18308e/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= github.com/polydawn/refmt v0.89.0 h1:ADJTApkvkeBZsN0tBTx8QjpD9JkmxbKp0cxfr9qszm4= github.com/polydawn/refmt v0.89.0/go.mod h1:/zvteZs/GwLtCgZ4BL6CBsk9IKIlexP43ObX9AxTqTw= @@ -744,8 +767,10 @@ github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= @@ -753,8 +778,8 @@ github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXl github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= -github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= -github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= +github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d h1:vfofYNRScrDdvS342BElfbETmL1Aiz3i2t0zfRj16Hs= +github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d/go.mod h1:RRCYJbIwD5jmqPI9XoAFR0OcDxqUctll6zUj/+B4S48= github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c h1:u6SKchux2yDvFQnDHS3lPnIRmfVJ5Sxy3ao2SIdysLQ= github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM= @@ -795,6 +820,12 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/zeebo/assert v1.1.0 h1:hU1L1vLTHsnO8x8c9KAR5GmM5QscxHg5RNU5z5qbUWY= +github.com/zeebo/assert v1.1.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= +github.com/zeebo/blake3 v0.2.4 h1:KYQPkhpRtcqh0ssGYcKLG1JYvddkEA8QwCM/yBqhaZI= +github.com/zeebo/blake3 v0.2.4/go.mod h1:7eeQ6d2iXWRGF6npfaxl2CU+xy2Fjo2gxeyZGCRUjcE= +github.com/zeebo/pcg v1.0.1 h1:lyqfGeWiv4ahac6ttHs+I5hwtH/+1mrhlCtVNQM2kHo= +github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4= go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= @@ -933,13 +964,15 @@ golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210423184538-5f58ad60dda6/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= @@ -999,11 +1032,10 @@ golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7w 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= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1012,6 +1044,8 @@ golang.org/x/sys v0.0.0-20210426080607-c94f62235c83/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1083,6 +1117,7 @@ golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapK golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= @@ -1093,6 +1128,7 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da h1:noIWHXmPHxILtqtCOPIhSt0ABwskkZKjD3bXGnZGpNY= golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= gonum.org/v1/gonum v0.15.0 h1:2lYxjRbTYyxkJxlhC+LvJIx3SsANPdRybu1tGj9/OrQ= @@ -1160,6 +1196,8 @@ google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/go.mod b/go.mod index 1699a1e1b..ca181eea1 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,7 @@ require ( contrib.go.opencensus.io/exporter/prometheus v0.4.2 github.com/benbjohnson/clock v1.3.5 github.com/blang/semver/v4 v4.0.0 + github.com/caddyserver/certmagic v0.21.4 github.com/cenkalti/backoff/v4 v4.3.0 github.com/ceramicnetwork/go-dag-jose v0.1.0 github.com/cheggaaa/pb v1.0.29 @@ -48,6 +49,7 @@ require ( github.com/ipld/go-car/v2 v2.14.2 github.com/ipld/go-codec-dagpb v1.6.0 github.com/ipld/go-ipld-prime v0.21.0 + github.com/ipshipyard/p2p-forge v0.0.0-20241028231853-f599f4803109 github.com/jbenet/go-temp-err-catcher v0.1.0 github.com/jbenet/goprocess v0.1.4 github.com/julienschmidt/httprouter v1.3.0 @@ -72,8 +74,8 @@ require ( github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 github.com/prometheus/client_golang v1.20.5 github.com/stretchr/testify v1.9.0 - github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 - github.com/tidwall/gjson v1.14.4 + github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d + github.com/tidwall/gjson v1.16.0 github.com/tidwall/sjson v1.2.5 github.com/whyrusleeping/go-sysinfo v0.0.0-20190219211824-4a357d4b90b1 github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 @@ -102,7 +104,7 @@ require ( github.com/alecthomas/units v0.0.0-20240626203959-61d1e3462e30 // indirect github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/cespare/xxhash v1.1.0 // indirect + github.com/caddyserver/zerossl v0.1.3 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cockroachdb/errors v1.11.3 // indirect github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce // indirect @@ -112,13 +114,14 @@ require ( github.com/containerd/cgroups v1.1.0 // indirect github.com/crackcomm/go-gitignore v0.0.0-20231225121904-e25f5bc08668 // indirect github.com/cskr/pubsub v1.0.2 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect github.com/dgraph-io/badger v1.6.2 // indirect - github.com/dgraph-io/ristretto v0.0.2 // indirect + github.com/dgraph-io/ristretto v0.1.1 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/elastic/gosigar v0.14.3 // indirect + github.com/fatih/color v1.15.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/flynn/noise v1.1.0 // indirect github.com/francoispqt/gojay v1.2.13 // indirect @@ -131,6 +134,7 @@ require ( github.com/go-task/slim-sprig/v3 v3.0.0 // indirect github.com/godbus/dbus/v5 v5.1.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/glog v1.2.0 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/golang/snappy v0.0.4 // indirect @@ -162,6 +166,7 @@ require ( github.com/koron/go-ssdp v0.0.4 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect + github.com/libdns/libdns v0.2.2 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/libp2p/go-cidranger v1.1.0 // indirect github.com/libp2p/go-flow-metrics v0.2.0 // indirect @@ -177,8 +182,9 @@ require ( github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mattn/go-runewidth v0.0.4 // indirect + github.com/mattn/go-runewidth v0.0.15 // indirect github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect + github.com/mholt/acmez/v2 v2.0.3 // indirect github.com/miekg/dns v1.1.62 // indirect github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect @@ -211,7 +217,7 @@ require ( github.com/pion/turn/v2 v2.1.6 // indirect github.com/pion/webrtc/v3 v3.3.4 // indirect github.com/pkg/errors v0.9.1 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/polydawn/refmt v0.89.0 // indirect github.com/prometheus/client_model v0.6.1 // indirect github.com/prometheus/common v0.60.0 // indirect @@ -221,13 +227,14 @@ require ( github.com/quic-go/quic-go v0.48.1 // indirect github.com/quic-go/webtransport-go v0.8.1-0.20241018022711-4ac2c9250e66 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect + github.com/rivo/uniseg v0.4.4 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect github.com/rs/cors v1.10.1 // indirect github.com/samber/lo v1.46.0 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/texttheater/golang-levenshtein v1.0.1 // indirect github.com/tidwall/match v1.1.1 // indirect - github.com/tidwall/pretty v1.2.0 // indirect + github.com/tidwall/pretty v1.2.1 // indirect github.com/ucarion/urlpath v0.0.0-20200424170820-7ccc79b76bbb // indirect github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc // indirect github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11 // indirect @@ -235,6 +242,7 @@ require ( github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f // indirect github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect github.com/wlynxg/anet v0.0.5 // indirect + github.com/zeebo/blake3 v0.2.4 // indirect go.opentelemetry.io/contrib/propagators/aws v1.21.1 // indirect go.opentelemetry.io/contrib/propagators/b3 v1.21.1 // indirect go.opentelemetry.io/contrib/propagators/jaeger v1.21.1 // indirect diff --git a/go.sum b/go.sum index 5c426d6c7..2c513c5a5 100644 --- a/go.sum +++ b/go.sum @@ -51,7 +51,6 @@ github.com/DataDog/zstd v1.4.5 h1:EndNeuB0l9syBZhut0wns3gV1hL8zX8LIu6ZiVHWLIQ= github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= github.com/Jorropo/jsync v1.0.1 h1:6HgRolFZnsdfzRUj+ImB9og1JYOxQoReSywkHOGSaUU= github.com/Jorropo/jsync v1.0.1/go.mod h1:jCOZj3vrBCri3bSU3ErUYvevKlnbssrXeCivybS5ABQ= -github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= @@ -87,12 +86,15 @@ github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= +github.com/caddyserver/certmagic v0.21.4 h1:e7VobB8rffHv8ZZpSiZtEwnLDHUwLVYLWzWSa1FfKI0= +github.com/caddyserver/certmagic v0.21.4/go.mod h1:swUXjQ1T9ZtMv95qj7/InJvWLXURU85r+CfG0T+ZbDE= +github.com/caddyserver/zerossl v0.1.3 h1:onS+pxp3M8HnHpN5MMbOMyNjmTheJyWRaZYwn+YTAyA= +github.com/caddyserver/zerossl v0.1.3/go.mod h1:CxA0acn7oEGO6//4rtrRjYgEoa4MFw/XofZnrYwGqG4= github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/ceramicnetwork/go-dag-jose v0.1.0 h1:yJ/HVlfKpnD3LdYP03AHyTvbm3BpPiz2oZiOeReJRdU= github.com/ceramicnetwork/go-dag-jose v0.1.0/go.mod h1:qYA1nYt0X8u4XoMAVoOV3upUVKtrxy/I670Dg5F0wjI= -github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= @@ -142,8 +144,9 @@ github.com/cskr/pubsub v1.0.2 h1:vlOzMhl6PFn60gRlTQQsIfVwaPB/B/8MziK8FhEPt/0= github.com/cskr/pubsub v1.0.2/go.mod h1:/8MzYXk/NJAz782G8RPkFzXTZVu63VotefPnR9TIRis= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c h1:pFUpOrbxDR6AkioZ1ySsx5yxlDQZ8stG2b88gTPxgJU= github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c/go.mod h1:6UhI8N9EjYm1c2odKpFpAYeR8dsBeM7PtzQhRgxRr9U= github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y= @@ -153,8 +156,9 @@ github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3 github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= github.com/dgraph-io/badger v1.6.2 h1:mNw0qs90GVgGGWylh0umH5iag1j6n/PeJtNvL6KY/x8= github.com/dgraph-io/badger v1.6.2/go.mod h1:JW2yswe3V058sS0kZ2h/AXeDSqFjxnZcRrVH//y2UQE= -github.com/dgraph-io/ristretto v0.0.2 h1:a5WaUrDa0qm0YrAAS1tUykT5El3kt62KNZZeMxQn3po= github.com/dgraph-io/ristretto v0.0.2/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= +github.com/dgraph-io/ristretto v0.1.1 h1:6CWw5tJNgpegArSHpNHJKldNeq03FQCwYvfMVWajOK8= +github.com/dgraph-io/ristretto v0.1.1/go.mod h1:S1GPSBCYCIhmVNfcth17y2zZtQT6wzkzgwUve0VDWWA= 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/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= @@ -174,8 +178,9 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5 h1:BBso6MBKW8ncyZLv37o+KNyy0HrrHgfnOaGQC2qvN+A= github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5/go.mod h1:JpoxHjuQauoxiFMl1ie8Xc/7TfLuMZ5eOCONd1sUBHg= -github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= +github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= +github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= @@ -189,6 +194,7 @@ github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHk github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/gabriel-vasile/mimetype v1.4.4 h1:QjV6pZ7/XZ7ryI2KuyeEDE8wnh7fHP9YnQy+R0LnH8I= @@ -221,6 +227,7 @@ github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ4 github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0= @@ -235,6 +242,8 @@ github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXP github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/glog v1.2.0 h1:uCdmnmatrKCgMBlM4rMuJZWOkPDqdbZPnrMXDY4gI68= +github.com/golang/glog v1.2.0/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -300,6 +309,7 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20241017200806-017d972448fc h1:NGyrhhFhwvRAZg02jnYVg3GBQy0qGBKmFQJwaPmpmxs= github.com/google/pprof v0.0.0-20241017200806-017d972448fc/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= @@ -343,6 +353,7 @@ github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpO github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs-shipyard/nopfs v0.0.12 h1:mvwaoefDF5VI9jyvgWCmaoTJIJFAfrbyQV5fJz35hlk= github.com/ipfs-shipyard/nopfs v0.0.12/go.mod h1:mQyd0BElYI2gB/kq/Oue97obP4B3os4eBmgfPZ+hnrE= @@ -458,6 +469,8 @@ github.com/ipld/go-ipld-prime v0.21.0 h1:n4JmcpOlPDIxBcY037SVfpd1G+Sj1nKZah0m6QH github.com/ipld/go-ipld-prime v0.21.0/go.mod h1:3RLqy//ERg/y5oShXXdx5YIp50cFGOanyMctpPjsvxQ= github.com/ipld/go-ipld-prime/storage/bsadapter v0.0.0-20230102063945-1a409dc236dd h1:gMlw/MhNr2Wtp5RwGdsW23cs+yCuj9k2ON7i9MiJlRo= github.com/ipld/go-ipld-prime/storage/bsadapter v0.0.0-20230102063945-1a409dc236dd/go.mod h1:wZ8hH8UxeryOs4kJEJaiui/s00hDSbE37OKsL47g+Sw= +github.com/ipshipyard/p2p-forge v0.0.0-20241028231853-f599f4803109 h1:Od9XhliY3EzRDCd/H6fMQ225+DSaS+CT0daHjEwbZTM= +github.com/ipshipyard/p2p-forge v0.0.0-20241028231853-f599f4803109/go.mod h1:taPeh3PDSO8Ual0/N2tIOAUXPV8gZoPF3uPXoUyiq14= github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/jbenet/go-cienv v0.1.0 h1:Vc/s0QbQtoxX8MwwSLWWh+xNNZvM3Lw7NsTcHrvvhMc= @@ -514,6 +527,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/libdns/libdns v0.2.2 h1:O6ws7bAfRPaBsgAYt8MDe2HcNBGC29hkZ9MX2eUSX3s= +github.com/libdns/libdns v0.2.2/go.mod h1:4Bj9+5CQiNMVGf87wjX4CY3HQJypUHRuLvlsfsZqLWQ= github.com/libp2p/go-buffer-pool v0.0.1/go.mod h1:xtyIz9PMobb13WaxR6Zo1Pd1zXJKYg0a8KiIvDp3TzQ= github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM= github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= @@ -591,11 +606,14 @@ github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27k github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -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= +github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= +github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4= github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= +github.com/mholt/acmez/v2 v2.0.3 h1:CgDBlEwg3QBp6s45tPQmFIBrkRIkBT4rW4orMM6p4sw= +github.com/mholt/acmez/v2 v2.0.3/go.mod h1:pQ1ysaDeGrIMvJ9dfJMk5kJNkn7L2sb3UhyrX6Q91cw= github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= @@ -675,19 +693,23 @@ github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRW github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY= github.com/nxadm/tail v1.4.11/go.mod h1:OTaG3NK980DZzxbRq6lEuzgU+mug70nY11sMd4JXXHc= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= +github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= +github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= github.com/onsi/ginkgo/v2 v2.20.2 h1:7NVCeyIWROIAheY21RLS+3j2bb52W0W82tkberYytp4= github.com/onsi/ginkgo/v2 v2.20.2/go.mod h1:K9gyxPIlb+aIvnZ8bd9Ak+YP18w3APlR+5coaZoE2ag= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k= github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= @@ -754,8 +776,9 @@ github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/polydawn/refmt v0.0.0-20201211092308-30ac6d18308e/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= github.com/polydawn/refmt v0.89.0 h1:ADJTApkvkeBZsN0tBTx8QjpD9JkmxbKp0cxfr9qszm4= github.com/polydawn/refmt v0.89.0/go.mod h1:/zvteZs/GwLtCgZ4BL6CBsk9IKIlexP43ObX9AxTqTw= @@ -803,6 +826,9 @@ github.com/quic-go/webtransport-go v0.8.1-0.20241018022711-4ac2c9250e66 h1:4WFk6 github.com/quic-go/webtransport-go v0.8.1-0.20241018022711-4ac2c9250e66/go.mod h1:Vp72IJajgeOL6ddqrAhmp7IM9zbTcgkQxD/YdxrVwMw= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= +github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= @@ -872,9 +898,11 @@ github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= @@ -883,18 +911,19 @@ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsT github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/stvp/go-udp-testing v0.0.0-20201019212854-469649b16807/go.mod h1:7jxmlfBCDBXRzr0eAQJ48XC1hBu1np4CS5+cHEYfwpc= github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= -github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= -github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= +github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d h1:vfofYNRScrDdvS342BElfbETmL1Aiz3i2t0zfRj16Hs= +github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d/go.mod h1:RRCYJbIwD5jmqPI9XoAFR0OcDxqUctll6zUj/+B4S48= github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= github.com/texttheater/golang-levenshtein v1.0.1 h1:+cRNoVrfiwufQPhoMzB6N0Yf/Mqajr6t1lOv8GyGE2U= github.com/texttheater/golang-levenshtein v1.0.1/go.mod h1:PYAKrbF5sAiq9wd+H82hs7gNaen0CplQ9uvm6+enD/8= github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= -github.com/tidwall/gjson v1.14.4 h1:uo0p8EbA09J7RQaflQ1aBRffTR7xedD2bcIVSYxLnkM= -github.com/tidwall/gjson v1.14.4/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/gjson v1.16.0 h1:SyXa+dsSPpUlcwEDuKuEBJEz5vzTvOea+9rjyYodQFg= +github.com/tidwall/gjson v1.16.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= -github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= +github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c h1:u6SKchux2yDvFQnDHS3lPnIRmfVJ5Sxy3ao2SIdysLQ= @@ -940,6 +969,12 @@ github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/zeebo/assert v1.1.0 h1:hU1L1vLTHsnO8x8c9KAR5GmM5QscxHg5RNU5z5qbUWY= +github.com/zeebo/assert v1.1.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= +github.com/zeebo/blake3 v0.2.4 h1:KYQPkhpRtcqh0ssGYcKLG1JYvddkEA8QwCM/yBqhaZI= +github.com/zeebo/blake3 v0.2.4/go.mod h1:7eeQ6d2iXWRGF6npfaxl2CU+xy2Fjo2gxeyZGCRUjcE= +github.com/zeebo/pcg v1.0.1 h1:lyqfGeWiv4ahac6ttHs+I5hwtH/+1mrhlCtVNQM2kHo= +github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4= go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= @@ -1105,7 +1140,6 @@ golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= @@ -1113,9 +1147,11 @@ golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210423184538-5f58ad60dda6/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= @@ -1195,15 +1231,14 @@ golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1216,10 +1251,12 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220708085239-5a0f0661e09d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1307,6 +1344,7 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= @@ -1317,6 +1355,7 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da h1:noIWHXmPHxILtqtCOPIhSt0ABwskkZKjD3bXGnZGpNY= golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= gonum.org/v1/gonum v0.15.0 h1:2lYxjRbTYyxkJxlhC+LvJIx3SsANPdRybu1tGj9/OrQ= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 56ce421ae..80f598e62 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -39,6 +39,7 @@ require ( github.com/alingse/asasalint v0.0.11 // indirect github.com/ashanbrown/forbidigo v1.6.0 // indirect github.com/ashanbrown/makezero v1.1.1 // indirect + github.com/benbjohnson/clock v1.3.5 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bitfield/gotestdox v0.2.2 // indirect github.com/bkielbasa/cyclop v1.2.1 // indirect @@ -48,6 +49,8 @@ require ( github.com/breml/errchkjson v0.3.6 // indirect github.com/butuzov/ireturn v0.3.0 // indirect github.com/butuzov/mirror v1.2.0 // indirect + github.com/caddyserver/certmagic v0.21.4 // indirect + github.com/caddyserver/zerossl v0.1.3 // indirect github.com/catenacyber/perfsprint v0.7.1 // indirect github.com/ccojocar/zxcvbn-go v1.0.2 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect @@ -58,6 +61,7 @@ require ( github.com/curioswitch/go-reassign v0.2.0 // indirect github.com/daixiang0/gci v0.13.4 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect github.com/denis-tingaikin/go-header v0.5.0 // indirect github.com/dnephin/pflag v1.0.7 // indirect @@ -67,12 +71,15 @@ require ( github.com/fatih/color v1.17.0 // indirect github.com/fatih/structtag v1.2.0 // indirect github.com/firefart/nonamedreturns v1.0.5 // indirect + github.com/flynn/noise v1.1.0 // indirect + github.com/francoispqt/gojay v1.2.13 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/fzipp/gocyclo v0.6.0 // indirect github.com/ghostiam/protogetter v0.3.6 // indirect github.com/go-critic/go-critic v0.11.4 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect + github.com/go-task/slim-sprig/v3 v3.0.0 // indirect github.com/go-toolsmith/astcast v1.1.0 // indirect github.com/go-toolsmith/astcopy v1.1.0 // indirect github.com/go-toolsmith/astequal v1.2.0 // indirect @@ -94,6 +101,7 @@ require ( github.com/golangci/unconvert v0.0.0-20240309020433-c5143eacb3ed // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/gopacket v1.1.19 // indirect + github.com/google/pprof v0.0.0-20241017200806-017d972448fc // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/google/uuid v1.6.0 // indirect github.com/gordonklaus/ineffassign v0.1.0 // indirect @@ -108,6 +116,7 @@ require ( github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/hexops/gotextdiff v1.0.3 // indirect + github.com/huin/goupnp v1.3.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/ipfs/bbloom v0.0.4 // indirect github.com/ipfs/boxo v0.24.2 // indirect @@ -121,6 +130,9 @@ require ( github.com/ipfs/kubo v0.31.0 // indirect github.com/ipld/go-codec-dagpb v1.6.0 // indirect github.com/ipld/go-ipld-prime v0.21.0 // indirect + github.com/ipshipyard/p2p-forge v0.0.0-20241028231853-f599f4803109 // indirect + github.com/jackpal/go-nat-pmp v1.0.2 // indirect + github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect github.com/jbenet/goprocess v0.1.4 // indirect github.com/jgautheron/goconst v1.7.1 // indirect github.com/jingyugao/rowserrcheck v1.1.1 // indirect @@ -130,7 +142,9 @@ require ( github.com/karamaru-alpha/copyloopvar v1.1.0 // indirect github.com/kisielk/errcheck v1.7.0 // indirect github.com/kkHAIKE/contextcheck v1.1.5 // indirect + github.com/klauspost/compress v1.17.11 // indirect github.com/klauspost/cpuid/v2 v2.2.8 // indirect + github.com/koron/go-ssdp v0.0.4 // indirect github.com/kulti/thelper v0.6.3 // indirect github.com/kunwardeep/paralleltest v1.0.10 // indirect github.com/kyoh86/exportloopref v0.1.11 // indirect @@ -138,8 +152,10 @@ require ( github.com/ldez/gomoddirectives v0.2.4 // indirect github.com/ldez/tagliatelle v0.5.0 // indirect github.com/leonklingele/grouper v1.1.2 // indirect + github.com/libdns/libdns v0.2.2 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/libp2p/go-cidranger v1.1.0 // indirect + github.com/libp2p/go-flow-metrics v0.2.0 // indirect github.com/libp2p/go-libp2p v0.37.0 // indirect github.com/libp2p/go-libp2p-asn-util v0.4.1 // indirect github.com/libp2p/go-libp2p-kad-dht v0.27.0 // indirect @@ -147,6 +163,7 @@ require ( github.com/libp2p/go-libp2p-record v0.2.0 // indirect github.com/libp2p/go-libp2p-routing-helpers v0.7.4 // indirect github.com/libp2p/go-msgio v0.3.0 // indirect + github.com/libp2p/go-nat v0.2.0 // indirect github.com/libp2p/go-netroute v0.2.1 // indirect github.com/lufeee/execinquery v1.2.1 // indirect github.com/macabu/inamedparam v0.1.3 // indirect @@ -159,6 +176,7 @@ require ( github.com/mattn/go-runewidth v0.0.15 // indirect github.com/mattn/go-shellwords v1.0.12 // indirect github.com/mgechev/revive v1.3.9 // indirect + github.com/mholt/acmez/v2 v2.0.3 // indirect github.com/miekg/dns v1.1.62 // indirect github.com/minio/sha256-simd v1.0.1 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect @@ -168,6 +186,7 @@ require ( github.com/multiformats/go-base32 v0.1.0 // indirect github.com/multiformats/go-base36 v0.2.0 // indirect github.com/multiformats/go-multiaddr-dns v0.4.0 // indirect + github.com/multiformats/go-multiaddr-fmt v0.1.0 // indirect github.com/multiformats/go-multibase v0.2.0 // indirect github.com/multiformats/go-multicodec v0.9.0 // indirect github.com/multiformats/go-multistream v0.5.0 // indirect @@ -178,7 +197,25 @@ require ( github.com/nishanths/predeclared v0.2.2 // indirect github.com/nunnatsa/ginkgolinter v0.16.2 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect + github.com/onsi/ginkgo/v2 v2.20.2 // indirect + github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect github.com/pelletier/go-toml/v2 v2.2.2 // indirect + github.com/pion/datachannel v1.5.9 // indirect + github.com/pion/dtls/v2 v2.2.12 // indirect + github.com/pion/ice/v2 v2.3.36 // indirect + github.com/pion/interceptor v0.1.37 // indirect + github.com/pion/logging v0.2.2 // indirect + github.com/pion/mdns v0.0.12 // indirect + github.com/pion/randutil v0.1.0 // indirect + github.com/pion/rtcp v1.2.14 // indirect + github.com/pion/rtp v1.8.9 // indirect + github.com/pion/sctp v1.8.33 // indirect + github.com/pion/sdp/v3 v3.0.9 // indirect + github.com/pion/srtp/v2 v2.0.20 // indirect + github.com/pion/stun v0.6.1 // indirect + github.com/pion/transport/v2 v2.2.10 // indirect + github.com/pion/turn/v2 v2.1.6 // indirect + github.com/pion/webrtc/v3 v3.3.4 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/polydawn/refmt v0.89.0 // indirect github.com/polyfloyd/go-errorlint v1.6.0 // indirect @@ -191,6 +228,9 @@ require ( github.com/quasilyte/gogrep v0.5.0 // indirect github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727 // indirect github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 // indirect + github.com/quic-go/qpack v0.5.1 // indirect + github.com/quic-go/quic-go v0.48.1 // indirect + github.com/quic-go/webtransport-go v0.8.1-0.20241018022711-4ac2c9250e66 // indirect github.com/rivo/uniseg v0.4.7 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/ryancurrah/gomodguard v1.3.3 // indirect @@ -233,10 +273,12 @@ require ( github.com/uudashr/gocognit v1.1.3 // indirect github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc // indirect github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect + github.com/wlynxg/anet v0.0.5 // indirect github.com/xen0n/gosmopolitan v1.2.2 // indirect github.com/yagipy/maintidx v1.0.0 // indirect github.com/yeya24/promlinter v0.3.0 // indirect github.com/ykadowak/zerologlint v0.1.5 // indirect + github.com/zeebo/blake3 v0.2.4 // indirect gitlab.com/bosi/decorder v0.4.2 // indirect go-simpler.org/musttag v0.12.2 // indirect go-simpler.org/sloglint v0.7.2 // indirect @@ -245,6 +287,9 @@ require ( go.opentelemetry.io/otel/metric v1.28.0 // indirect go.opentelemetry.io/otel/trace v1.28.0 // indirect go.uber.org/automaxprocs v1.5.3 // indirect + go.uber.org/dig v1.18.0 // indirect + go.uber.org/fx v1.23.0 // indirect + go.uber.org/mock v0.5.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect golang.org/x/crypto v0.28.0 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index df758ace8..3f49a4a46 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -3,6 +3,14 @@ 4d63.com/gochecknoglobals v0.2.1 h1:1eiorGsgHOFOuoOiJDy2psSrQbRdIHrlge0IJIkUgDc= 4d63.com/gochecknoglobals v0.2.1/go.mod h1:KRE8wtJB3CXCsb1xy421JfTHIIbmT3U5ruxw2Qu8fSU= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.31.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.37.0/go.mod h1:TS1dMSSfndXH133OKGwekG838Om/cQT0BUHV3HcBgoo= +dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU= +dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU= +dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4= +dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU= +git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg= github.com/4meepo/tagalign v1.3.4 h1:P51VcvBnf04YkHzjfclN6BbsopfJR5rxs1n+5zHt+w8= github.com/4meepo/tagalign v1.3.4/go.mod h1:M+pnkHH2vG8+qhE5bVc/zeP7HS/j910Fwa9TUSyZVI0= github.com/Abirdcfly/dupword v0.0.14 h1:3U4ulkc8EUo+CaT105/GJ1BQwtgyj6+VaBVbAX11Ba8= @@ -41,6 +49,7 @@ github.com/alexkohler/prealloc v1.0.0 h1:Hbq0/3fJPQhNkN0dR95AVrr6R7tou91y0uHG5pO github.com/alexkohler/prealloc v1.0.0/go.mod h1:VetnK3dIgFBBKmg0YnD9F9x6Icjd+9cvfHR56wJVlKE= github.com/alingse/asasalint v0.0.11 h1:SFwnQXJ49Kx/1GghOFz1XGqHYKp21Kq1nHad/0WQRnw= github.com/alingse/asasalint v0.0.11/go.mod h1:nCaoMhw7a9kSJObvQyVzNTPBDbNpdocqrSP7t/cW5+I= +github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= github.com/ashanbrown/forbidigo v1.6.0 h1:D3aewfM37Yb3pxHujIPSpTf6oQk9sc9WZi8gerOIVIY= github.com/ashanbrown/forbidigo v1.6.0/go.mod h1:Y8j9jy9ZYAEHXdu723cUlraTqbzjKF1MUyfOKL+AjcU= github.com/ashanbrown/makezero v1.1.1 h1:iCQ87C0V0vSyO+M9E/FZYbu65auqH0lnsOkf5FcB28s= @@ -48,6 +57,7 @@ github.com/ashanbrown/makezero v1.1.1/go.mod h1:i1bJLCRSCHOcOa9Y6MyF2FTfMZMFdHvx github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o= github.com/benbjohnson/clock v1.3.5/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bitfield/gotestdox v0.2.2 h1:x6RcPAbBbErKLnapz1QeAlf3ospg8efBsedU93CDsnE= @@ -58,14 +68,20 @@ github.com/blizzy78/varnamelen v0.8.0 h1:oqSblyuQvFsW1hbBHh1zfwrKe3kcSj0rnXkKzsQ github.com/blizzy78/varnamelen v0.8.0/go.mod h1:V9TzQZ4fLJ1DSrjVDfl89H7aMnTvKkApdHeyESmyR7k= github.com/bombsimon/wsl/v4 v4.4.1 h1:jfUaCkN+aUpobrMO24zwyAMwMAV5eSziCkOKEauOLdw= github.com/bombsimon/wsl/v4 v4.4.1/go.mod h1:Xu/kDxGZTofQcDGCtQe9KCzhHphIe0fDuyWTxER9Feo= +github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= github.com/breml/bidichk v0.2.7 h1:dAkKQPLl/Qrk7hnP6P+E0xOodrq8Us7+U0o4UBOAlQY= github.com/breml/bidichk v0.2.7/go.mod h1:YodjipAGI9fGcYM7II6wFvGhdMYsC5pHDlGzqvEW3tQ= github.com/breml/errchkjson v0.3.6 h1:VLhVkqSBH96AvXEyclMR37rZslRrY2kcyq+31HCsVrA= github.com/breml/errchkjson v0.3.6/go.mod h1:jhSDoFheAF2RSDOlCfhHO9KqhZgAYLyvHe7bRCX8f/U= +github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= github.com/butuzov/ireturn v0.3.0 h1:hTjMqWw3y5JC3kpnC5vXmFJAWI/m31jaCYQqzkS6PL0= github.com/butuzov/ireturn v0.3.0/go.mod h1:A09nIiwiqzN/IoVo9ogpa0Hzi9fex1kd9PSD6edP5ZA= github.com/butuzov/mirror v1.2.0 h1:9YVK1qIjNspaqWutSv8gsge2e/Xpq1eqEkslEUHy5cs= github.com/butuzov/mirror v1.2.0/go.mod h1:DqZZDtzm42wIAIyHXeN8W/qb1EPlb9Qn/if9icBOpdQ= +github.com/caddyserver/certmagic v0.21.4 h1:e7VobB8rffHv8ZZpSiZtEwnLDHUwLVYLWzWSa1FfKI0= +github.com/caddyserver/certmagic v0.21.4/go.mod h1:swUXjQ1T9ZtMv95qj7/InJvWLXURU85r+CfG0T+ZbDE= +github.com/caddyserver/zerossl v0.1.3 h1:onS+pxp3M8HnHpN5MMbOMyNjmTheJyWRaZYwn+YTAyA= +github.com/caddyserver/zerossl v0.1.3/go.mod h1:CxA0acn7oEGO6//4rtrRjYgEoa4MFw/XofZnrYwGqG4= github.com/catenacyber/perfsprint v0.7.1 h1:PGW5G/Kxn+YrN04cRAZKC+ZuvlVwolYMrIyyTJ/rMmc= github.com/catenacyber/perfsprint v0.7.1/go.mod h1:/wclWYompEyjUD2FuIIDVKNkqz7IgBIWXIH3V0Zol50= github.com/ccojocar/zxcvbn-go v1.0.2 h1:na/czXU8RrhXO4EZme6eQJLR4PzcGsahsBOAwU6I3Vg= @@ -83,6 +99,8 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM= github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw= +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.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= @@ -111,6 +129,7 @@ github.com/dnephin/pflag v1.0.7 h1:oxONGlWxhmUct0YzKTgrpQv9AUA1wtPBn7zuSjJqptk= github.com/dnephin/pflag v1.0.7/go.mod h1:uxE91IoWURlOiTUIA8Mq5ZZkAv3dPUfZNaT80Zm7OQE= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/elastic/gosigar v0.14.3 h1:xwkKwPia+hSfg9GqrCUKYdId102m9qTJIIr7egmK/uo= @@ -131,20 +150,25 @@ github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4 github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94= github.com/firefart/nonamedreturns v1.0.5 h1:tM+Me2ZaXs8tfdDw3X6DOX++wMCOqzYUho6tUTYIdRA= github.com/firefart/nonamedreturns v1.0.5/go.mod h1:gHJjDqhGM4WyPt639SOZs+G89Ko7QKH5R5BhnO6xJhw= +github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/flynn/noise v1.1.0 h1:KjPQoQCEFdZDiP03phOvGi11+SVVhBG2wOWAorLsstg= github.com/flynn/noise v1.1.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag= github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk= github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/fzipp/gocyclo v0.6.0 h1:lsblElZG7d3ALtGMx9fmxeTKZaLLpU8mET09yN4BBLo= github.com/fzipp/gocyclo v0.6.0/go.mod h1:rXPyn8fnlpa0R2csP/31uerbiVBugk5whMdlyaLkLoA= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghostiam/protogetter v0.3.6 h1:R7qEWaSgFCsy20yYHNIJsU9ZOb8TziSRRxuAOTVKeOk= github.com/ghostiam/protogetter v0.3.6/go.mod h1:7lpeDnEJ1ZjL/YtyoN99ljO4z0pd3H0d18/t2dPBxHw= +github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/go-critic/go-critic v0.11.4 h1:O7kGOCx0NDIni4czrkRIXTnit0mkyKOCePh3My6OyEU= github.com/go-critic/go-critic v0.11.4/go.mod h1:2QAdo4iuLik5S9YG0rT4wcZ8QxwHYkrr6/2MWAiv/vc= +github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= @@ -184,14 +208,18 @@ github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofrs/flock v0.12.1 h1:MTLVXXHf8ekldpJk3AKicLij9MdwOWkZ+a/jHHZby9E= github.com/gofrs/flock v0.12.1/go.mod h1:9zxTsyu5xtJ9DK+1tFZyibEV7y3uwDxPPfbxeeHCoD0= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= @@ -216,6 +244,7 @@ github.com/golangci/revgrep v0.5.3 h1:3tL7c1XBMtWHHqVpS5ChmiAAoe4PF/d5+ULzV9sLAz github.com/golangci/revgrep v0.5.3/go.mod h1:U4R/s9dlXZsg8uJmaR1GrloUr14D7qDl8gi2iPXJH8k= github.com/golangci/unconvert v0.0.0-20240309020433-c5143eacb3ed h1:IURFTjxeTfNFP0hTEi1YKjB/ub8zkpaOqFFMApi2EAs= github.com/golangci/unconvert v0.0.0-20240309020433-c5143eacb3ed/go.mod h1:XLXN8bNw4CGRPaqgl3bv/lhz7bsGPh4/xSaMTbo2vkQ= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -230,15 +259,22 @@ github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= +github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20241017200806-017d972448fc h1:NGyrhhFhwvRAZg02jnYVg3GBQy0qGBKmFQJwaPmpmxs= github.com/google/pprof v0.0.0-20241017200806-017d972448fc/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= +github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c h1:7lF+Vz0LqiRidnzC1Oq86fpX1q/iEv2KJdrCtttYjT4= github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= @@ -258,6 +294,8 @@ github.com/gostaticanalysis/nilerr v0.1.1/go.mod h1:wZYb6YI5YAxxq0i1+VJbY0s2YONW github.com/gostaticanalysis/testutil v0.3.1-0.20210208050101-bfb5c8eec0e4/go.mod h1:D+FIZ+7OahH3ePw/izIEeH5I06eKs1IKI4Xr64/Am3M= github.com/gostaticanalysis/testutil v0.4.0 h1:nhdCmubdmDF6VEatUNjgUZBJKWRqugoISdUv3PPQgHY= github.com/gostaticanalysis/testutil v0.4.0/go.mod h1:bLIoPefWXrRi/ssLFWX1dx7Repi5x3CuviD3dgAZaBU= +github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -320,6 +358,8 @@ github.com/ipld/go-codec-dagpb v1.6.0 h1:9nYazfyu9B1p3NAgfVdpRco3Fs2nFC72DqVsMj6 github.com/ipld/go-codec-dagpb v1.6.0/go.mod h1:ANzFhfP2uMJxRBr8CE+WQWs5UsNa0pYtmKZ+agnUw9s= github.com/ipld/go-ipld-prime v0.21.0 h1:n4JmcpOlPDIxBcY037SVfpd1G+Sj1nKZah0m6QH9C2E= github.com/ipld/go-ipld-prime v0.21.0/go.mod h1:3RLqy//ERg/y5oShXXdx5YIp50cFGOanyMctpPjsvxQ= +github.com/ipshipyard/p2p-forge v0.0.0-20241028231853-f599f4803109 h1:Od9XhliY3EzRDCd/H6fMQ225+DSaS+CT0daHjEwbZTM= +github.com/ipshipyard/p2p-forge v0.0.0-20241028231853-f599f4803109/go.mod h1:taPeh3PDSO8Ual0/N2tIOAUXPV8gZoPF3uPXoUyiq14= github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA= @@ -331,6 +371,7 @@ github.com/jbenet/go-temp-err-catcher v0.1.0 h1:zpb3ZH6wIE8Shj2sKS+khgRvf7T7RABo github.com/jbenet/go-temp-err-catcher v0.1.0/go.mod h1:0kJRvmDZXNMIiJirNPEYfhpPwbGVtZVWC34vc5WLsDk= github.com/jbenet/goprocess v0.1.4 h1:DRGOFReOMqqDNXwW70QkacFW0YN9QnwLV0Vqk+3oU0o= github.com/jbenet/goprocess v0.1.4/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= +github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU= github.com/jgautheron/goconst v1.7.1 h1:VpdAG7Ca7yvvJk5n8dMwQhfEZJh95kl/Hl9S1OI5Jkk= github.com/jgautheron/goconst v1.7.1/go.mod h1:aAosetZ5zaeC/2EfMeRswtxUFBpe2Hr7HzkgX4fanO4= github.com/jingyugao/rowserrcheck v1.1.1 h1:zibz55j/MJtLsjP1OF4bSdgXxwL1b+Vn7Tjzq7gFzUs= @@ -339,6 +380,8 @@ github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af h1:KA9B github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af/go.mod h1:HEWGJkRDzjJY2sqdDwxccsGicWEf9BQOZsq2tV+xzM0= github.com/jjti/go-spancheck v0.6.2 h1:iYtoxqPMzHUPp7St+5yA8+cONdyXD3ug6KK15n7Pklk= github.com/jjti/go-spancheck v0.6.2/go.mod h1:+X7lvIrR5ZdUTkxFYqzJ0abr8Sb5LOo80uOhWNqIrYA= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julz/importas v0.1.0 h1:F78HnrsjY3cR7j0etXy5+TU1Zuy7Xt08X/1aJnH5xXY= @@ -358,9 +401,11 @@ github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZY github.com/koron/go-ssdp v0.0.4 h1:1IDwrghSKYM7yLf7XCzbByg2sJ/JcNOZRXS2jczTwz0= github.com/koron/go-ssdp v0.0.4/go.mod h1:oDXq+E5IL5q0U8uSBcoAXzTzInwy5lEgC91HoKtbmZk= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= @@ -378,6 +423,8 @@ github.com/ldez/tagliatelle v0.5.0 h1:epgfuYt9v0CG3fms0pEgIMNPuFf/LpPIfjk4kyqSio github.com/ldez/tagliatelle v0.5.0/go.mod h1:rj1HmWiL1MiKQuOONhd09iySTEkUuE/8+5jtPYz9xa4= github.com/leonklingele/grouper v1.1.2 h1:o1ARBDLOmmasUaNDesWqWCIFH3u7hoFlM84YrjT3mIY= github.com/leonklingele/grouper v1.1.2/go.mod h1:6D0M/HVkhs2yRKRFZUoGjeDy7EZTfFBE9gl4kjmIGkA= +github.com/libdns/libdns v0.2.2 h1:O6ws7bAfRPaBsgAYt8MDe2HcNBGC29hkZ9MX2eUSX3s= +github.com/libdns/libdns v0.2.2/go.mod h1:4Bj9+5CQiNMVGf87wjX4CY3HQJypUHRuLvlsfsZqLWQ= github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38yPW7c= @@ -410,10 +457,12 @@ github.com/libp2p/go-yamux/v4 v4.0.1 h1:FfDR4S1wj6Bw2Pqbc8Uz7pCxeRBPbwsBbEdfwiCy github.com/libp2p/go-yamux/v4 v4.0.1/go.mod h1:NWjl8ZTLOGlozrXSOZ/HlfG++39iKNnM5wwmtQP1YB4= github.com/lufeee/execinquery v1.2.1 h1:hf0Ems4SHcUGBxpGN7Jz78z1ppVkP/837ZlETPCEtOM= github.com/lufeee/execinquery v1.2.1/go.mod h1:EC7DrEKView09ocscGHC+apXMIaorh4xqSxS/dy8SbM= +github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= github.com/macabu/inamedparam v0.1.3 h1:2tk/phHkMlEL/1GNe/Yf6kkR/hkcUdAEY3L0hjYV1Mk= github.com/macabu/inamedparam v0.1.3/go.mod h1:93FLICAIk/quk7eaPPQvbzihUdn/QkGDwIZEoLtpH6I= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= +github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/maratori/testableexamples v1.0.0 h1:dU5alXRrD8WKSjOUnmJZuzdxWOEQ57+7s93SLMxb2vI= github.com/maratori/testableexamples v1.0.0/go.mod h1:4rhjL1n20TUTT4vdh3RDqSizKLyXp7K2u6HgraZCGzE= github.com/maratori/testpackage v1.1.1 h1:S58XVV5AD7HADMmD0fNnziNHqKvSdDuEKdPD1rNTU04= @@ -437,28 +486,38 @@ github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZ github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-shellwords v1.0.12 h1:M2zGm7EW6UQJvDeQxo4T51eKPurbeFbe8WtebGE2xrk= github.com/mattn/go-shellwords v1.0.12/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mgechev/revive v1.3.9 h1:18Y3R4a2USSBF+QZKFQwVkBROUda7uoBlkEuBD+YD1A= github.com/mgechev/revive v1.3.9/go.mod h1:+uxEIr5UH0TjXWHTno3xh4u7eg6jDpXKzQccA9UGhHU= +github.com/mholt/acmez/v2 v2.0.3 h1:CgDBlEwg3QBp6s45tPQmFIBrkRIkBT4rW4orMM6p4sw= +github.com/mholt/acmez/v2 v2.0.3/go.mod h1:pQ1ysaDeGrIMvJ9dfJMk5kJNkn7L2sb3UhyrX6Q91cw= +github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= github.com/miekg/dns v1.1.62 h1:cN8OuEF1/x5Rq6Np+h1epln8OiyPWV+lROx9LxcGgIQ= github.com/miekg/dns v1.1.62/go.mod h1:mvDlcItzm+br7MToIKqkglaGhlFMHJ9DTNNWONWXbNQ= github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b/go.mod h1:lxPUiZwKoFL8DUUmalo2yJJUCxbPKtm8OKfqr2/FTNU= github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc h1:PTfri+PuQmWDqERdnNMiD9ZejrlswWrCpBEZgWOiTrc= github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc/go.mod h1:cGKTAVKx4SxOuR/czcZ/E2RSJ3sfHs8FpHhQ5CWMf9s= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM= github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/moricho/tparallel v0.3.2 h1:odr8aZVFA3NZrNybggMkYO3rgPRcqjeQUlBBFVxKHTI= github.com/moricho/tparallel v0.3.2/go.mod h1:OQ+K3b4Ln3l2TZveGCywybl68glfLEwFGqvnjok8b+U= +github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/multiformats/go-base32 v0.1.0 h1:pVx9xoSPqEIQG8o+UbAe7DNi51oej1NtK+aGkbLYxPE= github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYgtWibDcT0rExnbI= github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0= github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4= +github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo= github.com/multiformats/go-multiaddr v0.13.0 h1:BCBzs61E3AGHcYYTv8dqRH43ZfyrqM8RXVPT8t13tLQ= github.com/multiformats/go-multiaddr v0.13.0/go.mod h1:sBXrNzucqkFJhvKOiwwLyqamGa/P5EIXNPLovyhQCII= github.com/multiformats/go-multiaddr-dns v0.4.0 h1:P76EJ3qzBXpUXZ3twdCDx/kvagMsNo0LMFXpyms/zgU= @@ -469,6 +528,7 @@ github.com/multiformats/go-multibase v0.2.0 h1:isdYCVLvksgWlMW9OZRYJEa9pZETFivnc github.com/multiformats/go-multibase v0.2.0/go.mod h1:bFBZX4lKCA/2lyOFSAoKH5SS6oPyjtnzK/XTFDPkNuk= github.com/multiformats/go-multicodec v0.9.0 h1:pb/dlPnzee/Sxv/j4PmkDRxCOi3hXTz3IbPKOXWJkmg= github.com/multiformats/go-multicodec v0.9.0/go.mod h1:L3QTQvMIaVBkXOXXtVmYE+LI16i14xuaojr/H7Ai54k= +github.com/multiformats/go-multihash v0.0.8/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= github.com/multiformats/go-multihash v0.2.3 h1:7Lyc8XfX/IY2jWb/gI7JP+o7JEq9hOa7BFvVU9RSh+U= github.com/multiformats/go-multihash v0.2.3/go.mod h1:dXgKXCXjBzdscBLk9JkjINiEsCKRVch90MdaGiKsvSM= github.com/multiformats/go-multistream v0.5.0 h1:5htLSLl7lvJk3xx3qT/8Zm9J4K8vEOf/QGkvOGQAyiE= @@ -479,6 +539,8 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/nakabonne/nestif v0.3.1 h1:wm28nZjhQY5HyYPx+weN3Q65k6ilSBxDb8v5S81B81U= github.com/nakabonne/nestif v0.3.1/go.mod h1:9EtoZochLn5iUprVDmDjqGKPofoUEBL8U4Ngq6aY7OE= +github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= +github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= github.com/nishanths/exhaustive v0.12.0 h1:vIY9sALmw6T/yxiASewa4TQcFsVYZQQRUQJhKRf3Swg= github.com/nishanths/exhaustive v0.12.0/go.mod h1:mEZ95wPIZW+x8kC4TgC+9YCUgiST7ecevsVDTgc2obs= github.com/nishanths/predeclared v0.2.2 h1:V2EPdZPliZymNAn79T8RkNApBjMmVKh5XRpLm/w98Vk= @@ -493,6 +555,7 @@ github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k= github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY= github.com/opencontainers/runtime-spec v1.2.0 h1:z97+pHb3uELt/yiAWD691HNHQIF07bE7dzrbT927iTk= github.com/opencontainers/runtime-spec v1.2.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= github.com/otiai10/copy v1.2.0/go.mod h1:rrF5dJ5F0t/EWSYODDu4j9/vEeYHMkc8jt0zJChqQWw= github.com/otiai10/copy v1.14.0 h1:dCI/t1iTdYGtkvCuBG2BgR6KZa83PTclw4U5n2wAllU= github.com/otiai10/copy v1.14.0/go.mod h1:ECfuL02W+/FkTWZWgQqXPWZgW9oeKCSQ5qVfSc4qc4w= @@ -506,6 +569,7 @@ github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6 github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= github.com/pion/datachannel v1.5.9 h1:LpIWAOYPyDrXtU+BW7X0Yt/vGtYxtXQ8ql7dFfYUVZA= github.com/pion/datachannel v1.5.9/go.mod h1:kDUuk4CU4Uxp82NH4LQZbISULkX/HtzKa4P7ldf9izE= +github.com/pion/dtls/v2 v2.2.7/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s= github.com/pion/dtls/v2 v2.2.12 h1:KP7H5/c1EiVAAKUmXyCzPiQe5+bCJrpOeKg/L05dunk= github.com/pion/dtls/v2 v2.2.12/go.mod h1:d9SYc9fch0CqK90mRk1dC7AkzzpwJj6u2GU3u+9pqFE= github.com/pion/ice/v2 v2.3.36 h1:SopeXiVbbcooUg2EIR8sq4b13RQ8gzrkkldOVg+bBsc= @@ -518,8 +582,10 @@ github.com/pion/mdns v0.0.12 h1:CiMYlY+O0azojWDmxdNr7ADGrnZ+V6Ilfner+6mSVK8= github.com/pion/mdns v0.0.12/go.mod h1:VExJjv8to/6Wqm1FXK+Ii/Z9tsVk/F5sD/N70cnYFbk= github.com/pion/randutil v0.1.0 h1:CFG1UdESneORglEsnimhUjf33Rwjubwj6xfiOXBa3mA= github.com/pion/randutil v0.1.0/go.mod h1:XcJrSMMbbMRhASFVOlj/5hQial/Y8oH/HVo7TBZq+j8= +github.com/pion/rtcp v1.2.12/go.mod h1:sn6qjxvnwyAkkPzPULIbVqSKI5Dv54Rv7VG0kNxh9L4= github.com/pion/rtcp v1.2.14 h1:KCkGV3vJ+4DAJmvP0vaQShsb0xkRfWkO540Gy102KyE= github.com/pion/rtcp v1.2.14/go.mod h1:sn6qjxvnwyAkkPzPULIbVqSKI5Dv54Rv7VG0kNxh9L4= +github.com/pion/rtp v1.8.3/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU= github.com/pion/rtp v1.8.9 h1:E2HX740TZKaqdcPmf4pw6ZZuG8u5RlMMt+l3dxeu6Wk= github.com/pion/rtp v1.8.9/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU= github.com/pion/sctp v1.8.33 h1:dSE4wX6uTJBcNm8+YlMg7lw1wqyKHggsP5uKbdj+NZw= @@ -530,8 +596,15 @@ github.com/pion/srtp/v2 v2.0.20 h1:HNNny4s+OUmG280ETrCdgFndp4ufx3/uy85EawYEhTk= github.com/pion/srtp/v2 v2.0.20/go.mod h1:0KJQjA99A6/a0DOVTu1PhDSw0CXF2jTkqOoMg3ODqdA= github.com/pion/stun v0.6.1 h1:8lp6YejULeHBF8NmV8e2787BogQhduZugh5PdhDyyN4= github.com/pion/stun v0.6.1/go.mod h1:/hO7APkX4hZKu/D0f2lHzNyvdkTGtIy3NDmLR7kSz/8= +github.com/pion/transport/v2 v2.2.1/go.mod h1:cXXWavvCnFF6McHTft3DWS9iic2Mftcz1Aq29pGcU5g= +github.com/pion/transport/v2 v2.2.3/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0= +github.com/pion/transport/v2 v2.2.4/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0= github.com/pion/transport/v2 v2.2.10 h1:ucLBLE8nuxiHfvkFKnkDQRYWYfp8ejf4YBOPfaQpw6Q= github.com/pion/transport/v2 v2.2.10/go.mod h1:sq1kSLWs+cHW9E+2fJP95QudkzbK7wscs8yYgQToO5E= +github.com/pion/transport/v3 v3.0.1/go.mod h1:UY7kiITrlMv7/IKgd5eTUcaahZx5oUN3l9SzK5f5xE0= +github.com/pion/transport/v3 v3.0.7 h1:iRbMH05BzSNwhILHoBoAPxoB9xQgOaJk+591KC9P1o0= +github.com/pion/transport/v3 v3.0.7/go.mod h1:YleKiTZ4vqNxVwh77Z0zytYi7rXHl7j6uPLGhhz9rwo= +github.com/pion/turn/v2 v2.1.3/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY= github.com/pion/turn/v2 v2.1.6 h1:Xr2niVsiPTB0FPtt+yAWKFUkU1eotQbGgpTIld4x1Gc= github.com/pion/turn/v2 v2.1.6/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY= github.com/pion/webrtc/v3 v3.3.4 h1:v2heQVnXTSqNRXcaFQVOhIOYkLMxOu1iJG8uy1djvkk= @@ -548,13 +621,17 @@ github.com/polyfloyd/go-errorlint v1.6.0 h1:tftWV9DE7txiFzPpztTAwyoRLKNj9gpVm2cg github.com/polyfloyd/go-errorlint v1.6.0/go.mod h1:HR7u8wuP1kb1NeN1zqTd1ZMlqUKPPHF+Id4vIPvDqVw= github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g= github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U= +github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y= github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= +github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.60.0 h1:+V9PAREWNvJMAuJ1x1BaWl9dewMW4YrHZQbx0sJNllA= github.com/prometheus/common v0.60.0/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw= +github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/quasilyte/go-ruleguard v0.4.2 h1:htXcXDK6/rO12kiTHKfHuqR4kr3Y4M0J0rOL6CH/BYs= @@ -581,6 +658,7 @@ github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUc github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= @@ -604,11 +682,32 @@ github.com/sashamelentyev/usestdlibvars v1.27.0 h1:t/3jZpSXtRPRf2xr0m63i32Zrusyu github.com/sashamelentyev/usestdlibvars v1.27.0/go.mod h1:9nl0jgOfHKWNFS43Ojw0i7aRoS4j6EBye3YBhmAIRF8= github.com/securego/gosec/v2 v2.20.1-0.20240820084340-81cda2f91fbe h1:exdneYmXwZ4+VaIWv9mQ47uIHkTQSN50DYdCjXJ1cdQ= github.com/securego/gosec/v2 v2.20.1-0.20240820084340-81cda2f91fbe/go.mod h1:iyeMMRw8QEmueUSZ2VqmkQMiDyDcobfPnG00CV/NWdE= +github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c h1:W65qqJCIOVP4jpqPQ0YvHYKwcMEMVWIzWC5iNQQfBTU= github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c/go.mod h1:/PevMnwAxekIXwN8qQyfc5gl2NlkB3CQlkizAbOkeBs= +github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY= +github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM= +github.com/shurcooL/github_flavored_markdown v0.0.0-20181002035957-2122de532470/go.mod h1:2dOwnU2uBioM+SGy2aZoq1f/Sd1l9OkAeAUvjSyvgU0= github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ= +github.com/shurcooL/gofontwoff v0.0.0-20180329035133-29b52fc0a18d/go.mod h1:05UtEgK5zq39gLST6uB0cf3NEHjETfB4Fgr3Gx5R9Vw= +github.com/shurcooL/gopherjslib v0.0.0-20160914041154-feb6d3990c2c/go.mod h1:8d3azKNyqcHP1GaQE/c6dDgjkgSx2BZ4IoEi4F1reUI= +github.com/shurcooL/highlight_diff v0.0.0-20170515013008-09bb4053de1b/go.mod h1:ZpfEhSmds4ytuByIcDnOLkTHGUI6KNqRNPDLHDk+mUU= +github.com/shurcooL/highlight_go v0.0.0-20181028180052-98c3abbbae20/go.mod h1:UDKB5a1T23gOMUJrI+uSuH0VRDStOiUVSjBTRDVBVag= +github.com/shurcooL/home v0.0.0-20181020052607-80b7ffcb30f9/go.mod h1:+rgNQw2P9ARFAs37qieuu7ohDNQ3gds9msbT2yn85sg= +github.com/shurcooL/htmlg v0.0.0-20170918183704-d01228ac9e50/go.mod h1:zPn1wHpTIePGnXSHpsVPWEktKXHr6+SS6x/IKRb7cpw= +github.com/shurcooL/httperror v0.0.0-20170206035902-86b7830d14cc/go.mod h1:aYMfkZ6DWSJPJ6c4Wwz3QtW22G7mf/PEgaB9k/ik5+Y= +github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= +github.com/shurcooL/httpgzip v0.0.0-20180522190206-b1c53ac65af9/go.mod h1:919LwcH0M7/W4fcZ0/jy0qGght1GIhqyS/EgWGH2j5Q= +github.com/shurcooL/issues v0.0.0-20181008053335-6292fdc1e191/go.mod h1:e2qWDig5bLteJ4fwvDAc2NHzqFEthkqn7aOZAOpj+PQ= +github.com/shurcooL/issuesapp v0.0.0-20180602232740-048589ce2241/go.mod h1:NPpHK2TI7iSaM0buivtFUc9offApnI0Alt/K8hcHy0I= +github.com/shurcooL/notifications v0.0.0-20181007000457-627ab5aea122/go.mod h1:b5uSkrEVM1jQUspwbixRBhaIjIzL2xazXp6kntxYle0= +github.com/shurcooL/octicon v0.0.0-20181028054416-fa4f57f9efb2/go.mod h1:eWdoE5JD4R5UVWDucdOPg1g2fqQRq78IQa9zlOV1vpQ= +github.com/shurcooL/reactions v0.0.0-20181006231557-f2e0b4ca5b82/go.mod h1:TCR1lToEk4d2s07G3XGfz2QrgHXg4RJBvjrOozvoWfk= +github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYEDaXHZDBsXlPCDqdhQuJkuw4NOtaxYe3xii4= +github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/sivchari/containedctx v1.0.3 h1:x+etemjbsh2fB5ewm5FeLNi5bUjK0V8n0RB+Wwfd0XE= @@ -621,10 +720,12 @@ github.com/smartystreets/goconvey v1.7.2 h1:9RBaZCeXEQ3UselpuwUQHltGVXvdwm6cv1hg github.com/smartystreets/goconvey v1.7.2/go.mod h1:Vw0tHAZW6lzCRk3xgdin6fKYcG+G3Pg9vgXWeJpQFMM= github.com/sonatard/noctx v0.0.2 h1:L7Dz4De2zDQhW8S0t+KUjY0MAQJd6SgVwhzNIc4ok00= github.com/sonatard/noctx v0.0.2/go.mod h1:kzFz+CzWSjQ2OzIm46uJZoXuBpa2+0y3T36U18dWqIo= +github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE= github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= github.com/sourcegraph/go-diff v0.7.0 h1:9uLlrd5T46OXs5qpp8L/MTltk0zikUGi0sNNyCpA8G0= github.com/sourcegraph/go-diff v0.7.0/go.mod h1:iBszgVvyxdc8SFZ7gm69go2KDdt3ag071iBaWPF6cjs= +github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= @@ -646,6 +747,7 @@ github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSS github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= @@ -653,11 +755,13 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= +github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= github.com/tdakkota/asciicheck v0.2.0 h1:o8jvnUANo0qXtnslk2d3nMKTFNlOnJjRrNcj0j9qkHM= github.com/tdakkota/asciicheck v0.2.0/go.mod h1:Qb7Y9EgjCLJGup51gDHFzbI08/gbGhL/UVhYIPWG2rg= github.com/tenntenn/modver v1.0.1 h1:2klLppGhDgzJrScMpkj9Ujy3rXPUspSjAcev9tSEBgA= @@ -683,6 +787,8 @@ github.com/urfave/cli v1.22.16 h1:MH0k6uJxdwdeWQTwhSO42Pwr4YLrNLwBtg1MRgTqPdQ= github.com/urfave/cli v1.22.16/go.mod h1:EeJR6BKodywf4zciqrdw6hpCPk68JO9z5LazXZMn5Po= github.com/uudashr/gocognit v1.1.3 h1:l+a111VcDbKfynh+airAy/DJQKaXh2m9vkoysMPSZyM= github.com/uudashr/gocognit v1.1.3/go.mod h1:aKH8/e8xbTRBwjbCkwZ8qt4l2EpKXl31KMHgSS+lZ2U= +github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU= +github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM= github.com/warpfork/go-testmark v0.12.1 h1:rMgCpJfwy1sJ50x0M0NgyphxYYPMOODIJHhsXyEHU0s= github.com/warpfork/go-testmark v0.12.1/go.mod h1:kHwy7wfvGSPh1rQJYKayD4AbtNaeyZdcGi9tNJTaa5Y= github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0 h1:GDDkbFiaK8jsSDJfjId/PEGEShv6ugrt4kYsC5UIDaQ= @@ -691,6 +797,7 @@ github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc h1:BCPnHtcboa github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc/go.mod h1:r45hJU7yEoA81k6MWNhpMj/kms0n14dkzkxYHoB96UM= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 h1:EKhdznlJHPMoKr0XTrX+IlJs1LH3lyx2nfr1dOlZ79k= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc= +github.com/wlynxg/anet v0.0.3/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA= github.com/wlynxg/anet v0.0.5 h1:J3VJGi1gvo0JwZ/P1/Yc/8p63SoW98B5dHkYDmpgvvU= github.com/wlynxg/anet v0.0.5/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA= github.com/xen0n/gosmopolitan v1.2.2 h1:/p2KTnMzwRexIW8GlKawsTWOxn7UHA+jCMF/V8HHtvU= @@ -708,6 +815,12 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/zeebo/assert v1.1.0 h1:hU1L1vLTHsnO8x8c9KAR5GmM5QscxHg5RNU5z5qbUWY= +github.com/zeebo/assert v1.1.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= +github.com/zeebo/blake3 v0.2.4 h1:KYQPkhpRtcqh0ssGYcKLG1JYvddkEA8QwCM/yBqhaZI= +github.com/zeebo/blake3 v0.2.4/go.mod h1:7eeQ6d2iXWRGF6npfaxl2CU+xy2Fjo2gxeyZGCRUjcE= +github.com/zeebo/pcg v1.0.1 h1:lyqfGeWiv4ahac6ttHs+I5hwtH/+1mrhlCtVNQM2kHo= +github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4= gitlab.com/bosi/decorder v0.4.2 h1:qbQaV3zgwnBZ4zPMhGLW4KZe7A7NwxEhJx39R3shffo= gitlab.com/bosi/decorder v0.4.2/go.mod h1:muuhHoaJkA9QLcYHq4Mj8FJUwDZ+EirSHRiaTcTf6T8= go-simpler.org/assert v0.9.0 h1:PfpmcSvL7yAnWyChSjOz6Sp6m9j5lyK8Ok9pEL31YkQ= @@ -716,6 +829,7 @@ go-simpler.org/musttag v0.12.2 h1:J7lRc2ysXOq7eM8rwaTYnNrHd5JwjppzB6mScysB2Cs= go-simpler.org/musttag v0.12.2/go.mod h1:uN1DVIasMTQKk6XSik7yrJoEysGtR2GRqvWnI9S7TYM= go-simpler.org/sloglint v0.7.2 h1:Wc9Em/Zeuu7JYpl+oKoYOsQSy2X560aVueCW/m6IijY= go-simpler.org/sloglint v0.7.2/go.mod h1:US+9C80ppl7VsThQclkM7BkCHQAzuz8kHLsW3ppuluo= +go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= @@ -742,14 +856,24 @@ go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN8 go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= +go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= +golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw= +golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200602180216-279210d13fed/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= +golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= +golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= +golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= @@ -761,6 +885,7 @@ golang.org/x/exp/typeparams v0.0.0-20220428152302-39d4317da171/go.mod h1:AbB0pIl golang.org/x/exp/typeparams v0.0.0-20230203172020-98cc5a0785f9/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/exp/typeparams v0.0.0-20240613232115-7f521ea00fb8 h1:+ZJmEdDFzH5H0CnzOrwgbH3elHctfTecW9X0k2tkn5M= golang.org/x/exp/typeparams v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= +golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= @@ -786,8 +911,13 @@ golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -802,17 +932,26 @@ golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= +golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/net v0.16.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4= golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -826,9 +965,13 @@ golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -849,11 +992,15 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= @@ -865,15 +1012,19 @@ golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= +golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= +golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24= golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -883,11 +1034,18 @@ golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= +golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= @@ -928,11 +1086,23 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gonum.org/v1/gonum v0.15.0 h1:2lYxjRbTYyxkJxlhC+LvJIx3SsANPdRybu1tGj9/OrQ= gonum.org/v1/gonum v0.15.0/go.mod h1:xzZVBJBtS+Mz4q0Yl2LJTk+OxOg4jiXZ7qBoM0uISGo= +google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= +google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= +google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg= +google.golang.org/genproto v0.0.0-20190306203927-b5d61aea6440/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= +google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= +google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= @@ -951,10 +1121,13 @@ google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFyt google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= @@ -967,7 +1140,10 @@ gotest.tools/gotestsum v1.12.0 h1:CmwtaGDkHxrZm4Ib0Vob89MTfpc3GrEFMJKovliPwGk= gotest.tools/gotestsum v1.12.0/go.mod h1:fAvqkSptospfSbQw26CTYzNwnsE/ztqLeyhP0h67ARY= gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU= gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= +grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o= +honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.5.1 h1:4bH5o3b5ZULQ4UrBmP+63W9r7qIkqJClEA9ko5YKx+I= honnef.co/go/tools v0.5.1/go.mod h1:e9irvo83WDG9/irijV44wr3tbhcFeRnfpVlRqVwpzMs= @@ -977,3 +1153,5 @@ mvdan.cc/gofumpt v0.7.0 h1:bg91ttqXmi9y2xawvkuMXyvAA/1ZGJqYAEGjXuP0JXU= mvdan.cc/gofumpt v0.7.0/go.mod h1:txVFJy/Sc/mvaycET54pV8SW8gWxTlUuGHVEcncmNUo= mvdan.cc/unparam v0.0.0-20240528143540-8a5130ca722f h1:lMpcwN6GxNbWtbpI1+xzFLSW8XzX0u72NttUGVFjO3U= mvdan.cc/unparam v0.0.0-20240528143540-8a5130ca722f/go.mod h1:RSLa7mKKCNeTTMHBw5Hsy2rfJmd6O2ivt9Dw9ZqCQpQ= +sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck= +sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0= From 8c41c4d16210b225644fad446e19be73007dfb66 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 30 Oct 2024 17:28:06 +0100 Subject: [PATCH 1202/1212] chore(deps): bump codecov/codecov-action from 4.4.0 to 4.6.0 (#10541) Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 4.4.0 to 4.6.0. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/6d798873df2b1b8e5846dba6fb86631229fbcb17...b9fd7d16f6d7d1b5d2bec1a2887e65ceed900238) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/gotest.yml | 2 +- .github/workflows/sharness.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/gotest.yml b/.github/workflows/gotest.yml index f5225e8a3..c6cac2c78 100644 --- a/.github/workflows/gotest.yml +++ b/.github/workflows/gotest.yml @@ -45,7 +45,7 @@ jobs: make -j "$PARALLEL" test/unit/gotest.junit.xml && [[ ! $(jq -s -c 'map(select(.Action == "fail")) | .[]' test/unit/gotest.json) ]] - name: Upload coverage to Codecov - uses: codecov/codecov-action@6d798873df2b1b8e5846dba6fb86631229fbcb17 # v4.4.0 + uses: codecov/codecov-action@b9fd7d16f6d7d1b5d2bec1a2887e65ceed900238 # v4.6.0 if: failure() || success() with: name: unittests diff --git a/.github/workflows/sharness.yml b/.github/workflows/sharness.yml index af7fa896c..ac91b1321 100644 --- a/.github/workflows/sharness.yml +++ b/.github/workflows/sharness.yml @@ -55,7 +55,7 @@ jobs: # increasing parallelism beyond 10 doesn't speed up the tests much PARALLEL: ${{ github.repository == 'ipfs/kubo' && 10 || 3 }} - name: Upload coverage report - uses: codecov/codecov-action@6d798873df2b1b8e5846dba6fb86631229fbcb17 # v4.4.0 + uses: codecov/codecov-action@b9fd7d16f6d7d1b5d2bec1a2887e65ceed900238 # v4.6.0 if: failure() || success() with: name: sharness From caa88440cd5d8c3df87727d32c5deba8712c7c38 Mon Sep 17 00:00:00 2001 From: Daniel Norman <1992255+2color@users.noreply.github.com> Date: Wed, 30 Oct 2024 17:36:43 +0100 Subject: [PATCH 1203/1212] docs(autotls): add note about separate port use (#10562) Co-authored-by: Daniel N <2color@users.noreply.github.com> Co-authored-by: Marcin Rataj --- docs/changelogs/v0.32.md | 3 ++- docs/config.md | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/changelogs/v0.32.md b/docs/changelogs/v0.32.md index a8deab9e6..5e0e52406 100644 --- a/docs/changelogs/v0.32.md +++ b/docs/changelogs/v0.32.md @@ -24,7 +24,8 @@ See [`AutoTLS`](https://github.com/ipfs/kubo/blob/master/docs/config.md#autotls) #### 📦️ Boxo and go-libp2p updates -- update `boxo` to [v0.24.2](https://github.com/ipfs/boxo/releases/tag/v0.24.2). This includes a number of fixes and bitswap improvements. +- update `boxo` to [v0.24.1](https://github.com/ipfs/boxo/releases/tag/v0.24.1) + [v0.24.2](https://github.com/ipfs/boxo/releases/tag/v0.24.2) + - This includes a number of fixes and bitswap improvements, and support for filtering from [IPIP-484](https://specs.ipfs.tech/ipips/ipip-0484/) in delegated HTTP routing and IPNI queries. - update `go-libp2p` to [v0.37.0](https://github.com/libp2p/go-libp2p/releases/tag/v0.37.0) - This update required removal of `Swarm.RelayService.MaxReservationsPerPeer` configuration option from Kubo. If you had it set, remove it from your configuration file. - update `go-libp2p-kad-dht` to [v0.27.0](https://github.com/libp2p/go-libp2p-kad-dht/releases/tag/v0.27.0) diff --git a/docs/config.md b/docs/config.md index f1efc40bb..142042711 100644 --- a/docs/config.md +++ b/docs/config.md @@ -505,8 +505,8 @@ Kubo will obtain and set up a trusted PKI TLS certificate for it, making it dial > add catch-all `/ip4/0.0.0.0/tcp/4002/tls/sni/*.libp2p.direct/ws` and `/ip6/::/tcp/4002/tls/sni/*.libp2p.direct/ws` to [`Addresses.Swarm`](#addressesswarm) > and **wait 5-15 minutes** for libp2p node to set up and learn about own public addresses via [AutoNAT](#autonat). > - If your node is fresh and just started, the [p2p-forge] client may produce and log ERRORs during this time, but once a publicly diallable addresses are set up, a subsequent retry should be successful. -> - Requires manually updating [`Addresses.Swarm`](#addressesswarm) and opening a new port -> - A separate port has to be used instead of `4001` because we wait for TCP port sharing ([go-libp2p#2984](https://github.com/libp2p/go-libp2p/issues/2684)) to be implemented. +> - Listeners defined in [`Addresses.Swarm`](#addressesswarm) with `/tls/sni` must use a separate port from other TCP listeners, e.g. `4002` instead of the default `4001`. +> - A separate port (`/tcp/4002`) has to be used instead of `/tcp/4001` because we wait for TCP port sharing ([go-libp2p#2984](https://github.com/libp2p/go-libp2p/issues/2684)) to be implemented. > - If you use manual port forwarding, make sure incoming connections to this additional port are allowed the same way `4001` ones already are. > - The TLS certificate is used only for [libp2p WebSocket](https://github.com/libp2p/specs/blob/master/websockets/README.md) connections. > - Right now, this is NOT used for hosting a [Gateway](#gateway) over HTTPS (that use case still requires manual TLS setup on reverse proxy, and your own domain). From c5586d51ebaa1048aa65994aa6c0bad870c94c5f Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Wed, 30 Oct 2024 17:44:31 +0100 Subject: [PATCH 1204/1212] chore: bump master to 0.33.0-dev --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index 46704e0be..fb1f2383a 100644 --- a/version.go +++ b/version.go @@ -11,7 +11,7 @@ import ( var CurrentCommit string // CurrentVersionNumber is the current application's version literal. -const CurrentVersionNumber = "0.32.0-dev" +const CurrentVersionNumber = "0.33.0-dev" const ApiVersion = "/kubo/" + CurrentVersionNumber + "/" //nolint From 1ca0ae0af696ad379a654ebadbb3a7c347702d14 Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Wed, 30 Oct 2024 18:23:33 -0400 Subject: [PATCH 1205/1212] fix(autotls): store certificates at the location from the repo path (#10566) * fix(autotls): store certificates at the location from the repo path * docs(autotls): cert storale and other caveats --------- Co-authored-by: Marcin Rataj --- core/node/groups.go | 2 +- core/node/libp2p/addrs.go | 8 +++----- docs/config.md | 9 +++++++-- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/core/node/groups.go b/core/node/groups.go index 37bb1d6db..c74d0be8a 100644 --- a/core/node/groups.go +++ b/core/node/groups.go @@ -152,7 +152,7 @@ func LibP2P(bcfg *BuildCfg, cfg *config.Config, userResourceOverrides rcmgr.Part // Services (resource management) fx.Provide(libp2p.ResourceManager(bcfg.Repo.Path(), cfg.Swarm, userResourceOverrides)), - maybeProvide(libp2p.P2PForgeCertMgr(cfg.AutoTLS), enableAutoTLS), + maybeProvide(libp2p.P2PForgeCertMgr(bcfg.Repo.Path(), cfg.AutoTLS), enableAutoTLS), maybeInvoke(libp2p.StartP2PAutoTLS, enableAutoTLS), 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/addrs.go b/core/node/libp2p/addrs.go index c4c8bbe09..acb5bb9d6 100644 --- a/core/node/libp2p/addrs.go +++ b/core/node/libp2p/addrs.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "os" + "path/filepath" logging "github.com/ipfs/go-log" version "github.com/ipfs/kubo" @@ -132,12 +133,9 @@ func ListenOn(addresses []string) interface{} { } } -func P2PForgeCertMgr(cfg config.AutoTLS) interface{} { +func P2PForgeCertMgr(repoPath string, cfg config.AutoTLS) interface{} { return func() (*p2pforge.P2PForgeCertMgr, error) { - storagePath, err := config.Path("", "p2p-forge-certs") - if err != nil { - return nil, err - } + storagePath := filepath.Join(repoPath, "p2p-forge-certs") forgeLogger := logging.Logger("autotls").Desugar() certStorage := &certmagic.FileStorage{Path: storagePath} diff --git a/docs/config.md b/docs/config.md index 142042711..e2b169452 100644 --- a/docs/config.md +++ b/docs/config.md @@ -512,7 +512,8 @@ Kubo will obtain and set up a trusted PKI TLS certificate for it, making it dial > - Right now, this is NOT used for hosting a [Gateway](#gateway) over HTTPS (that use case still requires manual TLS setup on reverse proxy, and your own domain). > [!TIP] -> Debugging can be enabled by setting environment variable `GOLOG_LOG_LEVEL="error,autotls=debug,p2p-forge/client=debug"` +> - Debugging can be enabled by setting environment variable `GOLOG_LOG_LEVEL="error,autotls=debug,p2p-forge/client=debug"` +> - Certificates are stored in `$IPFS_PATH/p2p-forge-certs`. Removing directory and restarting daemon will trigger certificate rotation. Default: `false` @@ -530,7 +531,7 @@ Type: `optionalString` ### `AutoTLS.RegistrationEndpoint` Optional override of [p2p-forge] HTTP registration API. -Do not change this unless you self-host [p2p-forge]. +Do not change this unless you self-host [p2p-forge] under own domain. > [!IMPORTANT] > The default endpoint performs [libp2p Peer ID Authentication over HTTP](https://github.com/libp2p/specs/blob/master/http/peer-id-auth.md) @@ -553,6 +554,10 @@ Type: `optionalString` ### `AutoTLS.CAEndpoint` Optional override of CA ACME API used by [p2p-forge] system. +Do not change this unless you self-host [p2p-forge] under own domain. + +> [!IMPORTANT] +> CAA DNS record at `libp2p.direct` limits CA choice to Let's Encrypt. If you want to use a different CA, use your own domain. Default: [certmagic.LetsEncryptProductionCA](https://pkg.go.dev/github.com/caddyserver/certmagic#pkg-constants) (see [community.letsencrypt.org discussion](https://community.letsencrypt.org/t/feedback-on-raising-certificates-per-registered-domain-to-enable-peer-to-peer-networking/223003)) From d4ae7fa81223a7931a7907ecbf7ebf797e4ff11c Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Mon, 4 Nov 2024 14:24:34 -0500 Subject: [PATCH 1206/1212] chore: update deps (#10569) --- docs/examples/kubo-as-a-library/go.mod | 8 +++---- docs/examples/kubo-as-a-library/go.sum | 32 ++++++++------------------ go.mod | 8 +++---- go.sum | 31 ++++++++----------------- test/dependencies/go.mod | 2 +- test/dependencies/go.sum | 8 +++---- 6 files changed, 33 insertions(+), 56 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 6fed80107..8bd0d902c 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -26,7 +26,7 @@ require ( github.com/caddyserver/certmagic v0.21.4 // indirect github.com/caddyserver/zerossl v0.1.3 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect - github.com/ceramicnetwork/go-dag-jose v0.1.0 // indirect + github.com/ceramicnetwork/go-dag-jose v0.1.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cockroachdb/errors v1.11.3 // indirect github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce // indirect @@ -53,6 +53,7 @@ require ( github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/gabriel-vasile/mimetype v1.4.4 // indirect github.com/getsentry/sentry-go v0.27.0 // indirect + github.com/go-jose/go-jose/v4 v4.0.4 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-task/slim-sprig/v3 v3.0.0 // indirect @@ -108,7 +109,7 @@ require ( github.com/ipld/go-car/v2 v2.14.2 // indirect github.com/ipld/go-codec-dagpb v1.6.0 // indirect github.com/ipld/go-ipld-prime v0.21.0 // indirect - github.com/ipshipyard/p2p-forge v0.0.0-20241028231853-f599f4803109 // indirect + github.com/ipshipyard/p2p-forge v0.0.1 // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect github.com/jbenet/goprocess v0.1.4 // indirect @@ -188,7 +189,7 @@ require ( github.com/quic-go/quic-go v0.48.1 // indirect github.com/quic-go/webtransport-go v0.8.1-0.20241018022711-4ac2c9250e66 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect - github.com/rogpeppe/go-internal v1.12.0 // indirect + github.com/rogpeppe/go-internal v1.13.1 // indirect github.com/samber/lo v1.46.0 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/stretchr/testify v1.9.0 // indirect @@ -235,7 +236,6 @@ require ( google.golang.org/genproto/googleapis/rpc v0.0.0-20240617180043-68d350f18fd4 // indirect google.golang.org/grpc v1.64.0 // indirect google.golang.org/protobuf v1.35.1 // indirect - gopkg.in/square/go-jose.v2 v2.6.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect lukechampine.com/blake3 v1.3.0 // indirect ) diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 774aa59fe..5e8860c8a 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -68,8 +68,8 @@ github.com/caddyserver/zerossl v0.1.3/go.mod h1:CxA0acn7oEGO6//4rtrRjYgEoa4MFw/X github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/ceramicnetwork/go-dag-jose v0.1.0 h1:yJ/HVlfKpnD3LdYP03AHyTvbm3BpPiz2oZiOeReJRdU= -github.com/ceramicnetwork/go-dag-jose v0.1.0/go.mod h1:qYA1nYt0X8u4XoMAVoOV3upUVKtrxy/I670Dg5F0wjI= +github.com/ceramicnetwork/go-dag-jose v0.1.1 h1:7pObs22egc14vSS3AfCFfS1VmaL4lQUsAK7OGC3PlKk= +github.com/ceramicnetwork/go-dag-jose v0.1.1/go.mod h1:8ptnYwY2Z2y/s5oJnNBn/UCxLg6CpramNJ2ZXF/5aNY= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= @@ -155,7 +155,6 @@ github.com/flynn/noise v1.1.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwU github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk= github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= -github.com/frankban/quicktest v1.14.0/go.mod h1:NeW+ay9A/U67EYXNFA1nPE8e/tnQv/09mUdL/ijj8og= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= @@ -175,6 +174,8 @@ github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxI github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-jose/go-jose/v4 v4.0.4 h1:VsjPI33J0SB9vQM6PLmNjoHqMQNGPiZ0rHL7Ni7Q6/E= +github.com/go-jose/go-jose/v4 v4.0.4/go.mod h1:NKb5HO1EZccyMpiZNbdUw/14tiXNyUJh188dfnMCAfc= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= @@ -237,7 +238,6 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ 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= -github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= @@ -397,13 +397,12 @@ github.com/ipld/go-car/v2 v2.14.2/go.mod h1:0iPB/825lTZLU2zPK5bVTk/R3V2612E1VI27 github.com/ipld/go-codec-dagpb v1.6.0 h1:9nYazfyu9B1p3NAgfVdpRco3Fs2nFC72DqVsMj6rOcc= github.com/ipld/go-codec-dagpb v1.6.0/go.mod h1:ANzFhfP2uMJxRBr8CE+WQWs5UsNa0pYtmKZ+agnUw9s= github.com/ipld/go-ipld-prime v0.11.0/go.mod h1:+WIAkokurHmZ/KwzDOMUuoeJgaRQktHtEaLglS3ZeV8= -github.com/ipld/go-ipld-prime v0.14.1/go.mod h1:QcE4Y9n/ZZr8Ijg5bGPT0GqYWgZ1704nH0RDcQtgTP0= github.com/ipld/go-ipld-prime v0.21.0 h1:n4JmcpOlPDIxBcY037SVfpd1G+Sj1nKZah0m6QH9C2E= github.com/ipld/go-ipld-prime v0.21.0/go.mod h1:3RLqy//ERg/y5oShXXdx5YIp50cFGOanyMctpPjsvxQ= github.com/ipld/go-ipld-prime/storage/bsadapter v0.0.0-20230102063945-1a409dc236dd h1:gMlw/MhNr2Wtp5RwGdsW23cs+yCuj9k2ON7i9MiJlRo= github.com/ipld/go-ipld-prime/storage/bsadapter v0.0.0-20230102063945-1a409dc236dd/go.mod h1:wZ8hH8UxeryOs4kJEJaiui/s00hDSbE37OKsL47g+Sw= -github.com/ipshipyard/p2p-forge v0.0.0-20241028231853-f599f4803109 h1:Od9XhliY3EzRDCd/H6fMQ225+DSaS+CT0daHjEwbZTM= -github.com/ipshipyard/p2p-forge v0.0.0-20241028231853-f599f4803109/go.mod h1:taPeh3PDSO8Ual0/N2tIOAUXPV8gZoPF3uPXoUyiq14= +github.com/ipshipyard/p2p-forge v0.0.1 h1:7Wy3Ul4gGLIPx4LjMjGaO6MoKa54ITDqwMOyXshrvO4= +github.com/ipshipyard/p2p-forge v0.0.1/go.mod h1:taPeh3PDSO8Ual0/N2tIOAUXPV8gZoPF3uPXoUyiq14= github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/jbenet/go-cienv v0.1.0 h1:Vc/s0QbQtoxX8MwwSLWWh+xNNZvM3Lw7NsTcHrvvhMc= @@ -432,7 +431,6 @@ github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6 github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM= github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -441,7 +439,6 @@ github.com/koron/go-ssdp v0.0.4/go.mod h1:oDXq+E5IL5q0U8uSBcoAXzTzInwy5lEgC91HoK github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= @@ -569,7 +566,6 @@ github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/g github.com/multiformats/go-multibase v0.0.3/go.mod h1:5+1R4eQrT3PkYZ24C3W2Ue2tPwIdYQD509ZjSb5y9Oc= github.com/multiformats/go-multibase v0.2.0 h1:isdYCVLvksgWlMW9OZRYJEa9pZETFivncJHmHnnd87g= github.com/multiformats/go-multibase v0.2.0/go.mod h1:bFBZX4lKCA/2lyOFSAoKH5SS6oPyjtnzK/XTFDPkNuk= -github.com/multiformats/go-multicodec v0.3.0/go.mod h1:qGGaQmioCDh+TeFOnxrbU0DaIPw8yFgAZgFG0V7p1qQ= github.com/multiformats/go-multicodec v0.9.0 h1:pb/dlPnzee/Sxv/j4PmkDRxCOi3hXTz3IbPKOXWJkmg= github.com/multiformats/go-multicodec v0.9.0/go.mod h1:L3QTQvMIaVBkXOXXtVmYE+LI16i14xuaojr/H7Ai54k= github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= @@ -578,7 +574,6 @@ github.com/multiformats/go-multihash v0.0.10/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpK github.com/multiformats/go-multihash v0.0.13/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= github.com/multiformats/go-multihash v0.0.14/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= github.com/multiformats/go-multihash v0.0.15/go.mod h1:D6aZrWNLFTV/ynMpKsNtB40mJzmCl4jb1alC0OvHiHg= -github.com/multiformats/go-multihash v0.1.0/go.mod h1:RJlXsxt6vHGaia+S8We0ErjhojtKzPP2AH4+kYM7k84= github.com/multiformats/go-multihash v0.2.3 h1:7Lyc8XfX/IY2jWb/gI7JP+o7JEq9hOa7BFvVU9RSh+U= github.com/multiformats/go-multihash v0.2.3/go.mod h1:dXgKXCXjBzdscBLk9JkjINiEsCKRVch90MdaGiKsvSM= github.com/multiformats/go-multistream v0.5.0 h1:5htLSLl7lvJk3xx3qT/8Zm9J4K8vEOf/QGkvOGQAyiE= @@ -703,10 +698,9 @@ github.com/quic-go/webtransport-go v0.8.1-0.20241018022711-4ac2c9250e66/go.mod h github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= -github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd/go.mod h1:hPqNNc0+uJM6H+SuU8sEs5K5IQeKccPqeSjfgcKGgPk= @@ -791,8 +785,6 @@ github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60Nt github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU= github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM= github.com/wangjia184/sortedset v0.0.0-20160527075905-f5d03557ba30/go.mod h1:YkocrP2K2tcw938x9gCOmT5G5eCD6jsTz0SZuyAqwIE= -github.com/warpfork/go-testmark v0.3.0/go.mod h1:jhEf8FVxd+F17juRubpmut64NEG6I2rgkUhlcqqXwE0= -github.com/warpfork/go-testmark v0.9.0/go.mod h1:jhEf8FVxd+F17juRubpmut64NEG6I2rgkUhlcqqXwE0= github.com/warpfork/go-testmark v0.12.1 h1:rMgCpJfwy1sJ50x0M0NgyphxYYPMOODIJHhsXyEHU0s= github.com/warpfork/go-testmark v0.12.1/go.mod h1:kHwy7wfvGSPh1rQJYKayD4AbtNaeyZdcGi9tNJTaa5Y= github.com/warpfork/go-wish v0.0.0-20200122115046-b9ea61034e4a/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= @@ -1208,9 +1200,6 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EV gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= -gopkg.in/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI= -gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/src-d/go-cli.v0 v0.0.0-20181105080154-d492247bbc0d/go.mod h1:z+K8VcOYVYcSwSjGebuDL6176A1XskgbtNl64NSg+n8= gopkg.in/src-d/go-log.v1 v1.0.1/go.mod h1:GN34hKP0g305ysm2/hctJ0Y8nWP3zxXXJ8GFabTyABE= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= @@ -1233,11 +1222,10 @@ honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -lukechampine.com/blake3 v1.1.6/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= lukechampine.com/blake3 v1.3.0 h1:sJ3XhFINmHSrYCgl958hscfIa3bw8x4DqMP3u1YvoYE= lukechampine.com/blake3 v1.3.0/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= -pgregory.net/rapid v0.4.7 h1:MTNRktPuv5FNqOO151TM9mDTa+XHcX6ypYeISDVD14g= -pgregory.net/rapid v0.4.7/go.mod h1:UYpPVyjFHzYBGHIxLFoupi8vwk6rXNzRY9OMvVxFIOU= +pgregory.net/rapid v1.1.0 h1:CMa0sjHSru3puNx+J0MIAuiiEV4N0qj8/cMWGBBCsjw= +pgregory.net/rapid v1.1.0/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/go.mod b/go.mod index ca181eea1..bb0aef254 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/blang/semver/v4 v4.0.0 github.com/caddyserver/certmagic v0.21.4 github.com/cenkalti/backoff/v4 v4.3.0 - github.com/ceramicnetwork/go-dag-jose v0.1.0 + github.com/ceramicnetwork/go-dag-jose v0.1.1 github.com/cheggaaa/pb v1.0.29 github.com/cockroachdb/pebble v1.1.2 github.com/coreos/go-systemd/v22 v22.5.0 @@ -49,7 +49,7 @@ require ( github.com/ipld/go-car/v2 v2.14.2 github.com/ipld/go-codec-dagpb v1.6.0 github.com/ipld/go-ipld-prime v0.21.0 - github.com/ipshipyard/p2p-forge v0.0.0-20241028231853-f599f4803109 + github.com/ipshipyard/p2p-forge v0.0.1 github.com/jbenet/go-temp-err-catcher v0.1.0 github.com/jbenet/goprocess v0.1.4 github.com/julienschmidt/httprouter v1.3.0 @@ -127,6 +127,7 @@ require ( github.com/francoispqt/gojay v1.2.13 // indirect github.com/gabriel-vasile/mimetype v1.4.4 // indirect github.com/getsentry/sentry-go v0.27.0 // indirect + github.com/go-jose/go-jose/v4 v4.0.4 // indirect github.com/go-kit/log v0.2.1 // indirect github.com/go-logfmt/logfmt v0.5.1 // indirect github.com/go-logr/logr v1.4.2 // indirect @@ -228,7 +229,7 @@ require ( github.com/quic-go/webtransport-go v0.8.1-0.20241018022711-4ac2c9250e66 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/rivo/uniseg v0.4.4 // indirect - github.com/rogpeppe/go-internal v1.12.0 // indirect + github.com/rogpeppe/go-internal v1.13.1 // indirect github.com/rs/cors v1.10.1 // indirect github.com/samber/lo v1.46.0 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect @@ -267,7 +268,6 @@ require ( google.golang.org/genproto/googleapis/api v0.0.0-20240617180043-68d350f18fd4 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240617180043-68d350f18fd4 // indirect google.golang.org/grpc v1.64.0 // indirect - gopkg.in/square/go-jose.v2 v2.5.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect lukechampine.com/blake3 v1.3.0 // indirect diff --git a/go.sum b/go.sum index 2c513c5a5..704d9c240 100644 --- a/go.sum +++ b/go.sum @@ -93,8 +93,8 @@ github.com/caddyserver/zerossl v0.1.3/go.mod h1:CxA0acn7oEGO6//4rtrRjYgEoa4MFw/X github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/ceramicnetwork/go-dag-jose v0.1.0 h1:yJ/HVlfKpnD3LdYP03AHyTvbm3BpPiz2oZiOeReJRdU= -github.com/ceramicnetwork/go-dag-jose v0.1.0/go.mod h1:qYA1nYt0X8u4XoMAVoOV3upUVKtrxy/I670Dg5F0wjI= +github.com/ceramicnetwork/go-dag-jose v0.1.1 h1:7pObs22egc14vSS3AfCFfS1VmaL4lQUsAK7OGC3PlKk= +github.com/ceramicnetwork/go-dag-jose v0.1.1/go.mod h1:8ptnYwY2Z2y/s5oJnNBn/UCxLg6CpramNJ2ZXF/5aNY= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= @@ -189,7 +189,6 @@ github.com/flynn/noise v1.1.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwU github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk= github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= -github.com/frankban/quicktest v1.14.0/go.mod h1:NeW+ay9A/U67EYXNFA1nPE8e/tnQv/09mUdL/ijj8og= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= @@ -210,6 +209,8 @@ github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3Bop github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-jose/go-jose/v4 v4.0.4 h1:VsjPI33J0SB9vQM6PLmNjoHqMQNGPiZ0rHL7Ni7Q6/E= +github.com/go-jose/go-jose/v4 v4.0.4/go.mod h1:NKb5HO1EZccyMpiZNbdUw/14tiXNyUJh188dfnMCAfc= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= @@ -291,7 +292,6 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ 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= -github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= @@ -464,13 +464,12 @@ github.com/ipld/go-car/v2 v2.14.2/go.mod h1:0iPB/825lTZLU2zPK5bVTk/R3V2612E1VI27 github.com/ipld/go-codec-dagpb v1.6.0 h1:9nYazfyu9B1p3NAgfVdpRco3Fs2nFC72DqVsMj6rOcc= github.com/ipld/go-codec-dagpb v1.6.0/go.mod h1:ANzFhfP2uMJxRBr8CE+WQWs5UsNa0pYtmKZ+agnUw9s= github.com/ipld/go-ipld-prime v0.11.0/go.mod h1:+WIAkokurHmZ/KwzDOMUuoeJgaRQktHtEaLglS3ZeV8= -github.com/ipld/go-ipld-prime v0.14.1/go.mod h1:QcE4Y9n/ZZr8Ijg5bGPT0GqYWgZ1704nH0RDcQtgTP0= github.com/ipld/go-ipld-prime v0.21.0 h1:n4JmcpOlPDIxBcY037SVfpd1G+Sj1nKZah0m6QH9C2E= github.com/ipld/go-ipld-prime v0.21.0/go.mod h1:3RLqy//ERg/y5oShXXdx5YIp50cFGOanyMctpPjsvxQ= github.com/ipld/go-ipld-prime/storage/bsadapter v0.0.0-20230102063945-1a409dc236dd h1:gMlw/MhNr2Wtp5RwGdsW23cs+yCuj9k2ON7i9MiJlRo= github.com/ipld/go-ipld-prime/storage/bsadapter v0.0.0-20230102063945-1a409dc236dd/go.mod h1:wZ8hH8UxeryOs4kJEJaiui/s00hDSbE37OKsL47g+Sw= -github.com/ipshipyard/p2p-forge v0.0.0-20241028231853-f599f4803109 h1:Od9XhliY3EzRDCd/H6fMQ225+DSaS+CT0daHjEwbZTM= -github.com/ipshipyard/p2p-forge v0.0.0-20241028231853-f599f4803109/go.mod h1:taPeh3PDSO8Ual0/N2tIOAUXPV8gZoPF3uPXoUyiq14= +github.com/ipshipyard/p2p-forge v0.0.1 h1:7Wy3Ul4gGLIPx4LjMjGaO6MoKa54ITDqwMOyXshrvO4= +github.com/ipshipyard/p2p-forge v0.0.1/go.mod h1:taPeh3PDSO8Ual0/N2tIOAUXPV8gZoPF3uPXoUyiq14= github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/jbenet/go-cienv v0.1.0 h1:Vc/s0QbQtoxX8MwwSLWWh+xNNZvM3Lw7NsTcHrvvhMc= @@ -506,7 +505,6 @@ github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6 github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM= github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -517,7 +515,6 @@ github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFB github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= @@ -667,7 +664,6 @@ github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/g github.com/multiformats/go-multibase v0.0.3/go.mod h1:5+1R4eQrT3PkYZ24C3W2Ue2tPwIdYQD509ZjSb5y9Oc= github.com/multiformats/go-multibase v0.2.0 h1:isdYCVLvksgWlMW9OZRYJEa9pZETFivncJHmHnnd87g= github.com/multiformats/go-multibase v0.2.0/go.mod h1:bFBZX4lKCA/2lyOFSAoKH5SS6oPyjtnzK/XTFDPkNuk= -github.com/multiformats/go-multicodec v0.3.0/go.mod h1:qGGaQmioCDh+TeFOnxrbU0DaIPw8yFgAZgFG0V7p1qQ= github.com/multiformats/go-multicodec v0.9.0 h1:pb/dlPnzee/Sxv/j4PmkDRxCOi3hXTz3IbPKOXWJkmg= github.com/multiformats/go-multicodec v0.9.0/go.mod h1:L3QTQvMIaVBkXOXXtVmYE+LI16i14xuaojr/H7Ai54k= github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= @@ -676,7 +672,6 @@ github.com/multiformats/go-multihash v0.0.10/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpK github.com/multiformats/go-multihash v0.0.13/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= github.com/multiformats/go-multihash v0.0.14/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= github.com/multiformats/go-multihash v0.0.15/go.mod h1:D6aZrWNLFTV/ynMpKsNtB40mJzmCl4jb1alC0OvHiHg= -github.com/multiformats/go-multihash v0.1.0/go.mod h1:RJlXsxt6vHGaia+S8We0ErjhojtKzPP2AH4+kYM7k84= github.com/multiformats/go-multihash v0.2.3 h1:7Lyc8XfX/IY2jWb/gI7JP+o7JEq9hOa7BFvVU9RSh+U= github.com/multiformats/go-multihash v0.2.3/go.mod h1:dXgKXCXjBzdscBLk9JkjINiEsCKRVch90MdaGiKsvSM= github.com/multiformats/go-multistream v0.5.0 h1:5htLSLl7lvJk3xx3qT/8Zm9J4K8vEOf/QGkvOGQAyiE= @@ -830,10 +825,9 @@ github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJ github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= -github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= github.com/rs/cors v1.10.1 h1:L0uuZVXIKlI1SShY2nhFfo44TYvDPQ1w4oFkUJNfhyo= github.com/rs/cors v1.10.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= @@ -936,8 +930,6 @@ github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60Nt github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU= github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM= github.com/wangjia184/sortedset v0.0.0-20160527075905-f5d03557ba30/go.mod h1:YkocrP2K2tcw938x9gCOmT5G5eCD6jsTz0SZuyAqwIE= -github.com/warpfork/go-testmark v0.3.0/go.mod h1:jhEf8FVxd+F17juRubpmut64NEG6I2rgkUhlcqqXwE0= -github.com/warpfork/go-testmark v0.9.0/go.mod h1:jhEf8FVxd+F17juRubpmut64NEG6I2rgkUhlcqqXwE0= github.com/warpfork/go-testmark v0.12.1 h1:rMgCpJfwy1sJ50x0M0NgyphxYYPMOODIJHhsXyEHU0s= github.com/warpfork/go-testmark v0.12.1/go.mod h1:kHwy7wfvGSPh1rQJYKayD4AbtNaeyZdcGi9tNJTaa5Y= github.com/warpfork/go-wish v0.0.0-20200122115046-b9ea61034e4a/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= @@ -1467,8 +1459,6 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EV gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/square/go-jose.v2 v2.5.1 h1:7odma5RETjNHWJnR32wx8t+Io4djHE1PqxCFx3iiZ2w= -gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/src-d/go-cli.v0 v0.0.0-20181105080154-d492247bbc0d/go.mod h1:z+K8VcOYVYcSwSjGebuDL6176A1XskgbtNl64NSg+n8= gopkg.in/src-d/go-log.v1 v1.0.1/go.mod h1:GN34hKP0g305ysm2/hctJ0Y8nWP3zxXXJ8GFabTyABE= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= @@ -1494,11 +1484,10 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -lukechampine.com/blake3 v1.1.6/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= lukechampine.com/blake3 v1.3.0 h1:sJ3XhFINmHSrYCgl958hscfIa3bw8x4DqMP3u1YvoYE= lukechampine.com/blake3 v1.3.0/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= -pgregory.net/rapid v0.4.7 h1:MTNRktPuv5FNqOO151TM9mDTa+XHcX6ypYeISDVD14g= -pgregory.net/rapid v0.4.7/go.mod h1:UYpPVyjFHzYBGHIxLFoupi8vwk6rXNzRY9OMvVxFIOU= +pgregory.net/rapid v1.1.0 h1:CMa0sjHSru3puNx+J0MIAuiiEV4N0qj8/cMWGBBCsjw= +pgregory.net/rapid v1.1.0/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 80f598e62..66ec7fe9c 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -130,7 +130,7 @@ require ( github.com/ipfs/kubo v0.31.0 // indirect github.com/ipld/go-codec-dagpb v1.6.0 // indirect github.com/ipld/go-ipld-prime v0.21.0 // indirect - github.com/ipshipyard/p2p-forge v0.0.0-20241028231853-f599f4803109 // indirect + github.com/ipshipyard/p2p-forge v0.0.1 // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect github.com/jbenet/goprocess v0.1.4 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 3f49a4a46..bdbc9e199 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -358,8 +358,8 @@ github.com/ipld/go-codec-dagpb v1.6.0 h1:9nYazfyu9B1p3NAgfVdpRco3Fs2nFC72DqVsMj6 github.com/ipld/go-codec-dagpb v1.6.0/go.mod h1:ANzFhfP2uMJxRBr8CE+WQWs5UsNa0pYtmKZ+agnUw9s= github.com/ipld/go-ipld-prime v0.21.0 h1:n4JmcpOlPDIxBcY037SVfpd1G+Sj1nKZah0m6QH9C2E= github.com/ipld/go-ipld-prime v0.21.0/go.mod h1:3RLqy//ERg/y5oShXXdx5YIp50cFGOanyMctpPjsvxQ= -github.com/ipshipyard/p2p-forge v0.0.0-20241028231853-f599f4803109 h1:Od9XhliY3EzRDCd/H6fMQ225+DSaS+CT0daHjEwbZTM= -github.com/ipshipyard/p2p-forge v0.0.0-20241028231853-f599f4803109/go.mod h1:taPeh3PDSO8Ual0/N2tIOAUXPV8gZoPF3uPXoUyiq14= +github.com/ipshipyard/p2p-forge v0.0.1 h1:7Wy3Ul4gGLIPx4LjMjGaO6MoKa54ITDqwMOyXshrvO4= +github.com/ipshipyard/p2p-forge v0.0.1/go.mod h1:taPeh3PDSO8Ual0/N2tIOAUXPV8gZoPF3uPXoUyiq14= github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA= @@ -656,8 +656,8 @@ github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJ github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= -github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= From 14ec5503d31e0e58eed81ed7b8f4a32f2d8fbb13 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Mon, 4 Nov 2024 20:55:44 +0100 Subject: [PATCH 1207/1212] chore(github): update bug-report.yml docker image was missing, we also don't want to default to ipfs-desktop --- .github/ISSUE_TEMPLATE/bug-report.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug-report.yml b/.github/ISSUE_TEMPLATE/bug-report.yml index b0d0d1f0d..d89f921b8 100644 --- a/.github/ISSUE_TEMPLATE/bug-report.yml +++ b/.github/ISSUE_TEMPLATE/bug-report.yml @@ -32,8 +32,9 @@ body: label: Installation method description: Please select your installation method options: + - dist.ipfs.tech or ipfs-update + - docker image - ipfs-desktop - - ipfs-update or dist.ipfs.tech - third-party binary - built from source - type: textarea From e17dc2180c091f2a3b951f6f1ae7cd299ecbe578 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Tue, 5 Nov 2024 16:12:58 +0100 Subject: [PATCH 1208/1212] chore: go-ipfs-cmds@v0.14.0 (#10571) --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index bb0aef254..cb53c5c6e 100644 --- a/go.mod +++ b/go.mod @@ -34,7 +34,7 @@ require ( github.com/ipfs/go-ds-measure v0.2.0 github.com/ipfs/go-ds-pebble v0.4.0 github.com/ipfs/go-fs-lock v0.0.7 - github.com/ipfs/go-ipfs-cmds v0.13.0 + github.com/ipfs/go-ipfs-cmds v0.14.0 github.com/ipfs/go-ipld-cbor v0.2.0 github.com/ipfs/go-ipld-format v0.6.0 github.com/ipfs/go-ipld-git v0.1.1 @@ -230,7 +230,7 @@ require ( github.com/raulk/go-watchdog v1.3.0 // indirect github.com/rivo/uniseg v0.4.4 // indirect github.com/rogpeppe/go-internal v1.13.1 // indirect - github.com/rs/cors v1.10.1 // indirect + github.com/rs/cors v1.11.1 // indirect github.com/samber/lo v1.46.0 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/texttheater/golang-levenshtein v1.0.1 // indirect diff --git a/go.sum b/go.sum index 704d9c240..f9255efdf 100644 --- a/go.sum +++ b/go.sum @@ -404,8 +404,8 @@ github.com/ipfs/go-ipfs-blockstore v1.3.1 h1:cEI9ci7V0sRNivqaOr0elDsamxXFxJMMMy7 github.com/ipfs/go-ipfs-blockstore v1.3.1/go.mod h1:KgtZyc9fq+P2xJUiCAzbRdhhqJHvsw8u2Dlqy2MyRTE= github.com/ipfs/go-ipfs-blocksutil v0.0.1 h1:Eh/H4pc1hsvhzsQoMEP3Bke/aW5P5rVM1IWFJMcGIPQ= github.com/ipfs/go-ipfs-blocksutil v0.0.1/go.mod h1:Yq4M86uIOmxmGPUHv/uI7uKqZNtLb449gwKqXjIsnRk= -github.com/ipfs/go-ipfs-cmds v0.13.0 h1:+WVHZMrQNkPqwAQdrSFGbJgHpOc8H2G8eszNxnvoCQA= -github.com/ipfs/go-ipfs-cmds v0.13.0/go.mod h1:GYqjGSt6u9k9tyxIDT7M0ROWeB2raPGH94uuVnpWgY0= +github.com/ipfs/go-ipfs-cmds v0.14.0 h1:sxdurhAHSdQr5VrSNJjc+t92uJObSNq+gRVm/wLZGMM= +github.com/ipfs/go-ipfs-cmds v0.14.0/go.mod h1:zj2jN7bHJ4pDucRmqdq863AQYcsqdxXrfVkr9eqPfvo= github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= github.com/ipfs/go-ipfs-delay v0.0.1 h1:r/UXYyRcddO6thwOnhiznIAiSvxMECGgtv35Xs1IeRQ= github.com/ipfs/go-ipfs-delay v0.0.1/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= @@ -828,8 +828,8 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= -github.com/rs/cors v1.10.1 h1:L0uuZVXIKlI1SShY2nhFfo44TYvDPQ1w4oFkUJNfhyo= -github.com/rs/cors v1.10.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= +github.com/rs/cors v1.11.1 h1:eU3gRzXLRK57F5rKMGMZURNdIG4EoAmX8k94r9wXWHA= +github.com/rs/cors v1.11.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd/go.mod h1:hPqNNc0+uJM6H+SuU8sEs5K5IQeKccPqeSjfgcKGgPk= From 4009ad3e5a502518ddc7d48a888707f812ddc629 Mon Sep 17 00:00:00 2001 From: Andrew Gillis <11790789+gammazero@users.noreply.github.com> Date: Tue, 5 Nov 2024 05:45:11 -1000 Subject: [PATCH 1209/1212] chore: stop using go-homedir (#10568) * chore: stop using go-homedir The `github.com/mitchellh/go-homedir` repo is archived, no longer needed, and no longer maintained. - `homedir.Dir` is replaced by the stdlib `os.UserHomeDir` - `homedir.Expand` is replaced by fsutil.ExpandHome` in the `github.com/ipfs/kubo/misc/fsutil` package. Additional functionality, such as `DirWritable` and `FileExists` was moved into or included in the `github.com/ipfs/kubo/misc/fsutil` package. --- client/rpc/api.go | 4 +- cmd/ipfswatch/main.go | 4 +- config/config.go | 4 +- docs/changelogs/v0.32.md | 9 +++ docs/examples/kubo-as-a-library/go.mod | 1 - docs/examples/kubo-as-a-library/go.sum | 1 - go.mod | 1 - go.sum | 1 - misc/fsutil/fsutil.go | 82 +++++++++++++++++++++++ misc/fsutil/fsutil_test.go | 92 ++++++++++++++++++++++++++ plugin/plugins/pebbleds/pebbleds.go | 72 +------------------- repo/fsrepo/fsrepo.go | 9 ++- repo/fsrepo/migrations/ipfsdir.go | 10 +-- repo/fsrepo/misc.go | 4 +- 14 files changed, 200 insertions(+), 94 deletions(-) create mode 100644 misc/fsutil/fsutil.go create mode 100644 misc/fsutil/fsutil_test.go diff --git a/client/rpc/api.go b/client/rpc/api.go index 80a309b91..c4b73d387 100644 --- a/client/rpc/api.go +++ b/client/rpc/api.go @@ -20,10 +20,10 @@ import ( ipfs "github.com/ipfs/kubo" iface "github.com/ipfs/kubo/core/coreiface" caopts "github.com/ipfs/kubo/core/coreiface/options" + "github.com/ipfs/kubo/misc/fsutil" dagpb "github.com/ipld/go-codec-dagpb" _ "github.com/ipld/go-ipld-prime/codec/dagcbor" "github.com/ipld/go-ipld-prime/node/basicnode" - "github.com/mitchellh/go-homedir" ma "github.com/multiformats/go-multiaddr" manet "github.com/multiformats/go-multiaddr/net" ) @@ -82,7 +82,7 @@ func NewPathApi(ipfspath string) (*HttpApi, error) { // ApiAddr reads api file in specified ipfs path. func ApiAddr(ipfspath string) (ma.Multiaddr, error) { - baseDir, err := homedir.Expand(ipfspath) + baseDir, err := fsutil.ExpandHome(ipfspath) if err != nil { return nil, err } diff --git a/cmd/ipfswatch/main.go b/cmd/ipfswatch/main.go index 0f0283fb8..6850f6423 100644 --- a/cmd/ipfswatch/main.go +++ b/cmd/ipfswatch/main.go @@ -16,12 +16,12 @@ import ( core "github.com/ipfs/kubo/core" coreapi "github.com/ipfs/kubo/core/coreapi" corehttp "github.com/ipfs/kubo/core/corehttp" + "github.com/ipfs/kubo/misc/fsutil" fsrepo "github.com/ipfs/kubo/repo/fsrepo" fsnotify "github.com/fsnotify/fsnotify" "github.com/ipfs/boxo/files" process "github.com/jbenet/goprocess" - homedir "github.com/mitchellh/go-homedir" ) var ( @@ -57,7 +57,7 @@ func run(ipfsPath, watchPath string) error { proc := process.WithParent(process.Background()) log.Printf("running IPFSWatch on '%s' using repo at '%s'...", watchPath, ipfsPath) - ipfsPath, err := homedir.Expand(ipfsPath) + ipfsPath, err := fsutil.ExpandHome(ipfsPath) if err != nil { return err } diff --git a/config/config.go b/config/config.go index 6d91ff0f4..91fb219a2 100644 --- a/config/config.go +++ b/config/config.go @@ -9,7 +9,7 @@ import ( "path/filepath" "strings" - "github.com/mitchellh/go-homedir" + "github.com/ipfs/kubo/misc/fsutil" ) // Config is used to load ipfs config files. @@ -59,7 +59,7 @@ func PathRoot() (string, error) { dir := os.Getenv(EnvDir) var err error if len(dir) == 0 { - dir, err = homedir.Expand(DefaultPathRoot) + dir, err = fsutil.ExpandHome(DefaultPathRoot) } return dir, err } diff --git a/docs/changelogs/v0.32.md b/docs/changelogs/v0.32.md index 5e0e52406..0307de191 100644 --- a/docs/changelogs/v0.32.md +++ b/docs/changelogs/v0.32.md @@ -8,6 +8,7 @@ - [🔦 Highlights](#-highlights) - [🎯 AutoTLS: Automatic Certificates for libp2p WebSockets via `libp2p.direct`](#-autotls-automatic-certificates-for-libp2p-websockets-via-libp2pdirect) - [📦️ Boxo and go-libp2p updates](#-boxo-and-go-libp2p-updates) + - [Replaced dependency on archived `github.com/mitchellh/go-homedir`](replaced-go-homedir) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -31,6 +32,14 @@ See [`AutoTLS`](https://github.com/ipfs/kubo/blob/master/docs/config.md#autotls) - update `go-libp2p-kad-dht` to [v0.27.0](https://github.com/libp2p/go-libp2p-kad-dht/releases/tag/v0.27.0) - update `go-libp2p-pubsub` to [v0.12.0](https://github.com/libp2p/go-libp2p-pubsub/releases/tag/v0.12.0) +### Replaced go-homedir + +The `github.com/mitchellh/go-homedir` repo is archived, no longer needed, and no longer maintained. + +- `homedir.Dir` is replaced by the stdlib `os.UserHomeDir` +- `homedir.Expand` is replaced by `fsutil.ExpandHome` in the `github.com/ipfs/kubo/misc/fsutil` package. +- The new `github.com/ipfs/kubo/misc/fsutil` package contains file utility code previously located elsewhere in kubo. + ### 📝 Changelog ### 👨‍👩‍👧‍👦 Contributors diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 8bd0d902c..66b7eb202 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -144,7 +144,6 @@ require ( github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect github.com/minio/sha256-simd v1.0.1 // indirect - github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mr-tron/base58 v1.2.0 // indirect github.com/multiformats/go-base32 v0.1.0 // indirect github.com/multiformats/go-base36 v0.2.0 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 5e8860c8a..210f76f77 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -535,7 +535,6 @@ github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM= github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM= github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8= -github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= diff --git a/go.mod b/go.mod index cb53c5c6e..b46ffaaf0 100644 --- a/go.mod +++ b/go.mod @@ -64,7 +64,6 @@ require ( github.com/libp2p/go-libp2p-routing-helpers v0.7.4 github.com/libp2p/go-libp2p-testing v0.12.0 github.com/libp2p/go-socket-activation v0.1.0 - github.com/mitchellh/go-homedir v1.1.0 github.com/multiformats/go-multiaddr v0.13.0 github.com/multiformats/go-multiaddr-dns v0.4.0 github.com/multiformats/go-multibase v0.2.0 diff --git a/go.sum b/go.sum index f9255efdf..93f54daef 100644 --- a/go.sum +++ b/go.sum @@ -629,7 +629,6 @@ github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM= github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM= github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8= -github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= diff --git a/misc/fsutil/fsutil.go b/misc/fsutil/fsutil.go new file mode 100644 index 000000000..6773ec12f --- /dev/null +++ b/misc/fsutil/fsutil.go @@ -0,0 +1,82 @@ +package fsutil + +import ( + "errors" + "fmt" + "io/fs" + "os" + "path/filepath" +) + +// DirWritable checks if a directory is writable. If the directory does +// not exist it is created with writable permission. +func DirWritable(dir string) error { + if dir == "" { + return errors.New("directory not specified") + } + + var err error + dir, err = ExpandHome(dir) + if err != nil { + return err + } + + fi, err := os.Stat(dir) + if err != nil { + if errors.Is(err, fs.ErrNotExist) { + // Directory does not exist, so create it. + err = os.Mkdir(dir, 0775) + if err == nil { + return nil + } + } + if errors.Is(err, fs.ErrPermission) { + err = fs.ErrPermission + } + return fmt.Errorf("directory not writable: %s: %w", dir, err) + } + if !fi.IsDir() { + return fmt.Errorf("not a directory: %s", dir) + } + + // Directory exists, check that a file can be written. + file, err := os.CreateTemp(dir, "writetest") + if err != nil { + if errors.Is(err, fs.ErrPermission) { + err = fs.ErrPermission + } + return fmt.Errorf("directory not writable: %s: %w", dir, err) + } + file.Close() + return os.Remove(file.Name()) +} + +// ExpandHome expands the path to include the home directory if the path is +// prefixed with `~`. If it isn't prefixed with `~`, the path is returned +// as-is. +func ExpandHome(path string) (string, error) { + if path == "" { + return path, nil + } + + if path[0] != '~' { + return path, nil + } + + if len(path) > 1 && path[1] != '/' && path[1] != '\\' { + return "", errors.New("cannot expand user-specific home dir") + } + + dir, err := os.UserHomeDir() + if err != nil { + return "", err + } + + return filepath.Join(dir, path[1:]), nil +} + +// FileExists return true if the file exists +func FileExists(filename string) bool { + _, err := os.Lstat(filename) + return !errors.Is(err, os.ErrNotExist) +} diff --git a/misc/fsutil/fsutil_test.go b/misc/fsutil/fsutil_test.go new file mode 100644 index 000000000..72834ac10 --- /dev/null +++ b/misc/fsutil/fsutil_test.go @@ -0,0 +1,92 @@ +package fsutil_test + +import ( + "io/fs" + "os" + "path/filepath" + "runtime" + "testing" + + "github.com/ipfs/kubo/misc/fsutil" + "github.com/stretchr/testify/require" +) + +func TestDirWritable(t *testing.T) { + err := fsutil.DirWritable("") + require.Error(t, err) + + err = fsutil.DirWritable("~nosuchuser/tmp") + require.Error(t, err) + + tmpDir := t.TempDir() + + wrDir := filepath.Join(tmpDir, "readwrite") + err = fsutil.DirWritable(wrDir) + require.NoError(t, err) + + // Check that DirWritable created directory. + fi, err := os.Stat(wrDir) + require.NoError(t, err) + require.True(t, fi.IsDir()) + + err = fsutil.DirWritable(wrDir) + require.NoError(t, err) + + // If running on Windows, skip read-only directory tests. + if runtime.GOOS == "windows" { + t.SkipNow() + } + + roDir := filepath.Join(tmpDir, "readonly") + require.NoError(t, os.Mkdir(roDir, 0500)) + err = fsutil.DirWritable(roDir) + require.ErrorIs(t, err, fs.ErrPermission) + + roChild := filepath.Join(roDir, "child") + err = fsutil.DirWritable(roChild) + require.ErrorIs(t, err, fs.ErrPermission) +} + +func TestFileExists(t *testing.T) { + fileName := filepath.Join(t.TempDir(), "somefile") + require.False(t, fsutil.FileExists(fileName)) + + file, err := os.Create(fileName) + require.NoError(t, err) + file.Close() + + require.True(t, fsutil.FileExists(fileName)) +} + +func TestExpandHome(t *testing.T) { + dir, err := fsutil.ExpandHome("") + require.NoError(t, err) + require.Equal(t, "", dir) + + origDir := filepath.Join("somedir", "somesub") + dir, err = fsutil.ExpandHome(origDir) + require.NoError(t, err) + require.Equal(t, origDir, dir) + + _, err = fsutil.ExpandHome(filepath.FromSlash("~nosuchuser/somedir")) + require.Error(t, err) + + homeEnv := "HOME" + if runtime.GOOS == "windows" { + homeEnv = "USERPROFILE" + } + origHome := os.Getenv(homeEnv) + defer os.Setenv(homeEnv, origHome) + homeDir := filepath.Join(t.TempDir(), "testhome") + os.Setenv(homeEnv, homeDir) + + const subDir = "mytmp" + origDir = filepath.Join("~", subDir) + dir, err = fsutil.ExpandHome(origDir) + require.NoError(t, err) + require.Equal(t, filepath.Join(homeDir, subDir), dir) + + os.Unsetenv(homeEnv) + _, err = fsutil.ExpandHome(origDir) + require.Error(t, err) +} diff --git a/plugin/plugins/pebbleds/pebbleds.go b/plugin/plugins/pebbleds/pebbleds.go index 320fb3156..965dcce13 100644 --- a/plugin/plugins/pebbleds/pebbleds.go +++ b/plugin/plugins/pebbleds/pebbleds.go @@ -1,15 +1,13 @@ package pebbleds import ( - "errors" "fmt" - "io/fs" - "os" "path/filepath" "time" "github.com/cockroachdb/pebble" pebbleds "github.com/ipfs/go-ds-pebble" + "github.com/ipfs/kubo/misc/fsutil" "github.com/ipfs/kubo/plugin" "github.com/ipfs/kubo/repo" "github.com/ipfs/kubo/repo/fsrepo" @@ -172,75 +170,9 @@ func (c *datastoreConfig) Create(path string) (repo.Datastore, error) { p = filepath.Join(path, p) } - if err := dirWritable(p); err != nil { + if err := fsutil.DirWritable(p); err != nil { return nil, err } return pebbleds.NewDatastore(p, pebbleds.WithCacheSize(c.cacheSize), pebbleds.WithPebbleOpts(c.pebbleOpts)) } - -// dirWritable checks if a directory is writable. If the directory does -// not exist it is created with writable permission. -func dirWritable(dir string) error { - if dir == "" { - return errors.New("directory not specified") - } - var err error - dir, err = expandHome(dir) - if err != nil { - return err - } - - fi, err := os.Stat(dir) - if err != nil { - if errors.Is(err, fs.ErrNotExist) { - // Directory does not exist, so create it. - err = os.Mkdir(dir, 0775) - if err == nil { - return nil - } - } - if errors.Is(err, fs.ErrPermission) { - err = fs.ErrPermission - } - return fmt.Errorf("directory not writable: %s: %w", dir, err) - } - if !fi.IsDir() { - return fmt.Errorf("not a directory: %s", dir) - } - - // Directory exists, check that a file can be written. - file, err := os.CreateTemp(dir, "writetest") - if err != nil { - if errors.Is(err, fs.ErrPermission) { - err = fs.ErrPermission - } - return fmt.Errorf("directory not writable: %s: %w", dir, err) - } - file.Close() - return os.Remove(file.Name()) -} - -// expandHome expands the path to include the home directory if the path is -// prefixed with `~`. If it isn't prefixed with `~`, the path is returned -// as-is. -func expandHome(path string) (string, error) { - if path == "" { - return path, nil - } - - if path[0] != '~' { - return path, nil - } - - if len(path) > 1 && path[1] != '/' && path[1] != '\\' { - return "", errors.New("cannot expand user-specific home dir") - } - - dir, err := os.UserHomeDir() - if err != nil { - return "", err - } - - return filepath.Join(dir, path[1:]), nil -} diff --git a/repo/fsrepo/fsrepo.go b/repo/fsrepo/fsrepo.go index 6e9e01dab..b21b555cf 100644 --- a/repo/fsrepo/fsrepo.go +++ b/repo/fsrepo/fsrepo.go @@ -18,15 +18,14 @@ import ( dir "github.com/ipfs/kubo/thirdparty/dir" rcmgr "github.com/libp2p/go-libp2p/p2p/host/resource-manager" - util "github.com/ipfs/boxo/util" ds "github.com/ipfs/go-datastore" measure "github.com/ipfs/go-ds-measure" lockfile "github.com/ipfs/go-fs-lock" logging "github.com/ipfs/go-log" config "github.com/ipfs/kubo/config" serialize "github.com/ipfs/kubo/config/serialize" + "github.com/ipfs/kubo/misc/fsutil" "github.com/ipfs/kubo/repo/fsrepo/migrations" - homedir "github.com/mitchellh/go-homedir" ma "github.com/multiformats/go-multiaddr" ) @@ -207,7 +206,7 @@ func open(repoPath string, userConfigFilePath string) (repo.Repo, error) { } func newFSRepo(rpath string, userConfigFilePath string) (*FSRepo, error) { - expPath, err := homedir.Expand(filepath.Clean(rpath)) + expPath, err := fsutil.ExpandHome(filepath.Clean(rpath)) if err != nil { return nil, err } @@ -239,7 +238,7 @@ func configIsInitialized(path string) bool { if err != nil { return false } - if !util.FileExists(configFilename) { + if !fsutil.FileExists(configFilename) { return false } return true @@ -269,7 +268,7 @@ func initSpec(path string, conf map[string]interface{}) error { return err } - if util.FileExists(fn) { + if fsutil.FileExists(fn) { return nil } diff --git a/repo/fsrepo/migrations/ipfsdir.go b/repo/fsrepo/migrations/ipfsdir.go index 464118d1c..8cb087d53 100644 --- a/repo/fsrepo/migrations/ipfsdir.go +++ b/repo/fsrepo/migrations/ipfsdir.go @@ -8,7 +8,7 @@ import ( "strconv" "strings" - "github.com/mitchellh/go-homedir" + "github.com/ipfs/kubo/misc/fsutil" ) const ( @@ -17,10 +17,6 @@ const ( versionFile = "version" ) -func init() { - homedir.DisableCache = true -} - // IpfsDir returns the path of the ipfs directory. If dir specified, then // returns the expanded version dir. If dir is "", then return the directory // set by IPFS_PATH, or if IPFS_PATH is not set, then return the default @@ -31,14 +27,14 @@ func IpfsDir(dir string) (string, error) { dir = os.Getenv(envIpfsPath) } if dir != "" { - dir, err = homedir.Expand(dir) + dir, err = fsutil.ExpandHome(dir) if err != nil { return "", err } return dir, nil } - home, err := homedir.Dir() + home, err := os.UserHomeDir() if err != nil { return "", err } diff --git a/repo/fsrepo/misc.go b/repo/fsrepo/misc.go index 7824f2f4f..fa5b235e2 100644 --- a/repo/fsrepo/misc.go +++ b/repo/fsrepo/misc.go @@ -4,7 +4,7 @@ import ( "os" config "github.com/ipfs/kubo/config" - homedir "github.com/mitchellh/go-homedir" + "github.com/ipfs/kubo/misc/fsutil" ) // BestKnownPath returns the best known fsrepo path. If the ENV override is @@ -15,7 +15,7 @@ func BestKnownPath() (string, error) { if os.Getenv(config.EnvDir) != "" { ipfsPath = os.Getenv(config.EnvDir) } - ipfsPath, err := homedir.Expand(ipfsPath) + ipfsPath, err := fsutil.ExpandHome(ipfsPath) if err != nil { return "", err } From 1512ec5fa5dacda0aecd215b034d35c6f48e2195 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Thu, 7 Nov 2024 03:33:50 +0100 Subject: [PATCH 1210/1212] chore: boxo v0.24.3 and p2p-forge v0.0.2 (#10572) https://github.com/ipfs/boxo/releases/tag/v0.24.3 https://github.com/ipshipyard/p2p-forge/releases/tag/v0.0.2 --- docs/changelogs/v0.32.md | 21 +++---- docs/examples/kubo-as-a-library/go.mod | 42 ++++++------- docs/examples/kubo-as-a-library/go.sum | 84 +++++++++++++------------- go.mod | 42 ++++++------- go.sum | 84 +++++++++++++------------- test/dependencies/go.mod | 12 ++-- test/dependencies/go.sum | 24 ++++---- 7 files changed, 153 insertions(+), 156 deletions(-) diff --git a/docs/changelogs/v0.32.md b/docs/changelogs/v0.32.md index 0307de191..ca8a79bc2 100644 --- a/docs/changelogs/v0.32.md +++ b/docs/changelogs/v0.32.md @@ -7,8 +7,7 @@ - [Overview](#overview) - [🔦 Highlights](#-highlights) - [🎯 AutoTLS: Automatic Certificates for libp2p WebSockets via `libp2p.direct`](#-autotls-automatic-certificates-for-libp2p-websockets-via-libp2pdirect) - - [📦️ Boxo and go-libp2p updates](#-boxo-and-go-libp2p-updates) - - [Replaced dependency on archived `github.com/mitchellh/go-homedir`](replaced-go-homedir) + - [📦️ Dependency updates](#-dependency-updates) - [📝 Changelog](#-changelog) - [👨‍👩‍👧‍👦 Contributors](#-contributors) @@ -23,22 +22,20 @@ Opt-in configuration allows Kubo nodes to obtain CA-signed TLS certificates for See [`AutoTLS`](https://github.com/ipfs/kubo/blob/master/docs/config.md#autotls) configuration for details how to enable it. We appreciate you testing and providing an early feedback in [kubo#10560](https://github.com/ipfs/kubo/issues/10560). -#### 📦️ Boxo and go-libp2p updates +#### 📦️ Dependency updates -- update `boxo` to [v0.24.1](https://github.com/ipfs/boxo/releases/tag/v0.24.1) + [v0.24.2](https://github.com/ipfs/boxo/releases/tag/v0.24.2) +- update `boxo` to [v0.24.1](https://github.com/ipfs/boxo/releases/tag/v0.24.1) + [v0.24.2](https://github.com/ipfs/boxo/releases/tag/v0.24.2) + [v0.24.3](https://github.com/ipfs/boxo/releases/tag/v0.24.3) - This includes a number of fixes and bitswap improvements, and support for filtering from [IPIP-484](https://specs.ipfs.tech/ipips/ipip-0484/) in delegated HTTP routing and IPNI queries. - update `go-libp2p` to [v0.37.0](https://github.com/libp2p/go-libp2p/releases/tag/v0.37.0) - This update required removal of `Swarm.RelayService.MaxReservationsPerPeer` configuration option from Kubo. If you had it set, remove it from your configuration file. - update `go-libp2p-kad-dht` to [v0.27.0](https://github.com/libp2p/go-libp2p-kad-dht/releases/tag/v0.27.0) - update `go-libp2p-pubsub` to [v0.12.0](https://github.com/libp2p/go-libp2p-pubsub/releases/tag/v0.12.0) - -### Replaced go-homedir - -The `github.com/mitchellh/go-homedir` repo is archived, no longer needed, and no longer maintained. - -- `homedir.Dir` is replaced by the stdlib `os.UserHomeDir` -- `homedir.Expand` is replaced by `fsutil.ExpandHome` in the `github.com/ipfs/kubo/misc/fsutil` package. -- The new `github.com/ipfs/kubo/misc/fsutil` package contains file utility code previously located elsewhere in kubo. +- update `p2p-forge/client` to [v0.0.2](https://github.com/ipshipyard/p2p-forge/releases/tag/v0.0.2) +- removed `go-homedir` + - The `github.com/mitchellh/go-homedir` repo is archived, no longer needed, and no longer maintained. + - `homedir.Dir` is replaced by the stdlib `os.UserHomeDir` + - `homedir.Expand` is replaced by `fsutil.ExpandHome` in the `github.com/ipfs/kubo/misc/fsutil` package. + - The new `github.com/ipfs/kubo/misc/fsutil` package contains file utility code previously located elsewhere in kubo. ### 📝 Changelog diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 66b7eb202..69cd5cec2 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.23 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.24.2 + github.com/ipfs/boxo v0.24.3 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.37.0 github.com/multiformats/go-multiaddr v0.13.0 @@ -18,7 +18,7 @@ require ( github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 // indirect github.com/DataDog/zstd v1.4.5 // indirect github.com/Jorropo/jsync v1.0.1 // indirect - github.com/alecthomas/units v0.0.0-20240626203959-61d1e3462e30 // indirect + github.com/alecthomas/units v0.0.0-20240927000941-0f3dac36c52b // indirect github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5 // indirect github.com/benbjohnson/clock v1.3.5 // indirect github.com/beorn7/perks v1.0.1 // indirect @@ -36,7 +36,7 @@ require ( github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect github.com/containerd/cgroups v1.1.0 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect - github.com/crackcomm/go-gitignore v0.0.0-20231225121904-e25f5bc08668 // indirect + github.com/crackcomm/go-gitignore v0.0.0-20241020182519-7843d2ba8fdf // indirect github.com/cskr/pubsub v1.0.2 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect @@ -51,7 +51,7 @@ require ( github.com/flynn/noise v1.1.0 // indirect github.com/francoispqt/gojay v1.2.13 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect - github.com/gabriel-vasile/mimetype v1.4.4 // indirect + github.com/gabriel-vasile/mimetype v1.4.6 // indirect github.com/getsentry/sentry-go v0.27.0 // indirect github.com/go-jose/go-jose/v4 v4.0.4 // indirect github.com/go-logr/logr v1.4.2 // indirect @@ -59,14 +59,14 @@ require ( github.com/go-task/slim-sprig/v3 v3.0.0 // indirect github.com/godbus/dbus/v5 v5.1.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang/glog v1.2.1 // indirect + github.com/golang/glog v1.2.2 // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/gopacket v1.1.19 // indirect github.com/google/pprof v0.0.0-20241017200806-017d972448fc // indirect github.com/google/uuid v1.6.0 // indirect github.com/gorilla/websocket v1.5.3 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/golang-lru v1.0.2 // indirect @@ -109,7 +109,7 @@ require ( github.com/ipld/go-car/v2 v2.14.2 // indirect github.com/ipld/go-codec-dagpb v1.6.0 // indirect github.com/ipld/go-ipld-prime v0.21.0 // indirect - github.com/ipshipyard/p2p-forge v0.0.1 // indirect + github.com/ipshipyard/p2p-forge v0.0.2 // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect github.com/jbenet/goprocess v0.1.4 // indirect @@ -189,7 +189,7 @@ require ( github.com/quic-go/webtransport-go v0.8.1-0.20241018022711-4ac2c9250e66 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/rogpeppe/go-internal v1.13.1 // indirect - github.com/samber/lo v1.46.0 // indirect + github.com/samber/lo v1.47.0 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/stretchr/testify v1.9.0 // indirect github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect @@ -203,16 +203,16 @@ require ( github.com/wlynxg/anet v0.0.5 // indirect github.com/zeebo/blake3 v0.2.4 // indirect go.opencensus.io v0.24.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.52.0 // indirect - go.opentelemetry.io/otel v1.28.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.27.0 // indirect - go.opentelemetry.io/otel/exporters/zipkin v1.27.0 // indirect - go.opentelemetry.io/otel/metric v1.28.0 // indirect - go.opentelemetry.io/otel/sdk v1.27.0 // indirect - go.opentelemetry.io/otel/trace v1.28.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0 // indirect + go.opentelemetry.io/otel v1.31.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.31.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.31.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.31.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.31.0 // indirect + go.opentelemetry.io/otel/exporters/zipkin v1.31.0 // indirect + go.opentelemetry.io/otel/metric v1.31.0 // indirect + go.opentelemetry.io/otel/sdk v1.31.0 // indirect + go.opentelemetry.io/otel/trace v1.31.0 // indirect go.opentelemetry.io/proto/otlp v1.3.1 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/dig v1.18.0 // indirect @@ -231,9 +231,9 @@ require ( golang.org/x/tools v0.26.0 // indirect golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect gonum.org/v1/gonum v0.15.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240617180043-68d350f18fd4 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240617180043-68d350f18fd4 // indirect - google.golang.org/grpc v1.64.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20241007155032-5fefd90f89a9 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9 // indirect + google.golang.org/grpc v1.67.1 // indirect google.golang.org/protobuf v1.35.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect lukechampine.com/blake3 v1.3.0 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 210f76f77..e12055d92 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -35,8 +35,8 @@ github.com/Jorropo/jsync v1.0.1 h1:6HgRolFZnsdfzRUj+ImB9og1JYOxQoReSywkHOGSaUU= github.com/Jorropo/jsync v1.0.1/go.mod h1:jCOZj3vrBCri3bSU3ErUYvevKlnbssrXeCivybS5ABQ= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= -github.com/alecthomas/units v0.0.0-20240626203959-61d1e3462e30 h1:t3eaIm0rUkzbrIewtiFmMK5RXHej2XnoXNhxVsAYUfg= -github.com/alecthomas/units v0.0.0-20240626203959-61d1e3462e30/go.mod h1:fvzegU4vN3H1qMT+8wDmzjAcDONcgo2/SZ/TyfdUOFs= +github.com/alecthomas/units v0.0.0-20240927000941-0f3dac36c52b h1:mimo19zliBX/vSQ6PWWSL9lK8qwHozUj03+zLoEB8O0= +github.com/alecthomas/units v0.0.0-20240927000941-0f3dac36c52b/go.mod h1:fvzegU4vN3H1qMT+8wDmzjAcDONcgo2/SZ/TyfdUOFs= github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5 h1:iW0a5ljuFxkLGPNem5Ui+KBjFJzKg4Fv2fnxe4dvzpM= github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5/go.mod h1:Y2QMoi1vgtOIfc+6DhrMOGkLoGzqSV2rKp4Sm+opsyA= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= @@ -108,8 +108,8 @@ github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSV 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-20231225121904-e25f5bc08668 h1:ZFUue+PNxmHlu7pYv+IYMtqlaO/0VwaGEqKepZf9JpA= -github.com/crackcomm/go-gitignore v0.0.0-20231225121904-e25f5bc08668/go.mod h1:p1d6YEZWvFzEh4KLyvBcVSnrfNDDvK2zfK/4x2v/4pE= +github.com/crackcomm/go-gitignore v0.0.0-20241020182519-7843d2ba8fdf h1:dwGgBWn84wUS1pVikGiruW+x5XM4amhjaZO20vCjay4= +github.com/crackcomm/go-gitignore v0.0.0-20241020182519-7843d2ba8fdf/go.mod h1:p1d6YEZWvFzEh4KLyvBcVSnrfNDDvK2zfK/4x2v/4pE= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cskr/pubsub v1.0.2 h1:vlOzMhl6PFn60gRlTQQsIfVwaPB/B/8MziK8FhEPt/0= github.com/cskr/pubsub v1.0.2/go.mod h1:/8MzYXk/NJAz782G8RPkFzXTZVu63VotefPnR9TIRis= @@ -162,8 +162,8 @@ github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4 github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= -github.com/gabriel-vasile/mimetype v1.4.4 h1:QjV6pZ7/XZ7ryI2KuyeEDE8wnh7fHP9YnQy+R0LnH8I= -github.com/gabriel-vasile/mimetype v1.4.4/go.mod h1:JwLei5XPtWdGiMFB5Pjle1oEeoSeEuJfJE+TtfvdB/s= +github.com/gabriel-vasile/mimetype v1.4.6 h1:3+PzJTKLkvgjeTbts6msPJt4DixhT4YtFNf1gtGe3zc= +github.com/gabriel-vasile/mimetype v1.4.6/go.mod h1:JX1qVKqZd40hUPpAfiNTe0Sne7hdfKSbOqqmkq8GCXc= github.com/getsentry/sentry-go v0.27.0 h1:Pv98CIbtB3LkMWmXi4Joa5OOcwbmnX88sF5qbK3r3Ps= github.com/getsentry/sentry-go v0.27.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= @@ -196,8 +196,8 @@ github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXP github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.2.1 h1:OptwRhECazUx5ix5TTWC3EZhsZEHWcYWY4FQHTIubm4= -github.com/golang/glog v1.2.1/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= +github.com/golang/glog v1.2.2 h1:1+mZ9upx1Dh6FmUTFR1naJ77miKiXgALjWOZ3NVFPmY= +github.com/golang/glog v1.2.2/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -270,8 +270,8 @@ github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aN github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -298,8 +298,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.24.2 h1:feLM6DY6CNI0uSG3TvP/Hv4PdM/fsekjqSCqKtifF0E= -github.com/ipfs/boxo v0.24.2/go.mod h1:Dt3TJjMZtF2QksMv2LC8pQlG9VQUiSV2DsHQzvDiroo= +github.com/ipfs/boxo v0.24.3 h1:gldDPOWdM3Rz0v5LkVLtZu7A7gFNvAlWcmxhCqlHR3c= +github.com/ipfs/boxo v0.24.3/go.mod h1:h0DRzOY1IBFDHp6KNvrJLMFdSXTYID0Zf+q7X05JsNg= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= @@ -401,8 +401,8 @@ github.com/ipld/go-ipld-prime v0.21.0 h1:n4JmcpOlPDIxBcY037SVfpd1G+Sj1nKZah0m6QH github.com/ipld/go-ipld-prime v0.21.0/go.mod h1:3RLqy//ERg/y5oShXXdx5YIp50cFGOanyMctpPjsvxQ= github.com/ipld/go-ipld-prime/storage/bsadapter v0.0.0-20230102063945-1a409dc236dd h1:gMlw/MhNr2Wtp5RwGdsW23cs+yCuj9k2ON7i9MiJlRo= github.com/ipld/go-ipld-prime/storage/bsadapter v0.0.0-20230102063945-1a409dc236dd/go.mod h1:wZ8hH8UxeryOs4kJEJaiui/s00hDSbE37OKsL47g+Sw= -github.com/ipshipyard/p2p-forge v0.0.1 h1:7Wy3Ul4gGLIPx4LjMjGaO6MoKa54ITDqwMOyXshrvO4= -github.com/ipshipyard/p2p-forge v0.0.1/go.mod h1:taPeh3PDSO8Ual0/N2tIOAUXPV8gZoPF3uPXoUyiq14= +github.com/ipshipyard/p2p-forge v0.0.2 h1:86y9LxGB8sGxYQ/If5sNx+c8C/huSpBUg3UZ1uvtym8= +github.com/ipshipyard/p2p-forge v0.0.2/go.mod h1:taPeh3PDSO8Ual0/N2tIOAUXPV8gZoPF3uPXoUyiq14= github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/jbenet/go-cienv v0.1.0 h1:Vc/s0QbQtoxX8MwwSLWWh+xNNZvM3Lw7NsTcHrvvhMc= @@ -703,8 +703,8 @@ github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWN github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd/go.mod h1:hPqNNc0+uJM6H+SuU8sEs5K5IQeKccPqeSjfgcKGgPk= -github.com/samber/lo v1.46.0 h1:w8G+oaCPgz1PoCJztqymCFaKwXt+5cCXn51uPxExFfQ= -github.com/samber/lo v1.46.0/go.mod h1:RmDH9Ct32Qy3gduHQuKJ3gW1fMHAnE/fAzQuf6He5cU= +github.com/samber/lo v1.47.0 h1:z7RynLwP5nbyRscyvcD043DWYoOcYRv3mV8lBeqOCLc= +github.com/samber/lo v1.47.0/go.mod h1:RmDH9Ct32Qy3gduHQuKJ3gW1fMHAnE/fAzQuf6He5cU= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY= github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM= @@ -825,26 +825,26 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.52.0 h1:9l89oX4ba9kHbBol3Xin3leYJ+252h0zszDtBwyKe2A= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.52.0/go.mod h1:XLZfZboOJWHNKUv7eH0inh0E9VV6eWDFB/9yJyTLPp0= -go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= -go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 h1:R9DE4kQ4k+YtfLI2ULwX82VtNQ2J8yZmA7ZIF/D+7Mc= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0/go.mod h1:OQFyQVrDlbe+R7xrEyDr/2Wr67Ol0hRUgsfA+V5A95s= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 h1:qFffATk0X+HD+f1Z8lswGiOQYKHRlzfmdJm0wEaVrFA= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0/go.mod h1:MOiCmryaYtc+V0Ei+Tx9o5S1ZjA7kzLucuVuyzBZloQ= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.0 h1:QY7/0NeRPKlzusf40ZE4t1VlMKbqSNT7cJRYzWuja0s= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.0/go.mod h1:HVkSiDhTM9BoUJU8qE6j2eSWLLXvi1USXjyd2BXT8PY= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.27.0 h1:/0YaXu3755A/cFbtXp+21lkXgI0QE5avTWA2HjU9/WE= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.27.0/go.mod h1:m7SFxp0/7IxmJPLIY3JhOcU9CoFzDaCPL6xxQIxhA+o= -go.opentelemetry.io/otel/exporters/zipkin v1.27.0 h1:aXcxb7F6ZDC1o2Z52LDfS2g6M2FB5CrxdR2gzY4QRNs= -go.opentelemetry.io/otel/exporters/zipkin v1.27.0/go.mod h1:+WMURoi4KmVB7ypbFPx3xtZTWen2Ca3lRK9u6DVTO5M= -go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q= -go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s= -go.opentelemetry.io/otel/sdk v1.27.0 h1:mlk+/Y1gLPLn84U4tI8d3GNJmGT/eXe3ZuOXN9kTWmI= -go.opentelemetry.io/otel/sdk v1.27.0/go.mod h1:Ha9vbLwJE6W86YstIywK2xFfPjbWlCuwPtMkKdz/Y4A= -go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= -go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0 h1:UP6IpuHFkUgOQL9FFQFrZ+5LiwhhYRbi7VZSIx6Nj5s= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0/go.mod h1:qxuZLtbq5QDtdeSHsS7bcf6EH6uO6jUAgk764zd3rhM= +go.opentelemetry.io/otel v1.31.0 h1:NsJcKPIW0D0H3NgzPDHmo0WW6SptzPdqg/L1zsIm2hY= +go.opentelemetry.io/otel v1.31.0/go.mod h1:O0C14Yl9FgkjqcCZAsE053C13OaddMYr/hz6clDkEJE= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.31.0 h1:K0XaT3DwHAcV4nKLzcQvwAgSyisUghWoY20I7huthMk= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.31.0/go.mod h1:B5Ki776z/MBnVha1Nzwp5arlzBbE3+1jk+pGmaP5HME= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.31.0 h1:FFeLy03iVTXP6ffeN2iXrxfGsZGCjVx0/4KlizjyBwU= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.31.0/go.mod h1:TMu73/k1CP8nBUpDLc71Wj/Kf7ZS9FK5b53VapRsP9o= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.31.0 h1:lUsI2TYsQw2r1IASwoROaCnjdj2cvC2+Jbxvk6nHnWU= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.31.0/go.mod h1:2HpZxxQurfGxJlJDblybejHB6RX6pmExPNe517hREw4= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.31.0 h1:UGZ1QwZWY67Z6BmckTU+9Rxn04m2bD3gD6Mk0OIOCPk= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.31.0/go.mod h1:fcwWuDuaObkkChiDlhEpSq9+X1C0omv+s5mBtToAQ64= +go.opentelemetry.io/otel/exporters/zipkin v1.31.0 h1:CgucL0tj3717DJnni7HVVB2wExzi8c2zJNEA2BhLMvI= +go.opentelemetry.io/otel/exporters/zipkin v1.31.0/go.mod h1:rfzOVNiSwIcWtEC2J8epwG26fiaXlYvLySJ7bwsrtAE= +go.opentelemetry.io/otel/metric v1.31.0 h1:FSErL0ATQAmYHUIzSezZibnyVlft1ybhy4ozRPcF2fE= +go.opentelemetry.io/otel/metric v1.31.0/go.mod h1:C3dEloVbLuYoX41KpmAhOqNriGbA+qqH6PQ5E5mUfnY= +go.opentelemetry.io/otel/sdk v1.31.0 h1:xLY3abVHYZ5HSfOg3l2E5LUj2Cwva5Y7yGxnSW9H5Gk= +go.opentelemetry.io/otel/sdk v1.31.0/go.mod h1:TfRbMdhvxIIr/B2N2LQW2S5v9m3gOQ/08KsbbO5BPT0= +go.opentelemetry.io/otel/trace v1.31.0 h1:ffjsj1aRouKewfr85U2aGagJ46+MvodynlQ1HYdmJys= +go.opentelemetry.io/otel/trace v1.31.0/go.mod h1:TXZkRk7SM2ZQLtR6eoAWQFIHPvzQ06FJAsO1tJg480A= go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= @@ -1160,10 +1160,10 @@ google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvx google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto/googleapis/api v0.0.0-20240617180043-68d350f18fd4 h1:MuYw1wJzT+ZkybKfaOXKp5hJiZDn2iHaXRw0mRYdHSc= -google.golang.org/genproto/googleapis/api v0.0.0-20240617180043-68d350f18fd4/go.mod h1:px9SlOOZBg1wM1zdnr8jEL4CNGUBZ+ZKYtNPApNQc4c= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240617180043-68d350f18fd4 h1:Di6ANFilr+S60a4S61ZM00vLdw0IrQOSMS2/6mrnOU0= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240617180043-68d350f18fd4/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= +google.golang.org/genproto/googleapis/api v0.0.0-20241007155032-5fefd90f89a9 h1:T6rh4haD3GVYsgEfWExoCZA2o2FmbNyKpTuAxbEFPTg= +google.golang.org/genproto/googleapis/api v0.0.0-20241007155032-5fefd90f89a9/go.mod h1:wp2WsuBYj6j8wUdo3ToZsdxxixbvQNAHqVJrTgi5E5M= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9 h1:QCqS/PdaHTSWGvupk2F/ehwHtGc0/GYkT+3GAcR1CCc= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= @@ -1176,8 +1176,8 @@ google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8 google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.64.0 h1:KH3VH9y/MgNQg1dE7b3XfVK0GsPSIzJwdF617gUSbvY= -google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg= +google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= +google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/go.mod b/go.mod index b46ffaaf0..46e0fa9a5 100644 --- a/go.mod +++ b/go.mod @@ -22,7 +22,7 @@ require ( github.com/hashicorp/go-version v1.7.0 github.com/ipfs-shipyard/nopfs v0.0.12 github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c - github.com/ipfs/boxo v0.24.2 + github.com/ipfs/boxo v0.24.3 github.com/ipfs/go-block-format v0.2.0 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 @@ -49,7 +49,7 @@ require ( github.com/ipld/go-car/v2 v2.14.2 github.com/ipld/go-codec-dagpb v1.6.0 github.com/ipld/go-ipld-prime v0.21.0 - github.com/ipshipyard/p2p-forge v0.0.1 + github.com/ipshipyard/p2p-forge v0.0.2 github.com/jbenet/go-temp-err-catcher v0.1.0 github.com/jbenet/goprocess v0.1.4 github.com/julienschmidt/httprouter v1.3.0 @@ -79,11 +79,11 @@ 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.24.0 - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.52.0 + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0 go.opentelemetry.io/contrib/propagators/autoprop v0.46.1 - go.opentelemetry.io/otel v1.28.0 - go.opentelemetry.io/otel/sdk v1.27.0 - go.opentelemetry.io/otel/trace v1.28.0 + go.opentelemetry.io/otel v1.31.0 + go.opentelemetry.io/otel/sdk v1.31.0 + go.opentelemetry.io/otel/trace v1.31.0 go.uber.org/dig v1.18.0 go.uber.org/fx v1.23.0 go.uber.org/multierr v1.11.0 @@ -100,7 +100,7 @@ require ( github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 // indirect github.com/DataDog/zstd v1.4.5 // indirect github.com/Jorropo/jsync v1.0.1 // indirect - github.com/alecthomas/units v0.0.0-20240626203959-61d1e3462e30 // indirect + github.com/alecthomas/units v0.0.0-20240927000941-0f3dac36c52b // indirect github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/caddyserver/zerossl v0.1.3 // indirect @@ -111,7 +111,7 @@ require ( github.com/cockroachdb/redact v1.1.5 // indirect github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect github.com/containerd/cgroups v1.1.0 // indirect - github.com/crackcomm/go-gitignore v0.0.0-20231225121904-e25f5bc08668 // indirect + github.com/crackcomm/go-gitignore v0.0.0-20241020182519-7843d2ba8fdf // indirect github.com/cskr/pubsub v1.0.2 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect @@ -124,7 +124,7 @@ require ( github.com/felixge/httpsnoop v1.0.4 // indirect github.com/flynn/noise v1.1.0 // indirect github.com/francoispqt/gojay v1.2.13 // indirect - github.com/gabriel-vasile/mimetype v1.4.4 // indirect + github.com/gabriel-vasile/mimetype v1.4.6 // indirect github.com/getsentry/sentry-go v0.27.0 // indirect github.com/go-jose/go-jose/v4 v4.0.4 // indirect github.com/go-kit/log v0.2.1 // indirect @@ -134,7 +134,7 @@ require ( github.com/go-task/slim-sprig/v3 v3.0.0 // indirect github.com/godbus/dbus/v5 v5.1.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang/glog v1.2.0 // indirect + github.com/golang/glog v1.2.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/golang/snappy v0.0.4 // indirect @@ -142,7 +142,7 @@ require ( github.com/google/pprof v0.0.0-20241017200806-017d972448fc // indirect github.com/gorilla/mux v1.8.1 // indirect github.com/gorilla/websocket v1.5.3 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/golang-lru v1.0.2 // indirect github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect @@ -230,7 +230,7 @@ require ( github.com/rivo/uniseg v0.4.4 // indirect github.com/rogpeppe/go-internal v1.13.1 // indirect github.com/rs/cors v1.11.1 // indirect - github.com/samber/lo v1.46.0 // indirect + github.com/samber/lo v1.47.0 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/texttheater/golang-levenshtein v1.0.1 // indirect github.com/tidwall/match v1.1.1 // indirect @@ -247,12 +247,12 @@ require ( go.opentelemetry.io/contrib/propagators/b3 v1.21.1 // indirect go.opentelemetry.io/contrib/propagators/jaeger v1.21.1 // indirect go.opentelemetry.io/contrib/propagators/ot v1.21.1 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.27.0 // indirect - go.opentelemetry.io/otel/exporters/zipkin v1.27.0 // indirect - go.opentelemetry.io/otel/metric v1.28.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.31.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.31.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.31.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.31.0 // indirect + go.opentelemetry.io/otel/exporters/zipkin v1.31.0 // indirect + go.opentelemetry.io/otel/metric v1.31.0 // indirect go.opentelemetry.io/proto/otlp v1.3.1 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/mock v0.5.0 // indirect @@ -264,9 +264,9 @@ require ( golang.org/x/tools v0.26.0 // indirect golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect gonum.org/v1/gonum v0.15.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240617180043-68d350f18fd4 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240617180043-68d350f18fd4 // indirect - google.golang.org/grpc v1.64.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20241007155032-5fefd90f89a9 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9 // indirect + google.golang.org/grpc v1.67.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect lukechampine.com/blake3 v1.3.0 // indirect diff --git a/go.sum b/go.sum index 93f54daef..b0a1e4cc0 100644 --- a/go.sum +++ b/go.sum @@ -59,8 +59,8 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= -github.com/alecthomas/units v0.0.0-20240626203959-61d1e3462e30 h1:t3eaIm0rUkzbrIewtiFmMK5RXHej2XnoXNhxVsAYUfg= -github.com/alecthomas/units v0.0.0-20240626203959-61d1e3462e30/go.mod h1:fvzegU4vN3H1qMT+8wDmzjAcDONcgo2/SZ/TyfdUOFs= +github.com/alecthomas/units v0.0.0-20240927000941-0f3dac36c52b h1:mimo19zliBX/vSQ6PWWSL9lK8qwHozUj03+zLoEB8O0= +github.com/alecthomas/units v0.0.0-20240927000941-0f3dac36c52b/go.mod h1:fvzegU4vN3H1qMT+8wDmzjAcDONcgo2/SZ/TyfdUOFs= github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5 h1:iW0a5ljuFxkLGPNem5Ui+KBjFJzKg4Fv2fnxe4dvzpM= github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5/go.mod h1:Y2QMoi1vgtOIfc+6DhrMOGkLoGzqSV2rKp4Sm+opsyA= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= @@ -137,8 +137,8 @@ github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSV 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-20231225121904-e25f5bc08668 h1:ZFUue+PNxmHlu7pYv+IYMtqlaO/0VwaGEqKepZf9JpA= -github.com/crackcomm/go-gitignore v0.0.0-20231225121904-e25f5bc08668/go.mod h1:p1d6YEZWvFzEh4KLyvBcVSnrfNDDvK2zfK/4x2v/4pE= +github.com/crackcomm/go-gitignore v0.0.0-20241020182519-7843d2ba8fdf h1:dwGgBWn84wUS1pVikGiruW+x5XM4amhjaZO20vCjay4= +github.com/crackcomm/go-gitignore v0.0.0-20241020182519-7843d2ba8fdf/go.mod h1:p1d6YEZWvFzEh4KLyvBcVSnrfNDDvK2zfK/4x2v/4pE= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cskr/pubsub v1.0.2 h1:vlOzMhl6PFn60gRlTQQsIfVwaPB/B/8MziK8FhEPt/0= github.com/cskr/pubsub v1.0.2/go.mod h1:/8MzYXk/NJAz782G8RPkFzXTZVu63VotefPnR9TIRis= @@ -196,8 +196,8 @@ github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4 github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= -github.com/gabriel-vasile/mimetype v1.4.4 h1:QjV6pZ7/XZ7ryI2KuyeEDE8wnh7fHP9YnQy+R0LnH8I= -github.com/gabriel-vasile/mimetype v1.4.4/go.mod h1:JwLei5XPtWdGiMFB5Pjle1oEeoSeEuJfJE+TtfvdB/s= +github.com/gabriel-vasile/mimetype v1.4.6 h1:3+PzJTKLkvgjeTbts6msPJt4DixhT4YtFNf1gtGe3zc= +github.com/gabriel-vasile/mimetype v1.4.6/go.mod h1:JX1qVKqZd40hUPpAfiNTe0Sne7hdfKSbOqqmkq8GCXc= github.com/getsentry/sentry-go v0.27.0 h1:Pv98CIbtB3LkMWmXi4Joa5OOcwbmnX88sF5qbK3r3Ps= github.com/getsentry/sentry-go v0.27.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= @@ -243,8 +243,8 @@ github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXP github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.2.0 h1:uCdmnmatrKCgMBlM4rMuJZWOkPDqdbZPnrMXDY4gI68= -github.com/golang/glog v1.2.0/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= +github.com/golang/glog v1.2.2 h1:1+mZ9upx1Dh6FmUTFR1naJ77miKiXgALjWOZ3NVFPmY= +github.com/golang/glog v1.2.2/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -331,8 +331,8 @@ github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aN github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -361,8 +361,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.24.2 h1:feLM6DY6CNI0uSG3TvP/Hv4PdM/fsekjqSCqKtifF0E= -github.com/ipfs/boxo v0.24.2/go.mod h1:Dt3TJjMZtF2QksMv2LC8pQlG9VQUiSV2DsHQzvDiroo= +github.com/ipfs/boxo v0.24.3 h1:gldDPOWdM3Rz0v5LkVLtZu7A7gFNvAlWcmxhCqlHR3c= +github.com/ipfs/boxo v0.24.3/go.mod h1:h0DRzOY1IBFDHp6KNvrJLMFdSXTYID0Zf+q7X05JsNg= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= @@ -468,8 +468,8 @@ github.com/ipld/go-ipld-prime v0.21.0 h1:n4JmcpOlPDIxBcY037SVfpd1G+Sj1nKZah0m6QH github.com/ipld/go-ipld-prime v0.21.0/go.mod h1:3RLqy//ERg/y5oShXXdx5YIp50cFGOanyMctpPjsvxQ= github.com/ipld/go-ipld-prime/storage/bsadapter v0.0.0-20230102063945-1a409dc236dd h1:gMlw/MhNr2Wtp5RwGdsW23cs+yCuj9k2ON7i9MiJlRo= github.com/ipld/go-ipld-prime/storage/bsadapter v0.0.0-20230102063945-1a409dc236dd/go.mod h1:wZ8hH8UxeryOs4kJEJaiui/s00hDSbE37OKsL47g+Sw= -github.com/ipshipyard/p2p-forge v0.0.1 h1:7Wy3Ul4gGLIPx4LjMjGaO6MoKa54ITDqwMOyXshrvO4= -github.com/ipshipyard/p2p-forge v0.0.1/go.mod h1:taPeh3PDSO8Ual0/N2tIOAUXPV8gZoPF3uPXoUyiq14= +github.com/ipshipyard/p2p-forge v0.0.2 h1:86y9LxGB8sGxYQ/If5sNx+c8C/huSpBUg3UZ1uvtym8= +github.com/ipshipyard/p2p-forge v0.0.2/go.mod h1:taPeh3PDSO8Ual0/N2tIOAUXPV8gZoPF3uPXoUyiq14= github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/jbenet/go-cienv v0.1.0 h1:Vc/s0QbQtoxX8MwwSLWWh+xNNZvM3Lw7NsTcHrvvhMc= @@ -832,8 +832,8 @@ github.com/rs/cors v1.11.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd/go.mod h1:hPqNNc0+uJM6H+SuU8sEs5K5IQeKccPqeSjfgcKGgPk= -github.com/samber/lo v1.46.0 h1:w8G+oaCPgz1PoCJztqymCFaKwXt+5cCXn51uPxExFfQ= -github.com/samber/lo v1.46.0/go.mod h1:RmDH9Ct32Qy3gduHQuKJ3gW1fMHAnE/fAzQuf6He5cU= +github.com/samber/lo v1.47.0 h1:z7RynLwP5nbyRscyvcD043DWYoOcYRv3mV8lBeqOCLc= +github.com/samber/lo v1.47.0/go.mod h1:RmDH9Ct32Qy3gduHQuKJ3gW1fMHAnE/fAzQuf6He5cU= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY= github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM= @@ -976,8 +976,8 @@ go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.52.0 h1:9l89oX4ba9kHbBol3Xin3leYJ+252h0zszDtBwyKe2A= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.52.0/go.mod h1:XLZfZboOJWHNKUv7eH0inh0E9VV6eWDFB/9yJyTLPp0= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0 h1:UP6IpuHFkUgOQL9FFQFrZ+5LiwhhYRbi7VZSIx6Nj5s= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0/go.mod h1:qxuZLtbq5QDtdeSHsS7bcf6EH6uO6jUAgk764zd3rhM= go.opentelemetry.io/contrib/propagators/autoprop v0.46.1 h1:cXTYcMjY0dsYokAuo8LbNBQxpF8VgTHdiHJJ1zlIXl4= go.opentelemetry.io/contrib/propagators/autoprop v0.46.1/go.mod h1:WZxgny1/6+j67B1s72PLJ4bGjidoWFzSmLNfJKVt2bo= go.opentelemetry.io/contrib/propagators/aws v1.21.1 h1:uQIQIDWb0gzyvon2ICnghpLAf9w7ADOCUiIiwCQgR2o= @@ -988,24 +988,24 @@ go.opentelemetry.io/contrib/propagators/jaeger v1.21.1 h1:f4beMGDKiVzg9IcX7/VuWV go.opentelemetry.io/contrib/propagators/jaeger v1.21.1/go.mod h1:U9jhkEl8d1LL+QXY7q3kneJWJugiN3kZJV2OWz3hkBY= go.opentelemetry.io/contrib/propagators/ot v1.21.1 h1:3TN5vkXjKYWp0YdMcnUEC/A+pBPvqz9V3nCS2xmcurk= go.opentelemetry.io/contrib/propagators/ot v1.21.1/go.mod h1:oy0MYCbS/b3cqUDW37wBWtlwBIsutngS++Lklpgh+fc= -go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= -go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 h1:R9DE4kQ4k+YtfLI2ULwX82VtNQ2J8yZmA7ZIF/D+7Mc= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0/go.mod h1:OQFyQVrDlbe+R7xrEyDr/2Wr67Ol0hRUgsfA+V5A95s= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 h1:qFffATk0X+HD+f1Z8lswGiOQYKHRlzfmdJm0wEaVrFA= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0/go.mod h1:MOiCmryaYtc+V0Ei+Tx9o5S1ZjA7kzLucuVuyzBZloQ= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.0 h1:QY7/0NeRPKlzusf40ZE4t1VlMKbqSNT7cJRYzWuja0s= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.0/go.mod h1:HVkSiDhTM9BoUJU8qE6j2eSWLLXvi1USXjyd2BXT8PY= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.27.0 h1:/0YaXu3755A/cFbtXp+21lkXgI0QE5avTWA2HjU9/WE= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.27.0/go.mod h1:m7SFxp0/7IxmJPLIY3JhOcU9CoFzDaCPL6xxQIxhA+o= -go.opentelemetry.io/otel/exporters/zipkin v1.27.0 h1:aXcxb7F6ZDC1o2Z52LDfS2g6M2FB5CrxdR2gzY4QRNs= -go.opentelemetry.io/otel/exporters/zipkin v1.27.0/go.mod h1:+WMURoi4KmVB7ypbFPx3xtZTWen2Ca3lRK9u6DVTO5M= -go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q= -go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s= -go.opentelemetry.io/otel/sdk v1.27.0 h1:mlk+/Y1gLPLn84U4tI8d3GNJmGT/eXe3ZuOXN9kTWmI= -go.opentelemetry.io/otel/sdk v1.27.0/go.mod h1:Ha9vbLwJE6W86YstIywK2xFfPjbWlCuwPtMkKdz/Y4A= -go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= -go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= +go.opentelemetry.io/otel v1.31.0 h1:NsJcKPIW0D0H3NgzPDHmo0WW6SptzPdqg/L1zsIm2hY= +go.opentelemetry.io/otel v1.31.0/go.mod h1:O0C14Yl9FgkjqcCZAsE053C13OaddMYr/hz6clDkEJE= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.31.0 h1:K0XaT3DwHAcV4nKLzcQvwAgSyisUghWoY20I7huthMk= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.31.0/go.mod h1:B5Ki776z/MBnVha1Nzwp5arlzBbE3+1jk+pGmaP5HME= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.31.0 h1:FFeLy03iVTXP6ffeN2iXrxfGsZGCjVx0/4KlizjyBwU= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.31.0/go.mod h1:TMu73/k1CP8nBUpDLc71Wj/Kf7ZS9FK5b53VapRsP9o= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.31.0 h1:lUsI2TYsQw2r1IASwoROaCnjdj2cvC2+Jbxvk6nHnWU= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.31.0/go.mod h1:2HpZxxQurfGxJlJDblybejHB6RX6pmExPNe517hREw4= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.31.0 h1:UGZ1QwZWY67Z6BmckTU+9Rxn04m2bD3gD6Mk0OIOCPk= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.31.0/go.mod h1:fcwWuDuaObkkChiDlhEpSq9+X1C0omv+s5mBtToAQ64= +go.opentelemetry.io/otel/exporters/zipkin v1.31.0 h1:CgucL0tj3717DJnni7HVVB2wExzi8c2zJNEA2BhLMvI= +go.opentelemetry.io/otel/exporters/zipkin v1.31.0/go.mod h1:rfzOVNiSwIcWtEC2J8epwG26fiaXlYvLySJ7bwsrtAE= +go.opentelemetry.io/otel/metric v1.31.0 h1:FSErL0ATQAmYHUIzSezZibnyVlft1ybhy4ozRPcF2fE= +go.opentelemetry.io/otel/metric v1.31.0/go.mod h1:C3dEloVbLuYoX41KpmAhOqNriGbA+qqH6PQ5E5mUfnY= +go.opentelemetry.io/otel/sdk v1.31.0 h1:xLY3abVHYZ5HSfOg3l2E5LUj2Cwva5Y7yGxnSW9H5Gk= +go.opentelemetry.io/otel/sdk v1.31.0/go.mod h1:TfRbMdhvxIIr/B2N2LQW2S5v9m3gOQ/08KsbbO5BPT0= +go.opentelemetry.io/otel/trace v1.31.0 h1:ffjsj1aRouKewfr85U2aGagJ46+MvodynlQ1HYdmJys= +go.opentelemetry.io/otel/trace v1.31.0/go.mod h1:TXZkRk7SM2ZQLtR6eoAWQFIHPvzQ06FJAsO1tJg480A= go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= @@ -1411,10 +1411,10 @@ google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7Fc google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto/googleapis/api v0.0.0-20240617180043-68d350f18fd4 h1:MuYw1wJzT+ZkybKfaOXKp5hJiZDn2iHaXRw0mRYdHSc= -google.golang.org/genproto/googleapis/api v0.0.0-20240617180043-68d350f18fd4/go.mod h1:px9SlOOZBg1wM1zdnr8jEL4CNGUBZ+ZKYtNPApNQc4c= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240617180043-68d350f18fd4 h1:Di6ANFilr+S60a4S61ZM00vLdw0IrQOSMS2/6mrnOU0= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240617180043-68d350f18fd4/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= +google.golang.org/genproto/googleapis/api v0.0.0-20241007155032-5fefd90f89a9 h1:T6rh4haD3GVYsgEfWExoCZA2o2FmbNyKpTuAxbEFPTg= +google.golang.org/genproto/googleapis/api v0.0.0-20241007155032-5fefd90f89a9/go.mod h1:wp2WsuBYj6j8wUdo3ToZsdxxixbvQNAHqVJrTgi5E5M= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9 h1:QCqS/PdaHTSWGvupk2F/ehwHtGc0/GYkT+3GAcR1CCc= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= @@ -1431,8 +1431,8 @@ google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3Iji google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.64.0 h1:KH3VH9y/MgNQg1dE7b3XfVK0GsPSIzJwdF617gUSbvY= -google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg= +google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= +google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 66ec7fe9c..46b022a2b 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -119,7 +119,7 @@ require ( github.com/huin/goupnp v1.3.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/ipfs/bbloom v0.0.4 // indirect - github.com/ipfs/boxo v0.24.2 // indirect + github.com/ipfs/boxo v0.24.3 // indirect github.com/ipfs/go-block-format v0.2.0 // indirect github.com/ipfs/go-cid v0.4.1 // indirect github.com/ipfs/go-datastore v0.6.0 // indirect @@ -130,7 +130,7 @@ require ( github.com/ipfs/kubo v0.31.0 // indirect github.com/ipld/go-codec-dagpb v1.6.0 // indirect github.com/ipld/go-ipld-prime v0.21.0 // indirect - github.com/ipshipyard/p2p-forge v0.0.1 // indirect + github.com/ipshipyard/p2p-forge v0.0.2 // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect github.com/jbenet/goprocess v0.1.4 // indirect @@ -237,7 +237,7 @@ require ( github.com/ryanrolds/sqlclosecheck v0.5.1 // indirect github.com/sagikazarmark/locafero v0.6.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect - github.com/samber/lo v1.46.0 // indirect + github.com/samber/lo v1.47.0 // indirect github.com/sanposhiho/wastedassign/v2 v2.0.7 // indirect github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 // indirect github.com/sashamelentyev/interfacebloat v1.1.0 // indirect @@ -283,9 +283,9 @@ require ( go-simpler.org/musttag v0.12.2 // indirect go-simpler.org/sloglint v0.7.2 // indirect go.opencensus.io v0.24.0 // indirect - go.opentelemetry.io/otel v1.28.0 // indirect - go.opentelemetry.io/otel/metric v1.28.0 // indirect - go.opentelemetry.io/otel/trace v1.28.0 // indirect + go.opentelemetry.io/otel v1.31.0 // indirect + go.opentelemetry.io/otel/metric v1.31.0 // indirect + go.opentelemetry.io/otel/trace v1.31.0 // indirect go.uber.org/automaxprocs v1.5.3 // indirect go.uber.org/dig v1.18.0 // indirect go.uber.org/fx v1.23.0 // indirect diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index bdbc9e199..37a560dd9 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -318,8 +318,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.24.2 h1:feLM6DY6CNI0uSG3TvP/Hv4PdM/fsekjqSCqKtifF0E= -github.com/ipfs/boxo v0.24.2/go.mod h1:Dt3TJjMZtF2QksMv2LC8pQlG9VQUiSV2DsHQzvDiroo= +github.com/ipfs/boxo v0.24.3 h1:gldDPOWdM3Rz0v5LkVLtZu7A7gFNvAlWcmxhCqlHR3c= +github.com/ipfs/boxo v0.24.3/go.mod h1:h0DRzOY1IBFDHp6KNvrJLMFdSXTYID0Zf+q7X05JsNg= github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs= github.com/ipfs/go-block-format v0.2.0/go.mod h1:+jpL11nFx5A/SPpsoBn6Bzkra/zaArfSmsknbPMYgzM= github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= @@ -358,8 +358,8 @@ github.com/ipld/go-codec-dagpb v1.6.0 h1:9nYazfyu9B1p3NAgfVdpRco3Fs2nFC72DqVsMj6 github.com/ipld/go-codec-dagpb v1.6.0/go.mod h1:ANzFhfP2uMJxRBr8CE+WQWs5UsNa0pYtmKZ+agnUw9s= github.com/ipld/go-ipld-prime v0.21.0 h1:n4JmcpOlPDIxBcY037SVfpd1G+Sj1nKZah0m6QH9C2E= github.com/ipld/go-ipld-prime v0.21.0/go.mod h1:3RLqy//ERg/y5oShXXdx5YIp50cFGOanyMctpPjsvxQ= -github.com/ipshipyard/p2p-forge v0.0.1 h1:7Wy3Ul4gGLIPx4LjMjGaO6MoKa54ITDqwMOyXshrvO4= -github.com/ipshipyard/p2p-forge v0.0.1/go.mod h1:taPeh3PDSO8Ual0/N2tIOAUXPV8gZoPF3uPXoUyiq14= +github.com/ipshipyard/p2p-forge v0.0.2 h1:86y9LxGB8sGxYQ/If5sNx+c8C/huSpBUg3UZ1uvtym8= +github.com/ipshipyard/p2p-forge v0.0.2/go.mod h1:taPeh3PDSO8Ual0/N2tIOAUXPV8gZoPF3uPXoUyiq14= github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA= @@ -670,8 +670,8 @@ github.com/sagikazarmark/locafero v0.6.0 h1:ON7AQg37yzcRPU69mt7gwhFEBwxI6P9T4Qu3 github.com/sagikazarmark/locafero v0.6.0/go.mod h1:77OmuIc6VTraTXKXIs/uvUxKGUXjE1GbemJYHqdNjX0= github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= -github.com/samber/lo v1.46.0 h1:w8G+oaCPgz1PoCJztqymCFaKwXt+5cCXn51uPxExFfQ= -github.com/samber/lo v1.46.0/go.mod h1:RmDH9Ct32Qy3gduHQuKJ3gW1fMHAnE/fAzQuf6He5cU= +github.com/samber/lo v1.47.0 h1:z7RynLwP5nbyRscyvcD043DWYoOcYRv3mV8lBeqOCLc= +github.com/samber/lo v1.47.0/go.mod h1:RmDH9Ct32Qy3gduHQuKJ3gW1fMHAnE/fAzQuf6He5cU= github.com/sanposhiho/wastedassign/v2 v2.0.7 h1:J+6nrY4VW+gC9xFzUc+XjPD3g3wF3je/NsJFwFK7Uxc= github.com/sanposhiho/wastedassign/v2 v2.0.7/go.mod h1:KyZ0MWTwxxBmfwn33zh3k1dmsbF2ud9pAAGfoLfjhtI= github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6NgVqpn3+iol9aGu4= @@ -832,12 +832,12 @@ go-simpler.org/sloglint v0.7.2/go.mod h1:US+9C80ppl7VsThQclkM7BkCHQAzuz8kHLsW3pp go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= -go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= -go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q= -go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s= -go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= -go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= +go.opentelemetry.io/otel v1.31.0 h1:NsJcKPIW0D0H3NgzPDHmo0WW6SptzPdqg/L1zsIm2hY= +go.opentelemetry.io/otel v1.31.0/go.mod h1:O0C14Yl9FgkjqcCZAsE053C13OaddMYr/hz6clDkEJE= +go.opentelemetry.io/otel/metric v1.31.0 h1:FSErL0ATQAmYHUIzSezZibnyVlft1ybhy4ozRPcF2fE= +go.opentelemetry.io/otel/metric v1.31.0/go.mod h1:C3dEloVbLuYoX41KpmAhOqNriGbA+qqH6PQ5E5mUfnY= +go.opentelemetry.io/otel/trace v1.31.0 h1:ffjsj1aRouKewfr85U2aGagJ46+MvodynlQ1HYdmJys= +go.opentelemetry.io/otel/trace v1.31.0/go.mod h1:TXZkRk7SM2ZQLtR6eoAWQFIHPvzQ06FJAsO1tJg480A= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/automaxprocs v1.5.3 h1:kWazyxZUrS3Gs4qUpbwo5kEIMGe/DAvi5Z4tl2NW4j8= go.uber.org/automaxprocs v1.5.3/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0= From 5d2f5369c7947da423febb86ece29ed595bf6d9d Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Thu, 7 Nov 2024 22:12:42 +0100 Subject: [PATCH 1211/1212] feat: ipfs-webui v4.4.0 (#10574) https://github.com/ipfs/ipfs-webui/releases/tag/v4.4.0 --- core/corehttp/webui.go | 3 ++- docs/changelogs/v0.32.md | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/core/corehttp/webui.go b/core/corehttp/webui.go index 4014e69b3..4f00ad712 100644 --- a/core/corehttp/webui.go +++ b/core/corehttp/webui.go @@ -1,11 +1,12 @@ package corehttp // WebUI version confirmed to work with this Kubo version -const WebUIPath = "/ipfs/bafybeid4uxz7klxcu3ffsnmn64r7ihvysamlj4ohl5h2orjsffuegcpaeq" // v4.3.3 +const WebUIPath = "/ipfs/bafybeibgic2ex3fvzkinhy6k6aqyv3zy2o7bkbsmrzvzka24xetv7eeadm" // v4.4.0 // WebUIPaths is a list of all past webUI paths. var WebUIPaths = []string{ WebUIPath, + "/ipfs/bafybeid4uxz7klxcu3ffsnmn64r7ihvysamlj4ohl5h2orjsffuegcpaeq", "/ipfs/bafybeif6abowqcavbkz243biyh7pde7ick5kkwwytrh7pd2hkbtuqysjxy", "/ipfs/bafybeihatzsgposbr3hrngo42yckdyqcc56yean2rynnwpzxstvdlphxf4", "/ipfs/bafybeigggyffcf6yfhx5irtwzx3cgnk6n3dwylkvcpckzhqqrigsxowjwe", diff --git a/docs/changelogs/v0.32.md b/docs/changelogs/v0.32.md index ca8a79bc2..58ed16030 100644 --- a/docs/changelogs/v0.32.md +++ b/docs/changelogs/v0.32.md @@ -24,6 +24,7 @@ See [`AutoTLS`](https://github.com/ipfs/kubo/blob/master/docs/config.md#autotls) #### 📦️ Dependency updates +- update `ipfs-webui` to [v4.4.0](https://github.com/ipfs/ipfs-webui/releases/tag/v4.4.0) - update `boxo` to [v0.24.1](https://github.com/ipfs/boxo/releases/tag/v0.24.1) + [v0.24.2](https://github.com/ipfs/boxo/releases/tag/v0.24.2) + [v0.24.3](https://github.com/ipfs/boxo/releases/tag/v0.24.3) - This includes a number of fixes and bitswap improvements, and support for filtering from [IPIP-484](https://specs.ipfs.tech/ipips/ipip-0484/) in delegated HTTP routing and IPNI queries. - update `go-libp2p` to [v0.37.0](https://github.com/libp2p/go-libp2p/releases/tag/v0.37.0) From 71048b7687a551dd178acef90549a64e3c38568f Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Thu, 7 Nov 2024 23:03:33 +0100 Subject: [PATCH 1212/1212] chore(ci): adjust timeout in docker job history of https://github.com/ipfs/kubo/actions/workflows/docker-image.yml shows the job takes ~5m, so 15m is plenty if something goes wrong. --- .github/workflows/docker-image.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index ce927e5e5..ca4b5fdd4 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -32,7 +32,7 @@ jobs: if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' name: Push Docker image to Docker Hub runs-on: ubuntu-latest - timeout-minutes: 90 + timeout-minutes: 15 env: IMAGE_NAME: ipfs/kubo LEGACY_IMAGE_NAME: ipfs/go-ipfs